Index: UsbWattMeter/trunk/asp_dcre/arch/ccrx/tool_stddef.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/ccrx/tool_stddef.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/ccrx/tool_stddef.h	(revision 164)
@@ -0,0 +1,132 @@
+/*
+ *  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
+ *  Copyright (C) 2007-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  t_stddef.hÌJ­Â«Ë¶ilTX RXc[`FCpj
+ *
+ *  ±ÌCN[ht@CÍCt_stddef.h ÌæªÅCN[h³êéD
+ *  ¼Ìt@C©çÍ¼ÚCN[h·é±ÆÍÈ¢D¼ÌCN[h
+ *  t@CÉæ§ÁÄ³êé½ßC¼ÌCN[ht@CÉË¶µ
+ *  ÄÍÈçÈ¢D
+ */
+
+#if !defined( TOPPERS_TOOL_STDDEF_H )
+#define TOPPERS_TOOL_STDDEF_H
+
+/*
+ *  RpCÌg£@\Ì½ßÌ}Nè`
+ */
+/*
+ *  inline ¯ÊqÍOè`ð¶¬µÈ¢.
+ */
+#define	Inline		static inline
+
+/*
+ *  CCAZuÍ{RpCÅÍ
+ *  #pragma inline_asmÌÝÌT|[gÆÈé½ß,
+ *  asm/Asmè`ÍsíÈ¢.
+ */
+
+/*
+ *  NoReturn / alignofÍ{RpCÅÍT|[g³êÈ¢.
+ *  offsetofÍstddef.hÌè`ðp·é.
+ */
+#define	NoReturn
+
+
+/*
+ *  J­Â«ÌWCN[ht@CÌp
+ *
+ *  NULLÌè`ðstddef.h©çCINT_MAXCINT_MINCUINT_MAXCLONG_MAXC
+ *  LONG_MINCULONG_MAXCCHAR_BITÌè`ðlimits.h©çæèÞD
+ *
+ *  C++/EC++ÅÍCWdlãÍ±êçÌCN[ht@CªpÓ³êÄ
+ *  ¢éÆÍÀçÈ¢ÌÅÓªKvÅ éiÙÆñÇÌJ­Â«ÅpÓ³ê
+ *  Ä¢éjD
+ */
+#ifndef TOPPERS_MACRO_ONLY
+#include <stddef.h>
+#include <limits.h>
+#endif /* TOPPERS_MACRO_ONLY */
+
+
+/*
+ *  RpCË¶Ìf[^^Ìè`
+ *
+ *  stdint.hðCN[h·é
+ */
+#ifndef TOPPERS_MACRO_ONLY
+#include <stdint.h>
+#endif /* TOPPERS_MACRO_ONLY */
+
+
+/*
+ *  ®¬_^ÉÖ·éè`
+ *
+ *  ºLÌè`Ídbl_size = 8IvVðwèµ½êÌÝLøÆ·é±Æ.
+ */
+#ifndef TOPPERS_MACRO_ONLY
+typedef float		float32_t;			/* IEEE754ÌP¸x®¬_ */
+typedef double		double64_t;			/* IEEE754Ì{¸x®¬_ */
+#endif /* TOPPERS_MACRO_ONLY */
+
+#define FLOAT32_MIN		( 1.4012984643248171e-45F )
+#define FLOAT32_MAX		( 3.4028234663852886e+38F )
+#define DOUBLE64_MIN	( 4.9406564584124654e-324 )
+#define DOUBLE64_MAX	( 1.7976931348623157e+308 )
+
+
+/*
+ *  óxÌè`
+ *
+ *  {RpCÅÍå«³[ÌzñÍRpCG[ÉÈé½ß,
+ *  TCY1ÉÄè`·é.
+ */
+#define TOPPERS_EMPTY_LABEL( type, symbol )		type symbol[ 1 ]
+
+
+#endif /* TOPPERS_TOOL_STDDEF_H */
+
Index: UsbWattMeter/trunk/asp_dcre/arch/logtrace/MANIFEST
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/logtrace/MANIFEST	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/logtrace/MANIFEST	(revision 164)
@@ -0,0 +1,6 @@
+PACKAGE asp
+
+MANIFEST
+trace_config.c
+trace_config.h
+trace_dump.c
Index: UsbWattMeter/trunk/asp_dcre/arch/logtrace/trace_config.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/logtrace/trace_config.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/logtrace/trace_config.c	(revision 164)
@@ -0,0 +1,253 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  $Id$
+ */
+
+/*
+ *		g[XO@\
+ */
+
+#include "kernel_impl.h"
+#include "task.h"
+#include "time_event.h"
+#include <sil.h>
+
+/*
+ *  g[XOobt@Æ»êÉANZX·é½ßÌ|C^
+ */
+SYSLOG	trace_buffer[TCNT_TRACE_BUFFER];	/* g[XOobt@ */
+uint_t	trace_count;				/* g[XOobt@ÌOÌ */
+uint_t	trace_head;					/* æªÌg[XOÌi[Êu */
+uint_t	trace_tail;					/* Ìg[XOÌi[Êu */
+MODE	trace_mode;					/* g[X[h */
+
+/*
+ *  g[XO@\Ìú»
+ */
+void
+trace_initialize(intptr_t exinf)
+{
+	MODE	mode = ((MODE) exinf);
+
+	trace_count = 0U;
+	trace_head = 0U;
+	trace_tail = 0U;
+	trace_mode = mode;
+}     
+
+/*
+ *  g[XOÌJn
+ */
+ER
+trace_sta_log(MODE mode)
+{
+	if ((mode & TRACE_CLEAR) != 0U) {
+		trace_count = 0U;
+		trace_head = 0U;
+		trace_tail = 0U;
+	}
+	trace_mode = mode;
+	return(E_OK);
+}     
+
+/* 
+ *  g[XOÌÝ
+ */
+ER
+trace_wri_log(TRACE *p_trace)
+{
+	SIL_PRE_LOC;
+
+	if (trace_mode != TRACE_STOP) {
+		SIL_LOC_INT();
+
+		/*
+		 *  g[XÌÝè
+		 *
+		 *  LOG_WRI_LOG_ENTER©çÄÎê½êÉp_trace->logtimð«·
+		 *  ¦ÄµÜ¤ÌÍC¿ª«¢ªCwri_logÌûÅã«·é½ßâ
+		 *  èÍÈ¢D
+		 */
+		p_trace->logtim = TRACE_GET_TIM();
+
+		/*
+		 *  g[Xobt@ÉL^
+		 */
+		trace_buffer[trace_tail] = *p_trace;
+		trace_tail++;
+		if (trace_tail >= TCNT_TRACE_BUFFER) {
+			trace_tail = 0U;
+		}
+		if (trace_count < TCNT_TRACE_BUFFER) {
+			trace_count++;
+			if (trace_count >= TCNT_TRACE_BUFFER
+						&& (trace_mode & TRACE_AUTOSTOP) != 0U) {
+				trace_mode = TRACE_STOP;
+			}
+		}
+		else {
+			trace_head = trace_tail;
+		}
+
+		SIL_UNL_INT();
+	}
+	return(E_OK);
+}
+
+/*
+ *  g[XOÌÇoµ
+ */
+ER
+trace_rea_log(TRACE *p_trace)
+{
+	ER_UINT	ercd;
+	SIL_PRE_LOC;
+
+	SIL_LOC_INT();
+
+	/*
+	 *  g[XOobt@©çÌæoµ
+	 */
+	if (trace_count > 0U) {
+		*p_trace = trace_buffer[trace_head];
+		trace_count--;
+		trace_head++;
+		if (trace_head >= TCNT_TRACE_BUFFER) {
+			trace_head = 0U;
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+
+	SIL_UNL_INT();
+	return(ercd);
+}
+
+/*
+ *  g[XOðoÍ·é½ßÌCuÖ
+ */
+
+void
+trace_write_0(uint_t type)
+{
+	TRACE	trace;
+
+	trace.logtype = type;
+	(void) trace_wri_log(&trace);
+}
+
+void
+trace_write_1(uint_t type, intptr_t arg1)
+{
+	TRACE	trace;
+
+	trace.logtype = type;
+	trace.loginfo[0] = arg1;
+	(void) trace_wri_log(&trace);
+}
+
+void
+trace_write_2(uint_t type, intptr_t arg1, intptr_t arg2)
+{
+	TRACE	trace;
+
+	trace.logtype = type;
+	trace.loginfo[0] = arg1;
+	trace.loginfo[1] = arg2;
+	(void) trace_wri_log(&trace);
+}
+
+void
+trace_write_3(uint_t type, intptr_t arg1, intptr_t arg2, intptr_t arg3)
+{
+	TRACE	trace;
+
+	trace.logtype = type;
+	trace.loginfo[0] = arg1;
+	trace.loginfo[1] = arg2;
+	trace.loginfo[2] = arg3;
+	(void) trace_wri_log(&trace);
+}
+
+/*
+ *  AZu¾êÅLq³êéR[h©çg[XOðoÍ·é½ßÌÖ
+ *  
+ */
+
+void
+log_dsp_enter(TCB *p_tcb)
+{
+	trace_1(LOG_TYPE_DSP|LOG_ENTER, p_tcb);
+}
+
+void
+log_dsp_leave(TCB *p_tcb)
+{
+	trace_1(LOG_TYPE_DSP|LOG_LEAVE, p_tcb);
+}
+
+void
+log_inh_enter(INHNO inhno)
+{
+	trace_1(LOG_TYPE_INH|LOG_ENTER, inhno);
+}
+
+void
+log_inh_leave(INHNO inhno)
+{
+	trace_1(LOG_TYPE_INH|LOG_LEAVE, inhno);
+}
+
+void
+log_exc_enter(EXCNO excno)
+{
+	trace_1(LOG_TYPE_EXC|LOG_ENTER, excno);
+}
+
+void
+log_exc_leave(EXCNO excno)
+{
+	trace_1(LOG_TYPE_EXC|LOG_LEAVE, excno);
+}
Index: UsbWattMeter/trunk/asp_dcre/arch/logtrace/trace_config.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/logtrace/trace_config.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/logtrace/trace_config.h	(revision 164)
@@ -0,0 +1,185 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  $Id$
+ */
+
+/*
+ *		g[XOÉÖ·éÝè
+ *
+ *  ±ÌCN[ht@CÍCtarget_config.h¨æÑtarget_syssvc.hÌ
+ *  Ý©çCN[h³êéDÜ½Cg[XO@\Ìú»âL^ÌJ
+ *  n^â~Cg[XOÌ_vðs¤vO©çCN[h·é
+ *  ±ÆðzèµÄ¢éD
+ */
+
+#ifndef TOPPERS_TRACE_CONFIG_H
+#define TOPPERS_TRACE_CONFIG_H
+
+/*
+ *  g[XOobt@ÌTCY
+ */
+#ifndef TCNT_TRACE_BUFFER
+#define TCNT_TRACE_BUFFER	1024
+#endif /* TCNT_TRACE_BUFFER */
+
+/*
+ *  g[XÌæ¾û@
+ */
+#ifndef TRACE_GET_TIM
+#define TRACE_GET_TIM()		(current_time)
+#endif /* TRACE_GET_TIM */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  g[XOÌf[^\¢
+ *
+ *  VXeO@\ÌOîñÌf[^\¢Æ¯¶àÌðp¢éD
+ */
+#include <t_syslog.h>
+typedef	SYSLOG	TRACE;
+
+/*
+ *  g[XOobt@Æ»êÉANZX·é½ßÌ|C^
+ */
+extern TRACE	trace_buffer[];		/* g[XOobt@ */
+extern uint_t	trace_count;		/* g[XOobt@ÌOÌ */
+extern uint_t	trace_head;			/* æªÌg[XOÌi[Êu */
+extern uint_t	trace_tail;			/* Ìg[XOÌi[Êu */
+extern uint_t	trace_lost;			/* ¸íê½g[XÌ */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  g[X[hÌè`
+ */
+#define TRACE_STOP			UINT_C(0x00)	/* g[Xâ~ */
+#define TRACE_RINGBUF		UINT_C(0x01)	/* Oobt@[h */
+#define TRACE_AUTOSTOP		UINT_C(0x02)	/* ©®â~[h */
+#define TRACE_CLEAR			UINT_C(0x04)	/* g[XOÌNA */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  g[XO@\Ìú»
+ *
+ *  g[XO@\ðú»·éDú»[`ÆµÄo^·é±Æðz
+ *  èµÄ¢éDøÉæèÌ®ìðs¤D
+ *
+ *  TRACE_STOPFú»ÌÝÅg[XÍJnµÈ¢D
+ *  TRACE_RINGBUFFOobt@[hÅg[XðJnD
+ *  TRACE_AUTOSTOPF©®â~[hÅg[XðJnD
+ */
+extern void	trace_initialize(intptr_t exinf);
+
+/*
+ *  g[XOÌJn
+ *
+ *  g[XOÌL^ðJn^â~·éDøÉæèÌ®ìðs¤D
+ *
+ *  TRACE_STOPFg[Xðâ~D
+ *  TRACE_RINGBUFFOobt@[hÅg[XðJnD
+ *  TRACE_AUTOSTOPF©®â~[hÅg[XðJnD
+ *  TRACE_CLEARFg[XOðNAD
+ */
+extern ER	trace_sta_log(MODE mode);
+
+/*
+ *  g[XOÌÝ
+ */
+extern ER	trace_wri_log(TRACE *p_trace);
+
+/*
+ *  g[XOÌÇoµ
+ */
+extern ER	trace_rea_log(TRACE *p_trace);
+
+/* 
+ *  g[XOÌ_vitrace_dump.cj
+ *
+ *  g[XOð_v·éDI¹[`ÆµÄo^·é±Æàzè
+ *  µÄ¢éDøÆµÄC_væÆÈé¶oÍÖÖÌ|C^ðn·D
+ *  ^[QbgË¶Ìáx¶oÍðp·éêÉÍCtarget_putcðn
+ *  ·D
+ */
+extern void	trace_dump(intptr_t exinf);
+
+/*
+ *  g[XOðoÍ·é½ßÌCuÖ
+ */
+extern void	trace_write_0(uint_t type);
+extern void	trace_write_1(uint_t type, intptr_t arg1);
+extern void	trace_write_2(uint_t type, intptr_t arg1, intptr_t arg2);
+extern void	trace_write_3(uint_t type, intptr_t arg1, intptr_t arg2,
+														intptr_t arg3);
+
+/*
+ *  g[XOðoÍ·é½ßÌ}N
+ */
+
+#define trace_0(type) \
+				trace_write_0(type)
+
+#define trace_1(type, arg1) \
+				trace_write_1(type, (intptr_t)(arg1))
+
+#define trace_2(type, arg1, arg2) \
+				trace_write_2(type, (intptr_t)(arg1), (intptr_t)(arg2))
+
+#define trace_3(type, arg1, arg2, arg3) \
+				trace_write_3(type, (intptr_t)(arg1), (intptr_t)(arg2), \
+						(intptr_t)(arg3))
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  g[XOû@ÌÝè
+ */
+#define LOG_TSKSTAT(p_tcb)		trace_2(LOG_TYPE_TSKSTAT, p_tcb, p_tcb->tstat)
+
+#define LOG_DSP_LEAVE(p_tcb)	trace_1(LOG_TYPE_DSP|LOG_LEAVE, p_tcb)
+
+#define LOG_SYSLOG_WRI_LOG_ENTER(prio, p_syslog) \
+								trace_wri_log((TRACE *) p_syslog)
+
+#endif /* TOPPERS_TRACE_CONFIG_H */
Index: UsbWattMeter/trunk/asp_dcre/arch/logtrace/trace_dump.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/logtrace/trace_dump.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/logtrace/trace_dump.c	(revision 164)
@@ -0,0 +1,158 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  $Id$
+ */
+
+/*
+ *		g[XOÌ_v
+ */
+
+#include "kernel_impl.h"
+#include "task.h"
+#include <log_output.h>
+
+/* 
+ *  J[lîñÌæoµ
+ */
+static intptr_t
+get_tskid(intptr_t info)
+{
+	TCB		*p_tcb;
+	ID		tskid;
+
+	p_tcb = (TCB *) info;
+	if (p_tcb == NULL) {
+		tskid = 0;
+	}
+	else {
+		tskid = TSKID(p_tcb);
+	}
+	return((intptr_t) tskid);
+}
+
+static intptr_t
+get_tskstat(intptr_t info)
+{
+	uint_t		tstat;
+	const char	*tstatstr;
+
+	tstat = (uint_t) info;
+	switch (tstat & (TS_RUNNABLE|TS_WAITING|TS_SUSPENDED)) {
+	case TS_DORMANT:
+		tstatstr = "DORMANT";
+		break;
+	case TS_RUNNABLE:
+		tstatstr = "RUNNABLE";
+		break;
+	case TS_WAITING:
+		tstatstr = "WAITING";
+		break;
+	case TS_SUSPENDED:
+		tstatstr = "SUSPENDED";
+		break;
+	case TS_WAITING|TS_SUSPENDED:
+		tstatstr = "WAITING-SUSPENDED";
+		break;
+	default:
+		tstatstr = "unknown state";
+		break;
+	}
+	return((intptr_t) tstatstr);
+}
+
+/* 
+ *  g[XOÌ\¦
+ */
+static void
+trace_print(TRACE *p_trace, void (*putc)(char))
+{
+	intptr_t	traceinfo[TMAX_LOGINFO + 1];
+	const char	*tracemsg;
+	int_t		i;
+
+	traceinfo[0] = (intptr_t)(p_trace->logtim);
+	syslog_printf("[%d] ", traceinfo, putc);
+
+	switch (p_trace->logtype) {
+	case LOG_TYPE_TSKSTAT:
+		traceinfo[0] = get_tskid(p_trace->loginfo[0]);
+		traceinfo[1] = get_tskstat(p_trace->loginfo[1]);
+		tracemsg = "task %d becomes %s.";
+		break;
+	case LOG_TYPE_DSP|LOG_LEAVE:
+		traceinfo[0] = get_tskid(p_trace->loginfo[0]);
+		tracemsg = "dispatch to task %d.";
+		break;
+	case LOG_TYPE_COMMENT:
+		for (i = 1; i < TMAX_LOGINFO; i++) {
+			traceinfo[i-1] = p_trace->loginfo[i];
+		}
+		tracemsg = (const char *)(p_trace->loginfo[0]);
+		break;
+	case LOG_TYPE_ASSERT:
+		traceinfo[0] = p_trace->loginfo[0];
+		traceinfo[1] = p_trace->loginfo[1];
+		traceinfo[2] = p_trace->loginfo[2];
+		tracemsg = "%s:%u: Assertion `%s' failed.";
+		break;
+	default:
+		traceinfo[0] = p_trace->logtype;
+		tracemsg = "unknown trace log type: %d.";
+		break;
+	}
+	syslog_printf(tracemsg, traceinfo, putc);
+	(*putc)('\n');
+}
+
+/* 
+ *  g[XOÌ_v
+ */
+void
+trace_dump(intptr_t exinf)
+{
+	TRACE	trace;
+	void	(*putc)(char);
+
+	putc = (void (*)(char)) exinf;
+	while (trace_rea_log(&trace) >= 0) {
+		trace_print(&trace, putc);
+	}
+}
Index: UsbWattMeter/trunk/asp_dcre/arch/msvc/MANIFEST
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/msvc/MANIFEST	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/msvc/MANIFEST	(revision 164)
@@ -0,0 +1,4 @@
+PACKAGE asp
+
+MANIFEST
+tool_stddef.h
Index: UsbWattMeter/trunk/asp_dcre/arch/msvc/tool_stddef.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/msvc/tool_stddef.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/msvc/tool_stddef.h	(revision 164)
@@ -0,0 +1,203 @@
+/*
+ *  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-2008 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2014 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		t_stddef.hÌJ­Â«Ë¶iMSVCpj
+ */
+
+#ifndef TOPPERS_TOOL_STDDEF_H
+#define TOPPERS_TOOL_STDDEF_H
+
+/*
+ *  RpCÌg£@\Ì½ßÌ}Nè`
+ */
+#ifndef __cplusplus					/* C++ÉÍinline ª é */
+#if __STDC_VERSION__ < 199901L		/* C99ÉÍinline ª é */
+#define inline	__inline			/* CCÖ */
+#endif /* __STDC_VERSION__ < 199901L */
+#endif /* __cplusplus */
+
+#define Inline	static __inline	/* CCÖ */
+
+#define NoReturn
+									/* ^[µÈ¢Ö */
+
+/*
+ *  J­Â«ÌWCN[ht@CÌp
+ * 
+ *  NULLÌè`ðstddef.h©çCINT_MAXCINT_MINCUINT_MAXCLONG_MAXC
+ *  LONG_MINCULONG_MAXCCHAR_BITÌè`ðlimits.h©çæèÞD
+ * 
+ *  C++/EC++ÅÍCWdlãÍ±êçÌCN[ht@CªpÓ³êÄ
+ *  ¢éÆÍÀçÈ¢ÌÅÓªKvÅ éiÙÆñÇÌJ­Â«ÅpÓ³ê
+ *  Ä¢éjD
+ */
+#ifndef TOPPERS_MACRO_ONLY
+#include <stddef.h>
+#include <limits.h>
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  stdint.hÌãpÆÈéè`
+ * 
+ *  J­Â«Éstdint.hªpÓ³êÄ¨ç¸Ce®^ÌTCYª ép^[
+ *  ÉÄÍÜéêÉCstdint.hÌãpÆÈéè`ð^¦éD
+ * 
+ *  TOPPERS_STDINT_TYPE1: char/short/int/long longÌrbg·ª»ê¼ê
+ *                        8/16/32/64rbgÅC|C^Ìrbg·ªlong
+ *                        Ìrbg·Æêv·éê
+ */
+#ifdef TOPPERS_STDINT_TYPE1
+
+/*
+ *  RpCË¶Ìf[^^Ìè`
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+typedef signed char			int8_t;		/* t«8rbg® */
+typedef unsigned char		uint8_t;	/* ³µ8rbg® */
+
+typedef signed short		int16_t;	/* t«16rbg® */
+typedef unsigned short		uint16_t;	/* ³µ16rbg® */
+
+typedef signed int			int32_t;	/* t«32rbg® */
+typedef unsigned int		uint32_t;	/* ³µ32rbg® */
+
+typedef signed long long	int64_t;	/* t«64rbg® */
+typedef unsigned long long	uint64_t;	/* ³µ64rbg® */
+
+typedef int8_t				int_least8_t;	/* 8rbgÈãÌt«® */
+typedef uint8_t				uint_least8_t;	/* 8rbgÈãÌ³µ® */
+
+//typedef long				intptr_t;	/* |C^ði[Å«ét«® */
+//typedef unsigned long		uintptr_t;	/* |C^ði[Å«é³µ® */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  RpCË¶Ìf[^^Ì®èðìé}N
+ */
+#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 */
+
+/*
+ *  RpCË¶Ìf[^^Éi[Å«éÅålÆÅ¬lÌè`
+ */
+#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ÌP¸x®¬_C
+ *							doubleª{¸x®¬_Ìê
+ */
+#ifdef TOPPERS_STDFLOAT_TYPE1
+#ifndef TOPPERS_MACRO_ONLY
+
+typedef float		float32_t;			/* IEEE754ÌP¸x®¬_ */
+typedef double		double64_t;			/* IEEE754Ì{¸x®¬_ */
+
+#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 */
+
+#define TOPPERS_EMPTY_LABEL(x,y) x y[1]
+
+#endif /* TOPPERS_TOOL_STDDEF_H */
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/makeoffset.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/makeoffset.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/makeoffset.c	(revision 164)
@@ -0,0 +1,236 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2004 by Naoki Saito
+ *             Nagoya Municipal Industrial Research Institute, JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+
+/*
+ *	offset.inc (àµ­Í offset.h) ÉÂ¢Ä
+ *
+ *	  offset.inc Í\¢ÌÌÁèÌvfª\¢ÌÌæª©ç½oCgÚÉ
+ *	¶Ý·é©Æ¢¤±Æâ, ÁèÌrbgtB[hªæª©ç
+ *	½oCgæÌ½rbgÚÉ¶Ý·é©, Æ¢¤îñð
+ *	AZu¾êt@CÉ^¦é½ßÉ¶ÝµÄ¢é.
+ *
+ *	  offset.inc t@CÌgÍ, PÈéV{è`t@CÅ é.
+ *	V{Æ¢ÁÄàè`·éV{Ì¼ÌÉÍp^[ª è,
+ *	å«­ª¯ÄÌ3íÞÉªÞÅ«é.
+ *
+ *	<\¢Ì¼>_<vf¼>	(á) TCB_sp, TCB_pc, TCB_enatex ÈÇ
+ *	<\¢Ì¼>_<vf¼>_bit	(á) TCB_enatex_bit ÈÇ
+ *	<\¢Ì¼>_<vf¼>_mask (á) TCB_enatex_mask ÈÇ
+ *
+ *	(á)
+ *		TCB_texptn		.equ	14
+ *		TCB_sp			.equ	20
+ *		TCB_pc			.equ	24
+ *		TCB_enatex		.equ	13
+ *		TCB_enatex_bit		.equ	 6
+ *		TCB_enatex_mask		.equ	0040H
+ *
+ *	  êÔÍ¶ßÍÁèÌvfª\¢ÌÌæª©ç½oCgæÉ é©
+ *	Æ¢¤±Æð¦·lÉÂ¯éxÌ¼Ì.
+ *	  ñÔÚÍÁèÌrbgtB[hÌrbgª, ºÊ©ç¦Ä
+ *	½rbgÚÉ é©Æ¢¤±Æð¦·lÉÂ¯éxÌ¼Ì. 
+ *	0©çnÜélÅ\»·é. ÅàºÊÌrbgÍæ0rbgÅ é.
+ *	  OÔÚÍæÙÇÌ <\¢Ì¼>_<vf¼>_bit ÆàÖA·éª,
+ *	ÁèÌrbgtB[hÌrbgÌ}XNlÌ¼Ì.
+ *	_bit Æ *_mask ÌlÌÔÉÍÌÖWª é.
+ *		(*_mask) == (1 << *_bit)
+ * *	(á) TCB_enatex_bit ª 6 Ì, TCB_enatex_mask Í 40H
+ *
+ *	  ¿ÈÝÉM32CË¶ÌÀÅÍ, ÁèrbgÌ`FbNÈÇÉ
+ *	rbg½ßAhbVOðgpµÄ¢éÌÅ *_mask Æ¢¤xÍ
+ *	gpµÄ¢È¢.
+ */
+
+/*
+ *	offset.inc Ììèû(M32C^[QbgË¶ü¯)
+ *
+ *	  GNU CRpCðp¢Ä¢é^[QbgË¶ÉÂ¢ÄÍ,
+ *	J[lÌgbvfBNgÌºÉ é util Æ¢¤fBNgÌ
+ *	ºÉ genoffset Æ¢¤ perl XNvgªpÓ³êÄ¢éÌÅ,
+ *	ÁÉè®Å offset.h ðì¬·éKvÍÈ¢.
+ *	  genoffset Í GNU J­Â«ðzèµÄì¬³êÄ¢éÌÅ,
+ *	¶¬³êéAZu¾ê^½ßâ¶¬K¥ÌÙÈé¼Ì
+ *	CRpCÉÍ»ÌÜÜKpÅ«È¢Â\«ª é.
+ *	  »±Å, ±±ÅÍWindowsÂ« ü¯Ì genoffset ðpÓ¹¸,
+ *	ìèûð±±ÉLµ, èìÆÅ offset.inc ðì¬µÄàç¤±ÆÆ
+ *	·é. ÈºÉ»Ìû@ð¦·. È¨, ±Ìû@ÍM32CÌJ­Â«â
+ *	½ßZbgÉË¶µÄ¢é½ß, ¼Ì^[QbgðgpµÄ¢éêÍ
+ *	»ÌÜÜKpÅ«È¢.
+ *
+ *  1.	makeoffset.c Æ¢¤t@C©çCRpCðgpµÄ
+ *	AZu¾êt@C makeoffset.a30 ð¶¬·é.
+ *	RpCIvVÍJ[lR[hÉ^¦éàÌÆ¯¶
+ *	àÌð^¦é. 
+ *	lTX»c[ TM ðgpµÄ¢éêÍ, vWFNgGfB^Ì
+ *	¶¬èr
+[©ç makeoffset.a30 ðIÑ, ENbNj
+[Ì
+ *	¢ªrh£ðIð·é±ÆÅ¶¬Å«é.
+ *	àµ­ÍR}hvvgÅCNt@CÆ¯¶fBNgÉ
+ *	Ú®µ, "make -f CNt@C¼ makeoffset.a30" ð
+ *	ÀsµÄà¯lÌÊª¾çêé. (CNt@CÍTMªgpµÄ
+ *	¢éàÌÆ¯¶t@CðwèÂ\)
+ *
+ *  2.	æÙÇÌ 1. ÌìÆÅ¾çê½, makeoffset.a30 t@C©ç
+ *	"! BEGIN XXXX"  ÅÍ¶Üè "! END" ÅIíÁÄ¢éªðT·.
+ *
+ *	4Ó è, »ê¼ê­µ¸ÂÙÈéÌÅÉà¾·é.
+ *	(Èº, à¾ÅÍAZu¾êt@CÌRgsÍÈ­)
+ *
+ * (1)	\¢ÌÌæª©çoÖÌItZbg
+ *
+ *	! BEGIN TCB_texptn
+ *		bset	00H,0000000eH
+ *	! END
+ *
+ *	ãL"! BEGIN"ÌãëÌ¶ñªoffset.incÅè`·éV{¼ÆÈé.
+ *	»ÌV{ÌlÍ, sÌbset½ßÌæ2IyhÌlÅ é
+ *	0000000eHª»êÉ·é. ±êª\¢ÌÌæª©çtexptnÜÅÌ
+ *	ItZbglÆÈé. µ½ªÁÄ±Ìê, offset.inc ÉÍ
+ *	TCB_texptn	.equ	14
+ *	Æ¢¤sðLq·é.
+ *
+ * (2)	\¢ÌÌoª\¢ÌÅ, »ÌÌoÉÎ·éItZbg
+ *
+ *	TCB_sp ÉÂ¢ÄàÙÚ¯l¾ª, sp ÍTCB\¢ÌÌ¼ÚÌ
+ *	oÅÈ­TCB\¢ÌÌoÅ éTSKCTXB\¢ÌÌoÅ
+ *	 é_ªÙÈé. »êÅàè`·éV{¼ÆµÄÍ
+ *	TCB_sp Ìæ¤É\»·é. AZu¾êt@CÅÍ
+ *
+ *	! BEGIN TCB_sp
+ *		mov.l	00000014H,A0
+ *		extz	[A0],R0
+ *		bset	0,R0L
+ *		mov.l	#00000014H,A0
+ *		mov.b	R0L,[[A0]]
+ *	! END *
+ *
+ *	Ìæ¤ÉÈè,14H(=20) ªßélÈÌÅoffset.inc ÉÍÌæ¤É
+ *	Lq·é.
+ *
+ *	TCB_sp	.equ	20
+ *
+ * (3)	oªÖÖÌ|C^Å Á½ê
+ *
+ *	Í TCB_pc Ìê.
+ *
+ *	! BEGIN TCB_pc
+ *		mov.l	#00000018H,A0
+ *		jsri.a	[A0]
+ *	! END
+ *
+ *	pc à sp Æ¯¶­, TCB\¢ÌÌ¼ÚÌoÅÍÈ¢ª
+ *	TCB_pc Æ\»µÄ¢é. ±êÍÖÌAhXði[·éÏÈÌÅ,
+ *	(((TCB *)0)->tskctxb.pc)();
+ *	ÆµÄÖÄÑoµÌæ¤ÉLq·éÆãLÌæ¤ÈAZu¾ê
+ *	R[hðoÍ·é. V{è`·éÛÌV{¼Í¡ÜÅÆ
+ *	¯¶­, TCB_pc Æ·é. 
+ *	ßélÍ\¢Ì©çÖ|C^ÜÅÌItZbgÅ è, ãÌmov.l
+ *	½ßÌÊ©ç 	00000018H(=24) ÆÈé.
+ *	µ½ªÁÄ, offset.inc ÉÍÌæ¤ÉLq·é.
+ *
+ *	TCB_pc	.equ	24
+ *
+ * (4)	\¢ÌÌoªrbgtB[hÅ»ÌrbgÊuàmè½¢ê
+ *
+ *	! BEGIN TCB_enatex
+ *		bset	6,0000000cH+1
+ *	! END
+ *
+ *	¡ÜÅÆ¯l, BEGIN ÌãÌ¶ñðV{¼Æ·é.
+ *	±±ÅÌTCB_enatexÌlÍ\¢ÌÌæª©çrbgtB[hðÜÞo
+ *	CgÜÅÌItZbgÅ, M32CÌrbg½ßAhbVOÍwèÅ«
+ *	érbgÊuª0©ç7ÌÔÉûÜéæ¤ÉANZX·éAhXÉK
+ *	ªÁ¦çêéÌÅ cH+1(=13) ÆÈÁÄ¢é. Ü½, rbgtB[h
+ *	ÌÅºÊrbg©çÌrbgÊuÍ 6ÆÈé.
+ *	ÈãæèÌæ¤É­±ÆªÅ«é.
+ *
+ *		TCB_enatex	.equ	13
+ *		TCB_enatex_bit	.equ	 6
+ *		TCB_enatex_mask	.equ	40H
+ */
+
+#include "kernel_impl.h"
+#include "task.h"
+#include "sil.h"
+
+const TCB	____BEGIN_OFF_TCB_tstat = {
+		{ NULL, NULL }, NULL , 1, 0,
+		0, 0 , 0 , 0 , NULL , { NULL , NULL }
+	};
+
+const TCB	____BEGIN_OFF_TCB_tinib = {
+		{ NULL, NULL }, (TINIB *)1 , 0 , 0,
+		0, 0 , 0 , 0 , NULL , { NULL , NULL }
+	};
+
+const TCB	____BEGIN_OFF_TCB_pc = {
+		{ NULL, NULL }, NULL, 0, 0,
+		0, 0 , 0 , 0 , NULL , { NULL , (FP)1 }
+	};
+const TCB	____BEGIN_OFF_TCB_sp = {
+		{ NULL, NULL }, NULL, 0, 0,
+		0, 0 , 0 , 0 , NULL , { (void *)1 , NULL }
+	};
+
+const TCB	____BEGIN_BIT_TCB_enatex = {
+		{ NULL, NULL }, NULL, 0, 0,
+		0, 0 , 1 , 0 , NULL , { NULL , NULL }
+	};
+
+const TCB	____BEGIN_OFF_TCB_texptn = {
+		{ NULL, NULL }, NULL, 0, 0,
+		0 , 0 , 0 , 1 , NULL , { NULL , NULL }
+	};
+
+const TINIB	____BEGIN_OFF_TINIB_exinf = {
+		0 , (intptr_t)1 , NULL , 0 , 0 , NULL , 0 , NULL
+	};
+
+const TINIB	____BEGIN_OFF_TINIB_task = {
+		0 , NULL , (TASK)1 , 0 , 0 , NULL , 0 , NULL
+	};
+
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc.tf	(revision 164)
@@ -0,0 +1,363 @@
+$ 
+$  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
+$ 
+$  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$      XR[hÉÜÜêÄ¢é±ÆD
+$  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$      Ì³ÛØKèðfÚ·é±ÆD
+$  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$      ÆD
+$    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$        ñ·é±ÆD
+$  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$      ÆÓ·é±ÆD
+$ 
+$  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$  ÌÓCðíÈ¢D
+$ 
+$  @(#) $Id$
+$ 
+
+$ 
+$  A[LeN`Ë¶ev[giRX630pj
+$ 
+
+
+
+$ 
+$  ATT_ISRÅgpÅ«éÝÔÆ»êÉÎ·éÝnhÔ
+$ 
+
+$INTNO_ATTISR_VALID = INTNO_VALID$
+$INHNO_ATTISR_VALID = INHNO_VALID$
+
+
+$ 
+$  DEF_INT^DEF_EXCÅgpÅ«éÝnhÔ^CPUáOnhÔ
+$ 
+
+$INHNO_DEFINH_VALID = INHNO_VALID$
+$EXCNO_DEFEXC_VALID = EXCNO_VALID$
+
+
+$ 
+$  CFG_INTÅgpÅ«éÝÔÆÝDæx
+$ 
+
+$INTNO_CFGINT_VALID = INHNO_VALID$
+$INTPRI_CFGINT_VALID = { -7, -6,...,-1 }$
+
+
+$ 
+$  ^[QbgñË¶ÉÜÜêéWÌÝÇ@\/áOÇ@\Ìú»ðgp·é
+$ 
+
+$OMIT_INITIALIZE_INTERRUPT = 0$
+$OMIT_INITIALIZE_EXCEPTION = 0$
+
+
+$ 
+$  X^bNTCYÌ`FbNû@wè
+$ 
+
+$CHECK_STKSZ_ALIGN = 4$
+
+
+$ 
+$  ^XNX^bNTCYÌÅ¬l
+$ 
+$  ^XNN®É4byte,
+$  ÝüûÉÄ48byte, CPUáOüûÉÄ84byte,
+$  Å é½ß, Å¬lÍ88byteÆ·é.
+$ 
+
+$TARGET_MIN_STKSZ = 88$
+
+
+$ 
+$  èè`
+$ 
+
+$TA_POSEDGE = TA_EDGE$
+
+
+$ 
+$ ^[QbgË¶ÌÝ®«Ìè`
+$ 
+
+$TARGET_INTATR = TA_POSEDGE | TA_NEGEDGE | TA_BOTHEDGE | TA_LOWLEVEL$
+
+
+$ 
+$ ^[QbgË¶ÌÝnh®«Ìè`
+$ 
+
+$TARGET_INHATR = TA_NONKERNEL$
+
+
+$ 
+$ J[lÇOÝnhÍÅè³¹È¢½ß,
+$ INTNO_FIX_KERNEL
+$ INHNO_FIX_KERNEL
+$ INHNO_FIX_NONKERNEL
+$ INHNO_FIX_NONKERNEL
+$ ðè`µÈ¢.
+$ 
+
+
+$ 
+$  Wev[gt@CÌCN[h
+$ 
+$INCLUDE "kernel.tf"$
+
+
+
+$ 
+$  CFG_INTÌ^[QbgË¶ÌG[`FbN
+$ 
+
+$FOREACH intno INT.ORDER_LIST$
+$ IRQÝÔ©Ç¤©ð`FbN
+	$IF ( LENGTH( FIND( INTNO_INT, INT.INTNO[intno] ) ) != 0 )$
+
+$   TA_POSEDGEÆTA_NEGEDGEª¯ÉÝè³êÄ¢éê
+		$IF ((INT.INTATR[intno] & ( TA_POSEDGE | TA_NEGEDGE )) == ( TA_POSEDGE | TA_NEGEDGE ))$
+			$ERROR$ INT.TEXT_LINE[intno]:$FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "intatr", INT.INTATR[intno], INT.INTNO[intno], "CFG_INT")$$END$
+		$END$
+
+$   TA_POSEDGEÆTA_BOTHEDGEª¯ÉÝè³êÄ¢éê
+		$IF ((INT.INTATR[intno] & ( TA_POSEDGE | TA_BOTHEDGE )) == ( TA_POSEDGE | TA_BOTHEDGE ))$
+			$ERROR$ INT.TEXT_LINE[intno]:$FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "intatr", INT.INTATR[intno], INT.INTNO[intno], "CFG_INT")$$END$
+		$END$
+
+$   TA_NEGEDGEÆTA_BOTHEDGEª¯ÉÝè³êÄ¢éê
+		$IF ((INT.INTATR[intno] & ( TA_NEGEDGE | TA_BOTHEDGE )) == ( TA_NEGEDGE | TA_BOTHEDGE ))$
+			$ERROR$ INT.TEXT_LINE[intno]:$FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "intatr", INT.INTATR[intno], INT.INTNO[intno], "CFG_INT")$$END$
+		$END$
+
+$   TA_POSEDGEÆTA_NEGEDGEÆTA_BOTHEDGEª¯ÉÝè³êÄ¢éê
+		$IF ((INT.INTATR[intno] & ( TA_POSEDGE | TA_NEGEDGE | TA_BOTHEDGE )) == ( TA_POSEDGE | TA_NEGEDGE | TA_BOTHEDGE ))$
+			$ERROR$ INT.TEXT_LINE[intno]:$FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "intatr", INT.INTATR[intno], INT.INTNO[intno], "CFG_INT")$$END$
+		$END$
+
+	$ELSE$
+
+$   IRQÝÈOÌÝÉÎµÄÝ®«ªwè³êÄ¢éê
+		$IF (INT.INTATR[intno] & (~( TA_ENAINT | TA_EDGE ))) != 0$
+			$ERROR$ INT.TEXT_LINE[intno]: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "intatr", INT.INTATR[intno], INT.INTNO[intno], "CFG_INT")$$END$
+		$END$
+
+	$END$
+
+$END$
+
+
+
+$ 
+$ ÝÔ©çÝDæxyÑ®«ðæèo·e[u
+$ 
+
+/*$NL$
+$SPC$*$SPC$$SPC$Interrupt Level and Attribute Table$NL$
+$SPC$*/$NL$
+const CFG_INT_INFO _kernel_cfg_int_table[$LENGTH(INTNO_RANGE)$] = {$NL$
+$FOREACH intno INTNO_RANGE$
+$ ÝDæxðæ¾
+	$IF LENGTH(INT.INTNO[intno])$
+		$intpri = -INT.INTPRI[intno]$
+		$intatr = INT.INTATR[intno]$
+	$ELSE$
+		$intpri = "0"$
+		$intatr = "0xFFFFFFFF"$
+	$END$
+
+$ e[uÌgðoÍ
+	$TAB$$FORMAT("{ %2d, %08x }, /* %02u */", intpri, intatr, +intno)$$NL$
+$END$
+};$NL$$NL$
+
+
+$ 
+$  AZuoÍt@C
+$ 
+
+$FILE "kernel_cfg_asm.src"$
+
+;$NL$
+;  RX630A[LeN`Ë¶oÍt@C$NL$
+;$NL$
+;  ÝxN^yÑÝnhè`$NL$
+;$NL$
+$NL$$NL$
+
+
+$ 
+$  Ýüû
+$ 
+
+$ 
+$  ¤ÊÖÌé¾
+$ 
+
+$TAB$.section P, CODE$NL$
+$TAB$.glb$TAB$_kernel_interrupt$NL$
+$TAB$.glb$TAB$__kernel_default_int_handler$NL$
+$TAB$.glb$TAB$__kernel_default_exc_handler$NL$$NL$$NL$
+
+
+$ 
+$  ÝnhÌoÍ
+$ 
+
+$FOREACH inhno INHNO_RANGE$
+	$IF LENGTH(INH.INHNO[inhno])$
+		$IF ((INH.INHATR[inhno] & TA_NONKERNEL) == 0)$
+			$TAB$.glb	_$INH.INTHDR[inhno]$$NL$
+			$TAB$.glb	__kernel_$INH.INTHDR[inhno]$_$+INH.INHNO[inhno]$_entry$NL$
+			__kernel_$INH.INTHDR[inhno]$_$+INH.INHNO[inhno]$_entry:$NL$
+			$TAB$pushm	r1-r5						; XNb`WX^ð^XNX^bNÖÞð $NL$
+			$TAB$mov.l	#$+INH.INHNO[inhno]$, r1	; ÝnhÔðr1Ö $NL$
+			$TAB$mov.l	#_$INH.INTHDR[inhno]$, r2	; nhÌAhXðr2Ö $NL$
+			$TAB$bra.a	_kernel_interrupt			; ¤Ê[`Ö $NL$$NL$$NL$
+		$END$
+	$END$
+$END$
+
+
+$ ¢o^Ýnhüû
+$TAB$.glb$TAB$__kernel_default_int_handler_entry$NL$
+__kernel_default_int_handler_entry:$NL$
+$TAB$pushm	r1-r5								; XNb`WX^ð^XNX^bNÖÞð $NL$
+$TAB$mov.l	#0FFFFFFFFH, r1						; ÝnhÔðr1Ö $NL$
+$TAB$mov.l	#__kernel_default_int_handler, r2	; nhÌAhXðr2Ö $NL$
+$TAB$bra.a	_kernel_interrupt					; ¤Ê[`Ö $NL$$NL$$NL$
+
+
+$ 
+$  CPUáOnhüû
+$ 
+
+$TAB$.glb	_kernel_exception$NL$$NL$
+
+$FOREACH excno EXCNO_RANGE$
+	$IF LENGTH(EXC.EXCNO[excno])$
+		$TAB$.glb	_$EXC.EXCHDR[excno]$$NL$
+		$TAB$.glb	__kernel_$EXC.EXCHDR[excno]$_$+EXC.EXCNO[excno]$_entry$NL$
+		__kernel_$EXC.EXCHDR[excno]$_$+EXC.EXCNO[excno]$_entry:$NL$
+		$TAB$pushm	r1-r5						; XNb`WX^ð^XNX^bNÖÞð $NL$
+		$TAB$mov.l	#$+EXC.EXCNO[excno]$, r1	; CPUáOnhÔðr1Ö $NL$
+		$TAB$mov.l	#_$EXC.EXCHDR[excno]$, r2	; nhÌAhXðr2Ö $NL$
+		$TAB$bra.a	_kernel_exception			; ¤Ê[`Ö $NL$$NL$$NL$
+	$END$
+$END$
+
+
+$ ¢o^CPUáOnhüû
+$TAB$.glb$TAB$__kernel_default_exc_handler_entry$NL$
+__kernel_default_exc_handler_entry:$NL$
+$TAB$pushm	r1-r5								; XNb`WX^ð^XNX^bNÖÞð $NL$
+$TAB$mov.l	#0FFFFFFFFH, r1						; CPUáOnhÔðr1Ö $NL$
+$TAB$mov.l	#__kernel_default_exc_handler, r2	; nhÌAhXðr2Ö $NL$
+$TAB$bra.a	_kernel_exception					; ¤Ê[`Ö $NL$$NL$$NL$
+
+
+$ 
+$  ÂÏxN^e[u
+$ 
+
+;$NL$
+;  ÂÏxN^e[u$NL$
+;$NL$
+$NL$
+
+$TAB$.glb $TAB$ _start$NL$$NL$
+
+$FOREACH inhno INH.ORDER_LIST$
+	$IF ((INH.INHATR[inhno] & TA_NONKERNEL) != 0)$
+		$TAB$.glb $TAB$ _$INH.INTHDR[inhno]$ $NL$
+	$END$
+$END$
+$NL$
+
+$TAB$.section C$$VECT, ROMDATA$NL$$NL$
+vvector_table:$NL$
+$FOREACH inhno INHNO_RANGE$
+	$IF LENGTH(INH.INHNO[inhno])$
+		$IF ((INH.INHATR[inhno] & TA_NONKERNEL) == 0)$
+			$inhhdr = CONCAT(CONCAT("_kernel_" , CONCAT(INH.INTHDR[inhno] , "_")) , CONCAT(+INH.INHNO[inhno] , "_entry"))$
+		$ELSE$
+			$inhhdr = INH.INTHDR[inhno]$
+		$END$
+	$ELSE$
+		$inhhdr = "_kernel_default_int_handler_entry"$
+	$END$
+
+	$TAB$.lword$TAB$_$inhhdr$ $TAB$ $TAB$ $FORMAT("; %02d" , inhno)$ $NL$
+$END$
+
+
+$ 
+$  ÅèxN^e[u
+$ 
+$FOREACH excno EXCNO_RANGE$
+	$IF LENGTH(EXC.EXCNO[excno])$
+		$EXCHDR[excno] = CONCAT(CONCAT("_kernel_" , CONCAT(EXC.EXCHDR[excno] , "_")) , CONCAT(+EXC.EXCNO[excno] , "_entry"))$
+	$ELSE$
+		$EXCHDR[excno] = "_kernel_default_exc_handler_entry"$
+	$END$
+$END$
+
+$NL$
+;$NL$
+;  ÅèxN^e[u$NL$
+;$NL$
+$NL$
+
+$TAB$ .section FVECT, ROMDATA$NL$
+$NL$
+fvector_table:$NL$$NL$
+
+$TAB$ .offset$TAB$ 020H$NL$
+$TAB$ .lword$TAB$ 00000000 $TAB$ ; §äR[h, IDR[h1 - 3$NL$
+$TAB$ .lword$TAB$ 00000000 $TAB$ ; IDR[h4 - 7$NL$
+$TAB$ .lword$TAB$ 00000000 $TAB$ ; IDR[h8 - 11$NL$
+$TAB$ .lword$TAB$ 00000000 $TAB$ ; IDR[h12 - 15$NL$$NL$
+
+$TAB$ .offset$TAB$ 050H$NL$
+$TAB$ .lword$TAB$ _$EXCHDR[20]$ $TAB$ $TAB$ ;$SPC$ 20:Á ½ßáO $SPC$$NL$
+$TAB$ .offset$TAB$ 05CH$NL$
+$TAB$ .lword$TAB$ _$EXCHDR[23]$ $TAB$ $TAB$ ;$SPC$ 23:¢è`½ßáO $SPC$$NL$
+$TAB$ .offset$TAB$ 064H$NL$
+$TAB$ .lword$TAB$ _$EXCHDR[25]$ $TAB$ $TAB$ ;$SPC$ 25:®¬_áO $SPC$$NL$
+$TAB$ .offset$TAB$ 078H$NL$
+$TAB$ .lword$TAB$ _$EXCHDR[30]$ $TAB$ $TAB$ ;$SPC$ 30:m}XJuáO $SPC$$NL$
+$TAB$ .lword$TAB$ _start $TAB$ $TAB$ $TAB$ $TAB$ ;$SPC$ 31:Zbg $SPC$$NL$
+
+$NL$ $NL$
+
+	$TAB$.end
+$NL$
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_asm_config.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_asm_config.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_asm_config.tf	(revision 164)
@@ -0,0 +1,13 @@
+$ 
+$     asm_config.inc ¶¬p
+$     pX2ÌA[LeN`Ë¶ev[giRX630pj
+$ 
+
+$FILE "asm_config.inc"$
+
+
+TIPM_LOCK $TAB$$TAB$ .equ $TAB$ $+TIPM_LOCK$ $NL$
+IPL_LOCK $TAB$$TAB$ .equ $TAB$ $+IPL_LOCK$ $NL$
+PSW_I_MASK $TAB$$TAB$ .equ $TAB$ $+PSW_I_MASK$ $NL$
+PSW_IPL_MASK $TAB$$TAB$ .equ $TAB$ $+PSW_IPL_MASK$ $NL$
+EXC_GET_PSW_OFFSET $TAB$$TAB$ .equ $TAB$ $+EXC_GET_PSW_OFFSET$ $NL$
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_cfg1_out.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_cfg1_out.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_cfg1_out.h	(revision 164)
@@ -0,0 +1,48 @@
+/*
+ *		cfg1_out.cÌNÉKvÈX^uÌè`
+ */
+
+void sta_ker( void )
+{
+}
+
+void hardware_init_hook( void )
+{
+}
+
+void software_init_hook( void )
+{
+}
+
+const SIZE		_kernel_istksz = 0;
+
+STK_T *const	_kernel_istk = NULL;
+
+/*
+ *  ItZbgt@Cð¶¬·é½ßÌè`
+ */
+const uint8_t	MAGIC_1 = 0x12;
+const uint16_t	MAGIC_2 = 0x1234;
+const uint32_t	MAGIC_4 = 0x12345678;
+
+const TCB	TCB_enatex = {
+	{ NULL, NULL },			/* task_queue */
+	NULL,					/* p_tinib */
+	0U,						/* tstat */
+#ifdef TOPPERS_SUPPORT_MUTEX
+	0U,						/* bpriority */
+#endif /* TOPPERS_SUPPORT_MUTEX */
+	0U,						/* priority */
+	false,					/* acqeue */
+	false,					/* wupque */
+	true,					/* enatex */
+	0U,						/* texptn */
+	NULL,					/* p_winifo */
+#ifdef TOPPERS_SUPPORT_MUTEX
+	{ NULL, NULL },			/* mutex_queue */
+#endif /* TOPPERS_SUPPORT_MUTEX */
+#ifdef TOPPERS_SUPPORT_OVRHDR
+	0U,						/* leftotm */
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+	{ NULL, NULL }			/* tskctxb */
+};
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_check.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_check.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_check.tf	(revision 164)
@@ -0,0 +1,61 @@
+$ 
+$  TOPPERS/ASP Kernel
+$      Toyohashi Open Platform for Embedded Real-Time Systems/
+$      Advanced Standard Profile Kernel
+$ 
+$  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+$ 
+$  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$      XR[hÉÜÜêÄ¢é±ÆD
+$  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$      Ì³ÛØKèðfÚ·é±ÆD
+$  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$      ÆD
+$    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$        ñ·é±ÆD
+$  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$      ÆÓ·é±ÆD
+$ 
+$  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$  ÌÓCðíÈ¢D
+$ 
+$  @(#) $Id$
+$ 
+
+$ 
+$ 		pX3ÌvZbTË¶ev[giRX630pj
+$ 
+
+$ 
+$  `FbNû@Ìwè
+$ 
+$CHECK_FUNC_ALIGN = 1$
+$CHECK_FUNC_NONNULL = 1$
+$CHECK_STACK_ALIGN = 4$
+$CHECK_STACK_NONNULL = 1$
+$CHECK_MPF_ALIGN = 4$
+$CHECK_MPF_NONNULL = 1$
+
+$ 
+$  Wev[gt@CÌCN[h
+$ 
+$INCLUDE "kernel/kernel_check.tf"$
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_config.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_config.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_config.c	(revision 164)
@@ -0,0 +1,244 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		vZbTË¶W
+[iRX630pj
+ */
+
+#include "kernel_impl.h"
+#include "sil.h"
+
+
+/*
+ *  Ý­¶ñðÛ¶·éÏ
+ */
+uint16_t	intnest;
+
+/*
+ *  CPUbNtOÀ»Ì½ßÌÏ
+ */
+#if TIPM_LOCK != -15
+bool_t		lock_flag;		/* CPUbNtOÌlðÛ·éÏ */
+uint32_t	saved_ipl;		/* ÝDæxxðÛ¶·éÏ */
+#endif	/* TIPM_LOCK != -15	*/
+
+
+/*
+ *  vZbTË¶Ìú»
+ */
+void
+prc_initialize( void )
+{
+	/*
+	 *  Ý­¶ñÌú»
+	 *
+	 *  X^[gAbvÍSÝbNóÔ & ñ^XNReLXg
+	 *  ÉÄ®ì·é½ß, ñ^XNReLXgÉU·é.
+	 */
+	intnest = 1U;
+
+#if TIPM_LOCK != -15
+	/*
+	 *  CPUbNtOÀ»Ì½ßÌÏÌú»
+	 */
+	lock_flag = true;
+	saved_ipl = IPL_ENAALL;
+#endif	/* TIPM_LOCK != -15	*/
+}
+
+
+/*
+ *  vZbTË¶ÌI¹
+ */
+void
+prc_terminate( void )
+{
+	/*
+	 *  ÁÉKvÈÍÈ¢
+	 */
+}
+
+
+/*
+ *  CPUáOÌ­¶óµÌOoÍ
+ *
+ *  CPUáOnhÌ©çCCPUáOîñ|C^ip_excinfjðøÆµ
+ *  ÄÄÑo·±ÆÅCCPUáOÌ­¶óµðVXeOÉoÍ·éD
+ */
+#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 */
+
+
+/*
+ *  ÝvCÌ®«ÌÝè
+ *
+ *  ASPJ[lÅÌpðzèµÄCp[^G[ÍAT[VÅ`Fb
+ *  NµÄ¢éDcfg_intT[rXR[ðÝ¯éêÉÍCG[ðÔ·æ¤
+ *  É·×«Å ë¤D
+ */
+void
+x_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
+
+	/*
+	 *  ÝÌ}XN
+	 *
+	 *  Ýðó¯t¯½ÜÜCxgK^GbWgKÌÝèâC
+	 *  ÝDæxÌÝèðs¤ÌÍë¯È½ßCÝ®«É©©íç¸C
+	 *  êU}XN·éD
+	 */
+	( void )x_disable_int( intno );
+
+	/*
+	 *  xgK/GbWgKÌÝè
+	 *
+	 *  IRQÌÝT|[g·é
+	 */
+	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{
+			/*
+			 *  RtBM
+[^ÉÄ`FbNµÄ¢é½ß,
+			 *  ±±Ö­é±ÆÍ è¦È¢.
+			 */
+			irq_val = 0U;
+		}
+
+		sil_wrb_mem((uint8_t *)irqcr_reg_addr[irq_offset], irq_val);
+	}
+
+	/*
+	 *  ÝxÌÝè
+	 *
+	 *  ÝÔÉÎµ½IPRlðÝè·é.
+	 */
+	sil_wrb_mem((uint8_t *)ipr_reg_addr[intno], cfg_int_table[intno].intpri);
+
+	/*
+	 *  ÝÌ}XNð
+ 	 */
+	if( ( intatr & TA_ENAINT ) != 0U ){
+		( void )x_enable_int( intno );
+	}
+}
+
+
+#ifndef OMIT_DEFAULT_INT_HANDLER
+/*
+ *  ¢o^ÌÝª­¶µ½êÉÄÑo³êé
+ */
+void
+default_int_handler( void )
+{
+	syslog(LOG_EMERG, "Unregistered Interrupt occurs.");
+}
+#endif /* OMIT_DEFAULT_INT_HANDLER */
+
+#ifndef OMIT_DEFAULT_EXC_HANDLER
+/*
+ *  ¢o^ÌáOª­¶µ½êÉÄÑo³êé
+ */
+void
+default_exc_handler( void )
+{
+	syslog(LOG_EMERG, "Unregistered Expevt error occurs.");
+}
+#endif /* OMIT_DEFAULT_EXC_HANDLER */
+
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_config.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_config.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_config.h	(revision 164)
@@ -0,0 +1,718 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		vZbTË¶W
+[iRX630pj
+ *
+ *  ±ÌCN[ht@CÍCtarget_config.hiÜ½ÍC»±©çCN
+ *  [h³êét@CjÌÝ©çCN[h³êéD¼Ìt@C©ç
+ *  ¼ÚCN[hµÄÍÈçÈ¢D
+ */
+
+#ifndef TOPPERS_PRC_CONFIG_H
+#define TOPPERS_PRC_CONFIG_H
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  vZbTÌÁê½ßÌCCÖè`
+ */
+#include "prc_insn.h"
+#include "sil.h"
+
+
+/*
+ *  ñ^XNReLXgpÌX^bNúl
+ */
+
+//#define TOPPERS_ISTKPT( istk, istksz ) (( STK_T * )(( char * )( istk ) + ( istksz )))
+#define TOPPERS_ISTKPT( istk, istksz )  __secend("SI")
+
+/*
+ *  ^XNReLXgubNÌè`
+ */
+typedef struct task_context_block {
+	void	*sp;		/* X^bN|C^ */
+	FP		pc;			/* vOJE^ */
+} TSKCTXB;
+
+
+/*
+ *  Ý­¶ñðÛ¶·éÏ
+ */
+extern uint16_t intnest;
+
+
+/*
+ *  CPUbNóÔÅÌÝDæx}XN
+ *
+ *  TIPM_LOCKÍCCPUbNóÔÅÌÝDæx}XNC·Èí¿CJ[l
+ *  ÇOÌàÌð­·×ÄÌÝvð}XN·élÉè`·éD
+ *
+ *  TMIN_INTPRIÏX·é±ÆÅÇOÝÌL³ðè·éD
+ *  á¦ÎTMIN_INTPRIð-14ÉÝè·éÆCx15ÌÝªJ[lÇOÆ
+ *  ÈéDTMIN_INTPRIð-15ÉÝè·éÆCNMIÈOÉJ[lÇOÌÝð
+ *  Ý¯È¢±ÆÉÈéi±ÌêÉÍ-15ÉÝè·é±Æð§·éjD
+ */
+#ifndef TIPM_LOCK
+#define TIPM_LOCK	TMIN_INTPRI
+#endif /* TIPM_LOCK */
+
+
+/*
+ *  TOPPERSWÝfÌÀ»
+ */
+/*
+ *  ReLXgÌQÆ
+ *
+ *  RXÅÍCÝÌßèæª^XN©Ç¤©ð»f·é½ßÉ intnest
+ *  ðgpµÄ¢éD±êðp¢ÄReLXgð»f·éD
+ */
+Inline bool_t
+sense_context( void )
+{
+	/*  lXgJE^0æèåÈçñ^XNReLXg  */
+	return ( intnest > 0U );
+}
+
+
+/*
+ *  CPUbNtOÀ»Ì½ßÌÏ
+ *
+ *  ±êçÌÏÍCCPUbNóÔÌÌÝ«·¦Äæ¢àÌÆ·éD
+ */
+#if TIPM_LOCK != -15
+extern bool_t	lock_flag;		/* CPUbNtOÌlðÛ·éÏ */
+extern uint32_t	saved_ipl;		/* ÝDæxxðÛ¶·éÏ */
+#endif	/* TIPM_LOCK != -15	*/
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+
+/*
+ *  ÝDæx}XNÌO\»Æà\»ÌÏ·
+ *
+ *  RX630ÅÍCvZbTXe[^X[hWX^iPSWjÌº©ç
+ *  24`27rbgÚÌ4rbgÉÝDæxxiIPLjªu©êÄ¢éD
+ *  J[lÇOÝðÀ·éêÉIPLðgpµ½§äðs¤D
+ *  J[lÍÝDæx}XNi-1©çA±µ½ÌljÅÇ³êÄ
+ *  ¢é½ßIPLÆÌÏ·ªKvÆÈéD
+ */
+#define IPL_TO_IPM( ipl )	(-(( PRI )(( ipl ) >> 24U )))		/* IPLðIPMÉ	*/
+#define IPM_TO_IPL( ipm )	((( uint32_t )(-( ipm ))) << 24U )	/* IPMðIPLÉ	*/
+
+
+/*
+ *  CPUbNóÔÅÌÝDæx}XNÌIPL
+ */
+#define IPL_LOCK		( IPM_TO_IPL( TIPM_LOCK ) )
+
+/*
+ *  TIPM_ENAALLiÝDæx}XNSðjÌIPL
+ */
+#define IPL_ENAALL		( IPM_TO_IPL( TIPM_ENAALL ) )
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  ÝvöÌx & ®«è`e[u
+ *  (ev[gt@CÉæéoÍ)
+ */
+typedef struct cfg_int_info {
+	PRI		intpri;
+	ATR		intatr;
+} CFG_INT_INFO;
+
+extern const CFG_INT_INFO cfg_int_table[];
+
+
+/*
+ *  ÝÔÌÍÍÌ»è
+ *
+ *  ÝÔªLøÈl©µ§É`FbN·é½ß,
+ *  RtBM
+[^oÍe[uðQÆ·é.
+ */
+#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ÅLøÈÝÔÌwè  */
+#define VALID_INTNO_CREINT          VALID_INTNO_CFGINT((intno))
+
+/* cre_isrÅLøÈÝÔÌwè  */
+#define	VALID_INTNO_CREISR(intno)	VALID_INTNO_CFGINT((intno))
+
+
+/*
+ *  Ý§äWX^ÖAÌè`
+ */
+#define	IRQ_POSEDGE			( 0x08U )
+#define	IRQ_NEGEDGE			( 0x04U )
+#define	IRQ_BOTHEDGE		( 0x0CU )
+#define	IRQ_LOWLEVEL		( 0x00U )
+
+
+/*
+ *  CPUbNóÔÖÌÚs
+ *
+ *  IPMin[hEFAÌÝDæx}XNjðCsaved_iipmÉÛ¶µCJ[
+ *  lÇOÌàÌð­·×ÄÌÝvð}XN·éliTIPM_LOCKj
+ *  ÉÝè·éDÜ½Clock_flagðTRUEÉ·éD
+ *
+ *  IPMªCÅ©çTIPM_LOCKÆ¯¶©»êæè¢êÉÍC»êð
+ *  saved_iipmÉÛ¶·éÌÝÅCTIPM_LOCKÉÍÝèµÈ¢D±êÍCf
+ *  ãÌÝDæx}XNªCTIPM_LOCKÆ¯¶©»êæè¢xÉÝè
+ *  ³êÄ¢éóÔÉ ½éD
+ *
+ *  ±ÌÖÍCCPUbNóÔilock_flagªTRUEÌóÔjÅÄÎêé±ÆÍ
+ *  È¢àÌÆzèµÄ¢éD
+ */
+Inline void
+x_lock_cpu( void )
+{
+#if TIPM_LOCK == -15
+	disint();
+#else	/* TIPM_LOCK == -15	*/
+	uint32_t	ipl;
+
+	/*
+	 *  current_ipl()ÌÔèlð¼Úsaved_iplÉÛ¶¹¸CêÏipl
+	 *  ðp¢Ä¢éÌÍCcurrent_ipl()ðÄñ¾¼ãÉÝª­¶µC
+	 *  N®³ê½ÝÅsaved_iplªÏX³êéÂ\«ª é½ßÅ
+	 *   éD
+	 */
+	ipl = current_ipl();
+	if( IPL_LOCK > ipl ){
+		set_ipl( IPL_LOCK );
+	}
+
+	saved_ipl = ipl;
+	lock_flag = true;
+#endif	/* TIPM_LOCK == -15	*/
+}
+
+#define t_lock_cpu()	x_lock_cpu()
+#define i_lock_cpu()	x_lock_cpu()
+
+
+/*
+ *  CPUbNóÔÌð
+ *
+ *  lock_flagðFALSEÉµCIPMin[hEFAÌÝDæx}XNjðC
+ *  saved_iipmÉÛ¶µ½lÉß·D
+ *
+ *  ±ÌÖÍCCPUbNóÔilock_flagªtrueÌóÔjÅÌÝÄÎêéà
+ *  ÌÆzèµÄ¢éD
+ */
+Inline void
+x_unlock_cpu( void )
+{
+#if TIPM_LOCK == -15
+	enaint();
+#else	/* TIPM_LOCK == -15	*/
+	lock_flag = false;
+	set_ipl( saved_ipl );
+#endif	/* TIPM_LOCK == -15	*/
+}
+
+#define t_unlock_cpu()	x_unlock_cpu()
+#define i_unlock_cpu()	x_unlock_cpu()
+
+
+/*
+ *  CPUbNóÔÌQÆ
+ */
+Inline bool_t
+x_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	*/
+}
+
+#define t_sense_lock()	x_sense_lock()
+#define i_sense_lock()	x_sense_lock()
+
+
+/*
+ * ifãÌjÝDæx}XNÌÝè
+ *
+ *  CPUbNtOªNA³êÄ¢éÍCn[hEFAÌÝDæx}
+ *  XNðÝè·éDCPUbNtOªZbg³êÄ¢éÍCsaved_iipm
+ *  ðÝèµC³çÉCn[hEFAÌÝDæx}XNðCÝèµæ¤Æ
+ *  µ½ifãÌjÝDæx}XNÆTIPM_LOCKÌ¢ûÉÝè·éD
+ */
+Inline void
+x_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	*/
+}
+
+#define t_set_ipm( intpri )	x_set_ipm( intpri )
+#define i_set_ipm( intpri )	x_set_ipm( intpri )
+
+
+/*
+ * ifãÌjÝDæx}XNÌQÆ
+ *
+ *  CPUbNtOªNA³êÄ¢éÍn[hEFAÌÝDæx}
+ *  XNðCZbg³êÄ¢éÍsaved_iipmðQÆ·éD
+ */
+Inline PRI
+x_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 );
+}
+
+#define t_get_ipm()		x_get_ipm()
+#define i_get_ipm()		x_get_ipm()
+
+
+/*
+ *  ÝvÖ~tOÌZbg
+ *
+ *  Ý®«ªÝè³êÄ¢È¢ÝvCÉÎµÄÝvÖ~
+ *  tOðZbgµæ¤Æµ½êÉÍCFALSEðÔ·D
+ */
+Inline bool_t
+x_disable_int( INTNO intno )
+{
+	/*
+	 *  xè`ª0Å éêÍCFG_INT³êÄ¢È¢
+	 */
+	if( cfg_int_table[intno].intpri == 0 ){
+		return ( false );
+	}
+
+	*ier_reg_addr[intno].addr &= ( ~ier_reg_addr[intno].offset );
+
+	return ( true );
+}
+
+#define t_disable_int( intno )	x_disable_int( intno )
+#define i_disable_int( intno )	x_disable_int( intno )
+
+
+/*
+ *  ÝvÖ~tOÌNA
+ *
+ *  Ý®«ªÝè³êÄ¢È¢ÝvCÉÎµÄÝvÖ~
+ *  tOðNAµæ¤Æµ½êÉÍCFALSEðÔ·D
+ */
+Inline bool_t
+x_enable_int( INTNO intno )
+{
+	/*
+	 *  xè`ª0Å éêÍCFG_INT³êÄ¢È¢
+	 */
+	if( cfg_int_table[intno].intpri == 0 ){
+		return ( false );
+	}
+
+	*ier_reg_addr[intno].addr |= ier_reg_addr[intno].offset;
+
+	return ( true );
+}
+
+#define t_enable_int( intno )	x_enable_int( intno )
+#define i_enable_int( intno )	x_enable_int( intno )
+
+
+/*
+ *  ÝvÌNA
+ */
+Inline void
+x_clear_int( INTNO intno )
+{
+	*IR_REG(intno) = 0U;
+}
+
+#define t_clear_int( intno )	x_clear_int( intno )
+#define i_clear_int( intno )	x_clear_int( intno )
+
+
+/*
+ *  ÝvÌ`FbN
+ */
+Inline bool_t
+x_probe_int( INTNO intno )
+{
+	/*
+	 *  ÝvWX^Í0 or 1Åµ©È¢½ß,
+	 *  »ÌÜÜÌlðÔ·.
+	 */
+	return ( *IR_REG(intno) );
+}
+
+#define t_probe_int( intno )	x_probe_int( intno )
+#define i_probe_int( intno )	x_probe_int( intno )
+
+
+/*
+ *  ÝvCÌ®«ÌÝè
+ */
+extern void	x_config_int( INTNO intno, ATR intatr, PRI intpri );
+
+
+/*
+ *  ÝnhÌüûÅKvÈIRCì
+ *
+ */
+Inline void
+i_begin_int( INTNO intno )
+{
+	volatile uint8_t	reg;
+
+	/*
+	 *  xoÌÝÉÎµÄÍÝXe[^X
+	 *  tOðNA·é.
+	 */
+	if( ( cfg_int_table[intno].intatr & TA_LOWLEVEL ) > 0 ){
+		if( *IR_REG(intno) > 0U ){
+			/*
+			 *  OÝÌê, IRQ[qªHighÉßÁÄ¢é
+			 *  ±ÆðmF·é|ªLÚ³êÄ¢éª, Èª·é.
+			 */
+		//	*ir_reg_addr[intno] = 0U;
+
+			/*
+			 *  n[hEFA}j
+AÉ0ÉÈÁ½±Æð
+			 *  mF·é|ªLÚ é½ß, WX^lðÇÝo·.
+			 */
+		//	reg = *ir_reg_addr[intno];
+		}
+	}
+}
+
+
+/*
+ *  ÝnhÌoûÅKvÈIRCì
+ *
+ */
+Inline void
+i_end_int( INTNO intno )
+{
+	/* ÁÉs¤×«ÍÈ¢ */
+}
+
+
+/*
+ *  ÅDæÊ^XNÖÌfBXpb`iprc_support.a30j
+ *
+ *  dispatchÍC^XNReLXg©çÄÑo³ê½T[rXR[©
+ *  çÄÑo·×«àÌÅC^XNReLXgECPUbNóÔEfBXpb
+ *  `ÂóÔEifãÌjÝDæx}XNSðóÔÅÄÑo³È
+ *  ¯êÎÈçÈ¢D
+ */
+extern void	dispatch( void );
+
+/*
+ *  fBXpb`Ì®ìJniprc_support.a30j
+ *
+ *  start_dispatchÍCJ[lN®ÉÄÑo·×«àÌÅC·×ÄÌ
+ *  ÝðÖ~µ½óÔiSÝbNóÔÆ¯ÌóÔjÅÄÑo³È¯êÎ
+ *  ÈçÈ¢D
+ */
+extern void	start_dispatch( void ) NoReturn;
+
+/*
+ *  »ÝÌReLXgðÌÄÄfBXpb`iprc_support.a30j
+ *
+ *  exit_and_dispatchÍCext_tsk©çÄÑo·×«àÌÅC^XNReL
+ *  XgECPUbNóÔEfBXpb`ÂóÔEifãÌjÝDæ
+ *  x}XNSðóÔÅÄÑo³È¯êÎÈçÈ¢D
+ */
+#define _kernel_exit_and_dispatch();	\
+	_exit_and_dispatch();		\
+	ercd = E_SYS;
+
+extern void	_exit_and_dispatch( void ) NoReturn;
+
+/*
+ *  J[lÌI¹ÌÄoµiprc_support.a30j
+ *
+ *  call_exit_kernelÍCJ[lÌI¹ÉÄÑo·×«àÌÅCñ^XN
+ *  ReLXgÉØè·¦ÄCJ[lÌI¹iexit_kerneljðÄÑo
+ *  ·D
+ */
+extern void call_exit_kernel( void ) NoReturn;
+
+/*
+ *  ^XNReLXgÌú»
+ *
+ *  ^XNªx~óÔ©çÀsÅ«éóÔÉÚs·éÉÄÎêéD±Ì_
+ *  ÅX^bNÌæðgÁÄÍÈçÈ¢D
+ *
+ *  activate_contextðCCCÖÅÍÈ­}Nè`ÆµÄ¢éÌÍC
+ *  ±Ì_ÅÍTCBªè`³êÄ¢È¢½ßÅ éD
+ */
+extern void	start_r( void );
+
+#define activate_context( p_tcb )														\
+{																						\
+	{																					\
+																						\
+		/*  X^bN|C^úlÌÝè  */											\
+		( p_tcb )->tskctxb.sp = ( void * )((( uint32_t ) ( p_tcb )->p_tinib->stk ) + 	\
+								( p_tcb )->p_tinib->stksz );							\
+		/* N®ÔnÌÝè */															\
+		( p_tcb )->tskctxb.pc = ( FP ) start_r;											\
+	}																					\
+}
+
+
+/*
+ *  calltexÍgpµÈ¢
+ */
+#define OMIT_CALLTEX
+
+
+/*
+ *  ÝnhÌÝè
+ *
+ *  RX630ÍROMÉÝxN^ðzu·é½ßC{ÖÍóÖÅÀ·éD
+ */
+Inline void
+x_define_inh( INHNO inhno, FP inthdr )
+{
+}
+
+
+/*
+ *  CPUáOnhÌÝè
+ *
+ *  RX630ÍROMÉáOxN^ðzu·é½ßC{ÖÍóÖÅÀ·éD
+ */
+Inline void
+x_define_exc( EXCNO excno, FP exchdr )
+{
+}
+
+
+/*
+ *  Ý/áOnhÌüûÌ¶¬}N
+ *
+ *  ev[gt@CÉæè¶¬·é½ßó}NÆ·éD
+ */
+#define HDR_ENTRY(hdr, intexc_num , tobejmp)
+
+/*
+ *  ÝnhÌüûÌ¶¬}N
+ */
+#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 _kernel_##inthdr##_##inhno##_entry(void);
+#define INTHDR_ENTRY(inhno, inhno_num ,inthdr)	_INTHDR_ENTRY(inhno, inhno_num ,inthdr)
+
+
+/*
+ *  CPUáOnhÌüûÌ¶¬}N
+ */
+#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 _kernel_##exchdr##_##excno##_entry(void);
+#define EXCHDR_ENTRY(excno , excno_num , exchdr)	_EXCHDR_ENTRY(excno , excno_num , exchdr)
+
+
+/*
+ *  CPUáOÌ­¶µ½ÌReLXgÌQÆ
+ *
+ *  CPUáOÌ­¶µ½ÌReLXgªC^XNReLXgÌÉFALSEC
+ *  »¤ÅÈ¢ÉtrueðÔ·D
+ */
+Inline bool_t
+exc_sense_context( void *p_excinf )
+{
+	/* 
+	 *  lXgJE^ª1æèåÈçñ^XNReLXg
+	 */
+	return( intnest > 1U );
+}
+
+
+/*
+ *  CPUáOîñ p_excinf ©ç PSW Ìlðæ¾·é½ßÌItZbgl
+ *  EXCNO + ACC + FPSW + R1`R15 + PC
+ */
+#define EXC_GET_PSW_OFFSET	(4+8+4+60+4)
+
+/*
+ *  CPUáOÌ­¶µ½ÌIPLÌQÆ
+ */
+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áOÌ­¶µ½ÌReLXgÆÝÌ}XNóÔÌQÆ
+ *
+ *  CPUáOÌ­¶µ½ÌVXeóÔªCJ[lÀsÅÈ­C^XNR
+ *  eLXgÅ èCSÝbNóÔÅÈ­CCPUbNóÔÅÈ­Ci
+ *  fãÌjÝDæx}XNSðóÔÅ éÉtrueC»¤ÅÈ¢
+ *  ÉFALSEðÔ·iCPUáOªJ[lÇOÌÝÅ­¶µ½ê
+ *  ÉàFALSEðÔ·jD
+ *  
+ *  J[lÀsÅÈ¢¨ (TIPM_LOCK== -15) ItO == 1
+ *                         (else)           IPL < IPL_LOCK
+ *  ^XNReLXgÅ é¨intnest == 0
+ *  SÝbNÅÈ¢¨ ItO == 1
+ *  ÝDæx}XNªSð¨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áOÌ­¶µ½ÌReLXgÆÝ^CPUbNóÔÌQÆ
+ *
+ *  CPUáOÌ­¶µ½ÌVXeóÔªCJ[lÀsÅÈ­C^XNR
+ *  eLXgÅ èCSÝbNóÔÅÈ­CCPUbNóÔÅÈ¢É
+ *  trueC»¤ÅÈ¢ÉfalseðÔ·iCPUáOªJ[lÇOÌÝ
+ *  Å­¶µ½êÉàfalseðÔ·jD
+ *  
+ *  J[lÀsÅÈ¢¨ (TIPM_LOCK== -15) ItO == 1
+ *                         (else)           IPL < TIPM_LOCK
+ *  ^XNReLXgÅ é¨intnest < 1 
+ *  SÝbNÅÈ¢¨ ItO == 1
+ *  CPUbNóÔÅÈ¢¨(TIPM_LOCK== -15) ItO == 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
+}
+
+
+/*
+ *  vZbTË¶Ìú»
+ */
+extern void	prc_initialize( void );
+
+/*
+ *  vZbTË¶ÌI¹
+ */
+extern void	prc_terminate( void );
+
+
+#ifndef OMIT_DEFAULT_INT_HANDLER
+/*
+ *  ¢o^ÌÝª­¶µ½êÉÄÑo³êé
+ */
+void default_int_handler( void );
+#endif /* OMIT_DEFAULT_INT_HANDLER */
+
+#ifndef OMIT_DEFAULT_EXC_HANDLER
+/*
+ *  ¢o^ÌáOª­¶µ½êÉÄÑo³êé
+ */
+void default_exc_handler( void );
+#endif /* OMIT_DEFAULT_EXC_HANDLER */
+
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif /* TOPPERS_PRC_CONFIG_H */
+
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_def.csv
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_def.csv	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_def.csv	(revision 164)
@@ -0,0 +1,13 @@
+TA_LOWLEVEL,TA_LOWLEVEL
+TA_BOTHEDGE,TA_BOTHEDGE
+TA_NEGEDGE,TA_NEGEDGE
+TIPM_LOCK,TIPM_LOCK,signed
+IPL_LOCK,IPL_LOCK
+PSW_I_MASK,PSW_I_MASK
+PSW_IPL_MASK,PSW_IPL_MASK
+EXC_GET_PSW_OFFSET,EXC_GET_PSW_OFFSET
+sizeof_TCB,sizeof(TCB)
+offsetof_TCB_p_tinib,"offsetof(TCB,p_tinib)"
+offsetof_TCB_texptn,"offsetof(TCB,texptn)"
+offsetof_TCB_sp,"offsetof(TCB,tskctxb.sp)"
+offsetof_TCB_pc,"offsetof(TCB,tskctxb.pc)"
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_insn.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_insn.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_insn.h	(revision 164)
@@ -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,2006 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		vZbTÌÁê½ßÌCCÖè`iRX630pj
+ */
+
+#ifndef	TOPPERS_PRC_INSN_H
+#define	TOPPERS_PRC_INSN_H
+
+
+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 );
+
+
+/*
+ *  ItO, IPLðæ¾·é½ßÌ}Nè`
+ */
+#define PSW_I_MASK		( 0x00010000UL )
+#define PSW_IPL_MASK	( 0x0F000000UL )
+
+
+/*
+ *  vZbTXe[^XWX^(PSW)Ì»ÝlÌÇoµ
+ */
+#pragma inline_asm	current_psw
+static uint32_t
+current_psw( void )
+{
+	mvfc	psw, r1
+}
+
+
+/*
+ *  vZbTXe[^XWX^(PSW)ÖÝè
+ */
+#pragma inline_asm	set_psw
+static void
+set_psw( uint32_t psw )
+{
+	mvtc	r1, psw
+}
+
+
+/*
+ *  IPLÌ»ÝlÌÇoµ
+ */
+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ð­·×ÄÌÝÌÖ~
+ */
+#pragma inline_asm	disint
+static void
+disint( void )
+{
+	clrpsw	i
+}
+
+
+/*
+ *  NMIð­·×ÄÌÝÌÂ
+ */
+#pragma inline_asm	enaint
+static void
+enaint( void )
+{
+	setpsw	i
+}
+
+
+/*
+ *  GfBAÏ· 16bit
+ */
+#pragma inline_asm	rev_endian_uint16
+static uint16_t
+rev_endian_uint16( uint16_t data )
+{
+	revw	r1, r1
+}
+
+/*
+ *  GfBAÏ· 32bit
+ */
+#pragma inline_asm	rev_endian_uint32
+static uint32_t
+rev_endian_uint32( uint32_t data )
+{
+	revl	r1, r1
+}
+
+
+#endif /* TOPPERS_PRC_INSN_H */
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_kernel.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_kernel.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_kernel.h	(revision 164)
@@ -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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		kernel.hÌvZbTË¶iRX630pj
+ *
+ *  ±ÌCN[ht@CÍCtarget_kernel.hiÜ½ÍC»±©çCN
+ *  [h³êét@CjÌÝ©çCN[h³êéD¼Ìt@C©ç
+ *  ¼ÚCN[hµÄÍÈçÈ¢D
+ */
+
+#ifndef TOPPERS_PRC_KERNEL_H
+#define TOPPERS_PRC_KERNEL_H
+
+/*
+ *  J[l{ÌðRpC·é½ßÌ}Nè`
+ *
+ *  {Â«ÅÍ1Öð1IuWFNgt@CÉRpC·é±ÆªÅ«È¢½ßC
+ *  ALLFUNC}Nðè`·éD
+ */
+#define ALLFUNC
+
+
+/*
+ *  T|[g·é@\Ìè`
+ */
+#define TOPPERS_TARGET_SUPPORT_DIS_INT		/* dis_intðT|[g·é */
+#define TOPPERS_TARGET_SUPPORT_ENA_INT		/* ena_intðT|[g·é */
+
+
+/*
+ *  J[lÇÌÝDæxÌÍÍ
+ *
+ *  TMIN_INTPRIÌè`ðÏX·é±ÆÅCÇÌxæèà¢ÝDæx
+ *  ðÂàÌðJ[lÇOÌÝÆ·é©ðÏXÅ«éD
+ *
+ *  TMIN_INTPRIÉÝèÅ«élÍC-15`-1ÌÍÍÅ éDá¦ÎTMIN_INTPRI
+ *  ð-14ÉÝè·éÆCNMIÉÁ¦Äx7ÌÝªJ[lÇOÆÈéD
+ *  TMIN_INTPRIð-15ÉÝè·éÆCNMIÈOÉJ[lÇOÌÝð
+ *  Ý¯È¢±ÆÉÈéD
+ */
+#ifndef TMIN_INTPRI
+#define TMIN_INTPRI		( -15 )		/* ÝDæxÌÅ¬liÅlj*/
+#endif /* TMIN_INTPRI */
+#define TMAX_INTPRI		( -1 )		/* ÝDæxÌÅåliÅálj */
+
+
+/*
+ *  Ý®«Ìè`
+ */
+#define	TA_POSEDGE		TA_EDGE			/* |WeBuGbWgK */
+#define	TA_NEGEDGE		UINT_C( 0x04 )	/* lKeBuGbWgK */
+#define	TA_BOTHEDGE		UINT_C( 0x08 )	/* ¼GbWgK */
+
+#define	TA_LOWLEVEL		UINT_C( 0x10 )	/* Lx */
+
+
+/*
+ *  ftHgÌÝ/áOnhÌL³
+ */
+/*#define	OMIT_DEFAULT_INT_HANDLER*/
+/*#define	OMIT_DEFAULT_EXC_HANDLER*/
+
+
+#endif /* TOPPERS_PRC_KERNEL_H */
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_offset.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_offset.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_offset.tf	(revision 164)
@@ -0,0 +1,19 @@
+$ 
+$ 		ItZbgt@C¶¬pev[gt@CiRX630pj
+$ 
+
+$ 
+$  ItZbglÌ}Nè`Ì¶¬
+$ 
+$DEFINE("TCB_p_tinib", offsetof_TCB_p_tinib)$
+$DEFINE("TCB_texptn", offsetof_TCB_texptn)$
+$DEFINE("TCB_sp", offsetof_TCB_sp)$
+$DEFINE("TCB_pc", offsetof_TCB_pc)$
+
+$DEFINE("TINIB_exinf", offsetof_TINIB_exinf)$
+$DEFINE("TINIB_task", offsetof_TINIB_task)$
+
+$ 
+$  rbgItZbglÌ}Nè`Ì¶¬
+$ 
+$DEFINE_BIT("TCB_enatex", sizeof_TCB, "B")$
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_rename.def
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_rename.def	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_rename.def	(revision 164)
@@ -0,0 +1,27 @@
+# prc_config.c
+intnest
+lock_flag
+saved_ipl
+prc_initialize
+prc_terminate
+x_config_int
+default_int_handler
+default_exc_handler
+
+# prc_support.src
+dispatch
+start_dispatch
+exit_and_dispatch
+call_exit_kernel
+start_r
+interrupt
+exception
+
+# rx610_config.c
+ipr_reg_addr
+ier_reg_addr
+ir_reg_addr
+irqcr_reg_addr
+
+# kernel_cfg.c
+cfg_int_table
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_rename.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_rename.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_rename.h	(revision 164)
@@ -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_config.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 x_config_int				_kernel_x_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_config.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_config.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 _x_config_int				__kernel_x_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_config.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: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_sil.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_sil.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_sil.h	(revision 164)
@@ -0,0 +1,310 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		sil.hÌvZbTË¶iRX630pj
+ */
+
+#ifndef TOPPERS_PRC_SIL_H
+#define TOPPERS_PRC_SIL_H
+
+#define TOPPERS_OMIT_SIL_ACCESS
+
+#ifndef TOPPERS_MACRO_ONLY
+#include "prc_insn.h"
+
+
+/*
+ *  SÝÖ~
+ */
+Inline uint32_t
+TOPPERS_disint( void )
+{
+	volatile uint32_t	TOPPERS_psw;
+
+	TOPPERS_psw = current_psw();
+	disint();
+
+	return( TOPPERS_psw );
+}
+
+
+/*
+ *  SÝÂ
+ */
+Inline void
+TOPPERS_enaint( uint32_t TOPPERS_psw )
+{
+	if( TOPPERS_psw & PSW_I_MASK ){
+		enaint();
+	}
+}
+
+
+/*
+ *  SÝbNóÔÌ§ä
+ */
+#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 ) )
+
+
+/*
+ *  GfBAÌ½]
+ *
+ *  {J­Â«ÅÍGfBAÏ·½ßª¶Ý·é½ß,
+ *  A[LeN`Ë¶ÉÄ}Nðã«·é.
+ */
+#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 );
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+
+/*
+ *  vZbTÌGfBA
+ */
+#ifdef __LIT
+#define SIL_ENDIAN_LITTLE			/* gGfBA */
+#endif
+#ifdef __BIG
+#define SIL_ENDIAN_BIG				/* rbOGfBA */
+#endif
+
+
+/*
+ *  8rbgPÊÌÇoµ^Ý
+ */
+#ifdef UINT8_MAX
+
+#pragma inline(sil_reb_mem)
+static uint8_t
+sil_reb_mem(const volatile uint8_t __evenaccess *mem)
+{
+	uint8_t	data;
+
+	data = *mem;
+	return(data);
+}
+
+#pragma inline(sil_wrb_mem)
+static void
+sil_wrb_mem(volatile uint8_t __evenaccess *mem, uint8_t data)
+{
+	*mem = data;
+}
+
+#endif /* UINT8_MAX */
+
+/*
+ *  16rbgPÊÌÇoµ^Ý
+ */
+
+#pragma inline(sil_reh_mem)
+static uint16_t
+sil_reh_mem(const volatile uint16_t __evenaccess *mem)
+{
+	uint16_t	data;
+
+	data = *mem;
+	return(data);
+}
+
+#pragma inline(sil_wrh_mem)
+static void
+sil_wrh_mem(volatile uint16_t __evenaccess *mem, uint16_t data)
+{
+	*mem = data;
+}
+
+#ifdef SIL_ENDIAN_BIG			/* rbOGfBAvZbT */
+
+#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
+
+#pragma inline(sil_reh_lem)
+static uint16_t
+sil_reh_lem(const volatile uint16_t __evenaccess *mem)
+{
+	uint16_t	data;
+
+	data = *mem;
+	return(TOPPERS_SIL_REV_ENDIAN_UINT16(data));
+}
+
+#endif /* TOPPERS_OMIT_SIL_REH_LEM */
+#ifndef TOPPERS_OMIT_SIL_WRH_LEM
+
+#pragma inline(sil_wrh_lem)
+static void
+sil_wrh_lem(volatile uint16_t __evenaccess *mem, uint16_t data)
+{
+	*mem = TOPPERS_SIL_REV_ENDIAN_UINT16(data);
+}
+
+#endif /* TOPPERS_OMIT_SIL_WRH_LEM */
+#else /* SIL_ENDIAN_BIG */
+#ifdef SIL_ENDIAN_LITTLE		/* gGfBAvZbT */
+
+#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
+
+#pragma inline(sil_reh_bem)
+static uint16_t
+sil_reh_bem(const volatile uint16_t __evenaccess *mem)
+{
+	uint16_t	data;
+
+	data = *mem;
+	return(TOPPERS_SIL_REV_ENDIAN_UINT16(data));
+}
+
+#endif /* TOPPERS_OMIT_SIL_REH_BEM */
+#ifndef TOPPERS_OMIT_SIL_WRH_BEM
+
+#pragma inline(sil_wrh_bem)
+static void
+sil_wrh_bem(volatile uint16_t __evenaccess *mem, uint16_t data)
+{
+	*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 */
+
+/*
+ *  32rbgPÊÌÇoµ^Ý
+ */
+
+#pragma inline(sil_rew_mem)
+static uint32_t
+sil_rew_mem(const volatile uint32_t __evenaccess *mem)
+{
+	uint32_t	data;
+
+	data = *mem;
+	return(data);
+}
+
+#pragma inline(sil_wrw_mem)
+static void
+sil_wrw_mem(volatile uint32_t __evenaccess *mem, uint32_t data)
+{
+	*mem = data;
+}
+
+#ifdef SIL_ENDIAN_BIG			/* rbOGfBAvZbT */
+
+#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
+
+#pragma inline(sil_rew_lem)
+static uint32_t
+sil_rew_lem(const volatile uint32_t __evenaccess *mem)
+{
+	uint32_t	data;
+
+	data = *mem;
+	return(TOPPERS_SIL_REV_ENDIAN_UINT32(data));
+}
+
+#endif /* TOPPERS_OMIT_SIL_REW_LEM */
+#ifndef TOPPERS_OMIT_SIL_WRW_LEM
+
+#pragma inline(sil_wrw_lem)
+static void
+sil_wrw_lem(volatile uint32_t __evenaccess *mem, uint32_t data)
+{
+	*mem = TOPPERS_SIL_REV_ENDIAN_UINT32(data);
+}
+
+#endif /* TOPPERS_OMIT_SIL_WRW_LEM */
+#else /* SIL_ENDIAN_BIG */		/* gGfBAvZbT */
+
+#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
+
+#pragma inline(sil_rew_bem)
+static uint32_t
+sil_rew_bem(const volatile uint32_t __evenaccess *mem)
+{
+	uint32_t	data;
+
+	data = *mem;
+	return(TOPPERS_SIL_REV_ENDIAN_UINT32(data));
+}
+
+#endif /* TOPPERS_OMIT_SIL_REW_BEM */
+#ifndef TOPPERS_OMIT_SIL_WRW_BEM
+
+#pragma inline(sil_wrw_bem)
+static void
+sil_wrw_bem(volatile uint32_t __evenaccess *mem, uint32_t data)
+{
+	*mem = TOPPERS_SIL_REV_ENDIAN_UINT32(data);
+}
+
+#endif /* TOPPERS_OMIT_SIL_WRW_BEM */
+#endif /* SIL_ENDIAN_BIG */
+
+#endif /* TOPPERS_PRC_SIL_H */
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_stddef.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_stddef.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_stddef.h	(revision 164)
@@ -0,0 +1,59 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		t_stddef.hÌvZbTË¶iRX630pj
+ *
+ *  ±ÌCN[ht@CÍCtarget_stddef.hiÜ½ÍC»±©çCN
+ *  [h³êét@CjÌÝ©çCN[h³êéD¼Ìt@C©ç
+ *  ¼ÚCN[hµÄÍÈçÈ¢D
+ */
+
+#ifndef TOPPERS_PRC_STDDEF_H
+#define TOPPERS_PRC_STDDEF_H
+
+/*
+ *  ^[Qbgð¯Ê·é½ßÌ}NÌè`
+ */
+#define TOPPERS_RX630				/* vZbTªÌ */
+
+#endif /* TOPPERS_PRC_STDDEF_H */
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_support.src
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_support.src	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_support.src	(revision 164)
@@ -0,0 +1,864 @@
+; 
+;   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
+;  
+;   ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+;   Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+;   ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+;   (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+;        \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+;       XR[hÉÜÜêÄ¢é±ÆD
+;   (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+;       pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+;       Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+;       Ì³ÛØKèðfÚ·é±ÆD
+;   (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+;       pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+;       ÆD
+;     (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+;         ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+;     (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+;         ñ·é±ÆD
+;   (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+;       Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+;       Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+;       RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+;       ÆÓ·é±ÆD
+;  
+;   {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+;   æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+;   ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+;   AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+;   ÌÓCðíÈ¢D
+;  
+;  @(#) $Id: prc_support.src 536 2014-10-09 23:11:40Z coas-nagasima $
+;
+
+;
+;  vZbTË¶W
+[ AZu¾êiRX630pj
+;
+
+;
+;  fBXpb`¨æÑÝ(CPUáO)oüèûÌ[:
+;	®ì[hðÈºÌæ¤Éè`·é.
+;		fBXpb`[h:
+;			CPUbNóÔ, ÝDæx}XNSðóÔ,
+;			^XNReLXg(intnest = 0), ^XNX^bN
+;		Ý(CPUáO)[h
+;			SÝbNóÔ(PSWWX^Irbg = 0),
+;			ÝDæx}XNSðÅÈ¢óÔ(IPL != 0)
+;			ÝReLXg(intnest != 0), ÝX^bN
+;
+;	J[lÇOÝÌT|[gL³Æ, CPUbNóÔ, ÝDæx
+;	}XNSðóÔÌÖWÍÈºÌÊèÅ é.
+;		J[lÇOÝ¢T|[g:
+;			CPUbNóÔ(PSWWX^Irbg = 0)
+;			ÝDæx}XNSðóÔ(IPL = 0)
+;		J[lÇOÝT|[g:
+;			CPUbNóÔ
+;				(PSWWX^Irbg = 0, IPL = IPL_LOCK, lock_flag = true)
+;			ÝDæx}XNSðóÔ(saved_ipl = 0)
+;
+;	e\¢Ì|C^ðÈºÌæ¤ÉeWX^ÉATC·é.
+;		r15 = p_runtsk	½¾µfBXpb`ÌeoûÅÍ³ø
+;		r14 = *p_runtsk	dispatcher ÌÅÍ p_runtsk mèÉÄæ¾·é
+;	eüèû©çÅÉÏANZX·éÆ«ÉãLWX^ÉÛ¶·é.
+;
+;	\¢ÌACgÖÌÎ
+;		\¢ÌACgª4Byte(ApbN)Ìê:
+;			êÊIÈWX^ÎAhbVOªÂ\
+;				á:	mov.l	#__kernel_p_runtsk, r15
+;					mov.l  	r0, TCB_sp[r15]
+;		\¢ÌACgª4ByteÅÍÈ¢(pbN)Ìê:
+;			mov.lÌæ¤ÉOTCYwèÌêAÎlÍ4Ì{ÌÝLø
+;			±Ì½ß, êxÎÛAhXðßÄ©çANZX·éKvª é
+;				á:	mov.l	#__kernel_p_runtsk, r15
+;					add		#TCB_sp, r15, r5
+;					mov.l  	r0, [r5]
+;		eItZbglð»fµ, ðAZuÉæèR[hðØèÖ¦é
+;
+
+;
+;  \¢ÌANZXÌItZbgè`
+;
+	.include	offset.inc
+
+;
+;  eíEQUè`(Ht@CÌ#defineè`)
+;
+	.include	asm_config.inc
+
+	.glb	__kernel_istkpt
+	
+	.glb	__kernel_p_runtsk
+	.glb	__kernel_p_schedtsk
+	.glb	__kernel_reqflg
+	.glb	__kernel_dspflg
+
+	.glb	__kernel_dispatch
+	.glb	__exit_and_dispatch
+	.glb	__kernel_start_r
+	.glb	__kernel_call_texrtn
+	.glb	_kernel_interrupt
+	.glb	_kernel_exception
+	.glb	__kernel_intnest
+	.glb	__kernel_call_exit_kernel
+	.glb	__kernel_start_dispatch
+
+	.glb	_ext_tsk
+	.glb	__kernel_exit_kernel
+
+.if	TIPM_LOCK != -15
+	.glb	__kernel_lock_flag
+	.glb	__kernel_saved_ipl
+.endif
+
+	.glb	__kernel_break_wait
+	.glb	_sil_dly_nse
+
+.if LOG_INH_ENTER_ENABLE == 1
+	.glb	_kernel_log_inh_enter
+.endif	; LOG_INH_ENTER_ENABLE == 1
+.if LOG_INH_LEAVE_ENABLE == 1
+	.glb	_kernel_log_inh_leave
+.endif	; LOG_INH_LEAVE_ENABLE == 1
+.if LOG_EXC_ENTER_ENABLE == 1
+	.glb	_kernel_log_exc_enter
+.endif	; LOG_EXC_ENTER_ENABLE == 1
+.if LOG_EXC_LEAVE_ENABLE == 1
+	.glb	_kernel_log_exc_leave
+.endif	; LOG_EXC_LEAVE_ENABLE == 1
+.if LOG_DSP_ENTER_ENABLE == 1
+	.glb	_kernel_log_dsp_enter
+.endif	; LOG_DSP_ENTER_ENABLE == 1
+.if LOG_DSP_LEAVE_ENABLE == 1
+	.glb	_kernel_log_dsp_leave
+.endif	; LOG_DSP_LEAVE_ENABLE == 1
+
+;
+;  TCB_sp ÖÌÝ}N
+;
+st_TCB_sp	.macro	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 ©çÌÇoµ}N
+;
+ld_TCB_sp	.macro	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 ÖÌÝ}N
+;
+st_TCB_pc	.macro	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 ©çÌÇoµ}N
+;
+ld_TCB_pc	.macro	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 ©çÌÇoµ}N
+;
+ld_TCB_texptn	.macro	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 ©çÌÇoµ}N
+;
+ld_TCB_p_tinib	.macro	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 ©çÌÇoµ}N
+;
+ld_TINIB_exinf	.macro	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 ©çÌÇoµ}N
+;
+ld_TINIB_task	.macro	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©çÌ^XNfBXpb`üû
+;
+;  ÄÑoµð:
+;	EfBXpb`[h(t@Cwb_QÆ)
+;
+;  ±±ÅÍ, ReLXgÌÞðÆ, ÀsÄJÔnÌÝèð·é.
+;
+__kernel_dispatch:
+	pushm	r6-r13						; ñXNb`WX^Û¶
+	mov.l	#__kernel_p_runtsk, r15
+	mov.l	[r15], r14
+	st_TCB_sp	r0, r14, r5				; X^bN|C^ðTCBÉÛ¶
+	st_TCB_pc	#dispatch_r, r14, r5	; ÀsÄJÔnðTCBÉÛ¶
+	bra		dispatcher
+
+;
+;  APIÖÌ^XNfBXpb`oû
+;
+;  ÄÑoµð:
+;	EfBXpb`[h(t@Cwb_QÆ)
+;
+;  ±±ÅÍ, ^XNáOnhÄoµÆ, ReLXgÌAð·é.
+;
+dispatch_r:
+	btst 	#TCB_enatex_bit, TCB_enatex[r14]	; ^XNáOÂ?
+	bz   	dispatch_r_rts
+	ld_TCB_texptn	r5, r14, r4			; Û¯áOvöª é©H
+	cmp		#0, r5
+	bz   	dispatch_r_rts
+	bsr		__kernel_call_texrtn		; ^XNáOnhÄoµÀs
+dispatch_r_rts:
+	popm 	r6-r13						; ñXNb`WX^A
+	rts  	                        	; dispatch ÄÑoµ³Ößé.
+
+;
+;  ^XNN®(^XNæªÖÌ^XNfBXpb`oû)
+;
+;  ÄÑoµð:
+;	EfBXpb`[h(t@Cwb_QÆ)
+;
+;  ±±ÅÍ, CPUbNðóÔÉµ, ^XNðN®·é.
+;
+__kernel_start_r:
+	mov.l 	#_ext_tsk, r5
+	push.l	r5							; ßèÔnðX^bNÉÏÞ
+	ld_TCB_p_tinib	r5, r14, r4
+	ld_TINIB_exinf	r1, r5, r4			; g£îñðæêøÉÝè
+	ld_TINIB_task	r5, r5, r4			; ^XNÌN®Ônðæ¾
+.if	TIPM_LOCK == -15
+	setpsw	i							; ÝÂ(CPUbNðóÔ)
+.else
+	mov.l	#__kernel_lock_flag, r4		; CPUbNðóÔÖ
+	mov.l	#0, [r4]					; ±±ÉéÆ«ÍK¸ saved_ipl Ì
+	mvtc	#00010000H, psw				; lÍ 0 Ì½ß, ¼lðÝè·é.
+								; SÝbNðóÔ( I = 1 )
+								; ÝDæx}XNSðóÔ( IPL = 0 )
+.endif
+	jmp		r5
+
+;
+;  J[lN®©çÌ^XNfBXpb`üû
+;
+;  ±Ì[`ÍCJ[lN®ÉC·×ÄÌÝðÖ~µ½óÔ
+; iÝbNóÔÆ¯jÅÄÑo³êéDÜ½CÝ[hiñ
+;  ^XNReLXgÆ¯jÅÄÑo³êé±ÆðzèµÄ¢éD
+;
+;  ÄÑoµð:
+;	EÝ(CPUáO)[h(t@Cwb_QÆ)
+;
+;  ±±ÅÍ, fBXpb`[hÉÏX·é.
+;
+__kernel_start_dispatch:
+	mov.l	#__kernel_intnest, r5
+	mov.w	#0, [r5]					; ^XNReLXgÉØ·¦
+.if	TIPM_LOCK != -15
+	mvtc	#(IPL_LOCK | 00010000H), psw	; SÝbNðóÔ
+										; ÝDæx}XNSðÅÈ¢óÔ
+.endif
+
+;
+; ^XNI¹(»ÝÌReLXgðÌÄé)©çÌ^XNfBXpb`üû
+;
+;  ÄÑoµð:
+;	EfBXpb`[h(t@Cwb_QÆ)
+;
+;  ±±ÅÍ, ½à·é±ÆÍÈ¢.
+;  È¨, p_runtsk ÌAhXæ¾¾¯ÍsÈ¤.
+;
+__exit_and_dispatch:
+	mov.l	#__kernel_p_runtsk, r15     
+
+;
+; fBXpb`{Ì
+;
+;  ÄÑoµð:
+;	E·×ÄÌ^XNÌReLXgÍÛ¶³êÄ¢é.
+;
+;  dispatcher ÄoÌX^bN:
+;	E__kernel_dispatch ©ç«½ê			: ^XNX^bN
+;	Eexit_and_dispatch ©ç«½ê: 
+;		exit_task ©ç«½ê					: ^XNX^bN
+;		J[lN®(__kernel_start_dispatch)	: ÝX^bN
+;	Eret_int ©ç«½ê						: ^XNX^bN
+;	Edispatcher_idle_loop ©ç«½ê			: ÝX^bN
+;
+dispatcher:
+.if	LOG_DSP_ENTER == 1
+	push.l	r15
+	mov.l	r14, r1						; ø(fBXpb`³TCB)ðÝè
+	bsr		_kernel_log_dsp_enter
+	pop.l	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 ªÈ¯êÎACh[vÖ
+	ld_TCB_sp	r0, r14, r5				; ^XNX^bN|C^ðA
+.if	LOG_DSP_LEAVE == 1
+	push.l	r14
+	mov.l	r14, r1						; ø(fBXpb`æTCB)ðÝè
+	bsr		_kernel_log_dsp_leave
+	pop.l	r14
+.endif
+	ld_TCB_pc	r5, r14, r4
+	jmp		r5					; ÀsÄJÔnÖWv
+
+;
+;  schdedtskªNULLÌêÍACh[vÉüé
+;  ACh[vÍÝ[hÅ®ì³¹é
+;
+;  ±±ÅÝ[hÉØè·¦éÌÍC±±Å­¶·éÝÉ
+;  ÇÌX^bNðg¤©Æ¢¤âèÌðÆCÝnhàÅÌ^
+;  XNfBXpb`Ìh~Æ¢¤2ÂÌÓ¡ª éD
+;
+dispatcher_pre_idle:
+	mov.l	#__kernel_istkpt,r5
+	mov.l	[r5], r0					; ÝpÌX^bNÖØÖ¦
+	mov.l	#__kernel_intnest, r5
+	mov.w	#1, [r5]					; ñ^XNReLXgÉØ·¦
+.if	TIPM_LOCK != -15
+	mov.l	#__kernel_lock_flag, r5		; CPUbNðóÔÖ
+	mov.l	#0, [r5]
+	mvtc	#0, psw						; Dæx0ÌÝðU
+.endif
+
+dispatcher_idle_loop:
+	setpsw	i							; SÝÂ
+	clrpsw	i							; SÝÖ~
+
+	mov.l	#__kernel_reqflg, r5		; reqflg ª FALSE Èç
+	mov.l	[r5], r4
+	cmp		#0, r4
+	bz   	dispatcher_idle_loop		; ACh[vðJèÔ·
+	mov.l	#0, [r5]					; reqflgªtrueÈçfalseÉ·é
+	mov.l	#__kernel_intnest, r5
+	mov.w	#0, [r5]					; ^XNReLXgÉØ·¦
+.if	TIPM_LOCK != -15
+	mov.l	#__kernel_lock_flag, r5		; CPUbNóÔÖ
+	mov.l	#1, [r5]
+	mov.l	#__kernel_saved_ipl, r5
+	mov.l	#0, [r5]
+	mvtc	#(IPL_LOCK | PSW_I_MASK), psw	; SÝbNðóÔ
+										; ÝDæx}XNSðÅÈ¢óÔ
+.endif
+	bra		dispatcher					; dispatcher Ößé
+
+
+;
+; J[lÌI¹ÌÄoµ
+;
+; [hÆX^bNðñ^XNReLXgpÉØèÖ¦D
+;
+	.glb	__kernel_call_exit_kernel
+__kernel_call_exit_kernel:
+.if	TIPM_LOCK != -15
+	clrpsw	i							; SÝÖ~
+	mov.l	#__kernel_lock_flag, r5		; CPUbNðóÔÖ
+	mov.l	#0, [r5]
+.endif
+	mov.l	#__kernel_istkpt, r5
+	mov.l	[r5], r0					; ÝpÌX^bNÖØÖ¦
+	mov.l	#__kernel_intnest, r5
+	mov.w	#1, [r5]					; ñ^XNReLXgÉØ·¦
+	bsr		__kernel_exit_kernel
+	bra		__kernel_call_exit_kernel
+
+
+;
+;  Ý(CPUáO)©çÌ^XNfBXpb`üû
+;
+;	Äoµð:
+;	ESÝbNóÔ(PSWWX^Irbg = 0)
+;	EÝDæx}XNSðÅÈ¢óÔ(IPL != 0)
+;	E^XNReLXg(intnest=0)
+;	EgpX^bNÍ^XNX^bN
+;	Ereqflg = true
+;
+;  ±±ÅÍ, fBXpb`[hÉÏXµ, reqflgðOFFÉµÄ©ç, 
+;  xfBXpb`ÌL³ð»f·é.
+;
+
+;
+;  ret_intæªÅX^bNÉÏÜêÄ¢éPSWWX^ÖÌItZbg
+;  ACC + FPSW + R14--R15 + R1--R5 + PC
+;
+	RET_INT_GET_PSW_OFFSET	.equ	(8+4+28+4)
+
+ret_int:
+.if	TIPM_LOCK == -15
+	mov.l	RET_INT_GET_PSW_OFFSET[r0], r5	; Ý/CPUáO­¶OÌIPLlæ¾
+	and		#PSW_IPL_MASK, r5
+	mvtc	r5, psw						; SÝbN(CPUbN)óÔ
+										; Ý/CPUáO­¶OÌÝDæx
+.else
+	mov.l	#__kernel_lock_flag, r5		; CPUbNóÔÖ
+	mov.l	#1, [r5]
+	mov.l	RET_INT_GET_PSW_OFFSET[r0], r5	; Ý/CPUáO­¶OÌIPLlæ¾
+	and		#PSW_IPL_MASK, r5
+	mov.l	#__kernel_saved_ipl, r4
+	mov.l	r5, [r4]
+	mvtc	#(IPL_LOCK | PSW_I_MASK), psw	; SÝbNðóÔ
+										; ÝDæx}XNSðÅÈ¢óÔ
+.endif
+	mov.l	#__kernel_reqflg, r5
+	mov.l	#0, [r5]					; reqflg <--- FALSE
+	mov.l	#__kernel_p_runtsk, r15     
+	mov.l	[r15], r14
+	mov.l	#__kernel_dspflg, r5		; dspflg ª FALSE Èç ret_int_r Ö
+	mov.l	[r5], r5
+	cmp		#0, r5
+	bz   	ret_int_r_call_tex
+	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						; ñXNb`WX^Û¶
+	st_TCB_sp	r0, r14, r5				; X^bN|C^ðTCBÉÛ¶
+	st_TCB_pc	#ret_int_r, r14, r5		; ÀsÄJÔnðTCBÉÛ¶
+	bra		dispatcher
+
+;
+;  Ý(CPUáO)ÖÌ^XNfBXpb`oû
+;
+;  ÄÑoµð:
+;	EfBXpb`[h(t@Cwb_QÆ)
+;
+;  ±±ÅÍ, ^XNáOnhÄoµÆ, Ý(CPUáO)[hÖÌ
+;  ÏXÆ, ReLXgÌAðs¢, Ý(CUPáO)­¶³Ößé.
+;
+__kernel_break_wait:					;^XNj^px
+ret_int_r:
+	popm 	r6-r13						; ñXNb`WX^A
+ret_int_r_call_tex:
+	btst 	#TCB_enatex_bit, TCB_enatex[r14]	; ^XNáOÂ?
+	bz   	ret_int_r_rte
+	ld_TCB_texptn	r5, r14, r4			; Û¯áOvöª é©H
+	cmp		#0, r5
+	bz   	ret_int_r_rte
+	bsr		__kernel_call_texrtn		; ^XNáOnhÄoµÀs
+ret_int_r_rte:
+.if	TIPM_LOCK != -15
+	clrpsw	i							; SÝÖ~
+	mov.l	#__kernel_lock_flag, r5		; CPUbNðóÔÖ
+	mov.l	#0, [r5]
+.endif
+	popm	r4-r5						; AL
+[^A
+	mvtaclo	r5							; ACCÅºÊ16bitÍ0ÅA
+	mvtachi	r4
+	popc	fpsw						; FPUXe[^XWX^A
+	popm	r14-r15						; WX^A
+	popm	r1-r5
+	rte									; ÝOÌÉßé
+
+
+;
+;  ÝÌoüû(AZu¾êLqª)
+;
+;  Äoµð:
+;  EÝ­¶ÌH/WÉæè, PSWWX^ÌIrbg=0, IPLÍót¯
+;    ½ÝÌIPL.
+;  EX^bNÍ½dèÝÈçÝX^bN, »¤ÅÈ¯êÎ
+;    ^XNX^bN
+;  EÝ­¶ÌH/WÉæè,X^bNÉÝ©çÌAPCÆPSWª
+;    Û¶³êÄ¢é.
+;  ExN^e[uÉo^³ê½ÂÊÌüèûÉæè, X^bNÉ
+;    XNb`WX^(R1-R5)ªÛ¶³êÄ¢é.
+;
+;  ø:
+;  Er1:ÝvöÔ
+;  Er2:ÝnhÌAhX
+;
+;  WX^ªX^bNãÉÇÌæ¤ÉÛ¶³êÄ¢é©ðÈºÉ¦·.
+;  ±Ì}ÅÍãªáÊ, ºªÊÌAhXÅ, X^bNÍº©ç
+;  ãûüÉü©ÁÄÏÝã°çêéàÌÆ·é.
+;
+;	-------------------------
+;	|       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)
+;
+;  ±±ÅÍ, Ý[hÉÏXµÄnhðÀs·é.
+;
+;  nh©ç^[µ½ãÍ, ½dÝÅÈ­, ©Â reqflg ª
+;  TRUE ÉÈÁ½ÉCret_int Öªò(xfBXpb`)·éD
+;
+;  ½dÝ©Ç¤©ÍÝlXgJE^ÌlÅ»è·é.
+;  intnest != 0 ÈçÎ½dÝÅ éÆ»è·é.
+;
+;  reqflg ÍCPUbNóÔÅ`FbN·é. »¤ÅÈ¢ÆC
+;  reqflg `FbNãÉN®³ê½ÝnhàÅ
+;  fBXpb`ªv³ê½êÉCfBXpb`³êÈ¢.
+;
+_kernel_interrupt:
+	pushm	r14-r15						; XNb`WX^ðÞð
+	pushc	fpsw						; FPUXe[^XWX^Þð
+	mvfacmi	r5
+	shll	#16, r5						; ACCÅºÊ16bitÍ0Æ·é
+	mvfachi	r4
+	pushm	r4-r5						; AL
+[^Þð
+	mov.l	#__kernel_intnest, r5
+	mov.w	[r5], r4
+	add		#1, r4						; lXgñðCNg
+	mov.w	r4, [r5]
+	cmp		#1, r4						; ½dèÝ©Ç¤©
+	bnz		interrupt_from_int			; ÁZOª0ÅÈ¯êÎ½dÝ
+						; iÌÝ
+	mov.l	r0, r3						; X^bN|C^ðæèoµ
+	mov.l	#__kernel_istkpt, r5		; ÝpÌX^bNÖØÖ¦é
+	mov.l	[r5], r0
+	push.l	r3							; ^XNX^bNðÛ
+interrupt_from_int:		; ½dÝ
+	setpsw	i							; ÝÂ(CPUbNðóÔ)
+
+.if	LOG_INH_LEAVE == 1
+	push.l	r1							; Og[XÌøðÛ
+.endif
+
+.if	LOG_INH_ENTER == 1
+	push.l	r2
+	bsr		_kernel_log_inh_enter		; Og[XÖÌÄoµ
+							; øÌÝvöÔÍùÉr1ÉüÁÄ¢é
+	pop		r2
+.endif
+
+	jsr  	r2							; C[`ÄÑoµ
+
+.if	LOG_INH_LEAVE == 1
+	pop		r1							; øÉÝvöÔðÝè
+	bsr		_kernel_log_inh_leave		; Og[XÖÌÄoµ
+.endif
+
+	clrpsw	i							; ÝÖ~(CPUbNóÔ)
+	mov.l	#__kernel_intnest, r5
+	mov.w	[r5], r4
+	sub		#1, r4						; lXgñðfNg
+	mov.w	r4, [r5]
+	cmp		#0, r4						; ½dèÝ©Ç¤©
+	bnz		interrupt_return			; ½dèÝÈç^[
+	; iÌÝ
+	pop		r0							; ^XNÌX^bNÉß·
+	mov.l	#__kernel_reqflg, r5		; fBXpb`vªÈ¢©?
+	mov.l	[r5], r5
+	cmp		#1, r5
+	bz		ret_int						;  êÎ ret_int ÖWv
+interrupt_return:
+	popm	r4-r5						; AL
+[^A
+	mvtaclo	r5							; ACCÅºÊ16bitÍ0ÅA
+	mvtachi	r4
+	popc	fpsw						; FPUXe[^XWX^A
+	popm	r14-r15						; WX^A
+	popm	r1-r5
+	rte									; ÝOÌÉßé
+
+
+;
+;  CPUáOÌoüû(AZu¾êLqª)
+;
+;  Äoµð:
+;  ECPUáO­¶ÌH/WÉæè, PSWWX^ÌIrbg=0, IPL=0.
+;  EX^bNÍ½dèÝÈçÝX^bN, »¤ÅÈ¯êÎ
+;    ^XNX^bN
+;  ECPUáO­¶ÌH/WÉæè,X^bNÉCPUáO©çÌAPCÆ
+;    PSWªÛ¶³êÄ¢é.
+;  ExN^e[uÉo^³ê½ÂÊÌüèûÉæè, X^bNÉ
+;    XNb`WX^(R1-R5)ªÛ¶³êÄ¢é.
+;
+;  ø:
+;  Er1:CPUáOvöÔ
+;  Er2:CPUáOnhÌAhX
+;
+;  WX^ªX^bNãÉÇÌæ¤ÉÛ¶³êÄ¢é©ðÈºÉ¦·.
+;  ±Ì}ÅÍãªáÊ, ºªÊÌAhXÅ, X^bNÍº©ç
+;  ãûüÉü©ÁÄÏÝã°çêéàÌÆ·é.
+;  È¨, CPUáOvöÔÆR6-R13ÍCPUáOnhàÅîñðæ¾
+;  ·éÚIÅÞðµÄ¨è, oûÅÍÛ¶àeðjü·êÎæ¢.
+;
+;	-------------------------
+;	|    CPUáOvöÔ    | <----- 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)
+;
+;  ±±ÅÍ, Ý[hÉÏXµÄnhðÀs·é.
+;  CPUáOnhÉn·VP^ÌÏ p_excinf ÆµÄISPÌln·D
+;
+;  nh©ç^[µ½ãÍ, ½dÝÅÈ­, ©Â reqflg ª
+;  TRUE ÉÈÁ½ÉCret_int Öªò(xfBXpb`)·éD
+;
+;  ½dÝ©Ç¤©ÍÝlXgJE^ÌlÅ»è·é.
+;  intnest != 0 ÈçÎ½dÝÅ éÆ»è·é.
+;
+;  reqflg ÍCPUbNóÔÅ`FbN·é. »¤ÅÈ¢ÆC
+;  reqflg `FbNãÉN®³ê½ÝnhàÅ
+;  fBXpb`ªv³ê½êÉCfBXpb`³êÈ¢.
+;
+;
+;  CPUáOüû
+;
+;  ±±ÅÍ, Ý[hÉÏXµÄnhðÀs·é.
+;
+
+;
+;  CPUáOnhÄoµãÉsvÆÈéX^bNîñÌTCY
+;  EXCNO + R6--R13
+;
+	EXCINF_REG_SIZE	.equ	(4+32)
+
+_kernel_exception:
+	pushm	r14-r15						; XNb`WX^ðÞð
+	pushc	fpsw
+	mvfacmi	r5
+	shll	#16, r5						; ACCÅºÊ16bitÍ0Æ·é
+	mvfachi	r4
+	pushm	r4-r5						; AL
+[^Þð
+	pushm	r6-r13						; ñXNb`WX^Û¶
+	push.l	r1							; CPUáOvöÔðÛ
+	mov.l	r0, r3						; X^bN|C^ðæèoµ
+	mov.l	EXC_GET_PSW_OFFSET[r3], r5
+	and		#PSW_I_MASK, r5
+	bz		exception_nonkernel			; SÝÖ~(CPUbN)óÔÈçÇO
+.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ªCPUbNxÈãÈçÇO
+.endif
+	mov.l	#__kernel_intnest, r5
+	mov.w	[r5], r4
+	add		#1, r4						; lXgñðCNg
+	mov.w	r4, [r5]
+	cmp		#1, r4						; ½dèÝ©Ç¤©
+	bnz		exception_from_int			; ÁZOª0ÅÈ¯êÎ½dÝ
+						; iÌÝ
+	mov.l	#__kernel_istkpt, r5		; ÝpÌX^bNÖØÖ¦é
+	mov.l	[r5], r0
+	push.l	r3							; ^XNX^bNðÛ
+exception_from_int:		; ½dÝ
+	mov.l	EXC_GET_PSW_OFFSET[r3], r5
+	mvtc	r5, psw						; CPUáO­¶OÌóÔÉß·
+.if	LOG_EXC_LEAVE == 1
+	push.l	r1							; Og[XÌøðÛ
+.endif
+
+.if	LOG_EXC_ENTER == 1
+	pushm	r2-r3
+	bsr		_kernel_log_exc_enter		; Og[XÖÌÄoµ
+							; øÌÝvöÔÍùÉr1ÉüÁÄ¢é
+	popm	r2-r3
+.endif
+
+	mov.l	r3, r1						; øÌp_excinfðÝè
+	jsr  	r2							; C[`ÄÑoµ
+
+.if	LOG_EXC_LEAVE == 1
+	pop		r1							; øÉÝvöÔðÝè
+	bsr		_kernel_log_exc_leave		; Og[XÖÌÄoµ
+.endif
+
+	clrpsw	i							; ±±©çÍK¸ÝÖ~
+	mov.l	#__kernel_intnest, r5
+	mov.w	[r5], r4
+	sub		#1, r4						; lXgñðfNg
+	mov.w	r4, [r5]
+	cmp		#0, r4						; ½dèÝ©Ç¤©
+	bnz		exception_return			; ½dèÝÈç^[
+	; iÌÝ
+	pop		r0							; ^XNÌX^bNÉß·
+	mov.l	#__kernel_reqflg, r5		; fBXpb`vªÈ¢©?
+	mov.l	[r5], r5
+	cmp		#1, r5
+	bnz		exception_return			; È¯êÎ^[
+	add		#EXCINF_REG_SIZE, r0		; CPUáOîñÌjü
+	bra		ret_int						;  êÎ ret_int ÖWv
+
+exception_nonkernel:
+	mov.l	#__kernel_intnest, r5
+	mov.w	[r5], r4
+	add		#1, r4						; lXgñðCNg
+	mov.w	r4, [r5]
+	cmp		#1, r4						; ½dèÝ©Ç¤©
+	bnz		exception_from_nonkernelint	; ÁZOª0ÅÈ¯êÎ½dÝ
+						; iÌÝ
+	mov.l	#__kernel_istkpt, r5		; ÝpÌX^bNÖØÖ¦é
+	mov.l	[r5], r0
+	push.l	r3							; ^XNX^bNðÛ
+exception_from_nonkernelint:	; ½dÝ
+	mov.l	EXC_GET_PSW_OFFSET[r3], r5
+	mvtc	r5, psw						; CPUáO­¶OÌóÔÉß·
+
+	mov.l	r3, r1						; øÌp_excinfðÝè
+	jsr  	r2							; C[`ÄÑoµ
+
+	clrpsw	i							; ±±©çÍK¸ÝÖ~
+	mov.l	#__kernel_intnest, r5
+	mov.w	[r5], r4
+	sub		#1, r4						; lXgñðfNg
+	mov.w	r4, [r5]
+	cmp		#0, r4						; ½dèÝ©Ç¤©
+	bnz		exception_return			; ½dèÝÈç^[
+	; iÌÝ
+	pop		r0							; ^XNÌX^bNÉß·
+
+exception_return:
+	add		#EXCINF_REG_SIZE, r0		; CPUáOîñÌjü
+	popm	r4-r5						; AL
+[^A
+	mvtaclo	r5							; ACCÅºÊ16bitÍ0ÅA
+	mvtachi	r4
+	popc	fpsw						; FPUXe[^XWX^A
+	popm	r14-r15						; WX^A
+	popm	r1-r5
+	rte									; ÝOÌÉßé
+
+
+;
+;  ÷­ÔÒ¿
+;
+_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: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_syssvc.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_syssvc.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_syssvc.h	(revision 164)
@@ -0,0 +1,61 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		eXgvOÌ^[QbgË¶è`iRX630pj
+ */
+
+#ifndef TOPPERS_PRC_SYSSVC_H
+#define TOPPERS_PRC_SYSSVC_H
+
+/*
+ *  N®bZ[WÉ^[QbgË¶Ìì \¦ð
+ *  ÇÁ·é½ßÌ}ND
+ */
+#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: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_test.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_test.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_test.h	(revision 164)
@@ -0,0 +1,56 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		eXgvOÌ^[QbgË¶è`iRX630pj
+ */
+
+#ifndef TOPPERS_PRC_TEST_H
+#define TOPPERS_PRC_TEST_H
+
+#define CPUEXC1					25		/* ®¬_áO */
+#define RAISE_CPU_EXCEPTION		trigger_cpu_exception()
+
+extern void trigger_cpu_exception( void );
+
+#endif /* TOPPERS_PRC_TEST_H */
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_test.src
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_test.src	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_test.src	(revision 164)
@@ -0,0 +1,62 @@
+;*
+;*  TOPPERS/ASP Kernel
+;*      Toyohashi Open Platform for Embedded Real-Time Systems/
+;*      Advanced Standard Profile Kernel
+;* 
+;*  Copyright (C) 2010 by Witz Corporation, JAPAN
+;* 
+;*  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+;*  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+;*  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+;*  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+;*       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+;*      XR[hÉÜÜêÄ¢é±ÆD
+;*  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+;*      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+;*      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+;*      Ì³ÛØKèðfÚ·é±ÆD
+;*  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+;*      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+;*      ÆD
+;*    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+;*        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+;*    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+;*        ñ·é±ÆD
+;*  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+;*      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+;*      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+;*      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+;*      ÆÓ·é±ÆD
+;* 
+;*  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+;*  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+;*  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+;*  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+;*  ÌÓCðíÈ¢D
+;* 
+;*  @(#) $Id: prc_test.src 536 2014-10-09 23:11:40Z coas-nagasima $
+;* 
+
+	.section	P, CODE
+
+	.glb	_trigger_cpu_exception
+
+_trigger_cpu_exception:
+	;
+	;  CPUáOÌ­¶
+	;
+	;  [èZðs¤±ÆÅ, ®¬_áOð
+	;  ­¶³¹é.
+	;
+	mvtc	#00001000H, fpsw
+	mov.l	#1, r5
+	fdiv	#0, r5
+	mvtc	#00000000H, fpsw
+	rts
+
+	.end
+
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_unrename.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_unrename.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/prc_unrename.h	(revision 164)
@@ -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_config.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_config.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_config.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_config.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: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/rx630.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/rx630.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/rx630.h	(revision 164)
@@ -0,0 +1,1915 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  RX630ÉË¶·éè`
+ */
+#ifndef TOPPERS_RX630_H
+#define TOPPERS_RX630_H
+
+/*
+ *  CPUáOnhÔÌè`(ÅèxN^e[u)
+ *
+ *  ÔÌÍÍÍ0 - 31
+ */
+#define INT_PRIVILEGED_INSTRUNCTION		20		/* Á ½ßáO */
+#define INT_UNDEF_INSTRUNCTION			23		/* ¢è`½ßáO */
+#define INT_FLOATINGPOINT_INSTRUCTION	25		/* ®¬_áO */
+#define INT_NMI							30		/* m}XJuèÝ */
+#define INT_RESET						31		/* Zbg */
+
+/*
+ *  ÝÔÌè`(ÂÏxN^e[u)
+ */
+#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
+
+/*
+ *  eW
+[ÌWX^yÑÝèrbgîñ
+ */
+
+#define SYSTEM_SYSCR0_ADDR		( ( volatile uint16_t __evenaccess * )0x00080006 )
+
+/*
+ * W
+[XgbvRg[WX^AiMSTPCRAj
+ */
+#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)
+
+/*
+ * W
+[XgbvRg[WX^BiMSTPCRBj
+ */
+#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 )
+
+/*
+ * W
+[XgbvRg[WX^CiMSTPCRCj
+ */
+#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 )
+
+/*
+ * NbN­¶ñH
+ */
+#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 )
+
+/*
+ * veNgWX^
+ */
+#define SYSTEM_PRCR_ADDR		( ( volatile uint16_t __evenaccess * )0x000803FE )
+
+/*
+ * èÝvWX^
+ */
+#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 )
+
+/*
+ * èÝvæÝèWX^
+ */
+#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 )
+
+/*
+ * èÝvÂWX^
+ */
+#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 )
+
+/* 
+ * èÝvövCIeBWX^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_BIT				( 7U << 0U )
+
+
+/*
+ *  IRQRg[WX^
+ */
+#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 )
+
+
+/*
+ *  e`lÌWX^yÑÝèrbgîñ
+ */
+#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 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|[gÌWX^yÑÝèrbgîñ
+ */
+#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 )
+
+/*
+ *  }`t@NVsRg[ÌWX^îñ
+ */
+#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 )
+
+/*
+ * A^CNbN
+ */
+#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 rbgA/D Ro[^
+ */
+#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 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_TIORL_IOA_OFFSET	( 0U )
+#define TPU_TIORL_IOA_MASK		( 0xFU << TPU_TIORL_IOA_OFFSET )
+#define TPU_TIORL_IOB_OFFSET	( 4U )
+#define TPU_TIORL_IOB_MASK		( 0xFU << TPU_TIORL_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 )
+
+/*
+ * 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ÖAÌè`
+ *
+ *  pdicÌrx600/rx630_uart.cÅgp·éD
+ */
+/*
+ *  VAI/OÌÂ
+ */
+#define TNUM_SIOP	( 2 )
+
+#endif	/* TOPPERS_RX630_H */
+
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/rx630.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/rx630.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/rx630.tf	(revision 164)
@@ -0,0 +1,51 @@
+$ 
+$		A[LeN`Ë¶ev[giRX630pj
+$ 
+
+
+
+/*$NL$
+$SPC$*  Architecture-dependent Definitions (RX630)$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 
+$  ÝÔÆÝnhÔÌè`
+$ 
+$  RX630ÅÍÝÔÆÝnhÔª1Î1ÅÎ·éD
+$ 
+
+$INTNO_VALID = { 16, 21, 23 ; 27, 28,...,59 ; 62 ; 64, 65,...,79 ; 90, 91, 92, 93, 98, 102 ; 106, 107,...,112 ; 114 ; 122, 123,...,167 ; 170, 171,...,203 ; 214, 215,...,253 }$
+$INHNO_VALID = INTNO_VALID$
+
+$ 
+$  áOÔÌè`
+$ 
+$  ÅèxN^e[uÌxN^e[uAhXÌ¬³¢ÔÉáOÔðUéD
+$  (\ñÌæàÜÞ)
+$ 
+
+$EXCNO_VALID = { 20, 23, 25, 30 }$
+
+$ 
+$  INTÝÌÔ
+$ 
+
+$INTNO_INT = { 64, 65,...,79 }$
+
+$ 
+$  ÝÔCÝnhÔCáOÔÌÍÍ
+$ 
+$ (\ñÌæàÜÞ)
+$ 
+
+$INTNO_RANGE = { 0, 1,...,255 }$
+$INHNO_RANGE = INTNO_RANGE$
+$EXCNO_RANGE = { 0, 1,...,31 }$
+
+$ 
+$  vZbTË¶Ìev[gt@CÌCN[h
+$ 
+
+$INCLUDE"rx630_ccrx/prc.tf"$
+
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/rx630_config.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/rx630_config.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/rx630_config.c	(revision 164)
@@ -0,0 +1,600 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		vZbTË¶W
+[iRX630pj
+ */
+
+#include "kernel_impl.h"
+
+
+/*
+ *  ÝvövCIeBWX^AhXe[u
+ */
+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  oXG[ 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  CMTjbg0 CMT0 */
+	ICU_IPR005_ADDR,				/* No.29  CMTjbg0 CMT1 */
+	ICU_IPR006_ADDR,				/* No.30  CMTjbg1 CMT2 */
+	ICU_IPR007_ADDR,				/* No.31  CMTjbg1 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  O[q IRQ0 */
+	ICU_IPR065_ADDR,				/* No.65  O[q IRQ1 */
+	ICU_IPR066_ADDR,				/* No.66  O[q IRQ2 */
+	ICU_IPR067_ADDR,				/* No.67  O[q IRQ3 */
+	ICU_IPR068_ADDR,				/* No.68  O[q IRQ4 */
+	ICU_IPR069_ADDR,				/* No.69  O[q IRQ5 */
+	ICU_IPR070_ADDR,				/* No.70  O[q IRQ6 */
+	ICU_IPR071_ADDR,				/* No.71  O[q IRQ7 */
+	ICU_IPR072_ADDR,				/* No.72  O[q IRQ8 */
+	ICU_IPR073_ADDR,				/* No.73  O[q IRQ9 */
+	ICU_IPR074_ADDR,				/* No.74  O[q IRQ10 */
+	ICU_IPR075_ADDR,				/* No.75  O[q IRQ11 */
+	ICU_IPR076_ADDR,				/* No.76  O[q IRQ12 */
+	ICU_IPR077_ADDR,				/* No.77  O[q IRQ13 */
+	ICU_IPR078_ADDR,				/* No.78  O[q IRQ14 */
+	ICU_IPR079_ADDR,				/* No.79  O[q 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  \ñ */
+};
+
+
+/*
+ *  ÝvÂWX^AhXe[u
+ */
+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  oXG[ 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  CMTjbg0 CMT0 */
+	{ ICU_IER03_ADDR, ICU_IEN5_BIT },	/* No.29  CMTjbg0 CMT1 */
+	{ ICU_IER03_ADDR, ICU_IEN6_BIT },	/* No.30  CMTjbg1 CMT2 */
+	{ ICU_IER03_ADDR, ICU_IEN7_BIT },	/* No.31  CMTjbg1 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  O[q IRQ0 */
+	{ ICU_IER08_ADDR, ICU_IEN1_BIT },	/* No.65  O[q IRQ1 */
+	{ ICU_IER08_ADDR, ICU_IEN2_BIT },	/* No.66  O[q IRQ2 */
+	{ ICU_IER08_ADDR, ICU_IEN3_BIT },	/* No.67  O[q IRQ3 */
+	{ ICU_IER08_ADDR, ICU_IEN4_BIT },	/* No.68  O[q IRQ4 */
+	{ ICU_IER08_ADDR, ICU_IEN5_BIT },	/* No.69  O[q IRQ5 */
+	{ ICU_IER08_ADDR, ICU_IEN6_BIT },	/* No.70  O[q IRQ6 */
+	{ ICU_IER08_ADDR, ICU_IEN7_BIT },	/* No.71  O[q IRQ7 */
+	{ ICU_IER09_ADDR, ICU_IEN0_BIT },	/* No.72  O[q IRQ8 */
+	{ ICU_IER09_ADDR, ICU_IEN1_BIT },	/* No.73  O[q IRQ9 */
+	{ ICU_IER09_ADDR, ICU_IEN2_BIT },	/* No.74  O[q IRQ10 */
+	{ ICU_IER09_ADDR, ICU_IEN3_BIT },	/* No.75  O[q IRQ11 */
+	{ ICU_IER09_ADDR, ICU_IEN4_BIT },	/* No.76  O[q IRQ12 */
+	{ ICU_IER09_ADDR, ICU_IEN5_BIT },	/* No.77  O[q IRQ13 */
+	{ ICU_IER09_ADDR, ICU_IEN6_BIT },	/* No.78  O[q IRQ14 */
+	{ ICU_IER09_ADDR, ICU_IEN7_BIT },	/* No.79  O[q 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 \ñ */
+};
+
+
+/*
+ *  IRQRg[WX^AhXe[u
+ */
+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: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/rx630_config.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/rx630_config.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/rx630_config.h	(revision 164)
@@ -0,0 +1,106 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		vZbTË¶W
+[iRX630pj
+ *
+ *  ±ÌCN[ht@CÍCtarget_config.hiÜ½ÍC»±©çCN
+ *  [h³êét@CjÌÝ©çCN[h³êéD¼Ìt@C©ç
+ *  ¼ÚCN[hµÄÍÈçÈ¢D
+ */
+
+
+#ifndef TOPPERS_RX630_CONFIG_H
+#define TOPPERS_RX630_CONFIG_H
+
+
+/*
+ *  Ývö
+ */
+#define	INHNO_MAX	UINT_C( 256 )
+
+
+/*
+ *  Ý§äp^è`
+ */
+typedef struct ier_info {
+	volatile uint8_t __evenaccess	*addr;
+			 uint8_t				offset;
+} IER_INFO;
+
+
+/*
+ *  Ý§äpè`
+ */
+#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)))
+
+/*
+ *  Ý§äpe[u
+ */
+
+/* ÝvövCIeBWX^AhX */
+extern volatile uint8_t __evenaccess * const ipr_reg_addr[];
+/* ÝvÂWX^AhX */
+extern const IER_INFO ier_reg_addr[];
+/* ÝvWX^AhX */
+extern volatile uint8_t __evenaccess * const ir_reg_addr[];
+/* IRQRg[WX^AhX */
+extern volatile uint8_t __evenaccess * const irqcr_reg_addr[];
+
+
+/*
+ *  vZbTË¶W
+[iRX630pj
+ */
+#include "rx630_ccrx/prc_config.h"
+
+#endif	/* TOPPERS_RX630_CONFIG_H */
+
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/start.src
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/start.src	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_ccrx/start.src	(revision 164)
@@ -0,0 +1,176 @@
+;*
+;*  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
+;* 
+;*  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+;*  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+;*  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+;*  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+;*       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+;*      XR[hÉÜÜêÄ¢é±ÆD
+;*  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+;*      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+;*      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+;*      Ì³ÛØKèðfÚ·é±ÆD
+;*  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+;*      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+;*      ÆD
+;*    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+;*        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+;*    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+;*        ñ·é±ÆD
+;*  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+;*      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+;*      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+;*      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+;*      ÆÓ·é±ÆD
+;* 
+;*  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+;*  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+;*  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+;*  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+;*  ÌÓCðíÈ¢D
+;* 
+;*  @(#) $Id: start.src 536 2014-10-09 23:11:40Z coas-nagasima $
+;* 
+
+	.include	sectrx.inc
+
+	;
+	;  }bvÌè`(^[QbgË¶)
+	;
+
+DFLRE				.equ	007FC440H		; DFLREWX^
+
+DB_BLOCK_ENABLE		.equ	02D0FH
+
+;
+;  ú»[`
+;
+	.section	P, CODE
+
+	.glb	_start
+	.glb	_sta_ker
+	.glb	_software_init_hook
+	.glb	_hardware_init_hook
+	.glb	__kernel_istkpt
+
+_start:
+	;
+	;  d¹üãÍx0, SÝÖ~óÔÅ é.
+	;  J[lÅÍ¬ÝðgpµÈ¢½ßABPC, BPSWyÑFINTV
+	;  Ìú»ÍsíÈ¢.
+	;
+
+	;
+	;  à ROMif[^tbV
+jÌæÌÝè
+	;
+	;  Zbgã, f[^tbV
+ÌæÍÇÝoµÖ~ÆÈÁÄ¢é
+	;  ½ß, ÇÝoµÂÉÝè·é.
+	;
+	mov.l	#DFLRE, r5
+	mov.w	#DB_BLOCK_ENABLE, [R5]
+	
+	;
+	;  X^bN|C^ÌÝè
+	;
+	;  [UÉÄñ^XNReLXgpX^bNÌæðpÓµ½ê,
+	;  [UÌæðÝè·é.
+	;  kernel_cfg.cÉÄ"_kernel_istkpt"Ìlðè·é.
+	;
+	mov.l	#__kernel_istkpt, r5
+	mov.l	[r5], r0			; ñ^XNReLXgpX^bNÌæðÝè
+
+	;
+	;  ÂÏxN^e[uÌÝè
+	;
+	mvtc	#(topof C$VECT), intb			; xN^e[uÌÝè
+
+	;
+	;  n[hEFAÅLÌú»[`ÌÄoµ
+	;
+	mov.l	#_hardware_init_hook, r5
+	cmp		#0, r5
+	beq.b	init_D
+	jsr		r5
+
+	;
+	;  úl èÏÌæÌú»
+	;
+init_D:
+	mov.l	#(sizeof R), r3
+	cmp		#0, r3
+	beq.b	init_D_2					; TCY0Èçú»KvÈµ
+	mov.l	#(topof R), r1
+	mov.l	#(topof D), r2
+	smovf
+
+init_D_2:
+	mov.l	#(sizeof R_2), r3
+	cmp		#0, r3
+	beq.b	init_D_1					; TCY0Èçú»KvÈµ
+	mov.l	#(topof R_2), r1
+	mov.l	#(topof D_2), r2
+	smovf
+
+init_D_1:
+	mov.l	#(sizeof R_1), r3
+	cmp		#0, r3
+	beq.b	clear_B						; TCY0Èçú»KvÈµ
+	mov.l	#(topof R_1), r1
+	mov.l	#(topof D_1), r2
+	smovf
+
+	;
+	;  úlÈµÏÌæÌú»
+	;
+clear_B:
+	mov.l	#0, r2
+	mov.l	#(topof B), r1
+	mov.l	#(sizeof B) , r3
+	sstr.b
+
+clear_B_2:
+	mov.l	#0, r2
+	mov.l	#(topof B_2), r1
+	mov.l	#(sizeof B_2) , r3
+	sstr.b
+
+clear_B_1:
+	mov.l	#0, r2
+	mov.l	#(topof B_1), r1
+	mov.l	#(sizeof B_1) , r3
+	sstr.b
+
+	;
+	;  software_init_hook ðÄoµi0 ÅÈ¢êj
+	;
+	;  \tgEFAÂ«iÁÉCujÉË¶µÄKvÈú»
+	;  ª éêÍCsoftware_init_hook Æ¢¤ÖðpÓ·êÎæ¢.
+	;
+	mov.l	#_software_init_hook, r5
+	cmp		#0, r5
+	beq.b	kernel_link
+	jsr		r5
+
+	;
+	;  J[lX^[g
+	;
+kernel_link:
+	bra.a	_sta_ker					; --> _sta_ker()
+
+	.end
+
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/MANIFEST
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/MANIFEST	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/MANIFEST	(revision 164)
@@ -0,0 +1,35 @@
+PACKAGE asp_arch_rx620_msvc
+VERSION 1.6.1
+
+MANIFEST
+genoffset.bat
+makeoffset.c
+offset.exe
+prc.tf
+prc_asm_config.tf
+prc_cfg1_out.h
+prc_check.tf
+prc_config.c
+prc_config.h
+prc_def.csv
+prc_insn.h
+prc_kernel.h
+prc_rename.def
+prc_rename.h
+prc_sil.h
+prc_stddef.h
+prc_support.src
+prc_syssvc.h
+prc_test.h
+prc_test.src
+prc_unrename.h
+prc_user.txt
+rx610.h
+rx610.tf
+rx610_config.c
+rx610_config.h
+start.src
+
+INCLUDE ../../target/rsk_rx_hew/MANIFEST
+INCLUDE ../rxc/MANIFEST
+INCLUDE ../../pdic/rx600/MANIFEST
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/makeoffset.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/makeoffset.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/makeoffset.c	(revision 164)
@@ -0,0 +1,235 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2003-2004 by Naoki Saito
+ *             Nagoya Municipal Industrial Research Institute, JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ */
+
+
+/*
+ *	offset.inc (àµ­Í offset.h) ÉÂ¢Ä
+ *
+ *	  offset.inc Í\¢ÌÌÁèÌvfª\¢ÌÌæª©ç½oCgÚÉ
+ *	¶Ý·é©Æ¢¤±Æâ, ÁèÌrbgtB[hªæª©ç
+ *	½oCgæÌ½rbgÚÉ¶Ý·é©, Æ¢¤îñð
+ *	AZu¾êt@CÉ^¦é½ßÉ¶ÝµÄ¢é.
+ *
+ *	  offset.inc t@CÌgÍ, PÈéV{è`t@CÅ é.
+ *	V{Æ¢ÁÄàè`·éV{Ì¼ÌÉÍp^[ª è,
+ *	å«­ª¯ÄÌ3íÞÉªÞÅ«é.
+ *
+ *	<\¢Ì¼>_<vf¼>	(á) TCB_sp, TCB_pc, TCB_enatex ÈÇ
+ *	<\¢Ì¼>_<vf¼>_bit	(á) TCB_enatex_bit ÈÇ
+ *	<\¢Ì¼>_<vf¼>_mask (á) TCB_enatex_mask ÈÇ
+ *
+ *	(á)
+ *		TCB_texptn		.equ	14
+ *		TCB_sp			.equ	20
+ *		TCB_pc			.equ	24
+ *		TCB_enatex		.equ	13
+ *		TCB_enatex_bit		.equ	 6
+ *		TCB_enatex_mask		.equ	0040H
+ *
+ *	  êÔÍ¶ßÍÁèÌvfª\¢ÌÌæª©ç½oCgæÉ é©
+ *	Æ¢¤±Æð¦·lÉÂ¯éxÌ¼Ì.
+ *	  ñÔÚÍÁèÌrbgtB[hÌrbgª, ºÊ©ç¦Ä
+ *	½rbgÚÉ é©Æ¢¤±Æð¦·lÉÂ¯éxÌ¼Ì. 
+ *	0©çnÜélÅ\»·é. ÅàºÊÌrbgÍæ0rbgÅ é.
+ *	  OÔÚÍæÙÇÌ <\¢Ì¼>_<vf¼>_bit ÆàÖA·éª,
+ *	ÁèÌrbgtB[hÌrbgÌ}XNlÌ¼Ì.
+ *	_bit Æ *_mask ÌlÌÔÉÍÌÖWª é.
+ *		(*_mask) == (1 << *_bit)
+ * *	(á) TCB_enatex_bit ª 6 Ì, TCB_enatex_mask Í 40H
+ *
+ *	  ¿ÈÝÉM32CË¶ÌÀÅÍ, ÁèrbgÌ`FbNÈÇÉ
+ *	rbg½ßAhbVOðgpµÄ¢éÌÅ *_mask Æ¢¤xÍ
+ *	gpµÄ¢È¢.
+ */
+
+/*
+ *	offset.inc Ììèû(M32C^[QbgË¶ü¯)
+ *
+ *	  GNU CRpCðp¢Ä¢é^[QbgË¶ÉÂ¢ÄÍ,
+ *	J[lÌgbvfBNgÌºÉ é util Æ¢¤fBNgÌ
+ *	ºÉ genoffset Æ¢¤ perl XNvgªpÓ³êÄ¢éÌÅ,
+ *	ÁÉè®Å offset.h ðì¬·éKvÍÈ¢.
+ *	  genoffset Í GNU J­Â«ðzèµÄì¬³êÄ¢éÌÅ,
+ *	¶¬³êéAZu¾ê^½ßâ¶¬K¥ÌÙÈé¼Ì
+ *	CRpCÉÍ»ÌÜÜKpÅ«È¢Â\«ª é.
+ *	  »±Å, ±±ÅÍWindowsÂ« ü¯Ì genoffset ðpÓ¹¸,
+ *	ìèûð±±ÉLµ, èìÆÅ offset.inc ðì¬µÄàç¤±ÆÆ
+ *	·é. ÈºÉ»Ìû@ð¦·. È¨, ±Ìû@ÍM32CÌJ­Â«â
+ *	½ßZbgÉË¶µÄ¢é½ß, ¼Ì^[QbgðgpµÄ¢éêÍ
+ *	»ÌÜÜKpÅ«È¢.
+ *
+ *  1.	makeoffset.c Æ¢¤t@C©çCRpCðgpµÄ
+ *	AZu¾êt@C makeoffset.a30 ð¶¬·é.
+ *	RpCIvVÍJ[lR[hÉ^¦éàÌÆ¯¶
+ *	àÌð^¦é. 
+ *	lTX»c[ TM ðgpµÄ¢éêÍ, vWFNgGfB^Ì
+ *	¶¬èr
+[©ç makeoffset.a30 ðIÑ, ENbNj
+[Ì
+ *	¢ªrh£ðIð·é±ÆÅ¶¬Å«é.
+ *	àµ­ÍR}hvvgÅCNt@CÆ¯¶fBNgÉ
+ *	Ú®µ, "make -f CNt@C¼ makeoffset.a30" ð
+ *	ÀsµÄà¯lÌÊª¾çêé. (CNt@CÍTMªgpµÄ
+ *	¢éàÌÆ¯¶t@CðwèÂ\)
+ *
+ *  2.	æÙÇÌ 1. ÌìÆÅ¾çê½, makeoffset.a30 t@C©ç
+ *	"! BEGIN XXXX"  ÅÍ¶Üè "! END" ÅIíÁÄ¢éªðT·.
+ *
+ *	4Ó è, »ê¼ê­µ¸ÂÙÈéÌÅÉà¾·é.
+ *	(Èº, à¾ÅÍAZu¾êt@CÌRgsÍÈ­)
+ *
+ * (1)	\¢ÌÌæª©çoÖÌItZbg
+ *
+ *	! BEGIN TCB_texptn
+ *		bset	00H,0000000eH
+ *	! END
+ *
+ *	ãL"! BEGIN"ÌãëÌ¶ñªoffset.incÅè`·éV{¼ÆÈé.
+ *	»ÌV{ÌlÍ, sÌbset½ßÌæ2IyhÌlÅ é
+ *	0000000eHª»êÉ·é. ±êª\¢ÌÌæª©çtexptnÜÅÌ
+ *	ItZbglÆÈé. µ½ªÁÄ±Ìê, offset.inc ÉÍ
+ *	TCB_texptn	.equ	14
+ *	Æ¢¤sðLq·é.
+ *
+ * (2)	\¢ÌÌoª\¢ÌÅ, »ÌÌoÉÎ·éItZbg
+ *
+ *	TCB_sp ÉÂ¢ÄàÙÚ¯l¾ª, sp ÍTCB\¢ÌÌ¼ÚÌ
+ *	oÅÈ­TCB\¢ÌÌoÅ éTSKCTXB\¢ÌÌoÅ
+ *	 é_ªÙÈé. »êÅàè`·éV{¼ÆµÄÍ
+ *	TCB_sp Ìæ¤É\»·é. AZu¾êt@CÅÍ
+ *
+ *	! BEGIN TCB_sp
+ *		mov.l	00000014H,A0
+ *		extz	[A0],R0
+ *		bset	0,R0L
+ *		mov.l	#00000014H,A0
+ *		mov.b	R0L,[[A0]]
+ *	! END *
+ *
+ *	Ìæ¤ÉÈè,14H(=20) ªßélÈÌÅoffset.inc ÉÍÌæ¤É
+ *	Lq·é.
+ *
+ *	TCB_sp	.equ	20
+ *
+ * (3)	oªÖÖÌ|C^Å Á½ê
+ *
+ *	Í TCB_pc Ìê.
+ *
+ *	! BEGIN TCB_pc
+ *		mov.l	#00000018H,A0
+ *		jsri.a	[A0]
+ *	! END
+ *
+ *	pc à sp Æ¯¶­, TCB\¢ÌÌ¼ÚÌoÅÍÈ¢ª
+ *	TCB_pc Æ\»µÄ¢é. ±êÍÖÌAhXði[·éÏÈÌÅ,
+ *	(((TCB *)0)->tskctxb.pc)();
+ *	ÆµÄÖÄÑoµÌæ¤ÉLq·éÆãLÌæ¤ÈAZu¾ê
+ *	R[hðoÍ·é. V{è`·éÛÌV{¼Í¡ÜÅÆ
+ *	¯¶­, TCB_pc Æ·é. 
+ *	ßélÍ\¢Ì©çÖ|C^ÜÅÌItZbgÅ è, ãÌmov.l
+ *	½ßÌÊ©ç 	00000018H(=24) ÆÈé.
+ *	µ½ªÁÄ, offset.inc ÉÍÌæ¤ÉLq·é.
+ *
+ *	TCB_pc	.equ	24
+ *
+ * (4)	\¢ÌÌoªrbgtB[hÅ»ÌrbgÊuàmè½¢ê
+ *
+ *	! BEGIN TCB_enatex
+ *		bset	6,0000000cH+1
+ *	! END
+ *
+ *	¡ÜÅÆ¯l, BEGIN ÌãÌ¶ñðV{¼Æ·é.
+ *	±±ÅÌTCB_enatexÌlÍ\¢ÌÌæª©çrbgtB[hðÜÞo
+ *	CgÜÅÌItZbgÅ, M32CÌrbg½ßAhbVOÍwèÅ«
+ *	érbgÊuª0©ç7ÌÔÉûÜéæ¤ÉANZX·éAhXÉK
+ *	ªÁ¦çêéÌÅ cH+1(=13) ÆÈÁÄ¢é. Ü½, rbgtB[h
+ *	ÌÅºÊrbg©çÌrbgÊuÍ 6ÆÈé.
+ *	ÈãæèÌæ¤É­±ÆªÅ«é.
+ *
+ *		TCB_enatex	.equ	13
+ *		TCB_enatex_bit	.equ	 6
+ *		TCB_enatex_mask	.equ	40H
+ */
+
+#include "kernel_impl.h"
+#include "task.h"
+#include "sil.h"
+
+const TCB	____BEGIN_OFF_TCB_tstat = {
+		{ NULL, NULL }, NULL , 1, 0,
+		0, 0 , 0 , 0 , NULL , { NULL , NULL }
+	};
+
+const TCB	____BEGIN_OFF_TCB_tinib = {
+		{ NULL, NULL }, (TINIB *)1 , 0 , 0,
+		0, 0 , 0 , 0 , NULL , { NULL , NULL }
+	};
+
+const TCB	____BEGIN_OFF_TCB_pc = {
+		{ NULL, NULL }, NULL, 0, 0,
+		0, 0 , 0 , 0 , NULL , { NULL , (FP)1 }
+	};
+const TCB	____BEGIN_OFF_TCB_sp = {
+		{ NULL, NULL }, NULL, 0, 0,
+		0, 0 , 0 , 0 , NULL , { (void *)1 , NULL }
+	};
+
+const TCB	____BEGIN_BIT_TCB_enatex = {
+		{ NULL, NULL }, NULL, 0, 0,
+		0, 0 , 1 , 0 , NULL , { NULL , NULL }
+	};
+
+const TCB	____BEGIN_OFF_TCB_texptn = {
+		{ NULL, NULL }, NULL, 0, 0,
+		0 , 0 , 0 , 1 , NULL , { NULL , NULL }
+	};
+
+const TINIB	____BEGIN_OFF_TINIB_exinf = {
+		0 , (intptr_t)1 , NULL , 0 , 0 , NULL , 0 , NULL
+	};
+
+const TINIB	____BEGIN_OFF_TINIB_task = {
+		0 , NULL , (TASK)1 , 0 , 0 , NULL , 0 , NULL
+	};
+
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc.tf	(revision 164)
@@ -0,0 +1,201 @@
+$ 
+$  TOPPERS/ASP Kernel
+$      Toyohashi Open Platform for Embedded Real-Time Systems/
+$      Advanced Standard Profile Kernel
+$ 
+$  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+$ 
+$  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$      XR[hÉÜÜêÄ¢é±ÆD
+$  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$      Ì³ÛØKèðfÚ·é±ÆD
+$  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$      ÆD
+$    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$        ñ·é±ÆD
+$  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$      ÆÓ·é±ÆD
+$ 
+$  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$  ÌÓCðíÈ¢D
+$ 
+$  @(#) $Id$
+$ 
+
+$ 
+$  A[LeN`Ë¶ev[giRX630pj
+$ 
+
+
+
+$ 
+$  ATT_ISRÅgpÅ«éÝÔÆ»êÉÎ·éÝnhÔ
+$ 
+
+$INTNO_ATTISR_VALID = INTNO_VALID$
+$INHNO_ATTISR_VALID = INHNO_VALID$
+
+
+$ 
+$  DEF_INT^DEF_EXCÅgpÅ«éÝnhÔ^CPUáOnhÔ
+$ 
+
+$INHNO_DEFINH_VALID = INHNO_VALID$
+$EXCNO_DEFEXC_VALID = EXCNO_VALID$
+
+
+$ 
+$  CFG_INTÅgpÅ«éÝÔÆÝDæx
+$ 
+
+$INTNO_CFGINT_VALID = INHNO_VALID$
+$INTPRI_CFGINT_VALID = { -7, -6,...,-1 }$
+
+
+$ 
+$  ^[QbgñË¶ÉÜÜêéWÌÝÇ@\/áOÇ@\Ìú»ðgp·é
+$ 
+
+$OMIT_INITIALIZE_INTERRUPT = 0$
+$OMIT_INITIALIZE_EXCEPTION = 0$
+
+
+$ 
+$  X^bNTCYÌ`FbNû@wè
+$ 
+
+$CHECK_STKSZ_ALIGN = 4$
+
+
+$ 
+$  ^XNX^bNTCYÌÅ¬l
+$ 
+$  ^XNN®É4byte,
+$  ÝüûÉÄ48byte, CPUáOüûÉÄ84byte,
+$  Å é½ß, Å¬lÍ88byteÆ·é.
+$ 
+
+$TARGET_MIN_STKSZ = 88$
+
+
+$ 
+$  èè`
+$ 
+
+$TA_POSEDGE = TA_EDGE$
+
+
+$ 
+$ ^[QbgË¶ÌÝ®«Ìè`
+$ 
+
+$TARGET_INTATR = TA_POSEDGE | TA_NEGEDGE | TA_BOTHEDGE | TA_LOWLEVEL$
+
+
+$ 
+$ ^[QbgË¶ÌÝnh®«Ìè`
+$ 
+
+$TARGET_INHATR = TA_NONKERNEL$
+
+
+$ 
+$ J[lÇOÝnhÍÅè³¹È¢½ß,
+$ INTNO_FIX_KERNEL
+$ INHNO_FIX_KERNEL
+$ INHNO_FIX_NONKERNEL
+$ INHNO_FIX_NONKERNEL
+$ ðè`µÈ¢.
+$ 
+
+
+$ 
+$  Wev[gt@CÌCN[h
+$ 
+$INCLUDE "kernel.tf"$
+
+
+
+$ 
+$  CFG_INTÌ^[QbgË¶ÌG[`FbN
+$ 
+
+$FOREACH intno INT.ORDER_LIST$
+$ IRQÝÔ©Ç¤©ð`FbN
+	$IF ( LENGTH( FIND( INTNO_INT, INT.INTNO[intno] ) ) != 0 )$
+
+$   TA_POSEDGEÆTA_NEGEDGEª¯ÉÝè³êÄ¢éê
+		$IF ((INT.INTATR[intno] & ( TA_POSEDGE | TA_NEGEDGE )) == ( TA_POSEDGE | TA_NEGEDGE ))$
+			$ERROR$ INT.TEXT_LINE[intno]:$FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "intatr", INT.INTATR[intno], INT.INTNO[intno], "CFG_INT")$$END$
+		$END$
+
+$   TA_POSEDGEÆTA_BOTHEDGEª¯ÉÝè³êÄ¢éê
+		$IF ((INT.INTATR[intno] & ( TA_POSEDGE | TA_BOTHEDGE )) == ( TA_POSEDGE | TA_BOTHEDGE ))$
+			$ERROR$ INT.TEXT_LINE[intno]:$FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "intatr", INT.INTATR[intno], INT.INTNO[intno], "CFG_INT")$$END$
+		$END$
+
+$   TA_NEGEDGEÆTA_BOTHEDGEª¯ÉÝè³êÄ¢éê
+		$IF ((INT.INTATR[intno] & ( TA_NEGEDGE | TA_BOTHEDGE )) == ( TA_NEGEDGE | TA_BOTHEDGE ))$
+			$ERROR$ INT.TEXT_LINE[intno]:$FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "intatr", INT.INTATR[intno], INT.INTNO[intno], "CFG_INT")$$END$
+		$END$
+
+$   TA_POSEDGEÆTA_NEGEDGEÆTA_BOTHEDGEª¯ÉÝè³êÄ¢éê
+		$IF ((INT.INTATR[intno] & ( TA_POSEDGE | TA_NEGEDGE | TA_BOTHEDGE )) == ( TA_POSEDGE | TA_NEGEDGE | TA_BOTHEDGE ))$
+			$ERROR$ INT.TEXT_LINE[intno]:$FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "intatr", INT.INTATR[intno], INT.INTNO[intno], "CFG_INT")$$END$
+		$END$
+
+	$ELSE$
+
+$   IRQÝÈOÌÝÉÎµÄÝ®«ªwè³êÄ¢éê
+		$IF (INT.INTATR[intno] & (~( TA_ENAINT | TA_EDGE ))) != 0$
+			$ERROR$ INT.TEXT_LINE[intno]:$FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "intatr", INT.INTATR[intno], INT.INTNO[intno], "CFG_INT")$$END$
+		$END$
+
+	$END$
+
+$END$
+
+
+
+$ 
+$ ÝÔ©çÝDæxyÑ®«ðæèo·e[u
+$ 
+
+/*$NL$
+$SPC$*$SPC$$SPC$Interrupt Level and Attribute Table$NL$
+$SPC$*/$NL$
+const CFG_INT_INFO _kernel_cfg_int_table[$LENGTH(INTNO_RANGE)$] = {$NL$
+$FOREACH intno INTNO_RANGE$
+$ ÝDæxðæ¾
+	$IF LENGTH(INT.INTNO[intno])$
+		$intpri = -INT.INTPRI[intno]$
+		$intatr = INT.INTATR[intno]$
+	$ELSE$
+		$intpri = "0"$
+		$intatr = "0xFFFFFFFF"$
+	$END$
+
+$ e[uÌgðoÍ
+	$TAB$$FORMAT("{ %2d, %08x }, /* %02u */", intpri, intatr, +intno)$$NL$
+$END$
+};$NL$$NL$
+
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_cfg1_out.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_cfg1_out.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_cfg1_out.h	(revision 164)
@@ -0,0 +1,48 @@
+/*
+ *		cfg1_out.cÌNÉKvÈX^uÌè`
+ */
+
+void sta_ker( void )
+{
+}
+
+void hardware_init_hook( void )
+{
+}
+
+void software_init_hook( void )
+{
+}
+
+const SIZE		_kernel_istksz = 0;
+
+STK_T *const	_kernel_istk = NULL;
+
+/*
+ *  ItZbgt@Cð¶¬·é½ßÌè`
+ */
+const uint8_t	MAGIC_1 = 0x12;
+const uint16_t	MAGIC_2 = 0x1234;
+const uint32_t	MAGIC_4 = 0x12345678;
+
+const TCB	TCB_enatex = {
+	{ NULL, NULL },			/* task_queue */
+	NULL,					/* p_tinib */
+	0U,						/* tstat */
+#ifdef TOPPERS_SUPPORT_MUTEX
+	0U,						/* bpriority */
+#endif /* TOPPERS_SUPPORT_MUTEX */
+	0U,						/* priority */
+	false,					/* acqeue */
+	false,					/* wupque */
+	true,					/* enatex */
+	0U,						/* texptn */
+	NULL,					/* p_winifo */
+#ifdef TOPPERS_SUPPORT_MUTEX
+	{ NULL, NULL },			/* mutex_queue */
+#endif /* TOPPERS_SUPPORT_MUTEX */
+#ifdef TOPPERS_SUPPORT_OVRHDR
+	0U,						/* leftotm */
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+	{ NULL, NULL }			/* tskctxb */
+};
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_check.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_check.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_check.tf	(revision 164)
@@ -0,0 +1,61 @@
+$ 
+$  TOPPERS/ASP Kernel
+$      Toyohashi Open Platform for Embedded Real-Time Systems/
+$      Advanced Standard Profile Kernel
+$ 
+$  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+$ 
+$  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$      XR[hÉÜÜêÄ¢é±ÆD
+$  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$      Ì³ÛØKèðfÚ·é±ÆD
+$  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$      ÆD
+$    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$        ñ·é±ÆD
+$  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$      ÆÓ·é±ÆD
+$ 
+$  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$  ÌÓCðíÈ¢D
+$ 
+$  @(#) $Id$
+$ 
+
+$ 
+$ 		pX3ÌvZbTË¶ev[giRX630pj
+$ 
+
+$ 
+$  `FbNû@Ìwè
+$ 
+$CHECK_FUNC_ALIGN = 1$
+$CHECK_FUNC_NONNULL = 1$
+$CHECK_STACK_ALIGN = 4$
+$CHECK_STACK_NONNULL = 1$
+$CHECK_MPF_ALIGN = 4$
+$CHECK_MPF_NONNULL = 1$
+
+$ 
+$  Wev[gt@CÌCN[h
+$ 
+$INCLUDE "kernel/kernel_check.tf"$
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_config.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_config.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_config.c	(revision 164)
@@ -0,0 +1,244 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		vZbTË¶W
+[iRX630pj
+ */
+
+#include "kernel_impl.h"
+#include "sil.h"
+
+
+/*
+ *  Ý­¶ñðÛ¶·éÏ
+ */
+uint16_t	intnest;
+
+/*
+ *  CPUbNtOÀ»Ì½ßÌÏ
+ */
+#if TIPM_LOCK != -15
+bool_t		lock_flag;		/* CPUbNtOÌlðÛ·éÏ */
+uint32_t	saved_ipl;		/* ÝDæxxðÛ¶·éÏ */
+#endif	/* TIPM_LOCK != -15	*/
+
+
+/*
+ *  vZbTË¶Ìú»
+ */
+void
+prc_initialize( void )
+{
+	/*
+	 *  Ý­¶ñÌú»
+	 *
+	 *  X^[gAbvÍSÝbNóÔ & ñ^XNReLXg
+	 *  ÉÄ®ì·é½ß, ñ^XNReLXgÉU·é.
+	 */
+	intnest = 1U;
+
+#if TIPM_LOCK != -15
+	/*
+	 *  CPUbNtOÀ»Ì½ßÌÏÌú»
+	 */
+	lock_flag = true;
+	saved_ipl = IPL_ENAALL;
+#endif	/* TIPM_LOCK != -15	*/
+}
+
+
+/*
+ *  vZbTË¶ÌI¹
+ */
+void
+prc_terminate( void )
+{
+	/*
+	 *  ÁÉKvÈÍÈ¢
+	 */
+}
+
+
+/*
+ *  CPUáOÌ­¶óµÌOoÍ
+ *
+ *  CPUáOnhÌ©çCCPUáOîñ|C^ip_excinfjðøÆµ
+ *  ÄÄÑo·±ÆÅCCPUáOÌ­¶óµðVXeOÉoÍ·éD
+ */
+#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 */
+
+
+/*
+ *  ÝvCÌ®«ÌÝè
+ *
+ *  ASPJ[lÅÌpðzèµÄCp[^G[ÍAT[VÅ`Fb
+ *  NµÄ¢éDcfg_intT[rXR[ðÝ¯éêÉÍCG[ðÔ·æ¤
+ *  É·×«Å ë¤D
+ */
+void
+x_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
+
+	/*
+	 *  ÝÌ}XN
+	 *
+	 *  Ýðó¯t¯½ÜÜCxgK^GbWgKÌÝèâC
+	 *  ÝDæxÌÝèðs¤ÌÍë¯È½ßCÝ®«É©©íç¸C
+	 *  êU}XN·éD
+	 */
+	( void )x_disable_int( intno );
+
+	/*
+	 *  xgK/GbWgKÌÝè
+	 *
+	 *  IRQÌÝT|[g·é
+	 */
+	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{
+			/*
+			 *  RtBM
+[^ÉÄ`FbNµÄ¢é½ß,
+			 *  ±±Ö­é±ÆÍ è¦È¢.
+			 */
+			irq_val = 0U;
+		}
+
+		sil_wrb_mem((uint8_t *)irqcr_reg_addr[irq_offset], irq_val);
+	}
+
+	/*
+	 *  ÝxÌÝè
+	 *
+	 *  ÝÔÉÎµ½IPRlðÝè·é.
+	 */
+	sil_wrb_mem((uint8_t *)ipr_reg_addr[intno], cfg_int_table[intno].intpri);
+
+	/*
+	 *  ÝÌ}XNð
+ 	 */
+	if( ( intatr & TA_ENAINT ) != 0U ){
+		( void )x_enable_int( intno );
+	}
+}
+
+
+#ifndef OMIT_DEFAULT_INT_HANDLER
+/*
+ *  ¢o^ÌÝª­¶µ½êÉÄÑo³êé
+ */
+void
+default_int_handler( void )
+{
+	syslog(LOG_EMERG, "Unregistered Interrupt occurs.");
+}
+#endif /* OMIT_DEFAULT_INT_HANDLER */
+
+#ifndef OMIT_DEFAULT_EXC_HANDLER
+/*
+ *  ¢o^ÌáOª­¶µ½êÉÄÑo³êé
+ */
+void
+default_exc_handler( void )
+{
+	syslog(LOG_EMERG, "Unregistered Expevt error occurs.");
+}
+#endif /* OMIT_DEFAULT_EXC_HANDLER */
+
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_config.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_config.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_config.h	(revision 164)
@@ -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) 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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		vZbTË¶W
+[iRX630pj
+ *
+ *  ±ÌCN[ht@CÍCtarget_config.hiÜ½ÍC»±©çCN
+ *  [h³êét@CjÌÝ©çCN[h³êéD¼Ìt@C©ç
+ *  ¼ÚCN[hµÄÍÈçÈ¢D
+ */
+
+#ifndef TOPPERS_PRC_CONFIG_H
+#define TOPPERS_PRC_CONFIG_H
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  vZbTÌÁê½ßÌCCÖè`
+ */
+#include "prc_insn.h"
+#include "sil.h"
+
+/*
+ *  ñ^XNReLXgpÌX^bNúl
+ */
+
+#define TOPPERS_ISTKPT( istk, istksz ) (( STK_T * )(( char * )( istk ) + ( istksz )))
+
+/*
+ *  ^XNReLXgubNÌè`
+ */
+typedef struct task_context_block {
+	void	(*start)(void);
+	void	*cpu_context;
+} TSKCTXB;
+
+
+/*
+ *  Ý­¶ñðÛ¶·éÏ
+ */
+extern uint16_t intnest;
+
+
+/*
+ *  CPUbNóÔÅÌÝDæx}XN
+ *
+ *  TIPM_LOCKÍCCPUbNóÔÅÌÝDæx}XNC·Èí¿CJ[l
+ *  ÇOÌàÌð­·×ÄÌÝvð}XN·élÉè`·éD
+ *
+ *  TMIN_INTPRIÏX·é±ÆÅÇOÝÌL³ðè·éD
+ *  á¦ÎTMIN_INTPRIð-14ÉÝè·éÆCx7ÌÝªJ[lÇOÆ
+ *  ÈéDTMIN_INTPRIð-15ÉÝè·éÆCNMIÈOÉJ[lÇOÌÝð
+ *  Ý¯È¢±ÆÉÈéi±ÌêÉÍ-15ÉÝè·é±Æð§·éjD
+ */
+#ifndef TIPM_LOCK
+#define TIPM_LOCK	TMIN_INTPRI
+#endif /* TIPM_LOCK */
+
+
+/*
+ *  TOPPERSWÝfÌÀ»
+ */
+/*
+ *  ReLXgÌQÆ
+ *
+ *  RXÅÍCÝÌßèæª^XN©Ç¤©ð»f·é½ßÉ intnest
+ *  ðgpµÄ¢éD±êðp¢ÄReLXgð»f·éD
+ */
+extern bool_t sense_context( void );
+
+
+/*
+ *  CPUbNtOÀ»Ì½ßÌÏ
+ *
+ *  ±êçÌÏÍCCPUbNóÔÌÌÝ«·¦Äæ¢àÌÆ·éD
+ */
+#if TIPM_LOCK != -15
+extern bool_t	lock_flag;		/* CPUbNtOÌlðÛ·éÏ */
+extern uint32_t	saved_ipl;		/* ÝDæxxðÛ¶·éÏ */
+#endif	/* TIPM_LOCK != -15	*/
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+
+/*
+ *  ÝDæx}XNÌO\»Æà\»ÌÏ·
+ *
+ *  RX630ÅÍCvZbTXe[^X[hWX^iPSWjÌº©ç
+ *  24`27rbgÚÌ4rbgÉÝDæxxiIPLjªu©êÄ¢éD
+ *  J[lÇOÝðÀ·éêÉIPLðgpµ½§äðs¤D
+ *  J[lÍÝDæx}XNi-1©çA±µ½ÌljÅÇ³êÄ
+ *  ¢é½ßIPLÆÌÏ·ªKvÆÈéD
+ */
+#define IPL_TO_IPM( ipl )	(-(( PRI )(( ipl ) >> 24U )))		/* IPLðIPMÉ	*/
+#define IPM_TO_IPL( ipm )	((( uint32_t )(-( ipm ))) << 24U )	/* IPMðIPLÉ	*/
+
+
+/*
+ *  CPUbNóÔÅÌÝDæx}XNÌIPL
+ */
+#define IPL_LOCK		( IPM_TO_IPL( TIPM_LOCK ) )
+
+/*
+ *  TIPM_ENAALLiÝDæx}XNSðjÌIPL
+ */
+#define IPL_ENAALL		( IPM_TO_IPL( TIPM_ENAALL ) )
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  ÝvöÌx & ®«è`e[u
+ *  (ev[gt@CÉæéoÍ)
+ */
+typedef struct cfg_int_info {
+	PRI		intpri;
+	ATR		intatr;
+} CFG_INT_INFO;
+
+extern const CFG_INT_INFO cfg_int_table[];
+
+
+/*
+ *  ÝÔÌÍÍÌ»è
+ *
+ *  ÝÔªLøÈl©µ§É`FbN·é½ß,
+ *  RtBM
+[^oÍe[uðQÆ·é.
+ */
+#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ÅLøÈÝÔÌwè  */
+#define VALID_INTNO_CREINT          VALID_INTNO_CFGINT((intno))
+
+/* cre_isrÅLøÈÝÔÌwè  */
+#define	VALID_INTNO_CREISR(intno)	VALID_INTNO_CFGINT((intno))
+
+
+/*
+ *  Ý§äWX^ÖAÌè`
+ */
+#define	IRQ_POSEDGE			( 0x08U )
+#define	IRQ_NEGEDGE			( 0x04U )
+#define	IRQ_BOTHEDGE		( 0x0CU )
+#define	IRQ_LOWLEVEL		( 0x00U )
+
+
+/*
+ *  CPUbNóÔÖÌÚs
+ *
+ *  IPMin[hEFAÌÝDæx}XNjðCsaved_iipmÉÛ¶µCJ[
+ *  lÇOÌàÌð­·×ÄÌÝvð}XN·éliTIPM_LOCKj
+ *  ÉÝè·éDÜ½Clock_flagðTRUEÉ·éD
+ *
+ *  IPMªCÅ©çTIPM_LOCKÆ¯¶©»êæè¢êÉÍC»êð
+ *  saved_iipmÉÛ¶·éÌÝÅCTIPM_LOCKÉÍÝèµÈ¢D±êÍCf
+ *  ãÌÝDæx}XNªCTIPM_LOCKÆ¯¶©»êæè¢xÉÝè
+ *  ³êÄ¢éóÔÉ ½éD
+ *
+ *  ±ÌÖÍCCPUbNóÔilock_flagªTRUEÌóÔjÅÄÎêé±ÆÍ
+ *  È¢àÌÆzèµÄ¢éD
+ */
+Inline void
+x_lock_cpu( void )
+{
+#if TIPM_LOCK == -15
+	disint();
+#else	/* TIPM_LOCK == -15	*/
+	uint32_t	ipl;
+
+	/*
+	 *  current_ipl()ÌÔèlð¼Úsaved_iplÉÛ¶¹¸CêÏipl
+	 *  ðp¢Ä¢éÌÍCcurrent_ipl()ðÄñ¾¼ãÉÝª­¶µC
+	 *  N®³ê½ÝÅsaved_iplªÏX³êéÂ\«ª é½ßÅ
+	 *   éD
+	 */
+	ipl = current_ipl();
+	if( IPL_LOCK > ipl ){
+		set_ipl( IPL_LOCK );
+	}
+
+	saved_ipl = ipl;
+	lock_flag = true;
+#endif	/* TIPM_LOCK == -15	*/
+}
+
+#define t_lock_cpu()	x_lock_cpu()
+#define i_lock_cpu()	x_lock_cpu()
+
+
+/*
+ *  CPUbNóÔÌð
+ *
+ *  lock_flagðFALSEÉµCIPMin[hEFAÌÝDæx}XNjðC
+ *  saved_iipmÉÛ¶µ½lÉß·D
+ *
+ *  ±ÌÖÍCCPUbNóÔilock_flagªtrueÌóÔjÅÌÝÄÎêéà
+ *  ÌÆzèµÄ¢éD
+ */
+Inline void
+x_unlock_cpu( void )
+{
+#if TIPM_LOCK == -15
+	enaint();
+#else	/* TIPM_LOCK == -15	*/
+	lock_flag = false;
+	set_ipl( saved_ipl );
+#endif	/* TIPM_LOCK == -15	*/
+}
+
+#define t_unlock_cpu()	x_unlock_cpu()
+#define i_unlock_cpu()	x_unlock_cpu()
+
+
+/*
+ *  CPUbNóÔÌQÆ
+ */
+extern bool_t t_sense_lock();
+extern bool_t i_sense_lock();
+extern bool_t x_sense_lock();
+
+/*
+ * ifãÌjÝDæx}XNÌÝè
+ *
+ *  CPUbNtOªNA³êÄ¢éÍCn[hEFAÌÝDæx}
+ *  XNðÝè·éDCPUbNtOªZbg³êÄ¢éÍCsaved_iipm
+ *  ðÝèµC³çÉCn[hEFAÌÝDæx}XNðCÝèµæ¤Æ
+ *  µ½ifãÌjÝDæx}XNÆTIPM_LOCKÌ¢ûÉÝè·éD
+ */
+Inline void
+x_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	*/
+}
+
+#define t_set_ipm( intpri )	x_set_ipm( intpri )
+#define i_set_ipm( intpri )	x_set_ipm( intpri )
+
+
+/*
+ * ifãÌjÝDæx}XNÌQÆ
+ *
+ *  CPUbNtOªNA³êÄ¢éÍn[hEFAÌÝDæx}
+ *  XNðCZbg³êÄ¢éÍsaved_iipmðQÆ·éD
+ */
+Inline PRI
+x_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 );
+}
+
+#define t_get_ipm()		x_get_ipm()
+#define i_get_ipm()		x_get_ipm()
+
+
+/*
+ *  ÝvÖ~tOÌZbg
+ *
+ *  Ý®«ªÝè³êÄ¢È¢ÝvCÉÎµÄÝvÖ~
+ *  tOðZbgµæ¤Æµ½êÉÍCFALSEðÔ·D
+ */
+Inline bool_t
+x_disable_int( INTNO intno )
+{
+	/*
+	 *  xè`ª0Å éêÍCFG_INT³êÄ¢È¢
+	 */
+	if( cfg_int_table[intno].intpri == 0 ){
+		return ( false );
+	}
+
+	sil_wrb_mem((uint8_t *)ier_reg_addr[intno].addr,
+		sil_reb_mem((uint8_t *)ier_reg_addr[intno].addr) & ~ier_reg_addr[intno].offset);
+
+	return ( true );
+}
+
+#define t_disable_int( intno )	x_disable_int( intno )
+#define i_disable_int( intno )	x_disable_int( intno )
+
+
+/*
+ *  ÝvÖ~tOÌNA
+ *
+ *  Ý®«ªÝè³êÄ¢È¢ÝvCÉÎµÄÝvÖ~
+ *  tOðNAµæ¤Æµ½êÉÍCFALSEðÔ·D
+ */
+Inline bool_t
+x_enable_int( INTNO intno )
+{
+	/*
+	 *  xè`ª0Å éêÍCFG_INT³êÄ¢È¢
+	 */
+	if( cfg_int_table[intno].intpri == 0 ){
+		return ( false );
+	}
+
+	sil_wrb_mem((uint8_t *)ier_reg_addr[intno].addr,
+		sil_reb_mem((uint8_t *)ier_reg_addr[intno].addr) | ier_reg_addr[intno].offset);
+
+	return ( true );
+}
+
+#define t_enable_int( intno )	x_enable_int( intno )
+#define i_enable_int( intno )	x_enable_int( intno )
+
+
+/*
+ *  ÝvÌNA
+ */
+Inline void
+x_clear_int( INTNO intno )
+{
+	sil_wrb_mem((uint8_t *)IR_REG(intno), 0U);
+}
+
+#define t_clear_int( intno )	x_clear_int( intno )
+#define i_clear_int( intno )	x_clear_int( intno )
+
+
+/*
+ *  ÝvÌ`FbN
+ */
+Inline bool_t
+x_probe_int( INTNO intno )
+{
+	/*
+	 *  ÝvWX^Í0 or 1Åµ©È¢½ß,
+	 *  »ÌÜÜÌlðÔ·.
+	 */
+	return sil_reb_mem((uint8_t *)IR_REG(intno));
+}
+
+#define t_probe_int( intno )	x_probe_int( intno )
+#define i_probe_int( intno )	x_probe_int( intno )
+
+/*
+ *  ÝvCÌ®«ÌÝè
+ */
+extern void	x_config_int( INTNO intno, ATR intatr, PRI intpri );
+
+/*
+ *  ÝnhÌüûÅKvÈIRCì
+ *
+ */
+extern void i_begin_int(INTNO intno);
+
+/*
+ *  ÝnhÌoûÅKvÈIRCì
+ *
+ */
+extern void i_end_int(INTNO intno);
+
+/*
+ *  ÅDæÊ^XNÖÌfBXpb`iprc_support.a30j
+ *
+ *  dispatchÍC^XNReLXg©çÄÑo³ê½T[rXR[©
+ *  çÄÑo·×«àÌÅC^XNReLXgECPUbNóÔEfBXpb
+ *  `ÂóÔEifãÌjÝDæx}XNSðóÔÅÄÑo³È
+ *  ¯êÎÈçÈ¢D
+ */
+extern void	dispatch( void );
+
+/*
+ *  fBXpb`Ì®ìJniprc_support.a30j
+ *
+ *  start_dispatchÍCJ[lN®ÉÄÑo·×«àÌÅC·×ÄÌ
+ *  ÝðÖ~µ½óÔiSÝbNóÔÆ¯ÌóÔjÅÄÑo³È¯êÎ
+ *  ÈçÈ¢D
+ */
+extern void	_start_dispatch( void );
+#define _kernel_start_dispatch()	_start_dispatch(); return
+
+/*
+ *  »ÝÌReLXgðÌÄÄfBXpb`iprc_support.a30j
+ *
+ *  exit_and_dispatchÍCext_tsk©çÄÑo·×«àÌÅC^XNReL
+ *  XgECPUbNóÔEfBXpb`ÂóÔEifãÌjÝDæ
+ *  x}XNSðóÔÅÄÑo³È¯êÎÈçÈ¢D
+ */
+#define _kernel_exit_and_dispatch();	\
+	_exit_and_dispatch();		\
+	ercd = E_SYS;
+
+extern void	_exit_and_dispatch( void ) NoReturn;
+
+/*
+ *  J[lÌI¹ÌÄoµiprc_support.a30j
+ *
+ *  call_exit_kernelÍCJ[lÌI¹ÉÄÑo·×«àÌÅCñ^XN
+ *  ReLXgÉØè·¦ÄCJ[lÌI¹iexit_kerneljðÄÑo
+ *  ·D
+ */
+extern void call_exit_kernel( void ) NoReturn;
+
+/*
+ *  ^XNReLXgÌú»
+ *
+ *  ^XNªx~óÔ©çÀsÅ«éóÔÉÚs·éÉÄÎêéD±Ì_
+ *  ÅX^bNÌæðgÁÄÍÈçÈ¢D
+ *
+ *  activate_contextðCCCÖÅÍÈ­}Nè`ÆµÄ¢éÌÍC
+ *  ±Ì_ÅÍTCBªè`³êÄ¢È¢½ßÅ éD
+ */
+extern void    start_r(void);
+
+extern void   *new_context(void *p_tcb);
+#define activate_context(p_tcb)												\
+{																			\
+	(p_tcb)->tskctxb.start = (void (*)(void))start_r;						\
+	(p_tcb)->tskctxb.cpu_context = new_context(p_tcb);						\
+}
+
+/*
+ *  calltexÍgpµÈ¢
+ */
+#define OMIT_CALLTEX
+
+
+/*
+ *  ÝnhÌÝè
+ *
+ *  RX630ÍROMÉÝxN^ðzu·é½ßC{ÖÍóÖÅÀ·éD
+ */
+extern void x_define_inh( INHNO inhno, FP inthdr );
+
+/*
+ *  CPUáOnhÌÝè
+ *
+ *  RX630ÍROMÉáOxN^ðzu·é½ßC{ÖÍóÖÅÀ·éD
+ */
+Inline void
+x_define_exc( EXCNO excno, FP exchdr )
+{
+}
+
+
+/*
+ *  Ý/áOnhÌüûÌ¶¬}N
+ *
+ *  ev[gt@CÉæè¶¬·é½ßó}NÆ·éD
+ */
+#define HDR_ENTRY(hdr, intexc_num , tobejmp)
+
+/*
+ *  ÝnhÌüûÌ¶¬}N
+ */
+#define _INT_ENTRY(inhno, inthdr)				_kernel_##inthdr##_##inhno##_entry
+#define INT_ENTRY(inhno, inthdr)				inthdr
+
+#define _INTHDR_ENTRY(inhno, inhno_num ,inthdr)	\
+		extern _kernel_##inthdr##_##inhno##_entry(void);
+#define INTHDR_ENTRY(inhno, inhno_num ,inthdr)	_INTHDR_ENTRY(inhno, inhno_num ,inthdr)
+
+
+/*
+ *  CPUáOnhÌüûÌ¶¬}N
+ */
+#define _EXC_ENTRY(excno , exchdr)					_kernel_##exchdr##_##excno##_entry
+#define EXC_ENTRY(excno , exchdr)					exchdr
+
+#define _EXCHDR_ENTRY(excno , excno_num , exchdr)	\
+		extern _kernel_##exchdr##_##excno##_entry(void);
+#define EXCHDR_ENTRY(excno , excno_num , exchdr)	_EXCHDR_ENTRY(excno , excno_num , exchdr)
+
+
+/*
+ *  CPUáOÌ­¶µ½ÌReLXgÌQÆ
+ *
+ *  CPUáOÌ­¶µ½ÌReLXgªC^XNReLXgÌÉFALSEC
+ *  »¤ÅÈ¢ÉtrueðÔ·D
+ */
+extern bool_t exc_sense_context( void *p_excinf );
+
+
+/*
+ *  CPUáOîñ p_excinf ©ç PSW Ìlðæ¾·é½ßÌItZbgl
+ *  EXCNO + ACC + FPSW + R1`R15 + PC
+ */
+#define EXC_GET_PSW_OFFSET	(4+8+4+60+4)
+
+/*
+ *  CPUáOÌ­¶µ½ÌIPLÌQÆ
+ */
+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áOÌ­¶µ½ÌReLXgÆÝÌ}XNóÔÌQÆ
+ *
+ *  CPUáOÌ­¶µ½ÌVXeóÔªCJ[lÀsÅÈ­C^XNR
+ *  eLXgÅ èCSÝbNóÔÅÈ­CCPUbNóÔÅÈ­Ci
+ *  fãÌjÝDæx}XNSðóÔÅ éÉtrueC»¤ÅÈ¢
+ *  ÉFALSEðÔ·iCPUáOªJ[lÇOÌÝÅ­¶µ½ê
+ *  ÉàFALSEðÔ·jD
+ *  
+ *  J[lÀsÅÈ¢¨ (TIPM_LOCK== -15) ItO == 1
+ *                         (else)           IPL < IPL_LOCK
+ *  ^XNReLXgÅ é¨intnest == 0
+ *  SÝbNÅÈ¢¨ ItO == 1
+ *  ÝDæx}XNªSð¨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áOÌ­¶µ½ÌReLXgÆÝ^CPUbNóÔÌQÆ
+ *
+ *  CPUáOÌ­¶µ½ÌVXeóÔªCJ[lÀsÅÈ­C^XNR
+ *  eLXgÅ èCSÝbNóÔÅÈ­CCPUbNóÔÅÈ¢É
+ *  trueC»¤ÅÈ¢ÉfalseðÔ·iCPUáOªJ[lÇOÌÝ
+ *  Å­¶µ½êÉàfalseðÔ·jD
+ *  
+ *  J[lÀsÅÈ¢¨ (TIPM_LOCK== -15) ItO == 1
+ *                         (else)           IPL < TIPM_LOCK
+ *  ^XNReLXgÅ é¨intnest < 1 
+ *  SÝbNÅÈ¢¨ ItO == 1
+ *  CPUbNóÔÅÈ¢¨(TIPM_LOCK== -15) ItO == 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
+}
+
+
+/*
+ *  vZbTË¶Ìú»
+ */
+extern void	prc_initialize( void );
+
+/*
+ *  vZbTË¶ÌI¹
+ */
+extern void	prc_terminate( void );
+
+
+#ifndef OMIT_DEFAULT_INT_HANDLER
+/*
+ *  ¢o^ÌÝª­¶µ½êÉÄÑo³êé
+ */
+void default_int_handler( void );
+#endif /* OMIT_DEFAULT_INT_HANDLER */
+
+#ifndef OMIT_DEFAULT_EXC_HANDLER
+/*
+ *  ¢o^ÌáOª­¶µ½êÉÄÑo³êé
+ */
+void default_exc_handler( void );
+#endif /* OMIT_DEFAULT_EXC_HANDLER */
+
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif /* TOPPERS_PRC_CONFIG_H */
+
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_def.csv
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_def.csv	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_def.csv	(revision 164)
@@ -0,0 +1,13 @@
+TA_LOWLEVEL,TA_LOWLEVEL
+TA_BOTHEDGE,TA_BOTHEDGE
+TA_NEGEDGE,TA_NEGEDGE
+TIPM_LOCK,TIPM_LOCK,signed
+IPL_LOCK,IPL_LOCK
+PSW_I_MASK,PSW_I_MASK
+PSW_IPL_MASK,PSW_IPL_MASK
+EXC_GET_PSW_OFFSET,EXC_GET_PSW_OFFSET
+sizeof_TCB,sizeof(TCB)
+offsetof_TCB_p_tinib,"offsetof(TCB,p_tinib)"
+offsetof_TCB_texptn,"offsetof(TCB,texptn)"
+offsetof_TCB_start,"offsetof(TCB,tskctxb.start)"
+offsetof_TCB_cpu_context,"offsetof(TCB,tskctxb.cpu_context)"
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_insn.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_insn.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_insn.h	(revision 164)
@@ -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,2006 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		vZbTÌÁê½ßÌCCÖè`iRX630pj
+ */
+
+#ifndef	TOPPERS_PRC_INSN_H
+#define	TOPPERS_PRC_INSN_H
+
+
+extern uint32_t current_psw( void );
+extern void set_psw( uint32_t psw );
+Inline uint32_t current_ipl( void );
+Inline void set_ipl( uint32_t ipl );
+extern void disint( void );
+extern void enaint( void );
+static uint16_t rev_endian_uint16( uint16_t data );
+static uint32_t rev_endian_uint32( uint32_t data );
+
+
+/*
+ *  ItO, IPLðæ¾·é½ßÌ}Nè`
+ */
+#define PSW_I_MASK		( 0x00010000UL )
+#define PSW_IPL_MASK	( 0x0F000000UL )
+
+
+/*
+ *  vZbTXe[^XWX^(PSW)Ì»ÝlÌÇoµ
+ */
+extern uint32_t current_psw( void );
+
+
+/*
+ *  vZbTXe[^XWX^(PSW)ÖÝè
+ */
+extern void set_psw( uint32_t psw );
+
+
+/*
+ *  IPLÌ»ÝlÌÇoµ
+ */
+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ð­·×ÄÌÝÌÖ~
+ */
+extern void disint( void );
+
+/*
+ *  NMIð­·×ÄÌÝÌÂ
+ */
+extern void enaint( void );
+
+/*
+ *  GfBAÏ· 16bit
+ */
+Inline uint16_t
+rev_endian_uint16( uint16_t data )
+{
+	return (data >> 8) | (data << 8);
+}
+
+/*
+ *  GfBAÏ· 32bit
+ */
+Inline uint32_t
+rev_endian_uint32( uint32_t data )
+{
+	return (data >> 24) | ((data >> 8) & 0xFF) | ((data << 8) & 0xFF) | (data << 24);
+}
+
+
+#endif /* TOPPERS_PRC_INSN_H */
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_kernel.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_kernel.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_kernel.h	(revision 164)
@@ -0,0 +1,104 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ */
+
+/*
+ *		kernel.hÌvZbTË¶iRX630pj
+ *
+ *  ±ÌCN[ht@CÍCtarget_kernel.hiÜ½ÍC»±©çCN
+ *  [h³êét@CjÌÝ©çCN[h³êéD¼Ìt@C©ç
+ *  ¼ÚCN[hµÄÍÈçÈ¢D
+ */
+
+#ifndef TOPPERS_PRC_KERNEL_H
+#define TOPPERS_PRC_KERNEL_H
+
+/*
+ *  J[l{ÌðRpC·é½ßÌ}Nè`
+ *
+ *  {Â«ÅÍ1Öð1IuWFNgt@CÉRpC·é±ÆªÅ«È¢½ßC
+ *  ALLFUNC}Nðè`·éD
+ */
+#define ALLFUNC
+
+
+/*
+ *  T|[g·é@\Ìè`
+ */
+#define TOPPERS_TARGET_SUPPORT_DIS_INT		/* dis_intðT|[g·é */
+#define TOPPERS_TARGET_SUPPORT_ENA_INT		/* ena_intðT|[g·é */
+
+
+/*
+ *  J[lÇÌÝDæxÌÍÍ
+ *
+ *  TMIN_INTPRIÌè`ðÏX·é±ÆÅCÇÌxæèà¢ÝDæx
+ *  ðÂàÌðJ[lÇOÌÝÆ·é©ðÏXÅ«éD
+ *
+ *  TMIN_INTPRIÉÝèÅ«élÍC-15`-1ÌÍÍÅ éDá¦ÎTMIN_INTPRI
+ *  ð-14ÉÝè·éÆCNMIÉÁ¦Äx7ÌÝªJ[lÇOÆÈéD
+ *  TMIN_INTPRIð-15ÉÝè·éÆCNMIÈOÉJ[lÇOÌÝð
+ *  Ý¯È¢±ÆÉÈéD
+ */
+#ifndef TMIN_INTPRI
+#define TMIN_INTPRI		( -15 )		/* ÝDæxÌÅ¬liÅlj*/
+#endif /* TMIN_INTPRI */
+#define TMAX_INTPRI		( -1 )		/* ÝDæxÌÅåliÅálj */
+
+
+/*
+ *  Ý®«Ìè`
+ */
+#define	TA_POSEDGE		TA_EDGE			/* |WeBuGbWgK */
+#define	TA_NEGEDGE		UINT_C( 0x04 )	/* lKeBuGbWgK */
+#define	TA_BOTHEDGE		UINT_C( 0x08 )	/* ¼GbWgK */
+
+#define	TA_LOWLEVEL		UINT_C( 0x10 )	/* Lx */
+
+
+/*
+ *  ftHgÌÝ/áOnhÌL³
+ */
+/*#define	OMIT_DEFAULT_INT_HANDLER*/
+/*#define	OMIT_DEFAULT_EXC_HANDLER*/
+
+
+#endif /* TOPPERS_PRC_KERNEL_H */
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_offset.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_offset.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_offset.tf	(revision 164)
@@ -0,0 +1,19 @@
+$ 
+$ 		ItZbgt@C¶¬pev[gt@CiRX630pj
+$ 
+
+$ 
+$  ItZbglÌ}Nè`Ì¶¬
+$ 
+$DEFINE("TCB_p_tinib", offsetof_TCB_p_tinib)$
+$DEFINE("TCB_texptn", offsetof_TCB_texptn)$
+$DEFINE("TCB_sp", offsetof_TCB_sp)$
+$DEFINE("TCB_pc", offsetof_TCB_pc)$
+
+$DEFINE("TINIB_exinf", offsetof_TINIB_exinf)$
+$DEFINE("TINIB_task", offsetof_TINIB_task)$
+
+$ 
+$  rbgItZbglÌ}Nè`Ì¶¬
+$ 
+$DEFINE_BIT("TCB_enatex", sizeof_TCB, "B")$
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_rename.def
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_rename.def	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_rename.def	(revision 164)
@@ -0,0 +1,27 @@
+# prc_config.c
+intnest
+lock_flag
+saved_ipl
+prc_initialize
+prc_terminate
+x_config_int
+default_int_handler
+default_exc_handler
+
+# prc_support.src
+dispatch
+start_dispatch
+exit_and_dispatch
+call_exit_kernel
+start_r
+interrupt
+exception
+
+# rx610_config.c
+ipr_reg_addr
+ier_reg_addr
+ir_reg_addr
+irqcr_reg_addr
+
+# kernel_cfg.c
+cfg_int_table
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_rename.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_rename.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_rename.h	(revision 164)
@@ -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_config.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 x_config_int				_kernel_x_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_config.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_config.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 _x_config_int				__kernel_x_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_config.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: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_sil.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_sil.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_sil.h	(revision 164)
@@ -0,0 +1,153 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		sil.hÌvZbTË¶iRX630pj
+ */
+
+#ifndef TOPPERS_PRC_SIL_H
+#define TOPPERS_PRC_SIL_H
+
+#define TOPPERS_OMIT_SIL_ACCESS
+
+#ifndef TOPPERS_MACRO_ONLY
+#include "prc_insn.h"
+
+
+/*
+ *  8rbgPÊÌÇoµ^Ý
+ */
+#ifdef UINT8_MAX
+
+extern uint8_t sil_reb_mem(volatile uint8_t *mem);
+extern void sil_wrb_mem(volatile uint8_t *mem, uint8_t data);
+
+#endif /* UINT8_MAX */
+
+/*
+ *  16rbgPÊÌÇoµ^Ý
+ */
+
+extern uint16_t sil_reh_mem(volatile uint16_t *mem);
+extern void sil_wrh_mem(volatile uint16_t *mem, uint16_t data);
+
+#define	sil_reh_lem(mem)		sil_reh_mem(mem)
+#define	sil_wrh_lem(mem, data)	sil_wrh_mem(mem, data)
+
+extern uint16_t sil_reh_bem(volatile uint16_t *mem);
+extern void sil_wrh_bem(volatile uint16_t *mem, uint16_t data);
+
+/*
+ *  32rbgPÊÌÇoµ^Ý
+ */
+
+extern uint32_t sil_rew_mem(volatile uint32_t *mem);
+extern void sil_wrw_mem(volatile uint32_t *mem, uint32_t data);
+
+#define	sil_rew_lem(mem)		sil_rew_mem(mem)
+#define	sil_wrw_lem(mem, data)	sil_wrw_mem(mem, data)
+
+extern uint32_t sil_rew_bem(volatile uint32_t *mem);
+extern void sil_wrw_bem(volatile uint32_t *mem, uint32_t data);
+
+/*
+ *  SÝÖ~
+ */
+Inline uint32_t
+TOPPERS_disint( void )
+{
+	volatile uint32_t	TOPPERS_psw;
+
+	TOPPERS_psw = current_psw();
+	disint();
+
+	return( TOPPERS_psw );
+}
+
+
+/*
+ *  SÝÂ
+ */
+Inline void
+TOPPERS_enaint( uint32_t TOPPERS_psw )
+{
+	//if((TOPPERS_psw & PSW_I_MASK) != 0){
+		enaint();
+	//}
+}
+
+
+/*
+ *  SÝbNóÔÌ§ä
+ */
+#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 ) )
+
+
+/*
+ *  GfBAÌ½]
+ *
+ *  {J­Â«ÅÍGfBAÏ·½ßª¶Ý·é½ß,
+ *  A[LeN`Ë¶ÉÄ}Nðã«·é.
+ */
+#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 );
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+
+/*
+ *  vZbTÌGfBA
+ */
+#define SIL_ENDIAN_LITTLE			/* gGfBA */
+
+
+#endif /* TOPPERS_PRC_SIL_H */
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_stddef.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_stddef.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_stddef.h	(revision 164)
@@ -0,0 +1,59 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		t_stddef.hÌvZbTË¶iRX630pj
+ *
+ *  ±ÌCN[ht@CÍCtarget_stddef.hiÜ½ÍC»±©çCN
+ *  [h³êét@CjÌÝ©çCN[h³êéD¼Ìt@C©ç
+ *  ¼ÚCN[hµÄÍÈçÈ¢D
+ */
+
+#ifndef TOPPERS_PRC_STDDEF_H
+#define TOPPERS_PRC_STDDEF_H
+
+/*
+ *  ^[Qbgð¯Ê·é½ßÌ}NÌè`
+ */
+#define TOPPERS_RX630				/* vZbTªÌ */
+
+#endif /* TOPPERS_PRC_STDDEF_H */
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_support.cpp
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_support.cpp	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_support.cpp	(revision 164)
@@ -0,0 +1,206 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2014 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+#include "StdAfx.h"
+#include "prc_insn.h"
+#include "WinKernel.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+// ähsqnmJ[l
+extern CKernel *g_Kernel;
+
+uint32_t psw = PSW_I_MASK;
+
+uint32_t current_psw(void)
+{
+	return psw;
+}
+
+void set_psw(uint32_t psw)
+{
+	uint32_t temp = ::psw ^ psw;
+
+	::psw = psw;
+
+	if((temp & PSW_I_MASK) != 0) {
+		if((psw & PSW_I_MASK) != 0)
+			g_Kernel->LockCPU();
+		else
+			g_Kernel->UnlockCPU();
+	}
+}
+
+/*
+ *  NMIð­·×ÄÌÝÌÖ~
+ */
+void disint(void)
+{
+	g_Kernel->LockCPU();
+
+	psw |= PSW_I_MASK;
+}
+
+/*
+ *  NMIð­·×ÄÌÝÌÂ
+ */
+void enaint(void)
+{
+	psw &= ~PSW_I_MASK;
+
+	g_Kernel->UnlockCPU();
+}
+
+/*
+ *  ÝnhÌÝè
+ */
+void x_define_inh(uint_t inhno, FP int_entry)
+{
+	g_Kernel->DefineInterruptHandler(inhno, int_entry);
+}
+
+void i_begin_int(INTNO intno)
+{
+	g_Kernel->BeginInt();
+}
+
+void i_end_int(INTNO intno)
+{
+	g_Kernel->EndInt();
+}
+
+bool starting = true;
+
+bool_t t_sense_lock()
+{
+	return g_Kernel->CurrentIsLocked();
+}
+
+bool_t i_sense_lock()
+{
+	return g_Kernel->IsLocked();
+}
+
+bool_t x_sense_lock()
+{
+	if(g_Kernel->InTaskContext())
+		return g_Kernel->CurrentIsLocked();
+	else
+		return g_Kernel->IsLocked();
+}
+
+/*
+ *  ReLXgÌQÆ
+ */
+bool_t sense_context(void)
+{
+	return !g_Kernel->InTaskContext() && !starting;
+}
+
+/*
+ *  CPUáOÌ­¶µ½ÌReLXgÌQÆ
+ */
+bool_t exc_sense_context( void *p_excinf )
+{
+	return !g_Kernel->InTaskContext() && !starting;
+}
+
+/*
+ *  J[lN®^XNfBXpb`
+ */
+void _start_dispatch(void)
+{
+	starting = false;
+}
+
+/*
+ *  ^XNfBXpb`
+ */
+void dispatch(void)
+{
+	g_Kernel->Dispatch();
+}
+
+/*
+ *  »ÝÌReLXgðÌÄÄfBXpb`
+ */
+void _exit_and_dispatch(void)
+{
+	g_Kernel->ExitAndDispatch();
+}
+
+/*
+ *  J[lÌI¹ÌÄoµ
+ * 
+ *  X^bNðñ^XNReLXgpÉØèÖ¦D
+ * 
+ */
+void call_exit_kernel(void)
+{
+	g_Kernel->Terminate();
+}
+
+/*
+ *  ^XNN®
+ * 
+ */ 
+void start_r(void)
+{
+#if TIPM_LOCK != -15
+	lock_flag = false;
+#endif	/* TIPM_LOCK != -15	*/
+}
+
+extern "C" void Throw()
+{
+	throw std::exception();
+}
+
+extern "C" void trigger_cpu_exception( void )
+{
+	throw std::exception();
+}
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_syssvc.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_syssvc.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_syssvc.h	(revision 164)
@@ -0,0 +1,60 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		eXgvOÌ^[QbgË¶è`iRX630pj
+ */
+
+#ifndef TOPPERS_PRC_SYSSVC_H
+#define TOPPERS_PRC_SYSSVC_H
+
+/*
+ *  N®bZ[WÉ^[QbgË¶Ìì \¦ð
+ *  ÇÁ·é½ßÌ}ND
+ */
+#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: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_test.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_test.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_test.h	(revision 164)
@@ -0,0 +1,56 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		eXgvOÌ^[QbgË¶è`iRX630pj
+ */
+
+#ifndef TOPPERS_PRC_TEST_H
+#define TOPPERS_PRC_TEST_H
+
+#define CPUEXC1					25		/* ®¬_áO */
+#define RAISE_CPU_EXCEPTION		trigger_cpu_exception()
+
+extern void trigger_cpu_exception( void );
+
+#endif /* TOPPERS_PRC_TEST_H */
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_unrename.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_unrename.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/prc_unrename.h	(revision 164)
@@ -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_config.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_config.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_config.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_config.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: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/rx630.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/rx630.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/rx630.h	(revision 164)
@@ -0,0 +1,1915 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  RX630ÉË¶·éè`
+ */
+#ifndef TOPPERS_RX630_H
+#define TOPPERS_RX630_H
+
+/*
+ *  CPUáOnhÔÌè`(ÅèxN^e[u)
+ *
+ *  ÔÌÍÍÍ0 - 31
+ */
+#define INT_PRIVILEGED_INSTRUNCTION		20		/* Á ½ßáO */
+#define INT_UNDEF_INSTRUNCTION			23		/* ¢è`½ßáO */
+#define INT_FLOATINGPOINT_INSTRUCTION	25		/* ®¬_áO */
+#define INT_NMI							30		/* m}XJuèÝ */
+#define INT_RESET						31		/* Zbg */
+
+/*
+ *  ÝÔÌè`(ÂÏxN^e[u)
+ */
+#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
+
+/*
+ *  eW
+[ÌWX^yÑÝèrbgîñ
+ */
+
+#define SYSTEM_SYSCR0_ADDR		( ( volatile uint16_t __evenaccess * )0x00080006 )
+
+/*
+ * W
+[XgbvRg[WX^AiMSTPCRAj
+ */
+#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)
+
+/*
+ * W
+[XgbvRg[WX^BiMSTPCRBj
+ */
+#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 )
+
+/*
+ * W
+[XgbvRg[WX^CiMSTPCRCj
+ */
+#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 )
+
+/*
+ * NbN­¶ñH
+ */
+#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 )
+
+/*
+ * veNgWX^
+ */
+#define SYSTEM_PRCR_ADDR		( ( volatile uint16_t __evenaccess * )0x000803FE )
+
+/*
+ * èÝvWX^
+ */
+#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 )
+
+/*
+ * èÝvæÝèWX^
+ */
+#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 )
+
+/*
+ * èÝvÂWX^
+ */
+#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 )
+
+/* 
+ * èÝvövCIeBWX^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_BIT				( 7U << 0U )
+
+
+/*
+ *  IRQRg[WX^
+ */
+#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 )
+
+
+/*
+ *  e`lÌWX^yÑÝèrbgîñ
+ */
+#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 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|[gÌWX^yÑÝèrbgîñ
+ */
+#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 )
+
+/*
+ *  }`t@NVsRg[ÌWX^îñ
+ */
+#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 )
+
+/*
+ * A^CNbN
+ */
+#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 rbgA/D Ro[^
+ */
+#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 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_TIORL_IOA_OFFSET	( 0U )
+#define TPU_TIORL_IOA_MASK		( 0xFU << TPU_TIORL_IOA_OFFSET )
+#define TPU_TIORL_IOB_OFFSET	( 4U )
+#define TPU_TIORL_IOB_MASK		( 0xFU << TPU_TIORL_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 )
+
+/*
+ * 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ÖAÌè`
+ *
+ *  pdicÌrx600/rx630_uart.cÅgp·éD
+ */
+/*
+ *  VAI/OÌÂ
+ */
+#define TNUM_SIOP	( 2 )
+
+#endif	/* TOPPERS_RX630_H */
+
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/rx630.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/rx630.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/rx630.tf	(revision 164)
@@ -0,0 +1,51 @@
+$ 
+$		A[LeN`Ë¶ev[giRX630pj
+$ 
+
+
+
+/*$NL$
+$SPC$*  Architecture-dependent Definitions (RX630)$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 
+$  ÝÔÆÝnhÔÌè`
+$ 
+$  RX630ÅÍÝÔÆÝnhÔª1Î1ÅÎ·éD
+$ 
+
+$INTNO_VALID = { 16, 21, 23 ; 27, 28,...,59 ; 62 ; 64, 65,...,79 ; 90, 91, 92, 93, 98, 102 ; 106, 107,...,112 ; 114 ; 122, 123,...,167 ; 170, 171,...,203 ; 214, 215,...,253 }$
+$INHNO_VALID = INTNO_VALID$
+
+$ 
+$  áOÔÌè`
+$ 
+$  ÅèxN^e[uÌxN^e[uAhXÌ¬³¢ÔÉáOÔðUéD
+$  (\ñÌæàÜÞ)
+$ 
+
+$EXCNO_VALID = { 20, 23, 25, 30 }$
+
+$ 
+$  INTÝÌÔ
+$ 
+
+$INTNO_INT = { 64, 65,...,79 }$
+
+$ 
+$  ÝÔCÝnhÔCáOÔÌÍÍ
+$ 
+$ (\ñÌæàÜÞ)
+$ 
+
+$INTNO_RANGE = { 0, 1,...,255 }$
+$INHNO_RANGE = INTNO_RANGE$
+$EXCNO_RANGE = { 0, 1,...,31 }$
+
+$ 
+$  vZbTË¶Ìev[gt@CÌCN[h
+$ 
+
+$INCLUDE"rx630_msvc/prc.tf"$
+
Index: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/rx630_config.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/rx630_config.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/rx630_config.c	(revision 164)
@@ -0,0 +1,600 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		vZbTË¶W
+[iRX630pj
+ */
+
+#include "kernel_impl.h"
+
+
+/*
+ *  ÝvövCIeBWX^AhXe[u
+ */
+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  oXG[ 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  CMTjbg0 CMT0 */
+	ICU_IPR005_ADDR,				/* No.29  CMTjbg0 CMT1 */
+	ICU_IPR006_ADDR,				/* No.30  CMTjbg1 CMT2 */
+	ICU_IPR007_ADDR,				/* No.31  CMTjbg1 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  O[q IRQ0 */
+	ICU_IPR065_ADDR,				/* No.65  O[q IRQ1 */
+	ICU_IPR066_ADDR,				/* No.66  O[q IRQ2 */
+	ICU_IPR067_ADDR,				/* No.67  O[q IRQ3 */
+	ICU_IPR068_ADDR,				/* No.68  O[q IRQ4 */
+	ICU_IPR069_ADDR,				/* No.69  O[q IRQ5 */
+	ICU_IPR070_ADDR,				/* No.70  O[q IRQ6 */
+	ICU_IPR071_ADDR,				/* No.71  O[q IRQ7 */
+	ICU_IPR072_ADDR,				/* No.72  O[q IRQ8 */
+	ICU_IPR073_ADDR,				/* No.73  O[q IRQ9 */
+	ICU_IPR074_ADDR,				/* No.74  O[q IRQ10 */
+	ICU_IPR075_ADDR,				/* No.75  O[q IRQ11 */
+	ICU_IPR076_ADDR,				/* No.76  O[q IRQ12 */
+	ICU_IPR077_ADDR,				/* No.77  O[q IRQ13 */
+	ICU_IPR078_ADDR,				/* No.78  O[q IRQ14 */
+	ICU_IPR079_ADDR,				/* No.79  O[q 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  \ñ */
+};
+
+
+/*
+ *  ÝvÂWX^AhXe[u
+ */
+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  oXG[ 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  CMTjbg0 CMT0 */
+	{ ICU_IER03_ADDR, ICU_IEN5_BIT },	/* No.29  CMTjbg0 CMT1 */
+	{ ICU_IER03_ADDR, ICU_IEN6_BIT },	/* No.30  CMTjbg1 CMT2 */
+	{ ICU_IER03_ADDR, ICU_IEN7_BIT },	/* No.31  CMTjbg1 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  O[q IRQ0 */
+	{ ICU_IER08_ADDR, ICU_IEN1_BIT },	/* No.65  O[q IRQ1 */
+	{ ICU_IER08_ADDR, ICU_IEN2_BIT },	/* No.66  O[q IRQ2 */
+	{ ICU_IER08_ADDR, ICU_IEN3_BIT },	/* No.67  O[q IRQ3 */
+	{ ICU_IER08_ADDR, ICU_IEN4_BIT },	/* No.68  O[q IRQ4 */
+	{ ICU_IER08_ADDR, ICU_IEN5_BIT },	/* No.69  O[q IRQ5 */
+	{ ICU_IER08_ADDR, ICU_IEN6_BIT },	/* No.70  O[q IRQ6 */
+	{ ICU_IER08_ADDR, ICU_IEN7_BIT },	/* No.71  O[q IRQ7 */
+	{ ICU_IER09_ADDR, ICU_IEN0_BIT },	/* No.72  O[q IRQ8 */
+	{ ICU_IER09_ADDR, ICU_IEN1_BIT },	/* No.73  O[q IRQ9 */
+	{ ICU_IER09_ADDR, ICU_IEN2_BIT },	/* No.74  O[q IRQ10 */
+	{ ICU_IER09_ADDR, ICU_IEN3_BIT },	/* No.75  O[q IRQ11 */
+	{ ICU_IER09_ADDR, ICU_IEN4_BIT },	/* No.76  O[q IRQ12 */
+	{ ICU_IER09_ADDR, ICU_IEN5_BIT },	/* No.77  O[q IRQ13 */
+	{ ICU_IER09_ADDR, ICU_IEN6_BIT },	/* No.78  O[q IRQ14 */
+	{ ICU_IER09_ADDR, ICU_IEN7_BIT },	/* No.79  O[q 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 \ñ */
+};
+
+
+/*
+ *  IRQRg[WX^AhXe[u
+ */
+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: UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/rx630_config.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/rx630_config.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/arch/rx630_msvc/rx630_config.h	(revision 164)
@@ -0,0 +1,106 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		vZbTË¶W
+[iRX630pj
+ *
+ *  ±ÌCN[ht@CÍCtarget_config.hiÜ½ÍC»±©çCN
+ *  [h³êét@CjÌÝ©çCN[h³êéD¼Ìt@C©ç
+ *  ¼ÚCN[hµÄÍÈçÈ¢D
+ */
+
+
+#ifndef TOPPERS_RX630_CONFIG_H
+#define TOPPERS_RX630_CONFIG_H
+
+
+/*
+ *  Ývö
+ */
+#define	INHNO_MAX	UINT_C( 256 )
+
+
+/*
+ *  Ý§äp^è`
+ */
+typedef struct ier_info {
+	volatile uint8_t __evenaccess	*addr;
+			 uint8_t				offset;
+} IER_INFO;
+
+
+/*
+ *  Ý§äpè`
+ */
+#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)))
+
+/*
+ *  Ý§äpe[u
+ */
+
+/* ÝvövCIeBWX^AhX */
+extern volatile uint8_t __evenaccess * const ipr_reg_addr[];
+/* ÝvÂWX^AhX */
+extern const IER_INFO ier_reg_addr[];
+/* ÝvWX^AhX */
+extern volatile uint8_t __evenaccess * const ir_reg_addr[];
+/* IRQRg[WX^AhX */
+extern volatile uint8_t __evenaccess * const irqcr_reg_addr[];
+
+
+/*
+ *  vZbTË¶W
+[iRX630pj
+ */
+#include "rx630_msvc/prc_config.h"
+
+#endif	/* TOPPERS_RX630_CONFIG_H */
+
Index: UsbWattMeter/trunk/asp_dcre/include/histogram.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/include/histogram.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/include/histogram.h	(revision 164)
@@ -0,0 +1,80 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ÀsÔªzWvW
+[
+ */
+
+#ifndef TOPPERS_HISTOGRAM_H
+#define TOPPERS_HISTOGRAM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  ÀsÔªzvªÌú»
+ */
+extern void	init_hist(ID histid, uint_t maxval, uint_t histarea[]);
+
+/*
+ *  ÀsÔvªÌJn
+ */
+extern void	begin_measure(ID histid);
+
+/*
+ *  ÀsÔvªÌI¹
+ */
+extern void	end_measure(ID histid);
+
+/*
+ *  ÀsÔªzvªÌ\¦
+ */
+extern void	print_hist(ID histid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_HISTOGRAM_H */
Index: UsbWattMeter/trunk/asp_dcre/include/itron.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/include/itron.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/include/itron.h	(revision 164)
@@ -0,0 +1,142 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  $Id$
+ */
+
+/*
+ *		ITRONdl¤ÊKèÌf[^^EèE}N
+ *
+ *  ±Ìwb_t@CÍCITRONdl¤ÊKèÌf[^^EèE}NÌ
+ *  ÅCTOPPERS¤Êwb_t@CÉÜÜêÈ¢àÌÌè`ðÜÞDITRONd
+ *  lÆÌÝ·«ðKvÆ·éAvP[VªCN[h·é±Æðz
+ *  èµÄ¢éD
+ *
+ *  AZu¾êÌ\[Xt@C©ç±Ìt@CðCN[h·é
+ *  ÍCTOPPERS_MACRO_ONLYðè`µÄ¨­D±êÉæèC}Nè`ÈOð
+ *  ­æ¤ÉÈÁÄ¢éD
+ */
+
+#ifndef TOPPERS_ITRON_H
+#define TOPPERS_ITRON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  TOPPERS¤Êwb_t@C
+ */
+#include "t_stddef.h"
+
+/*
+ *  ITRONdl¤Êf[^^
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+#ifdef INT8_MAX
+typedef	int8_t			B;			/* t«8rbg® */
+#endif /* INT8_MAX */
+
+#ifdef UINT8_MAX
+typedef	uint8_t			UB;			/* ³µ8rbg® */
+typedef	uint8_t			VB;			/* ^ªèÜçÈ¢8rbgÌl */
+#endif /* UINT8_MAX */
+
+typedef	int16_t			H;			/* t«16rbg® */
+typedef	uint16_t		UH;			/* ³µ16rbg® */
+typedef	uint16_t		VH;			/* ^ªèÜçÈ¢16rbgÌl */
+
+typedef	int32_t			W;			/* t«32rbg® */
+typedef	uint32_t		UW;			/* ³µ32rbg® */
+typedef	uint32_t		VW;			/* ^ªèÜçÈ¢32rbgÌl */
+
+#ifdef INT64_MAX
+typedef	int64_t			D;			/* t«64rbg® */
+#endif /* INT64_MAX */
+
+#ifdef UINT64_MAX
+typedef	uint64_t		UD;			/* ³µ64rbg® */
+typedef	uint64_t		VD;			/* ^ªèÜçÈ¢64rbgÌl */
+#endif /* UINT64_MAX */
+
+typedef	void			*VP;		/* ^ªèÜçÈ¢àÌÖÌ|C^ */
+
+typedef int_t			INT;		/* ©RÈTCYÌt«® */
+typedef uint_t			UINT;		/* ©RÈTCYÌ³µ® */
+
+typedef bool_t			BOOL;		/* ^Ul */
+
+typedef	intptr_t		VP_INT;		/* |C^Ü½Ít«® */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  ITRONdl¤Êè
+ */
+#define	TRUE		true			/* ^ */
+#define	FALSE		false			/* U */
+
+/*
+ *  IuWFNg®«Ìè`
+ */
+#define TA_HLNG			UINT_C(0x00)	/* ¾êpC^tF[X */
+#define TA_TFIFO		UINT_C(0x00)	/* ^XNÌÒ¿sñðFIFOÉ */
+#define TA_MFIFO		UINT_C(0x00)	/* bZ[WL
+[ðFIFOÉ */
+#define TA_WSGL			UINT_C(0x00)	/* Ò¿^XNÍ1ÂÌÝ */
+
+/*
+ *  lXgñÌÅål
+ */
+#define TMAX_SUSCNT		UINT_C(1)		/* ­§Ò¿vlXgÌÅål */
+
+/*
+ *  ­§Ò¿óÔ©çÌ­§ÄJ
+ */
+#define frsm_tsk(tskid)		rsm_tsk(tskid)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_ITRON_H */
Index: UsbWattMeter/trunk/asp_dcre/include/kernel.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/include/kernel.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/include/kernel.h	(revision 164)
@@ -0,0 +1,639 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		TOPPERS/ASPJ[l Wwb_t@C
+ *
+ *  TOPPERS/ASPJ[lªT|[g·éT[rXR[Ìé¾ÆCKvÈf[
+ *  ^^CèC}NÌè`ðÜÞwb_t@CD
+ *
+ *  AZu¾êÌ\[Xt@C©ç±Ìt@CðCN[h·é
+ *  ÍCTOPPERS_MACRO_ONLYðè`µÄ¨­D±êÉæèC}Nè`ÈOð
+ *  ­æ¤ÉÈÁÄ¢éD
+ *
+ *  ±Ìt@CðCN[h·éOÉCN[hµÄ¨­×«t@C
+ *  ÍÈ¢D
+ */
+
+#ifndef TOPPERS_KERNEL_H
+#define TOPPERS_KERNEL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *	TOPPERS¤ÊÌf[^^EèE}N
+ */
+#include <t_stddef.h>
+
+/*
+ *  ^[QbgË¶
+ */
+#include "target_kernel.h"
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  f[^^Ìè`
+ */
+
+/*
+ *  rbgp^[âIuWFNgÔÌ^è`
+ */
+typedef	uint_t		TEXPTN;		/* ^XNáOvöÌrbgp^[ */
+typedef	uint_t		FLGPTN;		/* CxgtOÌrbgp^[ */
+typedef	uint_t		INTNO;		/* ÝÔ */
+typedef	uint_t		INHNO;		/* ÝnhÔ */
+typedef	uint_t		EXCNO;		/* CPUáOnhÔ */
+
+/*
+ *  PÊÌ^è`
+ */
+typedef void	(*TASK)(intptr_t exinf);
+typedef void	(*TEXRTN)(TEXPTN texptn, intptr_t exinf);
+typedef void	(*CYCHDR)(intptr_t exinf);
+typedef void	(*ALMHDR)(intptr_t exinf);
+typedef void	(*ISR)(intptr_t exinf);
+typedef void	(*INTHDR)(void);
+typedef void	(*EXCHDR)(void *p_excinf);
+typedef void	(*INIRTN)(intptr_t exinf);
+typedef void	(*TERRTN)(intptr_t exinf);
+
+/*
+ *  ÌæmÛÌ½ßÌ^è`
+ */
+#ifndef TOPPERS_STK_T
+#define TOPPERS_STK_T	intptr_t
+#endif /* TOPPERS_STK_T */
+typedef	TOPPERS_STK_T	STK_T;	/* X^bNÌæðmÛ·é½ßÌ^ */
+
+#ifndef TOPPERS_MPF_T
+#define TOPPERS_MPF_T	intptr_t
+#endif /* TOPPERS_MPF_T */
+typedef	TOPPERS_MPF_T	MPF_T;	/* Åè·v[ÌæðmÛ·é½ßÌ^ */
+
+/*
+ *  bZ[Wwb_Ì^è`
+ */
+typedef	struct t_msg {			/* [{bNXÌbZ[Wwb_ */
+	struct t_msg	*pk_next;
+} T_MSG;
+
+typedef	struct t_msg_pri {		/* Dæxt«bZ[Wwb_ */
+	T_MSG	msgque;				/* bZ[Wwb_ */
+	PRI		msgpri;				/* bZ[WDæx */
+} T_MSG_PRI;
+
+/*
+ *  pPbg`®Ìè`
+ */
+typedef struct t_ctsk {
+	ATR			tskatr;		/* ^XN®« */
+	intptr_t	exinf;		/* ^XNÌg£îñ */
+	TASK		task;		/* ^XNÌC[`ÌæªÔn */
+	PRI			itskpri;	/* ^XNÌN®Dæx */
+	SIZE		stksz;		/* ^XNÌX^bNÌæÌTCY */
+	STK_T 		*stk;		/* ^XNÌX^bNÌæÌæªÔn */
+} T_CTSK;
+
+typedef struct t_rtsk {
+	STAT	tskstat;	/* ^XNóÔ */
+	PRI		tskpri;		/* ^XNÌ»ÝDæx */
+	PRI		tskbpri;	/* ^XNÌx[XDæx */
+	STAT	tskwait;	/* Ò¿vö */
+	ID		wobjid;		/* Ò¿ÎÛÌIuWFNgÌID */
+	TMO		lefttmo;	/* ^CAEg·éÜÅÌÔ */
+	uint_t	actcnt;		/* N®vL
+[CO */
+	uint_t	wupcnt;		/* N°vL
+[CO */
+} T_RTSK;
+
+typedef struct t_dtex {
+	ATR		texatr;		/* ^XNáO[`®« */
+	TEXRTN	texrtn;		/* ^XNáO[`ÌæªÔn */
+} T_DTEX;
+
+typedef struct t_rtex {
+	STAT	texstat;	/* ^XNáOÌóÔ */
+	TEXPTN	pndptn;		/* Û¯áOvö */
+} T_RTEX;
+
+typedef struct t_csem {
+	ATR		sematr;		/* Z}tH®« */
+	uint_t	isemcnt;	/* Z}tHÌú¹ */
+	uint_t	maxsem;		/* Z}tHÌÅå¹ */
+} T_CSEM;
+
+typedef struct t_rsem {
+	ID		wtskid;		/* Z}tHÌÒ¿sñÌæªÌ^XNÌIDÔ */
+	uint_t	semcnt;		/* Z}tHÌ»ÝÌ¹ */
+} T_RSEM;
+
+typedef struct t_cflg {
+	ATR		flgatr;		/* CxgtO®« */
+	FLGPTN	iflgptn;	/* CxgtOÌúrbgp^[ */
+} T_CFLG;
+
+typedef struct t_rflg {
+	ID		wtskid;		/* CxgtOÌÒ¿sñÌæªÌ^XNÌIDÔ */
+	FLGPTN	flgptn;		/* CxgtOÌ»ÝÌrbgp^[ */
+} T_RFLG;
+
+typedef struct t_cdtq {
+	ATR		dtqatr;		/* f[^L
+[®« */
+	uint_t	dtqcnt;		/* f[^L
+[ÇÌæÉi[Å«éf[^ */
+	void 	*dtqmb;		/* f[^L
+[ÇÌæÌæªÔn */
+} T_CDTQ;
+
+typedef struct t_rdtq {
+	ID		stskid;		/* f[^L
+[ÌMÒ¿sñÌæªÌ^XNÌIDÔ */
+	ID		rtskid;		/* f[^L
+[ÌóMÒ¿sñÌæªÌ^XNÌIDÔ */
+	uint_t	sdtqcnt;	/* f[^L
+[ÇÌæÉi[³êÄ¢éf[^Ì */
+} T_RDTQ;
+
+typedef struct t_cpdq {
+	ATR		pdqatr;		/* Dæxf[^L
+[®« */
+	uint_t	pdqcnt;		/* Dæxf[^L
+[ÇÌæÉi[Å«éf[^ */
+	PRI		maxdpri;	/* Dæxf[^L
+[ÉMÅ«éf[^DæxÌÅ
+						   ål */
+	void 	*pdqmb;		/* Dæxf[^L
+[ÇÌæÌæªÔn */
+} T_CPDQ;
+
+typedef struct t_rpdq {
+	ID		stskid;		/* Dæxf[^L
+[ÌMÒ¿sñÌæªÌ^XN
+						   ÌIDÔ */
+	ID		rtskid;		/* Dæxf[^L
+[ÌóMÒ¿sñÌæªÌ^XN
+						   ÌIDÔ */
+	uint_t	spdqcnt;	/* Dæxf[^L
+[ÇÌæÉi[³êÄ¢éf[
+						   ^Ì */
+} T_RPDQ;
+
+typedef struct t_cmbx {
+	ATR		mbxatr;		/* [{bNX®« */
+	PRI		maxmpri;	/* Dæx[{bNXÉMÅ«ébZ[WDæ
+						   xÌÅål */
+	void 	*mprihd;	/* DæxÊÌbZ[WL
+[wb_ÌæÌæªÔn */
+} T_CMBX;
+
+typedef struct t_rmbx {
+	ID		wtskid;		/* [{bNXÌÒ¿sñÌæªÌ^XNÌIDÔ */
+	T_MSG	*pk_msg;	/* bZ[WL
+[ÌæªÉÂÈªê½bZ[W
+						   ÌæªÔn */
+} T_RMBX;
+
+typedef struct t_cmpf {
+	ATR		mpfatr;		/* Åè·v[®« */
+	uint_t	blkcnt;		/* l¾Å«éÅè·ubNÌ */
+	uint_t	blksz;		/* Åè·ubNÌTCY */
+	MPF_T 	*mpf;		/* Åè·v[ÌæÌæªÔn */
+	void 	*mpfmb;		/* Åè·v[ÇÌæÌæªÔn */
+} T_CMPF;
+
+typedef struct t_rmpf {
+	ID		wtskid;		/* Åè·v[ÌÒ¿sñÌæªÌ^XNÌ
+						   IDÔ */
+	uint_t	fblkcnt;	/* Åè·v[ÌæÌó«ÌæÉè
+						   t¯é±ÆªÅ«éÅè·ubNÌ */
+} T_RMPF;
+
+typedef struct t_ccyc {
+	ATR			cycatr;		/* üúnh®« */
+	intptr_t	exinf;		/* üúnhÌg£îñ */
+	CYCHDR		cychdr;		/* üúnhÌæªÔn */
+	RELTIM		cyctim;		/* üúnhÌN®üú */
+	RELTIM		cycphs;		/* üúnhÌN®Ê */
+} T_CCYC;
+
+typedef struct t_rcyc {
+	STAT	cycstat;	/* üúnhÌ®ìóÔ */
+	RELTIM	lefttim;	/* ÉüúnhðN®·éÜÅÌÎÔ */
+} T_RCYC;
+
+typedef struct t_calm {
+	ATR			almatr;		/* A[nh®« */
+	intptr_t	exinf;		/* A[nhÌg£îñ */
+	ALMHDR		almhdr;		/* A[nhÌæªÔn */
+} T_CALM;
+
+typedef struct t_ralm {
+	STAT	almstat;	/* A[nhÌ®ìóÔ */
+	RELTIM	lefttim;	/* A[nhðN®·éÜÅÌÎÔ */
+} T_RALM;
+
+typedef struct t_cisr {
+	ATR			isratr;		/* ÝT[rX[`®« */
+	intptr_t	exinf;		/* ÝT[rX[`Ìg£îñ */
+	INTNO		intno;		/* ÝT[rX[`ðo^·éÝÔ */
+	ISR			isr;		/* ÝT[rX[`ÌæªÔn */
+	PRI			isrpri;		/* ÝT[rX[`Dæx */
+} T_CISR;
+
+/*
+ *  T[rXR[Ìé¾
+ */
+
+/*
+ *  ^XNÇ@\
+ */
+extern ER_UINT	acre_tsk(const T_CTSK *pk_ctsk) throw();
+extern ER		del_tsk(ID tskid) throw();
+extern ER		act_tsk(ID tskid) throw();
+extern ER		iact_tsk(ID tskid) throw();
+extern ER_UINT	can_act(ID tskid) throw();
+extern ER		ext_tsk(void) throw();
+extern ER		ter_tsk(ID tskid) throw();
+extern ER		chg_pri(ID tskid, PRI tskpri) throw();
+extern ER		get_pri(ID tskid, PRI *p_tskpri) throw();
+extern ER		get_inf(intptr_t *p_exinf) throw();
+extern ER		ref_tsk(ID tskid, T_RTSK *pk_rtsk) throw();
+
+/*
+ *  ^XNt®¯ú@\
+ */
+extern ER		slp_tsk(void) throw();
+extern ER		tslp_tsk(TMO tmout) throw();
+extern ER		wup_tsk(ID tskid) throw();
+extern ER		iwup_tsk(ID tskid) throw();
+extern ER_UINT	can_wup(ID tskid) throw();
+extern ER		rel_wai(ID tskid) throw();
+extern ER		irel_wai(ID tskid) throw();
+extern ER		sus_tsk(ID tskid) throw();
+extern ER		rsm_tsk(ID tskid) throw();
+extern ER		dly_tsk(RELTIM dlytim) throw();
+
+/*
+ *  ^XNáO@\
+ */
+extern ER		def_tex(ID tskid, const T_DTEX *pk_dtex) throw();
+extern ER		ras_tex(ID tskid, TEXPTN rasptn) throw();
+extern ER		iras_tex(ID tskid, TEXPTN rasptn) throw();
+extern ER		dis_tex(void) throw();
+extern ER		ena_tex(void) throw();
+extern bool_t	sns_tex(void) throw();
+extern ER		ref_tex(ID tskid, T_RTEX *pk_rtex) throw();
+
+/*
+ *  ¯úEÊM@\
+ */
+extern ER_ID	acre_sem(const T_CSEM *pk_csem) throw();
+extern ER		del_sem(ID semid) throw();
+extern ER		sig_sem(ID semid) throw();
+extern ER		isig_sem(ID semid) throw();
+extern ER		wai_sem(ID semid) throw();
+extern ER		pol_sem(ID semid) throw();
+extern ER		twai_sem(ID semid, TMO tmout) throw();
+extern ER		ini_sem(ID semid) throw();
+extern ER		ref_sem(ID semid, T_RSEM *pk_rsem) throw();
+
+extern ER_ID	acre_flg(const T_CFLG *pk_cflg) throw();
+extern ER		del_flg(ID flgid) throw();
+extern ER		set_flg(ID flgid, FLGPTN setptn) throw();
+extern ER		iset_flg(ID flgid, FLGPTN setptn) throw();
+extern ER		clr_flg(ID flgid, FLGPTN clrptn) throw();
+extern ER		wai_flg(ID flgid, FLGPTN waiptn,
+						MODE wfmode, FLGPTN *p_flgptn) throw();
+extern ER		pol_flg(ID flgid, FLGPTN waiptn,
+						MODE wfmode, FLGPTN *p_flgptn) throw();
+extern ER		twai_flg(ID flgid, FLGPTN waiptn,
+						MODE wfmode, FLGPTN *p_flgptn, TMO tmout) throw();
+extern ER		ini_flg(ID flgid) throw();
+extern ER		ref_flg(ID flgid, T_RFLG *pk_rflg) throw();
+
+extern ER_ID	acre_dtq(const T_CDTQ *pk_cdtq) throw();
+extern ER		del_dtq(ID dtqid) throw();
+extern ER		snd_dtq(ID dtqid, intptr_t data) throw();
+extern ER		psnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER		ipsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER		tsnd_dtq(ID dtqid, intptr_t data, TMO tmout) throw();
+extern ER		fsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER		ifsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER		rcv_dtq(ID dtqid, intptr_t *p_data) throw();
+extern ER		prcv_dtq(ID dtqid, intptr_t *p_data) throw();
+extern ER		trcv_dtq(ID dtqid, intptr_t *p_data, TMO tmout) throw();
+extern ER		ini_dtq(ID dtqid) throw();
+extern ER		ref_dtq(ID dtqid, T_RDTQ *pk_rdtq) throw();
+
+extern ER_ID	acre_pdq(const T_CPDQ *pk_cpdq) throw();
+extern ER		del_pdq(ID pdqid) throw();
+extern ER		snd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER		psnd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER		ipsnd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER		tsnd_pdq(ID pdqid, intptr_t data,
+										PRI datapri, TMO tmout) throw();
+extern ER		rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) throw();
+extern ER		prcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) throw();
+extern ER		trcv_pdq(ID pdqid, intptr_t *p_data,
+										PRI *p_datapri, TMO tmout) throw();
+extern ER		ini_pdq(ID pdqid) throw();
+extern ER		ref_pdq(ID pdqid, T_RPDQ *pk_rpdq) throw();
+
+extern ER_ID	acre_mbx(const T_CMBX *pk_cmbx) throw();
+extern ER		del_mbx(ID mbxid) throw();
+extern ER		snd_mbx(ID mbxid, T_MSG *pk_msg) throw();
+extern ER		rcv_mbx(ID mbxid, T_MSG **ppk_msg) throw();
+extern ER		prcv_mbx(ID mbxid, T_MSG **ppk_msg) throw();
+extern ER		trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout) throw();
+extern ER		ini_mbx(ID mbxid) throw();
+extern ER		ref_mbx(ID mbxid, T_RMBX *pk_rmbx) throw();
+
+/*
+ *  v[Ç@\
+ */
+extern ER_ID	acre_mpf(const T_CMPF *pk_cmpf) throw();
+extern ER		del_mpf(ID mpfid) throw();
+extern ER		get_mpf(ID mpfid, void **p_blk) throw();
+extern ER		pget_mpf(ID mpfid, void **p_blk) throw();
+extern ER		tget_mpf(ID mpfid, void **p_blk, TMO tmout) throw();
+extern ER		rel_mpf(ID mpfid, void *blk) throw();
+extern ER		ini_mpf(ID mpfid) throw();
+extern ER		ref_mpf(ID mpfid, T_RMPF *pk_rmpf) throw();
+
+/*
+ *  ÔÇ@\
+ */
+extern ER		get_tim(SYSTIM *p_systim) throw();
+extern ER		get_utm(SYSUTM *p_sysutm) throw();
+
+extern ER_ID	acre_cyc(const T_CCYC *pk_ccyc) throw();
+extern ER		del_cyc(ID cycid) throw();
+extern ER		sta_cyc(ID cycid) throw();
+extern ER		stp_cyc(ID cycid) throw();
+extern ER		ref_cyc(ID cycid, T_RCYC *pk_rcyc) throw();
+
+extern ER_ID	acre_alm(const T_CALM *pk_calm) throw();
+extern ER		del_alm(ID almid) throw();
+extern ER		sta_alm(ID almid, RELTIM almtim) throw();
+extern ER		ista_alm(ID almid, RELTIM almtim) throw();
+extern ER		stp_alm(ID almid) throw();
+extern ER		istp_alm(ID almid) throw();
+extern ER		ref_alm(ID almid, T_RALM *pk_ralm) throw();
+
+/*
+ *  VXeóÔÇ@\
+ */
+extern ER		rot_rdq(PRI tskpri) throw();
+extern ER		irot_rdq(PRI tskpri) throw();
+extern ER		get_tid(ID *p_tskid) throw();
+extern ER		iget_tid(ID *p_tskid) throw();
+extern ER		loc_cpu(void) throw();
+extern ER		iloc_cpu(void) throw();
+extern ER		unl_cpu(void) throw();
+extern ER		iunl_cpu(void) throw();
+extern ER		dis_dsp(void) throw();
+extern ER		ena_dsp(void) throw();
+extern bool_t	sns_ctx(void) throw();
+extern bool_t	sns_loc(void) throw();
+extern bool_t	sns_dsp(void) throw();
+extern bool_t	sns_dpn(void) throw();
+extern bool_t	sns_ker(void) throw();
+extern ER		ext_ker(void) throw();
+
+/*
+ *  ÝÇ@\
+ */
+extern ER_ID	acre_isr(const T_CISR *pk_cisr) throw();
+extern ER		del_isr(ID isrid) throw();
+extern ER		dis_int(INTNO intno) throw();
+extern ER		ena_int(INTNO intno) throw();
+extern ER		chg_ipm(PRI intpri) throw();
+extern ER		get_ipm(PRI *p_intpri) throw();
+
+/*
+ *  CPUáOÇ@\
+ */
+extern bool_t	xsns_dpn(void *p_excinf) throw();
+extern bool_t	xsns_xpn(void *p_excinf) throw();
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  IuWFNg®«Ìè`
+ */
+#define TA_ACT			UINT_C(0x02)	/* ^XNðN®³ê½óÔÅ¶¬ */
+
+#define TA_TPRI			UINT_C(0x01)	/* ^XNÌÒ¿sñðDæxÉ */
+#define TA_MPRI			UINT_C(0x02)	/* bZ[WL
+[ðDæxÉ */
+
+#define TA_WMUL			UINT_C(0x02)	/* ¡ÌÒ¿^XN */
+#define TA_CLR			UINT_C(0x04)	/* CxgtOÌNAwè */
+
+#define TA_STA			UINT_C(0x02)	/* üúnhð®ìóÔÅ¶¬ */
+
+#define TA_NONKERNEL	UINT_C(0x02)	/* J[lÇOÌÝ */
+
+#define TA_ENAINT		UINT_C(0x01)	/* ÝvÖ~tOðNA */
+#define TA_EDGE			UINT_C(0x02)	/* GbWgK */
+
+/*
+ *  T[rXR[Ì®ì[hÌè`
+ */
+#define TWF_ORW			UINT_C(0x01)	/* CxgtOÌORÒ¿ */
+#define TWF_ANDW		UINT_C(0x02)	/* CxgtOÌANDÒ¿ */
+
+/*
+ *  IuWFNgÌóÔÌè`
+ */
+#define TTS_RUN			UINT_C(0x01)	/* ÀsóÔ */
+#define TTS_RDY			UINT_C(0x02)	/* ÀsÂ\óÔ */
+#define TTS_WAI			UINT_C(0x04)	/* Ò¿óÔ */
+#define TTS_SUS			UINT_C(0x08)	/* ­§Ò¿óÔ */
+#define TTS_WAS			UINT_C(0x0c)	/* ñdÒ¿óÔ */
+#define TTS_DMT			UINT_C(0x10)	/* x~óÔ */
+
+#define TTW_SLP			UINT_C(0x0001)	/* N°Ò¿ */
+#define TTW_DLY			UINT_C(0x0002)	/* ÔoßÒ¿ */
+#define TTW_SEM			UINT_C(0x0004)	/* Z}tHÌ¹l¾Ò¿ */
+#define TTW_FLG			UINT_C(0x0008)	/* CxgtOÒ¿ */
+#define TTW_SDTQ		UINT_C(0x0010)	/* f[^L
+[ÖÌMÒ¿ */
+#define TTW_RDTQ		UINT_C(0x0020)	/* f[^L
+[©çÌóMÒ¿ */
+#define TTW_SPDQ		UINT_C(0x0100)	/* Dæxf[^L
+[ÖÌMÒ¿ */
+#define TTW_RPDQ		UINT_C(0x0200)	/* Dæxf[^L
+[©çÌóMÒ¿ */
+#define TTW_MBX			UINT_C(0x0040)	/* [{bNX©çÌóMÒ¿ */
+#define TTW_MPF			UINT_C(0x2000)	/* Åè·ubNÌl¾Ò¿ */
+
+#define TTEX_ENA		UINT_C(0x01)	/* ^XNáOÂóÔ */
+#define TTEX_DIS		UINT_C(0x02)	/* ^XNáOÖ~óÔ */
+
+#define TCYC_STP		UINT_C(0x01)	/* üúnhª®ìµÄ¢È¢ */
+#define TCYC_STA		UINT_C(0x02)	/* üúnhª®ìµÄ¢é */
+
+#define TALM_STP		UINT_C(0x01)	/* A[nhª®ìµÄ¢È¢ */
+#define TALM_STA		UINT_C(0x02)	/* A[nhª®ìµÄ¢é */
+
+/*
+ *  »Ì¼ÌèÌè`
+ */
+#define TSK_SELF		0			/* ©^XNwè */
+#define TSK_NONE		0			/* Y·é^XNªÈ¢ */
+
+#define TPRI_SELF		0			/* ©^XNÌx[XDæx */
+#define TPRI_INI		0			/* ^XNÌN®Dæx */
+
+#define TIPM_ENAALL		0			/* ÝDæx}XNSð */
+
+/*
+ *  \¬èÆ}N
+ */
+
+/*
+ *  T|[g·é@\
+ */
+#ifdef TOPPERS_TARGET_SUPPORT_DIS_INT
+#define TOPPERS_SUPPORT_DIS_INT			/* dis_intªT|[g³êÄ¢é */
+#endif /* TOPPERS_TARGET_SUPPORT_DIS_INT */
+
+#ifdef TOPPERS_TARGET_SUPPORT_ENA_INT
+#define TOPPERS_SUPPORT_ENA_INT			/* ena_intªT|[g³êÄ¢é */
+#endif /* TOPPERS_TARGET_SUPPORT_ENA_INT */
+
+#ifdef TOPPERS_TARGET_SUPPORT_GET_UTM
+#define TOPPERS_SUPPORT_GET_UTM			/* get_utmªT|[g³êÄ¢é */
+#endif /* TOPPERS_TARGET_SUPPORT_GET_UTM */
+
+#define TOPPERS_SUPPORT_DYNAMIC_CRE		/* ®I¶¬@\g£ */
+
+/*
+ *  DæxÌÍÍ
+ */
+#define TMIN_TPRI		1			/* ^XNDæxÌÅ¬liÅlj*/
+#define TMAX_TPRI		16			/* ^XNDæxÌÅåliÅálj*/
+#define TMIN_DPRI		1			/* f[^DæxÌÅ¬liÅlj*/
+#define TMAX_DPRI		16			/* f[^DæxÌÅåliÅálj*/
+#define TMIN_MPRI		1			/* bZ[WDæxÌÅ¬liÅlj*/
+#define TMAX_MPRI		16			/* bZ[WDæxÌÅåliÅálj*/
+#define TMIN_ISRPRI		1			/* ÝT[rX[`DæxÌÅ¬l */
+#define TMAX_ISRPRI		16			/* ÝT[rX[`DæxÌÅål */
+
+/*
+ *  o[Wîñ
+ */
+#define TKERNEL_MAKER	UINT_C(0x0118)	/* J[lÌ[J[R[h */
+#define TKERNEL_PRID	UINT_C(0x0007)	/* J[lÌ¯ÊÔ */
+#define TKERNEL_SPVER	UINT_C(0xf517)	/* J[ldlÌo[WÔ */
+#define TKERNEL_PRVER	UINT_C(0x1092)	/* J[lÌo[WÔ */
+
+/*
+ *  L
+[COñÌÅål
+ */
+#define TMAX_ACTCNT		UINT_C(1)		/* N®vL
+[COÌÅål */
+#define TMAX_WUPCNT		UINT_C(1)		/* N°vL
+[COÌÅål */
+
+/*
+ *  rbgp^[Ìrbg
+ */
+#ifndef TBIT_TEXPTN					/* ^XNáOvöÌrbg */
+#define TBIT_TEXPTN		(sizeof(TEXPTN) * CHAR_BIT)
+#endif /* TBIT_TEXPTN */
+
+#ifndef TBIT_FLGPTN					/* CxgtOÌrbg */
+#define TBIT_FLGPTN		(sizeof(FLGPTN) * CHAR_BIT)
+#endif /* TBIT_FLGPTN */
+
+/*
+ *  ÌæmÛÌ½ßÌ}N
+ *
+ *  ÈºÌTOPPERS_COUNT_SZÆTOPPERS_ROUND_SZÌè`ÍCunitª2ÌÐæÅ 
+ *  é±Æð¼èµÄ¢éD
+ */
+#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	/* Z}tHÌÅå¹ÌÅål */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_KERNEL_H */
Index: UsbWattMeter/trunk/asp_dcre/include/log_output.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/include/log_output.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/include/log_output.h	(revision 164)
@@ -0,0 +1,88 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		VXeOÌtH[}bgoÍ
+ */
+
+#ifndef TOPPERS_LOG_OUTPUT_H
+#define TOPPERS_LOG_OUTPUT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <t_syslog.h>
+
+/*
+ *  ¶ñ®`oÍ
+ *
+ *  formatÅwè³êétH[}bgLqÆp_argsÅwè³êéøñ©çì
+ *  ¬µ½bZ[WðC1¶oÍÖputcðp¢ÄoÍ·éD
+ */
+extern void	syslog_printf(const char *format, const intptr_t *p_args,
+										void (*putc)(char)) throw();
+
+/*
+ *  OîñÌoÍ
+ *
+ *  p_syslogÅwè³êéOîñð¶ñÉ®`µC1¶oÍÖputcðp
+ *  ¢ÄoÍ·éD
+ */
+extern void	syslog_print(const SYSLOG *p_syslog, void (*putc)(char)) throw();
+
+/*
+ *  Oîñr¸bZ[W¶ñ
+ *
+ *  lostlogÂÌOîñª¸íê½|ÌbZ[WðC1¶oÍÖputcð
+ *  p¢ÄoÍ·éD
+ */
+extern void	syslog_lostmsg(uint_t lostlog, void (*putc)(char)) throw();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_LOG_OUTPUT_H */
Index: UsbWattMeter/trunk/asp_dcre/include/queue.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/include/queue.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/include/queue.h	(revision 164)
@@ -0,0 +1,242 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		L
+[ìCu
+ *
+ *  ±ÌL
+[ìCuÅÍCL
+[wb_ðÜÞO\¢Ì_u
+ *  NL
+[ðµ¤DïÌIÉÍCL
+[wb_ÌGgÍL
+[Ì
+ *  æªÌGgCOGgÍL
+[ÌöÌGgÆ·éDÜ½CL
+ *  
+[ÌæªÌGgÌOGgÆCL
+[ÌöÌGgÌG
+ *  gÍCL
+[wb_Æ·éDóÌL
+[ÍCGgCOGgÆ
+ *  à©ª©gðw·L
+[wb_Å çí·D
+ */
+
+#ifndef	TOPPERS_QUEUE_H
+#define	TOPPERS_QUEUE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  L
+[Ìf[^\¢Ìè`
+ */
+typedef struct queue {
+	struct queue *p_next;		/* GgÖÌ|C^ */
+	struct queue *p_prev;		/* OGgÖÌ|C^ */
+} QUEUE;
+
+/*
+ *  L
+[Ìú»
+ *
+ *  p_queueÉÍL
+[wb_ðwè·éD
+ */
+Inline void
+queue_initialize(QUEUE *p_queue)
+{
+	p_queue->p_prev = p_queue;
+	p_queue->p_next = p_queue;
+}
+
+/*
+ *  L
+[ÌOGgÖÌ}ü
+ *
+ *  p_queueÌOÉp_entryð}ü·éDp_queueÉL
+[wb_ðwèµ½ê
+ *  ÉÍCL
+[ÌöÉp_entryð}ü·é±ÆÉÈéD
+ */
+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;
+}
+
+/*
+ *  L
+[ÌGgÖÌ}ü
+ *
+ *  p_queueÌÉp_entryð}ü·éDp_queueÉL
+[wb_ðwèµ½ê
+ *  ÉÍCL
+[ÌæªÉp_entryð}ü·é±ÆÉÈéD
+ */
+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;
+}
+
+/*
+ *  GgÌí
+ *
+ *  p_entryðL
+[©çí·éD
+ */
+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;
+}
+
+/*
+ *  L
+[Ìñ
+ *
+ *  øp_topðL
+[Æ·éGgðæª©çñ·éB
+ *  ÅÌÄoµÅÍAp_entryÉNULLðn·BÔlÍp_topÌÌGg(ÂÜèæª)Å éB
+ *  ñÈ~ÍOñÉ¾½Ggðp_entryÉn·BÔlÍp_entryÌÌGgÆÈéB
+ *  p_entryÌÌGgªp_top¾Á½Æ«ANULLðÔlÆµÄAL
+[ÌI[ð çí·B
+ *  p_topÌNULL`FbNâp_entryÌÃ«ØÍsÁÄ¢È¢BÄoµ¤ÌÓCÅs¤±ÆB
+ *  Ü½A¾¤ÜÅàÈ¢ªAXbhZ[tÉÍÈè¦È¢Bñ[vÍr¼Í
+ *  Äoµ¤ÌÓCÅs¤±ÆB
+ */
+Inline QUEUE *
+queue_enumerate(QUEUE *p_top, QUEUE *p_entry)
+{
+	QUEUE *p_result;
+	if (p_entry == NULL) {
+		p_result = p_top->p_next;
+	} else {
+		p_result = p_entry->p_next;
+	}
+	if (p_result == p_top) {
+		return NULL;
+	}
+	return p_result;
+}
+
+/*
+ *  L
+[ÌGgÌæoµ
+ *
+ *  p_queueÌGgðL
+[©çíµCíµ½GgðÔ·D
+ *  p_queueÉL
+[wb_ðwèµ½êÉÍCL
+[ÌæªÌGgð
+ *  æèo·±ÆÉÈéDp_queueÉóÌL
+[ðwèµÄÄÑoµÄÍÈç
+ *  È¢D
+ */
+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);
+}
+
+/*
+ *  L
+[ÌGgÌ|C^ðæ¾
+ *
+ *  p_queue ÌGgðÔ·Dp_queue ÉL
+[wb_ðwèµ½êÉÍC
+ *  L
+[ÌæªÌGgðæèo·±ÆÉÈéDp_queue ÉóÌL
+[ð
+ *  wèµÄÄÑoµÄÍÈçÈ¢D
+ */
+Inline QUEUE *
+queue_peek_next(QUEUE *p_queue)
+{
+	assert(p_queue->p_next != p_queue);
+
+	return(p_queue->p_next);
+}
+
+/*
+ *  L
+[ªó©Ç¤©Ì`FbN
+ *
+ *  p_queueÉÍL
+[wb_ðwè·éD
+ */
+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: UsbWattMeter/trunk/asp_dcre/include/sil.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/include/sil.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/include/sil.h	(revision 164)
@@ -0,0 +1,291 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		VXeC^tF[XC
+ *
+ *  VXeC^tF[XCÌT[rXR[Ìè`Eé¾Æ}NÈ
+ *  ÇÌè`ðÜÞwb_t@CD
+ *
+ *  AZu¾êÌ\[Xt@C©ç±Ìt@CðCN[h·é
+ *  ÍCTOPPERS_MACRO_ONLYðè`µÄ¨­±ÆÅC}Nè`ÈOÌLqð
+ *  ­±ÆªÅ«éD
+ *
+ *  ±Ìt@CðCN[h·éOÉCN[hµÄ¨­×«t@C
+ *  ÍÈ¢D
+ */
+
+#ifndef TOPPERS_SIL_H
+#define TOPPERS_SIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *	TOPPERS¤ÊÌf[^^EèE}N
+ */
+#include <t_stddef.h>
+
+/*
+ *  ^[QbgË¶
+ */
+#include "target_sil.h"
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  SÝbNóÔÌ§ä
+ *
+ *  SIL_PRE_LOCCSIL_LOC_INT()CSIL_UNL_INT()ÍC^[QbgË¶Åp
+ *  Ó·éDftHgÌè`ÍpÓµÄ¢È¢D
+ */
+
+/*
+ *  ÷­ÔÒ¿
+ */
+extern void	sil_dly_nse(ulong_t dlytim) throw();
+
+/*
+ *  GfBAÌ½]
+ */
+#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 */
+
+/*
+ *  óÔANZXÖ
+ */
+#ifndef TOPPERS_OMIT_SIL_ACCESS
+
+/*
+ *  8rbgPÊÌÇoµ^Ý
+ */
+#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 */
+
+/*
+ *  16rbgPÊÌÇoµ^Ý
+ */
+
+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			/* rbOGfBAvZbT */
+
+#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		/* gGfBAvZbT */
+
+#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 */
+
+/*
+ *  32rbgPÊÌÇoµ^Ý
+ */
+
+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			/* rbOGfBAvZbT */
+
+#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 */		/* gGfBAvZbT */
+
+#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: UsbWattMeter/trunk/asp_dcre/include/t_stddef.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/include/t_stddef.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/include/t_stddef.h	(revision 164)
@@ -0,0 +1,291 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		TOPPERS¤Êwb_t@C
+ *
+ *  TOPPERSÖAÌ·×ÄÌ\[Xt@CÅCN[h·×«wb_t@C
+ *  DeíÌJ[lâ\tgEFAiÅ¤ÊÉp¢é±ÆðzèµÄ¢
+ *  éDTOPPERSÌeíÌJ[lâ\tgEFAiÅ¤ÊÉp¢éf[^^C
+ *  èC}NÌè`ÈÇðÜÞD
+ *
+ *  AZu¾êÌ\[Xt@C©ç±Ìt@CðCN[h·é
+ *  ÍCTOPPERS_MACRO_ONLYðè`µÄ¨­D±êÉæèC}Nè`ÈOð
+ *  ­æ¤ÉÈÁÄ¢éD
+ *
+ *  ±Ìt@CðCN[h·éOÉCN[hµÄ¨­×«t@C
+ *  ÍÈ¢D
+ */
+
+#ifndef TOPPERS_T_STDDEF_H
+#define TOPPERS_T_STDDEF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  ^[QbgË¶
+ */
+#include "target_stddef.h"
+
+/*
+ *  C¾ê/EC++Åthrow()ÉÎ·é½ßÌè`
+ */
+#if !defined(__cplusplus) || defined(__embedded_cplusplus)
+#define throw()
+#endif
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  ^[QbgË¶Ìf[^^Ì}NÌftHgè`
+ */
+#ifndef TOPPERS_bool
+#define TOPPERS_bool	int				/* u[^ */
+#endif /* TOPPERS_bool */
+
+#ifndef TOPPERS_size
+#define TOPPERS_size	uintptr_t		/* TCY^ */
+#endif /* TOPPERS_size */
+
+#ifndef TOPPERS_fp
+struct TOPPERS_dummy_t { int TOPPERS_dummy_field; };
+typedef	void			(*TOPPERS_fp_t)(struct TOPPERS_dummy_t);
+#define TOPPERS_fp		TOPPERS_fp_t	/* vOÌN®Ôn */
+#endif /* TOPPERS_fp */
+
+/*
+ *  ¤Êf[^^
+ */
+typedef TOPPERS_bool	bool_t;		/* ^Ul */
+
+typedef signed int		int_t;		/* ©RÈTCYÌt«® */
+typedef unsigned int	uint_t;		/* ©RÈTCYÌ³µ® */
+
+typedef signed long		long_t;		/* ·ßÌTCYÌt«® */
+typedef unsigned long	ulong_t;	/* ·ßÌTCYÌ³µ® */
+
+typedef int_t			FN;			/* @\R[h */
+typedef	int_t			ER;			/* G[R[h */
+typedef	int_t			ID;			/* IuWFNgÌIDÔ */
+typedef	uint_t			ATR;		/* IuWFNgÌ®« */
+typedef	uint_t			STAT;		/* IuWFNgÌóÔ */
+typedef	uint_t			MODE;		/* T[rXR[Ì®ì[h */
+typedef	int_t			PRI;		/* Dæx */
+typedef	TOPPERS_size	SIZE;		/* ÌæÌTCY */
+
+typedef	int_t			TMO;		/* ^CAEgwè */
+typedef	uint_t			RELTIM;		/* ÎÔ */
+typedef	ulong_t			SYSTIM;		/* VXe */
+typedef	ulong_t			SYSUTM;		/* «\]¿pVXe */
+
+typedef	TOPPERS_fp		FP;			/* vOÌN®Ôn */
+
+typedef	int_t			ER_BOOL;	/* G[R[hÜ½Í^Ul */
+typedef	int_t			ER_ID;		/* G[R[hÜ½ÍIDÔ */
+typedef	int_t			ER_UINT;	/* G[R[hÜ½Í³µ® */
+
+typedef uintptr_t		MB_T;		/* ÇÌæðmÛ·é½ßÌf[^^ */
+
+typedef	uint32_t		ACPTN;		/* ANZXÂp^[ */
+typedef	struct acvct {				/* ANZXÂxN^ */
+	ACPTN		acptn1;				/* Êíì1ÌANZXÂp^[ */
+	ACPTN		acptn2;				/* Êíì2ÌANZXÂp^[ */
+	ACPTN		acptn3;				/* ÇìÌANZXÂp^[ */
+	ACPTN		acptn4;				/* QÆìÌANZXÂp^[ */
+} ACVCT;
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  ®èðìé}N
+ */
+#ifndef UINT_C
+#define UINT_C(val)		(val ## U)		/* uint_t^Ìèðìé}N */
+#endif /* UINT_C */
+
+#ifndef ULONG_C
+#define ULONG_C(val)	(val ## UL)		/* ulong_t^Ìèðìé}N */
+#endif /* ULONG_C */
+
+/*
+ *  êÊè
+ */
+#ifndef NULL
+#define NULL		0			/* ³ø|C^ */
+#endif /* NULL */
+
+#ifndef true
+#define true		1			/* ^ */
+#endif /* true */
+
+#ifndef false
+#define false		0			/* U */
+#endif /* false */
+
+#define E_OK		0			/* ³íI¹ */
+
+/*
+ *  CG[R[h
+ */
+#define E_SYS		(-5)		/* VXeG[ */
+#define E_NOSPT		(-9)		/* ¢T|[g@\ */
+#define E_RSFN		(-10)		/* \ñ@\R[h */
+#define E_RSATR		(-11)		/* \ñ®« */
+#define E_PAR		(-17)		/* p[^G[ */
+#define E_ID		(-18)		/* s³IDÔ */
+#define E_CTX		(-25)		/* ReLXgG[ */
+#define E_MACV		(-26)		/* ANZXá½ */
+#define E_OACV		(-27)		/* IuWFNgANZXá½ */
+#define E_ILUSE		(-28)		/* T[rXR[s³gp */
+#define E_NOMEM		(-33)		/* s« */
+#define E_NOID		(-34)		/* IDÔs« */
+#define E_NORES		(-35)		/* ¹s« */
+#define E_OBJ		(-41)		/* IuWFNgóÔG[ */
+#define E_NOEXS		(-42)		/* IuWFNg¢¶¬ */
+#define E_QOVR		(-43)		/* L
+[COI[o[t[ */
+#define E_RLWAI		(-49)		/* Ò¿óÔÌ­§ð */
+#define E_TMOUT		(-50)		/* |[O¸sÜ½Í^CAEg */
+#define E_DLT		(-51)		/* Ò¿IuWFNgÌí */
+#define E_CLS		(-52)		/* Ò¿IuWFNgÌóÔÏ» */
+#define E_WBLK		(-57)		/* mubLOót¯ */
+#define E_BOVR		(-58)		/* obt@I[o[t[ */
+
+/*
+ *  IuWFNg®«
+ */
+#define TA_NULL		UINT_C(0)	/* IuWFNg®«ðwèµÈ¢ */
+
+/*
+ *  ^CAEgwè
+ */
+#define TMO_POL		0			/* |[O */
+#define TMO_FEVR	(-1)		/* ivÒ¿ */
+#define TMO_NBLK	(-2)		/* mubLO */
+
+/*
+ *  ANZXÂp^[
+ */
+#define TACP_KERNEL		(0U)	/* J[lhC¾¯ÉANZXðÂ */
+#define TACP_SHARED		(~0U)	/* ·×ÄÌhC©çANZXðÂ */
+
+/*
+ *  ^ÉÖ·éîñðæèo·½ßÌ}N
+ *
+ *  ÈºÌALIGN_TYPEÌè`ÍCACgÌPÊª2ÌÐæÅ é±Æð
+ *  ¼èµÄ¢éD
+ */
+#ifndef offsetof
+#define	offsetof(structure, field)	((uintptr_t) &(((structure *) 0)->field))
+#endif /* offsetof */
+
+#ifndef alignof
+#define alignof(type)	offsetof(struct { char field1; type field2; }, field2)
+#endif /* alignof */
+
+#ifndef ALIGN_TYPE				/* ACgÌ`FbN */
+#define ALIGN_TYPE(addr, type) \
+						((((uintptr_t)(addr)) & (alignof(type) - 1)) == 0U)
+#endif /* ALIGN_TYPE */
+
+/*
+ *  assert}N
+ */
+#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
+
+/*
+ *  G[R[h¶¬Eªð}N
+ *
+ *  ÈºÌ}Nè`ÍCt«®ª2ÌâÅ\»³êÄ¨èCEVtg
+ *  Zqi>>jªZpVtg³êé±Æð¼èµÄ¢éD»¤ÅÈ¢J­Â
+ *  «ÅÍCtarget_stddef.hÅ±êçÌè`ðã«µÈ¯êÎÈçÈ¢D
+ *
+ *  MERCD}NÌè`ÍCCG[R[hªÅ é±Æð¼èµÄ¢éD
+ *  »¤ÅÈ¢êC2ÂÌè`ªêvµÈ­ÈéD
+ */
+#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 */
+
+/*
+ *  ANZXÂp^[¶¬}N
+ */
+#define TACP(domid)		(1U << ((domid) - 1))	/* domid¾¯ÉANZXðÂ */
+
+/*
+ *  ÎÔiRELTIMjÉwèÅ«éÅål
+ */
+#if UINT_MAX < LONG_MAX
+#define TMAX_RELTIM		((RELTIM) UINT_MAX)
+#else /* UINT_MAX < LONG_MAX */
+#define TMAX_RELTIM		((RELTIM) LONG_MAX)
+#endif /* UINT_MAX < LONG_MAX */
+
+#endif /* TOPPERS_T_STDDEF_H */
Index: UsbWattMeter/trunk/asp_dcre/include/t_stdlib.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/include/t_stdlib.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/include/t_stdlib.h	(revision 164)
@@ -0,0 +1,78 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		î{IÈCuÖ
+ */
+
+#ifndef TOPPERS_T_STDLIB_H
+#define TOPPERS_T_STDLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  G[bZ[W¶ñðÔ·Ö
+ *
+ *  ercdÅwè³ê½G[R[hÌCG[R[hÌ¼ÌiE_PARC
+ *  E_OBJÈÇjÌ¶ñðÔ·ÖD
+ */
+extern const char	*itron_strerror(ER ercd) throw();
+
+/*
+ *  G[bZ[WÌOoÍ
+ *
+ *  T[rXR[ªG[ðÔµ½êÉC»Ìt@C¼CsÔCC
+ *  G[R[hð\¦·é½ßÌÖD
+ */
+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: UsbWattMeter/trunk/asp_dcre/include/t_syslog.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/include/t_syslog.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/include/t_syslog.h	(revision 164)
@@ -0,0 +1,340 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		VXeOoÍðs¤½ßÌè`
+ *
+ *  VXeOT[rXÍCVXeÌOîñðoÍ·é½ßÌT[rX
+ *  Å éDJ[l©çÌOîñÌoÍÉàp¢é½ßCàÅÒ¿óÔ
+ *  ÉÍ¢é±ÆÍÈ¢D
+ *
+ *  OîñÍCJ[làÌOobt@É«Þ©CáxÌ¶o
+ *  ÍÖðp¢ÄoÍ·éDÇ¿çðg¤©ÍCg£T[rXR[ÅØè
+ *  ·¦é±ÆªÅ«éD
+ *
+ *  Oobt@ÌæªI[ot[µ½êÉÍCÃ¢OîñðÁµÄã
+ *  «·éD
+ *
+ *  AZu¾êÌ\[Xt@C©ç±Ìt@CðCN[h·é
+ *  ÍCTOPPERS_MACRO_ONLYðè`µÄ¨­±ÆÅC}Nè`ÈOÌLqð
+ *  ­±ÆªÅ«éD
+ *
+ *  ±Ìt@CðCN[h·éOÉCt_stddef.hðCN[hµÄ¨
+ *  ­±ÆªKvÅ éD
+ */
+
+#ifndef TOPPERS_T_SYSLOG_H
+#define TOPPERS_T_SYSLOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  OîñÌíÊÌè`
+ */
+#define LOG_TYPE_COMMENT	UINT_C(0x01)	/* Rg */
+#define LOG_TYPE_ASSERT		UINT_C(0x02)	/* AT[VÌ¸s */
+
+#define LOG_TYPE_INH		UINT_C(0x11)	/* Ýnh */
+#define LOG_TYPE_ISR		UINT_C(0x12)	/* ÝT[rX[` */
+#define LOG_TYPE_CYC		UINT_C(0x13)	/* üúnh */
+#define LOG_TYPE_ALM		UINT_C(0x14)	/* A[nh */
+#define LOG_TYPE_OVR		UINT_C(0x15)	/* I[onh */
+#define LOG_TYPE_EXC		UINT_C(0x16)	/* CPUáOnh */
+#define LOG_TYPE_TEX		UINT_C(0x17)	/* ^XNáO[` */
+#define LOG_TYPE_TSKSTAT	UINT_C(0x18)	/* ^XNóÔÏ» */
+#define LOG_TYPE_DSP		UINT_C(0x19)	/* fBXpb` */
+#define LOG_TYPE_SVC		UINT_C(0x1a)	/* T[rXR[ */
+
+#define LOG_ENTER			UINT_C(0x00)	/* üû^Jn */
+#define LOG_LEAVE			UINT_C(0x80)	/* oû^I¹ */
+
+/*
+ *  OîñÌdvxÌè`
+ */
+#define LOG_EMERG			UINT_C(0)		/* Vbg_EÉl·éG[ */
+#define LOG_ALERT			UINT_C(1)
+#define LOG_CRIT			UINT_C(2)
+#define LOG_ERROR			UINT_C(3)		/* VXeG[ */
+#define LOG_WARNING			UINT_C(4)		/* xbZ[W */
+#define LOG_NOTICE			UINT_C(5)
+#define LOG_INFO			UINT_C(6)
+#define LOG_DEBUG			UINT_C(7)		/* fobOpbZ[W */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  OîñÌf[^\¢
+ */
+
+#define TMAX_LOGINFO	6
+
+typedef struct {
+	uint_t		logtype;				/* OîñÌíÊ */
+	SYSTIM		logtim;					/* O */
+	intptr_t	loginfo[TMAX_LOGINFO];	/* »Ì¼ÌOîñ */
+} SYSLOG;
+
+/*
+ *  OîñÌdvxÌrbg}bvðìé½ßÌ}N
+ */
+#define LOG_MASK(prio)		(1U << (prio))
+#define LOG_UPTO(prio)		((1U << ((prio) + 1)) - 1)
+
+/*
+ *  pPbg`®Ìè`
+ */
+typedef struct t_syslog_rlog {
+	uint_t	count;		/* Oobt@ÌOÌ */
+	uint_t	lost;		/* ¸íê½OÌ */
+	uint_t	logmask;	/* Oobt@ÉL^·×«dvx */
+	uint_t	lowmask;	/* áxoÍ·×«dvx */
+} T_SYSLOG_RLOG;
+
+/*
+ *  OîñðoÍ·é½ßÌCuÖ
+ */
+
+#ifndef TOPPERS_OMIT_SYSLOG
+
+extern ER	syslog_wri_log(uint_t prio, const SYSLOG *p_syslog) throw();
+
+Inline void
+_syslog_0(uint_t prio, uint_t type)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+Inline void
+_syslog_1(uint_t prio, uint_t type, intptr_t arg1)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.loginfo[0] = arg1;
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+Inline void
+_syslog_2(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.loginfo[0] = arg1;
+	logbuf.loginfo[1] = arg2;
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+Inline void
+_syslog_3(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+														intptr_t arg3)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.loginfo[0] = arg1;
+	logbuf.loginfo[1] = arg2;
+	logbuf.loginfo[2] = arg3;
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+Inline void
+_syslog_4(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+										intptr_t arg3, intptr_t arg4)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.loginfo[0] = arg1;
+	logbuf.loginfo[1] = arg2;
+	logbuf.loginfo[2] = arg3;
+	logbuf.loginfo[3] = arg4;
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+Inline void
+_syslog_5(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+							intptr_t arg3, intptr_t arg4, intptr_t arg5)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.loginfo[0] = arg1;
+	logbuf.loginfo[1] = arg2;
+	logbuf.loginfo[2] = arg3;
+	logbuf.loginfo[3] = arg4;
+	logbuf.loginfo[4] = arg5;
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+Inline void
+_syslog_6(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+				intptr_t arg3, intptr_t arg4, intptr_t arg5, intptr_t arg6)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.loginfo[0] = arg1;
+	logbuf.loginfo[1] = arg2;
+	logbuf.loginfo[2] = arg3;
+	logbuf.loginfo[3] = arg4;
+	logbuf.loginfo[4] = arg5;
+	logbuf.loginfo[5] = arg6;
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+/*
+ *  OîñiRgjðoÍ·é½ßÌCuÖivasyslog.cj
+ */
+extern void syslog(uint_t prio, const char *format, ...) throw();
+extern void vsyslog(uint_t prio, const char *format, va_list ap) throw();
+
+#else /* TOPPERS_OMIT_SYSLOG */
+
+/*
+ *  VXeOoÍð}~·éê
+ */
+
+Inline void
+_syslog_0(uint_t prio, uint_t type)
+{
+}
+
+Inline void
+_syslog_1(uint_t prio, uint_t type, intptr_t arg1)
+{
+}
+
+Inline void
+_syslog_2(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2)
+{
+}
+
+Inline void
+_syslog_3(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+														intptr_t arg3)
+{
+}
+
+Inline void
+_syslog_4(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+										intptr_t arg3, intptr_t arg4)
+{
+}
+
+Inline void
+_syslog_5(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+							intptr_t arg3, intptr_t arg4, intptr_t arg5)
+{
+}
+
+Inline void
+_syslog_6(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+				intptr_t arg3, intptr_t arg4, intptr_t arg5, intptr_t arg6)
+{
+}
+
+Inline void
+syslog(uint_t prio, const char *format, ...)
+{
+}
+
+#endif /* TOPPERS_OMIT_SYSLOG */
+
+/*
+ *  OîñiRgjðoÍ·é½ßÌ}N
+ *
+ *  format¨æÑã±Ìø©çì¬µ½bZ[WðCdåxprioÅOî
+ *  ñÆµÄoÍ·é½ßÌ}NDarg1`argnÍintptr_t^ÉLXg·é
+ *  ½ßCintptr_t^É^Ï·Å«éCÓÌ^Åæ¢D
+ */
+
+#define syslog_0(prio, format) \
+				_syslog_1(prio, LOG_TYPE_COMMENT, (intptr_t)(format))
+
+#define syslog_1(prio, format, arg1) \
+				_syslog_2(prio, LOG_TYPE_COMMENT, (intptr_t)(format), \
+														(intptr_t)(arg1))
+
+#define syslog_2(prio, format, arg1, arg2) \
+				_syslog_3(prio, LOG_TYPE_COMMENT, (intptr_t)(format), \
+										(intptr_t)(arg1), (intptr_t)(arg2))
+
+#define syslog_3(prio, format, arg1, arg2, arg3) \
+				_syslog_4(prio, LOG_TYPE_COMMENT, (intptr_t)(format), \
+						(intptr_t)(arg1), (intptr_t)(arg2), (intptr_t)(arg3))
+
+#define syslog_4(prio, format, arg1, arg2, arg3, arg4) \
+				_syslog_5(prio, LOG_TYPE_COMMENT, (intptr_t)(format), \
+						(intptr_t)(arg1), (intptr_t)(arg2), (intptr_t)(arg3), \
+														(intptr_t)(arg4))
+
+#define syslog_5(prio, format, arg1, arg2, arg3, arg4, arg5) \
+				_syslog_6(prio, LOG_TYPE_COMMENT, (intptr_t)(format), \
+						(intptr_t)(arg1), (intptr_t)(arg2), (intptr_t)(arg3), \
+										(intptr_t)(arg4), (intptr_t)(arg5))
+
+/*
+ *  OîñiAT[VÌ¸sjðoÍ·é½ßÌ}N
+ */
+#ifndef TOPPERS_assert_fail
+#define TOPPERS_assert_fail(exp, file, line) \
+				_syslog_3(LOG_EMERG, LOG_TYPE_ASSERT, (intptr_t)(file), \
+										(intptr_t)(line), (intptr_t)(exp))
+#endif /* TOPPERS_assert_fail */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_T_SYSLOG_H */
Index: UsbWattMeter/trunk/asp_dcre/include/test_lib.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/include/test_lib.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/include/test_lib.h	(revision 164)
@@ -0,0 +1,154 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2005-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *		eXgvOpCu
+ */
+
+#ifndef TOPPERS_TEST_LIB_H
+#define TOPPERS_TEST_LIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <t_stddef.h>
+
+/*
+ *  ^[QbgË¶Ìè`
+ */
+#include "target_test.h"
+
+/*
+ *	©ÈffÖÌ^
+ */
+typedef ER (*BIT_FUNC)(void);
+
+/*
+ *	©ÈffÖÌÝè
+ */
+extern void	set_bit_func(BIT_FUNC bit_func);
+
+/*
+ *  eXgvOÌJn
+ */
+extern void	test_start(char *progname);
+
+/*
+ *  VXeOÌoÍ
+ */
+extern void	syslog_flush(void);
+
+/*
+ *	eXgvOÌI¹
+ */
+extern void	test_finish(void);
+
+/*
+ *	`FbN|Cg
+ */
+extern void	check_point(uint_t count);
+
+/*
+ *	®¹`FbN|Cg
+ */
+extern void	check_finish(uint_t count);
+
+/*
+ *	ð`FbN
+ */
+extern void	_check_assert(const char *expr, const char *file, int_t line);
+#define check_assert(exp) \
+	((void)(!(exp) ? (_check_assert(#exp, __FILE__, __LINE__), 0) : 0))
+
+/*
+ *	G[R[h`FbN
+ */
+extern void	_check_ercd(ER ercd, const char *file, int_t line);
+#define check_ercd(ercd, expected_ercd) \
+	((void)((ercd) != (expected_ercd) ? \
+					(_check_ercd(ercd, __FILE__, __LINE__), 0) : 0))
+
+/*
+ *	VXeóÔÌ`FbN
+ */
+Inline void
+check_state(bool_t ctx, bool_t loc, PRI ipm, bool_t dsp,
+										bool_t dpn, bool_t tex)
+{
+	PRI		intpri;
+	ER		ercd;
+
+	check_assert(sns_ctx() == ctx);
+	check_assert(sns_loc() == loc);
+	if (!loc) {
+		/*
+		 *  IPMÌ`FbNÍCCPUbNðóÔÌêÉÌÝs¤D
+		 */
+		ercd = get_ipm(&intpri);
+		check_ercd(ercd, E_OK);
+		check_assert(intpri == ipm);
+	}
+	check_assert(sns_dsp() == dsp);
+	check_assert(sns_dpn() == dpn);
+	check_assert(sns_tex() == tex);
+}
+
+/*
+ *	VXeóÔÌ`FbNiñ^XNReLXgpj
+ */
+Inline void
+check_state_i(bool_t ctx, bool_t loc, bool_t dsp, bool_t dpn, bool_t tex)
+{
+	check_assert(sns_ctx() == ctx);
+	check_assert(sns_loc() == loc);
+	check_assert(sns_dsp() == dsp);
+	check_assert(sns_dpn() == dpn);
+	check_assert(sns_tex() == tex);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_TEST_LIB_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/Makefile.kernel
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/Makefile.kernel	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/Makefile.kernel	(revision 164)
@@ -0,0 +1,151 @@
+#
+#  TOPPERS/ASP Kernel
+#      Toyohashi Open Platform for Embedded Real-Time Systems/
+#      Advanced Standard Profile Kernel
+# 
+#  Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+#  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+#  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+#  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+#       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+#      XR[hÉÜÜêÄ¢é±ÆD
+#  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+#      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+#      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+#      Ì³ÛØKèðfÚ·é±ÆD
+#  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+#      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+#      ÆD
+#    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+#        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+#    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+#        ñ·é±ÆD
+#  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+#      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+#      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+#      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+#      ÆÓ·é±ÆD
+# 
+#  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+#  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+#  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+#  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+#  ÌÓCðíÈ¢D
+# 
+#  @(#) $Id: Makefile.kernel 1966 2010-11-20 07:23:56Z ertl-hiro $
+# 
+
+#
+#		J[lÌt@C\¬Ìè`
+#
+
+#
+#  1ÂÌ\[Xt@C©ç¡ÌIuWFNgt@Cð¶¬·éæ¤Éì
+#  ¬³ê½\[Xt@CÌXg
+#
+KERNEL_FCSRCS = startup.c kmem.c task.c wait.c time_event.c \
+				task_manage.c task_refer.c task_sync.c task_except.c \
+				semaphore.c eventflag.c dataqueue.c pridataq.c mailbox.c \
+				mempfix.c mempvar.c time_manage.c cyclic.c alarm.c \
+				sys_manage.c interrupt.c exception.c
+
+#
+#  e\[Xt@C©ç¶¬³êéIuWFNgt@CÌXg
+#
+startup = sta_ker.o ext_ker.o kermem.o
+
+kmem = kmemsetup.o kmemallocp.o kmemallocate.o kmemrelease.o kmemstat.o
+
+task = tskini.o tsksched.o tskrun.o tsknrun.o \
+		tskdmt.o tskact.o tskpri.o tskrot.o tsktex.o
+
+wait = waimake.o waicmp.o waitmo.o waitmook.o \
+		wairel.o wobjwai.o wobjwaitmo.o iniwque.o
+
+time_event = tmeini.o tmeup.o tmedown.o tmeins.o tmedel.o tmeltim.o sigtim.o
+
+task_manage = acre_tsk.o del_tsk.o act_tsk.o iact_tsk.o can_act.o \
+		ext_tsk.o ter_tsk.o chg_pri.o get_pri.o get_inf.o
+
+task_refer = ref_tsk.o
+
+task_sync = slp_tsk.o tslp_tsk.o wup_tsk.o iwup_tsk.o can_wup.o \
+		rel_wai.o irel_wai.o sus_tsk.o rsm_tsk.o dly_tsk.o
+
+task_except = def_tex.o ras_tex.o iras_tex.o dis_tex.o ena_tex.o \
+		sns_tex.o ref_tex.o
+
+semaphore = semini.o acre_sem.o del_sem.o sig_sem.o isig_sem.o \
+		wai_sem.o pol_sem.o twai_sem.o ini_sem.o ref_sem.o
+
+eventflag = flgini.o flgcnd.o acre_flg.o del_flg.o set_flg.o iset_flg.o \
+		clr_flg.o wai_flg.o pol_flg.o twai_flg.o ini_flg.o ref_flg.o
+
+dataqueue = dtqini.o dtqenq.o dtqfenq.o dtqdeq.o dtqsnd.o dtqfsnd.o dtqrcv.o \
+		acre_dtq.o del_dtq.o snd_dtq.o psnd_dtq.o ipsnd_dtq.o tsnd_dtq.o \
+		fsnd_dtq.o ifsnd_dtq.o rcv_dtq.o prcv_dtq.o trcv_dtq.o ini_dtq.o \
+		ref_dtq.o
+
+pridataq = pdqini.o pdqenq.o pdqdeq.o pdqsnd.o pdqrcv.o \
+		acre_pdq.o del_pdq.o snd_pdq.o psnd_pdq.o ipsnd_pdq.o tsnd_pdq.o \
+		rcv_pdq.o prcv_pdq.o trcv_pdq.o ini_pdq.o ref_pdq.o
+
+mailbox = mbxini.o acre_mbx.o del_mbx.o snd_mbx.o rcv_mbx.o \
+		prcv_mbx.o trcv_mbx.o ini_mbx.o ref_mbx.o
+
+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
+
+mempvar = mplini.o mplget.o acre_mpl.o del_mpl.o get_mpl.o\
+		 pget_mpl.o tget_mpl.o rel_mpl.o ini_mpl.o ref_mpl.o
+
+time_manage = get_tim.o get_utm.o
+
+cyclic = cycini.o acre_cyc.o del_cyc.o sta_cyc.o stp_cyc.o ref_cyc.o cyccal.o
+
+alarm = almini.o acre_alm.o del_alm.o sta_alm.o ista_alm.o stp_alm.o \
+		istp_alm.o ref_alm.o almcal.o
+
+sys_manage = rot_rdq.o irot_rdq.o get_tid.o iget_tid.o \
+		loc_cpu.o iloc_cpu.o unl_cpu.o iunl_cpu.o dis_dsp.o ena_dsp.o \
+		sns_ctx.o sns_loc.o sns_dsp.o sns_dpn.o sns_ker.o
+
+interrupt = isrini.o isrcal.o acre_isr.o del_isr.o \
+		intini.o dis_int.o ena_int.o chg_ipm.o get_ipm.o
+
+exception = excini.o xsns_dpn.o xsns_xpn.o
+
+#
+#  ¶¬³êéIuWFNgt@CÌË¶ÖWÌè`
+#
+$(startup) $(startup:.o=.s) $(startup:.o=.d): startup.c
+$(kmem) $(kmem:.o=.s) $(kmem:.o=.d): kmem.c
+$(task) $(task:.o=.s) $(task:.o=.d): task.c
+$(wait) $(wait:.o=.s) $(wait:.o=.d): wait.c
+$(time_event) $(time_event:.o=.s) $(time_event:.o=.d): time_event.c
+$(task_manage) $(task_manage:.o=.s) $(task_manage:.o=.d): task_manage.c
+$(task_refer) $(task_refer:.o=.s) $(task_refer:.o=.d): task_refer.c
+$(task_sync) $(task_sync:.o=.s) $(task_sync:.o=.d): task_sync.c
+$(task_except) $(task_except:.o=.s) $(task_except:.o=.d): task_except.c
+$(semaphore) $(semaphore:.o=.s) $(semaphore:.o=.d): semaphore.c
+$(eventflag) $(eventflag:.o=.s) $(eventflag:.o=.d): eventflag.c
+$(dataqueue) $(dataqueue:.o=.s) $(dataqueue:.o=.d): dataqueue.c
+$(pridataq) $(pridataq:.o=.s) $(pridataq:.o=.d): pridataq.c
+$(mailbox) $(mailbox:.o=.s) $(mailbox:.o=.d): mailbox.c
+$(mempfix) $(mempfix:.o=.s) $(mempfix:.o=.d): mempfix.c
+$(mempvar) $(mempvar:.o=.s) $(mempvar:.o=.d): mempvar.c
+$(time_manage) $(time_manage:.o=.s) $(time_manage:.o=.d): time_manage.c
+$(cyclic) $(cyclic:.o=.s) $(cyclic:.o=.d): cyclic.c
+$(alarm) $(alarm:.o=.s) $(alarm:.o=.d): alarm.c
+$(sys_manage) $(sys_manage:.o=.s) $(sys_manage:.o=.d): sys_manage.c
+$(interrupt) $(interrupt:.o=.s) $(interrupt:.o=.d): interrupt.c
+$(exception) $(exception:.o=.s) $(exception:.o=.d): exception.c
Index: UsbWattMeter/trunk/asp_dcre/kernel/alarm.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/alarm.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/alarm.c	(revision 164)
@@ -0,0 +1,482 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		A[nh@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "alarm.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_ALM_ENTER
+#define LOG_ALM_ENTER(p_almcb)
+#endif /* LOG_ALM_ENTER */
+
+#ifndef LOG_ALM_LEAVE
+#define LOG_ALM_LEAVE(p_almcb)
+#endif /* LOG_ALM_LEAVE */
+
+#ifndef LOG_ACRE_ALM_ENTER
+#define LOG_ACRE_ALM_ENTER(pk_calm)
+#endif /* LOG_ACRE_ALM_ENTER */
+
+#ifndef LOG_ACRE_ALM_LEAVE
+#define LOG_ACRE_ALM_LEAVE(ercd)
+#endif /* LOG_ACRE_ALM_LEAVE */
+
+#ifndef LOG_DEL_ALM_ENTER
+#define LOG_DEL_ALM_ENTER(almid)
+#endif /* LOG_DEL_ALM_ENTER */
+
+#ifndef LOG_DEL_ALM_LEAVE
+#define LOG_DEL_ALM_LEAVE(ercd)
+#endif /* LOG_DEL_ALM_LEAVE */
+
+#ifndef LOG_STA_ALM_ENTER
+#define LOG_STA_ALM_ENTER(almid, almtim)
+#endif /* LOG_STA_ALM_ENTER */
+
+#ifndef LOG_STA_ALM_LEAVE
+#define LOG_STA_ALM_LEAVE(ercd)
+#endif /* LOG_STA_ALM_LEAVE */
+
+#ifndef LOG_ISTA_ALM_ENTER
+#define LOG_ISTA_ALM_ENTER(almid, almtim)
+#endif /* LOG_ISTA_ALM_ENTER */
+
+#ifndef LOG_ISTA_ALM_LEAVE
+#define LOG_ISTA_ALM_LEAVE(ercd)
+#endif /* LOG_ISTA_ALM_LEAVE */
+
+#ifndef LOG_STP_ALM_ENTER
+#define LOG_STP_ALM_ENTER(almid)
+#endif /* LOG_STP_ALM_ENTER */
+
+#ifndef LOG_STP_ALM_LEAVE
+#define LOG_STP_ALM_LEAVE(ercd)
+#endif /* LOG_STP_ALM_LEAVE */
+
+#ifndef LOG_ISTP_ALM_ENTER
+#define LOG_ISTP_ALM_ENTER(almid)
+#endif /* LOG_ISTP_ALM_ENTER */
+
+#ifndef LOG_ISTP_ALM_LEAVE
+#define LOG_ISTP_ALM_LEAVE(ercd)
+#endif /* LOG_ISTP_ALM_LEAVE */
+
+#ifndef LOG_REF_ALM_ENTER
+#define LOG_REF_ALM_ENTER(almid, pk_ralm)
+#endif /* LOG_REF_ALM_ENTER */
+
+#ifndef LOG_REF_ALM_LEAVE
+#define LOG_REF_ALM_LEAVE(ercd, pk_ralm)
+#endif /* LOG_REF_ALM_LEAVE */
+
+/*
+ *  A[nhÌ
+ */
+#define tnum_alm	((uint_t)(tmax_almid - TMIN_ALMID + 1))
+#define tnum_salm	((uint_t)(tmax_salmid - TMIN_ALMID + 1))
+
+/*
+ *  A[nhID©çA[nhÇubNðæèo·½ßÌ}N
+ */
+#define INDEX_ALM(almid)	((uint_t)((almid) - TMIN_ALMID))
+#define get_almcb(almid)	(&(almcb_table[INDEX_ALM(almid)]))
+
+#ifdef TOPPERS_almini
+
+/*
+ *  gpµÄ¢È¢A[nhÇubNÌXg
+ *
+ *  A[nhÇubNÌæªÉÍL
+[ÉÂÈ®½ßÌÌæªÈ
+ *  ¢½ßC^CCxgubNitmevtbjÌÌæðp¢éD
+ */
+QUEUE	free_almcb;
+
+/*
+ *  A[nh@\Ìú»
+ */
+void
+initialize_alarm(void)
+{
+	uint_t	i, j;
+	ALMCB	*p_almcb;
+	ALMINIB	*p_alminib;
+
+	for (i = 0; i < tnum_salm; i++) {
+		p_almcb = &(almcb_table[i]);
+		p_almcb->p_alminib = &(alminib_table[i]);
+		p_almcb->almsta = false;
+	}
+	queue_initialize(&free_almcb);
+	for (j = 0; i < tnum_alm; i++, j++) {
+		p_almcb = &(almcb_table[i]);
+		p_alminib = &(aalminib_table[j]);
+		p_alminib->almatr = TA_NOEXS;
+		p_almcb->p_alminib = ((const ALMINIB *) p_alminib);
+		queue_insert_prev(&free_almcb, ((QUEUE *) &(p_almcb->tmevtb)));
+	}
+}
+
+#endif /* TOPPERS_almini */
+
+/*
+ *  A[nhÌ¶¬
+ */
+#ifdef TOPPERS_acre_alm
+
+ER_UINT
+acre_alm(const T_CALM *pk_calm)
+{
+	ALMCB	*p_almcb;
+	ALMINIB	*p_alminib;
+	ER		ercd;
+
+	LOG_ACRE_ALM_ENTER(pk_calm);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_calm->almatr, TA_NULL);
+	CHECK_ALIGN_FUNC(pk_calm->almhdr);
+	CHECK_NONNULL_FUNC(pk_calm->almhdr);
+
+	t_lock_cpu();
+	if (tnum_alm == 0 || queue_empty(&free_almcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		p_almcb = ((ALMCB *)(((char *) queue_delete_next(&free_almcb))
+												- offsetof(ALMCB, tmevtb)));
+		p_alminib = (ALMINIB *)(p_almcb->p_alminib);
+		p_alminib->almatr = pk_calm->almatr;
+		p_alminib->exinf = pk_calm->exinf;
+		p_alminib->almhdr = pk_calm->almhdr;
+
+		p_almcb->almsta = false;
+		ercd = ALMID(p_almcb);
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_ALM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_alm */
+
+/*
+ *  A[nhÌí
+ */
+#ifdef TOPPERS_del_alm
+
+ER
+del_alm(ID almid)
+{
+	ALMCB	*p_almcb;
+	ALMINIB	*p_alminib;
+	ER		ercd;
+
+	LOG_DEL_ALM_ENTER(almid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ALMID(almid);
+	p_almcb = get_almcb(almid);
+
+	t_lock_cpu();
+	if (p_almcb->p_alminib->almatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (ALMID(p_almcb) > tmax_salmid) {
+		if (p_almcb->almsta) {
+			p_almcb->almsta = false;
+			tmevtb_dequeue(&(p_almcb->tmevtb));
+		}
+
+		p_alminib = (ALMINIB *)(p_almcb->p_alminib);
+		p_alminib->almatr = TA_NOEXS;
+		queue_insert_prev(&free_almcb, ((QUEUE *) &(p_almcb->tmevtb)));
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_ALM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_alm */
+
+/*
+ *  A[nhÌ®ìJn
+ */
+#ifdef TOPPERS_sta_alm
+
+ER
+sta_alm(ID almid, RELTIM almtim)
+{
+	ALMCB	*p_almcb;
+	ER		ercd;
+
+	LOG_STA_ALM_ENTER(almid, almtim);
+	CHECK_TSKCTX_UNL();
+	CHECK_ALMID(almid);
+	CHECK_PAR(almtim <= TMAX_RELTIM);
+	p_almcb = get_almcb(almid);
+
+	t_lock_cpu();
+	if (p_almcb->p_alminib->almatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_almcb->almsta) {
+			tmevtb_dequeue(&(p_almcb->tmevtb));
+		}
+		else {
+			p_almcb->almsta = true;
+		}
+		tmevtb_enqueue(&(p_almcb->tmevtb), almtim,
+									(CBACK) call_almhdr, (void *) p_almcb);
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_STA_ALM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_sta_alm */
+
+/*
+ *  A[nhÌ®ìJniñ^XNReLXgpj
+ */
+#ifdef TOPPERS_ista_alm
+
+ER
+ista_alm(ID almid, RELTIM almtim)
+{
+	ALMCB	*p_almcb;
+	ER		ercd;
+
+	LOG_ISTA_ALM_ENTER(almid, almtim);
+	CHECK_INTCTX_UNL();
+	CHECK_ALMID(almid);
+	CHECK_PAR(almtim <= TMAX_RELTIM);
+	p_almcb = get_almcb(almid);
+
+	i_lock_cpu();
+	if (p_almcb->p_alminib->almatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_almcb->almsta) {
+			tmevtb_dequeue(&(p_almcb->tmevtb));
+		}
+		else {
+			p_almcb->almsta = true;
+		}
+		tmevtb_enqueue(&(p_almcb->tmevtb), almtim,
+									(CBACK) call_almhdr, (void *) p_almcb);
+		ercd = E_OK;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_ISTA_ALM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ista_alm */
+
+/*
+ *  A[nhÌ®ìâ~
+ */
+#ifdef TOPPERS_stp_alm
+
+ER
+stp_alm(ID almid)
+{
+	ALMCB	*p_almcb;
+	ER		ercd;
+
+	LOG_STP_ALM_ENTER(almid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ALMID(almid);
+	p_almcb = get_almcb(almid);
+
+	t_lock_cpu();
+	if (p_almcb->p_alminib->almatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_almcb->almsta) {
+			p_almcb->almsta = false;
+			tmevtb_dequeue(&(p_almcb->tmevtb));
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_STP_ALM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_stp_alm */
+
+/*
+ *  A[nhÌ®ìâ~iñ^XNReLXgpj
+ */
+#ifdef TOPPERS_istp_alm
+
+ER
+istp_alm(ID almid)
+{
+	ALMCB	*p_almcb;
+	ER		ercd;
+
+	LOG_ISTP_ALM_ENTER(almid);
+	CHECK_INTCTX_UNL();
+	CHECK_ALMID(almid);
+	p_almcb = get_almcb(almid);
+
+	i_lock_cpu();
+	if (p_almcb->p_alminib->almatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_almcb->almsta) {
+			p_almcb->almsta = false;
+			tmevtb_dequeue(&(p_almcb->tmevtb));
+		}
+		ercd = E_OK;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_ISTP_ALM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_istp_alm */
+
+/*
+ *  A[nhÌóÔQÆ
+ */
+#ifdef TOPPERS_ref_alm
+
+ER
+ref_alm(ID almid, T_RALM *pk_ralm)
+{
+	ALMCB	*p_almcb;
+	ER		ercd;
+    
+	LOG_REF_ALM_ENTER(almid, pk_ralm);
+	CHECK_TSKCTX_UNL();
+	CHECK_ALMID(almid);
+	p_almcb = get_almcb(almid);
+
+	t_lock_cpu();
+	if (p_almcb->p_alminib->almatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_almcb->almsta) {
+			pk_ralm->almstat = TALM_STA;
+			pk_ralm->lefttim = tmevt_lefttim(&(p_almcb->tmevtb));
+		}
+		else {
+			pk_ralm->almstat = TALM_STP;
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_ALM_LEAVE(ercd, pk_ralm);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_alm */
+
+/*
+ *  A[nhN®[`
+ */
+#ifdef TOPPERS_almcal
+
+void
+call_almhdr(ALMCB *p_almcb)
+{
+	PRI		saved_ipm;
+
+	/*
+	 *  A[nhðâ~óÔÉ·éD
+	 */
+	p_almcb->almsta = false;
+
+	/*
+	 *  A[nhðCCPUbNðóÔÅÄÑo·D
+	 */
+	saved_ipm = i_get_ipm();
+	i_unlock_cpu();
+
+	LOG_ALM_ENTER(p_almcb);
+	(*((ALMHDR)(p_almcb->p_alminib->almhdr)))(p_almcb->p_alminib->exinf);
+	LOG_ALM_LEAVE(p_almcb);
+
+	if (!i_sense_lock()) {
+		i_lock_cpu();
+	}
+	i_set_ipm(saved_ipm);
+}
+
+#endif /* TOPPERS_almcal */
Index: UsbWattMeter/trunk/asp_dcre/kernel/alarm.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/alarm.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/alarm.h	(revision 164)
@@ -0,0 +1,113 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		A[nh@\
+ */
+
+#ifndef TOPPERS_ALARM_H
+#define TOPPERS_ALARM_H
+
+#include <queue.h>
+#include "time_event.h"
+
+/*
+ *  A[nhú»ubN
+ */
+typedef struct alarm_handler_initialization_block {
+	ATR			almatr;			/* A[nh®« */
+	intptr_t	exinf;			/* A[nhÌg£îñ */
+	ALMHDR		almhdr;			/* A[nhÌN®Ôn */
+} ALMINIB;
+
+/*
+ *  A[nhÇubN
+ */
+typedef struct alarm_handler_control_block {
+	const ALMINIB *p_alminib;	/* ú»ubNÖÌ|C^ */
+	bool_t		almsta;			/* A[nhÌ®ìóÔ */
+	TMEVTB		tmevtb;			/* ^CCxgubN */
+} ALMCB;
+
+/*
+ *  gpµÄ¢È¢A[nhÇubNÌXg
+ */
+extern QUEUE	free_almcb;
+
+/*
+ *  A[nhIDÌÅålikernel_cfg.cj
+ */
+extern const ID	tmax_almid;
+extern const ID	tmax_salmid;
+
+/*
+ *  A[nhú»ubNÌGAikernel_cfg.cj
+ */
+extern const ALMINIB	alminib_table[];
+extern ALMINIB			aalminib_table[];
+
+/*
+ *  A[nhÇubNÌGAikernel_cfg.cj
+ */
+extern ALMCB	almcb_table[];
+
+/*
+ *  A[nhÇubN©çA[nhIDðæèo·½ßÌ
+ *  }N
+ */
+#define	ALMID(p_almcb)	((ID)(((p_almcb) - almcb_table) + TMIN_ALMID))
+
+/*
+ *  A[nh@\Ìú»
+ */
+extern void	initialize_alarm(void);
+
+/*
+ *  A[nhN®[`
+ */
+extern void	call_almhdr(ALMCB *p_almcb);
+
+#endif /* TOPPERS_ALARM_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/allfunc.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/allfunc.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/allfunc.h	(revision 164)
@@ -0,0 +1,269 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		·×ÄÌÖðRpC·é½ßÌè`
+ */
+
+#ifndef TOPPERS_ALLFUNC_H
+#define TOPPERS_ALLFUNC_H
+
+/* startup.c */
+#define TOPPERS_sta_ker
+#define TOPPERS_ext_ker
+#define TOPPERS_kermem
+
+/* task.c */
+#define TOPPERS_tskini
+#define TOPPERS_tsksched
+#define TOPPERS_tskrun
+#define TOPPERS_tsknrun
+#define TOPPERS_tskdmt
+#define TOPPERS_tskact
+#define TOPPERS_tskpri
+#define TOPPERS_tskrot
+#define TOPPERS_tsktex
+
+/* wait.c */
+#define TOPPERS_waimake
+#define TOPPERS_waicmp
+#define TOPPERS_waitmo
+#define TOPPERS_waitmook
+#define TOPPERS_wairel
+#define TOPPERS_wobjwai
+#define TOPPERS_wobjwaitmo
+#define TOPPERS_iniwque
+
+/* time_event.c */
+#define TOPPERS_tmeini
+#define TOPPERS_tmeup
+#define TOPPERS_tmedown
+#define TOPPERS_tmeins
+#define TOPPERS_tmedel
+#define TOPPERS_tmeltim
+#define TOPPERS_sigtim
+
+/* task_manage.c */
+#define TOPPERS_acre_tsk
+#define TOPPERS_del_tsk
+#define TOPPERS_act_tsk
+#define TOPPERS_iact_tsk
+#define TOPPERS_can_act
+#define TOPPERS_ext_tsk
+#define TOPPERS_ter_tsk
+#define TOPPERS_chg_pri
+#define TOPPERS_get_pri
+#define TOPPERS_get_inf
+
+/* task_refer.c */
+#define TOPPERS_ref_tsk
+
+/* task_sync.c */
+#define TOPPERS_slp_tsk
+#define TOPPERS_tslp_tsk
+#define TOPPERS_wup_tsk
+#define TOPPERS_iwup_tsk
+#define TOPPERS_can_wup
+#define TOPPERS_rel_wai
+#define TOPPERS_irel_wai
+#define TOPPERS_sus_tsk
+#define TOPPERS_rsm_tsk
+#define TOPPERS_dly_tsk
+
+/* task_except.c */
+#define TOPPERS_def_tex
+#define TOPPERS_ras_tex
+#define TOPPERS_iras_tex
+#define TOPPERS_dis_tex
+#define TOPPERS_ena_tex
+#define TOPPERS_sns_tex
+#define TOPPERS_ref_tex
+
+/* semaphore.c */
+#define TOPPERS_semini
+#define TOPPERS_acre_sem
+#define TOPPERS_del_sem
+#define TOPPERS_sig_sem
+#define TOPPERS_isig_sem
+#define TOPPERS_wai_sem
+#define TOPPERS_pol_sem
+#define TOPPERS_twai_sem
+#define TOPPERS_ini_sem
+#define TOPPERS_ref_sem
+
+/* eventflag.c */
+#define TOPPERS_flgini
+#define TOPPERS_flgcnd
+#define TOPPERS_acre_flg
+#define TOPPERS_del_flg
+#define TOPPERS_set_flg
+#define TOPPERS_iset_flg
+#define TOPPERS_clr_flg
+#define TOPPERS_wai_flg
+#define TOPPERS_pol_flg
+#define TOPPERS_twai_flg
+#define TOPPERS_ini_flg
+#define TOPPERS_ref_flg
+
+/* dataqueue.c */
+#define TOPPERS_dtqini
+#define TOPPERS_dtqenq
+#define TOPPERS_dtqfenq
+#define TOPPERS_dtqdeq
+#define TOPPERS_dtqsnd
+#define TOPPERS_dtqfsnd
+#define TOPPERS_dtqrcv
+#define TOPPERS_acre_dtq
+#define TOPPERS_del_dtq
+#define TOPPERS_snd_dtq
+#define TOPPERS_psnd_dtq
+#define TOPPERS_ipsnd_dtq
+#define TOPPERS_tsnd_dtq
+#define TOPPERS_fsnd_dtq
+#define TOPPERS_ifsnd_dtq
+#define TOPPERS_rcv_dtq
+#define TOPPERS_prcv_dtq
+#define TOPPERS_trcv_dtq
+#define TOPPERS_ini_dtq
+#define TOPPERS_ref_dtq
+
+/* pridataq.c */
+#define TOPPERS_pdqini
+#define TOPPERS_pdqenq
+#define TOPPERS_pdqdeq
+#define TOPPERS_pdqsnd
+#define TOPPERS_pdqrcv
+#define TOPPERS_acre_pdq
+#define TOPPERS_del_pdq
+#define TOPPERS_snd_pdq
+#define TOPPERS_psnd_pdq
+#define TOPPERS_ipsnd_pdq
+#define TOPPERS_tsnd_pdq
+#define TOPPERS_rcv_pdq
+#define TOPPERS_prcv_pdq
+#define TOPPERS_trcv_pdq
+#define TOPPERS_ini_pdq
+#define TOPPERS_ref_pdq
+
+/* mailbox.c */
+#define TOPPERS_mbxini
+#define TOPPERS_acre_mbx
+#define TOPPERS_del_mbx
+#define TOPPERS_snd_mbx
+#define TOPPERS_rcv_mbx
+#define TOPPERS_prcv_mbx
+#define TOPPERS_trcv_mbx
+#define TOPPERS_ini_mbx
+#define TOPPERS_ref_mbx
+
+/* mempfix.c */
+#define TOPPERS_mpfini
+#define TOPPERS_mpfget
+#define TOPPERS_acre_mpf
+#define TOPPERS_del_mpf
+#define TOPPERS_get_mpf
+#define TOPPERS_pget_mpf
+#define TOPPERS_tget_mpf
+#define TOPPERS_rel_mpf
+#define TOPPERS_ini_mpf
+#define TOPPERS_ref_mpf
+
+/* time_manage.c */
+#define TOPPERS_get_tim
+#define TOPPERS_get_utm
+
+/* cyclic.c */
+#define TOPPERS_cycini
+#define TOPPERS_acre_cyc
+#define TOPPERS_del_cyc
+#define TOPPERS_sta_cyc
+#define TOPPERS_stp_cyc
+#define TOPPERS_ref_cyc
+#define TOPPERS_cyccal
+
+/* alarm.c */
+#define TOPPERS_almini
+#define TOPPERS_acre_alm
+#define TOPPERS_del_alm
+#define TOPPERS_sta_alm
+#define TOPPERS_ista_alm
+#define TOPPERS_stp_alm
+#define TOPPERS_istp_alm
+#define TOPPERS_ref_alm
+#define TOPPERS_almcal
+
+/* sys_manage.c */
+#define TOPPERS_rot_rdq
+#define TOPPERS_irot_rdq
+#define TOPPERS_get_tid
+#define TOPPERS_iget_tid
+#define TOPPERS_loc_cpu
+#define TOPPERS_iloc_cpu
+#define TOPPERS_unl_cpu
+#define TOPPERS_iunl_cpu
+#define TOPPERS_dis_dsp
+#define TOPPERS_ena_dsp
+#define TOPPERS_sns_ctx
+#define TOPPERS_sns_loc
+#define TOPPERS_sns_dsp
+#define TOPPERS_sns_dpn
+#define TOPPERS_sns_ker
+
+/* interrupt.c */
+#define TOPPERS_isrini
+#define TOPPERS_isrcal
+#define TOPPERS_acre_isr
+#define TOPPERS_del_isr
+#define TOPPERS_intini
+#define TOPPERS_dis_int
+#define TOPPERS_ena_int
+#define TOPPERS_chg_ipm
+#define TOPPERS_get_ipm
+
+/* exception.c */
+#define TOPPERS_excini
+#define TOPPERS_xsns_dpn
+#define TOPPERS_xsns_xpn
+
+#endif /* TOPPERS_ALLFUNC_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/check.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/check.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/check.h	(revision 164)
@@ -0,0 +1,471 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		G[`FbNp}N
+ */
+
+#ifndef TOPPERS_CHECK_H
+#define TOPPERS_CHECK_H
+
+/*
+ *  \ñ®«G[Ì`FbNiE_PARj
+ */
+#define CHECK_RSATR(atr, valid_atr) do {					\
+	if (((atr) & ~(valid_atr)) != 0U) {						\
+		ercd = E_RSATR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  DæxÌÍÍÌ»è
+ */
+#define VALID_TPRI(tpri)	(TMIN_TPRI <= (tpri) && (tpri) <= TMAX_TPRI)
+
+#define VALID_DPRI(dpri)	(TMIN_DPRI <= (dpri) && (dpri) <= TMAX_DPRI)
+
+#define VALID_MPRI(mpri)	(TMIN_MPRI <= (mpri) && (mpri) <= TMAX_MPRI)
+
+#define VALID_ISRPRI(isrpri) \
+				(TMIN_ISRPRI <= (isrpri) && (isrpri) <= TMAX_ISRPRI)
+
+#ifndef VALID_INTPRI_CHGIPM
+#define VALID_INTPRI_CHGIPM(intpri) \
+				(TMIN_INTPRI <= (intpri) && (intpri) <= TIPM_ENAALL)
+#endif /* VALID_INTPRI_CHGIPM */
+
+/*
+ *  ^XNDæxÌ`FbNiE_PARj
+ */
+#define CHECK_TPRI(tpri) do {								\
+	if (!VALID_TPRI(tpri)) {								\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_TPRI_INI(tpri) do {							\
+	if (!(VALID_TPRI(tpri) || (tpri) == TPRI_INI)) {		\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_TPRI_SELF(tpri) do {							\
+	if (!(VALID_TPRI(tpri) || (tpri) == TPRI_SELF)) {		\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  f[^DæxÌ`FbNiE_PARj
+ */
+#define CHECK_DPRI(dpri) do {								\
+	if (!VALID_DPRI(dpri)) {								\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  bZ[WDæxÌ`FbNiE_PARj
+ */
+#define CHECK_MPRI(mpri) do {								\
+	if (!VALID_MPRI(mpri)) {								\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  ÝT[rX[`DæxÌ`FbNiE_PARj
+ */
+#define CHECK_ISRPRI(isrpri) do {							\
+	if (!VALID_ISRPRI(isrpri)) {							\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  ^CAEgwèlÌ`FbNiE_PARj
+ */
+#define CHECK_TMOUT(tmout) do {								\
+	if (!(TMO_FEVR <= (tmout))) {							\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  ÝDæxÌ`FbNiE_PARj
+ */
+#define CHECK_INTPRI_CHGIPM(intpri) do {					\
+	if (!VALID_INTPRI_CHGIPM(intpri)) {						\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  ÝÔÌ`FbNiE_PARj
+ */
+#define CHECK_INTNO_CREISR(intno) do {						\
+	if (!VALID_INTNO_CREISR(intno)) {						\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_INTNO_DISINT(intno) do {						\
+	if (!VALID_INTNO_DISINT(intno)) {						\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  ACµÄ¢é©Ì»è
+ */
+#define ALIGNED(val, align)		((((uintptr_t)(val)) & ((align) - 1U)) == 0U)
+
+#ifdef CHECK_FUNC_ALIGN
+#define FUNC_ALIGNED(func)		ALIGNED(func, CHECK_FUNC_ALIGN)
+#else /* CHECK_FUNC_ALIGN */
+#define FUNC_ALIGNED(func)		true
+#endif /* CHECK_FUNC_ALIGN */
+
+#ifdef CHECK_STKSZ_ALIGN
+#define STKSZ_ALIGNED(stksz)	ALIGNED(stksz, CHECK_STKSZ_ALIGN)
+#else /* CHECK_STKSZ_ALIGN */
+#define STKSZ_ALIGNED(stksz)	true
+#endif /* CHECK_STKSZ_ALIGN */
+
+#ifdef CHECK_STACK_ALIGN
+#define STACK_ALIGNED(stack)	ALIGNED(stack, CHECK_STACK_ALIGN)
+#else /* CHECK_STACK_ALIGN */
+#define STACK_ALIGNED(stack)	true
+#endif /* CHECK_STACK_ALIGN */
+
+#ifdef CHECK_MPF_ALIGN
+#define MPF_ALIGNED(mpf)		ALIGNED(mpf, CHECK_MPF_ALIGN)
+#else /* CHECK_MPF_ALIGN */
+#define MPF_ALIGNED(mpf)		true
+#endif /* CHECK_MPF_ALIGN */
+
+#ifdef CHECK_MB_ALIGN
+#define MB_ALIGNED(mb)			ALIGNED(mb, CHECK_MB_ALIGN)
+#else /* CHECK_MB_ALIGN */
+#define MB_ALIGNED(mb)			true
+#endif /* CHECK_MB_ALIGN */
+
+/*
+ *  NULLÅÈ¢±ÆÌ`FbN
+ */
+#ifdef CHECK_FUNC_NONNULL
+#define FUNC_NONNULL(func)		((func) != NULL)
+#else /* CHECK_FUNC_NONNULL */
+#define FUNC_NONNULL(func)		true
+#endif /* CHECK_FUNC_NONNULL */
+
+/*
+ *  ÖÌæªÔnÌ`FbNiE_PARj
+ */
+#define CHECK_ALIGN_FUNC(func) do {							\
+	if (!FUNC_ALIGNED(func)) {								\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_NONNULL_FUNC(func) do {						\
+	if (!FUNC_NONNULL(func)) {								\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  X^bNTCYÌ`FbNiE_PARj
+ */
+#define CHECK_ALIGN_STKSZ(stksz) do {						\
+	if (!STKSZ_ALIGNED(stksz)) {							\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  X^bNÌæªÔnÌ`FbNiE_PARj
+ */
+#define CHECK_ALIGN_STACK(stack) do {						\
+	if (!STACK_ALIGNED(stack)) {							\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  Åè·v[ÌæÌæªÔnÌ`FbNiE_PARj
+ */
+#define CHECK_ALIGN_MPF(mpf) do {							\
+	if (!MPF_ALIGNED(mpf)) {								\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  ÇÌæÌæªÔnÌ`FbNiE_PARj
+ */
+#define CHECK_ALIGN_MB(mb) do {								\
+	if (!MB_ALIGNED(mb)) {									\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  »Ì¼Ìp[^G[Ì`FbNiE_PARj
+ */
+#define CHECK_PAR(exp) do {									\
+	if (!(exp)) {											\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  IuWFNgIDÌÍÍÌ»è
+ */
+#define VALID_TSKID(tskid)	(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)
+#define VALID_SEMID(semid)	(TMIN_SEMID <= (semid) && (semid) <= tmax_semid)
+#define VALID_FLGID(flgid)	(TMIN_FLGID <= (flgid) && (flgid) <= tmax_flgid)
+#define VALID_DTQID(dtqid)	(TMIN_DTQID <= (dtqid) && (dtqid) <= tmax_dtqid)
+#define VALID_PDQID(pdqid)	(TMIN_PDQID <= (pdqid) && (pdqid) <= tmax_pdqid)
+#define VALID_MBXID(mbxid)	(TMIN_MBXID <= (mbxid) && (mbxid) <= tmax_mbxid)
+#define VALID_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)
+
+/*
+ *  IuWFNgIDÌ`FbNiE_IDj
+ */
+#define CHECK_TSKID(tskid) do {								\
+	if (!VALID_TSKID(tskid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_TSKID_SELF(tskid) do {						\
+	if (!(VALID_TSKID(tskid) || (tskid) == TSK_SELF)) {		\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_SEMID(semid) do {								\
+	if (!VALID_SEMID(semid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_FLGID(flgid) do {								\
+	if (!VALID_FLGID(flgid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_DTQID(dtqid) do {								\
+	if (!VALID_DTQID(dtqid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_PDQID(pdqid) do {								\
+	if (!VALID_PDQID(pdqid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_MBXID(mbxid) do {								\
+	if (!VALID_MBXID(mbxid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_MPFID(mpfid) do {								\
+	if (!VALID_MPFID(mpfid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_CYCID(cycid) do {								\
+	if (!VALID_CYCID(cycid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_ALMID(almid) do {								\
+	if (!VALID_ALMID(almid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_ISRID(isrid) do {								\
+	if (!VALID_ISRID(isrid)) {								\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  ÄoµReLXgÌ`FbNiE_CTXj
+ */
+#define CHECK_TSKCTX() do {									\
+	if (sense_context()) {									\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_INTCTX() do {									\
+	if (!sense_context()) {									\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  ÄoµReLXgÆCPUbNóÔÌ`FbNiE_CTXj
+ */
+#define CHECK_TSKCTX_UNL() do {								\
+	if (sense_context() || t_sense_lock()) {				\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#define CHECK_INTCTX_UNL() do {								\
+	if (!sense_context() || i_sense_lock()) {				\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  fBXpb`Û¯óÔÅÈ¢©Ì`FbNiE_CTXj
+ */
+#define CHECK_DISPATCH() do {								\
+	if (sense_context() || t_sense_lock() || !dspflg) {		\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  »Ì¼ÌReLXgG[Ì`FbNiE_CTXj
+ */
+#define CHECK_CTX(exp) do {									\
+	if (!(exp)) {											\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  ©^XNðwèµÄ¢È¢©Ì`FbNiE_ILUSEj
+ */
+#define CHECK_NONSELF(p_tcb) do {							\
+	if ((p_tcb) == p_runtsk) {								\
+		ercd = E_ILUSE;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  »Ì¼Ìs³gpG[Ì`FbNiE_ILUSEj
+ */
+#define CHECK_ILUSE(exp) do {								\
+	if (!(exp)) {											\
+		ercd = E_ILUSE;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  ¢T|[g@\G[Ì`FbNiE_NOSPTj
+ */
+#define CHECK_NOSPT(exp) do {								\
+	if (!(exp)) {											\
+		ercd = E_NOSPT;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  ÃIÈIuWFNgóÔG[Ì`FbNiE_OBJj
+ */
+#define CHECK_OBJ(exp) do {									\
+	if (!(exp)) {											\
+		ercd = E_OBJ;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+#endif /* TOPPERS_CHECK_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/cyclic.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/cyclic.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/cyclic.c	(revision 164)
@@ -0,0 +1,419 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		üúnh@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "cyclic.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#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 */
+
+/*
+ *  üúnhÌ
+ */
+#define tnum_cyc	((uint_t)(tmax_cycid - TMIN_CYCID + 1))
+#define tnum_scyc	((uint_t)(tmax_scycid - TMIN_CYCID + 1))
+
+/*
+ *  üúnhID©çüúnhÇubNðæèo·½ßÌ}N
+ */
+#define INDEX_CYC(cycid)	((uint_t)((cycid) - TMIN_CYCID))
+#define get_cyccb(cycid)	(&(cyccb_table[INDEX_CYC(cycid)]))
+
+/*
+ *  üúnhN®Ì½ßÌ^CCxgubNÌo^
+ */
+Inline void
+tmevtb_enqueue_cyc(CYCCB *p_cyccb, EVTTIM evttim)
+{
+	tmevtb_enqueue_evttim(&(p_cyccb->tmevtb), evttim,
+								(CBACK) call_cychdr, (void *) p_cyccb);
+	p_cyccb->evttim = evttim;
+}
+
+#ifdef TOPPERS_cycini
+
+/*
+ *  gpµÄ¢È¢üúnhÇubNÌXg
+ *
+ *  üúnhÇubNÌæªÉÍL
+[ÉÂÈ®½ßÌÌæªÈ¢½
+ *  ßC^CCxgubNitmevtbjÌÌæðp¢éD
+ */
+QUEUE	free_cyccb;
+
+/*
+ *  üúnh@\Ìú»
+ */
+void
+initialize_cyclic(void)
+{
+	uint_t	i, j;
+	CYCCB	*p_cyccb;
+	CYCINIB	*p_cycinib;
+
+	for (i = 0; i < tnum_scyc; i++) {
+		p_cyccb = &(cyccb_table[i]);
+		p_cyccb->p_cycinib = &(cycinib_table[i]);
+		if ((p_cyccb->p_cycinib->cycatr & TA_STA) != 0U) {
+			p_cyccb->cycsta = true;
+			tmevtb_enqueue_cyc(p_cyccb, (EVTTIM)(p_cyccb->p_cycinib->cycphs));
+		}
+		else {
+			p_cyccb->cycsta = false;
+		}
+	}
+	queue_initialize(&free_cyccb);
+	for (j = 0; i < tnum_cyc; i++, j++) {
+		p_cyccb = &(cyccb_table[i]);
+		p_cycinib = &(acycinib_table[j]);
+		p_cycinib->cycatr = TA_NOEXS;
+		p_cyccb->p_cycinib = ((const CYCINIB *) p_cycinib);
+		queue_insert_prev(&free_cyccb, ((QUEUE *) &(p_cyccb->tmevtb)));
+	}
+}
+
+#endif /* TOPPERS_cycini */
+
+/*
+ *  üúnhÌ¶¬
+ */
+#ifdef TOPPERS_acre_cyc
+
+ER_UINT
+acre_cyc(const T_CCYC *pk_ccyc)
+{
+	CYCCB	*p_cyccb;
+	CYCINIB	*p_cycinib;
+	ER		ercd;
+
+	LOG_ACRE_CYC_ENTER(pk_ccyc);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_ccyc->cycatr, TA_STA);
+	CHECK_ALIGN_FUNC(pk_ccyc->cychdr);
+	CHECK_NONNULL_FUNC(pk_ccyc->cychdr);
+	CHECK_PAR(0 < pk_ccyc->cyctim && pk_ccyc->cyctim <= TMAX_RELTIM);
+	CHECK_PAR(0 <= pk_ccyc->cycphs && pk_ccyc->cycphs <= TMAX_RELTIM);
+
+	t_lock_cpu();
+	if (tnum_cyc == 0 || queue_empty(&free_cyccb)) {
+		ercd = E_NOID;
+	}
+	else {
+		p_cyccb = ((CYCCB *)(((char *) queue_delete_next(&free_cyccb))
+												- offsetof(CYCCB, tmevtb)));
+		p_cycinib = (CYCINIB *)(p_cyccb->p_cycinib);
+		p_cycinib->cycatr = pk_ccyc->cycatr;
+		p_cycinib->exinf = pk_ccyc->exinf;
+		p_cycinib->cychdr = pk_ccyc->cychdr;
+		p_cycinib->cyctim = pk_ccyc->cyctim;
+		p_cycinib->cycphs = pk_ccyc->cycphs;
+
+		if ((p_cyccb->p_cycinib->cycatr & TA_STA) != 0U) {
+			p_cyccb->cycsta = true;
+			tmevtb_enqueue_cyc(p_cyccb,
+								base_time + p_cyccb->p_cycinib->cycphs);
+		}
+		else {
+			p_cyccb->cycsta = false;
+		}
+		ercd = CYCID(p_cyccb);
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_CYC_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_cyc */
+
+/*
+ *  üúnhÌí
+ */
+#ifdef TOPPERS_del_cyc
+
+ER
+del_cyc(ID cycid)
+{
+	CYCCB	*p_cyccb;
+	CYCINIB	*p_cycinib;
+	ER		ercd;
+
+	LOG_DEL_CYC_ENTER(cycid);
+	CHECK_TSKCTX_UNL();
+	CHECK_CYCID(cycid);
+	p_cyccb = get_cyccb(cycid);
+
+	t_lock_cpu();
+	if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (CYCID(p_cyccb) > tmax_scycid) {
+		if (p_cyccb->cycsta) {
+			p_cyccb->cycsta = false;
+			tmevtb_dequeue(&(p_cyccb->tmevtb));
+		}
+
+		p_cycinib = (CYCINIB *)(p_cyccb->p_cycinib);
+		p_cycinib->cycatr = TA_NOEXS;
+		queue_insert_prev(&free_cyccb, ((QUEUE *) &(p_cyccb->tmevtb)));
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_CYC_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_cyc */
+
+/*
+ *  üúnhÌ®ìJn
+ */
+#ifdef TOPPERS_sta_cyc
+
+ER
+sta_cyc(ID cycid)
+{
+	CYCCB	*p_cyccb;
+	ER		ercd;
+
+	LOG_STA_CYC_ENTER(cycid);
+	CHECK_TSKCTX_UNL();
+	CHECK_CYCID(cycid);
+	p_cyccb = get_cyccb(cycid);
+
+	t_lock_cpu();
+	if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_cyccb->cycsta) {
+			tmevtb_dequeue(&(p_cyccb->tmevtb));
+		}
+		else {
+			p_cyccb->cycsta = true;
+		}
+		tmevtb_enqueue_cyc(p_cyccb, base_time + p_cyccb->p_cycinib->cycphs);
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_STA_CYC_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_sta_cyc */
+
+/*
+ *  üúnhÌ®ìâ~
+ */
+#ifdef TOPPERS_stp_cyc
+
+ER
+stp_cyc(ID cycid)
+{
+	CYCCB	*p_cyccb;
+	ER		ercd;
+
+	LOG_STP_CYC_ENTER(cycid);
+	CHECK_TSKCTX_UNL();
+	CHECK_CYCID(cycid);
+	p_cyccb = get_cyccb(cycid);
+
+	t_lock_cpu();
+	if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_cyccb->cycsta) {
+			p_cyccb->cycsta = false;
+			tmevtb_dequeue(&(p_cyccb->tmevtb));
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_STP_CYC_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_stp_cyc */
+
+/*
+ *  üúnhÌóÔQÆ
+ */
+#ifdef TOPPERS_ref_cyc
+
+ER
+ref_cyc(ID cycid, T_RCYC *pk_rcyc)
+{
+	CYCCB	*p_cyccb;
+	ER		ercd;
+    
+	LOG_REF_CYC_ENTER(cycid, pk_rcyc);
+	CHECK_TSKCTX_UNL();
+	CHECK_CYCID(cycid);
+	p_cyccb = get_cyccb(cycid);
+
+	t_lock_cpu();
+	if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		if (p_cyccb->cycsta) {
+			pk_rcyc->cycstat = TCYC_STA;
+			pk_rcyc->lefttim = tmevt_lefttim(&(p_cyccb->tmevtb));
+		}
+		else {
+			pk_rcyc->cycstat = TCYC_STP;
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_CYC_LEAVE(ercd, pk_rcyc);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_cyc */
+
+/*
+ *  üúnhN®[`
+ */
+#ifdef TOPPERS_cyccal
+
+void
+call_cychdr(CYCCB *p_cyccb)
+{
+	PRI		saved_ipm;
+
+	/*
+	 *  ñÌN®Ì½ßÌ^CCxgubNðo^·éD
+	 *
+	 *  ¯¶^CeBbNÅüúnhðÄxN®·×«êÉÍC±Ì
+	 *  Ö©çsignal_timeÉßÁ½ãÉCÄx±ÌÖªÄÎêé±ÆÉÈ
+	 *  éD
+	 */
+	tmevtb_enqueue_cyc(p_cyccb, p_cyccb->evttim + p_cyccb->p_cycinib->cyctim);
+
+	/*
+	 *  üúnhðCCPUbNðóÔÅÄÑo·D
+	 */
+	saved_ipm = i_get_ipm();
+	i_unlock_cpu();
+
+	LOG_CYC_ENTER(p_cyccb);
+	(*((CYCHDR)(p_cyccb->p_cycinib->cychdr)))(p_cyccb->p_cycinib->exinf);
+	LOG_CYC_LEAVE(p_cyccb);
+
+	if (!i_sense_lock()) {
+		i_lock_cpu();
+	}
+	i_set_ipm(saved_ipm);
+}
+
+#endif /* TOPPERS_cyccal */
Index: UsbWattMeter/trunk/asp_dcre/kernel/cyclic.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/cyclic.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/cyclic.h	(revision 164)
@@ -0,0 +1,115 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		üúnh@\
+ */
+
+#ifndef TOPPERS_CYCLIC_H
+#define TOPPERS_CYCLIC_H
+
+#include <queue.h>
+#include "time_event.h"
+
+/*
+ *  üúnhú»ubN
+ */
+typedef struct cyclic_handler_initialization_block {
+	ATR			cycatr;			/* üúnh®« */
+	intptr_t	exinf;			/* üúnhÌg£îñ */
+	CYCHDR		cychdr;			/* üúnhÌN®Ôn */
+	RELTIM		cyctim;			/* üúnhÌN®üú */
+	RELTIM		cycphs;			/* üúnhÌN®Ê */
+} CYCINIB;
+
+/*
+ *  üúnhÇubN
+ */
+typedef struct cyclic_handler_control_block {
+	const CYCINIB *p_cycinib;	/* ú»ubNÖÌ|C^ */
+	bool_t		cycsta;			/* üúnhÌ®ìóÔ */
+	EVTTIM		evttim;			/* ÉüúnhðN®·é */
+	TMEVTB		tmevtb;			/* ^CCxgubN */
+} CYCCB;
+
+/*
+ *  gpµÄ¢È¢üúnhÇubNÌXg
+ */
+extern QUEUE	free_cyccb;
+
+/*
+ *  üúnhIDÌÅålikernel_cfg.cj
+ */
+extern const ID	tmax_cycid;
+extern const ID	tmax_scycid;
+
+/*
+ *  üúnhú»ubNÌGAikernel_cfg.cj
+ */
+extern const CYCINIB	cycinib_table[];
+extern CYCINIB			acycinib_table[];
+
+/*
+ *  üúnhÇubNÌGAikernel_cfg.cj
+ */
+extern CYCCB	cyccb_table[];
+
+/*
+ *  üúnhÇubN©çüúnhIDðæèo·½ßÌ}N
+ */
+#define	CYCID(p_cyccb)	((ID)(((p_cyccb) - cyccb_table) + TMIN_CYCID))
+
+/*
+ *  üúnh@\Ìú»
+ */
+extern void	initialize_cyclic(void);
+
+/*
+ *  üúnhN®[`
+ */
+extern void	call_cychdr(CYCCB *p_cyccb);
+
+#endif /* TOPPERS_CYCLIC_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/dataqueue.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/dataqueue.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/dataqueue.c	(revision 164)
@@ -0,0 +1,957 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		f[^L
+[@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "dataqueue.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_ACRE_DTQ_ENTER
+#define LOG_ACRE_DTQ_ENTER(pk_cdtq)
+#endif /* LOG_ACRE_DTQ_ENTER */
+
+#ifndef LOG_ACRE_DTQ_LEAVE
+#define LOG_ACRE_DTQ_LEAVE(ercd)
+#endif /* LOG_ACRE_DTQ_LEAVE */
+
+#ifndef LOG_DEL_DTQ_ENTER
+#define LOG_DEL_DTQ_ENTER(dtqid)
+#endif /* LOG_DEL_DTQ_ENTER */
+
+#ifndef LOG_DEL_DTQ_LEAVE
+#define LOG_DEL_DTQ_LEAVE(ercd)
+#endif /* LOG_DEL_DTQ_LEAVE */
+
+#ifndef LOG_SND_DTQ_ENTER
+#define LOG_SND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_SND_DTQ_ENTER */
+
+#ifndef LOG_SND_DTQ_LEAVE
+#define LOG_SND_DTQ_LEAVE(ercd)
+#endif /* LOG_SND_DTQ_LEAVE */
+
+#ifndef LOG_PSND_DTQ_ENTER
+#define LOG_PSND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_PSND_DTQ_ENTER */
+
+#ifndef LOG_PSND_DTQ_LEAVE
+#define LOG_PSND_DTQ_LEAVE(ercd)
+#endif /* LOG_PSND_DTQ_LEAVE */
+
+#ifndef LOG_IPSND_DTQ_ENTER
+#define LOG_IPSND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_IPSND_DTQ_ENTER */
+
+#ifndef LOG_IPSND_DTQ_LEAVE
+#define LOG_IPSND_DTQ_LEAVE(ercd)
+#endif /* LOG_IPSND_DTQ_LEAVE */
+
+#ifndef LOG_TSND_DTQ_ENTER
+#define LOG_TSND_DTQ_ENTER(dtqid, data, tmout)
+#endif /* LOG_TSND_DTQ_ENTER */
+
+#ifndef LOG_TSND_DTQ_LEAVE
+#define LOG_TSND_DTQ_LEAVE(ercd)
+#endif /* LOG_TSND_DTQ_LEAVE */
+
+#ifndef LOG_FSND_DTQ_ENTER
+#define LOG_FSND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_FSND_DTQ_ENTER */
+
+#ifndef LOG_FSND_DTQ_LEAVE
+#define LOG_FSND_DTQ_LEAVE(ercd)
+#endif /* LOG_FSND_DTQ_LEAVE */
+
+#ifndef LOG_IFSND_DTQ_ENTER
+#define LOG_IFSND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_IFSND_DTQ_ENTER */
+
+#ifndef LOG_IFSND_DTQ_LEAVE
+#define LOG_IFSND_DTQ_LEAVE(ercd)
+#endif /* LOG_IFSND_DTQ_LEAVE */
+
+#ifndef LOG_RCV_DTQ_ENTER
+#define LOG_RCV_DTQ_ENTER(dtqid, p_data)
+#endif /* LOG_RCV_DTQ_ENTER */
+
+#ifndef LOG_RCV_DTQ_LEAVE
+#define LOG_RCV_DTQ_LEAVE(ercd, data)
+#endif /* LOG_RCV_DTQ_LEAVE */
+
+#ifndef LOG_PRCV_DTQ_ENTER
+#define LOG_PRCV_DTQ_ENTER(dtqid, p_data)
+#endif /* LOG_PRCV_DTQ_ENTER */
+
+#ifndef LOG_PRCV_DTQ_LEAVE
+#define LOG_PRCV_DTQ_LEAVE(ercd, data)
+#endif /* LOG_PRCV_DTQ_LEAVE */
+
+#ifndef LOG_TRCV_DTQ_ENTER
+#define LOG_TRCV_DTQ_ENTER(dtqid, p_data, tmout)
+#endif /* LOG_TRCV_DTQ_ENTER */
+
+#ifndef LOG_TRCV_DTQ_LEAVE
+#define LOG_TRCV_DTQ_LEAVE(ercd, data)
+#endif /* LOG_TRCV_DTQ_LEAVE */
+
+#ifndef LOG_INI_DTQ_ENTER
+#define LOG_INI_DTQ_ENTER(dtqid)
+#endif /* LOG_INI_DTQ_ENTER */
+
+#ifndef LOG_INI_DTQ_LEAVE
+#define LOG_INI_DTQ_LEAVE(ercd)
+#endif /* LOG_INI_DTQ_LEAVE */
+
+#ifndef LOG_REF_DTQ_ENTER
+#define LOG_REF_DTQ_ENTER(dtqid, pk_rdtq)
+#endif /* LOG_REF_DTQ_ENTER */
+
+#ifndef LOG_REF_DTQ_LEAVE
+#define LOG_REF_DTQ_LEAVE(ercd, pk_rdtq)
+#endif /* LOG_REF_DTQ_LEAVE */
+
+/*
+ *  f[^L
+[Ì
+ */
+#define tnum_dtq	((uint_t)(tmax_dtqid - TMIN_DTQID + 1))
+#define tnum_sdtq	((uint_t)(tmax_sdtqid - TMIN_DTQID + 1))
+
+/*
+ *  f[^L
+[ID©çf[^L
+[ÇubNðæèo·½ßÌ}N
+ */
+#define INDEX_DTQ(dtqid)	((uint_t)((dtqid) - TMIN_DTQID))
+#define get_dtqcb(dtqid)	(&(dtqcb_table[INDEX_DTQ(dtqid)]))
+
+#ifdef TOPPERS_dtqini
+
+/*
+ *  gpµÄ¢È¢f[^L
+[ÇubNÌXg
+ */
+QUEUE	free_dtqcb;
+
+/*
+ *  f[^L
+[@\Ìú»
+ */
+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 */
+
+/*
+ *  f[^L
+[ÇÌæÖÌf[^Ìi[
+ */
+#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 */
+
+/*
+ *  f[^L
+[ÇÌæÖÌf[^Ì­§i[
+ */
+#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 */
+
+/*
+ *  f[^L
+[ÇÌæ©çÌf[^Ìæoµ
+ */
+#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 */
+
+/*
+ *  f[^L
+[ÖÌf[^M
+ */
+#ifdef TOPPERS_dtqsnd
+
+bool_t
+send_data(DTQCB *p_dtqcb, intptr_t data, bool_t *p_dspreq)
+{
+	TCB		*p_tcb;
+
+	if (!queue_empty(&(p_dtqcb->rwait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_dtqcb->rwait_queue));
+		((WINFO_DTQ *)(p_tcb->p_winfo))->data = data;
+		*p_dspreq = wait_complete(p_tcb);
+		return(true);
+	}
+	else if (p_dtqcb->count < p_dtqcb->p_dtqinib->dtqcnt) {
+		enqueue_data(p_dtqcb, data);
+		*p_dspreq = false;
+		return(true);
+	}
+	else {
+		return(false);
+	}
+}
+
+#endif /* TOPPERS_dtqsnd */
+
+/*
+ *  f[^L
+[ÖÌf[^­§M
+ */
+#ifdef TOPPERS_dtqfsnd
+
+bool_t
+force_send_data(DTQCB *p_dtqcb, intptr_t data)
+{
+	TCB		*p_tcb;
+
+	if (!queue_empty(&(p_dtqcb->rwait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_dtqcb->rwait_queue));
+		((WINFO_DTQ *)(p_tcb->p_winfo))->data = data;
+		return(wait_complete(p_tcb));
+	}
+	else {
+		force_enqueue_data(p_dtqcb, data);
+		return(false);
+	}
+}
+
+#endif /* TOPPERS_dtqfsnd */
+
+/*
+ *  f[^L
+[©çÌf[^óM
+ */
+#ifdef TOPPERS_dtqrcv
+
+bool_t
+receive_data(DTQCB *p_dtqcb, intptr_t *p_data, bool_t *p_dspreq)
+{
+	TCB		*p_tcb;
+	intptr_t data;
+
+	if (p_dtqcb->count > 0U) {
+		dequeue_data(p_dtqcb, p_data);
+		if (!queue_empty(&(p_dtqcb->swait_queue))) {
+			p_tcb = (TCB *) queue_delete_next(&(p_dtqcb->swait_queue));
+			data = ((WINFO_DTQ *)(p_tcb->p_winfo))->data;
+			enqueue_data(p_dtqcb, data);
+			*p_dspreq = wait_complete(p_tcb);
+		}
+		else {
+			*p_dspreq = false;
+		}
+		return(true);
+	}
+	else if (!queue_empty(&(p_dtqcb->swait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_dtqcb->swait_queue));
+		*p_data = ((WINFO_DTQ *)(p_tcb->p_winfo))->data;
+		*p_dspreq = wait_complete(p_tcb);
+		return(true);
+	}
+	else {
+		return(false);
+	}
+}
+
+#endif /* TOPPERS_dtqrcv */
+
+/*
+ *  f[^L
+[Ì¶¬
+ */
+#ifdef TOPPERS_acre_dtq
+
+ER_UINT
+acre_dtq(const T_CDTQ *pk_cdtq)
+{
+	DTQCB		*p_dtqcb;
+	DTQINIB		*p_dtqinib;
+	ATR			dtqatr;
+	DTQMB		*p_dtqmb;
+	ER			ercd;
+
+	LOG_ACRE_DTQ_ENTER(pk_cdtq);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_cdtq->dtqatr, TA_TPRI);
+	if (pk_cdtq->dtqmb != NULL) {
+		CHECK_ALIGN_MB(pk_cdtq->dtqmb);
+	}
+	dtqatr = pk_cdtq->dtqatr;
+	p_dtqmb = pk_cdtq->dtqmb;
+
+	t_lock_cpu();
+	if (tnum_dtq == 0 || queue_empty(&free_dtqcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		if (pk_cdtq->dtqcnt != 0 && p_dtqmb == NULL) {
+			p_dtqmb = kernel_malloc(sizeof(DTQMB) * pk_cdtq->dtqcnt);
+			dtqatr |= TA_MBALLOC;
+		}
+		if (pk_cdtq->dtqcnt != 0 && p_dtqmb == NULL) {
+			ercd = E_NOMEM;
+		}
+		else {
+			p_dtqcb = ((DTQCB *) queue_delete_next(&free_dtqcb));
+			p_dtqinib = (DTQINIB *)(p_dtqcb->p_dtqinib);
+			p_dtqinib->dtqatr = dtqatr;
+			p_dtqinib->dtqcnt = pk_cdtq->dtqcnt;
+			p_dtqinib->p_dtqmb = p_dtqmb;
+
+			queue_initialize(&(p_dtqcb->swait_queue));
+			queue_initialize(&(p_dtqcb->rwait_queue));
+			p_dtqcb->count = 0U;
+			p_dtqcb->head = 0U;
+			p_dtqcb->tail = 0U;
+			ercd = DTQID(p_dtqcb);
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_dtq */
+
+/*
+ *  f[^L
+[Ìí
+ */
+#ifdef TOPPERS_del_dtq
+
+ER
+del_dtq(ID dtqid)
+{
+	DTQCB	*p_dtqcb;
+	DTQINIB	*p_dtqinib;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_DEL_DTQ_ENTER(dtqid);
+	CHECK_TSKCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (DTQID(p_dtqcb) > tmax_sdtqid) {
+		dspreq = init_wait_queue(&(p_dtqcb->swait_queue));
+		if (init_wait_queue(&(p_dtqcb->rwait_queue))) {
+			dspreq = true;
+		}
+		p_dtqinib = (DTQINIB *)(p_dtqcb->p_dtqinib);
+		if ((p_dtqinib->dtqatr & TA_MBALLOC) != 0U) {
+			kernel_free(p_dtqinib->p_dtqmb);
+		}
+		p_dtqinib->dtqatr = TA_NOEXS;
+		queue_insert_prev(&free_dtqcb, &(p_dtqcb->swait_queue));
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_dtq */
+
+/*
+ *  f[^L
+[ÖÌM
+ */
+#ifdef TOPPERS_snd_dtq
+
+ER
+snd_dtq(ID dtqid, intptr_t data)
+{
+	DTQCB	*p_dtqcb;
+	WINFO_DTQ winfo_dtq;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_SND_DTQ_ENTER(dtqid, data);
+	CHECK_DISPATCH();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (send_data(p_dtqcb, data, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		winfo_dtq.data = data;
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SDTQ);
+		wobj_make_wait((WOBJCB *) p_dtqcb, (WINFO_WOBJ *) &winfo_dtq);
+		dispatch();
+		ercd = winfo_dtq.winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_SND_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_snd_dtq */
+
+/*
+ *  f[^L
+[ÖÌMi|[Oj
+ */
+#ifdef TOPPERS_psnd_dtq
+
+ER
+psnd_dtq(ID dtqid, intptr_t data)
+{
+	DTQCB	*p_dtqcb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_PSND_DTQ_ENTER(dtqid, data);
+	CHECK_TSKCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (send_data(p_dtqcb, data, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_PSND_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_psnd_dtq */
+
+/*
+ *  f[^L
+[ÖÌMi|[OCñ^XNReLXgpj
+ */
+#ifdef TOPPERS_ipsnd_dtq
+
+ER
+ipsnd_dtq(ID dtqid, intptr_t data)
+{
+	DTQCB	*p_dtqcb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_IPSND_DTQ_ENTER(dtqid, data);
+	CHECK_INTCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	i_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (send_data(p_dtqcb, data, &dspreq)) {
+		if (dspreq) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IPSND_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ipsnd_dtq */
+
+/*
+ *  f[^L
+[ÖÌMi^CAEg èj
+ */
+#ifdef TOPPERS_tsnd_dtq
+
+ER
+tsnd_dtq(ID dtqid, intptr_t data, TMO tmout)
+{
+	DTQCB	*p_dtqcb;
+	WINFO_DTQ winfo_dtq;
+	TMEVTB	tmevtb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_TSND_DTQ_ENTER(dtqid, data, tmout);
+	CHECK_DISPATCH();
+	CHECK_DTQID(dtqid);
+	CHECK_TMOUT(tmout);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (send_data(p_dtqcb, data, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		winfo_dtq.data = data;
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SDTQ);
+		wobj_make_wait_tmout((WOBJCB *) p_dtqcb, (WINFO_WOBJ *) &winfo_dtq,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_dtq.winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TSND_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_tsnd_dtq */
+
+/*
+ *  f[^L
+[ÖÌ­§M
+ */
+#ifdef TOPPERS_fsnd_dtq
+
+ER
+fsnd_dtq(ID dtqid, intptr_t data)
+{
+	DTQCB	*p_dtqcb;	
+	ER		ercd;
+
+	LOG_FSND_DTQ_ENTER(dtqid, data);
+	CHECK_TSKCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!(p_dtqcb->p_dtqinib->dtqcnt > 0U)) {
+		ercd = E_ILUSE;
+	}
+	else if (force_send_data(p_dtqcb, data)) {
+		dispatch();
+	}
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_FSND_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_fsnd_dtq */
+
+/*
+ *  f[^L
+[ÖÌ­§Miñ^XNReLXgpj
+ */
+#ifdef TOPPERS_ifsnd_dtq
+
+ER
+ifsnd_dtq(ID dtqid, intptr_t data)
+{
+	DTQCB	*p_dtqcb;
+	ER		ercd;
+
+	LOG_IFSND_DTQ_ENTER(dtqid, data);
+	CHECK_INTCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	i_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!(p_dtqcb->p_dtqinib->dtqcnt > 0U)) {
+		ercd = E_ILUSE;
+	}
+	else if (force_send_data(p_dtqcb, data)) {
+		reqflg = true;
+	}
+	ercd = E_OK;
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IFSND_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ifsnd_dtq */
+
+/*
+ *  f[^L
+[©çÌóM
+ */
+#ifdef TOPPERS_rcv_dtq
+
+ER
+rcv_dtq(ID dtqid, intptr_t *p_data)
+{
+	DTQCB	*p_dtqcb;
+	WINFO_DTQ winfo_dtq;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_RCV_DTQ_ENTER(dtqid, p_data);
+	CHECK_DISPATCH();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (receive_data(p_dtqcb, p_data, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_RDTQ);
+		make_wait(&(winfo_dtq.winfo));
+		queue_insert_prev(&(p_dtqcb->rwait_queue), &(p_runtsk->task_queue));
+		winfo_dtq.p_dtqcb = p_dtqcb;
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo_dtq.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_data = winfo_dtq.data;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_RCV_DTQ_LEAVE(ercd, *p_data);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rcv_dtq */
+
+/*
+ *  f[^L
+[©çÌóMi|[Oj
+ */
+#ifdef TOPPERS_prcv_dtq
+
+ER
+prcv_dtq(ID dtqid, intptr_t *p_data)
+{
+	DTQCB	*p_dtqcb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_PRCV_DTQ_ENTER(dtqid, p_data);
+	CHECK_TSKCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (receive_data(p_dtqcb, p_data, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_PRCV_DTQ_LEAVE(ercd, *p_data);
+	return(ercd);
+}
+
+#endif /* TOPPERS_prcv_dtq */
+
+/*
+ *  f[^L
+[©çÌóMi^CAEg èj
+ */
+#ifdef TOPPERS_trcv_dtq
+
+ER
+trcv_dtq(ID dtqid, intptr_t *p_data, TMO tmout)
+{
+	DTQCB	*p_dtqcb;
+	WINFO_DTQ winfo_dtq;
+	TMEVTB	tmevtb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_TRCV_DTQ_ENTER(dtqid, p_data, tmout);
+	CHECK_DISPATCH();
+	CHECK_DTQID(dtqid);
+	CHECK_TMOUT(tmout);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (receive_data(p_dtqcb, p_data, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_RDTQ);
+		make_wait_tmout(&(winfo_dtq.winfo), &tmevtb, tmout);
+		queue_insert_prev(&(p_dtqcb->rwait_queue), &(p_runtsk->task_queue));
+		winfo_dtq.p_dtqcb = p_dtqcb;
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo_dtq.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_data = winfo_dtq.data;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TRCV_DTQ_LEAVE(ercd, *p_data);
+	return(ercd);
+}
+
+#endif /* TOPPERS_trcv_dtq */
+
+/*
+ *  f[^L
+[ÌÄú»
+ */
+#ifdef TOPPERS_ini_dtq
+
+ER
+ini_dtq(ID dtqid)
+{
+	DTQCB	*p_dtqcb;
+	bool_t	dspreq;
+	ER		ercd;
+    
+	LOG_INI_DTQ_ENTER(dtqid);
+	CHECK_TSKCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		dspreq = init_wait_queue(&(p_dtqcb->swait_queue));
+		if (init_wait_queue(&(p_dtqcb->rwait_queue))) {
+			dspreq = true;
+			}
+		p_dtqcb->count = 0U;
+		p_dtqcb->head = 0U;
+		p_dtqcb->tail = 0U;
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_INI_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ini_dtq */
+
+/*
+ *  f[^L
+[ÌóÔQÆ
+ */
+#ifdef TOPPERS_ref_dtq
+
+ER
+ref_dtq(ID dtqid, T_RDTQ *pk_rdtq)
+{
+	DTQCB	*p_dtqcb;
+	ER		ercd;
+    
+	LOG_REF_DTQ_ENTER(dtqid, pk_rdtq);
+	CHECK_TSKCTX_UNL();
+	CHECK_DTQID(dtqid);
+	p_dtqcb = get_dtqcb(dtqid);
+
+	t_lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		pk_rdtq->stskid = wait_tskid(&(p_dtqcb->swait_queue));
+		pk_rdtq->rtskid = wait_tskid(&(p_dtqcb->rwait_queue));
+		pk_rdtq->sdtqcnt = p_dtqcb->count;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_DTQ_LEAVE(ercd, pk_rdtq);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_dtq */
Index: UsbWattMeter/trunk/asp_dcre/kernel/dataqueue.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/dataqueue.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/dataqueue.h	(revision 164)
@@ -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-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		f[^L
+[@\
+ */
+
+#ifndef TOPPERS_DATAQUEUE_H
+#define TOPPERS_DATAQUEUE_H
+
+#include "wait.h"
+
+/*
+ *  f[^ÇubN
+ */
+typedef struct data_management_block {
+	intptr_t	data;			/* f[^{Ì */
+} DTQMB;
+
+/*
+ *  f[^L
+[ú»ubN
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌú»ubNÌ¤Êª
+ *  iWOBJINIBjðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅC
+ *  ÅÌtB[hª¤ÊÉÈÁÄ¢éD
+ */
+typedef struct dataqueue_initialization_block {
+	ATR			dtqatr;			/* f[^L
+[®« */
+	uint_t		dtqcnt;			/* f[^L
+[ÌeÊ */
+	DTQMB		*p_dtqmb;		/* f[^L
+[ÇÌæÌæªÔn */
+} DTQINIB;
+
+/*
+ *  f[^L
+[ÇubN
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌÇubNÌ¤ÊªiWOBJCBj
+ *  ðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅCÅÌ2ÂÌ
+ *  tB[hª¤ÊÉÈÁÄ¢éD
+ */
+typedef struct dataqueue_control_block {
+	QUEUE		swait_queue;	/* f[^L
+[MÒ¿L
+[ */
+	const DTQINIB *p_dtqinib;	/* ú»ubNÖÌ|C^ */
+	QUEUE		rwait_queue;	/* f[^L
+[óMÒ¿L
+[ */
+	uint_t		count;			/* f[^L
+[Ìf[^Ì */
+	uint_t		head;			/* ÅÌf[^Ìi[ê */
+	uint_t		tail;			/* ÅãÌf[^Ìi[êÌ */
+} DTQCB;
+
+/*
+ *  f[^L
+[Ò¿îñubNÌè`
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌÒ¿îñubNÌ¤Êª
+ *  iWINFO_WOBJjðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅC
+ *  ÅÌ2ÂÌtB[hª¤ÊÉÈÁÄ¢éD
+ *  f[^L
+[ÖÌMÒ¿Æf[^L
+[©çÌóMÒ¿ÅC¯¶Ò¿î
+ *  ñubNðg¤D
+ */
+typedef struct dataqueue_waiting_information {
+	WINFO		winfo;			/* WÌÒ¿îñubN */
+	DTQCB		*p_dtqcb;		/* ÒÁÄ¢éf[^L
+[ÌÇubN */
+	intptr_t	data;			/* óMf[^ */
+} WINFO_DTQ;
+
+/*
+ *  gpµÄ¢È¢f[^L
+[ÇubNÌXg
+ */
+extern QUEUE	free_dtqcb;
+
+/*
+ *  f[^L
+[IDÌÅålikernel_cfg.cj
+ */
+extern const ID	tmax_dtqid;
+extern const ID	tmax_sdtqid;
+
+/*
+ *  f[^L
+[ú»ubNÌGAikernel_cfg.cj
+ */
+extern const DTQINIB	dtqinib_table[];
+extern DTQINIB			adtqinib_table[];
+
+/*
+ *  f[^L
+[ÇubNÌGAikernel_cfg.cj
+ */
+extern DTQCB	dtqcb_table[];
+
+/*
+ *  f[^L
+[ÇubN©çf[^L
+[IDðæèo·½ßÌ}N
+ */
+#define	DTQID(p_dtqcb)	((ID)(((p_dtqcb) - dtqcb_table) + TMIN_DTQID))
+
+/*
+ *  f[^L
+[@\Ìú»
+ */
+extern void	initialize_dataqueue(void);
+
+/*
+ *  f[^L
+[ÇÌæÖÌf[^Ìi[
+ */
+extern void	enqueue_data(DTQCB *p_dtqcb, intptr_t data);
+
+/*
+ *  f[^L
+[ÇÌæÖÌf[^Ì­§i[
+ */
+extern void	force_enqueue_data(DTQCB *p_dtqcb, intptr_t data);
+
+/*
+ *  f[^L
+[ÇÌæ©çÌf[^Ìæoµ
+ */
+extern void	dequeue_data(DTQCB *p_dtqcb, intptr_t *p_data);
+
+/*
+ *  f[^L
+[ÖÌf[^M
+ */
+extern bool_t	send_data(DTQCB *p_dtqcb, intptr_t data, bool_t *p_dspreq);
+
+/*
+ *  f[^L
+[ÖÌf[^­§M
+ */
+extern bool_t	force_send_data(DTQCB *p_dtqcb, intptr_t data);
+
+/*
+ *  f[^L
+[©çÌf[^óM
+ */
+extern bool_t	receive_data(DTQCB *p_dtqcb, intptr_t *p_data,
+													bool_t *p_dspreq);
+
+#endif /* TOPPERS_DATAQUEUE_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/eventflag.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/eventflag.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/eventflag.c	(revision 164)
@@ -0,0 +1,649 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		CxgtO@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "eventflag.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_ACRE_FLG_ENTER
+#define LOG_ACRE_FLG_ENTER(pk_cflg)
+#endif /* LOG_ACRE_FLG_ENTER */
+
+#ifndef LOG_ACRE_FLG_LEAVE
+#define LOG_ACRE_FLG_LEAVE(ercd)
+#endif /* LOG_ACRE_FLG_LEAVE */
+
+#ifndef LOG_DEL_FLG_ENTER
+#define LOG_DEL_FLG_ENTER(flgid)
+#endif /* LOG_DEL_FLG_ENTER */
+
+#ifndef LOG_DEL_FLG_LEAVE
+#define LOG_DEL_FLG_LEAVE(ercd)
+#endif /* LOG_DEL_FLG_LEAVE */
+
+#ifndef LOG_SET_FLG_ENTER
+#define LOG_SET_FLG_ENTER(flgid, setptn)
+#endif /* LOG_SET_FLG_ENTER */
+
+#ifndef LOG_SET_FLG_LEAVE
+#define LOG_SET_FLG_LEAVE(ercd)
+#endif /* LOG_SET_FLG_LEAVE */
+
+#ifndef LOG_ISET_FLG_ENTER
+#define LOG_ISET_FLG_ENTER(flgid, setptn)
+#endif /* LOG_ISET_FLG_ENTER */
+
+#ifndef LOG_ISET_FLG_LEAVE
+#define LOG_ISET_FLG_LEAVE(ercd)
+#endif /* LOG_ISET_FLG_LEAVE */
+
+#ifndef LOG_CLR_FLG_ENTER
+#define LOG_CLR_FLG_ENTER(flgid, clrptn)
+#endif /* LOG_CLR_FLG_ENTER */
+
+#ifndef LOG_CLR_FLG_LEAVE
+#define LOG_CLR_FLG_LEAVE(ercd)
+#endif /* LOG_CLR_FLG_LEAVE */
+
+#ifndef LOG_WAI_FLG_ENTER
+#define LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
+#endif /* LOG_WAI_FLG_ENTER */
+
+#ifndef LOG_WAI_FLG_LEAVE
+#define LOG_WAI_FLG_LEAVE(ercd, flgptn)
+#endif /* LOG_WAI_FLG_LEAVE */
+
+#ifndef LOG_POL_FLG_ENTER
+#define LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
+#endif /* LOG_POL_FLG_ENTER */
+
+#ifndef LOG_POL_FLG_LEAVE
+#define LOG_POL_FLG_LEAVE(ercd, flgptn)
+#endif /* LOG_POL_FLG_LEAVE */
+
+#ifndef LOG_TWAI_FLG_ENTER
+#define LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout)
+#endif /* LOG_TWAI_FLG_ENTER */
+
+#ifndef LOG_TWAI_FLG_LEAVE
+#define LOG_TWAI_FLG_LEAVE(ercd, flgptn)
+#endif /* LOG_TWAI_FLG_LEAVE */
+
+#ifndef LOG_INI_FLG_ENTER
+#define LOG_INI_FLG_ENTER(flgid)
+#endif /* LOG_INI_FLG_ENTER */
+
+#ifndef LOG_INI_FLG_LEAVE
+#define LOG_INI_FLG_LEAVE(ercd)
+#endif /* LOG_INI_FLG_LEAVE */
+
+#ifndef LOG_REF_FLG_ENTER
+#define LOG_REF_FLG_ENTER(flgid, pk_rflg)
+#endif /* LOG_REF_FLG_ENTER */
+
+#ifndef LOG_REF_FLG_LEAVE
+#define LOG_REF_FLG_LEAVE(ercd, pk_rflg)
+#endif /* LOG_REF_FLG_LEAVE */
+
+/*
+ *  CxgtOÌ
+ */
+#define tnum_flg	((uint_t)(tmax_flgid - TMIN_FLGID + 1))
+#define tnum_sflg	((uint_t)(tmax_sflgid - TMIN_FLGID + 1))
+
+/*
+ *  CxgtOID©çCxgtOÇubNðæèo·½ßÌ}N
+ */
+#define INDEX_FLG(flgid)	((uint_t)((flgid) - TMIN_FLGID))
+#define get_flgcb(flgid)	(&(flgcb_table[INDEX_FLG(flgid)]))
+
+#ifdef TOPPERS_flgini
+
+/*
+ *  gpµÄ¢È¢CxgtOÇubNÌXg
+ */
+QUEUE	free_flgcb;
+
+/*
+ *  CxgtO@\Ìú»
+ */
+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 */
+
+/*
+ *  CxgtOÒ¿ððÌ`FbN
+ */
+#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 */
+
+/*
+ *  CxgtOÌ¶¬
+ */
+#ifdef TOPPERS_acre_flg
+
+ER_UINT
+acre_flg(const T_CFLG *pk_cflg)
+{
+	FLGCB	*p_flgcb;
+	FLGINIB	*p_flginib;
+	ER		ercd;
+
+	LOG_ACRE_FLG_ENTER(pk_cflg);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_cflg->flgatr, TA_TPRI|TA_WMUL|TA_CLR);
+
+	t_lock_cpu();
+	if (tnum_flg == 0 || queue_empty(&free_flgcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		p_flgcb = ((FLGCB *) queue_delete_next(&free_flgcb));
+		p_flginib = (FLGINIB *)(p_flgcb->p_flginib);
+		p_flginib->flgatr = pk_cflg->flgatr;
+		p_flginib->iflgptn = pk_cflg->iflgptn;
+
+		queue_initialize(&(p_flgcb->wait_queue));
+		p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
+		ercd = FLGID(p_flgcb);
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_FLG_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_flg */
+
+/*
+ *  CxgtOÌí
+ */
+#ifdef TOPPERS_del_flg
+
+ER
+del_flg(ID flgid)
+{
+	FLGCB	*p_flgcb;
+	FLGINIB	*p_flginib;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_DEL_FLG_ENTER(flgid);
+	CHECK_TSKCTX_UNL();
+	CHECK_FLGID(flgid);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (FLGID(p_flgcb) > tmax_sflgid) {
+		dspreq = init_wait_queue(&(p_flgcb->wait_queue));
+		p_flginib = (FLGINIB *)(p_flgcb->p_flginib);
+		p_flginib->flgatr = TA_NOEXS;
+		queue_insert_prev(&free_flgcb, &(p_flgcb->wait_queue));
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_FLG_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_flg */
+
+/*
+ *  CxgtOÌZbg
+ */
+#ifdef TOPPERS_set_flg
+
+ER
+set_flg(ID flgid, FLGPTN setptn)
+{
+	FLGCB	*p_flgcb;
+	QUEUE	*p_queue;
+	TCB		*p_tcb;
+	WINFO_FLG *p_winfo_flg;
+	bool_t	dspreq = false;
+	ER		ercd;
+
+	LOG_SET_FLG_ENTER(flgid, setptn);
+	CHECK_TSKCTX_UNL();
+	CHECK_FLGID(flgid);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		p_flgcb->flgptn |= setptn;
+		p_queue = p_flgcb->wait_queue.p_next;
+		while (p_queue != &(p_flgcb->wait_queue)) {
+			p_tcb = (TCB *) p_queue;
+			p_queue = p_queue->p_next;
+			p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
+			if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
+							p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
+				queue_delete(&(p_tcb->task_queue));
+				if (wait_complete(p_tcb)) {
+					dspreq = true;
+				}
+				if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
+					break;
+				}
+			}
+		}
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_SET_FLG_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_set_flg */
+
+/*
+ *  CxgtOÌZbgiñ^XNReLXgpj
+ */
+#ifdef TOPPERS_iset_flg
+
+ER
+iset_flg(ID flgid, FLGPTN setptn)
+{
+	FLGCB	*p_flgcb;
+	QUEUE	*p_queue;
+	TCB		*p_tcb;
+	WINFO_FLG *p_winfo_flg;
+	ER		ercd;
+
+	LOG_ISET_FLG_ENTER(flgid, setptn);
+	CHECK_INTCTX_UNL();
+	CHECK_FLGID(flgid);
+	p_flgcb = get_flgcb(flgid);
+
+	i_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		p_flgcb->flgptn |= setptn;
+		p_queue = p_flgcb->wait_queue.p_next;
+		while (p_queue != &(p_flgcb->wait_queue)) {
+			p_tcb = (TCB *) p_queue;
+			p_queue = p_queue->p_next;
+			p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
+			if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
+							p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
+				queue_delete(&(p_tcb->task_queue));
+				if (wait_complete(p_tcb)) {
+					reqflg = true;
+				}
+				if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
+					break;
+				}
+			}
+		}
+		ercd = E_OK;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_ISET_FLG_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_iset_flg */
+
+/*
+ *  CxgtOÌNA
+ */
+#ifdef TOPPERS_clr_flg
+
+ER
+clr_flg(ID flgid, FLGPTN clrptn)
+{
+	FLGCB	*p_flgcb;
+	ER		ercd;
+
+	LOG_CLR_FLG_ENTER(flgid, clrptn);
+	CHECK_TSKCTX_UNL();
+	CHECK_FLGID(flgid);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		p_flgcb->flgptn &= clrptn; 
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_CLR_FLG_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_clr_flg */
+
+/*
+ *  CxgtOÒ¿
+ */
+#ifdef TOPPERS_wai_flg
+
+ER
+wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
+{
+	FLGCB	*p_flgcb;
+	WINFO_FLG winfo_flg;
+	ER		ercd;
+
+	LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
+	CHECK_DISPATCH();
+	CHECK_FLGID(flgid);
+	CHECK_PAR(waiptn != 0U);
+	CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
+					&& !queue_empty(&(p_flgcb->wait_queue))) {
+		ercd = E_ILUSE;
+	}
+	else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
+		ercd = E_OK;
+	}
+	else {
+		winfo_flg.waiptn = waiptn;
+		winfo_flg.wfmode = wfmode;
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
+		wobj_make_wait((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg);
+		dispatch();
+		ercd = winfo_flg.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_flgptn = winfo_flg.flgptn;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_WAI_FLG_LEAVE(ercd, *p_flgptn);
+	return(ercd);
+}
+
+#endif /* TOPPERS_wai_flg */
+
+/*
+ *  CxgtOÒ¿i|[Oj
+ */
+#ifdef TOPPERS_pol_flg
+
+ER
+pol_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
+{
+	FLGCB	*p_flgcb;
+	ER		ercd;
+
+	LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
+	CHECK_TSKCTX_UNL();
+	CHECK_FLGID(flgid);
+	CHECK_PAR(waiptn != 0U);
+	CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
+					&& !queue_empty(&(p_flgcb->wait_queue))) {
+		ercd = E_ILUSE;
+	}
+	else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_POL_FLG_LEAVE(ercd, *p_flgptn);
+	return(ercd);
+}
+
+#endif /* TOPPERS_pol_flg */
+
+/*
+ *  CxgtOÒ¿i^CAEg èj
+ */
+#ifdef TOPPERS_twai_flg
+
+ER
+twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
+{
+	FLGCB	*p_flgcb;
+	WINFO_FLG winfo_flg;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout);
+	CHECK_DISPATCH();
+	CHECK_FLGID(flgid);
+	CHECK_PAR(waiptn != 0U);
+	CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
+	CHECK_TMOUT(tmout);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
+					&& !queue_empty(&(p_flgcb->wait_queue))) {
+		ercd = E_ILUSE;
+	}
+	else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		winfo_flg.waiptn = waiptn;
+		winfo_flg.wfmode = wfmode;
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
+		wobj_make_wait_tmout((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_flg.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_flgptn = winfo_flg.flgptn;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TWAI_FLG_LEAVE(ercd, *p_flgptn);
+	return(ercd);
+}
+
+#endif /* TOPPERS_twai_flg */
+
+/*
+ *  CxgtOÌÄú»
+ */
+#ifdef TOPPERS_ini_flg
+
+ER
+ini_flg(ID flgid)
+{
+	FLGCB	*p_flgcb;
+	bool_t	dspreq;
+	ER		ercd;
+    
+	LOG_INI_FLG_ENTER(flgid);
+	CHECK_TSKCTX_UNL();
+	CHECK_FLGID(flgid);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		dspreq = init_wait_queue(&(p_flgcb->wait_queue));
+		p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_INI_FLG_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ini_flg */
+
+/*
+ *  CxgtOÌóÔQÆ
+ */
+#ifdef TOPPERS_ref_flg
+
+ER
+ref_flg(ID flgid, T_RFLG *pk_rflg)
+{
+	FLGCB	*p_flgcb;
+	ER		ercd;
+    
+	LOG_REF_FLG_ENTER(flgid, pk_rflg);
+	CHECK_TSKCTX_UNL();
+	CHECK_FLGID(flgid);
+	p_flgcb = get_flgcb(flgid);
+
+	t_lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		pk_rflg->wtskid = wait_tskid(&(p_flgcb->wait_queue));
+		pk_rflg->flgptn = p_flgcb->flgptn;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_FLG_LEAVE(ercd, pk_rflg);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_flg */
Index: UsbWattMeter/trunk/asp_dcre/kernel/eventflag.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/eventflag.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/eventflag.h	(revision 164)
@@ -0,0 +1,138 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		CxgtO@\
+ */
+
+#ifndef TOPPERS_EVENTFLAG_H
+#define TOPPERS_EVENTFLAG_H
+
+#include "wait.h"
+
+/*
+ *  CxgtOú»ubN
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌú»ubNÌ¤Êª
+ *  iWOBJINIBjðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅC
+ *  ÅÌtB[hª¤ÊÉÈÁÄ¢éD
+ */
+typedef struct eventflag_initialization_block {
+	ATR			flgatr;			/* CxgtO®« */
+	FLGPTN		iflgptn;		/* CxgtOÌrbgp^[Ìúl */
+} FLGINIB;
+
+/*
+ *  CxgtOÇubN
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌÇubNÌ¤ÊªiWOBJCBj
+ *  ðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅCÅÌ2ÂÌ
+ *  tB[hª¤ÊÉÈÁÄ¢éD
+ */
+typedef struct eventflag_control_block {
+	QUEUE		wait_queue;		/* CxgtOÒ¿L
+[ */
+	const FLGINIB *p_flginib;	/* ú»ubNÖÌ|C^ */
+	FLGPTN		flgptn;			/* CxgtO»Ýp^[ */
+} FLGCB;
+
+/*
+ *  CxgtOÒ¿îñubNÌè`
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌÒ¿îñubNÌ¤Êª
+ *  iWINFO_WOBJjðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅC
+ *  ÅÌ2ÂÌtB[hª¤ÊÉÈÁÄ¢éD
+ *
+ *  flgptnÍCwaiptn¨æÑwfmodeÆ¯Ég¤±ÆÍÈ¢½ßC¤pÌðg
+ *  ¦Îðßñ·é±ÆªÂ\Å éD
+ */
+typedef struct eventflag_waiting_information {
+	WINFO		winfo;			/* WÌÒ¿îñubN */
+	FLGCB		*p_flgcb;		/* ÒÁÄ¢éCxgtOÌÇubN */
+	FLGPTN		waiptn;			/* Ò¿p^[ */
+	MODE		wfmode;			/* Ò¿[h */
+	FLGPTN		flgptn;			/* Ò¿ðÌp^[ */
+} WINFO_FLG;
+
+/*
+ *  gpµÄ¢È¢CxgtOÇubNÌXg
+ */
+extern QUEUE	free_flgcb;
+
+/*
+ *  CxgtOIDÌÅålikernel_cfg.cj
+ */
+extern const ID	tmax_flgid;
+extern const ID	tmax_sflgid;
+
+/*
+ *  CxgtOú»ubNÌGAikernel_cfg.cj
+ */
+extern const FLGINIB	flginib_table[];
+extern FLGINIB			aflginib_table[];
+
+/*
+ *  CxgtOÇubNÌGAikernel_cfg.cj
+ */
+extern FLGCB	flgcb_table[];
+
+/*
+ *  CxgtOÇubN©çCxgtOIDðæèo·½ßÌ}N
+ */
+#define	FLGID(p_flgcb)	((ID)(((p_flgcb) - flgcb_table) + TMIN_FLGID))
+
+/*
+ *  CxgtO@\Ìú»
+ */
+extern void	initialize_eventflag(void);
+
+/*
+ *  CxgtOÒ¿ððÌ`FbN
+ */
+extern bool_t	check_flg_cond(FLGCB *p_flgcb, FLGPTN waiptn,
+								MODE wfmode, FLGPTN *p_flgptn);
+
+#endif /* TOPPERS_EVENTFLAG_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/exception.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/exception.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/exception.c	(revision 164)
@@ -0,0 +1,139 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		CPUáOÇ@\
+ */
+
+#include "kernel_impl.h"
+#include "task.h"
+#include "exception.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_XSNS_DPN_ENTER
+#define LOG_XSNS_DPN_ENTER(p_excinf)
+#endif /* LOG_XSNS_DPN_ENTER */
+
+#ifndef LOG_XSNS_DPN_LEAVE
+#define LOG_XSNS_DPN_LEAVE(state)
+#endif /* LOG_XSNS_DPN_LEAVE */
+
+#ifndef LOG_XSNS_XPN_ENTER
+#define LOG_XSNS_XPN_ENTER(p_excinf)
+#endif /* LOG_XSNS_XPN_ENTER */
+
+#ifndef LOG_XSNS_XPN_LEAVE
+#define LOG_XSNS_XPN_LEAVE(state)
+#endif /* LOG_XSNS_XPN_LEAVE */
+
+/* 
+ *  CPUáOnhÇ@\Ìú»
+ */
+#ifdef TOPPERS_excini
+#ifndef OMIT_INITIALIZE_EXCEPTION
+
+void
+initialize_exception(void)
+{
+	uint_t			i;
+	const EXCINIB	*p_excinib;
+
+	for (p_excinib = excinib_table, i = 0; i < tnum_excno; p_excinib++, i++) {
+		x_define_exc(p_excinib->excno, p_excinib->exc_entry);
+	}
+}
+
+#endif /* OMIT_INITIALIZE_EXCEPTION */
+#endif /* TOPPERS_excini */
+
+/*
+ *  CPUáOÌ­¶µ½ReLXgÌQÆ
+ */
+
+/*
+ *  CPUáO­¶ÌfBXpb`Û¯óÔÌQÆ
+ *
+ *  CPUáOnhÅdisdspªÏ»·é±ÆÍÈ¢½ßCCPUáOª­¶µ
+ *  ½ÌdisdspðÛ¶µÄ¨­KvÍÈ¢D
+ */
+#ifdef TOPPERS_xsns_dpn
+
+bool_t
+xsns_dpn(void *p_excinf)
+{
+	bool_t	state;
+
+	LOG_XSNS_DPN_ENTER(p_excinf);
+	state = (exc_sense_intmask(p_excinf) && !disdsp) ? false : true;
+	LOG_XSNS_DPN_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_xsns_dpn */
+
+/*
+ *  CPUáO­¶Ì^XNáOÛ¯óÔÌQÆ
+ *
+ *  CPUáOnhÅp_runtskÆp_runtsk->enatexªÏ»·é±ÆÍÈ¢
+ *  ½ßCCPUáOª­¶µ½Ìp_runtsk->enatexðÛ¶µÄ¨­KvÍÈ
+ *  ¢D
+ */
+#ifdef TOPPERS_xsns_xpn
+
+bool_t
+xsns_xpn(void *p_excinf)
+{
+	bool_t	state;
+
+	LOG_XSNS_XPN_ENTER(p_excinf);
+	state = (exc_sense_intmask(p_excinf) && p_runtsk->enatex) ? false : true;
+	LOG_XSNS_XPN_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_xsns_xpn */
Index: UsbWattMeter/trunk/asp_dcre/kernel/exception.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/exception.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/exception.h	(revision 164)
@@ -0,0 +1,82 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		CPUáOÇ@\
+ */
+
+#ifndef TOPPERS_EXCEPTION_H
+#define TOPPERS_EXCEPTION_H
+
+#ifndef OMIT_INITIALIZE_EXCEPTION
+
+/*
+ *  CPUáOnhú»ubN
+ */
+typedef struct cpu_exception_handler_initialization_block {
+	EXCNO		excno;			/* CPUáOnhÔ */
+	ATR			excatr;			/* CPUáOnh®« */
+	FP			exc_entry;		/* CPUáOnhÌoüûÌÔn */
+} EXCINIB;
+
+/*
+ *  CPUáOnhÔÌikernel_cfg.cj
+ */
+extern const uint_t	tnum_excno;
+
+/*
+ *  CPUáOnhú»ubNÌGAikernel_cfg.cj
+ */
+extern const EXCINIB	excinib_table[];
+
+#endif /* OMIT_INITIALIZE_EXCEPTION */
+
+/*
+ *  CPUáOnhÇ@\Ìú»
+ */
+extern void	initialize_exception(void);
+
+#endif /* TOPPERS_EXCEPTION_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/genoffset.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/genoffset.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/genoffset.tf	(revision 164)
@@ -0,0 +1,150 @@
+$ ======================================================================
+$ 
+$   TOPPERS/ASP Kernel
+$       Toyohashi Open Platform for Embedded Real-Time Systems/
+$       Advanced Standard Profile Kernel
+$ 
+$   Copyright (C) 2011 by Embedded and Real-Time Systems Laboratory
+$               Graduate School of Information Science, Nagoya Univ., JAPAN
+$  
+$   ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$   Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$   ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$   (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$        \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$       XR[hÉÜÜêÄ¢é±ÆD
+$   (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$       pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$       Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$       Ì³ÛØKèðfÚ·é±ÆD
+$   (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$       pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$       ÆD
+$     (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$         ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$     (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$         ñ·é±ÆD
+$   (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$       Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$       Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$       RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$       ÆÓ·é±ÆD
+$  
+$   {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$   æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$   ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$   AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$   ÌÓCðíÈ¢D
+$ 
+$   $Id$
+$ 
+$ =====================================================================
+
+$ 
+$  #definefBNeBuÌ¶¬
+$ 
+$FUNCTION DEFINE$
+	#define $ARGV[1]$$TAB$$FORMAT("%d", +ARGV[2])$$NL$
+$END$
+
+$ 
+$  rbgÌT[`
+$ 
+$FUNCTION SEARCH_BIT$
+	$_val = ARGV[1]$
+	$FOREACH _val_bit RANGE(0,7)$
+		$IF (_val & 1) != 0$
+			$RESULT = _val_bit$
+		$END$
+		$_val = _val >> 1$
+	$END$
+$END$
+
+$ 
+$  rbgtB[hÌItZbgÆrbgÊuÌè`Ì¶¬
+$ 
+$FUNCTION DEFINE_BIT$
+	$label = ARGV[1]$
+	$struct_size = ARGV[2]$
+	$output_size = ARGV[3]$
+
+	$top = SYMBOL(label)$
+	$IF !LENGTH(top)$
+		$ERROR$$FORMAT("label %1% not found", label)$$END$
+	$ELSE$
+		$val = 0$
+		$FOREACH i RANGE(0,struct_size-1)$
+			$tmp_val = PEEK(top + i, 1)$
+			$IF val == 0 && tmp_val != 0$
+				$val = tmp_val$
+				$offset = i$
+			$END$
+		$END$
+
+		$IF val == 0$
+			$ERROR$$FORMAT("bit not found in %1%", ARGV[1])$$END$
+		$ELSE$
+			$val_bit = SEARCH_BIT(val)$
+			$RESULT = {}$
+			$IF EQ(output_size, "W")$
+				$IF SIL_ENDIAN_BIG$
+					$val_bit = val_bit + 24 - ((offset & 0x03) << 3)$
+				$ELSE$
+					$val_bit = val_bit + ((offset & 0x03) << 3)$
+				$END$
+				$offset = offset & ~0x03$
+			$ELSE$$IF EQ(output_size, "H")$
+				$IF SIL_ENDIAN_BIG$
+					$val_bit = val_bit + 8 - ((offset & 0x01) << 3)$
+				$ELSE$
+					$val_bit = val_bit + ((offset & 0x01) << 3)$
+				$END$
+				$offset = offset & ~0x01$
+			$END$$END$
+		$END$
+
+		#define $label$$TAB$$FORMAT("%d", +offset)$$NL$
+		#define $label$_bit$TAB$$FORMAT("%d", +val_bit)$$NL$
+		#define $label$_mask$TAB$$FORMAT("0x%x", 1 << val_bit)$$NL$
+	$END$
+$END$
+
+$ 
+$  oCgzuÌ`FbN
+$ 
+$FUNCTION MAGIC_CHECK$
+	$size = ARGV[1]$
+	$check = ARGV[2]$
+
+	$label = FORMAT("MAGIC_%d", +size)$
+	$top = SYMBOL(label)$
+	$IF !LENGTH(top)$
+		$ERROR$$FORMAT("label %1% not found", label)$$END$
+	$ELSE$
+		$FOREACH offset RANGE(1,size)$
+			$IF SIL_ENDIAN_BIG$
+				$val = PEEK(top + offset - 1, 1)$
+			$ELSE$
+				$val = PEEK(top + size - offset, 1)$
+			$END$
+			$IF val != AT(check, offset - 1)$
+				$ERROR$$FORMAT("value check of %1% failed", label)$$END$
+			$END$
+		$END$
+	$END$
+$END$
+
+$MAGIC_CHECK(1, { 0x12 })$
+$MAGIC_CHECK(2, { 0x12, 0x34 })$
+$MAGIC_CHECK(4, { 0x12, 0x34, 0x56, 0x78 })$
+
+$ 
+$  t@Cwb_Ì¶¬
+$ 
+$FILE "offset.h"$
+/* offset.h */$NL$
+$NL$
Index: UsbWattMeter/trunk/asp_dcre/kernel/interrupt.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/interrupt.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/interrupt.c	(revision 164)
@@ -0,0 +1,500 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ÝÇ@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "interrupt.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_ISR_ENTER
+#define LOG_ISR_ENTER(intno)
+#endif /* LOG_ISR_ENTER */
+
+#ifndef LOG_ISR_LEAVE
+#define LOG_ISR_LEAVE(intno)
+#endif /* LOG_ISR_LEAVE */
+
+#ifndef LOG_ACRE_ISR_ENTER
+#define LOG_ACRE_ISR_ENTER(pk_cisr)
+#endif /* LOG_ACRE_ISR_ENTER */
+
+#ifndef LOG_ACRE_ISR_LEAVE
+#define LOG_ACRE_ISR_LEAVE(ercd)
+#endif /* LOG_ACRE_ISR_LEAVE */
+
+#ifndef LOG_DEL_ISR_ENTER
+#define LOG_DEL_ISR_ENTER(isrid)
+#endif /* LOG_DEL_ISR_ENTER */
+
+#ifndef LOG_DEL_ISR_LEAVE
+#define LOG_DEL_ISR_LEAVE(ercd)
+#endif /* LOG_DEL_ISR_LEAVE */
+
+#ifndef LOG_DIS_INT_ENTER
+#define LOG_DIS_INT_ENTER(intno)
+#endif /* LOG_DIS_INT_ENTER */
+
+#ifndef LOG_DIS_INT_LEAVE
+#define LOG_DIS_INT_LEAVE(ercd)
+#endif /* LOG_DIS_INT_LEAVE */
+
+#ifndef LOG_ENA_INT_ENTER
+#define LOG_ENA_INT_ENTER(intno)
+#endif /* LOG_ENA_INT_ENTER */
+
+#ifndef LOG_ENA_INT_LEAVE
+#define LOG_ENA_INT_LEAVE(ercd)
+#endif /* LOG_ENA_INT_LEAVE */
+
+#ifndef LOG_CHG_IPM_ENTER
+#define LOG_CHG_IPM_ENTER(intpri)
+#endif /* LOG_CHG_IPM_ENTER */
+
+#ifndef LOG_CHG_IPM_LEAVE
+#define LOG_CHG_IPM_LEAVE(ercd)
+#endif /* LOG_CHG_IPM_LEAVE */
+
+#ifndef LOG_GET_IPM_ENTER
+#define LOG_GET_IPM_ENTER(p_intpri)
+#endif /* LOG_GET_IPM_ENTER */
+
+#ifndef LOG_GET_IPM_LEAVE
+#define LOG_GET_IPM_LEAVE(ercd, intpri)
+#endif /* LOG_GET_IPM_LEAVE */
+
+/*
+ *  ÝT[rX[`Ì
+ */
+#define tnum_isr	((uint_t)(tmax_isrid - TMIN_SEMID + 1) + tnum_sisr)
+
+/*
+ *  ÝT[rX[`ID©çÝT[rX[`ÇubNðæ
+ *  èo·½ßÌ}N
+ */
+#define INDEX_ISR(isrid)	((uint_t)((isrid) - TMIN_ISRID) + tnum_sisr)
+#define get_isrcb(isrid)	(&(isrcb_table[INDEX_ISR(isrid)]))
+
+/*
+ *  ÝT[rX[`L
+[ÖÌo^
+ */
+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
+
+/*
+ *  gpµÄ¢È¢ÝT[rX[`ÇubNÌXg
+ */
+QUEUE	free_isrcb;
+
+/* 
+ *  ÝT[rX[`@\Ìú»
+ */
+void
+initialize_isr(void)
+{
+	uint_t	i, j;
+	ISRCB	*p_isrcb;
+	ISRINIB	*p_isrinib;
+
+	for (i = 0; i < tnum_isr_queue; i++) {
+		queue_initialize(&(isr_queue_table[i]));
+	}
+	for (i = 0; i < tnum_sisr; i++) {
+		p_isrcb = &(isrcb_table[i]);
+		p_isrcb->p_isrinib = &(sisrinib_table[i]);
+		enqueue_isr(p_isrcb->p_isrinib->p_isr_queue, p_isrcb);
+	}
+	queue_initialize(&free_isrcb);
+	for (j = 0; i < tnum_isr; i++, j++) {
+		p_isrcb = &(isrcb_table[i]);
+		p_isrinib = &(aisrinib_table[j]);
+		p_isrinib->isratr = TA_NOEXS;
+		p_isrcb->p_isrinib = ((const ISRINIB *) p_isrinib);
+		queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
+	}
+}
+
+#endif /* TOPPERS_isrini */
+
+/*
+ *  ÝT[rX[`ÌÄoµ
+ */
+#ifdef TOPPERS_isrcal
+
+void
+call_isr(QUEUE *p_isr_queue)
+{
+	QUEUE	*p_queue;
+	ISRINIB	*p_isrinib;
+	PRI		saved_ipm;
+
+	saved_ipm = i_get_ipm();
+	for (p_queue = p_isr_queue->p_next; p_queue != p_isr_queue;
+											p_queue = p_queue->p_next) {
+		p_isrinib = (ISRINIB *)(((ISRCB *) p_queue)->p_isrinib);
+		LOG_ISR_ENTER(p_isrinib->intno);
+		(*(p_isrinib->isr))(p_isrinib->exinf);
+		LOG_ISR_LEAVE(p_isrinib->intno);
+
+		if (p_queue->p_next != p_isr_queue) {
+			/* ISRÌÄoµOÌóÔÉß· */
+			if (i_sense_lock()) {
+				i_unlock_cpu();
+			}
+			i_set_ipm(saved_ipm);
+		}
+	}
+}
+
+#endif /* TOPPERS_isrcal */
+
+/*
+ *  ÝT[rX[`ÄoµL
+[Ìõ
+ */
+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);
+	}
+}
+
+/*
+ *  ÝT[rX[`Ì¶¬
+ */
+#ifdef TOPPERS_acre_isr
+
+ER_UINT
+acre_isr(const T_CISR *pk_cisr)
+{
+	ISRCB	*p_isrcb;
+	ISRINIB	*p_isrinib;
+	QUEUE	*p_isr_queue;
+	ER		ercd;
+
+	LOG_ACRE_ISR_ENTER(pk_cisr);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_cisr->isratr, TARGET_ISRATR);
+	CHECK_INTNO_CREISR(pk_cisr->intno);
+	CHECK_ALIGN_FUNC(pk_cisr->isr);
+	CHECK_NONNULL_FUNC(pk_cisr->isr);
+	CHECK_ISRPRI(pk_cisr->isrpri);
+
+	p_isr_queue = search_isr_queue(pk_cisr->intno);
+	CHECK_OBJ(p_isr_queue != NULL);
+
+	t_lock_cpu();
+	if (tnum_isr == 0 || queue_empty(&free_isrcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		p_isrcb = ((ISRCB *) queue_delete_next(&free_isrcb));
+		p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
+		p_isrinib->isratr = pk_cisr->isratr;
+		p_isrinib->exinf = pk_cisr->exinf;
+		p_isrinib->intno = pk_cisr->intno;
+		p_isrinib->p_isr_queue = p_isr_queue;
+		p_isrinib->isr = pk_cisr->isr;
+		p_isrinib->isrpri = pk_cisr->isrpri;
+		enqueue_isr(p_isr_queue, p_isrcb);
+		ercd = ISRID(p_isrcb);
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_ISR_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_isr */
+
+/*
+ *  ÝT[rX[`Ìí
+ */
+#ifdef TOPPERS_del_isr
+
+ER
+del_isr(ID isrid)
+{
+	ISRCB	*p_isrcb;
+	ISRINIB	*p_isrinib;
+	ER		ercd;
+
+	LOG_DEL_ISR_ENTER(isrid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ISRID(isrid);
+	p_isrcb = get_isrcb(isrid);
+
+	t_lock_cpu();
+	if (p_isrcb->p_isrinib->isratr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		queue_delete(&(p_isrcb->isr_queue));
+		p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
+		p_isrinib->isratr = TA_NOEXS;
+		queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_ISR_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_isr */
+
+/* 
+ *  ÝÇ@\Ìú»
+ */
+#ifdef TOPPERS_intini
+#ifndef OMIT_INITIALIZE_INTERRUPT
+
+void
+initialize_interrupt(void)
+{
+	uint_t			i;
+	const INHINIB	*p_inhinib;
+	const INTINIB	*p_intinib;
+
+	for (i = 0; i < tnum_inhno; i++) {
+		p_inhinib = &(inhinib_table[i]);
+		x_define_inh(p_inhinib->inhno, p_inhinib->int_entry);
+	}
+	for (i = 0; i < tnum_intno; i++) {
+		p_intinib = &(intinib_table[i]);
+		x_config_int(p_intinib->intno, p_intinib->intatr, p_intinib->intpri);
+	}
+}
+
+#endif /* OMIT_INITIALIZE_INTERRUPT */
+#endif /* TOPPERS_intini */
+
+/*
+ *  ÝÌÖ~
+ */
+#ifdef TOPPERS_dis_int
+#ifdef TOPPERS_SUPPORT_DIS_INT
+
+ER
+dis_int(INTNO intno)
+{
+	bool_t	locked;
+	ER		ercd;
+
+	LOG_DIS_INT_ENTER(intno);
+	CHECK_TSKCTX();
+	CHECK_INTNO_DISINT(intno);
+
+	locked = t_sense_lock();
+	if (!locked) {
+		t_lock_cpu();
+	}
+	if (t_disable_int(intno)) {
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	if (!locked) {
+		t_unlock_cpu();
+	}
+
+  error_exit:
+	LOG_DIS_INT_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_SUPPORT_DIS_INT */
+#endif /* TOPPERS_dis_int */
+
+/*
+ *  ÝÌÂ
+ */
+#ifdef TOPPERS_ena_int
+#ifdef TOPPERS_SUPPORT_ENA_INT
+
+ER
+ena_int(INTNO intno)
+{
+	bool_t	locked;
+	ER		ercd;
+
+	LOG_ENA_INT_ENTER(intno);
+	CHECK_TSKCTX();
+	CHECK_INTNO_DISINT(intno);
+
+	locked = t_sense_lock();
+	if (!locked) {
+		t_lock_cpu();
+	}
+	if (t_enable_int(intno)) {
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	if (!locked) {
+		t_unlock_cpu();
+	}
+
+  error_exit:
+	LOG_ENA_INT_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_SUPPORT_ENA_INT */
+#endif /* TOPPERS_ena_int */
+
+/*
+ *  ÝDæx}XNÌÏX
+ */
+#ifdef TOPPERS_chg_ipm
+
+ER
+chg_ipm(PRI intpri)
+{
+	ER		ercd;
+
+	LOG_CHG_IPM_ENTER(intpri);
+	CHECK_TSKCTX_UNL();
+	CHECK_INTPRI_CHGIPM(intpri);
+
+	t_lock_cpu();
+	t_set_ipm(intpri);
+	if (intpri == TIPM_ENAALL) {
+		ipmflg = true;
+		if (!disdsp) {
+			dspflg = true;
+			if (p_runtsk != p_schedtsk) {
+				dispatch();
+			}
+		}
+		if (p_runtsk->enatex && p_runtsk->texptn != 0U) {
+			call_texrtn();
+		}
+	}
+	else {
+		ipmflg = false;
+		dspflg = false;
+	}
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_CHG_IPM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_chg_ipm */
+
+/*
+ *  ÝDæx}XNÌQÆ
+ */
+#ifdef TOPPERS_get_ipm
+
+ER
+get_ipm(PRI *p_intpri)
+{
+	ER		ercd;
+
+	LOG_GET_IPM_ENTER(p_intpri);
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	*p_intpri = t_get_ipm();
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_GET_IPM_LEAVE(ercd, *p_intpri);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_ipm */
Index: UsbWattMeter/trunk/asp_dcre/kernel/interrupt.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/interrupt.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/interrupt.h	(revision 164)
@@ -0,0 +1,195 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ÝÇ@\
+ */
+
+#ifndef TOPPERS_INTERRUPT_H
+#define TOPPERS_INTERRUPT_H
+
+/*
+ *  ÝT[rX[`ú»ubN
+ */
+typedef struct isr_initialization_block {
+	ATR			isratr;			/* ÝT[rX[`®« */
+	intptr_t	exinf;			/* ÝT[rX[`Ìg£îñ */
+	INTNO		intno;			/* ÝT[rX[`ðo^·éÝÔ */
+	QUEUE		*p_isr_queue;	/* o^æÝT[rX[`L
+[ÌÔn */
+	ISR			isr;			/* ÝT[rX[`ÌæªÔn */
+	PRI			isrpri;			/* ÝT[rX[`Dæx */
+} ISRINIB;
+
+/*
+ *  ÝT[rX[`ÇubN
+ */
+typedef struct isr_control_block {
+	QUEUE		isr_queue;		/* ÝT[rX[`ÄoµL
+[ */
+	const ISRINIB *p_isrinib;	/* ú»ubNÖÌ|C^ */
+} ISRCB;
+
+/*
+ *  ÝT[rX[`ÄoµL
+[ðõ·é½ßÌf[^\¢
+ */
+typedef struct {
+	INTNO		intno;			/* ÝÔ */
+	QUEUE		*p_isr_queue;	/* ÝT[rX[`ÄoµL
+[ */
+} ISR_ENTRY;
+
+/*
+ *  ÝT[rX[`L
+[ÌGgikernel_cfg.cj
+ */
+extern const uint_t tnum_isr_queue;
+
+/*
+ *  ÝT[rX[`L
+[Xgikernel_cfg.cj
+ */
+extern const ISR_ENTRY isr_queue_list[];
+
+/*
+ *  ÝT[rX[`L
+[ÌGAikernel_cfg.cj
+ */
+extern QUEUE isr_queue_table[];
+
+/*
+ *  gpµÄ¢È¢ÝT[rX[`ÇubNÌXg
+ */
+extern QUEUE	free_isrcb;
+
+/*
+ *  ÝT[rX[`IDÌÅålikernel_cfg.cj
+ *
+ *  ÃIÉ¶¬³êéÝT[rX[`ÍIDÔð½È¢½ßC
+ *  tmax_isridÍ®IÉ¶¬³êéÝT[rX[`ÌIDÔÌÅål
+ *  Å éDÃIÉ¶¬³êéÝT[rX[`ÌÍCtnum_sisrÉÛ
+ *  ·éD
+ */
+extern const ID		tmax_isrid;
+extern const uint_t	tnum_sisr;
+
+/*
+ *  ÝT[rX[`ú»ubNÌGAikernel_cfg.cj
+ */
+extern const ISRINIB	sisrinib_table[];
+extern ISRINIB			aisrinib_table[];
+
+/*
+ *  ÝT[rX[`ÇubNÌGAikernel_cfg.cj
+ */
+extern ISRCB	isrcb_table[];
+
+/*
+ *  ÝT[rX[`ÇubN©çÝT[rX[`IDðæ
+ *  èo·½ßÌ}N
+ */
+#define	ISRID(p_isrcb)	((ID)(((p_isrcb) - isrcb_table) \
+										- tnum_sisr + TMIN_ISRID))
+
+/*
+ *  ÝT[rX[`@\Ìú»
+ */
+extern void initialize_isr(void);
+
+/*
+ *  ÝT[rX[`ÌÄoµ
+ */
+extern void call_isr(QUEUE *p_isr_queue);
+
+#ifndef OMIT_INITIALIZE_INTERRUPT
+
+/*
+ *  Ýnhú»ubN
+ */
+typedef struct interrupt_handler_initialization_block {
+	INHNO		inhno;			/* ÝnhÔ */
+	ATR			inhatr;			/* Ýnh®« */
+	FP			int_entry;		/* ÝnhÌoüûÌÔn */
+} INHINIB;
+
+/*
+ *  ÝvCú»ubN
+ */
+typedef struct interrupt_request_initialization_block {
+	INTNO		intno;			/* ÝÔ */
+	ATR			intatr;			/* Ý®« */
+	PRI			intpri;			/* ÝDæx */
+} INTINIB;
+
+/*
+ *  ÝnhÔÌikernel_cfg.cj
+ */
+extern const uint_t	tnum_inhno;
+
+/*
+ *  Ýnhú»ubNÌGAikernel_cfg.cj
+ */
+extern const INHINIB	inhinib_table[];
+
+/*
+ *  ÝvCÌikernel_cfg.cj
+ */
+extern const uint_t	tnum_intno;
+
+/*
+ *  ÝvCú»ubNÌGAikernel_cfg.cj
+ */
+extern const INTINIB	intinib_table[];
+
+#endif /* OMIT_INITIALIZE_INTERRUPT */
+
+/*
+ *  ÝÇ@\Ìú»
+ */
+extern void	initialize_interrupt(void);
+
+#endif /* TOPPERS_INTERRUPT_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/kernel.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/kernel.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/kernel.tf	(revision 164)
@@ -0,0 +1,1436 @@
+$ ======================================================================
+$ 
+$   TOPPERS/ASP Kernel
+$       Toyohashi Open Platform for Embedded Real-Time Systems/
+$       Advanced Standard Profile Kernel
+$ 
+$   Copyright (C) 2007 by TAKAGI Nobuhisa
+$   Copyright (C) 2007-2014 by Embedded and Real-Time Systems Laboratory
+$               Graduate School of Information Science, Nagoya Univ., JAPAN
+$  
+$   ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$   Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$   ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$   (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$        \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$       XR[hÉÜÜêÄ¢é±ÆD
+$   (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$       pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$       Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$       Ì³ÛØKèðfÚ·é±ÆD
+$   (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$       pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$       ÆD
+$     (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$         ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$     (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$         ñ·é±ÆD
+$   (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$       Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$       Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$       RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$       ÆÓ·é±ÆD
+$  
+$   {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$   æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$   ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$   AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$   ÌÓCðíÈ¢D
+$ 
+$   $Id$
+$  
+$ =====================================================================
+
+$ =====================================================================
+$ AID_YYYÌ
+$ =====================================================================
+
+$num_atskid = 0$
+$FOREACH i ATSK.ORDER_LIST$
+$	// notskªÌêiE_PARj
+	$IF ATSK.NOTSK[i] < 0$
+		$ERROR ATSK.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "notsk", ATSK.NOTSK[i], "AID_TSK")$$END$
+	$END$
+	$num_atskid = num_atskid + ATSK.NOTSK[i]$
+$END$
+$num_tskid = LENGTH(TSK.ID_LIST) + num_atskid$
+
+$num_asemid = 0$
+$FOREACH i ASEM.ORDER_LIST$
+$	// nosemªÌêiE_PARj
+	$IF ASEM.NOSEM[i] < 0$
+		$ERROR ASEM.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nosem", ASEM.NOSEM[i], "AID_SEM")$$END$
+	$END$
+	$num_asemid = num_asemid + ASEM.NOSEM[i]$
+$END$
+$num_semid = LENGTH(SEM.ID_LIST) + num_asemid$
+
+$num_aflgid = 0$
+$FOREACH i AFLG.ORDER_LIST$
+$	// noflgªÌêiE_PARj
+	$IF AFLG.NOFLG[i] < 0$
+		$ERROR AFLG.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "noflg", AFLG.NOFLG[i], "AID_FLG")$$END$
+	$END$
+	$num_aflgid = num_aflgid + AFLG.NOFLG[i]$
+$END$
+$num_flgid = LENGTH(FLG.ID_LIST) + num_aflgid$
+
+$num_adtqid = 0$
+$FOREACH i ADTQ.ORDER_LIST$
+$	// nodtqªÌêiE_PARj
+	$IF ADTQ.NODTQ[i] < 0$
+		$ERROR ADTQ.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nodtq", ADTQ.NODTQ[i], "AID_DTQ")$$END$
+	$END$
+	$num_adtqid = num_adtqid + ADTQ.NODTQ[i]$
+$END$
+$num_dtqid = LENGTH(DTQ.ID_LIST) + num_adtqid$
+
+$num_apdqid = 0$
+$FOREACH i APDQ.ORDER_LIST$
+$	// nopdqªÌêiE_PARj
+	$IF APDQ.NOPDQ[i] < 0$
+		$ERROR APDQ.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nopdq", APDQ.NOPDQ[i], "AID_PDQ")$$END$
+	$END$
+	$num_apdqid = num_apdqid + APDQ.NOPDQ[i]$
+$END$
+$num_pdqid = LENGTH(PDQ.ID_LIST) + num_apdqid$
+
+$num_ambxid = 0$
+$FOREACH i AMBX.ORDER_LIST$
+$	// nombxªÌêiE_PARj
+	$IF AMBX.NOMBX[i] < 0$
+		$ERROR AMBX.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nombx", AMBX.NOMBX[i], "AID_MBX")$$END$
+	$END$
+	$num_ambxid = num_ambxid + AMBX.NOMBX[i]$
+$END$
+$num_mbxid = LENGTH(MBX.ID_LIST) + num_ambxid$
+
+$num_ampfid = 0$
+$FOREACH i AMPF.ORDER_LIST$
+$	// nompfªÌêiE_PARj
+	$IF AMPF.NOMPF[i] < 0$
+		$ERROR AMPF.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nompf", AMPF.NOMPF[i], "AID_MPF")$$END$
+	$END$
+	$num_ampfid = num_ampfid + AMPF.NOMPF[i]$
+$END$
+$num_mpfid = LENGTH(MPF.ID_LIST) + num_ampfid$
+
+$num_acycid = 0$
+$FOREACH i ACYC.ORDER_LIST$
+$	// nocycªÌêiE_PARj
+	$IF ACYC.NOCYC[i] < 0$
+		$ERROR ACYC.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "nocyc", ACYC.NOCYC[i], "AID_CYC")$$END$
+	$END$
+	$num_acycid = num_acycid + ACYC.NOCYC[i]$
+$END$
+$num_cycid = LENGTH(CYC.ID_LIST) + num_acycid$
+
+$num_aalmid = 0$
+$FOREACH i AALM.ORDER_LIST$
+$	// noalmªÌêiE_PARj
+	$IF AALM.NOALM[i] < 0$
+		$ERROR AALM.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "noalm", AALM.NOALM[i], "AID_ALM")$$END$
+	$END$
+	$num_aalmid = num_aalmid + AALM.NOALM[i]$
+$END$
+$num_almid = LENGTH(ALM.ID_LIST) + num_aalmid$
+
+$num_aisrid = 0$
+$FOREACH i AISR.ORDER_LIST$
+$	// noisrªÌêiE_PARj
+	$IF AISR.NOISR[i] < 0$
+		$ERROR AISR.TEXT_LINE[i]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "noisr", AISR.NOISR[i], "AID_ISR")$$END$
+	$END$
+	$num_aisrid = num_aisrid + AISR.NOISR[i]$
+$END$
+$num_isrid = num_aisrid$
+$num_isr = LENGTH(ISR.ORDER_LIST) + num_aisrid$
+
+$ =====================================================================
+$ kernel_cfg.hÌ¶¬
+$ =====================================================================
+
+$FILE "kernel_cfg.h"$
+/* kernel_cfg.h */$NL$
+#ifndef TOPPERS_KERNEL_CFG_H$NL$
+#define TOPPERS_KERNEL_CFG_H$NL$
+$NL$
+#define TNUM_TSKID	$num_tskid$$NL$
+#define TNUM_SEMID	$num_semid$$NL$
+#define TNUM_FLGID	$num_flgid$$NL$
+#define TNUM_DTQID	$num_dtqid$$NL$
+#define TNUM_PDQID	$num_pdqid$$NL$
+#define TNUM_MBXID	$num_mbxid$$NL$
+#define TNUM_MPFID	$num_mpfid$$NL$
+#define TNUM_CYCID	$num_cycid$$NL$
+#define TNUM_ALMID	$num_almid$$NL$
+#define TNUM_ISRID	$num_isrid$$NL$
+$NL$
+$FOREACH id TSK.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id SEM.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id FLG.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id DTQ.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id PDQ.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id MBX.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id MPF.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id CYC.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$FOREACH id ALM.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$NL$
+#endif /* TOPPERS_KERNEL_CFG_H */$NL$
+
+$ =====================================================================
+$ kernel_cfg.cÌ¶¬
+$ =====================================================================
+
+$FILE "kernel_cfg.c"$
+/* kernel_cfg.c */$NL$
+#include "kernel/kernel_int.h"$NL$
+#include "kernel_cfg.h"$NL$
+$NL$
+#if TKERNEL_PRID != 0x07u$NL$
+#error The kernel does not match this configuration file.$NL$
+#endif$NL$
+$NL$
+
+$ 
+$  CN[hfBNeBui#includej
+$ 
+/*$NL$
+$SPC$*  Include Directives (#include)$NL$
+$SPC$*/$NL$
+$NL$
+$INCLUDES$
+$NL$
+
+$ 
+$  IuWFNgÌIDÔðÛ·éÏ
+$ 
+$IF USE_EXTERNAL_ID$
+	/*$NL$
+	$SPC$*  Variables for Object ID$NL$
+	$SPC$*/$NL$
+	$NL$
+	$FOREACH id TSK.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id SEM.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id FLG.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id DTQ.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id PDQ.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id MBX.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id MPF.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id CYC.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+	$FOREACH id ALM.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+$END$
+
+$ 
+$  ^XN
+$ 
+/*$NL$
+$SPC$*  Task Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ ÃIÉ¶¬³ê½^XNª1ÂÈã¶Ý·é±ÆÌ`FbN
+$IF !LENGTH(TSK.ID_LIST)$
+	$ERROR$$FORMAT(_("no task is registered"))$$END$
+$END$
+
+$ ÃIÉ¶¬³ê½^XNÌ
+#define TNUM_STSKID	$LENGTH(TSK.ID_LIST)$$NL$
+$NL$
+
+$ ^XNIDÔÌÅål
+const ID _kernel_tmax_tskid = (TMIN_TSKID + TNUM_TSKID - 1);$NL$
+const ID _kernel_tmax_stskid = (TMIN_TSKID + TNUM_STSKID - 1);$NL$
+$NL$
+
+$ G[`FbN
+$FOREACH tskid TSK.ID_LIST$
+$	// tskatrªimTA_ACTnjÅÈ¢êiE_RSATRj
+	$IF (TSK.TSKATR[tskid] & ~(TA_ACT|TARGET_TSKATR)) != 0$
+		$ERROR TSK.TEXT_LINE[tskid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "tskatr", TSK.TSKATR[tskid], tskid, "CRE_TSK")$$END$
+	$END$
+
+$	// (TMIN_TPRI <= itskpri && itskpri <= TMAX_TPRI)ÅÈ¢êiE_PARj
+	$IF !(TMIN_TPRI <= TSK.ITSKPRI[tskid] && TSK.ITSKPRI[tskid] <= TMAX_TPRI)$
+		$ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "itskpri", TSK.ITSKPRI[tskid], tskid, "CRE_TSK")$$END$
+	$END$
+
+$ 	// texatrªiTA_NULLjÅÈ¢êiE_RSATRj
+	$IF LENGTH(TSK.TEXATR[tskid]) && TSK.TEXATR[tskid] != 0$
+		$ERROR DEF_TEX.TEXT_LINE[tskid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "texatr", TSK.TEXATR[tskid], tskid, "DEF_TEX")$$END$
+	$END$
+$END$
+
+$ X^bNÌæÌ¶¬Æ»êÉÖ·éG[`FbN
+$FOREACH tskid TSK.ID_LIST$
+$	// stkszª0Èº©C^[Qbgè`ÌÅ¬liTARGET_MIN_STKSZjæèà
+$	// ¬³¢êiE_PARj
+	$IF TSK.STKSZ[tskid] <= 0 || (TARGET_MIN_STKSZ
+									&& TSK.STKSZ[tskid] < TARGET_MIN_STKSZ)$
+		$ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is too small"), "stksz", TSK.STKSZ[tskid], tskid, "CRE_TSK")$$END$
+	$END$
+
+$ 	// stkszªX^bNÌæÌTCYÆµÄ³µ­È¢êiE_PARj
+	$IF !EQ(TSK.STK[tskid], "NULL") && CHECK_STKSZ_ALIGN
+							&& (TSK.STKSZ[tskid] & (CHECK_STKSZ_ALIGN - 1))$
+		$ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"), "stksz", TSK.STKSZ[tskid], tskid, "CRE_TSK")$$END$
+	$END$
+
+	$IF EQ(TSK.STK[tskid],"NULL")$
+		static STK_T _kernel_stack_$tskid$[COUNT_STK_T($TSK.STKSZ[tskid]$)];$NL$
+		$TSK.TINIB_STKSZ[tskid] = FORMAT("ROUND_STK_T(%1%)", TSK.STKSZ[tskid])$
+		$TSK.TINIB_STK[tskid] = CONCAT("_kernel_stack_", tskid)$
+	$ELSE$
+		$TSK.TINIB_STKSZ[tskid] = TSK.STKSZ[tskid]$
+		$TSK.TINIB_STK[tskid] = FORMAT("(void *)(%1%)", TSK.STK[tskid])$
+	$END$
+$END$
+$NL$
+
+$ ^XNú»ubNÌ¶¬i^XNÍ1ÂÈã¶Ý·éj
+const TINIB _kernel_tinib_table[TNUM_STSKID] = {$NL$
+$JOINEACH tskid TSK.ID_LIST ",\n"$
+$	// ^XN®«Cg£îñCN®ÔnCN®Dæx
+	$TAB${
+	$SPC$($TSK.TSKATR[tskid]$), (intptr_t)($TSK.EXINF[tskid]$),
+	$SPC$((TASK)($TSK.TASK[tskid]$)), INT_PRIORITY($TSK.ITSKPRI[tskid]$),
+
+$	// ^XNú»ReLXgubNCX^bNÌæ
+	$IF USE_TSKINICTXB$
+		$GENERATE_TSKINICTXB(tskid)$
+	$ELSE$
+		$SPC$$TSK.TINIB_STKSZ[tskid]$, $TSK.TINIB_STK[tskid]$,
+	$END$
+
+$	// ^XNáO[`Ì®«ÆN®Ôn
+	$SPC$($ALT(TSK.TEXATR[tskid],"TA_NULL")$), ($ALT(TSK.TEXRTN[tskid],"NULL")$) }
+$END$$NL$
+};$NL$
+$NL$
+
+$ ®I¶¬^XNpÌ^XNú»ubNÌ¶¬
+$IF num_atskid > 0$
+	TINIB _kernel_atinib_table[$num_atskid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(TINIB, _kernel_atinib_table);$NL$
+$END$$NL$
+
+$ ^XNÇubNÌ¶¬
+TCB _kernel_tcb_table[TNUM_TSKID];$NL$
+$NL$
+
+$ ^XN¶¬e[uÌ¶¬
+const ID _kernel_torder_table[TNUM_STSKID] = {$NL$
+$TAB$$JOINEACH tskid TSK.ORDER_LIST ", "$$tskid$$END$$NL$
+};$NL$
+$NL$
+
+$ 
+$  Z}tH
+$ 
+/*$NL$
+$SPC$*  Semaphore Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ ÃIÉ¶¬³ê½Z}tHÌ
+#define TNUM_SSEMID	$LENGTH(SEM.ID_LIST)$$NL$
+$NL$
+
+$ Z}tHIDÔÌÅål
+const ID _kernel_tmax_semid = (TMIN_SEMID + TNUM_SEMID - 1);$NL$
+const ID _kernel_tmax_ssemid = (TMIN_SEMID + TNUM_SSEMID - 1);$NL$
+$NL$
+
+$ Z}tHú»ubNÌ¶¬
+$IF LENGTH(SEM.ID_LIST)$
+	const SEMINIB _kernel_seminib_table[TNUM_SSEMID] = {$NL$
+	$JOINEACH semid SEM.ID_LIST ",\n"$
+$		// sematrªimTA_TPRInjÅÈ¢êiE_RSATRj
+		$IF (SEM.SEMATR[semid] & ~TA_TPRI) != 0$
+			$ERROR SEM.TEXT_LINE[semid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "sematr", SEM.SEMATR[semid], semid, "CRE_SEM")$$END$
+		$END$
+
+$		// (0 <= isemcnt && isemcnt <= maxsem)ÅÈ¢êiE_PARj
+		$IF !(0 <= SEM.ISEMCNT[semid] && SEM.ISEMCNT[semid] <= SEM.MAXSEM[semid])$
+			$ERROR SEM.TEXT_LINE[semid]$E_PAR: $FORMAT(_("too large %1% `%2%\' of `%3%\' in %4%"), "isemcnt", SEM.ISEMCNT[semid], semid, "CRE_SEM")$$END$
+		$END$
+
+$		// (1 <= maxsem && maxsem <= TMAX_MAXSEM)ÅÈ¢êiE_PARj
+		$IF !(1 <= SEM.MAXSEM[semid] && SEM.MAXSEM[semid] <= TMAX_MAXSEM)$
+			$ERROR SEM.TEXT_LINE[semid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxsem", SEM.MAXSEM[semid], semid, "CRE_SEM")$$END$
+		$END$
+
+$		// Z}tHú»ubN
+		$TAB${ ($SEM.SEMATR[semid]$), ($SEM.ISEMCNT[semid]$), ($SEM.MAXSEM[semid]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const SEMINIB, _kernel_seminib_table);$NL$
+$END$$NL$
+
+$ ®I¶¬Z}tHpÌZ}tHú»ubNÌ¶¬
+$IF num_asemid > 0$
+	SEMINIB _kernel_aseminib_table[$num_asemid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(SEMINIB, _kernel_aseminib_table);$NL$
+$END$$NL$
+
+$ Z}tHÇubNÌ¶¬
+$IF num_semid > 0$
+	SEMCB _kernel_semcb_table[TNUM_SEMID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(SEMCB, _kernel_semcb_table);$NL$
+$END$$NL$
+
+$ 
+$  CxgtO
+$ 
+/*$NL$
+$SPC$*  Eventflag Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ ÃIÉ¶¬³ê½CxgtOÌ
+#define TNUM_SFLGID	$LENGTH(FLG.ID_LIST)$$NL$
+$NL$
+
+$ CxgtOIDÔÌÅål
+const ID _kernel_tmax_flgid = (TMIN_FLGID + TNUM_FLGID - 1);$NL$
+const ID _kernel_tmax_sflgid = (TMIN_FLGID + TNUM_SFLGID - 1);$NL$
+$NL$
+
+$ CxgtOú»ubNÌ¶¬
+$IF LENGTH(FLG.ID_LIST)$
+	const FLGINIB _kernel_flginib_table[TNUM_SFLGID] = {$NL$
+	$JOINEACH flgid FLG.ID_LIST ",\n"$
+$		// flgatrªimTA_TPRInbmTA_WMULnbmTA_CLRnjÅÈ¢êiE_RSATRj
+		$IF (FLG.FLGATR[flgid] & ~(TA_TPRI|TA_WMUL|TA_CLR)) != 0$
+			$ERROR FLG.TEXT_LINE[flgid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "flgatr", FLG.FLGATR[flgid], flgid, "CRE_FLG")$$END$
+		$END$
+
+$		// iflgptnªFLGPTNÉi[Å«È¢êiE_PARj
+		$IF (FLG.IFLGPTN[flgid] & ~((1 << TBIT_FLGPTN) - 1)) != 0$
+			$ERROR FLG.TEXT_LINE[flgid]$E_PAR: $FORMAT(_("too large %1% `%2%\' of `%3%\' in %4%"), "iflgptn", FLG.IFLGPTN[flgid], flgid, "CRE_FLG")$$END$
+		$END$
+
+$		// CxgtOú»ubN
+		$TAB${ ($FLG.FLGATR[flgid]$), ($FLG.IFLGPTN[flgid]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const FLGINIB, _kernel_flginib_table);$NL$
+$END$$NL$
+
+$ ®I¶¬CxgtOpÌCxgtOú»ubNÌ¶¬
+$IF num_aflgid > 0$
+	FLGINIB _kernel_aflginib_table[$num_aflgid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(FLGINIB, _kernel_aflginib_table);$NL$
+$END$$NL$
+
+$ CxgtOÇubNÌ¶¬
+$IF num_flgid > 0$
+	FLGCB _kernel_flgcb_table[TNUM_FLGID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(FLGCB, _kernel_flgcb_table);$NL$
+$END$$NL$
+
+$ 
+$  f[^L
+[
+$ 
+/*$NL$
+$SPC$*  Dataqueue Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ ÃIÉ¶¬³ê½f[^L
+[Ì
+#define TNUM_SDTQID	$LENGTH(DTQ.ID_LIST)$$NL$
+$NL$
+
+$ f[^L
+[IDÔÌÅål
+const ID _kernel_tmax_dtqid = (TMIN_DTQID + TNUM_DTQID - 1);$NL$
+const ID _kernel_tmax_sdtqid = (TMIN_DTQID + TNUM_SDTQID - 1);$NL$
+$NL$
+
+$IF LENGTH(DTQ.ID_LIST)$
+	$FOREACH dtqid DTQ.ID_LIST$
+$		// dtqatrªimTA_TPRInjÅÈ¢êiE_RSATRj
+		$IF (DTQ.DTQATR[dtqid] & ~TA_TPRI) != 0$
+			$ERROR DTQ.TEXT_LINE[dtqid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqatr", DTQ.DTQATR[dtqid], dtqid, "CRE_DTQ")$$END$
+		$END$
+
+$		// dtqcntªÌêiE_PARj
+		$IF DTQ.DTQCNT[dtqid] < 0$
+			$ERROR DTQ.TEXT_LINE[dtqid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqcnt", DTQ.DTQCNT[dtqid], dtqid, "CRE_DTQ")$$END$
+		$END$
+
+$		// dtqmbªNULLÅÈ¢êiE_NOSPTj
+		$IF !EQ(DTQ.DTQMB[dtqid], "NULL")$
+			$ERROR DTQ.TEXT_LINE[dtqid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqmb", DTQ.DTQMB[dtqid], dtqid, "CRE_DTQ")$$END$
+		$END$
+
+$		// f[^L
+[ÇÌæ
+		$IF DTQ.DTQCNT[dtqid]$
+			static DTQMB _kernel_dtqmb_$dtqid$[$DTQ.DTQCNT[dtqid]$];$NL$
+		$END$
+	$END$
+
+$	// f[^L
+[ú»ubNÌ¶¬
+	const DTQINIB _kernel_dtqinib_table[TNUM_SDTQID] = {$NL$
+	$JOINEACH dtqid DTQ.ID_LIST ",\n"$
+		$TAB${ ($DTQ.DTQATR[dtqid]$), ($DTQ.DTQCNT[dtqid]$), $IF DTQ.DTQCNT[dtqid]$(_kernel_dtqmb_$dtqid$)$ELSE$NULL$END$ }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const DTQINIB, _kernel_dtqinib_table);$NL$
+$END$$NL$
+
+$ ®I¶¬f[^L
+[pÌf[^L
+[ú»ubNÌ¶¬
+$IF num_adtqid > 0$
+	DTQINIB _kernel_adtqinib_table[$num_adtqid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(DTQINIB, _kernel_adtqinib_table);$NL$
+$END$$NL$
+
+$ f[^L
+[ÇubNÌ¶¬
+$IF num_dtqid > 0$
+	DTQCB _kernel_dtqcb_table[TNUM_DTQID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(DTQCB, _kernel_dtqcb_table);$NL$
+$END$$NL$
+
+$ 
+$  Dæxf[^L
+[
+$ 
+/*$NL$
+$SPC$*  Priority Dataqueue Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ ÃIÉ¶¬³ê½Dæxf[^L
+[Ì
+#define TNUM_SPDQID	$LENGTH(PDQ.ID_LIST)$$NL$
+$NL$
+
+$ Dæxf[^L
+[IDÔÌÅål
+const ID _kernel_tmax_pdqid = (TMIN_PDQID + TNUM_PDQID - 1);$NL$
+const ID _kernel_tmax_spdqid = (TMIN_PDQID + TNUM_SPDQID - 1);$NL$
+$NL$
+
+$IF LENGTH(PDQ.ID_LIST)$
+	$FOREACH pdqid PDQ.ID_LIST$
+$		// pdqatrªimTA_TPRInjÅÈ¢êiE_RSATRj
+		$IF (PDQ.PDQATR[pdqid] & ~TA_TPRI) != 0$
+			$ERROR PDQ.TEXT_LINE[pdqid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqatr", PDQ.PDQATR[pdqid], pdqid, "CRE_PDQ")$$END$
+		$END$
+
+$		// pdqcntªÌêiE_PARj
+		$IF PDQ.PDQCNT[pdqid] < 0$
+			$ERROR PDQ.TEXT_LINE[pdqid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqcnt", PDQ.PDQCNT[pdqid], pdqid, "CRE_PDQ")$$END$
+		$END$
+
+$		// (TMIN_DPRI <= maxdpri && maxdpri <= TMAX_DPRI)ÅÈ¢êiE_PARj
+		$IF !(TMIN_DPRI <= PDQ.MAXDPRI[pdqid] && PDQ.MAXDPRI[pdqid] <= TMAX_DPRI)$
+			$ERROR PDQ.TEXT_LINE[pdqid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxdpri", PDQ.MAXDPRI[pdqid], pdqid, "CRE_PDQ")$$END$
+		$END$
+
+$		// pdqmbªNULLÅÈ¢êiE_NOSPTj
+		$IF !EQ(PDQ.PDQMB[pdqid], "NULL")$
+			$ERROR PDQ.TEXT_LINE[pdqid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqmb", PDQ.PDQMB[pdqid], pdqid, "CRE_PDQ")$$END$
+		$END$
+
+$		// Dæxf[^L
+[ÇÌæ
+		$IF PDQ.PDQCNT[pdqid]$
+			static PDQMB _kernel_pdqmb_$pdqid$[$PDQ.PDQCNT[pdqid]$];$NL$
+		$END$
+	$END$
+
+$	// Dæxf[^L
+[ú»ubNÌ¶¬
+	const PDQINIB _kernel_pdqinib_table[TNUM_SPDQID] = {$NL$
+	$JOINEACH pdqid PDQ.ID_LIST ",\n"$
+		$TAB${ ($PDQ.PDQATR[pdqid]$), ($PDQ.PDQCNT[pdqid]$), ($PDQ.MAXDPRI[pdqid]$), $IF PDQ.PDQCNT[pdqid]$(_kernel_pdqmb_$pdqid$)$ELSE$NULL$END$ }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const PDQINIB, _kernel_pdqinib_table);$NL$
+$END$$NL$
+
+$ ®I¶¬Dæxf[^L
+[pÌDæxf[^L
+[ú»ubNÌ¶¬
+$IF num_apdqid > 0$
+	PDQINIB _kernel_apdqinib_table[$num_apdqid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(PDQINIB, _kernel_apdqinib_table);$NL$
+$END$$NL$
+
+$ Dæxf[^L
+[ÇubNÌ¶¬
+$IF num_pdqid > 0$
+	PDQCB _kernel_pdqcb_table[TNUM_PDQID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(PDQCB, _kernel_pdqcb_table);$NL$
+$END$$NL$
+
+$ 
+$  [{bNX
+$ 
+/*$NL$
+$SPC$*  Mailbox Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ ÃIÉ¶¬³ê½[{bNXÌ
+#define TNUM_SMBXID	$LENGTH(MBX.ID_LIST)$$NL$
+$NL$
+
+$ [{bNXIDÔÌÅål
+const ID _kernel_tmax_mbxid = (TMIN_MBXID + TNUM_MBXID - 1);$NL$
+const ID _kernel_tmax_smbxid = (TMIN_MBXID + TNUM_SMBXID - 1);$NL$
+$NL$
+
+$ [{bNXú»ubNÌ¶¬
+$IF LENGTH(MBX.ID_LIST)$
+	const MBXINIB _kernel_mbxinib_table[TNUM_SMBXID] = {$NL$
+	$JOINEACH mbxid MBX.ID_LIST ",\n"$
+$		// mbxatrªimTA_TPRInbmTA_MPRInjÅÈ¢êiE_RSATRj
+		$IF (MBX.MBXATR[mbxid] & ~(TA_TPRI|TA_MPRI)) != 0$
+			$ERROR MBX.TEXT_LINE[mbxid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mbxatr", MBX.MBXATR[mbxid], mbxid, "CRE_MBX")$$END$
+		$END$
+
+$		// (TMIN_MPRI <= maxmpri && maxmpri <= TMAX_MPRI)ÅÈ¢êiE_PARj
+		$IF !(TMIN_MPRI <= MBX.MAXMPRI[mbxid] && MBX.MAXMPRI[mbxid] <= TMAX_MPRI)$
+			$ERROR MBX.TEXT_LINE[mbxid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxmpri", MBX.MAXMPRI[mbxid], mbxid, "CRE_MBX")$$END$
+		$END$
+
+$		// mprihdªNULLÅÈ¢êiE_NOSPTj
+		$IF !EQ(MBX.MPRIHD[mbxid], "NULL")$
+			$ERROR MBX.TEXT_LINE[mbxid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mprihd", MBX.MPRIHD[mbxid], mbxid, "CRE_MBX")$$END$
+		$END$
+
+$		// [{bNXú»ubN
+		$TAB${ ($MBX.MBXATR[mbxid]$), ($MBX.MAXMPRI[mbxid]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const MBXINIB, _kernel_mbxinib_table);$NL$
+$END$$NL$
+
+$ ®I¶¬[{bNXpÌ[{bNXú»ubNÌ¶¬
+$IF num_ambxid > 0$
+	MBXINIB _kernel_ambxinib_table[$num_ambxid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(MBXINIB, _kernel_ambxinib_table);$NL$
+$END$$NL$
+
+$ [{bNXÇubNÌ¶¬
+$IF num_mbxid > 0$
+	MBXCB _kernel_mbxcb_table[TNUM_MBXID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(MBXCB, _kernel_mbxcb_table);$NL$
+$END$$NL$
+
+$ 
+$  Åè·v[
+$ 
+/*$NL$
+$SPC$*  Fixed-sized Memorypool Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ ÃIÉ¶¬³ê½Åè·v[Ì
+#define TNUM_SMPFID	$LENGTH(MPF.ID_LIST)$$NL$
+$NL$
+
+$ Åè·v[IDÔÌÅål
+const ID _kernel_tmax_mpfid = (TMIN_MPFID + TNUM_MPFID - 1);$NL$
+const ID _kernel_tmax_smpfid = (TMIN_MPFID + TNUM_SMPFID - 1);$NL$
+$NL$
+
+$IF LENGTH(MPF.ID_LIST)$
+	$FOREACH mpfid MPF.ID_LIST$
+$		// mpfatrªimTA_TPRInjÅÈ¢êiE_RSATRj
+		$IF (MPF.MPFATR[mpfid] & ~TA_TPRI) != 0$
+			$ERROR MPF.TEXT_LINE[mpfid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mpfatr", MPF.MPFATR[mpfid], mpfid, "CRE_MPF")$$END$
+		$END$
+
+$		// blkcntª0ÈºÌêiE_PARj
+		$IF MPF.BLKCNT[mpfid] <= 0$
+			$ERROR MPF.TEXT_LINE[mpfid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "blkcnt", MPF.BLKCNT[mpfid], mpfid, "CRE_MPF")$$END$
+		$END$
+
+$		// blkszª0ÈºÌêiE_PARj
+		$IF MPF.BLKSZ[mpfid] <= 0$
+			$ERROR MPF.TEXT_LINE[mpfid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "blksz", MPF.BLKSZ[mpfid], mpfid, "CRE_MPF")$$END$
+		$END$
+
+$		// Åè·v[Ìæ
+		$IF EQ(MPF.MPF[mpfid], "NULL")$
+			static MPF_T _kernel_mpf_$mpfid$[($MPF.BLKCNT[mpfid]$) * COUNT_MPF_T($MPF.BLKSZ[mpfid]$)];$NL$
+		$END$
+
+$		// mpfmbªNULLÅÈ¢êiE_NOSPTj
+		$IF !EQ(MPF.MPFMB[mpfid], "NULL")$
+			$ERROR MPF.TEXT_LINE[mpfid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mpfmb", MPF.MPFMB[mpfid], mpfid, "CRE_MPF")$$END$
+		$END$
+
+$		// Åè·v[ÇÌæ
+		static MPFMB _kernel_mpfmb_$mpfid$[$MPF.BLKCNT[mpfid]$];$NL$
+	$END$
+
+$	// Åè·v[ú»ubNÌ¶¬
+	const MPFINIB _kernel_mpfinib_table[TNUM_SMPFID] = {$NL$
+	$JOINEACH mpfid MPF.ID_LIST ",\n"$
+		$TAB${ ($MPF.MPFATR[mpfid]$), ($MPF.BLKCNT[mpfid]$), ROUND_MPF_T($MPF.BLKSZ[mpfid]$), $IF EQ(MPF.MPF[mpfid],"NULL")$(_kernel_mpf_$mpfid$)$ELSE$(void *)($MPF.MPF[mpfid]$)$END$, (_kernel_mpfmb_$mpfid$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const MPFINIB, _kernel_mpfinib_table);$NL$
+$END$$NL$
+
+$ ®I¶¬Åè·v[pÌÅè·v[ú»ubNÌ¶¬
+$IF num_ampfid > 0$
+	MPFINIB _kernel_ampfinib_table[$num_ampfid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(MPFINIB, _kernel_ampfinib_table);$NL$
+$END$$NL$
+
+$ Åè·v[ÇubNÌ¶¬
+$IF num_mpfid > 0$
+	MPFCB _kernel_mpfcb_table[TNUM_MPFID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(MPFCB, _kernel_mpfcb_table);$NL$
+$END$$NL$
+
+$ 
+$  üúnh
+$ 
+/*$NL$
+$SPC$*  Cyclic Handler Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ ÃIÉ¶¬³ê½üúnhÌ
+#define TNUM_SCYCID	$LENGTH(CYC.ID_LIST)$$NL$
+$NL$
+
+$ üúnhIDÔÌÅål
+const ID _kernel_tmax_cycid = (TMIN_CYCID + TNUM_CYCID - 1);$NL$
+const ID _kernel_tmax_scycid = (TMIN_CYCID + TNUM_SCYCID - 1);$NL$
+$NL$
+
+$ üúnhú»e[uÌ¶¬
+$IF LENGTH(CYC.ID_LIST)$
+	const CYCINIB _kernel_cycinib_table[TNUM_SCYCID] = {$NL$
+	$JOINEACH cycid CYC.ID_LIST ",\n"$
+$		// cycatrªimTA_STAnjÅÈ¢êiE_RSATRj
+		$IF (CYC.CYCATR[cycid] & ~TA_STA) != 0$
+			$ERROR CYC.TEXT_LINE[cycid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cycatr", CYC.CYCATR[cycid], cycid, "CRE_CYC")$$END$
+		$END$
+
+$		// (0 < cyctim && cyctim <= TMAX_RELTIM)ÅÈ¢êiE_PARj
+		$IF !(0 < CYC.CYCTIM[cycid] && CYC.CYCTIM[cycid] <= TMAX_RELTIM)$
+			$ERROR CYC.TEXT_LINE[cycid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cyctim", CYC.CYCTIM[cycid], cycid, "CRE_CYC")$$END$
+		$END$
+
+$		// (0 <= cycphs && cycphs <= TMAX_RELTIM)ÅÈ¢êiE_PARj
+		$IF !(0 <= CYC.CYCPHS[cycid] && CYC.CYCPHS[cycid] <= TMAX_RELTIM)$
+			$ERROR CYC.TEXT_LINE[cycid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cycphs", CYC.CYCPHS[cycid], cycid, "CRE_CYC")$$END$
+		$END$
+
+$		// xFcycatrÉTA_STAªÝè³êÄ¢ÄC(cycphs == 0)Ìê
+		$IF (CYC.CYCATR[cycid] & TA_STA) != 0 && CYC.CYCPHS[cycid] == 0$
+			$WARNING CYC.TEXT_LINE[cycid]$$FORMAT(_("%1% is not recommended when %2% is set to %3% in %4%"), "cycphs==0", "TA_STA", "cycatr", "CRE_CYC")$$END$
+		$END$
+
+$		// üúnhú»ubN
+		$TAB${ ($CYC.CYCATR[cycid]$), (intptr_t)($CYC.EXINF[cycid]$), ($CYC.CYCHDR[cycid]$), ($CYC.CYCTIM[cycid]$), ($CYC.CYCPHS[cycid]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const CYCINIB, _kernel_cycinib_table);$NL$
+$END$$NL$
+
+$ ®I¶¬üúnhpÌüúnhú»ubNÌ¶¬
+$IF num_acycid > 0$
+	CYCINIB _kernel_acycinib_table[$num_acycid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(CYCINIB, _kernel_acycinib_table);$NL$
+$END$$NL$
+
+$ üúnhÇubNÌ¶¬
+$IF num_cycid > 0$
+	CYCCB _kernel_cyccb_table[TNUM_CYCID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(CYCCB, _kernel_cyccb_table);$NL$
+$END$$NL$
+
+$ 
+$  A[nh
+$ 
+/*$NL$
+$SPC$*  Alarm Handler Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ ÃIÉ¶¬³ê½A[nhÌ
+#define TNUM_SALMID	$LENGTH(ALM.ID_LIST)$$NL$
+$NL$
+
+$ A[nhIDÔÌÅål
+const ID _kernel_tmax_almid = (TMIN_ALMID + TNUM_ALMID - 1);$NL$
+const ID _kernel_tmax_salmid = (TMIN_ALMID + TNUM_SALMID - 1);$NL$
+$NL$
+
+$ A[nhú»ubNÌ¶¬
+$IF LENGTH(ALM.ID_LIST)$
+	const ALMINIB _kernel_alminib_table[TNUM_SALMID] = {$NL$
+	$JOINEACH almid ALM.ID_LIST ",\n"$
+$		// almatrªiTA_NULLjÅÈ¢êiE_RSATRj
+		$IF ALM.ALMATR[almid] != 0$
+			$ERROR ALM.TEXT_LINE[almid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "almatr", ALM.ALMATR[almid], almid, "CRE_ALM")$$END$
+		$END$
+
+$		// A[nhú»ubN
+		$TAB${ ($ALM.ALMATR[almid]$), (intptr_t)($ALM.EXINF[almid]$), ($ALM.ALMHDR[almid]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const ALMINIB, _kernel_alminib_table);$NL$
+$END$$NL$
+
+$ ®I¶¬A[nhpÌA[nhú»ubNÌ¶¬
+$IF num_aalmid > 0$
+	ALMINIB _kernel_aalminib_table[$num_aalmid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(ALMINIB, _kernel_aalminib_table);$NL$
+$END$$NL$
+
+$ A[nhÇubNÌ¶¬
+$IF num_almid > 0$
+	ALMCB _kernel_almcb_table[TNUM_ALMID];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(ALMCB, _kernel_almcb_table);$NL$
+$END$$NL$
+
+$ 
+$  ÝÇ@\
+$ 
+/*$NL$
+$SPC$*  Interrupt Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ ÝÔÆÝnhÔÌÏ·e[uÌì¬
+$IF LENGTH(INTNO_ATTISR_VALID) != LENGTH(INHNO_ATTISR_VALID)$
+	$ERROR$length of `INTNO_ATTISR_VALID' is different from length of `INHNO_ATTISR_VALID'$END$
+$END$
+$i = 0$
+$FOREACH intno INTNO_ATTISR_VALID$
+	$inhno = AT(INHNO_ATTISR_VALID, i)$
+	$INHNO[intno] = inhno$
+	$INTNO[inhno] = intno$
+	$i = i + 1$
+$END$
+
+$ ÝvCÉÖ·éG[`FbN
+$i = 0$
+$FOREACH intno INT.ORDER_LIST$
+$	// intnoªCFG_INTÉÎ·éÝÔÆµÄ³µ­È¢êiE_PARj
+	$IF !LENGTH(FIND(INTNO_CFGINT_VALID, INT.INTNO[intno]))$
+		$ERROR INT.TEXT_LINE[intno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intno", INT.INTNO[intno], "CFG_INT")$$END$
+	$END$
+
+$	// intnoªCFG_INTÉæÁÄÝèÏÝÌêiE_OBJj
+	$j = 0$
+	$FOREACH intno2 INT.ORDER_LIST$
+		$IF INT.INTNO[intno] == INT.INTNO[intno2] && j < i$
+			$ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "intno", INT.INTNO[intno], "CFG_INT")$$END$
+		$END$
+		$j = j + 1$
+	$END$
+
+$	// intatrªimTA_ENAINTnbmTA_EDGEnjÅÈ¢êiE_RSATRj
+	$IF (INT.INTATR[intno] & ~(TA_ENAINT|TA_EDGE|TARGET_INTATR)) != 0$
+		$ERROR INT.TEXT_LINE[intno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "intatr", INT.INTATR[intno], "intno", INT.INTNO[intno], "CFG_INT")$$END$
+	$END$
+
+$	// intpriªCFG_INTÉÎ·éÝDæxÆµÄ³µ­È¢êiE_PARj
+	$IF !LENGTH(FIND(INTPRI_CFGINT_VALID, INT.INTPRI[intno]))$
+		$ERROR INT.TEXT_LINE[intno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intpri", INT.INTPRI[intno], "CFG_INT")$$END$
+	$END$
+
+$	// J[lÇÉÅè³êÄ¢éintnoÉÎµÄCintpriÉTMIN_INTPRI
+$	// æèà¬³¢lªwè³ê½êiE_OBJj
+	$IF LENGTH(FIND(INTNO_FIX_KERNEL, intno))$
+		$IF INT.INTPRI[intno] < TMIN_INTPRI$
+			$ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' must not have higher priority than %3%"), "intno", INT.INTNO[intno], "TMIN_INTPRI")$$END$
+		$END$
+	$END$
+
+$	// J[lÇOÉÅè³êÄ¢éintnoÉÎµÄCintpriÉTMIN_INTPRI
+$	// æèà¬³¢lªwè³êÈ©Á½êiE_OBJj
+	$IF LENGTH(FIND(INTNO_FIX_NONKERNEL, intno))$
+		$IF INT.INTPRI[intno] >= TMIN_INTPRI$
+			$ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' must have higher priority than %3%"), "intno", INT.INTNO[intno], "TMIN_INTPRI")$$END$
+		$END$
+	$END$
+	$i = i + 1$
+$END$
+
+$ ÝnhÉÖ·éG[`FbN
+$i = 0$
+$FOREACH inhno INH.ORDER_LIST$
+$	// inhnoªDEF_INHÉÎ·éÝnhÔÆµÄ³µ­È¢êiE_PARj
+	$IF !LENGTH(FIND(INHNO_DEFINH_VALID, INH.INHNO[inhno]))$
+		$ERROR INH.TEXT_LINE[inhno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+	$END$
+
+$	// inhnoªDEF_INHÉæÁÄÝèÏÝÌêiE_OBJj
+	$j = 0$
+	$FOREACH inhno2 INH.ORDER_LIST$
+		$IF INH.INHNO[inhno] == INH.INHNO[inhno2] && j < i$
+			$ERROR INH.TEXT_LINE[inhno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+		$END$
+		$j = j + 1$
+	$END$
+
+$	// inhatrªiTA_NULLjÅÈ¢êiE_RSATRj
+	$IF (INH.INHATR[inhno] & ~TARGET_INHATR) != 0$
+		$ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "inhatr", INH.INHATR[inhno], "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+	$END$
+
+$	// J[lÇÉÅè³êÄ¢éinhnoÉÎµÄCinhatrÉTA_NONKERNEL
+$	//@ªwè³êÄ¢éêiE_RSATRj
+	$IF LENGTH(FIND(INHNO_FIX_KERNEL, inhno))$
+		$IF (INH.INHATR[inhno] & TA_NONKERNEL) != 0$
+			$ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("%1% `%2%\' must not be non-kernel interrupt"), "inhno", INH.INHNO[inhno])$$END$
+		$END$
+	$END$
+
+$	// J[lÇOÉÅè³êÄ¢éinhnoÉÎµÄCinhatrÉTA_NONKERNEL
+$	// ªwè³êÄ¢È¢êiE_RSATRj
+	$IF LENGTH(FIND(INHNO_FIX_NONKERNEL, inhno))$
+		$IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+			$ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("%1% `%2%\' must be non-kernel interrupt"), "inhno", INH.INHNO[inhno])$$END$
+		$END$
+	$END$
+
+	$IF LENGTH(INTNO[INH.INHNO[inhno]])$
+		$intno = INTNO[INH.INHNO[inhno]]$
+$		// inhnoÉÎ·éintnoÉÎ·éCFG_INTªÈ¢êiE_OBJj
+		$IF !LENGTH(INT.INTNO[intno])$
+			$ERROR INH.TEXT_LINE[inhno]$E_OBJ: $FORMAT(_("%1% `%2%\' corresponding to %3% `%4%\' is not configured with %5%"), "intno", INT.INTNO[intno], "inhno", INH.INHNO[inhno], "CFG_INT")$$END$
+		$ELSE$
+			$IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+$				// inhatrÉTA_NONKERNELªwè³êÄ¨ç¸CinhnoÉÎ
+$				// ·éintnoÉÎµÄCFG_INTÅÝè³ê½ÝDæxª
+$				// TMIN_INTPRIæèà¬³¢êiE_OBJj
+				$IF INT.INTPRI[intno] < TMIN_INTPRI$
+					$ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is higher than %5%"), "intpri", INT.INTPRI[intno], "inhno", INH.INHNO[inhno], "TMIN_INTPRI")$$END$
+				$END$
+			$ELSE$
+$				// inhatrÉTA_NONKERNELªwè³êÄ¨èCinhnoÉÎ
+$				// ·éintnoÉÎµÄCFG_INTÅÝè³ê½ÝDæxª
+$				// TMIN_INTPRIÈãÅ éêiE_OBJj
+				$IF INT.INTPRI[intno] >= TMIN_INTPRI$
+					$ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is lower than or equal to %5%"), "intpri", INT.INTPRI[intno], "inhno", INH.INHNO[inhno], "TMIN_INTPRI")$$END$
+				$END$
+			$END$
+		$END$
+	$END$
+	$i = i + 1$
+$END$
+
+$ ÝT[rX[`iISRjÉÖ·éG[`FbN
+$FOREACH order ISR.ORDER_LIST$
+$	// isratrªiTA_NULLjÅÈ¢êiE_RSATRj
+	$IF (ISR.ISRATR[order] & ~TARGET_ISRATR) != 0$
+		$ERROR ISR.TEXT_LINE[order]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "isratr", ISR.ISRATR[order], "ATT_ISR")$$END$
+	$END$
+
+$	// intnoªATT_ISRÉÎ·éÝÔÆµÄ³µ­È¢êiE_PARj
+	$IF !LENGTH(FIND(INTNO_ATTISR_VALID, ISR.INTNO[order]))$
+		$ERROR ISR.TEXT_LINE[order]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intno", ISR.INTNO[order], "ATT_ISR")$$END$
+	$END$
+
+$	// (TMIN_ISRPRI <= isrpri && isrpri <= TMAX_ISRPRI)ÅÈ¢êiE_PARj
+	$IF !(TMIN_ISRPRI <= ISR.ISRPRI[order] && ISR.ISRPRI[order] <= TMAX_ISRPRI)$
+		$ERROR ISR.TEXT_LINE[order]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "isrpri", ISR.ISRPRI[order], "ATT_ISR")$$END$
+	$END$
+$END$
+
+$FOREACH intno INTNO_ATTISR_VALID$
+	$inhno = INHNO[intno]$
+
+$	// ÝÔintnoÉÎµÄo^³ê½ISRÌXgÌì¬
+	$isr_order_list = {}$
+	$FOREACH order ISR.ORDER_LIST$
+		$IF ISR.INTNO[order] == intno$
+			$isr_order_list = APPEND(isr_order_list, order)$
+			$order_for_error = order$
+		$END$
+	$END$
+
+$	// ÝÔintnoÉÎµÄo^³ê½ISRª¶Ý·éê
+	$IF LENGTH(isr_order_list) > 0$
+$		// intnoÉÎ·éinhnoÉÎµÄDEF_INHª éêiE_OBJj
+		$IF LENGTH(INH.INHNO[inhno])$
+			$ERROR ISR.TEXT_LINE[order_for_error]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated with %4% `%5%\'"), "intno", ISR.INTNO[order_for_error], "ATT_ISR", "inhno", INH.INHNO[inhno])$$END$
+		$END$
+
+$		// intnoÉÎ·éCFG_INTªÈ¢êiE_OBJj
+		$IF !LENGTH(INT.INTNO[intno])$
+			$ERROR ISR.TEXT_LINE[order_for_error]$E_OBJ: $FORMAT(_("%1% `%2%\' is not configured with %3%"), "intno", ISR.INTNO[order_for_error], "CFG_INT")$$END$
+		$ELSE$
+$			// intnoÉÎµÄCFG_INTÅÝè³ê½ÝDæxªTMIN_INTPRI
+$			// æèà¬³¢êiE_OBJj
+			$IF INT.INTPRI[intno] < TMIN_INTPRI$
+				$ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is higher than %5%"), "intpri", INT.INTPRI[intno], "intno", ISR.INTNO[order_for_error], "TMIN_INTPRI")$$END$
+			$END$
+		$END$
+	$END$
+$END$
+
+$ ÝT[rX[`iISRjÇÌf[^\¢
+$intno_isr_list = {}$
+$FOREACH intno INTNO_ATTISR_VALID$
+	$inhno = INHNO[intno]$
+	$IF LENGTH(INT.INTNO[intno]) && !LENGTH(INH.INHNO[inhno])$
+		$intno_isr_list = APPEND(intno_isr_list, intno)$
+	$END$
+$END$
+
+$INTNO_ISR = {}$
+$i = 0$
+$FOREACH intno SORT(intno_isr_list, "INT.INTNO")$
+	$INTNO_ISR = APPEND(INTNO_ISR, intno)$
+	$ISR_QUEUE_HEADER[intno] = FORMAT("&(_kernel_isr_queue_table[%d])", i)$
+	$i = i + 1$
+$END$
+
+const uint_t _kernel_tnum_isr_queue = $LENGTH(INTNO_ISR)$;$NL$
+$NL$
+
+$IF LENGTH(INTNO_ISR)$
+	const ISR_ENTRY _kernel_isr_queue_list[$LENGTH(INTNO_ISR)$] = {$NL$
+	$JOINEACH intno INTNO_ISR ",\n"$
+		$TAB${ $intno$, $ISR_QUEUE_HEADER[intno]$ }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(QUEUE, _kernel_isr_queue_table);$NL$
+$END$$NL$
+
+$IF LENGTH(INTNO_ISR)$
+	QUEUE _kernel_isr_queue_table[$LENGTH(INTNO_ISR)$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(QUEUE, _kernel_isr_queue_table);$NL$
+$END$$NL$
+
+$ ÝT[rX[`iISRjÄoµÌ½ßÌÝnhÌ¶¬
+$FOREACH intno INTNO_ISR$
+	$inhno = INHNO[intno]$
+
+$	// DEF_INH(inhno, { TA_NULL, _kernel_inthdr_<intno> } );
+	$INH.INHNO[inhno] = inhno$
+	$INH.INHATR[inhno] = VALUE("TA_NULL", 0)$
+	$INH.INTHDR[inhno] = CONCAT("_kernel_inthdr_", intno)$
+	$INH.ORDER_LIST = APPEND(INH.ORDER_LIST, inhno)$
+
+$	// ISRpÌÝnh
+	void$NL$
+	_kernel_inthdr_$intno$(void)$NL$
+	{$NL$
+	$TAB$i_begin_int($intno$);$NL$
+	$TAB$_kernel_call_isr($ISR_QUEUE_HEADER[intno]$);$NL$
+	$TAB$i_end_int($intno$);$NL$
+	}$NL$
+	$NL$
+$END$
+
+$ ÝT[rX[`Ì
+#define TNUM_SISR	$LENGTH(ISR.ORDER_LIST)$$NL$
+#define TNUM_ISR	$LENGTH(ISR.ORDER_LIST) + num_aisrid$$NL$
+$NL$
+
+$ ÝT[rX[`IDÔÌÅål
+const ID _kernel_tmax_isrid = (TMIN_ISRID + TNUM_ISRID - 1);$NL$
+const uint_t _kernel_tnum_sisr = TNUM_SISR;$NL$
+$NL$
+
+$ ÝT[rX[`ú»ubNÌ¶¬
+$IF LENGTH(ISR.ORDER_LIST)$
+	const ISRINIB _kernel_sisrinib_table[TNUM_SISR] = {$NL$
+	$JOINEACH order ISR.ORDER_LIST ",\n"$
+		$TAB${ ($ISR.ISRATR[order]$), ($ISR.EXINF[order]$), ($ISR.INTNO[order]$), ($ISR_QUEUE_HEADER[ISR.INTNO[order]]$), ($ISR.ISR[order]$), ($ISR.ISRPRI[order]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const ISRINIB, _kernel_sisrinib_table);$NL$
+$END$
+$NL$
+
+$ ®I¶¬ÝT[rX[`pÌÝT[rX[`ú»ub
+$ NÌ¶¬
+$IF num_aisrid > 0$
+	ISRINIB _kernel_aisrinib_table[$num_aisrid$];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(ISRINIB, _kernel_aisrinib_table);$NL$
+$END$
+$NL$
+
+$ ÝT[rX[`ÇubNÌ¶¬
+$IF num_isr > 0$
+	ISRCB _kernel_isrcb_table[TNUM_ISR];$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(ISRCB, _kernel_isrcb_table);$NL$
+$END$
+$NL$
+
+$ 
+$  ÝÇ@\Ì½ßÌWIÈú»îñÌ¶¬
+$ 
+$ ÝnhÌú»ÉKvÈîñ
+$IF !OMIT_INITIALIZE_INTERRUPT || ALT(USE_INHINIB_TABLE,0)$
+
+$ Ýnh
+#define TNUM_INHNO	$LENGTH(INH.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_inhno = TNUM_INHNO;$NL$
+$NL$
+$FOREACH inhno INH.ORDER_LIST$
+	$IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+		INTHDR_ENTRY($INH.INHNO[inhno]$, $+INH.INHNO[inhno]$, $INH.INTHDR[inhno]$)$NL$
+	$END$
+$END$
+$NL$
+
+$ Ýnhú»e[u
+$IF LENGTH(INH.ORDER_LIST)$
+	const INHINIB _kernel_inhinib_table[TNUM_INHNO] = {$NL$
+	$JOINEACH inhno INH.ORDER_LIST ",\n"$
+		$IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+			$TAB${ ($INH.INHNO[inhno]$), ($INH.INHATR[inhno]$), (FP)(INT_ENTRY($INH.INHNO[inhno]$, $INH.INTHDR[inhno]$)) }
+		$ELSE$
+			$TAB${ ($INH.INHNO[inhno]$), ($INH.INHATR[inhno]$), (FP)($INH.INTHDR[inhno]$) }
+		$END$
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const INHINIB, _kernel_inhinib_table);$NL$
+$END$$NL$
+$END$
+
+$ ÝvCÌú»ÉKvÈîñ
+$IF !OMIT_INITIALIZE_INTERRUPT || ALT(USE_INTINIB_TABLE,0)$
+
+$ ÝvC
+#define TNUM_INTNO	$LENGTH(INT.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_intno = TNUM_INTNO;$NL$
+$NL$
+
+$ ÝvCú»e[u
+$IF LENGTH(INT.ORDER_LIST)$
+	const INTINIB _kernel_intinib_table[TNUM_INTNO] = {$NL$
+	$JOINEACH intno INT.ORDER_LIST ",\n"$
+		$TAB${ ($INT.INTNO[intno]$), ($INT.INTATR[intno]$), ($INT.INTPRI[intno]$) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const INTINIB, _kernel_intinib_table);$NL$
+$END$$NL$
+$END$
+
+$ 
+$  CPUáOÇ@\
+$ 
+/*$NL$
+$SPC$*  CPU Exception Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ CPUáOnhÉÖ·éG[`FbN
+$i = 0$
+$FOREACH excno EXC.ORDER_LIST$
+$	// excnoªDEF_EXCÉÎ·éCPUáOnhÔÆµÄ³µ­È¢êiE_PARj
+	$IF !LENGTH(FIND(EXCNO_DEFEXC_VALID, EXC.EXCNO[excno]))$
+		$ERROR EXC.TEXT_LINE[excno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+	$END$
+
+$	// excnoªDEF_EXCÉæÁÄÝèÏÝÌêiE_OBJj
+	$j = 0$
+	$FOREACH excno2 EXC.ORDER_LIST$
+		$IF EXC.EXCNO[excno] == EXC.EXCNO[excno2] && j < i$
+			$ERROR EXC.TEXT_LINE[excno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+		$END$
+		$j = j + 1$
+	$END$
+
+$	// excatrªiTA_NULLjÅÈ¢êiE_RSATRj
+	$IF (EXC.EXCATR[excno] & ~TARGET_EXCATR) != 0$
+		$ERROR EXC.TEXT_LINE[excno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "excatr", EXC.EXCATR[excno], "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+	$END$
+	$i = i + 1$
+$END$
+
+$ CPUáOnhÌ½ßÌWIÈú»îñÌ¶¬
+$IF !OMIT_INITIALIZE_EXCEPTION$
+
+$ CPUáOnh
+#define TNUM_EXCNO	$LENGTH(EXC.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_excno = TNUM_EXCNO;$NL$
+$NL$
+$FOREACH excno EXC.ORDER_LIST$
+	EXCHDR_ENTRY($EXC.EXCNO[excno]$, $+EXC.EXCNO[excno]$, $EXC.EXCHDR[excno]$)$NL$
+$END$
+$NL$
+
+$ CPUáOnhú»e[u
+$IF LENGTH(EXC.ORDER_LIST)$
+	const EXCINIB _kernel_excinib_table[TNUM_EXCNO] = {$NL$
+	$JOINEACH excno EXC.ORDER_LIST ",\n"$
+		$TAB${ ($EXC.EXCNO[excno]$), ($EXC.EXCATR[excno]$), (FP)(EXC_ENTRY($EXC.EXCNO[excno]$, $EXC.EXCHDR[excno]$)) }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const EXCINIB, _kernel_excinib_table);$NL$
+$END$$NL$
+$END$
+
+$ 
+$  ñ^XNReLXgpÌX^bNÌæ
+$ 
+/*$NL$
+$SPC$*  Stack Area for Non-task Context$NL$
+$SPC$*/$NL$
+$NL$
+
+$IF !LENGTH(ICS.ORDER_LIST)$
+$	// DEF_ICSªÈ¢êÌftHglÌÝè
+	#ifdef DEFAULT_ISTK$NL$
+	$NL$
+	#define TOPPERS_ISTKSZ		DEFAULT_ISTKSZ$NL$
+	#define TOPPERS_ISTK		DEFAULT_ISTK$NL$
+	$NL$
+	#else /* DEAULT_ISTK */$NL$
+	$NL$
+	static STK_T				_kernel_istack[COUNT_STK_T(DEFAULT_ISTKSZ)];$NL$
+	#define TOPPERS_ISTKSZ		ROUND_STK_T(DEFAULT_ISTKSZ)$NL$
+	#define TOPPERS_ISTK		_kernel_istack$NL$
+	$NL$
+	#endif /* DEAULT_ISTK */$NL$
+$ELSE$
+
+$	// ÃIAPIuDEF_ICSvª¡ éiE_OBJj
+	$IF LENGTH(ICS.ORDER_LIST) > 1$
+		$ERROR$E_OBJ: $FORMAT(_("too many %1%"), "DEF_ICS")$$END$
+	$END$
+
+$	// istkszª0Èº©C^[Qbgè`ÌÅ¬liTARGET_MIN_ISTKSZjæèà
+$	// ¬³¢êiE_PARj
+	$IF ICS.ISTKSZ[1] <= 0 || (TARGET_MIN_ISTKSZ
+									&& ICS.ISTKSZ[1] < TARGET_MIN_ISTKSZ)$
+		$ERROR ICS.TEXT_LINE[1]$E_PAR: $FORMAT(_("%1% `%2%\' in %3% is too small"), "istksz", ICS.ISTKSZ[1], "DEF_ICS")$$END$
+	$END$
+
+$ 	// istkszªX^bNÌæÌTCYÆµÄ³µ­È¢êiE_PARj
+	$IF !EQ(ICS.ISTK[1], "NULL") && CHECK_STKSZ_ALIGN
+							&& (ICS.ISTKSZ[1] & (CHECK_STKSZ_ALIGN - 1))$
+		$ERROR ICS.TEXT_LINE[1]$E_PAR: $FORMAT(_("%1% `%2%\' in %3% is not aligned"), "istksz", ICS.ISTKSZ[1], "DEF_ICS")$$END$
+	$END$
+
+	$IF EQ(ICS.ISTK[1], "NULL")$
+$		// X^bNÌæÌ©®t¯
+		static STK_T				_kernel_istack[COUNT_STK_T($ICS.ISTKSZ[1]$)];$NL$
+		#define TOPPERS_ISTKSZ		ROUND_STK_T($ICS.ISTKSZ[1]$)$NL$
+		#define TOPPERS_ISTK		_kernel_istack$NL$
+	$ELSE$
+		#define TOPPERS_ISTKSZ		($ICS.ISTKSZ[1]$)$NL$
+		#define TOPPERS_ISTK		(void *)($ICS.ISTK[1]$)$NL$
+	$END$
+$END$
+$NL$
+
+$ ñ^XNReLXgpÌX^bNÌæ
+const SIZE		_kernel_istksz = TOPPERS_ISTKSZ;$NL$
+STK_T *const	_kernel_istk = TOPPERS_ISTK;$NL$
+$NL$
+#ifdef TOPPERS_ISTKPT$NL$
+STK_T *const	_kernel_istkpt = TOPPERS_ISTKPT(TOPPERS_ISTK, TOPPERS_ISTKSZ);$NL$
+#endif /* TOPPERS_ISTKPT */$NL$
+$NL$
+
+$ 
+$  J[lªèt¯éÌæ
+$ 
+/*$NL$
+$SPC$*  Memory Area Allocated by Kernel$NL$
+$SPC$*/$NL$
+$NL$
+
+$IF !LENGTH(KMM.ORDER_LIST)$
+$	// DEF_KMMªÈ¢êÌftHglÌÝè
+	#define TOPPERS_KMMSZ		0$NL$
+	#define TOPPERS_KMM			NULL$NL$
+$ELSE$
+$	// ÃIAPIuDEF_KMMvª¡ éiE_OBJj
+	$IF LENGTH(KMM.ORDER_LIST) > 1$
+		$ERROR$E_OBJ: $FORMAT(_("too many %1%"), "DEF_KMM")$$END$
+	$END$
+
+$	// kmmszª0ÈºÌêiE_PARj
+	$IF KMM.KMMSZ[1] <= 0$
+		$ERROR KMM.TEXT_LINE[1]$E_PAR: $FORMAT(_("%1% `%2%\' is zero in %3%"), "kmmsz", KMM.KMMSZ[1], "DEF_KMM")$$END$
+	$END$
+
+$ 	// kmmszªJ[lªèt¯éÌæÌTCYÆµÄ³µ­È¢êiE_PARj
+	$IF !EQ(KMM.KMM[1], "NULL") && CHECK_MB_ALIGN
+							&& (KMM.KMMSZ[1] & (CHECK_MB_ALIGN - 1))$
+		$ERROR KMM.TEXT_LINE[1]$E_PAR: $FORMAT(_("%1% `%2%\' in %3% is not aligned"), "kmmsz", KMM.KMMSZ[1], "DEF_KMM")$$END$
+	$END$
+
+	$IF EQ(KMM.KMM[1], "NULL")$
+$		// J[lªèt¯éÌæÌ©®t¯
+		static MB_T					_kernel_memory[TOPPERS_COUNT_SZ($KMM.KMMSZ[1]$, sizeof(MB_T))];$NL$
+		#define TOPPERS_KMMSZ		TOPPERS_ROUND_SZ($KMM.KMMSZ[1]$, sizeof(MB_T))$NL$
+		#define TOPPERS_KMM			_kernel_memory$NL$
+	$ELSE$
+		#define TOPPERS_KMMSZ		($KMM.KMMSZ[1]$)$NL$
+		#define TOPPERS_KMM			(void *)($KMM.KMM[1]$)$NL$
+	$END$
+$END$
+$NL$
+
+$ J[lªèt¯éÌæ
+const SIZE		_kernel_kmmsz = TOPPERS_KMMSZ;$NL$
+MB_T *const		_kernel_kmm = TOPPERS_KMM;$NL$
+$NL$
+
+$ 
+$  ^CCxgÇ
+$ 
+/*$NL$
+$SPC$*  Time Event Management$NL$
+$SPC$*/$NL$
+$NL$
+TMEVTN   _kernel_tmevt_heap[TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];$NL$
+$NL$
+
+$ 
+$  eW
+[Ìú»Ö
+$ 
+/*$NL$
+$SPC$*  Module Initialization Function$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_initialize_object(void)$NL$
+{$NL$
+$TAB$_kernel_initialize_task();$NL$
+$IF num_semid$$TAB$_kernel_initialize_semaphore();$NL$$END$
+$IF num_flgid$$TAB$_kernel_initialize_eventflag();$NL$$END$
+$IF num_dtqid$$TAB$_kernel_initialize_dataqueue();$NL$$END$
+$IF num_pdqid$$TAB$_kernel_initialize_pridataq();$NL$$END$
+$IF num_mbxid$$TAB$_kernel_initialize_mailbox();$NL$$END$
+$IF num_mpfid$$TAB$_kernel_initialize_mempfix();$NL$$END$
+$IF num_cycid$$TAB$_kernel_initialize_cyclic();$NL$$END$
+$IF num_almid$$TAB$_kernel_initialize_alarm();$NL$$END$
+$TAB$_kernel_initialize_interrupt();$NL$
+$IF num_isr$$TAB$_kernel_initialize_isr();$NL$$END$
+$TAB$_kernel_initialize_exception();$NL$
+}$NL$
+$NL$
+
+$ 
+$  ú»[`ÌÀsÖ
+$ 
+/*$NL$
+$SPC$*  Initialization Routine$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_call_inirtn(void)$NL$
+{$NL$
+$FOREACH order INI.ORDER_LIST$
+$ 	// iniatrªiTA_NULLjÅÈ¢êiE_RSATRj
+	$IF INI.INIATR[order] != 0$
+		$ERROR INI.TEXT_LINE[order]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "iniatr", INI.INIATR[order], "inirtn", INI.INIRTN[order], "ATT_INI")$$END$
+	$END$
+	$TAB$((INIRTN)($INI.INIRTN[order]$))((intptr_t)($INI.EXINF[order]$));$NL$
+$END$
+}$NL$
+$NL$
+
+$ 
+$  I¹[`ÌÀsÖ
+$ 
+/*$NL$
+$SPC$*  Termination Routine$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_call_terrtn(void)$NL$
+{$NL$
+$FOREACH rorder TER.RORDER_LIST$
+$ 	// teratrªiTA_NULLjÅÈ¢êiE_RSATRj
+	$IF TER.TERATR[rorder] != 0$
+		$ERROR TER.TEXT_LINE[rorder]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "teratr", TER.TERATR[rorder], "terrtn", TER.TERRTN[rorder], "ATT_TER")$$END$
+	$END$
+	$TAB$((TERRTN)($TER.TERRTN[rorder]$))((intptr_t)($TER.EXINF[rorder]$));$NL$
+$END$
+}$NL$
+$NL$
Index: UsbWattMeter/trunk/asp_dcre/kernel/kernel_api.csv
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/kernel_api.csv	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/kernel_api.csv	(revision 164)
@@ -0,0 +1,28 @@
+tsk,CRE_TSK,#tskid { .tskatr &exinf &task +itskpri .stksz &stk },,
+tsk,DEF_TEX,%tskid { .texatr &texrtn },0,1
+atsk,AID_TSK,.notsk,,
+sem,CRE_SEM,#semid { .sematr .isemcnt .maxsem },,
+asem,AID_SEM,.nosem,,
+flg,CRE_FLG,#flgid { .flgatr .iflgptn },,
+aflg,AID_FLG,.nosem,,
+dtq,CRE_DTQ,#dtqid { .dtqatr .dtqcnt &dtqmb },,
+adtq,AID_DTQ,.nodtq,,
+pdq,CRE_PDQ,#pdqid { .pdqatr .pdqcnt +maxdpri &pdqmb },,
+apdq,AID_PDQ,.nopdq,,
+mbx,CRE_MBX,#mbxid { .mbxatr +maxmpri &mprihd },,
+ambx,AID_MBX,.nombx,,
+mpf,CRE_MPF,#mpfid { .mpfatr .blkcnt .blksz &mpf &mpfmb },,
+ampf,AID_MPF,.nompf,,
+cyc,CRE_CYC,#cycid { .cycatr &exinf &cychdr .cyctim .cycphs },,
+acyc,AID_CYC,.nocyc,,
+alm,CRE_ALM,#almid { .almatr &exinf &almhdr },,
+aalm,AID_ALM,.noalm,,
+int,CFG_INT,.intno { .intatr +intpri },,
+isr,ATT_ISR,{ .isratr &exinf .intno &isr +isrpri },-1,
+aisr,AID_ISR,.noisr,,
+inh,DEF_INH,.inhno { .inhatr &inthdr },,
+exc,DEF_EXC,.excno { .excatr &exchdr },,
+ics,DEF_ICS,{ .istksz &istk },-1,
+kmm,DEF_KMM,{ .kmmsz &kmm },-1,
+ini,ATT_INI,{ .iniatr &exinf &inirtn },-1,
+ter,ATT_TER,{ .teratr &exinf &terrtn },-1,
Index: UsbWattMeter/trunk/asp_dcre/kernel/kernel_check.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/kernel_check.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/kernel_check.tf	(revision 164)
@@ -0,0 +1,216 @@
+$ ======================================================================
+$ 
+$   TOPPERS/ASP Kernel
+$       Toyohashi Open Platform for Embedded Real-Time Systems/
+$       Advanced Standard Profile Kernel
+$ 
+$   Copyright (C) 2008-2010 by Embedded and Real-Time Systems Laboratory
+$               Graduate School of Information Science, Nagoya Univ., JAPAN
+$  
+$   ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$   Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$   ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$   (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$        \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$       XR[hÉÜÜêÄ¢é±ÆD
+$   (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$       pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$       Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$       Ì³ÛØKèðfÚ·é±ÆD
+$   (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$       pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$       ÆD
+$     (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$         ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$     (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$         ñ·é±ÆD
+$   (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$       Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$       Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$       RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$       ÆÓ·é±ÆD
+$  
+$   {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$   æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$   ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$   AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$   ÌÓCðíÈ¢D
+$ 
+$   @(#) $Id$
+$  
+$ =====================================================================
+
+$
+$  f[^ZNVÌLMA©çVMAÖÌRs[
+$
+$FOREACH lma LMA.ORDER_LIST$
+	$start_data = SYMBOL(LMA.START_DATA[lma])$
+	$end_data = SYMBOL(LMA.END_DATA[lma])$
+	$start_idata = SYMBOL(LMA.START_IDATA[lma])$
+	$IF !LENGTH(start_data)$
+		$ERROR$$FORMAT(_("symbol '%1%' not found"), LMA.START_DATA[lma])$$END$
+	$ELIF !LENGTH(end_data)$
+		$ERROR$$FORMAT(_("symbol '%1%' not found"), LMA.END_DATA[lma])$$END$
+	$ELIF !LENGTH(start_idata)$
+		$ERROR$$FORMAT(_("symbol '%1%' not found"), LMA.START_IDATA[lma])$$END$
+	$ELSE$
+		$BCOPY(start_idata, start_data, end_data - start_data)$
+	$END$
+$END$
+
+$ 
+$  ÖÌæªÔnÌ`FbN
+$ 
+$IF CHECK_FUNC_ALIGN || CHECK_FUNC_NONNULL$
+$	// ^XNÆ^XNáO[`ÌæªÔnÌ`FbN
+	$tinib = SYMBOL("_kernel_tinib_table")$
+	$FOREACH tskid TSK.ID_LIST$
+		$task = PEEK(tinib + offsetof_TINIB_task, sizeof_FP)$
+		$IF CHECK_FUNC_ALIGN && (task & (CHECK_FUNC_ALIGN - 1)) != 0$
+			$ERROR TSK.TEXT_LINE[tskid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+				"task", TSK.TASK[tskid], tskid, "CRE_TSK")$$END$
+		$END$
+		$IF CHECK_FUNC_NONNULL && task == 0$
+			$ERROR TSK.TEXT_LINE[tskid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+				"task", TSK.TASK[tskid], tskid, "CRE_TSK")$$END$
+		$END$
+		$texrtn = PEEK(tinib + offsetof_TINIB_texrtn, sizeof_FP)$
+		$IF CHECK_FUNC_ALIGN && (texrtn & (CHECK_FUNC_ALIGN - 1)) != 0$
+			$ERROR DEF_TEX.TEXT_LINE[tskid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+				"texrtn", TSK.TEXRTN[tskid], tskid, "DEF_TEX")$$END$
+		$END$
+		$tinib = tinib + sizeof_TINIB$
+	$END$
+
+$	// üúnhÌæªÔnÌ`FbN
+	$cycinib = SYMBOL("_kernel_cycinib_table")$
+	$FOREACH cycid CYC.ID_LIST$
+		$cychdr = PEEK(cycinib + offsetof_CYCINIB_cychdr, sizeof_FP)$
+		$IF CHECK_FUNC_ALIGN && (cychdr & (CHECK_FUNC_ALIGN - 1)) != 0$
+			$ERROR CYC.TEXT_LINE[cycid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+				"cychdr", CYC.CYCHDR[cycid], cycid, "CRE_CYC")$$END$
+		$END$
+		$IF CHECK_FUNC_NONNULL && cychdr == 0$
+			$ERROR CYC.TEXT_LINE[cycid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+				"cychdr", CYC.CYCHDR[cycid], cycid, "CRE_CYC")$$END$
+		$END$
+		$cycinib = cycinib + sizeof_CYCINIB$
+	$END$
+
+$	// A[nhÌæªÔnÌ`FbN
+	$alminib = SYMBOL("_kernel_alminib_table")$
+	$FOREACH almid ALM.ID_LIST$
+		$almhdr = PEEK(alminib + offsetof_ALMINIB_almhdr, sizeof_FP)$
+		$IF CHECK_FUNC_ALIGN && (almhdr & (CHECK_FUNC_ALIGN - 1)) != 0$
+			$ERROR ALM.TEXT_LINE[almid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+				"almhdr", ALM.ALMHDR[almid], almid, "CRE_ALM")$$END$
+		$END$
+		$IF CHECK_FUNC_NONNULL && almhdr == 0$
+			$ERROR ALM.TEXT_LINE[almid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+				"almhdr", ALM.ALMHDR[almid], almid, "CRE_ALM")$$END$
+		$END$
+		$alminib = alminib + sizeof_ALMINIB$
+	$END$
+
+$	// ÝT[rX[`ÌæªÔnÌ`FbN
+	$isrinib = SYMBOL("_kernel_sisrinib_table")$
+	$FOREACH order ISR.ORDER_LIST$
+		$isr = PEEK(isrinib + offsetof_ISRINIB_isr, sizeof_FP)$
+		$IF CHECK_FUNC_ALIGN && (isr & (CHECK_FUNC_ALIGN - 1)) != 0$
+			$ERROR ISR.TEXT_LINE[order]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' in %4% is not aligned"),
+				"isr", ISR.ISR[order], "ATT_ISR")$$END$
+		$END$
+		$IF CHECK_FUNC_NONNULL && isr == 0$
+			$ERROR ISR.TEXT_LINE[order]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' in %4% is null"),
+				"isr", ISR.ISR[order], "ATT_ISR")$$END$
+		$END$
+		$isrinib = isrinib + sizeof_ISRINIB$
+	$END$
+$END$
+
+$ 
+$  X^bNÌæÌæªÔnÌ`FbN
+$ 
+$IF CHECK_STACK_ALIGN || CHECK_STACK_NONNULL$
+$	// ^XNÌX^bNÌæÌæªÔnÌ`FbN
+	$tinib = SYMBOL("_kernel_tinib_table")$
+	$FOREACH tskid TSK.ID_LIST$
+		$IF USE_TSKINICTXB$
+			$stk = GET_STK_TSKINICTXB(tinib)$
+		$ELSE$
+			$stk = PEEK(tinib + offsetof_TINIB_stk, sizeof_void_ptr)$
+		$END$
+		$IF CHECK_STACK_ALIGN && (stk & (CHECK_STACK_ALIGN - 1)) != 0$
+			$ERROR TSK.TEXT_LINE[tskid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+				"stk", TSK.STK[tskid], tskid, "CRE_TSK")$$END$
+		$END$
+		$IF CHECK_STACK_NONNULL && stk == 0$
+			$ERROR TSK.TEXT_LINE[tskid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+				"stk", TSK.STK[tskid], tskid, "CRE_TSK")$$END$
+		$END$
+		$tinib = tinib + sizeof_TINIB$
+	$END$
+
+$	// ñ^XNReLXgpÌX^bNÌæÌæªÔnÌ`FbN
+	$istk = PEEK(SYMBOL("_kernel_istk"), sizeof_void_ptr)$
+	$IF CHECK_STACK_ALIGN && (istk & (CHECK_STACK_ALIGN - 1)) != 0$
+		$ERROR ICS.TEXT_LINE[1]$E_PAR: 
+			$FORMAT(_("%1% `%2%\' in %3% is not aligned"),
+			"istk", ICS.ISTK[1], "DEF_ICS")$$END$
+	$END$
+	$IF CHECK_STACK_NONNULL && istk == 0$
+		$ERROR ICS.TEXT_LINE[1]$E_PAR: 
+			$FORMAT(_("%1% `%2%\' in %3% is null"),
+			"istk", ICS.ISTK[1], "DEF_ICS")$$END$
+	$END$
+$END$
+
+$ 
+$  Åè·v[ÌæÌæªÔnÌ`FbN
+$ 
+$IF CHECK_MPF_ALIGN || CHECK_MPF_NONNULL$
+$	// Åè·v[ÌæÌæªÔnÌ`FbN
+	$mpfinib = SYMBOL("_kernel_mpfinib_table")$
+	$FOREACH mpfid MPF.ID_LIST$
+		$mpf = PEEK(mpfinib + offsetof_MPFINIB_mpf, sizeof_void_ptr)$
+		$IF CHECK_MPF_ALIGN && (mpf & (CHECK_MPF_ALIGN - 1)) != 0$
+			$ERROR MPF.TEXT_LINE[mpfid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+				"mpf", MPF.MPF[mpfid], mpfid, "CRE_MPF")$$END$
+		$END$
+		$IF CHECK_MPF_NONNULL && mpf == 0$
+			$ERROR MPF.TEXT_LINE[mpfid]$E_PAR: 
+				$FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+				"mpf", MPF.MPF[mpfid], mpfid, "CRE_MPF")$$END$
+		$END$
+		$mpfinib = mpfinib + sizeof_MPFINIB$
+	$END$
+$END$
+
+$ 
+$  J[lªèt¯éÌæÌæªÔnÌ`FbN
+$ 
+$IF CHECK_MB_ALIGN$
+$	// J[lªèt¯éÌæÌæªÔnÌ`FbN
+	$kmm = PEEK(SYMBOL("_kernel_kmm"), sizeof_void_ptr)$
+	$IF CHECK_MB_ALIGN && (kmm & (CHECK_MB_ALIGN - 1)) != 0$
+		$ERROR KMM.TEXT_LINE[1]$E_PAR: 
+			$FORMAT(_("%1% `%2%\' in %3% is not aligned"),
+			"kmm", KMM.KMM[1], "DEF_KMM")$$END$
+	$END$
+$END$
Index: UsbWattMeter/trunk/asp_dcre/kernel/kernel_def.csv
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/kernel_def.csv	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/kernel_def.csv	(revision 164)
@@ -0,0 +1,119 @@
+SIL_ENDIAN_BIG,#defined(SIL_ENDIAN_BIG)
+SIL_ENDIAN_LITTLE,#defined(SIL_ENDIAN_LITTLE)
+TA_NULL,TA_NULL
+TA_ACT,TA_ACT
+TA_TPRI,TA_TPRI
+TA_MPRI,TA_MPRI
+TA_WMUL,TA_WMUL
+TA_CLR,TA_CLR
+TA_STA,TA_STA
+TA_NONKERNEL,TA_NONKERNEL
+TA_ENAINT,TA_ENAINT
+TA_EDGE,TA_EDGE
+TMIN_TPRI,TMIN_TPRI,signed
+TMAX_TPRI,TMAX_TPRI,signed
+TMIN_DPRI,TMIN_DPRI,signed
+TMAX_DPRI,TMAX_DPRI,signed
+TMIN_MPRI,TMIN_MPRI,signed
+TMAX_MPRI,TMAX_MPRI,signed
+TMIN_ISRPRI,TMIN_ISRPRI,signed
+TMAX_ISRPRI,TMAX_ISRPRI,signed
+TBIT_TEXPTN,TBIT_TEXPTN
+TBIT_FLGPTN,TBIT_FLGPTN
+TMAX_MAXSEM,TMAX_MAXSEM
+TMAX_RELTIM,TMAX_RELTIM
+TMIN_INTPRI,TMIN_INTPRI,signed
+OMIT_INITIALIZE_INTERRUPT,#defined(OMIT_INITIALIZE_INTERRUPT)
+OMIT_INITIALIZE_EXCEPTION,#defined(OMIT_INITIALIZE_EXCEPTION)
+USE_TSKINICTXB,#defined(USE_TSKINICTXB)
+TARGET_TSKATR,#defined(TARGET_TSKATR),,TARGET_TSKATR
+TARGET_INTATR,#defined(TARGET_INTATR),,TARGET_INTATR
+TARGET_INHATR,#defined(TARGET_INHATR),,TARGET_INHATR
+TARGET_ISRATR,#defined(TARGET_ISRATR),,TARGET_ISRATR
+TARGET_EXCATR,#defined(TARGET_EXCATR),,TARGET_EXCATR
+TARGET_MIN_STKSZ,#defined(TARGET_MIN_STKSZ),,TARGET_MIN_STKSZ
+TARGET_MIN_ISTKSZ,#defined(TARGET_MIN_ISTKSZ),,TARGET_MIN_ISTKSZ
+CHECK_STKSZ_ALIGN,#defined(CHECK_STKSZ_ALIGN),,CHECK_STKSZ_ALIGN
+CHECK_FUNC_ALIGN,#defined(CHECK_FUNC_ALIGN),,CHECK_FUNC_ALIGN
+CHECK_FUNC_NONNULL,#defined(CHECK_FUNC_NONNULL)
+CHECK_STACK_ALIGN,#defined(CHECK_STACK_ALIGN),,CHECK_STACK_ALIGN
+CHECK_STACK_NONNULL,#defined(CHECK_STACK_NONNULL)
+CHECK_MPF_ALIGN,#defined(CHECK_MPF_ALIGN),,CHECK_MPF_ALIGN
+CHECK_MPF_NONNULL,#defined(CHECK_MPF_NONNULL)
+CHECK_MB_ALIGN,#defined(CHECK_MB_ALIGN),,CHECK_MB_ALIGN
+sizeof_ID,sizeof(ID)
+sizeof_uint_t,sizeof(uint_t)
+sizeof_SIZE,sizeof(SIZE)
+sizeof_ATR,sizeof(ATR)
+sizeof_PRI,sizeof(PRI)
+sizeof_void_ptr,sizeof(void*)
+sizeof_VP,sizeof(void*)
+sizeof_intptr_t,sizeof(intptr_t)
+sizeof_FP,sizeof(FP)
+sizeof_INHNO,sizeof(INHNO)
+sizeof_INTNO,sizeof(INTNO)
+sizeof_EXCNO,sizeof(EXCNO)
+sizeof_TINIB,sizeof(TINIB)
+offsetof_TINIB_tskatr,"offsetof(TINIB,tskatr)"
+offsetof_TINIB_exinf,"offsetof(TINIB,exinf)"
+offsetof_TINIB_task,"offsetof(TINIB,task)"
+offsetof_TINIB_ipriority,"offsetof(TINIB,ipriority)"
+offsetof_TINIB_stksz,#!defined(USE_TSKINICTXB),,"offsetof(TINIB,stksz)"
+offsetof_TINIB_stk,#!defined(USE_TSKINICTXB),,"offsetof(TINIB,stk)"
+offsetof_TINIB_texatr,"offsetof(TINIB,texatr)"
+offsetof_TINIB_texrtn,"offsetof(TINIB,texrtn)"
+sizeof_SEMINIB,sizeof(SEMINIB)
+offsetof_SEMINIB_sematr,"offsetof(SEMINIB,sematr)"
+offsetof_SEMINIB_isemcnt,"offsetof(SEMINIB,isemcnt)"
+offsetof_SEMINIB_maxsem,"offsetof(SEMINIB,maxsem)"
+sizeof_FLGPTN,sizeof(FLGPTN)
+sizeof_FLGINIB,sizeof(FLGINIB)
+offsetof_FLGINIB_flgatr,"offsetof(FLGINIB,flgatr)"
+offsetof_FLGINIB_iflgptn,"offsetof(FLGINIB,iflgptn)"
+sizeof_DTQINIB,sizeof(DTQINIB)
+offsetof_DTQINIB_dtqatr,"offsetof(DTQINIB,dtqatr)"
+offsetof_DTQINIB_dtqcnt,"offsetof(DTQINIB,dtqcnt)"
+offsetof_DTQINIB_p_dtqmb,"offsetof(DTQINIB,p_dtqmb)"
+sizeof_PDQINIB,sizeof(PDQINIB)
+offsetof_PDQINIB_pdqatr,"offsetof(PDQINIB,pdqatr)"
+offsetof_PDQINIB_pdqcnt,"offsetof(PDQINIB,pdqcnt)"
+offsetof_PDQINIB_maxdpri,"offsetof(PDQINIB,maxdpri)"
+offsetof_PDQINIB_p_pdqmb,"offsetof(PDQINIB,p_pdqmb)"
+sizeof_MBXINIB,sizeof(MBXINIB)
+offsetof_MBXINIB_mbxatr,"offsetof(MBXINIB,mbxatr)"
+offsetof_MBXINIB_maxmpri,"offsetof(MBXINIB,maxmpri)"
+sizeof_MPFINIB,sizeof(MPFINIB)
+offsetof_MPFINIB_mpfatr,"offsetof(MPFINIB,mpfatr)"
+offsetof_MPFINIB_blkcnt,"offsetof(MPFINIB,blkcnt)"
+offsetof_MPFINIB_blksz,"offsetof(MPFINIB,blksz)"
+offsetof_MPFINIB_mpf,"offsetof(MPFINIB,mpf)"
+offsetof_MPFINIB_p_mpfmb,"offsetof(MPFINIB,p_mpfmb)"
+sizeof_CYCINIB,sizeof(CYCINIB)
+offsetof_CYCINIB_cycatr,"offsetof(CYCINIB,cycatr)"
+offsetof_CYCINIB_exinf,"offsetof(CYCINIB,exinf)"
+offsetof_CYCINIB_cychdr,"offsetof(CYCINIB,cychdr)"
+offsetof_CYCINIB_cyctim,"offsetof(CYCINIB,cyctim)"
+offsetof_CYCINIB_cycphs,"offsetof(CYCINIB,cycphs)"
+sizeof_ALMINIB,sizeof(ALMINIB)
+offsetof_ALMINIB_almatr,"offsetof(ALMINIB,almatr)"
+offsetof_ALMINIB_exinf,"offsetof(ALMINIB,exinf)"
+offsetof_ALMINIB_almhdr,"offsetof(ALMINIB,almhdr)"
+sizeof_ISRINIB,sizeof(ISRINIB)
+offsetof_ISRINIB_isratr,"offsetof(ISRINIB,isratr)"
+offsetof_ISRINIB_exinf,"offsetof(ISRINIB,exinf)"
+offsetof_ISRINIB_intno,"offsetof(ISRINIB,intno)"
+offsetof_ISRINIB_p_isr_queue,"offsetof(ISRINIB,p_isr_queue)"
+offsetof_ISRINIB_isr,"offsetof(ISRINIB,isr)"
+offsetof_ISRINIB_isrpri,"offsetof(ISRINIB,isrpri)"
+sizeof_INHINIB,#!defined(OMIT_INITIALIZE_INTERRUPT),,sizeof(INHINIB)
+offset_INHINIB_inhno,#!defined(OMIT_INITIALIZE_INTERRUPT),,"offsetof(INHINIB,inhno)"
+offset_INHINIB_inhatr,#!defined(OMIT_INITIALIZE_INTERRUPT),,"offsetof(INHINIB,inhatr)"
+offset_INHINIB_int_entry,#!defined(OMIT_INITIALIZE_INTERRUPT),,"offsetof(INHINIB,int_entry)"
+sizeof_INTINIB,#!defined(OMIT_INITIALIZE_INTERRUPT),,sizeof(INTINIB)
+offset_INTINIB_intno,#!defined(OMIT_INITIALIZE_INTERRUPT),,"offsetof(INTINIB,intno)"
+offset_INTINIB_intatr,#!defined(OMIT_INITIALIZE_INTERRUPT),,"offsetof(INTINIB,intatr)"
+offset_INTINIB_intpri,#!defined(OMIT_INITIALIZE_INTERRUPT),,"offsetof(INTINIB,intpri)"
+sizeof_EXCINIB,#!defined(OMIT_INITIALIZE_EXCEPTION),,sizeof(EXCINIB)
+offset_EXCINIB_excno,#!defined(OMIT_INITIALIZE_EXCEPTION),,"offsetof(EXCINIB,excno)"
+offset_EXCINIB_excatr,#!defined(OMIT_INITIALIZE_EXCEPTION),,"offsetof(EXCINIB,excatr)"
+offset_EXCINIB_exc_entry,#!defined(OMIT_INITIALIZE_EXCEPTION),,"offsetof(EXCINIB,exc_entry)"
Index: UsbWattMeter/trunk/asp_dcre/kernel/kernel_impl.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/kernel_impl.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/kernel_impl.h	(revision 164)
@@ -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) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		TOPPERS/ASPJ[làü¯Wwb_t@C
+ *
+ *  ±Ìwb_t@CÍCJ[lð\¬·évOÌ\[Xt@C
+ *  ÅK¸CN[h·é×«Wwb_t@CÅ éD
+ *
+ *  AZu¾êÌ\[Xt@C©ç±Ìt@CðCN[h·é
+ *  ÍCTOPPERS_MACRO_ONLYðè`µÄ¨­D±êÉæèC}Nè`ÈOð
+ *  ­æ¤ÉÈÁÄ¢éD
+ */
+
+#ifndef TOPPERS_KERNEL_IMPL_H
+#define TOPPERS_KERNEL_IMPL_H
+
+/*
+ *  J[lÌà¯Ê¼Ìl[
+ */
+#include "kernel_rename.h"
+
+/*
+ *  AvP[VÆ¤ÊÌwb_t@C
+ */
+#include <kernel.h>
+
+/*
+ *  VXeO@\Ì½ßÌè`
+ */
+#include <t_syslog.h>
+
+/*
+ *  ^LXgðs¤}NÌè`
+ */
+#ifndef CAST
+#define CAST(type, val)		((type)(val))
+#endif /* CAST */
+
+/*
+ *  ^[QbgË¶îñÌè`
+ */
+#include "target_config.h"
+
+/*
+ *  ·×ÄÌÖðRpC·é½ßÌè`
+ */
+#ifdef ALLFUNC
+#include "allfunc.h"
+#endif /* ALLFUNC */
+
+/*
+ *  rbgtB[hÅÌ³µ®^
+ *
+ *  8rbgÈºÌÌrbgtB[hÅC³µ®lðÛµ½¢ê
+ *  Ép¢é×«f[^^DANSI CÅÍCrbgtB[hÌf[^^ÉÍ
+ *  intÆunsigned intµ©³êÈ¢½ßCftHgÌè`Íunsigned
+ *  intÆµÄ¢éªC^[Qbg¨æÑc[Ë¶ÅCunsigned charÜ½Í
+ *  unsigned shortÉè`µ½ûªø¦ªÇ¢êª éD
+ */
+#ifndef BIT_FIELD_UINT
+#define BIT_FIELD_UINT		unsigned int
+#endif /* BIT_FIELD_UINT */
+
+/*
+ *  rbgtB[hÅÌu[^
+ *
+ *  1rbgÌrbgtB[hÅCu[lðÛµ½¢êÉp¢é×«
+ *  f[^^DftHgÅÍBIT_FIELD_UINTÆ¯êÉè`µÄ¢éªCu[
+ *  lðÛ·é±Æð¾¦·é½ßÉÊÌ¼ÌÆµÄ¢éD
+ */
+#ifndef BIT_FIELD_BOOL
+#define BIT_FIELD_BOOL		BIT_FIELD_UINT
+#endif /* BIT_FIELD_BOOL */
+
+/*
+ *  IuWFNgIDÌÅ¬lÌè`
+ */
+#define TMIN_TSKID		1		/* ^XNIDÌÅ¬l */
+#define TMIN_SEMID		1		/* Z}tHIDÌÅ¬l */
+#define TMIN_FLGID		1		/* tOIDÌÅ¬l */
+#define TMIN_DTQID		1		/* f[^L
+[IDÌÅ¬l */
+#define TMIN_PDQID		1		/* Dæxf[^L
+[IDÌÅ¬l */
+#define TMIN_MBXID		1		/* [{bNXIDÌÅ¬l */
+#define TMIN_MPFID		1		/* Åè·v[IDÌÅ¬l */
+#define TMIN_CYCID		1		/* üúnhIDÌÅ¬l */
+#define TMIN_ALMID		1		/* A[nhIDÌÅ¬l */
+#define TMIN_ISRID		1		/* ÝT[rX[`IDÌÅ¬l */
+
+/*
+ *  DæxÌiKÌè`
+ */
+#define TNUM_TPRI		(TMAX_TPRI - TMIN_TPRI + 1)
+#define TNUM_MPRI		(TMAX_MPRI - TMIN_MPRI + 1)
+#define TNUM_INTPRI		(TMAX_INTPRI - TMIN_INTPRI + 1)
+
+/*
+ *  J[làÅgp·é®«Ìè`
+ */
+#define TA_NOEXS		((ATR)(-1))			/* ¢o^óÔ */
+
+#ifndef TA_MEMALLOC
+#define TA_MEMALLOC		UINT_C(0x8000)		/* ÌæðJ[lÅmÛ */
+#endif /* TA_MEMALLOC */
+#ifndef TA_MBALLOC
+#define TA_MBALLOC		UINT_C(0x4000)		/* ÇÌæðJ[lÅmÛ */
+#endif /* TA_MBALLOC */
+
+/*
+ *  ^[Qbgè`ÌG[`FbN}NÌftHglÌè`
+ */
+#ifndef TARGET_TSKATR
+#define TARGET_TSKATR		0U		/* ^[Qbgè`Ì^XN®« */
+#endif /* TARGET_TSKATR */
+
+#ifndef TARGET_ISRATR
+#define TARGET_ISRATR		0U		/* ^[Qbgè`ÌISR®« */
+#endif /* TARGET_ISRATR */
+
+/*
+ *  wb_t@Cð½È¢W
+[ÌÖEÏÌé¾
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  eW
+[Ìú»ikernel_cfg.cj
+ */
+extern void	initialize_object(void);
+
+/*
+ *  ú»[`ÌÀsikernel_cfg.cj
+ */
+extern void	call_inirtn(void);
+
+/*
+ *  I¹[`ÌÀsikernel_cfg.cj
+ */
+extern void	call_terrtn(void);
+
+/*
+ *  ñ^XNReLXgpÌX^bNÌæikernel_cfg.cj
+ */
+extern const SIZE	istksz;		/* X^bNÌæÌTCYiÛß½lj */
+extern STK_T *const	istk;		/* X^bNÌæÌæªÔn */
+#ifdef TOPPERS_ISTKPT
+extern STK_T *const	istkpt;		/* X^bN|C^Ìúl */
+#endif /* TOPPERS_ISTKPT */
+
+/*
+ *  J[lªèt¯éÌæikernel_cfg.cj
+ */
+extern const SIZE	kmmsz;		/* J[lªèt¯éÌæÌTCY */
+extern MB_T *const	kmm;		/* J[lªèt¯éÌæÌæªÔn */
+
+/*
+ *  J[l®ìóÔtOistartup.cj
+ */
+extern bool_t	kerflg;
+
+/*
+ *  J[lÌN®istartup.cj
+ */
+extern void	sta_ker(void);
+
+/*
+ *  J[lÌI¹istartup.cj
+ */
+extern void	exit_kernel(void);
+
+/*
+ *  J[lÌèt¯éÌæÌÇistartup.cj
+ */
+extern void initialize_kmm(void);
+extern void *kernel_malloc(SIZE size);
+extern void kernel_free(void *ptr);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_KERNEL_IMPL_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/kernel_int.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/kernel_int.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/kernel_int.h	(revision 164)
@@ -0,0 +1,80 @@
+/*
+ *  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-2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		kernel_cfg.ci¨æÑcfg1_out.cjpwb_t@C
+ */
+
+#ifndef TOPPERS_KERNEL_INT_H
+#define TOPPERS_KERNEL_INT_H
+
+/*
+ *  J[lWwb_t@C
+ */
+#include "kernel_impl.h"
+
+/*
+ *  J[lÌewb_t@C
+ */
+#include "task.h"
+#include "semaphore.h"
+#include "eventflag.h"
+#include "dataqueue.h"
+#include "pridataq.h"
+#include "mailbox.h"
+#include "mempfix.h"
+#include "cyclic.h"
+#include "alarm.h"
+#include "interrupt.h"
+#include "exception.h"
+#include "time_event.h"
+
+/*
+ *  l[µ½V{ð³Éß·½ßÌwb_t@C
+ */
+#include "kernel_unrename.h"
+
+#endif /* TOPPERS_KERNEL_INT_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/kernel_rename.def
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/kernel_rename.def	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/kernel_rename.def	(revision 164)
@@ -0,0 +1,194 @@
+# startup.c
+kerflg
+exit_kernel
+initialize_kmm
+kernel_malloc
+kernel_free
+
+# kmem.c
+kmem_setup
+kmem_allocate
+kmem_allocatable
+kmem_release
+kmem_status
+
+# task.c
+p_runtsk
+p_schedtsk
+reqflg
+ipmflg
+disdsp
+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
+call_texrtn
+calltex
+
+# wait.c
+make_wait_tmout
+wait_complete
+wait_tmout
+wait_tmout_ok
+wait_release
+wobj_make_wait
+wobj_make_wait_tmout
+init_wait_queue
+
+# time_event.c
+current_time
+min_time
+next_time
+next_subtime
+last_index
+initialize_tmevt
+tmevt_up
+tmevt_down
+tmevtb_insert
+tmevtb_delete
+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
+
+# mailbox.c
+free_mbxcb
+initialize_mailbox
+
+# mempfix.c
+free_mpfcb
+initialize_mempfix
+get_mpf_block
+
+# mempvar.c
+initialize_mempvar
+
+# cyclic.c
+free_cyccb
+initialize_cyclic
+call_cychdr
+
+# alarm.c
+free_almcb
+initialize_alarm
+call_almhdr
+
+# interrupt.c
+free_isrcb
+initialize_isr
+inthdr_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
+tcb_table
+torder_table
+tmax_semid
+tmax_ssemid
+seminib_table
+aseminib_table
+semcb_table
+tmax_flgid
+tmax_sflgid
+flginib_table
+aflginib_table
+flgcb_table
+tmax_dtqid
+tmax_adtqid
+dtqinib_table
+sdtqinib_table
+dtqcb_table
+tmax_pdqid
+tmax_apdqid
+pdqinib_table
+apdqinib_table
+pdqcb_table
+tmax_mbxid
+tmax_smbxid
+mbxinib_table
+ambxinib_table
+mbxcb_table
+tmax_mpfid
+tmax_smpfid
+mpfinib_table
+ampfinib_table
+mpfcb_table
+tmax_mplid
+tmax_smplid
+mplinib_table
+amplinib_table
+mplcb_table
+tmax_cycid
+tmax_scycid
+cycinib_table
+acycinib_table
+cyccb_table
+tmax_almid
+tmax_salmid
+alminib_table
+aalminib_table
+almcb_table
+tnum_isr_queue
+isr_queue_table
+isr_queue_list
+tmax_isrid
+tnum_sisr
+sisrinib_table
+aisrinib_table
+isrcb_table
+tnum_inhno
+inhinib_table
+tnum_intno
+intinib_table
+tnum_excno
+excinib_table
+tmevt_heap
+istksz
+istk
+istkpt
+kmmsz
+kmm
+
+INCLUDE "target"
Index: UsbWattMeter/trunk/asp_dcre/kernel/kernel_rename.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/kernel_rename.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/kernel_rename.h	(revision 164)
@@ -0,0 +1,430 @@
+/* This file is generated from kernel_rename.def by genrename. */
+
+#ifndef TOPPERS_KERNEL_RENAME_H
+#define TOPPERS_KERNEL_RENAME_H
+
+/*
+ *  startup.c
+ */
+#define kerflg						_kernel_kerflg
+#define exit_kernel					_kernel_exit_kernel
+#define initialize_kmm				_kernel_initialize_kmm
+#define kernel_malloc				_kernel_kernel_malloc
+#define kernel_free					_kernel_kernel_free
+
+/*
+ *  task.c
+ */
+#define p_runtsk					_kernel_p_runtsk
+#define p_schedtsk					_kernel_p_schedtsk
+#define reqflg						_kernel_reqflg
+#define ipmflg						_kernel_ipmflg
+#define disdsp						_kernel_disdsp
+#define dspflg						_kernel_dspflg
+#define ready_queue					_kernel_ready_queue
+#define ready_primap				_kernel_ready_primap
+#define free_tcb					_kernel_free_tcb
+#define initialize_task				_kernel_initialize_task
+#define search_schedtsk				_kernel_search_schedtsk
+#define make_runnable				_kernel_make_runnable
+#define make_non_runnable			_kernel_make_non_runnable
+#define make_dormant				_kernel_make_dormant
+#define make_active					_kernel_make_active
+#define change_priority				_kernel_change_priority
+#define rotate_ready_queue			_kernel_rotate_ready_queue
+#define call_texrtn					_kernel_call_texrtn
+#define calltex						_kernel_calltex
+
+/*
+ *  wait.c
+ */
+#define make_wait_tmout				_kernel_make_wait_tmout
+#define wait_complete				_kernel_wait_complete
+#define wait_tmout					_kernel_wait_tmout
+#define wait_tmout_ok				_kernel_wait_tmout_ok
+#define wait_release				_kernel_wait_release
+#define wobj_make_wait				_kernel_wobj_make_wait
+#define wobj_make_wait_tmout		_kernel_wobj_make_wait_tmout
+#define init_wait_queue				_kernel_init_wait_queue
+
+/*
+ *  time_event.c
+ */
+#define current_time				_kernel_current_time
+#define min_time					_kernel_min_time
+#define next_time					_kernel_next_time
+#define next_subtime				_kernel_next_subtime
+#define last_index					_kernel_last_index
+#define initialize_tmevt			_kernel_initialize_tmevt
+#define tmevt_up					_kernel_tmevt_up
+#define tmevt_down					_kernel_tmevt_down
+#define tmevtb_insert				_kernel_tmevtb_insert
+#define tmevtb_delete				_kernel_tmevtb_delete
+#define tmevt_lefttim				_kernel_tmevt_lefttim
+#define signal_time					_kernel_signal_time
+
+/*
+ *  semaphore.c
+ */
+#define free_semcb					_kernel_free_semcb
+#define initialize_semaphore		_kernel_initialize_semaphore
+
+/*
+ *  eventflag.c
+ */
+#define free_flgcb					_kernel_free_flgcb
+#define initialize_eventflag		_kernel_initialize_eventflag
+#define check_flg_cond				_kernel_check_flg_cond
+
+/*
+ *  dataqueue.c
+ */
+#define free_dtqcb					_kernel_free_dtqcb
+#define initialize_dataqueue		_kernel_initialize_dataqueue
+#define enqueue_data				_kernel_enqueue_data
+#define force_enqueue_data			_kernel_force_enqueue_data
+#define dequeue_data				_kernel_dequeue_data
+#define send_data					_kernel_send_data
+#define force_send_data				_kernel_force_send_data
+#define receive_data				_kernel_receive_data
+
+/*
+ *  pridataq.c
+ */
+#define free_pdqcb					_kernel_free_pdqcb
+#define initialize_pridataq			_kernel_initialize_pridataq
+#define enqueue_pridata				_kernel_enqueue_pridata
+#define dequeue_pridata				_kernel_dequeue_pridata
+#define send_pridata				_kernel_send_pridata
+#define receive_pridata				_kernel_receive_pridata
+
+/*
+ *  mailbox.c
+ */
+#define free_mbxcb					_kernel_free_mbxcb
+#define initialize_mailbox			_kernel_initialize_mailbox
+
+/*
+ *  mempfix.c
+ */
+#define free_mpfcb					_kernel_free_mpfcb
+#define initialize_mempfix			_kernel_initialize_mempfix
+#define get_mpf_block				_kernel_get_mpf_block
+
+/*
+ *  cyclic.c
+ */
+#define free_cyccb					_kernel_free_cyccb
+#define initialize_cyclic			_kernel_initialize_cyclic
+#define call_cychdr					_kernel_call_cychdr
+
+/*
+ *  alarm.c
+ */
+#define free_almcb					_kernel_free_almcb
+#define initialize_alarm			_kernel_initialize_alarm
+#define call_almhdr					_kernel_call_almhdr
+
+/*
+ *  interrupt.c
+ */
+#define free_isrcb					_kernel_free_isrcb
+#define initialize_isr				_kernel_initialize_isr
+#define call_isr					_kernel_call_isr
+#define initialize_interrupt		_kernel_initialize_interrupt
+
+/*
+ *  exception.c
+ */
+#define initialize_exception		_kernel_initialize_exception
+
+/*
+ *  kernel_cfg.c
+ */
+#define initialize_object			_kernel_initialize_object
+#define call_inirtn					_kernel_call_inirtn
+#define call_terrtn					_kernel_call_terrtn
+#define tmax_tskid					_kernel_tmax_tskid
+#define tmax_stskid					_kernel_tmax_stskid
+#define tinib_table					_kernel_tinib_table
+#define atinib_table				_kernel_atinib_table
+#define tcb_table					_kernel_tcb_table
+#define torder_table				_kernel_torder_table
+#define tmax_semid					_kernel_tmax_semid
+#define tmax_ssemid					_kernel_tmax_ssemid
+#define seminib_table				_kernel_seminib_table
+#define aseminib_table				_kernel_aseminib_table
+#define semcb_table					_kernel_semcb_table
+#define tmax_flgid					_kernel_tmax_flgid
+#define tmax_sflgid					_kernel_tmax_sflgid
+#define flginib_table				_kernel_flginib_table
+#define aflginib_table				_kernel_aflginib_table
+#define flgcb_table					_kernel_flgcb_table
+#define tmax_dtqid					_kernel_tmax_dtqid
+#define tmax_sdtqid					_kernel_tmax_sdtqid
+#define dtqinib_table				_kernel_dtqinib_table
+#define adtqinib_table				_kernel_adtqinib_table
+#define dtqcb_table					_kernel_dtqcb_table
+#define tmax_pdqid					_kernel_tmax_pdqid
+#define tmax_spdqid					_kernel_tmax_spdqid
+#define pdqinib_table				_kernel_pdqinib_table
+#define apdqinib_table				_kernel_apdqinib_table
+#define pdqcb_table					_kernel_pdqcb_table
+#define tmax_mbxid					_kernel_tmax_mbxid
+#define tmax_smbxid					_kernel_tmax_smbxid
+#define mbxinib_table				_kernel_mbxinib_table
+#define ambxinib_table				_kernel_ambxinib_table
+#define mbxcb_table					_kernel_mbxcb_table
+#define tmax_mpfid					_kernel_tmax_mpfid
+#define tmax_smpfid					_kernel_tmax_smpfid
+#define mpfinib_table				_kernel_mpfinib_table
+#define ampfinib_table				_kernel_ampfinib_table
+#define mpfcb_table					_kernel_mpfcb_table
+#define tmax_cycid					_kernel_tmax_cycid
+#define tmax_scycid					_kernel_tmax_scycid
+#define cycinib_table				_kernel_cycinib_table
+#define acycinib_table				_kernel_acycinib_table
+#define cyccb_table					_kernel_cyccb_table
+#define tmax_almid					_kernel_tmax_almid
+#define tmax_salmid					_kernel_tmax_salmid
+#define alminib_table				_kernel_alminib_table
+#define aalminib_table				_kernel_aalminib_table
+#define almcb_table					_kernel_almcb_table
+#define tnum_isr_queue				_kernel_tnum_isr_queue
+#define isr_queue_table				_kernel_isr_queue_table
+#define isr_queue_list				_kernel_isr_queue_list
+#define tmax_isrid					_kernel_tmax_isrid
+#define tnum_sisr					_kernel_tnum_sisr
+#define sisrinib_table				_kernel_sisrinib_table
+#define aisrinib_table				_kernel_aisrinib_table
+#define isrcb_table					_kernel_isrcb_table
+#define tnum_inhno					_kernel_tnum_inhno
+#define inhinib_table				_kernel_inhinib_table
+#define tnum_intno					_kernel_tnum_intno
+#define intinib_table				_kernel_intinib_table
+#define tnum_excno					_kernel_tnum_excno
+#define excinib_table				_kernel_excinib_table
+#define tmevt_heap					_kernel_tmevt_heap
+#define istksz						_kernel_istksz
+#define istk						_kernel_istk
+#define istkpt						_kernel_istkpt
+#define kmmsz						_kernel_kmmsz
+#define kmm							_kernel_kmm
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ *  startup.c
+ */
+#define _kerflg						__kernel_kerflg
+#define _exit_kernel				__kernel_exit_kernel
+#define _initialize_kmm				__kernel_initialize_kmm
+#define _kernel_malloc				__kernel_kernel_malloc
+#define _kernel_free				__kernel_kernel_free
+
+/*
+ *  task.c
+ */
+#define _p_runtsk					__kernel_p_runtsk
+#define _p_schedtsk					__kernel_p_schedtsk
+#define _reqflg						__kernel_reqflg
+#define _ipmflg						__kernel_ipmflg
+#define _disdsp						__kernel_disdsp
+#define _dspflg						__kernel_dspflg
+#define _ready_queue				__kernel_ready_queue
+#define _ready_primap				__kernel_ready_primap
+#define _free_tcb					__kernel_free_tcb
+#define _initialize_task			__kernel_initialize_task
+#define _search_schedtsk			__kernel_search_schedtsk
+#define _make_runnable				__kernel_make_runnable
+#define _make_non_runnable			__kernel_make_non_runnable
+#define _make_dormant				__kernel_make_dormant
+#define _make_active				__kernel_make_active
+#define _change_priority			__kernel_change_priority
+#define _rotate_ready_queue			__kernel_rotate_ready_queue
+#define _call_texrtn				__kernel_call_texrtn
+#define _calltex					__kernel_calltex
+
+/*
+ *  wait.c
+ */
+#define _make_wait_tmout			__kernel_make_wait_tmout
+#define _wait_complete				__kernel_wait_complete
+#define _wait_tmout					__kernel_wait_tmout
+#define _wait_tmout_ok				__kernel_wait_tmout_ok
+#define _wait_release				__kernel_wait_release
+#define _wobj_make_wait				__kernel_wobj_make_wait
+#define _wobj_make_wait_tmout		__kernel_wobj_make_wait_tmout
+#define _init_wait_queue			__kernel_init_wait_queue
+
+/*
+ *  time_event.c
+ */
+#define _current_time				__kernel_current_time
+#define _min_time					__kernel_min_time
+#define _next_time					__kernel_next_time
+#define _next_subtime				__kernel_next_subtime
+#define _last_index					__kernel_last_index
+#define _initialize_tmevt			__kernel_initialize_tmevt
+#define _tmevt_up					__kernel_tmevt_up
+#define _tmevt_down					__kernel_tmevt_down
+#define _tmevtb_insert				__kernel_tmevtb_insert
+#define _tmevtb_delete				__kernel_tmevtb_delete
+#define _tmevt_lefttim				__kernel_tmevt_lefttim
+#define _signal_time				__kernel_signal_time
+
+/*
+ *  semaphore.c
+ */
+#define _free_semcb					__kernel_free_semcb
+#define _initialize_semaphore		__kernel_initialize_semaphore
+
+/*
+ *  eventflag.c
+ */
+#define _free_flgcb					__kernel_free_flgcb
+#define _initialize_eventflag		__kernel_initialize_eventflag
+#define _check_flg_cond				__kernel_check_flg_cond
+
+/*
+ *  dataqueue.c
+ */
+#define _free_dtqcb					__kernel_free_dtqcb
+#define _initialize_dataqueue		__kernel_initialize_dataqueue
+#define _enqueue_data				__kernel_enqueue_data
+#define _force_enqueue_data			__kernel_force_enqueue_data
+#define _dequeue_data				__kernel_dequeue_data
+#define _send_data					__kernel_send_data
+#define _force_send_data			__kernel_force_send_data
+#define _receive_data				__kernel_receive_data
+
+/*
+ *  pridataq.c
+ */
+#define _free_pdqcb					__kernel_free_pdqcb
+#define _initialize_pridataq		__kernel_initialize_pridataq
+#define _enqueue_pridata			__kernel_enqueue_pridata
+#define _dequeue_pridata			__kernel_dequeue_pridata
+#define _send_pridata				__kernel_send_pridata
+#define _receive_pridata			__kernel_receive_pridata
+
+/*
+ *  mailbox.c
+ */
+#define _free_mbxcb					__kernel_free_mbxcb
+#define _initialize_mailbox			__kernel_initialize_mailbox
+
+/*
+ *  mempfix.c
+ */
+#define _free_mpfcb					__kernel_free_mpfcb
+#define _initialize_mempfix			__kernel_initialize_mempfix
+#define _get_mpf_block				__kernel_get_mpf_block
+
+/*
+ *  cyclic.c
+ */
+#define _free_cyccb					__kernel_free_cyccb
+#define _initialize_cyclic			__kernel_initialize_cyclic
+#define _call_cychdr				__kernel_call_cychdr
+
+/*
+ *  alarm.c
+ */
+#define _free_almcb					__kernel_free_almcb
+#define _initialize_alarm			__kernel_initialize_alarm
+#define _call_almhdr				__kernel_call_almhdr
+
+/*
+ *  interrupt.c
+ */
+#define _free_isrcb					__kernel_free_isrcb
+#define _initialize_isr				__kernel_initialize_isr
+#define _call_isr					__kernel_call_isr
+#define _initialize_interrupt		__kernel_initialize_interrupt
+
+/*
+ *  exception.c
+ */
+#define _initialize_exception		__kernel_initialize_exception
+
+/*
+ *  kernel_cfg.c
+ */
+#define _initialize_object			__kernel_initialize_object
+#define _call_inirtn				__kernel_call_inirtn
+#define _call_terrtn				__kernel_call_terrtn
+#define _tmax_tskid					__kernel_tmax_tskid
+#define _tmax_stskid				__kernel_tmax_stskid
+#define _tinib_table				__kernel_tinib_table
+#define _atinib_table				__kernel_atinib_table
+#define _tcb_table					__kernel_tcb_table
+#define _torder_table				__kernel_torder_table
+#define _tmax_semid					__kernel_tmax_semid
+#define _tmax_ssemid				__kernel_tmax_ssemid
+#define _seminib_table				__kernel_seminib_table
+#define _aseminib_table				__kernel_aseminib_table
+#define _semcb_table				__kernel_semcb_table
+#define _tmax_flgid					__kernel_tmax_flgid
+#define _tmax_sflgid				__kernel_tmax_sflgid
+#define _flginib_table				__kernel_flginib_table
+#define _aflginib_table				__kernel_aflginib_table
+#define _flgcb_table				__kernel_flgcb_table
+#define _tmax_dtqid					__kernel_tmax_dtqid
+#define _tmax_sdtqid				__kernel_tmax_sdtqid
+#define _dtqinib_table				__kernel_dtqinib_table
+#define _adtqinib_table				__kernel_adtqinib_table
+#define _dtqcb_table				__kernel_dtqcb_table
+#define _tmax_pdqid					__kernel_tmax_pdqid
+#define _tmax_spdqid				__kernel_tmax_spdqid
+#define _pdqinib_table				__kernel_pdqinib_table
+#define _apdqinib_table				__kernel_apdqinib_table
+#define _pdqcb_table				__kernel_pdqcb_table
+#define _tmax_mbxid					__kernel_tmax_mbxid
+#define _tmax_smbxid				__kernel_tmax_smbxid
+#define _mbxinib_table				__kernel_mbxinib_table
+#define _ambxinib_table				__kernel_ambxinib_table
+#define _mbxcb_table				__kernel_mbxcb_table
+#define _tmax_mpfid					__kernel_tmax_mpfid
+#define _tmax_smpfid				__kernel_tmax_smpfid
+#define _mpfinib_table				__kernel_mpfinib_table
+#define _ampfinib_table				__kernel_ampfinib_table
+#define _mpfcb_table				__kernel_mpfcb_table
+#define _tmax_cycid					__kernel_tmax_cycid
+#define _tmax_scycid				__kernel_tmax_scycid
+#define _cycinib_table				__kernel_cycinib_table
+#define _acycinib_table				__kernel_acycinib_table
+#define _cyccb_table				__kernel_cyccb_table
+#define _tmax_almid					__kernel_tmax_almid
+#define _tmax_salmid				__kernel_tmax_salmid
+#define _alminib_table				__kernel_alminib_table
+#define _aalminib_table				__kernel_aalminib_table
+#define _almcb_table				__kernel_almcb_table
+#define _tnum_isr_queue				__kernel_tnum_isr_queue
+#define _isr_queue_table			__kernel_isr_queue_table
+#define _isr_queue_list				__kernel_isr_queue_list
+#define _tmax_isrid					__kernel_tmax_isrid
+#define _tnum_sisr					__kernel_tnum_sisr
+#define _sisrinib_table				__kernel_sisrinib_table
+#define _aisrinib_table				__kernel_aisrinib_table
+#define _isrcb_table				__kernel_isrcb_table
+#define _tnum_inhno					__kernel_tnum_inhno
+#define _inhinib_table				__kernel_inhinib_table
+#define _tnum_intno					__kernel_tnum_intno
+#define _intinib_table				__kernel_intinib_table
+#define _tnum_excno					__kernel_tnum_excno
+#define _excinib_table				__kernel_excinib_table
+#define _tmevt_heap					__kernel_tmevt_heap
+#define _istksz						__kernel_istksz
+#define _istk						__kernel_istk
+#define _istkpt						__kernel_istkpt
+#define _kmmsz						__kernel_kmmsz
+#define _kmm						__kernel_kmm
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "target_rename.h"
+
+#endif /* TOPPERS_KERNEL_RENAME_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/kernel_unrename.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/kernel_unrename.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/kernel_unrename.h	(revision 164)
@@ -0,0 +1,431 @@
+/* This file is generated from kernel_rename.def by genrename. */
+
+/* This file is included only when kernel_rename.h has been included. */
+#ifdef TOPPERS_KERNEL_RENAME_H
+#undef TOPPERS_KERNEL_RENAME_H
+
+/*
+ *  startup.c
+ */
+#undef kerflg
+#undef exit_kernel
+#undef initialize_kmm
+#undef kernel_malloc
+#undef kernel_free
+
+/*
+ *  task.c
+ */
+#undef p_runtsk
+#undef p_schedtsk
+#undef reqflg
+#undef ipmflg
+#undef disdsp
+#undef dspflg
+#undef ready_queue
+#undef ready_primap
+#undef free_tcb
+#undef initialize_task
+#undef search_schedtsk
+#undef make_runnable
+#undef make_non_runnable
+#undef make_dormant
+#undef make_active
+#undef change_priority
+#undef rotate_ready_queue
+#undef call_texrtn
+#undef calltex
+
+/*
+ *  wait.c
+ */
+#undef make_wait_tmout
+#undef wait_complete
+#undef wait_tmout
+#undef wait_tmout_ok
+#undef wait_release
+#undef wobj_make_wait
+#undef wobj_make_wait_tmout
+#undef init_wait_queue
+
+/*
+ *  time_event.c
+ */
+#undef current_time
+#undef min_time
+#undef next_time
+#undef next_subtime
+#undef last_index
+#undef initialize_tmevt
+#undef tmevt_up
+#undef tmevt_down
+#undef tmevtb_insert
+#undef tmevtb_delete
+#undef tmevt_lefttim
+#undef signal_time
+
+/*
+ *  semaphore.c
+ */
+#undef free_semcb
+#undef initialize_semaphore
+
+/*
+ *  eventflag.c
+ */
+#undef free_flgcb
+#undef initialize_eventflag
+#undef check_flg_cond
+
+/*
+ *  dataqueue.c
+ */
+#undef free_dtqcb
+#undef initialize_dataqueue
+#undef enqueue_data
+#undef force_enqueue_data
+#undef dequeue_data
+#undef send_data
+#undef force_send_data
+#undef receive_data
+
+/*
+ *  pridataq.c
+ */
+#undef free_pdqcb
+#undef initialize_pridataq
+#undef enqueue_pridata
+#undef dequeue_pridata
+#undef send_pridata
+#undef receive_pridata
+
+/*
+ *  mailbox.c
+ */
+#undef free_mbxcb
+#undef initialize_mailbox
+
+/*
+ *  mempfix.c
+ */
+#undef free_mpfcb
+#undef initialize_mempfix
+#undef get_mpf_block
+
+/*
+ *  cyclic.c
+ */
+#undef free_cyccb
+#undef initialize_cyclic
+#undef call_cychdr
+
+/*
+ *  alarm.c
+ */
+#undef free_almcb
+#undef initialize_alarm
+#undef call_almhdr
+
+/*
+ *  interrupt.c
+ */
+#undef free_isrcb
+#undef initialize_isr
+#undef call_isr
+#undef initialize_interrupt
+
+/*
+ *  exception.c
+ */
+#undef initialize_exception
+
+/*
+ *  kernel_cfg.c
+ */
+#undef initialize_object
+#undef call_inirtn
+#undef call_terrtn
+#undef tmax_tskid
+#undef tmax_stskid
+#undef tinib_table
+#undef atinib_table
+#undef tcb_table
+#undef torder_table
+#undef tmax_semid
+#undef tmax_ssemid
+#undef seminib_table
+#undef aseminib_table
+#undef semcb_table
+#undef tmax_flgid
+#undef tmax_sflgid
+#undef flginib_table
+#undef aflginib_table
+#undef flgcb_table
+#undef tmax_dtqid
+#undef tmax_sdtqid
+#undef dtqinib_table
+#undef adtqinib_table
+#undef dtqcb_table
+#undef tmax_pdqid
+#undef tmax_spdqid
+#undef pdqinib_table
+#undef apdqinib_table
+#undef pdqcb_table
+#undef tmax_mbxid
+#undef tmax_smbxid
+#undef mbxinib_table
+#undef ambxinib_table
+#undef mbxcb_table
+#undef tmax_mpfid
+#undef tmax_smpfid
+#undef mpfinib_table
+#undef ampfinib_table
+#undef mpfcb_table
+#undef tmax_cycid
+#undef tmax_scycid
+#undef cycinib_table
+#undef acycinib_table
+#undef cyccb_table
+#undef tmax_almid
+#undef tmax_salmid
+#undef alminib_table
+#undef aalminib_table
+#undef almcb_table
+#undef tnum_isr_queue
+#undef isr_queue_table
+#undef isr_queue_list
+#undef tmax_isrid
+#undef tnum_sisr
+#undef sisrinib_table
+#undef aisrinib_table
+#undef isrcb_table
+#undef tnum_inhno
+#undef inhinib_table
+#undef tnum_intno
+#undef intinib_table
+#undef tnum_excno
+#undef excinib_table
+#undef tmevt_heap
+#undef istksz
+#undef istk
+#undef istkpt
+#undef kmmsz
+#undef kmm
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ *  startup.c
+ */
+#undef _kerflg
+#undef _exit_kernel
+#undef _initialize_kmm
+#undef _kernel_malloc
+#undef _kernel_free
+
+/*
+ *  task.c
+ */
+#undef _p_runtsk
+#undef _p_schedtsk
+#undef _reqflg
+#undef _ipmflg
+#undef _disdsp
+#undef _dspflg
+#undef _ready_queue
+#undef _ready_primap
+#undef _free_tcb
+#undef _initialize_task
+#undef _search_schedtsk
+#undef _make_runnable
+#undef _make_non_runnable
+#undef _make_dormant
+#undef _make_active
+#undef _change_priority
+#undef _rotate_ready_queue
+#undef _call_texrtn
+#undef _calltex
+
+/*
+ *  wait.c
+ */
+#undef _make_wait_tmout
+#undef _wait_complete
+#undef _wait_tmout
+#undef _wait_tmout_ok
+#undef _wait_release
+#undef _wobj_make_wait
+#undef _wobj_make_wait_tmout
+#undef _init_wait_queue
+
+/*
+ *  time_event.c
+ */
+#undef _current_time
+#undef _min_time
+#undef _next_time
+#undef _next_subtime
+#undef _last_index
+#undef _initialize_tmevt
+#undef _tmevt_up
+#undef _tmevt_down
+#undef _tmevtb_insert
+#undef _tmevtb_delete
+#undef _tmevt_lefttim
+#undef _signal_time
+
+/*
+ *  semaphore.c
+ */
+#undef _free_semcb
+#undef _initialize_semaphore
+
+/*
+ *  eventflag.c
+ */
+#undef _free_flgcb
+#undef _initialize_eventflag
+#undef _check_flg_cond
+
+/*
+ *  dataqueue.c
+ */
+#undef _free_dtqcb
+#undef _initialize_dataqueue
+#undef _enqueue_data
+#undef _force_enqueue_data
+#undef _dequeue_data
+#undef _send_data
+#undef _force_send_data
+#undef _receive_data
+
+/*
+ *  pridataq.c
+ */
+#undef _free_pdqcb
+#undef _initialize_pridataq
+#undef _enqueue_pridata
+#undef _dequeue_pridata
+#undef _send_pridata
+#undef _receive_pridata
+
+/*
+ *  mailbox.c
+ */
+#undef _free_mbxcb
+#undef _initialize_mailbox
+
+/*
+ *  mempfix.c
+ */
+#undef _free_mpfcb
+#undef _initialize_mempfix
+#undef _get_mpf_block
+
+/*
+ *  cyclic.c
+ */
+#undef _free_cyccb
+#undef _initialize_cyclic
+#undef _call_cychdr
+
+/*
+ *  alarm.c
+ */
+#undef _free_almcb
+#undef _initialize_alarm
+#undef _call_almhdr
+
+/*
+ *  interrupt.c
+ */
+#undef _free_isrcb
+#undef _initialize_isr
+#undef _call_isr
+#undef _initialize_interrupt
+
+/*
+ *  exception.c
+ */
+#undef _initialize_exception
+
+/*
+ *  kernel_cfg.c
+ */
+#undef _initialize_object
+#undef _call_inirtn
+#undef _call_terrtn
+#undef _tmax_tskid
+#undef _tmax_stskid
+#undef _tinib_table
+#undef _atinib_table
+#undef _tcb_table
+#undef _torder_table
+#undef _tmax_semid
+#undef _tmax_ssemid
+#undef _seminib_table
+#undef _aseminib_table
+#undef _semcb_table
+#undef _tmax_flgid
+#undef _tmax_sflgid
+#undef _flginib_table
+#undef _aflginib_table
+#undef _flgcb_table
+#undef _tmax_dtqid
+#undef _tmax_sdtqid
+#undef _dtqinib_table
+#undef _adtqinib_table
+#undef _dtqcb_table
+#undef _tmax_pdqid
+#undef _tmax_spdqid
+#undef _pdqinib_table
+#undef _apdqinib_table
+#undef _pdqcb_table
+#undef _tmax_mbxid
+#undef _tmax_smbxid
+#undef _mbxinib_table
+#undef _ambxinib_table
+#undef _mbxcb_table
+#undef _tmax_mpfid
+#undef _tmax_smpfid
+#undef _mpfinib_table
+#undef _ampfinib_table
+#undef _mpfcb_table
+#undef _tmax_cycid
+#undef _tmax_scycid
+#undef _cycinib_table
+#undef _acycinib_table
+#undef _cyccb_table
+#undef _tmax_almid
+#undef _tmax_salmid
+#undef _alminib_table
+#undef _aalminib_table
+#undef _almcb_table
+#undef _tnum_isr_queue
+#undef _isr_queue_table
+#undef _isr_queue_list
+#undef _tmax_isrid
+#undef _tnum_sisr
+#undef _sisrinib_table
+#undef _aisrinib_table
+#undef _isrcb_table
+#undef _tnum_inhno
+#undef _inhinib_table
+#undef _tnum_intno
+#undef _intinib_table
+#undef _tnum_excno
+#undef _excinib_table
+#undef _tmevt_heap
+#undef _istksz
+#undef _istk
+#undef _istkpt
+#undef _kmmsz
+#undef _kmm
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "target_unrename.h"
+
+#endif /* TOPPERS_KERNEL_RENAME_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/mailbox.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/mailbox.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/mailbox.c	(revision 164)
@@ -0,0 +1,539 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		[{bNX@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "mailbox.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_ACRE_MBX_ENTER
+#define LOG_ACRE_MBX_ENTER(pk_cmbx)
+#endif /* LOG_ACRE_MBX_ENTER */
+
+#ifndef LOG_ACRE_MBX_LEAVE
+#define LOG_ACRE_MBX_LEAVE(ercd)
+#endif /* LOG_ACRE_MBX_LEAVE */
+
+#ifndef LOG_DEL_MBX_ENTER
+#define LOG_DEL_MBX_ENTER(mbxid)
+#endif /* LOG_DEL_MBX_ENTER */
+
+#ifndef LOG_DEL_MBX_LEAVE
+#define LOG_DEL_MBX_LEAVE(ercd)
+#endif /* LOG_DEL_MBX_LEAVE */
+
+#ifndef LOG_SND_MBX_ENTER
+#define LOG_SND_MBX_ENTER(mbxid, pk_msg)
+#endif /* LOG_SND_MBX_ENTER */
+
+#ifndef LOG_SND_MBX_LEAVE
+#define LOG_SND_MBX_LEAVE(ercd)
+#endif /* LOG_SND_MBX_LEAVE */
+
+#ifndef LOG_RCV_MBX_ENTER
+#define LOG_RCV_MBX_ENTER(mbxid, ppk_msg)
+#endif /* LOG_RCV_MBX_ENTER */
+
+#ifndef LOG_RCV_MBX_LEAVE
+#define LOG_RCV_MBX_LEAVE(ercd, pk_msg)
+#endif /* LOG_RCV_MBX_LEAVE */
+
+#ifndef LOG_PRCV_MBX_ENTER
+#define LOG_PRCV_MBX_ENTER(mbxid, ppk_msg)
+#endif /* LOG_PRCV_MBX_ENTER */
+
+#ifndef LOG_PRCV_MBX_LEAVE
+#define LOG_PRCV_MBX_LEAVE(ercd, pk_msg)
+#endif /* LOG_PRCV_MBX_LEAVE */
+
+#ifndef LOG_TRCV_MBX_ENTER
+#define LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout)
+#endif /* LOG_TRCV_MBX_ENTER */
+
+#ifndef LOG_TRCV_MBX_LEAVE
+#define LOG_TRCV_MBX_LEAVE(ercd, pk_msg)
+#endif /* LOG_TRCV_MBX_LEAVE */
+
+#ifndef LOG_INI_MBX_ENTER
+#define LOG_INI_MBX_ENTER(mbxid)
+#endif /* LOG_INI_MBX_ENTER */
+
+#ifndef LOG_INI_MBX_LEAVE
+#define LOG_INI_MBX_LEAVE(ercd)
+#endif /* LOG_INI_MBX_LEAVE */
+
+#ifndef LOG_REF_MBX_ENTER
+#define LOG_REF_MBX_ENTER(mbxid, pk_rmbx)
+#endif /* LOG_REF_MBX_ENTER */
+
+#ifndef LOG_REF_MBX_LEAVE
+#define LOG_REF_MBX_LEAVE(ercd, pk_rmbx)
+#endif /* LOG_REF_MBX_LEAVE */
+
+/*
+ *  [{bNXÌ
+ */
+#define tnum_mbx	((uint_t)(tmax_mbxid - TMIN_MBXID + 1))
+#define tnum_smbx	((uint_t)(tmax_smbxid - TMIN_MBXID + 1))
+
+/*
+ *  [{bNXID©ç[{bNXÇubNðæèo·½ßÌ}N
+ */
+#define INDEX_MBX(mbxid)	((uint_t)((mbxid) - TMIN_MBXID))
+#define get_mbxcb(mbxid)	(&(mbxcb_table[INDEX_MBX(mbxid)]))
+
+#ifdef TOPPERS_mbxini
+
+/*
+ *  gpµÄ¢È¢[{bNXÇubNÌXg
+ */
+QUEUE	free_mbxcb;
+
+/* 
+ *  [{bNX@\Ìú»
+ */
+void
+initialize_mailbox(void)
+{
+	uint_t	i, j;
+	MBXCB	*p_mbxcb;
+	MBXINIB	*p_mbxinib;
+
+	for (i = 0; i < tnum_smbx; i++) {
+		p_mbxcb = &(mbxcb_table[i]);
+		queue_initialize(&(p_mbxcb->wait_queue));
+		p_mbxcb->p_mbxinib = &(mbxinib_table[i]);
+		p_mbxcb->pk_head = NULL;
+	}
+	queue_initialize(&free_mbxcb);
+	for (j = 0; i < tnum_mbx; i++, j++) {
+		p_mbxcb = &(mbxcb_table[i]);
+		p_mbxinib = &(ambxinib_table[j]);
+		p_mbxinib->mbxatr = TA_NOEXS;
+		p_mbxcb->p_mbxinib = ((const MBXINIB *) p_mbxinib);
+		queue_insert_prev(&free_mbxcb, &(p_mbxcb->wait_queue));
+	}
+}
+
+#endif /* TOPPERS_mbxini */
+
+/*
+ *  bZ[WDæxÌæoµ
+ */
+#define	MSGPRI(pk_msg)	(((T_MSG_PRI *)(pk_msg))->msgpri)
+
+/*
+ *  DæxbZ[WL
+[ÖÌ}ü
+ */
+Inline void
+enqueue_msg_pri(T_MSG **ppk_prevmsg_next, T_MSG *pk_msg)
+{
+	T_MSG	*pk_nextmsg;
+
+	while ((pk_nextmsg = *ppk_prevmsg_next) != NULL) {
+		if (MSGPRI(pk_nextmsg) > MSGPRI(pk_msg)) {
+			break;
+		}
+		ppk_prevmsg_next = &(pk_nextmsg->pk_next);
+	}
+	pk_msg->pk_next = pk_nextmsg;
+	*ppk_prevmsg_next = pk_msg;
+}
+
+/*
+ *  [{bNXÌ¶¬
+ */
+#ifdef TOPPERS_acre_mbx
+
+ER_UINT
+acre_mbx(const T_CMBX *pk_cmbx)
+{
+	MBXCB	*p_mbxcb;
+	MBXINIB	*p_mbxinib;
+	ER		ercd;
+
+	LOG_ACRE_MBX_ENTER(pk_cmbx);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_cmbx->mbxatr, TA_TPRI|TA_MPRI);
+	CHECK_MPRI(pk_cmbx->maxmpri);
+	CHECK_NOSPT(pk_cmbx->mprihd == NULL);
+
+	t_lock_cpu();
+	if (tnum_mbx == 0 || queue_empty(&free_mbxcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		p_mbxcb = ((MBXCB *) queue_delete_next(&free_mbxcb));
+		p_mbxinib = (MBXINIB *)(p_mbxcb->p_mbxinib);
+		p_mbxinib->mbxatr = pk_cmbx->mbxatr;
+		p_mbxinib->maxmpri = pk_cmbx->maxmpri;
+
+		queue_initialize(&(p_mbxcb->wait_queue));
+		p_mbxcb->pk_head = NULL;
+		ercd = MBXID(p_mbxcb);
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_MBX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_mbx */
+
+/*
+ *  [{bNXÌí
+ */
+#ifdef TOPPERS_del_mbx
+
+ER
+del_mbx(ID mbxid)
+{
+	MBXCB	*p_mbxcb;
+	MBXINIB	*p_mbxinib;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_DEL_MBX_ENTER(mbxid);
+	CHECK_TSKCTX_UNL();
+	CHECK_MBXID(mbxid);
+	p_mbxcb = get_mbxcb(mbxid);
+
+	t_lock_cpu();
+	if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (MBXID(p_mbxcb) > tmax_smbxid) {
+		dspreq = init_wait_queue(&(p_mbxcb->wait_queue));
+		p_mbxinib = (MBXINIB *)(p_mbxcb->p_mbxinib);
+		p_mbxinib->mbxatr = TA_NOEXS;
+		queue_insert_prev(&free_mbxcb, &(p_mbxcb->wait_queue));
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_MBX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_mbx */
+
+/*
+ *  [{bNXÖÌM
+ */
+#ifdef TOPPERS_snd_mbx
+
+ER
+snd_mbx(ID mbxid, T_MSG *pk_msg)
+{
+	MBXCB	*p_mbxcb;
+	TCB		*p_tcb;
+	ER		ercd;
+    
+	LOG_SND_MBX_ENTER(mbxid, pk_msg);
+	CHECK_TSKCTX_UNL();
+	CHECK_MBXID(mbxid);
+	p_mbxcb = get_mbxcb(mbxid);
+
+	t_lock_cpu();
+	if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) == 0U
+				|| (TMIN_MPRI <= MSGPRI(pk_msg)
+					&& MSGPRI(pk_msg) <= p_mbxcb->p_mbxinib->maxmpri))) {
+		ercd = E_PAR;
+	}
+	else if (!queue_empty(&(p_mbxcb->wait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_mbxcb->wait_queue));
+		((WINFO_MBX *)(p_tcb->p_winfo))->pk_msg = pk_msg;
+		if (wait_complete(p_tcb)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if ((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) != 0U) {
+		enqueue_msg_pri(&(p_mbxcb->pk_head), pk_msg);
+		ercd = E_OK;
+	}
+	else {
+		pk_msg->pk_next = NULL;
+		if (p_mbxcb->pk_head != NULL) {
+			p_mbxcb->pk_last->pk_next = pk_msg;
+		}
+		else {
+			p_mbxcb->pk_head = pk_msg;
+		}
+		p_mbxcb->pk_last = pk_msg;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_SND_MBX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_snd_mbx */
+
+/*
+ *  [{bNX©çÌóM
+ */
+#ifdef TOPPERS_rcv_mbx
+
+ER
+rcv_mbx(ID mbxid, T_MSG **ppk_msg)
+{
+	MBXCB	*p_mbxcb;
+	WINFO_MBX winfo_mbx;
+	ER		ercd;
+    
+	LOG_RCV_MBX_ENTER(mbxid, ppk_msg);
+	CHECK_DISPATCH();
+	CHECK_MBXID(mbxid);
+	p_mbxcb = get_mbxcb(mbxid);
+    
+	t_lock_cpu();
+	if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_mbxcb->pk_head != NULL) {
+		*ppk_msg = p_mbxcb->pk_head;
+		p_mbxcb->pk_head = (*ppk_msg)->pk_next;
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX);
+		wobj_make_wait((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx);
+		dispatch();
+		ercd = winfo_mbx.winfo.wercd;
+		if (ercd == E_OK) {
+			*ppk_msg = winfo_mbx.pk_msg;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_RCV_MBX_LEAVE(ercd, *ppk_msg);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rcv_mbx */
+
+/*
+ *  [{bNX©çÌóMi|[Oj
+ */
+#ifdef TOPPERS_prcv_mbx
+
+ER
+prcv_mbx(ID mbxid, T_MSG **ppk_msg)
+{
+	MBXCB	*p_mbxcb;
+	ER		ercd;
+    
+	LOG_PRCV_MBX_ENTER(mbxid, ppk_msg);
+	CHECK_TSKCTX_UNL();
+	CHECK_MBXID(mbxid);
+	p_mbxcb = get_mbxcb(mbxid);
+    
+	t_lock_cpu();
+	if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_mbxcb->pk_head != NULL) {
+		*ppk_msg = p_mbxcb->pk_head;
+		p_mbxcb->pk_head = (*ppk_msg)->pk_next;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_PRCV_MBX_LEAVE(ercd, *ppk_msg);
+	return(ercd);
+}
+
+#endif /* TOPPERS_prcv_mbx */
+
+/*
+ *  [{bNX©çÌóMi^CAEg èj
+ */
+#ifdef TOPPERS_trcv_mbx
+
+ER
+trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout)
+{
+	MBXCB	*p_mbxcb;
+	WINFO_MBX winfo_mbx;
+	TMEVTB	tmevtb;
+	ER		ercd;
+    
+	LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout);
+	CHECK_DISPATCH();
+	CHECK_MBXID(mbxid);
+	CHECK_TMOUT(tmout);
+	p_mbxcb = get_mbxcb(mbxid);
+    
+	t_lock_cpu();
+	if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_mbxcb->pk_head != NULL) {
+		*ppk_msg = p_mbxcb->pk_head;
+		p_mbxcb->pk_head = (*ppk_msg)->pk_next;
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX);
+		wobj_make_wait_tmout((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_mbx.winfo.wercd;
+		if (ercd == E_OK) {
+			*ppk_msg = winfo_mbx.pk_msg;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TRCV_MBX_LEAVE(ercd, *ppk_msg);
+	return(ercd);
+}
+
+#endif /* TOPPERS_trcv_mbx */
+
+/*
+ *  [{bNXÌÄú»
+ */
+#ifdef TOPPERS_ini_mbx
+
+ER
+ini_mbx(ID mbxid)
+{
+	MBXCB	*p_mbxcb;
+	bool_t	dspreq;
+	ER		ercd;
+    
+	LOG_INI_MBX_ENTER(mbxid);
+	CHECK_TSKCTX_UNL();
+	CHECK_MBXID(mbxid);
+	p_mbxcb = get_mbxcb(mbxid);
+
+	t_lock_cpu();
+	if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		dspreq = init_wait_queue(&(p_mbxcb->wait_queue));
+		p_mbxcb->pk_head = NULL;
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_INI_MBX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ini_mbx */
+
+/*
+ *  [{bNXÌóÔQÆ
+ */
+#ifdef TOPPERS_ref_mbx
+
+ER
+ref_mbx(ID mbxid, T_RMBX *pk_rmbx)
+{
+	MBXCB	*p_mbxcb;
+	ER		ercd;
+    
+	LOG_REF_MBX_ENTER(mbxid, pk_rmbx);
+	CHECK_TSKCTX_UNL();
+	CHECK_MBXID(mbxid);
+	p_mbxcb = get_mbxcb(mbxid);
+
+	t_lock_cpu();
+	if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		pk_rmbx->wtskid = wait_tskid(&(p_mbxcb->wait_queue));
+		pk_rmbx->pk_msg = p_mbxcb->pk_head;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_MBX_LEAVE(ercd, pk_rmbx);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_mbx */
Index: UsbWattMeter/trunk/asp_dcre/kernel/mailbox.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/mailbox.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/mailbox.h	(revision 164)
@@ -0,0 +1,134 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		[{bNX@\
+ */
+
+#ifndef TOPPERS_MAILBOX_H
+#define TOPPERS_MAILBOX_H
+
+#include "wait.h"
+
+/*
+ *  [{bNXú»ubN
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌú»ubNÌ¤Êª
+ *  iWOBJINIBjðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅC
+ *  ÅÌtB[hª¤ÊÉÈÁÄ¢éD
+ */
+typedef struct mailbox_initialization_block {
+	ATR			mbxatr;			/* [{bNX®« */
+	PRI			maxmpri;		/* bZ[WDæxÌÅål */
+} MBXINIB;
+
+/*
+ *  [{bNXÇubN
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌÇubNÌ¤ÊªiWOBJCBj
+ *  ðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅCÅÌ2ÂÌ
+ *  tB[hª¤ÊÉÈÁÄ¢éD
+ *
+ *  bZ[WL
+[ªbZ[WÌDæxÌêÉÍCpk_lastÍgíÈ
+ *  ¢DÜ½CbZ[WL
+[ªóÌêipk_headªNULLÌêjÉàC
+ *  pk_lastÍ³øÅ éD
+ */
+typedef struct mailbox_control_block {
+	QUEUE		wait_queue;		/* [{bNXÒ¿L
+[ */
+	const MBXINIB *p_mbxinib;	/* ú»ubNÖÌ|C^ */
+	T_MSG		*pk_head;		/* æªÌbZ[W */
+	T_MSG		*pk_last;		/* öÌbZ[W */
+} MBXCB;
+
+/*
+ *  [{bNXÒ¿îñubNÌè`
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌÒ¿îñubNÌ¤Êª
+ *  iWINFO_WOBJjðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅC
+ *  ÅÌ2ÂÌtB[hª¤ÊÉÈÁÄ¢éD
+ */
+typedef struct mailbox_waiting_information {
+	WINFO		winfo;			/* WÌÒ¿îñubN */
+	MBXCB		*p_mbxcb;		/* ÒÁÄ¢é[{bNXÌÇubN */
+	T_MSG		*pk_msg;		/* óMµ½bZ[W */
+} WINFO_MBX;
+
+/*
+ *  gpµÄ¢È¢[{bNXÇubNÌXg
+ */
+extern QUEUE	free_mbxcb;
+
+/*
+ *  [{bNXIDÌÅålikernel_cfg.cj
+ */
+extern const ID	tmax_mbxid;
+extern const ID	tmax_smbxid;
+
+/*
+ *  [{bNXú»ubNÌGAikernel_cfg.cj
+ */
+extern const MBXINIB	mbxinib_table[];
+extern MBXINIB			ambxinib_table[];
+
+/*
+ *  [{bNXÇubNÌGAikernel_cfg.cj
+ */
+extern MBXCB	mbxcb_table[];
+
+/*
+ *  [{bNXÇubN©ç[{bNXIDðæèo·½ßÌ}N
+ */
+#define	MBXID(p_mbxcb)	((ID)(((p_mbxcb) - mbxcb_table) + TMIN_MBXID))
+
+/*
+ *  [{bNX@\Ìú»
+ */
+extern void	initialize_mailbox(void);
+
+#endif /* TOPPERS_MAILBOX_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/mempfix.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/mempfix.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/mempfix.c	(revision 164)
@@ -0,0 +1,592 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		Åè·v[@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "mempfix.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_ACRE_MPF_ENTER
+#define LOG_ACRE_MPF_ENTER(pk_cmpf)
+#endif /* LOG_ACRE_MPF_ENTER */
+
+#ifndef LOG_ACRE_MPF_LEAVE
+#define LOG_ACRE_MPF_LEAVE(ercd)
+#endif /* LOG_ACRE_MPF_LEAVE */
+
+#ifndef LOG_DEL_MPF_ENTER
+#define LOG_DEL_MPF_ENTER(mpfid)
+#endif /* LOG_DEL_MPF_ENTER */
+
+#ifndef LOG_DEL_MPF_LEAVE
+#define LOG_DEL_MPF_LEAVE(ercd)
+#endif /* LOG_DEL_MPF_LEAVE */
+
+#ifndef LOG_GET_MPF_ENTER
+#define LOG_GET_MPF_ENTER(mpfid, p_blk)
+#endif /* LOG_GET_MPF_ENTER */
+
+#ifndef LOG_GET_MPF_LEAVE
+#define LOG_GET_MPF_LEAVE(ercd, blk)
+#endif /* LOG_GET_MPF_LEAVE */
+
+#ifndef LOG_PGET_MPF_ENTER
+#define LOG_PGET_MPF_ENTER(mpfid, p_blk)
+#endif /* LOG_PGET_MPF_ENTER */
+
+#ifndef LOG_PGET_MPF_LEAVE
+#define LOG_PGET_MPF_LEAVE(ercd, blk)
+#endif /* LOG_PGET_MPF_LEAVE */
+
+#ifndef LOG_TGET_MPF_ENTER
+#define LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout)
+#endif /* LOG_TGET_MPF_ENTER */
+
+#ifndef LOG_TGET_MPF_LEAVE
+#define LOG_TGET_MPF_LEAVE(ercd, blk)
+#endif /* LOG_TGET_MPF_LEAVE */
+
+#ifndef LOG_REL_MPF_ENTER
+#define LOG_REL_MPF_ENTER(mpfid, blk)
+#endif /* LOG_REL_MPF_ENTER */
+
+#ifndef LOG_REL_MPF_LEAVE
+#define LOG_REL_MPF_LEAVE(ercd)
+#endif /* LOG_REL_MPF_LEAVE */
+
+#ifndef LOG_INI_MPF_ENTER
+#define LOG_INI_MPF_ENTER(mpfid)
+#endif /* LOG_INI_MPF_ENTER */
+
+#ifndef LOG_INI_MPF_LEAVE
+#define LOG_INI_MPF_LEAVE(ercd)
+#endif /* LOG_INI_MPF_LEAVE */
+
+#ifndef LOG_REF_MPF_ENTER
+#define LOG_REF_MPF_ENTER(mpfid, pk_rmpf)
+#endif /* LOG_REF_MPF_ENTER */
+
+#ifndef LOG_REF_MPF_LEAVE
+#define LOG_REF_MPF_LEAVE(ercd, pk_rmpf)
+#endif /* LOG_REF_MPF_LEAVE */
+
+/*
+ *  Åè·v[Ì
+ */
+#define tnum_mpf	((uint_t)(tmax_mpfid - TMIN_MPFID + 1))
+#define tnum_smpf	((uint_t)(tmax_smpfid - TMIN_MPFID + 1))
+
+/*
+ *  Åè·v[ID©çÅè·v[ÇubNðæèo·½
+ *  ßÌ}N
+ */
+#define INDEX_MPF(mpfid)	((uint_t)((mpfid) - TMIN_MPFID))
+#define get_mpfcb(mpfid)	(&(mpfcb_table[INDEX_MPF(mpfid)]))
+
+/*
+ *  ÁêÈCfbNXlÌè`
+ */
+#define INDEX_NULL		(~0U)		/* ó«ubNXgÌÅã */
+#define INDEX_ALLOC		(~1U)		/* ÄÏÝÌubN */
+
+#ifdef TOPPERS_mpfini
+
+/*
+ *  gpµÄ¢È¢Åè·v[ÇubNÌXg
+ */
+QUEUE	free_mpfcb;
+
+/* 
+ *  Åè·v[@\Ìú»
+ */
+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 */
+
+/*
+ *  Åè·v[©çubNðl¾
+ */
+#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 */
+
+/*
+ *  Åè·v[Ì¶¬
+ */
+#ifdef TOPPERS_acre_mpf
+
+ER_UINT
+acre_mpf(const T_CMPF *pk_cmpf)
+{
+	MPFCB	*p_mpfcb;
+	MPFINIB	*p_mpfinib;
+	ATR		mpfatr;
+	void	*mpf;
+	MPFMB	*p_mpfmb;
+	ER		ercd;
+
+	LOG_ACRE_MPF_ENTER(pk_cmpf);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_cmpf->mpfatr, TA_TPRI);
+	CHECK_PAR(pk_cmpf->blkcnt != 0);
+	CHECK_PAR(pk_cmpf->blksz != 0);
+	if (pk_cmpf->mpf != NULL) {
+		CHECK_ALIGN_MPF(pk_cmpf->mpf);
+	}
+	if (pk_cmpf->mpfmb != NULL) {
+		CHECK_ALIGN_MB(pk_cmpf->mpfmb);
+	}
+	mpfatr = pk_cmpf->mpfatr;
+	mpf = pk_cmpf->mpf;
+	p_mpfmb = pk_cmpf->mpfmb;
+
+	t_lock_cpu();
+	if (tnum_mpf == 0 || queue_empty(&free_mpfcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		if (mpf == NULL) {
+			mpf = kernel_malloc(ROUND_MPF_T(pk_cmpf->blksz) * pk_cmpf->blkcnt);
+			mpfatr |= TA_MEMALLOC;
+		}
+		if (mpf == NULL) {
+			ercd = E_NOMEM;
+		}
+		else {
+			if (p_mpfmb == NULL) {
+				p_mpfmb = kernel_malloc(sizeof(MPFMB) * pk_cmpf->blkcnt);
+				mpfatr |= TA_MBALLOC;
+			}
+			if (p_mpfmb == NULL) {
+				if (pk_cmpf->mpf == NULL) {
+					kernel_free(mpf);
+				}
+				ercd = E_NOMEM;
+			}
+			else {
+				p_mpfcb = ((MPFCB *) queue_delete_next(&free_mpfcb));
+				p_mpfinib = (MPFINIB *)(p_mpfcb->p_mpfinib);
+				p_mpfinib->mpfatr = mpfatr;
+				p_mpfinib->blkcnt = pk_cmpf->blkcnt;
+				p_mpfinib->blksz = ROUND_MPF_T(pk_cmpf->blksz);
+				p_mpfinib->mpf = mpf;
+				p_mpfinib->p_mpfmb = p_mpfmb;
+
+				queue_initialize(&(p_mpfcb->wait_queue));
+				p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
+				p_mpfcb->unused = 0U;
+				p_mpfcb->freelist = INDEX_NULL;
+				ercd = MPFID(p_mpfcb);
+			}
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_MPF_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_mpf */
+
+/*
+ *  Åè·v[Ìí
+ */
+#ifdef TOPPERS_del_mpf
+
+ER
+del_mpf(ID mpfid)
+{
+	MPFCB	*p_mpfcb;
+	MPFINIB	*p_mpfinib;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_DEL_MPF_ENTER(mpfid);
+	CHECK_TSKCTX_UNL();
+	CHECK_MPFID(mpfid);
+	p_mpfcb = get_mpfcb(mpfid);
+
+	t_lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (MPFID(p_mpfcb) > tmax_smpfid) {
+		dspreq = init_wait_queue(&(p_mpfcb->wait_queue));
+		p_mpfinib = (MPFINIB *)(p_mpfcb->p_mpfinib);
+		if ((p_mpfinib->mpfatr & TA_MEMALLOC) != 0U) {
+			kernel_free(p_mpfinib->mpf);
+		}
+		if ((p_mpfinib->mpfatr & TA_MBALLOC) != 0U) {
+			kernel_free(p_mpfinib->p_mpfmb);
+		}
+		p_mpfinib->mpfatr = TA_NOEXS;
+		queue_insert_prev(&free_mpfcb, &(p_mpfcb->wait_queue));
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_MPF_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_mpf */
+
+/*
+ *  Åè·ubNÌl¾
+ */
+#ifdef TOPPERS_get_mpf
+
+ER
+get_mpf(ID mpfid, void **p_blk)
+{
+	MPFCB	*p_mpfcb;
+	WINFO_MPF winfo_mpf;
+	ER		ercd;
+
+	LOG_GET_MPF_ENTER(mpfid, p_blk);
+	CHECK_DISPATCH();
+	CHECK_MPFID(mpfid);
+	p_mpfcb = get_mpfcb(mpfid);
+
+	t_lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_mpfcb->fblkcnt > 0) {
+		get_mpf_block(p_mpfcb, p_blk);
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF);
+		wobj_make_wait((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf);
+		dispatch();
+		ercd = winfo_mpf.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_blk = winfo_mpf.blk;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_GET_MPF_LEAVE(ercd, *p_blk);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_mpf */
+
+/*
+ *  Åè·ubNÌl¾i|[Oj
+ */
+#ifdef TOPPERS_pget_mpf
+
+ER
+pget_mpf(ID mpfid, void **p_blk)
+{
+	MPFCB	*p_mpfcb;
+	ER		ercd;
+
+	LOG_PGET_MPF_ENTER(mpfid, p_blk);
+	CHECK_TSKCTX_UNL();
+	CHECK_MPFID(mpfid);
+	p_mpfcb = get_mpfcb(mpfid);
+
+	t_lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_mpfcb->fblkcnt > 0) {
+		get_mpf_block(p_mpfcb, p_blk);
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_PGET_MPF_LEAVE(ercd, *p_blk);
+	return(ercd);
+}
+
+#endif /* TOPPERS_pget_mpf */
+
+/*
+ *  Åè·ubNÌl¾i^CAEg èj
+ */
+#ifdef TOPPERS_tget_mpf
+
+ER
+tget_mpf(ID mpfid, void **p_blk, TMO tmout)
+{
+	MPFCB	*p_mpfcb;
+	WINFO_MPF winfo_mpf;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout);
+	CHECK_DISPATCH();
+	CHECK_MPFID(mpfid);
+	CHECK_TMOUT(tmout);
+	p_mpfcb = get_mpfcb(mpfid);
+
+	t_lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_mpfcb->fblkcnt > 0) {
+		get_mpf_block(p_mpfcb, p_blk);
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF);
+		wobj_make_wait_tmout((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_mpf.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_blk = winfo_mpf.blk;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TGET_MPF_LEAVE(ercd, *p_blk);
+	return(ercd);
+}
+
+#endif /* TOPPERS_tget_mpf */
+
+/*
+ *  Åè·ubNÌÔp
+ */
+#ifdef TOPPERS_rel_mpf
+
+ER
+rel_mpf(ID mpfid, void *blk)
+{
+	MPFCB	*p_mpfcb;
+	SIZE	blkoffset;
+	uint_t	blkidx;
+	TCB		*p_tcb;
+	ER		ercd;
+    
+	LOG_REL_MPF_ENTER(mpfid, blk);
+	CHECK_TSKCTX_UNL();
+	CHECK_MPFID(mpfid);
+	p_mpfcb = get_mpfcb(mpfid);
+
+	t_lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		blkoffset = ((char *) blk) - (char *)(p_mpfcb->p_mpfinib->mpf);
+		blkidx = (uint_t)(blkoffset / p_mpfcb->p_mpfinib->blksz);
+		if (!(p_mpfcb->p_mpfinib->mpf <= blk)
+				|| !(blkoffset % p_mpfcb->p_mpfinib->blksz == 0U)
+				|| !(blkoffset / p_mpfcb->p_mpfinib->blksz < p_mpfcb->unused)
+				|| !((p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next
+															== INDEX_ALLOC)) {
+			ercd = E_PAR;
+		}
+		else if (!queue_empty(&(p_mpfcb->wait_queue))) {
+			p_tcb = (TCB *) queue_delete_next(&(p_mpfcb->wait_queue));
+			((WINFO_MPF *)(p_tcb->p_winfo))->blk = blk;
+			if (wait_complete(p_tcb)) {
+				dispatch();
+			}
+			ercd = E_OK;
+		}
+		else {
+			p_mpfcb->fblkcnt++;
+			(p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = p_mpfcb->freelist;
+			p_mpfcb->freelist = blkidx;
+			ercd = E_OK;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REL_MPF_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rel_mpf */
+
+/*
+ *  Åè·v[ÌÄú»
+ */
+#ifdef TOPPERS_ini_mpf
+
+ER
+ini_mpf(ID mpfid)
+{
+	MPFCB	*p_mpfcb;
+	bool_t	dspreq;
+	ER		ercd;
+    
+	LOG_INI_MPF_ENTER(mpfid);
+	CHECK_TSKCTX_UNL();
+	CHECK_MPFID(mpfid);
+	p_mpfcb = get_mpfcb(mpfid);
+
+	t_lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		dspreq = init_wait_queue(&(p_mpfcb->wait_queue));
+		p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
+		p_mpfcb->unused = 0U;
+		p_mpfcb->freelist = INDEX_NULL;
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_INI_MPF_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ini_mpf */
+
+/*
+ *  Åè·v[ÌóÔQÆ
+ */
+#ifdef TOPPERS_ref_mpf
+
+ER
+ref_mpf(ID mpfid, T_RMPF *pk_rmpf)
+{
+	MPFCB	*p_mpfcb;
+	ER		ercd;
+    
+	LOG_REF_MPF_ENTER(mpfid, pk_rmpf);
+	CHECK_TSKCTX_UNL();
+	CHECK_MPFID(mpfid);
+	p_mpfcb = get_mpfcb(mpfid);
+
+	t_lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		pk_rmpf->wtskid = wait_tskid(&(p_mpfcb->wait_queue));
+		pk_rmpf->fblkcnt = p_mpfcb->fblkcnt;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_MPF_LEAVE(ercd, pk_rmpf);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_mpf */
Index: UsbWattMeter/trunk/asp_dcre/kernel/mempfix.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/mempfix.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/mempfix.h	(revision 164)
@@ -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-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		Åè·v[@\
+ */
+
+#ifndef TOPPERS_MEMPFIX_H
+#define TOPPERS_MEMPFIX_H
+
+#include "wait.h"
+
+/*
+ *  Åè·ubNÇubN
+ *
+ *  nexttB[hÉÍCubNªÄÏÝÌêÍINDEX_ALLOCðC
+ *  ¢ÄÌêÍÌ¢ÄubNÌCfbNXÔði[·éD
+ *  ÅãÌ¢ÄubNÌêÉÍCINDEX_NULLði[·éD
+ */
+typedef struct fixed_memoryblock_management_block {
+	uint_t		next;			/* Ì¢ÄubN */
+} MPFMB;
+
+/*
+ *  Åè·v[ú»ubN
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌú»ubNÌ¤Êª
+ *  iWOBJINIBjðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅC
+ *  ÅÌtB[hª¤ÊÉÈÁÄ¢éD
+ */
+typedef struct fixed_memorypool_initialization_block {
+	ATR			mpfatr;			/* Åè·v[®« */
+	uint_t		blkcnt;			/* ubN */
+	uint_t		blksz;			/* ubNÌTCYiÛß½lj */
+	void		*mpf;			/* Åè·v[ÌæÌæªÔn */
+	MPFMB		*p_mpfmb;		/* Åè·v[ÇÌæÌæªÔn */
+} MPFINIB;
+
+/*
+ *  Åè·v[ÇubN
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌÇubNÌ¤ÊªiWOBJCBj
+ *  ðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅCÅÌ2ÂÌ
+ *  tB[hª¤ÊÉÈÁÄ¢éD
+ */
+typedef struct fixed_memorypool_control_block {
+	QUEUE		wait_queue;		/* Åè·v[Ò¿L
+[ */
+	const MPFINIB *p_mpfinib;	/* ú»ubNÖÌ|C^ */
+	uint_t		fblkcnt;		/* ¢ÄubN */
+	uint_t		unused;			/* ¢gpubNÌæª */
+	uint_t		freelist;		/* ¢ÄubNÌXg */
+} MPFCB;
+
+/*
+ *  Åè·v[Ò¿îñubNÌè`
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌÒ¿îñubNÌ¤Êª
+ *  iWINFO_WOBJjðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅC
+ *  ÅÌ2ÂÌtB[hª¤ÊÉÈÁÄ¢éD
+ */
+typedef struct fixed_memorypool_waiting_information {
+	WINFO		winfo;			/* WÌÒ¿îñubN */
+	MPFCB		*p_mpfcb;		/* ÒÁÄ¢éÅè·v[ÌÇubN*/
+	void		*blk;			/* l¾µ½ubN */
+} WINFO_MPF;
+
+/*
+ *  gpµÄ¢È¢Åè·v[ÇubNÌXg
+ */
+extern QUEUE	free_mpfcb;
+
+/*
+ *  Åè·v[IDÌÅålikernel_cfg.cj
+ */
+extern const ID	tmax_mpfid;
+extern const ID	tmax_smpfid;
+
+/*
+ *  Åè·v[ú»ubNÌGAikernel_cfg.cj
+ */
+extern const MPFINIB	mpfinib_table[];
+extern MPFINIB			ampfinib_table[];
+
+/*
+ *  Åè·v[ÇubNÌGAikernel_cfg.cj
+ */
+extern MPFCB	mpfcb_table[];
+
+/*
+ *  Åè·v[ÇubN©çÅè·v[IDðæèo·½
+ *  ßÌ}N
+ */
+#define	MPFID(p_mpfcb)	((ID)(((p_mpfcb) - mpfcb_table) + TMIN_MPFID))
+
+/*
+ *  Åè·v[@\Ìú»
+ */
+extern void	initialize_mempfix(void);
+
+/*
+ *  Åè·v[©çubNðl¾
+ */
+extern void	get_mpf_block(MPFCB *p_mpfcb, void **p_blk);
+
+#endif /* TOPPERS_MEMPFIX_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/pridataq.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/pridataq.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/pridataq.c	(revision 164)
@@ -0,0 +1,874 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		Dæxf[^L
+[@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "pridataq.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_ACRE_PDQ_ENTER
+#define LOG_ACRE_PDQ_ENTER(pk_cpdq)
+#endif /* LOG_ACRE_PDQ_ENTER */
+
+#ifndef LOG_ACRE_PDQ_LEAVE
+#define LOG_ACRE_PDQ_LEAVE(ercd)
+#endif /* LOG_ACRE_PDQ_LEAVE */
+
+#ifndef LOG_DEL_PDQ_ENTER
+#define LOG_DEL_PDQ_ENTER(pdqid)
+#endif /* LOG_DEL_PDQ_ENTER */
+
+#ifndef LOG_DEL_PDQ_LEAVE
+#define LOG_DEL_PDQ_LEAVE(ercd)
+#endif /* LOG_DEL_PDQ_LEAVE */
+
+#ifndef LOG_SND_PDQ_ENTER
+#define LOG_SND_PDQ_ENTER(pdqid, data, datapri)
+#endif /* LOG_SND_PDQ_ENTER */
+
+#ifndef LOG_SND_PDQ_LEAVE
+#define LOG_SND_PDQ_LEAVE(ercd)
+#endif /* LOG_SND_PDQ_LEAVE */
+
+#ifndef LOG_PSND_PDQ_ENTER
+#define LOG_PSND_PDQ_ENTER(pdqid, data, datapri)
+#endif /* LOG_PSND_PDQ_ENTER */
+
+#ifndef LOG_PSND_PDQ_LEAVE
+#define LOG_PSND_PDQ_LEAVE(ercd)
+#endif /* LOG_PSND_PDQ_LEAVE */
+
+#ifndef LOG_IPSND_PDQ_ENTER
+#define LOG_IPSND_PDQ_ENTER(pdqid, data, datapri)
+#endif /* LOG_IPSND_PDQ_ENTER */
+
+#ifndef LOG_IPSND_PDQ_LEAVE
+#define LOG_IPSND_PDQ_LEAVE(ercd)
+#endif /* LOG_IPSND_PDQ_LEAVE */
+
+#ifndef LOG_TSND_PDQ_ENTER
+#define LOG_TSND_PDQ_ENTER(pdqid, data, datapri, tmout)
+#endif /* LOG_TSND_PDQ_ENTER */
+
+#ifndef LOG_TSND_PDQ_LEAVE
+#define LOG_TSND_PDQ_LEAVE(ercd)
+#endif /* LOG_TSND_PDQ_LEAVE */
+
+#ifndef LOG_RCV_PDQ_ENTER
+#define LOG_RCV_PDQ_ENTER(pdqid, p_data, p_datapri)
+#endif /* LOG_RCV_PDQ_ENTER */
+
+#ifndef LOG_RCV_PDQ_LEAVE
+#define LOG_RCV_PDQ_LEAVE(ercd, data, datapri)
+#endif /* LOG_RCV_PDQ_LEAVE */
+
+#ifndef LOG_PRCV_PDQ_ENTER
+#define LOG_PRCV_PDQ_ENTER(pdqid, p_data, p_datapri)
+#endif /* LOG_PRCV_PDQ_ENTER */
+
+#ifndef LOG_PRCV_PDQ_LEAVE
+#define LOG_PRCV_PDQ_LEAVE(ercd, data, datapri)
+#endif /* LOG_PRCV_PDQ_LEAVE */
+
+#ifndef LOG_TRCV_PDQ_ENTER
+#define LOG_TRCV_PDQ_ENTER(pdqid, p_data, p_datapri, tmout)
+#endif /* LOG_TRCV_PDQ_ENTER */
+
+#ifndef LOG_TRCV_PDQ_LEAVE
+#define LOG_TRCV_PDQ_LEAVE(ercd, data, datapri)
+#endif /* LOG_TRCV_PDQ_LEAVE */
+
+#ifndef LOG_INI_PDQ_ENTER
+#define LOG_INI_PDQ_ENTER(pdqid)
+#endif /* LOG_INI_PDQ_ENTER */
+
+#ifndef LOG_INI_PDQ_LEAVE
+#define LOG_INI_PDQ_LEAVE(ercd)
+#endif /* LOG_INI_PDQ_LEAVE */
+
+#ifndef LOG_REF_PDQ_ENTER
+#define LOG_REF_PDQ_ENTER(pdqid, pk_rpdq)
+#endif /* LOG_REF_PDQ_ENTER */
+
+#ifndef LOG_REF_PDQ_LEAVE
+#define LOG_REF_PDQ_LEAVE(ercd, pk_rpdq)
+#endif /* LOG_REF_PDQ_LEAVE */
+
+/*
+ *  Dæxf[^L
+[Ì
+ */
+#define tnum_pdq	((uint_t)(tmax_pdqid - TMIN_PDQID + 1))
+#define tnum_spdq	((uint_t)(tmax_spdqid - TMIN_PDQID + 1))
+
+/*
+ *  Dæxf[^L
+[ID©çDæxf[^L
+[ÇubNðæèo·½
+ *  ßÌ}N
+ */
+#define INDEX_PDQ(pdqid)	((uint_t)((pdqid) - TMIN_PDQID))
+#define get_pdqcb(pdqid)	(&(pdqcb_table[INDEX_PDQ(pdqid)]))
+
+#ifdef TOPPERS_pdqini
+
+/*
+ *  gpµÄ¢È¢Dæxf[^L
+[ÇubNÌXg
+ */
+QUEUE	free_pdqcb;
+
+/*
+ *  Dæxf[^L
+[@\Ìú»
+ */
+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 */
+
+/*
+ *  Dæxf[^L
+[ÇÌæÖÌf[^Ìi[
+ */
+#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 */
+
+/*
+ *  Dæxf[^L
+[ÇÌæ©çÌf[^Ìæoµ
+ */
+#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 */
+
+/*
+ *  Dæxf[^L
+[ÖÌf[^M
+ */
+#ifdef TOPPERS_pdqsnd
+
+bool_t
+send_pridata(PDQCB *p_pdqcb, intptr_t data, PRI datapri, bool_t *p_dspreq)
+{
+	TCB		*p_tcb;
+
+	if (!queue_empty(&(p_pdqcb->rwait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_pdqcb->rwait_queue));
+		((WINFO_PDQ *)(p_tcb->p_winfo))->data = data;
+		((WINFO_PDQ *)(p_tcb->p_winfo))->datapri = datapri;
+		*p_dspreq = wait_complete(p_tcb);
+		return(true);
+	}
+	else if (p_pdqcb->count < p_pdqcb->p_pdqinib->pdqcnt) {
+		enqueue_pridata(p_pdqcb, data, datapri);
+		*p_dspreq = false;
+		return(true);
+	}
+	else {
+		return(false);
+	}
+}
+
+#endif /* TOPPERS_pdqsnd */
+
+/*
+ *  Dæxf[^L
+[©çÌf[^óM
+ */
+#ifdef TOPPERS_pdqrcv
+
+bool_t
+receive_pridata(PDQCB *p_pdqcb, intptr_t *p_data,
+									PRI *p_datapri, bool_t *p_dspreq)
+{
+	TCB		*p_tcb;
+	intptr_t data;
+	PRI		datapri;
+
+	if (p_pdqcb->count > 0U) {
+		dequeue_pridata(p_pdqcb, p_data, p_datapri);
+		if (!queue_empty(&(p_pdqcb->swait_queue))) {
+			p_tcb = (TCB *) queue_delete_next(&(p_pdqcb->swait_queue));
+			data = ((WINFO_PDQ *)(p_tcb->p_winfo))->data;
+			datapri = ((WINFO_PDQ *)(p_tcb->p_winfo))->datapri;
+			enqueue_pridata(p_pdqcb, data, datapri);
+			*p_dspreq = wait_complete(p_tcb);
+		}
+		else {
+			*p_dspreq = false;
+		}
+		return(true);
+	}
+	else if (!queue_empty(&(p_pdqcb->swait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_pdqcb->swait_queue));
+		*p_data = ((WINFO_PDQ *)(p_tcb->p_winfo))->data;
+		*p_datapri = ((WINFO_PDQ *)(p_tcb->p_winfo))->datapri;
+		*p_dspreq = wait_complete(p_tcb);
+		return(true);
+	}
+	else {
+		return(false);
+	}
+}
+
+#endif /* TOPPERS_pdqrcv */
+
+/*
+ *  Dæxf[^L
+[Ì¶¬
+ */
+#ifdef TOPPERS_acre_pdq
+
+ER_UINT
+acre_pdq(const T_CPDQ *pk_cpdq)
+{
+	PDQCB	*p_pdqcb;
+	PDQINIB	*p_pdqinib;
+	ATR		pdqatr;
+	PDQMB	*p_pdqmb;
+	ER		ercd;
+
+	LOG_ACRE_PDQ_ENTER(pk_cpdq);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_cpdq->pdqatr, TA_TPRI);
+	CHECK_DPRI(pk_cpdq->maxdpri);
+	if (pk_cpdq->pdqmb != NULL) {
+		CHECK_ALIGN_MB(pk_cpdq->pdqmb);
+	}
+	pdqatr = pk_cpdq->pdqatr;
+	p_pdqmb = pk_cpdq->pdqmb;
+
+	t_lock_cpu();
+	if (tnum_pdq == 0 || queue_empty(&free_pdqcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		if (pk_cpdq->pdqcnt != 0 && p_pdqmb == NULL) {
+			p_pdqmb = kernel_malloc(sizeof(PDQMB) * pk_cpdq->pdqcnt);
+			pdqatr |= TA_MBALLOC;
+		}
+		if (pk_cpdq->pdqcnt != 0 && p_pdqmb == NULL) {
+			ercd = E_NOMEM;
+		}
+		else {
+			p_pdqcb = ((PDQCB *) queue_delete_next(&free_pdqcb));
+			p_pdqinib = (PDQINIB *)(p_pdqcb->p_pdqinib);
+			p_pdqinib->pdqatr = pdqatr;
+			p_pdqinib->pdqcnt = pk_cpdq->pdqcnt;
+			p_pdqinib->maxdpri = pk_cpdq->maxdpri;
+			p_pdqinib->p_pdqmb = p_pdqmb;
+
+			queue_initialize(&(p_pdqcb->swait_queue));
+			queue_initialize(&(p_pdqcb->rwait_queue));
+			p_pdqcb->count = 0U;
+			p_pdqcb->p_head = NULL;
+			p_pdqcb->unused = 0U;
+			p_pdqcb->p_freelist = NULL;
+			ercd = PDQID(p_pdqcb);
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_pdq */
+
+/*
+ *  Dæxf[^L
+[Ìí
+ */
+#ifdef TOPPERS_del_pdq
+
+ER
+del_pdq(ID pdqid)
+{
+	PDQCB	*p_pdqcb;
+	PDQINIB	*p_pdqinib;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_DEL_PDQ_ENTER(pdqid);
+	CHECK_TSKCTX_UNL();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (PDQID(p_pdqcb) > tmax_spdqid) {
+		dspreq = init_wait_queue(&(p_pdqcb->swait_queue));
+		if (init_wait_queue(&(p_pdqcb->rwait_queue))) {
+			dspreq = true;
+		}
+		p_pdqinib = (PDQINIB *)(p_pdqcb->p_pdqinib);
+		if ((p_pdqinib->pdqatr & TA_MBALLOC) != 0U) {
+			kernel_free(p_pdqinib->p_pdqmb);
+		}
+		p_pdqinib->pdqatr = TA_NOEXS;
+		queue_insert_prev(&free_pdqcb, &(p_pdqcb->swait_queue));
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_pdq */
+
+/*
+ *  Dæxf[^L
+[ÖÌM
+ */
+#ifdef TOPPERS_snd_pdq
+
+ER
+snd_pdq(ID pdqid, intptr_t data, PRI datapri)
+{
+	PDQCB	*p_pdqcb;
+	WINFO_PDQ winfo_pdq;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_SND_PDQ_ENTER(pdqid, data, datapri);
+	CHECK_DISPATCH();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+	CHECK_PAR(TMIN_DPRI <= datapri);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!(datapri <= p_pdqcb->p_pdqinib->maxdpri)) {
+		ercd = E_PAR;
+	}
+	else if (send_pridata(p_pdqcb, data, datapri, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		winfo_pdq.data = data;
+		winfo_pdq.datapri = datapri;
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SPDQ);
+		wobj_make_wait((WOBJCB *) p_pdqcb, (WINFO_WOBJ *) &winfo_pdq);
+		dispatch();
+		ercd = winfo_pdq.winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_SND_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_snd_pdq */
+
+/*
+ *  Dæxf[^L
+[ÖÌMi|[Oj
+ */
+#ifdef TOPPERS_psnd_pdq
+
+ER
+psnd_pdq(ID pdqid, intptr_t data, PRI datapri)
+{
+	PDQCB	*p_pdqcb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_PSND_PDQ_ENTER(pdqid, data, datapri);
+	CHECK_TSKCTX_UNL();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+	CHECK_PAR(TMIN_DPRI <= datapri);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!(datapri <= p_pdqcb->p_pdqinib->maxdpri)) {
+		ercd = E_PAR;
+	}
+	else if (send_pridata(p_pdqcb, data, datapri, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_PSND_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_psnd_pdq */
+
+/*
+ *  Dæxf[^L
+[ÖÌMi|[OCñ^XNReLXgpj
+ */
+#ifdef TOPPERS_ipsnd_pdq
+
+ER
+ipsnd_pdq(ID pdqid, intptr_t data, PRI datapri)
+{
+	PDQCB	*p_pdqcb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_IPSND_PDQ_ENTER(pdqid, data, datapri);
+	CHECK_INTCTX_UNL();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+	CHECK_PAR(TMIN_DPRI <= datapri);
+
+	i_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!(datapri <= p_pdqcb->p_pdqinib->maxdpri)) {
+		ercd = E_PAR;
+	}
+	else if (send_pridata(p_pdqcb, data, datapri, &dspreq)) {
+		if (dspreq) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IPSND_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ipsnd_pdq */
+
+/*
+ *  Dæxf[^L
+[ÖÌMi^CAEg èj
+ */
+#ifdef TOPPERS_tsnd_pdq
+
+ER
+tsnd_pdq(ID pdqid, intptr_t data, PRI datapri, TMO tmout)
+{
+	PDQCB	*p_pdqcb;
+	WINFO_PDQ winfo_pdq;
+	TMEVTB	tmevtb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_TSND_PDQ_ENTER(pdqid, data, datapri, tmout);
+	CHECK_DISPATCH();
+	CHECK_PDQID(pdqid);
+	CHECK_TMOUT(tmout);
+	p_pdqcb = get_pdqcb(pdqid);
+	CHECK_PAR(TMIN_DPRI <= datapri);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!(datapri <= p_pdqcb->p_pdqinib->maxdpri)) {
+		ercd = E_PAR;
+	}
+	else if (send_pridata(p_pdqcb, data, datapri, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		winfo_pdq.data = data;
+		winfo_pdq.datapri = datapri;
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SPDQ);
+		wobj_make_wait_tmout((WOBJCB *) p_pdqcb, (WINFO_WOBJ *) &winfo_pdq,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_pdq.winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TSND_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_tsnd_pdq */
+
+/*
+ *  Dæxf[^L
+[©çÌóM
+ */
+#ifdef TOPPERS_rcv_pdq
+
+ER
+rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri)
+{
+	PDQCB	*p_pdqcb;
+	WINFO_PDQ winfo_pdq;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_RCV_PDQ_ENTER(pdqid, p_data, p_datapri);
+	CHECK_DISPATCH();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (receive_pridata(p_pdqcb, p_data, p_datapri, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_RPDQ);
+		make_wait(&(winfo_pdq.winfo));
+		queue_insert_prev(&(p_pdqcb->rwait_queue), &(p_runtsk->task_queue));
+		winfo_pdq.p_pdqcb = p_pdqcb;
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo_pdq.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_data = winfo_pdq.data;
+			*p_datapri = winfo_pdq.datapri;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_RCV_PDQ_LEAVE(ercd, *p_data, *p_datapri);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rcv_pdq */
+
+/*
+ *  Dæxf[^L
+[©çÌóMi|[Oj
+ */
+#ifdef TOPPERS_prcv_pdq
+
+ER
+prcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri)
+{
+	PDQCB	*p_pdqcb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_PRCV_PDQ_ENTER(pdqid, p_data, p_datapri);
+	CHECK_TSKCTX_UNL();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (receive_pridata(p_pdqcb, p_data, p_datapri, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_PRCV_PDQ_LEAVE(ercd, *p_data, *p_datapri);
+	return(ercd);
+}
+
+#endif /* TOPPERS_prcv_pdq */
+
+/*
+ *  Dæxf[^L
+[©çÌóMi^CAEg èj
+ */
+#ifdef TOPPERS_trcv_pdq
+
+ER
+trcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri, TMO tmout)
+{
+	PDQCB	*p_pdqcb;
+	WINFO_PDQ winfo_pdq;
+	TMEVTB	tmevtb;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_TRCV_PDQ_ENTER(pdqid, p_data, p_datapri, tmout);
+	CHECK_DISPATCH();
+	CHECK_PDQID(pdqid);
+	CHECK_TMOUT(tmout);
+	p_pdqcb = get_pdqcb(pdqid);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (receive_pridata(p_pdqcb, p_data, p_datapri, &dspreq)) {
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_RPDQ);
+		make_wait_tmout(&(winfo_pdq.winfo), &tmevtb, tmout);
+		queue_insert_prev(&(p_pdqcb->rwait_queue), &(p_runtsk->task_queue));
+		winfo_pdq.p_pdqcb = p_pdqcb;
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo_pdq.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_data = winfo_pdq.data;
+			*p_datapri = winfo_pdq.datapri;
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TRCV_PDQ_LEAVE(ercd, *p_data, *p_datapri);
+	return(ercd);
+}
+
+#endif /* TOPPERS_trcv_pdq */
+
+/*
+ *  Dæxf[^L
+[ÌÄú»
+ */
+#ifdef TOPPERS_ini_pdq
+
+ER
+ini_pdq(ID pdqid)
+{
+	PDQCB	*p_pdqcb;
+	bool_t	dspreq;
+	ER		ercd;
+    
+	LOG_INI_PDQ_ENTER(pdqid);
+	CHECK_TSKCTX_UNL();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		dspreq = init_wait_queue(&(p_pdqcb->swait_queue));
+		if (init_wait_queue(&(p_pdqcb->rwait_queue))) {
+			dspreq = true;
+		}
+		p_pdqcb->count = 0U;
+		p_pdqcb->p_head = NULL;
+		p_pdqcb->unused = 0U;
+		p_pdqcb->p_freelist = NULL;
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_INI_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ini_pdq */
+
+/*
+ *  Dæxf[^L
+[ÌóÔQÆ
+ */
+#ifdef TOPPERS_ref_pdq
+
+ER
+ref_pdq(ID pdqid, T_RPDQ *pk_rpdq)
+{
+	PDQCB	*p_pdqcb;
+	ER		ercd;
+    
+	LOG_REF_PDQ_ENTER(pdqid, pk_rpdq);
+	CHECK_TSKCTX_UNL();
+	CHECK_PDQID(pdqid);
+	p_pdqcb = get_pdqcb(pdqid);
+
+	t_lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		pk_rpdq->stskid = wait_tskid(&(p_pdqcb->swait_queue));
+		pk_rpdq->rtskid = wait_tskid(&(p_pdqcb->rwait_queue));
+		pk_rpdq->spdqcnt = p_pdqcb->count;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_PDQ_LEAVE(ercd, pk_rpdq);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_pdq */
Index: UsbWattMeter/trunk/asp_dcre/kernel/pridataq.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/pridataq.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/pridataq.h	(revision 164)
@@ -0,0 +1,195 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		Dæxf[^L
+[@\
+ */
+
+#ifndef TOPPERS_PRIDATAQ_H
+#define TOPPERS_PRIDATAQ_H
+
+#include "wait.h"
+
+/*
+ *  Dæxf[^ÇubN
+ */
+typedef struct pridata_management_block PDQMB;
+
+struct pridata_management_block {
+	PDQMB		*p_next;		/* Ìf[^ */
+	intptr_t	data;			/* f[^{Ì */
+	PRI			datapri;		/* f[^Dæx */
+};
+
+/*
+ *  Dæxf[^L
+[ú»ubN
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌú»ubNÌ¤Êª
+ *  iWOBJINIBjðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅC
+ *  ÅÌtB[hª¤ÊÉÈÁÄ¢éD
+ */
+typedef struct pridataq_initialization_block {
+	ATR			pdqatr;			/* Dæxf[^L
+[®« */
+	uint_t		pdqcnt;			/* Dæxf[^L
+[ÌeÊ */
+	PRI			maxdpri;		/* f[^DæxÌÅål */
+	PDQMB		*p_pdqmb;		/* Dæxf[^L
+[ÇÌæÌæªÔn */
+} PDQINIB;
+
+/*
+ *  Dæxf[^L
+[ÇubN
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌÇubNÌ¤ÊªiWOBJCBj
+ *  ðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅCÅÌ2ÂÌ
+ *  tB[hª¤ÊÉÈÁÄ¢éD
+ */
+typedef struct pridataq_control_block {
+	QUEUE		swait_queue;	/* Dæxf[^L
+[MÒ¿L
+[ */
+	const PDQINIB *p_pdqinib;	/* ú»ubNÖÌ|C^ */
+	QUEUE		rwait_queue;	/* Dæxf[^L
+[óMÒ¿L
+[ */
+	uint_t		count;			/* Dæxf[^L
+[Ìf[^Ì */
+	PDQMB		*p_head;		/* ÅÌf[^ */
+	uint_t		unused;			/* ¢gpf[^ÇubNÌæª */
+	PDQMB		*p_freelist;	/* ¢Äf[^ÇubNÌXg */
+} PDQCB;
+
+/*
+ *  Dæxf[^L
+[Ò¿îñubNÌè`
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌÒ¿îñubNÌ¤Êª
+ *  iWINFO_WOBJjðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅC
+ *  ÅÌ2ÂÌtB[hª¤ÊÉÈÁÄ¢éD
+ *  Dæxf[^L
+[ÖÌMÒ¿ÆDæxf[^L
+[©çÌóMÒ¿ÅC
+ *  ¯¶Ò¿îñubNðg¤D
+ */
+typedef struct pridataq_waiting_information {
+	WINFO		winfo;			/* WÌÒ¿îñubN */
+	PDQCB		*p_pdqcb;		/* ÒÁÄ¢éDæxf[^L
+[ÌÇubN*/
+	intptr_t	data;			/* óMf[^ */
+	PRI			datapri;		/* f[^Dæx */
+} WINFO_PDQ;
+
+/*
+ *  gpµÄ¢È¢Dæxf[^L
+[ÇubNÌXg
+ */
+extern QUEUE	free_pdqcb;
+
+/*
+ *  Dæxf[^L
+[IDÌÅålikernel_cfg.cj
+ */
+extern const ID	tmax_pdqid;
+extern const ID	tmax_spdqid;
+
+/*
+ *  Dæxf[^L
+[ú»ubNÌGAikernel_cfg.cj
+ */
+extern const PDQINIB	pdqinib_table[];
+extern PDQINIB			apdqinib_table[];
+
+/*
+ *  Dæxf[^L
+[ÇubNÌGAikernel_cfg.cj
+ */
+extern PDQCB	pdqcb_table[];
+
+/*
+ *  Dæxf[^L
+[ÇubN©çDæxf[^L
+[IDðæèo·½
+ *  ßÌ}N
+ */
+#define	PDQID(p_pdqcb)	((ID)(((p_pdqcb) - pdqcb_table) + TMIN_PDQID))
+
+/*
+ *  Dæxf[^L
+[@\Ìú»
+ */
+extern void	initialize_pridataq(void);
+
+/*
+ *  Dæxf[^L
+[ÇÌæÖÌf[^Ìi[
+ */
+extern void	enqueue_pridata(PDQCB *p_pdqcb, intptr_t data, PRI datapri);
+
+/*
+ *  Dæxf[^L
+[ÇÌæ©çÌf[^Ìæoµ
+ */
+extern void	dequeue_pridata(PDQCB *p_pdqcb, intptr_t *p_data, PRI *p_datapri);
+
+/*
+ *  Dæxf[^L
+[ÖÌf[^M
+ */
+extern bool_t	send_pridata(PDQCB *p_pdqcb, intptr_t data,
+											PRI datapri, bool_t *p_dspreq);
+
+/*
+ *  Dæxf[^L
+[©çÌf[^óM
+ */
+extern bool_t	receive_pridata(PDQCB *p_pdqcb, intptr_t *p_data,
+											PRI *p_datapri, bool_t *p_dspreq);
+
+#endif /* TOPPERS_PRIDATAQ_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/semaphore.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/semaphore.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/semaphore.c	(revision 164)
@@ -0,0 +1,545 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		Z}tH@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "semaphore.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_ACRE_SEM_ENTER
+#define LOG_ACRE_SEM_ENTER(pk_csem)
+#endif /* LOG_ACRE_SEM_ENTER */
+
+#ifndef LOG_ACRE_SEM_LEAVE
+#define LOG_ACRE_SEM_LEAVE(ercd)
+#endif /* LOG_ACRE_SEM_LEAVE */
+
+#ifndef LOG_DEL_SEM_ENTER
+#define LOG_DEL_SEM_ENTER(semid)
+#endif /* LOG_DEL_SEM_ENTER */
+
+#ifndef LOG_DEL_SEM_LEAVE
+#define LOG_DEL_SEM_LEAVE(ercd)
+#endif /* LOG_DEL_SEM_LEAVE */
+
+#ifndef LOG_SIG_SEM_ENTER
+#define LOG_SIG_SEM_ENTER(semid)
+#endif /* LOG_SIG_SEM_ENTER */
+
+#ifndef LOG_SIG_SEM_LEAVE
+#define LOG_SIG_SEM_LEAVE(ercd)
+#endif /* LOG_SIG_SEM_LEAVE */
+
+#ifndef LOG_ISIG_SEM_ENTER
+#define LOG_ISIG_SEM_ENTER(semid)
+#endif /* LOG_ISIG_SEM_ENTER */
+
+#ifndef LOG_ISIG_SEM_LEAVE
+#define LOG_ISIG_SEM_LEAVE(ercd)
+#endif /* LOG_ISIG_SEM_LEAVE */
+
+#ifndef LOG_WAI_SEM_ENTER
+#define LOG_WAI_SEM_ENTER(semid)
+#endif /* LOG_WAI_SEM_ENTER */
+
+#ifndef LOG_WAI_SEM_LEAVE
+#define LOG_WAI_SEM_LEAVE(ercd)
+#endif /* LOG_WAI_SEM_LEAVE */
+
+#ifndef LOG_POL_SEM_ENTER
+#define LOG_POL_SEM_ENTER(semid)
+#endif /* LOG_POL_SEM_ENTER */
+
+#ifndef LOG_POL_SEM_LEAVE
+#define LOG_POL_SEM_LEAVE(ercd)
+#endif /* LOG_POL_SEM_LEAVE */
+
+#ifndef LOG_TWAI_SEM_ENTER
+#define LOG_TWAI_SEM_ENTER(semid, tmout)
+#endif /* LOG_TWAI_SEM_ENTER */
+
+#ifndef LOG_TWAI_SEM_LEAVE
+#define LOG_TWAI_SEM_LEAVE(ercd)
+#endif /* LOG_TWAI_SEM_LEAVE */
+
+#ifndef LOG_INI_SEM_ENTER
+#define LOG_INI_SEM_ENTER(semid)
+#endif /* LOG_INI_SEM_ENTER */
+
+#ifndef LOG_INI_SEM_LEAVE
+#define LOG_INI_SEM_LEAVE(ercd)
+#endif /* LOG_INI_SEM_LEAVE */
+
+#ifndef LOG_REF_SEM_ENTER
+#define LOG_REF_SEM_ENTER(semid, pk_rsem)
+#endif /* LOG_REF_SEM_ENTER */
+
+#ifndef LOG_REF_SEM_LEAVE
+#define LOG_REF_SEM_LEAVE(ercd, pk_rsem)
+#endif /* LOG_REF_SEM_LEAVE */
+
+/*
+ *  Z}tHÌ
+ */
+#define tnum_sem	((uint_t)(tmax_semid - TMIN_SEMID + 1))
+#define tnum_ssem	((uint_t)(tmax_ssemid - TMIN_SEMID + 1))
+
+/*
+ *  Z}tHID©çZ}tHÇubNðæèo·½ßÌ}N
+ */
+#define INDEX_SEM(semid)	((uint_t)((semid) - TMIN_SEMID))
+#define get_semcb(semid)	(&(semcb_table[INDEX_SEM(semid)]))
+
+#ifdef TOPPERS_semini
+
+/*
+ *  gpµÄ¢È¢Z}tHÇubNÌXg
+ */
+QUEUE	free_semcb;
+
+/* 
+ *  Z}tH@\Ìú»
+ */
+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 */
+
+/*
+ *  Z}tHÌ¶¬
+ */
+#ifdef TOPPERS_acre_sem
+
+ER_UINT
+acre_sem(const T_CSEM *pk_csem)
+{
+	SEMCB	*p_semcb;
+	SEMINIB	*p_seminib;
+	ER		ercd;
+
+	LOG_ACRE_SEM_ENTER(pk_csem);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_csem->sematr, TA_TPRI);
+	CHECK_PAR(0 <= pk_csem->isemcnt && pk_csem->isemcnt <= pk_csem->maxsem);
+	CHECK_PAR(1 <= pk_csem->maxsem && pk_csem->maxsem <= TMAX_MAXSEM);
+
+	t_lock_cpu();
+	if (tnum_sem == 0 || queue_empty(&free_semcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		p_semcb = ((SEMCB *) queue_delete_next(&free_semcb));
+		p_seminib = (SEMINIB *)(p_semcb->p_seminib);
+		p_seminib->sematr = pk_csem->sematr;
+		p_seminib->isemcnt = pk_csem->isemcnt;
+		p_seminib->maxsem = pk_csem->maxsem;
+
+		queue_initialize(&(p_semcb->wait_queue));
+		p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
+		ercd = SEMID(p_semcb);
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_sem */
+
+/*
+ *  Z}tHÌí
+ */
+#ifdef TOPPERS_del_sem
+
+ER
+del_sem(ID semid)
+{
+	SEMCB	*p_semcb;
+	SEMINIB	*p_seminib;
+	bool_t	dspreq;
+	ER		ercd;
+
+	LOG_DEL_SEM_ENTER(semid);
+	CHECK_TSKCTX_UNL();
+	CHECK_SEMID(semid);
+	p_semcb = get_semcb(semid);
+
+	t_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (SEMID(p_semcb) > tmax_ssemid) {
+		dspreq = init_wait_queue(&(p_semcb->wait_queue));
+		p_seminib = (SEMINIB *)(p_semcb->p_seminib);
+		p_seminib->sematr = TA_NOEXS;
+		queue_insert_prev(&free_semcb, &(p_semcb->wait_queue));
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_sem */
+
+/*
+ *  Z}tH¹ÌÔp
+ */
+#ifdef TOPPERS_sig_sem
+
+ER
+sig_sem(ID semid)
+{
+	SEMCB	*p_semcb;
+	TCB		*p_tcb;
+	ER		ercd;
+    
+	LOG_SIG_SEM_ENTER(semid);
+	CHECK_TSKCTX_UNL();
+	CHECK_SEMID(semid);
+	p_semcb = get_semcb(semid);
+
+	t_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!queue_empty(&(p_semcb->wait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
+		if (wait_complete(p_tcb)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
+		p_semcb->semcnt += 1;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_QOVR;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_SIG_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_sig_sem */
+
+/*
+ *  Z}tH¹ÌÔpiñ^XNReLXgpj
+ */
+#ifdef TOPPERS_isig_sem
+
+ER
+isig_sem(ID semid)
+{
+	SEMCB	*p_semcb;
+	TCB		*p_tcb;
+	ER		ercd;
+    
+	LOG_ISIG_SEM_ENTER(semid);
+	CHECK_INTCTX_UNL();
+	CHECK_SEMID(semid);
+	p_semcb = get_semcb(semid);
+
+	i_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!queue_empty(&(p_semcb->wait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
+		if (wait_complete(p_tcb)) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
+		p_semcb->semcnt += 1;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_QOVR;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_ISIG_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_isig_sem */
+
+/*
+ *  Z}tH¹Ìl¾
+ */
+#ifdef TOPPERS_wai_sem
+
+ER
+wai_sem(ID semid)
+{
+	SEMCB	*p_semcb;
+	WINFO_SEM winfo_sem;
+	ER		ercd;
+
+	LOG_WAI_SEM_ENTER(semid);
+	CHECK_DISPATCH();
+	CHECK_SEMID(semid);
+	p_semcb = get_semcb(semid);
+
+	t_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_semcb->semcnt >= 1) {
+		p_semcb->semcnt -= 1;
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
+		wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
+		dispatch();
+		ercd = winfo_sem.winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_WAI_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_wai_sem */
+
+/*
+ *  Z}tH¹Ìl¾i|[Oj
+ */
+#ifdef TOPPERS_pol_sem
+
+ER
+pol_sem(ID semid)
+{
+	SEMCB	*p_semcb;
+	ER		ercd;
+
+	LOG_POL_SEM_ENTER(semid);
+	CHECK_TSKCTX_UNL();
+	CHECK_SEMID(semid);
+	p_semcb = get_semcb(semid);
+
+	t_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_semcb->semcnt >= 1) {
+		p_semcb->semcnt -= 1;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_POL_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_pol_sem */
+
+/*
+ *  Z}tH¹Ìl¾i^CAEg èj
+ */
+#ifdef TOPPERS_twai_sem
+
+ER
+twai_sem(ID semid, TMO tmout)
+{
+	SEMCB	*p_semcb;
+	WINFO_SEM winfo_sem;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_TWAI_SEM_ENTER(semid, tmout);
+	CHECK_DISPATCH();
+	CHECK_SEMID(semid);
+	CHECK_TMOUT(tmout);
+	p_semcb = get_semcb(semid);
+
+	t_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_semcb->semcnt >= 1) {
+		p_semcb->semcnt -= 1;
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
+		wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_sem.winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TWAI_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_twai_sem */
+
+/*
+ *  Z}tHÌÄú»
+ */
+#ifdef TOPPERS_ini_sem
+
+ER
+ini_sem(ID semid)
+{
+	SEMCB	*p_semcb;
+	bool_t	dspreq;
+	ER		ercd;
+    
+	LOG_INI_SEM_ENTER(semid);
+	CHECK_TSKCTX_UNL();
+	CHECK_SEMID(semid);
+	p_semcb = get_semcb(semid);
+
+	t_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		dspreq = init_wait_queue(&(p_semcb->wait_queue));
+		p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
+		if (dspreq) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_INI_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ini_sem */
+
+/*
+ *  Z}tHÌóÔQÆ
+ */
+#ifdef TOPPERS_ref_sem
+
+ER
+ref_sem(ID semid, T_RSEM *pk_rsem)
+{
+	SEMCB	*p_semcb;
+	ER		ercd;
+    
+	LOG_REF_SEM_ENTER(semid, pk_rsem);
+	CHECK_TSKCTX_UNL();
+	CHECK_SEMID(semid);
+	p_semcb = get_semcb(semid);
+
+	t_lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		pk_rsem->wtskid = wait_tskid(&(p_semcb->wait_queue));
+		pk_rsem->semcnt = p_semcb->semcnt;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_SEM_LEAVE(ercd, pk_rsem);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_sem */
Index: UsbWattMeter/trunk/asp_dcre/kernel/semaphore.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/semaphore.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/semaphore.h	(revision 164)
@@ -0,0 +1,127 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		Z}tH@\
+ */
+
+#ifndef TOPPERS_SEMAPHORE_H
+#define TOPPERS_SEMAPHORE_H
+
+#include "wait.h"
+
+/*
+ *  Z}tHú»ubN
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌú»ubNÌ¤Êª
+ *  iWOBJINIBjðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅC
+ *  ÅÌtB[hª¤ÊÉÈÁÄ¢éD
+ */
+typedef struct semaphore_initialization_block {
+	ATR			sematr;			/* Z}tH®« */
+	uint_t		isemcnt;		/* Z}tHÌ¹Ìúl */
+	uint_t		maxsem;			/* Z}tHÌÅå¹ */
+} SEMINIB;
+
+/*
+ *  Z}tHÇubN
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌÇubNÌ¤ÊªiWOBJCBj
+ *  ðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅCÅÌ2ÂÌ
+ *  tB[hª¤ÊÉÈÁÄ¢éD
+ */
+typedef struct semaphore_control_block {
+	QUEUE		wait_queue;		/* Z}tHÒ¿L
+[ */
+	const SEMINIB *p_seminib;	/* ú»ubNÖÌ|C^ */
+	uint_t		semcnt;			/* Z}tH»ÝJEgl */
+} SEMCB;
+
+/*
+ *  Z}tHÒ¿îñubNÌè`
+ *
+ *  ±Ì\¢ÌÍC¯úEÊMIuWFNgÌÒ¿îñubNÌ¤Êª
+ *  iWINFO_WOBJjðg£iIuWFNgwü¾êÌp³Éjµ½àÌÅC
+ *  ·×ÄÌtB[hª¤ÊÉÈÁÄ¢éD
+ */
+typedef struct semaphore_waiting_information {
+	WINFO	winfo;			/* WÌÒ¿îñubN */
+	SEMCB	*p_semcb;		/* ÒÁÄ¢éZ}tHÌÇubN */
+} WINFO_SEM;
+
+/*
+ *  gpµÄ¢È¢Z}tHÇubNÌXg
+ */
+extern QUEUE	free_semcb;
+
+/*
+ *  Z}tHIDÌÅålikernel_cfg.cj
+ */
+extern const ID	tmax_semid;
+extern const ID	tmax_ssemid;
+
+/*
+ *  Z}tHú»ubNÌGAikernel_cfg.cj
+ */
+extern const SEMINIB	seminib_table[];
+extern SEMINIB			aseminib_table[];
+
+/*
+ *  Z}tHÇubNÌGAikernel_cfg.cj
+ */
+extern SEMCB	semcb_table[];
+
+/*
+ *  Z}tHÇubN©çZ}tHIDðæèo·½ßÌ}N
+ */
+#define	SEMID(p_semcb)	((ID)(((p_semcb) - semcb_table) + TMIN_SEMID))
+
+/*
+ *  Z}tH@\Ìú»
+ */
+extern void	initialize_semaphore(void);
+
+#endif /* TOPPERS_SEMAPHORE_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/startup.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/startup.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/startup.c	(revision 164)
@@ -0,0 +1,218 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		J[lÌú»ÆI¹
+ */
+
+#include "kernel_impl.h"
+#include "time_event.h"
+#include <sil.h>
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#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
+
+/*
+ *  J[l®ìóÔtO
+ *
+ *  X^[gAbv[`ÅCfalsei0jÉú»³êé±ÆðúÒµÄ
+ *  ¢éD
+ */
+bool_t	kerflg = false;
+
+/*
+ *  J[lÌN®
+ */
+void
+sta_ker(void)
+{
+	/*
+	 *  ^[QbgË¶Ìú»
+	 */
+	target_initialize();
+
+	/*
+	 *  eW
+[Ìú»
+	 *
+	 *  ^CCxgÇW
+[Í¼ÌW
+[æèæÉú»
+	 *  ·éKvª éD
+	 */
+	initialize_kmm();
+	initialize_tmevt();
+	initialize_object();
+
+	/*
+	 *  ú»[`ÌÀs
+	 */ 
+	call_inirtn();
+
+	/*
+	 *  J[l®ìÌJn
+	 */
+	kerflg = true;
+	LOG_KER_ENTER();
+	start_dispatch();
+	assert(0);
+}
+
+#endif /* TOPPERS_sta_ker */
+
+/*
+ *  J[lÌI¹
+ */
+#ifdef TOPPERS_ext_ker
+
+ER
+ext_ker(void)
+{
+	SIL_PRE_LOC;
+
+	LOG_EXT_KER_ENTER();
+
+	/*
+	 *  ÝbNóÔÉÚs
+	 */
+	SIL_LOC_INT();
+
+	/*
+	 *  J[l®ìÌI¹
+	 */
+	LOG_KER_LEAVE();
+	kerflg = false;
+
+	/*
+	 *  J[lÌI¹ÌÄoµ
+	 *
+	 *  ñ^XNReLXgÉØè·¦ÄCexit_kernelðÄÑo·D
+	 */
+	call_exit_kernel();
+
+	/*
+	 *  RpCÌxÎôi±±Öé±ÆÍÈ¢Í¸j
+	 */
+	SIL_UNL_INT();
+	LOG_EXT_KER_LEAVE(E_SYS);
+	return(E_SYS);
+}
+
+/*
+ *  J[lÌI¹
+ */
+void
+exit_kernel(void)
+{
+	/*
+	 *  I¹[`ÌÀs
+	 */
+	call_terrtn();
+
+	/*
+	 *  ^[QbgË¶ÌI¹
+	 */
+	target_exit();
+	assert(0);
+}
+
+#endif /* TOPPERS_ext_ker */
+
+/*
+ *  J[lÌèt¯éÌæÌÇ
+ *
+ *  Ìæðæª©çÉèÄCðú³ê½ÌæðÄpµÈ
+ *  ¢ÇW
+[D
+ */
+#ifdef TOPPERS_kermem
+#ifndef OMIT_KMM_ALLOCONLY
+
+static void	*kmm_brk;
+
+void
+initialize_kmm(void)
+{
+	kmm_brk = ((char *) kmm) + kmmsz;
+}
+
+void *
+kernel_malloc(SIZE size)
+{
+	if (((char *) kmm_brk) - ((char *) kmm) >= size) {
+		kmm_brk = ((char *) kmm_brk) - size;
+		return(kmm_brk);
+	}
+	else {
+		return(NULL);
+	}
+}
+
+void
+kernel_free(void *ptr)
+{
+}
+
+#endif /* OMIT_KMM_ALLOCONLY */
+#endif /* TOPPERS_kermem */
Index: UsbWattMeter/trunk/asp_dcre/kernel/sys_manage.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/sys_manage.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/sys_manage.c	(revision 164)
@@ -0,0 +1,539 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		VXeóÔÇ@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_ROT_RDQ_ENTER
+#define LOG_ROT_RDQ_ENTER(tskpri)
+#endif /* LOG_ROT_RDQ_ENTER */
+
+#ifndef LOG_ROT_RDQ_LEAVE
+#define LOG_ROT_RDQ_LEAVE(ercd)
+#endif /* LOG_ROT_RDQ_LEAVE */
+
+#ifndef LOG_IROT_RDQ_ENTER
+#define LOG_IROT_RDQ_ENTER(tskpri)
+#endif /* LOG_IROT_RDQ_ENTER */
+
+#ifndef LOG_IROT_RDQ_LEAVE
+#define LOG_IROT_RDQ_LEAVE(ercd)
+#endif /* LOG_IROT_RDQ_LEAVE */
+
+#ifndef LOG_GET_TID_ENTER
+#define LOG_GET_TID_ENTER(p_tskid)
+#endif /* LOG_GET_TID_ENTER */
+
+#ifndef LOG_GET_TID_LEAVE
+#define LOG_GET_TID_LEAVE(ercd, tskid)
+#endif /* LOG_GET_TID_LEAVE */
+
+#ifndef LOG_IGET_TID_ENTER
+#define LOG_IGET_TID_ENTER(p_tskid)
+#endif /* LOG_IGET_TID_ENTER */
+
+#ifndef LOG_IGET_TID_LEAVE
+#define LOG_IGET_TID_LEAVE(ercd, tskid)
+#endif /* LOG_IGET_TID_LEAVE */
+
+#ifndef LOG_LOC_CPU_ENTER
+#define LOG_LOC_CPU_ENTER()
+#endif /* LOG_LOC_CPU_ENTER */
+
+#ifndef LOG_LOC_CPU_LEAVE
+#define LOG_LOC_CPU_LEAVE(ercd)
+#endif /* LOG_LOC_CPU_LEAVE */
+
+#ifndef LOG_ILOC_CPU_ENTER
+#define LOG_ILOC_CPU_ENTER()
+#endif /* LOG_ILOC_CPU_ENTER */
+
+#ifndef LOG_ILOC_CPU_LEAVE
+#define LOG_ILOC_CPU_LEAVE(ercd)
+#endif /* LOG_ILOC_CPU_LEAVE */
+
+#ifndef LOG_UNL_CPU_ENTER
+#define LOG_UNL_CPU_ENTER()
+#endif /* LOG_UNL_CPU_ENTER */
+
+#ifndef LOG_UNL_CPU_LEAVE
+#define LOG_UNL_CPU_LEAVE(ercd)
+#endif /* LOG_UNL_CPU_LEAVE */
+
+#ifndef LOG_IUNL_CPU_ENTER
+#define LOG_IUNL_CPU_ENTER()
+#endif /* LOG_IUNL_CPU_ENTER */
+
+#ifndef LOG_IUNL_CPU_LEAVE
+#define LOG_IUNL_CPU_LEAVE(ercd)
+#endif /* LOG_IUNL_CPU_LEAVE */
+
+#ifndef LOG_DIS_DSP_ENTER
+#define LOG_DIS_DSP_ENTER()
+#endif /* LOG_DIS_DSP_ENTER */
+
+#ifndef LOG_DIS_DSP_LEAVE
+#define LOG_DIS_DSP_LEAVE(ercd)
+#endif /* LOG_DIS_DSP_LEAVE */
+
+#ifndef LOG_ENA_DSP_ENTER
+#define LOG_ENA_DSP_ENTER()
+#endif /* LOG_ENA_DSP_ENTER */
+
+#ifndef LOG_ENA_DSP_LEAVE
+#define LOG_ENA_DSP_LEAVE(ercd)
+#endif /* LOG_ENA_DSP_LEAVE */
+
+#ifndef LOG_SNS_CTX_ENTER
+#define LOG_SNS_CTX_ENTER()
+#endif /* LOG_SNS_CTX_ENTER */
+
+#ifndef LOG_SNS_CTX_LEAVE
+#define LOG_SNS_CTX_LEAVE(state)
+#endif /* LOG_SNS_CTX_LEAVE */
+
+#ifndef LOG_SNS_LOC_ENTER
+#define LOG_SNS_LOC_ENTER()
+#endif /* LOG_SNS_LOC_ENTER */
+
+#ifndef LOG_SNS_LOC_LEAVE
+#define LOG_SNS_LOC_LEAVE(state)
+#endif /* LOG_SNS_LOC_LEAVE */
+
+#ifndef LOG_SNS_DSP_ENTER
+#define LOG_SNS_DSP_ENTER()
+#endif /* LOG_SNS_DSP_ENTER */
+
+#ifndef LOG_SNS_DSP_LEAVE
+#define LOG_SNS_DSP_LEAVE(state)
+#endif /* LOG_SNS_DSP_LEAVE */
+
+#ifndef LOG_SNS_DPN_ENTER
+#define LOG_SNS_DPN_ENTER()
+#endif /* LOG_SNS_DPN_ENTER */
+
+#ifndef LOG_SNS_DPN_LEAVE
+#define LOG_SNS_DPN_LEAVE(state)
+#endif /* LOG_SNS_DPN_LEAVE */
+
+#ifndef LOG_SNS_KER_ENTER
+#define LOG_SNS_KER_ENTER()
+#endif /* LOG_SNS_KER_ENTER */
+
+#ifndef LOG_SNS_KER_LEAVE
+#define LOG_SNS_KER_LEAVE(state)
+#endif /* LOG_SNS_KER_LEAVE */
+
+/*
+ *  ^XNÌDæÊÌñ]
+ */
+#ifdef TOPPERS_rot_rdq
+
+ER
+rot_rdq(PRI tskpri)
+{
+	uint_t	pri;
+	ER		ercd;
+
+	LOG_ROT_RDQ_ENTER(tskpri);
+	CHECK_TSKCTX_UNL();
+	CHECK_TPRI_SELF(tskpri);
+
+	t_lock_cpu();
+	pri = (tskpri == TPRI_SELF) ? p_runtsk->priority : INT_PRIORITY(tskpri);
+	if (rotate_ready_queue(pri)) {
+		dispatch();
+	}
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ROT_RDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rot_rdq */
+
+/*
+ *  ^XNÌDæÊÌñ]iñ^XNReLXgpj
+ */
+#ifdef TOPPERS_irot_rdq
+
+ER
+irot_rdq(PRI tskpri)
+{
+	ER		ercd;
+
+	LOG_IROT_RDQ_ENTER(tskpri);
+	CHECK_INTCTX_UNL();
+	CHECK_TPRI(tskpri);
+
+	i_lock_cpu();
+	if (rotate_ready_queue(INT_PRIORITY(tskpri))) {
+		reqflg = true;
+	}
+	ercd = E_OK;
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IROT_RDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_irot_rdq */
+
+/*
+ *  ÀsóÔÌ^XNIDÌQÆ
+ */
+#ifdef TOPPERS_get_tid
+
+ER
+get_tid(ID *p_tskid)
+{
+	ER		ercd;
+
+	LOG_GET_TID_ENTER(p_tskid);
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	*p_tskid = TSKID(p_runtsk);
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_GET_TID_LEAVE(ercd, *p_tskid);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_tid */
+
+/*
+ *  ÀsóÔÌ^XNIDÌQÆiñ^XNReLXgpj
+ */
+#ifdef TOPPERS_iget_tid
+
+ER
+iget_tid(ID *p_tskid)
+{
+	ER		ercd;
+
+	LOG_IGET_TID_ENTER(p_tskid);
+	CHECK_INTCTX_UNL();
+
+	i_lock_cpu();
+	*p_tskid = (p_runtsk == NULL) ? TSK_NONE : TSKID(p_runtsk);
+	ercd = E_OK;
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IGET_TID_LEAVE(ercd, *p_tskid);
+	return(ercd);
+}
+
+#endif /* TOPPERS_iget_tid */
+
+/*
+ *  CPUbNóÔÖÌÚs
+ */
+#ifdef TOPPERS_loc_cpu
+
+ER
+loc_cpu(void)
+{
+	ER		ercd;
+
+	LOG_LOC_CPU_ENTER();
+	CHECK_TSKCTX();
+
+	if (!t_sense_lock()) {
+		t_lock_cpu();
+	}
+	ercd = E_OK;
+
+  error_exit:
+	LOG_LOC_CPU_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_loc_cpu */
+
+/*
+ *  CPUbNóÔÖÌÚsiñ^XNReLXgpj
+ */
+#ifdef TOPPERS_iloc_cpu
+
+ER
+iloc_cpu(void)
+{
+	ER		ercd;
+
+	LOG_ILOC_CPU_ENTER();
+	CHECK_INTCTX();
+
+	if (!i_sense_lock()) {
+		i_lock_cpu();
+	}
+	ercd = E_OK;
+
+  error_exit:
+	LOG_ILOC_CPU_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_iloc_cpu */
+
+/*
+ *  CPUbNóÔÌð
+ *
+ *  CPUbNÍCfBXpb`ªKvÆÈéT[rXR[ðÄÑo·±
+ *  ÆÍÅ«È¢½ßCCPUbNóÔÌðÉfBXpb`ðN®·é
+ *  KvÍÈ¢D
+ */
+#ifdef TOPPERS_unl_cpu
+
+ER
+unl_cpu(void)
+{
+	ER		ercd;
+
+	LOG_UNL_CPU_ENTER();
+	CHECK_TSKCTX();
+
+	if (t_sense_lock()) {
+		t_unlock_cpu();
+	}
+	ercd = E_OK;
+
+  error_exit:
+	LOG_UNL_CPU_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_unl_cpu */
+
+/*
+ *  CPUbNóÔÌðiñ^XNReLXgpj
+ *
+ *  CPUbNÍCfBXpb`ªKvÆÈéT[rXR[ðÄÑo·±
+ *  ÆÍÅ«È¢½ßCCPUbNóÔÌðÉfBXpb`ÌN®ðv
+ *  ·éKvÍÈ¢D
+ */
+#ifdef TOPPERS_iunl_cpu
+
+ER
+iunl_cpu(void)
+{
+	ER		ercd;
+
+	LOG_IUNL_CPU_ENTER();
+	CHECK_INTCTX();
+
+	if (i_sense_lock()) {
+		i_unlock_cpu();
+	}
+	ercd = E_OK;
+
+  error_exit:
+	LOG_IUNL_CPU_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_iunl_cpu */
+
+/*
+ *  fBXpb`ÌÖ~
+ */
+#ifdef TOPPERS_dis_dsp
+
+ER
+dis_dsp(void)
+{
+	ER		ercd;
+
+	LOG_DIS_DSP_ENTER();
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	disdsp = true;
+	dspflg = false;
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DIS_DSP_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_dis_dsp */
+
+/*
+ *  fBXpb`ÌÂ
+ */
+#ifdef TOPPERS_ena_dsp
+
+ER
+ena_dsp(void)
+{
+	ER		ercd;
+
+	LOG_ENA_DSP_ENTER();
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	disdsp = false;
+	if (ipmflg) {
+		dspflg = true;
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+	}
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ENA_DSP_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ena_dsp */
+
+/*
+ *  ReLXgÌQÆ
+ */
+#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 */
+
+/*
+ *  CPUbNóÔÌQÆ
+ */
+#ifdef TOPPERS_sns_loc
+
+bool_t
+sns_loc(void)
+{
+	bool_t	state;
+
+	LOG_SNS_LOC_ENTER();
+	state = x_sense_lock() ? true : false;
+	LOG_SNS_LOC_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_sns_loc */
+
+/*
+ *  fBXpb`Ö~óÔÌQÆ
+ */
+#ifdef TOPPERS_sns_dsp
+
+bool_t
+sns_dsp(void)
+{
+	bool_t	state;
+
+	LOG_SNS_DSP_ENTER();
+	state = disdsp;
+	LOG_SNS_DSP_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_sns_dsp */
+
+/*
+ *  fBXpb`Û¯óÔÌQÆ
+ */
+#ifdef TOPPERS_sns_dpn
+
+bool_t
+sns_dpn(void)
+{
+	bool_t	state;
+
+	LOG_SNS_DPN_ENTER();
+	state = (sense_context() || t_sense_lock() || !dspflg) ? true : false;
+	LOG_SNS_DPN_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_sns_dpn */
+
+/*
+ *  J[lñ®ìóÔÌQÆ
+ */
+#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: UsbWattMeter/trunk/asp_dcre/kernel/task.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/task.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/task.c	(revision 164)
@@ -0,0 +1,513 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  $Id$
+ */
+
+/*
+ *		^XNÇW
+[
+ */
+
+#include "kernel_impl.h"
+#include "wait.h"
+#include "task.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_TEX_ENTER
+#define LOG_TEX_ENTER(p_tcb, texptn)
+#endif /* LOG_TEX_ENTER */
+
+#ifndef LOG_TEX_LEAVE
+#define LOG_TEX_LEAVE(p_tcb, texptn)
+#endif /* LOG_TEX_LEAVE */
+
+#ifdef TOPPERS_tskini
+
+/*
+ *  ÀsóÔÌ^XN
+ */
+TCB		*p_runtsk;
+
+/*
+ *  ÅDæÊÌ^XN
+ */
+TCB		*p_schedtsk;
+
+/*
+ *  ^XNfBXpb`^^XNáO[`N®vtO
+ */
+bool_t	reqflg;
+
+/*
+ *  ÝDæx}XNSðóÔ
+ */
+bool_t	ipmflg;
+
+/*
+ *  fBXpb`Ö~óÔ
+ */
+bool_t	disdsp;
+
+/*
+ *  ^XNfBXpb`Â\óÔ
+ */
+bool_t	dspflg;
+
+/*
+ *  fBL
+[
+ */
+QUEUE	ready_queue[TNUM_TPRI];
+
+/*
+ *  fBL
+[T[`Ì½ßÌrbg}bv
+ */
+uint16_t	ready_primap;
+
+/*
+ *  gpµÄ¢È¢TCBÌXg
+ */
+QUEUE	free_tcb;
+
+/*
+ *  ^XNÇW
+[Ìú»
+ */
+void
+initialize_task(void)
+{
+	uint_t	i, j;
+	TCB		*p_tcb;
+	TINIB	*p_tinib;
+
+	p_runtsk = NULL;
+	p_schedtsk = NULL;
+	reqflg = false;
+	ipmflg = true;
+	disdsp = false;
+	dspflg = true;
+
+	for (i = 0; i < TNUM_TPRI; i++) {
+		queue_initialize(&(ready_queue[i]));
+	}
+	ready_primap = 0U;
+
+	for (i = 0; i < tnum_stsk; i++) {
+		j = INDEX_TSK(torder_table[i]);
+		p_tcb = &(tcb_table[j]);
+		p_tcb->p_tinib = &(tinib_table[j]);
+		p_tcb->actque = false;
+		make_dormant(p_tcb);
+		if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
+			(void) make_active(p_tcb);
+		}
+	}
+	queue_initialize(&free_tcb);
+	for (j = 0; i < tnum_tsk; i++, j++) {
+		p_tcb = &(tcb_table[i]);
+		p_tinib = &(atinib_table[j]);
+		p_tinib->tskatr = TA_NOEXS;
+		p_tcb->p_tinib = ((const TINIB *) p_tinib);
+		queue_insert_prev(&free_tcb, &(p_tcb->task_queue));
+	}
+}
+
+#endif /* TOPPERS_tskini */
+
+/*
+ *  rbg}bvT[`Ö
+ *
+ *  bitmapàÌ1ÌrbgÌàCÅàºÊiEjÌàÌðT[`µC»Ìrb
+ *  gÔðÔ·DrbgÔÍCÅºÊrbgð0Æ·éDbitmapÉ0ðwè
+ *  µÄÍÈçÈ¢D±ÌÖÅÍCbitmapª16rbgÅ é±Æð¼èµC
+ *  uint16_t^ÆµÄ¢éD
+ *
+ *  rbgT[`½ßðÂvZbTÅÍCrbgT[`½ßðg¤æ¤É
+ *  «¼µ½ûªø¦ªÇ¢êª éD±Ìæ¤ÈêÉÍC^[Qbg
+ *  Ë¶ÅrbgT[`½ßðgÁ½bitmap_searchðè`µC
+ *  OMIT_BITMAP_SEARCHð}Nè`·êÎæ¢DÜ½CrbgT[`½ßÌ
+ *  T[`ûüªtÈÇÌRÅDæxÆrbgÆÌÎðÏXµ½¢êÉ
+ *  ÍCPRIMAP_BITð}Nè`·êÎæ¢D
+ *
+ *  Ü½CCuÉffsª éÈçCÌæ¤Éè`µÄCuÖð
+ *  gÁ½ûªø¦ªÇ¢Â\«à éD
+ *		#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 */
+
+/*
+ *  Dæxrbg}bvªó©Ì`FbN
+ */
+Inline bool_t
+primap_empty(void)
+{
+	return(ready_primap == 0U);
+}
+
+/*
+ *  Dæxrbg}bvÌT[`
+ */
+Inline uint_t
+primap_search(void)
+{
+	return(bitmap_search(ready_primap));
+}
+
+/*
+ *  Dæxrbg}bvÌZbg
+ */
+Inline void
+primap_set(uint_t pri)
+{
+	ready_primap |= PRIMAP_BIT(pri);
+}
+
+/*
+ *  Dæxrbg}bvÌNA
+ */
+Inline void
+primap_clear(uint_t pri)
+{
+	ready_primap &= ~PRIMAP_BIT(pri);
+}
+
+/*
+ *  ÅDæÊ^XNÌT[`
+ */
+#ifdef TOPPERS_tsksched
+
+TCB *
+search_schedtsk(void)
+{
+	uint_t	schedpri;
+
+	schedpri = primap_search();
+	return((TCB *)(ready_queue[schedpri].p_next));
+}
+
+#endif /* TOPPERS_tsksched */
+
+/*
+ *  ÀsÅ«éóÔÖÌJÚ
+ *
+ *  ÅDæÊÌ^XNðXV·éÌÍCÀsÅ«é^XNªÈ©Á½ê
+ *  ÆCp_tcbÌDæxªÅDæÊÌ^XNÌDæxæèà¢êÅ 
+ *  éD
+ */
+#ifdef TOPPERS_tskrun
+
+bool_t
+make_runnable(TCB *p_tcb)
+{
+	uint_t	pri = p_tcb->priority;
+
+	queue_insert_prev(&(ready_queue[pri]), &(p_tcb->task_queue));
+	primap_set(pri);
+
+	if (p_schedtsk == (TCB *) NULL || pri < p_schedtsk->priority) {
+		p_schedtsk = p_tcb;
+		return(dspflg);
+	}
+	return(false);
+}
+
+#endif /* TOPPERS_tskrun */
+
+/*
+ *  ÀsÅ«éóÔ©ç¼ÌóÔÖÌJÚ
+ *
+ *  ÅDæÊÌ^XNðXV·éÌÍCp_tcbªÅDæÊÌ^XNÅ
+ *   Á½êÅ éDp_tcbÆ¯¶DæxÌ^XNª¼É éêÍCp_tcb
+ *  ÌÌ^XNªÅDæÊÉÈéD»¤ÅÈ¢êÍCfBL
+[ð
+ *  T[`·éKvª éD
+ */
+#ifdef TOPPERS_tsknrun
+
+bool_t
+make_non_runnable(TCB *p_tcb)
+{
+	uint_t	pri = p_tcb->priority;
+	QUEUE	*p_queue = &(ready_queue[pri]);
+
+	queue_delete(&(p_tcb->task_queue));
+	if (queue_empty(p_queue)) {
+		primap_clear(pri);
+		if (p_schedtsk == p_tcb) {
+			p_schedtsk = primap_empty() ? (TCB *) NULL : search_schedtsk();
+			return(dspflg);
+		}
+	}
+	else {
+		if (p_schedtsk == p_tcb) {
+			p_schedtsk = (TCB *)(p_queue->p_next);
+			return(dspflg);
+		}
+	}
+	return(false);
+}
+
+#endif /* TOPPERS_tsknrun */
+
+/*
+ *  x~óÔÖÌJÚ
+ */
+#ifdef TOPPERS_tskdmt
+
+void
+make_dormant(TCB *p_tcb)
+{
+	p_tcb->tstat = TS_DORMANT;
+	p_tcb->priority = p_tcb->p_tinib->ipriority;
+	p_tcb->wupque = false;
+	p_tcb->enatex = false;
+	p_tcb->texptn = 0U;
+	LOG_TSKSTAT(p_tcb);
+}
+
+#endif /* TOPPERS_tskdmt */
+
+/*
+ *  x~óÔ©çÀsÅ«éóÔÖÌJÚ
+ */
+#ifdef TOPPERS_tskact
+
+bool_t
+make_active(TCB *p_tcb)
+{
+	activate_context(p_tcb);
+	p_tcb->tstat = TS_RUNNABLE;
+	LOG_TSKSTAT(p_tcb);
+	return(make_runnable(p_tcb));
+}
+
+#endif /* TOPPERS_tskact */
+
+/*
+ *  ^XNÌDæxÌÏX
+ *
+ *  ^XNªÀsÅ«éóÔÌêÉÍCfBL
+[ÌÅÌÊuðÏX·
+ *  éDIuWFNgÌÒ¿L
+[ÌÅÒ¿óÔÉÈÁÄ¢éêÉÍCÒ
+ *  ¿L
+[ÌÅÌÊuðÏX·éD
+ *
+ *  ÅDæÊÌ^XNðXV·éÌÍC(1) p_tcbªÅDæÊÌ^X
+ *  NÅ ÁÄC»ÌDæxðº°½êC(2) p_tcbªÅDæÊÌ^X
+ *  NÅÍÈ­CÏXãÌDæxªÅDæÊÌ^XNÌDæxæèà¢
+ *  êÅ éD(1)ÌêÉÍCfBL
+[ðT[`·éKvª éD
+ */
+#ifdef TOPPERS_tskpri
+
+bool_t
+change_priority(TCB *p_tcb, uint_t newpri)
+{
+	uint_t	oldpri;
+
+	oldpri = p_tcb->priority;
+	p_tcb->priority = newpri;
+
+	if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+		/*
+		 *  ^XNªÀsÅ«éóÔÌê
+		 */
+		queue_delete(&(p_tcb->task_queue));
+		if (queue_empty(&(ready_queue[oldpri]))) {
+			primap_clear(oldpri);
+		}
+		queue_insert_prev(&(ready_queue[newpri]), &(p_tcb->task_queue));
+		primap_set(newpri);
+
+		if (p_schedtsk == p_tcb) {
+			if (newpri >= oldpri) {
+				p_schedtsk = search_schedtsk();
+				return(p_schedtsk != p_tcb && dspflg);
+			}
+		}
+		else {
+			if (newpri < p_schedtsk->priority) {
+				p_schedtsk = p_tcb;
+				return(dspflg);
+			}
+		}
+	}
+	else {
+		if (TSTAT_WAIT_WOBJCB(p_tcb->tstat)) {
+			/*
+			 *  ^XNªC¯úEÊMIuWFNgÌÇubNÌ¤Ê
+			 *  ªiWOBJCBjÌÒ¿L
+[ÉÂÈªêÄ¢éê
+			 */
+			wobj_change_priority(((WINFO_WOBJ *)(p_tcb->p_winfo))->p_wobjcb,
+																	p_tcb);
+		}
+	}
+	return(false);
+}
+
+#endif /* TOPPERS_tskpri */
+
+/*
+ *  fBL
+[Ìñ]
+ *
+ *  ÅDæÊÌ^XNðXV·éÌÍCÅDæÊÌ^XNª^XNL
+ *  
+[ÌöÉÚ®µ½êÅ éD
+ */
+#ifdef TOPPERS_tskrot
+
+bool_t
+rotate_ready_queue(uint_t pri)
+{
+	QUEUE	*p_queue = &(ready_queue[pri]);
+	QUEUE	*p_entry;
+
+	if (!queue_empty(p_queue) && p_queue->p_next->p_next != p_queue) {
+		p_entry = queue_delete_next(p_queue);
+		queue_insert_prev(p_queue, p_entry);
+		if (p_schedtsk == (TCB *) p_entry) {
+			p_schedtsk = (TCB *)(p_queue->p_next);
+			return(dspflg);
+		}
+	}
+	return(false);
+}
+
+#endif /* TOPPERS_tskrot */
+
+/*
+ *  ^XNáO[`ÌÄoµ
+ *
+ *  ASPJ[lÅÍC^XNáO[`àÅCPUbNóÔÉJÚµC
+ *  ³ÌóÔÉß³¸É^[µ½êCJ[lª³ÌóÔÉß·D
+ */
+#ifdef TOPPERS_tsktex
+
+void
+call_texrtn(void)
+{
+	TEXPTN	texptn;
+	bool_t	saved_disdsp;
+
+	saved_disdsp = disdsp;
+	p_runtsk->enatex = false;
+	do {
+		texptn = p_runtsk->texptn;
+		p_runtsk->texptn = 0U;
+
+		t_unlock_cpu();
+		LOG_TEX_ENTER(p_runtsk, texptn);
+		(*((TEXRTN)(p_runtsk->p_tinib->texrtn)))(texptn,
+												p_runtsk->p_tinib->exinf);
+		LOG_TEX_LEAVE(p_runtsk, texptn);
+		if (!t_sense_lock()) {
+			t_lock_cpu();
+		}
+		if (!ipmflg) {
+			t_set_ipm(TIPM_ENAALL);
+			ipmflg = true;
+		}
+		disdsp = saved_disdsp;
+		dspflg = !disdsp;
+		p_runtsk->enatex = false;
+		if (p_runtsk != p_schedtsk && dspflg) {
+			/*
+			 *  ±±ÅdispatchðÄÑo·ÍCÝÄAÄoµÉÈÁÄ
+			 *  ¢éªCdispatchðÄÔOÉp_runtsk->enatexðfalseÉµÄ
+			 *  ¨¯ÎxáªÈ¢D»ÌRÉÂ¢ÄÍCuTOPPERS/ASP J[
+			 *  l ÝvvðQÆÌ±ÆD
+			 */
+			dispatch();
+		}
+	} while (p_runtsk->texptn != 0U);
+	p_runtsk->enatex = true;
+}
+
+/*
+ *  ^XNáO[`ÌN®
+ */
+#ifndef OMIT_CALLTEX
+
+void
+calltex(void)
+{
+	if (p_runtsk->enatex && p_runtsk->texptn != 0U && ipmflg) {
+		call_texrtn();
+	}
+}
+
+#endif /* OMIT_CALLTEX */
+#endif /* TOPPERS_tsktex */
Index: UsbWattMeter/trunk/asp_dcre/kernel/task.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/task.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/task.h	(revision 164)
@@ -0,0 +1,528 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  $Id$
+ */
+
+/*
+ *		^XNÇW
+[
+ */
+
+#ifndef TOPPERS_TASK_H
+#define TOPPERS_TASK_H
+
+#include <queue.h>
+#include "time_event.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_TSKSTAT
+#define LOG_TSKSTAT(p_tcb)
+#endif /* LOG_TSKSTAT */
+
+/*
+ *  ^XNDæxÌà\»EO\»Ï·}N
+ */
+#define INT_PRIORITY(x)		((uint_t)((x) - TMIN_TPRI))
+#define EXT_TSKPRI(x)		((PRI)(x) + TMIN_TPRI)
+
+/*
+ *  ^XNóÔÌà\»
+ *
+ *  TCBÌ^XNóÔÅÍCÀsóÔiRUNNINGjÆÀsÂ\óÔiREADYj
+ *  ÍæÊµÈ¢D¼óÔðÌµÄCÀsÅ«éóÔiRUNNABLEjÆÄÔD
+ *  ñdÒ¿óÔÍC(TS_WAITING | TS_SUSPENDED)Å\·DTS_WAIT_???ÍÒ
+ *  ¿vöð\µCÒ¿óÔiñdÒ¿óÔðÜÞjÌêÉÌÝÝè·éD
+ */
+#define TS_DORMANT		0x00U			/* x~óÔ */
+#define TS_RUNNABLE		0x01U			/* ÀsÅ«éóÔ */
+#define TS_WAITING		0x02U			/* Ò¿óÔ */
+#define TS_SUSPENDED	0x04U			/* ­§Ò¿óÔ */
+
+#define TS_WAIT_DLY		(0x00U << 3)	/* ÔoßÒ¿ */
+#define TS_WAIT_SLP		(0x01U << 3)	/* N°Ò¿ */
+#define TS_WAIT_RDTQ	(0x02U << 3)	/* f[^L
+[©çÌóMÒ¿ */
+#define TS_WAIT_RPDQ	(0x03U << 3)	/* Dæxf[^L
+[©çÌóMÒ¿ */
+#define TS_WAIT_SEM		(0x04U << 3)	/* Z}tH¹Ìl¾Ò¿ */
+#define TS_WAIT_FLG		(0x05U << 3)	/* CxgtOÒ¿ */
+#define TS_WAIT_SDTQ	(0x06U << 3)	/* f[^L
+[ÖÌMÒ¿ */
+#define TS_WAIT_SPDQ	(0x07U << 3)	/* Dæxf[^L
+[ÖÌMÒ¿ */
+#define TS_WAIT_MBX		(0x08U << 3)	/* [{bNX©çÌóMÒ¿ */
+#define TS_WAIT_MPF		(0x09U << 3)	/* Åè·ubNÌl¾Ò¿ */
+
+/*
+ *  ^XNóÔ»Ê}N
+ *
+ *  TSTAT_DORMANTÍ^XNªx~óÔÅ é©Ç¤©ðCTSTAT_RUNNABLEÍ
+ *  ^XNªÀsÅ«éóÔÅ é©Ç¤©ð»Ê·éDTSTAT_WAITINGÍÒ
+ *  ¿óÔÆñdÒ¿óÔÌ¢¸ê©Å é©Ç¤©ðCTSTAT_SUSPENDEDÍ
+ *  ­§Ò¿óÔÆñdÒ¿óÔÌ¢¸ê©Å é©Ç¤©ð»Ê·éD
+ */
+#define TSTAT_DORMANT(tstat)	((tstat) == TS_DORMANT)
+#define TSTAT_RUNNABLE(tstat)	(((tstat) & TS_RUNNABLE) != 0U)
+#define TSTAT_WAITING(tstat)	(((tstat) & TS_WAITING) != 0U)
+#define TSTAT_SUSPENDED(tstat)	(((tstat) & TS_SUSPENDED) != 0U)
+
+/*
+ *  ^XNÒ¿vö»Ê}N
+ *
+ *  TSTAT_WAIT_SLPÍ^XNªN°Ò¿Å é©Ç¤©ðCTSTAT_WAIT_WOBJ
+ *  Í^XNª¯úEÊMIuWFNgÉÎ·éÒ¿Å é©i¾¢·¦éÆC
+ *  ¯úÊMIuWFNgÌÒ¿L
+[ÉÂÈªêÄ¢é©jÇ¤©ð»Ê·
+ *  éDÜ½CTSTAT_WAIT_WOBJCBÍ^XNª¯úEÊMIuWFNgÌÇ
+ *  ubNÌ¤ÊªiWOBJCBjÌÒ¿L
+[ÉÂÈªêÄ¢é©Ç¤©ð
+ *  »Ê·éD
+ *
+ *  TSTAT_WAIT_SLPÍCCÓÌ^XNóÔÌ©çC^XNªN°Ò¿Å é
+ *  ±Æð»ÊÅ«éD·Èí¿CTSTAT_WAITINGÉæèÒ¿óÔÅ é±Æð
+ *  »Ê¹¸ÉCTSTAT_SLP¾¯ðp¢ÄN°Ò¿óÔÅ é±Æð»ÊÅ«éD
+ *  ±êðø¦IÉÀ»·é½ßÉCTS_WAIT_SLPÌlðC(0x00U << 3)ÅÍÈ
+ *  ­(0x01U << 3)ÆµÄ¢éD»Ì½ßC^XNªÔoßÒ¿óÔÅ é
+ *  ±Æð»Ê·é½ßÌTSTAT_WAIT_DLYðCTSTAT_WAIT_SLPÆ¯lÌû@Å
+ *  À»·é±ÆÍÅ«È¢D
+ */
+#define TS_WAIT_MASK	(0x0fU << 3)	/* Ò¿vöÌæoµ}XN */
+
+#define TSTAT_WAIT_SLP(tstat)		(((tstat) & TS_WAIT_MASK) == TS_WAIT_SLP)
+#define TSTAT_WAIT_WOBJ(tstat)		(((tstat) & TS_WAIT_MASK) >= TS_WAIT_RDTQ)
+#define TSTAT_WAIT_WOBJCB(tstat)	(((tstat) & TS_WAIT_MASK) >= TS_WAIT_SEM)
+
+/*
+ *  Ò¿îñubNiWINFOjÌè`
+ *
+ *  ^XNªÒ¿óÔÌÔÍCTCB¨æÑ»Ìp_winfoÅw³êéWINFOðÌ
+ *  æ¤ÉÝèµÈ¯êÎÈçÈ¢D
+ *
+ *  (a) TCBÌ^XNóÔðÒ¿óÔiTS_WAITINGjÉ·éD»ÌÛÉCÒ¿
+ *  vöiTS_WAIT_???jàÝè·éD
+ *
+ *  (b) ^CAEgðÄ·é½ßÉC^CCxgubNðo^·éD
+ *  o^·é^CCxgubNÍCÒ¿ÉüéT[rXR[Ö
+ *  Ì[JÏÆµÄmÛµC»êÖÌ|C^ðWINFOÌp_tmevtbÉL
+ *  ¯·éD^CAEgÌÄªKvÈ¢êiivÒ¿ÌêjÉÍC
+ *  p_tmevtbðNULLÉ·éD
+ *
+ *  ¯úEÊMIuWFNgÉÎ·éÒ¿óÔÌêÉÍCWÌWINFOÉ
+ *  p_wobjcbtB[hðÇÁµ½\¢ÌiWINFO_WOBJCwait.hÅè`jðg
+ *  ¤DÜ½CÈºÌ(c)`(e)ÌÝèðs¤Kvª éD¯úEÊMIuWF
+ *  NgÉÖWµÈ¢Ò¿iN°Ò¿CÔoßÒ¿jÌêÉÍC(c)`(e)
+ *  ÍKvÈ¢D
+ *
+ *  (c) TCBðÒ¿ÎÛÌ¯úEÊMIuWFNgÌÒ¿L
+[ÉÂÈ®DÒ
+ *  ¿L
+[ÉÂÈ®½ßÉCtask_queueðg¤D
+ *
+ *  (d) Ò¿ÎÛÌ¯úEÊMIuWFNgÌÇubNÖÌ|C^ðC
+ *  WINFO_WOBJÌp_wobjcbÉL¯·éD
+ *
+ *  (e) Ò¿ÎÛÌ¯úEÊMIuWFNgÉË¶µÄL¯·é±ÆªKvÈ
+ *  îñª éêÉÍCWINFO_WOBJÉKvÈîñÌ½ßÌtB[hðÇÁ
+ *  µ½\¢Ìðè`µCWINFO_WOBJÌãíèÉp¢éD
+ *
+ *  Ò¿óÔðð·éÛÉÍCÒ¿ðµ½^XNÉÎ·éÔlðWINFOÌ
+ *  wercdÉÝè·éDwercdªKvÈÌÍÒ¿ðÈ~Å éÌÉÎµÄC
+ *  p_tmevtbÍÒ¿ðãÍKvÈ¢½ßCßñÌ½ßÉ¤pÌðgÁ
+ *  Ä¢éD»Ì½ßCwercdÖG[R[hðÝè·éÌÍC^CCxg
+ *  ubNðo^ðµ½ãÉµÈ¯êÎÈçÈ¢D
+ */
+typedef union waiting_information {
+	ER		wercd;			/* Ò¿ðÌG[R[h */
+	TMEVTB	*p_tmevtb;		/* Ò¿óÔpÌ^CCxgubN */
+} WINFO;
+
+/*
+ *  ^XNú»ubN
+ *
+ *  ^XNÉÖ·éîñðClªÏíçÈ¢½ßÉROMÉu¯éªi^XN
+ *  ú»ubNjÆClªÏ»·é½ßÉRAMÉu©È¯êÎÈçÈ¢
+ *  ªi^XNÇubNCTCBjÉª£µCTCBàÉÎ·é^XNú»
+ *  ubNðw·|C^ðüêéD^XNú»ubNàÉÎ·é
+ *  TCBðw·|C^ðüêéû@ÌûªCRAMÌßñÌÏ_©çÍ]Üµ¢
+ *  ªCÀsø¦ª«­Èé½ßÉÌpµÄ¢È¢D¼ÌIuWFNgÉÂ¢
+ *  Äà¯lÉµ¤D
+ *
+ *  ^XNú»ubNÉÍCDEF_TEXÅè`³êé^XNáO[`
+ *  ÉÖ·éîñàÜÞD
+ */
+typedef struct task_initialization_block {
+	ATR			tskatr;			/* ^XN®« */
+	intptr_t	exinf;			/* ^XNÌg£îñ */
+	TASK		task;			/* ^XNÌN®Ôn */
+	uint_t		ipriority;		/* ^XNÌN®Dæxià\»j */
+
+#ifdef USE_TSKINICTXB
+	TSKINICTXB	tskinictxb;		/* ^XNú»ReLXgubN */
+#else /* USE_TSKINICTXB */
+	SIZE		stksz;			/* X^bNÌæÌTCYiÛß½lj */
+	void		*stk;			/* X^bNÌæÌæªÔn */
+#endif /* USE_TSKINICTXB */
+
+	ATR			texatr;			/* ^XNáO[`®« */
+	TEXRTN		texrtn;			/* ^XNáO[`ÌN®Ôn */
+} TINIB;
+
+/*
+ *  TCBÌtB[hÌrbgÌè`
+ *
+ *  vZbTÉæÁÄÍCTCBÌtB[hÌrbgÅgpÊÆ
+ *  «\ªg[hItÉÈé½ßC^[QbgË¶ÉtB[hÌrbg
+ *  ðÏX·é±ÆðµÄ¢éD
+ */
+#ifndef TBIT_TCB_PRIORITY
+#define	TBIT_TCB_PRIORITY		8		/* prioritytB[hÌrbg */
+#endif /* TBIT_TCB_PRIORITY */
+
+/*
+ *  ^XNÇubNiTCBj
+ *
+ *  ASPJ[lÅÍC^XNÌN®vL
+[COÌÅåliTMAX_ACTCNTj
+ *  ÆN°vL
+[COÌÅåliTMAX_WUPCNTjÍ1ÉÅè³êÄ¢é
+ *  ½ßCL
+[CO³êÄ¢é©Ç¤©Ì^UlÅ\»·é±ÆªÅ«éD
+ *  Ü½C­§Ò¿vlXgÌÅåliTMAX_SUSCNTjª1ÉÅè³êÄ¢
+ *  éÌÅC­§Ò¿vlXgisuscntjÍKvÈ¢D
+ *
+ *  TCBÌ¢­Â©ÌtB[hÍCÁèÌ^XNóÔÅÌÝLøÈlðÛµC
+ *  »êÈOÌêÍlªÛØ³êÈ¢iæÁÄCQÆµÄÍÈçÈ¢jDe
+ *  tB[hªLøÈlðÛ·éðÍÌÊèD
+ *
+ *  Eú»ãÍíÉLøF
+ *  		p_tinibCtstatCactque
+ *  Ex~óÔÈOÅLøix~óÔÅÍúlÉÈÁÄ¢éjF
+ *  		priorityCwupqueCenatexCtexptn
+ *  EÒ¿óÔiñdÒ¿óÔðÜÞjÅLøF
+ *  		p_winfo
+ *  EÀsÅ«éóÔÆ¯úEÊMIuWFNgÉÎ·éÒ¿óÔÅLøF
+ *  		task_queue
+ *  EÀsÂ\óÔCÒ¿óÔC­§Ò¿óÔCñdÒ¿óÔÅLøF
+ *  		tskctxb
+ */
+typedef struct task_control_block {
+	QUEUE			task_queue;		/* ^XNL
+[ */
+	const TINIB		*p_tinib;		/* ú»ubNÖÌ|C^ */
+
+#ifdef UINT8_MAX
+	uint8_t			tstat;			/* ^XNóÔià\»j*/
+#else /* UINT8_MAX */
+	BIT_FIELD_UINT	tstat : 8;		/* ^XNóÔià\»j*/
+#endif /* UINT8_MAX */
+#if defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8)
+	uint8_t			priority;		/* »ÝÌDæxià\»j*/
+#else /* defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8) */
+	BIT_FIELD_UINT	priority : TBIT_TCB_PRIORITY;
+									/* »ÝÌDæxià\»j*/
+#endif /* defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8) */
+	BIT_FIELD_BOOL	actque : 1;		/* N®vL
+[CO */
+	BIT_FIELD_BOOL	wupque : 1;		/* N°vL
+[CO */
+	BIT_FIELD_BOOL	enatex : 1;		/* ^XNáOÂóÔ */
+
+	TEXPTN			texptn;			/* Û¯áOvö */
+	WINFO			*p_winfo;		/* Ò¿îñubNÖÌ|C^ */
+	TSKCTXB			tskctxb;		/* ^XNReLXgubN */
+} TCB;
+
+/*
+ *  ÀsóÔÌ^XN
+ *
+ *  ÀsóÔÌ^XNivZbTªReLXgðÁÄ¢é^XNjÌ
+ *  TCBðw·|C^DÀsóÔÌ^XNªÈ¢êÍNULLÉ·éD
+ *
+ *  T[rXR[ÌÅC©^XNiT[rXR[ðÄÑoµ½^X
+ *  NjÉÖ·éîñðQÆ·éêÍp_runtskðg¤Dp_runtskð«·¦
+ *  éÌÍCfBXpb`iÆú»jÌÝÅ éD
+ */
+extern TCB	*p_runtsk;
+
+/*
+ *  ÅDæÊÌ^XN
+ *
+ *  ÀsÅ«é^XNÌÅÅDæÊÌ^XNÌTCBðw·|C^DÀ
+ *  sÅ«é^XNªÈ¢êÍNULLÉ·éD
+ *
+ *  fBXpb`Ö~óÔÈÇCfBXpb`ªÛ¯³êÄ¢éÔÍp_runtsk
+ *  ÆêvµÄ¢éÆÍÀçÈ¢D
+ */
+extern TCB	*p_schedtsk;
+
+/*
+ *  fBXpb`^^XNáO[`N®vtO
+ *
+ *  Ýnh^CPUáOnhÌoûÉCfBXpb`Ü½Í
+ *  ^XNáO[`ÌN®ðv·é±Æð¦·tOD
+ */
+extern bool_t	reqflg;
+
+/*
+ *  ÝDæx}XNSðóÔ
+ *
+ *  ÝDæx}XNSðóÔÅ é±Æð¦·tOD
+ */
+extern bool_t	ipmflg;
+
+/*
+ *  fBXpb`Ö~óÔ
+ *
+ *  fBXpb`Ö~óÔÅ é±Æð¦·tOD
+ */
+extern bool_t	disdsp;
+
+/*
+ *  ^XNfBXpb`Â\óÔ
+ *
+ *  ÝDæx}XNSðóÔÅ èCfBXpb`ÂóÔÅ éifB
+ *  Xpb`Ö~óÔÅÈ¢j±Æð¦·tOD
+ */
+extern bool_t	dspflg;
+
+/*
+ *  fBL
+[
+ *
+ *  fBL
+[ÍCÀsÅ«éóÔÌ^XNðÇ·é½ßÌL
+[Å éD
+ *  ÀsóÔÌ^XNàÇµÄ¢é½ßCfBiÀsÂ\jL
+[Æ¢¤
+ *  ¼ÌÍ³mÅÍÈ¢ªCfBL
+[Æ¢¤¼Ìªè
+µÄ¢é½ßC±
+ *  Ì¼ÌÅÄÔ±ÆÉ·éD
+ *
+ *  fBL
+[ÍCDæx²ÆÌ^XNL
+[Å\¬³êÄ¢éD^XNÌ
+ *  TCBÍCY·éDæxÌL
+[Éo^³êéD
+ */
+extern QUEUE	ready_queue[TNUM_TPRI];
+
+/*
+ *  fBL
+[T[`Ì½ßÌrbg}bv
+ *
+ *  fBL
+[ÌT[`ðø¦æ­s¤½ßÉCDæx²ÆÌ^XNL
+[
+ *  É^XNªüÁÄ¢é©Ç¤©ð¦·rbg}bvðpÓµÄ¢éDrb
+ *  g}bvðg¤±ÆÅCANZXÌñð¸ç·±ÆªÅ«éªC
+ *  rbgì½ßª[ÀµÄ¢È¢vZbTÅCDæxÌiKª­È¢
+ *  êÉÍCrbg}bvìÌI[o[wbhÌ½ßÉCtÉø¦ª¿
+ *  éÂ\«à éD
+ *
+ *  Dæxª16iKÅ é±Æð¼èµÄ¢é½ßCuint16_t^ÆµÄ¢éD
+ */
+extern uint16_t	ready_primap;
+
+/*
+ *  gpµÄ¢È¢TCBÌXg
+ */
+extern QUEUE	free_tcb;
+
+/*
+ *  ^XNIDÌÅålikernel_cfg.cj
+ */
+extern const ID	tmax_tskid;
+extern const ID	tmax_stskid;
+
+/*
+ *  ^XNú»ubNÌGAikernel_cfg.cj
+ */
+extern const TINIB	tinib_table[];
+extern TINIB		atinib_table[];
+
+/*
+ *  ^XN¶¬e[uikernel_cfg.cj
+ */
+extern const ID	torder_table[];
+
+/*
+ *  TCBÌGAikernel_cfg.cj
+ */
+extern TCB	tcb_table[];
+
+/*
+ *  ^XNÌ
+ */
+#define tnum_tsk	((uint_t)(tmax_tskid - TMIN_TSKID + 1))
+#define tnum_stsk	((uint_t)(tmax_stskid - TMIN_TSKID + 1))
+
+/*
+ *  ^XNID©çTCBðæèo·½ßÌ}N
+ */
+#define INDEX_TSK(tskid)	((uint_t)((tskid) - TMIN_TSKID))
+#define get_tcb(tskid)		(&(tcb_table[INDEX_TSK(tskid)]))
+#define get_tcb_self(tskid)	((tskid) == TSK_SELF ? p_runtsk : get_tcb(tskid))
+
+/*
+ *  TCB©ç^XNIDðæèo·½ßÌ}N
+ */
+#define	TSKID(p_tcb)	((ID)(((p_tcb) - tcb_table) + TMIN_TSKID))
+
+/*
+ *  ^XNÇW
+[Ìú»
+ */
+extern void	initialize_task(void);
+
+/*
+ *  ÅDæÊ^XNÌT[`
+ *
+ *  fBL
+[ÌÅDæÊÌ^XNðT[`µC»ÌTCBÖÌ|C^
+ *  ðÔ·DfBL
+[ªóÌêÉÍC±ÌÖðÄÑoµÄÍÈçÈ¢D
+ */
+extern TCB	*search_schedtsk(void);
+
+/*
+ *  ÀsÅ«éóÔÖÌJÚ
+ *
+ *  p_tcbÅwè³êé^XNðfBL
+[É}ü·éDfBL
+[É}ü
+ *  µ½^XNÌDæxªCÅDæÊÌ^XNÌDæxæèà¢êÍC
+ *  ÅDæÊÌ^XNðXVµCfBXpb`ÂóÔÅ êÎtrueðÔ
+ *  ·D»¤ÅÈ¢êÍfalseðÔ·D
+ */
+extern bool_t	make_runnable(TCB *p_tcb);
+
+/*
+ *  ÀsÅ«éóÔ©ç¼ÌóÔÖÌJÚ
+ *
+ *  p_tcbÅwè³êé^XNðfBL
+[©çí·éDp_tcbÅwèµ½
+ *  ^XNªÅDæÊÌ^XNÅ Á½êÉÍCÅDæÊÌ^XN
+ *  ðÝèµÈ¨µCfBXpb`ÂóÔÅ êÎtrueðÔ·D»¤ÅÈ¢
+ *  êÍfalseðÔ·D^XNÌóÔÍXVµÈ¢D
+ */
+extern bool_t	make_non_runnable(TCB *p_tcb);
+
+/*
+ *  x~óÔÖÌJÚ
+ *
+ *  p_tcbÅwè³êé^XNÌóÔðx~óÔÆ·éDÜ½C^XNÌN®
+ *  Éú»·×«ÏÌú»ÆC^XNN®Ì½ßÌReLXgðÝ
+ *  è·éD
+ */
+extern void	make_dormant(TCB *p_tcb);
+
+/*
+ *  x~óÔ©çÀsÅ«éóÔÖÌJÚ
+ *
+ *  p_tcbÅwè³êé^XNÌóÔðx~óÔ©çÀsÅ«éóÔÆ·éD
+ *  ÀsÅ«éóÔÉJÚµ½^XNÖÌfBXpb`ªKvÈêÍtrueC
+ *  »¤ÅÈ¢êÍfalseðÔ·D
+ */
+extern bool_t	make_active(TCB *p_tcb);
+
+/*
+ *  ^XNÌDæxÌÏX
+ *
+ *  p_tcbÅwè³êé^XNÌDæxðnewpriià\»jÉÏX·éDÜ½C
+ *  KvÈêÉÍÅDæÊÌ^XNðXVµCfBXpb`ÂóÔÅ
+ *   êÎtrueðÔ·D»¤ÅÈ¢êÍfalseðÔ·D
+ */
+extern bool_t	change_priority(TCB *p_tcb, uint_t newpri);
+
+/*
+ *  fBL
+[Ìñ]
+ *
+ *  fBL
+[ÌCpriÅwè³êéDæxÌ^XNL
+[ðñ]³¹éD
+ *  Ü½CKvÈêÉÍÅDæÊÌ^XNðÏXµCfBXpb`ªÛ
+ *  ¯³êÄ¢È¯êÎtrueðÔ·D»¤ÅÈ¢êÍfalseðÔ·D
+ */
+extern bool_t	rotate_ready_queue(uint_t pri);
+
+/*
+ *  ^XNáO[`ÌÄoµ
+ *
+ *  ^XNáO[`ðÄÑo·DÄÑo·OÉCÀsóÔÌ^XNÌ
+ *  Û¯áOvöðNAµC^XNáOÖ~óÔÉµCCPUbNðð
+ *  ·éD
+ *
+ *  ^XNáO[`©çßéÆCÜ¸CPUbNóÔÉßµC»ÌÔ
+ *  ÉÛ¯áOvöª0ÅÈ­ÈÁÄ¢êÎCÄÑ^XNáO[`ð
+ *  ÄÑo·DÛ¯áOvöª0ÌêÉÍCáOÂóÔÉµÄÖ©
+ *  ç^[·éD
+ *
+ *  ±ÌÖÍCÀsóÔÌ^XNªC^XNáOÂóÔienatexª
+ *  truejÅCÛ¯áOvöª0ÅÈ¢itexptnª0ÅÈ¢jêÉÄÑo·±
+ *  ÆðzèµÄ¢éD±ÌÖÍCCPUbNóÔÅÄÑo³È¯êÎÈç
+ *  È¢D
+ */
+extern void	call_texrtn(void);
+
+/*
+ *  ^XNáO[`ÌN®
+ *
+ *  ÀsóÔÌ^XNª^XNáO[`ÌN®ðð½µÄ¢êÎC
+ *  ^XNáO[`ðÄÑo·DCPUáO[`ðÄÑo·
+ *  ÍCêIÉCPUbNðð·éD
+ *
+ *  ±ÌÖÍCfBXpb`âÝnh^CPUáOnhÌoû
+ *  ©çÄÑo³êé±ÆðzèµÄ¢éD±ÌÖÍCCPUbNóÔ
+ *  ÅÄÑo³È¯êÎÈçÈ¢D
+ *
+ *  Àsø¦ðã°é½ßÉC±ÌÖð^[QbgË¶ÅLqµÄàæ¢D
+ *  »ÌêÉÍCOMIT_CALLTEXð}Nè`·éD
+ */
+extern void	calltex(void);
+
+#endif /* TOPPERS_TASK_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/task_except.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/task_except.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/task_except.c	(revision 164)
@@ -0,0 +1,372 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  $Id$
+ */
+
+/*
+ *		^XNáO@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_DEF_TEX_ENTER
+#define LOG_DEF_TEX_ENTER(tskid, pk_dtex)
+#endif /* LOG_DEF_TEX_ENTER */
+
+#ifndef LOG_DEF_TEX_LEAVE
+#define LOG_DEF_TEX_LEAVE(ercd)
+#endif /* LOG_DEF_TEX_LEAVE */
+
+#ifndef LOG_RAS_TEX_ENTER
+#define LOG_RAS_TEX_ENTER(tskid, rasptn)
+#endif /* LOG_RAS_TEX_ENTER */
+
+#ifndef LOG_RAS_TEX_LEAVE
+#define LOG_RAS_TEX_LEAVE(ercd)
+#endif /* LOG_RAS_TEX_LEAVE */
+
+#ifndef LOG_IRAS_TEX_ENTER
+#define LOG_IRAS_TEX_ENTER(tskid, rasptn)
+#endif /* LOG_IRAS_TEX_ENTER */
+
+#ifndef LOG_IRAS_TEX_LEAVE
+#define LOG_IRAS_TEX_LEAVE(ercd)
+#endif /* LOG_IRAS_TEX_LEAVE */
+
+#ifndef LOG_DIS_TEX_ENTER
+#define LOG_DIS_TEX_ENTER()
+#endif /* LOG_DIS_TEX_ENTER */
+
+#ifndef LOG_DIS_TEX_LEAVE
+#define LOG_DIS_TEX_LEAVE(ercd)
+#endif /* LOG_DIS_TEX_LEAVE */
+
+#ifndef LOG_ENA_TEX_ENTER
+#define LOG_ENA_TEX_ENTER()
+#endif /* LOG_ENA_TEX_ENTER */
+
+#ifndef LOG_ENA_TEX_LEAVE
+#define LOG_ENA_TEX_LEAVE(ercd)
+#endif /* LOG_ENA_TEX_LEAVE */
+
+#ifndef LOG_SNS_TEX_ENTER
+#define LOG_SNS_TEX_ENTER()
+#endif /* LOG_SNS_TEX_ENTER */
+
+#ifndef LOG_SNS_TEX_LEAVE
+#define LOG_SNS_TEX_LEAVE(state)
+#endif /* LOG_SNS_TEX_LEAVE */
+
+#ifndef LOG_REF_TEX_ENTER
+#define LOG_REF_TEX_ENTER(tskid, pk_rtex)
+#endif /* LOG_REF_TEX_ENTER */
+
+#ifndef LOG_REF_TEX_LEAVE
+#define LOG_REF_TEX_LEAVE(ercd, pk_rtex)
+#endif /* LOG_REF_TEX_LEAVE */
+
+/*
+ *  ^XNáO[`Ìè`
+ */
+#ifdef TOPPERS_def_tex
+
+ER_UINT
+def_tex(ID tskid, const T_DTEX *pk_dtex)
+{
+	TCB		*p_tcb;
+	TINIB	*p_tinib;
+	ER		ercd;
+
+	LOG_DEF_TEX_ENTER(tskid, pk_dtex);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	CHECK_RSATR(pk_dtex->texatr, TA_NULL);
+	if (pk_dtex->texrtn != NULL) {
+		CHECK_ALIGN_FUNC(pk_dtex->texrtn);
+		CHECK_NONNULL_FUNC(pk_dtex->texrtn);
+	}
+	p_tcb = get_tcb_self(tskid);
+	p_tinib = (TINIB *)(p_tcb->p_tinib);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSKID(p_tcb) > tmax_stskid) {
+		if (pk_dtex->texrtn != NULL) {
+			if (p_tinib->texrtn != NULL) {
+				ercd = E_OBJ;
+			}
+			else {
+				p_tinib->texatr = pk_dtex->texatr;
+				p_tinib->texrtn = pk_dtex->texrtn;
+				ercd = E_OK;
+			}
+		}
+		else {
+			if (p_tinib->texrtn != NULL) {
+				p_tinib->texrtn = NULL;
+				p_tcb->enatex = false;
+				p_tcb->texptn = 0U;
+				ercd = E_OK;
+			}
+			else {
+				ercd = E_OBJ;
+			}
+		}
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEF_TEX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_def_tex */
+
+/*
+ *  ^XNáOÌv
+ */
+#ifdef TOPPERS_ras_tex
+
+ER
+ras_tex(ID tskid, TEXPTN rasptn)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_RAS_TEX_ENTER(tskid, rasptn);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	CHECK_PAR(rasptn != 0U);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat) || p_tcb->p_tinib->texrtn == NULL) {
+		ercd = E_OBJ;
+	}
+	else {
+		p_tcb->texptn |= rasptn;
+		if (p_tcb == p_runtsk && p_runtsk->enatex && ipmflg) {
+			call_texrtn();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_RAS_TEX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ras_tex */
+
+/*
+ *  ^XNáOÌviñ^XNReLXgpj
+ */
+#ifdef TOPPERS_iras_tex
+
+ER
+iras_tex(ID tskid, TEXPTN rasptn)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_IRAS_TEX_ENTER(tskid, rasptn);
+	CHECK_INTCTX_UNL();
+	CHECK_TSKID(tskid);
+	CHECK_PAR(rasptn != 0U);
+	p_tcb = get_tcb(tskid);
+
+	i_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat) || p_tcb->p_tinib->texrtn == NULL) {
+		ercd = E_OBJ;
+	}
+	else {
+		p_tcb->texptn |= rasptn;
+		if (p_tcb == p_runtsk && p_runtsk->enatex && ipmflg) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IRAS_TEX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_iras_tex */
+
+/*
+ *  ^XNáOÌÖ~
+ */
+#ifdef TOPPERS_dis_tex
+
+ER
+dis_tex(void)
+{
+	ER		ercd;
+
+	LOG_DIS_TEX_ENTER();
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	if (p_runtsk->p_tinib->texrtn == NULL) {
+		ercd = E_OBJ;
+	}
+	else {
+		p_runtsk->enatex = false;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DIS_TEX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_dis_tex */
+
+/*
+ *  ^XNáOÌÂ
+ */
+#ifdef TOPPERS_ena_tex
+
+ER
+ena_tex(void)
+{
+	ER		ercd;
+
+	LOG_ENA_TEX_ENTER();
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	if (p_runtsk->p_tinib->texrtn == NULL) {
+		ercd = E_OBJ;
+	}
+	else {
+		p_runtsk->enatex = true;
+		if (p_runtsk->texptn != 0U && ipmflg) {
+			call_texrtn();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ENA_TEX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ena_tex */
+
+/*
+ *  ^XNáOÖ~óÔÌQÆ
+ */
+#ifdef TOPPERS_sns_tex
+
+bool_t
+sns_tex(void)
+{
+	bool_t	state;
+
+	LOG_SNS_TEX_ENTER();
+	state = (p_runtsk != NULL && p_runtsk->enatex) ? false : true;
+	LOG_SNS_TEX_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_sns_tex */
+
+/*
+ *  ^XNáOÌóÔQÆ
+ */
+#ifdef TOPPERS_ref_tex
+
+ER
+ref_tex(ID tskid, T_RTEX *pk_rtex)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_REF_TEX_ENTER(tskid, pk_rtex);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat) || p_tcb->p_tinib->texrtn == NULL) {
+		ercd = E_OBJ;
+	}
+	else {
+		pk_rtex->texstat = (p_tcb->enatex) ? TTEX_ENA : TTEX_DIS;
+		pk_rtex->pndptn = p_tcb->texptn;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_TEX_LEAVE(ercd, pk_rtex);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_tex */
Index: UsbWattMeter/trunk/asp_dcre/kernel/task_manage.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/task_manage.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/task_manage.c	(revision 164)
@@ -0,0 +1,592 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		^XNÇ@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_ACRE_TSK_ENTER
+#define LOG_ACRE_TSK_ENTER(pk_ctsk)
+#endif /* LOG_ACRE_TSK_ENTER */
+
+#ifndef LOG_ACRE_TSK_LEAVE
+#define LOG_ACRE_TSK_LEAVE(ercd)
+#endif /* LOG_ACRE_TSK_LEAVE */
+
+#ifndef LOG_DEL_TSK_ENTER
+#define LOG_DEL_TSK_ENTER(tskid)
+#endif /* LOG_DEL_TSK_ENTER */
+
+#ifndef LOG_DEL_TSK_LEAVE
+#define LOG_DEL_TSK_LEAVE(ercd)
+#endif /* LOG_DEL_TSK_LEAVE */
+
+#ifndef LOG_ACT_TSK_ENTER
+#define LOG_ACT_TSK_ENTER(tskid)
+#endif /* LOG_ACT_TSK_ENTER */
+
+#ifndef LOG_ACT_TSK_LEAVE
+#define LOG_ACT_TSK_LEAVE(ercd)
+#endif /* LOG_ACT_TSK_LEAVE */
+
+#ifndef LOG_IACT_TSK_ENTER
+#define LOG_IACT_TSK_ENTER(tskid)
+#endif /* LOG_IACT_TSK_ENTER */
+
+#ifndef LOG_IACT_TSK_LEAVE
+#define LOG_IACT_TSK_LEAVE(ercd)
+#endif /* LOG_IACT_TSK_LEAVE */
+
+#ifndef LOG_CAN_ACT_ENTER
+#define LOG_CAN_ACT_ENTER(tskid)
+#endif /* LOG_CAN_ACT_ENTER */
+
+#ifndef LOG_CAN_ACT_LEAVE
+#define LOG_CAN_ACT_LEAVE(ercd)
+#endif /* LOG_CAN_ACT_LEAVE */
+
+#ifndef LOG_EXT_TSK_ENTER
+#define LOG_EXT_TSK_ENTER()
+#endif /* LOG_EXT_TSK_ENTER */
+
+#ifndef LOG_EXT_TSK_LEAVE
+#define LOG_EXT_TSK_LEAVE(ercd)
+#endif /* LOG_EXT_TSK_LEAVE */
+
+#ifndef LOG_TER_TSK_ENTER
+#define LOG_TER_TSK_ENTER(tskid)
+#endif /* LOG_TER_TSK_ENTER */
+
+#ifndef LOG_TER_TSK_LEAVE
+#define LOG_TER_TSK_LEAVE(ercd)
+#endif /* LOG_TER_TSK_LEAVE */
+
+#ifndef LOG_CHG_PRI_ENTER
+#define LOG_CHG_PRI_ENTER(tskid, tskpri)
+#endif /* LOG_CHG_PRI_ENTER */
+
+#ifndef LOG_CHG_PRI_LEAVE
+#define LOG_CHG_PRI_LEAVE(ercd)
+#endif /* LOG_CHG_PRI_LEAVE */
+
+#ifndef LOG_GET_PRI_ENTER
+#define LOG_GET_PRI_ENTER(tskid, p_tskpri)
+#endif /* LOG_GET_PRI_ENTER */
+
+#ifndef LOG_GET_PRI_LEAVE
+#define LOG_GET_PRI_LEAVE(ercd, tskpri)
+#endif /* LOG_GET_PRI_LEAVE */
+
+#ifndef LOG_GET_INF_ENTER
+#define LOG_GET_INF_ENTER(p_exinf)
+#endif /* LOG_GET_INF_ENTER */
+
+#ifndef LOG_GET_INF_LEAVE
+#define LOG_GET_INF_LEAVE(ercd, exinf)
+#endif /* LOG_GET_INF_LEAVE */
+
+/*
+ *  ^XNÌ¶¬
+ */
+#ifdef TOPPERS_acre_tsk
+
+#ifndef TARGET_MIN_STKSZ
+#define TARGET_MIN_STKSZ	1U		/* ¢è`ÌêÍ0ÅÈ¢±Æð`FbN */
+#endif /* TARGET_MIN_STKSZ */
+
+ER_UINT
+acre_tsk(const T_CTSK *pk_ctsk)
+{
+	TCB		*p_tcb;
+	TINIB	*p_tinib;
+	ATR		tskatr;
+	void	*stk;
+	ER		ercd;
+
+	LOG_ACRE_TSK_ENTER(pk_ctsk);
+	CHECK_TSKCTX_UNL();
+	CHECK_RSATR(pk_ctsk->tskatr, TA_ACT|TARGET_TSKATR);
+	CHECK_ALIGN_FUNC(pk_ctsk->task);
+	CHECK_NONNULL_FUNC(pk_ctsk->task);
+	CHECK_TPRI(pk_ctsk->itskpri);
+	CHECK_PAR(pk_ctsk->stksz >= TARGET_MIN_STKSZ);
+	if (pk_ctsk->stk != NULL) {
+		CHECK_ALIGN_STKSZ(pk_ctsk->stksz);
+		CHECK_ALIGN_STACK(pk_ctsk->stk);
+	}
+	tskatr = pk_ctsk->tskatr;
+	stk = pk_ctsk->stk;
+
+	t_lock_cpu();
+	if (queue_empty(&free_tcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		if (stk == NULL) {
+			stk = kernel_malloc(ROUND_STK_T(pk_ctsk->stksz));
+			tskatr |= TA_MEMALLOC;
+		}
+		if (stk == NULL) {
+			ercd = E_NOMEM;
+		}
+		else {
+			p_tcb = ((TCB *) queue_delete_next(&free_tcb));
+			p_tinib = (TINIB *)(p_tcb->p_tinib);
+			p_tinib->tskatr = tskatr;
+			p_tinib->exinf = pk_ctsk->exinf;
+			p_tinib->task = pk_ctsk->task;
+			p_tinib->ipriority = INT_PRIORITY(pk_ctsk->itskpri);
+#ifdef USE_TSKINICTXB
+			init_tskinictxb(&(p_tinib->tskinictxb), stk, pk_ctsk);
+#else /* USE_TSKINICTXB */
+			p_tinib->stksz = pk_ctsk->stksz;
+			p_tinib->stk = stk;
+#endif /* USE_TSKINICTXB */
+			p_tinib->texatr = TA_NULL;
+			p_tinib->texrtn = NULL;
+
+			p_tcb->actque = false;
+			make_dormant(p_tcb);
+			if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
+				make_active(p_tcb);
+			}
+			ercd = TSKID(p_tcb);
+		}
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_tsk */
+
+/*
+ *  ^XNÌí
+ */
+#ifdef TOPPERS_del_tsk
+
+ER
+del_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	TINIB	*p_tinib;
+	ER		ercd;
+
+	LOG_DEL_TSK_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID(tskid);
+	p_tcb = get_tcb(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSKID(p_tcb) > tmax_stskid && TSTAT_DORMANT(p_tcb->tstat)) {
+		p_tinib = (TINIB *)(p_tcb->p_tinib);
+#ifdef USE_TSKINICTXB
+		term_tskinictxb(&(p_tinib->tskinictxb));
+#else /* USE_TSKINICTXB */
+		if ((p_tinib->tskatr & TA_MEMALLOC) != 0U) {
+			kernel_free(p_tinib->stk);
+		}
+#endif /* USE_TSKINICTXB */
+		p_tinib->tskatr = TA_NOEXS;
+		queue_insert_prev(&free_tcb, &(p_tcb->task_queue));
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DEL_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_tsk */
+
+/*
+ *  ^XNÌN®
+ */
+#ifdef TOPPERS_act_tsk
+
+ER
+act_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_ACT_TSK_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		if (make_active(p_tcb)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (!(p_tcb->actque)) {
+		p_tcb->actque = true;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_QOVR;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_ACT_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_act_tsk */
+
+/*
+ *  ^XNÌN®iñ^XNReLXgpj
+ */
+#ifdef TOPPERS_iact_tsk
+
+ER
+iact_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_IACT_TSK_ENTER(tskid);
+	CHECK_INTCTX_UNL();
+	CHECK_TSKID(tskid);
+	p_tcb = get_tcb(tskid);
+
+	i_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		if (make_active(p_tcb)) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	else if (!(p_tcb->actque)) {
+		p_tcb->actque = true;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_QOVR;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IACT_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_iact_tsk */
+
+/*
+ *  ^XNN®vÌLZ
+ */
+#ifdef TOPPERS_can_act
+
+ER_UINT
+can_act(ID tskid)
+{
+	TCB		*p_tcb;
+	ER_UINT	ercd;
+
+	LOG_CAN_ACT_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		ercd = p_tcb->actque ? 1 : 0;
+		p_tcb->actque = false;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_CAN_ACT_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_can_act */
+
+/*
+ *  ©^XNÌI¹
+ */
+#ifdef TOPPERS_ext_tsk
+
+ER
+ext_tsk(void)
+{
+	ER		ercd;
+
+	LOG_EXT_TSK_ENTER();
+	CHECK_TSKCTX();
+
+	if (t_sense_lock()) {
+		/*
+		 *  CPUbNóÔÅext_tskªÄÎê½êÍCCPUbNððµ
+		 *  Ä©ç^XNðI¹·éDÀãÍCT[rXR[àÅÌCPU
+		 *  bNðÈª·êÎæ¢¾¯D
+		 */
+	}
+	else {
+		t_lock_cpu();
+	}
+	if (disdsp) {
+		/*
+		 *  fBXpb`Ö~óÔÅext_tskªÄÎê½êÍCfBXpb
+		 *  `ÂóÔÉµÄ©ç^XNðI¹·éD
+		 */
+		disdsp = false;
+	}
+	if (!ipmflg) {
+		/*
+		 *  ÝDæx}XNiIPMjªTIPM_ENAALLÈOÌóÔÅext_tsk
+		 *  ªÄÎê½êÍCIPMðTIPM_ENAALLÉµÄ©ç^XNðI¹·
+		 *  éD
+		 */
+		t_set_ipm(TIPM_ENAALL);
+		ipmflg = true;
+	}
+	dspflg = true;
+
+	(void) make_non_runnable(p_runtsk);
+	make_dormant(p_runtsk);
+	if (p_runtsk->actque) {
+		p_runtsk->actque = false;
+		(void) make_active(p_runtsk);
+	}
+	exit_and_dispatch();
+	ercd = E_SYS;
+
+  error_exit:
+	LOG_EXT_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ext_tsk */
+
+/*
+ *  ^XNÌ­§I¹
+ */
+#ifdef TOPPERS_ter_tsk
+
+ER
+ter_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_TER_TSK_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID(tskid);
+	p_tcb = get_tcb(tskid);
+	CHECK_NONSELF(p_tcb);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else {
+		if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+			/*
+			 *  p_tcbÍ©^XNÅÈ¢½ßCiVOvZbTÅÍjÀ
+			 *  sóÔÅÈ­Cmake_non_runnable(p_tcb)Å^XNfBXpb
+			 *  `ªKvÉÈé±ÆÍÈ¢D
+			 */
+			(void) make_non_runnable(p_tcb);
+		}
+		else if (TSTAT_WAITING(p_tcb->tstat)) {
+			wait_dequeue_wobj(p_tcb);
+			wait_dequeue_tmevtb(p_tcb);
+		}
+		make_dormant(p_tcb);
+		if (p_tcb->actque) {
+			p_tcb->actque = false;
+			if (make_active(p_tcb)) {
+				dispatch();
+			}
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TER_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ter_tsk */
+
+/*
+ *  ^XNÌx[XDæxÌÏX
+ */
+#ifdef TOPPERS_chg_pri
+
+ER
+chg_pri(ID tskid, PRI tskpri)
+{
+	TCB		*p_tcb;
+	uint_t	newpri;
+	ER		ercd;
+
+	LOG_CHG_PRI_ENTER(tskid, tskpri);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	CHECK_TPRI_INI(tskpri);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else {
+		newpri = (tskpri == TPRI_INI) ? p_tcb->p_tinib->ipriority
+											: INT_PRIORITY(tskpri);
+		if (change_priority(p_tcb, newpri)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_CHG_PRI_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_chg_pri */
+
+/*
+ *  ^XNDæxÌQÆ
+ */
+#ifdef TOPPERS_get_pri
+
+ER
+get_pri(ID tskid, PRI *p_tskpri)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_GET_PRI_ENTER(tskid, p_tskpri);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else {
+		*p_tskpri = EXT_TSKPRI(p_tcb->priority);
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_GET_PRI_LEAVE(ercd, *p_tskpri);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_pri */
+
+/*
+ *  ©^XNÌg£îñÌQÆ
+ */
+#ifdef TOPPERS_get_inf
+
+ER
+get_inf(intptr_t *p_exinf)
+{
+	ER		ercd;
+
+	LOG_GET_INF_ENTER(p_exinf);
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	*p_exinf = p_runtsk->p_tinib->exinf;
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_GET_INF_LEAVE(ercd, *p_exinf);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_inf */
Index: UsbWattMeter/trunk/asp_dcre/kernel/task_refer.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/task_refer.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/task_refer.c	(revision 164)
@@ -0,0 +1,215 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2005-2014 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		^XNÌóÔQÆ@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "semaphore.h"
+#include "eventflag.h"
+#include "dataqueue.h"
+#include "pridataq.h"
+#include "mailbox.h"
+#include "mempfix.h"
+#include "time_event.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#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 */
+
+/*
+ *  ^XNÌóÔQÆ
+ */
+#ifdef TOPPERS_ref_tsk
+
+ER
+ref_tsk(ID tskid, T_RTSK *pk_rtsk)
+{
+	TCB		*p_tcb;
+	uint_t	tstat;
+	ER		ercd;
+
+	LOG_REF_TSK_ENTER(tskid, pk_rtsk);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		tstat = p_tcb->tstat;
+		if (TSTAT_DORMANT(tstat)) {
+			/*
+	 		 *  ÎÛ^XNªx~óÔÌê
+			 */
+			pk_rtsk->tskstat = TTS_DMT;
+		}
+		else {
+			/*
+	 		 *  ^XNóÔÌæoµ
+			 */
+			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;
+			}
+
+			/*
+	 		 *  »ÝDæxÆx[XDæxÌæoµ
+			 */
+			pk_rtsk->tskpri = EXT_TSKPRI(p_tcb->priority);
+			pk_rtsk->tskbpri = EXT_TSKPRI(p_tcb->priority);
+
+			if (TSTAT_WAITING(tstat)) {
+				/*
+		 		 *  Ò¿vöÆÒ¿ÎÛÌIuWFNgÌIDÌæoµ
+				 */
+				switch (tstat & TS_WAIT_MASK) {
+				case TS_WAIT_SLP:
+					pk_rtsk->tskwait = TTW_SLP;
+					break;
+				case TS_WAIT_DLY:
+					pk_rtsk->tskwait = TTW_DLY;
+					break;
+				case TS_WAIT_SEM:
+					pk_rtsk->tskwait = TTW_SEM;
+					pk_rtsk->wobjid = SEMID(((WINFO_SEM *)(p_tcb->p_winfo))
+																->p_semcb);
+					break;
+				case TS_WAIT_FLG:
+					pk_rtsk->tskwait = TTW_FLG;
+					pk_rtsk->wobjid = FLGID(((WINFO_FLG *)(p_tcb->p_winfo))
+																->p_flgcb);
+					break;
+				case TS_WAIT_SDTQ:
+					pk_rtsk->tskwait = TTW_SDTQ;
+					pk_rtsk->wobjid = DTQID(((WINFO_DTQ *)(p_tcb->p_winfo))
+																->p_dtqcb);
+					break;
+				case TS_WAIT_RDTQ:
+					pk_rtsk->tskwait = TTW_RDTQ;
+					pk_rtsk->wobjid = DTQID(((WINFO_DTQ *)(p_tcb->p_winfo))
+																->p_dtqcb);
+					break;
+				case TS_WAIT_SPDQ:
+					pk_rtsk->tskwait = TTW_SPDQ;
+					pk_rtsk->wobjid = PDQID(((WINFO_PDQ *)(p_tcb->p_winfo))
+																->p_pdqcb);
+					break;
+				case TS_WAIT_RPDQ:
+					pk_rtsk->tskwait = TTW_RPDQ;
+					pk_rtsk->wobjid = PDQID(((WINFO_PDQ *)(p_tcb->p_winfo))
+																->p_pdqcb);
+					break;
+				case TS_WAIT_MBX:
+					pk_rtsk->tskwait = TTW_MBX;
+					pk_rtsk->wobjid = MBXID(((WINFO_MBX *)(p_tcb->p_winfo))
+																->p_mbxcb);
+					break;
+				case TS_WAIT_MPF:
+					pk_rtsk->tskwait = TTW_MPF;
+					pk_rtsk->wobjid = MPFID(((WINFO_MPF *)(p_tcb->p_winfo))
+																->p_mpfcb);
+					break;
+				}
+
+				/*
+		 		 *  ^CAEg·éÜÅÌÔÌæoµ
+				 */
+				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;
+				}
+			}
+
+			/*
+	 		 *  N°vL
+[COÌæoµ
+			 */
+			pk_rtsk->wupcnt = p_tcb->wupque ? 1U : 0U;
+		}
+
+		/*
+		 *  N®vL
+[COÌæoµ
+		 */
+		pk_rtsk->actcnt = p_tcb->actque ? 1U : 0U;
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REF_TSK_LEAVE(ercd, pk_rtsk);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_tsk */
Index: UsbWattMeter/trunk/asp_dcre/kernel/task_sync.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/task_sync.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/task_sync.c	(revision 164)
@@ -0,0 +1,556 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		^XNt®¯ú@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_SLP_TSK_ENTER
+#define LOG_SLP_TSK_ENTER()
+#endif /* LOG_SLP_TSK_ENTER */
+
+#ifndef LOG_SLP_TSK_LEAVE
+#define LOG_SLP_TSK_LEAVE(ercd)
+#endif /* LOG_SLP_TSK_LEAVE */
+
+#ifndef LOG_TSLP_TSK_ENTER
+#define LOG_TSLP_TSK_ENTER(tmout)
+#endif /* LOG_TSLP_TSK_ENTER */
+
+#ifndef LOG_TSLP_TSK_LEAVE
+#define LOG_TSLP_TSK_LEAVE(ercd)
+#endif /* LOG_TSLP_TSK_LEAVE */
+
+#ifndef LOG_WUP_TSK_ENTER
+#define LOG_WUP_TSK_ENTER(tskid)
+#endif /* LOG_WUP_TSK_ENTER */
+
+#ifndef LOG_WUP_TSK_LEAVE
+#define LOG_WUP_TSK_LEAVE(ercd)
+#endif /* LOG_WUP_TSK_LEAVE */
+
+#ifndef LOG_IWUP_TSK_ENTER
+#define LOG_IWUP_TSK_ENTER(tskid)
+#endif /* LOG_IWUP_TSK_ENTER */
+
+#ifndef LOG_IWUP_TSK_LEAVE
+#define LOG_IWUP_TSK_LEAVE(ercd)
+#endif /* LOG_IWUP_TSK_LEAVE */
+
+#ifndef LOG_CAN_WUP_ENTER
+#define LOG_CAN_WUP_ENTER(tskid)
+#endif /* LOG_CAN_WUP_ENTER */
+
+#ifndef LOG_CAN_WUP_LEAVE
+#define LOG_CAN_WUP_LEAVE(ercd)
+#endif /* LOG_CAN_WUP_LEAVE */
+
+#ifndef LOG_REL_WAI_ENTER
+#define LOG_REL_WAI_ENTER(tskid)
+#endif /* LOG_REL_WAI_ENTER */
+
+#ifndef LOG_REL_WAI_LEAVE
+#define LOG_REL_WAI_LEAVE(ercd)
+#endif /* LOG_REL_WAI_LEAVE */
+
+#ifndef LOG_IREL_WAI_ENTER
+#define LOG_IREL_WAI_ENTER(tskid)
+#endif /* LOG_IREL_WAI_ENTER */
+
+#ifndef LOG_IREL_WAI_LEAVE
+#define LOG_IREL_WAI_LEAVE(ercd)
+#endif /* LOG_IREL_WAI_LEAVE */
+
+#ifndef LOG_SUS_TSK_ENTER
+#define LOG_SUS_TSK_ENTER(tskid)
+#endif /* LOG_SUS_TSK_ENTER */
+
+#ifndef LOG_SUS_TSK_LEAVE
+#define LOG_SUS_TSK_LEAVE(ercd)
+#endif /* LOG_SUS_TSK_LEAVE */
+
+#ifndef LOG_RSM_TSK_ENTER
+#define LOG_RSM_TSK_ENTER(tskid)
+#endif /* LOG_RSM_TSK_ENTER */
+
+#ifndef LOG_RSM_TSK_LEAVE
+#define LOG_RSM_TSK_LEAVE(ercd)
+#endif /* LOG_RSM_TSK_LEAVE */
+
+#ifndef LOG_DLY_TSK_ENTER
+#define LOG_DLY_TSK_ENTER(dlytim)
+#endif /* LOG_DLY_TSK_ENTER */
+
+#ifndef LOG_DLY_TSK_LEAVE
+#define LOG_DLY_TSK_LEAVE(ercd)
+#endif /* LOG_DLY_TSK_LEAVE */
+
+/*
+ *  N°Ò¿
+ */
+#ifdef TOPPERS_slp_tsk
+
+ER
+slp_tsk(void)
+{
+	WINFO	winfo;
+	ER		ercd;
+
+	LOG_SLP_TSK_ENTER();
+	CHECK_DISPATCH();
+
+	t_lock_cpu();
+	if (p_runtsk->wupque) {
+		p_runtsk->wupque = false;
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP);
+		make_wait(&winfo);
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_SLP_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_slp_tsk */
+
+/*
+ *  N°Ò¿i^CAEg èj
+ */
+#ifdef TOPPERS_tslp_tsk
+
+ER
+tslp_tsk(TMO tmout)
+{
+	WINFO	winfo;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_TSLP_TSK_ENTER(tmout);
+	CHECK_DISPATCH();
+	CHECK_TMOUT(tmout);
+
+	t_lock_cpu();
+	if (p_runtsk->wupque) {
+		p_runtsk->wupque = false;
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP);
+		make_wait_tmout(&winfo, &tmevtb, tmout);
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo.wercd;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_TSLP_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_tslp_tsk */
+
+/*
+ *  ^XNÌN°
+ */
+#ifdef TOPPERS_wup_tsk
+
+ER
+wup_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_WUP_TSK_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
+		if (wait_complete(p_tcb)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (!(p_tcb->wupque)) {
+		p_tcb->wupque = true;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_QOVR;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_WUP_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_wup_tsk */
+
+/*
+ *  ^XNÌN°iñ^XNReLXgpj
+ */
+#ifdef TOPPERS_iwup_tsk
+
+ER
+iwup_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_IWUP_TSK_ENTER(tskid);
+	CHECK_INTCTX_UNL();
+	CHECK_TSKID(tskid);
+	p_tcb = get_tcb(tskid);
+
+	i_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
+		if (wait_complete(p_tcb)) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	else if (!(p_tcb->wupque)) {
+		p_tcb->wupque = true;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_QOVR;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IWUP_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_iwup_tsk */
+
+/*
+ *  ^XNN°vÌLZ
+ */
+#ifdef TOPPERS_can_wup
+
+ER_UINT
+can_wup(ID tskid)
+{
+	TCB		*p_tcb;
+	ER_UINT	ercd;
+
+	LOG_CAN_WUP_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else {
+		ercd = p_tcb->wupque ? 1 : 0;
+		p_tcb->wupque = false;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_CAN_WUP_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_can_wup */
+
+/*
+ *  Ò¿óÔÌ­§ð
+ */
+#ifdef TOPPERS_rel_wai
+
+ER
+rel_wai(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_REL_WAI_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID(tskid);
+	p_tcb = get_tcb(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!TSTAT_WAITING(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else {
+		if (wait_release(p_tcb)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_REL_WAI_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rel_wai */
+
+/*
+ *  Ò¿óÔÌ­§ðiñ^XNReLXgpj
+ */
+#ifdef TOPPERS_irel_wai
+
+ER
+irel_wai(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_IREL_WAI_ENTER(tskid);
+	CHECK_INTCTX_UNL();
+	CHECK_TSKID(tskid);
+	p_tcb = get_tcb(tskid);
+
+	i_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!TSTAT_WAITING(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else {
+		if (wait_release(p_tcb)) {
+			reqflg = true;
+		}
+		ercd = E_OK;
+	}
+	i_unlock_cpu();
+
+  error_exit:
+	LOG_IREL_WAI_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_irel_wai */
+
+/*
+ *  ­§Ò¿óÔÖÌÚs
+ */
+#ifdef TOPPERS_sus_tsk
+
+ER
+sus_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_SUS_TSK_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID_SELF(tskid);
+	p_tcb = get_tcb_self(tskid);
+
+	t_lock_cpu();
+	if (p_tcb == p_runtsk && !dspflg) {
+		ercd = E_CTX;
+	}
+	else if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+		/*
+		 *  ÀsÅ«éóÔ©ç­§Ò¿óÔÖÌJÚ
+		 */
+		p_tcb->tstat = TS_SUSPENDED;
+		LOG_TSKSTAT(p_tcb);
+		if (make_non_runnable(p_tcb)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (TSTAT_SUSPENDED(p_tcb->tstat)) {
+		ercd = E_QOVR;
+	}
+	else {
+		/*
+		 *  Ò¿óÔ©çñdÒ¿óÔÖÌJÚ
+		 */
+		p_tcb->tstat |= TS_SUSPENDED;
+		LOG_TSKSTAT(p_tcb);
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_SUS_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_sus_tsk */
+
+/*
+ *  ­§Ò¿óÔ©çÌÄJ
+ */
+#ifdef TOPPERS_rsm_tsk
+
+ER
+rsm_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_RSM_TSK_ENTER(tskid);
+	CHECK_TSKCTX_UNL();
+	CHECK_TSKID(tskid);
+	p_tcb = get_tcb(tskid);
+
+	t_lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!TSTAT_SUSPENDED(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else if (!TSTAT_WAITING(p_tcb->tstat)) {
+		/*
+		 *  ­§Ò¿óÔ©çÀsÅ«éóÔÖÌJÚ
+		 */
+		p_tcb->tstat = TS_RUNNABLE;
+		LOG_TSKSTAT(p_tcb);
+		if (make_runnable(p_tcb)) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		/*
+		 *  ñdÒ¿óÔ©çÒ¿óÔÖÌJÚ
+		 */
+		p_tcb->tstat &= ~TS_SUSPENDED;
+		LOG_TSKSTAT(p_tcb);
+		ercd = E_OK;
+	}
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_RSM_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rsm_tsk */
+
+/*
+ *  ©^XNÌx
+ */
+#ifdef TOPPERS_dly_tsk
+
+ER
+dly_tsk(RELTIM dlytim)
+{
+	WINFO	winfo;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_DLY_TSK_ENTER(dlytim);
+	CHECK_DISPATCH();
+	CHECK_PAR(dlytim <= TMAX_RELTIM);
+
+	t_lock_cpu();
+	p_runtsk->tstat = (TS_WAITING | TS_WAIT_DLY);
+	(void) make_non_runnable(p_runtsk);
+	p_runtsk->p_winfo = &winfo;
+	winfo.p_tmevtb = &tmevtb;
+	tmevtb_enqueue(&tmevtb, dlytim, (CBACK) wait_tmout_ok, (void *) p_runtsk);
+	LOG_TSKSTAT(p_runtsk);
+	dispatch();
+	ercd = winfo.wercd;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_DLY_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_dly_tsk */
Index: UsbWattMeter/trunk/asp_dcre/kernel/time_event.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/time_event.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/time_event.c	(revision 164)
@@ -0,0 +1,405 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  $Id$
+ */
+
+/*
+ *		^CCxgÇW
+[
+ */
+
+#include "kernel_impl.h"
+#include "time_event.h"
+
+/*
+ *  ^CCxgq[vì}N
+ */
+#define	PARENT(index)		((index) >> 1)		/* em[hðßé */
+#define	LCHILD(index)		((index) << 1)		/* ¶Ìqm[hðßé */
+#define	TMEVT_NODE(index)	(tmevt_heap[(index) - 1])
+
+/*
+ *  Cxg­¶är}N
+ *
+ *  Cxg­¶ÍCmin_time©çÌÎlÅär·éD·Èí¿C
+ *  min_timeðÅ¬liÅàß¢jCmit_time-1ªÅåliÅà¢j
+ *  ÆÝÈµÄär·éD
+ */
+#define	EVTTIM_LT(t1, t2) (((t1) - min_time) < ((t2) - min_time))
+#define	EVTTIM_LE(t1, t2) (((t1) - min_time) <= ((t2) - min_time))
+
+#ifdef TOPPERS_tmeini
+
+/*
+ *  »ÝÌVXeiPÊ: 1~bj
+ *
+ *  µ§ÉÍCOÌ^CeBbNÌVXeD
+ */
+EVTTIM	current_time;
+
+/*
+ *  ^CCxgq[vÅLøÈÅ¬ÌVXeiPÊ: 1~bj
+ */
+EVTTIM	min_time;
+
+/*
+ *  Ì^CeBbNÌVXeiPÊ: 1~bj
+ */
+EVTTIM	next_time;
+
+/*
+ *  VXeÏZpÏiPÊ: 1/TIC_DENO~bj
+ */
+#if TIC_DENO != 1U
+uint_t	next_subtime;
+#endif /* TIC_DENO != 1U */
+
+/*
+ *  ^CCxgq[vÌÅãÌgpÌæÌCfbNX
+ */
+uint_t	last_index;
+
+/*
+ *  ^C}W
+[Ìú»
+ */
+void
+initialize_tmevt(void)
+{
+	current_time = 0U;
+	min_time = 0U;
+	next_time = current_time + TIC_NUME / TIC_DENO;
+#if TIC_DENO != 1U
+	next_subtime = TIC_NUME % TIC_DENO;
+#endif /* TIC_DENO != 1U */
+	last_index = 0U;
+}
+
+#endif /* TOPPERS_tmeini */
+
+/*
+ *  ^CCxgÌ}üÊuðãü«ÉTõ
+ *
+ *  timeÉ­¶·é^CCxgð}ü·ém[hðó¯é½ßÉC
+ *  q[vÌãÉü©ÁÄóm[hðÚ®³¹éDÚ®OÌóm[hÌÊuð
+ *  indexÉn·ÆCÚ®ãÌóm[hÌÊui·Èí¿}üÊujðÔ·D
+ */
+#ifdef TOPPERS_tmeup
+
+uint_t
+tmevt_up(uint_t index, EVTTIM time)
+{
+	uint_t	parent;
+
+	while (index > 1) {
+		/*
+		 *  em[hÌCxg­¶Ìûª¢iÜ½Í¯¶jÈçÎC
+		 *  indexª}üÊuÈÌÅ[vð²¯éD
+		 */
+		parent = PARENT(index);
+		if (EVTTIM_LE(TMEVT_NODE(parent).time, time)) {
+			break;
+		}
+
+		/*
+		 *  em[hðindexÌÊuÉÚ®³¹éD
+		 */
+		TMEVT_NODE(index) = TMEVT_NODE(parent);
+		TMEVT_NODE(index).p_tmevtb->index = index;
+
+		/*
+		 *  indexðem[hÌÊuÉXVD
+		 */
+		index = parent;
+	}
+	return(index);
+}
+
+#endif /* TOPPERS_tmeup */
+
+/*
+ *  ^CCxgÌ}üÊuðºü«ÉTõ
+ *
+ *  timeÉ­¶·é^CCxgð}ü·ém[hðó¯é½ßÉC
+ *  q[vÌºÉü©ÁÄóm[hðÚ®³¹éDÚ®OÌóm[hÌÊuð 
+ *  indexÉn·ÆCÚ®ãÌóm[hÌÊui·Èí¿}üÊujðÔ·D
+ */
+#ifdef TOPPERS_tmedown
+
+uint_t
+tmevt_down(uint_t index, EVTTIM time)
+{
+	uint_t	child;
+
+	while ((child = LCHILD(index)) <= last_index) {
+		/*
+		 *  ¶EÌqm[hÌCxg­¶ðärµC¢ûÌqm[h
+		 *  ÌÊuðchildÉÝè·éDÈºÌqm[hÍC±±ÅIÎê½û
+		 *  Ìqm[hÌ±ÆD
+		 */
+		if (child + 1 <= last_index
+						&& EVTTIM_LT(TMEVT_NODE(child + 1).time,
+										TMEVT_NODE(child).time)) {
+			child = child + 1;
+		}
+
+		/*
+		 *  qm[hÌCxg­¶Ìûªx¢iÜ½Í¯¶jÈçÎC
+		 *  indexª}üÊuÈÌÅ[vð²¯éD
+		 */
+		if (EVTTIM_LE(time, TMEVT_NODE(child).time)) {
+			break;
+		}
+
+		/*
+		 *  qm[hðindexÌÊuÉÚ®³¹éD
+		 */
+		TMEVT_NODE(index) = TMEVT_NODE(child);
+		TMEVT_NODE(index).p_tmevtb->index = index;
+
+		/*
+		 *  indexðqm[hÌÊuÉXVD
+		 */
+		index = child;
+	}
+	return(index);
+}
+
+#endif /* TOPPERS_tmedown */
+
+/*
+ *  ^CCxgq[vÖÌo^
+ *
+ *  p_tmevtbÅwèµ½^CCxgubNðCtimeÅwèµ½Ôªo
+ *  ßãÉCxgª­¶·éæ¤ÉC^CCxgq[vÉo^·éD
+ */
+#ifdef TOPPERS_tmeins
+
+void
+tmevtb_insert(TMEVTB *p_tmevtb, EVTTIM time)
+{
+	uint_t	index;
+
+	/*
+	 *  last_indexðCNgµC»±©çãÉ}üÊuðT·D
+	 */
+	index = tmevt_up(++last_index, time);
+
+	/*
+	 *  ^CCxgðindexÌÊuÉ}ü·éD
+	 */ 
+	TMEVT_NODE(index).time = time;
+	TMEVT_NODE(index).p_tmevtb = p_tmevtb;
+	p_tmevtb->index = index;
+}
+
+#endif /* TOPPERS_tmeins */
+
+/*
+ *  ^CCxgq[v©çÌí
+ */
+#ifdef TOPPERS_tmedel
+
+void
+tmevtb_delete(TMEVTB *p_tmevtb)
+{
+	uint_t	index = p_tmevtb->index;
+	uint_t	parent;
+	EVTTIM	event_time = TMEVT_NODE(last_index).time;
+
+	/*
+	 *  íÉæè^CCxgq[vªóÉÈéêÍ½àµÈ¢D
+	 */
+	if (--last_index == 0) {
+		return;
+	}
+
+	/*
+	 *  íµ½m[hÌÊuÉÅãÌm[hilast_index+1ÌÊuÌm[hj
+	 *  ð}üµC»êðKØÈÊuÖÚ®³¹éDÀÛÉÍCÅãÌm[h
+	 *  ðÀÛÉ}ü·éÌÅÍÈ­Cíµ½m[hÌÊuªóm[hÉÈ
+	 *  éÌÅCÅãÌm[hð}ü·×«ÊuÖü¯Äóm[hðÚ®³¹
+	 *  éD
+	 *  ÅãÌm[hÌCxg­¶ªCíµ½m[hÌem[hÌC
+	 *  xg­¶æèOÌêÉÍCãÉü©ÁÄ}üÊuðT·D»
+	 *  ¤ÅÈ¢êÉÍCºÉü©ÁÄT·D
+	 */
+	if (index > 1 && EVTTIM_LT(event_time,
+								TMEVT_NODE(parent = PARENT(index)).time)) {
+		/*
+		 *  em[hðindexÌÊuÉÚ®³¹éD
+		 */
+		TMEVT_NODE(index) = TMEVT_NODE(parent);
+		TMEVT_NODE(index).p_tmevtb->index = index;
+
+		/*
+		 *  íµ½m[hÌem[h©çãÉü©ÁÄ}üÊuðT·D
+		 */
+		index = tmevt_up(parent, event_time);
+	}
+	else {
+		/*
+		 *  íµ½m[h©çºÉü©ÁÄ}üÊuðT·D
+		 */
+		index = tmevt_down(index, event_time);
+	}
+
+	/*
+	 *  ÅãÌm[hðindexÌÊuÉ}ü·éD
+	 */ 
+	TMEVT_NODE(index) = TMEVT_NODE(last_index + 1);
+	TMEVT_NODE(index).p_tmevtb->index = index;
+}
+
+#endif /* TOPPERS_tmedel */
+
+/*
+ *  ^CCxgq[vÌæªÌm[hÌí
+ */
+Inline void
+tmevtb_delete_top(void)
+{
+	uint_t	index;
+	EVTTIM	event_time = TMEVT_NODE(last_index).time;
+
+	/*
+	 *  íÉæè^CCxgq[vªóÉÈéêÍ½àµÈ¢D
+	 */
+	if (--last_index == 0) {
+		return;
+	}
+
+	/*
+	 *  [gm[hÉÅãÌm[hilast_index + 1 ÌÊuÌm[hjð
+	 *  }üµC»êðKØÈÊuÖÚ®³¹éDÀÛÉÍCÅãÌm[hð
+	 *  ÀÛÉ}ü·éÌÅÍÈ­C[gm[hªóm[hÉÈéÌÅCÅ
+	 *  ãÌm[hð}ü·×«ÊuÖü¯Äóm[hðÚ®³¹éD
+	 */
+	index = tmevt_down(1, event_time);
+
+	/*
+	 *  ÅãÌm[hðindexÌÊuÉ}ü·éD
+	 */ 
+	TMEVT_NODE(index) = TMEVT_NODE(last_index + 1);
+	TMEVT_NODE(index).p_tmevtb->index = index;
+}
+
+/*
+ *  ^CCxgÜÅÌcèÔÌvZ
+ */
+#ifdef TOPPERS_tmeltim
+
+RELTIM
+tmevt_lefttim(TMEVTB *p_tmevtb)
+{
+	EVTTIM	time;
+
+	time = TMEVT_NODE(p_tmevtb->index).time;
+	if (EVTTIM_LE(time, next_time)) {
+		/*
+		 *  Ì^CeBbNÅ³êéêÉÍ0ðÔ·D
+		 */
+		return(0U);
+	}
+	else {
+		return((RELTIM)(time - base_time));
+	}
+}
+
+#endif /* TOPPERS_tmeltim */
+
+/*
+ *  ^CeBbNÌ
+ */
+#ifdef TOPPERS_sigtim
+
+void
+signal_time(void)
+{
+	TMEVTB	*p_tmevtb;
+
+	assert(sense_context());
+	assert(!i_sense_lock());
+
+	i_lock_cpu();
+
+	/*
+	 *  current_timeðXV·éD
+	 */
+	current_time = next_time;
+
+	/*
+	 *  next_timeCnext_subtimeðXV·éD
+	 */
+#if TIC_DENO == 1U
+	next_time = current_time + TIC_NUME;
+#else /* TIC_DENO == 1U */
+	next_subtime += TIC_NUME % TIC_DENO;
+	next_time = current_time + TIC_NUME / TIC_DENO;
+	if (next_subtime >= TIC_DENO) {
+		next_subtime -= TIC_DENO;
+		next_time += 1U;
+	}
+#endif /* TIC_DENO == 1U */
+
+	/*
+	 *  current_timeæèCxg­¶Ì¢iÜ½Í¯¶j^CCx
+	 *  gðC^CCxgq[v©çíµCR[obNÖðÄÑ
+	 *  o·D
+	 */
+	while (last_index > 0 && EVTTIM_LE(TMEVT_NODE(1).time, current_time)) {
+		p_tmevtb = TMEVT_NODE(1).p_tmevtb;
+		tmevtb_delete_top();
+		(*(p_tmevtb->callback))(p_tmevtb->arg);
+	}
+
+	/*
+	 *  min_timeðXV·éD
+	 */
+	min_time = current_time;
+
+	i_unlock_cpu();
+}
+
+#endif /* TOPPERS_sigtim */
Index: UsbWattMeter/trunk/asp_dcre/kernel/time_event.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/time_event.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/time_event.h	(revision 164)
@@ -0,0 +1,209 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  $Id$
+ */
+
+/*
+ *		^CCxgÇW
+[
+ */
+
+#ifndef TOPPERS_TIME_EVENT_H
+#define TOPPERS_TIME_EVENT_H
+
+/*
+ *  Cxg­¶Ìf[^^Ìè`
+ *
+ *  EVTTIMÍCRELTIMÆµÄwèÅ«éÍÍæèàL¢ÍÍð\»Å«éKv
+ *  ª éDÊITRON4.0dlÌX^_[hvt@CÅÍCRELTIMª16rb
+ *  gÈãÅÈ¯êÎÈçÈ¢½ßCEVTTIMÍ17rbgÈãÅ é±ÆªKv
+ *  Å éD»Ì½ßC16rbgÉÈéêª éuint_tÅÍÈ­Culong_tÉ
+ *  è`µÄ¢éD
+ */
+typedef ulong_t	EVTTIM;
+
+/* 
+ *  ^CCxgubNÌf[^^Ìè`
+ */
+typedef void	(*CBACK)(void *);	/* R[obNÖÌ^ */
+
+typedef struct time_event_block {
+	uint_t	index;			/* ^CCxgq[vÅÌÊu */
+	CBACK	callback;		/* R[obNÖ */
+	void	*arg;			/* R[obNÖÖn·ø */
+} TMEVTB;
+
+/*
+ *  ^CCxgq[vÌm[hÌf[^^Ìè`
+ */
+typedef struct time_event_node {
+	EVTTIM	time;			/* Cxg­¶ */
+	TMEVTB	*p_tmevtb;		/* Î·é^CCxgubN */
+} TMEVTN;
+
+/*
+ *  ^CCxgq[vikernel_cfg.cj
+ */
+extern TMEVTN	tmevt_heap[];
+
+/*
+ *  »ÝÌVXeiPÊ: 1~bj
+ *
+ *  VXeN®É0Éú»³êCÈ~C^CeBbNª³êéxÉ
+ *  P²ÉÁ·éD
+ */
+extern EVTTIM	current_time;
+
+/*
+ *  ^CCxgq[vÅLøÈÅ¬ÌVXeiPÊ: 1~bj
+ */
+extern EVTTIM	min_time;
+
+/*
+ *  Ì^CeBbNÌVXeiPÊ: 1~bj
+ */
+extern EVTTIM	next_time;
+
+/*
+ *  VXeÏZpÏiPÊ: 1/TIC_DENO~bj
+ *
+ *  Ì^CeBbNÌVXeÌºÊ
+ð¦·iãÊ
+Ínext_timejD
+ *  TIC_DENOª1ÌÍCºÊ
+ÍíÉ0Å é½ßC±ÌÏÍKvÈ¢D
+ */
+#if TIC_DENO != 1U
+extern uint_t	next_subtime;
+#endif /* TIC_DENO != 1U */
+
+/*
+ *  ÎÔÌîiPÊ: 1~bj
+ *
+ *  Ì^CeBbNÌVXeðØèã°½DTIC_DENOª1Ì
+ *  ÍCnext_timeÉêv·éD
+ */
+#if TIC_DENO == 1U
+#define	base_time	(next_time)
+#else /* TIC_DENO == 1U */
+#define	base_time	(next_time + (next_subtime > 0U ? 1U : 0U))
+#endif /* TIC_DENO == 1U */
+
+/*
+ *  ^CCxgq[vÌÅãÌgpÌæÌCfbNX
+ *
+ *  ^CCxgq[vÉo^³êÄ¢é^CCxgÌÉêv·éD
+ */
+extern uint_t	last_index;
+
+/*
+ *  ^CCxgÇW
+[Ìú»
+ */
+extern void	initialize_tmevt(void);
+
+/*
+ *  ^CCxgÌ}üÊuÌTõ
+ */
+extern uint_t	tmevt_up(uint_t index, EVTTIM time);
+extern uint_t	tmevt_down(uint_t index, EVTTIM time);
+
+/*
+ *  ^CCxgq[vÖÌo^Æí
+ */
+extern void	tmevtb_insert(TMEVTB *p_tmevtb, EVTTIM time);
+extern void	tmevtb_delete(TMEVTB *p_tmevtb);
+
+/*
+ *  ^CCxgubNÌo^iÎÔwèj
+ *
+ *  timeÅwèµ½ÎÔªoßµ½ãÉCargðøÆµÄcallbackªÄ
+ *  Ño³êéæ¤ÉCp_tmevtbÅwèµ½^CCxgubNðo^·
+ *  éD
+ *  
+ */
+Inline void
+tmevtb_enqueue(TMEVTB *p_tmevtb, RELTIM time, CBACK callback, void *arg)
+{
+	assert(time <= TMAX_RELTIM);
+
+	p_tmevtb->callback = callback;
+	p_tmevtb->arg = arg;
+	tmevtb_insert(p_tmevtb, base_time + time);
+}
+
+/*
+ *  ^CCxgubNÌo^iCxg­¶wèj
+ *
+ *  timeÅwèµ½Cxg­¶ÉCargðøÆµÄcallbackªÄÑo
+ *  ³êéæ¤ÉCp_tmevtbÅwèµ½^CCxgubNðo^·éD
+ */
+Inline void
+tmevtb_enqueue_evttim(TMEVTB *p_tmevtb, EVTTIM time, CBACK callback, void *arg)
+{
+	p_tmevtb->callback = callback;
+	p_tmevtb->arg = arg;
+	tmevtb_insert(p_tmevtb, time);
+}
+
+/*
+ *  ^CCxgubNÌo^ð
+ */
+Inline void
+tmevtb_dequeue(TMEVTB *p_tmevtb)
+{
+	tmevtb_delete(p_tmevtb);
+}
+
+/*
+ *  ^CCxgÜÅÌcèÔÌvZ
+ */
+extern RELTIM	tmevt_lefttim(TMEVTB *p_tmevtb);
+
+/*
+ *  ^CeBbNÌ
+ */
+extern void	signal_time(void);
+
+#endif /* TOPPERS_TIME_EVENT_H */
Index: UsbWattMeter/trunk/asp_dcre/kernel/time_manage.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/time_manage.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/time_manage.c	(revision 164)
@@ -0,0 +1,148 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  $Id$
+ */
+
+/*
+ *		VXeÇ@\
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "time_event.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_GET_TIM_ENTER
+#define LOG_GET_TIM_ENTER(p_systim)
+#endif /* LOG_GET_TIM_ENTER */
+
+#ifndef LOG_GET_TIM_LEAVE
+#define LOG_GET_TIM_LEAVE(ercd, systim)
+#endif /* LOG_GET_TIM_LEAVE */
+
+#ifndef LOG_GET_UTM_ENTER
+#define LOG_GET_UTM_ENTER(p_sysutm)
+#endif /* LOG_GET_UTM_ENTER */
+
+#ifndef LOG_GET_UTM_LEAVE
+#define LOG_GET_UTM_LEAVE(ercd, sysutm)
+#endif /* LOG_GET_UTM_LEAVE */
+
+/*
+ *  VXeÌQÆ
+ */
+#ifdef TOPPERS_get_tim
+
+ER
+get_tim(SYSTIM *p_systim)
+{
+	ER		ercd;
+
+	LOG_GET_TIM_ENTER(p_systim);
+	CHECK_TSKCTX_UNL();
+
+	t_lock_cpu();
+	*p_systim = current_time;
+	ercd = E_OK;
+	t_unlock_cpu();
+
+  error_exit:
+	LOG_GET_TIM_LEAVE(ercd, *p_systim);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_tim */
+
+/*
+ *  «\]¿pVXeÌQÆ
+ */
+#ifdef TOPPERS_get_utm
+#ifdef TOPPERS_SUPPORT_GET_UTM
+#ifndef OMIT_GET_UTM
+#include "target_timer.h"
+
+ER
+get_utm(SYSUTM *p_sysutm)
+{
+	SYSUTM	utime;
+	SYSTIM	time;
+#if TIC_DENO != 1
+	uint_t	subtime;
+#endif /* TIC_DENO != 1 */
+	CLOCK	clock1, clock2;
+	bool_t	ireq;
+	SIL_PRE_LOC;
+
+	LOG_GET_UTM_ENTER(p_sysutm);
+
+	SIL_LOC_INT();
+	time = next_time;
+#if TIC_DENO != 1
+	subtime = next_subtime;
+#endif /* TIC_DENO != 1 */
+	clock1 = target_timer_get_current();
+	ireq = target_timer_probe_int();
+	clock2 = target_timer_get_current();
+	SIL_UNL_INT();
+
+	utime = ((SYSUTM) time) * 1000U;
+#if TIC_DENO != 1
+	utime += subtime * 1000U / TIC_DENO;
+#endif /* TIC_DENO != 1 */
+
+	if (!ireq || clock1 > clock2) {
+		utime -= TIC_NUME * 1000U / TIC_DENO;
+	}
+	utime += TO_USEC(clock1);
+	*p_sysutm = utime;
+
+	LOG_GET_UTM_LEAVE(E_OK, *p_sysutm);
+	return(E_OK);
+}
+
+#endif /* OMIT_GET_UTM */
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+#endif /* TOPPERS_get_utm */
Index: UsbWattMeter/trunk/asp_dcre/kernel/wait.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/wait.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/wait.c	(revision 164)
@@ -0,0 +1,221 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		Ò¿óÔÇW
+[
+ */
+
+#include "kernel_impl.h"
+#include "wait.h"
+
+/*
+ *  Ò¿óÔÖÌJÚi^CAEgwèj
+ */
+#ifdef TOPPERS_waimake
+
+void
+make_wait_tmout(WINFO *p_winfo, TMEVTB *p_tmevtb, TMO tmout)
+{
+	(void) make_non_runnable(p_runtsk);
+	p_runtsk->p_winfo = p_winfo;
+	if (tmout > 0) {
+		p_winfo->p_tmevtb = p_tmevtb;
+		tmevtb_enqueue(p_tmevtb, (RELTIM) tmout,
+						(CBACK) wait_tmout, (void *) p_runtsk);
+	}
+	else {
+		assert(tmout == TMO_FEVR);
+		p_winfo->p_tmevtb = NULL;
+	}
+}
+
+#endif /* TOPPERS_waimake */
+
+/*
+ *  Ò¿ð
+ */
+#ifdef TOPPERS_waicmp
+
+bool_t
+wait_complete(TCB *p_tcb)
+{
+	wait_dequeue_tmevtb(p_tcb);
+	p_tcb->p_winfo->wercd = E_OK;
+	return(make_non_wait(p_tcb));
+}
+
+#endif /* TOPPERS_waicmp */
+
+/*
+ *  ^CAEgÉº¤Ò¿ð
+ */
+#ifdef TOPPERS_waitmo
+
+void
+wait_tmout(TCB *p_tcb)
+{
+	wait_dequeue_wobj(p_tcb);
+	p_tcb->p_winfo->wercd = E_TMOUT;
+	if (make_non_wait(p_tcb)) {
+		reqflg = true;
+	}
+
+	/*
+	 *  ±±ÅDæxÌ¢Ýðó¯t¯éD
+	 */
+	i_unlock_cpu();
+	i_lock_cpu();
+}
+
+#endif /* TOPPERS_waitmo */
+#ifdef TOPPERS_waitmook
+
+void
+wait_tmout_ok(TCB *p_tcb)
+{
+	p_tcb->p_winfo->wercd = E_OK;
+	if (make_non_wait(p_tcb)) {
+		reqflg = true;
+	}
+
+	/*
+	 *  ±±ÅDæxÌ¢Ýðó¯t¯éD
+	 */
+	i_unlock_cpu();
+	i_lock_cpu();
+}
+
+#endif /* TOPPERS_waitmook */
+
+/*
+ *  Ò¿óÔÌ­§ð
+ */
+#ifdef TOPPERS_wairel
+
+bool_t
+wait_release(TCB *p_tcb)
+{
+	wait_dequeue_wobj(p_tcb);
+	wait_dequeue_tmevtb(p_tcb);
+	p_tcb->p_winfo->wercd = E_RLWAI;
+	return(make_non_wait(p_tcb));
+}
+
+#endif /* TOPPERS_wairel */
+
+/*
+ *  ÀsÌ^XNÌ¯úEÊMIuWFNgÌÒ¿L
+[ÖÌ}ü
+ *
+ *  ÀsÌ^XNðC¯úEÊMIuWFNgÌÒ¿L
+[Ö}ü·éDI
+ *  uWFNgÌ®«É¶ÄCFIFOÜ½Í^XNDæxÅ}ü·éD
+ */
+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));
+	}
+}
+
+/*
+ *  ¯úEÊMIuWFNgÉÎ·éÒ¿óÔÖÌJÚ
+ */
+#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 */
+
+/*
+ *  Ò¿L
+[Ìú»
+ */
+#ifdef TOPPERS_iniwque
+
+bool_t
+init_wait_queue(QUEUE *p_wait_queue)
+{
+	TCB		*p_tcb;
+	bool_t	dspreq = false;
+
+	while (!queue_empty(p_wait_queue)) {
+		p_tcb = (TCB *) queue_delete_next(p_wait_queue);
+		wait_dequeue_tmevtb(p_tcb);
+		p_tcb->p_winfo->wercd = E_DLT;
+		if (make_non_wait(p_tcb)) {
+			dspreq = true;
+		}
+	}
+	return(dspreq);
+}
+
+#endif /* TOPPERS_iniwque */
Index: UsbWattMeter/trunk/asp_dcre/kernel/wait.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/kernel/wait.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/kernel/wait.h	(revision 164)
@@ -0,0 +1,318 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		Ò¿óÔÇW
+[
+ */
+
+#ifndef TOPPERS_WAIT_H
+#define TOPPERS_WAIT_H
+
+#include "task.h"
+#include "time_event.h"
+
+/*
+ *  ^XNÌDæxÌÒ¿L
+[ÖÌ}ü
+ *
+ *  p_tcbÅwè³êé^XNðC^XNDæxÌL
+[p_queueÉ}ü·éD
+ *  L
+[ÌÉ¯¶DæxÌ^XNª éêÉÍC»ÌÅãÉ}ü·éD
+ */
+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));
+}
+
+/*
+ *  Ò¿óÔÖÌJÚ
+ *
+ *  ÀsÌ^XNðÒ¿óÔÉJÚ³¹éDïÌIÉÍCÀsÌ^XNð
+ *  fBL
+[©çíµCTCBÌp_winfotB[hCWINFOÌp_tmevtbtB[
+ *  hðÝè·éD
+ */
+Inline void
+make_wait(WINFO *p_winfo)
+{
+	(void) make_non_runnable(p_runtsk);
+	p_runtsk->p_winfo = p_winfo;
+	p_winfo->p_tmevtb = NULL;
+}
+
+/*
+ *  Ò¿óÔÖÌJÚi^CAEgwèj
+ *
+ *  ÀsÌ^XNðC^CAEgwèt«ÅÒ¿óÔÉJÚ³¹éDïÌ
+ *  IÉÍCÀsÌ^XNðfBL
+[©çíµCTCBÌp_winfotB[
+ *  hCWINFOÌp_tmevtbtB[hðÝè·éDÜ½C^CCxgu
+ *  bNðo^·éD
+ */
+extern void	make_wait_tmout(WINFO *p_winfo, TMEVTB *p_tmevtb, TMO tmout);
+
+/*
+ *  Ò¿ðÌ½ßÌ^XNóÔÌXV
+ *
+ *  p_tcbÅwè³êé^XNðCÒ¿ð·éæ¤^XNóÔðXV·éD
+ *  Ò¿ð·é^XNªÀsÅ«éóÔÉÈéêÍCfBL
+[ÉÂÈ
+ *  ®DÜ½CfBXpb`ªKvÈêÉÍtrueðÔ·D
+ */
+Inline bool_t
+make_non_wait(TCB *p_tcb)
+{
+	assert(TSTAT_WAITING(p_tcb->tstat));
+
+	if (!TSTAT_SUSPENDED(p_tcb->tstat)) {
+		/*
+		 *  Ò¿óÔ©çÀsÅ«éóÔÖÌJÚ
+		 */
+		p_tcb->tstat = TS_RUNNABLE;
+		LOG_TSKSTAT(p_tcb);
+		return(make_runnable(p_tcb));
+	}
+	else {
+		/*
+		 *  ñdÒ¿óÔ©ç­§Ò¿óÔÖÌJÚ
+		 */
+		p_tcb->tstat = TS_SUSPENDED;
+		LOG_TSKSTAT(p_tcb);
+		return(false);
+	}
+}
+
+/*
+ *  IuWFNgÒ¿L
+[©çÌí
+ *
+ *  p_tcbÅwè³êé^XNªC¯úEÊMIuWFNgÌÒ¿L
+[ÉÂ
+ *  ÈªêÄ¢êÎCÒ¿L
+[©çí·éD
+ */
+Inline void
+wait_dequeue_wobj(TCB *p_tcb)
+{
+	if (TSTAT_WAIT_WOBJ(p_tcb->tstat)) {
+		queue_delete(&(p_tcb->task_queue));
+	}
+}
+
+/*
+ *  ÔÒ¿Ì½ßÌ^CCxgubNÌo^ð
+ *
+ *  p_tcbÅwè³êé^XNÉÎµÄCÔÒ¿Ì½ßÌ^CCxgu
+ *  bNªo^³êÄ¢êÎC»êðo^ð·éD
+ */
+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Åwè³êé^XNÌÒ¿óÔðð·éDïÌIÉÍC^CC
+ *  xgubNªo^³êÄ¢êÎC»êðo^ð·éDÜ½C^XN
+ *  óÔðXVµCÒ¿ðµ½^XN©çÌÔlðE_OKÆ·éDÒ¿L
+[
+ *  ©çÌíÍsíÈ¢DÒ¿ðµ½^XNÖÌfBXpb`ªKvÈê
+ *  ÉÍtrueðÔ·D
+ */
+extern bool_t	wait_complete(TCB *p_tcb);
+
+/*
+ *  ^CAEgÉº¤Ò¿ð
+ *
+ *  p_tcbÅwè³êé^XNªCÒ¿L
+[ÉÂÈªêÄ¢êÎÒ¿L
+[
+ *  ©çíµC^XNóÔðXV·éDÜ½CÒ¿ðµ½^XN©çÌÔ
+ *  lðCwait_tmoutÅÍE_TMOUTCwait_tmout_okÅÍE_OKÆ·éDÒ¿ð
+ *  µ½^XNÖÌfBXpb`ªKvÈÍCreqflgðtrueÉ·éD
+ *
+ *  wait_tmout_okÍCdly_tskÅg¤½ßÌàÌÅCÒ¿L
+[©çí·é
+ *  ðsíÈ¢D
+ *
+ *  ¢¸êÌÖàC^CCxgÌR[obNÖÆµÄp¢é½ßÌ
+ *  àÌÅCÝnh©çÄÑo³êé±ÆðzèµÄ¢éD
+ */
+extern void	wait_tmout(TCB *p_tcb);
+extern void	wait_tmout_ok(TCB *p_tcb);
+
+/*
+ *  Ò¿óÔÌ­§ð
+ *
+ *  p_tcbÅwè³êé^XNÌÒ¿óÔð­§IÉð·éDïÌIÉÍC
+ *  ^XNªÒ¿L
+[ÉÂÈªêÄ¢êÎÒ¿L
+[©çíµC^CC
+ *  xgubNªo^³êÄ¢êÎ»êðo^ð·éDÜ½C^XNÌ
+ *  óÔðXVµCÒ¿ðµ½^XN©çÌÔlðE_RLWAIÆ·éDÜ½C
+ *  Ò¿ðµ½^XNÖÌfBXpb`ªKvÈêÉÍtrueðÔ·D
+ */
+extern bool_t	wait_release(TCB *p_tcb);
+
+/*
+ *  Ò¿L
+[ÌæªÌ^XNID
+ *
+ *  p_wait_queueÅwèµ½Ò¿L
+[ÌæªÌ^XNIDðÔ·DÒ¿L
+[
+ *  ªóÌêÉÍCTSK_NONEðÔ·D
+ */
+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);
+	}
+}
+
+/*
+ *  ¯úEÊMIuWFNgÌÇubNÌ¤Êªì[`
+ *
+ *  ¯úEÊMIuWFNgÌú»ubNÆÇubNÌæªªÍ¤
+ *  ÊÉÈÁÄ¢éDÈºÍC»Ì¤Êªðµ¤½ßÌ^¨æÑ[`Q
+ *  Å éD
+ *
+ *  ¡ÌÒ¿L
+[ðÂ¯úEÊMIuWFNgÌêCæªÈOÌÒ¿
+ *  L
+[ðì·éêÉÍC±êçÌ[`Íg¦È¢DÜ½CIuWF
+ *  Ng®«ÌTA_TPRIrbgðQÆ·éÌÅC±Ìrbgð¼ÌÚIÉgÁÄ
+ *  ¢éêàC±êçÌ[`Íg¦È¢D
+ */
+
+/*
+ *  ¯úEÊMIuWFNgÌú»ubNÌ¤Êª
+ */
+typedef struct wait_object_initialization_block {
+	ATR			wobjatr;		/* IuWFNg®« */
+} WOBJINIB;
+
+/*
+ *  ¯úEÊMIuWFNgÌÇubNÌ¤Êª
+ */
+typedef struct wait_object_control_block {
+	QUEUE		wait_queue;		/* Ò¿L
+[ */
+	const WOBJINIB *p_wobjinib;	/* ú»ubNÖÌ|C^ */
+} WOBJCB;
+
+/*
+ *  ¯úEÊMIuWFNgÌÒ¿îñubNÌ¤Êª
+ *
+ *  ±Ì\¢ÌÍCÒ¿îñubNiWINFOjðg£iIuWFNgwü¾
+ *  êÌp³Éjµ½àÌÅ éªCWINFOª¤pÌÅè`³êÄ¢é½
+ *  ßÉC1ÂÌtB[hÆµÄÜßÄ¢éD
+ */
+typedef struct wait_object_waiting_information {
+	WINFO	winfo;			/* WÌÒ¿îñubN */
+	WOBJCB	*p_wobjcb;		/* Ò¿IuWFNgÌÇubN */
+} WINFO_WOBJ;
+
+/*
+ *  ¯úEÊMIuWFNgÉÎ·éÒ¿óÔÖÌJÚ
+ *  
+ *  ÀsÌ^XNðÒ¿óÔÉJÚ³¹C¯úEÊMIuWFNgÌÒ¿L
+[
+ *  ÉÂÈ®DÜ½CÒ¿îñubNiWINFOjÌp_wobjcbðÝè·éD
+ *  wobj_make_wait_tmoutÍC^CCxgubNÌo^às¤D
+ */
+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);
+
+/*
+ *  ^XNDæxÏXÌ
+ *
+ *  ¯úEÊMIuWFNgÉÎ·éÒ¿óÔÉ é^XNÌDæxªÏX³
+ *  ê½êÉCÒ¿L
+[ÌÅÌ^XNÌÊuðC³·éD
+ */
+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);
+	}
+}
+
+/*
+ *  Ò¿L
+[Ìú»
+ *
+ *  Ò¿L
+[ÉÂÈªêÄ¢é^XNð·×ÄÒ¿ð·éDÒ¿ðµ½
+ *  ^XN©çÌÔlÍCE_DLTÆ·éDÒ¿ðµ½^XNÖÌfBXpb`
+ *  ªKvÈêÍtrueC»¤ÅÈ¢êÍfalseðÔ·D
+ */
+extern bool_t	init_wait_queue(QUEUE *p_wait_queue);
+
+#endif /* TOPPERS_WAIT_H */
Index: UsbWattMeter/trunk/asp_dcre/library/histogram.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/library/histogram.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/library/histogram.c	(revision 164)
@@ -0,0 +1,194 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ÀsÔªzWvW
+[
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include <histogram.h>
+#include "target_test.h"
+
+/*
+ *  ÀsÔªzvªÌ
+ */
+#ifndef TNUM_HIST
+#define TNUM_HIST		10
+#endif /* TNUM_HIST */
+
+/*
+ *  ^[QbgË¶ÅÝèÏX·é½ßÌ}N
+ */
+#ifndef HISTTIM						/* ÀsÔvªpÌÌf[^^ */
+#define HISTTIM			SYSUTM
+#endif /* HISTTIM */
+
+#ifndef HIST_GET_TIM				/* ÀsÔvªpÌ»ÝÌæ¾ */
+#ifndef TOPPERS_SUPPORT_GET_UTM
+#error get_utm is not supported.
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+#define HIST_GET_TIM(p_time)	((void) get_utm(p_time))
+#endif /* HIST_GET_TIM */
+
+#ifndef HIST_CONV_TIM				/* Ì·©çÀsÔÖÌÏ· */
+#define HIST_CONV_TIM(time)		((uint_t)(time))
+#endif /* HIST_CONV_TIM */
+
+#ifndef HIST_BM_HOOK				/* ÀsÔvª¼OÉs¤×« */
+#define HIST_BM_HOOK()			((void) 0)
+#endif
+
+/*
+ *  ÀsÔªzvªÇubN
+ */
+typedef struct histogram_control_block {
+	HISTTIM		begin_time;			/* vªJn */
+	uint_t		maxval;				/* ªzðL^·éÅåÔ */
+	uint_t		*histarea;			/* ªzðL^·éÌæ */
+	uint_t		over;				/* ÅåÔð´¦½x */
+	uint_t		under;				/* ÔÌt]ª^íêéx */
+} HISTCB;
+
+/*
+ *  ÀsÔªzvªÇubNÌGA
+ */
+static HISTCB	histcb_table[TNUM_HIST];
+
+/*
+ *  ÀsÔªzvªIDÌÅ¬lÆÅål
+ */
+#define TMIN_HISTID		1
+#define TMAX_HISTID		(TMIN_HISTID + TNUM_HIST - 1)
+
+/*
+ *  ÀsÔªzvªÌú»
+ */
+void
+init_hist(ID histid, uint_t maxval, uint_t histarea[])
+{
+	HISTCB	*p_histcb;
+	uint_t	i;
+
+	assert(TMIN_HISTID <= histid && histid <= TMAX_HISTID);
+	p_histcb = &(histcb_table[histid - TMIN_HISTID]);
+
+	for (i = 0; i <= maxval; i++) {
+		histarea[i] = 0U;
+	}
+	p_histcb->maxval = maxval;
+	p_histcb->histarea = histarea;
+	p_histcb->over = 0U;
+	p_histcb->under = 0U;
+}
+
+/*
+ *  ÀsÔvªÌJn
+ */
+void
+begin_measure(ID histid)
+{
+	HISTCB	*p_histcb;
+
+	assert(TMIN_HISTID <= histid && histid <= TMAX_HISTID);
+	p_histcb = &(histcb_table[histid - TMIN_HISTID]);
+
+	HIST_BM_HOOK();
+	HIST_GET_TIM(&(p_histcb->begin_time));
+}
+
+/*
+ *  ÀsÔvªÌI¹
+ */
+void
+end_measure(ID histid)
+{
+	HISTCB	*p_histcb;
+	HISTTIM	end_time;
+	uint_t	val;
+
+	HIST_GET_TIM(&end_time);
+
+	assert(TMIN_HISTID <= histid && histid <= TMAX_HISTID);
+	p_histcb = &(histcb_table[histid - TMIN_HISTID]);
+
+	val = HIST_CONV_TIM(end_time - p_histcb->begin_time);
+	if (val <= p_histcb->maxval) {
+		p_histcb->histarea[val]++;
+	}
+	else if (val <= ((uint_t) INT_MAX)) {
+		p_histcb->over++;
+	}
+	else {
+		p_histcb->under++;
+	}
+}
+
+/*
+ *  ÀsÔªzvªÌ\¦
+ */
+void
+print_hist(ID histid)
+{
+	HISTCB	*p_histcb;
+	uint_t	i;
+
+	assert(TMIN_HISTID <= histid && histid <= TMAX_HISTID);
+	p_histcb = &(histcb_table[histid - TMIN_HISTID]);
+
+	for (i = 0; i <= p_histcb->maxval; i++) {
+		if (p_histcb->histarea[i] > 0) {
+			syslog_2(LOG_NOTICE, "%d : %d", i, p_histcb->histarea[i]);
+			syslog_flush();
+		}
+	}
+	if (p_histcb->over > 0) {
+		syslog_2(LOG_NOTICE, "> %d : %d", p_histcb->maxval, p_histcb->over);
+	}
+	if (p_histcb->under > 0) {
+		syslog_1(LOG_NOTICE, "> INT_MAX : %d", p_histcb->under);
+	}
+	syslog_flush();
+}
Index: UsbWattMeter/trunk/asp_dcre/library/log_output.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/library/log_output.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/library/log_output.c	(revision 164)
@@ -0,0 +1,204 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		VXeOÌtH[}bgoÍ
+ */
+
+#include <t_stddef.h>
+#include <t_syslog.h>
+#include <log_output.h>
+
+/*
+ *  lð¶ñÉÏ·
+ */
+#define CONVERT_BUFLEN	((sizeof(uintptr_t) * CHAR_BIT + 2) / 3)
+										/* uintptr_t^ÌlÌÅå¶ */
+static void
+convert(uintptr_t val, uint_t radix, const char *radchar,
+			uint_t width, bool_t minus, bool_t padzero, void (*putc)(char))
+{
+	char	buf[CONVERT_BUFLEN];
+	uint_t	i, j;
+
+	i = 0U;
+	do {
+		buf[i++] = radchar[val % radix];
+		val /= radix;
+	} while (i < CONVERT_BUFLEN && val != 0);
+
+	if (minus && width > 0) {
+		width -= 1;
+	}
+	if (minus && padzero) {
+		(*putc)('-');
+	}
+	for (j = i; j < width; j++) {
+		(*putc)(padzero ? '0' : ' ');
+	}
+	if (minus && !padzero) {
+		(*putc)('-');
+	}
+	while (i > 0U) {
+		(*putc)(buf[--i]);
+	}
+}
+
+/*
+ *  ¶ñ®`oÍ
+ */
+static const char raddec[] = "0123456789";
+static const char radhex[] = "0123456789abcdef";
+static const char radHEX[] = "0123456789ABCDEF";
+
+void
+syslog_printf(const char *format, const intptr_t *p_args, void (*putc)(char))
+{
+	char		c;
+	uint_t		width;
+	bool_t		padzero;
+	intptr_t	val;
+	const char	*str;
+
+	while ((c = *format++) != '\0') {
+		if (c != '%') {
+			(*putc)(c);
+			continue;
+		}
+
+		width = 0U;
+		padzero = false;
+		if ((c = *format++) == '0') {
+			padzero = true;
+			c = *format++;
+		}
+		while ('0' <= c && c <= '9') {
+			width = width * 10U + c - '0';
+			c = *format++;
+		}
+		if (c == 'l') {
+			c = *format++;
+		}
+		switch (c) {
+		case 'd':
+			val = (intptr_t)(*p_args++);
+			if (val >= 0) {
+				convert((uintptr_t) val, 10U, raddec,
+										width, false, padzero, putc);
+			}
+			else {
+				convert((uintptr_t)(-val), 10U, raddec,
+										width, true, padzero, putc);
+			}
+			break;
+		case 'u':
+			val = (intptr_t)(*p_args++);
+			convert((uintptr_t) val, 10U, raddec, width, false, padzero, putc);
+			break;
+		case 'x':
+		case 'p':
+			val = (intptr_t)(*p_args++);
+			convert((uintptr_t) val, 16U, radhex, width, false, padzero, putc);
+			break;
+		case 'X':
+			val = (intptr_t)(*p_args++);
+			convert((uintptr_t) val, 16U, radHEX, width, false, padzero, putc);
+			break;
+		case 'c':
+			(*putc)((char)(intptr_t)(*p_args++));
+			break;
+		case 's':
+			str = (const char *)(*p_args++);
+			while ((c = *str++) != '\0') {
+				(*putc)(c);
+			}
+			break;
+		case '%':
+			(*putc)('%');
+			break;
+		case '\0':
+			format--;
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+/*
+ *  OîñÌoÍ
+ */
+void
+syslog_print(const SYSLOG *p_syslog, void (*putc)(char))
+{
+	switch (p_syslog->logtype) {
+	case LOG_TYPE_COMMENT:
+		syslog_printf((const char *)(p_syslog->loginfo[0]),
+								&(p_syslog->loginfo[1]), putc);
+		break;
+	case LOG_TYPE_ASSERT:
+		syslog_printf("%s:%u: Assertion `%s' failed.",
+								&(p_syslog->loginfo[0]), putc);
+		break;
+	default:
+		/*
+		 *  ¼ÌíÊÌOîñÉÍÎµÄ¢È¢D
+		 */
+		break;
+	}
+}
+
+/*
+ *  Oîñr¸bZ[WÌoÍ
+ */
+void
+syslog_lostmsg(uint_t lostlog, void (*putc)(char))
+{
+	intptr_t	lostinfo[1];
+
+	lostinfo[0] = (intptr_t) lostlog;
+	syslog_printf("%d messages are lost.", lostinfo, putc);
+	(*putc)('\n');
+}
Index: UsbWattMeter/trunk/asp_dcre/library/mem_pool.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/library/mem_pool.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/library/mem_pool.c	(revision 164)
@@ -0,0 +1,49 @@
+/*
+ * æ3ñ TOPPERSpACfAEAvP[VJ­ReXg
+ * ¼Y õm³ñÌulwIP ÌÚAvðx[XÉµÜµ½B
+ * http://www.toppers.jp/contest.html
+ *
+ *  @(#) $Id$
+ */
+//asp\doc\porting.txt
+//6.15.1æè
+
+#include "kernel/kernel_impl.h"
+#include "tlsf.h"
+
+static tlsf_t tlsf_kmm;
+static pool_t pool_kmm;
+
+void
+initialize_kmm(void)
+{
+	if ((kmm == NULL) || (kmmsz <= tlsf_size())) {
+		tlsf_kmm = NULL;
+		return;
+	}
+
+	tlsf_kmm = tlsf_create(kmm);
+	if (tlsf_kmm == NULL)
+		return;
+
+	pool_kmm = tlsf_add_pool(tlsf_kmm, ((uint8_t *)kmm) + tlsf_size(), kmmsz - tlsf_size());
+}
+
+void *
+kernel_malloc(SIZE size)
+{
+	if (tlsf_kmm != NULL) {
+		return tlsf_malloc(tlsf_kmm, size);
+	}
+	else {
+		return(NULL);
+	}
+}
+
+void
+kernel_free(void *ptr)
+{
+	if (tlsf_kmm != NULL) {
+		tlsf_free(tlsf_kmm, ptr);
+	}
+}
Index: UsbWattMeter/trunk/asp_dcre/library/strerror.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/library/strerror.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/library/strerror.c	(revision 164)
@@ -0,0 +1,114 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		G[bZ[W¶ñðÔ·Ö
+ */
+
+#include <t_stddef.h>
+#include <t_stdlib.h>
+
+const char *
+itron_strerror(ER ercd)
+{
+	switch (MERCD(ercd)) {
+	case E_OK:
+		return("E_OK");
+
+	case E_SYS:
+		return("E_SYS");
+	case E_NOSPT:
+		return("E_NOSPT");
+	case E_RSFN:
+		return("E_RSFN");
+	case E_RSATR:
+		return("E_RSATR");
+
+	case E_PAR:
+		return("E_PAR");
+	case E_ID:
+		return("E_ID");
+
+	case E_CTX:
+		return("E_CTX");
+	case E_MACV:
+		return("E_MACV");
+	case E_OACV:
+		return("E_OACV");
+	case E_ILUSE:
+		return("E_ILUSE");
+
+	case E_NOMEM:
+		return("E_NOMEM");
+	case E_NOID:
+		return("E_NOID");
+	case E_NORES:
+		return("E_NORES");
+
+	case E_OBJ:
+		return("E_OBJ");
+	case E_NOEXS:
+		return("E_NOEXS");
+	case E_QOVR:
+		return("E_QOVR");
+
+	case E_RLWAI:
+		return("E_RLWAI");
+	case E_TMOUT:
+		return("E_TMOUT");
+	case E_DLT:
+		return("E_DLT");
+	case E_CLS:
+		return("E_CLS");
+
+	case E_WBLK:
+		return("E_WBLK");
+	case E_BOVR:
+		return("E_BOVR");
+
+	default:
+		return("unknown error");
+	}
+}
Index: UsbWattMeter/trunk/asp_dcre/library/t_perror.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/library/t_perror.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/library/t_perror.c	(revision 164)
@@ -0,0 +1,60 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		G[bZ[WÌoÍ
+ */
+
+#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: UsbWattMeter/trunk/asp_dcre/library/test_lib.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/library/test_lib.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/library/test_lib.c	(revision 164)
@@ -0,0 +1,207 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2005-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *		eXgvOpCu
+ */
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <log_output.h>
+#include "syssvc/syslog.h"
+#include "target_syssvc.h"
+#include <test_lib.h>
+
+/*
+ *	`FbN|Cg
+ */
+static uint_t	check_count = 0u;
+
+/*
+ *	©ÈffÖ
+ */
+static BIT_FUNC	check_bit_func = NULL;
+
+/*
+ *	©ÈffÖÌÝè
+ */
+void
+set_bit_func(BIT_FUNC bit_func)
+{
+	check_bit_func = bit_func;
+}
+
+/*
+ *  eXgvOÌJn
+ */
+void
+test_start(char *progname)
+{
+	syslog_1(LOG_NOTICE, "Test program: %s", progname);
+}
+
+/*
+ *  VXeOÌoÍ
+ */
+void
+syslog_flush(void)
+{
+	SYSLOG	logbuf;
+	ER_UINT	rercd;
+
+	/*
+	 *  Oobt@ÉL^³ê½OîñðCáxoÍ@\ðp¢Äo
+	 *  Í·éD
+	 */
+	while ((rercd = syslog_rea_log(&logbuf)) >= 0) {
+		if (rercd > 0) {
+			syslog_lostmsg((uint_t) rercd, target_fput_log);
+		}
+		if (logbuf.logtype >= LOG_TYPE_COMMENT) {
+			syslog_print(&logbuf, target_fput_log);
+			target_fput_log('\n');
+		}
+	}
+}
+
+/*
+ *	eXgvOÌI¹
+ */
+void
+test_finish(void)
+{
+	SIL_PRE_LOC;
+
+	SIL_LOC_INT();
+	syslog_flush();
+	(void) ext_ker();
+
+	/* ±±Öé±ÆÍÈ¢Í¸ */
+	SIL_UNL_INT();
+}
+
+/*
+ *	`FbN|Cg
+ */
+void
+check_point(uint_t count)
+{
+	bool_t	errorflag = false;
+	ER		rercd;
+	SIL_PRE_LOC;
+
+	/*
+	 *  ÝbNóÔÉ
+	 */
+	SIL_LOC_INT();
+
+	/*
+	 *  V[PX`FbN
+	 */
+	if (++check_count == count) {
+		syslog_1(LOG_NOTICE, "Check point %d passed.", count);
+	}
+	else {
+		syslog_1(LOG_ERROR, "## Unexpected check point %d.", count);
+		errorflag = true;
+	}
+
+	/*
+	 *  J[lÌàóÔÌ¸
+	 */
+	if (check_bit_func != NULL) {
+		rercd = (*check_bit_func)();
+		if (rercd < 0) {
+			syslog_2(LOG_ERROR, "## Internal inconsistency detected (%s, %d).",
+								itron_strerror(rercd), SERCD(rercd));
+			errorflag = true;
+		}
+	}
+
+	/*
+	 *  G[ªo³ê½êÍCeXgvOðI¹·éD
+	 */
+	if (errorflag) {
+		test_finish();
+	}
+
+	/*
+	 *  ÝbNóÔðð
+	 */
+	SIL_UNL_INT();
+}
+
+/*
+ *	®¹`FbN|Cg
+ */
+void
+check_finish(uint_t count)
+{
+	check_point(count);
+	syslog_0(LOG_NOTICE, "All check points passed.");
+	test_finish();
+}
+
+/*
+ *	ð`FbNÌG[
+ */
+void
+_check_assert(const char *expr, const char *file, int_t line)
+{
+	syslog_3(LOG_ERROR, "## Assertion `%s' failed at %s:%u.",
+								expr, file, line);
+	test_finish();
+}
+
+/*
+ *	G[R[h`FbNÌG[
+ */
+void
+_check_ercd(ER ercd, const char *file, int_t line)
+{
+	syslog_3(LOG_ERROR, "## Unexpected error %s detected at %s:%u.",
+								itron_strerror(ercd), file, line);
+	test_finish();
+}
Index: UsbWattMeter/trunk/asp_dcre/library/vasyslog.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/library/vasyslog.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/library/vasyslog.c	(revision 164)
@@ -0,0 +1,121 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ÂÏøÌVXeOCu
+ */
+
+#include <t_stddef.h>
+#include <t_syslog.h>
+#include <stdarg.h>
+
+#ifndef TOPPERS_OMIT_SYSLOG
+
+void
+vsyslog(uint_t prio, const char *format, va_list ap)
+{
+	SYSLOG	logbuf;
+	uint_t	i;
+	char	c;
+	bool_t	lflag;
+
+	logbuf.logtype = LOG_TYPE_COMMENT;
+	logbuf.loginfo[0] = (intptr_t) format;
+	i = 1U;
+
+	while ((c = *format++) != '\0' && i < TMAX_LOGINFO) {
+		if (c != '%') {
+			continue;
+		}
+
+		lflag = false;
+		c = *format++;
+		while ('0' <= c && c <= '9') {
+			c = *format++;
+		}
+		if (c == 'l') {
+			lflag = true;
+			c = *format++;
+		}
+		switch (c) {
+		case 'd':
+			logbuf.loginfo[i++] = lflag ? (intptr_t) va_arg(ap, long_t)
+										: (intptr_t) va_arg(ap, int_t);
+			break;
+		case 'u':
+		case 'x':
+		case 'X':
+			logbuf.loginfo[i++] = lflag ? (intptr_t) va_arg(ap, ulong_t)
+										: (intptr_t) va_arg(ap, uint_t);
+			break;
+		case 'p':
+			logbuf.loginfo[i++] = (intptr_t) va_arg(ap, void *);
+			break;
+		case 'c':
+			logbuf.loginfo[i++] = (intptr_t) va_arg(ap, int);
+			break;
+		case 's':
+			logbuf.loginfo[i++] = (intptr_t) va_arg(ap, const char *);
+			break;
+		case '\0':
+			format--;
+			break;
+		default:
+			break;
+		}
+	}
+	(void) syslog_wri_log(prio, &logbuf);
+}
+
+void
+syslog(uint_t prio, const char *format, ...)
+{
+	va_list	ap;
+	va_start(ap, format);
+	vsyslog(prio, format, ap);
+	va_end(ap);
+}
+
+#endif /* TOPPERS_OMIT_SYSLOG */
Index: UsbWattMeter/trunk/asp_dcre/pdic/rx600/MANIFEST
===================================================================
--- UsbWattMeter/trunk/asp_dcre/pdic/rx600/MANIFEST	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/pdic/rx600/MANIFEST	(revision 164)
@@ -0,0 +1,6 @@
+PACKAGE pdic_rx600
+VERSION 1.6.0
+
+MANIFEST
+rx600_uart.c
+rx600_uart.h
Index: UsbWattMeter/trunk/asp_dcre/pdic/rx600/rx630_uart.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/pdic/rx600/rx630_uart.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/pdic/rx600/rx630_uart.c	(revision 164)
@@ -0,0 +1,466 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+
+/*
+ * UARTp ÈÕSIOhCo
+ */
+
+#include <sil.h>
+#include <kernel.h>
+#include <t_syslog.h>
+#include "target_syssvc.h"
+#include "rx630_uart.h"
+
+/* VA[hWX^iSMR) */
+#define CKS			UINT_C(0x03)
+#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)
+
+/* VARg[WX^iSCR) */
+#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)
+
+/* VAXe[^XWX^iSSRj */
+#define TEND		UINT_C(0x04)
+#define PER			UINT_C(0x08)
+#define FER			UINT_C(0x10)
+#define ORER		UINT_C(0x20)
+
+/* VAg£[hWX^iSEMR) */
+#define ACS0		UINT_C(0x01)
+#define ABCS		UINT_C(0x10)
+
+#define SCI_SCR_FLG_ENABLE	(RE | TE)
+#define SCI_SMR_FLG_ENABLE	(STOP | PM | PE | CHR | CM)
+
+/*
+ *  VAI/O|[gú»ubNÌè`
+ */
+typedef struct sio_port_initialization_block {
+	volatile uint8_t	*ctlreg;		/* VARg[WX^iSCR) */
+	volatile uint8_t	*modereg;		/* VA[hWX^iSMR) */
+	volatile uint8_t	*extmodereg;	/* VAg£[hWX^iSEMR) */	
+	volatile uint8_t	*statusreg;		/* VAXe[^XWX^iSSRj */
+	volatile uint8_t	*tdreg;			/* gX~bgf[^WX^iTDR)*/
+	volatile uint8_t	*rdreg;			/* V[uf[^WX^iRDR) */
+	volatile uint8_t	*bitratereg;	/* rbg[gWX^iBRR) */
+	volatile uint32_t	*mstpcrreg;		/* W
+[XgbvRg[WX^iMSTPCRj */
+	volatile uint8_t	*ssrreg;		/* Xe[^XWX^ */
+	volatile uint8_t	*rxiirreg;		/* RXIpÝvWX^ */
+	uint8_t				tx_intno;		/* Mif[^GveBjèÝÔ */
+	uint8_t				rx_intno;		/* óMif[^tjèÝÔ */
+	uint8_t				te_intno;		/* MiI¹jèÝÔ */
+	uint8_t				sci_no;			/* SCIÌÔ(SCI0`SCI6) */
+	uint32_t			mstpcr_offset;	/* MSTPCRÌÎ·érbgItZbg */
+} SIOPINIB;
+
+/*
+ *  VAI/O|[gÇubNÌè`
+ */
+struct sio_port_control_block {
+	const SIOPINIB	*p_siopinib; 				/* VAI/O|[gú»ubN */
+	intptr_t 	exinf;			 				/* g£îñ */
+	bool_t		openflag;						/* I[vÏÝtO */
+	bool_t		sendflag;						/* MÝCl[utO */
+	bool_t		getready;						/* ¶ðóMµ½óÔ */
+	bool_t		putready;						/* ¶ðMÅ«éóÔ */
+	bool_t		is_initialized; 				/* foCXú»ÏÝtO */
+};
+
+/*
+ *  VAI/O|[gÇubNÌGA
+ */
+static SIOPCB	siopcb_table[TNUM_SIOP];
+
+/* WX^e[u */
+static const SIOPINIB siopinib_table[TNUM_SIOP] =
+{
+	{
+		(volatile uint8_t *)SCI0_SCR_ADDR,
+		(volatile uint8_t *)SCI0_SMR_ADDR,
+		(volatile uint8_t *)SCI0_SEMR_ADDR,
+		(volatile uint8_t *)SCI0_SSR_ADDR,
+		(volatile uint8_t *)SCI0_TDR_ADDR,
+		(volatile uint8_t *)SCI0_RDR_ADDR,
+		(volatile uint8_t *)SCI0_BRR_ADDR,
+		(volatile uint32_t *)SYSTEM_MSTPCRB_ADDR,
+		(volatile uint8_t *)SCI0_SSR_ADDR,
+		(volatile uint8_t *)ICU_IR215_ADDR,
+		INT_SCI0_TXI,
+		INT_SCI0_RXI,
+		INT_SCI0_TEI,
+		0,
+		SYSTEM_MSTPCRB_MSTPB31_BIT,
+	} ,			/* UART0 */
+#if TNUM_SIOP > 1
+	{
+		(volatile uint8_t *)SCI2_SCR_ADDR,
+		(volatile uint8_t *)SCI2_SMR_ADDR,
+		(volatile uint8_t *)SCI2_SEMR_ADDR,
+		(volatile uint8_t *)SCI2_SSR_ADDR,
+		(volatile uint8_t *)SCI2_TDR_ADDR,
+		(volatile uint8_t *)SCI2_RDR_ADDR,
+		(volatile uint8_t *)SCI2_BRR_ADDR,
+		(volatile uint32_t *)SYSTEM_MSTPCRB_ADDR,
+		(volatile uint8_t *)SCI2_SSR_ADDR,
+		(volatile uint8_t *)ICU_IR223_ADDR,
+		INT_SCI2_TXI,
+		INT_SCI2_RXI,
+		INT_SCI2_TEI,
+		2,
+		SYSTEM_MSTPCRB_MSTPB29_BIT,
+	} ,			/* UART2 */
+#endif
+};
+
+/*
+ *  VAI/O|[gID©çÇubNðæèo·½ßÌ}N
+ */
+#define INDEX_SIOP(siopid)	 ((uint_t)((siopid) - 1))
+#define get_siopcb(siopid)	 (&(siopcb_table[INDEX_SIOP(siopid)]))
+#define get_siopinib(siopid) (&(siopinib_table[INDEX_SIOP(siopid)]))
+
+
+/*
+ *  SIOhCoÌVA[hWX^(SMR)
+ */
+static void
+rx630_uart_setmode(const SIOPINIB *p_siopinib, uint8_t bitrate, uint8_t clksrc)
+{
+	volatile uint8_t i;
+
+	/*
+	 *  SCIhCoÌú»[`
+	 */
+
+	/*
+	 *  èÝvæWX^ÌÝè(ISELRi)
+	 *
+	 *  ZbglÆ¯¶lðÝè·é±ÆÉÈé½ß,
+	 *  ÍÈª·é.
+	 */
+
+	/*
+	 *  W
+[Xgbv@\ÌÝè
+	 */
+	sil_wrh_mem((uint16_t *)SYSTEM_PRCR_ADDR, (uint16_t)0xA502);	/* ÝÂ */
+	sil_wrw_mem((uint32_t *)p_siopinib->mstpcrreg,
+		sil_rew_mem((uint32_t *)p_siopinib->mstpcrreg) & ~p_siopinib->mstpcr_offset);
+	sil_wrh_mem((uint16_t *)SYSTEM_PRCR_ADDR, (uint16_t)0xA500);	/* ÝÖ~ */
+
+	/* óMÖ~, SCKn[qÍüoÍ|[gÆµÄgp */
+	sil_wrb_mem((uint8_t *)p_siopinib->ctlreg, 0x00U);
+
+	/* NbNIðrbg(SMR.CKS[1:0]rbgðÝè) */
+	sil_wrb_mem((uint8_t *)p_siopinib->modereg, 
+					sil_reb_mem((uint8_t *)p_siopinib->modereg) | clksrc);
+
+	/* SMRÉM^ óMtH[}bgðÝè) */
+	sil_wrb_mem((uint8_t *)p_siopinib->modereg, 
+			sil_reb_mem((uint8_t *)p_siopinib->modereg) & (~SCI_SMR_FLG_ENABLE));
+
+	/* rbg[gðÝè */
+	sil_wrb_mem((uint8_t *)p_siopinib->bitratereg, bitrate);
+
+	/* rbgúÔ(î{NbN16TCNÌúÔª1rbgúÔÆÈé) */
+	for(i = 0; i < 16; i++) { }
+
+	/* óMÂ */
+	sil_wrb_mem((uint8_t *)p_siopinib->ctlreg, 
+		(sil_reb_mem((uint8_t *)p_siopinib->ctlreg) | SCI_SCR_FLG_ENABLE));
+}
+
+
+/*
+ *  SIOhCoÌú»[`
+ */
+void
+rx630_uart_initialize(void)
+{
+	SIOPCB	*p_siopcb;
+	uint_t	i;
+
+	/*
+	 *  VAI/O|[gÇubNÌú»
+	 */
+	for (p_siopcb = siopcb_table, i = 0; i < TNUM_SIOP; p_siopcb++, i++){
+		p_siopcb->p_siopinib = &(siopinib_table[i]);
+		p_siopcb->openflag = false;
+		p_siopcb->sendflag = false;
+	}
+}
+
+/*
+ *  J[lN®Ìoi[oÍpÌú»
+ */
+void
+rx630_uart_init(ID siopid, uint8_t bitrate, uint8_t clksrc)
+{
+	SIOPCB          *p_siopcb   = get_siopcb(siopid);
+	const SIOPINIB  *p_siopinib = get_siopinib(siopid);
+	/*  ±Ì_ÅÍAp_siopcb->p_siopinibÍú»³êÄ¢È¢  */
+
+	/*  ñdú»Ìh~  */
+	p_siopcb->is_initialized = true;
+
+	/*  n[hEFAÌú»ÆMÂ  */
+	rx630_uart_setmode(p_siopinib , bitrate, clksrc);
+	sil_wrb_mem((uint8_t *)p_siopinib->ctlreg, 
+		(uint8_t)(sil_reb_mem((uint8_t *)p_siopinib->ctlreg) | TE));
+}
+
+/*
+ *  VAI/O|[gÖÌ|[OÅÌoÍ
+ */
+void
+rx630_uart_pol_putc(char c, ID siopid)
+{
+	const SIOPINIB *p_siopinib;
+
+	p_siopinib = get_siopinib(siopid);
+
+	/*
+	 *  MWX^ªóÉÈéÜÅÒÂ
+	 */
+	while((sil_reb_mem((uint8_t *)p_siopinib->ssrreg) & SCI_SSR_TEND_BIT) == 0U);
+
+	sil_wrb_mem((uint8_t *)p_siopinib->tdreg, (uint8_t)c);
+}
+
+/*
+ *  VAI/O|[gÌI[v
+ */
+SIOPCB *
+rx630_uart_opn_por
+	(ID siopid, intptr_t exinf, uint8_t bitrate, uint8_t clksrc)
+{
+	SIOPCB          *p_siopcb;
+	const SIOPINIB  *p_siopinib;
+
+	p_siopcb = get_siopcb(siopid);
+	p_siopinib = p_siopcb->p_siopinib;
+
+	/*
+	 *  n[hEFAÌú»
+	 *
+	 *  ùÉú»µÄ¢éêÍ, ñdÉú»µÈ¢.
+	 */
+	if(!(p_siopcb->is_initialized)){
+		rx630_uart_setmode(p_siopinib, bitrate, clksrc);
+		p_siopcb->is_initialized = true;
+	}
+
+	p_siopcb->exinf = exinf;
+	p_siopcb->getready = p_siopcb->putready = false;
+	p_siopcb->openflag = true;
+
+	return (p_siopcb);
+}
+
+/*
+ *  VAI/O|[gÌN[Y
+ */
+void
+rx630_uart_cls_por(SIOPCB *p_siopcb)
+{
+	/*
+	 *  UARTâ~
+	 */
+	sil_wrh_mem((uint16_t *)p_siopcb->p_siopinib->ctlreg, 0x00U);
+	p_siopcb->openflag = false;
+	p_siopcb->is_initialized = false;
+}
+
+/*
+ *  VAI/O|[gÖÌ¶M
+ */
+bool_t
+rx630_uart_snd_chr(SIOPCB *p_siopcb, char c)
+{
+	bool_t ercd = false;
+
+	if((sil_reb_mem(
+		(uint8_t *)p_siopcb->p_siopinib->ssrreg) & SCI_SSR_TEND_BIT) != 0){
+		sil_wrb_mem((uint8_t *)p_siopcb->p_siopinib->tdreg, (uint8_t)c);
+		ercd = true;
+	}
+
+	return ercd;
+}
+
+/*
+ *  VAI/O|[g©çÌ¶óM
+ */
+int_t
+rx630_uart_rcv_chr(SIOPCB *p_siopcb)
+{
+	int_t c = -1;
+
+	/*
+	 *  óMtOªONÌÆ«ÌÝóMobt@©ç¶ðæ¾·é.
+	 *  ±êÍ, |[OóMÉÎ·é½ßÅ é.
+	 *  µ©µ, RX600V[YÅÍóMtOªÈ¢±Æ, VXeT[rX
+	 *  ÅÍóMÝÌ©çµ©f[^ðóMµÉÈ¢±Æ©ç, íÉ
+	 *  óMobt@©ç¶ðæ¾·é.
+	 */
+	c = (int)(sil_reb_mem((uint8_t *)p_siopcb->p_siopinib->rdreg));
+
+	return c;
+}
+
+/*
+ *  VAI/O|[g©çÌR[obNÌÂ
+ */
+void
+rx630_uart_ena_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
+{
+	switch (cbrtn) {
+		case SIO_RDY_SND:
+			sil_wrb_mem((uint8_t *)p_siopcb->p_siopinib->ctlreg, 
+				(sil_reb_mem((uint8_t *)p_siopcb->p_siopinib->ctlreg) | SCI_SCR_TEIE_BIT));
+			break;
+		case SIO_RDY_RCV:
+			sil_wrb_mem((uint8_t *)p_siopcb->p_siopinib->ctlreg, 
+				(sil_reb_mem((uint8_t *)p_siopcb->p_siopinib->ctlreg) | SCI_SCR_RIE_BIT));
+			break;
+		default:
+			assert(1);
+			break;
+	}
+}
+
+/*
+ *  VAI/O|[g©çÌR[obNÌÖ~
+ */
+void
+rx630_uart_dis_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
+{
+	switch (cbrtn) {
+		case SIO_RDY_SND:
+			sil_wrb_mem((uint8_t *)p_siopcb->p_siopinib->ctlreg, 
+				(sil_reb_mem((uint8_t *)p_siopcb->p_siopinib->ctlreg) & (~SCI_SCR_TEIE_BIT)));
+			break;
+		case SIO_RDY_RCV:
+			sil_wrb_mem((uint8_t *)p_siopcb->p_siopinib->ctlreg, 
+				(sil_reb_mem((uint8_t *)p_siopcb->p_siopinib->ctlreg) & (~SCI_SCR_RIE_BIT)));
+			break;
+		default:
+			assert(1);
+			break;
+	}
+}
+
+/*
+ *  SIOÌÝT[rX[`
+ */
+void
+rx630_uart_tx_isr(ID siopid)
+{
+	SIOPCB	*p_siopcb = get_siopcb(siopid);
+
+	if((sil_reb_mem(
+		(void *)p_siopcb->p_siopinib->ssrreg) & SCI_SSR_TEND_BIT) != 0U){
+		/*
+		 *  MÂ\R[obN[`ðÄÑo·D
+		 */
+		rx630_uart_irdy_snd(p_siopcb->exinf);
+	}
+}
+
+void
+rx630_uart_rx_isr(ID siopid)
+{
+	SIOPCB	*p_siopcb = get_siopcb(siopid);
+
+	/*
+	 *  óMtOªONÌÆ«ÌÝóMÊmR[obN[`ðÄÑo·.
+	 *  µ©µ, RX600V[YÅÍóMtOªÈ¢½ß, íÉóMÊm
+	 *  R[obN[`ðÄÑo·.
+	 *  ±±ÅÍóMÝÌ­¶ðM¶é.
+	 */
+	/*
+	 *  óMÊmR[obN[`ðÄÑo·D
+	 */
+	rx630_uart_irdy_rcv(p_siopcb->exinf);
+}
+
+
+/*
+ *  |[gÔ©çÇubNÌæªÔnÖÌÏ·
+ */
+SIOPCB *
+rx630_uart_get_siopcb(ID siopid) {
+	SIOPCB *p_siopcb = get_siopcb(siopid);
+	return(p_siopcb);
+}
+
+/*
+ * ÇubNÌæªÔn©çóMÝÔÖÌÏ·
+ */
+INTNO 
+rx630_uart_intno_rx(SIOPCB *p_siopcb) {
+	INTNO intno = p_siopcb->p_siopinib->rx_intno;
+	return(intno);
+}
+
+/*
+ * ÇubNÌæªÔn©çMÝÔÖÌÏ·
+ */
+INTNO 
+rx630_uart_intno_tx(SIOPCB *p_siopcb) {
+	INTNO intno = p_siopcb->p_siopinib->te_intno;
+	return(intno);
+}
Index: UsbWattMeter/trunk/asp_dcre/pdic/rx600/rx630_uart.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/pdic/rx600/rx630_uart.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/pdic/rx600/rx630_uart.h	(revision 164)
@@ -0,0 +1,151 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UARTp ÈÕSIOhCo
+ */
+
+#ifndef TOPPERS_RX630_UART_H
+#define TOPPERS_RX630_UART_H
+
+/* wèÂ\ÈNbN\[X */
+#define CLK_F1	UINT_C(0x00)
+#define CLK_F4	UINT_C(0x01)
+#define CLK_F16	UINT_C(0x02)
+#define CLK_F64	UINT_C(0x03)
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  VAI/O|[gÇubNÌè`
+ */
+typedef struct sio_port_control_block	SIOPCB;
+
+/*
+ *  R[obN[`Ì¯ÊÔ
+ */
+#define SIO_RDY_SND    (1U)        /* MÂ\R[obN */
+#define SIO_RDY_RCV    (2U)        /* óMÊmR[obN */
+
+/*
+ *  SIOhCoÌú»[`
+ */
+extern void rx630_uart_initialize(void);
+
+/*
+ * J[lN®Ìoi[oÍpÌú»
+ */
+extern void rx630_uart_init(ID siopid , uint8_t baud , uint8_t clksrc);
+
+/*
+ *  VAI/O|[gÖÌ|[OÅÌoÍ
+ */
+extern void rx630_uart_pol_putc(char c, ID siopid);
+
+/*
+ *  VAI/O|[gÌI[v
+ */
+extern SIOPCB *rx630_uart_opn_por
+	(ID siopid, intptr_t exinf , uint8_t baud , uint8_t clksrc);
+
+/*
+ *  VAI/O|[gÌN[Y
+ */
+extern void rx630_uart_cls_por(SIOPCB *p_siopcb);
+
+/*
+ *  VAI/O|[gÖÌ¶M
+ */
+extern bool_t rx630_uart_snd_chr(SIOPCB *p_siopcb, char c);
+
+/*
+ *  VAI/O|[g©çÌ¶óM
+ */
+extern int_t rx630_uart_rcv_chr(SIOPCB *p_siopcb);
+
+/*
+ *  VAI/O|[g©çÌR[obNÌÂ
+ */
+extern void  rx630_uart_ena_cbr(SIOPCB *p_siopcb, uint_t cbrtn);
+
+/*
+ *  VAI/O|[g©çÌR[obNÌÖ~
+ */
+extern void rx630_uart_dis_cbr(SIOPCB *p_siopcb, uint_t cbrtn);
+
+/*
+ *  SIOÌÝT[rX[`
+ */
+extern void rx630_uart_tx_isr(ID siopid);
+extern void rx630_uart_rx_isr(ID siopid);
+
+/*
+ *  VAI/O|[g©çÌMÂ\R[obN
+ */
+extern void rx630_uart_irdy_snd(intptr_t exinf);
+
+/*
+ *  VAI/O|[g©çÌóMÊmR[obN
+ */
+extern void rx630_uart_irdy_rcv(intptr_t exinf);
+
+
+/*
+ *  |[gÔ©çÇubNÌæªÔnÖÌÏ·
+ */
+extern SIOPCB *rx630_uart_get_siopcb(ID siopid);
+
+/*
+ * ÇubNÌæªÔn©çóMÝÔÖÌÏ·
+ */
+extern INTNO rx630_uart_intno_rx(SIOPCB *p_siopcb);
+
+/*
+ * ÇubNÌæªÔn©çMÝÔÖÌÏ·
+ */
+extern INTNO rx630_uart_intno_tx(SIOPCB *p_siopcb);
+
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_RX630_UART_H */
Index: UsbWattMeter/trunk/asp_dcre/syssvc/banner.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/syssvc/banner.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/syssvc/banner.c	(revision 164)
@@ -0,0 +1,76 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		J[lN®bZ[WÌoÍ
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "target_syssvc.h"
+#include "banner.h"
+
+#ifndef TARGET_COPYRIGHT
+#define TARGET_COPYRIGHT
+#endif /* TARGET_COPYRIGHT */
+
+static const char banner[] = "\n"
+"TOPPERS/ASP Kernel Release %d.%X.%d for " TARGET_NAME
+" (" __DATE__ ", " __TIME__ ")\n"
+"Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory\n"
+"                            Toyohashi Univ. of Technology, JAPAN\n"
+"Copyright (C) 2004-2014 by Embedded and Real-Time Systems Laboratory\n"
+"            Graduate School of Information Science, Nagoya Univ., JAPAN\n"
+TARGET_COPYRIGHT;
+
+void
+print_banner(intptr_t exinf)
+{
+	syslog_3(LOG_NOTICE, banner,
+				(TKERNEL_PRVER >> 12) & 0x0fU,
+				(TKERNEL_PRVER >> 4) & 0xffU,
+				TKERNEL_PRVER & 0x0fU);
+}
Index: UsbWattMeter/trunk/asp_dcre/syssvc/banner.cfg
===================================================================
--- UsbWattMeter/trunk/asp_dcre/syssvc/banner.cfg	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/syssvc/banner.cfg	(revision 164)
@@ -0,0 +1,11 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *		J[lN®bZ[WÌoÍÌRtBM
+[Vt@C
+ */
+
+#include "syssvc/banner.h"
+ATT_INI({ TA_NULL, 0, print_banner });
Index: UsbWattMeter/trunk/asp_dcre/syssvc/banner.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/syssvc/banner.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/syssvc/banner.h	(revision 164)
@@ -0,0 +1,57 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		J[lN®bZ[WÌoÍ
+ */
+
+#ifndef TOPPERS_BANNER_H
+#define TOPPERS_BANNER_H
+
+/*
+ *  J[lN®bZ[WÌoÍ
+ */
+extern void	print_banner(intptr_t exinf) throw();
+
+#endif /* TOPPERS_BANNER_H */
Index: UsbWattMeter/trunk/asp_dcre/syssvc/logtask.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/syssvc/logtask.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/syssvc/logtask.c	(revision 164)
@@ -0,0 +1,202 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		VXeO^XN
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <log_output.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "logtask.h"
+
+/*
+ *  VXeO^XNÌoÍæÌ|[gID
+ */
+static ID	logtask_portid;
+
+/*
+ *  VAC^tF[XÖÌ1¶oÍ
+ */
+static void
+logtask_putc(char c)
+{
+	(void) serial_wri_dat(logtask_portid, &c, 1);
+}
+
+/*
+ *  VXeOoÍÌÒ¿í¹
+ */
+ER
+logtask_flush(uint_t count)
+{
+	T_SYSLOG_RLOG	rlog;
+	T_SERIAL_RPOR	rpor;
+	ER				ercd, rercd;
+
+	if (sns_dpn()) {
+		ercd = E_CTX;
+	}
+	else {
+		for (;;) {
+			if (syslog_ref_log(&rlog) < 0) {
+				ercd = E_SYS;
+				goto error_exit;
+			}
+			if (rlog.count <= count) {
+				if (count == 0U) {
+					/*
+					 *  countª0ÌêÉÍCVAobt@ªó©ðm
+					 *  F·éD
+					 */
+					if (serial_ref_por(logtask_portid, &rpor) < 0) {
+						ercd = E_SYS;
+						goto error_exit;
+					}
+					if (rpor.wricnt == 0U) {
+						ercd = E_OK;
+						goto error_exit;
+					}
+				}
+				else {
+					ercd = E_OK;
+					goto error_exit;
+				}
+			}
+
+			/*
+			 *  LOGTASK_FLUSH_WAIT~bÒÂD
+			 */
+			rercd = dly_tsk(LOGTASK_FLUSH_WAIT);
+			if (rercd < 0) {
+				ercd = (rercd == E_RLWAI) ? rercd : E_SYS;
+				goto error_exit;
+			}
+		}
+	}
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  VXeO^XNÌ{Ì
+ */
+void
+logtask_main(intptr_t exinf)
+{
+	SYSLOG	logbuf;
+	uint_t	lostlog;
+	ER_UINT	rercd;
+
+	logtask_portid = (ID) exinf;
+	(void) serial_opn_por(logtask_portid);
+	(void) syslog_msk_log(LOG_UPTO(LOG_NOTICE), LOG_UPTO(LOG_EMERG));
+	syslog_1(LOG_NOTICE, "System logging task is started on port %d.",
+													logtask_portid);
+	for (;;) {
+		lostlog = 0U;
+		while ((rercd = syslog_rea_log(&logbuf)) >= 0) {
+			lostlog += (uint_t) rercd;
+			if (logbuf.logtype >= LOG_TYPE_COMMENT) {
+				if (lostlog > 0U) {
+					syslog_lostmsg(lostlog, logtask_putc);
+					lostlog = 0U;
+				}
+				syslog_print(&logbuf, logtask_putc);
+				logtask_putc('\n');
+			}
+		}
+		if (lostlog > 0U) {
+			syslog_lostmsg(lostlog, logtask_putc);
+		}
+		(void) dly_tsk(LOGTASK_INTERVAL);
+	}
+}
+
+/*
+ *  VXeO^XNÌI¹
+ */
+void
+logtask_terminate(intptr_t exinf)
+{
+	char	c;
+	SYSLOG	logbuf;
+	bool_t	msgflg = false;
+	ER_UINT	rercd;
+
+	/*
+	 *  VAC^tF[XhCoÌMobt@É~Ï³ê½f[^
+	 *  ðCáxoÍ@\ðp¢ÄoÍ·éD
+	 */
+	while (serial_get_chr(logtask_portid, &c)) {
+		target_fput_log(c);
+	}
+
+	/*
+	 *  Oobt@ÉL^³ê½OîñðCáxoÍ@\ðp¢Äo
+	 *  Í·éD
+	 */
+	while ((rercd = syslog_rea_log(&logbuf)) >= 0) {
+		if (!msgflg) {
+			/*
+			 *  Oobt@ÉcÁ½OîñÅ é±Æð¦·¶ñðo
+			 *  Í·éD
+			 */
+			syslog_printf("-- buffered messages --\n", NULL, target_fput_log);
+			msgflg = true;
+		}
+		if (rercd > 0) {
+			syslog_lostmsg((uint_t) rercd, target_fput_log);
+		}
+		if (logbuf.logtype >= LOG_TYPE_COMMENT) {
+			syslog_print(&logbuf, target_fput_log);
+			target_fput_log('\n');
+		}
+	}
+}
Index: UsbWattMeter/trunk/asp_dcre/syssvc/logtask.cfg
===================================================================
--- UsbWattMeter/trunk/asp_dcre/syssvc/logtask.cfg	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/syssvc/logtask.cfg	(revision 164)
@@ -0,0 +1,13 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *		VXeO^XNÌRtBM
+[Vt@C
+ */
+
+#include "syssvc/logtask.h"
+CRE_TSK(LOGTASK, { TA_ACT, LOGTASK_PORTID, logtask_main,
+						LOGTASK_PRIORITY, LOGTASK_STACK_SIZE, NULL });
+ATT_TER({ TA_NULL, 0, logtask_terminate });
Index: UsbWattMeter/trunk/asp_dcre/syssvc/logtask.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/syssvc/logtask.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/syssvc/logtask.h	(revision 164)
@@ -0,0 +1,106 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2008 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		VXeO^XN
+ */
+
+#ifndef TOPPERS_LOGTASK_H
+#define TOPPERS_LOGTASK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "target_syssvc.h"
+
+/*
+ *  VXeO^XNÖAÌèÌftHglÌè`
+ */ 
+#ifndef LOGTASK_PRIORITY
+#define LOGTASK_PRIORITY	3		/* úDæx */
+#endif /* LOGTASK_PRIORITY */
+
+#ifndef LOGTASK_STACK_SIZE
+#define LOGTASK_STACK_SIZE	1024	/* X^bNÌæÌTCY */
+#endif /* LOGTASK_STACK_SIZE */
+
+#ifndef LOGTASK_PORTID
+#define LOGTASK_PORTID		1		/* VXeOpÌVA|[gÔ */
+#endif /* LOGTASK_PORTID */
+
+#ifndef LOGTASK_INTERVAL
+#define LOGTASK_INTERVAL	10U		/* VXeO^XNÌ®ìÔui~bj*/
+#endif /* LOGTASK_INTERVAL */
+
+#ifndef LOGTASK_FLUSH_WAIT
+#define LOGTASK_FLUSH_WAIT	1U		/* tbV
+Ò¿ÌPÊÔi~bj*/
+#endif /* LOGTASK_FLUSH_WAIT */
+
+/*
+ *  VXeOoÍÌÒ¿í¹
+ *
+ *  Oobt@ÌOÌªcountÈºÉÈéÜÅÒÂDcountª0ÌêÉ
+ *  ÍCVAobt@ªóÉÈéÌàÒÂD
+ */
+extern ER	logtask_flush(uint_t count) throw();
+
+/*
+ *  VXeO^XNÌ{Ì
+ */
+extern void	logtask_main(intptr_t exinf) throw();
+
+/*
+ *  VXeO^XNÌI¹
+ */
+extern void	logtask_terminate(intptr_t exinf) throw();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_LOGTASK_H */
Index: UsbWattMeter/trunk/asp_dcre/syssvc/serial.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/syssvc/serial.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/syssvc/serial.c	(revision 164)
@@ -0,0 +1,820 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2006-2013 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		VAC^tF[XhCo
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "target_syssvc.h"
+#include "target_serial.h"
+#include "serial.h"
+#include "kernel_cfg.h"
+
+/*
+ *  obt@TCYÌftHglÆobt@Ìè`
+ */
+#ifndef SERIAL_RCV_BUFSZ1
+#define	SERIAL_RCV_BUFSZ1	256			/* |[g1ÌóMobt@TCY */
+#endif /* SERIAL_RCV_BUFSZ1 */
+
+#ifndef SERIAL_SND_BUFSZ1
+#define	SERIAL_SND_BUFSZ1	256			/* |[g1ÌMobt@TCY */
+#endif /* SERIAL_SND_BUFSZ1 */
+
+static char	rcv_buffer1[SERIAL_RCV_BUFSZ1];
+static char	snd_buffer1[SERIAL_SND_BUFSZ1];
+
+#if TNUM_PORT >= 2						/* |[g2ÉÖ·éè` */
+
+#ifndef SERIAL_RCV_BUFSZ2
+#define	SERIAL_RCV_BUFSZ2	256			/* |[g2ÌóMobt@TCY */
+#endif /* SERIAL_RCV_BUFSZ2 */
+
+#ifndef SERIAL_SND_BUFSZ2
+#define	SERIAL_SND_BUFSZ2	256			/* |[g2ÌMobt@TCY */
+#endif /* SERIAL_SND_BUFSZ2 */
+
+static char	rcv_buffer2[SERIAL_RCV_BUFSZ2];
+static char	snd_buffer2[SERIAL_SND_BUFSZ2];
+
+#endif /* TNUM_PORT >= 2 */
+
+#if TNUM_PORT >= 3						/* |[g3ÉÖ·éè` */
+
+#ifndef SERIAL_RCV_BUFSZ3
+#define	SERIAL_RCV_BUFSZ3	256			/* |[g3ÌóMobt@TCY */
+#endif /* SERIAL_RCV_BUFSZ3 */
+
+#ifndef SERIAL_SND_BUFSZ3
+#define	SERIAL_SND_BUFSZ3	256			/* |[g3ÌMobt@TCY */
+#endif /* SERIAL_SND_BUFSZ3 */
+
+static char	rcv_buffer3[SERIAL_RCV_BUFSZ3];
+static char	snd_buffer3[SERIAL_SND_BUFSZ3];
+
+#endif /* TNUM_PORT >= 3 */
+
+#if TNUM_PORT >= 4						/* |[g4ÉÖ·éè` */
+
+#ifndef SERIAL_RCV_BUFSZ4
+#define	SERIAL_RCV_BUFSZ4	256			/* |[g4ÌóMobt@TCY */
+#endif /* SERIAL_RCV_BUFSZ4 */
+
+#ifndef SERIAL_SND_BUFSZ4
+#define	SERIAL_SND_BUFSZ4	256			/* |[g4ÌMobt@TCY */
+#endif /* SERIAL_SND_BUFSZ4 */
+
+static char	rcv_buffer4[SERIAL_RCV_BUFSZ4];
+static char	snd_buffer4[SERIAL_SND_BUFSZ4];
+
+#endif /* TNUM_PORT >= 4 */
+
+#if TNUM_PORT >= 5						/* |[g5ÉÖ·éè` */
+
+#ifndef SERIAL_RCV_BUFSZ5
+#define	SERIAL_RCV_BUFSZ5	256			/* |[g5ÌóMobt@TCY */
+#endif /* SERIAL_RCV_BUFSZ5 */
+
+#ifndef SERIAL_SND_BUFSZ5
+#define	SERIAL_SND_BUFSZ5	256			/* |[g5ÌMobt@TCY */
+#endif /* SERIAL_SND_BUFSZ5 */
+
+static char	rcv_buffer5[SERIAL_RCV_BUFSZ5];
+static char	snd_buffer5[SERIAL_SND_BUFSZ5];
+
+#endif /* TNUM_PORT >= 5 */
+
+#if TNUM_PORT >= 6						/* |[g6ÉÖ·éè` */
+
+#ifndef SERIAL_RCV_BUFSZ6
+#define	SERIAL_RCV_BUFSZ6	256			/* |[g6ÌóMobt@TCY */
+#endif /* SERIAL_RCV_BUFSZ6 */
+
+#ifndef SERIAL_SND_BUFSZ6
+#define	SERIAL_SND_BUFSZ6	256			/* |[g6ÌMobt@TCY */
+#endif /* SERIAL_SND_BUFSZ6 */
+
+static char	rcv_buffer6[SERIAL_RCV_BUFSZ6];
+static char	snd_buffer6[SERIAL_SND_BUFSZ6];
+
+#endif /* TNUM_PORT >= 6 */
+
+#if TNUM_PORT >= 7
+#error Serial interface driver supports up to 6 ports.
+#endif /* TNUM_PORT >= 7 */
+
+/*
+ *  t[§äÉÖA·éèÆ}N
+ */
+#define	FC_STOP			'\023'		/* Rg[-S */
+#define	FC_START		'\021'		/* Rg[-Q */
+
+#define BUFCNT_STOP(bufsz)		((bufsz) * 3 / 4)	/* STOPðéî¶ */
+#define BUFCNT_START(bufsz)		((bufsz) / 2)		/* STARTðéî¶ */
+
+/*
+ *  VA|[gú»ubN
+ */
+typedef struct serial_port_initialization_block {
+	ID		rcv_semid;		/* óMobt@ÇpZ}tHÌID */
+	ID		snd_semid;		/* Mobt@ÇpZ}tHÌID */
+	uint_t	rcv_bufsz;		/* óMobt@TCY */
+	char	*rcv_buffer;	/* óMobt@ */
+	uint_t	snd_bufsz;		/* Mobt@TCY */
+	char	*snd_buffer;	/* Mobt@ */
+} SPINIB;
+
+static const SPINIB spinib_table[TNUM_PORT] = {
+	{ SERIAL_RCV_SEM1, SERIAL_SND_SEM1,
+	  SERIAL_RCV_BUFSZ1, rcv_buffer1,
+	  SERIAL_SND_BUFSZ1, snd_buffer1 },
+#if TNUM_PORT >= 2
+	{ SERIAL_RCV_SEM2, SERIAL_SND_SEM2,
+	  SERIAL_RCV_BUFSZ2, rcv_buffer2,
+	  SERIAL_SND_BUFSZ2, snd_buffer2 },
+#endif /* TNUM_PORT >= 2 */
+#if TNUM_PORT >= 3
+	{ SERIAL_RCV_SEM3, SERIAL_SND_SEM3,
+	  SERIAL_RCV_BUFSZ3, rcv_buffer3,
+	  SERIAL_SND_BUFSZ3, snd_buffer3 },
+#endif /* TNUM_PORT >= 3 */
+#if TNUM_PORT >= 4
+	{ SERIAL_RCV_SEM4, SERIAL_SND_SEM4,
+	  SERIAL_RCV_BUFSZ4, rcv_buffer4,
+	  SERIAL_SND_BUFSZ4, snd_buffer4 },
+#endif /* TNUM_PORT >= 4 */
+};
+
+/*
+ *  VA|[gÇubN
+ */
+typedef struct serial_port_control_block {
+	const SPINIB *p_spinib;		/* VA|[gú»ubN */
+	SIOPCB	*p_siopcb;			/* VAI/O|[gÇubN */
+	bool_t	openflag;			/* I[vÏÝtO */
+	bool_t	errorflag;			/* G[tO */
+	uint_t	ioctl;				/* ®ì§äÌÝèl */
+
+	uint_t	rcv_read_ptr;		/* óMobt@Çoµ|C^ */
+	uint_t	rcv_write_ptr;		/* óMobt@Ý|C^ */
+	uint_t	rcv_count;			/* óMobt@Ì¶ */
+	char	rcv_fc_chr;			/* é×«START/STOP */
+	bool_t	rcv_stopped;		/* STOPðÁ½óÔ©H */
+
+	uint_t	snd_read_ptr;		/* Mobt@Çoµ|C^ */
+	uint_t	snd_write_ptr;		/* Mobt@Ý|C^ */
+	uint_t	snd_count;			/* Mobt@Ì¶ */
+	bool_t	snd_stopped;		/* STOPðó¯æÁ½óÔ©H */
+} SPCB;
+
+static SPCB	spcb_table[TNUM_PORT];
+
+/*
+ *  VA|[gID©çVA|[gÇubNðæèo·½ßÌ}N
+ */
+#define INDEX_PORT(portid)	((uint_t)((portid) - 1))
+#define get_spcb(portid)	(&(spcb_table[INDEX_PORT(portid)]))
+
+/*
+ *  |C^ÌCNg
+ */
+#define INC_PTR(ptr, bufsz) do {	\
+	if (++(ptr) == (bufsz)) {		\
+		(ptr) = 0;					\
+	}								\
+} while(false)
+
+/*
+ *  T[rXR[Äoµ}N
+ *
+ *  T[rXR[ÄoµðÜÞ®expð]¿µCÔlªG[iÌljÌê
+ *  ÉÍCercÉercd_expð]¿µ½lðãüµCerror_exitÉgoto·éD
+ */
+#define SVC(exp, ercd_exp) do {		\
+	if ((exp) < 0) {				\
+		ercd = (ercd_exp);			\
+		goto error_exit;			\
+	}								\
+} while(false)
+
+/*
+ *  E_SYSG[Ì¶¬
+ */
+static ER
+gen_ercd_sys(SPCB *p_spcb)
+{
+	p_spcb->errorflag = true;
+	return(E_SYS);
+}
+
+/*
+ *  Ò¿ÉüéT[rXR[©çÌG[ÌÏ·
+ */
+static ER
+gen_ercd_wait(ER rercd, SPCB *p_spcb)
+{
+	switch (MERCD(rercd)) {
+	case E_RLWAI:
+	case E_DLT:
+		return(rercd);
+	default:
+		p_spcb->errorflag = true;
+		return(E_SYS);
+	}
+}
+
+/*
+ *  VAC^tF[XhCoÌú»[`
+ */
+void
+serial_initialize(intptr_t exinf)
+{
+	uint_t	i;
+	SPCB	*p_spcb;
+
+	for (i = 0; i < TNUM_PORT; i++) {
+		p_spcb = &(spcb_table[i]);
+		p_spcb->p_spinib = &(spinib_table[i]);
+		p_spcb->openflag = false;
+	}
+}
+
+/*
+ *  VA|[gÌI[viT[rXR[j
+ */
+ER
+serial_opn_por(ID portid)
+{
+	SPCB	*p_spcb;
+	ER		ercd;
+
+	if (sns_dpn()) {				/* ReLXgÌ`FbN */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= TNUM_PORT)) {
+		return(E_ID);				/* |[gÔÌ`FbN */
+	}
+	p_spcb = get_spcb(portid);
+
+	SVC(dis_dsp(), gen_ercd_sys(p_spcb));
+	if (p_spcb->openflag) {			/* I[vÏÝ©Ì`FbN */
+		ercd = E_OBJ;
+	}
+	else {
+		/*
+		 *  ÏÌú»
+		 */
+		p_spcb->ioctl = (IOCTL_ECHO | IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV);
+
+		p_spcb->rcv_read_ptr = 0U;
+		p_spcb->rcv_write_ptr = 0U;
+		p_spcb->rcv_count = 0U;
+		p_spcb->rcv_fc_chr = '\0';
+		p_spcb->rcv_stopped = false;
+
+		p_spcb->snd_read_ptr = 0U;
+		p_spcb->snd_write_ptr = 0U;
+		p_spcb->snd_count = 0U;
+		p_spcb->snd_stopped = false;
+
+		/*
+		 *  ±êÈ~CÝðÖ~·éD
+		 */
+		if (loc_cpu() < 0) {
+			ercd = E_SYS;
+			goto error_exit_enadsp;
+		}
+
+		/*
+		 *  n[hEFAË¶ÌI[v
+		 */
+		p_spcb->p_siopcb = sio_opn_por(portid, (intptr_t) p_spcb);
+
+		/*
+		 *  óMÊmR[obNðÂ·éD
+		 */
+		sio_ena_cbr(p_spcb->p_siopcb, SIO_RDY_RCV);
+		p_spcb->openflag = true;
+		p_spcb->errorflag = false;
+
+		if (unl_cpu() < 0) {
+			p_spcb->errorflag = true;
+			ercd = E_SYS;
+			goto error_exit_enadsp;
+		}
+		ercd = E_OK;
+	}
+
+  error_exit_enadsp:
+	SVC(ena_dsp(), gen_ercd_sys(p_spcb));
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  VA|[gÌN[YiT[rXR[j
+ */
+ER
+serial_cls_por(ID portid)
+{
+	SPCB	*p_spcb;
+	ER		ercd;
+	bool_t	eflag = false;
+
+	if (sns_dpn()) {				/* ReLXgÌ`FbN */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= TNUM_PORT)) {
+		return(E_ID);				/* |[gÔÌ`FbN */
+	}
+	p_spcb = get_spcb(portid);
+
+	SVC(dis_dsp(), gen_ercd_sys(p_spcb));
+	if (!(p_spcb->openflag)) {		/* I[vÏÝ©Ì`FbN */
+		ercd = E_OBJ;
+	}
+	else {
+		/*
+		 *  n[hEFAË¶ÌN[Y
+		 */
+		if (loc_cpu() < 0) {
+			eflag = true;
+		}
+		sio_cls_por(p_spcb->p_siopcb);
+		p_spcb->openflag = false;
+		if (unl_cpu() < 0) {
+			eflag = true;
+		}
+
+		/*
+		 *  Z}tHÌú»
+		 */
+		if (ini_sem(p_spcb->p_spinib->snd_semid) < 0) {
+			eflag = true;
+		}
+		if (ini_sem(p_spcb->p_spinib->rcv_semid) < 0) {
+			eflag = true;
+		}
+
+		/*
+		 *  G[R[hÌÝè
+		 */
+		if (eflag) {
+			ercd = gen_ercd_sys(p_spcb);
+		}
+		else {
+			ercd = E_OK;
+		}
+	}
+	SVC(ena_dsp(), gen_ercd_sys(p_spcb));
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  VA|[gÖÌ¶M
+ *
+ *  p_spcbÅwè³êéVAI/O|[gÉÎµÄC¶cðM·éD¶
+ *  ðMWX^É¢ê½êÉÍtrueðÔ·D»¤ÅÈ¢êÉÍCM
+ *  WX^ªó¢½±ÆðÊm·éR[obNÖðÂµCfalseðÔ·D
+ *  ±ÌÖÍCCPUbNóÔÅÄÑo³êéD
+ */
+Inline bool_t
+serial_snd_chr(SPCB *p_spcb, char c)
+{
+	if (sio_snd_chr(p_spcb->p_siopcb, c)) {
+		return(true);
+	}
+	else {
+		sio_ena_cbr(p_spcb->p_siopcb, SIO_RDY_SND);
+		return(false);
+	}
+}
+
+/*
+ *  VA|[gÖÌ1¶M
+ */
+static ER_BOOL
+serial_wri_chr(SPCB *p_spcb, char c)
+{
+	bool_t	buffer_full;
+	ER		ercd, rercd;
+
+	/*
+	 *  LFÌOÉCRðM·éD
+	 */
+	if (c == '\n' && (p_spcb->ioctl & IOCTL_CRLF) != 0U) {
+		/*
+		 *  ÈºÌR[hÍÄAÄoµÉÈÁÄ¢éªCøcª'\n'ÌêÉ
+		 *  øcð'\r'ÆµÄÄÑo·±Æ©çC±ÌÄAÄoµÍ2ñÚÌ
+		 *  ÄÑoµÅK¸~ÜéD
+		 */
+		SVC(rercd = serial_wri_chr(p_spcb, '\r'), rercd);
+		if ((bool_t) rercd) {
+			SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
+										gen_ercd_wait(rercd, p_spcb));
+		}
+	}
+
+	SVC(loc_cpu(), gen_ercd_sys(p_spcb));
+	if (p_spcb->snd_count == 0U && !(p_spcb->snd_stopped)
+								&& serial_snd_chr(p_spcb, c)) {
+		/*
+		 *  VAI/OfoCXÌMWX^É¶ðüêé±ÆÉ¬÷µ
+		 *  ½êD
+		 */
+		buffer_full = false;
+	}
+	else {
+		/*
+		 *  Mobt@É¶ðüêéD
+		 */
+		p_spcb->p_spinib->snd_buffer[p_spcb->snd_write_ptr] = c;
+		INC_PTR(p_spcb->snd_write_ptr, p_spcb->p_spinib->snd_bufsz);
+		p_spcb->snd_count++;
+		buffer_full = (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz);
+	}
+
+	SVC(unl_cpu(), gen_ercd_sys(p_spcb));
+	ercd = (ER_BOOL) buffer_full;
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  VA|[gÖÌ¶ñMiT[rXR[j
+ */
+ER_UINT
+serial_wri_dat(ID portid, const char *buf, uint_t len)
+{
+	SPCB	*p_spcb;
+	bool_t	buffer_full;
+	uint_t	wricnt = 0U;
+	ER		ercd, rercd;
+
+	if (sns_dpn()) {				/* ReLXgÌ`FbN */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= TNUM_PORT)) {
+		return(E_ID);				/* |[gÔÌ`FbN */
+	}
+
+	p_spcb = get_spcb(portid);
+	if (!(p_spcb->openflag)) {		/* I[vÏÝ©Ì`FbN */
+		return(E_OBJ);
+	}
+	if (p_spcb->errorflag) {		/* G[óÔ©Ì`FbN */
+		return(E_SYS);
+	}
+
+	buffer_full = true;				/* [vÌ1ñßÍwai_sem·é */
+	while (wricnt < len) {
+		if (buffer_full) {
+			SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
+										gen_ercd_wait(rercd, p_spcb));
+		}
+		SVC(rercd = serial_wri_chr(p_spcb, *buf++), rercd);
+		wricnt++;
+		buffer_full = (bool_t) rercd;
+	}
+	if (!buffer_full) {
+		SVC(sig_sem(p_spcb->p_spinib->snd_semid), gen_ercd_sys(p_spcb));
+	}
+	ercd = E_OK;
+
+  error_exit:
+	return(wricnt > 0U ? (ER_UINT) wricnt : ercd);
+}
+
+/*
+ *  VA|[g©çÌ1¶óM
+ */
+static bool_t
+serial_rea_chr(SPCB *p_spcb, char *p_c)
+{
+	bool_t	buffer_empty;
+	ER		ercd;
+
+	SVC(loc_cpu(), gen_ercd_sys(p_spcb));
+
+	/*
+	 *  óMobt@©ç¶ðæèo·D
+	 */
+	*p_c = p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_read_ptr];
+	INC_PTR(p_spcb->rcv_read_ptr, p_spcb->p_spinib->rcv_bufsz);
+	p_spcb->rcv_count--;
+	buffer_empty = (p_spcb->rcv_count == 0U);
+
+	/*
+	 *  STARTðM·éD
+	 */
+	if (p_spcb->rcv_stopped && p_spcb->rcv_count
+								<= BUFCNT_START(p_spcb->p_spinib->rcv_bufsz)) {
+		if (!serial_snd_chr(p_spcb, FC_START)) {
+			p_spcb->rcv_fc_chr = FC_START;
+		}
+		p_spcb->rcv_stopped = false;
+	}
+
+	SVC(unl_cpu(), gen_ercd_sys(p_spcb));
+	ercd = (ER_BOOL) buffer_empty;
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  VA|[g©çÌ¶ñóMiT[rXR[j
+ */
+ER_UINT
+serial_rea_dat(ID portid, char *buf, uint_t len)
+{
+	SPCB	*p_spcb;
+	bool_t	buffer_empty;
+	uint_t	reacnt = 0U;
+	char	c = '\0';		/* RpCÌxð}~·é½ßÉú»·é */
+	ER		ercd, rercd;
+
+	if (sns_dpn()) {				/* ReLXgÌ`FbN */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= TNUM_PORT)) {
+		return(E_ID);				/* |[gÔÌ`FbN */
+	}
+
+	p_spcb = get_spcb(portid);
+	if (!(p_spcb->openflag)) {		/* I[vÏÝ©Ì`FbN */
+		return(E_OBJ);
+	}
+	if (p_spcb->errorflag) {		/* G[óÔ©Ì`FbN */
+		return(E_SYS);
+	}
+
+	buffer_empty = true;			/* [vÌ1ñßÍwai_sem·é */
+	while (reacnt < len) {
+		if (buffer_empty) {
+			SVC(rercd = wai_sem(p_spcb->p_spinib->rcv_semid),
+										gen_ercd_wait(rercd, p_spcb));
+		}
+		SVC(rercd = serial_rea_chr(p_spcb, &c), rercd);
+		*buf++ = c;
+		reacnt++;
+		buffer_empty = (bool_t) rercd;
+
+		/*
+		 *  GR[obND
+		 */
+		if ((p_spcb->ioctl & IOCTL_ECHO) != 0U) {
+			SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
+										gen_ercd_wait(rercd, p_spcb));
+			SVC(rercd = serial_wri_chr(p_spcb, c), rercd);
+			if (!((bool_t) rercd)) {
+				SVC(sig_sem(p_spcb->p_spinib->snd_semid),
+										gen_ercd_sys(p_spcb));
+			}
+		}
+	}
+	if (!buffer_empty) {
+		SVC(sig_sem(p_spcb->p_spinib->rcv_semid), gen_ercd_sys(p_spcb));
+	}
+	ercd = E_OK;
+
+  error_exit:
+	return(reacnt > 0U ? (ER_UINT) reacnt : ercd);
+}
+
+/*
+ *  VA|[gÌ§äiT[rXR[j
+ */
+ER
+serial_ctl_por(ID portid, uint_t ioctl)
+{
+	SPCB	*p_spcb;
+
+	if (sns_dpn()) {				/* ReLXgÌ`FbN */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= TNUM_PORT)) {
+		return(E_ID);				/* |[gÔÌ`FbN */
+	}
+
+	p_spcb = get_spcb(portid);
+	if (!(p_spcb->openflag)) {		/* I[vÏÝ©Ì`FbN */
+		return(E_OBJ);
+	}
+	if (p_spcb->errorflag) {		/* G[óÔ©Ì`FbN */
+		return(E_SYS);
+	}
+
+	p_spcb->ioctl = ioctl;
+	return(E_OK);
+}
+
+/*
+ *  VA|[góÔÌQÆiT[rXR[j
+ */
+ER
+serial_ref_por(ID portid, T_SERIAL_RPOR *pk_rpor)
+{
+	SPCB	*p_spcb;
+
+	if (sns_dpn()) {				/* ReLXgÌ`FbN */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= TNUM_PORT)) {
+		return(E_ID);				/* |[gÔÌ`FbN */
+	}
+
+	p_spcb = get_spcb(portid);
+	if (!(p_spcb->openflag)) {		/* I[vÏÝ©Ì`FbN */
+		return(E_OBJ);
+	}
+	if (p_spcb->errorflag) {		/* G[óÔ©Ì`FbN */
+		return(E_SYS);
+	}
+
+	pk_rpor->reacnt = p_spcb->rcv_count;
+	pk_rpor->wricnt = p_spcb->snd_count;
+	return(E_OK);
+}
+
+/*
+ *  VA|[g©çÌMÂ\R[obN
+ */
+void
+sio_irdy_snd(intptr_t exinf)
+{
+	SPCB	*p_spcb;
+
+	p_spcb = (SPCB *) exinf;
+	if (p_spcb->rcv_fc_chr != '\0') {
+		/*
+		 *  START/STOP ðM·éD
+		 */
+		(void) sio_snd_chr(p_spcb->p_siopcb, p_spcb->rcv_fc_chr);
+		p_spcb->rcv_fc_chr = '\0';
+	}
+	else if (!(p_spcb->snd_stopped) && p_spcb->snd_count > 0U) {
+		/*
+		 *  Mobt@©ç¶ðæèoµÄM·éD
+		 */
+		(void) sio_snd_chr(p_spcb->p_siopcb,
+					p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr]);
+		INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
+		if (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz) {
+			if (isig_sem(p_spcb->p_spinib->snd_semid) < 0) {
+				p_spcb->errorflag = true;
+			}
+		}
+		p_spcb->snd_count--;
+	}
+	else {
+		/*
+		 *  M·×«¶ªÈ¢êÍCMÂ\R[obNðÖ~·éD
+		 */
+		sio_dis_cbr(p_spcb->p_siopcb, SIO_RDY_SND);
+	}
+}
+
+/*
+ *  VA|[g©çÌóMÊmR[obN
+ */
+void
+sio_irdy_rcv(intptr_t exinf)
+{
+	SPCB	*p_spcb;
+	char	c;
+
+	p_spcb = (SPCB *) exinf;
+	c = (char) sio_rcv_chr(p_spcb->p_siopcb);
+	if ((p_spcb->ioctl & IOCTL_FCSND) != 0U && c == FC_STOP) {
+		/*
+		 *  Mðêâ~·éDMÌ¶Í»ÌÜÜM·éD
+		 */
+		p_spcb->snd_stopped = true;
+	}
+	else if (p_spcb->snd_stopped && (c == FC_START
+				|| (p_spcb->ioctl & IOCTL_FCANY) != 0U)) {
+		/*
+		 *  MðÄJ·éD
+		 */
+		p_spcb->snd_stopped = false;
+		if (p_spcb->snd_count > 0U) {
+			c = p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr];
+			if (serial_snd_chr(p_spcb, c)) {
+				INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
+				if (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz) {
+					if (isig_sem(p_spcb->p_spinib->snd_semid) < 0) {
+						p_spcb->errorflag = true;
+					}
+				}
+				p_spcb->snd_count--;
+			}
+		}
+	}
+	else if ((p_spcb->ioctl & IOCTL_FCSND) != 0U && c == FC_START) {
+		/*
+		 *  MÉÎµÄt[§äµÄ¢éêCSTART ÍÌÄéD
+		 */
+	}
+	else if (p_spcb->rcv_count == p_spcb->p_spinib->rcv_bufsz) {
+		/*
+		 *  obt@tÌêCóMµ½¶ðÌÄéD
+		 */
+	}
+	else {
+		/*
+		 *  óMµ½¶ðóMobt@ÉüêéD
+		 */
+		p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_write_ptr] = c;
+		INC_PTR(p_spcb->rcv_write_ptr, p_spcb->p_spinib->rcv_bufsz);
+		if (p_spcb->rcv_count == 0U) {
+			if (isig_sem(p_spcb->p_spinib->rcv_semid) < 0) {
+				p_spcb->errorflag = true;
+			}
+		}
+		p_spcb->rcv_count++;
+
+		/*
+		 *  STOPðM·éD
+		 */
+		if ((p_spcb->ioctl & IOCTL_FCRCV) != 0U && !(p_spcb->rcv_stopped)
+						&& p_spcb->rcv_count
+							>= BUFCNT_STOP(p_spcb->p_spinib->rcv_bufsz)) {
+			if (!serial_snd_chr(p_spcb, FC_STOP)) {
+				p_spcb->rcv_fc_chr = FC_STOP;
+			}
+			p_spcb->rcv_stopped = true;
+		}
+	}
+}
+
+/*
+ *  VAC^tF[XhCo©çÌ¢M¶Ìæoµ
+ */
+bool_t
+serial_get_chr(ID portid, char *p_c)
+{
+	SPCB	*p_spcb;
+
+	if (1 <= portid && portid <= TNUM_PORT) {	/* |[gÔÌ`FbN */
+		p_spcb = get_spcb(portid);
+		if (p_spcb->openflag) {					/* I[vÏÝ©Ì`FbN */
+			if (p_spcb->snd_count > 0U) {
+				*p_c = p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr];
+				INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
+				p_spcb->snd_count--;
+				return(true);
+			}
+		}
+	}
+	return(false);
+}
Index: UsbWattMeter/trunk/asp_dcre/syssvc/serial.cfg
===================================================================
--- UsbWattMeter/trunk/asp_dcre/syssvc/serial.cfg	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/syssvc/serial.cfg	(revision 164)
@@ -0,0 +1,29 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  VAC^tF[XhCoÌRtBM
+[Vt@C
+ */
+
+#include "target_syssvc.h"
+INCLUDE("target_serial.cfg");
+
+#include "syssvc/serial.h"
+ATT_INI({ TA_NULL, 0, serial_initialize });
+
+CRE_SEM(SERIAL_RCV_SEM1, { TA_TPRI, 0, 1 });
+CRE_SEM(SERIAL_SND_SEM1, { TA_TPRI, 1, 1 });
+#if TNUM_PORT >= 2
+CRE_SEM(SERIAL_RCV_SEM2, { TA_TPRI, 0, 1 });
+CRE_SEM(SERIAL_SND_SEM2, { TA_TPRI, 1, 1 });
+#endif /* TNUM_PORT >= 2 */
+#if TNUM_PORT >= 3
+CRE_SEM(SERIAL_RCV_SEM3, { TA_TPRI, 0, 1 });
+CRE_SEM(SERIAL_SND_SEM3, { TA_TPRI, 1, 1 });
+#endif /* TNUM_PORT >= 3 */
+#if TNUM_PORT >= 4
+CRE_SEM(SERIAL_RCV_SEM4, { TA_TPRI, 0, 1 });
+CRE_SEM(SERIAL_SND_SEM4, { TA_TPRI, 1, 1 });
+#endif /* TNUM_PORT >= 4 */
Index: UsbWattMeter/trunk/asp_dcre/syssvc/serial.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/syssvc/serial.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/syssvc/serial.h	(revision 164)
@@ -0,0 +1,102 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2011 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		VAC^tF[XhCo
+ */
+
+#ifndef TOPPERS_SERIAL_H
+#define TOPPERS_SERIAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  VAC^tF[XhCoÌp¢épPbg
+ */
+typedef struct {
+	uint_t		reacnt;			/* óMobt@Ì¶ */
+	uint_t		wricnt;			/* Mobt@Ì¶ */
+} T_SERIAL_RPOR;
+
+/*
+ *  VAC^tF[XhCoÌú»[`
+ */
+extern void		serial_initialize(intptr_t exinf) throw();
+
+/*
+ *  VAC^tF[XhCo©çÌ¢M¶Ìæoµ
+ */
+extern bool_t	serial_get_chr(ID portid, char *p_c) throw();
+
+/*
+ *  VAC^tF[XhCoÌT[rXR[
+ */
+extern ER		serial_opn_por(ID portid) throw();
+extern ER		serial_cls_por(ID portid) throw();
+extern ER_UINT	serial_rea_dat(ID portid, char *buf, uint_t len) throw();
+extern ER_UINT	serial_wri_dat(ID portid, const char *buf, uint_t len) throw();
+extern ER		serial_ctl_por(ID portid, uint_t ioctl) throw();
+extern ER		serial_ref_por(ID portid, T_SERIAL_RPOR *pk_rpor) throw();
+
+/*
+ *  VAC^tF[XhCoÌ®ì§äpÌ½ßÌè
+ *
+ *  ÈºÌèÍCrbgÉ_aðÆÁÄp¢éD
+ */
+#define	IOCTL_NULL	0U			/* wèÈµ */
+#define	IOCTL_ECHO	0x0001U		/* óMµ½¶ðGR[obN */
+#define	IOCTL_CRLF	0x0010U		/* LFðM·éOÉCRðtÁ */
+#define	IOCTL_FCSND	0x0100U		/* MÉÎµÄt[§äðs¤ */
+#define	IOCTL_FCANY	0x0200U		/* ÇÌæ¤È¶ÅàMÄJ */
+#define	IOCTL_FCRCV	0x0400U		/* óMÉÎµÄt[§äðs¤ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_SERIAL_H */
Index: UsbWattMeter/trunk/asp_dcre/syssvc/syslog.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/syssvc/syslog.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/syssvc/syslog.c	(revision 164)
@@ -0,0 +1,247 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  $Id$
+ */
+
+/*
+ *		VXeO@\
+ */
+
+#include <sil.h>
+#undef TOPPERS_OMIT_SYSLOG
+#include <t_syslog.h>
+#include <log_output.h>
+#include "target_syssvc.h"
+#include "syslog.h"
+
+/*
+ *  g[XO}NÌftHgè`
+ */
+#ifndef LOG_SYSLOG_WRI_LOG_ENTER
+#define LOG_SYSLOG_WRI_LOG_ENTER(prio, p_syslog)
+#endif /* LOG_SYSLOG_WRI_LOG_ENTER */
+
+#ifndef LOG_SYSLOG_WRI_LOG_LEAVE
+#define LOG_SYSLOG_WRI_LOG_LEAVE(ercd)
+#endif /* LOG_SYSLOG_WRI_LOG_LEAVE */
+
+#ifndef LOG_SYSLOG_REA_LOG_ENTER
+#define LOG_SYSLOG_REA_LOG_ENTER(p_syslog)
+#endif /* LOG_SYSLOG_REA_LOG_ENTER */
+
+#ifndef LOG_SYSLOG_REA_LOG_LEAVE
+#define LOG_SYSLOG_REA_LOG_LEAVE(ercd, p_syslog)
+#endif /* LOG_SYSLOG_REA_LOG_LEAVE */
+
+#ifndef LOG_SYSLOG_MSK_LOG_ENTER
+#define LOG_SYSLOG_MSK_LOG_ENTER(logmask, lowmask)
+#endif /* LOG_SYSLOG_MSK_LOG_ENTER */
+
+#ifndef LOG_SYSLOG_MSK_LOG_LEAVE
+#define LOG_SYSLOG_MSK_LOG_LEAVE(ercd)
+#endif /* LOG_SYSLOG_MSK_LOG_LEAVE */
+
+#ifndef LOG_SYSLOG_REF_LOG_ENTER
+#define LOG_SYSLOG_REF_LOG_ENTER(pk_rlog)
+#endif /* LOG_SYSLOG_REF_LOG_ENTER */
+
+#ifndef LOG_SYSLOG_REF_LOG_LEAVE
+#define LOG_SYSLOG_REF_LOG_LEAVE(pk_rlog)
+#endif /* LOG_SYSLOG_REF_LOG_LEAVE */
+
+/*
+ *  »ÝÌVXe
+ *
+ *  Oðæèo·½ßÉCâÞÈ­CJ[lÌàÏðQÆµÄ¢
+ *  éD
+ */
+extern ulong_t	_kernel_current_time;
+
+/*
+ *  Oobt@Æ»êÉANZX·é½ßÌ|C^
+ */
+static SYSLOG	syslog_buffer[TCNT_SYSLOG_BUFFER];	/* Oobt@ */
+static uint_t	syslog_count;			/* Oobt@ÌOÌ */
+static uint_t	syslog_head;			/* æªÌOÌi[Êu */
+static uint_t	syslog_tail;			/* ÌOÌi[Êu */
+static uint_t	syslog_lost;			/* ¸íê½OÌ */
+
+/*
+ *  oÍ·×«OîñÌdvxirbg}bvj
+ */
+static uint_t	syslog_logmask;			/* Oobt@ÉL^·×«dvx */
+static uint_t	syslog_lowmask_not;		/* áxoÍ·×«dvxi½]j*/
+
+/*
+ *  VXeO@\Ìú»
+ */
+void
+syslog_initialize(intptr_t exinf)
+{
+	syslog_count = 0U;
+	syslog_head = 0U;
+	syslog_tail = 0U;
+	syslog_lost = 0U;
+	syslog_logmask = 0U;
+	syslog_lowmask_not = 0U;
+}     
+
+/* 
+ *  OîñÌoÍ
+ *
+ *  CPUbNóÔâÀsReLXgÉæç¸®ìÅ«éæ¤ÉÀµÄ éD
+ */
+ER
+syslog_wri_log(uint_t prio, const SYSLOG *p_syslog)
+{
+	SIL_PRE_LOC;
+
+	LOG_SYSLOG_WRI_LOG_ENTER(prio, p_syslog);
+	SIL_LOC_INT();
+
+	/*
+	 *  OÌÝè
+	 */
+	((SYSLOG *) p_syslog)->logtim = _kernel_current_time;
+
+	/*
+	 *  Oobt@ÉL^
+	 */
+	if ((syslog_logmask & LOG_MASK(prio)) != 0U) {
+		syslog_buffer[syslog_tail] = *p_syslog;
+		syslog_tail++;
+		if (syslog_tail >= TCNT_SYSLOG_BUFFER) {
+			syslog_tail = 0U;
+		}
+		if (syslog_count < TCNT_SYSLOG_BUFFER) {
+			syslog_count++;
+		}
+		else {
+			syslog_head = syslog_tail;
+			syslog_lost++;
+		}
+	}
+
+	/*
+	 *  áxoÍ
+	 */
+	if (((~syslog_lowmask_not) & LOG_MASK(prio)) != 0U) {
+		syslog_print(p_syslog, target_fput_log);
+		target_fput_log('\n');
+	}
+
+	SIL_UNL_INT();
+	LOG_SYSLOG_WRI_LOG_LEAVE(E_OK);
+	return(E_OK);
+}
+
+/*
+ *  Oobt@©çÌÇoµ
+ *
+ *  CPUbNóÔâÀsReLXgÉæç¸®ìÅ«éæ¤ÉÀµÄ éD
+ */
+ER_UINT
+syslog_rea_log(SYSLOG *p_syslog)
+{
+	ER_UINT	ercd;
+	SIL_PRE_LOC;
+
+	LOG_SYSLOG_REA_LOG_ENTER(p_syslog);
+	SIL_LOC_INT();
+
+	/*
+	 *  Oobt@©çÌæoµ
+	 */
+	if (syslog_count > 0U) {
+		*p_syslog = syslog_buffer[syslog_head];
+		syslog_count--;
+		syslog_head++;
+		if (syslog_head >= TCNT_SYSLOG_BUFFER) {
+			syslog_head = 0U;
+		}
+		ercd = (ER_UINT) syslog_lost;
+		syslog_lost = 0U;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+
+	SIL_UNL_INT();
+	LOG_SYSLOG_REA_LOG_LEAVE(ercd, p_syslog);
+	return(ercd);
+}
+
+/* 
+ *  oÍ·×«OîñÌdvxÌÝè
+ */
+ER
+syslog_msk_log(uint_t logmask, uint_t lowmask)
+{
+	LOG_SYSLOG_MSK_LOG_ENTER(logmask, lowmask);
+	syslog_logmask = logmask;
+	syslog_lowmask_not = ~lowmask;
+	LOG_SYSLOG_MSK_LOG_LEAVE(E_OK);
+	return(E_OK);
+}
+
+/*
+ *  Oobt@ÌóÔQÆ
+ */
+ER
+syslog_ref_log(T_SYSLOG_RLOG *pk_rlog)
+{
+	SIL_PRE_LOC;
+
+	LOG_SYSLOG_REF_LOG_ENTER(pk_rlog);
+	SIL_LOC_INT();
+
+	pk_rlog->count = syslog_count;
+	pk_rlog->lost = syslog_lost;
+	pk_rlog->logmask = syslog_logmask;
+	pk_rlog->lowmask = ~syslog_lowmask_not;
+
+	SIL_UNL_INT();
+	LOG_SYSLOG_REF_LOG_LEAVE(pk_rlog);
+	return(E_OK);
+}
Index: UsbWattMeter/trunk/asp_dcre/syssvc/syslog.cfg
===================================================================
--- UsbWattMeter/trunk/asp_dcre/syssvc/syslog.cfg	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/syssvc/syslog.cfg	(revision 164)
@@ -0,0 +1,11 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *		VXeO@\ÌRtBM
+[Vt@C
+ */
+
+#include "syssvc/syslog.h"
+ATT_INI({ TA_NULL, 0, syslog_initialize });
Index: UsbWattMeter/trunk/asp_dcre/syssvc/syslog.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/syssvc/syslog.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/syssvc/syslog.h	(revision 164)
@@ -0,0 +1,99 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		VXeO@\
+ */
+
+#ifndef TOPPERS_SYSLOG_H
+#define TOPPERS_SYSLOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  VXeOoÍðs¤½ßÌè`
+ */
+#include <t_syslog.h>
+
+/*
+ *  Oobt@Æ»êÉANZX·é½ßÌ|C^
+ */
+#ifndef TCNT_SYSLOG_BUFFER
+#define TCNT_SYSLOG_BUFFER	32		/* Oobt@ÌTCY */
+#endif /* TCNT_SYSLOG_BUFFER */
+
+/*
+ *  VXeO@\Ìú»
+ */
+extern void	syslog_initialize(intptr_t exinf) throw();
+
+/*
+ *  OîñÌoÍ
+ */
+extern ER	syslog_wri_log(uint_t prio, const SYSLOG *p_syslog) throw();
+
+/*
+ *  Oobt@©çÌOîñÌÇoµ
+ */
+extern ER_UINT	syslog_rea_log(SYSLOG *p_syslog) throw();
+
+/* 
+ *  oÍ·×«OîñÌdvxÌÝè
+ */
+extern ER	syslog_msk_log(uint_t logmask, uint_t lowmask) throw();
+
+/* 
+ *  Oobt@ÌóÔQÆ
+ */
+extern ER	syslog_ref_log(T_SYSLOG_RLOG *pk_rlog) throw();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_SYSLOG_H */
Index: UsbWattMeter/trunk/asp_dcre/syssvc/vasyslog.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/syssvc/vasyslog.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/syssvc/vasyslog.c	(revision 164)
@@ -0,0 +1,111 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2008 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ÂÏøÌVXeOCu
+ */
+
+#include <t_stddef.h>
+#include <t_syslog.h>
+#include <stdarg.h>
+
+void
+syslog(uint_t prio, const char *format, ...)
+{
+	SYSLOG	syslog;
+	va_list	ap;
+	uint_t	i;
+	char	c;
+	bool_t	lflag;
+
+	syslog.logtype = LOG_TYPE_COMMENT;
+	syslog.loginfo[0] = (intptr_t) format;
+	i = 1U;
+	va_start(ap, format);
+
+	while ((c = *format++) != '\0' && i < TMAX_LOGINFO) {
+		if (c != '%') {
+			continue;
+		}
+
+		lflag = false;
+		c = *format++;
+		while ('0' <= c && c <= '9') {
+			c = *format++;
+		}
+		if (c == 'l') {
+			lflag = true;
+			c = *format++;
+		}
+		switch (c) {
+		case 'd':
+			syslog.loginfo[i++] = lflag ? (intptr_t) va_arg(ap, long_t)
+										: (intptr_t) va_arg(ap, int_t);
+			break;
+		case 'u':
+		case 'x':
+		case 'X':
+			syslog.loginfo[i++] = lflag ? (intptr_t) va_arg(ap, ulong_t)
+										: (intptr_t) va_arg(ap, uint_t);
+			break;
+		case 'p':
+			syslog.loginfo[i++] = (intptr_t) va_arg(ap, void *);
+			break;
+		case 'c':
+			syslog.loginfo[i++] = (intptr_t) va_arg(ap, int);
+			break;
+		case 's':
+			syslog.loginfo[i++] = (intptr_t) va_arg(ap, const char *);
+			break;
+		case '\0':
+			format--;
+			break;
+		default:
+			break;
+		}
+	}
+	va_end(ap);
+	(void) syslog_wri_log(prio, &syslog);
+}
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/E_PACKAGE
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/E_PACKAGE	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/E_PACKAGE	(revision 164)
@@ -0,0 +1,7 @@
+E_PACKAGE asp_grsakura_ccrx
+VERSION %date
+
+INCLUDE ../../MANIFEST
+INCLUDE ../../arch/rx630_ccrx/MANIFEST
+#INCLUDE ../../arch/ccrx/MANIFEST
+INCLUDE ../../cfg/MANIFEST
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/MANIFEST
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/MANIFEST	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/MANIFEST	(revision 164)
@@ -0,0 +1,34 @@
+PACKAGE asp_target_rsk_rx_hew
+
+E_PACKAGE
+MANIFEST
+asm_config.cfg
+grsakura.h
+sectrx.inc
+target.tf
+target_asm_config.tf
+target_ccrx_echonet.tf
+target_cfg1_out.h
+target_check.tf
+target_config.c
+target_config.h
+target_def.csv
+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: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/asm_config.cfg
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/asm_config.cfg	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/asm_config.cfg	(revision 164)
@@ -0,0 +1,8 @@
+/*
+ *  asm_config.inc ¶¬vWFNgpRtBM
+[Vt@C
+ *
+ *  RtBM
+[VÍsÈíÈ¢½ßót@CÆ·é.
+ */
+
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/grsakura.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/grsakura.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/grsakura.h	(revision 164)
@@ -0,0 +1,98 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/* GR-SAKURApwb_t@ */
+
+#ifndef	TOPPERS_GRSAKURA_H
+#define	TOPPERS_GRSAKURA_H
+
+
+/*
+ *  MCUË¶îñÌÇÝÝ
+ */
+#ifdef __RX
+#include "rx630_ccrx/rx630.h"
+#else
+#include "rx630_msvc/rx630.h"
+#endif
+
+/*
+ *  NbNÝè
+ */
+
+/*
+ *  VXeNbNICLK(kHz)
+ *
+ *  CPUCDTCCDMACACETHERCCEDMACCROMCRAMp
+ *  
+ */
+#define FREQ_ICLK  (96000U)
+
+/*
+ *  NbNPCLK(kHz)
+ *
+ *  ^C}CVAÈÇüÓW
+[p
+ */
+#define FREQ_PCLK  (48000U)
+
+
+/*
+ *  {[[gÝè
+ */
+#define BAUD_19200BPS		UINT_C( 78 )
+#define BAUD_38400BPS		UINT_C( 39 )
+#define BAUD_57600BPS		UINT_C( 25 )
+#define BAUD_115200BPS		UINT_C( 12 )
+
+#define UART_BAUDRATE		BAUD_38400BPS
+
+
+/*
+ *  NbN\[X
+ */
+#define UART_CLKSRC			CLK_F1
+
+#endif	/* TOPPERS_GRSAKURA_H */
+
+ 
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/sectrx.inc
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/sectrx.inc	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/sectrx.inc	(revision 164)
@@ -0,0 +1,134 @@
+;*
+;*  TOPPERS/ASP Kernel
+;*      Toyohashi Open Platform for Embedded Real-Time Systems/
+;*      Advanced Standard Profile Kernel
+;* 
+;*  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+;* 
+;*  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+;*  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+;*  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+;*  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+;*       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+;*      XR[hÉÜÜêÄ¢é±ÆD
+;*  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+;*      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+;*      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+;*      Ì³ÛØKèðfÚ·é±ÆD
+;*  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+;*      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+;*      ÆD
+;*    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+;*        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+;*    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+;*        ñ·é±ÆD
+;*  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+;*      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+;*      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+;*      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+;*      ÆÓ·é±ÆD
+;* 
+;*  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+;*  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+;*  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+;*  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+;*  ÌÓCðíÈ¢D
+;* 
+;*  @(#) $Id$
+;* 
+
+;
+;  ^[QbgVXeË¶ZNVè`t@C(X^[^[Lbgp)
+;
+
+;
+;  ZNVÌè`
+;
+;  ZNVÌAhXè`ÍHEWãÌÅK»JÌ
+;  IvVÉÄÀ{·é.
+;
+
+	;
+	;  úlLèf[^ÌæÌZNV
+	;
+	;  00000000h - 00020000h
+	;
+	.section	D, ROMDATA
+	.section	D_2, ROMDATA, ALIGN = 2
+	.section	D_1, ROMDATA
+
+
+	;
+	;  úl³µf[^ÌæÌZNV
+	;
+	;  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
+
+
+	;
+	;  J[lX^bNÌæÌZNV
+	;
+	;  00000000h - 00020000h
+	;
+	;  Èº.blkb½ßÅmÛµÄ¢éJ[lX^bNÌæÌTCYð
+	;  ÏX·éêÍ, target_config.hÌDEFAULT_ISTKSZÌlð, ¯¶
+	;  lÉÏX·é±Æ.
+	;
+	.section	SI, DATA, ALIGN = 4
+	.glb _DEFAULT_ISTACK
+_DEFAULT_ISTACK:
+	.blkb		0400H
+	.glb DEFAULT_ISTACK_TOP
+DEFAULT_ISTACK_TOP:
+
+	;
+	;  èÌæÌZNV
+	;
+	;  00100000h - 00107FFFh
+	;
+	.section	C, ROMDATA, ALIGN = 4
+	.section	C_2, ROMDATA, ALIGN = 2
+	.section	C_1, ROMDATA
+
+	;
+	;  úlLèf[^ÌæÌúl
+	;
+	;  00100000h - 00107FFFh
+	;
+	.section	R, DATA, ALIGN = 4
+	.section	R_2, DATA, ALIGN = 2
+	.section	R_1, DATA
+
+	;
+	;  ÂÏxN^e[uÌæÌZNV
+	;
+	;  00100000h - 00107FFFh
+	;
+	.section	C$VECT, ROMDATA, ALIGN = 4
+	.glb VVECTOR_TOP
+VVECTOR_TOP:
+
+	;
+	;  vOÌæÌZNV
+	;
+	;  FFE80000h - FFFFFF7Fh
+	;
+	.section	P, CODE
+
+	;
+	;  ÅèxN^e[uÌæÌZNV
+	;
+	;  FFFFFF80h - FFFFFFFFh
+	;
+	.section	FVECT, ROMDATA, ALIGN = 4
+
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target.tf	(revision 164)
@@ -0,0 +1,62 @@
+$ 
+$  TOPPERS/ASP Kernel
+$      Toyohashi Open Platform for Embedded Real-Time Systems/
+$      Advanced Standard Profile Kernel
+$ 
+$  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+$ 
+$  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$      XR[hÉÜÜêÄ¢é±ÆD
+$  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$      Ì³ÛØKèðfÚ·é±ÆD
+$  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$      ÆD
+$    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$        ñ·é±ÆD
+$  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$      ÆÓ·é±ÆD
+$ 
+$  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$  ÌÓCðíÈ¢D
+$ 
+$  @(#) $Id$
+$ 
+
+$ 
+$  ^[QbgË¶ev[giGR-SAKURApj
+$ 
+
+
+/*$NL$
+$SPC$*  Target-dependent Definitions (GR-SAKURA)$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 
+$  RX630Ë¶ÌÇÝÝ
+$ 
+$INCLUDE "rx630_ccrx/rx630.tf"$
+
+$
+$  AZut@CpÌwb_t@CÌ¶¬
+$
+$INCLUDE "target_asm_config.tf"$
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_asm_config.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_asm_config.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_asm_config.tf	(revision 164)
@@ -0,0 +1,25 @@
+$ 
+$     asm_config.inc ¶¬p
+$     pX2Ì^[QbgË¶ev[giGR-SAKURApj
+$ 
+$     Copyright (C) 2010 by Witz Corporation, JAPAN
+
+$ 
+
+$ 
+$  vZbTË¶Ìev[gt@CÌCN[h
+$ 
+$INCLUDE"rx630_ccrx/prc_asm_config.tf"$
+
+$FILE "asm_config.inc"$
+
+$NL$
+
+LOG_INH_ENTER_ENABLE $TAB$ .equ $TAB$ $+LOG_INH_ENTER_ENABLE$ $NL$
+LOG_INH_LEAVE_ENABLE $TAB$ .equ $TAB$ $+LOG_INH_LEAVE_ENABLE$ $NL$
+LOG_EXC_ENTER_ENABLE $TAB$ .equ $TAB$ $+LOG_EXC_ENTER_ENABLE$ $NL$
+LOG_EXC_LEAVE_ENABLE $TAB$ .equ $TAB$ $+LOG_EXC_LEAVE_ENABLE$ $NL$
+LOG_DSP_ENTER_ENABLE $TAB$ .equ $TAB$ $+LOG_DSP_ENTER_ENABLE$ $NL$
+LOG_DSP_LEAVE_ENABLE $TAB$ .equ $TAB$ $+LOG_DSP_LEAVE_ENABLE$ $NL$
+SIL_DLY_TIM1 $TAB$ .equ $TAB$ $+SIL_DLY_TIM1$ $NL$
+SIL_DLY_TIM2 $TAB$ .equ $TAB$ $+SIL_DLY_TIM2$ $NL$
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_ccrx_echonet.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_ccrx_echonet.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_ccrx_echonet.tf	(revision 164)
@@ -0,0 +1,67 @@
+$ 
+$  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) 2014 Cores Co., Ltd. Japan
+$ 
+$  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$      XR[hÉÜÜêÄ¢é±ÆD
+$  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$      Ì³ÛØKèðfÚ·é±ÆD
+$  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$      ÆD
+$    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$        ñ·é±ÆD
+$  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$      ÆÓ·é±ÆD
+$ 
+$  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$  ÌÓCðíÈ¢D
+$ 
+$  @(#) $Id$
+$ 
+
+$ 
+$  ^[QbgË¶ev[giGR-SAKURApj
+$ 
+
+
+/*$NL$
+$SPC$*  Target-dependent Definitions (GR-SAKURA)$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 
+$  RX630Ë¶ÌÇÝÝ
+$ 
+$INCLUDE "rx630_ccrx/rx630.tf"$
+
+$
+$  AZut@CpÌwb_t@CÌ¶¬
+$
+$INCLUDE "target_asm_config.tf"$
+
+$ ECHONET Lite~hEFATFt@CÌCN[h
+$INCLUDE "../../echonet/echonet.tf"$
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_ccrx_ecnl_lwip.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_ccrx_ecnl_lwip.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_ccrx_ecnl_lwip.tf	(revision 164)
@@ -0,0 +1,67 @@
+$ 
+$  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) 2014 Cores Co., Ltd. Japan
+$ 
+$  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$      XR[hÉÜÜêÄ¢é±ÆD
+$  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$      Ì³ÛØKèðfÚ·é±ÆD
+$  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$      ÆD
+$    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$        ñ·é±ÆD
+$  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$      ÆÓ·é±ÆD
+$ 
+$  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$  ÌÓCðíÈ¢D
+$ 
+$  @(#) $Id$
+$ 
+
+$ 
+$  ^[QbgË¶ev[giGR-SAKURApj
+$ 
+
+
+/*$NL$
+$SPC$*  Target-dependent Definitions (GR-SAKURA)$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 
+$  RX630Ë¶ÌÇÝÝ
+$ 
+$INCLUDE "rx630_ccrx/rx630.tf"$
+
+$
+$  AZut@CpÌwb_t@CÌ¶¬
+$
+$INCLUDE "target_asm_config.tf"$
+
+$ ECHONET Lite~hEFATFt@CÌCN[h
+$INCLUDE "../../ecnl_lwip/echonet.tf"$
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_cfg1_out.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_cfg1_out.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_cfg1_out.h	(revision 164)
@@ -0,0 +1,10 @@
+/*
+ *		cfg1_out.cÌNÉKvÈX^uÌè`
+ */
+
+#ifdef __RX
+#include "rx630_ccrx/prc_cfg1_out.h"
+#else
+#include "rx630_msvc/prc_cfg1_out.h"
+#endif
+#include "sil.h"
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_check.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_check.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_check.tf	(revision 164)
@@ -0,0 +1,51 @@
+$ 
+$  TOPPERS/ASP Kernel
+$      Toyohashi Open Platform for Embedded Real-Time Systems/
+$      Advanced Standard Profile Kernel
+$ 
+$  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+$ 
+$  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$      XR[hÉÜÜêÄ¢é±ÆD
+$  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$      Ì³ÛØKèðfÚ·é±ÆD
+$  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$      ÆD
+$    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$        ñ·é±ÆD
+$  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$      ÆÓ·é±ÆD
+$ 
+$  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$  ÌÓCðíÈ¢D
+$ 
+$  @(#) $Id$
+$ 
+
+$ 
+$     pX3Ì^[QbgË¶ev[giGR-SAKURApj
+$ 
+
+$ 
+$  pX3ÌvZbTË¶Ìev[gÌCN[h
+$ 
+$INCLUDE"rx630_ccrx/prc_check.tf"$
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_config.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_config.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_config.c	(revision 164)
@@ -0,0 +1,161 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	^[QbgVXeË¶W
+[iGR-SAKURApj
+ */
+
+#include "kernel_impl.h"
+#include <sil.h>
+#include "grsakura.h"
+#include "rx600/rx630_uart.h"
+
+/*
+ *  ^[QbgVXeË¶ ú»[`
+ */
+void
+target_initialize( void )
+{
+	/*
+	 *  vZbTË¶Ìú»
+	 */
+	prc_initialize();
+
+	/* IO|[gú» */
+	/* P25ðoÍ|[gÉ·é */
+	sil_wrb_mem((uint8_t *)PORT2_PDR_ADDR, 
+		sil_reb_mem((uint8_t *)PORT2_PDR_ADDR) | PORT_PDR_B5_BIT);
+	/* PA0, PA1, PA2, PA6ðoÍ|[gÉ·é */
+	sil_wrb_mem((uint8_t *)PORTA_PDR_ADDR,
+		sil_reb_mem((uint8_t *)PORTA_PDR_ADDR) | PORT_PDR_B0_BIT | PORT_PDR_B1_BIT | PORT_PDR_B2_BIT | PORT_PDR_B6_BIT);
+	/* PA7ðüÍ|[gÉ·é */
+	sil_wrb_mem((uint8_t *)PORTA_PDR_ADDR,
+		sil_reb_mem((uint8_t *)PORTA_PDR_ADDR) & ~PORT_PDR_B7_BIT);
+
+	/*
+	 *  VA|[gÌÝè
+	 */
+	rx630_uart_init(TARGET_PUTC_PORTID, UART_BAUDRATE, UART_CLKSRC);
+
+	/* |[gP20ðTxD0, |[gP21ðRxD0É */
+	sil_wrb_mem((uint8_t *)PORT2_PMR_ADDR, 0x03);
+
+	/* f[^fBNVWX^(PDR)ÌÝè P21(RxD0)ðüÍ|[gÉ·é */
+	sil_wrb_mem((uint8_t *)PORT2_PDR_ADDR, 
+		sil_reb_mem((uint8_t *)PORT2_PDR_ADDR) & ~PORT_PDR_B1_BIT);
+
+	/* f[^fBNVWX^(PDR)ÌÝè P20(TxD0)ðoÍ|[gÉ·é */
+	sil_wrb_mem((uint8_t *)PORT2_PDR_ADDR, 
+		sil_reb_mem((uint8_t *)PORT2_PDR_ADDR) | PORT_PDR_B0_BIT);
+
+	/* |[gP40`P47ðüÓ@íÉ */
+	sil_wrb_mem((uint8_t *)PORT4_PMR_ADDR, 0xFF);
+
+	/* |[gP40`P47ðüÍ|[gÉ·é */
+	sil_wrb_mem((uint8_t *)PORT4_PDR_ADDR, 0x00);
+
+	/* «ÝveNgWX^ÌÝè PFSWErbgÖÌ«ÝðÂ */
+	sil_wrb_mem((uint8_t *)MPC_PWPR_ADDR, 0x00);
+	/* «ÝveNgWX^ÌÝè PxxFSWX^ÖÌ«ÝðÂ */
+	sil_wrb_mem((uint8_t *)MPC_PWPR_ADDR, 0x40);
+
+	/* P21[q@\§äWX^ RXD0Æ·é */
+	sil_wrb_mem((uint8_t *)MPC_P21PFS_ADDR, 0x0a);
+	/* P20[q@\§äWX^ TXD0Æ·é */
+	sil_wrb_mem((uint8_t *)MPC_P20PFS_ADDR, 0x0a);
+
+	/* P40[q@\§äWX^ AiOüÍAN000Æ·é */
+	sil_wrb_mem((uint8_t *)MPC_P40PFS_ADDR, 0x80);
+	/* P41[q@\§äWX^ AiOüÍAN001Æ·é */
+	sil_wrb_mem((uint8_t *)MPC_P41PFS_ADDR, 0x80);
+	/* P42[q@\§äWX^ AiOüÍAN002Æ·é */
+	sil_wrb_mem((uint8_t *)MPC_P42PFS_ADDR, 0x80);
+	/* P43[q@\§äWX^ AiOüÍAN003Æ·é */
+	sil_wrb_mem((uint8_t *)MPC_P43PFS_ADDR, 0x80);
+	/* P44[q@\§äWX^ AiOüÍAN004Æ·é */
+	sil_wrb_mem((uint8_t *)MPC_P44PFS_ADDR, 0x80);
+	/* P45[q@\§äWX^ AiOüÍAN005Æ·é */
+	sil_wrb_mem((uint8_t *)MPC_P45PFS_ADDR, 0x80);
+	/* P46[q@\§äWX^ AiOüÍAN006Æ·é */
+	sil_wrb_mem((uint8_t *)MPC_P46PFS_ADDR, 0x80);
+	/* P47[q@\§äWX^ AiOüÍAN007Æ·é */
+	sil_wrb_mem((uint8_t *)MPC_P47PFS_ADDR, 0x80);
+
+	/* «ÝveNgWX^ÌÝè «ÝðÖ~ */
+	sil_wrb_mem((uint8_t *)MPC_PWPR_ADDR, 0x80);
+}
+
+
+/*
+ *  ^[QbgVXeÌI¹[`
+ */
+void
+target_exit( void )
+{
+	/*
+	 *	vZbTË¶ÌI¹
+	 */
+	prc_terminate();
+
+	while ( 1 );
+}
+
+
+/*
+ *  VXeOÌáxoÍÌ½ßÌ¶oÍ
+ */
+void
+target_fput_log( char c )
+{
+	if( c == '\n' ){
+		rx630_uart_pol_putc( '\r' , TARGET_PUTC_PORTID );
+	}
+
+	rx630_uart_pol_putc( c , TARGET_PUTC_PORTID );
+}
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_config.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_config.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_config.h	(revision 164)
@@ -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-2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		^[QbgË¶W
+[iGR-SAKURApj
+ *
+ *  J[lÌ^[QbgË¶ÌCN[ht@CDkernel_impl.hÌ^[
+ *  QbgË¶ÌÊut¯ÆÈéD
+ */
+
+#ifndef TOPPERS_TARGET_CONFIG_H
+#define TOPPERS_TARGET_CONFIG_H
+
+/*
+ *  ^[QbgVXeÌn[hEFA¹Ìè`
+ */
+#include "grsakura.h"
+
+
+/*
+ *  ftHgÌñ^XNReLXgpÌX^bNÌæÌè`
+ *
+ *  X^bNTCYðÏX·éêÍ, sectrx.incÌ_DEFAULT_ISTACK
+ *  xÌÊuÉ é.blkb½ßÌTCYÆ, ÈºDEFAULT_ISTKSZÌ
+ *  TCYðí¹Ä¯¶lÉÏX·é±Æ.
+ */
+#ifndef _MSC_VER
+#define DEFAULT_ISTKSZ		( 0x400/*__secsize("SI")*/ )
+#define DEFAULT_ISTK		(STK_T *)__sectop("SI")
+#else
+#define DEFAULT_ISTKSZ		( 0 )
+#define DEFAULT_ISTK		(STK_T *)NULL
+#endif // !_MSC_VER
+
+/*
+ *  ^[QbgË¶Ì¶oÍÉgp·é|[gÌè`  
+ */
+#define TARGET_PUTC_PORTID	( 1 )
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  ^[QbgVXeË¶Ìú»
+ */
+extern void	target_initialize( void );
+
+/*
+ *  ^[QbgVXeÌI¹
+ *
+ *  VXeðI¹·éÉg¤D
+ */
+extern void	target_exit( void )	NoReturn;
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+
+/*
+ *  vZbTË¶W
+[iRX630pj
+ */
+#ifdef __RX
+#include "rx630_ccrx/rx630_config.h"
+#else
+#include "rx630_msvc/rx630_config.h"
+#endif
+
+/*
+ *  g[XOÉÖ·éÝè
+ */
+#define TCNT_TRACE_BUFFER	( 32 )
+
+/*
+ *  g[XOoÍ·éÓÌIð
+ *    OoÍ·éÓð1Åè`
+ *    OoÍµÈ¢Óð0Åè`
+ */
+#ifdef TOPPERS_ENABLE_TRACE
+#define LOG_DSP_ENTER_ENABLE	( 1 )
+#define LOG_DSP_LEAVE_ENABLE	( 1 )
+#define LOG_INH_ENTER_ENABLE	( 1 )
+#define LOG_INH_LEAVE_ENABLE	( 1 )
+#define LOG_EXC_ENTER_ENABLE	( 1 )
+#define LOG_EXC_LEAVE_ENABLE	( 1 )
+#else
+#define LOG_DSP_ENTER_ENABLE	( 0 )
+#define LOG_DSP_LEAVE_ENABLE	( 0 )
+#define LOG_INH_ENTER_ENABLE	( 0 )
+#define LOG_INH_LEAVE_ENABLE	( 0 )
+#define LOG_EXC_ENTER_ENABLE	( 0 )
+#define LOG_EXC_LEAVE_ENABLE	( 0 )
+#endif
+
+#ifdef TOPPERS_ENABLE_TRACE
+#include "logtrace/trace_config.h"
+#endif /* TOPPERS_ENABLE_TRACE */
+
+#endif /* TOPPERS_TARGET_CONFIG_H */
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_def.csv
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_def.csv	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_def.csv	(revision 164)
@@ -0,0 +1,8 @@
+LOG_DSP_ENTER_ENABLE,LOG_DSP_ENTER_ENABLE
+LOG_DSP_LEAVE_ENABLE,LOG_DSP_LEAVE_ENABLE
+LOG_INH_ENTER_ENABLE,LOG_INH_ENTER_ENABLE
+LOG_INH_LEAVE_ENABLE,LOG_INH_LEAVE_ENABLE
+LOG_EXC_ENTER_ENABLE,LOG_EXC_ENTER_ENABLE
+LOG_EXC_LEAVE_ENABLE,LOG_EXC_LEAVE_ENABLE
+SIL_DLY_TIM1,SIL_DLY_TIM1
+SIL_DLY_TIM2,SIL_DLY_TIM2
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_kernel.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_kernel.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_kernel.h	(revision 164)
@@ -0,0 +1,86 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  J[lÌ^[QbgË¶è`iGR-SAKURApj
+ */
+
+/*
+ *  ±ÌCN[ht@CÍCkernel.hÅCN[h³êéD¼Ìt@
+ *  C©ç¼ÚCN[h·é±ÆÍÈ¢D±Ìt@CðCN[h
+ *  ·éOÉCt_stddef.hªCN[h³êéÌÅC»êçÉË¶µÄàæ
+ *  ¢D
+ */
+
+#ifndef TOPPERS_TARGET_KERNEL_H
+#define TOPPERS_TARGET_KERNEL_H
+
+
+/*
+ *  vZbTÅ¤ÊÈè`
+ */
+#ifdef __RX
+#include "rx630_ccrx/prc_kernel.h"
+#else
+#include "rx630_msvc/prc_kernel.h"
+#endif
+
+/*
+ *  T|[g·é@\Ìè`
+ */
+#define	TOPPERS_TARGET_SUPPORT_GET_UTM		/* get_utmðT|[g·é */
+
+
+/*
+ *  ^CeBbNÌè`
+ */
+#define	TIC_NUME		( 1U )		/* ^CeBbNÌüúÌªq */
+#define	TIC_DENO		( 1U )		/* ^CeBbNÌüúÌªê */
+
+#endif /* TOPPERS_TARGET_KERNEL_H */
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_msvc.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_msvc.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_msvc.tf	(revision 164)
@@ -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
+$ 
+$  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$      XR[hÉÜÜêÄ¢é±ÆD
+$  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$      Ì³ÛØKèðfÚ·é±ÆD
+$  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$      ÆD
+$    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$        ñ·é±ÆD
+$  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$      ÆÓ·é±ÆD
+$ 
+$  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$  ÌÓCðíÈ¢D
+$ 
+$ 
+
+$ 
+$  ^[QbgË¶ev[giGR-SAKURApj
+$ 
+
+
+/*$NL$
+$SPC$*  Target-dependent Definitions (GR-SAKURA)$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 
+$  RX630Ë¶ÌÇÝÝ
+$ 
+$INCLUDE "rx630_msvc/rx630.tf"$
+
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_msvc_echonet.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_msvc_echonet.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_msvc_echonet.tf	(revision 164)
@@ -0,0 +1,59 @@
+$ 
+$  TOPPERS/ASP Kernel
+$      Toyohashi Open Platform for Embedded Real-Time Systems/
+$      Advanced Standard Profile Kernel
+$ 
+$  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+$ 
+$  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$      XR[hÉÜÜêÄ¢é±ÆD
+$  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$      Ì³ÛØKèðfÚ·é±ÆD
+$  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$      ÆD
+$    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$        ñ·é±ÆD
+$  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$      ÆÓ·é±ÆD
+$ 
+$  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$  ÌÓCðíÈ¢D
+$ 
+$ 
+
+$ 
+$  ^[QbgË¶ev[giGR-SAKURApj
+$ 
+
+
+/*$NL$
+$SPC$*  Target-dependent Definitions (GR-SAKURA)$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 
+$  RX630Ë¶ÌÇÝÝ
+$ 
+$INCLUDE "rx630_msvc/rx630.tf"$
+
+$ ECHONET Lite~hEFATFt@CÌCN[h
+$INCLUDE "../../echonet/echonet.tf"$
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_msvc_ecnl_lwip.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_msvc_ecnl_lwip.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_msvc_ecnl_lwip.tf	(revision 164)
@@ -0,0 +1,59 @@
+$ 
+$  TOPPERS/ASP Kernel
+$      Toyohashi Open Platform for Embedded Real-Time Systems/
+$      Advanced Standard Profile Kernel
+$ 
+$  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+$ 
+$  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$      XR[hÉÜÜêÄ¢é±ÆD
+$  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$      Ì³ÛØKèðfÚ·é±ÆD
+$  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$      ÆD
+$    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$        ñ·é±ÆD
+$  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$      ÆÓ·é±ÆD
+$ 
+$  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$  ÌÓCðíÈ¢D
+$ 
+$ 
+
+$ 
+$  ^[QbgË¶ev[giGR-SAKURApj
+$ 
+
+
+/*$NL$
+$SPC$*  Target-dependent Definitions (GR-SAKURA)$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 
+$  RX630Ë¶ÌÇÝÝ
+$ 
+$INCLUDE "rx630_msvc/rx630.tf"$
+
+$ ECHONET Lite~hEFATFt@CÌCN[h
+$INCLUDE "../../ecnl_lwip/echonet.tf"$
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_offset.tf
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_offset.tf	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_offset.tf	(revision 164)
@@ -0,0 +1,13 @@
+$ 
+$       ItZbgt@C¶¬pev[gt@CiGR-SAKURApj
+$
+
+$
+$  Wev[gt@CÌCN[h
+$
+$INCLUDE "kernel/genoffset.tf"$
+
+$ 
+$  RAË¶ev[gÌCN[hiRX630pj
+$ 
+$INCLUDE"../../arch/rx630_ccrx/prc_offset.tf"$
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_rename.def
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_rename.def	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_rename.def	(revision 164)
@@ -0,0 +1,13 @@
+# target_config.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: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_rename.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_rename.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_rename.h	(revision 164)
@@ -0,0 +1,53 @@
+/* This file is generated from target_rename.def by genrename. */
+
+#ifndef TOPPERS_TARGET_RENAME_H
+#define TOPPERS_TARGET_RENAME_H
+
+/*
+ *  target_config.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_config.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 _x_config_int				__kernel_x_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 */
+
+#ifdef __RX
+#include "rx630_ccrx/prc_rename.h"
+#else
+#include "rx630_msvc/prc_rename.h"
+#endif
+
+#endif /* TOPPERS_TARGET_RENAME_H */
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_serial.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_serial.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_serial.c	(revision 164)
@@ -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) 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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	RX630 UARTpVAI/OW
+[
+ */
+#include "kernel_impl.h"
+#include <sil.h>
+#include "target_serial.h"
+
+/*
+ *  SIOhCoÌú»
+ */
+void
+sio_initialize(intptr_t exinf)
+{
+	rx630_uart_initialize();
+}
+
+/*
+ *  VAI/O|[gÌI[v
+ */
+SIOPCB *
+sio_opn_por(ID siopid, intptr_t exinf)
+{
+	SIOPCB  *p_siopcb = NULL;
+	ER      ercd;
+	INTNO	intno_sio_tx, intno_sio_rx;
+	
+	/*
+	 *  VAI/OÝð}XN·éD
+	 *  (dis_intÖÍA"\kernel\interrupt.c"ÉLq)
+	 */
+	p_siopcb = rx630_uart_get_siopcb(siopid);
+	intno_sio_tx = rx630_uart_intno_tx(p_siopcb);
+	intno_sio_rx = rx630_uart_intno_rx(p_siopcb);
+	ercd = dis_int(intno_sio_tx);
+	assert(ercd == E_OK);
+	ercd = dis_int(intno_sio_rx);
+	assert(ercd == E_OK);
+	
+	p_siopcb = 
+		rx630_uart_opn_por(siopid , exinf , UART_BAUDRATE , UART_CLKSRC);
+
+	/*
+	 *  VAI/OÝð}XNð·éD
+	 *  (ena_intÖÍA"\kernel\interrupt.c"ÉLq)
+	 */
+	ercd = ena_int(intno_sio_tx);
+	assert(ercd == E_OK);
+	ercd = ena_int(intno_sio_rx);
+	assert(ercd == E_OK);
+
+	return(p_siopcb);
+}
+
+/*
+ *  VAI/O|[gÌN[Y
+ */
+void
+sio_cls_por(SIOPCB *p_siopcb)
+{
+	ER        ercd;
+	INTNO	intno_sio_tx, intno_sio_rx;
+
+	/*
+	 *  foCXË¶ÌN[YD
+	 */
+	rx630_uart_cls_por(p_siopcb);
+	
+	/*
+	 *  VAI/OÝð}XN·éD
+	 */
+	intno_sio_tx = rx630_uart_intno_tx(p_siopcb);
+	intno_sio_rx = rx630_uart_intno_rx(p_siopcb);
+	ercd = dis_int(intno_sio_tx);
+	assert(ercd == E_OK);
+	ercd = dis_int(intno_sio_rx);
+	assert(ercd == E_OK);
+}
+
+/*
+ *  SIOÌÝnh
+ */
+void sio_tx_isr(intptr_t exinf)
+{
+	rx630_uart_tx_isr(exinf);
+}
+
+/*
+ *  SIOÌÝnh
+ */
+void sio_rx_isr(intptr_t exinf)
+{
+	rx630_uart_rx_isr(exinf);
+}
+
+/*
+ *  VAI/O|[gÖÌ¶M
+ */
+bool_t
+sio_snd_chr(SIOPCB *siopcb, char c)
+{
+	return(rx630_uart_snd_chr(siopcb, c));
+}
+
+/*
+ *  VAI/O|[g©çÌ¶óM
+ */
+int_t
+sio_rcv_chr(SIOPCB *siopcb)
+{
+	return(rx630_uart_rcv_chr(siopcb));
+}
+
+/*
+ *  VAI/O|[g©çÌR[obNÌÂ
+ */
+void
+sio_ena_cbr(SIOPCB *siopcb, uint_t cbrtn)
+{
+	rx630_uart_ena_cbr(siopcb, cbrtn);
+}
+
+/*
+ *  VAI/O|[g©çÌR[obNÌÖ~
+ */
+void
+sio_dis_cbr(SIOPCB *siopcb, uint_t cbrtn)
+{
+	rx630_uart_dis_cbr(siopcb, cbrtn);
+}
+
+/*
+ *  VAI/O|[g©çÌMÂ\R[obN
+ */
+void
+rx630_uart_irdy_snd(intptr_t exinf)
+{
+	/* ¤Êisyssvc\serial.cjÉ ésio_irdy_sndÖðÄÑoµ*/
+	sio_irdy_snd(exinf);
+}
+
+/*
+ *  VAI/O|[g©çÌóMÊmR[obN
+ */
+void
+rx630_uart_irdy_rcv(intptr_t exinf)
+{
+	/* ¤Êisyssvc\serial.cjÉ ésio_irdy_rcvÖðÄÑoµ*/
+	sio_irdy_rcv(exinf);
+}
+
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_serial.cfg
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_serial.cfg	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_serial.cfg	(revision 164)
@@ -0,0 +1,12 @@
+/*
+ *	SIOhCoiGR-SAKURApjÌRtBM
+[Vt@C
+ */
+
+#include <target_serial.h>
+ATT_INI({ TA_NULL, 0, sio_initialize });
+CFG_INT(INTNO_SIO_TX, { INTATR_SIO, INTPRI_SIO });
+CFG_INT(INTNO_SIO_RX, { INTATR_SIO, INTPRI_SIO });
+
+ATT_ISR({TA_NULL, SIO_PORTID, INTNO_SIO_TX, sio_tx_isr, 1});
+ATT_ISR({TA_NULL, SIO_PORTID, INTNO_SIO_RX, sio_rx_isr, 1});
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_serial.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_serial.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_serial.h	(revision 164)
@@ -0,0 +1,127 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		VAI/OfoCXiSIOjhCoiGR-SAKURApj
+ */
+
+#ifndef TOPPERS_TARGET_SERIAL_H
+#define TOPPERS_TARGET_SERIAL_H
+
+#include "grsakura.h"
+#include "rx600/rx630_uart.h"
+
+/*
+ *  SIOÌÝnhÌxN^Ô
+ */
+#define INHNO_SIO_TX	INT_SCI0_TEI			/* ÝnhÔ */
+#define INTNO_SIO_TX	INT_SCI0_TEI			/* ÝÔ */
+#define INHNO_SIO_RX	INT_SCI0_RXI			/* ÝnhÔ */
+#define INTNO_SIO_RX	INT_SCI0_RXI			/* ÝÔ */
+#define INTPRI_SIO		-4						/* ÝDæx */
+#define INTATR_SIO		(TA_NULL)				/* Ý®« */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+
+/*
+ *  SIOhCoÌú»
+ */
+extern void		sio_initialize(intptr_t exinf);
+
+/*
+ *  VAI/O|[gÌI[v
+ */
+extern SIOPCB	*sio_opn_por(ID siopid, intptr_t exinf);
+
+/*
+ *  VAI/O|[gÌN[Y
+ */
+extern void		sio_cls_por(SIOPCB *p_siopcb);
+
+/*
+ *  SIOÌÝnh
+ */
+extern void 	sio_tx_isr(intptr_t exinf);
+extern void 	sio_rx_isr(intptr_t exinf);
+
+/*
+ *  VAI/O|[gÖÌ¶M
+ */
+extern bool_t	sio_snd_chr(SIOPCB *siopcb, char c);
+
+/*
+ *  VAI/O|[g©çÌ¶óM
+ */
+extern int_t	sio_rcv_chr(SIOPCB *siopcb);
+
+/*
+ *  VAI/O|[g©çÌR[obNÌÂ
+ */
+extern void		sio_ena_cbr(SIOPCB *siopcb, uint_t cbrtn);
+
+/*
+ *  VAI/O|[g©çÌR[obNÌÖ~
+ */
+extern void		sio_dis_cbr(SIOPCB *siopcb, uint_t cbrtn);
+
+/*
+ *  VAI/O|[g©çÌMÂ\R[obN
+ */
+extern void		sio_irdy_snd(intptr_t exinf);
+
+/*
+ *  VAI/O|[g©çÌóMÊmR[obN
+ */
+extern void		sio_irdy_rcv(intptr_t exinf);
+
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_TARGET_SERIAL_H */
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_sil.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_sil.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_sil.h	(revision 164)
@@ -0,0 +1,70 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		sil.hÌ^[QbgË¶iGR-SAKURApj
+ *
+ *  ±ÌCN[ht@CÍCsil.hÌæªÅCN[h³êéD¼Ìt@
+ *  C©çÍ¼ÚCN[h·é±ÆÍÈ¢D±Ìt@CðCN[
+ *  h·éOÉCt_stddef.hªCN[h³êéÌÅC»êçÉË¶µÄà
+ *  æ¢D
+ */
+
+#ifndef TOPPERS_TARGET_SIL_H
+#define TOPPERS_TARGET_SIL_H
+
+/*
+ *  ÷­ÔÒ¿Ì½ßÌè`
+ */
+#define SIL_DLY_TIM1     69
+#define SIL_DLY_TIM2     50
+
+/*
+ *  vZbTÅ¤ÊÈè`
+ */
+#ifdef __RX
+#include "rx630_ccrx/prc_sil.h"
+#else
+#include "rx630_msvc/prc_sil.h"
+#endif
+
+#endif /* TOPPERS_TARGET_SIL_H */
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_stddef.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_stddef.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_stddef.h	(revision 164)
@@ -0,0 +1,110 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  t_stddef.hÌ^[QbgË¶iGR-SAKURApj
+ *
+ *  ±ÌCN[ht@CÍCt_stddef.hÌæªÅCN[h³êéD
+ *  ¼Ìt@C©çÍ¼ÚCN[h·é±ÆÍÈ¢D¼ÌCN[h
+ *  t@CÉæ§ÁÄ³êé½ßC¼ÌCN[ht@CÉË¶µ
+ *  ÄÍÈçÈ¢D
+ */
+
+#ifndef TOPPERS_TARGET_STDDEF_H
+#define TOPPERS_TARGET_STDDEF_H
+
+/*
+ *  ^[Qbgð¯Ê·é½ßÌ}NÌè`
+ */
+#define TOPPERS_GRSAKURA			/* VXeªÌ */
+
+
+#ifdef __RX
+/*
+ *  J­Â«Å¤ÊÈè`
+ */
+/*#define TOPPERS_STDINT_TYPE1*/
+#include "ccrx/tool_stddef.h"
+
+
+/*
+ *  vZbTÅ¤ÊÈè`
+ */
+#include "rx630_ccrx/prc_stddef.h"
+#else /* __RX */
+/*
+ *  J­Â«Å¤ÊÈè`
+ */
+#include <stdint.h>
+#include "msvc/tool_stddef.h"
+
+/*
+ *  vZbTÅ¤ÊÈè`
+ */
+#include "rx630_msvc/prc_stddef.h"
+
+#define __evenaccess
+#endif /* __RX */
+
+/*
+ *  AT[VÌ¸sÌÀsf
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+#ifdef __RX
+Inline void
+TOPPERS_assert_abort( void )
+{
+}
+#else /* __RX */
+extern void TOPPERS_assert_abort( void );
+#endif /* __RX */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif /* TOPPERS_TARGET_STDDEF_H */
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_support.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_support.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_support.c	(revision 164)
@@ -0,0 +1,96 @@
+/*-----------------------------------------------------------------------------
+ *  TOPPERS/SSP Windows Debug Environment
+ *  Copyright (C) 2014 Cores Co., Ltd. Japan
+ *-----------------------------------------------------------------------------
+ * $Id$
+ */
+
+/*
+ *	^[QbgVXeË¶W
+[iAP-RX62N-0Apj
+ */
+
+#include "kernel_impl.h"
+#include <sil.h>
+
+void hardware_init_hook()
+{
+	/*
+	 * ®ì[hÝè
+	 *
+	 * ®ì[hÍ{[hãÌ[qÉæÁÄè³êé½ß,
+	 * ±±ÅÍÁÊÝèµÈ¢.
+	 * ½¾µ, gGfBA/VO`bv[h
+	 * Å é±ÆðOñÆ·é.
+	 *
+	 * Ü½Zbgã, à ROMFLø, à RAMFLø, OoXF³ø
+	 * Å é.
+	 */
+
+	/*
+	 * NbNÝè
+	 *
+	 * üÍF12MHz
+	 * PLLñHF12 x 8 = 96MHz
+	 * VXeNbNF96MHz
+	 * üÓW
+[NbNF48MHz
+	 * OoXNbNF96MHz
+	 * Æ·é.
+	 */
+	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);
+
+	/* CNbN­Uí­§­U */
+	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);
+
+	/* CNbN­Uí®ì */
+	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);
+
+	/* PLLñHIð */
+	sil_wrh_mem(SYSTEM_SCKCR3_ADDR,
+		(sil_reh_mem(SYSTEM_SCKCR3_ADDR) & ~SYSTEM_SCKCR3_CKSEL_MASK)
+		| (4 << SYSTEM_SCKCR3_CKSEL_OFFSET));
+
+	/*
+	 * W
+[Xgbv
+	 *
+	 * Zbgã, ®ìµÄ¢éà üÓW
+[ÍDMAC, DTC,
+	 * à RAMÌÝÅ é.
+	 * »êÈOÌà üÓW
+[ÉÖµÄÍgp·é¤Å
+	 * Ýè·é±Æ.
+	 */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, 0xa500);
+}
+
+void software_init_hook()
+{
+	/*
+	 * {RpCÅÍweak definitionÌ@\ª³¢½ß,
+	 * ÁÉKvÈÍÈ¢ª, K¸ÄÑo·±ÆÆ·é.
+	 */
+}
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_support.src
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_support.src	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_support.src	(revision 164)
@@ -0,0 +1,191 @@
+;*
+;*  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) 2001 by OAKS16KIT support
+;*  Copyright (C) 2003-2004 by Naoki Saito
+;*             Nagoya Municipal Industrial Research Institute, JAPAN
+;*  Copyright (C) 2003-2004 by Ryosuke Takeuchi
+;*               Platform Development Center RICOH COMPANY,LTD. JAPAN
+;*  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+;*  Copyright (C) 2013      by Mitsuhiro Matsuura
+;* 
+;*  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+;*  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+;*  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+;*  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+;*       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+;*      XR[hÉÜÜêÄ¢é±ÆD
+;*  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+;*      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+;*      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+;*      Ì³ÛØKèðfÚ·é±ÆD
+;*  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+;*      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+;*      ÆD
+;*    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+;*        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+;*    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+;*        ñ·é±ÆD
+;*  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+;*      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+;*      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+;*      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+;*      ÆÓ·é±ÆD
+;* 
+;*  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+;*  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+;*  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+;*  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+;*  ÌÓCðíÈ¢D
+;* 
+;*  @(#) $Id: target_support.src 536 2014-10-09 23:11:40Z coas-nagasima $
+;*
+
+	.section	P, CODE
+
+
+	.glb	_hardware_init_hook
+	.glb	_software_init_hook
+
+
+_hardware_init_hook:
+	;
+	;  ®ì[hÝè
+	;
+	;  ®ì[hÍ{[hãÌ[qÉæÁÄè³êé½ß,
+	;  ±±ÅÍÁÊÝèµÈ¢.
+	;  ½¾µ, gGfBA/VO`bv[h
+	;  Å é±ÆðOñÆ·é.
+	;
+	;  Ü½Zbgã, à ROMFLø, à RAMFLø, OoXF³ø
+	;  Å é.
+	;
+
+	;
+	;  NbNÝè
+	;
+	;  üÍF12MHz
+	;  PLLñHF12 x 8 = 96MHz
+	;  VXeNbNF96MHz
+	;  üÓW
+[NbNF48MHz
+	;  OoXNbNF96MHz
+	;  Æ·é.
+	;
+
+	;PORT3.PDR.BIT.B6 = 0;
+	MOV.L	#08C003H,R11
+	MOV.B	[R11],R10
+	BCLR	#6,R10
+	MOV.B	R10,[R11]
+	;PORT3.PDR.BIT.B7 = 0;
+	MOV.L	#08C003H,R11
+	MOV.B	[R11],R10
+	BCLR	#7,R10
+	MOV.B	R10,[R11]
+	;PORT3.PMR.BIT.B6 = 0;
+	MOV.L	#08C003H,R11
+	MOV.B	60H[R11],R10
+	BCLR	#6,R10
+	MOV.B	R10,60H[R11]
+	;PORT3.PMR.BIT.B7 = 0;
+	MOV.L	#08C003H,R11
+	MOV.B	60H[R11],R10
+	BCLR	#7,R10
+	MOV.B	R10,60H[R11]
+	;
+	;SYSTEM.PRCR.WORD = 0xa503;
+	MOV.L	#080000H,R10
+	MOV.W	#-5AFDH,03FEH[R10]
+	;
+	;while(SYSTEM.MOFCR.BIT.MOFXIN == 0)
+	BRA.B	_hardware_init_hook_01
+	;SYSTEM.MOFCR.BIT.MOFXIN = 1;	// CNbN­Uí­§­U
+_hardware_init_hook_00:
+	MOV.L	#080000H,R11
+	MOV.B	0C293H[R11],R10
+	BSET	#0,R10
+	MOV.B	R10,0C293H[R11]
+_hardware_init_hook_01:
+	MOV.L	#080000H,R10
+	MOV.B	0C293H[R10],R10
+	AND		#1H,R10
+	MOVU.B	R10,R10
+	CMP		#0H,R10
+	BEQ.B	_hardware_init_hook_00
+	;
+	;while(SYSTEM.MOSCCR.BIT.MOSTP == 1)
+	BRA.B	_hardware_init_hook_11
+	;SYSTEM.MOSCCR.BIT.MOSTP = 0;	// CNbN­Uí®ì
+_hardware_init_hook_10:
+	MOV.L	#080000H,R11
+	MOV.B	32H[R11],R10
+	BCLR	#0,R10
+	MOV.B	R10,32H[R11]
+_hardware_init_hook_11:
+	MOV.L	#080000H,R10
+	MOV.B	32H[R10],R10
+	AND		#1H,R10
+	MOVU.B	R10,R10
+	CMP		#0H,R10
+	BNE.B	_hardware_init_hook_10
+	;
+	;SYSTEM.PLLCR.BIT.STC = 0x0f;
+	MOV.L	#080000H,R10
+	MOV.W	28H[R10],R11
+	AND		#-3F01H,R11
+	OR		#0F00H,R11
+	MOV.W	R11,28H[R10]
+	;SYSTEM.PLLCR2.BIT.PLLEN = 0;
+	MOV.L	#080000H,R11
+	MOV.B	2AH[R11],R10
+	BCLR	#0,R10
+	MOV.B	R10,2AH[R11]
+	;
+	;SYSTEM.SCKCR.LONG = 0x21021211;
+	MOV.L	#080000H,R10
+	MOV.L	#21021211H,20H[R10]
+	;
+	;SYSTEM.SCKCR3.BIT.CKSEL = 4;		// PLLñHIð
+	MOV.L	#080000H,R10
+	MOV.W	26H[R10],R11
+	AND		#-0701H,R11
+	OR		#0400H,R11
+	MOV.W	R11,26H[R10]
+
+	;
+	;  W
+[Xgbv
+	;
+	;  Zbgã, ®ìµÄ¢éà üÓW
+[ÍDMAC, DTC,
+	;  à RAMÌÝÅ é.
+	;  »êÈOÌà üÓW
+[ÉÖµÄÍgp·é¤Å
+	;  Ýè·é±Æ.
+	;
+
+	;SYSTEM.PRCR.WORD = 0xa500;
+	MOV.L	#080000H,R10
+	MOV.W	#-5B00H,03FEH[R10]
+	rts
+
+
+_software_init_hook:
+	;
+	;  {RpCÅÍweak definitionÌ@\ª³¢½ß,
+	;  ÁÉKvÈÍÈ¢ª, K¸ÄÑo·±ÆÆ·é.
+	;
+	rts
+
+
+	.end
+
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_syssvc.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_syssvc.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_syssvc.h	(revision 164)
@@ -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) 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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		VXeT[rXÌ^[QbgË¶iGR-SAKURApj
+ *
+ *  VXeT[rXÌ^[QbgË¶ÌCN[ht@CD±Ìt@
+ *  CÌàeÍCR|[lgLqt@CÉLq³êC±Ìt@CÍ
+ *  ³­Èé©ÝD
+ */
+
+#ifndef TOPPERS_TARGET_SYSSVC_H
+#define TOPPERS_TARGET_SYSSVC_H
+
+
+/*
+ *  vZbTË¶Ìè`
+ */
+#ifdef __RX
+#include "rx630_ccrx/prc_syssvc.h"
+#else
+#include "rx630_msvc/prc_syssvc.h"
+#endif
+
+/*
+ *  g[XOÉÖ·éÝè
+ */
+#ifdef TOPPERS_ENABLE_TRACE
+#include "logtrace/trace_config.h"
+#endif /* TOPPERS_ENABLE_TRACE */
+
+
+/*
+ *  {[hË¶îñÌÇÝÝ
+ */
+#include "grsakura.h"
+
+
+/*
+ *  N®bZ[WÌ^[QbgVXe¼
+ */
+#define	TARGET_NAME	"GRSAKURA"
+
+
+/*
+ *  VXeOÌáxoÍÌ½ßÌ¶oÍ
+ *
+ *  ^[QbgË¶Ìû@ÅC¶cð\¦/oÍ/Û¶·éD
+ */
+extern void	target_fput_log( char c );
+
+
+/*
+ *  N®bZ[WÉ^[QbgË¶Ìì \¦ð
+ *  ÇÁ·é½ßÌ}ND
+ */
+#ifdef PRC_COPYRIGHT
+#define	TARGET_COPYRIGHT	PRC_COPYRIGHT
+#endif /* PRC_COPYRIGHT */
+
+
+/*
+ *  VA|[gÌè`
+ */
+#define	TNUM_PORT			UINT_C( 2 )
+
+/*
+ *  gp·éVA|[gID
+ */
+#define	SIO_PORTID			UINT_C( 1 )
+
+#define LOGTASK_PORTID		SIO_PORTID
+
+#define STACK_SIZE			(512)
+
+/*
+ *  VXeO^XNÖAÌèÌè`
+ *
+ *  ftHglÌÊèD
+ */
+
+#endif /* TOPPERS_TARGET_SYSSVC_H */
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_test.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_test.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_test.h	(revision 164)
@@ -0,0 +1,72 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		eXgvOÌ^[QbgË¶è`iGR-SAKURApj
+ */
+
+#ifndef TOPPERS_TARGET_TEST_H
+#define TOPPERS_TARGET_TEST_H
+
+/*
+ *  vZbTÅ¤ÊÈè`
+ */
+#ifdef __RX
+#include "rx630_ccrx/prc_test.h"
+#else
+#include "rx630_msvc/prc_test.h"
+#endif
+
+/*
+ *  ^XNÅgp·éVA|[gID
+ */
+#define	TASK_PORTID		( 1 )
+
+
+#endif /* TOPPERS_TARGET_TEST_H */
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_timer.c
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_timer.c	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_timer.c	(revision 164)
@@ -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) 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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		^C}hCoiGR-SAKURApj
+ */
+
+#include "kernel_impl.h"
+#include "time_event.h"
+#include <sil.h>
+#include "target_timer.h"
+
+/*
+ *  ^C}Ìú»
+ */
+void
+target_timer_initialize(intptr_t exinf)
+{
+	/*
+	 * W
+[Xgbv@\ÌÝè
+	 */
+	sil_wrh_mem((uint16_t *)SYSTEM_PRCR_ADDR, (uint16_t)0xA502);	/* ÝÂ */
+	sil_wrw_mem((uint32_t *)SYSTEM_MSTPCRA_ADDR,
+		sil_rew_mem((uint32_t *)SYSTEM_MSTPCRA_ADDR) & ~SYSTEM_MSTPCRA_MSTPA15_BIT); /* CMT0 */
+	sil_wrh_mem((uint16_t *)SYSTEM_PRCR_ADDR, (uint16_t)0xA500);	/* ÝÖ~ */
+
+	/* 
+	 * ^C}â~ 
+	 */
+	sil_wrh_mem((uint16_t *)CMT_CMSTR0_ADDR,
+		sil_reh_mem((uint16_t *)CMT_CMSTR0_ADDR) & ~CMT_CMSTR0_STR0_BIT);
+	
+	/*
+ 	 * JEgAbvÉp¢çêéNbNÝè
+	 * PCLK/32ðIð
+	 */
+	sil_wrh_mem((uint16_t *)CMT0_CMCR_ADDR, CMT_PCLK_DIV_8);
+
+	/* 
+	 * RyA}b`^C}JE^Ýè
+	 */
+	sil_wrh_mem((uint16_t *)CMT0_CMCNT_ADDR, 0U);
+
+	/* 
+	 * RyA}b`^C}üúÝè
+	 */
+	sil_wrh_mem((uint16_t *)CMT0_CMCOR_ADDR, CMCOR_PERIOD);
+
+	/*
+	 * RyA}b`^C}èÝvæÝèWX^iISELR28j
+	 */
+	sil_wrb_mem((uint8_t *)ICU_ISELR028_ADDR, ICU_ISEL_CPU);
+
+	/*
+	 *  ^C}®ìJnOÌÝvðNA
+	 */
+	x_clear_int(INTNO_TIMER);
+
+	/* 
+	 * RyA}b`^C}èÝðÂ
+	 */
+	sil_wrh_mem((uint16_t *)CMT0_CMCR_ADDR,
+		sil_reh_mem((uint16_t *)CMT0_CMCR_ADDR) | CMT0_CMCR_CMIE_BIT);
+	
+	/* 
+	 * ^C}®ìJn
+	 */
+	sil_wrh_mem((uint16_t *)CMT_CMSTR0_ADDR,
+		sil_reh_mem((uint16_t *)CMT_CMSTR0_ADDR) | CMT_CMSTR0_STR0_BIT);
+}
+
+/*
+ *  ^C}Ìâ~
+ */
+void
+target_timer_terminate(intptr_t exinf)
+{
+	/* 
+	 * ^C}â~ 
+	 */
+	sil_wrh_mem((uint16_t *)CMT_CMSTR0_ADDR,
+		sil_reh_mem((uint16_t *)CMT_CMSTR0_ADDR) & ~CMT_CMSTR0_STR0_BIT);
+}
+
+/*
+ *  ^C}Ýnh
+ */
+void target_timer_handler(void)
+{
+	i_begin_int(INTNO_TIMER);
+
+	signal_time();				/* ^CeBbNÌ */
+
+	i_end_int(INTNO_TIMER);
+}
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_timer.cfg
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_timer.cfg	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_timer.cfg	(revision 164)
@@ -0,0 +1,10 @@
+/*
+ *  ^C}hCoiRX630pjÌRtBM
+[Vt@C
+ */
+
+#include "target_timer.h"
+ATT_INI({ TA_NULL, 0, target_timer_initialize });
+ATT_TER({ TA_NULL, 0, target_timer_terminate });
+DEF_INH(INHNO_TIMER, { TA_NULL, target_timer_handler });
+CFG_INT(INTNO_TIMER, { INTATR_TIMER, INTPRI_TIMER });
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_timer.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_timer.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_timer.h	(revision 164)
@@ -0,0 +1,184 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		^C}hCoiGR-SAKURApj
+ */
+ 
+#ifndef TOPPERS_TARGET_TIMER_H
+#define TOPPERS_TARGET_TIMER_H
+
+#include <sil.h>
+#include "grsakura.h"
+#include "target_syssvc.h"
+
+/*
+ *  ^C}Ýnho^Ì½ßÌè
+ */
+#define INHNO_TIMER		INT_CMT0_CMI				/* ÝnhÔ */
+#define INTNO_TIMER		INT_CMT0_CMI				/* ÝÔ */
+#define INTPRI_TIMER	-5							/* ÝDæx */
+#define INTATR_TIMER	(TA_ENAINT | TA_EDGE)		/* Ý®« */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  ^C}lÌà\»Ì^
+ */
+typedef uint16_t	CLOCK;
+
+/*
+ *  ^C}lÌà\»Æ~bPÊÆÌÏ·
+ *
+ *  1msÌ^C}[èÝðgp·éÌÅ»ÌNbNðè`·éD
+ */
+#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))
+
+/*
+ *  ÝèÅ«éÅåÌ^C}üúiPÊÍà\»j
+ */
+#define	MAX_CLOCK	((CLOCK) 0xFFFFU)
+
+/*
+ *  «\]¿pVXeðæèo·ÛÌÔÌ©ÏèliPÊÍà\»j
+ */
+#define	GET_TOLERANCE	(100U)	/* xêÌ©ÏèliPÊÍà\»j*/
+#define	BEFORE_IREQ(clock) \
+		((clock) >= (TO_CLOCK(TIC_NUME, TIC_DENO) - GET_TOLERANCE))
+
+/*
+ *  RyA}b`^C}Rg[WX^ÌÝèl
+ */
+/*
+ *  NbNIðrbg
+ *
+ *  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)
+
+/*
+ *  RyA}b`^C}RX^gWX^iCMCORj
+ *
+ *  RyA}b`üúð1msÆ·éD
+ *  üÓW
+[NbNiPCLKj48MHzð8ªü·éÌÅC
+ *  1üú ½è166.7nsecÆÈèC6000üúÅ1msi^CeBbNÌüújÆ·éD
+ */
+#define CMCOR_PERIOD			(TIMER_CLOCK)
+
+/*
+ * RyA}b`^C}èÝvæÝèWX^iiISELRijii= èÝxN^Ôj
+ */
+#define ICU_ISEL_CPU			(0x00U)
+
+
+
+
+/*
+ *  ^C}ÌN®
+ *
+ *  ^C}ðú»µCüúIÈ^C}Ývð­¶³¹éD
+ */
+extern void	target_timer_initialize(intptr_t exinf);
+
+/*
+ *  ^C}Ìâ~
+ *
+ *  ^C}Ì®ìðâ~³¹éD
+ */
+extern void	target_timer_terminate(intptr_t exinf);
+
+/*
+ *  ^C}WX^lÌÇÝoµ
+ */
+Inline uint16_t rx630_cmt_getcount(void)
+{
+	return sil_reh_mem((uint16_t *)CMT0_CMCNT_ADDR);
+}
+
+/*
+ *  ^C}WX^lÌ«Ý
+ */
+Inline void rx630_cmt_setcount(uint16_t count)
+{
+	sil_wrh_mem((uint16_t *)CMT0_CMCNT_ADDR, count);
+}
+
+/*
+ *  ^C}Ì»ÝlÌÇoµ
+ */
+Inline CLOCK
+target_timer_get_current(void)
+{
+	/* AbvJEgÌ½ß^C}WX^lð»ÌÜÜÔ·	*/
+	return (rx630_cmt_getcount());
+}
+
+/*
+ *  ^C}ÝvÌ`FbN
+ */
+Inline bool_t
+target_timer_probe_int(void)
+{
+	return(x_probe_int(INTNO_TIMER));
+}
+
+/*
+ *  ^C}Ýnh
+ */
+extern void	target_timer_handler(void);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_TARGET_TIMER_H */
Index: UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_unrename.h
===================================================================
--- UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_unrename.h	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/target/grsakura_ccrx/target_unrename.h	(revision 164)
@@ -0,0 +1,50 @@
+/* This file is generated from target_rename.def by genrename. */
+
+#ifndef TOPPERS_TARGET_RENAME_H
+#define TOPPERS_TARGET_RENAME_H
+
+/*
+ *  target_config.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_config.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 */
+
+#ifdef __RX
+#include "rx630_ccrx/prc_unrename.h"
+#else
+#include "rx630_msvc/prc_unrename.h"
+#endif
+
+#endif /* TOPPERS_TARGET_RENAME_H */
Index: UsbWattMeter/trunk/asp_dcre/utils/applyrename
===================================================================
--- UsbWattMeter/trunk/asp_dcre/utils/applyrename	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/utils/applyrename	(revision 164)
@@ -0,0 +1,123 @@
+#! /usr/bin/perl
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2004-2011 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+#  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+#  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+#  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+#       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+#      XR[hÉÜÜêÄ¢é±ÆD
+#  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+#      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+#      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+#      Ì³ÛØKèðfÚ·é±ÆD
+#  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+#      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+#      ÆD
+#    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+#        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+#    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+#        ñ·é±ÆD
+#  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+#      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+#      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+#      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+#      ÆÓ·é±ÆD
+# 
+#  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+#  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+#  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+#  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+#  ÌÓCðíÈ¢D
+# 
+#  @(#) $Id: applyrename 332 2007-07-17 12:15:37Z hiro $
+# 
+
+#
+#  t@CÉl[ðKp·é
+#
+sub applyrename
+{
+	local($infile) = @_;
+	local($outfile) = $infile.".new";
+	local($line);
+
+	open(INFILE, "< ".$infile) || die;
+	open(OUTFILE, "> ".$outfile) || die;
+
+	while ($line = <INFILE>) {
+		$line =~ s/\b(_?)($syms)\b/$1_kernel_$2/gc;
+		print OUTFILE $line;
+	}
+
+	close(INFILE);
+	close(OUTFILE);
+
+	if (`cmp $infile $outfile`) {
+		rename($infile, $infile.".bak");
+		rename($outfile, $infile);
+		print STDERR "Modified: ",$infile,"\n";
+	}
+	else {
+		unlink($outfile);
+	}
+}
+
+#
+#  G[`FbN
+#
+if ($#ARGV < 1) {
+	die "Usage: appyrename <prefix> <filelist>\n";
+}
+
+#
+#  ú»
+#
+@syms = ();
+$name = $ARGV[0];
+
+#
+#  V{XgðÇÝÞ
+#
+$deffile = $name."_rename.def";
+open(INFILE, $deffile) || die "Cannot open $deffile";
+while ($line = <INFILE>) {
+	chomp $line;
+	if ($line =~ /^#(.*)$/) {
+		# do nothing
+	}
+	elsif ($line =~ /^INCLUDE[ \t]+(.*)$/) {
+		# do nothing
+	}
+	elsif ($line ne "") {
+		@syms = (@syms, $line)
+	}
+}
+close(INFILE);
+
+#
+#  ³K\»ðìé
+#
+$syms = join("|", @syms);
+
+#
+#  t@CÉl[ðKp·é
+#
+shift @ARGV;
+foreach $infile (@ARGV) {
+	# t@CÅÈ¯êÎXLbv
+	next unless (-f $infile);
+
+	applyrename($infile) if ($infile ne $deffile);
+}
Index: UsbWattMeter/trunk/asp_dcre/utils/genoffset
===================================================================
--- UsbWattMeter/trunk/asp_dcre/utils/genoffset	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/utils/genoffset	(revision 164)
@@ -0,0 +1,275 @@
+#! /usr/bin/perl
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2004-2011 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+#  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+#  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+#  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+#       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+#      XR[hÉÜÜêÄ¢é±ÆD
+#  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+#      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+#      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+#      Ì³ÛØKèðfÚ·é±ÆD
+#  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+#      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+#      ÆD
+#    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+#        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+#    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+#        ñ·é±ÆD
+#  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+#      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+#      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+#      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+#      ÆÓ·é±ÆD
+# 
+#  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+#  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+#  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+#  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+#  ÌÓCðíÈ¢D
+# 
+#  @(#) $Id: genoffset 1840 2010-07-10 17:29:42Z ertl-hiro $
+# 
+
+#
+#  ú»
+#
+$infile = $ARGV[0];
+$sil_endian = "";
+
+#
+#  ðßÅ«éfBNeBuÌe[u
+#
+%directives = (
+	"long", "",
+	"dword", "",
+	"word", "",
+	"hword", "",
+	"int", "",
+	"short", "",
+	"half", "",
+	"byte", "",
+	"value", "",
+	"uaword", "",
+	"uashort", "",
+	"data32", 4,
+	"data16", 2,
+	"data8", 1,
+	"zero", -1,
+	"space", -1,
+	"globl", 0,
+	"global", 0,
+	"align", 0,
+	"p2align", 0,
+	"even", 0,
+	"data", 0,
+	"stabs", 0,
+	"type", 0,
+	"size", 0,
+	"section", 0,
+	"sdata", 0,
+	"code", 0,
+);
+
+#
+#  ItZbglÌoÍ
+#
+sub parse_offset {
+	my($label, $val) = @_;
+
+	printf "#define %s\t%d\n",$label,$val;
+}
+
+#
+#  fBNeBuÌÇÝæè
+#
+sub ref_bit {
+	my($size) = @_;
+	my($dir, $directive);
+
+	while ($line = <INFILE>) {
+		chomp $line;
+		next if ($line =~ /^[ \t]*[#;].*$/);
+
+		if ($line =~ /[ \t]*\.([a-zA-Z0-9]+)[ \t]*([^ \t]*)[ \t]*/
+						&& defined($dir = $directives{$1})) {
+			$directive = $1;
+			if ($dir eq "") {
+				# o^·×«fBNeBu
+				$directives{$directive} = $size;
+			}
+			last;
+		}
+		else {
+			# ðÍÅ«È¢s
+			print STDERR "genoffset: cannot parse: $line\n";
+			$error = 1;
+		}
+	}
+}
+
+#
+#  rbgT[`
+#
+sub search_bit {
+	my($val) = @_;
+	my($val_bit);
+
+	return(-1) if ($val == 0);
+
+	$val_bit = 0;
+	while (($val & 1) == 0) {
+		$val >>= 1;
+		$val_bit++;
+	}
+	return($val_bit);
+}
+
+#
+#  rbgÊuÌoÍ
+#
+sub parse_bit {
+	my($endian, $size, $label) = @_;
+	my($offset, $dir, $val, $val_bit);
+
+	if ($sil_endian && $endian ne $sil_endian) {
+		# GfBAÌsêv
+		print STDERR "genoffset: endian mismatch: $line\n";
+		$error = 1;
+	}
+
+	$offset = 0;
+	while ($line = <INFILE>) {
+		chomp $line;
+		next if ($line =~ /^[ \t]*[#;].*$/);
+
+		if ($line =~ /[ \t]*\.([a-zA-Z0-9]+)[ \t]*([^ \t]*)[ \t]*/
+						&& defined($dir = $directives{$1})) {
+			$val = $2;
+
+			# 16iÆ8iÌlÖÌÏ·
+			if ($val =~ /^0x(.+)$/) {
+				$val = hex($1);
+			}
+			elsif ($val =~ /^0(.+)$/) {
+				$val = oct($1);
+			}
+
+			if ($dir eq "") {
+				# TCYðmçÈ¢fBNeBu
+				print STDERR "genoffset: unknown directive: $line\n";
+				$error = 1;
+			}
+			elsif ($dir == 0) {
+				# ÇÝòÎ·×«fBNeBu
+			}
+			elsif ($dir == -1) {
+				# .zerofBNeBuÌ
+				$offset += $val;
+			}
+			elsif ($val == 0) {
+				# lª0ÌtB[hÌ
+				$offset += $dir;
+			}
+			else {
+				# lª0ÅÈ¢tB[hª©Â©êÎ[vðI¹
+				last;
+			}
+		}
+		else {
+			# ðÍÅ«È¢s
+			print STDERR "genoffset: cannot parse: $line\n";
+			$error = 1;
+		}
+	}
+
+	# rbgÊuðT·
+	$val_bit = search_bit($val);
+
+	# oCgPÊÉ·Z·é
+	if ($endian eq "B") {
+		$offset += $dir - 1;
+		$offset -= $val_bit >> 3;
+	}
+	else {
+		$offset += $val_bit >> 3;
+	}
+	$val_bit &= 0x07;
+
+	# oÍPÊÉ·Z·é
+	if ($size eq "W") {
+		if ($endian eq "B") {
+			$val_bit += 24;
+			$val_bit -= ($offset & 0x03) << 3;
+		}
+		else {
+			$val_bit += ($offset & 0x03) << 3;
+		}
+		$offset &= ~0x03;
+	}
+	elsif ($size eq "H") {
+		if ($endian eq "B") {
+			$val_bit += 8;
+			$val_bit -= ($offset & 0x01) << 3;
+		}
+		else {
+			$val_bit += ($offset & 0x01) << 3;
+		}
+		$offset &= ~0x01;
+	}
+
+	# è`ÌoÍ
+	$label =~ s/^_//;
+	printf "#define %s\t%d\n",$label,$offset;
+	printf "#define %s_bit\t%d\n",$label,$val_bit;
+	printf "#define %s_mask\t0x%x\n",$label,(1 << $val_bit);
+}
+
+#
+#  C[`
+#
+print "/* This file is generated by genoffset. */\n";
+print "\n";
+
+$error = 0;
+open(INFILE, $infile) || die "Cannot open $infile";
+while ($line = <INFILE>) {
+	chomp $line;
+
+	if ($line =~ /^[ \t]*OFFSET_DEF ([^ \t]+) = [#\$]?([^ \t]+)/) {
+		parse_offset($1, $2);
+	}
+	elsif ($line =~ /^[ \t]*_?BIT_REF_([0-9]+):/) {
+		ref_bit($1);
+	}
+	elsif ($line =~ /^[ \t]*SIL_ENDIAN = ([BL])/) {
+		$sil_endian = $1;
+	}
+}
+#
+#  RpCªO[oÏÌzuðÏX·éÆCBIT_REF_?ªºÉÈ
+#  éÂ\«ª é½ßCª©çÇÝ¼·D
+#
+seek(INFILE, 0, SEEK_SET);
+while ($line = <INFILE>) {
+	chomp $line;
+
+	if ($line =~ /^[ \t]*_?BIT_([BL])([BHW])_([^ \t]+):/) {
+		parse_bit($1, $2, $3);
+	}
+}
+close(INFILE);
+exit($error);
Index: UsbWattMeter/trunk/asp_dcre/utils/genrename
===================================================================
--- UsbWattMeter/trunk/asp_dcre/utils/genrename	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/utils/genrename	(revision 164)
@@ -0,0 +1,253 @@
+#! /usr/bin/perl
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+#  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+#  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+#  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+#       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+#      XR[hÉÜÜêÄ¢é±ÆD
+#  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+#      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+#      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+#      Ì³ÛØKèðfÚ·é±ÆD
+#  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+#      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+#      ÆD
+#    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+#        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+#    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+#        ñ·é±ÆD
+#  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+#      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+#      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+#      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+#      ÆÓ·é±ÆD
+# 
+#  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+#  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+#  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+#  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+#  ÌÓCðíÈ¢D
+# 
+#  @(#) $Id: genrename 509 2007-08-22 23:09:56Z hiro $
+# 
+
+#
+#  æªÉÂ¯é¶ñ
+#
+sub prefix_string {
+	local($sym) = @_;
+
+	if ($sym =~ /[a-z]/) {
+		return("_kernel_");
+	}
+	else {
+		return("_KERNEL_");
+	}
+}
+
+#
+#  l[è`ð¶¬·é
+#
+sub generate_define
+{
+	local($sym, $prefix) = @_;
+
+	print FILE "#define ",$prefix,$sym;
+	print FILE "\t" if (length($prefix.$sym) < 4);
+	print FILE "\t" if (length($prefix.$sym) < 8);
+	print FILE "\t" if (length($prefix.$sym) < 12);
+	print FILE "\t" if (length($prefix.$sym) < 16);
+	print FILE "\t" if (length($prefix.$sym) < 20);
+	print FILE "\t" if (length($prefix.$sym) < 24);
+	print FILE "\t",$prefix,prefix_string($sym),$sym,"\n";
+}
+
+#
+#  l[ðð¶¬·é
+#
+sub generate_undef
+{
+	local($sym, $prefix) = @_;
+
+	print FILE "#undef ",$prefix,$sym,"\n";
+}
+
+#
+#  CN[hfBNeBuð¶¬·é
+#
+sub generate_include
+{
+	local($file, $prefix) = @_;
+
+	$file =~ s/([>"])$/_$prefix.h$1/;
+	$includes .= "#include ".$file."\n";
+}
+
+#
+#  G[`FbN
+#
+if ($#ARGV != 0) {
+	die "Usage: genrename <prefix>\n";
+}
+
+#
+#  ú»
+#
+@syms = ();
+$name = $ARGV[0];
+$NAME = $name; $NAME =~ y/a-z/A-Z/;
+
+$infile = $name."_rename.def";
+$header_defsym = "TOPPERS_".$NAME."_RENAME_H";
+
+#
+#  V{XgðÇÝÞ
+#
+open(INFILE, $infile) || die "Cannot open $infile";
+while ($line = <INFILE>) {
+	chomp $line;
+	@syms = (@syms, $line);
+}
+close(INFILE);
+
+#
+#  ???_rename.h ð¶¬·é
+#
+$includes = "";
+$file = $name."_rename.h";
+open(FILE, "> ".$file);
+
+print FILE <<END;
+/* This file is generated from $infile by genrename. */
+
+#ifndef $header_defsym
+#define $header_defsym
+
+END
+
+foreach $sym (@syms) {
+	if ($sym =~ /^#(.*)$/) {
+		print FILE "/*\n";
+		print FILE " * ",$1,"\n";
+		print FILE " */\n";
+	}
+	elsif ($sym =~ /^INCLUDE[ \t]+(.*)$/) {
+		generate_include($1, "rename");
+	}
+	elsif ($sym ne "") {
+		generate_define($sym, "");
+	}
+	else {
+		print FILE "\n";
+	}
+}
+
+print FILE <<END;
+
+#ifdef TOPPERS_LABEL_ASM
+
+END
+
+foreach $sym (@syms) {
+	if ($sym =~ /^#(.*)$/) {
+		print FILE "/*\n";
+		print FILE " * ",$1,"\n";
+		print FILE " */\n";
+	}
+	elsif ($sym =~ /^INCLUDE[ \t]+(.*)$/) {
+		# do nothing
+	}
+	elsif ($sym ne "") {
+		generate_define($sym, "_");
+	}
+	else {
+		print FILE "\n";
+	}
+}
+
+print FILE <<END;
+
+#endif /* TOPPERS_LABEL_ASM */
+
+$includes
+#endif /* $header_defsym */
+END
+
+#
+#  ???_unrename.h ð¶¬·é
+#
+$includes = "";
+$file = $name."_unrename.h";
+open(FILE, "> ".$file);
+
+print FILE <<END;
+/* This file is generated from $infile by genrename. */
+
+/* This file is included only when $name\_rename.h has been included. */
+#ifdef $header_defsym
+#undef $header_defsym
+
+END
+
+foreach $sym (@syms) {
+	if ($sym =~ /^#(.*)$/) {
+		print FILE "/*\n";
+		print FILE " * ",$1,"\n";
+		print FILE " */\n";
+	}
+	elsif ($sym =~ /^INCLUDE[ \t]+(.*)$/) {
+		generate_include($1, "unrename");
+	}
+	elsif ($sym ne "") {
+		generate_undef($sym, "");
+	}
+	else {
+		print FILE "\n";
+	}
+}
+
+print FILE <<END;
+
+#ifdef TOPPERS_LABEL_ASM
+
+END
+
+foreach $sym (@syms) {
+	if ($sym =~ /^#(.*)$/) {
+		print FILE "/*\n";
+		print FILE " * ",$1,"\n";
+		print FILE " */\n";
+	}
+	elsif ($sym =~ /^INCLUDE[ \t]+(.*)$/) {
+		# do nothing
+	}
+	elsif ($sym ne "") {
+		generate_undef($sym, "_");
+	}
+	else {
+		print FILE "\n";
+	}
+}
+
+print FILE <<END;
+
+#endif /* TOPPERS_LABEL_ASM */
+
+$includes
+#endif /* $header_defsym */
+END
+
+close(FILE);
Index: UsbWattMeter/trunk/asp_dcre/utils/gentest
===================================================================
--- UsbWattMeter/trunk/asp_dcre/utils/gentest	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/utils/gentest	(revision 164)
@@ -0,0 +1,333 @@
+#! /usr/bin/perl
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2007-2012 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+#  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+#  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+#  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+#       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+#      XR[hÉÜÜêÄ¢é±ÆD
+#  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+#      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+#      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+#      Ì³ÛØKèðfÚ·é±ÆD
+#  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+#      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+#      ÆD
+#    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+#        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+#    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+#        ñ·é±ÆD
+#  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+#      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+#      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+#      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+#      ÆÓ·é±ÆD
+# 
+#  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+#  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+#  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+#  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+#  ÌÓCðíÈ¢D
+# 
+#  $Id: gentest 2417 2012-09-07 08:16:42Z ertl-hiro $
+# 
+
+#
+#		eXgvO¶¬c[
+#
+
+$infile = $ARGV[0];
+
+%parampos = (
+	"get_pri" => 2,
+	"get_inf" => 1,
+	"ref_tsk" => 2,
+	"ref_tex" => 2,
+	"ref_sem" => 2,
+	"ref_flg" => 2,
+	"ref_dtq" => 2,
+	"ref_pdq" => 2,
+	"ref_mbx" => 2,
+	"ref_mtx" => 2,
+	"ref_mpf" => 2,
+	"get_tim" => 1,
+	"get_utm" => 1,
+	"ref_cyc" => 2,
+	"ref_alm" => 2,
+	"get_tid" => 1,
+	"iget_tid" => 1,
+	"get_ipm" => 1,
+);
+
+%paramtype = (
+	"get_pri" => "PRI",
+	"get_inf" => "intptr_t",
+	"ref_tsk" => "T_RTSK",
+	"ref_tex" => "T_RTEX",
+	"ref_sem" => "T_RSEM",
+	"ref_flg" => "T_RFLG",
+	"ref_dtq" => "T_RDTQ",
+	"ref_pdq" => "T_RPDQ",
+	"ref_mbx" => "T_RMBX",
+	"ref_mtx" => "T_RMTX",
+	"ref_mpf" => "T_RMPF",
+	"get_tim" => "SYSTIM",
+	"get_utm" => "SYSUTM",
+	"ref_cyc" => "T_RCYC",
+	"ref_alm" => "T_RALM",
+	"get_tid" => "ID",
+	"iget_tid" => "ID",
+	"get_ipm" => "PRI",
+);
+
+sub gen_var_def {
+	local($svc_call) = @_;
+	local($svcname, @params);
+	local($typename, $varname);
+
+	if ($svc_call =~ /^([a-z_]+)\((.*)\)$/) {
+		$svcname = $1;
+		@params = split(/\s*,\s*/, $2);
+
+		if ($parampos{$svcname}) {
+			$varname = $params[@parampos{$svcname} - 1];
+			$varname =~ s/^\&//;
+			$typename = $paramtype{$svcname};
+			${$TASKVAR{$tskid}}{$typename} = ${varname};
+		}
+	}
+}
+
+sub gen_svc_call {
+	local($svc_call, $error_code_string) = @_;
+	local($error_code);
+
+	$TASKCODE{$tskid} .= $indentstr;
+	$TASKCODE{$tskid} .= sprintf("ercd = %s;\n", $svc_call);
+	gen_var_def($svc_call);
+
+	if ($error_code_string eq "") {
+		$TASKCODE{$tskid} .= $indentstr;
+		$TASKCODE{$tskid} .= sprintf("check_ercd(ercd, E_OK);\n");
+	}
+	elsif ($error_code_string =~ /^\-\>\s*noreturn$/) {
+		# do nothing.
+	}
+	else {
+		$error_code = $error_code_string;
+		$error_code =~ s/^\-\>\s*([A-Z_]*)$/$1/;
+		$TASKCODE{$tskid} .= $indentstr;
+		$TASKCODE{$tskid} .= sprintf("check_ercd(ercd, %s);\n", $error_code);
+	}
+}
+
+sub parse_line {
+	local($line) = @_;
+
+	while ($line =~ s/\\$//) {
+		$line1 = <INFILE>;
+		chomp $line1;
+		$line1 =~ s/^\s*\*\s*//;
+		$line1 =~ s/\s*\/\/.*$//;
+		$line1 =~ s/\s*\.\.\..*$//;
+		$line .= $line1;
+	}
+
+	if ($line =~ /^\.\./) {
+		# do nothing.
+	}
+	elsif ($line =~ /^==\s*((TASK|ALM|CPUEXC|EXTSVC)[0-9]*)(.*)$/) {
+		$startflag = 1;
+		$tskid = $1;
+		$line2 = $3;
+		if ($line2 =~ /^\-TEX(.*)$/) {
+			$tskid = $tskid."-TEX";
+			$line2 = $1;
+		}
+		if ($line2 =~ /^\-([0-9]+)(.*)$/) {
+			$tskcount = $1;
+			$line3 = $2;
+			$indentstr = "\t\t";
+			if (!$TASKCOUNT{$tskid}) {
+				$TASKCOUNT{$tskid} = 0;
+				if ($tskid =~ /^TASK([0-9]*)$/) {
+					$countvar = "task$1_count";
+				}
+				elsif ($tskid =~ /^TASK([0-9]*)-TEX$/) {
+					$countvar = "tex_task$1_count";
+				}
+				elsif ($tskid =~ /^ALM([0-9]*)$/) {
+					$countvar = "alarm$1_count";
+				}
+				elsif ($tskid =~ /^CPUEXC([0-9]*)$/) {
+					$countvar = "cpuexc$1_count";
+				}
+				elsif ($tskid =~ /^EXTSVC([0-9]*)$/) {
+					$countvar = "extsvc$1_count";
+				}
+				$TASKCOUNTVAR{$tskid} = $countvar;
+			}
+			if ($tskcount == $TASKCOUNT{$tskid} + 1) {
+				if ($tskcount > 1) {
+					$TASKCODE{$tskid} .= "\n".$indentstr;
+					$TASKCODE{$tskid} .= sprintf("check_point(0);\n\n");
+				}
+				$TASKCOUNT{$tskid} = $tskcount;
+				$TASKCODE{$tskid} .= sprintf("\tcase %d:", $tskcount);
+			}
+			elsif ($tskcount != $TASKCOUNT{$tskid} && $line3 !~ /^-/) {
+				printf STDERR "Subtask count error: %s-%s\n",$tskid,$tskcount;
+			}
+		}
+		else {
+			$tskcount = "";
+			$indentstr = "\t";
+		}
+	}
+	elsif (!$startflag) {
+		# do nothing.
+	}
+	elsif ($line =~ /^([0-9]+)\:\s*END$/) {
+		$check_no = $1;
+		$TASKCODE{$tskid} .= "\n".$indentstr;
+		$TASKCODE{$tskid} .= sprintf("check_finish(%d);\n", $check_no);
+		$endflag = 1;
+	}
+	else {
+		if ($line =~ /^([0-9]+)\:\s*(.*)/) {
+			$check_no = $1;
+			$line = $2;
+			$TASKCODE{$tskid} .= "\n".$indentstr;
+			$TASKCODE{$tskid} .= sprintf("check_point(%d);\n", $check_no);
+		}
+		if ($line =~ /^(assert\(.*\))$/) {
+			$assert_string = $1;
+			$TASKCODE{$tskid} .= $indentstr;
+			$TASKCODE{$tskid} .= sprintf("check_%s;\n", $assert_string);
+		}
+		elsif ($line =~ /^(state(_i)?\(.*\))$/) {
+			$state_string = $1;
+			$TASKCODE{$tskid} .= $indentstr;
+			$TASKCODE{$tskid} .= sprintf("check_%s;\n", $state_string);
+		}
+		elsif ($line =~ /^call\((.*)\)$/ || $line =~ /^DO\((.*)\)$/) {
+			$call_string = $1;
+			$TASKCODE{$tskid} .= "\n".$indentstr;
+			$TASKCODE{$tskid} .= sprintf("%s;\n", $call_string);
+		}
+		elsif ($line =~ /^MISSING$/) {
+			# do nothing.
+		}
+		elsif ($line =~ /^RETURN((\(.*\))?)$/) {
+			$return_string = $1;
+			$TASKCODE{$tskid} .= "\n".$indentstr;
+			$TASKCODE{$tskid} .= "return".$return_string.";\n";
+		}
+		elsif ($line =~ /^GOTO\((.*)\)$/) {
+			$goto_string = $1;
+			$TASKCODE{$tskid} .= "\n".$indentstr;
+			$TASKCODE{$tskid} .= sprintf("goto %s;\n", $goto_string);
+		}
+		elsif ($line =~ /^LABEL\((.*)\)$/) {
+			$label_string = $1;
+			$indent_string = $indentstr;
+			$indent_string =~ s/\t$//;
+			$TASKCODE{$tskid} .= "\n".$indent_string;
+			$TASKCODE{$tskid} .= sprintf("%s:", $label_string);
+		}
+		elsif ($line =~ /^([a-z_]+\(.*\))\s*(\-\>\s*[A-Za-z_]*)?\s*$/) {
+			$svc_call = $1;
+			$error_code_string = $2;
+			$TASKCODE{$tskid} .= "\n";
+			gen_svc_call($svc_call, $error_code_string);
+		}
+		else {
+			print STDERR "Error: ",$line,"\n";
+		}
+	}
+}
+
+#
+#  XNvgt@CÇÝ
+#
+$startflag = 0;
+$endflag = 0;
+open(INFILE, $infile) || die "Cannot open $infile";
+while (($line = <INFILE>) && !$endflag) {
+	chomp $line;
+	$line =~ s/^\s*\*\s*//;
+	$line =~ s/\s*\/\/.*$//;
+	$line =~ s/\s*\.\.\..*$//;
+	next unless($line);
+	parse_line($line);
+}
+close(INFILE);
+
+#
+#  ^XNR[hÌoÍ
+#
+sub output_task {
+	if ($TASKCOUNT{$tskid}) {
+		printf "\nstatic uint_t\t%s = 0;\n", $TASKCOUNTVAR{$tskid};
+	}
+	if ($tskid =~ /^TASK([0-9]*)$/) {
+		print "\nvoid\n";
+		print "task$1(intptr_t exinf)\n";
+	}
+	elsif ($tskid =~ /^TASK([0-9]*)-TEX$/) {
+		print "\nvoid\n";
+		print "tex_task$1(TEXPTN texptn, intptr_t exinf)\n";
+	}
+	elsif ($tskid =~ /^ALM([0-9]*)$/) {
+		print "\nvoid\n";
+		print "alarm$1_handler(intptr_t exinf)\n";
+	}
+	elsif ($tskid =~ /^CPUEXC([0-9]*)$/) {
+		print "\nvoid\n";
+		print "cpuexc$1_handler(void *p_excinf)\n";
+	}
+	elsif ($tskid =~ /^EXTSVC([0-9]*)$/) {
+		print "\nER_UINT\n";
+		print "extsvc$1_routine(intptr_t par1, intptr_t par2, intptr_t par3,\n";
+		print "\t\t\t\t\t\t\t\tintptr_t par4, intptr_t par5, ID cdmid)\n";
+	}
+	print "{\n";
+	print "\tER\t\tercd;\n";
+	foreach $typename (keys(%{$TASKVAR{$tskid}})) {
+		print "\t",$typename, (length($typename) < 4 ? "\t\t" : "\t"),
+								${$TASKVAR{$tskid}}{$typename},";\n";
+	}
+	if ($TASKCOUNT{$tskid}) {
+		printf "\n\tswitch (++%s) {\n", $TASKCOUNTVAR{$tskid};
+	}
+	print $TASKCODE{$tskid};
+	if ($TASKCOUNT{$tskid}) {
+		printf "\n\t\tcheck_point(0);\n";
+		printf "\t}\n";
+	}
+	else {
+		print "\n";
+	}
+	print "\tcheck_point(0);\n";
+	if ($tskid =~ /^EXTSVC([0-9]*)$/) {
+		print "\treturn(E_SYS);\n";
+	}
+	print "}\n";
+}
+
+#
+#  eXgvOoÍ
+#
+foreach $tskid (sort(keys(%TASKCODE))) {
+	output_task();
+}
Index: UsbWattMeter/trunk/asp_dcre/utils/makedep
===================================================================
--- UsbWattMeter/trunk/asp_dcre/utils/makedep	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/utils/makedep	(revision 164)
@@ -0,0 +1,183 @@
+#! /usr/bin/perl
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2004-2011 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+#  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+#  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+#  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+#       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+#      XR[hÉÜÜêÄ¢é±ÆD
+#  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+#      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+#      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+#      Ì³ÛØKèðfÚ·é±ÆD
+#  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+#      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+#      ÆD
+#    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+#        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+#    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+#        ñ·é±ÆD
+#  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+#      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+#      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+#      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+#      ÆÓ·é±ÆD
+# 
+#  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+#  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+#  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+#  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+#  ÌÓCðíÈ¢D
+# 
+#  @(#) $Id: makedep 2264 2011-10-27 04:22:01Z ertl-hiro $
+# 
+
+use Getopt::Std;
+
+#  IvVÌè`
+#
+#  -C <cc_path>		CRpCÌR}h¼
+#  -O <cc_opts>		CRpC/CPPÉn·IvV
+#  -X				\[Xt@Cð­§IÉCwb_t@CÆ©È·
+#
+#  -T <target>		^[Qbg¼iÌXgj
+#  -D <t_dir>		^[QbgÌfBNg¼ðwè·éi-Tðp¢½ê
+#					Í³øj
+#  -d				^[QbgÌfBNgðÛ·éi-Tðp¢½ê
+#					Í³øj
+#  -S				¡Ì^[Qbgª éË¶[ðC^[QbgÉ
+#					ª·éi±¤µÈ¢ÆÎÅ«È¢makeª éçµ¢j
+#
+#  -R <dirname>		CygwinÂ«É¨¯é[gfBNg¼ðwè·é
+#					iftHgÍcygdrivej
+
+#
+#  IvVÌ
+#
+getopt("COTDR");
+
+$cc_path = $opt_C;
+$cc_opts = $opt_O;
+
+if ($opt_T) {
+	$target_name = $opt_T;
+}
+elsif ($opt_D) {
+	$target_dir = $opt_D;
+}
+elsif (!$opt_d) {
+	$target_dir = "";
+}
+
+if ($opt_R) {
+	$cygwin_root = $opt_R;
+}
+else {
+	$cygwin_root = "cygdrive";
+}
+
+#
+#  CygwinÂ«Ì»Ê
+#
+if ($^O eq 'cygwin') {
+	$cygwin = 1;
+}
+
+#
+#  %dependlist Éìçê½Ë¶ÖWðoÍ·é
+#
+sub output_dependlist {
+	local($target) = @_;
+	local($column, $len, $file);
+
+	print $target, ": ";
+	$column = length($target) + 2;
+
+	foreach $file (keys(%dependlist)) {
+		$len = length($file) + 1;
+		if ($column > 8 && $column + $len >= 70) {
+			print "\\\n\t";
+			$column = 8;
+		}
+		$column += $len;
+		print "$file ";
+	}
+	print "\n";
+}
+
+#
+#  $file ÌË¶ÖWð %dependlist Éìé
+#
+sub makedepend_one {
+	local($file) = @_;
+	local($command, $input, $dir, $filename);
+
+	$command = "$cc_path -E $cc_opts";
+	if ($opt_X) {
+		$command .= " -x c-header";
+	}
+	unless (open(INPUT, "$command $file |")) {
+		print STDERR "makedep: can't open $file\n";
+		exit(1);
+	}
+	while ($line = <INPUT>) {
+		if ($line =~ /^\#\s*([0-9]+)\s*\"([^\"]+)\"/) {
+			$filename = $2;
+			$filename =~ s/ /\\ /g;
+			if ($filename !~ /^\<.*\>$/ && $filename !~ /\/$/) {
+				if ($cygwin) {
+					$filename =~ s/\\\\/\//g;
+					$filename =~ s/^([a-zA-Z]):/\/$cygwin_root\/$1/;
+				}
+				$dependlist{$filename} = 1;
+			}
+		}
+	}
+	unless (close(INPUT)) {
+		print STDERR "makedep: can't execute $command\n";
+		exit(1);
+	}
+}
+
+#
+#  C[`
+#
+foreach $file (@ARGV) {
+	%dependlist = ();
+	makedepend_one($file);
+	if (%dependlist) {
+		if ($target_name) {
+			if ($opt_S) {
+				foreach $target (split(/[ \t]+/, $target_name)) {
+					output_dependlist($target);
+				}
+			}
+			else {
+				output_dependlist($target_name);
+			}
+		}
+		else {
+			$target = $file;
+			$target =~ s/(.*)\.(.*)/$1.o/;
+			if (defined($target_dir)) {
+				$target =~ s/^.*\/([^\/]+)$/$1/;
+				if ($target_dir) {
+					$target = $target_dir."/".$target;
+				}
+			}
+			output_dependlist($target);
+		}
+	}
+}
Index: UsbWattMeter/trunk/asp_dcre/utils/makerelease
===================================================================
--- UsbWattMeter/trunk/asp_dcre/utils/makerelease	(revision 164)
+++ UsbWattMeter/trunk/asp_dcre/utils/makerelease	(revision 164)
@@ -0,0 +1,160 @@
+#! /usr/bin/perl
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2006-2011 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+# 
+#  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+#  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+#  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+#  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+#       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+#      XR[hÉÜÜêÄ¢é±ÆD
+#  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+#      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+#      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+#      Ì³ÛØKèðfÚ·é±ÆD
+#  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+#      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+#      ÆD
+#    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+#        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+#    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+#        ñ·é±ÆD
+#  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+#      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+#      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+#      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+#      ÆÓ·é±ÆD
+# 
+#  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+#  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+#  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+#  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+#  ÌÓCðíÈ¢D
+# 
+#  @(#) $Id: makerelease 2253 2011-09-11 01:23:40Z ertl-hiro $
+# 
+
+require 'getcwd.pl';
+
+$cwd = getcwd();
+$cwd =~ s/^.*[\/\\]([^\/\\]+)$/$1/;
+$prefix = "./".$cwd;
+
+@file_list = ();
+%file_list = ();
+
+if ($#ARGV >= 0) {
+	$arg1 = $ARGV[0];
+	$arg1 =~ s/\.\///;
+}
+else {
+	$arg1 = "MANIFEST";
+}
+
+sub gen_path
+{
+	local($base, $path) = @_;
+
+	while ($path =~ /^..\/(.*)$/) {
+		$path = $1;
+		$base =~ s/(\/?)[^\/]*\/$/$1/;
+	}
+	return($base.$path);
+}
+
+sub read_file {
+	local($filename) = @_;
+	local($fh, $dirname);
+
+	if ($filename =~ /^(.*\/)[^\/]*$/) {
+		$dirname = $1;
+	}
+	else {
+		$dirname = "";
+	}
+
+	open($fh, $filename) || die "Cannot open $filename";
+	while ($line = <$fh>) {
+		chomp $line;
+		$line =~ s/\r$//;
+		$line =~ s/[ \t]*\#.*$//;
+		next if ($line =~ /^[ \t]*$/);
+
+		if ($line =~ /^E_PACKAGE[ \t]+(.*)$/) {
+			if ($package) {
+				die "Duplicated E_PACKAGE directive.";
+			}
+			else {
+				$package = $1;
+				$e_package = 1;
+			}
+		}
+		elsif ($line =~ /^PACKAGE[ \t]+(.*)$/) {
+			if ($package) {
+				if (!$e_package && $package != $1) {
+					die "Inconsistent PACKAGE directive.";
+				}
+			}
+			else {
+				$package = $1;
+			}
+		}
+		elsif ($line =~ /^VERSION[ \t]+(.*)$/) {
+			if ($version) {
+				if (!$e_package && $version != $1) {
+					die "Inconsistent VERSION directive.";
+				}
+			}
+			else {
+				$version = $1;
+				if ($version =~ /%date/) {
+					@current_time = localtime();
+					$vdate = sprintf("%04d%02d%02d", $current_time[5]+1900,
+										$current_time[4]+1, $current_time[3]);
+					$version =~ s/%date/$vdate/;
+				}
+			}
+		}
+		elsif ($line =~ /^INCLUDE[ \t]+(.*)$/) {
+			read_file(gen_path($dirname, $1));
+		}
+		else {
+			$filename = $prefix."/".$dirname.$line;
+			while ($filename =~ s|/[^/]+/\.\./|/|) {}
+			if ($file_list{$filename}) {
+				die "$filename is duplicated.";
+			}
+			else {
+				push(@file_list, $filename);
+				$file_list{$filename} = $filename;
+			}
+		}
+	}
+	close($fh);
+}
+
+read_file($arg1);
+unless ($package) {
+	die "PACKAGE/E_PACKAGE directive not found.";
+}
+unless ($version) {
+	die "VERSION directive not found.";
+}
+
+if (! -d "RELEASE") {
+	mkdir("RELEASE");
+}
+
+$archive_name = $package."-".$version.".tar.gz";
+$file_list = join(" ", @file_list);
+$command = "tar cvfz RELEASE/$archive_name -C .. $file_list\n";
+die if (system($command));
+print STDERR "== RELEASE/$archive_name is generated. ==\n";
Index: UsbWattMeter/trunk/csp/libasp/asm_config.inc
===================================================================
--- UsbWattMeter/trunk/csp/libasp/asm_config.inc	(revision 164)
+++ UsbWattMeter/trunk/csp/libasp/asm_config.inc	(revision 164)
@@ -0,0 +1,15 @@
+TIPM_LOCK 		 .equ 	 -15 
+IPL_LOCK 		 .equ 	 251658240 
+PSW_I_MASK 		 .equ 	 65536 
+PSW_IPL_MASK 		 .equ 	 251658240 
+EXC_GET_PSW_OFFSET 		 .equ 	 80 
+
+
+LOG_INH_ENTER_ENABLE 	 .equ 	 0 
+LOG_INH_LEAVE_ENABLE 	 .equ 	 0 
+LOG_EXC_ENTER_ENABLE 	 .equ 	 0 
+LOG_EXC_LEAVE_ENABLE 	 .equ 	 0 
+LOG_DSP_ENTER_ENABLE 	 .equ 	 0 
+LOG_DSP_LEAVE_ENABLE 	 .equ 	 0 
+SIL_DLY_TIM1 	 .equ 	 69 
+SIL_DLY_TIM2 	 .equ 	 50 
Index: UsbWattMeter/trunk/csp/libasp/cfg/cfg.mtsp
===================================================================
--- UsbWattMeter/trunk/csp/libasp/cfg/cfg.mtsp	(revision 164)
+++ UsbWattMeter/trunk/csp/libasp/cfg/cfg.mtsp	(revision 164)
@@ -0,0 +1,1172 @@
+<CubeSuiteProject>
+  <ProductVersion>4.02.00.00</ProductVersion>
+  <Class Guid="68f4a651-b9cd-473b-a595-b00447132ffa">
+    <Instance Guid="00000000-0000-0000-0000-000000000000">
+      <FormatVersion>2.0</FormatVersion>
+      <FileVersion>4.2</FileVersion>
+      <ProjectGuid>c170030b-b19d-470a-99cb-00eb1a66ac6b</ProjectGuid>
+      <ProjectItemGuid>e7b5b09e-b638-4529-91de-eb34915bbeb7</ProjectItemGuid>
+      <FileCategoryGuid>479fec8d-854b-4e39-83c6-c84e8b20ea01</FileCategoryGuid>
+      <Property>fb98844b-2c27-4275-9804-f6e63e204da0</Property>
+    </Instance>
+    <Instance Guid="2663a3a4-1aa9-423b-8114-929eeb0f323e">
+      <Name>cfg1_out.c</Name>
+      <Type>File</Type>
+      <RelativePath>cfg1_out.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>479fec8d-854b-4e39-83c6-c84e8b20ea01</ParentItem>
+    </Instance>
+    <Instance Guid="d3775719-f1c8-4906-8da0-338d3f5fccfe">
+      <Name>makeoffset.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\..\asp_dcre\arch\rx630_ccrx\makeoffset.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>479fec8d-854b-4e39-83c6-c84e8b20ea01</ParentItem>
+    </Instance>
+  </Class>
+  <Class Guid="fb98844b-2c27-4275-9804-f6e63e204da0">
+    <Instance Guid="2a349cb6-b982-4ade-adcd-104b883ad81c">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="8fb9c1f6-d351-4d10-8d99-bf5b3015b84c">
+    <Instance Guid="00000000-0000-0000-0000-000000000000">
+      <UsingPlatformGuid>500ba51a-4219-4828-b4be-80f54d6d3551</UsingPlatformGuid>
+      <UsingPlatformTypeGuid>f96683fa-8de4-4c6d-a1ab-925d7f232c09</UsingPlatformTypeGuid>
+    </Instance>
+  </Class>
+  <Class Guid="c325714f-8f51-484b-9e96-b4b59c0fb263">
+    <Instance Guid="c325714f-8f51-484b-9e96-b4b59c0fb263">
+      <DeviceManager>0e793ff3-2e3f-43c0-bdc9-926269595403</DeviceManager>
+    </Instance>
+  </Class>
+  <Class Guid="0e793ff3-2e3f-43c0-bdc9-926269595403">
+    <Instance Guid="0e793ff3-2e3f-43c0-bdc9-926269595403">
+      <DataFormatVersion>1.0</DataFormatVersion>
+    </Instance>
+    <Instance Guid="2a81c37a-5015-44c2-9f40-e58b669eec75">
+      <DeviceName>R5F563NBDxFP</DeviceName>
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="873c9a58-9bc5-439a-b476-78629a4553ed">
+    <Instance Guid="873c9a58-9bc5-439a-b476-78629a4553ed">
+      <ProjectDeviceChangedCounter>0</ProjectDeviceChangedCounter>
+      <ProjectInitialDeviceName>R5F563NBDxFP</ProjectInitialDeviceName>
+    </Instance>
+  </Class>
+  <Class Guid="c3835e31-dea3-4c93-b02b-d2db997f7630">
+    <Instance Guid="c3835e31-dea3-4c93-b02b-d2db997f7630">
+      <BuildToolManager>3a79707d-5977-45f7-ac11-19c35e333132</BuildToolManager>
+    </Instance>
+  </Class>
+  <Class Guid="3a79707d-5977-45f7-ac11-19c35e333132">
+    <Instance Guid="3a79707d-5977-45f7-ac11-19c35e333132">
+      <DataFormatVersion>1.2</DataFormatVersion>
+      <BuildModeCount>1</BuildModeCount>
+      <BuildMode0>RABlAGYAYQB1AGwAdABCAHUAaQBsAGQA</BuildMode0>
+      <BatchBuildFlag0>False</BatchBuildFlag0>
+      <CurrentBuildMode>DefaultBuild</CurrentBuildMode>
+      <SourceItemGuid0>2663a3a4-1aa9-423b-8114-929eeb0f323e</SourceItemGuid0>
+      <SourceItemType0>CSource</SourceItemType0>
+      <SourceItemGuid1>d3775719-f1c8-4906-8da0-338d3f5fccfe</SourceItemGuid1>
+      <SourceItemType1>CSource</SourceItemType1>
+      <SourceItemCount>2</SourceItemCount>
+      <LastDeviceChangedCounter>0</LastDeviceChangedCounter>
+    </Instance>
+    <Instance Guid="9e208646-ccba-4100-a676-29b1efe6545f">
+      <AsmOptionInclude-DefaultValue />
+      <BuildMode-DefaultValue>DefaultBuild</BuildMode-DefaultValue>
+      <COptionInclude-DefaultValue />
+      <GeneralOptionIsa-DefaultValue>RXv1</GeneralOptionIsa-DefaultValue>
+      <GeneralOptionOutput-DefaultValue>LoadModuleFile</GeneralOptionOutput-DefaultValue>
+      <GeneralOptionPic-DefaultValue>False</GeneralOptionPic-DefaultValue>
+      <GeneralOptionSimultaneousBuild-DefaultValue>True</GeneralOptionSimultaneousBuild-DefaultValue>
+      <HexOptionOutput-DefaultValue>True</HexOptionOutput-DefaultValue>
+      <LibOptionDebug-DefaultValue>Debug</LibOptionDebug-DefaultValue>
+      <LinkOptionLibrary-DefaultValue />
+      <Memo-DefaultValue />
+      <OutputMessageFormat-DefaultValue>%TargetFiles%</OutputMessageFormat-DefaultValue>
+      <AsmOptionSystemInclude-DefaultValue />
+      <COptionSystemInclude-DefaultValue />
+      <CompilerVersion-DefaultValue>
+
+0</CompilerVersion-DefaultValue>
+      <DependencyFileExistCheckingType-DefaultValue>Rebuild</DependencyFileExistCheckingType-DefaultValue>
+      <FormatBuildOptionList-DefaultValue>%TargetFiles% : %Program% %Options%</FormatBuildOptionList-DefaultValue>
+      <GeneralOptionCpu-DefaultValue>RX600</GeneralOptionCpu-DefaultValue>
+      <GeneralOptionOutputFolder-DefaultValue>%BuildModeName%</GeneralOptionOutputFolder-DefaultValue>
+      <GeneralOptionPid-DefaultValue>None</GeneralOptionPid-DefaultValue>
+      <HexOptionForm-DefaultValue>Stype</HexOptionForm-DefaultValue>
+      <LinkOptionDebug-DefaultValue>Debug</LinkOptionDebug-DefaultValue>
+      <AsmOptionDefine-DefaultValue />
+      <COptionDefine-DefaultValue />
+      <EnsureCompatibilityOfPathAndLinkageOrder-DefaultValue>False</EnsureCompatibilityOfPathAndLinkageOrder-DefaultValue>
+      <GeneralOptionFpu-DefaultValue>Auto</GeneralOptionFpu-DefaultValue>
+      <GeneralOptionNousePidRegister-DefaultValue>True</GeneralOptionNousePidRegister-DefaultValue>
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionOptimize-DefaultValue>None</LinkOptionOptimize-DefaultValue>
+      <AsmOptionDebug-DefaultValue>True</AsmOptionDebug-DefaultValue>
+      <COptionDebug-DefaultValue>True</COptionDebug-DefaultValue>
+      <GeneralOptionEndian-DefaultValue>Little</GeneralOptionEndian-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionOptimizeSymbolDelete-DefaultValue>False</LinkOptionOptimizeSymbolDelete-DefaultValue>
+      <PreBuildCommands-DefaultValue />
+      <AsmOptionGoptimize-DefaultValue>False</AsmOptionGoptimize-DefaultValue>
+      <COptionOptimize-DefaultValue>Level2</COptionOptimize-DefaultValue>
+      <GeneralOptionRound-DefaultValue>Nearest</GeneralOptionRound-DefaultValue>
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionOptimizeSameCode-DefaultValue>False</LinkOptionOptimizeSameCode-DefaultValue>
+      <PostBuildCommands-DefaultValue />
+      <AsmOptionListFile-DefaultValue>False</AsmOptionListFile-DefaultValue>
+      <COptionGoptimize-DefaultValue>False</COptionGoptimize-DefaultValue>
+      <GeneralOptionDenormalize-DefaultValue>Off</GeneralOptionDenormalize-DefaultValue>
+      <LinkOptionSameSize-DefaultValue>1E</LinkOptionSameSize-DefaultValue>
+      <AsmOptionShowConditionals-DefaultValue>False</AsmOptionShowConditionals-DefaultValue>
+      <COptionSpeedAndSize-DefaultValue>Size</COptionSpeedAndSize-DefaultValue>
+      <GeneralOptionDblSize-DefaultValue>SinglePrecision</GeneralOptionDblSize-DefaultValue>
+      <LinkOptionOptimizeShortFormat-DefaultValue>False</LinkOptionOptimizeShortFormat-DefaultValue>
+      <AsmOptionShowDefinitions-DefaultValue>False</AsmOptionShowDefinitions-DefaultValue>
+      <COptionListfile-DefaultValue>False</COptionListfile-DefaultValue>
+      <GeneralOptionIntToShort-DefaultValue>False</GeneralOptionIntToShort-DefaultValue>
+      <LinkOptionOptimizeBranch-DefaultValue>False</LinkOptionOptimizeBranch-DefaultValue>
+      <AsmOptionShowExpansions-DefaultValue>False</AsmOptionShowExpansions-DefaultValue>
+      <COptionShowSource-DefaultValue>False</COptionShowSource-DefaultValue>
+      <GeneralOptionSignedChar-DefaultValue>Unsigned</GeneralOptionSignedChar-DefaultValue>
+      <LinkOptionStart-DefaultValue>B_1,R_1,B_2,R_2,B,R,SU,SI/04,PResetPRG/0FFFF8000,C_1,C_2,C,C$DSEC,C$BSEC,C$INIT,C$VTBL,C$VECT,D_1,D_2,D,P,PIntPRG,W_1,W_2,W,L/0FFFF8100,FIXEDVECT/0FFFFFFD0</LinkOptionStart-DefaultValue>
+      <COptionShowConditionals-DefaultValue>False</COptionShowConditionals-DefaultValue>
+      <GeneralOptionOtherAdditionalOptions-DefaultValue />
+      <GeneralOptionSignedBitfield-DefaultValue>Unsigned</GeneralOptionSignedBitfield-DefaultValue>
+      <COptionShowDefinitions-DefaultValue>False</COptionShowDefinitions-DefaultValue>
+      <GeneralOptionAutoEnum-DefaultValue>False</GeneralOptionAutoEnum-DefaultValue>
+      <COptionShowExpansions-DefaultValue>False</COptionShowExpansions-DefaultValue>
+      <GeneralOptionBitOrder-DefaultValue>Right</GeneralOptionBitOrder-DefaultValue>
+      <GeneralOptionPack-DefaultValue>False</GeneralOptionPack-DefaultValue>
+      <GeneralOptionException-DefaultValue>False</GeneralOptionException-DefaultValue>
+      <GeneralOptionRtti-DefaultValue>False</GeneralOptionRtti-DefaultValue>
+      <GeneralOptionFintRegister-DefaultValue>None</GeneralOptionFintRegister-DefaultValue>
+      <GeneralOptionBranch-DefaultValue>Branch24</GeneralOptionBranch-DefaultValue>
+      <GeneralOptionBaseRomRegister-DefaultValue>None</GeneralOptionBaseRomRegister-DefaultValue>
+      <GeneralOptionBaseRamRegister-DefaultValue>None</GeneralOptionBaseRamRegister-DefaultValue>
+      <GeneralOptionBaseAddressAddress-DefaultValue>00000000</GeneralOptionBaseAddressAddress-DefaultValue>
+      <GeneralOptionBaseAddressRegister-DefaultValue>None</GeneralOptionBaseAddressRegister-DefaultValue>
+      <GeneralOptionPatch-DefaultValue>None</GeneralOptionPatch-DefaultValue>
+      <GeneralOptionSaveAcc-DefaultValue>False</GeneralOptionSaveAcc-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587442586619935989</TimeTagModified--0>
+      <BuildMode-0>DefaultBuild</BuildMode-0>
+      <Memo-0 />
+      <OutputMessageFormat-0>%TargetFiles%</OutputMessageFormat-0>
+      <FormatBuildOptionList-0>%TargetFiles% : %Program% %Options%</FormatBuildOptionList-0>
+      <PreBuildCommands-0>if exist "%OutputDir%\%ProjectName%.syms" del "%OutputDir%\%ProjectName%.syms"
+..\..\..\asp_dcre\cfg\cfg\cfg.exe --pass 1 --kernel asp_dcre --api-table ..\..\..\asp_dcre\kernel\kernel_api.csv --cfg1-def-table ..\..\..\asp_dcre\kernel\kernel_def.csv --cfg1-def-table ..\..\..\asp_dcre\arch\rx630_ccrx\prc_def.csv --cfg1-def-table ..\..\..\asp_dcre\target\grsakura_ccrx\target_def.csv -I ..\..\..\asp_dcre -I ..\..\..\asp_dcre\arch -I ..\..\..\asp_dcre\include -I ..\..\..\asp_dcre\target\grsakura_ccrx ..\dummy.cfg
+</PreBuildCommands-0>
+      <PostBuildCommands-0>..\..\..\asp_dcre\arch\ccrx\gensyms.exe "%OutputDir%\%ProjectName%.map"
+%WinDir%\cscript //Nologo ..\..\tools\update.js "%OutputDir%\%ProjectName%.mot" cfg1_out.srec
+..\..\..\asp_dcre\cfg\cfg\cfg.exe --pass 2 --kernel asp_dcre --api-table ..\..\..\asp_dcre\kernel\kernel_api.csv --cfg1-def-table ..\..\..\asp_dcre\kernel\kernel_def.csv --cfg1-def-table ..\..\..\asp_dcre\arch\rx630_ccrx\prc_def.csv --cfg1-def-table ..\..\..\asp_dcre\target\grsakura_ccrx\target_def.csv -I ..\..\..\asp_dcre -I ..\..\..\asp_dcre\arch -I ..\..\..\asp_dcre\arch\rx630_ccrx -I ..\..\..\asp_dcre\include -I ..\..\..\asp_dcre\kernel -I ..\..\..\asp_dcre\target\grsakura_ccrx --template-file ..\..\..\asp_dcre\target\grsakura_ccrx\target.tf ..\dummy.cfg
+..\..\..\asp_dcre\cfg\cfg\cfg.exe --pass 3 --kernel asp_dcre --api-table ..\..\..\asp_dcre\kernel\kernel_api.csv --cfg1-def-table ..\..\..\asp_dcre\kernel\kernel_def.csv --cfg1-def-table ..\..\..\asp_dcre\arch\rx630_ccrx\prc_def.csv --cfg1-def-table ..\..\..\asp_dcre\target\grsakura_ccrx\target_def.csv -I ..\..\..\asp_dcre -I ..\..\..\asp_dcre\arch -I ..\..\..\asp_dcre\arch\rx630_ccrx -I ..\..\..\asp_dcre\include -I ..\..\..\asp_dcre\kernel -I ..\..\..\asp_dcre\target\grsakura_ccrx --template-file ..\..\..\asp_dcre\target\grsakura_ccrx\target_offset.tf --rom-image cfg1_out.srec --symbol-table cfg1_out.syms ..\dummy.cfg
+%WinDir%\cscript //Nologo ..\..\tools\DefToEqu.js offset.h offset.inc
+%WinDir%\cscript //Nologo ..\..\tools\cmp_update.js kernel_cfg.c ..\kernel_cfg.c
+%WinDir%\cscript //Nologo ..\..\tools\cmp_update.js kernel_cfg.h ..\kernel_cfg.h
+%WinDir%\cscript //Nologo ..\..\tools\cmp_update.js kernel_cfg_asm.src ..\kernel_cfg_asm.src
+%WinDir%\cscript //Nologo ..\..\tools\cmp_update.js asm_config.inc ..\asm_config.inc
+%WinDir%\cscript //Nologo ..\..\tools\cmp_update.js offset.h ..\offset.h
+%WinDir%\cscript //Nologo ..\..\tools\cmp_update.js offset.inc ..\offset.inc
+</PostBuildCommands-0>
+      <GeneralOptionIsa-0>None</GeneralOptionIsa-0>
+      <GeneralOptionOutput-0>LoadModuleFile</GeneralOptionOutput-0>
+      <GeneralOptionPic-0>False</GeneralOptionPic-0>
+      <GeneralOptionSimultaneousBuild-0>True</GeneralOptionSimultaneousBuild-0>
+      <CompilerVersion-0>
+
+0</CompilerVersion-0>
+      <DependencyFileExistCheckingType-0>Rebuild</DependencyFileExistCheckingType-0>
+      <GeneralOptionCpu-0>RX600</GeneralOptionCpu-0>
+      <GeneralOptionOutputFolder-0>%BuildModeName%</GeneralOptionOutputFolder-0>
+      <GeneralOptionPid-0>None</GeneralOptionPid-0>
+      <EnsureCompatibilityOfPathAndLinkageOrder-0>False</EnsureCompatibilityOfPathAndLinkageOrder-0>
+      <GeneralOptionFpu-0>Fpu</GeneralOptionFpu-0>
+      <GeneralOptionNousePidRegister-0>True</GeneralOptionNousePidRegister-0>
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <GeneralOptionEndian-0>Little</GeneralOptionEndian-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <AsmOptionGoptimize-0>False</AsmOptionGoptimize-0>
+      <GeneralOptionRound-0>Nearest</GeneralOptionRound-0>
+      <LinkOptionMultiConvertFileName-0 />
+      <AsmOptionListFile-0>False</AsmOptionListFile-0>
+      <COptionGoptimize-0>False</COptionGoptimize-0>
+      <GeneralOptionDenormalize-0>Off</GeneralOptionDenormalize-0>
+      <AsmOptionShowConditionals-0>False</AsmOptionShowConditionals-0>
+      <GeneralOptionDblSize-0>SinglePrecision</GeneralOptionDblSize-0>
+      <AsmOptionShowDefinitions-0>False</AsmOptionShowDefinitions-0>
+      <COptionListfile-0>False</COptionListfile-0>
+      <GeneralOptionIntToShort-0>False</GeneralOptionIntToShort-0>
+      <AsmOptionShowExpansions-0>False</AsmOptionShowExpansions-0>
+      <COptionShowSource-0>False</COptionShowSource-0>
+      <GeneralOptionSignedChar-0>Unsigned</GeneralOptionSignedChar-0>
+      <COptionShowConditionals-0>False</COptionShowConditionals-0>
+      <GeneralOptionOtherAdditionalOptions-0 />
+      <GeneralOptionSignedBitfield-0>Unsigned</GeneralOptionSignedBitfield-0>
+      <COptionShowDefinitions-0>False</COptionShowDefinitions-0>
+      <GeneralOptionAutoEnum-0>False</GeneralOptionAutoEnum-0>
+      <COptionShowExpansions-0>False</COptionShowExpansions-0>
+      <GeneralOptionBitOrder-0>Right</GeneralOptionBitOrder-0>
+      <GeneralOptionPack-0>False</GeneralOptionPack-0>
+      <GeneralOptionException-0>False</GeneralOptionException-0>
+      <GeneralOptionRtti-0>False</GeneralOptionRtti-0>
+      <GeneralOptionFintRegister-0>None</GeneralOptionFintRegister-0>
+      <GeneralOptionBranch-0>Branch24</GeneralOptionBranch-0>
+      <GeneralOptionBaseRomRegister-0>None</GeneralOptionBaseRomRegister-0>
+      <GeneralOptionBaseRamRegister-0>None</GeneralOptionBaseRamRegister-0>
+      <GeneralOptionBaseAddressAddress-0>00000000</GeneralOptionBaseAddressAddress-0>
+      <GeneralOptionBaseAddressRegister-0>None</GeneralOptionBaseAddressRegister-0>
+      <GeneralOptionPatch-0>None</GeneralOptionPatch-0>
+      <GeneralOptionSaveAcc-0>False</GeneralOptionSaveAcc-0>
+      <LastCompilerVersion-0>V2.02.00</LastCompilerVersion-0>
+    </Instance>
+    <Instance Guid="95a63257-4aa7-40c0-a74a-7991543b099b">
+      <COptionLangC-DefaultValue>C</COptionLangC-DefaultValue>
+      <COptionListfile-DefaultValue>False</COptionListfile-DefaultValue>
+      <COptionLogo-DefaultValue>False</COptionLogo-DefaultValue>
+      <COptionMisra2004-DefaultValue>None</COptionMisra2004-DefaultValue>
+      <COptionOptimize-DefaultValue>Level2</COptionOptimize-DefaultValue>
+      <COptionOutput-DefaultValue>Object</COptionOutput-DefaultValue>
+      <COptionOutputAssembly-DefaultValue>False</COptionOutputAssembly-DefaultValue>
+      <COptionGoptimize-DefaultValue>False</COptionGoptimize-DefaultValue>
+      <COptionLangCpp-DefaultValue>Cpp</COptionLangCpp-DefaultValue>
+      <COptionMisra2004RuleFile-DefaultValue />
+      <COptionOutputFolder-DefaultValue>%BuildModeName%</COptionOutputFolder-DefaultValue>
+      <COptionOutputPreprocessed-DefaultValue>None</COptionOutputPreprocessed-DefaultValue>
+      <COptionShowSource-DefaultValue>False</COptionShowSource-DefaultValue>
+      <COptionXcref-DefaultValue>False</COptionXcref-DefaultValue>
+      <COptionDebug-DefaultValue>True</COptionDebug-DefaultValue>
+      <COptionInclude-DefaultValue />
+      <COptionMisra2004RuleNumberApply-DefaultValue />
+      <COptionPreCompileCommands-DefaultValue />
+      <COptionShowConditionals-DefaultValue>False</COptionShowConditionals-DefaultValue>
+      <COptionSpeedAndSize-DefaultValue>Size</COptionSpeedAndSize-DefaultValue>
+      <COptionLoop-DefaultValue>Auto</COptionLoop-DefaultValue>
+      <COptionMisra2004RuleNumberIgnore-DefaultValue />
+      <COptionPostCompileCommands-DefaultValue />
+      <COptionSectionP-DefaultValue>P</COptionSectionP-DefaultValue>
+      <COptionShowDefinitions-DefaultValue>False</COptionShowDefinitions-DefaultValue>
+      <COptionSystemInclude-DefaultValue />
+      <COptionLoopValue-DefaultValue>2</COptionLoopValue-DefaultValue>
+      <COptionMisra2004RuleNumberRequiredAdd-DefaultValue />
+      <COptionOtherAdditionalOptions-DefaultValue />
+      <COptionPreinclude-DefaultValue />
+      <COptionSectionC-DefaultValue>C</COptionSectionC-DefaultValue>
+      <COptionShowExpansions-DefaultValue>False</COptionShowExpansions-DefaultValue>
+      <COptionCommandLine-DefaultValue>-isa=rxv1
+-include=..\..\..\asp_dcre
+-include=..\..\..\asp_dcre\arch
+-include=..\..\..\asp_dcre\include
+-include=..\..\..\asp_dcre\kernel
+-include=..\..\..\asp_dcre\arch
+-include=..\..\..\asp_dcre\syssvc
+-include=..\..\..\asp_dcre\library
+-include=..\..\..\asp_dcre\pdic
+-include=..\..\..\asp_dcre\target\grsakura_ccrx
+-include=..
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-fpu
+-nologo
+</COptionCommandLine-DefaultValue>
+      <COptionDefine-DefaultValue />
+      <COptionInline-DefaultValue>Auto</COptionInline-DefaultValue>
+      <COptionMisra2004RuleNumberRequiredRemove-DefaultValue />
+      <COptionSectionD-DefaultValue>D</COptionSectionD-DefaultValue>
+      <COptionIgnoreFilesMisra-DefaultValue />
+      <COptionInlineValue-DefaultValue>100</COptionInlineValue-DefaultValue>
+      <COptionSectionB-DefaultValue>B</COptionSectionB-DefaultValue>
+      <COptionUndefine-DefaultValue />
+      <COptionCheckLanguageExtension-DefaultValue>False</COptionCheckLanguageExtension-DefaultValue>
+      <COptionFileInline-DefaultValue />
+      <COptionMessage-DefaultValue>False</COptionMessage-DefaultValue>
+      <COptionSectionL-DefaultValue>L</COptionSectionL-DefaultValue>
+      <COptionCase-DefaultValue>Auto</COptionCase-DefaultValue>
+      <COptionMessage2-DefaultValue>False</COptionMessage2-DefaultValue>
+      <COptionSectionW-DefaultValue>W</COptionSectionW-DefaultValue>
+      <COptionNoMessageErrorNumber-DefaultValue />
+      <COptionNostuffB-DefaultValue>False</COptionNostuffB-DefaultValue>
+      <COptionVolatile-DefaultValue>False</COptionVolatile-DefaultValue>
+      <COptionConstCopy-DefaultValue>Auto</COptionConstCopy-DefaultValue>
+      <COptionNoMessageErrorNumber2-DefaultValue />
+      <COptionNostuffD-DefaultValue>False</COptionNostuffD-DefaultValue>
+      <COptionChangeMessageInformation-DefaultValue>No</COptionChangeMessageInformation-DefaultValue>
+      <COptionConstDiv-DefaultValue>Auto</COptionConstDiv-DefaultValue>
+      <COptionNostuffC-DefaultValue>False</COptionNostuffC-DefaultValue>
+      <COptionChangeMessageInformationNumber-DefaultValue />
+      <COptionLibrary-DefaultValue>Intrinsic</COptionLibrary-DefaultValue>
+      <COptionNostuffW-DefaultValue>False</COptionNostuffW-DefaultValue>
+      <COptionChangeMessageInformationNumber2-DefaultValue />
+      <COptionInstalign-DefaultValue>Noinstalign</COptionInstalign-DefaultValue>
+      <COptionScope-DefaultValue>Auto</COptionScope-DefaultValue>
+      <COptionChangeMessageWarning-DefaultValue>No</COptionChangeMessageWarning-DefaultValue>
+      <COptionNouseDiv-DefaultValue>True</COptionNouseDiv-DefaultValue>
+      <COptionSchedule-DefaultValue>Auto</COptionSchedule-DefaultValue>
+      <COptionChangeMessageWarningNumber-DefaultValue />
+      <COptionMap-DefaultValue>NoMap</COptionMap-DefaultValue>
+      <COptionOutcode-DefaultValue>Sjis</COptionOutcode-DefaultValue>
+      <COptionChangeMessageWarningNumber2-DefaultValue />
+      <COptionIntermodule-DefaultValue>None</COptionIntermodule-DefaultValue>
+      <COptionApproxdiv-DefaultValue>False</COptionApproxdiv-DefaultValue>
+      <COptionChangeMessageError-DefaultValue>No</COptionChangeMessageError-DefaultValue>
+      <COptionChangeMessageErrorNumber-DefaultValue />
+      <COptionEnableRegister-DefaultValue>False</COptionEnableRegister-DefaultValue>
+      <COptionChangeMessageErrorNumber2-DefaultValue />
+      <COptionSimpleFloatConv-DefaultValue>False</COptionSimpleFloatConv-DefaultValue>
+      <COptionFileInlinePath-DefaultValue />
+      <COptionFpu-DefaultValue>Fpu</COptionFpu-DefaultValue>
+      <COptionAlias-DefaultValue>False</COptionAlias-DefaultValue>
+      <COptionComment-DefaultValue>False</COptionComment-DefaultValue>
+      <COptionCheck-DefaultValue>No</COptionCheck-DefaultValue>
+      <COptionFloatOrder-DefaultValue>False</COptionFloatOrder-DefaultValue>
+      <COptionIncode-DefaultValue>Sjis</COptionIncode-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588050931703493217</TimeTagModified--0>
+      <COptionLangC-0>C99</COptionLangC-0>
+      <COptionListfile-0>False</COptionListfile-0>
+      <COptionLogo-0>False</COptionLogo-0>
+      <COptionMisra2004-0>None</COptionMisra2004-0>
+      <COptionOptimize-0>Level2</COptionOptimize-0>
+      <COptionOutput-0>Object</COptionOutput-0>
+      <COptionOutputAssembly-0>False</COptionOutputAssembly-0>
+      <COptionGoptimize-0>False</COptionGoptimize-0>
+      <COptionLangCpp-0>Cpp</COptionLangCpp-0>
+      <COptionMisra2004RuleFile-0 />
+      <COptionOutputFolder-0>%BuildModeName%</COptionOutputFolder-0>
+      <COptionOutputPreprocessed-0>None</COptionOutputPreprocessed-0>
+      <COptionShowSource-0>False</COptionShowSource-0>
+      <COptionXcref-0>False</COptionXcref-0>
+      <COptionDebug-0>True</COptionDebug-0>
+      <COptionInclude-0>..\..\..\asp_dcre
+..\..\..\asp_dcre\arch
+..\..\..\asp_dcre\include
+..\..\..\asp_dcre\kernel
+..\..\..\asp_dcre\arch
+..\..\..\asp_dcre\syssvc
+..\..\..\asp_dcre\library
+..\..\..\asp_dcre\pdic
+..\..\..\asp_dcre\target\grsakura_ccrx
+..
+</COptionInclude-0>
+      <COptionMisra2004RuleNumberApply-0 />
+      <COptionPreCompileCommands-0 />
+      <COptionShowConditionals-0>False</COptionShowConditionals-0>
+      <COptionSpeedAndSize-0>Size</COptionSpeedAndSize-0>
+      <COptionLoop-0>Auto</COptionLoop-0>
+      <COptionMisra2004RuleNumberIgnore-0 />
+      <COptionPostCompileCommands-0 />
+      <COptionSectionP-0>P</COptionSectionP-0>
+      <COptionShowDefinitions-0>False</COptionShowDefinitions-0>
+      <COptionSystemInclude-0 />
+      <COptionLoopValue-0>2</COptionLoopValue-0>
+      <COptionMisra2004RuleNumberRequiredAdd-0 />
+      <COptionOtherAdditionalOptions-0 />
+      <COptionPreinclude-0 />
+      <COptionSectionC-0>C</COptionSectionC-0>
+      <COptionShowExpansions-0>False</COptionShowExpansions-0>
+      <COptionCommandLine-0>-isa=rxv1
+-include=..\..\..\asp_dcre
+-include=..\..\..\asp_dcre\arch
+-include=..\..\..\asp_dcre\include
+-include=..\..\..\asp_dcre\kernel
+-include=..\..\..\asp_dcre\arch
+-include=..\..\..\asp_dcre\syssvc
+-include=..\..\..\asp_dcre\library
+-include=..\..\..\asp_dcre\pdic
+-include=..\..\..\asp_dcre\target\grsakura_ccrx
+-include=..
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-fpu
+-nologo
+</COptionCommandLine-0>
+      <COptionDefine-0 />
+      <COptionInline-0>Auto</COptionInline-0>
+      <COptionMisra2004RuleNumberRequiredRemove-0 />
+      <COptionSectionD-0>D</COptionSectionD-0>
+      <COptionIgnoreFilesMisra-0 />
+      <COptionInlineValue-0>100</COptionInlineValue-0>
+      <COptionSectionB-0>B</COptionSectionB-0>
+      <COptionUndefine-0 />
+      <COptionCheckLanguageExtension-0>False</COptionCheckLanguageExtension-0>
+      <COptionFileInline-0 />
+      <COptionMessage-0>False</COptionMessage-0>
+      <COptionSectionL-0>L</COptionSectionL-0>
+      <COptionCase-0>Auto</COptionCase-0>
+      <COptionSectionW-0>W</COptionSectionW-0>
+      <COptionNoMessageErrorNumber-0 />
+      <COptionNostuffB-0>False</COptionNostuffB-0>
+      <COptionVolatile-0>False</COptionVolatile-0>
+      <COptionConstCopy-0>Auto</COptionConstCopy-0>
+      <COptionNostuffD-0>False</COptionNostuffD-0>
+      <COptionChangeMessageInformation-0>No</COptionChangeMessageInformation-0>
+      <COptionConstDiv-0>Auto</COptionConstDiv-0>
+      <COptionNostuffC-0>False</COptionNostuffC-0>
+      <COptionChangeMessageInformationNumber-0 />
+      <COptionLibrary-0>Intrinsic</COptionLibrary-0>
+      <COptionNostuffW-0>False</COptionNostuffW-0>
+      <COptionInstalign-0>Noinstalign</COptionInstalign-0>
+      <COptionScope-0>Auto</COptionScope-0>
+      <COptionChangeMessageWarning-0>No</COptionChangeMessageWarning-0>
+      <COptionNouseDiv-0>True</COptionNouseDiv-0>
+      <COptionSchedule-0>Auto</COptionSchedule-0>
+      <COptionChangeMessageWarningNumber-0 />
+      <COptionMap-0>NoMap</COptionMap-0>
+      <COptionOutcode-0>Sjis</COptionOutcode-0>
+      <COptionIntermodule-0>None</COptionIntermodule-0>
+      <COptionApproxdiv-0>False</COptionApproxdiv-0>
+      <COptionChangeMessageError-0>No</COptionChangeMessageError-0>
+      <COptionChangeMessageErrorNumber-0 />
+      <COptionEnableRegister-0>False</COptionEnableRegister-0>
+      <COptionSimpleFloatConv-0>False</COptionSimpleFloatConv-0>
+      <COptionFileInlinePath-0 />
+      <COptionFpu-0>Fpu</COptionFpu-0>
+      <COptionAlias-0>False</COptionAlias-0>
+      <COptionComment-0>False</COptionComment-0>
+      <COptionCheck-0>No</COptionCheck-0>
+      <COptionFloatOrder-0>False</COptionFloatOrder-0>
+      <COptionIncode-0>Sjis</COptionIncode-0>
+    </Instance>
+    <Instance Guid="5ad1746c-d03e-4610-a91f-aaa4fb37bc10">
+      <AsmOptionChkpm-DefaultValue>False</AsmOptionChkpm-DefaultValue>
+      <AsmOptionGoptimize-DefaultValue>False</AsmOptionGoptimize-DefaultValue>
+      <AsmOptionInclude-DefaultValue />
+      <AsmOptionListFile-DefaultValue>False</AsmOptionListFile-DefaultValue>
+      <AsmOptionOutput-DefaultValue>%BuildModeName%</AsmOptionOutput-DefaultValue>
+      <AsmOptionChkfpu-DefaultValue>False</AsmOptionChkfpu-DefaultValue>
+      <AsmOptionDebug-DefaultValue>True</AsmOptionDebug-DefaultValue>
+      <AsmOptionShowConditionals-DefaultValue>False</AsmOptionShowConditionals-DefaultValue>
+      <AsmOptionSystemInclude-DefaultValue />
+      <AsmOptionChkdsp-DefaultValue>False</AsmOptionChkdsp-DefaultValue>
+      <AsmOptionDefine-DefaultValue />
+      <AsmOptionShowDefinitions-DefaultValue>False</AsmOptionShowDefinitions-DefaultValue>
+      <AsmOptionInCode-DefaultValue>SJIS</AsmOptionInCode-DefaultValue>
+      <AsmOptionLogo-DefaultValue>False</AsmOptionLogo-DefaultValue>
+      <AsmOptionShowExpansions-DefaultValue>False</AsmOptionShowExpansions-DefaultValue>
+      <AsmOptionPreAssembleCommands-DefaultValue />
+      <AsmOptionPostAssembleCommands-DefaultValue />
+      <AsmOptionOtherAdditionalOptions-DefaultValue />
+      <AsmOptionCommandLine-DefaultValue>-isa=rxv1
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</AsmOptionCommandLine-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053514216173186</TimeTagModified--0>
+      <AsmOptionChkpm-0>False</AsmOptionChkpm-0>
+      <AsmOptionGoptimize-0>False</AsmOptionGoptimize-0>
+      <AsmOptionInclude-0 />
+      <AsmOptionListFile-0>False</AsmOptionListFile-0>
+      <AsmOptionOutput-0>%BuildModeName%</AsmOptionOutput-0>
+      <AsmOptionChkfpu-0>False</AsmOptionChkfpu-0>
+      <AsmOptionDebug-0>True</AsmOptionDebug-0>
+      <AsmOptionShowConditionals-0>False</AsmOptionShowConditionals-0>
+      <AsmOptionSystemInclude-0 />
+      <AsmOptionChkdsp-0>False</AsmOptionChkdsp-0>
+      <AsmOptionDefine-0 />
+      <AsmOptionShowDefinitions-0>False</AsmOptionShowDefinitions-0>
+      <AsmOptionInCode-0>SJIS</AsmOptionInCode-0>
+      <AsmOptionLogo-0>False</AsmOptionLogo-0>
+      <AsmOptionShowExpansions-0>False</AsmOptionShowExpansions-0>
+      <AsmOptionPreAssembleCommands-0 />
+      <AsmOptionPostAssembleCommands-0 />
+      <AsmOptionOtherAdditionalOptions-0 />
+      <AsmOptionCommandLine-0>-isa=rxv1
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</AsmOptionCommandLine-0>
+    </Instance>
+    <Instance Guid="dbb16727-3e81-4169-956a-790355cab4a1">
+      <LinkOptionCpu-DefaultValue>False</LinkOptionCpu-DefaultValue>
+      <LinkOptionForm-DefaultValue>Absolute</LinkOptionForm-DefaultValue>
+      <LinkOptionFormConvert-DefaultValue>Stype</LinkOptionFormConvert-DefaultValue>
+      <LinkOptionInput-DefaultValue />
+      <LinkOptionListShow-DefaultValue>List</LinkOptionListShow-DefaultValue>
+      <LinkOptionOptimize-DefaultValue>None</LinkOptionOptimize-DefaultValue>
+      <LinkOptionStack-DefaultValue>False</LinkOptionStack-DefaultValue>
+      <LinkOptionStart-DefaultValue>B_1,R_1,B_2,R_2,B,R,SU,SI/04,PResetPRG/0FFFF8000,C_1,C_2,C,C$DSEC,C$BSEC,C$INIT,C$VTBL,C$VECT,D_1,D_2,D,P,PIntPRG,W_1,W_2,W,L/0FFFF8100,FIXEDVECT/0FFFFFFD0</LinkOptionStart-DefaultValue>
+      <LinkOptionCompress-DefaultValue>False</LinkOptionCompress-DefaultValue>
+      <LinkOptionCpuInformation-DefaultValue />
+      <LinkOptionDebug-DefaultValue>Debug</LinkOptionDebug-DefaultValue>
+      <LinkOptionFSymbol-DefaultValue />
+      <LinkOptionLibrary-DefaultValue />
+      <LinkOptionOptimizeSymbolDelete-DefaultValue>False</LinkOptionOptimizeSymbolDelete-DefaultValue>
+      <LinkOptionRecordH-DefaultValue>None</LinkOptionRecordH-DefaultValue>
+      <LinkOptionShowSymbol-DefaultValue>False</LinkOptionShowSymbol-DefaultValue>
+      <LinkOptionAlignedSection-DefaultValue />
+      <LinkOptionCpuStride-DefaultValue>False</LinkOptionCpuStride-DefaultValue>
+      <LinkOptionMemory-DefaultValue>False</LinkOptionMemory-DefaultValue>
+      <LinkOptionOptimizeSameCode-DefaultValue>False</LinkOptionOptimizeSameCode-DefaultValue>
+      <LinkOptionOutputFolder-DefaultValue>%BuildModeName%</LinkOptionOutputFolder-DefaultValue>
+      <LinkOptionRecordS-DefaultValue>None</LinkOptionRecordS-DefaultValue>
+      <LinkOptionShowReference-DefaultValue>False</LinkOptionShowReference-DefaultValue>
+      <LinkOptionSystemLibrary-DefaultValue />
+      <LinkOptionBinary-DefaultValue />
+      <LinkOptionChangeMessageInformation-DefaultValue>None</LinkOptionChangeMessageInformation-DefaultValue>
+      <LinkOptionContiguousSection-DefaultValue />
+      <LinkOptionDividedConvertFile-DefaultValue>False</LinkOptionDividedConvertFile-DefaultValue>
+      <LinkOptionOutputFileName-DefaultValue>%ProjectName%.abs</LinkOptionOutputFileName-DefaultValue>
+      <LinkOptionRom-DefaultValue />
+      <LinkOptionSameSize-DefaultValue>1E</LinkOptionSameSize-DefaultValue>
+      <LinkOptionShowXreference-DefaultValue>False</LinkOptionShowXreference-DefaultValue>
+      <LinkOptionChangeMessageInformationNumber-DefaultValue />
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionDefine-DefaultValue />
+      <LinkOptionMap-DefaultValue>False</LinkOptionMap-DefaultValue>
+      <LinkOptionOptimizeShortFormat-DefaultValue>False</LinkOptionOptimizeShortFormat-DefaultValue>
+      <LinkOptionShowTotalSize-DefaultValue>False</LinkOptionShowTotalSize-DefaultValue>
+      <LinkOptionChangeMessageWarning-DefaultValue>None</LinkOptionChangeMessageWarning-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionEntry-DefaultValue>False</LinkOptionEntry-DefaultValue>
+      <LinkOptionMessage-DefaultValue>NoMessage</LinkOptionMessage-DefaultValue>
+      <LinkOptionOptimizeBranch-DefaultValue>False</LinkOptionOptimizeBranch-DefaultValue>
+      <LinkOptionShowVector-DefaultValue>False</LinkOptionShowVector-DefaultValue>
+      <LinkOptionChangeMessageWarningNumber-DefaultValue />
+      <LinkOptionEntryPoint-DefaultValue />
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionNoMessageErrorNumber-DefaultValue />
+      <LinkOptionSymbolForbid-DefaultValue />
+      <LinkOptionChangeMessageError-DefaultValue>None</LinkOptionChangeMessageError-DefaultValue>
+      <LinkOptionNoPrelink-DefaultValue>Auto</LinkOptionNoPrelink-DefaultValue>
+      <LinkOptionPadding-DefaultValue>False</LinkOptionPadding-DefaultValue>
+      <LinkOptionSameCodeForbid-DefaultValue />
+      <LinkOptionSpace-DefaultValue>None</LinkOptionSpace-DefaultValue>
+      <LinkOptionChangeMessageErrorNumber-DefaultValue />
+      <LinkOptionSectionForbid-DefaultValue />
+      <LinkOptionSpaceValue-DefaultValue>FF</LinkOptionSpaceValue-DefaultValue>
+      <LinkOptionVectN-DefaultValue />
+      <LinkOptionAbsoluteForbid-DefaultValue />
+      <LinkOptionByteCount-DefaultValue>False</LinkOptionByteCount-DefaultValue>
+      <LinkOptionHide-DefaultValue>False</LinkOptionHide-DefaultValue>
+      <LinkOptionVect-DefaultValue />
+      <LinkOptionByteCountValue-DefaultValue>FF</LinkOptionByteCountValue-DefaultValue>
+      <LinkOptionJumpEntriesForPic-DefaultValue>False</LinkOptionJumpEntriesForPic-DefaultValue>
+      <LinkOptionTotalSize-DefaultValue>False</LinkOptionTotalSize-DefaultValue>
+      <LinkOptionCrc-DefaultValue>None</LinkOptionCrc-DefaultValue>
+      <LinkOptionJumpEntriesForPicSectionName-DefaultValue />
+      <LinkOptionLogo-DefaultValue>False</LinkOptionLogo-DefaultValue>
+      <LinkOptionCrcOutputAddress-DefaultValue>0</LinkOptionCrcOutputAddress-DefaultValue>
+      <LinkOptionPreLinkCommands-DefaultValue />
+      <LinkOptionCrcCalculationRange-DefaultValue />
+      <LinkOptionPostLinkCommands-DefaultValue />
+      <LinkOptionOtherAdditionalOptionsForLoadModule-DefaultValue />
+      <LinkOptionS9-DefaultValue>False</LinkOptionS9-DefaultValue>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-DefaultValue />
+      <LinkOptionCommandLine-DefaultValue>-noprelink
+-output=%BuildModeName%\%ProjectName%.abs
+-list=%BuildModeName%\%ProjectName%.map
+-show=symbol
+-nooptimize
+-start=B_1,R_1,B_2,R_2,B,R,SU,SI/04,PResetPRG/0FFF80000,C_1,C_2,C,C$DSEC,C$BSEC,C$INIT,C$VTBL,C$VECT,D_1,D_2,D,P,PIntPRG,W_1,W_2,W,L/0FFF80100,FIXEDVECT/0FFFFFFD0
+-nologo
+-exit
+</LinkOptionCommandLine-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588032587969760537</TimeTagModified--0>
+      <LinkOptionCpu-0>False</LinkOptionCpu-0>
+      <LinkOptionForm-0>Absolute</LinkOptionForm-0>
+      <LinkOptionFormConvert-0>Stype</LinkOptionFormConvert-0>
+      <LinkOptionInput-0 />
+      <LinkOptionListShow-0>List</LinkOptionListShow-0>
+      <LinkOptionOptimize-0>None</LinkOptionOptimize-0>
+      <LinkOptionStack-0>False</LinkOptionStack-0>
+      <LinkOptionStart-0>B_1,R_1,B_2,R_2,B,R,SU,SI/04,PResetPRG/0FFF80000,C_1,C_2,C,C$DSEC,C$BSEC,C$INIT,C$VTBL,C$VECT,D_1,D_2,D,P,PIntPRG,W_1,W_2,W,L/0FFF80100,FIXEDVECT/0FFFFFFD0</LinkOptionStart-0>
+      <LinkOptionCompress-0>False</LinkOptionCompress-0>
+      <LinkOptionCpuInformation-0 />
+      <LinkOptionDebug-0>Debug</LinkOptionDebug-0>
+      <LinkOptionFSymbol-0 />
+      <LinkOptionLibrary-0 />
+      <LinkOptionOptimizeSymbolDelete-0>False</LinkOptionOptimizeSymbolDelete-0>
+      <LinkOptionRecordH-0>None</LinkOptionRecordH-0>
+      <LinkOptionShowSymbol-0>True</LinkOptionShowSymbol-0>
+      <LinkOptionAlignedSection-0 />
+      <LinkOptionCpuStride-0>False</LinkOptionCpuStride-0>
+      <LinkOptionMemory-0>False</LinkOptionMemory-0>
+      <LinkOptionOptimizeSameCode-0>False</LinkOptionOptimizeSameCode-0>
+      <LinkOptionOutputFolder-0>%BuildModeName%</LinkOptionOutputFolder-0>
+      <LinkOptionRecordS-0>None</LinkOptionRecordS-0>
+      <LinkOptionShowReference-0>False</LinkOptionShowReference-0>
+      <LinkOptionSystemLibrary-0 />
+      <LinkOptionBinary-0 />
+      <LinkOptionChangeMessageInformation-0>None</LinkOptionChangeMessageInformation-0>
+      <LinkOptionContiguousSection-0 />
+      <LinkOptionDividedConvertFile-0>False</LinkOptionDividedConvertFile-0>
+      <LinkOptionOutputFileName-0>%ProjectName%.abs</LinkOptionOutputFileName-0>
+      <LinkOptionRom-0 />
+      <LinkOptionSameSize-0>1E</LinkOptionSameSize-0>
+      <LinkOptionShowXreference-0>False</LinkOptionShowXreference-0>
+      <LinkOptionChangeMessageInformationNumber-0 />
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <LinkOptionDefine-0 />
+      <LinkOptionMap-0>False</LinkOptionMap-0>
+      <LinkOptionOptimizeShortFormat-0>False</LinkOptionOptimizeShortFormat-0>
+      <LinkOptionShowTotalSize-0>False</LinkOptionShowTotalSize-0>
+      <LinkOptionChangeMessageWarning-0>None</LinkOptionChangeMessageWarning-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <LinkOptionEntry-0>False</LinkOptionEntry-0>
+      <LinkOptionMessage-0>NoMessage</LinkOptionMessage-0>
+      <LinkOptionOptimizeBranch-0>False</LinkOptionOptimizeBranch-0>
+      <LinkOptionShowVector-0>False</LinkOptionShowVector-0>
+      <LinkOptionChangeMessageWarningNumber-0 />
+      <LinkOptionEntryPoint-0 />
+      <LinkOptionMultiConvertFileName-0 />
+      <LinkOptionNoMessageErrorNumber-0 />
+      <LinkOptionSymbolForbid-0 />
+      <LinkOptionChangeMessageError-0>None</LinkOptionChangeMessageError-0>
+      <LinkOptionNoPrelink-0>Auto</LinkOptionNoPrelink-0>
+      <LinkOptionPadding-0>False</LinkOptionPadding-0>
+      <LinkOptionSameCodeForbid-0 />
+      <LinkOptionSpace-0>None</LinkOptionSpace-0>
+      <LinkOptionChangeMessageErrorNumber-0 />
+      <LinkOptionSectionForbid-0 />
+      <LinkOptionSpaceValue-0>FF</LinkOptionSpaceValue-0>
+      <LinkOptionVectN-0 />
+      <LinkOptionAbsoluteForbid-0 />
+      <LinkOptionByteCount-0>False</LinkOptionByteCount-0>
+      <LinkOptionHide-0>False</LinkOptionHide-0>
+      <LinkOptionVect-0 />
+      <LinkOptionByteCountValue-0>FF</LinkOptionByteCountValue-0>
+      <LinkOptionJumpEntriesForPic-0>False</LinkOptionJumpEntriesForPic-0>
+      <LinkOptionTotalSize-0>False</LinkOptionTotalSize-0>
+      <LinkOptionCrc-0>None</LinkOptionCrc-0>
+      <LinkOptionJumpEntriesForPicSectionName-0 />
+      <LinkOptionLogo-0>False</LinkOptionLogo-0>
+      <LinkOptionCrcOutputAddress-0>0</LinkOptionCrcOutputAddress-0>
+      <LinkOptionPreLinkCommands-0 />
+      <LinkOptionCrcCalculationRange-0 />
+      <LinkOptionPostLinkCommands-0 />
+      <LinkOptionOtherAdditionalOptionsForLoadModule-0 />
+      <LinkOptionS9-0>False</LinkOptionS9-0>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-0 />
+      <LinkOptionCommandLine-0>-noprelink
+-output=%BuildModeName%\%ProjectName%.abs
+-list=%BuildModeName%\%ProjectName%.map
+-show=symbol
+-nooptimize
+-start=B_1,R_1,B_2,R_2,B,R,SU,SI/04,PResetPRG/0FFF80000,C_1,C_2,C,C$DSEC,C$BSEC,C$INIT,C$VTBL,C$VECT,D_1,D_2,D,P,PIntPRG,W_1,W_2,W,L/0FFF80100,FIXEDVECT/0FFFFFFD0
+-nologo
+-exit
+</LinkOptionCommandLine-0>
+    </Instance>
+    <Instance Guid="df74c69e-635e-42d9-845e-14128ba4d48a">
+      <HexOptionForm-DefaultValue>Stype</HexOptionForm-DefaultValue>
+      <HexOptionOutput-DefaultValue>True</HexOptionOutput-DefaultValue>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-DefaultValue />
+      <HexOptionCommandLine-DefaultValue>-end
+-input=%BuildModeName%\%ProjectName%.abs
+-form=stype
+-output=%BuildModeName%\%ProjectName%.mot
+-exit
+</HexOptionCommandLine-DefaultValue>
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionRecordH-DefaultValue>None</LinkOptionRecordH-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionRecordS-DefaultValue>None</LinkOptionRecordS-DefaultValue>
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionSpace-DefaultValue>None</LinkOptionSpace-DefaultValue>
+      <LinkOptionSpaceValue-DefaultValue>FF</LinkOptionSpaceValue-DefaultValue>
+      <LinkOptionByteCount-DefaultValue>False</LinkOptionByteCount-DefaultValue>
+      <LinkOptionByteCountValue-DefaultValue>FF</LinkOptionByteCountValue-DefaultValue>
+      <LinkOptionCrc-DefaultValue>None</LinkOptionCrc-DefaultValue>
+      <LinkOptionCrcOutputAddress-DefaultValue>0</LinkOptionCrcOutputAddress-DefaultValue>
+      <LinkOptionCrcCalculationRange-DefaultValue />
+      <LinkOptionS9-DefaultValue>False</LinkOptionS9-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053514216073187</TimeTagModified--0>
+      <HexOptionForm-0>Stype</HexOptionForm-0>
+      <HexOptionOutput-0>True</HexOptionOutput-0>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-0 />
+      <HexOptionCommandLine-0>-end
+-input=%BuildModeName%\%ProjectName%.abs
+-form=stype
+-output=%BuildModeName%\%ProjectName%.mot
+-exit
+</HexOptionCommandLine-0>
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <LinkOptionRecordH-0>None</LinkOptionRecordH-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <LinkOptionRecordS-0>None</LinkOptionRecordS-0>
+      <LinkOptionMultiConvertFileName-0 />
+      <LinkOptionSpace-0>None</LinkOptionSpace-0>
+      <LinkOptionSpaceValue-0>FF</LinkOptionSpaceValue-0>
+      <LinkOptionByteCount-0>False</LinkOptionByteCount-0>
+      <LinkOptionByteCountValue-0>FF</LinkOptionByteCountValue-0>
+      <LinkOptionCrc-0>None</LinkOptionCrc-0>
+      <LinkOptionCrcOutputAddress-0>0</LinkOptionCrcOutputAddress-0>
+      <LinkOptionCrcCalculationRange-0 />
+      <LinkOptionS9-0>False</LinkOptionS9-0>
+    </Instance>
+    <Instance Guid="fff50d2e-74da-44ea-90a8-c47756029e83">
+      <LibOptionForm-DefaultValue>LibraryU</LibOptionForm-DefaultValue>
+      <LibOptionInput-DefaultValue />
+      <LibOptionListShow-DefaultValue>None</LibOptionListShow-DefaultValue>
+      <LibOptionMemory-DefaultValue>False</LibOptionMemory-DefaultValue>
+      <LibOptionChangeMessageInformation-DefaultValue>None</LibOptionChangeMessageInformation-DefaultValue>
+      <LibOptionDebug-DefaultValue>Debug</LibOptionDebug-DefaultValue>
+      <LibOptionLibrary-DefaultValue />
+      <LibOptionShowSymbol-DefaultValue>False</LibOptionShowSymbol-DefaultValue>
+      <LibOptionChangeMessageInformationNumber-DefaultValue />
+      <LibOptionOutputFolder-DefaultValue>%BuildModeName%</LibOptionOutputFolder-DefaultValue>
+      <LibOptionShowSection-DefaultValue>False</LibOptionShowSection-DefaultValue>
+      <LibOptionSystemLibrary-DefaultValue />
+      <LibOptionBinary-DefaultValue />
+      <LibOptionChangeMessageWarning-DefaultValue>None</LibOptionChangeMessageWarning-DefaultValue>
+      <LibOptionOutputFileName-DefaultValue>%ProjectName%.lib</LibOptionOutputFileName-DefaultValue>
+      <LibOptionShowXreference-DefaultValue>False</LibOptionShowXreference-DefaultValue>
+      <LibOptionChangeMessageWarningNumber-DefaultValue />
+      <LibOptionMessage-DefaultValue>NoMessage</LibOptionMessage-DefaultValue>
+      <LibOptionNoPrelink-DefaultValue>Auto</LibOptionNoPrelink-DefaultValue>
+      <LibOptionShowTotalSize-DefaultValue>False</LibOptionShowTotalSize-DefaultValue>
+      <LibOptionChangeMessageError-DefaultValue>None</LibOptionChangeMessageError-DefaultValue>
+      <LibOptionNoMessageErrorNumber-DefaultValue />
+      <LibOptionShowVector-DefaultValue>False</LibOptionShowVector-DefaultValue>
+      <LibOptionChangeMessageErrorNumber-DefaultValue />
+      <LibOptionHide-DefaultValue>False</LibOptionHide-DefaultValue>
+      <LibOptionTotalSize-DefaultValue>False</LibOptionTotalSize-DefaultValue>
+      <LibOptionLogo-DefaultValue>False</LibOptionLogo-DefaultValue>
+      <LibOptionPreLibrarianCommands-DefaultValue />
+      <LibOptionPostLibrarianCommands-DefaultValue />
+      <LibOptionOtherAdditionalOptions-DefaultValue />
+      <LibOptionCommandLine-DefaultValue />
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053514216073187</TimeTagModified--0>
+      <LibOptionForm-0>LibraryU</LibOptionForm-0>
+      <LibOptionInput-0 />
+      <LibOptionListShow-0>None</LibOptionListShow-0>
+      <LibOptionMemory-0>False</LibOptionMemory-0>
+      <LibOptionChangeMessageInformation-0>None</LibOptionChangeMessageInformation-0>
+      <LibOptionDebug-0>Debug</LibOptionDebug-0>
+      <LibOptionLibrary-0 />
+      <LibOptionShowSymbol-0>False</LibOptionShowSymbol-0>
+      <LibOptionChangeMessageInformationNumber-0 />
+      <LibOptionOutputFolder-0>%BuildModeName%</LibOptionOutputFolder-0>
+      <LibOptionShowSection-0>False</LibOptionShowSection-0>
+      <LibOptionSystemLibrary-0 />
+      <LibOptionBinary-0 />
+      <LibOptionChangeMessageWarning-0>None</LibOptionChangeMessageWarning-0>
+      <LibOptionOutputFileName-0>%ProjectName%.lib</LibOptionOutputFileName-0>
+      <LibOptionShowXreference-0>False</LibOptionShowXreference-0>
+      <LibOptionChangeMessageWarningNumber-0 />
+      <LibOptionMessage-0>NoMessage</LibOptionMessage-0>
+      <LibOptionNoPrelink-0>Auto</LibOptionNoPrelink-0>
+      <LibOptionShowTotalSize-0>False</LibOptionShowTotalSize-0>
+      <LibOptionChangeMessageError-0>None</LibOptionChangeMessageError-0>
+      <LibOptionNoMessageErrorNumber-0 />
+      <LibOptionShowVector-0>False</LibOptionShowVector-0>
+      <LibOptionChangeMessageErrorNumber-0 />
+      <LibOptionHide-0>False</LibOptionHide-0>
+      <LibOptionTotalSize-0>False</LibOptionTotalSize-0>
+      <LibOptionLogo-0>False</LibOptionLogo-0>
+      <LibOptionPreLibrarianCommands-0 />
+      <LibOptionPostLibrarianCommands-0 />
+      <LibOptionOtherAdditionalOptions-0 />
+      <LibOptionCommandLine-0 />
+    </Instance>
+    <Instance Guid="9cb0ade0-b3cb-4e21-823c-290b5fdb5f1e">
+      <LbgOptionLanguage-DefaultValue>C</LbgOptionLanguage-DefaultValue>
+      <LbgOptionLibraryMode-DefaultValue>MakeOptionChanged</LbgOptionLibraryMode-DefaultValue>
+      <LbgOptionLogo-DefaultValue>False</LbgOptionLogo-DefaultValue>
+      <LbgOptionOptimize-DefaultValue>Level2</LbgOptionOptimize-DefaultValue>
+      <LbgOptionOutputFolder-DefaultValue>%BuildModeName%</LbgOptionOutputFolder-DefaultValue>
+      <LbgOptionGoptimize-DefaultValue>False</LbgOptionGoptimize-DefaultValue>
+      <LbgOptionHead-DefaultValue>Custom</LbgOptionHead-DefaultValue>
+      <LbgOptionOutputFileName-DefaultValue>%ProjectName%.lib</LbgOptionOutputFileName-DefaultValue>
+      <LbgOptionPreLibraryGenerateCommands-DefaultValue />
+      <LbgOptionFunctionalCutdown-DefaultValue>None</LbgOptionFunctionalCutdown-DefaultValue>
+      <LbgOptionHeadRuntime-DefaultValue>True</LbgOptionHeadRuntime-DefaultValue>
+      <LbgOptionPostLibraryGenerateCommands-DefaultValue />
+      <LbgOptionSpeedAndSize-DefaultValue>Size</LbgOptionSpeedAndSize-DefaultValue>
+      <LbgOptionHeadCtypeH-DefaultValue>False</LbgOptionHeadCtypeH-DefaultValue>
+      <LbgOptionLoop-DefaultValue>Auto</LbgOptionLoop-DefaultValue>
+      <LbgOptionOtherAdditionalOptions-DefaultValue />
+      <LbgOptionReent-DefaultValue>False</LbgOptionReent-DefaultValue>
+      <LbgOptionCommandLine-DefaultValue />
+      <LbgOptionHeadMathH-DefaultValue>False</LbgOptionHeadMathH-DefaultValue>
+      <LbgOptionLoopValue-DefaultValue>2</LbgOptionLoopValue-DefaultValue>
+      <LbgOptionSectionP-DefaultValue>P</LbgOptionSectionP-DefaultValue>
+      <LbgOptionHeadMathfH-DefaultValue>False</LbgOptionHeadMathfH-DefaultValue>
+      <LbgOptionInline-DefaultValue>Auto</LbgOptionInline-DefaultValue>
+      <LbgOptionSectionC-DefaultValue>C</LbgOptionSectionC-DefaultValue>
+      <LbgOptionHeadStdargH-DefaultValue>False</LbgOptionHeadStdargH-DefaultValue>
+      <LbgOptionInlineValue-DefaultValue>100</LbgOptionInlineValue-DefaultValue>
+      <LbgOptionSectionD-DefaultValue>D</LbgOptionSectionD-DefaultValue>
+      <LbgOptionFileInline-DefaultValue />
+      <LbgOptionHeadStdioH-DefaultValue>True</LbgOptionHeadStdioH-DefaultValue>
+      <LbgOptionSectionB-DefaultValue>B</LbgOptionSectionB-DefaultValue>
+      <LbgOptionCase-DefaultValue>Auto</LbgOptionCase-DefaultValue>
+      <LbgOptionHeadStdlibH-DefaultValue>True</LbgOptionHeadStdlibH-DefaultValue>
+      <LbgOptionSectionL-DefaultValue>L</LbgOptionSectionL-DefaultValue>
+      <LbgOptionHeadStringH-DefaultValue>True</LbgOptionHeadStringH-DefaultValue>
+      <LbgOptionSectionW-DefaultValue>W</LbgOptionSectionW-DefaultValue>
+      <LbgOptionVolatile-DefaultValue>False</LbgOptionVolatile-DefaultValue>
+      <LbgOptionConstCopy-DefaultValue>Auto</LbgOptionConstCopy-DefaultValue>
+      <LbgOptionHeadIos-DefaultValue>False</LbgOptionHeadIos-DefaultValue>
+      <LbgOptionNostuffB-DefaultValue>False</LbgOptionNostuffB-DefaultValue>
+      <LbgOptionConstDiv-DefaultValue>Auto</LbgOptionConstDiv-DefaultValue>
+      <LbgOptionHeadNew-DefaultValue>True</LbgOptionHeadNew-DefaultValue>
+      <LbgOptionNostuffD-DefaultValue>False</LbgOptionNostuffD-DefaultValue>
+      <LbgOptionHeadComplex-DefaultValue>False</LbgOptionHeadComplex-DefaultValue>
+      <LbgOptionLibrary-DefaultValue>Intrinsic</LbgOptionLibrary-DefaultValue>
+      <LbgOptionNostuffC-DefaultValue>False</LbgOptionNostuffC-DefaultValue>
+      <LbgOptionHeadString-DefaultValue>False</LbgOptionHeadString-DefaultValue>
+      <LbgOptionNostuffW-DefaultValue>False</LbgOptionNostuffW-DefaultValue>
+      <LbgOptionScope-DefaultValue>Auto</LbgOptionScope-DefaultValue>
+      <LbgOptionHeadComplexH-DefaultValue>False</LbgOptionHeadComplexH-DefaultValue>
+      <LbgOptionInstalign-DefaultValue>Noinstalign</LbgOptionInstalign-DefaultValue>
+      <LbgOptionSchedule-DefaultValue>Auto</LbgOptionSchedule-DefaultValue>
+      <LbgOptionApproxdiv-DefaultValue>False</LbgOptionApproxdiv-DefaultValue>
+      <LbgOptionHeadFenvH-DefaultValue>False</LbgOptionHeadFenvH-DefaultValue>
+      <LbgOptionNouseDiv-DefaultValue>True</LbgOptionNouseDiv-DefaultValue>
+      <LbgOptionEnableRegister-DefaultValue>False</LbgOptionEnableRegister-DefaultValue>
+      <LbgOptionHeadInttypesH-DefaultValue>False</LbgOptionHeadInttypesH-DefaultValue>
+      <LbgOptionHeadWcharH-DefaultValue>False</LbgOptionHeadWcharH-DefaultValue>
+      <LbgOptionSimpleFloatConv-DefaultValue>False</LbgOptionSimpleFloatConv-DefaultValue>
+      <LbgOptionFpu-DefaultValue>Fpu</LbgOptionFpu-DefaultValue>
+      <LbgOptionHeadWctypeH-DefaultValue>False</LbgOptionHeadWctypeH-DefaultValue>
+      <LbgOptionFloatOrder-DefaultValue>False</LbgOptionFloatOrder-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053514216073187</TimeTagModified--0>
+      <LbgOptionLanguage-0>C</LbgOptionLanguage-0>
+      <LbgOptionLibraryMode-0>MakeOptionChanged</LbgOptionLibraryMode-0>
+      <LbgOptionLogo-0>False</LbgOptionLogo-0>
+      <LbgOptionOptimize-0>Level2</LbgOptionOptimize-0>
+      <LbgOptionOutputFolder-0>%BuildModeName%</LbgOptionOutputFolder-0>
+      <LbgOptionGoptimize-0>False</LbgOptionGoptimize-0>
+      <LbgOptionHead-0>Custom</LbgOptionHead-0>
+      <LbgOptionOutputFileName-0>%ProjectName%.lib</LbgOptionOutputFileName-0>
+      <LbgOptionPreLibraryGenerateCommands-0 />
+      <LbgOptionFunctionalCutdown-0>None</LbgOptionFunctionalCutdown-0>
+      <LbgOptionPostLibraryGenerateCommands-0 />
+      <LbgOptionSpeedAndSize-0>Size</LbgOptionSpeedAndSize-0>
+      <LbgOptionHeadCtypeH-0>False</LbgOptionHeadCtypeH-0>
+      <LbgOptionLoop-0>Auto</LbgOptionLoop-0>
+      <LbgOptionOtherAdditionalOptions-0 />
+      <LbgOptionReent-0>False</LbgOptionReent-0>
+      <LbgOptionCommandLine-0 />
+      <LbgOptionHeadMathH-0>False</LbgOptionHeadMathH-0>
+      <LbgOptionLoopValue-0>2</LbgOptionLoopValue-0>
+      <LbgOptionSectionP-0>P</LbgOptionSectionP-0>
+      <LbgOptionHeadMathfH-0>False</LbgOptionHeadMathfH-0>
+      <LbgOptionInline-0>Auto</LbgOptionInline-0>
+      <LbgOptionSectionC-0>C</LbgOptionSectionC-0>
+      <LbgOptionHeadStdargH-0>False</LbgOptionHeadStdargH-0>
+      <LbgOptionInlineValue-0>100</LbgOptionInlineValue-0>
+      <LbgOptionSectionD-0>D</LbgOptionSectionD-0>
+      <LbgOptionFileInline-0 />
+      <LbgOptionHeadStdioH-0>True</LbgOptionHeadStdioH-0>
+      <LbgOptionSectionB-0>B</LbgOptionSectionB-0>
+      <LbgOptionCase-0>Auto</LbgOptionCase-0>
+      <LbgOptionHeadStdlibH-0>True</LbgOptionHeadStdlibH-0>
+      <LbgOptionSectionL-0>L</LbgOptionSectionL-0>
+      <LbgOptionHeadStringH-0>True</LbgOptionHeadStringH-0>
+      <LbgOptionSectionW-0>W</LbgOptionSectionW-0>
+      <LbgOptionVolatile-0>False</LbgOptionVolatile-0>
+      <LbgOptionConstCopy-0>Auto</LbgOptionConstCopy-0>
+      <LbgOptionHeadIos-0>False</LbgOptionHeadIos-0>
+      <LbgOptionNostuffB-0>False</LbgOptionNostuffB-0>
+      <LbgOptionConstDiv-0>Auto</LbgOptionConstDiv-0>
+      <LbgOptionHeadNew-0>True</LbgOptionHeadNew-0>
+      <LbgOptionNostuffD-0>False</LbgOptionNostuffD-0>
+      <LbgOptionHeadComplex-0>False</LbgOptionHeadComplex-0>
+      <LbgOptionLibrary-0>Intrinsic</LbgOptionLibrary-0>
+      <LbgOptionNostuffC-0>False</LbgOptionNostuffC-0>
+      <LbgOptionHeadString-0>False</LbgOptionHeadString-0>
+      <LbgOptionNostuffW-0>False</LbgOptionNostuffW-0>
+      <LbgOptionScope-0>Auto</LbgOptionScope-0>
+      <LbgOptionHeadComplexH-0>False</LbgOptionHeadComplexH-0>
+      <LbgOptionInstalign-0>Noinstalign</LbgOptionInstalign-0>
+      <LbgOptionSchedule-0>Auto</LbgOptionSchedule-0>
+      <LbgOptionApproxdiv-0>False</LbgOptionApproxdiv-0>
+      <LbgOptionHeadFenvH-0>False</LbgOptionHeadFenvH-0>
+      <LbgOptionNouseDiv-0>True</LbgOptionNouseDiv-0>
+      <LbgOptionEnableRegister-0>False</LbgOptionEnableRegister-0>
+      <LbgOptionHeadInttypesH-0>False</LbgOptionHeadInttypesH-0>
+      <LbgOptionHeadWcharH-0>False</LbgOptionHeadWcharH-0>
+      <LbgOptionSimpleFloatConv-0>False</LbgOptionSimpleFloatConv-0>
+      <LbgOptionFpu-0>Fpu</LbgOptionFpu-0>
+      <LbgOptionHeadWctypeH-0>False</LbgOptionHeadWctypeH-0>
+      <LbgOptionFloatOrder-0>False</LbgOptionFloatOrder-0>
+    </Instance>
+    <Instance Guid="2663a3a4-1aa9-423b-8114-929eeb0f323e">
+      <ItemAddTime>635318851240186844</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d3775719-f1c8-4906-8da0-338d3f5fccfe">
+      <ItemAddTime>635318906929090006</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a7be515f-f007-45ed-9059-4e1500c0f74d">
+      <TimeTagModified-SourceItem0--0>-8588053509614588964</TimeTagModified-SourceItem0--0>
+      <SourceItem0-IsLockedByUser>False</SourceItem0-IsLockedByUser>
+      <SourceItem0-BuildingTarget-0>True</SourceItem0-BuildingTarget-0>
+      <SourceItem0-IndividualCompileOption-0>False</SourceItem0-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem1--0>-8588053453925685802</TimeTagModified-SourceItem1--0>
+      <SourceItem1-IsLockedByUser>False</SourceItem1-IsLockedByUser>
+      <SourceItem1-BuildingTarget-0>True</SourceItem1-BuildingTarget-0>
+      <SourceItem1-IndividualCompileOption-0>False</SourceItem1-IndividualCompileOption-0>
+    </Instance>
+  </Class>
+  <Class Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
+    <Instance Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
+      <IsLibraryMode>False</IsLibraryMode>
+      <StartUpCategoryItem>00000000-0000-0000-0000-000000000000</StartUpCategoryItem>
+    </Instance>
+  </Class>
+  <Class Guid="a29a09ee-92c3-4ce7-9586-a1b058043f92">
+    <Instance Guid="a29a09ee-92c3-4ce7-9586-a1b058043f92">
+      <ProjectGeneratr-GeneratedFile0 />
+    </Instance>
+  </Class>
+  <Class Guid="31a86ad3-37bd-4846-aff2-e08abdc00197">
+    <Instance Guid="31a86ad3-37bd-4846-aff2-e08abdc00197">
+      <DeviceNameOnCreateStartup>R5F563NBDxFP</DeviceNameOnCreateStartup>
+    </Instance>
+  </Class>
+  <Class Guid="8b5af363-dcc2-48e6-919c-6cdb80d50173">
+    <Instance Guid="8b5af363-dcc2-48e6-919c-6cdb80d50173">
+      <DataFormatVersionPlugin>1.0</DataFormatVersionPlugin>
+      <DataFormatVersionDebugger>1.0</DataFormatVersionDebugger>
+    </Instance>
+  </Class>
+  <Class Guid="932085a2-9361-4df9-a3f7-12e6de7681a8">
+    <Instance Guid="932085a2-9361-4df9-a3f7-12e6de7681a8">
+      <DebugToolManager>1d1a55cf-2b92-481a-af4f-5975d095c419</DebugToolManager>
+    </Instance>
+  </Class>
+  <Class Guid="e4df8d71-236e-4af2-aaea-56345a08da25">
+    <Instance Guid="9e76d4e8-0b8f-4e7c-91b7-a4c442bcf2e7">
+      <DeviceChangedCounter>0</DeviceChangedCounter>
+      <DeviceName>R5F563NBDxFP</DeviceName>
+      <DebuggerProperty-EssentialProperty-Endian-CpuEndian>Little</DebuggerProperty-EssentialProperty-Endian-CpuEndian>
+      <DebuggerProperty-EssentialProperty-Clock-SystemClockFrequency>100</DebuggerProperty-EssentialProperty-Clock-SystemClockFrequency>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Length>3</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Length>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item0-Name>CMT</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item0-Name>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item0-IsUse>False</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item0-IsUse>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item1-Name>ICU</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item1-Name>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item1-IsUse>False</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item1-IsUse>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item2-Name>MPU</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item2-Name>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item2-IsUse>False</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item2-IsUse>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-PeripheralClockRate>ClockRate_1</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-PeripheralClockRate>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-Length>1</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-Length>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-DebuggerGuid />
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-FileName>DefaultBuild\cfg.abs</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-FileName>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-FileType>LoadModuleFile</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-FileType>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-Offset>0</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-Offset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-StartAddress>0</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-StartAddress>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-ObjectDownload>True</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-ObjectDownload>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-SymbolDownload>True</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-SymbolDownload>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-UsePicPidOffset>False</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-UsePicPidOffset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-PicOffset>0</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-PicOffset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-PidOffset>0</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-PidOffset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-GenerateInformationForInputCompletion>True</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-GenerateInformationForInputCompletion>
+      <DebuggerProperty-DownloadProperty-DebugInformation-CpuReset>True</DebuggerProperty-DownloadProperty-DebugInformation-CpuReset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-FlashErase>False</DebuggerProperty-DownloadProperty-DebugInformation-FlashErase>
+      <DebuggerProperty-DownloadProperty-DebugInformation-EventCorrection>SuspendEvent</DebuggerProperty-DownloadProperty-DebugInformation-EventCorrection>
+      <DebuggerProperty-DownloadProperty-DebugInformation-SkipStartup>True</DebuggerProperty-DownloadProperty-DebugInformation-SkipStartup>
+      <DebuggerProperty-DownloadProperty-DebugInformation-MainSymbol>XwBtAGEAaQBuAA==</DebuggerProperty-DownloadProperty-DebugInformation-MainSymbol>
+      <DebuggerProperty-OptionalProperty-Register-UpdateDisplayInExecutionForPC>No</DebuggerProperty-OptionalProperty-Register-UpdateDisplayInExecutionForPC>
+      <DebuggerProperty-OptionalProperty-Register-UpdateIntervalForPC>500</DebuggerProperty-OptionalProperty-Register-UpdateIntervalForPC>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-Length>17</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-Length>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-MapType>InternalRam</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-StartAddress>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-EndAddress>131071</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-StartAddress>131072</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-EndAddress>524287</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-StartAddress>524288</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-EndAddress>540671</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-StartAddress>540672</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-EndAddress>548863</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-StartAddress>548864</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-EndAddress>557055</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-StartAddress>557056</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-EndAddress>581631</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-StartAddress>581632</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-EndAddress>589823</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-StartAddress>589824</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-EndAddress>655359</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-StartAddress>655360</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-EndAddress>786431</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-StartAddress>786432</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-EndAddress>1048575</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-MapType>InternalRom</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-StartAddress>1048576</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-EndAddress>1081343</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-StartAddress>1081344</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-EndAddress>8372223</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-StartAddress>8372224</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-EndAddress>8373503</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-StartAddress>8373504</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-EndAddress>8387583</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-StartAddress>8387584</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-EndAddress>8388607</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-StartAddress>8388608</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-EndAddress>4293918719</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-MapType>InternalRom</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-StartAddress>4293918720</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-EndAddress>4294967295</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-Endian>
+      <DebuggerProperty-OptionalProperty-AccessMemory-UpdateDisplayInExecution>Yes</DebuggerProperty-OptionalProperty-AccessMemory-UpdateDisplayInExecution>
+      <DebuggerProperty-OptionalProperty-AccessMemory-UpdateInterval>500</DebuggerProperty-OptionalProperty-AccessMemory-UpdateInterval>
+      <DebuggerProperty-OptionalProperty-Trace-UseTrace>No</DebuggerProperty-OptionalProperty-Trace-UseTrace>
+      <DebuggerProperty-OptionalProperty-Trace-ClearTraceMemory>Yes</DebuggerProperty-OptionalProperty-Trace-ClearTraceMemory>
+      <DebuggerProperty-OptionalProperty-Trace-TraceMode>Nonstop</DebuggerProperty-OptionalProperty-Trace-TraceMode>
+      <DebuggerProperty-OptionalProperty-Trace-AddUptimeTag>No</DebuggerProperty-OptionalProperty-Trace-AddUptimeTag>
+      <DebuggerProperty-OptionalProperty-Trace-TraceMemorySize>TraceMemory_64KB</DebuggerProperty-OptionalProperty-Trace-TraceMemorySize>
+      <DebuggerProperty-OptionalProperty-Coverage-UseCoverage>No</DebuggerProperty-OptionalProperty-Coverage-UseCoverage>
+      <DebuggerProperty-OptionalProperty-Coverage-ReuseCoverageData>No</DebuggerProperty-OptionalProperty-Coverage-ReuseCoverageData>
+      <DebuggerProperty-OptionalProperty-StreamIO-SelectStreamIO>Simulator</DebuggerProperty-OptionalProperty-StreamIO-SelectStreamIO>
+      <DebuggerProperty-OptionalProperty-StreamIO-UseStreamIO>No</DebuggerProperty-OptionalProperty-StreamIO-UseStreamIO>
+      <DebuggerProperty-OptionalProperty-StreamIO-StreamIOAddress>0</DebuggerProperty-OptionalProperty-StreamIO-StreamIOAddress>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-ExecutionModeType>Stop</DebuggerProperty-OptionalProperty-ExecutionMode-ExecutionModeType>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopUndefined>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopUndefined>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopPrivileged>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopPrivileged>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopAccess>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopAccess>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopFloatingPoint>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopFloatingPoint>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopInterrupt>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopInterrupt>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopInt>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopInt>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopBrk>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopBrk>
+      <DebuggerProperty-OptionalProperty-InstructionDecodeCache-CacheResults>No</DebuggerProperty-OptionalProperty-InstructionDecodeCache-CacheResults>
+      <DebuggerProperty-HookProperty-HookTransaction-Downloading-Length>0</DebuggerProperty-HookProperty-HookTransaction-Downloading-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Downloaded-Length>0</DebuggerProperty-HookProperty-HookTransaction-Downloaded-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Reset-Length>0</DebuggerProperty-HookProperty-HookTransaction-Reset-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Going-Length>0</DebuggerProperty-HookProperty-HookTransaction-Going-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Broke-Length>0</DebuggerProperty-HookProperty-HookTransaction-Broke-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Connected-Length>0</DebuggerProperty-HookProperty-HookTransaction-Connected-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Disconnecting-Length>0</DebuggerProperty-HookProperty-HookTransaction-Disconnecting-Length>
+      <DebuggerProperty-DownloadProperty-DebugInformation-MaxLoaderMemorySize>500</DebuggerProperty-DownloadProperty-DebugInformation-MaxLoaderMemorySize>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-IsDefaultItem>True</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-IsDefaultItem>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-DefaultItemProjectGuid>c170030b-b19d-470a-99cb-00eb1a66ac6b</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-DefaultItemProjectGuid>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-CompilerType>Auto</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-CompilerType>
+      <DebuggerProperty-DownloadProperty-None-DefaultDownloadItemSupported>True</DebuggerProperty-DownloadProperty-None-DefaultDownloadItemSupported>
+    </Instance>
+  </Class>
+  <Class Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">
+    <Instance Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">
+      <ProductVersion>4.01.00.00</ProductVersion>
+    </Instance>
+  </Class>
+</CubeSuiteProject>
Index: UsbWattMeter/trunk/csp/libasp/dummy.c
===================================================================
--- UsbWattMeter/trunk/csp/libasp/dummy.c	(revision 164)
+++ UsbWattMeter/trunk/csp/libasp/dummy.c	(revision 164)
@@ -0,0 +1,60 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2004-2008 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  J[lì¬p_~[^XN
+ */
+
+#include <kernel.h>
+#include "kernel_cfg.h"
+#include "dummy.h"
+
+/*
+ *  C^XN
+ */
+void dummy_task(intptr_t exinf)
+{
+}
Index: UsbWattMeter/trunk/csp/libasp/dummy.cfg
===================================================================
--- UsbWattMeter/trunk/csp/libasp/dummy.cfg	(revision 164)
+++ UsbWattMeter/trunk/csp/libasp/dummy.cfg	(revision 164)
@@ -0,0 +1,10 @@
+/*
+ *  @(#) $Id$
+ */
+
+/*
+ *  TvvO(1)ÌVXeRtBM
+[Vt@C
+ */
+#include "dummy.h"
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, dummy_task, MAIN_PRIORITY, STACK_SIZE, NULL });
Index: UsbWattMeter/trunk/csp/libasp/dummy.h
===================================================================
--- UsbWattMeter/trunk/csp/libasp/dummy.h	(revision 164)
+++ UsbWattMeter/trunk/csp/libasp/dummy.h	(revision 164)
@@ -0,0 +1,81 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	J[lì¬p_~[^XNÌwb_t@C
+ */
+
+/*
+ *  ^[QbgË¶Ìè`
+ */
+#include "target_test.h"
+
+/*
+ *  e^XNÌDæxÌè`
+ */
+
+#define MAIN_PRIORITY	5		/* C^XNÌDæx */
+
+/*
+ *  ^[QbgÉË¶·éÂ\«Ì éèÌè`
+ */
+
+#ifndef TASK_PORTID
+#define	TASK_PORTID		1			/* ¶üÍ·éVA|[gID */
+#endif /* TASK_PORTID */
+
+#ifndef STACK_SIZE
+#define	STACK_SIZE		4096		/* ^XNÌX^bNTCY */
+#endif /* STACK_SIZE */
+
+/*
+ *  ÖÌvg^Cvé¾
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void	dummy_task(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: UsbWattMeter/trunk/csp/libasp/libasp.mtpj
===================================================================
--- UsbWattMeter/trunk/csp/libasp/libasp.mtpj	(revision 164)
+++ UsbWattMeter/trunk/csp/libasp/libasp.mtpj	(revision 164)
@@ -0,0 +1,1433 @@
+<CubeSuiteProject>
+  <ProductVersion>4.02.00.00</ProductVersion>
+  <Class Guid="68f4a651-b9cd-473b-a595-b00447132ffa">
+    <Instance Guid="00000000-0000-0000-0000-000000000000">
+      <FormatVersion>2.0</FormatVersion>
+      <FileVersion>4.2</FileVersion>
+      <ProjectGuid>150cc6fd-f95b-4858-a2b7-a4a61e9c9529</ProjectGuid>
+      <ProjectItemGuid>a9f64010-8222-4d5e-a730-09e4f4dd7b72</ProjectItemGuid>
+      <FileCategoryGuid>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</FileCategoryGuid>
+      <Property>fb98844b-2c27-4275-9804-f6e63e204da0</Property>
+      <ActiveProjectGuid>150cc6fd-f95b-4858-a2b7-a4a61e9c9529</ActiveProjectGuid>
+    </Instance>
+    <Instance Guid="bbf392be-9376-4aba-bf45-bd3546fe324a">
+      <DependentProjectsGuidsSourceProjectsCount>0</DependentProjectsGuidsSourceProjectsCount>
+      <Type>Data</Type>
+    </Instance>
+    <Instance Guid="418104fd-31b7-4e10-a52a-f3a40218ae47">
+      <Name>alarm.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\alarm.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="2a16567e-8174-41dd-a27a-386158a175b9">
+      <Name>cyclic.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\cyclic.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="7fee077f-b7de-40c9-ae6f-270d4788dfb2">
+      <Name>dataqueue.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\dataqueue.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="d29759b5-0b65-433e-a5dd-eabaa827926e">
+      <Name>eventflag.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\eventflag.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="62cdd7dc-f110-46fd-b286-34e5470c8adf">
+      <Name>exception.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\exception.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="0c3f9205-2818-4d8b-9fdb-70bc98dc06ad">
+      <Name>interrupt.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\interrupt.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="53f28d48-2f3c-4921-87d5-084187a0c09c">
+      <Name>mailbox.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\mailbox.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="d8ec7fa9-8632-4326-a402-eeacf5a9e908">
+      <Name>mempfix.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\mempfix.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="761d7481-e11f-4604-89fe-3027801ca3f3">
+      <Name>pridataq.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\pridataq.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="1d249bd6-772e-4580-bbb0-34a948c6c162">
+      <Name>semaphore.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\semaphore.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="9aa3586d-4df3-430e-8496-da67b6df11c8">
+      <Name>startup.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\startup.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+      <Property>327d4bc3-0935-40d7-ab02-db406b2a8255</Property>
+    </Instance>
+    <Instance Guid="3a8e9b1d-6baa-4c8d-afbf-6aba1462f4f6">
+      <Name>sys_manage.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\sys_manage.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="e4e95360-f85f-4469-b053-ce16e92de312">
+      <Name>task.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\task.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="4ba93070-6c47-43b0-bd20-7ada64b7cf1f">
+      <Name>task_except.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\task_except.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="c68ccba7-5feb-4fc1-b6c6-1aaf66aa1e21">
+      <Name>task_manage.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\task_manage.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="813f006e-dcb2-44ee-80b0-a4456606b25c">
+      <Name>task_refer.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\task_refer.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="d7749f59-8c46-465e-9396-40fbcafd8c1b">
+      <Name>task_sync.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\task_sync.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="2aeaad0c-aef9-466b-acb5-fc12dd38b66a">
+      <Name>time_event.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\time_event.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="e5d7bf19-a826-482d-a700-42d7d39b557a">
+      <Name>time_manage.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\time_manage.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="f35b2475-1163-4fd3-8584-159c3462e074">
+      <Name>wait.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\kernel\wait.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="d15e7073-c94f-4650-ac1c-2508bdbbe93a">
+      <Name>prc_config.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\arch\rx630_ccrx\prc_config.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="d2abd517-45be-45ae-8b92-233b54a5a9f6">
+      <Name>prc_support.src</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\arch\rx630_ccrx\prc_support.src</RelativePath>
+      <TreeImageGuid>f654126d-e7ad-426d-be34-8455271d959b</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="615ab7b6-f056-4147-9b71-8f13cd6dfcc5">
+      <Name>rx630_config.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\arch\rx630_ccrx\rx630_config.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="3f36ed22-46b8-4376-98de-6f9973dd0af1">
+      <Name>target_config.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\target\grsakura_ccrx\target_config.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="f22bd1a3-ee49-4534-bd7c-71c786e19406">
+      <Name>target_serial.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\target\grsakura_ccrx\target_serial.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="490f6f78-f35a-4c25-9787-987f826efe89">
+      <Name>target_timer.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\target\grsakura_ccrx\target_timer.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="98db2870-7312-4fc3-833a-62f65a1dbd09">
+      <Name>target_support.src</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\target\grsakura_ccrx\target_support.src</RelativePath>
+      <TreeImageGuid>f654126d-e7ad-426d-be34-8455271d959b</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="e2945293-5f45-4a79-92cb-e335f3cb6c87">
+      <Name>rx630_uart.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\pdic\rx600\rx630_uart.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+    </Instance>
+    <Instance Guid="db552b0d-ce14-4338-ad3c-4c4353102b71">
+      <Name>mem_pool.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\library\mem_pool.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+      <Property>299404f2-f430-460f-8b14-4b95a803bdf0</Property>
+    </Instance>
+    <Instance Guid="b19e241d-c82f-4d73-9bc0-36e68e4baa8d">
+      <Name>tlsf.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\tlsf-3.0\tlsf.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>04c58fd6-d589-4a0b-85c2-7233ec6f5a10</ParentItem>
+      <Property>0b60db49-c55e-43a1-b3e3-df28dd378663</Property>
+    </Instance>
+  </Class>
+  <Class Guid="9033e9fb-2b12-4437-a25e-27b28d42582b">
+    <Instance Guid="c170030b-b19d-470a-99cb-00eb1a66ac6b">
+      <Name>cfg</Name>
+      <RelativePath>cfg\cfg.mtsp</RelativePath>
+    </Instance>
+  </Class>
+  <Class Guid="fb98844b-2c27-4275-9804-f6e63e204da0">
+    <Instance Guid="fb98844b-2c27-4275-9804-f6e63e204da0">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="0d548289-d5e9-4893-9a8f-9374b13f19a9">
+    <Instance Guid="327d4bc3-0935-40d7-ab02-db406b2a8255">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="299404f2-f430-460f-8b14-4b95a803bdf0">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="0b60db49-c55e-43a1-b3e3-df28dd378663">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="8fb9c1f6-d351-4d10-8d99-bf5b3015b84c">
+    <Instance Guid="00000000-0000-0000-0000-000000000000">
+      <UsingPlatformGuid>7020d445-1358-4043-a8ea-3b101e73ceaa</UsingPlatformGuid>
+      <UsingPlatformTypeGuid>f96683fa-8de4-4c6d-a1ab-925d7f232c09</UsingPlatformTypeGuid>
+    </Instance>
+  </Class>
+  <Class Guid="c325714f-8f51-484b-9e96-b4b59c0fb263">
+    <Instance Guid="c325714f-8f51-484b-9e96-b4b59c0fb263">
+      <DeviceManager>0e793ff3-2e3f-43c0-bdc9-926269595403</DeviceManager>
+    </Instance>
+  </Class>
+  <Class Guid="0e793ff3-2e3f-43c0-bdc9-926269595403">
+    <Instance Guid="0e793ff3-2e3f-43c0-bdc9-926269595403">
+      <DataFormatVersion>1.0</DataFormatVersion>
+    </Instance>
+    <Instance Guid="2a81c37a-5015-44c2-9f40-e58b669eec75">
+      <DeviceName>R5F563NBDxFP</DeviceName>
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="873c9a58-9bc5-439a-b476-78629a4553ed">
+    <Instance Guid="873c9a58-9bc5-439a-b476-78629a4553ed">
+      <ProjectDeviceChangedCounter>0</ProjectDeviceChangedCounter>
+      <ProjectInitialDeviceName>R5F563NBDxFP</ProjectInitialDeviceName>
+    </Instance>
+  </Class>
+  <Class Guid="c3835e31-dea3-4c93-b02b-d2db997f7630">
+    <Instance Guid="c3835e31-dea3-4c93-b02b-d2db997f7630">
+      <BuildToolManager>3a79707d-5977-45f7-ac11-19c35e333132</BuildToolManager>
+    </Instance>
+  </Class>
+  <Class Guid="3a79707d-5977-45f7-ac11-19c35e333132">
+    <Instance Guid="3a79707d-5977-45f7-ac11-19c35e333132">
+      <DataFormatVersion>1.2</DataFormatVersion>
+      <BuildModeCount>1</BuildModeCount>
+      <BuildMode0>RABlAGYAYQB1AGwAdABCAHUAaQBsAGQA</BuildMode0>
+      <BatchBuildFlag0>False</BatchBuildFlag0>
+      <CurrentBuildMode>DefaultBuild</CurrentBuildMode>
+      <SourceItemGuid0>418104fd-31b7-4e10-a52a-f3a40218ae47</SourceItemGuid0>
+      <SourceItemType0>CSource</SourceItemType0>
+      <SourceItemGuid1>2a16567e-8174-41dd-a27a-386158a175b9</SourceItemGuid1>
+      <SourceItemType1>CSource</SourceItemType1>
+      <SourceItemGuid2>7fee077f-b7de-40c9-ae6f-270d4788dfb2</SourceItemGuid2>
+      <SourceItemType2>CSource</SourceItemType2>
+      <SourceItemGuid3>d29759b5-0b65-433e-a5dd-eabaa827926e</SourceItemGuid3>
+      <SourceItemType3>CSource</SourceItemType3>
+      <SourceItemGuid4>62cdd7dc-f110-46fd-b286-34e5470c8adf</SourceItemGuid4>
+      <SourceItemType4>CSource</SourceItemType4>
+      <SourceItemGuid5>0c3f9205-2818-4d8b-9fdb-70bc98dc06ad</SourceItemGuid5>
+      <SourceItemType5>CSource</SourceItemType5>
+      <SourceItemGuid6>53f28d48-2f3c-4921-87d5-084187a0c09c</SourceItemGuid6>
+      <SourceItemType6>CSource</SourceItemType6>
+      <SourceItemGuid7>d8ec7fa9-8632-4326-a402-eeacf5a9e908</SourceItemGuid7>
+      <SourceItemType7>CSource</SourceItemType7>
+      <SourceItemGuid8>761d7481-e11f-4604-89fe-3027801ca3f3</SourceItemGuid8>
+      <SourceItemType8>CSource</SourceItemType8>
+      <SourceItemGuid9>1d249bd6-772e-4580-bbb0-34a948c6c162</SourceItemGuid9>
+      <SourceItemType9>CSource</SourceItemType9>
+      <SourceItemGuid10>9aa3586d-4df3-430e-8496-da67b6df11c8</SourceItemGuid10>
+      <SourceItemType10>CSource</SourceItemType10>
+      <SourceItemGuid11>3a8e9b1d-6baa-4c8d-afbf-6aba1462f4f6</SourceItemGuid11>
+      <SourceItemType11>CSource</SourceItemType11>
+      <SourceItemGuid12>e4e95360-f85f-4469-b053-ce16e92de312</SourceItemGuid12>
+      <SourceItemType12>CSource</SourceItemType12>
+      <SourceItemGuid13>4ba93070-6c47-43b0-bd20-7ada64b7cf1f</SourceItemGuid13>
+      <SourceItemType13>CSource</SourceItemType13>
+      <SourceItemGuid14>c68ccba7-5feb-4fc1-b6c6-1aaf66aa1e21</SourceItemGuid14>
+      <SourceItemType14>CSource</SourceItemType14>
+      <SourceItemGuid15>813f006e-dcb2-44ee-80b0-a4456606b25c</SourceItemGuid15>
+      <SourceItemType15>CSource</SourceItemType15>
+      <SourceItemGuid16>d7749f59-8c46-465e-9396-40fbcafd8c1b</SourceItemGuid16>
+      <SourceItemType16>CSource</SourceItemType16>
+      <SourceItemGuid17>2aeaad0c-aef9-466b-acb5-fc12dd38b66a</SourceItemGuid17>
+      <SourceItemType17>CSource</SourceItemType17>
+      <SourceItemGuid18>e5d7bf19-a826-482d-a700-42d7d39b557a</SourceItemGuid18>
+      <SourceItemType18>CSource</SourceItemType18>
+      <SourceItemGuid19>f35b2475-1163-4fd3-8584-159c3462e074</SourceItemGuid19>
+      <SourceItemType19>CSource</SourceItemType19>
+      <SourceItemGuid20>d15e7073-c94f-4650-ac1c-2508bdbbe93a</SourceItemGuid20>
+      <SourceItemType20>CSource</SourceItemType20>
+      <SourceItemGuid21>d2abd517-45be-45ae-8b92-233b54a5a9f6</SourceItemGuid21>
+      <SourceItemType21>AsmSource</SourceItemType21>
+      <SourceItemGuid22>615ab7b6-f056-4147-9b71-8f13cd6dfcc5</SourceItemGuid22>
+      <SourceItemType22>CSource</SourceItemType22>
+      <SourceItemGuid23>3f36ed22-46b8-4376-98de-6f9973dd0af1</SourceItemGuid23>
+      <SourceItemType23>CSource</SourceItemType23>
+      <SourceItemGuid24>f22bd1a3-ee49-4534-bd7c-71c786e19406</SourceItemGuid24>
+      <SourceItemType24>CSource</SourceItemType24>
+      <SourceItemGuid25>490f6f78-f35a-4c25-9787-987f826efe89</SourceItemGuid25>
+      <SourceItemType25>CSource</SourceItemType25>
+      <SourceItemGuid26>98db2870-7312-4fc3-833a-62f65a1dbd09</SourceItemGuid26>
+      <SourceItemType26>AsmSource</SourceItemType26>
+      <SourceItemGuid27>e2945293-5f45-4a79-92cb-e335f3cb6c87</SourceItemGuid27>
+      <SourceItemType27>CSource</SourceItemType27>
+      <SourceItemGuid28>db552b0d-ce14-4338-ad3c-4c4353102b71</SourceItemGuid28>
+      <SourceItemType28>CSource</SourceItemType28>
+      <SourceItemGuid29>b19e241d-c82f-4d73-9bc0-36e68e4baa8d</SourceItemGuid29>
+      <SourceItemType29>CSource</SourceItemType29>
+      <SourceItemCount>30</SourceItemCount>
+      <LastDeviceChangedCounter>0</LastDeviceChangedCounter>
+    </Instance>
+    <Instance Guid="9e208646-ccba-4100-a676-29b1efe6545f">
+      <AsmOptionInclude-DefaultValue />
+      <BuildMode-DefaultValue>DefaultBuild</BuildMode-DefaultValue>
+      <COptionInclude-DefaultValue />
+      <GeneralOptionIsa-DefaultValue>RXv1</GeneralOptionIsa-DefaultValue>
+      <GeneralOptionOutput-DefaultValue>LibraryFile</GeneralOptionOutput-DefaultValue>
+      <GeneralOptionPic-DefaultValue>False</GeneralOptionPic-DefaultValue>
+      <GeneralOptionSimultaneousBuild-DefaultValue>True</GeneralOptionSimultaneousBuild-DefaultValue>
+      <HexOptionOutput-DefaultValue>True</HexOptionOutput-DefaultValue>
+      <LibOptionDebug-DefaultValue>Debug</LibOptionDebug-DefaultValue>
+      <LinkOptionLibrary-DefaultValue />
+      <Memo-DefaultValue />
+      <OutputMessageFormat-DefaultValue>%TargetFiles%</OutputMessageFormat-DefaultValue>
+      <AsmOptionSystemInclude-DefaultValue />
+      <COptionSystemInclude-DefaultValue />
+      <CompilerVersion-DefaultValue>
+
+0</CompilerVersion-DefaultValue>
+      <DependencyFileExistCheckingType-DefaultValue>Rebuild</DependencyFileExistCheckingType-DefaultValue>
+      <FormatBuildOptionList-DefaultValue>%TargetFiles% : %Program% %Options%</FormatBuildOptionList-DefaultValue>
+      <GeneralOptionCpu-DefaultValue>RX600</GeneralOptionCpu-DefaultValue>
+      <GeneralOptionOutputFolder-DefaultValue>%BuildModeName%</GeneralOptionOutputFolder-DefaultValue>
+      <GeneralOptionPid-DefaultValue>None</GeneralOptionPid-DefaultValue>
+      <HexOptionForm-DefaultValue>Stype</HexOptionForm-DefaultValue>
+      <LinkOptionDebug-DefaultValue>Debug</LinkOptionDebug-DefaultValue>
+      <AsmOptionDefine-DefaultValue />
+      <COptionDefine-DefaultValue />
+      <EnsureCompatibilityOfPathAndLinkageOrder-DefaultValue>False</EnsureCompatibilityOfPathAndLinkageOrder-DefaultValue>
+      <GeneralOptionFpu-DefaultValue>Auto</GeneralOptionFpu-DefaultValue>
+      <GeneralOptionNousePidRegister-DefaultValue>True</GeneralOptionNousePidRegister-DefaultValue>
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionOptimize-DefaultValue>None</LinkOptionOptimize-DefaultValue>
+      <AsmOptionDebug-DefaultValue>True</AsmOptionDebug-DefaultValue>
+      <COptionDebug-DefaultValue>True</COptionDebug-DefaultValue>
+      <GeneralOptionEndian-DefaultValue>Little</GeneralOptionEndian-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionOptimizeSymbolDelete-DefaultValue>False</LinkOptionOptimizeSymbolDelete-DefaultValue>
+      <PreBuildCommands-DefaultValue />
+      <AsmOptionGoptimize-DefaultValue>False</AsmOptionGoptimize-DefaultValue>
+      <COptionOptimize-DefaultValue>Level2</COptionOptimize-DefaultValue>
+      <GeneralOptionRound-DefaultValue>Nearest</GeneralOptionRound-DefaultValue>
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionOptimizeSameCode-DefaultValue>False</LinkOptionOptimizeSameCode-DefaultValue>
+      <PostBuildCommands-DefaultValue />
+      <AsmOptionListFile-DefaultValue>False</AsmOptionListFile-DefaultValue>
+      <COptionGoptimize-DefaultValue>False</COptionGoptimize-DefaultValue>
+      <GeneralOptionDenormalize-DefaultValue>Off</GeneralOptionDenormalize-DefaultValue>
+      <LinkOptionSameSize-DefaultValue>1E</LinkOptionSameSize-DefaultValue>
+      <AsmOptionShowConditionals-DefaultValue>False</AsmOptionShowConditionals-DefaultValue>
+      <COptionSpeedAndSize-DefaultValue>Size</COptionSpeedAndSize-DefaultValue>
+      <GeneralOptionDblSize-DefaultValue>SinglePrecision</GeneralOptionDblSize-DefaultValue>
+      <LinkOptionOptimizeShortFormat-DefaultValue>False</LinkOptionOptimizeShortFormat-DefaultValue>
+      <AsmOptionShowDefinitions-DefaultValue>False</AsmOptionShowDefinitions-DefaultValue>
+      <COptionListfile-DefaultValue>False</COptionListfile-DefaultValue>
+      <GeneralOptionIntToShort-DefaultValue>False</GeneralOptionIntToShort-DefaultValue>
+      <LinkOptionOptimizeBranch-DefaultValue>False</LinkOptionOptimizeBranch-DefaultValue>
+      <AsmOptionShowExpansions-DefaultValue>False</AsmOptionShowExpansions-DefaultValue>
+      <COptionShowSource-DefaultValue>False</COptionShowSource-DefaultValue>
+      <GeneralOptionSignedChar-DefaultValue>Unsigned</GeneralOptionSignedChar-DefaultValue>
+      <LinkOptionStart-DefaultValue />
+      <COptionShowConditionals-DefaultValue>False</COptionShowConditionals-DefaultValue>
+      <GeneralOptionOtherAdditionalOptions-DefaultValue />
+      <GeneralOptionSignedBitfield-DefaultValue>Unsigned</GeneralOptionSignedBitfield-DefaultValue>
+      <COptionShowDefinitions-DefaultValue>False</COptionShowDefinitions-DefaultValue>
+      <GeneralOptionAutoEnum-DefaultValue>False</GeneralOptionAutoEnum-DefaultValue>
+      <COptionShowExpansions-DefaultValue>False</COptionShowExpansions-DefaultValue>
+      <GeneralOptionBitOrder-DefaultValue>Right</GeneralOptionBitOrder-DefaultValue>
+      <GeneralOptionPack-DefaultValue>False</GeneralOptionPack-DefaultValue>
+      <GeneralOptionException-DefaultValue>False</GeneralOptionException-DefaultValue>
+      <GeneralOptionRtti-DefaultValue>False</GeneralOptionRtti-DefaultValue>
+      <GeneralOptionFintRegister-DefaultValue>None</GeneralOptionFintRegister-DefaultValue>
+      <GeneralOptionBranch-DefaultValue>Branch24</GeneralOptionBranch-DefaultValue>
+      <GeneralOptionBaseRomRegister-DefaultValue>None</GeneralOptionBaseRomRegister-DefaultValue>
+      <GeneralOptionBaseRamRegister-DefaultValue>None</GeneralOptionBaseRamRegister-DefaultValue>
+      <GeneralOptionBaseAddressAddress-DefaultValue>00000000</GeneralOptionBaseAddressAddress-DefaultValue>
+      <GeneralOptionBaseAddressRegister-DefaultValue>None</GeneralOptionBaseAddressRegister-DefaultValue>
+      <GeneralOptionPatch-DefaultValue>None</GeneralOptionPatch-DefaultValue>
+      <GeneralOptionSaveAcc-DefaultValue>False</GeneralOptionSaveAcc-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587442586619935989</TimeTagModified--0>
+      <BuildMode-0>DefaultBuild</BuildMode-0>
+      <Memo-0 />
+      <OutputMessageFormat-0>%TargetFiles%</OutputMessageFormat-0>
+      <FormatBuildOptionList-0>%TargetFiles% : %Program% %Options%</FormatBuildOptionList-0>
+      <PreBuildCommands-0 />
+      <PostBuildCommands-0 />
+      <GeneralOptionIsa-0>None</GeneralOptionIsa-0>
+      <GeneralOptionOutput-0>LibraryFile</GeneralOptionOutput-0>
+      <GeneralOptionPic-0>False</GeneralOptionPic-0>
+      <GeneralOptionSimultaneousBuild-0>True</GeneralOptionSimultaneousBuild-0>
+      <CompilerVersion-0>
+
+0</CompilerVersion-0>
+      <DependencyFileExistCheckingType-0>Rebuild</DependencyFileExistCheckingType-0>
+      <GeneralOptionCpu-0>RX600</GeneralOptionCpu-0>
+      <GeneralOptionOutputFolder-0>%BuildModeName%</GeneralOptionOutputFolder-0>
+      <GeneralOptionPid-0>None</GeneralOptionPid-0>
+      <EnsureCompatibilityOfPathAndLinkageOrder-0>False</EnsureCompatibilityOfPathAndLinkageOrder-0>
+      <GeneralOptionFpu-0>Fpu</GeneralOptionFpu-0>
+      <GeneralOptionNousePidRegister-0>True</GeneralOptionNousePidRegister-0>
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <GeneralOptionEndian-0>Little</GeneralOptionEndian-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <AsmOptionGoptimize-0>False</AsmOptionGoptimize-0>
+      <GeneralOptionRound-0>Nearest</GeneralOptionRound-0>
+      <LinkOptionMultiConvertFileName-0 />
+      <AsmOptionListFile-0>False</AsmOptionListFile-0>
+      <COptionGoptimize-0>False</COptionGoptimize-0>
+      <GeneralOptionDenormalize-0>Off</GeneralOptionDenormalize-0>
+      <AsmOptionShowConditionals-0>False</AsmOptionShowConditionals-0>
+      <GeneralOptionDblSize-0>SinglePrecision</GeneralOptionDblSize-0>
+      <AsmOptionShowDefinitions-0>False</AsmOptionShowDefinitions-0>
+      <COptionListfile-0>False</COptionListfile-0>
+      <GeneralOptionIntToShort-0>False</GeneralOptionIntToShort-0>
+      <AsmOptionShowExpansions-0>False</AsmOptionShowExpansions-0>
+      <COptionShowSource-0>False</COptionShowSource-0>
+      <GeneralOptionSignedChar-0>Unsigned</GeneralOptionSignedChar-0>
+      <COptionShowConditionals-0>False</COptionShowConditionals-0>
+      <GeneralOptionOtherAdditionalOptions-0 />
+      <GeneralOptionSignedBitfield-0>Unsigned</GeneralOptionSignedBitfield-0>
+      <COptionShowDefinitions-0>False</COptionShowDefinitions-0>
+      <GeneralOptionAutoEnum-0>False</GeneralOptionAutoEnum-0>
+      <COptionShowExpansions-0>False</COptionShowExpansions-0>
+      <GeneralOptionBitOrder-0>Right</GeneralOptionBitOrder-0>
+      <GeneralOptionPack-0>False</GeneralOptionPack-0>
+      <GeneralOptionException-0>False</GeneralOptionException-0>
+      <GeneralOptionRtti-0>False</GeneralOptionRtti-0>
+      <GeneralOptionFintRegister-0>None</GeneralOptionFintRegister-0>
+      <GeneralOptionBranch-0>Branch24</GeneralOptionBranch-0>
+      <GeneralOptionBaseRomRegister-0>None</GeneralOptionBaseRomRegister-0>
+      <GeneralOptionBaseRamRegister-0>None</GeneralOptionBaseRamRegister-0>
+      <GeneralOptionBaseAddressAddress-0>00000000</GeneralOptionBaseAddressAddress-0>
+      <GeneralOptionBaseAddressRegister-0>None</GeneralOptionBaseAddressRegister-0>
+      <GeneralOptionPatch-0>None</GeneralOptionPatch-0>
+      <GeneralOptionSaveAcc-0>False</GeneralOptionSaveAcc-0>
+      <LastCompilerVersion-0>V2.02.00</LastCompilerVersion-0>
+    </Instance>
+    <Instance Guid="95a63257-4aa7-40c0-a74a-7991543b099b">
+      <COptionLangC-DefaultValue>C</COptionLangC-DefaultValue>
+      <COptionListfile-DefaultValue>False</COptionListfile-DefaultValue>
+      <COptionLogo-DefaultValue>False</COptionLogo-DefaultValue>
+      <COptionMisra2004-DefaultValue>None</COptionMisra2004-DefaultValue>
+      <COptionOptimize-DefaultValue>Level2</COptionOptimize-DefaultValue>
+      <COptionOutput-DefaultValue>Object</COptionOutput-DefaultValue>
+      <COptionOutputAssembly-DefaultValue>False</COptionOutputAssembly-DefaultValue>
+      <COptionGoptimize-DefaultValue>False</COptionGoptimize-DefaultValue>
+      <COptionLangCpp-DefaultValue>Cpp</COptionLangCpp-DefaultValue>
+      <COptionMisra2004RuleFile-DefaultValue />
+      <COptionOutputFolder-DefaultValue>%BuildModeName%</COptionOutputFolder-DefaultValue>
+      <COptionOutputPreprocessed-DefaultValue>None</COptionOutputPreprocessed-DefaultValue>
+      <COptionShowSource-DefaultValue>False</COptionShowSource-DefaultValue>
+      <COptionXcref-DefaultValue>False</COptionXcref-DefaultValue>
+      <COptionDebug-DefaultValue>True</COptionDebug-DefaultValue>
+      <COptionInclude-DefaultValue />
+      <COptionMisra2004RuleNumberApply-DefaultValue />
+      <COptionPreCompileCommands-DefaultValue />
+      <COptionShowConditionals-DefaultValue>False</COptionShowConditionals-DefaultValue>
+      <COptionSpeedAndSize-DefaultValue>Size</COptionSpeedAndSize-DefaultValue>
+      <COptionLoop-DefaultValue>Auto</COptionLoop-DefaultValue>
+      <COptionMisra2004RuleNumberIgnore-DefaultValue />
+      <COptionPostCompileCommands-DefaultValue />
+      <COptionSectionP-DefaultValue>P</COptionSectionP-DefaultValue>
+      <COptionShowDefinitions-DefaultValue>False</COptionShowDefinitions-DefaultValue>
+      <COptionSystemInclude-DefaultValue />
+      <COptionLoopValue-DefaultValue>2</COptionLoopValue-DefaultValue>
+      <COptionMisra2004RuleNumberRequiredAdd-DefaultValue />
+      <COptionOtherAdditionalOptions-DefaultValue />
+      <COptionPreinclude-DefaultValue />
+      <COptionSectionC-DefaultValue>C</COptionSectionC-DefaultValue>
+      <COptionShowExpansions-DefaultValue>False</COptionShowExpansions-DefaultValue>
+      <COptionCommandLine-DefaultValue>-cpu=rx600
+-fpu
+-include=..\..\asp_dcre
+-include=..\..\asp_dcre\arch
+-include=..\..\asp_dcre\include
+-include=..\..\asp_dcre\kernel
+-include=..\..\asp_dcre\arch
+-include=..\..\asp_dcre\syssvc
+-include=..\..\asp_dcre\library
+-include=..\..\asp_dcre\pdic
+-include=..\..\asp_dcre\target\grsakura_ccrx
+-include=..\..\tlsf-3.0
+-include=.
+-define=ALLFUNC,OMIT_KMM_ALLOCONLY
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</COptionCommandLine-DefaultValue>
+      <COptionDefine-DefaultValue />
+      <COptionInline-DefaultValue>Auto</COptionInline-DefaultValue>
+      <COptionMisra2004RuleNumberRequiredRemove-DefaultValue />
+      <COptionSectionD-DefaultValue>D</COptionSectionD-DefaultValue>
+      <COptionIgnoreFilesMisra-DefaultValue />
+      <COptionInlineValue-DefaultValue>100</COptionInlineValue-DefaultValue>
+      <COptionSectionB-DefaultValue>B</COptionSectionB-DefaultValue>
+      <COptionUndefine-DefaultValue />
+      <COptionCheckLanguageExtension-DefaultValue>False</COptionCheckLanguageExtension-DefaultValue>
+      <COptionFileInline-DefaultValue />
+      <COptionMessage-DefaultValue>False</COptionMessage-DefaultValue>
+      <COptionSectionL-DefaultValue>L</COptionSectionL-DefaultValue>
+      <COptionCase-DefaultValue>Auto</COptionCase-DefaultValue>
+      <COptionMessage2-DefaultValue>False</COptionMessage2-DefaultValue>
+      <COptionSectionW-DefaultValue>W</COptionSectionW-DefaultValue>
+      <COptionNoMessageErrorNumber-DefaultValue />
+      <COptionNostuffB-DefaultValue>False</COptionNostuffB-DefaultValue>
+      <COptionVolatile-DefaultValue>False</COptionVolatile-DefaultValue>
+      <COptionConstCopy-DefaultValue>Auto</COptionConstCopy-DefaultValue>
+      <COptionNoMessageErrorNumber2-DefaultValue />
+      <COptionNostuffD-DefaultValue>False</COptionNostuffD-DefaultValue>
+      <COptionChangeMessageInformation-DefaultValue>No</COptionChangeMessageInformation-DefaultValue>
+      <COptionConstDiv-DefaultValue>Auto</COptionConstDiv-DefaultValue>
+      <COptionNostuffC-DefaultValue>False</COptionNostuffC-DefaultValue>
+      <COptionChangeMessageInformationNumber-DefaultValue />
+      <COptionLibrary-DefaultValue>Intrinsic</COptionLibrary-DefaultValue>
+      <COptionNostuffW-DefaultValue>False</COptionNostuffW-DefaultValue>
+      <COptionChangeMessageInformationNumber2-DefaultValue />
+      <COptionInstalign-DefaultValue>Noinstalign</COptionInstalign-DefaultValue>
+      <COptionScope-DefaultValue>Auto</COptionScope-DefaultValue>
+      <COptionChangeMessageWarning-DefaultValue>No</COptionChangeMessageWarning-DefaultValue>
+      <COptionNouseDiv-DefaultValue>True</COptionNouseDiv-DefaultValue>
+      <COptionSchedule-DefaultValue>Auto</COptionSchedule-DefaultValue>
+      <COptionChangeMessageWarningNumber-DefaultValue />
+      <COptionMap-DefaultValue>NoMap</COptionMap-DefaultValue>
+      <COptionOutcode-DefaultValue>Sjis</COptionOutcode-DefaultValue>
+      <COptionChangeMessageWarningNumber2-DefaultValue />
+      <COptionIntermodule-DefaultValue>None</COptionIntermodule-DefaultValue>
+      <COptionApproxdiv-DefaultValue>False</COptionApproxdiv-DefaultValue>
+      <COptionChangeMessageError-DefaultValue>No</COptionChangeMessageError-DefaultValue>
+      <COptionChangeMessageErrorNumber-DefaultValue />
+      <COptionEnableRegister-DefaultValue>False</COptionEnableRegister-DefaultValue>
+      <COptionChangeMessageErrorNumber2-DefaultValue />
+      <COptionSimpleFloatConv-DefaultValue>False</COptionSimpleFloatConv-DefaultValue>
+      <COptionFileInlinePath-DefaultValue />
+      <COptionFpu-DefaultValue>Fpu</COptionFpu-DefaultValue>
+      <COptionAlias-DefaultValue>False</COptionAlias-DefaultValue>
+      <COptionComment-DefaultValue>False</COptionComment-DefaultValue>
+      <COptionCheck-DefaultValue>No</COptionCheck-DefaultValue>
+      <COptionFloatOrder-DefaultValue>False</COptionFloatOrder-DefaultValue>
+      <COptionIncode-DefaultValue>Sjis</COptionIncode-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587490387675759622</TimeTagModified--0>
+      <COptionLangC-0>C99</COptionLangC-0>
+      <COptionListfile-0>False</COptionListfile-0>
+      <COptionLogo-0>False</COptionLogo-0>
+      <COptionMisra2004-0>None</COptionMisra2004-0>
+      <COptionOptimize-0>Level2</COptionOptimize-0>
+      <COptionOutput-0>Object</COptionOutput-0>
+      <COptionOutputAssembly-0>False</COptionOutputAssembly-0>
+      <COptionGoptimize-0>False</COptionGoptimize-0>
+      <COptionLangCpp-0>Cpp</COptionLangCpp-0>
+      <COptionMisra2004RuleFile-0 />
+      <COptionOutputFolder-0>%BuildModeName%</COptionOutputFolder-0>
+      <COptionOutputPreprocessed-0>None</COptionOutputPreprocessed-0>
+      <COptionShowSource-0>False</COptionShowSource-0>
+      <COptionXcref-0>False</COptionXcref-0>
+      <COptionDebug-0>True</COptionDebug-0>
+      <COptionInclude-0>..\..\asp_dcre
+..\..\asp_dcre\arch
+..\..\asp_dcre\include
+..\..\asp_dcre\kernel
+..\..\asp_dcre\arch
+..\..\asp_dcre\syssvc
+..\..\asp_dcre\library
+..\..\asp_dcre\pdic
+..\..\asp_dcre\target\grsakura_ccrx
+..\..\tlsf-3.0
+.
+</COptionInclude-0>
+      <COptionMisra2004RuleNumberApply-0 />
+      <COptionPreCompileCommands-0 />
+      <COptionShowConditionals-0>False</COptionShowConditionals-0>
+      <COptionSpeedAndSize-0>Size</COptionSpeedAndSize-0>
+      <COptionLoop-0>Auto</COptionLoop-0>
+      <COptionMisra2004RuleNumberIgnore-0 />
+      <COptionPostCompileCommands-0 />
+      <COptionSectionP-0>P</COptionSectionP-0>
+      <COptionShowDefinitions-0>False</COptionShowDefinitions-0>
+      <COptionSystemInclude-0 />
+      <COptionLoopValue-0>2</COptionLoopValue-0>
+      <COptionMisra2004RuleNumberRequiredAdd-0 />
+      <COptionOtherAdditionalOptions-0 />
+      <COptionPreinclude-0 />
+      <COptionSectionC-0>C</COptionSectionC-0>
+      <COptionShowExpansions-0>False</COptionShowExpansions-0>
+      <COptionCommandLine-0>-cpu=rx600
+-fpu
+-include=..\..\asp_dcre
+-include=..\..\asp_dcre\arch
+-include=..\..\asp_dcre\include
+-include=..\..\asp_dcre\kernel
+-include=..\..\asp_dcre\arch
+-include=..\..\asp_dcre\syssvc
+-include=..\..\asp_dcre\library
+-include=..\..\asp_dcre\pdic
+-include=..\..\asp_dcre\target\grsakura_ccrx
+-include=..\..\tlsf-3.0
+-include=.
+-define=ALLFUNC,OMIT_KMM_ALLOCONLY
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</COptionCommandLine-0>
+      <COptionDefine-0>ALLFUNC
+OMIT_KMM_ALLOCONLY
+</COptionDefine-0>
+      <COptionInline-0>Auto</COptionInline-0>
+      <COptionMisra2004RuleNumberRequiredRemove-0 />
+      <COptionSectionD-0>D</COptionSectionD-0>
+      <COptionIgnoreFilesMisra-0 />
+      <COptionInlineValue-0>100</COptionInlineValue-0>
+      <COptionSectionB-0>B</COptionSectionB-0>
+      <COptionUndefine-0 />
+      <COptionCheckLanguageExtension-0>False</COptionCheckLanguageExtension-0>
+      <COptionFileInline-0 />
+      <COptionMessage-0>False</COptionMessage-0>
+      <COptionSectionL-0>L</COptionSectionL-0>
+      <COptionCase-0>Auto</COptionCase-0>
+      <COptionSectionW-0>W</COptionSectionW-0>
+      <COptionNoMessageErrorNumber-0 />
+      <COptionNostuffB-0>False</COptionNostuffB-0>
+      <COptionVolatile-0>False</COptionVolatile-0>
+      <COptionConstCopy-0>Auto</COptionConstCopy-0>
+      <COptionNostuffD-0>False</COptionNostuffD-0>
+      <COptionChangeMessageInformation-0>No</COptionChangeMessageInformation-0>
+      <COptionConstDiv-0>Auto</COptionConstDiv-0>
+      <COptionNostuffC-0>False</COptionNostuffC-0>
+      <COptionChangeMessageInformationNumber-0 />
+      <COptionLibrary-0>Intrinsic</COptionLibrary-0>
+      <COptionNostuffW-0>False</COptionNostuffW-0>
+      <COptionInstalign-0>Noinstalign</COptionInstalign-0>
+      <COptionScope-0>Auto</COptionScope-0>
+      <COptionChangeMessageWarning-0>No</COptionChangeMessageWarning-0>
+      <COptionNouseDiv-0>True</COptionNouseDiv-0>
+      <COptionSchedule-0>Auto</COptionSchedule-0>
+      <COptionChangeMessageWarningNumber-0 />
+      <COptionMap-0>NoMap</COptionMap-0>
+      <COptionOutcode-0>Sjis</COptionOutcode-0>
+      <COptionIntermodule-0>None</COptionIntermodule-0>
+      <COptionApproxdiv-0>False</COptionApproxdiv-0>
+      <COptionChangeMessageError-0>No</COptionChangeMessageError-0>
+      <COptionChangeMessageErrorNumber-0 />
+      <COptionEnableRegister-0>False</COptionEnableRegister-0>
+      <COptionSimpleFloatConv-0>False</COptionSimpleFloatConv-0>
+      <COptionFileInlinePath-0 />
+      <COptionFpu-0>Fpu</COptionFpu-0>
+      <COptionAlias-0>False</COptionAlias-0>
+      <COptionComment-0>False</COptionComment-0>
+      <COptionCheck-0>No</COptionCheck-0>
+      <COptionFloatOrder-0>False</COptionFloatOrder-0>
+      <COptionIncode-0>Sjis</COptionIncode-0>
+    </Instance>
+    <Instance Guid="5ad1746c-d03e-4610-a91f-aaa4fb37bc10">
+      <AsmOptionChkpm-DefaultValue>False</AsmOptionChkpm-DefaultValue>
+      <AsmOptionGoptimize-DefaultValue>False</AsmOptionGoptimize-DefaultValue>
+      <AsmOptionInclude-DefaultValue />
+      <AsmOptionListFile-DefaultValue>False</AsmOptionListFile-DefaultValue>
+      <AsmOptionOutput-DefaultValue>%BuildModeName%</AsmOptionOutput-DefaultValue>
+      <AsmOptionChkfpu-DefaultValue>False</AsmOptionChkfpu-DefaultValue>
+      <AsmOptionDebug-DefaultValue>True</AsmOptionDebug-DefaultValue>
+      <AsmOptionShowConditionals-DefaultValue>False</AsmOptionShowConditionals-DefaultValue>
+      <AsmOptionSystemInclude-DefaultValue />
+      <AsmOptionChkdsp-DefaultValue>False</AsmOptionChkdsp-DefaultValue>
+      <AsmOptionDefine-DefaultValue />
+      <AsmOptionShowDefinitions-DefaultValue>False</AsmOptionShowDefinitions-DefaultValue>
+      <AsmOptionInCode-DefaultValue>SJIS</AsmOptionInCode-DefaultValue>
+      <AsmOptionLogo-DefaultValue>False</AsmOptionLogo-DefaultValue>
+      <AsmOptionShowExpansions-DefaultValue>False</AsmOptionShowExpansions-DefaultValue>
+      <AsmOptionPreAssembleCommands-DefaultValue />
+      <AsmOptionPostAssembleCommands-DefaultValue />
+      <AsmOptionOtherAdditionalOptions-DefaultValue />
+      <AsmOptionCommandLine-DefaultValue>-isa=rxv1
+-include=..\..\asp_dcre\target\grsakura_ccrx
+-include=.
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</AsmOptionCommandLine-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053511973115383</TimeTagModified--0>
+      <AsmOptionChkpm-0>False</AsmOptionChkpm-0>
+      <AsmOptionGoptimize-0>False</AsmOptionGoptimize-0>
+      <AsmOptionInclude-0>..\..\asp_dcre\target\grsakura_ccrx
+.
+</AsmOptionInclude-0>
+      <AsmOptionListFile-0>False</AsmOptionListFile-0>
+      <AsmOptionOutput-0>%BuildModeName%</AsmOptionOutput-0>
+      <AsmOptionChkfpu-0>False</AsmOptionChkfpu-0>
+      <AsmOptionDebug-0>True</AsmOptionDebug-0>
+      <AsmOptionShowConditionals-0>False</AsmOptionShowConditionals-0>
+      <AsmOptionSystemInclude-0 />
+      <AsmOptionChkdsp-0>False</AsmOptionChkdsp-0>
+      <AsmOptionDefine-0 />
+      <AsmOptionShowDefinitions-0>False</AsmOptionShowDefinitions-0>
+      <AsmOptionInCode-0>SJIS</AsmOptionInCode-0>
+      <AsmOptionLogo-0>False</AsmOptionLogo-0>
+      <AsmOptionShowExpansions-0>False</AsmOptionShowExpansions-0>
+      <AsmOptionPreAssembleCommands-0 />
+      <AsmOptionPostAssembleCommands-0 />
+      <AsmOptionOtherAdditionalOptions-0 />
+      <AsmOptionCommandLine-0>-isa=rxv1
+-include=..\..\asp_dcre\target\grsakura_ccrx
+-include=.
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</AsmOptionCommandLine-0>
+    </Instance>
+    <Instance Guid="dbb16727-3e81-4169-956a-790355cab4a1">
+      <LinkOptionCpu-DefaultValue>False</LinkOptionCpu-DefaultValue>
+      <LinkOptionForm-DefaultValue>Absolute</LinkOptionForm-DefaultValue>
+      <LinkOptionFormConvert-DefaultValue>Stype</LinkOptionFormConvert-DefaultValue>
+      <LinkOptionInput-DefaultValue />
+      <LinkOptionListShow-DefaultValue>None</LinkOptionListShow-DefaultValue>
+      <LinkOptionOptimize-DefaultValue>None</LinkOptionOptimize-DefaultValue>
+      <LinkOptionStack-DefaultValue>False</LinkOptionStack-DefaultValue>
+      <LinkOptionStart-DefaultValue />
+      <LinkOptionCompress-DefaultValue>False</LinkOptionCompress-DefaultValue>
+      <LinkOptionCpuInformation-DefaultValue />
+      <LinkOptionDebug-DefaultValue>Debug</LinkOptionDebug-DefaultValue>
+      <LinkOptionFSymbol-DefaultValue />
+      <LinkOptionLibrary-DefaultValue />
+      <LinkOptionOptimizeSymbolDelete-DefaultValue>False</LinkOptionOptimizeSymbolDelete-DefaultValue>
+      <LinkOptionRecordH-DefaultValue>None</LinkOptionRecordH-DefaultValue>
+      <LinkOptionShowSymbol-DefaultValue>False</LinkOptionShowSymbol-DefaultValue>
+      <LinkOptionAlignedSection-DefaultValue />
+      <LinkOptionCpuStride-DefaultValue>False</LinkOptionCpuStride-DefaultValue>
+      <LinkOptionMemory-DefaultValue>False</LinkOptionMemory-DefaultValue>
+      <LinkOptionOptimizeSameCode-DefaultValue>False</LinkOptionOptimizeSameCode-DefaultValue>
+      <LinkOptionOutputFolder-DefaultValue>%BuildModeName%</LinkOptionOutputFolder-DefaultValue>
+      <LinkOptionRecordS-DefaultValue>None</LinkOptionRecordS-DefaultValue>
+      <LinkOptionShowReference-DefaultValue>False</LinkOptionShowReference-DefaultValue>
+      <LinkOptionSystemLibrary-DefaultValue />
+      <LinkOptionBinary-DefaultValue />
+      <LinkOptionChangeMessageInformation-DefaultValue>None</LinkOptionChangeMessageInformation-DefaultValue>
+      <LinkOptionContiguousSection-DefaultValue />
+      <LinkOptionDividedConvertFile-DefaultValue>False</LinkOptionDividedConvertFile-DefaultValue>
+      <LinkOptionOutputFileName-DefaultValue>%ProjectName%.abs</LinkOptionOutputFileName-DefaultValue>
+      <LinkOptionRom-DefaultValue />
+      <LinkOptionSameSize-DefaultValue>1E</LinkOptionSameSize-DefaultValue>
+      <LinkOptionShowXreference-DefaultValue>False</LinkOptionShowXreference-DefaultValue>
+      <LinkOptionChangeMessageInformationNumber-DefaultValue />
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionDefine-DefaultValue />
+      <LinkOptionMap-DefaultValue>False</LinkOptionMap-DefaultValue>
+      <LinkOptionOptimizeShortFormat-DefaultValue>False</LinkOptionOptimizeShortFormat-DefaultValue>
+      <LinkOptionShowTotalSize-DefaultValue>False</LinkOptionShowTotalSize-DefaultValue>
+      <LinkOptionChangeMessageWarning-DefaultValue>None</LinkOptionChangeMessageWarning-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionEntry-DefaultValue>False</LinkOptionEntry-DefaultValue>
+      <LinkOptionMessage-DefaultValue>NoMessage</LinkOptionMessage-DefaultValue>
+      <LinkOptionOptimizeBranch-DefaultValue>False</LinkOptionOptimizeBranch-DefaultValue>
+      <LinkOptionShowVector-DefaultValue>False</LinkOptionShowVector-DefaultValue>
+      <LinkOptionChangeMessageWarningNumber-DefaultValue />
+      <LinkOptionEntryPoint-DefaultValue />
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionNoMessageErrorNumber-DefaultValue />
+      <LinkOptionSymbolForbid-DefaultValue />
+      <LinkOptionChangeMessageError-DefaultValue>None</LinkOptionChangeMessageError-DefaultValue>
+      <LinkOptionNoPrelink-DefaultValue>Auto</LinkOptionNoPrelink-DefaultValue>
+      <LinkOptionPadding-DefaultValue>False</LinkOptionPadding-DefaultValue>
+      <LinkOptionSameCodeForbid-DefaultValue />
+      <LinkOptionSpace-DefaultValue>None</LinkOptionSpace-DefaultValue>
+      <LinkOptionChangeMessageErrorNumber-DefaultValue />
+      <LinkOptionSectionForbid-DefaultValue />
+      <LinkOptionSpaceValue-DefaultValue>FF</LinkOptionSpaceValue-DefaultValue>
+      <LinkOptionVectN-DefaultValue />
+      <LinkOptionAbsoluteForbid-DefaultValue />
+      <LinkOptionByteCount-DefaultValue>False</LinkOptionByteCount-DefaultValue>
+      <LinkOptionHide-DefaultValue>False</LinkOptionHide-DefaultValue>
+      <LinkOptionVect-DefaultValue />
+      <LinkOptionByteCountValue-DefaultValue>FF</LinkOptionByteCountValue-DefaultValue>
+      <LinkOptionJumpEntriesForPic-DefaultValue>False</LinkOptionJumpEntriesForPic-DefaultValue>
+      <LinkOptionTotalSize-DefaultValue>False</LinkOptionTotalSize-DefaultValue>
+      <LinkOptionCrc-DefaultValue>None</LinkOptionCrc-DefaultValue>
+      <LinkOptionJumpEntriesForPicSectionName-DefaultValue />
+      <LinkOptionLogo-DefaultValue>False</LinkOptionLogo-DefaultValue>
+      <LinkOptionCrcOutputAddress-DefaultValue>0</LinkOptionCrcOutputAddress-DefaultValue>
+      <LinkOptionPreLinkCommands-DefaultValue />
+      <LinkOptionCrcCalculationRange-DefaultValue />
+      <LinkOptionPostLinkCommands-DefaultValue />
+      <LinkOptionOtherAdditionalOptionsForLoadModule-DefaultValue />
+      <LinkOptionS9-DefaultValue>False</LinkOptionS9-DefaultValue>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-DefaultValue />
+      <LinkOptionCommandLine-DefaultValue />
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588032261274910101</TimeTagModified--0>
+      <LinkOptionCpu-0>False</LinkOptionCpu-0>
+      <LinkOptionForm-0>Absolute</LinkOptionForm-0>
+      <LinkOptionFormConvert-0>Stype</LinkOptionFormConvert-0>
+      <LinkOptionInput-0 />
+      <LinkOptionListShow-0>None</LinkOptionListShow-0>
+      <LinkOptionOptimize-0>None</LinkOptionOptimize-0>
+      <LinkOptionStack-0>False</LinkOptionStack-0>
+      <LinkOptionStart-0 />
+      <LinkOptionCompress-0>False</LinkOptionCompress-0>
+      <LinkOptionCpuInformation-0 />
+      <LinkOptionDebug-0>Debug</LinkOptionDebug-0>
+      <LinkOptionFSymbol-0 />
+      <LinkOptionLibrary-0 />
+      <LinkOptionOptimizeSymbolDelete-0>False</LinkOptionOptimizeSymbolDelete-0>
+      <LinkOptionRecordH-0>None</LinkOptionRecordH-0>
+      <LinkOptionShowSymbol-0>False</LinkOptionShowSymbol-0>
+      <LinkOptionAlignedSection-0 />
+      <LinkOptionCpuStride-0>False</LinkOptionCpuStride-0>
+      <LinkOptionMemory-0>False</LinkOptionMemory-0>
+      <LinkOptionOptimizeSameCode-0>False</LinkOptionOptimizeSameCode-0>
+      <LinkOptionOutputFolder-0>%BuildModeName%</LinkOptionOutputFolder-0>
+      <LinkOptionRecordS-0>None</LinkOptionRecordS-0>
+      <LinkOptionShowReference-0>False</LinkOptionShowReference-0>
+      <LinkOptionSystemLibrary-0 />
+      <LinkOptionBinary-0 />
+      <LinkOptionChangeMessageInformation-0>None</LinkOptionChangeMessageInformation-0>
+      <LinkOptionContiguousSection-0 />
+      <LinkOptionDividedConvertFile-0>False</LinkOptionDividedConvertFile-0>
+      <LinkOptionOutputFileName-0>%ProjectName%.abs</LinkOptionOutputFileName-0>
+      <LinkOptionRom-0 />
+      <LinkOptionSameSize-0>1E</LinkOptionSameSize-0>
+      <LinkOptionShowXreference-0>False</LinkOptionShowXreference-0>
+      <LinkOptionChangeMessageInformationNumber-0 />
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <LinkOptionDefine-0 />
+      <LinkOptionMap-0>False</LinkOptionMap-0>
+      <LinkOptionOptimizeShortFormat-0>False</LinkOptionOptimizeShortFormat-0>
+      <LinkOptionShowTotalSize-0>False</LinkOptionShowTotalSize-0>
+      <LinkOptionChangeMessageWarning-0>None</LinkOptionChangeMessageWarning-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <LinkOptionEntry-0>False</LinkOptionEntry-0>
+      <LinkOptionMessage-0>NoMessage</LinkOptionMessage-0>
+      <LinkOptionOptimizeBranch-0>False</LinkOptionOptimizeBranch-0>
+      <LinkOptionShowVector-0>False</LinkOptionShowVector-0>
+      <LinkOptionChangeMessageWarningNumber-0 />
+      <LinkOptionEntryPoint-0 />
+      <LinkOptionMultiConvertFileName-0 />
+      <LinkOptionNoMessageErrorNumber-0 />
+      <LinkOptionSymbolForbid-0 />
+      <LinkOptionChangeMessageError-0>None</LinkOptionChangeMessageError-0>
+      <LinkOptionNoPrelink-0>Auto</LinkOptionNoPrelink-0>
+      <LinkOptionPadding-0>False</LinkOptionPadding-0>
+      <LinkOptionSameCodeForbid-0 />
+      <LinkOptionSpace-0>None</LinkOptionSpace-0>
+      <LinkOptionChangeMessageErrorNumber-0 />
+      <LinkOptionSectionForbid-0 />
+      <LinkOptionSpaceValue-0>FF</LinkOptionSpaceValue-0>
+      <LinkOptionVectN-0 />
+      <LinkOptionAbsoluteForbid-0 />
+      <LinkOptionByteCount-0>False</LinkOptionByteCount-0>
+      <LinkOptionHide-0>False</LinkOptionHide-0>
+      <LinkOptionVect-0 />
+      <LinkOptionByteCountValue-0>FF</LinkOptionByteCountValue-0>
+      <LinkOptionJumpEntriesForPic-0>False</LinkOptionJumpEntriesForPic-0>
+      <LinkOptionTotalSize-0>False</LinkOptionTotalSize-0>
+      <LinkOptionCrc-0>None</LinkOptionCrc-0>
+      <LinkOptionJumpEntriesForPicSectionName-0 />
+      <LinkOptionLogo-0>False</LinkOptionLogo-0>
+      <LinkOptionCrcOutputAddress-0>0</LinkOptionCrcOutputAddress-0>
+      <LinkOptionPreLinkCommands-0 />
+      <LinkOptionCrcCalculationRange-0 />
+      <LinkOptionPostLinkCommands-0 />
+      <LinkOptionOtherAdditionalOptionsForLoadModule-0 />
+      <LinkOptionS9-0>False</LinkOptionS9-0>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-0 />
+      <LinkOptionCommandLine-0 />
+    </Instance>
+    <Instance Guid="df74c69e-635e-42d9-845e-14128ba4d48a">
+      <HexOptionForm-DefaultValue>Stype</HexOptionForm-DefaultValue>
+      <HexOptionOutput-DefaultValue>True</HexOptionOutput-DefaultValue>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-DefaultValue />
+      <HexOptionCommandLine-DefaultValue />
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionRecordH-DefaultValue>None</LinkOptionRecordH-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionRecordS-DefaultValue>None</LinkOptionRecordS-DefaultValue>
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionSpace-DefaultValue>None</LinkOptionSpace-DefaultValue>
+      <LinkOptionSpaceValue-DefaultValue>FF</LinkOptionSpaceValue-DefaultValue>
+      <LinkOptionByteCount-DefaultValue>False</LinkOptionByteCount-DefaultValue>
+      <LinkOptionByteCountValue-DefaultValue>FF</LinkOptionByteCountValue-DefaultValue>
+      <LinkOptionCrc-DefaultValue>None</LinkOptionCrc-DefaultValue>
+      <LinkOptionCrcOutputAddress-DefaultValue>0</LinkOptionCrcOutputAddress-DefaultValue>
+      <LinkOptionCrcCalculationRange-DefaultValue />
+      <LinkOptionS9-DefaultValue>False</LinkOptionS9-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053514561269735</TimeTagModified--0>
+      <HexOptionForm-0>Stype</HexOptionForm-0>
+      <HexOptionOutput-0>True</HexOptionOutput-0>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-0 />
+      <HexOptionCommandLine-0 />
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <LinkOptionRecordH-0>None</LinkOptionRecordH-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <LinkOptionRecordS-0>None</LinkOptionRecordS-0>
+      <LinkOptionMultiConvertFileName-0 />
+      <LinkOptionSpace-0>None</LinkOptionSpace-0>
+      <LinkOptionSpaceValue-0>FF</LinkOptionSpaceValue-0>
+      <LinkOptionByteCount-0>False</LinkOptionByteCount-0>
+      <LinkOptionByteCountValue-0>FF</LinkOptionByteCountValue-0>
+      <LinkOptionCrc-0>None</LinkOptionCrc-0>
+      <LinkOptionCrcOutputAddress-0>0</LinkOptionCrcOutputAddress-0>
+      <LinkOptionCrcCalculationRange-0 />
+      <LinkOptionS9-0>False</LinkOptionS9-0>
+    </Instance>
+    <Instance Guid="fff50d2e-74da-44ea-90a8-c47756029e83">
+      <LibOptionForm-DefaultValue>LibraryU</LibOptionForm-DefaultValue>
+      <LibOptionInput-DefaultValue />
+      <LibOptionListShow-DefaultValue>List</LibOptionListShow-DefaultValue>
+      <LibOptionMemory-DefaultValue>False</LibOptionMemory-DefaultValue>
+      <LibOptionChangeMessageInformation-DefaultValue>None</LibOptionChangeMessageInformation-DefaultValue>
+      <LibOptionDebug-DefaultValue>Debug</LibOptionDebug-DefaultValue>
+      <LibOptionLibrary-DefaultValue />
+      <LibOptionShowSymbol-DefaultValue>False</LibOptionShowSymbol-DefaultValue>
+      <LibOptionChangeMessageInformationNumber-DefaultValue />
+      <LibOptionOutputFolder-DefaultValue>%BuildModeName%</LibOptionOutputFolder-DefaultValue>
+      <LibOptionShowSection-DefaultValue>False</LibOptionShowSection-DefaultValue>
+      <LibOptionSystemLibrary-DefaultValue />
+      <LibOptionBinary-DefaultValue />
+      <LibOptionChangeMessageWarning-DefaultValue>None</LibOptionChangeMessageWarning-DefaultValue>
+      <LibOptionOutputFileName-DefaultValue>%ProjectName%.lib</LibOptionOutputFileName-DefaultValue>
+      <LibOptionShowXreference-DefaultValue>False</LibOptionShowXreference-DefaultValue>
+      <LibOptionChangeMessageWarningNumber-DefaultValue />
+      <LibOptionMessage-DefaultValue>NoMessage</LibOptionMessage-DefaultValue>
+      <LibOptionNoPrelink-DefaultValue>Auto</LibOptionNoPrelink-DefaultValue>
+      <LibOptionShowTotalSize-DefaultValue>False</LibOptionShowTotalSize-DefaultValue>
+      <LibOptionChangeMessageError-DefaultValue>None</LibOptionChangeMessageError-DefaultValue>
+      <LibOptionNoMessageErrorNumber-DefaultValue />
+      <LibOptionShowVector-DefaultValue>False</LibOptionShowVector-DefaultValue>
+      <LibOptionChangeMessageErrorNumber-DefaultValue />
+      <LibOptionHide-DefaultValue>False</LibOptionHide-DefaultValue>
+      <LibOptionTotalSize-DefaultValue>False</LibOptionTotalSize-DefaultValue>
+      <LibOptionLogo-DefaultValue>False</LibOptionLogo-DefaultValue>
+      <LibOptionPreLibrarianCommands-DefaultValue />
+      <LibOptionPostLibrarianCommands-DefaultValue />
+      <LibOptionOtherAdditionalOptions-DefaultValue />
+      <LibOptionCommandLine-DefaultValue>-noprelink
+-form=library=u
+-output=%BuildModeName%\%ProjectName%.lib
+-list=%BuildModeName%\%ProjectName%.lbp
+-nologo
+-exit
+</LibOptionCommandLine-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588032261274930101</TimeTagModified--0>
+      <LibOptionForm-0>LibraryU</LibOptionForm-0>
+      <LibOptionInput-0 />
+      <LibOptionListShow-0>List</LibOptionListShow-0>
+      <LibOptionMemory-0>False</LibOptionMemory-0>
+      <LibOptionChangeMessageInformation-0>None</LibOptionChangeMessageInformation-0>
+      <LibOptionDebug-0>Debug</LibOptionDebug-0>
+      <LibOptionLibrary-0 />
+      <LibOptionShowSymbol-0>False</LibOptionShowSymbol-0>
+      <LibOptionChangeMessageInformationNumber-0 />
+      <LibOptionOutputFolder-0>%BuildModeName%</LibOptionOutputFolder-0>
+      <LibOptionShowSection-0>False</LibOptionShowSection-0>
+      <LibOptionSystemLibrary-0 />
+      <LibOptionBinary-0 />
+      <LibOptionChangeMessageWarning-0>None</LibOptionChangeMessageWarning-0>
+      <LibOptionOutputFileName-0>%ProjectName%.lib</LibOptionOutputFileName-0>
+      <LibOptionShowXreference-0>False</LibOptionShowXreference-0>
+      <LibOptionChangeMessageWarningNumber-0 />
+      <LibOptionMessage-0>NoMessage</LibOptionMessage-0>
+      <LibOptionNoPrelink-0>Auto</LibOptionNoPrelink-0>
+      <LibOptionShowTotalSize-0>False</LibOptionShowTotalSize-0>
+      <LibOptionChangeMessageError-0>None</LibOptionChangeMessageError-0>
+      <LibOptionNoMessageErrorNumber-0 />
+      <LibOptionShowVector-0>False</LibOptionShowVector-0>
+      <LibOptionChangeMessageErrorNumber-0 />
+      <LibOptionHide-0>False</LibOptionHide-0>
+      <LibOptionTotalSize-0>False</LibOptionTotalSize-0>
+      <LibOptionLogo-0>False</LibOptionLogo-0>
+      <LibOptionPreLibrarianCommands-0 />
+      <LibOptionPostLibrarianCommands-0 />
+      <LibOptionOtherAdditionalOptions-0 />
+      <LibOptionCommandLine-0>-noprelink
+-form=library=u
+-output=%BuildModeName%\%ProjectName%.lib
+-list=%BuildModeName%\%ProjectName%.lbp
+-nologo
+-exit
+</LibOptionCommandLine-0>
+    </Instance>
+    <Instance Guid="9cb0ade0-b3cb-4e21-823c-290b5fdb5f1e">
+      <LbgOptionLanguage-DefaultValue>C</LbgOptionLanguage-DefaultValue>
+      <LbgOptionLibraryMode-DefaultValue>None</LbgOptionLibraryMode-DefaultValue>
+      <LbgOptionLogo-DefaultValue>False</LbgOptionLogo-DefaultValue>
+      <LbgOptionOptimize-DefaultValue>Level2</LbgOptionOptimize-DefaultValue>
+      <LbgOptionOutputFolder-DefaultValue>%BuildModeName%</LbgOptionOutputFolder-DefaultValue>
+      <LbgOptionGoptimize-DefaultValue>False</LbgOptionGoptimize-DefaultValue>
+      <LbgOptionHead-DefaultValue>Custom</LbgOptionHead-DefaultValue>
+      <LbgOptionOutputFileName-DefaultValue>%ProjectName%.lib</LbgOptionOutputFileName-DefaultValue>
+      <LbgOptionPreLibraryGenerateCommands-DefaultValue />
+      <LbgOptionFunctionalCutdown-DefaultValue>None</LbgOptionFunctionalCutdown-DefaultValue>
+      <LbgOptionHeadRuntime-DefaultValue>True</LbgOptionHeadRuntime-DefaultValue>
+      <LbgOptionPostLibraryGenerateCommands-DefaultValue />
+      <LbgOptionSpeedAndSize-DefaultValue>Size</LbgOptionSpeedAndSize-DefaultValue>
+      <LbgOptionHeadCtypeH-DefaultValue>False</LbgOptionHeadCtypeH-DefaultValue>
+      <LbgOptionLoop-DefaultValue>Auto</LbgOptionLoop-DefaultValue>
+      <LbgOptionOtherAdditionalOptions-DefaultValue />
+      <LbgOptionReent-DefaultValue>False</LbgOptionReent-DefaultValue>
+      <LbgOptionCommandLine-DefaultValue />
+      <LbgOptionHeadMathH-DefaultValue>False</LbgOptionHeadMathH-DefaultValue>
+      <LbgOptionLoopValue-DefaultValue>2</LbgOptionLoopValue-DefaultValue>
+      <LbgOptionSectionP-DefaultValue>P</LbgOptionSectionP-DefaultValue>
+      <LbgOptionHeadMathfH-DefaultValue>False</LbgOptionHeadMathfH-DefaultValue>
+      <LbgOptionInline-DefaultValue>Auto</LbgOptionInline-DefaultValue>
+      <LbgOptionSectionC-DefaultValue>C</LbgOptionSectionC-DefaultValue>
+      <LbgOptionHeadStdargH-DefaultValue>False</LbgOptionHeadStdargH-DefaultValue>
+      <LbgOptionInlineValue-DefaultValue>100</LbgOptionInlineValue-DefaultValue>
+      <LbgOptionSectionD-DefaultValue>D</LbgOptionSectionD-DefaultValue>
+      <LbgOptionFileInline-DefaultValue />
+      <LbgOptionHeadStdioH-DefaultValue>True</LbgOptionHeadStdioH-DefaultValue>
+      <LbgOptionSectionB-DefaultValue>B</LbgOptionSectionB-DefaultValue>
+      <LbgOptionCase-DefaultValue>Auto</LbgOptionCase-DefaultValue>
+      <LbgOptionHeadStdlibH-DefaultValue>True</LbgOptionHeadStdlibH-DefaultValue>
+      <LbgOptionSectionL-DefaultValue>L</LbgOptionSectionL-DefaultValue>
+      <LbgOptionHeadStringH-DefaultValue>True</LbgOptionHeadStringH-DefaultValue>
+      <LbgOptionSectionW-DefaultValue>W</LbgOptionSectionW-DefaultValue>
+      <LbgOptionVolatile-DefaultValue>False</LbgOptionVolatile-DefaultValue>
+      <LbgOptionConstCopy-DefaultValue>Auto</LbgOptionConstCopy-DefaultValue>
+      <LbgOptionHeadIos-DefaultValue>False</LbgOptionHeadIos-DefaultValue>
+      <LbgOptionNostuffB-DefaultValue>False</LbgOptionNostuffB-DefaultValue>
+      <LbgOptionConstDiv-DefaultValue>Auto</LbgOptionConstDiv-DefaultValue>
+      <LbgOptionHeadNew-DefaultValue>True</LbgOptionHeadNew-DefaultValue>
+      <LbgOptionNostuffD-DefaultValue>False</LbgOptionNostuffD-DefaultValue>
+      <LbgOptionHeadComplex-DefaultValue>False</LbgOptionHeadComplex-DefaultValue>
+      <LbgOptionLibrary-DefaultValue>Intrinsic</LbgOptionLibrary-DefaultValue>
+      <LbgOptionNostuffC-DefaultValue>False</LbgOptionNostuffC-DefaultValue>
+      <LbgOptionHeadString-DefaultValue>False</LbgOptionHeadString-DefaultValue>
+      <LbgOptionNostuffW-DefaultValue>False</LbgOptionNostuffW-DefaultValue>
+      <LbgOptionScope-DefaultValue>Auto</LbgOptionScope-DefaultValue>
+      <LbgOptionHeadComplexH-DefaultValue>False</LbgOptionHeadComplexH-DefaultValue>
+      <LbgOptionInstalign-DefaultValue>Noinstalign</LbgOptionInstalign-DefaultValue>
+      <LbgOptionSchedule-DefaultValue>Auto</LbgOptionSchedule-DefaultValue>
+      <LbgOptionApproxdiv-DefaultValue>False</LbgOptionApproxdiv-DefaultValue>
+      <LbgOptionHeadFenvH-DefaultValue>False</LbgOptionHeadFenvH-DefaultValue>
+      <LbgOptionNouseDiv-DefaultValue>True</LbgOptionNouseDiv-DefaultValue>
+      <LbgOptionEnableRegister-DefaultValue>False</LbgOptionEnableRegister-DefaultValue>
+      <LbgOptionHeadInttypesH-DefaultValue>False</LbgOptionHeadInttypesH-DefaultValue>
+      <LbgOptionHeadWcharH-DefaultValue>False</LbgOptionHeadWcharH-DefaultValue>
+      <LbgOptionSimpleFloatConv-DefaultValue>False</LbgOptionSimpleFloatConv-DefaultValue>
+      <LbgOptionFpu-DefaultValue>Fpu</LbgOptionFpu-DefaultValue>
+      <LbgOptionHeadWctypeH-DefaultValue>False</LbgOptionHeadWctypeH-DefaultValue>
+      <LbgOptionFloatOrder-DefaultValue>False</LbgOptionFloatOrder-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053514561269735</TimeTagModified--0>
+      <LbgOptionLanguage-0>C</LbgOptionLanguage-0>
+      <LbgOptionLibraryMode-0>None</LbgOptionLibraryMode-0>
+      <LbgOptionLogo-0>False</LbgOptionLogo-0>
+      <LbgOptionOptimize-0>Level2</LbgOptionOptimize-0>
+      <LbgOptionOutputFolder-0>%BuildModeName%</LbgOptionOutputFolder-0>
+      <LbgOptionGoptimize-0>False</LbgOptionGoptimize-0>
+      <LbgOptionHead-0>Custom</LbgOptionHead-0>
+      <LbgOptionOutputFileName-0>%ProjectName%.lib</LbgOptionOutputFileName-0>
+      <LbgOptionPreLibraryGenerateCommands-0 />
+      <LbgOptionFunctionalCutdown-0>None</LbgOptionFunctionalCutdown-0>
+      <LbgOptionPostLibraryGenerateCommands-0 />
+      <LbgOptionSpeedAndSize-0>Size</LbgOptionSpeedAndSize-0>
+      <LbgOptionHeadCtypeH-0>False</LbgOptionHeadCtypeH-0>
+      <LbgOptionLoop-0>Auto</LbgOptionLoop-0>
+      <LbgOptionOtherAdditionalOptions-0 />
+      <LbgOptionReent-0>False</LbgOptionReent-0>
+      <LbgOptionCommandLine-0 />
+      <LbgOptionHeadMathH-0>False</LbgOptionHeadMathH-0>
+      <LbgOptionLoopValue-0>2</LbgOptionLoopValue-0>
+      <LbgOptionSectionP-0>P</LbgOptionSectionP-0>
+      <LbgOptionHeadMathfH-0>False</LbgOptionHeadMathfH-0>
+      <LbgOptionInline-0>Auto</LbgOptionInline-0>
+      <LbgOptionSectionC-0>C</LbgOptionSectionC-0>
+      <LbgOptionHeadStdargH-0>False</LbgOptionHeadStdargH-0>
+      <LbgOptionInlineValue-0>100</LbgOptionInlineValue-0>
+      <LbgOptionSectionD-0>D</LbgOptionSectionD-0>
+      <LbgOptionFileInline-0 />
+      <LbgOptionHeadStdioH-0>True</LbgOptionHeadStdioH-0>
+      <LbgOptionSectionB-0>B</LbgOptionSectionB-0>
+      <LbgOptionCase-0>Auto</LbgOptionCase-0>
+      <LbgOptionHeadStdlibH-0>True</LbgOptionHeadStdlibH-0>
+      <LbgOptionSectionL-0>L</LbgOptionSectionL-0>
+      <LbgOptionHeadStringH-0>True</LbgOptionHeadStringH-0>
+      <LbgOptionSectionW-0>W</LbgOptionSectionW-0>
+      <LbgOptionVolatile-0>False</LbgOptionVolatile-0>
+      <LbgOptionConstCopy-0>Auto</LbgOptionConstCopy-0>
+      <LbgOptionHeadIos-0>False</LbgOptionHeadIos-0>
+      <LbgOptionNostuffB-0>False</LbgOptionNostuffB-0>
+      <LbgOptionConstDiv-0>Auto</LbgOptionConstDiv-0>
+      <LbgOptionHeadNew-0>True</LbgOptionHeadNew-0>
+      <LbgOptionNostuffD-0>False</LbgOptionNostuffD-0>
+      <LbgOptionHeadComplex-0>False</LbgOptionHeadComplex-0>
+      <LbgOptionLibrary-0>Intrinsic</LbgOptionLibrary-0>
+      <LbgOptionNostuffC-0>False</LbgOptionNostuffC-0>
+      <LbgOptionHeadString-0>False</LbgOptionHeadString-0>
+      <LbgOptionNostuffW-0>False</LbgOptionNostuffW-0>
+      <LbgOptionScope-0>Auto</LbgOptionScope-0>
+      <LbgOptionHeadComplexH-0>False</LbgOptionHeadComplexH-0>
+      <LbgOptionInstalign-0>Noinstalign</LbgOptionInstalign-0>
+      <LbgOptionSchedule-0>Auto</LbgOptionSchedule-0>
+      <LbgOptionApproxdiv-0>False</LbgOptionApproxdiv-0>
+      <LbgOptionHeadFenvH-0>False</LbgOptionHeadFenvH-0>
+      <LbgOptionNouseDiv-0>True</LbgOptionNouseDiv-0>
+      <LbgOptionEnableRegister-0>False</LbgOptionEnableRegister-0>
+      <LbgOptionHeadInttypesH-0>False</LbgOptionHeadInttypesH-0>
+      <LbgOptionHeadWcharH-0>False</LbgOptionHeadWcharH-0>
+      <LbgOptionSimpleFloatConv-0>False</LbgOptionSimpleFloatConv-0>
+      <LbgOptionFpu-0>Fpu</LbgOptionFpu-0>
+      <LbgOptionHeadWctypeH-0>False</LbgOptionHeadWctypeH-0>
+      <LbgOptionFloatOrder-0>False</LbgOptionFloatOrder-0>
+    </Instance>
+    <Instance Guid="418104fd-31b7-4e10-a52a-f3a40218ae47">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="2a16567e-8174-41dd-a27a-386158a175b9">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="7fee077f-b7de-40c9-ae6f-270d4788dfb2">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>2</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d29759b5-0b65-433e-a5dd-eabaa827926e">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>3</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="62cdd7dc-f110-46fd-b286-34e5470c8adf">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>4</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="0c3f9205-2818-4d8b-9fdb-70bc98dc06ad">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>5</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="53f28d48-2f3c-4921-87d5-084187a0c09c">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>6</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d8ec7fa9-8632-4326-a402-eeacf5a9e908">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>7</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="761d7481-e11f-4604-89fe-3027801ca3f3">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>8</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="1d249bd6-772e-4580-bbb0-34a948c6c162">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>9</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="9aa3586d-4df3-430e-8496-da67b6df11c8">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>10</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="3a8e9b1d-6baa-4c8d-afbf-6aba1462f4f6">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>11</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="e4e95360-f85f-4469-b053-ce16e92de312">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>12</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="4ba93070-6c47-43b0-bd20-7ada64b7cf1f">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>13</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="c68ccba7-5feb-4fc1-b6c6-1aaf66aa1e21">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>14</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="813f006e-dcb2-44ee-80b0-a4456606b25c">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>15</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d7749f59-8c46-465e-9396-40fbcafd8c1b">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>16</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="2aeaad0c-aef9-466b-acb5-fc12dd38b66a">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>17</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="e5d7bf19-a826-482d-a700-42d7d39b557a">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>18</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f35b2475-1163-4fd3-8584-159c3462e074">
+      <ItemAddTime>635318846895400054</ItemAddTime>
+      <ItemAddTimeCount>19</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d15e7073-c94f-4650-ac1c-2508bdbbe93a">
+      <ItemAddTime>635318847616332867</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d2abd517-45be-45ae-8b92-233b54a5a9f6">
+      <ItemAddTime>635318904163677659</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="615ab7b6-f056-4147-9b71-8f13cd6dfcc5">
+      <ItemAddTime>635318847616332867</ItemAddTime>
+      <ItemAddTimeCount>2</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="3f36ed22-46b8-4376-98de-6f9973dd0af1">
+      <ItemAddTime>635318848092228250</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f22bd1a3-ee49-4534-bd7c-71c786e19406">
+      <ItemAddTime>635318848092228250</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="490f6f78-f35a-4c25-9787-987f826efe89">
+      <ItemAddTime>635318848092228250</ItemAddTime>
+      <ItemAddTimeCount>3</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="98db2870-7312-4fc3-833a-62f65a1dbd09">
+      <ItemAddTime>635340099755735707</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="e2945293-5f45-4a79-92cb-e335f3cb6c87">
+      <ItemAddTime>635321518825483024</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="b19e241d-c82f-4d73-9bc0-36e68e4baa8d">
+      <ItemAddTime>635881931545417595</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="db552b0d-ce14-4338-ad3c-4c4353102b71">
+      <ItemAddTime>635881931682616223</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a7be515f-f007-45ed-9059-4e1500c0f74d">
+      <TimeTagModified-SourceItem0--0>-8588053513959375754</TimeTagModified-SourceItem0--0>
+      <SourceItem0-IsLockedByUser>False</SourceItem0-IsLockedByUser>
+      <SourceItem0-BuildingTarget-0>True</SourceItem0-BuildingTarget-0>
+      <SourceItem0-IndividualCompileOption-0>False</SourceItem0-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem1--0>-8588053513959375754</TimeTagModified-SourceItem1--0>
+      <SourceItem1-IsLockedByUser>False</SourceItem1-IsLockedByUser>
+      <SourceItem1-BuildingTarget-0>True</SourceItem1-BuildingTarget-0>
+      <SourceItem1-IndividualCompileOption-0>False</SourceItem1-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem2--0>-8588053513959375754</TimeTagModified-SourceItem2--0>
+      <SourceItem2-IsLockedByUser>False</SourceItem2-IsLockedByUser>
+      <SourceItem2-BuildingTarget-0>True</SourceItem2-BuildingTarget-0>
+      <SourceItem2-IndividualCompileOption-0>False</SourceItem2-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem3--0>-8588053513959375754</TimeTagModified-SourceItem3--0>
+      <SourceItem3-IsLockedByUser>False</SourceItem3-IsLockedByUser>
+      <SourceItem3-BuildingTarget-0>True</SourceItem3-BuildingTarget-0>
+      <SourceItem3-IndividualCompileOption-0>False</SourceItem3-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem4--0>-8588053513959375754</TimeTagModified-SourceItem4--0>
+      <SourceItem4-IsLockedByUser>False</SourceItem4-IsLockedByUser>
+      <SourceItem4-BuildingTarget-0>True</SourceItem4-BuildingTarget-0>
+      <SourceItem4-IndividualCompileOption-0>False</SourceItem4-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem5--0>-8588053513959375754</TimeTagModified-SourceItem5--0>
+      <SourceItem5-IsLockedByUser>False</SourceItem5-IsLockedByUser>
+      <SourceItem5-BuildingTarget-0>True</SourceItem5-BuildingTarget-0>
+      <SourceItem5-IndividualCompileOption-0>False</SourceItem5-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem6--0>-8588053513959375754</TimeTagModified-SourceItem6--0>
+      <SourceItem6-IsLockedByUser>False</SourceItem6-IsLockedByUser>
+      <SourceItem6-BuildingTarget-0>True</SourceItem6-BuildingTarget-0>
+      <SourceItem6-IndividualCompileOption-0>False</SourceItem6-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem7--0>-8588053513959375754</TimeTagModified-SourceItem7--0>
+      <SourceItem7-IsLockedByUser>False</SourceItem7-IsLockedByUser>
+      <SourceItem7-BuildingTarget-0>True</SourceItem7-BuildingTarget-0>
+      <SourceItem7-IndividualCompileOption-0>False</SourceItem7-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem8--0>-8588053513959375754</TimeTagModified-SourceItem8--0>
+      <SourceItem8-IsLockedByUser>False</SourceItem8-IsLockedByUser>
+      <SourceItem8-BuildingTarget-0>True</SourceItem8-BuildingTarget-0>
+      <SourceItem8-IndividualCompileOption-0>False</SourceItem8-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem9--0>-8588053513959375754</TimeTagModified-SourceItem9--0>
+      <SourceItem9-IsLockedByUser>False</SourceItem9-IsLockedByUser>
+      <SourceItem9-BuildingTarget-0>True</SourceItem9-BuildingTarget-0>
+      <SourceItem9-IndividualCompileOption-0>False</SourceItem9-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem10--0>-8588053513959375754</TimeTagModified-SourceItem10--0>
+      <SourceItem10-IsLockedByUser>False</SourceItem10-IsLockedByUser>
+      <SourceItem10-BuildingTarget-0>True</SourceItem10-BuildingTarget-0>
+      <SourceItem10-IndividualCompileOption-0>False</SourceItem10-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem11--0>-8588053513959375754</TimeTagModified-SourceItem11--0>
+      <SourceItem11-IsLockedByUser>False</SourceItem11-IsLockedByUser>
+      <SourceItem11-BuildingTarget-0>True</SourceItem11-BuildingTarget-0>
+      <SourceItem11-IndividualCompileOption-0>False</SourceItem11-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem12--0>-8588053513959375754</TimeTagModified-SourceItem12--0>
+      <SourceItem12-IsLockedByUser>False</SourceItem12-IsLockedByUser>
+      <SourceItem12-BuildingTarget-0>True</SourceItem12-BuildingTarget-0>
+      <SourceItem12-IndividualCompileOption-0>False</SourceItem12-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem13--0>-8588053513959375754</TimeTagModified-SourceItem13--0>
+      <SourceItem13-IsLockedByUser>False</SourceItem13-IsLockedByUser>
+      <SourceItem13-BuildingTarget-0>True</SourceItem13-BuildingTarget-0>
+      <SourceItem13-IndividualCompileOption-0>False</SourceItem13-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem14--0>-8588053513959375754</TimeTagModified-SourceItem14--0>
+      <SourceItem14-IsLockedByUser>False</SourceItem14-IsLockedByUser>
+      <SourceItem14-BuildingTarget-0>True</SourceItem14-BuildingTarget-0>
+      <SourceItem14-IndividualCompileOption-0>False</SourceItem14-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem15--0>-8588053513959375754</TimeTagModified-SourceItem15--0>
+      <SourceItem15-IsLockedByUser>False</SourceItem15-IsLockedByUser>
+      <SourceItem15-BuildingTarget-0>True</SourceItem15-BuildingTarget-0>
+      <SourceItem15-IndividualCompileOption-0>False</SourceItem15-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem16--0>-8588053513959375754</TimeTagModified-SourceItem16--0>
+      <SourceItem16-IsLockedByUser>False</SourceItem16-IsLockedByUser>
+      <SourceItem16-BuildingTarget-0>True</SourceItem16-BuildingTarget-0>
+      <SourceItem16-IndividualCompileOption-0>False</SourceItem16-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem17--0>-8588053513959375754</TimeTagModified-SourceItem17--0>
+      <SourceItem17-IsLockedByUser>False</SourceItem17-IsLockedByUser>
+      <SourceItem17-BuildingTarget-0>True</SourceItem17-BuildingTarget-0>
+      <SourceItem17-IndividualCompileOption-0>False</SourceItem17-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem18--0>-8588053513959375754</TimeTagModified-SourceItem18--0>
+      <SourceItem18-IsLockedByUser>False</SourceItem18-IsLockedByUser>
+      <SourceItem18-BuildingTarget-0>True</SourceItem18-BuildingTarget-0>
+      <SourceItem18-IndividualCompileOption-0>False</SourceItem18-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem19--0>-8588053513959375754</TimeTagModified-SourceItem19--0>
+      <SourceItem19-IsLockedByUser>False</SourceItem19-IsLockedByUser>
+      <SourceItem19-BuildingTarget-0>True</SourceItem19-BuildingTarget-0>
+      <SourceItem19-IndividualCompileOption-0>False</SourceItem19-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem20--0>-8588053513238442941</TimeTagModified-SourceItem20--0>
+      <SourceItem20-IsLockedByUser>False</SourceItem20-IsLockedByUser>
+      <SourceItem20-BuildingTarget-0>True</SourceItem20-BuildingTarget-0>
+      <SourceItem20-IndividualCompileOption-0>False</SourceItem20-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem22--0>-8588053513238442941</TimeTagModified-SourceItem22--0>
+      <SourceItem22-IsLockedByUser>False</SourceItem22-IsLockedByUser>
+      <SourceItem22-BuildingTarget-0>True</SourceItem22-BuildingTarget-0>
+      <SourceItem22-IndividualCompileOption-0>False</SourceItem22-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem23--0>-8588053512762547558</TimeTagModified-SourceItem23--0>
+      <SourceItem23-IsLockedByUser>False</SourceItem23-IsLockedByUser>
+      <SourceItem23-BuildingTarget-0>True</SourceItem23-BuildingTarget-0>
+      <SourceItem23-IndividualCompileOption-0>False</SourceItem23-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem24--0>-8588053512762547558</TimeTagModified-SourceItem24--0>
+      <SourceItem24-IsLockedByUser>False</SourceItem24-IsLockedByUser>
+      <SourceItem24-BuildingTarget-0>True</SourceItem24-BuildingTarget-0>
+      <SourceItem24-IndividualCompileOption-0>False</SourceItem24-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem25--0>-8588053512762547558</TimeTagModified-SourceItem25--0>
+      <SourceItem25-IsLockedByUser>False</SourceItem25-IsLockedByUser>
+      <SourceItem25-BuildingTarget-0>True</SourceItem25-BuildingTarget-0>
+      <SourceItem25-IndividualCompileOption-0>False</SourceItem25-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem27--0>-8588050842029292784</TimeTagModified-SourceItem27--0>
+      <SourceItem27-IsLockedByUser>False</SourceItem27-IsLockedByUser>
+      <SourceItem27-BuildingTarget-0>True</SourceItem27-BuildingTarget-0>
+      <SourceItem27-IndividualCompileOption-0>False</SourceItem27-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem28--0>-8587443530824988344</TimeTagModified-SourceItem28--0>
+      <SourceItem28-IsLockedByUser>False</SourceItem28-IsLockedByUser>
+      <SourceItem28-BuildingTarget-0>True</SourceItem28-BuildingTarget-0>
+      <SourceItem28-IndividualCompileOption-0>False</SourceItem28-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem29--0>-8587443530824988344</TimeTagModified-SourceItem29--0>
+      <SourceItem29-IsLockedByUser>False</SourceItem29-IsLockedByUser>
+      <SourceItem29-BuildingTarget-0>True</SourceItem29-BuildingTarget-0>
+      <SourceItem29-IndividualCompileOption-0>False</SourceItem29-IndividualCompileOption-0>
+    </Instance>
+    <Instance Guid="c20a78d9-8038-46fe-9b87-bc2fa2aa9bdc">
+      <TimeTagModified-SourceItem21--0>-8588053456691098149</TimeTagModified-SourceItem21--0>
+      <SourceItem21-IsLockedByUser>False</SourceItem21-IsLockedByUser>
+      <SourceItem21-BuildingTarget-0>True</SourceItem21-BuildingTarget-0>
+      <SourceItem21-IndividualAssembleOption-0>False</SourceItem21-IndividualAssembleOption-0>
+      <TimeTagModified-SourceItem26--0>-8588032261099040101</TimeTagModified-SourceItem26--0>
+      <SourceItem26-IsLockedByUser>False</SourceItem26-IsLockedByUser>
+      <SourceItem26-BuildingTarget-0>True</SourceItem26-BuildingTarget-0>
+      <SourceItem26-IndividualAssembleOption-0>False</SourceItem26-IndividualAssembleOption-0>
+    </Instance>
+  </Class>
+  <Class Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
+    <Instance Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
+      <IsLibraryMode>True</IsLibraryMode>
+      <StartUpCategoryItem>00000000-0000-0000-0000-000000000000</StartUpCategoryItem>
+    </Instance>
+  </Class>
+  <Class Guid="a29a09ee-92c3-4ce7-9586-a1b058043f92">
+    <Instance Guid="a29a09ee-92c3-4ce7-9586-a1b058043f92">
+      <ProjectGeneratr-GeneratedFile0 />
+    </Instance>
+  </Class>
+  <Class Guid="31a86ad3-37bd-4846-aff2-e08abdc00197">
+    <Instance Guid="31a86ad3-37bd-4846-aff2-e08abdc00197">
+      <DeviceNameOnCreateStartup>R5F563NBDxFP</DeviceNameOnCreateStartup>
+    </Instance>
+  </Class>
+  <Class Guid="78a5c5cd-76cb-4bcc-a031-3020011fbc9a">
+    <Instance Guid="b3ad6185-fcd2-434b-a062-4ee857913572">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">
+    <Instance Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">
+      <ProductVersion>4.01.00.00</ProductVersion>
+    </Instance>
+  </Class>
+</CubeSuiteProject>
Index: UsbWattMeter/trunk/csp/libcurl/curl_config.h
===================================================================
--- UsbWattMeter/trunk/csp/libcurl/curl_config.h	(revision 164)
+++ UsbWattMeter/trunk/csp/libcurl/curl_config.h	(revision 164)
@@ -0,0 +1,538 @@
+#ifndef HEADER_CURL_CONFIG_TOPPERS_ASP_H
+#define HEADER_CURL_CONFIG_TOPPERS_ASP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/*               Hand crafted config file for TOPPERS/ASP               */
+/* ================================================================ */
+
+/* Name of this package! */
+#undef PACKAGE
+
+/* Version number of this archive. */
+#undef VERSION
+
+/* Define if you have the getpass function.  */
+#undef HAVE_GETPASS
+
+/* Define cpu-machine-OS */
+#define OS "TOPPERS/ASP"
+
+/* Define if you want the built-in manual */
+#undef USE_MANUAL
+
+/* Define if you have the gethostbyaddr_r() function with 5 arguments */
+#undef HAVE_GETHOSTBYADDR_R_5
+
+/* Define if you have the gethostbyaddr_r() function with 7 arguments */
+#undef HAVE_GETHOSTBYADDR_R_7
+
+/* Define if you have the gethostbyaddr_r() function with 8 arguments */
+#undef HAVE_GETHOSTBYADDR_R_8
+
+/* Define if you have the gethostbyname_r() function with 3 arguments */
+#undef HAVE_GETHOSTBYNAME_R_3
+
+/* Define if you have the gethostbyname_r() function with 5 arguments */
+#undef HAVE_GETHOSTBYNAME_R_5
+
+/* Define if you have the gethostbyname_r() function with 6 arguments */
+#undef HAVE_GETHOSTBYNAME_R_6
+
+/* Define if you need the _REENTRANT define for some functions */
+#undef NEED_REENTRANT
+
+/* Define if you have the Kerberos4 libraries (including -ldes) */
+#undef HAVE_KRB4
+
+/* Define if you want to enable IPv6 support */
+#undef ENABLE_IPV6
+
+/* Define if struct sockaddr_in6 has the sin6_scope_id member */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define this to 'int' if ssize_t is not an available typedefed type */
+#undef ssize_t
+
+/* Define this as a suitable file to read random data from */
+#undef RANDOM_FILE
+
+/* Define this to your Entropy Gathering Daemon socket pathname */
+#undef EGD_SOCKET
+
+/* Define if you want to enable IPv6 support */
+#undef ENABLE_IPV6
+
+/* Define if you have the alarm function. */
+#define HAVE_ALARM
+
+/* Define if you have the <alloca.h> header file. */
+#define HAVE_ALLOCA_H
+
+/* Define if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define if you have the `closesocket' function. */
+#undef HAVE_CLOSESOCKET
+
+/* Define if you have the <crypto.h> header file. */
+#undef HAVE_CRYPTO_H
+
+/* Define if you have the <des.h> header file. */
+#undef HAVE_DES_H
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H
+
+/* Define if you have the <err.h> header file. */
+#undef HAVE_ERR_H
+
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the `ftruncate' function. */
+#define HAVE_FTRUNCATE
+
+/* Define if getaddrinfo exists and works */
+#define HAVE_GETADDRINFO
+
+/* Define if you have the `geteuid' function. */
+#undef HAVE_GETEUID
+
+/* Define if you have the `gethostbyaddr' function. */
+#define HAVE_GETHOSTBYADDR
+
+/* Define if you have the `gethostbyaddr_r' function. */
+#undef HAVE_GETHOSTBYADDR_R
+
+/* Define if you have the `gethostbyname_r' function. */
+#undef HAVE_GETHOSTBYNAME_R
+
+/* Define if you have the `gethostname' function. */
+#define HAVE_GETHOSTNAME
+
+/* Define if you have the <getopt.h> header file. */
+#define HAVE_GETOPT_H
+
+/* Define if you have the `getpass_r' function. */
+#undef HAVE_GETPASS_R
+
+/* Define if you have the `getpwuid' function. */
+#undef HAVE_GETPWUID
+
+/* Define if you have the `getservbyname' function. */
+#undef HAVE_GETSERVBYNAME
+
+/* Define if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define if you have the `timeval' struct. */
+#define HAVE_STRUCT_TIMEVAL
+
+/* Define if you have the `inet_addr' function. */
+#undef HAVE_INET_ADDR
+
+/* Define if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H
+
+/* Define if you have the <io.h> header file. */
+#undef HAVE_IO_H
+
+/* Define if you have the `krb_get_our_ip_for_realm' function. */
+#undef HAVE_KRB_GET_OUR_IP_FOR_REALM
+
+/* Define if you have the <krb.h> header file. */
+#undef HAVE_KRB_H
+
+/* Define if you have the `crypto' library (-lcrypto). */
+#undef HAVE_LIBCRYPTO
+
+/* Define if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define if you have the `resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define if you have the `resolve' library (-lresolve). */
+#undef HAVE_LIBRESOLVE
+
+/* Define if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define if you have the `ssl' library (-lssl). */
+#undef HAVE_LIBSSL
+
+/* Define if you have the `ucb' library (-lucb). */
+#undef HAVE_LIBUCB
+
+/* Define if you have the `localtime_r' function. */
+#undef HAVE_LOCALTIME_R
+
+/* Define if you have the <malloc.h> header file. */
+#define HAVE_MALLOC_H
+
+/* Define if you need the malloc.h header file even with stdlib.h  */
+/* #define NEED_MALLOC_H 1 */
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define if you have the <netinet/if_ether.h> header file. */
+#undef HAVE_NETINET_IF_ETHER_H
+
+/* Define if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define if you have the <net/if.h> header file. */
+#undef HAVE_NET_IF_H
+
+/* Define if you have the <openssl/crypto.h> header file. */
+#undef HAVE_OPENSSL_CRYPTO_H
+
+/* Define if you have the <openssl/err.h> header file. */
+#undef HAVE_OPENSSL_ERR_H
+
+/* Define if you have the <openssl/pem.h> header file. */
+#undef HAVE_OPENSSL_PEM_H
+
+/* Define if you have the <openssl/rsa.h> header file. */
+#undef HAVE_OPENSSL_RSA_H
+
+/* Define if you have the <openssl/ssl.h> header file. */
+#undef HAVE_OPENSSL_SSL_H
+
+/* Define if you have the <openssl/x509.h> header file. */
+#undef HAVE_OPENSSL_X509_H
+
+/* Define if you have the <pem.h> header file. */
+#undef HAVE_PEM_H
+
+/* Define if you have the `perror' function. */
+#undef HAVE_PERROR
+
+/* Define if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
+/* Define if you have the `RAND_egd' function. */
+#undef HAVE_RAND_EGD
+
+/* Define if you have the `RAND_screen' function. */
+#undef HAVE_RAND_SCREEN
+
+/* Define if you have the `RAND_status' function. */
+#undef HAVE_RAND_STATUS
+
+/* Define if you have the <rsa.h> header file. */
+#undef HAVE_RSA_H
+
+/* Define if you have the `select' function. */
+#define HAVE_SELECT
+
+/* Define if you have the `setvbuf' function. */
+#undef HAVE_SETVBUF
+
+/* Define if you have the <sgtty.h> header file. */
+#define HAVE_SGTTY_H
+
+/* Define if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define if you have the `signal' function. */
+#define HAVE_SIGNAL
+
+/* Define if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T
+
+/* Define if sig_atomic_t is already defined as volatile. */
+#undef HAVE_SIG_ATOMIC_T_VOLATILE
+
+/* Define if you have the `socket' function. */
+#define HAVE_SOCKET
+
+/* Define if you have the <ssl.h> header file. */
+#undef HAVE_SSL_H
+
+/* Define if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H
+
+/* Define if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the `strcmpi' function. */
+#undef HAVE_STRCMPI
+
+/* Define if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define if you have the `strftime' function. */
+#define HAVE_STRFTIME
+
+/* Define if you have the `stricmp' function. */
+#undef HAVE_STRICMP
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H
+
+/* Define if you have the `strlcpy' function. */
+#undef HAVE_STRLCPY
+
+/* Define if you have the `strstr' function. */
+#define HAVE_STRSTR
+
+/* Define if you have the `strtok_r' function. */
+#undef HAVE_STRTOK_R
+
+/* Define if you have the `strtoll' function. */
+#undef HAVE_STRTOLL
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+#define USE_LWIPSOCK
+
+/* Define if you have the <sys/sockio.h> header file. */
+#undef HAVE_SYS_SOCKIO_H
+
+/* Define if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H
+
+/* Define if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H
+
+/* Define if you have the `tcgetattr' function. */
+#define HAVE_TCGETATTR
+
+/* Define if you have the `tcsetattr' function. */
+#define HAVE_TCSETATTR
+
+/* Define if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H
+
+/* Define if you have the <termio.h> header file. */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define if you have the `uname' function. */
+#define HAVE_UNAME
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the <winsock.h> header file. */
+#undef HAVE_WINSOCK_H
+
+/* Define if you have the <x509.h> header file. */
+#undef HAVE_X509_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long double', as computed by sizeof. */
+#undef SIZEOF_LONG_DOUBLE
+
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef ssize_t
+
+/* Define if you have the ioctl function. */
+#define HAVE_IOCTL
+
+/* Define if you have a working ioctl FIONBIO function. */
+#undef HAVE_IOCTL_FIONBIO
+#define HAVE_IOCTLSOCKET_FIONBIO
+
+/* to disable LDAP */
+#define CURL_DISABLE_LDAP 1
+
+/* Define if you have the getnameinfo function. */
+#define HAVE_GETNAMEINFO 1
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 size_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 int
+
+/* Define if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV ssize_t
+
+/* Define 1 if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 void
+
+/* Define if the type pointed by arg 2 for recvfrom is void. */
+#define RECVFROM_TYPE_ARG2_IS_VOID
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 int
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV ssize_t
+
+/* Define if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV ssize_t
+
+#define USE_CYASSL
+#define HAVE_CYASSL_ERROR_SSL_H
+#define OPENSSL_NO_MD4
+#define HTTP_ONLY
+#define STDC_HEADERS
+#define EISCONN ERR_USE
+#define HAVE_GMTIME_R
+#define HAVE_BOOL_T
+#define bool unsigned char
+//#define CURL_DISABLE_VERBOSE_STRINGS
+#define CURL_MAX_WRITE_SIZE 1024
+#define CURL_MAX_HTTP_HEADER 1024
+#define HAVE_WOLFSSL_GET_PEER_CERTIFICATE
+
+#include <integer.h>
+#define ssize_t int
+#define MAX_PATH 255
+#include <openssl/opensslv.h>
+#include "arch/sys_arch.h"
+void sys_sprintf(void *dst, const char *format, ...);
+#define sprintf sys_sprintf
+typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
+
+#endif /* HEADER_CURL_CONFIG_TOPPERS_ASP_H */
Index: UsbWattMeter/trunk/csp/libcurl/libcurl.mtpj
===================================================================
--- UsbWattMeter/trunk/csp/libcurl/libcurl.mtpj	(revision 164)
+++ UsbWattMeter/trunk/csp/libcurl/libcurl.mtpj	(revision 164)
@@ -0,0 +1,2730 @@
+<CubeSuiteProject>
+  <ProductVersion>4.02.00.00</ProductVersion>
+  <Class Guid="68f4a651-b9cd-473b-a595-b00447132ffa">
+    <Instance Guid="00000000-0000-0000-0000-000000000000">
+      <FormatVersion>2.0</FormatVersion>
+      <FileVersion>4.2</FileVersion>
+      <ProjectGuid>f0da2e13-ba87-4846-8bf0-0b501c3efa68</ProjectGuid>
+      <ProjectItemGuid>65c1e590-9c09-4e37-8f79-0c1840680aee</ProjectItemGuid>
+      <FileCategoryGuid>434f1efc-d438-449f-90f6-aeb0676e24f0</FileCategoryGuid>
+      <Property>fb98844b-2c27-4275-9804-f6e63e204da0</Property>
+      <ActiveProjectGuid>f0da2e13-ba87-4846-8bf0-0b501c3efa68</ActiveProjectGuid>
+    </Instance>
+    <Instance Guid="782acbe9-5cf7-4169-82be-0086cc92a94d">
+      <Name>amigaos.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\amigaos.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="1feacf8a-aca0-4c32-abbc-9ea634e59480">
+      <Name>asyn-ares.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\asyn-ares.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="f5345a6b-b651-4c4d-80fb-dc8e7701b4d3">
+      <Name>asyn-thread.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\asyn-thread.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="180ad314-b1eb-44ae-b5a3-242c407f0fba">
+      <Name>base64.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\base64.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="2576c0eb-e2bb-46f9-85f5-dc42e2e8bdaf">
+      <Name>conncache.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\conncache.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="66a18d69-f281-4ede-b5bc-b5150110196a">
+      <Name>connect.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\connect.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+      <Property>b1f36e75-27d3-49c3-b59b-2b0a75d6ce76</Property>
+    </Instance>
+    <Instance Guid="749ab9cb-be85-4c3e-9c42-aa24e5bad9f7">
+      <Name>content_encoding.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\content_encoding.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="d3f28a38-4e81-4931-9e4f-dd279e18cb3d">
+      <Name>cookie.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\cookie.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="c0423dfc-830f-4b19-ba87-79963909a3df">
+      <Name>curl_addrinfo.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_addrinfo.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="6579e164-1600-4ee9-82b1-f28b29ca034b">
+      <Name>curl_des.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_des.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="418365f9-2b8d-491e-ad6e-ba4838b71d54">
+      <Name>curl_endian.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_endian.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="3af94e22-91c2-4859-a9f1-ad7ba2e056d3">
+      <Name>curl_fnmatch.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_fnmatch.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="2db36ad4-004f-4d10-8823-aec4489d4473">
+      <Name>curl_gethostname.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_gethostname.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="6032b4b4-b29e-4278-a314-1a799ea842e4">
+      <Name>curl_gssapi.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_gssapi.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="84abe35a-d3f2-4e39-9c76-2a1d732a9280">
+      <Name>curl_memrchr.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_memrchr.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="eae21ebb-bf1f-4558-a8ca-c5bded683344">
+      <Name>curl_multibyte.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_multibyte.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="4cf957f4-ae3b-4c34-8675-f661bdef4806">
+      <Name>curl_ntlm.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_ntlm.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="f5044f5d-88f9-4d00-b9b2-5f2af8cb7bfb">
+      <Name>curl_ntlm_core.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_ntlm_core.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="5de6660f-e7ad-45fe-9c8f-afd2793b4159">
+      <Name>curl_ntlm_msgs.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_ntlm_msgs.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="eaf993b2-1312-492e-9836-539071a8f9a8">
+      <Name>curl_ntlm_wb.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_ntlm_wb.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="e1672a92-ed4b-4a3d-a6d9-40948ebe0601">
+      <Name>curl_rtmp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_rtmp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="b4784de3-f972-41e2-b199-e64bea00c6a5">
+      <Name>curl_sasl.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_sasl.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="0bb29243-3950-4fb4-85ae-324d87937d87">
+      <Name>curl_sasl_gssapi.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_sasl_gssapi.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="c7b49799-272e-4869-a113-1f2f19bf0202">
+      <Name>curl_sasl_sspi.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_sasl_sspi.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="0b8aaf6c-7522-4a7e-a654-5c6127b28f03">
+      <Name>curl_sspi.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_sspi.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="1cd171c0-cb2d-4637-8f4b-3b54a575f643">
+      <Name>curl_threads.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\curl_threads.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="0f5a1d35-4b00-4ce0-8531-0de2ab8a123f">
+      <Name>dict.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\dict.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="9b9f3434-ec89-434b-99f7-a72314ca4250">
+      <Name>dotdot.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\dotdot.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="790e3342-c173-444b-9e23-deccc2df0268">
+      <Name>easy.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\easy.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+      <Property>08c3e5b2-f823-4e0d-9781-e5706ab4b163</Property>
+    </Instance>
+    <Instance Guid="d72867ed-199e-4141-800f-2fb92007032f">
+      <Name>escape.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\escape.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="6c0f6d34-386f-4862-803f-e6e1cf18b0ca">
+      <Name>file.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\file.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="b5bf059f-b56e-4d08-95da-0ee7f9450ec6">
+      <Name>fileinfo.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\fileinfo.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="f1c1cf0e-33e9-4e88-b75c-ed2c2150dfe4">
+      <Name>formdata.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\formdata.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+      <Property>9ec8a05a-d3b6-43b7-8505-fd6aa170c8ce</Property>
+    </Instance>
+    <Instance Guid="741d7f88-85b9-4340-8415-d9023fc2a39b">
+      <Name>ftp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\ftp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="ad988a0a-d5ff-4aca-af62-a0a9adc389ae">
+      <Name>ftplistparser.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\ftplistparser.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="ee886e6a-6f57-42f1-9683-d4832059d2e6">
+      <Name>getenv.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\getenv.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="74e8d9eb-3261-451f-a4fd-6001f760d396">
+      <Name>getinfo.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\getinfo.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="1dc13d6a-4a24-43e5-a831-2b45d4ba243a">
+      <Name>gopher.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\gopher.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="a96a247f-1f65-47ad-855e-4c30e4864f97">
+      <Name>hash.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\hash.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="3aa11eb9-3713-4cf8-9eca-ea0f62d8ffe5">
+      <Name>hmac.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\hmac.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="8e1bdb7d-948b-41f7-bdcb-3d56eb4c9176">
+      <Name>hostasyn.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\hostasyn.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="187a1d11-344f-46d7-9bc7-0b98b131e3fa">
+      <Name>hostcheck.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\hostcheck.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="761de404-09b5-41f1-83d2-d24dfdfbb50c">
+      <Name>hostip.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\hostip.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="f9394348-e3a0-47d6-9522-43cacc254833">
+      <Name>hostip4.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\hostip4.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="a6a6466d-2a56-411e-8844-a4a1c1a48543">
+      <Name>hostip6.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\hostip6.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="8601845c-95ac-413b-a98e-80d514767494">
+      <Name>hostsyn.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\hostsyn.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="960b8aee-c6c0-4cb4-a314-63df4fef4961">
+      <Name>http.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\http.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="8a90fd8f-f340-4005-8766-e7937cc6ffce">
+      <Name>http_chunks.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\http_chunks.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="ccdecbd2-243c-42dd-9d48-4c276f116b01">
+      <Name>http_digest.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\http_digest.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="b575786e-50db-4a62-841d-9627a67a0bbb">
+      <Name>http_negotiate.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\http_negotiate.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="fdedefc7-53ca-4daa-9436-b5b46e5f6831">
+      <Name>http_negotiate_sspi.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\http_negotiate_sspi.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="0a4b55dc-74ea-45d6-bd1b-e40c51bf8cd4">
+      <Name>http_proxy.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\http_proxy.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="4cbb2de7-5dae-4a98-b09f-cc04c202f9fc">
+      <Name>http2.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\http2.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="f81e708a-b9a4-4f36-b84d-ce25fa843a43">
+      <Name>idn_win32.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\idn_win32.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="b355e759-afe5-41b0-8f0a-8200762a9046">
+      <Name>if2ip.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\if2ip.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="14844d6e-8941-4d29-bf85-29068c43aa94">
+      <Name>imap.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\imap.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="b3ce2223-daf1-41bd-9244-28f3fa010100">
+      <Name>inet_ntop.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\inet_ntop.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="de00ccf9-01d8-4539-92fb-42435617d3e7">
+      <Name>inet_pton.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\inet_pton.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="9784dcda-a5ae-4d46-bbc6-4d063ca8c05d">
+      <Name>krb5.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\krb5.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="9493d492-bbcb-4d60-9bd2-603cc4b24d29">
+      <Name>ldap.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\ldap.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="d2b2e7c1-fe24-4fca-8a95-ec7b9fb3b486">
+      <Name>llist.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\llist.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="58f77449-e9c2-472d-b2f2-b03805e42759">
+      <Name>md4.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\md4.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="5ab616a7-3ec1-423f-a135-eea134e78841">
+      <Name>md5.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\md5.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="decc8864-8bc3-497d-9f3c-ed1b6954a857">
+      <Name>memdebug.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\memdebug.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="8e058660-9748-4679-b381-ebc82081a7c5">
+      <Name>mprintf.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\mprintf.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="e40aab60-b084-4ff5-bbe8-523b25e406eb">
+      <Name>multi.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\multi.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="866fe1e0-aca7-4944-bcf1-4e8d6bdf7e6a">
+      <Name>netrc.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\netrc.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="f5da104b-4f4b-4927-a9e5-a3a62a045a3a">
+      <Name>non-ascii.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\non-ascii.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="e0e4588c-7de1-46cb-bcbb-b9d03b3a4af0">
+      <Name>nonblock.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\nonblock.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="0761423f-604f-48fb-9f8b-ee9983366be7">
+      <Name>nwlib.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\nwlib.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="0958d97f-eaa0-4d76-81f4-5eb8b244baf4">
+      <Name>nwos.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\nwos.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="99f62c21-dff6-4469-a1e3-13187d02331f">
+      <Name>openldap.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\openldap.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="a6e94e0f-0849-4398-917c-e6a924cf48d6">
+      <Name>parsedate.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\parsedate.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="6fac82ca-94f3-460d-bd7f-386bcbfc3615">
+      <Name>pingpong.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\pingpong.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="b01b180b-ae9d-48fe-b22f-08230b40db8d">
+      <Name>pipeline.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\pipeline.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="4291413c-a84b-4ce3-a709-751df9431e3a">
+      <Name>pop3.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\pop3.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="9c576831-3da3-4869-a95d-b4e0aad35d16">
+      <Name>progress.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\progress.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="503429a7-cbda-4825-8f0d-f3765f3ee76d">
+      <Name>rawstr.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\rawstr.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="1dc2f041-6a23-4d35-b7a2-cfeb13e8eeb9">
+      <Name>rtsp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\rtsp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="3fe81a7f-6260-4a68-a81f-1ef0ab5230c4">
+      <Name>security.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\security.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="1cd05811-189c-4e24-920d-473ad0e5614c">
+      <Name>select.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\select.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="f34207af-343c-4c2d-985e-296cb065aa55">
+      <Name>sendf.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\sendf.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="83149e99-e7ef-421b-9178-f72edab7748d">
+      <Name>share.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\share.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="cd203796-7b11-4872-88ae-770eddf17923">
+      <Name>slist.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\slist.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="22421e7d-6b65-4c26-bd0d-798637478d70">
+      <Name>smb.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\smb.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="e6a72f5c-0021-4d25-9ccf-8ffddf5ce599">
+      <Name>smtp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\smtp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="1cafe355-05a7-42a2-af9e-9f0ca0a90880">
+      <Name>socks.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\socks.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="2a6aece1-4f1d-4ff6-9860-c493f4d27221">
+      <Name>socks_gssapi.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\socks_gssapi.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="a2b1bf35-fa87-4073-bb76-11c04892f28b">
+      <Name>socks_sspi.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\socks_sspi.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="a84d211f-e911-45c0-bd95-9648646a563d">
+      <Name>speedcheck.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\speedcheck.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="95b231b9-0801-4245-925c-ed071c03ece2">
+      <Name>splay.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\splay.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="20e8e714-a306-4b2c-95ee-eba59ededade">
+      <Name>ssh.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\ssh.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="aaa983a3-61ac-4e97-9ec2-6146e40be0f0">
+      <Name>strdup.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\strdup.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="41a5594a-edac-40ea-bb78-4f1e809d40d8">
+      <Name>strequal.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\strequal.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="62a8d1f7-b124-48d7-b011-b68f614ec0d7">
+      <Name>strerror.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\strerror.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="c0f047b1-97af-44c5-a10e-a9831d1c97ca">
+      <Name>strtok.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\strtok.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="029c071f-a252-4b94-8445-0ec25919ed08">
+      <Name>strtoofft.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\strtoofft.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="d26ffb2e-8b0d-4fe4-9bf3-943ac85d8abc">
+      <Name>telnet.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\telnet.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="f7e60d17-dbc9-46d2-a666-45a8de4a6f2a">
+      <Name>tftp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\tftp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="80daab28-c7a4-4c35-8802-5ed3c3654bfb">
+      <Name>timeval.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\timeval.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="8c1e4bb7-0ced-4fce-a544-a9355e709c82">
+      <Name>transfer.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\transfer.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="d9d736c7-f4e0-4d87-9878-9ce85131fa4a">
+      <Name>url.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\url.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="bdccac78-382d-43dc-95a1-29f20a922711">
+      <Name>version.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\version.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="4cf04bad-3c0e-4648-b778-0a128863b82c">
+      <Name>warnless.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\warnless.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="f452e069-2666-4b40-9446-eb49151c2091">
+      <Name>wildcard.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\wildcard.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="a6d29305-cf6b-455c-8575-1a958b0277f2">
+      <Name>x509asn1.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\x509asn1.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="d1f3b4d1-e0e4-4617-a3f8-a31fc90dd1f6">
+      <Name>cyassl.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\vtls\cyassl.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+    <Instance Guid="ea37bd1c-74e2-4e52-b30e-5c9bb8aa404c">
+      <Name>vtls.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\curl-7.47.1\lib\vtls\vtls.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>434f1efc-d438-449f-90f6-aeb0676e24f0</ParentItem>
+    </Instance>
+  </Class>
+  <Class Guid="fb98844b-2c27-4275-9804-f6e63e204da0">
+    <Instance Guid="fb98844b-2c27-4275-9804-f6e63e204da0">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="0d548289-d5e9-4893-9a8f-9374b13f19a9">
+    <Instance Guid="b1f36e75-27d3-49c3-b59b-2b0a75d6ce76">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="08c3e5b2-f823-4e0d-9781-e5706ab4b163">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="9ec8a05a-d3b6-43b7-8505-fd6aa170c8ce">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="8fb9c1f6-d351-4d10-8d99-bf5b3015b84c">
+    <Instance Guid="00000000-0000-0000-0000-000000000000">
+      <UsingPlatformGuid>7020d445-1358-4043-a8ea-3b101e73ceaa</UsingPlatformGuid>
+      <UsingPlatformTypeGuid>f96683fa-8de4-4c6d-a1ab-925d7f232c09</UsingPlatformTypeGuid>
+    </Instance>
+  </Class>
+  <Class Guid="c325714f-8f51-484b-9e96-b4b59c0fb263">
+    <Instance Guid="c325714f-8f51-484b-9e96-b4b59c0fb263">
+      <DeviceManager>0e793ff3-2e3f-43c0-bdc9-926269595403</DeviceManager>
+    </Instance>
+  </Class>
+  <Class Guid="0e793ff3-2e3f-43c0-bdc9-926269595403">
+    <Instance Guid="0e793ff3-2e3f-43c0-bdc9-926269595403">
+      <DataFormatVersion>1.0</DataFormatVersion>
+    </Instance>
+    <Instance Guid="2a81c37a-5015-44c2-9f40-e58b669eec75">
+      <DeviceName>R5F563NBDxFP</DeviceName>
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="873c9a58-9bc5-439a-b476-78629a4553ed">
+    <Instance Guid="873c9a58-9bc5-439a-b476-78629a4553ed">
+      <ProjectDeviceChangedCounter>0</ProjectDeviceChangedCounter>
+      <ProjectInitialDeviceName>R5F563NBDxFP</ProjectInitialDeviceName>
+    </Instance>
+  </Class>
+  <Class Guid="c3835e31-dea3-4c93-b02b-d2db997f7630">
+    <Instance Guid="c3835e31-dea3-4c93-b02b-d2db997f7630">
+      <BuildToolManager>3a79707d-5977-45f7-ac11-19c35e333132</BuildToolManager>
+    </Instance>
+  </Class>
+  <Class Guid="3a79707d-5977-45f7-ac11-19c35e333132">
+    <Instance Guid="3a79707d-5977-45f7-ac11-19c35e333132">
+      <DataFormatVersion>1.2</DataFormatVersion>
+      <BuildModeCount>1</BuildModeCount>
+      <BuildMode0>RABlAGYAYQB1AGwAdABCAHUAaQBsAGQA</BuildMode0>
+      <BatchBuildFlag0>False</BatchBuildFlag0>
+      <CurrentBuildMode>DefaultBuild</CurrentBuildMode>
+      <SourceItemGuid0>782acbe9-5cf7-4169-82be-0086cc92a94d</SourceItemGuid0>
+      <SourceItemType0>CSource</SourceItemType0>
+      <SourceItemGuid1>1feacf8a-aca0-4c32-abbc-9ea634e59480</SourceItemGuid1>
+      <SourceItemType1>CSource</SourceItemType1>
+      <SourceItemGuid2>f5345a6b-b651-4c4d-80fb-dc8e7701b4d3</SourceItemGuid2>
+      <SourceItemType2>CSource</SourceItemType2>
+      <SourceItemGuid3>180ad314-b1eb-44ae-b5a3-242c407f0fba</SourceItemGuid3>
+      <SourceItemType3>CSource</SourceItemType3>
+      <SourceItemGuid4>2576c0eb-e2bb-46f9-85f5-dc42e2e8bdaf</SourceItemGuid4>
+      <SourceItemType4>CSource</SourceItemType4>
+      <SourceItemGuid5>66a18d69-f281-4ede-b5bc-b5150110196a</SourceItemGuid5>
+      <SourceItemType5>CSource</SourceItemType5>
+      <SourceItemGuid6>749ab9cb-be85-4c3e-9c42-aa24e5bad9f7</SourceItemGuid6>
+      <SourceItemType6>CSource</SourceItemType6>
+      <SourceItemGuid7>d3f28a38-4e81-4931-9e4f-dd279e18cb3d</SourceItemGuid7>
+      <SourceItemType7>CSource</SourceItemType7>
+      <SourceItemGuid8>c0423dfc-830f-4b19-ba87-79963909a3df</SourceItemGuid8>
+      <SourceItemType8>CSource</SourceItemType8>
+      <SourceItemGuid9>6579e164-1600-4ee9-82b1-f28b29ca034b</SourceItemGuid9>
+      <SourceItemType9>CSource</SourceItemType9>
+      <SourceItemGuid10>418365f9-2b8d-491e-ad6e-ba4838b71d54</SourceItemGuid10>
+      <SourceItemType10>CSource</SourceItemType10>
+      <SourceItemGuid11>3af94e22-91c2-4859-a9f1-ad7ba2e056d3</SourceItemGuid11>
+      <SourceItemType11>CSource</SourceItemType11>
+      <SourceItemGuid12>2db36ad4-004f-4d10-8823-aec4489d4473</SourceItemGuid12>
+      <SourceItemType12>CSource</SourceItemType12>
+      <SourceItemGuid13>6032b4b4-b29e-4278-a314-1a799ea842e4</SourceItemGuid13>
+      <SourceItemType13>CSource</SourceItemType13>
+      <SourceItemGuid14>84abe35a-d3f2-4e39-9c76-2a1d732a9280</SourceItemGuid14>
+      <SourceItemType14>CSource</SourceItemType14>
+      <SourceItemGuid15>eae21ebb-bf1f-4558-a8ca-c5bded683344</SourceItemGuid15>
+      <SourceItemType15>CSource</SourceItemType15>
+      <SourceItemGuid16>4cf957f4-ae3b-4c34-8675-f661bdef4806</SourceItemGuid16>
+      <SourceItemType16>CSource</SourceItemType16>
+      <SourceItemGuid17>f5044f5d-88f9-4d00-b9b2-5f2af8cb7bfb</SourceItemGuid17>
+      <SourceItemType17>CSource</SourceItemType17>
+      <SourceItemGuid18>5de6660f-e7ad-45fe-9c8f-afd2793b4159</SourceItemGuid18>
+      <SourceItemType18>CSource</SourceItemType18>
+      <SourceItemGuid19>eaf993b2-1312-492e-9836-539071a8f9a8</SourceItemGuid19>
+      <SourceItemType19>CSource</SourceItemType19>
+      <SourceItemGuid20>e1672a92-ed4b-4a3d-a6d9-40948ebe0601</SourceItemGuid20>
+      <SourceItemType20>CSource</SourceItemType20>
+      <SourceItemGuid21>b4784de3-f972-41e2-b199-e64bea00c6a5</SourceItemGuid21>
+      <SourceItemType21>CSource</SourceItemType21>
+      <SourceItemGuid22>0bb29243-3950-4fb4-85ae-324d87937d87</SourceItemGuid22>
+      <SourceItemType22>CSource</SourceItemType22>
+      <SourceItemGuid23>c7b49799-272e-4869-a113-1f2f19bf0202</SourceItemGuid23>
+      <SourceItemType23>CSource</SourceItemType23>
+      <SourceItemGuid24>0b8aaf6c-7522-4a7e-a654-5c6127b28f03</SourceItemGuid24>
+      <SourceItemType24>CSource</SourceItemType24>
+      <SourceItemGuid25>1cd171c0-cb2d-4637-8f4b-3b54a575f643</SourceItemGuid25>
+      <SourceItemType25>CSource</SourceItemType25>
+      <SourceItemGuid26>0f5a1d35-4b00-4ce0-8531-0de2ab8a123f</SourceItemGuid26>
+      <SourceItemType26>CSource</SourceItemType26>
+      <SourceItemGuid27>9b9f3434-ec89-434b-99f7-a72314ca4250</SourceItemGuid27>
+      <SourceItemType27>CSource</SourceItemType27>
+      <SourceItemGuid28>790e3342-c173-444b-9e23-deccc2df0268</SourceItemGuid28>
+      <SourceItemType28>CSource</SourceItemType28>
+      <SourceItemGuid29>d72867ed-199e-4141-800f-2fb92007032f</SourceItemGuid29>
+      <SourceItemType29>CSource</SourceItemType29>
+      <SourceItemGuid30>6c0f6d34-386f-4862-803f-e6e1cf18b0ca</SourceItemGuid30>
+      <SourceItemType30>CSource</SourceItemType30>
+      <SourceItemGuid31>b5bf059f-b56e-4d08-95da-0ee7f9450ec6</SourceItemGuid31>
+      <SourceItemType31>CSource</SourceItemType31>
+      <SourceItemGuid32>f1c1cf0e-33e9-4e88-b75c-ed2c2150dfe4</SourceItemGuid32>
+      <SourceItemType32>CSource</SourceItemType32>
+      <SourceItemGuid33>741d7f88-85b9-4340-8415-d9023fc2a39b</SourceItemGuid33>
+      <SourceItemType33>CSource</SourceItemType33>
+      <SourceItemGuid34>ad988a0a-d5ff-4aca-af62-a0a9adc389ae</SourceItemGuid34>
+      <SourceItemType34>CSource</SourceItemType34>
+      <SourceItemGuid35>ee886e6a-6f57-42f1-9683-d4832059d2e6</SourceItemGuid35>
+      <SourceItemType35>CSource</SourceItemType35>
+      <SourceItemGuid36>74e8d9eb-3261-451f-a4fd-6001f760d396</SourceItemGuid36>
+      <SourceItemType36>CSource</SourceItemType36>
+      <SourceItemGuid37>1dc13d6a-4a24-43e5-a831-2b45d4ba243a</SourceItemGuid37>
+      <SourceItemType37>CSource</SourceItemType37>
+      <SourceItemGuid38>a96a247f-1f65-47ad-855e-4c30e4864f97</SourceItemGuid38>
+      <SourceItemType38>CSource</SourceItemType38>
+      <SourceItemGuid39>3aa11eb9-3713-4cf8-9eca-ea0f62d8ffe5</SourceItemGuid39>
+      <SourceItemType39>CSource</SourceItemType39>
+      <SourceItemGuid40>8e1bdb7d-948b-41f7-bdcb-3d56eb4c9176</SourceItemGuid40>
+      <SourceItemType40>CSource</SourceItemType40>
+      <SourceItemGuid41>187a1d11-344f-46d7-9bc7-0b98b131e3fa</SourceItemGuid41>
+      <SourceItemType41>CSource</SourceItemType41>
+      <SourceItemGuid42>761de404-09b5-41f1-83d2-d24dfdfbb50c</SourceItemGuid42>
+      <SourceItemType42>CSource</SourceItemType42>
+      <SourceItemGuid43>f9394348-e3a0-47d6-9522-43cacc254833</SourceItemGuid43>
+      <SourceItemType43>CSource</SourceItemType43>
+      <SourceItemGuid44>a6a6466d-2a56-411e-8844-a4a1c1a48543</SourceItemGuid44>
+      <SourceItemType44>CSource</SourceItemType44>
+      <SourceItemGuid45>8601845c-95ac-413b-a98e-80d514767494</SourceItemGuid45>
+      <SourceItemType45>CSource</SourceItemType45>
+      <SourceItemGuid46>960b8aee-c6c0-4cb4-a314-63df4fef4961</SourceItemGuid46>
+      <SourceItemType46>CSource</SourceItemType46>
+      <SourceItemGuid47>8a90fd8f-f340-4005-8766-e7937cc6ffce</SourceItemGuid47>
+      <SourceItemType47>CSource</SourceItemType47>
+      <SourceItemGuid48>ccdecbd2-243c-42dd-9d48-4c276f116b01</SourceItemGuid48>
+      <SourceItemType48>CSource</SourceItemType48>
+      <SourceItemGuid49>b575786e-50db-4a62-841d-9627a67a0bbb</SourceItemGuid49>
+      <SourceItemType49>CSource</SourceItemType49>
+      <SourceItemGuid50>fdedefc7-53ca-4daa-9436-b5b46e5f6831</SourceItemGuid50>
+      <SourceItemType50>CSource</SourceItemType50>
+      <SourceItemGuid51>0a4b55dc-74ea-45d6-bd1b-e40c51bf8cd4</SourceItemGuid51>
+      <SourceItemType51>CSource</SourceItemType51>
+      <SourceItemGuid52>4cbb2de7-5dae-4a98-b09f-cc04c202f9fc</SourceItemGuid52>
+      <SourceItemType52>CSource</SourceItemType52>
+      <SourceItemGuid53>f81e708a-b9a4-4f36-b84d-ce25fa843a43</SourceItemGuid53>
+      <SourceItemType53>CSource</SourceItemType53>
+      <SourceItemGuid54>b355e759-afe5-41b0-8f0a-8200762a9046</SourceItemGuid54>
+      <SourceItemType54>CSource</SourceItemType54>
+      <SourceItemGuid55>14844d6e-8941-4d29-bf85-29068c43aa94</SourceItemGuid55>
+      <SourceItemType55>CSource</SourceItemType55>
+      <SourceItemGuid56>b3ce2223-daf1-41bd-9244-28f3fa010100</SourceItemGuid56>
+      <SourceItemType56>CSource</SourceItemType56>
+      <SourceItemGuid57>de00ccf9-01d8-4539-92fb-42435617d3e7</SourceItemGuid57>
+      <SourceItemType57>CSource</SourceItemType57>
+      <SourceItemGuid58>9784dcda-a5ae-4d46-bbc6-4d063ca8c05d</SourceItemGuid58>
+      <SourceItemType58>CSource</SourceItemType58>
+      <SourceItemGuid59>9493d492-bbcb-4d60-9bd2-603cc4b24d29</SourceItemGuid59>
+      <SourceItemType59>CSource</SourceItemType59>
+      <SourceItemGuid60>d2b2e7c1-fe24-4fca-8a95-ec7b9fb3b486</SourceItemGuid60>
+      <SourceItemType60>CSource</SourceItemType60>
+      <SourceItemGuid61>58f77449-e9c2-472d-b2f2-b03805e42759</SourceItemGuid61>
+      <SourceItemType61>CSource</SourceItemType61>
+      <SourceItemGuid62>5ab616a7-3ec1-423f-a135-eea134e78841</SourceItemGuid62>
+      <SourceItemType62>CSource</SourceItemType62>
+      <SourceItemGuid63>decc8864-8bc3-497d-9f3c-ed1b6954a857</SourceItemGuid63>
+      <SourceItemType63>CSource</SourceItemType63>
+      <SourceItemGuid64>8e058660-9748-4679-b381-ebc82081a7c5</SourceItemGuid64>
+      <SourceItemType64>CSource</SourceItemType64>
+      <SourceItemGuid65>e40aab60-b084-4ff5-bbe8-523b25e406eb</SourceItemGuid65>
+      <SourceItemType65>CSource</SourceItemType65>
+      <SourceItemGuid66>866fe1e0-aca7-4944-bcf1-4e8d6bdf7e6a</SourceItemGuid66>
+      <SourceItemType66>CSource</SourceItemType66>
+      <SourceItemGuid67>f5da104b-4f4b-4927-a9e5-a3a62a045a3a</SourceItemGuid67>
+      <SourceItemType67>CSource</SourceItemType67>
+      <SourceItemGuid68>e0e4588c-7de1-46cb-bcbb-b9d03b3a4af0</SourceItemGuid68>
+      <SourceItemType68>CSource</SourceItemType68>
+      <SourceItemGuid69>0761423f-604f-48fb-9f8b-ee9983366be7</SourceItemGuid69>
+      <SourceItemType69>CSource</SourceItemType69>
+      <SourceItemGuid70>0958d97f-eaa0-4d76-81f4-5eb8b244baf4</SourceItemGuid70>
+      <SourceItemType70>CSource</SourceItemType70>
+      <SourceItemGuid71>99f62c21-dff6-4469-a1e3-13187d02331f</SourceItemGuid71>
+      <SourceItemType71>CSource</SourceItemType71>
+      <SourceItemGuid72>a6e94e0f-0849-4398-917c-e6a924cf48d6</SourceItemGuid72>
+      <SourceItemType72>CSource</SourceItemType72>
+      <SourceItemGuid73>6fac82ca-94f3-460d-bd7f-386bcbfc3615</SourceItemGuid73>
+      <SourceItemType73>CSource</SourceItemType73>
+      <SourceItemGuid74>b01b180b-ae9d-48fe-b22f-08230b40db8d</SourceItemGuid74>
+      <SourceItemType74>CSource</SourceItemType74>
+      <SourceItemGuid75>4291413c-a84b-4ce3-a709-751df9431e3a</SourceItemGuid75>
+      <SourceItemType75>CSource</SourceItemType75>
+      <SourceItemGuid76>9c576831-3da3-4869-a95d-b4e0aad35d16</SourceItemGuid76>
+      <SourceItemType76>CSource</SourceItemType76>
+      <SourceItemGuid77>503429a7-cbda-4825-8f0d-f3765f3ee76d</SourceItemGuid77>
+      <SourceItemType77>CSource</SourceItemType77>
+      <SourceItemGuid78>1dc2f041-6a23-4d35-b7a2-cfeb13e8eeb9</SourceItemGuid78>
+      <SourceItemType78>CSource</SourceItemType78>
+      <SourceItemGuid79>3fe81a7f-6260-4a68-a81f-1ef0ab5230c4</SourceItemGuid79>
+      <SourceItemType79>CSource</SourceItemType79>
+      <SourceItemGuid80>1cd05811-189c-4e24-920d-473ad0e5614c</SourceItemGuid80>
+      <SourceItemType80>CSource</SourceItemType80>
+      <SourceItemGuid81>f34207af-343c-4c2d-985e-296cb065aa55</SourceItemGuid81>
+      <SourceItemType81>CSource</SourceItemType81>
+      <SourceItemGuid82>83149e99-e7ef-421b-9178-f72edab7748d</SourceItemGuid82>
+      <SourceItemType82>CSource</SourceItemType82>
+      <SourceItemGuid83>cd203796-7b11-4872-88ae-770eddf17923</SourceItemGuid83>
+      <SourceItemType83>CSource</SourceItemType83>
+      <SourceItemGuid84>22421e7d-6b65-4c26-bd0d-798637478d70</SourceItemGuid84>
+      <SourceItemType84>CSource</SourceItemType84>
+      <SourceItemGuid85>e6a72f5c-0021-4d25-9ccf-8ffddf5ce599</SourceItemGuid85>
+      <SourceItemType85>CSource</SourceItemType85>
+      <SourceItemGuid86>1cafe355-05a7-42a2-af9e-9f0ca0a90880</SourceItemGuid86>
+      <SourceItemType86>CSource</SourceItemType86>
+      <SourceItemGuid87>2a6aece1-4f1d-4ff6-9860-c493f4d27221</SourceItemGuid87>
+      <SourceItemType87>CSource</SourceItemType87>
+      <SourceItemGuid88>a2b1bf35-fa87-4073-bb76-11c04892f28b</SourceItemGuid88>
+      <SourceItemType88>CSource</SourceItemType88>
+      <SourceItemGuid89>a84d211f-e911-45c0-bd95-9648646a563d</SourceItemGuid89>
+      <SourceItemType89>CSource</SourceItemType89>
+      <SourceItemGuid90>95b231b9-0801-4245-925c-ed071c03ece2</SourceItemGuid90>
+      <SourceItemType90>CSource</SourceItemType90>
+      <SourceItemGuid91>20e8e714-a306-4b2c-95ee-eba59ededade</SourceItemGuid91>
+      <SourceItemType91>CSource</SourceItemType91>
+      <SourceItemGuid92>aaa983a3-61ac-4e97-9ec2-6146e40be0f0</SourceItemGuid92>
+      <SourceItemType92>CSource</SourceItemType92>
+      <SourceItemGuid93>41a5594a-edac-40ea-bb78-4f1e809d40d8</SourceItemGuid93>
+      <SourceItemType93>CSource</SourceItemType93>
+      <SourceItemGuid94>62a8d1f7-b124-48d7-b011-b68f614ec0d7</SourceItemGuid94>
+      <SourceItemType94>CSource</SourceItemType94>
+      <SourceItemGuid95>c0f047b1-97af-44c5-a10e-a9831d1c97ca</SourceItemGuid95>
+      <SourceItemType95>CSource</SourceItemType95>
+      <SourceItemGuid96>029c071f-a252-4b94-8445-0ec25919ed08</SourceItemGuid96>
+      <SourceItemType96>CSource</SourceItemType96>
+      <SourceItemGuid97>d26ffb2e-8b0d-4fe4-9bf3-943ac85d8abc</SourceItemGuid97>
+      <SourceItemType97>CSource</SourceItemType97>
+      <SourceItemGuid98>f7e60d17-dbc9-46d2-a666-45a8de4a6f2a</SourceItemGuid98>
+      <SourceItemType98>CSource</SourceItemType98>
+      <SourceItemGuid99>80daab28-c7a4-4c35-8802-5ed3c3654bfb</SourceItemGuid99>
+      <SourceItemType99>CSource</SourceItemType99>
+      <SourceItemGuid100>8c1e4bb7-0ced-4fce-a544-a9355e709c82</SourceItemGuid100>
+      <SourceItemType100>CSource</SourceItemType100>
+      <SourceItemGuid101>d9d736c7-f4e0-4d87-9878-9ce85131fa4a</SourceItemGuid101>
+      <SourceItemType101>CSource</SourceItemType101>
+      <SourceItemGuid102>bdccac78-382d-43dc-95a1-29f20a922711</SourceItemGuid102>
+      <SourceItemType102>CSource</SourceItemType102>
+      <SourceItemGuid103>4cf04bad-3c0e-4648-b778-0a128863b82c</SourceItemGuid103>
+      <SourceItemType103>CSource</SourceItemType103>
+      <SourceItemGuid104>f452e069-2666-4b40-9446-eb49151c2091</SourceItemGuid104>
+      <SourceItemType104>CSource</SourceItemType104>
+      <SourceItemGuid105>a6d29305-cf6b-455c-8575-1a958b0277f2</SourceItemGuid105>
+      <SourceItemType105>CSource</SourceItemType105>
+      <SourceItemGuid106>d1f3b4d1-e0e4-4617-a3f8-a31fc90dd1f6</SourceItemGuid106>
+      <SourceItemType106>CSource</SourceItemType106>
+      <SourceItemGuid107>ea37bd1c-74e2-4e52-b30e-5c9bb8aa404c</SourceItemGuid107>
+      <SourceItemType107>CSource</SourceItemType107>
+      <SourceItemCount>108</SourceItemCount>
+      <LastDeviceChangedCounter>0</LastDeviceChangedCounter>
+    </Instance>
+    <Instance Guid="9e208646-ccba-4100-a676-29b1efe6545f">
+      <AsmOptionInclude-DefaultValue />
+      <BuildMode-DefaultValue>DefaultBuild</BuildMode-DefaultValue>
+      <COptionInclude-DefaultValue />
+      <GeneralOptionIsa-DefaultValue>RXv1</GeneralOptionIsa-DefaultValue>
+      <GeneralOptionOutput-DefaultValue>LibraryFile</GeneralOptionOutput-DefaultValue>
+      <GeneralOptionPic-DefaultValue>False</GeneralOptionPic-DefaultValue>
+      <GeneralOptionSimultaneousBuild-DefaultValue>True</GeneralOptionSimultaneousBuild-DefaultValue>
+      <HexOptionOutput-DefaultValue>True</HexOptionOutput-DefaultValue>
+      <LibOptionDebug-DefaultValue>Debug</LibOptionDebug-DefaultValue>
+      <LinkOptionLibrary-DefaultValue />
+      <Memo-DefaultValue />
+      <OutputMessageFormat-DefaultValue>%TargetFiles%</OutputMessageFormat-DefaultValue>
+      <AsmOptionSystemInclude-DefaultValue />
+      <COptionSystemInclude-DefaultValue />
+      <CompilerVersion-DefaultValue>
+
+0</CompilerVersion-DefaultValue>
+      <DependencyFileExistCheckingType-DefaultValue>Rebuild</DependencyFileExistCheckingType-DefaultValue>
+      <FormatBuildOptionList-DefaultValue>%TargetFiles% : %Program% %Options%</FormatBuildOptionList-DefaultValue>
+      <GeneralOptionCpu-DefaultValue>RX600</GeneralOptionCpu-DefaultValue>
+      <GeneralOptionOutputFolder-DefaultValue>%BuildModeName%</GeneralOptionOutputFolder-DefaultValue>
+      <GeneralOptionPid-DefaultValue>None</GeneralOptionPid-DefaultValue>
+      <HexOptionForm-DefaultValue>Stype</HexOptionForm-DefaultValue>
+      <LinkOptionDebug-DefaultValue>Debug</LinkOptionDebug-DefaultValue>
+      <AsmOptionDefine-DefaultValue />
+      <COptionDefine-DefaultValue />
+      <EnsureCompatibilityOfPathAndLinkageOrder-DefaultValue>False</EnsureCompatibilityOfPathAndLinkageOrder-DefaultValue>
+      <GeneralOptionFpu-DefaultValue>Fpu</GeneralOptionFpu-DefaultValue>
+      <GeneralOptionNousePidRegister-DefaultValue>True</GeneralOptionNousePidRegister-DefaultValue>
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionOptimize-DefaultValue>None</LinkOptionOptimize-DefaultValue>
+      <AsmOptionDebug-DefaultValue>True</AsmOptionDebug-DefaultValue>
+      <COptionDebug-DefaultValue>True</COptionDebug-DefaultValue>
+      <GeneralOptionEndian-DefaultValue>Little</GeneralOptionEndian-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionOptimizeSymbolDelete-DefaultValue>False</LinkOptionOptimizeSymbolDelete-DefaultValue>
+      <PreBuildCommands-DefaultValue />
+      <AsmOptionGoptimize-DefaultValue>False</AsmOptionGoptimize-DefaultValue>
+      <COptionOptimize-DefaultValue>Level2</COptionOptimize-DefaultValue>
+      <GeneralOptionRound-DefaultValue>Nearest</GeneralOptionRound-DefaultValue>
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionOptimizeSameCode-DefaultValue>False</LinkOptionOptimizeSameCode-DefaultValue>
+      <PostBuildCommands-DefaultValue />
+      <AsmOptionListFile-DefaultValue>False</AsmOptionListFile-DefaultValue>
+      <COptionGoptimize-DefaultValue>False</COptionGoptimize-DefaultValue>
+      <GeneralOptionDenormalize-DefaultValue>Off</GeneralOptionDenormalize-DefaultValue>
+      <LinkOptionSameSize-DefaultValue>1E</LinkOptionSameSize-DefaultValue>
+      <AsmOptionShowConditionals-DefaultValue>False</AsmOptionShowConditionals-DefaultValue>
+      <COptionSpeedAndSize-DefaultValue>Size</COptionSpeedAndSize-DefaultValue>
+      <GeneralOptionDblSize-DefaultValue>SinglePrecision</GeneralOptionDblSize-DefaultValue>
+      <LinkOptionOptimizeShortFormat-DefaultValue>False</LinkOptionOptimizeShortFormat-DefaultValue>
+      <AsmOptionShowDefinitions-DefaultValue>False</AsmOptionShowDefinitions-DefaultValue>
+      <COptionListfile-DefaultValue>False</COptionListfile-DefaultValue>
+      <GeneralOptionIntToShort-DefaultValue>False</GeneralOptionIntToShort-DefaultValue>
+      <LinkOptionOptimizeBranch-DefaultValue>False</LinkOptionOptimizeBranch-DefaultValue>
+      <AsmOptionShowExpansions-DefaultValue>False</AsmOptionShowExpansions-DefaultValue>
+      <COptionShowSource-DefaultValue>False</COptionShowSource-DefaultValue>
+      <GeneralOptionSignedChar-DefaultValue>Unsigned</GeneralOptionSignedChar-DefaultValue>
+      <LinkOptionStart-DefaultValue />
+      <COptionShowConditionals-DefaultValue>False</COptionShowConditionals-DefaultValue>
+      <GeneralOptionOtherAdditionalOptions-DefaultValue />
+      <GeneralOptionSignedBitfield-DefaultValue>Unsigned</GeneralOptionSignedBitfield-DefaultValue>
+      <COptionShowDefinitions-DefaultValue>False</COptionShowDefinitions-DefaultValue>
+      <GeneralOptionAutoEnum-DefaultValue>False</GeneralOptionAutoEnum-DefaultValue>
+      <COptionShowExpansions-DefaultValue>False</COptionShowExpansions-DefaultValue>
+      <GeneralOptionBitOrder-DefaultValue>Right</GeneralOptionBitOrder-DefaultValue>
+      <GeneralOptionPack-DefaultValue>False</GeneralOptionPack-DefaultValue>
+      <GeneralOptionException-DefaultValue>False</GeneralOptionException-DefaultValue>
+      <GeneralOptionRtti-DefaultValue>False</GeneralOptionRtti-DefaultValue>
+      <GeneralOptionFintRegister-DefaultValue>None</GeneralOptionFintRegister-DefaultValue>
+      <GeneralOptionBranch-DefaultValue>Branch24</GeneralOptionBranch-DefaultValue>
+      <GeneralOptionBaseRomRegister-DefaultValue>None</GeneralOptionBaseRomRegister-DefaultValue>
+      <GeneralOptionBaseRamRegister-DefaultValue>None</GeneralOptionBaseRamRegister-DefaultValue>
+      <GeneralOptionBaseAddressAddress-DefaultValue>00000000</GeneralOptionBaseAddressAddress-DefaultValue>
+      <GeneralOptionBaseAddressRegister-DefaultValue>None</GeneralOptionBaseAddressRegister-DefaultValue>
+      <GeneralOptionPatch-DefaultValue>None</GeneralOptionPatch-DefaultValue>
+      <GeneralOptionSaveAcc-DefaultValue>False</GeneralOptionSaveAcc-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587442585982635989</TimeTagModified--0>
+      <BuildMode-0>DefaultBuild</BuildMode-0>
+      <Memo-0 />
+      <OutputMessageFormat-0>%TargetFiles%</OutputMessageFormat-0>
+      <FormatBuildOptionList-0>%TargetFiles% : %Program% %Options%</FormatBuildOptionList-0>
+      <PreBuildCommands-0 />
+      <PostBuildCommands-0 />
+      <GeneralOptionIsa-0>RXv1</GeneralOptionIsa-0>
+      <GeneralOptionOutput-0>LibraryFile</GeneralOptionOutput-0>
+      <GeneralOptionPic-0>False</GeneralOptionPic-0>
+      <GeneralOptionSimultaneousBuild-0>True</GeneralOptionSimultaneousBuild-0>
+      <CompilerVersion-0>
+
+0</CompilerVersion-0>
+      <DependencyFileExistCheckingType-0>Rebuild</DependencyFileExistCheckingType-0>
+      <GeneralOptionCpu-0>RX600</GeneralOptionCpu-0>
+      <GeneralOptionOutputFolder-0>%BuildModeName%</GeneralOptionOutputFolder-0>
+      <GeneralOptionPid-0>None</GeneralOptionPid-0>
+      <EnsureCompatibilityOfPathAndLinkageOrder-0>False</EnsureCompatibilityOfPathAndLinkageOrder-0>
+      <GeneralOptionFpu-0>Fpu</GeneralOptionFpu-0>
+      <GeneralOptionNousePidRegister-0>True</GeneralOptionNousePidRegister-0>
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <GeneralOptionEndian-0>Little</GeneralOptionEndian-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <AsmOptionGoptimize-0>False</AsmOptionGoptimize-0>
+      <GeneralOptionRound-0>Nearest</GeneralOptionRound-0>
+      <LinkOptionMultiConvertFileName-0 />
+      <AsmOptionListFile-0>False</AsmOptionListFile-0>
+      <COptionGoptimize-0>False</COptionGoptimize-0>
+      <GeneralOptionDenormalize-0>Off</GeneralOptionDenormalize-0>
+      <AsmOptionShowConditionals-0>False</AsmOptionShowConditionals-0>
+      <GeneralOptionDblSize-0>SinglePrecision</GeneralOptionDblSize-0>
+      <AsmOptionShowDefinitions-0>False</AsmOptionShowDefinitions-0>
+      <COptionListfile-0>False</COptionListfile-0>
+      <GeneralOptionIntToShort-0>False</GeneralOptionIntToShort-0>
+      <AsmOptionShowExpansions-0>False</AsmOptionShowExpansions-0>
+      <COptionShowSource-0>False</COptionShowSource-0>
+      <GeneralOptionSignedChar-0>Unsigned</GeneralOptionSignedChar-0>
+      <COptionShowConditionals-0>False</COptionShowConditionals-0>
+      <GeneralOptionOtherAdditionalOptions-0 />
+      <GeneralOptionSignedBitfield-0>Unsigned</GeneralOptionSignedBitfield-0>
+      <COptionShowDefinitions-0>False</COptionShowDefinitions-0>
+      <GeneralOptionAutoEnum-0>False</GeneralOptionAutoEnum-0>
+      <COptionShowExpansions-0>False</COptionShowExpansions-0>
+      <GeneralOptionBitOrder-0>Right</GeneralOptionBitOrder-0>
+      <GeneralOptionPack-0>False</GeneralOptionPack-0>
+      <GeneralOptionException-0>False</GeneralOptionException-0>
+      <GeneralOptionRtti-0>False</GeneralOptionRtti-0>
+      <GeneralOptionFintRegister-0>None</GeneralOptionFintRegister-0>
+      <GeneralOptionBranch-0>Branch24</GeneralOptionBranch-0>
+      <GeneralOptionBaseRomRegister-0>None</GeneralOptionBaseRomRegister-0>
+      <GeneralOptionBaseRamRegister-0>None</GeneralOptionBaseRamRegister-0>
+      <GeneralOptionBaseAddressAddress-0>00000000</GeneralOptionBaseAddressAddress-0>
+      <GeneralOptionBaseAddressRegister-0>None</GeneralOptionBaseAddressRegister-0>
+      <GeneralOptionPatch-0>None</GeneralOptionPatch-0>
+      <GeneralOptionSaveAcc-0>False</GeneralOptionSaveAcc-0>
+      <LastCompilerVersion-0>V2.02.00</LastCompilerVersion-0>
+    </Instance>
+    <Instance Guid="95a63257-4aa7-40c0-a74a-7991543b099b">
+      <COptionLangC-DefaultValue>C</COptionLangC-DefaultValue>
+      <COptionListfile-DefaultValue>False</COptionListfile-DefaultValue>
+      <COptionLogo-DefaultValue>False</COptionLogo-DefaultValue>
+      <COptionMisra2004-DefaultValue>None</COptionMisra2004-DefaultValue>
+      <COptionOptimize-DefaultValue>Level2</COptionOptimize-DefaultValue>
+      <COptionOutput-DefaultValue>Object</COptionOutput-DefaultValue>
+      <COptionOutputAssembly-DefaultValue>False</COptionOutputAssembly-DefaultValue>
+      <COptionGoptimize-DefaultValue>False</COptionGoptimize-DefaultValue>
+      <COptionLangCpp-DefaultValue>Cpp</COptionLangCpp-DefaultValue>
+      <COptionMisra2004RuleFile-DefaultValue />
+      <COptionOutputFolder-DefaultValue>%BuildModeName%</COptionOutputFolder-DefaultValue>
+      <COptionOutputPreprocessed-DefaultValue>None</COptionOutputPreprocessed-DefaultValue>
+      <COptionShowSource-DefaultValue>False</COptionShowSource-DefaultValue>
+      <COptionXcref-DefaultValue>False</COptionXcref-DefaultValue>
+      <COptionDebug-DefaultValue>True</COptionDebug-DefaultValue>
+      <COptionInclude-DefaultValue />
+      <COptionMisra2004RuleNumberApply-DefaultValue />
+      <COptionPreCompileCommands-DefaultValue />
+      <COptionShowConditionals-DefaultValue>False</COptionShowConditionals-DefaultValue>
+      <COptionSpeedAndSize-DefaultValue>Size</COptionSpeedAndSize-DefaultValue>
+      <COptionLoop-DefaultValue>Auto</COptionLoop-DefaultValue>
+      <COptionMisra2004RuleNumberIgnore-DefaultValue />
+      <COptionPostCompileCommands-DefaultValue />
+      <COptionSectionP-DefaultValue>P</COptionSectionP-DefaultValue>
+      <COptionShowDefinitions-DefaultValue>False</COptionShowDefinitions-DefaultValue>
+      <COptionSystemInclude-DefaultValue />
+      <COptionLoopValue-DefaultValue>2</COptionLoopValue-DefaultValue>
+      <COptionMisra2004RuleNumberRequiredAdd-DefaultValue />
+      <COptionOtherAdditionalOptions-DefaultValue />
+      <COptionPreinclude-DefaultValue />
+      <COptionSectionC-DefaultValue>C</COptionSectionC-DefaultValue>
+      <COptionShowExpansions-DefaultValue>False</COptionShowExpansions-DefaultValue>
+      <COptionCommandLine-DefaultValue>-isa=rxv1
+-fpu
+-include=..\..\curl-7.47.1\include
+-include=..\..\curl-7.47.1\lib
+-include=..\..\wolfssl-3.7.0
+-include=..\..\wolfssl-3.7.0\wolfssl
+-include=..\..\lwip-1.4.1\src\include
+-include=..\..\lwip-1.4.1\src\include\ipv4
+-include=..\..\asp_dcre\include
+-include=..\..\asp_dcre\arch
+-include=..\..\asp_dcre\target\grsakura_ccrx
+-include=..\..\fatfs
+-include=..\..\src\usb_watt_meter
+-include=..\..\lwip-1.4.1\ports\asp_dcre
+-include=..\..\lwip-1.4.1\ports\ccrx
+-include=..\..\lwip-1.4.1\ports\grsakura
+-include=.
+-define=HAVE_CONFIG_H
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</COptionCommandLine-DefaultValue>
+      <COptionDefine-DefaultValue />
+      <COptionInline-DefaultValue>Auto</COptionInline-DefaultValue>
+      <COptionMisra2004RuleNumberRequiredRemove-DefaultValue />
+      <COptionSectionD-DefaultValue>D</COptionSectionD-DefaultValue>
+      <COptionIgnoreFilesMisra-DefaultValue />
+      <COptionInlineValue-DefaultValue>100</COptionInlineValue-DefaultValue>
+      <COptionSectionB-DefaultValue>B</COptionSectionB-DefaultValue>
+      <COptionUndefine-DefaultValue />
+      <COptionCheckLanguageExtension-DefaultValue>False</COptionCheckLanguageExtension-DefaultValue>
+      <COptionFileInline-DefaultValue />
+      <COptionMessage-DefaultValue>False</COptionMessage-DefaultValue>
+      <COptionSectionL-DefaultValue>L</COptionSectionL-DefaultValue>
+      <COptionCase-DefaultValue>Auto</COptionCase-DefaultValue>
+      <COptionMessage2-DefaultValue>False</COptionMessage2-DefaultValue>
+      <COptionSectionW-DefaultValue>W</COptionSectionW-DefaultValue>
+      <COptionNoMessageErrorNumber-DefaultValue />
+      <COptionNostuffB-DefaultValue>False</COptionNostuffB-DefaultValue>
+      <COptionVolatile-DefaultValue>False</COptionVolatile-DefaultValue>
+      <COptionConstCopy-DefaultValue>Auto</COptionConstCopy-DefaultValue>
+      <COptionNoMessageErrorNumber2-DefaultValue />
+      <COptionNostuffD-DefaultValue>False</COptionNostuffD-DefaultValue>
+      <COptionChangeMessageInformation-DefaultValue>No</COptionChangeMessageInformation-DefaultValue>
+      <COptionConstDiv-DefaultValue>Auto</COptionConstDiv-DefaultValue>
+      <COptionNostuffC-DefaultValue>False</COptionNostuffC-DefaultValue>
+      <COptionChangeMessageInformationNumber-DefaultValue />
+      <COptionLibrary-DefaultValue>Intrinsic</COptionLibrary-DefaultValue>
+      <COptionNostuffW-DefaultValue>False</COptionNostuffW-DefaultValue>
+      <COptionChangeMessageInformationNumber2-DefaultValue />
+      <COptionInstalign-DefaultValue>Noinstalign</COptionInstalign-DefaultValue>
+      <COptionScope-DefaultValue>Auto</COptionScope-DefaultValue>
+      <COptionChangeMessageWarning-DefaultValue>No</COptionChangeMessageWarning-DefaultValue>
+      <COptionNouseDiv-DefaultValue>True</COptionNouseDiv-DefaultValue>
+      <COptionSchedule-DefaultValue>Auto</COptionSchedule-DefaultValue>
+      <COptionChangeMessageWarningNumber-DefaultValue />
+      <COptionMap-DefaultValue>NoMap</COptionMap-DefaultValue>
+      <COptionOutcode-DefaultValue>Sjis</COptionOutcode-DefaultValue>
+      <COptionChangeMessageWarningNumber2-DefaultValue />
+      <COptionIntermodule-DefaultValue>None</COptionIntermodule-DefaultValue>
+      <COptionApproxdiv-DefaultValue>False</COptionApproxdiv-DefaultValue>
+      <COptionChangeMessageError-DefaultValue>No</COptionChangeMessageError-DefaultValue>
+      <COptionChangeMessageErrorNumber-DefaultValue />
+      <COptionEnableRegister-DefaultValue>False</COptionEnableRegister-DefaultValue>
+      <COptionChangeMessageErrorNumber2-DefaultValue />
+      <COptionSimpleFloatConv-DefaultValue>False</COptionSimpleFloatConv-DefaultValue>
+      <COptionFileInlinePath-DefaultValue />
+      <COptionFpu-DefaultValue>Fpu</COptionFpu-DefaultValue>
+      <COptionAlias-DefaultValue>False</COptionAlias-DefaultValue>
+      <COptionComment-DefaultValue>False</COptionComment-DefaultValue>
+      <COptionCheck-DefaultValue>No</COptionCheck-DefaultValue>
+      <COptionFloatOrder-DefaultValue>False</COptionFloatOrder-DefaultValue>
+      <COptionIncode-DefaultValue>Sjis</COptionIncode-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587459028127937007</TimeTagModified--0>
+      <COptionLangC-0>C99</COptionLangC-0>
+      <COptionListfile-0>False</COptionListfile-0>
+      <COptionLogo-0>False</COptionLogo-0>
+      <COptionMisra2004-0>None</COptionMisra2004-0>
+      <COptionOptimize-0>Level2</COptionOptimize-0>
+      <COptionOutput-0>Object</COptionOutput-0>
+      <COptionOutputAssembly-0>False</COptionOutputAssembly-0>
+      <COptionGoptimize-0>False</COptionGoptimize-0>
+      <COptionLangCpp-0>Cpp</COptionLangCpp-0>
+      <COptionMisra2004RuleFile-0 />
+      <COptionOutputFolder-0>%BuildModeName%</COptionOutputFolder-0>
+      <COptionOutputPreprocessed-0>None</COptionOutputPreprocessed-0>
+      <COptionShowSource-0>False</COptionShowSource-0>
+      <COptionXcref-0>False</COptionXcref-0>
+      <COptionDebug-0>True</COptionDebug-0>
+      <COptionInclude-0>..\..\curl-7.47.1\include
+..\..\curl-7.47.1\lib
+..\..\wolfssl-3.7.0
+..\..\wolfssl-3.7.0\wolfssl
+..\..\lwip-1.4.1\src\include
+..\..\lwip-1.4.1\src\include\ipv4
+..\..\asp_dcre\include
+..\..\asp_dcre\arch
+..\..\asp_dcre\target\grsakura_ccrx
+..\..\fatfs
+..\..\src\usb_watt_meter
+..\..\lwip-1.4.1\ports\asp_dcre
+..\..\lwip-1.4.1\ports\ccrx
+..\..\lwip-1.4.1\ports\grsakura
+.
+</COptionInclude-0>
+      <COptionMisra2004RuleNumberApply-0 />
+      <COptionPreCompileCommands-0 />
+      <COptionShowConditionals-0>False</COptionShowConditionals-0>
+      <COptionSpeedAndSize-0>Size</COptionSpeedAndSize-0>
+      <COptionLoop-0>Auto</COptionLoop-0>
+      <COptionMisra2004RuleNumberIgnore-0 />
+      <COptionPostCompileCommands-0 />
+      <COptionSectionP-0>P</COptionSectionP-0>
+      <COptionShowDefinitions-0>False</COptionShowDefinitions-0>
+      <COptionSystemInclude-0 />
+      <COptionLoopValue-0>2</COptionLoopValue-0>
+      <COptionMisra2004RuleNumberRequiredAdd-0 />
+      <COptionOtherAdditionalOptions-0 />
+      <COptionPreinclude-0 />
+      <COptionSectionC-0>C</COptionSectionC-0>
+      <COptionShowExpansions-0>False</COptionShowExpansions-0>
+      <COptionCommandLine-0>-isa=rxv1
+-fpu
+-include=..\..\curl-7.47.1\include
+-include=..\..\curl-7.47.1\lib
+-include=..\..\wolfssl-3.7.0
+-include=..\..\wolfssl-3.7.0\wolfssl
+-include=..\..\lwip-1.4.1\src\include
+-include=..\..\lwip-1.4.1\src\include\ipv4
+-include=..\..\asp_dcre\include
+-include=..\..\asp_dcre\arch
+-include=..\..\asp_dcre\target\grsakura_ccrx
+-include=..\..\fatfs
+-include=..\..\src\usb_watt_meter
+-include=..\..\lwip-1.4.1\ports\asp_dcre
+-include=..\..\lwip-1.4.1\ports\ccrx
+-include=..\..\lwip-1.4.1\ports\grsakura
+-include=.
+-define=HAVE_CONFIG_H
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</COptionCommandLine-0>
+      <COptionDefine-0>HAVE_CONFIG_H
+</COptionDefine-0>
+      <COptionInline-0>Auto</COptionInline-0>
+      <COptionMisra2004RuleNumberRequiredRemove-0 />
+      <COptionSectionD-0>D</COptionSectionD-0>
+      <COptionIgnoreFilesMisra-0 />
+      <COptionInlineValue-0>100</COptionInlineValue-0>
+      <COptionSectionB-0>B</COptionSectionB-0>
+      <COptionUndefine-0 />
+      <COptionCheckLanguageExtension-0>False</COptionCheckLanguageExtension-0>
+      <COptionFileInline-0 />
+      <COptionMessage-0>False</COptionMessage-0>
+      <COptionSectionL-0>L</COptionSectionL-0>
+      <COptionCase-0>Auto</COptionCase-0>
+      <COptionSectionW-0>W</COptionSectionW-0>
+      <COptionNoMessageErrorNumber-0 />
+      <COptionNostuffB-0>False</COptionNostuffB-0>
+      <COptionVolatile-0>False</COptionVolatile-0>
+      <COptionConstCopy-0>Auto</COptionConstCopy-0>
+      <COptionNostuffD-0>False</COptionNostuffD-0>
+      <COptionChangeMessageInformation-0>No</COptionChangeMessageInformation-0>
+      <COptionConstDiv-0>Auto</COptionConstDiv-0>
+      <COptionNostuffC-0>False</COptionNostuffC-0>
+      <COptionChangeMessageInformationNumber-0 />
+      <COptionLibrary-0>Intrinsic</COptionLibrary-0>
+      <COptionNostuffW-0>False</COptionNostuffW-0>
+      <COptionInstalign-0>Noinstalign</COptionInstalign-0>
+      <COptionScope-0>Auto</COptionScope-0>
+      <COptionChangeMessageWarning-0>No</COptionChangeMessageWarning-0>
+      <COptionNouseDiv-0>True</COptionNouseDiv-0>
+      <COptionSchedule-0>Auto</COptionSchedule-0>
+      <COptionChangeMessageWarningNumber-0 />
+      <COptionMap-0>NoMap</COptionMap-0>
+      <COptionOutcode-0>Sjis</COptionOutcode-0>
+      <COptionIntermodule-0>None</COptionIntermodule-0>
+      <COptionApproxdiv-0>False</COptionApproxdiv-0>
+      <COptionChangeMessageError-0>No</COptionChangeMessageError-0>
+      <COptionChangeMessageErrorNumber-0 />
+      <COptionEnableRegister-0>False</COptionEnableRegister-0>
+      <COptionSimpleFloatConv-0>False</COptionSimpleFloatConv-0>
+      <COptionFileInlinePath-0 />
+      <COptionFpu-0>Fpu</COptionFpu-0>
+      <COptionAlias-0>False</COptionAlias-0>
+      <COptionComment-0>False</COptionComment-0>
+      <COptionCheck-0>No</COptionCheck-0>
+      <COptionFloatOrder-0>False</COptionFloatOrder-0>
+      <COptionIncode-0>Sjis</COptionIncode-0>
+    </Instance>
+    <Instance Guid="5ad1746c-d03e-4610-a91f-aaa4fb37bc10">
+      <AsmOptionChkpm-DefaultValue>False</AsmOptionChkpm-DefaultValue>
+      <AsmOptionGoptimize-DefaultValue>False</AsmOptionGoptimize-DefaultValue>
+      <AsmOptionInclude-DefaultValue />
+      <AsmOptionListFile-DefaultValue>False</AsmOptionListFile-DefaultValue>
+      <AsmOptionOutput-DefaultValue>%BuildModeName%</AsmOptionOutput-DefaultValue>
+      <AsmOptionChkfpu-DefaultValue>False</AsmOptionChkfpu-DefaultValue>
+      <AsmOptionDebug-DefaultValue>True</AsmOptionDebug-DefaultValue>
+      <AsmOptionShowConditionals-DefaultValue>False</AsmOptionShowConditionals-DefaultValue>
+      <AsmOptionSystemInclude-DefaultValue />
+      <AsmOptionChkdsp-DefaultValue>False</AsmOptionChkdsp-DefaultValue>
+      <AsmOptionDefine-DefaultValue />
+      <AsmOptionShowDefinitions-DefaultValue>False</AsmOptionShowDefinitions-DefaultValue>
+      <AsmOptionInCode-DefaultValue>SJIS</AsmOptionInCode-DefaultValue>
+      <AsmOptionLogo-DefaultValue>False</AsmOptionLogo-DefaultValue>
+      <AsmOptionShowExpansions-DefaultValue>False</AsmOptionShowExpansions-DefaultValue>
+      <AsmOptionPreAssembleCommands-DefaultValue />
+      <AsmOptionPostAssembleCommands-DefaultValue />
+      <AsmOptionOtherAdditionalOptions-DefaultValue />
+      <AsmOptionCommandLine-DefaultValue />
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587466605916905885</TimeTagModified--0>
+      <AsmOptionChkpm-0>False</AsmOptionChkpm-0>
+      <AsmOptionGoptimize-0>False</AsmOptionGoptimize-0>
+      <AsmOptionInclude-0 />
+      <AsmOptionListFile-0>False</AsmOptionListFile-0>
+      <AsmOptionOutput-0>%BuildModeName%</AsmOptionOutput-0>
+      <AsmOptionChkfpu-0>False</AsmOptionChkfpu-0>
+      <AsmOptionDebug-0>True</AsmOptionDebug-0>
+      <AsmOptionShowConditionals-0>False</AsmOptionShowConditionals-0>
+      <AsmOptionSystemInclude-0 />
+      <AsmOptionChkdsp-0>False</AsmOptionChkdsp-0>
+      <AsmOptionDefine-0 />
+      <AsmOptionShowDefinitions-0>False</AsmOptionShowDefinitions-0>
+      <AsmOptionInCode-0>SJIS</AsmOptionInCode-0>
+      <AsmOptionLogo-0>False</AsmOptionLogo-0>
+      <AsmOptionShowExpansions-0>False</AsmOptionShowExpansions-0>
+      <AsmOptionPreAssembleCommands-0 />
+      <AsmOptionPostAssembleCommands-0 />
+      <AsmOptionOtherAdditionalOptions-0 />
+      <AsmOptionCommandLine-0 />
+    </Instance>
+    <Instance Guid="dbb16727-3e81-4169-956a-790355cab4a1">
+      <LinkOptionCpu-DefaultValue>False</LinkOptionCpu-DefaultValue>
+      <LinkOptionForm-DefaultValue>Absolute</LinkOptionForm-DefaultValue>
+      <LinkOptionFormConvert-DefaultValue>Stype</LinkOptionFormConvert-DefaultValue>
+      <LinkOptionInput-DefaultValue />
+      <LinkOptionListShow-DefaultValue>None</LinkOptionListShow-DefaultValue>
+      <LinkOptionOptimize-DefaultValue>None</LinkOptionOptimize-DefaultValue>
+      <LinkOptionStack-DefaultValue>False</LinkOptionStack-DefaultValue>
+      <LinkOptionStart-DefaultValue />
+      <LinkOptionCompress-DefaultValue>False</LinkOptionCompress-DefaultValue>
+      <LinkOptionCpuInformation-DefaultValue />
+      <LinkOptionDebug-DefaultValue>Debug</LinkOptionDebug-DefaultValue>
+      <LinkOptionFSymbol-DefaultValue />
+      <LinkOptionLibrary-DefaultValue />
+      <LinkOptionOptimizeSymbolDelete-DefaultValue>False</LinkOptionOptimizeSymbolDelete-DefaultValue>
+      <LinkOptionRecordH-DefaultValue>None</LinkOptionRecordH-DefaultValue>
+      <LinkOptionShowSymbol-DefaultValue>False</LinkOptionShowSymbol-DefaultValue>
+      <LinkOptionAlignedSection-DefaultValue />
+      <LinkOptionCpuStride-DefaultValue>False</LinkOptionCpuStride-DefaultValue>
+      <LinkOptionMemory-DefaultValue>False</LinkOptionMemory-DefaultValue>
+      <LinkOptionOptimizeSameCode-DefaultValue>False</LinkOptionOptimizeSameCode-DefaultValue>
+      <LinkOptionOutputFolder-DefaultValue>%BuildModeName%</LinkOptionOutputFolder-DefaultValue>
+      <LinkOptionRecordS-DefaultValue>None</LinkOptionRecordS-DefaultValue>
+      <LinkOptionShowReference-DefaultValue>False</LinkOptionShowReference-DefaultValue>
+      <LinkOptionSystemLibrary-DefaultValue />
+      <LinkOptionBinary-DefaultValue />
+      <LinkOptionChangeMessageInformation-DefaultValue>None</LinkOptionChangeMessageInformation-DefaultValue>
+      <LinkOptionContiguousSection-DefaultValue />
+      <LinkOptionDividedConvertFile-DefaultValue>False</LinkOptionDividedConvertFile-DefaultValue>
+      <LinkOptionOutputFileName-DefaultValue>%ProjectName%.abs</LinkOptionOutputFileName-DefaultValue>
+      <LinkOptionRom-DefaultValue />
+      <LinkOptionSameSize-DefaultValue>1E</LinkOptionSameSize-DefaultValue>
+      <LinkOptionShowXreference-DefaultValue>False</LinkOptionShowXreference-DefaultValue>
+      <LinkOptionChangeMessageInformationNumber-DefaultValue />
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionDefine-DefaultValue />
+      <LinkOptionMap-DefaultValue>False</LinkOptionMap-DefaultValue>
+      <LinkOptionOptimizeShortFormat-DefaultValue>False</LinkOptionOptimizeShortFormat-DefaultValue>
+      <LinkOptionShowTotalSize-DefaultValue>False</LinkOptionShowTotalSize-DefaultValue>
+      <LinkOptionChangeMessageWarning-DefaultValue>None</LinkOptionChangeMessageWarning-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionEntry-DefaultValue>False</LinkOptionEntry-DefaultValue>
+      <LinkOptionMessage-DefaultValue>NoMessage</LinkOptionMessage-DefaultValue>
+      <LinkOptionOptimizeBranch-DefaultValue>False</LinkOptionOptimizeBranch-DefaultValue>
+      <LinkOptionShowVector-DefaultValue>False</LinkOptionShowVector-DefaultValue>
+      <LinkOptionChangeMessageWarningNumber-DefaultValue />
+      <LinkOptionEntryPoint-DefaultValue />
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionNoMessageErrorNumber-DefaultValue />
+      <LinkOptionSymbolForbid-DefaultValue />
+      <LinkOptionChangeMessageError-DefaultValue>None</LinkOptionChangeMessageError-DefaultValue>
+      <LinkOptionNoPrelink-DefaultValue>Auto</LinkOptionNoPrelink-DefaultValue>
+      <LinkOptionPadding-DefaultValue>False</LinkOptionPadding-DefaultValue>
+      <LinkOptionSameCodeForbid-DefaultValue />
+      <LinkOptionSpace-DefaultValue>None</LinkOptionSpace-DefaultValue>
+      <LinkOptionChangeMessageErrorNumber-DefaultValue />
+      <LinkOptionSectionForbid-DefaultValue />
+      <LinkOptionSpaceValue-DefaultValue>FF</LinkOptionSpaceValue-DefaultValue>
+      <LinkOptionVectN-DefaultValue />
+      <LinkOptionAbsoluteForbid-DefaultValue />
+      <LinkOptionByteCount-DefaultValue>False</LinkOptionByteCount-DefaultValue>
+      <LinkOptionHide-DefaultValue>False</LinkOptionHide-DefaultValue>
+      <LinkOptionVect-DefaultValue />
+      <LinkOptionByteCountValue-DefaultValue>FF</LinkOptionByteCountValue-DefaultValue>
+      <LinkOptionJumpEntriesForPic-DefaultValue>False</LinkOptionJumpEntriesForPic-DefaultValue>
+      <LinkOptionTotalSize-DefaultValue>False</LinkOptionTotalSize-DefaultValue>
+      <LinkOptionCrc-DefaultValue>None</LinkOptionCrc-DefaultValue>
+      <LinkOptionJumpEntriesForPicSectionName-DefaultValue />
+      <LinkOptionLogo-DefaultValue>False</LinkOptionLogo-DefaultValue>
+      <LinkOptionCrcOutputAddress-DefaultValue>0</LinkOptionCrcOutputAddress-DefaultValue>
+      <LinkOptionPreLinkCommands-DefaultValue />
+      <LinkOptionCrcCalculationRange-DefaultValue />
+      <LinkOptionPostLinkCommands-DefaultValue />
+      <LinkOptionOtherAdditionalOptionsForLoadModule-DefaultValue />
+      <LinkOptionS9-DefaultValue>False</LinkOptionS9-DefaultValue>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-DefaultValue />
+      <LinkOptionCommandLine-DefaultValue />
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587462011360995641</TimeTagModified--0>
+      <LinkOptionCpu-0>False</LinkOptionCpu-0>
+      <LinkOptionForm-0>Absolute</LinkOptionForm-0>
+      <LinkOptionFormConvert-0>Stype</LinkOptionFormConvert-0>
+      <LinkOptionInput-0 />
+      <LinkOptionListShow-0>None</LinkOptionListShow-0>
+      <LinkOptionOptimize-0>None</LinkOptionOptimize-0>
+      <LinkOptionStack-0>False</LinkOptionStack-0>
+      <LinkOptionStart-0 />
+      <LinkOptionCompress-0>False</LinkOptionCompress-0>
+      <LinkOptionCpuInformation-0 />
+      <LinkOptionDebug-0>Debug</LinkOptionDebug-0>
+      <LinkOptionFSymbol-0 />
+      <LinkOptionLibrary-0 />
+      <LinkOptionOptimizeSymbolDelete-0>False</LinkOptionOptimizeSymbolDelete-0>
+      <LinkOptionRecordH-0>None</LinkOptionRecordH-0>
+      <LinkOptionShowSymbol-0>False</LinkOptionShowSymbol-0>
+      <LinkOptionAlignedSection-0 />
+      <LinkOptionCpuStride-0>False</LinkOptionCpuStride-0>
+      <LinkOptionMemory-0>False</LinkOptionMemory-0>
+      <LinkOptionOptimizeSameCode-0>False</LinkOptionOptimizeSameCode-0>
+      <LinkOptionOutputFolder-0>%BuildModeName%</LinkOptionOutputFolder-0>
+      <LinkOptionRecordS-0>None</LinkOptionRecordS-0>
+      <LinkOptionShowReference-0>False</LinkOptionShowReference-0>
+      <LinkOptionSystemLibrary-0 />
+      <LinkOptionBinary-0 />
+      <LinkOptionChangeMessageInformation-0>None</LinkOptionChangeMessageInformation-0>
+      <LinkOptionContiguousSection-0 />
+      <LinkOptionDividedConvertFile-0>False</LinkOptionDividedConvertFile-0>
+      <LinkOptionOutputFileName-0>%ProjectName%.abs</LinkOptionOutputFileName-0>
+      <LinkOptionRom-0 />
+      <LinkOptionSameSize-0>1E</LinkOptionSameSize-0>
+      <LinkOptionShowXreference-0>False</LinkOptionShowXreference-0>
+      <LinkOptionChangeMessageInformationNumber-0 />
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <LinkOptionDefine-0 />
+      <LinkOptionMap-0>False</LinkOptionMap-0>
+      <LinkOptionOptimizeShortFormat-0>False</LinkOptionOptimizeShortFormat-0>
+      <LinkOptionShowTotalSize-0>False</LinkOptionShowTotalSize-0>
+      <LinkOptionChangeMessageWarning-0>None</LinkOptionChangeMessageWarning-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <LinkOptionEntry-0>False</LinkOptionEntry-0>
+      <LinkOptionMessage-0>NoMessage</LinkOptionMessage-0>
+      <LinkOptionOptimizeBranch-0>False</LinkOptionOptimizeBranch-0>
+      <LinkOptionShowVector-0>False</LinkOptionShowVector-0>
+      <LinkOptionChangeMessageWarningNumber-0 />
+      <LinkOptionEntryPoint-0 />
+      <LinkOptionMultiConvertFileName-0 />
+      <LinkOptionNoMessageErrorNumber-0 />
+      <LinkOptionSymbolForbid-0 />
+      <LinkOptionChangeMessageError-0>None</LinkOptionChangeMessageError-0>
+      <LinkOptionNoPrelink-0>Auto</LinkOptionNoPrelink-0>
+      <LinkOptionPadding-0>False</LinkOptionPadding-0>
+      <LinkOptionSameCodeForbid-0 />
+      <LinkOptionSpace-0>None</LinkOptionSpace-0>
+      <LinkOptionChangeMessageErrorNumber-0 />
+      <LinkOptionSectionForbid-0 />
+      <LinkOptionSpaceValue-0>FF</LinkOptionSpaceValue-0>
+      <LinkOptionVectN-0 />
+      <LinkOptionAbsoluteForbid-0 />
+      <LinkOptionByteCount-0>False</LinkOptionByteCount-0>
+      <LinkOptionHide-0>False</LinkOptionHide-0>
+      <LinkOptionVect-0 />
+      <LinkOptionByteCountValue-0>FF</LinkOptionByteCountValue-0>
+      <LinkOptionJumpEntriesForPic-0>False</LinkOptionJumpEntriesForPic-0>
+      <LinkOptionTotalSize-0>False</LinkOptionTotalSize-0>
+      <LinkOptionCrc-0>None</LinkOptionCrc-0>
+      <LinkOptionJumpEntriesForPicSectionName-0 />
+      <LinkOptionLogo-0>False</LinkOptionLogo-0>
+      <LinkOptionCrcOutputAddress-0>0</LinkOptionCrcOutputAddress-0>
+      <LinkOptionPreLinkCommands-0 />
+      <LinkOptionCrcCalculationRange-0 />
+      <LinkOptionPostLinkCommands-0 />
+      <LinkOptionOtherAdditionalOptionsForLoadModule-0 />
+      <LinkOptionS9-0>False</LinkOptionS9-0>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-0 />
+      <LinkOptionCommandLine-0 />
+    </Instance>
+    <Instance Guid="df74c69e-635e-42d9-845e-14128ba4d48a">
+      <HexOptionForm-DefaultValue>Stype</HexOptionForm-DefaultValue>
+      <HexOptionOutput-DefaultValue>True</HexOptionOutput-DefaultValue>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-DefaultValue />
+      <HexOptionCommandLine-DefaultValue />
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionRecordH-DefaultValue>None</LinkOptionRecordH-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionRecordS-DefaultValue>None</LinkOptionRecordS-DefaultValue>
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionSpace-DefaultValue>None</LinkOptionSpace-DefaultValue>
+      <LinkOptionSpaceValue-DefaultValue>FF</LinkOptionSpaceValue-DefaultValue>
+      <LinkOptionByteCount-DefaultValue>False</LinkOptionByteCount-DefaultValue>
+      <LinkOptionByteCountValue-DefaultValue>FF</LinkOptionByteCountValue-DefaultValue>
+      <LinkOptionCrc-DefaultValue>None</LinkOptionCrc-DefaultValue>
+      <LinkOptionCrcOutputAddress-DefaultValue>0</LinkOptionCrcOutputAddress-DefaultValue>
+      <LinkOptionCrcCalculationRange-DefaultValue />
+      <LinkOptionS9-DefaultValue>False</LinkOptionS9-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587466605916905885</TimeTagModified--0>
+      <HexOptionForm-0>Stype</HexOptionForm-0>
+      <HexOptionOutput-0>True</HexOptionOutput-0>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-0 />
+      <HexOptionCommandLine-0 />
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <LinkOptionRecordH-0>None</LinkOptionRecordH-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <LinkOptionRecordS-0>None</LinkOptionRecordS-0>
+      <LinkOptionMultiConvertFileName-0 />
+      <LinkOptionSpace-0>None</LinkOptionSpace-0>
+      <LinkOptionSpaceValue-0>FF</LinkOptionSpaceValue-0>
+      <LinkOptionByteCount-0>False</LinkOptionByteCount-0>
+      <LinkOptionByteCountValue-0>FF</LinkOptionByteCountValue-0>
+      <LinkOptionCrc-0>None</LinkOptionCrc-0>
+      <LinkOptionCrcOutputAddress-0>0</LinkOptionCrcOutputAddress-0>
+      <LinkOptionCrcCalculationRange-0 />
+      <LinkOptionS9-0>False</LinkOptionS9-0>
+    </Instance>
+    <Instance Guid="fff50d2e-74da-44ea-90a8-c47756029e83">
+      <LibOptionForm-DefaultValue>LibraryU</LibOptionForm-DefaultValue>
+      <LibOptionInput-DefaultValue />
+      <LibOptionListShow-DefaultValue>List</LibOptionListShow-DefaultValue>
+      <LibOptionMemory-DefaultValue>False</LibOptionMemory-DefaultValue>
+      <LibOptionChangeMessageInformation-DefaultValue>None</LibOptionChangeMessageInformation-DefaultValue>
+      <LibOptionDebug-DefaultValue>Debug</LibOptionDebug-DefaultValue>
+      <LibOptionLibrary-DefaultValue />
+      <LibOptionShowSymbol-DefaultValue>False</LibOptionShowSymbol-DefaultValue>
+      <LibOptionChangeMessageInformationNumber-DefaultValue />
+      <LibOptionOutputFolder-DefaultValue>%BuildModeName%</LibOptionOutputFolder-DefaultValue>
+      <LibOptionShowSection-DefaultValue>False</LibOptionShowSection-DefaultValue>
+      <LibOptionSystemLibrary-DefaultValue />
+      <LibOptionBinary-DefaultValue />
+      <LibOptionChangeMessageWarning-DefaultValue>None</LibOptionChangeMessageWarning-DefaultValue>
+      <LibOptionOutputFileName-DefaultValue>%ProjectName%.lib</LibOptionOutputFileName-DefaultValue>
+      <LibOptionShowXreference-DefaultValue>False</LibOptionShowXreference-DefaultValue>
+      <LibOptionChangeMessageWarningNumber-DefaultValue />
+      <LibOptionMessage-DefaultValue>NoMessage</LibOptionMessage-DefaultValue>
+      <LibOptionNoPrelink-DefaultValue>Auto</LibOptionNoPrelink-DefaultValue>
+      <LibOptionShowTotalSize-DefaultValue>False</LibOptionShowTotalSize-DefaultValue>
+      <LibOptionChangeMessageError-DefaultValue>None</LibOptionChangeMessageError-DefaultValue>
+      <LibOptionNoMessageErrorNumber-DefaultValue />
+      <LibOptionShowVector-DefaultValue>False</LibOptionShowVector-DefaultValue>
+      <LibOptionChangeMessageErrorNumber-DefaultValue />
+      <LibOptionHide-DefaultValue>False</LibOptionHide-DefaultValue>
+      <LibOptionTotalSize-DefaultValue>False</LibOptionTotalSize-DefaultValue>
+      <LibOptionLogo-DefaultValue>False</LibOptionLogo-DefaultValue>
+      <LibOptionPreLibrarianCommands-DefaultValue />
+      <LibOptionPostLibrarianCommands-DefaultValue />
+      <LibOptionOtherAdditionalOptions-DefaultValue />
+      <LibOptionCommandLine-DefaultValue />
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587462011360995641</TimeTagModified--0>
+      <LibOptionForm-0>LibraryU</LibOptionForm-0>
+      <LibOptionInput-0 />
+      <LibOptionListShow-0>List</LibOptionListShow-0>
+      <LibOptionMemory-0>False</LibOptionMemory-0>
+      <LibOptionChangeMessageInformation-0>None</LibOptionChangeMessageInformation-0>
+      <LibOptionDebug-0>Debug</LibOptionDebug-0>
+      <LibOptionLibrary-0 />
+      <LibOptionShowSymbol-0>False</LibOptionShowSymbol-0>
+      <LibOptionChangeMessageInformationNumber-0 />
+      <LibOptionOutputFolder-0>%BuildModeName%</LibOptionOutputFolder-0>
+      <LibOptionShowSection-0>False</LibOptionShowSection-0>
+      <LibOptionSystemLibrary-0 />
+      <LibOptionBinary-0 />
+      <LibOptionChangeMessageWarning-0>None</LibOptionChangeMessageWarning-0>
+      <LibOptionOutputFileName-0>%ProjectName%.lib</LibOptionOutputFileName-0>
+      <LibOptionShowXreference-0>False</LibOptionShowXreference-0>
+      <LibOptionChangeMessageWarningNumber-0 />
+      <LibOptionMessage-0>NoMessage</LibOptionMessage-0>
+      <LibOptionNoPrelink-0>Auto</LibOptionNoPrelink-0>
+      <LibOptionShowTotalSize-0>False</LibOptionShowTotalSize-0>
+      <LibOptionChangeMessageError-0>None</LibOptionChangeMessageError-0>
+      <LibOptionNoMessageErrorNumber-0 />
+      <LibOptionShowVector-0>False</LibOptionShowVector-0>
+      <LibOptionChangeMessageErrorNumber-0 />
+      <LibOptionHide-0>False</LibOptionHide-0>
+      <LibOptionTotalSize-0>False</LibOptionTotalSize-0>
+      <LibOptionLogo-0>False</LibOptionLogo-0>
+      <LibOptionPreLibrarianCommands-0 />
+      <LibOptionPostLibrarianCommands-0 />
+      <LibOptionOtherAdditionalOptions-0 />
+      <LibOptionCommandLine-0 />
+    </Instance>
+    <Instance Guid="9cb0ade0-b3cb-4e21-823c-290b5fdb5f1e">
+      <LbgOptionLanguage-DefaultValue>C</LbgOptionLanguage-DefaultValue>
+      <LbgOptionLibraryMode-DefaultValue>None</LbgOptionLibraryMode-DefaultValue>
+      <LbgOptionLogo-DefaultValue>False</LbgOptionLogo-DefaultValue>
+      <LbgOptionOptimize-DefaultValue>Level2</LbgOptionOptimize-DefaultValue>
+      <LbgOptionOutputFolder-DefaultValue>%BuildModeName%</LbgOptionOutputFolder-DefaultValue>
+      <LbgOptionGoptimize-DefaultValue>False</LbgOptionGoptimize-DefaultValue>
+      <LbgOptionHead-DefaultValue>Custom</LbgOptionHead-DefaultValue>
+      <LbgOptionOutputFileName-DefaultValue>%ProjectName%.lib</LbgOptionOutputFileName-DefaultValue>
+      <LbgOptionPreLibraryGenerateCommands-DefaultValue />
+      <LbgOptionFunctionalCutdown-DefaultValue>None</LbgOptionFunctionalCutdown-DefaultValue>
+      <LbgOptionHeadRuntime-DefaultValue>True</LbgOptionHeadRuntime-DefaultValue>
+      <LbgOptionPostLibraryGenerateCommands-DefaultValue />
+      <LbgOptionSpeedAndSize-DefaultValue>Size</LbgOptionSpeedAndSize-DefaultValue>
+      <LbgOptionHeadCtypeH-DefaultValue>False</LbgOptionHeadCtypeH-DefaultValue>
+      <LbgOptionLoop-DefaultValue>Auto</LbgOptionLoop-DefaultValue>
+      <LbgOptionOtherAdditionalOptions-DefaultValue />
+      <LbgOptionReent-DefaultValue>False</LbgOptionReent-DefaultValue>
+      <LbgOptionCommandLine-DefaultValue />
+      <LbgOptionHeadMathH-DefaultValue>False</LbgOptionHeadMathH-DefaultValue>
+      <LbgOptionLoopValue-DefaultValue>2</LbgOptionLoopValue-DefaultValue>
+      <LbgOptionSectionP-DefaultValue>P</LbgOptionSectionP-DefaultValue>
+      <LbgOptionHeadMathfH-DefaultValue>False</LbgOptionHeadMathfH-DefaultValue>
+      <LbgOptionInline-DefaultValue>Auto</LbgOptionInline-DefaultValue>
+      <LbgOptionSectionC-DefaultValue>C</LbgOptionSectionC-DefaultValue>
+      <LbgOptionHeadStdargH-DefaultValue>False</LbgOptionHeadStdargH-DefaultValue>
+      <LbgOptionInlineValue-DefaultValue>100</LbgOptionInlineValue-DefaultValue>
+      <LbgOptionSectionD-DefaultValue>D</LbgOptionSectionD-DefaultValue>
+      <LbgOptionFileInline-DefaultValue />
+      <LbgOptionHeadStdioH-DefaultValue>True</LbgOptionHeadStdioH-DefaultValue>
+      <LbgOptionSectionB-DefaultValue>B</LbgOptionSectionB-DefaultValue>
+      <LbgOptionCase-DefaultValue>Auto</LbgOptionCase-DefaultValue>
+      <LbgOptionHeadStdlibH-DefaultValue>True</LbgOptionHeadStdlibH-DefaultValue>
+      <LbgOptionSectionL-DefaultValue>L</LbgOptionSectionL-DefaultValue>
+      <LbgOptionHeadStringH-DefaultValue>True</LbgOptionHeadStringH-DefaultValue>
+      <LbgOptionSectionW-DefaultValue>W</LbgOptionSectionW-DefaultValue>
+      <LbgOptionVolatile-DefaultValue>False</LbgOptionVolatile-DefaultValue>
+      <LbgOptionConstCopy-DefaultValue>Auto</LbgOptionConstCopy-DefaultValue>
+      <LbgOptionHeadIos-DefaultValue>False</LbgOptionHeadIos-DefaultValue>
+      <LbgOptionNostuffB-DefaultValue>False</LbgOptionNostuffB-DefaultValue>
+      <LbgOptionConstDiv-DefaultValue>Auto</LbgOptionConstDiv-DefaultValue>
+      <LbgOptionHeadNew-DefaultValue>True</LbgOptionHeadNew-DefaultValue>
+      <LbgOptionNostuffD-DefaultValue>False</LbgOptionNostuffD-DefaultValue>
+      <LbgOptionHeadComplex-DefaultValue>False</LbgOptionHeadComplex-DefaultValue>
+      <LbgOptionLibrary-DefaultValue>Intrinsic</LbgOptionLibrary-DefaultValue>
+      <LbgOptionNostuffC-DefaultValue>False</LbgOptionNostuffC-DefaultValue>
+      <LbgOptionHeadString-DefaultValue>False</LbgOptionHeadString-DefaultValue>
+      <LbgOptionNostuffW-DefaultValue>False</LbgOptionNostuffW-DefaultValue>
+      <LbgOptionScope-DefaultValue>Auto</LbgOptionScope-DefaultValue>
+      <LbgOptionHeadComplexH-DefaultValue>False</LbgOptionHeadComplexH-DefaultValue>
+      <LbgOptionInstalign-DefaultValue>Noinstalign</LbgOptionInstalign-DefaultValue>
+      <LbgOptionSchedule-DefaultValue>Auto</LbgOptionSchedule-DefaultValue>
+      <LbgOptionApproxdiv-DefaultValue>False</LbgOptionApproxdiv-DefaultValue>
+      <LbgOptionHeadFenvH-DefaultValue>False</LbgOptionHeadFenvH-DefaultValue>
+      <LbgOptionNouseDiv-DefaultValue>True</LbgOptionNouseDiv-DefaultValue>
+      <LbgOptionEnableRegister-DefaultValue>False</LbgOptionEnableRegister-DefaultValue>
+      <LbgOptionHeadInttypesH-DefaultValue>False</LbgOptionHeadInttypesH-DefaultValue>
+      <LbgOptionHeadWcharH-DefaultValue>False</LbgOptionHeadWcharH-DefaultValue>
+      <LbgOptionSimpleFloatConv-DefaultValue>False</LbgOptionSimpleFloatConv-DefaultValue>
+      <LbgOptionFpu-DefaultValue>Fpu</LbgOptionFpu-DefaultValue>
+      <LbgOptionHeadWctypeH-DefaultValue>False</LbgOptionHeadWctypeH-DefaultValue>
+      <LbgOptionFloatOrder-DefaultValue>False</LbgOptionFloatOrder-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587466605916905885</TimeTagModified--0>
+      <LbgOptionLanguage-0>C</LbgOptionLanguage-0>
+      <LbgOptionLibraryMode-0>None</LbgOptionLibraryMode-0>
+      <LbgOptionLogo-0>False</LbgOptionLogo-0>
+      <LbgOptionOptimize-0>Level2</LbgOptionOptimize-0>
+      <LbgOptionOutputFolder-0>%BuildModeName%</LbgOptionOutputFolder-0>
+      <LbgOptionGoptimize-0>False</LbgOptionGoptimize-0>
+      <LbgOptionHead-0>Custom</LbgOptionHead-0>
+      <LbgOptionOutputFileName-0>%ProjectName%.lib</LbgOptionOutputFileName-0>
+      <LbgOptionPreLibraryGenerateCommands-0 />
+      <LbgOptionFunctionalCutdown-0>None</LbgOptionFunctionalCutdown-0>
+      <LbgOptionPostLibraryGenerateCommands-0 />
+      <LbgOptionSpeedAndSize-0>Size</LbgOptionSpeedAndSize-0>
+      <LbgOptionHeadCtypeH-0>False</LbgOptionHeadCtypeH-0>
+      <LbgOptionLoop-0>Auto</LbgOptionLoop-0>
+      <LbgOptionOtherAdditionalOptions-0 />
+      <LbgOptionReent-0>False</LbgOptionReent-0>
+      <LbgOptionCommandLine-0 />
+      <LbgOptionHeadMathH-0>False</LbgOptionHeadMathH-0>
+      <LbgOptionLoopValue-0>2</LbgOptionLoopValue-0>
+      <LbgOptionSectionP-0>P</LbgOptionSectionP-0>
+      <LbgOptionHeadMathfH-0>False</LbgOptionHeadMathfH-0>
+      <LbgOptionInline-0>Auto</LbgOptionInline-0>
+      <LbgOptionSectionC-0>C</LbgOptionSectionC-0>
+      <LbgOptionHeadStdargH-0>False</LbgOptionHeadStdargH-0>
+      <LbgOptionInlineValue-0>100</LbgOptionInlineValue-0>
+      <LbgOptionSectionD-0>D</LbgOptionSectionD-0>
+      <LbgOptionFileInline-0 />
+      <LbgOptionHeadStdioH-0>True</LbgOptionHeadStdioH-0>
+      <LbgOptionSectionB-0>B</LbgOptionSectionB-0>
+      <LbgOptionCase-0>Auto</LbgOptionCase-0>
+      <LbgOptionHeadStdlibH-0>True</LbgOptionHeadStdlibH-0>
+      <LbgOptionSectionL-0>L</LbgOptionSectionL-0>
+      <LbgOptionHeadStringH-0>True</LbgOptionHeadStringH-0>
+      <LbgOptionSectionW-0>W</LbgOptionSectionW-0>
+      <LbgOptionVolatile-0>False</LbgOptionVolatile-0>
+      <LbgOptionConstCopy-0>Auto</LbgOptionConstCopy-0>
+      <LbgOptionHeadIos-0>False</LbgOptionHeadIos-0>
+      <LbgOptionNostuffB-0>False</LbgOptionNostuffB-0>
+      <LbgOptionConstDiv-0>Auto</LbgOptionConstDiv-0>
+      <LbgOptionHeadNew-0>True</LbgOptionHeadNew-0>
+      <LbgOptionNostuffD-0>False</LbgOptionNostuffD-0>
+      <LbgOptionHeadComplex-0>False</LbgOptionHeadComplex-0>
+      <LbgOptionLibrary-0>Intrinsic</LbgOptionLibrary-0>
+      <LbgOptionNostuffC-0>False</LbgOptionNostuffC-0>
+      <LbgOptionHeadString-0>False</LbgOptionHeadString-0>
+      <LbgOptionNostuffW-0>False</LbgOptionNostuffW-0>
+      <LbgOptionScope-0>Auto</LbgOptionScope-0>
+      <LbgOptionHeadComplexH-0>False</LbgOptionHeadComplexH-0>
+      <LbgOptionInstalign-0>Noinstalign</LbgOptionInstalign-0>
+      <LbgOptionSchedule-0>Auto</LbgOptionSchedule-0>
+      <LbgOptionApproxdiv-0>False</LbgOptionApproxdiv-0>
+      <LbgOptionHeadFenvH-0>False</LbgOptionHeadFenvH-0>
+      <LbgOptionNouseDiv-0>True</LbgOptionNouseDiv-0>
+      <LbgOptionEnableRegister-0>False</LbgOptionEnableRegister-0>
+      <LbgOptionHeadInttypesH-0>False</LbgOptionHeadInttypesH-0>
+      <LbgOptionHeadWcharH-0>False</LbgOptionHeadWcharH-0>
+      <LbgOptionSimpleFloatConv-0>False</LbgOptionSimpleFloatConv-0>
+      <LbgOptionFpu-0>Fpu</LbgOptionFpu-0>
+      <LbgOptionHeadWctypeH-0>False</LbgOptionHeadWctypeH-0>
+      <LbgOptionFloatOrder-0>False</LbgOptionFloatOrder-0>
+    </Instance>
+    <Instance Guid="782acbe9-5cf7-4169-82be-0086cc92a94d">
+      <ItemAddTime>635905757263483472</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="1feacf8a-aca0-4c32-abbc-9ea634e59480">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f5345a6b-b651-4c4d-80fb-dc8e7701b4d3">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="180ad314-b1eb-44ae-b5a3-242c407f0fba">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>2</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="2576c0eb-e2bb-46f9-85f5-dc42e2e8bdaf">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>3</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="66a18d69-f281-4ede-b5bc-b5150110196a">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>4</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="749ab9cb-be85-4c3e-9c42-aa24e5bad9f7">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>5</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d3f28a38-4e81-4931-9e4f-dd279e18cb3d">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>6</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="c0423dfc-830f-4b19-ba87-79963909a3df">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>7</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="6579e164-1600-4ee9-82b1-f28b29ca034b">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>8</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="418365f9-2b8d-491e-ad6e-ba4838b71d54">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>9</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="3af94e22-91c2-4859-a9f1-ad7ba2e056d3">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>10</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="2db36ad4-004f-4d10-8823-aec4489d4473">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>11</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="6032b4b4-b29e-4278-a314-1a799ea842e4">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>12</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="84abe35a-d3f2-4e39-9c76-2a1d732a9280">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>13</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="eae21ebb-bf1f-4558-a8ca-c5bded683344">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>14</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="4cf957f4-ae3b-4c34-8675-f661bdef4806">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>15</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f5044f5d-88f9-4d00-b9b2-5f2af8cb7bfb">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>16</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="5de6660f-e7ad-45fe-9c8f-afd2793b4159">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>17</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="eaf993b2-1312-492e-9836-539071a8f9a8">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>18</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="e1672a92-ed4b-4a3d-a6d9-40948ebe0601">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>19</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="b4784de3-f972-41e2-b199-e64bea00c6a5">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>20</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="0bb29243-3950-4fb4-85ae-324d87937d87">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>21</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="c7b49799-272e-4869-a113-1f2f19bf0202">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>22</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="0b8aaf6c-7522-4a7e-a654-5c6127b28f03">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>23</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="1cd171c0-cb2d-4637-8f4b-3b54a575f643">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>24</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="0f5a1d35-4b00-4ce0-8531-0de2ab8a123f">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>25</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="9b9f3434-ec89-434b-99f7-a72314ca4250">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>26</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="790e3342-c173-444b-9e23-deccc2df0268">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>27</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d72867ed-199e-4141-800f-2fb92007032f">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>28</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="6c0f6d34-386f-4862-803f-e6e1cf18b0ca">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>29</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="b5bf059f-b56e-4d08-95da-0ee7f9450ec6">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>30</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f1c1cf0e-33e9-4e88-b75c-ed2c2150dfe4">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>31</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="741d7f88-85b9-4340-8415-d9023fc2a39b">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>32</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="ad988a0a-d5ff-4aca-af62-a0a9adc389ae">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>33</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="ee886e6a-6f57-42f1-9683-d4832059d2e6">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>34</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="74e8d9eb-3261-451f-a4fd-6001f760d396">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>35</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="1dc13d6a-4a24-43e5-a831-2b45d4ba243a">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>36</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a96a247f-1f65-47ad-855e-4c30e4864f97">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>37</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="3aa11eb9-3713-4cf8-9eca-ea0f62d8ffe5">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>38</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="8e1bdb7d-948b-41f7-bdcb-3d56eb4c9176">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>39</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="187a1d11-344f-46d7-9bc7-0b98b131e3fa">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>40</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="761de404-09b5-41f1-83d2-d24dfdfbb50c">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>41</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f9394348-e3a0-47d6-9522-43cacc254833">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>42</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a6a6466d-2a56-411e-8844-a4a1c1a48543">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>43</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="8601845c-95ac-413b-a98e-80d514767494">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>44</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="960b8aee-c6c0-4cb4-a314-63df4fef4961">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>45</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="8a90fd8f-f340-4005-8766-e7937cc6ffce">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>46</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="ccdecbd2-243c-42dd-9d48-4c276f116b01">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>47</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="b575786e-50db-4a62-841d-9627a67a0bbb">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>48</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="fdedefc7-53ca-4daa-9436-b5b46e5f6831">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>49</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="0a4b55dc-74ea-45d6-bd1b-e40c51bf8cd4">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>50</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="4cbb2de7-5dae-4a98-b09f-cc04c202f9fc">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>51</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f81e708a-b9a4-4f36-b84d-ce25fa843a43">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>52</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="b355e759-afe5-41b0-8f0a-8200762a9046">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>53</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="14844d6e-8941-4d29-bf85-29068c43aa94">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>54</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="b3ce2223-daf1-41bd-9244-28f3fa010100">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>55</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="de00ccf9-01d8-4539-92fb-42435617d3e7">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>56</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="9784dcda-a5ae-4d46-bbc6-4d063ca8c05d">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>57</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="9493d492-bbcb-4d60-9bd2-603cc4b24d29">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>58</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d2b2e7c1-fe24-4fca-8a95-ec7b9fb3b486">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>59</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="58f77449-e9c2-472d-b2f2-b03805e42759">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>60</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="5ab616a7-3ec1-423f-a135-eea134e78841">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>61</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="decc8864-8bc3-497d-9f3c-ed1b6954a857">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>62</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="8e058660-9748-4679-b381-ebc82081a7c5">
+      <ItemAddTime>635910360453903034</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="e40aab60-b084-4ff5-bbe8-523b25e406eb">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>64</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="866fe1e0-aca7-4944-bcf1-4e8d6bdf7e6a">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>65</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f5da104b-4f4b-4927-a9e5-a3a62a045a3a">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>66</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="e0e4588c-7de1-46cb-bcbb-b9d03b3a4af0">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>67</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="0761423f-604f-48fb-9f8b-ee9983366be7">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>68</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="0958d97f-eaa0-4d76-81f4-5eb8b244baf4">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>69</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="99f62c21-dff6-4469-a1e3-13187d02331f">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>70</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a6e94e0f-0849-4398-917c-e6a924cf48d6">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>71</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="6fac82ca-94f3-460d-bd7f-386bcbfc3615">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>72</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="b01b180b-ae9d-48fe-b22f-08230b40db8d">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>73</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="4291413c-a84b-4ce3-a709-751df9431e3a">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>74</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="9c576831-3da3-4869-a95d-b4e0aad35d16">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>75</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="503429a7-cbda-4825-8f0d-f3765f3ee76d">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>76</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="1dc2f041-6a23-4d35-b7a2-cfeb13e8eeb9">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>77</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="3fe81a7f-6260-4a68-a81f-1ef0ab5230c4">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>78</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="1cd05811-189c-4e24-920d-473ad0e5614c">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>79</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f34207af-343c-4c2d-985e-296cb065aa55">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>80</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="83149e99-e7ef-421b-9178-f72edab7748d">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>81</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="cd203796-7b11-4872-88ae-770eddf17923">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>82</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="22421e7d-6b65-4c26-bd0d-798637478d70">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>83</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="e6a72f5c-0021-4d25-9ccf-8ffddf5ce599">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>84</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="1cafe355-05a7-42a2-af9e-9f0ca0a90880">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>85</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="2a6aece1-4f1d-4ff6-9860-c493f4d27221">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>86</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a2b1bf35-fa87-4073-bb76-11c04892f28b">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>87</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a84d211f-e911-45c0-bd95-9648646a563d">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>88</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="95b231b9-0801-4245-925c-ed071c03ece2">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>89</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="20e8e714-a306-4b2c-95ee-eba59ededade">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>90</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="aaa983a3-61ac-4e97-9ec2-6146e40be0f0">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>91</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="41a5594a-edac-40ea-bb78-4f1e809d40d8">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>92</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="62a8d1f7-b124-48d7-b011-b68f614ec0d7">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>93</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="c0f047b1-97af-44c5-a10e-a9831d1c97ca">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>94</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="029c071f-a252-4b94-8445-0ec25919ed08">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>95</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d26ffb2e-8b0d-4fe4-9bf3-943ac85d8abc">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>96</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f7e60d17-dbc9-46d2-a666-45a8de4a6f2a">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>97</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="80daab28-c7a4-4c35-8802-5ed3c3654bfb">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>98</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="8c1e4bb7-0ced-4fce-a544-a9355e709c82">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>99</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d9d736c7-f4e0-4d87-9878-9ce85131fa4a">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>100</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="bdccac78-382d-43dc-95a1-29f20a922711">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>101</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="4cf04bad-3c0e-4648-b778-0a128863b82c">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>102</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f452e069-2666-4b40-9446-eb49151c2091">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>103</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a6d29305-cf6b-455c-8575-1a958b0277f2">
+      <ItemAddTime>635905757263583485</ItemAddTime>
+      <ItemAddTimeCount>104</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d1f3b4d1-e0e4-4617-a3f8-a31fc90dd1f6">
+      <ItemAddTime>635905757723338063</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="ea37bd1c-74e2-4e52-b30e-5c9bb8aa404c">
+      <ItemAddTime>635905757723338063</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a7be515f-f007-45ed-9059-4e1500c0f74d">
+      <TimeTagModified-SourceItem0--0>-8587466603591192323</TimeTagModified-SourceItem0--0>
+      <SourceItem0-IsLockedByUser>False</SourceItem0-IsLockedByUser>
+      <SourceItem0-BuildingTarget-0>True</SourceItem0-BuildingTarget-0>
+      <SourceItem0-IndividualCompileOption-0>False</SourceItem0-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem1--0>-8587466603591082258</TimeTagModified-SourceItem1--0>
+      <SourceItem1-IsLockedByUser>False</SourceItem1-IsLockedByUser>
+      <SourceItem1-BuildingTarget-0>True</SourceItem1-BuildingTarget-0>
+      <SourceItem1-IndividualCompileOption-0>False</SourceItem1-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem2--0>-8587466603591082258</TimeTagModified-SourceItem2--0>
+      <SourceItem2-IsLockedByUser>False</SourceItem2-IsLockedByUser>
+      <SourceItem2-BuildingTarget-0>True</SourceItem2-BuildingTarget-0>
+      <SourceItem2-IndividualCompileOption-0>False</SourceItem2-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem3--0>-8587466603591082258</TimeTagModified-SourceItem3--0>
+      <SourceItem3-IsLockedByUser>False</SourceItem3-IsLockedByUser>
+      <SourceItem3-BuildingTarget-0>True</SourceItem3-BuildingTarget-0>
+      <SourceItem3-IndividualCompileOption-0>False</SourceItem3-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem4--0>-8587466603591082258</TimeTagModified-SourceItem4--0>
+      <SourceItem4-IsLockedByUser>False</SourceItem4-IsLockedByUser>
+      <SourceItem4-BuildingTarget-0>True</SourceItem4-BuildingTarget-0>
+      <SourceItem4-IndividualCompileOption-0>False</SourceItem4-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem5--0>-8587466603591082258</TimeTagModified-SourceItem5--0>
+      <SourceItem5-IsLockedByUser>False</SourceItem5-IsLockedByUser>
+      <SourceItem5-BuildingTarget-0>True</SourceItem5-BuildingTarget-0>
+      <SourceItem5-IndividualCompileOption-0>False</SourceItem5-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem6--0>-8587466603591082258</TimeTagModified-SourceItem6--0>
+      <SourceItem6-IsLockedByUser>False</SourceItem6-IsLockedByUser>
+      <SourceItem6-BuildingTarget-0>True</SourceItem6-BuildingTarget-0>
+      <SourceItem6-IndividualCompileOption-0>False</SourceItem6-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem7--0>-8587466603591082258</TimeTagModified-SourceItem7--0>
+      <SourceItem7-IsLockedByUser>False</SourceItem7-IsLockedByUser>
+      <SourceItem7-BuildingTarget-0>True</SourceItem7-BuildingTarget-0>
+      <SourceItem7-IndividualCompileOption-0>False</SourceItem7-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem8--0>-8587466603591082258</TimeTagModified-SourceItem8--0>
+      <SourceItem8-IsLockedByUser>False</SourceItem8-IsLockedByUser>
+      <SourceItem8-BuildingTarget-0>True</SourceItem8-BuildingTarget-0>
+      <SourceItem8-IndividualCompileOption-0>False</SourceItem8-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem9--0>-8587466603591082258</TimeTagModified-SourceItem9--0>
+      <SourceItem9-IsLockedByUser>False</SourceItem9-IsLockedByUser>
+      <SourceItem9-BuildingTarget-0>True</SourceItem9-BuildingTarget-0>
+      <SourceItem9-IndividualCompileOption-0>False</SourceItem9-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem10--0>-8587466603591082258</TimeTagModified-SourceItem10--0>
+      <SourceItem10-IsLockedByUser>False</SourceItem10-IsLockedByUser>
+      <SourceItem10-BuildingTarget-0>True</SourceItem10-BuildingTarget-0>
+      <SourceItem10-IndividualCompileOption-0>False</SourceItem10-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem11--0>-8587466603591082258</TimeTagModified-SourceItem11--0>
+      <SourceItem11-IsLockedByUser>False</SourceItem11-IsLockedByUser>
+      <SourceItem11-BuildingTarget-0>True</SourceItem11-BuildingTarget-0>
+      <SourceItem11-IndividualCompileOption-0>False</SourceItem11-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem12--0>-8587466603591082258</TimeTagModified-SourceItem12--0>
+      <SourceItem12-IsLockedByUser>False</SourceItem12-IsLockedByUser>
+      <SourceItem12-BuildingTarget-0>True</SourceItem12-BuildingTarget-0>
+      <SourceItem12-IndividualCompileOption-0>False</SourceItem12-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem13--0>-8587466603591082258</TimeTagModified-SourceItem13--0>
+      <SourceItem13-IsLockedByUser>False</SourceItem13-IsLockedByUser>
+      <SourceItem13-BuildingTarget-0>True</SourceItem13-BuildingTarget-0>
+      <SourceItem13-IndividualCompileOption-0>False</SourceItem13-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem14--0>-8587466603591082258</TimeTagModified-SourceItem14--0>
+      <SourceItem14-IsLockedByUser>False</SourceItem14-IsLockedByUser>
+      <SourceItem14-BuildingTarget-0>True</SourceItem14-BuildingTarget-0>
+      <SourceItem14-IndividualCompileOption-0>False</SourceItem14-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem15--0>-8587466603591082258</TimeTagModified-SourceItem15--0>
+      <SourceItem15-IsLockedByUser>False</SourceItem15-IsLockedByUser>
+      <SourceItem15-BuildingTarget-0>True</SourceItem15-BuildingTarget-0>
+      <SourceItem15-IndividualCompileOption-0>False</SourceItem15-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem16--0>-8587466603591082258</TimeTagModified-SourceItem16--0>
+      <SourceItem16-IsLockedByUser>False</SourceItem16-IsLockedByUser>
+      <SourceItem16-BuildingTarget-0>True</SourceItem16-BuildingTarget-0>
+      <SourceItem16-IndividualCompileOption-0>False</SourceItem16-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem17--0>-8587466603591077261</TimeTagModified-SourceItem17--0>
+      <SourceItem17-IsLockedByUser>False</SourceItem17-IsLockedByUser>
+      <SourceItem17-BuildingTarget-0>True</SourceItem17-BuildingTarget-0>
+      <SourceItem17-IndividualCompileOption-0>False</SourceItem17-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem18--0>-8587466603591077261</TimeTagModified-SourceItem18--0>
+      <SourceItem18-IsLockedByUser>False</SourceItem18-IsLockedByUser>
+      <SourceItem18-BuildingTarget-0>True</SourceItem18-BuildingTarget-0>
+      <SourceItem18-IndividualCompileOption-0>False</SourceItem18-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem19--0>-8587466603591077261</TimeTagModified-SourceItem19--0>
+      <SourceItem19-IsLockedByUser>False</SourceItem19-IsLockedByUser>
+      <SourceItem19-BuildingTarget-0>True</SourceItem19-BuildingTarget-0>
+      <SourceItem19-IndividualCompileOption-0>False</SourceItem19-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem20--0>-8587466603591077261</TimeTagModified-SourceItem20--0>
+      <SourceItem20-IsLockedByUser>False</SourceItem20-IsLockedByUser>
+      <SourceItem20-BuildingTarget-0>True</SourceItem20-BuildingTarget-0>
+      <SourceItem20-IndividualCompileOption-0>False</SourceItem20-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem21--0>-8587466603591077261</TimeTagModified-SourceItem21--0>
+      <SourceItem21-IsLockedByUser>False</SourceItem21-IsLockedByUser>
+      <SourceItem21-BuildingTarget-0>True</SourceItem21-BuildingTarget-0>
+      <SourceItem21-IndividualCompileOption-0>False</SourceItem21-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem22--0>-8587466603591077261</TimeTagModified-SourceItem22--0>
+      <SourceItem22-IsLockedByUser>False</SourceItem22-IsLockedByUser>
+      <SourceItem22-BuildingTarget-0>True</SourceItem22-BuildingTarget-0>
+      <SourceItem22-IndividualCompileOption-0>False</SourceItem22-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem23--0>-8587466603591077261</TimeTagModified-SourceItem23--0>
+      <SourceItem23-IsLockedByUser>False</SourceItem23-IsLockedByUser>
+      <SourceItem23-BuildingTarget-0>True</SourceItem23-BuildingTarget-0>
+      <SourceItem23-IndividualCompileOption-0>False</SourceItem23-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem24--0>-8587466603591077261</TimeTagModified-SourceItem24--0>
+      <SourceItem24-IsLockedByUser>False</SourceItem24-IsLockedByUser>
+      <SourceItem24-BuildingTarget-0>True</SourceItem24-BuildingTarget-0>
+      <SourceItem24-IndividualCompileOption-0>False</SourceItem24-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem25--0>-8587466603591077261</TimeTagModified-SourceItem25--0>
+      <SourceItem25-IsLockedByUser>False</SourceItem25-IsLockedByUser>
+      <SourceItem25-BuildingTarget-0>True</SourceItem25-BuildingTarget-0>
+      <SourceItem25-IndividualCompileOption-0>False</SourceItem25-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem26--0>-8587466603591077261</TimeTagModified-SourceItem26--0>
+      <SourceItem26-IsLockedByUser>False</SourceItem26-IsLockedByUser>
+      <SourceItem26-BuildingTarget-0>True</SourceItem26-BuildingTarget-0>
+      <SourceItem26-IndividualCompileOption-0>False</SourceItem26-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem27--0>-8587466603591077261</TimeTagModified-SourceItem27--0>
+      <SourceItem27-IsLockedByUser>False</SourceItem27-IsLockedByUser>
+      <SourceItem27-BuildingTarget-0>True</SourceItem27-BuildingTarget-0>
+      <SourceItem27-IndividualCompileOption-0>False</SourceItem27-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem28--0>-8587466603591077261</TimeTagModified-SourceItem28--0>
+      <SourceItem28-IsLockedByUser>False</SourceItem28-IsLockedByUser>
+      <SourceItem28-BuildingTarget-0>True</SourceItem28-BuildingTarget-0>
+      <SourceItem28-IndividualCompileOption-0>False</SourceItem28-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem29--0>-8587466603591077261</TimeTagModified-SourceItem29--0>
+      <SourceItem29-IsLockedByUser>False</SourceItem29-IsLockedByUser>
+      <SourceItem29-BuildingTarget-0>True</SourceItem29-BuildingTarget-0>
+      <SourceItem29-IndividualCompileOption-0>False</SourceItem29-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem30--0>-8587466603591077261</TimeTagModified-SourceItem30--0>
+      <SourceItem30-IsLockedByUser>False</SourceItem30-IsLockedByUser>
+      <SourceItem30-BuildingTarget-0>True</SourceItem30-BuildingTarget-0>
+      <SourceItem30-IndividualCompileOption-0>False</SourceItem30-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem31--0>-8587466603591077261</TimeTagModified-SourceItem31--0>
+      <SourceItem31-IsLockedByUser>False</SourceItem31-IsLockedByUser>
+      <SourceItem31-BuildingTarget-0>True</SourceItem31-BuildingTarget-0>
+      <SourceItem31-IndividualCompileOption-0>False</SourceItem31-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem32--0>-8587466603591077261</TimeTagModified-SourceItem32--0>
+      <SourceItem32-IsLockedByUser>False</SourceItem32-IsLockedByUser>
+      <SourceItem32-BuildingTarget-0>True</SourceItem32-BuildingTarget-0>
+      <SourceItem32-IndividualCompileOption-0>False</SourceItem32-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem33--0>-8587466603591072259</TimeTagModified-SourceItem33--0>
+      <SourceItem33-IsLockedByUser>False</SourceItem33-IsLockedByUser>
+      <SourceItem33-BuildingTarget-0>True</SourceItem33-BuildingTarget-0>
+      <SourceItem33-IndividualCompileOption-0>False</SourceItem33-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem34--0>-8587466603591072259</TimeTagModified-SourceItem34--0>
+      <SourceItem34-IsLockedByUser>False</SourceItem34-IsLockedByUser>
+      <SourceItem34-BuildingTarget-0>True</SourceItem34-BuildingTarget-0>
+      <SourceItem34-IndividualCompileOption-0>False</SourceItem34-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem35--0>-8587466603591072259</TimeTagModified-SourceItem35--0>
+      <SourceItem35-IsLockedByUser>False</SourceItem35-IsLockedByUser>
+      <SourceItem35-BuildingTarget-0>True</SourceItem35-BuildingTarget-0>
+      <SourceItem35-IndividualCompileOption-0>False</SourceItem35-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem36--0>-8587466603591072259</TimeTagModified-SourceItem36--0>
+      <SourceItem36-IsLockedByUser>False</SourceItem36-IsLockedByUser>
+      <SourceItem36-BuildingTarget-0>True</SourceItem36-BuildingTarget-0>
+      <SourceItem36-IndividualCompileOption-0>False</SourceItem36-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem37--0>-8587466603591072259</TimeTagModified-SourceItem37--0>
+      <SourceItem37-IsLockedByUser>False</SourceItem37-IsLockedByUser>
+      <SourceItem37-BuildingTarget-0>True</SourceItem37-BuildingTarget-0>
+      <SourceItem37-IndividualCompileOption-0>False</SourceItem37-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem38--0>-8587466603591072259</TimeTagModified-SourceItem38--0>
+      <SourceItem38-IsLockedByUser>False</SourceItem38-IsLockedByUser>
+      <SourceItem38-BuildingTarget-0>True</SourceItem38-BuildingTarget-0>
+      <SourceItem38-IndividualCompileOption-0>False</SourceItem38-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem39--0>-8587466603591072259</TimeTagModified-SourceItem39--0>
+      <SourceItem39-IsLockedByUser>False</SourceItem39-IsLockedByUser>
+      <SourceItem39-BuildingTarget-0>True</SourceItem39-BuildingTarget-0>
+      <SourceItem39-IndividualCompileOption-0>False</SourceItem39-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem40--0>-8587466603591072259</TimeTagModified-SourceItem40--0>
+      <SourceItem40-IsLockedByUser>False</SourceItem40-IsLockedByUser>
+      <SourceItem40-BuildingTarget-0>True</SourceItem40-BuildingTarget-0>
+      <SourceItem40-IndividualCompileOption-0>False</SourceItem40-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem41--0>-8587466603591072259</TimeTagModified-SourceItem41--0>
+      <SourceItem41-IsLockedByUser>False</SourceItem41-IsLockedByUser>
+      <SourceItem41-BuildingTarget-0>True</SourceItem41-BuildingTarget-0>
+      <SourceItem41-IndividualCompileOption-0>False</SourceItem41-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem42--0>-8587466603591072259</TimeTagModified-SourceItem42--0>
+      <SourceItem42-IsLockedByUser>False</SourceItem42-IsLockedByUser>
+      <SourceItem42-BuildingTarget-0>True</SourceItem42-BuildingTarget-0>
+      <SourceItem42-IndividualCompileOption-0>False</SourceItem42-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem43--0>-8587466603591072259</TimeTagModified-SourceItem43--0>
+      <SourceItem43-IsLockedByUser>False</SourceItem43-IsLockedByUser>
+      <SourceItem43-BuildingTarget-0>True</SourceItem43-BuildingTarget-0>
+      <SourceItem43-IndividualCompileOption-0>False</SourceItem43-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem44--0>-8587466603591072259</TimeTagModified-SourceItem44--0>
+      <SourceItem44-IsLockedByUser>False</SourceItem44-IsLockedByUser>
+      <SourceItem44-BuildingTarget-0>True</SourceItem44-BuildingTarget-0>
+      <SourceItem44-IndividualCompileOption-0>False</SourceItem44-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem45--0>-8587466603591072259</TimeTagModified-SourceItem45--0>
+      <SourceItem45-IsLockedByUser>False</SourceItem45-IsLockedByUser>
+      <SourceItem45-BuildingTarget-0>True</SourceItem45-BuildingTarget-0>
+      <SourceItem45-IndividualCompileOption-0>False</SourceItem45-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem46--0>-8587466603591072259</TimeTagModified-SourceItem46--0>
+      <SourceItem46-IsLockedByUser>False</SourceItem46-IsLockedByUser>
+      <SourceItem46-BuildingTarget-0>True</SourceItem46-BuildingTarget-0>
+      <SourceItem46-IndividualCompileOption-0>False</SourceItem46-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem47--0>-8587466603591072259</TimeTagModified-SourceItem47--0>
+      <SourceItem47-IsLockedByUser>False</SourceItem47-IsLockedByUser>
+      <SourceItem47-BuildingTarget-0>True</SourceItem47-BuildingTarget-0>
+      <SourceItem47-IndividualCompileOption-0>False</SourceItem47-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem48--0>-8587466603591067257</TimeTagModified-SourceItem48--0>
+      <SourceItem48-IsLockedByUser>False</SourceItem48-IsLockedByUser>
+      <SourceItem48-BuildingTarget-0>True</SourceItem48-BuildingTarget-0>
+      <SourceItem48-IndividualCompileOption-0>False</SourceItem48-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem49--0>-8587466603591067257</TimeTagModified-SourceItem49--0>
+      <SourceItem49-IsLockedByUser>False</SourceItem49-IsLockedByUser>
+      <SourceItem49-BuildingTarget-0>True</SourceItem49-BuildingTarget-0>
+      <SourceItem49-IndividualCompileOption-0>False</SourceItem49-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem50--0>-8587466603591067257</TimeTagModified-SourceItem50--0>
+      <SourceItem50-IsLockedByUser>False</SourceItem50-IsLockedByUser>
+      <SourceItem50-BuildingTarget-0>True</SourceItem50-BuildingTarget-0>
+      <SourceItem50-IndividualCompileOption-0>False</SourceItem50-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem51--0>-8587466603591067257</TimeTagModified-SourceItem51--0>
+      <SourceItem51-IsLockedByUser>False</SourceItem51-IsLockedByUser>
+      <SourceItem51-BuildingTarget-0>True</SourceItem51-BuildingTarget-0>
+      <SourceItem51-IndividualCompileOption-0>False</SourceItem51-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem52--0>-8587466603591067257</TimeTagModified-SourceItem52--0>
+      <SourceItem52-IsLockedByUser>False</SourceItem52-IsLockedByUser>
+      <SourceItem52-BuildingTarget-0>True</SourceItem52-BuildingTarget-0>
+      <SourceItem52-IndividualCompileOption-0>False</SourceItem52-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem53--0>-8587466603591067257</TimeTagModified-SourceItem53--0>
+      <SourceItem53-IsLockedByUser>False</SourceItem53-IsLockedByUser>
+      <SourceItem53-BuildingTarget-0>True</SourceItem53-BuildingTarget-0>
+      <SourceItem53-IndividualCompileOption-0>False</SourceItem53-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem54--0>-8587466603591067257</TimeTagModified-SourceItem54--0>
+      <SourceItem54-IsLockedByUser>False</SourceItem54-IsLockedByUser>
+      <SourceItem54-BuildingTarget-0>True</SourceItem54-BuildingTarget-0>
+      <SourceItem54-IndividualCompileOption-0>False</SourceItem54-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem55--0>-8587466603591067257</TimeTagModified-SourceItem55--0>
+      <SourceItem55-IsLockedByUser>False</SourceItem55-IsLockedByUser>
+      <SourceItem55-BuildingTarget-0>True</SourceItem55-BuildingTarget-0>
+      <SourceItem55-IndividualCompileOption-0>False</SourceItem55-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem56--0>-8587466603591067257</TimeTagModified-SourceItem56--0>
+      <SourceItem56-IsLockedByUser>False</SourceItem56-IsLockedByUser>
+      <SourceItem56-BuildingTarget-0>True</SourceItem56-BuildingTarget-0>
+      <SourceItem56-IndividualCompileOption-0>False</SourceItem56-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem57--0>-8587466603591067257</TimeTagModified-SourceItem57--0>
+      <SourceItem57-IsLockedByUser>False</SourceItem57-IsLockedByUser>
+      <SourceItem57-BuildingTarget-0>True</SourceItem57-BuildingTarget-0>
+      <SourceItem57-IndividualCompileOption-0>False</SourceItem57-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem58--0>-8587466603591067257</TimeTagModified-SourceItem58--0>
+      <SourceItem58-IsLockedByUser>False</SourceItem58-IsLockedByUser>
+      <SourceItem58-BuildingTarget-0>True</SourceItem58-BuildingTarget-0>
+      <SourceItem58-IndividualCompileOption-0>False</SourceItem58-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem59--0>-8587466603591067257</TimeTagModified-SourceItem59--0>
+      <SourceItem59-IsLockedByUser>False</SourceItem59-IsLockedByUser>
+      <SourceItem59-BuildingTarget-0>True</SourceItem59-BuildingTarget-0>
+      <SourceItem59-IndividualCompileOption-0>False</SourceItem59-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem60--0>-8587466603591067257</TimeTagModified-SourceItem60--0>
+      <SourceItem60-IsLockedByUser>False</SourceItem60-IsLockedByUser>
+      <SourceItem60-BuildingTarget-0>True</SourceItem60-BuildingTarget-0>
+      <SourceItem60-IndividualCompileOption-0>False</SourceItem60-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem61--0>-8587466603591067257</TimeTagModified-SourceItem61--0>
+      <SourceItem61-IsLockedByUser>False</SourceItem61-IsLockedByUser>
+      <SourceItem61-BuildingTarget-0>True</SourceItem61-BuildingTarget-0>
+      <SourceItem61-IndividualCompileOption-0>False</SourceItem61-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem62--0>-8587466603591067257</TimeTagModified-SourceItem62--0>
+      <SourceItem62-IsLockedByUser>False</SourceItem62-IsLockedByUser>
+      <SourceItem62-BuildingTarget-0>True</SourceItem62-BuildingTarget-0>
+      <SourceItem62-IndividualCompileOption-0>False</SourceItem62-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem63--0>-8587466603591062255</TimeTagModified-SourceItem63--0>
+      <SourceItem63-IsLockedByUser>False</SourceItem63-IsLockedByUser>
+      <SourceItem63-BuildingTarget-0>True</SourceItem63-BuildingTarget-0>
+      <SourceItem63-IndividualCompileOption-0>False</SourceItem63-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem64--0>-8587462000400872774</TimeTagModified-SourceItem64--0>
+      <SourceItem64-IsLockedByUser>False</SourceItem64-IsLockedByUser>
+      <SourceItem64-BuildingTarget-0>True</SourceItem64-BuildingTarget-0>
+      <SourceItem64-IndividualCompileOption-0>False</SourceItem64-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem65--0>-8587466603591062255</TimeTagModified-SourceItem65--0>
+      <SourceItem65-IsLockedByUser>False</SourceItem65-IsLockedByUser>
+      <SourceItem65-BuildingTarget-0>True</SourceItem65-BuildingTarget-0>
+      <SourceItem65-IndividualCompileOption-0>False</SourceItem65-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem66--0>-8587466603591062255</TimeTagModified-SourceItem66--0>
+      <SourceItem66-IsLockedByUser>False</SourceItem66-IsLockedByUser>
+      <SourceItem66-BuildingTarget-0>True</SourceItem66-BuildingTarget-0>
+      <SourceItem66-IndividualCompileOption-0>False</SourceItem66-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem67--0>-8587466603591062255</TimeTagModified-SourceItem67--0>
+      <SourceItem67-IsLockedByUser>False</SourceItem67-IsLockedByUser>
+      <SourceItem67-BuildingTarget-0>True</SourceItem67-BuildingTarget-0>
+      <SourceItem67-IndividualCompileOption-0>False</SourceItem67-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem68--0>-8587466603591062255</TimeTagModified-SourceItem68--0>
+      <SourceItem68-IsLockedByUser>False</SourceItem68-IsLockedByUser>
+      <SourceItem68-BuildingTarget-0>True</SourceItem68-BuildingTarget-0>
+      <SourceItem68-IndividualCompileOption-0>False</SourceItem68-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem69--0>-8587466603591062255</TimeTagModified-SourceItem69--0>
+      <SourceItem69-IsLockedByUser>False</SourceItem69-IsLockedByUser>
+      <SourceItem69-BuildingTarget-0>True</SourceItem69-BuildingTarget-0>
+      <SourceItem69-IndividualCompileOption-0>False</SourceItem69-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem70--0>-8587466603591062255</TimeTagModified-SourceItem70--0>
+      <SourceItem70-IsLockedByUser>False</SourceItem70-IsLockedByUser>
+      <SourceItem70-BuildingTarget-0>True</SourceItem70-BuildingTarget-0>
+      <SourceItem70-IndividualCompileOption-0>False</SourceItem70-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem71--0>-8587466603591062255</TimeTagModified-SourceItem71--0>
+      <SourceItem71-IsLockedByUser>False</SourceItem71-IsLockedByUser>
+      <SourceItem71-BuildingTarget-0>True</SourceItem71-BuildingTarget-0>
+      <SourceItem71-IndividualCompileOption-0>False</SourceItem71-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem72--0>-8587466603591062255</TimeTagModified-SourceItem72--0>
+      <SourceItem72-IsLockedByUser>False</SourceItem72-IsLockedByUser>
+      <SourceItem72-BuildingTarget-0>True</SourceItem72-BuildingTarget-0>
+      <SourceItem72-IndividualCompileOption-0>False</SourceItem72-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem73--0>-8587466603591062255</TimeTagModified-SourceItem73--0>
+      <SourceItem73-IsLockedByUser>False</SourceItem73-IsLockedByUser>
+      <SourceItem73-BuildingTarget-0>True</SourceItem73-BuildingTarget-0>
+      <SourceItem73-IndividualCompileOption-0>False</SourceItem73-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem74--0>-8587466603591062255</TimeTagModified-SourceItem74--0>
+      <SourceItem74-IsLockedByUser>False</SourceItem74-IsLockedByUser>
+      <SourceItem74-BuildingTarget-0>True</SourceItem74-BuildingTarget-0>
+      <SourceItem74-IndividualCompileOption-0>False</SourceItem74-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem75--0>-8587466603591062255</TimeTagModified-SourceItem75--0>
+      <SourceItem75-IsLockedByUser>False</SourceItem75-IsLockedByUser>
+      <SourceItem75-BuildingTarget-0>True</SourceItem75-BuildingTarget-0>
+      <SourceItem75-IndividualCompileOption-0>False</SourceItem75-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem76--0>-8587466603591062255</TimeTagModified-SourceItem76--0>
+      <SourceItem76-IsLockedByUser>False</SourceItem76-IsLockedByUser>
+      <SourceItem76-BuildingTarget-0>True</SourceItem76-BuildingTarget-0>
+      <SourceItem76-IndividualCompileOption-0>False</SourceItem76-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem77--0>-8587466603591057248</TimeTagModified-SourceItem77--0>
+      <SourceItem77-IsLockedByUser>False</SourceItem77-IsLockedByUser>
+      <SourceItem77-BuildingTarget-0>True</SourceItem77-BuildingTarget-0>
+      <SourceItem77-IndividualCompileOption-0>False</SourceItem77-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem78--0>-8587466603591057248</TimeTagModified-SourceItem78--0>
+      <SourceItem78-IsLockedByUser>False</SourceItem78-IsLockedByUser>
+      <SourceItem78-BuildingTarget-0>True</SourceItem78-BuildingTarget-0>
+      <SourceItem78-IndividualCompileOption-0>False</SourceItem78-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem79--0>-8587466603591057248</TimeTagModified-SourceItem79--0>
+      <SourceItem79-IsLockedByUser>False</SourceItem79-IsLockedByUser>
+      <SourceItem79-BuildingTarget-0>True</SourceItem79-BuildingTarget-0>
+      <SourceItem79-IndividualCompileOption-0>False</SourceItem79-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem80--0>-8587466603591057248</TimeTagModified-SourceItem80--0>
+      <SourceItem80-IsLockedByUser>False</SourceItem80-IsLockedByUser>
+      <SourceItem80-BuildingTarget-0>True</SourceItem80-BuildingTarget-0>
+      <SourceItem80-IndividualCompileOption-0>False</SourceItem80-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem81--0>-8587466603591057248</TimeTagModified-SourceItem81--0>
+      <SourceItem81-IsLockedByUser>False</SourceItem81-IsLockedByUser>
+      <SourceItem81-BuildingTarget-0>True</SourceItem81-BuildingTarget-0>
+      <SourceItem81-IndividualCompileOption-0>False</SourceItem81-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem82--0>-8587466603591057248</TimeTagModified-SourceItem82--0>
+      <SourceItem82-IsLockedByUser>False</SourceItem82-IsLockedByUser>
+      <SourceItem82-BuildingTarget-0>True</SourceItem82-BuildingTarget-0>
+      <SourceItem82-IndividualCompileOption-0>False</SourceItem82-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem83--0>-8587466603591057248</TimeTagModified-SourceItem83--0>
+      <SourceItem83-IsLockedByUser>False</SourceItem83-IsLockedByUser>
+      <SourceItem83-BuildingTarget-0>True</SourceItem83-BuildingTarget-0>
+      <SourceItem83-IndividualCompileOption-0>False</SourceItem83-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem84--0>-8587466603591057248</TimeTagModified-SourceItem84--0>
+      <SourceItem84-IsLockedByUser>False</SourceItem84-IsLockedByUser>
+      <SourceItem84-BuildingTarget-0>True</SourceItem84-BuildingTarget-0>
+      <SourceItem84-IndividualCompileOption-0>False</SourceItem84-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem85--0>-8587466603591057248</TimeTagModified-SourceItem85--0>
+      <SourceItem85-IsLockedByUser>False</SourceItem85-IsLockedByUser>
+      <SourceItem85-BuildingTarget-0>True</SourceItem85-BuildingTarget-0>
+      <SourceItem85-IndividualCompileOption-0>False</SourceItem85-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem86--0>-8587466603591057248</TimeTagModified-SourceItem86--0>
+      <SourceItem86-IsLockedByUser>False</SourceItem86-IsLockedByUser>
+      <SourceItem86-BuildingTarget-0>True</SourceItem86-BuildingTarget-0>
+      <SourceItem86-IndividualCompileOption-0>False</SourceItem86-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem87--0>-8587466603591057248</TimeTagModified-SourceItem87--0>
+      <SourceItem87-IsLockedByUser>False</SourceItem87-IsLockedByUser>
+      <SourceItem87-BuildingTarget-0>True</SourceItem87-BuildingTarget-0>
+      <SourceItem87-IndividualCompileOption-0>False</SourceItem87-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem88--0>-8587466603591057248</TimeTagModified-SourceItem88--0>
+      <SourceItem88-IsLockedByUser>False</SourceItem88-IsLockedByUser>
+      <SourceItem88-BuildingTarget-0>True</SourceItem88-BuildingTarget-0>
+      <SourceItem88-IndividualCompileOption-0>False</SourceItem88-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem89--0>-8587466603591057248</TimeTagModified-SourceItem89--0>
+      <SourceItem89-IsLockedByUser>False</SourceItem89-IsLockedByUser>
+      <SourceItem89-BuildingTarget-0>True</SourceItem89-BuildingTarget-0>
+      <SourceItem89-IndividualCompileOption-0>False</SourceItem89-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem90--0>-8587466603591052246</TimeTagModified-SourceItem90--0>
+      <SourceItem90-IsLockedByUser>False</SourceItem90-IsLockedByUser>
+      <SourceItem90-BuildingTarget-0>True</SourceItem90-BuildingTarget-0>
+      <SourceItem90-IndividualCompileOption-0>False</SourceItem90-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem91--0>-8587466603591052246</TimeTagModified-SourceItem91--0>
+      <SourceItem91-IsLockedByUser>False</SourceItem91-IsLockedByUser>
+      <SourceItem91-BuildingTarget-0>True</SourceItem91-BuildingTarget-0>
+      <SourceItem91-IndividualCompileOption-0>False</SourceItem91-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem92--0>-8587466603591052246</TimeTagModified-SourceItem92--0>
+      <SourceItem92-IsLockedByUser>False</SourceItem92-IsLockedByUser>
+      <SourceItem92-BuildingTarget-0>True</SourceItem92-BuildingTarget-0>
+      <SourceItem92-IndividualCompileOption-0>False</SourceItem92-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem93--0>-8587466603591052246</TimeTagModified-SourceItem93--0>
+      <SourceItem93-IsLockedByUser>False</SourceItem93-IsLockedByUser>
+      <SourceItem93-BuildingTarget-0>True</SourceItem93-BuildingTarget-0>
+      <SourceItem93-IndividualCompileOption-0>False</SourceItem93-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem94--0>-8587466603591052246</TimeTagModified-SourceItem94--0>
+      <SourceItem94-IsLockedByUser>False</SourceItem94-IsLockedByUser>
+      <SourceItem94-BuildingTarget-0>True</SourceItem94-BuildingTarget-0>
+      <SourceItem94-IndividualCompileOption-0>False</SourceItem94-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem95--0>-8587466603591052246</TimeTagModified-SourceItem95--0>
+      <SourceItem95-IsLockedByUser>False</SourceItem95-IsLockedByUser>
+      <SourceItem95-BuildingTarget-0>True</SourceItem95-BuildingTarget-0>
+      <SourceItem95-IndividualCompileOption-0>False</SourceItem95-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem96--0>-8587466603591052246</TimeTagModified-SourceItem96--0>
+      <SourceItem96-IsLockedByUser>False</SourceItem96-IsLockedByUser>
+      <SourceItem96-BuildingTarget-0>True</SourceItem96-BuildingTarget-0>
+      <SourceItem96-IndividualCompileOption-0>False</SourceItem96-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem97--0>-8587466603591052246</TimeTagModified-SourceItem97--0>
+      <SourceItem97-IsLockedByUser>False</SourceItem97-IsLockedByUser>
+      <SourceItem97-BuildingTarget-0>True</SourceItem97-BuildingTarget-0>
+      <SourceItem97-IndividualCompileOption-0>False</SourceItem97-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem98--0>-8587466603591052246</TimeTagModified-SourceItem98--0>
+      <SourceItem98-IsLockedByUser>False</SourceItem98-IsLockedByUser>
+      <SourceItem98-BuildingTarget-0>True</SourceItem98-BuildingTarget-0>
+      <SourceItem98-IndividualCompileOption-0>False</SourceItem98-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem99--0>-8587466603591052246</TimeTagModified-SourceItem99--0>
+      <SourceItem99-IsLockedByUser>False</SourceItem99-IsLockedByUser>
+      <SourceItem99-BuildingTarget-0>True</SourceItem99-BuildingTarget-0>
+      <SourceItem99-IndividualCompileOption-0>False</SourceItem99-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem100--0>-8587466603591052246</TimeTagModified-SourceItem100--0>
+      <SourceItem100-IsLockedByUser>False</SourceItem100-IsLockedByUser>
+      <SourceItem100-BuildingTarget-0>True</SourceItem100-BuildingTarget-0>
+      <SourceItem100-IndividualCompileOption-0>False</SourceItem100-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem101--0>-8587466603591052246</TimeTagModified-SourceItem101--0>
+      <SourceItem101-IsLockedByUser>False</SourceItem101-IsLockedByUser>
+      <SourceItem101-BuildingTarget-0>True</SourceItem101-BuildingTarget-0>
+      <SourceItem101-IndividualCompileOption-0>False</SourceItem101-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem102--0>-8587466603591052246</TimeTagModified-SourceItem102--0>
+      <SourceItem102-IsLockedByUser>False</SourceItem102-IsLockedByUser>
+      <SourceItem102-BuildingTarget-0>True</SourceItem102-BuildingTarget-0>
+      <SourceItem102-IndividualCompileOption-0>False</SourceItem102-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem103--0>-8587466603591047244</TimeTagModified-SourceItem103--0>
+      <SourceItem103-IsLockedByUser>False</SourceItem103-IsLockedByUser>
+      <SourceItem103-BuildingTarget-0>True</SourceItem103-BuildingTarget-0>
+      <SourceItem103-IndividualCompileOption-0>False</SourceItem103-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem104--0>-8587466603591047244</TimeTagModified-SourceItem104--0>
+      <SourceItem104-IsLockedByUser>False</SourceItem104-IsLockedByUser>
+      <SourceItem104-BuildingTarget-0>True</SourceItem104-BuildingTarget-0>
+      <SourceItem104-IndividualCompileOption-0>False</SourceItem104-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem105--0>-8587466603591047244</TimeTagModified-SourceItem105--0>
+      <SourceItem105-IsLockedByUser>False</SourceItem105-IsLockedByUser>
+      <SourceItem105-BuildingTarget-0>True</SourceItem105-BuildingTarget-0>
+      <SourceItem105-IndividualCompileOption-0>False</SourceItem105-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem106--0>-8587466603131437745</TimeTagModified-SourceItem106--0>
+      <SourceItem106-IsLockedByUser>False</SourceItem106-IsLockedByUser>
+      <SourceItem106-BuildingTarget-0>True</SourceItem106-BuildingTarget-0>
+      <SourceItem106-IndividualCompileOption-0>False</SourceItem106-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem107--0>-8587466603131437745</TimeTagModified-SourceItem107--0>
+      <SourceItem107-IsLockedByUser>False</SourceItem107-IsLockedByUser>
+      <SourceItem107-BuildingTarget-0>True</SourceItem107-BuildingTarget-0>
+      <SourceItem107-IndividualCompileOption-0>False</SourceItem107-IndividualCompileOption-0>
+    </Instance>
+  </Class>
+  <Class Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
+    <Instance Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
+      <IsLibraryMode>True</IsLibraryMode>
+      <StartUpCategoryItem>00000000-0000-0000-0000-000000000000</StartUpCategoryItem>
+    </Instance>
+  </Class>
+  <Class Guid="a29a09ee-92c3-4ce7-9586-a1b058043f92">
+    <Instance Guid="a29a09ee-92c3-4ce7-9586-a1b058043f92">
+      <ProjectGeneratr-GeneratedFile0 />
+    </Instance>
+  </Class>
+  <Class Guid="31a86ad3-37bd-4846-aff2-e08abdc00197">
+    <Instance Guid="31a86ad3-37bd-4846-aff2-e08abdc00197">
+      <DeviceNameOnCreateStartup>R5F563NBDxFP</DeviceNameOnCreateStartup>
+    </Instance>
+  </Class>
+  <Class Guid="78a5c5cd-76cb-4bcc-a031-3020011fbc9a">
+    <Instance Guid="2b9ee042-9cd4-4114-8e75-84c6e59402df">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">
+    <Instance Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">
+      <ProductVersion>5.02.00.00</ProductVersion>
+    </Instance>
+  </Class>
+</CubeSuiteProject>
Index: UsbWattMeter/trunk/csp/liblwip/liblwip.mtpj
===================================================================
--- UsbWattMeter/trunk/csp/liblwip/liblwip.mtpj	(revision 164)
+++ UsbWattMeter/trunk/csp/liblwip/liblwip.mtpj	(revision 164)
@@ -0,0 +1,2182 @@
+<CubeSuiteProject>
+  <ProductVersion>4.02.00.00</ProductVersion>
+  <Class Guid="68f4a651-b9cd-473b-a595-b00447132ffa">
+    <Instance Guid="00000000-0000-0000-0000-000000000000">
+      <FormatVersion>2.0</FormatVersion>
+      <FileVersion>4.2</FileVersion>
+      <ProjectGuid>feb1751b-bb32-42be-98f4-cc9f0a3f1912</ProjectGuid>
+      <ProjectItemGuid>207ed42e-4c73-498f-916d-aaf41c22488a</ProjectItemGuid>
+      <FileCategoryGuid>56d9720b-191b-4240-bdbe-d0defdfec9fb</FileCategoryGuid>
+      <Property>fb98844b-2c27-4275-9804-f6e63e204da0</Property>
+      <ActiveProjectGuid>feb1751b-bb32-42be-98f4-cc9f0a3f1912</ActiveProjectGuid>
+    </Instance>
+    <Instance Guid="0f757d33-e545-42d2-8431-3f741ac34d37">
+      <Name>api</Name>
+      <Type>Category</Type>
+      <ParentItem>56d9720b-191b-4240-bdbe-d0defdfec9fb</ParentItem>
+      <Property>932d046d-f082-49f4-a741-7406cd636fa4</Property>
+    </Instance>
+    <Instance Guid="1ff5022e-0201-4de1-9877-a0ee5e7a0bb7">
+      <Name>core</Name>
+      <Type>Category</Type>
+      <ParentItem>56d9720b-191b-4240-bdbe-d0defdfec9fb</ParentItem>
+      <Property>19fbfcda-ea2b-4da8-9002-8b9f5becaf18</Property>
+    </Instance>
+    <Instance Guid="11a43ca7-8e6d-408e-a1b3-01bf1fce0fc1">
+      <Name>netif</Name>
+      <Type>Category</Type>
+      <ParentItem>56d9720b-191b-4240-bdbe-d0defdfec9fb</ParentItem>
+      <Property>bf751ff3-b5c4-4138-ace9-3204ad838d83</Property>
+    </Instance>
+    <Instance Guid="866fbc09-7e11-405e-9f0d-92eb78e699be">
+      <Name>sys_arch.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\ports\asp_dcre\sys_arch.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>56d9720b-191b-4240-bdbe-d0defdfec9fb</ParentItem>
+      <Property>1553fe25-ea6b-41e5-b0ea-10ff008cf53c</Property>
+    </Instance>
+    <Instance Guid="fb24d4e3-498f-45ef-bdb2-79936c6ddd44">
+      <Name>lwip_task.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\ports\asp_dcre\lwip_task.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>56d9720b-191b-4240-bdbe-d0defdfec9fb</ParentItem>
+      <Property>91b084d5-a0fc-4c56-a23c-93af25b4d484</Property>
+    </Instance>
+    <Instance Guid="a3674528-00e9-4533-8063-65032b408db3">
+      <Name>api_lib.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\api\api_lib.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>0f757d33-e545-42d2-8431-3f741ac34d37</ParentItem>
+      <Property>95674899-740d-4940-b772-cbee83c4c920</Property>
+    </Instance>
+    <Instance Guid="198fe5f0-554f-4c50-88bc-0e69c1514fcd">
+      <Name>api_msg.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\api\api_msg.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>0f757d33-e545-42d2-8431-3f741ac34d37</ParentItem>
+      <Property>63d5671a-dd85-48e1-be58-67228180e587</Property>
+    </Instance>
+    <Instance Guid="0b395f47-da36-416f-9d47-da6d06dc23d1">
+      <Name>err.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\api\err.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>0f757d33-e545-42d2-8431-3f741ac34d37</ParentItem>
+      <Property>da12b667-507d-442a-a74f-f6ddb8c60c28</Property>
+    </Instance>
+    <Instance Guid="280687ba-82a3-41a6-a5b4-c7517299fb01">
+      <Name>netbuf.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\api\netbuf.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>0f757d33-e545-42d2-8431-3f741ac34d37</ParentItem>
+      <Property>9091b1f6-a525-4392-b9c5-2d3ad83aedf5</Property>
+    </Instance>
+    <Instance Guid="a6ae1533-dfbb-4aec-a09b-f233e6272050">
+      <Name>netdb.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\api\netdb.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>0f757d33-e545-42d2-8431-3f741ac34d37</ParentItem>
+      <Property>11f3434b-f761-45b1-bdde-19d3ea6c252b</Property>
+    </Instance>
+    <Instance Guid="65b2b931-0cca-4612-97fa-2e9a61fc7244">
+      <Name>netifapi.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\api\netifapi.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>0f757d33-e545-42d2-8431-3f741ac34d37</ParentItem>
+      <Property>46d4312c-dce7-4b53-bbf8-fc58159c4f42</Property>
+    </Instance>
+    <Instance Guid="86daecbd-5ecc-4c22-9184-edf543d18d90">
+      <Name>sockets.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\api\sockets.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>0f757d33-e545-42d2-8431-3f741ac34d37</ParentItem>
+      <Property>c23ed742-d1ff-45f2-9e2b-0bb99c1a4fe7</Property>
+    </Instance>
+    <Instance Guid="31232115-7500-42f7-9874-a16d5b42f4fa">
+      <Name>tcpip.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\api\tcpip.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>0f757d33-e545-42d2-8431-3f741ac34d37</ParentItem>
+      <Property>0478816f-da05-495b-b189-b59fdf9fd317</Property>
+    </Instance>
+    <Instance Guid="1ddc393c-8a83-4011-9386-edb46bf00c14">
+      <Name>ipv4</Name>
+      <Type>Category</Type>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>7830cfcf-5cf0-4ec4-b981-b365345fd4be</Property>
+    </Instance>
+    <Instance Guid="9a19ae4a-0d29-459e-8ca4-3a599fd2da97">
+      <Name>ipv6</Name>
+      <Type>Category</Type>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>1ba413f0-3a90-478c-b5ee-054af207d7b8</Property>
+    </Instance>
+    <Instance Guid="ad78cf6e-335c-4487-ad7b-e358d8e476ba">
+      <Name>snmp</Name>
+      <Type>Category</Type>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>f9bb050d-7da3-4934-a70d-334fbe87464e</Property>
+    </Instance>
+    <Instance Guid="96e1434d-c7a3-45e5-a84b-3a62b10cc5fa">
+      <Name>def.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\def.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>084caeb4-a3d2-4967-a99f-55654f9c889d</Property>
+    </Instance>
+    <Instance Guid="a5721642-ad90-4677-92a2-b4e5b6f6f8dc">
+      <Name>dhcp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\dhcp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>6fbfd966-b0a1-45fc-b235-c588a11d36ac</Property>
+    </Instance>
+    <Instance Guid="4ea6cf6b-b92f-429a-816d-2f9b1fc1db57">
+      <Name>dns.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\dns.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>a0d0d1de-04ad-44e2-86a2-46880c0b3cdb</Property>
+    </Instance>
+    <Instance Guid="62147325-dc74-482f-ae14-fe94400d8cb1">
+      <Name>init.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\init.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>6b751d79-a73e-43ab-bfd7-c8f5b1c1f3fd</Property>
+    </Instance>
+    <Instance Guid="234a83ac-04b7-4cad-8202-e6c9a99ea731">
+      <Name>mem.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\mem.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>295198f0-3769-4469-8ec0-b721995ac9e0</Property>
+    </Instance>
+    <Instance Guid="af1e26d9-bfd9-42f8-8a66-d622d9933dd0">
+      <Name>memp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\memp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>9e17d71a-073d-48f7-94ba-6f3f266e1b3b</Property>
+    </Instance>
+    <Instance Guid="ae5848a7-54bb-461f-b5d2-8594e6b66a1e">
+      <Name>netif.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\netif.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>6e5ad97c-0fa5-4f34-8124-9699b35e7090</Property>
+    </Instance>
+    <Instance Guid="f2fbf733-f77e-4e17-bc84-e1788e6c00b2">
+      <Name>pbuf.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\pbuf.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>6d042040-4643-43df-ba4f-0cb26ae4bf6a</Property>
+    </Instance>
+    <Instance Guid="508ee1c5-8d5e-409d-8e3a-004cdac69699">
+      <Name>raw.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\raw.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>c8fc4241-d439-4d2f-a5c1-934239ff5c26</Property>
+    </Instance>
+    <Instance Guid="22395ed5-fbe7-46d6-bf5b-8de642b8f2ce">
+      <Name>stats.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\stats.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>15cabe46-3383-4983-8715-f310a348c742</Property>
+    </Instance>
+    <Instance Guid="5c452fec-c9da-40e5-8741-8e87293080cb">
+      <Name>sys.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\sys.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>1fdee431-6029-4b51-96d5-2304b7d5a2f1</Property>
+    </Instance>
+    <Instance Guid="8b24ed2f-eaa8-4756-9c71-013ba384b1a0">
+      <Name>tcp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\tcp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>fba97ea2-159b-4fff-ac6d-fc01715137c5</Property>
+    </Instance>
+    <Instance Guid="c373deec-64d2-4f42-be96-397d83a08860">
+      <Name>tcp_in.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\tcp_in.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>c7bb081b-9c68-4d36-900d-f1bf17d2c82b</Property>
+    </Instance>
+    <Instance Guid="6f0f2f1b-dc20-4ad8-a0ff-44cd9873e897">
+      <Name>tcp_out.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\tcp_out.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>c3167cf2-d943-44a3-b4f3-b091ebc2fa15</Property>
+    </Instance>
+    <Instance Guid="5b6c5f18-4b13-45d1-9a95-7c487cfb010b">
+      <Name>timers.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\timers.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>3e702737-028b-4d45-b0b4-398efec9fbb1</Property>
+    </Instance>
+    <Instance Guid="803f7136-a524-471c-a96d-38dde2b30e71">
+      <Name>udp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\udp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ff5022e-0201-4de1-9877-a0ee5e7a0bb7</ParentItem>
+      <Property>69637c55-870b-4946-b03b-3dc9443ac313</Property>
+    </Instance>
+    <Instance Guid="eeb7cf38-60e7-4f9e-8c5d-37e42f95dcee">
+      <Name>autoip.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\ipv4\autoip.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ddc393c-8a83-4011-9386-edb46bf00c14</ParentItem>
+      <Property>bd8d6765-0ce7-40fc-9317-d15b287ccd1c</Property>
+    </Instance>
+    <Instance Guid="67b54e87-a62c-4b30-9029-f01dcf4d76cb">
+      <Name>icmp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\ipv4\icmp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ddc393c-8a83-4011-9386-edb46bf00c14</ParentItem>
+      <Property>b4afe9ab-6754-4cd7-aea3-a1e35c292a93</Property>
+    </Instance>
+    <Instance Guid="b65d2ea2-f59a-43b4-bf04-36a6d80e1e96">
+      <Name>igmp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\ipv4\igmp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ddc393c-8a83-4011-9386-edb46bf00c14</ParentItem>
+      <Property>b7bfa92c-935a-40dd-b9b4-9ab9b11ffed5</Property>
+    </Instance>
+    <Instance Guid="e01a0e44-98a1-43e9-baa4-a4fcd6009616">
+      <Name>inet.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\ipv4\inet.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ddc393c-8a83-4011-9386-edb46bf00c14</ParentItem>
+      <Property>f7516879-3a6a-4971-a732-83647bb3c59a</Property>
+    </Instance>
+    <Instance Guid="5f87b41c-932f-442c-af8d-952b33c37066">
+      <Name>inet_chksum.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\ipv4\inet_chksum.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ddc393c-8a83-4011-9386-edb46bf00c14</ParentItem>
+      <Property>0fc41b46-7feb-46c9-a457-a5a0a7bf03b6</Property>
+    </Instance>
+    <Instance Guid="6f410e40-0ed4-44e5-8caa-f0f5535c9877">
+      <Name>ip.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\ipv4\ip.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ddc393c-8a83-4011-9386-edb46bf00c14</ParentItem>
+      <Property>06c6a3da-4728-43fa-8fd2-d69dda171152</Property>
+    </Instance>
+    <Instance Guid="bff660ca-c28f-4b65-9388-8aa4a6eacfd5">
+      <Name>ip_addr.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\ipv4\ip_addr.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ddc393c-8a83-4011-9386-edb46bf00c14</ParentItem>
+      <Property>da152663-5aa2-4a8d-b11b-13e2271b151d</Property>
+    </Instance>
+    <Instance Guid="b2269172-b272-40aa-93f1-91de85f71e1b">
+      <Name>ip_frag.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\ipv4\ip_frag.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1ddc393c-8a83-4011-9386-edb46bf00c14</ParentItem>
+      <Property>a6f6208c-f037-4d2e-8345-014e385eeba3</Property>
+    </Instance>
+    <Instance Guid="a32a19d5-7fa1-4712-86fe-b74d30be3b67">
+      <Name>icmp6.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\ipv6\icmp6.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>9a19ae4a-0d29-459e-8ca4-3a599fd2da97</ParentItem>
+      <Property>e010b464-feef-4805-916d-230e4207ddfc</Property>
+    </Instance>
+    <Instance Guid="27a6585c-fd00-46c2-8ffd-cf2b033839b7">
+      <Name>inet6.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\ipv6\inet6.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>9a19ae4a-0d29-459e-8ca4-3a599fd2da97</ParentItem>
+      <Property>b779cf20-fda6-467c-be18-6d34e2445098</Property>
+    </Instance>
+    <Instance Guid="cd5ce58e-37fa-4d93-86c3-907bd16741b0">
+      <Name>ip6.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\ipv6\ip6.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>9a19ae4a-0d29-459e-8ca4-3a599fd2da97</ParentItem>
+      <Property>923d7ddc-7254-427d-b1a8-b2cb4251f0d6</Property>
+    </Instance>
+    <Instance Guid="d3585ac9-0ff2-4676-a631-7667d89ca17d">
+      <Name>ip6_addr.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\ipv6\ip6_addr.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>9a19ae4a-0d29-459e-8ca4-3a599fd2da97</ParentItem>
+      <Property>f5377580-cff4-4ab5-94bb-35cdcc4a3c36</Property>
+    </Instance>
+    <Instance Guid="ccd312a3-5583-4dc7-8aac-a1962b7022b6">
+      <Name>asn1_dec.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\snmp\asn1_dec.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>ad78cf6e-335c-4487-ad7b-e358d8e476ba</ParentItem>
+      <Property>d93afc2b-cda1-4893-a148-7395e10100a7</Property>
+    </Instance>
+    <Instance Guid="95719e8a-a536-4bfb-81d0-b9f39e723dc2">
+      <Name>asn1_enc.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\snmp\asn1_enc.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>ad78cf6e-335c-4487-ad7b-e358d8e476ba</ParentItem>
+      <Property>440a5d70-a58b-4759-a359-ab51ad68ac18</Property>
+    </Instance>
+    <Instance Guid="dc58f692-1303-46ff-9088-5d6f2f4ca5cf">
+      <Name>mib_structs.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\snmp\mib_structs.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>ad78cf6e-335c-4487-ad7b-e358d8e476ba</ParentItem>
+      <Property>e7dc6bcd-a885-4c0a-8680-998dd16bc5cd</Property>
+    </Instance>
+    <Instance Guid="f71665e2-aa59-4914-92b6-fe5b3916b08e">
+      <Name>mib2.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\snmp\mib2.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>ad78cf6e-335c-4487-ad7b-e358d8e476ba</ParentItem>
+      <Property>f202b8f9-410a-4f3d-a62b-ba5e536a5ce6</Property>
+    </Instance>
+    <Instance Guid="e5514c17-b3da-4629-9b16-bbf829cdcadf">
+      <Name>msg_in.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\snmp\msg_in.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>ad78cf6e-335c-4487-ad7b-e358d8e476ba</ParentItem>
+      <Property>24f74281-d001-4c2c-aec8-9f5c67c61092</Property>
+    </Instance>
+    <Instance Guid="c6031625-36e7-45b9-9d90-3838f58e3205">
+      <Name>msg_out.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\core\snmp\msg_out.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>ad78cf6e-335c-4487-ad7b-e358d8e476ba</ParentItem>
+      <Property>2a7359bf-ccff-4c5c-a046-ff029cd59ba9</Property>
+    </Instance>
+    <Instance Guid="b6afb671-48fc-42ed-9d52-1a44a8c11d5a">
+      <Name>ppp</Name>
+      <Type>Category</Type>
+      <ParentItem>11a43ca7-8e6d-408e-a1b3-01bf1fce0fc1</ParentItem>
+      <Property>a847d110-05ed-4499-ac82-e612276601e1</Property>
+    </Instance>
+    <Instance Guid="497fd722-c504-4b88-94d8-078fe882a9b5">
+      <Name>etharp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\etharp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>11a43ca7-8e6d-408e-a1b3-01bf1fce0fc1</ParentItem>
+      <Property>0d36df3a-983b-459f-a6e4-5ddf030f8022</Property>
+    </Instance>
+    <Instance Guid="5ae65c88-f108-4f08-b968-a12d434372b1">
+      <Name>ethernetif.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\ethernetif.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>11a43ca7-8e6d-408e-a1b3-01bf1fce0fc1</ParentItem>
+      <Property>9c013d7a-2d65-42b8-9ec8-4fb8a4451e3e</Property>
+    </Instance>
+    <Instance Guid="b9b76a58-56d8-4a06-85af-5e9669f1c525">
+      <Name>slipif.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\slipif.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>11a43ca7-8e6d-408e-a1b3-01bf1fce0fc1</ParentItem>
+      <Property>16a78ad4-ae58-4520-a118-700ab1babf3a</Property>
+    </Instance>
+    <Instance Guid="be850028-ff7a-4a26-bf90-48908301144e">
+      <Name>auth.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\ppp\auth.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>b6afb671-48fc-42ed-9d52-1a44a8c11d5a</ParentItem>
+      <Property>a6c1a549-72a0-4591-a62d-da36477ee241</Property>
+    </Instance>
+    <Instance Guid="ebc76664-a15d-4f3b-a020-e56371722789">
+      <Name>chap.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\ppp\chap.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>b6afb671-48fc-42ed-9d52-1a44a8c11d5a</ParentItem>
+      <Property>9edf0e29-8a66-44e4-bf5f-0df6442efc8d</Property>
+    </Instance>
+    <Instance Guid="71a28012-ae55-4508-a189-8801c666d42c">
+      <Name>chpms.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\ppp\chpms.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>b6afb671-48fc-42ed-9d52-1a44a8c11d5a</ParentItem>
+      <Property>b0ec9c6b-baf1-4c50-bf13-85f6bbddfac3</Property>
+    </Instance>
+    <Instance Guid="3f2ffd69-75f2-4113-a447-7595b31dabb4">
+      <Name>fsm.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\ppp\fsm.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>b6afb671-48fc-42ed-9d52-1a44a8c11d5a</ParentItem>
+      <Property>edc4db0d-5a5d-4eb2-b534-1136f1c9482d</Property>
+    </Instance>
+    <Instance Guid="b54f32cd-68df-4aca-910f-fb9b4848dd45">
+      <Name>ipcp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\ppp\ipcp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>b6afb671-48fc-42ed-9d52-1a44a8c11d5a</ParentItem>
+      <Property>9699e73b-405c-45f0-af48-a21238216733</Property>
+    </Instance>
+    <Instance Guid="0a609342-dc84-4790-b85e-7e83f6460a40">
+      <Name>lcp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\ppp\lcp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>b6afb671-48fc-42ed-9d52-1a44a8c11d5a</ParentItem>
+      <Property>5188efc5-1158-4ec2-9e45-c247c37fb644</Property>
+    </Instance>
+    <Instance Guid="29cd1675-d97b-43ee-995a-07de9a12c809">
+      <Name>magic.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\ppp\magic.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>b6afb671-48fc-42ed-9d52-1a44a8c11d5a</ParentItem>
+      <Property>62a65bd2-9bac-4359-8230-2247056b264f</Property>
+    </Instance>
+    <Instance Guid="589ecf13-6abd-42b4-98ad-0fa1fbf41784">
+      <Name>md5.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\ppp\md5.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>b6afb671-48fc-42ed-9d52-1a44a8c11d5a</ParentItem>
+      <Property>dea4c788-2010-4947-bb77-c405461e24f8</Property>
+    </Instance>
+    <Instance Guid="5cc41ea4-be5d-449f-9942-fc19150becb9">
+      <Name>pap.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\ppp\pap.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>b6afb671-48fc-42ed-9d52-1a44a8c11d5a</ParentItem>
+      <Property>134f1bb7-8261-4c7b-bd42-befc357a9ef4</Property>
+    </Instance>
+    <Instance Guid="971bab9c-8d2b-4d4b-a745-c4232ac530e2">
+      <Name>ppp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\ppp\ppp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>b6afb671-48fc-42ed-9d52-1a44a8c11d5a</ParentItem>
+      <Property>7da9c135-1d8d-4ec0-93fa-866031a1d40a</Property>
+    </Instance>
+    <Instance Guid="b651ebab-82e3-4d94-9e0d-aee5646044e8">
+      <Name>ppp_oe.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\ppp\ppp_oe.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>b6afb671-48fc-42ed-9d52-1a44a8c11d5a</ParentItem>
+      <Property>ab519702-09c1-4d1c-9968-189389d5f2fb</Property>
+    </Instance>
+    <Instance Guid="39bfb8ee-0c21-46db-bb53-08e9466dde69">
+      <Name>randm.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\ppp\randm.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>b6afb671-48fc-42ed-9d52-1a44a8c11d5a</ParentItem>
+      <Property>034bbaa5-2ebd-4f77-b8ff-6f233605af74</Property>
+    </Instance>
+    <Instance Guid="8c90089a-1122-461e-9773-bc6313c96305">
+      <Name>vj.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\src\netif\ppp\vj.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>b6afb671-48fc-42ed-9d52-1a44a8c11d5a</ParentItem>
+      <Property>3144c8b6-ebbd-4f4a-b8c2-e23e34be9bc9</Property>
+    </Instance>
+  </Class>
+  <Class Guid="fb98844b-2c27-4275-9804-f6e63e204da0">
+    <Instance Guid="fb98844b-2c27-4275-9804-f6e63e204da0">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="0d548289-d5e9-4893-9a8f-9374b13f19a9">
+    <Instance Guid="1553fe25-ea6b-41e5-b0ea-10ff008cf53c">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="91b084d5-a0fc-4c56-a23c-93af25b4d484">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="95674899-740d-4940-b772-cbee83c4c920">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="63d5671a-dd85-48e1-be58-67228180e587">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="da12b667-507d-442a-a74f-f6ddb8c60c28">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="9091b1f6-a525-4392-b9c5-2d3ad83aedf5">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="11f3434b-f761-45b1-bdde-19d3ea6c252b">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="46d4312c-dce7-4b53-bbf8-fc58159c4f42">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="c23ed742-d1ff-45f2-9e2b-0bb99c1a4fe7">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="0478816f-da05-495b-b189-b59fdf9fd317">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="084caeb4-a3d2-4967-a99f-55654f9c889d">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="6fbfd966-b0a1-45fc-b235-c588a11d36ac">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="a0d0d1de-04ad-44e2-86a2-46880c0b3cdb">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="6b751d79-a73e-43ab-bfd7-c8f5b1c1f3fd">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="295198f0-3769-4469-8ec0-b721995ac9e0">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="9e17d71a-073d-48f7-94ba-6f3f266e1b3b">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="6e5ad97c-0fa5-4f34-8124-9699b35e7090">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="6d042040-4643-43df-ba4f-0cb26ae4bf6a">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="c8fc4241-d439-4d2f-a5c1-934239ff5c26">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="15cabe46-3383-4983-8715-f310a348c742">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="1fdee431-6029-4b51-96d5-2304b7d5a2f1">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="fba97ea2-159b-4fff-ac6d-fc01715137c5">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="c7bb081b-9c68-4d36-900d-f1bf17d2c82b">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="c3167cf2-d943-44a3-b4f3-b091ebc2fa15">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="3e702737-028b-4d45-b0b4-398efec9fbb1">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="69637c55-870b-4946-b03b-3dc9443ac313">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="bd8d6765-0ce7-40fc-9317-d15b287ccd1c">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="b4afe9ab-6754-4cd7-aea3-a1e35c292a93">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="b7bfa92c-935a-40dd-b9b4-9ab9b11ffed5">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="f7516879-3a6a-4971-a732-83647bb3c59a">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="0fc41b46-7feb-46c9-a457-a5a0a7bf03b6">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="06c6a3da-4728-43fa-8fd2-d69dda171152">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="da152663-5aa2-4a8d-b11b-13e2271b151d">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="a6f6208c-f037-4d2e-8345-014e385eeba3">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="e010b464-feef-4805-916d-230e4207ddfc">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="b779cf20-fda6-467c-be18-6d34e2445098">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="923d7ddc-7254-427d-b1a8-b2cb4251f0d6">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="f5377580-cff4-4ab5-94bb-35cdcc4a3c36">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="d93afc2b-cda1-4893-a148-7395e10100a7">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="440a5d70-a58b-4759-a359-ab51ad68ac18">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="e7dc6bcd-a885-4c0a-8680-998dd16bc5cd">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="f202b8f9-410a-4f3d-a62b-ba5e536a5ce6">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="24f74281-d001-4c2c-aec8-9f5c67c61092">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="2a7359bf-ccff-4c5c-a046-ff029cd59ba9">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="0d36df3a-983b-459f-a6e4-5ddf030f8022">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="9c013d7a-2d65-42b8-9ec8-4fb8a4451e3e">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="16a78ad4-ae58-4520-a118-700ab1babf3a">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="a6c1a549-72a0-4591-a62d-da36477ee241">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="9edf0e29-8a66-44e4-bf5f-0df6442efc8d">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="b0ec9c6b-baf1-4c50-bf13-85f6bbddfac3">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="edc4db0d-5a5d-4eb2-b534-1136f1c9482d">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="9699e73b-405c-45f0-af48-a21238216733">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="5188efc5-1158-4ec2-9e45-c247c37fb644">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="62a65bd2-9bac-4359-8230-2247056b264f">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="dea4c788-2010-4947-bb77-c405461e24f8">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="134f1bb7-8261-4c7b-bd42-befc357a9ef4">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="7da9c135-1d8d-4ec0-93fa-866031a1d40a">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="ab519702-09c1-4d1c-9968-189389d5f2fb">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="034bbaa5-2ebd-4f77-b8ff-6f233605af74">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="3144c8b6-ebbd-4f4a-b8c2-e23e34be9bc9">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="78a5c5cd-76cb-4bcc-a031-3020011fbc9a">
+    <Instance Guid="932d046d-f082-49f4-a741-7406cd636fa4">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="19fbfcda-ea2b-4da8-9002-8b9f5becaf18">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="bf751ff3-b5c4-4138-ace9-3204ad838d83">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="7830cfcf-5cf0-4ec4-b981-b365345fd4be">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="1ba413f0-3a90-478c-b5ee-054af207d7b8">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="f9bb050d-7da3-4934-a70d-334fbe87464e">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="a847d110-05ed-4499-ac82-e612276601e1">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="8fb9c1f6-d351-4d10-8d99-bf5b3015b84c">
+    <Instance Guid="00000000-0000-0000-0000-000000000000">
+      <UsingPlatformGuid>7020d445-1358-4043-a8ea-3b101e73ceaa</UsingPlatformGuid>
+      <UsingPlatformTypeGuid>f96683fa-8de4-4c6d-a1ab-925d7f232c09</UsingPlatformTypeGuid>
+    </Instance>
+  </Class>
+  <Class Guid="c325714f-8f51-484b-9e96-b4b59c0fb263">
+    <Instance Guid="c325714f-8f51-484b-9e96-b4b59c0fb263">
+      <DeviceManager>0e793ff3-2e3f-43c0-bdc9-926269595403</DeviceManager>
+    </Instance>
+  </Class>
+  <Class Guid="0e793ff3-2e3f-43c0-bdc9-926269595403">
+    <Instance Guid="0e793ff3-2e3f-43c0-bdc9-926269595403">
+      <DataFormatVersion>1.0</DataFormatVersion>
+    </Instance>
+    <Instance Guid="2a81c37a-5015-44c2-9f40-e58b669eec75">
+      <DeviceName>R5F563NBDxFP</DeviceName>
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="873c9a58-9bc5-439a-b476-78629a4553ed">
+    <Instance Guid="873c9a58-9bc5-439a-b476-78629a4553ed">
+      <ProjectDeviceChangedCounter>0</ProjectDeviceChangedCounter>
+      <ProjectInitialDeviceName>R5F563NBDxFP</ProjectInitialDeviceName>
+    </Instance>
+  </Class>
+  <Class Guid="c3835e31-dea3-4c93-b02b-d2db997f7630">
+    <Instance Guid="c3835e31-dea3-4c93-b02b-d2db997f7630">
+      <BuildToolManager>3a79707d-5977-45f7-ac11-19c35e333132</BuildToolManager>
+    </Instance>
+  </Class>
+  <Class Guid="3a79707d-5977-45f7-ac11-19c35e333132">
+    <Instance Guid="3a79707d-5977-45f7-ac11-19c35e333132">
+      <DataFormatVersion>1.2</DataFormatVersion>
+      <BuildModeCount>1</BuildModeCount>
+      <BuildMode0>RABlAGYAYQB1AGwAdABCAHUAaQBsAGQA</BuildMode0>
+      <BatchBuildFlag0>False</BatchBuildFlag0>
+      <CurrentBuildMode>DefaultBuild</CurrentBuildMode>
+      <SourceItemGuid0>866fbc09-7e11-405e-9f0d-92eb78e699be</SourceItemGuid0>
+      <SourceItemType0>CSource</SourceItemType0>
+      <SourceItemGuid1>fb24d4e3-498f-45ef-bdb2-79936c6ddd44</SourceItemGuid1>
+      <SourceItemType1>CSource</SourceItemType1>
+      <SourceItemGuid2>a3674528-00e9-4533-8063-65032b408db3</SourceItemGuid2>
+      <SourceItemType2>CSource</SourceItemType2>
+      <SourceItemGuid3>198fe5f0-554f-4c50-88bc-0e69c1514fcd</SourceItemGuid3>
+      <SourceItemType3>CSource</SourceItemType3>
+      <SourceItemGuid4>0b395f47-da36-416f-9d47-da6d06dc23d1</SourceItemGuid4>
+      <SourceItemType4>CSource</SourceItemType4>
+      <SourceItemGuid5>280687ba-82a3-41a6-a5b4-c7517299fb01</SourceItemGuid5>
+      <SourceItemType5>CSource</SourceItemType5>
+      <SourceItemGuid6>a6ae1533-dfbb-4aec-a09b-f233e6272050</SourceItemGuid6>
+      <SourceItemType6>CSource</SourceItemType6>
+      <SourceItemGuid7>65b2b931-0cca-4612-97fa-2e9a61fc7244</SourceItemGuid7>
+      <SourceItemType7>CSource</SourceItemType7>
+      <SourceItemGuid8>86daecbd-5ecc-4c22-9184-edf543d18d90</SourceItemGuid8>
+      <SourceItemType8>CSource</SourceItemType8>
+      <SourceItemGuid9>31232115-7500-42f7-9874-a16d5b42f4fa</SourceItemGuid9>
+      <SourceItemType9>CSource</SourceItemType9>
+      <SourceItemGuid10>96e1434d-c7a3-45e5-a84b-3a62b10cc5fa</SourceItemGuid10>
+      <SourceItemType10>CSource</SourceItemType10>
+      <SourceItemGuid11>a5721642-ad90-4677-92a2-b4e5b6f6f8dc</SourceItemGuid11>
+      <SourceItemType11>CSource</SourceItemType11>
+      <SourceItemGuid12>4ea6cf6b-b92f-429a-816d-2f9b1fc1db57</SourceItemGuid12>
+      <SourceItemType12>CSource</SourceItemType12>
+      <SourceItemGuid13>62147325-dc74-482f-ae14-fe94400d8cb1</SourceItemGuid13>
+      <SourceItemType13>CSource</SourceItemType13>
+      <SourceItemGuid14>234a83ac-04b7-4cad-8202-e6c9a99ea731</SourceItemGuid14>
+      <SourceItemType14>CSource</SourceItemType14>
+      <SourceItemGuid15>af1e26d9-bfd9-42f8-8a66-d622d9933dd0</SourceItemGuid15>
+      <SourceItemType15>CSource</SourceItemType15>
+      <SourceItemGuid16>ae5848a7-54bb-461f-b5d2-8594e6b66a1e</SourceItemGuid16>
+      <SourceItemType16>CSource</SourceItemType16>
+      <SourceItemGuid17>f2fbf733-f77e-4e17-bc84-e1788e6c00b2</SourceItemGuid17>
+      <SourceItemType17>CSource</SourceItemType17>
+      <SourceItemGuid18>508ee1c5-8d5e-409d-8e3a-004cdac69699</SourceItemGuid18>
+      <SourceItemType18>CSource</SourceItemType18>
+      <SourceItemGuid19>22395ed5-fbe7-46d6-bf5b-8de642b8f2ce</SourceItemGuid19>
+      <SourceItemType19>CSource</SourceItemType19>
+      <SourceItemGuid20>5c452fec-c9da-40e5-8741-8e87293080cb</SourceItemGuid20>
+      <SourceItemType20>CSource</SourceItemType20>
+      <SourceItemGuid21>8b24ed2f-eaa8-4756-9c71-013ba384b1a0</SourceItemGuid21>
+      <SourceItemType21>CSource</SourceItemType21>
+      <SourceItemGuid22>c373deec-64d2-4f42-be96-397d83a08860</SourceItemGuid22>
+      <SourceItemType22>CSource</SourceItemType22>
+      <SourceItemGuid23>6f0f2f1b-dc20-4ad8-a0ff-44cd9873e897</SourceItemGuid23>
+      <SourceItemType23>CSource</SourceItemType23>
+      <SourceItemGuid24>5b6c5f18-4b13-45d1-9a95-7c487cfb010b</SourceItemGuid24>
+      <SourceItemType24>CSource</SourceItemType24>
+      <SourceItemGuid25>803f7136-a524-471c-a96d-38dde2b30e71</SourceItemGuid25>
+      <SourceItemType25>CSource</SourceItemType25>
+      <SourceItemGuid26>eeb7cf38-60e7-4f9e-8c5d-37e42f95dcee</SourceItemGuid26>
+      <SourceItemType26>CSource</SourceItemType26>
+      <SourceItemGuid27>67b54e87-a62c-4b30-9029-f01dcf4d76cb</SourceItemGuid27>
+      <SourceItemType27>CSource</SourceItemType27>
+      <SourceItemGuid28>b65d2ea2-f59a-43b4-bf04-36a6d80e1e96</SourceItemGuid28>
+      <SourceItemType28>CSource</SourceItemType28>
+      <SourceItemGuid29>e01a0e44-98a1-43e9-baa4-a4fcd6009616</SourceItemGuid29>
+      <SourceItemType29>CSource</SourceItemType29>
+      <SourceItemGuid30>5f87b41c-932f-442c-af8d-952b33c37066</SourceItemGuid30>
+      <SourceItemType30>CSource</SourceItemType30>
+      <SourceItemGuid31>6f410e40-0ed4-44e5-8caa-f0f5535c9877</SourceItemGuid31>
+      <SourceItemType31>CSource</SourceItemType31>
+      <SourceItemGuid32>bff660ca-c28f-4b65-9388-8aa4a6eacfd5</SourceItemGuid32>
+      <SourceItemType32>CSource</SourceItemType32>
+      <SourceItemGuid33>b2269172-b272-40aa-93f1-91de85f71e1b</SourceItemGuid33>
+      <SourceItemType33>CSource</SourceItemType33>
+      <SourceItemGuid34>a32a19d5-7fa1-4712-86fe-b74d30be3b67</SourceItemGuid34>
+      <SourceItemType34>CSource</SourceItemType34>
+      <SourceItemGuid35>27a6585c-fd00-46c2-8ffd-cf2b033839b7</SourceItemGuid35>
+      <SourceItemType35>CSource</SourceItemType35>
+      <SourceItemGuid36>cd5ce58e-37fa-4d93-86c3-907bd16741b0</SourceItemGuid36>
+      <SourceItemType36>CSource</SourceItemType36>
+      <SourceItemGuid37>d3585ac9-0ff2-4676-a631-7667d89ca17d</SourceItemGuid37>
+      <SourceItemType37>CSource</SourceItemType37>
+      <SourceItemGuid38>ccd312a3-5583-4dc7-8aac-a1962b7022b6</SourceItemGuid38>
+      <SourceItemType38>CSource</SourceItemType38>
+      <SourceItemGuid39>95719e8a-a536-4bfb-81d0-b9f39e723dc2</SourceItemGuid39>
+      <SourceItemType39>CSource</SourceItemType39>
+      <SourceItemGuid40>dc58f692-1303-46ff-9088-5d6f2f4ca5cf</SourceItemGuid40>
+      <SourceItemType40>CSource</SourceItemType40>
+      <SourceItemGuid41>f71665e2-aa59-4914-92b6-fe5b3916b08e</SourceItemGuid41>
+      <SourceItemType41>CSource</SourceItemType41>
+      <SourceItemGuid42>e5514c17-b3da-4629-9b16-bbf829cdcadf</SourceItemGuid42>
+      <SourceItemType42>CSource</SourceItemType42>
+      <SourceItemGuid43>c6031625-36e7-45b9-9d90-3838f58e3205</SourceItemGuid43>
+      <SourceItemType43>CSource</SourceItemType43>
+      <SourceItemGuid44>497fd722-c504-4b88-94d8-078fe882a9b5</SourceItemGuid44>
+      <SourceItemType44>CSource</SourceItemType44>
+      <SourceItemGuid45>5ae65c88-f108-4f08-b968-a12d434372b1</SourceItemGuid45>
+      <SourceItemType45>CSource</SourceItemType45>
+      <SourceItemGuid46>b9b76a58-56d8-4a06-85af-5e9669f1c525</SourceItemGuid46>
+      <SourceItemType46>CSource</SourceItemType46>
+      <SourceItemGuid47>be850028-ff7a-4a26-bf90-48908301144e</SourceItemGuid47>
+      <SourceItemType47>CSource</SourceItemType47>
+      <SourceItemGuid48>ebc76664-a15d-4f3b-a020-e56371722789</SourceItemGuid48>
+      <SourceItemType48>CSource</SourceItemType48>
+      <SourceItemGuid49>71a28012-ae55-4508-a189-8801c666d42c</SourceItemGuid49>
+      <SourceItemType49>CSource</SourceItemType49>
+      <SourceItemGuid50>3f2ffd69-75f2-4113-a447-7595b31dabb4</SourceItemGuid50>
+      <SourceItemType50>CSource</SourceItemType50>
+      <SourceItemGuid51>b54f32cd-68df-4aca-910f-fb9b4848dd45</SourceItemGuid51>
+      <SourceItemType51>CSource</SourceItemType51>
+      <SourceItemGuid52>0a609342-dc84-4790-b85e-7e83f6460a40</SourceItemGuid52>
+      <SourceItemType52>CSource</SourceItemType52>
+      <SourceItemGuid53>29cd1675-d97b-43ee-995a-07de9a12c809</SourceItemGuid53>
+      <SourceItemType53>CSource</SourceItemType53>
+      <SourceItemGuid54>589ecf13-6abd-42b4-98ad-0fa1fbf41784</SourceItemGuid54>
+      <SourceItemType54>CSource</SourceItemType54>
+      <SourceItemGuid55>5cc41ea4-be5d-449f-9942-fc19150becb9</SourceItemGuid55>
+      <SourceItemType55>CSource</SourceItemType55>
+      <SourceItemGuid56>971bab9c-8d2b-4d4b-a745-c4232ac530e2</SourceItemGuid56>
+      <SourceItemType56>CSource</SourceItemType56>
+      <SourceItemGuid57>b651ebab-82e3-4d94-9e0d-aee5646044e8</SourceItemGuid57>
+      <SourceItemType57>CSource</SourceItemType57>
+      <SourceItemGuid58>39bfb8ee-0c21-46db-bb53-08e9466dde69</SourceItemGuid58>
+      <SourceItemType58>CSource</SourceItemType58>
+      <SourceItemGuid59>8c90089a-1122-461e-9773-bc6313c96305</SourceItemGuid59>
+      <SourceItemType59>CSource</SourceItemType59>
+      <SourceItemCount>60</SourceItemCount>
+      <LastDeviceChangedCounter>0</LastDeviceChangedCounter>
+    </Instance>
+    <Instance Guid="9e208646-ccba-4100-a676-29b1efe6545f">
+      <AsmOptionInclude-DefaultValue />
+      <BuildMode-DefaultValue>DefaultBuild</BuildMode-DefaultValue>
+      <COptionInclude-DefaultValue />
+      <GeneralOptionIsa-DefaultValue>RXv1</GeneralOptionIsa-DefaultValue>
+      <GeneralOptionOutput-DefaultValue>LibraryFile</GeneralOptionOutput-DefaultValue>
+      <GeneralOptionPic-DefaultValue>False</GeneralOptionPic-DefaultValue>
+      <GeneralOptionSimultaneousBuild-DefaultValue>True</GeneralOptionSimultaneousBuild-DefaultValue>
+      <HexOptionOutput-DefaultValue>True</HexOptionOutput-DefaultValue>
+      <LibOptionDebug-DefaultValue>Debug</LibOptionDebug-DefaultValue>
+      <LinkOptionLibrary-DefaultValue />
+      <Memo-DefaultValue />
+      <OutputMessageFormat-DefaultValue>%TargetFiles%</OutputMessageFormat-DefaultValue>
+      <AsmOptionSystemInclude-DefaultValue />
+      <COptionSystemInclude-DefaultValue />
+      <CompilerVersion-DefaultValue>
+
+0</CompilerVersion-DefaultValue>
+      <DependencyFileExistCheckingType-DefaultValue>Rebuild</DependencyFileExistCheckingType-DefaultValue>
+      <FormatBuildOptionList-DefaultValue>%TargetFiles% : %Program% %Options%</FormatBuildOptionList-DefaultValue>
+      <GeneralOptionCpu-DefaultValue>RX600</GeneralOptionCpu-DefaultValue>
+      <GeneralOptionOutputFolder-DefaultValue>%BuildModeName%</GeneralOptionOutputFolder-DefaultValue>
+      <GeneralOptionPid-DefaultValue>None</GeneralOptionPid-DefaultValue>
+      <HexOptionForm-DefaultValue>Stype</HexOptionForm-DefaultValue>
+      <LinkOptionDebug-DefaultValue>Debug</LinkOptionDebug-DefaultValue>
+      <AsmOptionDefine-DefaultValue />
+      <COptionDefine-DefaultValue />
+      <EnsureCompatibilityOfPathAndLinkageOrder-DefaultValue>False</EnsureCompatibilityOfPathAndLinkageOrder-DefaultValue>
+      <GeneralOptionFpu-DefaultValue>Fpu</GeneralOptionFpu-DefaultValue>
+      <GeneralOptionNousePidRegister-DefaultValue>True</GeneralOptionNousePidRegister-DefaultValue>
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionOptimize-DefaultValue>None</LinkOptionOptimize-DefaultValue>
+      <AsmOptionDebug-DefaultValue>True</AsmOptionDebug-DefaultValue>
+      <COptionDebug-DefaultValue>True</COptionDebug-DefaultValue>
+      <GeneralOptionEndian-DefaultValue>Little</GeneralOptionEndian-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionOptimizeSymbolDelete-DefaultValue>False</LinkOptionOptimizeSymbolDelete-DefaultValue>
+      <PreBuildCommands-DefaultValue />
+      <AsmOptionGoptimize-DefaultValue>False</AsmOptionGoptimize-DefaultValue>
+      <COptionOptimize-DefaultValue>Level2</COptionOptimize-DefaultValue>
+      <GeneralOptionRound-DefaultValue>Nearest</GeneralOptionRound-DefaultValue>
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionOptimizeSameCode-DefaultValue>False</LinkOptionOptimizeSameCode-DefaultValue>
+      <PostBuildCommands-DefaultValue />
+      <AsmOptionListFile-DefaultValue>False</AsmOptionListFile-DefaultValue>
+      <COptionGoptimize-DefaultValue>False</COptionGoptimize-DefaultValue>
+      <GeneralOptionDenormalize-DefaultValue>Off</GeneralOptionDenormalize-DefaultValue>
+      <LinkOptionSameSize-DefaultValue>1E</LinkOptionSameSize-DefaultValue>
+      <AsmOptionShowConditionals-DefaultValue>False</AsmOptionShowConditionals-DefaultValue>
+      <COptionSpeedAndSize-DefaultValue>Size</COptionSpeedAndSize-DefaultValue>
+      <GeneralOptionDblSize-DefaultValue>SinglePrecision</GeneralOptionDblSize-DefaultValue>
+      <LinkOptionOptimizeShortFormat-DefaultValue>False</LinkOptionOptimizeShortFormat-DefaultValue>
+      <AsmOptionShowDefinitions-DefaultValue>False</AsmOptionShowDefinitions-DefaultValue>
+      <COptionListfile-DefaultValue>False</COptionListfile-DefaultValue>
+      <GeneralOptionIntToShort-DefaultValue>False</GeneralOptionIntToShort-DefaultValue>
+      <LinkOptionOptimizeBranch-DefaultValue>False</LinkOptionOptimizeBranch-DefaultValue>
+      <AsmOptionShowExpansions-DefaultValue>False</AsmOptionShowExpansions-DefaultValue>
+      <COptionShowSource-DefaultValue>False</COptionShowSource-DefaultValue>
+      <GeneralOptionSignedChar-DefaultValue>Unsigned</GeneralOptionSignedChar-DefaultValue>
+      <LinkOptionStart-DefaultValue />
+      <COptionShowConditionals-DefaultValue>False</COptionShowConditionals-DefaultValue>
+      <GeneralOptionOtherAdditionalOptions-DefaultValue />
+      <GeneralOptionSignedBitfield-DefaultValue>Unsigned</GeneralOptionSignedBitfield-DefaultValue>
+      <COptionShowDefinitions-DefaultValue>False</COptionShowDefinitions-DefaultValue>
+      <GeneralOptionAutoEnum-DefaultValue>False</GeneralOptionAutoEnum-DefaultValue>
+      <COptionShowExpansions-DefaultValue>False</COptionShowExpansions-DefaultValue>
+      <GeneralOptionBitOrder-DefaultValue>Right</GeneralOptionBitOrder-DefaultValue>
+      <GeneralOptionPack-DefaultValue>False</GeneralOptionPack-DefaultValue>
+      <GeneralOptionException-DefaultValue>False</GeneralOptionException-DefaultValue>
+      <GeneralOptionRtti-DefaultValue>False</GeneralOptionRtti-DefaultValue>
+      <GeneralOptionFintRegister-DefaultValue>None</GeneralOptionFintRegister-DefaultValue>
+      <GeneralOptionBranch-DefaultValue>Branch24</GeneralOptionBranch-DefaultValue>
+      <GeneralOptionBaseRomRegister-DefaultValue>None</GeneralOptionBaseRomRegister-DefaultValue>
+      <GeneralOptionBaseRamRegister-DefaultValue>None</GeneralOptionBaseRamRegister-DefaultValue>
+      <GeneralOptionBaseAddressAddress-DefaultValue>00000000</GeneralOptionBaseAddressAddress-DefaultValue>
+      <GeneralOptionBaseAddressRegister-DefaultValue>None</GeneralOptionBaseAddressRegister-DefaultValue>
+      <GeneralOptionPatch-DefaultValue>None</GeneralOptionPatch-DefaultValue>
+      <GeneralOptionSaveAcc-DefaultValue>False</GeneralOptionSaveAcc-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587442585497125989</TimeTagModified--0>
+      <BuildMode-0>DefaultBuild</BuildMode-0>
+      <Memo-0 />
+      <OutputMessageFormat-0>%TargetFiles%</OutputMessageFormat-0>
+      <FormatBuildOptionList-0>%TargetFiles% : %Program% %Options%</FormatBuildOptionList-0>
+      <PreBuildCommands-0 />
+      <PostBuildCommands-0 />
+      <GeneralOptionIsa-0>RXv1</GeneralOptionIsa-0>
+      <GeneralOptionOutput-0>LibraryFile</GeneralOptionOutput-0>
+      <GeneralOptionPic-0>False</GeneralOptionPic-0>
+      <GeneralOptionSimultaneousBuild-0>True</GeneralOptionSimultaneousBuild-0>
+      <CompilerVersion-0>
+
+0</CompilerVersion-0>
+      <DependencyFileExistCheckingType-0>Rebuild</DependencyFileExistCheckingType-0>
+      <GeneralOptionCpu-0>RX600</GeneralOptionCpu-0>
+      <GeneralOptionOutputFolder-0>%BuildModeName%</GeneralOptionOutputFolder-0>
+      <GeneralOptionPid-0>None</GeneralOptionPid-0>
+      <EnsureCompatibilityOfPathAndLinkageOrder-0>False</EnsureCompatibilityOfPathAndLinkageOrder-0>
+      <GeneralOptionFpu-0>Fpu</GeneralOptionFpu-0>
+      <GeneralOptionNousePidRegister-0>True</GeneralOptionNousePidRegister-0>
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <GeneralOptionEndian-0>Little</GeneralOptionEndian-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <AsmOptionGoptimize-0>False</AsmOptionGoptimize-0>
+      <GeneralOptionRound-0>Nearest</GeneralOptionRound-0>
+      <LinkOptionMultiConvertFileName-0 />
+      <AsmOptionListFile-0>False</AsmOptionListFile-0>
+      <COptionGoptimize-0>False</COptionGoptimize-0>
+      <GeneralOptionDenormalize-0>Off</GeneralOptionDenormalize-0>
+      <AsmOptionShowConditionals-0>False</AsmOptionShowConditionals-0>
+      <GeneralOptionDblSize-0>SinglePrecision</GeneralOptionDblSize-0>
+      <AsmOptionShowDefinitions-0>False</AsmOptionShowDefinitions-0>
+      <COptionListfile-0>False</COptionListfile-0>
+      <GeneralOptionIntToShort-0>False</GeneralOptionIntToShort-0>
+      <AsmOptionShowExpansions-0>False</AsmOptionShowExpansions-0>
+      <COptionShowSource-0>False</COptionShowSource-0>
+      <GeneralOptionSignedChar-0>Unsigned</GeneralOptionSignedChar-0>
+      <COptionShowConditionals-0>False</COptionShowConditionals-0>
+      <GeneralOptionOtherAdditionalOptions-0 />
+      <GeneralOptionSignedBitfield-0>Unsigned</GeneralOptionSignedBitfield-0>
+      <COptionShowDefinitions-0>False</COptionShowDefinitions-0>
+      <GeneralOptionAutoEnum-0>False</GeneralOptionAutoEnum-0>
+      <COptionShowExpansions-0>False</COptionShowExpansions-0>
+      <GeneralOptionBitOrder-0>Right</GeneralOptionBitOrder-0>
+      <GeneralOptionPack-0>False</GeneralOptionPack-0>
+      <GeneralOptionException-0>False</GeneralOptionException-0>
+      <GeneralOptionRtti-0>False</GeneralOptionRtti-0>
+      <GeneralOptionFintRegister-0>None</GeneralOptionFintRegister-0>
+      <GeneralOptionBranch-0>Branch24</GeneralOptionBranch-0>
+      <GeneralOptionBaseRomRegister-0>None</GeneralOptionBaseRomRegister-0>
+      <GeneralOptionBaseRamRegister-0>None</GeneralOptionBaseRamRegister-0>
+      <GeneralOptionBaseAddressAddress-0>00000000</GeneralOptionBaseAddressAddress-0>
+      <GeneralOptionBaseAddressRegister-0>None</GeneralOptionBaseAddressRegister-0>
+      <GeneralOptionPatch-0>None</GeneralOptionPatch-0>
+      <GeneralOptionSaveAcc-0>False</GeneralOptionSaveAcc-0>
+      <LastCompilerVersion-0>V2.02.00</LastCompilerVersion-0>
+    </Instance>
+    <Instance Guid="95a63257-4aa7-40c0-a74a-7991543b099b">
+      <COptionLangC-DefaultValue>C</COptionLangC-DefaultValue>
+      <COptionListfile-DefaultValue>False</COptionListfile-DefaultValue>
+      <COptionLogo-DefaultValue>False</COptionLogo-DefaultValue>
+      <COptionMisra2004-DefaultValue>None</COptionMisra2004-DefaultValue>
+      <COptionOptimize-DefaultValue>Level2</COptionOptimize-DefaultValue>
+      <COptionOutput-DefaultValue>Object</COptionOutput-DefaultValue>
+      <COptionOutputAssembly-DefaultValue>False</COptionOutputAssembly-DefaultValue>
+      <COptionGoptimize-DefaultValue>False</COptionGoptimize-DefaultValue>
+      <COptionLangCpp-DefaultValue>Cpp</COptionLangCpp-DefaultValue>
+      <COptionMisra2004RuleFile-DefaultValue />
+      <COptionOutputFolder-DefaultValue>%BuildModeName%</COptionOutputFolder-DefaultValue>
+      <COptionOutputPreprocessed-DefaultValue>None</COptionOutputPreprocessed-DefaultValue>
+      <COptionShowSource-DefaultValue>False</COptionShowSource-DefaultValue>
+      <COptionXcref-DefaultValue>False</COptionXcref-DefaultValue>
+      <COptionDebug-DefaultValue>True</COptionDebug-DefaultValue>
+      <COptionInclude-DefaultValue />
+      <COptionMisra2004RuleNumberApply-DefaultValue />
+      <COptionPreCompileCommands-DefaultValue />
+      <COptionShowConditionals-DefaultValue>False</COptionShowConditionals-DefaultValue>
+      <COptionSpeedAndSize-DefaultValue>Size</COptionSpeedAndSize-DefaultValue>
+      <COptionLoop-DefaultValue>Auto</COptionLoop-DefaultValue>
+      <COptionMisra2004RuleNumberIgnore-DefaultValue />
+      <COptionPostCompileCommands-DefaultValue />
+      <COptionSectionP-DefaultValue>P</COptionSectionP-DefaultValue>
+      <COptionShowDefinitions-DefaultValue>False</COptionShowDefinitions-DefaultValue>
+      <COptionSystemInclude-DefaultValue />
+      <COptionLoopValue-DefaultValue>2</COptionLoopValue-DefaultValue>
+      <COptionMisra2004RuleNumberRequiredAdd-DefaultValue />
+      <COptionOtherAdditionalOptions-DefaultValue />
+      <COptionPreinclude-DefaultValue />
+      <COptionSectionC-DefaultValue>C</COptionSectionC-DefaultValue>
+      <COptionShowExpansions-DefaultValue>False</COptionShowExpansions-DefaultValue>
+      <COptionCommandLine-DefaultValue>-isa=rxv1
+-fpu
+-include=..\..\lwip-1.4.1\src\include
+-include=..\..\lwip-1.4.1\src\include\ipv4
+-include=..\..\lwip-1.4.1\ports\asp_dcre
+-include=..\..\asp_dcre\include
+-include=..\..\asp_dcre\arch
+-include=..\..\asp_dcre\target\grsakura_ccrx
+-include=..\..\fatfs
+-include=..\..\tlsf-3.0
+-include=..\..\lwip-1.4.1\ports\grsakura
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</COptionCommandLine-DefaultValue>
+      <COptionDefine-DefaultValue />
+      <COptionInline-DefaultValue>Auto</COptionInline-DefaultValue>
+      <COptionMisra2004RuleNumberRequiredRemove-DefaultValue />
+      <COptionSectionD-DefaultValue>D</COptionSectionD-DefaultValue>
+      <COptionIgnoreFilesMisra-DefaultValue />
+      <COptionInlineValue-DefaultValue>100</COptionInlineValue-DefaultValue>
+      <COptionSectionB-DefaultValue>B</COptionSectionB-DefaultValue>
+      <COptionUndefine-DefaultValue />
+      <COptionCheckLanguageExtension-DefaultValue>False</COptionCheckLanguageExtension-DefaultValue>
+      <COptionFileInline-DefaultValue />
+      <COptionMessage-DefaultValue>False</COptionMessage-DefaultValue>
+      <COptionSectionL-DefaultValue>L</COptionSectionL-DefaultValue>
+      <COptionCase-DefaultValue>Auto</COptionCase-DefaultValue>
+      <COptionMessage2-DefaultValue>False</COptionMessage2-DefaultValue>
+      <COptionSectionW-DefaultValue>W</COptionSectionW-DefaultValue>
+      <COptionNoMessageErrorNumber-DefaultValue />
+      <COptionNostuffB-DefaultValue>False</COptionNostuffB-DefaultValue>
+      <COptionVolatile-DefaultValue>False</COptionVolatile-DefaultValue>
+      <COptionConstCopy-DefaultValue>Auto</COptionConstCopy-DefaultValue>
+      <COptionNoMessageErrorNumber2-DefaultValue />
+      <COptionNostuffD-DefaultValue>False</COptionNostuffD-DefaultValue>
+      <COptionChangeMessageInformation-DefaultValue>No</COptionChangeMessageInformation-DefaultValue>
+      <COptionConstDiv-DefaultValue>Auto</COptionConstDiv-DefaultValue>
+      <COptionNostuffC-DefaultValue>False</COptionNostuffC-DefaultValue>
+      <COptionChangeMessageInformationNumber-DefaultValue />
+      <COptionLibrary-DefaultValue>Intrinsic</COptionLibrary-DefaultValue>
+      <COptionNostuffW-DefaultValue>False</COptionNostuffW-DefaultValue>
+      <COptionChangeMessageInformationNumber2-DefaultValue />
+      <COptionInstalign-DefaultValue>Noinstalign</COptionInstalign-DefaultValue>
+      <COptionScope-DefaultValue>Auto</COptionScope-DefaultValue>
+      <COptionChangeMessageWarning-DefaultValue>No</COptionChangeMessageWarning-DefaultValue>
+      <COptionNouseDiv-DefaultValue>True</COptionNouseDiv-DefaultValue>
+      <COptionSchedule-DefaultValue>Auto</COptionSchedule-DefaultValue>
+      <COptionChangeMessageWarningNumber-DefaultValue />
+      <COptionMap-DefaultValue>NoMap</COptionMap-DefaultValue>
+      <COptionOutcode-DefaultValue>Sjis</COptionOutcode-DefaultValue>
+      <COptionChangeMessageWarningNumber2-DefaultValue />
+      <COptionIntermodule-DefaultValue>None</COptionIntermodule-DefaultValue>
+      <COptionApproxdiv-DefaultValue>False</COptionApproxdiv-DefaultValue>
+      <COptionChangeMessageError-DefaultValue>No</COptionChangeMessageError-DefaultValue>
+      <COptionChangeMessageErrorNumber-DefaultValue />
+      <COptionEnableRegister-DefaultValue>False</COptionEnableRegister-DefaultValue>
+      <COptionChangeMessageErrorNumber2-DefaultValue />
+      <COptionSimpleFloatConv-DefaultValue>False</COptionSimpleFloatConv-DefaultValue>
+      <COptionFileInlinePath-DefaultValue />
+      <COptionFpu-DefaultValue>Fpu</COptionFpu-DefaultValue>
+      <COptionAlias-DefaultValue>False</COptionAlias-DefaultValue>
+      <COptionComment-DefaultValue>False</COptionComment-DefaultValue>
+      <COptionCheck-DefaultValue>No</COptionCheck-DefaultValue>
+      <COptionFloatOrder-DefaultValue>False</COptionFloatOrder-DefaultValue>
+      <COptionIncode-DefaultValue>Sjis</COptionIncode-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587457385261885853</TimeTagModified--0>
+      <COptionLangC-0>C99</COptionLangC-0>
+      <COptionListfile-0>False</COptionListfile-0>
+      <COptionLogo-0>False</COptionLogo-0>
+      <COptionMisra2004-0>None</COptionMisra2004-0>
+      <COptionOptimize-0>Level2</COptionOptimize-0>
+      <COptionOutput-0>Object</COptionOutput-0>
+      <COptionOutputAssembly-0>False</COptionOutputAssembly-0>
+      <COptionGoptimize-0>False</COptionGoptimize-0>
+      <COptionLangCpp-0>Cpp</COptionLangCpp-0>
+      <COptionMisra2004RuleFile-0 />
+      <COptionOutputFolder-0>%BuildModeName%</COptionOutputFolder-0>
+      <COptionOutputPreprocessed-0>None</COptionOutputPreprocessed-0>
+      <COptionShowSource-0>False</COptionShowSource-0>
+      <COptionXcref-0>False</COptionXcref-0>
+      <COptionDebug-0>True</COptionDebug-0>
+      <COptionInclude-0>..\..\lwip-1.4.1\src\include
+..\..\lwip-1.4.1\src\include\ipv4
+..\..\lwip-1.4.1\ports\ccrx
+..\..\lwip-1.4.1\ports\asp_dcre
+..\..\asp_dcre\include
+..\..\asp_dcre\arch
+..\..\asp_dcre\target\grsakura_ccrx
+..\..\fatfs
+..\..\tlsf-3.0
+..\..\lwip-1.4.1\ports\grsakura
+</COptionInclude-0>
+      <COptionMisra2004RuleNumberApply-0 />
+      <COptionPreCompileCommands-0 />
+      <COptionShowConditionals-0>False</COptionShowConditionals-0>
+      <COptionSpeedAndSize-0>Size</COptionSpeedAndSize-0>
+      <COptionLoop-0>Auto</COptionLoop-0>
+      <COptionMisra2004RuleNumberIgnore-0 />
+      <COptionPostCompileCommands-0 />
+      <COptionSectionP-0>P</COptionSectionP-0>
+      <COptionShowDefinitions-0>False</COptionShowDefinitions-0>
+      <COptionSystemInclude-0 />
+      <COptionLoopValue-0>2</COptionLoopValue-0>
+      <COptionMisra2004RuleNumberRequiredAdd-0 />
+      <COptionOtherAdditionalOptions-0 />
+      <COptionPreinclude-0 />
+      <COptionSectionC-0>C</COptionSectionC-0>
+      <COptionShowExpansions-0>False</COptionShowExpansions-0>
+      <COptionCommandLine-0>-isa=rxv1
+-fpu
+-include=..\..\lwip-1.4.1\src\include
+-include=..\..\lwip-1.4.1\src\include\ipv4
+-include=..\..\lwip-1.4.1\ports\asp_dcre
+-include=..\..\asp_dcre\include
+-include=..\..\asp_dcre\arch
+-include=..\..\asp_dcre\target\grsakura_ccrx
+-include=..\..\fatfs
+-include=..\..\tlsf-3.0
+-include=..\..\lwip-1.4.1\ports\grsakura
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</COptionCommandLine-0>
+      <COptionDefine-0 />
+      <COptionInline-0>Auto</COptionInline-0>
+      <COptionMisra2004RuleNumberRequiredRemove-0 />
+      <COptionSectionD-0>D</COptionSectionD-0>
+      <COptionIgnoreFilesMisra-0 />
+      <COptionInlineValue-0>100</COptionInlineValue-0>
+      <COptionSectionB-0>B</COptionSectionB-0>
+      <COptionUndefine-0 />
+      <COptionCheckLanguageExtension-0>False</COptionCheckLanguageExtension-0>
+      <COptionFileInline-0 />
+      <COptionMessage-0>False</COptionMessage-0>
+      <COptionSectionL-0>L</COptionSectionL-0>
+      <COptionCase-0>Auto</COptionCase-0>
+      <COptionSectionW-0>W</COptionSectionW-0>
+      <COptionNoMessageErrorNumber-0 />
+      <COptionNostuffB-0>False</COptionNostuffB-0>
+      <COptionVolatile-0>False</COptionVolatile-0>
+      <COptionConstCopy-0>Auto</COptionConstCopy-0>
+      <COptionNostuffD-0>False</COptionNostuffD-0>
+      <COptionChangeMessageInformation-0>No</COptionChangeMessageInformation-0>
+      <COptionConstDiv-0>Auto</COptionConstDiv-0>
+      <COptionNostuffC-0>False</COptionNostuffC-0>
+      <COptionChangeMessageInformationNumber-0 />
+      <COptionLibrary-0>Intrinsic</COptionLibrary-0>
+      <COptionNostuffW-0>False</COptionNostuffW-0>
+      <COptionInstalign-0>Noinstalign</COptionInstalign-0>
+      <COptionScope-0>Auto</COptionScope-0>
+      <COptionChangeMessageWarning-0>No</COptionChangeMessageWarning-0>
+      <COptionNouseDiv-0>True</COptionNouseDiv-0>
+      <COptionSchedule-0>Auto</COptionSchedule-0>
+      <COptionChangeMessageWarningNumber-0 />
+      <COptionMap-0>NoMap</COptionMap-0>
+      <COptionOutcode-0>Sjis</COptionOutcode-0>
+      <COptionIntermodule-0>None</COptionIntermodule-0>
+      <COptionApproxdiv-0>False</COptionApproxdiv-0>
+      <COptionChangeMessageError-0>No</COptionChangeMessageError-0>
+      <COptionChangeMessageErrorNumber-0 />
+      <COptionEnableRegister-0>False</COptionEnableRegister-0>
+      <COptionSimpleFloatConv-0>False</COptionSimpleFloatConv-0>
+      <COptionFileInlinePath-0 />
+      <COptionFpu-0>Fpu</COptionFpu-0>
+      <COptionAlias-0>False</COptionAlias-0>
+      <COptionComment-0>False</COptionComment-0>
+      <COptionCheck-0>No</COptionCheck-0>
+      <COptionFloatOrder-0>False</COptionFloatOrder-0>
+      <COptionIncode-0>Sjis</COptionIncode-0>
+    </Instance>
+    <Instance Guid="5ad1746c-d03e-4610-a91f-aaa4fb37bc10">
+      <AsmOptionChkpm-DefaultValue>False</AsmOptionChkpm-DefaultValue>
+      <AsmOptionGoptimize-DefaultValue>False</AsmOptionGoptimize-DefaultValue>
+      <AsmOptionInclude-DefaultValue />
+      <AsmOptionListFile-DefaultValue>False</AsmOptionListFile-DefaultValue>
+      <AsmOptionOutput-DefaultValue>%BuildModeName%</AsmOptionOutput-DefaultValue>
+      <AsmOptionChkfpu-DefaultValue>False</AsmOptionChkfpu-DefaultValue>
+      <AsmOptionDebug-DefaultValue>True</AsmOptionDebug-DefaultValue>
+      <AsmOptionShowConditionals-DefaultValue>False</AsmOptionShowConditionals-DefaultValue>
+      <AsmOptionSystemInclude-DefaultValue />
+      <AsmOptionChkdsp-DefaultValue>False</AsmOptionChkdsp-DefaultValue>
+      <AsmOptionDefine-DefaultValue />
+      <AsmOptionShowDefinitions-DefaultValue>False</AsmOptionShowDefinitions-DefaultValue>
+      <AsmOptionInCode-DefaultValue>SJIS</AsmOptionInCode-DefaultValue>
+      <AsmOptionLogo-DefaultValue>False</AsmOptionLogo-DefaultValue>
+      <AsmOptionShowExpansions-DefaultValue>False</AsmOptionShowExpansions-DefaultValue>
+      <AsmOptionPreAssembleCommands-DefaultValue />
+      <AsmOptionPostAssembleCommands-DefaultValue />
+      <AsmOptionOtherAdditionalOptions-DefaultValue />
+      <AsmOptionCommandLine-DefaultValue />
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587490433519350633</TimeTagModified--0>
+      <AsmOptionChkpm-0>False</AsmOptionChkpm-0>
+      <AsmOptionGoptimize-0>False</AsmOptionGoptimize-0>
+      <AsmOptionInclude-0 />
+      <AsmOptionListFile-0>False</AsmOptionListFile-0>
+      <AsmOptionOutput-0>%BuildModeName%</AsmOptionOutput-0>
+      <AsmOptionChkfpu-0>False</AsmOptionChkfpu-0>
+      <AsmOptionDebug-0>True</AsmOptionDebug-0>
+      <AsmOptionShowConditionals-0>False</AsmOptionShowConditionals-0>
+      <AsmOptionSystemInclude-0 />
+      <AsmOptionChkdsp-0>False</AsmOptionChkdsp-0>
+      <AsmOptionDefine-0 />
+      <AsmOptionShowDefinitions-0>False</AsmOptionShowDefinitions-0>
+      <AsmOptionInCode-0>SJIS</AsmOptionInCode-0>
+      <AsmOptionLogo-0>False</AsmOptionLogo-0>
+      <AsmOptionShowExpansions-0>False</AsmOptionShowExpansions-0>
+      <AsmOptionPreAssembleCommands-0 />
+      <AsmOptionPostAssembleCommands-0 />
+      <AsmOptionOtherAdditionalOptions-0 />
+      <AsmOptionCommandLine-0 />
+    </Instance>
+    <Instance Guid="dbb16727-3e81-4169-956a-790355cab4a1">
+      <LinkOptionCpu-DefaultValue>False</LinkOptionCpu-DefaultValue>
+      <LinkOptionForm-DefaultValue>Absolute</LinkOptionForm-DefaultValue>
+      <LinkOptionFormConvert-DefaultValue>Stype</LinkOptionFormConvert-DefaultValue>
+      <LinkOptionInput-DefaultValue />
+      <LinkOptionListShow-DefaultValue>None</LinkOptionListShow-DefaultValue>
+      <LinkOptionOptimize-DefaultValue>None</LinkOptionOptimize-DefaultValue>
+      <LinkOptionStack-DefaultValue>False</LinkOptionStack-DefaultValue>
+      <LinkOptionStart-DefaultValue />
+      <LinkOptionCompress-DefaultValue>False</LinkOptionCompress-DefaultValue>
+      <LinkOptionCpuInformation-DefaultValue />
+      <LinkOptionDebug-DefaultValue>Debug</LinkOptionDebug-DefaultValue>
+      <LinkOptionFSymbol-DefaultValue />
+      <LinkOptionLibrary-DefaultValue />
+      <LinkOptionOptimizeSymbolDelete-DefaultValue>False</LinkOptionOptimizeSymbolDelete-DefaultValue>
+      <LinkOptionRecordH-DefaultValue>None</LinkOptionRecordH-DefaultValue>
+      <LinkOptionShowSymbol-DefaultValue>False</LinkOptionShowSymbol-DefaultValue>
+      <LinkOptionAlignedSection-DefaultValue />
+      <LinkOptionCpuStride-DefaultValue>False</LinkOptionCpuStride-DefaultValue>
+      <LinkOptionMemory-DefaultValue>False</LinkOptionMemory-DefaultValue>
+      <LinkOptionOptimizeSameCode-DefaultValue>False</LinkOptionOptimizeSameCode-DefaultValue>
+      <LinkOptionOutputFolder-DefaultValue>%BuildModeName%</LinkOptionOutputFolder-DefaultValue>
+      <LinkOptionRecordS-DefaultValue>None</LinkOptionRecordS-DefaultValue>
+      <LinkOptionShowReference-DefaultValue>False</LinkOptionShowReference-DefaultValue>
+      <LinkOptionSystemLibrary-DefaultValue />
+      <LinkOptionBinary-DefaultValue />
+      <LinkOptionChangeMessageInformation-DefaultValue>None</LinkOptionChangeMessageInformation-DefaultValue>
+      <LinkOptionContiguousSection-DefaultValue />
+      <LinkOptionDividedConvertFile-DefaultValue>False</LinkOptionDividedConvertFile-DefaultValue>
+      <LinkOptionOutputFileName-DefaultValue>%ProjectName%.abs</LinkOptionOutputFileName-DefaultValue>
+      <LinkOptionRom-DefaultValue />
+      <LinkOptionSameSize-DefaultValue>1E</LinkOptionSameSize-DefaultValue>
+      <LinkOptionShowXreference-DefaultValue>False</LinkOptionShowXreference-DefaultValue>
+      <LinkOptionChangeMessageInformationNumber-DefaultValue />
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionDefine-DefaultValue />
+      <LinkOptionMap-DefaultValue>False</LinkOptionMap-DefaultValue>
+      <LinkOptionOptimizeShortFormat-DefaultValue>False</LinkOptionOptimizeShortFormat-DefaultValue>
+      <LinkOptionShowTotalSize-DefaultValue>False</LinkOptionShowTotalSize-DefaultValue>
+      <LinkOptionChangeMessageWarning-DefaultValue>None</LinkOptionChangeMessageWarning-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionEntry-DefaultValue>False</LinkOptionEntry-DefaultValue>
+      <LinkOptionMessage-DefaultValue>NoMessage</LinkOptionMessage-DefaultValue>
+      <LinkOptionOptimizeBranch-DefaultValue>False</LinkOptionOptimizeBranch-DefaultValue>
+      <LinkOptionShowVector-DefaultValue>False</LinkOptionShowVector-DefaultValue>
+      <LinkOptionChangeMessageWarningNumber-DefaultValue />
+      <LinkOptionEntryPoint-DefaultValue />
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionNoMessageErrorNumber-DefaultValue />
+      <LinkOptionSymbolForbid-DefaultValue />
+      <LinkOptionChangeMessageError-DefaultValue>None</LinkOptionChangeMessageError-DefaultValue>
+      <LinkOptionNoPrelink-DefaultValue>Auto</LinkOptionNoPrelink-DefaultValue>
+      <LinkOptionPadding-DefaultValue>False</LinkOptionPadding-DefaultValue>
+      <LinkOptionSameCodeForbid-DefaultValue />
+      <LinkOptionSpace-DefaultValue>None</LinkOptionSpace-DefaultValue>
+      <LinkOptionChangeMessageErrorNumber-DefaultValue />
+      <LinkOptionSectionForbid-DefaultValue />
+      <LinkOptionSpaceValue-DefaultValue>FF</LinkOptionSpaceValue-DefaultValue>
+      <LinkOptionVectN-DefaultValue />
+      <LinkOptionAbsoluteForbid-DefaultValue />
+      <LinkOptionByteCount-DefaultValue>False</LinkOptionByteCount-DefaultValue>
+      <LinkOptionHide-DefaultValue>False</LinkOptionHide-DefaultValue>
+      <LinkOptionVect-DefaultValue />
+      <LinkOptionByteCountValue-DefaultValue>FF</LinkOptionByteCountValue-DefaultValue>
+      <LinkOptionJumpEntriesForPic-DefaultValue>False</LinkOptionJumpEntriesForPic-DefaultValue>
+      <LinkOptionTotalSize-DefaultValue>False</LinkOptionTotalSize-DefaultValue>
+      <LinkOptionCrc-DefaultValue>None</LinkOptionCrc-DefaultValue>
+      <LinkOptionJumpEntriesForPicSectionName-DefaultValue />
+      <LinkOptionLogo-DefaultValue>False</LinkOptionLogo-DefaultValue>
+      <LinkOptionCrcOutputAddress-DefaultValue>0</LinkOptionCrcOutputAddress-DefaultValue>
+      <LinkOptionPreLinkCommands-DefaultValue />
+      <LinkOptionCrcCalculationRange-DefaultValue />
+      <LinkOptionPostLinkCommands-DefaultValue />
+      <LinkOptionOtherAdditionalOptionsForLoadModule-DefaultValue />
+      <LinkOptionS9-DefaultValue>False</LinkOptionS9-DefaultValue>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-DefaultValue />
+      <LinkOptionCommandLine-DefaultValue />
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587490430307228235</TimeTagModified--0>
+      <LinkOptionCpu-0>False</LinkOptionCpu-0>
+      <LinkOptionForm-0>Absolute</LinkOptionForm-0>
+      <LinkOptionFormConvert-0>Stype</LinkOptionFormConvert-0>
+      <LinkOptionInput-0 />
+      <LinkOptionListShow-0>None</LinkOptionListShow-0>
+      <LinkOptionOptimize-0>None</LinkOptionOptimize-0>
+      <LinkOptionStack-0>False</LinkOptionStack-0>
+      <LinkOptionStart-0 />
+      <LinkOptionCompress-0>False</LinkOptionCompress-0>
+      <LinkOptionCpuInformation-0 />
+      <LinkOptionDebug-0>Debug</LinkOptionDebug-0>
+      <LinkOptionFSymbol-0 />
+      <LinkOptionLibrary-0 />
+      <LinkOptionOptimizeSymbolDelete-0>False</LinkOptionOptimizeSymbolDelete-0>
+      <LinkOptionRecordH-0>None</LinkOptionRecordH-0>
+      <LinkOptionShowSymbol-0>False</LinkOptionShowSymbol-0>
+      <LinkOptionAlignedSection-0 />
+      <LinkOptionCpuStride-0>False</LinkOptionCpuStride-0>
+      <LinkOptionMemory-0>False</LinkOptionMemory-0>
+      <LinkOptionOptimizeSameCode-0>False</LinkOptionOptimizeSameCode-0>
+      <LinkOptionOutputFolder-0>%BuildModeName%</LinkOptionOutputFolder-0>
+      <LinkOptionRecordS-0>None</LinkOptionRecordS-0>
+      <LinkOptionShowReference-0>False</LinkOptionShowReference-0>
+      <LinkOptionSystemLibrary-0 />
+      <LinkOptionBinary-0 />
+      <LinkOptionChangeMessageInformation-0>None</LinkOptionChangeMessageInformation-0>
+      <LinkOptionContiguousSection-0 />
+      <LinkOptionDividedConvertFile-0>False</LinkOptionDividedConvertFile-0>
+      <LinkOptionOutputFileName-0>%ProjectName%.abs</LinkOptionOutputFileName-0>
+      <LinkOptionRom-0 />
+      <LinkOptionSameSize-0>1E</LinkOptionSameSize-0>
+      <LinkOptionShowXreference-0>False</LinkOptionShowXreference-0>
+      <LinkOptionChangeMessageInformationNumber-0 />
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <LinkOptionDefine-0 />
+      <LinkOptionMap-0>False</LinkOptionMap-0>
+      <LinkOptionOptimizeShortFormat-0>False</LinkOptionOptimizeShortFormat-0>
+      <LinkOptionShowTotalSize-0>False</LinkOptionShowTotalSize-0>
+      <LinkOptionChangeMessageWarning-0>None</LinkOptionChangeMessageWarning-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <LinkOptionEntry-0>False</LinkOptionEntry-0>
+      <LinkOptionMessage-0>NoMessage</LinkOptionMessage-0>
+      <LinkOptionOptimizeBranch-0>False</LinkOptionOptimizeBranch-0>
+      <LinkOptionShowVector-0>False</LinkOptionShowVector-0>
+      <LinkOptionChangeMessageWarningNumber-0 />
+      <LinkOptionEntryPoint-0 />
+      <LinkOptionMultiConvertFileName-0 />
+      <LinkOptionNoMessageErrorNumber-0 />
+      <LinkOptionSymbolForbid-0 />
+      <LinkOptionChangeMessageError-0>None</LinkOptionChangeMessageError-0>
+      <LinkOptionNoPrelink-0>Auto</LinkOptionNoPrelink-0>
+      <LinkOptionPadding-0>False</LinkOptionPadding-0>
+      <LinkOptionSameCodeForbid-0 />
+      <LinkOptionSpace-0>None</LinkOptionSpace-0>
+      <LinkOptionChangeMessageErrorNumber-0 />
+      <LinkOptionSectionForbid-0 />
+      <LinkOptionSpaceValue-0>FF</LinkOptionSpaceValue-0>
+      <LinkOptionVectN-0 />
+      <LinkOptionAbsoluteForbid-0 />
+      <LinkOptionByteCount-0>False</LinkOptionByteCount-0>
+      <LinkOptionHide-0>False</LinkOptionHide-0>
+      <LinkOptionVect-0 />
+      <LinkOptionByteCountValue-0>FF</LinkOptionByteCountValue-0>
+      <LinkOptionJumpEntriesForPic-0>False</LinkOptionJumpEntriesForPic-0>
+      <LinkOptionTotalSize-0>False</LinkOptionTotalSize-0>
+      <LinkOptionCrc-0>None</LinkOptionCrc-0>
+      <LinkOptionJumpEntriesForPicSectionName-0 />
+      <LinkOptionLogo-0>False</LinkOptionLogo-0>
+      <LinkOptionCrcOutputAddress-0>0</LinkOptionCrcOutputAddress-0>
+      <LinkOptionPreLinkCommands-0 />
+      <LinkOptionCrcCalculationRange-0 />
+      <LinkOptionPostLinkCommands-0 />
+      <LinkOptionOtherAdditionalOptionsForLoadModule-0 />
+      <LinkOptionS9-0>False</LinkOptionS9-0>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-0 />
+      <LinkOptionCommandLine-0 />
+    </Instance>
+    <Instance Guid="df74c69e-635e-42d9-845e-14128ba4d48a">
+      <HexOptionForm-DefaultValue>Stype</HexOptionForm-DefaultValue>
+      <HexOptionOutput-DefaultValue>True</HexOptionOutput-DefaultValue>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-DefaultValue />
+      <HexOptionCommandLine-DefaultValue />
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionRecordH-DefaultValue>None</LinkOptionRecordH-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionRecordS-DefaultValue>None</LinkOptionRecordS-DefaultValue>
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionSpace-DefaultValue>None</LinkOptionSpace-DefaultValue>
+      <LinkOptionSpaceValue-DefaultValue>FF</LinkOptionSpaceValue-DefaultValue>
+      <LinkOptionByteCount-DefaultValue>False</LinkOptionByteCount-DefaultValue>
+      <LinkOptionByteCountValue-DefaultValue>FF</LinkOptionByteCountValue-DefaultValue>
+      <LinkOptionCrc-DefaultValue>None</LinkOptionCrc-DefaultValue>
+      <LinkOptionCrcOutputAddress-DefaultValue>0</LinkOptionCrcOutputAddress-DefaultValue>
+      <LinkOptionCrcCalculationRange-DefaultValue />
+      <LinkOptionS9-DefaultValue>False</LinkOptionS9-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587490433519150637</TimeTagModified--0>
+      <HexOptionForm-0>Stype</HexOptionForm-0>
+      <HexOptionOutput-0>True</HexOptionOutput-0>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-0 />
+      <HexOptionCommandLine-0 />
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <LinkOptionRecordH-0>None</LinkOptionRecordH-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <LinkOptionRecordS-0>None</LinkOptionRecordS-0>
+      <LinkOptionMultiConvertFileName-0 />
+      <LinkOptionSpace-0>None</LinkOptionSpace-0>
+      <LinkOptionSpaceValue-0>FF</LinkOptionSpaceValue-0>
+      <LinkOptionByteCount-0>False</LinkOptionByteCount-0>
+      <LinkOptionByteCountValue-0>FF</LinkOptionByteCountValue-0>
+      <LinkOptionCrc-0>None</LinkOptionCrc-0>
+      <LinkOptionCrcOutputAddress-0>0</LinkOptionCrcOutputAddress-0>
+      <LinkOptionCrcCalculationRange-0 />
+      <LinkOptionS9-0>False</LinkOptionS9-0>
+    </Instance>
+    <Instance Guid="fff50d2e-74da-44ea-90a8-c47756029e83">
+      <LibOptionForm-DefaultValue>LibraryU</LibOptionForm-DefaultValue>
+      <LibOptionInput-DefaultValue />
+      <LibOptionListShow-DefaultValue>List</LibOptionListShow-DefaultValue>
+      <LibOptionMemory-DefaultValue>False</LibOptionMemory-DefaultValue>
+      <LibOptionChangeMessageInformation-DefaultValue>None</LibOptionChangeMessageInformation-DefaultValue>
+      <LibOptionDebug-DefaultValue>Debug</LibOptionDebug-DefaultValue>
+      <LibOptionLibrary-DefaultValue />
+      <LibOptionShowSymbol-DefaultValue>False</LibOptionShowSymbol-DefaultValue>
+      <LibOptionChangeMessageInformationNumber-DefaultValue />
+      <LibOptionOutputFolder-DefaultValue>%BuildModeName%</LibOptionOutputFolder-DefaultValue>
+      <LibOptionShowSection-DefaultValue>False</LibOptionShowSection-DefaultValue>
+      <LibOptionSystemLibrary-DefaultValue />
+      <LibOptionBinary-DefaultValue />
+      <LibOptionChangeMessageWarning-DefaultValue>None</LibOptionChangeMessageWarning-DefaultValue>
+      <LibOptionOutputFileName-DefaultValue>%ProjectName%.lib</LibOptionOutputFileName-DefaultValue>
+      <LibOptionShowXreference-DefaultValue>False</LibOptionShowXreference-DefaultValue>
+      <LibOptionChangeMessageWarningNumber-DefaultValue />
+      <LibOptionMessage-DefaultValue>NoMessage</LibOptionMessage-DefaultValue>
+      <LibOptionNoPrelink-DefaultValue>Auto</LibOptionNoPrelink-DefaultValue>
+      <LibOptionShowTotalSize-DefaultValue>False</LibOptionShowTotalSize-DefaultValue>
+      <LibOptionChangeMessageError-DefaultValue>None</LibOptionChangeMessageError-DefaultValue>
+      <LibOptionNoMessageErrorNumber-DefaultValue />
+      <LibOptionShowVector-DefaultValue>False</LibOptionShowVector-DefaultValue>
+      <LibOptionChangeMessageErrorNumber-DefaultValue />
+      <LibOptionHide-DefaultValue>False</LibOptionHide-DefaultValue>
+      <LibOptionTotalSize-DefaultValue>False</LibOptionTotalSize-DefaultValue>
+      <LibOptionLogo-DefaultValue>False</LibOptionLogo-DefaultValue>
+      <LibOptionPreLibrarianCommands-DefaultValue />
+      <LibOptionPostLibrarianCommands-DefaultValue />
+      <LibOptionOtherAdditionalOptions-DefaultValue />
+      <LibOptionCommandLine-DefaultValue />
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587490433519150637</TimeTagModified--0>
+      <LibOptionForm-0>LibraryU</LibOptionForm-0>
+      <LibOptionInput-0 />
+      <LibOptionListShow-0>List</LibOptionListShow-0>
+      <LibOptionMemory-0>False</LibOptionMemory-0>
+      <LibOptionChangeMessageInformation-0>None</LibOptionChangeMessageInformation-0>
+      <LibOptionDebug-0>Debug</LibOptionDebug-0>
+      <LibOptionLibrary-0 />
+      <LibOptionShowSymbol-0>False</LibOptionShowSymbol-0>
+      <LibOptionChangeMessageInformationNumber-0 />
+      <LibOptionOutputFolder-0>%BuildModeName%</LibOptionOutputFolder-0>
+      <LibOptionShowSection-0>False</LibOptionShowSection-0>
+      <LibOptionSystemLibrary-0 />
+      <LibOptionBinary-0 />
+      <LibOptionChangeMessageWarning-0>None</LibOptionChangeMessageWarning-0>
+      <LibOptionOutputFileName-0>%ProjectName%.lib</LibOptionOutputFileName-0>
+      <LibOptionShowXreference-0>False</LibOptionShowXreference-0>
+      <LibOptionChangeMessageWarningNumber-0 />
+      <LibOptionMessage-0>NoMessage</LibOptionMessage-0>
+      <LibOptionNoPrelink-0>Auto</LibOptionNoPrelink-0>
+      <LibOptionShowTotalSize-0>False</LibOptionShowTotalSize-0>
+      <LibOptionChangeMessageError-0>None</LibOptionChangeMessageError-0>
+      <LibOptionNoMessageErrorNumber-0 />
+      <LibOptionShowVector-0>False</LibOptionShowVector-0>
+      <LibOptionChangeMessageErrorNumber-0 />
+      <LibOptionHide-0>False</LibOptionHide-0>
+      <LibOptionTotalSize-0>False</LibOptionTotalSize-0>
+      <LibOptionLogo-0>False</LibOptionLogo-0>
+      <LibOptionPreLibrarianCommands-0 />
+      <LibOptionPostLibrarianCommands-0 />
+      <LibOptionOtherAdditionalOptions-0 />
+      <LibOptionCommandLine-0 />
+    </Instance>
+    <Instance Guid="9cb0ade0-b3cb-4e21-823c-290b5fdb5f1e">
+      <LbgOptionLanguage-DefaultValue>C</LbgOptionLanguage-DefaultValue>
+      <LbgOptionLibraryMode-DefaultValue>None</LbgOptionLibraryMode-DefaultValue>
+      <LbgOptionLogo-DefaultValue>False</LbgOptionLogo-DefaultValue>
+      <LbgOptionOptimize-DefaultValue>Level2</LbgOptionOptimize-DefaultValue>
+      <LbgOptionOutputFolder-DefaultValue>%BuildModeName%</LbgOptionOutputFolder-DefaultValue>
+      <LbgOptionGoptimize-DefaultValue>False</LbgOptionGoptimize-DefaultValue>
+      <LbgOptionHead-DefaultValue>Custom</LbgOptionHead-DefaultValue>
+      <LbgOptionOutputFileName-DefaultValue>%ProjectName%.lib</LbgOptionOutputFileName-DefaultValue>
+      <LbgOptionPreLibraryGenerateCommands-DefaultValue />
+      <LbgOptionFunctionalCutdown-DefaultValue>None</LbgOptionFunctionalCutdown-DefaultValue>
+      <LbgOptionHeadRuntime-DefaultValue>True</LbgOptionHeadRuntime-DefaultValue>
+      <LbgOptionPostLibraryGenerateCommands-DefaultValue />
+      <LbgOptionSpeedAndSize-DefaultValue>Size</LbgOptionSpeedAndSize-DefaultValue>
+      <LbgOptionHeadCtypeH-DefaultValue>False</LbgOptionHeadCtypeH-DefaultValue>
+      <LbgOptionLoop-DefaultValue>Auto</LbgOptionLoop-DefaultValue>
+      <LbgOptionOtherAdditionalOptions-DefaultValue />
+      <LbgOptionReent-DefaultValue>False</LbgOptionReent-DefaultValue>
+      <LbgOptionCommandLine-DefaultValue />
+      <LbgOptionHeadMathH-DefaultValue>False</LbgOptionHeadMathH-DefaultValue>
+      <LbgOptionLoopValue-DefaultValue>2</LbgOptionLoopValue-DefaultValue>
+      <LbgOptionSectionP-DefaultValue>P</LbgOptionSectionP-DefaultValue>
+      <LbgOptionHeadMathfH-DefaultValue>False</LbgOptionHeadMathfH-DefaultValue>
+      <LbgOptionInline-DefaultValue>Auto</LbgOptionInline-DefaultValue>
+      <LbgOptionSectionC-DefaultValue>C</LbgOptionSectionC-DefaultValue>
+      <LbgOptionHeadStdargH-DefaultValue>False</LbgOptionHeadStdargH-DefaultValue>
+      <LbgOptionInlineValue-DefaultValue>100</LbgOptionInlineValue-DefaultValue>
+      <LbgOptionSectionD-DefaultValue>D</LbgOptionSectionD-DefaultValue>
+      <LbgOptionFileInline-DefaultValue />
+      <LbgOptionHeadStdioH-DefaultValue>True</LbgOptionHeadStdioH-DefaultValue>
+      <LbgOptionSectionB-DefaultValue>B</LbgOptionSectionB-DefaultValue>
+      <LbgOptionCase-DefaultValue>Auto</LbgOptionCase-DefaultValue>
+      <LbgOptionHeadStdlibH-DefaultValue>True</LbgOptionHeadStdlibH-DefaultValue>
+      <LbgOptionSectionL-DefaultValue>L</LbgOptionSectionL-DefaultValue>
+      <LbgOptionHeadStringH-DefaultValue>True</LbgOptionHeadStringH-DefaultValue>
+      <LbgOptionSectionW-DefaultValue>W</LbgOptionSectionW-DefaultValue>
+      <LbgOptionVolatile-DefaultValue>False</LbgOptionVolatile-DefaultValue>
+      <LbgOptionConstCopy-DefaultValue>Auto</LbgOptionConstCopy-DefaultValue>
+      <LbgOptionHeadIos-DefaultValue>False</LbgOptionHeadIos-DefaultValue>
+      <LbgOptionNostuffB-DefaultValue>False</LbgOptionNostuffB-DefaultValue>
+      <LbgOptionConstDiv-DefaultValue>Auto</LbgOptionConstDiv-DefaultValue>
+      <LbgOptionHeadNew-DefaultValue>True</LbgOptionHeadNew-DefaultValue>
+      <LbgOptionNostuffD-DefaultValue>False</LbgOptionNostuffD-DefaultValue>
+      <LbgOptionHeadComplex-DefaultValue>False</LbgOptionHeadComplex-DefaultValue>
+      <LbgOptionLibrary-DefaultValue>Intrinsic</LbgOptionLibrary-DefaultValue>
+      <LbgOptionNostuffC-DefaultValue>False</LbgOptionNostuffC-DefaultValue>
+      <LbgOptionHeadString-DefaultValue>False</LbgOptionHeadString-DefaultValue>
+      <LbgOptionNostuffW-DefaultValue>False</LbgOptionNostuffW-DefaultValue>
+      <LbgOptionScope-DefaultValue>Auto</LbgOptionScope-DefaultValue>
+      <LbgOptionHeadComplexH-DefaultValue>False</LbgOptionHeadComplexH-DefaultValue>
+      <LbgOptionInstalign-DefaultValue>Noinstalign</LbgOptionInstalign-DefaultValue>
+      <LbgOptionSchedule-DefaultValue>Auto</LbgOptionSchedule-DefaultValue>
+      <LbgOptionApproxdiv-DefaultValue>False</LbgOptionApproxdiv-DefaultValue>
+      <LbgOptionHeadFenvH-DefaultValue>False</LbgOptionHeadFenvH-DefaultValue>
+      <LbgOptionNouseDiv-DefaultValue>True</LbgOptionNouseDiv-DefaultValue>
+      <LbgOptionEnableRegister-DefaultValue>False</LbgOptionEnableRegister-DefaultValue>
+      <LbgOptionHeadInttypesH-DefaultValue>False</LbgOptionHeadInttypesH-DefaultValue>
+      <LbgOptionHeadWcharH-DefaultValue>False</LbgOptionHeadWcharH-DefaultValue>
+      <LbgOptionSimpleFloatConv-DefaultValue>False</LbgOptionSimpleFloatConv-DefaultValue>
+      <LbgOptionFpu-DefaultValue>Fpu</LbgOptionFpu-DefaultValue>
+      <LbgOptionHeadWctypeH-DefaultValue>False</LbgOptionHeadWctypeH-DefaultValue>
+      <LbgOptionFloatOrder-DefaultValue>False</LbgOptionFloatOrder-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587490430307228235</TimeTagModified--0>
+      <LbgOptionLanguage-0>C</LbgOptionLanguage-0>
+      <LbgOptionLibraryMode-0>None</LbgOptionLibraryMode-0>
+      <LbgOptionLogo-0>False</LbgOptionLogo-0>
+      <LbgOptionOptimize-0>Level2</LbgOptionOptimize-0>
+      <LbgOptionOutputFolder-0>%BuildModeName%</LbgOptionOutputFolder-0>
+      <LbgOptionGoptimize-0>False</LbgOptionGoptimize-0>
+      <LbgOptionHead-0>Custom</LbgOptionHead-0>
+      <LbgOptionOutputFileName-0>%ProjectName%.lib</LbgOptionOutputFileName-0>
+      <LbgOptionPreLibraryGenerateCommands-0 />
+      <LbgOptionFunctionalCutdown-0>None</LbgOptionFunctionalCutdown-0>
+      <LbgOptionPostLibraryGenerateCommands-0 />
+      <LbgOptionSpeedAndSize-0>Size</LbgOptionSpeedAndSize-0>
+      <LbgOptionHeadCtypeH-0>False</LbgOptionHeadCtypeH-0>
+      <LbgOptionLoop-0>Auto</LbgOptionLoop-0>
+      <LbgOptionOtherAdditionalOptions-0 />
+      <LbgOptionReent-0>False</LbgOptionReent-0>
+      <LbgOptionCommandLine-0 />
+      <LbgOptionHeadMathH-0>False</LbgOptionHeadMathH-0>
+      <LbgOptionLoopValue-0>2</LbgOptionLoopValue-0>
+      <LbgOptionSectionP-0>P</LbgOptionSectionP-0>
+      <LbgOptionHeadMathfH-0>False</LbgOptionHeadMathfH-0>
+      <LbgOptionInline-0>Auto</LbgOptionInline-0>
+      <LbgOptionSectionC-0>C</LbgOptionSectionC-0>
+      <LbgOptionHeadStdargH-0>False</LbgOptionHeadStdargH-0>
+      <LbgOptionInlineValue-0>100</LbgOptionInlineValue-0>
+      <LbgOptionSectionD-0>D</LbgOptionSectionD-0>
+      <LbgOptionFileInline-0 />
+      <LbgOptionHeadStdioH-0>True</LbgOptionHeadStdioH-0>
+      <LbgOptionSectionB-0>B</LbgOptionSectionB-0>
+      <LbgOptionCase-0>Auto</LbgOptionCase-0>
+      <LbgOptionHeadStdlibH-0>True</LbgOptionHeadStdlibH-0>
+      <LbgOptionSectionL-0>L</LbgOptionSectionL-0>
+      <LbgOptionHeadStringH-0>True</LbgOptionHeadStringH-0>
+      <LbgOptionSectionW-0>W</LbgOptionSectionW-0>
+      <LbgOptionVolatile-0>False</LbgOptionVolatile-0>
+      <LbgOptionConstCopy-0>Auto</LbgOptionConstCopy-0>
+      <LbgOptionHeadIos-0>False</LbgOptionHeadIos-0>
+      <LbgOptionNostuffB-0>False</LbgOptionNostuffB-0>
+      <LbgOptionConstDiv-0>Auto</LbgOptionConstDiv-0>
+      <LbgOptionHeadNew-0>True</LbgOptionHeadNew-0>
+      <LbgOptionNostuffD-0>False</LbgOptionNostuffD-0>
+      <LbgOptionHeadComplex-0>False</LbgOptionHeadComplex-0>
+      <LbgOptionLibrary-0>Intrinsic</LbgOptionLibrary-0>
+      <LbgOptionNostuffC-0>False</LbgOptionNostuffC-0>
+      <LbgOptionHeadString-0>False</LbgOptionHeadString-0>
+      <LbgOptionNostuffW-0>False</LbgOptionNostuffW-0>
+      <LbgOptionScope-0>Auto</LbgOptionScope-0>
+      <LbgOptionHeadComplexH-0>False</LbgOptionHeadComplexH-0>
+      <LbgOptionInstalign-0>Noinstalign</LbgOptionInstalign-0>
+      <LbgOptionSchedule-0>Auto</LbgOptionSchedule-0>
+      <LbgOptionApproxdiv-0>False</LbgOptionApproxdiv-0>
+      <LbgOptionHeadFenvH-0>False</LbgOptionHeadFenvH-0>
+      <LbgOptionNouseDiv-0>True</LbgOptionNouseDiv-0>
+      <LbgOptionEnableRegister-0>False</LbgOptionEnableRegister-0>
+      <LbgOptionHeadInttypesH-0>False</LbgOptionHeadInttypesH-0>
+      <LbgOptionHeadWcharH-0>False</LbgOptionHeadWcharH-0>
+      <LbgOptionSimpleFloatConv-0>False</LbgOptionSimpleFloatConv-0>
+      <LbgOptionFpu-0>Fpu</LbgOptionFpu-0>
+      <LbgOptionHeadWctypeH-0>False</LbgOptionHeadWctypeH-0>
+      <LbgOptionFloatOrder-0>False</LbgOptionFloatOrder-0>
+    </Instance>
+    <Instance Guid="a3674528-00e9-4533-8063-65032b408db3">
+      <ItemAddTime>635881928453222821</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="198fe5f0-554f-4c50-88bc-0e69c1514fcd">
+      <ItemAddTime>635881928453222821</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="0b395f47-da36-416f-9d47-da6d06dc23d1">
+      <ItemAddTime>635881928453222821</ItemAddTime>
+      <ItemAddTimeCount>2</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="280687ba-82a3-41a6-a5b4-c7517299fb01">
+      <ItemAddTime>635881928453222821</ItemAddTime>
+      <ItemAddTimeCount>3</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a6ae1533-dfbb-4aec-a09b-f233e6272050">
+      <ItemAddTime>635881928453222821</ItemAddTime>
+      <ItemAddTimeCount>4</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="65b2b931-0cca-4612-97fa-2e9a61fc7244">
+      <ItemAddTime>635881928453222821</ItemAddTime>
+      <ItemAddTimeCount>5</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="86daecbd-5ecc-4c22-9184-edf543d18d90">
+      <ItemAddTime>635881928453222821</ItemAddTime>
+      <ItemAddTimeCount>6</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="31232115-7500-42f7-9874-a16d5b42f4fa">
+      <ItemAddTime>635881928453222821</ItemAddTime>
+      <ItemAddTimeCount>7</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="96e1434d-c7a3-45e5-a84b-3a62b10cc5fa">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a5721642-ad90-4677-92a2-b4e5b6f6f8dc">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="4ea6cf6b-b92f-429a-816d-2f9b1fc1db57">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>2</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="62147325-dc74-482f-ae14-fe94400d8cb1">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>3</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="234a83ac-04b7-4cad-8202-e6c9a99ea731">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>4</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="af1e26d9-bfd9-42f8-8a66-d622d9933dd0">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>5</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="ae5848a7-54bb-461f-b5d2-8594e6b66a1e">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>6</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f2fbf733-f77e-4e17-bc84-e1788e6c00b2">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>7</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="508ee1c5-8d5e-409d-8e3a-004cdac69699">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>8</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="22395ed5-fbe7-46d6-bf5b-8de642b8f2ce">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>9</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="5c452fec-c9da-40e5-8741-8e87293080cb">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>10</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="8b24ed2f-eaa8-4756-9c71-013ba384b1a0">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>11</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="c373deec-64d2-4f42-be96-397d83a08860">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>12</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="6f0f2f1b-dc20-4ad8-a0ff-44cd9873e897">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>13</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="5b6c5f18-4b13-45d1-9a95-7c487cfb010b">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>14</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="803f7136-a524-471c-a96d-38dde2b30e71">
+      <ItemAddTime>635881929231267265</ItemAddTime>
+      <ItemAddTimeCount>15</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="eeb7cf38-60e7-4f9e-8c5d-37e42f95dcee">
+      <ItemAddTime>635881929419063509</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="67b54e87-a62c-4b30-9029-f01dcf4d76cb">
+      <ItemAddTime>635881929419063509</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="b65d2ea2-f59a-43b4-bf04-36a6d80e1e96">
+      <ItemAddTime>635881929419063509</ItemAddTime>
+      <ItemAddTimeCount>2</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="e01a0e44-98a1-43e9-baa4-a4fcd6009616">
+      <ItemAddTime>635881929419063509</ItemAddTime>
+      <ItemAddTimeCount>3</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="5f87b41c-932f-442c-af8d-952b33c37066">
+      <ItemAddTime>635881929419063509</ItemAddTime>
+      <ItemAddTimeCount>4</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="6f410e40-0ed4-44e5-8caa-f0f5535c9877">
+      <ItemAddTime>635881929419063509</ItemAddTime>
+      <ItemAddTimeCount>5</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="bff660ca-c28f-4b65-9388-8aa4a6eacfd5">
+      <ItemAddTime>635881929419063509</ItemAddTime>
+      <ItemAddTimeCount>6</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="b2269172-b272-40aa-93f1-91de85f71e1b">
+      <ItemAddTime>635881929419063509</ItemAddTime>
+      <ItemAddTimeCount>7</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a32a19d5-7fa1-4712-86fe-b74d30be3b67">
+      <ItemAddTime>635881929555860773</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="27a6585c-fd00-46c2-8ffd-cf2b033839b7">
+      <ItemAddTime>635881929555860773</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="cd5ce58e-37fa-4d93-86c3-907bd16741b0">
+      <ItemAddTime>635881929555860773</ItemAddTime>
+      <ItemAddTimeCount>2</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d3585ac9-0ff2-4676-a631-7667d89ca17d">
+      <ItemAddTime>635881929555860773</ItemAddTime>
+      <ItemAddTimeCount>3</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="ccd312a3-5583-4dc7-8aac-a1962b7022b6">
+      <ItemAddTime>635881929741657057</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="95719e8a-a536-4bfb-81d0-b9f39e723dc2">
+      <ItemAddTime>635881929741657057</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="dc58f692-1303-46ff-9088-5d6f2f4ca5cf">
+      <ItemAddTime>635881929741657057</ItemAddTime>
+      <ItemAddTimeCount>2</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f71665e2-aa59-4914-92b6-fe5b3916b08e">
+      <ItemAddTime>635881929741657057</ItemAddTime>
+      <ItemAddTimeCount>3</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="e5514c17-b3da-4629-9b16-bbf829cdcadf">
+      <ItemAddTime>635881929741657057</ItemAddTime>
+      <ItemAddTimeCount>4</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="c6031625-36e7-45b9-9d90-3838f58e3205">
+      <ItemAddTime>635881929741657057</ItemAddTime>
+      <ItemAddTimeCount>5</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="497fd722-c504-4b88-94d8-078fe882a9b5">
+      <ItemAddTime>635881929966453384</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="5ae65c88-f108-4f08-b968-a12d434372b1">
+      <ItemAddTime>635881929966453384</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="b9b76a58-56d8-4a06-85af-5e9669f1c525">
+      <ItemAddTime>635881929966453384</ItemAddTime>
+      <ItemAddTimeCount>2</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="be850028-ff7a-4a26-bf90-48908301144e">
+      <ItemAddTime>635881930243450614</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="ebc76664-a15d-4f3b-a020-e56371722789">
+      <ItemAddTime>635881930243450614</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="71a28012-ae55-4508-a189-8801c666d42c">
+      <ItemAddTime>635881930243450614</ItemAddTime>
+      <ItemAddTimeCount>2</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="3f2ffd69-75f2-4113-a447-7595b31dabb4">
+      <ItemAddTime>635881930243450614</ItemAddTime>
+      <ItemAddTimeCount>3</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="b54f32cd-68df-4aca-910f-fb9b4848dd45">
+      <ItemAddTime>635881930243450614</ItemAddTime>
+      <ItemAddTimeCount>4</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="0a609342-dc84-4790-b85e-7e83f6460a40">
+      <ItemAddTime>635881930243450614</ItemAddTime>
+      <ItemAddTimeCount>5</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="29cd1675-d97b-43ee-995a-07de9a12c809">
+      <ItemAddTime>635881930243450614</ItemAddTime>
+      <ItemAddTimeCount>6</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="589ecf13-6abd-42b4-98ad-0fa1fbf41784">
+      <ItemAddTime>635881930243450614</ItemAddTime>
+      <ItemAddTimeCount>7</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="5cc41ea4-be5d-449f-9942-fc19150becb9">
+      <ItemAddTime>635881930243450614</ItemAddTime>
+      <ItemAddTimeCount>8</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="971bab9c-8d2b-4d4b-a745-c4232ac530e2">
+      <ItemAddTime>635881930243450614</ItemAddTime>
+      <ItemAddTimeCount>9</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="b651ebab-82e3-4d94-9e0d-aee5646044e8">
+      <ItemAddTime>635881930243450614</ItemAddTime>
+      <ItemAddTimeCount>10</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="39bfb8ee-0c21-46db-bb53-08e9466dde69">
+      <ItemAddTime>635881930243450614</ItemAddTime>
+      <ItemAddTimeCount>11</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="8c90089a-1122-461e-9773-bc6313c96305">
+      <ItemAddTime>635881930243450614</ItemAddTime>
+      <ItemAddTimeCount>12</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="866fbc09-7e11-405e-9f0d-92eb78e699be">
+      <ItemAddTime>635881930763945409</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="fb24d4e3-498f-45ef-bdb2-79936c6ddd44">
+      <ItemAddTime>635881930763945409</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a7be515f-f007-45ed-9059-4e1500c0f74d">
+      <TimeTagModified-SourceItem0--0>-8587490430090830399</TimeTagModified-SourceItem0--0>
+      <SourceItem0-IsLockedByUser>False</SourceItem0-IsLockedByUser>
+      <SourceItem0-BuildingTarget-0>True</SourceItem0-BuildingTarget-0>
+      <SourceItem0-IndividualCompileOption-0>False</SourceItem0-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem1--0>-8587490430090830399</TimeTagModified-SourceItem1--0>
+      <SourceItem1-IsLockedByUser>False</SourceItem1-IsLockedByUser>
+      <SourceItem1-BuildingTarget-0>True</SourceItem1-BuildingTarget-0>
+      <SourceItem1-IndividualCompileOption-0>False</SourceItem1-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem2--0>-8587490432401552987</TimeTagModified-SourceItem2--0>
+      <SourceItem2-IsLockedByUser>False</SourceItem2-IsLockedByUser>
+      <SourceItem2-BuildingTarget-0>True</SourceItem2-BuildingTarget-0>
+      <SourceItem2-IndividualCompileOption-0>False</SourceItem2-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem3--0>-8587490432401552987</TimeTagModified-SourceItem3--0>
+      <SourceItem3-IsLockedByUser>False</SourceItem3-IsLockedByUser>
+      <SourceItem3-BuildingTarget-0>True</SourceItem3-BuildingTarget-0>
+      <SourceItem3-IndividualCompileOption-0>False</SourceItem3-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem4--0>-8587490432401552987</TimeTagModified-SourceItem4--0>
+      <SourceItem4-IsLockedByUser>False</SourceItem4-IsLockedByUser>
+      <SourceItem4-BuildingTarget-0>True</SourceItem4-BuildingTarget-0>
+      <SourceItem4-IndividualCompileOption-0>False</SourceItem4-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem5--0>-8587490432401552987</TimeTagModified-SourceItem5--0>
+      <SourceItem5-IsLockedByUser>False</SourceItem5-IsLockedByUser>
+      <SourceItem5-BuildingTarget-0>True</SourceItem5-BuildingTarget-0>
+      <SourceItem5-IndividualCompileOption-0>False</SourceItem5-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem6--0>-8587490432401552987</TimeTagModified-SourceItem6--0>
+      <SourceItem6-IsLockedByUser>False</SourceItem6-IsLockedByUser>
+      <SourceItem6-BuildingTarget-0>True</SourceItem6-BuildingTarget-0>
+      <SourceItem6-IndividualCompileOption-0>False</SourceItem6-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem7--0>-8587490432401552987</TimeTagModified-SourceItem7--0>
+      <SourceItem7-IsLockedByUser>False</SourceItem7-IsLockedByUser>
+      <SourceItem7-BuildingTarget-0>True</SourceItem7-BuildingTarget-0>
+      <SourceItem7-IndividualCompileOption-0>False</SourceItem7-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem8--0>-8587490432401552987</TimeTagModified-SourceItem8--0>
+      <SourceItem8-IsLockedByUser>False</SourceItem8-IsLockedByUser>
+      <SourceItem8-BuildingTarget-0>True</SourceItem8-BuildingTarget-0>
+      <SourceItem8-IndividualCompileOption-0>False</SourceItem8-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem9--0>-8587490432401552987</TimeTagModified-SourceItem9--0>
+      <SourceItem9-IsLockedByUser>False</SourceItem9-IsLockedByUser>
+      <SourceItem9-BuildingTarget-0>True</SourceItem9-BuildingTarget-0>
+      <SourceItem9-IndividualCompileOption-0>False</SourceItem9-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem10--0>-8587490431623508543</TimeTagModified-SourceItem10--0>
+      <SourceItem10-IsLockedByUser>False</SourceItem10-IsLockedByUser>
+      <SourceItem10-BuildingTarget-0>True</SourceItem10-BuildingTarget-0>
+      <SourceItem10-IndividualCompileOption-0>False</SourceItem10-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem11--0>-8587490431623508543</TimeTagModified-SourceItem11--0>
+      <SourceItem11-IsLockedByUser>False</SourceItem11-IsLockedByUser>
+      <SourceItem11-BuildingTarget-0>True</SourceItem11-BuildingTarget-0>
+      <SourceItem11-IndividualCompileOption-0>False</SourceItem11-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem12--0>-8587490431623508543</TimeTagModified-SourceItem12--0>
+      <SourceItem12-IsLockedByUser>False</SourceItem12-IsLockedByUser>
+      <SourceItem12-BuildingTarget-0>True</SourceItem12-BuildingTarget-0>
+      <SourceItem12-IndividualCompileOption-0>False</SourceItem12-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem13--0>-8587490431623508543</TimeTagModified-SourceItem13--0>
+      <SourceItem13-IsLockedByUser>False</SourceItem13-IsLockedByUser>
+      <SourceItem13-BuildingTarget-0>True</SourceItem13-BuildingTarget-0>
+      <SourceItem13-IndividualCompileOption-0>False</SourceItem13-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem14--0>-8587490431623508543</TimeTagModified-SourceItem14--0>
+      <SourceItem14-IsLockedByUser>False</SourceItem14-IsLockedByUser>
+      <SourceItem14-BuildingTarget-0>True</SourceItem14-BuildingTarget-0>
+      <SourceItem14-IndividualCompileOption-0>False</SourceItem14-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem15--0>-8587490431623508543</TimeTagModified-SourceItem15--0>
+      <SourceItem15-IsLockedByUser>False</SourceItem15-IsLockedByUser>
+      <SourceItem15-BuildingTarget-0>True</SourceItem15-BuildingTarget-0>
+      <SourceItem15-IndividualCompileOption-0>False</SourceItem15-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem16--0>-8587490431623508543</TimeTagModified-SourceItem16--0>
+      <SourceItem16-IsLockedByUser>False</SourceItem16-IsLockedByUser>
+      <SourceItem16-BuildingTarget-0>True</SourceItem16-BuildingTarget-0>
+      <SourceItem16-IndividualCompileOption-0>False</SourceItem16-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem17--0>-8587490431623508543</TimeTagModified-SourceItem17--0>
+      <SourceItem17-IsLockedByUser>False</SourceItem17-IsLockedByUser>
+      <SourceItem17-BuildingTarget-0>True</SourceItem17-BuildingTarget-0>
+      <SourceItem17-IndividualCompileOption-0>False</SourceItem17-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem18--0>-8587490431623508543</TimeTagModified-SourceItem18--0>
+      <SourceItem18-IsLockedByUser>False</SourceItem18-IsLockedByUser>
+      <SourceItem18-BuildingTarget-0>True</SourceItem18-BuildingTarget-0>
+      <SourceItem18-IndividualCompileOption-0>False</SourceItem18-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem19--0>-8587490431623508543</TimeTagModified-SourceItem19--0>
+      <SourceItem19-IsLockedByUser>False</SourceItem19-IsLockedByUser>
+      <SourceItem19-BuildingTarget-0>True</SourceItem19-BuildingTarget-0>
+      <SourceItem19-IndividualCompileOption-0>False</SourceItem19-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem20--0>-8587490431623508543</TimeTagModified-SourceItem20--0>
+      <SourceItem20-IsLockedByUser>False</SourceItem20-IsLockedByUser>
+      <SourceItem20-BuildingTarget-0>True</SourceItem20-BuildingTarget-0>
+      <SourceItem20-IndividualCompileOption-0>False</SourceItem20-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem21--0>-8587490431623508543</TimeTagModified-SourceItem21--0>
+      <SourceItem21-IsLockedByUser>False</SourceItem21-IsLockedByUser>
+      <SourceItem21-BuildingTarget-0>True</SourceItem21-BuildingTarget-0>
+      <SourceItem21-IndividualCompileOption-0>False</SourceItem21-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem22--0>-8587490431623508543</TimeTagModified-SourceItem22--0>
+      <SourceItem22-IsLockedByUser>False</SourceItem22-IsLockedByUser>
+      <SourceItem22-BuildingTarget-0>True</SourceItem22-BuildingTarget-0>
+      <SourceItem22-IndividualCompileOption-0>False</SourceItem22-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem23--0>-8587490431623508543</TimeTagModified-SourceItem23--0>
+      <SourceItem23-IsLockedByUser>False</SourceItem23-IsLockedByUser>
+      <SourceItem23-BuildingTarget-0>True</SourceItem23-BuildingTarget-0>
+      <SourceItem23-IndividualCompileOption-0>False</SourceItem23-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem24--0>-8587490431623508543</TimeTagModified-SourceItem24--0>
+      <SourceItem24-IsLockedByUser>False</SourceItem24-IsLockedByUser>
+      <SourceItem24-BuildingTarget-0>True</SourceItem24-BuildingTarget-0>
+      <SourceItem24-IndividualCompileOption-0>False</SourceItem24-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem25--0>-8587490431623508543</TimeTagModified-SourceItem25--0>
+      <SourceItem25-IsLockedByUser>False</SourceItem25-IsLockedByUser>
+      <SourceItem25-BuildingTarget-0>True</SourceItem25-BuildingTarget-0>
+      <SourceItem25-IndividualCompileOption-0>False</SourceItem25-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem26--0>-8587490431435712299</TimeTagModified-SourceItem26--0>
+      <SourceItem26-IsLockedByUser>False</SourceItem26-IsLockedByUser>
+      <SourceItem26-BuildingTarget-0>True</SourceItem26-BuildingTarget-0>
+      <SourceItem26-IndividualCompileOption-0>False</SourceItem26-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem27--0>-8587490431435712299</TimeTagModified-SourceItem27--0>
+      <SourceItem27-IsLockedByUser>False</SourceItem27-IsLockedByUser>
+      <SourceItem27-BuildingTarget-0>True</SourceItem27-BuildingTarget-0>
+      <SourceItem27-IndividualCompileOption-0>False</SourceItem27-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem28--0>-8587490431435712299</TimeTagModified-SourceItem28--0>
+      <SourceItem28-IsLockedByUser>False</SourceItem28-IsLockedByUser>
+      <SourceItem28-BuildingTarget-0>True</SourceItem28-BuildingTarget-0>
+      <SourceItem28-IndividualCompileOption-0>False</SourceItem28-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem29--0>-8587490431435712299</TimeTagModified-SourceItem29--0>
+      <SourceItem29-IsLockedByUser>False</SourceItem29-IsLockedByUser>
+      <SourceItem29-BuildingTarget-0>True</SourceItem29-BuildingTarget-0>
+      <SourceItem29-IndividualCompileOption-0>False</SourceItem29-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem30--0>-8587490431435712299</TimeTagModified-SourceItem30--0>
+      <SourceItem30-IsLockedByUser>False</SourceItem30-IsLockedByUser>
+      <SourceItem30-BuildingTarget-0>True</SourceItem30-BuildingTarget-0>
+      <SourceItem30-IndividualCompileOption-0>False</SourceItem30-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem31--0>-8587490431435712299</TimeTagModified-SourceItem31--0>
+      <SourceItem31-IsLockedByUser>False</SourceItem31-IsLockedByUser>
+      <SourceItem31-BuildingTarget-0>True</SourceItem31-BuildingTarget-0>
+      <SourceItem31-IndividualCompileOption-0>False</SourceItem31-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem32--0>-8587490431435712299</TimeTagModified-SourceItem32--0>
+      <SourceItem32-IsLockedByUser>False</SourceItem32-IsLockedByUser>
+      <SourceItem32-BuildingTarget-0>True</SourceItem32-BuildingTarget-0>
+      <SourceItem32-IndividualCompileOption-0>False</SourceItem32-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem33--0>-8587490431435712299</TimeTagModified-SourceItem33--0>
+      <SourceItem33-IsLockedByUser>False</SourceItem33-IsLockedByUser>
+      <SourceItem33-BuildingTarget-0>True</SourceItem33-BuildingTarget-0>
+      <SourceItem33-IndividualCompileOption-0>False</SourceItem33-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem34--0>-8587490430510226205</TimeTagModified-SourceItem34--0>
+      <SourceItem34-IsLockedByUser>False</SourceItem34-IsLockedByUser>
+      <SourceItem34-BuildingTarget-0>False</SourceItem34-BuildingTarget-0>
+      <SourceItem34-IndividualCompileOption-0>False</SourceItem34-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem35--0>-8587490430414227165</TimeTagModified-SourceItem35--0>
+      <SourceItem35-IsLockedByUser>False</SourceItem35-IsLockedByUser>
+      <SourceItem35-BuildingTarget-0>False</SourceItem35-BuildingTarget-0>
+      <SourceItem35-IndividualCompileOption-0>False</SourceItem35-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem36--0>-8587490430356727740</TimeTagModified-SourceItem36--0>
+      <SourceItem36-IsLockedByUser>False</SourceItem36-IsLockedByUser>
+      <SourceItem36-BuildingTarget-0>False</SourceItem36-BuildingTarget-0>
+      <SourceItem36-IndividualCompileOption-0>False</SourceItem36-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem37--0>-8587490430307228235</TimeTagModified-SourceItem37--0>
+      <SourceItem37-IsLockedByUser>False</SourceItem37-IsLockedByUser>
+      <SourceItem37-BuildingTarget-0>False</SourceItem37-BuildingTarget-0>
+      <SourceItem37-IndividualCompileOption-0>False</SourceItem37-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem38--0>-8587490431113118751</TimeTagModified-SourceItem38--0>
+      <SourceItem38-IsLockedByUser>False</SourceItem38-IsLockedByUser>
+      <SourceItem38-BuildingTarget-0>True</SourceItem38-BuildingTarget-0>
+      <SourceItem38-IndividualCompileOption-0>False</SourceItem38-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem39--0>-8587490431113118751</TimeTagModified-SourceItem39--0>
+      <SourceItem39-IsLockedByUser>False</SourceItem39-IsLockedByUser>
+      <SourceItem39-BuildingTarget-0>True</SourceItem39-BuildingTarget-0>
+      <SourceItem39-IndividualCompileOption-0>False</SourceItem39-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem40--0>-8587490431113118751</TimeTagModified-SourceItem40--0>
+      <SourceItem40-IsLockedByUser>False</SourceItem40-IsLockedByUser>
+      <SourceItem40-BuildingTarget-0>True</SourceItem40-BuildingTarget-0>
+      <SourceItem40-IndividualCompileOption-0>False</SourceItem40-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem41--0>-8587490431113118751</TimeTagModified-SourceItem41--0>
+      <SourceItem41-IsLockedByUser>False</SourceItem41-IsLockedByUser>
+      <SourceItem41-BuildingTarget-0>True</SourceItem41-BuildingTarget-0>
+      <SourceItem41-IndividualCompileOption-0>False</SourceItem41-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem42--0>-8587490431113118751</TimeTagModified-SourceItem42--0>
+      <SourceItem42-IsLockedByUser>False</SourceItem42-IsLockedByUser>
+      <SourceItem42-BuildingTarget-0>True</SourceItem42-BuildingTarget-0>
+      <SourceItem42-IndividualCompileOption-0>False</SourceItem42-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem43--0>-8587490431113118751</TimeTagModified-SourceItem43--0>
+      <SourceItem43-IsLockedByUser>False</SourceItem43-IsLockedByUser>
+      <SourceItem43-BuildingTarget-0>True</SourceItem43-BuildingTarget-0>
+      <SourceItem43-IndividualCompileOption-0>False</SourceItem43-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem44--0>-8587490430888322424</TimeTagModified-SourceItem44--0>
+      <SourceItem44-IsLockedByUser>False</SourceItem44-IsLockedByUser>
+      <SourceItem44-BuildingTarget-0>True</SourceItem44-BuildingTarget-0>
+      <SourceItem44-IndividualCompileOption-0>False</SourceItem44-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem45--0>-8587490430888322424</TimeTagModified-SourceItem45--0>
+      <SourceItem45-IsLockedByUser>False</SourceItem45-IsLockedByUser>
+      <SourceItem45-BuildingTarget-0>True</SourceItem45-BuildingTarget-0>
+      <SourceItem45-IndividualCompileOption-0>False</SourceItem45-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem46--0>-8587490430888322424</TimeTagModified-SourceItem46--0>
+      <SourceItem46-IsLockedByUser>False</SourceItem46-IsLockedByUser>
+      <SourceItem46-BuildingTarget-0>True</SourceItem46-BuildingTarget-0>
+      <SourceItem46-IndividualCompileOption-0>False</SourceItem46-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem47--0>-8587490430611325194</TimeTagModified-SourceItem47--0>
+      <SourceItem47-IsLockedByUser>False</SourceItem47-IsLockedByUser>
+      <SourceItem47-BuildingTarget-0>True</SourceItem47-BuildingTarget-0>
+      <SourceItem47-IndividualCompileOption-0>False</SourceItem47-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem48--0>-8587490430611325194</TimeTagModified-SourceItem48--0>
+      <SourceItem48-IsLockedByUser>False</SourceItem48-IsLockedByUser>
+      <SourceItem48-BuildingTarget-0>True</SourceItem48-BuildingTarget-0>
+      <SourceItem48-IndividualCompileOption-0>False</SourceItem48-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem49--0>-8587490430611325194</TimeTagModified-SourceItem49--0>
+      <SourceItem49-IsLockedByUser>False</SourceItem49-IsLockedByUser>
+      <SourceItem49-BuildingTarget-0>True</SourceItem49-BuildingTarget-0>
+      <SourceItem49-IndividualCompileOption-0>False</SourceItem49-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem50--0>-8587490430611325194</TimeTagModified-SourceItem50--0>
+      <SourceItem50-IsLockedByUser>False</SourceItem50-IsLockedByUser>
+      <SourceItem50-BuildingTarget-0>True</SourceItem50-BuildingTarget-0>
+      <SourceItem50-IndividualCompileOption-0>False</SourceItem50-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem51--0>-8587490430611325194</TimeTagModified-SourceItem51--0>
+      <SourceItem51-IsLockedByUser>False</SourceItem51-IsLockedByUser>
+      <SourceItem51-BuildingTarget-0>True</SourceItem51-BuildingTarget-0>
+      <SourceItem51-IndividualCompileOption-0>False</SourceItem51-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem52--0>-8587490430611325194</TimeTagModified-SourceItem52--0>
+      <SourceItem52-IsLockedByUser>False</SourceItem52-IsLockedByUser>
+      <SourceItem52-BuildingTarget-0>True</SourceItem52-BuildingTarget-0>
+      <SourceItem52-IndividualCompileOption-0>False</SourceItem52-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem53--0>-8587490430611325194</TimeTagModified-SourceItem53--0>
+      <SourceItem53-IsLockedByUser>False</SourceItem53-IsLockedByUser>
+      <SourceItem53-BuildingTarget-0>True</SourceItem53-BuildingTarget-0>
+      <SourceItem53-IndividualCompileOption-0>False</SourceItem53-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem54--0>-8587490430611325194</TimeTagModified-SourceItem54--0>
+      <SourceItem54-IsLockedByUser>False</SourceItem54-IsLockedByUser>
+      <SourceItem54-BuildingTarget-0>True</SourceItem54-BuildingTarget-0>
+      <SourceItem54-IndividualCompileOption-0>False</SourceItem54-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem55--0>-8587490430611325194</TimeTagModified-SourceItem55--0>
+      <SourceItem55-IsLockedByUser>False</SourceItem55-IsLockedByUser>
+      <SourceItem55-BuildingTarget-0>True</SourceItem55-BuildingTarget-0>
+      <SourceItem55-IndividualCompileOption-0>False</SourceItem55-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem56--0>-8587490430611325194</TimeTagModified-SourceItem56--0>
+      <SourceItem56-IsLockedByUser>False</SourceItem56-IsLockedByUser>
+      <SourceItem56-BuildingTarget-0>True</SourceItem56-BuildingTarget-0>
+      <SourceItem56-IndividualCompileOption-0>False</SourceItem56-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem57--0>-8587490430611325194</TimeTagModified-SourceItem57--0>
+      <SourceItem57-IsLockedByUser>False</SourceItem57-IsLockedByUser>
+      <SourceItem57-BuildingTarget-0>True</SourceItem57-BuildingTarget-0>
+      <SourceItem57-IndividualCompileOption-0>False</SourceItem57-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem58--0>-8587490430611325194</TimeTagModified-SourceItem58--0>
+      <SourceItem58-IsLockedByUser>False</SourceItem58-IsLockedByUser>
+      <SourceItem58-BuildingTarget-0>True</SourceItem58-BuildingTarget-0>
+      <SourceItem58-IndividualCompileOption-0>False</SourceItem58-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem59--0>-8587490430611325194</TimeTagModified-SourceItem59--0>
+      <SourceItem59-IsLockedByUser>False</SourceItem59-IsLockedByUser>
+      <SourceItem59-BuildingTarget-0>True</SourceItem59-BuildingTarget-0>
+      <SourceItem59-IndividualCompileOption-0>False</SourceItem59-IndividualCompileOption-0>
+    </Instance>
+  </Class>
+  <Class Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
+    <Instance Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
+      <IsLibraryMode>True</IsLibraryMode>
+      <StartUpCategoryItem>00000000-0000-0000-0000-000000000000</StartUpCategoryItem>
+    </Instance>
+  </Class>
+  <Class Guid="a29a09ee-92c3-4ce7-9586-a1b058043f92">
+    <Instance Guid="a29a09ee-92c3-4ce7-9586-a1b058043f92">
+      <ProjectGeneratr-GeneratedFile0 />
+    </Instance>
+  </Class>
+  <Class Guid="31a86ad3-37bd-4846-aff2-e08abdc00197">
+    <Instance Guid="31a86ad3-37bd-4846-aff2-e08abdc00197">
+      <DeviceNameOnCreateStartup>R5F563NBDxFP</DeviceNameOnCreateStartup>
+    </Instance>
+  </Class>
+  <Class Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">
+    <Instance Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">
+      <ProductVersion>4.02.00.00</ProductVersion>
+    </Instance>
+  </Class>
+</CubeSuiteProject>
Index: UsbWattMeter/trunk/csp/libwolfssl/libwolfssl.mtpj
===================================================================
--- UsbWattMeter/trunk/csp/libwolfssl/libwolfssl.mtpj	(revision 164)
+++ UsbWattMeter/trunk/csp/libwolfssl/libwolfssl.mtpj	(revision 164)
@@ -0,0 +1,1677 @@
+<CubeSuiteProject>
+  <ProductVersion>4.02.00.00</ProductVersion>
+  <Class Guid="68f4a651-b9cd-473b-a595-b00447132ffa">
+    <Instance Guid="00000000-0000-0000-0000-000000000000">
+      <FormatVersion>2.0</FormatVersion>
+      <FileVersion>4.2</FileVersion>
+      <ProjectGuid>de0caab6-5fc3-4cd5-b7dd-4fa5d9b1ee0c</ProjectGuid>
+      <ProjectItemGuid>49cc0cf9-1c8a-4295-8614-c5de04bed4fd</ProjectItemGuid>
+      <FileCategoryGuid>aa85bea4-e39e-4833-87c8-01e2270eec68</FileCategoryGuid>
+      <Property>fb98844b-2c27-4275-9804-f6e63e204da0</Property>
+      <ActiveProjectGuid>de0caab6-5fc3-4cd5-b7dd-4fa5d9b1ee0c</ActiveProjectGuid>
+    </Instance>
+    <Instance Guid="20b6de82-615c-444e-b129-b421e7bb6b2e">
+      <Name>wolfcrypt</Name>
+      <Type>Category</Type>
+      <ParentItem>aa85bea4-e39e-4833-87c8-01e2270eec68</ParentItem>
+      <Property>059b2382-1d42-48cf-af58-896efce8b65b</Property>
+    </Instance>
+    <Instance Guid="a8f544da-e670-4f81-bdf0-302c128849d3">
+      <Name>crl.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\src\crl.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>aa85bea4-e39e-4833-87c8-01e2270eec68</ParentItem>
+      <Property>95c72f5d-0f1a-4a95-8704-7c836a94ab26</Property>
+    </Instance>
+    <Instance Guid="2e69b8d4-0091-4536-bdae-3c8ed3fbbce5">
+      <Name>internal.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\src\internal.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>aa85bea4-e39e-4833-87c8-01e2270eec68</ParentItem>
+      <Property>8d2d990c-4b71-4474-844f-713593097221</Property>
+    </Instance>
+    <Instance Guid="8f189067-23ba-4764-8096-1c87bc59d677">
+      <Name>io.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\src\io.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>aa85bea4-e39e-4833-87c8-01e2270eec68</ParentItem>
+      <Property>b1f68088-0258-4c2c-a3b9-6b42ecccbe5d</Property>
+    </Instance>
+    <Instance Guid="e8a40ef7-84d6-43c7-839a-3e5225cf5e33">
+      <Name>keys.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\src\keys.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>aa85bea4-e39e-4833-87c8-01e2270eec68</ParentItem>
+      <Property>7796c118-693d-40c6-bcfa-edae150e2497</Property>
+    </Instance>
+    <Instance Guid="5490e1ed-eefb-4222-b5d1-9edc32763f97">
+      <Name>ocsp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\src\ocsp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>aa85bea4-e39e-4833-87c8-01e2270eec68</ParentItem>
+      <Property>290b65b7-bef9-4a8d-a080-23cb32abeb5c</Property>
+    </Instance>
+    <Instance Guid="af565ef2-c045-4bc0-bba2-14c9a98465d2">
+      <Name>sniffer.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\src\sniffer.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>aa85bea4-e39e-4833-87c8-01e2270eec68</ParentItem>
+      <Property>ba1fdc24-a05e-4ee8-9eef-2102a1066fbc</Property>
+    </Instance>
+    <Instance Guid="5e6b7bf7-bd92-461d-84bd-dafbe290b317">
+      <Name>ssl.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\src\ssl.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>aa85bea4-e39e-4833-87c8-01e2270eec68</ParentItem>
+      <Property>c70b6eaa-de6a-40fe-ab50-21abb3c143ed</Property>
+    </Instance>
+    <Instance Guid="8e698c09-5097-444e-8342-19f6512bd4b0">
+      <Name>tls.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\src\tls.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>aa85bea4-e39e-4833-87c8-01e2270eec68</ParentItem>
+      <Property>c9504358-c91c-4af8-8154-6014307cc716</Property>
+    </Instance>
+    <Instance Guid="fd90ffa4-5d9b-43cd-91d0-f4830247c96e">
+      <Name>aes.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\aes.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>e4e2b216-e6f1-48d8-a069-bb2f7958a685</Property>
+    </Instance>
+    <Instance Guid="93bbcbdd-6989-46ae-9cd2-13374a458a2a">
+      <Name>arc4.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\arc4.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>216a499d-f2ad-4831-84f3-82dc2dfa49d9</Property>
+    </Instance>
+    <Instance Guid="33b97578-6550-4399-983b-21c317cd3dae">
+      <Name>asn.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\asn.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>9ea6971f-5b5c-4074-9575-3192db4d9381</Property>
+    </Instance>
+    <Instance Guid="9afcf469-0afc-47cc-ab99-53f8d372e707">
+      <Name>blake2b.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\blake2b.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>3156cd49-7114-4ab6-a088-2731a49c02d9</Property>
+    </Instance>
+    <Instance Guid="e16f9919-5f9b-453c-8cdc-8958b44a0731">
+      <Name>camellia.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\camellia.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>20db2b5b-2b62-4769-be5c-668821f4de7b</Property>
+    </Instance>
+    <Instance Guid="162c8aa9-7915-498d-9eaf-4a86c754cafc">
+      <Name>coding.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\coding.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>cb3791b4-8119-4c7d-a748-5e14e821da7b</Property>
+    </Instance>
+    <Instance Guid="7d3ae7f7-8cee-45ba-8e6c-5c70ae26c124">
+      <Name>des3.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\des3.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>296306e7-9bb3-4e92-a13f-6109f6fb89da</Property>
+    </Instance>
+    <Instance Guid="c14daa42-03b4-4321-9840-43513554edf5">
+      <Name>dh.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\dh.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>6da33b96-3b35-4226-a6f6-c425b1dc7d43</Property>
+    </Instance>
+    <Instance Guid="cea570e4-52af-4e53-9b20-37d34800f495">
+      <Name>dsa.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\dsa.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>445668d9-de4c-45b7-aee4-78795525ccb8</Property>
+    </Instance>
+    <Instance Guid="4690fcde-d968-4239-a0a8-57fe645e2d5c">
+      <Name>ecc.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\ecc.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>ee601a2c-243b-4741-8eb1-d655f71cf730</Property>
+    </Instance>
+    <Instance Guid="cfe5ca36-46ce-4fc2-834c-0da1c3728b34">
+      <Name>error.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\error.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>92bdba94-c4c9-46e5-af3c-62f462c20bbf</Property>
+    </Instance>
+    <Instance Guid="8b954fec-9423-4c49-b509-cd0526a4575a">
+      <Name>hash.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\hash.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>f758ad13-4997-4851-9570-94d851afa2e8</Property>
+    </Instance>
+    <Instance Guid="f7292e22-977c-4c0b-b5ce-75a26b2cfc6e">
+      <Name>hc128.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\hc128.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>2f83f76b-be2b-49b5-abb0-eac5a6b2397c</Property>
+    </Instance>
+    <Instance Guid="c7a5c3f9-adc0-4f2c-8274-9b938748faaf">
+      <Name>hmac.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\hmac.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>ae65c6c9-9e18-4b53-a145-256a498096a6</Property>
+    </Instance>
+    <Instance Guid="31c58253-720c-4a63-9797-fff29563300f">
+      <Name>integer.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\integer.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>2bfd6672-6f50-47f4-b4a3-f62f528f6de6</Property>
+    </Instance>
+    <Instance Guid="f3174502-6793-4acf-98df-e85b44f3980b">
+      <Name>logging.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\logging.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>6516aab1-c402-47b0-892a-7385f0e10143</Property>
+    </Instance>
+    <Instance Guid="2eeb3b6e-b74b-4f36-98a8-1b4c6d7c3766">
+      <Name>md4.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\md4.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>7e50ad94-a1e8-4681-b45e-f236151bb1de</Property>
+    </Instance>
+    <Instance Guid="f18e4ce9-8cca-44ff-8d9f-d63c7bb293ab">
+      <Name>md5.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\md5.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>750f6a39-cda5-4bee-8ad5-b0f1aaa6b1a5</Property>
+    </Instance>
+    <Instance Guid="b3b3a308-6b24-4930-82bb-edd785893281">
+      <Name>memory.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\memory.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>2f643d44-cdd1-4686-9375-066bda97ea85</Property>
+    </Instance>
+    <Instance Guid="49238843-c08d-4342-95a1-7896eec7f2fc">
+      <Name>misc.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\misc.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>0680de03-3cfb-4f54-8a9d-8eb97f9cf413</Property>
+    </Instance>
+    <Instance Guid="6584642a-5899-4579-8b26-7a08d0f7b0d8">
+      <Name>pwdbased.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\pwdbased.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>3e184f04-ce98-423f-bde0-d19b9569807d</Property>
+    </Instance>
+    <Instance Guid="92df22fc-4f1a-4a9c-a6f9-6fe981a6551b">
+      <Name>rabbit.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\rabbit.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>5e8efca8-e2f1-464c-8147-494a15e292fb</Property>
+    </Instance>
+    <Instance Guid="875a8eb6-b09d-43a5-a6cd-863f5d1de818">
+      <Name>random.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\random.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>b45a53aa-8106-4a42-8aea-eeefbc226ae3</Property>
+    </Instance>
+    <Instance Guid="42c1cced-3ccb-41d6-a09e-c1f7a9a65254">
+      <Name>ripemd.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\ripemd.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>eb15ec57-ca4d-43d6-9dac-3427492bae83</Property>
+    </Instance>
+    <Instance Guid="3e006428-dd0a-4f7f-ab26-8e41e5d3fc63">
+      <Name>rsa.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\rsa.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>970729f7-9e08-4391-9e5a-a9614734d355</Property>
+    </Instance>
+    <Instance Guid="267fea6c-b9f0-4037-9ad8-cea2f443d560">
+      <Name>sha.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\sha.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>95441897-eb77-48e3-a054-6594ca99d0f3</Property>
+    </Instance>
+    <Instance Guid="3d410f00-ba86-47fa-bb43-b9167a5edba6">
+      <Name>sha256.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\sha256.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>c6226aef-4743-43aa-b865-a8de39916a43</Property>
+    </Instance>
+    <Instance Guid="387c8b98-e894-4de8-8988-31af2fdf4334">
+      <Name>sha512.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\sha512.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>7b8f607b-4c18-4393-bd1d-1b1b82e5e02f</Property>
+    </Instance>
+    <Instance Guid="ed66d182-bc22-462a-b334-c84306114b1a">
+      <Name>wc_encrypt.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\wc_encrypt.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>ba040d06-b30c-496f-892f-cff755d93000</Property>
+    </Instance>
+    <Instance Guid="ee86d025-7a48-4f67-99f5-3105b26868be">
+      <Name>wc_port.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\wolfssl-3.7.0\wolfcrypt\src\wc_port.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>20b6de82-615c-444e-b129-b421e7bb6b2e</ParentItem>
+      <Property>fc987f74-6f7e-4790-ab89-7d69e952f4d3</Property>
+    </Instance>
+  </Class>
+  <Class Guid="fb98844b-2c27-4275-9804-f6e63e204da0">
+    <Instance Guid="fb98844b-2c27-4275-9804-f6e63e204da0">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="0d548289-d5e9-4893-9a8f-9374b13f19a9">
+    <Instance Guid="95c72f5d-0f1a-4a95-8704-7c836a94ab26">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="8d2d990c-4b71-4474-844f-713593097221">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="b1f68088-0258-4c2c-a3b9-6b42ecccbe5d">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="7796c118-693d-40c6-bcfa-edae150e2497">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="290b65b7-bef9-4a8d-a080-23cb32abeb5c">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="ba1fdc24-a05e-4ee8-9eef-2102a1066fbc">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="c70b6eaa-de6a-40fe-ab50-21abb3c143ed">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="c9504358-c91c-4af8-8154-6014307cc716">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="e4e2b216-e6f1-48d8-a069-bb2f7958a685">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="216a499d-f2ad-4831-84f3-82dc2dfa49d9">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="9ea6971f-5b5c-4074-9575-3192db4d9381">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="3156cd49-7114-4ab6-a088-2731a49c02d9">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="20db2b5b-2b62-4769-be5c-668821f4de7b">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="cb3791b4-8119-4c7d-a748-5e14e821da7b">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="296306e7-9bb3-4e92-a13f-6109f6fb89da">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="6da33b96-3b35-4226-a6f6-c425b1dc7d43">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="445668d9-de4c-45b7-aee4-78795525ccb8">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="ee601a2c-243b-4741-8eb1-d655f71cf730">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="92bdba94-c4c9-46e5-af3c-62f462c20bbf">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="f758ad13-4997-4851-9570-94d851afa2e8">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="2f83f76b-be2b-49b5-abb0-eac5a6b2397c">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="ae65c6c9-9e18-4b53-a145-256a498096a6">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="2bfd6672-6f50-47f4-b4a3-f62f528f6de6">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="6516aab1-c402-47b0-892a-7385f0e10143">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="7e50ad94-a1e8-4681-b45e-f236151bb1de">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="750f6a39-cda5-4bee-8ad5-b0f1aaa6b1a5">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="2f643d44-cdd1-4686-9375-066bda97ea85">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="0680de03-3cfb-4f54-8a9d-8eb97f9cf413">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="3e184f04-ce98-423f-bde0-d19b9569807d">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="5e8efca8-e2f1-464c-8147-494a15e292fb">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="b45a53aa-8106-4a42-8aea-eeefbc226ae3">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="eb15ec57-ca4d-43d6-9dac-3427492bae83">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="970729f7-9e08-4391-9e5a-a9614734d355">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="95441897-eb77-48e3-a054-6594ca99d0f3">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="c6226aef-4743-43aa-b865-a8de39916a43">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="7b8f607b-4c18-4393-bd1d-1b1b82e5e02f">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="ba040d06-b30c-496f-892f-cff755d93000">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="fc987f74-6f7e-4790-ab89-7d69e952f4d3">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="78a5c5cd-76cb-4bcc-a031-3020011fbc9a">
+    <Instance Guid="059b2382-1d42-48cf-af58-896efce8b65b">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="8fb9c1f6-d351-4d10-8d99-bf5b3015b84c">
+    <Instance Guid="00000000-0000-0000-0000-000000000000">
+      <UsingPlatformGuid>7020d445-1358-4043-a8ea-3b101e73ceaa</UsingPlatformGuid>
+      <UsingPlatformTypeGuid>f96683fa-8de4-4c6d-a1ab-925d7f232c09</UsingPlatformTypeGuid>
+    </Instance>
+  </Class>
+  <Class Guid="c325714f-8f51-484b-9e96-b4b59c0fb263">
+    <Instance Guid="c325714f-8f51-484b-9e96-b4b59c0fb263">
+      <DeviceManager>0e793ff3-2e3f-43c0-bdc9-926269595403</DeviceManager>
+    </Instance>
+  </Class>
+  <Class Guid="0e793ff3-2e3f-43c0-bdc9-926269595403">
+    <Instance Guid="0e793ff3-2e3f-43c0-bdc9-926269595403">
+      <DataFormatVersion>1.0</DataFormatVersion>
+    </Instance>
+    <Instance Guid="2a81c37a-5015-44c2-9f40-e58b669eec75">
+      <DeviceName>R5F563NBDxFP</DeviceName>
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="873c9a58-9bc5-439a-b476-78629a4553ed">
+    <Instance Guid="873c9a58-9bc5-439a-b476-78629a4553ed">
+      <ProjectDeviceChangedCounter>0</ProjectDeviceChangedCounter>
+      <ProjectInitialDeviceName>R5F563NBDxFP</ProjectInitialDeviceName>
+    </Instance>
+  </Class>
+  <Class Guid="c3835e31-dea3-4c93-b02b-d2db997f7630">
+    <Instance Guid="c3835e31-dea3-4c93-b02b-d2db997f7630">
+      <BuildToolManager>3a79707d-5977-45f7-ac11-19c35e333132</BuildToolManager>
+    </Instance>
+  </Class>
+  <Class Guid="3a79707d-5977-45f7-ac11-19c35e333132">
+    <Instance Guid="3a79707d-5977-45f7-ac11-19c35e333132">
+      <DataFormatVersion>1.2</DataFormatVersion>
+      <BuildModeCount>1</BuildModeCount>
+      <BuildMode0>RABlAGYAYQB1AGwAdABCAHUAaQBsAGQA</BuildMode0>
+      <BatchBuildFlag0>False</BatchBuildFlag0>
+      <CurrentBuildMode>DefaultBuild</CurrentBuildMode>
+      <SourceItemGuid0>a8f544da-e670-4f81-bdf0-302c128849d3</SourceItemGuid0>
+      <SourceItemType0>CSource</SourceItemType0>
+      <SourceItemGuid1>2e69b8d4-0091-4536-bdae-3c8ed3fbbce5</SourceItemGuid1>
+      <SourceItemType1>CSource</SourceItemType1>
+      <SourceItemGuid2>8f189067-23ba-4764-8096-1c87bc59d677</SourceItemGuid2>
+      <SourceItemType2>CSource</SourceItemType2>
+      <SourceItemGuid3>e8a40ef7-84d6-43c7-839a-3e5225cf5e33</SourceItemGuid3>
+      <SourceItemType3>CSource</SourceItemType3>
+      <SourceItemGuid4>5490e1ed-eefb-4222-b5d1-9edc32763f97</SourceItemGuid4>
+      <SourceItemType4>CSource</SourceItemType4>
+      <SourceItemGuid5>af565ef2-c045-4bc0-bba2-14c9a98465d2</SourceItemGuid5>
+      <SourceItemType5>CSource</SourceItemType5>
+      <SourceItemGuid6>5e6b7bf7-bd92-461d-84bd-dafbe290b317</SourceItemGuid6>
+      <SourceItemType6>CSource</SourceItemType6>
+      <SourceItemGuid7>8e698c09-5097-444e-8342-19f6512bd4b0</SourceItemGuid7>
+      <SourceItemType7>CSource</SourceItemType7>
+      <SourceItemGuid8>fd90ffa4-5d9b-43cd-91d0-f4830247c96e</SourceItemGuid8>
+      <SourceItemType8>CSource</SourceItemType8>
+      <SourceItemGuid9>93bbcbdd-6989-46ae-9cd2-13374a458a2a</SourceItemGuid9>
+      <SourceItemType9>CSource</SourceItemType9>
+      <SourceItemGuid10>33b97578-6550-4399-983b-21c317cd3dae</SourceItemGuid10>
+      <SourceItemType10>CSource</SourceItemType10>
+      <SourceItemGuid11>9afcf469-0afc-47cc-ab99-53f8d372e707</SourceItemGuid11>
+      <SourceItemType11>CSource</SourceItemType11>
+      <SourceItemGuid12>e16f9919-5f9b-453c-8cdc-8958b44a0731</SourceItemGuid12>
+      <SourceItemType12>CSource</SourceItemType12>
+      <SourceItemGuid13>162c8aa9-7915-498d-9eaf-4a86c754cafc</SourceItemGuid13>
+      <SourceItemType13>CSource</SourceItemType13>
+      <SourceItemGuid14>7d3ae7f7-8cee-45ba-8e6c-5c70ae26c124</SourceItemGuid14>
+      <SourceItemType14>CSource</SourceItemType14>
+      <SourceItemGuid15>c14daa42-03b4-4321-9840-43513554edf5</SourceItemGuid15>
+      <SourceItemType15>CSource</SourceItemType15>
+      <SourceItemGuid16>cea570e4-52af-4e53-9b20-37d34800f495</SourceItemGuid16>
+      <SourceItemType16>CSource</SourceItemType16>
+      <SourceItemGuid17>4690fcde-d968-4239-a0a8-57fe645e2d5c</SourceItemGuid17>
+      <SourceItemType17>CSource</SourceItemType17>
+      <SourceItemGuid18>cfe5ca36-46ce-4fc2-834c-0da1c3728b34</SourceItemGuid18>
+      <SourceItemType18>CSource</SourceItemType18>
+      <SourceItemGuid19>8b954fec-9423-4c49-b509-cd0526a4575a</SourceItemGuid19>
+      <SourceItemType19>CSource</SourceItemType19>
+      <SourceItemGuid20>f7292e22-977c-4c0b-b5ce-75a26b2cfc6e</SourceItemGuid20>
+      <SourceItemType20>CSource</SourceItemType20>
+      <SourceItemGuid21>c7a5c3f9-adc0-4f2c-8274-9b938748faaf</SourceItemGuid21>
+      <SourceItemType21>CSource</SourceItemType21>
+      <SourceItemGuid22>31c58253-720c-4a63-9797-fff29563300f</SourceItemGuid22>
+      <SourceItemType22>CSource</SourceItemType22>
+      <SourceItemGuid23>f3174502-6793-4acf-98df-e85b44f3980b</SourceItemGuid23>
+      <SourceItemType23>CSource</SourceItemType23>
+      <SourceItemGuid24>2eeb3b6e-b74b-4f36-98a8-1b4c6d7c3766</SourceItemGuid24>
+      <SourceItemType24>CSource</SourceItemType24>
+      <SourceItemGuid25>f18e4ce9-8cca-44ff-8d9f-d63c7bb293ab</SourceItemGuid25>
+      <SourceItemType25>CSource</SourceItemType25>
+      <SourceItemGuid26>b3b3a308-6b24-4930-82bb-edd785893281</SourceItemGuid26>
+      <SourceItemType26>CSource</SourceItemType26>
+      <SourceItemGuid27>49238843-c08d-4342-95a1-7896eec7f2fc</SourceItemGuid27>
+      <SourceItemType27>CSource</SourceItemType27>
+      <SourceItemGuid28>6584642a-5899-4579-8b26-7a08d0f7b0d8</SourceItemGuid28>
+      <SourceItemType28>CSource</SourceItemType28>
+      <SourceItemGuid29>92df22fc-4f1a-4a9c-a6f9-6fe981a6551b</SourceItemGuid29>
+      <SourceItemType29>CSource</SourceItemType29>
+      <SourceItemGuid30>875a8eb6-b09d-43a5-a6cd-863f5d1de818</SourceItemGuid30>
+      <SourceItemType30>CSource</SourceItemType30>
+      <SourceItemGuid31>42c1cced-3ccb-41d6-a09e-c1f7a9a65254</SourceItemGuid31>
+      <SourceItemType31>CSource</SourceItemType31>
+      <SourceItemGuid32>3e006428-dd0a-4f7f-ab26-8e41e5d3fc63</SourceItemGuid32>
+      <SourceItemType32>CSource</SourceItemType32>
+      <SourceItemGuid33>267fea6c-b9f0-4037-9ad8-cea2f443d560</SourceItemGuid33>
+      <SourceItemType33>CSource</SourceItemType33>
+      <SourceItemGuid34>3d410f00-ba86-47fa-bb43-b9167a5edba6</SourceItemGuid34>
+      <SourceItemType34>CSource</SourceItemType34>
+      <SourceItemGuid35>387c8b98-e894-4de8-8988-31af2fdf4334</SourceItemGuid35>
+      <SourceItemType35>CSource</SourceItemType35>
+      <SourceItemGuid36>ed66d182-bc22-462a-b334-c84306114b1a</SourceItemGuid36>
+      <SourceItemType36>CSource</SourceItemType36>
+      <SourceItemGuid37>ee86d025-7a48-4f67-99f5-3105b26868be</SourceItemGuid37>
+      <SourceItemType37>CSource</SourceItemType37>
+      <SourceItemCount>38</SourceItemCount>
+      <LastDeviceChangedCounter>0</LastDeviceChangedCounter>
+    </Instance>
+    <Instance Guid="9e208646-ccba-4100-a676-29b1efe6545f">
+      <AsmOptionInclude-DefaultValue />
+      <BuildMode-DefaultValue>DefaultBuild</BuildMode-DefaultValue>
+      <COptionInclude-DefaultValue />
+      <GeneralOptionIsa-DefaultValue>RXv1</GeneralOptionIsa-DefaultValue>
+      <GeneralOptionOutput-DefaultValue>LibraryFile</GeneralOptionOutput-DefaultValue>
+      <GeneralOptionPic-DefaultValue>False</GeneralOptionPic-DefaultValue>
+      <GeneralOptionSimultaneousBuild-DefaultValue>True</GeneralOptionSimultaneousBuild-DefaultValue>
+      <HexOptionOutput-DefaultValue>True</HexOptionOutput-DefaultValue>
+      <LibOptionDebug-DefaultValue>Debug</LibOptionDebug-DefaultValue>
+      <LinkOptionLibrary-DefaultValue />
+      <Memo-DefaultValue />
+      <OutputMessageFormat-DefaultValue>%TargetFiles%</OutputMessageFormat-DefaultValue>
+      <AsmOptionSystemInclude-DefaultValue />
+      <COptionSystemInclude-DefaultValue />
+      <CompilerVersion-DefaultValue>
+
+0</CompilerVersion-DefaultValue>
+      <DependencyFileExistCheckingType-DefaultValue>Rebuild</DependencyFileExistCheckingType-DefaultValue>
+      <FormatBuildOptionList-DefaultValue>%TargetFiles% : %Program% %Options%</FormatBuildOptionList-DefaultValue>
+      <GeneralOptionCpu-DefaultValue>RX600</GeneralOptionCpu-DefaultValue>
+      <GeneralOptionOutputFolder-DefaultValue>%BuildModeName%</GeneralOptionOutputFolder-DefaultValue>
+      <GeneralOptionPid-DefaultValue>None</GeneralOptionPid-DefaultValue>
+      <HexOptionForm-DefaultValue>Stype</HexOptionForm-DefaultValue>
+      <LinkOptionDebug-DefaultValue>Debug</LinkOptionDebug-DefaultValue>
+      <AsmOptionDefine-DefaultValue />
+      <COptionDefine-DefaultValue />
+      <EnsureCompatibilityOfPathAndLinkageOrder-DefaultValue>False</EnsureCompatibilityOfPathAndLinkageOrder-DefaultValue>
+      <GeneralOptionFpu-DefaultValue>Fpu</GeneralOptionFpu-DefaultValue>
+      <GeneralOptionNousePidRegister-DefaultValue>True</GeneralOptionNousePidRegister-DefaultValue>
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionOptimize-DefaultValue>None</LinkOptionOptimize-DefaultValue>
+      <AsmOptionDebug-DefaultValue>True</AsmOptionDebug-DefaultValue>
+      <COptionDebug-DefaultValue>True</COptionDebug-DefaultValue>
+      <GeneralOptionEndian-DefaultValue>Little</GeneralOptionEndian-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionOptimizeSymbolDelete-DefaultValue>False</LinkOptionOptimizeSymbolDelete-DefaultValue>
+      <PreBuildCommands-DefaultValue />
+      <AsmOptionGoptimize-DefaultValue>False</AsmOptionGoptimize-DefaultValue>
+      <COptionOptimize-DefaultValue>Level2</COptionOptimize-DefaultValue>
+      <GeneralOptionRound-DefaultValue>Nearest</GeneralOptionRound-DefaultValue>
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionOptimizeSameCode-DefaultValue>False</LinkOptionOptimizeSameCode-DefaultValue>
+      <PostBuildCommands-DefaultValue />
+      <AsmOptionListFile-DefaultValue>False</AsmOptionListFile-DefaultValue>
+      <COptionGoptimize-DefaultValue>False</COptionGoptimize-DefaultValue>
+      <GeneralOptionDenormalize-DefaultValue>Off</GeneralOptionDenormalize-DefaultValue>
+      <LinkOptionSameSize-DefaultValue>1E</LinkOptionSameSize-DefaultValue>
+      <AsmOptionShowConditionals-DefaultValue>False</AsmOptionShowConditionals-DefaultValue>
+      <COptionSpeedAndSize-DefaultValue>Size</COptionSpeedAndSize-DefaultValue>
+      <GeneralOptionDblSize-DefaultValue>SinglePrecision</GeneralOptionDblSize-DefaultValue>
+      <LinkOptionOptimizeShortFormat-DefaultValue>False</LinkOptionOptimizeShortFormat-DefaultValue>
+      <AsmOptionShowDefinitions-DefaultValue>False</AsmOptionShowDefinitions-DefaultValue>
+      <COptionListfile-DefaultValue>False</COptionListfile-DefaultValue>
+      <GeneralOptionIntToShort-DefaultValue>False</GeneralOptionIntToShort-DefaultValue>
+      <LinkOptionOptimizeBranch-DefaultValue>False</LinkOptionOptimizeBranch-DefaultValue>
+      <AsmOptionShowExpansions-DefaultValue>False</AsmOptionShowExpansions-DefaultValue>
+      <COptionShowSource-DefaultValue>False</COptionShowSource-DefaultValue>
+      <GeneralOptionSignedChar-DefaultValue>Unsigned</GeneralOptionSignedChar-DefaultValue>
+      <LinkOptionStart-DefaultValue />
+      <COptionShowConditionals-DefaultValue>False</COptionShowConditionals-DefaultValue>
+      <GeneralOptionOtherAdditionalOptions-DefaultValue />
+      <GeneralOptionSignedBitfield-DefaultValue>Unsigned</GeneralOptionSignedBitfield-DefaultValue>
+      <COptionShowDefinitions-DefaultValue>False</COptionShowDefinitions-DefaultValue>
+      <GeneralOptionAutoEnum-DefaultValue>False</GeneralOptionAutoEnum-DefaultValue>
+      <COptionShowExpansions-DefaultValue>False</COptionShowExpansions-DefaultValue>
+      <GeneralOptionBitOrder-DefaultValue>Right</GeneralOptionBitOrder-DefaultValue>
+      <GeneralOptionPack-DefaultValue>False</GeneralOptionPack-DefaultValue>
+      <GeneralOptionException-DefaultValue>False</GeneralOptionException-DefaultValue>
+      <GeneralOptionRtti-DefaultValue>False</GeneralOptionRtti-DefaultValue>
+      <GeneralOptionFintRegister-DefaultValue>None</GeneralOptionFintRegister-DefaultValue>
+      <GeneralOptionBranch-DefaultValue>Branch24</GeneralOptionBranch-DefaultValue>
+      <GeneralOptionBaseRomRegister-DefaultValue>None</GeneralOptionBaseRomRegister-DefaultValue>
+      <GeneralOptionBaseRamRegister-DefaultValue>None</GeneralOptionBaseRamRegister-DefaultValue>
+      <GeneralOptionBaseAddressAddress-DefaultValue>00000000</GeneralOptionBaseAddressAddress-DefaultValue>
+      <GeneralOptionBaseAddressRegister-DefaultValue>None</GeneralOptionBaseAddressRegister-DefaultValue>
+      <GeneralOptionPatch-DefaultValue>None</GeneralOptionPatch-DefaultValue>
+      <GeneralOptionSaveAcc-DefaultValue>False</GeneralOptionSaveAcc-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587442585163025989</TimeTagModified--0>
+      <BuildMode-0>DefaultBuild</BuildMode-0>
+      <Memo-0 />
+      <OutputMessageFormat-0>%TargetFiles%</OutputMessageFormat-0>
+      <FormatBuildOptionList-0>%TargetFiles% : %Program% %Options%</FormatBuildOptionList-0>
+      <PreBuildCommands-0 />
+      <PostBuildCommands-0 />
+      <GeneralOptionIsa-0>RXv1</GeneralOptionIsa-0>
+      <GeneralOptionOutput-0>LibraryFile</GeneralOptionOutput-0>
+      <GeneralOptionPic-0>False</GeneralOptionPic-0>
+      <GeneralOptionSimultaneousBuild-0>True</GeneralOptionSimultaneousBuild-0>
+      <CompilerVersion-0>
+
+0</CompilerVersion-0>
+      <DependencyFileExistCheckingType-0>Rebuild</DependencyFileExistCheckingType-0>
+      <GeneralOptionCpu-0>RX600</GeneralOptionCpu-0>
+      <GeneralOptionOutputFolder-0>%BuildModeName%</GeneralOptionOutputFolder-0>
+      <GeneralOptionPid-0>None</GeneralOptionPid-0>
+      <EnsureCompatibilityOfPathAndLinkageOrder-0>False</EnsureCompatibilityOfPathAndLinkageOrder-0>
+      <GeneralOptionFpu-0>Fpu</GeneralOptionFpu-0>
+      <GeneralOptionNousePidRegister-0>True</GeneralOptionNousePidRegister-0>
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <GeneralOptionEndian-0>Little</GeneralOptionEndian-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <AsmOptionGoptimize-0>False</AsmOptionGoptimize-0>
+      <GeneralOptionRound-0>Nearest</GeneralOptionRound-0>
+      <LinkOptionMultiConvertFileName-0 />
+      <AsmOptionListFile-0>False</AsmOptionListFile-0>
+      <COptionGoptimize-0>False</COptionGoptimize-0>
+      <GeneralOptionDenormalize-0>Off</GeneralOptionDenormalize-0>
+      <AsmOptionShowConditionals-0>False</AsmOptionShowConditionals-0>
+      <GeneralOptionDblSize-0>SinglePrecision</GeneralOptionDblSize-0>
+      <AsmOptionShowDefinitions-0>False</AsmOptionShowDefinitions-0>
+      <COptionListfile-0>False</COptionListfile-0>
+      <GeneralOptionIntToShort-0>False</GeneralOptionIntToShort-0>
+      <AsmOptionShowExpansions-0>False</AsmOptionShowExpansions-0>
+      <COptionShowSource-0>False</COptionShowSource-0>
+      <GeneralOptionSignedChar-0>Unsigned</GeneralOptionSignedChar-0>
+      <COptionShowConditionals-0>False</COptionShowConditionals-0>
+      <GeneralOptionOtherAdditionalOptions-0 />
+      <GeneralOptionSignedBitfield-0>Unsigned</GeneralOptionSignedBitfield-0>
+      <COptionShowDefinitions-0>False</COptionShowDefinitions-0>
+      <GeneralOptionAutoEnum-0>False</GeneralOptionAutoEnum-0>
+      <COptionShowExpansions-0>False</COptionShowExpansions-0>
+      <GeneralOptionBitOrder-0>Right</GeneralOptionBitOrder-0>
+      <GeneralOptionPack-0>False</GeneralOptionPack-0>
+      <GeneralOptionException-0>False</GeneralOptionException-0>
+      <GeneralOptionRtti-0>False</GeneralOptionRtti-0>
+      <GeneralOptionFintRegister-0>None</GeneralOptionFintRegister-0>
+      <GeneralOptionBranch-0>Branch24</GeneralOptionBranch-0>
+      <GeneralOptionBaseRomRegister-0>None</GeneralOptionBaseRomRegister-0>
+      <GeneralOptionBaseRamRegister-0>None</GeneralOptionBaseRamRegister-0>
+      <GeneralOptionBaseAddressAddress-0>00000000</GeneralOptionBaseAddressAddress-0>
+      <GeneralOptionBaseAddressRegister-0>None</GeneralOptionBaseAddressRegister-0>
+      <GeneralOptionPatch-0>None</GeneralOptionPatch-0>
+      <GeneralOptionSaveAcc-0>False</GeneralOptionSaveAcc-0>
+      <LastCompilerVersion-0>V2.02.00</LastCompilerVersion-0>
+    </Instance>
+    <Instance Guid="95a63257-4aa7-40c0-a74a-7991543b099b">
+      <COptionLangC-DefaultValue>C</COptionLangC-DefaultValue>
+      <COptionListfile-DefaultValue>False</COptionListfile-DefaultValue>
+      <COptionLogo-DefaultValue>False</COptionLogo-DefaultValue>
+      <COptionMisra2004-DefaultValue>None</COptionMisra2004-DefaultValue>
+      <COptionOptimize-DefaultValue>Level2</COptionOptimize-DefaultValue>
+      <COptionOutput-DefaultValue>Object</COptionOutput-DefaultValue>
+      <COptionOutputAssembly-DefaultValue>False</COptionOutputAssembly-DefaultValue>
+      <COptionGoptimize-DefaultValue>False</COptionGoptimize-DefaultValue>
+      <COptionLangCpp-DefaultValue>Cpp</COptionLangCpp-DefaultValue>
+      <COptionMisra2004RuleFile-DefaultValue />
+      <COptionOutputFolder-DefaultValue>%BuildModeName%</COptionOutputFolder-DefaultValue>
+      <COptionOutputPreprocessed-DefaultValue>None</COptionOutputPreprocessed-DefaultValue>
+      <COptionShowSource-DefaultValue>False</COptionShowSource-DefaultValue>
+      <COptionXcref-DefaultValue>False</COptionXcref-DefaultValue>
+      <COptionDebug-DefaultValue>True</COptionDebug-DefaultValue>
+      <COptionInclude-DefaultValue />
+      <COptionMisra2004RuleNumberApply-DefaultValue />
+      <COptionPreCompileCommands-DefaultValue />
+      <COptionShowConditionals-DefaultValue>False</COptionShowConditionals-DefaultValue>
+      <COptionSpeedAndSize-DefaultValue>Size</COptionSpeedAndSize-DefaultValue>
+      <COptionLoop-DefaultValue>Auto</COptionLoop-DefaultValue>
+      <COptionMisra2004RuleNumberIgnore-DefaultValue />
+      <COptionPostCompileCommands-DefaultValue />
+      <COptionSectionP-DefaultValue>P</COptionSectionP-DefaultValue>
+      <COptionShowDefinitions-DefaultValue>False</COptionShowDefinitions-DefaultValue>
+      <COptionSystemInclude-DefaultValue />
+      <COptionLoopValue-DefaultValue>2</COptionLoopValue-DefaultValue>
+      <COptionMisra2004RuleNumberRequiredAdd-DefaultValue />
+      <COptionOtherAdditionalOptions-DefaultValue />
+      <COptionPreinclude-DefaultValue />
+      <COptionSectionC-DefaultValue>C</COptionSectionC-DefaultValue>
+      <COptionShowExpansions-DefaultValue>False</COptionShowExpansions-DefaultValue>
+      <COptionCommandLine-DefaultValue>-isa=rxv1
+-fpu
+-include=.
+-include=..\..\wolfssl-3.7.0
+-include=..\..\lwip-1.4.1\src\include
+-include=..\..\lwip-1.4.1\src\include\ipv4
+-include=..\..\asp_dcre\include
+-include=..\..\asp_dcre\arch
+-include=..\..\asp_dcre\target\grsakura_ccrx
+-include=..\..\fatfs
+-include=..\..\lwip-1.4.1\ports\asp_dcre
+-include=..\..\lwip-1.4.1\ports\grsakura
+-include=..\..\src\usb_watt_meter
+-define=WOLFSSL_RIPEMD,WOLFSSL_SHA512,SIZEOF_LONG_LONG=8
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</COptionCommandLine-DefaultValue>
+      <COptionDefine-DefaultValue />
+      <COptionInline-DefaultValue>Auto</COptionInline-DefaultValue>
+      <COptionMisra2004RuleNumberRequiredRemove-DefaultValue />
+      <COptionSectionD-DefaultValue>D</COptionSectionD-DefaultValue>
+      <COptionIgnoreFilesMisra-DefaultValue />
+      <COptionInlineValue-DefaultValue>100</COptionInlineValue-DefaultValue>
+      <COptionSectionB-DefaultValue>B</COptionSectionB-DefaultValue>
+      <COptionUndefine-DefaultValue />
+      <COptionCheckLanguageExtension-DefaultValue>False</COptionCheckLanguageExtension-DefaultValue>
+      <COptionFileInline-DefaultValue />
+      <COptionMessage-DefaultValue>False</COptionMessage-DefaultValue>
+      <COptionSectionL-DefaultValue>L</COptionSectionL-DefaultValue>
+      <COptionCase-DefaultValue>Auto</COptionCase-DefaultValue>
+      <COptionMessage2-DefaultValue>False</COptionMessage2-DefaultValue>
+      <COptionSectionW-DefaultValue>W</COptionSectionW-DefaultValue>
+      <COptionNoMessageErrorNumber-DefaultValue />
+      <COptionNostuffB-DefaultValue>False</COptionNostuffB-DefaultValue>
+      <COptionVolatile-DefaultValue>False</COptionVolatile-DefaultValue>
+      <COptionConstCopy-DefaultValue>Auto</COptionConstCopy-DefaultValue>
+      <COptionNoMessageErrorNumber2-DefaultValue />
+      <COptionNostuffD-DefaultValue>False</COptionNostuffD-DefaultValue>
+      <COptionChangeMessageInformation-DefaultValue>No</COptionChangeMessageInformation-DefaultValue>
+      <COptionConstDiv-DefaultValue>Auto</COptionConstDiv-DefaultValue>
+      <COptionNostuffC-DefaultValue>False</COptionNostuffC-DefaultValue>
+      <COptionChangeMessageInformationNumber-DefaultValue />
+      <COptionLibrary-DefaultValue>Intrinsic</COptionLibrary-DefaultValue>
+      <COptionNostuffW-DefaultValue>False</COptionNostuffW-DefaultValue>
+      <COptionChangeMessageInformationNumber2-DefaultValue />
+      <COptionInstalign-DefaultValue>Noinstalign</COptionInstalign-DefaultValue>
+      <COptionScope-DefaultValue>Auto</COptionScope-DefaultValue>
+      <COptionChangeMessageWarning-DefaultValue>No</COptionChangeMessageWarning-DefaultValue>
+      <COptionNouseDiv-DefaultValue>True</COptionNouseDiv-DefaultValue>
+      <COptionSchedule-DefaultValue>Auto</COptionSchedule-DefaultValue>
+      <COptionChangeMessageWarningNumber-DefaultValue />
+      <COptionMap-DefaultValue>NoMap</COptionMap-DefaultValue>
+      <COptionOutcode-DefaultValue>Sjis</COptionOutcode-DefaultValue>
+      <COptionChangeMessageWarningNumber2-DefaultValue />
+      <COptionIntermodule-DefaultValue>None</COptionIntermodule-DefaultValue>
+      <COptionApproxdiv-DefaultValue>False</COptionApproxdiv-DefaultValue>
+      <COptionChangeMessageError-DefaultValue>No</COptionChangeMessageError-DefaultValue>
+      <COptionChangeMessageErrorNumber-DefaultValue />
+      <COptionEnableRegister-DefaultValue>False</COptionEnableRegister-DefaultValue>
+      <COptionChangeMessageErrorNumber2-DefaultValue />
+      <COptionSimpleFloatConv-DefaultValue>False</COptionSimpleFloatConv-DefaultValue>
+      <COptionFileInlinePath-DefaultValue />
+      <COptionFpu-DefaultValue>Fpu</COptionFpu-DefaultValue>
+      <COptionAlias-DefaultValue>False</COptionAlias-DefaultValue>
+      <COptionComment-DefaultValue>False</COptionComment-DefaultValue>
+      <COptionCheck-DefaultValue>No</COptionCheck-DefaultValue>
+      <COptionFloatOrder-DefaultValue>False</COptionFloatOrder-DefaultValue>
+      <COptionIncode-DefaultValue>Sjis</COptionIncode-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587457383419295853</TimeTagModified--0>
+      <COptionLangC-0>C99</COptionLangC-0>
+      <COptionListfile-0>False</COptionListfile-0>
+      <COptionLogo-0>False</COptionLogo-0>
+      <COptionMisra2004-0>None</COptionMisra2004-0>
+      <COptionOptimize-0>Level2</COptionOptimize-0>
+      <COptionOutput-0>Object</COptionOutput-0>
+      <COptionOutputAssembly-0>False</COptionOutputAssembly-0>
+      <COptionGoptimize-0>False</COptionGoptimize-0>
+      <COptionLangCpp-0>Cpp</COptionLangCpp-0>
+      <COptionMisra2004RuleFile-0 />
+      <COptionOutputFolder-0>%BuildModeName%</COptionOutputFolder-0>
+      <COptionOutputPreprocessed-0>None</COptionOutputPreprocessed-0>
+      <COptionShowSource-0>False</COptionShowSource-0>
+      <COptionXcref-0>False</COptionXcref-0>
+      <COptionDebug-0>True</COptionDebug-0>
+      <COptionInclude-0>.
+..\..\wolfssl-3.7.0
+..\..\lwip-1.4.1\src\include
+..\..\lwip-1.4.1\src\include\ipv4
+..\..\asp_dcre\include
+..\..\asp_dcre\arch
+..\..\asp_dcre\target\grsakura_ccrx
+..\..\fatfs
+..\..\lwip-1.4.1\ports\ccrx
+..\..\lwip-1.4.1\ports\asp_dcre
+..\..\lwip-1.4.1\ports\grsakura
+..\..\src\usb_watt_meter
+</COptionInclude-0>
+      <COptionMisra2004RuleNumberApply-0 />
+      <COptionPreCompileCommands-0 />
+      <COptionShowConditionals-0>False</COptionShowConditionals-0>
+      <COptionSpeedAndSize-0>Size</COptionSpeedAndSize-0>
+      <COptionLoop-0>Auto</COptionLoop-0>
+      <COptionMisra2004RuleNumberIgnore-0 />
+      <COptionPostCompileCommands-0 />
+      <COptionSectionP-0>P</COptionSectionP-0>
+      <COptionShowDefinitions-0>False</COptionShowDefinitions-0>
+      <COptionSystemInclude-0 />
+      <COptionLoopValue-0>2</COptionLoopValue-0>
+      <COptionMisra2004RuleNumberRequiredAdd-0 />
+      <COptionOtherAdditionalOptions-0 />
+      <COptionPreinclude-0 />
+      <COptionSectionC-0>C</COptionSectionC-0>
+      <COptionShowExpansions-0>False</COptionShowExpansions-0>
+      <COptionCommandLine-0>-isa=rxv1
+-fpu
+-include=.
+-include=..\..\wolfssl-3.7.0
+-include=..\..\lwip-1.4.1\src\include
+-include=..\..\lwip-1.4.1\src\include\ipv4
+-include=..\..\asp_dcre\include
+-include=..\..\asp_dcre\arch
+-include=..\..\asp_dcre\target\grsakura_ccrx
+-include=..\..\fatfs
+-include=..\..\lwip-1.4.1\ports\asp_dcre
+-include=..\..\lwip-1.4.1\ports\grsakura
+-include=..\..\src\usb_watt_meter
+-define=WOLFSSL_RIPEMD,WOLFSSL_SHA512,SIZEOF_LONG_LONG=8
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</COptionCommandLine-0>
+      <COptionDefine-0>WOLFSSL_RIPEMD
+WOLFSSL_SHA512
+SIZEOF_LONG_LONG=8
+</COptionDefine-0>
+      <COptionInline-0>Auto</COptionInline-0>
+      <COptionMisra2004RuleNumberRequiredRemove-0 />
+      <COptionSectionD-0>D</COptionSectionD-0>
+      <COptionIgnoreFilesMisra-0 />
+      <COptionInlineValue-0>100</COptionInlineValue-0>
+      <COptionSectionB-0>B</COptionSectionB-0>
+      <COptionUndefine-0 />
+      <COptionCheckLanguageExtension-0>False</COptionCheckLanguageExtension-0>
+      <COptionFileInline-0 />
+      <COptionMessage-0>False</COptionMessage-0>
+      <COptionSectionL-0>L</COptionSectionL-0>
+      <COptionCase-0>Auto</COptionCase-0>
+      <COptionSectionW-0>W</COptionSectionW-0>
+      <COptionNoMessageErrorNumber-0 />
+      <COptionNostuffB-0>False</COptionNostuffB-0>
+      <COptionVolatile-0>False</COptionVolatile-0>
+      <COptionConstCopy-0>Auto</COptionConstCopy-0>
+      <COptionNostuffD-0>False</COptionNostuffD-0>
+      <COptionChangeMessageInformation-0>No</COptionChangeMessageInformation-0>
+      <COptionConstDiv-0>Auto</COptionConstDiv-0>
+      <COptionNostuffC-0>False</COptionNostuffC-0>
+      <COptionChangeMessageInformationNumber-0 />
+      <COptionLibrary-0>Intrinsic</COptionLibrary-0>
+      <COptionNostuffW-0>False</COptionNostuffW-0>
+      <COptionInstalign-0>Noinstalign</COptionInstalign-0>
+      <COptionScope-0>Auto</COptionScope-0>
+      <COptionChangeMessageWarning-0>No</COptionChangeMessageWarning-0>
+      <COptionNouseDiv-0>True</COptionNouseDiv-0>
+      <COptionSchedule-0>Auto</COptionSchedule-0>
+      <COptionChangeMessageWarningNumber-0 />
+      <COptionMap-0>NoMap</COptionMap-0>
+      <COptionOutcode-0>Sjis</COptionOutcode-0>
+      <COptionIntermodule-0>None</COptionIntermodule-0>
+      <COptionApproxdiv-0>False</COptionApproxdiv-0>
+      <COptionChangeMessageError-0>No</COptionChangeMessageError-0>
+      <COptionChangeMessageErrorNumber-0 />
+      <COptionEnableRegister-0>False</COptionEnableRegister-0>
+      <COptionSimpleFloatConv-0>False</COptionSimpleFloatConv-0>
+      <COptionFileInlinePath-0 />
+      <COptionFpu-0>Fpu</COptionFpu-0>
+      <COptionAlias-0>False</COptionAlias-0>
+      <COptionComment-0>False</COptionComment-0>
+      <COptionCheck-0>No</COptionCheck-0>
+      <COptionFloatOrder-0>False</COptionFloatOrder-0>
+      <COptionIncode-0>Sjis</COptionIncode-0>
+    </Instance>
+    <Instance Guid="5ad1746c-d03e-4610-a91f-aaa4fb37bc10">
+      <AsmOptionChkpm-DefaultValue>False</AsmOptionChkpm-DefaultValue>
+      <AsmOptionGoptimize-DefaultValue>False</AsmOptionGoptimize-DefaultValue>
+      <AsmOptionInclude-DefaultValue />
+      <AsmOptionListFile-DefaultValue>False</AsmOptionListFile-DefaultValue>
+      <AsmOptionOutput-DefaultValue>%BuildModeName%</AsmOptionOutput-DefaultValue>
+      <AsmOptionChkfpu-DefaultValue>False</AsmOptionChkfpu-DefaultValue>
+      <AsmOptionDebug-DefaultValue>True</AsmOptionDebug-DefaultValue>
+      <AsmOptionShowConditionals-DefaultValue>False</AsmOptionShowConditionals-DefaultValue>
+      <AsmOptionSystemInclude-DefaultValue />
+      <AsmOptionChkdsp-DefaultValue>False</AsmOptionChkdsp-DefaultValue>
+      <AsmOptionDefine-DefaultValue />
+      <AsmOptionShowDefinitions-DefaultValue>False</AsmOptionShowDefinitions-DefaultValue>
+      <AsmOptionInCode-DefaultValue>SJIS</AsmOptionInCode-DefaultValue>
+      <AsmOptionLogo-DefaultValue>False</AsmOptionLogo-DefaultValue>
+      <AsmOptionShowExpansions-DefaultValue>False</AsmOptionShowExpansions-DefaultValue>
+      <AsmOptionPreAssembleCommands-DefaultValue />
+      <AsmOptionPostAssembleCommands-DefaultValue />
+      <AsmOptionOtherAdditionalOptions-DefaultValue />
+      <AsmOptionCommandLine-DefaultValue />
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587490453535448457</TimeTagModified--0>
+      <AsmOptionChkpm-0>False</AsmOptionChkpm-0>
+      <AsmOptionGoptimize-0>False</AsmOptionGoptimize-0>
+      <AsmOptionInclude-0 />
+      <AsmOptionListFile-0>False</AsmOptionListFile-0>
+      <AsmOptionOutput-0>%BuildModeName%</AsmOptionOutput-0>
+      <AsmOptionChkfpu-0>False</AsmOptionChkfpu-0>
+      <AsmOptionDebug-0>True</AsmOptionDebug-0>
+      <AsmOptionShowConditionals-0>False</AsmOptionShowConditionals-0>
+      <AsmOptionSystemInclude-0 />
+      <AsmOptionChkdsp-0>False</AsmOptionChkdsp-0>
+      <AsmOptionDefine-0 />
+      <AsmOptionShowDefinitions-0>False</AsmOptionShowDefinitions-0>
+      <AsmOptionInCode-0>SJIS</AsmOptionInCode-0>
+      <AsmOptionLogo-0>False</AsmOptionLogo-0>
+      <AsmOptionShowExpansions-0>False</AsmOptionShowExpansions-0>
+      <AsmOptionPreAssembleCommands-0 />
+      <AsmOptionPostAssembleCommands-0 />
+      <AsmOptionOtherAdditionalOptions-0 />
+      <AsmOptionCommandLine-0 />
+    </Instance>
+    <Instance Guid="dbb16727-3e81-4169-956a-790355cab4a1">
+      <LinkOptionCpu-DefaultValue>False</LinkOptionCpu-DefaultValue>
+      <LinkOptionForm-DefaultValue>Absolute</LinkOptionForm-DefaultValue>
+      <LinkOptionFormConvert-DefaultValue>Stype</LinkOptionFormConvert-DefaultValue>
+      <LinkOptionInput-DefaultValue />
+      <LinkOptionListShow-DefaultValue>None</LinkOptionListShow-DefaultValue>
+      <LinkOptionOptimize-DefaultValue>None</LinkOptionOptimize-DefaultValue>
+      <LinkOptionStack-DefaultValue>False</LinkOptionStack-DefaultValue>
+      <LinkOptionStart-DefaultValue />
+      <LinkOptionCompress-DefaultValue>False</LinkOptionCompress-DefaultValue>
+      <LinkOptionCpuInformation-DefaultValue />
+      <LinkOptionDebug-DefaultValue>Debug</LinkOptionDebug-DefaultValue>
+      <LinkOptionFSymbol-DefaultValue />
+      <LinkOptionLibrary-DefaultValue />
+      <LinkOptionOptimizeSymbolDelete-DefaultValue>False</LinkOptionOptimizeSymbolDelete-DefaultValue>
+      <LinkOptionRecordH-DefaultValue>None</LinkOptionRecordH-DefaultValue>
+      <LinkOptionShowSymbol-DefaultValue>False</LinkOptionShowSymbol-DefaultValue>
+      <LinkOptionAlignedSection-DefaultValue />
+      <LinkOptionCpuStride-DefaultValue>False</LinkOptionCpuStride-DefaultValue>
+      <LinkOptionMemory-DefaultValue>False</LinkOptionMemory-DefaultValue>
+      <LinkOptionOptimizeSameCode-DefaultValue>False</LinkOptionOptimizeSameCode-DefaultValue>
+      <LinkOptionOutputFolder-DefaultValue>%BuildModeName%</LinkOptionOutputFolder-DefaultValue>
+      <LinkOptionRecordS-DefaultValue>None</LinkOptionRecordS-DefaultValue>
+      <LinkOptionShowReference-DefaultValue>False</LinkOptionShowReference-DefaultValue>
+      <LinkOptionSystemLibrary-DefaultValue />
+      <LinkOptionBinary-DefaultValue />
+      <LinkOptionChangeMessageInformation-DefaultValue>None</LinkOptionChangeMessageInformation-DefaultValue>
+      <LinkOptionContiguousSection-DefaultValue />
+      <LinkOptionDividedConvertFile-DefaultValue>False</LinkOptionDividedConvertFile-DefaultValue>
+      <LinkOptionOutputFileName-DefaultValue>%ProjectName%.abs</LinkOptionOutputFileName-DefaultValue>
+      <LinkOptionRom-DefaultValue />
+      <LinkOptionSameSize-DefaultValue>1E</LinkOptionSameSize-DefaultValue>
+      <LinkOptionShowXreference-DefaultValue>False</LinkOptionShowXreference-DefaultValue>
+      <LinkOptionChangeMessageInformationNumber-DefaultValue />
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionDefine-DefaultValue />
+      <LinkOptionMap-DefaultValue>False</LinkOptionMap-DefaultValue>
+      <LinkOptionOptimizeShortFormat-DefaultValue>False</LinkOptionOptimizeShortFormat-DefaultValue>
+      <LinkOptionShowTotalSize-DefaultValue>False</LinkOptionShowTotalSize-DefaultValue>
+      <LinkOptionChangeMessageWarning-DefaultValue>None</LinkOptionChangeMessageWarning-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionEntry-DefaultValue>False</LinkOptionEntry-DefaultValue>
+      <LinkOptionMessage-DefaultValue>NoMessage</LinkOptionMessage-DefaultValue>
+      <LinkOptionOptimizeBranch-DefaultValue>False</LinkOptionOptimizeBranch-DefaultValue>
+      <LinkOptionShowVector-DefaultValue>False</LinkOptionShowVector-DefaultValue>
+      <LinkOptionChangeMessageWarningNumber-DefaultValue />
+      <LinkOptionEntryPoint-DefaultValue />
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionNoMessageErrorNumber-DefaultValue />
+      <LinkOptionSymbolForbid-DefaultValue />
+      <LinkOptionChangeMessageError-DefaultValue>None</LinkOptionChangeMessageError-DefaultValue>
+      <LinkOptionNoPrelink-DefaultValue>Auto</LinkOptionNoPrelink-DefaultValue>
+      <LinkOptionPadding-DefaultValue>False</LinkOptionPadding-DefaultValue>
+      <LinkOptionSameCodeForbid-DefaultValue />
+      <LinkOptionSpace-DefaultValue>None</LinkOptionSpace-DefaultValue>
+      <LinkOptionChangeMessageErrorNumber-DefaultValue />
+      <LinkOptionSectionForbid-DefaultValue />
+      <LinkOptionSpaceValue-DefaultValue>FF</LinkOptionSpaceValue-DefaultValue>
+      <LinkOptionVectN-DefaultValue />
+      <LinkOptionAbsoluteForbid-DefaultValue />
+      <LinkOptionByteCount-DefaultValue>False</LinkOptionByteCount-DefaultValue>
+      <LinkOptionHide-DefaultValue>False</LinkOptionHide-DefaultValue>
+      <LinkOptionVect-DefaultValue />
+      <LinkOptionByteCountValue-DefaultValue>FF</LinkOptionByteCountValue-DefaultValue>
+      <LinkOptionJumpEntriesForPic-DefaultValue>False</LinkOptionJumpEntriesForPic-DefaultValue>
+      <LinkOptionTotalSize-DefaultValue>False</LinkOptionTotalSize-DefaultValue>
+      <LinkOptionCrc-DefaultValue>None</LinkOptionCrc-DefaultValue>
+      <LinkOptionJumpEntriesForPicSectionName-DefaultValue />
+      <LinkOptionLogo-DefaultValue>False</LinkOptionLogo-DefaultValue>
+      <LinkOptionCrcOutputAddress-DefaultValue>0</LinkOptionCrcOutputAddress-DefaultValue>
+      <LinkOptionPreLinkCommands-DefaultValue />
+      <LinkOptionCrcCalculationRange-DefaultValue />
+      <LinkOptionPostLinkCommands-DefaultValue />
+      <LinkOptionOtherAdditionalOptionsForLoadModule-DefaultValue />
+      <LinkOptionS9-DefaultValue>False</LinkOptionS9-DefaultValue>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-DefaultValue />
+      <LinkOptionCommandLine-DefaultValue />
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587485723834711443</TimeTagModified--0>
+      <LinkOptionCpu-0>False</LinkOptionCpu-0>
+      <LinkOptionForm-0>Absolute</LinkOptionForm-0>
+      <LinkOptionFormConvert-0>Stype</LinkOptionFormConvert-0>
+      <LinkOptionInput-0 />
+      <LinkOptionListShow-0>None</LinkOptionListShow-0>
+      <LinkOptionOptimize-0>None</LinkOptionOptimize-0>
+      <LinkOptionStack-0>False</LinkOptionStack-0>
+      <LinkOptionStart-0 />
+      <LinkOptionCompress-0>False</LinkOptionCompress-0>
+      <LinkOptionCpuInformation-0 />
+      <LinkOptionDebug-0>Debug</LinkOptionDebug-0>
+      <LinkOptionFSymbol-0 />
+      <LinkOptionLibrary-0 />
+      <LinkOptionOptimizeSymbolDelete-0>False</LinkOptionOptimizeSymbolDelete-0>
+      <LinkOptionRecordH-0>None</LinkOptionRecordH-0>
+      <LinkOptionShowSymbol-0>False</LinkOptionShowSymbol-0>
+      <LinkOptionAlignedSection-0 />
+      <LinkOptionCpuStride-0>False</LinkOptionCpuStride-0>
+      <LinkOptionMemory-0>False</LinkOptionMemory-0>
+      <LinkOptionOptimizeSameCode-0>False</LinkOptionOptimizeSameCode-0>
+      <LinkOptionOutputFolder-0>%BuildModeName%</LinkOptionOutputFolder-0>
+      <LinkOptionRecordS-0>None</LinkOptionRecordS-0>
+      <LinkOptionShowReference-0>False</LinkOptionShowReference-0>
+      <LinkOptionSystemLibrary-0 />
+      <LinkOptionBinary-0 />
+      <LinkOptionChangeMessageInformation-0>None</LinkOptionChangeMessageInformation-0>
+      <LinkOptionContiguousSection-0 />
+      <LinkOptionDividedConvertFile-0>False</LinkOptionDividedConvertFile-0>
+      <LinkOptionOutputFileName-0>%ProjectName%.abs</LinkOptionOutputFileName-0>
+      <LinkOptionRom-0 />
+      <LinkOptionSameSize-0>1E</LinkOptionSameSize-0>
+      <LinkOptionShowXreference-0>False</LinkOptionShowXreference-0>
+      <LinkOptionChangeMessageInformationNumber-0 />
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <LinkOptionDefine-0 />
+      <LinkOptionMap-0>False</LinkOptionMap-0>
+      <LinkOptionOptimizeShortFormat-0>False</LinkOptionOptimizeShortFormat-0>
+      <LinkOptionShowTotalSize-0>False</LinkOptionShowTotalSize-0>
+      <LinkOptionChangeMessageWarning-0>None</LinkOptionChangeMessageWarning-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <LinkOptionEntry-0>False</LinkOptionEntry-0>
+      <LinkOptionMessage-0>NoMessage</LinkOptionMessage-0>
+      <LinkOptionOptimizeBranch-0>False</LinkOptionOptimizeBranch-0>
+      <LinkOptionShowVector-0>False</LinkOptionShowVector-0>
+      <LinkOptionChangeMessageWarningNumber-0 />
+      <LinkOptionEntryPoint-0 />
+      <LinkOptionMultiConvertFileName-0 />
+      <LinkOptionNoMessageErrorNumber-0 />
+      <LinkOptionSymbolForbid-0 />
+      <LinkOptionChangeMessageError-0>None</LinkOptionChangeMessageError-0>
+      <LinkOptionNoPrelink-0>Auto</LinkOptionNoPrelink-0>
+      <LinkOptionPadding-0>False</LinkOptionPadding-0>
+      <LinkOptionSameCodeForbid-0 />
+      <LinkOptionSpace-0>None</LinkOptionSpace-0>
+      <LinkOptionChangeMessageErrorNumber-0 />
+      <LinkOptionSectionForbid-0 />
+      <LinkOptionSpaceValue-0>FF</LinkOptionSpaceValue-0>
+      <LinkOptionVectN-0 />
+      <LinkOptionAbsoluteForbid-0 />
+      <LinkOptionByteCount-0>False</LinkOptionByteCount-0>
+      <LinkOptionHide-0>False</LinkOptionHide-0>
+      <LinkOptionVect-0 />
+      <LinkOptionByteCountValue-0>FF</LinkOptionByteCountValue-0>
+      <LinkOptionJumpEntriesForPic-0>False</LinkOptionJumpEntriesForPic-0>
+      <LinkOptionTotalSize-0>False</LinkOptionTotalSize-0>
+      <LinkOptionCrc-0>None</LinkOptionCrc-0>
+      <LinkOptionJumpEntriesForPicSectionName-0 />
+      <LinkOptionLogo-0>False</LinkOptionLogo-0>
+      <LinkOptionCrcOutputAddress-0>0</LinkOptionCrcOutputAddress-0>
+      <LinkOptionPreLinkCommands-0 />
+      <LinkOptionCrcCalculationRange-0 />
+      <LinkOptionPostLinkCommands-0 />
+      <LinkOptionOtherAdditionalOptionsForLoadModule-0 />
+      <LinkOptionS9-0>False</LinkOptionS9-0>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-0 />
+      <LinkOptionCommandLine-0 />
+    </Instance>
+    <Instance Guid="df74c69e-635e-42d9-845e-14128ba4d48a">
+      <HexOptionForm-DefaultValue>Stype</HexOptionForm-DefaultValue>
+      <HexOptionOutput-DefaultValue>True</HexOptionOutput-DefaultValue>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-DefaultValue />
+      <HexOptionCommandLine-DefaultValue />
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionRecordH-DefaultValue>None</LinkOptionRecordH-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionRecordS-DefaultValue>None</LinkOptionRecordS-DefaultValue>
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionSpace-DefaultValue>None</LinkOptionSpace-DefaultValue>
+      <LinkOptionSpaceValue-DefaultValue>FF</LinkOptionSpaceValue-DefaultValue>
+      <LinkOptionByteCount-DefaultValue>False</LinkOptionByteCount-DefaultValue>
+      <LinkOptionByteCountValue-DefaultValue>FF</LinkOptionByteCountValue-DefaultValue>
+      <LinkOptionCrc-DefaultValue>None</LinkOptionCrc-DefaultValue>
+      <LinkOptionCrcOutputAddress-DefaultValue>0</LinkOptionCrcOutputAddress-DefaultValue>
+      <LinkOptionCrcCalculationRange-DefaultValue />
+      <LinkOptionS9-DefaultValue>False</LinkOptionS9-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587490453535448457</TimeTagModified--0>
+      <HexOptionForm-0>Stype</HexOptionForm-0>
+      <HexOptionOutput-0>True</HexOptionOutput-0>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-0 />
+      <HexOptionCommandLine-0 />
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <LinkOptionRecordH-0>None</LinkOptionRecordH-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <LinkOptionRecordS-0>None</LinkOptionRecordS-0>
+      <LinkOptionMultiConvertFileName-0 />
+      <LinkOptionSpace-0>None</LinkOptionSpace-0>
+      <LinkOptionSpaceValue-0>FF</LinkOptionSpaceValue-0>
+      <LinkOptionByteCount-0>False</LinkOptionByteCount-0>
+      <LinkOptionByteCountValue-0>FF</LinkOptionByteCountValue-0>
+      <LinkOptionCrc-0>None</LinkOptionCrc-0>
+      <LinkOptionCrcOutputAddress-0>0</LinkOptionCrcOutputAddress-0>
+      <LinkOptionCrcCalculationRange-0 />
+      <LinkOptionS9-0>False</LinkOptionS9-0>
+    </Instance>
+    <Instance Guid="fff50d2e-74da-44ea-90a8-c47756029e83">
+      <LibOptionForm-DefaultValue>LibraryU</LibOptionForm-DefaultValue>
+      <LibOptionInput-DefaultValue />
+      <LibOptionListShow-DefaultValue>List</LibOptionListShow-DefaultValue>
+      <LibOptionMemory-DefaultValue>False</LibOptionMemory-DefaultValue>
+      <LibOptionChangeMessageInformation-DefaultValue>None</LibOptionChangeMessageInformation-DefaultValue>
+      <LibOptionDebug-DefaultValue>Debug</LibOptionDebug-DefaultValue>
+      <LibOptionLibrary-DefaultValue />
+      <LibOptionShowSymbol-DefaultValue>False</LibOptionShowSymbol-DefaultValue>
+      <LibOptionChangeMessageInformationNumber-DefaultValue />
+      <LibOptionOutputFolder-DefaultValue>%BuildModeName%</LibOptionOutputFolder-DefaultValue>
+      <LibOptionShowSection-DefaultValue>False</LibOptionShowSection-DefaultValue>
+      <LibOptionSystemLibrary-DefaultValue />
+      <LibOptionBinary-DefaultValue />
+      <LibOptionChangeMessageWarning-DefaultValue>None</LibOptionChangeMessageWarning-DefaultValue>
+      <LibOptionOutputFileName-DefaultValue>%ProjectName%.lib</LibOptionOutputFileName-DefaultValue>
+      <LibOptionShowXreference-DefaultValue>False</LibOptionShowXreference-DefaultValue>
+      <LibOptionChangeMessageWarningNumber-DefaultValue />
+      <LibOptionMessage-DefaultValue>NoMessage</LibOptionMessage-DefaultValue>
+      <LibOptionNoPrelink-DefaultValue>Auto</LibOptionNoPrelink-DefaultValue>
+      <LibOptionShowTotalSize-DefaultValue>False</LibOptionShowTotalSize-DefaultValue>
+      <LibOptionChangeMessageError-DefaultValue>None</LibOptionChangeMessageError-DefaultValue>
+      <LibOptionNoMessageErrorNumber-DefaultValue />
+      <LibOptionShowVector-DefaultValue>False</LibOptionShowVector-DefaultValue>
+      <LibOptionChangeMessageErrorNumber-DefaultValue />
+      <LibOptionHide-DefaultValue>False</LibOptionHide-DefaultValue>
+      <LibOptionTotalSize-DefaultValue>False</LibOptionTotalSize-DefaultValue>
+      <LibOptionLogo-DefaultValue>False</LibOptionLogo-DefaultValue>
+      <LibOptionPreLibrarianCommands-DefaultValue />
+      <LibOptionPostLibrarianCommands-DefaultValue />
+      <LibOptionOtherAdditionalOptions-DefaultValue />
+      <LibOptionCommandLine-DefaultValue />
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587490453535448457</TimeTagModified--0>
+      <LibOptionForm-0>LibraryU</LibOptionForm-0>
+      <LibOptionInput-0 />
+      <LibOptionListShow-0>List</LibOptionListShow-0>
+      <LibOptionMemory-0>False</LibOptionMemory-0>
+      <LibOptionChangeMessageInformation-0>None</LibOptionChangeMessageInformation-0>
+      <LibOptionDebug-0>Debug</LibOptionDebug-0>
+      <LibOptionLibrary-0 />
+      <LibOptionShowSymbol-0>False</LibOptionShowSymbol-0>
+      <LibOptionChangeMessageInformationNumber-0 />
+      <LibOptionOutputFolder-0>%BuildModeName%</LibOptionOutputFolder-0>
+      <LibOptionShowSection-0>False</LibOptionShowSection-0>
+      <LibOptionSystemLibrary-0 />
+      <LibOptionBinary-0 />
+      <LibOptionChangeMessageWarning-0>None</LibOptionChangeMessageWarning-0>
+      <LibOptionOutputFileName-0>%ProjectName%.lib</LibOptionOutputFileName-0>
+      <LibOptionShowXreference-0>False</LibOptionShowXreference-0>
+      <LibOptionChangeMessageWarningNumber-0 />
+      <LibOptionMessage-0>NoMessage</LibOptionMessage-0>
+      <LibOptionNoPrelink-0>Auto</LibOptionNoPrelink-0>
+      <LibOptionShowTotalSize-0>False</LibOptionShowTotalSize-0>
+      <LibOptionChangeMessageError-0>None</LibOptionChangeMessageError-0>
+      <LibOptionNoMessageErrorNumber-0 />
+      <LibOptionShowVector-0>False</LibOptionShowVector-0>
+      <LibOptionChangeMessageErrorNumber-0 />
+      <LibOptionHide-0>False</LibOptionHide-0>
+      <LibOptionTotalSize-0>False</LibOptionTotalSize-0>
+      <LibOptionLogo-0>False</LibOptionLogo-0>
+      <LibOptionPreLibrarianCommands-0 />
+      <LibOptionPostLibrarianCommands-0 />
+      <LibOptionOtherAdditionalOptions-0 />
+      <LibOptionCommandLine-0 />
+    </Instance>
+    <Instance Guid="9cb0ade0-b3cb-4e21-823c-290b5fdb5f1e">
+      <LbgOptionLanguage-DefaultValue>C</LbgOptionLanguage-DefaultValue>
+      <LbgOptionLibraryMode-DefaultValue>None</LbgOptionLibraryMode-DefaultValue>
+      <LbgOptionLogo-DefaultValue>False</LbgOptionLogo-DefaultValue>
+      <LbgOptionOptimize-DefaultValue>Level2</LbgOptionOptimize-DefaultValue>
+      <LbgOptionOutputFolder-DefaultValue>%BuildModeName%</LbgOptionOutputFolder-DefaultValue>
+      <LbgOptionGoptimize-DefaultValue>False</LbgOptionGoptimize-DefaultValue>
+      <LbgOptionHead-DefaultValue>Custom</LbgOptionHead-DefaultValue>
+      <LbgOptionOutputFileName-DefaultValue>%ProjectName%.lib</LbgOptionOutputFileName-DefaultValue>
+      <LbgOptionPreLibraryGenerateCommands-DefaultValue />
+      <LbgOptionFunctionalCutdown-DefaultValue>None</LbgOptionFunctionalCutdown-DefaultValue>
+      <LbgOptionHeadRuntime-DefaultValue>True</LbgOptionHeadRuntime-DefaultValue>
+      <LbgOptionPostLibraryGenerateCommands-DefaultValue />
+      <LbgOptionSpeedAndSize-DefaultValue>Size</LbgOptionSpeedAndSize-DefaultValue>
+      <LbgOptionHeadCtypeH-DefaultValue>False</LbgOptionHeadCtypeH-DefaultValue>
+      <LbgOptionLoop-DefaultValue>Auto</LbgOptionLoop-DefaultValue>
+      <LbgOptionOtherAdditionalOptions-DefaultValue />
+      <LbgOptionReent-DefaultValue>False</LbgOptionReent-DefaultValue>
+      <LbgOptionCommandLine-DefaultValue />
+      <LbgOptionHeadMathH-DefaultValue>False</LbgOptionHeadMathH-DefaultValue>
+      <LbgOptionLoopValue-DefaultValue>2</LbgOptionLoopValue-DefaultValue>
+      <LbgOptionSectionP-DefaultValue>P</LbgOptionSectionP-DefaultValue>
+      <LbgOptionHeadMathfH-DefaultValue>False</LbgOptionHeadMathfH-DefaultValue>
+      <LbgOptionInline-DefaultValue>Auto</LbgOptionInline-DefaultValue>
+      <LbgOptionSectionC-DefaultValue>C</LbgOptionSectionC-DefaultValue>
+      <LbgOptionHeadStdargH-DefaultValue>False</LbgOptionHeadStdargH-DefaultValue>
+      <LbgOptionInlineValue-DefaultValue>100</LbgOptionInlineValue-DefaultValue>
+      <LbgOptionSectionD-DefaultValue>D</LbgOptionSectionD-DefaultValue>
+      <LbgOptionFileInline-DefaultValue />
+      <LbgOptionHeadStdioH-DefaultValue>True</LbgOptionHeadStdioH-DefaultValue>
+      <LbgOptionSectionB-DefaultValue>B</LbgOptionSectionB-DefaultValue>
+      <LbgOptionCase-DefaultValue>Auto</LbgOptionCase-DefaultValue>
+      <LbgOptionHeadStdlibH-DefaultValue>True</LbgOptionHeadStdlibH-DefaultValue>
+      <LbgOptionSectionL-DefaultValue>L</LbgOptionSectionL-DefaultValue>
+      <LbgOptionHeadStringH-DefaultValue>True</LbgOptionHeadStringH-DefaultValue>
+      <LbgOptionSectionW-DefaultValue>W</LbgOptionSectionW-DefaultValue>
+      <LbgOptionVolatile-DefaultValue>False</LbgOptionVolatile-DefaultValue>
+      <LbgOptionConstCopy-DefaultValue>Auto</LbgOptionConstCopy-DefaultValue>
+      <LbgOptionHeadIos-DefaultValue>False</LbgOptionHeadIos-DefaultValue>
+      <LbgOptionNostuffB-DefaultValue>False</LbgOptionNostuffB-DefaultValue>
+      <LbgOptionConstDiv-DefaultValue>Auto</LbgOptionConstDiv-DefaultValue>
+      <LbgOptionHeadNew-DefaultValue>True</LbgOptionHeadNew-DefaultValue>
+      <LbgOptionNostuffD-DefaultValue>False</LbgOptionNostuffD-DefaultValue>
+      <LbgOptionHeadComplex-DefaultValue>False</LbgOptionHeadComplex-DefaultValue>
+      <LbgOptionLibrary-DefaultValue>Intrinsic</LbgOptionLibrary-DefaultValue>
+      <LbgOptionNostuffC-DefaultValue>False</LbgOptionNostuffC-DefaultValue>
+      <LbgOptionHeadString-DefaultValue>False</LbgOptionHeadString-DefaultValue>
+      <LbgOptionNostuffW-DefaultValue>False</LbgOptionNostuffW-DefaultValue>
+      <LbgOptionScope-DefaultValue>Auto</LbgOptionScope-DefaultValue>
+      <LbgOptionHeadComplexH-DefaultValue>False</LbgOptionHeadComplexH-DefaultValue>
+      <LbgOptionInstalign-DefaultValue>Noinstalign</LbgOptionInstalign-DefaultValue>
+      <LbgOptionSchedule-DefaultValue>Auto</LbgOptionSchedule-DefaultValue>
+      <LbgOptionApproxdiv-DefaultValue>False</LbgOptionApproxdiv-DefaultValue>
+      <LbgOptionHeadFenvH-DefaultValue>False</LbgOptionHeadFenvH-DefaultValue>
+      <LbgOptionNouseDiv-DefaultValue>True</LbgOptionNouseDiv-DefaultValue>
+      <LbgOptionEnableRegister-DefaultValue>False</LbgOptionEnableRegister-DefaultValue>
+      <LbgOptionHeadInttypesH-DefaultValue>False</LbgOptionHeadInttypesH-DefaultValue>
+      <LbgOptionHeadWcharH-DefaultValue>False</LbgOptionHeadWcharH-DefaultValue>
+      <LbgOptionSimpleFloatConv-DefaultValue>False</LbgOptionSimpleFloatConv-DefaultValue>
+      <LbgOptionFpu-DefaultValue>Fpu</LbgOptionFpu-DefaultValue>
+      <LbgOptionHeadWctypeH-DefaultValue>False</LbgOptionHeadWctypeH-DefaultValue>
+      <LbgOptionFloatOrder-DefaultValue>False</LbgOptionFloatOrder-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587485723834711443</TimeTagModified--0>
+      <LbgOptionLanguage-0>C</LbgOptionLanguage-0>
+      <LbgOptionLibraryMode-0>None</LbgOptionLibraryMode-0>
+      <LbgOptionLogo-0>False</LbgOptionLogo-0>
+      <LbgOptionOptimize-0>Level2</LbgOptionOptimize-0>
+      <LbgOptionOutputFolder-0>%BuildModeName%</LbgOptionOutputFolder-0>
+      <LbgOptionGoptimize-0>False</LbgOptionGoptimize-0>
+      <LbgOptionHead-0>Custom</LbgOptionHead-0>
+      <LbgOptionOutputFileName-0>%ProjectName%.lib</LbgOptionOutputFileName-0>
+      <LbgOptionPreLibraryGenerateCommands-0 />
+      <LbgOptionFunctionalCutdown-0>None</LbgOptionFunctionalCutdown-0>
+      <LbgOptionPostLibraryGenerateCommands-0 />
+      <LbgOptionSpeedAndSize-0>Size</LbgOptionSpeedAndSize-0>
+      <LbgOptionHeadCtypeH-0>False</LbgOptionHeadCtypeH-0>
+      <LbgOptionLoop-0>Auto</LbgOptionLoop-0>
+      <LbgOptionOtherAdditionalOptions-0 />
+      <LbgOptionReent-0>False</LbgOptionReent-0>
+      <LbgOptionCommandLine-0 />
+      <LbgOptionHeadMathH-0>False</LbgOptionHeadMathH-0>
+      <LbgOptionLoopValue-0>2</LbgOptionLoopValue-0>
+      <LbgOptionSectionP-0>P</LbgOptionSectionP-0>
+      <LbgOptionHeadMathfH-0>False</LbgOptionHeadMathfH-0>
+      <LbgOptionInline-0>Auto</LbgOptionInline-0>
+      <LbgOptionSectionC-0>C</LbgOptionSectionC-0>
+      <LbgOptionHeadStdargH-0>False</LbgOptionHeadStdargH-0>
+      <LbgOptionInlineValue-0>100</LbgOptionInlineValue-0>
+      <LbgOptionSectionD-0>D</LbgOptionSectionD-0>
+      <LbgOptionFileInline-0 />
+      <LbgOptionHeadStdioH-0>True</LbgOptionHeadStdioH-0>
+      <LbgOptionSectionB-0>B</LbgOptionSectionB-0>
+      <LbgOptionCase-0>Auto</LbgOptionCase-0>
+      <LbgOptionHeadStdlibH-0>True</LbgOptionHeadStdlibH-0>
+      <LbgOptionSectionL-0>L</LbgOptionSectionL-0>
+      <LbgOptionHeadStringH-0>True</LbgOptionHeadStringH-0>
+      <LbgOptionSectionW-0>W</LbgOptionSectionW-0>
+      <LbgOptionVolatile-0>False</LbgOptionVolatile-0>
+      <LbgOptionConstCopy-0>Auto</LbgOptionConstCopy-0>
+      <LbgOptionHeadIos-0>False</LbgOptionHeadIos-0>
+      <LbgOptionNostuffB-0>False</LbgOptionNostuffB-0>
+      <LbgOptionConstDiv-0>Auto</LbgOptionConstDiv-0>
+      <LbgOptionHeadNew-0>True</LbgOptionHeadNew-0>
+      <LbgOptionNostuffD-0>False</LbgOptionNostuffD-0>
+      <LbgOptionHeadComplex-0>False</LbgOptionHeadComplex-0>
+      <LbgOptionLibrary-0>Intrinsic</LbgOptionLibrary-0>
+      <LbgOptionNostuffC-0>False</LbgOptionNostuffC-0>
+      <LbgOptionHeadString-0>False</LbgOptionHeadString-0>
+      <LbgOptionNostuffW-0>False</LbgOptionNostuffW-0>
+      <LbgOptionScope-0>Auto</LbgOptionScope-0>
+      <LbgOptionHeadComplexH-0>False</LbgOptionHeadComplexH-0>
+      <LbgOptionInstalign-0>Noinstalign</LbgOptionInstalign-0>
+      <LbgOptionSchedule-0>Auto</LbgOptionSchedule-0>
+      <LbgOptionApproxdiv-0>False</LbgOptionApproxdiv-0>
+      <LbgOptionHeadFenvH-0>False</LbgOptionHeadFenvH-0>
+      <LbgOptionNouseDiv-0>True</LbgOptionNouseDiv-0>
+      <LbgOptionEnableRegister-0>False</LbgOptionEnableRegister-0>
+      <LbgOptionHeadInttypesH-0>False</LbgOptionHeadInttypesH-0>
+      <LbgOptionHeadWcharH-0>False</LbgOptionHeadWcharH-0>
+      <LbgOptionSimpleFloatConv-0>False</LbgOptionSimpleFloatConv-0>
+      <LbgOptionFpu-0>Fpu</LbgOptionFpu-0>
+      <LbgOptionHeadWctypeH-0>False</LbgOptionHeadWctypeH-0>
+      <LbgOptionFloatOrder-0>False</LbgOptionFloatOrder-0>
+    </Instance>
+    <Instance Guid="a8f544da-e670-4f81-bdf0-302c128849d3">
+      <ItemAddTime>635881911139188449</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="2e69b8d4-0091-4536-bdae-3c8ed3fbbce5">
+      <ItemAddTime>635881911139188449</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="8f189067-23ba-4764-8096-1c87bc59d677">
+      <ItemAddTime>635881911139188449</ItemAddTime>
+      <ItemAddTimeCount>2</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="e8a40ef7-84d6-43c7-839a-3e5225cf5e33">
+      <ItemAddTime>635881911139188449</ItemAddTime>
+      <ItemAddTimeCount>3</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="5490e1ed-eefb-4222-b5d1-9edc32763f97">
+      <ItemAddTime>635881911139188449</ItemAddTime>
+      <ItemAddTimeCount>4</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="af565ef2-c045-4bc0-bba2-14c9a98465d2">
+      <ItemAddTime>635881911139188449</ItemAddTime>
+      <ItemAddTimeCount>5</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="5e6b7bf7-bd92-461d-84bd-dafbe290b317">
+      <ItemAddTime>635881911139188449</ItemAddTime>
+      <ItemAddTimeCount>6</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="8e698c09-5097-444e-8342-19f6512bd4b0">
+      <ItemAddTime>635881911139188449</ItemAddTime>
+      <ItemAddTimeCount>7</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="fd90ffa4-5d9b-43cd-91d0-f4830247c96e">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="93bbcbdd-6989-46ae-9cd2-13374a458a2a">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="33b97578-6550-4399-983b-21c317cd3dae">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>2</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="9afcf469-0afc-47cc-ab99-53f8d372e707">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>3</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="e16f9919-5f9b-453c-8cdc-8958b44a0731">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>4</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="162c8aa9-7915-498d-9eaf-4a86c754cafc">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>5</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="7d3ae7f7-8cee-45ba-8e6c-5c70ae26c124">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>6</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="c14daa42-03b4-4321-9840-43513554edf5">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>7</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="cea570e4-52af-4e53-9b20-37d34800f495">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>8</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="4690fcde-d968-4239-a0a8-57fe645e2d5c">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>9</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="cfe5ca36-46ce-4fc2-834c-0da1c3728b34">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>10</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="8b954fec-9423-4c49-b509-cd0526a4575a">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>11</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f7292e22-977c-4c0b-b5ce-75a26b2cfc6e">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>12</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="c7a5c3f9-adc0-4f2c-8274-9b938748faaf">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>13</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="31c58253-720c-4a63-9797-fff29563300f">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>14</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f3174502-6793-4acf-98df-e85b44f3980b">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>15</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="2eeb3b6e-b74b-4f36-98a8-1b4c6d7c3766">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>16</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="f18e4ce9-8cca-44ff-8d9f-d63c7bb293ab">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>17</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="b3b3a308-6b24-4930-82bb-edd785893281">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>18</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="49238843-c08d-4342-95a1-7896eec7f2fc">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>19</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="6584642a-5899-4579-8b26-7a08d0f7b0d8">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>20</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="92df22fc-4f1a-4a9c-a6f9-6fe981a6551b">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>21</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="875a8eb6-b09d-43a5-a6cd-863f5d1de818">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>22</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="42c1cced-3ccb-41d6-a09e-c1f7a9a65254">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>23</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="3e006428-dd0a-4f7f-ab26-8e41e5d3fc63">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>24</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="267fea6c-b9f0-4037-9ad8-cea2f443d560">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>25</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="3d410f00-ba86-47fa-bb43-b9167a5edba6">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>26</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="387c8b98-e894-4de8-8988-31af2fdf4334">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>27</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="ed66d182-bc22-462a-b334-c84306114b1a">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>28</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="ee86d025-7a48-4f67-99f5-3105b26868be">
+      <ItemAddTime>635881911548784353</ItemAddTime>
+      <ItemAddTimeCount>29</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a7be515f-f007-45ed-9059-4e1500c0f74d">
+      <TimeTagModified-SourceItem0--0>-8587490449715587359</TimeTagModified-SourceItem0--0>
+      <SourceItem0-IsLockedByUser>False</SourceItem0-IsLockedByUser>
+      <SourceItem0-BuildingTarget-0>True</SourceItem0-BuildingTarget-0>
+      <SourceItem0-IndividualCompileOption-0>False</SourceItem0-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem1--0>-8587490449715587359</TimeTagModified-SourceItem1--0>
+      <SourceItem1-IsLockedByUser>False</SourceItem1-IsLockedByUser>
+      <SourceItem1-BuildingTarget-0>True</SourceItem1-BuildingTarget-0>
+      <SourceItem1-IndividualCompileOption-0>False</SourceItem1-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem2--0>-8587490449715587359</TimeTagModified-SourceItem2--0>
+      <SourceItem2-IsLockedByUser>False</SourceItem2-IsLockedByUser>
+      <SourceItem2-BuildingTarget-0>True</SourceItem2-BuildingTarget-0>
+      <SourceItem2-IndividualCompileOption-0>False</SourceItem2-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem3--0>-8587490449715587359</TimeTagModified-SourceItem3--0>
+      <SourceItem3-IsLockedByUser>False</SourceItem3-IsLockedByUser>
+      <SourceItem3-BuildingTarget-0>True</SourceItem3-BuildingTarget-0>
+      <SourceItem3-IndividualCompileOption-0>False</SourceItem3-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem4--0>-8587490449715587359</TimeTagModified-SourceItem4--0>
+      <SourceItem4-IsLockedByUser>False</SourceItem4-IsLockedByUser>
+      <SourceItem4-BuildingTarget-0>True</SourceItem4-BuildingTarget-0>
+      <SourceItem4-IndividualCompileOption-0>False</SourceItem4-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem5--0>-8587490449715587359</TimeTagModified-SourceItem5--0>
+      <SourceItem5-IsLockedByUser>False</SourceItem5-IsLockedByUser>
+      <SourceItem5-BuildingTarget-0>True</SourceItem5-BuildingTarget-0>
+      <SourceItem5-IndividualCompileOption-0>False</SourceItem5-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem6--0>-8587490449715587359</TimeTagModified-SourceItem6--0>
+      <SourceItem6-IsLockedByUser>False</SourceItem6-IsLockedByUser>
+      <SourceItem6-BuildingTarget-0>True</SourceItem6-BuildingTarget-0>
+      <SourceItem6-IndividualCompileOption-0>False</SourceItem6-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem7--0>-8587490449715587359</TimeTagModified-SourceItem7--0>
+      <SourceItem7-IsLockedByUser>False</SourceItem7-IsLockedByUser>
+      <SourceItem7-BuildingTarget-0>True</SourceItem7-BuildingTarget-0>
+      <SourceItem7-IndividualCompileOption-0>False</SourceItem7-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem8--0>-8587490449305991455</TimeTagModified-SourceItem8--0>
+      <SourceItem8-IsLockedByUser>False</SourceItem8-IsLockedByUser>
+      <SourceItem8-BuildingTarget-0>True</SourceItem8-BuildingTarget-0>
+      <SourceItem8-IndividualCompileOption-0>False</SourceItem8-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem9--0>-8587490449305991455</TimeTagModified-SourceItem9--0>
+      <SourceItem9-IsLockedByUser>False</SourceItem9-IsLockedByUser>
+      <SourceItem9-BuildingTarget-0>True</SourceItem9-BuildingTarget-0>
+      <SourceItem9-IndividualCompileOption-0>False</SourceItem9-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem10--0>-8587490449305991455</TimeTagModified-SourceItem10--0>
+      <SourceItem10-IsLockedByUser>False</SourceItem10-IsLockedByUser>
+      <SourceItem10-BuildingTarget-0>True</SourceItem10-BuildingTarget-0>
+      <SourceItem10-IndividualCompileOption-0>False</SourceItem10-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem11--0>-8587490449305991455</TimeTagModified-SourceItem11--0>
+      <SourceItem11-IsLockedByUser>False</SourceItem11-IsLockedByUser>
+      <SourceItem11-BuildingTarget-0>True</SourceItem11-BuildingTarget-0>
+      <SourceItem11-IndividualCompileOption-0>False</SourceItem11-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem12--0>-8587490449305991455</TimeTagModified-SourceItem12--0>
+      <SourceItem12-IsLockedByUser>False</SourceItem12-IsLockedByUser>
+      <SourceItem12-BuildingTarget-0>True</SourceItem12-BuildingTarget-0>
+      <SourceItem12-IndividualCompileOption-0>False</SourceItem12-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem13--0>-8587490449305991455</TimeTagModified-SourceItem13--0>
+      <SourceItem13-IsLockedByUser>False</SourceItem13-IsLockedByUser>
+      <SourceItem13-BuildingTarget-0>True</SourceItem13-BuildingTarget-0>
+      <SourceItem13-IndividualCompileOption-0>False</SourceItem13-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem14--0>-8587490449305991455</TimeTagModified-SourceItem14--0>
+      <SourceItem14-IsLockedByUser>False</SourceItem14-IsLockedByUser>
+      <SourceItem14-BuildingTarget-0>True</SourceItem14-BuildingTarget-0>
+      <SourceItem14-IndividualCompileOption-0>False</SourceItem14-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem15--0>-8587490449305991455</TimeTagModified-SourceItem15--0>
+      <SourceItem15-IsLockedByUser>False</SourceItem15-IsLockedByUser>
+      <SourceItem15-BuildingTarget-0>True</SourceItem15-BuildingTarget-0>
+      <SourceItem15-IndividualCompileOption-0>False</SourceItem15-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem16--0>-8587490449305991455</TimeTagModified-SourceItem16--0>
+      <SourceItem16-IsLockedByUser>False</SourceItem16-IsLockedByUser>
+      <SourceItem16-BuildingTarget-0>True</SourceItem16-BuildingTarget-0>
+      <SourceItem16-IndividualCompileOption-0>False</SourceItem16-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem17--0>-8587490449305991455</TimeTagModified-SourceItem17--0>
+      <SourceItem17-IsLockedByUser>False</SourceItem17-IsLockedByUser>
+      <SourceItem17-BuildingTarget-0>True</SourceItem17-BuildingTarget-0>
+      <SourceItem17-IndividualCompileOption-0>False</SourceItem17-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem18--0>-8587490449305991455</TimeTagModified-SourceItem18--0>
+      <SourceItem18-IsLockedByUser>False</SourceItem18-IsLockedByUser>
+      <SourceItem18-BuildingTarget-0>True</SourceItem18-BuildingTarget-0>
+      <SourceItem18-IndividualCompileOption-0>False</SourceItem18-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem19--0>-8587490449305991455</TimeTagModified-SourceItem19--0>
+      <SourceItem19-IsLockedByUser>False</SourceItem19-IsLockedByUser>
+      <SourceItem19-BuildingTarget-0>True</SourceItem19-BuildingTarget-0>
+      <SourceItem19-IndividualCompileOption-0>False</SourceItem19-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem20--0>-8587490449305991455</TimeTagModified-SourceItem20--0>
+      <SourceItem20-IsLockedByUser>False</SourceItem20-IsLockedByUser>
+      <SourceItem20-BuildingTarget-0>True</SourceItem20-BuildingTarget-0>
+      <SourceItem20-IndividualCompileOption-0>False</SourceItem20-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem21--0>-8587490449305991455</TimeTagModified-SourceItem21--0>
+      <SourceItem21-IsLockedByUser>False</SourceItem21-IsLockedByUser>
+      <SourceItem21-BuildingTarget-0>True</SourceItem21-BuildingTarget-0>
+      <SourceItem21-IndividualCompileOption-0>False</SourceItem21-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem22--0>-8587490449305991455</TimeTagModified-SourceItem22--0>
+      <SourceItem22-IsLockedByUser>False</SourceItem22-IsLockedByUser>
+      <SourceItem22-BuildingTarget-0>True</SourceItem22-BuildingTarget-0>
+      <SourceItem22-IndividualCompileOption-0>False</SourceItem22-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem23--0>-8587490449305991455</TimeTagModified-SourceItem23--0>
+      <SourceItem23-IsLockedByUser>False</SourceItem23-IsLockedByUser>
+      <SourceItem23-BuildingTarget-0>True</SourceItem23-BuildingTarget-0>
+      <SourceItem23-IndividualCompileOption-0>False</SourceItem23-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem24--0>-8587490449305991455</TimeTagModified-SourceItem24--0>
+      <SourceItem24-IsLockedByUser>False</SourceItem24-IsLockedByUser>
+      <SourceItem24-BuildingTarget-0>True</SourceItem24-BuildingTarget-0>
+      <SourceItem24-IndividualCompileOption-0>False</SourceItem24-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem25--0>-8587490449305991455</TimeTagModified-SourceItem25--0>
+      <SourceItem25-IsLockedByUser>False</SourceItem25-IsLockedByUser>
+      <SourceItem25-BuildingTarget-0>True</SourceItem25-BuildingTarget-0>
+      <SourceItem25-IndividualCompileOption-0>False</SourceItem25-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem26--0>-8587490449305991455</TimeTagModified-SourceItem26--0>
+      <SourceItem26-IsLockedByUser>False</SourceItem26-IsLockedByUser>
+      <SourceItem26-BuildingTarget-0>True</SourceItem26-BuildingTarget-0>
+      <SourceItem26-IndividualCompileOption-0>False</SourceItem26-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem27--0>-8587490449305991455</TimeTagModified-SourceItem27--0>
+      <SourceItem27-IsLockedByUser>False</SourceItem27-IsLockedByUser>
+      <SourceItem27-BuildingTarget-0>True</SourceItem27-BuildingTarget-0>
+      <SourceItem27-IndividualCompileOption-0>False</SourceItem27-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem28--0>-8587490449305991455</TimeTagModified-SourceItem28--0>
+      <SourceItem28-IsLockedByUser>False</SourceItem28-IsLockedByUser>
+      <SourceItem28-BuildingTarget-0>True</SourceItem28-BuildingTarget-0>
+      <SourceItem28-IndividualCompileOption-0>False</SourceItem28-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem29--0>-8587490449305991455</TimeTagModified-SourceItem29--0>
+      <SourceItem29-IsLockedByUser>False</SourceItem29-IsLockedByUser>
+      <SourceItem29-BuildingTarget-0>True</SourceItem29-BuildingTarget-0>
+      <SourceItem29-IndividualCompileOption-0>False</SourceItem29-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem30--0>-8587490449305991455</TimeTagModified-SourceItem30--0>
+      <SourceItem30-IsLockedByUser>False</SourceItem30-IsLockedByUser>
+      <SourceItem30-BuildingTarget-0>True</SourceItem30-BuildingTarget-0>
+      <SourceItem30-IndividualCompileOption-0>False</SourceItem30-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem31--0>-8587490449305991455</TimeTagModified-SourceItem31--0>
+      <SourceItem31-IsLockedByUser>False</SourceItem31-IsLockedByUser>
+      <SourceItem31-BuildingTarget-0>True</SourceItem31-BuildingTarget-0>
+      <SourceItem31-IndividualCompileOption-0>False</SourceItem31-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem32--0>-8587490449305991455</TimeTagModified-SourceItem32--0>
+      <SourceItem32-IsLockedByUser>False</SourceItem32-IsLockedByUser>
+      <SourceItem32-BuildingTarget-0>True</SourceItem32-BuildingTarget-0>
+      <SourceItem32-IndividualCompileOption-0>False</SourceItem32-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem33--0>-8587490449305991455</TimeTagModified-SourceItem33--0>
+      <SourceItem33-IsLockedByUser>False</SourceItem33-IsLockedByUser>
+      <SourceItem33-BuildingTarget-0>True</SourceItem33-BuildingTarget-0>
+      <SourceItem33-IndividualCompileOption-0>False</SourceItem33-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem34--0>-8587490449305991455</TimeTagModified-SourceItem34--0>
+      <SourceItem34-IsLockedByUser>False</SourceItem34-IsLockedByUser>
+      <SourceItem34-BuildingTarget-0>True</SourceItem34-BuildingTarget-0>
+      <SourceItem34-IndividualCompileOption-0>False</SourceItem34-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem35--0>-8587490449305991455</TimeTagModified-SourceItem35--0>
+      <SourceItem35-IsLockedByUser>False</SourceItem35-IsLockedByUser>
+      <SourceItem35-BuildingTarget-0>True</SourceItem35-BuildingTarget-0>
+      <SourceItem35-IndividualCompileOption-0>False</SourceItem35-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem36--0>-8587490449305991455</TimeTagModified-SourceItem36--0>
+      <SourceItem36-IsLockedByUser>False</SourceItem36-IsLockedByUser>
+      <SourceItem36-BuildingTarget-0>True</SourceItem36-BuildingTarget-0>
+      <SourceItem36-IndividualCompileOption-0>False</SourceItem36-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem37--0>-8587485723834711443</TimeTagModified-SourceItem37--0>
+      <SourceItem37-IsLockedByUser>False</SourceItem37-IsLockedByUser>
+      <SourceItem37-BuildingTarget-0>True</SourceItem37-BuildingTarget-0>
+      <SourceItem37-IndividualCompileOption-0>False</SourceItem37-IndividualCompileOption-0>
+    </Instance>
+  </Class>
+  <Class Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
+    <Instance Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
+      <IsLibraryMode>True</IsLibraryMode>
+      <StartUpCategoryItem>00000000-0000-0000-0000-000000000000</StartUpCategoryItem>
+    </Instance>
+  </Class>
+  <Class Guid="a29a09ee-92c3-4ce7-9586-a1b058043f92">
+    <Instance Guid="a29a09ee-92c3-4ce7-9586-a1b058043f92">
+      <ProjectGeneratr-GeneratedFile0 />
+    </Instance>
+  </Class>
+  <Class Guid="31a86ad3-37bd-4846-aff2-e08abdc00197">
+    <Instance Guid="31a86ad3-37bd-4846-aff2-e08abdc00197">
+      <DeviceNameOnCreateStartup>R5F563NBDxFP</DeviceNameOnCreateStartup>
+    </Instance>
+  </Class>
+  <Class Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">
+    <Instance Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">
+      <ProductVersion>4.02.00.00</ProductVersion>
+    </Instance>
+  </Class>
+</CubeSuiteProject>
Index: UsbWattMeter/trunk/csp/tools/DefToEqu.js
===================================================================
--- UsbWattMeter/trunk/csp/tools/DefToEqu.js	(revision 164)
+++ UsbWattMeter/trunk/csp/tools/DefToEqu.js	(revision 164)
@@ -0,0 +1,36 @@
+var fs = WScript.CreateObject("Scripting.FileSystemObject");
+
+args = WScript.Arguments;
+
+if(args.length >= 2)
+{
+	var istrm = fs.OpenTextFile(args(0)); // offset.h
+	var ostrm = fs.CreateTextFile(args(1)); // offset.inc
+
+	ostrm.WriteLine("; offset.inc");
+	ostrm.WriteLine("");
+
+	var line;
+	var newline;
+
+	while(!istrm.AtEndOfStream){
+		line = istrm.ReadLine();
+
+		re=/\s+$/;
+		newline = line.replace(re, "");
+		re=/^#define\s+([0-9|a-z|A-Z|_]+)\s+(.+)$/;
+		if(newline.search(re) == -1)
+			continue;
+
+		var value = newline.replace(re, "$2");
+		re2=/^0x([0-9A-Fa-f]+)$/;
+		if(value.search(re2) != -1)
+			value = "0" + value.replace(re2, "$1") + "H";
+
+		newline = newline.replace(re, "	$1	.equ	" + value);
+
+		ostrm.WriteLine(newline);
+	}
+	istrm.Close();
+	ostrm.Close();
+}
Index: UsbWattMeter/trunk/csp/tools/cmp_update.js
===================================================================
--- UsbWattMeter/trunk/csp/tools/cmp_update.js	(revision 164)
+++ UsbWattMeter/trunk/csp/tools/cmp_update.js	(revision 164)
@@ -0,0 +1,82 @@
+var fs = WScript.CreateObject("Scripting.FileSystemObject");
+
+function Compare(a, b)
+{
+	var stream = WScript.CreateObject('ADODB.Stream');
+	//stream.Type=1;//1=binary,2=text
+	stream.type = 2;	//adTypeText
+	stream.charset = "ascii";
+
+	stream.Open();
+	stream.LoadFromFile(fs.GetAbsolutePathName(a));
+	//var fa = stream.Read(-1);//-1:read all , -2 : read line
+	var fa = stream.ReadText();
+	stream.Close();
+
+	stream.Open();
+	stream.LoadFromFile(fs.GetAbsolutePathName(b));
+	//var fb = stream.Read(-1);
+	var fb = stream.ReadText();
+	stream.Close();
+
+	if (fa.length != fb.length)
+		return false;
+
+	for (var i = 0; i < fa.length; i++) {
+		if(fa.charCodeAt(i) != fb.charCodeAt(i))
+			return false;
+	}
+
+	return true;
+}
+
+args = WScript.Arguments;
+
+if(args.length >= 2)
+{
+	var src_file = args(0);
+	var dst_file = args(1);
+
+	if(fs.FileExists(src_file))
+	{
+		if(fs.FileExists(dst_file))
+		{
+			var src = fs.GetFile(src_file);
+			var dst = fs.GetFile(dst_file);
+
+			if(!Compare(src, dst))
+			{
+				fs.CopyFile(src_file, dst_file, true);
+
+				WScript.StdOut.Write(dst_file);
+				WScript.StdOut.WriteLine("ðRs[µÜµ½B");
+			}
+		}
+		else
+		{
+			fs.CopyFile(src_file, dst_file);
+
+			WScript.StdOut.Write(dst_file);
+			WScript.StdOut.WriteLine("ðRs[µÜµ½B");
+		}
+	}
+	else
+	{
+		if(fs.FileExists(dst_file))
+		{
+			var dst = fs.GetFile(dst_file);
+			
+			fs.DeleteFile(dst_file);
+
+			WScript.StdOut.Write(dst_file);
+			WScript.StdOut.WriteLine("ðíµÜµ½B");
+		}
+		else
+		{
+			WScript.StdOut.WriteLine("wè³ê½t@Cª èÜ¹ñB");
+			WScript.StdOut.WriteLine(src_file);
+			WScript.StdOut.WriteLine(dst_file);
+		}
+	}
+}
+
Index: UsbWattMeter/trunk/csp/tools/update.js
===================================================================
--- UsbWattMeter/trunk/csp/tools/update.js	(revision 164)
+++ UsbWattMeter/trunk/csp/tools/update.js	(revision 164)
@@ -0,0 +1,52 @@
+var fs = WScript.CreateObject("Scripting.FileSystemObject");
+
+args = WScript.Arguments;
+
+if(args.length >= 2)
+{
+	var src_file = args(0);
+	var dst_file = args(1);
+
+	if(fs.FileExists(src_file))
+	{
+		if(fs.FileExists(dst_file))
+		{
+			var src = fs.GetFile(src_file);
+			var dst = fs.GetFile(dst_file);
+
+			if(src.DateLastModified > dst.DateLastModified)
+			{
+				fs.CopyFile(src_file, dst_file, true);
+
+				WScript.StdOut.Write(dst_file);
+				WScript.StdOut.WriteLine("ðRs[µÜµ½B");
+			}
+		}
+		else
+		{
+			fs.CopyFile(src_file, dst_file);
+
+			WScript.StdOut.Write(dst_file);
+			WScript.StdOut.WriteLine("ðRs[µÜµ½B");
+		}
+	}
+	else
+	{
+		if(fs.FileExists(dst_file))
+		{
+			var dst = fs.GetFile(dst_file);
+			
+			fs.DeleteFile(dst_file);
+
+			WScript.StdOut.Write(dst_file);
+			WScript.StdOut.WriteLine("ðíµÜµ½B");
+		}
+		else
+		{
+			WScript.StdOut.WriteLine("wè³ê½t@Cª èÜ¹ñB");
+			WScript.StdOut.WriteLine(src_file);
+			WScript.StdOut.WriteLine(dst_file);
+		}
+	}
+}
+
Index: UsbWattMeter/trunk/csp/usb_watt_meter/cfg/cfg.mtsp
===================================================================
--- UsbWattMeter/trunk/csp/usb_watt_meter/cfg/cfg.mtsp	(revision 164)
+++ UsbWattMeter/trunk/csp/usb_watt_meter/cfg/cfg.mtsp	(revision 164)
@@ -0,0 +1,1171 @@
+<CubeSuiteProject>
+  <ProductVersion>4.02.00.00</ProductVersion>
+  <Class Guid="68f4a651-b9cd-473b-a595-b00447132ffa">
+    <Instance Guid="00000000-0000-0000-0000-000000000000">
+      <FormatVersion>2.0</FormatVersion>
+      <FileVersion>4.2</FileVersion>
+      <ProjectGuid>04dd15f3-a521-4091-8ca9-d183965ea77a</ProjectGuid>
+      <ProjectItemGuid>de7cfdb7-12a5-4b15-bd64-1894fa1140bd</ProjectItemGuid>
+      <FileCategoryGuid>0ebd8804-8dca-422f-b9b3-c8bc0543ce9d</FileCategoryGuid>
+      <Property>fb98844b-2c27-4275-9804-f6e63e204da0</Property>
+    </Instance>
+    <Instance Guid="76d4ee54-712a-4601-bcfd-b16a1a54c781">
+      <Name>cfg1_out.c</Name>
+      <Type>File</Type>
+      <RelativePath>cfg1_out.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>0ebd8804-8dca-422f-b9b3-c8bc0543ce9d</ParentItem>
+      <Property>93ec8d93-b2ab-4193-b319-856c487a0d45</Property>
+    </Instance>
+  </Class>
+  <Class Guid="fb98844b-2c27-4275-9804-f6e63e204da0">
+    <Instance Guid="2a349cb6-b982-4ade-adcd-104b883ad81c">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="0d548289-d5e9-4893-9a8f-9374b13f19a9">
+    <Instance Guid="93ec8d93-b2ab-4193-b319-856c487a0d45">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="8fb9c1f6-d351-4d10-8d99-bf5b3015b84c">
+    <Instance Guid="00000000-0000-0000-0000-000000000000">
+      <UsingPlatformGuid>500ba51a-4219-4828-b4be-80f54d6d3551</UsingPlatformGuid>
+      <UsingPlatformTypeGuid>f96683fa-8de4-4c6d-a1ab-925d7f232c09</UsingPlatformTypeGuid>
+    </Instance>
+  </Class>
+  <Class Guid="c325714f-8f51-484b-9e96-b4b59c0fb263">
+    <Instance Guid="c325714f-8f51-484b-9e96-b4b59c0fb263">
+      <DeviceManager>0e793ff3-2e3f-43c0-bdc9-926269595403</DeviceManager>
+    </Instance>
+  </Class>
+  <Class Guid="0e793ff3-2e3f-43c0-bdc9-926269595403">
+    <Instance Guid="0e793ff3-2e3f-43c0-bdc9-926269595403">
+      <DataFormatVersion>1.0</DataFormatVersion>
+    </Instance>
+    <Instance Guid="2a81c37a-5015-44c2-9f40-e58b669eec75">
+      <DeviceName>R5F563NBDxFP</DeviceName>
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="873c9a58-9bc5-439a-b476-78629a4553ed">
+    <Instance Guid="873c9a58-9bc5-439a-b476-78629a4553ed">
+      <ProjectDeviceChangedCounter>0</ProjectDeviceChangedCounter>
+      <ProjectInitialDeviceName>R5F563NBDxFP</ProjectInitialDeviceName>
+    </Instance>
+  </Class>
+  <Class Guid="c3835e31-dea3-4c93-b02b-d2db997f7630">
+    <Instance Guid="c3835e31-dea3-4c93-b02b-d2db997f7630">
+      <BuildToolManager>3a79707d-5977-45f7-ac11-19c35e333132</BuildToolManager>
+    </Instance>
+  </Class>
+  <Class Guid="3a79707d-5977-45f7-ac11-19c35e333132">
+    <Instance Guid="3a79707d-5977-45f7-ac11-19c35e333132">
+      <DataFormatVersion>1.2</DataFormatVersion>
+      <BuildModeCount>1</BuildModeCount>
+      <BuildMode0>RABlAGYAYQB1AGwAdABCAHUAaQBsAGQA</BuildMode0>
+      <BatchBuildFlag0>False</BatchBuildFlag0>
+      <CurrentBuildMode>DefaultBuild</CurrentBuildMode>
+      <SourceItemGuid0>76d4ee54-712a-4601-bcfd-b16a1a54c781</SourceItemGuid0>
+      <SourceItemType0>CSource</SourceItemType0>
+      <SourceItemCount>1</SourceItemCount>
+      <LastDeviceChangedCounter>0</LastDeviceChangedCounter>
+    </Instance>
+    <Instance Guid="9e208646-ccba-4100-a676-29b1efe6545f">
+      <AsmOptionInclude-DefaultValue />
+      <BuildMode-DefaultValue>DefaultBuild</BuildMode-DefaultValue>
+      <COptionInclude-DefaultValue />
+      <GeneralOptionIsa-DefaultValue>RXv1</GeneralOptionIsa-DefaultValue>
+      <GeneralOptionOutput-DefaultValue>LoadModuleFile</GeneralOptionOutput-DefaultValue>
+      <GeneralOptionPic-DefaultValue>False</GeneralOptionPic-DefaultValue>
+      <GeneralOptionSimultaneousBuild-DefaultValue>True</GeneralOptionSimultaneousBuild-DefaultValue>
+      <HexOptionOutput-DefaultValue>True</HexOptionOutput-DefaultValue>
+      <LibOptionDebug-DefaultValue>Debug</LibOptionDebug-DefaultValue>
+      <LinkOptionLibrary-DefaultValue />
+      <Memo-DefaultValue />
+      <OutputMessageFormat-DefaultValue>%TargetFiles%</OutputMessageFormat-DefaultValue>
+      <AsmOptionSystemInclude-DefaultValue />
+      <COptionSystemInclude-DefaultValue />
+      <CompilerVersion-DefaultValue>
+
+0</CompilerVersion-DefaultValue>
+      <DependencyFileExistCheckingType-DefaultValue>Rebuild</DependencyFileExistCheckingType-DefaultValue>
+      <FormatBuildOptionList-DefaultValue>%TargetFiles% : %Program% %Options%</FormatBuildOptionList-DefaultValue>
+      <GeneralOptionCpu-DefaultValue>RX600</GeneralOptionCpu-DefaultValue>
+      <GeneralOptionOutputFolder-DefaultValue>%BuildModeName%</GeneralOptionOutputFolder-DefaultValue>
+      <GeneralOptionPid-DefaultValue>None</GeneralOptionPid-DefaultValue>
+      <HexOptionForm-DefaultValue>Stype</HexOptionForm-DefaultValue>
+      <LinkOptionDebug-DefaultValue>Debug</LinkOptionDebug-DefaultValue>
+      <AsmOptionDefine-DefaultValue />
+      <COptionDefine-DefaultValue />
+      <EnsureCompatibilityOfPathAndLinkageOrder-DefaultValue>False</EnsureCompatibilityOfPathAndLinkageOrder-DefaultValue>
+      <GeneralOptionFpu-DefaultValue>Auto</GeneralOptionFpu-DefaultValue>
+      <GeneralOptionNousePidRegister-DefaultValue>True</GeneralOptionNousePidRegister-DefaultValue>
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionOptimize-DefaultValue>None</LinkOptionOptimize-DefaultValue>
+      <AsmOptionDebug-DefaultValue>True</AsmOptionDebug-DefaultValue>
+      <COptionDebug-DefaultValue>True</COptionDebug-DefaultValue>
+      <GeneralOptionEndian-DefaultValue>Little</GeneralOptionEndian-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionOptimizeSymbolDelete-DefaultValue>False</LinkOptionOptimizeSymbolDelete-DefaultValue>
+      <PreBuildCommands-DefaultValue />
+      <AsmOptionGoptimize-DefaultValue>False</AsmOptionGoptimize-DefaultValue>
+      <COptionOptimize-DefaultValue>Level2</COptionOptimize-DefaultValue>
+      <GeneralOptionRound-DefaultValue>Nearest</GeneralOptionRound-DefaultValue>
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionOptimizeSameCode-DefaultValue>False</LinkOptionOptimizeSameCode-DefaultValue>
+      <PostBuildCommands-DefaultValue />
+      <AsmOptionListFile-DefaultValue>False</AsmOptionListFile-DefaultValue>
+      <COptionGoptimize-DefaultValue>False</COptionGoptimize-DefaultValue>
+      <GeneralOptionDenormalize-DefaultValue>Off</GeneralOptionDenormalize-DefaultValue>
+      <LinkOptionSameSize-DefaultValue>1E</LinkOptionSameSize-DefaultValue>
+      <AsmOptionShowConditionals-DefaultValue>False</AsmOptionShowConditionals-DefaultValue>
+      <COptionSpeedAndSize-DefaultValue>Size</COptionSpeedAndSize-DefaultValue>
+      <GeneralOptionDblSize-DefaultValue>SinglePrecision</GeneralOptionDblSize-DefaultValue>
+      <LinkOptionOptimizeShortFormat-DefaultValue>False</LinkOptionOptimizeShortFormat-DefaultValue>
+      <AsmOptionShowDefinitions-DefaultValue>False</AsmOptionShowDefinitions-DefaultValue>
+      <COptionListfile-DefaultValue>False</COptionListfile-DefaultValue>
+      <GeneralOptionIntToShort-DefaultValue>False</GeneralOptionIntToShort-DefaultValue>
+      <LinkOptionOptimizeBranch-DefaultValue>False</LinkOptionOptimizeBranch-DefaultValue>
+      <AsmOptionShowExpansions-DefaultValue>False</AsmOptionShowExpansions-DefaultValue>
+      <COptionShowSource-DefaultValue>False</COptionShowSource-DefaultValue>
+      <GeneralOptionSignedChar-DefaultValue>Unsigned</GeneralOptionSignedChar-DefaultValue>
+      <LinkOptionStart-DefaultValue>B_1,R_1,B_2,R_2,B,R,SU,SI/04,PResetPRG/0FFFF8000,C_1,C_2,C,C$DSEC,C$BSEC,C$INIT,C$VTBL,C$VECT,D_1,D_2,D,P,PIntPRG,W_1,W_2,W,L/0FFFF8100,FIXEDVECT/0FFFFFFD0</LinkOptionStart-DefaultValue>
+      <COptionShowConditionals-DefaultValue>False</COptionShowConditionals-DefaultValue>
+      <GeneralOptionOtherAdditionalOptions-DefaultValue />
+      <GeneralOptionSignedBitfield-DefaultValue>Unsigned</GeneralOptionSignedBitfield-DefaultValue>
+      <COptionShowDefinitions-DefaultValue>False</COptionShowDefinitions-DefaultValue>
+      <GeneralOptionAutoEnum-DefaultValue>False</GeneralOptionAutoEnum-DefaultValue>
+      <COptionShowExpansions-DefaultValue>False</COptionShowExpansions-DefaultValue>
+      <GeneralOptionBitOrder-DefaultValue>Right</GeneralOptionBitOrder-DefaultValue>
+      <GeneralOptionPack-DefaultValue>False</GeneralOptionPack-DefaultValue>
+      <GeneralOptionException-DefaultValue>False</GeneralOptionException-DefaultValue>
+      <GeneralOptionRtti-DefaultValue>False</GeneralOptionRtti-DefaultValue>
+      <GeneralOptionFintRegister-DefaultValue>None</GeneralOptionFintRegister-DefaultValue>
+      <GeneralOptionBranch-DefaultValue>Branch24</GeneralOptionBranch-DefaultValue>
+      <GeneralOptionBaseRomRegister-DefaultValue>None</GeneralOptionBaseRomRegister-DefaultValue>
+      <GeneralOptionBaseRamRegister-DefaultValue>None</GeneralOptionBaseRamRegister-DefaultValue>
+      <GeneralOptionBaseAddressAddress-DefaultValue>00000000</GeneralOptionBaseAddressAddress-DefaultValue>
+      <GeneralOptionBaseAddressRegister-DefaultValue>None</GeneralOptionBaseAddressRegister-DefaultValue>
+      <GeneralOptionPatch-DefaultValue>None</GeneralOptionPatch-DefaultValue>
+      <GeneralOptionSaveAcc-DefaultValue>False</GeneralOptionSaveAcc-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587442584791015989</TimeTagModified--0>
+      <BuildMode-0>DefaultBuild</BuildMode-0>
+      <Memo-0 />
+      <OutputMessageFormat-0>%TargetFiles%</OutputMessageFormat-0>
+      <FormatBuildOptionList-0>%TargetFiles% : %Program% %Options%</FormatBuildOptionList-0>
+      <PreBuildCommands-0>if exist "%OutputDir%\%ProjectName%.syms" del "%OutputDir%\%ProjectName%.syms"
+..\..\..\asp_dcre\cfg\cfg\cfg.exe --pass 1 --kernel asp_dcre --api-table ..\..\..\asp_dcre\kernel\kernel_api.csv --api-table ..\..\..\ecnl_lwip\echonet_api.csv --cfg1-def-table ..\..\..\asp_dcre\kernel\kernel_def.csv --cfg1-def-table ..\..\..\asp_dcre\arch\rx630_ccrx\prc_def.csv --cfg1-def-table ..\..\..\asp_dcre\target\grsakura_ccrx\target_def.csv --cfg1-def-table ..\..\..\ecnl_lwip\echonet_def.csv -I ..\..\..\asp_dcre -I ..\..\..\asp_dcre\arch -I ..\..\..\asp_dcre\arch\rx630_ccrx -I ..\..\..\asp_dcre\include -I ..\..\..\asp_dcre\kernel -I ..\..\..\asp_dcre\target\grsakura_ccrx -I ..\..\..\ecnl_lwip -I ..\..\..\fatfs -I ..\..\..\lwip-1.4.1\ports\asp_dcre -I ..\..\..\lwip-1.4.1\ports\grsakura -I "%MainProjectDir%" ..\..\..\src\%MainProjectName%\main.cfg
+</PreBuildCommands-0>
+      <PostBuildCommands-0>..\..\..\asp_dcre\arch\ccrx\gensyms.exe "%OutputDir%\%ProjectName%.map"
+%WinDir%\cscript //Nologo ..\..\tools\update.js "%OutputDir%\%ProjectName%.mot" cfg1_out.srec
+..\..\..\asp_dcre\cfg\cfg\cfg.exe --pass 2 --kernel asp_dcre --api-table ..\..\..\asp_dcre\kernel\kernel_api.csv --api-table ..\..\..\ecnl_lwip\echonet_api.csv --cfg1-def-table ..\..\..\asp_dcre\kernel\kernel_def.csv --cfg1-def-table ..\..\..\asp_dcre\arch\rx630_ccrx\prc_def.csv --cfg1-def-table ..\..\..\asp_dcre\target\grsakura_ccrx\target_def.csv --cfg1-def-table ..\..\..\ecnl_lwip\echonet_def.csv -I ..\..\..\asp_dcre -I ..\..\..\asp_dcre\arch -I ..\..\..\asp_dcre\arch\rx630_ccrx -I ..\..\..\asp_dcre\include -I ..\..\..\asp_dcre\kernel -I ..\..\..\asp_dcre\target\grsakura_ccrx -I ..\..\..\ecnl_lwip -I ..\..\..\fatfs -I ..\..\..\lwip-1.4.1\ports\asp_dcre -I ..\..\..\lwip-1.4.1\ports\grsakura -I "%MainProjectDir%" --template-file ..\..\..\asp_dcre\target\grsakura_ccrx\target_ccrx_ecnl_lwip.tf ..\..\..\src\%MainProjectName%\main.cfg
+%WinDir%\cscript //Nologo ..\..\tools\cmp_update.js kernel_cfg.c ..\kernel_cfg.c
+%WinDir%\cscript //Nologo ..\..\tools\cmp_update.js kernel_cfg.h ..\kernel_cfg.h
+%WinDir%\cscript //Nologo ..\..\tools\cmp_update.js kernel_cfg_asm.src ..\kernel_cfg_asm.src
+%WinDir%\cscript //Nologo ..\..\tools\cmp_update.js echonet_cfg.c ..\echonet_cfg.c
+%WinDir%\cscript //Nologo ..\..\tools\cmp_update.js echonet_cfg.h ..\echonet_cfg.h
+</PostBuildCommands-0>
+      <GeneralOptionIsa-0>None</GeneralOptionIsa-0>
+      <GeneralOptionOutput-0>LoadModuleFile</GeneralOptionOutput-0>
+      <GeneralOptionPic-0>False</GeneralOptionPic-0>
+      <GeneralOptionSimultaneousBuild-0>True</GeneralOptionSimultaneousBuild-0>
+      <CompilerVersion-0>
+
+0</CompilerVersion-0>
+      <DependencyFileExistCheckingType-0>Rebuild</DependencyFileExistCheckingType-0>
+      <GeneralOptionCpu-0>RX600</GeneralOptionCpu-0>
+      <GeneralOptionOutputFolder-0>%BuildModeName%</GeneralOptionOutputFolder-0>
+      <GeneralOptionPid-0>None</GeneralOptionPid-0>
+      <EnsureCompatibilityOfPathAndLinkageOrder-0>False</EnsureCompatibilityOfPathAndLinkageOrder-0>
+      <GeneralOptionFpu-0>Fpu</GeneralOptionFpu-0>
+      <GeneralOptionNousePidRegister-0>True</GeneralOptionNousePidRegister-0>
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <GeneralOptionEndian-0>Little</GeneralOptionEndian-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <AsmOptionGoptimize-0>False</AsmOptionGoptimize-0>
+      <GeneralOptionRound-0>Nearest</GeneralOptionRound-0>
+      <LinkOptionMultiConvertFileName-0 />
+      <AsmOptionListFile-0>False</AsmOptionListFile-0>
+      <COptionGoptimize-0>False</COptionGoptimize-0>
+      <GeneralOptionDenormalize-0>Off</GeneralOptionDenormalize-0>
+      <AsmOptionShowConditionals-0>False</AsmOptionShowConditionals-0>
+      <GeneralOptionDblSize-0>SinglePrecision</GeneralOptionDblSize-0>
+      <AsmOptionShowDefinitions-0>False</AsmOptionShowDefinitions-0>
+      <COptionListfile-0>False</COptionListfile-0>
+      <GeneralOptionIntToShort-0>False</GeneralOptionIntToShort-0>
+      <AsmOptionShowExpansions-0>False</AsmOptionShowExpansions-0>
+      <COptionShowSource-0>False</COptionShowSource-0>
+      <GeneralOptionSignedChar-0>Unsigned</GeneralOptionSignedChar-0>
+      <COptionShowConditionals-0>False</COptionShowConditionals-0>
+      <GeneralOptionOtherAdditionalOptions-0 />
+      <GeneralOptionSignedBitfield-0>Unsigned</GeneralOptionSignedBitfield-0>
+      <COptionShowDefinitions-0>False</COptionShowDefinitions-0>
+      <GeneralOptionAutoEnum-0>False</GeneralOptionAutoEnum-0>
+      <COptionShowExpansions-0>False</COptionShowExpansions-0>
+      <GeneralOptionBitOrder-0>Right</GeneralOptionBitOrder-0>
+      <GeneralOptionPack-0>False</GeneralOptionPack-0>
+      <GeneralOptionException-0>False</GeneralOptionException-0>
+      <GeneralOptionRtti-0>False</GeneralOptionRtti-0>
+      <GeneralOptionFintRegister-0>None</GeneralOptionFintRegister-0>
+      <GeneralOptionBranch-0>Branch24</GeneralOptionBranch-0>
+      <GeneralOptionBaseRomRegister-0>None</GeneralOptionBaseRomRegister-0>
+      <GeneralOptionBaseRamRegister-0>None</GeneralOptionBaseRamRegister-0>
+      <GeneralOptionBaseAddressAddress-0>00000000</GeneralOptionBaseAddressAddress-0>
+      <GeneralOptionBaseAddressRegister-0>None</GeneralOptionBaseAddressRegister-0>
+      <GeneralOptionPatch-0>None</GeneralOptionPatch-0>
+      <GeneralOptionSaveAcc-0>False</GeneralOptionSaveAcc-0>
+      <LastCompilerVersion-0>V2.02.00</LastCompilerVersion-0>
+    </Instance>
+    <Instance Guid="95a63257-4aa7-40c0-a74a-7991543b099b">
+      <COptionLangC-DefaultValue>C</COptionLangC-DefaultValue>
+      <COptionListfile-DefaultValue>False</COptionListfile-DefaultValue>
+      <COptionLogo-DefaultValue>False</COptionLogo-DefaultValue>
+      <COptionMisra2004-DefaultValue>None</COptionMisra2004-DefaultValue>
+      <COptionOptimize-DefaultValue>Level2</COptionOptimize-DefaultValue>
+      <COptionOutput-DefaultValue>Object</COptionOutput-DefaultValue>
+      <COptionOutputAssembly-DefaultValue>False</COptionOutputAssembly-DefaultValue>
+      <COptionGoptimize-DefaultValue>False</COptionGoptimize-DefaultValue>
+      <COptionLangCpp-DefaultValue>Cpp</COptionLangCpp-DefaultValue>
+      <COptionMisra2004RuleFile-DefaultValue />
+      <COptionOutputFolder-DefaultValue>%BuildModeName%</COptionOutputFolder-DefaultValue>
+      <COptionOutputPreprocessed-DefaultValue>None</COptionOutputPreprocessed-DefaultValue>
+      <COptionShowSource-DefaultValue>False</COptionShowSource-DefaultValue>
+      <COptionXcref-DefaultValue>False</COptionXcref-DefaultValue>
+      <COptionDebug-DefaultValue>True</COptionDebug-DefaultValue>
+      <COptionInclude-DefaultValue />
+      <COptionMisra2004RuleNumberApply-DefaultValue />
+      <COptionPreCompileCommands-DefaultValue />
+      <COptionShowConditionals-DefaultValue>False</COptionShowConditionals-DefaultValue>
+      <COptionSpeedAndSize-DefaultValue>Size</COptionSpeedAndSize-DefaultValue>
+      <COptionLoop-DefaultValue>Auto</COptionLoop-DefaultValue>
+      <COptionMisra2004RuleNumberIgnore-DefaultValue />
+      <COptionPostCompileCommands-DefaultValue />
+      <COptionSectionP-DefaultValue>P</COptionSectionP-DefaultValue>
+      <COptionShowDefinitions-DefaultValue>False</COptionShowDefinitions-DefaultValue>
+      <COptionSystemInclude-DefaultValue />
+      <COptionLoopValue-DefaultValue>2</COptionLoopValue-DefaultValue>
+      <COptionMisra2004RuleNumberRequiredAdd-DefaultValue />
+      <COptionOtherAdditionalOptions-DefaultValue />
+      <COptionPreinclude-DefaultValue />
+      <COptionSectionC-DefaultValue>C</COptionSectionC-DefaultValue>
+      <COptionShowExpansions-DefaultValue>False</COptionShowExpansions-DefaultValue>
+      <COptionCommandLine-DefaultValue>-cpu=rx600
+-fpu
+-include=..\..\..\asp_dcre
+-include=..\..\..\asp_dcre\arch
+-include=..\..\..\asp_dcre\include
+-include=..\..\..\asp_dcre\kernel
+-include=..\..\..\asp_dcre\arch
+-include=..\..\..\asp_dcre\syssvc
+-include=..\..\..\asp_dcre\library
+-include=..\..\..\asp_dcre\pdic
+-include=..\..\..\asp_dcre\target\grsakura_ccrx
+-include=..\..\..\lwip-1.4.1\src\include
+-include=..\..\..\lwip-1.4.1\src\include\ipv4
+-include=..\..\..\ecnl_lwip
+-include=..\..\..\fatfs
+-include=..\..\..\lwip-1.4.1\ports\ccrx
+-include=..\..\..\lwip-1.4.1\ports\asp_dcre
+-include=..\..\..\lwip-1.4.1\ports\grsakura
+-include=..\..\..\src\usb_watt_meter
+-include=..
+-include=.
+-define=TARGET_KERNEL_ASP,SUPPORT_ETHER,SUPPORT_INET4,SUPPORT_UDP
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</COptionCommandLine-DefaultValue>
+      <COptionDefine-DefaultValue />
+      <COptionInline-DefaultValue>Auto</COptionInline-DefaultValue>
+      <COptionMisra2004RuleNumberRequiredRemove-DefaultValue />
+      <COptionSectionD-DefaultValue>D</COptionSectionD-DefaultValue>
+      <COptionIgnoreFilesMisra-DefaultValue />
+      <COptionInlineValue-DefaultValue>100</COptionInlineValue-DefaultValue>
+      <COptionSectionB-DefaultValue>B</COptionSectionB-DefaultValue>
+      <COptionUndefine-DefaultValue />
+      <COptionCheckLanguageExtension-DefaultValue>False</COptionCheckLanguageExtension-DefaultValue>
+      <COptionFileInline-DefaultValue />
+      <COptionMessage-DefaultValue>False</COptionMessage-DefaultValue>
+      <COptionSectionL-DefaultValue>L</COptionSectionL-DefaultValue>
+      <COptionCase-DefaultValue>Auto</COptionCase-DefaultValue>
+      <COptionMessage2-DefaultValue>False</COptionMessage2-DefaultValue>
+      <COptionSectionW-DefaultValue>W</COptionSectionW-DefaultValue>
+      <COptionNoMessageErrorNumber-DefaultValue />
+      <COptionNostuffB-DefaultValue>False</COptionNostuffB-DefaultValue>
+      <COptionVolatile-DefaultValue>False</COptionVolatile-DefaultValue>
+      <COptionConstCopy-DefaultValue>Auto</COptionConstCopy-DefaultValue>
+      <COptionNoMessageErrorNumber2-DefaultValue />
+      <COptionNostuffD-DefaultValue>False</COptionNostuffD-DefaultValue>
+      <COptionChangeMessageInformation-DefaultValue>No</COptionChangeMessageInformation-DefaultValue>
+      <COptionConstDiv-DefaultValue>Auto</COptionConstDiv-DefaultValue>
+      <COptionNostuffC-DefaultValue>False</COptionNostuffC-DefaultValue>
+      <COptionChangeMessageInformationNumber-DefaultValue />
+      <COptionLibrary-DefaultValue>Intrinsic</COptionLibrary-DefaultValue>
+      <COptionNostuffW-DefaultValue>False</COptionNostuffW-DefaultValue>
+      <COptionChangeMessageInformationNumber2-DefaultValue />
+      <COptionInstalign-DefaultValue>Noinstalign</COptionInstalign-DefaultValue>
+      <COptionScope-DefaultValue>Auto</COptionScope-DefaultValue>
+      <COptionChangeMessageWarning-DefaultValue>No</COptionChangeMessageWarning-DefaultValue>
+      <COptionNouseDiv-DefaultValue>True</COptionNouseDiv-DefaultValue>
+      <COptionSchedule-DefaultValue>Auto</COptionSchedule-DefaultValue>
+      <COptionChangeMessageWarningNumber-DefaultValue />
+      <COptionMap-DefaultValue>NoMap</COptionMap-DefaultValue>
+      <COptionOutcode-DefaultValue>Sjis</COptionOutcode-DefaultValue>
+      <COptionChangeMessageWarningNumber2-DefaultValue />
+      <COptionIntermodule-DefaultValue>None</COptionIntermodule-DefaultValue>
+      <COptionApproxdiv-DefaultValue>False</COptionApproxdiv-DefaultValue>
+      <COptionChangeMessageError-DefaultValue>No</COptionChangeMessageError-DefaultValue>
+      <COptionChangeMessageErrorNumber-DefaultValue />
+      <COptionEnableRegister-DefaultValue>False</COptionEnableRegister-DefaultValue>
+      <COptionChangeMessageErrorNumber2-DefaultValue />
+      <COptionSimpleFloatConv-DefaultValue>False</COptionSimpleFloatConv-DefaultValue>
+      <COptionFileInlinePath-DefaultValue />
+      <COptionFpu-DefaultValue>Fpu</COptionFpu-DefaultValue>
+      <COptionAlias-DefaultValue>False</COptionAlias-DefaultValue>
+      <COptionComment-DefaultValue>False</COptionComment-DefaultValue>
+      <COptionCheck-DefaultValue>No</COptionCheck-DefaultValue>
+      <COptionFloatOrder-DefaultValue>False</COptionFloatOrder-DefaultValue>
+      <COptionIncode-DefaultValue>Sjis</COptionIncode-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587457371974625189</TimeTagModified--0>
+      <COptionLangC-0>C99</COptionLangC-0>
+      <COptionListfile-0>False</COptionListfile-0>
+      <COptionLogo-0>False</COptionLogo-0>
+      <COptionMisra2004-0>None</COptionMisra2004-0>
+      <COptionOptimize-0>Level2</COptionOptimize-0>
+      <COptionOutput-0>Object</COptionOutput-0>
+      <COptionOutputAssembly-0>False</COptionOutputAssembly-0>
+      <COptionGoptimize-0>False</COptionGoptimize-0>
+      <COptionLangCpp-0>Cpp</COptionLangCpp-0>
+      <COptionMisra2004RuleFile-0 />
+      <COptionOutputFolder-0>%BuildModeName%</COptionOutputFolder-0>
+      <COptionOutputPreprocessed-0>None</COptionOutputPreprocessed-0>
+      <COptionShowSource-0>False</COptionShowSource-0>
+      <COptionXcref-0>False</COptionXcref-0>
+      <COptionDebug-0>True</COptionDebug-0>
+      <COptionInclude-0>..\..\..\asp_dcre
+..\..\..\asp_dcre\arch
+..\..\..\asp_dcre\include
+..\..\..\asp_dcre\kernel
+..\..\..\asp_dcre\arch
+..\..\..\asp_dcre\syssvc
+..\..\..\asp_dcre\library
+..\..\..\asp_dcre\pdic
+..\..\..\asp_dcre\target\grsakura_ccrx
+..\..\..\lwip-1.4.1\src\include
+..\..\..\lwip-1.4.1\src\include\ipv4
+..\..\..\ecnl_lwip
+..\..\..\fatfs
+..\..\..\lwip-1.4.1\ports\ccrx
+..\..\..\lwip-1.4.1\ports\asp_dcre
+..\..\..\lwip-1.4.1\ports\grsakura
+..\..\..\src\usb_watt_meter
+..
+.
+</COptionInclude-0>
+      <COptionMisra2004RuleNumberApply-0 />
+      <COptionPreCompileCommands-0 />
+      <COptionShowConditionals-0>False</COptionShowConditionals-0>
+      <COptionSpeedAndSize-0>Size</COptionSpeedAndSize-0>
+      <COptionLoop-0>Auto</COptionLoop-0>
+      <COptionMisra2004RuleNumberIgnore-0 />
+      <COptionPostCompileCommands-0 />
+      <COptionSectionP-0>P</COptionSectionP-0>
+      <COptionShowDefinitions-0>False</COptionShowDefinitions-0>
+      <COptionSystemInclude-0 />
+      <COptionLoopValue-0>2</COptionLoopValue-0>
+      <COptionMisra2004RuleNumberRequiredAdd-0 />
+      <COptionOtherAdditionalOptions-0 />
+      <COptionPreinclude-0 />
+      <COptionSectionC-0>C</COptionSectionC-0>
+      <COptionShowExpansions-0>False</COptionShowExpansions-0>
+      <COptionCommandLine-0>-cpu=rx600
+-fpu
+-include=..\..\..\asp_dcre
+-include=..\..\..\asp_dcre\arch
+-include=..\..\..\asp_dcre\include
+-include=..\..\..\asp_dcre\kernel
+-include=..\..\..\asp_dcre\arch
+-include=..\..\..\asp_dcre\syssvc
+-include=..\..\..\asp_dcre\library
+-include=..\..\..\asp_dcre\pdic
+-include=..\..\..\asp_dcre\target\grsakura_ccrx
+-include=..\..\..\lwip-1.4.1\src\include
+-include=..\..\..\lwip-1.4.1\src\include\ipv4
+-include=..\..\..\ecnl_lwip
+-include=..\..\..\fatfs
+-include=..\..\..\lwip-1.4.1\ports\ccrx
+-include=..\..\..\lwip-1.4.1\ports\asp_dcre
+-include=..\..\..\lwip-1.4.1\ports\grsakura
+-include=..\..\..\src\usb_watt_meter
+-include=..
+-include=.
+-define=TARGET_KERNEL_ASP,SUPPORT_ETHER,SUPPORT_INET4,SUPPORT_UDP
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</COptionCommandLine-0>
+      <COptionDefine-0>TARGET_KERNEL_ASP
+SUPPORT_ETHER
+SUPPORT_INET4
+SUPPORT_UDP
+</COptionDefine-0>
+      <COptionInline-0>Auto</COptionInline-0>
+      <COptionMisra2004RuleNumberRequiredRemove-0 />
+      <COptionSectionD-0>D</COptionSectionD-0>
+      <COptionIgnoreFilesMisra-0 />
+      <COptionInlineValue-0>100</COptionInlineValue-0>
+      <COptionSectionB-0>B</COptionSectionB-0>
+      <COptionUndefine-0 />
+      <COptionCheckLanguageExtension-0>False</COptionCheckLanguageExtension-0>
+      <COptionFileInline-0 />
+      <COptionMessage-0>False</COptionMessage-0>
+      <COptionSectionL-0>L</COptionSectionL-0>
+      <COptionCase-0>Auto</COptionCase-0>
+      <COptionSectionW-0>W</COptionSectionW-0>
+      <COptionNoMessageErrorNumber-0 />
+      <COptionNostuffB-0>False</COptionNostuffB-0>
+      <COptionVolatile-0>False</COptionVolatile-0>
+      <COptionConstCopy-0>Auto</COptionConstCopy-0>
+      <COptionNostuffD-0>False</COptionNostuffD-0>
+      <COptionChangeMessageInformation-0>No</COptionChangeMessageInformation-0>
+      <COptionConstDiv-0>Auto</COptionConstDiv-0>
+      <COptionNostuffC-0>False</COptionNostuffC-0>
+      <COptionChangeMessageInformationNumber-0 />
+      <COptionLibrary-0>Intrinsic</COptionLibrary-0>
+      <COptionNostuffW-0>False</COptionNostuffW-0>
+      <COptionInstalign-0>Noinstalign</COptionInstalign-0>
+      <COptionScope-0>Auto</COptionScope-0>
+      <COptionChangeMessageWarning-0>No</COptionChangeMessageWarning-0>
+      <COptionNouseDiv-0>True</COptionNouseDiv-0>
+      <COptionSchedule-0>Auto</COptionSchedule-0>
+      <COptionChangeMessageWarningNumber-0 />
+      <COptionMap-0>NoMap</COptionMap-0>
+      <COptionOutcode-0>Sjis</COptionOutcode-0>
+      <COptionIntermodule-0>None</COptionIntermodule-0>
+      <COptionApproxdiv-0>False</COptionApproxdiv-0>
+      <COptionChangeMessageError-0>No</COptionChangeMessageError-0>
+      <COptionChangeMessageErrorNumber-0 />
+      <COptionEnableRegister-0>False</COptionEnableRegister-0>
+      <COptionSimpleFloatConv-0>False</COptionSimpleFloatConv-0>
+      <COptionFileInlinePath-0 />
+      <COptionFpu-0>Fpu</COptionFpu-0>
+      <COptionAlias-0>False</COptionAlias-0>
+      <COptionComment-0>False</COptionComment-0>
+      <COptionCheck-0>No</COptionCheck-0>
+      <COptionFloatOrder-0>False</COptionFloatOrder-0>
+      <COptionIncode-0>Sjis</COptionIncode-0>
+    </Instance>
+    <Instance Guid="5ad1746c-d03e-4610-a91f-aaa4fb37bc10">
+      <AsmOptionChkpm-DefaultValue>False</AsmOptionChkpm-DefaultValue>
+      <AsmOptionGoptimize-DefaultValue>False</AsmOptionGoptimize-DefaultValue>
+      <AsmOptionInclude-DefaultValue />
+      <AsmOptionListFile-DefaultValue>False</AsmOptionListFile-DefaultValue>
+      <AsmOptionOutput-DefaultValue>%BuildModeName%</AsmOptionOutput-DefaultValue>
+      <AsmOptionChkfpu-DefaultValue>False</AsmOptionChkfpu-DefaultValue>
+      <AsmOptionDebug-DefaultValue>True</AsmOptionDebug-DefaultValue>
+      <AsmOptionShowConditionals-DefaultValue>False</AsmOptionShowConditionals-DefaultValue>
+      <AsmOptionSystemInclude-DefaultValue />
+      <AsmOptionChkdsp-DefaultValue>False</AsmOptionChkdsp-DefaultValue>
+      <AsmOptionDefine-DefaultValue />
+      <AsmOptionShowDefinitions-DefaultValue>False</AsmOptionShowDefinitions-DefaultValue>
+      <AsmOptionInCode-DefaultValue>SJIS</AsmOptionInCode-DefaultValue>
+      <AsmOptionLogo-DefaultValue>False</AsmOptionLogo-DefaultValue>
+      <AsmOptionShowExpansions-DefaultValue>False</AsmOptionShowExpansions-DefaultValue>
+      <AsmOptionPreAssembleCommands-DefaultValue />
+      <AsmOptionPostAssembleCommands-DefaultValue />
+      <AsmOptionOtherAdditionalOptions-DefaultValue />
+      <AsmOptionCommandLine-DefaultValue />
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053503357851523</TimeTagModified--0>
+      <AsmOptionChkpm-0>False</AsmOptionChkpm-0>
+      <AsmOptionGoptimize-0>False</AsmOptionGoptimize-0>
+      <AsmOptionInclude-0 />
+      <AsmOptionListFile-0>False</AsmOptionListFile-0>
+      <AsmOptionOutput-0>%BuildModeName%</AsmOptionOutput-0>
+      <AsmOptionChkfpu-0>False</AsmOptionChkfpu-0>
+      <AsmOptionDebug-0>True</AsmOptionDebug-0>
+      <AsmOptionShowConditionals-0>False</AsmOptionShowConditionals-0>
+      <AsmOptionSystemInclude-0 />
+      <AsmOptionChkdsp-0>False</AsmOptionChkdsp-0>
+      <AsmOptionDefine-0 />
+      <AsmOptionShowDefinitions-0>False</AsmOptionShowDefinitions-0>
+      <AsmOptionInCode-0>SJIS</AsmOptionInCode-0>
+      <AsmOptionLogo-0>False</AsmOptionLogo-0>
+      <AsmOptionShowExpansions-0>False</AsmOptionShowExpansions-0>
+      <AsmOptionPreAssembleCommands-0 />
+      <AsmOptionPostAssembleCommands-0 />
+      <AsmOptionOtherAdditionalOptions-0 />
+      <AsmOptionCommandLine-0 />
+    </Instance>
+    <Instance Guid="dbb16727-3e81-4169-956a-790355cab4a1">
+      <LinkOptionCpu-DefaultValue>False</LinkOptionCpu-DefaultValue>
+      <LinkOptionForm-DefaultValue>Absolute</LinkOptionForm-DefaultValue>
+      <LinkOptionFormConvert-DefaultValue>Stype</LinkOptionFormConvert-DefaultValue>
+      <LinkOptionInput-DefaultValue />
+      <LinkOptionListShow-DefaultValue>List</LinkOptionListShow-DefaultValue>
+      <LinkOptionOptimize-DefaultValue>None</LinkOptionOptimize-DefaultValue>
+      <LinkOptionStack-DefaultValue>False</LinkOptionStack-DefaultValue>
+      <LinkOptionStart-DefaultValue>B_1,R_1,B_2,R_2,B,R,SU,SI/04,PResetPRG/0FFFF8000,C_1,C_2,C,C$DSEC,C$BSEC,C$INIT,C$VTBL,C$VECT,D_1,D_2,D,P,PIntPRG,W_1,W_2,W,L/0FFFF8100,FIXEDVECT/0FFFFFFD0</LinkOptionStart-DefaultValue>
+      <LinkOptionCompress-DefaultValue>False</LinkOptionCompress-DefaultValue>
+      <LinkOptionCpuInformation-DefaultValue />
+      <LinkOptionDebug-DefaultValue>Debug</LinkOptionDebug-DefaultValue>
+      <LinkOptionFSymbol-DefaultValue />
+      <LinkOptionLibrary-DefaultValue />
+      <LinkOptionOptimizeSymbolDelete-DefaultValue>False</LinkOptionOptimizeSymbolDelete-DefaultValue>
+      <LinkOptionRecordH-DefaultValue>None</LinkOptionRecordH-DefaultValue>
+      <LinkOptionShowSymbol-DefaultValue>False</LinkOptionShowSymbol-DefaultValue>
+      <LinkOptionAlignedSection-DefaultValue />
+      <LinkOptionCpuStride-DefaultValue>False</LinkOptionCpuStride-DefaultValue>
+      <LinkOptionMemory-DefaultValue>False</LinkOptionMemory-DefaultValue>
+      <LinkOptionOptimizeSameCode-DefaultValue>False</LinkOptionOptimizeSameCode-DefaultValue>
+      <LinkOptionOutputFolder-DefaultValue>%BuildModeName%</LinkOptionOutputFolder-DefaultValue>
+      <LinkOptionRecordS-DefaultValue>None</LinkOptionRecordS-DefaultValue>
+      <LinkOptionShowReference-DefaultValue>False</LinkOptionShowReference-DefaultValue>
+      <LinkOptionSystemLibrary-DefaultValue />
+      <LinkOptionBinary-DefaultValue />
+      <LinkOptionChangeMessageInformation-DefaultValue>None</LinkOptionChangeMessageInformation-DefaultValue>
+      <LinkOptionContiguousSection-DefaultValue />
+      <LinkOptionDividedConvertFile-DefaultValue>False</LinkOptionDividedConvertFile-DefaultValue>
+      <LinkOptionOutputFileName-DefaultValue>%ProjectName%.abs</LinkOptionOutputFileName-DefaultValue>
+      <LinkOptionRom-DefaultValue />
+      <LinkOptionSameSize-DefaultValue>1E</LinkOptionSameSize-DefaultValue>
+      <LinkOptionShowXreference-DefaultValue>False</LinkOptionShowXreference-DefaultValue>
+      <LinkOptionChangeMessageInformationNumber-DefaultValue />
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionDefine-DefaultValue />
+      <LinkOptionMap-DefaultValue>False</LinkOptionMap-DefaultValue>
+      <LinkOptionOptimizeShortFormat-DefaultValue>False</LinkOptionOptimizeShortFormat-DefaultValue>
+      <LinkOptionShowTotalSize-DefaultValue>False</LinkOptionShowTotalSize-DefaultValue>
+      <LinkOptionChangeMessageWarning-DefaultValue>None</LinkOptionChangeMessageWarning-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionEntry-DefaultValue>False</LinkOptionEntry-DefaultValue>
+      <LinkOptionMessage-DefaultValue>NoMessage</LinkOptionMessage-DefaultValue>
+      <LinkOptionOptimizeBranch-DefaultValue>False</LinkOptionOptimizeBranch-DefaultValue>
+      <LinkOptionShowVector-DefaultValue>False</LinkOptionShowVector-DefaultValue>
+      <LinkOptionChangeMessageWarningNumber-DefaultValue />
+      <LinkOptionEntryPoint-DefaultValue />
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionNoMessageErrorNumber-DefaultValue />
+      <LinkOptionSymbolForbid-DefaultValue />
+      <LinkOptionChangeMessageError-DefaultValue>None</LinkOptionChangeMessageError-DefaultValue>
+      <LinkOptionNoPrelink-DefaultValue>Auto</LinkOptionNoPrelink-DefaultValue>
+      <LinkOptionPadding-DefaultValue>False</LinkOptionPadding-DefaultValue>
+      <LinkOptionSameCodeForbid-DefaultValue />
+      <LinkOptionSpace-DefaultValue>None</LinkOptionSpace-DefaultValue>
+      <LinkOptionChangeMessageErrorNumber-DefaultValue />
+      <LinkOptionSectionForbid-DefaultValue />
+      <LinkOptionSpaceValue-DefaultValue>FF</LinkOptionSpaceValue-DefaultValue>
+      <LinkOptionVectN-DefaultValue />
+      <LinkOptionAbsoluteForbid-DefaultValue />
+      <LinkOptionByteCount-DefaultValue>False</LinkOptionByteCount-DefaultValue>
+      <LinkOptionHide-DefaultValue>False</LinkOptionHide-DefaultValue>
+      <LinkOptionVect-DefaultValue />
+      <LinkOptionByteCountValue-DefaultValue>FF</LinkOptionByteCountValue-DefaultValue>
+      <LinkOptionJumpEntriesForPic-DefaultValue>False</LinkOptionJumpEntriesForPic-DefaultValue>
+      <LinkOptionTotalSize-DefaultValue>False</LinkOptionTotalSize-DefaultValue>
+      <LinkOptionCrc-DefaultValue>None</LinkOptionCrc-DefaultValue>
+      <LinkOptionJumpEntriesForPicSectionName-DefaultValue />
+      <LinkOptionLogo-DefaultValue>False</LinkOptionLogo-DefaultValue>
+      <LinkOptionCrcOutputAddress-DefaultValue>0</LinkOptionCrcOutputAddress-DefaultValue>
+      <LinkOptionPreLinkCommands-DefaultValue />
+      <LinkOptionCrcCalculationRange-DefaultValue />
+      <LinkOptionPostLinkCommands-DefaultValue />
+      <LinkOptionOtherAdditionalOptionsForLoadModule-DefaultValue />
+      <LinkOptionS9-DefaultValue>False</LinkOptionS9-DefaultValue>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-DefaultValue />
+      <LinkOptionCommandLine-DefaultValue>-noprelink
+-output=%BuildModeName%\%ProjectName%.abs
+-list=%BuildModeName%\%ProjectName%.map
+-show=symbol
+-nooptimize
+-start=B_1,R_1,B_2,R_2,B,R,SU,SI/04,PResetPRG/0FFFF8000,C_1,C_2,C,C$DSEC,C$BSEC,C$INIT,C$VTBL,C$VECT,D_1,D_2,D,P,PIntPRG,W_1,W_2,W,L/0FFFF8100,FIXEDVECT/0FFFFFFD0
+-nologo
+-exit
+</LinkOptionCommandLine-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053497661758479</TimeTagModified--0>
+      <LinkOptionCpu-0>False</LinkOptionCpu-0>
+      <LinkOptionForm-0>Absolute</LinkOptionForm-0>
+      <LinkOptionFormConvert-0>Stype</LinkOptionFormConvert-0>
+      <LinkOptionInput-0 />
+      <LinkOptionListShow-0>List</LinkOptionListShow-0>
+      <LinkOptionOptimize-0>None</LinkOptionOptimize-0>
+      <LinkOptionStack-0>False</LinkOptionStack-0>
+      <LinkOptionStart-0>B_1,R_1,B_2,R_2,B,R,SU,SI/04,PResetPRG/0FFFF8000,C_1,C_2,C,C$DSEC,C$BSEC,C$INIT,C$VTBL,C$VECT,D_1,D_2,D,P,PIntPRG,W_1,W_2,W,L/0FFFF8100,FIXEDVECT/0FFFFFFD0</LinkOptionStart-0>
+      <LinkOptionCompress-0>False</LinkOptionCompress-0>
+      <LinkOptionCpuInformation-0 />
+      <LinkOptionDebug-0>Debug</LinkOptionDebug-0>
+      <LinkOptionFSymbol-0 />
+      <LinkOptionLibrary-0 />
+      <LinkOptionOptimizeSymbolDelete-0>False</LinkOptionOptimizeSymbolDelete-0>
+      <LinkOptionRecordH-0>None</LinkOptionRecordH-0>
+      <LinkOptionShowSymbol-0>True</LinkOptionShowSymbol-0>
+      <LinkOptionAlignedSection-0 />
+      <LinkOptionCpuStride-0>False</LinkOptionCpuStride-0>
+      <LinkOptionMemory-0>False</LinkOptionMemory-0>
+      <LinkOptionOptimizeSameCode-0>False</LinkOptionOptimizeSameCode-0>
+      <LinkOptionOutputFolder-0>%BuildModeName%</LinkOptionOutputFolder-0>
+      <LinkOptionRecordS-0>None</LinkOptionRecordS-0>
+      <LinkOptionShowReference-0>False</LinkOptionShowReference-0>
+      <LinkOptionSystemLibrary-0 />
+      <LinkOptionBinary-0 />
+      <LinkOptionChangeMessageInformation-0>None</LinkOptionChangeMessageInformation-0>
+      <LinkOptionContiguousSection-0 />
+      <LinkOptionDividedConvertFile-0>False</LinkOptionDividedConvertFile-0>
+      <LinkOptionOutputFileName-0>%ProjectName%.abs</LinkOptionOutputFileName-0>
+      <LinkOptionRom-0 />
+      <LinkOptionSameSize-0>1E</LinkOptionSameSize-0>
+      <LinkOptionShowXreference-0>False</LinkOptionShowXreference-0>
+      <LinkOptionChangeMessageInformationNumber-0 />
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <LinkOptionDefine-0 />
+      <LinkOptionMap-0>False</LinkOptionMap-0>
+      <LinkOptionOptimizeShortFormat-0>False</LinkOptionOptimizeShortFormat-0>
+      <LinkOptionShowTotalSize-0>False</LinkOptionShowTotalSize-0>
+      <LinkOptionChangeMessageWarning-0>None</LinkOptionChangeMessageWarning-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <LinkOptionEntry-0>False</LinkOptionEntry-0>
+      <LinkOptionMessage-0>NoMessage</LinkOptionMessage-0>
+      <LinkOptionOptimizeBranch-0>False</LinkOptionOptimizeBranch-0>
+      <LinkOptionShowVector-0>False</LinkOptionShowVector-0>
+      <LinkOptionChangeMessageWarningNumber-0 />
+      <LinkOptionEntryPoint-0 />
+      <LinkOptionMultiConvertFileName-0 />
+      <LinkOptionNoMessageErrorNumber-0 />
+      <LinkOptionSymbolForbid-0 />
+      <LinkOptionChangeMessageError-0>None</LinkOptionChangeMessageError-0>
+      <LinkOptionNoPrelink-0>Auto</LinkOptionNoPrelink-0>
+      <LinkOptionPadding-0>False</LinkOptionPadding-0>
+      <LinkOptionSameCodeForbid-0 />
+      <LinkOptionSpace-0>None</LinkOptionSpace-0>
+      <LinkOptionChangeMessageErrorNumber-0 />
+      <LinkOptionSectionForbid-0 />
+      <LinkOptionSpaceValue-0>FF</LinkOptionSpaceValue-0>
+      <LinkOptionVectN-0 />
+      <LinkOptionAbsoluteForbid-0 />
+      <LinkOptionByteCount-0>False</LinkOptionByteCount-0>
+      <LinkOptionHide-0>False</LinkOptionHide-0>
+      <LinkOptionVect-0 />
+      <LinkOptionByteCountValue-0>FF</LinkOptionByteCountValue-0>
+      <LinkOptionJumpEntriesForPic-0>False</LinkOptionJumpEntriesForPic-0>
+      <LinkOptionTotalSize-0>False</LinkOptionTotalSize-0>
+      <LinkOptionCrc-0>None</LinkOptionCrc-0>
+      <LinkOptionJumpEntriesForPicSectionName-0 />
+      <LinkOptionLogo-0>False</LinkOptionLogo-0>
+      <LinkOptionCrcOutputAddress-0>0</LinkOptionCrcOutputAddress-0>
+      <LinkOptionPreLinkCommands-0 />
+      <LinkOptionCrcCalculationRange-0 />
+      <LinkOptionPostLinkCommands-0 />
+      <LinkOptionOtherAdditionalOptionsForLoadModule-0 />
+      <LinkOptionS9-0>False</LinkOptionS9-0>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-0 />
+      <LinkOptionCommandLine-0>-noprelink
+-output=%BuildModeName%\%ProjectName%.abs
+-list=%BuildModeName%\%ProjectName%.map
+-show=symbol
+-nooptimize
+-start=B_1,R_1,B_2,R_2,B,R,SU,SI/04,PResetPRG/0FFFF8000,C_1,C_2,C,C$DSEC,C$BSEC,C$INIT,C$VTBL,C$VECT,D_1,D_2,D,P,PIntPRG,W_1,W_2,W,L/0FFFF8100,FIXEDVECT/0FFFFFFD0
+-nologo
+-exit
+</LinkOptionCommandLine-0>
+    </Instance>
+    <Instance Guid="df74c69e-635e-42d9-845e-14128ba4d48a">
+      <HexOptionForm-DefaultValue>Stype</HexOptionForm-DefaultValue>
+      <HexOptionOutput-DefaultValue>True</HexOptionOutput-DefaultValue>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-DefaultValue />
+      <HexOptionCommandLine-DefaultValue />
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionRecordH-DefaultValue>None</LinkOptionRecordH-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionRecordS-DefaultValue>None</LinkOptionRecordS-DefaultValue>
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionSpace-DefaultValue>None</LinkOptionSpace-DefaultValue>
+      <LinkOptionSpaceValue-DefaultValue>FF</LinkOptionSpaceValue-DefaultValue>
+      <LinkOptionByteCount-DefaultValue>False</LinkOptionByteCount-DefaultValue>
+      <LinkOptionByteCountValue-DefaultValue>FF</LinkOptionByteCountValue-DefaultValue>
+      <LinkOptionCrc-DefaultValue>None</LinkOptionCrc-DefaultValue>
+      <LinkOptionCrcOutputAddress-DefaultValue>0</LinkOptionCrcOutputAddress-DefaultValue>
+      <LinkOptionCrcCalculationRange-DefaultValue />
+      <LinkOptionS9-DefaultValue>False</LinkOptionS9-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053503357851523</TimeTagModified--0>
+      <HexOptionForm-0>Stype</HexOptionForm-0>
+      <HexOptionOutput-0>True</HexOptionOutput-0>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-0 />
+      <HexOptionCommandLine-0 />
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <LinkOptionRecordH-0>None</LinkOptionRecordH-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <LinkOptionRecordS-0>None</LinkOptionRecordS-0>
+      <LinkOptionMultiConvertFileName-0 />
+      <LinkOptionSpace-0>None</LinkOptionSpace-0>
+      <LinkOptionSpaceValue-0>FF</LinkOptionSpaceValue-0>
+      <LinkOptionByteCount-0>False</LinkOptionByteCount-0>
+      <LinkOptionByteCountValue-0>FF</LinkOptionByteCountValue-0>
+      <LinkOptionCrc-0>None</LinkOptionCrc-0>
+      <LinkOptionCrcOutputAddress-0>0</LinkOptionCrcOutputAddress-0>
+      <LinkOptionCrcCalculationRange-0 />
+      <LinkOptionS9-0>False</LinkOptionS9-0>
+    </Instance>
+    <Instance Guid="fff50d2e-74da-44ea-90a8-c47756029e83">
+      <LibOptionForm-DefaultValue>LibraryU</LibOptionForm-DefaultValue>
+      <LibOptionInput-DefaultValue />
+      <LibOptionListShow-DefaultValue>None</LibOptionListShow-DefaultValue>
+      <LibOptionMemory-DefaultValue>False</LibOptionMemory-DefaultValue>
+      <LibOptionChangeMessageInformation-DefaultValue>None</LibOptionChangeMessageInformation-DefaultValue>
+      <LibOptionDebug-DefaultValue>Debug</LibOptionDebug-DefaultValue>
+      <LibOptionLibrary-DefaultValue />
+      <LibOptionShowSymbol-DefaultValue>False</LibOptionShowSymbol-DefaultValue>
+      <LibOptionChangeMessageInformationNumber-DefaultValue />
+      <LibOptionOutputFolder-DefaultValue>%BuildModeName%</LibOptionOutputFolder-DefaultValue>
+      <LibOptionShowSection-DefaultValue>False</LibOptionShowSection-DefaultValue>
+      <LibOptionSystemLibrary-DefaultValue />
+      <LibOptionBinary-DefaultValue />
+      <LibOptionChangeMessageWarning-DefaultValue>None</LibOptionChangeMessageWarning-DefaultValue>
+      <LibOptionOutputFileName-DefaultValue>%ProjectName%.lib</LibOptionOutputFileName-DefaultValue>
+      <LibOptionShowXreference-DefaultValue>False</LibOptionShowXreference-DefaultValue>
+      <LibOptionChangeMessageWarningNumber-DefaultValue />
+      <LibOptionMessage-DefaultValue>NoMessage</LibOptionMessage-DefaultValue>
+      <LibOptionNoPrelink-DefaultValue>Auto</LibOptionNoPrelink-DefaultValue>
+      <LibOptionShowTotalSize-DefaultValue>False</LibOptionShowTotalSize-DefaultValue>
+      <LibOptionChangeMessageError-DefaultValue>None</LibOptionChangeMessageError-DefaultValue>
+      <LibOptionNoMessageErrorNumber-DefaultValue />
+      <LibOptionShowVector-DefaultValue>False</LibOptionShowVector-DefaultValue>
+      <LibOptionChangeMessageErrorNumber-DefaultValue />
+      <LibOptionHide-DefaultValue>False</LibOptionHide-DefaultValue>
+      <LibOptionTotalSize-DefaultValue>False</LibOptionTotalSize-DefaultValue>
+      <LibOptionLogo-DefaultValue>False</LibOptionLogo-DefaultValue>
+      <LibOptionPreLibrarianCommands-DefaultValue />
+      <LibOptionPostLibrarianCommands-DefaultValue />
+      <LibOptionOtherAdditionalOptions-DefaultValue />
+      <LibOptionCommandLine-DefaultValue />
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053503357851523</TimeTagModified--0>
+      <LibOptionForm-0>LibraryU</LibOptionForm-0>
+      <LibOptionInput-0 />
+      <LibOptionListShow-0>None</LibOptionListShow-0>
+      <LibOptionMemory-0>False</LibOptionMemory-0>
+      <LibOptionChangeMessageInformation-0>None</LibOptionChangeMessageInformation-0>
+      <LibOptionDebug-0>Debug</LibOptionDebug-0>
+      <LibOptionLibrary-0 />
+      <LibOptionShowSymbol-0>False</LibOptionShowSymbol-0>
+      <LibOptionChangeMessageInformationNumber-0 />
+      <LibOptionOutputFolder-0>%BuildModeName%</LibOptionOutputFolder-0>
+      <LibOptionShowSection-0>False</LibOptionShowSection-0>
+      <LibOptionSystemLibrary-0 />
+      <LibOptionBinary-0 />
+      <LibOptionChangeMessageWarning-0>None</LibOptionChangeMessageWarning-0>
+      <LibOptionOutputFileName-0>%ProjectName%.lib</LibOptionOutputFileName-0>
+      <LibOptionShowXreference-0>False</LibOptionShowXreference-0>
+      <LibOptionChangeMessageWarningNumber-0 />
+      <LibOptionMessage-0>NoMessage</LibOptionMessage-0>
+      <LibOptionNoPrelink-0>Auto</LibOptionNoPrelink-0>
+      <LibOptionShowTotalSize-0>False</LibOptionShowTotalSize-0>
+      <LibOptionChangeMessageError-0>None</LibOptionChangeMessageError-0>
+      <LibOptionNoMessageErrorNumber-0 />
+      <LibOptionShowVector-0>False</LibOptionShowVector-0>
+      <LibOptionChangeMessageErrorNumber-0 />
+      <LibOptionHide-0>False</LibOptionHide-0>
+      <LibOptionTotalSize-0>False</LibOptionTotalSize-0>
+      <LibOptionLogo-0>False</LibOptionLogo-0>
+      <LibOptionPreLibrarianCommands-0 />
+      <LibOptionPostLibrarianCommands-0 />
+      <LibOptionOtherAdditionalOptions-0 />
+      <LibOptionCommandLine-0 />
+    </Instance>
+    <Instance Guid="9cb0ade0-b3cb-4e21-823c-290b5fdb5f1e">
+      <LbgOptionLanguage-DefaultValue>C</LbgOptionLanguage-DefaultValue>
+      <LbgOptionLibraryMode-DefaultValue>MakeOptionChanged</LbgOptionLibraryMode-DefaultValue>
+      <LbgOptionLogo-DefaultValue>False</LbgOptionLogo-DefaultValue>
+      <LbgOptionOptimize-DefaultValue>Level2</LbgOptionOptimize-DefaultValue>
+      <LbgOptionOutputFolder-DefaultValue>%BuildModeName%</LbgOptionOutputFolder-DefaultValue>
+      <LbgOptionGoptimize-DefaultValue>False</LbgOptionGoptimize-DefaultValue>
+      <LbgOptionHead-DefaultValue>Custom</LbgOptionHead-DefaultValue>
+      <LbgOptionOutputFileName-DefaultValue>%ProjectName%.lib</LbgOptionOutputFileName-DefaultValue>
+      <LbgOptionPreLibraryGenerateCommands-DefaultValue />
+      <LbgOptionFunctionalCutdown-DefaultValue>None</LbgOptionFunctionalCutdown-DefaultValue>
+      <LbgOptionHeadRuntime-DefaultValue>True</LbgOptionHeadRuntime-DefaultValue>
+      <LbgOptionPostLibraryGenerateCommands-DefaultValue />
+      <LbgOptionSpeedAndSize-DefaultValue>Size</LbgOptionSpeedAndSize-DefaultValue>
+      <LbgOptionHeadCtypeH-DefaultValue>False</LbgOptionHeadCtypeH-DefaultValue>
+      <LbgOptionLoop-DefaultValue>Auto</LbgOptionLoop-DefaultValue>
+      <LbgOptionOtherAdditionalOptions-DefaultValue />
+      <LbgOptionReent-DefaultValue>False</LbgOptionReent-DefaultValue>
+      <LbgOptionCommandLine-DefaultValue />
+      <LbgOptionHeadMathH-DefaultValue>False</LbgOptionHeadMathH-DefaultValue>
+      <LbgOptionLoopValue-DefaultValue>2</LbgOptionLoopValue-DefaultValue>
+      <LbgOptionSectionP-DefaultValue>P</LbgOptionSectionP-DefaultValue>
+      <LbgOptionHeadMathfH-DefaultValue>False</LbgOptionHeadMathfH-DefaultValue>
+      <LbgOptionInline-DefaultValue>Auto</LbgOptionInline-DefaultValue>
+      <LbgOptionSectionC-DefaultValue>C</LbgOptionSectionC-DefaultValue>
+      <LbgOptionHeadStdargH-DefaultValue>False</LbgOptionHeadStdargH-DefaultValue>
+      <LbgOptionInlineValue-DefaultValue>100</LbgOptionInlineValue-DefaultValue>
+      <LbgOptionSectionD-DefaultValue>D</LbgOptionSectionD-DefaultValue>
+      <LbgOptionFileInline-DefaultValue />
+      <LbgOptionHeadStdioH-DefaultValue>True</LbgOptionHeadStdioH-DefaultValue>
+      <LbgOptionSectionB-DefaultValue>B</LbgOptionSectionB-DefaultValue>
+      <LbgOptionCase-DefaultValue>Auto</LbgOptionCase-DefaultValue>
+      <LbgOptionHeadStdlibH-DefaultValue>True</LbgOptionHeadStdlibH-DefaultValue>
+      <LbgOptionSectionL-DefaultValue>L</LbgOptionSectionL-DefaultValue>
+      <LbgOptionHeadStringH-DefaultValue>True</LbgOptionHeadStringH-DefaultValue>
+      <LbgOptionSectionW-DefaultValue>W</LbgOptionSectionW-DefaultValue>
+      <LbgOptionVolatile-DefaultValue>False</LbgOptionVolatile-DefaultValue>
+      <LbgOptionConstCopy-DefaultValue>Auto</LbgOptionConstCopy-DefaultValue>
+      <LbgOptionHeadIos-DefaultValue>False</LbgOptionHeadIos-DefaultValue>
+      <LbgOptionNostuffB-DefaultValue>False</LbgOptionNostuffB-DefaultValue>
+      <LbgOptionConstDiv-DefaultValue>Auto</LbgOptionConstDiv-DefaultValue>
+      <LbgOptionHeadNew-DefaultValue>True</LbgOptionHeadNew-DefaultValue>
+      <LbgOptionNostuffD-DefaultValue>False</LbgOptionNostuffD-DefaultValue>
+      <LbgOptionHeadComplex-DefaultValue>False</LbgOptionHeadComplex-DefaultValue>
+      <LbgOptionLibrary-DefaultValue>Intrinsic</LbgOptionLibrary-DefaultValue>
+      <LbgOptionNostuffC-DefaultValue>False</LbgOptionNostuffC-DefaultValue>
+      <LbgOptionHeadString-DefaultValue>False</LbgOptionHeadString-DefaultValue>
+      <LbgOptionNostuffW-DefaultValue>False</LbgOptionNostuffW-DefaultValue>
+      <LbgOptionScope-DefaultValue>Auto</LbgOptionScope-DefaultValue>
+      <LbgOptionHeadComplexH-DefaultValue>False</LbgOptionHeadComplexH-DefaultValue>
+      <LbgOptionInstalign-DefaultValue>Noinstalign</LbgOptionInstalign-DefaultValue>
+      <LbgOptionSchedule-DefaultValue>Auto</LbgOptionSchedule-DefaultValue>
+      <LbgOptionApproxdiv-DefaultValue>False</LbgOptionApproxdiv-DefaultValue>
+      <LbgOptionHeadFenvH-DefaultValue>False</LbgOptionHeadFenvH-DefaultValue>
+      <LbgOptionNouseDiv-DefaultValue>True</LbgOptionNouseDiv-DefaultValue>
+      <LbgOptionEnableRegister-DefaultValue>False</LbgOptionEnableRegister-DefaultValue>
+      <LbgOptionHeadInttypesH-DefaultValue>False</LbgOptionHeadInttypesH-DefaultValue>
+      <LbgOptionHeadWcharH-DefaultValue>False</LbgOptionHeadWcharH-DefaultValue>
+      <LbgOptionSimpleFloatConv-DefaultValue>False</LbgOptionSimpleFloatConv-DefaultValue>
+      <LbgOptionFpu-DefaultValue>Fpu</LbgOptionFpu-DefaultValue>
+      <LbgOptionHeadWctypeH-DefaultValue>False</LbgOptionHeadWctypeH-DefaultValue>
+      <LbgOptionFloatOrder-DefaultValue>False</LbgOptionFloatOrder-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053503357851523</TimeTagModified--0>
+      <LbgOptionLanguage-0>C</LbgOptionLanguage-0>
+      <LbgOptionLibraryMode-0>MakeOptionChanged</LbgOptionLibraryMode-0>
+      <LbgOptionLogo-0>False</LbgOptionLogo-0>
+      <LbgOptionOptimize-0>Level2</LbgOptionOptimize-0>
+      <LbgOptionOutputFolder-0>%BuildModeName%</LbgOptionOutputFolder-0>
+      <LbgOptionGoptimize-0>False</LbgOptionGoptimize-0>
+      <LbgOptionHead-0>Custom</LbgOptionHead-0>
+      <LbgOptionOutputFileName-0>%ProjectName%.lib</LbgOptionOutputFileName-0>
+      <LbgOptionPreLibraryGenerateCommands-0 />
+      <LbgOptionFunctionalCutdown-0>None</LbgOptionFunctionalCutdown-0>
+      <LbgOptionPostLibraryGenerateCommands-0 />
+      <LbgOptionSpeedAndSize-0>Size</LbgOptionSpeedAndSize-0>
+      <LbgOptionHeadCtypeH-0>False</LbgOptionHeadCtypeH-0>
+      <LbgOptionLoop-0>Auto</LbgOptionLoop-0>
+      <LbgOptionOtherAdditionalOptions-0 />
+      <LbgOptionReent-0>False</LbgOptionReent-0>
+      <LbgOptionCommandLine-0 />
+      <LbgOptionHeadMathH-0>False</LbgOptionHeadMathH-0>
+      <LbgOptionLoopValue-0>2</LbgOptionLoopValue-0>
+      <LbgOptionSectionP-0>P</LbgOptionSectionP-0>
+      <LbgOptionHeadMathfH-0>False</LbgOptionHeadMathfH-0>
+      <LbgOptionInline-0>Auto</LbgOptionInline-0>
+      <LbgOptionSectionC-0>C</LbgOptionSectionC-0>
+      <LbgOptionHeadStdargH-0>False</LbgOptionHeadStdargH-0>
+      <LbgOptionInlineValue-0>100</LbgOptionInlineValue-0>
+      <LbgOptionSectionD-0>D</LbgOptionSectionD-0>
+      <LbgOptionFileInline-0 />
+      <LbgOptionHeadStdioH-0>True</LbgOptionHeadStdioH-0>
+      <LbgOptionSectionB-0>B</LbgOptionSectionB-0>
+      <LbgOptionCase-0>Auto</LbgOptionCase-0>
+      <LbgOptionHeadStdlibH-0>True</LbgOptionHeadStdlibH-0>
+      <LbgOptionSectionL-0>L</LbgOptionSectionL-0>
+      <LbgOptionHeadStringH-0>True</LbgOptionHeadStringH-0>
+      <LbgOptionSectionW-0>W</LbgOptionSectionW-0>
+      <LbgOptionVolatile-0>False</LbgOptionVolatile-0>
+      <LbgOptionConstCopy-0>Auto</LbgOptionConstCopy-0>
+      <LbgOptionHeadIos-0>False</LbgOptionHeadIos-0>
+      <LbgOptionNostuffB-0>False</LbgOptionNostuffB-0>
+      <LbgOptionConstDiv-0>Auto</LbgOptionConstDiv-0>
+      <LbgOptionHeadNew-0>True</LbgOptionHeadNew-0>
+      <LbgOptionNostuffD-0>False</LbgOptionNostuffD-0>
+      <LbgOptionHeadComplex-0>False</LbgOptionHeadComplex-0>
+      <LbgOptionLibrary-0>Intrinsic</LbgOptionLibrary-0>
+      <LbgOptionNostuffC-0>False</LbgOptionNostuffC-0>
+      <LbgOptionHeadString-0>False</LbgOptionHeadString-0>
+      <LbgOptionNostuffW-0>False</LbgOptionNostuffW-0>
+      <LbgOptionScope-0>Auto</LbgOptionScope-0>
+      <LbgOptionHeadComplexH-0>False</LbgOptionHeadComplexH-0>
+      <LbgOptionInstalign-0>Noinstalign</LbgOptionInstalign-0>
+      <LbgOptionSchedule-0>Auto</LbgOptionSchedule-0>
+      <LbgOptionApproxdiv-0>False</LbgOptionApproxdiv-0>
+      <LbgOptionHeadFenvH-0>False</LbgOptionHeadFenvH-0>
+      <LbgOptionNouseDiv-0>True</LbgOptionNouseDiv-0>
+      <LbgOptionEnableRegister-0>False</LbgOptionEnableRegister-0>
+      <LbgOptionHeadInttypesH-0>False</LbgOptionHeadInttypesH-0>
+      <LbgOptionHeadWcharH-0>False</LbgOptionHeadWcharH-0>
+      <LbgOptionSimpleFloatConv-0>False</LbgOptionSimpleFloatConv-0>
+      <LbgOptionFpu-0>Fpu</LbgOptionFpu-0>
+      <LbgOptionHeadWctypeH-0>False</LbgOptionHeadWctypeH-0>
+      <LbgOptionFloatOrder-0>False</LbgOptionFloatOrder-0>
+    </Instance>
+    <Instance Guid="76d4ee54-712a-4601-bcfd-b16a1a54c781">
+      <ItemAddTime>635318883980019487</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a7be515f-f007-45ed-9059-4e1500c0f74d">
+      <TimeTagModified-SourceItem0--0>-8588053476874756321</TimeTagModified-SourceItem0--0>
+      <SourceItem0-IsLockedByUser>False</SourceItem0-IsLockedByUser>
+      <SourceItem0-BuildingTarget-0>True</SourceItem0-BuildingTarget-0>
+      <SourceItem0-IndividualCompileOption-0>False</SourceItem0-IndividualCompileOption-0>
+    </Instance>
+  </Class>
+  <Class Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
+    <Instance Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
+      <IsLibraryMode>False</IsLibraryMode>
+      <StartUpCategoryItem>00000000-0000-0000-0000-000000000000</StartUpCategoryItem>
+    </Instance>
+  </Class>
+  <Class Guid="a29a09ee-92c3-4ce7-9586-a1b058043f92">
+    <Instance Guid="a29a09ee-92c3-4ce7-9586-a1b058043f92">
+      <ProjectGeneratr-GeneratedFile0 />
+    </Instance>
+  </Class>
+  <Class Guid="31a86ad3-37bd-4846-aff2-e08abdc00197">
+    <Instance Guid="31a86ad3-37bd-4846-aff2-e08abdc00197">
+      <DeviceNameOnCreateStartup>R5F563NBDxFP</DeviceNameOnCreateStartup>
+    </Instance>
+  </Class>
+  <Class Guid="8b5af363-dcc2-48e6-919c-6cdb80d50173">
+    <Instance Guid="8b5af363-dcc2-48e6-919c-6cdb80d50173">
+      <DataFormatVersionPlugin>1.0</DataFormatVersionPlugin>
+      <DataFormatVersionDebugger>1.0</DataFormatVersionDebugger>
+    </Instance>
+  </Class>
+  <Class Guid="932085a2-9361-4df9-a3f7-12e6de7681a8">
+    <Instance Guid="932085a2-9361-4df9-a3f7-12e6de7681a8">
+      <DebugToolManager>1d1a55cf-2b92-481a-af4f-5975d095c419</DebugToolManager>
+    </Instance>
+  </Class>
+  <Class Guid="e4df8d71-236e-4af2-aaea-56345a08da25">
+    <Instance Guid="9e76d4e8-0b8f-4e7c-91b7-a4c442bcf2e7">
+      <DeviceChangedCounter>0</DeviceChangedCounter>
+      <DeviceName>R5F563NBDxFP</DeviceName>
+      <DebuggerProperty-EssentialProperty-Endian-CpuEndian>Little</DebuggerProperty-EssentialProperty-Endian-CpuEndian>
+      <DebuggerProperty-EssentialProperty-Clock-SystemClockFrequency>100</DebuggerProperty-EssentialProperty-Clock-SystemClockFrequency>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Length>3</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Length>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item0-Name>CMT</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item0-Name>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item0-IsUse>False</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item0-IsUse>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item1-Name>ICU</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item1-Name>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item1-IsUse>False</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item1-IsUse>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item2-Name>MPU</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item2-Name>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item2-IsUse>False</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item2-IsUse>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-PeripheralClockRate>ClockRate_1</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-PeripheralClockRate>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-Length>1</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-Length>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-DebuggerGuid />
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-FileName>DefaultBuild\cfg.abs</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-FileName>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-FileType>LoadModuleFile</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-FileType>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-Offset>0</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-Offset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-StartAddress>0</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-StartAddress>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-ObjectDownload>True</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-ObjectDownload>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-SymbolDownload>True</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-SymbolDownload>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-UsePicPidOffset>False</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-UsePicPidOffset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-PicOffset>0</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-PicOffset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-PidOffset>0</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-PidOffset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-GenerateInformationForInputCompletion>True</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-GenerateInformationForInputCompletion>
+      <DebuggerProperty-DownloadProperty-DebugInformation-CpuReset>True</DebuggerProperty-DownloadProperty-DebugInformation-CpuReset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-FlashErase>False</DebuggerProperty-DownloadProperty-DebugInformation-FlashErase>
+      <DebuggerProperty-DownloadProperty-DebugInformation-EventCorrection>SuspendEvent</DebuggerProperty-DownloadProperty-DebugInformation-EventCorrection>
+      <DebuggerProperty-DownloadProperty-DebugInformation-SkipStartup>True</DebuggerProperty-DownloadProperty-DebugInformation-SkipStartup>
+      <DebuggerProperty-DownloadProperty-DebugInformation-MainSymbol>XwBtAGEAaQBuAA==</DebuggerProperty-DownloadProperty-DebugInformation-MainSymbol>
+      <DebuggerProperty-OptionalProperty-Register-UpdateDisplayInExecutionForPC>No</DebuggerProperty-OptionalProperty-Register-UpdateDisplayInExecutionForPC>
+      <DebuggerProperty-OptionalProperty-Register-UpdateIntervalForPC>500</DebuggerProperty-OptionalProperty-Register-UpdateIntervalForPC>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-Length>17</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-Length>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-MapType>InternalRam</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-StartAddress>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-EndAddress>131071</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-StartAddress>131072</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-EndAddress>524287</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-StartAddress>524288</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-EndAddress>540671</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-StartAddress>540672</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-EndAddress>548863</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-StartAddress>548864</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-EndAddress>557055</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-StartAddress>557056</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-EndAddress>581631</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-StartAddress>581632</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-EndAddress>589823</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-StartAddress>589824</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-EndAddress>655359</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-StartAddress>655360</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-EndAddress>786431</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-StartAddress>786432</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-EndAddress>1048575</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-MapType>InternalRom</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-StartAddress>1048576</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-EndAddress>1081343</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-StartAddress>1081344</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-EndAddress>8372223</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-StartAddress>8372224</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-EndAddress>8373503</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-StartAddress>8373504</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-EndAddress>8387583</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-StartAddress>8387584</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-EndAddress>8388607</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-StartAddress>8388608</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-EndAddress>4293918719</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-MapType>InternalRom</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-StartAddress>4293918720</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-EndAddress>4294967295</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-Endian>
+      <DebuggerProperty-OptionalProperty-AccessMemory-UpdateDisplayInExecution>Yes</DebuggerProperty-OptionalProperty-AccessMemory-UpdateDisplayInExecution>
+      <DebuggerProperty-OptionalProperty-AccessMemory-UpdateInterval>500</DebuggerProperty-OptionalProperty-AccessMemory-UpdateInterval>
+      <DebuggerProperty-OptionalProperty-Trace-UseTrace>No</DebuggerProperty-OptionalProperty-Trace-UseTrace>
+      <DebuggerProperty-OptionalProperty-Trace-ClearTraceMemory>Yes</DebuggerProperty-OptionalProperty-Trace-ClearTraceMemory>
+      <DebuggerProperty-OptionalProperty-Trace-TraceMode>Nonstop</DebuggerProperty-OptionalProperty-Trace-TraceMode>
+      <DebuggerProperty-OptionalProperty-Trace-AddUptimeTag>No</DebuggerProperty-OptionalProperty-Trace-AddUptimeTag>
+      <DebuggerProperty-OptionalProperty-Trace-TraceMemorySize>TraceMemory_64KB</DebuggerProperty-OptionalProperty-Trace-TraceMemorySize>
+      <DebuggerProperty-OptionalProperty-Coverage-UseCoverage>No</DebuggerProperty-OptionalProperty-Coverage-UseCoverage>
+      <DebuggerProperty-OptionalProperty-Coverage-ReuseCoverageData>No</DebuggerProperty-OptionalProperty-Coverage-ReuseCoverageData>
+      <DebuggerProperty-OptionalProperty-StreamIO-SelectStreamIO>Simulator</DebuggerProperty-OptionalProperty-StreamIO-SelectStreamIO>
+      <DebuggerProperty-OptionalProperty-StreamIO-UseStreamIO>No</DebuggerProperty-OptionalProperty-StreamIO-UseStreamIO>
+      <DebuggerProperty-OptionalProperty-StreamIO-StreamIOAddress>0</DebuggerProperty-OptionalProperty-StreamIO-StreamIOAddress>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-ExecutionModeType>Stop</DebuggerProperty-OptionalProperty-ExecutionMode-ExecutionModeType>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopUndefined>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopUndefined>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopPrivileged>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopPrivileged>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopAccess>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopAccess>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopFloatingPoint>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopFloatingPoint>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopInterrupt>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopInterrupt>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopInt>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopInt>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopBrk>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopBrk>
+      <DebuggerProperty-OptionalProperty-InstructionDecodeCache-CacheResults>No</DebuggerProperty-OptionalProperty-InstructionDecodeCache-CacheResults>
+      <DebuggerProperty-HookProperty-HookTransaction-Downloading-Length>0</DebuggerProperty-HookProperty-HookTransaction-Downloading-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Downloaded-Length>0</DebuggerProperty-HookProperty-HookTransaction-Downloaded-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Reset-Length>0</DebuggerProperty-HookProperty-HookTransaction-Reset-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Going-Length>0</DebuggerProperty-HookProperty-HookTransaction-Going-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Broke-Length>0</DebuggerProperty-HookProperty-HookTransaction-Broke-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Connected-Length>0</DebuggerProperty-HookProperty-HookTransaction-Connected-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Disconnecting-Length>0</DebuggerProperty-HookProperty-HookTransaction-Disconnecting-Length>
+      <DebuggerProperty-DownloadProperty-DebugInformation-MaxLoaderMemorySize>500</DebuggerProperty-DownloadProperty-DebugInformation-MaxLoaderMemorySize>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-IsDefaultItem>True</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-IsDefaultItem>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-DefaultItemProjectGuid>04dd15f3-a521-4091-8ca9-d183965ea77a</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-DefaultItemProjectGuid>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-CompilerType>Auto</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-CompilerType>
+      <DebuggerProperty-DownloadProperty-None-DefaultDownloadItemSupported>True</DebuggerProperty-DownloadProperty-None-DefaultDownloadItemSupported>
+    </Instance>
+  </Class>
+  <Class Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">
+    <Instance Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">
+      <ProductVersion>5.01.00.00</ProductVersion>
+    </Instance>
+  </Class>
+</CubeSuiteProject>
Index: UsbWattMeter/trunk/csp/usb_watt_meter/usb_watt_meter.mtpj
===================================================================
--- UsbWattMeter/trunk/csp/usb_watt_meter/usb_watt_meter.mtpj	(revision 164)
+++ UsbWattMeter/trunk/csp/usb_watt_meter/usb_watt_meter.mtpj	(revision 164)
@@ -0,0 +1,1792 @@
+<CubeSuiteProject>
+  <ProductVersion>4.02.00.00</ProductVersion>
+  <Class Guid="68f4a651-b9cd-473b-a595-b00447132ffa">
+    <Instance Guid="00000000-0000-0000-0000-000000000000">
+      <FormatVersion>2.0</FormatVersion>
+      <FileVersion>4.2</FileVersion>
+      <ProjectGuid>ad88300a-1835-4edd-9d7a-ced9831fd7cf</ProjectGuid>
+      <ProjectItemGuid>dba4de3d-9630-48ea-8e19-e3b15f11075b</ProjectItemGuid>
+      <FileCategoryGuid>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</FileCategoryGuid>
+      <Property>fb98844b-2c27-4275-9804-f6e63e204da0</Property>
+      <ActiveProjectGuid>04dd15f3-a521-4091-8ca9-d183965ea77a</ActiveProjectGuid>
+    </Instance>
+    <Instance Guid="bbf392be-9376-4aba-bf45-bd3546fe324a">
+      <DependentProjectsGuidsSourceProjectsCount>0</DependentProjectsGuidsSourceProjectsCount>
+      <Type>Data</Type>
+    </Instance>
+    <Instance Guid="3224139c-b886-43ad-bca0-15066024d5c2">
+      <Name>fatfs</Name>
+      <Type>Category</Type>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>ea0c91ca-c0a2-4326-8d29-e191f9f14dde</Property>
+    </Instance>
+    <Instance Guid="bdc42ae3-d03d-43e3-9b75-95c94d70671e">
+      <Name>ecnl</Name>
+      <Type>Category</Type>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>cd904f63-ac3f-4aed-a383-ceef3a655b2e</Property>
+    </Instance>
+    <Instance Guid="a6e69da5-6a9c-4b29-beab-311d258c5bb9">
+      <Name>start.src</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\arch\rx630_ccrx\start.src</RelativePath>
+      <TreeImageGuid>f654126d-e7ad-426d-be34-8455271d959b</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>4f7dbe97-4222-4212-b2ae-e2debe443c76</Property>
+    </Instance>
+    <Instance Guid="75ed79e0-6ed0-4035-9691-328d6ff5dfa1">
+      <Name>banner.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\syssvc\banner.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>0287adb3-642f-449d-aace-8e3eff5f145c</Property>
+    </Instance>
+    <Instance Guid="ba73b40c-9528-4333-9dc1-a7ea8a90f98c">
+      <Name>logtask.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\syssvc\logtask.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>b05f08ed-e4d9-43a9-bc12-d6ba63636450</Property>
+    </Instance>
+    <Instance Guid="4ecc3644-1ccc-4566-9842-5f9212542f0c">
+      <Name>serial.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\syssvc\serial.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>f11db484-b3ad-4509-885b-d752730b65d9</Property>
+    </Instance>
+    <Instance Guid="1aef2559-762d-4094-9d4a-ca5deabc3734">
+      <Name>syslog.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\syssvc\syslog.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+    </Instance>
+    <Instance Guid="b20590e5-5bde-44da-aed4-9c2b60191d31">
+      <Name>log_output.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\library\log_output.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+    </Instance>
+    <Instance Guid="a45d8b6d-ce19-44bf-8c02-4d5d70e21532">
+      <Name>strerror.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\library\strerror.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+    </Instance>
+    <Instance Guid="85c7a3c6-84ec-41bc-9ce4-3701677a68dc">
+      <Name>vasyslog.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\asp_dcre\library\vasyslog.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+    </Instance>
+    <Instance Guid="e8a40594-66bb-4c27-bd03-af9184da00de">
+      <Name>main.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\src\usb_watt_meter\main.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>69485232-b41e-4452-85ff-31fb2332167a</Property>
+    </Instance>
+    <Instance Guid="7cde729a-32f8-4fca-8b33-09d98d30b3bb">
+      <Name>echonet_cfg.c</Name>
+      <Type>File</Type>
+      <RelativePath>echonet_cfg.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>7c0febd7-ebd6-49f7-a642-71fe22398814</Property>
+    </Instance>
+    <Instance Guid="7b86eb36-f2ac-4b0c-91b1-35e955c2885e">
+      <Name>kernel_cfg.c</Name>
+      <Type>File</Type>
+      <RelativePath>kernel_cfg.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>35d89aa9-7427-447e-96e7-f5da67af021e</Property>
+    </Instance>
+    <Instance Guid="d5d89bef-c974-4a49-b425-a6fa988ddab8">
+      <Name>kernel_cfg_asm.src</Name>
+      <Type>File</Type>
+      <RelativePath>kernel_cfg_asm.src</RelativePath>
+      <TreeImageGuid>f654126d-e7ad-426d-be34-8455271d959b</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>62c7ff1b-6013-48e4-b91a-841a9c7f754d</Property>
+    </Instance>
+    <Instance Guid="00c1f55e-c4e4-4973-8fe4-b9aa1c2a5ecc">
+      <Name>ether_phy.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\ports\grsakura\ether_phy.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>10e21a53-25de-4c49-acf7-d100b3d4826e</Property>
+    </Instance>
+    <Instance Guid="4540ea18-558c-4f77-bde1-c0b7c36e1935">
+      <Name>if_rx62n.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\ports\grsakura\if_rx62n.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>2af9394c-8cf4-49c9-9ab7-831f78eb0e80</Property>
+    </Instance>
+    <Instance Guid="e01bbf59-b19d-4092-9a90-9db3c5cd8215">
+      <Name>sntp.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\apps\sntp\sntp.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>eba4d127-d9d3-41c8-8e45-ca02cbaf8378</Property>
+    </Instance>
+    <Instance Guid="37b40277-9931-49ba-b46c-2437dc8a9616">
+      <Name>wolfssl_asp_dcre.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\lwip-1.4.1\ports\grsakura\wolfssl_asp_dcre.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>fc7bd1de-7367-4938-986e-27f3642a4726</Property>
+    </Instance>
+    <Instance Guid="0d86e5ab-2f37-412a-a8bf-cd4c865ef2d9">
+      <Name>client.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\src\usb_watt_meter\client.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>1b6f0080-9e35-4fe6-8e2a-f7a381d3a5ce</ParentItem>
+      <Property>a52da8f3-e57d-4374-b17c-c40d5b3e4804</Property>
+    </Instance>
+    <Instance Guid="73395af5-564a-47ee-a7be-3573d271e471">
+      <Name>mmc_rspi.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\fatfs\mmc_rspi.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>3224139c-b886-43ad-bca0-15066024d5c2</ParentItem>
+      <Property>77cae475-9857-4889-979a-8e7ee1bf46ee</Property>
+    </Instance>
+    <Instance Guid="9e563cbe-ae2a-4afd-b742-072c30f44930">
+      <Name>ff.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\fatfs\ff.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>3224139c-b886-43ad-bca0-15066024d5c2</ParentItem>
+    </Instance>
+    <Instance Guid="d616fb78-cb8e-45f3-a8f1-0e334d21ceb9">
+      <Name>ccsbcs.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\fatfs\option\ccsbcs.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>3224139c-b886-43ad-bca0-15066024d5c2</ParentItem>
+      <Property>efb6bd71-9213-420d-a642-3fbb4711da1b</Property>
+    </Instance>
+    <Instance Guid="7a65af48-b4ff-4352-b5f1-9bc7ab7f2b23">
+      <Name>echonet.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\ecnl_lwip\echonet.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>bdc42ae3-d03d-43e3-9b75-95c94d70671e</ParentItem>
+      <Property>ea632fc9-c5fb-4062-9e13-2f2d0cfec327</Property>
+    </Instance>
+    <Instance Guid="2f6b3d63-eaf1-4641-a3c7-031702646365">
+      <Name>echonet_agent.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\ecnl_lwip\echonet_agent.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>bdc42ae3-d03d-43e3-9b75-95c94d70671e</ParentItem>
+      <Property>f43770a3-d11d-42dd-9e1a-589c47286c67</Property>
+    </Instance>
+    <Instance Guid="814fae99-905c-4f06-91a8-4ca70f1fbddd">
+      <Name>echonet_dbg.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\ecnl_lwip\echonet_dbg.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>bdc42ae3-d03d-43e3-9b75-95c94d70671e</ParentItem>
+      <Property>55866a9e-6d76-4ce4-8fcd-2a24c102f0b9</Property>
+    </Instance>
+    <Instance Guid="51c7f00f-2ec9-4295-93fb-ef32dcbe66c1">
+      <Name>echonet_fbs.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\ecnl_lwip\echonet_fbs.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>bdc42ae3-d03d-43e3-9b75-95c94d70671e</ParentItem>
+      <Property>8a6d3346-ba55-43da-90ab-f02105c30346</Property>
+    </Instance>
+    <Instance Guid="8dea4e10-7304-48ef-a1e2-0e82092b8406">
+      <Name>echonet_task.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\ecnl_lwip\echonet_task.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>bdc42ae3-d03d-43e3-9b75-95c94d70671e</ParentItem>
+      <Property>3378768d-77a1-4988-934b-85d745436d45</Property>
+    </Instance>
+    <Instance Guid="795c9018-08d8-489b-8fc0-9bde7a85ce6f">
+      <Name>echonet_udp_task.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\ecnl_lwip\echonet_udp_task.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>bdc42ae3-d03d-43e3-9b75-95c94d70671e</ParentItem>
+      <Property>43a6b8a0-f69a-428f-9f11-adae44103903</Property>
+    </Instance>
+    <Instance Guid="13c5046e-040e-4102-9301-6aee6c37c0b2">
+      <Name>fbs_string.c</Name>
+      <Type>File</Type>
+      <RelativePath>..\..\ecnl_lwip\fbs_string.c</RelativePath>
+      <TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
+      <ParentItem>bdc42ae3-d03d-43e3-9b75-95c94d70671e</ParentItem>
+      <Property>6002dcab-d7bd-4693-a7df-0c52b1e4a832</Property>
+    </Instance>
+  </Class>
+  <Class Guid="9033e9fb-2b12-4437-a25e-27b28d42582b">
+    <Instance Guid="04dd15f3-a521-4091-8ca9-d183965ea77a">
+      <Name>cfg</Name>
+      <RelativePath>cfg\cfg.mtsp</RelativePath>
+    </Instance>
+  </Class>
+  <Class Guid="fb98844b-2c27-4275-9804-f6e63e204da0">
+    <Instance Guid="fb98844b-2c27-4275-9804-f6e63e204da0">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="0d548289-d5e9-4893-9a8f-9374b13f19a9">
+    <Instance Guid="4f7dbe97-4222-4212-b2ae-e2debe443c76">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="0287adb3-642f-449d-aace-8e3eff5f145c">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="b05f08ed-e4d9-43a9-bc12-d6ba63636450">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="f11db484-b3ad-4509-885b-d752730b65d9">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="69485232-b41e-4452-85ff-31fb2332167a">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="7c0febd7-ebd6-49f7-a642-71fe22398814">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="35d89aa9-7427-447e-96e7-f5da67af021e">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="62c7ff1b-6013-48e4-b91a-841a9c7f754d">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="10e21a53-25de-4c49-acf7-d100b3d4826e">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="2af9394c-8cf4-49c9-9ab7-831f78eb0e80">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="eba4d127-d9d3-41c8-8e45-ca02cbaf8378">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="fc7bd1de-7367-4938-986e-27f3642a4726">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="a52da8f3-e57d-4374-b17c-c40d5b3e4804">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="77cae475-9857-4889-979a-8e7ee1bf46ee">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="efb6bd71-9213-420d-a642-3fbb4711da1b">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="ea632fc9-c5fb-4062-9e13-2f2d0cfec327">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="f43770a3-d11d-42dd-9e1a-589c47286c67">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="55866a9e-6d76-4ce4-8fcd-2a24c102f0b9">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="8a6d3346-ba55-43da-90ab-f02105c30346">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="3378768d-77a1-4988-934b-85d745436d45">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="43a6b8a0-f69a-428f-9f11-adae44103903">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="6002dcab-d7bd-4693-a7df-0c52b1e4a832">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="78a5c5cd-76cb-4bcc-a031-3020011fbc9a">
+    <Instance Guid="ea0c91ca-c0a2-4326-8d29-e191f9f14dde">
+      <MemoCount>0</MemoCount>
+    </Instance>
+    <Instance Guid="cd904f63-ac3f-4aed-a383-ceef3a655b2e">
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="8fb9c1f6-d351-4d10-8d99-bf5b3015b84c">
+    <Instance Guid="00000000-0000-0000-0000-000000000000">
+      <UsingPlatformGuid>500ba51a-4219-4828-b4be-80f54d6d3551</UsingPlatformGuid>
+      <UsingPlatformTypeGuid>f96683fa-8de4-4c6d-a1ab-925d7f232c09</UsingPlatformTypeGuid>
+    </Instance>
+  </Class>
+  <Class Guid="c325714f-8f51-484b-9e96-b4b59c0fb263">
+    <Instance Guid="c325714f-8f51-484b-9e96-b4b59c0fb263">
+      <DeviceManager>0e793ff3-2e3f-43c0-bdc9-926269595403</DeviceManager>
+    </Instance>
+  </Class>
+  <Class Guid="0e793ff3-2e3f-43c0-bdc9-926269595403">
+    <Instance Guid="0e793ff3-2e3f-43c0-bdc9-926269595403">
+      <DataFormatVersion>1.0</DataFormatVersion>
+    </Instance>
+    <Instance Guid="2a81c37a-5015-44c2-9f40-e58b669eec75">
+      <DeviceName>R5F563NBDxFP</DeviceName>
+      <MemoCount>0</MemoCount>
+    </Instance>
+  </Class>
+  <Class Guid="873c9a58-9bc5-439a-b476-78629a4553ed">
+    <Instance Guid="873c9a58-9bc5-439a-b476-78629a4553ed">
+      <ProjectDeviceChangedCounter>0</ProjectDeviceChangedCounter>
+      <ProjectInitialDeviceName>R5F563NBDxFP</ProjectInitialDeviceName>
+    </Instance>
+  </Class>
+  <Class Guid="c3835e31-dea3-4c93-b02b-d2db997f7630">
+    <Instance Guid="c3835e31-dea3-4c93-b02b-d2db997f7630">
+      <BuildToolManager>3a79707d-5977-45f7-ac11-19c35e333132</BuildToolManager>
+    </Instance>
+  </Class>
+  <Class Guid="3a79707d-5977-45f7-ac11-19c35e333132">
+    <Instance Guid="3a79707d-5977-45f7-ac11-19c35e333132">
+      <DataFormatVersion>1.2</DataFormatVersion>
+      <BuildModeCount>1</BuildModeCount>
+      <BuildMode0>RABlAGYAYQB1AGwAdABCAHUAaQBsAGQA</BuildMode0>
+      <BatchBuildFlag0>False</BatchBuildFlag0>
+      <CurrentBuildMode>DefaultBuild</CurrentBuildMode>
+      <SourceItemGuid0>a6e69da5-6a9c-4b29-beab-311d258c5bb9</SourceItemGuid0>
+      <SourceItemType0>AsmSource</SourceItemType0>
+      <SourceItemGuid1>75ed79e0-6ed0-4035-9691-328d6ff5dfa1</SourceItemGuid1>
+      <SourceItemType1>CSource</SourceItemType1>
+      <SourceItemGuid2>ba73b40c-9528-4333-9dc1-a7ea8a90f98c</SourceItemGuid2>
+      <SourceItemType2>CSource</SourceItemType2>
+      <SourceItemGuid3>4ecc3644-1ccc-4566-9842-5f9212542f0c</SourceItemGuid3>
+      <SourceItemType3>CSource</SourceItemType3>
+      <SourceItemGuid4>1aef2559-762d-4094-9d4a-ca5deabc3734</SourceItemGuid4>
+      <SourceItemType4>CSource</SourceItemType4>
+      <SourceItemGuid5>b20590e5-5bde-44da-aed4-9c2b60191d31</SourceItemGuid5>
+      <SourceItemType5>CSource</SourceItemType5>
+      <SourceItemGuid6>a45d8b6d-ce19-44bf-8c02-4d5d70e21532</SourceItemGuid6>
+      <SourceItemType6>CSource</SourceItemType6>
+      <SourceItemGuid7>85c7a3c6-84ec-41bc-9ce4-3701677a68dc</SourceItemGuid7>
+      <SourceItemType7>CSource</SourceItemType7>
+      <SourceItemGuid8>e8a40594-66bb-4c27-bd03-af9184da00de</SourceItemGuid8>
+      <SourceItemType8>CSource</SourceItemType8>
+      <SourceItemGuid9>7cde729a-32f8-4fca-8b33-09d98d30b3bb</SourceItemGuid9>
+      <SourceItemType9>CSource</SourceItemType9>
+      <SourceItemGuid10>7b86eb36-f2ac-4b0c-91b1-35e955c2885e</SourceItemGuid10>
+      <SourceItemType10>CSource</SourceItemType10>
+      <SourceItemGuid11>d5d89bef-c974-4a49-b425-a6fa988ddab8</SourceItemGuid11>
+      <SourceItemType11>AsmSource</SourceItemType11>
+      <SourceItemGuid12>00c1f55e-c4e4-4973-8fe4-b9aa1c2a5ecc</SourceItemGuid12>
+      <SourceItemType12>CSource</SourceItemType12>
+      <SourceItemGuid13>4540ea18-558c-4f77-bde1-c0b7c36e1935</SourceItemGuid13>
+      <SourceItemType13>CSource</SourceItemType13>
+      <SourceItemGuid14>e01bbf59-b19d-4092-9a90-9db3c5cd8215</SourceItemGuid14>
+      <SourceItemType14>CSource</SourceItemType14>
+      <SourceItemGuid15>37b40277-9931-49ba-b46c-2437dc8a9616</SourceItemGuid15>
+      <SourceItemType15>CSource</SourceItemType15>
+      <SourceItemGuid16>0d86e5ab-2f37-412a-a8bf-cd4c865ef2d9</SourceItemGuid16>
+      <SourceItemType16>CSource</SourceItemType16>
+      <SourceItemGuid17>73395af5-564a-47ee-a7be-3573d271e471</SourceItemGuid17>
+      <SourceItemType17>CSource</SourceItemType17>
+      <SourceItemGuid18>9e563cbe-ae2a-4afd-b742-072c30f44930</SourceItemGuid18>
+      <SourceItemType18>CSource</SourceItemType18>
+      <SourceItemGuid19>d616fb78-cb8e-45f3-a8f1-0e334d21ceb9</SourceItemGuid19>
+      <SourceItemType19>CSource</SourceItemType19>
+      <SourceItemGuid20>7a65af48-b4ff-4352-b5f1-9bc7ab7f2b23</SourceItemGuid20>
+      <SourceItemType20>CSource</SourceItemType20>
+      <SourceItemGuid21>2f6b3d63-eaf1-4641-a3c7-031702646365</SourceItemGuid21>
+      <SourceItemType21>CSource</SourceItemType21>
+      <SourceItemGuid22>814fae99-905c-4f06-91a8-4ca70f1fbddd</SourceItemGuid22>
+      <SourceItemType22>CSource</SourceItemType22>
+      <SourceItemGuid23>51c7f00f-2ec9-4295-93fb-ef32dcbe66c1</SourceItemGuid23>
+      <SourceItemType23>CSource</SourceItemType23>
+      <SourceItemGuid24>8dea4e10-7304-48ef-a1e2-0e82092b8406</SourceItemGuid24>
+      <SourceItemType24>CSource</SourceItemType24>
+      <SourceItemGuid25>795c9018-08d8-489b-8fc0-9bde7a85ce6f</SourceItemGuid25>
+      <SourceItemType25>CSource</SourceItemType25>
+      <SourceItemGuid26>13c5046e-040e-4102-9301-6aee6c37c0b2</SourceItemGuid26>
+      <SourceItemType26>CSource</SourceItemType26>
+      <SourceItemCount>27</SourceItemCount>
+      <LastDeviceChangedCounter>0</LastDeviceChangedCounter>
+    </Instance>
+    <Instance Guid="9e208646-ccba-4100-a676-29b1efe6545f">
+      <AsmOptionInclude-DefaultValue />
+      <BuildMode-DefaultValue>DefaultBuild</BuildMode-DefaultValue>
+      <COptionInclude-DefaultValue />
+      <GeneralOptionIsa-DefaultValue>RXv1</GeneralOptionIsa-DefaultValue>
+      <GeneralOptionOutput-DefaultValue>LoadModuleFile</GeneralOptionOutput-DefaultValue>
+      <GeneralOptionPic-DefaultValue>False</GeneralOptionPic-DefaultValue>
+      <GeneralOptionSimultaneousBuild-DefaultValue>True</GeneralOptionSimultaneousBuild-DefaultValue>
+      <HexOptionOutput-DefaultValue>True</HexOptionOutput-DefaultValue>
+      <LibOptionDebug-DefaultValue>Debug</LibOptionDebug-DefaultValue>
+      <LinkOptionLibrary-DefaultValue />
+      <Memo-DefaultValue />
+      <OutputMessageFormat-DefaultValue>%TargetFiles%</OutputMessageFormat-DefaultValue>
+      <AsmOptionSystemInclude-DefaultValue />
+      <COptionSystemInclude-DefaultValue />
+      <CompilerVersion-DefaultValue>
+
+0</CompilerVersion-DefaultValue>
+      <DependencyFileExistCheckingType-DefaultValue>Rebuild</DependencyFileExistCheckingType-DefaultValue>
+      <FormatBuildOptionList-DefaultValue>%TargetFiles% : %Program% %Options%</FormatBuildOptionList-DefaultValue>
+      <GeneralOptionCpu-DefaultValue>RX600</GeneralOptionCpu-DefaultValue>
+      <GeneralOptionOutputFolder-DefaultValue>%BuildModeName%</GeneralOptionOutputFolder-DefaultValue>
+      <GeneralOptionPid-DefaultValue>None</GeneralOptionPid-DefaultValue>
+      <HexOptionForm-DefaultValue>Stype</HexOptionForm-DefaultValue>
+      <LinkOptionDebug-DefaultValue>Debug</LinkOptionDebug-DefaultValue>
+      <AsmOptionDefine-DefaultValue />
+      <COptionDefine-DefaultValue />
+      <EnsureCompatibilityOfPathAndLinkageOrder-DefaultValue>False</EnsureCompatibilityOfPathAndLinkageOrder-DefaultValue>
+      <GeneralOptionFpu-DefaultValue>Fpu</GeneralOptionFpu-DefaultValue>
+      <GeneralOptionNousePidRegister-DefaultValue>True</GeneralOptionNousePidRegister-DefaultValue>
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionOptimize-DefaultValue>None</LinkOptionOptimize-DefaultValue>
+      <AsmOptionDebug-DefaultValue>True</AsmOptionDebug-DefaultValue>
+      <COptionDebug-DefaultValue>True</COptionDebug-DefaultValue>
+      <GeneralOptionEndian-DefaultValue>Little</GeneralOptionEndian-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionOptimizeSymbolDelete-DefaultValue>False</LinkOptionOptimizeSymbolDelete-DefaultValue>
+      <PreBuildCommands-DefaultValue />
+      <AsmOptionGoptimize-DefaultValue>False</AsmOptionGoptimize-DefaultValue>
+      <COptionOptimize-DefaultValue>Level2</COptionOptimize-DefaultValue>
+      <GeneralOptionRound-DefaultValue>Nearest</GeneralOptionRound-DefaultValue>
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionOptimizeSameCode-DefaultValue>False</LinkOptionOptimizeSameCode-DefaultValue>
+      <PostBuildCommands-DefaultValue />
+      <AsmOptionListFile-DefaultValue>False</AsmOptionListFile-DefaultValue>
+      <COptionGoptimize-DefaultValue>False</COptionGoptimize-DefaultValue>
+      <GeneralOptionDenormalize-DefaultValue>Off</GeneralOptionDenormalize-DefaultValue>
+      <LinkOptionSameSize-DefaultValue>1E</LinkOptionSameSize-DefaultValue>
+      <AsmOptionShowConditionals-DefaultValue>False</AsmOptionShowConditionals-DefaultValue>
+      <COptionSpeedAndSize-DefaultValue>Size</COptionSpeedAndSize-DefaultValue>
+      <GeneralOptionDblSize-DefaultValue>SinglePrecision</GeneralOptionDblSize-DefaultValue>
+      <LinkOptionOptimizeShortFormat-DefaultValue>False</LinkOptionOptimizeShortFormat-DefaultValue>
+      <AsmOptionShowDefinitions-DefaultValue>False</AsmOptionShowDefinitions-DefaultValue>
+      <COptionListfile-DefaultValue>False</COptionListfile-DefaultValue>
+      <GeneralOptionIntToShort-DefaultValue>False</GeneralOptionIntToShort-DefaultValue>
+      <LinkOptionOptimizeBranch-DefaultValue>False</LinkOptionOptimizeBranch-DefaultValue>
+      <AsmOptionShowExpansions-DefaultValue>False</AsmOptionShowExpansions-DefaultValue>
+      <COptionShowSource-DefaultValue>False</COptionShowSource-DefaultValue>
+      <GeneralOptionSignedChar-DefaultValue>Unsigned</GeneralOptionSignedChar-DefaultValue>
+      <LinkOptionStart-DefaultValue>B_1,R_1,B_2,R_2,B,R,SU,SI/04,PResetPRG/0FFFF8000,C_1,C_2,C,C$DSEC,C$BSEC,C$INIT,C$VTBL,C$VECT,D_1,D_2,D,P,PIntPRG,W_1,W_2,W,L/0FFFF8100,FIXEDVECT/0FFFFFFD0</LinkOptionStart-DefaultValue>
+      <COptionShowConditionals-DefaultValue>False</COptionShowConditionals-DefaultValue>
+      <GeneralOptionOtherAdditionalOptions-DefaultValue />
+      <GeneralOptionSignedBitfield-DefaultValue>Unsigned</GeneralOptionSignedBitfield-DefaultValue>
+      <COptionShowDefinitions-DefaultValue>False</COptionShowDefinitions-DefaultValue>
+      <GeneralOptionAutoEnum-DefaultValue>False</GeneralOptionAutoEnum-DefaultValue>
+      <COptionShowExpansions-DefaultValue>False</COptionShowExpansions-DefaultValue>
+      <GeneralOptionBitOrder-DefaultValue>Right</GeneralOptionBitOrder-DefaultValue>
+      <GeneralOptionPack-DefaultValue>False</GeneralOptionPack-DefaultValue>
+      <GeneralOptionException-DefaultValue>False</GeneralOptionException-DefaultValue>
+      <GeneralOptionRtti-DefaultValue>False</GeneralOptionRtti-DefaultValue>
+      <GeneralOptionFintRegister-DefaultValue>None</GeneralOptionFintRegister-DefaultValue>
+      <GeneralOptionBranch-DefaultValue>Branch24</GeneralOptionBranch-DefaultValue>
+      <GeneralOptionBaseRomRegister-DefaultValue>None</GeneralOptionBaseRomRegister-DefaultValue>
+      <GeneralOptionBaseRamRegister-DefaultValue>None</GeneralOptionBaseRamRegister-DefaultValue>
+      <GeneralOptionBaseAddressAddress-DefaultValue>00000000</GeneralOptionBaseAddressAddress-DefaultValue>
+      <GeneralOptionBaseAddressRegister-DefaultValue>None</GeneralOptionBaseAddressRegister-DefaultValue>
+      <GeneralOptionPatch-DefaultValue>None</GeneralOptionPatch-DefaultValue>
+      <GeneralOptionSaveAcc-DefaultValue>False</GeneralOptionSaveAcc-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587442584791015989</TimeTagModified--0>
+      <BuildMode-0>DefaultBuild</BuildMode-0>
+      <Memo-0 />
+      <OutputMessageFormat-0>%TargetFiles%</OutputMessageFormat-0>
+      <FormatBuildOptionList-0>%TargetFiles% : %Program% %Options%</FormatBuildOptionList-0>
+      <PreBuildCommands-0 />
+      <PostBuildCommands-0 />
+      <GeneralOptionIsa-0>RXv1</GeneralOptionIsa-0>
+      <GeneralOptionOutput-0>LoadModuleFile</GeneralOptionOutput-0>
+      <GeneralOptionPic-0>False</GeneralOptionPic-0>
+      <GeneralOptionSimultaneousBuild-0>True</GeneralOptionSimultaneousBuild-0>
+      <CompilerVersion-0>
+
+0</CompilerVersion-0>
+      <DependencyFileExistCheckingType-0>Rebuild</DependencyFileExistCheckingType-0>
+      <GeneralOptionCpu-0>RX600</GeneralOptionCpu-0>
+      <GeneralOptionOutputFolder-0>%BuildModeName%</GeneralOptionOutputFolder-0>
+      <GeneralOptionPid-0>None</GeneralOptionPid-0>
+      <EnsureCompatibilityOfPathAndLinkageOrder-0>False</EnsureCompatibilityOfPathAndLinkageOrder-0>
+      <GeneralOptionFpu-0>Fpu</GeneralOptionFpu-0>
+      <GeneralOptionNousePidRegister-0>True</GeneralOptionNousePidRegister-0>
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <GeneralOptionEndian-0>Little</GeneralOptionEndian-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <AsmOptionGoptimize-0>False</AsmOptionGoptimize-0>
+      <GeneralOptionRound-0>Nearest</GeneralOptionRound-0>
+      <LinkOptionMultiConvertFileName-0 />
+      <AsmOptionListFile-0>False</AsmOptionListFile-0>
+      <COptionGoptimize-0>False</COptionGoptimize-0>
+      <GeneralOptionDenormalize-0>Off</GeneralOptionDenormalize-0>
+      <AsmOptionShowConditionals-0>False</AsmOptionShowConditionals-0>
+      <GeneralOptionDblSize-0>SinglePrecision</GeneralOptionDblSize-0>
+      <AsmOptionShowDefinitions-0>False</AsmOptionShowDefinitions-0>
+      <COptionListfile-0>False</COptionListfile-0>
+      <GeneralOptionIntToShort-0>False</GeneralOptionIntToShort-0>
+      <AsmOptionShowExpansions-0>False</AsmOptionShowExpansions-0>
+      <COptionShowSource-0>False</COptionShowSource-0>
+      <GeneralOptionSignedChar-0>Unsigned</GeneralOptionSignedChar-0>
+      <COptionShowConditionals-0>False</COptionShowConditionals-0>
+      <GeneralOptionOtherAdditionalOptions-0 />
+      <GeneralOptionSignedBitfield-0>Unsigned</GeneralOptionSignedBitfield-0>
+      <COptionShowDefinitions-0>False</COptionShowDefinitions-0>
+      <GeneralOptionAutoEnum-0>False</GeneralOptionAutoEnum-0>
+      <COptionShowExpansions-0>False</COptionShowExpansions-0>
+      <GeneralOptionBitOrder-0>Right</GeneralOptionBitOrder-0>
+      <GeneralOptionPack-0>False</GeneralOptionPack-0>
+      <GeneralOptionException-0>False</GeneralOptionException-0>
+      <GeneralOptionRtti-0>False</GeneralOptionRtti-0>
+      <GeneralOptionFintRegister-0>None</GeneralOptionFintRegister-0>
+      <GeneralOptionBranch-0>Branch24</GeneralOptionBranch-0>
+      <GeneralOptionBaseRomRegister-0>None</GeneralOptionBaseRomRegister-0>
+      <GeneralOptionBaseRamRegister-0>None</GeneralOptionBaseRamRegister-0>
+      <GeneralOptionBaseAddressAddress-0>00000000</GeneralOptionBaseAddressAddress-0>
+      <GeneralOptionBaseAddressRegister-0>None</GeneralOptionBaseAddressRegister-0>
+      <GeneralOptionPatch-0>None</GeneralOptionPatch-0>
+      <GeneralOptionSaveAcc-0>False</GeneralOptionSaveAcc-0>
+      <LastCompilerVersion-0>V2.02.00</LastCompilerVersion-0>
+    </Instance>
+    <Instance Guid="95a63257-4aa7-40c0-a74a-7991543b099b">
+      <COptionLangC-DefaultValue>C</COptionLangC-DefaultValue>
+      <COptionListfile-DefaultValue>False</COptionListfile-DefaultValue>
+      <COptionLogo-DefaultValue>False</COptionLogo-DefaultValue>
+      <COptionMisra2004-DefaultValue>None</COptionMisra2004-DefaultValue>
+      <COptionOptimize-DefaultValue>Level2</COptionOptimize-DefaultValue>
+      <COptionOutput-DefaultValue>Object</COptionOutput-DefaultValue>
+      <COptionOutputAssembly-DefaultValue>False</COptionOutputAssembly-DefaultValue>
+      <COptionGoptimize-DefaultValue>False</COptionGoptimize-DefaultValue>
+      <COptionLangCpp-DefaultValue>Cpp</COptionLangCpp-DefaultValue>
+      <COptionMisra2004RuleFile-DefaultValue />
+      <COptionOutputFolder-DefaultValue>%BuildModeName%</COptionOutputFolder-DefaultValue>
+      <COptionOutputPreprocessed-DefaultValue>None</COptionOutputPreprocessed-DefaultValue>
+      <COptionShowSource-DefaultValue>False</COptionShowSource-DefaultValue>
+      <COptionXcref-DefaultValue>False</COptionXcref-DefaultValue>
+      <COptionDebug-DefaultValue>True</COptionDebug-DefaultValue>
+      <COptionInclude-DefaultValue />
+      <COptionMisra2004RuleNumberApply-DefaultValue />
+      <COptionPreCompileCommands-DefaultValue />
+      <COptionShowConditionals-DefaultValue>False</COptionShowConditionals-DefaultValue>
+      <COptionSpeedAndSize-DefaultValue>Size</COptionSpeedAndSize-DefaultValue>
+      <COptionLoop-DefaultValue>Auto</COptionLoop-DefaultValue>
+      <COptionMisra2004RuleNumberIgnore-DefaultValue />
+      <COptionPostCompileCommands-DefaultValue />
+      <COptionSectionP-DefaultValue>P</COptionSectionP-DefaultValue>
+      <COptionShowDefinitions-DefaultValue>False</COptionShowDefinitions-DefaultValue>
+      <COptionSystemInclude-DefaultValue />
+      <COptionLoopValue-DefaultValue>2</COptionLoopValue-DefaultValue>
+      <COptionMisra2004RuleNumberRequiredAdd-DefaultValue />
+      <COptionOtherAdditionalOptions-DefaultValue />
+      <COptionPreinclude-DefaultValue />
+      <COptionSectionC-DefaultValue>C</COptionSectionC-DefaultValue>
+      <COptionShowExpansions-DefaultValue>False</COptionShowExpansions-DefaultValue>
+      <COptionCommandLine-DefaultValue>-isa=rxv1
+-fpu
+-include=..\..\asp_dcre
+-include=..\..\asp_dcre\arch
+-include=..\..\asp_dcre\include
+-include=..\..\asp_dcre\pdic
+-include=..\..\asp_dcre\target\grsakura_ccrx
+-include=..\..\ecnl_lwip
+-include=..\..\fatfs
+-include=..\..\lwip-1.4.1\src\include
+-include=..\..\lwip-1.4.1\src\include\ipv4
+-include=..\..\lwip-1.4.1\ports\asp_dcre
+-include=..\..\lwip-1.4.1\ports\ccrx
+-include=..\..\lwip-1.4.1\ports\grsakura
+-include=..\..\lwip-1.4.1\apps
+-include=..\..\wolfssl-3.7.0
+-include=..\..\wolfssl-3.7.0\wolfssl
+-include=..\..\curl-7.47.1\include
+-include=..\..\curl-7.47.1
+-include=..\libcurl
+-include=..\..\src\usb_watt_meter
+-include=.
+-define=TARGET_KERNEL_ASP,SUPPORT_ETHER,SUPPORT_INET4,SUPPORT_UDP,WOLFSSL_RIPEMD,WOLFSSL_SHA512,SIZEOF_LONG_LONG=8,HAVE_CONFIG_H
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</COptionCommandLine-DefaultValue>
+      <COptionDefine-DefaultValue />
+      <COptionInline-DefaultValue>Auto</COptionInline-DefaultValue>
+      <COptionMisra2004RuleNumberRequiredRemove-DefaultValue />
+      <COptionSectionD-DefaultValue>D</COptionSectionD-DefaultValue>
+      <COptionIgnoreFilesMisra-DefaultValue />
+      <COptionInlineValue-DefaultValue>100</COptionInlineValue-DefaultValue>
+      <COptionSectionB-DefaultValue>B</COptionSectionB-DefaultValue>
+      <COptionUndefine-DefaultValue />
+      <COptionCheckLanguageExtension-DefaultValue>False</COptionCheckLanguageExtension-DefaultValue>
+      <COptionFileInline-DefaultValue />
+      <COptionMessage-DefaultValue>False</COptionMessage-DefaultValue>
+      <COptionSectionL-DefaultValue>L</COptionSectionL-DefaultValue>
+      <COptionCase-DefaultValue>Auto</COptionCase-DefaultValue>
+      <COptionMessage2-DefaultValue>False</COptionMessage2-DefaultValue>
+      <COptionSectionW-DefaultValue>W</COptionSectionW-DefaultValue>
+      <COptionNoMessageErrorNumber-DefaultValue />
+      <COptionNostuffB-DefaultValue>False</COptionNostuffB-DefaultValue>
+      <COptionVolatile-DefaultValue>False</COptionVolatile-DefaultValue>
+      <COptionConstCopy-DefaultValue>Auto</COptionConstCopy-DefaultValue>
+      <COptionNoMessageErrorNumber2-DefaultValue />
+      <COptionNostuffD-DefaultValue>False</COptionNostuffD-DefaultValue>
+      <COptionChangeMessageInformation-DefaultValue>No</COptionChangeMessageInformation-DefaultValue>
+      <COptionConstDiv-DefaultValue>Auto</COptionConstDiv-DefaultValue>
+      <COptionNostuffC-DefaultValue>False</COptionNostuffC-DefaultValue>
+      <COptionChangeMessageInformationNumber-DefaultValue />
+      <COptionLibrary-DefaultValue>Intrinsic</COptionLibrary-DefaultValue>
+      <COptionNostuffW-DefaultValue>False</COptionNostuffW-DefaultValue>
+      <COptionChangeMessageInformationNumber2-DefaultValue />
+      <COptionInstalign-DefaultValue>Noinstalign</COptionInstalign-DefaultValue>
+      <COptionScope-DefaultValue>Auto</COptionScope-DefaultValue>
+      <COptionChangeMessageWarning-DefaultValue>No</COptionChangeMessageWarning-DefaultValue>
+      <COptionNouseDiv-DefaultValue>True</COptionNouseDiv-DefaultValue>
+      <COptionSchedule-DefaultValue>Auto</COptionSchedule-DefaultValue>
+      <COptionChangeMessageWarningNumber-DefaultValue />
+      <COptionMap-DefaultValue>NoMap</COptionMap-DefaultValue>
+      <COptionOutcode-DefaultValue>Sjis</COptionOutcode-DefaultValue>
+      <COptionChangeMessageWarningNumber2-DefaultValue />
+      <COptionIntermodule-DefaultValue>None</COptionIntermodule-DefaultValue>
+      <COptionApproxdiv-DefaultValue>False</COptionApproxdiv-DefaultValue>
+      <COptionChangeMessageError-DefaultValue>No</COptionChangeMessageError-DefaultValue>
+      <COptionChangeMessageErrorNumber-DefaultValue />
+      <COptionEnableRegister-DefaultValue>False</COptionEnableRegister-DefaultValue>
+      <COptionChangeMessageErrorNumber2-DefaultValue />
+      <COptionSimpleFloatConv-DefaultValue>False</COptionSimpleFloatConv-DefaultValue>
+      <COptionFileInlinePath-DefaultValue />
+      <COptionFpu-DefaultValue>Fpu</COptionFpu-DefaultValue>
+      <COptionAlias-DefaultValue>False</COptionAlias-DefaultValue>
+      <COptionComment-DefaultValue>False</COptionComment-DefaultValue>
+      <COptionCheck-DefaultValue>No</COptionCheck-DefaultValue>
+      <COptionFloatOrder-DefaultValue>False</COptionFloatOrder-DefaultValue>
+      <COptionIncode-DefaultValue>Sjis</COptionIncode-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587457390276275853</TimeTagModified--0>
+      <COptionLangC-0>C99</COptionLangC-0>
+      <COptionListfile-0>False</COptionListfile-0>
+      <COptionLogo-0>False</COptionLogo-0>
+      <COptionMisra2004-0>None</COptionMisra2004-0>
+      <COptionOptimize-0>Level2</COptionOptimize-0>
+      <COptionOutput-0>Object</COptionOutput-0>
+      <COptionOutputAssembly-0>False</COptionOutputAssembly-0>
+      <COptionGoptimize-0>False</COptionGoptimize-0>
+      <COptionLangCpp-0>Cpp</COptionLangCpp-0>
+      <COptionMisra2004RuleFile-0 />
+      <COptionOutputFolder-0>%BuildModeName%</COptionOutputFolder-0>
+      <COptionOutputPreprocessed-0>None</COptionOutputPreprocessed-0>
+      <COptionShowSource-0>False</COptionShowSource-0>
+      <COptionXcref-0>False</COptionXcref-0>
+      <COptionDebug-0>True</COptionDebug-0>
+      <COptionInclude-0>..\..\asp_dcre
+..\..\asp_dcre\arch
+..\..\asp_dcre\include
+..\..\asp_dcre\pdic
+..\..\asp_dcre\target\grsakura_ccrx
+..\..\ecnl_lwip
+..\..\fatfs
+..\..\lwip-1.4.1\src\include
+..\..\lwip-1.4.1\src\include\ipv4
+..\..\lwip-1.4.1\ports\asp_dcre
+..\..\lwip-1.4.1\ports\ccrx
+..\..\lwip-1.4.1\ports\grsakura
+..\..\lwip-1.4.1\apps
+..\..\wolfssl-3.7.0
+..\..\wolfssl-3.7.0\wolfssl
+..\..\curl-7.47.1\include
+..\..\curl-7.47.1
+..\libcurl
+..\..\src\usb_watt_meter
+.
+</COptionInclude-0>
+      <COptionMisra2004RuleNumberApply-0 />
+      <COptionPreCompileCommands-0 />
+      <COptionShowConditionals-0>False</COptionShowConditionals-0>
+      <COptionSpeedAndSize-0>Size</COptionSpeedAndSize-0>
+      <COptionLoop-0>Auto</COptionLoop-0>
+      <COptionMisra2004RuleNumberIgnore-0 />
+      <COptionPostCompileCommands-0 />
+      <COptionSectionP-0>P</COptionSectionP-0>
+      <COptionShowDefinitions-0>False</COptionShowDefinitions-0>
+      <COptionSystemInclude-0 />
+      <COptionLoopValue-0>2</COptionLoopValue-0>
+      <COptionMisra2004RuleNumberRequiredAdd-0 />
+      <COptionOtherAdditionalOptions-0 />
+      <COptionPreinclude-0 />
+      <COptionSectionC-0>C</COptionSectionC-0>
+      <COptionShowExpansions-0>False</COptionShowExpansions-0>
+      <COptionCommandLine-0>-isa=rxv1
+-fpu
+-include=..\..\asp_dcre
+-include=..\..\asp_dcre\arch
+-include=..\..\asp_dcre\include
+-include=..\..\asp_dcre\pdic
+-include=..\..\asp_dcre\target\grsakura_ccrx
+-include=..\..\ecnl_lwip
+-include=..\..\fatfs
+-include=..\..\lwip-1.4.1\src\include
+-include=..\..\lwip-1.4.1\src\include\ipv4
+-include=..\..\lwip-1.4.1\ports\asp_dcre
+-include=..\..\lwip-1.4.1\ports\ccrx
+-include=..\..\lwip-1.4.1\ports\grsakura
+-include=..\..\lwip-1.4.1\apps
+-include=..\..\wolfssl-3.7.0
+-include=..\..\wolfssl-3.7.0\wolfssl
+-include=..\..\curl-7.47.1\include
+-include=..\..\curl-7.47.1
+-include=..\libcurl
+-include=..\..\src\usb_watt_meter
+-include=.
+-define=TARGET_KERNEL_ASP,SUPPORT_ETHER,SUPPORT_INET4,SUPPORT_UDP,WOLFSSL_RIPEMD,WOLFSSL_SHA512,SIZEOF_LONG_LONG=8,HAVE_CONFIG_H
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</COptionCommandLine-0>
+      <COptionDefine-0>TARGET_KERNEL_ASP
+SUPPORT_ETHER
+SUPPORT_INET4
+SUPPORT_UDP
+WOLFSSL_RIPEMD
+WOLFSSL_SHA512
+SIZEOF_LONG_LONG=8
+HAVE_CONFIG_H
+</COptionDefine-0>
+      <COptionInline-0>Auto</COptionInline-0>
+      <COptionMisra2004RuleNumberRequiredRemove-0 />
+      <COptionSectionD-0>D</COptionSectionD-0>
+      <COptionIgnoreFilesMisra-0 />
+      <COptionInlineValue-0>100</COptionInlineValue-0>
+      <COptionSectionB-0>B</COptionSectionB-0>
+      <COptionUndefine-0 />
+      <COptionCheckLanguageExtension-0>False</COptionCheckLanguageExtension-0>
+      <COptionFileInline-0 />
+      <COptionMessage-0>False</COptionMessage-0>
+      <COptionSectionL-0>L</COptionSectionL-0>
+      <COptionCase-0>Auto</COptionCase-0>
+      <COptionSectionW-0>W</COptionSectionW-0>
+      <COptionNoMessageErrorNumber-0 />
+      <COptionNostuffB-0>False</COptionNostuffB-0>
+      <COptionVolatile-0>False</COptionVolatile-0>
+      <COptionConstCopy-0>Auto</COptionConstCopy-0>
+      <COptionNostuffD-0>False</COptionNostuffD-0>
+      <COptionChangeMessageInformation-0>No</COptionChangeMessageInformation-0>
+      <COptionConstDiv-0>Auto</COptionConstDiv-0>
+      <COptionNostuffC-0>False</COptionNostuffC-0>
+      <COptionChangeMessageInformationNumber-0 />
+      <COptionLibrary-0>Intrinsic</COptionLibrary-0>
+      <COptionNostuffW-0>False</COptionNostuffW-0>
+      <COptionInstalign-0>Noinstalign</COptionInstalign-0>
+      <COptionScope-0>Auto</COptionScope-0>
+      <COptionChangeMessageWarning-0>No</COptionChangeMessageWarning-0>
+      <COptionNouseDiv-0>True</COptionNouseDiv-0>
+      <COptionSchedule-0>Auto</COptionSchedule-0>
+      <COptionChangeMessageWarningNumber-0 />
+      <COptionMap-0>NoMap</COptionMap-0>
+      <COptionOutcode-0>Sjis</COptionOutcode-0>
+      <COptionIntermodule-0>None</COptionIntermodule-0>
+      <COptionApproxdiv-0>False</COptionApproxdiv-0>
+      <COptionChangeMessageError-0>No</COptionChangeMessageError-0>
+      <COptionChangeMessageErrorNumber-0 />
+      <COptionEnableRegister-0>False</COptionEnableRegister-0>
+      <COptionSimpleFloatConv-0>False</COptionSimpleFloatConv-0>
+      <COptionFileInlinePath-0 />
+      <COptionFpu-0>Fpu</COptionFpu-0>
+      <COptionAlias-0>False</COptionAlias-0>
+      <COptionComment-0>False</COptionComment-0>
+      <COptionCheck-0>No</COptionCheck-0>
+      <COptionFloatOrder-0>False</COptionFloatOrder-0>
+      <COptionIncode-0>Sjis</COptionIncode-0>
+    </Instance>
+    <Instance Guid="5ad1746c-d03e-4610-a91f-aaa4fb37bc10">
+      <AsmOptionChkpm-DefaultValue>False</AsmOptionChkpm-DefaultValue>
+      <AsmOptionGoptimize-DefaultValue>False</AsmOptionGoptimize-DefaultValue>
+      <AsmOptionInclude-DefaultValue />
+      <AsmOptionListFile-DefaultValue>False</AsmOptionListFile-DefaultValue>
+      <AsmOptionOutput-DefaultValue>%BuildModeName%</AsmOptionOutput-DefaultValue>
+      <AsmOptionChkfpu-DefaultValue>False</AsmOptionChkfpu-DefaultValue>
+      <AsmOptionDebug-DefaultValue>True</AsmOptionDebug-DefaultValue>
+      <AsmOptionShowConditionals-DefaultValue>False</AsmOptionShowConditionals-DefaultValue>
+      <AsmOptionSystemInclude-DefaultValue />
+      <AsmOptionChkdsp-DefaultValue>False</AsmOptionChkdsp-DefaultValue>
+      <AsmOptionDefine-DefaultValue />
+      <AsmOptionShowDefinitions-DefaultValue>False</AsmOptionShowDefinitions-DefaultValue>
+      <AsmOptionInCode-DefaultValue>SJIS</AsmOptionInCode-DefaultValue>
+      <AsmOptionLogo-DefaultValue>False</AsmOptionLogo-DefaultValue>
+      <AsmOptionShowExpansions-DefaultValue>False</AsmOptionShowExpansions-DefaultValue>
+      <AsmOptionPreAssembleCommands-DefaultValue />
+      <AsmOptionPostAssembleCommands-DefaultValue />
+      <AsmOptionOtherAdditionalOptions-DefaultValue />
+      <AsmOptionCommandLine-DefaultValue>-isa=rxv1
+-fpu
+-include=../../asp_dcre/target/grsakura_ccrx
+-include=.
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</AsmOptionCommandLine-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053500505650041</TimeTagModified--0>
+      <AsmOptionChkpm-0>False</AsmOptionChkpm-0>
+      <AsmOptionGoptimize-0>False</AsmOptionGoptimize-0>
+      <AsmOptionInclude-0>../../asp_dcre/target/grsakura_ccrx
+.
+</AsmOptionInclude-0>
+      <AsmOptionListFile-0>False</AsmOptionListFile-0>
+      <AsmOptionOutput-0>%BuildModeName%</AsmOptionOutput-0>
+      <AsmOptionChkfpu-0>False</AsmOptionChkfpu-0>
+      <AsmOptionDebug-0>True</AsmOptionDebug-0>
+      <AsmOptionShowConditionals-0>False</AsmOptionShowConditionals-0>
+      <AsmOptionSystemInclude-0 />
+      <AsmOptionChkdsp-0>False</AsmOptionChkdsp-0>
+      <AsmOptionDefine-0 />
+      <AsmOptionShowDefinitions-0>False</AsmOptionShowDefinitions-0>
+      <AsmOptionInCode-0>SJIS</AsmOptionInCode-0>
+      <AsmOptionLogo-0>False</AsmOptionLogo-0>
+      <AsmOptionShowExpansions-0>False</AsmOptionShowExpansions-0>
+      <AsmOptionPreAssembleCommands-0 />
+      <AsmOptionPostAssembleCommands-0 />
+      <AsmOptionOtherAdditionalOptions-0 />
+      <AsmOptionCommandLine-0>-isa=rxv1
+-fpu
+-include=../../asp_dcre/target/grsakura_ccrx
+-include=.
+-output=obj
+-obj_path=%BuildModeName%
+-debug
+-nologo
+</AsmOptionCommandLine-0>
+    </Instance>
+    <Instance Guid="dbb16727-3e81-4169-956a-790355cab4a1">
+      <LinkOptionCpu-DefaultValue>False</LinkOptionCpu-DefaultValue>
+      <LinkOptionForm-DefaultValue>Absolute</LinkOptionForm-DefaultValue>
+      <LinkOptionFormConvert-DefaultValue>Stype</LinkOptionFormConvert-DefaultValue>
+      <LinkOptionInput-DefaultValue />
+      <LinkOptionListShow-DefaultValue>List</LinkOptionListShow-DefaultValue>
+      <LinkOptionOptimize-DefaultValue>None</LinkOptionOptimize-DefaultValue>
+      <LinkOptionStack-DefaultValue>False</LinkOptionStack-DefaultValue>
+      <LinkOptionStart-DefaultValue>B_1,R_1,B_2,R_2,B,R,SU,SI/04,PResetPRG/0FFFF8000,C_1,C_2,C,C$DSEC,C$BSEC,C$INIT,C$VTBL,C$VECT,D_1,D_2,D,P,PIntPRG,W_1,W_2,W,L/0FFFF8100,FIXEDVECT/0FFFFFFD0</LinkOptionStart-DefaultValue>
+      <LinkOptionCompress-DefaultValue>False</LinkOptionCompress-DefaultValue>
+      <LinkOptionCpuInformation-DefaultValue />
+      <LinkOptionDebug-DefaultValue>Debug</LinkOptionDebug-DefaultValue>
+      <LinkOptionFSymbol-DefaultValue />
+      <LinkOptionLibrary-DefaultValue />
+      <LinkOptionOptimizeSymbolDelete-DefaultValue>False</LinkOptionOptimizeSymbolDelete-DefaultValue>
+      <LinkOptionRecordH-DefaultValue>None</LinkOptionRecordH-DefaultValue>
+      <LinkOptionShowSymbol-DefaultValue>False</LinkOptionShowSymbol-DefaultValue>
+      <LinkOptionAlignedSection-DefaultValue />
+      <LinkOptionCpuStride-DefaultValue>False</LinkOptionCpuStride-DefaultValue>
+      <LinkOptionMemory-DefaultValue>False</LinkOptionMemory-DefaultValue>
+      <LinkOptionOptimizeSameCode-DefaultValue>False</LinkOptionOptimizeSameCode-DefaultValue>
+      <LinkOptionOutputFolder-DefaultValue>%BuildModeName%</LinkOptionOutputFolder-DefaultValue>
+      <LinkOptionRecordS-DefaultValue>None</LinkOptionRecordS-DefaultValue>
+      <LinkOptionShowReference-DefaultValue>False</LinkOptionShowReference-DefaultValue>
+      <LinkOptionSystemLibrary-DefaultValue />
+      <LinkOptionBinary-DefaultValue />
+      <LinkOptionChangeMessageInformation-DefaultValue>None</LinkOptionChangeMessageInformation-DefaultValue>
+      <LinkOptionContiguousSection-DefaultValue />
+      <LinkOptionDividedConvertFile-DefaultValue>False</LinkOptionDividedConvertFile-DefaultValue>
+      <LinkOptionOutputFileName-DefaultValue>%ProjectName%.abs</LinkOptionOutputFileName-DefaultValue>
+      <LinkOptionRom-DefaultValue />
+      <LinkOptionSameSize-DefaultValue>1E</LinkOptionSameSize-DefaultValue>
+      <LinkOptionShowXreference-DefaultValue>False</LinkOptionShowXreference-DefaultValue>
+      <LinkOptionChangeMessageInformationNumber-DefaultValue />
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionDefine-DefaultValue />
+      <LinkOptionMap-DefaultValue>False</LinkOptionMap-DefaultValue>
+      <LinkOptionOptimizeShortFormat-DefaultValue>False</LinkOptionOptimizeShortFormat-DefaultValue>
+      <LinkOptionShowTotalSize-DefaultValue>False</LinkOptionShowTotalSize-DefaultValue>
+      <LinkOptionChangeMessageWarning-DefaultValue>None</LinkOptionChangeMessageWarning-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionEntry-DefaultValue>False</LinkOptionEntry-DefaultValue>
+      <LinkOptionMessage-DefaultValue>NoMessage</LinkOptionMessage-DefaultValue>
+      <LinkOptionOptimizeBranch-DefaultValue>False</LinkOptionOptimizeBranch-DefaultValue>
+      <LinkOptionShowVector-DefaultValue>False</LinkOptionShowVector-DefaultValue>
+      <LinkOptionChangeMessageWarningNumber-DefaultValue />
+      <LinkOptionEntryPoint-DefaultValue />
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionNoMessageErrorNumber-DefaultValue />
+      <LinkOptionSymbolForbid-DefaultValue />
+      <LinkOptionChangeMessageError-DefaultValue>None</LinkOptionChangeMessageError-DefaultValue>
+      <LinkOptionNoPrelink-DefaultValue>Auto</LinkOptionNoPrelink-DefaultValue>
+      <LinkOptionPadding-DefaultValue>False</LinkOptionPadding-DefaultValue>
+      <LinkOptionSameCodeForbid-DefaultValue />
+      <LinkOptionSpace-DefaultValue>None</LinkOptionSpace-DefaultValue>
+      <LinkOptionChangeMessageErrorNumber-DefaultValue />
+      <LinkOptionSectionForbid-DefaultValue />
+      <LinkOptionSpaceValue-DefaultValue>FF</LinkOptionSpaceValue-DefaultValue>
+      <LinkOptionVectN-DefaultValue />
+      <LinkOptionAbsoluteForbid-DefaultValue />
+      <LinkOptionByteCount-DefaultValue>False</LinkOptionByteCount-DefaultValue>
+      <LinkOptionHide-DefaultValue>False</LinkOptionHide-DefaultValue>
+      <LinkOptionVect-DefaultValue />
+      <LinkOptionByteCountValue-DefaultValue>FF</LinkOptionByteCountValue-DefaultValue>
+      <LinkOptionJumpEntriesForPic-DefaultValue>False</LinkOptionJumpEntriesForPic-DefaultValue>
+      <LinkOptionTotalSize-DefaultValue>False</LinkOptionTotalSize-DefaultValue>
+      <LinkOptionCrc-DefaultValue>None</LinkOptionCrc-DefaultValue>
+      <LinkOptionJumpEntriesForPicSectionName-DefaultValue />
+      <LinkOptionLogo-DefaultValue>False</LinkOptionLogo-DefaultValue>
+      <LinkOptionCrcOutputAddress-DefaultValue>0</LinkOptionCrcOutputAddress-DefaultValue>
+      <LinkOptionPreLinkCommands-DefaultValue />
+      <LinkOptionCrcCalculationRange-DefaultValue />
+      <LinkOptionPostLinkCommands-DefaultValue />
+      <LinkOptionOtherAdditionalOptionsForLoadModule-DefaultValue />
+      <LinkOptionS9-DefaultValue>False</LinkOptionS9-DefaultValue>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-DefaultValue />
+      <LinkOptionCommandLine-DefaultValue>-library=..\libasp\%BuildModeName%\libasp
+-library=..\liblwip\%BuildModeName%\liblwip
+-library=..\libwolfssl\%BuildModeName%\libwolfssl
+-library=..\libcurl\%BuildModeName%\libcurl
+-noprelink
+-output=%BuildModeName%\%ProjectName%.abs
+-list=%BuildModeName%\%ProjectName%.map
+-show=symbol,xreference,total_size
+-nooptimize
+-start=SU,SI,R,R_2,R_1,B,B_2,B_1/00000000,BETH_MEMORY/0001E7C0,C$VECT,P,D,D_2,D_1,W,W_2,W_1,C,C_2,C_1,L/0FFF00000,FVECT/0FFFFFF80
+-rom=D=R,D_1=R_1,D_2=R_2
+-nologo
+-exit
+</LinkOptionCommandLine-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587459010024537007</TimeTagModified--0>
+      <LinkOptionCpu-0>False</LinkOptionCpu-0>
+      <LinkOptionForm-0>Absolute</LinkOptionForm-0>
+      <LinkOptionFormConvert-0>Stype</LinkOptionFormConvert-0>
+      <LinkOptionInput-0 />
+      <LinkOptionListShow-0>List</LinkOptionListShow-0>
+      <LinkOptionOptimize-0>None</LinkOptionOptimize-0>
+      <LinkOptionStack-0>False</LinkOptionStack-0>
+      <LinkOptionStart-0>SU,SI,R,R_2,R_1,B,B_2,B_1/00000000,BETH_MEMORY/0001E7C0,C$VECT,P,D,D_2,D_1,W,W_2,W_1,C,C_2,C_1,L/0FFF00000,FVECT/0FFFFFF80</LinkOptionStart-0>
+      <LinkOptionCompress-0>False</LinkOptionCompress-0>
+      <LinkOptionCpuInformation-0 />
+      <LinkOptionDebug-0>Debug</LinkOptionDebug-0>
+      <LinkOptionFSymbol-0 />
+      <LinkOptionLibrary-0>..\libasp\%BuildModeName%\libasp
+..\liblwip\%BuildModeName%\liblwip
+..\libwolfssl\%BuildModeName%\libwolfssl
+..\libcurl\%BuildModeName%\libcurl
+</LinkOptionLibrary-0>
+      <LinkOptionOptimizeSymbolDelete-0>False</LinkOptionOptimizeSymbolDelete-0>
+      <LinkOptionRecordH-0>None</LinkOptionRecordH-0>
+      <LinkOptionShowSymbol-0>True</LinkOptionShowSymbol-0>
+      <LinkOptionAlignedSection-0 />
+      <LinkOptionCpuStride-0>False</LinkOptionCpuStride-0>
+      <LinkOptionMemory-0>False</LinkOptionMemory-0>
+      <LinkOptionOptimizeSameCode-0>False</LinkOptionOptimizeSameCode-0>
+      <LinkOptionOutputFolder-0>%BuildModeName%</LinkOptionOutputFolder-0>
+      <LinkOptionRecordS-0>None</LinkOptionRecordS-0>
+      <LinkOptionShowReference-0>False</LinkOptionShowReference-0>
+      <LinkOptionSystemLibrary-0 />
+      <LinkOptionBinary-0 />
+      <LinkOptionChangeMessageInformation-0>None</LinkOptionChangeMessageInformation-0>
+      <LinkOptionContiguousSection-0 />
+      <LinkOptionDividedConvertFile-0>False</LinkOptionDividedConvertFile-0>
+      <LinkOptionOutputFileName-0>%ProjectName%.abs</LinkOptionOutputFileName-0>
+      <LinkOptionRom-0>D=R
+D_1=R_1
+D_2=R_2
+</LinkOptionRom-0>
+      <LinkOptionSameSize-0>1E</LinkOptionSameSize-0>
+      <LinkOptionShowXreference-0>True</LinkOptionShowXreference-0>
+      <LinkOptionChangeMessageInformationNumber-0 />
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <LinkOptionDefine-0 />
+      <LinkOptionMap-0>False</LinkOptionMap-0>
+      <LinkOptionOptimizeShortFormat-0>False</LinkOptionOptimizeShortFormat-0>
+      <LinkOptionShowTotalSize-0>True</LinkOptionShowTotalSize-0>
+      <LinkOptionChangeMessageWarning-0>None</LinkOptionChangeMessageWarning-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <LinkOptionEntry-0>False</LinkOptionEntry-0>
+      <LinkOptionMessage-0>NoMessage</LinkOptionMessage-0>
+      <LinkOptionOptimizeBranch-0>False</LinkOptionOptimizeBranch-0>
+      <LinkOptionShowVector-0>False</LinkOptionShowVector-0>
+      <LinkOptionChangeMessageWarningNumber-0 />
+      <LinkOptionEntryPoint-0 />
+      <LinkOptionMultiConvertFileName-0 />
+      <LinkOptionNoMessageErrorNumber-0 />
+      <LinkOptionSymbolForbid-0 />
+      <LinkOptionChangeMessageError-0>None</LinkOptionChangeMessageError-0>
+      <LinkOptionNoPrelink-0>Auto</LinkOptionNoPrelink-0>
+      <LinkOptionPadding-0>False</LinkOptionPadding-0>
+      <LinkOptionSameCodeForbid-0 />
+      <LinkOptionSpace-0>None</LinkOptionSpace-0>
+      <LinkOptionChangeMessageErrorNumber-0 />
+      <LinkOptionSectionForbid-0 />
+      <LinkOptionSpaceValue-0>FF</LinkOptionSpaceValue-0>
+      <LinkOptionVectN-0 />
+      <LinkOptionAbsoluteForbid-0 />
+      <LinkOptionByteCount-0>False</LinkOptionByteCount-0>
+      <LinkOptionHide-0>False</LinkOptionHide-0>
+      <LinkOptionVect-0 />
+      <LinkOptionByteCountValue-0>FF</LinkOptionByteCountValue-0>
+      <LinkOptionJumpEntriesForPic-0>False</LinkOptionJumpEntriesForPic-0>
+      <LinkOptionTotalSize-0>False</LinkOptionTotalSize-0>
+      <LinkOptionCrc-0>None</LinkOptionCrc-0>
+      <LinkOptionJumpEntriesForPicSectionName-0 />
+      <LinkOptionLogo-0>False</LinkOptionLogo-0>
+      <LinkOptionCrcOutputAddress-0>0</LinkOptionCrcOutputAddress-0>
+      <LinkOptionPreLinkCommands-0 />
+      <LinkOptionCrcCalculationRange-0 />
+      <LinkOptionPostLinkCommands-0 />
+      <LinkOptionOtherAdditionalOptionsForLoadModule-0 />
+      <LinkOptionS9-0>False</LinkOptionS9-0>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-0 />
+      <LinkOptionCommandLine-0>-library=..\libasp\%BuildModeName%\libasp
+-library=..\liblwip\%BuildModeName%\liblwip
+-library=..\libwolfssl\%BuildModeName%\libwolfssl
+-library=..\libcurl\%BuildModeName%\libcurl
+-noprelink
+-output=%BuildModeName%\%ProjectName%.abs
+-list=%BuildModeName%\%ProjectName%.map
+-show=symbol,xreference,total_size
+-nooptimize
+-start=SU,SI,R,R_2,R_1,B,B_2,B_1/00000000,BETH_MEMORY/0001E7C0,C$VECT,P,D,D_2,D_1,W,W_2,W_1,C,C_2,C_1,L/0FFF00000,FVECT/0FFFFFF80
+-rom=D=R,D_1=R_1,D_2=R_2
+-nologo
+-exit
+</LinkOptionCommandLine-0>
+    </Instance>
+    <Instance Guid="df74c69e-635e-42d9-845e-14128ba4d48a">
+      <HexOptionForm-DefaultValue>Stype</HexOptionForm-DefaultValue>
+      <HexOptionOutput-DefaultValue>True</HexOptionOutput-DefaultValue>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-DefaultValue />
+      <HexOptionCommandLine-DefaultValue>-end
+-input=%BuildModeName%\%ProjectName%.abs
+-form=stype
+-output=%BuildModeName%\%ProjectName%.mot
+-exit
+</HexOptionCommandLine-DefaultValue>
+      <LinkOptionConvertFolder-DefaultValue>%BuildModeName%</LinkOptionConvertFolder-DefaultValue>
+      <LinkOptionRecordH-DefaultValue>None</LinkOptionRecordH-DefaultValue>
+      <LinkOptionConvertFileName-DefaultValue>%ProjectName%.mot</LinkOptionConvertFileName-DefaultValue>
+      <LinkOptionRecordS-DefaultValue>None</LinkOptionRecordS-DefaultValue>
+      <LinkOptionMultiConvertFileName-DefaultValue />
+      <LinkOptionSpace-DefaultValue>None</LinkOptionSpace-DefaultValue>
+      <LinkOptionSpaceValue-DefaultValue>FF</LinkOptionSpaceValue-DefaultValue>
+      <LinkOptionByteCount-DefaultValue>False</LinkOptionByteCount-DefaultValue>
+      <LinkOptionByteCountValue-DefaultValue>FF</LinkOptionByteCountValue-DefaultValue>
+      <LinkOptionCrc-DefaultValue>None</LinkOptionCrc-DefaultValue>
+      <LinkOptionCrcOutputAddress-DefaultValue>0</LinkOptionCrcOutputAddress-DefaultValue>
+      <LinkOptionCrcCalculationRange-DefaultValue />
+      <LinkOptionS9-DefaultValue>False</LinkOptionS9-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053503578449317</TimeTagModified--0>
+      <HexOptionForm-0>Stype</HexOptionForm-0>
+      <HexOptionOutput-0>True</HexOptionOutput-0>
+      <LinkOptionOtherAdditionalOptionsForConvertFile-0 />
+      <HexOptionCommandLine-0>-end
+-input=%BuildModeName%\%ProjectName%.abs
+-form=stype
+-output=%BuildModeName%\%ProjectName%.mot
+-exit
+</HexOptionCommandLine-0>
+      <LinkOptionConvertFolder-0>%BuildModeName%</LinkOptionConvertFolder-0>
+      <LinkOptionRecordH-0>None</LinkOptionRecordH-0>
+      <LinkOptionConvertFileName-0>%ProjectName%.mot</LinkOptionConvertFileName-0>
+      <LinkOptionRecordS-0>None</LinkOptionRecordS-0>
+      <LinkOptionMultiConvertFileName-0 />
+      <LinkOptionSpace-0>None</LinkOptionSpace-0>
+      <LinkOptionSpaceValue-0>FF</LinkOptionSpaceValue-0>
+      <LinkOptionByteCount-0>False</LinkOptionByteCount-0>
+      <LinkOptionByteCountValue-0>FF</LinkOptionByteCountValue-0>
+      <LinkOptionCrc-0>None</LinkOptionCrc-0>
+      <LinkOptionCrcOutputAddress-0>0</LinkOptionCrcOutputAddress-0>
+      <LinkOptionCrcCalculationRange-0 />
+      <LinkOptionS9-0>False</LinkOptionS9-0>
+    </Instance>
+    <Instance Guid="fff50d2e-74da-44ea-90a8-c47756029e83">
+      <LibOptionForm-DefaultValue>LibraryU</LibOptionForm-DefaultValue>
+      <LibOptionInput-DefaultValue />
+      <LibOptionListShow-DefaultValue>None</LibOptionListShow-DefaultValue>
+      <LibOptionMemory-DefaultValue>False</LibOptionMemory-DefaultValue>
+      <LibOptionChangeMessageInformation-DefaultValue>None</LibOptionChangeMessageInformation-DefaultValue>
+      <LibOptionDebug-DefaultValue>Debug</LibOptionDebug-DefaultValue>
+      <LibOptionLibrary-DefaultValue />
+      <LibOptionShowSymbol-DefaultValue>False</LibOptionShowSymbol-DefaultValue>
+      <LibOptionChangeMessageInformationNumber-DefaultValue />
+      <LibOptionOutputFolder-DefaultValue>%BuildModeName%</LibOptionOutputFolder-DefaultValue>
+      <LibOptionShowSection-DefaultValue>False</LibOptionShowSection-DefaultValue>
+      <LibOptionSystemLibrary-DefaultValue />
+      <LibOptionBinary-DefaultValue />
+      <LibOptionChangeMessageWarning-DefaultValue>None</LibOptionChangeMessageWarning-DefaultValue>
+      <LibOptionOutputFileName-DefaultValue>%ProjectName%.lib</LibOptionOutputFileName-DefaultValue>
+      <LibOptionShowXreference-DefaultValue>False</LibOptionShowXreference-DefaultValue>
+      <LibOptionChangeMessageWarningNumber-DefaultValue />
+      <LibOptionMessage-DefaultValue>NoMessage</LibOptionMessage-DefaultValue>
+      <LibOptionNoPrelink-DefaultValue>Auto</LibOptionNoPrelink-DefaultValue>
+      <LibOptionShowTotalSize-DefaultValue>False</LibOptionShowTotalSize-DefaultValue>
+      <LibOptionChangeMessageError-DefaultValue>None</LibOptionChangeMessageError-DefaultValue>
+      <LibOptionNoMessageErrorNumber-DefaultValue />
+      <LibOptionShowVector-DefaultValue>False</LibOptionShowVector-DefaultValue>
+      <LibOptionChangeMessageErrorNumber-DefaultValue />
+      <LibOptionHide-DefaultValue>False</LibOptionHide-DefaultValue>
+      <LibOptionTotalSize-DefaultValue>False</LibOptionTotalSize-DefaultValue>
+      <LibOptionLogo-DefaultValue>False</LibOptionLogo-DefaultValue>
+      <LibOptionPreLibrarianCommands-DefaultValue />
+      <LibOptionPostLibrarianCommands-DefaultValue />
+      <LibOptionOtherAdditionalOptions-DefaultValue />
+      <LibOptionCommandLine-DefaultValue />
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8588053503578449317</TimeTagModified--0>
+      <LibOptionForm-0>LibraryU</LibOptionForm-0>
+      <LibOptionInput-0 />
+      <LibOptionListShow-0>None</LibOptionListShow-0>
+      <LibOptionMemory-0>False</LibOptionMemory-0>
+      <LibOptionChangeMessageInformation-0>None</LibOptionChangeMessageInformation-0>
+      <LibOptionDebug-0>Debug</LibOptionDebug-0>
+      <LibOptionLibrary-0 />
+      <LibOptionShowSymbol-0>False</LibOptionShowSymbol-0>
+      <LibOptionChangeMessageInformationNumber-0 />
+      <LibOptionOutputFolder-0>%BuildModeName%</LibOptionOutputFolder-0>
+      <LibOptionShowSection-0>False</LibOptionShowSection-0>
+      <LibOptionSystemLibrary-0 />
+      <LibOptionBinary-0 />
+      <LibOptionChangeMessageWarning-0>None</LibOptionChangeMessageWarning-0>
+      <LibOptionOutputFileName-0>%ProjectName%.lib</LibOptionOutputFileName-0>
+      <LibOptionShowXreference-0>False</LibOptionShowXreference-0>
+      <LibOptionChangeMessageWarningNumber-0 />
+      <LibOptionMessage-0>NoMessage</LibOptionMessage-0>
+      <LibOptionNoPrelink-0>Auto</LibOptionNoPrelink-0>
+      <LibOptionShowTotalSize-0>False</LibOptionShowTotalSize-0>
+      <LibOptionChangeMessageError-0>None</LibOptionChangeMessageError-0>
+      <LibOptionNoMessageErrorNumber-0 />
+      <LibOptionShowVector-0>False</LibOptionShowVector-0>
+      <LibOptionChangeMessageErrorNumber-0 />
+      <LibOptionHide-0>False</LibOptionHide-0>
+      <LibOptionTotalSize-0>False</LibOptionTotalSize-0>
+      <LibOptionLogo-0>False</LibOptionLogo-0>
+      <LibOptionPreLibrarianCommands-0 />
+      <LibOptionPostLibrarianCommands-0 />
+      <LibOptionOtherAdditionalOptions-0 />
+      <LibOptionCommandLine-0 />
+    </Instance>
+    <Instance Guid="9cb0ade0-b3cb-4e21-823c-290b5fdb5f1e">
+      <LbgOptionLanguage-DefaultValue>C</LbgOptionLanguage-DefaultValue>
+      <LbgOptionLibraryMode-DefaultValue>MakeOptionChanged</LbgOptionLibraryMode-DefaultValue>
+      <LbgOptionLogo-DefaultValue>False</LbgOptionLogo-DefaultValue>
+      <LbgOptionOptimize-DefaultValue>Level2</LbgOptionOptimize-DefaultValue>
+      <LbgOptionOutputFolder-DefaultValue>%BuildModeName%</LbgOptionOutputFolder-DefaultValue>
+      <LbgOptionGoptimize-DefaultValue>False</LbgOptionGoptimize-DefaultValue>
+      <LbgOptionHead-DefaultValue>Custom</LbgOptionHead-DefaultValue>
+      <LbgOptionOutputFileName-DefaultValue>%ProjectName%.lib</LbgOptionOutputFileName-DefaultValue>
+      <LbgOptionPreLibraryGenerateCommands-DefaultValue />
+      <LbgOptionFunctionalCutdown-DefaultValue>None</LbgOptionFunctionalCutdown-DefaultValue>
+      <LbgOptionHeadRuntime-DefaultValue>True</LbgOptionHeadRuntime-DefaultValue>
+      <LbgOptionPostLibraryGenerateCommands-DefaultValue />
+      <LbgOptionSpeedAndSize-DefaultValue>Size</LbgOptionSpeedAndSize-DefaultValue>
+      <LbgOptionHeadCtypeH-DefaultValue>False</LbgOptionHeadCtypeH-DefaultValue>
+      <LbgOptionLoop-DefaultValue>Auto</LbgOptionLoop-DefaultValue>
+      <LbgOptionOtherAdditionalOptions-DefaultValue />
+      <LbgOptionReent-DefaultValue>False</LbgOptionReent-DefaultValue>
+      <LbgOptionCommandLine-DefaultValue>-isa=rxv1
+-fpu
+-lang=c99
+-head=runtime,math,stdio,stdlib,string,new
+-output=%BuildModeName%\%ProjectName%.lib
+-nologo
+</LbgOptionCommandLine-DefaultValue>
+      <LbgOptionHeadMathH-DefaultValue>False</LbgOptionHeadMathH-DefaultValue>
+      <LbgOptionLoopValue-DefaultValue>2</LbgOptionLoopValue-DefaultValue>
+      <LbgOptionSectionP-DefaultValue>P</LbgOptionSectionP-DefaultValue>
+      <LbgOptionHeadMathfH-DefaultValue>False</LbgOptionHeadMathfH-DefaultValue>
+      <LbgOptionInline-DefaultValue>Auto</LbgOptionInline-DefaultValue>
+      <LbgOptionSectionC-DefaultValue>C</LbgOptionSectionC-DefaultValue>
+      <LbgOptionHeadStdargH-DefaultValue>False</LbgOptionHeadStdargH-DefaultValue>
+      <LbgOptionInlineValue-DefaultValue>100</LbgOptionInlineValue-DefaultValue>
+      <LbgOptionSectionD-DefaultValue>D</LbgOptionSectionD-DefaultValue>
+      <LbgOptionFileInline-DefaultValue />
+      <LbgOptionHeadStdioH-DefaultValue>True</LbgOptionHeadStdioH-DefaultValue>
+      <LbgOptionSectionB-DefaultValue>B</LbgOptionSectionB-DefaultValue>
+      <LbgOptionCase-DefaultValue>Auto</LbgOptionCase-DefaultValue>
+      <LbgOptionHeadStdlibH-DefaultValue>True</LbgOptionHeadStdlibH-DefaultValue>
+      <LbgOptionSectionL-DefaultValue>L</LbgOptionSectionL-DefaultValue>
+      <LbgOptionHeadStringH-DefaultValue>True</LbgOptionHeadStringH-DefaultValue>
+      <LbgOptionSectionW-DefaultValue>W</LbgOptionSectionW-DefaultValue>
+      <LbgOptionVolatile-DefaultValue>False</LbgOptionVolatile-DefaultValue>
+      <LbgOptionConstCopy-DefaultValue>Auto</LbgOptionConstCopy-DefaultValue>
+      <LbgOptionHeadIos-DefaultValue>False</LbgOptionHeadIos-DefaultValue>
+      <LbgOptionNostuffB-DefaultValue>False</LbgOptionNostuffB-DefaultValue>
+      <LbgOptionConstDiv-DefaultValue>Auto</LbgOptionConstDiv-DefaultValue>
+      <LbgOptionHeadNew-DefaultValue>True</LbgOptionHeadNew-DefaultValue>
+      <LbgOptionNostuffD-DefaultValue>False</LbgOptionNostuffD-DefaultValue>
+      <LbgOptionHeadComplex-DefaultValue>False</LbgOptionHeadComplex-DefaultValue>
+      <LbgOptionLibrary-DefaultValue>Intrinsic</LbgOptionLibrary-DefaultValue>
+      <LbgOptionNostuffC-DefaultValue>False</LbgOptionNostuffC-DefaultValue>
+      <LbgOptionHeadString-DefaultValue>False</LbgOptionHeadString-DefaultValue>
+      <LbgOptionNostuffW-DefaultValue>False</LbgOptionNostuffW-DefaultValue>
+      <LbgOptionScope-DefaultValue>Auto</LbgOptionScope-DefaultValue>
+      <LbgOptionHeadComplexH-DefaultValue>False</LbgOptionHeadComplexH-DefaultValue>
+      <LbgOptionInstalign-DefaultValue>Noinstalign</LbgOptionInstalign-DefaultValue>
+      <LbgOptionSchedule-DefaultValue>Auto</LbgOptionSchedule-DefaultValue>
+      <LbgOptionApproxdiv-DefaultValue>False</LbgOptionApproxdiv-DefaultValue>
+      <LbgOptionHeadFenvH-DefaultValue>False</LbgOptionHeadFenvH-DefaultValue>
+      <LbgOptionNouseDiv-DefaultValue>True</LbgOptionNouseDiv-DefaultValue>
+      <LbgOptionEnableRegister-DefaultValue>False</LbgOptionEnableRegister-DefaultValue>
+      <LbgOptionHeadInttypesH-DefaultValue>False</LbgOptionHeadInttypesH-DefaultValue>
+      <LbgOptionHeadWcharH-DefaultValue>False</LbgOptionHeadWcharH-DefaultValue>
+      <LbgOptionSimpleFloatConv-DefaultValue>False</LbgOptionSimpleFloatConv-DefaultValue>
+      <LbgOptionFpu-DefaultValue>Fpu</LbgOptionFpu-DefaultValue>
+      <LbgOptionHeadWctypeH-DefaultValue>False</LbgOptionHeadWctypeH-DefaultValue>
+      <LbgOptionFloatOrder-DefaultValue>False</LbgOptionFloatOrder-DefaultValue>
+      <IsLockedByUser>False</IsLockedByUser>
+      <TimeTagModified--0>-8587462791552684202</TimeTagModified--0>
+      <LbgOptionLanguage-0>C99</LbgOptionLanguage-0>
+      <LbgOptionLibraryMode-0>MakeOptionChanged</LbgOptionLibraryMode-0>
+      <LbgOptionLogo-0>False</LbgOptionLogo-0>
+      <LbgOptionOptimize-0>Level2</LbgOptionOptimize-0>
+      <LbgOptionOutputFolder-0>%BuildModeName%</LbgOptionOutputFolder-0>
+      <LbgOptionGoptimize-0>False</LbgOptionGoptimize-0>
+      <LbgOptionHead-0>Custom</LbgOptionHead-0>
+      <LbgOptionOutputFileName-0>%ProjectName%.lib</LbgOptionOutputFileName-0>
+      <LbgOptionPreLibraryGenerateCommands-0 />
+      <LbgOptionFunctionalCutdown-0>None</LbgOptionFunctionalCutdown-0>
+      <LbgOptionPostLibraryGenerateCommands-0 />
+      <LbgOptionSpeedAndSize-0>Size</LbgOptionSpeedAndSize-0>
+      <LbgOptionHeadCtypeH-0>False</LbgOptionHeadCtypeH-0>
+      <LbgOptionLoop-0>Auto</LbgOptionLoop-0>
+      <LbgOptionOtherAdditionalOptions-0 />
+      <LbgOptionReent-0>False</LbgOptionReent-0>
+      <LbgOptionCommandLine-0>-isa=rxv1
+-fpu
+-lang=c99
+-head=runtime,math,stdio,stdlib,string,new
+-output=%BuildModeName%\%ProjectName%.lib
+-nologo
+</LbgOptionCommandLine-0>
+      <LbgOptionHeadMathH-0>True</LbgOptionHeadMathH-0>
+      <LbgOptionLoopValue-0>2</LbgOptionLoopValue-0>
+      <LbgOptionSectionP-0>P</LbgOptionSectionP-0>
+      <LbgOptionHeadMathfH-0>False</LbgOptionHeadMathfH-0>
+      <LbgOptionInline-0>Auto</LbgOptionInline-0>
+      <LbgOptionSectionC-0>C</LbgOptionSectionC-0>
+      <LbgOptionHeadStdargH-0>False</LbgOptionHeadStdargH-0>
+      <LbgOptionInlineValue-0>100</LbgOptionInlineValue-0>
+      <LbgOptionSectionD-0>D</LbgOptionSectionD-0>
+      <LbgOptionFileInline-0 />
+      <LbgOptionHeadStdioH-0>True</LbgOptionHeadStdioH-0>
+      <LbgOptionSectionB-0>B</LbgOptionSectionB-0>
+      <LbgOptionCase-0>Auto</LbgOptionCase-0>
+      <LbgOptionHeadStdlibH-0>True</LbgOptionHeadStdlibH-0>
+      <LbgOptionSectionL-0>L</LbgOptionSectionL-0>
+      <LbgOptionHeadStringH-0>True</LbgOptionHeadStringH-0>
+      <LbgOptionSectionW-0>W</LbgOptionSectionW-0>
+      <LbgOptionVolatile-0>False</LbgOptionVolatile-0>
+      <LbgOptionConstCopy-0>Auto</LbgOptionConstCopy-0>
+      <LbgOptionHeadIos-0>False</LbgOptionHeadIos-0>
+      <LbgOptionNostuffB-0>False</LbgOptionNostuffB-0>
+      <LbgOptionConstDiv-0>Auto</LbgOptionConstDiv-0>
+      <LbgOptionHeadNew-0>True</LbgOptionHeadNew-0>
+      <LbgOptionNostuffD-0>False</LbgOptionNostuffD-0>
+      <LbgOptionHeadComplex-0>False</LbgOptionHeadComplex-0>
+      <LbgOptionLibrary-0>Intrinsic</LbgOptionLibrary-0>
+      <LbgOptionNostuffC-0>False</LbgOptionNostuffC-0>
+      <LbgOptionHeadString-0>False</LbgOptionHeadString-0>
+      <LbgOptionNostuffW-0>False</LbgOptionNostuffW-0>
+      <LbgOptionScope-0>Auto</LbgOptionScope-0>
+      <LbgOptionHeadComplexH-0>False</LbgOptionHeadComplexH-0>
+      <LbgOptionInstalign-0>Noinstalign</LbgOptionInstalign-0>
+      <LbgOptionSchedule-0>Auto</LbgOptionSchedule-0>
+      <LbgOptionApproxdiv-0>False</LbgOptionApproxdiv-0>
+      <LbgOptionHeadFenvH-0>False</LbgOptionHeadFenvH-0>
+      <LbgOptionNouseDiv-0>True</LbgOptionNouseDiv-0>
+      <LbgOptionEnableRegister-0>False</LbgOptionEnableRegister-0>
+      <LbgOptionHeadInttypesH-0>False</LbgOptionHeadInttypesH-0>
+      <LbgOptionHeadWcharH-0>False</LbgOptionHeadWcharH-0>
+      <LbgOptionSimpleFloatConv-0>False</LbgOptionSimpleFloatConv-0>
+      <LbgOptionFpu-0>Fpu</LbgOptionFpu-0>
+      <LbgOptionHeadWctypeH-0>False</LbgOptionHeadWctypeH-0>
+      <LbgOptionFloatOrder-0>False</LbgOptionFloatOrder-0>
+    </Instance>
+    <Instance Guid="a6e69da5-6a9c-4b29-beab-311d258c5bb9">
+      <ItemAddTime>635318890363515654</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="75ed79e0-6ed0-4035-9691-328d6ff5dfa1">
+      <ItemAddTime>635318898924660048</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="ba73b40c-9528-4333-9dc1-a7ea8a90f98c">
+      <ItemAddTime>635318898924660048</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="4ecc3644-1ccc-4566-9842-5f9212542f0c">
+      <ItemAddTime>635318898924660048</ItemAddTime>
+      <ItemAddTimeCount>2</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="1aef2559-762d-4094-9d4a-ca5deabc3734">
+      <ItemAddTime>635318898924660048</ItemAddTime>
+      <ItemAddTimeCount>3</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="b20590e5-5bde-44da-aed4-9c2b60191d31">
+      <ItemAddTime>635318923493278978</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="a45d8b6d-ce19-44bf-8c02-4d5d70e21532">
+      <ItemAddTime>635318924191171999</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="85c7a3c6-84ec-41bc-9ce4-3701677a68dc">
+      <ItemAddTime>635318900550953785</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="13c5046e-040e-4102-9301-6aee6c37c0b2">
+      <ItemAddTime>635881933795994226</ItemAddTime>
+      <ItemAddTimeCount>7</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="795c9018-08d8-489b-8fc0-9bde7a85ce6f">
+      <ItemAddTime>635881933795994226</ItemAddTime>
+      <ItemAddTimeCount>5</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="8dea4e10-7304-48ef-a1e2-0e82092b8406">
+      <ItemAddTime>635881933795994226</ItemAddTime>
+      <ItemAddTimeCount>4</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="51c7f00f-2ec9-4295-93fb-ef32dcbe66c1">
+      <ItemAddTime>635881933795994226</ItemAddTime>
+      <ItemAddTimeCount>3</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="814fae99-905c-4f06-91a8-4ca70f1fbddd">
+      <ItemAddTime>635881933795994226</ItemAddTime>
+      <ItemAddTimeCount>2</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="2f6b3d63-eaf1-4641-a3c7-031702646365">
+      <ItemAddTime>635881933795994226</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="7a65af48-b4ff-4352-b5f1-9bc7ab7f2b23">
+      <ItemAddTime>635881933795994226</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="e8a40594-66bb-4c27-bd03-af9184da00de">
+      <ItemAddTime>635318861523734021</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="7cde729a-32f8-4fca-8b33-09d98d30b3bb">
+      <ItemAddTime>635318887141347875</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="ad3be50b-10fd-4116-8a30-852e1a927899">
+      <ItemAddTime>635318889906720222</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="db429c54-393d-4aeb-adbf-7a7c9f6bac76">
+      <ItemAddTime>635318887141347875</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="7b86eb36-f2ac-4b0c-91b1-35e955c2885e">
+      <ItemAddTime>635838926504832579</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d5d89bef-c974-4a49-b425-a6fa988ddab8">
+      <ItemAddTime>635838927962966904</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="00c1f55e-c4e4-4973-8fe4-b9aa1c2a5ecc">
+      <ItemAddTime>635881939115682908</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="4540ea18-558c-4f77-bde1-c0b7c36e1935">
+      <ItemAddTime>635881939115682908</ItemAddTime>
+      <ItemAddTimeCount>1</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="9e563cbe-ae2a-4afd-b742-072c30f44930">
+      <ItemAddTime>635885810836042844</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="73395af5-564a-47ee-a7be-3573d271e471">
+      <ItemAddTime>635885805744949970</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="37b40277-9931-49ba-b46c-2437dc8a9616">
+      <ItemAddTime>635886288738687268</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="0d86e5ab-2f37-412a-a8bf-cd4c865ef2d9">
+      <ItemAddTime>635891758991145438</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="d616fb78-cb8e-45f3-a8f1-0e334d21ceb9">
+      <ItemAddTime>635894328558081841</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="e01bbf59-b19d-4092-9a90-9db3c5cd8215">
+      <ItemAddTime>635914969627289955</ItemAddTime>
+      <ItemAddTimeCount>0</ItemAddTimeCount>
+    </Instance>
+    <Instance Guid="c20a78d9-8038-46fe-9b87-bc2fa2aa9bdc">
+      <TimeTagModified-SourceItem0--0>-8588053470491260154</TimeTagModified-SourceItem0--0>
+      <SourceItem0-IsLockedByUser>False</SourceItem0-IsLockedByUser>
+      <SourceItem0-BuildingTarget-0>True</SourceItem0-BuildingTarget-0>
+      <SourceItem0-IndividualAssembleOption-0>False</SourceItem0-IndividualAssembleOption-0>
+      <TimeTagModified-SourceItem11--0>-8587533432891808904</TimeTagModified-SourceItem11--0>
+      <SourceItem11-IsLockedByUser>False</SourceItem11-IsLockedByUser>
+      <SourceItem11-BuildingTarget-0>True</SourceItem11-BuildingTarget-0>
+      <SourceItem11-IndividualAssembleOption-0>False</SourceItem11-IndividualAssembleOption-0>
+    </Instance>
+    <Instance Guid="a7be515f-f007-45ed-9059-4e1500c0f74d">
+      <TimeTagModified-SourceItem1--0>-8588053461930115760</TimeTagModified-SourceItem1--0>
+      <SourceItem1-IsLockedByUser>False</SourceItem1-IsLockedByUser>
+      <SourceItem1-BuildingTarget-0>True</SourceItem1-BuildingTarget-0>
+      <SourceItem1-IndividualCompileOption-0>False</SourceItem1-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem2--0>-8588053461930115760</TimeTagModified-SourceItem2--0>
+      <SourceItem2-IsLockedByUser>False</SourceItem2-IsLockedByUser>
+      <SourceItem2-BuildingTarget-0>True</SourceItem2-BuildingTarget-0>
+      <SourceItem2-IndividualCompileOption-0>False</SourceItem2-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem3--0>-8588053461930115760</TimeTagModified-SourceItem3--0>
+      <SourceItem3-IsLockedByUser>False</SourceItem3-IsLockedByUser>
+      <SourceItem3-BuildingTarget-0>True</SourceItem3-BuildingTarget-0>
+      <SourceItem3-IndividualCompileOption-0>False</SourceItem3-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem4--0>-8588053461930115760</TimeTagModified-SourceItem4--0>
+      <SourceItem4-IsLockedByUser>False</SourceItem4-IsLockedByUser>
+      <SourceItem4-BuildingTarget-0>True</SourceItem4-BuildingTarget-0>
+      <SourceItem4-IndividualCompileOption-0>False</SourceItem4-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem5--0>-8588053437361496830</TimeTagModified-SourceItem5--0>
+      <SourceItem5-IsLockedByUser>False</SourceItem5-IsLockedByUser>
+      <SourceItem5-BuildingTarget-0>True</SourceItem5-BuildingTarget-0>
+      <SourceItem5-IndividualCompileOption-0>False</SourceItem5-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem6--0>-8588053436663603809</TimeTagModified-SourceItem6--0>
+      <SourceItem6-IsLockedByUser>False</SourceItem6-IsLockedByUser>
+      <SourceItem6-BuildingTarget-0>True</SourceItem6-BuildingTarget-0>
+      <SourceItem6-IndividualCompileOption-0>False</SourceItem6-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem7--0>-8588053460303822023</TimeTagModified-SourceItem7--0>
+      <SourceItem7-IsLockedByUser>False</SourceItem7-IsLockedByUser>
+      <SourceItem7-BuildingTarget-0>True</SourceItem7-BuildingTarget-0>
+      <SourceItem7-IndividualCompileOption-0>False</SourceItem7-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem8--0>-8588053499331041787</TimeTagModified-SourceItem8--0>
+      <SourceItem8-IsLockedByUser>False</SourceItem8-IsLockedByUser>
+      <SourceItem8-BuildingTarget-0>True</SourceItem8-BuildingTarget-0>
+      <SourceItem8-IndividualCompileOption-0>False</SourceItem8-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem9--0>-8588053473713427933</TimeTagModified-SourceItem9--0>
+      <SourceItem9-IsLockedByUser>False</SourceItem9-IsLockedByUser>
+      <SourceItem9-BuildingTarget-0>True</SourceItem9-BuildingTarget-0>
+      <SourceItem9-IndividualCompileOption-0>False</SourceItem9-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem10--0>-8587533434349943229</TimeTagModified-SourceItem10--0>
+      <SourceItem10-IsLockedByUser>False</SourceItem10-IsLockedByUser>
+      <SourceItem10-BuildingTarget-0>True</SourceItem10-BuildingTarget-0>
+      <SourceItem10-IndividualCompileOption-0>False</SourceItem10-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem12--0>-8587490421739092900</TimeTagModified-SourceItem12--0>
+      <SourceItem12-IsLockedByUser>False</SourceItem12-IsLockedByUser>
+      <SourceItem12-BuildingTarget-0>True</SourceItem12-BuildingTarget-0>
+      <SourceItem12-IndividualCompileOption-0>False</SourceItem12-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem13--0>-8587490421739092900</TimeTagModified-SourceItem13--0>
+      <SourceItem13-IsLockedByUser>False</SourceItem13-IsLockedByUser>
+      <SourceItem13-BuildingTarget-0>True</SourceItem13-BuildingTarget-0>
+      <SourceItem13-IndividualCompileOption-0>False</SourceItem13-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem14--0>-8587457391227485853</TimeTagModified-SourceItem14--0>
+      <SourceItem14-IsLockedByUser>False</SourceItem14-IsLockedByUser>
+      <SourceItem14-BuildingTarget-0>True</SourceItem14-BuildingTarget-0>
+      <SourceItem14-IndividualCompileOption-0>False</SourceItem14-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem15--0>-8587486072116088540</TimeTagModified-SourceItem15--0>
+      <SourceItem15-IsLockedByUser>False</SourceItem15-IsLockedByUser>
+      <SourceItem15-BuildingTarget-0>True</SourceItem15-BuildingTarget-0>
+      <SourceItem15-IndividualCompileOption-0>False</SourceItem15-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem16--0>-8587480601863630370</TimeTagModified-SourceItem16--0>
+      <SourceItem16-IsLockedByUser>False</SourceItem16-IsLockedByUser>
+      <SourceItem16-BuildingTarget-0>True</SourceItem16-BuildingTarget-0>
+      <SourceItem16-IndividualCompileOption-0>False</SourceItem16-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem17--0>-8587486555109815834</TimeTagModified-SourceItem17--0>
+      <SourceItem17-IsLockedByUser>False</SourceItem17-IsLockedByUser>
+      <SourceItem17-BuildingTarget-0>True</SourceItem17-BuildingTarget-0>
+      <SourceItem17-IndividualCompileOption-0>False</SourceItem17-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem18--0>-8587486550018732964</TimeTagModified-SourceItem18--0>
+      <SourceItem18-IsLockedByUser>False</SourceItem18-IsLockedByUser>
+      <SourceItem18-BuildingTarget-0>True</SourceItem18-BuildingTarget-0>
+      <SourceItem18-IndividualCompileOption-0>False</SourceItem18-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem19--0>-8587478032296693967</TimeTagModified-SourceItem19--0>
+      <SourceItem19-IsLockedByUser>False</SourceItem19-IsLockedByUser>
+      <SourceItem19-BuildingTarget-0>True</SourceItem19-BuildingTarget-0>
+      <SourceItem19-IndividualCompileOption-0>False</SourceItem19-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem20--0>-8587490427058781582</TimeTagModified-SourceItem20--0>
+      <SourceItem20-IsLockedByUser>False</SourceItem20-IsLockedByUser>
+      <SourceItem20-BuildingTarget-0>True</SourceItem20-BuildingTarget-0>
+      <SourceItem20-IndividualCompileOption-0>False</SourceItem20-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem21--0>-8587490427058781582</TimeTagModified-SourceItem21--0>
+      <SourceItem21-IsLockedByUser>False</SourceItem21-IsLockedByUser>
+      <SourceItem21-BuildingTarget-0>True</SourceItem21-BuildingTarget-0>
+      <SourceItem21-IndividualCompileOption-0>False</SourceItem21-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem22--0>-8587490427058781582</TimeTagModified-SourceItem22--0>
+      <SourceItem22-IsLockedByUser>False</SourceItem22-IsLockedByUser>
+      <SourceItem22-BuildingTarget-0>True</SourceItem22-BuildingTarget-0>
+      <SourceItem22-IndividualCompileOption-0>False</SourceItem22-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem23--0>-8587490427058781582</TimeTagModified-SourceItem23--0>
+      <SourceItem23-IsLockedByUser>False</SourceItem23-IsLockedByUser>
+      <SourceItem23-BuildingTarget-0>True</SourceItem23-BuildingTarget-0>
+      <SourceItem23-IndividualCompileOption-0>False</SourceItem23-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem24--0>-8587490427058781582</TimeTagModified-SourceItem24--0>
+      <SourceItem24-IsLockedByUser>False</SourceItem24-IsLockedByUser>
+      <SourceItem24-BuildingTarget-0>True</SourceItem24-BuildingTarget-0>
+      <SourceItem24-IndividualCompileOption-0>False</SourceItem24-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem25--0>-8587490427058781582</TimeTagModified-SourceItem25--0>
+      <SourceItem25-IsLockedByUser>False</SourceItem25-IsLockedByUser>
+      <SourceItem25-BuildingTarget-0>True</SourceItem25-BuildingTarget-0>
+      <SourceItem25-IndividualCompileOption-0>False</SourceItem25-IndividualCompileOption-0>
+      <TimeTagModified-SourceItem26--0>-8587490427058781582</TimeTagModified-SourceItem26--0>
+      <SourceItem26-IsLockedByUser>False</SourceItem26-IsLockedByUser>
+      <SourceItem26-BuildingTarget-0>True</SourceItem26-BuildingTarget-0>
+      <SourceItem26-IndividualCompileOption-0>False</SourceItem26-IndividualCompileOption-0>
+    </Instance>
+  </Class>
+  <Class Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
+    <Instance Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
+      <IsLibraryMode>False</IsLibraryMode>
+      <StartUpCategoryItem>00000000-0000-0000-0000-000000000000</StartUpCategoryItem>
+    </Instance>
+  </Class>
+  <Class Guid="a29a09ee-92c3-4ce7-9586-a1b058043f92">
+    <Instance Guid="a29a09ee-92c3-4ce7-9586-a1b058043f92">
+      <ProjectGeneratr-GeneratedFile0 />
+    </Instance>
+  </Class>
+  <Class Guid="31a86ad3-37bd-4846-aff2-e08abdc00197">
+    <Instance Guid="31a86ad3-37bd-4846-aff2-e08abdc00197">
+      <DeviceNameOnCreateStartup>R5F563NBDxFP</DeviceNameOnCreateStartup>
+    </Instance>
+  </Class>
+  <Class Guid="8b5af363-dcc2-48e6-919c-6cdb80d50173">
+    <Instance Guid="8b5af363-dcc2-48e6-919c-6cdb80d50173">
+      <DataFormatVersionPlugin>1.0</DataFormatVersionPlugin>
+      <DataFormatVersionDebugger>1.0</DataFormatVersionDebugger>
+    </Instance>
+  </Class>
+  <Class Guid="932085a2-9361-4df9-a3f7-12e6de7681a8">
+    <Instance Guid="932085a2-9361-4df9-a3f7-12e6de7681a8">
+      <DebugToolManager>1d1a55cf-2b92-481a-af4f-5975d095c419</DebugToolManager>
+    </Instance>
+  </Class>
+  <Class Guid="e4df8d71-236e-4af2-aaea-56345a08da25">
+    <Instance Guid="9e76d4e8-0b8f-4e7c-91b7-a4c442bcf2e7">
+      <DeviceChangedCounter>0</DeviceChangedCounter>
+      <DeviceName>R5F563NBDxFP</DeviceName>
+      <DebuggerProperty-EssentialProperty-Endian-CpuEndian>Little</DebuggerProperty-EssentialProperty-Endian-CpuEndian>
+      <DebuggerProperty-EssentialProperty-Clock-SystemClockFrequency>100</DebuggerProperty-EssentialProperty-Clock-SystemClockFrequency>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Length>3</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Length>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item0-Name>CMT</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item0-Name>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item0-IsUse>False</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item0-IsUse>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item1-Name>ICU</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item1-Name>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item1-IsUse>False</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item1-IsUse>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item2-Name>MPU</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item2-Name>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item2-IsUse>False</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-RegisterPeripheral-Item2-IsUse>
+      <DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-PeripheralClockRate>ClockRate_1</DebuggerProperty-EssentialProperty-PeripheralFunctionSimulation-PeripheralClockRate>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-Length>1</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-Length>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-DebuggerGuid />
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-FileName>DefaultBuild\usb_watt_meter.abs</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-FileName>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-FileType>LoadModuleFile</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-FileType>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-Offset>0</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-Offset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-StartAddress>0</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-StartAddress>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-ObjectDownload>True</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-ObjectDownload>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-SymbolDownload>True</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-SymbolDownload>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-UsePicPidOffset>False</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-UsePicPidOffset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-PicOffset>0</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-PicOffset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-PidOffset>0</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-PidOffset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-GenerateInformationForInputCompletion>True</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-GenerateInformationForInputCompletion>
+      <DebuggerProperty-DownloadProperty-DebugInformation-CpuReset>True</DebuggerProperty-DownloadProperty-DebugInformation-CpuReset>
+      <DebuggerProperty-DownloadProperty-DebugInformation-FlashErase>False</DebuggerProperty-DownloadProperty-DebugInformation-FlashErase>
+      <DebuggerProperty-DownloadProperty-DebugInformation-EventCorrection>SuspendEvent</DebuggerProperty-DownloadProperty-DebugInformation-EventCorrection>
+      <DebuggerProperty-DownloadProperty-DebugInformation-SkipStartup>True</DebuggerProperty-DownloadProperty-DebugInformation-SkipStartup>
+      <DebuggerProperty-DownloadProperty-DebugInformation-MainSymbol>XwBtAGEAaQBuAA==</DebuggerProperty-DownloadProperty-DebugInformation-MainSymbol>
+      <DebuggerProperty-DownloadProperty-DebugInformation-MaxLoaderMemorySize>500</DebuggerProperty-DownloadProperty-DebugInformation-MaxLoaderMemorySize>
+      <DebuggerProperty-OptionalProperty-Register-UpdateDisplayInExecutionForPC>No</DebuggerProperty-OptionalProperty-Register-UpdateDisplayInExecutionForPC>
+      <DebuggerProperty-OptionalProperty-Register-UpdateIntervalForPC>500</DebuggerProperty-OptionalProperty-Register-UpdateIntervalForPC>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-Length>17</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-Length>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-MapType>InternalRam</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-StartAddress>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-EndAddress>131071</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem0-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-StartAddress>131072</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-EndAddress>524287</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem1-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-StartAddress>524288</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-EndAddress>540671</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem2-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-StartAddress>540672</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-EndAddress>548863</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem3-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-StartAddress>548864</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-EndAddress>557055</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem4-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-StartAddress>557056</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-EndAddress>581631</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem5-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-StartAddress>581632</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-EndAddress>589823</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem6-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-StartAddress>589824</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-EndAddress>655359</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem7-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-StartAddress>655360</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-EndAddress>786431</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem8-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-StartAddress>786432</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-EndAddress>1048575</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem9-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-MapType>InternalRom</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-StartAddress>1048576</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-EndAddress>1081343</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem10-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-StartAddress>1081344</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-EndAddress>8372223</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem11-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-StartAddress>8372224</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-EndAddress>8373503</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem12-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-StartAddress>8373504</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-EndAddress>8387583</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem13-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-MapType>Sfr</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-StartAddress>8387584</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-EndAddress>8388607</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-Endian>Big</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem14-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-MapType>NonMap</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-StartAddress>8388608</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-EndAddress>4293918719</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem15-Endian>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-MapType>InternalRom</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-MapType>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-StartAddress>4293918720</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-StartAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-EndAddress>4294967295</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-EndAddress>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-ChipSelect>0</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-ChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-AccessSize>8</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-AccessSize>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-IsReadOnly>True</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-IsReadOnly>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-HasChipSelect>False</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-HasChipSelect>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-FieldInformation>None</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-FieldInformation>
+      <DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-Endian>Little</DebuggerProperty-OptionalProperty-Memory-MemoryMappings-MemoryMapItem16-Endian>
+      <DebuggerProperty-OptionalProperty-AccessMemory-UpdateDisplayInExecution>Yes</DebuggerProperty-OptionalProperty-AccessMemory-UpdateDisplayInExecution>
+      <DebuggerProperty-OptionalProperty-AccessMemory-UpdateInterval>500</DebuggerProperty-OptionalProperty-AccessMemory-UpdateInterval>
+      <DebuggerProperty-OptionalProperty-Trace-UseTrace>No</DebuggerProperty-OptionalProperty-Trace-UseTrace>
+      <DebuggerProperty-OptionalProperty-Trace-ClearTraceMemory>Yes</DebuggerProperty-OptionalProperty-Trace-ClearTraceMemory>
+      <DebuggerProperty-OptionalProperty-Trace-TraceMode>Nonstop</DebuggerProperty-OptionalProperty-Trace-TraceMode>
+      <DebuggerProperty-OptionalProperty-Trace-AddUptimeTag>No</DebuggerProperty-OptionalProperty-Trace-AddUptimeTag>
+      <DebuggerProperty-OptionalProperty-Trace-TraceMemorySize>TraceMemory_64KB</DebuggerProperty-OptionalProperty-Trace-TraceMemorySize>
+      <DebuggerProperty-OptionalProperty-Coverage-UseCoverage>No</DebuggerProperty-OptionalProperty-Coverage-UseCoverage>
+      <DebuggerProperty-OptionalProperty-Coverage-ReuseCoverageData>No</DebuggerProperty-OptionalProperty-Coverage-ReuseCoverageData>
+      <DebuggerProperty-OptionalProperty-StreamIO-SelectStreamIO>Simulator</DebuggerProperty-OptionalProperty-StreamIO-SelectStreamIO>
+      <DebuggerProperty-OptionalProperty-StreamIO-UseStreamIO>No</DebuggerProperty-OptionalProperty-StreamIO-UseStreamIO>
+      <DebuggerProperty-OptionalProperty-StreamIO-StreamIOAddress>0</DebuggerProperty-OptionalProperty-StreamIO-StreamIOAddress>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-ExecutionModeType>Stop</DebuggerProperty-OptionalProperty-ExecutionMode-ExecutionModeType>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopUndefined>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopUndefined>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopPrivileged>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopPrivileged>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopAccess>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopAccess>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopFloatingPoint>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopFloatingPoint>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopInterrupt>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopInterrupt>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopInt>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopInt>
+      <DebuggerProperty-OptionalProperty-ExecutionMode-StopBrk>Yes</DebuggerProperty-OptionalProperty-ExecutionMode-StopBrk>
+      <DebuggerProperty-OptionalProperty-InstructionDecodeCache-CacheResults>No</DebuggerProperty-OptionalProperty-InstructionDecodeCache-CacheResults>
+      <DebuggerProperty-HookProperty-HookTransaction-Downloading-Length>0</DebuggerProperty-HookProperty-HookTransaction-Downloading-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Downloaded-Length>0</DebuggerProperty-HookProperty-HookTransaction-Downloaded-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Reset-Length>0</DebuggerProperty-HookProperty-HookTransaction-Reset-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Going-Length>0</DebuggerProperty-HookProperty-HookTransaction-Going-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Broke-Length>0</DebuggerProperty-HookProperty-HookTransaction-Broke-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Connected-Length>0</DebuggerProperty-HookProperty-HookTransaction-Connected-Length>
+      <DebuggerProperty-HookProperty-HookTransaction-Disconnecting-Length>0</DebuggerProperty-HookProperty-HookTransaction-Disconnecting-Length>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-IsDefaultItem>True</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-IsDefaultItem>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-DefaultItemProjectGuid>ad88300a-1835-4edd-9d7a-ced9831fd7cf</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-DefaultItemProjectGuid>
+      <DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-CompilerType>Auto</DebuggerProperty-DownloadProperty-DebugInformation-DownloadFiles-DownloadItem0-CompilerType>
+      <DebuggerProperty-DownloadProperty-None-DefaultDownloadItemSupported>True</DebuggerProperty-DownloadProperty-None-DefaultDownloadItemSupported>
+    </Instance>
+  </Class>
+  <Class Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">
+    <Instance Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">
+      <ProductVersion>5.01.00.00</ProductVersion>
+    </Instance>
+  </Class>
+</CubeSuiteProject>
Index: UsbWattMeter/trunk/curl-7.47.1/CHANGES
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/CHANGES	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/CHANGES	(revision 164)
@@ -0,0 +1,5464 @@
+                                  _   _ ____  _
+                              ___| | | |  _ \| |
+                             / __| | | | |_) | |
+                            | (__| |_| |  _ <| |___
+                             \___|\___/|_| \_\_____|
+
+                                  Changelog
+
+Version 7.47.1 (8 Feb 2016)
+
+Daniel Stenberg (8 Feb 2016)
+- RELEASE-NOTES: curl 7.47.1 time!
+
+Jay Satiro (8 Feb 2016)
+- tool_operhlp: Check for backslashes in get_url_file_name
+  
+  Extract the filename from the last slash or backslash. Prior to this
+  change backslashes could be part of the filename.
+  
+  This change needed for the curl tool built for Cygwin. Refer to the
+  CYGWIN addendum in advisory 20160127B.
+  
+  Bug: https://curl.haxx.se/docs/adv_20160127B.html
+
+Daniel Stenberg (7 Feb 2016)
+- RELEASE-NOTES: synced with d6a8869ea34
+
+Jay Satiro (6 Feb 2016)
+- openssl: Fix signed/unsigned mismatch warning in X509V3_ext
+  
+  sk_X509_EXTENSION_num may return an unsigned integer, however the value
+  will fit in an int.
+  
+  Bug: https://github.com/curl/curl/commit/dd1b44c#commitcomment-15913896
+  Reported-by: Gisle Vanem
+
+Daniel Stenberg (7 Feb 2016)
+- TODO: 17.11 -w output to stderr
+
+Jay Satiro (6 Feb 2016)
+- [Michael Kaufmann brought this change]
+
+  idn_win32: Better error checking
+  
+  .. also fix a conversion bug in the unused function
+  curl_win32_ascii_to_idn().
+  
+  And remove wprintfs on error (Jay).
+  
+  Bug: https://github.com/curl/curl/pull/637
+
+- [Gisle Vanem brought this change]
+
+  examples/asiohiper: Avoid function name collision on Windows
+  
+  closesocket => close_socket
+  Winsock already has the former.
+  
+  Bug: https://curl.haxx.se/mail/lib-2016-02/0016.html
+
+- [Gisle Vanem brought this change]
+
+  examples/htmltitle: Use _stricmp on Windows
+  
+  Bug: https://curl.haxx.se/mail/lib-2016-02/0017.html
+
+Daniel Stenberg (6 Feb 2016)
+- COPYING: clarify that Daniel is not the sole author
+  
+  ... done on request and as it is a fair point.
+
+Jay Satiro (5 Feb 2016)
+- unit1604: Fix unit setup return code
+
+- tool_doswin: Use type SANITIZEcode in sanitize_file_name
+
+- tool_doswin: Improve sanitization processing
+  
+  - Add unit test 1604 to test the sanitize_file_name function.
+  
+  - Use -DCURL_STATICLIB when building libcurltool for unit testing.
+  
+  - Better detection of reserved DOS device names.
+  
+  - New flags to modify sanitize behavior:
+  
+  SANITIZE_ALLOW_COLONS: Allow colons
+  SANITIZE_ALLOW_PATH: Allow path separators and colons
+  SANITIZE_ALLOW_RESERVED: Allow reserved device names
+  SANITIZE_ALLOW_TRUNCATE: Allow truncating a long filename
+  
+  - Restore sanitization of banned characters from user-specified outfile.
+  
+  Prior to this commit sanitization of a user-specified outfile was
+  temporarily disabled in 2b6dadc because there was no way to allow path
+  separators and colons through while replacing other banned characters.
+  Now in such a case we call the sanitize function with
+  SANITIZE_ALLOW_PATH which allows path separators and colons to pass
+  through.
+  
+  
+  Closes https://github.com/curl/curl/issues/624
+  Reported-by: Octavio Schroeder
+
+- [Viktor Szakats brought this change]
+
+  URLs: change more http to https
+
+- sasl_sspi: Fix memory leak in domain populate
+  
+  Free an existing domain before replacing it.
+  
+  Bug: https://github.com/curl/curl/issues/635
+  Reported-by: silveja1@users.noreply.github.com
+
+Daniel Stenberg (4 Feb 2016)
+- [Viktor Szakats brought this change]
+
+  URLs: follow GitHub project rename (also Travis CI)
+  
+  Closes #632
+
+- CHANGES.o: fix references to curl.haxx.nu
+  
+  I removed the scheme prefix from the URLs references this host name, as
+  we don't own/run that anymore but the name is kept for historic reasons.
+
+- HISTORY: add some info about when we used which host names
+
+Jay Satiro (2 Feb 2016)
+- [Viktor Szakats brought this change]
+
+  URLs: change more http to https
+
+Dan Fandrich (3 Feb 2016)
+- URLs: Change more haxx.se URLs from http: to https:
+
+Daniel Stenberg (3 Feb 2016)
+- RELEASE-NOTES: synced with 4af40b364
+
+- URLs: change all http:// URLs to https://
+
+- configure: update the copyright year range in output
+
+- dotdot: allow an empty input string too
+  
+  It isn't used by the code in current conditions but for safety it seems
+  sensible to at least not crash on such input.
+  
+  Extended unit test 1395 to verify this too as well as a plain "/" input.
+
+- HTTPS: update a bunch of URLs from HTTP to HTTPS
+
+- [Sergei Nikulov brought this change]
+
+  AppVeyor: updated to handle OpenSSL/WinSSL builds
+  
+  Closes #621
+
+Jay Satiro (1 Feb 2016)
+- tool_operate: Don't sanitize --output path (Windows)
+  
+  Due to path separators being incorrectly sanitized in --output
+  pathnames, eg -o c:\foo => c__foo
+  
+  This is a partial revert of 3017d8a until I write a proper fix. The
+  remote-name will continue to be sanitized, but if the user specified an
+  --output with string replacement (#1, #2, etc) that data is unsanitized
+  until I finish a fix.
+  
+  Bug: https://github.com/bagder/curl/issues/624
+  Reported-by: Octavio Schroeder
+
+- curl.1: Explain remote-name behavior if file already exists
+  
+  .. also warn about letting the server pick the filename.
+
+- [Gisle Vanem brought this change]
+
+  urldata: Error on missing SSL backend-specific connect info
+
+Daniel Stenberg (28 Jan 2016)
+- bump: towards the next (7.47.1 ?)
+
+- [Sergei Nikulov brought this change]
+
+  cmake: fixed when OpenSSL enabled on Windows and schannel detected
+  
+  Closes #617
+
+Jay Satiro (28 Jan 2016)
+- [Sergei Nikulov brought this change]
+
+  urldata: moved common variable out of ifdef
+  
+  Closes https://github.com/bagder/curl/pull/618
+
+- [Viktor Szakats brought this change]
+
+  tool_doswin: silence unused function warning
+  
+  tool_doswin.c:185:14: warning: 'msdosify' defined but not used
+  [-Wunused-function]
+  
+  Closes https://github.com/bagder/curl/pull/616
+
+Daniel Stenberg (27 Jan 2016)
+- getredirect.c: fix variable name
+  
+  Reported-by: Bernard Spil
+
+Version 7.47.0 (27 Jan 2016)
+
+Daniel Stenberg (27 Jan 2016)
+- examples/Makefile.inc: specify programs without .c!
+
+- THANKS: 6 new contributors from 7.47.0 release notes
+
+- [Isaac Boukris brought this change]
+
+  NTLM: Fix ConnectionExists to compare Proxy credentials
+  
+  Proxy NTLM authentication should compare credentials when
+  re-using a connection similar to host authentication, as it
+  authenticate the connection.
+  
+  Example:
+  curl -v -x http://proxy:port http://host/ -U good_user:good_pwd
+    --proxy-ntlm --next -x http://proxy:port http://host/
+      [-U fake_user:fake_pwd --proxy-ntlm]
+  
+  CVE-2016-0755
+  
+  Bug: http://curl.haxx.se/docs/adv_20160127A.html
+
+- [Ray Satiro brought this change]
+
+  curl: avoid local drive traversal when saving file (Windows)
+  
+  curl does not sanitize colons in a remote file name that is used as the
+  local file name. This may lead to a vulnerability on systems where the
+  colon is a special path character. Currently Windows/DOS is the only OS
+  where this vulnerability applies.
+  
+  CVE-2016-0754
+  
+  Bug: http://curl.haxx.se/docs/adv_20160127B.html
+
+- RELEASE-NOTES: 7.47.0
+
+- FAQ: language fix in 4.19
+
+- [paulehoffman brought this change]
+
+  FAQ: Update to point to GitHub
+  
+  Current FAQ didn't make it clear where the main repo is.
+  
+  Closes #612
+
+- maketgz: generate date stamp with LC_TIME=C
+  
+  bug: http://curl.haxx.se/mail/lib-2016-01/0123.html
+
+- curl_multi_socket_action.3: line wrap
+
+- RELEASE-NOTES: synced with d58ba66eeceb
+
+Steve Holme (21 Jan 2016)
+- TODO: "Create remote directories" for SMB
+
+Jay Satiro (18 Jan 2016)
+- mbedtls: Fix pinned key return value on fail
+  
+  - Switch from verifying a pinned public key in a callback during the
+  certificate verification to inline after the certificate verification.
+  
+  The callback method had three problems:
+  
+  1. If a pinned public key didn't match, CURLE_SSL_PINNEDPUBKEYNOTMATCH
+  was not returned.
+  
+  2. If peer certificate verification was disabled the pinned key
+  verification did not take place as it should.
+  
+  3. (related to #2) If there was no certificate of depth 0 the callback
+  would not have checked the pinned public key.
+  
+  Though all those problems could have been fixed it would have made the
+  code more complex. Instead we now verify inline after the certificate
+  verification in mbedtls_connect_step2.
+  
+  Ref: http://curl.haxx.se/mail/lib-2016-01/0047.html
+  Ref: https://github.com/bagder/curl/pull/601
+
+- tests: Add a test for pinnedpubkey fail even when insecure
+  
+  Because disabling the peer verification (--insecure) must not disable
+  the public key pinning check (--pinnedpubkey).
+
+- [Daniel Schauenberg brought this change]
+
+  CURLINFO_RESPONSE_CODE.3: add example
+
+Kamil Dudka (15 Jan 2016)
+- ssh: make CURLOPT_SSH_PUBLIC_KEYFILE treat "" as NULL
+  
+  The CURLOPT_SSH_PUBLIC_KEYFILE option has been documented to handle
+  empty strings specially since curl-7_25_0-31-g05a443a but the behavior
+  was unintentionally removed in curl-7_38_0-47-gfa7d04f.
+  
+  This commit restores the original behavior and clarifies it in the
+  documentation that NULL and "" have both the same meaning when passed
+  to CURLOPT_SSH_PUBLIC_KEYFILE.
+  
+  Bug: http://curl.haxx.se/mail/lib-2016-01/0072.html
+
+Daniel Stenberg (14 Jan 2016)
+- RELEASE-NOTES: synced with 35083ca60ed035a
+
+- openssl: improved error detection/reporting
+  
+  ... by extracting the LIB + REASON from the OpenSSL error code. OpenSSL
+  1.1.0+ returned a new func number of another cerfificate fail so this
+  required a fix and this is the better way to catch this error anyway.
+
+- openssl: for 1.1.0+ they now provide a SSLeay() macro of their own
+
+- CURLOPT_RESOLVE.3: minor language polish
+
+- configure: assume IPv6 works when cross-compiled
+  
+  The configure test uses AC_TRY_RUN to figure out if an ipv6 socket
+  works, and testing like that doesn't work for cross-compiles. These days
+  IPv6 support is widespread so a blind guess is probably more likely to
+  be 'yes' than 'no' now.
+  
+  Further: anyone who cross-compiles can use configure's --disable-ipv6 to
+  explicitly disable IPv6 and that also works for cross-compiles.
+  
+  Made happen after discussions in issue #594
+
+- TODO: "Try to URL encode given URL"
+  
+  Closes #514
+
+- ConnectionExists: only do pipelining/multiplexing when asked
+  
+  When an HTTP/2 upgrade request fails (no protocol switch), it would
+  previously detect that as still possible to pipeline on (which is
+  acorrect) and do that when PIPEWAIT was enabled even if pipelining was
+  not explictily enabled.
+  
+  It should only pipelined if explicitly asked to.
+  
+  Closes #584
+
+- [Mohammad AlSaleh brought this change]
+
+  lib: Prefix URLs with lower-case protocol names/schemes
+  
+  Before this patch, if a URL does not start with the protocol
+  name/scheme, effective URLs would be prefixed with upper-case protocol
+  names/schemes. This behavior might not be expected by library users or
+  end users.
+  
+  For example, if `CURLOPT_DEFAULT_PROTOCOL` is set to "https". And the
+  URL is "hostname/path". The effective URL would be
+  "HTTPS://hostname/path" instead of "https://hostname/path".
+  
+  After this patch, effective URLs would be prefixed with a lower-case
+  protocol name/scheme.
+  
+  Closes #597
+  
+  Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
+
+- [Alessandro Ghedini brought this change]
+
+  scripts: don't generate and install zsh completion when cross-compiling
+
+- [Alessandro Ghedini brought this change]
+
+  scripts: fix zsh completion generation
+  
+  The script should use the just-built curl, not the system one. This fixes
+  zsh completion generation when no system curl is installed.
+
+- [Alessandro Ghedini brought this change]
+
+  zsh.pl: fail if no curl is found
+  
+  Instead of generation a broken completion file.
+
+- [Michael Kaufmann brought this change]
+
+  IDN host names: Remove the port number before converting to ACE
+  
+  Closes #596
+
+Jay Satiro (10 Jan 2016)
+- runtests: Add mbedTLS to the SSL backends
+  
+  .. and enable SSLpinning tests for mbedTLS, BoringSSL and LibreSSL.
+
+Daniel Stenberg (10 Jan 2016)
+- [Thomas Glanzmann brought this change]
+
+  mbedtls: implement CURLOPT_PINNEDPUBLICKEY
+
+Jay Satiro (9 Jan 2016)
+- [Tatsuhiro Tsujikawa brought this change]
+
+  url: Fix compile error with --enable-werror
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Ensure that http2_handle_stream_close is called
+  
+  Previously, when HTTP/2 is enabled and used, and stream has content
+  length known, Curl_read was not called when there was no bytes left to
+  read. Because of this, we could not make sure that
+  http2_handle_stream_close was called for every stream. Since we use
+  http2_handle_stream_close to emit trailer fields, they were
+  effectively ignored. This commit changes the code so that Curl_read is
+  called even if no bytes left to read, to ensure that
+  http2_handle_stream_close is called for every stream.
+  
+  Discussed in https://github.com/bagder/curl/pull/564
+
+Daniel Stenberg (8 Jan 2016)
+- http2: handle the received SETTINGS frame
+  
+  This regression landed in 5778e6f5 and made libcurl not act on received
+  settings and instead stayed with its internal defaults.
+  
+  Bug: http://curl.haxx.se/mail/lib-2016-01/0031.html
+  Reported-by: Bankde
+
+- Revert "multiplex: allow only once HTTP/2 is actually used"
+  
+  This reverts commit 46cb70e9fa81c9a56de484cdd7c5d9d0d9fbec36.
+  
+  Bug: http://curl.haxx.se/mail/lib-2016-01/0031.html
+
+Jay Satiro (8 Jan 2016)
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Fix PUSH_PROMISE headers being treated as trailers
+  
+  Discussed in https://github.com/bagder/curl/pull/564
+
+Daniel Stenberg (8 Jan 2016)
+- [Michael Kaufmann brought this change]
+
+  connection reuse: IDN host names fixed
+  
+  Use the ACE form of IDN hostnames as key in the connection cache.  Add
+  new tests.
+  
+  Closes #592
+
+- tests: mark IPv6 FTP and FTPS tests with the FTP keyword
+
+Jay Satiro (7 Jan 2016)
+- mbedtls: Fix ALPN support
+  
+  - Fix ALPN reply detection.
+  
+  - Wrap nghttp2 code in ifdef USE_NGHTTP2.
+  
+  
+  Prior to this change ALPN and HTTP/2 did not work properly in mbedTLS.
+
+- http2: Fix client write for trailers on stream close
+  
+  Check that the trailer buffer exists before attempting a client write
+  for trailers on stream close.
+  
+  Refer to comments in https://github.com/bagder/curl/pull/564
+
+Daniel Stenberg (7 Jan 2016)
+- COPYING: update general copyright year range
+
+- ConnectionExists: add missing newline in infof() call
+  
+  Mistake from commit a464f33843ee1
+
+- multiplex: allow only once HTTP/2 is actually used
+  
+  To make sure curl doesn't allow multiplexing before a connection is
+  upgraded to HTTP/2 (like when Upgrade: h2c fails), we must make sure the
+  connection uses HTTP/2 as well and not only check what's wanted.
+  
+  Closes #584
+  
+  Patch-by: c0ff
+
+Jay Satiro (4 Jan 2016)
+- curl_global_init.3: Add Windows-specific info for init via DLL
+  
+  - Add to both curl_global_init.3 and libcurl.3 the caveat for Windows
+  that initializing libcurl via a DLL's DllMain or static initializer
+  could cause a deadlock.
+  
+  Bug: https://github.com/bagder/curl/issues/586
+  Reported-by: marc-groundctl@users.noreply.github.com
+
+Daniel Stenberg (4 Jan 2016)
+- FAQ: clarify who to mail about ECCN clarifications
+
+- progressfunc.c: spellfix description
+
+- docs/examples/multi-app.c: fix bad desc formatting
+
+- examples: added descriptions
+
+- example/simple.c: add description
+
+- getredirect.c: a new example
+
+Marc Hoersken (27 Dec 2015)
+- RELEASE-NOTES: add 5e0e81a9c4e35f04ca
+
+Daniel Stenberg (26 Dec 2015)
+- RELEASE-NOTES: synced with 2aec4359db1088b10d
+
+Marc Hoersken (26 Dec 2015)
+- test 1515: add data check
+
+- test 1515: add MSYS support by passing a relative path
+  
+  MSYS would otherwise turn a /-style path into a C:\-style path.
+
+- test 539: use datacheck mode text for ASCII-mode LISTings
+  
+  While still using datacheck mode binary for the inline reply data.
+
+- runtests.pl: check up to 5 data parts with different text modes
+  
+  Move the text-mode conversion for reply/replycheck from the verify
+  section into the load section and add support for 4 more check parts.
+
+Daniel Stenberg (24 Dec 2015)
+- CURLOPT_RANGE: for HTTP servers, range support is optional
+
+Marc Hoersken (24 Dec 2015)
+- tests 1048 and 1050: use datacheck mode text for ASCII-mode LISTings
+
+- tests 706 and 707: use datacheck mode text for ASCII-mode LISTings
+
+- tests 400,403,406: use datacheck mode text for ASCII-mode LISTings
+
+- sockfilt.c: fix calculation of sleep timeout on Windows
+  
+  Not converting to double caused small timeouts to be skipped.
+
+- tests first.c: fix calculation of sleep timeout on Windows
+  
+  Not converting to double caused small timeouts to be skipped.
+
+- test 573: add more debug output
+
+- ftplistparser.c: fix handling of file LISTings using Windows EOL
+  
+  Previously file.txt[CR][LF] would have been returned as file.tx
+  (without the last t) if filetype is symlink. Now the t is
+  included and the internal item_length includes the zero byte.
+  
+  Spotted using test 576 on Windows.
+
+- test 16: fix on Linux (and Windows) by using plain ASCII characters
+  
+  Follow up on b064ff0c351bb287557228575ef4c1d079b866fb, thanks Daniel.
+
+- tftpd server: add Windows support by writing files in binary mode
+
+- tests 252-255: use datacheck mode text for ASCII-mode LISTings
+
+- test 16: fix on Windows by converting data file from ANSI to UTF-8
+
+Daniel Stenberg (23 Dec 2015)
+- Makefile.inc: s/curl_SOURCES/CURL_FILES
+  
+  This allows the root Makefile.am to include the Makefile.inc without
+  causing automake to warn on it (variables named *_SOURCES are
+  magic). curl_SOURCES is then instead assigned properly in
+  src/Makefile.am only.
+  
+  Closes #577
+
+- [Anders Bakken brought this change]
+
+  ConnectionExists: with *PIPEWAIT, wait for connections
+  
+  Try harder to prevent libcurl from opening up an additional socket when
+  CURLOPT_PIPEWAIT is set. Accomplished by letting ongoing TCP and TLS
+  handshakes complete first before the decision is made.
+  
+  Closes #575
+
+- [Anders Bakken brought this change]
+
+  Add .dir-locals and set c-basic-offset to 2.
+  
+  This makes it easier for emacs users to automatically get the right
+  2-space indentation when they edit curl source files.
+  
+  c++-mode is in there as well because Emacs can't easily know if
+  something is a C or C++ header.
+  
+  Closes #574
+
+- [Johannes Schindelin brought this change]
+
+  configure: detect IPv6 support on Windows
+  
+  This patch was "nicked" from the MINGW-packages project by Daniel.
+  
+  https://github.com/Alexpux/MINGW-packages/commit/9253d0bf58a1486e91f7efb5316e7fdb48fa4007
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- configure: allow static builds on mingw
+  
+  This patch is adopted from the MINGW-packages project. It makes it
+  possible to build curl both shared and static again.
+  
+  URL: https://github.com/Alexpux/MINGW-packages/tree/master/mingw-w64-curl
+
+Marc Hoersken (17 Dec 2015)
+- test 1326: fix file check since curl is outputting binary data
+
+- test 1326: fix getting stuck on Windows due to incomplete request
+  
+  The request needs to be read and send in binary mode in order to use
+  CRLF instead of LF. Adding --upload-file - causes curl to read stdin
+  in binary mode.
+
+Daniel Stenberg (17 Dec 2015)
+- RELEASE-NOTES: command line option recount
+
+Dan Fandrich (16 Dec 2015)
+- scripts/Makefile: build zsh script even in an out-of-tree build
+
+Marc Hoersken (16 Dec 2015)
+- sockfilt.c: added some debug output to select_ws
+
+- sockfilt.c: keep lines shorter than 80 chars
+
+- sockfilt.c: do not wait on unreliable file or pipe handle
+  
+  The previous implementation caused issues on modern MSYS2 runtimes.
+
+Daniel Stenberg (16 Dec 2015)
+- cyassl: deal with lack of *get_peer_certificate
+  
+  The function is only present in wolfssl/cyassl if it was built with
+  --enable-opensslextra. With these checks added, pinning support is disabled
+  unless the TLS lib has that function available.
+  
+  Also fix the mistake in configure that checks for the wrong lib name.
+  
+  Closes #566
+
+- wolfssl: handle builds without SSLv3 support
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Support trailer fields
+  
+  This commit adds trailer support in HTTP/2.  In HTTP/1.1, chunked
+  encoding must be used to send trialer fields.  HTTP/2 deprecated any
+  trandfer-encoding, including chunked.  But trailer fields are now
+  always available.
+  
+  Since trailer fields are relatively rare these days (gRPC uses them
+  extensively though), allocating buffer for trailer fields is done when
+  we detect that HEADERS frame containing trailer fields is started.  We
+  use Curl_add_buffer_* functions to buffer all trailers, just like we
+  do for regular header fields.  And then deliver them when stream is
+  closed.  We have to be careful here so that all data are delivered to
+  upper layer before sending trailers to the application.
+  
+  We can deliver trailer field one by one using NGHTTP2_ERR_PAUSE
+  mechanism, but current method is far more simple.
+  
+  Another possibility is use chunked encoding internally for HTTP/2
+  traffic.  I have not tested it, but it could add another overhead.
+  
+  Closes #564
+
+- RELEASE-NOTES: synced with 6c2c019654e658a
+
+Jay Satiro (15 Dec 2015)
+- x509asn1: Fix host altname verification
+  
+  - In Curl_verifyhost check all altnames in the certificate.
+  
+  Prior to this change only the first altname was checked. Only the GSKit
+  SSL backend was affected by this bug.
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-12/0062.html
+  Reported-by: John Kohl
+
+Daniel Stenberg (15 Dec 2015)
+- curl --expect100-timeout: added
+  
+  This is the new command line option to set the value for the existing
+  libcurl option CURLOPT_EXPECT_100_TIMEOUT_MS
+
+- cyassl: fix compiler warning on type conversion
+
+- curlver: the pending release will become 7.47.0
+
+- [Anders Bakken brought this change]
+
+  setstropt: const-correctness
+  
+  Closes #565
+
+- ROADMAP: implemented HTTP2 for HTTPS-only
+
+- HTTP2.md: spell fix and remove TODO now implemented
+
+- libressl: the latest openssl x509 funcs are not in libressl
+
+- curl: use 2TLS by default
+  
+  Make this the default for the curl tool (if built with HTTP/2 powers
+  enabled) unless a specific HTTP version is requested on the command
+  line.
+  
+  This should allow more users to get HTTP/2 powers without having to
+  change anything.
+
+- http: add libcurl option to allow HTTP/2 for HTTPS only
+  
+  ... and stick to 1.1 for HTTP. This is in line with what browsers do and
+  should have very little risk.
+
+- openssl: adapt to openssl >= 1.1.0 X509 opaque structs
+  
+  Closes #491
+
+- openssl: avoid BIO_reset() warnings since it returns a value
+
+- openssl: adapt to 1.1.0+ name changes
+
+- scripts/makefile: add standard header
+
+- scripts/Makefile: fix GNUism and survive no perl
+  
+  Closes #555
+  
+  Reported-by: Thomas Klausner
+
+- fix b6d5cb40d7038fe
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Fix hanging paused stream
+  
+  When NGHTTP2_ERR_PAUSE is returned from data_source_read_callback, we
+  might not process DATA frame fully.  Calling nghttp2_session_mem_recv()
+  again will continue to process DATA frame, but if there is no incoming
+  frames, then we have to call it again with 0-length data.  Without this,
+  on_stream_close callback will not be called, and stream could be hanged.
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-11/0103.html
+  Reported-by: Francisco Moraes
+
+- [Christian Stewart brought this change]
+
+  build: fix compilation error with CURL_DISABLE_VERBOSE_STRINGS
+  
+  With curl disable verbose strings in http.c the compilation fails due to
+  the data variable being undefined later on in the function.
+  
+  Closes #558
+
+Jay Satiro (7 Dec 2015)
+- [Gisle Vanem brought this change]
+
+  config-win32: Fix warning HAVE_WINSOCK2_H undefined
+
+- [Gisle Vanem brought this change]
+
+  openssl: BoringSSL doesn't have CONF_modules_free
+
+- [Gisle Vanem brought this change]
+
+  lwip: Fix compatibility issues with later versions
+  
+  The name of the header guard in lwIP's <lwip/opt.h> has changed from
+  '__LWIP_OPT_H__' to 'LWIP_HDR_OPT_H' (bug #35874 in May 2015).
+  
+  Other fixes:
+  
+  - In curl_setup.h, the problem with an old PSDK doesn't apply if lwIP is
+  used.
+  
+  - In memdebug.h, the 'socket' should be undefined first due to lwIP's
+  lwip_socket() macro.
+  
+  - In curl_addrinfo.c lwIP's getaddrinfo() + freeaddrinfo() macros need
+  special handling because they were undef'ed in memdebug.h.
+  
+  - In select.c we can't use preprocessor conditionals inside select if
+  MSVC and select is a macro, as it is with lwIP.
+  
+  http://curl.haxx.se/mail/lib-2015-12/0023.html
+  http://curl.haxx.se/mail/lib-2015-12/0024.html
+
+Patrick Monnerat (7 Dec 2015)
+- os400: define CURL_VERSION_PSL in ILE/RPG binding
+
+Jay Satiro (7 Dec 2015)
+- [Gisle Vanem brought this change]
+
+  version: Add flag CURL_VERSION_PSL for libpsl
+
+- formdata: Check if length is too large for memory
+  
+  - If the size of the length type (curl_off_t) is greater than the size
+  of the size_t type then check before allocating memory to make sure the
+  value of length will fit in a size_t without overflow. If it doesn't
+  then return CURLE_BAD_FUNCTION_ARGUMENT.
+  
+  Bug: https://github.com/bagder/curl/issues/425#issuecomment-154518679
+  Reported-by: Steve Holme
+
+Steve Holme (3 Dec 2015)
+- tests: Corrected copy and pasted comments from commit e643c5c908
+
+Daniel Stenberg (3 Dec 2015)
+- curl: remove keepalive #ifdef checks done on libcurl's behalf
+  
+  They didn't match the ifdef logic used within libcurl anyway so they
+  could indeed warn for the wrong case - plus the tool cannot know how the
+  lib actually performs at that level.
+
+Steve Holme (2 Dec 2015)
+- test947: Corrected typo in test name
+
+- tests: Disable the OAUTHBEARER tests when using a non-default port number
+  
+  Tests 842, 843, 844, 845, 887, 888, 889, 890, 946, 947, 948 and 949 fail
+  if a custom port number is specified via the -b option of runtests.pl.
+  
+  Suggested by: Kamil Dudka
+  Bug: http://curl.haxx.se/mail/lib-2015-12/0003.html
+
+Daniel Stenberg (2 Dec 2015)
+- bump: towards next release
+  
+  for all we know now, it might be called 7.46.1
+
+Version 7.46.0 (1 Dec 2015)
+
+Daniel Stenberg (1 Dec 2015)
+- RELEASE-NOTES: updated contributor count for 7.46.0
+
+- THANKS: new contributors from the 7.46.0 release
+
+- THANKS-filter: single Tim RÃ¼hsen spelling
+
+- docs/examples: gitignore some more built examples
+
+- RELEASE-NOTES; this bug was never released
+
+- RELEASE-NOTES: synced with e55f15454efacb0
+
+- [Flavio Medeiros brought this change]
+
+  Curl_read_plain: clean up ifdefs that break statements
+  
+  Closes #546
+
+- http2: convert some verbose output into debug-only output
+
+- http2 push: add missing inits of new stream
+  
+  - set the correct stream_id for pushed streams
+  - init maxdownload and size properly
+
+- http2 push: set weight for new stream
+  
+  give the new stream the old one's stream_weight internally to avoid
+  sending a PRIORITY frame unless asked for it
+
+- curl_setup.h: undef freeaddrinfo in c-ares block to fix build
+  
+  Fixes warnings 78c25c854a added.
+
+- nonblock: fix setting non-blocking mode for Amiga
+  
+  IoctlSocket() apparently wants a pointer to a long, passed as a char *
+  in its third parameter. This bug was introduced already back in commit
+  c5fdeef41d from October 1 2001!
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-11/0088.html
+  Reported-by: Norbert Kett
+
+- zsh install: fix DESTDIR support
+  
+  Reported-by: Mohammad AlSaleh
+
+Dan Fandrich (27 Nov 2015)
+- lib: Only define curl_dofreeaddrinfo if struct addrinfo is available
+
+Steve Holme (27 Nov 2015)
+- tool_paramhlp: Fixed display of URL index in password prompt for --next
+  
+  Commit f3bae6ed73 added the URL index to the password prompt when using
+  --next. Unfortunately, because the size_t specifier (%zu) is not
+  supported by all sprintf() implementations we use the curl_off_t format
+  specifier instead. The display of an incorrect value arises on platforms
+  where size_t and curl_off_t are of a different size.
+
+Daniel Stenberg (25 Nov 2015)
+- timecond: do not add if-modified-since without timecondition
+  
+  The RTSP code path didn't skip adding the if-modified-since for certain
+  RTSP code paths, even if CURLOPT_TIMECONDITION was set to
+  CURL_TIMECOND_NONE.
+  
+  Also, an unknown non-zero CURLOPT_TIMECONDITION value no longer equals
+  CURL_TIMECOND_IFMODSINCE.
+  
+  Bug: http://stackoverflow.com/questions/33903982/curl-timecond-none-doesnt-work-how-to-remove-if-modified-since-header
+
+- RELEASE-NOTES: synced with 99d17a5e2ba77e58
+
+- examples/README: cut out the incomplete list
+  
+  ... and add a generic explanation for them instead. Each example file
+  should contain its own description these days.
+
+- test1513: make sure the callback is only called once
+
+- [Daniel Shahaf brought this change]
+
+  build: Install zsh completion
+  
+  Fixes #534
+  Closes #537
+
+- done: make sure the final progress update is made
+  
+  It would previously be skipped if an existing error was returned, but
+  would lead to a previous value being left there and later used.
+  CURLINFO_TOTAL_TIME for example.
+  
+  Still it avoids that final progress update if we reached DONE as the
+  result of a callback abort to avoid another callback to be called after
+  an abort-by-callback.
+  
+  Reported-by: Lukas Ruzicka
+  
+  Closes #538
+
+- curl: expanded the -XHEAD warning text
+  
+  ... to also mention the specific options used.
+
+- Revert "cleanup: general removal of TODO (and similar) comments"
+  
+  This reverts commit 64e959ffe37c436503f9fed1ce2d6ee6ae50bd9a.
+  
+  Feedback-by: Dan Fandrich
+  URL: http://curl.haxx.se/mail/lib-2015-11/0062.html
+
+- CURLOPT_HEADERFUNCTION.3: fix typo
+  
+  Refer to _HEADERDATA not _WRITEDATA.
+  
+  Reported-by: MichaÅ Piechowski
+
+- TODO: TCP Fast Open
+
+Steve Holme (22 Nov 2015)
+- examples: Added website parse-able descriptions to the e-mail examples
+
+- TODO: Added another 'multi-interface' idea
+
+- smb.c: Fixed compilation warnings
+  
+  smb.c:134:3: warning: conversion to 'short unsigned int' from 'int' may
+               alter its value
+  smb.c:146:42: warning: conversion to 'unsigned int' from 'long long
+                unsigned int' may alter its value
+  smb.c:146:65: warning: conversion to 'unsigned int' from 'long long
+                unsigned int' may alter its value
+
+- schannel: Corrected copy/paste error in commit 8d17117683
+
+- schannel: Use GetVersionEx() when VerifyVersionInfo() isn't available
+  
+  Regression from commit 7a8e861a5 as highlighted in the msys autobuilds.
+
+- examples: Fixed compilation warnings
+  
+  pop3-multi.c:96:5: warning: implicit declaration of function 'memset'
+  imap-multi.c:96:5: warning: implicit declaration of function 'memset'
+  http2-download.c:226:5: warning: implicit declaration of function 'memset'
+  http2-upload.c:290:5: warning: implicit declaration of function 'memset'
+  http2-upload.c:290:5: warning: implicit declaration of function 'memset'
+
+- Makefile.inc: Fixed test run error
+  
+  test845 not present in tests/data/Makefile.inc
+
+Daniel Stenberg (20 Nov 2015)
+- TODO: remove duplicated title
+
+- TODO: added two more libcurl ideas
+  
+  Moved some ideas from "next major" to just ordinary ideas since we can
+  always add new things while keeping the old without doing a "next
+  major".
+
+Steve Holme (20 Nov 2015)
+- tests: Re-enabled tests 889 and 890 following POP3 fix
+
+- pop3: Differentiate between success and continuation responses
+
+- pop3: Added clarity on some server response codes
+
+Daniel Stenberg (20 Nov 2015)
+- [Daniel Shahaf brought this change]
+
+  build: Fix theoretical infinite loops
+  
+  Add error-checking to 'cd' in a few cases where omitting the checks
+  might result in an infinite loop.
+  
+  Closes #535
+
+Patrick Monnerat (19 Nov 2015)
+- curl.h: s/#defien/#define/
+
+- os400: synchronize ILE/RPG header file
+
+- os400: Provide options for libssh2 use in compile scripts. Adjust README.
+
+Daniel Stenberg (19 Nov 2015)
+- [danielsh@apache.org brought this change]
+
+  zsh completion: Preserve single quotes in output
+  
+  When an option's help string contains literal single quotes, those
+  single quotes would be stripped from the option's description in the
+  completion output (unless the zsh RC_QUOTES option were set while the
+  completion function was being sourced, which is not the default).  This
+  patch makes the completion output contain single quotes where the --help
+  output does.
+  
+  Closes #532
+
+Jay Satiro (18 Nov 2015)
+- [MaxGiting brought this change]
+
+  FAQ: Grammar changes
+  
+  Closes https://github.com/bagder/curl/pull/533
+
+Daniel Stenberg (17 Nov 2015)
+- http2: http_done: don't free already-freed push headers
+  
+  The push headers are freed after the push callback has been invoked,
+  meaning this code should only free the headers if the callback was never
+  invoked and thus the headers weren't freed at that time.
+  
+  Reported-by: Davey Shafik
+
+- [Anders Bakken brought this change]
+
+  getconnectinfo: Don't call recv(2) if socket == -1
+  
+  Closes #528
+
+- CURLMOPT_PUSHFUNCTION.3: *_byname() returns only the first header
+  
+  ... if there are more than one using the same name
+
+- http2: minor comment typo
+
+- sasl; fix checksrc warnings
+
+Steve Holme (15 Nov 2015)
+- RELEASE-NOTES: Adjusted for the recent OAuth 2.0 activity
+
+- tests: Disabled 889 and 890 until we support POP3 continuation responses
+  
+  As POP3 final and continuation responses both begin with a + character,
+  and both the finalcode and contcode variables in SASLprotoc are set as
+  such, we cannot tell the difference between them when we are expecting
+  an optional continuation from the server such as the following:
+  
+  + something else from the server
+  +OK final response
+  
+  Disabled these tests until such a time we can tell the responses apart.
+
+- tests: Corrected typos from commit ba4d8f7eba
+
+- tests: Added OAUTHBEARER failure response tests
+
+- oauth2: Support OAUTHBEARER failures sent as continuation responses
+  
+  According to RFC7628 a failure message may be sent by the server in a
+  base64 encoded JSON string as a continuation response.
+  
+  Currently only implemented for OAUTHBEARER and not XAUTH2.
+
+Daniel Stenberg (15 Nov 2015)
+- RELEASE-NOTES: synced with 808a17ee675
+
+Steve Holme (14 Nov 2015)
+- tests: Renamed existing OAuth 2.0 (XOAUTH) tests
+
+- tests: Added OAuth 2.0 (OAUTHBEARER) tests
+
+- oauth2: Added support for OAUTHBEARER SASL mechanism to IMAP, POP3 and SNMP
+  
+  OAUTHBEARER is now the official "registered" SASL mechanism name for
+  OAuth 2.0. However, we don't want to drop support for XOAUTH2 as some
+  servers won't support the new mechanism yet.
+
+Daniel Stenberg (13 Nov 2015)
+- RELEASE-NOTES: recounted curl_easy_setopt() options
+
+- typecheck-gcc.h: add missing slist-using options
+  
+  CURLOPT_RESOLVE and CURLOPT_PROXYHEADER were missing
+  
+  Also sorted the list.
+
+- typecheck-gcc.h: added CURLOPT_CLOSESOCKETDATA
+  
+  ... and sorted curl_is_cb_data_option alphabetically
+
+Jay Satiro (13 Nov 2015)
+- [Sebastian Pohlschmidt brought this change]
+
+  openssl: Free modules on cleanup
+  
+  Curl_ossl_init calls OPENSSL_load_builtin_modules() but
+  Curl_ossl_cleanup doesn't make a call to free these modules.
+  
+  Bug: https://github.com/bagder/curl/issues/526
+
+Steve Holme (13 Nov 2015)
+- symbols-in-versions: Added new CURLOPTTYPE_STRINGPOINT alias
+  
+  ...following commit aba281e762 to fix test 1119.
+
+Daniel Stenberg (13 Nov 2015)
+- curl: mark two more options strings for --libcurl output
+
+- typecheck-gcc.h: add some missing string types
+  
+  Also sorted that list alphabetically
+
+- curl.h: introducing the STRINGPOINT alias
+  
+  As an alias for OBJECTPOINT. Provided to allow us to grep for all string
+  options easier.
+
+- cleanup: general removal of TODO (and similar) comments
+  
+  They tend to never get updated anyway so they're frequently inaccurate
+  and we never go back to revisit them anyway. We document issues to work
+  on properly in KNOWN_BUGS and TODO instead.
+
+- ftplistparser: remove empty function
+
+- openssl: remove #if check for 0.9.7 for ENGINE_load_private_key
+
+- openssl: all supported versions have X509_STORE_set_flags
+  
+  Simplify by removing #ifdefs and macros
+
+- openssl: remove 0.9.3 check
+
+- openssl: remove #ifdefs for < 0.9.5 support
+  
+  We only support >= 0.9.7
+
+- lib/vtls/openssl: remove unused traces of yassl ifdefs
+
+Dan Fandrich (12 Nov 2015)
+- [dfandrich brought this change]
+
+  unit1603: Demote hash mismatch failure to a warning
+  
+  The hashes can vary between architectures (e.g. Sparc differs from x86_64).
+  This is not a fatal problem but just reduces the coverage of these white-box
+  tests, as the assumptions about into which hash bucket each key falls are no
+  longer valid.
+
+- [dfandrich brought this change]
+
+  unit1603: Added unit tests for hash functions
+
+- [dfandrich brought this change]
+
+  unit1602: Fixed failure in torture test
+
+Steve Holme (12 Nov 2015)
+- sasl: Re-introduced XOAUTH2 in the default enabled authentication mechanism
+  
+  Following the fix in commit d6d58dd558 it is necessary to re-introduce
+  XOAUTH2 in the default enabled authentication mechanism, which was
+  removed in commit 7b2012f262, otherwise users will have to specify
+  AUTH=XOAUTH2 in the URL.
+  
+  Note: OAuth 2.0 will only be used when the bearer is specified.
+
+- [Stefan BÃ¼hler brought this change]
+
+  sasl_sspi: fix identity memory leak in digest authentication
+
+- [Stefan BÃ¼hler brought this change]
+
+  sasl_sspi: fixed unicode build for digest authentication
+  
+  Closes #525
+
+- oauth2: Re-factored OAuth 2.0 state variable
+
+- sasl: Don't choose OAuth 2.0 if mechanism not advertised
+  
+  Regression from commit 9e8ced9890 which meant if --oauth2-bearer was
+  specified but the SASL mechanism wasn't supported by the server then
+  the mechanism would be chosen.
+
+Daniel Stenberg (12 Nov 2015)
+- runtests: more compact "System characteristics" output
+  
+  - no point in repeating curl features that is already listed as features
+    from the curl -V output
+  
+  - remove the port numbers/unix domain path from the output unless
+    verbose is used, as that is rarely interesting to users.
+
+- runtests: rename conditional curl-features to $has_[name]
+
+Steve Holme (11 Nov 2015)
+- oauth2: Introduced support for host and port details
+  
+  Added support to the OAuth 2.0 message function for host and port, in
+  order to accommodate the official OAUTHBEARER SASL mechanism which is
+  to be added shortly.
+
+- curl_setup.h: Removed duplicate CURL_DISABLE_RTSP when HTTP_ONLY defined
+
+- cmake: Add missing feature macros in config header (Part 2)
+  
+  In addition to commit a215381c94 added the RTSP, RTMP and SMB protocols.
+
+Daniel Stenberg (10 Nov 2015)
+- [Douglas Creager brought this change]
+
+  cmake: Add missing feature macros in config header
+  
+  The curl_config.h file can be generated either from curl_config.h.cmake
+  or curl_config.h.in, depending on whether you're building using CMake or
+  the autotools.  The CMake template header doesn't include entries for
+  all of the protocols that you can disable, which (I think) means that
+  you can't actually disable those protocols when building via CMake.
+  
+  Closes #523
+
+- [Douglas Creager brought this change]
+
+  BoringSSL: Work with stricter BIO_get_mem_data()
+  
+  BoringSSL implements `BIO_get_mem_data` as a function, instead of a
+  macro, and expects the output pointer to be a `char **`.  We have to add
+  an explicit cast to grab the pointer as a `const char **`.
+  
+  Closes #524
+
+- http2: rectify the http2 version #if check
+  
+  We need 1.0.0 or later. Also verified by configure.
+
+Steve Holme (9 Nov 2015)
+- oauth2: Don't use XAUTH2 in OAuth 2.0 function name
+
+- oauth2: Don't use XOAUTH2 in OAuth 2.0 variables
+
+- oauth2: Use OAuth 2.0 rather than XOAUTH2 in comments
+  
+  When referring to OAuth 2.0 we should use the official name rather the
+  SASL mechanism name.
+
+Daniel Stenberg (9 Nov 2015)
+- imap: avoid freeing constant string
+  
+  The fix in 1a614c6c3 was wrong and would leed to free() of a fixed
+  string.
+  
+  Pointed-out-by: Kamil Dudka
+
+- ROADMAP: remove two items already done
+
+- RELEASE-NOTES: synced with 2200bf62054
+
+Jay Satiro (9 Nov 2015)
+- acinclude: Remove check for 16-bit curl_off_t
+  
+  Because it's illogical to check for a 16-bit curl_off_t.
+  
+  Ref: https://github.com/bagder/curl/issues/425#issuecomment-154964205
+
+Dan Fandrich (8 Nov 2015)
+- tool: Fixed a memory leak on OOM introduced in 19cb0c4a
+
+Steve Holme (8 Nov 2015)
+- [Justin Ehlert brought this change]
+
+  imap: Don't check for continuation when executing a CUSTOMREQUEST
+  
+  Bug: https://github.com/bagder/curl/issues/486
+  Closes https://github.com/bagder/curl/pull/487
+
+Daniel Stenberg (7 Nov 2015)
+- imap: checksrc: remove space after while before paren
+
+- checksrc.whitelist: "missing space after close paren"
+  
+  ... when it was within a string!
+
+Steve Holme (7 Nov 2015)
+- opts: Corrected TLS protocols list to include POP3S rather than POP3
+
+- imap: Quote other 'atom-specials' and not just the space character
+  
+  Closes #517
+
+- imap: Fixed double quote in LIST command when mailbox contains spaces
+
+Daniel Stenberg (6 Nov 2015)
+- imap: fix compiler warning
+  
+  imap.c:657:13: error: assignment discards 'const' qualifier from pointer
+  target type [-Werror=discarded-qualifiers]
+
+Steve Holme (6 Nov 2015)
+- imap: Don't call imap_atom() when no mailbox specified in LIST command
+
+Daniel Stenberg (6 Nov 2015)
+- curl.1: remove the overlap --range example
+  
+  ... it is just weird to include by default even if it still works.
+
+- tftp tests: verify sent options too
+  
+  The tftpd test server now logs all received options and thus all TFTP
+  test cases need to match them exactly.
+  
+  Extended test 283 to use and verify --tftp-blksize.
+
+Jay Satiro (6 Nov 2015)
+- getinfo: CURLINFO_ACTIVESOCKET: fix bad socket value
+  
+  - Set user info param to the socket returned by Curl_getconnectinfo,
+  regardless of if the socket is bad. Effectively this means the user info
+  param now will receive CURL_SOCKET_BAD instead of -1 on bad socket.
+  
+  - Remove incorrect comments.
+  
+  CURLINFO_ACTIVESOCKET is documented to write CURL_SOCKET_BAD to user
+  info param but prior to this change it wrote -1.
+  
+  Bug: https://github.com/bagder/curl/pull/518
+  Reported-by: Marcel Raad
+
+Patrick Monnerat (5 Nov 2015)
+- curl_ntlm_core: fix 2 curl_off_t constant overflows.
+
+- os400: adjust specific code to support new options.
+
+Daniel Stenberg (2 Nov 2015)
+- [Lauri Kasanen brought this change]
+
+  rawstr: Speed up Curl_raw_toupper by 40%
+  
+  Rationale: when starting up a curl-using app, all cookies from the jar
+  are checked against each other. This was causing a startup delay in the
+  Fifth browser.
+  
+  All tests pass.
+  
+  Signed-off-by: Lauri Kasanen <cand@gmx.com>
+
+- http redirects: %-encode bytes outside of ascii range
+  
+  Apparently there are sites out there that do redirects to URLs they
+  provide in plain UTF-8 or similar. Browsers and wget %-encode such
+  headers when doing a subsequent request. Now libcurl does too.
+  
+  Added test 1138 to verify.
+  
+  Closes #473
+
+- RELEASE-NOTES: synced with cba5bc585410
+
+- symbols-in-version: add all CURL_HTTPPOST_* symbols
+
+- formadd: support >2GB files on windows
+  
+  Closes #425
+
+- curl.h: s/HTTPPOST_/CURL_HTTPOST_
+  
+  Fixes a name space pollution at the cost of programs using one of these
+  defines will no longer compile. However, the vast majority of libcurl
+  programs that do multipart formposts use curl_formadd() to build this
+  list.
+  
+  Closes #506
+
+- mbedtls: fix "Structurally dead code"
+  
+  CID 1332129
+
+- mbedtls: fix "Logically dead code"
+  
+  CID 1332128
+
+- Revert "openssl: engine: remove double-free"
+  
+  This reverts commit 370ee919b37cc9a46c36428b2bb1527eae5db2bd.
+  
+  Issue #509 has all the details but it was confirmed that the crash was
+  not due to this, so the previous commit was wrong.
+
+- curl.1: -E: s/private certificate/client certificate
+  
+  ... as the certificate is strictly speaking not private.
+  
+  Reported-by: John Levon
+
+- openssl: engine: remove double-free
+  
+  After a successful call to SSL_CTX_use_PrivateKey(), we must not call
+  EVP_PKEY_free() on the key.
+  
+  Reported-by: nased0
+  Closes #509
+
+Jay Satiro (27 Oct 2015)
+- socks: Fix incorrect port numbers in failed connect messages
+
+Daniel Stenberg (26 Oct 2015)
+- DISTRO-DILEMMA: removed
+  
+  Out of date and not kept accurate. It was sort of a problem of the past
+  anyway.
+
+- [xiangbin li brought this change]
+
+  MacOSX-Framework: sdk regex fix for sdk 10.10 and later
+  
+  closes #507
+
+Jay Satiro (24 Oct 2015)
+- build: Fix support for PKG_CONFIG
+  
+  - Allow the user to use PKG_CONFIG but not PKGCONFIG.
+  
+  Background:
+  
+  Last week in 14d5a86 a change was made to allow the user to set the
+  PKGCONFIG variable. Today in 72d99f2 I supplemented that to allow the
+  more common PKG_CONFIG as an alternative if PKGCONFIG is not set.
+  
+  Neither of those changes worked as expected because PKGCONFIG is
+  occasionally reset in configure and by the CURL_CHECK_PKGCONFIG macro.
+  Instead in this commit I take the approach that the user may set
+  PKG_CONFIG only.
+
+- build: Fix mingw ssl gdi32 order
+  
+  - If mingw ssl make sure -lgdi32 comes after ssl libs
+  
+  - Allow PKG_CONFIG to set pkg-config location and options
+  
+  Bug: https://github.com/bagder/curl/pull/501
+  Reported-by: Kang Lin
+
+Daniel Stenberg (23 Oct 2015)
+- RELEASE-NOTES: synced with 03b6e078163f
+
+- polarssl/mbedtls: fix name space pollution
+  
+  Global private symbols MUST start with Curl_!
+
+- [Dmitry S. Baikov brought this change]
+
+  mbedTLS: THREADING_SUPPORT compilation fix
+  
+  Closes #505
+
+- test1137: verify --ignore-content-length for FTP
+
+- curl.1: --ignore-content-length now works for FTP too
+
+- [Kurt Fankhauser brought this change]
+
+  ftp: allow CURLOPT_IGNORE_CONTENT_LENGTH to ignore size
+  
+  This allows FTP transfers with growing (or shrinking) files without
+  causing a transfer error.
+  
+  Closes #480
+
+- CURLOPT_STREAM_WEIGHT.3: call argument 'weight' too
+  
+  ... and add a little example of what the weight actually means. "Relative
+  proportion of bandwidth".
+
+- http2: add stream options to dist and curl_easy_setopt.3
+
+- http2: s/priority/weight
+
+- http2: on_frame_recv: trust the conn/data input
+  
+  Removed wrong assert()s
+  
+  The 'conn' passed in as userdata can be used and there can be other
+  sessionhandles ('data') than the single one this checked for.
+
+- http2: added three stream prio/deps options
+  
+  CURLOPT_STREAM_DEPENDS
+  
+  CURLOPT_STREAM_DEPENDS_E
+  
+  CURLOPT_STREAM_PRIORITY
+
+- RELEASE-NOTES: synced with ace68fdc0cfed83d
+
+- [m-gardet brought this change]
+
+  mbedtls:new profile with RSA min key len = 1024.
+  
+  Closes #502
+
+- checksrc: add crude // detection
+
+Jay Satiro (21 Oct 2015)
+- [Gisle Vanem brought this change]
+
+  build: fix for MSDOS/djgpp
+  
+  - Add a VPATH-statement for the vtls/*.c files.
+  
+  - Due to 'vtls/*.c', remove that subdir part from $(OBJECTS).
+
+Daniel Stenberg (20 Oct 2015)
+- copyrights: update Gisle Vanem's email
+
+- vtls: fix compiler warning for TLS backends without sha256
+  
+  ... noticed with mbedTLS.
+
+- [Jonas Minnberg brought this change]
+
+  vtls: added support for mbedTLS
+  
+  closes #496
+
+Jay Satiro (19 Oct 2015)
+- [Javier G. Sogo brought this change]
+
+  cmake: Fix for add_subdirectory(curl) use-case
+  
+  - Use CURL_BINARY_DIR instead of CMAKE_BINARY_DIR.
+  
+  When including CURL using add_subdirectory the variables
+  CMAKE_BINARY_DIR and CURL_BINARY_DIR hold different paths.
+  
+  Closes https://github.com/bagder/curl/pull/488
+  Closes https://github.com/bagder/curl/pull/498
+
+Daniel Stenberg (18 Oct 2015)
+- RELEASE-NOTES: synced with 4c773bcb474e
+
+- tests/FILEFORMAT: mention PSL as a valid feture to check for
+  
+  For example in test 1136
+
+- teste1136: only run when PSL is enabled
+
+- curl: slist_wc: remove curl_memory.h inclusion
+  
+  ... that's for the library only.
+
+- configure: add PSL to the list of features
+  
+  ... to make test 1014 work again after e77b5b7453.
+
+- [Daniel Hwang brought this change]
+
+  tool: Generate easysrc with last cache linked-list
+  
+  Using a last cache linked-list improves the performance of easysrc
+  generation.
+  
+  Bug: https://github.com/bagder/curl/issues/444
+  Ref: https://github.com/bagder/curl/issues/429
+  
+  Closes #452
+
+- [Tim RÃ¼hsen brought this change]
+
+  cookies: Add support for Mozilla's Publix Suffix List
+  
+  Use libpsl to check the domain value of Set-Cookie headers (and cookie
+  jar entries) for not being a Publix Suffix.
+  
+  The configure script checks for "libpsl" by default. Disable the check
+  with --without-libpsl.
+  
+  Ref: https://publicsuffix.org/
+  Ref: https://github.com/publicsuffix/list
+  Ref: https://github.com/rockdaboot/libpsl
+
+- [Richard Hosking brought this change]
+
+  curlbuild.h: Fix non-configure compiling to mips and sh4 targets
+
+- [Anders Bakken brought this change]
+
+  http2: Don't pass unitialized name+len pairs to nghttp2_submit_request
+  
+  bug introduced by 18691642931e5c7ac8af83ac3a84fbcb36000f96.
+  
+  Closes #493
+
+Dan Fandrich (16 Oct 2015)
+- test1601: fix compilation with --enable-debug and --disable-crypto-auth
+
+Daniel Stenberg (16 Oct 2015)
+- multi: fix off-by-one finit[] array size
+  
+  introduced in c6aedf680f6. It needs to be CURLM_STATE_LAST big since it
+  must hande the range 0 .. CURLM_STATE_MSGSENT (18) and CURLM_STATE_LAST
+  is 19 right now.
+  
+  Reported-by: Dan Fandrich
+  Bug: http://curl.haxx.se/mail/lib-2015-10/0069.html
+
+- fread_func: move callback pointer from set to state struct
+  
+  ... and assign it from the set.fread_func_set pointer in the
+  Curl_init_CONNECT function. This A) avoids that we have code that
+  assigns fields in the 'set' struct (which we always knew was bad) and
+  more importantly B) it makes it impossibly to accidentally leave the
+  wrong value for when the handle is re-used etc.
+  
+  Introducing a state-init functionality in multi.c, so that we can set a
+  specific function to get called when we enter a state. The
+  Curl_init_CONNECT is thus called when switching to the CONNECT state.
+  
+  Bug: https://github.com/bagder/curl/issues/346
+  
+  Closes #346
+
+Dan Fandrich (14 Oct 2015)
+- test1531: case the size to fix the test on non-largefile builds
+
+Daniel Stenberg (13 Oct 2015)
+- acinclude: remove PKGCONFIG override
+  
+  ... and allow it to get set by a caller easier.
+  
+  Reported-by: Rainer Jung
+  Bug: http://curl.haxx.se/mail/lib-2015-10/0035.html
+
+Dan Fandrich (12 Oct 2015)
+- docs/INSTALL: Updated example minimal binary sizes
+
+Daniel Stenberg (11 Oct 2015)
+- [Erik Johansson brought this change]
+
+  openssl: Fix set up of pkcs12 certificate verification chain
+  
+  sk_X509_pop will decrease the size of the stack which means that the loop would
+  end after having added only half of the certificates.
+  
+  Also make sure that the X509 certificate is freed in case
+  SSL_CTX_add_extra_chain_cert fails.
+
+- ntlm: error out without 64bit support as the code needs it
+  
+  It makes it a clearer message for developers reaching that point without
+  the necessary support.
+  
+  Thanks-by: Jay Satiro
+  
+  Closes #78
+
+- curl_global_init: set the memory function pointers correct
+  
+  follow-up from 6f8ecea0
+
+- curl_global_init_mem: set function pointers before doing init
+  
+  ... as in the polarssl TLS backend for example it uses memory functions.
+
+Jay Satiro (9 Oct 2015)
+- http2: Fix http2_recv to return -1 if recv returned -1
+  
+  If the underlying recv called by http2_recv returns -1 then that is the
+  value http2_recv returns to the caller.
+
+Daniel Stenberg (8 Oct 2015)
+- [Svyatoslav Mishyn brought this change]
+
+  curl_easy_recv.3: CURLINFO_LASTSOCKET => CURLINFO_ACTIVESOCKET
+  
+  Closes #479
+
+- [Svyatoslav Mishyn brought this change]
+
+  curl_easy_send.3: CURLINFO_LASTSOCKET => CURLINFO_ACTIVESOCKET
+
+- [Svyatoslav Mishyn brought this change]
+
+  CURLOPT_CONNECT_ONLY.3: CURLINFO_LASTSOCKET => CURLINFO_ACTIVESOCKET
+
+- CURLOPT_CERTINFO.3: fix reference to CURLINFO_CERTINFO
+
+- ntlm: get rid of unconditional use of long long
+  
+  ... since some compilers don't have it and instead use other types, such
+  as __int64.
+  
+  Reported by: gkinseyhpw
+  Closes #478
+
+Jay Satiro (8 Oct 2015)
+- [Anders Bakken brought this change]
+
+  des: Fix header conditional for Curl_des_set_odd_parity
+  
+  Follow up to 613e502.
+
+Daniel Stenberg (7 Oct 2015)
+- configure: build silently by default
+  
+  'make V=1' will make the build verbose like before
+
+- bump: start climbing toward 7.46.0
+
+- RELEASE-PROCEDURE: add the github HTTPS download step
+
+Version 7.45.0 (7 Oct 2015)
+
+Daniel Stenberg (7 Oct 2015)
+- THANKS: 19 new contributors from the 7.45.0 announcement
+
+- RELEASE-NOTES: synced with 69ea57970080
+
+Jay Satiro (4 Oct 2015)
+- getinfo: Fix return code for unknown CURLINFO options
+  
+  - If a CURLINFO option is unknown return CURLE_UNKNOWN_OPTION.
+  
+  Prior to this change CURLE_BAD_FUNCTION_ARGUMENT was returned on
+  unknown. That return value is contradicted by the CURLINFO option
+  documentation which specifies a return of CURLE_UNKNOWN_OPTION on
+  unknown.
+
+- [rouzier brought this change]
+
+  hiperfifo: fix the pointer passed to WRITEDATA
+  
+  Closes https://github.com/bagder/curl/pull/471
+
+- [Maksim Stsepanenka brought this change]
+
+  tool_setopt: fix c_escape truncated octal
+  
+  Closes https://github.com/bagder/curl/pull/469
+
+Daniel Stenberg (1 Oct 2015)
+- [Orange Tsai brought this change]
+
+  gopher: don't send NUL byte
+  
+  Closes #466
+
+Jay Satiro (29 Sep 2015)
+- runtests: Fix pid check in checkdied
+  
+  Because the 'not' operator has a very low precedence and as a result the
+  entire statement was erroneously negated and could never be true.
+
+Daniel Stenberg (30 Sep 2015)
+- [Thorsten SchÃ¶ning brought this change]
+
+  win32: make recent Borland compilers use long long
+
+- RELEASE-NOTES: synced with 69b89050d4
+
+Jay Satiro (28 Sep 2015)
+- [Michael Kalinin brought this change]
+
+  openssl: Fix algorithm init
+  
+  - Change algorithm init to happen after OpenSSL config load.
+  
+  Additional algorithms may be available due to the user's config so we
+  initialize the algorithms after the user's config is loaded.
+  
+  Bug: https://github.com/bagder/curl/issues/447
+  Reported-by: Denis Feklushkin
+
+- [Svyatoslav Mishyn brought this change]
+
+  docs: fix unescaped '\n' in man pages
+  
+  Closes https://github.com/bagder/curl/pull/459
+
+Daniel Stenberg (27 Sep 2015)
+- http2: set TCP_NODELAY unconditionally
+  
+  For a single-stream download from localhost, we managed to increase
+  transfer speed from 1.6MB/sec to around 400MB/sec, mostly because of
+  this single fix.
+
+- http2: avoid superfluous Curl_expire() calls
+  
+  ... only call it when there is data arriving for another handle than the
+  one that is currently driving it.
+  
+  Improves single-stream download performance quite a lot.
+  
+  Thanks-to: Tatsuhiro Tsujikawa
+  Bug: http://curl.haxx.se/mail/lib-2015-09/0097.html
+
+- readwrite_data: set a max number of loops
+  
+  ... as otherwise a really fast pipe can "lock" one transfer for some
+  protocols, like with HTTP/2.
+
+- [Sergei Nikulov brought this change]
+
+  CI: Added AppVeyor-CI for curl
+  
+  Closes #439
+
+- FTP: fix uploading ASCII with unknown size
+  
+  ... don't try to increase the supposed file size on newlines if we don't
+  know what file size it is!
+  
+  Patch-by: lzsiga
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  build: fix failures with -Wcast-align and -Werror
+  
+  Closes #457
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  curl-confopts.m4: Add missing ')'
+  
+  ... for CURL_CHECK_OPTION_RT
+  
+  Closes #456
+
+Jay Satiro (25 Sep 2015)
+- curl_easy_getinfo.3: Add brief description for each CURLINFO
+
+Daniel Stenberg (23 Sep 2015)
+- [Jakub Zakrzewski brought this change]
+
+  CMake: Ensure discovered include dirs are considered
+  
+  ...during header checks. Otherwise some following header tests
+  (incorrectly) fail.
+  
+  Closes #436
+
+- [Jakub Zakrzewski brought this change]
+
+  CMake: Put "winsock2.h" before "windows.h" during configure checks
+  
+  "windows.h" includes "winsock.h" what causes many redefinition errors
+  if "winsock2.h" is included afterwards and can cause build to fail.
+
+- tests: disable 1510 due to CI-problems on github
+
+- [Mike Crowe brought this change]
+
+  gnutls: Report actual GnuTLS error message for certificate errors
+  
+  If GnuTLS fails to read the certificate then include whatever reason it
+  provides in the failure message reported to the client.
+  
+  Signed-off-by: Mike Crowe <mac@mcrowe.com>
+
+- RELEASE-NOTES: synced with 6b56901b56e
+
+- [Mike Crowe brought this change]
+
+  gnutls: Support CURLOPT_KEYPASSWD
+  
+  The gnutls vtls back-end was previously ignoring any password set via
+  CURLOPT_KEYPASSWD. Presumably this was because
+  gnutls_certificate_set_x509_key_file did not support encrypted keys.
+  
+  gnutls now has a gnutls_certificate_set_x509_key_file2 function that
+  does support encrypted keys. Let's determine at compile time whether the
+  available gnutls supports this new function. If it does then use it to
+  pass the password. If it does not then emit a helpful diagnostic if a
+  password is set. This is preferable to the previous behaviour of just
+  failing to read the certificate without giving a reason in that case.
+  
+  Signed-off-by: Mike Crowe <mac@mcrowe.com>
+
+- CURLINFO_TLS_SESSION: always return backend info
+  
+  ... even for those that don't support providing anything in the
+  'internals' struct member since it offers a convenient way for
+  applications to figure this out.
+
+- [Daniel Hwang brought this change]
+
+  tool: remove redundant libcurl check
+  
+  The easysrc generation is run only when --libcurl is initialized.
+  
+  Ref: https://github.com/bagder/curl/issues/429
+  
+  Closes #448
+
+- [Richard van den Berg brought this change]
+
+  CURLOPT_PROXY.3: A proxy given as env variable gets no special treatment
+  
+  Closes #449
+
+- TODO: 5.7 More compressions
+  
+  Like for example brotli, as being implemented in Firefox now.
+
+Jay Satiro (21 Sep 2015)
+- tool_operate: Don't call easysrc cleanup unless --libcurl
+  
+  - Review of 4d95491.
+  
+  The author changed it so easysrc only initializes when --libcurl but did
+  not do the same for the call to easysrc cleanup.
+  
+  Ref: https://github.com/bagder/curl/issues/429
+
+Daniel Stenberg (20 Sep 2015)
+- [Viktor Szakats brought this change]
+
+  CURLOPT_PINNEDPUBLICKEY.3: replace test.com with example.com
+  
+  closes #443
+
+- KNOWN_BUGS: 91 "curl_easy_perform hangs with imap and PolarSSL"
+  
+  Closes #334
+
+- KNOWN_BUGS: add link to #85
+
+- tests: disable 1801 until fixed
+  
+  It is unreliable and causes CI problems on github
+  
+  Closes #380
+
+- RELEASE-NOTES: synced with 4d95491636ee
+
+- [Daniel Lee Hwang brought this change]
+
+  tool: generate easysrc only on --libcurl
+  
+  Code should only be generated when --libcurl is used.
+  
+  Bug: https://github.com/bagder/curl/issues/429
+  Reported-by: @greafhe, Jay Satiro
+  
+  Closes #429
+  Closes #442
+
+Jay Satiro (19 Sep 2015)
+- vtls: Change designator name for server's pubkey hash
+  
+  - Change the designator name we use to show the base64 encoded sha256
+  hash of the server's public key from 'pinnedpubkey' to
+  'public key hash'.
+  
+  Though the server's public key hash is only shown when comparing pinned
+  public key hashes, the server's hash may not match one of the pinned.
+
+Daniel Stenberg (19 Sep 2015)
+- [Isaac Boukris brought this change]
+
+  NTLM: Reset auth-done when using a fresh connection
+  
+  With NTLM a new connection will always require authentication.
+  Fixes #435
+
+- [Daniel Hwang brought this change]
+
+  ssl: add server cert's "sha256//" hash to verbose
+  
+  Add a "pinnedpubkey" section to the "Server Certificate" verbose
+  
+  Bug: https://github.com/bagder/curl/issues/410
+  Reported-by: W. Mark Kubacki
+  
+  Closes #430
+  Closes #410
+
+- [Jakub Zakrzewski brought this change]
+
+  openldap: only part of LDAP query results received
+  
+  Introduced with commit 65d141e6da5c6003a1592bbc87ee550b0ad75c2f
+  
+  Closes #440
+
+- [Alessandro Ghedini brought this change]
+
+  openssl: don't output certinfo data
+
+- [Alessandro Ghedini brought this change]
+
+  openssl: refactor certificate parsing to use OpenSSL memory BIO
+  
+  Fixes #427
+
+Kamil Dudka (18 Sep 2015)
+- nss: prevent NSS from incorrectly re-using a session
+  
+  Without this workaround, NSS re-uses a session cache entry despite the
+  server name does not match.  This causes SNI host name to differ from
+  the actual host name.  Consequently, certain servers (e.g. github.com)
+  respond by 400 to such requests.
+  
+  Bug: https://bugzilla.mozilla.org/1202264
+
+- nss: check return values of NSS functions
+
+Daniel Stenberg (17 Sep 2015)
+- CURLOPT_PINNEDPUBLICKEY.3: mention error code
+
+- openssl: build with < 0.9.8
+  
+  ... without sha256 support and no define saying so.
+  
+  Reported-by: Rajkumar Mandal
+
+- libcurl-errors.3: add two missing error codes
+  
+  CURLE_SSL_PINNEDPUBKEYNOTMATCH and CURLE_SSL_INVALIDCERTSTATUS
+
+Jay Satiro (14 Sep 2015)
+- CURLOPT_PINNEDPUBLICKEY.3: Improve pubkey extraction example
+  
+  - Show how a certificate can be obtained using OpenSSL.
+  
+  Bug: https://github.com/bagder/curl/pull/430
+  Reported-by: Daniel Hwang
+
+Daniel Stenberg (13 Sep 2015)
+- http2: removed unused function
+
+- CURLINFO_ACTIVESOCKET.3: mention it replaces *LASTSOCKET
+
+- opts: add CURLINFO_* man pages to dist
+
+- opts: 19 more CURLINFO_* options made into stand-alone man pages
+
+- RELEASE-NOTES: synced with fad9604613
+
+- curl: customrequest_helper: deal with NULL custom method
+
+- [Svyatoslav Mishyn brought this change]
+
+  CURLOPT_FNMATCH_FUNCTION.3: fix typo
+  
+  s => is
+  
+  Closes #428
+
+- curl: point out unnecessary uses of -X in verbose mode
+  
+  It uses 'Note:' as a prefix as opposed to the common 'Warning:' to take
+  down the tone a bit.
+  
+  It adds a warning for using -XHEAD on other methods becasue that may
+  lead to a hanging connection.
+
+Jay Satiro (10 Sep 2015)
+- curl_sspi: fix possibly undefined CRYPT_E_REVOKED
+  
+  Bug: https://github.com/bagder/curl/pull/411
+  Reported-by: Viktor Szakats
+
+- buildconf.bat: fix syntax error
+
+- [Benjamin Kircher brought this change]
+
+  winbuild: run buildconf.bat if necessary
+
+- [Svyatoslav Mishyn brought this change]
+
+  docs: fix argument type for CURLINFO_SPEED_*, CURLINFO_SIZE_*
+  
+  long => double
+
+Daniel Stenberg (8 Sep 2015)
+- [Sergei Nikulov brought this change]
+
+  cmake: IPv6 : disable Unix header check on Windows platform
+  
+  Closes #409
+
+- parse_proxy: reject illegal port numbers
+  
+  If the port number in the proxy string ended weirdly or the number is
+  too large, skip it. Mostly as a means to bail out early if a "bare" IPv6
+  numerical address is used without enclosing brackets.
+  
+  Also mention the bracket requirement for IPv6 numerical addresses to the
+  man page for CURLOPT_PROXY.
+  
+  Closes #415
+  
+  Reported-by: Marcel Raad
+
+- FTP: do_more: add check for wait_data_conn in upload case
+  
+  In some timing-dependnt cases when a 4xx response immediately followed
+  after a 150 when a STOR was issued, this function would wrongly return
+  'complete == true' while 'wait_data_conn' was still set.
+  
+  Closes #405
+  
+  Reported-by: Patricia Muscalu
+
+- [Svyatoslav Mishyn brought this change]
+
+  CURLOPT_TLSAUTH_TYPE.3: update description
+  
+  Closes #414
+  Closes #413
+
+- [Svyatoslav Mishyn brought this change]
+
+  CURLOPT_PATH_AS_IS.3: fix typo
+  
+  leavit => leaveit
+  
+  closes #412
+
+- [Svyatoslav Mishyn brought this change]
+
+  CURLINFO_SSL_VERIFYRESULT.3: add short description
+
+- [Svyatoslav Mishyn brought this change]
+
+  CURLINFO_SSL_ENGINES.3: add short description
+
+- [Svyatoslav Mishyn brought this change]
+
+  CURLINFO_CONTENT_LENGTH_UPLOAD.3: replace "receive" with "get" for consistency
+
+- [Svyatoslav Mishyn brought this change]
+
+  CURLINFO_REDIRECT_TIME.3: remove redundant '!'
+
+Kamil Dudka (4 Sep 2015)
+- Revert "has: generate the curl/has.h header"
+  
+  This reverts commit a60bde79f9adeb135d5c642a07f0d783fbfbbc25 I have
+  pushed by mistake.  Apologies for my incompetent use of the git repo!
+
+- nss: do not directly access SSL_ImplementedCiphers[]
+  
+  It causes dynamic linking issues at run-time after an update of NSS.
+  
+  Bug: https://lists.fedoraproject.org/pipermail/devel/2015-September/214117.html
+
+- [Daniel Stenberg brought this change]
+
+  has: generate the curl/has.h header
+  
+  changed macro name, moved and renamed script to become docs/libcurl/has.pl,
+  generate code that is checksrc compliant
+
+Daniel Stenberg (3 Sep 2015)
+- gitignore: ignore more generated VC Makefiles
+
+- projects/Windows/.gitignore: ignore generated files for release
+
+- http2: don't pass on Connection: headers
+  
+  RFC 7540 section 8.1.2.2 states: "An endpoint MUST NOT generate an
+  HTTP/2 message containing connection-specific header fields; any message
+  containing connection-specific header fields MUST be treated as
+  malformed"
+  
+  Closes #401
+
+- curl.1: update RFC references
+
+- CURLOPT_POSTREDIR.3: update RFC number and section
+
+- CURLOPT_FOLLOWLOCATION.3: mention methods for redirects
+  
+  and some general cleaning up
+
+- [Marcel Raad brought this change]
+
+  inet_pton.c: Fix MSVC run-time check failure (2)
+  
+  This fixes another run-time check failure because of a narrowing cast on
+  Visual C++.
+  
+  Closes #408
+
+Jay Satiro (3 Sep 2015)
+- docs: Warn about any-domain cookies and multiple transfers
+  
+  - Warn that cookies without a domain are sent to any domain:
+  CURLOPT_COOKIELIST, CURLOPT_COOKIEFILE, --cookie
+  
+  - Note that imported Set-Cookie cookies without a domain are no longer
+  exported:
+  CURLINFO_COOKIELIST, CURLOPT_COOKIEJAR, --cookie-jar
+
+Steve Holme (2 Sep 2015)
+- tool_sdecls.h: Fixed compilation warning from commit 4a889441d3
+  
+  tool_sdecls.h:139 warning: comma at end of enumerator list
+
+Daniel Stenberg (2 Sep 2015)
+- opts: 8 more CURLINFO* options as stand-alone man pages
+
+- RELEASE-NOTES: synced with c764cb4add1a8
+
+- man-pages: more SEE ALSO links
+
+- opts: more CURLINFO_* options as stand-alone man pages
+
+Steve Holme (31 Aug 2015)
+- sasl: Only define Curl_sasl_digest_get_pair() when CRYPTO_AUTH enabled
+  
+  Introduced in commit 59f3f92ba6 this function is only implemented when
+  CURL_DISABLE_CRYPTO_AUTH is not defined. As such we shouldn't define
+  the function in the header file either.
+
+- sasl: Updated SPN variables and comments for consistency
+  
+  In places the "host name" and "realm" variable was referred to as
+  "instance" whilst in others it was referred to as "host".
+
+Daniel Stenberg (30 Aug 2015)
+- configure: check for HMAC_Update in openssl
+  
+  Turns out HMAC_Init is now deprecated in openssl master (and I spelled
+  HMAC_Init_ex wrong in previous commit)
+
+Steve Holme (30 Aug 2015)
+- win32: Use DES_set_odd_parity() from OpenSSL/BoringSSL by default
+  
+  Set HAVE_DES_SET_ODD_PARITY when using OpenSSL/BoringSSL as native
+  Windows builds don't use the autoconf tools.
+
+- des: Fixed compilation warning from commit 613e5022fe
+  
+  curl_ntlm_core.c:150: warning 'Curl_des_set_odd_parity' undefined;
+                        assuming extern returning int
+
+- buildconf.bat: Fixed double blank line in 'curl manual' warning output
+
+- makefiles: Added our standard copyright header
+  
+  But kept the original author, when they were specified in a comment, as
+  the initial copyright holder.
+
+Jay Satiro (29 Aug 2015)
+- CURLOPT_FILETIME.3: CURLINFO_FILETIME has its own manpage now
+
+Daniel Stenberg (29 Aug 2015)
+- CURLINFO_RESPONSE_CODE.3: added short description
+
+- opts: 7 initial CURLINFO_* options as stand-alone man pages
+
+- [Nikolai Kondrashov brought this change]
+
+  libcurl.m4: Put braces around empty if body
+  
+  Put braces around empty "if" body in libcurl.m4 check to avoid warning:
+  
+          suggest braces around empty body in an 'if' statement
+  
+  and make it work with -Werror builds.
+  
+  Closes #402
+
+- [Svyatoslav Mishyn brought this change]
+
+  curl_easy_escape.3: escape '\n'
+  
+  Closes #398
+
+- [Svyatoslav Mishyn brought this change]
+
+  curl_easy_{escape,setopt}.3: fix example
+  
+  remove redundant '}'
+
+- [Sergei Nikulov brought this change]
+
+  cmake: added Windows SSL support
+  
+  Closes #399
+
+- curl: point out the conflicting HTTP methods if used
+  
+  It isn't always clear to the user which options that cause the HTTP
+  methods to conflict so by spelling them out it should hopefully be
+  easier to understand why curl complains.
+
+- curl: clarify that users can only specify one _METHOD_
+
+- [Svyatoslav Mishyn brought this change]
+
+  curl_easy_{escape,unescape}.3: "char *" vs. "const char *"
+  
+  Closes #395
+
+Patrick Monnerat (24 Aug 2015)
+- os400: include new options in wrappers and update ILE/RPG binding.
+
+Daniel Stenberg (24 Aug 2015)
+- KNOWN_BUGS: #2, not reading a HEAD response-body is not a bug
+  
+  ... since HTTP is forbidden to return any such.
+
+- KNOWN_BUGS: #78 zero-length files is already fixed!
+
+- [Razvan Cojocaru brought this change]
+
+  getinfo: added CURLINFO_ACTIVESOCKET
+  
+  This patch addresses known bug #76, where on 64-bit Windows SOCKET is 64
+  bits wide, but long is only 32, making CURLINFO_LASTSOCKET unreliable.
+  
+  Signed-off-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
+
+- http2: remove dead code
+  
+  Leftovers from when we removed the private socket hash.
+  
+  Coverity CID 1317365, "Logically dead code"
+
+- ntlm: mark deliberate switch case fall-through
+  
+  Coverity CID 1317367, "Missing break in switch"
+
+- http2: on_frame_recv: get a proper 'conn' for the debug logging
+  
+  "Explicit null dereferenced (FORWARD_NULL)"
+  
+  Coverity CID 1317366
+
+- RELEASE-NOTES: synced with 2acaf3c804
+
+Dan Fandrich (23 Aug 2015)
+- tool: fix memory leak with --proto-default option
+
+Jay Satiro (22 Aug 2015)
+- [Nathaniel Waisbrot brought this change]
+
+  CURLOPT_DEFAULT_PROTOCOL: added
+  
+  - Add new option CURLOPT_DEFAULT_PROTOCOL to allow specifying a default
+  protocol for schemeless URLs.
+  
+  - Add new tool option --proto-default to expose
+  CURLOPT_DEFAULT_PROTOCOL.
+  
+  In the case of schemeless URLs libcurl will behave in this way:
+  
+  When the option is used libcurl will use the supplied default.
+  
+  When the option is not used, libcurl will follow its usual plan of
+  guessing from the hostname and falling back to 'http'.
+
+- runtests: Allow for spaces in server-verify curl custom path
+
+Daniel Stenberg (22 Aug 2015)
+- NTLM: recent boringssl brought DES_set_odd_parity back
+  
+  ... so improve the #ifdefs for using our local implementation.
+
+- configure: detect latest boringssl
+  
+  Since boringssl brought back DES_set_odd_parity again, it cannot be used
+  to differentiate from boringssl. Using the OPENSSL_IS_BORINGSSL define
+  seems better anyway.
+  
+  URL: https://android.googlesource.com/platform/external/curl/+/f551028d5caab29d4b4a4ae8c159c76c3cfd4887%5E!/
+  Original-patch-by: Bertrand Simonnet
+  
+  Closes #393
+
+- configure: change functions to detect openssl (clones)
+  
+  ... since boringssl moved the former ones and the check started to fail.
+  
+  URL: https://android.googlesource.com/platform/external/curl/+/f551028d5caab29d4b4a4ae8c159c76c3cfd4887%5E!/
+  Original-patch-by: Bertrand Simonnet
+
+- [Alessandro Ghedini brought this change]
+
+  openssl: handle lack of server cert when strict checking disabled
+  
+  If strict certificate checking is disabled (CURLOPT_SSL_VERIFYPEER
+  and CURLOPT_SSL_VERIFYHOST are disabled) do not fail if the server
+  doesn't present a certificate at all.
+  
+  Closes #392
+
+- ftp: clear the do_more bit when the server has connected
+  
+  The multi state machine would otherwise go into the DO_MORE state after
+  DO, even for the case when the FTP state machine had already performed
+  those duties, which caused libcurl to get stuck in that state and fail
+  miserably. This occured for for active ftp uploads.
+  
+  Reported-by: Patricia Muscalu
+
+- [Jactry Zeng brought this change]
+
+  travis.yml: Add OS X testbot.
+
+- [RÃ©my LÃ©one brought this change]
+
+  travis: Upgrading to container based build
+  
+  http://docs.travis-ci.com/user/migrating-from-legacy
+  
+  Closes #388
+
+- RELEASE-NOTES: synced with 14ff86256b13e
+
+- [Erik Janssen brought this change]
+
+  rtsp: stop reading empty DESCRIBE responses
+  
+  Based-on-patch-by: Jim Hollinger
+
+- [Erik Janssen brought this change]
+
+  rtsp: support basic/digest authentication
+
+- [Sam Roth brought this change]
+
+  CURLMOPT_PUSHFUNCTION.3: fix argument types
+  
+  Closes #389
+  Closes #386
+
+- [Marcel Raad brought this change]
+
+  inet_pton.c: Fix MSVC run-time check failure
+  
+  Visual Studio complains with a message box:
+  
+  "Run-Time Check Failure #1 - A cast to a smaller data type has caused a
+  loss of data.  If this was intentional, you should mask the source of
+  the cast with the appropriate bitmask.
+  
+  For example:
+  char c = (i & 0xFF);
+  
+  Changing the code in this way will not affect the quality of the
+  resulting optimized code."
+  
+  This is because only 'val' is cast to unsigned char, so the "& 0xff" has
+  no effect.
+  
+  Closes #387
+
+Jay Satiro (18 Aug 2015)
+- docs: Update the redirect protocols disabled by default
+  
+  - Clarify that FILE and SCP are disabled by default since 7.19.4
+  - Add that SMB and SMBS are disabled by default since 7.40.0
+  - Add CURLPROTO_SMBS to the list of protocols
+
+- gitignore: Sort for readability
+  
+  find . -name .gitignore -print0 | xargs -i -0 sort -o '{}' '{}'
+
+Daniel Stenberg (15 Aug 2015)
+- curl_easy_getinfo.3: fix superfluous space
+  
+  ... and changed "oriented" to "related"
+  
+  Closes #378
+
+- CURLOPT_HTTP_VERSION.3: connection re-use goes before version
+
+- [Daniel Kahn Gillmor brought this change]
+
+  curl.1: Document weaknesses in SSLv2 and SSLv3
+  
+  Acknowledge that SSLv3 is also widely considered to be insecure.
+  
+  Also, provide references for people who want to know more about why it's
+  insecure.
+
+Steve Holme (14 Aug 2015)
+- generate.bat: Added support for generating only the prerequisite files
+
+- generate.bat: Only call buildconf.bat if it exists
+
+- generate.bat: Fixed issues when ran in directories with special chars
+
+Daniel Stenberg (14 Aug 2015)
+- [Brad King brought this change]
+
+  cmake: Fix CurlTests check for gethostbyname_r with 5 arguments
+  
+  Fix the check code to pass 5 arguments instead of 6.  This typo was
+  introduced by commit aebfd4cfbf (cmake: fix gethostby{addr,name}_r in
+  CurlTests, 2014-10-31).
+
+Steve Holme (14 Aug 2015)
+- * buildconf.bat: Fixed issues when ran in directories with special chars
+  
+  Bug: https://github.com/bagder/curl/pull/379
+  Reported-by: Daniel Seither
+
+Jay Satiro (13 Aug 2015)
+- curl_global_init_mem.3: Stronger thread safety warning
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-08/0016.html
+  Reported-by: Eric Ridge
+
+Daniel Stenberg (12 Aug 2015)
+- [Svyatoslav Mishyn brought this change]
+
+  curl_multi_add_handle.3: fix a typo
+  
+  "can not" => "cannot"
+  
+  closes #377
+
+- [Alessandro Ghedini brought this change]
+
+  docs: fix typos
+  
+  closes #376
+
+- bump: start working toward 7.45.0
+
+- THANKS: remove duplicate name
+
+- THANKS-filter: merge Todd's names
+
+- THANKS: 13 new contributors from the 7.44.0 RELEASE-NOTES
+
+Version 7.44.0 (11 Aug 2015)
+
+Daniel Stenberg (11 Aug 2015)
+- RELEASE-NOTES: synced with c75a1e775061
+
+- [Svyatoslav Mishyn brought this change]
+
+  curl_formget.3: correct return code
+  
+  Closes #375
+
+- [Svyatoslav Mishyn brought this change]
+
+  libcurl-tutorial.3: fix formatting
+  
+  Closes #374
+
+- [Svyatoslav Mishyn brought this change]
+
+  curl_easy_recv.3: fix formatting
+
+- [Anders Bakken brought this change]
+
+  http2: discard frames with no SessionHandle
+  
+  Return 0 instead of NGHTTP2_ERR_CALLBACK_FAILURE if we can't locate the
+  SessionHandle. Apparently mod_h2 will sometimes send a frame for a
+  stream_id we're finished with.
+  
+  Use nghttp2_session_get_stream_user_data and
+  nghttp2_session_set_stream_user_data to identify SessionHandles instead
+  of a hash.
+  
+  Closes #372
+
+- RELEASE-NOTES: synced with 9ee40ce2aba
+
+- [Viktor Szakats brought this change]
+
+  build: refer to fixed libidn versions
+  
+  closes #371
+
+- Revert "configure: disable libidn by default"
+  
+  This reverts commit e6749055d65398315fd77f5b5b8234c5552ac2d3.
+  
+  ... since libidn has since been fixed.
+
+- [Jakub Zakrzewski brought this change]
+
+  CMake: s/HAVE_GSS_API/HAVE_GSSAPI/ to match header define
+  
+  Otherwise the build only pretended to use GSS-API
+  
+  Closes #370
+
+- SFTP: fix range request off-by-one in size check
+  
+  Reported-by: Tim Stack
+  
+  Closes #359
+
+- test46: update cookie expire time
+  
+  ... since it went old and thus was expired and caused the test to fail!
+
+Steve Holme (9 Aug 2015)
+- generate.bat: Use buildconf.bat for prerequisite file generation
+
+- buildconf.bat: Tidy up of comments after recent commits
+
+- buildconf.bat: Added full generation of src\tool_hugehelp.c
+  
+  Added support for generating the full man page based on code from
+  generate.bat.
+
+- buildconf.bat: Added detection of groff, nroff, perl and gzip
+  
+  To allow for the full generation of tool_hugehelp.c added detection of
+  the required programs - based on code from generate.bat.
+
+- buildconf.bat: Move DOS variable clean-up code to separate function
+  
+  Rather than duplicate future variables, during clean-up of both success
+  and error conditions, use a common function that can be called by both.
+
+- RELEASE-NOTES: Synced with 39dcf352d2
+
+- buildconf.bat: Added error messages on failure
+
+- buildconf.bat: Generate and clean files in the same order
+
+- buildconf.bat: Maintain compatibility with DOS based systems
+  
+  Commit f08e30d7bc broke compatibility with DOS and non Windows NT based
+  versions of Windows due to the use of the setlocal command.
+
+Jay Satiro (9 Aug 2015)
+- CURLOPT_RESOLVE.3: Note removal support was added in 7.42
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-08/0019.html
+  Reported-by: Inca R
+
+Steve Holme (8 Aug 2015)
+- checksrc.bat: Fixed error when missing *.c and *.h files
+  
+  File Not Found
+
+- checksrc.bat: Fixed incorrect 'lib\vtls' path check in commit 333c36b276
+
+- checksrc.bat: Fixed error when [directory] isn't a curl source directory
+  
+  The system cannot find the file specified.
+
+- checksrc.bat: Added check for unknown arguments
+
+- scripts: Added missing comments
+
+- scripts: Always perform setlocal and endlocal calls in pairs
+  
+  Ensure that there isn't a mismatch between setlocal and endlocal calls,
+  which could have happened due to setlocal being called after certain
+  error conditions were checked for.
+
+- scripts: Allow -help to be specified in any argument
+  
+  Allow the -help command line argument to be specified in any argument
+  and not just as the first.
+
+Daniel Stenberg (6 Aug 2015)
+- [juef brought this change]
+
+  curl_multi_remove_handle.3: fix formatting
+  
+  closes #366
+
+Steve Holme (6 Aug 2015)
+- README: Added notes about 'Running DLL based configurations'
+  
+  ...as well as a TODO for a future enhancement to the project files.
+  
+  Thanks-to: Jay Satiro
+
+- RELEASE-NOTES: Synced with cf8975387f
+
+- buildconf.bat: Synchronise no repository error with generate.bat
+
+- generate.bat: Added a check for the presence of a git repository
+
+- [Jay Satiro brought this change]
+
+  build: Added wolfSSL configurations to VC10+ project files
+  
+  URL: https://github.com/bagder/curl/pull/174
+
+- [Jay Satiro brought this change]
+
+  build: Added wolfSSL build script for Visual Studio projects
+  
+  Added the wolfSSL build script, based on build-openssl.bat, as well as
+  the property sheet and header file required for the upcoming additions
+  to the Visual Studio project files.
+
+Daniel Stenberg (6 Aug 2015)
+- CHANGES: refer to the online changelog
+  
+  Suggested-by: mc0e
+
+- [Isaac Boukris brought this change]
+
+  NTLM: handle auth for only a single request
+  
+  Currently when the server responds with 401 on NTLM authenticated
+  connection (re-used) we consider it to have failed.  However this is
+  legitimate and may happen when for example IIS is set configured to
+  'authPersistSingleRequest' or when the request goes thru a proxy (with
+  'via' header).
+  
+  Implemented by imploying an additional state once a connection is
+  re-used to indicate that if we receive 401 we need to restart
+  authentication.
+  
+  Closes #363
+
+Steve Holme (5 Aug 2015)
+- RELEASE-NOTES: Synced with 473807b95f
+
+- generate.bat: Use buildconf.bat for prerequisite file clean-up
+
+- buildconf.bat: Added support for file clean-up via -clean
+
+- buildconf.bat: Added progress output
+
+- buildconf.bat: Avoid using goto for file not in repository
+
+Daniel Stenberg (5 Aug 2015)
+- curl_slist_append.3: add error checking to the example
+
+Steve Holme (5 Aug 2015)
+- buildconf.bat: Added display of usage text with -help
+
+- buildconf.bat: Added exit codes for error handling
+
+- buildconf.bat: Added our standard copyright header
+
+- buildconf.bat: Use lower-case for commands and reserved keywords
+
+- generate.bat: Only clean prerequisite files when in ALL mode
+
+- generate.bat: Moved error messages out of sub-routines
+
+- generate.bat: More use of lower-case for commands and reserved keywords
+
+Daniel Stenberg (3 Aug 2015)
+- libcurl.3: fix a single typo
+  
+  Closes #361
+
+- RELEASE-NOTES: synced with c4eb10e2f06f
+
+- SSH: three state machine fixups
+  
+  The SSH state machine didn't clear the 'rc' variable appropriately in a
+  two places which prevented it from looping the way it should. And it
+  lacked an 'else' statement that made it possible to erroneously get
+  stuck in the SSH_AUTH_AGENT state.
+  
+  Reported-by: Tim Stack
+  
+  Closes #357
+
+- curl_gssapi: remove 'const' to fix compiler warnings
+  
+  initialization discards 'const' qualifier from pointer target type
+
+- docs: formpost needs the full size at start of upload
+  
+  Closes #360
+
+Steve Holme (1 Aug 2015)
+- sspi: Fix typo from left over from old code which referenced NTLM
+  
+  References to NTLM in the identity generation should have been removed
+  in commit c469941293 but not all were.
+
+- win32: Fix compilation warnings from commit 40c921f8b8
+  
+  connect.c:953:5: warning: initializer element is not computable at load
+                   time
+  connect.c:953:5: warning: missing initializer for field 'dwMinorVersion'
+                   of 'OSVERSIONINFOEX'
+  curl_sspi.c:97:5: warning: initializer element is not computable at load
+                    time
+  curl_sspi.c:97:5: warning: missing initializer for field 'szCSDVersion'
+                    of 'OSVERSIONINFOEX'
+
+- schannel: Fix compilation warning from commit 7a8e861a56
+  
+  schannel.c:1125:5: warning: missing initializer for field 'dwMinorVersion'
+                     of 'OSVERSIONINFOEX' [-Wmissing-field-initializers
+
+Daniel Stenberg (31 Jul 2015)
+- libcurl-thread.3: minor reformatting
+
+Jay Satiro (31 Jul 2015)
+- curl_global_init_mem.3: Warn threaded resolver needs thread safe funcs
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-07/0149.html
+  Reported-by: Eric Ridge
+
+- libcurl-thread.3: Warn memory functions must be thread safe
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-07/0149.html
+  Reported-by: Eric Ridge
+
+Steve Holme (31 Jul 2015)
+- RELEASE-NOTES: Synced with 8b1d00ac1a
+
+- INSTALL: Minor formatting correction in 'Legacy Windows and SSL' section
+  
+  ...as well as some rewording.
+
+Kamil Dudka (30 Jul 2015)
+- http: move HTTP/2 cleanup code off http_disconnect()
+  
+  Otherwise it would never be called for an HTTP/2 connection, which has
+  its own disconnect handler.
+  
+  I spotted this while debugging <https://bugzilla.redhat.com/1248389>
+  where the http_disconnect() handler was called on an FTP session handle
+  causing 'dnf' to crash.  conn->data->req.protop of type (struct FTP *)
+  was reinterpreted as type (struct HTTP *) which resulted in SIGSEGV in
+  Curl_add_buffer_free() after printing the "Connection cache is full,
+  closing the oldest one." message.
+  
+  A previously working version of libcurl started to crash after it was
+  recompiled with the HTTP/2 support despite the HTTP/2 protocol was not
+  actually used.  This commit makes it work again although I suspect the
+  root cause (reinterpreting session handle data of incompatible protocol)
+  still has to be fixed.  Otherwise the same will happen when mixing FTP
+  and HTTP/2 connections and exceeding the connection cache limit.
+  
+  Reported-by: Tomas Tomecek
+  Bug: https://bugzilla.redhat.com/1248389
+
+Daniel Stenberg (30 Jul 2015)
+- [Viktor Szakats brought this change]
+
+  ABI doc: use secure URL
+
+- ABI: remove the ascii logo
+  
+  and made the indent level to 1
+
+- libcurl-multi.3: mention curl_multi_wait
+  
+  ... and some general rewordings to improve this docs.
+  
+  Reported-by: Tim Stack
+  
+  Closes #356
+
+Steve Holme (30 Jul 2015)
+- maketgz: Fixed some VC makefiles missing from the release tarball
+  
+  VC7, VC11, VC12 and VC14 makefiles were missing from the release
+  tarball.
+
+- RELEASE-NOTES: Synced with 2d7e165761
+
+- build: Added VC14 project files to Makefile.am
+
+- build: Added VC14 project files
+  
+  Updates to Makefile.am for the generation of the project files in
+  the tarball to follow.
+
+Jay Satiro (29 Jul 2015)
+- libcurl-thread.3: Clarify CURLOPT_NOSIGNAL takes long value 1L
+
+Steve Holme (28 Jul 2015)
+- generate.bat: Use lower-case for commands and reserved keywords
+  
+  Whilst there are no coding standards for the batch files used in curl,
+  most tend to use lower-case for keywords and upper-case for variables.
+
+- build: Added initial VC14 support to generate.bat
+  
+  Visual Studio project files and updates to makefile.am to follow.
+
+- build: Fixed missing .opensdf files from VC10+ .gitignore files
+
+- build: Use $(ProjectName) macro for curl.exe and curld.exe filenames
+  
+  This wasn't possible with the old curlsrc project filenames, but like
+  commit 2a615a2b64 and 11397eb6dd for libcurl use the built in Visual
+  Studio macros for the output filenames.
+
+- build: Renamed curl src Visual Studio project files
+  
+  Following commit 957fcd9049 and in preparation for adding the VC14
+  project files renamed the curl source project files.
+
+Daniel Stenberg (28 Jul 2015)
+- [Jay Satiro brought this change]
+
+  libcurl-thread.3: Revert to stricter handle wording
+  
+  .. also update formatting and add WinSSL and wolfSSL to the SSL/TLS
+  handlers list.
+
+- [Jay Satiro brought this change]
+
+  libcurl-thread.3: Consolidate thread safety info
+  
+  This is a new document to consolidate our thread safety information from
+  several documents (curl-www:features, libcurl.3, libcurl-tutorial.3).
+  Each document's section on multi-threading will now point to this one.
+
+Steve Holme (27 Jul 2015)
+- README: Corrected formatting for 'Legacy Windows and SSL' section
+  
+  ...as well as some wording.
+
+- build-openssl.bat: Added support for VC14
+
+Daniel Stenberg (26 Jul 2015)
+- RELEASE-NOTES: synced with 0f645adc95390e8
+
+- test1902: attempt to make the test more reliable
+  
+  Closes #355
+
+- comment: fix comment about adding new option support
+
+Jay Satiro (25 Jul 2015)
+- build-openssl.bat: Show syntax if required args are missing
+
+Daniel Stenberg (26 Jul 2015)
+- TODO: improve how curl works in a windows console window
+  
+  Closes #322 for now
+
+- 1.11 minimize dependencies with dynamicly loaded modules
+  
+  Closes #349 for now
+
+Jay Satiro (25 Jul 2015)
+- tool_operate: Fix CURLOPT_SSL_OPTIONS for builds without HTTPS
+  
+  - Set CURLOPT_SSL_OPTIONS only if the tool enabled an SSL option.
+  
+  Broken by me several days ago in 172b2be.
+  https://github.com/bagder/curl/commit/172b2be#diff-70b44ee478e58d4e1ddcf9c9a73d257b
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-07/0119.html
+  Reported-by: Dan Fandrich
+
+Daniel Stenberg (25 Jul 2015)
+- configure: check if OpenSSL linking wants -ldl
+  
+  To make it easier to link with static versions of OpenSSL, the configure
+  script now checks if -ldl is needed for linking.
+  
+  Help-by: TJ Saunders
+
+- [Michael Kaufmann brought this change]
+
+  HTTP: ignore "Content-Encoding: compress"
+  
+  Currently, libcurl rejects responses with "Content-Encoding: compress"
+  when CURLOPT_ACCEPT_ENCODING is set to "". I think that libcurl should
+  treat the Content-Encoding "compress" the same as other
+  Content-Encodings that it does not support, e.g. "bzip2". That means
+  just ignoring it.
+
+- [Marcel Raad brought this change]
+
+  openssl: work around MSVC warning
+  
+  MSVC 12 complains:
+  
+  lib\vtls\openssl.c(1554): warning C4701: potentially uninitialized local
+  variable 'verstr' used It's a false positive, but as it's normally not,
+  I have enabled warning-as-error for that warning.
+
+- [MichaÅ Fita brought this change]
+
+  configure: add --disable-rt option
+  
+  This option disables any attempts in configure to create dependency on
+  stuff requiring linking to librt.so and libpthread.so, in this case this
+  means clock_gettime(CLOCK_MONOTONIC, &mt).
+  
+  We were in need to build curl which doesn't link libpthread.so to avoid
+  the following bug:
+  https://sourceware.org/bugzilla/show_bug.cgi?id=16628.
+
+Kamil Dudka (23 Jul 2015)
+- http2: verify success of strchr() in http2_send()
+  
+  Detected by Coverity.
+  
+  Error: NULL_RETURNS:
+  lib/http2.c:1301: returned_null: "strchr" returns null (checked 103 out of 109 times).
+  lib/http2.c:1301: var_assigned: Assigning: "hdbuf" = null return value from "strchr".
+  lib/http2.c:1302: dereference: Incrementing a pointer which might be null: "hdbuf".
+  1300|
+  1301|     hdbuf = strchr(hdbuf, 0x0a);
+  1302|->   ++hdbuf;
+  1303|
+  1304|     authority_idx = 0;
+
+Jay Satiro (22 Jul 2015)
+- Windows: Fix VerifyVersionInfo calls
+  
+  - Fix the VerifyVersionInfo calls, which we use to test for the OS major
+  version, to also test for the minor version as well as the service pack
+  major and minor versions.
+  
+  MSDN: "If you are testing the major version, you must also test the
+  minor version and the service pack major and minor versions."
+  
+  https://msdn.microsoft.com/en-us/library/windows/desktop/ms725492.aspx
+  
+  Bug: https://github.com/bagder/curl/pull/353#issuecomment-123493098
+  Reported-by: Marcel Raad <MarcelRaad@users.noreply.github.com>
+
+- [Marcel Raad brought this change]
+
+  schannel: Replace deprecated GetVersion with VerifyVersionInfo
+
+Steve Holme (21 Jul 2015)
+- makefile: Added support for VC14
+
+Patrick Monnerat (21 Jul 2015)
+- os400: ebcdic wrappers for new functions. Upgrade ILE/RPG bindings.
+
+- libcurl: VERSIONINFO update
+  Addition of new procedures curl_pushheader_bynum and curl_pushheader_byname
+  requires VERSIONINFO updating.
+
+- http2: satisfy external references even if http2 is not compiled in.
+
+Daniel Stenberg (20 Jul 2015)
+- http2: add stream != NULL checks for reliability
+  
+  They should not trigger, but in case of internal problems we at least
+  avoid crashes this way.
+
+Jay Satiro (18 Jul 2015)
+- symbols-in-versions: Add new CURLSSLOPT_NO_REVOKE symbol
+
+- SSL: Add an option to disable certificate revocation checks
+  
+  New tool option --ssl-no-revoke.
+  New value CURLSSLOPT_NO_REVOKE for CURLOPT_SSL_OPTIONS.
+  
+  Currently this option applies only to WinSSL where we have automatic
+  certificate revocation checking by default. According to the
+  ssl-compared chart there are other backends that have automatic checking
+  (NSS, wolfSSL and DarwinSSL) so we could possibly accommodate them at
+  some later point.
+  
+  Bug: https://github.com/bagder/curl/issues/264
+  Reported-by: zenden2k <zenden2k@gmail.com>
+
+- runtests: Allow for spaces in curl custom path
+  
+  .. also fix some typos in test's FILEFORMAT spec.
+
+- [David Woodhouse brought this change]
+
+  ntlm_wb: Fix theoretical memory leak
+  
+  Static analysis indicated that my commit 9008f3d564 ("ntlm_wb: Fix
+  hard-coded limit on NTLM auth packet size") introduced a potential
+  memory leak on an error path, because we forget to free the buffer
+  before returning an error.
+  
+  Fix this.
+  
+  Although actually, it never happens in practice because we never *get*
+  here with state == NTLMSTATE_TYPE1. The state is always zero. That
+  might want cleaning up in a separate patch.
+  
+  Reported-by: Terri Oda
+
+- strerror: Add CRYPT_E_REVOKED to SSPI error strings
+
+Kamil Dudka (14 Jul 2015)
+- libtest: call PR_Cleanup() on exit if NSPR is used
+  
+  This prevents valgrind from reporting possibly lost memory that NSPR
+  uses for file descriptor cache and other globally allocated internal
+  data structures.
+  
+  Reported-by: Å tefan KremeÅ
+
+Jay Satiro (14 Jul 2015)
+- [John Malmberg brought this change]
+
+  openssl: VMS support for SHA256
+  
+  setup-vms.h: More symbols for SHA256, hacks for older VAX
+  
+  openssl.h: Use OpenSSL OPENSSL_NO_SHA256 macro to allow building on VAX.
+  
+  openssl.c: Use OpenSSL version checks and OPENSSL_NO_SHA256 macro to
+  allow building on VAX and 64 bit VMS.
+
+- examples: Fix typo in multi-single.c
+
+Daniel Stenberg (7 Jul 2015)
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Fix memory leak in push header array
+
+Dan Fandrich (2 Jul 2015)
+- test2041: fixed line endings in protocol part
+
+- cyassl: fixed mismatched sha256sum function prototype
+
+Daniel Stenberg (1 Jul 2015)
+- [moparisthebest brought this change]
+
+  SSL: Pinned public key hash support
+
+- examples: provide <DESC> sections
+
+- [John Malmberg brought this change]
+
+  OpenVMS: VMS Software, Inc now the supplier.
+  
+  setup-vms.h: Symbol case fixups submitted by Michael Steve
+  
+  build_gnv_curl_pcsi_desc.com: VSI aka as VMS Software, is now the
+  supplier of new versions of VMS.  The install kit needs to accept
+  VSI as a producer.
+
+Jay Satiro (30 Jun 2015)
+- multi: Move http2 push function declarations to header end
+  
+  This change necessary for binary compatibility.
+  
+  Prior to this change test 1135 failed due to the order of functions.
+
+- symbols-in-versions: Add new http2 push symbols
+  
+  Prior to this change test 1119 failed due to the missing symbols.
+
+Daniel Stenberg (30 Jun 2015)
+- RELEASE-NOTES: synced with e6749055d653
+
+- configure: disable libidn by default
+  
+  For security reasons, until there is a fix.
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-06/0143.html
+  Reported-by: Gustavo Grieco, Feist Josselin
+
+- SSL-PROBLEMS: mention WinSSL problems in WinXP
+
+- CODE_OF_CONDUCT.md: added
+  
+  Just to underscore how we treat each other in this project. Nothing new
+  really, but could be useful for newcomers and outsiders to see our
+  values.
+
+- tool_header_cb: fflush the header stream
+  
+  Flush the header stream when -D is used so that they are sent off
+  earlier.
+  
+  Bug: https://github.com/bagder/curl/issues/324
+  Reported-by: CÃ©dric Connes
+
+- [Roger Leigh brought this change]
+
+  tests: Distribute CMakeLists.txt files in subdirectories
+
+- CURLOPT_FAILONERROR.3: mention that it closes the connection
+  
+  Reported-by: bemoody
+  Bug: https://github.com/bagder/curl/issues/325
+
+- curl_multi_setopt.3: alpha sort the options
+
+- curl_multi_setopt.3: add the new push options
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Use nghttp2 library error code for error return value
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Harden header validation for curl_pushheader_byname
+  
+  Since we do prefix match using given header by application code
+  against header name pair in format "NAME:VALUE", and VALUE part can
+  contain ":", we have to careful about existence of ":" in header
+  parameter.  ":" should be allowed to match HTTP/2 pseudo-header field,
+  and other use of ":" in header must be treated as error, and
+  curl_pushheader_byname should return NULL.  This commit implements
+  this behaviour.
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  CURLMOPT_PUSHFUNCTION.3: Remove unused variable
+
+- CURLMOPT_PUSHFUNCTION.3: added example
+
+- http2: curl_pushheader_byname now takes a const char *
+
+- http2-serverpush.c: example code
+
+- http2: free all header memory after the push callback
+
+- http2: init the pushed transfer properly
+
+- http2: fixed the header accessor functions for the push callback
+
+- http2: setup the new pushed stream properly
+
+- http2: initial implementation of the push callback
+
+- http2: initial HTTP/2 server push types/docs
+
+- test1531: verify POSTFIELDSIZE set after add_handle
+  
+  Following the fix made in 903b6e05565bf.
+
+- pretransfer: init state.infilesize here, not in add_handle
+  
+  ... to properly support that options are set to the handle after it is
+  added to the multi handle.
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-06/0122.html
+  Reported-by: Stefan BÃ¼hler
+
+Jay Satiro (21 Jun 2015)
+- [Lior Kaplan brought this change]
+
+  tool_help: fix --tlsv1 help text to use >= for TLSv1
+
+- INSTALL: Advise use of non-native SSL for Windows <= XP
+  
+  Advise that WinSSL in versions <= XP will not be able to connect to
+  servers that no longer support the legacy handshakes and algorithms used
+  by those versions, and to use an alternate backend like OpenSSL instead.
+  
+  Bug: https://github.com/bagder/curl/issues/253
+  Reported-by: zenden2k <zenden2k@gmail.com>
+
+Kamil Dudka (19 Jun 2015)
+- curl_easy_setopt.3: restore contents removed by mistake
+  
+  ... in commit curl-7_43_0-18-g570076e
+
+Daniel Stenberg (19 Jun 2015)
+- curl_easy_setopt.3: mention CURLOPT_PIPEWAIT
+
+Jay Satiro (18 Jun 2015)
+- cookie: Fix bug in export if any-domain cookie is present
+  
+  In 3013bb6 I had changed cookie export to ignore any-domain cookies,
+  however the logic I used to do so was incorrect, and would lead to a
+  busy loop in the case of exporting a cookie list that contained
+  any-domain cookies. The result of that is worse though, because in that
+  case the other cookies would not be written resulting in an empty file
+  once the application is terminated to stop the busy loop.
+
+Dan Fandrich (18 Jun 2015)
+- FTP: fixed compiling with --disable-proxy, broken in b88f980a
+
+Daniel Stenberg (18 Jun 2015)
+- tool: always provide negotiate/kerberos options
+  
+  libcurl can still be built with it, even if the tool is not. Maintain
+  independence!
+
+- TODO: Support IDNA2008
+
+- [Viktor Szakats brought this change]
+
+  Makefile.m32: add support for CURL_LDFLAG_EXTRAS
+  
+  It is similar to existing CURL_CFLAG_EXTRAS, but for
+  extra linker option.
+
+- RTSP: removed another piece of dead code
+  
+  Coverity CID 1306668
+
+- openssl: fix use of uninitialized buffer
+  
+  Make sure that the error buffer is always initialized and simplify the
+  use of it to make the logic easier.
+  
+  Bug: https://github.com/bagder/curl/issues/318
+  Reported-by: sneis
+
+- examples: more descriptions
+
+- examples: add descriptions with <DESC>
+  
+  Using this fixed format for example descriptions, we can generate a
+  better list on the web site.
+
+- libcurl-errors.3: fix typo
+
+- curl_easy_setopt.3: option order doesn't matter
+
+- openssl: fix build with BoringSSL
+  
+  OPENSSL_load_builtin_modules does not exist in BoringSSL. Regression
+  from cae43a1
+
+- [Paul Howarth brought this change]
+
+  openssl: Fix build with openssl < ~ 0.9.8f
+  
+  The symbol SSL3_MT_NEWSESSION_TICKET appears to have been introduced at
+  around openssl 0.9.8f, and the use of it in lib/vtls/openssl.c breaks
+  builds with older openssls (certainly with 0.9.8b, which is the latest
+  older version I have to try with).
+
+- FTP: do the HTTP CONNECT for data connection blocking
+  
+  ** WORK-AROUND **
+  
+  The introduced non-blocking general behaviour for Curl_proxyCONNECT()
+  didn't work for the data connection establishment unless it was very
+  fast. The newly introduced function argument makes it operate in a more
+  blocking manner, more like it used to work in the past. This blocking
+  approach is only used when the FTP data connecting through HTTP proxy.
+  
+  Blocking like this is bad. A better fix would make it work more
+  asynchronously.
+  
+  Bug: https://github.com/bagder/curl/issues/278
+
+- bump: start the journey toward 7.44.0
+
+Jay Satiro (17 Jun 2015)
+- CURLOPT_ERRORBUFFER.3: Fix example, escape backslashes
+
+- CURLOPT_ERRORBUFFER.3: Improve example
+
+Version 7.43.0 (17 Jun 2015)
+
+Daniel Stenberg (17 Jun 2015)
+- RELEASE-NOTES: 7.43.0 release
+
+- THANKS: updated with 7.43.0 names
+
+- [Kamil Dudka brought this change]
+
+  http: do not leak basic auth credentials on re-used connections
+  
+  CVE-2015-3236
+  
+  This partially reverts commit curl-7_39_0-237-g87c4abb
+  
+  Reported-by: Tomas Tomecek, Kamil Dudka
+  Bug: http://curl.haxx.se/docs/adv_20150617A.html
+
+- [Kamil Dudka brought this change]
+
+  test2040: verify basic auth on re-used connections
+
+- SMB: rangecheck values read off incoming packet
+  
+  CVE-2015-3237
+  
+  Detected by Coverity. CID 1299430.
+  
+  Bug: http://curl.haxx.se/docs/adv_20150617B.html
+
+Jay Satiro (17 Jun 2015)
+- schannel: schannel_recv overhaul
+  
+  This commit is several drafts squashed together. The changes from each
+  draft are noted below. If any changes are similar and possibly
+  contradictory the change in the latest draft takes precedence.
+  
+  Bug: https://github.com/bagder/curl/issues/244
+  Reported-by: Chris Araman
+  
+  %%
+  %% Draft 1
+  %%
+  - return 0 if len == 0. that will have to be documented.
+  - continue on and process the caches regardless of raw recv
+  - if decrypted data will be returned then set the error code to CURLE_OK
+  and return its count
+  - if decrypted data will not be returned and the connection has closed
+  (eg nread == 0) then return 0 and CURLE_OK
+  - if decrypted data will not be returned and the connection *hasn't*
+  closed then set the error code to CURLE_AGAIN --only if an error code
+  isn't already set-- and return -1
+  - narrow the Win2k workaround to only Win2k
+  
+  %%
+  %% Draft 2
+  %%
+  - Trying out a change in flow to handle corner cases.
+  
+  %%
+  %% Draft 3
+  %%
+  - Back out the lazier decryption change made in draft2.
+  
+  %%
+  %% Draft 4
+  %%
+  - Some formatting and branching changes
+  - Decrypt all encrypted cached data when len == 0
+  - Save connection closed state
+  - Change special Win2k check to use connection closed state
+  
+  %%
+  %% Draft 5
+  %%
+  - Default to CURLE_AGAIN in cleanup if an error code wasn't set and the
+  connection isn't closed.
+  
+  %%
+  %% Draft 6
+  %%
+  - Save the last error only if it is an unrecoverable error.
+  
+  Prior to this I saved the last error state in all cases; unfortunately
+  the logic to cover that in all cases would lead to some muddle and I'm
+  concerned that could then lead to a bug in the future so I've replaced
+  it by only recording an unrecoverable error and that state will persist.
+  
+  - Do not recurse on renegotiation.
+  
+  Instead we'll continue on to process any trailing encrypted data
+  received during the renegotiation only.
+  
+  - Move the err checks in cleanup after the check for decrypted data.
+  
+  In either case decrypted data is always returned but I think it's easier
+  to understand when those err checks come after the decrypted data check.
+  
+  %%
+  %% Draft 7
+  %%
+  - Regardless of len value go directly to cleanup if there is an
+  unrecoverable error or a close_notify was already received. Prior to
+  this change we only acknowledged those two states if len != 0.
+  
+  - Fix a bug in connection closed behavior: Set the error state in the
+  cleanup, because we don't know for sure it's an error until that time.
+  
+  - (Related to above) In the case the connection is closed go "greedy"
+  with the decryption to make sure all remaining encrypted data has been
+  decrypted even if it is not needed at that time by the caller. This is
+  necessary because we can only tell if the connection closed gracefully
+  (close_notify) once all encrypted data has been decrypted.
+  
+  - Do not renegotiate when an unrecoverable error is pending.
+  
+  %%
+  %% Draft 8
+  %%
+  - Don't show 'server closed the connection' info message twice.
+  
+  - Show an info message if server closed abruptly (missing close_notify).
+
+Daniel Stenberg (16 Jun 2015)
+- [Paul Oliver brought this change]
+
+  Fix typo in docs
+  
+  s/curret/current/
+
+- [Viktor Szakats brought this change]
+
+  docs: update URLs
+
+- RELEASE-NOTES: synced with f29f2cbd00dbe5f
+
+- [Viktor Szakats brought this change]
+
+  README: use secure protocol for Git repository
+
+- [Viktor Szakats brought this change]
+
+  HTTP2.md: use SSL/TLS IETF URLs
+
+- [Viktor Szakats brought this change]
+
+  LICENSE-MIXING: update URLs
+  
+  * use SSL/TLS where available
+  * follow permanent redirects
+
+- LICENSE-MIXING: refreshed
+
+- curl_easy_duphandle: see also *reset
+
+- rtsp_do: fix DEAD CODE
+  
+  "At condition p_request, the value of p_request cannot be NULL."
+  
+  Coverity CID 1306668.
+
+- security:choose_mech fix DEAD CODE warning
+  
+  ... by removing the "do {} while (0)" block.
+  
+  Coverity CID 1306669
+
+- curl.1: netrc is in man section 5
+
+- curl.1: small format fix
+  
+  use \fI-style instead of .BR for references
+
+- urldata: store POST size in state.infilesize too
+  
+  ... to simplify checking when PUT _or_ POST have completed.
+  
+  Reported-by: Frank Meier
+  Bug: http://curl.haxx.se/mail/lib-2015-06/0019.html
+
+Dan Fandrich (14 Jun 2015)
+- test1530: added http to required features
+
+Jay Satiro (14 Jun 2015)
+- [Drake Arconis brought this change]
+
+  build: Fix typo from OpenSSL 1.0.2 version detection fix
+
+- [Drake Arconis brought this change]
+
+  build: Properly detect OpenSSL 1.0.2 when using configure
+
+- curl_multi_info_read.3: fix example formatting
+
+Daniel Stenberg (13 Jun 2015)
+- BINDINGS: there's a new R binding in town!
+
+- BINDINGS: added the Xojo binding
+
+Jay Satiro (11 Jun 2015)
+- [Joel Depooter brought this change]
+
+  schannel: Add support for optional client certificates
+  
+  Some servers will request a client certificate, but not require one.
+  This change allows libcurl to connect to such servers when using
+  schannel as its ssl/tls backend. When a server requests a client
+  certificate, libcurl will now continue the handshake without one,
+  rather than terminating the handshake. The server can then decide
+  if that is acceptable or not. Prior to this change, libcurl would
+  terminate the handshake, reporting a SEC_I_INCOMPLETE_CREDENTIALS
+  error.
+
+Daniel Stenberg (11 Jun 2015)
+- curl_easy_cleanup.3: provide more SEE ALSO
+
+- debug: remove http2 debug leftovers
+
+- VERSIONS: now using markdown
+
+- RELEASE-PROCEDURE: remove ascii logo at the top of file
+
+- INTERNALS: absorbed docs/LIBCURL-STRUCTS
+
+- INTERNALS: cat lib/README* >> INTERNALS
+  
+  and a conversion to markdown. Removed the lib/README.* files. The idea
+  being to move toward having INTERNALS as the one and only "book" of
+  internals documentation.
+  
+  Added a TOC to top of the document.
+
+Jay Satiro (8 Jun 2015)
+- openssl: LibreSSL and BoringSSL do not use TLS_client_method
+  
+  Although OpenSSL 1.1.0+ deprecated SSLv23_client_method in favor of
+  TLS_client_method LibreSSL and BoringSSL didn't and still use
+  SSLv23_client_method.
+  
+  Bug: https://github.com/bagder/curl/commit/49a6642#commitcomment-11578009
+  Reported-by: asavah@users.noreply.github.com
+
+Daniel Stenberg (9 Jun 2015)
+- RELEASE-NOTES: synced with 20ac3458068
+
+- CURLOPT_OPENSOCKETFUNCTION: return error at once
+  
+  When CURL_SOCKET_BAD is returned in the callback, it should be treated
+  as an error (CURLE_COULDNT_CONNECT) if no other socket is subsequently
+  created when trying to connect to a server.
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-06/0047.html
+
+- fopen.c: fix a few compiler warnings
+
+- [Ville SkyttÃ¤ brought this change]
+
+  docs: Spelling fixes
+
+- [Ville SkyttÃ¤ brought this change]
+
+  docs: man page indentation and syntax fixes
+
+Linus Nielsen (8 Jun 2015)
+- help: Add --proxy-service-name and --service-name to the --help output
+
+Jay Satiro (7 Jun 2015)
+- openssl: Fix verification of server-sent legacy intermediates
+  
+  - Try building a chain using issuers in the trusted store first to avoid
+  problems with server-sent legacy intermediates.
+  
+  Prior to this change server-sent legacy intermediates with missing
+  legacy issuers would cause verification to fail even if the client's CA
+  bundle contained a valid replacement for the intermediate and an
+  alternate chain could be constructed that would verify successfully.
+  
+  https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest
+
+Daniel Stenberg (5 Jun 2015)
+- BINDINGS: update several URLs
+  
+  Stop linking to the curl.haxx.se anchor pages, they are usually only
+  themselves pointers to the real page so better point there directly
+  instead.
+
+- BINDINGS: the curl-rust binding
+
+- curl.h: add CURL_HTTP_VERSION_2
+  
+  The protocol is named "HTTP/2" after all. It is an alias for the
+  existing CURL_HTTP_VERSION_2_0 enum.
+
+- openssl: removed error string #ifdef
+  
+  ERR_error_string_n() was introduced in 0.9.6, no need to #ifdef anymore
+
+- openssl: removed USERDATA_IN_PWD_CALLBACK kludge
+  
+  Code for OpenSSL 0.9.4 serves no purpose anymore!
+
+- openssl: remove SSL_get_session()-using code
+  
+  It was present for OpenSSL 0.9.5 code but we only support 0.9.7 or
+  later.
+
+- openssl: remove dummy callback use from SSL_CTX_set_verify()
+  
+  The existing callback served no purpose.
+
+- LIBCURL-STRUCTS: clarify for multiplexing
+
+Jay Satiro (3 Jun 2015)
+- cookie: Stop exporting any-domain cookies
+  
+  Prior to this change any-domain cookies (cookies without a domain that
+  are sent to any domain) were exported with domain name "unknown".
+  
+  Bug: https://github.com/bagder/curl/issues/292
+
+Daniel Stenberg (3 Jun 2015)
+- RELEASE-PROCEDURE: refreshed 'coming dates'
+
+Jay Satiro (2 Jun 2015)
+- curl_setup: Change fopen text macros to use 't' for MSDOS
+  
+  Bug: https://github.com/bagder/curl/pull/258#issuecomment-107915198
+  Reported-by: Gisle Vanem
+
+Daniel Stenberg (2 Jun 2015)
+- curl_multi_timeout.3: added example
+
+- curl_multi_perform.3: added example
+
+- curl_multi_info_read.3: added example
+
+- checksrc: detect fopen() for text without the FOPEN_* macros
+  
+  Follow-up to e8423f9ce150 with discussionis in
+  https://github.com/bagder/curl/pull/258
+  
+  This check scans for fopen() with a mode string without 'b' present, as
+  it may indicate that an FOPEN_* define should rather be used.
+
+- curl_getdate.3: update RFC reference
+
+Jay Satiro (1 Jun 2015)
+- curl_setup: Add macros for FOPEN_READTEXT, FOPEN_WRITETEXT
+  
+  - Change fopen calls to use FOPEN_READTEXT instead of "r" or "rt"
+  - Change fopen calls to use FOPEN_WRITETEXT instead of "w" or "wt"
+  
+  This change is to explicitly specify when we need to read/write text.
+  Unfortunately 't' is not part of POSIX fopen so we can't specify it
+  directly. Instead we now have FOPEN_READTEXT, FOPEN_WRITETEXT.
+  
+  Prior to this change we had an issue on Windows if an application that
+  uses libcurl overrides the default file mode to binary. The default file
+  mode in Windows is normally text mode (translation mode) and that's what
+  libcurl expects.
+  
+  Bug: https://github.com/bagder/curl/pull/258#issuecomment-107093055
+  Reported-by: Orgad Shaneh
+
+Daniel Stenberg (1 Jun 2015)
+- http2-upload.c: use PIPEWAIT for playing HTTP/2 better
+
+- http2-download: check for CURLPIPE_MULTIPLEX properly
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-06/0001.html
+  Reported-by: Rafayel Mkrtchyan
+
+- [Isaac Boukris brought this change]
+
+  HTTP-NTLM: fail auth on connection close instead of looping
+  
+  Bug: https://github.com/bagder/curl/issues/256
+
+- 5.6 Refuse "downgrade" redirects
+
+- README.pingpong: removed
+
+- ROADMAP: remove HTTP/2 multiplexing - its here now
+
+- HTTP2.md: formatted properly
+
+- HTTP2: moved docs into docs/ and make it markdown
+
+- README.http2: refreshed and added multiplexing info
+
+- dist: add the http2 examples
+
+- http2 examples: clean up some comments
+
+- examples: added two programs doing multiplexed HTTP/2
+
+- scripts: moved contributors.sh and contrithanks.sh into subdir
+
+- RELEASE-NOTES: synced with c005790ff1c0a
+
+- [Daniel Melani brought this change]
+
+  openssl: typo in comment
+
+Jay Satiro (27 May 2015)
+- openssl: Use TLS_client_method for OpenSSL 1.1.0+
+  
+  SSLv23_client_method is deprecated starting in OpenSSL 1.1.0. The
+  equivalent is TLS_client_method.
+  
+  https://github.com/openssl/openssl/commit/13c9bb3#diff-708d3ae0f2c2973b272b811315381557
+
+Daniel Stenberg (26 May 2015)
+- FAQ: How do I port libcurl to my OS?
+
+Jay Satiro (25 May 2015)
+- CURLOPT_COOKIELIST.3: Explain Set-Cookie without a domain
+  
+  Document that if Set-Cookie is used without a domain then the cookie is
+  sent for any domain and will not be modified.
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-05/0137.html
+  Reported-by: Alexander Dyagilev
+
+Daniel Stenberg (25 May 2015)
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Copy data passed in Curl_http2_switched into HTTP/2 connection buffer
+  
+  Previously, after seeing upgrade to HTTP/2, we feed data followed by
+  upgrade response headers directly to nghttp2_session_mem_recv() in
+  Curl_http2_switched().  But it turns out that passed buffer, mem, is
+  part of stream->mem, and callbacks called by
+  nghttp2_session_mem_recv() will write stream specific data into
+  stream->mem, overwriting input data.  This will corrupt input, and
+  most likely frame length error is detected by nghttp2 library.  The
+  fix is first copy the passed data to HTTP/2 connection buffer,
+  httpc->inbuf, and call nghttp2_session_mem_recv().
+
+Jay Satiro (24 May 2015)
+- CURLOPT_COOKIE.3: Explain that the cookies won't be modified
+  
+  The CURLOPT_COOKIE doc says it "sets the cookie header explicitly in the
+  outgoing request(s)." However there seems to be some user confusion
+  about cookie modification. Document that the cookies set by this option
+  are not modified by the cookie engine.
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-05/0115.html
+  Reported-by: Alexander Dyagilev
+
+- CURLOPT_COOKIELIST.3: Add example
+
+Dan Fandrich (24 May 2015)
+- testcurl.pl: use rel2abs to make the source directory absolute
+  
+  This function makes a platform-specific absolute path which uses
+  backslashes on Windows. This form works when passing it on the
+  command-line, as well as if the source is on another drive.
+
+- conncache: fixed memory leak on OOM (torture tests)
+
+Daniel Stenberg (24 May 2015)
+- perl: remove subdir, not touched in 9 years
+
+- log2changes.pl: moved to scripts/
+
+- [Alessandro Ghedini brought this change]
+
+  scripts: add zsh.pl for generating zsh completion
+
+Dan Fandrich (23 May 2015)
+- test1510: another flaky test
+
+Daniel Stenberg (22 May 2015)
+- security: fix "Unchecked return value" from sscanf()
+  
+  By (void) prefixing it and adding a comment. Did some minor related
+  cleanups.
+  
+  Coverity CID 1299423.
+
+- security: simplify choose_mech
+  
+  Coverity CID 1299424 identified dead code because of checks that could
+  never equal true (if the mechanism's name was NULL).
+  
+  Simplified the function by removing a level of pointers and removing the
+  loop and array that weren't used.
+
+- RTSP: catch attempted unsupported requests better
+  
+  Replace use of assert with code that properly catches bad input at
+  run-time even in non-debug builds.
+  
+  This flaw was sort of detected by Coverity CID 1299425 which claimed the
+  "case RTSPREQ_NONE" was dead code.
+
+- share_init: fix OOM crash
+  
+  A failed calloc() would lead to NULL pointer use.
+  
+  Coverity CID 1299427.
+
+- parse_proxy: switch off tunneling if non-HTTP proxy
+  
+  non-HTTP proxy implies not using CURLOPT_HTTPPROXYTUNNEL
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-05/0056.html
+  Reported-by: Sean Boudreau
+
+- curl: fix potential NULL dereference
+  
+  Coverity CID 1299428: Dereference after null check (FORWARD_NULL)
+
+- http2: on_frame_recv: return early on stream 0
+  
+  Coverity CID 1299426 warned about possible NULL dereference otherwise,
+  but that would only ever happen if we get invalid HTTP/2 data with
+  frames for stream 0. Avoid this risk by returning early when stream 0 is
+  used.
+
+- http: removed self assignment
+  
+  Follow-up fix from b0143a2a33f0
+  
+  Detected by coverity. CID 1299429
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Make HTTP Upgrade work
+  
+  This commit just add implicitly opened stream 1 to streams hash.
+
+Jay Satiro (22 May 2015)
+- strerror: Change SEC_E_ILLEGAL_MESSAGE description
+  
+  Prior to this change the description for SEC_E_ILLEGAL_MESSAGE was OS
+  and language specific, and invariably translated to something not very
+  helpful like: "The message received was unexpected or badly formatted."
+  
+  Bug: https://github.com/bagder/curl/issues/267
+  Reported-by: Michael Osipov
+
+- telnet: Fix read-callback change for Windows builds
+  
+  Refer to b0143a2 for more information on the read-callback change.
+
+Daniel Stenberg (21 May 2015)
+- CURLOPT_HTTPPROXYTUNNEL.3: only works with a HTTP proxy!
+
+Dan Fandrich (21 May 2015)
+- testcurl.pl: allow source to be in an arbitrary directory
+  
+  This way, the build directory can be located on an entirely different
+  filesystem from the source code (e.g. a tmpfs).
+
+Daniel Stenberg (20 May 2015)
+- read_callback: move to SessionHandle from connectdata
+  
+  With many easy handles using the same connection for multiplexing, it is
+  important we store and keep the transfer-oriented stuff in the
+  SessionHandle so that callbacks and callback data work fine even when
+  many easy handles share the same physical connection.
+
+- http2: show stream IDs in decimal
+  
+  It makes them easier to match output from the nghttpd test server.
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Faster http2 upload
+  
+  Previously, when we send all given buffer in data_source_callback, we
+  return NGHTTP2_ERR_DEFERRED, and nghttp2 library removes this stream
+  temporarily for writing.  This itself is good.  If this is the sole
+  stream in the session, nghttp2_session_want_write() returns zero,
+  which means that libcurl does not check writeability of the underlying
+  socket.  This leads to very slow upload, because it seems curl only
+  upload 16k something per 1 second.  To fix this, if we still have data
+  to send, call nghttp2_session_resume_data after nghttp2_session_send.
+  This makes nghttp2_session_want_write() returns nonzero (if connection
+  window still opens), and as a result, socket writeability is checked,
+  and upload speed becomes normal.
+
+- [Dmitry Eremin-Solenikov brought this change]
+
+  gtls: don't fail on non-fatal alerts during handshake
+  
+  Stop curl from failing when non-fatal alert is received during
+  handshake.  This e.g. fixes lots of problems when working with https
+  sites through proxies.
+
+- curl_easy_unescape.3: update RFC reference
+  
+  Reported-by: bsammon
+  Bug: https://github.com/bagder/curl/issues/282
+
+Jay Satiro (20 May 2015)
+- CURLOPT_POSTFIELDS.3: Mention curl_easy_escape
+  
+  .. also correct some variable naming in curl_easy_escape.3
+  
+  Bug: https://github.com/bagder/curl/issues/281
+  Reported-by: bsammon@users.noreply.github.com
+
+Daniel Stenberg (19 May 2015)
+- [Brian Prodoehl brought this change]
+
+  openssl: Use SSL_CTX_set_msg_callback and SSL_CTX_set_msg_callback_arg
+  
+  BoringSSL removed support for direct callers of SSL_CTX_callback_ctrl
+  and SSL_CTX_ctrl, so move to a way that should work on BoringSSL and
+  OpenSSL.
+  
+  re #275
+
+Jay Satiro (19 May 2015)
+- curl.1: fix missing space in section --data
+
+Daniel Stenberg (19 May 2015)
+- transfer: remove erroneous and misleading comment
+
+Kamil Dudka (19 May 2015)
+- http: silence compile-time warnings without USE_NGHTTP2
+  
+  Error: CLANG_WARNING:
+  lib/http.c:173:16: warning: Value stored to 'http' during its initialization is never read
+  
+  Error: COMPILER_WARNING:
+  lib/http.c: scope_hint: In function âhttp_disconnectâ
+  lib/http.c:173:16: warning: unused variable âhttpâ [-Wunused-variable]
+
+Jay Satiro (19 May 2015)
+- transfer: Replace __func__ instances with function name
+  
+  .. also make __func__ replacement in multi.
+  
+  Prior to this change debug builds would fail to build if the compiler
+  was building pre-c99 and didn't support __func__.
+
+Daniel Stenberg (19 May 2015)
+- [Viktor Szakats brought this change]
+
+  build: bump version in default nghttp2 paths
+
+- INTERNALS: we require nghttp2 1.0.0+ now
+
+Jay Satiro (18 May 2015)
+- http: Add some include guards for the new HTTP/2 stuff
+
+Daniel Stenberg (18 May 2015)
+- http2: store upload state per stream
+  
+  Use a curl_off_t for upload left
+
+- http2: fix build when NOT h2-enabled
+
+- http2: switch to use Curl_hash_destroy()
+  
+  as after 4883f7019d3, the *_clean() function only flushes the hash.
+
+- curlver: restore LIBCURL_VERSION_NUM defined as a full number
+  
+  As it breaks configure, curl-config and test 1023 if not.
+
+- [Anthony Avina brought this change]
+
+  hostip: fix unintended destruction of hash table
+  
+  .. and added unit1602 for hash.c
+
+- curlver: introducing new version number (checking) macros
+
+- runtests.pl: use 'h2c' now, no -14 anymore
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Ignore if we have stream ID not in hash in on_stream_close
+  
+  We could get stream ID not in the hash in on_stream_close.  For
+  example, if we decided to reject stream (e.g., PUSH_PROMISE), then we
+  don't create stream and store it in hash with its stream ID.
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  Require nghttp2 v1.0.0
+  
+  This commit requires nghttp2 v1.0.0 to compile, and migrate to v1.0.0,
+  and utilize recent version of nghttp2 to simplify the code,
+  
+  First we use nghttp2_option_set_no_recv_client_magic function to
+  detect nghttp2 v1.0.0.  That function only exists since v1.0.0.
+  
+  Since nghttp2 v0.7.5, nghttp2 ensures header field ordering, and
+  validates received header field.  If it found error, RST_STREAM with
+  PROTOCOL_ERROR is issued.  Since we require v1.0.0, we can utilize
+  this feature to simplify libcurl code.  This commit does this.
+  
+  Migration from 0.7 series are done based on nghttp2 migration
+  document.  For libcurl, we removed the code sending first 24 bytes
+  client magic.  It is now done by nghttp2 library.
+  on_invalid_frame_recv callback signature changed, and is updated
+  accordingly.
+
+- http2: infof length in on_frame_send()
+
+- pipeline: switch some code over to functions
+  
+  ... to "compartmentalize" a bit and make it easier to change behavior
+  when multiplexing is used instead of good old pipelining.
+
+- symbols-in-versions: add CURLOPT_PIPEWAIT
+
+- CURLOPT_PIPEWAIT: added
+  
+  By setting this option to 1 libcurl will wait for a connection to reveal
+  if it is possible to pipeline/multiplex on before it continues.
+
+- Curl_http_readwrite_headers: minor code simplification
+
+- IsPipeliningPossible: fixed for http2
+
+- http2: bump the h2 buffer size to 32K for speed
+
+- http2: remove the stream from the hash in stream_close callback
+  
+  ... and suddenly things work much better!
+
+- http2: if there is paused data, do not clear the drain field
+
+- http2: rename s/data/pausedata
+
+- http2: "stream %x" in all outputs to make it easier to search for
+
+- http2: Curl_expire() all handles with incoming traffic
+  
+  ... so that they'll get handled next in the multi loop.
+
+- http2: don't signal settings change for same values
+
+- http2: set default concurrency, fix ConnectionExists for multiplex
+
+- bundles: store no/default/pipeline/multiplex
+  
+  to allow code to act differently on the situation.
+  
+  Also added some more info message for the connection re-use function to
+  make it clearer when connections are not re-used.
+
+- http2: lazy init header_recvbuf
+  
+  It makes us use less memory when not doing HTTP/2 and subsequently also
+  makes us not have to cleanup HTTP/2 related data when not using HTTP/2!
+
+- http2: separate multiplex/pipelining + cleanup memory leaks
+
+- CURLMOPT_PIPELINE: bit 1 is for multiplexing
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Fix bug that data to be drained are overwritten by pending "paused" data
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Don't call nghttp2_session_mem_recv while it is paused by a stream
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Read data left in connection buffer after pause
+  
+  Previously when we do pause because of out of buffer, we just throw
+  away unread data in connection buffer.  This just broke protocol
+  framing, and I saw occasional FRAME_SIZE_ERROR.  This commit fix this
+  issue by remembering how much data read, and in the next iteration, we
+  process remaining data.
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Fix streams get stuck
+  
+  This commit fixes the bug that streams get stuck if stream gets some
+  DATA, and stream->closed becomes true at the same time.  Previously,
+  in this condition, after we processed DATA, we are going to try to
+  read data from underlying transport, but there is no data, and gets
+  EAGAIN.  There was no code path to evaludate stream->closed.
+
+- http2: store incoming h2 SETTINGS
+
+- pipeline: move function to pipeline.c and make static
+  
+  ... as it was only used from there.
+
+- IsPipeliningPossible: http2 can always "pipeline" (multiplex)
+
+- http2: remove debug logging from on_frame_recv
+
+- http2: remove the closed check in http2_recv
+  
+  With the "drained" functionality we can get here slightly asynchronously
+  so the stream have have been closed but there is pending data left to
+  read.
+
+- http2: bump the h2 buffer to 8K
+
+- http2: Curl_read should not use the single buffer
+  
+  ... as it does for pipelining when we're multiplexing, as we need the
+  different buffers to store incoming data correctly for all streams.
+
+- http2: more debug outputs
+
+- http2: leave WAITPERFORM when conn is multiplexed
+  
+  No need to wait for our "spot" like for pipelining
+
+- http2: force "drainage" of streams
+  
+  ... which is necessary since the socket won't be readable but there is
+  data waiting in the buffer.
+
+- http2: move the mem+len pair to the stream struct
+
+- http2: more stream-oriented data, stream ID 0 is for connections
+
+- http2: move lots of state data to the 'stream' struct
+  
+  ... from the connection struct. The stream one being the 'struct HTTP'
+  which is kept in the SessionHandle struct (easy handle).
+  
+  lookup streams for incoming frames in the stream hash, hashing is based
+  on the stream id and we get the SessionHandle for the incoming stream
+  that way.
+
+- HTTP: partial start at fixing up hash-lookups on http2 frame receival
+
+- http: a stream hash for h2 multiplexing
+
+- http: a stream hash for h2 multiplexing
+
+- http2: debug log when receiving unexpected stream_id
+
+- http2: move stream_id to the HTTP struct (per-stream)
+
+- Curl_http2_setup: only do it once and enable multiplex on the server
+  
+  Once we know we are HTTP/2 enabled we know the server can multiplex.
+
+- http: switch on "pipelining" (multiplexing) for HTTP/2 servers
+  
+  ... and do not blacklist any.
+
+- README.pipelining: removed
+  
+  All the details mentioned here are better documented in man pages
+
+Dan Fandrich (14 May 2015)
+- build: removed bundles.c from make files
+  
+  This file was removed in commit fd137786
+
+Daniel Stenberg (14 May 2015)
+- Curl_conncache_add_conn: fix memory leak on OOM
+
+- CURLMOPT_MAX_HOST_CONNECTIONS: host = host name + port number
+
+- conncache: keep bundles on host+port bases, not only host names
+  
+  Previously we counted all connections to a specific host name and that
+  would be used for the CURLMOPT_MAX_HOST_CONNECTIONS check for example,
+  while servers on different port numbers are normally considered
+  different "origins" on the web and should thus be considered different
+  hosts.
+
+- bundles: merged into conncache.c
+  
+  All the existing Curl_bundle* functions were only ever used from within
+  the conncache.c file, so I moved them over and made them static (and
+  removed the Curl_ prefix).
+
+- hostcache: made all host caches use structs, not pointers
+  
+  This avoids unnecessary dynamic allocs and as this also removed the last
+  users of *hash_alloc() and *hash_destroy(), those two functions are now
+  removed.
+
+- multi: converted socket hash into non-allocated struct
+  
+  avoids extra dynamic allocation
+
+- connection cache: avoid Curl_hash_alloc()
+  
+  ... by using plain structs instead of pointers for the connection cache,
+  we can avoid several dynamic allocations that weren't necessary.
+
+- proxy: add newline to info message
+
+Patrick Monnerat (8 May 2015)
+- FTP: fix dangling conn->ip_addr dereference on verbose EPSV.
+
+- FTP: Make EPSV use the control IP address rather than the original host.
+  This ensures an alternate address is not used.
+  Does not apply to proxy tunnel.
+
+Daniel Stenberg (8 May 2015)
+- [Alessandro Ghedini brought this change]
+
+  tool_help: fix formatting for --next option
+
+- [Egon Eckert brought this change]
+
+  opts: improved the TCP keepalive examples
+
+Jay Satiro (8 May 2015)
+- winbuild: Document the option used to statically link the CRT
+  
+  - Document option RTLIBCFG (runtime library configuration).
+  
+  Bug: https://github.com/bagder/curl/issues/254
+  Reported-by: Bert Huijben
+
+- [Orgad Shaneh brought this change]
+
+  netrc: Read in text mode when cygwin
+  
+  Use text mode when cygwin to eliminate trailing carriage returns.
+  
+  Bug: https://github.com/bagder/curl/pull/258
+
+Patrick Monnerat (5 May 2015)
+- OS400: Add SPNEGO service name options to ILE/RPG binding.
+
+Daniel Stenberg (4 May 2015)
+- curl_multi_info_read.3: fix typo
+  
+  Reported-by: Liviu Chircu
+
+- MANUAL: language fix
+  
+  Reported-by: Fred Stluka
+  Bug: https://github.com/bagder/curl/issues/255
+
+- [Alessandro Ghedini brought this change]
+
+  gtls: properly retrieve certificate status
+  
+  Also print the revocation reason if appropriate.
+
+- OpenSSL: conditional check for SSL3_RT_HEADER
+  
+  The symbol is fairly new.
+  
+  Reported-by: Kamil Dudka
+
+- openssl: skip trace outputs for ssl_ver == 0
+  
+  The OpenSSL trace callback is wonderfully undocumented but given a
+  journey in the source code, it seems the cases were ssl_ver is zero
+  doesn't follow the same pattern and thus turned out confusing and
+  misleading. For now, we skip doing any CURLINFO_TEXT logging on those
+  but keep sending them as CURLINFO_SSL_DATA_OUT/IN.
+  
+  Also, I added direction to the text info and I edited some functions
+  slightly.
+  
+  Bug: https://github.com/bagder/curl/issues/219
+  Reported-by: Jay Satiro, Ashish Shukla
+
+Marc Hoersken (2 May 2015)
+- schannel.c: Small changes
+
+- schannel.c: Improve code path and readability
+
+- schannel.c: Improve error and return code handling upon aa99a63f03
+
+- [Chris Araman brought this change]
+
+  schannel: fix regression in schannel_recv
+  
+  https://github.com/bagder/curl/issues/244
+  
+  Commit 145c263 changed the behavior when Curl_read_plain returns
+  CURLE_AGAIN. We now handle CURLE_AGAIN and SEC_I_CONTEXT_EXPIRED
+  correctly.
+
+- Bug born in changes made several days ago 9a91e80.
+  
+  Commit: https://github.com/bagder/curl/commit/926cb9f
+  Reported-by: Ray Satiro
+
+Daniel Stenberg (30 Apr 2015)
+- [Michael Osipov brought this change]
+
+  configure: remove missing and make it autogenerate
+  
+  The missing file has not been autogenerated because a temporary fix was
+  employed in acinclude.m4 which blocked update. Removed that fix and a recent
+  version of missing is copied to build root.
+
+- [Michael Osipov brought this change]
+
+  acinclude.m4: fix test for default CA cert bundle/path
+  
+  test(1) on HP-UX requires a single equals sign and fails with two.
+  Let's use one and make every OS happy.
+
+- CONTRIBUTING.md: remove the sourceforge mention
+  
+  Reported-By: Michael Osipov
+
+Dan Fandrich (30 Apr 2015)
+- http_negotiate_sspi: added missing data variable
+
+Daniel Stenberg (30 Apr 2015)
+- [Michael Osipov brought this change]
+
+  configure: remove --automake from libtoolize call
+  
+  That option is not mentioned in the man page of libtoolize 2.4.4.19-fda4.
+  Moveover, a comment in line 2623 says "--automake is for 1.5 compatibility".
+  
+  This option is redundant now.
+
+- [Viktor Szakats brought this change]
+
+  build: update depedency versions, urls, example makefiles
+  
+  - update default versions of dependencies (except for rare/old platforms)
+  - update urls
+  - sync examples makefiles with main ones
+  - remove line ending space
+
+- [Michael Osipov brought this change]
+
+  configure: remove autogenerated files by autoconf
+  
+  * install-sh is always regenerated
+  * mkinstalldirs was already redudant years ago. Automake uses install for
+    that. See: http://lists.gnu.org/archive/html/automake/2007-03/msg00015.html
+
+- [Anders Bakken brought this change]
+
+  curl_multi_add_handle: next is already NULL
+
+Jay Satiro (30 Apr 2015)
+- schannel: Fix out of bounds array
+  
+  Bug born in changes made several days ago 9a91e80.
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-04/0199.html
+  Reported-by: Brian Chrisman
+
+- docs/libcurl: gitignore libcurl-symbols.3
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-04/0191.html
+  Reported-by: Michael Osipov
+
+- [Viktor Szakats brought this change]
+
+  lib/makefile.m32: add arch -m32/-m64 to LDFLAGS
+  
+  This fixes using a multi-target mingw distro to build curl .dll for the
+  non-default target.
+  (mirroring the same patch present in src/makefile.m32)
+
+Daniel Stenberg (29 Apr 2015)
+- RELEASE-NOTES: synced with cd39b944afc
+  
+  I've not mentioned the bug fixes that were shipped in 7.42.1 from the
+  7_42 branch.
+
+- THANKS: merged from the 7.42.1 release
+
+- CURLOPT_HEADEROPT: default to separate
+  
+  Make the HTTP headers separated by default for improved security and
+  reduced risk for information leakage.
+  
+  Bug: http://curl.haxx.se/docs/adv_20150429.html
+  Reported-by: Yehezkel Horowitz, Oren Souroujon
+
+Linus Nielsen (28 Apr 2015)
+- docs/libcurl: Corrected a typo in the CURLOPT_PROXY_SERVICE_NAME documentation
+
+Daniel Stenberg (28 Apr 2015)
+- hash: simplify Curl_str_key_compare()
+
+- dist: ship CURLOPT_PROXY_SERVICE_NAME and CURLOPT_SERVICE_NAME
+
+- [Linus Nielsen brought this change]
+
+  Negotiate: custom service names for SPNEGO.
+  
+  * Add new options, CURLOPT_PROXY_SERVICE_NAME and CURLOPT_SERVICE_NAME.
+  * Add new curl options, --proxy-service-name and --service-name.
+
+- http2: unify http_conn variable names to 'c'
+
+- ConnectionExists: call it multi-use instead of pipelining
+  
+  So that it fits HTTP/2 as well
+
+Kamil Dudka (27 Apr 2015)
+- [Paul Howarth brought this change]
+
+  nss: fix compilation failure with old versions of NSS
+  
+  Bug: http://curl.haxx.se/mail/lib-2015-04/0095.html
+
+Daniel Stenberg (27 Apr 2015)
+- sws: init http2 state properly
+  
+  It would otherwise cause problems when running tests after 1801 etc.
+
+- curl_easy_getinfo.3: document 'internals' in CURLINFO_TLS_SESSION
+  
+  ... as it was previouly undocumented what the pointer was.
+
+- runtests: use a DISABLED.local file too
+  
+  ... and have git ignore that. Allows for a dev to add tests to ignore in
+  local tests and yet don't obstruct a normal git work flow.
+
+Marc Hoersken (26 Apr 2015)
+- schannel.c: Fix typo introduced with 3447c973d0
+
+- schannel.c: Fix possible SEC_E_BUFFER_TOO_SMALL error
+  
+  Reported-by: Brian Chrisman
+
+Daniel Stenberg (26 Apr 2015)
+- schannel: re-indented file to follow curl style better
+  
+  white space changes only
+
+- Curl_ossl_init: load builtin modules
+  
+  To have engine modules work, we must tell openssl to load builtin
+  modules first.
+  
+  Bug: https://github.com/bagder/curl/pull/206
+
+- configure: follow-up fix for krb5-config
+  
+  commit 5b66860652 was incomplete so here's a follow-up fix
+  
+  Reported-by: Dagobert Michelsen
+  Bug: https://github.com/bagder/curl/commit/5b668606527613179d0349f21b4ab0df2971e3d2#commitcomment-10473445
+
+- openssl: fix serial number output
+  
+  The code extracting the cert serial number was broken and didn't display
+  it properly.
+  
+  Bug: https://github.com/bagder/curl/issues/235
+  Reported-by: dkjjr89
+
+- [Grant Pannell brought this change]
+
+  sasl_sspi: Populate domain from the realm in the challenge
+  
+  Without this, SSPI based digest auth was broken.
+  
+  Bug: https://github.com/bagder/curl/pull/141.patch
+
+Jay Satiro (25 Apr 2015)
+- [Anthony Avina brought this change]
+
+  tool: New option --data-raw to HTTP POST data, '@' allowed.
+  
+  Add new option --data-raw which is almost the same as --data but does
+  not have a special interpretation of the @ character.
+  
+  Prior to this change there was no (easy) way to pass the @ character as
+  the first character in POST data without it being interpreted as a
+  special character.
+  
+  Bug: https://github.com/bagder/curl/issues/198
+  Reported-by: Jens Rantil
+
+Dan Fandrich (25 Apr 2015)
+- test2039: fixed line endings that caused a test failure
+
+Daniel Stenberg (24 Apr 2015)
+- [Viktor Szakats brought this change]
+
+  netrc: add unit tests for 'default' support
+
+- [Viktor Szakats brought this change]
+
+  netrc: support 'default' token
+  
+  The 'default' token has no argument and means to match _any_ domain.
+  It must be placed last if there are 'machine <name>' tokens in the same file.
+  
+  See full description here:
+  https://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-File.html
+
+- ROADMAP.md: extended the HTTP/2 section, reformatted
+  
+  Elaborated on several of the remaining HTTP/2 parts and made document
+  use a format that ends up nicer on the web page:
+  http://curl.haxx.se/dev/roadmap.html
+
+Kamil Dudka (23 Apr 2015)
+- curl -z: do not write empty file on unmet condition
+  
+  This commit fixes a regression introduced in curl-7_41_0-186-g261a0fe.
+  It also introduces a regression test 1424 based on tests 78 and 1423.
+  
+  Reported-by: Viktor Szakats
+  Bug: https://github.com/bagder/curl/issues/237
+
+Dan Fandrich (23 Apr 2015)
+- tool: fixed a comment typo
+
+- README: convert to UTF-8
+
+Jay Satiro (22 Apr 2015)
+- cyassl: Implement public key pinning
+  
+  Also add public key extraction example to CURLOPT_PINNEDPUBLICKEY doc.
+
+Dan Fandrich (22 Apr 2015)
+- [Alessandro Ghedini brought this change]
+
+  curl.1: fix typo
+
+Kamil Dudka (22 Apr 2015)
+- docs: distribute the CURLOPT_PINNEDPUBLICKEY(3) man page, too
+
+- tests/unit/.gitignore: hide unit1601 and above, too
+
+Daniel Stenberg (22 Apr 2015)
+- connectionexists: follow-up to fd9d3a1ef1f
+  
+  PROTOPT_CREDSPERREQUEST still needs to be checked even when NTLM is not
+  enabled.
+  
+  Mistake-caught-by: Kamil Dudka
+
+- connectionexists: fix build without NTLM
+  
+  Do not access NTLM-specific struct fields when built without NTLM
+  enabled!
+  
+  bug: http://curl.haxx.se/?i=231
+  Reported-by: Patrick Rapin
+
+- bump: start working toward 7.43.0
+
+Kamil Dudka (22 Apr 2015)
+- nss: implement public key pinning for NSS backend
+  
+  Bug: https://bugzilla.redhat.com/1195771
+
+Daniel Stenberg (22 Apr 2015)
+- dist: include {src,lib}/checksrc.whitelist
+
+Version 7.42.0 (22 Apr 2015)
+
+Daniel Stenberg (22 Apr 2015)
+- RELEASE-NOTES: updated for 7.42.0
+
+- THANKS: added contributors from 7.42.0 release notes
+
+- THANKS-filter: a few more alterations to squash
+
+- contrithanks.sh: helper script for maintaining THANKS
+
+- http_done: close Negotiate connections when done
+  
+  When doing HTTP requests Negotiate authenticated, the entire connnection
+  may become authenticated and not just the specific HTTP request which is
+  otherwise how HTTP works, as Negotiate can basically use NTLM under the
+  hood. curl was not adhering to this fact but would assume that such
+  requests would also be authenticated per request.
+  
+  CVE-2015-3148
+  
+  Bug: http://curl.haxx.se/docs/adv_20150422B.html
+  Reported-by: Isaac Boukris
+
+- fix_hostname: zero length host name caused -1 index offset
+  
+  If a URL is given with a zero-length host name, like in "http://:80" or
+  just ":80", `fix_hostname()` will index the host name pointer with a -1
+  offset (as it blindly assumes a non-zero length) and both read and
+  assign that address.
+  
+  CVE-2015-3144
+  
+  Bug: http://curl.haxx.se/docs/adv_20150422D.html
+  Reported-by: Hanno BÃ¶ck
+
+- cookie: cookie parser out of boundary memory access
+  
+  The internal libcurl function called sanitize_cookie_path() that cleans
+  up the path element as given to it from a remote site or when read from
+  a file, did not properly validate the input. If given a path that
+  consisted of a single double-quote, libcurl would index a newly
+  allocated memory area with index -1 and assign a zero to it, thus
+  destroying heap memory it wasn't supposed to.
+  
+  CVE-2015-3145
+  
+  Bug: http://curl.haxx.se/docs/adv_20150422C.html
+  Reported-by: Hanno BÃ¶ck
+
+- ConnectionExists: for NTLM re-use, require credentials to match
+  
+  CVE-2015-3143
+  
+  Bug: http://curl.haxx.se/docs/adv_20150422A.html
+  Reported-by: Paras Sethia
+
+Jay Satiro (21 Apr 2015)
+- [byronhe brought this change]
+
+  openssl: add OPENSSL_NO_SSL3_METHOD check
+
+Daniel Stenberg (20 Apr 2015)
+- CURLOPT_HEADERFUNCTION.3: match parameter name in synopsis and desc
+  
+  Bug: https://github.com/bagder/curl/issues/229
+  Reported-by: bsammon
+
+Kamil Dudka (20 Apr 2015)
+- [Mostyn Bramley-Moore brought this change]
+
+  configure --with-nss: remove unneeded libs from the fallback
+
+Daniel Stenberg (20 Apr 2015)
+- contributors.sh: fix help output, filter out (-prefix from names
+
+- RELEASE-NOTES: synced with cc0e7ebc3be0
+
+- [Michael Stapelberg brought this change]
+
+  CURLMOPT_TIMERFUNCTION.3: Clarify, add an example
+
+- [Viktor SzakÃ¡ts brought this change]
+
+  vtls/openssl: use https in URLs and a comment typo fixed
+
+- curl_version_info.3: fixed the 'protocols' variable type
+  
+  Reported-by: John Marshall
+  Bug: https://github.com/bagder/curl/issues/225
+
+Dan Fandrich (18 Apr 2015)
+- test1423: added missing "file" to server section
+
+Daniel Stenberg (17 Apr 2015)
+- TheArtOfHttpScripting: Multiple URLs + Multiple HTTP methods
+  
+  ... and some minor edits
+
+- Revert "HTTP: don't abort connections with pending Negotiate authentication"
+  
+  This reverts commit 5dc68dd6092a789bb5e0a67a1c1356ba87fdcbc6.
+  
+  Bug: https://github.com/bagder/curl/issues/223
+  Reported-by: Michael Osipov
+
+Jay Satiro (17 Apr 2015)
+- cyassl: Fix include order
+  
+  Prior to this change CyaSSL's build options could redefine some generic
+  build symbols.
+  
+  http://curl.haxx.se/mail/lib-2015-04/0069.html
+
+Kamil Dudka (17 Apr 2015)
+- configure --with-nss: drop redundant if statement
+
+- configure --with-nss=PATH: query pkg-config if available
+  
+  Bug: https://github.com/bagder/curl/pull/171
+
+Daniel Stenberg (17 Apr 2015)
+- parsecfg: do not continue past a zero termination
+  
+  When a config file line ends without newline, the parsing function could
+  continue reading beyond that point in memory.
+  
+  Reported-by: Hanno BÃ¶ck
+
+Jay Satiro (16 Apr 2015)
+- gitignore: Ignore Windows build output directories
+
+Daniel Stenberg (15 Apr 2015)
+- RELEASE-NOTES: synced with 1ba6e4c88e0
+
+- TODO: 17.9 Choose the name of file in braces for complex URLs
+
+- TODO: a little caution that maybe not all ideas are still good
+
+- TODO: 17.8 offer color-coded HTTP header output
+
+- TODO: 17.7 warning when sending binary output to terminal
+
+- KNOWN_BUGS: #90 IMAP "SEARCH ALL" truncates output on large boxes
+
+Jay Satiro (14 Apr 2015)
+- cyassl: Add support for TLS extension SNI
+
+Daniel Stenberg (13 Apr 2015)
+- [Matthew Hall brought this change]
+
+  gitignore: ignore test-driver file
+
+- [Matthew Hall brought this change]
+
+  vtls_openssl: improve PKCS#12 load failure error message
+
+- [Matthew Hall brought this change]
+
+  vtls_openssl: fix minor typo in PKCS#12 load routine
+
+- [Matthew Hall brought this change]
+
+  vtls_openssl: improve client certificate load failure error messages
+
+- [Matthew Hall brought this change]
+
+  vtls_openssl: remove ambiguous SSL_CLIENT_CERT_ERR constant
+
+- BUGS: refer to the github issue tracker now as primary
+
+- firefox-db2pem: fix wildcard to find Firefox default profile
+  
+  At some point, Firefox has changed and generates different directory
+  names for the default profile that made this script fail to find them.
+  
+  Bug: https://github.com/bagder/curl/issues/207
+  Reported-by: sneakyimp
+
+Jay Satiro (11 Apr 2015)
+- cyassl: Include the CyaSSL build config
+  
+  CyaSSL >= 2.6.0 may have an options.h that was generated during
+  its build by configure.
+
+- build: Generate source prerequisites for Visual Studio in generate.bat
+  
+  Prior to this change Visual Studio builds could fail due to missing
+  prerequisites src/tool_hugehelp.c and include/curl/curlbuild.h.
+  
+  http://curl.haxx.se/mail/lib-2015-04/0034.html
+
+Daniel Stenberg (9 Apr 2015)
+- [Viktor Szakats brought this change]
+
+  lib/makefile.m32: add missing libs to build libcurl.dll
+  
+  Add 'gdi32' and 'crypt32' Windows implibs to avoid failure
+  while building libcurl.dll using the mingw compiler.
+  The same logic is used in 'src/makefile.m32' when
+  building curl.exe.
+
+Kamil Dudka (8 Apr 2015)
+- test142[23]: verify that an empty file is stored on success
+
+- src/tool_operate: create output file on successful download
+  
+  ... of an empty file
+  
+  Bug: https://github.com/bagder/curl/issues/183
+
+- src/tool_cb_wrt: separate fnc for output file creation
+
+Daniel Stenberg (7 Apr 2015)
+- [Da-Yoon Chung brought this change]
+
+  lib/transfer.c: Remove factor of 8 from sleep time calculation
+  
+  The factor of 8 is a bytes-to-bits conversion factor, but pkt_size and
+  rate_bps are both in bytes. When using the rate limiting option, curl
+  waits 8 times too long, and then transfers very quickly until the
+  average rate reaches the limit. The average rate follows the limit over
+  time, but the actual traffic is bursty.
+  
+  Thanks-to: Benjamin Gilbert
+
+- [Jay Satiro brought this change]
+
+  x509asn1: Silence x64 loss-of-data warning on RSA key length assignment
+  
+  The key length in bits will always fit in an unsigned long so the
+  loss-of-data warning assigning the result of x64 pointer arithmetic to
+  an unsigned long is unnecessary.
+
+- [Jay Satiro brought this change]
+
+  cyassl: Use CYASSL_MAX_ERROR_SZ for error buffer size
+  
+  Also fix it so that all ERR_error_string calls use an error buffer.
+  CyaSSL's implementation of ERR_error_string only writes the error when
+  an error buffer is passed.
+  
+  http://www.yassl.com/forums/topic599-openssl-compatibility-and-errerrorstring.html
+
+- [Jay Satiro brought this change]
+
+  cyassl: Remove 'Connecting to' message from cyassl_connect_step2
+  
+  Prior to this change libcurl could show multiple 'CyaSSL: Connecting to'
+  messages since cyassl_connect_step2 is called multiple times, typically.
+  The message is superfluous even once since libcurl already informs the
+  user elsewhere in code that it is connecting.
+
+- [Viktor Szakats brought this change]
+
+  checksrc.bat: quotes to support an SRC_DIR with spaces
+
+- hostip: fix compiler warnings
+  
+  introduced in the previous mini-series of 3 commits
+
+- [Stefan BÃ¼hler brought this change]
+
+  actually implement CURLOPT_RESOLVE removals
+  
+  - also log when a CURLOPT_RESOLVE entry couldn't get parsed
+
+- [Stefan BÃ¼hler brought this change]
+
+  move Curl_share_lock and ref counting into Curl_fetch_addr
+
+- [Stefan BÃ¼hler brought this change]
+
+  fix refreshing of obsolete dns cache entries
+  
+  - cache entries must be also refreshed when they are in use
+  - have the cache count as inuse reference too, freeing timestamp == 0 special
+    value
+  - use timestamp == 0 for CURLOPT_RESOLVE entries which don't get refreshed
+  - remove CURLOPT_RESOLVE special inuse reference (timestamp == 0 will prevent refresh)
+  - fix Curl_hostcache_clean - CURLOPT_RESOLVE entries don't have a special
+    reference anymore, and it would also release non CURLOPT_RESOLVE references
+  - fix locking in Curl_hostcache_clean
+  - fix unit1305.c: hash now keeps a reference, need to set inuse = 1
+
+- RELEASE-NOTES: synced with abf6bddc14a
+
+- [Jay Satiro brought this change]
+
+  checksrc.bat: Check lib\vtls source
+
+- [Jay Satiro brought this change]
+
+  cyassl: Set minimum protocol version before CTX callback
+  
+  This change is to allow the user's CTX callback to change the minimum
+  protocol version in the CTX without us later overriding it, as we did
+  prior to this change.
+
+- [Jay Satiro brought this change]
+
+  build-openssl.bat: Fix mixed line endings
+  
+  Use LF not CRLF, throughout.  msysgit will only convert a file to CRLF
+  on checkout if it's not mixed.
+
+- [Jay Satiro brought this change]
+
+  cyassl: Fix certificate load check
+  
+  SSL_CTX_load_verify_locations can return negative values on fail,
+  therefore to check for failure we check if load is != 1 (success)
+  instead of if load is == 0 (failure), the latter being incorrect given
+  that behavior.
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  http2: Fix missing nghttp2_session_send call in Curl_http2_switched
+  
+  Previously in Curl_http2_switched, we called nghttp2_session_mem_recv to
+  parse incoming data which were already received while curl was handling
+  upgrade.  But we didn't call nghttp2_session_send, and it led to make
+  curl not send any response to the received frames.  Most likely, we
+  received SETTINGS from server at this point, so we missed opportunity to
+  send SETTINGS + ACK.  This commit adds missing nghttp2_session_send call
+  in Curl_http2_switched to fix this issue.
+  
+  Bug: https://github.com/bagder/curl/issues/192
+  Reported-by: Stefan Eissing
+
+- cookie: handle spaces after the name in Set-Cookie
+  
+  "name =value" is fine and the space should just be skipped.
+  
+  Updated test 31 to also test for this.
+  
+  Bug: https://github.com/bagder/curl/issues/195
+  Reported-by: cromestant
+  Help-by: Frank Gevaerts
+
+- [Jay Satiro brought this change]
+
+  cyassl: Fix library initialization return value
+  
+  (Curl_cyassl_init)
+  - Return 1 on success, 0 in failure.
+  
+  Prior to this change the fail path returned an incorrect value and the
+  evaluation to determine whether CyaSSL_Init had succeeded was incorrect.
+  Ironically that combined with the way curl_global_init tests SSL library
+  initialization (!Curl_ssl_init()) meant that CyaSSL having been
+  successfully initialized would be seen as that even though the code path
+  and return value in Curl_cyassl_init were wrong.
+
+- [Thomas Ruecker brought this change]
+
+  CURLOPT_HTTP200ALIASES.3: Mainly SHOUTcast servers use "ICY 200"
+  
+  Icecast versions 1.3.0 through 1.3.12 would reply with "ICY 200"
+  under certain conditions:
+  
+      client_wants_icy_headers (connection_t *con)
+      {
+              const char *val;
+  
+              if (!con)
+                      return 1;
+  
+              val = get_user_agent (con);
+              if (!val || !val[0] || strcmp (val, "(null)") == 0)
+                      return 1;
+  
+              if (con->food.client->use_icy)
+                      return 1;
+              if (strncasecmp (val, "winamp", 6) == 0)
+                      return 1;
+              if (strncasecmp (val, "Shoutcast", 9) == 0)
+                      return 1;
+  
+              return 0;
+      }
+  
+  So mainly if there is no 'user agent' or it is '(null)' or contains
+  'winamp' or 'Shoutcast'.
+  
+  No mainstream distribution carries Icecast 1.3.x anymore, after all
+  it was released in 2002 and superseded by Icecast 2.x.
+
+Dan Fandrich (31 Mar 2015)
+- axtls: add timeout within Curl_axtls_connect
+  
+  This allows test 405 to pass on axTLS.
+
+Daniel Stenberg (30 Mar 2015)
+- [Jay Satiro brought this change]
+
+  checksrc: Windows-specific input fixes
+  
+  lib/config-win32ce.h
+  - Fix whitespace for checksrc compliance.
+  
+  lib/checksrc.pl
+  - Remove trailing carriage returns from input.
+  
+  projects/checksrc.bat
+  - Ignore tool_hugehelp.c.
+
+- [Dagobert Michelsen brought this change]
+
+  configure: Use KRB5CONFIG for krb5-config
+  
+  Allows the user to easier override its path.
+  
+  Bug: http://curl.haxx.se/bug/view.cgi?id=1486
+
+- multi: remove_handle: move pending connections
+  
+  If the handle removed from the multi handle happens to be the one
+  "owning" the pipeline other transfers will be waiting indefinitely. Now
+  we move such handles back to connect to have them race (again) for
+  getting the connection and thus avoid hanging.
+  
+  Bug: http://curl.haxx.se/bug/view.cgi?id=1465
+  Reported-by: Jiri Dvorak
+
+- KNOWN_BUGS: 89 is bug #1411
+  
+  Disabling pipelining on multi handle with in-progress pipelined requests
+  leads to heap corruption and crash
+
+- [Jay Satiro brought this change]
+
+  cyassl: CTX callback cosmetic changes and doc fix
+  
+  - More descriptive fail message for NO_FILESYSTEM builds.
+  - Cosmetic changes.
+  - Change more of CURLOPT_SSL_CTX_* doc to not be OpenSSL specific.
+
+- RELEASE-NOTES: synced with d2feb71752f
+
+Dan Fandrich (28 Mar 2015)
+- tool_operate: only set SSL options if SSL is enabled
+
+- runtests.pl: detect WolfSSL as yassl
+
+Daniel Stenberg (27 Mar 2015)
+- [Kyle L. Huff brought this change]
+
+  cyassl: add SSL context callback support for CyaSSL
+  
+  Adds support for CURLOPT_SSL_CTX_FUNCTION when using CyaSSL, and better
+  handles CyaSSL instances using NO_FILESYSTEM.
+
+- [Kyle L. Huff brought this change]
+
+  cyassl: remove undefined reference to CyaSSL_no_filesystem_verify
+  
+  CyaSSL_no_filesystem_verify is not (or no longer) defined by cURL or
+  CyaSSL. This reference causes build errors when compiling with
+  NO_FILESYSTEM.
+
+- [Jay Satiro brought this change]
+
+  build: Fix libcurl.sln erroneous mixed configurations
+  
+  Prior to this change some Release configurations had an active
+  configuration assignment to their Debug counterpart.
+
+- [Jay Satiro brought this change]
+
+  vtls: Don't accept unknown CURLOPT_SSLVERSION values
+
+- [Jay Satiro brought this change]
+
+  url: Don't accept CURLOPT_SSLVERSION unless USE_SSL is defined
+
+- [Paul Howarth brought this change]
+
+  build: link curl to openssl libraries when openssl support is enabled
+  
+  This fixes a build failure where openssl and libmetalink are used
+  together and the system linker does not do implicit linking (e.g.
+  Fedora 13 and later releases). The MD5 functions required for
+  metalink support must be pulled in from the openssl crypto library.
+  
+  This is similar to commit c6e7cbb94e669b85d3eb8e015ec51d0072112133,
+  which fixes the same sort of problem for NSS builds.
+
+- multi: on a request completion, check all CONNECT_PEND transfers
+  
+  ... even if they don't have an associated connection anymore. It could
+  leave the waiting transfers pending with no active one on the
+  connection.
+  
+  Bug: http://curl.haxx.se/bug/view.cgi?id=1465
+  Reported-by: Jiri Dvorak
+
+- [Emil Lerner brought this change]
+
+  globbing: fix url number calculation when using range with step
+  
+  In function glob_range, the number of urls was multiplied by (max - min
+  + 1), regardless of step. The correct formula is (max - min) / step + 1
+
+- README.http2: refreshed and added TODO items
+
+- [Emil Lerner brought this change]
+
+  globbing: fix step parsing for character globbing ranges
+  
+  The glob_range function used wrong offset (3 instead of 4) for parsing
+  integer step inside character range specification, which led to 'bad
+  range' error when using character ranges with explicitly specified step
+  (such as '[a-z:2]')
+
+- polarssl: called mbedTLS in 1.3.10 and later
+
+- polarssl: remove dead code
+  
+  and simplify code by changing if-elses to a switch()
+  
+  CID 1291706: Logically dead code. Execution cannot reach this statement
+
+- polarssl: remove superfluous for(;;) loop
+  
+  "unreachable: Since the loop increment is unreachable, the loop body
+  will never execute more than once."
+  
+  Coverity CID 1291707
+
+- Curl_ssl_md5sum: return CURLcode
+  
+  ... since the funciton can fail on OOM. Check this return code.
+  
+  Coverity CID 1291705.
+
+- [Jay Satiro brought this change]
+
+  cyassl: default to highest possible TLS version
+  
+  (cyassl_connect_step1)
+  - Use TLS 1.0-1.2 by default when available.
+  
+  CyaSSL/wolfSSL >= v3.3.0 supports setting a minimum protocol downgrade
+  version.
+  
+  cyassl/cyassl@322f79f
+
+- [Jay Satiro brought this change]
+
+  cyassl: Check for invalid length parameter in Curl_cyassl_random
+
+- [Jay Satiro brought this change]
+
+  cyassl: If wolfSSL then identify as such in version string
+
+Dan Fandrich (24 Mar 2015)
+- symbols-in-versions: added CURLOPT_PATH_AS_IS
+
+- testcurl.pl: add the --notes option to supply more info about a build
+  
+  Support for notes has been in place for a while, but it required
+  being added to the setup file manually.
+
+- curl_memory: make curl_memory.h the second-last header file loaded
+  
+  This header file must be included after all header files except
+  memdebug.h, as it does similar memory function redefinitions and can be
+  similarly affected by conflicting definitions in system or dependent
+  library headers.
+
+Daniel Stenberg (24 Mar 2015)
+- openssl: do the OCSP work-around for libressl too
+  
+  I tested with libressl git master now (v2.1.4-27-g34bf96c) and it seems to
+  still require the work-around for stapling to work.
+
+- openssl: verifystatus: only use the OCSP work-around <= 1.0.2a
+  
+  URL: http://curl.haxx.se/mail/lib-2015-03/0205.html
+  Reported-by: Alessandro Ghedini
+
+- openssl: adapt to ASN1/X509 things gone opaque in 1.1
+
+Dan Fandrich (24 Mar 2015)
+- [Jay Satiro brought this change]
+
+  curl_easy_setopt.3: Fix misspelling in CURLOPT_PATH_AS_IS description
+
+- [Viktor SzakÃ¡ts brought this change]
+
+  CURLOPT_HTTPHEADER.3: fix typo in recent commit
+
+- [Viktor SzakÃ¡ts brought this change]
+
+  CURLOPT_PATH_AS_IS.3: add type 'long' to prototype
+
+- vtls: fix compile with --disable-crypto-auth but with SSL
+  
+  This is a strange combination of options, but is allowed.
+
+Patrick Monnerat (24 Mar 2015)
+- os400: define new options in ILE/RPG binding.
+
+Daniel Stenberg (24 Mar 2015)
+- RELEASE-NOTES: synced with f6878609361
+
+- curl_easy_setopt.3: Add CURLOPT_PATH_AS_IS
+
+- CURLOPT_PATH_AS_IS: added
+  
+  --path-as-is is the command line option
+  
+  Added docs in curl.1 and CURLOPT_PATH_AS_IS.3
+  
+  Added test in test 1241
+
+- [Yamada Yasuharu brought this change]
+
+  curl_easy_recv/send: make them work with the multi interface
+  
+  By making sure Curl_getconnectinfo() uses the correct connection cache
+  to find the last connection.
+
+- http2: move the init too for when its actually needed
+  
+  ... it would otherwise lead to memory leakage if we never actually do
+  the switch.
+
+Dan Fandrich (23 Mar 2015)
+- dict: rename byte to avoid compiler shadowed declaration warning
+  
+  This conflicted with a WolfSSL typedef.
+
+- cyassl: include version.h to ensure the version macros are defined
+
+- test1513: eliminated race condition in test run
+  
+  It seems that some systems (e.g. fairly consistently in some recent
+  Solaris autobuilds) would manage to get to the connect phase before the
+  progress callback was called, resulting in a CURLE_COULDNT_CONNECT
+  error. Reworked the test to point at a test server that never returns a
+  full result so the progress callback always gets a chance to be called
+  before the transfer can complete in some other way.
+
+Nick Zitzmann (21 Mar 2015)
+- darwinsssl: add support for TLS False Start
+  
+  TLS False Start support requires iOS 7.0 or later, or OS X 10.9 or later.
+
+Daniel Stenberg (21 Mar 2015)
+- gtls: add check of return code
+  
+  Coverity CID 1291167 pointed out that 'rc' was received but never used when
+  gnutls_credentials_set() was used. Added return code check now.
+
+- gtls: dereferencing NULL pointer
+  
+  Coverity CID 1291165 pointed out 'chainp' could be dereferenced when
+  NULL if gnutls_certificate_get_peers() had previously failed.
+
+- gtls: avoid uninitialized variable.
+  
+  Coverity CID 1291166 pointed out that we could read this variable
+  uninitialized.
+
+Dan Fandrich (21 Mar 2015)
+- tests/certs: rebuild certificates with modified key usage bits
+  
+  The certificates were missing the digitalSignature and keyAgreement
+  usage types, of which at least digitalSignature was checked by CyaSSL.
+  This caused the test server in test 310 (among others) to fail the
+  startup verification and therefore run (see
+  http://curl.haxx.se/mail/lib-2014-07/0303.html).
+
+- tests/certs: added make target to rebuild certificates
+  
+  The certificate generation scripts were also updated to better match the
+  format of the certificates currently checked in.
+
+Daniel Stenberg (21 Mar 2015)
+- x509asn1: add /* fallthrough */ in switch() case
+
+- x509asn1: minor edit to unconfuse Coverity
+  
+  CID 1202732 warns on the previous use, although I cannot fine any
+  problems with it. I'm doing this change only to make the code use a more
+  familiar approach to accomplish the same thing.
+
+- [Dagobert Michelsen brought this change]
+
+  testcurl: Allow '=' in values given on command line
+
+- nss: error: unused variable 'connssl'
+
+Dan Fandrich (21 Mar 2015)
+- test938: added missing closing tags
+
+- cyassl: use new library version macro when available
+
+Kamil Dudka (20 Mar 2015)
+- [Alessandro Ghedini brought this change]
+
+  curl: add --false-start option
+
+- [Alessandro Ghedini brought this change]
+
+  nss: add support for TLS False Start
+
+- [Alessandro Ghedini brought this change]
+
+  url: add CURLOPT_SSL_FALSESTART option
+  
+  This option can be used to enable/disable TLS False Start defined in the RFC
+  draft-bmoeller-tls-falsestart.
+
+Patrick Monnerat (20 Mar 2015)
+- [Alessandro Ghedini brought this change]
+
+  gtls: implement CURLOPT_CERTINFO
+
+Daniel Stenberg (20 Mar 2015)
+- [Alessandro Ghedini brought this change]
+
+  openssl: try to avoid accessing OCSP structs when possible
+
+- CURLOPT_URL.3: spelling!
+  
+  Reported-by: Frank Gevaerts
+
+- CURLOPT_URL.3: Added "SECURITY CONCERNS"
+
+- CURLOPT_HTTPHEADER.3: add a "SECURITY CONCERNS" section
+
+Dan Fandrich (19 Mar 2015)
+- cyassl: detect the library as renamed wolfssl
+  
+  This change was made in CyaSSL/WolfSSL ver. 3.4.0
+
+Daniel Stenberg (19 Mar 2015)
+- HTTP: don't switch to HTTP/2 from 1.1 until we get the 101
+  
+  We prematurely changed protocol handler to HTTP/2 which made things very
+  slow (and wrong).
+  
+  Reported-by: Stefan Eissing
+  Bug: https://github.com/bagder/curl/issues/169
+
+Dan Fandrich (19 Mar 2015)
+- axtls: version 1.5.2 now requires that config.h be manually included
+
+Daniel Stenberg (19 Mar 2015)
+- metalink: fix resource leak in OOM
+  
+  Coverity CID 1288826
+
+Dan Fandrich (18 Mar 2015)
+- docs/libcurl: clean up libcurl-symbols.3
+
+- docs/libcurl: check that all options with man pages are referenced
+  
+  If a man page exists in the opts/ directory, it must also be referenced
+  either in curl_easy_setopt.3 or curl_multi_setopt.3
+
+- curl_easy_setopt.3: added a few missing options
+
+Kamil Dudka (18 Mar 2015)
+- nss: explicitly tell NSS to disable NPN/ALPN
+  
+  ... if disabled at libcurl level.  Otherwise, we would allow to
+  negotiate NPN despite curl was invoked with the --no-npn option.
+
+Daniel Stenberg (18 Mar 2015)
+- [Jay Satiro brought this change]
+
+  mkhelp: Remove trailing carriage return from every line of input
+  
+  - Get rid of this flood of warnings in Windows mingw build:
+  warning: missing terminating " character
+  
+  The warning is due to the carriage return. When msysgit checks out files
+  from the repo by default it converts the line endings to CRLF. Prior to
+  this change when mkhelp.pl processed the MANUAL and curl.1 in CRLF
+  format the trailing carriage returns caused unnecessary CR in the
+  output.
+
+- RELEASE-NOTES: synced with e539f01567
+
+- [Christian Weisgerber brought this change]
+
+  docs/libcurl: make portability fix
+  
+  Using $< in a non-suffix rule context is a GNU make idiom.  This bug was
+  introduced in 7.41.0.
+
+Dan Fandrich (17 Mar 2015)
+- checksrc: Fix whitelist on out-of-tree builds
+
+Daniel Stenberg (17 Mar 2015)
+- [Stefan BÃ¼hler brought this change]
+
+  Curl_sh_entry: remove unused 'timestamp'
+
+- HTTP: don't use Expect: headers when on HTTP/2
+  
+  Reported-by: Stefan Eissing
+  Bug: https://github.com/bagder/curl/issues/169
+
+- checksrc: detect and remove space before trailing semicolons
+
+- checksrc: introduce a whitelisting concept
+
+- checksrc: use space after comma
Index: UsbWattMeter/trunk/curl-7.47.1/COPYING
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/COPYING	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/COPYING	(revision 164)
@@ -0,0 +1,22 @@
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright (c) 1996 - 2016, Daniel Stenberg, <daniel@haxx.se>, and many
+contributors, see the THANKS file.
+
+All rights reserved.
+
+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", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 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.
+
+Except as contained in this notice, the name of a copyright holder shall not
+be used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization of the copyright holder.
Index: UsbWattMeter/trunk/curl-7.47.1/README
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/README	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/README	(revision 164)
@@ -0,0 +1,49 @@
+                                  _   _ ____  _
+                              ___| | | |  _ \| |
+                             / __| | | | |_) | |
+                            | (__| |_| |  _ <| |___
+                             \___|\___/|_| \_\_____|
+
+README
+
+  Curl is a command line tool for transferring data specified with URL
+  syntax. Find out how to use curl by reading the curl.1 man page or the
+  MANUAL document. Find out how to install Curl by reading the INSTALL
+  document.
+
+  libcurl is the library curl is using to do its job. It is readily
+  available to be used by your software. Read the libcurl.3 man page to
+  learn how!
+
+  You find answers to the most frequent questions we get in the FAQ document.
+
+  Study the COPYING file for distribution terms and similar. If you distribute
+  curl binaries or other binaries that involve libcurl, you might enjoy the
+  LICENSE-MIXING document.
+
+CONTACT
+
+  If you have problems, questions, ideas or suggestions, please contact us
+  by posting to a suitable mailing list. See https://curl.haxx.se/mail/
+
+  All contributors to the project are listed in the THANKS document.
+
+WEB SITE
+
+  Visit the curl web site for the latest news and downloads:
+
+        https://curl.haxx.se/
+
+GIT
+
+  To download the very latest source off the GIT server do this:
+
+    git clone https://github.com/curl/curl.git
+
+  (you'll get a directory named curl created, filled with the source code)
+
+NOTICE
+
+  Curl contains pieces of source code that is Copyright (c) 1998, 1999
+  Kungliga Tekniska H旦gskolan. This notice is included here to comply with the
+  distribution terms.
Index: UsbWattMeter/trunk/curl-7.47.1/RELEASE-NOTES
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/RELEASE-NOTES	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/RELEASE-NOTES	(revision 164)
@@ -0,0 +1,48 @@
+Curl and libcurl 7.47.1
+
+ Public curl releases:         152
+ Command line options:         179
+ curl_easy_setopt() options:   221
+ Public functions in libcurl:  61
+ Contributors:                 1346
+
+This release includes the following bugfixes:
+
+ o getredirect.c: fix variable name
+ o tool_doswin: silence unused function warning [1]
+ o cmake: fixed when OpenSSL enabled on Windows and schannel detected [2]
+ o curl.1: Explain remote-name behavior if file already exists
+ o tool_operate: Don't sanitize --output path (Windows) [3]
+ o URLs: change all http:// URLs to https:// in documentation & comments
+ o sasl_sspi: Fix memory leak in domain populate [4]
+ o COPYING: clarify that Daniel is not the sole author
+ o examples/htmltitle: Use _stricmp on Windows [5]
+ o examples/asiohiper: Avoid function name collision on Windows [6]
+ o idn_win32: Better error checking [7]
+ o openssl: Fix signed/unsigned mismatch warning in X509V3_ext [8]
+ o curl save files: check for backslashes on cygwin [9]
+
+This release includes the following known bugs:
+
+ o see docs/KNOWN_BUGS (https://curl.haxx.se/docs/knownbugs.html)
+
+This release would not have looked like this without help, code, reports and
+advice from friends like these:
+
+  Bernard Spil, Dan Fandrich, Daniel Stenberg, Gisle Vanem, Michael Kaufmann,
+  Octavio Schroeder, Ray Satiro, Sergei Nikulov, Viktor Szak叩ts,
+  (9 contributors)
+
+        Thanks! (and sorry if I forgot to mention someone)
+
+References to bug reports and discussions on issues:
+
+ [1] = https://github.com/curl/curl/pull/616
+ [2] = https://curl.haxx.se/bug/?i=617
+ [3] = https://curl.haxx.se/bug/?i=624
+ [4] = https://github.com/curl/curl/issues/635
+ [5] = https://curl.haxx.se/mail/lib-2016-02/0017.html
+ [6] = https://curl.haxx.se/mail/lib-2016-02/0016.html
+ [7] = https://github.com/curl/curl/pull/637
+ [8] = https://github.com/curl/curl/commit/dd1b44c#commitcomment-15913896
+ [9] = https://curl.haxx.se/docs/adv_20160127B.html
Index: UsbWattMeter/trunk/curl-7.47.1/include/README
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/include/README	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/include/README	(revision 164)
@@ -0,0 +1,55 @@
+                                  _   _ ____  _
+                              ___| | | |  _ \| |
+                             / __| | | | |_) | |
+                            | (__| |_| |  _ <| |___
+                             \___|\___/|_| \_\_____|
+
+Include files for libcurl, external users.
+
+They're all placed in the curl subdirectory here for better fit in any kind
+of environment. You must include files from here using...
+
+        #include <curl/curl.h>
+
+... style and point the compiler's include path to the directory holding the
+curl subdirectory. It makes it more likely to survive future modifications.
+
+NOTE FOR LIBCURL HACKERS
+
+The following notes apply to libcurl version 7.19.0 and later.
+
+* The distributed curl/curlbuild.h file is only intended to be used on systems
+  which can not run the also distributed configure script.
+
+* The distributed curlbuild.h file is generated as a copy of curlbuild.h.dist
+  when the libcurl source code distribution archive file is originally created.
+
+* If you check out from git on a non-configure platform, you must run the
+  appropriate buildconf* script to set up curlbuild.h and other local files
+  before being able of compiling the library.
+
+* On systems capable of running the configure script, the configure process
+  will overwrite the distributed include/curl/curlbuild.h file with one that
+  is suitable and specific to the library being configured and built, which
+  is generated from the include/curl/curlbuild.h.in template file.
+
+* If you intend to distribute an already compiled libcurl library you _MUST_
+  also distribute along with it the generated curl/curlbuild.h which has been
+  used to compile it. Otherwise the library will be of no use for the users of
+  the library that you have built. It is _your_ responsibility to provide this
+  file. No one at the cURL project can know how you have built the library.
+
+* File curl/curlbuild.h includes platform and configuration dependent info,
+  and must not be modified by anyone. Configure script generates it for you.
+
+* We cannot assume anything else but very basic compiler features being
+  present. While libcurl requires an ANSI C compiler to build, some of the
+  earlier ANSI compilers clearly can't deal with some preprocessor operators.
+
+* Newlines must remain unix-style for older compilers' sake.
+
+* Comments must be written in the old-style /* unnested C-fashion */
+
+To figure out how to do good and portable checks for features, operating
+systems or specific hardwarare, a very good resource is Bjorn Reese's
+collection at http://predef.sf.net/
Index: UsbWattMeter/trunk/curl-7.47.1/include/curl/curl.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/include/curl/curl.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/include/curl/curl.h	(revision 164)
@@ -0,0 +1,2415 @@
+#ifndef __CURL_CURL_H
+#define __CURL_CURL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * If you have libcurl problems, all docs and details are found here:
+ *   https://curl.haxx.se/libcurl/
+ *
+ * curl-library mailing list subscription and unsubscription web interface:
+ *   https://cool.haxx.se/mailman/listinfo/curl-library/
+ */
+
+#include "curlver.h"         /* libcurl version defines   */
+#include "curlbuild.h"       /* libcurl build definitions */
+#include "curlrules.h"       /* libcurl rules enforcement */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && \
+     !defined(WIN32) && !defined(__SYMBIAN32__)
+#define WIN32
+#endif
+
+#include <stdio.h>
+#include <limits.h>
+
+#if defined(__FreeBSD__) && (__FreeBSD__ >= 2)
+/* Needed for __FreeBSD_version symbol definition */
+#include <osreldate.h>
+#endif
+
+/* The include stuff here below is mainly for time_t! */
+#include <sys/types.h>
+#include <time.h>
+
+#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__)
+#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \
+      defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H))
+/* The check above prevents the winsock2 inclusion if winsock.h already was
+   included, since they can't co-exist without problems */
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#endif
+#endif
+
+/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
+   libc5-based Linux systems. Only include it on systems that are known to
+   require it! */
+#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
+    defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
+    defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
+   (defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
+#include <sys/select.h>
+#endif
+
+#if !defined(WIN32) && !defined(_WIN32_WCE) && !defined(USE_LWIPSOCK)
+#include <sys/socket.h>
+#endif
+
+#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__)
+#include <sys/time.h>
+#endif
+
+#ifdef __BEOS__
+#include <support/SupportDefs.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef void CURL;
+
+/*
+ * libcurl external API function linkage decorations.
+ */
+
+#ifdef CURL_STATICLIB
+#  define CURL_EXTERN
+#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)
+#  if defined(BUILDING_LIBCURL)
+#    define CURL_EXTERN  __declspec(dllexport)
+#  else
+#    define CURL_EXTERN  __declspec(dllimport)
+#  endif
+#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS)
+#  define CURL_EXTERN CURL_EXTERN_SYMBOL
+#else
+#  define CURL_EXTERN
+#endif
+
+#ifndef curl_socket_typedef
+/* socket typedef */
+#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H)
+typedef SOCKET curl_socket_t;
+#define CURL_SOCKET_BAD INVALID_SOCKET
+#else
+typedef int curl_socket_t;
+#define CURL_SOCKET_BAD -1
+#endif
+#define curl_socket_typedef
+#endif /* curl_socket_typedef */
+
+struct curl_httppost {
+  struct curl_httppost *next;       /* next entry in the list */
+  char *name;                       /* pointer to allocated name */
+  long namelength;                  /* length of name length */
+  char *contents;                   /* pointer to allocated data contents */
+  long contentslength;              /* length of contents field, see also
+                                       CURL_HTTPPOST_LARGE */
+  char *buffer;                     /* pointer to allocated buffer contents */
+  long bufferlength;                /* length of buffer field */
+  char *contenttype;                /* Content-Type */
+  struct curl_slist* contentheader; /* list of extra headers for this form */
+  struct curl_httppost *more;       /* if one field name has more than one
+                                       file, this link should link to following
+                                       files */
+  long flags;                       /* as defined below */
+
+/* specified content is a file name */
+#define CURL_HTTPPOST_FILENAME (1<<0)
+/* specified content is a file name */
+#define CURL_HTTPPOST_READFILE (1<<1)
+/* name is only stored pointer do not free in formfree */
+#define CURL_HTTPPOST_PTRNAME (1<<2)
+/* contents is only stored pointer do not free in formfree */
+#define CURL_HTTPPOST_PTRCONTENTS (1<<3)
+/* upload file from buffer */
+#define CURL_HTTPPOST_BUFFER (1<<4)
+/* upload file from pointer contents */
+#define CURL_HTTPPOST_PTRBUFFER (1<<5)
+/* upload file contents by using the regular read callback to get the data and
+   pass the given pointer as custom pointer */
+#define CURL_HTTPPOST_CALLBACK (1<<6)
+/* use size in 'contentlen', added in 7.46.0 */
+#define CURL_HTTPPOST_LARGE (1<<7)
+
+  char *showfilename;               /* The file name to show. If not set, the
+                                       actual file name will be used (if this
+                                       is a file part) */
+  void *userp;                      /* custom pointer used for
+                                       HTTPPOST_CALLBACK posts */
+  curl_off_t contentlen;            /* alternative length of contents
+                                       field. Used if CURL_HTTPPOST_LARGE is
+                                       set. Added in 7.46.0 */
+};
+
+/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered
+   deprecated but was the only choice up until 7.31.0 */
+typedef int (*curl_progress_callback)(void *clientp,
+                                      double dltotal,
+                                      double dlnow,
+                                      double ultotal,
+                                      double ulnow);
+
+/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in
+   7.32.0, it avoids floating point and provides more detailed information. */
+typedef int (*curl_xferinfo_callback)(void *clientp,
+                                      curl_off_t dltotal,
+                                      curl_off_t dlnow,
+                                      curl_off_t ultotal,
+                                      curl_off_t ulnow);
+
+#ifndef CURL_MAX_WRITE_SIZE
+  /* Tests have proven that 20K is a very bad buffer size for uploads on
+     Windows, while 16K for some odd reason performed a lot better.
+     We do the ifndef check to allow this value to easier be changed at build
+     time for those who feel adventurous. The practical minimum is about
+     400 bytes since libcurl uses a buffer of this size as a scratch area
+     (unrelated to network send operations). */
+#define CURL_MAX_WRITE_SIZE 16384
+#endif
+
+#ifndef CURL_MAX_HTTP_HEADER
+/* The only reason to have a max limit for this is to avoid the risk of a bad
+   server feeding libcurl with a never-ending header that will cause reallocs
+   infinitely */
+#define CURL_MAX_HTTP_HEADER (100*1024)
+#endif
+
+/* This is a magic return code for the write callback that, when returned,
+   will signal libcurl to pause receiving on the current transfer. */
+#define CURL_WRITEFUNC_PAUSE 0x10000001
+
+typedef size_t (*curl_write_callback)(char *buffer,
+                                      size_t size,
+                                      size_t nitems,
+                                      void *outstream);
+
+
+
+/* enumeration of file types */
+typedef enum {
+  CURLFILETYPE_FILE = 0,
+  CURLFILETYPE_DIRECTORY,
+  CURLFILETYPE_SYMLINK,
+  CURLFILETYPE_DEVICE_BLOCK,
+  CURLFILETYPE_DEVICE_CHAR,
+  CURLFILETYPE_NAMEDPIPE,
+  CURLFILETYPE_SOCKET,
+  CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */
+
+  CURLFILETYPE_UNKNOWN /* should never occur */
+} curlfiletype;
+
+#define CURLFINFOFLAG_KNOWN_FILENAME    (1<<0)
+#define CURLFINFOFLAG_KNOWN_FILETYPE    (1<<1)
+#define CURLFINFOFLAG_KNOWN_TIME        (1<<2)
+#define CURLFINFOFLAG_KNOWN_PERM        (1<<3)
+#define CURLFINFOFLAG_KNOWN_UID         (1<<4)
+#define CURLFINFOFLAG_KNOWN_GID         (1<<5)
+#define CURLFINFOFLAG_KNOWN_SIZE        (1<<6)
+#define CURLFINFOFLAG_KNOWN_HLINKCOUNT  (1<<7)
+
+/* Content of this structure depends on information which is known and is
+   achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man
+   page for callbacks returning this structure -- some fields are mandatory,
+   some others are optional. The FLAG field has special meaning. */
+struct curl_fileinfo {
+  char *filename;
+  curlfiletype filetype;
+  time_t time;
+  unsigned int perm;
+  int uid;
+  int gid;
+  curl_off_t size;
+  long int hardlinks;
+
+  struct {
+    /* If some of these fields is not NULL, it is a pointer to b_data. */
+    char *time;
+    char *perm;
+    char *user;
+    char *group;
+    char *target; /* pointer to the target filename of a symlink */
+  } strings;
+
+  unsigned int flags;
+
+  /* used internally */
+  char * b_data;
+  size_t b_size;
+  size_t b_used;
+};
+
+/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */
+#define CURL_CHUNK_BGN_FUNC_OK      0
+#define CURL_CHUNK_BGN_FUNC_FAIL    1 /* tell the lib to end the task */
+#define CURL_CHUNK_BGN_FUNC_SKIP    2 /* skip this chunk over */
+
+/* if splitting of data transfer is enabled, this callback is called before
+   download of an individual chunk started. Note that parameter "remains" works
+   only for FTP wildcard downloading (for now), otherwise is not used */
+typedef long (*curl_chunk_bgn_callback)(const void *transfer_info,
+                                        void *ptr,
+                                        int remains);
+
+/* return codes for CURLOPT_CHUNK_END_FUNCTION */
+#define CURL_CHUNK_END_FUNC_OK      0
+#define CURL_CHUNK_END_FUNC_FAIL    1 /* tell the lib to end the task */
+
+/* If splitting of data transfer is enabled this callback is called after
+   download of an individual chunk finished.
+   Note! After this callback was set then it have to be called FOR ALL chunks.
+   Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC.
+   This is the reason why we don't need "transfer_info" parameter in this
+   callback and we are not interested in "remains" parameter too. */
+typedef long (*curl_chunk_end_callback)(void *ptr);
+
+/* return codes for FNMATCHFUNCTION */
+#define CURL_FNMATCHFUNC_MATCH    0 /* string corresponds to the pattern */
+#define CURL_FNMATCHFUNC_NOMATCH  1 /* pattern doesn't match the string */
+#define CURL_FNMATCHFUNC_FAIL     2 /* an error occurred */
+
+/* callback type for wildcard downloading pattern matching. If the
+   string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */
+typedef int (*curl_fnmatch_callback)(void *ptr,
+                                     const char *pattern,
+                                     const char *string);
+
+/* These are the return codes for the seek callbacks */
+#define CURL_SEEKFUNC_OK       0
+#define CURL_SEEKFUNC_FAIL     1 /* fail the entire transfer */
+#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so
+                                    libcurl might try other means instead */
+typedef int (*curl_seek_callback)(void *instream,
+                                  curl_off_t offset,
+                                  int origin); /* 'whence' */
+
+/* This is a return code for the read callback that, when returned, will
+   signal libcurl to immediately abort the current transfer. */
+#define CURL_READFUNC_ABORT 0x10000000
+/* This is a return code for the read callback that, when returned, will
+   signal libcurl to pause sending data on the current transfer. */
+#define CURL_READFUNC_PAUSE 0x10000001
+
+typedef size_t (*curl_read_callback)(char *buffer,
+                                      size_t size,
+                                      size_t nitems,
+                                      void *instream);
+
+typedef enum  {
+  CURLSOCKTYPE_IPCXN,  /* socket created for a specific IP connection */
+  CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */
+  CURLSOCKTYPE_LAST    /* never use */
+} curlsocktype;
+
+/* The return code from the sockopt_callback can signal information back
+   to libcurl: */
+#define CURL_SOCKOPT_OK 0
+#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return
+                                CURLE_ABORTED_BY_CALLBACK */
+#define CURL_SOCKOPT_ALREADY_CONNECTED 2
+
+typedef int (*curl_sockopt_callback)(void *clientp,
+                                     curl_socket_t curlfd,
+                                     curlsocktype purpose);
+
+struct curl_sockaddr {
+  int family;
+  int socktype;
+  int protocol;
+  unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it
+                           turned really ugly and painful on the systems that
+                           lack this type */
+  struct sockaddr addr;
+};
+
+typedef curl_socket_t
+(*curl_opensocket_callback)(void *clientp,
+                            curlsocktype purpose,
+                            struct curl_sockaddr *address);
+
+typedef int
+(*curl_closesocket_callback)(void *clientp, curl_socket_t item);
+
+typedef enum {
+  CURLIOE_OK,            /* I/O operation successful */
+  CURLIOE_UNKNOWNCMD,    /* command was unknown to callback */
+  CURLIOE_FAILRESTART,   /* failed to restart the read */
+  CURLIOE_LAST           /* never use */
+} curlioerr;
+
+typedef enum  {
+  CURLIOCMD_NOP,         /* no operation */
+  CURLIOCMD_RESTARTREAD, /* restart the read stream from start */
+  CURLIOCMD_LAST         /* never use */
+} curliocmd;
+
+typedef curlioerr (*curl_ioctl_callback)(CURL *handle,
+                                         int cmd,
+                                         void *clientp);
+
+/*
+ * The following typedef's are signatures of malloc, free, realloc, strdup and
+ * calloc respectively.  Function pointers of these types can be passed to the
+ * curl_global_init_mem() function to set user defined memory management
+ * callback routines.
+ */
+typedef void *(*curl_malloc_callback)(size_t size);
+typedef void (*curl_free_callback)(void *ptr);
+typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
+typedef char *(*curl_strdup_callback)(const char *str);
+typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
+
+/* the kind of data that is passed to information_callback*/
+typedef enum {
+  CURLINFO_TEXT = 0,
+  CURLINFO_HEADER_IN,    /* 1 */
+  CURLINFO_HEADER_OUT,   /* 2 */
+  CURLINFO_DATA_IN,      /* 3 */
+  CURLINFO_DATA_OUT,     /* 4 */
+  CURLINFO_SSL_DATA_IN,  /* 5 */
+  CURLINFO_SSL_DATA_OUT, /* 6 */
+  CURLINFO_END
+} curl_infotype;
+
+typedef int (*curl_debug_callback)
+       (CURL *handle,      /* the handle/transfer this concerns */
+        curl_infotype type, /* what kind of data */
+        char *data,        /* points to the data */
+        size_t size,       /* size of the data pointed to */
+        void *userptr);    /* whatever the user please */
+
+/* All possible error codes from all sorts of curl functions. Future versions
+   may return other values, stay prepared.
+
+   Always add new return codes last. Never *EVER* remove any. The return
+   codes must remain the same!
+ */
+
+typedef enum {
+  CURLE_OK = 0,
+  CURLE_UNSUPPORTED_PROTOCOL,    /* 1 */
+  CURLE_FAILED_INIT,             /* 2 */
+  CURLE_URL_MALFORMAT,           /* 3 */
+  CURLE_NOT_BUILT_IN,            /* 4 - [was obsoleted in August 2007 for
+                                    7.17.0, reused in April 2011 for 7.21.5] */
+  CURLE_COULDNT_RESOLVE_PROXY,   /* 5 */
+  CURLE_COULDNT_RESOLVE_HOST,    /* 6 */
+  CURLE_COULDNT_CONNECT,         /* 7 */
+  CURLE_FTP_WEIRD_SERVER_REPLY,  /* 8 */
+  CURLE_REMOTE_ACCESS_DENIED,    /* 9 a service was denied by the server
+                                    due to lack of access - when login fails
+                                    this is not returned. */
+  CURLE_FTP_ACCEPT_FAILED,       /* 10 - [was obsoleted in April 2006 for
+                                    7.15.4, reused in Dec 2011 for 7.24.0]*/
+  CURLE_FTP_WEIRD_PASS_REPLY,    /* 11 */
+  CURLE_FTP_ACCEPT_TIMEOUT,      /* 12 - timeout occurred accepting server
+                                    [was obsoleted in August 2007 for 7.17.0,
+                                    reused in Dec 2011 for 7.24.0]*/
+  CURLE_FTP_WEIRD_PASV_REPLY,    /* 13 */
+  CURLE_FTP_WEIRD_227_FORMAT,    /* 14 */
+  CURLE_FTP_CANT_GET_HOST,       /* 15 */
+  CURLE_HTTP2,                   /* 16 - A problem in the http2 framing layer.
+                                    [was obsoleted in August 2007 for 7.17.0,
+                                    reused in July 2014 for 7.38.0] */
+  CURLE_FTP_COULDNT_SET_TYPE,    /* 17 */
+  CURLE_PARTIAL_FILE,            /* 18 */
+  CURLE_FTP_COULDNT_RETR_FILE,   /* 19 */
+  CURLE_OBSOLETE20,              /* 20 - NOT USED */
+  CURLE_QUOTE_ERROR,             /* 21 - quote command failure */
+  CURLE_HTTP_RETURNED_ERROR,     /* 22 */
+  CURLE_WRITE_ERROR,             /* 23 */
+  CURLE_OBSOLETE24,              /* 24 - NOT USED */
+  CURLE_UPLOAD_FAILED,           /* 25 - failed upload "command" */
+  CURLE_READ_ERROR,              /* 26 - couldn't open/read from file */
+  CURLE_OUT_OF_MEMORY,           /* 27 */
+  /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
+           instead of a memory allocation error if CURL_DOES_CONVERSIONS
+           is defined
+  */
+  CURLE_OPERATION_TIMEDOUT,      /* 28 - the timeout time was reached */
+  CURLE_OBSOLETE29,              /* 29 - NOT USED */
+  CURLE_FTP_PORT_FAILED,         /* 30 - FTP PORT operation failed */
+  CURLE_FTP_COULDNT_USE_REST,    /* 31 - the REST command failed */
+  CURLE_OBSOLETE32,              /* 32 - NOT USED */
+  CURLE_RANGE_ERROR,             /* 33 - RANGE "command" didn't work */
+  CURLE_HTTP_POST_ERROR,         /* 34 */
+  CURLE_SSL_CONNECT_ERROR,       /* 35 - wrong when connecting with SSL */
+  CURLE_BAD_DOWNLOAD_RESUME,     /* 36 - couldn't resume download */
+  CURLE_FILE_COULDNT_READ_FILE,  /* 37 */
+  CURLE_LDAP_CANNOT_BIND,        /* 38 */
+  CURLE_LDAP_SEARCH_FAILED,      /* 39 */
+  CURLE_OBSOLETE40,              /* 40 - NOT USED */
+  CURLE_FUNCTION_NOT_FOUND,      /* 41 */
+  CURLE_ABORTED_BY_CALLBACK,     /* 42 */
+  CURLE_BAD_FUNCTION_ARGUMENT,   /* 43 */
+  CURLE_OBSOLETE44,              /* 44 - NOT USED */
+  CURLE_INTERFACE_FAILED,        /* 45 - CURLOPT_INTERFACE failed */
+  CURLE_OBSOLETE46,              /* 46 - NOT USED */
+  CURLE_TOO_MANY_REDIRECTS ,     /* 47 - catch endless re-direct loops */
+  CURLE_UNKNOWN_OPTION,          /* 48 - User specified an unknown option */
+  CURLE_TELNET_OPTION_SYNTAX ,   /* 49 - Malformed telnet option */
+  CURLE_OBSOLETE50,              /* 50 - NOT USED */
+  CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint
+                                     wasn't verified fine */
+  CURLE_GOT_NOTHING,             /* 52 - when this is a specific error */
+  CURLE_SSL_ENGINE_NOTFOUND,     /* 53 - SSL crypto engine not found */
+  CURLE_SSL_ENGINE_SETFAILED,    /* 54 - can not set SSL crypto engine as
+                                    default */
+  CURLE_SEND_ERROR,              /* 55 - failed sending network data */
+  CURLE_RECV_ERROR,              /* 56 - failure in receiving network data */
+  CURLE_OBSOLETE57,              /* 57 - NOT IN USE */
+  CURLE_SSL_CERTPROBLEM,         /* 58 - problem with the local certificate */
+  CURLE_SSL_CIPHER,              /* 59 - couldn't use specified cipher */
+  CURLE_SSL_CACERT,              /* 60 - problem with the CA cert (path?) */
+  CURLE_BAD_CONTENT_ENCODING,    /* 61 - Unrecognized/bad encoding */
+  CURLE_LDAP_INVALID_URL,        /* 62 - Invalid LDAP URL */
+  CURLE_FILESIZE_EXCEEDED,       /* 63 - Maximum file size exceeded */
+  CURLE_USE_SSL_FAILED,          /* 64 - Requested FTP SSL level failed */
+  CURLE_SEND_FAIL_REWIND,        /* 65 - Sending the data requires a rewind
+                                    that failed */
+  CURLE_SSL_ENGINE_INITFAILED,   /* 66 - failed to initialise ENGINE */
+  CURLE_LOGIN_DENIED,            /* 67 - user, password or similar was not
+                                    accepted and we failed to login */
+  CURLE_TFTP_NOTFOUND,           /* 68 - file not found on server */
+  CURLE_TFTP_PERM,               /* 69 - permission problem on server */
+  CURLE_REMOTE_DISK_FULL,        /* 70 - out of disk space on server */
+  CURLE_TFTP_ILLEGAL,            /* 71 - Illegal TFTP operation */
+  CURLE_TFTP_UNKNOWNID,          /* 72 - Unknown transfer ID */
+  CURLE_REMOTE_FILE_EXISTS,      /* 73 - File already exists */
+  CURLE_TFTP_NOSUCHUSER,         /* 74 - No such user */
+  CURLE_CONV_FAILED,             /* 75 - conversion failed */
+  CURLE_CONV_REQD,               /* 76 - caller must register conversion
+                                    callbacks using curl_easy_setopt options
+                                    CURLOPT_CONV_FROM_NETWORK_FUNCTION,
+                                    CURLOPT_CONV_TO_NETWORK_FUNCTION, and
+                                    CURLOPT_CONV_FROM_UTF8_FUNCTION */
+  CURLE_SSL_CACERT_BADFILE,      /* 77 - could not load CACERT file, missing
+                                    or wrong format */
+  CURLE_REMOTE_FILE_NOT_FOUND,   /* 78 - remote file not found */
+  CURLE_SSH,                     /* 79 - error from the SSH layer, somewhat
+                                    generic so the error message will be of
+                                    interest when this has happened */
+
+  CURLE_SSL_SHUTDOWN_FAILED,     /* 80 - Failed to shut down the SSL
+                                    connection */
+  CURLE_AGAIN,                   /* 81 - socket is not ready for send/recv,
+                                    wait till it's ready and try again (Added
+                                    in 7.18.2) */
+  CURLE_SSL_CRL_BADFILE,         /* 82 - could not load CRL file, missing or
+                                    wrong format (Added in 7.19.0) */
+  CURLE_SSL_ISSUER_ERROR,        /* 83 - Issuer check failed.  (Added in
+                                    7.19.0) */
+  CURLE_FTP_PRET_FAILED,         /* 84 - a PRET command failed */
+  CURLE_RTSP_CSEQ_ERROR,         /* 85 - mismatch of RTSP CSeq numbers */
+  CURLE_RTSP_SESSION_ERROR,      /* 86 - mismatch of RTSP Session Ids */
+  CURLE_FTP_BAD_FILE_LIST,       /* 87 - unable to parse FTP file list */
+  CURLE_CHUNK_FAILED,            /* 88 - chunk callback reported error */
+  CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
+                                    session will be queued */
+  CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not
+                                     match */
+  CURLE_SSL_INVALIDCERTSTATUS,   /* 91 - invalid certificate status */
+  CURL_LAST /* never use! */
+} CURLcode;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+                          the obsolete stuff removed! */
+
+/* Previously obsolete error code re-used in 7.38.0 */
+#define CURLE_OBSOLETE16 CURLE_HTTP2
+
+/* Previously obsolete error codes re-used in 7.24.0 */
+#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED
+#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT
+
+/*  compatibility with older names */
+#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING
+
+/* The following were added in 7.21.5, April 2011 */
+#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION
+
+/* The following were added in 7.17.1 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION
+
+/* The following were added in 7.17.0 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */
+#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46
+#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44
+#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10
+#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16
+#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32
+#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29
+#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12
+#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20
+#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40
+#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24
+#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57
+#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN
+
+#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED
+#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE
+#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR
+#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL
+#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS
+#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR
+#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED
+
+/* The following were added earlier */
+
+#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT
+
+#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
+#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
+#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED
+
+#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
+#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
+
+/* This was the error code 50 in 7.7.3 and a few earlier versions, this
+   is no longer used by libcurl but is instead #defined here only to not
+   make programs break */
+#define CURLE_ALREADY_COMPLETE 99999
+
+/* Provide defines for really old option names */
+#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */
+#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */
+#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA
+
+/* Since long deprecated options with no code in the lib that does anything
+   with them. */
+#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40
+#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72
+
+#endif /*!CURL_NO_OLDIES*/
+
+/* This prototype applies to all conversion callbacks */
+typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
+
+typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl,    /* easy handle */
+                                          void *ssl_ctx, /* actually an
+                                                            OpenSSL SSL_CTX */
+                                          void *userptr);
+
+typedef enum {
+  CURLPROXY_HTTP = 0,   /* added in 7.10, new in 7.19.4 default is to use
+                           CONNECT HTTP/1.1 */
+  CURLPROXY_HTTP_1_0 = 1,   /* added in 7.19.4, force to use CONNECT
+                               HTTP/1.0  */
+  CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
+                           in 7.10 */
+  CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
+  CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */
+  CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the
+                                   host name rather than the IP address. added
+                                   in 7.18.0 */
+} curl_proxytype;  /* this enum was added in 7.10 */
+
+/*
+ * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options:
+ *
+ * CURLAUTH_NONE         - No HTTP authentication
+ * CURLAUTH_BASIC        - HTTP Basic authentication (default)
+ * CURLAUTH_DIGEST       - HTTP Digest authentication
+ * CURLAUTH_NEGOTIATE    - HTTP Negotiate (SPNEGO) authentication
+ * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated)
+ * CURLAUTH_NTLM         - HTTP NTLM authentication
+ * CURLAUTH_DIGEST_IE    - HTTP Digest authentication with IE flavour
+ * CURLAUTH_NTLM_WB      - HTTP NTLM authentication delegated to winbind helper
+ * CURLAUTH_ONLY         - Use together with a single other type to force no
+ *                         authentication or just that single type
+ * CURLAUTH_ANY          - All fine types set
+ * CURLAUTH_ANYSAFE      - All fine types except Basic
+ */
+
+#define CURLAUTH_NONE         ((unsigned long)0)
+#define CURLAUTH_BASIC        (((unsigned long)1)<<0)
+#define CURLAUTH_DIGEST       (((unsigned long)1)<<1)
+#define CURLAUTH_NEGOTIATE    (((unsigned long)1)<<2)
+/* Deprecated since the advent of CURLAUTH_NEGOTIATE */
+#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE
+#define CURLAUTH_NTLM         (((unsigned long)1)<<3)
+#define CURLAUTH_DIGEST_IE    (((unsigned long)1)<<4)
+#define CURLAUTH_NTLM_WB      (((unsigned long)1)<<5)
+#define CURLAUTH_ONLY         (((unsigned long)1)<<31)
+#define CURLAUTH_ANY          (~CURLAUTH_DIGEST_IE)
+#define CURLAUTH_ANYSAFE      (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
+
+#define CURLSSH_AUTH_ANY       ~0     /* all types supported by the server */
+#define CURLSSH_AUTH_NONE      0      /* none allowed, silly but complete */
+#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
+#define CURLSSH_AUTH_PASSWORD  (1<<1) /* password */
+#define CURLSSH_AUTH_HOST      (1<<2) /* host key files */
+#define CURLSSH_AUTH_KEYBOARD  (1<<3) /* keyboard interactive */
+#define CURLSSH_AUTH_AGENT     (1<<4) /* agent (ssh-agent, pageant...) */
+#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
+
+#define CURLGSSAPI_DELEGATION_NONE        0      /* no delegation (default) */
+#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */
+#define CURLGSSAPI_DELEGATION_FLAG        (1<<1) /* delegate always */
+
+#define CURL_ERROR_SIZE 256
+
+enum curl_khtype {
+  CURLKHTYPE_UNKNOWN,
+  CURLKHTYPE_RSA1,
+  CURLKHTYPE_RSA,
+  CURLKHTYPE_DSS
+};
+
+struct curl_khkey {
+  const char *key; /* points to a zero-terminated string encoded with base64
+                      if len is zero, otherwise to the "raw" data */
+  size_t len;
+  enum curl_khtype keytype;
+};
+
+/* this is the set of return values expected from the curl_sshkeycallback
+   callback */
+enum curl_khstat {
+  CURLKHSTAT_FINE_ADD_TO_FILE,
+  CURLKHSTAT_FINE,
+  CURLKHSTAT_REJECT, /* reject the connection, return an error */
+  CURLKHSTAT_DEFER,  /* do not accept it, but we can't answer right now so
+                        this causes a CURLE_DEFER error but otherwise the
+                        connection will be left intact etc */
+  CURLKHSTAT_LAST    /* not for use, only a marker for last-in-list */
+};
+
+/* this is the set of status codes pass in to the callback */
+enum curl_khmatch {
+  CURLKHMATCH_OK,       /* match */
+  CURLKHMATCH_MISMATCH, /* host found, key mismatch! */
+  CURLKHMATCH_MISSING,  /* no matching host/key found */
+  CURLKHMATCH_LAST      /* not for use, only a marker for last-in-list */
+};
+
+typedef int
+  (*curl_sshkeycallback) (CURL *easy,     /* easy handle */
+                          const struct curl_khkey *knownkey, /* known */
+                          const struct curl_khkey *foundkey, /* found */
+                          enum curl_khmatch, /* libcurl's view on the keys */
+                          void *clientp); /* custom pointer passed from app */
+
+/* parameter for the CURLOPT_USE_SSL option */
+typedef enum {
+  CURLUSESSL_NONE,    /* do not attempt to use SSL */
+  CURLUSESSL_TRY,     /* try using SSL, proceed anyway otherwise */
+  CURLUSESSL_CONTROL, /* SSL for the control connection or fail */
+  CURLUSESSL_ALL,     /* SSL for all communication or fail */
+  CURLUSESSL_LAST     /* not an option, never use */
+} curl_usessl;
+
+/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */
+
+/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the
+   name of improving interoperability with older servers. Some SSL libraries
+   have introduced work-arounds for this flaw but those work-arounds sometimes
+   make the SSL communication fail. To regain functionality with those broken
+   servers, a user can this way allow the vulnerability back. */
+#define CURLSSLOPT_ALLOW_BEAST (1<<0)
+
+/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those
+   SSL backends where such behavior is present. */
+#define CURLSSLOPT_NO_REVOKE (1<<1)
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+                          the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2009 */
+
+#define CURLFTPSSL_NONE CURLUSESSL_NONE
+#define CURLFTPSSL_TRY CURLUSESSL_TRY
+#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL
+#define CURLFTPSSL_ALL CURLUSESSL_ALL
+#define CURLFTPSSL_LAST CURLUSESSL_LAST
+#define curl_ftpssl curl_usessl
+#endif /*!CURL_NO_OLDIES*/
+
+/* parameter for the CURLOPT_FTP_SSL_CCC option */
+typedef enum {
+  CURLFTPSSL_CCC_NONE,    /* do not send CCC */
+  CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */
+  CURLFTPSSL_CCC_ACTIVE,  /* Initiate the shutdown */
+  CURLFTPSSL_CCC_LAST     /* not an option, never use */
+} curl_ftpccc;
+
+/* parameter for the CURLOPT_FTPSSLAUTH option */
+typedef enum {
+  CURLFTPAUTH_DEFAULT, /* let libcurl decide */
+  CURLFTPAUTH_SSL,     /* use "AUTH SSL" */
+  CURLFTPAUTH_TLS,     /* use "AUTH TLS" */
+  CURLFTPAUTH_LAST /* not an option, never use */
+} curl_ftpauth;
+
+/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */
+typedef enum {
+  CURLFTP_CREATE_DIR_NONE,  /* do NOT create missing dirs! */
+  CURLFTP_CREATE_DIR,       /* (FTP/SFTP) if CWD fails, try MKD and then CWD
+                               again if MKD succeeded, for SFTP this does
+                               similar magic */
+  CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD
+                               again even if MKD failed! */
+  CURLFTP_CREATE_DIR_LAST   /* not an option, never use */
+} curl_ftpcreatedir;
+
+/* parameter for the CURLOPT_FTP_FILEMETHOD option */
+typedef enum {
+  CURLFTPMETHOD_DEFAULT,   /* let libcurl pick */
+  CURLFTPMETHOD_MULTICWD,  /* single CWD operation for each path part */
+  CURLFTPMETHOD_NOCWD,     /* no CWD at all */
+  CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
+  CURLFTPMETHOD_LAST       /* not an option, never use */
+} curl_ftpmethod;
+
+/* bitmask defines for CURLOPT_HEADEROPT */
+#define CURLHEADER_UNIFIED  0
+#define CURLHEADER_SEPARATE (1<<0)
+
+/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
+#define CURLPROTO_HTTP   (1<<0)
+#define CURLPROTO_HTTPS  (1<<1)
+#define CURLPROTO_FTP    (1<<2)
+#define CURLPROTO_FTPS   (1<<3)
+#define CURLPROTO_SCP    (1<<4)
+#define CURLPROTO_SFTP   (1<<5)
+#define CURLPROTO_TELNET (1<<6)
+#define CURLPROTO_LDAP   (1<<7)
+#define CURLPROTO_LDAPS  (1<<8)
+#define CURLPROTO_DICT   (1<<9)
+#define CURLPROTO_FILE   (1<<10)
+#define CURLPROTO_TFTP   (1<<11)
+#define CURLPROTO_IMAP   (1<<12)
+#define CURLPROTO_IMAPS  (1<<13)
+#define CURLPROTO_POP3   (1<<14)
+#define CURLPROTO_POP3S  (1<<15)
+#define CURLPROTO_SMTP   (1<<16)
+#define CURLPROTO_SMTPS  (1<<17)
+#define CURLPROTO_RTSP   (1<<18)
+#define CURLPROTO_RTMP   (1<<19)
+#define CURLPROTO_RTMPT  (1<<20)
+#define CURLPROTO_RTMPE  (1<<21)
+#define CURLPROTO_RTMPTE (1<<22)
+#define CURLPROTO_RTMPS  (1<<23)
+#define CURLPROTO_RTMPTS (1<<24)
+#define CURLPROTO_GOPHER (1<<25)
+#define CURLPROTO_SMB    (1<<26)
+#define CURLPROTO_SMBS   (1<<27)
+#define CURLPROTO_ALL    (~0) /* enable everything */
+
+/* long may be 32 or 64 bits, but we should never depend on anything else
+   but 32 */
+#define CURLOPTTYPE_LONG          0
+#define CURLOPTTYPE_OBJECTPOINT   10000
+#define CURLOPTTYPE_STRINGPOINT   10000
+#define CURLOPTTYPE_FUNCTIONPOINT 20000
+#define CURLOPTTYPE_OFF_T         30000
+
+/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the
+   string options from the header file */
+
+/* name is uppercase CURLOPT_<name>,
+   type is one of the defined CURLOPTTYPE_<type>
+   number is unique identifier */
+#ifdef CINIT
+#undef CINIT
+#endif
+
+#ifdef CURL_ISOCPP
+#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG          CURLOPTTYPE_LONG
+#define OBJECTPOINT   CURLOPTTYPE_OBJECTPOINT
+#define STRINGPOINT   CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define OFF_T         CURLOPTTYPE_OFF_T
+#define CINIT(name,type,number) CURLOPT_/**/name = type + number
+#endif
+
+/*
+ * This macro-mania below setups the CURLOPT_[what] enum, to be used with
+ * curl_easy_setopt(). The first argument in the CINIT() macro is the [what]
+ * word.
+ */
+
+typedef enum {
+  /* This is the FILE * or void * the regular output should be written to. */
+  CINIT(WRITEDATA, OBJECTPOINT, 1),
+
+  /* The full URL to get/put */
+  CINIT(URL, STRINGPOINT, 2),
+
+  /* Port number to connect to, if other than default. */
+  CINIT(PORT, LONG, 3),
+
+  /* Name of proxy to use. */
+  CINIT(PROXY, STRINGPOINT, 4),
+
+  /* "user:password;options" to use when fetching. */
+  CINIT(USERPWD, STRINGPOINT, 5),
+
+  /* "user:password" to use with proxy. */
+  CINIT(PROXYUSERPWD, STRINGPOINT, 6),
+
+  /* Range to get, specified as an ASCII string. */
+  CINIT(RANGE, STRINGPOINT, 7),
+
+  /* not used */
+
+  /* Specified file stream to upload from (use as input): */
+  CINIT(READDATA, OBJECTPOINT, 9),
+
+  /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
+   * bytes big. If this is not used, error messages go to stderr instead: */
+  CINIT(ERRORBUFFER, OBJECTPOINT, 10),
+
+  /* Function that will be called to store the output (instead of fwrite). The
+   * parameters will use fwrite() syntax, make sure to follow them. */
+  CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11),
+
+  /* Function that will be called to read the input (instead of fread). The
+   * parameters will use fread() syntax, make sure to follow them. */
+  CINIT(READFUNCTION, FUNCTIONPOINT, 12),
+
+  /* Time-out the read operation after this amount of seconds */
+  CINIT(TIMEOUT, LONG, 13),
+
+  /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about
+   * how large the file being sent really is. That allows better error
+   * checking and better verifies that the upload was successful. -1 means
+   * unknown size.
+   *
+   * For large file support, there is also a _LARGE version of the key
+   * which takes an off_t type, allowing platforms with larger off_t
+   * sizes to handle larger files.  See below for INFILESIZE_LARGE.
+   */
+  CINIT(INFILESIZE, LONG, 14),
+
+  /* POST static input fields. */
+  CINIT(POSTFIELDS, OBJECTPOINT, 15),
+
+  /* Set the referrer page (needed by some CGIs) */
+  CINIT(REFERER, STRINGPOINT, 16),
+
+  /* Set the FTP PORT string (interface name, named or numerical IP address)
+     Use i.e '-' to use default address. */
+  CINIT(FTPPORT, STRINGPOINT, 17),
+
+  /* Set the User-Agent string (examined by some CGIs) */
+  CINIT(USERAGENT, STRINGPOINT, 18),
+
+  /* If the download receives less than "low speed limit" bytes/second
+   * during "low speed time" seconds, the operations is aborted.
+   * You could i.e if you have a pretty high speed connection, abort if
+   * it is less than 2000 bytes/sec during 20 seconds.
+   */
+
+  /* Set the "low speed limit" */
+  CINIT(LOW_SPEED_LIMIT, LONG, 19),
+
+  /* Set the "low speed time" */
+  CINIT(LOW_SPEED_TIME, LONG, 20),
+
+  /* Set the continuation offset.
+   *
+   * Note there is also a _LARGE version of this key which uses
+   * off_t types, allowing for large file offsets on platforms which
+   * use larger-than-32-bit off_t's.  Look below for RESUME_FROM_LARGE.
+   */
+  CINIT(RESUME_FROM, LONG, 21),
+
+  /* Set cookie in request: */
+  CINIT(COOKIE, STRINGPOINT, 22),
+
+  /* This points to a linked list of headers, struct curl_slist kind. This
+     list is also used for RTSP (in spite of its name) */
+  CINIT(HTTPHEADER, OBJECTPOINT, 23),
+
+  /* This points to a linked list of post entries, struct curl_httppost */
+  CINIT(HTTPPOST, OBJECTPOINT, 24),
+
+  /* name of the file keeping your private SSL-certificate */
+  CINIT(SSLCERT, STRINGPOINT, 25),
+
+  /* password for the SSL or SSH private key */
+  CINIT(KEYPASSWD, STRINGPOINT, 26),
+
+  /* send TYPE parameter? */
+  CINIT(CRLF, LONG, 27),
+
+  /* send linked-list of QUOTE commands */
+  CINIT(QUOTE, OBJECTPOINT, 28),
+
+  /* send FILE * or void * to store headers to, if you use a callback it
+     is simply passed to the callback unmodified */
+  CINIT(HEADERDATA, OBJECTPOINT, 29),
+
+  /* point to a file to read the initial cookies from, also enables
+     "cookie awareness" */
+  CINIT(COOKIEFILE, STRINGPOINT, 31),
+
+  /* What version to specifically try to use.
+     See CURL_SSLVERSION defines below. */
+  CINIT(SSLVERSION, LONG, 32),
+
+  /* What kind of HTTP time condition to use, see defines */
+  CINIT(TIMECONDITION, LONG, 33),
+
+  /* Time to use with the above condition. Specified in number of seconds
+     since 1 Jan 1970 */
+  CINIT(TIMEVALUE, LONG, 34),
+
+  /* 35 = OBSOLETE */
+
+  /* Custom request, for customizing the get command like
+     HTTP: DELETE, TRACE and others
+     FTP: to use a different list command
+     */
+  CINIT(CUSTOMREQUEST, STRINGPOINT, 36),
+
+  /* FILE handle to use instead of stderr */
+  CINIT(STDERR, OBJECTPOINT, 37),
+
+  /* 38 is not used */
+
+  /* send linked-list of post-transfer QUOTE commands */
+  CINIT(POSTQUOTE, OBJECTPOINT, 39),
+
+  CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */
+
+  CINIT(VERBOSE, LONG, 41),      /* talk a lot */
+  CINIT(HEADER, LONG, 42),       /* throw the header out too */
+  CINIT(NOPROGRESS, LONG, 43),   /* shut off the progress meter */
+  CINIT(NOBODY, LONG, 44),       /* use HEAD to get http document */
+  CINIT(FAILONERROR, LONG, 45),  /* no output on http error codes >= 400 */
+  CINIT(UPLOAD, LONG, 46),       /* this is an upload */
+  CINIT(POST, LONG, 47),         /* HTTP POST method */
+  CINIT(DIRLISTONLY, LONG, 48),  /* bare names when listing directories */
+
+  CINIT(APPEND, LONG, 50),       /* Append instead of overwrite on upload! */
+
+  /* Specify whether to read the user+password from the .netrc or the URL.
+   * This must be one of the CURL_NETRC_* enums below. */
+  CINIT(NETRC, LONG, 51),
+
+  CINIT(FOLLOWLOCATION, LONG, 52),  /* use Location: Luke! */
+
+  CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
+  CINIT(PUT, LONG, 54),          /* HTTP PUT */
+
+  /* 55 = OBSOLETE */
+
+  /* DEPRECATED
+   * Function that will be called instead of the internal progress display
+   * function. This function should be defined as the curl_progress_callback
+   * prototype defines. */
+  CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
+
+  /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
+     callbacks */
+  CINIT(PROGRESSDATA, OBJECTPOINT, 57),
+#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA
+
+  /* We want the referrer field set automatically when following locations */
+  CINIT(AUTOREFERER, LONG, 58),
+
+  /* Port of the proxy, can be set in the proxy string as well with:
+     "[host]:[port]" */
+  CINIT(PROXYPORT, LONG, 59),
+
+  /* size of the POST input data, if strlen() is not good to use */
+  CINIT(POSTFIELDSIZE, LONG, 60),
+
+  /* tunnel non-http operations through a HTTP proxy */
+  CINIT(HTTPPROXYTUNNEL, LONG, 61),
+
+  /* Set the interface string to use as outgoing network interface */
+  CINIT(INTERFACE, STRINGPOINT, 62),
+
+  /* Set the krb4/5 security level, this also enables krb4/5 awareness.  This
+   * is a string, 'clear', 'safe', 'confidential' or 'private'.  If the string
+   * is set but doesn't match one of these, 'private' will be used.  */
+  CINIT(KRBLEVEL, STRINGPOINT, 63),
+
+  /* Set if we should verify the peer in ssl handshake, set 1 to verify. */
+  CINIT(SSL_VERIFYPEER, LONG, 64),
+
+  /* The CApath or CAfile used to validate the peer certificate
+     this option is used only if SSL_VERIFYPEER is true */
+  CINIT(CAINFO, STRINGPOINT, 65),
+
+  /* 66 = OBSOLETE */
+  /* 67 = OBSOLETE */
+
+  /* Maximum number of http redirects to follow */
+  CINIT(MAXREDIRS, LONG, 68),
+
+  /* Pass a long set to 1 to get the date of the requested document (if
+     possible)! Pass a zero to shut it off. */
+  CINIT(FILETIME, LONG, 69),
+
+  /* This points to a linked list of telnet options */
+  CINIT(TELNETOPTIONS, OBJECTPOINT, 70),
+
+  /* Max amount of cached alive connections */
+  CINIT(MAXCONNECTS, LONG, 71),
+
+  CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */
+
+  /* 73 = OBSOLETE */
+
+  /* Set to explicitly use a new connection for the upcoming transfer.
+     Do not use this unless you're absolutely sure of this, as it makes the
+     operation slower and is less friendly for the network. */
+  CINIT(FRESH_CONNECT, LONG, 74),
+
+  /* Set to explicitly forbid the upcoming transfer's connection to be re-used
+     when done. Do not use this unless you're absolutely sure of this, as it
+     makes the operation slower and is less friendly for the network. */
+  CINIT(FORBID_REUSE, LONG, 75),
+
+  /* Set to a file name that contains random data for libcurl to use to
+     seed the random engine when doing SSL connects. */
+  CINIT(RANDOM_FILE, STRINGPOINT, 76),
+
+  /* Set to the Entropy Gathering Daemon socket pathname */
+  CINIT(EGDSOCKET, STRINGPOINT, 77),
+
+  /* Time-out connect operations after this amount of seconds, if connects are
+     OK within this time, then fine... This only aborts the connect phase. */
+  CINIT(CONNECTTIMEOUT, LONG, 78),
+
+  /* Function that will be called to store headers (instead of fwrite). The
+   * parameters will use fwrite() syntax, make sure to follow them. */
+  CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79),
+
+  /* Set this to force the HTTP request to get back to GET. Only really usable
+     if POST, PUT or a custom request have been used first.
+   */
+  CINIT(HTTPGET, LONG, 80),
+
+  /* Set if we should verify the Common name from the peer certificate in ssl
+   * handshake, set 1 to check existence, 2 to ensure that it matches the
+   * provided hostname. */
+  CINIT(SSL_VERIFYHOST, LONG, 81),
+
+  /* Specify which file name to write all known cookies in after completed
+     operation. Set file name to "-" (dash) to make it go to stdout. */
+  CINIT(COOKIEJAR, STRINGPOINT, 82),
+
+  /* Specify which SSL ciphers to use */
+  CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83),
+
+  /* Specify which HTTP version to use! This must be set to one of the
+     CURL_HTTP_VERSION* enums set below. */
+  CINIT(HTTP_VERSION, LONG, 84),
+
+  /* Specifically switch on or off the FTP engine's use of the EPSV command. By
+     default, that one will always be attempted before the more traditional
+     PASV command. */
+  CINIT(FTP_USE_EPSV, LONG, 85),
+
+  /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
+  CINIT(SSLCERTTYPE, STRINGPOINT, 86),
+
+  /* name of the file keeping your private SSL-key */
+  CINIT(SSLKEY, STRINGPOINT, 87),
+
+  /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
+  CINIT(SSLKEYTYPE, STRINGPOINT, 88),
+
+  /* crypto engine for the SSL-sub system */
+  CINIT(SSLENGINE, STRINGPOINT, 89),
+
+  /* set the crypto engine for the SSL-sub system as default
+     the param has no meaning...
+   */
+  CINIT(SSLENGINE_DEFAULT, LONG, 90),
+
+  /* Non-zero value means to use the global dns cache */
+  CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */
+
+  /* DNS cache timeout */
+  CINIT(DNS_CACHE_TIMEOUT, LONG, 92),
+
+  /* send linked-list of pre-transfer QUOTE commands */
+  CINIT(PREQUOTE, OBJECTPOINT, 93),
+
+  /* set the debug function */
+  CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94),
+
+  /* set the data for the debug function */
+  CINIT(DEBUGDATA, OBJECTPOINT, 95),
+
+  /* mark this as start of a cookie session */
+  CINIT(COOKIESESSION, LONG, 96),
+
+  /* The CApath directory used to validate the peer certificate
+     this option is used only if SSL_VERIFYPEER is true */
+  CINIT(CAPATH, STRINGPOINT, 97),
+
+  /* Instruct libcurl to use a smaller receive buffer */
+  CINIT(BUFFERSIZE, LONG, 98),
+
+  /* Instruct libcurl to not use any signal/alarm handlers, even when using
+     timeouts. This option is useful for multi-threaded applications.
+     See libcurl-the-guide for more background information. */
+  CINIT(NOSIGNAL, LONG, 99),
+
+  /* Provide a CURLShare for mutexing non-ts data */
+  CINIT(SHARE, OBJECTPOINT, 100),
+
+  /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
+     CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */
+  CINIT(PROXYTYPE, LONG, 101),
+
+  /* Set the Accept-Encoding string. Use this to tell a server you would like
+     the response to be compressed. Before 7.21.6, this was known as
+     CURLOPT_ENCODING */
+  CINIT(ACCEPT_ENCODING, STRINGPOINT, 102),
+
+  /* Set pointer to private data */
+  CINIT(PRIVATE, OBJECTPOINT, 103),
+
+  /* Set aliases for HTTP 200 in the HTTP Response header */
+  CINIT(HTTP200ALIASES, OBJECTPOINT, 104),
+
+  /* Continue to send authentication (user+password) when following locations,
+     even when hostname changed. This can potentially send off the name
+     and password to whatever host the server decides. */
+  CINIT(UNRESTRICTED_AUTH, LONG, 105),
+
+  /* Specifically switch on or off the FTP engine's use of the EPRT command (
+     it also disables the LPRT attempt). By default, those ones will always be
+     attempted before the good old traditional PORT command. */
+  CINIT(FTP_USE_EPRT, LONG, 106),
+
+  /* Set this to a bitmask value to enable the particular authentications
+     methods you like. Use this in combination with CURLOPT_USERPWD.
+     Note that setting multiple bits may cause extra network round-trips. */
+  CINIT(HTTPAUTH, LONG, 107),
+
+  /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
+     in second argument. The function must be matching the
+     curl_ssl_ctx_callback proto. */
+  CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),
+
+  /* Set the userdata for the ssl context callback function's third
+     argument */
+  CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
+
+  /* FTP Option that causes missing dirs to be created on the remote server.
+     In 7.19.4 we introduced the convenience enums for this option using the
+     CURLFTP_CREATE_DIR prefix.
+  */
+  CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110),
+
+  /* Set this to a bitmask value to enable the particular authentications
+     methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
+     Note that setting multiple bits may cause extra network round-trips. */
+  CINIT(PROXYAUTH, LONG, 111),
+
+  /* FTP option that changes the timeout, in seconds, associated with
+     getting a response.  This is different from transfer timeout time and
+     essentially places a demand on the FTP server to acknowledge commands
+     in a timely manner. */
+  CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112),
+#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT
+
+  /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
+     tell libcurl to resolve names to those IP versions only. This only has
+     affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
+  CINIT(IPRESOLVE, LONG, 113),
+
+  /* Set this option to limit the size of a file that will be downloaded from
+     an HTTP or FTP server.
+
+     Note there is also _LARGE version which adds large file support for
+     platforms which have larger off_t sizes.  See MAXFILESIZE_LARGE below. */
+  CINIT(MAXFILESIZE, LONG, 114),
+
+  /* See the comment for INFILESIZE above, but in short, specifies
+   * the size of the file being uploaded.  -1 means unknown.
+   */
+  CINIT(INFILESIZE_LARGE, OFF_T, 115),
+
+  /* Sets the continuation offset.  There is also a LONG version of this;
+   * look above for RESUME_FROM.
+   */
+  CINIT(RESUME_FROM_LARGE, OFF_T, 116),
+
+  /* Sets the maximum size of data that will be downloaded from
+   * an HTTP or FTP server.  See MAXFILESIZE above for the LONG version.
+   */
+  CINIT(MAXFILESIZE_LARGE, OFF_T, 117),
+
+  /* Set this option to the file name of your .netrc file you want libcurl
+     to parse (using the CURLOPT_NETRC option). If not set, libcurl will do
+     a poor attempt to find the user's home directory and check for a .netrc
+     file in there. */
+  CINIT(NETRC_FILE, STRINGPOINT, 118),
+
+  /* Enable SSL/TLS for FTP, pick one of:
+     CURLUSESSL_TRY     - try using SSL, proceed anyway otherwise
+     CURLUSESSL_CONTROL - SSL for the control connection or fail
+     CURLUSESSL_ALL     - SSL for all communication or fail
+  */
+  CINIT(USE_SSL, LONG, 119),
+
+  /* The _LARGE version of the standard POSTFIELDSIZE option */
+  CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
+
+  /* Enable/disable the TCP Nagle algorithm */
+  CINIT(TCP_NODELAY, LONG, 121),
+
+  /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 123 OBSOLETE. Gone in 7.16.0 */
+  /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 127 OBSOLETE. Gone in 7.16.0 */
+  /* 128 OBSOLETE. Gone in 7.16.0 */
+
+  /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option
+     can be used to change libcurl's default action which is to first try
+     "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK
+     response has been received.
+
+     Available parameters are:
+     CURLFTPAUTH_DEFAULT - let libcurl decide
+     CURLFTPAUTH_SSL     - try "AUTH SSL" first, then TLS
+     CURLFTPAUTH_TLS     - try "AUTH TLS" first, then SSL
+  */
+  CINIT(FTPSSLAUTH, LONG, 129),
+
+  CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130),
+  CINIT(IOCTLDATA, OBJECTPOINT, 131),
+
+  /* 132 OBSOLETE. Gone in 7.16.0 */
+  /* 133 OBSOLETE. Gone in 7.16.0 */
+
+  /* zero terminated string for pass on to the FTP server when asked for
+     "account" info */
+  CINIT(FTP_ACCOUNT, STRINGPOINT, 134),
+
+  /* feed cookie into cookie engine */
+  CINIT(COOKIELIST, STRINGPOINT, 135),
+
+  /* ignore Content-Length */
+  CINIT(IGNORE_CONTENT_LENGTH, LONG, 136),
+
+  /* Set to non-zero to skip the IP address received in a 227 PASV FTP server
+     response. Typically used for FTP-SSL purposes but is not restricted to
+     that. libcurl will then instead use the same IP address it used for the
+     control connection. */
+  CINIT(FTP_SKIP_PASV_IP, LONG, 137),
+
+  /* Select "file method" to use when doing FTP, see the curl_ftpmethod
+     above. */
+  CINIT(FTP_FILEMETHOD, LONG, 138),
+
+  /* Local port number to bind the socket to */
+  CINIT(LOCALPORT, LONG, 139),
+
+  /* Number of ports to try, including the first one set with LOCALPORT.
+     Thus, setting it to 1 will make no additional attempts but the first.
+  */
+  CINIT(LOCALPORTRANGE, LONG, 140),
+
+  /* no transfer, set up connection and let application use the socket by
+     extracting it with CURLINFO_LASTSOCKET */
+  CINIT(CONNECT_ONLY, LONG, 141),
+
+  /* Function that will be called to convert from the
+     network encoding (instead of using the iconv calls in libcurl) */
+  CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142),
+
+  /* Function that will be called to convert to the
+     network encoding (instead of using the iconv calls in libcurl) */
+  CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143),
+
+  /* Function that will be called to convert from UTF8
+     (instead of using the iconv calls in libcurl)
+     Note that this is used only for SSL certificate processing */
+  CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144),
+
+  /* if the connection proceeds too quickly then need to slow it down */
+  /* limit-rate: maximum number of bytes per second to send or receive */
+  CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145),
+  CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146),
+
+  /* Pointer to command string to send if USER/PASS fails. */
+  CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147),
+
+  /* callback function for setting socket options */
+  CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
+  CINIT(SOCKOPTDATA, OBJECTPOINT, 149),
+
+  /* set to 0 to disable session ID re-use for this transfer, default is
+     enabled (== 1) */
+  CINIT(SSL_SESSIONID_CACHE, LONG, 150),
+
+  /* allowed SSH authentication methods */
+  CINIT(SSH_AUTH_TYPES, LONG, 151),
+
+  /* Used by scp/sftp to do public/private key authentication */
+  CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152),
+  CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153),
+
+  /* Send CCC (Clear Command Channel) after authentication */
+  CINIT(FTP_SSL_CCC, LONG, 154),
+
+  /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */
+  CINIT(TIMEOUT_MS, LONG, 155),
+  CINIT(CONNECTTIMEOUT_MS, LONG, 156),
+
+  /* set to zero to disable the libcurl's decoding and thus pass the raw body
+     data to the application even when it is encoded/compressed */
+  CINIT(HTTP_TRANSFER_DECODING, LONG, 157),
+  CINIT(HTTP_CONTENT_DECODING, LONG, 158),
+
+  /* Permission used when creating new files and directories on the remote
+     server for protocols that support it, SFTP/SCP/FILE */
+  CINIT(NEW_FILE_PERMS, LONG, 159),
+  CINIT(NEW_DIRECTORY_PERMS, LONG, 160),
+
+  /* Set the behaviour of POST when redirecting. Values must be set to one
+     of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */
+  CINIT(POSTREDIR, LONG, 161),
+
+  /* used by scp/sftp to verify the host's public key */
+  CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162),
+
+  /* Callback function for opening socket (instead of socket(2)). Optionally,
+     callback is able change the address or refuse to connect returning
+     CURL_SOCKET_BAD.  The callback should have type
+     curl_opensocket_callback */
+  CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163),
+  CINIT(OPENSOCKETDATA, OBJECTPOINT, 164),
+
+  /* POST volatile input fields. */
+  CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165),
+
+  /* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy */
+  CINIT(PROXY_TRANSFER_MODE, LONG, 166),
+
+  /* Callback function for seeking in the input stream */
+  CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167),
+  CINIT(SEEKDATA, OBJECTPOINT, 168),
+
+  /* CRL file */
+  CINIT(CRLFILE, STRINGPOINT, 169),
+
+  /* Issuer certificate */
+  CINIT(ISSUERCERT, STRINGPOINT, 170),
+
+  /* (IPv6) Address scope */
+  CINIT(ADDRESS_SCOPE, LONG, 171),
+
+  /* Collect certificate chain info and allow it to get retrievable with
+     CURLINFO_CERTINFO after the transfer is complete. */
+  CINIT(CERTINFO, LONG, 172),
+
+  /* "name" and "pwd" to use when fetching. */
+  CINIT(USERNAME, STRINGPOINT, 173),
+  CINIT(PASSWORD, STRINGPOINT, 174),
+
+    /* "name" and "pwd" to use with Proxy when fetching. */
+  CINIT(PROXYUSERNAME, STRINGPOINT, 175),
+  CINIT(PROXYPASSWORD, STRINGPOINT, 176),
+
+  /* Comma separated list of hostnames defining no-proxy zones. These should
+     match both hostnames directly, and hostnames within a domain. For
+     example, local.com will match local.com and www.local.com, but NOT
+     notlocal.com or www.notlocal.com. For compatibility with other
+     implementations of this, .local.com will be considered to be the same as
+     local.com. A single * is the only valid wildcard, and effectively
+     disables the use of proxy. */
+  CINIT(NOPROXY, STRINGPOINT, 177),
+
+  /* block size for TFTP transfers */
+  CINIT(TFTP_BLKSIZE, LONG, 178),
+
+  /* Socks Service */
+  CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179),
+
+  /* Socks Service */
+  CINIT(SOCKS5_GSSAPI_NEC, LONG, 180),
+
+  /* set the bitmask for the protocols that are allowed to be used for the
+     transfer, which thus helps the app which takes URLs from users or other
+     external inputs and want to restrict what protocol(s) to deal
+     with. Defaults to CURLPROTO_ALL. */
+  CINIT(PROTOCOLS, LONG, 181),
+
+  /* set the bitmask for the protocols that libcurl is allowed to follow to,
+     as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+     to be set in both bitmasks to be allowed to get redirected to. Defaults
+     to all protocols except FILE and SCP. */
+  CINIT(REDIR_PROTOCOLS, LONG, 182),
+
+  /* set the SSH knownhost file name to use */
+  CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183),
+
+  /* set the SSH host key callback, must point to a curl_sshkeycallback
+     function */
+  CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184),
+
+  /* set the SSH host key callback custom pointer */
+  CINIT(SSH_KEYDATA, OBJECTPOINT, 185),
+
+  /* set the SMTP mail originator */
+  CINIT(MAIL_FROM, STRINGPOINT, 186),
+
+  /* set the list of SMTP mail receiver(s) */
+  CINIT(MAIL_RCPT, OBJECTPOINT, 187),
+
+  /* FTP: send PRET before PASV */
+  CINIT(FTP_USE_PRET, LONG, 188),
+
+  /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */
+  CINIT(RTSP_REQUEST, LONG, 189),
+
+  /* The RTSP session identifier */
+  CINIT(RTSP_SESSION_ID, STRINGPOINT, 190),
+
+  /* The RTSP stream URI */
+  CINIT(RTSP_STREAM_URI, STRINGPOINT, 191),
+
+  /* The Transport: header to use in RTSP requests */
+  CINIT(RTSP_TRANSPORT, STRINGPOINT, 192),
+
+  /* Manually initialize the client RTSP CSeq for this handle */
+  CINIT(RTSP_CLIENT_CSEQ, LONG, 193),
+
+  /* Manually initialize the server RTSP CSeq for this handle */
+  CINIT(RTSP_SERVER_CSEQ, LONG, 194),
+
+  /* The stream to pass to INTERLEAVEFUNCTION. */
+  CINIT(INTERLEAVEDATA, OBJECTPOINT, 195),
+
+  /* Let the application define a custom write method for RTP data */
+  CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196),
+
+  /* Turn on wildcard matching */
+  CINIT(WILDCARDMATCH, LONG, 197),
+
+  /* Directory matching callback called before downloading of an
+     individual file (chunk) started */
+  CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198),
+
+  /* Directory matching callback called after the file (chunk)
+     was downloaded, or skipped */
+  CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199),
+
+  /* Change match (fnmatch-like) callback for wildcard matching */
+  CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200),
+
+  /* Let the application define custom chunk data pointer */
+  CINIT(CHUNK_DATA, OBJECTPOINT, 201),
+
+  /* FNMATCH_FUNCTION user pointer */
+  CINIT(FNMATCH_DATA, OBJECTPOINT, 202),
+
+  /* send linked-list of name:port:address sets */
+  CINIT(RESOLVE, OBJECTPOINT, 203),
+
+  /* Set a username for authenticated TLS */
+  CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204),
+
+  /* Set a password for authenticated TLS */
+  CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205),
+
+  /* Set authentication type for authenticated TLS */
+  CINIT(TLSAUTH_TYPE, STRINGPOINT, 206),
+
+  /* Set to 1 to enable the "TE:" header in HTTP requests to ask for
+     compressed transfer-encoded responses. Set to 0 to disable the use of TE:
+     in outgoing requests. The current default is 0, but it might change in a
+     future libcurl release.
+
+     libcurl will ask for the compressed methods it knows of, and if that
+     isn't any, it will not ask for transfer-encoding at all even if this
+     option is set to 1.
+
+  */
+  CINIT(TRANSFER_ENCODING, LONG, 207),
+
+  /* Callback function for closing socket (instead of close(2)). The callback
+     should have type curl_closesocket_callback */
+  CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208),
+  CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209),
+
+  /* allow GSSAPI credential delegation */
+  CINIT(GSSAPI_DELEGATION, LONG, 210),
+
+  /* Set the name servers to use for DNS resolution */
+  CINIT(DNS_SERVERS, STRINGPOINT, 211),
+
+  /* Time-out accept operations (currently for FTP only) after this amount
+     of miliseconds. */
+  CINIT(ACCEPTTIMEOUT_MS, LONG, 212),
+
+  /* Set TCP keepalive */
+  CINIT(TCP_KEEPALIVE, LONG, 213),
+
+  /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */
+  CINIT(TCP_KEEPIDLE, LONG, 214),
+  CINIT(TCP_KEEPINTVL, LONG, 215),
+
+  /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
+  CINIT(SSL_OPTIONS, LONG, 216),
+
+  /* Set the SMTP auth originator */
+  CINIT(MAIL_AUTH, STRINGPOINT, 217),
+
+  /* Enable/disable SASL initial response */
+  CINIT(SASL_IR, LONG, 218),
+
+  /* Function that will be called instead of the internal progress display
+   * function. This function should be defined as the curl_xferinfo_callback
+   * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */
+  CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219),
+
+  /* The XOAUTH2 bearer token */
+  CINIT(XOAUTH2_BEARER, STRINGPOINT, 220),
+
+  /* Set the interface string to use as outgoing network
+   * interface for DNS requests.
+   * Only supported by the c-ares DNS backend */
+  CINIT(DNS_INTERFACE, STRINGPOINT, 221),
+
+  /* Set the local IPv4 address to use for outgoing DNS requests.
+   * Only supported by the c-ares DNS backend */
+  CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222),
+
+  /* Set the local IPv4 address to use for outgoing DNS requests.
+   * Only supported by the c-ares DNS backend */
+  CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223),
+
+  /* Set authentication options directly */
+  CINIT(LOGIN_OPTIONS, STRINGPOINT, 224),
+
+  /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */
+  CINIT(SSL_ENABLE_NPN, LONG, 225),
+
+  /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */
+  CINIT(SSL_ENABLE_ALPN, LONG, 226),
+
+  /* Time to wait for a response to a HTTP request containing an
+   * Expect: 100-continue header before sending the data anyway. */
+  CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227),
+
+  /* This points to a linked list of headers used for proxy requests only,
+     struct curl_slist kind */
+  CINIT(PROXYHEADER, OBJECTPOINT, 228),
+
+  /* Pass in a bitmask of "header options" */
+  CINIT(HEADEROPT, LONG, 229),
+
+  /* The public key in DER form used to validate the peer public key
+     this option is used only if SSL_VERIFYPEER is true */
+  CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230),
+
+  /* Path to Unix domain socket */
+  CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231),
+
+  /* Set if we should verify the certificate status. */
+  CINIT(SSL_VERIFYSTATUS, LONG, 232),
+
+  /* Set if we should enable TLS false start. */
+  CINIT(SSL_FALSESTART, LONG, 233),
+
+  /* Do not squash dot-dot sequences */
+  CINIT(PATH_AS_IS, LONG, 234),
+
+  /* Proxy Service Name */
+  CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235),
+
+  /* Service Name */
+  CINIT(SERVICE_NAME, STRINGPOINT, 236),
+
+  /* Wait/don't wait for pipe/mutex to clarify */
+  CINIT(PIPEWAIT, LONG, 237),
+
+  /* Set the protocol used when curl is given a URL without a protocol */
+  CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238),
+
+  /* Set stream weight, 1 - 256 (default is 16) */
+  CINIT(STREAM_WEIGHT, LONG, 239),
+
+  /* Set stream dependency on another CURL handle */
+  CINIT(STREAM_DEPENDS, OBJECTPOINT, 240),
+
+  /* Set E-xclusive stream dependency on another CURL handle */
+  CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241),
+
+  CURLOPT_LASTENTRY /* the last unused */
+} CURLoption;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+                          the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2011 */
+
+/* This was added in version 7.19.1 */
+#define CURLOPT_POST301 CURLOPT_POSTREDIR
+
+/* These are scheduled to disappear by 2009 */
+
+/* The following were added in 7.17.0 */
+#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_FTPAPPEND CURLOPT_APPEND
+#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY
+#define CURLOPT_FTP_SSL CURLOPT_USE_SSL
+
+/* The following were added earlier */
+
+#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL
+
+#else
+/* This is set if CURL_NO_OLDIES is defined at compile-time */
+#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
+#endif
+
+
+  /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
+     name resolves addresses using more than one IP protocol version, this
+     option might be handy to force libcurl to use a specific IP version. */
+#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
+                                     versions that your system allows */
+#define CURL_IPRESOLVE_V4       1 /* resolve to IPv4 addresses */
+#define CURL_IPRESOLVE_V6       2 /* resolve to IPv6 addresses */
+
+  /* three convenient "aliases" that follow the name scheme better */
+#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER
+
+  /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
+enum {
+  CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd
+                             like the library to choose the best possible
+                             for us! */
+  CURL_HTTP_VERSION_1_0,  /* please use HTTP 1.0 in the request */
+  CURL_HTTP_VERSION_1_1,  /* please use HTTP 1.1 in the request */
+  CURL_HTTP_VERSION_2_0,  /* please use HTTP 2 in the request */
+  CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */
+
+  CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
+};
+
+/* Convenience definition simple because the name of the version is HTTP/2 and
+   not 2.0. The 2_0 version of the enum name was set while the version was
+   still planned to be 2.0 and we stick to it for compatibility. */
+#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0
+
+/*
+ * Public API enums for RTSP requests
+ */
+enum {
+    CURL_RTSPREQ_NONE, /* first in list */
+    CURL_RTSPREQ_OPTIONS,
+    CURL_RTSPREQ_DESCRIBE,
+    CURL_RTSPREQ_ANNOUNCE,
+    CURL_RTSPREQ_SETUP,
+    CURL_RTSPREQ_PLAY,
+    CURL_RTSPREQ_PAUSE,
+    CURL_RTSPREQ_TEARDOWN,
+    CURL_RTSPREQ_GET_PARAMETER,
+    CURL_RTSPREQ_SET_PARAMETER,
+    CURL_RTSPREQ_RECORD,
+    CURL_RTSPREQ_RECEIVE,
+    CURL_RTSPREQ_LAST /* last in list */
+};
+
+  /* These enums are for use with the CURLOPT_NETRC option. */
+enum CURL_NETRC_OPTION {
+  CURL_NETRC_IGNORED,     /* The .netrc will never be read.
+                           * This is the default. */
+  CURL_NETRC_OPTIONAL,    /* A user:password in the URL will be preferred
+                           * to one in the .netrc. */
+  CURL_NETRC_REQUIRED,    /* A user:password in the URL will be ignored.
+                           * Unless one is set programmatically, the .netrc
+                           * will be queried. */
+  CURL_NETRC_LAST
+};
+
+enum {
+  CURL_SSLVERSION_DEFAULT,
+  CURL_SSLVERSION_TLSv1, /* TLS 1.x */
+  CURL_SSLVERSION_SSLv2,
+  CURL_SSLVERSION_SSLv3,
+  CURL_SSLVERSION_TLSv1_0,
+  CURL_SSLVERSION_TLSv1_1,
+  CURL_SSLVERSION_TLSv1_2,
+
+  CURL_SSLVERSION_LAST /* never use, keep last */
+};
+
+enum CURL_TLSAUTH {
+  CURL_TLSAUTH_NONE,
+  CURL_TLSAUTH_SRP,
+  CURL_TLSAUTH_LAST /* never use, keep last */
+};
+
+/* symbols to use with CURLOPT_POSTREDIR.
+   CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303
+   can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302
+   | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */
+
+#define CURL_REDIR_GET_ALL  0
+#define CURL_REDIR_POST_301 1
+#define CURL_REDIR_POST_302 2
+#define CURL_REDIR_POST_303 4
+#define CURL_REDIR_POST_ALL \
+    (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303)
+
+typedef enum {
+  CURL_TIMECOND_NONE,
+
+  CURL_TIMECOND_IFMODSINCE,
+  CURL_TIMECOND_IFUNMODSINCE,
+  CURL_TIMECOND_LASTMOD,
+
+  CURL_TIMECOND_LAST
+} curl_TimeCond;
+
+
+/* curl_strequal() and curl_strnequal() are subject for removal in a future
+   libcurl, see lib/README.curlx for details */
+CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2);
+CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n);
+
+/* name is uppercase CURLFORM_<name> */
+#ifdef CFINIT
+#undef CFINIT
+#endif
+
+#ifdef CURL_ISOCPP
+#define CFINIT(name) CURLFORM_ ## name
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define CFINIT(name) CURLFORM_/**/name
+#endif
+
+typedef enum {
+  CFINIT(NOTHING),        /********* the first one is unused ************/
+
+  /*  */
+  CFINIT(COPYNAME),
+  CFINIT(PTRNAME),
+  CFINIT(NAMELENGTH),
+  CFINIT(COPYCONTENTS),
+  CFINIT(PTRCONTENTS),
+  CFINIT(CONTENTSLENGTH),
+  CFINIT(FILECONTENT),
+  CFINIT(ARRAY),
+  CFINIT(OBSOLETE),
+  CFINIT(FILE),
+
+  CFINIT(BUFFER),
+  CFINIT(BUFFERPTR),
+  CFINIT(BUFFERLENGTH),
+
+  CFINIT(CONTENTTYPE),
+  CFINIT(CONTENTHEADER),
+  CFINIT(FILENAME),
+  CFINIT(END),
+  CFINIT(OBSOLETE2),
+
+  CFINIT(STREAM),
+  CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */
+
+  CURLFORM_LASTENTRY /* the last unused */
+} CURLformoption;
+
+#undef CFINIT /* done */
+
+/* structure to be used as parameter for CURLFORM_ARRAY */
+struct curl_forms {
+  CURLformoption option;
+  const char     *value;
+};
+
+/* use this for multipart formpost building */
+/* Returns code for curl_formadd()
+ *
+ * Returns:
+ * CURL_FORMADD_OK             on success
+ * CURL_FORMADD_MEMORY         if the FormInfo allocation fails
+ * CURL_FORMADD_OPTION_TWICE   if one option is given twice for one Form
+ * CURL_FORMADD_NULL           if a null pointer was given for a char
+ * CURL_FORMADD_MEMORY         if the allocation of a FormInfo struct failed
+ * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
+ * CURL_FORMADD_INCOMPLETE     if the some FormInfo is not complete (or error)
+ * CURL_FORMADD_MEMORY         if a curl_httppost struct cannot be allocated
+ * CURL_FORMADD_MEMORY         if some allocation for string copying failed.
+ * CURL_FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array
+ *
+ ***************************************************************************/
+typedef enum {
+  CURL_FORMADD_OK, /* first, no error */
+
+  CURL_FORMADD_MEMORY,
+  CURL_FORMADD_OPTION_TWICE,
+  CURL_FORMADD_NULL,
+  CURL_FORMADD_UNKNOWN_OPTION,
+  CURL_FORMADD_INCOMPLETE,
+  CURL_FORMADD_ILLEGAL_ARRAY,
+  CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */
+
+  CURL_FORMADD_LAST /* last */
+} CURLFORMcode;
+
+/*
+ * NAME curl_formadd()
+ *
+ * DESCRIPTION
+ *
+ * Pretty advanced function for building multi-part formposts. Each invoke
+ * adds one part that together construct a full post. Then use
+ * CURLOPT_HTTPPOST to send it off to libcurl.
+ */
+CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+                                      struct curl_httppost **last_post,
+                                      ...);
+
+/*
+ * callback function for curl_formget()
+ * The void *arg pointer will be the one passed as second argument to
+ *   curl_formget().
+ * The character buffer passed to it must not be freed.
+ * Should return the buffer length passed to it as the argument "len" on
+ *   success.
+ */
+typedef size_t (*curl_formget_callback)(void *arg, const char *buf,
+                                        size_t len);
+
+/*
+ * NAME curl_formget()
+ *
+ * DESCRIPTION
+ *
+ * Serialize a curl_httppost struct built with curl_formadd().
+ * Accepts a void pointer as second argument which will be passed to
+ * the curl_formget_callback function.
+ * Returns 0 on success.
+ */
+CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg,
+                             curl_formget_callback append);
+/*
+ * NAME curl_formfree()
+ *
+ * DESCRIPTION
+ *
+ * Free a multipart formpost previously built with curl_formadd().
+ */
+CURL_EXTERN void curl_formfree(struct curl_httppost *form);
+
+/*
+ * NAME curl_getenv()
+ *
+ * DESCRIPTION
+ *
+ * Returns a malloc()'ed string that MUST be curl_free()ed after usage is
+ * complete. DEPRECATED - see lib/README.curlx
+ */
+CURL_EXTERN char *curl_getenv(const char *variable);
+
+/*
+ * NAME curl_version()
+ *
+ * DESCRIPTION
+ *
+ * Returns a static ascii string of the libcurl version.
+ */
+CURL_EXTERN char *curl_version(void);
+
+/*
+ * NAME curl_easy_escape()
+ *
+ * DESCRIPTION
+ *
+ * Escapes URL strings (converts all letters consider illegal in URLs to their
+ * %XX versions). This function returns a new allocated string or NULL if an
+ * error occurred.
+ */
+CURL_EXTERN char *curl_easy_escape(CURL *handle,
+                                   const char *string,
+                                   int length);
+
+/* the previous version: */
+CURL_EXTERN char *curl_escape(const char *string,
+                              int length);
+
+
+/*
+ * NAME curl_easy_unescape()
+ *
+ * DESCRIPTION
+ *
+ * Unescapes URL encoding in strings (converts all %XX codes to their 8bit
+ * versions). This function returns a new allocated string or NULL if an error
+ * occurred.
+ * Conversion Note: On non-ASCII platforms the ASCII %XX codes are
+ * converted into the host encoding.
+ */
+CURL_EXTERN char *curl_easy_unescape(CURL *handle,
+                                     const char *string,
+                                     int length,
+                                     int *outlength);
+
+/* the previous version */
+CURL_EXTERN char *curl_unescape(const char *string,
+                                int length);
+
+/*
+ * NAME curl_free()
+ *
+ * DESCRIPTION
+ *
+ * Provided for de-allocation in the same translation unit that did the
+ * allocation. Added in libcurl 7.10
+ */
+CURL_EXTERN void curl_free(void *p);
+
+/*
+ * NAME curl_global_init()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() should be invoked exactly once for each application that
+ * uses libcurl and before any call of other libcurl functions.
+ *
+ * This function is not thread-safe!
+ */
+CURL_EXTERN CURLcode curl_global_init(long flags);
+
+/*
+ * NAME curl_global_init_mem()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() or curl_global_init_mem() should be invoked exactly once
+ * for each application that uses libcurl.  This function can be used to
+ * initialize libcurl and set user defined memory management callback
+ * functions.  Users can implement memory management routines to check for
+ * memory leaks, check for mis-use of the curl library etc.  User registered
+ * callback routines with be invoked by this library instead of the system
+ * memory management routines like malloc, free etc.
+ */
+CURL_EXTERN CURLcode curl_global_init_mem(long flags,
+                                          curl_malloc_callback m,
+                                          curl_free_callback f,
+                                          curl_realloc_callback r,
+                                          curl_strdup_callback s,
+                                          curl_calloc_callback c);
+
+/*
+ * NAME curl_global_cleanup()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_cleanup() should be invoked exactly once for each application
+ * that uses libcurl
+ */
+CURL_EXTERN void curl_global_cleanup(void);
+
+/* linked-list structure for the CURLOPT_QUOTE option (and other) */
+struct curl_slist {
+  char *data;
+  struct curl_slist *next;
+};
+
+/*
+ * NAME curl_slist_append()
+ *
+ * DESCRIPTION
+ *
+ * Appends a string to a linked list. If no list exists, it will be created
+ * first. Returns the new list, after appending.
+ */
+CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *,
+                                                 const char *);
+
+/*
+ * NAME curl_slist_free_all()
+ *
+ * DESCRIPTION
+ *
+ * free a previously built curl_slist.
+ */
+CURL_EXTERN void curl_slist_free_all(struct curl_slist *);
+
+/*
+ * NAME curl_getdate()
+ *
+ * DESCRIPTION
+ *
+ * Returns the time, in seconds since 1 Jan 1970 of the time string given in
+ * the first argument. The time argument in the second parameter is unused
+ * and should be set to NULL.
+ */
+CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused);
+
+/* info about the certificate chain, only for OpenSSL builds. Asked
+   for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+struct curl_certinfo {
+  int num_of_certs;             /* number of certificates with information */
+  struct curl_slist **certinfo; /* for each index in this array, there's a
+                                   linked list with textual information in the
+                                   format "name: value" */
+};
+
+/* enum for the different supported SSL backends */
+typedef enum {
+  CURLSSLBACKEND_NONE = 0,
+  CURLSSLBACKEND_OPENSSL = 1,
+  CURLSSLBACKEND_GNUTLS = 2,
+  CURLSSLBACKEND_NSS = 3,
+  CURLSSLBACKEND_OBSOLETE4 = 4,  /* Was QSOSSL. */
+  CURLSSLBACKEND_GSKIT = 5,
+  CURLSSLBACKEND_POLARSSL = 6,
+  CURLSSLBACKEND_CYASSL = 7,
+  CURLSSLBACKEND_SCHANNEL = 8,
+  CURLSSLBACKEND_DARWINSSL = 9,
+  CURLSSLBACKEND_AXTLS = 10,
+  CURLSSLBACKEND_MBEDTLS = 11
+} curl_sslbackend;
+
+/* Information about the SSL library used and the respective internal SSL
+   handle, which can be used to obtain further information regarding the
+   connection. Asked for with CURLINFO_TLS_SESSION. */
+struct curl_tlssessioninfo {
+  curl_sslbackend backend;
+  void *internals;
+};
+
+#define CURLINFO_STRING   0x100000
+#define CURLINFO_LONG     0x200000
+#define CURLINFO_DOUBLE   0x300000
+#define CURLINFO_SLIST    0x400000
+#define CURLINFO_SOCKET   0x500000
+#define CURLINFO_MASK     0x0fffff
+#define CURLINFO_TYPEMASK 0xf00000
+
+typedef enum {
+  CURLINFO_NONE, /* first, never use this */
+  CURLINFO_EFFECTIVE_URL    = CURLINFO_STRING + 1,
+  CURLINFO_RESPONSE_CODE    = CURLINFO_LONG   + 2,
+  CURLINFO_TOTAL_TIME       = CURLINFO_DOUBLE + 3,
+  CURLINFO_NAMELOOKUP_TIME  = CURLINFO_DOUBLE + 4,
+  CURLINFO_CONNECT_TIME     = CURLINFO_DOUBLE + 5,
+  CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6,
+  CURLINFO_SIZE_UPLOAD      = CURLINFO_DOUBLE + 7,
+  CURLINFO_SIZE_DOWNLOAD    = CURLINFO_DOUBLE + 8,
+  CURLINFO_SPEED_DOWNLOAD   = CURLINFO_DOUBLE + 9,
+  CURLINFO_SPEED_UPLOAD     = CURLINFO_DOUBLE + 10,
+  CURLINFO_HEADER_SIZE      = CURLINFO_LONG   + 11,
+  CURLINFO_REQUEST_SIZE     = CURLINFO_LONG   + 12,
+  CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG   + 13,
+  CURLINFO_FILETIME         = CURLINFO_LONG   + 14,
+  CURLINFO_CONTENT_LENGTH_DOWNLOAD   = CURLINFO_DOUBLE + 15,
+  CURLINFO_CONTENT_LENGTH_UPLOAD     = CURLINFO_DOUBLE + 16,
+  CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17,
+  CURLINFO_CONTENT_TYPE     = CURLINFO_STRING + 18,
+  CURLINFO_REDIRECT_TIME    = CURLINFO_DOUBLE + 19,
+  CURLINFO_REDIRECT_COUNT   = CURLINFO_LONG   + 20,
+  CURLINFO_PRIVATE          = CURLINFO_STRING + 21,
+  CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG   + 22,
+  CURLINFO_HTTPAUTH_AVAIL   = CURLINFO_LONG   + 23,
+  CURLINFO_PROXYAUTH_AVAIL  = CURLINFO_LONG   + 24,
+  CURLINFO_OS_ERRNO         = CURLINFO_LONG   + 25,
+  CURLINFO_NUM_CONNECTS     = CURLINFO_LONG   + 26,
+  CURLINFO_SSL_ENGINES      = CURLINFO_SLIST  + 27,
+  CURLINFO_COOKIELIST       = CURLINFO_SLIST  + 28,
+  CURLINFO_LASTSOCKET       = CURLINFO_LONG   + 29,
+  CURLINFO_FTP_ENTRY_PATH   = CURLINFO_STRING + 30,
+  CURLINFO_REDIRECT_URL     = CURLINFO_STRING + 31,
+  CURLINFO_PRIMARY_IP       = CURLINFO_STRING + 32,
+  CURLINFO_APPCONNECT_TIME  = CURLINFO_DOUBLE + 33,
+  CURLINFO_CERTINFO         = CURLINFO_SLIST  + 34,
+  CURLINFO_CONDITION_UNMET  = CURLINFO_LONG   + 35,
+  CURLINFO_RTSP_SESSION_ID  = CURLINFO_STRING + 36,
+  CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG   + 37,
+  CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG   + 38,
+  CURLINFO_RTSP_CSEQ_RECV   = CURLINFO_LONG   + 39,
+  CURLINFO_PRIMARY_PORT     = CURLINFO_LONG   + 40,
+  CURLINFO_LOCAL_IP         = CURLINFO_STRING + 41,
+  CURLINFO_LOCAL_PORT       = CURLINFO_LONG   + 42,
+  CURLINFO_TLS_SESSION      = CURLINFO_SLIST  + 43,
+  CURLINFO_ACTIVESOCKET     = CURLINFO_SOCKET + 44,
+  /* Fill in new entries below here! */
+
+  CURLINFO_LASTONE          = 44
+} CURLINFO;
+
+/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
+   CURLINFO_HTTP_CODE */
+#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE
+
+typedef enum {
+  CURLCLOSEPOLICY_NONE, /* first, never use this */
+
+  CURLCLOSEPOLICY_OLDEST,
+  CURLCLOSEPOLICY_LEAST_RECENTLY_USED,
+  CURLCLOSEPOLICY_LEAST_TRAFFIC,
+  CURLCLOSEPOLICY_SLOWEST,
+  CURLCLOSEPOLICY_CALLBACK,
+
+  CURLCLOSEPOLICY_LAST /* last, never use this */
+} curl_closepolicy;
+
+#define CURL_GLOBAL_SSL (1<<0)
+#define CURL_GLOBAL_WIN32 (1<<1)
+#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
+#define CURL_GLOBAL_NOTHING 0
+#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
+#define CURL_GLOBAL_ACK_EINTR (1<<2)
+
+
+/*****************************************************************************
+ * Setup defines, protos etc for the sharing stuff.
+ */
+
+/* Different data locks for a single share */
+typedef enum {
+  CURL_LOCK_DATA_NONE = 0,
+  /*  CURL_LOCK_DATA_SHARE is used internally to say that
+   *  the locking is just made to change the internal state of the share
+   *  itself.
+   */
+  CURL_LOCK_DATA_SHARE,
+  CURL_LOCK_DATA_COOKIE,
+  CURL_LOCK_DATA_DNS,
+  CURL_LOCK_DATA_SSL_SESSION,
+  CURL_LOCK_DATA_CONNECT,
+  CURL_LOCK_DATA_LAST
+} curl_lock_data;
+
+/* Different lock access types */
+typedef enum {
+  CURL_LOCK_ACCESS_NONE = 0,   /* unspecified action */
+  CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */
+  CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */
+  CURL_LOCK_ACCESS_LAST        /* never use */
+} curl_lock_access;
+
+typedef void (*curl_lock_function)(CURL *handle,
+                                   curl_lock_data data,
+                                   curl_lock_access locktype,
+                                   void *userptr);
+typedef void (*curl_unlock_function)(CURL *handle,
+                                     curl_lock_data data,
+                                     void *userptr);
+
+typedef void CURLSH;
+
+typedef enum {
+  CURLSHE_OK,  /* all is fine */
+  CURLSHE_BAD_OPTION, /* 1 */
+  CURLSHE_IN_USE,     /* 2 */
+  CURLSHE_INVALID,    /* 3 */
+  CURLSHE_NOMEM,      /* 4 out of memory */
+  CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */
+  CURLSHE_LAST        /* never use */
+} CURLSHcode;
+
+typedef enum {
+  CURLSHOPT_NONE,  /* don't use */
+  CURLSHOPT_SHARE,   /* specify a data type to share */
+  CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */
+  CURLSHOPT_LOCKFUNC,   /* pass in a 'curl_lock_function' pointer */
+  CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */
+  CURLSHOPT_USERDATA,   /* pass in a user data pointer used in the lock/unlock
+                           callback functions */
+  CURLSHOPT_LAST  /* never use */
+} CURLSHoption;
+
+CURL_EXTERN CURLSH *curl_share_init(void);
+CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...);
+CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *);
+
+/****************************************************************************
+ * Structures for querying information about the curl library at runtime.
+ */
+
+typedef enum {
+  CURLVERSION_FIRST,
+  CURLVERSION_SECOND,
+  CURLVERSION_THIRD,
+  CURLVERSION_FOURTH,
+  CURLVERSION_LAST /* never actually use this */
+} CURLversion;
+
+/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by
+   basically all programs ever that want to get version information. It is
+   meant to be a built-in version number for what kind of struct the caller
+   expects. If the struct ever changes, we redefine the NOW to another enum
+   from above. */
+#define CURLVERSION_NOW CURLVERSION_FOURTH
+
+typedef struct {
+  CURLversion age;          /* age of the returned struct */
+  const char *version;      /* LIBCURL_VERSION */
+  unsigned int version_num; /* LIBCURL_VERSION_NUM */
+  const char *host;         /* OS/host/cpu/machine when configured */
+  int features;             /* bitmask, see defines below */
+  const char *ssl_version;  /* human readable string */
+  long ssl_version_num;     /* not used anymore, always 0 */
+  const char *libz_version; /* human readable string */
+  /* protocols is terminated by an entry with a NULL protoname */
+  const char * const *protocols;
+
+  /* The fields below this were added in CURLVERSION_SECOND */
+  const char *ares;
+  int ares_num;
+
+  /* This field was added in CURLVERSION_THIRD */
+  const char *libidn;
+
+  /* These field were added in CURLVERSION_FOURTH */
+
+  /* Same as '_libiconv_version' if built with HAVE_ICONV */
+  int iconv_ver_num;
+
+  const char *libssh_version; /* human readable string */
+
+} curl_version_info_data;
+
+#define CURL_VERSION_IPV6         (1<<0)  /* IPv6-enabled */
+#define CURL_VERSION_KERBEROS4    (1<<1)  /* Kerberos V4 auth is supported
+                                             (deprecated) */
+#define CURL_VERSION_SSL          (1<<2)  /* SSL options are present */
+#define CURL_VERSION_LIBZ         (1<<3)  /* libz features are present */
+#define CURL_VERSION_NTLM         (1<<4)  /* NTLM auth is supported */
+#define CURL_VERSION_GSSNEGOTIATE (1<<5)  /* Negotiate auth is supported
+                                             (deprecated) */
+#define CURL_VERSION_DEBUG        (1<<6)  /* Built with debug capabilities */
+#define CURL_VERSION_ASYNCHDNS    (1<<7)  /* Asynchronous DNS resolves */
+#define CURL_VERSION_SPNEGO       (1<<8)  /* SPNEGO auth is supported */
+#define CURL_VERSION_LARGEFILE    (1<<9)  /* Supports files larger than 2GB */
+#define CURL_VERSION_IDN          (1<<10) /* Internationized Domain Names are
+                                             supported */
+#define CURL_VERSION_SSPI         (1<<11) /* Built against Windows SSPI */
+#define CURL_VERSION_CONV         (1<<12) /* Character conversions supported */
+#define CURL_VERSION_CURLDEBUG    (1<<13) /* Debug memory tracking supported */
+#define CURL_VERSION_TLSAUTH_SRP  (1<<14) /* TLS-SRP auth is supported */
+#define CURL_VERSION_NTLM_WB      (1<<15) /* NTLM delegation to winbind helper
+                                             is suported */
+#define CURL_VERSION_HTTP2        (1<<16) /* HTTP2 support built-in */
+#define CURL_VERSION_GSSAPI       (1<<17) /* Built against a GSS-API library */
+#define CURL_VERSION_KERBEROS5    (1<<18) /* Kerberos V5 auth is supported */
+#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */
+#define CURL_VERSION_PSL          (1<<20) /* Mozilla's Public Suffix List, used
+                                             for cookie domain verification */
+
+ /*
+ * NAME curl_version_info()
+ *
+ * DESCRIPTION
+ *
+ * This function returns a pointer to a static copy of the version info
+ * struct. See above.
+ */
+CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion);
+
+/*
+ * NAME curl_easy_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_strerror function may be used to turn a CURLcode value
+ * into the equivalent human readable error string.  This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_easy_strerror(CURLcode);
+
+/*
+ * NAME curl_share_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_share_strerror function may be used to turn a CURLSHcode value
+ * into the equivalent human readable error string.  This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_share_strerror(CURLSHcode);
+
+/*
+ * NAME curl_easy_pause()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_pause function pauses or unpauses transfers. Select the new
+ * state by setting the bitmask, use the convenience defines below.
+ *
+ */
+CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
+
+#define CURLPAUSE_RECV      (1<<0)
+#define CURLPAUSE_RECV_CONT (0)
+
+#define CURLPAUSE_SEND      (1<<2)
+#define CURLPAUSE_SEND_CONT (0)
+
+#define CURLPAUSE_ALL       (CURLPAUSE_RECV|CURLPAUSE_SEND)
+#define CURLPAUSE_CONT      (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT)
+
+#ifdef  __cplusplus
+}
+#endif
+
+/* unfortunately, the easy.h and multi.h include files need options and info
+  stuff before they can be included! */
+#include "easy.h" /* nothing in curl is fun without the easy stuff */
+#include "multi.h"
+
+/* the typechecker doesn't work in C++ (yet) */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
+    ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \
+    !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK)
+#include "typecheck-gcc.h"
+#else
+#if defined(__STDC__) && (__STDC__ >= 1)
+/* This preprocessor magic that replaces a call with the exact same call is
+   only done to make sure application authors pass exactly three arguments
+   to these functions. */
+#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param)
+#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg)
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+#endif /* __STDC__ >= 1 */
+#endif /* gcc >= 4.3 && !__cplusplus */
+
+#endif /* __CURL_CURL_H */
Index: UsbWattMeter/trunk/curl-7.47.1/include/curl/curlbuild.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/include/curl/curlbuild.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/include/curl/curlbuild.h	(revision 164)
@@ -0,0 +1,597 @@
+#ifndef __CURL_CURLBUILD_H
+#define __CURL_CURLBUILD_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/*               NOTES FOR CONFIGURE CAPABLE SYSTEMS                */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * See file include/curl/curlbuild.h.in, run configure, and forget
+ * that this file exists it is only used for non-configure systems.
+ * But you can keep reading if you want ;-)
+ *
+ */
+
+/* ================================================================ */
+/*                 NOTES FOR NON-CONFIGURE SYSTEMS                  */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * curl library user nor by the curl library builder.
+ *
+ * If you think that something actually needs to be changed, adjusted
+ * or fixed in this file, then, report it on the libcurl development
+ * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/
+ *
+ * Try to keep one section per platform, compiler and architecture,
+ * otherwise, if an existing section is reused for a different one and
+ * later on the original is adjusted, probably the piggybacking one can
+ * be adversely changed.
+ *
+ * In order to differentiate between platforms/compilers/architectures
+ * use only compiler built in predefined preprocessor symbols.
+ *
+ * This header file shall only export symbols which are 'curl' or 'CURL'
+ * prefixed, otherwise public name space would be polluted.
+ *
+ * NOTE 2:
+ * -------
+ *
+ * For any given platform/compiler curl_off_t must be typedef'ed to a
+ * 64-bit wide signed integral data type. The width of this data type
+ * must remain constant and independent of any possible large file
+ * support settings.
+ *
+ * As an exception to the above, curl_off_t shall be typedef'ed to a
+ * 32-bit wide signed integral data type if there is no 64-bit type.
+ *
+ * As a general rule, curl_off_t shall not be mapped to off_t. This
+ * rule shall only be violated if off_t is the only 64-bit data type
+ * available and the size of off_t is independent of large file support
+ * settings. Keep your build on the safe side avoiding an off_t gating.
+ * If you have a 64-bit off_t then take for sure that another 64-bit
+ * data type exists, dig deeper and you will find it.
+ *
+ * NOTE 3:
+ * -------
+ *
+ * Right now you might be staring at file include/curl/curlbuild.h.dist or
+ * at file include/curl/curlbuild.h, this is due to the following reason:
+ * file include/curl/curlbuild.h.dist is renamed to include/curl/curlbuild.h
+ * when the libcurl source code distribution archive file is created.
+ *
+ * File include/curl/curlbuild.h.dist is not included in the distribution
+ * archive. File include/curl/curlbuild.h is not present in the git tree.
+ *
+ * The distributed include/curl/curlbuild.h file is only intended to be used
+ * on systems which can not run the also distributed configure script.
+ *
+ * On systems capable of running the configure script, the configure process
+ * will overwrite the distributed include/curl/curlbuild.h file with one that
+ * is suitable and specific to the library being configured and built, which
+ * is generated from the include/curl/curlbuild.h.in template file.
+ *
+ * If you check out from git on a non-configure platform, you must run the
+ * appropriate buildconf* script to set up curlbuild.h and other local files.
+ *
+ */
+
+/* ================================================================ */
+/*  DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE  */
+/* ================================================================ */
+
+#ifdef CURL_SIZEOF_LONG
+#  error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
+#endif
+
+#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
+#  error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
+#  error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CURL_TYPEOF_CURL_OFF_T
+#  error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_FORMAT_CURL_OFF_T
+#  error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_FORMAT_CURL_OFF_TU
+#  error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
+#endif
+
+#ifdef CURL_FORMAT_OFF_T
+#  error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SIZEOF_CURL_OFF_T
+#  error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SUFFIX_CURL_OFF_T
+#  error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SUFFIX_CURL_OFF_TU
+#  error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
+   Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
+#endif
+
+/* ================================================================ */
+/*    EXTERNAL INTERFACE SETTINGS FOR NON-CONFIGURE SYSTEMS ONLY    */
+/* ================================================================ */
+
+#if defined(__DJGPP__) || defined(__GO32__)
+#  if defined(__DJGPP__) && (__DJGPP__ > 1)
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_FORMAT_OFF_T          "%lld"
+#    define CURL_SIZEOF_CURL_OFF_T     8
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  else
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_FORMAT_OFF_T          "%ld"
+#    define CURL_SIZEOF_CURL_OFF_T     4
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__SALFORDC__)
+#  define CURL_SIZEOF_LONG           4
+#  define CURL_TYPEOF_CURL_OFF_T     long
+#  define CURL_FORMAT_CURL_OFF_T     "ld"
+#  define CURL_FORMAT_CURL_OFF_TU    "lu"
+#  define CURL_FORMAT_OFF_T          "%ld"
+#  define CURL_SIZEOF_CURL_OFF_T     4
+#  define CURL_SUFFIX_CURL_OFF_T     L
+#  define CURL_SUFFIX_CURL_OFF_TU    UL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__BORLANDC__)
+#  if (__BORLANDC__ < 0x520)
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_FORMAT_OFF_T          "%ld"
+#    define CURL_SIZEOF_CURL_OFF_T     4
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  else
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "I64d"
+#    define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURL_FORMAT_OFF_T          "%I64d"
+#    define CURL_SIZEOF_CURL_OFF_T     8
+#    define CURL_SUFFIX_CURL_OFF_T     i64
+#    define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__TURBOC__)
+#  define CURL_SIZEOF_LONG           4
+#  define CURL_TYPEOF_CURL_OFF_T     long
+#  define CURL_FORMAT_CURL_OFF_T     "ld"
+#  define CURL_FORMAT_CURL_OFF_TU    "lu"
+#  define CURL_FORMAT_OFF_T          "%ld"
+#  define CURL_SIZEOF_CURL_OFF_T     4
+#  define CURL_SUFFIX_CURL_OFF_T     L
+#  define CURL_SUFFIX_CURL_OFF_TU    UL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__WATCOMC__)
+#  if defined(__386__)
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "I64d"
+#    define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURL_FORMAT_OFF_T          "%I64d"
+#    define CURL_SIZEOF_CURL_OFF_T     8
+#    define CURL_SUFFIX_CURL_OFF_T     i64
+#    define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  else
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_FORMAT_OFF_T          "%ld"
+#    define CURL_SIZEOF_CURL_OFF_T     4
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__POCC__)
+#  if (__POCC__ < 280)
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_FORMAT_OFF_T          "%ld"
+#    define CURL_SIZEOF_CURL_OFF_T     4
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  elif defined(_MSC_VER)
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "I64d"
+#    define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURL_FORMAT_OFF_T          "%I64d"
+#    define CURL_SIZEOF_CURL_OFF_T     8
+#    define CURL_SUFFIX_CURL_OFF_T     i64
+#    define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  else
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_FORMAT_OFF_T          "%lld"
+#    define CURL_SIZEOF_CURL_OFF_T     8
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__LCC__)
+#  define CURL_SIZEOF_LONG           4
+#  define CURL_TYPEOF_CURL_OFF_T     long
+#  define CURL_FORMAT_CURL_OFF_T     "ld"
+#  define CURL_FORMAT_CURL_OFF_TU    "lu"
+#  define CURL_FORMAT_OFF_T          "%ld"
+#  define CURL_SIZEOF_CURL_OFF_T     4
+#  define CURL_SUFFIX_CURL_OFF_T     L
+#  define CURL_SUFFIX_CURL_OFF_TU    UL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__SYMBIAN32__)
+#  if defined(__EABI__)  /* Treat all ARM compilers equally */
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_FORMAT_OFF_T          "%lld"
+#    define CURL_SIZEOF_CURL_OFF_T     8
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  elif defined(__CW32__)
+#    pragma longlong on
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_FORMAT_OFF_T          "%lld"
+#    define CURL_SIZEOF_CURL_OFF_T     8
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  elif defined(__VC32__)
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_FORMAT_OFF_T          "%lld"
+#    define CURL_SIZEOF_CURL_OFF_T     8
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__MWERKS__)
+#  define CURL_SIZEOF_LONG           4
+#  define CURL_TYPEOF_CURL_OFF_T     long long
+#  define CURL_FORMAT_CURL_OFF_T     "lld"
+#  define CURL_FORMAT_CURL_OFF_TU    "llu"
+#  define CURL_FORMAT_OFF_T          "%lld"
+#  define CURL_SIZEOF_CURL_OFF_T     8
+#  define CURL_SUFFIX_CURL_OFF_T     LL
+#  define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(_WIN32_WCE)
+#  define CURL_SIZEOF_LONG           4
+#  define CURL_TYPEOF_CURL_OFF_T     __int64
+#  define CURL_FORMAT_CURL_OFF_T     "I64d"
+#  define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#  define CURL_FORMAT_OFF_T          "%I64d"
+#  define CURL_SIZEOF_CURL_OFF_T     8
+#  define CURL_SUFFIX_CURL_OFF_T     i64
+#  define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__MINGW32__)
+#  define CURL_SIZEOF_LONG           4
+#  define CURL_TYPEOF_CURL_OFF_T     long long
+#  define CURL_FORMAT_CURL_OFF_T     "I64d"
+#  define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#  define CURL_FORMAT_OFF_T          "%I64d"
+#  define CURL_SIZEOF_CURL_OFF_T     8
+#  define CURL_SUFFIX_CURL_OFF_T     LL
+#  define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__VMS)
+#  if defined(__VAX)
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_FORMAT_OFF_T          "%ld"
+#    define CURL_SIZEOF_CURL_OFF_T     4
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  else
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_FORMAT_OFF_T          "%lld"
+#    define CURL_SIZEOF_CURL_OFF_T     8
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__OS400__)
+#  if defined(__ILEC400__)
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_FORMAT_OFF_T          "%lld"
+#    define CURL_SIZEOF_CURL_OFF_T     8
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#    define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#    define CURL_SIZEOF_CURL_SOCKLEN_T 4
+#    define CURL_PULL_SYS_TYPES_H      1
+#    define CURL_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(__MVS__)
+#  if defined(__IBMC__) || defined(__IBMCPP__)
+#    if defined(_ILP32)
+#      define CURL_SIZEOF_LONG           4
+#    elif defined(_LP64)
+#      define CURL_SIZEOF_LONG           8
+#    endif
+#    if defined(_LONG_LONG)
+#      define CURL_TYPEOF_CURL_OFF_T     long long
+#      define CURL_FORMAT_CURL_OFF_T     "lld"
+#      define CURL_FORMAT_CURL_OFF_TU    "llu"
+#      define CURL_FORMAT_OFF_T          "%lld"
+#      define CURL_SIZEOF_CURL_OFF_T     8
+#      define CURL_SUFFIX_CURL_OFF_T     LL
+#      define CURL_SUFFIX_CURL_OFF_TU    ULL
+#    elif defined(_LP64)
+#      define CURL_TYPEOF_CURL_OFF_T     long
+#      define CURL_FORMAT_CURL_OFF_T     "ld"
+#      define CURL_FORMAT_CURL_OFF_TU    "lu"
+#      define CURL_FORMAT_OFF_T          "%ld"
+#      define CURL_SIZEOF_CURL_OFF_T     8
+#      define CURL_SUFFIX_CURL_OFF_T     L
+#      define CURL_SUFFIX_CURL_OFF_TU    UL
+#    else
+#      define CURL_TYPEOF_CURL_OFF_T     long
+#      define CURL_FORMAT_CURL_OFF_T     "ld"
+#      define CURL_FORMAT_CURL_OFF_TU    "lu"
+#      define CURL_FORMAT_OFF_T          "%ld"
+#      define CURL_SIZEOF_CURL_OFF_T     4
+#      define CURL_SUFFIX_CURL_OFF_T     L
+#      define CURL_SUFFIX_CURL_OFF_TU    UL
+#    endif
+#    define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#    define CURL_SIZEOF_CURL_SOCKLEN_T 4
+#    define CURL_PULL_SYS_TYPES_H      1
+#    define CURL_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(__370__)
+#  if defined(__IBMC__) || defined(__IBMCPP__)
+#    if defined(_ILP32)
+#      define CURL_SIZEOF_LONG           4
+#    elif defined(_LP64)
+#      define CURL_SIZEOF_LONG           8
+#    endif
+#    if defined(_LONG_LONG)
+#      define CURL_TYPEOF_CURL_OFF_T     long long
+#      define CURL_FORMAT_CURL_OFF_T     "lld"
+#      define CURL_FORMAT_CURL_OFF_TU    "llu"
+#      define CURL_FORMAT_OFF_T          "%lld"
+#      define CURL_SIZEOF_CURL_OFF_T     8
+#      define CURL_SUFFIX_CURL_OFF_T     LL
+#      define CURL_SUFFIX_CURL_OFF_TU    ULL
+#    elif defined(_LP64)
+#      define CURL_TYPEOF_CURL_OFF_T     long
+#      define CURL_FORMAT_CURL_OFF_T     "ld"
+#      define CURL_FORMAT_CURL_OFF_TU    "lu"
+#      define CURL_FORMAT_OFF_T          "%ld"
+#      define CURL_SIZEOF_CURL_OFF_T     8
+#      define CURL_SUFFIX_CURL_OFF_T     L
+#      define CURL_SUFFIX_CURL_OFF_TU    UL
+#    else
+#      define CURL_TYPEOF_CURL_OFF_T     long
+#      define CURL_FORMAT_CURL_OFF_T     "ld"
+#      define CURL_FORMAT_CURL_OFF_TU    "lu"
+#      define CURL_FORMAT_OFF_T          "%ld"
+#      define CURL_SIZEOF_CURL_OFF_T     4
+#      define CURL_SUFFIX_CURL_OFF_T     L
+#      define CURL_SUFFIX_CURL_OFF_TU    UL
+#    endif
+#    define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#    define CURL_SIZEOF_CURL_SOCKLEN_T 4
+#    define CURL_PULL_SYS_TYPES_H      1
+#    define CURL_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(TPF)
+#  define CURL_SIZEOF_LONG           8
+#  define CURL_TYPEOF_CURL_OFF_T     long
+#  define CURL_FORMAT_CURL_OFF_T     "ld"
+#  define CURL_FORMAT_CURL_OFF_TU    "lu"
+#  define CURL_FORMAT_OFF_T          "%ld"
+#  define CURL_SIZEOF_CURL_OFF_T     8
+#  define CURL_SUFFIX_CURL_OFF_T     L
+#  define CURL_SUFFIX_CURL_OFF_TU    UL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+/* ===================================== */
+/*    KEEP MSVC THE PENULTIMATE ENTRY    */
+/* ===================================== */
+
+#elif defined(_MSC_VER)
+#  if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "I64d"
+#    define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURL_FORMAT_OFF_T          "%I64d"
+#    define CURL_SIZEOF_CURL_OFF_T     8
+#    define CURL_SUFFIX_CURL_OFF_T     i64
+#    define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  else
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_FORMAT_OFF_T          "%ld"
+#    define CURL_SIZEOF_CURL_OFF_T     4
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+
+/* ===================================== */
+/*    KEEP GENERIC GCC THE LAST ENTRY    */
+/* ===================================== */
+
+#elif defined(__GNUC__)
+#  if defined(__ILP32__) || \
+      defined(__i386__) || defined(__ppc__) || defined(__arm__) || \
+      defined(__sparc__) || defined(__mips__) || defined(__sh__)
+#    define CURL_SIZEOF_LONG           4
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_FORMAT_OFF_T          "%lld"
+#    define CURL_SIZEOF_CURL_OFF_T     8
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  elif defined(__LP64__) || \
+        defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__)
+#    define CURL_SIZEOF_LONG           8
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_FORMAT_OFF_T          "%ld"
+#    define CURL_SIZEOF_CURL_OFF_T     8
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+#  define CURL_PULL_SYS_TYPES_H      1
+#  define CURL_PULL_SYS_SOCKET_H     1
+
+#elif defined(__RX)
+#  define CURL_SIZEOF_LONG           4
+#  define CURL_TYPEOF_CURL_OFF_T     long
+#  define CURL_FORMAT_CURL_OFF_T     "ld"
+#  define CURL_FORMAT_CURL_OFF_TU    "lu"
+#  define CURL_FORMAT_OFF_T          "%ld"
+#  define CURL_SIZEOF_CURL_OFF_T     4
+#  define CURL_SUFFIX_CURL_OFF_T     L
+#  define CURL_SUFFIX_CURL_OFF_TU    UL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  define CURL_SIZEOF_CURL_SOCKLEN_T 4
+#else
+#  error "Unknown non-configure build target!"
+   Error Compilation_aborted_Unknown_non_configure_build_target
+#endif
+
+/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file  */
+/* sys/types.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_SYS_TYPES_H
+#  include <sys/types.h>
+#endif
+
+/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file  */
+/* sys/socket.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+
+/* Data type definition of curl_socklen_t. */
+
+#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
+  typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
+#endif
+
+/* Data type definition of curl_off_t. */
+
+#ifdef CURL_TYPEOF_CURL_OFF_T
+  typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
+#endif
+
+#endif /* __CURL_CURLBUILD_H */
Index: UsbWattMeter/trunk/curl-7.47.1/include/curl/curlrules.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/include/curl/curlrules.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/include/curl/curlrules.h	(revision 164)
@@ -0,0 +1,262 @@
+#ifndef __CURL_CURLRULES_H
+#define __CURL_CURLRULES_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/*                    COMPILE TIME SANITY CHECKS                    */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * All checks done in this file are intentionally placed in a public
+ * header file which is pulled by curl/curl.h when an application is
+ * being built using an already built libcurl library. Additionally
+ * this file is also included and used when building the library.
+ *
+ * If compilation fails on this file it is certainly sure that the
+ * problem is elsewhere. It could be a problem in the curlbuild.h
+ * header file, or simply that you are using different compilation
+ * settings than those used to build the library.
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * curl library user nor by the curl library builder.
+ *
+ * Do not deactivate any check, these are done to make sure that the
+ * library is properly built and used.
+ *
+ * You can find further help on the libcurl development mailing list:
+ * https://cool.haxx.se/mailman/listinfo/curl-library/
+ *
+ * NOTE 2
+ * ------
+ *
+ * Some of the following compile time checks are based on the fact
+ * that the dimension of a constant array can not be a negative one.
+ * In this way if the compile time verification fails, the compilation
+ * will fail issuing an error. The error description wording is compiler
+ * dependent but it will be quite similar to one of the following:
+ *
+ *   "negative subscript or subscript is too large"
+ *   "array must have at least one element"
+ *   "-1 is an illegal array size"
+ *   "size of array is negative"
+ *
+ * If you are building an application which tries to use an already
+ * built libcurl library and you are getting this kind of errors on
+ * this file, it is a clear indication that there is a mismatch between
+ * how the library was built and how you are trying to use it for your
+ * application. Your already compiled or binary library provider is the
+ * only one who can give you the details you need to properly use it.
+ */
+
+/*
+ * Verify that some macros are actually defined.
+ */
+
+#ifndef CURL_SIZEOF_LONG
+#  error "CURL_SIZEOF_LONG definition is missing!"
+   Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing
+#endif
+
+#ifndef CURL_TYPEOF_CURL_SOCKLEN_T
+#  error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!"
+   Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing
+#endif
+
+#ifndef CURL_SIZEOF_CURL_SOCKLEN_T
+#  error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!"
+   Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing
+#endif
+
+#ifndef CURL_TYPEOF_CURL_OFF_T
+#  error "CURL_TYPEOF_CURL_OFF_T definition is missing!"
+   Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_FORMAT_CURL_OFF_T
+#  error "CURL_FORMAT_CURL_OFF_T definition is missing!"
+   Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_FORMAT_CURL_OFF_TU
+#  error "CURL_FORMAT_CURL_OFF_TU definition is missing!"
+   Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing
+#endif
+
+#ifndef CURL_FORMAT_OFF_T
+#  error "CURL_FORMAT_OFF_T definition is missing!"
+   Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SIZEOF_CURL_OFF_T
+#  error "CURL_SIZEOF_CURL_OFF_T definition is missing!"
+   Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SUFFIX_CURL_OFF_T
+#  error "CURL_SUFFIX_CURL_OFF_T definition is missing!"
+   Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SUFFIX_CURL_OFF_TU
+#  error "CURL_SUFFIX_CURL_OFF_TU definition is missing!"
+   Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing
+#endif
+
+/*
+ * Macros private to this header file.
+ */
+
+#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1
+
+#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1
+
+/*
+ * Verify that the size previously defined and expected for long
+ * is the same as the one reported by sizeof() at compile time.
+ */
+
+typedef char
+  __curl_rule_01__
+    [CurlchkszEQ(long, CURL_SIZEOF_LONG)];
+
+/*
+ * Verify that the size previously defined and expected for
+ * curl_off_t is actually the the same as the one reported
+ * by sizeof() at compile time.
+ */
+
+typedef char
+  __curl_rule_02__
+    [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)];
+
+/*
+ * Verify at compile time that the size of curl_off_t as reported
+ * by sizeof() is greater or equal than the one reported for long
+ * for the current compilation.
+ */
+
+typedef char
+  __curl_rule_03__
+    [CurlchkszGE(curl_off_t, long)];
+
+/*
+ * Verify that the size previously defined and expected for
+ * curl_socklen_t is actually the the same as the one reported
+ * by sizeof() at compile time.
+ */
+
+typedef char
+  __curl_rule_04__
+    [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)];
+
+/*
+ * Verify at compile time that the size of curl_socklen_t as reported
+ * by sizeof() is greater or equal than the one reported for int for
+ * the current compilation.
+ */
+
+typedef char
+  __curl_rule_05__
+    [CurlchkszGE(curl_socklen_t, int)];
+
+/* ================================================================ */
+/*          EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS           */
+/* ================================================================ */
+
+/*
+ * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
+ * these to be visible and exported by the external libcurl interface API,
+ * while also making them visible to the library internals, simply including
+ * curl_setup.h, without actually needing to include curl.h internally.
+ * If some day this section would grow big enough, all this should be moved
+ * to its own header file.
+ */
+
+/*
+ * Figure out if we can use the ## preprocessor operator, which is supported
+ * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
+ * or  __cplusplus so we need to carefully check for them too.
+ */
+
+#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
+  defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
+  defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
+  defined(__ILEC400__)
+  /* This compiler is believed to have an ISO compatible preprocessor */
+#define CURL_ISOCPP
+#else
+  /* This compiler is believed NOT to have an ISO compatible preprocessor */
+#undef CURL_ISOCPP
+#endif
+
+/*
+ * Macros for minimum-width signed and unsigned curl_off_t integer constants.
+ */
+
+#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
+#  define __CURL_OFF_T_C_HLPR2(x) x
+#  define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x)
+#  define CURL_OFF_T_C(Val)  __CURL_OFF_T_C_HLPR1(Val) ## \
+                             __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
+#  define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
+                             __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
+#else
+#  ifdef CURL_ISOCPP
+#    define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
+#  else
+#    define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
+#  endif
+#  define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix)
+#  define CURL_OFF_T_C(Val)  __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
+#  define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
+#endif
+
+/*
+ * Get rid of macros private to this header file.
+ */
+
+#undef CurlchkszEQ
+#undef CurlchkszGE
+
+/*
+ * Get rid of macros not intended to exist beyond this point.
+ */
+
+#undef CURL_PULL_WS2TCPIP_H
+#undef CURL_PULL_SYS_TYPES_H
+#undef CURL_PULL_SYS_SOCKET_H
+#undef CURL_PULL_SYS_POLL_H
+#undef CURL_PULL_STDINT_H
+#undef CURL_PULL_INTTYPES_H
+
+#undef CURL_TYPEOF_CURL_SOCKLEN_T
+#undef CURL_TYPEOF_CURL_OFF_T
+
+#ifdef CURL_NO_OLDIES
+#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */
+#endif
+
+#endif /* __CURL_CURLRULES_H */
Index: UsbWattMeter/trunk/curl-7.47.1/include/curl/curlver.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/include/curl/curlver.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/include/curl/curlver.h	(revision 164)
@@ -0,0 +1,77 @@
+#ifndef __CURL_CURLVER_H
+#define __CURL_CURLVER_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This header file contains nothing but libcurl version info, generated by
+   a script at release-time. This was made its own header file in 7.11.2 */
+
+/* This is the global package copyright */
+#define LIBCURL_COPYRIGHT "1996 - 2016 Daniel Stenberg, <daniel@haxx.se>."
+
+/* This is the version number of the libcurl package from which this header
+   file origins: */
+#define LIBCURL_VERSION "7.47.1"
+
+/* The numeric version number is also available "in parts" by using these
+   defines: */
+#define LIBCURL_VERSION_MAJOR 7
+#define LIBCURL_VERSION_MINOR 47
+#define LIBCURL_VERSION_PATCH 1
+
+/* This is the numeric version of the libcurl version number, meant for easier
+   parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
+   always follow this syntax:
+
+         0xXXYYZZ
+
+   Where XX, YY and ZZ are the main version, release and patch numbers in
+   hexadecimal (using 8 bits each). All three numbers are always represented
+   using two digits.  1.2 would appear as "0x010200" while version 9.11.7
+   appears as "0x090b07".
+
+   This 6-digit (24 bits) hexadecimal number does not show pre-release number,
+   and it is always a greater number in a more recent release. It makes
+   comparisons with greater than and less than work.
+
+   Note: This define is the full hex number and _does not_ use the
+   CURL_VERSION_BITS() macro since curl's own configure script greps for it
+   and needs it to contain the full number.
+*/
+#define LIBCURL_VERSION_NUM 0x072f01
+
+/*
+ * This is the date and time when the full source package was created. The
+ * timestamp is not stored in git, as the timestamp is properly set in the
+ * tarballs by the maketgz script.
+ *
+ * The format of the date should follow this template:
+ *
+ * "Mon Feb 12 11:35:33 UTC 2007"
+ */
+#define LIBCURL_TIMESTAMP "Mon Feb  8 09:27:16 UTC 2016"
+
+#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z)
+#define CURL_AT_LEAST_VERSION(x,y,z) \
+  (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
+
+#endif /* __CURL_CURLVER_H */
Index: UsbWattMeter/trunk/curl-7.47.1/include/curl/easy.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/include/curl/easy.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/include/curl/easy.h	(revision 164)
@@ -0,0 +1,105 @@
+#ifndef __CURL_EASY_H
+#define __CURL_EASY_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdarg.h>
+
+CURL_EXTERN CURL *curl_easy_init(void);
+CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
+CURL_EXTERN CURLcode curl_easy_vsetopt(CURL *curl, CURLoption option, va_list args);
+CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
+CURL_EXTERN void curl_easy_cleanup(CURL *curl);
+
+/*
+ * NAME curl_easy_getinfo()
+ *
+ * DESCRIPTION
+ *
+ * Request internal information from the curl session with this function.  The
+ * third argument MUST be a pointer to a long, a pointer to a char * or a
+ * pointer to a double (as the documentation describes elsewhere).  The data
+ * pointed to will be filled in accordingly and can be relied upon only if the
+ * function returns CURLE_OK.  This function is intended to get used *AFTER* a
+ * performed transfer, all results from this function are undefined until the
+ * transfer is completed.
+ */
+CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
+
+
+/*
+ * NAME curl_easy_duphandle()
+ *
+ * DESCRIPTION
+ *
+ * Creates a new curl session handle with the same options set for the handle
+ * passed in. Duplicating a handle could only be a matter of cloning data and
+ * options, internal state info and things like persistent connections cannot
+ * be transferred. It is useful in multithreaded applications when you can run
+ * curl_easy_duphandle() for each new thread to avoid a series of identical
+ * curl_easy_setopt() invokes in every thread.
+ */
+CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl);
+
+/*
+ * NAME curl_easy_reset()
+ *
+ * DESCRIPTION
+ *
+ * Re-initializes a CURL handle to the default values. This puts back the
+ * handle to the same state as it was in when it was just created.
+ *
+ * It does keep: live connections, the Session ID cache, the DNS cache and the
+ * cookies.
+ */
+CURL_EXTERN void curl_easy_reset(CURL *curl);
+
+/*
+ * NAME curl_easy_recv()
+ *
+ * DESCRIPTION
+ *
+ * Receives data from the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
+                                    size_t *n);
+
+/*
+ * NAME curl_easy_send()
+ *
+ * DESCRIPTION
+ *
+ * Sends data over the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
+                                    size_t buflen, size_t *n);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/include/curl/mprintf.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/include/curl/mprintf.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/include/curl/mprintf.h	(revision 164)
@@ -0,0 +1,74 @@
+#ifndef __CURL_MPRINTF_H
+#define __CURL_MPRINTF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <stdarg.h>
+#include <stdio.h> /* needed for FILE */
+
+#include "curl.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+CURL_EXTERN int curl_mprintf(const char *format, ...);
+CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
+CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
+CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
+                               const char *format, ...);
+CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
+CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
+CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
+CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
+                                const char *format, va_list args);
+CURL_EXTERN char *curl_maprintf(const char *format, ...);
+CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
+
+#ifdef _MPRINTF_REPLACE
+# undef printf
+# undef fprintf
+# undef sprintf
+# undef vsprintf
+# undef snprintf
+# undef vprintf
+# undef vfprintf
+# undef vsnprintf
+# undef aprintf
+# undef vaprintf
+# define printf curl_mprintf
+# define fprintf curl_mfprintf
+# define sprintf curl_msprintf
+# define vsprintf curl_mvsprintf
+# define snprintf curl_msnprintf
+# define vprintf curl_mvprintf
+# define vfprintf curl_mvfprintf
+# define vsnprintf curl_mvsnprintf
+# define aprintf curl_maprintf
+# define vaprintf curl_mvaprintf
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __CURL_MPRINTF_H */
Index: UsbWattMeter/trunk/curl-7.47.1/include/curl/multi.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/include/curl/multi.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/include/curl/multi.h	(revision 164)
@@ -0,0 +1,435 @@
+#ifndef __CURL_MULTI_H
+#define __CURL_MULTI_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+  This is an "external" header file. Don't give away any internals here!
+
+  GOALS
+
+  o Enable a "pull" interface. The application that uses libcurl decides where
+    and when to ask libcurl to get/send data.
+
+  o Enable multiple simultaneous transfers in the same thread without making it
+    complicated for the application.
+
+  o Enable the application to select() on its own file descriptors and curl's
+    file descriptors simultaneous easily.
+
+*/
+
+/*
+ * This header file should not really need to include "curl.h" since curl.h
+ * itself includes this file and we expect user applications to do #include
+ * <curl/curl.h> without the need for especially including multi.h.
+ *
+ * For some reason we added this include here at one point, and rather than to
+ * break existing (wrongly written) libcurl applications, we leave it as-is
+ * but with this warning attached.
+ */
+#include "curl.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef void CURLM;
+
+typedef enum {
+  CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
+                                    curl_multi_socket*() soon */
+  CURLM_OK,
+  CURLM_BAD_HANDLE,      /* the passed-in handle is not a valid CURLM handle */
+  CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
+  CURLM_OUT_OF_MEMORY,   /* if you ever get this, you're in deep sh*t */
+  CURLM_INTERNAL_ERROR,  /* this is a libcurl bug */
+  CURLM_BAD_SOCKET,      /* the passed in socket argument did not match */
+  CURLM_UNKNOWN_OPTION,  /* curl_multi_setopt() with unsupported option */
+  CURLM_ADDED_ALREADY,   /* an easy handle already added to a multi handle was
+                            attempted to get added - again */
+  CURLM_LAST
+} CURLMcode;
+
+/* just to make code nicer when using curl_multi_socket() you can now check
+   for CURLM_CALL_MULTI_SOCKET too in the same style it works for
+   curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
+#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
+
+/* bitmask bits for CURLMOPT_PIPELINING */
+#define CURLPIPE_NOTHING   0L
+#define CURLPIPE_HTTP1     1L
+#define CURLPIPE_MULTIPLEX 2L
+
+typedef enum {
+  CURLMSG_NONE, /* first, not used */
+  CURLMSG_DONE, /* This easy handle has completed. 'result' contains
+                   the CURLcode of the transfer */
+  CURLMSG_LAST /* last, not used */
+} CURLMSG;
+
+struct CURLMsg {
+  CURLMSG msg;       /* what this message means */
+  CURL *easy_handle; /* the handle it concerns */
+  union {
+    void *whatever;    /* message-specific data */
+    CURLcode result;   /* return code for transfer */
+  } data;
+};
+typedef struct CURLMsg CURLMsg;
+
+/* Based on poll(2) structure and values.
+ * We don't use pollfd and POLL* constants explicitly
+ * to cover platforms without poll(). */
+#define CURL_WAIT_POLLIN    0x0001
+#define CURL_WAIT_POLLPRI   0x0002
+#define CURL_WAIT_POLLOUT   0x0004
+
+struct curl_waitfd {
+  curl_socket_t fd;
+  short events;
+  short revents; /* not supported yet */
+};
+
+/*
+ * Name:    curl_multi_init()
+ *
+ * Desc:    inititalize multi-style curl usage
+ *
+ * Returns: a new CURLM handle to use in all 'curl_multi' functions.
+ */
+CURL_EXTERN CURLM *curl_multi_init(void);
+
+/*
+ * Name:    curl_multi_add_handle()
+ *
+ * Desc:    add a standard curl handle to the multi stack
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
+                                            CURL *curl_handle);
+
+ /*
+  * Name:    curl_multi_remove_handle()
+  *
+  * Desc:    removes a curl handle from the multi stack again
+  *
+  * Returns: CURLMcode type, general multi error code.
+  */
+CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
+                                               CURL *curl_handle);
+
+ /*
+  * Name:    curl_multi_fdset()
+  *
+  * Desc:    Ask curl for its fd_set sets. The app can use these to select() or
+  *          poll() on. We want curl_multi_perform() called as soon as one of
+  *          them are ready.
+  *
+  * Returns: CURLMcode type, general multi error code.
+  */
+CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
+                                       fd_set *read_fd_set,
+                                       fd_set *write_fd_set,
+                                       fd_set *exc_fd_set,
+                                       int *max_fd);
+
+/*
+ * Name:     curl_multi_wait()
+ *
+ * Desc:     Poll on all fds within a CURLM set as well as any
+ *           additional fds passed to the function.
+ *
+ * Returns:  CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
+                                      struct curl_waitfd extra_fds[],
+                                      unsigned int extra_nfds,
+                                      int timeout_ms,
+                                      int *ret);
+
+ /*
+  * Name:    curl_multi_perform()
+  *
+  * Desc:    When the app thinks there's data available for curl it calls this
+  *          function to read/write whatever there is right now. This returns
+  *          as soon as the reads and writes are done. This function does not
+  *          require that there actually is data available for reading or that
+  *          data can be written, it can be called just in case. It returns
+  *          the number of handles that still transfer data in the second
+  *          argument's integer-pointer.
+  *
+  * Returns: CURLMcode type, general multi error code. *NOTE* that this only
+  *          returns errors etc regarding the whole multi stack. There might
+  *          still have occurred problems on invidual transfers even when this
+  *          returns OK.
+  */
+CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
+                                         int *running_handles);
+
+ /*
+  * Name:    curl_multi_cleanup()
+  *
+  * Desc:    Cleans up and removes a whole multi stack. It does not free or
+  *          touch any individual easy handles in any way. We need to define
+  *          in what state those handles will be if this function is called
+  *          in the middle of a transfer.
+  *
+  * Returns: CURLMcode type, general multi error code.
+  */
+CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
+
+/*
+ * Name:    curl_multi_info_read()
+ *
+ * Desc:    Ask the multi handle if there's any messages/informationals from
+ *          the individual transfers. Messages include informationals such as
+ *          error code from the transfer or just the fact that a transfer is
+ *          completed. More details on these should be written down as well.
+ *
+ *          Repeated calls to this function will return a new struct each
+ *          time, until a special "end of msgs" struct is returned as a signal
+ *          that there is no more to get at this point.
+ *
+ *          The data the returned pointer points to will not survive calling
+ *          curl_multi_cleanup().
+ *
+ *          The 'CURLMsg' struct is meant to be very simple and only contain
+ *          very basic informations. If more involved information is wanted,
+ *          we will provide the particular "transfer handle" in that struct
+ *          and that should/could/would be used in subsequent
+ *          curl_easy_getinfo() calls (or similar). The point being that we
+ *          must never expose complex structs to applications, as then we'll
+ *          undoubtably get backwards compatibility problems in the future.
+ *
+ * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
+ *          of structs. It also writes the number of messages left in the
+ *          queue (after this read) in the integer the second argument points
+ *          to.
+ */
+CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
+                                          int *msgs_in_queue);
+
+/*
+ * Name:    curl_multi_strerror()
+ *
+ * Desc:    The curl_multi_strerror function may be used to turn a CURLMcode
+ *          value into the equivalent human readable error string.  This is
+ *          useful for printing meaningful error messages.
+ *
+ * Returns: A pointer to a zero-terminated error message.
+ */
+CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
+
+/*
+ * Name:    curl_multi_socket() and
+ *          curl_multi_socket_all()
+ *
+ * Desc:    An alternative version of curl_multi_perform() that allows the
+ *          application to pass in one of the file descriptors that have been
+ *          detected to have "action" on them and let libcurl perform.
+ *          See man page for details.
+ */
+#define CURL_POLL_NONE   0
+#define CURL_POLL_IN     1
+#define CURL_POLL_OUT    2
+#define CURL_POLL_INOUT  3
+#define CURL_POLL_REMOVE 4
+
+#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
+
+#define CURL_CSELECT_IN   0x01
+#define CURL_CSELECT_OUT  0x02
+#define CURL_CSELECT_ERR  0x04
+
+typedef int (*curl_socket_callback)(CURL *easy,      /* easy handle */
+                                    curl_socket_t s, /* socket */
+                                    int what,        /* see above */
+                                    void *userp,     /* private callback
+                                                        pointer */
+                                    void *socketp);  /* private socket
+                                                        pointer */
+/*
+ * Name:    curl_multi_timer_callback
+ *
+ * Desc:    Called by libcurl whenever the library detects a change in the
+ *          maximum number of milliseconds the app is allowed to wait before
+ *          curl_multi_socket() or curl_multi_perform() must be called
+ *          (to allow libcurl's timed events to take place).
+ *
+ * Returns: The callback should return zero.
+ */
+typedef int (*curl_multi_timer_callback)(CURLM *multi,    /* multi handle */
+                                         long timeout_ms, /* see above */
+                                         void *userp);    /* private callback
+                                                             pointer */
+
+CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
+                                        int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
+                                               curl_socket_t s,
+                                               int ev_bitmask,
+                                               int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
+                                            int *running_handles);
+
+#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
+/* This macro below was added in 7.16.3 to push users who recompile to use
+   the new curl_multi_socket_action() instead of the old curl_multi_socket()
+*/
+#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
+#endif
+
+/*
+ * Name:    curl_multi_timeout()
+ *
+ * Desc:    Returns the maximum number of milliseconds the app is allowed to
+ *          wait before curl_multi_socket() or curl_multi_perform() must be
+ *          called (to allow libcurl's timed events to take place).
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
+                                         long *milliseconds);
+
+#undef CINIT /* re-using the same name as in curl.h */
+
+#ifdef CURL_ISOCPP
+#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG          CURLOPTTYPE_LONG
+#define OBJECTPOINT   CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define OFF_T         CURLOPTTYPE_OFF_T
+#define CINIT(name,type,number) CURLMOPT_/**/name = type + number
+#endif
+
+typedef enum {
+  /* This is the socket callback function pointer */
+  CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1),
+
+  /* This is the argument passed to the socket callback */
+  CINIT(SOCKETDATA, OBJECTPOINT, 2),
+
+    /* set to 1 to enable pipelining for this multi handle */
+  CINIT(PIPELINING, LONG, 3),
+
+   /* This is the timer callback function pointer */
+  CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
+
+  /* This is the argument passed to the timer callback */
+  CINIT(TIMERDATA, OBJECTPOINT, 5),
+
+  /* maximum number of entries in the connection cache */
+  CINIT(MAXCONNECTS, LONG, 6),
+
+  /* maximum number of (pipelining) connections to one host */
+  CINIT(MAX_HOST_CONNECTIONS, LONG, 7),
+
+  /* maximum number of requests in a pipeline */
+  CINIT(MAX_PIPELINE_LENGTH, LONG, 8),
+
+  /* a connection with a content-length longer than this
+     will not be considered for pipelining */
+  CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9),
+
+  /* a connection with a chunk length longer than this
+     will not be considered for pipelining */
+  CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10),
+
+  /* a list of site names(+port) that are blacklisted from
+     pipelining */
+  CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11),
+
+  /* a list of server types that are blacklisted from
+     pipelining */
+  CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12),
+
+  /* maximum number of open connections in total */
+  CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13),
+
+   /* This is the server push callback function pointer */
+  CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14),
+
+  /* This is the argument passed to the server push callback */
+  CINIT(PUSHDATA, OBJECTPOINT, 15),
+
+  CURLMOPT_LASTENTRY /* the last unused */
+} CURLMoption;
+
+
+/*
+ * Name:    curl_multi_setopt()
+ *
+ * Desc:    Sets options for the multi handle.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
+                                        CURLMoption option, ...);
+
+
+/*
+ * Name:    curl_multi_assign()
+ *
+ * Desc:    This function sets an association in the multi handle between the
+ *          given socket and a private pointer of the application. This is
+ *          (only) useful for curl_multi_socket uses.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
+                                        curl_socket_t sockfd, void *sockp);
+
+
+/*
+ * Name: curl_push_callback
+ *
+ * Desc: This callback gets called when a new stream is being pushed by the
+ *       server. It approves or denies the new stream.
+ *
+ * Returns: CURL_PUSH_OK or CURL_PUSH_DENY.
+ */
+#define CURL_PUSH_OK   0
+#define CURL_PUSH_DENY 1
+
+struct curl_pushheaders;  /* forward declaration only */
+
+CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
+                                        size_t num);
+CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
+                                         const char *name);
+
+typedef int (*curl_push_callback)(CURL *parent,
+                                  CURL *easy,
+                                  size_t num_headers,
+                                  struct curl_pushheaders *headers,
+                                  void *userp);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/include/curl/stdcheaders.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/include/curl/stdcheaders.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/include/curl/stdcheaders.h	(revision 164)
@@ -0,0 +1,33 @@
+#ifndef __STDC_HEADERS_H
+#define __STDC_HEADERS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <sys/types.h>
+
+size_t fread (void *, size_t, size_t, FILE *);
+size_t fwrite (const void *, size_t, size_t, FILE *);
+
+int strcasecmp(const char *, const char *);
+int strncasecmp(const char *, const char *, size_t);
+
+#endif /* __STDC_HEADERS_H */
Index: UsbWattMeter/trunk/curl-7.47.1/include/curl/typecheck-gcc.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/include/curl/typecheck-gcc.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/include/curl/typecheck-gcc.h	(revision 164)
@@ -0,0 +1,622 @@
+#ifndef __CURL_TYPECHECK_GCC_H
+#define __CURL_TYPECHECK_GCC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* wraps curl_easy_setopt() with typechecking */
+
+/* To add a new kind of warning, add an
+ *   if(_curl_is_sometype_option(_curl_opt))
+ *     if(!_curl_is_sometype(value))
+ *       _curl_easy_setopt_err_sometype();
+ * block and define _curl_is_sometype_option, _curl_is_sometype and
+ * _curl_easy_setopt_err_sometype below
+ *
+ * NOTE: We use two nested 'if' statements here instead of the && operator, in
+ *       order to work around gcc bug #32061.  It affects only gcc 4.3.x/4.4.x
+ *       when compiling with -Wlogical-op.
+ *
+ * To add an option that uses the same type as an existing option, you'll just
+ * need to extend the appropriate _curl_*_option macro
+ */
+#define curl_easy_setopt(handle, option, value)                               \
+__extension__ ({                                                              \
+  __typeof__ (option) _curl_opt = option;                                     \
+  if(__builtin_constant_p(_curl_opt)) {                                       \
+    if(_curl_is_long_option(_curl_opt))                                       \
+      if(!_curl_is_long(value))                                               \
+        _curl_easy_setopt_err_long();                                         \
+    if(_curl_is_off_t_option(_curl_opt))                                      \
+      if(!_curl_is_off_t(value))                                              \
+        _curl_easy_setopt_err_curl_off_t();                                   \
+    if(_curl_is_string_option(_curl_opt))                                     \
+      if(!_curl_is_string(value))                                             \
+        _curl_easy_setopt_err_string();                                       \
+    if(_curl_is_write_cb_option(_curl_opt))                                   \
+      if(!_curl_is_write_cb(value))                                           \
+        _curl_easy_setopt_err_write_callback();                               \
+    if((_curl_opt) == CURLOPT_READFUNCTION)                                   \
+      if(!_curl_is_read_cb(value))                                            \
+        _curl_easy_setopt_err_read_cb();                                      \
+    if((_curl_opt) == CURLOPT_IOCTLFUNCTION)                                  \
+      if(!_curl_is_ioctl_cb(value))                                           \
+        _curl_easy_setopt_err_ioctl_cb();                                     \
+    if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION)                                \
+      if(!_curl_is_sockopt_cb(value))                                         \
+        _curl_easy_setopt_err_sockopt_cb();                                   \
+    if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION)                             \
+      if(!_curl_is_opensocket_cb(value))                                      \
+        _curl_easy_setopt_err_opensocket_cb();                                \
+    if((_curl_opt) == CURLOPT_PROGRESSFUNCTION)                               \
+      if(!_curl_is_progress_cb(value))                                        \
+        _curl_easy_setopt_err_progress_cb();                                  \
+    if((_curl_opt) == CURLOPT_DEBUGFUNCTION)                                  \
+      if(!_curl_is_debug_cb(value))                                           \
+        _curl_easy_setopt_err_debug_cb();                                     \
+    if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION)                               \
+      if(!_curl_is_ssl_ctx_cb(value))                                         \
+        _curl_easy_setopt_err_ssl_ctx_cb();                                   \
+    if(_curl_is_conv_cb_option(_curl_opt))                                    \
+      if(!_curl_is_conv_cb(value))                                            \
+        _curl_easy_setopt_err_conv_cb();                                      \
+    if((_curl_opt) == CURLOPT_SEEKFUNCTION)                                   \
+      if(!_curl_is_seek_cb(value))                                            \
+        _curl_easy_setopt_err_seek_cb();                                      \
+    if(_curl_is_cb_data_option(_curl_opt))                                    \
+      if(!_curl_is_cb_data(value))                                            \
+        _curl_easy_setopt_err_cb_data();                                      \
+    if((_curl_opt) == CURLOPT_ERRORBUFFER)                                    \
+      if(!_curl_is_error_buffer(value))                                       \
+        _curl_easy_setopt_err_error_buffer();                                 \
+    if((_curl_opt) == CURLOPT_STDERR)                                         \
+      if(!_curl_is_FILE(value))                                               \
+        _curl_easy_setopt_err_FILE();                                         \
+    if(_curl_is_postfields_option(_curl_opt))                                 \
+      if(!_curl_is_postfields(value))                                         \
+        _curl_easy_setopt_err_postfields();                                   \
+    if((_curl_opt) == CURLOPT_HTTPPOST)                                       \
+      if(!_curl_is_arr((value), struct curl_httppost))                        \
+        _curl_easy_setopt_err_curl_httpost();                                 \
+    if(_curl_is_slist_option(_curl_opt))                                      \
+      if(!_curl_is_arr((value), struct curl_slist))                           \
+        _curl_easy_setopt_err_curl_slist();                                   \
+    if((_curl_opt) == CURLOPT_SHARE)                                          \
+      if(!_curl_is_ptr((value), CURLSH))                                      \
+        _curl_easy_setopt_err_CURLSH();                                       \
+  }                                                                           \
+  curl_easy_setopt(handle, _curl_opt, value);                                 \
+})
+
+/* wraps curl_easy_getinfo() with typechecking */
+/* FIXME: don't allow const pointers */
+#define curl_easy_getinfo(handle, info, arg)                                  \
+__extension__ ({                                                              \
+  __typeof__ (info) _curl_info = info;                                        \
+  if(__builtin_constant_p(_curl_info)) {                                      \
+    if(_curl_is_string_info(_curl_info))                                      \
+      if(!_curl_is_arr((arg), char *))                                        \
+        _curl_easy_getinfo_err_string();                                      \
+    if(_curl_is_long_info(_curl_info))                                        \
+      if(!_curl_is_arr((arg), long))                                          \
+        _curl_easy_getinfo_err_long();                                        \
+    if(_curl_is_double_info(_curl_info))                                      \
+      if(!_curl_is_arr((arg), double))                                        \
+        _curl_easy_getinfo_err_double();                                      \
+    if(_curl_is_slist_info(_curl_info))                                       \
+      if(!_curl_is_arr((arg), struct curl_slist *))                           \
+        _curl_easy_getinfo_err_curl_slist();                                  \
+  }                                                                           \
+  curl_easy_getinfo(handle, _curl_info, arg);                                 \
+})
+
+/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(),
+ * for now just make sure that the functions are called with three
+ * arguments
+ */
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+
+
+/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
+ * functions */
+
+/* To define a new warning, use _CURL_WARNING(identifier, "message") */
+#define _CURL_WARNING(id, message)                                            \
+  static void __attribute__((__warning__(message)))                           \
+  __attribute__((__unused__)) __attribute__((__noinline__))                   \
+  id(void) { __asm__(""); }
+
+_CURL_WARNING(_curl_easy_setopt_err_long,
+  "curl_easy_setopt expects a long argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
+  "curl_easy_setopt expects a curl_off_t argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_string,
+              "curl_easy_setopt expects a "
+              "string (char* or char[]) argument for this option"
+  )
+_CURL_WARNING(_curl_easy_setopt_err_write_callback,
+  "curl_easy_setopt expects a curl_write_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_read_cb,
+  "curl_easy_setopt expects a curl_read_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
+  "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
+  "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
+              "curl_easy_setopt expects a "
+              "curl_opensocket_callback argument for this option"
+  )
+_CURL_WARNING(_curl_easy_setopt_err_progress_cb,
+  "curl_easy_setopt expects a curl_progress_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_debug_cb,
+  "curl_easy_setopt expects a curl_debug_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb,
+  "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_conv_cb,
+  "curl_easy_setopt expects a curl_conv_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_seek_cb,
+  "curl_easy_setopt expects a curl_seek_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_cb_data,
+              "curl_easy_setopt expects a "
+              "private data pointer as argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_error_buffer,
+              "curl_easy_setopt expects a "
+              "char buffer of CURL_ERROR_SIZE as argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_FILE,
+  "curl_easy_setopt expects a FILE* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_postfields,
+  "curl_easy_setopt expects a void* or char* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
+  "curl_easy_setopt expects a struct curl_httppost* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_slist,
+  "curl_easy_setopt expects a struct curl_slist* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
+  "curl_easy_setopt expects a CURLSH* argument for this option")
+
+_CURL_WARNING(_curl_easy_getinfo_err_string,
+  "curl_easy_getinfo expects a pointer to char * for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_long,
+  "curl_easy_getinfo expects a pointer to long for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_double,
+  "curl_easy_getinfo expects a pointer to double for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
+  "curl_easy_getinfo expects a pointer to struct curl_slist * for this info")
+
+/* groups of curl_easy_setops options that take the same type of argument */
+
+/* To add a new option to one of the groups, just add
+ *   (option) == CURLOPT_SOMETHING
+ * to the or-expression. If the option takes a long or curl_off_t, you don't
+ * have to do anything
+ */
+
+/* evaluates to true if option takes a long argument */
+#define _curl_is_long_option(option)                                          \
+  (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
+
+#define _curl_is_off_t_option(option)                                         \
+  ((option) > CURLOPTTYPE_OFF_T)
+
+/* evaluates to true if option takes a char* argument */
+#define _curl_is_string_option(option)                                        \
+  ((option) == CURLOPT_ACCEPT_ENCODING ||                                     \
+   (option) == CURLOPT_CAINFO ||                                              \
+   (option) == CURLOPT_CAPATH ||                                              \
+   (option) == CURLOPT_COOKIE ||                                              \
+   (option) == CURLOPT_COOKIEFILE ||                                          \
+   (option) == CURLOPT_COOKIEJAR ||                                           \
+   (option) == CURLOPT_COOKIELIST ||                                          \
+   (option) == CURLOPT_CRLFILE ||                                             \
+   (option) == CURLOPT_CUSTOMREQUEST ||                                       \
+   (option) == CURLOPT_DEFAULT_PROTOCOL ||                                    \
+   (option) == CURLOPT_DNS_INTERFACE ||                                       \
+   (option) == CURLOPT_DNS_LOCAL_IP4 ||                                       \
+   (option) == CURLOPT_DNS_LOCAL_IP6 ||                                       \
+   (option) == CURLOPT_DNS_SERVERS ||                                         \
+   (option) == CURLOPT_EGDSOCKET ||                                           \
+   (option) == CURLOPT_FTPPORT ||                                             \
+   (option) == CURLOPT_FTP_ACCOUNT ||                                         \
+   (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER ||                             \
+   (option) == CURLOPT_INTERFACE ||                                           \
+   (option) == CURLOPT_ISSUERCERT ||                                          \
+   (option) == CURLOPT_KEYPASSWD ||                                           \
+   (option) == CURLOPT_KRBLEVEL ||                                            \
+   (option) == CURLOPT_LOGIN_OPTIONS ||                                       \
+   (option) == CURLOPT_MAIL_AUTH ||                                           \
+   (option) == CURLOPT_MAIL_FROM ||                                           \
+   (option) == CURLOPT_NETRC_FILE ||                                          \
+   (option) == CURLOPT_NOPROXY ||                                             \
+   (option) == CURLOPT_PASSWORD ||                                            \
+   (option) == CURLOPT_PINNEDPUBLICKEY ||                                     \
+   (option) == CURLOPT_PROXY ||                                               \
+   (option) == CURLOPT_PROXYPASSWORD ||                                       \
+   (option) == CURLOPT_PROXYUSERNAME ||                                       \
+   (option) == CURLOPT_PROXYUSERPWD ||                                        \
+   (option) == CURLOPT_PROXY_SERVICE_NAME ||                                  \
+   (option) == CURLOPT_RANDOM_FILE ||                                         \
+   (option) == CURLOPT_RANGE ||                                               \
+   (option) == CURLOPT_REFERER ||                                             \
+   (option) == CURLOPT_RTSP_SESSION_ID ||                                     \
+   (option) == CURLOPT_RTSP_STREAM_URI ||                                     \
+   (option) == CURLOPT_RTSP_TRANSPORT ||                                      \
+   (option) == CURLOPT_SERVICE_NAME ||                                        \
+   (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE ||                               \
+   (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 ||                             \
+   (option) == CURLOPT_SSH_KNOWNHOSTS ||                                      \
+   (option) == CURLOPT_SSH_PRIVATE_KEYFILE ||                                 \
+   (option) == CURLOPT_SSH_PUBLIC_KEYFILE ||                                  \
+   (option) == CURLOPT_SSLCERT ||                                             \
+   (option) == CURLOPT_SSLCERTTYPE ||                                         \
+   (option) == CURLOPT_SSLENGINE ||                                           \
+   (option) == CURLOPT_SSLKEY ||                                              \
+   (option) == CURLOPT_SSLKEYTYPE ||                                          \
+   (option) == CURLOPT_SSL_CIPHER_LIST ||                                     \
+   (option) == CURLOPT_TLSAUTH_PASSWORD ||                                    \
+   (option) == CURLOPT_TLSAUTH_TYPE ||                                        \
+   (option) == CURLOPT_TLSAUTH_USERNAME ||                                    \
+   (option) == CURLOPT_UNIX_SOCKET_PATH ||                                    \
+   (option) == CURLOPT_URL ||                                                 \
+   (option) == CURLOPT_USERAGENT ||                                           \
+   (option) == CURLOPT_USERNAME ||                                            \
+   (option) == CURLOPT_USERPWD ||                                             \
+   (option) == CURLOPT_XOAUTH2_BEARER ||                                      \
+   0)
+
+/* evaluates to true if option takes a curl_write_callback argument */
+#define _curl_is_write_cb_option(option)                                      \
+  ((option) == CURLOPT_HEADERFUNCTION ||                                      \
+   (option) == CURLOPT_WRITEFUNCTION)
+
+/* evaluates to true if option takes a curl_conv_callback argument */
+#define _curl_is_conv_cb_option(option)                                       \
+  ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION ||                            \
+   (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION ||                          \
+   (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
+
+/* evaluates to true if option takes a data argument to pass to a callback */
+#define _curl_is_cb_data_option(option)                                       \
+  ((option) == CURLOPT_CHUNK_DATA ||                                          \
+   (option) == CURLOPT_CLOSESOCKETDATA ||                                     \
+   (option) == CURLOPT_DEBUGDATA ||                                           \
+   (option) == CURLOPT_FNMATCH_DATA ||                                        \
+   (option) == CURLOPT_HEADERDATA ||                                          \
+   (option) == CURLOPT_INTERLEAVEDATA ||                                      \
+   (option) == CURLOPT_IOCTLDATA ||                                           \
+   (option) == CURLOPT_OPENSOCKETDATA ||                                      \
+   (option) == CURLOPT_PRIVATE ||                                             \
+   (option) == CURLOPT_PROGRESSDATA ||                                        \
+   (option) == CURLOPT_READDATA ||                                            \
+   (option) == CURLOPT_SEEKDATA ||                                            \
+   (option) == CURLOPT_SOCKOPTDATA ||                                         \
+   (option) == CURLOPT_SSH_KEYDATA ||                                         \
+   (option) == CURLOPT_SSL_CTX_DATA ||                                        \
+   (option) == CURLOPT_WRITEDATA ||                                           \
+   0)
+
+/* evaluates to true if option takes a POST data argument (void* or char*) */
+#define _curl_is_postfields_option(option)                                    \
+  ((option) == CURLOPT_POSTFIELDS ||                                          \
+   (option) == CURLOPT_COPYPOSTFIELDS ||                                      \
+   0)
+
+/* evaluates to true if option takes a struct curl_slist * argument */
+#define _curl_is_slist_option(option)                                         \
+  ((option) == CURLOPT_HTTP200ALIASES ||                                      \
+   (option) == CURLOPT_HTTPHEADER ||                                          \
+   (option) == CURLOPT_MAIL_RCPT ||                                           \
+   (option) == CURLOPT_POSTQUOTE ||                                           \
+   (option) == CURLOPT_PREQUOTE ||                                            \
+   (option) == CURLOPT_PROXYHEADER ||                                         \
+   (option) == CURLOPT_QUOTE ||                                               \
+   (option) == CURLOPT_RESOLVE ||                                             \
+   (option) == CURLOPT_TELNETOPTIONS ||                                       \
+   0)
+
+/* groups of curl_easy_getinfo infos that take the same type of argument */
+
+/* evaluates to true if info expects a pointer to char * argument */
+#define _curl_is_string_info(info)                                            \
+  (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
+
+/* evaluates to true if info expects a pointer to long argument */
+#define _curl_is_long_info(info)                                              \
+  (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
+
+/* evaluates to true if info expects a pointer to double argument */
+#define _curl_is_double_info(info)                                            \
+  (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
+
+/* true if info expects a pointer to struct curl_slist * argument */
+#define _curl_is_slist_info(info)                                             \
+  (CURLINFO_SLIST < (info))
+
+
+/* typecheck helpers -- check whether given expression has requested type*/
+
+/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
+ * otherwise define a new macro. Search for __builtin_types_compatible_p
+ * in the GCC manual.
+ * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
+ * the actual expression passed to the curl_easy_setopt macro. This
+ * means that you can only apply the sizeof and __typeof__ operators, no
+ * == or whatsoever.
+ */
+
+/* XXX: should evaluate to true iff expr is a pointer */
+#define _curl_is_any_ptr(expr)                                                \
+  (sizeof(expr) == sizeof(void*))
+
+/* evaluates to true if expr is NULL */
+/* XXX: must not evaluate expr, so this check is not accurate */
+#define _curl_is_NULL(expr)                                                   \
+  (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
+
+/* evaluates to true if expr is type*, const type* or NULL */
+#define _curl_is_ptr(expr, type)                                              \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), type *) ||                  \
+   __builtin_types_compatible_p(__typeof__(expr), const type *))
+
+/* evaluates to true if expr is one of type[], type*, NULL or const type* */
+#define _curl_is_arr(expr, type)                                              \
+  (_curl_is_ptr((expr), type) ||                                              \
+   __builtin_types_compatible_p(__typeof__(expr), type []))
+
+/* evaluates to true if expr is a string */
+#define _curl_is_string(expr)                                                 \
+  (_curl_is_arr((expr), char) ||                                              \
+   _curl_is_arr((expr), signed char) ||                                       \
+   _curl_is_arr((expr), unsigned char))
+
+/* evaluates to true if expr is a long (no matter the signedness)
+ * XXX: for now, int is also accepted (and therefore short and char, which
+ * are promoted to int when passed to a variadic function) */
+#define _curl_is_long(expr)                                                   \
+  (__builtin_types_compatible_p(__typeof__(expr), long) ||                    \
+   __builtin_types_compatible_p(__typeof__(expr), signed long) ||             \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned long) ||           \
+   __builtin_types_compatible_p(__typeof__(expr), int) ||                     \
+   __builtin_types_compatible_p(__typeof__(expr), signed int) ||              \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned int) ||            \
+   __builtin_types_compatible_p(__typeof__(expr), short) ||                   \
+   __builtin_types_compatible_p(__typeof__(expr), signed short) ||            \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned short) ||          \
+   __builtin_types_compatible_p(__typeof__(expr), char) ||                    \
+   __builtin_types_compatible_p(__typeof__(expr), signed char) ||             \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned char))
+
+/* evaluates to true if expr is of type curl_off_t */
+#define _curl_is_off_t(expr)                                                  \
+  (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
+
+/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
+/* XXX: also check size of an char[] array? */
+#define _curl_is_error_buffer(expr)                                           \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), char *) ||                  \
+   __builtin_types_compatible_p(__typeof__(expr), char[]))
+
+/* evaluates to true if expr is of type (const) void* or (const) FILE* */
+#if 0
+#define _curl_is_cb_data(expr)                                                \
+  (_curl_is_ptr((expr), void) ||                                              \
+   _curl_is_ptr((expr), FILE))
+#else /* be less strict */
+#define _curl_is_cb_data(expr)                                                \
+  _curl_is_any_ptr(expr)
+#endif
+
+/* evaluates to true if expr is of type FILE* */
+#define _curl_is_FILE(expr)                                                   \
+  (__builtin_types_compatible_p(__typeof__(expr), FILE *))
+
+/* evaluates to true if expr can be passed as POST data (void* or char*) */
+#define _curl_is_postfields(expr)                                             \
+  (_curl_is_ptr((expr), void) ||                                              \
+   _curl_is_arr((expr), char))
+
+/* FIXME: the whole callback checking is messy...
+ * The idea is to tolerate char vs. void and const vs. not const
+ * pointers in arguments at least
+ */
+/* helper: __builtin_types_compatible_p distinguishes between functions and
+ * function pointers, hide it */
+#define _curl_callback_compatible(func, type)                                 \
+  (__builtin_types_compatible_p(__typeof__(func), type) ||                    \
+   __builtin_types_compatible_p(__typeof__(func), type*))
+
+/* evaluates to true if expr is of type curl_read_callback or "similar" */
+#define _curl_is_read_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) ||       \
+   __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) ||      \
+   _curl_callback_compatible((expr), _curl_read_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback2) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback3) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback4) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback5) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback6))
+typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*);
+typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*);
+typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*);
+typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*);
+typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*);
+typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*);
+
+/* evaluates to true if expr is of type curl_write_callback or "similar" */
+#define _curl_is_write_cb(expr)                                               \
+  (_curl_is_read_cb(expr) ||                                            \
+   __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) ||      \
+   __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) ||     \
+   _curl_callback_compatible((expr), _curl_write_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback4) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback5) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback6))
+typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*);
+typedef size_t (_curl_write_callback2)(const char *, size_t, size_t,
+                                       const void*);
+typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*);
+typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*);
+typedef size_t (_curl_write_callback5)(const void *, size_t, size_t,
+                                       const void*);
+typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*);
+
+/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
+#define _curl_is_ioctl_cb(expr)                                         \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) ||     \
+   _curl_callback_compatible((expr), _curl_ioctl_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback4))
+typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*);
+typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*);
+typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*);
+typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*);
+
+/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
+#define _curl_is_sockopt_cb(expr)                                       \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) ||   \
+   _curl_callback_compatible((expr), _curl_sockopt_callback1) ||              \
+   _curl_callback_compatible((expr), _curl_sockopt_callback2))
+typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
+typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t,
+                                      curlsocktype);
+
+/* evaluates to true if expr is of type curl_opensocket_callback or
+   "similar" */
+#define _curl_is_opensocket_cb(expr)                                    \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\
+   _curl_callback_compatible((expr), _curl_opensocket_callback1) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback2) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback3) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback4))
+typedef curl_socket_t (_curl_opensocket_callback1)
+  (void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback2)
+  (void *, curlsocktype, const struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback3)
+  (const void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback4)
+  (const void *, curlsocktype, const struct curl_sockaddr *);
+
+/* evaluates to true if expr is of type curl_progress_callback or "similar" */
+#define _curl_is_progress_cb(expr)                                      \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) ||  \
+   _curl_callback_compatible((expr), _curl_progress_callback1) ||             \
+   _curl_callback_compatible((expr), _curl_progress_callback2))
+typedef int (_curl_progress_callback1)(void *,
+    double, double, double, double);
+typedef int (_curl_progress_callback2)(const void *,
+    double, double, double, double);
+
+/* evaluates to true if expr is of type curl_debug_callback or "similar" */
+#define _curl_is_debug_cb(expr)                                         \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) ||     \
+   _curl_callback_compatible((expr), _curl_debug_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback4) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback5) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback6) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback7) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback8))
+typedef int (_curl_debug_callback1) (CURL *,
+    curl_infotype, char *, size_t, void *);
+typedef int (_curl_debug_callback2) (CURL *,
+    curl_infotype, char *, size_t, const void *);
+typedef int (_curl_debug_callback3) (CURL *,
+    curl_infotype, const char *, size_t, void *);
+typedef int (_curl_debug_callback4) (CURL *,
+    curl_infotype, const char *, size_t, const void *);
+typedef int (_curl_debug_callback5) (CURL *,
+    curl_infotype, unsigned char *, size_t, void *);
+typedef int (_curl_debug_callback6) (CURL *,
+    curl_infotype, unsigned char *, size_t, const void *);
+typedef int (_curl_debug_callback7) (CURL *,
+    curl_infotype, const unsigned char *, size_t, void *);
+typedef int (_curl_debug_callback8) (CURL *,
+    curl_infotype, const unsigned char *, size_t, const void *);
+
+/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
+/* this is getting even messier... */
+#define _curl_is_ssl_ctx_cb(expr)                                       \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) ||   \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
+typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *);
+typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
+typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
+typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *);
+#ifdef HEADER_SSL_H
+/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
+ * this will of course break if we're included before OpenSSL headers...
+ */
+typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
+typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
+typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
+typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX,
+                                           const void *);
+#else
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
+#endif
+
+/* evaluates to true if expr is of type curl_conv_callback or "similar" */
+#define _curl_is_conv_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) ||      \
+   _curl_callback_compatible((expr), _curl_conv_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback2) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback3) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback4))
+typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
+typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
+typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
+typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
+
+/* evaluates to true if expr is of type curl_seek_callback or "similar" */
+#define _curl_is_seek_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) ||      \
+   _curl_callback_compatible((expr), _curl_seek_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_seek_callback2))
+typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
+typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
+
+
+#endif /* __CURL_TYPECHECK_GCC_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/amigaos.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/amigaos.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/amigaos.c	(revision 164)
@@ -0,0 +1,77 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(__AMIGA__) && !defined(__ixemul__)
+
+#include <amitcp/socketbasetags.h>
+
+#include "amigaos.h"
+
+struct Library *SocketBase = NULL;
+extern int errno, h_errno;
+
+#ifdef __libnix__
+#include <stabs.h>
+void __request(const char *msg);
+#else
+# define __request( msg )       Printf( msg "\n\a")
+#endif
+
+void Curl_amiga_cleanup()
+{
+  if(SocketBase) {
+    CloseLibrary(SocketBase);
+    SocketBase = NULL;
+  }
+}
+
+bool Curl_amiga_init()
+{
+  if(!SocketBase)
+    SocketBase = OpenLibrary("bsdsocket.library", 4);
+
+  if(!SocketBase) {
+    __request("No TCP/IP Stack running!");
+    return FALSE;
+  }
+
+  if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
+                    SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "cURL",
+                    TAG_DONE)) {
+    __request("SocketBaseTags ERROR");
+    return FALSE;
+  }
+
+#ifndef __libnix__
+  atexit(Curl_amiga_cleanup);
+#endif
+
+  return TRUE;
+}
+
+#ifdef __libnix__
+ADD2EXIT(Curl_amiga_cleanup, -50);
+#endif
+
+#endif /* __AMIGA__ && ! __ixemul__ */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/amigaos.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/amigaos.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/amigaos.h	(revision 164)
@@ -0,0 +1,39 @@
+#ifndef HEADER_CURL_AMIGAOS_H
+#define HEADER_CURL_AMIGAOS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(__AMIGA__) && !defined(__ixemul__)
+
+bool Curl_amiga_init();
+void Curl_amiga_cleanup();
+
+#else
+
+#define Curl_amiga_init() 1
+#define Curl_amiga_cleanup() Curl_nop_stmt
+
+#endif
+
+#endif /* HEADER_CURL_AMIGAOS_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/arpa_telnet.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/arpa_telnet.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/arpa_telnet.h	(revision 164)
@@ -0,0 +1,104 @@
+#ifndef HEADER_CURL_ARPA_TELNET_H
+#define HEADER_CURL_ARPA_TELNET_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_TELNET
+/*
+ * Telnet option defines. Add more here if in need.
+ */
+#define CURL_TELOPT_BINARY   0  /* binary 8bit data */
+#define CURL_TELOPT_ECHO     1  /* just echo! */
+#define CURL_TELOPT_SGA      3  /* Suppress Go Ahead */
+#define CURL_TELOPT_EXOPL  255  /* EXtended OPtions List */
+#define CURL_TELOPT_TTYPE   24  /* Terminal TYPE */
+#define CURL_TELOPT_NAWS    31  /* Negotiate About Window Size */
+#define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */
+
+#define CURL_TELOPT_NEW_ENVIRON 39  /* NEW ENVIRONment variables */
+#define CURL_NEW_ENV_VAR   0
+#define CURL_NEW_ENV_VALUE 1
+
+/*
+ * The telnet options represented as strings
+ */
+static const char * const telnetoptions[]=
+{
+  "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",
+  "DE TERMINAL", "SUPDUP",         "SUPDUP OUTPUT", "SEND LOCATION",
+  "TERM TYPE",   "END OF RECORD",  "TACACS UID",    "OUTPUT MARKING",
+  "TTYLOC",      "3270 REGIME",    "X3 PAD",        "NAWS",
+  "TERM SPEED",  "LFLOW",          "LINEMODE",      "XDISPLOC",
+  "OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT",       "NEW-ENVIRON"
+};
+
+#define CURL_TELOPT_MAXIMUM CURL_TELOPT_NEW_ENVIRON
+
+#define CURL_TELOPT_OK(x) ((x) <= CURL_TELOPT_MAXIMUM)
+#define CURL_TELOPT(x)    telnetoptions[x]
+
+#define CURL_NTELOPTS 40
+
+/*
+ * First some defines
+ */
+#define CURL_xEOF 236 /* End Of File */
+#define CURL_SE   240 /* Sub negotiation End */
+#define CURL_NOP  241 /* No OPeration */
+#define CURL_DM   242 /* Data Mark */
+#define CURL_GA   249 /* Go Ahead, reverse the line */
+#define CURL_SB   250 /* SuBnegotiation */
+#define CURL_WILL 251 /* Our side WILL use this option */
+#define CURL_WONT 252 /* Our side WON'T use this option */
+#define CURL_DO   253 /* DO use this option! */
+#define CURL_DONT 254 /* DON'T use this option! */
+#define CURL_IAC  255 /* Interpret As Command */
+
+/*
+ * Then those numbers represented as strings:
+ */
+static const char * const telnetcmds[]=
+{
+  "EOF",  "SUSP",  "ABORT", "EOR",  "SE",
+  "NOP",  "DMARK", "BRK",   "IP",   "AO",
+  "AYT",  "EC",    "EL",    "GA",   "SB",
+  "WILL", "WONT",  "DO",    "DONT", "IAC"
+};
+
+#define CURL_TELCMD_MINIMUM CURL_xEOF /* the first one */
+#define CURL_TELCMD_MAXIMUM CURL_IAC  /* surprise, 255 is the last one! ;-) */
+
+#define CURL_TELQUAL_IS   0
+#define CURL_TELQUAL_SEND 1
+#define CURL_TELQUAL_INFO 2
+#define CURL_TELQUAL_NAME 3
+
+#define CURL_TELCMD_OK(x) ( ((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \
+                       ((unsigned int)(x) <= CURL_TELCMD_MAXIMUM) )
+#define CURL_TELCMD(x)    telnetcmds[(x)-CURL_TELCMD_MINIMUM]
+
+#endif /* CURL_DISABLE_TELNET */
+
+#endif /* HEADER_CURL_ARPA_TELNET_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/asyn-ares.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/asyn-ares.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/asyn-ares.c	(revision 164)
@@ -0,0 +1,691 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+/***********************************************************************
+ * Only for ares-enabled builds
+ * And only for functions that fulfill the asynch resolver backend API
+ * as defined in asyn.h, nothing else belongs in this file!
+ **********************************************************************/
+
+#ifdef CURLRES_ARES
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "multiif.h"
+#include "inet_pton.h"
+#include "connect.h"
+#include "select.h"
+#include "progress.h"
+#include "curl_printf.h"
+
+#  if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
+     (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
+#    define CARES_STATICLIB
+#  endif
+#  include <ares.h>
+#  include <ares_version.h> /* really old c-ares didn't include this by
+                               itself */
+
+#if ARES_VERSION >= 0x010500
+/* c-ares 1.5.0 or later, the callback proto is modified */
+#define HAVE_CARES_CALLBACK_TIMEOUTS 1
+#endif
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+struct ResolverResults {
+  int num_pending; /* number of ares_gethostbyname() requests */
+  Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */
+  int last_status;
+};
+
+/*
+ * Curl_resolver_global_init() - the generic low-level asynchronous name
+ * resolve API.  Called from curl_global_init() to initialize global resolver
+ * environment.  Initializes ares library.
+ */
+int Curl_resolver_global_init(void)
+{
+#ifdef CARES_HAVE_ARES_LIBRARY_INIT
+  if(ares_library_init(ARES_LIB_INIT_ALL)) {
+    return CURLE_FAILED_INIT;
+  }
+#endif
+  return CURLE_OK;
+}
+
+/*
+ * Curl_resolver_global_cleanup()
+ *
+ * Called from curl_global_cleanup() to destroy global resolver environment.
+ * Deinitializes ares library.
+ */
+void Curl_resolver_global_cleanup(void)
+{
+#ifdef CARES_HAVE_ARES_LIBRARY_CLEANUP
+  ares_library_cleanup();
+#endif
+}
+
+/*
+ * Curl_resolver_init()
+ *
+ * Called from curl_easy_init() -> Curl_open() to initialize resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure).  Fills the passed pointer by the initialized ares_channel.
+ */
+CURLcode Curl_resolver_init(void **resolver)
+{
+  int status = ares_init((ares_channel*)resolver);
+  if(status != ARES_SUCCESS) {
+    if(status == ARES_ENOMEM)
+      return CURLE_OUT_OF_MEMORY;
+    else
+      return CURLE_FAILED_INIT;
+  }
+  return CURLE_OK;
+  /* make sure that all other returns from this function should destroy the
+     ares channel before returning error! */
+}
+
+/*
+ * Curl_resolver_cleanup()
+ *
+ * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure).  Destroys the ares channel.
+ */
+void Curl_resolver_cleanup(void *resolver)
+{
+  ares_destroy((ares_channel)resolver);
+}
+
+/*
+ * Curl_resolver_duphandle()
+ *
+ * Called from curl_easy_duphandle() to duplicate resolver URL-state specific
+ * environment ('resolver' member of the UrlState structure).  Duplicates the
+ * 'from' ares channel and passes the resulting channel to the 'to' pointer.
+ */
+int Curl_resolver_duphandle(void **to, void *from)
+{
+  /* Clone the ares channel for the new handle */
+  if(ARES_SUCCESS != ares_dup((ares_channel*)to, (ares_channel)from))
+    return CURLE_FAILED_INIT;
+  return CURLE_OK;
+}
+
+static void destroy_async_data (struct Curl_async *async);
+
+/*
+ * Cancel all possibly still on-going resolves for this connection.
+ */
+void Curl_resolver_cancel(struct connectdata *conn)
+{
+  if(conn->data && conn->data->state.resolver)
+    ares_cancel((ares_channel)conn->data->state.resolver);
+  destroy_async_data(&conn->async);
+}
+
+/*
+ * destroy_async_data() cleans up async resolver data.
+ */
+static void destroy_async_data (struct Curl_async *async)
+{
+  free(async->hostname);
+
+  if(async->os_specific) {
+    struct ResolverResults *res = (struct ResolverResults *)async->os_specific;
+    if(res) {
+      if(res->temp_ai) {
+        Curl_freeaddrinfo(res->temp_ai);
+        res->temp_ai = NULL;
+      }
+      free(res);
+    }
+    async->os_specific = NULL;
+  }
+
+  async->hostname = NULL;
+}
+
+/*
+ * Curl_resolver_getsock() is called when someone from the outside world
+ * (using curl_multi_fdset()) wants to get our fd_set setup and we're talking
+ * with ares. The caller must make sure that this function is only called when
+ * we have a working ares channel.
+ *
+ * Returns: sockets-in-use-bitmap
+ */
+
+int Curl_resolver_getsock(struct connectdata *conn,
+                          curl_socket_t *socks,
+                          int numsocks)
+
+{
+  struct timeval maxtime;
+  struct timeval timebuf;
+  struct timeval *timeout;
+  long milli;
+  int max = ares_getsock((ares_channel)conn->data->state.resolver,
+                         (ares_socket_t *)socks, numsocks);
+
+  maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
+  maxtime.tv_usec = 0;
+
+  timeout = ares_timeout((ares_channel)conn->data->state.resolver, &maxtime,
+                         &timebuf);
+  milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
+  if(milli == 0)
+    milli += 10;
+  Curl_expire_latest(conn->data, milli);
+
+  return max;
+}
+
+/*
+ * waitperform()
+ *
+ * 1) Ask ares what sockets it currently plays with, then
+ * 2) wait for the timeout period to check for action on ares' sockets.
+ * 3) tell ares to act on all the sockets marked as "with action"
+ *
+ * return number of sockets it worked on
+ */
+
+static int waitperform(struct connectdata *conn, int timeout_ms)
+{
+  struct SessionHandle *data = conn->data;
+  int nfds;
+  int bitmask;
+  ares_socket_t socks[ARES_GETSOCK_MAXNUM];
+  struct pollfd pfd[ARES_GETSOCK_MAXNUM];
+  int i;
+  int num = 0;
+
+  bitmask = ares_getsock((ares_channel)data->state.resolver, socks,
+                         ARES_GETSOCK_MAXNUM);
+
+  for(i=0; i < ARES_GETSOCK_MAXNUM; i++) {
+    pfd[i].events = 0;
+    pfd[i].revents = 0;
+    if(ARES_GETSOCK_READABLE(bitmask, i)) {
+      pfd[i].fd = socks[i];
+      pfd[i].events |= POLLRDNORM|POLLIN;
+    }
+    if(ARES_GETSOCK_WRITABLE(bitmask, i)) {
+      pfd[i].fd = socks[i];
+      pfd[i].events |= POLLWRNORM|POLLOUT;
+    }
+    if(pfd[i].events != 0)
+      num++;
+    else
+      break;
+  }
+
+  if(num)
+    nfds = Curl_poll(pfd, num, timeout_ms);
+  else
+    nfds = 0;
+
+  if(!nfds)
+    /* Call ares_process() unconditonally here, even if we simply timed out
+       above, as otherwise the ares name resolve won't timeout! */
+    ares_process_fd((ares_channel)data->state.resolver, ARES_SOCKET_BAD,
+                    ARES_SOCKET_BAD);
+  else {
+    /* move through the descriptors and ask for processing on them */
+    for(i=0; i < num; i++)
+      ares_process_fd((ares_channel)data->state.resolver,
+                      pfd[i].revents & (POLLRDNORM|POLLIN)?
+                      pfd[i].fd:ARES_SOCKET_BAD,
+                      pfd[i].revents & (POLLWRNORM|POLLOUT)?
+                      pfd[i].fd:ARES_SOCKET_BAD);
+  }
+  return nfds;
+}
+
+/*
+ * Curl_resolver_is_resolved() is called repeatedly to check if a previous
+ * name resolve request has completed. It should also make sure to time-out if
+ * the operation seems to take too long.
+ *
+ * Returns normal CURLcode errors.
+ */
+CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
+                                   struct Curl_dns_entry **dns)
+{
+  struct SessionHandle *data = conn->data;
+  struct ResolverResults *res = (struct ResolverResults *)
+    conn->async.os_specific;
+  CURLcode result = CURLE_OK;
+
+  *dns = NULL;
+
+  waitperform(conn, 0);
+
+  if(res && !res->num_pending) {
+    (void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
+    /* temp_ai ownership is moved to the connection, so we need not free-up
+       them */
+    res->temp_ai = NULL;
+    if(!conn->async.dns) {
+      failf(data, "Could not resolve: %s (%s)",
+            conn->async.hostname, ares_strerror(conn->async.status));
+      result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
+        CURLE_COULDNT_RESOLVE_HOST;
+    }
+    else
+      *dns = conn->async.dns;
+
+    destroy_async_data(&conn->async);
+  }
+
+  return result;
+}
+
+/*
+ * Curl_resolver_wait_resolv()
+ *
+ * waits for a resolve to finish. This function should be avoided since using
+ * this risk getting the multi interface to "hang".
+ *
+ * If 'entry' is non-NULL, make it point to the resolved dns entry
+ *
+ * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
+ * CURLE_OPERATION_TIMEDOUT if a time-out occurred.
+ */
+CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
+                                   struct Curl_dns_entry **entry)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  long timeout;
+  struct timeval now = Curl_tvnow();
+  struct Curl_dns_entry *temp_entry;
+
+  timeout = Curl_timeleft(data, &now, TRUE);
+  if(!timeout)
+    timeout = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */
+
+  /* Wait for the name resolve query to complete. */
+  for(;;) {
+    struct timeval *tvp, tv, store;
+    long timediff;
+    int itimeout;
+    int timeout_ms;
+
+    itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
+
+    store.tv_sec = itimeout/1000;
+    store.tv_usec = (itimeout%1000)*1000;
+
+    tvp = ares_timeout((ares_channel)data->state.resolver, &store, &tv);
+
+    /* use the timeout period ares returned to us above if less than one
+       second is left, otherwise just use 1000ms to make sure the progress
+       callback gets called frequent enough */
+    if(!tvp->tv_sec)
+      timeout_ms = (int)(tvp->tv_usec/1000);
+    else
+      timeout_ms = 1000;
+
+    waitperform(conn, timeout_ms);
+    Curl_resolver_is_resolved(conn, &temp_entry);
+
+    if(conn->async.done)
+      break;
+
+    if(Curl_pgrsUpdate(conn)) {
+      result = CURLE_ABORTED_BY_CALLBACK;
+      timeout = -1; /* trigger the cancel below */
+    }
+    else {
+      struct timeval now2 = Curl_tvnow();
+      timediff = Curl_tvdiff(now2, now); /* spent time */
+      timeout -= timediff?timediff:1; /* always deduct at least 1 */
+      now = now2; /* for next loop */
+    }
+
+    if(timeout < 0) {
+      /* our timeout, so we cancel the ares operation */
+      ares_cancel((ares_channel)data->state.resolver);
+      break;
+    }
+  }
+
+  /* Operation complete, if the lookup was successful we now have the entry
+     in the cache. */
+  if(entry)
+    *entry = conn->async.dns;
+
+  if(result)
+    /* close the connection, since we can't return failure here without
+       cleaning up this connection properly.
+       TODO: remove this action from here, it is not a name resolver decision.
+    */
+    connclose(conn, "c-ares resolve failed");
+
+  return result;
+}
+
+/* Connects results to the list */
+static void compound_results(struct ResolverResults *res,
+                             Curl_addrinfo *ai)
+{
+  Curl_addrinfo *ai_tail;
+  if(!ai)
+    return;
+  ai_tail = ai;
+
+  while(ai_tail->ai_next)
+    ai_tail = ai_tail->ai_next;
+
+  /* Add the new results to the list of old results. */
+  ai_tail->ai_next = res->temp_ai;
+  res->temp_ai = ai;
+}
+
+/*
+ * ares_query_completed_cb() is the callback that ares will call when
+ * the host query initiated by ares_gethostbyname() from Curl_getaddrinfo(),
+ * when using ares, is completed either successfully or with failure.
+ */
+static void query_completed_cb(void *arg,  /* (struct connectdata *) */
+                               int status,
+#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
+                               int timeouts,
+#endif
+                               struct hostent *hostent)
+{
+  struct connectdata *conn = (struct connectdata *)arg;
+  struct ResolverResults *res;
+
+#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
+  (void)timeouts; /* ignored */
+#endif
+
+  if(ARES_EDESTRUCTION == status)
+    /* when this ares handle is getting destroyed, the 'arg' pointer may not
+       be valid so only defer it when we know the 'status' says its fine! */
+    return;
+
+  res = (struct ResolverResults *)conn->async.os_specific;
+  res->num_pending--;
+
+  if(CURL_ASYNC_SUCCESS == status) {
+    Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
+    if(ai) {
+      compound_results(res, ai);
+    }
+  }
+  /* A successful result overwrites any previous error */
+  if(res->last_status != ARES_SUCCESS)
+    res->last_status = status;
+}
+
+/*
+ * Curl_resolver_getaddrinfo() - when using ares
+ *
+ * Returns name information about the given hostname and port number. If
+ * successful, the 'hostent' is returned and the forth argument will point to
+ * memory we need to free after use. That memory *MUST* be freed with
+ * Curl_freeaddrinfo(), nothing else.
+ */
+Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+                                         const char *hostname,
+                                         int port,
+                                         int *waitp)
+{
+  char *bufp;
+  struct SessionHandle *data = conn->data;
+  struct in_addr in;
+  int family = PF_INET;
+#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
+  struct in6_addr in6;
+#endif /* CURLRES_IPV6 */
+
+  *waitp = 0; /* default to synchronous response */
+
+  /* First check if this is an IPv4 address string */
+  if(Curl_inet_pton(AF_INET, hostname, &in) > 0) {
+    /* This is a dotted IP address 123.123.123.123-style */
+    return Curl_ip2addr(AF_INET, &in, hostname, port);
+  }
+
+#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
+  /* Otherwise, check if this is an IPv6 address string */
+  if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0)
+    /* This must be an IPv6 address literal.  */
+    return Curl_ip2addr(AF_INET6, &in6, hostname, port);
+
+  switch(conn->ip_version) {
+  default:
+#if ARES_VERSION >= 0x010601
+    family = PF_UNSPEC; /* supported by c-ares since 1.6.1, so for older
+                           c-ares versions this just falls through and defaults
+                           to PF_INET */
+    break;
+#endif
+  case CURL_IPRESOLVE_V4:
+    family = PF_INET;
+    break;
+  case CURL_IPRESOLVE_V6:
+    family = PF_INET6;
+    break;
+  }
+#endif /* CURLRES_IPV6 */
+
+  bufp = strdup(hostname);
+  if(bufp) {
+    struct ResolverResults *res = NULL;
+    free(conn->async.hostname);
+    conn->async.hostname = bufp;
+    conn->async.port = port;
+    conn->async.done = FALSE;   /* not done */
+    conn->async.status = 0;     /* clear */
+    conn->async.dns = NULL;     /* clear */
+    res = calloc(sizeof(struct ResolverResults), 1);
+    if(!res) {
+      free(conn->async.hostname);
+      conn->async.hostname = NULL;
+      return NULL;
+    }
+    conn->async.os_specific = res;
+
+    /* initial status - failed */
+    res->last_status = ARES_ENOTFOUND;
+#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
+    if(family == PF_UNSPEC) {
+      if(Curl_ipv6works()) {
+        res->num_pending = 2;
+
+        /* areschannel is already setup in the Curl_open() function */
+        ares_gethostbyname((ares_channel)data->state.resolver, hostname,
+                            PF_INET, query_completed_cb, conn);
+        ares_gethostbyname((ares_channel)data->state.resolver, hostname,
+                            PF_INET6, query_completed_cb, conn);
+      }
+      else {
+        res->num_pending = 1;
+
+        /* areschannel is already setup in the Curl_open() function */
+        ares_gethostbyname((ares_channel)data->state.resolver, hostname,
+                            PF_INET, query_completed_cb, conn);
+      }
+    }
+    else
+#endif /* CURLRES_IPV6 */
+    {
+      res->num_pending = 1;
+
+      /* areschannel is already setup in the Curl_open() function */
+      ares_gethostbyname((ares_channel)data->state.resolver, hostname, family,
+                         query_completed_cb, conn);
+    }
+
+    *waitp = 1; /* expect asynchronous response */
+  }
+  return NULL; /* no struct yet */
+}
+
+CURLcode Curl_set_dns_servers(struct SessionHandle *data,
+                              char *servers)
+{
+  CURLcode result = CURLE_NOT_BUILT_IN;
+  int ares_result;
+
+  /* If server is NULL or empty, this would purge all DNS servers
+   * from ares library, which will cause any and all queries to fail.
+   * So, just return OK if none are configured and don't actually make
+   * any changes to c-ares.  This lets c-ares use it's defaults, which
+   * it gets from the OS (for instance from /etc/resolv.conf on Linux).
+   */
+  if(!(servers && servers[0]))
+    return CURLE_OK;
+
+#if (ARES_VERSION >= 0x010704)
+  ares_result = ares_set_servers_csv(data->state.resolver, servers);
+  switch(ares_result) {
+  case ARES_SUCCESS:
+    result = CURLE_OK;
+    break;
+  case ARES_ENOMEM:
+    result = CURLE_OUT_OF_MEMORY;
+    break;
+  case ARES_ENOTINITIALIZED:
+  case ARES_ENODATA:
+  case ARES_EBADSTR:
+  default:
+    result = CURLE_BAD_FUNCTION_ARGUMENT;
+    break;
+  }
+#else /* too old c-ares version! */
+  (void)data;
+  (void)(ares_result);
+#endif
+  return result;
+}
+
+CURLcode Curl_set_dns_interface(struct SessionHandle *data,
+                                const char *interf)
+{
+#if (ARES_VERSION >= 0x010704)
+  if(!interf)
+    interf = "";
+
+  ares_set_local_dev((ares_channel)data->state.resolver, interf);
+
+  return CURLE_OK;
+#else /* c-ares version too old! */
+  (void)data;
+  (void)interf;
+  return CURLE_NOT_BUILT_IN;
+#endif
+}
+
+CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
+                                const char *local_ip4)
+{
+#if (ARES_VERSION >= 0x010704)
+  struct in_addr a4;
+
+  if((!local_ip4) || (local_ip4[0] == 0)) {
+    a4.s_addr = 0; /* disabled: do not bind to a specific address */
+  }
+  else {
+    if(Curl_inet_pton(AF_INET, local_ip4, &a4) != 1) {
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+  }
+
+  ares_set_local_ip4((ares_channel)data->state.resolver, ntohl(a4.s_addr));
+
+  return CURLE_OK;
+#else /* c-ares version too old! */
+  (void)data;
+  (void)local_ip4;
+  return CURLE_NOT_BUILT_IN;
+#endif
+}
+
+CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
+                                const char *local_ip6)
+{
+#if (ARES_VERSION >= 0x010704) && defined(ENABLE_IPV6)
+  unsigned char a6[INET6_ADDRSTRLEN];
+
+  if((!local_ip6) || (local_ip6[0] == 0)) {
+    /* disabled: do not bind to a specific address */
+    memset(a6, 0, sizeof(a6));
+  }
+  else {
+    if(Curl_inet_pton(AF_INET6, local_ip6, a6) != 1) {
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+  }
+
+  ares_set_local_ip6((ares_channel)data->state.resolver, a6);
+
+  return CURLE_OK;
+#else /* c-ares version too old! */
+  (void)data;
+  (void)local_ip6;
+  return CURLE_NOT_BUILT_IN;
+#endif
+}
+#endif /* CURLRES_ARES */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/asyn-thread.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/asyn-thread.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/asyn-thread.c	(revision 164)
@@ -0,0 +1,698 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if defined(USE_THREADS_POSIX)
+#  ifdef HAVE_PTHREAD_H
+#    include <pthread.h>
+#  endif
+#elif defined(USE_THREADS_WIN32)
+#  ifdef HAVE_PROCESS_H
+#    include <process.h>
+#  endif
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#ifdef HAVE_GETADDRINFO
+#  define RESOLVER_ENOMEM  EAI_MEMORY
+#else
+#  define RESOLVER_ENOMEM  ENOMEM
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "multiif.h"
+#include "inet_pton.h"
+#include "inet_ntop.h"
+#include "curl_threads.h"
+#include "connect.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/***********************************************************************
+ * Only for threaded name resolves builds
+ **********************************************************************/
+#ifdef CURLRES_THREADED
+
+/*
+ * Curl_resolver_global_init()
+ * Called from curl_global_init() to initialize global resolver environment.
+ * Does nothing here.
+ */
+int Curl_resolver_global_init(void)
+{
+  return CURLE_OK;
+}
+
+/*
+ * Curl_resolver_global_cleanup()
+ * Called from curl_global_cleanup() to destroy global resolver environment.
+ * Does nothing here.
+ */
+void Curl_resolver_global_cleanup(void)
+{
+}
+
+/*
+ * Curl_resolver_init()
+ * Called from curl_easy_init() -> Curl_open() to initialize resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure).  Does nothing here.
+ */
+CURLcode Curl_resolver_init(void **resolver)
+{
+  (void)resolver;
+  return CURLE_OK;
+}
+
+/*
+ * Curl_resolver_cleanup()
+ * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure).  Does nothing here.
+ */
+void Curl_resolver_cleanup(void *resolver)
+{
+  (void)resolver;
+}
+
+/*
+ * Curl_resolver_duphandle()
+ * Called from curl_easy_duphandle() to duplicate resolver URL state-specific
+ * environment ('resolver' member of the UrlState structure).  Does nothing
+ * here.
+ */
+int Curl_resolver_duphandle(void **to, void *from)
+{
+  (void)to;
+  (void)from;
+  return CURLE_OK;
+}
+
+static void destroy_async_data(struct Curl_async *);
+
+/*
+ * Cancel all possibly still on-going resolves for this connection.
+ */
+void Curl_resolver_cancel(struct connectdata *conn)
+{
+  destroy_async_data(&conn->async);
+}
+
+/* This function is used to init a threaded resolve */
+static bool init_resolve_thread(struct connectdata *conn,
+                                const char *hostname, int port,
+                                const struct addrinfo *hints);
+
+
+/* Data for synchronization between resolver thread and its parent */
+struct thread_sync_data {
+  curl_mutex_t * mtx;
+  int done;
+
+  char * hostname;        /* hostname to resolve, Curl_async.hostname
+                             duplicate */
+  int port;
+  int sock_error;
+  Curl_addrinfo *res;
+#ifdef HAVE_GETADDRINFO
+  struct addrinfo hints;
+#endif
+  struct thread_data *td; /* for thread-self cleanup */
+};
+
+struct thread_data {
+  curl_thread_t thread_hnd;
+  unsigned int poll_interval;
+  long interval_end;
+  struct thread_sync_data tsd;
+};
+
+static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn)
+{
+  return &(((struct thread_data *)conn->async.os_specific)->tsd);
+}
+
+#define CONN_THREAD_SYNC_DATA(conn) &(((conn)->async.os_specific)->tsd);
+
+/* Destroy resolver thread synchronization data */
+static
+void destroy_thread_sync_data(struct thread_sync_data * tsd)
+{
+  if(tsd->mtx) {
+    Curl_mutex_destroy(tsd->mtx);
+    free(tsd->mtx);
+  }
+
+  free(tsd->hostname);
+
+  if(tsd->res)
+    Curl_freeaddrinfo(tsd->res);
+
+  memset(tsd, 0, sizeof(*tsd));
+}
+
+/* Initialize resolver thread synchronization data */
+static
+int init_thread_sync_data(struct thread_data * td,
+                           const char * hostname,
+                           int port,
+                           const struct addrinfo *hints)
+{
+  struct thread_sync_data *tsd = &td->tsd;
+
+  memset(tsd, 0, sizeof(*tsd));
+
+  tsd->td = td;
+  tsd->port = port;
+#ifdef HAVE_GETADDRINFO
+  DEBUGASSERT(hints);
+  tsd->hints = *hints;
+#else
+  (void) hints;
+#endif
+
+  tsd->mtx = malloc(sizeof(curl_mutex_t));
+  if(tsd->mtx == NULL)
+    goto err_exit;
+
+  Curl_mutex_init(tsd->mtx);
+
+  tsd->sock_error = CURL_ASYNC_SUCCESS;
+
+  /* Copying hostname string because original can be destroyed by parent
+   * thread during gethostbyname execution.
+   */
+  tsd->hostname = strdup(hostname);
+  if(!tsd->hostname)
+    goto err_exit;
+
+  return 1;
+
+ err_exit:
+  /* Memory allocation failed */
+  destroy_thread_sync_data(tsd);
+  return 0;
+}
+
+static int getaddrinfo_complete(struct connectdata *conn)
+{
+  struct thread_sync_data *tsd = conn_thread_sync_data(conn);
+  int rc;
+
+  rc = Curl_addrinfo_callback(conn, tsd->sock_error, tsd->res);
+  /* The tsd->res structure has been copied to async.dns and perhaps the DNS
+     cache.  Set our copy to NULL so destroy_thread_sync_data doesn't free it.
+  */
+  tsd->res = NULL;
+
+  return rc;
+}
+
+
+#ifdef HAVE_GETADDRINFO
+
+/*
+ * getaddrinfo_thread() resolves a name and then exits.
+ *
+ * For builds without ARES, but with ENABLE_IPV6, create a resolver thread
+ * and wait on it.
+ */
+static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
+{
+  struct thread_sync_data *tsd = (struct thread_sync_data*)arg;
+  struct thread_data *td = tsd->td;
+  char service[12];
+  int rc;
+
+  snprintf(service, sizeof(service), "%d", tsd->port);
+
+  rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
+
+  if(rc != 0) {
+    tsd->sock_error = SOCKERRNO?SOCKERRNO:rc;
+    if(tsd->sock_error == 0)
+      tsd->sock_error = RESOLVER_ENOMEM;
+  }
+
+  Curl_mutex_acquire(tsd->mtx);
+  if(tsd->done) {
+    /* too late, gotta clean up the mess */
+    Curl_mutex_release(tsd->mtx);
+    destroy_thread_sync_data(tsd);
+    free(td);
+  }
+  else {
+    tsd->done = 1;
+    Curl_mutex_release(tsd->mtx);
+  }
+
+  return 0;
+}
+
+#else /* HAVE_GETADDRINFO */
+
+/*
+ * gethostbyname_thread() resolves a name and then exits.
+ */
+static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
+{
+  struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
+  struct thread_data *td = tsd->td;
+
+  tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port);
+
+  if(!tsd->res) {
+    tsd->sock_error = SOCKERRNO;
+    if(tsd->sock_error == 0)
+      tsd->sock_error = RESOLVER_ENOMEM;
+  }
+
+  Curl_mutex_acquire(tsd->mtx);
+  if(tsd->done) {
+    /* too late, gotta clean up the mess */
+    Curl_mutex_release(tsd->mtx);
+    destroy_thread_sync_data(tsd);
+    free(td);
+  }
+  else {
+    tsd->done = 1;
+    Curl_mutex_release(tsd->mtx);
+  }
+
+  return 0;
+}
+
+#endif /* HAVE_GETADDRINFO */
+
+/*
+ * destroy_async_data() cleans up async resolver data and thread handle.
+ */
+static void destroy_async_data (struct Curl_async *async)
+{
+  if(async->os_specific) {
+    struct thread_data *td = (struct thread_data*) async->os_specific;
+    int done;
+
+    /*
+     * if the thread is still blocking in the resolve syscall, detach it and
+     * let the thread do the cleanup...
+     */
+    Curl_mutex_acquire(td->tsd.mtx);
+    done = td->tsd.done;
+    td->tsd.done = 1;
+    Curl_mutex_release(td->tsd.mtx);
+
+    if(!done) {
+      Curl_thread_destroy(td->thread_hnd);
+    }
+    else {
+      if(td->thread_hnd != curl_thread_t_null)
+        Curl_thread_join(&td->thread_hnd);
+
+      destroy_thread_sync_data(&td->tsd);
+
+      free(async->os_specific);
+    }
+  }
+  async->os_specific = NULL;
+
+  free(async->hostname);
+  async->hostname = NULL;
+}
+
+/*
+ * init_resolve_thread() starts a new thread that performs the actual
+ * resolve. This function returns before the resolve is done.
+ *
+ * Returns FALSE in case of failure, otherwise TRUE.
+ */
+static bool init_resolve_thread (struct connectdata *conn,
+                                 const char *hostname, int port,
+                                 const struct addrinfo *hints)
+{
+  struct thread_data *td = calloc(1, sizeof(struct thread_data));
+  int err = RESOLVER_ENOMEM;
+
+  conn->async.os_specific = (void*) td;
+  if(!td)
+    goto err_exit;
+
+  conn->async.port = port;
+  conn->async.done = FALSE;
+  conn->async.status = 0;
+  conn->async.dns = NULL;
+  td->thread_hnd = curl_thread_t_null;
+
+  if(!init_thread_sync_data(td, hostname, port, hints))
+    goto err_exit;
+
+  free(conn->async.hostname);
+  conn->async.hostname = strdup(hostname);
+  if(!conn->async.hostname)
+    goto err_exit;
+
+#ifdef HAVE_GETADDRINFO
+  td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd);
+#else
+  td->thread_hnd = Curl_thread_create(gethostbyname_thread, &td->tsd);
+#endif
+
+  if(!td->thread_hnd) {
+#ifndef _WIN32_WCE
+    err = errno;
+#endif
+    goto err_exit;
+  }
+
+  return TRUE;
+
+ err_exit:
+  destroy_async_data(&conn->async);
+
+  SET_ERRNO(err);
+
+  return FALSE;
+}
+
+/*
+ * resolver_error() calls failf() with the appropriate message after a resolve
+ * error
+ */
+
+static CURLcode resolver_error(struct connectdata *conn)
+{
+  const char *host_or_proxy;
+  CURLcode result;
+
+  if(conn->bits.httpproxy) {
+    host_or_proxy = "proxy";
+    result = CURLE_COULDNT_RESOLVE_PROXY;
+  }
+  else {
+    host_or_proxy = "host";
+    result = CURLE_COULDNT_RESOLVE_HOST;
+  }
+
+  failf(conn->data, "Could not resolve %s: %s", host_or_proxy,
+        conn->async.hostname);
+
+  return result;
+}
+
+/*
+ * Curl_resolver_wait_resolv()
+ *
+ * waits for a resolve to finish. This function should be avoided since using
+ * this risk getting the multi interface to "hang".
+ *
+ * If 'entry' is non-NULL, make it point to the resolved dns entry
+ *
+ * This is the version for resolves-in-a-thread.
+ */
+CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
+                                   struct Curl_dns_entry **entry)
+{
+  struct thread_data   *td = (struct thread_data*) conn->async.os_specific;
+  CURLcode result = CURLE_OK;
+
+  DEBUGASSERT(conn && td);
+
+  /* wait for the thread to resolve the name */
+  if(Curl_thread_join(&td->thread_hnd))
+    result = getaddrinfo_complete(conn);
+  else
+    DEBUGASSERT(0);
+
+  conn->async.done = TRUE;
+
+  if(entry)
+    *entry = conn->async.dns;
+
+  if(!conn->async.dns)
+    /* a name was not resolved, report error */
+    result = resolver_error(conn);
+
+  destroy_async_data(&conn->async);
+
+  if(!conn->async.dns)
+    connclose(conn, "asynch resolve failed");
+
+  return result;
+}
+
+/*
+ * Curl_resolver_is_resolved() is called repeatedly to check if a previous
+ * name resolve request has completed. It should also make sure to time-out if
+ * the operation seems to take too long.
+ */
+CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
+                                   struct Curl_dns_entry **entry)
+{
+  struct SessionHandle *data = conn->data;
+  struct thread_data   *td = (struct thread_data*) conn->async.os_specific;
+  int done = 0;
+
+  *entry = NULL;
+
+  if(!td) {
+    DEBUGASSERT(td);
+    return CURLE_COULDNT_RESOLVE_HOST;
+  }
+
+  Curl_mutex_acquire(td->tsd.mtx);
+  done = td->tsd.done;
+  Curl_mutex_release(td->tsd.mtx);
+
+  if(done) {
+    getaddrinfo_complete(conn);
+
+    if(!conn->async.dns) {
+      CURLcode result = resolver_error(conn);
+      destroy_async_data(&conn->async);
+      return result;
+    }
+    destroy_async_data(&conn->async);
+    *entry = conn->async.dns;
+  }
+  else {
+    /* poll for name lookup done with exponential backoff up to 250ms */
+    long elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
+    if(elapsed < 0)
+      elapsed = 0;
+
+    if(td->poll_interval == 0)
+      /* Start at 1ms poll interval */
+      td->poll_interval = 1;
+    else if(elapsed >= td->interval_end)
+      /* Back-off exponentially if last interval expired  */
+      td->poll_interval *= 2;
+
+    if(td->poll_interval > 250)
+      td->poll_interval = 250;
+
+    td->interval_end = elapsed + td->poll_interval;
+    Curl_expire(conn->data, td->poll_interval);
+  }
+
+  return CURLE_OK;
+}
+
+int Curl_resolver_getsock(struct connectdata *conn,
+                          curl_socket_t *socks,
+                          int numsocks)
+{
+  (void)conn;
+  (void)socks;
+  (void)numsocks;
+  return 0;
+}
+
+#ifndef HAVE_GETADDRINFO
+/*
+ * Curl_getaddrinfo() - for platforms without getaddrinfo
+ */
+Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+                                         const char *hostname,
+                                         int port,
+                                         int *waitp)
+{
+  struct in_addr in;
+
+  *waitp = 0; /* default to synchronous response */
+
+  if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+    /* This is a dotted IP address 123.123.123.123-style */
+    return Curl_ip2addr(AF_INET, &in, hostname, port);
+
+  /* fire up a new resolver thread! */
+  if(init_resolve_thread(conn, hostname, port, NULL)) {
+    *waitp = 1; /* expect asynchronous response */
+    return NULL;
+  }
+
+  /* fall-back to blocking version */
+  return Curl_ipv4_resolve_r(hostname, port);
+}
+
+#else /* !HAVE_GETADDRINFO */
+
+/*
+ * Curl_resolver_getaddrinfo() - for getaddrinfo
+ */
+Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+                                         const char *hostname,
+                                         int port,
+                                         int *waitp)
+{
+  struct addrinfo hints;
+  struct in_addr in;
+  Curl_addrinfo *res;
+  int error;
+  char sbuf[12];
+  int pf = PF_INET;
+#ifdef CURLRES_IPV6
+  struct in6_addr in6;
+#endif /* CURLRES_IPV6 */
+
+  *waitp = 0; /* default to synchronous response */
+
+  /* First check if this is an IPv4 address string */
+  if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+    /* This is a dotted IP address 123.123.123.123-style */
+    return Curl_ip2addr(AF_INET, &in, hostname, port);
+
+#ifdef CURLRES_IPV6
+  /* check if this is an IPv6 address string */
+  if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0)
+    /* This is an IPv6 address literal */
+    return Curl_ip2addr(AF_INET6, &in6, hostname, port);
+
+  /*
+   * Check if a limited name resolve has been requested.
+   */
+  switch(conn->ip_version) {
+  case CURL_IPRESOLVE_V4:
+    pf = PF_INET;
+    break;
+  case CURL_IPRESOLVE_V6:
+    pf = PF_INET6;
+    break;
+  default:
+    pf = PF_UNSPEC;
+    break;
+  }
+
+  if((pf != PF_INET) && !Curl_ipv6works())
+    /* The stack seems to be a non-IPv6 one */
+    pf = PF_INET;
+
+#endif /* CURLRES_IPV6 */
+
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = pf;
+  hints.ai_socktype = conn->socktype;
+
+  snprintf(sbuf, sizeof(sbuf), "%d", port);
+
+  /* fire up a new resolver thread! */
+  if(init_resolve_thread(conn, hostname, port, &hints)) {
+    *waitp = 1; /* expect asynchronous response */
+    return NULL;
+  }
+
+  /* fall-back to blocking version */
+  infof(conn->data, "init_resolve_thread() failed for %s; %s\n",
+        hostname, Curl_strerror(conn, ERRNO));
+
+  error = Curl_getaddrinfo_ex(hostname, sbuf, &hints, &res);
+  if(error) {
+    infof(conn->data, "getaddrinfo() failed for %s:%d; %s\n",
+          hostname, port, Curl_strerror(conn, SOCKERRNO));
+    return NULL;
+  }
+  return res;
+}
+
+#endif /* !HAVE_GETADDRINFO */
+
+CURLcode Curl_set_dns_servers(struct SessionHandle *data,
+                              char *servers)
+{
+  (void)data;
+  (void)servers;
+  return CURLE_NOT_BUILT_IN;
+
+}
+
+CURLcode Curl_set_dns_interface(struct SessionHandle *data,
+                                const char *interf)
+{
+  (void)data;
+  (void)interf;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
+                                const char *local_ip4)
+{
+  (void)data;
+  (void)local_ip4;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
+                                const char *local_ip6)
+{
+  (void)data;
+  (void)local_ip6;
+  return CURLE_NOT_BUILT_IN;
+}
+
+#endif /* CURLRES_THREADED */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/asyn.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/asyn.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/asyn.h	(revision 164)
@@ -0,0 +1,168 @@
+#ifndef HEADER_CURL_ASYN_H
+#define HEADER_CURL_ASYN_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "curl_addrinfo.h"
+
+struct addrinfo;
+struct hostent;
+struct SessionHandle;
+struct connectdata;
+struct Curl_dns_entry;
+
+/*
+ * This header defines all functions in the internal asynch resolver interface.
+ * All asynch resolvers need to provide these functions.
+ * asyn-ares.c and asyn-thread.c are the current implementations of asynch
+ * resolver backends.
+ */
+
+/*
+ * Curl_resolver_global_init()
+ *
+ * Called from curl_global_init() to initialize global resolver environment.
+ * Returning anything else than CURLE_OK fails curl_global_init().
+ */
+int Curl_resolver_global_init(void);
+
+/*
+ * Curl_resolver_global_cleanup()
+ * Called from curl_global_cleanup() to destroy global resolver environment.
+ */
+void Curl_resolver_global_cleanup(void);
+
+/*
+ * Curl_resolver_init()
+ * Called from curl_easy_init() -> Curl_open() to initialize resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure).  Should fill the passed pointer by the initialized handler.
+ * Returning anything else than CURLE_OK fails curl_easy_init() with the
+ * correspondent code.
+ */
+CURLcode Curl_resolver_init(void **resolver);
+
+/*
+ * Curl_resolver_cleanup()
+ * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure).  Should destroy the handler and free all resources connected to
+ * it.
+ */
+void Curl_resolver_cleanup(void *resolver);
+
+/*
+ * Curl_resolver_duphandle()
+ * Called from curl_easy_duphandle() to duplicate resolver URL-state specific
+ * environment ('resolver' member of the UrlState structure).  Should
+ * duplicate the 'from' handle and pass the resulting handle to the 'to'
+ * pointer.  Returning anything else than CURLE_OK causes failed
+ * curl_easy_duphandle() call.
+ */
+int Curl_resolver_duphandle(void **to, void *from);
+
+/*
+ * Curl_resolver_cancel().
+ *
+ * It is called from inside other functions to cancel currently performing
+ * resolver request. Should also free any temporary resources allocated to
+ * perform a request.
+ */
+void Curl_resolver_cancel(struct connectdata *conn);
+
+/* Curl_resolver_getsock()
+ *
+ * This function is called from the multi_getsock() function.  'sock' is a
+ * pointer to an array to hold the file descriptors, with 'numsock' being the
+ * size of that array (in number of entries). This function is supposed to
+ * return bitmask indicating what file descriptors (referring to array indexes
+ * in the 'sock' array) to wait for, read/write.
+ */
+int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock,
+                          int numsocks);
+
+/*
+ * Curl_resolver_is_resolved()
+ *
+ * Called repeatedly to check if a previous name resolve request has
+ * completed. It should also make sure to time-out if the operation seems to
+ * take too long.
+ *
+ * Returns normal CURLcode errors.
+ */
+CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
+                                   struct Curl_dns_entry **dns);
+
+/*
+ * Curl_resolver_wait_resolv()
+ *
+ * waits for a resolve to finish. This function should be avoided since using
+ * this risk getting the multi interface to "hang".
+ *
+ * If 'entry' is non-NULL, make it point to the resolved dns entry
+ *
+ * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
+ * CURLE_OPERATION_TIMEDOUT if a time-out occurred.
+
+ */
+CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
+                                   struct Curl_dns_entry **dnsentry);
+
+/*
+ * Curl_resolver_getaddrinfo() - when using this resolver
+ *
+ * Returns name information about the given hostname and port number. If
+ * successful, the 'hostent' is returned and the forth argument will point to
+ * memory we need to free after use. That memory *MUST* be freed with
+ * Curl_freeaddrinfo(), nothing else.
+ *
+ * Each resolver backend must of course make sure to return data in the
+ * correct format to comply with this.
+ */
+Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+                                         const char *hostname,
+                                         int port,
+                                         int *waitp);
+
+#ifndef CURLRES_ASYNCH
+/* convert these functions if an asynch resolver isn't used */
+#define Curl_resolver_cancel(x) Curl_nop_stmt
+#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
+#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST
+#define Curl_resolver_getsock(x,y,z) 0
+#define Curl_resolver_duphandle(x,y) CURLE_OK
+#define Curl_resolver_init(x) CURLE_OK
+#define Curl_resolver_global_init() CURLE_OK
+#define Curl_resolver_global_cleanup() Curl_nop_stmt
+#define Curl_resolver_cleanup(x) Curl_nop_stmt
+#endif
+
+#ifdef CURLRES_ASYNCH
+#define Curl_resolver_asynch() 1
+#else
+#define Curl_resolver_asynch() 0
+#endif
+
+
+/********** end of generic resolver interface functions *****************/
+#endif /* HEADER_CURL_ASYN_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/base64.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/base64.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/base64.c	(revision 164)
@@ -0,0 +1,309 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Base64 encoding/decoding */
+
+#include "curl_setup.h"
+#include "curl_printf.h"
+#include "urldata.h" /* for the SessionHandle definition */
+#include "warnless.h"
+#include "curl_base64.h"
+#include "non-ascii.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* ---- Base64 Encoding/Decoding Table --- */
+static const char base64[]=
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/* The Base 64 encoding with an URL and filename safe alphabet, RFC 4648
+   section 5 */
+static const char base64url[]=
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+
+static size_t decodeQuantum(unsigned char *dest, const char *src)
+{
+  size_t padding = 0;
+  const char *s, *p;
+  unsigned long i, x = 0;
+
+  for(i = 0, s = src; i < 4; i++, s++) {
+    unsigned long v = 0;
+
+    if(*s == '=') {
+      x = (x << 6);
+      padding++;
+    }
+    else {
+      p = base64;
+
+      while(*p && (*p != *s)) {
+        v++;
+        p++;
+      }
+
+      if(*p == *s)
+        x = (x << 6) + v;
+      else
+        return 0;
+    }
+  }
+
+  if(padding < 1)
+    dest[2] = curlx_ultouc(x & 0xFFUL);
+
+  x >>= 8;
+  if(padding < 2)
+    dest[1] = curlx_ultouc(x & 0xFFUL);
+
+  x >>= 8;
+  dest[0] = curlx_ultouc(x & 0xFFUL);
+
+  return 3 - padding;
+}
+
+/*
+ * Curl_base64_decode()
+ *
+ * Given a base64 NUL-terminated string at src, decode it and return a
+ * pointer in *outptr to a newly allocated memory area holding decoded
+ * data. Size of decoded data is returned in variable pointed by outlen.
+ *
+ * Returns CURLE_OK on success, otherwise specific error code. Function
+ * output shall not be considered valid unless CURLE_OK is returned.
+ *
+ * When decoded data length is 0, returns NULL in *outptr.
+ *
+ * @unittest: 1302
+ */
+CURLcode Curl_base64_decode(const char *src,
+                            unsigned char **outptr, size_t *outlen)
+{
+  size_t srclen = 0;
+  size_t length = 0;
+  size_t padding = 0;
+  size_t i;
+  size_t numQuantums;
+  size_t rawlen = 0;
+  unsigned char *pos;
+  unsigned char *newstr;
+
+  *outptr = NULL;
+  *outlen = 0;
+  srclen = strlen(src);
+
+  /* Check the length of the input string is valid */
+  if(!srclen || srclen % 4)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* Find the position of any = padding characters */
+  while((src[length] != '=') && src[length])
+    length++;
+
+  /* A maximum of two = padding characters is allowed */
+  if(src[length] == '=') {
+    padding++;
+    if(src[length + 1] == '=')
+      padding++;
+  }
+
+  /* Check the = padding characters weren't part way through the input */
+  if(length + padding != srclen)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* Calculate the number of quantums */
+  numQuantums = srclen / 4;
+
+  /* Calculate the size of the decoded string */
+  rawlen = (numQuantums * 3) - padding;
+
+  /* Allocate our buffer including room for a zero terminator */
+  newstr = malloc(rawlen + 1);
+  if(!newstr)
+    return CURLE_OUT_OF_MEMORY;
+
+  pos = newstr;
+
+  /* Decode the quantums */
+  for(i = 0; i < numQuantums; i++) {
+    size_t result = decodeQuantum(pos, src);
+    if(!result) {
+      free(newstr);
+
+      return CURLE_BAD_CONTENT_ENCODING;
+    }
+
+    pos += result;
+    src += 4;
+  }
+
+  /* Zero terminate */
+  *pos = '\0';
+
+  /* Return the decoded data */
+  *outptr = newstr;
+  *outlen = rawlen;
+
+  return CURLE_OK;
+}
+
+static CURLcode base64_encode(const char *table64,
+                              struct SessionHandle *data,
+                              const char *inputbuff, size_t insize,
+                              char **outptr, size_t *outlen)
+{
+  CURLcode error;
+  unsigned char ibuf[3];
+  unsigned char obuf[4];
+  int i;
+  int inputparts;
+  char *output;
+  char *base64data;
+  char *convbuf = NULL;
+
+  const char *indata = inputbuff;
+
+  *outptr = NULL;
+  *outlen = 0;
+
+  if(0 == insize)
+    insize = strlen(indata);
+
+  base64data = output = malloc(insize*4/3+4);
+  if(NULL == output)
+    return CURLE_OUT_OF_MEMORY;
+
+  /*
+   * The base64 data needs to be created using the network encoding
+   * not the host encoding.  And we can't change the actual input
+   * so we copy it to a buffer, translate it, and use that instead.
+   */
+  error = Curl_convert_clone(data, indata, insize, &convbuf);
+  if(error) {
+    free(output);
+    return error;
+  }
+
+  if(convbuf)
+    indata = (char *)convbuf;
+
+  while(insize > 0) {
+    for(i = inputparts = 0; i < 3; i++) {
+      if(insize > 0) {
+        inputparts++;
+        ibuf[i] = (unsigned char) *indata;
+        indata++;
+        insize--;
+      }
+      else
+        ibuf[i] = 0;
+    }
+
+    obuf[0] = (unsigned char)  ((ibuf[0] & 0xFC) >> 2);
+    obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \
+                               ((ibuf[1] & 0xF0) >> 4));
+    obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \
+                               ((ibuf[2] & 0xC0) >> 6));
+    obuf[3] = (unsigned char)   (ibuf[2] & 0x3F);
+
+    switch(inputparts) {
+    case 1: /* only one byte read */
+      snprintf(output, 5, "%c%c==",
+               table64[obuf[0]],
+               table64[obuf[1]]);
+      break;
+    case 2: /* two bytes read */
+      snprintf(output, 5, "%c%c%c=",
+               table64[obuf[0]],
+               table64[obuf[1]],
+               table64[obuf[2]]);
+      break;
+    default:
+      snprintf(output, 5, "%c%c%c%c",
+               table64[obuf[0]],
+               table64[obuf[1]],
+               table64[obuf[2]],
+               table64[obuf[3]] );
+      break;
+    }
+    output += 4;
+  }
+  *output = '\0';
+  *outptr = base64data; /* return pointer to new data, allocated memory */
+
+  free(convbuf);
+
+  *outlen = strlen(base64data); /* return the length of the new data */
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_base64_encode()
+ *
+ * Given a pointer to an input buffer and an input size, encode it and
+ * return a pointer in *outptr to a newly allocated memory area holding
+ * encoded data. Size of encoded data is returned in variable pointed by
+ * outlen.
+ *
+ * Input length of 0 indicates input buffer holds a NUL-terminated string.
+ *
+ * Returns CURLE_OK on success, otherwise specific error code. Function
+ * output shall not be considered valid unless CURLE_OK is returned.
+ *
+ * When encoded data length is 0, returns NULL in *outptr.
+ *
+ * @unittest: 1302
+ */
+CURLcode Curl_base64_encode(struct SessionHandle *data,
+                            const char *inputbuff, size_t insize,
+                            char **outptr, size_t *outlen)
+{
+  return base64_encode(base64, data, inputbuff, insize, outptr, outlen);
+}
+
+/*
+ * Curl_base64url_encode()
+ *
+ * Given a pointer to an input buffer and an input size, encode it and
+ * return a pointer in *outptr to a newly allocated memory area holding
+ * encoded data. Size of encoded data is returned in variable pointed by
+ * outlen.
+ *
+ * Input length of 0 indicates input buffer holds a NUL-terminated string.
+ *
+ * Returns CURLE_OK on success, otherwise specific error code. Function
+ * output shall not be considered valid unless CURLE_OK is returned.
+ *
+ * When encoded data length is 0, returns NULL in *outptr.
+ *
+ * @unittest: 1302
+ */
+CURLcode Curl_base64url_encode(struct SessionHandle *data,
+                               const char *inputbuff, size_t insize,
+                               char **outptr, size_t *outlen)
+{
+  return base64_encode(base64url, data, inputbuff, insize, outptr, outlen);
+}
+/* ---- End of Base64 Encoding ---- */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/config-amigaos.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/config-amigaos.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/config-amigaos.h	(revision 164)
@@ -0,0 +1,166 @@
+#ifndef HEADER_CURL_CONFIG_AMIGAOS_H
+#define HEADER_CURL_CONFIG_AMIGAOS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/*               Hand crafted config file for AmigaOS               */
+/* ================================================================ */
+
+#ifdef __AMIGA__ /* Any AmigaOS flavour */
+
+#define HAVE_ARPA_INET_H 1
+#define HAVE_CLOSESOCKET_CAMEL 1
+#define HAVE_ERRNO_H 1
+#define HAVE_GETHOSTBYADDR 1
+#define HAVE_INET_ADDR 1
+#define HAVE_INTTYPES_H 1
+#define HAVE_IOCTLSOCKET_CAMEL 1
+#define HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1
+#define HAVE_LIBCRYPTO 1
+#define HAVE_LIBSSL 1
+#define HAVE_LIBZ 1
+#define HAVE_LONGLONG 1
+#define HAVE_MALLOC_H 1
+#define HAVE_MEMORY_H 1
+#define HAVE_NETDB_H 1
+#define HAVE_NETINET_IN_H 1
+#define HAVE_NET_IF_H 1
+#define HAVE_OPENSSL_CRYPTO_H 1
+#define HAVE_OPENSSL_ERR_H 1
+#define HAVE_OPENSSL_PEM_H 1
+#define HAVE_OPENSSL_RSA_H 1
+#define HAVE_OPENSSL_SSL_H 1
+#define HAVE_OPENSSL_X509_H 1
+#define HAVE_PERROR 1
+#define HAVE_PWD_H 1
+#define HAVE_RAND_EGD 1
+#define HAVE_RAND_STATUS 1
+#define HAVE_SELECT 1
+#define HAVE_SETJMP_H 1
+#define HAVE_SGTTY_H 1
+#define HAVE_SIGNAL 1
+#define HAVE_SIGNAL_H 1
+#define HAVE_SIG_ATOMIC_T 1
+#define HAVE_SOCKET 1
+#define HAVE_STRCASECMP 1
+#define HAVE_STRDUP 1
+#define HAVE_STRFTIME 1
+#define HAVE_STRICMP 1
+#define HAVE_STRINGS_H 1
+#define HAVE_STRING_H 1
+#define HAVE_STRSTR 1
+#define HAVE_STRUCT_TIMEVAL 1
+#define HAVE_SYS_PARAM_H 1
+#define HAVE_SYS_SOCKET_H 1
+#define HAVE_SYS_SOCKIO_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_TIME_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_TIME_H 1
+#define HAVE_UNAME 1
+#define HAVE_UNISTD_H 1
+#define HAVE_UTIME 1
+#define HAVE_UTIME_H 1
+#define HAVE_WRITABLE_ARGV 1
+#define HAVE_ZLIB_H 1
+#define HAVE_SYS_IOCTL_H 1
+
+#define NEED_MALLOC_H 1
+
+#define SIZEOF_INT 4
+#define SIZEOF_SHORT 2
+#define SIZEOF_SIZE_T 4
+
+#define USE_MANUAL 1
+#define USE_OPENSSL 1
+#define CURL_DISABLE_LDAP 1
+
+#define OS "AmigaOS"
+
+#define PACKAGE "curl"
+#define PACKAGE_BUGREPORT "curl-bug@haxx.se"
+#define PACKAGE_NAME "curl"
+#define PACKAGE_STRING "curl -"
+#define PACKAGE_TARNAME "curl"
+#define PACKAGE_VERSION "-"
+#define CURL_CA_BUNDLE "s:curl-ca-bundle.crt"
+
+#define RETSIGTYPE void
+#define SELECT_TYPE_ARG1 int
+#define SELECT_TYPE_ARG234 (fd_set *)
+#define SELECT_TYPE_ARG5 (struct timeval *)
+
+#define STDC_HEADERS 1
+#define TIME_WITH_SYS_TIME 1
+
+#define in_addr_t int
+
+#ifndef F_OK
+#  define F_OK 0
+#endif
+
+#ifndef O_RDONLY
+#  define O_RDONLY 0x0000
+#endif
+
+#ifndef LONG_MAX
+#  define LONG_MAX 0x7fffffffL
+#endif
+
+#ifndef LONG_MIN
+#  define LONG_MIN (-0x7fffffffL-1)
+#endif
+
+#define HAVE_GETNAMEINFO 1
+#define GETNAMEINFO_QUAL_ARG1 const
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+#define GETNAMEINFO_TYPE_ARG2 int
+#define GETNAMEINFO_TYPE_ARG46 size_t
+#define GETNAMEINFO_TYPE_ARG7 int
+
+#define HAVE_RECV 1
+#define RECV_TYPE_ARG1 long
+#define RECV_TYPE_ARG2 char *
+#define RECV_TYPE_ARG3 long
+#define RECV_TYPE_ARG4 long
+#define RECV_TYPE_RETV long
+
+#define HAVE_RECVFROM 1
+#define RECVFROM_TYPE_ARG1 long
+#define RECVFROM_TYPE_ARG2 char
+#define RECVFROM_TYPE_ARG3 long
+#define RECVFROM_TYPE_ARG4 long
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+#define RECVFROM_TYPE_ARG6 long
+#define RECVFROM_TYPE_RETV long
+
+#define HAVE_SEND 1
+#define SEND_TYPE_ARG1 int
+#define SEND_QUAL_ARG2 const
+#define SEND_TYPE_ARG2 char *
+#define SEND_TYPE_ARG3 int
+#define SEND_TYPE_ARG4 int
+#define SEND_TYPE_RETV int
+
+#endif /* __AMIGA__ */
+#endif /* HEADER_CURL_CONFIG_AMIGAOS_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/config-dos.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/config-dos.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/config-dos.h	(revision 164)
@@ -0,0 +1,181 @@
+#ifndef HEADER_CURL_CONFIG_DOS_H
+#define HEADER_CURL_CONFIG_DOS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+
+/* ================================================================ */
+/*       lib/config-dos.h - Hand crafted config file for DOS        */
+/* ================================================================ */
+
+#if defined(DJGPP)
+  #define OS  "MSDOS/djgpp"
+#elif defined(__HIGHC__)
+  #define OS  "MSDOS/HighC"
+#elif defined(__WATCOMC__)
+  #define OS  "MSDOS/Watcom"
+#else
+  #define OS  "MSDOS/?"
+#endif
+
+#define PACKAGE  "curl"
+
+#define HAVE_ARPA_INET_H       1
+#define HAVE_ERRNO_H           1
+#define HAVE_FCNTL_H           1
+#define HAVE_GETADDRINFO       1
+#define HAVE_GETNAMEINFO       1
+#define HAVE_GETPROTOBYNAME    1
+#define HAVE_GETTIMEOFDAY      1
+#define HAVE_IO_H              1
+#define HAVE_IOCTL             1
+#define HAVE_IOCTL_FIONBIO     1
+#define HAVE_IOCTLSOCKET       1
+#define HAVE_IOCTLSOCKET_FIONBIO   1
+#define HAVE_LIMITS_H          1
+#define HAVE_LOCALE_H          1
+#define HAVE_LONGLONG          1
+#define HAVE_MEMORY_H          1
+#define HAVE_NETDB_H           1
+#define HAVE_NETINET_IN_H      1
+#define HAVE_NETINET_TCP_H     1
+#define HAVE_NET_IF_H          1
+#define HAVE_PROCESS_H         1
+#define HAVE_RECV              1
+#define HAVE_RECVFROM          1
+#define HAVE_SELECT            1
+#define HAVE_SEND              1
+#define HAVE_SETJMP_H          1
+#define HAVE_SETLOCALE         1
+#define HAVE_SETMODE           1
+#define HAVE_SIGNAL            1
+#define HAVE_SOCKET            1
+#define HAVE_STRDUP            1
+#define HAVE_STRICMP           1
+#define HAVE_STRTOLL           1
+#define HAVE_STRUCT_TIMEVAL    1
+#define HAVE_STRUCT_IN6_ADDR   1
+#define HAVE_SYS_IOCTL_H       1
+#define HAVE_SYS_SOCKET_H      1
+#define HAVE_SYS_STAT_H        1
+#define HAVE_SYS_TYPES_H       1
+#define HAVE_TIME_H            1
+#define HAVE_UNISTD_H          1
+
+#define NEED_MALLOC_H          1
+
+#define RETSIGTYPE             void
+#define SIZEOF_INT             4
+#define SIZEOF_LONG_DOUBLE     16
+#define SIZEOF_SHORT           2
+#define SIZEOF_SIZE_T          4
+#define STDC_HEADERS           1
+#define TIME_WITH_SYS_TIME     1
+
+/* Qualifiers for send(), recv(), recvfrom() and getnameinfo(). */
+
+#define SEND_TYPE_ARG1         int
+#define SEND_QUAL_ARG2         const
+#define SEND_TYPE_ARG2         void *
+#define SEND_TYPE_ARG3         int
+#define SEND_TYPE_ARG4         int
+#define SEND_TYPE_RETV         int
+
+#define RECV_TYPE_ARG1         int
+#define RECV_TYPE_ARG2         void *
+#define RECV_TYPE_ARG3         int
+#define RECV_TYPE_ARG4         int
+#define RECV_TYPE_RETV         int
+
+#define RECVFROM_TYPE_ARG1     int
+#define RECVFROM_TYPE_ARG2     void
+#define RECVFROM_TYPE_ARG3     int
+#define RECVFROM_TYPE_ARG4     int
+#define RECVFROM_TYPE_ARG5     struct sockaddr
+#define RECVFROM_TYPE_ARG6     int
+#define RECVFROM_TYPE_RETV     int
+#define RECVFROM_TYPE_ARG2_IS_VOID 1
+
+#define GETNAMEINFO_QUAL_ARG1  const
+#define GETNAMEINFO_TYPE_ARG1  struct sockaddr *
+#define GETNAMEINFO_TYPE_ARG2  int
+#define GETNAMEINFO_TYPE_ARG46 int
+#define GETNAMEINFO_TYPE_ARG7  int
+
+#define BSD
+
+/* CURLDEBUG definition enables memory tracking */
+/* #define CURLDEBUG */
+
+/* USE_ZLIB on cmd-line */
+#ifdef USE_ZLIB
+  #define HAVE_ZLIB_H            1
+  #define HAVE_LIBZ              1
+#endif
+
+/* USE_OPENSSL on cmd-line */
+#ifdef USE_OPENSSL
+  #define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
+  #define HAVE_OPENSSL_ENGINE_H  1
+  #define OPENSSL_NO_KRB5        1
+#endif
+
+/* to disable LDAP */
+#define CURL_DISABLE_LDAP        1
+
+#define in_addr_t  u_long
+
+#if defined(__HIGHC__) || \
+    (defined(__GNUC__) && (__GNUC__ < 4))
+  #define ssize_t  int
+#endif
+
+#define CURL_CA_BUNDLE  getenv("CURL_CA_BUNDLE")
+
+/* Target HAVE_x section */
+
+#if defined(DJGPP)
+  #define HAVE_BASENAME   1
+  #define HAVE_STRCASECMP 1
+  #define HAVE_SIGACTION  1
+  #define HAVE_SIGSETJMP  1
+  #define HAVE_SYS_TIME_H 1
+  #define HAVE_TERMIOS_H  1
+  #define HAVE_VARIADIC_MACROS_GCC 1
+
+#elif defined(__WATCOMC__)
+  #define HAVE_STRCASECMP 1
+
+#elif defined(__HIGHC__)
+  #define HAVE_SYS_TIME_H 1
+  #define strerror(e) strerror_s_((e))
+#endif
+
+#ifdef MSDOS  /* Watt-32 */
+  #define HAVE_CLOSE_S    1
+#endif
+
+#undef word
+#undef byte
+
+#endif /* HEADER_CURL_CONFIG_DOS_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/config-mac.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/config-mac.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/config-mac.h	(revision 164)
@@ -0,0 +1,125 @@
+#ifndef HEADER_CURL_CONFIG_MAC_H
+#define HEADER_CURL_CONFIG_MAC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* =================================================================== */
+/*                Hand crafted config file for Mac OS 9                */
+/* =================================================================== */
+/*  On Mac OS X you must run configure to generate curl_config.h file  */
+/* =================================================================== */
+
+#define OS "mac"
+
+/* Define if you want the built-in manual */
+#define USE_MANUAL              1
+
+#define HAVE_ERRNO_H            1
+#define HAVE_NETINET_IN_H       1
+#define HAVE_SYS_SOCKET_H       1
+#define HAVE_SYS_SELECT_H       1
+#define HAVE_NETDB_H            1
+#define HAVE_ARPA_INET_H        1
+#define HAVE_UNISTD_H           1
+#define HAVE_NET_IF_H           1
+#define HAVE_SYS_TYPES_H        1
+#define HAVE_GETTIMEOFDAY       1
+#define HAVE_FCNTL_H            1
+#define HAVE_SYS_STAT_H         1
+#define HAVE_ALLOCA_H           1
+#define HAVE_STDLIB_H           1
+#define HAVE_TIME_H             1
+#define HAVE_UTIME_H            1
+#define HAVE_SYS_TIME_H         1
+#define HAVE_SYS_UTIME_H        1
+
+#define TIME_WITH_SYS_TIME      1
+
+#define HAVE_ALARM              1
+#define HAVE_FTRUNCATE          1
+#define HAVE_UTIME              1
+#define HAVE_SETVBUF            1
+#define HAVE_STRFTIME           1
+#define HAVE_INET_ADDR          1
+#define HAVE_MEMCPY             1
+#define HAVE_SELECT             1
+#define HAVE_SOCKET             1
+#define HAVE_STRUCT_TIMEVAL     1
+
+#define HAVE_SIGACTION          1
+#define HAVE_SIGNAL_H           1
+#define HAVE_SIG_ATOMIC_T       1
+
+#ifdef MACOS_SSL_SUPPORT
+#  define USE_OPENSSL           1
+#endif
+
+#define CURL_DISABLE_LDAP       1
+
+#define HAVE_RAND_STATUS        1
+#define HAVE_RAND_EGD           1
+
+#define HAVE_IOCTL              1
+#define HAVE_IOCTL_FIONBIO      1
+
+#define RETSIGTYPE void
+
+#define SIZEOF_INT              4
+#define SIZEOF_SHORT            2
+#define SIZEOF_SIZE_T           4
+
+#define HAVE_GETNAMEINFO 1
+#define GETNAMEINFO_QUAL_ARG1 const
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+#define GETNAMEINFO_TYPE_ARG46 size_t
+#define GETNAMEINFO_TYPE_ARG7 int
+
+#define HAVE_RECV 1
+#define RECV_TYPE_ARG1 int
+#define RECV_TYPE_ARG2 void *
+#define RECV_TYPE_ARG3 size_t
+#define RECV_TYPE_ARG4 int
+#define RECV_TYPE_RETV ssize_t
+
+#define HAVE_RECVFROM 1
+#define RECVFROM_TYPE_ARG1 int
+#define RECVFROM_TYPE_ARG2 void
+#define RECVFROM_TYPE_ARG3 size_t
+#define RECVFROM_TYPE_ARG4 int
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+#define RECVFROM_TYPE_ARG6 int
+#define RECVFROM_TYPE_RETV ssize_t
+#define RECVFROM_TYPE_ARG2_IS_VOID 1
+
+#define HAVE_SEND 1
+#define SEND_TYPE_ARG1 int
+#define SEND_QUAL_ARG2 const
+#define SEND_TYPE_ARG2 void *
+#define SEND_TYPE_ARG3 size_T
+#define SEND_TYPE_ARG4 int
+#define SEND_TYPE_RETV ssize_t
+
+#define HAVE_EXTRA_STRICMP_H 1
+#define HAVE_EXTRA_STRDUP_H  1
+
+#endif /* HEADER_CURL_CONFIG_MAC_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/config-os400.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/config-os400.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/config-os400.h	(revision 164)
@@ -0,0 +1,563 @@
+#ifndef HEADER_CURL_CONFIG_OS400_H
+#define HEADER_CURL_CONFIG_OS400_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/*                Hand crafted config file for OS/400               */
+/* ================================================================ */
+
+#pragma enum(int)
+
+#undef PACKAGE
+
+/* Version number of this archive. */
+#undef VERSION
+
+/* Define if you have the getpass function.  */
+#undef HAVE_GETPASS
+
+/* Define cpu-machine-OS */
+#define OS "OS/400"
+
+/* Define if you have the gethostbyaddr_r() function with 5 arguments */
+#define HAVE_GETHOSTBYADDR_R_5
+
+/* Define if you have the gethostbyaddr_r() function with 7 arguments */
+#undef HAVE_GETHOSTBYADDR_R_7
+
+/* Define if you have the gethostbyaddr_r() function with 8 arguments */
+#undef HAVE_GETHOSTBYADDR_R_8
+
+/* OS400 supports a 3-argument ASCII version of gethostbyaddr_r(), but its
+ *  prototype is incompatible with the "standard" one (1st argument is not
+ *  const). However, getaddrinfo() is supported (ASCII version defined as
+ *  a local wrapper in setup-os400.h) in a threadsafe way: we can then
+ *  configure getaddrinfo() as such and get rid of gethostbyname_r() without
+ *  loss of threadsafeness. */
+#undef HAVE_GETHOSTBYNAME_R
+#undef HAVE_GETHOSTBYNAME_R_3
+#undef HAVE_GETHOSTBYNAME_R_5
+#undef HAVE_GETHOSTBYNAME_R_6
+#define HAVE_GETADDRINFO
+#define HAVE_GETADDRINFO_THREADSAFE
+
+/* Define if you need the _REENTRANT define for some functions */
+#undef NEED_REENTRANT
+
+/* Define if you have the Kerberos4 libraries (including -ldes) */
+#undef HAVE_KRB4
+
+/* Define if you want to enable IPv6 support */
+#define ENABLE_IPV6
+
+/* Define if struct sockaddr_in6 has the sin6_scope_id member */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define this to 'int' if ssize_t is not an available typedefed type */
+#undef ssize_t
+
+/* Define this as a suitable file to read random data from */
+#undef RANDOM_FILE
+
+/* Define this to your Entropy Gathering Daemon socket pathname */
+#undef EGD_SOCKET
+
+/* Define to 1 if you have the alarm function. */
+#define HAVE_ALARM 1
+
+/* Define if you have the <alloca.h> header file. */
+#undef HAVE_ALLOCA_H
+
+/* Define if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H
+
+/* Define if you have the `closesocket' function. */
+#undef HAVE_CLOSESOCKET
+
+/* Define if you have the <crypto.h> header file. */
+#undef HAVE_CRYPTO_H
+
+/* Define if you have the <des.h> header file. */
+#undef HAVE_DES_H
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H
+
+/* Define if you have the <err.h> header file. */
+#undef HAVE_ERR_H
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H
+
+/* Define if you have the `geteuid' function. */
+#define HAVE_GETEUID
+
+/* Define if you have the `gethostbyaddr' function. */
+#define HAVE_GETHOSTBYADDR
+
+/* Define if you have the `gethostbyaddr_r' function. */
+#define HAVE_GETHOSTBYADDR_R
+
+/* Define if you have the `gethostname' function. */
+#define HAVE_GETHOSTNAME
+
+/* Define if you have the <getopt.h> header file. */
+#undef HAVE_GETOPT_H
+
+/* Define if you have the `getpass_r' function. */
+#undef HAVE_GETPASS_R
+
+/* Define if you have the `getpwuid' function. */
+#define HAVE_GETPWUID
+
+/* Define if you have the `getservbyname' function. */
+#define HAVE_GETSERVBYNAME
+
+/* Define if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY
+
+/* Define if you have the `timeval' struct. */
+#define HAVE_STRUCT_TIMEVAL
+
+/* Define if you have the `inet_addr' function. */
+#define HAVE_INET_ADDR
+
+/* Define if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H
+
+/* Define if you have the <io.h> header file. */
+#undef HAVE_IO_H
+
+/* Define if you have the `krb_get_our_ip_for_realm' function. */
+#undef HAVE_KRB_GET_OUR_IP_FOR_REALM
+
+/* Define if you have the <krb.h> header file. */
+#undef HAVE_KRB_H
+
+/* Define if you have the `crypto' library (-lcrypto). */
+#undef HAVE_LIBCRYPTO
+
+/* Define if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define if you have the `resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define if you have the `resolve' library (-lresolve). */
+#undef HAVE_LIBRESOLVE
+
+/* Define if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define if you have the `ssl' library (-lssl). */
+#undef HAVE_LIBSSL
+
+/* Define if you have GSS API. */
+#define HAVE_GSSAPI
+
+/* Define if you have the GNU gssapi libraries */
+#undef HAVE_GSSGNU
+
+/* Define if you have the Heimdal gssapi libraries */
+#define HAVE_GSSHEIMDAL
+
+/* Define if you have the MIT gssapi libraries */
+#undef HAVE_GSSMIT
+
+/* Define if you have the `ucb' library (-lucb). */
+#undef HAVE_LIBUCB
+
+/* Define if you have the `localtime_r' function. */
+#define HAVE_LOCALTIME_R
+
+/* Define if you have the <malloc.h> header file. */
+#define HAVE_MALLOC_H
+
+/* Define if you need the malloc.h header file even with stdlib.h  */
+/* #define NEED_MALLOC_H 1 */
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H
+
+/* Define if you have the <netinet/if_ether.h> header file. */
+#undef HAVE_NETINET_IF_ETHER_H
+
+/* Define if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H
+
+/* Define if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H
+
+/* Define if you have the <openssl/crypto.h> header file. */
+#undef HAVE_OPENSSL_CRYPTO_H
+
+/* Define if you have the <openssl/err.h> header file. */
+#undef HAVE_OPENSSL_ERR_H
+
+/* Define if you have the <openssl/pem.h> header file. */
+#undef HAVE_OPENSSL_PEM_H
+
+/* Define if you have the <openssl/rsa.h> header file. */
+#undef HAVE_OPENSSL_RSA_H
+
+/* Define if you have the <openssl/ssl.h> header file. */
+#undef HAVE_OPENSSL_SSL_H
+
+/* Define if you have the <openssl/x509.h> header file. */
+#undef HAVE_OPENSSL_X509_H
+
+/* Define if you have the <pem.h> header file. */
+#undef HAVE_PEM_H
+
+/* Define if you have the `perror' function. */
+#define HAVE_PERROR
+
+/* Define if you have the <pwd.h> header file. */
+#define HAVE_PWD_H
+
+/* Define if you have the `RAND_egd' function. */
+#undef HAVE_RAND_EGD
+
+/* Define if you have the `RAND_screen' function. */
+#undef HAVE_RAND_SCREEN
+
+/* Define if you have the `RAND_status' function. */
+#undef HAVE_RAND_STATUS
+
+/* Define if you have the <rsa.h> header file. */
+#undef HAVE_RSA_H
+
+/* Define if you have the `select' function. */
+#define HAVE_SELECT
+
+/* Define if you have the `setvbuf' function. */
+#define HAVE_SETVBUF
+
+/* Define if you have the <sgtty.h> header file. */
+#undef HAVE_SGTTY_H
+
+/* Define if you have the `sigaction' function. */
+#define HAVE_SIGACTION
+
+/* Define if you have the `signal' function. */
+#undef HAVE_SIGNAL
+
+/* Define if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H
+
+/* Define if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T
+
+/* Define if sig_atomic_t is already defined as volatile. */
+#undef HAVE_SIG_ATOMIC_T_VOLATILE
+
+/* Define if you have the `socket' function. */
+#define HAVE_SOCKET
+
+/* Define if you have the <ssl.h> header file. */
+#undef HAVE_SSL_H
+
+/* Define if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H
+
+
+/* The following define is needed on OS400 to enable strcmpi(), stricmp() and
+   strdup(). */
+#define __cplusplus__strings__
+
+/* Define if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the `strcmpi' function. */
+#define HAVE_STRCMPI
+
+/* Define if you have the `stricmp' function. */
+#define HAVE_STRICMP
+
+/* Define if you have the `strdup' function. */
+#define HAVE_STRDUP
+
+
+/* Define if you have the `strftime' function. */
+#define HAVE_STRFTIME
+
+/* Define if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H
+
+/* Define if you have the `strlcpy' function. */
+#undef HAVE_STRLCPY
+
+/* Define if you have the <stropts.h> header file. */
+#undef HAVE_STROPTS_H
+
+/* Define if you have the `strstr' function. */
+#define HAVE_STRSTR
+
+/* Define if you have the `strtok_r' function. */
+#define HAVE_STRTOK_R
+
+/* Define if you have the `strtoll' function. */
+#undef HAVE_STRTOLL             /* Allows ASCII compile on V5R1. */
+
+/* Define if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H
+
+/* Define if you have the <sys/sockio.h> header file. */
+#undef HAVE_SYS_SOCKIO_H
+
+/* Define if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H
+
+/* Define if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H
+
+/* Define if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H
+
+/* Define if you have the <sys/un.h> header file. */
+#define HAVE_SYS_UN_H
+
+/* Define if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H
+
+/* Define if you have the `tcgetattr' function. */
+#undef HAVE_TCGETATTR
+
+/* Define if you have the `tcsetattr' function. */
+#undef HAVE_TCSETATTR
+
+/* Define if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define if you have the <termio.h> header file. */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the <time.h> header file. */
+#define HAVE_TIME_H
+
+/* Define if you have the `uname' function. */
+#undef HAVE_UNAME
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H
+
+/* Define if you have the <winsock.h> header file. */
+#undef HAVE_WINSOCK_H
+
+/* Define if you have the <x509.h> header file. */
+#undef HAVE_X509_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT              4
+
+/* The size of a `long double', as computed by sizeof. */
+#define SIZEOF_LONG_DOUBLE      8
+
+/* Define if the compiler supports the 'long long' data type. */
+#define HAVE_LONGLONG
+
+/* The size of a `long long', as computed by sizeof. */
+#define SIZEOF_LONG_LONG        8
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT            2
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T           8
+
+/* Whether long long constants must be suffixed by LL. */
+
+#define HAVE_LL
+
+/* Define this if you have struct sockaddr_storage */
+#define HAVE_STRUCT_SOCKADDR_STORAGE
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#define _LARGE_FILES
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* type to use in place of in_addr_t if not defined */
+#define in_addr_t       unsigned long
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define if you have the ioctl function. */
+#define HAVE_IOCTL
+
+/* Define if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO
+
+/* Define if you have a working ioctl SIOCGIFADDR function. */
+#define HAVE_IOCTL_SIOCGIFADDR
+
+/* To disable LDAP */
+#undef CURL_DISABLE_LDAP
+
+/* Definition to make a library symbol externally visible. */
+#define CURL_EXTERN_SYMBOL
+
+/* Define if you have the ldap_url_parse procedure. */
+/* #define HAVE_LDAP_URL_PARSE */    /* Disabled because of an IBM bug. */
+
+/* Define if you have the getnameinfo function. */
+/* OS400 has no ASCII version of this procedure: wrapped in setup-os400.h. */
+#define HAVE_GETNAMEINFO
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 socklen_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 int
+
+/* Define if you have the recv function. */
+#define HAVE_RECV
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV int
+
+/* Define if you have the recvfrom function. */
+#define HAVE_RECVFROM
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 char
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 int
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV int
+
+/* Define if you have the send function. */
+#define HAVE_SEND
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV int
+
+/* Define to use the GSKit package. */
+#define USE_GSKIT
+
+/* Define to use the OS/400 crypto library. */
+#define USE_OS400CRYPTO
+
+/* Define to use Unix sockets. */
+#define USE_UNIX_SOCKETS
+
+/* Use the system keyring as the default CA bundle. */
+#define CURL_CA_BUNDLE  "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB"
+
+/* ---------------------------------------------------------------- */
+/*                       ADDITIONAL DEFINITIONS                     */
+/* ---------------------------------------------------------------- */
+
+/* The following must be defined BEFORE system header files inclusion. */
+
+#define __ptr128                       /* No teraspace. */
+#define qadrt_use_fputc_inline         /* Generate fputc() wrapper inline. */
+#define qadrt_use_fread_inline         /* Generate fread() wrapper inline. */
+#define qadrt_use_fwrite_inline        /* Generate fwrite() wrapper inline. */
+
+#endif /* HEADER_CURL_CONFIG_OS400_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/config-riscos.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/config-riscos.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/config-riscos.h	(revision 164)
@@ -0,0 +1,513 @@
+#ifndef HEADER_CURL_CONFIG_RISCOS_H
+#define HEADER_CURL_CONFIG_RISCOS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/*               Hand crafted config file for RISC OS               */
+/* ================================================================ */
+
+/* Name of this package! */
+#undef PACKAGE
+
+/* Version number of this archive. */
+#undef VERSION
+
+/* Define if you have the getpass function.  */
+#undef HAVE_GETPASS
+
+/* Define cpu-machine-OS */
+#define OS "ARM-RISC OS"
+
+/* Define if you want the built-in manual */
+#define USE_MANUAL
+
+/* Define if you have the gethostbyaddr_r() function with 5 arguments */
+#undef HAVE_GETHOSTBYADDR_R_5
+
+/* Define if you have the gethostbyaddr_r() function with 7 arguments */
+#undef HAVE_GETHOSTBYADDR_R_7
+
+/* Define if you have the gethostbyaddr_r() function with 8 arguments */
+#undef HAVE_GETHOSTBYADDR_R_8
+
+/* Define if you have the gethostbyname_r() function with 3 arguments */
+#undef HAVE_GETHOSTBYNAME_R_3
+
+/* Define if you have the gethostbyname_r() function with 5 arguments */
+#undef HAVE_GETHOSTBYNAME_R_5
+
+/* Define if you have the gethostbyname_r() function with 6 arguments */
+#undef HAVE_GETHOSTBYNAME_R_6
+
+/* Define if you need the _REENTRANT define for some functions */
+#undef NEED_REENTRANT
+
+/* Define if you have the Kerberos4 libraries (including -ldes) */
+#undef HAVE_KRB4
+
+/* Define if you want to enable IPv6 support */
+#undef ENABLE_IPV6
+
+/* Define if struct sockaddr_in6 has the sin6_scope_id member */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define this to 'int' if ssize_t is not an available typedefed type */
+#undef ssize_t
+
+/* Define this as a suitable file to read random data from */
+#undef RANDOM_FILE
+
+/* Define this to your Entropy Gathering Daemon socket pathname */
+#undef EGD_SOCKET
+
+/* Define if you want to enable IPv6 support */
+#undef ENABLE_IPV6
+
+/* Define if you have the alarm function. */
+#define HAVE_ALARM
+
+/* Define if you have the <alloca.h> header file. */
+#define HAVE_ALLOCA_H
+
+/* Define if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H
+
+/* Define if you have the `closesocket' function. */
+#undef HAVE_CLOSESOCKET
+
+/* Define if you have the <crypto.h> header file. */
+#undef HAVE_CRYPTO_H
+
+/* Define if you have the <des.h> header file. */
+#undef HAVE_DES_H
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H
+
+/* Define if you have the <err.h> header file. */
+#undef HAVE_ERR_H
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H
+
+/* Define if you have the `ftruncate' function. */
+#define HAVE_FTRUNCATE
+
+/* Define if getaddrinfo exists and works */
+#define HAVE_GETADDRINFO
+
+/* Define if you have the `geteuid' function. */
+#undef HAVE_GETEUID
+
+/* Define if you have the `gethostbyaddr' function. */
+#define HAVE_GETHOSTBYADDR
+
+/* Define if you have the `gethostbyaddr_r' function. */
+#undef HAVE_GETHOSTBYADDR_R
+
+/* Define if you have the `gethostbyname_r' function. */
+#undef HAVE_GETHOSTBYNAME_R
+
+/* Define if you have the `gethostname' function. */
+#define HAVE_GETHOSTNAME
+
+/* Define if you have the <getopt.h> header file. */
+#define HAVE_GETOPT_H
+
+/* Define if you have the `getpass_r' function. */
+#undef HAVE_GETPASS_R
+
+/* Define if you have the `getpwuid' function. */
+#undef HAVE_GETPWUID
+
+/* Define if you have the `getservbyname' function. */
+#undef HAVE_GETSERVBYNAME
+
+/* Define if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY
+
+/* Define if you have the `timeval' struct. */
+#define HAVE_STRUCT_TIMEVAL
+
+/* Define if you have the `inet_addr' function. */
+#undef HAVE_INET_ADDR
+
+/* Define if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H
+
+/* Define if you have the <io.h> header file. */
+#undef HAVE_IO_H
+
+/* Define if you have the `krb_get_our_ip_for_realm' function. */
+#undef HAVE_KRB_GET_OUR_IP_FOR_REALM
+
+/* Define if you have the <krb.h> header file. */
+#undef HAVE_KRB_H
+
+/* Define if you have the `crypto' library (-lcrypto). */
+#undef HAVE_LIBCRYPTO
+
+/* Define if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define if you have the `resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define if you have the `resolve' library (-lresolve). */
+#undef HAVE_LIBRESOLVE
+
+/* Define if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define if you have the `ssl' library (-lssl). */
+#undef HAVE_LIBSSL
+
+/* Define if you have the `ucb' library (-lucb). */
+#undef HAVE_LIBUCB
+
+/* Define if you have the `localtime_r' function. */
+#undef HAVE_LOCALTIME_R
+
+/* Define if you have the <malloc.h> header file. */
+#define HAVE_MALLOC_H
+
+/* Define if you need the malloc.h header file even with stdlib.h  */
+/* #define NEED_MALLOC_H 1 */
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H
+
+/* Define if you have the <netinet/if_ether.h> header file. */
+#undef HAVE_NETINET_IF_ETHER_H
+
+/* Define if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H
+
+/* Define if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H
+
+/* Define if you have the <openssl/crypto.h> header file. */
+#undef HAVE_OPENSSL_CRYPTO_H
+
+/* Define if you have the <openssl/err.h> header file. */
+#undef HAVE_OPENSSL_ERR_H
+
+/* Define if you have the <openssl/pem.h> header file. */
+#undef HAVE_OPENSSL_PEM_H
+
+/* Define if you have the <openssl/rsa.h> header file. */
+#undef HAVE_OPENSSL_RSA_H
+
+/* Define if you have the <openssl/ssl.h> header file. */
+#undef HAVE_OPENSSL_SSL_H
+
+/* Define if you have the <openssl/x509.h> header file. */
+#undef HAVE_OPENSSL_X509_H
+
+/* Define if you have the <pem.h> header file. */
+#undef HAVE_PEM_H
+
+/* Define if you have the `perror' function. */
+#undef HAVE_PERROR
+
+/* Define if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
+/* Define if you have the `RAND_egd' function. */
+#undef HAVE_RAND_EGD
+
+/* Define if you have the `RAND_screen' function. */
+#undef HAVE_RAND_SCREEN
+
+/* Define if you have the `RAND_status' function. */
+#undef HAVE_RAND_STATUS
+
+/* Define if you have the <rsa.h> header file. */
+#undef HAVE_RSA_H
+
+/* Define if you have the `select' function. */
+#define HAVE_SELECT
+
+/* Define if you have the `setvbuf' function. */
+#undef HAVE_SETVBUF
+
+/* Define if you have the <sgtty.h> header file. */
+#define HAVE_SGTTY_H
+
+/* Define if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define if you have the `signal' function. */
+#define HAVE_SIGNAL
+
+/* Define if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H
+
+/* Define if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T
+
+/* Define if sig_atomic_t is already defined as volatile. */
+#undef HAVE_SIG_ATOMIC_T_VOLATILE
+
+/* Define if you have the `socket' function. */
+#define HAVE_SOCKET
+
+/* Define if you have the <ssl.h> header file. */
+#undef HAVE_SSL_H
+
+/* Define if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H
+
+/* Define if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the `strcmpi' function. */
+#undef HAVE_STRCMPI
+
+/* Define if you have the `strdup' function. */
+#define HAVE_STRDUP
+
+/* Define if you have the `strftime' function. */
+#define HAVE_STRFTIME
+
+/* Define if you have the `stricmp' function. */
+#define HAVE_STRICMP
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H
+
+/* Define if you have the `strlcpy' function. */
+#undef HAVE_STRLCPY
+
+/* Define if you have the `strstr' function. */
+#define HAVE_STRSTR
+
+/* Define if you have the `strtok_r' function. */
+#undef HAVE_STRTOK_R
+
+/* Define if you have the `strtoll' function. */
+#undef HAVE_STRTOLL
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H
+
+/* Define if you have the <sys/sockio.h> header file. */
+#undef HAVE_SYS_SOCKIO_H
+
+/* Define if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H
+
+/* Define if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H
+
+/* Define if you have the `tcgetattr' function. */
+#define HAVE_TCGETATTR
+
+/* Define if you have the `tcsetattr' function. */
+#define HAVE_TCSETATTR
+
+/* Define if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H
+
+/* Define if you have the <termio.h> header file. */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define if you have the `uname' function. */
+#define HAVE_UNAME
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H
+
+/* Define if you have the <winsock.h> header file. */
+#undef HAVE_WINSOCK_H
+
+/* Define if you have the <x509.h> header file. */
+#undef HAVE_X509_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long double', as computed by sizeof. */
+#undef SIZEOF_LONG_DOUBLE
+
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef ssize_t
+
+/* Define if you have the ioctl function. */
+#define HAVE_IOCTL
+
+/* Define if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO
+
+/* to disable LDAP */
+#define CURL_DISABLE_LDAP
+
+/* Define if you have the getnameinfo function. */
+#define HAVE_GETNAMEINFO 1
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 size_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 int
+
+/* Define if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV ssize_t
+
+/* Define 1 if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 void
+
+/* Define if the type pointed by arg 2 for recvfrom is void. */
+#define RECVFROM_TYPE_ARG2_IS_VOID
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 int
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV ssize_t
+
+/* Define if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV ssize_t
+
+#endif /* HEADER_CURL_CONFIG_RISCOS_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/config-symbian.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/config-symbian.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/config-symbian.h	(revision 164)
@@ -0,0 +1,811 @@
+#ifndef HEADER_CURL_CONFIG_SYMBIAN_H
+#define HEADER_CURL_CONFIG_SYMBIAN_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/*               Hand crafted config file for Symbian               */
+/* ================================================================ */
+
+/* Location of default ca bundle */
+/* #define CURL_CA_BUNDLE "/etc/pki/tls/certs/ca-bundle.crt"*/
+
+/* Location of default ca path */
+/* #undef CURL_CA_PATH */
+
+/* to disable cookies support */
+/* #undef CURL_DISABLE_COOKIES */
+
+/* to disable cryptographic authentication */
+/* #undef CURL_DISABLE_CRYPTO_AUTH */
+
+/* to disable DICT */
+/* #undef CURL_DISABLE_DICT */
+
+/* to disable FILE */
+/* #undef CURL_DISABLE_FILE */
+
+/* to disable FTP */
+/* #undef CURL_DISABLE_FTP */
+
+/* to disable HTTP */
+/* #undef CURL_DISABLE_HTTP */
+
+/* to disable LDAP */
+#define CURL_DISABLE_LDAP 1
+
+/* to disable LDAPS */
+#define CURL_DISABLE_LDAPS 1
+
+/* to disable TELNET */
+/* #undef CURL_DISABLE_TELNET */
+
+/* to disable TFTP */
+/* #undef CURL_DISABLE_TFTP */
+
+/* to disable verbose strings */
+/* #define CURL_DISABLE_VERBOSE_STRINGS 1*/
+
+/* Definition to make a library symbol externally visible. */
+/* #undef CURL_EXTERN_SYMBOL */
+
+/* Use Windows LDAP implementation */
+/* #undef USE_WIN32_LDAP */
+
+/* your Entropy Gathering Daemon socket pathname */
+/* #undef EGD_SOCKET */
+
+/* Define if you want to enable IPv6 support */
+#define ENABLE_IPV6 1
+
+/* Define if struct sockaddr_in6 has the sin6_scope_id member */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 size_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 int
+
+/* Define to 1 if you have the <alloca.h> header file. */
+/*#define HAVE_ALLOCA_H 1*/
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/tftp.h> header file. */
+/*#define HAVE_ARPA_TFTP_H 1*/
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `basename' function. */
+/*#define HAVE_BASENAME 1*/
+
+/* Define to 1 if bool is an available type. */
+/*#define HAVE_BOOL_T 1*/
+
+/* Define to 1 if you have the `closesocket' function. */
+/* #undef HAVE_CLOSESOCKET */
+
+/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
+/*#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1*/
+
+/* Define to 1 if you have the <crypto.h> header file. */
+/* #undef HAVE_CRYPTO_H */
+
+/* Define to 1 if you have the <des.h> header file. */
+/* #undef HAVE_DES_H */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
+/*#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1*/
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <err.h> header file. */
+#define HAVE_ERR_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the fcntl function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
+#define HAVE_FCNTL_O_NONBLOCK 1
+
+/* Define to 1 if you have the `fork' function. */
+/*#define HAVE_FORK 1*/
+
+/* Define to 1 if you have the `ftruncate' function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define if getaddrinfo exists and works */
+#define HAVE_GETADDRINFO 1
+
+/* Define to 1 if you have the `geteuid' function. */
+#define HAVE_GETEUID 1
+
+/* Define to 1 if you have the `gethostbyaddr' function. */
+#define HAVE_GETHOSTBYADDR 1
+
+/* If you have gethostbyname */
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define to 1 if you have the `gethostbyname_r' function. */
+/* #undef HAVE_GETHOSTBYNAME_R */
+
+/* gethostbyname_r() takes 3 args */
+/* #undef HAVE_GETHOSTBYNAME_R_3 */
+
+/* gethostbyname_r() takes 5 args */
+/* #undef HAVE_GETHOSTBYNAME_R_5 */
+
+/* gethostbyname_r() takes 6 args */
+/* #undef HAVE_GETHOSTBYNAME_R_6 */
+
+/* Define to 1 if you have the getnameinfo function. */
+#define HAVE_GETNAMEINFO 1
+
+/* Define to 1 if you have the `getpass_r' function. */
+/* #undef HAVE_GETPASS_R */
+
+/* Define to 1 if you have the `getppid' function. */
+#define HAVE_GETPPID 1
+
+/* Define to 1 if you have the `getprotobyname' function. */
+#define HAVE_GETPROTOBYNAME 1
+
+/* Define to 1 if you have the `getpwuid' function. */
+#define HAVE_GETPWUID 1
+
+/* Define to 1 if you have the `getrlimit' function. */
+/*#define HAVE_GETRLIMIT 1*/
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* we have a glibc-style strerror_r() */
+/* #undef HAVE_GLIBC_STRERROR_R */
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#define HAVE_GMTIME_R 1
+
+/* if you have the gssapi libraries */
+/* #undef HAVE_GSSAPI */
+
+/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */
+/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */
+
+/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
+/* #undef HAVE_GSSAPI_GSSAPI_H */
+
+/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
+/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */
+
+/* if you have the GNU gssapi libraries */
+/* #undef HAVE_GSSGNU */
+
+/* if you have the Heimdal gssapi libraries */
+/* #undef HAVE_GSSHEIMDAL */
+
+/* if you have the MIT gssapi libraries */
+/* #undef HAVE_GSSMIT */
+
+/* Define to 1 if you have the `idna_strerror' function. */
+/*#define HAVE_IDNA_STRERROR 1*/
+
+/* Define to 1 if you have the `idn_free' function. */
+/*#define HAVE_IDN_FREE 1*/
+
+/* Define to 1 if you have the <idn-free.h> header file. */
+/*#define HAVE_IDN_FREE_H 1*/
+
+/* Define to 1 if you have the `inet_addr' function. */
+/*#define HAVE_INET_ADDR 1*/
+
+/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
+/*#define HAVE_INET_NTOP 1*/
+
+/* Define to 1 if you have a IPv6 capable working inet_pton function. */
+/*#define HAVE_INET_PTON 1*/
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the ioctl function. */
+#define HAVE_IOCTL 1
+
+/* Define to 1 if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO 1
+
+/* Define to 1 if you have the ioctlsocket function. */
+/* #undef HAVE_IOCTLSOCKET */
+
+/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
+/* #undef HAVE_IOCTLSOCKET_FIONBIO */
+
+/* Define to 1 if you have the IoctlSocket camel case function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL */
+
+/* Define to 1 if you have a working IoctlSocket camel case FIONBIO
+   function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
+
+/* Define to 1 if you have the <io.h> header file. */
+/* #undef HAVE_IO_H */
+
+/* if you have the Kerberos4 libraries (including -ldes) */
+/* #undef HAVE_KRB4 */
+
+/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
+/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */
+
+/* Define to 1 if you have the <krb.h> header file. */
+/* #undef HAVE_KRB_H */
+
+/* Define to 1 if you have the lber.h header file. */
+/*#define HAVE_LBER_H 1*/
+
+/* Define to 1 if you have the ldapssl.h header file. */
+/* #undef HAVE_LDAPSSL_H */
+
+/* Define to 1 if you have the ldap.h header file. */
+/*#define HAVE_LDAP_H 1*/
+
+/* Use LDAPS implementation */
+/*#define HAVE_LDAP_SSL 1*/
+
+/* Define to 1 if you have the ldap_ssl.h header file. */
+/* #undef HAVE_LDAP_SSL_H */
+
+/* Define to 1 if you have the `ldap_url_parse' function. */
+/*#define HAVE_LDAP_URL_PARSE 1*/
+
+/* Define to 1 if you have the <libgen.h> header file. */
+/*#define HAVE_LIBGEN_H 1*/
+
+/* Define to 1 if you have the `idn' library (-lidn). */
+/*#define HAVE_LIBIDN 1*/
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+/* #undef HAVE_LIBRESOLV */
+
+/* Define to 1 if you have the `resolve' library (-lresolve). */
+/* #undef HAVE_LIBRESOLVE */
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
+
+/* Define to 1 if you have the `ssh2' library (-lssh2). */
+/*#define HAVE_LIBSSH2 1*/
+
+/* Define to 1 if you have the <libssh2.h> header file. */
+/*#define HAVE_LIBSSH2_H 1*/
+
+/* Define to 1 if you have the `ssl' library (-lssl). */
+/*#define HAVE_LIBSSL 1*/
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* if your compiler supports LL */
+#define HAVE_LL 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define to 1 if you have the `localtime_r' function. */
+#define HAVE_LOCALTIME_R 1
+
+/* Define to 1 if the compiler supports the 'long long' data type. */
+#define HAVE_LONGLONG 1
+
+/* Define to 1 if you have the malloc.h header file. */
+/*#define HAVE_MALLOC_H 1*/
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the MSG_NOSIGNAL flag. */
+/*#define HAVE_MSG_NOSIGNAL 1*/
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+/*#define HAVE_NETINET_TCP_H 1*/
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H 1
+
+/* Define to 1 if NI_WITHSCOPEID exists and works. */
+/*#define HAVE_NI_WITHSCOPEID 1*/
+
+/* we have no strerror_r() proto */
+/* #undef HAVE_NO_STRERROR_R_DECL */
+
+/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE
+   */
+/* #undef HAVE_OLD_GSSMIT */
+
+/* Define to 1 if you have the <openssl/crypto.h> header file. */
+/*#define HAVE_OPENSSL_CRYPTO_H 1*/
+
+/* Define to 1 if you have the <openssl/engine.h> header file. */
+/*#define HAVE_OPENSSL_ENGINE_H 1*/
+
+/* Define to 1 if you have the <openssl/err.h> header file. */
+/*#define HAVE_OPENSSL_ERR_H 1*/
+
+/* Define to 1 if you have the <openssl/pem.h> header file. */
+/*#define HAVE_OPENSSL_PEM_H 1*/
+
+/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
+/*#define HAVE_OPENSSL_PKCS12_H 1*/
+
+/* Define to 1 if you have the <openssl/rsa.h> header file. */
+/*#define HAVE_OPENSSL_RSA_H 1*/
+
+/* Define to 1 if you have the <openssl/ssl.h> header file. */
+/*#define HAVE_OPENSSL_SSL_H 1*/
+
+/* Define to 1 if you have the <openssl/x509.h> header file. */
+/*#define HAVE_OPENSSL_X509_H 1*/
+
+/* Define to 1 if you have the <pem.h> header file. */
+/* #undef HAVE_PEM_H */
+
+/* Define to 1 if you have the `perror' function. */
+#define HAVE_PERROR 1
+
+/* Define to 1 if you have the `pipe' function. */
+#define HAVE_PIPE 1
+
+/* Define to 1 if you have the `poll' function. */
+/*#define HAVE_POLL 1*/
+
+/* If you have a fine poll */
+/*#define HAVE_POLL_FINE 1*/
+
+/* Define to 1 if you have the <poll.h> header file. */
+/*#define HAVE_POLL_H 1*/
+
+/* we have a POSIX-style strerror_r() */
+#define HAVE_POSIX_STRERROR_R 1
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#define HAVE_PWD_H 1
+
+/* Define to 1 if you have the `RAND_egd' function. */
+#define HAVE_RAND_EGD 1
+
+/* Define to 1 if you have the `RAND_screen' function. */
+/* #undef HAVE_RAND_SCREEN */
+
+/* Define to 1 if you have the `RAND_status' function. */
+/*#define HAVE_RAND_STATUS 1*/
+
+/* Define to 1 if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to 1 if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to 1 if you have the <rsa.h> header file. */
+/* #undef HAVE_RSA_H */
+
+/* Define to 1 if you have the select function. */
+#define HAVE_SELECT 1
+
+/* Define to 1 if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to 1 if you have the <setjmp.h> header file. */
+#define HAVE_SETJMP_H 1
+
+/* Define to 1 if you have the `setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the `setmode' function. */
+/* #undef HAVE_SETMODE */
+
+/* Define to 1 if you have the `setrlimit' function. */
+/*#define HAVE_SETRLIMIT 1*/
+
+/* Define to 1 if you have the setsockopt function. */
+/* #undef HAVE_SETSOCKOPT */
+
+/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
+/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
+
+/* Define to 1 if you have the <sgtty.h> header file. */
+/*#define HAVE_SGTTY_H 1*/
+
+/* Define to 1 if you have the `sigaction' function. */
+/*#define HAVE_SIGACTION 1*/
+
+/* Define to 1 if you have the `siginterrupt' function. */
+/*#define HAVE_SIGINTERRUPT 1*/
+
+/* Define to 1 if you have the `signal' function. */
+/*#define HAVE_SIGNAL 1*/
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* If you have sigsetjmp */
+/*#define HAVE_SIGSETJMP 1*/
+
+/* Define to 1 if sig_atomic_t is an available typedef. */
+/*#define HAVE_SIG_ATOMIC_T 1*/
+
+/* Define to 1 if sig_atomic_t is already defined as volatile. */
+/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
+
+/* Define to 1 if you have the `socket' function. */
+#define HAVE_SOCKET 1
+
+/* Define to 1 if you have the `SSL_get_shutdown' function. */
+/*#define HAVE_SSL_GET_SHUTDOWN 1*/
+
+/* Define to 1 if you have the <ssl.h> header file. */
+/* #undef HAVE_SSL_H */
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strcmpi' function. */
+/* #undef HAVE_STRCMPI */
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror_r' function. */
+#define HAVE_STRERROR_R 1
+
+/* Define to 1 if you have the `stricmp' function. */
+/* #undef HAVE_STRICMP */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcpy' function. */
+#define HAVE_STRLCPY 1
+
+/* Define to 1 if you have the `strstr' function. */
+#define HAVE_STRSTR 1
+
+/* Define to 1 if you have the `strtok_r' function. */
+#define HAVE_STRTOK_R 1
+
+/* Define to 1 if you have the `strtoll' function. */
+#define HAVE_STRTOLL 1
+
+/* if struct sockaddr_storage is defined */
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/* Define to 1 if you have the timeval struct. */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* Define to 1 if you have the <sys/filio.h> header file. */
+#define HAVE_SYS_FILIO_H 1
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+/*#define HAVE_SYS_POLL_H 1*/
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+#define HAVE_SYS_SOCKIO_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/utime.h> header file. */
+/* #undef HAVE_SYS_UTIME_H */
+
+/* Define to 1 if you have the <termios.h> header file. */
+/*#define HAVE_TERMIOS_H 1*/
+
+/* Define to 1 if you have the <termio.h> header file. */
+/*#define HAVE_TERMIO_H 1*/
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the <tld.h> header file. */
+/*#define HAVE_TLD_H 1*/
+
+/* Define to 1 if you have the `tld_strerror' function. */
+/*#define HAVE_TLD_STRERROR 1*/
+
+/* Define to 1 if you have the `uname' function. */
+#define HAVE_UNAME 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `utime' function. */
+#define HAVE_UTIME 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if compiler supports C99 variadic macro style. */
+#define HAVE_VARIADIC_MACROS_C99 1
+
+/* Define to 1 if compiler supports old gcc variadic macro style. */
+/*#define HAVE_VARIADIC_MACROS_GCC 1*/
+
+/* Define to 1 if you have the winber.h header file. */
+/* #undef HAVE_WINBER_H */
+
+/* Define to 1 if you have the windows.h header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the winldap.h header file. */
+/* #undef HAVE_WINLDAP_H */
+
+/* Define to 1 if you have the winsock2.h header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if you have the winsock.h header file. */
+/* #undef HAVE_WINSOCK_H */
+
+/* Define this symbol if your OS supports changing the contents of argv */
+/*#define HAVE_WRITABLE_ARGV 1*/
+
+/* Define to 1 if you have the ws2tcpip.h header file. */
+/* #undef HAVE_WS2TCPIP_H */
+
+/* Define to 1 if you have the <x509.h> header file. */
+/* #undef HAVE_X509_H */
+
+/* Define to 1 if you need the lber.h header file even with ldap.h */
+/* #undef NEED_LBER_H */
+
+/* Define to 1 if you need the malloc.h header file even with stdlib.h */
+/* #undef NEED_MALLOC_H */
+
+/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
+/* #undef NEED_REENTRANT */
+
+/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */
+/* #undef NEED_THREAD_SAFE */
+
+/* cpu-machine-OS */
+#ifdef __WINS__
+#define OS "i386-pc-epoc32"
+#elif __MARM__
+#define OS "arm-unknown-epoc32"
+#else
+/* This won't happen on any current Symbian version */
+#define OS "unknown-unknown-epoc32"
+#endif
+
+/* Name of package */
+/*#define PACKAGE "curl"*/
+
+/* Define to the address where bug reports for this package should be sent. */
+/*#define PACKAGE_BUGREPORT \
+  "a suitable curl mailing list => https://curl.haxx.se/mail/"*/
+
+/* Define to the full name of this package. */
+/*#define PACKAGE_NAME "curl"*/
+
+/* Define to the full name and version of this package. */
+/*#define PACKAGE_STRING "curl -"*/
+
+/* Define to the one symbol short name of this package. */
+/*#define PACKAGE_TARNAME "curl"*/
+
+/* Define to the version of this package. */
+/*#define PACKAGE_VERSION "-"*/
+
+/* a suitable file to read random data from */
+/*#define RANDOM_FILE "/dev/urandom"*/
+
+#define RECV_TYPE_ARG1 int
+#define RECV_TYPE_ARG2 void*
+#define RECV_TYPE_ARG3 size_t
+#define RECV_TYPE_ARG4 int
+#define RECV_TYPE_RETV ssize_t
+
+#define RECVFROM_TYPE_ARG1 int
+#define RECVFROM_TYPE_ARG2 void
+#define RECVFROM_TYPE_ARG3 size_t
+#define RECVFROM_TYPE_ARG4 int
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+#define RECVFROM_TYPE_ARG6 size_t
+#define RECVFROM_TYPE_RETV ssize_t
+#define RECVFROM_TYPE_ARG2_IS_VOID 1
+
+#define SEND_TYPE_ARG1 int
+#define SEND_QUAL_ARG2 const
+#define SEND_TYPE_ARG2 void*
+#define SEND_TYPE_ARG3 size_t
+#define SEND_TYPE_ARG4 int
+#define SEND_TYPE_RETV ssize_t
+
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+/*#define RETSIGTYPE void*/
+
+/* Define to the type of arg 1 for `select'. */
+#define SELECT_TYPE_ARG1 int
+
+/* Define to the type of args 2, 3 and 4 for `select'. */
+#define SELECT_TYPE_ARG234 (fd_set *)
+
+/* Define to the type of arg 5 for `select'. */
+#define SELECT_TYPE_ARG5 (struct timeval *)
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `off_t', as computed by sizeof. */
+#define SIZEOF_OFF_T 8
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* The size of `time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 4
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define if you want to enable c-ares support */
+/* #undef USE_ARES */
+
+/* Define to disable non-blocking sockets */
+/* #undef USE_BLOCKING_SOCKETS */
+
+/* if GnuTLS is enabled */
+/* #undef USE_GNUTLS */
+
+/* if libSSH2 is in use */
+/*#define USE_LIBSSH2 1*/
+
+/* If you want to build curl with the built-in manual */
+/*#define USE_MANUAL 1*/
+
+/* if NSS is enabled */
+/* #undef USE_NSS */
+
+/* to enable SSPI support */
+/* #undef USE_WINDOWS_SSPI */
+
+/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */
+/* #undef USE_YASSLEMUL */
+
+/* Version number of package */
+/*#define VERSION "7.18.2-CVS"*/
+
+/* Define to avoid automatic inclusion of winsock.h */
+/* #undef WIN32_LEAN_AND_MEAN */
+
+/* Define to 1 if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+/* # undef _ALL_SOURCE */
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#define _FILE_OFFSET_BITS 64
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* type to use in place of in_addr_t if not defined */
+/* #undef in_addr_t */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* the signed version of size_t */
+/* #undef ssize_t */
+
+/* Enabling curl debug mode when building in Symbian debug mode would work */
+/* except that debug mode introduces new exports that must be frozen. */
+#ifdef _DEBUG
+/* #define CURLDEBUG */
+#endif
+
+/* sys/cdefs.h fails to define this for WINSCW prior to Symbian OS ver. 9.4 */
+#ifndef __LONG_LONG_SUPPORTED
+#define __LONG_LONG_SUPPORTED
+#endif
+
+/* Enable appropriate header only when zlib support is enabled */
+#ifdef HAVE_LIBZ
+#define HAVE_ZLIB_H 1
+#endif
+
+#endif /* HEADER_CURL_CONFIG_SYMBIAN_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/config-tpf.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/config-tpf.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/config-tpf.h	(revision 164)
@@ -0,0 +1,772 @@
+#ifndef HEADER_CURL_CONFIG_TPF_H
+#define HEADER_CURL_CONFIG_TPF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/*                 Hand crafted config file for TPF                 */
+/* ================================================================ */
+
+/* ---------------------------------------------------------------- */
+/*            FEATURES, FUNCTIONS, and DEFINITIONS                  */
+/* ---------------------------------------------------------------- */
+
+/* NOTE: Refer also to the .mak file for some of the flags below */
+
+/* to disable cookies support */
+/* #undef CURL_DISABLE_COOKIES */
+
+/* to disable cryptographic authentication */
+/* #undef CURL_DISABLE_CRYPTO_AUTH */
+
+/* to disable DICT */
+/* #undef CURL_DISABLE_DICT */
+
+/* to disable FILE */
+/* #undef CURL_DISABLE_FILE */
+
+/* to disable FTP */
+/* #undef CURL_DISABLE_FTP */
+
+/* to disable HTTP */
+/* #undef CURL_DISABLE_HTTP */
+
+/* to disable LDAP */
+/* #undef CURL_DISABLE_LDAP */
+
+/* to disable TELNET */
+/* #undef CURL_DISABLE_TELNET */
+
+/* to disable TFTP */
+/* #undef CURL_DISABLE_TFTP */
+
+/* to disable verbose strings */
+/* #undef CURL_DISABLE_VERBOSE_STRINGS */
+
+/* lber dynamic library file */
+/* #undef DL_LBER_FILE */
+
+/* ldap dynamic library file */
+/* #undef DL_LDAP_FILE */
+
+/* your Entropy Gathering Daemon socket pathname */
+/* #undef EGD_SOCKET */
+
+/* Define if you want to enable IPv6 support */
+/* #undef ENABLE_IPV6 */
+
+/* Define if struct sockaddr_in6 has the sin6_scope_id member */
+/* #undef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID */
+
+/* Define to the type of arg 1 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG1 */
+
+/* Define to the type of arg 2 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG2 */
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG46 */
+
+/* Define to the type of arg 7 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG7 */
+
+/* Define to 1 if you have the alarm function. */
+#define HAVE_ALARM 1
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/tftp.h> header file. */
+/* #undef HAVE_ARPA_TFTP_H */
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `basename' function. */
+#define HAVE_BASENAME 1
+
+/* Define to 1 if you have the `closesocket' function. */
+/* #undef HAVE_CLOSESOCKET */
+
+/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
+/* #undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA */
+#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
+
+/* Define to 1 if you have the <crypto.h> header file. */
+/* #undef HAVE_CRYPTO_H */
+#define HAVE_CRYPTO_H 1
+
+/* Define to 1 if you have the <des.h> header file. */
+/* #undef HAVE_DES_H */
+#define HAVE_DES_H 1
+
+/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
+/* #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
+#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <err.h> header file. */
+/* #undef HAVE_ERR_H */
+#define HAVE_ERR_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the fcntl function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
+#define HAVE_FCNTL_O_NONBLOCK 1
+
+/* Define to 1 if you have the `fork' function. */
+/* #undef HAVE_FORK */
+#define HAVE_FORK 1
+
+/* Define to 1 if you have the `ftruncate' function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define if getaddrinfo exists and works */
+/* #undef HAVE_GETADDRINFO */
+
+/* Define to 1 if you have the `geteuid' function. */
+#define HAVE_GETEUID 1
+
+/* Define to 1 if you have the `gethostbyaddr' function. */
+#define HAVE_GETHOSTBYADDR 1
+
+/* If you have gethostbyname */
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define to 1 if you have the `gethostbyname_r' function. */
+/* #undef HAVE_GETHOSTBYNAME_R */
+
+/* gethostbyname_r() takes 3 args */
+/* #undef HAVE_GETHOSTBYNAME_R_3 */
+
+/* gethostbyname_r() takes 5 args */
+/* #undef HAVE_GETHOSTBYNAME_R_5 */
+
+/* gethostbyname_r() takes 6 args */
+/* #undef HAVE_GETHOSTBYNAME_R_6 1 */
+
+/* Define to 1 if you have the getnameinfo function. */
+/* #undef HAVE_GETNAMEINFO */
+
+/* Define to 1 if you have the `getpass_r' function. */
+/* #undef HAVE_GETPASS_R */
+
+/* Define to 1 if you have the `getprotobyname' function. */
+/* #undef HAVE_GETPROTOBYNAME */
+
+/* Define to 1 if you have the `getpwuid' function. */
+#define HAVE_GETPWUID 1
+
+/* Define to 1 if you have the `getrlimit' function. */
+/* #undef HAVE_GETRLIMIT */
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* we have a glibc-style strerror_r() */
+/* #undef HAVE_GLIBC_STRERROR_R */
+#define HAVE_GLIBC_STRERROR_R 1
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#define HAVE_GMTIME_R 1
+
+/* if you have the gssapi libraries */
+/* #undef HAVE_GSSAPI */
+
+/* if you have the GNU gssapi libraries */
+/* #undef HAVE_GSSGNU */
+
+/* if you have the Heimdal gssapi libraries */
+/* #undef HAVE_GSSHEIMDAL */
+
+/* if you have the MIT gssapi libraries */
+/* #undef HAVE_GSSMIT */
+
+/* Define to 1 if you have the `iconv' functions. */
+#define HAVE_ICONV 1
+
+/* Define to 1 if you have the `idna_strerror' function. */
+/* #undef HAVE_IDNA_STRERROR */
+
+/* Define to 1 if you have the `idn_free' function. */
+/* #undef HAVE_IDN_FREE */
+
+/* Define to 1 if you have the <idn-free.h> header file. */
+/* #undef HAVE_IDN_FREE_H */
+
+/* Define to 1 if you have the `inet_addr' function. */
+#define HAVE_INET_ADDR 1
+
+/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
+/* #undef HAVE_INET_NTOP */
+
+/* Define to 1 if you have a IPv6 capable working inet_pton function. */
+/* #undef HAVE_INET_PTON */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the ioctl function. */
+#define HAVE_IOCTL 1
+
+/* Define to 1 if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO 1
+
+/* Define to 1 if you have the ioctlsocket function. */
+/* #undef HAVE_IOCTLSOCKET */
+
+/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
+/* #undef HAVE_IOCTLSOCKET_FIONBIO */
+
+/* Define to 1 if you have the IoctlSocket camel case function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL */
+
+/* Define to 1 if you have a working IoctlSocket camel case FIONBIO
+   function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
+
+/* Define to 1 if you have the <io.h> header file. */
+/* #undef HAVE_IO_H */
+
+/* if you have the Kerberos4 libraries (including -ldes) */
+/* #undef HAVE_KRB4 */
+
+/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
+/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */
+
+/* Define to 1 if you have the <krb.h> header file. */
+/* #undef HAVE_KRB_H */
+
+/* Define to 1 if you have the <libgen.h> header file. */
+/* #undef HAVE_LIBGEN_H 1 */
+
+/* Define to 1 if you have the `idn' library (-lidn). */
+/* #undef HAVE_LIBIDN */
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+/* #undef HAVE_LIBRESOLV */
+
+/* Define to 1 if you have the `resolve' library (-lresolve). */
+/* #undef HAVE_LIBRESOLVE */
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
+
+/* Define to 1 if you have the `ssl' library (-lssl). */
+/* #undef HAVE_LIBSSL */
+#define HAVE_LIBSSL 1
+
+/* if zlib is available */
+/* #undef HAVE_LIBZ */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* if your compiler supports LL */
+#define HAVE_LL 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define to 1 if you have the `localtime_r' function. */
+#define HAVE_LOCALTIME_R 1
+
+/* Define to 1 if the compiler supports the 'long long' data type. */
+#define HAVE_LONGLONG 1
+
+/* Define to 1 if you need the malloc.h header file even with stdlib.h  */
+/* #undef NEED_MALLOC_H */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+/* undef HAVE_NETINET_TCP_H */
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H 1
+
+/* Define if NI_WITHSCOPEID exists and works */
+/* #undef HAVE_NI_WITHSCOPEID */
+
+/* we have no strerror_r() proto */
+/* #undef HAVE_NO_STRERROR_R_DECL */
+
+/* Define to 1 if you have the <openssl/crypto.h> header file. */
+/* #undef HAVE_OPENSSL_CRYPTO_H */
+#define HAVE_OPENSSL_CRYPTO_H 1
+
+/* Define to 1 if you have the <openssl/engine.h> header file. */
+/* #undef HAVE_OPENSSL_ENGINE_H */
+#define HAVE_OPENSSL_ENGINE_H 1
+
+/* Define to 1 if you have the <openssl/err.h> header file. */
+/* #undef HAVE_OPENSSL_ERR_H */
+#define HAVE_OPENSSL_ERR_H 1
+
+/* Define to 1 if you have the <openssl/pem.h> header file. */
+/* #undef HAVE_OPENSSL_PEM_H */
+#define HAVE_OPENSSL_PEM_H 1
+
+/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
+/* #undef HAVE_OPENSSL_PKCS12_H */
+#define HAVE_OPENSSL_PKCS12_H 1
+
+/* Define to 1 if you have the <openssl/rsa.h> header file. */
+/* #undef HAVE_OPENSSL_RSA_H */
+#define HAVE_OPENSSL_RSA_H 1
+
+/* Define to 1 if you have the <openssl/ssl.h> header file. */
+/* #undef HAVE_OPENSSL_SSL_H */
+#define HAVE_OPENSSL_SSL_H 1
+
+/* Define to 1 if you have the <openssl/x509.h> header file. */
+/* #undef HAVE_OPENSSL_X509_H */
+#define HAVE_OPENSSL_X509_H 1
+
+/* Define to 1 if you have the <pem.h> header file. */
+/* #undef HAVE_PEM_H */
+#define HAVE_PEM_H 1
+
+/* Define to 1 if you have the `perror' function. */
+#define HAVE_PERROR 1
+
+/* Define to 1 if you have the `pipe' function. */
+#define HAVE_PIPE 1
+
+/* Define to 1 if you have the `poll' function. */
+/* #undef HAVE_POLL */
+
+/* If you have a fine poll */
+/* #undef HAVE_POLL_FINE */
+
+/* we have a POSIX-style strerror_r() */
+/* #undef HAVE_POSIX_STRERROR_R */
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#define HAVE_PWD_H 1
+
+/* Define to 1 if you have the `RAND_egd' function. */
+/* #undef HAVE_RAND_EGD */
+#define HAVE_RAND_EGD 1
+
+/* Define to 1 if you have the `RAND_screen' function. */
+/* #undef HAVE_RAND_SCREEN */
+
+/* Define to 1 if you have the `RAND_status' function. */
+/* #undef HAVE_RAND_STATUS */
+#define HAVE_RAND_STATUS 1
+
+/* Define to 1 if you have the <rsa.h> header file. */
+/* #undef HAVE_RSA_H */
+#define HAVE_RSA_H 1
+
+/* Define to 1 if you have the `select' function. */
+#define HAVE_SELECT 1
+
+/* Define to 1 if you have the <setjmp.h> header file. */
+#define HAVE_SETJMP_H 1
+
+/* Define to 1 if you have the `setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the `setrlimit' function. */
+#define HAVE_SETRLIMIT 1
+
+/* Define to 1 if you have the setsockopt function. */
+/* #undef HAVE_SETSOCKOPT */
+
+/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
+/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
+
+/* Define to 1 if you have the <sgtty.h> header file. */
+/* #undef HAVE_SGTTY_H 1 */
+
+/* Define to 1 if you have the `sigaction' function. */
+#define HAVE_SIGACTION 1
+
+/* Define to 1 if you have the `siginterrupt' function. */
+/* #undef HAVE_SIGINTERRUPT */
+
+/* Define to 1 if you have the `signal' function. */
+#define HAVE_SIGNAL 1
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T 1
+
+/* Define to 1 if sig_atomic_t is already defined as volatile. */
+/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
+
+/* If you have sigsetjmp */
+/* #undef HAVE_SIGSETJMP */
+
+/* Define to 1 if you have the `socket' function. */
+#define HAVE_SOCKET 1
+
+/* Define to 1 if you have the <ssl.h> header file. */
+/* #undef HAVE_SSL_H */
+#define HAVE_SSL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strcmpi' function. */
+/* #undef HAVE_STRCMPI */
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror_r' function. */
+#define HAVE_STRERROR_R 1
+
+/* Define to 1 if you have the `stricmp' function. */
+/* #undef HAVE_STRICMP */
+#define HAVE_STRICMP 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcpy' function. */
+/* #undef HAVE_STRLCPY */
+
+/* Define to 1 if you have the `strstr' function. */
+#define HAVE_STRSTR 1
+
+/* Define to 1 if you have the `strtok_r' function. */
+#define HAVE_STRTOK_R 1
+
+/* Define to 1 if you have the `strtoll' function. */
+#define HAVE_STRTOLL 1
+
+/* if struct sockaddr_storage is defined */
+/* #undef HAVE_STRUCT_SOCKADDR_STORAGE */
+
+/* Define this if you have struct timeval */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* Define to 1 if you have the <sys/filio.h> header file. */
+#define HAVE_SYS_FILIO_H 1
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+/* #undef HAVE_SYS_POLL_H */
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+/* #undef HAVE_SYS_SOCKIO_H */
+#define HAVE_SYS_SOCKIO_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/utime.h> header file. */
+/* #undef HAVE_SYS_UTIME_H */
+
+/* Define to 1 if you have the <termios.h> header file. */
+/* #undef HAVE_TERMIOS_H */
+
+/* Define to 1 if you have the <termio.h> header file. */
+/* #undef HAVE_TERMIO_H */
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the <tld.h> header file. */
+/* #undef HAVE_TLD_H */
+
+/* Define to 1 if you have the `tld_strerror' function. */
+/* #undef HAVE_TLD_STRERROR */
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `utime' function. */
+#define HAVE_UTIME 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if you have the <winsock.h> header file. */
+/* #undef HAVE_WINSOCK_H */
+
+/* Define this symbol if your OS supports changing the contents of argv */
+/* #undef HAVE_WRITABLE_ARGV */
+
+/* Define to 1 if you have the ws2tcpip.h header file. */
+/* #undef HAVE_WS2TCPIP_H */
+
+/* Define to 1 if you have the <x509.h> header file. */
+/* #undef HAVE_X509_H */
+
+/* if you have the zlib.h header file */
+/* #undef HAVE_ZLIB_H */
+
+/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
+/* #undef NEED_REENTRANT */
+
+/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */
+/* #undef NEED_THREAD_SAFE */
+
+/* cpu-machine-OS */
+#define OS "s390x-ibm-tpf"
+
+/* Name of package */
+#define PACKAGE "curl"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT \
+  "a suitable curl mailing list => https://curl.haxx.se/mail/"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "curl"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "curl -"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "curl"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "-"
+
+/* a suitable file to read random data from */
+/* #undef RANDOM_FILE */
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to the type of arg 1 for `select'. */
+#define SELECT_TYPE_ARG1 int
+
+/* Define to the type of args 2, 3 and 4 for `select'. */
+#define SELECT_TYPE_ARG234 (fd_set *)
+
+/* Define to the type of arg 5 for `select'. */
+#define SELECT_TYPE_ARG5 (struct timeval *)
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `off_t', as computed by sizeof. */
+#define SIZEOF_OFF_T 8
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 8
+
+/* The size of `time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 8
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define if you want to enable ares support */
+/* #undef USE_ARES */
+
+/* Define to disable non-blocking sockets */
+/* #undef USE_BLOCKING_SOCKETS */
+
+/* if GnuTLS is enabled */
+/* #undef USE_GNUTLS */
+
+/* If you want to build curl with the built-in manual */
+/* #undef USE_MANUAL */
+
+/* if OpenSSL is in use */
+/* #undef USE_OPENSSL */
+
+/* if SSL is enabled */
+/* #undef USE_OPENSSL */
+
+/* to enable SSPI support */
+/* #undef USE_WINDOWS_SSPI */
+
+/* Version number of package */
+#define VERSION "not-used"
+
+/* Define to avoid automatic inclusion of winsock.h */
+/* #undef WIN32_LEAN_AND_MEAN */
+
+/* Define to 1 if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+/* # undef _ALL_SOURCE */
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* type to use in place of in_addr_t if not defined */
+/* #undef in_addr_t */
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* the signed version of size_t */
+/* #undef ssize_t */
+
+/* Define to 1 if you have the getnameinfo function. */
+/* #undef HAVE_GETNAMEINFO 1 */
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+/* #undef GETNAMEINFO_QUAL_ARG1 const */
+
+/* Define to the type of arg 1 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG1 struct sockaddr * */
+
+/* Define to the type of arg 2 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG2 socklen_t */
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG46 size_t */
+
+/* Define to the type of arg 7 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG7 int */
+
+/* Define to 1 if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV int
+
+/* Define to 1 if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 char
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 int
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV int
+
+/* Define to 1 if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV int
+
+#define CURL_DOES_CONVERSIONS
+#ifndef CURL_ICONV_CODESET_OF_HOST
+#define CURL_ICONV_CODESET_OF_HOST "IBM-1047"
+#endif
+
+
+#endif /* HEADER_CURL_CONFIG_TPF_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/config-vxworks.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/config-vxworks.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/config-vxworks.h	(revision 164)
@@ -0,0 +1,928 @@
+#ifndef HEADER_CURL_CONFIG_VXWORKS_H
+#define HEADER_CURL_CONFIG_VXWORKS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* =============================================================== */
+/*               Hand crafted config file for VxWorks              */
+/* =============================================================== */
+
+/* Location of default ca bundle */
+/* #undef CURL_CA_BUNDLE */
+
+/* Location of default ca path */
+/* #undef CURL_CA_PATH */
+
+/* to disable cookies support */
+/* #undef CURL_DISABLE_COOKIES */
+
+/* to disable cryptographic authentication */
+/* #undef CURL_DISABLE_CRYPTO_AUTH */
+
+/* to disable DICT */
+/* #undef CURL_DISABLE_DICT */
+
+/* to disable FILE */
+/* #undef CURL_DISABLE_FILE */
+
+/* to disable FTP */
+#define CURL_DISABLE_FTP 1
+
+/* to disable HTTP */
+/* #undef CURL_DISABLE_HTTP */
+
+/* to disable LDAP */
+#define CURL_DISABLE_LDAP 1
+
+/* to disable LDAPS */
+#define CURL_DISABLE_LDAPS 1
+
+/* to disable NTLM authentication */
+#define CURL_DISABLE_NTLM 1
+
+/* to disable proxies */
+/* #undef CURL_DISABLE_PROXY */
+
+/* to disable TELNET */
+#define CURL_DISABLE_TELNET 1
+
+/* to disable TFTP */
+#define CURL_DISABLE_TFTP 1
+
+/* to disable verbose strings */
+/* #undef CURL_DISABLE_VERBOSE_STRINGS */
+
+/* Definition to make a library symbol externally visible. */
+/* #undef CURL_EXTERN_SYMBOL */
+
+/* Use Windows LDAP implementation */
+/* #undef USE_WIN32_LDAP */
+
+/* your Entropy Gathering Daemon socket pathname */
+/* #undef EGD_SOCKET */
+
+/* Define if you want to enable IPv6 support */
+#define ENABLE_IPV6 1
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 size_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 unsigned int
+
+/* Specifies the number of arguments to getservbyport_r */
+#define GETSERVBYPORT_R_ARGS 6
+
+/* Specifies the size of the buffer to pass to getservbyport_r */
+#define GETSERVBYPORT_R_BUFSIZE 4096
+
+/* Define to 1 if you have the alarm function. */
+#define HAVE_ALARM 1
+
+/* Define to 1 if you have the <alloca.h> header file. */
+#define HAVE_ALLOCA_H 1
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/tftp.h> header file. */
+/* #undef HAVE_ARPA_TFTP_H */
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `basename' function. */
+/* #undef HAVE_BASENAME */
+
+/* Define to 1 if bool is an available type. */
+#define HAVE_BOOL_T 1
+
+/* Define to 1 if you have the clock_gettime function and monotonic timer. */
+/* #undef HAVE_CLOCK_GETTIME_MONOTONIC */
+
+/* Define to 1 if you have the `closesocket' function. */
+/* #undef HAVE_CLOSESOCKET */
+
+/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
+#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
+
+/* Define to 1 if you have the <crypto.h> header file. */
+/* #undef HAVE_CRYPTO_H */
+
+/* Define to 1 if you have the <des.h> header file. */
+/* #undef HAVE_DES_H */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
+#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <err.h> header file. */
+/* #undef HAVE_ERR_H */
+
+/* Define to 1 if you have the fcntl function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
+#define HAVE_FCNTL_O_NONBLOCK 1
+
+/* Define to 1 if you have the fdopen function. */
+#define HAVE_FDOPEN 1
+
+/* Define to 1 if you have the `fork' function. */
+#define HAVE_FORK 1
+
+/* Define to 1 if you have the freeaddrinfo function. */
+#define HAVE_FREEADDRINFO 1
+
+/* Define to 1 if you have the freeifaddrs function. */
+#define HAVE_FREEIFADDRS 1
+
+/* Define to 1 if you have the ftruncate function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define to 1 if you have a working getaddrinfo function. */
+#define HAVE_GETADDRINFO 1
+
+/* Define to 1 if you have the `geteuid' function. */
+/* #undef HAVE_GETEUID */
+
+/* Define to 1 if you have the gethostbyaddr function. */
+#define HAVE_GETHOSTBYADDR 1
+
+/* Define to 1 if you have the gethostbyaddr_r function. */
+#define HAVE_GETHOSTBYADDR_R 1
+
+/* gethostbyaddr_r() takes 5 args */
+/* #undef HAVE_GETHOSTBYADDR_R_5 */
+
+/* gethostbyaddr_r() takes 7 args */
+/* #undef HAVE_GETHOSTBYADDR_R_7 */
+
+/* gethostbyaddr_r() takes 8 args */
+#define HAVE_GETHOSTBYADDR_R_8 1
+
+/* Define to 1 if you have the gethostbyname function. */
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define to 1 if you have the gethostbyname_r function. */
+/* #undef HAVE_GETHOSTBYNAME_R */
+
+/* gethostbyname_r() takes 3 args */
+/* #undef HAVE_GETHOSTBYNAME_R_3 */
+
+/* gethostbyname_r() takes 5 args */
+/* #undef HAVE_GETHOSTBYNAME_R_5 */
+
+/* gethostbyname_r() takes 6 args */
+/* #undef HAVE_GETHOSTBYNAME_R_6 */
+
+/* Define to 1 if you have the gethostname function. */
+#define HAVE_GETHOSTNAME 1
+
+/* Define to 1 if you have a working getifaddrs function. */
+/* #undef HAVE_GETIFADDRS */
+
+/* Define to 1 if you have the getnameinfo function. */
+#define HAVE_GETNAMEINFO 1
+
+/* Define to 1 if you have the `getpass_r' function. */
+/* #undef HAVE_GETPASS_R */
+
+/* Define to 1 if you have the `getppid' function. */
+#define HAVE_GETPPID 1
+
+/* Define to 1 if you have the `getprotobyname' function. */
+#define HAVE_GETPROTOBYNAME 1
+
+/* Define to 1 if you have the `getpwuid' function. */
+/* #undef HAVE_GETPWUID */
+
+/* Define to 1 if you have the `getrlimit' function. */
+#define HAVE_GETRLIMIT 1
+
+/* Define to 1 if you have the getservbyport_r function. */
+/* #undef HAVE_GETSERVBYPORT_R */
+
+/* Define to 1 if you have the `gettimeofday' function. */
+/* #undef HAVE_GETTIMEOFDAY */
+
+/* Define to 1 if you have a working glibc-style strerror_r function. */
+/* #undef HAVE_GLIBC_STRERROR_R */
+
+/* Define to 1 if you have a working gmtime_r function. */
+#define HAVE_GMTIME_R 1
+
+/* if you have the gssapi libraries */
+/* #undef HAVE_GSSAPI */
+
+/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */
+/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */
+
+/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
+/* #undef HAVE_GSSAPI_GSSAPI_H */
+
+/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
+/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */
+
+/* if you have the GNU gssapi libraries */
+/* #undef HAVE_GSSGNU */
+
+/* if you have the Heimdal gssapi libraries */
+/* #undef HAVE_GSSHEIMDAL */
+
+/* if you have the MIT gssapi libraries */
+/* #undef HAVE_GSSMIT */
+
+/* Define to 1 if you have the `idna_strerror' function. */
+/* #undef HAVE_IDNA_STRERROR */
+
+/* Define to 1 if you have the `idn_free' function. */
+/* #undef HAVE_IDN_FREE */
+
+/* Define to 1 if you have the <idn-free.h> header file. */
+/* #undef HAVE_IDN_FREE_H */
+
+/* Define to 1 if you have the <ifaddrs.h> header file. */
+/* #undef HAVE_IFADDRS_H */
+
+/* Define to 1 if you have the `inet_addr' function. */
+#define HAVE_INET_ADDR 1
+
+/* Define to 1 if you have the inet_ntoa_r function. */
+/* #undef HAVE_INET_NTOA_R */
+
+/* inet_ntoa_r() takes 2 args */
+/* #undef HAVE_INET_NTOA_R_2 */
+
+/* inet_ntoa_r() takes 3 args */
+/* #undef HAVE_INET_NTOA_R_3 */
+
+/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
+/* #undef HAVE_INET_NTOP */
+
+/* Define to 1 if you have a IPv6 capable working inet_pton function. */
+/* #undef HAVE_INET_PTON */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the ioctl function. */
+#define HAVE_IOCTL 1
+
+/* Define to 1 if you have the ioctlsocket function. */
+/* #undef HAVE_IOCTLSOCKET */
+
+/* Define to 1 if you have the IoctlSocket camel case function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL */
+
+/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
+   */
+/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
+
+/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
+/* #undef HAVE_IOCTLSOCKET_FIONBIO */
+
+/* Define to 1 if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO 1
+
+/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
+#define HAVE_IOCTL_SIOCGIFADDR 1
+
+/* Define to 1 if you have the <io.h> header file. */
+#define HAVE_IO_H 1
+
+/* if you have the Kerberos4 libraries (including -ldes) */
+/* #undef HAVE_KRB4 */
+
+/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
+/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */
+
+/* Define to 1 if you have the <krb.h> header file. */
+/* #undef HAVE_KRB_H */
+
+/* Define to 1 if you have the lber.h header file. */
+/* #undef HAVE_LBER_H */
+
+/* Define to 1 if you have the ldapssl.h header file. */
+/* #undef HAVE_LDAPSSL_H */
+
+/* Define to 1 if you have the ldap.h header file. */
+/* #undef HAVE_LDAP_H */
+
+/* Use LDAPS implementation */
+/* #undef HAVE_LDAP_SSL */
+
+/* Define to 1 if you have the ldap_ssl.h header file. */
+/* #undef HAVE_LDAP_SSL_H */
+
+/* Define to 1 if you have the `ldap_url_parse' function. */
+/* #undef HAVE_LDAP_URL_PARSE */
+
+/* Define to 1 if you have the <libgen.h> header file. */
+/* #undef HAVE_LIBGEN_H */
+
+/* Define to 1 if you have the `idn' library (-lidn). */
+/* #undef HAVE_LIBIDN */
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+/* #undef HAVE_LIBRESOLV */
+
+/* Define to 1 if you have the `resolve' library (-lresolve). */
+/* #undef HAVE_LIBRESOLVE */
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
+
+/* Define to 1 if you have the `ssh2' library (-lssh2). */
+/* #undef HAVE_LIBSSH2 */
+
+/* Define to 1 if you have the <libssh2.h> header file. */
+/* #undef HAVE_LIBSSH2_H */
+
+/* Define to 1 if you have the `libssh2_version' function. */
+/* #undef HAVE_LIBSSH2_VERSION */
+
+/* Define to 1 if you have the `ssl' library (-lssl). */
+#define HAVE_LIBSSL 1
+
+/* if zlib is available */
+#define HAVE_LIBZ 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* if your compiler supports LL */
+#define HAVE_LL 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define to 1 if you have a working localtime_r function. */
+#define HAVE_LOCALTIME_R 1
+
+/* Define to 1 if the compiler supports the 'long long' data type. */
+#define HAVE_LONGLONG 1
+
+/* Define to 1 if you have the malloc.h header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define to 1 if you have the memory.h header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the MSG_NOSIGNAL flag. */
+/* #undef HAVE_MSG_NOSIGNAL */
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#define HAVE_NETINET_TCP_H 1
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H 1
+
+/* Define to 1 if NI_WITHSCOPEID exists and works. */
+/* #undef HAVE_NI_WITHSCOPEID */
+
+/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE
+   */
+/* #undef HAVE_OLD_GSSMIT */
+
+/* Define to 1 if you have the <openssl/crypto.h> header file. */
+#define HAVE_OPENSSL_CRYPTO_H 1
+
+/* Define to 1 if you have the <openssl/engine.h> header file. */
+#define HAVE_OPENSSL_ENGINE_H 1
+
+/* Define to 1 if you have the <openssl/err.h> header file. */
+#define HAVE_OPENSSL_ERR_H 1
+
+/* Define to 1 if you have the <openssl/pem.h> header file. */
+#define HAVE_OPENSSL_PEM_H 1
+
+/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
+#define HAVE_OPENSSL_PKCS12_H 1
+
+/* Define to 1 if you have the <openssl/rsa.h> header file. */
+#define HAVE_OPENSSL_RSA_H 1
+
+/* Define to 1 if you have the <openssl/ssl.h> header file. */
+#define HAVE_OPENSSL_SSL_H 1
+
+/* Define to 1 if you have the <openssl/x509.h> header file. */
+#define HAVE_OPENSSL_X509_H 1
+
+/* Define to 1 if you have the <pem.h> header file. */
+/* #undef HAVE_PEM_H */
+
+/* Define to 1 if you have the `perror' function. */
+#define HAVE_PERROR 1
+
+/* Define to 1 if you have the `pipe' function. */
+#define HAVE_PIPE 1
+
+/* Define to 1 if you have a working poll function. */
+/* #undef HAVE_POLL */
+
+/* If you have a fine poll */
+/* #undef HAVE_POLL_FINE */
+
+/* Define to 1 if you have the <poll.h> header file. */
+/* #undef HAVE_POLL_H */
+
+/* Define to 1 if you have a working POSIX-style strerror_r function. */
+/* #undef HAVE_POSIX_STRERROR_R */
+
+/* Define to 1 if you have the <pwd.h> header file. */
+/* #undef HAVE_PWD_H */
+
+/* Define to 1 if you have the `RAND_egd' function. */
+#define HAVE_RAND_EGD 1
+
+/* Define to 1 if you have the `RAND_screen' function. */
+/* #undef HAVE_RAND_SCREEN */
+
+/* Define to 1 if you have the `RAND_status' function. */
+#define HAVE_RAND_STATUS 1
+
+/* Define to 1 if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to 1 if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to 1 if you have the <rsa.h> header file. */
+/* #undef HAVE_RSA_H */
+
+/* Define to 1 if you have the select function. */
+#define HAVE_SELECT 1
+
+/* Define to 1 if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to 1 if you have the <setjmp.h> header file. */
+#define HAVE_SETJMP_H 1
+
+/* Define to 1 if you have the `setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the `setmode' function. */
+#define HAVE_SETMODE 1
+
+/* Define to 1 if you have the `setrlimit' function. */
+#define HAVE_SETRLIMIT 1
+
+/* Define to 1 if you have the setsockopt function. */
+#define HAVE_SETSOCKOPT 1
+
+/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
+/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
+
+/* Define to 1 if you have the <sgtty.h> header file. */
+/* #undef HAVE_SGTTY_H */
+
+/* Define to 1 if you have the sigaction function. */
+#define HAVE_SIGACTION 1
+
+/* Define to 1 if you have the siginterrupt function. */
+#define HAVE_SIGINTERRUPT 1
+
+/* Define to 1 if you have the signal function. */
+#define HAVE_SIGNAL 1
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the sigsetjmp function or macro. */
+/* #undef HAVE_SIGSETJMP */
+
+/* Define to 1 if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T 1
+
+/* Define to 1 if sig_atomic_t is already defined as volatile. */
+/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
+
+/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define to 1 if you have the `socket' function. */
+#define HAVE_SOCKET 1
+
+/* Define to 1 if you have the `SSL_get_shutdown' function. */
+#define HAVE_SSL_GET_SHUTDOWN 1
+
+/* Define to 1 if you have the <ssl.h> header file. */
+/* #undef HAVE_SSL_H */
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+/* #undef HAVE_STDINT_H */
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the strcasecmp function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the strcmpi function. */
+/* #undef HAVE_STRCMPI */
+
+/* Define to 1 if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the strerror_r function. */
+#define HAVE_STRERROR_R 1
+
+/* Define to 1 if you have the stricmp function. */
+/* #undef HAVE_STRICMP */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcpy' function. */
+/* #undef HAVE_STRLCPY */
+
+/* Define to 1 if you have the strncasecmp function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the strncmpi function. */
+/* #undef HAVE_STRNCMPI */
+
+/* Define to 1 if you have the strnicmp function. */
+/* #undef HAVE_STRNICMP */
+
+/* Define to 1 if you have the <stropts.h> header file. */
+/* #undef HAVE_STROPTS_H */
+
+/* Define to 1 if you have the strstr function. */
+#define HAVE_STRSTR 1
+
+/* Define to 1 if you have the strtok_r function. */
+#define HAVE_STRTOK_R 1
+
+/* Define to 1 if you have the strtoll function. */
+/* #undef HAVE_STRTOLL */
+
+/* if struct sockaddr_storage is defined */
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/* Define to 1 if you have the timeval struct. */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* Define to 1 if you have the <sys/filio.h> header file. */
+/* #undef HAVE_SYS_FILIO_H */
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+/* #undef HAVE_SYS_PARAM_H */
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+/* #undef HAVE_SYS_POLL_H */
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+/* #undef HAVE_SYS_SELECT_H */
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+/* #undef HAVE_SYS_SOCKIO_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+/* #undef HAVE_SYS_TIME_H */
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#define HAVE_SYS_UN_H 1
+
+/* Define to 1 if you have the <sys/utime.h> header file. */
+#define HAVE_SYS_UTIME_H 1
+
+/* Define to 1 if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H 1
+
+/* Define to 1 if you have the <termio.h> header file. */
+#define HAVE_TERMIO_H 1
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the <tld.h> header file. */
+/* #undef HAVE_TLD_H */
+
+/* Define to 1 if you have the `tld_strerror' function. */
+/* #undef HAVE_TLD_STRERROR */
+
+/* Define to 1 if you have the `uname' function. */
+#define HAVE_UNAME 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `utime' function. */
+#define HAVE_UTIME 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if compiler supports C99 variadic macro style. */
+#define HAVE_VARIADIC_MACROS_C99 1
+
+/* Define to 1 if compiler supports old gcc variadic macro style. */
+#define HAVE_VARIADIC_MACROS_GCC 1
+
+/* Define to 1 if you have a working vxworks-style strerror_r function. */
+#define HAVE_VXWORKS_STRERROR_R 1
+
+/* Define to 1 if you have the winber.h header file. */
+/* #undef HAVE_WINBER_H */
+
+/* Define to 1 if you have the windows.h header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the winldap.h header file. */
+/* #undef HAVE_WINLDAP_H */
+
+/* Define to 1 if you have the winsock2.h header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if you have the winsock.h header file. */
+/* #undef HAVE_WINSOCK_H */
+
+/* Define this symbol if your OS supports changing the contents of argv */
+#define HAVE_WRITABLE_ARGV 1
+
+/* Define to 1 if you have the writev function. */
+#define HAVE_WRITEV 1
+
+/* Define to 1 if you have the ws2tcpip.h header file. */
+/* #undef HAVE_WS2TCPIP_H */
+
+/* Define to 1 if you have the <x509.h> header file. */
+/* #undef HAVE_X509_H */
+
+/* if you have the zlib.h header file */
+#define HAVE_ZLIB_H 1
+
+/* Define to 1 if you need the lber.h header file even with ldap.h */
+/* #undef NEED_LBER_H */
+
+/* Define to 1 if you need the malloc.h header file even with stdlib.h */
+/* #undef NEED_MALLOC_H */
+
+/* Define to 1 if you need the memory.h header file even with stdlib.h */
+/* #undef NEED_MEMORY_H */
+
+/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
+/* #undef NEED_REENTRANT */
+
+/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */
+/* #undef NEED_THREAD_SAFE */
+
+/* Define to 1 if the open function requires three arguments. */
+#define OPEN_NEEDS_ARG3 1
+
+/* cpu-machine-OS */
+#define OS "unknown-unknown-vxworks"
+
+/* Name of package */
+#define PACKAGE "curl"
+
+/* a suitable file to read random data from */
+#define RANDOM_FILE "/dev/urandom"
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 void
+
+/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
+#define RECVFROM_TYPE_ARG2_IS_VOID 1
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
+/* #undef RECVFROM_TYPE_ARG5_IS_VOID */
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 socklen_t
+
+/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
+/* #undef RECVFROM_TYPE_ARG6_IS_VOID */
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV int
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV int
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to the type qualifier of arg 5 for select. */
+#define SELECT_QUAL_ARG5
+
+/* Define to the type of arg 1 for select. */
+#define SELECT_TYPE_ARG1 int
+
+/* Define to the type of args 2, 3 and 4 for select. */
+#define SELECT_TYPE_ARG234 fd_set *
+
+/* Define to the type of arg 5 for select. */
+#define SELECT_TYPE_ARG5 struct timeval *
+
+/* Define to the function return type for select. */
+#define SELECT_TYPE_RETV int
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV int
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of `off_t', as computed by sizeof. */
+#define SIZEOF_OFF_T 8
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* The size of `time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 4
+
+/* The size of `void*', as computed by sizeof. */
+#define SIZEOF_VOIDP 4
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to the type of arg 3 for strerror_r. */
+/* #undef STRERROR_R_TYPE_ARG3 */
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+/* #undef TIME_WITH_SYS_TIME */
+
+/* Define if you want to enable c-ares support */
+/* #undef USE_ARES */
+
+/* Define to disable non-blocking sockets. */
+/* #undef USE_BLOCKING_SOCKETS */
+
+/* if GnuTLS is enabled */
+/* #undef USE_GNUTLS */
+
+/* if libSSH2 is in use */
+/* #undef USE_LIBSSH2 */
+
+/* If you want to build curl with the built-in manual */
+#define USE_MANUAL 1
+
+/* if NSS is enabled */
+/* #undef USE_NSS */
+
+/* if OpenSSL is in use */
+#define USE_OPENSSL 1
+
+/* Define to 1 if you are building a Windows target without large file
+   support. */
+/* #undef USE_WIN32_LARGE_FILES */
+
+/* to enable SSPI support */
+/* #undef USE_WINDOWS_SSPI */
+
+/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */
+/* #undef USE_YASSLEMUL */
+
+/* Define to avoid automatic inclusion of winsock.h */
+/* #undef WIN32_LEAN_AND_MEAN */
+
+/* Define to 1 if OS is AIX. */
+#ifndef _ALL_SOURCE
+/* #  undef _ALL_SOURCE */
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Type to use in place of in_addr_t when system does not provide it. */
+/* #undef in_addr_t */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* the signed version of size_t */
+/* #undef ssize_t */
+
+#endif /* HEADER_CURL_CONFIG_VXWORKS_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/config-win32.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/config-win32.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/config-win32.h	(revision 164)
@@ -0,0 +1,742 @@
+#ifndef HEADER_CURL_CONFIG_WIN32_H
+#define HEADER_CURL_CONFIG_WIN32_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/*               Hand crafted config file for Windows               */
+/* ================================================================ */
+
+/* ---------------------------------------------------------------- */
+/*                          HEADER FILES                            */
+/* ---------------------------------------------------------------- */
+
+/* Define if you have the <arpa/inet.h> header file. */
+/* #define HAVE_ARPA_INET_H 1 */
+
+/* Define if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define if you have the <crypto.h> header file. */
+/* #define HAVE_CRYPTO_H 1 */
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define if you have the <err.h> header file. */
+/* #define HAVE_ERR_H 1 */
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <getopt.h> header file. */
+#if defined(__MINGW32__) || defined(__POCC__)
+#define HAVE_GETOPT_H 1
+#endif
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1800)
+#define HAVE_INTTYPES_H 1
+#endif
+
+/* Define if you have the <io.h> header file. */
+#define HAVE_IO_H 1
+
+/* Define if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define if you need <malloc.h> header even with <stdlib.h> header file. */
+#if !defined(__SALFORDC__) && !defined(__POCC__)
+#define NEED_MALLOC_H 1
+#endif
+
+/* Define if you have the <netdb.h> header file. */
+/* #define HAVE_NETDB_H 1 */
+
+/* Define if you have the <netinet/in.h> header file. */
+/* #define HAVE_NETINET_IN_H 1 */
+
+/* Define if you have the <process.h> header file. */
+#ifndef __SALFORDC__
+#define HAVE_PROCESS_H 1
+#endif
+
+/* Define if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define if you have the <sgtty.h> header file. */
+/* #define HAVE_SGTTY_H 1 */
+
+/* Define if you have the <ssl.h> header file. */
+/* #define HAVE_SSL_H 1 */
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1800)
+#define HAVE_STDBOOL_H 1
+#endif
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the <sys/param.h> header file. */
+/* #define HAVE_SYS_PARAM_H 1 */
+
+/* Define if you have the <sys/select.h> header file. */
+/* #define HAVE_SYS_SELECT_H 1 */
+
+/* Define if you have the <sys/socket.h> header file. */
+/* #define HAVE_SYS_SOCKET_H 1 */
+
+/* Define if you have the <sys/sockio.h> header file. */
+/* #define HAVE_SYS_SOCKIO_H 1 */
+
+/* Define if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define if you have the <sys/time.h> header file. */
+/* #define HAVE_SYS_TIME_H 1 */
+
+/* Define if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define if you have the <sys/utime.h> header file. */
+#ifndef __BORLANDC__
+#define HAVE_SYS_UTIME_H 1
+#endif
+
+/* Define if you have the <termio.h> header file. */
+/* #define HAVE_TERMIO_H 1 */
+
+/* Define if you have the <termios.h> header file. */
+/* #define HAVE_TERMIOS_H 1 */
+
+/* Define if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \
+    defined(__POCC__)
+#define HAVE_UNISTD_H 1
+#endif
+
+/* Define if you have the <windows.h> header file. */
+#define HAVE_WINDOWS_H 1
+
+/* Define if you have the <winsock.h> header file. */
+#define HAVE_WINSOCK_H 1
+
+/* Define if you have the <winsock2.h> header file. */
+#ifndef __SALFORDC__
+#define HAVE_WINSOCK2_H 1
+#endif
+
+/* Define if you have the <ws2tcpip.h> header file. */
+#ifndef __SALFORDC__
+#define HAVE_WS2TCPIP_H 1
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                        OTHER HEADER INFO                         */
+/* ---------------------------------------------------------------- */
+
+/* Define if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T 1
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+/* #define TIME_WITH_SYS_TIME 1 */
+
+/* Define to 1 if bool is an available type. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1800)
+#define HAVE_BOOL_T 1
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                             FUNCTIONS                            */
+/* ---------------------------------------------------------------- */
+
+/* Define if you have the closesocket function. */
+#define HAVE_CLOSESOCKET 1
+
+/* Define if you don't have vprintf but do have _doprnt. */
+/* #define HAVE_DOPRNT 1 */
+
+/* Define if you have the ftruncate function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define if you have the gethostbyaddr function. */
+#define HAVE_GETHOSTBYADDR 1
+
+/* Define if you have the gethostname function. */
+#define HAVE_GETHOSTNAME 1
+
+/* Define if you have the getpass function. */
+/* #define HAVE_GETPASS 1 */
+
+/* Define if you have the getservbyname function. */
+#define HAVE_GETSERVBYNAME 1
+
+/* Define if you have the getprotobyname function. */
+#define HAVE_GETPROTOBYNAME
+
+/* Define if you have the gettimeofday function. */
+/* #define HAVE_GETTIMEOFDAY 1 */
+
+/* Define if you have the inet_addr function. */
+#define HAVE_INET_ADDR 1
+
+/* Define if you have the ioctlsocket function. */
+#define HAVE_IOCTLSOCKET 1
+
+/* Define if you have a working ioctlsocket FIONBIO function. */
+#define HAVE_IOCTLSOCKET_FIONBIO 1
+
+/* Define if you have the perror function. */
+#define HAVE_PERROR 1
+
+/* Define if you have the RAND_screen function when using SSL. */
+#define HAVE_RAND_SCREEN 1
+
+/* Define if you have the `RAND_status' function when using SSL. */
+#define HAVE_RAND_STATUS 1
+
+/* Define if you have the `CRYPTO_cleanup_all_ex_data' function.
+   This is present in OpenSSL versions after 0.9.6b */
+#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
+
+/* Define if you have the 'DES_set_odd_parity' function when using OpenSSL/
+   BoringSSL */
+#if defined(USE_OPENSSL) || defined(HAVE_BORINGSSL)
+#define HAVE_DES_SET_ODD_PARITY 1
+#endif
+
+/* Define if you have the select function. */
+#define HAVE_SELECT 1
+
+/* Define if you have the setlocale function. */
+#define HAVE_SETLOCALE 1
+
+/* Define if you have the setmode function. */
+#define HAVE_SETMODE 1
+
+/* Define if you have the setvbuf function. */
+#define HAVE_SETVBUF 1
+
+/* Define if you have the socket function. */
+#define HAVE_SOCKET 1
+
+/* Define if you have the strcasecmp function. */
+/* #define HAVE_STRCASECMP 1 */
+
+/* Define if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define if you have the strftime function. */
+#define HAVE_STRFTIME 1
+
+/* Define if you have the stricmp function. */
+#define HAVE_STRICMP 1
+
+/* Define if you have the strncasecmp function. */
+/* #define HAVE_STRNCASECMP 1 */
+
+/* Define if you have the strnicmp function. */
+#define HAVE_STRNICMP 1
+
+/* Define if you have the strstr function. */
+#define HAVE_STRSTR 1
+
+/* Define if you have the strtoll function. */
+#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__POCC__) || \
+    (defined(_MSC_VER) && (_MSC_VER >= 1800))
+#define HAVE_STRTOLL 1
+#endif
+
+/* Define if you have the tcgetattr function. */
+/* #define HAVE_TCGETATTR 1 */
+
+/* Define if you have the tcsetattr function. */
+/* #define HAVE_TCSETATTR 1 */
+
+/* Define if you have the utime function. */
+#ifndef __BORLANDC__
+#define HAVE_UTIME 1
+#endif
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 DWORD
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 int
+
+/* Define if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 SOCKET
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV int
+
+/* Define if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 SOCKET
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 char
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 int
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV int
+
+/* Define if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 SOCKET
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV int
+
+/* ---------------------------------------------------------------- */
+/*                       TYPEDEF REPLACEMENTS                       */
+/* ---------------------------------------------------------------- */
+
+/* Define if in_addr_t is not an available 'typedefed' type. */
+#define in_addr_t unsigned long
+
+/* Define to the return type of signal handlers (int or void). */
+#define RETSIGTYPE void
+
+/* Define if ssize_t is not an available 'typedefed' type. */
+#ifndef _SSIZE_T_DEFINED
+#  if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || \
+      defined(__POCC__) || \
+      defined(__MINGW32__)
+#  elif defined(_WIN64)
+#    define _SSIZE_T_DEFINED
+#    define ssize_t __int64
+#  else
+#    define _SSIZE_T_DEFINED
+#    define ssize_t int
+#  endif
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                            TYPE SIZES                            */
+/* ---------------------------------------------------------------- */
+
+/* Define to the size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* Define to the size of `long double', as computed by sizeof. */
+#define SIZEOF_LONG_DOUBLE 16
+
+/* Define to the size of `long long', as computed by sizeof. */
+/* #define SIZEOF_LONG_LONG 8 */
+
+/* Define to the size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* Define to the size of `size_t', as computed by sizeof. */
+#if defined(_WIN64)
+#  define SIZEOF_SIZE_T 8
+#else
+#  define SIZEOF_SIZE_T 4
+#endif
+
+/* ---------------------------------------------------------------- */
+/*               BSD-style lwIP TCP/IP stack SPECIFIC               */
+/* ---------------------------------------------------------------- */
+
+/* Define to use BSD-style lwIP TCP/IP stack. */
+/* #define USE_LWIPSOCK 1 */
+
+#ifdef USE_LWIPSOCK
+#  undef USE_WINSOCK
+#  undef HAVE_WINSOCK_H
+#  undef HAVE_WINSOCK2_H
+#  undef HAVE_WS2TCPIP_H
+#  undef HAVE_ERRNO_H
+#  undef HAVE_GETHOSTNAME
+#  undef HAVE_GETNAMEINFO
+#  undef LWIP_POSIX_SOCKETS_IO_NAMES
+#  undef RECV_TYPE_ARG1
+#  undef RECV_TYPE_ARG3
+#  undef SEND_TYPE_ARG1
+#  undef SEND_TYPE_ARG3
+#  define HAVE_FREEADDRINFO
+#  define HAVE_GETADDRINFO
+#  define HAVE_GETHOSTBYNAME
+#  define HAVE_GETHOSTBYNAME_R
+#  define HAVE_GETHOSTBYNAME_R_6
+#  define LWIP_POSIX_SOCKETS_IO_NAMES 0
+#  define RECV_TYPE_ARG1 int
+#  define RECV_TYPE_ARG3 size_t
+#  define SEND_TYPE_ARG1 int
+#  define SEND_TYPE_ARG3 size_t
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                        Watt-32 tcp/ip SPECIFIC                   */
+/* ---------------------------------------------------------------- */
+
+#ifdef USE_WATT32
+  #include <tcp.h>
+  #undef byte
+  #undef word
+  #undef USE_WINSOCK
+  #undef HAVE_WINSOCK_H
+  #undef HAVE_WINSOCK2_H
+  #undef HAVE_WS2TCPIP_H
+  #define HAVE_GETADDRINFO
+  #define HAVE_GETNAMEINFO
+  #define HAVE_SYS_IOCTL_H
+  #define HAVE_SYS_SOCKET_H
+  #define HAVE_NETINET_IN_H
+  #define HAVE_NETDB_H
+  #define HAVE_ARPA_INET_H
+  #define HAVE_FREEADDRINFO
+  #define SOCKET int
+#endif
+
+
+/* ---------------------------------------------------------------- */
+/*                        COMPILER SPECIFIC                         */
+/* ---------------------------------------------------------------- */
+
+/* Define to nothing if compiler does not support 'const' qualifier. */
+/* #define const */
+
+/* Define to nothing if compiler does not support 'volatile' qualifier. */
+/* #define volatile */
+
+/* Windows should not have HAVE_GMTIME_R defined */
+/* #undef HAVE_GMTIME_R */
+
+/* Define if the compiler supports C99 variadic macro style. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+#define HAVE_VARIADIC_MACROS_C99 1
+#endif
+
+/* Define if the compiler supports the 'long long' data type. */
+#if defined(__MINGW32__) || defined(__WATCOMC__)      || \
+    (defined(_MSC_VER)     && (_MSC_VER     >= 1310)) || \
+    (defined(__BORLANDC__) && (__BORLANDC__ >= 0x561))
+#define HAVE_LONGLONG 1
+#endif
+
+/* Define to avoid VS2005 complaining about portable C functions. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+#define _CRT_SECURE_NO_DEPRECATE 1
+#define _CRT_NONSTDC_NO_DEPRECATE 1
+#endif
+
+/* VS2005 and later dafault size for time_t is 64-bit, unless
+   _USE_32BIT_TIME_T has been defined to get a 32-bit time_t. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+#  ifndef _USE_32BIT_TIME_T
+#    define SIZEOF_TIME_T 8
+#  else
+#    define SIZEOF_TIME_T 4
+#  endif
+#endif
+
+/* Define some minimum and default build targets for Visual Studio */
+#if defined(_MSC_VER)
+   /* Officially, Microsoft's Windows SDK versions 6.X does not support Windows
+      2000 as a supported build target. VS2008 default installations provides
+      an embedded Windows SDK v6.0A along with the claim that Windows 2000 is a
+      valid build target for VS2008. Popular belief is that binaries built with
+      VS2008 using Windows SDK versions v6.X and Windows 2000 as a build target
+      are functional. */
+#  define VS2008_MIN_TARGET 0x0500
+
+   /* The minimum build target for VS2012 is Vista unless Update 1 is installed
+      and the v110_xp toolset is choosen. */
+#  if defined(_USING_V110_SDK71_)
+#    define VS2012_MIN_TARGET 0x0501
+#  else
+#    define VS2012_MIN_TARGET 0x0600
+#  endif
+
+   /* VS2008 default build target is Windows Vista. We override default target
+      to be Windows XP. */
+#  define VS2008_DEF_TARGET 0x0501
+
+   /* VS2012 default build target is Windows Vista unless Update 1 is installed
+      and the v110_xp toolset is choosen. */
+#  if defined(_USING_V110_SDK71_)
+#    define VS2012_DEF_TARGET 0x0501
+#  else
+#    define VS2012_DEF_TARGET 0x0600
+#  endif
+#endif
+
+/* VS2008 default target settings and minimum build target check. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (_MSC_VER <= 1600)
+#  ifndef _WIN32_WINNT
+#    define _WIN32_WINNT VS2008_DEF_TARGET
+#  endif
+#  ifndef WINVER
+#    define WINVER VS2008_DEF_TARGET
+#  endif
+#  if (_WIN32_WINNT < VS2008_MIN_TARGET) || (WINVER < VS2008_MIN_TARGET)
+#    error VS2008 does not support Windows build targets prior to Windows 2000
+#  endif
+#endif
+
+/* VS2012 default target settings and minimum build target check. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1700)
+#  ifndef _WIN32_WINNT
+#    define _WIN32_WINNT VS2012_DEF_TARGET
+#  endif
+#  ifndef WINVER
+#    define WINVER VS2012_DEF_TARGET
+#  endif
+#  if (_WIN32_WINNT < VS2012_MIN_TARGET) || (WINVER < VS2012_MIN_TARGET)
+#    if defined(_USING_V110_SDK71_)
+#      error VS2012 does not support Windows build targets prior to Windows XP
+#    else
+#      error VS2012 does not support Windows build targets prior to Windows \
+Vista
+#    endif
+#  endif
+#endif
+
+/* When no build target is specified Pelles C 5.00 and later default build
+   target is Windows Vista. We override default target to be Windows 2000. */
+#if defined(__POCC__) && (__POCC__ >= 500)
+#  ifndef _WIN32_WINNT
+#    define _WIN32_WINNT 0x0500
+#  endif
+#  ifndef WINVER
+#    define WINVER 0x0500
+#  endif
+#endif
+
+/* Availability of freeaddrinfo, getaddrinfo and getnameinfo functions is
+   quite convoluted, compiler dependent and even build target dependent. */
+#if defined(HAVE_WS2TCPIP_H)
+#  if defined(__POCC__)
+#    define HAVE_FREEADDRINFO           1
+#    define HAVE_GETADDRINFO            1
+#    define HAVE_GETADDRINFO_THREADSAFE 1
+#    define HAVE_GETNAMEINFO            1
+#  elif defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
+#    define HAVE_FREEADDRINFO           1
+#    define HAVE_GETADDRINFO            1
+#    define HAVE_GETADDRINFO_THREADSAFE 1
+#    define HAVE_GETNAMEINFO            1
+#  elif defined(_MSC_VER) && (_MSC_VER >= 1200)
+#    define HAVE_FREEADDRINFO           1
+#    define HAVE_GETADDRINFO            1
+#    define HAVE_GETADDRINFO_THREADSAFE 1
+#    define HAVE_GETNAMEINFO            1
+#  endif
+#endif
+
+#if defined(__POCC__)
+#  ifndef _MSC_VER
+#    error Microsoft extensions /Ze compiler option is required
+#  endif
+#  ifndef __POCC__OLDNAMES
+#    error Compatibility names /Go compiler option is required
+#  endif
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                          STRUCT RELATED                          */
+/* ---------------------------------------------------------------- */
+
+/* Define if you have struct sockaddr_storage. */
+#if !defined(__SALFORDC__) && !defined(__BORLANDC__)
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+#endif
+
+/* Define if you have struct timeval. */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* Define if struct sockaddr_in6 has the sin6_scope_id member. */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+#if defined(HAVE_WINSOCK2_H) && defined(_WIN32_WINNT) && \
+    (_WIN32_WINNT >= 0x0600)
+#define HAVE_STRUCT_POLLFD 1
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                        LARGE FILE SUPPORT                        */
+/* ---------------------------------------------------------------- */
+
+#if defined(_MSC_VER) && !defined(_WIN32_WCE)
+#  if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
+#    define USE_WIN32_LARGE_FILES
+#  else
+#    define USE_WIN32_SMALL_FILES
+#  endif
+#endif
+
+#if defined(__MINGW32__) && !defined(USE_WIN32_LARGE_FILES)
+#  define USE_WIN32_LARGE_FILES
+#endif
+
+#if defined(__WATCOMC__) && !defined(USE_WIN32_LARGE_FILES)
+#  define USE_WIN32_LARGE_FILES
+#endif
+
+#if defined(__POCC__)
+#  undef USE_WIN32_LARGE_FILES
+#endif
+
+#if !defined(USE_WIN32_LARGE_FILES) && !defined(USE_WIN32_SMALL_FILES)
+#  define USE_WIN32_SMALL_FILES
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                       DNS RESOLVER SPECIALTY                     */
+/* ---------------------------------------------------------------- */
+
+/*
+ * Undefine both USE_ARES and USE_THREADS_WIN32 for synchronous DNS.
+ */
+
+/* Define to enable c-ares asynchronous DNS lookups. */
+/* #define USE_ARES 1 */
+
+/* Default define to enable threaded asynchronous DNS lookups. */
+#if !defined(USE_SYNC_DNS) && !defined(USE_ARES) && \
+    !defined(USE_THREADS_WIN32)
+#  define USE_THREADS_WIN32 1
+#endif
+
+#if defined(USE_ARES) && defined(USE_THREADS_WIN32)
+#  error "Only one DNS lookup specialty may be defined at most"
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                           LDAP SUPPORT                           */
+/* ---------------------------------------------------------------- */
+
+#if defined(CURL_HAS_NOVELL_LDAPSDK) || defined(CURL_HAS_MOZILLA_LDAPSDK)
+#undef USE_WIN32_LDAP
+#define HAVE_LDAP_SSL_H 1
+#define HAVE_LDAP_URL_PARSE 1
+#elif defined(CURL_HAS_OPENLDAP_LDAPSDK)
+#undef USE_WIN32_LDAP
+#define HAVE_LDAP_URL_PARSE 1
+#else
+#undef HAVE_LDAP_URL_PARSE
+#define USE_WIN32_LDAP 1
+#endif
+
+#if defined(__WATCOMC__) && defined(USE_WIN32_LDAP)
+#if __WATCOMC__ < 1280
+#define WINBERAPI  __declspec(cdecl)
+#define WINLDAPAPI __declspec(cdecl)
+#endif
+#endif
+
+#if defined(__POCC__) && defined(USE_WIN32_LDAP)
+#  define CURL_DISABLE_LDAP 1
+#endif
+
+/* Define to use the Windows crypto library. */
+#if !defined(USE_OPENSSL) && !defined(USE_NSS)
+#define USE_WIN32_CRYPTO
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                       ADDITIONAL DEFINITIONS                     */
+/* ---------------------------------------------------------------- */
+
+/* Define cpu-machine-OS */
+#undef OS
+#if defined(_M_IX86) || defined(__i386__) /* x86 (MSVC or gcc) */
+#define OS "i386-pc-win32"
+#elif defined(_M_X64) || defined(__x86_64__) /* x86_64 (MSVC >=2005 or gcc) */
+#define OS "x86_64-pc-win32"
+#elif defined(_M_IA64) /* Itanium */
+#define OS "ia64-pc-win32"
+#else
+#define OS "unknown-pc-win32"
+#endif
+
+/* Name of package */
+#define PACKAGE "curl"
+
+/* If you want to build curl with the built-in manual */
+#define USE_MANUAL 1
+
+#if defined(__POCC__) || (USE_IPV6)
+#  define ENABLE_IPV6 1
+#endif
+
+#endif /* HEADER_CURL_CONFIG_WIN32_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/config-win32ce.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/config-win32ce.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/config-win32ce.h	(revision 164)
@@ -0,0 +1,448 @@
+#ifndef HEADER_CURL_CONFIG_WIN32CE_H
+#define HEADER_CURL_CONFIG_WIN32CE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/*  lib/config-win32ce.h - Hand crafted config file for windows ce  */
+/* ================================================================ */
+
+/* ---------------------------------------------------------------- */
+/*                          HEADER FILES                            */
+/* ---------------------------------------------------------------- */
+
+/* Define if you have the <arpa/inet.h> header file.  */
+/* #define HAVE_ARPA_INET_H 1 */
+
+/* Define if you have the <assert.h> header file.  */
+/* #define HAVE_ASSERT_H 1 */
+
+/* Define if you have the <crypto.h> header file.  */
+/* #define HAVE_CRYPTO_H 1 */
+
+/* Define if you have the <errno.h> header file.  */
+/* #define HAVE_ERRNO_H 1 */
+
+/* Define if you have the <err.h> header file.  */
+/* #define HAVE_ERR_H 1 */
+
+/* Define if you have the <fcntl.h> header file.  */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <getopt.h> header file.  */
+/* #define HAVE_GETOPT_H 1 */
+
+/* Define if you have the <io.h> header file.  */
+#define HAVE_IO_H 1
+
+/* Define if you have the <limits.h> header file.  */
+#define HAVE_LIMITS_H 1
+
+/* Define if you need the malloc.h header header file even with stdlib.h  */
+#define NEED_MALLOC_H 1
+
+/* Define if you have the <netdb.h> header file.  */
+/* #define HAVE_NETDB_H 1 */
+
+/* Define if you have the <netinet/in.h> header file.  */
+/* #define HAVE_NETINET_IN_H 1 */
+
+/* Define if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define if you have the <sgtty.h> header file.  */
+/* #define HAVE_SGTTY_H 1 */
+
+/* Define if you have the <ssl.h> header file.  */
+/* #define HAVE_SSL_H 1 */
+
+/* Define if you have the <stdlib.h> header file.  */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the <process.h> header file.  */
+/* #define HAVE_PROCESS_H 1 */
+
+/* Define if you have the <sys/param.h> header file.  */
+/* #define HAVE_SYS_PARAM_H 1 */
+
+/* Define if you have the <sys/select.h> header file.  */
+/* #define HAVE_SYS_SELECT_H 1 */
+
+/* Define if you have the <sys/socket.h> header file.  */
+/* #define HAVE_SYS_SOCKET_H 1 */
+
+/* Define if you have the <sys/sockio.h> header file.  */
+/* #define HAVE_SYS_SOCKIO_H 1 */
+
+/* Define if you have the <sys/stat.h> header file.  */
+#define HAVE_SYS_STAT_H 1
+
+/* Define if you have the <sys/time.h> header file */
+/* #define HAVE_SYS_TIME_H 1 */
+
+/* Define if you have the <sys/types.h> header file.  */
+/* #define HAVE_SYS_TYPES_H 1 */
+
+/* Define if you have the <sys/utime.h> header file */
+#define HAVE_SYS_UTIME_H 1
+
+/* Define if you have the <termio.h> header file.  */
+/* #define HAVE_TERMIO_H 1 */
+
+/* Define if you have the <termios.h> header file.  */
+/* #define HAVE_TERMIOS_H 1 */
+
+/* Define if you have the <time.h> header file.  */
+#define HAVE_TIME_H 1
+
+/* Define if you have the <unistd.h> header file.  */
+#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__)
+#define HAVE_UNISTD_H 1
+#endif
+
+/* Define if you have the <windows.h> header file.  */
+#define HAVE_WINDOWS_H 1
+
+/* Define if you have the <winsock.h> header file.  */
+#define HAVE_WINSOCK_H 1
+
+/* Define if you have the <winsock2.h> header file.  */
+/* #define HAVE_WINSOCK2_H 1 */
+
+/* Define if you have the <ws2tcpip.h> header file.  */
+/* #define HAVE_WS2TCPIP_H 1 */
+
+/* ---------------------------------------------------------------- */
+/*                        OTHER HEADER INFO                         */
+/* ---------------------------------------------------------------- */
+
+/* Define if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T 1
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+/* #define TIME_WITH_SYS_TIME 1 */
+
+/* ---------------------------------------------------------------- */
+/*                             FUNCTIONS                            */
+/* ---------------------------------------------------------------- */
+
+/* Define if you have the closesocket function.  */
+#define HAVE_CLOSESOCKET 1
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+/* #define HAVE_DOPRNT 1 */
+
+/* Define if you have the gethostbyaddr function.  */
+#define HAVE_GETHOSTBYADDR 1
+
+/* Define if you have the gethostname function.  */
+#define HAVE_GETHOSTNAME 1
+
+/* Define if you have the getpass function.  */
+/* #define HAVE_GETPASS 1 */
+
+/* Define if you have the getservbyname function.  */
+#define HAVE_GETSERVBYNAME 1
+
+/* Define if you have the gettimeofday function.  */
+/*  #define HAVE_GETTIMEOFDAY 1 */
+
+/* Define if you have the inet_addr function.  */
+#define HAVE_INET_ADDR 1
+
+/* Define if you have the ioctlsocket function. */
+#define HAVE_IOCTLSOCKET 1
+
+/* Define if you have a working ioctlsocket FIONBIO function. */
+#define HAVE_IOCTLSOCKET_FIONBIO 1
+
+/* Define if you have the perror function.  */
+#define HAVE_PERROR 1
+
+/* Define if you have the RAND_screen function when using SSL  */
+#define HAVE_RAND_SCREEN 1
+
+/* Define if you have the `RAND_status' function when using SSL. */
+#define HAVE_RAND_STATUS 1
+
+/* Define if you have the select function.  */
+#define HAVE_SELECT 1
+
+/* Define if you have the setvbuf function.  */
+#define HAVE_SETVBUF 1
+
+/* Define if you have the socket function.  */
+#define HAVE_SOCKET 1
+
+/* Define if you have the strcasecmp function.  */
+/* #define HAVE_STRCASECMP 1 */
+
+/* Define if you have the strdup function.  */
+/* #define HAVE_STRDUP 1 */
+
+/* Define if you have the strftime function.  */
+/* #define HAVE_STRFTIME 1 */
+
+/* Define if you have the stricmp function. */
+/* #define HAVE_STRICMP 1 */
+
+/* Define if you have the strncasecmp function. */
+/* #define HAVE_STRNCASECMP 1 */
+
+/* Define if you have the strnicmp function. */
+/* #define HAVE_STRNICMP 1 */
+
+/* Define if you have the strstr function.  */
+#define HAVE_STRSTR 1
+
+/* Define if you have the strtoll function.  */
+#if defined(__MINGW32__) || defined(__WATCOMC__)
+#define HAVE_STRTOLL 1
+#endif
+
+/* Define if you have the tcgetattr function.  */
+/* #define HAVE_TCGETATTR 1 */
+
+/* Define if you have the tcsetattr function.  */
+/* #define HAVE_TCSETATTR 1 */
+
+/* Define if you have the utime function */
+#define HAVE_UTIME 1
+
+/* Define if you have the getnameinfo function. */
+#define HAVE_GETNAMEINFO 1
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 DWORD
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 int
+
+/* Define if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 SOCKET
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV int
+
+/* Define if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 SOCKET
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 char
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 int
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV int
+
+/* Define if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 SOCKET
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV int
+
+/* ---------------------------------------------------------------- */
+/*                       TYPEDEF REPLACEMENTS                       */
+/* ---------------------------------------------------------------- */
+
+/* Define this if in_addr_t is not an available 'typedefed' type */
+#define in_addr_t unsigned long
+
+/* Define as the return type of signal handlers (int or void).  */
+#define RETSIGTYPE void
+
+/* Define ssize_t if it is not an available 'typedefed' type */
+#if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || defined(__POCC__)
+#elif defined(_WIN64)
+#define ssize_t __int64
+#else
+#define ssize_t int
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                            TYPE SIZES                            */
+/* ---------------------------------------------------------------- */
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long double', as computed by sizeof. */
+#define SIZEOF_LONG_DOUBLE 16
+
+/* The size of `long long', as computed by sizeof. */
+/* #define SIZEOF_LONG_LONG 8 */
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `size_t', as computed by sizeof. */
+#if defined(_WIN64)
+#  define SIZEOF_SIZE_T 8
+#else
+#  define SIZEOF_SIZE_T 4
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                          STRUCT RELATED                          */
+/* ---------------------------------------------------------------- */
+
+/* Define this if you have struct sockaddr_storage */
+/* #define HAVE_STRUCT_SOCKADDR_STORAGE 1 */
+
+/* Define this if you have struct timeval */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* Define this if struct sockaddr_in6 has the sin6_scope_id member */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* ---------------------------------------------------------------- */
+/*                        COMPILER SPECIFIC                         */
+/* ---------------------------------------------------------------- */
+
+/* Undef keyword 'const' if it does not work.  */
+/* #undef const */
+
+/* Define to avoid VS2005 complaining about portable C functions */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+#define _CRT_SECURE_NO_DEPRECATE 1
+#define _CRT_NONSTDC_NO_DEPRECATE 1
+#endif
+
+/* VS2005 and later dafault size for time_t is 64-bit, unless */
+/* _USE_32BIT_TIME_T has been defined to get a 32-bit time_t. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+#  ifndef _USE_32BIT_TIME_T
+#    define SIZEOF_TIME_T 8
+#  else
+#    define SIZEOF_TIME_T 4
+#  endif
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                        LARGE FILE SUPPORT                        */
+/* ---------------------------------------------------------------- */
+
+#if defined(_MSC_VER) && !defined(_WIN32_WCE)
+#  if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
+#    define USE_WIN32_LARGE_FILES
+#  else
+#    define USE_WIN32_SMALL_FILES
+#  endif
+#endif
+
+#if !defined(USE_WIN32_LARGE_FILES) && !defined(USE_WIN32_SMALL_FILES)
+#  define USE_WIN32_SMALL_FILES
+#endif
+
+/* ---------------------------------------------------------------- */
+/*                           LDAP SUPPORT                           */
+/* ---------------------------------------------------------------- */
+
+#define USE_WIN32_LDAP 1
+#undef HAVE_LDAP_URL_PARSE
+
+/* ---------------------------------------------------------------- */
+/*                       ADDITIONAL DEFINITIONS                     */
+/* ---------------------------------------------------------------- */
+
+/* Define cpu-machine-OS */
+#undef OS
+#define OS "i386-pc-win32ce"
+
+/* Name of package */
+#define PACKAGE "curl"
+
+/* ---------------------------------------------------------------- */
+/*                       WinCE                                      */
+/* ---------------------------------------------------------------- */
+
+#ifndef UNICODE
+#  define UNICODE
+#endif
+
+#ifndef _UNICODE
+#  define _UNICODE
+#endif
+
+#define CURL_DISABLE_FILE 1
+#define CURL_DISABLE_TELNET 1
+#define CURL_DISABLE_LDAP 1
+
+#define ENOSPC 1
+#define ENOMEM 2
+#define EAGAIN 3
+
+extern int stat(const char *path, struct stat *buffer);
+
+#endif /* HEADER_CURL_CONFIG_WIN32CE_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/conncache.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/conncache.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/conncache.c	(revision 164)
@@ -0,0 +1,364 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012, Linus Nielsen Feltzing, <linus@haxx.se>
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "url.h"
+#include "progress.h"
+#include "multiif.h"
+#include "sendf.h"
+#include "rawstr.h"
+#include "conncache.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+static void conn_llist_dtor(void *user, void *element)
+{
+  struct connectdata *data = element;
+  (void)user;
+
+  data->bundle = NULL;
+}
+
+static CURLcode bundle_create(struct SessionHandle *data,
+                              struct connectbundle **cb_ptr)
+{
+  (void)data;
+  DEBUGASSERT(*cb_ptr == NULL);
+  *cb_ptr = malloc(sizeof(struct connectbundle));
+  if(!*cb_ptr)
+    return CURLE_OUT_OF_MEMORY;
+
+  (*cb_ptr)->num_connections = 0;
+  (*cb_ptr)->multiuse = BUNDLE_UNKNOWN;
+
+  (*cb_ptr)->conn_list = Curl_llist_alloc((curl_llist_dtor) conn_llist_dtor);
+  if(!(*cb_ptr)->conn_list) {
+    Curl_safefree(*cb_ptr);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  return CURLE_OK;
+}
+
+static void bundle_destroy(struct connectbundle *cb_ptr)
+{
+  if(!cb_ptr)
+    return;
+
+  if(cb_ptr->conn_list) {
+    Curl_llist_destroy(cb_ptr->conn_list, NULL);
+    cb_ptr->conn_list = NULL;
+  }
+  free(cb_ptr);
+}
+
+/* Add a connection to a bundle */
+static CURLcode bundle_add_conn(struct connectbundle *cb_ptr,
+                              struct connectdata *conn)
+{
+  if(!Curl_llist_insert_next(cb_ptr->conn_list, cb_ptr->conn_list->tail, conn))
+    return CURLE_OUT_OF_MEMORY;
+
+  conn->bundle = cb_ptr;
+
+  cb_ptr->num_connections++;
+  return CURLE_OK;
+}
+
+/* Remove a connection from a bundle */
+static int bundle_remove_conn(struct connectbundle *cb_ptr,
+                              struct connectdata *conn)
+{
+  struct curl_llist_element *curr;
+
+  curr = cb_ptr->conn_list->head;
+  while(curr) {
+    if(curr->ptr == conn) {
+      Curl_llist_remove(cb_ptr->conn_list, curr, NULL);
+      cb_ptr->num_connections--;
+      conn->bundle = NULL;
+      return 1; /* we removed a handle */
+    }
+    curr = curr->next;
+  }
+  return 0;
+}
+
+static void free_bundle_hash_entry(void *freethis)
+{
+  struct connectbundle *b = (struct connectbundle *) freethis;
+
+  bundle_destroy(b);
+}
+
+int Curl_conncache_init(struct conncache *connc, int size)
+{
+  return Curl_hash_init(&connc->hash, size, Curl_hash_str,
+                        Curl_str_key_compare, free_bundle_hash_entry);
+}
+
+void Curl_conncache_destroy(struct conncache *connc)
+{
+  if(connc)
+    Curl_hash_destroy(&connc->hash);
+}
+
+/* returns an allocated key to find a bundle for this connection */
+static char *hashkey(struct connectdata *conn)
+{
+  return aprintf("%s:%d",
+                 conn->bits.proxy?conn->proxy.name:conn->host.name,
+                 conn->localport);
+}
+
+/* Look up the bundle with all the connections to the same host this
+   connectdata struct is setup to use. */
+struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
+                                                 struct conncache *connc)
+{
+  struct connectbundle *bundle = NULL;
+  if(connc) {
+    char *key = hashkey(conn);
+    if(key) {
+      bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
+      free(key);
+    }
+  }
+
+  return bundle;
+}
+
+static bool conncache_add_bundle(struct conncache *connc,
+                                 char *key,
+                                 struct connectbundle *bundle)
+{
+  void *p = Curl_hash_add(&connc->hash, key, strlen(key), bundle);
+
+  return p?TRUE:FALSE;
+}
+
+static void conncache_remove_bundle(struct conncache *connc,
+                                    struct connectbundle *bundle)
+{
+  struct curl_hash_iterator iter;
+  struct curl_hash_element *he;
+
+  if(!connc)
+    return;
+
+  Curl_hash_start_iterate(&connc->hash, &iter);
+
+  he = Curl_hash_next_element(&iter);
+  while(he) {
+    if(he->ptr == bundle) {
+      /* The bundle is destroyed by the hash destructor function,
+         free_bundle_hash_entry() */
+      Curl_hash_delete(&connc->hash, he->key, he->key_len);
+      return;
+    }
+
+    he = Curl_hash_next_element(&iter);
+  }
+}
+
+CURLcode Curl_conncache_add_conn(struct conncache *connc,
+                                 struct connectdata *conn)
+{
+  CURLcode result;
+  struct connectbundle *bundle;
+  struct connectbundle *new_bundle = NULL;
+  struct SessionHandle *data = conn->data;
+
+  bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
+  if(!bundle) {
+    char *key;
+    int rc;
+
+    result = bundle_create(data, &new_bundle);
+    if(result)
+      return result;
+
+    key = hashkey(conn);
+    if(!key) {
+      bundle_destroy(new_bundle);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
+    free(key);
+    if(!rc) {
+      bundle_destroy(new_bundle);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    bundle = new_bundle;
+  }
+
+  result = bundle_add_conn(bundle, conn);
+  if(result) {
+    if(new_bundle)
+      conncache_remove_bundle(data->state.conn_cache, new_bundle);
+    return result;
+  }
+
+  conn->connection_id = connc->next_connection_id++;
+  connc->num_connections++;
+
+  DEBUGF(infof(conn->data, "Added connection %ld. "
+               "The cache now contains %" CURL_FORMAT_CURL_OFF_TU " members\n",
+               conn->connection_id, (curl_off_t) connc->num_connections));
+
+  return CURLE_OK;
+}
+
+void Curl_conncache_remove_conn(struct conncache *connc,
+                                struct connectdata *conn)
+{
+  struct connectbundle *bundle = conn->bundle;
+
+  /* The bundle pointer can be NULL, since this function can be called
+     due to a failed connection attempt, before being added to a bundle */
+  if(bundle) {
+    bundle_remove_conn(bundle, conn);
+    if(bundle->num_connections == 0) {
+      conncache_remove_bundle(connc, bundle);
+    }
+
+    if(connc) {
+      connc->num_connections--;
+
+      DEBUGF(infof(conn->data, "The cache now contains %"
+                   CURL_FORMAT_CURL_OFF_TU " members\n",
+                   (curl_off_t) connc->num_connections));
+    }
+  }
+}
+
+/* This function iterates the entire connection cache and calls the
+   function func() with the connection pointer as the first argument
+   and the supplied 'param' argument as the other,
+
+   Return 0 from func() to continue the loop, return 1 to abort it.
+ */
+void Curl_conncache_foreach(struct conncache *connc,
+                            void *param,
+                            int (*func)(struct connectdata *conn, void *param))
+{
+  struct curl_hash_iterator iter;
+  struct curl_llist_element *curr;
+  struct curl_hash_element *he;
+
+  if(!connc)
+    return;
+
+  Curl_hash_start_iterate(&connc->hash, &iter);
+
+  he = Curl_hash_next_element(&iter);
+  while(he) {
+    struct connectbundle *bundle;
+
+    bundle = he->ptr;
+    he = Curl_hash_next_element(&iter);
+
+    curr = bundle->conn_list->head;
+    while(curr) {
+      /* Yes, we need to update curr before calling func(), because func()
+         might decide to remove the connection */
+      struct connectdata *conn = curr->ptr;
+      curr = curr->next;
+
+      if(1 == func(conn, param))
+        return;
+    }
+  }
+}
+
+/* Return the first connection found in the cache. Used when closing all
+   connections */
+struct connectdata *
+Curl_conncache_find_first_connection(struct conncache *connc)
+{
+  struct curl_hash_iterator iter;
+  struct curl_hash_element *he;
+  struct connectbundle *bundle;
+
+  Curl_hash_start_iterate(&connc->hash, &iter);
+
+  he = Curl_hash_next_element(&iter);
+  while(he) {
+    struct curl_llist_element *curr;
+    bundle = he->ptr;
+
+    curr = bundle->conn_list->head;
+    if(curr) {
+      return curr->ptr;
+    }
+
+    he = Curl_hash_next_element(&iter);
+  }
+
+  return NULL;
+}
+
+
+#if 0
+/* Useful for debugging the connection cache */
+void Curl_conncache_print(struct conncache *connc)
+{
+  struct curl_hash_iterator iter;
+  struct curl_llist_element *curr;
+  struct curl_hash_element *he;
+
+  if(!connc)
+    return;
+
+  fprintf(stderr, "=Bundle cache=\n");
+
+  Curl_hash_start_iterate(connc->hash, &iter);
+
+  he = Curl_hash_next_element(&iter);
+  while(he) {
+    struct connectbundle *bundle;
+    struct connectdata *conn;
+
+    bundle = he->ptr;
+
+    fprintf(stderr, "%s -", he->key);
+    curr = bundle->conn_list->head;
+    while(curr) {
+      conn = curr->ptr;
+
+      fprintf(stderr, " [%p %d]", (void *)conn, conn->inuse);
+      curr = curr->next;
+    }
+    fprintf(stderr, "\n");
+
+    he = Curl_hash_next_element(&iter);
+  }
+}
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/lib/conncache.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/conncache.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/conncache.h	(revision 164)
@@ -0,0 +1,68 @@
+#ifndef HEADER_CURL_CONNCACHE_H
+#define HEADER_CURL_CONNCACHE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+struct conncache {
+  struct curl_hash hash;
+  size_t num_connections;
+  long next_connection_id;
+  struct timeval last_cleanup;
+};
+
+#define BUNDLE_NO_MULTIUSE -1
+#define BUNDLE_UNKNOWN     0  /* initial value */
+#define BUNDLE_PIPELINING  1
+#define BUNDLE_MULTIPLEX   2
+
+struct connectbundle {
+  int multiuse;                 /* supports multi-use */
+  size_t num_connections;       /* Number of connections in the bundle */
+  struct curl_llist *conn_list; /* The connectdata members of the bundle */
+};
+
+int Curl_conncache_init(struct conncache *, int size);
+
+void Curl_conncache_destroy(struct conncache *connc);
+
+/* return the correct bundle, to a host or a proxy */
+struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
+                                                 struct conncache *connc);
+
+CURLcode Curl_conncache_add_conn(struct conncache *connc,
+                                 struct connectdata *conn);
+
+void Curl_conncache_remove_conn(struct conncache *connc,
+                                struct connectdata *conn);
+
+void Curl_conncache_foreach(struct conncache *connc,
+                            void *param,
+                            int (*func)(struct connectdata *conn,
+                                        void *param));
+
+struct connectdata *
+Curl_conncache_find_first_connection(struct conncache *connc);
+
+void Curl_conncache_print(struct conncache *connc);
+
+#endif /* HEADER_CURL_CONNCACHE_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/connect.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/connect.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/connect.c	(revision 164)
@@ -0,0 +1,1382 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h> /* <netinet/tcp.h> may need it */
+#endif
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h> /* for sockaddr_un */
+#endif
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h> /* for TCP_NODELAY */
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE))
+#include <sys/filio.h>
+#endif
+#ifdef NETWARE
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#include "curl_printf.h"
+#include "urldata.h"
+#include "sendf.h"
+#include "if2ip.h"
+#include "strerror.h"
+#include "connect.h"
+#include "select.h"
+#include "url.h" /* for Curl_safefree() */
+#include "multiif.h"
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "inet_ntop.h"
+#include "inet_pton.h"
+#include "vtls/vtls.h" /* for Curl_ssl_check_cxn() */
+#include "progress.h"
+#include "warnless.h"
+#include "conncache.h"
+#include "multihandle.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifdef __SYMBIAN32__
+/* This isn't actually supported under Symbian OS */
+#undef SO_NOSIGPIPE
+#endif
+
+static bool verifyconnect(curl_socket_t sockfd, int *error);
+
+#if defined(__DragonFly__) || defined(HAVE_WINSOCK_H)
+/* DragonFlyBSD and Windows use millisecond units */
+#define KEEPALIVE_FACTOR(x) (x *= 1000)
+#else
+#define KEEPALIVE_FACTOR(x)
+#endif
+
+#if defined(HAVE_WINSOCK2_H) && !defined(SIO_KEEPALIVE_VALS)
+#define SIO_KEEPALIVE_VALS    _WSAIOW(IOC_VENDOR,4)
+
+struct tcp_keepalive {
+  u_long onoff;
+  u_long keepalivetime;
+  u_long keepaliveinterval;
+};
+#endif
+
+static void
+tcpkeepalive(struct SessionHandle *data,
+             curl_socket_t sockfd)
+{
+  int optval = data->set.tcp_keepalive?1:0;
+
+  /* only set IDLE and INTVL if setting KEEPALIVE is successful */
+  if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
+        (void *)&optval, sizeof(optval)) < 0) {
+    infof(data, "Failed to set SO_KEEPALIVE on fd %d\n", sockfd);
+  }
+  else {
+#if defined(SIO_KEEPALIVE_VALS)
+    struct tcp_keepalive vals;
+    DWORD dummy;
+    vals.onoff = 1;
+    optval = curlx_sltosi(data->set.tcp_keepidle);
+    KEEPALIVE_FACTOR(optval);
+    vals.keepalivetime = optval;
+    optval = curlx_sltosi(data->set.tcp_keepintvl);
+    KEEPALIVE_FACTOR(optval);
+    vals.keepaliveinterval = optval;
+    if(WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID) &vals, sizeof(vals),
+                NULL, 0, &dummy, NULL, NULL) != 0) {
+      infof(data, "Failed to set SIO_KEEPALIVE_VALS on fd %d: %d\n",
+            (int)sockfd, WSAGetLastError());
+    }
+#else
+#ifdef TCP_KEEPIDLE
+    optval = curlx_sltosi(data->set.tcp_keepidle);
+    KEEPALIVE_FACTOR(optval);
+    if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
+          (void *)&optval, sizeof(optval)) < 0) {
+      infof(data, "Failed to set TCP_KEEPIDLE on fd %d\n", sockfd);
+    }
+#endif
+#ifdef TCP_KEEPINTVL
+    optval = curlx_sltosi(data->set.tcp_keepintvl);
+    KEEPALIVE_FACTOR(optval);
+    if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
+          (void *)&optval, sizeof(optval)) < 0) {
+      infof(data, "Failed to set TCP_KEEPINTVL on fd %d\n", sockfd);
+    }
+#endif
+#ifdef TCP_KEEPALIVE
+    /* Mac OS X style */
+    optval = curlx_sltosi(data->set.tcp_keepidle);
+    KEEPALIVE_FACTOR(optval);
+    if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE,
+          (void *)&optval, sizeof(optval)) < 0) {
+      infof(data, "Failed to set TCP_KEEPALIVE on fd %d\n", sockfd);
+    }
+#endif
+#endif
+  }
+}
+
+static CURLcode
+singleipconnect(struct connectdata *conn,
+                const Curl_addrinfo *ai, /* start connecting to this */
+                curl_socket_t *sock);
+
+/*
+ * Curl_timeleft() returns the amount of milliseconds left allowed for the
+ * transfer/connection. If the value is negative, the timeout time has already
+ * elapsed.
+ *
+ * The start time is stored in progress.t_startsingle - as set with
+ * Curl_pgrsTime(..., TIMER_STARTSINGLE);
+ *
+ * If 'nowp' is non-NULL, it points to the current time.
+ * 'duringconnect' is FALSE if not during a connect, as then of course the
+ * connect timeout is not taken into account!
+ *
+ * @unittest: 1303
+ */
+long Curl_timeleft(struct SessionHandle *data,
+                   struct timeval *nowp,
+                   bool duringconnect)
+{
+  int timeout_set = 0;
+  long timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0;
+  struct timeval now;
+
+  /* if a timeout is set, use the most restrictive one */
+
+  if(data->set.timeout > 0)
+    timeout_set |= 1;
+  if(duringconnect && (data->set.connecttimeout > 0))
+    timeout_set |= 2;
+
+  switch (timeout_set) {
+  case 1:
+    timeout_ms = data->set.timeout;
+    break;
+  case 2:
+    timeout_ms = data->set.connecttimeout;
+    break;
+  case 3:
+    if(data->set.timeout < data->set.connecttimeout)
+      timeout_ms = data->set.timeout;
+    else
+      timeout_ms = data->set.connecttimeout;
+    break;
+  default:
+    /* use the default */
+    if(!duringconnect)
+      /* if we're not during connect, there's no default timeout so if we're
+         at zero we better just return zero and not make it a negative number
+         by the math below */
+      return 0;
+    break;
+  }
+
+  if(!nowp) {
+    now = Curl_tvnow();
+    nowp = &now;
+  }
+
+  /* subtract elapsed time */
+  if(duringconnect)
+    /* since this most recent connect started */
+    timeout_ms -= Curl_tvdiff(*nowp, data->progress.t_startsingle);
+  else
+    /* since the entire operation started */
+    timeout_ms -= Curl_tvdiff(*nowp, data->progress.t_startop);
+  if(!timeout_ms)
+    /* avoid returning 0 as that means no timeout! */
+    return -1;
+
+  return timeout_ms;
+}
+
+static CURLcode bindlocal(struct connectdata *conn,
+                          curl_socket_t sockfd, int af, unsigned int scope)
+{
+  struct SessionHandle *data = conn->data;
+
+  struct Curl_sockaddr_storage sa;
+  struct sockaddr *sock = (struct sockaddr *)&sa;  /* bind to this address */
+  curl_socklen_t sizeof_sa = 0; /* size of the data sock points to */
+  struct sockaddr_in *si4 = (struct sockaddr_in *)&sa;
+#ifdef ENABLE_IPV6
+  struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)&sa;
+#endif
+
+  struct Curl_dns_entry *h=NULL;
+  unsigned short port = data->set.localport; /* use this port number, 0 for
+                                                "random" */
+  /* how many port numbers to try to bind to, increasing one at a time */
+  int portnum = data->set.localportrange;
+  const char *dev = data->set.str[STRING_DEVICE];
+  int error;
+
+  /*************************************************************
+   * Select device to bind socket to
+   *************************************************************/
+  if(!dev && !port)
+    /* no local kind of binding was requested */
+    return CURLE_OK;
+
+  memset(&sa, 0, sizeof(struct Curl_sockaddr_storage));
+
+  if(dev && (strlen(dev)<255) ) {
+    char myhost[256] = "";
+    int done = 0; /* -1 for error, 1 for address found */
+    bool is_interface = FALSE;
+    bool is_host = FALSE;
+    static const char *if_prefix = "if!";
+    static const char *host_prefix = "host!";
+
+    if(strncmp(if_prefix, dev, strlen(if_prefix)) == 0) {
+      dev += strlen(if_prefix);
+      is_interface = TRUE;
+    }
+    else if(strncmp(host_prefix, dev, strlen(host_prefix)) == 0) {
+      dev += strlen(host_prefix);
+      is_host = TRUE;
+    }
+
+    /* interface */
+    if(!is_host) {
+      switch(Curl_if2ip(af, scope, conn->scope_id, dev,
+                        myhost, sizeof(myhost))) {
+        case IF2IP_NOT_FOUND:
+          if(is_interface) {
+            /* Do not fall back to treating it as a host name */
+            failf(data, "Couldn't bind to interface '%s'", dev);
+            return CURLE_INTERFACE_FAILED;
+          }
+          break;
+        case IF2IP_AF_NOT_SUPPORTED:
+          /* Signal the caller to try another address family if available */
+          return CURLE_UNSUPPORTED_PROTOCOL;
+        case IF2IP_FOUND:
+          is_interface = TRUE;
+          /*
+           * We now have the numerical IP address in the 'myhost' buffer
+           */
+          infof(data, "Local Interface %s is ip %s using address family %i\n",
+                dev, myhost, af);
+          done = 1;
+
+#ifdef SO_BINDTODEVICE
+          /* I am not sure any other OSs than Linux that provide this feature,
+           * and at the least I cannot test. --Ben
+           *
+           * This feature allows one to tightly bind the local socket to a
+           * particular interface.  This will force even requests to other
+           * local interfaces to go out the external interface.
+           *
+           *
+           * Only bind to the interface when specified as interface, not just
+           * as a hostname or ip address.
+           */
+          if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
+                        dev, (curl_socklen_t)strlen(dev)+1) != 0) {
+            error = SOCKERRNO;
+            infof(data, "SO_BINDTODEVICE %s failed with errno %d: %s;"
+                  " will do regular bind\n",
+                  dev, error, Curl_strerror(conn, error));
+            /* This is typically "errno 1, error: Operation not permitted" if
+               you're not running as root or another suitable privileged
+               user */
+          }
+#endif
+          break;
+      }
+    }
+    if(!is_interface) {
+      /*
+       * This was not an interface, resolve the name as a host name
+       * or IP number
+       *
+       * Temporarily force name resolution to use only the address type
+       * of the connection. The resolve functions should really be changed
+       * to take a type parameter instead.
+       */
+      long ipver = conn->ip_version;
+      int rc;
+
+      if(af == AF_INET)
+        conn->ip_version = CURL_IPRESOLVE_V4;
+#ifdef ENABLE_IPV6
+      else if(af == AF_INET6)
+        conn->ip_version = CURL_IPRESOLVE_V6;
+#endif
+
+      rc = Curl_resolv(conn, dev, 0, &h);
+      if(rc == CURLRESOLV_PENDING)
+        (void)Curl_resolver_wait_resolv(conn, &h);
+      conn->ip_version = ipver;
+
+      if(h) {
+        /* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */
+        Curl_printable_address(h->addr, myhost, sizeof(myhost));
+        infof(data, "Name '%s' family %i resolved to '%s' family %i\n",
+              dev, af, myhost, h->addr->ai_family);
+        Curl_resolv_unlock(data, h);
+        done = 1;
+      }
+      else {
+        /*
+         * provided dev was no interface (or interfaces are not supported
+         * e.g. solaris) no ip address and no domain we fail here
+         */
+        done = -1;
+      }
+    }
+
+    if(done > 0) {
+#ifdef ENABLE_IPV6
+      /* IPv6 address */
+      if(af == AF_INET6) {
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+        char *scope_ptr = strchr(myhost, '%');
+        if(scope_ptr)
+          *(scope_ptr++) = 0;
+#endif
+        if(Curl_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0) {
+          si6->sin6_family = AF_INET6;
+          si6->sin6_port = htons(port);
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+          if(scope_ptr)
+            /* The "myhost" string either comes from Curl_if2ip or from
+               Curl_printable_address. The latter returns only numeric scope
+               IDs and the former returns none at all.  So the scope ID, if
+               present, is known to be numeric */
+            si6->sin6_scope_id = atoi(scope_ptr);
+#endif
+        }
+        sizeof_sa = sizeof(struct sockaddr_in6);
+      }
+      else
+#endif
+      /* IPv4 address */
+      if((af == AF_INET) &&
+         (Curl_inet_pton(AF_INET, myhost, &si4->sin_addr) > 0)) {
+        si4->sin_family = AF_INET;
+        si4->sin_port = htons(port);
+        sizeof_sa = sizeof(struct sockaddr_in);
+      }
+    }
+
+    if(done < 1) {
+      failf(data, "Couldn't bind to '%s'", dev);
+      return CURLE_INTERFACE_FAILED;
+    }
+  }
+  else {
+    /* no device was given, prepare sa to match af's needs */
+#ifdef ENABLE_IPV6
+    if(af == AF_INET6) {
+      si6->sin6_family = AF_INET6;
+      si6->sin6_port = htons(port);
+      sizeof_sa = sizeof(struct sockaddr_in6);
+    }
+    else
+#endif
+    if(af == AF_INET) {
+      si4->sin_family = AF_INET;
+      si4->sin_port = htons(port);
+      sizeof_sa = sizeof(struct sockaddr_in);
+    }
+  }
+
+  for(;;) {
+    if(bind(sockfd, sock, sizeof_sa) >= 0) {
+      /* we succeeded to bind */
+      struct Curl_sockaddr_storage add;
+      curl_socklen_t size = sizeof(add);
+      memset(&add, 0, sizeof(struct Curl_sockaddr_storage));
+      if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) {
+        data->state.os_errno = error = SOCKERRNO;
+        failf(data, "getsockname() failed with errno %d: %s",
+              error, Curl_strerror(conn, error));
+        return CURLE_INTERFACE_FAILED;
+      }
+      infof(data, "Local port: %hu\n", port);
+      conn->bits.bound = TRUE;
+      return CURLE_OK;
+    }
+
+    if(--portnum > 0) {
+      infof(data, "Bind to local port %hu failed, trying next\n", port);
+      port++; /* try next port */
+      /* We re-use/clobber the port variable here below */
+      if(sock->sa_family == AF_INET)
+        si4->sin_port = ntohs(port);
+#ifdef ENABLE_IPV6
+      else
+        si6->sin6_port = ntohs(port);
+#endif
+    }
+    else
+      break;
+  }
+
+  data->state.os_errno = error = SOCKERRNO;
+  failf(data, "bind failed with errno %d: %s",
+        error, Curl_strerror(conn, error));
+
+  return CURLE_INTERFACE_FAILED;
+}
+
+/*
+ * verifyconnect() returns TRUE if the connect really has happened.
+ */
+static bool verifyconnect(curl_socket_t sockfd, int *error)
+{
+  bool rc = TRUE;
+#ifdef SO_ERROR
+  int err = 0;
+  curl_socklen_t errSize = sizeof(err);
+
+#if 0//def WIN32
+  /*
+   * In October 2003 we effectively nullified this function on Windows due to
+   * problems with it using all CPU in multi-threaded cases.
+   *
+   * In May 2004, we bring it back to offer more info back on connect failures.
+   * Gisle Vanem could reproduce the former problems with this function, but
+   * could avoid them by adding this SleepEx() call below:
+   *
+   *    "I don't have Rational Quantify, but the hint from his post was
+   *    ntdll::NtRemoveIoCompletion(). So I'd assume the SleepEx (or maybe
+   *    just Sleep(0) would be enough?) would release whatever
+   *    mutex/critical-section the ntdll call is waiting on.
+   *
+   *    Someone got to verify this on Win-NT 4.0, 2000."
+   */
+
+#ifdef _WIN32_WCE
+  Sleep(0);
+#else
+  SleepEx(0, FALSE);
+#endif
+
+#endif
+
+  if(0 != getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&err, &errSize))
+    err = SOCKERRNO;
+#ifdef _WIN32_WCE
+  /* Old WinCE versions don't support SO_ERROR */
+  if(WSAENOPROTOOPT == err) {
+    SET_SOCKERRNO(0);
+    err = 0;
+  }
+#endif
+#ifdef __minix
+  /* Minix 3.1.x doesn't support getsockopt on UDP sockets */
+  if(EBADIOCTL == err) {
+    SET_SOCKERRNO(0);
+    err = 0;
+  }
+#endif
+  if((0 == err) || (EISCONN == err))
+    /* we are connected, awesome! */
+    rc = TRUE;
+  else
+    /* This wasn't a successful connect */
+    rc = FALSE;
+  if(error)
+    *error = err;
+#else
+  (void)sockfd;
+  if(error)
+    *error = SOCKERRNO;
+#endif
+  return rc;
+}
+
+/* Used within the multi interface. Try next IP address, return TRUE if no
+   more address exists or error */
+static CURLcode trynextip(struct connectdata *conn,
+                          int sockindex,
+                          int tempindex)
+{
+  const int other = tempindex ^ 1;
+  CURLcode result = CURLE_COULDNT_CONNECT;
+
+  /* First clean up after the failed socket.
+     Don't close it yet to ensure that the next IP's socket gets a different
+     file descriptor, which can prevent bugs when the curl_multi_socket_action
+     interface is used with certain select() replacements such as kqueue. */
+  curl_socket_t fd_to_close = conn->tempsock[tempindex];
+  conn->tempsock[tempindex] = CURL_SOCKET_BAD;
+
+  if(sockindex == FIRSTSOCKET) {
+    Curl_addrinfo *ai = NULL;
+    int family = AF_UNSPEC;
+
+    if(conn->tempaddr[tempindex]) {
+      /* find next address in the same protocol family */
+      family = conn->tempaddr[tempindex]->ai_family;
+      ai = conn->tempaddr[tempindex]->ai_next;
+    }
+#ifdef ENABLE_IPV6
+    else if(conn->tempaddr[0]) {
+      /* happy eyeballs - try the other protocol family */
+      int firstfamily = conn->tempaddr[0]->ai_family;
+      family = (firstfamily == AF_INET) ? AF_INET6 : AF_INET;
+      ai = conn->tempaddr[0]->ai_next;
+    }
+#endif
+
+    while(ai) {
+      if(conn->tempaddr[other]) {
+        /* we can safely skip addresses of the other protocol family */
+        while(ai && ai->ai_family != family)
+          ai = ai->ai_next;
+      }
+
+      if(ai) {
+        result = singleipconnect(conn, ai, &conn->tempsock[tempindex]);
+        if(result == CURLE_COULDNT_CONNECT) {
+          ai = ai->ai_next;
+          continue;
+        }
+
+        conn->tempaddr[tempindex] = ai;
+      }
+      break;
+    }
+  }
+
+  if(fd_to_close != CURL_SOCKET_BAD)
+    Curl_closesocket(conn, fd_to_close);
+
+  return result;
+}
+
+/* Copies connection info into the session handle to make it available
+   when the session handle is no longer associated with a connection. */
+void Curl_persistconninfo(struct connectdata *conn)
+{
+  memcpy(conn->data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN);
+  memcpy(conn->data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN);
+  conn->data->info.conn_primary_port = conn->primary_port;
+  conn->data->info.conn_local_port = conn->local_port;
+}
+
+/* retrieves ip address and port from a sockaddr structure */
+static bool getaddressinfo(struct sockaddr* sa, char* addr,
+                           long* port)
+{
+  unsigned short us_port;
+  struct sockaddr_in* si = NULL;
+#ifdef ENABLE_IPV6
+  struct sockaddr_in6* si6 = NULL;
+#endif
+#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
+  struct sockaddr_un* su = NULL;
+#endif
+
+  switch (sa->sa_family) {
+    case AF_INET:
+      si = (struct sockaddr_in*)(void*) sa;
+      if(Curl_inet_ntop(sa->sa_family, &si->sin_addr,
+                        addr, MAX_IPADR_LEN)) {
+        us_port = ntohs(si->sin_port);
+        *port = us_port;
+        return TRUE;
+      }
+      break;
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      si6 = (struct sockaddr_in6*)(void*) sa;
+      if(Curl_inet_ntop(sa->sa_family, &si6->sin6_addr,
+                        addr, MAX_IPADR_LEN)) {
+        us_port = ntohs(si6->sin6_port);
+        *port = us_port;
+        return TRUE;
+      }
+      break;
+#endif
+#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
+    case AF_UNIX:
+      su = (struct sockaddr_un*)sa;
+      snprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
+      *port = 0;
+      return TRUE;
+#endif
+    default:
+      break;
+  }
+
+  addr[0] = '\0';
+  *port = 0;
+
+  return FALSE;
+}
+
+/* retrieves the start/end point information of a socket of an established
+   connection */
+void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
+{
+  curl_socklen_t len;
+  struct Curl_sockaddr_storage ssrem;
+  struct Curl_sockaddr_storage ssloc;
+  struct SessionHandle *data = conn->data;
+
+  if(conn->socktype == SOCK_DGRAM)
+    /* there's no connection! */
+    return;
+
+  if(!conn->bits.reuse) {
+    int error;
+
+    len = sizeof(struct Curl_sockaddr_storage);
+    if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) {
+      error = SOCKERRNO;
+      failf(data, "getpeername() failed with errno %d: %s",
+            error, Curl_strerror(conn, error));
+      return;
+    }
+
+    len = sizeof(struct Curl_sockaddr_storage);
+    memset(&ssloc, 0, sizeof(ssloc));
+    if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
+      error = SOCKERRNO;
+      failf(data, "getsockname() failed with errno %d: %s",
+            error, Curl_strerror(conn, error));
+      return;
+    }
+
+    if(!getaddressinfo((struct sockaddr*)&ssrem,
+                        conn->primary_ip, &conn->primary_port)) {
+      error = ERRNO;
+      failf(data, "ssrem inet_ntop() failed with errno %d: %s",
+            error, Curl_strerror(conn, error));
+      return;
+    }
+    memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
+
+    if(!getaddressinfo((struct sockaddr*)&ssloc,
+                       conn->local_ip, &conn->local_port)) {
+      error = ERRNO;
+      failf(data, "ssloc inet_ntop() failed with errno %d: %s",
+            error, Curl_strerror(conn, error));
+      return;
+    }
+
+  }
+
+  /* persist connection info in session handle */
+  Curl_persistconninfo(conn);
+}
+
+/*
+ * Curl_is_connected() checks if the socket has connected.
+ */
+
+CURLcode Curl_is_connected(struct connectdata *conn,
+                           int sockindex,
+                           bool *connected)
+{
+  struct SessionHandle *data = conn->data;
+  CURLcode result = CURLE_OK;
+  long allow;
+  int error = 0;
+  struct timeval now;
+  int rc;
+  int i;
+
+  DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
+
+  *connected = FALSE; /* a very negative world view is best */
+
+  if(conn->bits.tcpconnect[sockindex]) {
+    /* we are connected already! */
+    *connected = TRUE;
+    return CURLE_OK;
+  }
+
+  now = Curl_tvnow();
+
+  /* figure out how long time we have left to connect */
+  allow = Curl_timeleft(data, &now, TRUE);
+
+  if(allow < 0) {
+    /* time-out, bail out, go home */
+    failf(data, "Connection time-out");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  for(i=0; i<2; i++) {
+    const int other = i ^ 1;
+    if(conn->tempsock[i] == CURL_SOCKET_BAD)
+      continue;
+
+#ifdef mpeix
+    /* Call this function once now, and ignore the results. We do this to
+       "clear" the error state on the socket so that we can later read it
+       reliably. This is reported necessary on the MPE/iX operating system. */
+    (void)verifyconnect(conn->tempsock[i], NULL);
+#endif
+
+    /* check socket for connect */
+    rc = Curl_socket_ready(CURL_SOCKET_BAD, conn->tempsock[i], 0);
+
+    if(rc == 0) { /* no connection yet */
+      if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
+        infof(data, "After %ldms connect time, move on!\n",
+              conn->timeoutms_per_addr);
+        error = ETIMEDOUT;
+      }
+
+      /* should we try another protocol family? */
+      if(i == 0 && conn->tempaddr[1] == NULL &&
+         curlx_tvdiff(now, conn->connecttime) >= HAPPY_EYEBALLS_TIMEOUT) {
+        trynextip(conn, sockindex, 1);
+      }
+    }
+    else if(rc == CURL_CSELECT_OUT) {
+      if(verifyconnect(conn->tempsock[i], &error)) {
+        /* we are connected with TCP, awesome! */
+
+        /* use this socket from now on */
+        conn->sock[sockindex] = conn->tempsock[i];
+        conn->ip_addr = conn->tempaddr[i];
+        conn->tempsock[i] = CURL_SOCKET_BAD;
+
+        /* close the other socket, if open */
+        if(conn->tempsock[other] != CURL_SOCKET_BAD) {
+          Curl_closesocket(conn, conn->tempsock[other]);
+          conn->tempsock[other] = CURL_SOCKET_BAD;
+        }
+
+        /* see if we need to do any proxy magic first once we connected */
+        result = Curl_connected_proxy(conn, sockindex);
+        if(result)
+          return result;
+
+        conn->bits.tcpconnect[sockindex] = TRUE;
+
+        *connected = TRUE;
+        if(sockindex == FIRSTSOCKET)
+          Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
+        Curl_updateconninfo(conn, conn->sock[sockindex]);
+        Curl_verboseconnect(conn);
+
+        return CURLE_OK;
+      }
+      else
+        infof(data, "Connection failed\n");
+    }
+    else if(rc & CURL_CSELECT_ERR)
+      (void)verifyconnect(conn->tempsock[i], &error);
+
+    /*
+     * The connection failed here, we should attempt to connect to the "next
+     * address" for the given host. But first remember the latest error.
+     */
+    if(error) {
+      data->state.os_errno = error;
+      SET_SOCKERRNO(error);
+      if(conn->tempaddr[i]) {
+        CURLcode status;
+        char ipaddress[MAX_IPADR_LEN];
+        Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN);
+        infof(data, "connect to %s port %ld failed: %s\n",
+              ipaddress, conn->port, Curl_strerror(conn, error));
+
+        conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
+                                   allow : allow / 2;
+
+        status = trynextip(conn, sockindex, i);
+        if(status != CURLE_COULDNT_CONNECT
+            || conn->tempsock[other] == CURL_SOCKET_BAD)
+          /* the last attempt failed and no other sockets remain open */
+          result = status;
+      }
+    }
+  }
+
+  if(result) {
+    /* no more addresses to try */
+
+    /* if the first address family runs out of addresses to try before
+       the happy eyeball timeout, go ahead and try the next family now */
+    if(conn->tempaddr[1] == NULL) {
+      result = trynextip(conn, sockindex, 1);
+      if(!result)
+        return result;
+    }
+
+    failf(data, "Failed to connect to %s port %ld: %s",
+          conn->bits.proxy?conn->proxy.name:conn->host.name,
+          conn->port, Curl_strerror(conn, error));
+  }
+
+  return result;
+}
+
+void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
+{
+#ifdef TCP_NODELAY
+  struct SessionHandle *data= conn->data;
+  curl_socklen_t onoff = (curl_socklen_t) 1;
+  int level = IPPROTO_TCP;
+
+#if 0
+  /* The use of getprotobyname() is disabled since it isn't thread-safe on
+     numerous systems. On these getprotobyname_r() should be used instead, but
+     that exists in at least one 4 arg version and one 5 arg version, and
+     since the proto number rarely changes anyway we now just use the hard
+     coded number. The "proper" fix would need a configure check for the
+     correct function much in the same style the gethostbyname_r versions are
+     detected. */
+  struct protoent *pe = getprotobyname("tcp");
+  if(pe)
+    level = pe->p_proto;
+#endif
+
+  if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
+                sizeof(onoff)) < 0)
+    infof(data, "Could not set TCP_NODELAY: %s\n",
+          Curl_strerror(conn, SOCKERRNO));
+  else
+    infof(data, "TCP_NODELAY set\n");
+#else
+  (void)conn;
+  (void)sockfd;
+#endif
+}
+
+#ifdef SO_NOSIGPIPE
+/* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when
+   sending data to a dead peer (instead of relying on the 4th argument to send
+   being MSG_NOSIGNAL). Possibly also existing and in use on other BSD
+   systems? */
+static void nosigpipe(struct connectdata *conn,
+                      curl_socket_t sockfd)
+{
+  struct SessionHandle *data= conn->data;
+  int onoff = 1;
+  if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
+                sizeof(onoff)) < 0)
+    infof(data, "Could not set SO_NOSIGPIPE: %s\n",
+          Curl_strerror(conn, SOCKERRNO));
+}
+#else
+#define nosigpipe(x,y) Curl_nop_stmt
+#endif
+
+#ifdef USE_WINSOCK
+/* When you run a program that uses the Windows Sockets API, you may
+   experience slow performance when you copy data to a TCP server.
+
+   https://support.microsoft.com/kb/823764
+
+   Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
+   Buffer Size
+
+   The problem described in this knowledge-base is applied only to pre-Vista
+   Windows.  Following function trying to detect OS version and skips
+   SO_SNDBUF adjustment for Windows Vista and above.
+*/
+#define DETECT_OS_NONE 0
+#define DETECT_OS_PREVISTA 1
+#define DETECT_OS_VISTA_OR_LATER 2
+
+void Curl_sndbufset(curl_socket_t sockfd)
+{
+  int val = CURL_MAX_WRITE_SIZE + 32;
+  int curval = 0;
+  int curlen = sizeof(curval);
+  DWORD majorVersion = 6;
+
+  static int detectOsState = DETECT_OS_NONE;
+
+  if(detectOsState == DETECT_OS_NONE) {
+#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
+    (_WIN32_WINNT < _WIN32_WINNT_WIN2K)
+    OSVERSIONINFO osver;
+
+    memset(&osver, 0, sizeof(osver));
+    osver.dwOSVersionInfoSize = sizeof(osver);
+
+    detectOsState = DETECT_OS_PREVISTA;
+    if(GetVersionEx(&osver)) {
+      if(osver.dwMajorVersion >= majorVersion)
+        detectOsState = DETECT_OS_VISTA_OR_LATER;
+    }
+#else
+    ULONGLONG cm;
+    OSVERSIONINFOEX osver;
+
+    memset(&osver, 0, sizeof(osver));
+    osver.dwOSVersionInfoSize = sizeof(osver);
+    osver.dwMajorVersion = majorVersion;
+
+    cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
+
+    if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
+                                  VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
+                         cm))
+      detectOsState = DETECT_OS_VISTA_OR_LATER;
+    else
+      detectOsState = DETECT_OS_PREVISTA;
+#endif
+  }
+
+  if(detectOsState == DETECT_OS_VISTA_OR_LATER)
+    return;
+
+  if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0)
+    if(curval > val)
+      return;
+
+  setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&val, sizeof(val));
+}
+#endif
+
+/*
+ * singleipconnect()
+ *
+ * Note that even on connect fail it returns CURLE_OK, but with 'sock' set to
+ * CURL_SOCKET_BAD. Other errors will however return proper errors.
+ *
+ * singleipconnect() connects to the given IP only, and it may return without
+ * having connected.
+ */
+static CURLcode singleipconnect(struct connectdata *conn,
+                                const Curl_addrinfo *ai,
+                                curl_socket_t *sockp)
+{
+  struct Curl_sockaddr_ex addr;
+  int rc;
+  int error = 0;
+  bool isconnected = FALSE;
+  struct SessionHandle *data = conn->data;
+  curl_socket_t sockfd;
+  CURLcode result;
+  char ipaddress[MAX_IPADR_LEN];
+  long port;
+  bool is_tcp;
+
+  *sockp = CURL_SOCKET_BAD;
+
+  result = Curl_socket(conn, ai, &addr, &sockfd);
+  if(result)
+    /* Failed to create the socket, but still return OK since we signal the
+       lack of socket as well. This allows the parent function to keep looping
+       over alternative addresses/socket families etc. */
+    return CURLE_OK;
+
+  /* store remote address and port used in this connection attempt */
+  if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
+                     ipaddress, &port)) {
+    /* malformed address or bug in inet_ntop, try next address */
+    error = ERRNO;
+    failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
+          error, Curl_strerror(conn, error));
+    Curl_closesocket(conn, sockfd);
+    return CURLE_OK;
+  }
+  infof(data, "  Trying %s...\n", ipaddress);
+
+#ifdef ENABLE_IPV6
+  is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) &&
+    addr.socktype == SOCK_STREAM;
+#else
+  is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM;
+#endif
+  if(is_tcp && data->set.tcp_nodelay)
+    Curl_tcpnodelay(conn, sockfd);
+
+  nosigpipe(conn, sockfd);
+
+  Curl_sndbufset(sockfd);
+
+  if(is_tcp && data->set.tcp_keepalive)
+    tcpkeepalive(data, sockfd);
+
+  if(data->set.fsockopt) {
+    /* activate callback for setting socket options */
+    error = data->set.fsockopt(data->set.sockopt_client,
+                               sockfd,
+                               CURLSOCKTYPE_IPCXN);
+
+    if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
+      isconnected = TRUE;
+    else if(error) {
+      Curl_closesocket(conn, sockfd); /* close the socket and bail out */
+      return CURLE_ABORTED_BY_CALLBACK;
+    }
+  }
+
+  /* possibly bind the local end to an IP, interface or port */
+  if(addr.family == AF_INET
+#ifdef ENABLE_IPV6
+     || addr.family == AF_INET6
+#endif
+    ) {
+    result = bindlocal(conn, sockfd, addr.family,
+                       Curl_ipv6_scope((struct sockaddr*)&addr.sa_addr));
+    if(result) {
+      Curl_closesocket(conn, sockfd); /* close socket and bail out */
+      if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+        /* The address family is not supported on this interface.
+           We can continue trying addresses */
+        return CURLE_COULDNT_CONNECT;
+      }
+      return result;
+    }
+  }
+
+  /* set socket non-blocking */
+  (void)curlx_nonblock(sockfd, TRUE);
+
+  conn->connecttime = Curl_tvnow();
+  if(conn->num_addr > 1)
+    Curl_expire_latest(data, conn->timeoutms_per_addr);
+
+  /* Connect TCP sockets, bind UDP */
+  if(!isconnected && (conn->socktype == SOCK_STREAM)) {
+    rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
+    if(-1 == rc)
+      error = SOCKERRNO;
+  }
+  else {
+    *sockp = sockfd;
+    return CURLE_OK;
+  }
+
+#ifdef ENABLE_IPV6
+  conn->bits.ipv6 = (addr.family == AF_INET6)?TRUE:FALSE;
+#endif
+
+  if(-1 == rc) {
+    switch(error) {
+    case EINPROGRESS:
+    case EWOULDBLOCK:
+#if defined(EAGAIN)
+#if (EAGAIN) != (EWOULDBLOCK)
+      /* On some platforms EAGAIN and EWOULDBLOCK are the
+       * same value, and on others they are different, hence
+       * the odd #if
+       */
+    case EAGAIN:
+#endif
+#endif
+      result = CURLE_OK;
+      break;
+
+    default:
+      /* unknown error, fallthrough and try another address! */
+      infof(data, "Immediate connect fail for %s: %s\n",
+            ipaddress, Curl_strerror(conn, error));
+      data->state.os_errno = error;
+
+      /* connect failed */
+      Curl_closesocket(conn, sockfd);
+      result = CURLE_COULDNT_CONNECT;
+    }
+  }
+
+  if(!result)
+    *sockp = sockfd;
+
+  return result;
+}
+
+/*
+ * TCP connect to the given host with timeout, proxy or remote doesn't matter.
+ * There might be more than one IP address to try out. Fill in the passed
+ * pointer with the connected socket.
+ */
+
+CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
+                          const struct Curl_dns_entry *remotehost)
+{
+  struct SessionHandle *data = conn->data;
+  struct timeval before = Curl_tvnow();
+  CURLcode result = CURLE_COULDNT_CONNECT;
+
+  long timeout_ms = Curl_timeleft(data, &before, TRUE);
+
+  if(timeout_ms < 0) {
+    /* a precaution, no need to continue if time already is up */
+    failf(data, "Connection time-out");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  conn->num_addr = Curl_num_addresses(remotehost->addr);
+  conn->tempaddr[0] = remotehost->addr;
+  conn->tempaddr[1] = NULL;
+  conn->tempsock[0] = CURL_SOCKET_BAD;
+  conn->tempsock[1] = CURL_SOCKET_BAD;
+  Curl_expire(conn->data, HAPPY_EYEBALLS_TIMEOUT);
+
+  /* Max time for the next connection attempt */
+  conn->timeoutms_per_addr =
+    conn->tempaddr[0]->ai_next == NULL ? timeout_ms : timeout_ms / 2;
+
+  /* start connecting to first IP */
+  while(conn->tempaddr[0]) {
+    result = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0]));
+    if(!result)
+      break;
+    conn->tempaddr[0] = conn->tempaddr[0]->ai_next;
+  }
+
+  if(conn->tempsock[0] == CURL_SOCKET_BAD) {
+    if(!result)
+      result = CURLE_COULDNT_CONNECT;
+    return result;
+  }
+
+  data->info.numconnects++; /* to track the number of connections made */
+
+  return CURLE_OK;
+}
+
+struct connfind {
+  struct connectdata *tofind;
+  bool found;
+};
+
+static int conn_is_conn(struct connectdata *conn, void *param)
+{
+  struct connfind *f = (struct connfind *)param;
+  if(conn == f->tofind) {
+    f->found = TRUE;
+    return 1;
+  }
+  return 0;
+}
+
+/*
+ * Used to extract socket and connectdata struct for the most recent
+ * transfer on the given SessionHandle.
+ *
+ * The returned socket will be CURL_SOCKET_BAD in case of failure!
+ */
+curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
+                                  struct connectdata **connp)
+{
+  curl_socket_t sockfd;
+
+  DEBUGASSERT(data);
+
+  /* this works for an easy handle:
+   * - that has been used for curl_easy_perform()
+   * - that is associated with a multi handle, and whose connection
+   *   was detached with CURLOPT_CONNECT_ONLY
+   */
+  if(data->state.lastconnect && (data->multi_easy || data->multi)) {
+    struct connectdata *c = data->state.lastconnect;
+    struct connfind find;
+    find.tofind = data->state.lastconnect;
+    find.found = FALSE;
+
+    Curl_conncache_foreach(data->multi_easy?
+                           &data->multi_easy->conn_cache:
+                           &data->multi->conn_cache, &find, conn_is_conn);
+
+    if(!find.found) {
+      data->state.lastconnect = NULL;
+      return CURL_SOCKET_BAD;
+    }
+
+    if(connp)
+      /* only store this if the caller cares for it */
+      *connp = c;
+    sockfd = c->sock[FIRSTSOCKET];
+    /* we have a socket connected, let's determine if the server shut down */
+    /* determine if ssl */
+    if(c->ssl[FIRSTSOCKET].use) {
+      /* use the SSL context */
+      if(!Curl_ssl_check_cxn(c))
+        return CURL_SOCKET_BAD;   /* FIN received */
+    }
+/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
+#ifdef MSG_PEEK
+    else if(sockfd != CURL_SOCKET_BAD) {
+      /* use the socket */
+      char buf;
+      if(recv((RECV_TYPE_ARG1)sockfd, (RECV_TYPE_ARG2)&buf,
+              (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
+        return CURL_SOCKET_BAD;   /* FIN received */
+      }
+    }
+#endif
+  }
+  else
+    return CURL_SOCKET_BAD;
+
+  return sockfd;
+}
+
+/*
+ * Close a socket.
+ *
+ * 'conn' can be NULL, beware!
+ */
+int Curl_closesocket(struct connectdata *conn,
+                      curl_socket_t sock)
+{
+  if(conn && conn->fclosesocket) {
+    if((sock == conn->sock[SECONDARYSOCKET]) &&
+       conn->sock_accepted[SECONDARYSOCKET])
+      /* if this socket matches the second socket, and that was created with
+         accept, then we MUST NOT call the callback but clear the accepted
+         status */
+      conn->sock_accepted[SECONDARYSOCKET] = FALSE;
+    else {
+      Curl_multi_closed(conn, sock);
+      return conn->fclosesocket(conn->closesocket_client, sock);
+    }
+  }
+
+  if(conn)
+    /* tell the multi-socket code about this */
+    Curl_multi_closed(conn, sock);
+
+  sclose(sock);
+
+  return 0;
+}
+
+/*
+ * Create a socket based on info from 'conn' and 'ai'.
+ *
+ * 'addr' should be a pointer to the correct struct to get data back, or NULL.
+ * 'sockfd' must be a pointer to a socket descriptor.
+ *
+ * If the open socket callback is set, used that!
+ *
+ */
+CURLcode Curl_socket(struct connectdata *conn,
+                     const Curl_addrinfo *ai,
+                     struct Curl_sockaddr_ex *addr,
+                     curl_socket_t *sockfd)
+{
+  struct SessionHandle *data = conn->data;
+  struct Curl_sockaddr_ex dummy;
+
+  if(!addr)
+    /* if the caller doesn't want info back, use a local temp copy */
+    addr = &dummy;
+
+  /*
+   * The Curl_sockaddr_ex structure is basically libcurl's external API
+   * curl_sockaddr structure with enough space available to directly hold
+   * any protocol-specific address structures. The variable declared here
+   * will be used to pass / receive data to/from the fopensocket callback
+   * if this has been set, before that, it is initialized from parameters.
+   */
+
+  addr->family = ai->ai_family;
+  addr->socktype = conn->socktype;
+  addr->protocol = conn->socktype==SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol;
+  addr->addrlen = ai->ai_addrlen;
+
+  if(addr->addrlen > sizeof(struct Curl_sockaddr_storage))
+     addr->addrlen = sizeof(struct Curl_sockaddr_storage);
+  memcpy(&addr->sa_addr, ai->ai_addr, addr->addrlen);
+
+  if(data->set.fopensocket)
+   /*
+    * If the opensocket callback is set, all the destination address
+    * information is passed to the callback. Depending on this information the
+    * callback may opt to abort the connection, this is indicated returning
+    * CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When
+    * the callback returns a valid socket the destination address information
+    * might have been changed and this 'new' address will actually be used
+    * here to connect.
+    */
+    *sockfd = data->set.fopensocket(data->set.opensocket_client,
+                                    CURLSOCKTYPE_IPCXN,
+                                    (struct curl_sockaddr *)addr);
+  else
+    /* opensocket callback not set, so simply create the socket now */
+    *sockfd = socket(addr->family, addr->socktype, addr->protocol);
+
+  if(*sockfd == CURL_SOCKET_BAD)
+    /* no socket, no connection */
+    return CURLE_COULDNT_CONNECT;
+
+#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
+  if(conn->scope_id && (addr->family == AF_INET6)) {
+    struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
+    sa6->sin6_scope_id = conn->scope_id;
+  }
+#endif
+
+  return CURLE_OK;
+
+}
+
+#ifdef CURLDEBUG
+/*
+ * Curl_conncontrol() is used to set the conn->bits.close bit on or off. It
+ * MUST be called with the connclose() or connkeep() macros with a stated
+ * reason. The reason is only shown in debug builds but helps to figure out
+ * decision paths when connections are or aren't re-used as expected.
+ */
+void Curl_conncontrol(struct connectdata *conn, bool closeit,
+                      const char *reason)
+{
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) reason;
+#endif
+  if(closeit != conn->bits.close) {
+    infof(conn->data, "Marked for [%s]: %s\n", closeit?"closure":"keep alive",
+          reason);
+
+    conn->bits.close = closeit; /* the only place in the source code that
+                                   should assign this bit */
+  }
+}
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/lib/connect.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/connect.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/connect.h	(revision 164)
@@ -0,0 +1,124 @@
+#ifndef HEADER_CURL_CONNECT_H
+#define HEADER_CURL_CONNECT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
+#include "sockaddr.h"
+
+CURLcode Curl_is_connected(struct connectdata *conn,
+                           int sockindex,
+                           bool *connected);
+
+CURLcode Curl_connecthost(struct connectdata *conn,
+                          const struct Curl_dns_entry *host);
+
+/* generic function that returns how much time there's left to run, according
+   to the timeouts set */
+long Curl_timeleft(struct SessionHandle *data,
+                   struct timeval *nowp,
+                   bool duringconnect);
+
+#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
+#define HAPPY_EYEBALLS_TIMEOUT     200 /* milliseconds to wait between
+                                          IPv4/IPv6 connection attempts */
+
+/*
+ * Used to extract socket and connectdata struct for the most recent
+ * transfer on the given SessionHandle.
+ *
+ * The returned socket will be CURL_SOCKET_BAD in case of failure!
+ */
+curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
+                                  struct connectdata **connp);
+
+#ifdef USE_WINSOCK
+/* When you run a program that uses the Windows Sockets API, you may
+   experience slow performance when you copy data to a TCP server.
+
+   https://support.microsoft.com/kb/823764
+
+   Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
+   Buffer Size
+
+*/
+void Curl_sndbufset(curl_socket_t sockfd);
+#else
+#define Curl_sndbufset(y) Curl_nop_stmt
+#endif
+
+void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
+void Curl_persistconninfo(struct connectdata *conn);
+int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
+
+/*
+ * The Curl_sockaddr_ex structure is basically libcurl's external API
+ * curl_sockaddr structure with enough space available to directly hold any
+ * protocol-specific address structures. The variable declared here will be
+ * used to pass / receive data to/from the fopensocket callback if this has
+ * been set, before that, it is initialized from parameters.
+ */
+struct Curl_sockaddr_ex {
+  int family;
+  int socktype;
+  int protocol;
+  unsigned int addrlen;
+  union {
+    struct sockaddr addr;
+    struct Curl_sockaddr_storage buff;
+  } _sa_ex_u;
+};
+#define sa_addr _sa_ex_u.addr
+
+/*
+ * Create a socket based on info from 'conn' and 'ai'.
+ *
+ * Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open
+ * socket callback is set, used that!
+ *
+ */
+CURLcode Curl_socket(struct connectdata *conn,
+                     const Curl_addrinfo *ai,
+                     struct Curl_sockaddr_ex *addr,
+                     curl_socket_t *sockfd);
+
+void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd);
+
+#ifdef CURLDEBUG
+/*
+ * Curl_connclose() sets the bit.close bit to TRUE with an explanation.
+ * Nothing else.
+ */
+void Curl_conncontrol(struct connectdata *conn,
+                      bool closeit,
+                      const char *reason);
+#define connclose(x,y) Curl_conncontrol(x,TRUE, y)
+#define connkeep(x,y) Curl_conncontrol(x, FALSE, y)
+#else /* if !CURLDEBUG */
+
+#define connclose(x,y) (x)->bits.close = TRUE
+#define connkeep(x,y) (x)->bits.close = FALSE
+
+#endif
+
+#endif /* HEADER_CURL_CONNECT_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/content_encoding.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/content_encoding.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/content_encoding.c	(revision 164)
@@ -0,0 +1,435 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_LIBZ
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "sendf.h"
+#include "content_encoding.h"
+#include "curl_memory.h"
+
+#include "memdebug.h"
+
+/* Comment this out if zlib is always going to be at least ver. 1.2.0.4
+   (doing so will reduce code size slightly). */
+#define OLD_ZLIB_SUPPORT 1
+
+#define DSIZ CURL_MAX_WRITE_SIZE /* buffer size for decompressed data */
+
+#define GZIP_MAGIC_0 0x1f
+#define GZIP_MAGIC_1 0x8b
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define RESERVED     0xE0 /* bits 5..7: reserved */
+
+static voidpf
+zalloc_cb(voidpf opaque, unsigned int items, unsigned int size)
+{
+  (void) opaque;
+  /* not a typo, keep it calloc() */
+  return (voidpf) calloc(items, size);
+}
+
+static void
+zfree_cb(voidpf opaque, voidpf ptr)
+{
+  (void) opaque;
+  free(ptr);
+}
+
+static CURLcode
+process_zlib_error(struct connectdata *conn, z_stream *z)
+{
+  struct SessionHandle *data = conn->data;
+  if(z->msg)
+    failf (data, "Error while processing content unencoding: %s",
+           z->msg);
+  else
+    failf (data, "Error while processing content unencoding: "
+           "Unknown failure within decompression software.");
+
+  return CURLE_BAD_CONTENT_ENCODING;
+}
+
+static CURLcode
+exit_zlib(z_stream *z, zlibInitState *zlib_init, CURLcode result)
+{
+  inflateEnd(z);
+  *zlib_init = ZLIB_UNINIT;
+  return result;
+}
+
+static CURLcode
+inflate_stream(struct connectdata *conn,
+               struct SingleRequest *k)
+{
+  int allow_restart = 1;
+  z_stream *z = &k->z;          /* zlib state structure */
+  uInt nread = z->avail_in;
+  Bytef *orig_in = z->next_in;
+  int status;                   /* zlib status */
+  CURLcode result = CURLE_OK;   /* Curl_client_write status */
+  char *decomp;                 /* Put the decompressed data here. */
+
+  /* Dynamically allocate a buffer for decompression because it's uncommonly
+     large to hold on the stack */
+  decomp = malloc(DSIZ);
+  if(decomp == NULL) {
+    return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
+  }
+
+  /* because the buffer size is fixed, iteratively decompress and transfer to
+     the client via client_write. */
+  for(;;) {
+    /* (re)set buffer for decompressed output for every iteration */
+    z->next_out = (Bytef *)decomp;
+    z->avail_out = DSIZ;
+
+    status = inflate(z, Z_SYNC_FLUSH);
+    if(status == Z_OK || status == Z_STREAM_END) {
+      allow_restart = 0;
+      if((DSIZ - z->avail_out) && (!k->ignorebody)) {
+        result = Curl_client_write(conn, CLIENTWRITE_BODY, decomp,
+                                   DSIZ - z->avail_out);
+        /* if !CURLE_OK, clean up, return */
+        if(result) {
+          free(decomp);
+          return exit_zlib(z, &k->zlib_init, result);
+        }
+      }
+
+      /* Done? clean up, return */
+      if(status == Z_STREAM_END) {
+        free(decomp);
+        if(inflateEnd(z) == Z_OK)
+          return exit_zlib(z, &k->zlib_init, result);
+        else
+          return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
+      }
+
+      /* Done with these bytes, exit */
+
+      /* status is always Z_OK at this point! */
+      if(z->avail_in == 0) {
+        free(decomp);
+        return result;
+      }
+    }
+    else if(allow_restart && status == Z_DATA_ERROR) {
+      /* some servers seem to not generate zlib headers, so this is an attempt
+         to fix and continue anyway */
+
+      (void) inflateEnd(z);     /* don't care about the return code */
+      if(inflateInit2(z, -MAX_WBITS) != Z_OK) {
+        free(decomp);
+        return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
+      }
+      z->next_in = orig_in;
+      z->avail_in = nread;
+      allow_restart = 0;
+      continue;
+    }
+    else {                      /* Error; exit loop, handle below */
+      free(decomp);
+      return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
+    }
+  }
+  /* Will never get here */
+}
+
+CURLcode
+Curl_unencode_deflate_write(struct connectdata *conn,
+                            struct SingleRequest *k,
+                            ssize_t nread)
+{
+  z_stream *z = &k->z;          /* zlib state structure */
+
+  /* Initialize zlib? */
+  if(k->zlib_init == ZLIB_UNINIT) {
+    memset(z, 0, sizeof(z_stream));
+    z->zalloc = (alloc_func)zalloc_cb;
+    z->zfree = (free_func)zfree_cb;
+
+    if(inflateInit(z) != Z_OK)
+      return process_zlib_error(conn, z);
+    k->zlib_init = ZLIB_INIT;
+  }
+
+  /* Set the compressed input when this function is called */
+  z->next_in = (Bytef *)k->str;
+  z->avail_in = (uInt)nread;
+
+  /* Now uncompress the data */
+  return inflate_stream(conn, k);
+}
+
+#ifdef OLD_ZLIB_SUPPORT
+/* Skip over the gzip header */
+static enum {
+  GZIP_OK,
+  GZIP_BAD,
+  GZIP_UNDERFLOW
+} check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen)
+{
+  int method, flags;
+  const ssize_t totallen = len;
+
+  /* The shortest header is 10 bytes */
+  if(len < 10)
+    return GZIP_UNDERFLOW;
+
+  if((data[0] != GZIP_MAGIC_0) || (data[1] != GZIP_MAGIC_1))
+    return GZIP_BAD;
+
+  method = data[2];
+  flags = data[3];
+
+  if(method != Z_DEFLATED || (flags & RESERVED) != 0) {
+    /* Can't handle this compression method or unknown flag */
+    return GZIP_BAD;
+  }
+
+  /* Skip over time, xflags, OS code and all previous bytes */
+  len -= 10;
+  data += 10;
+
+  if(flags & EXTRA_FIELD) {
+    ssize_t extra_len;
+
+    if(len < 2)
+      return GZIP_UNDERFLOW;
+
+    extra_len = (data[1] << 8) | data[0];
+
+    if(len < (extra_len+2))
+      return GZIP_UNDERFLOW;
+
+    len -= (extra_len + 2);
+    data += (extra_len + 2);
+  }
+
+  if(flags & ORIG_NAME) {
+    /* Skip over NUL-terminated file name */
+    while(len && *data) {
+      --len;
+      ++data;
+    }
+    if(!len || *data)
+      return GZIP_UNDERFLOW;
+
+    /* Skip over the NUL */
+    --len;
+    ++data;
+  }
+
+  if(flags & COMMENT) {
+    /* Skip over NUL-terminated comment */
+    while(len && *data) {
+      --len;
+      ++data;
+    }
+    if(!len || *data)
+      return GZIP_UNDERFLOW;
+
+    /* Skip over the NUL */
+    --len;
+  }
+
+  if(flags & HEAD_CRC) {
+    if(len < 2)
+      return GZIP_UNDERFLOW;
+
+    len -= 2;
+  }
+
+  *headerlen = totallen - len;
+  return GZIP_OK;
+}
+#endif
+
+CURLcode
+Curl_unencode_gzip_write(struct connectdata *conn,
+                         struct SingleRequest *k,
+                         ssize_t nread)
+{
+  z_stream *z = &k->z;          /* zlib state structure */
+
+  /* Initialize zlib? */
+  if(k->zlib_init == ZLIB_UNINIT) {
+    memset(z, 0, sizeof(z_stream));
+    z->zalloc = (alloc_func)zalloc_cb;
+    z->zfree = (free_func)zfree_cb;
+
+    if(strcmp(zlibVersion(), "1.2.0.4") >= 0) {
+      /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */
+      if(inflateInit2(z, MAX_WBITS+32) != Z_OK) {
+        return process_zlib_error(conn, z);
+      }
+      k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */
+    }
+    else {
+      /* we must parse the gzip header ourselves */
+      if(inflateInit2(z, -MAX_WBITS) != Z_OK) {
+        return process_zlib_error(conn, z);
+      }
+      k->zlib_init = ZLIB_INIT;   /* Initial call state */
+    }
+  }
+
+  if(k->zlib_init == ZLIB_INIT_GZIP) {
+    /* Let zlib handle the gzip decompression entirely */
+    z->next_in = (Bytef *)k->str;
+    z->avail_in = (uInt)nread;
+    /* Now uncompress the data */
+    return inflate_stream(conn, k);
+  }
+
+#ifndef OLD_ZLIB_SUPPORT
+  /* Support for old zlib versions is compiled away and we are running with
+     an old version, so return an error. */
+  return exit_zlib(z, &k->zlib_init, CURLE_FUNCTION_NOT_FOUND);
+
+#else
+  /* This next mess is to get around the potential case where there isn't
+   * enough data passed in to skip over the gzip header.  If that happens, we
+   * malloc a block and copy what we have then wait for the next call.  If
+   * there still isn't enough (this is definitely a worst-case scenario), we
+   * make the block bigger, copy the next part in and keep waiting.
+   *
+   * This is only required with zlib versions < 1.2.0.4 as newer versions
+   * can handle the gzip header themselves.
+   */
+
+  switch (k->zlib_init) {
+  /* Skip over gzip header? */
+  case ZLIB_INIT:
+  {
+    /* Initial call state */
+    ssize_t hlen;
+
+    switch (check_gzip_header((unsigned char *)k->str, nread, &hlen)) {
+    case GZIP_OK:
+      z->next_in = (Bytef *)k->str + hlen;
+      z->avail_in = (uInt)(nread - hlen);
+      k->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */
+      break;
+
+    case GZIP_UNDERFLOW:
+      /* We need more data so we can find the end of the gzip header.  It's
+       * possible that the memory block we malloc here will never be freed if
+       * the transfer abruptly aborts after this point.  Since it's unlikely
+       * that circumstances will be right for this code path to be followed in
+       * the first place, and it's even more unlikely for a transfer to fail
+       * immediately afterwards, it should seldom be a problem.
+       */
+      z->avail_in = (uInt)nread;
+      z->next_in = malloc(z->avail_in);
+      if(z->next_in == NULL) {
+        return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
+      }
+      memcpy(z->next_in, k->str, z->avail_in);
+      k->zlib_init = ZLIB_GZIP_HEADER;   /* Need more gzip header data state */
+      /* We don't have any data to inflate yet */
+      return CURLE_OK;
+
+    case GZIP_BAD:
+    default:
+      return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
+    }
+
+  }
+  break;
+
+  case ZLIB_GZIP_HEADER:
+  {
+    /* Need more gzip header data state */
+    ssize_t hlen;
+    unsigned char *oldblock = z->next_in;
+
+    z->avail_in += (uInt)nread;
+    z->next_in = realloc(z->next_in, z->avail_in);
+    if(z->next_in == NULL) {
+      free(oldblock);
+      return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
+    }
+    /* Append the new block of data to the previous one */
+    memcpy(z->next_in + z->avail_in - nread, k->str, nread);
+
+    switch (check_gzip_header(z->next_in, z->avail_in, &hlen)) {
+    case GZIP_OK:
+      /* This is the zlib stream data */
+      free(z->next_in);
+      /* Don't point into the malloced block since we just freed it */
+      z->next_in = (Bytef *)k->str + hlen + nread - z->avail_in;
+      z->avail_in = (uInt)(z->avail_in - hlen);
+      k->zlib_init = ZLIB_GZIP_INFLATING;   /* Inflating stream state */
+      break;
+
+    case GZIP_UNDERFLOW:
+      /* We still don't have any data to inflate! */
+      return CURLE_OK;
+
+    case GZIP_BAD:
+    default:
+      free(z->next_in);
+      return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
+    }
+
+  }
+  break;
+
+  case ZLIB_GZIP_INFLATING:
+  default:
+    /* Inflating stream state */
+    z->next_in = (Bytef *)k->str;
+    z->avail_in = (uInt)nread;
+    break;
+  }
+
+  if(z->avail_in == 0) {
+    /* We don't have any data to inflate; wait until next time */
+    return CURLE_OK;
+  }
+
+  /* We've parsed the header, now uncompress the data */
+  return inflate_stream(conn, k);
+#endif
+}
+
+void Curl_unencode_cleanup(struct connectdata *conn)
+{
+  struct SessionHandle *data = conn->data;
+  struct SingleRequest *k = &data->req;
+  z_stream *z = &k->z;
+  if(k->zlib_init != ZLIB_UNINIT)
+    (void) exit_zlib(z, &k->zlib_init, CURLE_OK);
+}
+
+#endif /* HAVE_LIBZ */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/content_encoding.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/content_encoding.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/content_encoding.h	(revision 164)
@@ -0,0 +1,48 @@
+#ifndef HEADER_CURL_CONTENT_ENCODING_H
+#define HEADER_CURL_CONTENT_ENCODING_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/*
+ * Comma-separated list all supported Content-Encodings ('identity' is implied)
+ */
+#ifdef HAVE_LIBZ
+#define ALL_CONTENT_ENCODINGS "deflate, gzip"
+/* force a cleanup */
+void Curl_unencode_cleanup(struct connectdata *conn);
+#else
+#define ALL_CONTENT_ENCODINGS "identity"
+#define Curl_unencode_cleanup(x) Curl_nop_stmt
+#endif
+
+CURLcode Curl_unencode_deflate_write(struct connectdata *conn,
+                                     struct SingleRequest *req,
+                                     ssize_t nread);
+
+CURLcode
+Curl_unencode_gzip_write(struct connectdata *conn,
+                         struct SingleRequest *k,
+                         ssize_t nread);
+
+
+#endif /* HEADER_CURL_CONTENT_ENCODING_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/cookie.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/cookie.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/cookie.c	(revision 164)
@@ -0,0 +1,1384 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/***
+
+
+RECEIVING COOKIE INFORMATION
+============================
+
+struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
+                    const char *file, struct CookieInfo *inc, bool newsession);
+
+        Inits a cookie struct to store data in a local file. This is always
+        called before any cookies are set.
+
+struct Cookie *Curl_cookie_add(struct SessionHandle *data,
+                 struct CookieInfo *c, bool httpheader, char *lineptr,
+                 const char *domain, const char *path);
+
+        The 'lineptr' parameter is a full "Set-cookie:" line as
+        received from a server.
+
+        The function need to replace previously stored lines that this new
+        line superceeds.
+
+        It may remove lines that are expired.
+
+        It should return an indication of success/error.
+
+
+SENDING COOKIE INFORMATION
+==========================
+
+struct Cookies *Curl_cookie_getlist(struct CookieInfo *cookie,
+                                    char *host, char *path, bool secure);
+
+        For a given host and path, return a linked list of cookies that
+        the client should send to the server if used now. The secure
+        boolean informs the cookie if a secure connection is achieved or
+        not.
+
+        It shall only return cookies that haven't expired.
+
+
+Example set of cookies:
+
+    Set-cookie: PRODUCTINFO=webxpress; domain=.fidelity.com; path=/; secure
+    Set-cookie: PERSONALIZE=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+    domain=.fidelity.com; path=/ftgw; secure
+    Set-cookie: FidHist=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+    domain=.fidelity.com; path=/; secure
+    Set-cookie: FidOrder=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+    domain=.fidelity.com; path=/; secure
+    Set-cookie: DisPend=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+    domain=.fidelity.com; path=/; secure
+    Set-cookie: FidDis=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+    domain=.fidelity.com; path=/; secure
+    Set-cookie:
+    Session_Key@6791a9e0-901a-11d0-a1c8-9b012c88aa77=none;expires=Monday,
+    13-Jun-1988 03:04:55 GMT; domain=.fidelity.com; path=/; secure
+****/
+
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+
+#ifdef USE_LIBPSL
+# include <libpsl.h>
+#endif
+
+#include "curl_printf.h"
+#include "urldata.h"
+#include "cookie.h"
+#include "strequal.h"
+#include "strtok.h"
+#include "sendf.h"
+#include "slist.h"
+#include "share.h"
+#include "strtoofft.h"
+#include "rawstr.h"
+#include "curl_memrchr.h"
+#include "inet_pton.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+static void freecookie(struct Cookie *co)
+{
+  free(co->expirestr);
+  free(co->domain);
+  free(co->path);
+  free(co->spath);
+  free(co->name);
+  free(co->value);
+  free(co->maxage);
+  free(co->version);
+  free(co);
+}
+
+static bool tailmatch(const char *cooke_domain, const char *hostname)
+{
+  size_t cookie_domain_len = strlen(cooke_domain);
+  size_t hostname_len = strlen(hostname);
+
+  if(hostname_len < cookie_domain_len)
+    return FALSE;
+
+  if(!Curl_raw_equal(cooke_domain, hostname+hostname_len-cookie_domain_len))
+    return FALSE;
+
+  /* A lead char of cookie_domain is not '.'.
+     RFC6265 4.1.2.3. The Domain Attribute says:
+       For example, if the value of the Domain attribute is
+       "example.com", the user agent will include the cookie in the Cookie
+       header when making HTTP requests to example.com, www.example.com, and
+       www.corp.example.com.
+   */
+  if(hostname_len == cookie_domain_len)
+    return TRUE;
+  if('.' == *(hostname + hostname_len - cookie_domain_len - 1))
+    return TRUE;
+  return FALSE;
+}
+
+/*
+ * matching cookie path and url path
+ * RFC6265 5.1.4 Paths and Path-Match
+ */
+static bool pathmatch(const char* cookie_path, const char* request_uri)
+{
+  size_t cookie_path_len;
+  size_t uri_path_len;
+  char* uri_path = NULL;
+  char* pos;
+  bool ret = FALSE;
+
+  /* cookie_path must not have last '/' separator. ex: /sample */
+  cookie_path_len = strlen(cookie_path);
+  if(1 == cookie_path_len) {
+    /* cookie_path must be '/' */
+    return TRUE;
+  }
+
+  uri_path = strdup(request_uri);
+  if(!uri_path)
+    return FALSE;
+  pos = strchr(uri_path, '?');
+  if(pos)
+    *pos = 0x0;
+
+  /* #-fragments are already cut off! */
+  if(0 == strlen(uri_path) || uri_path[0] != '/') {
+    free(uri_path);
+    uri_path = strdup("/");
+    if(!uri_path)
+      return FALSE;
+  }
+
+  /* here, RFC6265 5.1.4 says
+     4. Output the characters of the uri-path from the first character up
+        to, but not including, the right-most %x2F ("/").
+     but URL path /hoge?fuga=xxx means /hoge/index.cgi?fuga=xxx in some site
+     without redirect.
+     Ignore this algorithm because /hoge is uri path for this case
+     (uri path is not /).
+   */
+
+  uri_path_len = strlen(uri_path);
+
+  if(uri_path_len < cookie_path_len) {
+    ret = FALSE;
+    goto pathmatched;
+  }
+
+  /* not using checkprefix() because matching should be case-sensitive */
+  if(strncmp(cookie_path, uri_path, cookie_path_len)) {
+    ret = FALSE;
+    goto pathmatched;
+  }
+
+  /* The cookie-path and the uri-path are identical. */
+  if(cookie_path_len == uri_path_len) {
+    ret = TRUE;
+    goto pathmatched;
+  }
+
+  /* here, cookie_path_len < url_path_len */
+  if(uri_path[cookie_path_len] == '/') {
+    ret = TRUE;
+    goto pathmatched;
+  }
+
+  ret = FALSE;
+
+pathmatched:
+  free(uri_path);
+  return ret;
+}
+
+/*
+ * cookie path sanitize
+ */
+static char *sanitize_cookie_path(const char *cookie_path)
+{
+  size_t len;
+  char *new_path = strdup(cookie_path);
+  if(!new_path)
+    return NULL;
+
+  /* some stupid site sends path attribute with '"'. */
+  len = strlen(new_path);
+  if(new_path[0] == '\"') {
+    memmove((void *)new_path, (const void *)(new_path + 1), len);
+    len--;
+  }
+  if(len && (new_path[len - 1] == '\"')) {
+    new_path[len - 1] = 0x0;
+    len--;
+  }
+
+  /* RFC6265 5.2.4 The Path Attribute */
+  if(new_path[0] != '/') {
+    /* Let cookie-path be the default-path. */
+    free(new_path);
+    new_path = strdup("/");
+    return new_path;
+  }
+
+  /* convert /hoge/ to /hoge */
+  if(len && new_path[len - 1] == '/') {
+    new_path[len - 1] = 0x0;
+  }
+
+  return new_path;
+}
+
+/*
+ * Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
+ *
+ * NOTE: OOM or cookie parsing failures are ignored.
+ */
+void Curl_cookie_loadfiles(struct SessionHandle *data)
+{
+  struct curl_slist *list = data->change.cookielist;
+  if(list) {
+    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+    while(list) {
+      struct CookieInfo *newcookies = Curl_cookie_init(data,
+                                        list->data,
+                                        data->cookies,
+                                        data->set.cookiesession);
+      if(!newcookies)
+        /* Failure may be due to OOM or a bad cookie; both are ignored
+         * but only the first should be
+         */
+        infof(data, "ignoring failed cookie_init for %s\n", list->data);
+      else
+        data->cookies = newcookies;
+      list = list->next;
+    }
+    curl_slist_free_all(data->change.cookielist); /* clean up list */
+    data->change.cookielist = NULL; /* don't do this again! */
+    Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+  }
+}
+
+/*
+ * strstore() makes a strdup() on the 'newstr' and if '*str' is non-NULL
+ * that will be freed before the allocated string is stored there.
+ *
+ * It is meant to easily replace strdup()
+ */
+static void strstore(char **str, const char *newstr)
+{
+  free(*str);
+  *str = strdup(newstr);
+}
+
+/*
+ * remove_expired() removes expired cookies.
+ */
+static void remove_expired(struct CookieInfo *cookies)
+{
+  struct Cookie *co, *nx, *pv;
+  curl_off_t now = (curl_off_t)time(NULL);
+
+  co = cookies->cookies;
+  pv = NULL;
+  while(co) {
+    nx = co->next;
+    if((co->expirestr || co->maxage) && co->expires < now) {
+      if(co == cookies->cookies) {
+        cookies->cookies = co->next;
+      }
+      else {
+        pv->next = co->next;
+      }
+      cookies->numcookies--;
+      freecookie(co);
+    }
+    else {
+      pv = co;
+    }
+    co = nx;
+  }
+}
+
+/*
+ * Return true if the given string is an IP(v4|v6) address.
+ */
+static bool isip(const char *domain)
+{
+  struct in_addr addr;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr6;
+#endif
+
+  if(Curl_inet_pton(AF_INET, domain, &addr)
+#ifdef ENABLE_IPV6
+     || Curl_inet_pton(AF_INET6, domain, &addr6)
+#endif
+    ) {
+    /* domain name given as IP address */
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/****************************************************************************
+ *
+ * Curl_cookie_add()
+ *
+ * Add a single cookie line to the cookie keeping object.
+ *
+ * Be aware that sometimes we get an IP-only host name, and that might also be
+ * a numerical IPv6 address.
+ *
+ * Returns NULL on out of memory or invalid cookie. This is suboptimal,
+ * as they should be treated separately.
+ ***************************************************************************/
+
+struct Cookie *
+Curl_cookie_add(struct SessionHandle *data,
+                /* The 'data' pointer here may be NULL at times, and thus
+                   must only be used very carefully for things that can deal
+                   with data being NULL. Such as infof() and similar */
+
+                struct CookieInfo *c,
+                bool httpheader, /* TRUE if HTTP header-style line */
+                char *lineptr,   /* first character of the line */
+                const char *domain, /* default domain */
+                const char *path)   /* full path used when this cookie is set,
+                                       used to get default path for the cookie
+                                       unless set */
+{
+  struct Cookie *clist;
+  char name[MAX_NAME];
+  struct Cookie *co;
+  struct Cookie *lastc=NULL;
+  time_t now = time(NULL);
+  bool replace_old = FALSE;
+  bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */
+
+#ifdef USE_LIBPSL
+  const psl_ctx_t *psl;
+#endif
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+  (void)data;
+#endif
+
+  /* First, alloc and init a new struct for it */
+  co = calloc(1, sizeof(struct Cookie));
+  if(!co)
+    return NULL; /* bail out if we're this low on memory */
+
+  if(httpheader) {
+    /* This line was read off a HTTP-header */
+    const char *ptr;
+    const char *semiptr;
+    char *what;
+
+    what = malloc(MAX_COOKIE_LINE);
+    if(!what) {
+      free(co);
+      return NULL;
+    }
+
+    semiptr=strchr(lineptr, ';'); /* first, find a semicolon */
+
+    while(*lineptr && ISBLANK(*lineptr))
+      lineptr++;
+
+    ptr = lineptr;
+    do {
+      /* we have a <what>=<this> pair or a stand-alone word here */
+      name[0]=what[0]=0; /* init the buffers */
+      if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n =] =%"
+                     MAX_COOKIE_LINE_TXT "[^;\r\n]",
+                     name, what)) {
+        /* Use strstore() below to properly deal with received cookie
+           headers that have the same string property set more than once,
+           and then we use the last one. */
+        const char *whatptr;
+        bool done = FALSE;
+        bool sep;
+        size_t len=strlen(what);
+        const char *endofn = &ptr[ strlen(name) ];
+
+        /* skip trailing spaces in name */
+        while(*endofn && ISBLANK(*endofn))
+          endofn++;
+
+        /* name ends with a '=' ? */
+        sep = (*endofn == '=')?TRUE:FALSE;
+
+        /* Strip off trailing whitespace from the 'what' */
+        while(len && ISBLANK(what[len-1])) {
+          what[len-1]=0;
+          len--;
+        }
+
+        /* Skip leading whitespace from the 'what' */
+        whatptr=what;
+        while(*whatptr && ISBLANK(*whatptr))
+          whatptr++;
+
+        if(!len) {
+          /* this was a "<name>=" with no content, and we must allow
+             'secure' and 'httponly' specified this weirdly */
+          done = TRUE;
+          if(Curl_raw_equal("secure", name))
+            co->secure = TRUE;
+          else if(Curl_raw_equal("httponly", name))
+            co->httponly = TRUE;
+          else if(sep)
+            /* there was a '=' so we're not done parsing this field */
+            done = FALSE;
+        }
+        if(done)
+          ;
+        else if(Curl_raw_equal("path", name)) {
+          strstore(&co->path, whatptr);
+          if(!co->path) {
+            badcookie = TRUE; /* out of memory bad */
+            break;
+          }
+          co->spath = sanitize_cookie_path(co->path);
+          if(!co->spath) {
+            badcookie = TRUE; /* out of memory bad */
+            break;
+          }
+        }
+        else if(Curl_raw_equal("domain", name)) {
+          bool is_ip;
+          const char *dotp;
+
+          /* Now, we make sure that our host is within the given domain,
+             or the given domain is not valid and thus cannot be set. */
+
+          if('.' == whatptr[0])
+            whatptr++; /* ignore preceding dot */
+
+          is_ip = isip(domain ? domain : whatptr);
+
+          /* check for more dots */
+          dotp = strchr(whatptr, '.');
+          if(!dotp)
+            domain=":";
+
+          if(!domain
+             || (is_ip && !strcmp(whatptr, domain))
+             || (!is_ip && tailmatch(whatptr, domain))) {
+            strstore(&co->domain, whatptr);
+            if(!co->domain) {
+              badcookie = TRUE;
+              break;
+            }
+            if(!is_ip)
+              co->tailmatch=TRUE; /* we always do that if the domain name was
+                                     given */
+          }
+          else {
+            /* we did not get a tailmatch and then the attempted set domain
+               is not a domain to which the current host belongs. Mark as
+               bad. */
+            badcookie=TRUE;
+            infof(data, "skipped cookie with bad tailmatch domain: %s\n",
+                  whatptr);
+          }
+        }
+        else if(Curl_raw_equal("version", name)) {
+          strstore(&co->version, whatptr);
+          if(!co->version) {
+            badcookie = TRUE;
+            break;
+          }
+        }
+        else if(Curl_raw_equal("max-age", name)) {
+          /* Defined in RFC2109:
+
+             Optional.  The Max-Age attribute defines the lifetime of the
+             cookie, in seconds.  The delta-seconds value is a decimal non-
+             negative integer.  After delta-seconds seconds elapse, the
+             client should discard the cookie.  A value of zero means the
+             cookie should be discarded immediately.
+
+          */
+          strstore(&co->maxage, whatptr);
+          if(!co->maxage) {
+            badcookie = TRUE;
+            break;
+          }
+        }
+        else if(Curl_raw_equal("expires", name)) {
+          strstore(&co->expirestr, whatptr);
+          if(!co->expirestr) {
+            badcookie = TRUE;
+            break;
+          }
+        }
+        else if(!co->name) {
+          co->name = strdup(name);
+          co->value = strdup(whatptr);
+          if(!co->name || !co->value) {
+            badcookie = TRUE;
+            break;
+          }
+        }
+        /*
+          else this is the second (or more) name we don't know
+          about! */
+      }
+      else {
+        /* this is an "illegal" <what>=<this> pair */
+      }
+
+      if(!semiptr || !*semiptr) {
+        /* we already know there are no more cookies */
+        semiptr = NULL;
+        continue;
+      }
+
+      ptr=semiptr+1;
+      while(*ptr && ISBLANK(*ptr))
+        ptr++;
+      semiptr=strchr(ptr, ';'); /* now, find the next semicolon */
+
+      if(!semiptr && *ptr)
+        /* There are no more semicolons, but there's a final name=value pair
+           coming up */
+        semiptr=strchr(ptr, '\0');
+    } while(semiptr);
+
+    if(co->maxage) {
+      co->expires =
+        curlx_strtoofft((*co->maxage=='\"')?
+                        &co->maxage[1]:&co->maxage[0], NULL, 10);
+      if(CURL_OFF_T_MAX - now < co->expires)
+        /* avoid overflow */
+        co->expires = CURL_OFF_T_MAX;
+      else
+        co->expires += now;
+    }
+    else if(co->expirestr) {
+      /* Note that if the date couldn't get parsed for whatever reason,
+         the cookie will be treated as a session cookie */
+      co->expires = curl_getdate(co->expirestr, NULL);
+
+      /* Session cookies have expires set to 0 so if we get that back
+         from the date parser let's add a second to make it a
+         non-session cookie */
+      if(co->expires == 0)
+        co->expires = 1;
+      else if(co->expires < 0)
+        co->expires = 0;
+    }
+
+    if(!badcookie && !co->domain) {
+      if(domain) {
+        /* no domain was given in the header line, set the default */
+        co->domain=strdup(domain);
+        if(!co->domain)
+          badcookie = TRUE;
+      }
+    }
+
+    if(!badcookie && !co->path && path) {
+      /* No path was given in the header line, set the default.
+         Note that the passed-in path to this function MAY have a '?' and
+         following part that MUST not be stored as part of the path. */
+      char *queryp = strchr(path, '?');
+
+      /* queryp is where the interesting part of the path ends, so now we
+         want to the find the last */
+      char *endslash;
+      if(!queryp)
+        endslash = strrchr(path, '/');
+      else
+        endslash = memrchr(path, '/', (size_t)(queryp - path));
+      if(endslash) {
+        size_t pathlen = (size_t)(endslash-path+1); /* include ending slash */
+        co->path=malloc(pathlen+1); /* one extra for the zero byte */
+        if(co->path) {
+          memcpy(co->path, path, pathlen);
+          co->path[pathlen]=0; /* zero terminate */
+          co->spath = sanitize_cookie_path(co->path);
+          if(!co->spath)
+            badcookie = TRUE; /* out of memory bad */
+        }
+        else
+          badcookie = TRUE;
+      }
+    }
+
+    free(what);
+
+    if(badcookie || !co->name) {
+      /* we didn't get a cookie name or a bad one,
+         this is an illegal line, bail out */
+      freecookie(co);
+      return NULL;
+    }
+
+  }
+  else {
+    /* This line is NOT a HTTP header style line, we do offer support for
+       reading the odd netscape cookies-file format here */
+    char *ptr;
+    char *firstptr;
+    char *tok_buf=NULL;
+    int fields;
+
+    /* IE introduced HTTP-only cookies to prevent XSS attacks. Cookies
+       marked with httpOnly after the domain name are not accessible
+       from javascripts, but since curl does not operate at javascript
+       level, we include them anyway. In Firefox's cookie files, these
+       lines are preceded with #HttpOnly_ and then everything is
+       as usual, so we skip 10 characters of the line..
+    */
+    if(strncmp(lineptr, "#HttpOnly_", 10) == 0) {
+      lineptr += 10;
+      co->httponly = TRUE;
+    }
+
+    if(lineptr[0]=='#') {
+      /* don't even try the comments */
+      free(co);
+      return NULL;
+    }
+    /* strip off the possible end-of-line characters */
+    ptr=strchr(lineptr, '\r');
+    if(ptr)
+      *ptr=0; /* clear it */
+    ptr=strchr(lineptr, '\n');
+    if(ptr)
+      *ptr=0; /* clear it */
+
+    firstptr=strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */
+
+    /* Now loop through the fields and init the struct we already have
+       allocated */
+    for(ptr=firstptr, fields=0; ptr && !badcookie;
+        ptr=strtok_r(NULL, "\t", &tok_buf), fields++) {
+      switch(fields) {
+      case 0:
+        if(ptr[0]=='.') /* skip preceding dots */
+          ptr++;
+        co->domain = strdup(ptr);
+        if(!co->domain)
+          badcookie = TRUE;
+        break;
+      case 1:
+        /* This field got its explanation on the 23rd of May 2001 by
+           Andrés Garcú}:
+
+           flag: A TRUE/FALSE value indicating if all machines within a given
+           domain can access the variable. This value is set automatically by
+           the browser, depending on the value you set for the domain.
+
+           As far as I can see, it is set to true when the cookie says
+           .domain.com and to false when the domain is complete www.domain.com
+        */
+        co->tailmatch = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
+        break;
+      case 2:
+        /* It turns out, that sometimes the file format allows the path
+           field to remain not filled in, we try to detect this and work
+           around it! Andrés Garcú} made us aware of this... */
+        if(strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) {
+          /* only if the path doesn't look like a boolean option! */
+          co->path = strdup(ptr);
+          if(!co->path)
+            badcookie = TRUE;
+          else {
+            co->spath = sanitize_cookie_path(co->path);
+            if(!co->spath) {
+              badcookie = TRUE; /* out of memory bad */
+            }
+          }
+          break;
+        }
+        /* this doesn't look like a path, make one up! */
+        co->path = strdup("/");
+        if(!co->path)
+          badcookie = TRUE;
+        co->spath = strdup("/");
+        if(!co->spath)
+          badcookie = TRUE;
+        fields++; /* add a field and fall down to secure */
+        /* FALLTHROUGH */
+      case 3:
+        co->secure = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
+        break;
+      case 4:
+        co->expires = curlx_strtoofft(ptr, NULL, 10);
+        break;
+      case 5:
+        co->name = strdup(ptr);
+        if(!co->name)
+          badcookie = TRUE;
+        break;
+      case 6:
+        co->value = strdup(ptr);
+        if(!co->value)
+          badcookie = TRUE;
+        break;
+      }
+    }
+    if(6 == fields) {
+      /* we got a cookie with blank contents, fix it */
+      co->value = strdup("");
+      if(!co->value)
+        badcookie = TRUE;
+      else
+        fields++;
+    }
+
+    if(!badcookie && (7 != fields))
+      /* we did not find the sufficient number of fields */
+      badcookie = TRUE;
+
+    if(badcookie) {
+      freecookie(co);
+      return NULL;
+    }
+
+  }
+
+  if(!c->running &&    /* read from a file */
+     c->newsession &&  /* clean session cookies */
+     !co->expires) {   /* this is a session cookie since it doesn't expire! */
+    freecookie(co);
+    return NULL;
+  }
+
+  co->livecookie = c->running;
+
+  /* now, we have parsed the incoming line, we must now check if this
+     superceeds an already existing cookie, which it may if the previous have
+     the same domain and path as this */
+
+  /* at first, remove expired cookies */
+  remove_expired(c);
+
+#ifdef USE_LIBPSL
+  /* Check if the domain is a Public Suffix and if yes, ignore the cookie.
+     This needs a libpsl compiled with builtin data. */
+  if(co->domain && !isip(co->domain) && (psl = psl_builtin()) != NULL) {
+    if(psl_is_public_suffix(psl, co->domain)) {
+      infof(data, "cookie '%s' dropped, domain '%s' is a public suffix\n",
+            co->name, co->domain);
+      freecookie(co);
+      return NULL;
+    }
+  }
+#endif
+
+  clist = c->cookies;
+  replace_old = FALSE;
+  while(clist) {
+    if(Curl_raw_equal(clist->name, co->name)) {
+      /* the names are identical */
+
+      if(clist->domain && co->domain) {
+        if(Curl_raw_equal(clist->domain, co->domain))
+          /* The domains are identical */
+          replace_old=TRUE;
+      }
+      else if(!clist->domain && !co->domain)
+        replace_old = TRUE;
+
+      if(replace_old) {
+        /* the domains were identical */
+
+        if(clist->spath && co->spath) {
+          if(Curl_raw_equal(clist->spath, co->spath)) {
+            replace_old = TRUE;
+          }
+          else
+            replace_old = FALSE;
+        }
+        else if(!clist->spath && !co->spath)
+          replace_old = TRUE;
+        else
+          replace_old = FALSE;
+
+      }
+
+      if(replace_old && !co->livecookie && clist->livecookie) {
+        /* Both cookies matched fine, except that the already present
+           cookie is "live", which means it was set from a header, while
+           the new one isn't "live" and thus only read from a file. We let
+           live cookies stay alive */
+
+        /* Free the newcomer and get out of here! */
+        freecookie(co);
+        return NULL;
+      }
+
+      if(replace_old) {
+        co->next = clist->next; /* get the next-pointer first */
+
+        /* then free all the old pointers */
+        free(clist->name);
+        free(clist->value);
+        free(clist->domain);
+        free(clist->path);
+        free(clist->spath);
+        free(clist->expirestr);
+        free(clist->version);
+        free(clist->maxage);
+
+        *clist = *co;  /* then store all the new data */
+
+        free(co);   /* free the newly alloced memory */
+        co = clist; /* point to the previous struct instead */
+
+        /* We have replaced a cookie, now skip the rest of the list but
+           make sure the 'lastc' pointer is properly set */
+        do {
+          lastc = clist;
+          clist = clist->next;
+        } while(clist);
+        break;
+      }
+    }
+    lastc = clist;
+    clist = clist->next;
+  }
+
+  if(c->running)
+    /* Only show this when NOT reading the cookies from a file */
+    infof(data, "%s cookie %s=\"%s\" for domain %s, path %s, "
+          "expire %" CURL_FORMAT_CURL_OFF_T "\n",
+          replace_old?"Replaced":"Added", co->name, co->value,
+          co->domain, co->path, co->expires);
+
+  if(!replace_old) {
+    /* then make the last item point on this new one */
+    if(lastc)
+      lastc->next = co;
+    else
+      c->cookies = co;
+    c->numcookies++; /* one more cookie in the jar */
+  }
+
+  return co;
+}
+
+/*****************************************************************************
+ *
+ * Curl_cookie_init()
+ *
+ * Inits a cookie struct to read data from a local file. This is always
+ * called before any cookies are set. File may be NULL.
+ *
+ * If 'newsession' is TRUE, discard all "session cookies" on read from file.
+ *
+ * Returns NULL on out of memory. Invalid cookies are ignored.
+ ****************************************************************************/
+struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
+                                    const char *file,
+                                    struct CookieInfo *inc,
+                                    bool newsession)
+{
+  struct CookieInfo *c;
+  FILE *fp = NULL;
+  bool fromfile=TRUE;
+  char *line = NULL;
+
+  if(NULL == inc) {
+    /* we didn't get a struct, create one */
+    c = calloc(1, sizeof(struct CookieInfo));
+    if(!c)
+      return NULL; /* failed to get memory */
+    c->filename = strdup(file?file:"none"); /* copy the name just in case */
+    if(!c->filename)
+      goto fail; /* failed to get memory */
+  }
+  else {
+    /* we got an already existing one, use that */
+    c = inc;
+  }
+  c->running = FALSE; /* this is not running, this is init */
+
+  if(file && strequal(file, "-")) {
+    fp = stdin;
+    fromfile=FALSE;
+  }
+  else if(file && !*file) {
+    /* points to a "" string */
+    fp = NULL;
+  }
+  else
+    fp = file?fopen(file, FOPEN_READTEXT):NULL;
+
+  c->newsession = newsession; /* new session? */
+
+  if(fp) {
+    char *lineptr;
+    bool headerline;
+
+    line = malloc(MAX_COOKIE_LINE);
+    if(!line)
+      goto fail;
+    while(fgets(line, MAX_COOKIE_LINE, fp)) {
+      if(checkprefix("Set-Cookie:", line)) {
+        /* This is a cookie line, get it! */
+        lineptr=&line[11];
+        headerline=TRUE;
+      }
+      else {
+        lineptr=line;
+        headerline=FALSE;
+      }
+      while(*lineptr && ISBLANK(*lineptr))
+        lineptr++;
+
+      Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL);
+    }
+    free(line); /* free the line buffer */
+
+    if(fromfile)
+      fclose(fp);
+  }
+
+  c->running = TRUE;          /* now, we're running */
+
+  return c;
+
+fail:
+  free(line);
+  if(!inc)
+    /* Only clean up if we allocated it here, as the original could still be in
+     * use by a share handle */
+    Curl_cookie_cleanup(c);
+  if(fromfile && fp)
+    fclose(fp);
+  return NULL; /* out of memory */
+}
+
+/* sort this so that the longest path gets before the shorter path */
+static int cookie_sort(const void *p1, const void *p2)
+{
+  struct Cookie *c1 = *(struct Cookie **)p1;
+  struct Cookie *c2 = *(struct Cookie **)p2;
+  size_t l1, l2;
+
+  /* 1 - compare cookie path lengths */
+  l1 = c1->path ? strlen(c1->path) : 0;
+  l2 = c2->path ? strlen(c2->path) : 0;
+
+  if(l1 != l2)
+    return (l2 > l1) ? 1 : -1 ; /* avoid size_t <=> int conversions */
+
+  /* 2 - compare cookie domain lengths */
+  l1 = c1->domain ? strlen(c1->domain) : 0;
+  l2 = c2->domain ? strlen(c2->domain) : 0;
+
+  if(l1 != l2)
+    return (l2 > l1) ? 1 : -1 ;  /* avoid size_t <=> int conversions */
+
+  /* 3 - compare cookie names */
+  if(c1->name && c2->name)
+    return strcmp(c1->name, c2->name);
+
+  /* sorry, can't be more deterministic */
+  return 0;
+}
+
+/*****************************************************************************
+ *
+ * Curl_cookie_getlist()
+ *
+ * For a given host and path, return a linked list of cookies that the
+ * client should send to the server if used now. The secure boolean informs
+ * the cookie if a secure connection is achieved or not.
+ *
+ * It shall only return cookies that haven't expired.
+ *
+ ****************************************************************************/
+
+struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
+                                   const char *host, const char *path,
+                                   bool secure)
+{
+  struct Cookie *newco;
+  struct Cookie *co;
+  time_t now = time(NULL);
+  struct Cookie *mainco=NULL;
+  size_t matches = 0;
+  bool is_ip;
+
+  if(!c || !c->cookies)
+    return NULL; /* no cookie struct or no cookies in the struct */
+
+  /* at first, remove expired cookies */
+  remove_expired(c);
+
+  /* check if host is an IP(v4|v6) address */
+  is_ip = isip(host);
+
+  co = c->cookies;
+
+  while(co) {
+    /* only process this cookie if it is not expired or had no expire
+       date AND that if the cookie requires we're secure we must only
+       continue if we are! */
+    if((!co->expires || (co->expires > now)) &&
+       (co->secure?secure:TRUE)) {
+
+      /* now check if the domain is correct */
+      if(!co->domain ||
+         (co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
+         ((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) {
+        /* the right part of the host matches the domain stuff in the
+           cookie data */
+
+        /* now check the left part of the path with the cookies path
+           requirement */
+        if(!co->spath || pathmatch(co->spath, path) ) {
+
+          /* and now, we know this is a match and we should create an
+             entry for the return-linked-list */
+
+          newco = malloc(sizeof(struct Cookie));
+          if(newco) {
+            /* first, copy the whole source cookie: */
+            memcpy(newco, co, sizeof(struct Cookie));
+
+            /* then modify our next */
+            newco->next = mainco;
+
+            /* point the main to us */
+            mainco = newco;
+
+            matches++;
+          }
+          else {
+            fail:
+            /* failure, clear up the allocated chain and return NULL */
+            while(mainco) {
+              co = mainco->next;
+              free(mainco);
+              mainco = co;
+            }
+
+            return NULL;
+          }
+        }
+      }
+    }
+    co = co->next;
+  }
+
+  if(matches) {
+    /* Now we need to make sure that if there is a name appearing more than
+       once, the longest specified path version comes first. To make this
+       the swiftest way, we just sort them all based on path length. */
+    struct Cookie **array;
+    size_t i;
+
+    /* alloc an array and store all cookie pointers */
+    array = malloc(sizeof(struct Cookie *) * matches);
+    if(!array)
+      goto fail;
+
+    co = mainco;
+
+    for(i=0; co; co = co->next)
+      array[i++] = co;
+
+    /* now sort the cookie pointers in path length order */
+    qsort(array, matches, sizeof(struct Cookie *), cookie_sort);
+
+    /* remake the linked list order according to the new order */
+
+    mainco = array[0]; /* start here */
+    for(i=0; i<matches-1; i++)
+      array[i]->next = array[i+1];
+    array[matches-1]->next = NULL; /* terminate the list */
+
+    free(array); /* remove the temporary data again */
+  }
+
+  return mainco; /* return the new list */
+}
+
+/*****************************************************************************
+ *
+ * Curl_cookie_clearall()
+ *
+ * Clear all existing cookies and reset the counter.
+ *
+ ****************************************************************************/
+void Curl_cookie_clearall(struct CookieInfo *cookies)
+{
+  if(cookies) {
+    Curl_cookie_freelist(cookies->cookies, TRUE);
+    cookies->cookies = NULL;
+    cookies->numcookies = 0;
+  }
+}
+
+/*****************************************************************************
+ *
+ * Curl_cookie_freelist()
+ *
+ * Free a list of cookies previously returned by Curl_cookie_getlist();
+ *
+ * The 'cookiestoo' argument tells this function whether to just free the
+ * list or actually also free all cookies within the list as well.
+ *
+ ****************************************************************************/
+
+void Curl_cookie_freelist(struct Cookie *co, bool cookiestoo)
+{
+  struct Cookie *next;
+  while(co) {
+    next = co->next;
+    if(cookiestoo)
+      freecookie(co);
+    else
+      free(co); /* we only free the struct since the "members" are all just
+                   pointed out in the main cookie list! */
+    co = next;
+  }
+}
+
+
+/*****************************************************************************
+ *
+ * Curl_cookie_clearsess()
+ *
+ * Free all session cookies in the cookies list.
+ *
+ ****************************************************************************/
+void Curl_cookie_clearsess(struct CookieInfo *cookies)
+{
+  struct Cookie *first, *curr, *next, *prev = NULL;
+
+  if(!cookies || !cookies->cookies)
+    return;
+
+  first = curr = prev = cookies->cookies;
+
+  for(; curr; curr = next) {
+    next = curr->next;
+    if(!curr->expires) {
+      if(first == curr)
+        first = next;
+
+      if(prev == curr)
+        prev = next;
+      else
+        prev->next = next;
+
+      freecookie(curr);
+      cookies->numcookies--;
+    }
+    else
+      prev = curr;
+  }
+
+  cookies->cookies = first;
+}
+
+
+/*****************************************************************************
+ *
+ * Curl_cookie_cleanup()
+ *
+ * Free a "cookie object" previous created with Curl_cookie_init().
+ *
+ ****************************************************************************/
+void Curl_cookie_cleanup(struct CookieInfo *c)
+{
+  if(c) {
+    free(c->filename);
+    Curl_cookie_freelist(c->cookies, TRUE);
+    free(c); /* free the base struct as well */
+  }
+}
+
+/* get_netscape_format()
+ *
+ * Formats a string for Netscape output file, w/o a newline at the end.
+ *
+ * Function returns a char * to a formatted line. Has to be free()d
+*/
+static char *get_netscape_format(const struct Cookie *co)
+{
+  return aprintf(
+    "%s"     /* httponly preamble */
+    "%s%s\t" /* domain */
+    "%s\t"   /* tailmatch */
+    "%s\t"   /* path */
+    "%s\t"   /* secure */
+    "%" CURL_FORMAT_CURL_OFF_T "\t"   /* expires */
+    "%s\t"   /* name */
+    "%s",    /* value */
+    co->httponly?"#HttpOnly_":"",
+    /* Make sure all domains are prefixed with a dot if they allow
+       tailmatching. This is Mozilla-style. */
+    (co->tailmatch && co->domain && co->domain[0] != '.')? ".":"",
+    co->domain?co->domain:"unknown",
+    co->tailmatch?"TRUE":"FALSE",
+    co->path?co->path:"/",
+    co->secure?"TRUE":"FALSE",
+    co->expires,
+    co->name,
+    co->value?co->value:"");
+}
+
+/*
+ * cookie_output()
+ *
+ * Writes all internally known cookies to the specified file. Specify
+ * "-" as file name to write to stdout.
+ *
+ * The function returns non-zero on write failure.
+ */
+static int cookie_output(struct CookieInfo *c, const char *dumphere)
+{
+  struct Cookie *co;
+  FILE *out;
+  bool use_stdout=FALSE;
+
+  if((NULL == c) || (0 == c->numcookies))
+    /* If there are no known cookies, we don't write or even create any
+       destination file */
+    return 0;
+
+  /* at first, remove expired cookies */
+  remove_expired(c);
+
+  if(strequal("-", dumphere)) {
+    /* use stdout */
+    out = stdout;
+    use_stdout=TRUE;
+  }
+  else {
+    out = fopen(dumphere, FOPEN_WRITETEXT);
+    if(!out)
+      return 1; /* failure */
+  }
+
+  if(c) {
+    char *format_ptr;
+
+    fputs("# Netscape HTTP Cookie File\n"
+          "# https://curl.haxx.se/docs/http-cookies.html\n"
+          "# This file was generated by libcurl! Edit at your own risk.\n\n",
+          out);
+
+    for(co = c->cookies; co; co = co->next) {
+      if(!co->domain)
+        continue;
+      format_ptr = get_netscape_format(co);
+      if(format_ptr == NULL) {
+        fprintf(out, "#\n# Fatal libcurl error\n");
+        if(!use_stdout)
+          fclose(out);
+        return 1;
+      }
+      fprintf(out, "%s\n", format_ptr);
+      free(format_ptr);
+    }
+  }
+
+  if(!use_stdout)
+    fclose(out);
+
+  return 0;
+}
+
+struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
+{
+  struct curl_slist *list = NULL;
+  struct curl_slist *beg;
+  struct Cookie *c;
+  char *line;
+
+  if((data->cookies == NULL) ||
+      (data->cookies->numcookies == 0))
+    return NULL;
+
+  for(c = data->cookies->cookies; c; c = c->next) {
+    if(!c->domain)
+      continue;
+    line = get_netscape_format(c);
+    if(!line) {
+      curl_slist_free_all(list);
+      return NULL;
+    }
+    beg = Curl_slist_append_nodup(list, line);
+    if(!beg) {
+      free(line);
+      curl_slist_free_all(list);
+      return NULL;
+    }
+    list = beg;
+  }
+
+  return list;
+}
+
+void Curl_flush_cookies(struct SessionHandle *data, int cleanup)
+{
+  if(data->set.str[STRING_COOKIEJAR]) {
+    if(data->change.cookielist) {
+      /* If there is a list of cookie files to read, do it first so that
+         we have all the told files read before we write the new jar.
+         Curl_cookie_loadfiles() LOCKS and UNLOCKS the share itself! */
+      Curl_cookie_loadfiles(data);
+    }
+
+    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+
+    /* if we have a destination file for all the cookies to get dumped to */
+    if(cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR]))
+      infof(data, "WARNING: failed to save cookies in %s\n",
+            data->set.str[STRING_COOKIEJAR]);
+  }
+  else {
+    if(cleanup && data->change.cookielist) {
+      /* since nothing is written, we can just free the list of cookie file
+         names */
+      curl_slist_free_all(data->change.cookielist); /* clean up list */
+      data->change.cookielist = NULL;
+    }
+    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+  }
+
+  if(cleanup && (!data->share || (data->cookies != data->share->cookies))) {
+    Curl_cookie_cleanup(data->cookies);
+  }
+  Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+}
+
+#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_COOKIES */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/cookie.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/cookie.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/cookie.h	(revision 164)
@@ -0,0 +1,104 @@
+#ifndef HEADER_CURL_COOKIE_H
+#define HEADER_CURL_COOKIE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+struct Cookie {
+  struct Cookie *next; /* next in the chain */
+  char *name;        /* <this> = value */
+  char *value;       /* name = <this> */
+  char *path;         /* path = <this> which is in Set-Cookie: */
+  char *spath;        /* sanitized cookie path */
+  char *domain;      /* domain = <this> */
+  curl_off_t expires;  /* expires = <this> */
+  char *expirestr;   /* the plain text version */
+  bool tailmatch;    /* weather we do tail-matchning of the domain name */
+
+  /* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
+  char *version;     /* Version = <value> */
+  char *maxage;      /* Max-Age = <value> */
+
+  bool secure;       /* whether the 'secure' keyword was used */
+  bool livecookie;   /* updated from a server, not a stored file */
+  bool httponly;     /* true if the httponly directive is present */
+};
+
+struct CookieInfo {
+  /* linked list of cookies we know of */
+  struct Cookie *cookies;
+
+  char *filename;  /* file we read from/write to */
+  bool running;    /* state info, for cookie adding information */
+  long numcookies; /* number of cookies in the "jar" */
+  bool newsession; /* new session, discard session cookies on load */
+};
+
+/* This is the maximum line length we accept for a cookie line. RFC 2109
+   section 6.3 says:
+
+   "at least 4096 bytes per cookie (as measured by the size of the characters
+   that comprise the cookie non-terminal in the syntax description of the
+   Set-Cookie header)"
+
+*/
+#define MAX_COOKIE_LINE 5000
+#define MAX_COOKIE_LINE_TXT "4999"
+
+/* This is the maximum length of a cookie name we deal with: */
+#define MAX_NAME 1024
+#define MAX_NAME_TXT "1023"
+
+struct SessionHandle;
+/*
+ * Add a cookie to the internal list of cookies. The domain and path arguments
+ * are only used if the header boolean is TRUE.
+ */
+
+struct Cookie *Curl_cookie_add(struct SessionHandle *data,
+                               struct CookieInfo *, bool header, char *lineptr,
+                               const char *domain, const char *path);
+
+struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *,
+                                   const char *, bool);
+void Curl_cookie_freelist(struct Cookie *cookies, bool cookiestoo);
+void Curl_cookie_clearall(struct CookieInfo *cookies);
+void Curl_cookie_clearsess(struct CookieInfo *cookies);
+
+#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
+#define Curl_cookie_list(x) NULL
+#define Curl_cookie_loadfiles(x) Curl_nop_stmt
+#define Curl_cookie_init(x,y,z,w) NULL
+#define Curl_cookie_cleanup(x) Curl_nop_stmt
+#define Curl_flush_cookies(x,y) Curl_nop_stmt
+#else
+void Curl_flush_cookies(struct SessionHandle *data, int cleanup);
+void Curl_cookie_cleanup(struct CookieInfo *);
+struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
+                                    const char *, struct CookieInfo *, bool);
+struct curl_slist *Curl_cookie_list(struct SessionHandle *data);
+void Curl_cookie_loadfiles(struct SessionHandle *data);
+#endif
+
+#endif /* HEADER_CURL_COOKIE_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_addrinfo.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_addrinfo.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_addrinfo.c	(revision 164)
@@ -0,0 +1,566 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include <sys/un.h>
+#endif
+
+#ifdef __VMS
+#  include <in.h>
+#  include <inet.h>
+#endif
+
+#if defined(NETWARE) && defined(__NOVELL_LIBC__)
+#  undef  in_addr_t
+#  define in_addr_t unsigned long
+#endif
+
+#include "curl_addrinfo.h"
+#include "inet_pton.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Curl_freeaddrinfo()
+ *
+ * This is used to free a linked list of Curl_addrinfo structs along
+ * with all its associated allocated storage. This function should be
+ * called once for each successful call to Curl_getaddrinfo_ex() or to
+ * any function call which actually allocates a Curl_addrinfo struct.
+ */
+
+#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
+    defined(__OPTIMIZE__) && defined(__unix__) &&  defined(__i386__)
+  /* workaround icc 9.1 optimizer issue */
+# define vqualifier volatile
+#else
+# define vqualifier
+#endif
+
+void
+Curl_freeaddrinfo(Curl_addrinfo *cahead)
+{
+  Curl_addrinfo *vqualifier canext;
+  Curl_addrinfo *ca;
+
+  for(ca = cahead; ca != NULL; ca = canext) {
+    free(ca->ai_addr);
+    free(ca->ai_canonname);
+    canext = ca->ai_next;
+
+    free(ca);
+  }
+}
+
+
+#ifdef HAVE_GETADDRINFO
+/*
+ * Curl_getaddrinfo_ex()
+ *
+ * This is a wrapper function around system's getaddrinfo(), with
+ * the only difference that instead of returning a linked list of
+ * addrinfo structs this one returns a linked list of Curl_addrinfo
+ * ones. The memory allocated by this function *MUST* be free'd with
+ * Curl_freeaddrinfo().  For each successful call to this function
+ * there must be an associated call later to Curl_freeaddrinfo().
+ *
+ * There should be no single call to system's getaddrinfo() in the
+ * whole library, any such call should be 'routed' through this one.
+ */
+
+int
+Curl_getaddrinfo_ex(const char *nodename,
+                    const char *servname,
+                    const struct addrinfo *hints,
+                    Curl_addrinfo **result)
+{
+  const struct addrinfo *ai;
+  struct addrinfo *aihead;
+  Curl_addrinfo *cafirst = NULL;
+  Curl_addrinfo *calast = NULL;
+  Curl_addrinfo *ca;
+  size_t ss_size;
+  int error;
+
+  *result = NULL; /* assume failure */
+
+  error = getaddrinfo(nodename, servname, hints, &aihead);
+  if(error)
+    return error;
+
+  /* traverse the addrinfo list */
+
+  for(ai = aihead; ai != NULL; ai = ai->ai_next) {
+
+    /* ignore elements with unsupported address family, */
+    /* settle family-specific sockaddr structure size.  */
+    if(ai->ai_family == AF_INET)
+      ss_size = sizeof(struct sockaddr_in);
+#ifdef ENABLE_IPV6
+    else if(ai->ai_family == AF_INET6)
+      ss_size = sizeof(struct sockaddr_in6);
+#endif
+    else
+      continue;
+
+    /* ignore elements without required address info */
+    if((ai->ai_addr == NULL) || !(ai->ai_addrlen > 0))
+      continue;
+
+    /* ignore elements with bogus address size */
+    if((size_t)ai->ai_addrlen < ss_size)
+      continue;
+
+    if((ca = malloc(sizeof(Curl_addrinfo))) == NULL) {
+      error = EAI_MEMORY;
+      break;
+    }
+
+    /* copy each structure member individually, member ordering, */
+    /* size, or padding might be different for each platform.    */
+
+    ca->ai_flags     = ai->ai_flags;
+    ca->ai_family    = ai->ai_family;
+    ca->ai_socktype  = ai->ai_socktype;
+    ca->ai_protocol  = ai->ai_protocol;
+    ca->ai_addrlen   = (curl_socklen_t)ss_size;
+    ca->ai_addr      = NULL;
+    ca->ai_canonname = NULL;
+    ca->ai_next      = NULL;
+
+    if((ca->ai_addr = malloc(ss_size)) == NULL) {
+      error = EAI_MEMORY;
+      free(ca);
+      break;
+    }
+    memcpy(ca->ai_addr, ai->ai_addr, ss_size);
+
+    if(ai->ai_canonname != NULL) {
+      if((ca->ai_canonname = strdup(ai->ai_canonname)) == NULL) {
+        error = EAI_MEMORY;
+        free(ca->ai_addr);
+        free(ca);
+        break;
+      }
+    }
+
+    /* if the return list is empty, this becomes the first element */
+    if(!cafirst)
+      cafirst = ca;
+
+    /* add this element last in the return list */
+    if(calast)
+      calast->ai_next = ca;
+    calast = ca;
+
+  }
+
+  /* destroy the addrinfo list */
+  if(aihead)
+    freeaddrinfo(aihead);
+
+  /* if we failed, also destroy the Curl_addrinfo list */
+  if(error) {
+    Curl_freeaddrinfo(cafirst);
+    cafirst = NULL;
+  }
+  else if(!cafirst) {
+#ifdef EAI_NONAME
+    /* rfc3493 conformant */
+    error = EAI_NONAME;
+#else
+    /* rfc3493 obsoleted */
+    error = EAI_NODATA;
+#endif
+#ifdef USE_WINSOCK
+    SET_SOCKERRNO(error);
+#endif
+  }
+
+  *result = cafirst;
+
+  /* This is not a CURLcode */
+  return error;
+}
+#endif /* HAVE_GETADDRINFO */
+
+
+/*
+ * Curl_he2ai()
+ *
+ * This function returns a pointer to the first element of a newly allocated
+ * Curl_addrinfo struct linked list filled with the data of a given hostent.
+ * Curl_addrinfo is meant to work like the addrinfo struct does for a IPv6
+ * stack, but usable also for IPv4, all hosts and environments.
+ *
+ * The memory allocated by this function *MUST* be free'd later on calling
+ * Curl_freeaddrinfo().  For each successful call to this function there
+ * must be an associated call later to Curl_freeaddrinfo().
+ *
+ *   Curl_addrinfo defined in "lib/curl_addrinfo.h"
+ *
+ *     struct Curl_addrinfo {
+ *       int                   ai_flags;
+ *       int                   ai_family;
+ *       int                   ai_socktype;
+ *       int                   ai_protocol;
+ *       curl_socklen_t        ai_addrlen;   * Follow rfc3493 struct addrinfo *
+ *       char                 *ai_canonname;
+ *       struct sockaddr      *ai_addr;
+ *       struct Curl_addrinfo *ai_next;
+ *     };
+ *     typedef struct Curl_addrinfo Curl_addrinfo;
+ *
+ *   hostent defined in <netdb.h>
+ *
+ *     struct hostent {
+ *       char    *h_name;
+ *       char    **h_aliases;
+ *       int     h_addrtype;
+ *       int     h_length;
+ *       char    **h_addr_list;
+ *     };
+ *
+ *   for backward compatibility:
+ *
+ *     #define h_addr  h_addr_list[0]
+ */
+
+Curl_addrinfo *
+Curl_he2ai(const struct hostent *he, int port)
+{
+  Curl_addrinfo *ai;
+  Curl_addrinfo *prevai = NULL;
+  Curl_addrinfo *firstai = NULL;
+  struct sockaddr_in *addr;
+#ifdef ENABLE_IPV6
+  struct sockaddr_in6 *addr6;
+#endif
+  CURLcode result = CURLE_OK;
+  int i;
+  char *curr;
+
+  if(!he)
+    /* no input == no output! */
+    return NULL;
+
+  DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));
+
+  for(i=0; (curr = he->h_addr_list[i]) != NULL; i++) {
+
+    size_t ss_size;
+#ifdef ENABLE_IPV6
+    if(he->h_addrtype == AF_INET6)
+      ss_size = sizeof (struct sockaddr_in6);
+    else
+#endif
+      ss_size = sizeof (struct sockaddr_in);
+
+    if((ai = calloc(1, sizeof(Curl_addrinfo))) == NULL) {
+      result = CURLE_OUT_OF_MEMORY;
+      break;
+    }
+    if((ai->ai_canonname = strdup(he->h_name)) == NULL) {
+      result = CURLE_OUT_OF_MEMORY;
+      free(ai);
+      break;
+    }
+    if((ai->ai_addr = calloc(1, ss_size)) == NULL) {
+      result = CURLE_OUT_OF_MEMORY;
+      free(ai->ai_canonname);
+      free(ai);
+      break;
+    }
+
+    if(!firstai)
+      /* store the pointer we want to return from this function */
+      firstai = ai;
+
+    if(prevai)
+      /* make the previous entry point to this */
+      prevai->ai_next = ai;
+
+    ai->ai_family = he->h_addrtype;
+
+    /* we return all names as STREAM, so when using this address for TFTP
+       the type must be ignored and conn->socktype be used instead! */
+    ai->ai_socktype = SOCK_STREAM;
+
+    ai->ai_addrlen = (curl_socklen_t)ss_size;
+
+    /* leave the rest of the struct filled with zero */
+
+    switch (ai->ai_family) {
+    case AF_INET:
+      addr = (void *)ai->ai_addr; /* storage area for this info */
+
+      memcpy(&addr->sin_addr, curr, sizeof(struct in_addr));
+      addr->sin_family = (unsigned short)(he->h_addrtype);
+      addr->sin_port = htons((unsigned short)port);
+      break;
+
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      addr6 = (void *)ai->ai_addr; /* storage area for this info */
+
+      memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr));
+      addr6->sin6_family = (unsigned short)(he->h_addrtype);
+      addr6->sin6_port = htons((unsigned short)port);
+      break;
+#endif
+    }
+
+    prevai = ai;
+  }
+
+  if(result) {
+    Curl_freeaddrinfo(firstai);
+    firstai = NULL;
+  }
+
+  return firstai;
+}
+
+
+struct namebuff {
+  struct hostent hostentry;
+  union {
+    struct in_addr  ina4;
+#ifdef ENABLE_IPV6
+    struct in6_addr ina6;
+#endif
+  } addrentry;
+  char *h_addr_list[2];
+};
+
+
+/*
+ * Curl_ip2addr()
+ *
+ * This function takes an internet address, in binary form, as input parameter
+ * along with its address family and the string version of the address, and it
+ * returns a Curl_addrinfo chain filled in correctly with information for the
+ * given address/host
+ */
+
+Curl_addrinfo *
+Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
+{
+  Curl_addrinfo *ai;
+
+#if defined(__VMS) && \
+    defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
+#pragma pointer_size save
+#pragma pointer_size short
+#pragma message disable PTRMISMATCH
+#endif
+
+  struct hostent  *h;
+  struct namebuff *buf;
+  char  *addrentry;
+  char  *hoststr;
+  size_t addrsize;
+
+  DEBUGASSERT(inaddr && hostname);
+
+  buf = malloc(sizeof(struct namebuff));
+  if(!buf)
+    return NULL;
+
+  hoststr = strdup(hostname);
+  if(!hoststr) {
+    free(buf);
+    return NULL;
+  }
+
+  switch(af) {
+  case AF_INET:
+    addrsize = sizeof(struct in_addr);
+    addrentry = (void *)&buf->addrentry.ina4;
+    memcpy(addrentry, inaddr, sizeof(struct in_addr));
+    break;
+#ifdef ENABLE_IPV6
+  case AF_INET6:
+    addrsize = sizeof(struct in6_addr);
+    addrentry = (void *)&buf->addrentry.ina6;
+    memcpy(addrentry, inaddr, sizeof(struct in6_addr));
+    break;
+#endif
+  default:
+    free(hoststr);
+    free(buf);
+    return NULL;
+  }
+
+  h = &buf->hostentry;
+  h->h_name = hoststr;
+  h->h_aliases = NULL;
+  h->h_addrtype = (short)af;
+  h->h_length = (short)addrsize;
+  h->h_addr_list = &buf->h_addr_list[0];
+  h->h_addr_list[0] = addrentry;
+  h->h_addr_list[1] = NULL; /* terminate list of entries */
+
+#if defined(__VMS) && \
+    defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
+#pragma pointer_size restore
+#pragma message enable PTRMISMATCH
+#endif
+
+  ai = Curl_he2ai(h, port);
+
+  free(hoststr);
+  free(buf);
+
+  return ai;
+}
+
+/*
+ * Given an IPv4 or IPv6 dotted string address, this converts it to a proper
+ * allocated Curl_addrinfo struct and returns it.
+ */
+Curl_addrinfo *Curl_str2addr(char *address, int port)
+{
+  struct in_addr in;
+  if(Curl_inet_pton(AF_INET, address, &in) > 0)
+    /* This is a dotted IP address 123.123.123.123-style */
+    return Curl_ip2addr(AF_INET, &in, address, port);
+#ifdef ENABLE_IPV6
+  else {
+    struct in6_addr in6;
+    if(Curl_inet_pton(AF_INET6, address, &in6) > 0)
+      /* This is a dotted IPv6 address ::1-style */
+      return Curl_ip2addr(AF_INET6, &in6, address, port);
+  }
+#endif
+  return NULL; /* bad input format */
+}
+
+#ifdef USE_UNIX_SOCKETS
+/**
+ * Given a path to a Unix domain socket, return a newly allocated Curl_addrinfo
+ * struct initialized with this path.
+ */
+Curl_addrinfo *Curl_unix2addr(const char *path)
+{
+  Curl_addrinfo *ai;
+  struct sockaddr_un *sa_un;
+  size_t path_len;
+
+  ai = calloc(1, sizeof(Curl_addrinfo));
+  if(!ai)
+    return NULL;
+  if((ai->ai_addr = calloc(1, sizeof(struct sockaddr_un))) == NULL) {
+    free(ai);
+    return NULL;
+  }
+  /* sun_path must be able to store the NUL-terminated path */
+  path_len = strlen(path);
+  if(path_len >= sizeof(sa_un->sun_path)) {
+    free(ai->ai_addr);
+    free(ai);
+    return NULL;
+  }
+
+  ai->ai_family = AF_UNIX;
+  ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */
+  ai->ai_addrlen = (curl_socklen_t) sizeof(struct sockaddr_un);
+  sa_un = (void *) ai->ai_addr;
+  sa_un->sun_family = AF_UNIX;
+  memcpy(sa_un->sun_path, path, path_len + 1); /* copy NUL byte */
+  return ai;
+}
+#endif
+
+#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
+/*
+ * curl_dofreeaddrinfo()
+ *
+ * This is strictly for memory tracing and are using the same style as the
+ * family otherwise present in memdebug.c. I put these ones here since they
+ * require a bunch of structs I didn't want to include in memdebug.c
+ */
+
+void
+curl_dofreeaddrinfo(struct addrinfo *freethis,
+                    int line, const char *source)
+{
+#ifdef USE_LWIPSOCK
+  lwip_freeaddrinfo(freethis);
+#else
+  (freeaddrinfo)(freethis);
+#endif
+  curl_memlog("ADDR %s:%d freeaddrinfo(%p)\n",
+              source, line, (void *)freethis);
+}
+#endif /* defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) */
+
+
+#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
+/*
+ * curl_dogetaddrinfo()
+ *
+ * This is strictly for memory tracing and are using the same style as the
+ * family otherwise present in memdebug.c. I put these ones here since they
+ * require a bunch of structs I didn't want to include in memdebug.c
+ */
+
+int
+curl_dogetaddrinfo(const char *hostname,
+                   const char *service,
+                   const struct addrinfo *hints,
+                   struct addrinfo **result,
+                   int line, const char *source)
+{
+#ifdef USE_LWIPSOCK
+  int res=lwip_getaddrinfo(hostname, service, hints, result);
+#else
+  int res=(getaddrinfo)(hostname, service, hints, result);
+#endif
+  if(0 == res)
+    /* success */
+    curl_memlog("ADDR %s:%d getaddrinfo() = %p\n",
+                source, line, (void *)*result);
+  else
+    curl_memlog("ADDR %s:%d getaddrinfo() failed\n",
+                source, line);
+  return res;
+}
+#endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_addrinfo.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_addrinfo.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_addrinfo.h	(revision 164)
@@ -0,0 +1,102 @@
+#ifndef HEADER_CURL_ADDRINFO_H
+#define HEADER_CURL_ADDRINFO_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+
+#ifdef __VMS
+#  include <in.h>
+#  include <inet.h>
+#  include <stdlib.h>
+#endif
+
+
+/*
+ * Curl_addrinfo is our internal struct definition that we use to allow
+ * consistent internal handling of this data. We use this even when the
+ * system provides an addrinfo structure definition. And we use this for
+ * all sorts of IPv4 and IPV6 builds.
+ */
+
+struct Curl_addrinfo {
+  int                   ai_flags;
+  int                   ai_family;
+  int                   ai_socktype;
+  int                   ai_protocol;
+  curl_socklen_t        ai_addrlen;   /* Follow rfc3493 struct addrinfo */
+  char                 *ai_canonname;
+  struct sockaddr      *ai_addr;
+  struct Curl_addrinfo *ai_next;
+};
+typedef struct Curl_addrinfo Curl_addrinfo;
+
+void
+Curl_freeaddrinfo(Curl_addrinfo *cahead);
+
+#ifdef HAVE_GETADDRINFO
+int
+Curl_getaddrinfo_ex(const char *nodename,
+                    const char *servname,
+                    const struct addrinfo *hints,
+                    Curl_addrinfo **result);
+#endif
+
+Curl_addrinfo *
+Curl_he2ai(const struct hostent *he, int port);
+
+Curl_addrinfo *
+Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
+
+Curl_addrinfo *Curl_str2addr(char *dotted, int port);
+
+#ifdef USE_UNIX_SOCKETS
+Curl_addrinfo *Curl_unix2addr(const char *path);
+#endif
+
+#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
+    defined(HAVE_FREEADDRINFO)
+void
+curl_dofreeaddrinfo(struct addrinfo *freethis,
+                    int line, const char *source);
+#endif
+
+#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
+int
+curl_dogetaddrinfo(const char *hostname,
+                   const char *service,
+                   const struct addrinfo *hints,
+                   struct addrinfo **result,
+                   int line, const char *source);
+#endif
+
+#endif /* HEADER_CURL_ADDRINFO_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_base64.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_base64.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_base64.h	(revision 164)
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_BASE64_H
+#define HEADER_CURL_BASE64_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+CURLcode Curl_base64_encode(struct SessionHandle *data,
+                            const char *inputbuff, size_t insize,
+                            char **outptr, size_t *outlen);
+CURLcode Curl_base64url_encode(struct SessionHandle *data,
+                               const char *inputbuff, size_t insize,
+                               char **outptr, size_t *outlen);
+
+CURLcode Curl_base64_decode(const char *src,
+                            unsigned char **outptr, size_t *outlen);
+
+#endif /* HEADER_CURL_BASE64_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_des.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_des.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_des.c	(revision 164)
@@ -0,0 +1,63 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2015, Steve Holme, <steve_holme@hotmail.com>.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM) && !defined(HAVE_DES_SET_ODD_PARITY)
+
+#include "curl_des.h"
+
+/*
+ * Curl_des_set_odd_parity()
+ *
+ * This is used to apply odd parity to the given byte array. It is typically
+ * used by when a cryptography engines doesn't have it's own version.
+ *
+ * The function is a port of the Java based oddParity() function over at:
+ *
+ * http://davenport.sourceforge.net/ntlm.html
+ *
+ * Parameters:
+ *
+ * bytes       [in/out] - The data whose parity bits are to be adjusted for
+ *                        odd parity.
+ * len         [out]    - The length of the data.
+ */
+void Curl_des_set_odd_parity(unsigned char *bytes, size_t len)
+{
+  size_t i;
+
+  for(i = 0; i < len; i++) {
+    unsigned char b = bytes[i];
+
+    bool needs_parity = (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^
+                          (b >> 4) ^ (b >> 3) ^ (b >> 2) ^
+                          (b >> 1)) & 0x01) == 0;
+
+    if(needs_parity)
+      bytes[i] |= 0x01;
+    else
+      bytes[i] &= 0xfe;
+  }
+}
+
+#endif /* USE_NTLM && !HAVE_DES_SET_ODD_PARITY */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_des.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_des.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_des.h	(revision 164)
@@ -0,0 +1,34 @@
+#ifndef HEADER_CURL_DES_H
+#define HEADER_CURL_DES_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2015, Steve Holme, <steve_holme@hotmail.com>.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM) && !defined(HAVE_DES_SET_ODD_PARITY)
+
+/* Applies odd parity to the given byte array */
+void Curl_des_set_odd_parity(unsigned char *bytes, size_t length);
+
+#endif /* USE_NTLM && !HAVE_DES_SET_ODD_PARITY */
+
+#endif /* HEADER_CURL_DES_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_endian.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_endian.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_endian.c	(revision 164)
@@ -0,0 +1,236 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "curl_endian.h"
+
+/*
+ * Curl_read16_le()
+ *
+ * This function converts a 16-bit integer from the little endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 2 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned short Curl_read16_le(unsigned char *buf)
+{
+  return (unsigned short)(((unsigned short)buf[0]) |
+                          ((unsigned short)buf[1] << 8));
+}
+
+/*
+ * Curl_read32_le()
+ *
+ * This function converts a 32-bit integer from the little endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 4 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned int Curl_read32_le(unsigned char *buf)
+{
+  return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
+         ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
+}
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/*
+ * Curl_read64_le()
+ *
+ * This function converts a 64-bit integer from the little endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 8 byte buffer.
+ *
+ * Returns the integer.
+ */
+#if defined(HAVE_LONGLONG)
+unsigned long long Curl_read64_le(unsigned char *buf)
+{
+  return ((unsigned long long)buf[0]) |
+         ((unsigned long long)buf[1] << 8) |
+         ((unsigned long long)buf[2] << 16) |
+         ((unsigned long long)buf[3] << 24) |
+         ((unsigned long long)buf[4] << 32) |
+         ((unsigned long long)buf[5] << 40) |
+         ((unsigned long long)buf[6] << 48) |
+         ((unsigned long long)buf[7] << 56);
+}
+#else
+unsigned __int64 Curl_read64_le(unsigned char *buf)
+{
+  return ((unsigned __int64)buf[0]) | ((unsigned __int64)buf[1] << 8) |
+         ((unsigned __int64)buf[2] << 16) | ((unsigned __int64)buf[3] << 24) |
+         ((unsigned __int64)buf[4] << 32) | ((unsigned __int64)buf[5] << 40) |
+         ((unsigned __int64)buf[6] << 48) | ((unsigned __int64)buf[7] << 56);
+}
+#endif
+
+#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
+
+/*
+ * Curl_read16_be()
+ *
+ * This function converts a 16-bit integer from the big endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 2 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned short Curl_read16_be(unsigned char *buf)
+{
+  return (unsigned short)(((unsigned short)buf[0] << 8) |
+                          ((unsigned short)buf[1]));
+}
+
+/*
+ * Curl_read32_be()
+ *
+ * This function converts a 32-bit integer from the big endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 4 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned int Curl_read32_be(unsigned char *buf)
+{
+  return ((unsigned int)buf[0] << 24) | ((unsigned int)buf[1] << 16) |
+         ((unsigned int)buf[2] << 8) | ((unsigned int)buf[3]);
+}
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/*
+ * Curl_read64_be()
+ *
+ * This function converts a 64-bit integer from the big endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 8 byte buffer.
+ *
+ * Returns the integer.
+ */
+#if defined(HAVE_LONGLONG)
+unsigned long long Curl_read64_be(unsigned char *buf)
+{
+  return ((unsigned long long)buf[0] << 56) |
+         ((unsigned long long)buf[1] << 48) |
+         ((unsigned long long)buf[2] << 40) |
+         ((unsigned long long)buf[3] << 32) |
+         ((unsigned long long)buf[4] << 24) |
+         ((unsigned long long)buf[5] << 16) |
+         ((unsigned long long)buf[6] << 8) |
+         ((unsigned long long)buf[7]);
+}
+#else
+unsigned __int64 Curl_read64_be(unsigned char *buf)
+{
+  return ((unsigned __int64)buf[0] << 56) | ((unsigned __int64)buf[1] << 48) |
+         ((unsigned __int64)buf[2] << 40) | ((unsigned __int64)buf[3] << 32) |
+         ((unsigned __int64)buf[4] << 24) | ((unsigned __int64)buf[5] << 16) |
+         ((unsigned __int64)buf[6] << 8) | ((unsigned __int64)buf[7]);
+}
+#endif
+
+#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
+
+/*
+ * Curl_write16_le()
+ *
+ * This function converts a 16-bit integer from the native endian format,
+ * to little endian format ready for sending down the wire.
+ *
+ * Parameters:
+ *
+ * value    [in]     - The 16-bit integer value.
+ * buffer   [in]     - A pointer to the output buffer.
+ */
+void Curl_write16_le(const short value, unsigned char *buffer)
+{
+  buffer[0] = (char)(value & 0x00FF);
+  buffer[1] = (char)((value & 0xFF00) >> 8);
+}
+
+/*
+ * Curl_write32_le()
+ *
+ * This function converts a 32-bit integer from the native endian format,
+ * to little endian format ready for sending down the wire.
+ *
+ * Parameters:
+ *
+ * value    [in]     - The 32-bit integer value.
+ * buffer   [in]     - A pointer to the output buffer.
+ */
+void Curl_write32_le(const int value, unsigned char *buffer)
+{
+  buffer[0] = (char)(value & 0x000000FF);
+  buffer[1] = (char)((value & 0x0000FF00) >> 8);
+  buffer[2] = (char)((value & 0x00FF0000) >> 16);
+  buffer[3] = (char)((value & 0xFF000000) >> 24);
+}
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/*
+ * Curl_write64_le()
+ *
+ * This function converts a 64-bit integer from the native endian format,
+ * to little endian format ready for sending down the wire.
+ *
+ * Parameters:
+ *
+ * value    [in]     - The 64-bit integer value.
+ * buffer   [in]     - A pointer to the output buffer.
+ */
+#if defined(HAVE_LONGLONG)
+void Curl_write64_le(const long long value, unsigned char *buffer)
+#else
+void Curl_write64_le(const __int64 value, unsigned char *buffer)
+#endif
+{
+  Curl_write32_le((int)value, buffer);
+  Curl_write32_le((int)(value >> 32), buffer + 4);
+}
+#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_endian.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_endian.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_endian.h	(revision 164)
@@ -0,0 +1,70 @@
+#ifndef HEADER_CURL_ENDIAN_H
+#define HEADER_CURL_ENDIAN_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Converts a 16-bit integer from little endian */
+unsigned short Curl_read16_le(unsigned char *buf);
+
+/* Converts a 32-bit integer from little endian */
+unsigned int Curl_read32_le(unsigned char *buf);
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/* Converts a 64-bit integer from little endian */
+#if defined(HAVE_LONGLONG)
+unsigned long long Curl_read64_le(unsigned char *buf);
+#else
+unsigned __int64 Curl_read64_le(unsigned char *buf);
+#endif
+#endif
+
+/* Converts a 16-bit integer from big endian */
+unsigned short Curl_read16_be(unsigned char *buf);
+
+/* Converts a 32-bit integer from big endian */
+unsigned int Curl_read32_be(unsigned char *buf);
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/* Converts a 64-bit integer from big endian */
+#if defined(HAVE_LONGLONG)
+unsigned long long Curl_read64_be(unsigned char *buf);
+#else
+unsigned __int64 Curl_read64_be(unsigned char *buf);
+#endif
+#endif
+
+/* Converts a 16-bit integer to little endian */
+void Curl_write16_le(const short value, unsigned char *buffer);
+
+/* Converts a 32-bit integer to little endian */
+void Curl_write32_le(const int value, unsigned char *buffer);
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/* Converts a 64-bit integer to little endian */
+#if defined(HAVE_LONGLONG)
+void Curl_write64_le(const long long value, unsigned char *buffer);
+#else
+void Curl_write64_le(const __int64 value, unsigned char *buffer);
+#endif
+#endif
+
+#endif /* HEADER_CURL_ENDIAN_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_fnmatch.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_fnmatch.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_fnmatch.c	(revision 164)
@@ -0,0 +1,424 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "curl_fnmatch.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#define CURLFNM_CHARSET_LEN (sizeof(char) * 256)
+#define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15)
+
+#define CURLFNM_NEGATE  CURLFNM_CHARSET_LEN
+
+#define CURLFNM_ALNUM   (CURLFNM_CHARSET_LEN + 1)
+#define CURLFNM_DIGIT   (CURLFNM_CHARSET_LEN + 2)
+#define CURLFNM_XDIGIT  (CURLFNM_CHARSET_LEN + 3)
+#define CURLFNM_ALPHA   (CURLFNM_CHARSET_LEN + 4)
+#define CURLFNM_PRINT   (CURLFNM_CHARSET_LEN + 5)
+#define CURLFNM_BLANK   (CURLFNM_CHARSET_LEN + 6)
+#define CURLFNM_LOWER   (CURLFNM_CHARSET_LEN + 7)
+#define CURLFNM_GRAPH   (CURLFNM_CHARSET_LEN + 8)
+#define CURLFNM_SPACE   (CURLFNM_CHARSET_LEN + 9)
+#define CURLFNM_UPPER   (CURLFNM_CHARSET_LEN + 10)
+
+typedef enum {
+  CURLFNM_LOOP_DEFAULT = 0,
+  CURLFNM_LOOP_BACKSLASH
+} loop_state;
+
+typedef enum {
+  CURLFNM_SCHS_DEFAULT = 0,
+  CURLFNM_SCHS_MAYRANGE,
+  CURLFNM_SCHS_MAYRANGE2,
+  CURLFNM_SCHS_RIGHTBR,
+  CURLFNM_SCHS_RIGHTBRLEFTBR
+} setcharset_state;
+
+typedef enum {
+  CURLFNM_PKW_INIT = 0,
+  CURLFNM_PKW_DDOT
+} parsekey_state;
+
+#define SETCHARSET_OK     1
+#define SETCHARSET_FAIL   0
+
+static int parsekeyword(unsigned char **pattern, unsigned char *charset)
+{
+  parsekey_state state = CURLFNM_PKW_INIT;
+#define KEYLEN 10
+  char keyword[KEYLEN] = { 0 };
+  int found = FALSE;
+  int i;
+  unsigned char *p = *pattern;
+  for(i = 0; !found; i++) {
+    char c = *p++;
+    if(i >= KEYLEN)
+      return SETCHARSET_FAIL;
+    switch(state) {
+    case CURLFNM_PKW_INIT:
+      if(ISALPHA(c) && ISLOWER(c))
+        keyword[i] = c;
+      else if(c == ':')
+        state = CURLFNM_PKW_DDOT;
+      else
+        return 0;
+      break;
+    case CURLFNM_PKW_DDOT:
+      if(c == ']')
+        found = TRUE;
+      else
+        return SETCHARSET_FAIL;
+    }
+  }
+#undef KEYLEN
+
+  *pattern = p; /* move caller's pattern pointer */
+  if(strcmp(keyword, "digit") == 0)
+    charset[CURLFNM_DIGIT] = 1;
+  else if(strcmp(keyword, "alnum") == 0)
+    charset[CURLFNM_ALNUM] = 1;
+  else if(strcmp(keyword, "alpha") == 0)
+    charset[CURLFNM_ALPHA] = 1;
+  else if(strcmp(keyword, "xdigit") == 0)
+    charset[CURLFNM_XDIGIT] = 1;
+  else if(strcmp(keyword, "print") == 0)
+    charset[CURLFNM_PRINT] = 1;
+  else if(strcmp(keyword, "graph") == 0)
+    charset[CURLFNM_GRAPH] = 1;
+  else if(strcmp(keyword, "space") == 0)
+    charset[CURLFNM_SPACE] = 1;
+  else if(strcmp(keyword, "blank") == 0)
+    charset[CURLFNM_BLANK] = 1;
+  else if(strcmp(keyword, "upper") == 0)
+    charset[CURLFNM_UPPER] = 1;
+  else if(strcmp(keyword, "lower") == 0)
+    charset[CURLFNM_LOWER] = 1;
+  else
+    return SETCHARSET_FAIL;
+  return SETCHARSET_OK;
+}
+
+/* returns 1 (true) if pattern is OK, 0 if is bad ("p" is pattern pointer) */
+static int setcharset(unsigned char **p, unsigned char *charset)
+{
+  setcharset_state state = CURLFNM_SCHS_DEFAULT;
+  unsigned char rangestart = 0;
+  unsigned char lastchar   = 0;
+  bool something_found = FALSE;
+  unsigned char c;
+  for(;;) {
+    c = **p;
+    switch(state) {
+    case CURLFNM_SCHS_DEFAULT:
+      if(ISALNUM(c)) { /* ASCII value */
+        rangestart = c;
+        charset[c] = 1;
+        (*p)++;
+        state = CURLFNM_SCHS_MAYRANGE;
+        something_found = TRUE;
+      }
+      else if(c == ']') {
+        if(something_found)
+          return SETCHARSET_OK;
+        else
+          something_found = TRUE;
+        state = CURLFNM_SCHS_RIGHTBR;
+        charset[c] = 1;
+        (*p)++;
+      }
+      else if(c == '[') {
+        char c2 = *((*p)+1);
+        if(c2 == ':') { /* there has to be a keyword */
+          (*p) += 2;
+          if(parsekeyword(p, charset)) {
+            state = CURLFNM_SCHS_DEFAULT;
+          }
+          else
+            return SETCHARSET_FAIL;
+        }
+        else {
+          charset[c] = 1;
+          (*p)++;
+        }
+        something_found = TRUE;
+      }
+      else if(c == '?' || c == '*') {
+        something_found = TRUE;
+        charset[c] = 1;
+        (*p)++;
+      }
+      else if(c == '^' || c == '!') {
+        if(!something_found) {
+          if(charset[CURLFNM_NEGATE]) {
+            charset[c] = 1;
+            something_found = TRUE;
+          }
+          else
+            charset[CURLFNM_NEGATE] = 1; /* negate charset */
+        }
+        else
+          charset[c] = 1;
+        (*p)++;
+      }
+      else if(c == '\\') {
+        c = *(++(*p));
+        if(ISPRINT((c))) {
+          something_found = TRUE;
+          state = CURLFNM_SCHS_MAYRANGE;
+          charset[c] = 1;
+          rangestart = c;
+          (*p)++;
+        }
+        else
+          return SETCHARSET_FAIL;
+      }
+      else if(c == '\0') {
+        return SETCHARSET_FAIL;
+      }
+      else {
+        charset[c] = 1;
+        (*p)++;
+        something_found = TRUE;
+      }
+      break;
+    case CURLFNM_SCHS_MAYRANGE:
+      if(c == '-') {
+        charset[c] = 1;
+        (*p)++;
+        lastchar = '-';
+        state = CURLFNM_SCHS_MAYRANGE2;
+      }
+      else if(c == '[') {
+        state = CURLFNM_SCHS_DEFAULT;
+      }
+      else if(ISALNUM(c)) {
+        charset[c] = 1;
+        (*p)++;
+      }
+      else if(c == '\\') {
+        c = *(++(*p));
+        if(ISPRINT(c)) {
+          charset[c] = 1;
+          (*p)++;
+        }
+        else
+          return SETCHARSET_FAIL;
+      }
+      else if(c == ']') {
+        return SETCHARSET_OK;
+      }
+      else
+        return SETCHARSET_FAIL;
+      break;
+    case CURLFNM_SCHS_MAYRANGE2:
+      if(c == '\\') {
+        c = *(++(*p));
+        if(!ISPRINT(c))
+          return SETCHARSET_FAIL;
+      }
+      if(c == ']') {
+        return SETCHARSET_OK;
+      }
+      else if(c == '\\') {
+        c = *(++(*p));
+        if(ISPRINT(c)) {
+          charset[c] = 1;
+          state = CURLFNM_SCHS_DEFAULT;
+          (*p)++;
+        }
+        else
+          return SETCHARSET_FAIL;
+      }
+      if(c >= rangestart) {
+        if((ISLOWER(c) && ISLOWER(rangestart)) ||
+           (ISDIGIT(c) && ISDIGIT(rangestart)) ||
+           (ISUPPER(c) && ISUPPER(rangestart))) {
+          charset[lastchar] = 0;
+          rangestart++;
+          while(rangestart++ <= c)
+            charset[rangestart-1] = 1;
+          (*p)++;
+          state = CURLFNM_SCHS_DEFAULT;
+        }
+        else
+          return SETCHARSET_FAIL;
+      }
+      break;
+    case CURLFNM_SCHS_RIGHTBR:
+      if(c == '[') {
+        state = CURLFNM_SCHS_RIGHTBRLEFTBR;
+        charset[c] = 1;
+        (*p)++;
+      }
+      else if(c == ']') {
+        return SETCHARSET_OK;
+      }
+      else if(c == '\0') {
+        return SETCHARSET_FAIL;
+      }
+      else if(ISPRINT(c)) {
+        charset[c] = 1;
+        (*p)++;
+        state = CURLFNM_SCHS_DEFAULT;
+      }
+      else
+        /* used 'goto fail' instead of 'return SETCHARSET_FAIL' to avoid a
+         * nonsense warning 'statement not reached' at end of the fnc when
+         * compiling on Solaris */
+        goto fail;
+      break;
+    case CURLFNM_SCHS_RIGHTBRLEFTBR:
+      if(c == ']') {
+        return SETCHARSET_OK;
+      }
+      else {
+        state  = CURLFNM_SCHS_DEFAULT;
+        charset[c] = 1;
+        (*p)++;
+      }
+      break;
+    }
+  }
+fail:
+  return SETCHARSET_FAIL;
+}
+
+static int loop(const unsigned char *pattern, const unsigned char *string)
+{
+  loop_state state = CURLFNM_LOOP_DEFAULT;
+  unsigned char *p = (unsigned char *)pattern;
+  unsigned char *s = (unsigned char *)string;
+  unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 };
+  int rc = 0;
+
+  for(;;) {
+    switch(state) {
+    case CURLFNM_LOOP_DEFAULT:
+      if(*p == '*') {
+        while(*(p+1) == '*') /* eliminate multiple stars */
+          p++;
+        if(*s == '\0' && *(p+1) == '\0')
+          return CURL_FNMATCH_MATCH;
+        rc = loop(p + 1, s); /* *.txt matches .txt <=> .txt matches .txt */
+        if(rc == CURL_FNMATCH_MATCH)
+          return CURL_FNMATCH_MATCH;
+        if(*s) /* let the star eat up one character */
+          s++;
+        else
+          return CURL_FNMATCH_NOMATCH;
+      }
+      else if(*p == '?') {
+        if(ISPRINT(*s)) {
+          s++;
+          p++;
+        }
+        else if(*s == '\0')
+          return CURL_FNMATCH_NOMATCH;
+        else
+          return CURL_FNMATCH_FAIL; /* cannot deal with other character */
+      }
+      else if(*p == '\0') {
+        if(*s == '\0')
+          return CURL_FNMATCH_MATCH;
+        else
+          return CURL_FNMATCH_NOMATCH;
+      }
+      else if(*p == '\\') {
+        state = CURLFNM_LOOP_BACKSLASH;
+        p++;
+      }
+      else if(*p == '[') {
+        unsigned char *pp = p+1; /* cannot handle with pointer to register */
+        if(setcharset(&pp, charset)) {
+          int found = FALSE;
+          if(charset[(unsigned int)*s])
+            found = TRUE;
+          else if(charset[CURLFNM_ALNUM])
+            found = ISALNUM(*s);
+          else if(charset[CURLFNM_ALPHA])
+            found = ISALPHA(*s);
+          else if(charset[CURLFNM_DIGIT])
+            found = ISDIGIT(*s);
+          else if(charset[CURLFNM_XDIGIT])
+            found = ISXDIGIT(*s);
+          else if(charset[CURLFNM_PRINT])
+            found = ISPRINT(*s);
+          else if(charset[CURLFNM_SPACE])
+            found = ISSPACE(*s);
+          else if(charset[CURLFNM_UPPER])
+            found = ISUPPER(*s);
+          else if(charset[CURLFNM_LOWER])
+            found = ISLOWER(*s);
+          else if(charset[CURLFNM_BLANK])
+            found = ISBLANK(*s);
+          else if(charset[CURLFNM_GRAPH])
+            found = ISGRAPH(*s);
+
+          if(charset[CURLFNM_NEGATE])
+            found = !found;
+
+          if(found) {
+            p = pp+1;
+            s++;
+            memset(charset, 0, CURLFNM_CHSET_SIZE);
+          }
+          else
+            return CURL_FNMATCH_NOMATCH;
+        }
+        else
+          return CURL_FNMATCH_FAIL;
+      }
+      else {
+        if(*p++ != *s++)
+          return CURL_FNMATCH_NOMATCH;
+      }
+      break;
+    case CURLFNM_LOOP_BACKSLASH:
+      if(ISPRINT(*p)) {
+        if(*p++ == *s++)
+          state = CURLFNM_LOOP_DEFAULT;
+        else
+          return CURL_FNMATCH_NOMATCH;
+      }
+      else
+        return CURL_FNMATCH_FAIL;
+      break;
+    }
+  }
+}
+
+/*
+ * @unittest: 1307
+ */
+int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
+{
+  (void)ptr; /* the argument is specified by the curl_fnmatch_callback
+                prototype, but not used by Curl_fnmatch() */
+  if(!pattern || !string) {
+    return CURL_FNMATCH_FAIL;
+  }
+  return loop((unsigned char *)pattern, (unsigned char *)string);
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_fnmatch.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_fnmatch.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_fnmatch.h	(revision 164)
@@ -0,0 +1,44 @@
+#ifndef HEADER_CURL_FNMATCH_H
+#define HEADER_CURL_FNMATCH_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#define CURL_FNMATCH_MATCH    0
+#define CURL_FNMATCH_NOMATCH  1
+#define CURL_FNMATCH_FAIL     2
+
+/* default pattern matching function
+ * =================================
+ * Implemented with recursive backtracking, if you want to use Curl_fnmatch,
+ * please note that there is not implemented UTF/UNICODE support.
+ *
+ * Implemented features:
+ * '?' notation, does not match UTF characters
+ * '*' can also work with UTF string
+ * [a-zA-Z0-9] enumeration support
+ *
+ * keywords: alnum, digit, xdigit, alpha, print, blank, lower, graph, space
+ *           and upper (use as "[[:alnum:]]")
+ */
+int Curl_fnmatch(void *ptr, const char *pattern, const char *string);
+
+#endif /* HEADER_CURL_FNMATCH_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_gethostname.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_gethostname.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_gethostname.c	(revision 164)
@@ -0,0 +1,100 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "curl_gethostname.h"
+
+/*
+ * Curl_gethostname() is a wrapper around gethostname() which allows
+ * overriding the host name that the function would normally return.
+ * This capability is used by the test suite to verify exact matching
+ * of NTLM authentication, which exercises libcurl's MD4 and DES code
+ * as well as by the SMTP module when a hostname is not provided.
+ *
+ * For libcurl debug enabled builds host name overriding takes place
+ * when environment variable CURL_GETHOSTNAME is set, using the value
+ * held by the variable to override returned host name.
+ *
+ * Note: The function always returns the un-qualified hostname rather
+ * than being provider dependent.
+ *
+ * For libcurl shared library release builds the test suite preloads
+ * another shared library named libhostname using the LD_PRELOAD
+ * mechanism which intercepts, and might override, the gethostname()
+ * function call. In this case a given platform must support the
+ * LD_PRELOAD mechanism and additionally have environment variable
+ * CURL_GETHOSTNAME set in order to override the returned host name.
+ *
+ * For libcurl static library release builds no overriding takes place.
+ */
+
+int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) {
+
+#ifndef HAVE_GETHOSTNAME
+
+  /* Allow compilation and return failure when unavailable */
+  (void) name;
+  (void) namelen;
+  return -1;
+
+#else
+  int err;
+  char* dot;
+
+#ifdef DEBUGBUILD
+
+  /* Override host name when environment variable CURL_GETHOSTNAME is set */
+  const char *force_hostname = getenv("CURL_GETHOSTNAME");
+  if(force_hostname) {
+    strncpy(name, force_hostname, namelen);
+    err = 0;
+  }
+  else {
+    name[0] = '\0';
+    err = gethostname(name, namelen);
+  }
+
+#else /* DEBUGBUILD */
+
+  /* The call to system's gethostname() might get intercepted by the
+     libhostname library when libcurl is built as a non-debug shared
+     library when running the test suite. */
+  name[0] = '\0';
+  err = gethostname(name, namelen);
+
+#endif
+
+  name[namelen - 1] = '\0';
+
+  if(err)
+    return err;
+
+  /* Truncate domain, leave only machine name */
+  dot = strchr(name, '.');
+  if(dot)
+    *dot = '\0';
+
+  return 0;
+#endif
+
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_gethostname.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_gethostname.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_gethostname.h	(revision 164)
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_GETHOSTNAME_H
+#define HEADER_CURL_GETHOSTNAME_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Hostname buffer size */
+#define HOSTNAME_MAX 1024
+
+/* This returns the local machine's un-qualified hostname */
+int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen);
+
+#endif /* HEADER_CURL_GETHOSTNAME_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_gssapi.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_gssapi.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_gssapi.c	(revision 164)
@@ -0,0 +1,120 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_GSSAPI
+
+#include "curl_gssapi.h"
+#include "sendf.h"
+
+static char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02";
+gss_OID_desc Curl_spnego_mech_oid = { 6, &spnego_oid_bytes };
+static char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02";
+gss_OID_desc Curl_krb5_mech_oid = { 9, &krb5_oid_bytes };
+
+OM_uint32 Curl_gss_init_sec_context(
+    struct SessionHandle *data,
+    OM_uint32 *minor_status,
+    gss_ctx_id_t *context,
+    gss_name_t target_name,
+    gss_OID mech_type,
+    gss_channel_bindings_t input_chan_bindings,
+    gss_buffer_t input_token,
+    gss_buffer_t output_token,
+    const bool mutual_auth,
+    OM_uint32 *ret_flags)
+{
+  OM_uint32 req_flags = GSS_C_REPLAY_FLAG;
+
+  if(mutual_auth)
+    req_flags |= GSS_C_MUTUAL_FLAG;
+
+  if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) {
+#ifdef GSS_C_DELEG_POLICY_FLAG
+    req_flags |= GSS_C_DELEG_POLICY_FLAG;
+#else
+    infof(data, "warning: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not "
+        "compiled in\n");
+#endif
+  }
+
+  if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG)
+    req_flags |= GSS_C_DELEG_FLAG;
+
+  return gss_init_sec_context(minor_status,
+                              GSS_C_NO_CREDENTIAL, /* cred_handle */
+                              context,
+                              target_name,
+                              mech_type,
+                              req_flags,
+                              0, /* time_req */
+                              input_chan_bindings,
+                              input_token,
+                              NULL, /* actual_mech_type */
+                              output_token,
+                              ret_flags,
+                              NULL /* time_rec */);
+}
+
+/*
+ * Curl_gss_log_error()
+ *
+ * This is used to log a GSS-API error status.
+ *
+ * Parameters:
+ *
+ * data    [in] - The session handle.
+ * status  [in] - The status code.
+ * prefix  [in] - The prefix of the log message.
+ */
+void Curl_gss_log_error(struct SessionHandle *data, OM_uint32 status,
+                        const char *prefix)
+{
+  OM_uint32 maj_stat;
+  OM_uint32 min_stat;
+  OM_uint32 msg_ctx = 0;
+  gss_buffer_desc status_string;
+  char buf[1024];
+  size_t len;
+
+  snprintf(buf, sizeof(buf), "%s", prefix);
+  len = strlen(buf);
+  do {
+    maj_stat = gss_display_status(&min_stat,
+                                  status,
+                                  GSS_C_MECH_CODE,
+                                  GSS_C_NO_OID,
+                                  &msg_ctx,
+                                  &status_string);
+    if(sizeof(buf) > len + status_string.length + 1) {
+      snprintf(buf + len, sizeof(buf) - len,
+        ": %s", (char*)status_string.value);
+      len += status_string.length;
+    }
+    gss_release_buffer(&min_stat, &status_string);
+  } while(!GSS_ERROR(maj_stat) && msg_ctx != 0);
+
+  infof(data, "%s\n", buf);
+}
+
+#endif /* HAVE_GSSAPI */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_gssapi.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_gssapi.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_gssapi.h	(revision 164)
@@ -0,0 +1,75 @@
+#ifndef HEADER_CURL_GSSAPI_H
+#define HEADER_CURL_GSSAPI_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "urldata.h"
+
+#ifdef HAVE_GSSAPI
+
+#ifdef HAVE_GSSGNU
+#  include <gss.h>
+#elif defined HAVE_GSSMIT
+   /* MIT style */
+#  include <gssapi/gssapi.h>
+#  include <gssapi/gssapi_generic.h>
+#  include <gssapi/gssapi_krb5.h>
+#else
+   /* Heimdal-style */
+#  include <gssapi.h>
+#endif
+
+extern gss_OID_desc Curl_spnego_mech_oid;
+extern gss_OID_desc Curl_krb5_mech_oid;
+
+/* Common method for using GSS-API */
+OM_uint32 Curl_gss_init_sec_context(
+    struct SessionHandle *data,
+    OM_uint32 *minor_status,
+    gss_ctx_id_t *context,
+    gss_name_t target_name,
+    gss_OID mech_type,
+    gss_channel_bindings_t input_chan_bindings,
+    gss_buffer_t input_token,
+    gss_buffer_t output_token,
+    const bool mutual_auth,
+    OM_uint32 *ret_flags);
+
+/* Helper to log a GSS-API error status */
+void Curl_gss_log_error(struct SessionHandle *data, OM_uint32 status,
+                        const char *prefix);
+
+/* Provide some definitions missing in old headers */
+#ifdef HAVE_OLD_GSSMIT
+#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
+#define NCOMPAT 1
+#endif
+
+/* Define our privacy and integrity protection values */
+#define GSSAUTH_P_NONE      1
+#define GSSAUTH_P_INTEGRITY 2
+#define GSSAUTH_P_PRIVACY   4
+
+#endif /* HAVE_GSSAPI */
+
+#endif /* HEADER_CURL_GSSAPI_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_hmac.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_hmac.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_hmac.h	(revision 164)
@@ -0,0 +1,67 @@
+#ifndef HEADER_CURL_HMAC_H
+#define HEADER_CURL_HMAC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+
+typedef void    (* HMAC_hinit_func)(void * context);
+typedef void    (* HMAC_hupdate_func)(void * context,
+                                      const unsigned char * data,
+                                      unsigned int len);
+typedef void    (* HMAC_hfinal_func)(unsigned char * result, void * context);
+
+
+/* Per-hash function HMAC parameters. */
+
+typedef struct {
+  HMAC_hinit_func       hmac_hinit;     /* Initialize context procedure. */
+  HMAC_hupdate_func     hmac_hupdate;   /* Update context with data. */
+  HMAC_hfinal_func      hmac_hfinal;    /* Get final result procedure. */
+  unsigned int          hmac_ctxtsize;  /* Context structure size. */
+  unsigned int          hmac_maxkeylen; /* Maximum key length (bytes). */
+  unsigned int          hmac_resultlen; /* Result length (bytes). */
+} HMAC_params;
+
+
+/* HMAC computation context. */
+
+typedef struct {
+  const HMAC_params *   hmac_hash;      /* Hash function definition. */
+  void *                hmac_hashctxt1; /* Hash function context 1. */
+  void *                hmac_hashctxt2; /* Hash function context 2. */
+} HMAC_context;
+
+
+/* Prototypes. */
+
+HMAC_context * Curl_HMAC_init(const HMAC_params * hashparams,
+                              const unsigned char * key,
+                              unsigned int keylen);
+int Curl_HMAC_update(HMAC_context * context,
+                     const unsigned char * data,
+                     unsigned int len);
+int Curl_HMAC_final(HMAC_context * context, unsigned char * result);
+
+#endif
+
+#endif /* HEADER_CURL_HMAC_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_ldap.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_ldap.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_ldap.h	(revision 164)
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_LDAP_H
+#define HEADER_CURL_LDAP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_LDAP
+extern const struct Curl_handler Curl_handler_ldap;
+
+#if !defined(CURL_DISABLE_LDAPS) && \
+    ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
+     (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
+extern const struct Curl_handler Curl_handler_ldaps;
+#endif
+
+#endif
+#endif /* HEADER_CURL_LDAP_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_md4.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_md4.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_md4.h	(revision 164)
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_MD4_H
+#define HEADER_CURL_MD4_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/* NSS and OS/400 crypto library do not provide the MD4 hash algorithm, so
+ * that we have a local implementation of it */
+#if defined(USE_NSS) || defined(USE_OS400CRYPTO)
+
+void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len);
+
+#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) */
+
+#endif /* HEADER_CURL_MD4_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_md5.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_md5.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_md5.h	(revision 164)
@@ -0,0 +1,63 @@
+#ifndef HEADER_CURL_MD5_H
+#define HEADER_CURL_MD5_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+#include "curl_hmac.h"
+
+#define MD5_DIGEST_LEN  16
+
+typedef void (* Curl_MD5_init_func)(void *context);
+typedef void (* Curl_MD5_update_func)(void *context,
+                                      const unsigned char *data,
+                                      unsigned int len);
+typedef void (* Curl_MD5_final_func)(unsigned char *result, void *context);
+
+typedef struct {
+  Curl_MD5_init_func     md5_init_func;   /* Initialize context procedure */
+  Curl_MD5_update_func   md5_update_func; /* Update context with data */
+  Curl_MD5_final_func    md5_final_func;  /* Get final result procedure */
+  unsigned int           md5_ctxtsize;  /* Context structure size */
+  unsigned int           md5_resultlen; /* Result length (bytes) */
+} MD5_params;
+
+typedef struct {
+  const MD5_params      *md5_hash;      /* Hash function definition */
+  void                  *md5_hashctx;   /* Hash function context */
+} MD5_context;
+
+extern const MD5_params Curl_DIGEST_MD5[1];
+extern const HMAC_params Curl_HMAC_MD5[1];
+
+void Curl_md5it(unsigned char *output,
+                const unsigned char *input);
+
+MD5_context * Curl_MD5_init(const MD5_params *md5params);
+int Curl_MD5_update(MD5_context *context,
+                    const unsigned char *data,
+                    unsigned int len);
+int Curl_MD5_final(MD5_context *context, unsigned char *result);
+
+#endif
+
+#endif /* HEADER_CURL_MD5_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_memory.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_memory.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_memory.h	(revision 164)
@@ -0,0 +1,143 @@
+#ifndef HEADER_CURL_MEMORY_H
+#define HEADER_CURL_MEMORY_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Nasty internal details ahead...
+ *
+ * File curl_memory.h must be included by _all_ *.c source files
+ * that use memory related functions strdup, malloc, calloc, realloc
+ * or free, and given source file is used to build libcurl library.
+ * It should be included immediately before memdebug.h as the last files
+ * included to avoid undesired interaction with other memory function
+ * headers in dependent libraries.
+ *
+ * There is nearly no exception to above rule. All libcurl source
+ * files in 'lib' subdirectory as well as those living deep inside
+ * 'packages' subdirectories and linked together in order to build
+ * libcurl library shall follow it.
+ *
+ * File lib/strdup.c is an exception, given that it provides a strdup
+ * clone implementation while using malloc. Extra care needed inside
+ * this one. TODO: revisit this paragraph and related code.
+ *
+ * The need for curl_memory.h inclusion is due to libcurl's feature
+ * of allowing library user to provide memory replacement functions,
+ * memory callbacks, at runtime with curl_global_init_mem()
+ *
+ * Any *.c source file used to build libcurl library that does not
+ * include curl_memory.h and uses any memory function of the five
+ * mentioned above will compile without any indication, but it will
+ * trigger weird memory related issues at runtime.
+ *
+ * OTOH some source files from 'lib' subdirectory may additionally be
+ * used directly as source code when using some curlx_ functions by
+ * third party programs that don't even use libcurl at all. When using
+ * these source files in this way it is necessary these are compiled
+ * with CURLX_NO_MEMORY_CALLBACKS defined, in order to ensure that no
+ * attempt of calling libcurl's memory callbacks is done from code
+ * which can not use this machinery.
+ *
+ * Notice that libcurl's 'memory tracking' system works chaining into
+ * the memory callback machinery. This implies that when compiling
+ * 'lib' source files with CURLX_NO_MEMORY_CALLBACKS defined this file
+ * disengages usage of libcurl's 'memory tracking' system, defining
+ * MEMDEBUG_NODEFINES and overriding CURLDEBUG purpose.
+ *
+ * CURLX_NO_MEMORY_CALLBACKS takes precedence over CURLDEBUG. This is
+ * done in order to allow building a 'memory tracking' enabled libcurl
+ * and at the same time allow building programs which do not use it.
+ *
+ * Programs and libraries in 'tests' subdirectories have specific
+ * purposes and needs, and as such each one will use whatever fits
+ * best, depending additionally wether it links with libcurl or not.
+ *
+ * Caveat emptor. Proper curlx_* separation is a work in progress
+ * the same as CURLX_NO_MEMORY_CALLBACKS usage, some adjustments may
+ * still be required. IOW don't use them yet, there are sharp edges.
+ */
+
+#ifdef HEADER_CURL_MEMDEBUG_H
+#error "Header memdebug.h shall not be included before curl_memory.h"
+#endif
+
+#ifndef CURLX_NO_MEMORY_CALLBACKS
+
+#include <curl/curl.h> /* for the callback typedefs */
+
+extern curl_malloc_callback Curl_cmalloc;
+extern curl_free_callback Curl_cfree;
+extern curl_realloc_callback Curl_crealloc;
+extern curl_strdup_callback Curl_cstrdup;
+extern curl_calloc_callback Curl_ccalloc;
+#if defined(WIN32) && defined(UNICODE)
+extern curl_wcsdup_callback Curl_cwcsdup;
+#endif
+
+#ifndef CURLDEBUG
+
+/*
+ * libcurl's 'memory tracking' system defines strdup, malloc, calloc,
+ * realloc and free, along with others, in memdebug.h in a different
+ * way although still using memory callbacks forward declared above.
+ * When using the 'memory tracking' system (CURLDEBUG defined) we do
+ * not define here the five memory functions given that definitions
+ * from memdebug.h are the ones that shall be used.
+ */
+
+#undef strdup
+#define strdup(ptr) Curl_cstrdup(ptr)
+#undef malloc
+#define malloc(size) Curl_cmalloc(size)
+#undef calloc
+#define calloc(nbelem,size) Curl_ccalloc(nbelem, size)
+#undef realloc
+#define realloc(ptr,size) Curl_crealloc(ptr, size)
+#undef free
+#define free(ptr) Curl_cfree(ptr)
+
+#ifdef WIN32
+#  ifdef UNICODE
+#    undef wcsdup
+#    define wcsdup(ptr) Curl_cwcsdup(ptr)
+#    undef _wcsdup
+#    define _wcsdup(ptr) Curl_cwcsdup(ptr)
+#    undef _tcsdup
+#    define _tcsdup(ptr) Curl_cwcsdup(ptr)
+#  else
+#    undef _tcsdup
+#    define _tcsdup(ptr) Curl_cstrdup(ptr)
+#  endif
+#endif
+
+#endif /* CURLDEBUG */
+
+#else /* CURLX_NO_MEMORY_CALLBACKS */
+
+#ifndef MEMDEBUG_NODEFINES
+#define MEMDEBUG_NODEFINES
+#endif
+
+#endif /* CURLX_NO_MEMORY_CALLBACKS */
+
+#endif /* HEADER_CURL_MEMORY_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_memrchr.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_memrchr.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_memrchr.c	(revision 164)
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "curl_memrchr.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifndef HAVE_MEMRCHR
+
+/*
+ * Curl_memrchr()
+ *
+ * Our memrchr() function clone for systems which lack this function. The
+ * memrchr() function is like the memchr() function, except that it searches
+ * backwards from the end of the n bytes pointed to by s instead of forward
+ * from the beginning.
+ */
+
+void *
+Curl_memrchr(const void *s, int c, size_t n)
+{
+  const unsigned char *p = s;
+  const unsigned char *q = s;
+
+  p += n - 1;
+
+  while(p >= q) {
+    if(*p == (unsigned char)c)
+      return (void *)p;
+    p--;
+  }
+
+  return NULL;
+}
+
+#endif /* HAVE_MEMRCHR */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_memrchr.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_memrchr.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_memrchr.h	(revision 164)
@@ -0,0 +1,44 @@
+#ifndef HEADER_CURL_MEMRCHR_H
+#define HEADER_CURL_MEMRCHR_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_MEMRCHR
+
+#ifdef HAVE_STRING_H
+#  include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+
+#else /* HAVE_MEMRCHR */
+
+void *Curl_memrchr(const void *s, int c, size_t n);
+
+#define memrchr(x,y,z) Curl_memrchr((x),(y),(z))
+
+#endif /* HAVE_MEMRCHR */
+
+#endif /* HEADER_CURL_MEMRCHR_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_multibyte.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_multibyte.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_multibyte.c	(revision 164)
@@ -0,0 +1,82 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
+                                defined(USE_WIN32_LDAP)) && defined(UNICODE))
+
+ /*
+  * MultiByte conversions using Windows kernel32 library.
+  */
+
+#include "curl_multibyte.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8)
+{
+  wchar_t *str_w = NULL;
+
+  if(str_utf8) {
+    int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
+                                        str_utf8, -1, NULL, 0);
+    if(str_w_len > 0) {
+      str_w = malloc(str_w_len * sizeof(wchar_t));
+      if(str_w) {
+        if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
+                               str_w_len) == 0) {
+          free(str_w);
+          return NULL;
+        }
+      }
+    }
+  }
+
+  return str_w;
+}
+
+char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
+{
+  char *str_utf8 = NULL;
+
+  if(str_w) {
+    int str_utf8_len = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL,
+                                           0, NULL, NULL);
+    if(str_utf8_len > 0) {
+      str_utf8 = malloc(str_utf8_len * sizeof(wchar_t));
+      if(str_utf8) {
+        if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
+                               NULL, FALSE) == 0) {
+          free(str_utf8);
+          return NULL;
+        }
+      }
+    }
+  }
+
+  return str_utf8;
+}
+
+#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_multibyte.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_multibyte.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_multibyte.h	(revision 164)
@@ -0,0 +1,92 @@
+#ifndef HEADER_CURL_MULTIBYTE_H
+#define HEADER_CURL_MULTIBYTE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
+                                defined(USE_WIN32_LDAP)) && defined(UNICODE))
+
+ /*
+  * MultiByte conversions using Windows kernel32 library.
+  */
+
+wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8);
+char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w);
+
+#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
+
+
+#if defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI) || \
+    defined(USE_WIN32_LDAP)
+
+/*
+ * Macros Curl_convert_UTF8_to_tchar(), Curl_convert_tchar_to_UTF8()
+ * and Curl_unicodefree() main purpose is to minimize the number of
+ * preprocessor conditional directives needed by code using these
+ * to differentiate UNICODE from non-UNICODE builds.
+ *
+ * When building with UNICODE defined, this two macros
+ * Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8()
+ * return a pointer to a newly allocated memory area holding result.
+ * When the result is no longer needed, allocated memory is intended
+ * to be free'ed with Curl_unicodefree().
+ *
+ * When building without UNICODE defined, this macros
+ * Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8()
+ * return the pointer received as argument. Curl_unicodefree() does
+ * no actual free'ing of this pointer it is simply set to NULL.
+ */
+
+#ifdef UNICODE
+
+#define Curl_convert_UTF8_to_tchar(ptr) Curl_convert_UTF8_to_wchar((ptr))
+#define Curl_convert_tchar_to_UTF8(ptr) Curl_convert_wchar_to_UTF8((ptr))
+#define Curl_unicodefree(ptr) \
+  do {if((ptr)) {free((ptr)); (ptr) = NULL;}} WHILE_FALSE
+
+typedef union {
+  unsigned short       *tchar_ptr;
+  const unsigned short *const_tchar_ptr;
+  unsigned short       *tbyte_ptr;
+  const unsigned short *const_tbyte_ptr;
+} xcharp_u;
+
+#else
+
+#define Curl_convert_UTF8_to_tchar(ptr) (ptr)
+#define Curl_convert_tchar_to_UTF8(ptr) (ptr)
+#define Curl_unicodefree(ptr) \
+  do {(ptr) = NULL;} WHILE_FALSE
+
+typedef union {
+  char                *tchar_ptr;
+  const char          *const_tchar_ptr;
+  unsigned char       *tbyte_ptr;
+  const unsigned char *const_tbyte_ptr;
+} xcharp_u;
+
+#endif /* UNICODE */
+
+#endif /* USE_WIN32_IDN || USE_WINDOWS_SSPI || USE_WIN32_LDAP */
+
+#endif /* HEADER_CURL_MULTIBYTE_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm.c	(revision 164)
@@ -0,0 +1,239 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
+
+/*
+ * NTLM details:
+ *
+ * http://davenport.sourceforge.net/ntlm.html
+ * http://www.innovation.ch/java/ntlm.html
+ */
+
+#define DEBUG_ME 0
+
+#include "urldata.h"
+#include "sendf.h"
+#include "rawstr.h"
+#include "curl_ntlm.h"
+#include "curl_ntlm_msgs.h"
+#include "curl_ntlm_wb.h"
+#include "curl_sasl.h"
+#include "url.h"
+#include "curl_printf.h"
+
+#if defined(USE_NSS)
+#include "vtls/nssg.h"
+#elif defined(USE_WINDOWS_SSPI)
+#include "curl_sspi.h"
+#endif
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if DEBUG_ME
+# define DEBUG_OUT(x) x
+#else
+# define DEBUG_OUT(x) Curl_nop_stmt
+#endif
+
+CURLcode Curl_input_ntlm(struct connectdata *conn,
+                         bool proxy,         /* if proxy or not */
+                         const char *header) /* rest of the www-authenticate:
+                                                header */
+{
+  /* point to the correct struct with this */
+  struct ntlmdata *ntlm;
+  CURLcode result = CURLE_OK;
+
+  ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
+
+  if(checkprefix("NTLM", header)) {
+    header += strlen("NTLM");
+
+    while(*header && ISSPACE(*header))
+      header++;
+
+    if(*header) {
+      result = Curl_sasl_decode_ntlm_type2_message(conn->data, header, ntlm);
+      if(result)
+        return result;
+
+      ntlm->state = NTLMSTATE_TYPE2; /* We got a type-2 message */
+    }
+    else {
+      if(ntlm->state == NTLMSTATE_LAST) {
+        infof(conn->data, "NTLM auth restarted\n");
+        Curl_http_ntlm_cleanup(conn);
+      }
+      else if(ntlm->state == NTLMSTATE_TYPE3) {
+        infof(conn->data, "NTLM handshake rejected\n");
+        Curl_http_ntlm_cleanup(conn);
+        ntlm->state = NTLMSTATE_NONE;
+        return CURLE_REMOTE_ACCESS_DENIED;
+      }
+      else if(ntlm->state >= NTLMSTATE_TYPE1) {
+        infof(conn->data, "NTLM handshake failure (internal error)\n");
+        return CURLE_REMOTE_ACCESS_DENIED;
+      }
+
+      ntlm->state = NTLMSTATE_TYPE1; /* We should send away a type-1 */
+    }
+  }
+
+  return result;
+}
+
+/*
+ * This is for creating ntlm header output
+ */
+CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
+{
+  char *base64 = NULL;
+  size_t len = 0;
+  CURLcode result;
+
+  /* point to the address of the pointer that holds the string to send to the
+     server, which is for a plain host or for a HTTP proxy */
+  char **allocuserpwd;
+
+  /* point to the name and password for this */
+  const char *userp;
+  const char *passwdp;
+
+  /* point to the correct struct with this */
+  struct ntlmdata *ntlm;
+  struct auth *authp;
+
+  DEBUGASSERT(conn);
+  DEBUGASSERT(conn->data);
+
+#ifdef USE_NSS
+  if(CURLE_OK != Curl_nss_force_init(conn->data))
+    return CURLE_OUT_OF_MEMORY;
+#endif
+
+  if(proxy) {
+    allocuserpwd = &conn->allocptr.proxyuserpwd;
+    userp = conn->proxyuser;
+    passwdp = conn->proxypasswd;
+    ntlm = &conn->proxyntlm;
+    authp = &conn->data->state.authproxy;
+  }
+  else {
+    allocuserpwd = &conn->allocptr.userpwd;
+    userp = conn->user;
+    passwdp = conn->passwd;
+    ntlm = &conn->ntlm;
+    authp = &conn->data->state.authhost;
+  }
+  authp->done = FALSE;
+
+  /* not set means empty */
+  if(!userp)
+    userp = "";
+
+  if(!passwdp)
+    passwdp = "";
+
+#ifdef USE_WINDOWS_SSPI
+  if(s_hSecDll == NULL) {
+    /* not thread safe and leaks - use curl_global_init() to avoid */
+    CURLcode err = Curl_sspi_global_init();
+    if(s_hSecDll == NULL)
+      return err;
+  }
+#endif
+
+  switch(ntlm->state) {
+  case NTLMSTATE_TYPE1:
+  default: /* for the weird cases we (re)start here */
+    /* Create a type-1 message */
+    result = Curl_sasl_create_ntlm_type1_message(userp, passwdp, ntlm, &base64,
+                                                 &len);
+    if(result)
+      return result;
+
+    if(base64) {
+      free(*allocuserpwd);
+      *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
+                              proxy ? "Proxy-" : "",
+                              base64);
+      free(base64);
+      if(!*allocuserpwd)
+        return CURLE_OUT_OF_MEMORY;
+
+      DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
+    }
+    break;
+
+  case NTLMSTATE_TYPE2:
+    /* We already received the type-2 message, create a type-3 message */
+    result = Curl_sasl_create_ntlm_type3_message(conn->data, userp, passwdp,
+                                                 ntlm, &base64, &len);
+    if(result)
+      return result;
+
+    if(base64) {
+      free(*allocuserpwd);
+      *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
+                              proxy ? "Proxy-" : "",
+                              base64);
+      free(base64);
+      if(!*allocuserpwd)
+        return CURLE_OUT_OF_MEMORY;
+
+      DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
+
+      ntlm->state = NTLMSTATE_TYPE3; /* we send a type-3 */
+      authp->done = TRUE;
+    }
+    break;
+
+  case NTLMSTATE_TYPE3:
+    /* connection is already authenticated,
+     * don't send a header in future requests */
+    ntlm->state = NTLMSTATE_LAST;
+    /* fall-through */
+  case NTLMSTATE_LAST:
+    Curl_safefree(*allocuserpwd);
+    authp->done = TRUE;
+    break;
+  }
+
+  return CURLE_OK;
+}
+
+void Curl_http_ntlm_cleanup(struct connectdata *conn)
+{
+  Curl_sasl_ntlm_cleanup(&conn->ntlm);
+  Curl_sasl_ntlm_cleanup(&conn->proxyntlm);
+
+#if defined(NTLM_WB_ENABLED)
+  Curl_ntlm_wb_cleanup(conn);
+#endif
+}
+
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm.h	(revision 164)
@@ -0,0 +1,40 @@
+#ifndef HEADER_CURL_NTLM_H
+#define HEADER_CURL_NTLM_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
+
+/* this is for ntlm header input */
+CURLcode Curl_input_ntlm(struct connectdata *conn, bool proxy,
+                         const char *header);
+
+/* this is for creating ntlm header output */
+CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
+
+void Curl_http_ntlm_cleanup(struct connectdata *conn);
+
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
+
+#endif /* HEADER_CURL_NTLM_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_core.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_core.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_core.c	(revision 164)
@@ -0,0 +1,766 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM)
+
+/*
+ * NTLM details:
+ *
+ * http://davenport.sourceforge.net/ntlm.html
+ * http://www.innovation.ch/java/ntlm.html
+ */
+
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+#ifdef USE_OPENSSL
+
+#  ifdef USE_OPENSSL
+#    include <openssl/des.h>
+#    ifndef OPENSSL_NO_MD4
+#      include <openssl/md4.h>
+#    endif
+#    include <openssl/md5.h>
+#    include <openssl/ssl.h>
+#    include <openssl/rand.h>
+#  else
+#    include <des.h>
+#    ifndef OPENSSL_NO_MD4
+#      include <md4.h>
+#    endif
+#    include <md5.h>
+#    include <ssl.h>
+#    include <rand.h>
+#  endif
+#  if (OPENSSL_VERSION_NUMBER < 0x00907001L)
+#    define DES_key_schedule des_key_schedule
+#    define DES_cblock des_cblock
+#    define DES_set_odd_parity des_set_odd_parity
+#    define DES_set_key des_set_key
+#    define DES_ecb_encrypt des_ecb_encrypt
+#    define DESKEY(x) x
+#    define DESKEYARG(x) x
+#  else
+#    define DESKEYARG(x) *x
+#    define DESKEY(x) &x
+#  endif
+
+#elif defined(USE_GNUTLS_NETTLE)
+
+#  include <nettle/des.h>
+#  include <nettle/md4.h>
+
+#elif defined(USE_GNUTLS)
+
+#  include <gcrypt.h>
+#  define MD5_DIGEST_LENGTH 16
+#  define MD4_DIGEST_LENGTH 16
+
+#elif defined(USE_NSS)
+
+#  include <nss.h>
+#  include <pk11pub.h>
+#  include <hasht.h>
+#  include "curl_md4.h"
+#  define MD5_DIGEST_LENGTH MD5_LENGTH
+
+#elif defined(USE_DARWINSSL)
+
+#  include <CommonCrypto/CommonCryptor.h>
+#  include <CommonCrypto/CommonDigest.h>
+
+#elif defined(USE_OS400CRYPTO)
+#  include "cipher.mih"  /* mih/cipher */
+#  include "curl_md4.h"
+#elif defined(USE_WIN32_CRYPTO)
+#  include <wincrypt.h>
+#else
+#  error "Can't compile NTLM support without a crypto library."
+#endif
+
+#include "urldata.h"
+#include "non-ascii.h"
+#include "rawstr.h"
+#include "curl_ntlm_core.h"
+#include "curl_md5.h"
+#include "curl_hmac.h"
+#include "warnless.h"
+#include "curl_endian.h"
+#include "curl_des.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define NTLM_HMAC_MD5_LEN     (16)
+#define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00"
+#define NTLMv2_BLOB_LEN       (44 -16 + ntlm->target_info_len + 4)
+
+/*
+* Turns a 56-bit key into being 64-bit wide.
+*/
+static void extend_key_56_to_64(const unsigned char *key_56, char *key)
+{
+  key[0] = key_56[0];
+  key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
+  key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
+  key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
+  key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
+  key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
+  key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
+  key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
+}
+
+#ifdef USE_OPENSSL
+/*
+ * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.  The
+ * key schedule ks is also set.
+ */
+static void setup_des_key(const unsigned char *key_56,
+                          DES_key_schedule DESKEYARG(ks))
+{
+  DES_cblock key;
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, (char *) key);
+
+  /* Set the key parity to odd */
+#ifndef HAVE_DES_SET_ODD_PARITY /* older boringssl */
+  Curl_des_set_odd_parity((unsigned char *) &key, sizeof(key));
+#else
+  DES_set_odd_parity(&key);
+#endif
+
+  /* Set the key */
+  DES_set_key(&key, ks);
+}
+
+#elif defined(USE_GNUTLS_NETTLE)
+
+static void setup_des_key(const unsigned char *key_56,
+                          struct des_ctx *des)
+{
+  char key[8];
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+  /* Set the key */
+  des_set_key(des, (const uint8_t *) key);
+}
+
+#elif defined(USE_GNUTLS)
+
+/*
+ * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.
+ */
+static void setup_des_key(const unsigned char *key_56,
+                          gcry_cipher_hd_t *des)
+{
+  char key[8];
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+  /* Set the key */
+  gcry_cipher_setkey(*des, key, sizeof(key));
+}
+
+#elif defined(USE_NSS)
+
+/*
+ * Expands a 56 bit key KEY_56 to 64 bit and encrypts 64 bit of data, using
+ * the expanded key.  The caller is responsible for giving 64 bit of valid
+ * data is IN and (at least) 64 bit large buffer as OUT.
+ */
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+                        const unsigned char *key_56)
+{
+  const CK_MECHANISM_TYPE mech = CKM_DES_ECB; /* DES cipher in ECB mode */
+  PK11SlotInfo *slot = NULL;
+  char key[8];                                /* expanded 64 bit key */
+  SECItem key_item;
+  PK11SymKey *symkey = NULL;
+  SECItem *param = NULL;
+  PK11Context *ctx = NULL;
+  int out_len;                                /* not used, required by NSS */
+  bool rv = FALSE;
+
+  /* use internal slot for DES encryption (requires NSS to be initialized) */
+  slot = PK11_GetInternalKeySlot();
+  if(!slot)
+    return FALSE;
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+  /* Import the key */
+  key_item.data = (unsigned char *)key;
+  key_item.len = sizeof(key);
+  symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT,
+                             &key_item, NULL);
+  if(!symkey)
+    goto fail;
+
+  /* Create the DES encryption context */
+  param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL);
+  if(!param)
+    goto fail;
+  ctx = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symkey, param);
+  if(!ctx)
+    goto fail;
+
+  /* Perform the encryption */
+  if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8,
+                                 (unsigned char *)in, /* inbuflen */ 8)
+      && SECSuccess == PK11_Finalize(ctx))
+    rv = /* all OK */ TRUE;
+
+fail:
+  /* cleanup */
+  if(ctx)
+    PK11_DestroyContext(ctx, PR_TRUE);
+  if(symkey)
+    PK11_FreeSymKey(symkey);
+  if(param)
+    SECITEM_FreeItem(param, PR_TRUE);
+  PK11_FreeSlot(slot);
+  return rv;
+}
+
+#elif defined(USE_DARWINSSL)
+
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+                        const unsigned char *key_56)
+{
+  char key[8];
+  size_t out_len;
+  CCCryptorStatus err;
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+  /* Perform the encryption */
+  err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key,
+                kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out,
+                8 /* outbuflen */, &out_len);
+
+  return err == kCCSuccess;
+}
+
+#elif defined(USE_OS400CRYPTO)
+
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+                        const unsigned char *key_56)
+{
+  char key[8];
+  _CIPHER_Control_T ctl;
+
+  /* Setup the cipher control structure */
+  ctl.Func_ID = ENCRYPT_ONLY;
+  ctl.Data_Len = sizeof(key);
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, ctl.Crypto_Key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) ctl.Crypto_Key, ctl.Data_Len);
+
+  /* Perform the encryption */
+  _CIPHER((_SPCPTR *) &out, &ctl, (_SPCPTR *) &in);
+
+  return TRUE;
+}
+
+#elif defined(USE_WIN32_CRYPTO)
+
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+                        const unsigned char *key_56)
+{
+  HCRYPTPROV hprov;
+  HCRYPTKEY hkey;
+  struct {
+    BLOBHEADER hdr;
+    unsigned int len;
+    char key[8];
+  } blob;
+  DWORD len = 8;
+
+  /* Acquire the crypto provider */
+  if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
+                          CRYPT_VERIFYCONTEXT))
+    return FALSE;
+
+  /* Setup the key blob structure */
+  memset(&blob, 0, sizeof(blob));
+  blob.hdr.bType = PLAINTEXTKEYBLOB;
+  blob.hdr.bVersion = 2;
+  blob.hdr.aiKeyAlg = CALG_DES;
+  blob.len = sizeof(blob.key);
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, blob.key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) blob.key, sizeof(blob.key));
+
+  /* Import the key */
+  if(!CryptImportKey(hprov, (BYTE *) &blob, sizeof(blob), 0, 0, &hkey)) {
+    CryptReleaseContext(hprov, 0);
+
+    return FALSE;
+  }
+
+  memcpy(out, in, 8);
+
+  /* Perform the encryption */
+  CryptEncrypt(hkey, 0, FALSE, 0, out, &len, len);
+
+  CryptDestroyKey(hkey);
+  CryptReleaseContext(hprov, 0);
+
+  return TRUE;
+}
+
+#endif /* defined(USE_WIN32_CRYPTO) */
+
+ /*
+  * takes a 21 byte array and treats it as 3 56-bit DES keys. The
+  * 8 byte plaintext is encrypted with each key and the resulting 24
+  * bytes are stored in the results array.
+  */
+void Curl_ntlm_core_lm_resp(const unsigned char *keys,
+                            const unsigned char *plaintext,
+                            unsigned char *results)
+{
+#ifdef USE_OPENSSL
+  DES_key_schedule ks;
+
+  setup_des_key(keys, DESKEY(ks));
+  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
+                  DESKEY(ks), DES_ENCRYPT);
+
+  setup_des_key(keys + 7, DESKEY(ks));
+  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 8),
+                  DESKEY(ks), DES_ENCRYPT);
+
+  setup_des_key(keys + 14, DESKEY(ks));
+  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16),
+                  DESKEY(ks), DES_ENCRYPT);
+#elif defined(USE_GNUTLS_NETTLE)
+  struct des_ctx des;
+  setup_des_key(keys, &des);
+  des_encrypt(&des, 8, results, plaintext);
+  setup_des_key(keys + 7, &des);
+  des_encrypt(&des, 8, results + 8, plaintext);
+  setup_des_key(keys + 14, &des);
+  des_encrypt(&des, 8, results + 16, plaintext);
+#elif defined(USE_GNUTLS)
+  gcry_cipher_hd_t des;
+
+  gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+  setup_des_key(keys, &des);
+  gcry_cipher_encrypt(des, results, 8, plaintext, 8);
+  gcry_cipher_close(des);
+
+  gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+  setup_des_key(keys + 7, &des);
+  gcry_cipher_encrypt(des, results + 8, 8, plaintext, 8);
+  gcry_cipher_close(des);
+
+  gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+  setup_des_key(keys + 14, &des);
+  gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8);
+  gcry_cipher_close(des);
+#elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \
+  || defined(USE_WIN32_CRYPTO)
+  encrypt_des(plaintext, results, keys);
+  encrypt_des(plaintext, results + 8, keys + 7);
+  encrypt_des(plaintext, results + 16, keys + 14);
+#endif
+}
+
+/*
+ * Set up lanmanager hashed password
+ */
+CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
+                                   const char *password,
+                                   unsigned char *lmbuffer /* 21 bytes */)
+{
+  CURLcode result;
+  unsigned char pw[14];
+  static const unsigned char magic[] = {
+    0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
+  };
+  size_t len = CURLMIN(strlen(password), 14);
+
+  Curl_strntoupper((char *)pw, password, len);
+  memset(&pw[len], 0, 14 - len);
+
+  /*
+   * The LanManager hashed password needs to be created using the
+   * password in the network encoding not the host encoding.
+   */
+  result = Curl_convert_to_network(data, (char *)pw, 14);
+  if(result)
+    return result;
+
+  {
+    /* Create LanManager hashed password. */
+
+#ifdef USE_OPENSSL
+    DES_key_schedule ks;
+
+    setup_des_key(pw, DESKEY(ks));
+    DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
+                    DESKEY(ks), DES_ENCRYPT);
+
+    setup_des_key(pw + 7, DESKEY(ks));
+    DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8),
+                    DESKEY(ks), DES_ENCRYPT);
+#elif defined(USE_GNUTLS_NETTLE)
+    struct des_ctx des;
+    setup_des_key(pw, &des);
+    des_encrypt(&des, 8, lmbuffer, magic);
+    setup_des_key(pw + 7, &des);
+    des_encrypt(&des, 8, lmbuffer + 8, magic);
+#elif defined(USE_GNUTLS)
+    gcry_cipher_hd_t des;
+
+    gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+    setup_des_key(pw, &des);
+    gcry_cipher_encrypt(des, lmbuffer, 8, magic, 8);
+    gcry_cipher_close(des);
+
+    gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+    setup_des_key(pw + 7, &des);
+    gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8);
+    gcry_cipher_close(des);
+#elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \
+  || defined(USE_WIN32_CRYPTO)
+    encrypt_des(magic, lmbuffer, pw);
+    encrypt_des(magic, lmbuffer + 8, pw + 7);
+#endif
+
+    memset(lmbuffer + 16, 0, 21 - 16);
+  }
+
+  return CURLE_OK;
+}
+
+#if USE_NTRESPONSES
+static void ascii_to_unicode_le(unsigned char *dest, const char *src,
+                                size_t srclen)
+{
+  size_t i;
+  for(i = 0; i < srclen; i++) {
+    dest[2 * i] = (unsigned char)src[i];
+    dest[2 * i + 1] = '\0';
+  }
+}
+
+#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
+
+static void ascii_uppercase_to_unicode_le(unsigned char *dest,
+                                          const char *src, size_t srclen)
+{
+  size_t i;
+  for(i = 0; i < srclen; i++) {
+    dest[2 * i] = (unsigned char)(toupper(src[i]));
+    dest[2 * i + 1] = '\0';
+  }
+}
+
+#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
+
+/*
+ * Set up nt hashed passwords
+ * @unittest: 1600
+ */
+CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
+                                   const char *password,
+                                   unsigned char *ntbuffer /* 21 bytes */)
+{
+  size_t len = strlen(password);
+  unsigned char *pw = malloc(len * 2);
+  CURLcode result;
+  if(!pw)
+    return CURLE_OUT_OF_MEMORY;
+
+  ascii_to_unicode_le(pw, password, len);
+
+  /*
+   * The NT hashed password needs to be created using the password in the
+   * network encoding not the host encoding.
+   */
+  result = Curl_convert_to_network(data, (char *)pw, len * 2);
+  if(result)
+    return result;
+
+  {
+    /* Create NT hashed password. */
+#ifdef USE_OPENSSL
+    MD4_CTX MD4pw;
+    MD4_Init(&MD4pw);
+    MD4_Update(&MD4pw, pw, 2 * len);
+    MD4_Final(ntbuffer, &MD4pw);
+#elif defined(USE_GNUTLS_NETTLE)
+    struct md4_ctx MD4pw;
+    md4_init(&MD4pw);
+    md4_update(&MD4pw, (unsigned int)(2 * len), pw);
+    md4_digest(&MD4pw, MD4_DIGEST_SIZE, ntbuffer);
+#elif defined(USE_GNUTLS)
+    gcry_md_hd_t MD4pw;
+    gcry_md_open(&MD4pw, GCRY_MD_MD4, 0);
+    gcry_md_write(MD4pw, pw, 2 * len);
+    memcpy (ntbuffer, gcry_md_read (MD4pw, 0), MD4_DIGEST_LENGTH);
+    gcry_md_close(MD4pw);
+#elif defined(USE_NSS) || defined(USE_OS400CRYPTO)
+    Curl_md4it(ntbuffer, pw, 2 * len);
+#elif defined(USE_DARWINSSL)
+    (void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer);
+#elif defined(USE_WIN32_CRYPTO)
+    HCRYPTPROV hprov;
+    if(CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
+                           CRYPT_VERIFYCONTEXT)) {
+      HCRYPTHASH hhash;
+      if(CryptCreateHash(hprov, CALG_MD4, 0, 0, &hhash)) {
+        DWORD length = 16;
+        CryptHashData(hhash, pw, (unsigned int)len * 2, 0);
+        CryptGetHashParam(hhash, HP_HASHVAL, ntbuffer, &length, 0);
+        CryptDestroyHash(hhash);
+      }
+      CryptReleaseContext(hprov, 0);
+    }
+#endif
+
+    memset(ntbuffer + 16, 0, 21 - 16);
+  }
+
+  free(pw);
+
+  return CURLE_OK;
+}
+
+#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
+
+/* This returns the HMAC MD5 digest */
+CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
+                       const unsigned char *data, unsigned int datalen,
+                       unsigned char *output)
+{
+  HMAC_context *ctxt = Curl_HMAC_init(Curl_HMAC_MD5, key, keylen);
+
+  if(!ctxt)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Update the digest with the given challenge */
+  Curl_HMAC_update(ctxt, data, datalen);
+
+  /* Finalise the digest */
+  Curl_HMAC_final(ctxt, output);
+
+  return CURLE_OK;
+}
+
+/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
+ * (uppercase UserName + Domain) as the data
+ */
+CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
+                                       const char *domain, size_t domlen,
+                                       unsigned char *ntlmhash,
+                                       unsigned char *ntlmv2hash)
+{
+  /* Unicode representation */
+  size_t identity_len = (userlen + domlen) * 2;
+  unsigned char *identity = malloc(identity_len);
+  CURLcode result = CURLE_OK;
+
+  if(!identity)
+    return CURLE_OUT_OF_MEMORY;
+
+  ascii_uppercase_to_unicode_le(identity, user, userlen);
+  ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
+
+  result = Curl_hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
+                         ntlmv2hash);
+
+  free(identity);
+
+  return result;
+}
+
+/*
+ * Curl_ntlm_core_mk_ntlmv2_resp()
+ *
+ * This creates the NTLMv2 response as set in the ntlm type-3 message.
+ *
+ * Parameters:
+ *
+ * ntlmv2hash       [in] - The ntlmv2 hash (16 bytes)
+ * challenge_client [in] - The client nonce (8 bytes)
+ * ntlm             [in] - The ntlm data struct being used to read TargetInfo
+                           and Server challenge received in the type-2 message
+ * ntresp          [out] - The address where a pointer to newly allocated
+ *                         memory holding the NTLMv2 response.
+ * ntresp_len      [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
+                                       unsigned char *challenge_client,
+                                       struct ntlmdata *ntlm,
+                                       unsigned char **ntresp,
+                                       unsigned int *ntresp_len)
+{
+/* NTLMv2 response structure :
+------------------------------------------------------------------------------
+0     HMAC MD5         16 bytes
+------BLOB--------------------------------------------------------------------
+16    Signature        0x01010000
+20    Reserved         long (0x00000000)
+24    Timestamp        LE, 64-bit signed value representing the number of
+                       tenths of a microsecond since January 1, 1601.
+32    Client Nonce     8 bytes
+40    Unknown          4 bytes
+44    Target Info      N bytes (from the type-2 message)
+44+N  Unknown          4 bytes
+------------------------------------------------------------------------------
+*/
+
+  unsigned int len = 0;
+  unsigned char *ptr = NULL;
+  unsigned char hmac_output[NTLM_HMAC_MD5_LEN];
+  curl_off_t tw;
+
+  CURLcode result = CURLE_OK;
+
+#if CURL_SIZEOF_CURL_OFF_T < 8
+#error "this section needs 64bit support to work"
+#endif
+
+  /* Calculate the timestamp */
+#ifdef DEBUGBUILD
+  char *force_timestamp = getenv("CURL_FORCETIME");
+  if(force_timestamp)
+    tw = CURL_OFF_T_C(11644473600) * 10000000;
+  else
+#endif
+    tw = ((curl_off_t)time(NULL) + CURL_OFF_T_C(11644473600)) * 10000000;
+
+  /* Calculate the response len */
+  len = NTLM_HMAC_MD5_LEN + NTLMv2_BLOB_LEN;
+
+  /* Allocate the response */
+  ptr = malloc(len);
+  if(!ptr)
+    return CURLE_OUT_OF_MEMORY;
+
+  memset(ptr, 0, len);
+
+  /* Create the BLOB structure */
+  snprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN,
+           NTLMv2_BLOB_SIGNATURE
+           "%c%c%c%c",  /* Reserved = 0 */
+           0, 0, 0, 0);
+
+  Curl_write64_le(tw, ptr + 24);
+  memcpy(ptr + 32, challenge_client, 8);
+  memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len);
+
+  /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
+  memcpy(ptr + 8, &ntlm->nonce[0], 8);
+  result = Curl_hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
+                         NTLMv2_BLOB_LEN + 8, hmac_output);
+  if(result) {
+    free(ptr);
+    return result;
+  }
+
+  /* Concatenate the HMAC MD5 output  with the BLOB */
+  memcpy(ptr, hmac_output, NTLM_HMAC_MD5_LEN);
+
+  /* Return the response */
+  *ntresp = ptr;
+  *ntresp_len = len;
+
+  return result;
+}
+
+/*
+ * Curl_ntlm_core_mk_lmv2_resp()
+ *
+ * This creates the LMv2 response as used in the ntlm type-3 message.
+ *
+ * Parameters:
+ *
+ * ntlmv2hash        [in] - The ntlmv2 hash (16 bytes)
+ * challenge_client  [in] - The client nonce (8 bytes)
+ * challenge_client  [in] - The server challenge (8 bytes)
+ * lmresp           [out] - The LMv2 response (24 bytes)
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode  Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
+                                      unsigned char *challenge_client,
+                                      unsigned char *challenge_server,
+                                      unsigned char *lmresp)
+{
+  unsigned char data[16];
+  unsigned char hmac_output[16];
+  CURLcode result = CURLE_OK;
+
+  memcpy(&data[0], challenge_server, 8);
+  memcpy(&data[8], challenge_client, 8);
+
+  result = Curl_hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
+  if(result)
+    return result;
+
+  /* Concatenate the HMAC MD5 output  with the client nonce */
+  memcpy(lmresp, hmac_output, 16);
+  memcpy(lmresp+16, challenge_client, 8);
+
+  return result;
+}
+
+#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
+
+#endif /* USE_NTRESPONSES */
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* USE_NTLM */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_core.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_core.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_core.h	(revision 164)
@@ -0,0 +1,106 @@
+#ifndef HEADER_CURL_NTLM_CORE_H
+#define HEADER_CURL_NTLM_CORE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM)
+
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+#ifdef USE_OPENSSL
+#  if !defined(OPENSSL_VERSION_NUMBER) && \
+      !defined(HEADER_SSL_H) && !defined(HEADER_MD5_H)
+#    error "curl_ntlm_core.h shall not be included before OpenSSL headers."
+#  endif
+#  ifdef OPENSSL_NO_MD4
+#    define USE_NTRESPONSES 0
+#    define USE_NTLM2SESSION 0
+#    define USE_NTLM_V2 0
+#  endif
+#endif
+
+/* Define USE_NTRESPONSES to 1 in order to make the type-3 message include
+ * the NT response message. */
+#ifndef USE_NTRESPONSES
+#define USE_NTRESPONSES 1
+#endif
+
+/* Define USE_NTLM2SESSION to 1 in order to make the type-3 message include the
+   NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a
+   Crypto engine that we have curl_ssl_md5sum() for. */
+#if !defined(USE_NTLM2SESSION) && USE_NTRESPONSES && !defined(USE_WIN32_CRYPTO)
+#define USE_NTLM2SESSION 1
+#endif
+
+/* Define USE_NTLM_V2 to 1 in order to allow the type-3 message to include the
+   LMv2 and NTLMv2 response messages, requires USE_NTRESPONSES defined to 1
+   and support for 64-bit integers. */
+#if !defined(USE_NTLM_V2) && USE_NTRESPONSES && (CURL_SIZEOF_CURL_OFF_T > 4)
+#define USE_NTLM_V2 1
+#endif
+
+void Curl_ntlm_core_lm_resp(const unsigned char *keys,
+                            const unsigned char *plaintext,
+                            unsigned char *results);
+
+CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
+                                   const char *password,
+                                   unsigned char *lmbuffer /* 21 bytes */);
+
+#if USE_NTRESPONSES
+CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
+                                   const char *password,
+                                   unsigned char *ntbuffer /* 21 bytes */);
+
+#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
+
+CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
+                       const unsigned char *data, unsigned int datalen,
+                       unsigned char *output);
+
+CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
+                                       const char *domain, size_t domlen,
+                                       unsigned char *ntlmhash,
+                                       unsigned char *ntlmv2hash);
+
+CURLcode  Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
+                                        unsigned char *challenge_client,
+                                        struct ntlmdata *ntlm,
+                                        unsigned char **ntresp,
+                                        unsigned int *ntresp_len);
+
+CURLcode  Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
+                                      unsigned char *challenge_client,
+                                      unsigned char *challenge_server,
+                                      unsigned char *lmresp);
+
+#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
+
+#endif /* USE_NTRESPONSES */
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* USE_NTLM */
+
+#endif /* HEADER_CURL_NTLM_CORE_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_msgs.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_msgs.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_msgs.c	(revision 164)
@@ -0,0 +1,817 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
+
+/*
+ * NTLM details:
+ *
+ * http://davenport.sourceforge.net/ntlm.html
+ * http://www.innovation.ch/java/ntlm.html
+ */
+
+#define DEBUG_ME 0
+
+#include "urldata.h"
+#include "non-ascii.h"
+#include "sendf.h"
+#include "curl_base64.h"
+#include "curl_ntlm_core.h"
+#include "curl_gethostname.h"
+#include "curl_multibyte.h"
+#include "warnless.h"
+
+#include "vtls/vtls.h"
+
+#ifdef USE_NSS
+#include "vtls/nssg.h" /* for Curl_nss_force_init() */
+#endif
+
+#define BUILDING_CURL_NTLM_MSGS_C
+#include "curl_ntlm_msgs.h"
+#include "curl_sasl.h"
+#include "curl_endian.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* "NTLMSSP" signature is always in ASCII regardless of the platform */
+#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50"
+
+#define SHORTPAIR(x) ((x) & 0xff), (((x) >> 8) & 0xff)
+#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8) & 0xff), \
+  (((x) >> 16) & 0xff), (((x) >> 24) & 0xff)
+
+#if DEBUG_ME
+# define DEBUG_OUT(x) x
+static void ntlm_print_flags(FILE *handle, unsigned long flags)
+{
+  if(flags & NTLMFLAG_NEGOTIATE_UNICODE)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE ");
+  if(flags & NTLMFLAG_NEGOTIATE_OEM)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_OEM ");
+  if(flags & NTLMFLAG_REQUEST_TARGET)
+    fprintf(handle, "NTLMFLAG_REQUEST_TARGET ");
+  if(flags & (1<<3))
+    fprintf(handle, "NTLMFLAG_UNKNOWN_3 ");
+  if(flags & NTLMFLAG_NEGOTIATE_SIGN)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN ");
+  if(flags & NTLMFLAG_NEGOTIATE_SEAL)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL ");
+  if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE ");
+  if(flags & NTLMFLAG_NEGOTIATE_LM_KEY)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY ");
+  if(flags & NTLMFLAG_NEGOTIATE_NETWARE)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_NETWARE ");
+  if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY ");
+  if(flags & (1<<10))
+    fprintf(handle, "NTLMFLAG_UNKNOWN_10 ");
+  if(flags & NTLMFLAG_NEGOTIATE_ANONYMOUS)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_ANONYMOUS ");
+  if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED ");
+  if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED ");
+  if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL ");
+  if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN ");
+  if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN)
+    fprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN ");
+  if(flags & NTLMFLAG_TARGET_TYPE_SERVER)
+    fprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER ");
+  if(flags & NTLMFLAG_TARGET_TYPE_SHARE)
+    fprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE ");
+  if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY ");
+  if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE)
+    fprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE ");
+  if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE)
+    fprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE ");
+  if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY)
+    fprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY ");
+  if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO ");
+  if(flags & (1<<24))
+    fprintf(handle, "NTLMFLAG_UNKNOWN_24 ");
+  if(flags & (1<<25))
+    fprintf(handle, "NTLMFLAG_UNKNOWN_25 ");
+  if(flags & (1<<26))
+    fprintf(handle, "NTLMFLAG_UNKNOWN_26 ");
+  if(flags & (1<<27))
+    fprintf(handle, "NTLMFLAG_UNKNOWN_27 ");
+  if(flags & (1<<28))
+    fprintf(handle, "NTLMFLAG_UNKNOWN_28 ");
+  if(flags & NTLMFLAG_NEGOTIATE_128)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_128 ");
+  if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE ");
+  if(flags & NTLMFLAG_NEGOTIATE_56)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_56 ");
+}
+
+static void ntlm_print_hex(FILE *handle, const char *buf, size_t len)
+{
+  const char *p = buf;
+  (void)handle;
+  fprintf(stderr, "0x");
+  while(len-- > 0)
+    fprintf(stderr, "%02.2x", (unsigned int)*p++);
+}
+#else
+# define DEBUG_OUT(x) Curl_nop_stmt
+#endif
+
+/*
+ * ntlm_decode_type2_target()
+ *
+ * This is used to decode the "target info" in the ntlm type-2 message
+ * received.
+ *
+ * Parameters:
+ *
+ * data      [in]     - The session handle.
+ * buffer    [in]     - The decoded type-2 message.
+ * size      [in]     - The input buffer size, at least 32 bytes.
+ * ntlm      [in/out] - The ntlm data struct being used and modified.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode ntlm_decode_type2_target(struct SessionHandle *data,
+                                         unsigned char *buffer,
+                                         size_t size,
+                                         struct ntlmdata *ntlm)
+{
+  unsigned short target_info_len = 0;
+  unsigned int target_info_offset = 0;
+
+  if(size >= 48) {
+    target_info_len = Curl_read16_le(&buffer[40]);
+    target_info_offset = Curl_read32_le(&buffer[44]);
+    if(target_info_len > 0) {
+      if(((target_info_offset + target_info_len) > size) ||
+         (target_info_offset < 48)) {
+        infof(data, "NTLM handshake failure (bad type-2 message). "
+                    "Target Info Offset Len is set incorrect by the peer\n");
+        return CURLE_BAD_CONTENT_ENCODING;
+      }
+
+      ntlm->target_info = malloc(target_info_len);
+      if(!ntlm->target_info)
+        return CURLE_OUT_OF_MEMORY;
+
+      memcpy(ntlm->target_info, &buffer[target_info_offset], target_info_len);
+    }
+  }
+
+  ntlm->target_info_len = target_info_len;
+
+  return CURLE_OK;
+}
+
+/*
+  NTLM message structure notes:
+
+  A 'short' is a 'network short', a little-endian 16-bit unsigned value.
+
+  A 'long' is a 'network long', a little-endian, 32-bit unsigned value.
+
+  A 'security buffer' represents a triplet used to point to a buffer,
+  consisting of two shorts and one long:
+
+    1. A 'short' containing the length of the buffer content in bytes.
+    2. A 'short' containing the allocated space for the buffer in bytes.
+    3. A 'long' containing the offset to the start of the buffer in bytes,
+       from the beginning of the NTLM message.
+*/
+
+/*
+ * Curl_sasl_decode_ntlm_type2_message()
+ *
+ * This is used to decode an already encoded NTLM type-2 message. The message
+ * is first decoded from a base64 string into a raw NTLM message and checked
+ * for validity before the appropriate data for creating a type-3 message is
+ * written to the given NTLM data structure.
+ *
+ * Parameters:
+ *
+ * data     [in]     - The session handle.
+ * type2msg [in]     - The base64 encoded type-2 message.
+ * ntlm     [in/out] - The ntlm data struct being used and modified.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
+                                             const char *type2msg,
+                                             struct ntlmdata *ntlm)
+{
+  static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 };
+
+  /* NTLM type-2 message structure:
+
+          Index  Description            Content
+            0    NTLMSSP Signature      Null-terminated ASCII "NTLMSSP"
+                                        (0x4e544c4d53535000)
+            8    NTLM Message Type      long (0x02000000)
+           12    Target Name            security buffer
+           20    Flags                  long
+           24    Challenge              8 bytes
+          (32)   Context                8 bytes (two consecutive longs) (*)
+          (40)   Target Information     security buffer (*)
+          (48)   OS Version Structure   8 bytes (*)
+  32 (48) (56)   Start of data block    (*)
+                                        (*) -> Optional
+  */
+
+  CURLcode result = CURLE_OK;
+  unsigned char *type2 = NULL;
+  size_t type2_len = 0;
+
+#if defined(USE_NSS)
+  /* Make sure the crypto backend is initialized */
+  result = Curl_nss_force_init(data);
+  if(result)
+    return result;
+#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void)data;
+#endif
+
+  /* Decode the base-64 encoded type-2 message */
+  if(strlen(type2msg) && *type2msg != '=') {
+    result = Curl_base64_decode(type2msg, &type2, &type2_len);
+    if(result)
+      return result;
+  }
+
+  /* Ensure we have a valid type-2 message */
+  if(!type2) {
+    infof(data, "NTLM handshake failure (empty type-2 message)\n");
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  ntlm->flags = 0;
+
+  if((type2_len < 32) ||
+     (memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) ||
+     (memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) {
+    /* This was not a good enough type-2 message */
+    free(type2);
+    infof(data, "NTLM handshake failure (bad type-2 message)\n");
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  ntlm->flags = Curl_read32_le(&type2[20]);
+  memcpy(ntlm->nonce, &type2[24], 8);
+
+  if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) {
+    result = ntlm_decode_type2_target(data, type2, type2_len, ntlm);
+    if(result) {
+      free(type2);
+      infof(data, "NTLM handshake failure (bad type-2 message)\n");
+      return result;
+    }
+  }
+
+  DEBUG_OUT({
+    fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags);
+    ntlm_print_flags(stderr, ntlm->flags);
+    fprintf(stderr, "\n                  nonce=");
+    ntlm_print_hex(stderr, (char *)ntlm->nonce, 8);
+    fprintf(stderr, "\n****\n");
+    fprintf(stderr, "**** Header %s\n ", header);
+  });
+
+  free(type2);
+
+  return result;
+}
+
+/* copy the source to the destination and fill in zeroes in every
+   other destination byte! */
+static void unicodecpy(unsigned char *dest, const char *src, size_t length)
+{
+  size_t i;
+  for(i = 0; i < length; i++) {
+    dest[2 * i] = (unsigned char)src[i];
+    dest[2 * i + 1] = '\0';
+  }
+}
+
+/*
+ * Curl_sasl_create_ntlm_type1_message()
+ *
+ * This is used to generate an already encoded NTLM type-1 message ready for
+ * sending to the recipient using the appropriate compile time crypto API.
+ *
+ * Parameters:
+ *
+ * userp   [in]     - The user name in the format User or Domain\User.
+ * passdwp [in]     - The user's password.
+ * ntlm    [in/out] - The ntlm data struct being used and modified.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
+                                             const char *passwdp,
+                                             struct ntlmdata *ntlm,
+                                             char **outptr, size_t *outlen)
+{
+  /* NTLM type-1 message structure:
+
+       Index  Description            Content
+         0    NTLMSSP Signature      Null-terminated ASCII "NTLMSSP"
+                                     (0x4e544c4d53535000)
+         8    NTLM Message Type      long (0x01000000)
+        12    Flags                  long
+       (16)   Supplied Domain        security buffer (*)
+       (24)   Supplied Workstation   security buffer (*)
+       (32)   OS Version Structure   8 bytes (*)
+  (32) (40)   Start of data block    (*)
+                                     (*) -> Optional
+  */
+
+  size_t size;
+
+  unsigned char ntlmbuf[NTLM_BUFSIZE];
+  const char *host = "";              /* empty */
+  const char *domain = "";            /* empty */
+  size_t hostlen = 0;
+  size_t domlen = 0;
+  size_t hostoff = 0;
+  size_t domoff = hostoff + hostlen;  /* This is 0: remember that host and
+                                         domain are empty */
+  (void)userp;
+  (void)passwdp;
+
+  /* Clean up any former leftovers and initialise to defaults */
+  Curl_sasl_ntlm_cleanup(ntlm);
+
+#if USE_NTRESPONSES && USE_NTLM2SESSION
+#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
+#else
+#define NTLM2FLAG 0
+#endif
+  snprintf((char *)ntlmbuf, NTLM_BUFSIZE,
+           NTLMSSP_SIGNATURE "%c"
+           "\x01%c%c%c" /* 32-bit type = 1 */
+           "%c%c%c%c"   /* 32-bit NTLM flag field */
+           "%c%c"       /* domain length */
+           "%c%c"       /* domain allocated space */
+           "%c%c"       /* domain name offset */
+           "%c%c"       /* 2 zeroes */
+           "%c%c"       /* host length */
+           "%c%c"       /* host allocated space */
+           "%c%c"       /* host name offset */
+           "%c%c"       /* 2 zeroes */
+           "%s"         /* host name */
+           "%s",        /* domain string */
+           0,           /* trailing zero */
+           0, 0, 0,     /* part of type-1 long */
+
+           LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
+                       NTLMFLAG_REQUEST_TARGET |
+                       NTLMFLAG_NEGOTIATE_NTLM_KEY |
+                       NTLM2FLAG |
+                       NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
+           SHORTPAIR(domlen),
+           SHORTPAIR(domlen),
+           SHORTPAIR(domoff),
+           0, 0,
+           SHORTPAIR(hostlen),
+           SHORTPAIR(hostlen),
+           SHORTPAIR(hostoff),
+           0, 0,
+           host,  /* this is empty */
+           domain /* this is empty */);
+
+  /* Initial packet length */
+  size = 32 + hostlen + domlen;
+
+  DEBUG_OUT({
+    fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x "
+            "0x%08.8x ",
+            LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
+                        NTLMFLAG_REQUEST_TARGET |
+                        NTLMFLAG_NEGOTIATE_NTLM_KEY |
+                        NTLM2FLAG |
+                        NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
+            NTLMFLAG_NEGOTIATE_OEM |
+            NTLMFLAG_REQUEST_TARGET |
+            NTLMFLAG_NEGOTIATE_NTLM_KEY |
+            NTLM2FLAG |
+            NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
+    ntlm_print_flags(stderr,
+                     NTLMFLAG_NEGOTIATE_OEM |
+                     NTLMFLAG_REQUEST_TARGET |
+                     NTLMFLAG_NEGOTIATE_NTLM_KEY |
+                     NTLM2FLAG |
+                     NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
+    fprintf(stderr, "\n****\n");
+  });
+
+  /* Return with binary blob encoded into base64 */
+  return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
+}
+
+/*
+ * Curl_sasl_create_ntlm_type3_message()
+ *
+ * This is used to generate an already encoded NTLM type-3 message ready for
+ * sending to the recipient using the appropriate compile time crypto API.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * userp   [in]     - The user name in the format User or Domain\User.
+ * passdwp [in]     - The user's password.
+ * ntlm    [in/out] - The ntlm data struct being used and modified.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             struct ntlmdata *ntlm,
+                                             char **outptr, size_t *outlen)
+
+{
+  /* NTLM type-3 message structure:
+
+          Index  Description            Content
+            0    NTLMSSP Signature      Null-terminated ASCII "NTLMSSP"
+                                        (0x4e544c4d53535000)
+            8    NTLM Message Type      long (0x03000000)
+           12    LM/LMv2 Response       security buffer
+           20    NTLM/NTLMv2 Response   security buffer
+           28    Target Name            security buffer
+           36    User Name              security buffer
+           44    Workstation Name       security buffer
+          (52)   Session Key            security buffer (*)
+          (60)   Flags                  long (*)
+          (64)   OS Version Structure   8 bytes (*)
+  52 (64) (72)   Start of data block
+                                          (*) -> Optional
+  */
+
+  CURLcode result = CURLE_OK;
+  size_t size;
+  unsigned char ntlmbuf[NTLM_BUFSIZE];
+  int lmrespoff;
+  unsigned char lmresp[24]; /* fixed-size */
+#if USE_NTRESPONSES
+  int ntrespoff;
+  unsigned int ntresplen = 24;
+  unsigned char ntresp[24]; /* fixed-size */
+  unsigned char *ptr_ntresp = &ntresp[0];
+  unsigned char *ntlmv2resp = NULL;
+#endif
+  bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE) ? TRUE : FALSE;
+  char host[HOSTNAME_MAX + 1] = "";
+  const char *user;
+  const char *domain = "";
+  size_t hostoff = 0;
+  size_t useroff = 0;
+  size_t domoff = 0;
+  size_t hostlen = 0;
+  size_t userlen = 0;
+  size_t domlen = 0;
+
+  user = strchr(userp, '\\');
+  if(!user)
+    user = strchr(userp, '/');
+
+  if(user) {
+    domain = userp;
+    domlen = (user - domain);
+    user++;
+  }
+  else
+    user = userp;
+
+  if(user)
+    userlen = strlen(user);
+
+  /* Get the machine's un-qualified host name as NTLM doesn't like the fully
+     qualified domain name */
+  if(Curl_gethostname(host, sizeof(host))) {
+    infof(data, "gethostname() failed, continuing without!\n");
+    hostlen = 0;
+  }
+  else {
+    hostlen = strlen(host);
+  }
+
+#if USE_NTRESPONSES && USE_NTLM_V2
+  if(ntlm->target_info_len) {
+    unsigned char ntbuffer[0x18];
+    unsigned int entropy[2];
+    unsigned char ntlmv2hash[0x18];
+
+    entropy[0] = Curl_rand(data);
+    entropy[1] = Curl_rand(data);
+
+    result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+    if(result)
+      return result;
+
+    result = Curl_ntlm_core_mk_ntlmv2_hash(user, userlen, domain, domlen,
+                                           ntbuffer, ntlmv2hash);
+    if(result)
+      return result;
+
+    /* LMv2 response */
+    result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash,
+                                         (unsigned char *)&entropy[0],
+                                         &ntlm->nonce[0], lmresp);
+    if(result)
+      return result;
+
+    /* NTLMv2 response */
+    result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash,
+                                           (unsigned char *)&entropy[0],
+                                           ntlm, &ntlmv2resp, &ntresplen);
+    if(result)
+      return result;
+
+    ptr_ntresp = ntlmv2resp;
+  }
+  else
+#endif
+
+#if USE_NTRESPONSES && USE_NTLM2SESSION
+  /* We don't support NTLM2 if we don't have USE_NTRESPONSES */
+  if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
+    unsigned char ntbuffer[0x18];
+    unsigned char tmp[0x18];
+    unsigned char md5sum[MD5_DIGEST_LENGTH];
+    unsigned int entropy[2];
+
+    /* Need to create 8 bytes random data */
+    entropy[0] = Curl_rand(data);
+    entropy[1] = Curl_rand(data);
+
+    /* 8 bytes random data as challenge in lmresp */
+    memcpy(lmresp, entropy, 8);
+
+    /* Pad with zeros */
+    memset(lmresp + 8, 0, 0x10);
+
+    /* Fill tmp with challenge(nonce?) + entropy */
+    memcpy(tmp, &ntlm->nonce[0], 8);
+    memcpy(tmp + 8, entropy, 8);
+
+    result = Curl_ssl_md5sum(tmp, 16, md5sum, MD5_DIGEST_LENGTH);
+    if(!result)
+      /* We shall only use the first 8 bytes of md5sum, but the des code in
+         Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
+      result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+    if(result)
+      return result;
+
+    Curl_ntlm_core_lm_resp(ntbuffer, md5sum, ntresp);
+
+    /* End of NTLM2 Session code */
+
+  }
+  else
+#endif
+  {
+
+#if USE_NTRESPONSES
+    unsigned char ntbuffer[0x18];
+#endif
+    unsigned char lmbuffer[0x18];
+
+#if USE_NTRESPONSES
+    result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+    if(result)
+      return result;
+
+    Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
+#endif
+
+    result = Curl_ntlm_core_mk_lm_hash(data, passwdp, lmbuffer);
+    if(result)
+      return result;
+
+    Curl_ntlm_core_lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
+
+    /* A safer but less compatible alternative is:
+     *   Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
+     * See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
+  }
+
+  if(unicode) {
+    domlen = domlen * 2;
+    userlen = userlen * 2;
+    hostlen = hostlen * 2;
+  }
+
+  lmrespoff = 64; /* size of the message header */
+#if USE_NTRESPONSES
+  ntrespoff = lmrespoff + 0x18;
+  domoff = ntrespoff + ntresplen;
+#else
+  domoff = lmrespoff + 0x18;
+#endif
+  useroff = domoff + domlen;
+  hostoff = useroff + userlen;
+
+  /* Create the big type-3 message binary blob */
+  size = snprintf((char *)ntlmbuf, NTLM_BUFSIZE,
+                  NTLMSSP_SIGNATURE "%c"
+                  "\x03%c%c%c"  /* 32-bit type = 3 */
+
+                  "%c%c"  /* LanManager length */
+                  "%c%c"  /* LanManager allocated space */
+                  "%c%c"  /* LanManager offset */
+                  "%c%c"  /* 2 zeroes */
+
+                  "%c%c"  /* NT-response length */
+                  "%c%c"  /* NT-response allocated space */
+                  "%c%c"  /* NT-response offset */
+                  "%c%c"  /* 2 zeroes */
+
+                  "%c%c"  /* domain length */
+                  "%c%c"  /* domain allocated space */
+                  "%c%c"  /* domain name offset */
+                  "%c%c"  /* 2 zeroes */
+
+                  "%c%c"  /* user length */
+                  "%c%c"  /* user allocated space */
+                  "%c%c"  /* user offset */
+                  "%c%c"  /* 2 zeroes */
+
+                  "%c%c"  /* host length */
+                  "%c%c"  /* host allocated space */
+                  "%c%c"  /* host offset */
+                  "%c%c"  /* 2 zeroes */
+
+                  "%c%c"  /* session key length (unknown purpose) */
+                  "%c%c"  /* session key allocated space (unknown purpose) */
+                  "%c%c"  /* session key offset (unknown purpose) */
+                  "%c%c"  /* 2 zeroes */
+
+                  "%c%c%c%c",  /* flags */
+
+                  /* domain string */
+                  /* user string */
+                  /* host string */
+                  /* LanManager response */
+                  /* NT response */
+
+                  0,                /* zero termination */
+                  0, 0, 0,          /* type-3 long, the 24 upper bits */
+
+                  SHORTPAIR(0x18),  /* LanManager response length, twice */
+                  SHORTPAIR(0x18),
+                  SHORTPAIR(lmrespoff),
+                  0x0, 0x0,
+
+#if USE_NTRESPONSES
+                  SHORTPAIR(ntresplen),  /* NT-response length, twice */
+                  SHORTPAIR(ntresplen),
+                  SHORTPAIR(ntrespoff),
+                  0x0, 0x0,
+#else
+                  0x0, 0x0,
+                  0x0, 0x0,
+                  0x0, 0x0,
+                  0x0, 0x0,
+#endif
+                  SHORTPAIR(domlen),
+                  SHORTPAIR(domlen),
+                  SHORTPAIR(domoff),
+                  0x0, 0x0,
+
+                  SHORTPAIR(userlen),
+                  SHORTPAIR(userlen),
+                  SHORTPAIR(useroff),
+                  0x0, 0x0,
+
+                  SHORTPAIR(hostlen),
+                  SHORTPAIR(hostlen),
+                  SHORTPAIR(hostoff),
+                  0x0, 0x0,
+
+                  0x0, 0x0,
+                  0x0, 0x0,
+                  0x0, 0x0,
+                  0x0, 0x0,
+
+                  LONGQUARTET(ntlm->flags));
+
+  DEBUGASSERT(size == 64);
+  DEBUGASSERT(size == (size_t)lmrespoff);
+
+  /* We append the binary hashes */
+  if(size < (NTLM_BUFSIZE - 0x18)) {
+    memcpy(&ntlmbuf[size], lmresp, 0x18);
+    size += 0x18;
+  }
+
+  DEBUG_OUT({
+    fprintf(stderr, "**** TYPE3 header lmresp=");
+    ntlm_print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
+  });
+
+#if USE_NTRESPONSES
+  if(size < (NTLM_BUFSIZE - ntresplen)) {
+    DEBUGASSERT(size == (size_t)ntrespoff);
+    memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen);
+    size += ntresplen;
+  }
+
+  DEBUG_OUT({
+    fprintf(stderr, "\n   ntresp=");
+    ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], ntresplen);
+  });
+
+  free(ntlmv2resp);/* Free the dynamic buffer allocated for NTLMv2 */
+
+#endif
+
+  DEBUG_OUT({
+    fprintf(stderr, "\n   flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
+            LONGQUARTET(ntlm->flags), ntlm->flags);
+    ntlm_print_flags(stderr, ntlm->flags);
+    fprintf(stderr, "\n****\n");
+  });
+
+  /* Make sure that the domain, user and host strings fit in the
+     buffer before we copy them there. */
+  if(size + userlen + domlen + hostlen >= NTLM_BUFSIZE) {
+    failf(data, "user + domain + host name too big");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  DEBUGASSERT(size == domoff);
+  if(unicode)
+    unicodecpy(&ntlmbuf[size], domain, domlen / 2);
+  else
+    memcpy(&ntlmbuf[size], domain, domlen);
+
+  size += domlen;
+
+  DEBUGASSERT(size == useroff);
+  if(unicode)
+    unicodecpy(&ntlmbuf[size], user, userlen / 2);
+  else
+    memcpy(&ntlmbuf[size], user, userlen);
+
+  size += userlen;
+
+  DEBUGASSERT(size == hostoff);
+  if(unicode)
+    unicodecpy(&ntlmbuf[size], host, hostlen / 2);
+  else
+    memcpy(&ntlmbuf[size], host, hostlen);
+
+  size += hostlen;
+
+  /* Convert domain, user, and host to ASCII but leave the rest as-is */
+  result = Curl_convert_to_network(data, (char *)&ntlmbuf[domoff],
+                                   size - domoff);
+  if(result)
+    return CURLE_CONV_FAILED;
+
+  /* Return with binary blob encoded into base64 */
+  result = Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
+
+  Curl_sasl_ntlm_cleanup(ntlm);
+
+  return result;
+}
+
+#endif /* USE_NTLM && !USE_WINDOWS_SSPI */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_msgs.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_msgs.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_msgs.h	(revision 164)
@@ -0,0 +1,143 @@
+#ifndef HEADER_CURL_NTLM_MSGS_H
+#define HEADER_CURL_NTLM_MSGS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_NTLM
+
+/* NTLM buffer fixed size, large enough for long user + host + domain */
+#define NTLM_BUFSIZE 1024
+
+/* Stuff only required for curl_ntlm_msgs.c */
+#ifdef BUILDING_CURL_NTLM_MSGS_C
+
+/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */
+
+#define NTLMFLAG_NEGOTIATE_UNICODE               (1<<0)
+/* Indicates that Unicode strings are supported for use in security buffer
+   data. */
+
+#define NTLMFLAG_NEGOTIATE_OEM                   (1<<1)
+/* Indicates that OEM strings are supported for use in security buffer data. */
+
+#define NTLMFLAG_REQUEST_TARGET                  (1<<2)
+/* Requests that the server's authentication realm be included in the Type 2
+   message. */
+
+/* unknown (1<<3) */
+#define NTLMFLAG_NEGOTIATE_SIGN                  (1<<4)
+/* Specifies that authenticated communication between the client and server
+   should carry a digital signature (message integrity). */
+
+#define NTLMFLAG_NEGOTIATE_SEAL                  (1<<5)
+/* Specifies that authenticated communication between the client and server
+   should be encrypted (message confidentiality). */
+
+#define NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE        (1<<6)
+/* Indicates that datagram authentication is being used. */
+
+#define NTLMFLAG_NEGOTIATE_LM_KEY                (1<<7)
+/* Indicates that the LAN Manager session key should be used for signing and
+   sealing authenticated communications. */
+
+#define NTLMFLAG_NEGOTIATE_NETWARE               (1<<8)
+/* unknown purpose */
+
+#define NTLMFLAG_NEGOTIATE_NTLM_KEY              (1<<9)
+/* Indicates that NTLM authentication is being used. */
+
+/* unknown (1<<10) */
+
+#define NTLMFLAG_NEGOTIATE_ANONYMOUS             (1<<11)
+/* Sent by the client in the Type 3 message to indicate that an anonymous
+   context has been established. This also affects the response fields. */
+
+#define NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED       (1<<12)
+/* Sent by the client in the Type 1 message to indicate that a desired
+   authentication realm is included in the message. */
+
+#define NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED  (1<<13)
+/* Sent by the client in the Type 1 message to indicate that the client
+   workstation's name is included in the message. */
+
+#define NTLMFLAG_NEGOTIATE_LOCAL_CALL            (1<<14)
+/* Sent by the server to indicate that the server and client are on the same
+   machine. Implies that the client may use a pre-established local security
+   context rather than responding to the challenge. */
+
+#define NTLMFLAG_NEGOTIATE_ALWAYS_SIGN           (1<<15)
+/* Indicates that authenticated communication between the client and server
+   should be signed with a "dummy" signature. */
+
+#define NTLMFLAG_TARGET_TYPE_DOMAIN              (1<<16)
+/* Sent by the server in the Type 2 message to indicate that the target
+   authentication realm is a domain. */
+
+#define NTLMFLAG_TARGET_TYPE_SERVER              (1<<17)
+/* Sent by the server in the Type 2 message to indicate that the target
+   authentication realm is a server. */
+
+#define NTLMFLAG_TARGET_TYPE_SHARE               (1<<18)
+/* Sent by the server in the Type 2 message to indicate that the target
+   authentication realm is a share. Presumably, this is for share-level
+   authentication. Usage is unclear. */
+
+#define NTLMFLAG_NEGOTIATE_NTLM2_KEY             (1<<19)
+/* Indicates that the NTLM2 signing and sealing scheme should be used for
+   protecting authenticated communications. */
+
+#define NTLMFLAG_REQUEST_INIT_RESPONSE           (1<<20)
+/* unknown purpose */
+
+#define NTLMFLAG_REQUEST_ACCEPT_RESPONSE         (1<<21)
+/* unknown purpose */
+
+#define NTLMFLAG_REQUEST_NONNT_SESSION_KEY       (1<<22)
+/* unknown purpose */
+
+#define NTLMFLAG_NEGOTIATE_TARGET_INFO           (1<<23)
+/* Sent by the server in the Type 2 message to indicate that it is including a
+   Target Information block in the message. */
+
+/* unknown (1<24) */
+/* unknown (1<25) */
+/* unknown (1<26) */
+/* unknown (1<27) */
+/* unknown (1<28) */
+
+#define NTLMFLAG_NEGOTIATE_128                   (1<<29)
+/* Indicates that 128-bit encryption is supported. */
+
+#define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE          (1<<30)
+/* Indicates that the client will provide an encrypted master key in
+   the "Session Key" field of the Type 3 message. */
+
+#define NTLMFLAG_NEGOTIATE_56                    (1<<31)
+/* Indicates that 56-bit encryption is supported. */
+
+#endif /* BUILDING_CURL_NTLM_MSGS_C */
+
+#endif /* USE_NTLM */
+
+#endif /* HEADER_CURL_NTLM_MSGS_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_wb.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_wb.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_wb.c	(revision 164)
@@ -0,0 +1,431 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+    defined(NTLM_WB_ENABLED)
+
+/*
+ * NTLM details:
+ *
+ * http://davenport.sourceforge.net/ntlm.html
+ * http://www.innovation.ch/java/ntlm.html
+ */
+
+#define DEBUG_ME 0
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "select.h"
+#include "curl_ntlm_msgs.h"
+#include "curl_ntlm_wb.h"
+#include "url.h"
+#include "strerror.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if DEBUG_ME
+# define DEBUG_OUT(x) x
+#else
+# define DEBUG_OUT(x) Curl_nop_stmt
+#endif
+
+/* Portable 'sclose_nolog' used only in child process instead of 'sclose'
+   to avoid fooling the socket leak detector */
+#if defined(HAVE_CLOSESOCKET)
+#  define sclose_nolog(x)  closesocket((x))
+#elif defined(HAVE_CLOSESOCKET_CAMEL)
+#  define sclose_nolog(x)  CloseSocket((x))
+#else
+#  define sclose_nolog(x)  close((x))
+#endif
+
+void Curl_ntlm_wb_cleanup(struct connectdata *conn)
+{
+  if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) {
+    sclose(conn->ntlm_auth_hlpr_socket);
+    conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
+  }
+
+  if(conn->ntlm_auth_hlpr_pid) {
+    int i;
+    for(i = 0; i < 4; i++) {
+      pid_t ret = waitpid(conn->ntlm_auth_hlpr_pid, NULL, WNOHANG);
+      if(ret == conn->ntlm_auth_hlpr_pid || errno == ECHILD)
+        break;
+      switch(i) {
+      case 0:
+        kill(conn->ntlm_auth_hlpr_pid, SIGTERM);
+        break;
+      case 1:
+        /* Give the process another moment to shut down cleanly before
+           bringing down the axe */
+        Curl_wait_ms(1);
+        break;
+      case 2:
+        kill(conn->ntlm_auth_hlpr_pid, SIGKILL);
+        break;
+      case 3:
+        break;
+      }
+    }
+    conn->ntlm_auth_hlpr_pid = 0;
+  }
+
+  free(conn->challenge_header);
+  conn->challenge_header = NULL;
+  free(conn->response_header);
+  conn->response_header = NULL;
+}
+
+static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
+{
+  curl_socket_t sockfds[2];
+  pid_t child_pid;
+  const char *username;
+  char *slash, *domain = NULL;
+  const char *ntlm_auth = NULL;
+  char *ntlm_auth_alloc = NULL;
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
+  struct passwd pw, *pw_res;
+  char pwbuf[1024];
+#endif
+  int error;
+
+  /* Return if communication with ntlm_auth already set up */
+  if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
+     conn->ntlm_auth_hlpr_pid)
+    return CURLE_OK;
+
+  username = userp;
+  /* The real ntlm_auth really doesn't like being invoked with an
+     empty username. It won't make inferences for itself, and expects
+     the client to do so (mostly because it's really designed for
+     servers like squid to use for auth, and client support is an
+     afterthought for it). So try hard to provide a suitable username
+     if we don't already have one. But if we can't, provide the
+     empty one anyway. Perhaps they have an implementation of the
+     ntlm_auth helper which *doesn't* need it so we might as well try */
+  if(!username || !username[0]) {
+    username = getenv("NTLMUSER");
+    if(!username || !username[0])
+      username = getenv("LOGNAME");
+    if(!username || !username[0])
+      username = getenv("USER");
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
+    if((!username || !username[0]) &&
+       !getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) &&
+       pw_res) {
+      username = pw.pw_name;
+    }
+#endif
+    if(!username || !username[0])
+      username = userp;
+  }
+  slash = strpbrk(username, "\\/");
+  if(slash) {
+    if((domain = strdup(username)) == NULL)
+      return CURLE_OUT_OF_MEMORY;
+    slash = domain + (slash - username);
+    *slash = '\0';
+    username = username + (slash - domain) + 1;
+  }
+
+  /* For testing purposes, when DEBUGBUILD is defined and environment
+     variable CURL_NTLM_WB_FILE is set a fake_ntlm is used to perform
+     NTLM challenge/response which only accepts commands and output
+     strings pre-written in test case definitions */
+#ifdef DEBUGBUILD
+  ntlm_auth_alloc = curl_getenv("CURL_NTLM_WB_FILE");
+  if(ntlm_auth_alloc)
+    ntlm_auth = ntlm_auth_alloc;
+  else
+#endif
+    ntlm_auth = NTLM_WB_FILE;
+
+  if(access(ntlm_auth, X_OK) != 0) {
+    error = ERRNO;
+    failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s",
+          ntlm_auth, error, Curl_strerror(conn, error));
+    goto done;
+  }
+
+  if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
+    error = ERRNO;
+    failf(conn->data, "Could not open socket pair. errno %d: %s",
+          error, Curl_strerror(conn, error));
+    goto done;
+  }
+
+  child_pid = fork();
+  if(child_pid == -1) {
+    error = ERRNO;
+    sclose(sockfds[0]);
+    sclose(sockfds[1]);
+    failf(conn->data, "Could not fork. errno %d: %s",
+          error, Curl_strerror(conn, error));
+    goto done;
+  }
+  else if(!child_pid) {
+    /*
+     * child process
+     */
+
+    /* Don't use sclose in the child since it fools the socket leak detector */
+    sclose_nolog(sockfds[0]);
+    if(dup2(sockfds[1], STDIN_FILENO) == -1) {
+      error = ERRNO;
+      failf(conn->data, "Could not redirect child stdin. errno %d: %s",
+            error, Curl_strerror(conn, error));
+      exit(1);
+    }
+
+    if(dup2(sockfds[1], STDOUT_FILENO) == -1) {
+      error = ERRNO;
+      failf(conn->data, "Could not redirect child stdout. errno %d: %s",
+            error, Curl_strerror(conn, error));
+      exit(1);
+    }
+
+    if(domain)
+      execl(ntlm_auth, ntlm_auth,
+            "--helper-protocol", "ntlmssp-client-1",
+            "--use-cached-creds",
+            "--username", username,
+            "--domain", domain,
+            NULL);
+    else
+      execl(ntlm_auth, ntlm_auth,
+            "--helper-protocol", "ntlmssp-client-1",
+            "--use-cached-creds",
+            "--username", username,
+            NULL);
+
+    error = ERRNO;
+    sclose_nolog(sockfds[1]);
+    failf(conn->data, "Could not execl(). errno %d: %s",
+          error, Curl_strerror(conn, error));
+    exit(1);
+  }
+
+  sclose(sockfds[1]);
+  conn->ntlm_auth_hlpr_socket = sockfds[0];
+  conn->ntlm_auth_hlpr_pid = child_pid;
+  free(domain);
+  free(ntlm_auth_alloc);
+  return CURLE_OK;
+
+done:
+  free(domain);
+  free(ntlm_auth_alloc);
+  return CURLE_REMOTE_ACCESS_DENIED;
+}
+
+static CURLcode ntlm_wb_response(struct connectdata *conn,
+                                 const char *input, curlntlm state)
+{
+  char *buf = malloc(NTLM_BUFSIZE);
+  size_t len_in = strlen(input), len_out = 0;
+
+  if(!buf)
+    return CURLE_OUT_OF_MEMORY;
+
+  while(len_in > 0) {
+    ssize_t written = swrite(conn->ntlm_auth_hlpr_socket, input, len_in);
+    if(written == -1) {
+      /* Interrupted by a signal, retry it */
+      if(errno == EINTR)
+        continue;
+      /* write failed if other errors happen */
+      goto done;
+    }
+    input += written;
+    len_in -= written;
+  }
+  /* Read one line */
+  while(1) {
+    ssize_t size;
+    char *newbuf;
+
+    size = sread(conn->ntlm_auth_hlpr_socket, buf + len_out, NTLM_BUFSIZE);
+    if(size == -1) {
+      if(errno == EINTR)
+        continue;
+      goto done;
+    }
+    else if(size == 0)
+      goto done;
+
+    len_out += size;
+    if(buf[len_out - 1] == '\n') {
+      buf[len_out - 1] = '\0';
+      break;
+    }
+    newbuf = realloc(buf, len_out + NTLM_BUFSIZE);
+    if(!newbuf) {
+      free(buf);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    buf = newbuf;
+  }
+
+  /* Samba/winbind installed but not configured */
+  if(state == NTLMSTATE_TYPE1 &&
+     len_out == 3 &&
+     buf[0] == 'P' && buf[1] == 'W')
+    goto done;
+  /* invalid response */
+  if(len_out < 4)
+    goto done;
+  if(state == NTLMSTATE_TYPE1 &&
+     (buf[0]!='Y' || buf[1]!='R' || buf[2]!=' '))
+    goto done;
+  if(state == NTLMSTATE_TYPE2 &&
+     (buf[0]!='K' || buf[1]!='K' || buf[2]!=' ') &&
+     (buf[0]!='A' || buf[1]!='F' || buf[2]!=' '))
+    goto done;
+
+  conn->response_header = aprintf("NTLM %.*s", len_out - 4, buf + 3);
+  free(buf);
+  return CURLE_OK;
+done:
+  free(buf);
+  return CURLE_REMOTE_ACCESS_DENIED;
+}
+
+/*
+ * This is for creating ntlm header output by delegating challenge/response
+ * to Samba's winbind daemon helper ntlm_auth.
+ */
+CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
+                              bool proxy)
+{
+  /* point to the address of the pointer that holds the string to send to the
+     server, which is for a plain host or for a HTTP proxy */
+  char **allocuserpwd;
+  /* point to the name and password for this */
+  const char *userp;
+  /* point to the correct struct with this */
+  struct ntlmdata *ntlm;
+  struct auth *authp;
+
+  CURLcode res = CURLE_OK;
+  char *input;
+
+  DEBUGASSERT(conn);
+  DEBUGASSERT(conn->data);
+
+  if(proxy) {
+    allocuserpwd = &conn->allocptr.proxyuserpwd;
+    userp = conn->proxyuser;
+    ntlm = &conn->proxyntlm;
+    authp = &conn->data->state.authproxy;
+  }
+  else {
+    allocuserpwd = &conn->allocptr.userpwd;
+    userp = conn->user;
+    ntlm = &conn->ntlm;
+    authp = &conn->data->state.authhost;
+  }
+  authp->done = FALSE;
+
+  /* not set means empty */
+  if(!userp)
+    userp="";
+
+  switch(ntlm->state) {
+  case NTLMSTATE_TYPE1:
+  default:
+    /* Use Samba's 'winbind' daemon to support NTLM authentication,
+     * by delegating the NTLM challenge/response protocal to a helper
+     * in ntlm_auth.
+     * http://devel.squid-cache.org/ntlm/squid_helper_protocol.html
+     * https://www.samba.org/samba/docs/man/manpages-3/winbindd.8.html
+     * https://www.samba.org/samba/docs/man/manpages-3/ntlm_auth.1.html
+     * Preprocessor symbol 'NTLM_WB_ENABLED' is defined when this
+     * feature is enabled and 'NTLM_WB_FILE' symbol holds absolute
+     * filename of ntlm_auth helper.
+     * If NTLM authentication using winbind fails, go back to original
+     * request handling process.
+     */
+    /* Create communication with ntlm_auth */
+    res = ntlm_wb_init(conn, userp);
+    if(res)
+      return res;
+    res = ntlm_wb_response(conn, "YR\n", ntlm->state);
+    if(res)
+      return res;
+
+    free(*allocuserpwd);
+    *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
+                            proxy ? "Proxy-" : "",
+                            conn->response_header);
+    DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
+    free(conn->response_header);
+    conn->response_header = NULL;
+    break;
+  case NTLMSTATE_TYPE2:
+    input = aprintf("TT %s\n", conn->challenge_header);
+    if(!input)
+      return CURLE_OUT_OF_MEMORY;
+    res = ntlm_wb_response(conn, input, ntlm->state);
+    free(input);
+    input = NULL;
+    if(res)
+      return res;
+
+    free(*allocuserpwd);
+    *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
+                            proxy ? "Proxy-" : "",
+                            conn->response_header);
+    DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
+    ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
+    authp->done = TRUE;
+    Curl_ntlm_wb_cleanup(conn);
+    break;
+  case NTLMSTATE_TYPE3:
+    /* connection is already authenticated,
+     * don't send a header in future requests */
+    free(*allocuserpwd);
+    *allocuserpwd=NULL;
+    authp->done = TRUE;
+    break;
+  }
+
+  return CURLE_OK;
+}
+
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_wb.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_wb.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_ntlm_wb.h	(revision 164)
@@ -0,0 +1,38 @@
+#ifndef HEADER_CURL_NTLM_WB_H
+#define HEADER_CURL_NTLM_WB_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+    defined(NTLM_WB_ENABLED)
+
+/* this is for creating ntlm header output by delegating challenge/response
+   to Samba's winbind daemon helper ntlm_auth */
+CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy);
+
+void Curl_ntlm_wb_cleanup(struct connectdata *conn);
+
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
+
+#endif /* HEADER_CURL_NTLM_WB_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_printf.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_printf.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_printf.h	(revision 164)
@@ -0,0 +1,56 @@
+#ifndef HEADER_CURL_PRINTF_H
+#define HEADER_CURL_PRINTF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * This header should be included by ALL code in libcurl that uses any
+ * *rintf() functions.
+ */
+
+#include <curl/mprintf.h>
+
+# undef printf
+# undef fprintf
+# undef snprintf
+# undef vprintf
+# undef vfprintf
+# undef vsnprintf
+# undef aprintf
+# undef vaprintf
+# define printf curl_mprintf
+# define fprintf curl_mfprintf
+# define snprintf curl_msnprintf
+# define vprintf curl_mvprintf
+# define vfprintf curl_mvfprintf
+# define vsnprintf curl_mvsnprintf
+# define aprintf curl_maprintf
+# define vaprintf curl_mvaprintf
+
+/* We define away the sprintf functions unconditonally since we don't want
+   internal code to be using them, intentionally or by mistake!*/
+# undef sprintf
+# undef vsprintf
+# define sprintf sprintf_was_used
+# define vsprintf vsprintf_was_used
+
+#endif /* HEADER_CURL_PRINTF_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_rtmp.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_rtmp.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_rtmp.c	(revision 164)
@@ -0,0 +1,306 @@
+/***************************************************************************
+ *                      _   _ ____  _
+ *  Project         ___| | | |  _ \| |
+ *                 / __| | | | |_) | |
+ *                | (__| |_| |  _ <| |___
+ *                 \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_LIBRTMP
+
+#include "urldata.h"
+#include "nonblock.h" /* for curlx_nonblock */
+#include "progress.h" /* for Curl_pgrsSetUploadSize */
+#include "transfer.h"
+#include "warnless.h"
+#include <curl/curl.h>
+#include <librtmp/rtmp.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifdef _WIN32
+#define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e)
+#define SET_RCVTIMEO(tv,s)   int tv = s*1000
+#else
+#define SET_RCVTIMEO(tv,s)   struct timeval tv = {s,0}
+#endif
+
+#define DEF_BUFTIME    (2*60*60*1000)    /* 2 hours */
+
+static CURLcode rtmp_setup_connection(struct connectdata *conn);
+static CURLcode rtmp_do(struct connectdata *conn, bool *done);
+static CURLcode rtmp_done(struct connectdata *conn, CURLcode, bool premature);
+static CURLcode rtmp_connect(struct connectdata *conn, bool *done);
+static CURLcode rtmp_disconnect(struct connectdata *conn, bool dead);
+
+static Curl_recv rtmp_recv;
+static Curl_send rtmp_send;
+
+/*
+ * RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu
+ */
+
+const struct Curl_handler Curl_handler_rtmp = {
+  "RTMP",                               /* scheme */
+  rtmp_setup_connection,                /* setup_connection */
+  rtmp_do,                              /* do_it */
+  rtmp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  rtmp_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_RTMP,                            /* defport */
+  CURLPROTO_RTMP,                       /* protocol */
+  PROTOPT_NONE                          /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmpt = {
+  "RTMPT",                              /* scheme */
+  rtmp_setup_connection,                /* setup_connection */
+  rtmp_do,                              /* do_it */
+  rtmp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  rtmp_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_RTMPT,                           /* defport */
+  CURLPROTO_RTMPT,                      /* protocol */
+  PROTOPT_NONE                          /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmpe = {
+  "RTMPE",                              /* scheme */
+  rtmp_setup_connection,                /* setup_connection */
+  rtmp_do,                              /* do_it */
+  rtmp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  rtmp_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_RTMP,                            /* defport */
+  CURLPROTO_RTMPE,                      /* protocol */
+  PROTOPT_NONE                          /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmpte = {
+  "RTMPTE",                             /* scheme */
+  rtmp_setup_connection,                /* setup_connection */
+  rtmp_do,                              /* do_it */
+  rtmp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  rtmp_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_RTMPT,                           /* defport */
+  CURLPROTO_RTMPTE,                     /* protocol */
+  PROTOPT_NONE                          /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmps = {
+  "RTMPS",                              /* scheme */
+  rtmp_setup_connection,                /* setup_connection */
+  rtmp_do,                              /* do_it */
+  rtmp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  rtmp_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_RTMPS,                           /* defport */
+  CURLPROTO_RTMPS,                      /* protocol */
+  PROTOPT_NONE                          /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmpts = {
+  "RTMPTS",                             /* scheme */
+  rtmp_setup_connection,                /* setup_connection */
+  rtmp_do,                              /* do_it */
+  rtmp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  rtmp_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_RTMPS,                           /* defport */
+  CURLPROTO_RTMPTS,                     /* protocol */
+  PROTOPT_NONE                          /* flags*/
+};
+
+static CURLcode rtmp_setup_connection(struct connectdata *conn)
+{
+  RTMP *r = RTMP_Alloc();
+  if(!r)
+    return CURLE_OUT_OF_MEMORY;
+
+  RTMP_Init(r);
+  RTMP_SetBufferMS(r, DEF_BUFTIME);
+  if(!RTMP_SetupURL(r, conn->data->change.url)) {
+    RTMP_Free(r);
+    return CURLE_URL_MALFORMAT;
+  }
+  conn->proto.generic = r;
+  return CURLE_OK;
+}
+
+static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
+{
+  RTMP *r = conn->proto.generic;
+  SET_RCVTIMEO(tv, 10);
+
+  r->m_sb.sb_socket = conn->sock[FIRSTSOCKET];
+
+  /* We have to know if it's a write before we send the
+   * connect request packet
+   */
+  if(conn->data->set.upload)
+    r->Link.protocol |= RTMP_FEATURE_WRITE;
+
+  /* For plain streams, use the buffer toggle trick to keep data flowing */
+  if(!(r->Link.lFlags & RTMP_LF_LIVE) &&
+     !(r->Link.protocol & RTMP_FEATURE_HTTP))
+    r->Link.lFlags |= RTMP_LF_BUFX;
+
+  (void)curlx_nonblock(r->m_sb.sb_socket, FALSE);
+  setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO,
+             (char *)&tv, sizeof(tv));
+
+  if(!RTMP_Connect1(r, NULL))
+    return CURLE_FAILED_INIT;
+
+  /* Clients must send a periodic BytesReceived report to the server */
+  r->m_bSendCounter = true;
+
+  *done = TRUE;
+  conn->recv[FIRSTSOCKET] = rtmp_recv;
+  conn->send[FIRSTSOCKET] = rtmp_send;
+  return CURLE_OK;
+}
+
+static CURLcode rtmp_do(struct connectdata *conn, bool *done)
+{
+  RTMP *r = conn->proto.generic;
+
+  if(!RTMP_ConnectStream(r, 0))
+    return CURLE_FAILED_INIT;
+
+  if(conn->data->set.upload) {
+    Curl_pgrsSetUploadSize(conn->data, conn->data->state.infilesize);
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+  }
+  else
+    Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
+  *done = TRUE;
+  return CURLE_OK;
+}
+
+static CURLcode rtmp_done(struct connectdata *conn, CURLcode status,
+                          bool premature)
+{
+  (void)conn; /* unused */
+  (void)status; /* unused */
+  (void)premature; /* unused */
+
+  return CURLE_OK;
+}
+
+static CURLcode rtmp_disconnect(struct connectdata *conn,
+                                bool dead_connection)
+{
+  RTMP *r = conn->proto.generic;
+  (void)dead_connection;
+  if(r) {
+    conn->proto.generic = NULL;
+    RTMP_Close(r);
+    RTMP_Free(r);
+  }
+  return CURLE_OK;
+}
+
+static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf,
+                         size_t len, CURLcode *err)
+{
+  RTMP *r = conn->proto.generic;
+  ssize_t nread;
+
+  (void)sockindex; /* unused */
+
+  nread = RTMP_Read(r, buf, curlx_uztosi(len));
+  if(nread < 0) {
+    if(r->m_read.status == RTMP_READ_COMPLETE ||
+        r->m_read.status == RTMP_READ_EOF) {
+      conn->data->req.size = conn->data->req.bytecount;
+      nread = 0;
+    }
+    else
+      *err = CURLE_RECV_ERROR;
+  }
+  return nread;
+}
+
+static ssize_t rtmp_send(struct connectdata *conn, int sockindex,
+                         const void *buf, size_t len, CURLcode *err)
+{
+  RTMP *r = conn->proto.generic;
+  ssize_t num;
+
+  (void)sockindex; /* unused */
+
+  num = RTMP_Write(r, (char *)buf, curlx_uztosi(len));
+  if(num < 0)
+    *err = CURLE_SEND_ERROR;
+
+  return num;
+}
+#endif  /* USE_LIBRTMP */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_rtmp.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_rtmp.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_rtmp.h	(revision 164)
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_RTMP_H
+#define HEADER_CURL_RTMP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifdef USE_LIBRTMP
+extern const struct Curl_handler Curl_handler_rtmp;
+extern const struct Curl_handler Curl_handler_rtmpt;
+extern const struct Curl_handler Curl_handler_rtmpe;
+extern const struct Curl_handler Curl_handler_rtmpte;
+extern const struct Curl_handler Curl_handler_rtmps;
+extern const struct Curl_handler Curl_handler_rtmpts;
+#endif
+
+#endif /* HEADER_CURL_RTMP_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_sasl.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_sasl.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_sasl.c	(revision 164)
@@ -0,0 +1,1734 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC2195 CRAM-MD5 authentication
+ * RFC2617 Basic and Digest Access Authentication
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC4422 Simple Authentication and Security Layer (SASL)
+ * RFC4616 PLAIN authentication
+ * RFC6749 OAuth 2.0 Authorization Framework
+ * RFC7628 A Set of SASL Mechanisms for OAuth
+ * Draft   LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "urldata.h"
+
+#include "curl_base64.h"
+#include "curl_md5.h"
+#include "vtls/vtls.h"
+#include "curl_hmac.h"
+#include "curl_sasl.h"
+#include "warnless.h"
+#include "strtok.h"
+#include "strequal.h"
+#include "rawstr.h"
+#include "sendf.h"
+#include "non-ascii.h" /* included for Curl_convert_... prototypes */
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Supported mechanisms */
+const struct {
+  const char   *name;  /* Name */
+  size_t        len;   /* Name length */
+  unsigned int  bit;   /* Flag bit */
+} mechtable[] = {
+  { "LOGIN",        5,  SASL_MECH_LOGIN },
+  { "PLAIN",        5,  SASL_MECH_PLAIN },
+  { "CRAM-MD5",     8,  SASL_MECH_CRAM_MD5 },
+  { "DIGEST-MD5",   10, SASL_MECH_DIGEST_MD5 },
+  { "GSSAPI",       6,  SASL_MECH_GSSAPI },
+  { "EXTERNAL",     8,  SASL_MECH_EXTERNAL },
+  { "NTLM",         4,  SASL_MECH_NTLM },
+  { "XOAUTH2",      7,  SASL_MECH_XOAUTH2 },
+  { "OAUTHBEARER",  11, SASL_MECH_OAUTHBEARER },
+  { ZERO_NULL,      0,  0 }
+};
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI)
+#define DIGEST_QOP_VALUE_AUTH             (1 << 0)
+#define DIGEST_QOP_VALUE_AUTH_INT         (1 << 1)
+#define DIGEST_QOP_VALUE_AUTH_CONF        (1 << 2)
+
+#define DIGEST_QOP_VALUE_STRING_AUTH      "auth"
+#define DIGEST_QOP_VALUE_STRING_AUTH_INT  "auth-int"
+#define DIGEST_QOP_VALUE_STRING_AUTH_CONF "auth-conf"
+
+/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines.
+   It converts digest text to ASCII so the MD5 will be correct for
+   what ultimately goes over the network.
+*/
+#define CURL_OUTPUT_DIGEST_CONV(a, b) \
+  result = Curl_convert_to_network(a, (char *)b, strlen((const char*)b)); \
+  if(result) { \
+    free(b); \
+    return result; \
+  }
+
+#endif
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+/*
+ * Returns 0 on success and then the buffers are filled in fine.
+ *
+ * Non-zero means failure to parse.
+ */
+int Curl_sasl_digest_get_pair(const char *str, char *value, char *content,
+                              const char **endptr)
+{
+  int c;
+  bool starts_with_quote = FALSE;
+  bool escape = FALSE;
+
+  for(c = DIGEST_MAX_VALUE_LENGTH - 1; (*str && (*str != '=') && c--); )
+    *value++ = *str++;
+  *value = 0;
+
+  if('=' != *str++)
+    /* eek, no match */
+    return 1;
+
+  if('\"' == *str) {
+    /* this starts with a quote so it must end with one as well! */
+    str++;
+    starts_with_quote = TRUE;
+  }
+
+  for(c = DIGEST_MAX_CONTENT_LENGTH - 1; *str && c--; str++) {
+    switch(*str) {
+    case '\\':
+      if(!escape) {
+        /* possibly the start of an escaped quote */
+        escape = TRUE;
+        *content++ = '\\'; /* even though this is an escape character, we still
+                              store it as-is in the target buffer */
+        continue;
+      }
+      break;
+    case ',':
+      if(!starts_with_quote) {
+        /* this signals the end of the content if we didn't get a starting
+           quote and then we do "sloppy" parsing */
+        c = 0; /* the end */
+        continue;
+      }
+      break;
+    case '\r':
+    case '\n':
+      /* end of string */
+      c = 0;
+      continue;
+    case '\"':
+      if(!escape && starts_with_quote) {
+        /* end of string */
+        c = 0;
+        continue;
+      }
+      break;
+    }
+    escape = FALSE;
+    *content++ = *str;
+  }
+  *content = 0;
+
+  *endptr = str;
+
+  return 0; /* all is fine! */
+}
+#endif
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI)
+/* Convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/
+static void sasl_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */
+                                     unsigned char *dest) /* 33 bytes */
+{
+  int i;
+  for(i = 0; i < 16; i++)
+    snprintf((char *)&dest[i*2], 3, "%02x", source[i]);
+}
+
+/* Perform quoted-string escaping as described in RFC2616 and its errata */
+static char *sasl_digest_string_quoted(const char *source)
+{
+  char *dest, *d;
+  const char *s = source;
+  size_t n = 1; /* null terminator */
+
+  /* Calculate size needed */
+  while(*s) {
+    ++n;
+    if(*s == '"' || *s == '\\') {
+      ++n;
+    }
+    ++s;
+  }
+
+  dest = malloc(n);
+  if(dest) {
+    s = source;
+    d = dest;
+    while(*s) {
+      if(*s == '"' || *s == '\\') {
+        *d++ = '\\';
+      }
+      *d++ = *s++;
+    }
+    *d = 0;
+  }
+
+  return dest;
+}
+
+/* Retrieves the value for a corresponding key from the challenge string
+ * returns TRUE if the key could be found, FALSE if it does not exists
+ */
+static bool sasl_digest_get_key_value(const char *chlg,
+                                      const char *key,
+                                      char *value,
+                                      size_t max_val_len,
+                                      char end_char)
+{
+  char *find_pos;
+  size_t i;
+
+  find_pos = strstr(chlg, key);
+  if(!find_pos)
+    return FALSE;
+
+  find_pos += strlen(key);
+
+  for(i = 0; *find_pos && *find_pos != end_char && i < max_val_len - 1; ++i)
+    value[i] = *find_pos++;
+  value[i] = '\0';
+
+  return TRUE;
+}
+
+static CURLcode sasl_digest_get_qop_values(const char *options, int *value)
+{
+  char *tmp;
+  char *token;
+  char *tok_buf;
+
+  /* Initialise the output */
+  *value = 0;
+
+  /* Tokenise the list of qop values. Use a temporary clone of the buffer since
+     strtok_r() ruins it. */
+  tmp = strdup(options);
+  if(!tmp)
+    return CURLE_OUT_OF_MEMORY;
+
+  token = strtok_r(tmp, ",", &tok_buf);
+  while(token != NULL) {
+    if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH))
+      *value |= DIGEST_QOP_VALUE_AUTH;
+    else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_INT))
+      *value |= DIGEST_QOP_VALUE_AUTH_INT;
+    else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_CONF))
+      *value |= DIGEST_QOP_VALUE_AUTH_CONF;
+
+    token = strtok_r(NULL, ",", &tok_buf);
+  }
+
+  free(tmp);
+
+  return CURLE_OK;
+}
+#endif /* !CURL_DISABLE_CRYPTO_AUTH && !USE_WINDOWS_SSPI */
+
+#if !defined(USE_WINDOWS_SSPI)
+/*
+ * Curl_sasl_build_spn()
+ *
+ * This is used to build a SPN string in the format service/instance.
+ *
+ * Parameters:
+ *
+ * service  [in] - The service type such as www, smtp, pop or imap.
+ * instance [in] - The host name or realm.
+ *
+ * Returns a pointer to the newly allocated SPN.
+ */
+char *Curl_sasl_build_spn(const char *service, const char *instance)
+{
+  /* Generate and return our SPN */
+  return aprintf("%s/%s", service, instance);
+}
+#endif
+
+/*
+ * sasl_create_plain_message()
+ *
+ * This is used to generate an already encoded PLAIN message ready
+ * for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * userp   [in]     - The user name.
+ * passdwp [in]     - The user's password.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_create_plain_message(struct SessionHandle *data,
+                                          const char *userp,
+                                          const char *passwdp,
+                                          char **outptr, size_t *outlen)
+{
+  CURLcode result;
+  char *plainauth;
+  size_t ulen;
+  size_t plen;
+
+  ulen = strlen(userp);
+  plen = strlen(passwdp);
+
+  plainauth = malloc(2 * ulen + plen + 2);
+  if(!plainauth) {
+    *outlen = 0;
+    *outptr = NULL;
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Calculate the reply */
+  memcpy(plainauth, userp, ulen);
+  plainauth[ulen] = '\0';
+  memcpy(plainauth + ulen + 1, userp, ulen);
+  plainauth[2 * ulen + 1] = '\0';
+  memcpy(plainauth + 2 * ulen + 2, passwdp, plen);
+
+  /* Base64 encode the reply */
+  result = Curl_base64_encode(data, plainauth, 2 * ulen + plen + 2, outptr,
+                              outlen);
+  free(plainauth);
+  return result;
+}
+
+/*
+ * sasl_create_login_message()
+ *
+ * This is used to generate an already encoded LOGIN message containing the
+ * user name or password ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * valuep  [in]     - The user name or user's password.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_create_login_message(struct SessionHandle *data,
+                                          const char *valuep, char **outptr,
+                                          size_t *outlen)
+{
+  size_t vlen = strlen(valuep);
+
+  if(!vlen) {
+    /* Calculate an empty reply */
+    *outptr = strdup("=");
+    if(*outptr) {
+      *outlen = (size_t) 1;
+      return CURLE_OK;
+    }
+
+    *outlen = 0;
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Base64 encode the value */
+  return Curl_base64_encode(data, valuep, vlen, outptr, outlen);
+}
+
+/*
+ * sasl_create_external_message()
+ *
+ * This is used to generate an already encoded EXTERNAL message containing
+ * the user name ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * user    [in]     - The user name.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_create_external_message(struct SessionHandle *data,
+                                             const char *user, char **outptr,
+                                             size_t *outlen)
+{
+  /* This is the same formatting as the login message. */
+  return sasl_create_login_message(data, user, outptr, outlen);
+}
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+ /*
+ * sasl_decode_cram_md5_message()
+ *
+ * This is used to decode an already encoded CRAM-MD5 challenge message.
+ *
+ * Parameters:
+ *
+ * chlg64  [in]     - The base64 encoded challenge message.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
+                                             size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  size_t chlg64len = strlen(chlg64);
+
+  *outptr = NULL;
+  *outlen = 0;
+
+  /* Decode the challenge if necessary */
+  if(chlg64len && *chlg64 != '=')
+    result = Curl_base64_decode(chlg64, (unsigned char **) outptr, outlen);
+
+    return result;
+ }
+
+ /*
+ * sasl_create_cram_md5_message()
+ *
+ * This is used to generate an already encoded CRAM-MD5 response message ready
+ * for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * chlg    [in]     - The challenge.
+ * userp   [in]     - The user name.
+ * passdwp [in]     - The user's password.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_create_cram_md5_message(struct SessionHandle *data,
+                                             const char *chlg,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             char **outptr, size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  size_t chlglen = 0;
+  HMAC_context *ctxt;
+  unsigned char digest[MD5_DIGEST_LEN];
+  char *response;
+
+  if(chlg)
+    chlglen = strlen(chlg);
+
+  /* Compute the digest using the password as the key */
+  ctxt = Curl_HMAC_init(Curl_HMAC_MD5,
+                        (const unsigned char *) passwdp,
+                        curlx_uztoui(strlen(passwdp)));
+  if(!ctxt)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Update the digest with the given challenge */
+  if(chlglen > 0)
+    Curl_HMAC_update(ctxt, (const unsigned char *) chlg,
+                     curlx_uztoui(chlglen));
+
+  /* Finalise the digest */
+  Curl_HMAC_final(ctxt, digest);
+
+  /* Generate the response */
+  response = aprintf(
+      "%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+           userp, digest[0], digest[1], digest[2], digest[3], digest[4],
+           digest[5], digest[6], digest[7], digest[8], digest[9], digest[10],
+           digest[11], digest[12], digest[13], digest[14], digest[15]);
+  if(!response)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Base64 encode the response */
+  result = Curl_base64_encode(data, response, 0, outptr, outlen);
+
+  free(response);
+
+  return result;
+}
+
+#ifndef USE_WINDOWS_SSPI
+/*
+ * sasl_decode_digest_md5_message()
+ *
+ * This is used internally to decode an already encoded DIGEST-MD5 challenge
+ * message into the seperate attributes.
+ *
+ * Parameters:
+ *
+ * chlg64  [in]     - The base64 encoded challenge message.
+ * nonce   [in/out] - The buffer where the nonce will be stored.
+ * nlen    [in]     - The length of the nonce buffer.
+ * realm   [in/out] - The buffer where the realm will be stored.
+ * rlen    [in]     - The length of the realm buffer.
+ * alg     [in/out] - The buffer where the algorithm will be stored.
+ * alen    [in]     - The length of the algorithm buffer.
+ * qop     [in/out] - The buffer where the qop-options will be stored.
+ * qlen    [in]     - The length of the qop buffer.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_decode_digest_md5_message(const char *chlg64,
+                                               char *nonce, size_t nlen,
+                                               char *realm, size_t rlen,
+                                               char *alg, size_t alen,
+                                               char *qop, size_t qlen)
+{
+  CURLcode result = CURLE_OK;
+  unsigned char *chlg = NULL;
+  size_t chlglen = 0;
+  size_t chlg64len = strlen(chlg64);
+
+  /* Decode the base-64 encoded challenge message */
+  if(chlg64len && *chlg64 != '=') {
+    result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+    if(result)
+      return result;
+  }
+
+  /* Ensure we have a valid challenge message */
+  if(!chlg)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* Retrieve nonce string from the challenge */
+  if(!sasl_digest_get_key_value((char *)chlg, "nonce=\"", nonce, nlen, '\"')) {
+    free(chlg);
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Retrieve realm string from the challenge */
+  if(!sasl_digest_get_key_value((char *)chlg, "realm=\"", realm, rlen, '\"')) {
+    /* Challenge does not have a realm, set empty string [RFC2831] page 6 */
+    strcpy(realm, "");
+  }
+
+  /* Retrieve algorithm string from the challenge */
+  if(!sasl_digest_get_key_value((char *)chlg, "algorithm=", alg, alen, ',')) {
+    free(chlg);
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Retrieve qop-options string from the challenge */
+  if(!sasl_digest_get_key_value((char *)chlg, "qop=\"", qop, qlen, '\"')) {
+    free(chlg);
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  free(chlg);
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_create_digest_md5_message()
+ *
+ * This is used to generate an already encoded DIGEST-MD5 response message
+ * ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * chlg64  [in]     - The base64 encoded challenge message.
+ * userp   [in]     - The user name.
+ * passdwp [in]     - The user's password.
+ * service [in]     - The service type such as www, smtp, pop or imap.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
+                                             const char *chlg64,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             const char *service,
+                                             char **outptr, size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  size_t i;
+  MD5_context *ctxt;
+  char *response = NULL;
+  unsigned char digest[MD5_DIGEST_LEN];
+  char HA1_hex[2 * MD5_DIGEST_LEN + 1];
+  char HA2_hex[2 * MD5_DIGEST_LEN + 1];
+  char resp_hash_hex[2 * MD5_DIGEST_LEN + 1];
+  char nonce[64];
+  char realm[128];
+  char algorithm[64];
+  char qop_options[64];
+  int qop_values;
+  char cnonce[33];
+  unsigned int entropy[4];
+  char nonceCount[] = "00000001";
+  char method[]     = "AUTHENTICATE";
+  char qop[]        = DIGEST_QOP_VALUE_STRING_AUTH;
+  char *spn         = NULL;
+
+  /* Decode the challange message */
+  result = sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
+                                          realm, sizeof(realm),
+                                          algorithm, sizeof(algorithm),
+                                          qop_options, sizeof(qop_options));
+  if(result)
+    return result;
+
+  /* We only support md5 sessions */
+  if(strcmp(algorithm, "md5-sess") != 0)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* Get the qop-values from the qop-options */
+  result = sasl_digest_get_qop_values(qop_options, &qop_values);
+  if(result)
+    return result;
+
+  /* We only support auth quality-of-protection */
+  if(!(qop_values & DIGEST_QOP_VALUE_AUTH))
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* Generate 16 bytes of random data */
+  entropy[0] = Curl_rand(data);
+  entropy[1] = Curl_rand(data);
+  entropy[2] = Curl_rand(data);
+  entropy[3] = Curl_rand(data);
+
+  /* Convert the random data into a 32 byte hex string */
+  snprintf(cnonce, sizeof(cnonce), "%08x%08x%08x%08x",
+           entropy[0], entropy[1], entropy[2], entropy[3]);
+
+  /* So far so good, now calculate A1 and H(A1) according to RFC 2831 */
+  ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+  if(!ctxt)
+    return CURLE_OUT_OF_MEMORY;
+
+  Curl_MD5_update(ctxt, (const unsigned char *) userp,
+                  curlx_uztoui(strlen(userp)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) realm,
+                  curlx_uztoui(strlen(realm)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) passwdp,
+                  curlx_uztoui(strlen(passwdp)));
+  Curl_MD5_final(ctxt, digest);
+
+  ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+  if(!ctxt)
+    return CURLE_OUT_OF_MEMORY;
+
+  Curl_MD5_update(ctxt, (const unsigned char *) digest, MD5_DIGEST_LEN);
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) nonce,
+                  curlx_uztoui(strlen(nonce)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) cnonce,
+                  curlx_uztoui(strlen(cnonce)));
+  Curl_MD5_final(ctxt, digest);
+
+  /* Convert calculated 16 octet hex into 32 bytes string */
+  for(i = 0; i < MD5_DIGEST_LEN; i++)
+    snprintf(&HA1_hex[2 * i], 3, "%02x", digest[i]);
+
+  /* Generate our SPN */
+  spn = Curl_sasl_build_spn(service, realm);
+  if(!spn)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Calculate H(A2) */
+  ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+  if(!ctxt) {
+    free(spn);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  Curl_MD5_update(ctxt, (const unsigned char *) method,
+                  curlx_uztoui(strlen(method)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) spn,
+                  curlx_uztoui(strlen(spn)));
+  Curl_MD5_final(ctxt, digest);
+
+  for(i = 0; i < MD5_DIGEST_LEN; i++)
+    snprintf(&HA2_hex[2 * i], 3, "%02x", digest[i]);
+
+  /* Now calculate the response hash */
+  ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+  if(!ctxt) {
+    free(spn);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  Curl_MD5_update(ctxt, (const unsigned char *) HA1_hex, 2 * MD5_DIGEST_LEN);
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) nonce,
+                  curlx_uztoui(strlen(nonce)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+
+  Curl_MD5_update(ctxt, (const unsigned char *) nonceCount,
+                  curlx_uztoui(strlen(nonceCount)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) cnonce,
+                  curlx_uztoui(strlen(cnonce)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) qop,
+                  curlx_uztoui(strlen(qop)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+
+  Curl_MD5_update(ctxt, (const unsigned char *) HA2_hex, 2 * MD5_DIGEST_LEN);
+  Curl_MD5_final(ctxt, digest);
+
+  for(i = 0; i < MD5_DIGEST_LEN; i++)
+    snprintf(&resp_hash_hex[2 * i], 3, "%02x", digest[i]);
+
+  /* Generate the response */
+  response = aprintf("username=\"%s\",realm=\"%s\",nonce=\"%s\","
+                     "cnonce=\"%s\",nc=\"%s\",digest-uri=\"%s\",response=%s,"
+                     "qop=%s",
+                     userp, realm, nonce,
+                     cnonce, nonceCount, spn, resp_hash_hex, qop);
+  free(spn);
+  if(!response)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Base64 encode the response */
+  result = Curl_base64_encode(data, response, 0, outptr, outlen);
+
+  free(response);
+
+  return result;
+}
+
+/*
+ * Curl_sasl_decode_digest_http_message()
+ *
+ * This is used to decode a HTTP DIGEST challenge message into the seperate
+ * attributes.
+ *
+ * Parameters:
+ *
+ * chlg    [in]     - The challenge message.
+ * digest  [in/out] - The digest data struct being used and modified.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_decode_digest_http_message(const char *chlg,
+                                              struct digestdata *digest)
+{
+  bool before = FALSE; /* got a nonce before */
+  bool foundAuth = FALSE;
+  bool foundAuthInt = FALSE;
+  char *token = NULL;
+  char *tmp = NULL;
+
+  /* If we already have received a nonce, keep that in mind */
+  if(digest->nonce)
+    before = TRUE;
+
+  /* Clean up any former leftovers and initialise to defaults */
+  Curl_sasl_digest_cleanup(digest);
+
+  for(;;) {
+    char value[DIGEST_MAX_VALUE_LENGTH];
+    char content[DIGEST_MAX_CONTENT_LENGTH];
+
+    /* Pass all additional spaces here */
+    while(*chlg && ISSPACE(*chlg))
+      chlg++;
+
+    /* Extract a value=content pair */
+    if(!Curl_sasl_digest_get_pair(chlg, value, content, &chlg)) {
+      if(Curl_raw_equal(value, "nonce")) {
+        digest->nonce = strdup(content);
+        if(!digest->nonce)
+          return CURLE_OUT_OF_MEMORY;
+      }
+      else if(Curl_raw_equal(value, "stale")) {
+        if(Curl_raw_equal(content, "true")) {
+          digest->stale = TRUE;
+          digest->nc = 1; /* we make a new nonce now */
+        }
+      }
+      else if(Curl_raw_equal(value, "realm")) {
+        digest->realm = strdup(content);
+        if(!digest->realm)
+          return CURLE_OUT_OF_MEMORY;
+      }
+      else if(Curl_raw_equal(value, "opaque")) {
+        digest->opaque = strdup(content);
+        if(!digest->opaque)
+          return CURLE_OUT_OF_MEMORY;
+      }
+      else if(Curl_raw_equal(value, "qop")) {
+        char *tok_buf;
+        /* Tokenize the list and choose auth if possible, use a temporary
+            clone of the buffer since strtok_r() ruins it */
+        tmp = strdup(content);
+        if(!tmp)
+          return CURLE_OUT_OF_MEMORY;
+
+        token = strtok_r(tmp, ",", &tok_buf);
+        while(token != NULL) {
+          if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH)) {
+            foundAuth = TRUE;
+          }
+          else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) {
+            foundAuthInt = TRUE;
+          }
+          token = strtok_r(NULL, ",", &tok_buf);
+        }
+
+        free(tmp);
+
+        /* Select only auth or auth-int. Otherwise, ignore */
+        if(foundAuth) {
+          digest->qop = strdup(DIGEST_QOP_VALUE_STRING_AUTH);
+          if(!digest->qop)
+            return CURLE_OUT_OF_MEMORY;
+        }
+        else if(foundAuthInt) {
+          digest->qop = strdup(DIGEST_QOP_VALUE_STRING_AUTH_INT);
+          if(!digest->qop)
+            return CURLE_OUT_OF_MEMORY;
+        }
+      }
+      else if(Curl_raw_equal(value, "algorithm")) {
+        digest->algorithm = strdup(content);
+        if(!digest->algorithm)
+          return CURLE_OUT_OF_MEMORY;
+
+        if(Curl_raw_equal(content, "MD5-sess"))
+          digest->algo = CURLDIGESTALGO_MD5SESS;
+        else if(Curl_raw_equal(content, "MD5"))
+          digest->algo = CURLDIGESTALGO_MD5;
+        else
+          return CURLE_BAD_CONTENT_ENCODING;
+      }
+      else {
+        /* unknown specifier, ignore it! */
+      }
+    }
+    else
+      break; /* we're done here */
+
+    /* Pass all additional spaces here */
+    while(*chlg && ISSPACE(*chlg))
+      chlg++;
+
+    /* Allow the list to be comma-separated */
+    if(',' == *chlg)
+      chlg++;
+  }
+
+  /* We had a nonce since before, and we got another one now without
+     'stale=true'. This means we provided bad credentials in the previous
+     request */
+  if(before && !digest->stale)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* We got this header without a nonce, that's a bad Digest line! */
+  if(!digest->nonce)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_create_digest_http_message()
+ *
+ * This is used to generate a HTTP DIGEST response message ready for sending
+ * to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * userp   [in]     - The user name.
+ * passdwp [in]     - The user's password.
+ * request [in]     - The HTTP request.
+ * uripath [in]     - The path of the HTTP uri.
+ * digest  [in/out] - The digest data struct being used and modified.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data,
+                                              const char *userp,
+                                              const char *passwdp,
+                                              const unsigned char *request,
+                                              const unsigned char *uripath,
+                                              struct digestdata *digest,
+                                              char **outptr, size_t *outlen)
+{
+  CURLcode result;
+  unsigned char md5buf[16]; /* 16 bytes/128 bits */
+  unsigned char request_digest[33];
+  unsigned char *md5this;
+  unsigned char ha1[33];/* 32 digits and 1 zero byte */
+  unsigned char ha2[33];/* 32 digits and 1 zero byte */
+  char cnoncebuf[33];
+  char *cnonce = NULL;
+  size_t cnonce_sz = 0;
+  char *userp_quoted;
+  char *response = NULL;
+  char *tmp = NULL;
+
+  if(!digest->nc)
+    digest->nc = 1;
+
+  if(!digest->cnonce) {
+    snprintf(cnoncebuf, sizeof(cnoncebuf), "%08x%08x%08x%08x",
+             Curl_rand(data), Curl_rand(data),
+             Curl_rand(data), Curl_rand(data));
+
+    result = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
+                                &cnonce, &cnonce_sz);
+    if(result)
+      return result;
+
+    digest->cnonce = cnonce;
+  }
+
+  /*
+    if the algorithm is "MD5" or unspecified (which then defaults to MD5):
+
+    A1 = unq(username-value) ":" unq(realm-value) ":" passwd
+
+    if the algorithm is "MD5-sess" then:
+
+    A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd )
+         ":" unq(nonce-value) ":" unq(cnonce-value)
+  */
+
+  md5this = (unsigned char *)
+    aprintf("%s:%s:%s", userp, digest->realm, passwdp);
+  if(!md5this)
+    return CURLE_OUT_OF_MEMORY;
+
+  CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
+  Curl_md5it(md5buf, md5this);
+  free(md5this);
+  sasl_digest_md5_to_ascii(md5buf, ha1);
+
+  if(digest->algo == CURLDIGESTALGO_MD5SESS) {
+    /* nonce and cnonce are OUTSIDE the hash */
+    tmp = aprintf("%s:%s:%s", ha1, digest->nonce, digest->cnonce);
+    if(!tmp)
+      return CURLE_OUT_OF_MEMORY;
+
+    CURL_OUTPUT_DIGEST_CONV(data, tmp); /* convert on non-ASCII machines */
+    Curl_md5it(md5buf, (unsigned char *)tmp);
+    free(tmp);
+    sasl_digest_md5_to_ascii(md5buf, ha1);
+  }
+
+  /*
+    If the "qop" directive's value is "auth" or is unspecified, then A2 is:
+
+      A2       = Method ":" digest-uri-value
+
+          If the "qop" value is "auth-int", then A2 is:
+
+      A2       = Method ":" digest-uri-value ":" H(entity-body)
+
+    (The "Method" value is the HTTP request method as specified in section
+    5.1.1 of RFC 2616)
+  */
+
+  md5this = (unsigned char *)aprintf("%s:%s", request, uripath);
+
+  if(digest->qop && Curl_raw_equal(digest->qop, "auth-int")) {
+    /* We don't support auth-int for PUT or POST at the moment.
+       TODO: replace md5 of empty string with entity-body for PUT/POST */
+    unsigned char *md5this2 = (unsigned char *)
+      aprintf("%s:%s", md5this, "d41d8cd98f00b204e9800998ecf8427e");
+    free(md5this);
+    md5this = md5this2;
+  }
+
+  if(!md5this)
+    return CURLE_OUT_OF_MEMORY;
+
+  CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
+  Curl_md5it(md5buf, md5this);
+  free(md5this);
+  sasl_digest_md5_to_ascii(md5buf, ha2);
+
+  if(digest->qop) {
+    md5this = (unsigned char *)aprintf("%s:%s:%08x:%s:%s:%s",
+                                       ha1,
+                                       digest->nonce,
+                                       digest->nc,
+                                       digest->cnonce,
+                                       digest->qop,
+                                       ha2);
+  }
+  else {
+    md5this = (unsigned char *)aprintf("%s:%s:%s",
+                                       ha1,
+                                       digest->nonce,
+                                       ha2);
+  }
+
+  if(!md5this)
+    return CURLE_OUT_OF_MEMORY;
+
+  CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
+  Curl_md5it(md5buf, md5this);
+  free(md5this);
+  sasl_digest_md5_to_ascii(md5buf, request_digest);
+
+  /* for test case 64 (snooped from a Mozilla 1.3a request)
+
+    Authorization: Digest username="testuser", realm="testrealm", \
+    nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
+
+    Digest parameters are all quoted strings.  Username which is provided by
+    the user will need double quotes and backslashes within it escaped.  For
+    the other fields, this shouldn't be an issue.  realm, nonce, and opaque
+    are copied as is from the server, escapes and all.  cnonce is generated
+    with web-safe characters.  uri is already percent encoded.  nc is 8 hex
+    characters.  algorithm and qop with standard values only contain web-safe
+    chracters.
+  */
+  userp_quoted = sasl_digest_string_quoted(userp);
+  if(!userp_quoted)
+    return CURLE_OUT_OF_MEMORY;
+
+  if(digest->qop) {
+    response = aprintf("username=\"%s\", "
+                       "realm=\"%s\", "
+                       "nonce=\"%s\", "
+                       "uri=\"%s\", "
+                       "cnonce=\"%s\", "
+                       "nc=%08x, "
+                       "qop=%s, "
+                       "response=\"%s\"",
+                       userp_quoted,
+                       digest->realm,
+                       digest->nonce,
+                       uripath,
+                       digest->cnonce,
+                       digest->nc,
+                       digest->qop,
+                       request_digest);
+
+    if(Curl_raw_equal(digest->qop, "auth"))
+      digest->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0
+                       padded which tells to the server how many times you are
+                       using the same nonce in the qop=auth mode */
+  }
+  else {
+    response = aprintf("username=\"%s\", "
+                       "realm=\"%s\", "
+                       "nonce=\"%s\", "
+                       "uri=\"%s\", "
+                       "response=\"%s\"",
+                       userp_quoted,
+                       digest->realm,
+                       digest->nonce,
+                       uripath,
+                       request_digest);
+  }
+  free(userp_quoted);
+  if(!response)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Add the optional fields */
+  if(digest->opaque) {
+    /* Append the opaque */
+    tmp = aprintf("%s, opaque=\"%s\"", response, digest->opaque);
+    free(response);
+    if(!tmp)
+      return CURLE_OUT_OF_MEMORY;
+
+    response = tmp;
+  }
+
+  if(digest->algorithm) {
+    /* Append the algorithm */
+    tmp = aprintf("%s, algorithm=\"%s\"", response, digest->algorithm);
+    free(response);
+    if(!tmp)
+      return CURLE_OUT_OF_MEMORY;
+
+    response = tmp;
+  }
+
+  /* Return the output */
+  *outptr = response;
+  *outlen = strlen(response);
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_digest_cleanup()
+ *
+ * This is used to clean up the digest specific data.
+ *
+ * Parameters:
+ *
+ * digest    [in/out] - The digest data struct being cleaned up.
+ *
+ */
+void Curl_sasl_digest_cleanup(struct digestdata *digest)
+{
+  Curl_safefree(digest->nonce);
+  Curl_safefree(digest->cnonce);
+  Curl_safefree(digest->realm);
+  Curl_safefree(digest->opaque);
+  Curl_safefree(digest->qop);
+  Curl_safefree(digest->algorithm);
+
+  digest->nc = 0;
+  digest->algo = CURLDIGESTALGO_MD5; /* default algorithm */
+  digest->stale = FALSE; /* default means normal, not stale */
+}
+#endif  /* !USE_WINDOWS_SSPI */
+
+#endif  /* CURL_DISABLE_CRYPTO_AUTH */
+
+#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
+/*
+ * Curl_sasl_ntlm_cleanup()
+ *
+ * This is used to clean up the ntlm specific data.
+ *
+ * Parameters:
+ *
+ * ntlm    [in/out] - The ntlm data struct being cleaned up.
+ *
+ */
+void Curl_sasl_ntlm_cleanup(struct ntlmdata *ntlm)
+{
+  /* Free the target info */
+  Curl_safefree(ntlm->target_info);
+
+  /* Reset any variables */
+  ntlm->target_info_len = 0;
+}
+#endif /* USE_NTLM && !USE_WINDOWS_SSPI*/
+
+/*
+ * sasl_create_oauth_bearer_message()
+ *
+ * This is used to generate an already encoded OAuth 2.0 message ready for
+ * sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * user    [in]     - The user name.
+ * host    [in]     - The host name (for OAUTHBEARER).
+ * port    [in]     - The port (for OAUTHBEARER when not Port 80).
+ * bearer  [in]     - The bearer token.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_create_oauth_bearer_message(struct SessionHandle *data,
+                                                 const char *user,
+                                                 const char *host,
+                                                 const long port,
+                                                 const char *bearer,
+                                                 char **outptr, size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  char *oauth = NULL;
+
+  /* Generate the message */
+  if(host == NULL && (port == 0 || port == 80))
+    oauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer);
+  else if(port == 0 || port == 80)
+    oauth = aprintf("user=%s\1host=%s\1auth=Bearer %s\1\1", user, host,
+                    bearer);
+  else
+    oauth = aprintf("user=%s\1host=%s\1port=%ld\1auth=Bearer %s\1\1", user,
+                    host, port, bearer);
+  if(!oauth)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Base64 encode the reply */
+  result = Curl_base64_encode(data, oauth, strlen(oauth), outptr, outlen);
+
+  free(oauth);
+
+  return result;
+}
+
+/*
+ * Curl_sasl_cleanup()
+ *
+ * This is used to cleanup any libraries or curl modules used by the sasl
+ * functions.
+ *
+ * Parameters:
+ *
+ * conn     [in]     - The connection data.
+ * authused [in]     - The authentication mechanism used.
+ */
+void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused)
+{
+#if defined(USE_KERBEROS5)
+  /* Cleanup the gssapi structure */
+  if(authused == SASL_MECH_GSSAPI) {
+    Curl_sasl_gssapi_cleanup(&conn->krb5);
+  }
+#endif
+
+#if defined(USE_NTLM)
+  /* Cleanup the ntlm structure */
+  if(authused == SASL_MECH_NTLM) {
+    Curl_sasl_ntlm_cleanup(&conn->ntlm);
+  }
+#endif
+
+#if !defined(USE_KERBEROS5) && !defined(USE_NTLM)
+  /* Reserved for future use */
+  (void)conn;
+  (void)authused;
+#endif
+}
+
+/*
+ * Curl_sasl_decode_mech()
+ *
+ * Convert a SASL mechanism name into a token.
+ *
+ * Parameters:
+ *
+ * ptr    [in]     - The mechanism string.
+ * maxlen [in]     - Maximum mechanism string length.
+ * len    [out]    - If not NULL, effective name length.
+ *
+ * Returns the SASL mechanism token or 0 if no match.
+ */
+unsigned int Curl_sasl_decode_mech(const char *ptr, size_t maxlen, size_t *len)
+{
+  unsigned int i;
+  char c;
+
+  for(i = 0; mechtable[i].name; i++) {
+    if(maxlen >= mechtable[i].len &&
+       !memcmp(ptr, mechtable[i].name, mechtable[i].len)) {
+      if(len)
+        *len = mechtable[i].len;
+
+      if(maxlen == mechtable[i].len)
+        return mechtable[i].bit;
+
+      c = ptr[mechtable[i].len];
+      if(!ISUPPER(c) && !ISDIGIT(c) && c != '-' && c != '_')
+        return mechtable[i].bit;
+    }
+  }
+
+  return 0;
+}
+
+/*
+ * Curl_sasl_parse_url_auth_option()
+ *
+ * Parse the URL login options.
+ */
+CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
+                                         const char *value, size_t len)
+{
+  CURLcode result = CURLE_OK;
+  unsigned int mechbit;
+  size_t mechlen;
+
+  if(!len)
+    return CURLE_URL_MALFORMAT;
+
+    if(sasl->resetprefs) {
+      sasl->resetprefs = FALSE;
+      sasl->prefmech = SASL_AUTH_NONE;
+    }
+
+    if(strnequal(value, "*", len))
+      sasl->prefmech = SASL_AUTH_DEFAULT;
+    else if((mechbit = Curl_sasl_decode_mech(value, len, &mechlen)) &&
+            mechlen == len)
+      sasl->prefmech |= mechbit;
+    else
+      result = CURLE_URL_MALFORMAT;
+
+  return result;
+}
+
+/*
+ * Curl_sasl_init()
+ *
+ * Initializes the SASL structure.
+ */
+void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params)
+{
+  sasl->params = params;           /* Set protocol dependent parameters */
+  sasl->state = SASL_STOP;         /* Not yet running */
+  sasl->authmechs = SASL_AUTH_NONE; /* No known authentication mechanism yet */
+  sasl->prefmech = SASL_AUTH_DEFAULT; /* Prefer all mechanisms */
+  sasl->authused = SASL_AUTH_NONE; /* No the authentication mechanism used */
+  sasl->resetprefs = TRUE;         /* Reset prefmech upon AUTH parsing. */
+  sasl->mutual_auth = FALSE;       /* No mutual authentication (GSSAPI only) */
+  sasl->force_ir = FALSE;          /* Respect external option */
+}
+
+/*
+ * state()
+ *
+ * This is the ONLY way to change SASL state!
+ */
+static void state(struct SASL *sasl, struct connectdata *conn,
+                  saslstate newstate)
+{
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[]={
+    "STOP",
+    "PLAIN",
+    "LOGIN",
+    "LOGIN_PASSWD",
+    "EXTERNAL",
+    "CRAMMD5",
+    "DIGESTMD5",
+    "DIGESTMD5_RESP",
+    "NTLM",
+    "NTLM_TYPE2MSG",
+    "GSSAPI",
+    "GSSAPI_TOKEN",
+    "GSSAPI_NO_DATA",
+    "OAUTH2",
+    "OAUTH2_RESP",
+    "CANCEL",
+    "FINAL",
+    /* LAST */
+  };
+
+  if(sasl->state != newstate)
+    infof(conn->data, "SASL %p state change from %s to %s\n",
+          (void *)sasl, names[sasl->state], names[newstate]);
+#else
+  (void) conn;
+#endif
+
+  sasl->state = newstate;
+}
+
+/*
+ * Curl_sasl_can_authenticate()
+ *
+ * Check if we have enough auth data and capabilities to authenticate.
+ */
+bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn)
+{
+  /* Have credentials been provided? */
+  if(conn->bits.user_passwd)
+    return TRUE;
+
+  /* EXTERNAL can authenticate without a user name and/or password */
+  if(sasl->authmechs & sasl->prefmech & SASL_MECH_EXTERNAL)
+    return TRUE;
+
+  return FALSE;
+}
+
+/*
+ * Curl_sasl_start()
+ *
+ * Calculate the required login details for SASL authentication.
+ */
+CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
+                         bool force_ir, saslprogress *progress)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  unsigned int enabledmechs;
+  const char *mech = NULL;
+  char *resp = NULL;
+  size_t len = 0;
+  saslstate state1 = SASL_STOP;
+  saslstate state2 = SASL_FINAL;
+
+  sasl->force_ir = force_ir;    /* Latch for future use */
+  sasl->authused = 0;           /* No mechanism used yet */
+  enabledmechs = sasl->authmechs & sasl->prefmech;
+  *progress = SASL_IDLE;
+
+  /* Calculate the supported authentication mechanism, by decreasing order of
+     security, as well as the initial response where appropriate */
+  if((enabledmechs & SASL_MECH_EXTERNAL) && !conn->passwd[0]) {
+    mech = SASL_MECH_STRING_EXTERNAL;
+    state1 = SASL_EXTERNAL;
+    sasl->authused = SASL_MECH_EXTERNAL;
+
+    if(force_ir || data->set.sasl_ir)
+      result = sasl_create_external_message(data, conn->user, &resp, &len);
+  }
+  else if(conn->bits.user_passwd) {
+#if defined(USE_KERBEROS5)
+    if(enabledmechs & SASL_MECH_GSSAPI) {
+      sasl->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
+      mech = SASL_MECH_STRING_GSSAPI;
+      state1 = SASL_GSSAPI;
+      state2 = SASL_GSSAPI_TOKEN;
+      sasl->authused = SASL_MECH_GSSAPI;
+
+      if(force_ir || data->set.sasl_ir)
+        result = Curl_sasl_create_gssapi_user_message(data, conn->user,
+                                                      conn->passwd,
+                                                      sasl->params->service,
+                                                      sasl->mutual_auth,
+                                                      NULL, &conn->krb5,
+                                                      &resp, &len);
+    }
+    else
+#endif
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+    if(enabledmechs & SASL_MECH_DIGEST_MD5) {
+      mech = SASL_MECH_STRING_DIGEST_MD5;
+      state1 = SASL_DIGESTMD5;
+      sasl->authused = SASL_MECH_DIGEST_MD5;
+    }
+    else if(enabledmechs & SASL_MECH_CRAM_MD5) {
+      mech = SASL_MECH_STRING_CRAM_MD5;
+      state1 = SASL_CRAMMD5;
+      sasl->authused = SASL_MECH_CRAM_MD5;
+    }
+    else
+#endif
+#ifdef USE_NTLM
+    if(enabledmechs & SASL_MECH_NTLM) {
+      mech = SASL_MECH_STRING_NTLM;
+      state1 = SASL_NTLM;
+      state2 = SASL_NTLM_TYPE2MSG;
+      sasl->authused = SASL_MECH_NTLM;
+
+      if(force_ir || data->set.sasl_ir)
+        result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
+                                                     &conn->ntlm, &resp, &len);
+      }
+    else
+#endif
+    if((enabledmechs & SASL_MECH_OAUTHBEARER) && conn->oauth_bearer) {
+      mech = SASL_MECH_STRING_OAUTHBEARER;
+      state1 = SASL_OAUTH2;
+      state2 = SASL_OAUTH2_RESP;
+      sasl->authused = SASL_MECH_OAUTHBEARER;
+
+      if(force_ir || data->set.sasl_ir)
+        result = sasl_create_oauth_bearer_message(data, conn->user,
+                                                  conn->host.name,
+                                                  conn->port,
+                                                  conn->oauth_bearer,
+                                                  &resp, &len);
+    }
+    else if((enabledmechs & SASL_MECH_XOAUTH2) && conn->oauth_bearer) {
+      mech = SASL_MECH_STRING_XOAUTH2;
+      state1 = SASL_OAUTH2;
+      sasl->authused = SASL_MECH_XOAUTH2;
+
+      if(force_ir || data->set.sasl_ir)
+        result = sasl_create_oauth_bearer_message(data, conn->user,
+                                                  NULL, 0,
+                                                  conn->oauth_bearer,
+                                                  &resp, &len);
+    }
+    else if(enabledmechs & SASL_MECH_LOGIN) {
+      mech = SASL_MECH_STRING_LOGIN;
+      state1 = SASL_LOGIN;
+      state2 = SASL_LOGIN_PASSWD;
+      sasl->authused = SASL_MECH_LOGIN;
+
+      if(force_ir || data->set.sasl_ir)
+        result = sasl_create_login_message(data, conn->user, &resp, &len);
+    }
+    else if(enabledmechs & SASL_MECH_PLAIN) {
+      mech = SASL_MECH_STRING_PLAIN;
+      state1 = SASL_PLAIN;
+      sasl->authused = SASL_MECH_PLAIN;
+
+      if(force_ir || data->set.sasl_ir)
+        result = sasl_create_plain_message(data, conn->user, conn->passwd,
+                                           &resp, &len);
+    }
+  }
+
+  if(!result) {
+    if(resp && sasl->params->maxirlen &&
+       strlen(mech) + len > sasl->params->maxirlen) {
+      free(resp);
+      resp = NULL;
+    }
+
+    if(mech) {
+      result = sasl->params->sendauth(conn, mech, resp);
+      if(!result) {
+        *progress = SASL_INPROGRESS;
+        state(sasl, conn, resp? state2: state1);
+      }
+    }
+  }
+
+  free(resp);
+
+  return result;
+}
+
+/*
+ * Curl_sasl_continue()
+ *
+ * Continue the authentication.
+ */
+CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
+                            int code, saslprogress *progress)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  saslstate newstate = SASL_FINAL;
+  char *resp = NULL;
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+  char *serverdata;
+  char *chlg = NULL;
+  size_t chlglen = 0;
+#endif
+  size_t len = 0;
+
+  *progress = SASL_INPROGRESS;
+
+  if(sasl->state == SASL_FINAL) {
+    if(code != sasl->params->finalcode)
+      result = CURLE_LOGIN_DENIED;
+    *progress = SASL_DONE;
+    state(sasl, conn, SASL_STOP);
+    return result;
+  }
+
+  if(sasl->state != SASL_CANCEL && sasl->state != SASL_OAUTH2_RESP &&
+     code != sasl->params->contcode) {
+    *progress = SASL_DONE;
+    state(sasl, conn, SASL_STOP);
+    return CURLE_LOGIN_DENIED;
+  }
+
+  switch(sasl->state) {
+  case SASL_STOP:
+    *progress = SASL_DONE;
+    return result;
+  case SASL_PLAIN:
+    result = sasl_create_plain_message(data, conn->user, conn->passwd, &resp,
+                                       &len);
+    break;
+  case SASL_LOGIN:
+    result = sasl_create_login_message(data, conn->user, &resp, &len);
+    newstate = SASL_LOGIN_PASSWD;
+    break;
+  case SASL_LOGIN_PASSWD:
+    result = sasl_create_login_message(data, conn->passwd, &resp, &len);
+    break;
+  case SASL_EXTERNAL:
+    result = sasl_create_external_message(data, conn->user, &resp, &len);
+    break;
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+  case SASL_CRAMMD5:
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    result = sasl_decode_cram_md5_message(serverdata, &chlg, &chlglen);
+    if(!result)
+      result = sasl_create_cram_md5_message(data, chlg, conn->user,
+                                            conn->passwd, &resp, &len);
+    free(chlg);
+    break;
+  case SASL_DIGESTMD5:
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    result = Curl_sasl_create_digest_md5_message(data, serverdata,
+                                                 conn->user, conn->passwd,
+                                                 sasl->params->service,
+                                                 &resp, &len);
+    newstate = SASL_DIGESTMD5_RESP;
+    break;
+  case SASL_DIGESTMD5_RESP:
+    if(!(resp = strdup("")))
+      result = CURLE_OUT_OF_MEMORY;
+    break;
+#endif
+
+#ifdef USE_NTLM
+  case SASL_NTLM:
+    /* Create the type-1 message */
+    result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
+                                                 &conn->ntlm, &resp, &len);
+    newstate = SASL_NTLM_TYPE2MSG;
+    break;
+  case SASL_NTLM_TYPE2MSG:
+    /* Decode the type-2 message */
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    result = Curl_sasl_decode_ntlm_type2_message(data, serverdata,
+                                                 &conn->ntlm);
+    if(!result)
+      result = Curl_sasl_create_ntlm_type3_message(data, conn->user,
+                                                   conn->passwd, &conn->ntlm,
+                                                   &resp, &len);
+    break;
+#endif
+
+#if defined(USE_KERBEROS5)
+  case SASL_GSSAPI:
+    result = Curl_sasl_create_gssapi_user_message(data, conn->user,
+                                                  conn->passwd,
+                                                  sasl->params->service,
+                                                  sasl->mutual_auth, NULL,
+                                                  &conn->krb5,
+                                                  &resp, &len);
+    newstate = SASL_GSSAPI_TOKEN;
+    break;
+  case SASL_GSSAPI_TOKEN:
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    if(sasl->mutual_auth) {
+      /* Decode the user token challenge and create the optional response
+         message */
+      result = Curl_sasl_create_gssapi_user_message(data, NULL, NULL, NULL,
+                                                    sasl->mutual_auth,
+                                                    serverdata, &conn->krb5,
+                                                    &resp, &len);
+      newstate = SASL_GSSAPI_NO_DATA;
+    }
+    else
+      /* Decode the security challenge and create the response message */
+      result = Curl_sasl_create_gssapi_security_message(data, serverdata,
+                                                        &conn->krb5,
+                                                        &resp, &len);
+    break;
+  case SASL_GSSAPI_NO_DATA:
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    /* Decode the security challenge and create the response message */
+    result = Curl_sasl_create_gssapi_security_message(data, serverdata,
+                                                      &conn->krb5,
+                                                      &resp, &len);
+    break;
+#endif
+
+  case SASL_OAUTH2:
+    /* Create the authorisation message */
+    if(sasl->authused == SASL_MECH_OAUTHBEARER) {
+      result = sasl_create_oauth_bearer_message(data, conn->user,
+                                                conn->host.name,
+                                                conn->port,
+                                                conn->oauth_bearer,
+                                                &resp, &len);
+
+      /* Failures maybe sent by the server as continuations for OAUTHBEARER */
+      newstate = SASL_OAUTH2_RESP;
+    }
+    else
+      result = sasl_create_oauth_bearer_message(data, conn->user,
+                                                NULL, 0,
+                                                conn->oauth_bearer,
+                                                &resp, &len);
+    break;
+
+  case SASL_OAUTH2_RESP:
+    /* The continuation is optional so check the response code */
+    if(code == sasl->params->finalcode) {
+      /* Final response was received so we are done */
+      *progress = SASL_DONE;
+      state(sasl, conn, SASL_STOP);
+      return result;
+    }
+    else if(code == sasl->params->contcode) {
+      /* Acknowledge the continuation by sending a 0x01 response base64
+         encoded */
+      resp = strdup("AQ==");
+      if(!resp)
+        result = CURLE_OUT_OF_MEMORY;
+      break;
+    }
+    else {
+      *progress = SASL_DONE;
+      state(sasl, conn, SASL_STOP);
+      return CURLE_LOGIN_DENIED;
+    }
+
+  case SASL_CANCEL:
+    /* Remove the offending mechanism from the supported list */
+    sasl->authmechs ^= sasl->authused;
+
+    /* Start an alternative SASL authentication */
+    result = Curl_sasl_start(sasl, conn, sasl->force_ir, progress);
+    newstate = sasl->state;   /* Use state from Curl_sasl_start() */
+    break;
+  default:
+    failf(data, "Unsupported SASL authentication mechanism");
+    result = CURLE_UNSUPPORTED_PROTOCOL;  /* Should not happen */
+    break;
+  }
+
+  switch(result) {
+  case CURLE_BAD_CONTENT_ENCODING:
+    /* Cancel dialog */
+    result = sasl->params->sendcont(conn, "*");
+    newstate = SASL_CANCEL;
+    break;
+  case CURLE_OK:
+    if(resp)
+      result = sasl->params->sendcont(conn, resp);
+    break;
+  default:
+    newstate = SASL_STOP;    /* Stop on error */
+    *progress = SASL_DONE;
+    break;
+  }
+
+  free(resp);
+
+  state(sasl, conn, newstate);
+
+  return result;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_sasl.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_sasl.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_sasl.h	(revision 164)
@@ -0,0 +1,255 @@
+#ifndef HEADER_CURL_SASL_H
+#define HEADER_CURL_SASL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+struct SessionHandle;
+struct connectdata;
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+struct digestdata;
+#endif
+
+#if defined(USE_NTLM)
+struct ntlmdata;
+#endif
+
+#if defined(USE_KERBEROS5)
+struct kerberos5data;
+#endif
+
+/* Authentication mechanism flags */
+#define SASL_MECH_LOGIN             (1 << 0)
+#define SASL_MECH_PLAIN             (1 << 1)
+#define SASL_MECH_CRAM_MD5          (1 << 2)
+#define SASL_MECH_DIGEST_MD5        (1 << 3)
+#define SASL_MECH_GSSAPI            (1 << 4)
+#define SASL_MECH_EXTERNAL          (1 << 5)
+#define SASL_MECH_NTLM              (1 << 6)
+#define SASL_MECH_XOAUTH2           (1 << 7)
+#define SASL_MECH_OAUTHBEARER       (1 << 8)
+
+/* Authentication mechanism values */
+#define SASL_AUTH_NONE          0
+#define SASL_AUTH_ANY           ~0U
+#define SASL_AUTH_DEFAULT       (SASL_AUTH_ANY & ~SASL_MECH_EXTERNAL)
+
+/* Authentication mechanism strings */
+#define SASL_MECH_STRING_LOGIN        "LOGIN"
+#define SASL_MECH_STRING_PLAIN        "PLAIN"
+#define SASL_MECH_STRING_CRAM_MD5     "CRAM-MD5"
+#define SASL_MECH_STRING_DIGEST_MD5   "DIGEST-MD5"
+#define SASL_MECH_STRING_GSSAPI       "GSSAPI"
+#define SASL_MECH_STRING_EXTERNAL     "EXTERNAL"
+#define SASL_MECH_STRING_NTLM         "NTLM"
+#define SASL_MECH_STRING_XOAUTH2      "XOAUTH2"
+#define SASL_MECH_STRING_OAUTHBEARER  "OAUTHBEARER"
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+#define DIGEST_MAX_VALUE_LENGTH           256
+#define DIGEST_MAX_CONTENT_LENGTH         1024
+#endif
+
+enum {
+  CURLDIGESTALGO_MD5,
+  CURLDIGESTALGO_MD5SESS
+};
+
+/* SASL machine states */
+typedef enum {
+  SASL_STOP,
+  SASL_PLAIN,
+  SASL_LOGIN,
+  SASL_LOGIN_PASSWD,
+  SASL_EXTERNAL,
+  SASL_CRAMMD5,
+  SASL_DIGESTMD5,
+  SASL_DIGESTMD5_RESP,
+  SASL_NTLM,
+  SASL_NTLM_TYPE2MSG,
+  SASL_GSSAPI,
+  SASL_GSSAPI_TOKEN,
+  SASL_GSSAPI_NO_DATA,
+  SASL_OAUTH2,
+  SASL_OAUTH2_RESP,
+  SASL_CANCEL,
+  SASL_FINAL
+} saslstate;
+
+/* Progress indicator */
+typedef enum {
+  SASL_IDLE,
+  SASL_INPROGRESS,
+  SASL_DONE
+} saslprogress;
+
+/* Protocol dependent SASL parameters */
+struct SASLproto {
+  const char *service;     /* The service name */
+  int contcode;            /* Code to receive when continuation is expected */
+  int finalcode;           /* Code to receive upon authentication success */
+  size_t maxirlen;         /* Maximum initial response length */
+  CURLcode (*sendauth)(struct connectdata *conn,
+                       const char *mech, const char *ir);
+                           /* Send authentication command */
+  CURLcode (*sendcont)(struct connectdata *conn, const char *contauth);
+                           /* Send authentication continuation */
+  void (*getmessage)(char *buffer, char **outptr);
+                           /* Get SASL response message */
+};
+
+/* Per-connection parameters */
+struct SASL {
+  const struct SASLproto *params; /* Protocol dependent parameters */
+  saslstate state;         /* Current machine state */
+  unsigned int authmechs;  /* Accepted authentication mechanisms */
+  unsigned int prefmech;   /* Preferred authentication mechanism */
+  unsigned int authused;   /* Auth mechanism used for the connection */
+  bool resetprefs;         /* For URL auth option parsing. */
+  bool mutual_auth;        /* Mutual authentication enabled (GSSAPI only) */
+  bool force_ir;           /* Protocol always supports initial response */
+};
+
+/* This is used to test whether the line starts with the given mechanism */
+#define sasl_mech_equal(line, wordlen, mech) \
+  (wordlen == (sizeof(mech) - 1) / sizeof(char) && \
+   !memcmp(line, mech, wordlen))
+
+/* This is used to build a SPN string */
+#if !defined(USE_WINDOWS_SSPI)
+char *Curl_sasl_build_spn(const char *service, const char *instance);
+#else
+TCHAR *Curl_sasl_build_spn(const char *service, const char *instance);
+#endif
+
+#if defined(HAVE_GSSAPI)
+char *Curl_sasl_build_gssapi_spn(const char *service, const char *instance);
+#endif
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+/* This is used to extract the realm from a challenge message */
+int Curl_sasl_digest_get_pair(const char *str, char *value, char *content,
+                              const char **endptr);
+
+/* This is used to generate a base64 encoded DIGEST-MD5 response message */
+CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
+                                             const char *chlg64,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             const char *service,
+                                             char **outptr, size_t *outlen);
+
+/* This is used to decode a HTTP DIGEST challenge message */
+CURLcode Curl_sasl_decode_digest_http_message(const char *chlg,
+                                              struct digestdata *digest);
+
+/* This is used to generate a HTTP DIGEST response message */
+CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data,
+                                              const char *userp,
+                                              const char *passwdp,
+                                              const unsigned char *request,
+                                              const unsigned char *uri,
+                                              struct digestdata *digest,
+                                              char **outptr, size_t *outlen);
+
+/* This is used to clean up the digest specific data */
+void Curl_sasl_digest_cleanup(struct digestdata *digest);
+#endif
+
+#ifdef USE_NTLM
+/* This is used to generate a base64 encoded NTLM type-1 message */
+CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
+                                             const char *passwdp,
+                                             struct ntlmdata *ntlm,
+                                             char **outptr,
+                                             size_t *outlen);
+
+/* This is used to decode a base64 encoded NTLM type-2 message */
+CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
+                                             const char *type2msg,
+                                             struct ntlmdata *ntlm);
+
+/* This is used to generate a base64 encoded NTLM type-3 message */
+CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             struct ntlmdata *ntlm,
+                                             char **outptr, size_t *outlen);
+
+/* This is used to clean up the ntlm specific data */
+void Curl_sasl_ntlm_cleanup(struct ntlmdata *ntlm);
+
+#endif /* USE_NTLM */
+
+#if defined(USE_KERBEROS5)
+/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) user token
+   message */
+CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
+                                              const char *userp,
+                                              const char *passwdp,
+                                              const char *service,
+                                              const bool mutual,
+                                              const char *chlg64,
+                                              struct kerberos5data *krb5,
+                                              char **outptr, size_t *outlen);
+
+/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) security
+   token message */
+CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
+                                                  const char *input,
+                                                  struct kerberos5data *krb5,
+                                                  char **outptr,
+                                                  size_t *outlen);
+
+/* This is used to clean up the gssapi specific data */
+void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5);
+#endif /* USE_KERBEROS5 */
+
+/* This is used to cleanup any libraries or curl modules used by the sasl
+   functions */
+void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused);
+
+/* Convert a mechanism name to a token */
+unsigned int Curl_sasl_decode_mech(const char *ptr,
+                                   size_t maxlen, size_t *len);
+
+/* Parse the URL login options */
+CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
+                                         const char *value, size_t len);
+
+/* Initializes an SASL structure */
+void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params);
+
+/* Check if we have enough auth data and capabilities to authenticate */
+bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn);
+
+/* Calculate the required login details for SASL authentication  */
+CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
+                         bool force_ir, saslprogress *progress);
+
+/* Continue an SASL authentication  */
+CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
+                            int code, saslprogress *progress);
+
+#endif /* HEADER_CURL_SASL_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_sasl_gssapi.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_sasl_gssapi.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_sasl_gssapi.c	(revision 164)
@@ -0,0 +1,392 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014 - 2015, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(HAVE_GSSAPI) && defined(USE_KERBEROS5)
+
+#include <curl/curl.h>
+
+#include "curl_sasl.h"
+#include "urldata.h"
+#include "curl_base64.h"
+#include "curl_gssapi.h"
+#include "sendf.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+* Curl_sasl_build_gssapi_spn()
+*
+* This is used to build a SPN string in the format service@instance.
+*
+* Parameters:
+*
+* service  [in] - The service type such as www, smtp, pop or imap.
+* instance [in] - The host name or realm.
+*
+* Returns a pointer to the newly allocated SPN.
+*/
+char *Curl_sasl_build_gssapi_spn(const char *service, const char *instance)
+{
+  /* Generate and return our SPN */
+  return aprintf("%s@%s", service, instance);
+}
+
+/*
+ * Curl_sasl_create_gssapi_user_message()
+ *
+ * This is used to generate an already encoded GSSAPI (Kerberos V5) user token
+ * message ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data        [in]     - The session handle.
+ * userp       [in]     - The user name.
+ * passdwp     [in]     - The user's password.
+ * service     [in]     - The service type such as www, smtp, pop or imap.
+ * mutual_auth [in]     - Flag specifing whether or not mutual authentication
+ *                        is enabled.
+ * chlg64      [in]     - Pointer to the optional base64 encoded challenge
+ *                        message.
+ * krb5        [in/out] - The gssapi data struct being used and modified.
+ * outptr      [in/out] - The address where a pointer to newly allocated memory
+ *                        holding the result will be stored upon completion.
+ * outlen      [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
+                                              const char *userp,
+                                              const char *passwdp,
+                                              const char *service,
+                                              const bool mutual_auth,
+                                              const char *chlg64,
+                                              struct kerberos5data *krb5,
+                                              char **outptr, size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  size_t chlglen = 0;
+  unsigned char *chlg = NULL;
+  OM_uint32 gss_status;
+  OM_uint32 gss_major_status;
+  OM_uint32 gss_minor_status;
+  gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+
+  (void) userp;
+  (void) passwdp;
+
+  if(krb5->context == GSS_C_NO_CONTEXT) {
+    /* Generate our SPN */
+    char *spn = Curl_sasl_build_gssapi_spn(service,
+                                           data->easy_conn->host.name);
+    if(!spn)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Populate the SPN structure */
+    spn_token.value = spn;
+    spn_token.length = strlen(spn);
+
+    /* Import the SPN */
+    gss_major_status = gss_import_name(&gss_minor_status, &spn_token,
+                                       GSS_C_NT_HOSTBASED_SERVICE, &krb5->spn);
+    if(GSS_ERROR(gss_major_status)) {
+      Curl_gss_log_error(data, gss_minor_status, "gss_import_name() failed: ");
+
+      free(spn);
+
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    free(spn);
+  }
+  else {
+    /* Decode the base-64 encoded challenge message */
+    if(strlen(chlg64) && *chlg64 != '=') {
+      result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+      if(result)
+        return result;
+    }
+
+    /* Ensure we have a valid challenge message */
+    if(!chlg) {
+      infof(data, "GSSAPI handshake failure (empty challenge message)\n");
+
+      return CURLE_BAD_CONTENT_ENCODING;
+    }
+
+    /* Setup the challenge "input" security buffer */
+    input_token.value = chlg;
+    input_token.length = chlglen;
+  }
+
+  gss_major_status = Curl_gss_init_sec_context(data,
+                                               &gss_minor_status,
+                                               &krb5->context,
+                                               krb5->spn,
+                                               &Curl_krb5_mech_oid,
+                                               GSS_C_NO_CHANNEL_BINDINGS,
+                                               &input_token,
+                                               &output_token,
+                                               mutual_auth,
+                                               NULL);
+
+  free(input_token.value);
+
+  if(GSS_ERROR(gss_major_status)) {
+    if(output_token.value)
+      gss_release_buffer(&gss_status, &output_token);
+
+    Curl_gss_log_error(data, gss_minor_status,
+                       "gss_init_sec_context() failed: ");
+
+    return CURLE_RECV_ERROR;
+  }
+
+  if(output_token.value && output_token.length) {
+    /* Base64 encode the response */
+    result = Curl_base64_encode(data, (char *) output_token.value,
+                                output_token.length, outptr, outlen);
+
+    gss_release_buffer(&gss_status, &output_token);
+  }
+
+  return result;
+}
+
+/*
+ * Curl_sasl_create_gssapi_security_message()
+ *
+ * This is used to generate an already encoded GSSAPI (Kerberos V5) security
+ * token message ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * chlg64  [in]     - Pointer to the optional base64 encoded challenge message.
+ * krb5    [in/out] - The gssapi data struct being used and modified.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
+                                                  const char *chlg64,
+                                                  struct kerberos5data *krb5,
+                                                  char **outptr,
+                                                  size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  size_t chlglen = 0;
+  size_t messagelen = 0;
+  unsigned char *chlg = NULL;
+  unsigned char *message = NULL;
+  OM_uint32 gss_status;
+  OM_uint32 gss_major_status;
+  OM_uint32 gss_minor_status;
+  gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+  unsigned int indata = 0;
+  unsigned int outdata = 0;
+  gss_qop_t qop = GSS_C_QOP_DEFAULT;
+  unsigned int sec_layer = 0;
+  unsigned int max_size = 0;
+  gss_name_t username = GSS_C_NO_NAME;
+  gss_buffer_desc username_token;
+
+  /* Decode the base-64 encoded input message */
+  if(strlen(chlg64) && *chlg64 != '=') {
+    result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+    if(result)
+      return result;
+  }
+
+  /* Ensure we have a valid challenge message */
+  if(!chlg) {
+    infof(data, "GSSAPI handshake failure (empty security message)\n");
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Get the fully qualified username back from the context */
+  gss_major_status = gss_inquire_context(&gss_minor_status, krb5->context,
+                                         &username, NULL, NULL, NULL, NULL,
+                                         NULL, NULL);
+  if(GSS_ERROR(gss_major_status)) {
+    Curl_gss_log_error(data, gss_minor_status,
+                       "gss_inquire_context() failed: ");
+
+    free(chlg);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Convert the username from internal format to a displayable token */
+  gss_major_status = gss_display_name(&gss_minor_status, username,
+                                      &username_token, NULL);
+  if(GSS_ERROR(gss_major_status)) {
+    Curl_gss_log_error(data, gss_minor_status, "gss_display_name() failed: ");
+
+    free(chlg);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Setup the challenge "input" security buffer */
+  input_token.value = chlg;
+  input_token.length = chlglen;
+
+  /* Decrypt the inbound challenge and obtain the qop */
+  gss_major_status = gss_unwrap(&gss_minor_status, krb5->context, &input_token,
+                                &output_token, NULL, &qop);
+  if(GSS_ERROR(gss_major_status)) {
+    Curl_gss_log_error(data, gss_minor_status, "gss_unwrap() failed: ");
+
+    gss_release_buffer(&gss_status, &username_token);
+    free(chlg);
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Not 4 octets long so fail as per RFC4752 Section 3.1 */
+  if(output_token.length != 4) {
+    infof(data, "GSSAPI handshake failure (invalid security data)\n");
+
+    gss_release_buffer(&gss_status, &username_token);
+    free(chlg);
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Copy the data out and free the challenge as it is not required anymore */
+  memcpy(&indata, output_token.value, 4);
+  gss_release_buffer(&gss_status, &output_token);
+  free(chlg);
+
+  /* Extract the security layer */
+  sec_layer = indata & 0x000000FF;
+  if(!(sec_layer & GSSAUTH_P_NONE)) {
+    infof(data, "GSSAPI handshake failure (invalid security layer)\n");
+
+    gss_release_buffer(&gss_status, &username_token);
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Extract the maximum message size the server can receive */
+  max_size = ntohl(indata & 0xFFFFFF00);
+  if(max_size > 0) {
+    /* The server has told us it supports a maximum receive buffer, however, as
+       we don't require one unless we are encrypting data, we tell the server
+       our receive buffer is zero. */
+    max_size = 0;
+  }
+
+  /* Allocate our message */
+  messagelen = sizeof(outdata) + username_token.length + 1;
+  message = malloc(messagelen);
+  if(!message) {
+    gss_release_buffer(&gss_status, &username_token);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Populate the message with the security layer, client supported receive
+     message size and authorization identity including the 0x00 based
+     terminator. Note: Dispite RFC4752 Section 3.1 stating "The authorization
+     identity is not terminated with the zero-valued (%x00) octet." it seems
+     necessary to include it. */
+  outdata = htonl(max_size) | sec_layer;
+  memcpy(message, &outdata, sizeof(outdata));
+  memcpy(message + sizeof(outdata), username_token.value,
+         username_token.length);
+  message[messagelen - 1] = '\0';
+
+  /* Free the username token as it is not required anymore */
+  gss_release_buffer(&gss_status, &username_token);
+
+  /* Setup the "authentication data" security buffer */
+  input_token.value = message;
+  input_token.length = messagelen;
+
+  /* Encrypt the data */
+  gss_major_status = gss_wrap(&gss_minor_status, krb5->context, 0,
+                              GSS_C_QOP_DEFAULT, &input_token, NULL,
+                              &output_token);
+  if(GSS_ERROR(gss_major_status)) {
+    Curl_gss_log_error(data, gss_minor_status, "gss_wrap() failed: ");
+
+    free(message);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Base64 encode the response */
+  result = Curl_base64_encode(data, (char *) output_token.value,
+                              output_token.length, outptr, outlen);
+
+  /* Free the output buffer */
+  gss_release_buffer(&gss_status, &output_token);
+
+  /* Free the message buffer */
+  free(message);
+
+  return result;
+}
+
+/*
+ * Curl_sasl_gssapi_cleanup()
+ *
+ * This is used to clean up the gssapi specific data.
+ *
+ * Parameters:
+ *
+ * krb5     [in/out] - The kerberos 5 data struct being cleaned up.
+ *
+ */
+void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5)
+{
+  OM_uint32 minor_status;
+
+  /* Free our security context */
+  if(krb5->context != GSS_C_NO_CONTEXT) {
+    gss_delete_sec_context(&minor_status, &krb5->context, GSS_C_NO_BUFFER);
+    krb5->context = GSS_C_NO_CONTEXT;
+  }
+
+  /* Free the SPN */
+  if(krb5->spn != GSS_C_NO_NAME) {
+    gss_release_name(&minor_status, &krb5->spn);
+    krb5->spn = GSS_C_NO_NAME;
+  }
+}
+
+#endif /* HAVE_GSSAPI && USE_KERBEROS5 */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_sasl_sspi.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_sasl_sspi.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_sasl_sspi.c	(revision 164)
@@ -0,0 +1,1295 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2014 - 2015, Steve Holme, <steve_holme@hotmail.com>.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC2617 Basic and Digest Access Authentication
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC4422 Simple Authentication and Security Layer (SASL)
+ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_WINDOWS_SSPI)
+
+#include <curl/curl.h>
+
+#include "curl_sasl.h"
+#include "urldata.h"
+#include "curl_base64.h"
+#include "warnless.h"
+#include "curl_multibyte.h"
+#include "sendf.h"
+#include "strdup.h"
+#include "curl_printf.h"
+#include "rawstr.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Curl_sasl_build_spn()
+ *
+ * This is used to build a SPN string in the format service/instance.
+ *
+ * Parameters:
+ *
+ * serivce  [in] - The service type such as www, smtp, pop or imap.
+ * instance [in] - The host name or realm.
+ *
+ * Returns a pointer to the newly allocated SPN.
+ */
+TCHAR *Curl_sasl_build_spn(const char *service, const char *instance)
+{
+  char *utf8_spn = NULL;
+  TCHAR *tchar_spn = NULL;
+
+  /* Note: We could use DsMakeSPN() or DsClientMakeSpnForTargetServer() rather
+     than doing this ourselves but the first is only available in Windows XP
+     and Windows Server 2003 and the latter is only available in Windows 2000
+     but not Windows95/98/ME or Windows NT4.0 unless the Active Directory
+     Client Extensions are installed. As such it is far simpler for us to
+     formulate the SPN instead. */
+
+  /* Allocate our UTF8 based SPN */
+  utf8_spn = aprintf("%s/%s", service, instance);
+  if(!utf8_spn) {
+    return NULL;
+  }
+
+  /* Allocate our TCHAR based SPN */
+  tchar_spn = Curl_convert_UTF8_to_tchar(utf8_spn);
+  if(!tchar_spn) {
+    free(utf8_spn);
+
+    return NULL;
+  }
+
+  /* Release the UTF8 variant when operating with Unicode */
+  Curl_unicodefree(utf8_spn);
+
+  /* Return our newly allocated SPN */
+  return tchar_spn;
+}
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+/*
+ * Curl_sasl_create_digest_md5_message()
+ *
+ * This is used to generate an already encoded DIGEST-MD5 response message
+ * ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * chlg64  [in]     - The base64 encoded challenge message.
+ * userp   [in]     - The user name in the format User or Domain\User.
+ * passdwp [in]     - The user's password.
+ * service [in]     - The service type such as www, smtp, pop or imap.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
+                                             const char *chlg64,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             const char *service,
+                                             char **outptr, size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  TCHAR *spn = NULL;
+  size_t chlglen = 0;
+  size_t token_max = 0;
+  unsigned char *input_token = NULL;
+  unsigned char *output_token = NULL;
+  CredHandle credentials;
+  CtxtHandle context;
+  PSecPkgInfo SecurityPackage;
+  SEC_WINNT_AUTH_IDENTITY identity;
+  SEC_WINNT_AUTH_IDENTITY *p_identity;
+  SecBuffer chlg_buf;
+  SecBuffer resp_buf;
+  SecBufferDesc chlg_desc;
+  SecBufferDesc resp_desc;
+  SECURITY_STATUS status;
+  unsigned long attrs;
+  TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+
+  /* Decode the base-64 encoded challenge message */
+  if(strlen(chlg64) && *chlg64 != '=') {
+    result = Curl_base64_decode(chlg64, &input_token, &chlglen);
+    if(result)
+      return result;
+  }
+
+  /* Ensure we have a valid challenge message */
+  if(!input_token) {
+    infof(data, "DIGEST-MD5 handshake failure (empty challenge message)\n");
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Query the security package for DigestSSP */
+  status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST),
+                                              &SecurityPackage);
+  if(status != SEC_E_OK) {
+    free(input_token);
+
+    return CURLE_NOT_BUILT_IN;
+  }
+
+  token_max = SecurityPackage->cbMaxToken;
+
+  /* Release the package buffer as it is not required anymore */
+  s_pSecFn->FreeContextBuffer(SecurityPackage);
+
+  /* Allocate our response buffer */
+  output_token = malloc(token_max);
+  if(!output_token) {
+    free(input_token);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Generate our SPN */
+  spn = Curl_sasl_build_spn(service, data->easy_conn->host.name);
+  if(!spn) {
+    free(output_token);
+    free(input_token);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(userp && *userp) {
+    /* Populate our identity structure */
+    result = Curl_create_sspi_identity(userp, passwdp, &identity);
+    if(result) {
+      free(spn);
+      free(output_token);
+      free(input_token);
+
+      return result;
+    }
+
+    /* Allow proper cleanup of the identity structure */
+    p_identity = &identity;
+  }
+  else
+    /* Use the current Windows user */
+    p_identity = NULL;
+
+  /* Acquire our credentials handle */
+  status = s_pSecFn->AcquireCredentialsHandle(NULL,
+                                              (TCHAR *) TEXT(SP_NAME_DIGEST),
+                                              SECPKG_CRED_OUTBOUND, NULL,
+                                              p_identity, NULL, NULL,
+                                              &credentials, &expiry);
+
+  if(status != SEC_E_OK) {
+    Curl_sspi_free_identity(p_identity);
+    free(spn);
+    free(output_token);
+    free(input_token);
+
+    return CURLE_LOGIN_DENIED;
+  }
+
+  /* Setup the challenge "input" security buffer */
+  chlg_desc.ulVersion = SECBUFFER_VERSION;
+  chlg_desc.cBuffers  = 1;
+  chlg_desc.pBuffers  = &chlg_buf;
+  chlg_buf.BufferType = SECBUFFER_TOKEN;
+  chlg_buf.pvBuffer   = input_token;
+  chlg_buf.cbBuffer   = curlx_uztoul(chlglen);
+
+  /* Setup the response "output" security buffer */
+  resp_desc.ulVersion = SECBUFFER_VERSION;
+  resp_desc.cBuffers  = 1;
+  resp_desc.pBuffers  = &resp_buf;
+  resp_buf.BufferType = SECBUFFER_TOKEN;
+  resp_buf.pvBuffer   = output_token;
+  resp_buf.cbBuffer   = curlx_uztoul(token_max);
+
+  /* Generate our response message */
+  status = s_pSecFn->InitializeSecurityContext(&credentials, NULL, spn,
+                                               0, 0, 0, &chlg_desc, 0,
+                                               &context, &resp_desc, &attrs,
+                                               &expiry);
+
+  if(status == SEC_I_COMPLETE_NEEDED ||
+     status == SEC_I_COMPLETE_AND_CONTINUE)
+    s_pSecFn->CompleteAuthToken(&credentials, &resp_desc);
+  else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
+    s_pSecFn->FreeCredentialsHandle(&credentials);
+    Curl_sspi_free_identity(p_identity);
+    free(spn);
+    free(output_token);
+    free(input_token);
+
+    return CURLE_RECV_ERROR;
+  }
+
+  /* Base64 encode the response */
+  result = Curl_base64_encode(data, (char *) output_token, resp_buf.cbBuffer,
+                              outptr, outlen);
+
+  /* Free our handles */
+  s_pSecFn->DeleteSecurityContext(&context);
+  s_pSecFn->FreeCredentialsHandle(&credentials);
+
+  /* Free the identity structure */
+  Curl_sspi_free_identity(p_identity);
+
+  /* Free the SPN */
+  free(spn);
+
+  /* Free the response buffer */
+  free(output_token);
+
+  /* Free the decoded challenge message */
+  free(input_token);
+
+  return result;
+}
+
+/*
+* Curl_override_sspi_http_realm()
+*
+* This is used to populate the domain in a SSPI identity structure
+* The realm is extracted from the challenge message and used as the
+* domain if it is not already explicitly set.
+*
+* Parameters:
+*
+* chlg     [in]     - The challenge message.
+* identity [in/out] - The identity structure.
+*
+* Returns CURLE_OK on success.
+*/
+CURLcode Curl_override_sspi_http_realm(const char *chlg,
+                                       SEC_WINNT_AUTH_IDENTITY *identity)
+{
+  xcharp_u domain, dup_domain;
+
+  /* If domain is blank or unset, check challenge message for realm */
+  if(!identity->Domain || !identity->DomainLength) {
+    for(;;) {
+      char value[DIGEST_MAX_VALUE_LENGTH];
+      char content[DIGEST_MAX_CONTENT_LENGTH];
+
+      /* Pass all additional spaces here */
+      while(*chlg && ISSPACE(*chlg))
+        chlg++;
+
+      /* Extract a value=content pair */
+      if(!Curl_sasl_digest_get_pair(chlg, value, content, &chlg)) {
+        if(Curl_raw_equal(value, "realm")) {
+
+          /* Setup identity's domain and length */
+          domain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)content);
+          if(!domain.tchar_ptr)
+            return CURLE_OUT_OF_MEMORY;
+          dup_domain.tchar_ptr = _tcsdup(domain.tchar_ptr);
+          if(!dup_domain.tchar_ptr) {
+            Curl_unicodefree(domain.tchar_ptr);
+            return CURLE_OUT_OF_MEMORY;
+          }
+          free(identity->Domain);
+          identity->Domain = dup_domain.tbyte_ptr;
+          identity->DomainLength = curlx_uztoul(_tcslen(dup_domain.tchar_ptr));
+          dup_domain.tchar_ptr = NULL;
+
+          Curl_unicodefree(domain.tchar_ptr);
+        }
+        else {
+          /* unknown specifier, ignore it! */
+        }
+      }
+      else
+        break; /* we're done here */
+
+      /* Pass all additional spaces here */
+      while(*chlg && ISSPACE(*chlg))
+        chlg++;
+
+      /* Allow the list to be comma-separated */
+      if(',' == *chlg)
+        chlg++;
+    }
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_decode_digest_http_message()
+ *
+ * This is used to decode a HTTP DIGEST challenge message into the seperate
+ * attributes.
+ *
+ * Parameters:
+ *
+ * chlg    [in]     - The challenge message.
+ * digest  [in/out] - The digest data struct being used and modified.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_decode_digest_http_message(const char *chlg,
+                                              struct digestdata *digest)
+{
+  size_t chlglen = strlen(chlg);
+
+  /* We had an input token before and we got another one now. This means we
+  provided bad credentials in the previous request. */
+  if(digest->input_token)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* Simply store the challenge for use later */
+  digest->input_token = (BYTE *) Curl_memdup(chlg, chlglen);
+  if(!digest->input_token)
+    return CURLE_OUT_OF_MEMORY;
+
+  digest->input_token_len = chlglen;
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_create_digest_http_message()
+ *
+ * This is used to generate a HTTP DIGEST response message ready for sending
+ * to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * userp   [in]     - The user name in the format User or Domain\User.
+ * passdwp [in]     - The user's password.
+ * request [in]     - The HTTP request.
+ * uripath [in]     - The path of the HTTP uri.
+ * digest  [in/out] - The digest data struct being used and modified.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data,
+                                              const char *userp,
+                                              const char *passwdp,
+                                              const unsigned char *request,
+                                              const unsigned char *uripath,
+                                              struct digestdata *digest,
+                                              char **outptr, size_t *outlen)
+{
+  size_t token_max;
+  CredHandle credentials;
+  CtxtHandle context;
+  char *resp;
+  BYTE *output_token;
+  PSecPkgInfo SecurityPackage;
+  SEC_WINNT_AUTH_IDENTITY identity;
+  SEC_WINNT_AUTH_IDENTITY *p_identity;
+  SecBuffer chlg_buf[3];
+  SecBuffer resp_buf;
+  SecBufferDesc chlg_desc;
+  SecBufferDesc resp_desc;
+  SECURITY_STATUS status;
+  unsigned long attrs;
+  TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+  TCHAR *spn;
+
+  (void) data;
+
+  /* Query the security package for DigestSSP */
+  status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST),
+                                              &SecurityPackage);
+  if(status != SEC_E_OK)
+    return CURLE_NOT_BUILT_IN;
+
+  token_max = SecurityPackage->cbMaxToken;
+
+  /* Release the package buffer as it is not required anymore */
+  s_pSecFn->FreeContextBuffer(SecurityPackage);
+
+  /* Allocate the output buffer according to the max token size as indicated
+     by the security package */
+  output_token = malloc(token_max);
+  if(!output_token)
+    return CURLE_OUT_OF_MEMORY;
+
+  if(userp && *userp) {
+    /* Populate our identity structure */
+    if(Curl_create_sspi_identity(userp, passwdp, &identity))
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Populate our identity domain */
+    if(Curl_override_sspi_http_realm((const char*)digest->input_token,
+                                     &identity))
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Allow proper cleanup of the identity structure */
+    p_identity = &identity;
+  }
+  else
+    /* Use the current Windows user */
+    p_identity = NULL;
+
+  /* Acquire our credentials handle */
+  status = s_pSecFn->AcquireCredentialsHandle(NULL,
+                                              (TCHAR *) TEXT(SP_NAME_DIGEST),
+                                              SECPKG_CRED_OUTBOUND, NULL,
+                                              p_identity, NULL, NULL,
+                                              &credentials, &expiry);
+  if(status != SEC_E_OK) {
+    Curl_sspi_free_identity(p_identity);
+    free(output_token);
+
+    return CURLE_LOGIN_DENIED;
+  }
+
+  /* Setup the challenge "input" security buffer if present */
+  chlg_desc.ulVersion    = SECBUFFER_VERSION;
+  chlg_desc.cBuffers     = 3;
+  chlg_desc.pBuffers     = chlg_buf;
+  chlg_buf[0].BufferType = SECBUFFER_TOKEN;
+  chlg_buf[0].pvBuffer   = digest->input_token;
+  chlg_buf[0].cbBuffer   = curlx_uztoul(digest->input_token_len);
+  chlg_buf[1].BufferType = SECBUFFER_PKG_PARAMS;
+  chlg_buf[1].pvBuffer   = (void *)request;
+  chlg_buf[1].cbBuffer   = curlx_uztoul(strlen((const char *) request));
+  chlg_buf[2].BufferType = SECBUFFER_PKG_PARAMS;
+  chlg_buf[2].pvBuffer   = NULL;
+  chlg_buf[2].cbBuffer   = 0;
+
+  /* Setup the response "output" security buffer */
+  resp_desc.ulVersion = SECBUFFER_VERSION;
+  resp_desc.cBuffers  = 1;
+  resp_desc.pBuffers  = &resp_buf;
+  resp_buf.BufferType = SECBUFFER_TOKEN;
+  resp_buf.pvBuffer   = output_token;
+  resp_buf.cbBuffer   = curlx_uztoul(token_max);
+
+  spn = Curl_convert_UTF8_to_tchar((char *) uripath);
+  if(!spn) {
+    Curl_sspi_free_identity(p_identity);
+    free(output_token);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Generate our reponse message */
+  status = s_pSecFn->InitializeSecurityContext(&credentials, NULL,
+                                               spn,
+                                               ISC_REQ_USE_HTTP_STYLE, 0, 0,
+                                               &chlg_desc, 0, &context,
+                                               &resp_desc, &attrs, &expiry);
+  Curl_unicodefree(spn);
+
+  if(status == SEC_I_COMPLETE_NEEDED ||
+     status == SEC_I_COMPLETE_AND_CONTINUE)
+    s_pSecFn->CompleteAuthToken(&credentials, &resp_desc);
+  else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
+    s_pSecFn->FreeCredentialsHandle(&credentials);
+
+    Curl_sspi_free_identity(p_identity);
+    free(output_token);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  resp = malloc(resp_buf.cbBuffer + 1);
+  if(!resp) {
+    s_pSecFn->DeleteSecurityContext(&context);
+    s_pSecFn->FreeCredentialsHandle(&credentials);
+
+    Curl_sspi_free_identity(p_identity);
+    free(output_token);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Copy the generated reponse */
+  memcpy(resp, resp_buf.pvBuffer, resp_buf.cbBuffer);
+  resp[resp_buf.cbBuffer] = 0x00;
+
+  /* Return the response */
+  *outptr = resp;
+  *outlen = resp_buf.cbBuffer;
+
+  /* Free our handles */
+  s_pSecFn->DeleteSecurityContext(&context);
+  s_pSecFn->FreeCredentialsHandle(&credentials);
+
+  /* Free the identity structure */
+  Curl_sspi_free_identity(p_identity);
+
+  /* Free the response buffer */
+  free(output_token);
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_digest_cleanup()
+ *
+ * This is used to clean up the digest specific data.
+ *
+ * Parameters:
+ *
+ * digest    [in/out] - The digest data struct being cleaned up.
+ *
+ */
+void Curl_sasl_digest_cleanup(struct digestdata *digest)
+{
+  /* Free the input token */
+  Curl_safefree(digest->input_token);
+
+  /* Reset any variables */
+  digest->input_token_len = 0;
+}
+#endif /* !CURL_DISABLE_CRYPTO_AUTH */
+
+#if defined USE_NTLM
+/*
+* Curl_sasl_create_ntlm_type1_message()
+*
+* This is used to generate an already encoded NTLM type-1 message ready for
+* sending to the recipient.
+*
+* Parameters:
+*
+* userp   [in]     - The user name in the format User or Domain\User.
+* passdwp [in]     - The user's password.
+* ntlm    [in/out] - The ntlm data struct being used and modified.
+* outptr  [in/out] - The address where a pointer to newly allocated memory
+*                    holding the result will be stored upon completion.
+* outlen  [out]    - The length of the output message.
+*
+* Returns CURLE_OK on success.
+*/
+CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
+                                             const char *passwdp,
+                                             struct ntlmdata *ntlm,
+                                             char **outptr, size_t *outlen)
+{
+  PSecPkgInfo SecurityPackage;
+  SecBuffer type_1_buf;
+  SecBufferDesc type_1_desc;
+  SECURITY_STATUS status;
+  unsigned long attrs;
+  TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+
+  /* Clean up any former leftovers and initialise to defaults */
+  Curl_sasl_ntlm_cleanup(ntlm);
+
+  /* Query the security package for NTLM */
+  status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM),
+                                              &SecurityPackage);
+  if(status != SEC_E_OK)
+    return CURLE_NOT_BUILT_IN;
+
+  ntlm->token_max = SecurityPackage->cbMaxToken;
+
+  /* Release the package buffer as it is not required anymore */
+  s_pSecFn->FreeContextBuffer(SecurityPackage);
+
+  /* Allocate our output buffer */
+  ntlm->output_token = malloc(ntlm->token_max);
+  if(!ntlm->output_token)
+    return CURLE_OUT_OF_MEMORY;
+
+  if(userp && *userp) {
+    CURLcode result;
+
+    /* Populate our identity structure */
+    result = Curl_create_sspi_identity(userp, passwdp, &ntlm->identity);
+    if(result)
+      return result;
+
+    /* Allow proper cleanup of the identity structure */
+    ntlm->p_identity = &ntlm->identity;
+  }
+  else
+    /* Use the current Windows user */
+    ntlm->p_identity = NULL;
+
+  /* Allocate our credentials handle */
+  ntlm->credentials = malloc(sizeof(CredHandle));
+  if(!ntlm->credentials)
+    return CURLE_OUT_OF_MEMORY;
+
+  memset(ntlm->credentials, 0, sizeof(CredHandle));
+
+  /* Acquire our credentials handle */
+  status = s_pSecFn->AcquireCredentialsHandle(NULL,
+                                              (TCHAR *) TEXT(SP_NAME_NTLM),
+                                              SECPKG_CRED_OUTBOUND, NULL,
+                                              ntlm->p_identity, NULL, NULL,
+                                              ntlm->credentials, &expiry);
+  if(status != SEC_E_OK)
+    return CURLE_LOGIN_DENIED;
+
+  /* Allocate our new context handle */
+  ntlm->context = malloc(sizeof(CtxtHandle));
+  if(!ntlm->context)
+    return CURLE_OUT_OF_MEMORY;
+
+  memset(ntlm->context, 0, sizeof(CtxtHandle));
+
+  /* Setup the type-1 "output" security buffer */
+  type_1_desc.ulVersion = SECBUFFER_VERSION;
+  type_1_desc.cBuffers  = 1;
+  type_1_desc.pBuffers  = &type_1_buf;
+  type_1_buf.BufferType = SECBUFFER_TOKEN;
+  type_1_buf.pvBuffer   = ntlm->output_token;
+  type_1_buf.cbBuffer   = curlx_uztoul(ntlm->token_max);
+
+  /* Generate our type-1 message */
+  status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, NULL,
+                                               (TCHAR *) TEXT(""),
+                                               0, 0, SECURITY_NETWORK_DREP,
+                                               NULL, 0,
+                                               ntlm->context, &type_1_desc,
+                                               &attrs, &expiry);
+  if(status == SEC_I_COMPLETE_NEEDED ||
+    status == SEC_I_COMPLETE_AND_CONTINUE)
+    s_pSecFn->CompleteAuthToken(ntlm->context, &type_1_desc);
+  else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED)
+    return CURLE_RECV_ERROR;
+
+  /* Base64 encode the response */
+  return Curl_base64_encode(NULL, (char *) ntlm->output_token,
+                            type_1_buf.cbBuffer, outptr, outlen);
+}
+
+/*
+* Curl_sasl_decode_ntlm_type2_message()
+*
+* This is used to decode an already encoded NTLM type-2 message.
+*
+* Parameters:
+*
+* data     [in]     - The session handle.
+* type2msg [in]     - The base64 encoded type-2 message.
+* ntlm     [in/out] - The ntlm data struct being used and modified.
+*
+* Returns CURLE_OK on success.
+*/
+CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
+                                             const char *type2msg,
+                                             struct ntlmdata *ntlm)
+{
+  CURLcode result = CURLE_OK;
+  unsigned char *type2 = NULL;
+  size_t type2_len = 0;
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) data;
+#endif
+
+  /* Decode the base-64 encoded type-2 message */
+  if(strlen(type2msg) && *type2msg != '=') {
+    result = Curl_base64_decode(type2msg, &type2, &type2_len);
+    if(result)
+      return result;
+  }
+
+  /* Ensure we have a valid type-2 message */
+  if(!type2) {
+    infof(data, "NTLM handshake failure (empty type-2 message)\n");
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Simply store the challenge for use later */
+  ntlm->input_token = type2;
+  ntlm->input_token_len = type2_len;
+
+  return result;
+}
+
+/*
+* Curl_sasl_create_ntlm_type3_message()
+*
+* This is used to generate an already encoded NTLM type-3 message ready for
+* sending to the recipient.
+*
+* Parameters:
+*
+* data    [in]     - The session handle.
+* userp   [in]     - The user name in the format User or Domain\User.
+* passdwp [in]     - The user's password.
+* ntlm    [in/out] - The ntlm data struct being used and modified.
+* outptr  [in/out] - The address where a pointer to newly allocated memory
+*                    holding the result will be stored upon completion.
+* outlen  [out]    - The length of the output message.
+*
+* Returns CURLE_OK on success.
+*/
+CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             struct ntlmdata *ntlm,
+                                             char **outptr, size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  SecBuffer type_2_buf;
+  SecBuffer type_3_buf;
+  SecBufferDesc type_2_desc;
+  SecBufferDesc type_3_desc;
+  SECURITY_STATUS status;
+  unsigned long attrs;
+  TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+
+  (void) passwdp;
+  (void) userp;
+
+  /* Setup the type-2 "input" security buffer */
+  type_2_desc.ulVersion = SECBUFFER_VERSION;
+  type_2_desc.cBuffers  = 1;
+  type_2_desc.pBuffers  = &type_2_buf;
+  type_2_buf.BufferType = SECBUFFER_TOKEN;
+  type_2_buf.pvBuffer   = ntlm->input_token;
+  type_2_buf.cbBuffer   = curlx_uztoul(ntlm->input_token_len);
+
+  /* Setup the type-3 "output" security buffer */
+  type_3_desc.ulVersion = SECBUFFER_VERSION;
+  type_3_desc.cBuffers  = 1;
+  type_3_desc.pBuffers  = &type_3_buf;
+  type_3_buf.BufferType = SECBUFFER_TOKEN;
+  type_3_buf.pvBuffer   = ntlm->output_token;
+  type_3_buf.cbBuffer   = curlx_uztoul(ntlm->token_max);
+
+  /* Generate our type-3 message */
+  status = s_pSecFn->InitializeSecurityContext(ntlm->credentials,
+                                               ntlm->context,
+                                               (TCHAR *) TEXT(""),
+                                               0, 0, SECURITY_NETWORK_DREP,
+                                               &type_2_desc,
+                                               0, ntlm->context,
+                                               &type_3_desc,
+                                               &attrs, &expiry);
+  if(status != SEC_E_OK) {
+    infof(data, "NTLM handshake failure (type-3 message): Status=%x\n",
+          status);
+
+    return CURLE_RECV_ERROR;
+  }
+
+  /* Base64 encode the response */
+  result = Curl_base64_encode(data, (char *) ntlm->output_token,
+                              type_3_buf.cbBuffer, outptr, outlen);
+
+  Curl_sasl_ntlm_cleanup(ntlm);
+
+  return result;
+}
+
+/*
+ * Curl_sasl_ntlm_cleanup()
+ *
+ * This is used to clean up the ntlm specific data.
+ *
+ * Parameters:
+ *
+ * ntlm    [in/out] - The ntlm data struct being cleaned up.
+ *
+ */
+void Curl_sasl_ntlm_cleanup(struct ntlmdata *ntlm)
+{
+  /* Free our security context */
+  if(ntlm->context) {
+    s_pSecFn->DeleteSecurityContext(ntlm->context);
+    free(ntlm->context);
+    ntlm->context = NULL;
+  }
+
+  /* Free our credentials handle */
+  if(ntlm->credentials) {
+    s_pSecFn->FreeCredentialsHandle(ntlm->credentials);
+    free(ntlm->credentials);
+    ntlm->credentials = NULL;
+  }
+
+  /* Free our identity */
+  Curl_sspi_free_identity(ntlm->p_identity);
+  ntlm->p_identity = NULL;
+
+  /* Free the input and output tokens */
+  Curl_safefree(ntlm->input_token);
+  Curl_safefree(ntlm->output_token);
+
+  /* Reset any variables */
+  ntlm->token_max = 0;
+}
+#endif /* USE_NTLM */
+
+#if defined(USE_KERBEROS5)
+/*
+ * Curl_sasl_create_gssapi_user_message()
+ *
+ * This is used to generate an already encoded GSSAPI (Kerberos V5) user token
+ * message ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data        [in]     - The session handle.
+ * userp       [in]     - The user name in the format User or Domain\User.
+ * passdwp     [in]     - The user's password.
+ * service     [in]     - The service type such as www, smtp, pop or imap.
+ * mutual_auth [in]     - Flag specifing whether or not mutual authentication
+ *                        is enabled.
+ * chlg64      [in]     - The optional base64 encoded challenge message.
+ * krb5        [in/out] - The gssapi data struct being used and modified.
+ * outptr      [in/out] - The address where a pointer to newly allocated memory
+ *                        holding the result will be stored upon completion.
+ * outlen      [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
+                                              const char *userp,
+                                              const char *passwdp,
+                                              const char *service,
+                                              const bool mutual_auth,
+                                              const char *chlg64,
+                                              struct kerberos5data *krb5,
+                                              char **outptr, size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  size_t chlglen = 0;
+  unsigned char *chlg = NULL;
+  CtxtHandle context;
+  PSecPkgInfo SecurityPackage;
+  SecBuffer chlg_buf;
+  SecBuffer resp_buf;
+  SecBufferDesc chlg_desc;
+  SecBufferDesc resp_desc;
+  SECURITY_STATUS status;
+  unsigned long attrs;
+  TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+
+  if(!krb5->credentials) {
+    /* Query the security package for Kerberos */
+    status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
+                                                TEXT(SP_NAME_KERBEROS),
+                                                &SecurityPackage);
+    if(status != SEC_E_OK) {
+      return CURLE_NOT_BUILT_IN;
+    }
+
+    krb5->token_max = SecurityPackage->cbMaxToken;
+
+    /* Release the package buffer as it is not required anymore */
+    s_pSecFn->FreeContextBuffer(SecurityPackage);
+
+    /* Allocate our response buffer */
+    krb5->output_token = malloc(krb5->token_max);
+    if(!krb5->output_token)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Generate our SPN */
+    krb5->spn = Curl_sasl_build_spn(service, data->easy_conn->host.name);
+    if(!krb5->spn)
+      return CURLE_OUT_OF_MEMORY;
+
+    if(userp && *userp) {
+      /* Populate our identity structure */
+      result = Curl_create_sspi_identity(userp, passwdp, &krb5->identity);
+      if(result)
+        return result;
+
+      /* Allow proper cleanup of the identity structure */
+      krb5->p_identity = &krb5->identity;
+    }
+    else
+      /* Use the current Windows user */
+      krb5->p_identity = NULL;
+
+    /* Allocate our credentials handle */
+    krb5->credentials = malloc(sizeof(CredHandle));
+    if(!krb5->credentials)
+      return CURLE_OUT_OF_MEMORY;
+
+    memset(krb5->credentials, 0, sizeof(CredHandle));
+
+    /* Acquire our credentials handle */
+    status = s_pSecFn->AcquireCredentialsHandle(NULL,
+                                                (TCHAR *)
+                                                TEXT(SP_NAME_KERBEROS),
+                                                SECPKG_CRED_OUTBOUND, NULL,
+                                                krb5->p_identity, NULL, NULL,
+                                                krb5->credentials, &expiry);
+    if(status != SEC_E_OK)
+      return CURLE_LOGIN_DENIED;
+
+    /* Allocate our new context handle */
+    krb5->context = malloc(sizeof(CtxtHandle));
+    if(!krb5->context)
+      return CURLE_OUT_OF_MEMORY;
+
+    memset(krb5->context, 0, sizeof(CtxtHandle));
+  }
+  else {
+    /* Decode the base-64 encoded challenge message */
+    if(strlen(chlg64) && *chlg64 != '=') {
+      result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+      if(result)
+        return result;
+    }
+
+    /* Ensure we have a valid challenge message */
+    if(!chlg) {
+      infof(data, "GSSAPI handshake failure (empty challenge message)\n");
+
+      return CURLE_BAD_CONTENT_ENCODING;
+    }
+
+    /* Setup the challenge "input" security buffer */
+    chlg_desc.ulVersion = SECBUFFER_VERSION;
+    chlg_desc.cBuffers  = 1;
+    chlg_desc.pBuffers  = &chlg_buf;
+    chlg_buf.BufferType = SECBUFFER_TOKEN;
+    chlg_buf.pvBuffer   = chlg;
+    chlg_buf.cbBuffer   = curlx_uztoul(chlglen);
+  }
+
+  /* Setup the response "output" security buffer */
+  resp_desc.ulVersion = SECBUFFER_VERSION;
+  resp_desc.cBuffers  = 1;
+  resp_desc.pBuffers  = &resp_buf;
+  resp_buf.BufferType = SECBUFFER_TOKEN;
+  resp_buf.pvBuffer   = krb5->output_token;
+  resp_buf.cbBuffer   = curlx_uztoul(krb5->token_max);
+
+  /* Generate our challenge-response message */
+  status = s_pSecFn->InitializeSecurityContext(krb5->credentials,
+                                               chlg ? krb5->context : NULL,
+                                               krb5->spn,
+                                               (mutual_auth ?
+                                                 ISC_REQ_MUTUAL_AUTH : 0),
+                                               0, SECURITY_NATIVE_DREP,
+                                               chlg ? &chlg_desc : NULL, 0,
+                                               &context,
+                                               &resp_desc, &attrs,
+                                               &expiry);
+
+  if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
+    free(chlg);
+
+    return CURLE_RECV_ERROR;
+  }
+
+  if(memcmp(&context, krb5->context, sizeof(context))) {
+    s_pSecFn->DeleteSecurityContext(krb5->context);
+
+    memcpy(krb5->context, &context, sizeof(context));
+  }
+
+  if(resp_buf.cbBuffer) {
+    /* Base64 encode the response */
+    result = Curl_base64_encode(data, (char *)resp_buf.pvBuffer,
+                                resp_buf.cbBuffer, outptr, outlen);
+  }
+
+  /* Free the decoded challenge */
+  free(chlg);
+
+  return result;
+}
+
+/*
+ * Curl_sasl_create_gssapi_security_message()
+ *
+ * This is used to generate an already encoded GSSAPI (Kerberos V5) security
+ * token message ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * chlg64  [in]     - The optional base64 encoded challenge message.
+ * krb5    [in/out] - The gssapi data struct being used and modified.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
+                                                  const char *chlg64,
+                                                  struct kerberos5data *krb5,
+                                                  char **outptr,
+                                                  size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  size_t offset = 0;
+  size_t chlglen = 0;
+  size_t messagelen = 0;
+  size_t appdatalen = 0;
+  unsigned char *chlg = NULL;
+  unsigned char *trailer = NULL;
+  unsigned char *message = NULL;
+  unsigned char *padding = NULL;
+  unsigned char *appdata = NULL;
+  SecBuffer input_buf[2];
+  SecBuffer wrap_buf[3];
+  SecBufferDesc input_desc;
+  SecBufferDesc wrap_desc;
+  unsigned long indata = 0;
+  unsigned long outdata = 0;
+  unsigned long qop = 0;
+  unsigned long sec_layer = 0;
+  unsigned long max_size = 0;
+  SecPkgContext_Sizes sizes;
+  SecPkgCredentials_Names names;
+  SECURITY_STATUS status;
+  char *user_name;
+
+  /* Decode the base-64 encoded input message */
+  if(strlen(chlg64) && *chlg64 != '=') {
+    result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+    if(result)
+      return result;
+  }
+
+  /* Ensure we have a valid challenge message */
+  if(!chlg) {
+    infof(data, "GSSAPI handshake failure (empty security message)\n");
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Get our response size information */
+  status = s_pSecFn->QueryContextAttributes(krb5->context,
+                                            SECPKG_ATTR_SIZES,
+                                            &sizes);
+  if(status != SEC_E_OK) {
+    free(chlg);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Get the fully qualified username back from the context */
+  status = s_pSecFn->QueryCredentialsAttributes(krb5->credentials,
+                                                SECPKG_CRED_ATTR_NAMES,
+                                                &names);
+  if(status != SEC_E_OK) {
+    free(chlg);
+
+    return CURLE_RECV_ERROR;
+  }
+
+  /* Setup the "input" security buffer */
+  input_desc.ulVersion = SECBUFFER_VERSION;
+  input_desc.cBuffers = 2;
+  input_desc.pBuffers = input_buf;
+  input_buf[0].BufferType = SECBUFFER_STREAM;
+  input_buf[0].pvBuffer = chlg;
+  input_buf[0].cbBuffer = curlx_uztoul(chlglen);
+  input_buf[1].BufferType = SECBUFFER_DATA;
+  input_buf[1].pvBuffer = NULL;
+  input_buf[1].cbBuffer = 0;
+
+  /* Decrypt the inbound challenge and obtain the qop */
+  status = s_pSecFn->DecryptMessage(krb5->context, &input_desc, 0, &qop);
+  if(status != SEC_E_OK) {
+    infof(data, "GSSAPI handshake failure (empty security message)\n");
+
+    free(chlg);
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Not 4 octets long so fail as per RFC4752 Section 3.1 */
+  if(input_buf[1].cbBuffer != 4) {
+    infof(data, "GSSAPI handshake failure (invalid security data)\n");
+
+    free(chlg);
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Copy the data out and free the challenge as it is not required anymore */
+  memcpy(&indata, input_buf[1].pvBuffer, 4);
+  s_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer);
+  free(chlg);
+
+  /* Extract the security layer */
+  sec_layer = indata & 0x000000FF;
+  if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) {
+    infof(data, "GSSAPI handshake failure (invalid security layer)\n");
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Extract the maximum message size the server can receive */
+  max_size = ntohl(indata & 0xFFFFFF00);
+  if(max_size > 0) {
+    /* The server has told us it supports a maximum receive buffer, however, as
+       we don't require one unless we are encrypting data, we tell the server
+       our receive buffer is zero. */
+    max_size = 0;
+  }
+
+  /* Allocate the trailer */
+  trailer = malloc(sizes.cbSecurityTrailer);
+  if(!trailer)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Convert the user name to UTF8 when operating with Unicode */
+  user_name = Curl_convert_tchar_to_UTF8(names.sUserName);
+  if(!user_name) {
+    free(trailer);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Allocate our message */
+  messagelen = sizeof(outdata) + strlen(user_name) + 1;
+  message = malloc(messagelen);
+  if(!message) {
+    free(trailer);
+    Curl_unicodefree(user_name);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Populate the message with the security layer, client supported receive
+     message size and authorization identity including the 0x00 based
+     terminator. Note: Dispite RFC4752 Section 3.1 stating "The authorization
+     identity is not terminated with the zero-valued (%x00) octet." it seems
+     necessary to include it. */
+  outdata = htonl(max_size) | sec_layer;
+  memcpy(message, &outdata, sizeof(outdata));
+  strcpy((char *) message + sizeof(outdata), user_name);
+  Curl_unicodefree(user_name);
+
+  /* Allocate the padding */
+  padding = malloc(sizes.cbBlockSize);
+  if(!padding) {
+    free(message);
+    free(trailer);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Setup the "authentication data" security buffer */
+  wrap_desc.ulVersion    = SECBUFFER_VERSION;
+  wrap_desc.cBuffers     = 3;
+  wrap_desc.pBuffers     = wrap_buf;
+  wrap_buf[0].BufferType = SECBUFFER_TOKEN;
+  wrap_buf[0].pvBuffer   = trailer;
+  wrap_buf[0].cbBuffer   = sizes.cbSecurityTrailer;
+  wrap_buf[1].BufferType = SECBUFFER_DATA;
+  wrap_buf[1].pvBuffer   = message;
+  wrap_buf[1].cbBuffer   = curlx_uztoul(messagelen);
+  wrap_buf[2].BufferType = SECBUFFER_PADDING;
+  wrap_buf[2].pvBuffer   = padding;
+  wrap_buf[2].cbBuffer   = sizes.cbBlockSize;
+
+  /* Encrypt the data */
+  status = s_pSecFn->EncryptMessage(krb5->context, KERB_WRAP_NO_ENCRYPT,
+                                    &wrap_desc, 0);
+  if(status != SEC_E_OK) {
+    free(padding);
+    free(message);
+    free(trailer);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Allocate the encryption (wrap) buffer */
+  appdatalen = wrap_buf[0].cbBuffer + wrap_buf[1].cbBuffer +
+               wrap_buf[2].cbBuffer;
+  appdata = malloc(appdatalen);
+  if(!appdata) {
+    free(padding);
+    free(message);
+    free(trailer);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Populate the encryption buffer */
+  memcpy(appdata, wrap_buf[0].pvBuffer, wrap_buf[0].cbBuffer);
+  offset += wrap_buf[0].cbBuffer;
+  memcpy(appdata + offset, wrap_buf[1].pvBuffer, wrap_buf[1].cbBuffer);
+  offset += wrap_buf[1].cbBuffer;
+  memcpy(appdata + offset, wrap_buf[2].pvBuffer, wrap_buf[2].cbBuffer);
+
+  /* Base64 encode the response */
+  result = Curl_base64_encode(data, (char *)appdata, appdatalen, outptr,
+                              outlen);
+
+  /* Free all of our local buffers */
+  free(appdata);
+  free(padding);
+  free(message);
+  free(trailer);
+
+  return result;
+}
+
+/*
+ * Curl_sasl_gssapi_cleanup()
+ *
+ * This is used to clean up the gssapi specific data.
+ *
+ * Parameters:
+ *
+ * krb5     [in/out] - The kerberos 5 data struct being cleaned up.
+ *
+ */
+void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5)
+{
+  /* Free our security context */
+  if(krb5->context) {
+    s_pSecFn->DeleteSecurityContext(krb5->context);
+    free(krb5->context);
+    krb5->context = NULL;
+  }
+
+  /* Free our credentials handle */
+  if(krb5->credentials) {
+    s_pSecFn->FreeCredentialsHandle(krb5->credentials);
+    free(krb5->credentials);
+    krb5->credentials = NULL;
+  }
+
+  /* Free our identity */
+  Curl_sspi_free_identity(krb5->p_identity);
+  krb5->p_identity = NULL;
+
+  /* Free the SPN and output token */
+  Curl_safefree(krb5->spn);
+  Curl_safefree(krb5->output_token);
+
+  /* Reset any variables */
+  krb5->token_max = 0;
+}
+#endif /* USE_KERBEROS5 */
+
+#endif /* USE_WINDOWS_SSPI */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_sec.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_sec.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_sec.h	(revision 164)
@@ -0,0 +1,51 @@
+#ifndef HEADER_CURL_SECURITY_H
+#define HEADER_CURL_SECURITY_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+struct Curl_sec_client_mech {
+  const char *name;
+  size_t size;
+  int (*init)(void *);
+  int (*auth)(void *, struct connectdata *);
+  void (*end)(void *);
+  int (*check_prot)(void *, int);
+  int (*overhead)(void *, int, int);
+  int (*encode)(void *, const void*, int, int, void**);
+  int (*decode)(void *, void*, int, int, struct connectdata *);
+};
+
+#define AUTH_OK         0
+#define AUTH_CONTINUE   1
+#define AUTH_ERROR      2
+
+#ifdef HAVE_GSSAPI
+int Curl_sec_read_msg (struct connectdata *conn, char *,
+                       enum protection_level);
+void Curl_sec_end (struct connectdata *);
+CURLcode Curl_sec_login (struct connectdata *);
+int Curl_sec_request_prot (struct connectdata *conn, const char *level);
+
+extern struct Curl_sec_client_mech Curl_krb5_client_mech;
+#endif
+
+#endif /* HEADER_CURL_SECURITY_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_setup.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_setup.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_setup.h	(revision 164)
@@ -0,0 +1,729 @@
+#ifndef HEADER_CURL_SETUP_H
+#define HEADER_CURL_SETUP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) && \
+    !defined(__SYMBIAN32__)
+#define WIN32
+#endif
+
+/*
+ * Include configuration script results or hand-crafted
+ * configuration file for platforms which lack config tool.
+ */
+
+#ifdef HAVE_CONFIG_H
+
+#include "curl_config.h"
+
+#else /* HAVE_CONFIG_H */
+
+#ifdef _WIN32_WCE
+#  include "config-win32ce.h"
+#else
+#  ifdef WIN32
+#    include "config-win32.h"
+#  endif
+#endif
+
+#if defined(macintosh) && defined(__MRC__)
+#  include "config-mac.h"
+#endif
+
+#ifdef __riscos__
+#  include "config-riscos.h"
+#endif
+
+#ifdef __AMIGA__
+#  include "config-amigaos.h"
+#endif
+
+#ifdef __SYMBIAN32__
+#  include "config-symbian.h"
+#endif
+
+#ifdef __OS400__
+#  include "config-os400.h"
+#endif
+
+#ifdef TPF
+#  include "config-tpf.h"
+#endif
+
+#ifdef __VXWORKS__
+#  include "config-vxworks.h"
+#endif
+
+#endif /* HAVE_CONFIG_H */
+
+/* ================================================================ */
+/* Definition of preprocessor macros/symbols which modify compiler  */
+/* behavior or generated code characteristics must be done here,   */
+/* as appropriate, before any system header file is included. It is */
+/* also possible to have them defined in the config file included   */
+/* before this point. As a result of all this we frown inclusion of */
+/* system header files in our config files, avoid this at any cost. */
+/* ================================================================ */
+
+/*
+ * AIX 4.3 and newer needs _THREAD_SAFE defined to build
+ * proper reentrant code. Others may also need it.
+ */
+
+#ifdef NEED_THREAD_SAFE
+#  ifndef _THREAD_SAFE
+#    define _THREAD_SAFE
+#  endif
+#endif
+
+/*
+ * Tru64 needs _REENTRANT set for a few function prototypes and
+ * things to appear in the system header files. Unixware needs it
+ * to build proper reentrant code. Others may also need it.
+ */
+
+#ifdef NEED_REENTRANT
+#  ifndef _REENTRANT
+#    define _REENTRANT
+#  endif
+#endif
+
+/* Solaris needs this to get a POSIX-conformant getpwuid_r */
+#if defined(sun) || defined(__sun)
+#  ifndef _POSIX_PTHREAD_SEMANTICS
+#    define _POSIX_PTHREAD_SEMANTICS 1
+#  endif
+#endif
+
+/* ================================================================ */
+/*  If you need to include a system header file for your platform,  */
+/*  please, do it beyond the point further indicated in this file.  */
+/* ================================================================ */
+
+/*
+ * libcurl's external interface definitions are also used internally,
+ * and might also include required system header files to define them.
+ */
+
+#include <curl/curlbuild.h>
+
+/*
+ * Compile time sanity checks must also be done when building the library.
+ */
+
+#include <curl/curlrules.h>
+
+/*
+ * Ensure that no one is using the old SIZEOF_CURL_OFF_T macro
+ */
+
+#ifdef SIZEOF_CURL_OFF_T
+#  error "SIZEOF_CURL_OFF_T shall not be defined!"
+   Error Compilation_aborted_SIZEOF_CURL_OFF_T_shall_not_be_defined
+#endif
+
+/*
+ * Disable other protocols when http is the only one desired.
+ */
+
+#ifdef HTTP_ONLY
+#  ifndef CURL_DISABLE_TFTP
+#    define CURL_DISABLE_TFTP
+#  endif
+#  ifndef CURL_DISABLE_FTP
+#    define CURL_DISABLE_FTP
+#  endif
+#  ifndef CURL_DISABLE_LDAP
+#    define CURL_DISABLE_LDAP
+#  endif
+#  ifndef CURL_DISABLE_TELNET
+#    define CURL_DISABLE_TELNET
+#  endif
+#  ifndef CURL_DISABLE_DICT
+#    define CURL_DISABLE_DICT
+#  endif
+#  ifndef CURL_DISABLE_FILE
+#    define CURL_DISABLE_FILE
+#  endif
+#  ifndef CURL_DISABLE_RTSP
+#    define CURL_DISABLE_RTSP
+#  endif
+#  ifndef CURL_DISABLE_POP3
+#    define CURL_DISABLE_POP3
+#  endif
+#  ifndef CURL_DISABLE_IMAP
+#    define CURL_DISABLE_IMAP
+#  endif
+#  ifndef CURL_DISABLE_SMTP
+#    define CURL_DISABLE_SMTP
+#  endif
+#  ifndef CURL_DISABLE_RTMP
+#    define CURL_DISABLE_RTMP
+#  endif
+#  ifndef CURL_DISABLE_GOPHER
+#    define CURL_DISABLE_GOPHER
+#  endif
+#  ifndef CURL_DISABLE_SMB
+#    define CURL_DISABLE_SMB
+#  endif
+#endif
+
+/*
+ * When http is disabled rtsp is not supported.
+ */
+
+#if defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_RTSP)
+#  define CURL_DISABLE_RTSP
+#endif
+
+/* ================================================================ */
+/* No system header file shall be included in this file before this */
+/* point. The only allowed ones are those included from curlbuild.h */
+/* ================================================================ */
+
+/*
+ * OS/400 setup file includes some system headers.
+ */
+
+#ifdef __OS400__
+#  include "setup-os400.h"
+#endif
+
+/*
+ * VMS setup file includes some system headers.
+ */
+
+#ifdef __VMS
+#  include "setup-vms.h"
+#endif
+
+/*
+ * Include header files for windows builds before redefining anything.
+ * Use this preprocessor block only to include or exclude windows.h,
+ * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
+ * to any other further and independent block.  Under Cygwin things work
+ * just as under linux (e.g. <sys/socket.h>) and the winsock headers should
+ * never be included when __CYGWIN__ is defined.  configure script takes
+ * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
+ * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
+ */
+
+#ifdef HAVE_WINDOWS_H
+#  if defined(UNICODE) && !defined(_UNICODE)
+#    define _UNICODE
+#  endif
+#  if defined(_UNICODE) && !defined(UNICODE)
+#    define UNICODE
+#  endif
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif
+#  include <windows.h>
+#  ifdef HAVE_WINSOCK2_H
+#    include <winsock2.h>
+#    ifdef HAVE_WS2TCPIP_H
+#      include <ws2tcpip.h>
+#    endif
+#  else
+#    ifdef HAVE_WINSOCK_H
+#      include <winsock.h>
+#    endif
+#  endif
+#  include <tchar.h>
+#  ifdef UNICODE
+     typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
+#  endif
+#endif
+
+/*
+ * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
+ * define USE_WINSOCK to 1 if we have and use WINSOCK  API, else
+ * undefine USE_WINSOCK.
+ */
+
+#undef USE_WINSOCK
+
+#ifdef HAVE_WINSOCK2_H
+#  define USE_WINSOCK 2
+#else
+#  ifdef HAVE_WINSOCK_H
+#    define USE_WINSOCK 1
+#  endif
+#endif
+
+#ifdef USE_LWIPSOCK
+#  include <lwip/init.h>
+#  include <lwip/sockets.h>
+#  include <lwip/netdb.h>
+#endif
+
+#ifdef HAVE_EXTRA_STRICMP_H
+#  include <extra/stricmp.h>
+#endif
+
+#ifdef HAVE_EXTRA_STRDUP_H
+#  include <extra/strdup.h>
+#endif
+
+#ifdef TPF
+#  include <strings.h>    /* for bzero, strcasecmp, and strncasecmp */
+#  include <string.h>     /* for strcpy and strlen */
+#  include <stdlib.h>     /* for rand and srand */
+#  include <sys/socket.h> /* for select and ioctl*/
+#  include <netdb.h>      /* for in_addr_t definition */
+#  include <tpf/sysapi.h> /* for tpf_process_signals */
+   /* change which select is used for libcurl */
+#  define select(a,b,c,d,e) tpf_select_libcurl(a,b,c,d,e)
+#endif
+
+#ifdef __VXWORKS__
+#  include <sockLib.h>    /* for generic BSD socket functions */
+#  include <ioLib.h>      /* for basic I/O interface functions */
+#endif
+
+#ifdef __AMIGA__
+#  ifndef __ixemul__
+#    include <exec/types.h>
+#    include <exec/execbase.h>
+#    include <proto/exec.h>
+#    include <proto/dos.h>
+#    define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
+#  endif
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#ifdef __TANDEM /* for nsr-tandem-nsk systems */
+#include <floss.h>
+#endif
+
+#ifndef STDC_HEADERS /* no standard C headers! */
+#include <curl/stdcheaders.h>
+#endif
+
+#ifdef __POCC__
+#  include <sys/types.h>
+#  include <unistd.h>
+#  define sys_nerr EILSEQ
+#endif
+
+/*
+ * Salford-C kludge section (mostly borrowed from wxWidgets).
+ */
+#ifdef __SALFORDC__
+  #pragma suppress 353             /* Possible nested comments */
+  #pragma suppress 593             /* Define not used */
+  #pragma suppress 61              /* enum has no name */
+  #pragma suppress 106             /* unnamed, unused parameter */
+  #include <clib.h>
+#endif
+
+/*
+ * Large file (>2Gb) support using WIN32 functions.
+ */
+
+#ifdef USE_WIN32_LARGE_FILES
+#  include <io.h>
+#  include <sys/types.h>
+#  include <sys/stat.h>
+#  undef  lseek
+#  define lseek(fdes,offset,whence)  _lseeki64(fdes, offset, whence)
+#  undef  fstat
+#  define fstat(fdes,stp)            _fstati64(fdes, stp)
+#  undef  stat
+#  define stat(fname,stp)            _stati64(fname, stp)
+#  define struct_stat                struct _stati64
+#  define LSEEK_ERROR                (__int64)-1
+#endif
+
+/*
+ * Small file (<2Gb) support using WIN32 functions.
+ */
+
+#ifdef USE_WIN32_SMALL_FILES
+#  include <io.h>
+#  include <sys/types.h>
+#  include <sys/stat.h>
+#  ifndef _WIN32_WCE
+#    undef  lseek
+#    define lseek(fdes,offset,whence)  _lseek(fdes, (long)offset, whence)
+#    define fstat(fdes,stp)            _fstat(fdes, stp)
+#    define stat(fname,stp)            _stat(fname, stp)
+#    define struct_stat                struct _stat
+#  endif
+#  define LSEEK_ERROR                (long)-1
+#endif
+
+#ifndef struct_stat
+#  define struct_stat struct stat
+#endif
+
+#ifndef LSEEK_ERROR
+#  define LSEEK_ERROR (off_t)-1
+#endif
+
+/*
+ * Default sizeof(off_t) in case it hasn't been defined in config file.
+ */
+
+#ifndef SIZEOF_OFF_T
+#  if defined(__VMS) && !defined(__VAX)
+#    if defined(_LARGEFILE)
+#      define SIZEOF_OFF_T 8
+#    endif
+#  elif defined(__OS400__) && defined(__ILEC400__)
+#    if defined(_LARGE_FILES)
+#      define SIZEOF_OFF_T 8
+#    endif
+#  elif defined(__MVS__) && defined(__IBMC__)
+#    if defined(_LP64) || defined(_LARGE_FILES)
+#      define SIZEOF_OFF_T 8
+#    endif
+#  elif defined(__370__) && defined(__IBMC__)
+#    if defined(_LP64) || defined(_LARGE_FILES)
+#      define SIZEOF_OFF_T 8
+#    endif
+#  endif
+#  ifndef SIZEOF_OFF_T
+#    define SIZEOF_OFF_T 4
+#  endif
+#endif
+
+/*
+ * Arg 2 type for gethostname in case it hasn't been defined in config file.
+ */
+
+#ifndef GETHOSTNAME_TYPE_ARG2
+#  ifdef USE_WINSOCK
+#    define GETHOSTNAME_TYPE_ARG2 int
+#  else
+#    define GETHOSTNAME_TYPE_ARG2 size_t
+#  endif
+#endif
+
+/* Below we define some functions. They should
+
+   4. set the SIGALRM signal timeout
+   5. set dir/file naming defines
+   */
+
+#ifdef WIN32
+
+#  define DIR_CHAR      "\\"
+#  define DOT_CHAR      "_"
+
+#else /* WIN32 */
+
+#  ifdef MSDOS  /* Watt-32 */
+
+#    include <sys/ioctl.h>
+#    define select(n,r,w,x,t) select_s(n,r,w,x,t)
+#    define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z))
+#    include <tcp.h>
+#    ifdef word
+#      undef word
+#    endif
+#    ifdef byte
+#      undef byte
+#    endif
+
+#  endif /* MSDOS */
+
+#  ifdef __minix
+     /* Minix 3 versions up to at least 3.1.3 are missing these prototypes */
+     extern char * strtok_r(char *s, const char *delim, char **last);
+     extern struct tm * gmtime_r(const time_t * const timep, struct tm *tmp);
+#  endif
+
+#  define DIR_CHAR      "/"
+#  ifndef DOT_CHAR
+#    define DOT_CHAR      "."
+#  endif
+
+#  ifdef MSDOS
+#    undef DOT_CHAR
+#    define DOT_CHAR      "_"
+#  endif
+
+#  ifndef fileno /* sunos 4 have this as a macro! */
+     int fileno( FILE *stream);
+#  endif
+
+#endif /* WIN32 */
+
+/*
+ * msvc 6.0 requires PSDK in order to have INET6_ADDRSTRLEN
+ * defined in ws2tcpip.h as well as to provide IPv6 support.
+ * Does not apply if lwIP is used.
+ */
+
+#if defined(_MSC_VER) && !defined(__POCC__) && !defined(USE_LWIPSOCK)
+#  if !defined(HAVE_WS2TCPIP_H) || \
+     ((_MSC_VER < 1300) && !defined(INET6_ADDRSTRLEN))
+#    undef HAVE_GETADDRINFO_THREADSAFE
+#    undef HAVE_FREEADDRINFO
+#    undef HAVE_GETADDRINFO
+#    undef HAVE_GETNAMEINFO
+#    undef ENABLE_IPV6
+#  endif
+#endif
+
+/* ---------------------------------------------------------------- */
+/*             resolver specialty compile-time defines              */
+/*         CURLRES_* defines to use in the host*.c sources          */
+/* ---------------------------------------------------------------- */
+
+/*
+ * lcc-win32 doesn't have _beginthreadex(), lacks threads support.
+ */
+
+#if defined(__LCC__) && defined(WIN32)
+#  undef USE_THREADS_POSIX
+#  undef USE_THREADS_WIN32
+#endif
+
+/*
+ * MSVC threads support requires a multi-threaded runtime library.
+ * _beginthreadex() is not available in single-threaded ones.
+ */
+
+#if defined(_MSC_VER) && !defined(__POCC__) && !defined(_MT)
+#  undef USE_THREADS_POSIX
+#  undef USE_THREADS_WIN32
+#endif
+
+/*
+ * Mutually exclusive CURLRES_* definitions.
+ */
+
+#ifdef USE_ARES
+#  define CURLRES_ASYNCH
+#  define CURLRES_ARES
+/* now undef the stock libc functions just to avoid them being used */
+#  undef HAVE_GETADDRINFO
+#  undef HAVE_FREEADDRINFO
+#  undef HAVE_GETHOSTBYNAME
+#elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+#  define CURLRES_ASYNCH
+#  define CURLRES_THREADED
+#else
+#  define CURLRES_SYNCH
+#endif
+
+#ifdef ENABLE_IPV6
+#  define CURLRES_IPV6
+#else
+#  define CURLRES_IPV4
+#endif
+
+/* ---------------------------------------------------------------- */
+
+/*
+ * When using WINSOCK, TELNET protocol requires WINSOCK2 API.
+ */
+
+#if defined(USE_WINSOCK) && (USE_WINSOCK != 2)
+#  define CURL_DISABLE_TELNET 1
+#endif
+
+/*
+ * msvc 6.0 does not have struct sockaddr_storage and
+ * does not define IPPROTO_ESP in winsock2.h. But both
+ * are available if PSDK is properly installed.
+ */
+
+#if defined(_MSC_VER) && !defined(__POCC__)
+#  if !defined(HAVE_WINSOCK2_H) || ((_MSC_VER < 1300) && !defined(IPPROTO_ESP))
+#    undef HAVE_STRUCT_SOCKADDR_STORAGE
+#  endif
+#endif
+
+/*
+ * Intentionally fail to build when using msvc 6.0 without PSDK installed.
+ * The brave of heart can circumvent this, defining ALLOW_MSVC6_WITHOUT_PSDK
+ * in lib/config-win32.h although absolutely discouraged and unsupported.
+ */
+
+#if defined(_MSC_VER) && !defined(__POCC__)
+#  if !defined(HAVE_WINDOWS_H) || ((_MSC_VER < 1300) && !defined(_FILETIME_))
+#    if !defined(ALLOW_MSVC6_WITHOUT_PSDK)
+#      error MSVC 6.0 requires "February 2003 Platform SDK" a.k.a. \
+             "Windows Server 2003 PSDK"
+#    else
+#      define CURL_DISABLE_LDAP 1
+#    endif
+#  endif
+#endif
+
+#ifdef NETWARE
+int netware_init(void);
+#ifndef __NOVELL_LIBC__
+#include <sys/bsdskt.h>
+#include <sys/timeval.h>
+#endif
+#endif
+
+#if defined(HAVE_LIBIDN) && defined(HAVE_TLD_H)
+/* The lib was present and the tld.h header (which is missing in libidn 0.3.X
+   but we only work with libidn 0.4.1 or later) */
+#define USE_LIBIDN
+#endif
+
+#ifndef SIZEOF_TIME_T
+/* assume default size of time_t to be 32 bit */
+#define SIZEOF_TIME_T 4
+#endif
+
+#define LIBIDN_REQUIRED_VERSION "0.4.1"
+
+#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
+    defined(USE_POLARSSL) || defined(USE_AXTLS) || defined(USE_MBEDTLS) || \
+    defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
+    defined(USE_DARWINSSL) || defined(USE_GSKIT)
+#define USE_SSL    /* SSL support has been enabled */
+#endif
+
+/* Single point where USE_SPNEGO definition might be defined */
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
+    (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
+#define USE_SPNEGO
+#endif
+
+/* Single point where USE_KERBEROS5 definition might be defined */
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
+    (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
+#define USE_KERBEROS5
+#endif
+
+/* Single point where USE_NTLM definition might be defined */
+#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \
+    defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) || \
+    defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
+
+#ifdef HAVE_BORINGSSL /* BoringSSL is not NTLM capable */
+#undef USE_NTLM
+#else
+#define USE_NTLM
+#endif
+#endif
+#endif
+
+/* non-configure builds may define CURL_WANTS_CA_BUNDLE_ENV */
+#if defined(CURL_WANTS_CA_BUNDLE_ENV) && !defined(CURL_CA_BUNDLE)
+#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")
+#endif
+
+/*
+ * Provide a mechanism to silence picky compilers, such as gcc 4.6+.
+ * Parameters should of course normally not be unused, but for example when
+ * we have multiple implementations of the same interface it may happen.
+ */
+
+#if defined(__GNUC__) && ((__GNUC__ >= 3) || \
+  ((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7)))
+#  define UNUSED_PARAM __attribute__((__unused__))
+#  define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#  define UNUSED_PARAM /*NOTHING*/
+#  define WARN_UNUSED_RESULT
+#endif
+
+/*
+ * Include macros and defines that should only be processed once.
+ */
+
+#ifndef HEADER_CURL_SETUP_ONCE_H
+#include "curl_setup_once.h"
+#endif
+
+/*
+ * Definition of our NOP statement Object-like macro
+ */
+
+#ifndef Curl_nop_stmt
+#  define Curl_nop_stmt do { } WHILE_FALSE
+#endif
+
+/*
+ * Ensure that Winsock and lwIP TCP/IP stacks are not mixed.
+ */
+
+#if defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)
+#  if defined(SOCKET) || \
+     defined(USE_WINSOCK) || \
+     defined(HAVE_WINSOCK_H) || \
+     defined(HAVE_WINSOCK2_H) || \
+     defined(HAVE_WS2TCPIP_H)
+#    error "Winsock and lwIP TCP/IP stack definitions shall not coexist!"
+#  endif
+#endif
+
+/*
+ * Portable symbolic names for Winsock shutdown() mode flags.
+ */
+
+#ifdef USE_WINSOCK
+#  define SHUT_RD   0x00
+#  define SHUT_WR   0x01
+#  define SHUT_RDWR 0x02
+#endif
+
+/* Define S_ISREG if not defined by system headers, f.e. MSVC */
+#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+
+/* Define S_ISDIR if not defined by system headers, f.e. MSVC */
+#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+/* In Windows the default file mode is text but an application can override it.
+Therefore we specify it explicitly. https://github.com/curl/curl/pull/258
+*/
+#if defined(WIN32) || defined(MSDOS)
+#define FOPEN_READTEXT "rt"
+#define FOPEN_WRITETEXT "wt"
+#elif defined(__CYGWIN__)
+/* Cygwin has specific behavior we need to address when WIN32 is not defined.
+https://cygwin.com/cygwin-ug-net/using-textbinary.html
+For write we want our output to have line endings of LF and be compatible with
+other Cygwin utilities. For read we want to handle input that may have line
+endings either CRLF or LF so 't' is appropriate.
+*/
+#define FOPEN_READTEXT "rt"
+#define FOPEN_WRITETEXT "w"
+#else
+#define FOPEN_READTEXT "r"
+#define FOPEN_WRITETEXT "w"
+#endif
+
+#endif /* HEADER_CURL_SETUP_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_setup_once.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_setup_once.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_setup_once.h	(revision 164)
@@ -0,0 +1,553 @@
+#ifndef HEADER_CURL_SETUP_ONCE_H
+#define HEADER_CURL_SETUP_ONCE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+
+/*
+ * Inclusion of common header files.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef NEED_MALLOC_H
+#include <malloc.h>
+#endif
+
+#ifdef NEED_MEMORY_H
+#include <memory.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <time.h>
+#endif
+#else
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#endif
+
+#ifdef WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+#if defined(HAVE_STDBOOL_H) && defined(HAVE_BOOL_T)
+#include <stdbool.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef __hpux
+#  if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
+#    ifdef _APP32_64BIT_OFF_T
+#      define OLD_APP32_64BIT_OFF_T _APP32_64BIT_OFF_T
+#      undef _APP32_64BIT_OFF_T
+#    else
+#      undef OLD_APP32_64BIT_OFF_T
+#    endif
+#  endif
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef __hpux
+#  if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
+#    ifdef OLD_APP32_64BIT_OFF_T
+#      define _APP32_64BIT_OFF_T OLD_APP32_64BIT_OFF_T
+#      undef OLD_APP32_64BIT_OFF_T
+#    endif
+#  endif
+#endif
+
+
+/*
+ * Definition of timeval struct for platforms that don't have it.
+ */
+
+#ifndef HAVE_STRUCT_TIMEVAL
+struct timeval {
+ long tv_sec;
+ long tv_usec;
+};
+#endif
+
+
+/*
+ * If we have the MSG_NOSIGNAL define, make sure we use
+ * it as the fourth argument of function send()
+ */
+
+#ifdef HAVE_MSG_NOSIGNAL
+#define SEND_4TH_ARG MSG_NOSIGNAL
+#else
+#define SEND_4TH_ARG 0
+#endif
+
+
+#if defined(__minix)
+/* Minix doesn't support recv on TCP sockets */
+#define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \
+                                   (RECV_TYPE_ARG2)(y), \
+                                   (RECV_TYPE_ARG3)(z))
+
+#elif defined(HAVE_RECV)
+/*
+ * The definitions for the return type and arguments types
+ * of functions recv() and send() belong and come from the
+ * configuration file. Do not define them in any other place.
+ *
+ * HAVE_RECV is defined if you have a function named recv()
+ * which is used to read incoming data from sockets. If your
+ * function has another name then don't define HAVE_RECV.
+ *
+ * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2,
+ * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also
+ * be defined.
+ *
+ * HAVE_SEND is defined if you have a function named send()
+ * which is used to write outgoing data on a connected socket.
+ * If yours has another name then don't define HAVE_SEND.
+ *
+ * If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2,
+ * SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and
+ * SEND_TYPE_RETV must also be defined.
+ */
+
+#if !defined(RECV_TYPE_ARG1) || \
+    !defined(RECV_TYPE_ARG2) || \
+    !defined(RECV_TYPE_ARG3) || \
+    !defined(RECV_TYPE_ARG4) || \
+    !defined(RECV_TYPE_RETV)
+  /* */
+  Error Missing_definition_of_return_and_arguments_types_of_recv
+  /* */
+#else
+#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
+                                   (RECV_TYPE_ARG2)(y), \
+                                   (RECV_TYPE_ARG3)(z), \
+                                   (RECV_TYPE_ARG4)(0))
+#endif
+#else /* HAVE_RECV */
+#ifndef sread
+  /* */
+  Error Missing_definition_of_macro_sread
+  /* */
+#endif
+#endif /* HAVE_RECV */
+
+
+#if defined(__minix)
+/* Minix doesn't support send on TCP sockets */
+#define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \
+                                    (SEND_TYPE_ARG2)(y), \
+                                    (SEND_TYPE_ARG3)(z))
+
+#elif defined(HAVE_SEND)
+#if !defined(SEND_TYPE_ARG1) || \
+    !defined(SEND_QUAL_ARG2) || \
+    !defined(SEND_TYPE_ARG2) || \
+    !defined(SEND_TYPE_ARG3) || \
+    !defined(SEND_TYPE_ARG4) || \
+    !defined(SEND_TYPE_RETV)
+  /* */
+  Error Missing_definition_of_return_and_arguments_types_of_send
+  /* */
+#else
+#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
+                                    (SEND_TYPE_ARG2)(y), \
+                                    (SEND_TYPE_ARG3)(z), \
+                                    (SEND_TYPE_ARG4)(SEND_4TH_ARG))
+#endif
+#else /* HAVE_SEND */
+#ifndef swrite
+  /* */
+  Error Missing_definition_of_macro_swrite
+  /* */
+#endif
+#endif /* HAVE_SEND */
+
+
+#if 0
+#if defined(HAVE_RECVFROM)
+/*
+ * Currently recvfrom is only used on udp sockets.
+ */
+#if !defined(RECVFROM_TYPE_ARG1) || \
+    !defined(RECVFROM_TYPE_ARG2) || \
+    !defined(RECVFROM_TYPE_ARG3) || \
+    !defined(RECVFROM_TYPE_ARG4) || \
+    !defined(RECVFROM_TYPE_ARG5) || \
+    !defined(RECVFROM_TYPE_ARG6) || \
+    !defined(RECVFROM_TYPE_RETV)
+  /* */
+  Error Missing_definition_of_return_and_arguments_types_of_recvfrom
+  /* */
+#else
+#define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1)  (s),  \
+                                                 (RECVFROM_TYPE_ARG2 *)(b),  \
+                                                 (RECVFROM_TYPE_ARG3)  (bl), \
+                                                 (RECVFROM_TYPE_ARG4)  (0),  \
+                                                 (RECVFROM_TYPE_ARG5 *)(f),  \
+                                                 (RECVFROM_TYPE_ARG6 *)(fl))
+#endif
+#else /* HAVE_RECVFROM */
+#ifndef sreadfrom
+  /* */
+  Error Missing_definition_of_macro_sreadfrom
+  /* */
+#endif
+#endif /* HAVE_RECVFROM */
+
+
+#ifdef RECVFROM_TYPE_ARG6_IS_VOID
+#  define RECVFROM_ARG6_T int
+#else
+#  define RECVFROM_ARG6_T RECVFROM_TYPE_ARG6
+#endif
+#endif /* if 0 */
+
+
+/*
+ * Function-like macro definition used to close a socket.
+ */
+
+#if defined(HAVE_CLOSESOCKET)
+#  define sclose(x)  closesocket((x))
+#elif defined(HAVE_CLOSESOCKET_CAMEL)
+#  define sclose(x)  CloseSocket((x))
+#elif defined(HAVE_CLOSE_S)
+#  define sclose(x)  close_s((x))
+#elif defined(USE_LWIPSOCK)
+#  define sclose(x)  lwip_close((x))
+#else
+#  define sclose(x)  close((x))
+#endif
+
+/*
+ * Stack-independent version of fcntl() on sockets:
+ */
+#if defined(USE_LWIPSOCK)
+#  define sfcntl  lwip_fcntl
+#else
+#  define sfcntl  fcntl
+#endif
+
+/*
+ * Uppercase macro versions of ANSI/ISO is*() functions/macros which
+ * avoid negative number inputs with argument byte codes > 127.
+ */
+
+#define ISSPACE(x)  (isspace((int)  ((unsigned char)x)))
+#define ISDIGIT(x)  (isdigit((int)  ((unsigned char)x)))
+#define ISALNUM(x)  (isalnum((int)  ((unsigned char)x)))
+#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
+#define ISGRAPH(x)  (isgraph((int)  ((unsigned char)x)))
+#define ISALPHA(x)  (isalpha((int)  ((unsigned char)x)))
+#define ISPRINT(x)  (isprint((int)  ((unsigned char)x)))
+#define ISUPPER(x)  (isupper((int)  ((unsigned char)x)))
+#define ISLOWER(x)  (islower((int)  ((unsigned char)x)))
+#define ISASCII(x)  (isascii((int)  ((unsigned char)x)))
+
+#define ISBLANK(x)  (int)((((unsigned char)x) == ' ') || \
+                          (((unsigned char)x) == '\t'))
+
+#define TOLOWER(x)  (tolower((int)  ((unsigned char)x)))
+
+
+/*
+ * 'bool' stuff compatible with HP-UX headers.
+ */
+
+#if defined(__hpux) && !defined(HAVE_BOOL_T)
+   typedef int bool;
+#  define false 0
+#  define true 1
+#  define HAVE_BOOL_T
+#endif
+
+
+/*
+ * 'bool' exists on platforms with <stdbool.h>, i.e. C99 platforms.
+ * On non-C99 platforms there's no bool, so define an enum for that.
+ * On C99 platforms 'false' and 'true' also exist. Enum uses a
+ * global namespace though, so use bool_false and bool_true.
+ */
+
+#ifndef HAVE_BOOL_T
+  typedef enum {
+      bool_false = 0,
+      bool_true  = 1
+  } bool;
+
+/*
+ * Use a define to let 'true' and 'false' use those enums.  There
+ * are currently no use of true and false in libcurl proper, but
+ * there are some in the examples. This will cater for any later
+ * code happening to use true and false.
+ */
+#  define false bool_false
+#  define true  bool_true
+#  define HAVE_BOOL_T
+#endif
+
+
+/*
+ * Redefine TRUE and FALSE too, to catch current use. With this
+ * change, 'bool found = 1' will give a warning on MIPSPro, but
+ * 'bool found = TRUE' will not. Change tested on IRIX/MIPSPro,
+ * AIX 5.1/Xlc, Tru64 5.1/cc, w/make test too.
+ */
+
+#ifndef TRUE
+#define TRUE true
+#endif
+#ifndef FALSE
+#define FALSE false
+#endif
+
+
+/*
+ * Macro WHILE_FALSE may be used to build single-iteration do-while loops,
+ * avoiding compiler warnings. Mostly intended for other macro definitions.
+ */
+
+#define WHILE_FALSE  while(0)
+
+#if defined(_MSC_VER) && !defined(__POCC__)
+#  undef WHILE_FALSE
+#  if (_MSC_VER < 1500)
+#    define WHILE_FALSE  while(1, 0)
+#  else
+#    define WHILE_FALSE \
+__pragma(warning(push)) \
+__pragma(warning(disable:4127)) \
+while(0) \
+__pragma(warning(pop))
+#  endif
+#endif
+
+
+/*
+ * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
+ */
+
+#ifndef HAVE_SIG_ATOMIC_T
+typedef int sig_atomic_t;
+#define HAVE_SIG_ATOMIC_T
+#endif
+
+
+/*
+ * Convenience SIG_ATOMIC_T definition
+ */
+
+#ifdef HAVE_SIG_ATOMIC_T_VOLATILE
+#define SIG_ATOMIC_T static sig_atomic_t
+#else
+#define SIG_ATOMIC_T static volatile sig_atomic_t
+#endif
+
+
+/*
+ * Default return type for signal handlers.
+ */
+
+#ifndef RETSIGTYPE
+#define RETSIGTYPE void
+#endif
+
+
+/*
+ * Macro used to include code only in debug builds.
+ */
+
+#ifdef DEBUGBUILD
+#define DEBUGF(x) x
+#else
+#define DEBUGF(x) do { } WHILE_FALSE
+#endif
+
+
+/*
+ * Macro used to include assertion code only in debug builds.
+ */
+
+#if defined(DEBUGBUILD) && defined(HAVE_ASSERT_H)
+#define DEBUGASSERT(x) assert(x)
+#else
+#define DEBUGASSERT(x) do { } WHILE_FALSE
+#endif
+
+
+/*
+ * Macro SOCKERRNO / SET_SOCKERRNO() returns / sets the *socket-related* errno
+ * (or equivalent) on this platform to hide platform details to code using it.
+ */
+
+#ifdef USE_WINSOCK
+#define SOCKERRNO         ((int)WSAGetLastError())
+#define SET_SOCKERRNO(x)  (WSASetLastError((int)(x)))
+#else
+#define SOCKERRNO         (errno)
+#define SET_SOCKERRNO(x)  (errno = (x))
+#endif
+
+
+/*
+ * Macro ERRNO / SET_ERRNO() returns / sets the NOT *socket-related* errno
+ * (or equivalent) on this platform to hide platform details to code using it.
+ */
+
+#if defined(WIN32) && !defined(USE_LWIPSOCK)
+#define ERRNO         ((int)GetLastError())
+#define SET_ERRNO(x)  (SetLastError((DWORD)(x)))
+#else
+#ifndef ERRNO
+#define ERRNO         (errno)
+#endif // !ERRNO
+#define SET_ERRNO(x)  (errno = (x))
+#endif
+
+
+/*
+ * Portable error number symbolic names defined to Winsock error codes.
+ */
+
+#ifdef USE_WINSOCK
+#undef  EBADF            /* override definition in errno.h */
+#define EBADF            WSAEBADF
+#undef  EINTR            /* override definition in errno.h */
+#define EINTR            WSAEINTR
+#undef  EINVAL           /* override definition in errno.h */
+#define EINVAL           WSAEINVAL
+#undef  EWOULDBLOCK      /* override definition in errno.h */
+#define EWOULDBLOCK      WSAEWOULDBLOCK
+#undef  EINPROGRESS      /* override definition in errno.h */
+#define EINPROGRESS      WSAEINPROGRESS
+#undef  EALREADY         /* override definition in errno.h */
+#define EALREADY         WSAEALREADY
+#undef  ENOTSOCK         /* override definition in errno.h */
+#define ENOTSOCK         WSAENOTSOCK
+#undef  EDESTADDRREQ     /* override definition in errno.h */
+#define EDESTADDRREQ     WSAEDESTADDRREQ
+#undef  EMSGSIZE         /* override definition in errno.h */
+#define EMSGSIZE         WSAEMSGSIZE
+#undef  EPROTOTYPE       /* override definition in errno.h */
+#define EPROTOTYPE       WSAEPROTOTYPE
+#undef  ENOPROTOOPT      /* override definition in errno.h */
+#define ENOPROTOOPT      WSAENOPROTOOPT
+#undef  EPROTONOSUPPORT  /* override definition in errno.h */
+#define EPROTONOSUPPORT  WSAEPROTONOSUPPORT
+#define ESOCKTNOSUPPORT  WSAESOCKTNOSUPPORT
+#undef  EOPNOTSUPP       /* override definition in errno.h */
+#define EOPNOTSUPP       WSAEOPNOTSUPP
+#define EPFNOSUPPORT     WSAEPFNOSUPPORT
+#undef  EAFNOSUPPORT     /* override definition in errno.h */
+#define EAFNOSUPPORT     WSAEAFNOSUPPORT
+#undef  EADDRINUSE       /* override definition in errno.h */
+#define EADDRINUSE       WSAEADDRINUSE
+#undef  EADDRNOTAVAIL    /* override definition in errno.h */
+#define EADDRNOTAVAIL    WSAEADDRNOTAVAIL
+#undef  ENETDOWN         /* override definition in errno.h */
+#define ENETDOWN         WSAENETDOWN
+#undef  ENETUNREACH      /* override definition in errno.h */
+#define ENETUNREACH      WSAENETUNREACH
+#undef  ENETRESET        /* override definition in errno.h */
+#define ENETRESET        WSAENETRESET
+#undef  ECONNABORTED     /* override definition in errno.h */
+#define ECONNABORTED     WSAECONNABORTED
+#undef  ECONNRESET       /* override definition in errno.h */
+#define ECONNRESET       WSAECONNRESET
+#undef  ENOBUFS          /* override definition in errno.h */
+#define ENOBUFS          WSAENOBUFS
+#undef  EISCONN          /* override definition in errno.h */
+#define EISCONN          WSAEISCONN
+#undef  ENOTCONN         /* override definition in errno.h */
+#define ENOTCONN         WSAENOTCONN
+#define ESHUTDOWN        WSAESHUTDOWN
+#define ETOOMANYREFS     WSAETOOMANYREFS
+#undef  ETIMEDOUT        /* override definition in errno.h */
+#define ETIMEDOUT        WSAETIMEDOUT
+#undef  ECONNREFUSED     /* override definition in errno.h */
+#define ECONNREFUSED     WSAECONNREFUSED
+#undef  ELOOP            /* override definition in errno.h */
+#define ELOOP            WSAELOOP
+#ifndef ENAMETOOLONG     /* possible previous definition in errno.h */
+#define ENAMETOOLONG     WSAENAMETOOLONG
+#endif
+#define EHOSTDOWN        WSAEHOSTDOWN
+#undef  EHOSTUNREACH     /* override definition in errno.h */
+#define EHOSTUNREACH     WSAEHOSTUNREACH
+#ifndef ENOTEMPTY        /* possible previous definition in errno.h */
+#define ENOTEMPTY        WSAENOTEMPTY
+#endif
+#define EPROCLIM         WSAEPROCLIM
+#define EUSERS           WSAEUSERS
+#define EDQUOT           WSAEDQUOT
+#define ESTALE           WSAESTALE
+#define EREMOTE          WSAEREMOTE
+#endif
+
+/*
+ * Macro argv_item_t hides platform details to code using it.
+ */
+
+#ifdef __VMS
+#define argv_item_t  __char_ptr32
+#else
+#define argv_item_t  char *
+#endif
+
+
+/*
+ * We use this ZERO_NULL to avoid picky compiler warnings,
+ * when assigning a NULL pointer to a function pointer var.
+ */
+
+#define ZERO_NULL 0
+
+
+#endif /* HEADER_CURL_SETUP_ONCE_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_sspi.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_sspi.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_sspi.c	(revision 164)
@@ -0,0 +1,257 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_WINDOWS_SSPI
+
+#include <curl/curl.h>
+#include "curl_sspi.h"
+#include "curl_multibyte.h"
+#include "warnless.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* We use our own typedef here since some headers might lack these */
+typedef PSecurityFunctionTable (APIENTRY *INITSECURITYINTERFACE_FN)(VOID);
+
+/* See definition of SECURITY_ENTRYPOINT in sspi.h */
+#ifdef UNICODE
+#  ifdef _WIN32_WCE
+#    define SECURITYENTRYPOINT L"InitSecurityInterfaceW"
+#  else
+#    define SECURITYENTRYPOINT "InitSecurityInterfaceW"
+#  endif
+#else
+#  define SECURITYENTRYPOINT "InitSecurityInterfaceA"
+#endif
+
+/* Handle of security.dll or secur32.dll, depending on Windows version */
+HMODULE s_hSecDll = NULL;
+
+/* Pointer to SSPI dispatch table */
+PSecurityFunctionTable s_pSecFn = NULL;
+
+/*
+ * Curl_sspi_global_init()
+ *
+ * This is used to load the Security Service Provider Interface (SSPI)
+ * dynamic link library portably across all Windows versions, without
+ * the need to directly link libcurl, nor the application using it, at
+ * build time.
+ *
+ * Once this function has been executed, Windows SSPI functions can be
+ * called through the Security Service Provider Interface dispatch table.
+ */
+CURLcode Curl_sspi_global_init(void)
+{
+  bool securityDll = FALSE;
+  INITSECURITYINTERFACE_FN pInitSecurityInterface;
+
+  /* If security interface is not yet initialized try to do this */
+  if(!s_hSecDll) {
+    /* Security Service Provider Interface (SSPI) functions are located in
+     * security.dll on WinNT 4.0 and in secur32.dll on Win9x. Win2K and XP
+     * have both these DLLs (security.dll forwards calls to secur32.dll) */
+    DWORD majorVersion = 4;
+    DWORD platformId = VER_PLATFORM_WIN32_NT;
+
+#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
+    (_WIN32_WINNT < _WIN32_WINNT_WIN2K)
+    OSVERSIONINFO osver;
+
+    memset(&osver, 0, sizeof(osver));
+    osver.dwOSVersionInfoSize = sizeof(osver);
+
+    /* Find out Windows version */
+    if(!GetVersionEx(&osver))
+      return CURLE_FAILED_INIT;
+
+    /* Verify the major version number == 4 and platform id == WIN_NT */
+    if(osver.dwMajorVersion == majorVersion &&
+       osver.dwPlatformId == platformId)
+      securityDll = TRUE;
+#else
+    ULONGLONG cm;
+    OSVERSIONINFOEX osver;
+
+    memset(&osver, 0, sizeof(osver));
+    osver.dwOSVersionInfoSize = sizeof(osver);
+    osver.dwMajorVersion = majorVersion;
+    osver.dwPlatformId = platformId;
+
+    cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL);
+
+    /* Verify the major version number == 4 and platform id == WIN_NT */
+    if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
+                                  VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR |
+                                  VER_PLATFORMID),
+                         cm))
+      securityDll = TRUE;
+#endif
+
+    /* Load SSPI dll into the address space of the calling process */
+    if(securityDll)
+      s_hSecDll = LoadLibrary(TEXT("security.dll"));
+    else
+      s_hSecDll = LoadLibrary(TEXT("secur32.dll"));
+    if(!s_hSecDll)
+      return CURLE_FAILED_INIT;
+
+    /* Get address of the InitSecurityInterfaceA function from the SSPI dll */
+    pInitSecurityInterface = (INITSECURITYINTERFACE_FN)
+      GetProcAddress(s_hSecDll, SECURITYENTRYPOINT);
+    if(!pInitSecurityInterface)
+      return CURLE_FAILED_INIT;
+
+    /* Get pointer to Security Service Provider Interface dispatch table */
+    s_pSecFn = pInitSecurityInterface();
+    if(!s_pSecFn)
+      return CURLE_FAILED_INIT;
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_sspi_global_cleanup()
+ *
+ * This deinitializes the Security Service Provider Interface from libcurl.
+ */
+
+void Curl_sspi_global_cleanup(void)
+{
+  if(s_hSecDll) {
+    FreeLibrary(s_hSecDll);
+    s_hSecDll = NULL;
+    s_pSecFn = NULL;
+  }
+}
+
+/*
+ * Curl_create_sspi_identity()
+ *
+ * This is used to populate a SSPI identity structure based on the supplied
+ * username and password.
+ *
+ * Parameters:
+ *
+ * userp    [in]     - The user name in the format User or Domain\User.
+ * passdwp  [in]     - The user's password.
+ * identity [in/out] - The identity structure.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
+                                   SEC_WINNT_AUTH_IDENTITY *identity)
+{
+  xcharp_u useranddomain;
+  xcharp_u user, dup_user;
+  xcharp_u domain, dup_domain;
+  xcharp_u passwd, dup_passwd;
+  size_t domlen = 0;
+
+  domain.const_tchar_ptr = TEXT("");
+
+  /* Initialize the identity */
+  memset(identity, 0, sizeof(*identity));
+
+  useranddomain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)userp);
+  if(!useranddomain.tchar_ptr)
+    return CURLE_OUT_OF_MEMORY;
+
+  user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('\\'));
+  if(!user.const_tchar_ptr)
+    user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('/'));
+
+  if(user.tchar_ptr) {
+    domain.tchar_ptr = useranddomain.tchar_ptr;
+    domlen = user.tchar_ptr - useranddomain.tchar_ptr;
+    user.tchar_ptr++;
+  }
+  else {
+    user.tchar_ptr = useranddomain.tchar_ptr;
+    domain.const_tchar_ptr = TEXT("");
+    domlen = 0;
+  }
+
+  /* Setup the identity's user and length */
+  dup_user.tchar_ptr = _tcsdup(user.tchar_ptr);
+  if(!dup_user.tchar_ptr) {
+    Curl_unicodefree(useranddomain.tchar_ptr);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  identity->User = dup_user.tbyte_ptr;
+  identity->UserLength = curlx_uztoul(_tcslen(dup_user.tchar_ptr));
+  dup_user.tchar_ptr = NULL;
+
+  /* Setup the identity's domain and length */
+  dup_domain.tchar_ptr = malloc(sizeof(TCHAR) * (domlen + 1));
+  if(!dup_domain.tchar_ptr) {
+    Curl_unicodefree(useranddomain.tchar_ptr);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  _tcsncpy(dup_domain.tchar_ptr, domain.tchar_ptr, domlen);
+  *(dup_domain.tchar_ptr + domlen) = TEXT('\0');
+  identity->Domain = dup_domain.tbyte_ptr;
+  identity->DomainLength = curlx_uztoul(domlen);
+  dup_domain.tchar_ptr = NULL;
+
+  Curl_unicodefree(useranddomain.tchar_ptr);
+
+  /* Setup the identity's password and length */
+  passwd.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)passwdp);
+  if(!passwd.tchar_ptr)
+    return CURLE_OUT_OF_MEMORY;
+  dup_passwd.tchar_ptr = _tcsdup(passwd.tchar_ptr);
+  if(!dup_passwd.tchar_ptr) {
+    Curl_unicodefree(passwd.tchar_ptr);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  identity->Password = dup_passwd.tbyte_ptr;
+  identity->PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr));
+  dup_passwd.tchar_ptr = NULL;
+
+  Curl_unicodefree(passwd.tchar_ptr);
+
+  /* Setup the identity's flags */
+  identity->Flags = SECFLAG_WINNT_AUTH_IDENTITY;
+
+  return CURLE_OK;
+}
+
+void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity)
+{
+  if(identity) {
+    Curl_safefree(identity->User);
+    Curl_safefree(identity->Password);
+    Curl_safefree(identity->Domain);
+  }
+}
+
+#endif /* USE_WINDOWS_SSPI */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_sspi.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_sspi.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_sspi.h	(revision 164)
@@ -0,0 +1,350 @@
+#ifndef HEADER_CURL_SSPI_H
+#define HEADER_CURL_SSPI_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_WINDOWS_SSPI
+
+#include <curl/curl.h>
+
+/*
+ * When including the following three headers, it is mandatory to define either
+ * SECURITY_WIN32 or SECURITY_KERNEL, indicating who is compiling the code.
+ */
+
+#undef SECURITY_WIN32
+#undef SECURITY_KERNEL
+#define SECURITY_WIN32 1
+#include <security.h>
+#include <sspi.h>
+#include <rpc.h>
+
+CURLcode Curl_sspi_global_init(void);
+void Curl_sspi_global_cleanup(void);
+
+/* This is used to populate the domain in a SSPI identity structure */
+CURLcode Curl_override_sspi_http_realm(const char *chlg,
+                                       SEC_WINNT_AUTH_IDENTITY *identity);
+
+/* This is used to generate an SSPI identity structure */
+CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
+                                   SEC_WINNT_AUTH_IDENTITY *identity);
+
+/* This is used to free an SSPI identity structure */
+void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity);
+
+/* Forward-declaration of global variables defined in curl_sspi.c */
+extern HMODULE s_hSecDll;
+extern PSecurityFunctionTable s_pSecFn;
+
+/* Provide some definitions missing in old headers */
+#define SP_NAME_DIGEST              "WDigest"
+#define SP_NAME_NTLM                "NTLM"
+#define SP_NAME_NEGOTIATE           "Negotiate"
+#define SP_NAME_KERBEROS            "Kerberos"
+
+#ifndef ISC_REQ_USE_HTTP_STYLE
+#define ISC_REQ_USE_HTTP_STYLE                0x01000000
+#endif
+
+#ifndef ISC_RET_REPLAY_DETECT
+#define ISC_RET_REPLAY_DETECT                 0x00000004
+#endif
+
+#ifndef ISC_RET_SEQUENCE_DETECT
+#define ISC_RET_SEQUENCE_DETECT               0x00000008
+#endif
+
+#ifndef ISC_RET_CONFIDENTIALITY
+#define ISC_RET_CONFIDENTIALITY               0x00000010
+#endif
+
+#ifndef ISC_RET_ALLOCATED_MEMORY
+#define ISC_RET_ALLOCATED_MEMORY              0x00000100
+#endif
+
+#ifndef ISC_RET_STREAM
+#define ISC_RET_STREAM                        0x00008000
+#endif
+
+#ifndef SEC_E_INSUFFICIENT_MEMORY
+# define SEC_E_INSUFFICIENT_MEMORY            ((HRESULT)0x80090300L)
+#endif
+#ifndef SEC_E_INVALID_HANDLE
+# define SEC_E_INVALID_HANDLE                 ((HRESULT)0x80090301L)
+#endif
+#ifndef SEC_E_UNSUPPORTED_FUNCTION
+# define SEC_E_UNSUPPORTED_FUNCTION           ((HRESULT)0x80090302L)
+#endif
+#ifndef SEC_E_TARGET_UNKNOWN
+# define SEC_E_TARGET_UNKNOWN                 ((HRESULT)0x80090303L)
+#endif
+#ifndef SEC_E_INTERNAL_ERROR
+# define SEC_E_INTERNAL_ERROR                 ((HRESULT)0x80090304L)
+#endif
+#ifndef SEC_E_SECPKG_NOT_FOUND
+# define SEC_E_SECPKG_NOT_FOUND               ((HRESULT)0x80090305L)
+#endif
+#ifndef SEC_E_NOT_OWNER
+# define SEC_E_NOT_OWNER                      ((HRESULT)0x80090306L)
+#endif
+#ifndef SEC_E_CANNOT_INSTALL
+# define SEC_E_CANNOT_INSTALL                 ((HRESULT)0x80090307L)
+#endif
+#ifndef SEC_E_INVALID_TOKEN
+# define SEC_E_INVALID_TOKEN                  ((HRESULT)0x80090308L)
+#endif
+#ifndef SEC_E_CANNOT_PACK
+# define SEC_E_CANNOT_PACK                    ((HRESULT)0x80090309L)
+#endif
+#ifndef SEC_E_QOP_NOT_SUPPORTED
+# define SEC_E_QOP_NOT_SUPPORTED              ((HRESULT)0x8009030AL)
+#endif
+#ifndef SEC_E_NO_IMPERSONATION
+# define SEC_E_NO_IMPERSONATION               ((HRESULT)0x8009030BL)
+#endif
+#ifndef SEC_E_LOGON_DENIED
+# define SEC_E_LOGON_DENIED                   ((HRESULT)0x8009030CL)
+#endif
+#ifndef SEC_E_UNKNOWN_CREDENTIALS
+# define SEC_E_UNKNOWN_CREDENTIALS            ((HRESULT)0x8009030DL)
+#endif
+#ifndef SEC_E_NO_CREDENTIALS
+# define SEC_E_NO_CREDENTIALS                 ((HRESULT)0x8009030EL)
+#endif
+#ifndef SEC_E_MESSAGE_ALTERED
+# define SEC_E_MESSAGE_ALTERED                ((HRESULT)0x8009030FL)
+#endif
+#ifndef SEC_E_OUT_OF_SEQUENCE
+# define SEC_E_OUT_OF_SEQUENCE                ((HRESULT)0x80090310L)
+#endif
+#ifndef SEC_E_NO_AUTHENTICATING_AUTHORITY
+# define SEC_E_NO_AUTHENTICATING_AUTHORITY    ((HRESULT)0x80090311L)
+#endif
+#ifndef SEC_E_BAD_PKGID
+# define SEC_E_BAD_PKGID                      ((HRESULT)0x80090316L)
+#endif
+#ifndef SEC_E_CONTEXT_EXPIRED
+# define SEC_E_CONTEXT_EXPIRED                ((HRESULT)0x80090317L)
+#endif
+#ifndef SEC_E_INCOMPLETE_MESSAGE
+# define SEC_E_INCOMPLETE_MESSAGE             ((HRESULT)0x80090318L)
+#endif
+#ifndef SEC_E_INCOMPLETE_CREDENTIALS
+# define SEC_E_INCOMPLETE_CREDENTIALS         ((HRESULT)0x80090320L)
+#endif
+#ifndef SEC_E_BUFFER_TOO_SMALL
+# define SEC_E_BUFFER_TOO_SMALL               ((HRESULT)0x80090321L)
+#endif
+#ifndef SEC_E_WRONG_PRINCIPAL
+# define SEC_E_WRONG_PRINCIPAL                ((HRESULT)0x80090322L)
+#endif
+#ifndef SEC_E_TIME_SKEW
+# define SEC_E_TIME_SKEW                      ((HRESULT)0x80090324L)
+#endif
+#ifndef SEC_E_UNTRUSTED_ROOT
+# define SEC_E_UNTRUSTED_ROOT                 ((HRESULT)0x80090325L)
+#endif
+#ifndef SEC_E_ILLEGAL_MESSAGE
+# define SEC_E_ILLEGAL_MESSAGE                ((HRESULT)0x80090326L)
+#endif
+#ifndef SEC_E_CERT_UNKNOWN
+# define SEC_E_CERT_UNKNOWN                   ((HRESULT)0x80090327L)
+#endif
+#ifndef SEC_E_CERT_EXPIRED
+# define SEC_E_CERT_EXPIRED                   ((HRESULT)0x80090328L)
+#endif
+#ifndef SEC_E_ENCRYPT_FAILURE
+# define SEC_E_ENCRYPT_FAILURE                ((HRESULT)0x80090329L)
+#endif
+#ifndef SEC_E_DECRYPT_FAILURE
+# define SEC_E_DECRYPT_FAILURE                ((HRESULT)0x80090330L)
+#endif
+#ifndef SEC_E_ALGORITHM_MISMATCH
+# define SEC_E_ALGORITHM_MISMATCH             ((HRESULT)0x80090331L)
+#endif
+#ifndef SEC_E_SECURITY_QOS_FAILED
+# define SEC_E_SECURITY_QOS_FAILED            ((HRESULT)0x80090332L)
+#endif
+#ifndef SEC_E_UNFINISHED_CONTEXT_DELETED
+# define SEC_E_UNFINISHED_CONTEXT_DELETED     ((HRESULT)0x80090333L)
+#endif
+#ifndef SEC_E_NO_TGT_REPLY
+# define SEC_E_NO_TGT_REPLY                   ((HRESULT)0x80090334L)
+#endif
+#ifndef SEC_E_NO_IP_ADDRESSES
+# define SEC_E_NO_IP_ADDRESSES                ((HRESULT)0x80090335L)
+#endif
+#ifndef SEC_E_WRONG_CREDENTIAL_HANDLE
+# define SEC_E_WRONG_CREDENTIAL_HANDLE        ((HRESULT)0x80090336L)
+#endif
+#ifndef SEC_E_CRYPTO_SYSTEM_INVALID
+# define SEC_E_CRYPTO_SYSTEM_INVALID          ((HRESULT)0x80090337L)
+#endif
+#ifndef SEC_E_MAX_REFERRALS_EXCEEDED
+# define SEC_E_MAX_REFERRALS_EXCEEDED         ((HRESULT)0x80090338L)
+#endif
+#ifndef SEC_E_MUST_BE_KDC
+# define SEC_E_MUST_BE_KDC                    ((HRESULT)0x80090339L)
+#endif
+#ifndef SEC_E_STRONG_CRYPTO_NOT_SUPPORTED
+# define SEC_E_STRONG_CRYPTO_NOT_SUPPORTED    ((HRESULT)0x8009033AL)
+#endif
+#ifndef SEC_E_TOO_MANY_PRINCIPALS
+# define SEC_E_TOO_MANY_PRINCIPALS            ((HRESULT)0x8009033BL)
+#endif
+#ifndef SEC_E_NO_PA_DATA
+# define SEC_E_NO_PA_DATA                     ((HRESULT)0x8009033CL)
+#endif
+#ifndef SEC_E_PKINIT_NAME_MISMATCH
+# define SEC_E_PKINIT_NAME_MISMATCH           ((HRESULT)0x8009033DL)
+#endif
+#ifndef SEC_E_SMARTCARD_LOGON_REQUIRED
+# define SEC_E_SMARTCARD_LOGON_REQUIRED       ((HRESULT)0x8009033EL)
+#endif
+#ifndef SEC_E_SHUTDOWN_IN_PROGRESS
+# define SEC_E_SHUTDOWN_IN_PROGRESS           ((HRESULT)0x8009033FL)
+#endif
+#ifndef SEC_E_KDC_INVALID_REQUEST
+# define SEC_E_KDC_INVALID_REQUEST            ((HRESULT)0x80090340L)
+#endif
+#ifndef SEC_E_KDC_UNABLE_TO_REFER
+# define SEC_E_KDC_UNABLE_TO_REFER            ((HRESULT)0x80090341L)
+#endif
+#ifndef SEC_E_KDC_UNKNOWN_ETYPE
+# define SEC_E_KDC_UNKNOWN_ETYPE              ((HRESULT)0x80090342L)
+#endif
+#ifndef SEC_E_UNSUPPORTED_PREAUTH
+# define SEC_E_UNSUPPORTED_PREAUTH            ((HRESULT)0x80090343L)
+#endif
+#ifndef SEC_E_DELEGATION_REQUIRED
+# define SEC_E_DELEGATION_REQUIRED            ((HRESULT)0x80090345L)
+#endif
+#ifndef SEC_E_BAD_BINDINGS
+# define SEC_E_BAD_BINDINGS                   ((HRESULT)0x80090346L)
+#endif
+#ifndef SEC_E_MULTIPLE_ACCOUNTS
+# define SEC_E_MULTIPLE_ACCOUNTS              ((HRESULT)0x80090347L)
+#endif
+#ifndef SEC_E_NO_KERB_KEY
+# define SEC_E_NO_KERB_KEY                    ((HRESULT)0x80090348L)
+#endif
+#ifndef SEC_E_CERT_WRONG_USAGE
+# define SEC_E_CERT_WRONG_USAGE               ((HRESULT)0x80090349L)
+#endif
+#ifndef SEC_E_DOWNGRADE_DETECTED
+# define SEC_E_DOWNGRADE_DETECTED             ((HRESULT)0x80090350L)
+#endif
+#ifndef SEC_E_SMARTCARD_CERT_REVOKED
+# define SEC_E_SMARTCARD_CERT_REVOKED         ((HRESULT)0x80090351L)
+#endif
+#ifndef SEC_E_ISSUING_CA_UNTRUSTED
+# define SEC_E_ISSUING_CA_UNTRUSTED           ((HRESULT)0x80090352L)
+#endif
+#ifndef SEC_E_REVOCATION_OFFLINE_C
+# define SEC_E_REVOCATION_OFFLINE_C           ((HRESULT)0x80090353L)
+#endif
+#ifndef SEC_E_PKINIT_CLIENT_FAILURE
+# define SEC_E_PKINIT_CLIENT_FAILURE          ((HRESULT)0x80090354L)
+#endif
+#ifndef SEC_E_SMARTCARD_CERT_EXPIRED
+# define SEC_E_SMARTCARD_CERT_EXPIRED         ((HRESULT)0x80090355L)
+#endif
+#ifndef SEC_E_NO_S4U_PROT_SUPPORT
+# define SEC_E_NO_S4U_PROT_SUPPORT            ((HRESULT)0x80090356L)
+#endif
+#ifndef SEC_E_CROSSREALM_DELEGATION_FAILURE
+# define SEC_E_CROSSREALM_DELEGATION_FAILURE  ((HRESULT)0x80090357L)
+#endif
+#ifndef SEC_E_REVOCATION_OFFLINE_KDC
+# define SEC_E_REVOCATION_OFFLINE_KDC         ((HRESULT)0x80090358L)
+#endif
+#ifndef SEC_E_ISSUING_CA_UNTRUSTED_KDC
+# define SEC_E_ISSUING_CA_UNTRUSTED_KDC       ((HRESULT)0x80090359L)
+#endif
+#ifndef SEC_E_KDC_CERT_EXPIRED
+# define SEC_E_KDC_CERT_EXPIRED               ((HRESULT)0x8009035AL)
+#endif
+#ifndef SEC_E_KDC_CERT_REVOKED
+# define SEC_E_KDC_CERT_REVOKED               ((HRESULT)0x8009035BL)
+#endif
+#ifndef SEC_E_INVALID_PARAMETER
+# define SEC_E_INVALID_PARAMETER              ((HRESULT)0x8009035DL)
+#endif
+#ifndef SEC_E_DELEGATION_POLICY
+# define SEC_E_DELEGATION_POLICY              ((HRESULT)0x8009035EL)
+#endif
+#ifndef SEC_E_POLICY_NLTM_ONLY
+# define SEC_E_POLICY_NLTM_ONLY               ((HRESULT)0x8009035FL)
+#endif
+
+#ifndef SEC_I_CONTINUE_NEEDED
+# define SEC_I_CONTINUE_NEEDED                ((HRESULT)0x00090312L)
+#endif
+#ifndef SEC_I_COMPLETE_NEEDED
+# define SEC_I_COMPLETE_NEEDED                ((HRESULT)0x00090313L)
+#endif
+#ifndef SEC_I_COMPLETE_AND_CONTINUE
+# define SEC_I_COMPLETE_AND_CONTINUE          ((HRESULT)0x00090314L)
+#endif
+#ifndef SEC_I_LOCAL_LOGON
+# define SEC_I_LOCAL_LOGON                    ((HRESULT)0x00090315L)
+#endif
+#ifndef SEC_I_CONTEXT_EXPIRED
+# define SEC_I_CONTEXT_EXPIRED                ((HRESULT)0x00090317L)
+#endif
+#ifndef SEC_I_INCOMPLETE_CREDENTIALS
+# define SEC_I_INCOMPLETE_CREDENTIALS         ((HRESULT)0x00090320L)
+#endif
+#ifndef SEC_I_RENEGOTIATE
+# define SEC_I_RENEGOTIATE                    ((HRESULT)0x00090321L)
+#endif
+#ifndef SEC_I_NO_LSA_CONTEXT
+# define SEC_I_NO_LSA_CONTEXT                 ((HRESULT)0x00090323L)
+#endif
+#ifndef SEC_I_SIGNATURE_NEEDED
+# define SEC_I_SIGNATURE_NEEDED               ((HRESULT)0x0009035CL)
+#endif
+
+#ifndef CRYPT_E_REVOKED
+# define CRYPT_E_REVOKED                      ((HRESULT)0x80092010L)
+#endif
+
+#ifdef UNICODE
+#  define SECFLAG_WINNT_AUTH_IDENTITY \
+     (unsigned long)SEC_WINNT_AUTH_IDENTITY_UNICODE
+#else
+#  define SECFLAG_WINNT_AUTH_IDENTITY \
+     (unsigned long)SEC_WINNT_AUTH_IDENTITY_ANSI
+#endif
+
+/*
+ * Definitions required from ntsecapi.h are directly provided below this point
+ * to avoid including ntsecapi.h due to a conflict with OpenSSL's safestack.h
+ */
+#define KERB_WRAP_NO_ENCRYPT 0x80000001
+
+#endif /* USE_WINDOWS_SSPI */
+
+#endif /* HEADER_CURL_SSPI_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_threads.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_threads.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_threads.c	(revision 164)
@@ -0,0 +1,136 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_THREADS_POSIX)
+#  ifdef HAVE_PTHREAD_H
+#    include <pthread.h>
+#  endif
+#elif defined(USE_THREADS_WIN32)
+#  ifdef HAVE_PROCESS_H
+#    include <process.h>
+#  endif
+#endif
+
+#include "curl_threads.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#if defined(USE_THREADS_POSIX)
+
+struct curl_actual_call {
+  unsigned int (*func)(void *);
+  void *arg;
+};
+
+static void *curl_thread_create_thunk(void *arg)
+{
+  struct curl_actual_call * ac = arg;
+  unsigned int (*func)(void *) = ac->func;
+  void *real_arg = ac->arg;
+
+  free(ac);
+
+  (*func)(real_arg);
+
+  return 0;
+}
+
+curl_thread_t Curl_thread_create(unsigned int (*func) (void*), void *arg)
+{
+  curl_thread_t t = malloc(sizeof(pthread_t));
+  struct curl_actual_call *ac = malloc(sizeof(struct curl_actual_call));
+  if(!(ac && t))
+    goto err;
+
+  ac->func = func;
+  ac->arg = arg;
+
+  if(pthread_create(t, NULL, curl_thread_create_thunk, ac) != 0)
+    goto err;
+
+  return t;
+
+err:
+  free(t);
+  free(ac);
+  return curl_thread_t_null;
+}
+
+void Curl_thread_destroy(curl_thread_t hnd)
+{
+  if(hnd != curl_thread_t_null) {
+    pthread_detach(*hnd);
+    free(hnd);
+  }
+}
+
+int Curl_thread_join(curl_thread_t *hnd)
+{
+  int ret = (pthread_join(**hnd, NULL) == 0);
+
+  free(*hnd);
+  *hnd = curl_thread_t_null;
+
+  return ret;
+}
+
+#elif defined(USE_THREADS_WIN32)
+
+curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*),
+                                 void *arg)
+{
+#ifdef _WIN32_WCE
+  return CreateThread(NULL, 0, func, arg, 0, NULL);
+#else
+  curl_thread_t t;
+  t = (curl_thread_t)_beginthreadex(NULL, 0, func, arg, 0, NULL);
+  if((t == 0) || (t == (curl_thread_t)-1L))
+    return curl_thread_t_null;
+  return t;
+#endif
+}
+
+void Curl_thread_destroy(curl_thread_t hnd)
+{
+  CloseHandle(hnd);
+}
+
+int Curl_thread_join(curl_thread_t *hnd)
+{
+#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
+    (_WIN32_WINNT < _WIN32_WINNT_VISTA)
+  int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0);
+#else
+  int ret = (WaitForSingleObjectEx(*hnd, INFINITE, FALSE) == WAIT_OBJECT_0);
+#endif
+
+  Curl_thread_destroy(*hnd);
+
+  *hnd = curl_thread_t_null;
+
+  return ret;
+}
+
+#endif /* USE_THREADS_* */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curl_threads.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curl_threads.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curl_threads.h	(revision 164)
@@ -0,0 +1,62 @@
+#ifndef HEADER_CURL_THREADS_H
+#define HEADER_CURL_THREADS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(USE_THREADS_POSIX)
+#  define CURL_STDCALL
+#  define curl_mutex_t           pthread_mutex_t
+#  define curl_thread_t          pthread_t *
+#  define curl_thread_t_null     (pthread_t *)0
+#  define Curl_mutex_init(m)     pthread_mutex_init(m, NULL)
+#  define Curl_mutex_acquire(m)  pthread_mutex_lock(m)
+#  define Curl_mutex_release(m)  pthread_mutex_unlock(m)
+#  define Curl_mutex_destroy(m)  pthread_mutex_destroy(m)
+#elif defined(USE_THREADS_WIN32)
+#  define CURL_STDCALL           __stdcall
+#  define curl_mutex_t           CRITICAL_SECTION
+#  define curl_thread_t          HANDLE
+#  define curl_thread_t_null     (HANDLE)0
+#  if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
+      (_WIN32_WINNT < _WIN32_WINNT_VISTA)
+#    define Curl_mutex_init(m)   InitializeCriticalSection(m)
+#  else
+#    define Curl_mutex_init(m)   InitializeCriticalSectionEx(m, 0, 1)
+#  endif
+#  define Curl_mutex_acquire(m)  EnterCriticalSection(m)
+#  define Curl_mutex_release(m)  LeaveCriticalSection(m)
+#  define Curl_mutex_destroy(m)  DeleteCriticalSection(m)
+#endif
+
+#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+
+curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*),
+                                 void *arg);
+
+void Curl_thread_destroy(curl_thread_t hnd);
+
+int Curl_thread_join(curl_thread_t *hnd);
+
+#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */
+
+#endif /* HEADER_CURL_THREADS_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/curlx.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/curlx.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/curlx.h	(revision 164)
@@ -0,0 +1,118 @@
+#ifndef HEADER_CURL_CURLX_H
+#define HEADER_CURL_CURLX_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Defines protos and includes all header files that provide the curlx_*
+ * functions. The curlx_* functions are not part of the libcurl API, but are
+ * stand-alone functions whose sources can be built and linked by apps if need
+ * be.
+ */
+
+#include <curl/mprintf.h>
+/* this is still a public header file that provides the curl_mprintf()
+   functions while they still are offered publicly. They will be made library-
+   private one day */
+
+#include "strequal.h"
+/* "strequal.h" provides the strequal protos */
+
+#include "strtoofft.h"
+/* "strtoofft.h" provides this function: curlx_strtoofft(), returns a
+   curl_off_t number from a given string.
+*/
+
+#include "timeval.h"
+/*
+  "timeval.h" sets up a 'struct timeval' even for platforms that otherwise
+  don't have one and has protos for these functions:
+
+  curlx_tvnow()
+  curlx_tvdiff()
+  curlx_tvdiff_secs()
+*/
+
+#include "nonblock.h"
+/* "nonblock.h" provides curlx_nonblock() */
+
+#include "warnless.h"
+/* "warnless.h" provides functions:
+
+  curlx_ultous()
+  curlx_ultouc()
+  curlx_uztosi()
+*/
+
+/* Now setup curlx_ * names for the functions that are to become curlx_ and
+   be removed from a future libcurl official API:
+   curlx_getenv
+   curlx_mprintf (and its variations)
+   curlx_strequal
+   curlx_strnequal
+
+*/
+
+#define curlx_getenv curl_getenv
+#define curlx_strequal curl_strequal
+#define curlx_strnequal curl_strnequal
+#define curlx_raw_equal Curl_raw_equal
+#define curlx_mvsnprintf curl_mvsnprintf
+#define curlx_msnprintf curl_msnprintf
+#define curlx_maprintf curl_maprintf
+#define curlx_mvaprintf curl_mvaprintf
+#define curlx_msprintf curl_msprintf
+#define curlx_mprintf curl_mprintf
+#define curlx_mfprintf curl_mfprintf
+#define curlx_mvsprintf curl_mvsprintf
+#define curlx_mvprintf curl_mvprintf
+#define curlx_mvfprintf curl_mvfprintf
+
+#ifdef ENABLE_CURLX_PRINTF
+/* If this define is set, we define all "standard" printf() functions to use
+   the curlx_* version instead. It makes the source code transparent and
+   easier to understand/patch. Undefine them first. */
+# undef printf
+# undef fprintf
+# undef sprintf
+# undef snprintf
+# undef vprintf
+# undef vfprintf
+# undef vsprintf
+# undef vsnprintf
+# undef aprintf
+# undef vaprintf
+
+# define printf curlx_mprintf
+# define fprintf curlx_mfprintf
+# define sprintf curlx_msprintf
+# define snprintf curlx_msnprintf
+# define vprintf curlx_mvprintf
+# define vfprintf curlx_mvfprintf
+# define vsprintf curlx_mvsprintf
+# define vsnprintf curlx_mvsnprintf
+# define aprintf curlx_maprintf
+# define vaprintf curlx_mvaprintf
+#endif /* ENABLE_CURLX_PRINTF */
+
+#endif /* HEADER_CURL_CURLX_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/dict.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/dict.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/dict.c	(revision 164)
@@ -0,0 +1,279 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_DICT
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+
+#include "progress.h"
+#include "strequal.h"
+#include "dict.h"
+#include "rawstr.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Forward declarations.
+ */
+
+static CURLcode dict_do(struct connectdata *conn, bool *done);
+
+/*
+ * DICT protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_dict = {
+  "DICT",                               /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  dict_do,                              /* do_it */
+  ZERO_NULL,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_DICT,                            /* defport */
+  CURLPROTO_DICT,                       /* protocol */
+  PROTOPT_NONE | PROTOPT_NOURLQUERY      /* flags */
+};
+
+static char *unescape_word(struct SessionHandle *data, const char *inputbuff)
+{
+  char *newp;
+  char *dictp;
+  char *ptr;
+  int len;
+  char ch;
+  int olen=0;
+
+  newp = curl_easy_unescape(data, inputbuff, 0, &len);
+  if(!newp)
+    return NULL;
+
+  dictp = malloc(((size_t)len)*2 + 1); /* add one for terminating zero */
+  if(dictp) {
+    /* According to RFC2229 section 2.2, these letters need to be escaped with
+       \[letter] */
+    for(ptr = newp;
+        (ch = *ptr) != 0;
+        ptr++) {
+      if((ch <= 32) || (ch == 127) ||
+          (ch == '\'') || (ch == '\"') || (ch == '\\')) {
+        dictp[olen++] = '\\';
+      }
+      dictp[olen++] = ch;
+    }
+    dictp[olen]=0;
+  }
+  free(newp);
+  return dictp;
+}
+
+static CURLcode dict_do(struct connectdata *conn, bool *done)
+{
+  char *word;
+  char *eword;
+  char *ppath;
+  char *database = NULL;
+  char *strategy = NULL;
+  char *nthdef = NULL; /* This is not part of the protocol, but required
+                          by RFC 2229 */
+  CURLcode result=CURLE_OK;
+  struct SessionHandle *data=conn->data;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+
+  char *path = data->state.path;
+  curl_off_t *bytecount = &data->req.bytecount;
+
+  *done = TRUE; /* unconditionally */
+
+  if(conn->bits.user_passwd) {
+    /* AUTH is missing */
+  }
+
+  if(Curl_raw_nequal(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
+      Curl_raw_nequal(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
+      Curl_raw_nequal(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
+
+    word = strchr(path, ':');
+    if(word) {
+      word++;
+      database = strchr(word, ':');
+      if(database) {
+        *database++ = (char)0;
+        strategy = strchr(database, ':');
+        if(strategy) {
+          *strategy++ = (char)0;
+          nthdef = strchr(strategy, ':');
+          if(nthdef) {
+            *nthdef = (char)0;
+          }
+        }
+      }
+    }
+
+    if((word == NULL) || (*word == (char)0)) {
+      infof(data, "lookup word is missing\n");
+      word=(char *)"default";
+    }
+    if((database == NULL) || (*database == (char)0)) {
+      database = (char *)"!";
+    }
+    if((strategy == NULL) || (*strategy == (char)0)) {
+      strategy = (char *)".";
+    }
+
+    eword = unescape_word(data, word);
+    if(!eword)
+      return CURLE_OUT_OF_MEMORY;
+
+    result = Curl_sendf(sockfd, conn,
+                        "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+                        "MATCH "
+                        "%s "    /* database */
+                        "%s "    /* strategy */
+                        "%s\r\n" /* word */
+                        "QUIT\r\n",
+
+                        database,
+                        strategy,
+                        eword
+                        );
+
+    free(eword);
+
+    if(result) {
+      failf(data, "Failed sending DICT request");
+      return result;
+    }
+    Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
+                        -1, NULL); /* no upload */
+  }
+  else if(Curl_raw_nequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
+           Curl_raw_nequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
+           Curl_raw_nequal(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
+
+    word = strchr(path, ':');
+    if(word) {
+      word++;
+      database = strchr(word, ':');
+      if(database) {
+        *database++ = (char)0;
+        nthdef = strchr(database, ':');
+        if(nthdef) {
+          *nthdef = (char)0;
+        }
+      }
+    }
+
+    if((word == NULL) || (*word == (char)0)) {
+      infof(data, "lookup word is missing\n");
+      word=(char *)"default";
+    }
+    if((database == NULL) || (*database == (char)0)) {
+      database = (char *)"!";
+    }
+
+    eword = unescape_word(data, word);
+    if(!eword)
+      return CURLE_OUT_OF_MEMORY;
+
+    result = Curl_sendf(sockfd, conn,
+                        "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+                        "DEFINE "
+                        "%s "     /* database */
+                        "%s\r\n"  /* word */
+                        "QUIT\r\n",
+                        database,
+                        eword);
+
+    free(eword);
+
+    if(result) {
+      failf(data, "Failed sending DICT request");
+      return result;
+    }
+    Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
+                        -1, NULL); /* no upload */
+  }
+  else {
+
+    ppath = strchr(path, '/');
+    if(ppath) {
+      int i;
+
+      ppath++;
+      for(i = 0; ppath[i]; i++) {
+        if(ppath[i] == ':')
+          ppath[i] = ' ';
+      }
+      result = Curl_sendf(sockfd, conn,
+                          "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+                          "%s\r\n"
+                          "QUIT\r\n", ppath);
+      if(result) {
+        failf(data, "Failed sending DICT request");
+        return result;
+      }
+
+      Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, -1, NULL);
+    }
+  }
+
+  return CURLE_OK;
+}
+#endif /*CURL_DISABLE_DICT*/
Index: UsbWattMeter/trunk/curl-7.47.1/lib/dict.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/dict.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/dict.h	(revision 164)
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_DICT_H
+#define HEADER_CURL_DICT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifndef CURL_DISABLE_DICT
+extern const struct Curl_handler Curl_handler_dict;
+#endif
+
+#endif /* HEADER_CURL_DICT_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/dotdot.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/dotdot.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/dotdot.c	(revision 164)
@@ -0,0 +1,177 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "dotdot.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * "Remove Dot Segments"
+ * https://tools.ietf.org/html/rfc3986#section-5.2.4
+ */
+
+/*
+ * Curl_dedotdotify()
+ * @unittest: 1395
+ *
+ * This function gets a zero-terminated path with dot and dotdot sequences
+ * passed in and strips them off according to the rules in RFC 3986 section
+ * 5.2.4.
+ *
+ * The function handles a query part ('?' + stuff) appended but it expects
+ * that fragments ('#' + stuff) have already been cut off.
+ *
+ * RETURNS
+ *
+ * an allocated dedotdotified output string
+ */
+char *Curl_dedotdotify(const char *input)
+{
+  size_t inlen = strlen(input);
+  char *clone;
+  size_t clen = inlen; /* the length of the cloned input */
+  char *out = malloc(inlen+1);
+  char *outptr;
+  char *orgclone;
+  char *queryp;
+  if(!out)
+    return NULL; /* out of memory */
+
+  /* get a cloned copy of the input */
+  clone = strdup(input);
+  if(!clone) {
+    free(out);
+    return NULL;
+  }
+  orgclone = clone;
+  outptr = out;
+
+  if(!*clone) {
+    /* zero length string, return that */
+    free(out);
+    return clone;
+  }
+
+  /*
+   * To handle query-parts properly, we must find it and remove it during the
+   * dotdot-operation and then append it again at the end to the output
+   * string.
+   */
+  queryp = strchr(clone, '?');
+  if(queryp)
+    *queryp = 0;
+
+  do {
+
+    /*  A.  If the input buffer begins with a prefix of "../" or "./", then
+        remove that prefix from the input buffer; otherwise, */
+
+    if(!strncmp("./", clone, 2)) {
+      clone+=2;
+      clen-=2;
+    }
+    else if(!strncmp("../", clone, 3)) {
+      clone+=3;
+      clen-=3;
+    }
+
+    /*  B.  if the input buffer begins with a prefix of "/./" or "/.", where
+        "."  is a complete path segment, then replace that prefix with "/" in
+        the input buffer; otherwise, */
+    else if(!strncmp("/./", clone, 3)) {
+      clone+=2;
+      clen-=2;
+    }
+    else if(!strcmp("/.", clone)) {
+      clone[1]='/';
+      clone++;
+      clen-=1;
+    }
+
+    /*  C.  if the input buffer begins with a prefix of "/../" or "/..", where
+        ".." is a complete path segment, then replace that prefix with "/" in
+        the input buffer and remove the last segment and its preceding "/" (if
+        any) from the output buffer; otherwise, */
+
+    else if(!strncmp("/../", clone, 4)) {
+      clone+=3;
+      clen-=3;
+      /* remove the last segment from the output buffer */
+      while(outptr > out) {
+        outptr--;
+        if(*outptr == '/')
+          break;
+      }
+      *outptr = 0; /* zero-terminate where it stops */
+    }
+    else if(!strcmp("/..", clone)) {
+      clone[2]='/';
+      clone+=2;
+      clen-=2;
+      /* remove the last segment from the output buffer */
+      while(outptr > out) {
+        outptr--;
+        if(*outptr == '/')
+          break;
+      }
+      *outptr = 0; /* zero-terminate where it stops */
+    }
+
+    /*  D.  if the input buffer consists only of "." or "..", then remove
+        that from the input buffer; otherwise, */
+
+    else if(!strcmp(".", clone) || !strcmp("..", clone)) {
+      *clone=0;
+    }
+
+    else {
+      /*  E.  move the first path segment in the input buffer to the end of
+          the output buffer, including the initial "/" character (if any) and
+          any subsequent characters up to, but not including, the next "/"
+          character or the end of the input buffer. */
+
+      do {
+        *outptr++ = *clone++;
+        clen--;
+      } while(*clone && (*clone != '/'));
+      *outptr = 0;
+    }
+
+  } while(*clone);
+
+  if(queryp) {
+    size_t qlen;
+    /* There was a query part, append that to the output. The 'clone' string
+       may now have been altered so we copy from the original input string
+       from the correct index. */
+    size_t oindex = queryp - orgclone;
+    qlen = strlen(&input[oindex]);
+    memcpy(outptr, &input[oindex], qlen+1); /* include the ending zero byte */
+  }
+
+  free(orgclone);
+  return out;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/dotdot.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/dotdot.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/dotdot.h	(revision 164)
@@ -0,0 +1,25 @@
+#ifndef HEADER_CURL_DOTDOT_H
+#define HEADER_CURL_DOTDOT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+char *Curl_dedotdotify(const char *input);
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/lib/easy.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/easy.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/easy.c	(revision 164)
@@ -0,0 +1,1155 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/*
+ * See comment in curl_memory.h for the explanation of this sanity check.
+ */
+
+#ifdef CURLX_NO_MEMORY_CALLBACKS
+#error "libcurl shall not ever be built with CURLX_NO_MEMORY_CALLBACKS defined"
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include "strequal.h"
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "vtls/vtls.h"
+#include "url.h"
+#include "getinfo.h"
+#include "hostip.h"
+#include "share.h"
+#include "strdup.h"
+#include "progress.h"
+#include "easyif.h"
+#include "select.h"
+#include "sendf.h" /* for failf function prototype */
+#include "curl_ntlm.h"
+#include "connect.h" /* for Curl_getconnectinfo */
+#include "slist.h"
+#include "amigaos.h"
+#include "non-ascii.h"
+#include "warnless.h"
+#include "conncache.h"
+#include "multiif.h"
+#include "sigpipe.h"
+#include "ssh.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+#if defined(USE_LWIPSOCK)
+#include "lwip/tcpip.h"
+#endif
+
+/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
+   of win32_init() */
+static void win32_cleanup(void)
+{
+#ifdef USE_WINSOCK
+  WSACleanup();
+#endif
+#ifdef USE_WINDOWS_SSPI
+  Curl_sspi_global_cleanup();
+#endif
+}
+
+/* win32_init() performs win32 socket initialization to properly setup the
+   stack to allow networking */
+static CURLcode win32_init(void)
+{
+#ifdef USE_WINSOCK
+  WORD wVersionRequested;
+  WSADATA wsaData;
+  int res;
+
+#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
+  Error IPV6_requires_winsock2
+#endif
+
+  wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
+
+  res = WSAStartup(wVersionRequested, &wsaData);
+
+  if(res != 0)
+    /* Tell the user that we couldn't find a useable */
+    /* winsock.dll.     */
+    return CURLE_FAILED_INIT;
+
+  /* Confirm that the Windows Sockets DLL supports what we need.*/
+  /* Note that if the DLL supports versions greater */
+  /* than wVersionRequested, it will still return */
+  /* wVersionRequested in wVersion. wHighVersion contains the */
+  /* highest supported version. */
+
+  if(LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
+     HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
+    /* Tell the user that we couldn't find a useable */
+
+    /* winsock.dll. */
+    WSACleanup();
+    return CURLE_FAILED_INIT;
+  }
+  /* The Windows Sockets DLL is acceptable. Proceed. */
+#elif defined(USE_LWIPSOCK)
+  tcpip_init(NULL, NULL);
+#endif
+
+#ifdef USE_WINDOWS_SSPI
+  {
+    CURLcode result = Curl_sspi_global_init();
+    if(result)
+      return result;
+  }
+#endif
+
+  return CURLE_OK;
+}
+
+#ifdef USE_LIBIDN
+/*
+ * Initialise use of IDNA library.
+ * It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
+ * idna_to_ascii_lz().
+ */
+static void idna_init (void)
+{
+#ifdef WIN32
+  char buf[60];
+  UINT cp = GetACP();
+
+  if(!getenv("CHARSET") && cp > 0) {
+    snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
+    putenv(buf);
+  }
+#else
+  /* to do? */
+#endif
+}
+#endif  /* USE_LIBIDN */
+
+/* true globals -- for curl_global_init() and curl_global_cleanup() */
+static unsigned int  initialized;
+static long          init_flags;
+
+/*
+ * strdup (and other memory functions) is redefined in complicated
+ * ways, but at this point it must be defined as the system-supplied strdup
+ * so the callback pointer is initialized correctly.
+ */
+#if defined(_WIN32_WCE)
+#define system_strdup _strdup
+#elif !defined(HAVE_STRDUP)
+#define system_strdup curlx_strdup
+#else
+#define system_strdup strdup
+#endif
+
+#if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
+#  pragma warning(disable:4232) /* MSVC extension, dllimport identity */
+#endif
+
+#ifndef __SYMBIAN32__
+/*
+ * If a memory-using function (like curl_getenv) is used before
+ * curl_global_init() is called, we need to have these pointers set already.
+ */
+curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)sys_malloc;
+curl_free_callback Curl_cfree = (curl_free_callback)sys_free;
+curl_realloc_callback Curl_crealloc = (curl_realloc_callback)sys_realloc;
+curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
+curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)sys_calloc;
+#if defined(WIN32) && defined(UNICODE)
+curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
+#endif
+#else
+/*
+ * Symbian OS doesn't support initialization to code in writeable static data.
+ * Initialization will occur in the curl_global_init() call.
+ */
+curl_malloc_callback Curl_cmalloc;
+curl_free_callback Curl_cfree;
+curl_realloc_callback Curl_crealloc;
+curl_strdup_callback Curl_cstrdup;
+curl_calloc_callback Curl_ccalloc;
+#endif
+
+#if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
+#  pragma warning(default:4232) /* MSVC extension, dllimport identity */
+#endif
+
+/**
+ * curl_global_init() globally initializes cURL given a bitwise set of the
+ * different features of what to initialize.
+ */
+static CURLcode global_init(long flags, bool memoryfuncs)
+{
+  if(initialized++)
+    return CURLE_OK;
+
+  if(memoryfuncs) {
+    /* Setup the default memory functions here (again) */
+    Curl_cmalloc = (curl_malloc_callback)sys_malloc;
+    Curl_cfree = (curl_free_callback)sys_free;
+    Curl_crealloc = (curl_realloc_callback)sys_realloc;
+    Curl_cstrdup = (curl_strdup_callback)system_strdup;
+    Curl_ccalloc = (curl_calloc_callback)sys_calloc;
+#if defined(WIN32) && defined(UNICODE)
+    Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
+#endif
+  }
+
+  if(flags & CURL_GLOBAL_SSL)
+    if(!Curl_ssl_init()) {
+      DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n"));
+      return CURLE_FAILED_INIT;
+    }
+
+  if(flags & CURL_GLOBAL_WIN32)
+    if(win32_init()) {
+      DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
+      return CURLE_FAILED_INIT;
+    }
+
+#ifdef __AMIGA__
+  if(!Curl_amiga_init()) {
+    DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n"));
+    return CURLE_FAILED_INIT;
+  }
+#endif
+
+#ifdef NETWARE
+  if(netware_init()) {
+    DEBUGF(fprintf(stderr, "Warning: LONG namespace not available\n"));
+  }
+#endif
+
+#ifdef USE_LIBIDN
+  idna_init();
+#endif
+
+  if(Curl_resolver_global_init()) {
+    DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
+    return CURLE_FAILED_INIT;
+  }
+
+#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
+  if(libssh2_init(0)) {
+    DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
+    return CURLE_FAILED_INIT;
+  }
+#endif
+
+  if(flags & CURL_GLOBAL_ACK_EINTR)
+    Curl_ack_eintr = 1;
+
+  init_flags  = flags;
+
+  return CURLE_OK;
+}
+
+
+/**
+ * curl_global_init() globally initializes cURL given a bitwise set of the
+ * different features of what to initialize.
+ */
+CURLcode curl_global_init(long flags)
+{
+  return global_init(flags, TRUE);
+}
+
+/*
+ * curl_global_init_mem() globally initializes cURL and also registers the
+ * user provided callback routines.
+ */
+CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
+                              curl_free_callback f, curl_realloc_callback r,
+                              curl_strdup_callback s, curl_calloc_callback c)
+{
+  /* Invalid input, return immediately */
+  if(!m || !f || !r || !s || !c)
+    return CURLE_FAILED_INIT;
+
+  if(initialized) {
+    /* Already initialized, don't do it again, but bump the variable anyway to
+       work like curl_global_init() and require the same amount of cleanup
+       calls. */
+    initialized++;
+    return CURLE_OK;
+  }
+
+  /* set memory functions before global_init() in case it wants memory
+     functions */
+  Curl_cmalloc = m;
+  Curl_cfree = f;
+  Curl_cstrdup = s;
+  Curl_crealloc = r;
+  Curl_ccalloc = c;
+
+  /* Call the actual init function, but without setting */
+  return global_init(flags, FALSE);
+}
+
+/**
+ * curl_global_cleanup() globally cleanups cURL, uses the value of
+ * "init_flags" to determine what needs to be cleaned up and what doesn't.
+ */
+void curl_global_cleanup(void)
+{
+  if(!initialized)
+    return;
+
+  if(--initialized)
+    return;
+
+  Curl_global_host_cache_dtor();
+
+  if(init_flags & CURL_GLOBAL_SSL)
+    Curl_ssl_cleanup();
+
+  Curl_resolver_global_cleanup();
+
+  if(init_flags & CURL_GLOBAL_WIN32)
+    win32_cleanup();
+
+  Curl_amiga_cleanup();
+
+#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT)
+  (void)libssh2_exit();
+#endif
+
+  init_flags  = 0;
+}
+
+/*
+ * curl_easy_init() is the external interface to alloc, setup and init an
+ * easy handle that is returned. If anything goes wrong, NULL is returned.
+ */
+CURL *curl_easy_init(void)
+{
+  CURLcode result;
+  struct SessionHandle *data;
+
+  /* Make sure we inited the global SSL stuff */
+  if(!initialized) {
+    result = curl_global_init(CURL_GLOBAL_DEFAULT);
+    if(result) {
+      /* something in the global init failed, return nothing */
+      DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
+      return NULL;
+    }
+  }
+
+  /* We use curl_open() with undefined URL so far */
+  result = Curl_open(&data);
+  if(result) {
+    DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
+    return NULL;
+  }
+
+  return data;
+}
+
+/*
+ * curl_easy_setopt() is the external interface for setting options on an
+ * easy handle.
+ */
+
+#undef curl_easy_setopt
+CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
+{
+  va_list arg;
+  struct SessionHandle *data = curl;
+  CURLcode result;
+
+  if(!curl)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  va_start(arg, tag);
+
+  result = Curl_setopt(data, tag, arg);
+
+  va_end(arg);
+  return result;
+}
+
+CURLcode curl_easy_vsetopt(CURL *curl, CURLoption tag, va_list arg)
+{
+  struct SessionHandle *data = curl;
+  CURLcode result;
+
+  if(!curl)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  result = Curl_setopt(data, tag, arg);
+
+  return result;
+}
+
+#ifdef CURLDEBUG
+
+struct socketmonitor {
+  struct socketmonitor *next; /* the next node in the list or NULL */
+  struct pollfd socket; /* socket info of what to monitor */
+};
+
+struct events {
+  long ms;              /* timeout, run the timeout function when reached */
+  bool msbump;          /* set TRUE when timeout is set by callback */
+  int num_sockets;      /* number of nodes in the monitor list */
+  struct socketmonitor *list; /* list of sockets to monitor */
+  int running_handles;  /* store the returned number */
+};
+
+/* events_timer
+ *
+ * Callback that gets called with a new value when the timeout should be
+ * updated.
+ */
+
+static int events_timer(CURLM *multi,    /* multi handle */
+                        long timeout_ms, /* see above */
+                        void *userp)    /* private callback pointer */
+{
+  struct events *ev = userp;
+  (void)multi;
+  if(timeout_ms == -1)
+    /* timeout removed */
+    timeout_ms = 0;
+  else if(timeout_ms == 0)
+    /* timeout is already reached! */
+    timeout_ms = 1; /* trigger asap */
+
+  ev->ms = timeout_ms;
+  ev->msbump = TRUE;
+  return 0;
+}
+
+
+/* poll2cselect
+ *
+ * convert from poll() bit definitions to libcurl's CURL_CSELECT_* ones
+ */
+static int poll2cselect(int pollmask)
+{
+  int omask=0;
+  if(pollmask & POLLIN)
+    omask |= CURL_CSELECT_IN;
+  if(pollmask & POLLOUT)
+    omask |= CURL_CSELECT_OUT;
+  if(pollmask & POLLERR)
+    omask |= CURL_CSELECT_ERR;
+  return omask;
+}
+
+
+/* socketcb2poll
+ *
+ * convert from libcurl' CURL_POLL_* bit definitions to poll()'s
+ */
+static short socketcb2poll(int pollmask)
+{
+  short omask=0;
+  if(pollmask & CURL_POLL_IN)
+    omask |= POLLIN;
+  if(pollmask & CURL_POLL_OUT)
+    omask |= POLLOUT;
+  return omask;
+}
+
+/* events_socket
+ *
+ * Callback that gets called with information about socket activity to
+ * monitor.
+ */
+static int events_socket(CURL *easy,      /* easy handle */
+                         curl_socket_t s, /* socket */
+                         int what,        /* see above */
+                         void *userp,     /* private callback
+                                             pointer */
+                         void *socketp)   /* private socket
+                                             pointer */
+{
+  struct events *ev = userp;
+  struct socketmonitor *m;
+  struct socketmonitor *prev=NULL;
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) easy;
+#endif
+  (void)socketp;
+
+  m = ev->list;
+  while(m) {
+    if(m->socket.fd == s) {
+
+      if(what == CURL_POLL_REMOVE) {
+        struct socketmonitor *nxt = m->next;
+        /* remove this node from the list of monitored sockets */
+        if(prev)
+          prev->next = nxt;
+        else
+          ev->list = nxt;
+        free(m);
+        m = nxt;
+        infof(easy, "socket cb: socket %d REMOVED\n", s);
+      }
+      else {
+        /* The socket 's' is already being monitored, update the activity
+           mask. Convert from libcurl bitmask to the poll one. */
+        m->socket.events = socketcb2poll(what);
+        infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s,
+              what&CURL_POLL_IN?"IN":"",
+              what&CURL_POLL_OUT?"OUT":"");
+      }
+      break;
+    }
+    prev = m;
+    m = m->next; /* move to next node */
+  }
+  if(!m) {
+    if(what == CURL_POLL_REMOVE) {
+      /* this happens a bit too often, libcurl fix perhaps? */
+      /* fprintf(stderr,
+         "%s: socket %d asked to be REMOVED but not present!\n",
+                 __func__, s); */
+    }
+    else {
+      m = malloc(sizeof(struct socketmonitor));
+      m->next = ev->list;
+      m->socket.fd = s;
+      m->socket.events = socketcb2poll(what);
+      m->socket.revents = 0;
+      ev->list = m;
+      infof(easy, "socket cb: socket %d ADDED as %s%s\n", s,
+            what&CURL_POLL_IN?"IN":"",
+            what&CURL_POLL_OUT?"OUT":"");
+    }
+  }
+
+  return 0;
+}
+
+
+/*
+ * events_setup()
+ *
+ * Do the multi handle setups that only event-based transfers need.
+ */
+static void events_setup(CURLM *multi, struct events *ev)
+{
+  /* timer callback */
+  curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer);
+  curl_multi_setopt(multi, CURLMOPT_TIMERDATA, ev);
+
+  /* socket callback */
+  curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, events_socket);
+  curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, ev);
+}
+
+
+/* wait_or_timeout()
+ *
+ * waits for activity on any of the given sockets, or the timeout to trigger.
+ */
+
+static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
+{
+  bool done = FALSE;
+  CURLMcode mcode;
+  CURLcode result = CURLE_OK;
+
+  while(!done) {
+    CURLMsg *msg;
+    struct socketmonitor *m;
+    struct pollfd *f;
+    struct pollfd fds[4];
+    int numfds=0;
+    int pollrc;
+    int i;
+    struct timeval before;
+    struct timeval after;
+
+    /* populate the fds[] array */
+    for(m = ev->list, f=&fds[0]; m; m = m->next) {
+      f->fd = m->socket.fd;
+      f->events = m->socket.events;
+      f->revents = 0;
+      /* fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); */
+      f++;
+      numfds++;
+    }
+
+    /* get the time stamp to use to figure out how long poll takes */
+    before = curlx_tvnow();
+
+    /* wait for activity or timeout */
+    pollrc = Curl_poll(fds, numfds, (int)ev->ms);
+
+    after = curlx_tvnow();
+
+    ev->msbump = FALSE; /* reset here */
+
+    if(0 == pollrc) {
+      /* timeout! */
+      ev->ms = 0;
+      /* fprintf(stderr, "call curl_multi_socket_action( TIMEOUT )\n"); */
+      mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0,
+                                       &ev->running_handles);
+    }
+    else if(pollrc > 0) {
+      /* loop over the monitored sockets to see which ones had activity */
+      for(i = 0; i< numfds; i++) {
+        if(fds[i].revents) {
+          /* socket activity, tell libcurl */
+          int act = poll2cselect(fds[i].revents); /* convert */
+          infof(multi->easyp, "call curl_multi_socket_action( socket %d )\n",
+                fds[i].fd);
+          mcode = curl_multi_socket_action(multi, fds[i].fd, act,
+                                           &ev->running_handles);
+        }
+      }
+
+      if(!ev->msbump)
+        /* If nothing updated the timeout, we decrease it by the spent time.
+         * If it was updated, it has the new timeout time stored already.
+         */
+        ev->ms += curlx_tvdiff(after, before);
+
+    }
+    else
+      return CURLE_RECV_ERROR;
+
+    if(mcode)
+      return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
+
+    /* we don't really care about the "msgs_in_queue" value returned in the
+       second argument */
+    msg = curl_multi_info_read(multi, &pollrc);
+    if(msg) {
+      result = msg->data.result;
+      done = TRUE;
+    }
+  }
+
+  return result;
+}
+
+
+/* easy_events()
+ *
+ * Runs a transfer in a blocking manner using the events-based API
+ */
+static CURLcode easy_events(CURLM *multi)
+{
+  struct events evs= {2, FALSE, 0, NULL, 0};
+
+  /* if running event-based, do some further multi inits */
+  events_setup(multi, &evs);
+
+  return wait_or_timeout(multi, &evs);
+}
+#else /* CURLDEBUG */
+/* when not built with debug, this function doesn't exist */
+#define easy_events(x) CURLE_NOT_BUILT_IN
+#endif
+
+static CURLcode easy_transfer(CURLM *multi)
+{
+  bool done = FALSE;
+  CURLMcode mcode = CURLM_OK;
+  CURLcode result = CURLE_OK;
+  struct timeval before;
+  int without_fds = 0;  /* count number of consecutive returns from
+                           curl_multi_wait() without any filedescriptors */
+
+  while(!done && !mcode) {
+    int still_running = 0;
+    int ret;
+
+    before = curlx_tvnow();
+    mcode = curl_multi_wait(multi, NULL, 0, 1000, &ret);
+
+    if(mcode == CURLM_OK) {
+      if(ret == -1) {
+        /* poll() failed not on EINTR, indicate a network problem */
+        result = CURLE_RECV_ERROR;
+        break;
+      }
+      else if(ret == 0) {
+        struct timeval after = curlx_tvnow();
+        /* If it returns without any filedescriptor instantly, we need to
+           avoid busy-looping during periods where it has nothing particular
+           to wait for */
+        if(curlx_tvdiff(after, before) <= 10) {
+          without_fds++;
+          if(without_fds > 2) {
+            int sleep_ms = without_fds < 10 ? (1 << (without_fds-1)): 1000;
+            Curl_wait_ms(sleep_ms);
+          }
+        }
+        else
+          /* it wasn't "instant", restart counter */
+          without_fds = 0;
+      }
+      else
+        /* got file descriptor, restart counter */
+        without_fds = 0;
+
+      mcode = curl_multi_perform(multi, &still_running);
+    }
+
+    /* only read 'still_running' if curl_multi_perform() return OK */
+    if((mcode == CURLM_OK) && !still_running) {
+      int rc;
+      CURLMsg *msg = curl_multi_info_read(multi, &rc);
+      if(msg) {
+        result = msg->data.result;
+        done = TRUE;
+      }
+    }
+  }
+
+  /* Make sure to return some kind of error if there was a multi problem */
+  if(mcode) {
+    return (mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY :
+            /* The other multi errors should never happen, so return
+               something suitably generic */
+            CURLE_BAD_FUNCTION_ARGUMENT;
+  }
+
+  return result;
+}
+
+
+/*
+ * easy_perform() is the external interface that performs a blocking
+ * transfer as previously setup.
+ *
+ * CONCEPT: This function creates a multi handle, adds the easy handle to it,
+ * runs curl_multi_perform() until the transfer is done, then detaches the
+ * easy handle, destroys the multi handle and returns the easy handle's return
+ * code.
+ *
+ * REALITY: it can't just create and destroy the multi handle that easily. It
+ * needs to keep it around since if this easy handle is used again by this
+ * function, the same multi handle must be re-used so that the same pools and
+ * caches can be used.
+ *
+ * DEBUG: if 'events' is set TRUE, this function will use a replacement engine
+ * instead of curl_multi_perform() and use curl_multi_socket_action().
+ */
+static CURLcode easy_perform(struct SessionHandle *data, bool events)
+{
+  CURLM *multi;
+  CURLMcode mcode;
+  CURLcode result = CURLE_OK;
+  SIGPIPE_VARIABLE(pipe_st);
+
+  if(!data)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  if(data->multi) {
+    failf(data, "easy handle already used in multi handle");
+    return CURLE_FAILED_INIT;
+  }
+
+  if(data->multi_easy)
+    multi = data->multi_easy;
+  else {
+    /* this multi handle will only ever have a single easy handled attached
+       to it, so make it use minimal hashes */
+    multi = Curl_multi_handle(1, 3);
+    if(!multi)
+      return CURLE_OUT_OF_MEMORY;
+    data->multi_easy = multi;
+  }
+
+  /* Copy the MAXCONNECTS option to the multi handle */
+  curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects);
+
+  mcode = curl_multi_add_handle(multi, data);
+  if(mcode) {
+    curl_multi_cleanup(multi);
+    if(mcode == CURLM_OUT_OF_MEMORY)
+      return CURLE_OUT_OF_MEMORY;
+    else
+      return CURLE_FAILED_INIT;
+  }
+
+  sigpipe_ignore(data, &pipe_st);
+
+  /* assign this after curl_multi_add_handle() since that function checks for
+     it and rejects this handle otherwise */
+  data->multi = multi;
+
+  /* run the transfer */
+  result = events ? easy_events(multi) : easy_transfer(multi);
+
+  /* ignoring the return code isn't nice, but atm we can't really handle
+     a failure here, room for future improvement! */
+  (void)curl_multi_remove_handle(multi, data);
+
+  sigpipe_restore(&pipe_st);
+
+  /* The multi handle is kept alive, owned by the easy handle */
+  return result;
+}
+
+
+/*
+ * curl_easy_perform() is the external interface that performs a blocking
+ * transfer as previously setup.
+ */
+CURLcode curl_easy_perform(CURL *easy)
+{
+  return easy_perform(easy, FALSE);
+}
+
+#ifdef CURLDEBUG
+/*
+ * curl_easy_perform_ev() is the external interface that performs a blocking
+ * transfer using the event-based API internally.
+ */
+CURLcode curl_easy_perform_ev(CURL *easy)
+{
+  return easy_perform(easy, TRUE);
+}
+
+#endif
+
+/*
+ * curl_easy_cleanup() is the external interface to cleaning/freeing the given
+ * easy handle.
+ */
+void curl_easy_cleanup(CURL *curl)
+{
+  struct SessionHandle *data = (struct SessionHandle *)curl;
+  SIGPIPE_VARIABLE(pipe_st);
+
+  if(!data)
+    return;
+
+  sigpipe_ignore(data, &pipe_st);
+  Curl_close(data);
+  sigpipe_restore(&pipe_st);
+}
+
+/*
+ * curl_easy_getinfo() is an external interface that allows an app to retrieve
+ * information from a performed transfer and similar.
+ */
+#undef curl_easy_getinfo
+CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
+{
+  va_list arg;
+  void *paramp;
+  CURLcode result;
+  struct SessionHandle *data = (struct SessionHandle *)curl;
+
+  va_start(arg, info);
+  paramp = va_arg(arg, void *);
+
+  result = Curl_getinfo(data, info, paramp);
+
+  va_end(arg);
+  return result;
+}
+
+/*
+ * curl_easy_duphandle() is an external interface to allow duplication of a
+ * given input easy handle. The returned handle will be a new working handle
+ * with all options set exactly as the input source handle.
+ */
+CURL *curl_easy_duphandle(CURL *incurl)
+{
+  struct SessionHandle *data=(struct SessionHandle *)incurl;
+
+  struct SessionHandle *outcurl = calloc(1, sizeof(struct SessionHandle));
+  if(NULL == outcurl)
+    goto fail;
+
+  /*
+   * We setup a few buffers we need. We should probably make them
+   * get setup on-demand in the code, as that would probably decrease
+   * the likeliness of us forgetting to init a buffer here in the future.
+   */
+  outcurl->state.headerbuff = malloc(HEADERSIZE);
+  if(!outcurl->state.headerbuff)
+    goto fail;
+  outcurl->state.headersize = HEADERSIZE;
+
+  /* copy all userdefined values */
+  if(Curl_dupset(outcurl, data))
+    goto fail;
+
+  /* the connection cache is setup on demand */
+  outcurl->state.conn_cache = NULL;
+
+  outcurl->state.lastconnect = NULL;
+
+  outcurl->progress.flags    = data->progress.flags;
+  outcurl->progress.callback = data->progress.callback;
+
+  if(data->cookies) {
+    /* If cookies are enabled in the parent handle, we enable them
+       in the clone as well! */
+    outcurl->cookies = Curl_cookie_init(data,
+                                        data->cookies->filename,
+                                        outcurl->cookies,
+                                        data->set.cookiesession);
+    if(!outcurl->cookies)
+      goto fail;
+  }
+
+  /* duplicate all values in 'change' */
+  if(data->change.cookielist) {
+    outcurl->change.cookielist =
+      Curl_slist_duplicate(data->change.cookielist);
+    if(!outcurl->change.cookielist)
+      goto fail;
+  }
+
+  if(data->change.url) {
+    outcurl->change.url = strdup(data->change.url);
+    if(!outcurl->change.url)
+      goto fail;
+    outcurl->change.url_alloc = TRUE;
+  }
+
+  if(data->change.referer) {
+    outcurl->change.referer = strdup(data->change.referer);
+    if(!outcurl->change.referer)
+      goto fail;
+    outcurl->change.referer_alloc = TRUE;
+  }
+
+  /* Clone the resolver handle, if present, for the new handle */
+  if(Curl_resolver_duphandle(&outcurl->state.resolver,
+                             data->state.resolver))
+    goto fail;
+
+  Curl_convert_setup(outcurl);
+
+  outcurl->magic = CURLEASY_MAGIC_NUMBER;
+
+  /* we reach this point and thus we are OK */
+
+  return outcurl;
+
+  fail:
+
+  if(outcurl) {
+    curl_slist_free_all(outcurl->change.cookielist);
+    outcurl->change.cookielist = NULL;
+    Curl_safefree(outcurl->state.headerbuff);
+    Curl_safefree(outcurl->change.url);
+    Curl_safefree(outcurl->change.referer);
+    Curl_freeset(outcurl);
+    free(outcurl);
+  }
+
+  return NULL;
+}
+
+/*
+ * curl_easy_reset() is an external interface that allows an app to re-
+ * initialize a session handle to the default values.
+ */
+void curl_easy_reset(CURL *curl)
+{
+  struct SessionHandle *data = (struct SessionHandle *)curl;
+
+  Curl_safefree(data->state.pathbuffer);
+
+  data->state.path = NULL;
+
+  Curl_free_request_state(data);
+
+  /* zero out UserDefined data: */
+  Curl_freeset(data);
+  memset(&data->set, 0, sizeof(struct UserDefined));
+  (void)Curl_init_userdefined(&data->set);
+
+  /* zero out Progress data: */
+  memset(&data->progress, 0, sizeof(struct Progress));
+
+  data->progress.flags |= PGRS_HIDE;
+  data->state.current_speed = -1; /* init to negative == impossible */
+}
+
+/*
+ * curl_easy_pause() allows an application to pause or unpause a specific
+ * transfer and direction. This function sets the full new state for the
+ * current connection this easy handle operates on.
+ *
+ * NOTE: if you have the receiving paused and you call this function to remove
+ * the pausing, you may get your write callback called at this point.
+ *
+ * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h
+ */
+CURLcode curl_easy_pause(CURL *curl, int action)
+{
+  struct SessionHandle *data = (struct SessionHandle *)curl;
+  struct SingleRequest *k = &data->req;
+  CURLcode result = CURLE_OK;
+
+  /* first switch off both pause bits */
+  int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
+
+  /* set the new desired pause bits */
+  newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
+    ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
+
+  /* put it back in the keepon */
+  k->keepon = newstate;
+
+  if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempwrite) {
+    /* we have a buffer for sending that we now seem to be able to deliver
+       since the receive pausing is lifted! */
+
+    /* get the pointer in local copy since the function may return PAUSE
+       again and then we'll get a new copy allocted and stored in
+       the tempwrite variables */
+    char *tempwrite = data->state.tempwrite;
+
+    data->state.tempwrite = NULL;
+    result = Curl_client_chop_write(data->easy_conn, data->state.tempwritetype,
+                                    tempwrite, data->state.tempwritesize);
+    free(tempwrite);
+  }
+
+  /* if there's no error and we're not pausing both directions, we want
+     to have this handle checked soon */
+  if(!result &&
+     ((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
+      (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
+    Curl_expire(data, 1); /* get this handle going again */
+
+  return result;
+}
+
+
+static CURLcode easy_connection(struct SessionHandle *data,
+                                curl_socket_t *sfd,
+                                struct connectdata **connp)
+{
+  if(data == NULL)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
+  if(!data->set.connect_only) {
+    failf(data, "CONNECT_ONLY is required!");
+    return CURLE_UNSUPPORTED_PROTOCOL;
+  }
+
+  *sfd = Curl_getconnectinfo(data, connp);
+
+  if(*sfd == CURL_SOCKET_BAD) {
+    failf(data, "Failed to get recent socket");
+    return CURLE_UNSUPPORTED_PROTOCOL;
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Receives data from the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ * Returns CURLE_OK on success, error code on error.
+ */
+CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
+{
+  curl_socket_t sfd;
+  CURLcode result;
+  ssize_t n1;
+  struct connectdata *c;
+  struct SessionHandle *data = (struct SessionHandle *)curl;
+
+  result = easy_connection(data, &sfd, &c);
+  if(result)
+    return result;
+
+  *n = 0;
+  result = Curl_read(c, sfd, buffer, buflen, &n1);
+
+  if(result)
+    return result;
+
+  *n = (size_t)n1;
+
+  return CURLE_OK;
+}
+
+/*
+ * Sends data over the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen,
+                        size_t *n)
+{
+  curl_socket_t sfd;
+  CURLcode result;
+  ssize_t n1;
+  struct connectdata *c = NULL;
+  struct SessionHandle *data = (struct SessionHandle *)curl;
+
+  result = easy_connection(data, &sfd, &c);
+  if(result)
+    return result;
+
+  *n = 0;
+  result = Curl_write(c, sfd, buffer, buflen, &n1);
+
+  if(n1 == -1)
+    return CURLE_SEND_ERROR;
+
+  /* detect EAGAIN */
+  if(!result && !n1)
+    return CURLE_AGAIN;
+
+  *n = (size_t)n1;
+
+  return result;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/easyif.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/easyif.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/easyif.h	(revision 164)
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_EASYIF_H
+#define HEADER_CURL_EASYIF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Prototypes for library-wide functions provided by easy.c
+ */
+#ifdef CURLDEBUG
+CURL_EXTERN CURLcode curl_easy_perform_ev(CURL *easy);
+#endif
+
+#endif /* HEADER_CURL_EASYIF_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/escape.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/escape.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/escape.c	(revision 164)
@@ -0,0 +1,231 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Escape and unescape URL encoding in strings. The functions return a new
+ * allocated string or NULL if an error occurred.  */
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "warnless.h"
+#include "non-ascii.h"
+#include "escape.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Portable character check (remember EBCDIC). Do not use isalnum() because
+   its behavior is altered by the current locale.
+   See https://tools.ietf.org/html/rfc3986#section-2.3
+*/
+static bool Curl_isunreserved(unsigned char in)
+{
+  switch (in) {
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+    case 'a': case 'b': case 'c': case 'd': case 'e':
+    case 'f': case 'g': case 'h': case 'i': case 'j':
+    case 'k': case 'l': case 'm': case 'n': case 'o':
+    case 'p': case 'q': case 'r': case 's': case 't':
+    case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
+    case 'A': case 'B': case 'C': case 'D': case 'E':
+    case 'F': case 'G': case 'H': case 'I': case 'J':
+    case 'K': case 'L': case 'M': case 'N': case 'O':
+    case 'P': case 'Q': case 'R': case 'S': case 'T':
+    case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
+    case '-': case '.': case '_': case '~':
+      return TRUE;
+    default:
+      break;
+  }
+  return FALSE;
+}
+
+/* for ABI-compatibility with previous versions */
+char *curl_escape(const char *string, int inlength)
+{
+  return curl_easy_escape(NULL, string, inlength);
+}
+
+/* for ABI-compatibility with previous versions */
+char *curl_unescape(const char *string, int length)
+{
+  return curl_easy_unescape(NULL, string, length, NULL);
+}
+
+char *curl_easy_escape(CURL *handle, const char *string, int inlength)
+{
+  size_t alloc = (inlength?(size_t)inlength:strlen(string))+1;
+  char *ns;
+  char *testing_ptr = NULL;
+  unsigned char in; /* we need to treat the characters unsigned */
+  size_t newlen = alloc;
+  size_t strindex=0;
+  size_t length;
+  CURLcode result;
+
+  ns = malloc(alloc);
+  if(!ns)
+    return NULL;
+
+  length = alloc-1;
+  while(length--) {
+    in = *string;
+
+    if(Curl_isunreserved(in))
+      /* just copy this */
+      ns[strindex++]=in;
+    else {
+      /* encode it */
+      newlen += 2; /* the size grows with two, since this'll become a %XX */
+      if(newlen > alloc) {
+        alloc *= 2;
+        testing_ptr = realloc(ns, alloc);
+        if(!testing_ptr) {
+          free( ns );
+          return NULL;
+        }
+        else {
+          ns = testing_ptr;
+        }
+      }
+
+      result = Curl_convert_to_network(handle, &in, 1);
+      if(result) {
+        /* Curl_convert_to_network calls failf if unsuccessful */
+        free(ns);
+        return NULL;
+      }
+
+      snprintf(&ns[strindex], 4, "%%%02X", in);
+
+      strindex+=3;
+    }
+    string++;
+  }
+  ns[strindex]=0; /* terminate it */
+  return ns;
+}
+
+/*
+ * Curl_urldecode() URL decodes the given string.
+ *
+ * Optionally detects control characters (byte codes lower than 32) in the
+ * data and rejects such data.
+ *
+ * Returns a pointer to a malloced string in *ostring with length given in
+ * *olen. If length == 0, the length is assumed to be strlen(string).
+ *
+ */
+CURLcode Curl_urldecode(struct SessionHandle *data,
+                        const char *string, size_t length,
+                        char **ostring, size_t *olen,
+                        bool reject_ctrl)
+{
+  size_t alloc = (length?length:strlen(string))+1;
+  char *ns = malloc(alloc);
+  unsigned char in;
+  size_t strindex=0;
+  unsigned long hex;
+  CURLcode result;
+
+  if(!ns)
+    return CURLE_OUT_OF_MEMORY;
+
+  while(--alloc > 0) {
+    in = *string;
+    if(('%' == in) && (alloc > 2) &&
+       ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
+      /* this is two hexadecimal digits following a '%' */
+      char hexstr[3];
+      char *ptr;
+      hexstr[0] = string[1];
+      hexstr[1] = string[2];
+      hexstr[2] = 0;
+
+      hex = strtoul(hexstr, &ptr, 16);
+
+      in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */
+
+      result = Curl_convert_from_network(data, &in, 1);
+      if(result) {
+        /* Curl_convert_from_network calls failf if unsuccessful */
+        free(ns);
+        return result;
+      }
+
+      string+=2;
+      alloc-=2;
+    }
+
+    if(reject_ctrl && (in < 0x20)) {
+      free(ns);
+      return CURLE_URL_MALFORMAT;
+    }
+
+    ns[strindex++] = in;
+    string++;
+  }
+  ns[strindex]=0; /* terminate it */
+
+  if(olen)
+    /* store output size */
+    *olen = strindex;
+
+  /* store output string */
+  *ostring = ns;
+
+  return CURLE_OK;
+}
+
+/*
+ * Unescapes the given URL escaped string of given length. Returns a
+ * pointer to a malloced string with length given in *olen.
+ * If length == 0, the length is assumed to be strlen(string).
+ * If olen == NULL, no output length is stored.
+ */
+char *curl_easy_unescape(CURL *handle, const char *string, int length,
+                         int *olen)
+{
+  char *str = NULL;
+  size_t inputlen = length;
+  size_t outputlen;
+  CURLcode res = Curl_urldecode(handle, string, inputlen, &str, &outputlen,
+                                FALSE);
+  if(res)
+    return NULL;
+  if(olen)
+    *olen = curlx_uztosi(outputlen);
+  return str;
+}
+
+/* For operating systems/environments that use different malloc/free
+   systems for the app and for this library, we provide a free that uses
+   the library's memory system */
+void curl_free(void *p)
+{
+  free(p);
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/escape.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/escape.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/escape.h	(revision 164)
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_ESCAPE_H
+#define HEADER_CURL_ESCAPE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* Escape and unescape URL encoding in strings. The functions return a new
+ * allocated string or NULL if an error occurred.  */
+
+CURLcode Curl_urldecode(struct SessionHandle *data,
+                        const char *string, size_t length,
+                        char **ostring, size_t *olen,
+                        bool reject_crlf);
+
+#endif /* HEADER_CURL_ESCAPE_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/file.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/file.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/file.c	(revision 164)
@@ -0,0 +1,586 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FILE
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include "strtoofft.h"
+#include "urldata.h"
+#include <curl/curl.h>
+#include "progress.h"
+#include "sendf.h"
+#include "escape.h"
+#include "file.h"
+#include "speedcheck.h"
+#include "getinfo.h"
+#include "transfer.h"
+#include "url.h"
+#include "parsedate.h" /* for the week day and month names */
+#include "warnless.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || \
+  defined(__SYMBIAN32__)
+#define DOS_FILESYSTEM 1
+#endif
+
+#ifdef OPEN_NEEDS_ARG3
+#  define open_readonly(p,f) open((p),(f),(0))
+#else
+#  define open_readonly(p,f) open((p),(f))
+#endif
+
+/*
+ * Forward declarations.
+ */
+
+static CURLcode file_do(struct connectdata *, bool *done);
+static CURLcode file_done(struct connectdata *conn,
+                          CURLcode status, bool premature);
+static CURLcode file_connect(struct connectdata *conn, bool *done);
+static CURLcode file_disconnect(struct connectdata *conn,
+                                bool dead_connection);
+static CURLcode file_setup_connection(struct connectdata *conn);
+
+/*
+ * FILE scheme handler.
+ */
+
+const struct Curl_handler Curl_handler_file = {
+  "FILE",                               /* scheme */
+  file_setup_connection,                /* setup_connection */
+  file_do,                              /* do_it */
+  file_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  file_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  file_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  0,                                    /* defport */
+  CURLPROTO_FILE,                       /* protocol */
+  PROTOPT_NONETWORK | PROTOPT_NOURLQUERY /* flags */
+};
+
+
+static CURLcode file_setup_connection(struct connectdata *conn)
+{
+  /* allocate the FILE specific struct */
+  conn->data->req.protop = calloc(1, sizeof(struct FILEPROTO));
+  if(!conn->data->req.protop)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+ /*
+  Check if this is a range download, and if so, set the internal variables
+  properly. This code is copied from the FTP implementation and might as
+  well be factored out.
+ */
+static CURLcode file_range(struct connectdata *conn)
+{
+  curl_off_t from, to;
+  curl_off_t totalsize=-1;
+  char *ptr;
+  char *ptr2;
+  struct SessionHandle *data = conn->data;
+
+  if(data->state.use_range && data->state.range) {
+    from=curlx_strtoofft(data->state.range, &ptr, 0);
+    while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
+      ptr++;
+    to=curlx_strtoofft(ptr, &ptr2, 0);
+    if(ptr == ptr2) {
+      /* we didn't get any digit */
+      to=-1;
+    }
+    if((-1 == to) && (from>=0)) {
+      /* X - */
+      data->state.resume_from = from;
+      DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file\n",
+                   from));
+    }
+    else if(from < 0) {
+      /* -Y */
+      data->req.maxdownload = -from;
+      data->state.resume_from = from;
+      DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes\n",
+                   -from));
+    }
+    else {
+      /* X-Y */
+      totalsize = to-from;
+      data->req.maxdownload = totalsize+1; /* include last byte */
+      data->state.resume_from = from;
+      DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T
+                   " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n",
+                   from, data->req.maxdownload));
+    }
+    DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T
+                 " to %" CURL_FORMAT_CURL_OFF_T ", totally %"
+                 CURL_FORMAT_CURL_OFF_T " bytes\n",
+                 from, to, data->req.maxdownload));
+  }
+  else
+    data->req.maxdownload = -1;
+  return CURLE_OK;
+}
+
+/*
+ * file_connect() gets called from Curl_protocol_connect() to allow us to
+ * do protocol-specific actions at connect-time.  We emulate a
+ * connect-then-transfer protocol and "connect" to the file here
+ */
+static CURLcode file_connect(struct connectdata *conn, bool *done)
+{
+  struct SessionHandle *data = conn->data;
+  char *real_path;
+  struct FILEPROTO *file = data->req.protop;
+  int fd;
+#ifdef DOS_FILESYSTEM
+  int i;
+  char *actual_path;
+#endif
+  int real_path_len;
+
+  real_path = curl_easy_unescape(data, data->state.path, 0, &real_path_len);
+  if(!real_path)
+    return CURLE_OUT_OF_MEMORY;
+
+#ifdef DOS_FILESYSTEM
+  /* If the first character is a slash, and there's
+     something that looks like a drive at the beginning of
+     the path, skip the slash.  If we remove the initial
+     slash in all cases, paths without drive letters end up
+     relative to the current directory which isn't how
+     browsers work.
+
+     Some browsers accept | instead of : as the drive letter
+     separator, so we do too.
+
+     On other platforms, we need the slash to indicate an
+     absolute pathname.  On Windows, absolute paths start
+     with a drive letter.
+  */
+  actual_path = real_path;
+  if((actual_path[0] == '/') &&
+      actual_path[1] &&
+     (actual_path[2] == ':' || actual_path[2] == '|')) {
+    actual_path[2] = ':';
+    actual_path++;
+    real_path_len--;
+  }
+
+  /* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
+  for(i=0; i < real_path_len; ++i)
+    if(actual_path[i] == '/')
+      actual_path[i] = '\\';
+    else if(!actual_path[i]) /* binary zero */
+      return CURLE_URL_MALFORMAT;
+
+  fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
+  file->path = actual_path;
+#else
+  if(memchr(real_path, 0, real_path_len))
+    /* binary zeroes indicate foul play */
+    return CURLE_URL_MALFORMAT;
+
+  fd = open_readonly(real_path, O_RDONLY);
+  file->path = real_path;
+#endif
+  file->freepath = real_path; /* free this when done */
+
+  file->fd = fd;
+  if(!data->set.upload && (fd == -1)) {
+    failf(data, "Couldn't open file %s", data->state.path);
+    file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
+    return CURLE_FILE_COULDNT_READ_FILE;
+  }
+  *done = TRUE;
+
+  return CURLE_OK;
+}
+
+static CURLcode file_done(struct connectdata *conn,
+                               CURLcode status, bool premature)
+{
+  struct FILEPROTO *file = conn->data->req.protop;
+  (void)status; /* not used */
+  (void)premature; /* not used */
+
+  if(file) {
+    Curl_safefree(file->freepath);
+    file->path = NULL;
+    if(file->fd != -1)
+      close(file->fd);
+    file->fd = -1;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode file_disconnect(struct connectdata *conn,
+                                bool dead_connection)
+{
+  struct FILEPROTO *file = conn->data->req.protop;
+  (void)dead_connection; /* not used */
+
+  if(file) {
+    Curl_safefree(file->freepath);
+    file->path = NULL;
+    if(file->fd != -1)
+      close(file->fd);
+    file->fd = -1;
+  }
+
+  return CURLE_OK;
+}
+
+#ifdef DOS_FILESYSTEM
+#define DIRSEP '\\'
+#else
+#define DIRSEP '/'
+#endif
+
+static CURLcode file_upload(struct connectdata *conn)
+{
+  struct FILEPROTO *file = conn->data->req.protop;
+  const char *dir = strchr(file->path, DIRSEP);
+  int fd;
+  int mode;
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  char *buf = data->state.buffer;
+  size_t nread;
+  size_t nwrite;
+  curl_off_t bytecount = 0;
+  struct timeval now = Curl_tvnow();
+  struct_stat file_stat;
+  const char* buf2;
+
+  /*
+   * Since FILE: doesn't do the full init, we need to provide some extra
+   * assignments here.
+   */
+  conn->data->req.upload_fromhere = buf;
+
+  if(!dir)
+    return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
+
+  if(!dir[1])
+    return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
+
+#ifdef O_BINARY
+#define MODE_DEFAULT O_WRONLY|O_CREAT|O_BINARY
+#else
+#define MODE_DEFAULT O_WRONLY|O_CREAT
+#endif
+
+  if(data->state.resume_from)
+    mode = MODE_DEFAULT|O_APPEND;
+  else
+    mode = MODE_DEFAULT|O_TRUNC;
+
+  fd = open(file->path, mode, conn->data->set.new_file_perms);
+  if(fd < 0) {
+    failf(data, "Can't open %s for writing", file->path);
+    return CURLE_WRITE_ERROR;
+  }
+
+  if(-1 != data->state.infilesize)
+    /* known size of data to "upload" */
+    Curl_pgrsSetUploadSize(data, data->state.infilesize);
+
+  /* treat the negative resume offset value as the case of "-" */
+  if(data->state.resume_from < 0) {
+    if(fstat(fd, &file_stat)) {
+      close(fd);
+      failf(data, "Can't get the size of %s", file->path);
+      return CURLE_WRITE_ERROR;
+    }
+    else
+      data->state.resume_from = (curl_off_t)file_stat.st_size;
+  }
+
+  while(!result) {
+    int readcount;
+    result = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
+    if(result)
+      break;
+
+    if(readcount <= 0)  /* fix questionable compare error. curlvms */
+      break;
+
+    nread = (size_t)readcount;
+
+    /*skip bytes before resume point*/
+    if(data->state.resume_from) {
+      if((curl_off_t)nread <= data->state.resume_from ) {
+        data->state.resume_from -= nread;
+        nread = 0;
+        buf2 = buf;
+      }
+      else {
+        buf2 = buf + data->state.resume_from;
+        nread -= (size_t)data->state.resume_from;
+        data->state.resume_from = 0;
+      }
+    }
+    else
+      buf2 = buf;
+
+    /* write the data to the target */
+    nwrite = write(fd, buf2, nread);
+    if(nwrite != nread) {
+      result = CURLE_SEND_ERROR;
+      break;
+    }
+
+    bytecount += nread;
+
+    Curl_pgrsSetUploadCounter(data, bytecount);
+
+    if(Curl_pgrsUpdate(conn))
+      result = CURLE_ABORTED_BY_CALLBACK;
+    else
+      result = Curl_speedcheck(data, now);
+  }
+  if(!result && Curl_pgrsUpdate(conn))
+    result = CURLE_ABORTED_BY_CALLBACK;
+
+  close(fd);
+
+  return result;
+}
+
+/*
+ * file_do() is the protocol-specific function for the do-phase, separated
+ * from the connect-phase above. Other protocols merely setup the transfer in
+ * the do-phase, to have it done in the main transfer loop but since some
+ * platforms we support don't allow select()ing etc on file handles (as
+ * opposed to sockets) we instead perform the whole do-operation in this
+ * function.
+ */
+static CURLcode file_do(struct connectdata *conn, bool *done)
+{
+  /* This implementation ignores the host name in conformance with
+     RFC 1738. Only local files (reachable via the standard file system)
+     are supported. This means that files on remotely mounted directories
+     (via NFS, Samba, NT sharing) can be accessed through a file:// URL
+  */
+  CURLcode result = CURLE_OK;
+  struct_stat statbuf; /* struct_stat instead of struct stat just to allow the
+                          Windows version to have a different struct without
+                          having to redefine the simple word 'stat' */
+  curl_off_t expected_size=0;
+  bool fstated=FALSE;
+  ssize_t nread;
+  struct SessionHandle *data = conn->data;
+  char *buf = data->state.buffer;
+  curl_off_t bytecount = 0;
+  int fd;
+  struct timeval now = Curl_tvnow();
+  struct FILEPROTO *file;
+
+  *done = TRUE; /* unconditionally */
+
+  Curl_initinfo(data);
+  Curl_pgrsStartNow(data);
+
+  if(data->set.upload)
+    return file_upload(conn);
+
+  file = conn->data->req.protop;
+
+  /* get the fd from the connection phase */
+  fd = file->fd;
+
+  /* VMS: This only works reliable for STREAMLF files */
+  if(-1 != fstat(fd, &statbuf)) {
+    /* we could stat it, then read out the size */
+    expected_size = statbuf.st_size;
+    /* and store the modification time */
+    data->info.filetime = (long)statbuf.st_mtime;
+    fstated = TRUE;
+  }
+
+  if(fstated && !data->state.range && data->set.timecondition) {
+    if(!Curl_meets_timecondition(data, (time_t)data->info.filetime)) {
+      *done = TRUE;
+      return CURLE_OK;
+    }
+  }
+
+  /* If we have selected NOBODY and HEADER, it means that we only want file
+     information. Which for FILE can't be much more than the file size and
+     date. */
+  if(data->set.opt_no_body && data->set.include_header && fstated) {
+    snprintf(buf, sizeof(data->state.buffer),
+             "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size);
+    result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
+    if(result)
+      return result;
+
+    result = Curl_client_write(conn, CLIENTWRITE_BOTH,
+                               (char *)"Accept-ranges: bytes\r\n", 0);
+    if(result)
+      return result;
+
+    if(fstated) {
+      time_t filetime = (time_t)statbuf.st_mtime;
+      struct tm buffer;
+      const struct tm *tm = &buffer;
+      result = Curl_gmtime(filetime, &buffer);
+      if(result)
+        return result;
+
+      /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
+      snprintf(buf, BUFSIZE-1,
+               "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
+               Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+               tm->tm_mday,
+               Curl_month[tm->tm_mon],
+               tm->tm_year + 1900,
+               tm->tm_hour,
+               tm->tm_min,
+               tm->tm_sec);
+      result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
+    }
+    /* if we fstat()ed the file, set the file size to make it available post-
+       transfer */
+    if(fstated)
+      Curl_pgrsSetDownloadSize(data, expected_size);
+    return result;
+  }
+
+  /* Check whether file range has been specified */
+  file_range(conn);
+
+  /* Adjust the start offset in case we want to get the N last bytes
+   * of the stream iff the filesize could be determined */
+  if(data->state.resume_from < 0) {
+    if(!fstated) {
+      failf(data, "Can't get the size of file.");
+      return CURLE_READ_ERROR;
+    }
+    else
+      data->state.resume_from += (curl_off_t)statbuf.st_size;
+  }
+
+  if(data->state.resume_from <= expected_size)
+    expected_size -= data->state.resume_from;
+  else {
+    failf(data, "failed to resume file:// transfer");
+    return CURLE_BAD_DOWNLOAD_RESUME;
+  }
+
+  /* A high water mark has been specified so we obey... */
+  if(data->req.maxdownload > 0)
+    expected_size = data->req.maxdownload;
+
+  if(fstated && (expected_size == 0))
+    return CURLE_OK;
+
+  /* The following is a shortcut implementation of file reading
+     this is both more efficient than the former call to download() and
+     it avoids problems with select() and recv() on file descriptors
+     in Winsock */
+  if(fstated)
+    Curl_pgrsSetDownloadSize(data, expected_size);
+
+  if(data->state.resume_from) {
+    if(data->state.resume_from !=
+       lseek(fd, data->state.resume_from, SEEK_SET))
+      return CURLE_BAD_DOWNLOAD_RESUME;
+  }
+
+  Curl_pgrsTime(data, TIMER_STARTTRANSFER);
+
+  while(!result) {
+    /* Don't fill a whole buffer if we want less than all data */
+    size_t bytestoread =
+      (expected_size < CURL_OFF_T_C(BUFSIZE) - CURL_OFF_T_C(1)) ?
+      curlx_sotouz(expected_size) : BUFSIZE - 1;
+
+    nread = read(fd, buf, bytestoread);
+
+    if(nread > 0)
+      buf[nread] = 0;
+
+    if(nread <= 0 || expected_size == 0)
+      break;
+
+    bytecount += nread;
+    expected_size -= nread;
+
+    result = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
+    if(result)
+      return result;
+
+    Curl_pgrsSetDownloadCounter(data, bytecount);
+
+    if(Curl_pgrsUpdate(conn))
+      result = CURLE_ABORTED_BY_CALLBACK;
+    else
+      result = Curl_speedcheck(data, now);
+  }
+  if(Curl_pgrsUpdate(conn))
+    result = CURLE_ABORTED_BY_CALLBACK;
+
+  return result;
+}
+
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/lib/file.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/file.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/file.h	(revision 164)
@@ -0,0 +1,41 @@
+#ifndef HEADER_CURL_FILE_H
+#define HEADER_CURL_FILE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+
+/****************************************************************************
+ * FILE unique setup
+ ***************************************************************************/
+struct FILEPROTO {
+  char *path; /* the path we operate on */
+  char *freepath; /* pointer to the allocated block we must free, this might
+                     differ from the 'path' pointer */
+  int fd;     /* open file descriptor to read from! */
+};
+
+#ifndef CURL_DISABLE_FILE
+extern const struct Curl_handler Curl_handler_file;
+#endif
+
+#endif /* HEADER_CURL_FILE_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/fileinfo.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/fileinfo.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/fileinfo.c	(revision 164)
@@ -0,0 +1,50 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "strdup.h"
+#include "fileinfo.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+struct curl_fileinfo *Curl_fileinfo_alloc(void)
+{
+  struct curl_fileinfo *tmp = malloc(sizeof(struct curl_fileinfo));
+  if(!tmp)
+    return NULL;
+  memset(tmp, 0, sizeof(struct curl_fileinfo));
+  return tmp;
+}
+
+void Curl_fileinfo_dtor(void *user, void *element)
+{
+  struct curl_fileinfo *finfo = element;
+  (void) user;
+  if(!finfo)
+    return;
+
+  Curl_safefree(finfo->b_data);
+
+  free(finfo);
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/fileinfo.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/fileinfo.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/fileinfo.h	(revision 164)
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_FILEINFO_H
+#define HEADER_CURL_FILEINFO_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+struct curl_fileinfo *Curl_fileinfo_alloc(void);
+
+void Curl_fileinfo_dtor(void *, void *);
+
+struct curl_fileinfo *Curl_fileinfo_dup(const struct curl_fileinfo *src);
+
+#endif /* HEADER_CURL_FILEINFO_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/formdata.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/formdata.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/formdata.c	(revision 164)
@@ -0,0 +1,1573 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#ifndef CURL_DISABLE_HTTP
+
+#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
+#include <libgen.h>
+#endif
+
+#include "urldata.h" /* for struct SessionHandle */
+#include "formdata.h"
+#include "vtls/vtls.h"
+#include "strequal.h"
+#include "sendf.h"
+#include "strdup.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef HAVE_BASENAME
+static char *Curl_basename(char *path);
+#define basename(x)  Curl_basename((x))
+#endif
+
+static size_t readfromfile(struct Form *form, char *buffer, size_t size);
+static char *formboundary(struct SessionHandle *data);
+
+/* What kind of Content-Type to use on un-specified files with unrecognized
+   extensions. */
+#define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream"
+
+#define FORM_FILE_SEPARATOR ','
+#define FORM_TYPE_SEPARATOR ';'
+
+#define HTTPPOST_PTRNAME CURL_HTTPPOST_PTRNAME
+#define HTTPPOST_FILENAME CURL_HTTPPOST_FILENAME
+#define HTTPPOST_PTRCONTENTS CURL_HTTPPOST_PTRCONTENTS
+#define HTTPPOST_READFILE CURL_HTTPPOST_READFILE
+#define HTTPPOST_PTRBUFFER CURL_HTTPPOST_PTRBUFFER
+#define HTTPPOST_CALLBACK CURL_HTTPPOST_CALLBACK
+#define HTTPPOST_BUFFER CURL_HTTPPOST_BUFFER
+
+/***************************************************************************
+ *
+ * AddHttpPost()
+ *
+ * Adds a HttpPost structure to the list, if parent_post is given becomes
+ * a subpost of parent_post instead of a direct list element.
+ *
+ * Returns newly allocated HttpPost on success and NULL if malloc failed.
+ *
+ ***************************************************************************/
+static struct curl_httppost *
+AddHttpPost(char *name, size_t namelength,
+            char *value, curl_off_t contentslength,
+            char *buffer, size_t bufferlength,
+            char *contenttype,
+            long flags,
+            struct curl_slist* contentHeader,
+            char *showfilename, char *userp,
+            struct curl_httppost *parent_post,
+            struct curl_httppost **httppost,
+            struct curl_httppost **last_post)
+{
+  struct curl_httppost *post;
+  post = calloc(1, sizeof(struct curl_httppost));
+  if(post) {
+    post->name = name;
+    post->namelength = (long)(name?(namelength?namelength:strlen(name)):0);
+    post->contents = value;
+    post->contentlen = contentslength;
+    post->buffer = buffer;
+    post->bufferlength = (long)bufferlength;
+    post->contenttype = contenttype;
+    post->contentheader = contentHeader;
+    post->showfilename = showfilename;
+    post->userp = userp,
+    post->flags = flags | CURL_HTTPPOST_LARGE;
+  }
+  else
+    return NULL;
+
+  if(parent_post) {
+    /* now, point our 'more' to the original 'more' */
+    post->more = parent_post->more;
+
+    /* then move the original 'more' to point to ourselves */
+    parent_post->more = post;
+  }
+  else {
+    /* make the previous point to this */
+    if(*last_post)
+      (*last_post)->next = post;
+    else
+      (*httppost) = post;
+
+    (*last_post) = post;
+  }
+  return post;
+}
+
+/***************************************************************************
+ *
+ * AddFormInfo()
+ *
+ * Adds a FormInfo structure to the list presented by parent_form_info.
+ *
+ * Returns newly allocated FormInfo on success and NULL if malloc failed/
+ * parent_form_info is NULL.
+ *
+ ***************************************************************************/
+static FormInfo * AddFormInfo(char *value,
+                              char *contenttype,
+                              FormInfo *parent_form_info)
+{
+  FormInfo *form_info;
+  form_info = calloc(1, sizeof(struct FormInfo));
+  if(form_info) {
+    if(value)
+      form_info->value = value;
+    if(contenttype)
+      form_info->contenttype = contenttype;
+    form_info->flags = HTTPPOST_FILENAME;
+  }
+  else
+    return NULL;
+
+  if(parent_form_info) {
+    /* now, point our 'more' to the original 'more' */
+    form_info->more = parent_form_info->more;
+
+    /* then move the original 'more' to point to ourselves */
+    parent_form_info->more = form_info;
+  }
+
+  return form_info;
+}
+
+/***************************************************************************
+ *
+ * ContentTypeForFilename()
+ *
+ * Provides content type for filename if one of the known types (else
+ * (either the prevtype or the default is returned).
+ *
+ * Returns some valid contenttype for filename.
+ *
+ ***************************************************************************/
+static const char *ContentTypeForFilename(const char *filename,
+                                          const char *prevtype)
+{
+  const char *contenttype = NULL;
+  unsigned int i;
+  /*
+   * No type was specified, we scan through a few well-known
+   * extensions and pick the first we match!
+   */
+  struct ContentType {
+    const char *extension;
+    const char *type;
+  };
+  static const struct ContentType ctts[]={
+    {".gif",  "image/gif"},
+    {".jpg",  "image/jpeg"},
+    {".jpeg", "image/jpeg"},
+    {".txt",  "text/plain"},
+    {".html", "text/html"},
+    {".xml", "application/xml"}
+  };
+
+  if(prevtype)
+    /* default to the previously set/used! */
+    contenttype = prevtype;
+  else
+    contenttype = HTTPPOST_CONTENTTYPE_DEFAULT;
+
+  if(filename) { /* in case a NULL was passed in */
+    for(i=0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
+      if(strlen(filename) >= strlen(ctts[i].extension)) {
+        if(strequal(filename +
+                    strlen(filename) - strlen(ctts[i].extension),
+                    ctts[i].extension)) {
+          contenttype = ctts[i].type;
+          break;
+        }
+      }
+    }
+  }
+  /* we have a contenttype by now */
+  return contenttype;
+}
+
+/***************************************************************************
+ *
+ * FormAdd()
+ *
+ * Stores a formpost parameter and builds the appropriate linked list.
+ *
+ * Has two principal functionalities: using files and byte arrays as
+ * post parts. Byte arrays are either copied or just the pointer is stored
+ * (as the user requests) while for files only the filename and not the
+ * content is stored.
+ *
+ * While you may have only one byte array for each name, multiple filenames
+ * are allowed (and because of this feature CURLFORM_END is needed after
+ * using CURLFORM_FILE).
+ *
+ * Examples:
+ *
+ * Simple name/value pair with copied contents:
+ * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
+ * CURLFORM_COPYCONTENTS, "value", CURLFORM_END);
+ *
+ * name/value pair where only the content pointer is remembered:
+ * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
+ * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END);
+ * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used)
+ *
+ * storing a filename (CONTENTTYPE is optional!):
+ * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
+ * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text",
+ * CURLFORM_END);
+ *
+ * storing multiple filenames:
+ * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
+ * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END);
+ *
+ * Returns:
+ * CURL_FORMADD_OK             on success
+ * CURL_FORMADD_MEMORY         if the FormInfo allocation fails
+ * CURL_FORMADD_OPTION_TWICE   if one option is given twice for one Form
+ * CURL_FORMADD_NULL           if a null pointer was given for a char
+ * CURL_FORMADD_MEMORY         if the allocation of a FormInfo struct failed
+ * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
+ * CURL_FORMADD_INCOMPLETE     if the some FormInfo is not complete (or error)
+ * CURL_FORMADD_MEMORY         if a HttpPost struct cannot be allocated
+ * CURL_FORMADD_MEMORY         if some allocation for string copying failed.
+ * CURL_FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array
+ *
+ ***************************************************************************/
+
+static
+CURLFORMcode FormAdd(struct curl_httppost **httppost,
+                     struct curl_httppost **last_post,
+                     va_list params)
+{
+  FormInfo *first_form, *current_form, *form = NULL;
+  CURLFORMcode return_value = CURL_FORMADD_OK;
+  const char *prevtype = NULL;
+  struct curl_httppost *post = NULL;
+  CURLformoption option;
+  struct curl_forms *forms = NULL;
+  char *array_value=NULL; /* value read from an array */
+
+  /* This is a state variable, that if TRUE means that we're parsing an
+     array that we got passed to us. If FALSE we're parsing the input
+     va_list arguments. */
+  bool array_state = FALSE;
+
+  /*
+   * We need to allocate the first struct to fill in.
+   */
+  first_form = calloc(1, sizeof(struct FormInfo));
+  if(!first_form)
+    return CURL_FORMADD_MEMORY;
+
+  current_form = first_form;
+
+  /*
+   * Loop through all the options set. Break if we have an error to report.
+   */
+  while(return_value == CURL_FORMADD_OK) {
+
+    /* first see if we have more parts of the array param */
+    if(array_state && forms) {
+      /* get the upcoming option from the given array */
+      option = forms->option;
+      array_value = (char *)forms->value;
+
+      forms++; /* advance this to next entry */
+      if(CURLFORM_END == option) {
+        /* end of array state */
+        array_state = FALSE;
+        continue;
+      }
+    }
+    else {
+      /* This is not array-state, get next option */
+      option = va_arg(params, CURLformoption);
+      if(CURLFORM_END == option)
+        break;
+    }
+
+    switch (option) {
+    case CURLFORM_ARRAY:
+      if(array_state)
+        /* we don't support an array from within an array */
+        return_value = CURL_FORMADD_ILLEGAL_ARRAY;
+      else {
+        forms = va_arg(params, struct curl_forms *);
+        if(forms)
+          array_state = TRUE;
+        else
+          return_value = CURL_FORMADD_NULL;
+      }
+      break;
+
+      /*
+       * Set the Name property.
+       */
+    case CURLFORM_PTRNAME:
+#ifdef CURL_DOES_CONVERSIONS
+      /* Treat CURLFORM_PTR like CURLFORM_COPYNAME so that libcurl will copy
+       * the data in all cases so that we'll have safe memory for the eventual
+       * conversion.
+       */
+#else
+      current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
+#endif
+    case CURLFORM_COPYNAME:
+      if(current_form->name)
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else {
+        char *name = array_state?
+          array_value:va_arg(params, char *);
+        if(name)
+          current_form->name = name; /* store for the moment */
+        else
+          return_value = CURL_FORMADD_NULL;
+      }
+      break;
+    case CURLFORM_NAMELENGTH:
+      if(current_form->namelength)
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else
+        current_form->namelength =
+          array_state?(size_t)array_value:(size_t)va_arg(params, long);
+      break;
+
+      /*
+       * Set the contents property.
+       */
+    case CURLFORM_PTRCONTENTS:
+      current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
+    case CURLFORM_COPYCONTENTS:
+      if(current_form->value)
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else {
+        char *value =
+          array_state?array_value:va_arg(params, char *);
+        if(value)
+          current_form->value = value; /* store for the moment */
+        else
+          return_value = CURL_FORMADD_NULL;
+      }
+      break;
+    case CURLFORM_CONTENTSLENGTH:
+      current_form->contentslength =
+        array_state?(size_t)array_value:(size_t)va_arg(params, long);
+      break;
+
+    case CURLFORM_CONTENTLEN:
+      current_form->flags |= CURL_HTTPPOST_LARGE;
+      current_form->contentslength =
+        array_state?(curl_off_t)array_value:va_arg(params, curl_off_t);
+      break;
+
+      /* Get contents from a given file name */
+    case CURLFORM_FILECONTENT:
+      if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else {
+        const char *filename = array_state?
+          array_value:va_arg(params, char *);
+        if(filename) {
+          current_form->value = strdup(filename);
+          if(!current_form->value)
+            return_value = CURL_FORMADD_MEMORY;
+          else {
+            current_form->flags |= HTTPPOST_READFILE;
+            current_form->value_alloc = TRUE;
+          }
+        }
+        else
+          return_value = CURL_FORMADD_NULL;
+      }
+      break;
+
+      /* We upload a file */
+    case CURLFORM_FILE:
+      {
+        const char *filename = array_state?array_value:
+          va_arg(params, char *);
+
+        if(current_form->value) {
+          if(current_form->flags & HTTPPOST_FILENAME) {
+            if(filename) {
+              char *fname = strdup(filename);
+              if(!fname)
+                return_value = CURL_FORMADD_MEMORY;
+              else {
+                form = AddFormInfo(fname, NULL, current_form);
+                if(!form) {
+                  free(fname);
+                  return_value = CURL_FORMADD_MEMORY;
+                }
+                else {
+                  form->value_alloc = TRUE;
+                  current_form = form;
+                  form = NULL;
+                }
+              }
+            }
+            else
+              return_value = CURL_FORMADD_NULL;
+          }
+          else
+            return_value = CURL_FORMADD_OPTION_TWICE;
+        }
+        else {
+          if(filename) {
+            current_form->value = strdup(filename);
+            if(!current_form->value)
+              return_value = CURL_FORMADD_MEMORY;
+            else {
+              current_form->flags |= HTTPPOST_FILENAME;
+              current_form->value_alloc = TRUE;
+            }
+          }
+          else
+            return_value = CURL_FORMADD_NULL;
+        }
+        break;
+      }
+
+    case CURLFORM_BUFFERPTR:
+      current_form->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER;
+      if(current_form->buffer)
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else {
+        char *buffer =
+          array_state?array_value:va_arg(params, char *);
+        if(buffer) {
+          current_form->buffer = buffer; /* store for the moment */
+          current_form->value = buffer; /* make it non-NULL to be accepted
+                                           as fine */
+        }
+        else
+          return_value = CURL_FORMADD_NULL;
+      }
+      break;
+
+    case CURLFORM_BUFFERLENGTH:
+      if(current_form->bufferlength)
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else
+        current_form->bufferlength =
+          array_state?(size_t)array_value:(size_t)va_arg(params, long);
+      break;
+
+    case CURLFORM_STREAM:
+      current_form->flags |= HTTPPOST_CALLBACK;
+      if(current_form->userp)
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else {
+        char *userp =
+          array_state?array_value:va_arg(params, char *);
+        if(userp) {
+          current_form->userp = userp;
+          current_form->value = userp; /* this isn't strictly true but we
+                                          derive a value from this later on
+                                          and we need this non-NULL to be
+                                          accepted as a fine form part */
+        }
+        else
+          return_value = CURL_FORMADD_NULL;
+      }
+      break;
+
+    case CURLFORM_CONTENTTYPE:
+      {
+        const char *contenttype =
+          array_state?array_value:va_arg(params, char *);
+        if(current_form->contenttype) {
+          if(current_form->flags & HTTPPOST_FILENAME) {
+            if(contenttype) {
+              char *type = strdup(contenttype);
+              if(!type)
+                return_value = CURL_FORMADD_MEMORY;
+              else {
+                form = AddFormInfo(NULL, type, current_form);
+                if(!form) {
+                  free(type);
+                  return_value = CURL_FORMADD_MEMORY;
+                }
+                else {
+                  form->contenttype_alloc = TRUE;
+                  current_form = form;
+                  form = NULL;
+                }
+              }
+            }
+            else
+              return_value = CURL_FORMADD_NULL;
+          }
+          else
+            return_value = CURL_FORMADD_OPTION_TWICE;
+        }
+        else {
+          if(contenttype) {
+            current_form->contenttype = strdup(contenttype);
+            if(!current_form->contenttype)
+              return_value = CURL_FORMADD_MEMORY;
+            else
+              current_form->contenttype_alloc = TRUE;
+          }
+          else
+            return_value = CURL_FORMADD_NULL;
+        }
+        break;
+      }
+    case CURLFORM_CONTENTHEADER:
+      {
+        /* this "cast increases required alignment of target type" but
+           we consider it OK anyway */
+        struct curl_slist* list = array_state?
+          (struct curl_slist*)(void*)array_value:
+          va_arg(params, struct curl_slist*);
+
+        if(current_form->contentheader)
+          return_value = CURL_FORMADD_OPTION_TWICE;
+        else
+          current_form->contentheader = list;
+
+        break;
+      }
+    case CURLFORM_FILENAME:
+    case CURLFORM_BUFFER:
+      {
+        const char *filename = array_state?array_value:
+          va_arg(params, char *);
+        if(current_form->showfilename)
+          return_value = CURL_FORMADD_OPTION_TWICE;
+        else {
+          current_form->showfilename = strdup(filename);
+          if(!current_form->showfilename)
+            return_value = CURL_FORMADD_MEMORY;
+          else
+            current_form->showfilename_alloc = TRUE;
+        }
+        break;
+      }
+    default:
+      return_value = CURL_FORMADD_UNKNOWN_OPTION;
+      break;
+    }
+  }
+
+  if(CURL_FORMADD_OK != return_value) {
+    /* On error, free allocated fields for all nodes of the FormInfo linked
+       list without deallocating nodes. List nodes are deallocated later on */
+    FormInfo *ptr;
+    for(ptr = first_form; ptr != NULL; ptr = ptr->more) {
+      if(ptr->name_alloc) {
+        Curl_safefree(ptr->name);
+        ptr->name_alloc = FALSE;
+      }
+      if(ptr->value_alloc) {
+        Curl_safefree(ptr->value);
+        ptr->value_alloc = FALSE;
+      }
+      if(ptr->contenttype_alloc) {
+        Curl_safefree(ptr->contenttype);
+        ptr->contenttype_alloc = FALSE;
+      }
+      if(ptr->showfilename_alloc) {
+        Curl_safefree(ptr->showfilename);
+        ptr->showfilename_alloc = FALSE;
+      }
+    }
+  }
+
+  if(CURL_FORMADD_OK == return_value) {
+    /* go through the list, check for completeness and if everything is
+     * alright add the HttpPost item otherwise set return_value accordingly */
+
+    post = NULL;
+    for(form = first_form;
+        form != NULL;
+        form = form->more) {
+      if(((!form->name || !form->value) && !post) ||
+         ( (form->contentslength) &&
+           (form->flags & HTTPPOST_FILENAME) ) ||
+         ( (form->flags & HTTPPOST_FILENAME) &&
+           (form->flags & HTTPPOST_PTRCONTENTS) ) ||
+
+         ( (!form->buffer) &&
+           (form->flags & HTTPPOST_BUFFER) &&
+           (form->flags & HTTPPOST_PTRBUFFER) ) ||
+
+         ( (form->flags & HTTPPOST_READFILE) &&
+           (form->flags & HTTPPOST_PTRCONTENTS) )
+        ) {
+        return_value = CURL_FORMADD_INCOMPLETE;
+        break;
+      }
+      else {
+        if(((form->flags & HTTPPOST_FILENAME) ||
+            (form->flags & HTTPPOST_BUFFER)) &&
+           !form->contenttype ) {
+          char *f = form->flags & HTTPPOST_BUFFER?
+            form->showfilename : form->value;
+
+          /* our contenttype is missing */
+          form->contenttype = strdup(ContentTypeForFilename(f, prevtype));
+          if(!form->contenttype) {
+            return_value = CURL_FORMADD_MEMORY;
+            break;
+          }
+          form->contenttype_alloc = TRUE;
+        }
+        if(!(form->flags & HTTPPOST_PTRNAME) &&
+           (form == first_form) ) {
+          /* Note that there's small risk that form->name is NULL here if the
+             app passed in a bad combo, so we better check for that first. */
+          if(form->name) {
+            /* copy name (without strdup; possibly contains null characters) */
+            form->name = Curl_memdup(form->name, form->namelength?
+                                     form->namelength:
+                                     strlen(form->name)+1);
+          }
+          if(!form->name) {
+            return_value = CURL_FORMADD_MEMORY;
+            break;
+          }
+          form->name_alloc = TRUE;
+        }
+        if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
+                            HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
+                            HTTPPOST_CALLBACK)) && form->value) {
+          /* copy value (without strdup; possibly contains null characters) */
+          size_t clen  = (size_t) form->contentslength;
+          if(!clen)
+            clen = strlen(form->value)+1;
+
+          form->value = Curl_memdup(form->value, clen);
+
+          if(!form->value) {
+            return_value = CURL_FORMADD_MEMORY;
+            break;
+          }
+          form->value_alloc = TRUE;
+        }
+        post = AddHttpPost(form->name, form->namelength,
+                           form->value, form->contentslength,
+                           form->buffer, form->bufferlength,
+                           form->contenttype, form->flags,
+                           form->contentheader, form->showfilename,
+                           form->userp,
+                           post, httppost,
+                           last_post);
+
+        if(!post) {
+          return_value = CURL_FORMADD_MEMORY;
+          break;
+        }
+
+        if(form->contenttype)
+          prevtype = form->contenttype;
+      }
+    }
+    if(CURL_FORMADD_OK != return_value) {
+      /* On error, free allocated fields for nodes of the FormInfo linked
+         list which are not already owned by the httppost linked list
+         without deallocating nodes. List nodes are deallocated later on */
+      FormInfo *ptr;
+      for(ptr = form; ptr != NULL; ptr = ptr->more) {
+        if(ptr->name_alloc) {
+          Curl_safefree(ptr->name);
+          ptr->name_alloc = FALSE;
+        }
+        if(ptr->value_alloc) {
+          Curl_safefree(ptr->value);
+          ptr->value_alloc = FALSE;
+        }
+        if(ptr->contenttype_alloc) {
+          Curl_safefree(ptr->contenttype);
+          ptr->contenttype_alloc = FALSE;
+        }
+        if(ptr->showfilename_alloc) {
+          Curl_safefree(ptr->showfilename);
+          ptr->showfilename_alloc = FALSE;
+        }
+      }
+    }
+  }
+
+  /* Always deallocate FormInfo linked list nodes without touching node
+     fields given that these have either been deallocated or are owned
+     now by the httppost linked list */
+  while(first_form) {
+    FormInfo *ptr = first_form->more;
+    free(first_form);
+    first_form = ptr;
+  }
+
+  return return_value;
+}
+
+/*
+ * curl_formadd() is a public API to add a section to the multipart formpost.
+ *
+ * @unittest: 1308
+ */
+
+CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+                          struct curl_httppost **last_post,
+                          ...)
+{
+  va_list arg;
+  CURLFORMcode result;
+  va_start(arg, last_post);
+  result = FormAdd(httppost, last_post, arg);
+  va_end(arg);
+  return result;
+}
+
+#ifdef __VMS
+#include <fabdef.h>
+/*
+ * get_vms_file_size does what it takes to get the real size of the file
+ *
+ * For fixed files, find out the size of the EOF block and adjust.
+ *
+ * For all others, have to read the entire file in, discarding the contents.
+ * Most posted text files will be small, and binary files like zlib archives
+ * and CD/DVD images should be either a STREAM_LF format or a fixed format.
+ *
+ */
+curl_off_t VmsRealFileSize(const char * name,
+                           const struct_stat * stat_buf)
+{
+  char buffer[8192];
+  curl_off_t count;
+  int ret_stat;
+  FILE * file;
+
+  file = fopen(name, "r"); /* VMS */
+  if(file == NULL)
+    return 0;
+
+  count = 0;
+  ret_stat = 1;
+  while(ret_stat > 0) {
+    ret_stat = fread(buffer, 1, sizeof(buffer), file);
+    if(ret_stat != 0)
+      count += ret_stat;
+  }
+  fclose(file);
+
+  return count;
+}
+
+/*
+ *
+ *  VmsSpecialSize checks to see if the stat st_size can be trusted and
+ *  if not to call a routine to get the correct size.
+ *
+ */
+static curl_off_t VmsSpecialSize(const char * name,
+                                 const struct_stat * stat_buf)
+{
+  switch(stat_buf->st_fab_rfm) {
+  case FAB$C_VAR:
+  case FAB$C_VFC:
+    return VmsRealFileSize(name, stat_buf);
+    break;
+  default:
+    return stat_buf->st_size;
+  }
+}
+
+#endif
+
+#ifndef __VMS
+#define filesize(name, stat_data) (stat_data.st_size)
+#else
+    /* Getting the expected file size needs help on VMS */
+#define filesize(name, stat_data) VmsSpecialSize(name, &stat_data)
+#endif
+
+/*
+ * AddFormData() adds a chunk of data to the FormData linked list.
+ *
+ * size is incremented by the chunk length, unless it is NULL
+ */
+static CURLcode AddFormData(struct FormData **formp,
+                            enum formtype type,
+                            const void *line,
+                            curl_off_t length,
+                            curl_off_t *size)
+{
+  struct FormData *newform = malloc(sizeof(struct FormData));
+  if(!newform)
+    return CURLE_OUT_OF_MEMORY;
+  newform->next = NULL;
+
+  if(length < 0 || (size && *size < 0))
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  if(type <= FORM_CONTENT) {
+    /* we make it easier for plain strings: */
+    if(!length)
+      length = strlen((char *)line);
+#if (SIZEOF_SIZE_T < CURL_SIZEOF_CURL_OFF_T)
+    else if(length >= (curl_off_t)(size_t)-1)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+#endif
+
+    newform->line = malloc((size_t)length+1);
+    if(!newform->line) {
+      free(newform);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    memcpy(newform->line, line, (size_t)length);
+    newform->length = (size_t)length;
+    newform->line[(size_t)length]=0; /* zero terminate for easier debugging */
+  }
+  else
+    /* For callbacks and files we don't have any actual data so we just keep a
+       pointer to whatever this points to */
+    newform->line = (char *)line;
+
+  newform->type = type;
+
+  if(*formp) {
+    (*formp)->next = newform;
+    *formp = newform;
+  }
+  else
+    *formp = newform;
+
+  if(size) {
+    if(type != FORM_FILE)
+      /* for static content as well as callback data we add the size given
+         as input argument */
+      *size += length;
+    else {
+      /* Since this is a file to be uploaded here, add the size of the actual
+         file */
+      if(!strequal("-", newform->line)) {
+        FILINFO file;
+        if(!f_stat(newform->line, &file) && ((file.fattrib & AM_DIR) == 0))
+          *size += f_size(&file);
+        else
+          return CURLE_BAD_FUNCTION_ARGUMENT;
+      }
+    }
+  }
+  return CURLE_OK;
+}
+
+/*
+ * AddFormDataf() adds printf()-style formatted data to the formdata chain.
+ */
+
+static CURLcode AddFormDataf(struct FormData **formp,
+                             curl_off_t *size,
+                             const char *fmt, ...)
+{
+  char s[1024/*4096*/];
+  va_list ap;
+  va_start(ap, fmt);
+  vsnprintf(s, sizeof(s), fmt, ap);
+  va_end(ap);
+
+  return AddFormData(formp, FORM_DATA, s, 0, size);
+}
+
+/*
+ * Curl_formclean() is used from http.c, this cleans a built FormData linked
+ * list
+ */
+void Curl_formclean(struct FormData **form_ptr)
+{
+  struct FormData *next, *form;
+
+  form = *form_ptr;
+  if(!form)
+    return;
+
+  do {
+    next=form->next;  /* the following form line */
+    if(form->type <= FORM_CONTENT)
+      free(form->line); /* free the line */
+    free(form);       /* free the struct */
+
+  } while((form = next) != NULL); /* continue */
+
+  *form_ptr = NULL;
+}
+
+/*
+ * curl_formget()
+ * Serialize a curl_httppost struct.
+ * Returns 0 on success.
+ *
+ * @unittest: 1308
+ */
+int curl_formget(struct curl_httppost *form, void *arg,
+                 curl_formget_callback append)
+{
+  CURLcode result;
+  curl_off_t size;
+  struct FormData *data, *ptr;
+
+  result = Curl_getformdata(NULL, &data, form, NULL, &size);
+  if(result)
+    return (int)result;
+
+  for(ptr = data; ptr; ptr = ptr->next) {
+    if((ptr->type == FORM_FILE) || (ptr->type == FORM_CALLBACK)) {
+      char buffer[2048/*8192*/];
+      size_t nread;
+      struct Form temp;
+
+      Curl_FormInit(&temp, ptr);
+
+      do {
+        nread = readfromfile(&temp, buffer, sizeof(buffer));
+        if((nread == (size_t) -1) ||
+           (nread > sizeof(buffer)) ||
+           (nread != append(arg, buffer, nread))) {
+          if(temp.fp)
+            fclose(temp.fp);
+          Curl_formclean(&data);
+          return -1;
+        }
+      } while(nread);
+    }
+    else {
+      if(ptr->length != append(arg, ptr->line, ptr->length)) {
+        Curl_formclean(&data);
+        return -1;
+      }
+    }
+  }
+  Curl_formclean(&data);
+  return 0;
+}
+
+/*
+ * curl_formfree() is an external function to free up a whole form post
+ * chain
+ */
+void curl_formfree(struct curl_httppost *form)
+{
+  struct curl_httppost *next;
+
+  if(!form)
+    /* no form to free, just get out of this */
+    return;
+
+  do {
+    next=form->next;  /* the following form line */
+
+    /* recurse to sub-contents */
+    curl_formfree(form->more);
+
+    if(!(form->flags & HTTPPOST_PTRNAME))
+      free(form->name); /* free the name */
+    if(!(form->flags &
+         (HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK))
+      )
+      free(form->contents); /* free the contents */
+    free(form->contenttype); /* free the content type */
+    free(form->showfilename); /* free the faked file name */
+    free(form);       /* free the struct */
+
+  } while((form = next) != NULL); /* continue */
+}
+
+#ifndef HAVE_BASENAME
+/*
+  (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004
+  Edition)
+
+  The basename() function shall take the pathname pointed to by path and
+  return a pointer to the final component of the pathname, deleting any
+  trailing '/' characters.
+
+  If the string pointed to by path consists entirely of the '/' character,
+  basename() shall return a pointer to the string "/". If the string pointed
+  to by path is exactly "//", it is implementation-defined whether '/' or "//"
+  is returned.
+
+  If path is a null pointer or points to an empty string, basename() shall
+  return a pointer to the string ".".
+
+  The basename() function may modify the string pointed to by path, and may
+  return a pointer to static storage that may then be overwritten by a
+  subsequent call to basename().
+
+  The basename() function need not be reentrant. A function that is not
+  required to be reentrant is not required to be thread-safe.
+
+*/
+static char *Curl_basename(char *path)
+{
+  /* Ignore all the details above for now and make a quick and simple
+     implementaion here */
+  char *s1;
+  char *s2;
+
+  s1=strrchr(path, '/');
+  s2=strrchr(path, '\\');
+
+  if(s1 && s2) {
+    path = (s1 > s2? s1 : s2)+1;
+  }
+  else if(s1)
+    path = s1 + 1;
+  else if(s2)
+    path = s2 + 1;
+
+  return path;
+}
+#endif
+
+static char *strippath(const char *fullfile)
+{
+  char *filename;
+  char *base;
+  filename = strdup(fullfile); /* duplicate since basename() may ruin the
+                                  buffer it works on */
+  if(!filename)
+    return NULL;
+  base = strdup(basename(filename));
+
+  free(filename); /* free temporary buffer */
+
+  return base; /* returns an allocated string or NULL ! */
+}
+
+static CURLcode formdata_add_filename(const struct curl_httppost *file,
+                                      struct FormData **form,
+                                      curl_off_t *size)
+{
+  CURLcode result = CURLE_OK;
+  char *filename = file->showfilename;
+  char *filebasename = NULL;
+  char *filename_escaped = NULL;
+
+  if(!filename) {
+    filebasename = strippath(file->contents);
+    if(!filebasename)
+      return CURLE_OUT_OF_MEMORY;
+    filename = filebasename;
+  }
+
+  if(strchr(filename, '\\') || strchr(filename, '"')) {
+    char *p0, *p1;
+
+    /* filename need be escaped */
+    filename_escaped = malloc(strlen(filename)*2+1);
+    if(!filename_escaped) {
+      free(filebasename);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    p0 = filename_escaped;
+    p1 = filename;
+    while(*p1) {
+      if(*p1 == '\\' || *p1 == '"')
+        *p0++ = '\\';
+      *p0++ = *p1++;
+    }
+    *p0 = '\0';
+    filename = filename_escaped;
+  }
+  result = AddFormDataf(form, size,
+                        "; filename=\"%s\"",
+                        filename);
+  free(filename_escaped);
+  free(filebasename);
+  return result;
+}
+
+/*
+ * Curl_getformdata() converts a linked list of "meta data" into a complete
+ * (possibly huge) multipart formdata. The input list is in 'post', while the
+ * output resulting linked lists gets stored in '*finalform'. *sizep will get
+ * the total size of the whole POST.
+ * A multipart/form_data content-type is built, unless a custom content-type
+ * is passed in 'custom_content_type'.
+ *
+ * This function will not do a failf() for the potential memory failures but
+ * should for all other errors it spots. Just note that this function MAY get
+ * a NULL pointer in the 'data' argument.
+ */
+
+CURLcode Curl_getformdata(struct SessionHandle *data,
+                          struct FormData **finalform,
+                          struct curl_httppost *post,
+                          const char *custom_content_type,
+                          curl_off_t *sizep)
+{
+  struct FormData *form = NULL;
+  struct FormData *firstform;
+  struct curl_httppost *file;
+  CURLcode result = CURLE_OK;
+
+  curl_off_t size = 0; /* support potentially ENORMOUS formposts */
+  char *boundary;
+  char *fileboundary = NULL;
+  struct curl_slist* curList;
+
+  *finalform = NULL; /* default form is empty */
+
+  if(!post)
+    return result; /* no input => no output! */
+
+  boundary = formboundary(data);
+  if(!boundary)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Make the first line of the output */
+  result = AddFormDataf(&form, NULL,
+                        "%s; boundary=%s\r\n",
+                        custom_content_type?custom_content_type:
+                        "Content-Type: multipart/form-data",
+                        boundary);
+
+  if(result) {
+    free(boundary);
+    return result;
+  }
+  /* we DO NOT include that line in the total size of the POST, since it'll be
+     part of the header! */
+
+  firstform = form;
+
+  do {
+
+    if(size) {
+      result = AddFormDataf(&form, &size, "\r\n");
+      if(result)
+        break;
+    }
+
+    /* boundary */
+    result = AddFormDataf(&form, &size, "--%s\r\n", boundary);
+    if(result)
+      break;
+
+    /* Maybe later this should be disabled when a custom_content_type is
+       passed, since Content-Disposition is not meaningful for all multipart
+       types.
+    */
+    result = AddFormDataf(&form, &size,
+                          "Content-Disposition: form-data; name=\"");
+    if(result)
+      break;
+
+    result = AddFormData(&form, FORM_DATA, post->name, post->namelength,
+                         &size);
+    if(result)
+      break;
+
+    result = AddFormDataf(&form, &size, "\"");
+    if(result)
+      break;
+
+    if(post->more) {
+      /* If used, this is a link to more file names, we must then do
+         the magic to include several files with the same field name */
+
+      free(fileboundary);
+      fileboundary = formboundary(data);
+      if(!fileboundary) {
+        result = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+
+      result = AddFormDataf(&form, &size,
+                            "\r\nContent-Type: multipart/mixed;"
+                            " boundary=%s\r\n",
+                            fileboundary);
+      if(result)
+        break;
+    }
+
+    file = post;
+
+    do {
+
+      /* If 'showfilename' is set, that is a faked name passed on to us
+         to use to in the formpost. If that is not set, the actually used
+         local file name should be added. */
+
+      if(post->more) {
+        /* if multiple-file */
+        result = AddFormDataf(&form, &size,
+                              "\r\n--%s\r\nContent-Disposition: "
+                              "attachment",
+                              fileboundary);
+        if(result)
+          break;
+        result = formdata_add_filename(file, &form, &size);
+        if(result)
+          break;
+      }
+      else if(post->flags & (HTTPPOST_FILENAME|HTTPPOST_BUFFER|
+                             HTTPPOST_CALLBACK)) {
+        /* it should be noted that for the HTTPPOST_FILENAME and
+           HTTPPOST_CALLBACK cases the ->showfilename struct member is always
+           assigned at this point */
+        if(post->showfilename || (post->flags & HTTPPOST_FILENAME)) {
+          result = formdata_add_filename(post, &form, &size);
+        }
+
+        if(result)
+          break;
+      }
+
+      if(file->contenttype) {
+        /* we have a specified type */
+        result = AddFormDataf(&form, &size,
+                              "\r\nContent-Type: %s",
+                              file->contenttype);
+        if(result)
+          break;
+      }
+
+      curList = file->contentheader;
+      while(curList) {
+        /* Process the additional headers specified for this form */
+        result = AddFormDataf( &form, &size, "\r\n%s", curList->data );
+        if(result)
+          break;
+        curList = curList->next;
+      }
+      if(result)
+        break;
+
+      result = AddFormDataf(&form, &size, "\r\n\r\n");
+      if(result)
+        break;
+
+      if((post->flags & HTTPPOST_FILENAME) ||
+         (post->flags & HTTPPOST_READFILE)) {
+        /* we should include the contents from the specified file */
+        FILE *fileread;
+
+        fileread = strequal("-", file->contents)?
+          stdin:fopen(file->contents, "rb"); /* binary read for win32  */
+
+        /*
+         * VMS: This only allows for stream files on VMS.  Stream files are
+         * OK, as are FIXED & VAR files WITHOUT implied CC For implied CC,
+         * every record needs to have a \n appended & 1 added to SIZE
+         */
+
+        if(fileread) {
+          if(fileread != stdin) {
+            /* close the file */
+            fclose(fileread);
+            /* add the file name only - for later reading from this */
+            result = AddFormData(&form, FORM_FILE, file->contents, 0, &size);
+          }
+          else {
+            /* When uploading from stdin, we can't know the size of the file,
+             * thus must read the full file as before. We *could* use chunked
+             * transfer-encoding, but that only works for HTTP 1.1 and we
+             * can't be sure we work with such a server.
+             */
+            size_t nread;
+            char buffer[512];
+            while((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
+              result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size);
+              if(result)
+                break;
+            }
+          }
+        }
+        else {
+          if(data)
+            failf(data, "couldn't open file \"%s\"", file->contents);
+          *finalform = NULL;
+          result = CURLE_READ_ERROR;
+        }
+      }
+      else if(post->flags & HTTPPOST_BUFFER)
+        /* include contents of buffer */
+        result = AddFormData(&form, FORM_CONTENT, post->buffer,
+                             post->bufferlength, &size);
+      else if(post->flags & HTTPPOST_CALLBACK)
+        /* the contents should be read with the callback and the size is set
+           with the contentslength */
+        result = AddFormData(&form, FORM_CALLBACK, post->userp,
+                             post->flags&CURL_HTTPPOST_LARGE?
+                             post->contentlen:post->contentslength, &size);
+      else
+        /* include the contents we got */
+        result = AddFormData(&form, FORM_CONTENT, post->contents,
+                             post->flags&CURL_HTTPPOST_LARGE?
+                             post->contentlen:post->contentslength, &size);
+      file = file->more;
+    } while(file && !result); /* for each specified file for this field */
+
+    if(result)
+      break;
+
+    if(post->more) {
+      /* this was a multiple-file inclusion, make a termination file
+         boundary: */
+      result = AddFormDataf(&form, &size,
+                           "\r\n--%s--",
+                           fileboundary);
+      if(result)
+        break;
+    }
+
+  } while((post = post->next) != NULL); /* for each field */
+
+  /* end-boundary for everything */
+  if(!result)
+    result = AddFormDataf(&form, &size, "\r\n--%s--\r\n", boundary);
+
+  if(result) {
+    Curl_formclean(&firstform);
+    free(fileboundary);
+    free(boundary);
+    return result;
+  }
+
+  *sizep = size;
+
+  free(fileboundary);
+  free(boundary);
+
+  *finalform = firstform;
+
+  return result;
+}
+
+/*
+ * Curl_FormInit() inits the struct 'form' points to with the 'formdata'
+ * and resets the 'sent' counter.
+ */
+int Curl_FormInit(struct Form *form, struct FormData *formdata )
+{
+  if(!formdata)
+    return 1; /* error */
+
+  form->data = formdata;
+  form->sent = 0;
+  form->fp = NULL;
+  form->fread_func = ZERO_NULL;
+
+  return 0;
+}
+
+#ifndef __VMS
+# define fopen_read fopen
+#else
+  /*
+   * vmsfopenread
+   *
+   * For upload to work as expected on VMS, different optional
+   * parameters must be added to the fopen command based on
+   * record format of the file.
+   *
+   */
+# define fopen_read vmsfopenread
+static FILE * vmsfopenread(const char *file, const char *mode) {
+  struct_stat statbuf;
+  int result;
+
+  result = stat(file, &statbuf);
+
+  switch (statbuf.st_fab_rfm) {
+  case FAB$C_VAR:
+  case FAB$C_VFC:
+  case FAB$C_STMCR:
+    return fopen(file, "r"); /* VMS */
+    break;
+  default:
+    return fopen(file, "r", "rfm=stmlf", "ctx=stm");
+  }
+}
+#endif
+
+/*
+ * readfromfile()
+ *
+ * The read callback that this function may use can return a value larger than
+ * 'size' (which then this function returns) that indicates a problem and it
+ * must be properly dealt with
+ */
+static size_t readfromfile(struct Form *form, char *buffer,
+                           size_t size)
+{
+  size_t nread;
+  bool callback = (form->data->type == FORM_CALLBACK)?TRUE:FALSE;
+
+  if(callback) {
+    if(form->fread_func == ZERO_NULL)
+      return 0;
+    else
+      nread = form->fread_func(buffer, 1, size, form->data->line);
+  }
+  else {
+    if(!form->fp) {
+      /* this file hasn't yet been opened */
+      form->fp = fopen_read(form->data->line, "rb"); /* b is for binary */
+      if(!form->fp)
+        return (size_t)-1; /* failure */
+    }
+    nread = fread(buffer, 1, size, form->fp);
+  }
+  if(!nread) {
+    /* this is the last chunk from the file, move on */
+    if(form->fp) {
+      fclose(form->fp);
+      form->fp = NULL;
+    }
+    form->data = form->data->next;
+  }
+
+  return nread;
+}
+
+/*
+ * Curl_FormReader() is the fread() emulation function that will be used to
+ * deliver the formdata to the transfer loop and then sent away to the peer.
+ */
+size_t Curl_FormReader(char *buffer,
+                       size_t size,
+                       size_t nitems,
+                       FILE *mydata)
+{
+  struct Form *form;
+  size_t wantedsize;
+  size_t gotsize = 0;
+
+  form=(struct Form *)mydata;
+
+  wantedsize = size * nitems;
+
+  if(!form->data)
+    return 0; /* nothing, error, empty */
+
+  if((form->data->type == FORM_FILE) ||
+     (form->data->type == FORM_CALLBACK)) {
+    gotsize = readfromfile(form, buffer, wantedsize);
+
+    if(gotsize)
+      /* If positive or -1, return. If zero, continue! */
+      return gotsize;
+  }
+  do {
+
+    if((form->data->length - form->sent ) > wantedsize - gotsize) {
+
+      memcpy(buffer + gotsize , form->data->line + form->sent,
+             wantedsize - gotsize);
+
+      form->sent += wantedsize-gotsize;
+
+      return wantedsize;
+    }
+
+    memcpy(buffer+gotsize,
+           form->data->line + form->sent,
+           (form->data->length - form->sent) );
+    gotsize += form->data->length - form->sent;
+
+    form->sent = 0;
+
+    form->data = form->data->next; /* advance */
+
+  } while(form->data && (form->data->type < FORM_CALLBACK));
+  /* If we got an empty line and we have more data, we proceed to the next
+     line immediately to avoid returning zero before we've reached the end. */
+
+  return gotsize;
+}
+
+/*
+ * Curl_formpostheader() returns the first line of the formpost, the
+ * request-header part (which is not part of the request-body like the rest of
+ * the post).
+ */
+char *Curl_formpostheader(void *formp, size_t *len)
+{
+  char *header;
+  struct Form *form=(struct Form *)formp;
+
+  if(!form->data)
+    return 0; /* nothing, ERROR! */
+
+  header = form->data->line;
+  *len = form->data->length;
+
+  form->data = form->data->next; /* advance */
+
+  return header;
+}
+
+/*
+ * formboundary() creates a suitable boundary string and returns an allocated
+ * one.
+ */
+static char *formboundary(struct SessionHandle *data)
+{
+  /* 24 dashes and 16 hexadecimal digits makes 64 bit (18446744073709551615)
+     combinations */
+  return aprintf("------------------------%08x%08x",
+                 Curl_rand(data), Curl_rand(data));
+}
+
+#else  /* CURL_DISABLE_HTTP */
+CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+                          struct curl_httppost **last_post,
+                          ...)
+{
+  (void)httppost;
+  (void)last_post;
+  return CURL_FORMADD_DISABLED;
+}
+
+int curl_formget(struct curl_httppost *form, void *arg,
+                 curl_formget_callback append)
+{
+  (void) form;
+  (void) arg;
+  (void) append;
+  return CURL_FORMADD_DISABLED;
+}
+
+void curl_formfree(struct curl_httppost *form)
+{
+  (void)form;
+  /* does nothing HTTP is disabled */
+}
+
+
+#endif  /* !defined(CURL_DISABLE_HTTP) */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/formdata.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/formdata.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/formdata.h	(revision 164)
@@ -0,0 +1,98 @@
+#ifndef HEADER_CURL_FORMDATA_H
+#define HEADER_CURL_FORMDATA_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+enum formtype {
+  FORM_DATA,    /* form metadata (convert to network encoding if necessary) */
+  FORM_CONTENT, /* form content  (never convert) */
+  FORM_CALLBACK, /* 'line' points to the custom pointer we pass to the callback
+                  */
+  FORM_FILE     /* 'line' points to a file name we should read from
+                   to create the form data (never convert) */
+};
+
+/* plain and simple linked list with lines to send */
+struct FormData {
+  struct FormData *next;
+  enum formtype type;
+  char *line;
+  size_t length;
+};
+
+struct Form {
+  struct FormData *data; /* current form line to send */
+  size_t sent;           /* number of bytes of the current line that has
+                            already been sent in a previous invoke */
+  FILE *fp;              /* file to read from */
+  curl_read_callback fread_func; /* fread callback pointer */
+};
+
+/* used by FormAdd for temporary storage */
+typedef struct FormInfo {
+  char *name;
+  bool name_alloc;
+  size_t namelength;
+  char *value;
+  bool value_alloc;
+  curl_off_t contentslength;
+  char *contenttype;
+  bool contenttype_alloc;
+  long flags;
+  char *buffer;      /* pointer to existing buffer used for file upload */
+  size_t bufferlength;
+  char *showfilename; /* The file name to show. If not set, the actual
+                         file name will be used */
+  bool showfilename_alloc;
+  char *userp;        /* pointer for the read callback */
+  struct curl_slist* contentheader;
+  struct FormInfo *more;
+} FormInfo;
+
+int Curl_FormInit(struct Form *form, struct FormData *formdata );
+
+CURLcode Curl_getformdata(struct SessionHandle *data,
+                          struct FormData **,
+                          struct curl_httppost *post,
+                          const char *custom_contenttype,
+                          curl_off_t *size);
+
+/* fread() emulation */
+size_t Curl_FormReader(char *buffer,
+                       size_t size,
+                       size_t nitems,
+                       FILE *mydata);
+
+/*
+ * Curl_formpostheader() returns the first line of the formpost, the
+ * request-header part (which is not part of the request-body like the rest of
+ * the post).
+ */
+char *Curl_formpostheader(void *formp, size_t *len);
+
+char *Curl_FormBoundary(void);
+
+void Curl_formclean(struct FormData **);
+
+CURLcode Curl_formconvert(struct SessionHandle *, struct FormData *);
+
+#endif /* HEADER_CURL_FORMDATA_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/ftp.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/ftp.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/ftp.c	(revision 164)
@@ -0,0 +1,4619 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FTP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "if2ip.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "socks.h"
+#include "ftp.h"
+#include "fileinfo.h"
+#include "ftplistparser.h"
+#include "curl_sec.h"
+#include "strtoofft.h"
+#include "strequal.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "inet_ntop.h"
+#include "inet_pton.h"
+#include "select.h"
+#include "parsedate.h" /* for the week day and month names */
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "multiif.h"
+#include "url.h"
+#include "rawstr.h"
+#include "speedcheck.h"
+#include "warnless.h"
+#include "http_proxy.h"
+#include "non-ascii.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#endif
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+#define ftp_pasv_verbose(a,b,c,d)  Curl_nop_stmt
+#endif
+
+/* Local API functions */
+#ifndef DEBUGBUILD
+static void _state(struct connectdata *conn,
+                   ftpstate newstate);
+#define state(x,y) _state(x,y)
+#else
+static void _state(struct connectdata *conn,
+                   ftpstate newstate,
+                   int lineno);
+#define state(x,y) _state(x,y,__LINE__)
+#endif
+
+static CURLcode ftp_sendquote(struct connectdata *conn,
+                              struct curl_slist *quote);
+static CURLcode ftp_quit(struct connectdata *conn);
+static CURLcode ftp_parse_url_path(struct connectdata *conn);
+static CURLcode ftp_regular_transfer(struct connectdata *conn, bool *done);
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static void ftp_pasv_verbose(struct connectdata *conn,
+                             Curl_addrinfo *ai,
+                             char *newhost, /* ascii version */
+                             int port);
+#endif
+static CURLcode ftp_state_prepare_transfer(struct connectdata *conn);
+static CURLcode ftp_state_mdtm(struct connectdata *conn);
+static CURLcode ftp_state_quote(struct connectdata *conn,
+                                bool init, ftpstate instate);
+static CURLcode ftp_nb_type(struct connectdata *conn,
+                            bool ascii, ftpstate newstate);
+static int ftp_need_type(struct connectdata *conn,
+                         bool ascii);
+static CURLcode ftp_do(struct connectdata *conn, bool *done);
+static CURLcode ftp_done(struct connectdata *conn,
+                         CURLcode, bool premature);
+static CURLcode ftp_connect(struct connectdata *conn, bool *done);
+static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection);
+static CURLcode ftp_do_more(struct connectdata *conn, int *completed);
+static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done);
+static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks,
+                       int numsocks);
+static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
+                              int numsocks);
+static CURLcode ftp_doing(struct connectdata *conn,
+                          bool *dophase_done);
+static CURLcode ftp_setup_connection(struct connectdata * conn);
+
+static CURLcode init_wc_data(struct connectdata *conn);
+static CURLcode wc_statemach(struct connectdata *conn);
+
+static void wc_data_dtor(void *ptr);
+
+static CURLcode ftp_state_retr(struct connectdata *conn, curl_off_t filesize);
+
+static CURLcode ftp_readresp(curl_socket_t sockfd,
+                             struct pingpong *pp,
+                             int *ftpcode,
+                             size_t *size);
+static CURLcode ftp_dophase_done(struct connectdata *conn,
+                                 bool connected);
+
+/* easy-to-use macro: */
+#define PPSENDF(x,y,z)  if((result = Curl_pp_sendf(x,y,z)))     \
+                              return result
+
+
+/*
+ * FTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ftp = {
+  "FTP",                           /* scheme */
+  ftp_setup_connection,            /* setup_connection */
+  ftp_do,                          /* do_it */
+  ftp_done,                        /* done */
+  ftp_do_more,                     /* do_more */
+  ftp_connect,                     /* connect_it */
+  ftp_multi_statemach,             /* connecting */
+  ftp_doing,                       /* doing */
+  ftp_getsock,                     /* proto_getsock */
+  ftp_getsock,                     /* doing_getsock */
+  ftp_domore_getsock,              /* domore_getsock */
+  ZERO_NULL,                       /* perform_getsock */
+  ftp_disconnect,                  /* disconnect */
+  ZERO_NULL,                       /* readwrite */
+  PORT_FTP,                        /* defport */
+  CURLPROTO_FTP,                   /* protocol */
+  PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD
+  | PROTOPT_NOURLQUERY /* flags */
+};
+
+
+#ifdef USE_SSL
+/*
+ * FTPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ftps = {
+  "FTPS",                          /* scheme */
+  ftp_setup_connection,            /* setup_connection */
+  ftp_do,                          /* do_it */
+  ftp_done,                        /* done */
+  ftp_do_more,                     /* do_more */
+  ftp_connect,                     /* connect_it */
+  ftp_multi_statemach,             /* connecting */
+  ftp_doing,                       /* doing */
+  ftp_getsock,                     /* proto_getsock */
+  ftp_getsock,                     /* doing_getsock */
+  ftp_domore_getsock,              /* domore_getsock */
+  ZERO_NULL,                       /* perform_getsock */
+  ftp_disconnect,                  /* disconnect */
+  ZERO_NULL,                       /* readwrite */
+  PORT_FTPS,                       /* defport */
+  CURLPROTO_FTPS,                  /* protocol */
+  PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
+  PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY /* flags */
+};
+#endif
+
+#ifndef CURL_DISABLE_HTTP
+/*
+ * HTTP-proxyed FTP protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_ftp_proxy = {
+  "FTP",                                /* scheme */
+  Curl_http_setup_conn,                 /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_FTP,                             /* defport */
+  CURLPROTO_HTTP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+
+#ifdef USE_SSL
+/*
+ * HTTP-proxyed FTPS protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_ftps_proxy = {
+  "FTPS",                               /* scheme */
+  Curl_http_setup_conn,                 /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_FTPS,                            /* defport */
+  CURLPROTO_HTTP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+#endif
+#endif
+
+
+/*
+ * NOTE: back in the old days, we added code in the FTP code that made NOBODY
+ * requests on files respond with headers passed to the client/stdout that
+ * looked like HTTP ones.
+ *
+ * This approach is not very elegant, it causes confusion and is error-prone.
+ * It is subject for removal at the next (or at least a future) soname bump.
+ * Until then you can test the effects of the removal by undefining the
+ * following define named CURL_FTP_HTTPSTYLE_HEAD.
+ */
+#define CURL_FTP_HTTPSTYLE_HEAD 1
+
+static void freedirs(struct ftp_conn *ftpc)
+{
+  int i;
+  if(ftpc->dirs) {
+    for(i=0; i < ftpc->dirdepth; i++) {
+      free(ftpc->dirs[i]);
+      ftpc->dirs[i]=NULL;
+    }
+    free(ftpc->dirs);
+    ftpc->dirs = NULL;
+    ftpc->dirdepth = 0;
+  }
+  Curl_safefree(ftpc->file);
+
+  /* no longer of any use */
+  Curl_safefree(ftpc->newhost);
+}
+
+/* Returns non-zero if the given string contains CR (\r) or LF (\n),
+   which are not allowed within RFC 959 <string>.
+   Note: The input string is in the client's encoding which might
+   not be ASCII, so escape sequences \r & \n must be used instead
+   of hex values 0x0d & 0x0a.
+*/
+static bool isBadFtpString(const char *string)
+{
+  return ((NULL != strchr(string, '\r')) ||
+          (NULL != strchr(string, '\n'))) ? TRUE : FALSE;
+}
+
+/***********************************************************************
+ *
+ * AcceptServerConnect()
+ *
+ * After connection request is received from the server this function is
+ * called to accept the connection and close the listening socket
+ *
+ */
+static CURLcode AcceptServerConnect(struct connectdata *conn)
+{
+  struct SessionHandle *data = conn->data;
+  curl_socket_t sock = conn->sock[SECONDARYSOCKET];
+  curl_socket_t s = CURL_SOCKET_BAD;
+#ifdef ENABLE_IPV6
+  struct Curl_sockaddr_storage add;
+#else
+  struct sockaddr_in add;
+#endif
+  curl_socklen_t size = (curl_socklen_t) sizeof(add);
+
+  if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) {
+    size = sizeof(add);
+
+    s=accept(sock, (struct sockaddr *) &add, &size);
+  }
+  Curl_closesocket(conn, sock); /* close the first socket */
+
+  if(CURL_SOCKET_BAD == s) {
+    failf(data, "Error accept()ing server connect");
+    return CURLE_FTP_PORT_FAILED;
+  }
+  infof(data, "Connection accepted from server\n");
+  /* when this happens within the DO state it is important that we mark us as
+     not needing DO_MORE anymore */
+  conn->bits.do_more = FALSE;
+
+  conn->sock[SECONDARYSOCKET] = s;
+  (void)curlx_nonblock(s, TRUE); /* enable non-blocking */
+  conn->sock_accepted[SECONDARYSOCKET] = TRUE;
+
+  if(data->set.fsockopt) {
+    int error = 0;
+
+    /* activate callback for setting socket options */
+    error = data->set.fsockopt(data->set.sockopt_client,
+                               s,
+                               CURLSOCKTYPE_ACCEPT);
+
+    if(error) {
+      Curl_closesocket(conn, s); /* close the socket and bail out */
+      conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
+      return CURLE_ABORTED_BY_CALLBACK;
+    }
+  }
+
+  return CURLE_OK;
+
+}
+
+/*
+ * ftp_timeleft_accept() returns the amount of milliseconds left allowed for
+ * waiting server to connect. If the value is negative, the timeout time has
+ * already elapsed.
+ *
+ * The start time is stored in progress.t_acceptdata - as set with
+ * Curl_pgrsTime(..., TIMER_STARTACCEPT);
+ *
+ */
+static long ftp_timeleft_accept(struct SessionHandle *data)
+{
+  long timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
+  long other;
+  struct timeval now;
+
+  if(data->set.accepttimeout > 0)
+    timeout_ms = data->set.accepttimeout;
+
+  now = Curl_tvnow();
+
+  /* check if the generic timeout possibly is set shorter */
+  other =  Curl_timeleft(data, &now, FALSE);
+  if(other && (other < timeout_ms))
+    /* note that this also works fine for when other happens to be negative
+       due to it already having elapsed */
+    timeout_ms = other;
+  else {
+    /* subtract elapsed time */
+    timeout_ms -= Curl_tvdiff(now, data->progress.t_acceptdata);
+    if(!timeout_ms)
+      /* avoid returning 0 as that means no timeout! */
+      return -1;
+  }
+
+  return timeout_ms;
+}
+
+
+/***********************************************************************
+ *
+ * ReceivedServerConnect()
+ *
+ * After allowing server to connect to us from data port, this function
+ * checks both data connection for connection establishment and ctrl
+ * connection for a negative response regarding a failure in connecting
+ *
+ */
+static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
+{
+  struct SessionHandle *data = conn->data;
+  curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET];
+  curl_socket_t data_sock = conn->sock[SECONDARYSOCKET];
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+  int result;
+  long timeout_ms;
+  ssize_t nread;
+  int ftpcode;
+
+  *received = FALSE;
+
+  timeout_ms = ftp_timeleft_accept(data);
+  infof(data, "Checking for server connect\n");
+  if(timeout_ms < 0) {
+    /* if a timeout was already reached, bail out */
+    failf(data, "Accept timeout occurred while waiting server connect");
+    return CURLE_FTP_ACCEPT_TIMEOUT;
+  }
+
+  /* First check whether there is a cached response from server */
+  if(pp->cache_size && pp->cache && pp->cache[0] > '3') {
+    /* Data connection could not be established, let's return */
+    infof(data, "There is negative response in cache while serv connect\n");
+    Curl_GetFTPResponse(&nread, conn, &ftpcode);
+    return CURLE_FTP_ACCEPT_FAILED;
+  }
+
+  result = Curl_socket_check(ctrl_sock, data_sock, CURL_SOCKET_BAD, 0);
+
+  /* see if the connection request is already here */
+  switch (result) {
+  case -1: /* error */
+    /* let's die here */
+    failf(data, "Error while waiting for server connect");
+    return CURLE_FTP_ACCEPT_FAILED;
+  case 0:  /* Server connect is not received yet */
+    break; /* loop */
+  default:
+
+    if(result & CURL_CSELECT_IN2) {
+      infof(data, "Ready to accept data connection from server\n");
+      *received = TRUE;
+    }
+    else if(result & CURL_CSELECT_IN) {
+      infof(data, "Ctrl conn has data while waiting for data conn\n");
+      Curl_GetFTPResponse(&nread, conn, &ftpcode);
+
+      if(ftpcode/100 > 3)
+        return CURLE_FTP_ACCEPT_FAILED;
+
+      return CURLE_FTP_WEIRD_SERVER_REPLY;
+    }
+
+    break;
+  } /* switch() */
+
+  return CURLE_OK;
+}
+
+
+/***********************************************************************
+ *
+ * InitiateTransfer()
+ *
+ * After connection from server is accepted this function is called to
+ * setup transfer parameters and initiate the data transfer.
+ *
+ */
+static CURLcode InitiateTransfer(struct connectdata *conn)
+{
+  struct SessionHandle *data = conn->data;
+  struct FTP *ftp = data->req.protop;
+  CURLcode result = CURLE_OK;
+
+  if(conn->ssl[SECONDARYSOCKET].use) {
+    /* since we only have a plaintext TCP connection here, we must now
+     * do the TLS stuff */
+    infof(data, "Doing the SSL/TLS handshake on the data stream\n");
+    result = Curl_ssl_connect(conn, SECONDARYSOCKET);
+    if(result)
+      return result;
+  }
+
+  if(conn->proto.ftpc.state_saved == FTP_STOR) {
+    *(ftp->bytecountp)=0;
+
+    /* When we know we're uploading a specified file, we can get the file
+       size prior to the actual upload. */
+
+    Curl_pgrsSetUploadSize(data, data->state.infilesize);
+
+    /* set the SO_SNDBUF for the secondary socket for those who need it */
+    Curl_sndbufset(conn->sock[SECONDARYSOCKET]);
+
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
+                        SECONDARYSOCKET, ftp->bytecountp);
+  }
+  else {
+    /* FTP download: */
+    Curl_setup_transfer(conn, SECONDARYSOCKET,
+                        conn->proto.ftpc.retr_size_saved, FALSE,
+                        ftp->bytecountp, -1, NULL); /* no upload here */
+  }
+
+  conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
+  state(conn, FTP_STOP);
+
+  return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * AllowServerConnect()
+ *
+ * When we've issue the PORT command, we have told the server to connect to
+ * us. This function checks whether data connection is established if so it is
+ * accepted.
+ *
+ */
+static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
+{
+  struct SessionHandle *data = conn->data;
+  long timeout_ms;
+  CURLcode result = CURLE_OK;
+
+  *connected = FALSE;
+  infof(data, "Preparing for accepting server on data port\n");
+
+  /* Save the time we start accepting server connect */
+  Curl_pgrsTime(data, TIMER_STARTACCEPT);
+
+  timeout_ms = ftp_timeleft_accept(data);
+  if(timeout_ms < 0) {
+    /* if a timeout was already reached, bail out */
+    failf(data, "Accept timeout occurred while waiting server connect");
+    return CURLE_FTP_ACCEPT_TIMEOUT;
+  }
+
+  /* see if the connection request is already here */
+  result = ReceivedServerConnect(conn, connected);
+  if(result)
+    return result;
+
+  if(*connected) {
+    result = AcceptServerConnect(conn);
+    if(result)
+      return result;
+
+    result = InitiateTransfer(conn);
+    if(result)
+      return result;
+  }
+  else {
+    /* Add timeout to multi handle and break out of the loop */
+    if(!result && *connected == FALSE) {
+      if(data->set.accepttimeout > 0)
+        Curl_expire(data, data->set.accepttimeout);
+      else
+        Curl_expire(data, DEFAULT_ACCEPT_TIMEOUT);
+    }
+  }
+
+  return result;
+}
+
+/* macro to check for a three-digit ftp status code at the start of the
+   given string */
+#define STATUSCODE(line) (ISDIGIT(line[0]) && ISDIGIT(line[1]) &&       \
+                          ISDIGIT(line[2]))
+
+/* macro to check for the last line in an FTP server response */
+#define LASTLINE(line) (STATUSCODE(line) && (' ' == line[3]))
+
+static bool ftp_endofresp(struct connectdata *conn, char *line, size_t len,
+                          int *code)
+{
+  (void)conn;
+
+  if((len > 3) && LASTLINE(line)) {
+    *code = curlx_sltosi(strtol(line, NULL, 10));
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+static CURLcode ftp_readresp(curl_socket_t sockfd,
+                             struct pingpong *pp,
+                             int *ftpcode, /* return the ftp-code if done */
+                             size_t *size) /* size of the response */
+{
+  struct connectdata *conn = pp->conn;
+  struct SessionHandle *data = conn->data;
+#ifdef HAVE_GSSAPI
+  char * const buf = data->state.buffer;
+#endif
+  CURLcode result = CURLE_OK;
+  int code;
+
+  result = Curl_pp_readresp(sockfd, pp, &code, size);
+
+#if defined(HAVE_GSSAPI)
+  /* handle the security-oriented responses 6xx ***/
+  /* FIXME: some errorchecking perhaps... ***/
+  switch(code) {
+  case 631:
+    code = Curl_sec_read_msg(conn, buf, PROT_SAFE);
+    break;
+  case 632:
+    code = Curl_sec_read_msg(conn, buf, PROT_PRIVATE);
+    break;
+  case 633:
+    code = Curl_sec_read_msg(conn, buf, PROT_CONFIDENTIAL);
+    break;
+  default:
+    /* normal ftp stuff we pass through! */
+    break;
+  }
+#endif
+
+  /* store the latest code for later retrieval */
+  data->info.httpcode=code;
+
+  if(ftpcode)
+    *ftpcode = code;
+
+  if(421 == code) {
+    /* 421 means "Service not available, closing control connection." and FTP
+     * servers use it to signal that idle session timeout has been exceeded.
+     * If we ignored the response, it could end up hanging in some cases.
+     *
+     * This response code can come at any point so having it treated
+     * generically is a good idea.
+     */
+    infof(data, "We got a 421 - timeout!\n");
+    state(conn, FTP_STOP);
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  return result;
+}
+
+/* --- parse FTP server responses --- */
+
+/*
+ * Curl_GetFTPResponse() is a BLOCKING function to read the full response
+ * from a server after a command.
+ *
+ */
+
+CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
+                             struct connectdata *conn,
+                             int *ftpcode) /* return the ftp-code */
+{
+  /*
+   * We cannot read just one byte per read() and then go back to select() as
+   * the OpenSSL read() doesn't grok that properly.
+   *
+   * Alas, read as much as possible, split up into lines, use the ending
+   * line in a response or continue reading.  */
+
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+  long timeout;              /* timeout in milliseconds */
+  long interval_ms;
+  struct SessionHandle *data = conn->data;
+  CURLcode result = CURLE_OK;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+  size_t nread;
+  int cache_skip=0;
+  int value_to_be_ignored=0;
+
+  if(ftpcode)
+    *ftpcode = 0; /* 0 for errors */
+  else
+    /* make the pointer point to something for the rest of this function */
+    ftpcode = &value_to_be_ignored;
+
+  *nreadp=0;
+
+  while(!*ftpcode && !result) {
+    /* check and reset timeout value every lap */
+    timeout = Curl_pp_state_timeout(pp);
+
+    if(timeout <=0 ) {
+      failf(data, "FTP response timeout");
+      return CURLE_OPERATION_TIMEDOUT; /* already too little time */
+    }
+
+    interval_ms = 1000;  /* use 1 second timeout intervals */
+    if(timeout < interval_ms)
+      interval_ms = timeout;
+
+    /*
+     * Since this function is blocking, we need to wait here for input on the
+     * connection and only then we call the response reading function. We do
+     * timeout at least every second to make the timeout check run.
+     *
+     * A caution here is that the ftp_readresp() function has a cache that may
+     * contain pieces of a response from the previous invoke and we need to
+     * make sure we don't just wait for input while there is unhandled data in
+     * that cache. But also, if the cache is there, we call ftp_readresp() and
+     * the cache wasn't good enough to continue we must not just busy-loop
+     * around this function.
+     *
+     */
+
+    if(pp->cache && (cache_skip < 2)) {
+      /*
+       * There's a cache left since before. We then skipping the wait for
+       * socket action, unless this is the same cache like the previous round
+       * as then the cache was deemed not enough to act on and we then need to
+       * wait for more data anyway.
+       */
+    }
+    else {
+      switch (Curl_socket_ready(sockfd, CURL_SOCKET_BAD, interval_ms)) {
+      case -1: /* select() error, stop reading */
+        failf(data, "FTP response aborted due to select/poll error: %d",
+              SOCKERRNO);
+        return CURLE_RECV_ERROR;
+
+      case 0: /* timeout */
+        if(Curl_pgrsUpdate(conn))
+          return CURLE_ABORTED_BY_CALLBACK;
+        continue; /* just continue in our loop for the timeout duration */
+
+      default: /* for clarity */
+        break;
+      }
+    }
+    result = ftp_readresp(sockfd, pp, ftpcode, &nread);
+    if(result)
+      break;
+
+    if(!nread && pp->cache)
+      /* bump cache skip counter as on repeated skips we must wait for more
+         data */
+      cache_skip++;
+    else
+      /* when we got data or there is no cache left, we reset the cache skip
+         counter */
+      cache_skip=0;
+
+    *nreadp += nread;
+
+  } /* while there's buffer left and loop is requested */
+
+  pp->pending_resp = FALSE;
+
+  return result;
+}
+
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+static const char * const ftp_state_names[]={
+  "STOP",
+  "WAIT220",
+  "AUTH",
+  "USER",
+  "PASS",
+  "ACCT",
+  "PBSZ",
+  "PROT",
+  "CCC",
+  "PWD",
+  "SYST",
+  "NAMEFMT",
+  "QUOTE",
+  "RETR_PREQUOTE",
+  "STOR_PREQUOTE",
+  "POSTQUOTE",
+  "CWD",
+  "MKD",
+  "MDTM",
+  "TYPE",
+  "LIST_TYPE",
+  "RETR_TYPE",
+  "STOR_TYPE",
+  "SIZE",
+  "RETR_SIZE",
+  "STOR_SIZE",
+  "REST",
+  "RETR_REST",
+  "PORT",
+  "PRET",
+  "PASV",
+  "LIST",
+  "RETR",
+  "STOR",
+  "QUIT"
+};
+#endif
+
+/* This is the ONLY way to change FTP state! */
+static void _state(struct connectdata *conn,
+                   ftpstate newstate
+#ifdef DEBUGBUILD
+                   , int lineno
+#endif
+  )
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+#if defined(DEBUGBUILD)
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) lineno;
+#else
+  if(ftpc->state != newstate)
+    infof(conn->data, "FTP %p (line %d) state change from %s to %s\n",
+          (void *)ftpc, lineno, ftp_state_names[ftpc->state],
+          ftp_state_names[newstate]);
+#endif
+#endif
+
+  ftpc->state = newstate;
+}
+
+static CURLcode ftp_state_user(struct connectdata *conn)
+{
+  CURLcode result;
+  struct FTP *ftp = conn->data->req.protop;
+  /* send USER */
+  PPSENDF(&conn->proto.ftpc.pp, "USER %s", ftp->user?ftp->user:"");
+
+  state(conn, FTP_USER);
+  conn->data->state.ftp_trying_alternative = FALSE;
+
+  return CURLE_OK;
+}
+
+static CURLcode ftp_state_pwd(struct connectdata *conn)
+{
+  CURLcode result;
+
+  /* send PWD to discover our entry point */
+  PPSENDF(&conn->proto.ftpc.pp, "%s", "PWD");
+  state(conn, FTP_PWD);
+
+  return CURLE_OK;
+}
+
+/* For the FTP "protocol connect" and "doing" phases only */
+static int ftp_getsock(struct connectdata *conn,
+                       curl_socket_t *socks,
+                       int numsocks)
+{
+  return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
+}
+
+/* For the FTP "DO_MORE" phase only */
+static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
+                              int numsocks)
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  /* When in DO_MORE state, we could be either waiting for us to connect to a
+   * remote site, or we could wait for that site to connect to us. Or just
+   * handle ordinary commands.
+   */
+
+  if(FTP_STOP == ftpc->state) {
+    int bits = GETSOCK_READSOCK(0);
+
+    /* if stopped and still in this state, then we're also waiting for a
+       connect on the secondary connection */
+    socks[0] = conn->sock[FIRSTSOCKET];
+
+    if(!conn->data->set.ftp_use_port) {
+      int s;
+      int i;
+      /* PORT is used to tell the server to connect to us, and during that we
+         don't do happy eyeballs, but we do if we connect to the server */
+      for(s=1, i=0; i<2; i++) {
+        if(conn->tempsock[i] != CURL_SOCKET_BAD) {
+          socks[s] = conn->tempsock[i];
+          bits |= GETSOCK_WRITESOCK(s++);
+        }
+      }
+    }
+    else {
+      socks[1] = conn->sock[SECONDARYSOCKET];
+      bits |= GETSOCK_WRITESOCK(1);
+    }
+
+    return bits;
+  }
+  else
+    return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
+}
+
+/* This is called after the FTP_QUOTE state is passed.
+
+   ftp_state_cwd() sends the range of CWD commands to the server to change to
+   the correct directory. It may also need to send MKD commands to create
+   missing ones, if that option is enabled.
+*/
+static CURLcode ftp_state_cwd(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  if(ftpc->cwddone)
+    /* already done and fine */
+    result = ftp_state_mdtm(conn);
+  else {
+    ftpc->count2 = 0; /* count2 counts failed CWDs */
+
+    /* count3 is set to allow a MKD to fail once. In the case when first CWD
+       fails and then MKD fails (due to another session raced it to create the
+       dir) this then allows for a second try to CWD to it */
+    ftpc->count3 = (conn->data->set.ftp_create_missing_dirs==2)?1:0;
+
+    if(conn->bits.reuse && ftpc->entrypath) {
+      /* This is a re-used connection. Since we change directory to where the
+         transfer is taking place, we must first get back to the original dir
+         where we ended up after login: */
+      ftpc->count1 = 0; /* we count this as the first path, then we add one
+                          for all upcoming ones in the ftp->dirs[] array */
+      PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->entrypath);
+      state(conn, FTP_CWD);
+    }
+    else {
+      if(ftpc->dirdepth) {
+        ftpc->count1 = 1;
+        /* issue the first CWD, the rest is sent when the CWD responses are
+           received... */
+        PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->dirs[ftpc->count1 -1]);
+        state(conn, FTP_CWD);
+      }
+      else {
+        /* No CWD necessary */
+        result = ftp_state_mdtm(conn);
+      }
+    }
+  }
+  return result;
+}
+
+typedef enum {
+  EPRT,
+  PORT,
+  DONE
+} ftpport;
+
+static CURLcode ftp_state_use_port(struct connectdata *conn,
+                                   ftpport fcmd) /* start with this */
+
+{
+  CURLcode result = CURLE_OK;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct SessionHandle *data=conn->data;
+  curl_socket_t portsock= CURL_SOCKET_BAD;
+  char myhost[256] = "";
+
+  struct Curl_sockaddr_storage ss;
+  Curl_addrinfo *res, *ai;
+  curl_socklen_t sslen;
+  char hbuf[NI_MAXHOST];
+  struct sockaddr *sa=(struct sockaddr *)&ss;
+  struct sockaddr_in * const sa4 = (void *)sa;
+#ifdef ENABLE_IPV6
+  struct sockaddr_in6 * const sa6 = (void *)sa;
+#endif
+  char tmp[1024];
+  static const char mode[][5] = { "EPRT", "PORT" };
+  int rc;
+  int error;
+  char *host = NULL;
+  char *string_ftpport = data->set.str[STRING_FTPPORT];
+  struct Curl_dns_entry *h=NULL;
+  unsigned short port_min = 0;
+  unsigned short port_max = 0;
+  unsigned short port;
+  bool possibly_non_local = TRUE;
+
+  char *addr = NULL;
+
+  /* Step 1, figure out what is requested,
+   * accepted format :
+   * (ipv4|ipv6|domain|interface)?(:port(-range)?)?
+   */
+
+  if(data->set.str[STRING_FTPPORT] &&
+     (strlen(data->set.str[STRING_FTPPORT]) > 1)) {
+
+#ifdef ENABLE_IPV6
+    size_t addrlen = INET6_ADDRSTRLEN > strlen(string_ftpport) ?
+      INET6_ADDRSTRLEN : strlen(string_ftpport);
+#else
+    size_t addrlen = INET_ADDRSTRLEN > strlen(string_ftpport) ?
+      INET_ADDRSTRLEN : strlen(string_ftpport);
+#endif
+    char *ip_start = string_ftpport;
+    char *ip_end = NULL;
+    char *port_start = NULL;
+    char *port_sep = NULL;
+
+    addr = calloc(addrlen+1, 1);
+    if(!addr)
+      return CURLE_OUT_OF_MEMORY;
+
+#ifdef ENABLE_IPV6
+    if(*string_ftpport == '[') {
+      /* [ipv6]:port(-range) */
+      ip_start = string_ftpport + 1;
+      if((ip_end = strchr(string_ftpport, ']')) != NULL )
+        strncpy(addr, ip_start, ip_end - ip_start);
+    }
+    else
+#endif
+      if(*string_ftpport == ':') {
+        /* :port */
+        ip_end = string_ftpport;
+    }
+    else if((ip_end = strchr(string_ftpport, ':')) != NULL) {
+        /* either ipv6 or (ipv4|domain|interface):port(-range) */
+#ifdef ENABLE_IPV6
+      if(Curl_inet_pton(AF_INET6, string_ftpport, sa6) == 1) {
+        /* ipv6 */
+        port_min = port_max = 0;
+        strcpy(addr, string_ftpport);
+        ip_end = NULL; /* this got no port ! */
+      }
+      else
+#endif
+        /* (ipv4|domain|interface):port(-range) */
+        strncpy(addr, string_ftpport, ip_end - ip_start );
+    }
+    else
+      /* ipv4|interface */
+      strcpy(addr, string_ftpport);
+
+    /* parse the port */
+    if(ip_end != NULL) {
+      if((port_start = strchr(ip_end, ':')) != NULL) {
+        port_min = curlx_ultous(strtoul(port_start+1, NULL, 10));
+        if((port_sep = strchr(port_start, '-')) != NULL) {
+          port_max = curlx_ultous(strtoul(port_sep + 1, NULL, 10));
+        }
+        else
+          port_max = port_min;
+      }
+    }
+
+    /* correct errors like:
+     *  :1234-1230
+     *  :-4711 , in this case port_min is (unsigned)-1,
+     *           therefore port_min > port_max for all cases
+     *           but port_max = (unsigned)-1
+     */
+    if(port_min > port_max )
+      port_min = port_max = 0;
+
+
+    if(*addr != '\0') {
+      /* attempt to get the address of the given interface name */
+      switch(Curl_if2ip(conn->ip_addr->ai_family,
+                        Curl_ipv6_scope(conn->ip_addr->ai_addr),
+                        conn->scope_id, addr, hbuf, sizeof(hbuf))) {
+        case IF2IP_NOT_FOUND:
+          /* not an interface, use the given string as host name instead */
+          host = addr;
+          break;
+        case IF2IP_AF_NOT_SUPPORTED:
+          return CURLE_FTP_PORT_FAILED;
+        case IF2IP_FOUND:
+          host = hbuf; /* use the hbuf for host name */
+      }
+    }
+    else
+      /* there was only a port(-range) given, default the host */
+      host = NULL;
+  } /* data->set.ftpport */
+
+  if(!host) {
+    /* not an interface and not a host name, get default by extracting
+       the IP from the control connection */
+
+    sslen = sizeof(ss);
+    if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
+      failf(data, "getsockname() failed: %s",
+          Curl_strerror(conn, SOCKERRNO) );
+      free(addr);
+      return CURLE_FTP_PORT_FAILED;
+    }
+    switch(sa->sa_family) {
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      Curl_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf));
+      break;
+#endif
+    default:
+      Curl_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf));
+      break;
+    }
+    host = hbuf; /* use this host name */
+    possibly_non_local = FALSE; /* we know it is local now */
+  }
+
+  /* resolv ip/host to ip */
+  rc = Curl_resolv(conn, host, 0, &h);
+  if(rc == CURLRESOLV_PENDING)
+    (void)Curl_resolver_wait_resolv(conn, &h);
+  if(h) {
+    res = h->addr;
+    /* when we return from this function, we can forget about this entry
+       to we can unlock it now already */
+    Curl_resolv_unlock(data, h);
+  } /* (h) */
+  else
+    res = NULL; /* failure! */
+
+  if(res == NULL) {
+    failf(data, "failed to resolve the address provided to PORT: %s", host);
+    free(addr);
+    return CURLE_FTP_PORT_FAILED;
+  }
+
+  free(addr);
+  host = NULL;
+
+  /* step 2, create a socket for the requested address */
+
+  portsock = CURL_SOCKET_BAD;
+  error = 0;
+  for(ai = res; ai; ai = ai->ai_next) {
+    result = Curl_socket(conn, ai, NULL, &portsock);
+    if(result) {
+      error = SOCKERRNO;
+      continue;
+    }
+    break;
+  }
+  if(!ai) {
+    failf(data, "socket failure: %s", Curl_strerror(conn, error));
+    return CURLE_FTP_PORT_FAILED;
+  }
+
+  /* step 3, bind to a suitable local address */
+
+  memcpy(sa, ai->ai_addr, ai->ai_addrlen);
+  sslen = ai->ai_addrlen;
+
+  for(port = port_min; port <= port_max;) {
+    if(sa->sa_family == AF_INET)
+      sa4->sin_port = htons(port);
+#ifdef ENABLE_IPV6
+    else
+      sa6->sin6_port = htons(port);
+#endif
+    /* Try binding the given address. */
+    if(bind(portsock, sa, sslen) ) {
+      /* It failed. */
+      error = SOCKERRNO;
+      if(possibly_non_local && (error == EADDRNOTAVAIL)) {
+        /* The requested bind address is not local.  Use the address used for
+         * the control connection instead and restart the port loop
+         */
+
+        infof(data, "bind(port=%hu) on non-local address failed: %s\n", port,
+              Curl_strerror(conn, error) );
+
+        sslen = sizeof(ss);
+        if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
+          failf(data, "getsockname() failed: %s",
+                Curl_strerror(conn, SOCKERRNO) );
+          Curl_closesocket(conn, portsock);
+          return CURLE_FTP_PORT_FAILED;
+        }
+        port = port_min;
+        possibly_non_local = FALSE; /* don't try this again */
+        continue;
+      }
+      else if(error != EADDRINUSE && error != EACCES) {
+        failf(data, "bind(port=%hu) failed: %s", port,
+              Curl_strerror(conn, error) );
+        Curl_closesocket(conn, portsock);
+        return CURLE_FTP_PORT_FAILED;
+      }
+    }
+    else
+      break;
+
+    port++;
+  }
+
+  /* maybe all ports were in use already*/
+  if(port > port_max) {
+    failf(data, "bind() failed, we ran out of ports!");
+    Curl_closesocket(conn, portsock);
+    return CURLE_FTP_PORT_FAILED;
+  }
+
+  /* get the name again after the bind() so that we can extract the
+     port number it uses now */
+  sslen = sizeof(ss);
+  if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) {
+    failf(data, "getsockname() failed: %s",
+          Curl_strerror(conn, SOCKERRNO) );
+    Curl_closesocket(conn, portsock);
+    return CURLE_FTP_PORT_FAILED;
+  }
+
+  /* step 4, listen on the socket */
+
+  if(listen(portsock, 1)) {
+    failf(data, "socket failure: %s", Curl_strerror(conn, SOCKERRNO));
+    Curl_closesocket(conn, portsock);
+    return CURLE_FTP_PORT_FAILED;
+  }
+
+  /* step 5, send the proper FTP command */
+
+  /* get a plain printable version of the numerical address to work with
+     below */
+  Curl_printable_address(ai, myhost, sizeof(myhost));
+
+#ifdef ENABLE_IPV6
+  if(!conn->bits.ftp_use_eprt && conn->bits.ipv6)
+    /* EPRT is disabled but we are connected to a IPv6 host, so we ignore the
+       request and enable EPRT again! */
+    conn->bits.ftp_use_eprt = TRUE;
+#endif
+
+  for(; fcmd != DONE; fcmd++) {
+
+    if(!conn->bits.ftp_use_eprt && (EPRT == fcmd))
+      /* if disabled, goto next */
+      continue;
+
+    if((PORT == fcmd) && sa->sa_family != AF_INET)
+      /* PORT is IPv4 only */
+      continue;
+
+    switch(sa->sa_family) {
+    case AF_INET:
+      port = ntohs(sa4->sin_port);
+      break;
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      port = ntohs(sa6->sin6_port);
+      break;
+#endif
+    default:
+      continue; /* might as well skip this */
+    }
+
+    if(EPRT == fcmd) {
+      /*
+       * Two fine examples from RFC2428;
+       *
+       * EPRT |1|132.235.1.2|6275|
+       *
+       * EPRT |2|1080::8:800:200C:417A|5282|
+       */
+
+      result = Curl_pp_sendf(&ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd],
+                             sa->sa_family == AF_INET?1:2,
+                             myhost, port);
+      if(result) {
+        failf(data, "Failure sending EPRT command: %s",
+              curl_easy_strerror(result));
+        Curl_closesocket(conn, portsock);
+        /* don't retry using PORT */
+        ftpc->count1 = PORT;
+        /* bail out */
+        state(conn, FTP_STOP);
+        return result;
+      }
+      break;
+    }
+    else if(PORT == fcmd) {
+      char *source = myhost;
+      char *dest = tmp;
+
+      /* translate x.x.x.x to x,x,x,x */
+      while(source && *source) {
+        if(*source == '.')
+          *dest=',';
+        else
+          *dest = *source;
+        dest++;
+        source++;
+      }
+      *dest = 0;
+      snprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff));
+
+      result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], tmp);
+      if(result) {
+        failf(data, "Failure sending PORT command: %s",
+              curl_easy_strerror(result));
+        Curl_closesocket(conn, portsock);
+        /* bail out */
+        state(conn, FTP_STOP);
+        return result;
+      }
+      break;
+    }
+  }
+
+  /* store which command was sent */
+  ftpc->count1 = fcmd;
+
+  /* we set the secondary socket variable to this for now, it is only so that
+     the cleanup function will close it in case we fail before the true
+     secondary stuff is made */
+  if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
+    Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
+  conn->sock[SECONDARYSOCKET] = portsock;
+
+  /* this tcpconnect assignment below is a hackish work-around to make the
+     multi interface with active FTP work - as it will not wait for a
+     (passive) connect in Curl_is_connected().
+
+     The *proper* fix is to make sure that the active connection from the
+     server is done in a non-blocking way. Currently, it is still BLOCKING.
+  */
+  conn->bits.tcpconnect[SECONDARYSOCKET] = TRUE;
+
+  state(conn, FTP_PORT);
+  return result;
+}
+
+static CURLcode ftp_state_use_pasv(struct connectdata *conn)
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  CURLcode result = CURLE_OK;
+  /*
+    Here's the excecutive summary on what to do:
+
+    PASV is RFC959, expect:
+    227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
+
+    LPSV is RFC1639, expect:
+    228 Entering Long Passive Mode (4,4,a1,a2,a3,a4,2,p1,p2)
+
+    EPSV is RFC2428, expect:
+    229 Entering Extended Passive Mode (|||port|)
+
+  */
+
+  static const char mode[][5] = { "EPSV", "PASV" };
+  int modeoff;
+
+#ifdef PF_INET6
+  if(!conn->bits.ftp_use_epsv && conn->bits.ipv6)
+    /* EPSV is disabled but we are connected to a IPv6 host, so we ignore the
+       request and enable EPSV again! */
+    conn->bits.ftp_use_epsv = TRUE;
+#endif
+
+  modeoff = conn->bits.ftp_use_epsv?0:1;
+
+  PPSENDF(&ftpc->pp, "%s", mode[modeoff]);
+
+  ftpc->count1 = modeoff;
+  state(conn, FTP_PASV);
+  infof(conn->data, "Connect data stream passively\n");
+
+  return result;
+}
+
+/*
+ * ftp_state_prepare_transfer() starts PORT, PASV or PRET etc.
+ *
+ * REST is the last command in the chain of commands when a "head"-like
+ * request is made. Thus, if an actual transfer is to be made this is where we
+ * take off for real.
+ */
+static CURLcode ftp_state_prepare_transfer(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct FTP *ftp = conn->data->req.protop;
+  struct SessionHandle *data = conn->data;
+
+  if(ftp->transfer != FTPTRANSFER_BODY) {
+    /* doesn't transfer any data */
+
+    /* still possibly do PRE QUOTE jobs */
+    state(conn, FTP_RETR_PREQUOTE);
+    result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE);
+  }
+  else if(data->set.ftp_use_port) {
+    /* We have chosen to use the PORT (or similar) command */
+    result = ftp_state_use_port(conn, EPRT);
+  }
+  else {
+    /* We have chosen (this is default) to use the PASV (or similar) command */
+    if(data->set.ftp_use_pret) {
+      /* The user has requested that we send a PRET command
+         to prepare the server for the upcoming PASV */
+      if(!conn->proto.ftpc.file) {
+        PPSENDF(&conn->proto.ftpc.pp, "PRET %s",
+                data->set.str[STRING_CUSTOMREQUEST]?
+                data->set.str[STRING_CUSTOMREQUEST]:
+                (data->set.ftp_list_only?"NLST":"LIST"));
+      }
+      else if(data->set.upload) {
+        PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file);
+      }
+      else {
+        PPSENDF(&conn->proto.ftpc.pp, "PRET RETR %s", conn->proto.ftpc.file);
+      }
+      state(conn, FTP_PRET);
+    }
+    else {
+      result = ftp_state_use_pasv(conn);
+    }
+  }
+  return result;
+}
+
+static CURLcode ftp_state_rest(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct FTP *ftp = conn->data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  if((ftp->transfer != FTPTRANSFER_BODY) && ftpc->file) {
+    /* if a "head"-like request is being made (on a file) */
+
+    /* Determine if server can respond to REST command and therefore
+       whether it supports range */
+    PPSENDF(&conn->proto.ftpc.pp, "REST %d", 0);
+
+    state(conn, FTP_REST);
+  }
+  else
+    result = ftp_state_prepare_transfer(conn);
+
+  return result;
+}
+
+static CURLcode ftp_state_size(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct FTP *ftp = conn->data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  if((ftp->transfer == FTPTRANSFER_INFO) && ftpc->file) {
+    /* if a "head"-like request is being made (on a file) */
+
+    /* we know ftpc->file is a valid pointer to a file name */
+    PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
+
+    state(conn, FTP_SIZE);
+  }
+  else
+    result = ftp_state_rest(conn);
+
+  return result;
+}
+
+static CURLcode ftp_state_list(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  /* If this output is to be machine-parsed, the NLST command might be better
+     to use, since the LIST command output is not specified or standard in any
+     way. It has turned out that the NLST list output is not the same on all
+     servers either... */
+
+  /*
+     if FTPFILE_NOCWD was specified, we are currently in
+     the user's home directory, so we should add the path
+     as argument for the LIST / NLST / or custom command.
+     Whether the server will support this, is uncertain.
+
+     The other ftp_filemethods will CWD into dir/dir/ first and
+     then just do LIST (in that case: nothing to do here)
+  */
+  char *cmd, *lstArg, *slashPos;
+
+  lstArg = NULL;
+  if((data->set.ftp_filemethod == FTPFILE_NOCWD) &&
+     data->state.path &&
+     data->state.path[0] &&
+     strchr(data->state.path, '/')) {
+
+    lstArg = strdup(data->state.path);
+    if(!lstArg)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Check if path does not end with /, as then we cut off the file part */
+    if(lstArg[strlen(lstArg) - 1] != '/')  {
+
+      /* chop off the file part if format is dir/dir/file */
+      slashPos = strrchr(lstArg, '/');
+      if(slashPos)
+        *(slashPos+1) = '\0';
+    }
+  }
+
+  cmd = aprintf( "%s%s%s",
+                 data->set.str[STRING_CUSTOMREQUEST]?
+                 data->set.str[STRING_CUSTOMREQUEST]:
+                 (data->set.ftp_list_only?"NLST":"LIST"),
+                 lstArg? " ": "",
+                 lstArg? lstArg: "" );
+
+  if(!cmd) {
+    free(lstArg);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd);
+
+  free(lstArg);
+  free(cmd);
+
+  if(result)
+    return result;
+
+  state(conn, FTP_LIST);
+
+  return result;
+}
+
+static CURLcode ftp_state_retr_prequote(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* We've sent the TYPE, now we must send the list of prequote strings */
+
+  result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE);
+
+  return result;
+}
+
+static CURLcode ftp_state_stor_prequote(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* We've sent the TYPE, now we must send the list of prequote strings */
+
+  result = ftp_state_quote(conn, TRUE, FTP_STOR_PREQUOTE);
+
+  return result;
+}
+
+static CURLcode ftp_state_type(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct FTP *ftp = conn->data->req.protop;
+  struct SessionHandle *data = conn->data;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  /* If we have selected NOBODY and HEADER, it means that we only want file
+     information. Which in FTP can't be much more than the file size and
+     date. */
+  if(data->set.opt_no_body && ftpc->file &&
+     ftp_need_type(conn, data->set.prefer_ascii)) {
+    /* The SIZE command is _not_ RFC 959 specified, and therefor many servers
+       may not support it! It is however the only way we have to get a file's
+       size! */
+
+    ftp->transfer = FTPTRANSFER_INFO;
+    /* this means no actual transfer will be made */
+
+    /* Some servers return different sizes for different modes, and thus we
+       must set the proper type before we check the size */
+    result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_TYPE);
+    if(result)
+      return result;
+  }
+  else
+    result = ftp_state_size(conn);
+
+  return result;
+}
+
+/* This is called after the CWD commands have been done in the beginning of
+   the DO phase */
+static CURLcode ftp_state_mdtm(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  /* Requested time of file or time-depended transfer? */
+  if((data->set.get_filetime || data->set.timecondition) && ftpc->file) {
+
+    /* we have requested to get the modified-time of the file, this is a white
+       spot as the MDTM is not mentioned in RFC959 */
+    PPSENDF(&ftpc->pp, "MDTM %s", ftpc->file);
+
+    state(conn, FTP_MDTM);
+  }
+  else
+    result = ftp_state_type(conn);
+
+  return result;
+}
+
+
+/* This is called after the TYPE and possible quote commands have been sent */
+static CURLcode ftp_state_ul_setup(struct connectdata *conn,
+                                   bool sizechecked)
+{
+  CURLcode result = CURLE_OK;
+  struct FTP *ftp = conn->data->req.protop;
+  struct SessionHandle *data = conn->data;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  int seekerr = CURL_SEEKFUNC_OK;
+
+  if((data->state.resume_from && !sizechecked) ||
+     ((data->state.resume_from > 0) && sizechecked)) {
+    /* we're about to continue the uploading of a file */
+    /* 1. get already existing file's size. We use the SIZE command for this
+       which may not exist in the server!  The SIZE command is not in
+       RFC959. */
+
+    /* 2. This used to set REST. But since we can do append, we
+       don't another ftp command. We just skip the source file
+       offset and then we APPEND the rest on the file instead */
+
+    /* 3. pass file-size number of bytes in the source file */
+    /* 4. lower the infilesize counter */
+    /* => transfer as usual */
+
+    if(data->state.resume_from < 0 ) {
+      /* Got no given size to start from, figure it out */
+      PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
+      state(conn, FTP_STOR_SIZE);
+      return result;
+    }
+
+    /* enable append */
+    data->set.ftp_append = TRUE;
+
+    /* Let's read off the proper amount of bytes from the input. */
+    if(conn->seek_func) {
+      seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+                                SEEK_SET);
+    }
+
+    if(seekerr != CURL_SEEKFUNC_OK) {
+      if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+        failf(data, "Could not seek stream");
+        return CURLE_FTP_COULDNT_USE_REST;
+      }
+      /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+      else {
+        curl_off_t passed=0;
+        do {
+          size_t readthisamountnow =
+            (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
+            BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
+
+          size_t actuallyread =
+            data->state.fread_func(data->state.buffer, 1, readthisamountnow,
+                                   data->state.in);
+
+          passed += actuallyread;
+          if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+            /* this checks for greater-than only to make sure that the
+               CURL_READFUNC_ABORT return code still aborts */
+            failf(data, "Failed to read data");
+            return CURLE_FTP_COULDNT_USE_REST;
+          }
+        } while(passed < data->state.resume_from);
+      }
+    }
+    /* now, decrease the size of the read */
+    if(data->state.infilesize>0) {
+      data->state.infilesize -= data->state.resume_from;
+
+      if(data->state.infilesize <= 0) {
+        infof(data, "File already completely uploaded\n");
+
+        /* no data to transfer */
+        Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+        /* Set ->transfer so that we won't get any error in
+         * ftp_done() because we didn't transfer anything! */
+        ftp->transfer = FTPTRANSFER_NONE;
+
+        state(conn, FTP_STOP);
+        return CURLE_OK;
+      }
+    }
+    /* we've passed, proceed as normal */
+  } /* resume_from */
+
+  PPSENDF(&ftpc->pp, data->set.ftp_append?"APPE %s":"STOR %s",
+          ftpc->file);
+
+  state(conn, FTP_STOR);
+
+  return result;
+}
+
+static CURLcode ftp_state_quote(struct connectdata *conn,
+                                bool init,
+                                ftpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct FTP *ftp = data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  bool quote=FALSE;
+  struct curl_slist *item;
+
+  switch(instate) {
+  case FTP_QUOTE:
+  default:
+    item = data->set.quote;
+    break;
+  case FTP_RETR_PREQUOTE:
+  case FTP_STOR_PREQUOTE:
+    item = data->set.prequote;
+    break;
+  case FTP_POSTQUOTE:
+    item = data->set.postquote;
+    break;
+  }
+
+  /*
+   * This state uses:
+   * 'count1' to iterate over the commands to send
+   * 'count2' to store wether to allow commands to fail
+   */
+
+  if(init)
+    ftpc->count1 = 0;
+  else
+    ftpc->count1++;
+
+  if(item) {
+    int i = 0;
+
+    /* Skip count1 items in the linked list */
+    while((i< ftpc->count1) && item) {
+      item = item->next;
+      i++;
+    }
+    if(item) {
+      char *cmd = item->data;
+      if(cmd[0] == '*') {
+        cmd++;
+        ftpc->count2 = 1; /* the sent command is allowed to fail */
+      }
+      else
+        ftpc->count2 = 0; /* failure means cancel operation */
+
+      PPSENDF(&ftpc->pp, "%s", cmd);
+      state(conn, instate);
+      quote = TRUE;
+    }
+  }
+
+  if(!quote) {
+    /* No more quote to send, continue to ... */
+    switch(instate) {
+    case FTP_QUOTE:
+    default:
+      result = ftp_state_cwd(conn);
+      break;
+    case FTP_RETR_PREQUOTE:
+      if(ftp->transfer != FTPTRANSFER_BODY)
+        state(conn, FTP_STOP);
+      else {
+        if(ftpc->known_filesize != -1) {
+          Curl_pgrsSetDownloadSize(data, ftpc->known_filesize);
+          result = ftp_state_retr(conn, ftpc->known_filesize);
+        }
+        else {
+          if(data->set.ignorecl) {
+            /* This code is to support download of growing files.  It prevents
+               the state machine from requesting the file size from the
+               server.  With an unknown file size the download continues until
+               the server terminates it, otherwise the client stops if the
+               received byte count exceeds the reported file size.  Set option
+               CURLOPT_IGNORE_CONTENT_LENGTH to 1 to enable this behavior.*/
+            PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
+            state(conn, FTP_RETR);
+          }
+          else {
+            PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
+            state(conn, FTP_RETR_SIZE);
+          }
+        }
+      }
+      break;
+    case FTP_STOR_PREQUOTE:
+      result = ftp_state_ul_setup(conn, FALSE);
+      break;
+    case FTP_POSTQUOTE:
+      break;
+    }
+  }
+
+  return result;
+}
+
+/* called from ftp_state_pasv_resp to switch to PASV in case of EPSV
+   problems */
+static CURLcode ftp_epsv_disable(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  if(conn->bits.ipv6) {
+    /* We can't disable EPSV when doing IPv6, so this is instead a fail */
+    failf(conn->data, "Failed EPSV attempt, exiting\n");
+    return CURLE_FTP_WEIRD_SERVER_REPLY;
+  }
+
+  infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n");
+  /* disable it for next transfer */
+  conn->bits.ftp_use_epsv = FALSE;
+  conn->data->state.errorbuf = FALSE; /* allow error message to get
+                                         rewritten */
+  PPSENDF(&conn->proto.ftpc.pp, "%s", "PASV");
+  conn->proto.ftpc.count1++;
+  /* remain in/go to the FTP_PASV state */
+  state(conn, FTP_PASV);
+  return result;
+}
+
+/*
+ * Perform the necessary magic that needs to be done once the TCP connection
+ * to the proxy has completed.
+ */
+static CURLcode proxy_magic(struct connectdata *conn,
+                            char *newhost, unsigned short newport,
+                            bool *magicdone)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+#if defined(CURL_DISABLE_PROXY)
+  (void) newhost;
+  (void) newport;
+#endif
+
+  *magicdone = FALSE;
+
+  switch(conn->proxytype) {
+  case CURLPROXY_SOCKS5:
+  case CURLPROXY_SOCKS5_HOSTNAME:
+    result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, newhost,
+                         newport, SECONDARYSOCKET, conn);
+    *magicdone = TRUE;
+    break;
+  case CURLPROXY_SOCKS4:
+    result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
+                         SECONDARYSOCKET, conn, FALSE);
+    *magicdone = TRUE;
+    break;
+  case CURLPROXY_SOCKS4A:
+    result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
+                         SECONDARYSOCKET, conn, TRUE);
+    *magicdone = TRUE;
+    break;
+  case CURLPROXY_HTTP:
+  case CURLPROXY_HTTP_1_0:
+    /* do nothing here. handled later. */
+    break;
+  default:
+    failf(data, "unknown proxytype option given");
+    result = CURLE_COULDNT_CONNECT;
+    break;
+  }
+
+  if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
+    /* BLOCKING */
+    /* We want "seamless" FTP operations through HTTP proxy tunnel */
+
+    /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
+     * member conn->proto.http; we want FTP through HTTP and we have to
+     * change the member temporarily for connecting to the HTTP proxy. After
+     * Curl_proxyCONNECT we have to set back the member to the original
+     * struct FTP pointer
+     */
+    struct HTTP http_proxy;
+    struct FTP *ftp_save = data->req.protop;
+    memset(&http_proxy, 0, sizeof(http_proxy));
+    data->req.protop = &http_proxy;
+
+    result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport, TRUE);
+
+    data->req.protop = ftp_save;
+
+    if(result)
+      return result;
+
+    if(conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE) {
+      /* the CONNECT procedure is not complete, the tunnel is not yet up */
+      state(conn, FTP_STOP); /* this phase is completed */
+      return result;
+    }
+    else
+      *magicdone = TRUE;
+  }
+
+  return result;
+}
+
+static char *control_address(struct connectdata *conn)
+{
+  /* Returns the control connection IP address.
+     If a proxy tunnel is used, returns the original host name instead, because
+     the effective control connection address is the proxy address,
+     not the ftp host. */
+  if(conn->bits.tunnel_proxy ||
+     conn->proxytype == CURLPROXY_SOCKS5 ||
+     conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
+     conn->proxytype == CURLPROXY_SOCKS4 ||
+     conn->proxytype == CURLPROXY_SOCKS4A)
+    return conn->host.name;
+
+  return conn->ip_addr_str;
+}
+
+static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
+                                    int ftpcode)
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  CURLcode result;
+  struct SessionHandle *data=conn->data;
+  struct Curl_dns_entry *addr=NULL;
+  int rc;
+  unsigned short connectport; /* the local port connect() should use! */
+  char *str=&data->state.buffer[4];  /* start on the first letter */
+
+  /* if we come here again, make sure the former name is cleared */
+  Curl_safefree(ftpc->newhost);
+
+  if((ftpc->count1 == 0) &&
+     (ftpcode == 229)) {
+    /* positive EPSV response */
+    char *ptr = strchr(str, '(');
+    if(ptr) {
+      unsigned int num;
+      char separator[4];
+      ptr++;
+      if(5 == sscanf(ptr, "%c%c%c%u%c",
+                     &separator[0],
+                     &separator[1],
+                     &separator[2],
+                     &num,
+                     &separator[3])) {
+        const char sep1 = separator[0];
+        int i;
+
+        /* The four separators should be identical, or else this is an oddly
+           formatted reply and we bail out immediately. */
+        for(i=1; i<4; i++) {
+          if(separator[i] != sep1) {
+            ptr=NULL; /* set to NULL to signal error */
+            break;
+          }
+        }
+        if(num > 0xffff) {
+          failf(data, "Illegal port number in EPSV reply");
+          return CURLE_FTP_WEIRD_PASV_REPLY;
+        }
+        if(ptr) {
+          ftpc->newport = (unsigned short)(num & 0xffff);
+          ftpc->newhost = strdup(control_address(conn));
+          if(!ftpc->newhost)
+            return CURLE_OUT_OF_MEMORY;
+        }
+      }
+      else
+        ptr=NULL;
+    }
+    if(!ptr) {
+      failf(data, "Weirdly formatted EPSV reply");
+      return CURLE_FTP_WEIRD_PASV_REPLY;
+    }
+  }
+  else if((ftpc->count1 == 1) &&
+          (ftpcode == 227)) {
+    /* positive PASV response */
+    int ip[4];
+    int port[2];
+
+    /*
+     * Scan for a sequence of six comma-separated numbers and use them as
+     * IP+port indicators.
+     *
+     * Found reply-strings include:
+     * "227 Entering Passive Mode (127,0,0,1,4,51)"
+     * "227 Data transfer will passively listen to 127,0,0,1,4,51"
+     * "227 Entering passive mode. 127,0,0,1,4,51"
+     */
+    while(*str) {
+      if(6 == sscanf(str, "%d,%d,%d,%d,%d,%d",
+                     &ip[0], &ip[1], &ip[2], &ip[3],
+                     &port[0], &port[1]))
+        break;
+      str++;
+    }
+
+    if(!*str) {
+      failf(data, "Couldn't interpret the 227-response");
+      return CURLE_FTP_WEIRD_227_FORMAT;
+    }
+
+    /* we got OK from server */
+    if(data->set.ftp_skip_ip) {
+      /* told to ignore the remotely given IP but instead use the host we used
+         for the control connection */
+      infof(data, "Skip %d.%d.%d.%d for data connection, re-use %s instead\n",
+            ip[0], ip[1], ip[2], ip[3],
+            conn->host.name);
+      ftpc->newhost = strdup(control_address(conn));
+    }
+    else
+      ftpc->newhost = aprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+
+    if(!ftpc->newhost)
+      return CURLE_OUT_OF_MEMORY;
+
+    ftpc->newport = (unsigned short)(((port[0]<<8) + port[1]) & 0xffff);
+  }
+  else if(ftpc->count1 == 0) {
+    /* EPSV failed, move on to PASV */
+    return ftp_epsv_disable(conn);
+  }
+  else {
+    failf(data, "Bad PASV/EPSV response: %03d", ftpcode);
+    return CURLE_FTP_WEIRD_PASV_REPLY;
+  }
+
+  if(conn->bits.proxy) {
+    /*
+     * This connection uses a proxy and we need to connect to the proxy again
+     * here. We don't want to rely on a former host lookup that might've
+     * expired now, instead we remake the lookup here and now!
+     */
+    rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &addr);
+    if(rc == CURLRESOLV_PENDING)
+      /* BLOCKING, ignores the return code but 'addr' will be NULL in
+         case of failure */
+      (void)Curl_resolver_wait_resolv(conn, &addr);
+
+    connectport =
+      (unsigned short)conn->port; /* we connect to the proxy's port */
+
+    if(!addr) {
+      failf(data, "Can't resolve proxy host %s:%hu",
+            conn->proxy.name, connectport);
+      return CURLE_FTP_CANT_GET_HOST;
+    }
+  }
+  else {
+    /* normal, direct, ftp connection */
+    rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, &addr);
+    if(rc == CURLRESOLV_PENDING)
+      /* BLOCKING */
+      (void)Curl_resolver_wait_resolv(conn, &addr);
+
+    connectport = ftpc->newport; /* we connect to the remote port */
+
+    if(!addr) {
+      failf(data, "Can't resolve new host %s:%hu", ftpc->newhost, connectport);
+      return CURLE_FTP_CANT_GET_HOST;
+    }
+  }
+
+  conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
+  result = Curl_connecthost(conn, addr);
+
+  if(result) {
+    Curl_resolv_unlock(data, addr); /* we're done using this address */
+    if(ftpc->count1 == 0 && ftpcode == 229)
+      return ftp_epsv_disable(conn);
+
+    return result;
+  }
+
+
+  /*
+   * When this is used from the multi interface, this might've returned with
+   * the 'connected' set to FALSE and thus we are now awaiting a non-blocking
+   * connect to connect.
+   */
+
+  if(data->set.verbose)
+    /* this just dumps information about this second connection */
+    ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport);
+
+  Curl_resolv_unlock(data, addr); /* we're done using this address */
+  conn->bits.do_more = TRUE;
+  state(conn, FTP_STOP); /* this phase is completed */
+
+  return result;
+}
+
+static CURLcode ftp_state_port_resp(struct connectdata *conn,
+                                    int ftpcode)
+{
+  struct SessionHandle *data = conn->data;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  ftpport fcmd = (ftpport)ftpc->count1;
+  CURLcode result = CURLE_OK;
+
+  /* The FTP spec tells a positive response should have code 200.
+     Be more permissive here to tolerate deviant servers. */
+  if(ftpcode / 100 != 2) {
+    /* the command failed */
+
+    if(EPRT == fcmd) {
+      infof(data, "disabling EPRT usage\n");
+      conn->bits.ftp_use_eprt = FALSE;
+    }
+    fcmd++;
+
+    if(fcmd == DONE) {
+      failf(data, "Failed to do PORT");
+      result = CURLE_FTP_PORT_FAILED;
+    }
+    else
+      /* try next */
+      result = ftp_state_use_port(conn, fcmd);
+  }
+  else {
+    infof(data, "Connect data stream actively\n");
+    state(conn, FTP_STOP); /* end of DO phase */
+    result = ftp_dophase_done(conn, FALSE);
+  }
+
+  return result;
+}
+
+static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
+                                    int ftpcode)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data=conn->data;
+  struct FTP *ftp = data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  switch(ftpcode) {
+  case 213:
+    {
+      /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the
+         last .sss part is optional and means fractions of a second */
+      int year, month, day, hour, minute, second;
+      char *buf = data->state.buffer;
+      if(6 == sscanf(buf+4, "%04d%02d%02d%02d%02d%02d",
+                     &year, &month, &day, &hour, &minute, &second)) {
+        /* we have a time, reformat it */
+        time_t secs=time(NULL);
+        /* using the good old yacc/bison yuck */
+        snprintf(buf, sizeof(conn->data->state.buffer),
+                 "%04d%02d%02d %02d:%02d:%02d GMT",
+                 year, month, day, hour, minute, second);
+        /* now, convert this into a time() value: */
+        data->info.filetime = (long)curl_getdate(buf, &secs);
+      }
+
+#ifdef CURL_FTP_HTTPSTYLE_HEAD
+      /* If we asked for a time of the file and we actually got one as well,
+         we "emulate" a HTTP-style header in our output. */
+
+      if(data->set.opt_no_body &&
+         ftpc->file &&
+         data->set.get_filetime &&
+         (data->info.filetime>=0) ) {
+        time_t filetime = (time_t)data->info.filetime;
+        struct tm buffer;
+        const struct tm *tm = &buffer;
+
+        result = Curl_gmtime(filetime, &buffer);
+        if(result)
+          return result;
+
+        /* format: "Tue, 15 Nov 1994 12:45:26" */
+        snprintf(buf, BUFSIZE-1,
+                 "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
+                 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+                 tm->tm_mday,
+                 Curl_month[tm->tm_mon],
+                 tm->tm_year + 1900,
+                 tm->tm_hour,
+                 tm->tm_min,
+                 tm->tm_sec);
+        result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
+        if(result)
+          return result;
+      } /* end of a ridiculous amount of conditionals */
+#endif
+    }
+    break;
+  default:
+    infof(data, "unsupported MDTM reply format\n");
+    break;
+  case 550: /* "No such file or directory" */
+    failf(data, "Given file does not exist");
+    result = CURLE_FTP_COULDNT_RETR_FILE;
+    break;
+  }
+
+  if(data->set.timecondition) {
+    if((data->info.filetime > 0) && (data->set.timevalue > 0)) {
+      switch(data->set.timecondition) {
+      case CURL_TIMECOND_IFMODSINCE:
+      default:
+        if(data->info.filetime <= data->set.timevalue) {
+          infof(data, "The requested document is not new enough\n");
+          ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */
+          data->info.timecond = TRUE;
+          state(conn, FTP_STOP);
+          return CURLE_OK;
+        }
+        break;
+      case CURL_TIMECOND_IFUNMODSINCE:
+        if(data->info.filetime > data->set.timevalue) {
+          infof(data, "The requested document is not old enough\n");
+          ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */
+          data->info.timecond = TRUE;
+          state(conn, FTP_STOP);
+          return CURLE_OK;
+        }
+        break;
+      } /* switch */
+    }
+    else {
+      infof(data, "Skipping time comparison\n");
+    }
+  }
+
+  if(!result)
+    result = ftp_state_type(conn);
+
+  return result;
+}
+
+static CURLcode ftp_state_type_resp(struct connectdata *conn,
+                                    int ftpcode,
+                                    ftpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data=conn->data;
+
+  if(ftpcode/100 != 2) {
+    /* "sasserftpd" and "(u)r(x)bot ftpd" both responds with 226 after a
+       successful 'TYPE I'. While that is not as RFC959 says, it is still a
+       positive response code and we allow that. */
+    failf(data, "Couldn't set desired mode");
+    return CURLE_FTP_COULDNT_SET_TYPE;
+  }
+  if(ftpcode != 200)
+    infof(data, "Got a %03d response code instead of the assumed 200\n",
+          ftpcode);
+
+  if(instate == FTP_TYPE)
+    result = ftp_state_size(conn);
+  else if(instate == FTP_LIST_TYPE)
+    result = ftp_state_list(conn);
+  else if(instate == FTP_RETR_TYPE)
+    result = ftp_state_retr_prequote(conn);
+  else if(instate == FTP_STOR_TYPE)
+    result = ftp_state_stor_prequote(conn);
+
+  return result;
+}
+
+static CURLcode ftp_state_retr(struct connectdata *conn,
+                                         curl_off_t filesize)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data=conn->data;
+  struct FTP *ftp = data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  if(data->set.max_filesize && (filesize > data->set.max_filesize)) {
+    failf(data, "Maximum file size exceeded");
+    return CURLE_FILESIZE_EXCEEDED;
+  }
+  ftp->downloadsize = filesize;
+
+  if(data->state.resume_from) {
+    /* We always (attempt to) get the size of downloads, so it is done before
+       this even when not doing resumes. */
+    if(filesize == -1) {
+      infof(data, "ftp server doesn't support SIZE\n");
+      /* We couldn't get the size and therefore we can't know if there really
+         is a part of the file left to get, although the server will just
+         close the connection when we start the connection so it won't cause
+         us any harm, just not make us exit as nicely. */
+    }
+    else {
+      /* We got a file size report, so we check that there actually is a
+         part of the file left to get, or else we go home.  */
+      if(data->state.resume_from< 0) {
+        /* We're supposed to download the last abs(from) bytes */
+        if(filesize < -data->state.resume_from) {
+          failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
+                ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
+                data->state.resume_from, filesize);
+          return CURLE_BAD_DOWNLOAD_RESUME;
+        }
+        /* convert to size to download */
+        ftp->downloadsize = -data->state.resume_from;
+        /* download from where? */
+        data->state.resume_from = filesize - ftp->downloadsize;
+      }
+      else {
+        if(filesize < data->state.resume_from) {
+          failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
+                ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
+                data->state.resume_from, filesize);
+          return CURLE_BAD_DOWNLOAD_RESUME;
+        }
+        /* Now store the number of bytes we are expected to download */
+        ftp->downloadsize = filesize-data->state.resume_from;
+      }
+    }
+
+    if(ftp->downloadsize == 0) {
+      /* no data to transfer */
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+      infof(data, "File already completely downloaded\n");
+
+      /* Set ->transfer so that we won't get any error in ftp_done()
+       * because we didn't transfer the any file */
+      ftp->transfer = FTPTRANSFER_NONE;
+      state(conn, FTP_STOP);
+      return CURLE_OK;
+    }
+
+    /* Set resume file transfer offset */
+    infof(data, "Instructs server to resume from offset %"
+          CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from);
+
+    PPSENDF(&ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
+            data->state.resume_from);
+
+    state(conn, FTP_RETR_REST);
+  }
+  else {
+    /* no resume */
+    PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
+    state(conn, FTP_RETR);
+  }
+
+  return result;
+}
+
+static CURLcode ftp_state_size_resp(struct connectdata *conn,
+                                    int ftpcode,
+                                    ftpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data=conn->data;
+  curl_off_t filesize;
+  char *buf = data->state.buffer;
+
+  /* get the size from the ascii string: */
+  filesize = (ftpcode == 213)?curlx_strtoofft(buf+4, NULL, 0):-1;
+
+  if(instate == FTP_SIZE) {
+#ifdef CURL_FTP_HTTPSTYLE_HEAD
+    if(-1 != filesize) {
+      snprintf(buf, sizeof(data->state.buffer),
+               "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize);
+      result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
+      if(result)
+        return result;
+    }
+#endif
+    Curl_pgrsSetDownloadSize(data, filesize);
+    result = ftp_state_rest(conn);
+  }
+  else if(instate == FTP_RETR_SIZE) {
+    Curl_pgrsSetDownloadSize(data, filesize);
+    result = ftp_state_retr(conn, filesize);
+  }
+  else if(instate == FTP_STOR_SIZE) {
+    data->state.resume_from = filesize;
+    result = ftp_state_ul_setup(conn, TRUE);
+  }
+
+  return result;
+}
+
+static CURLcode ftp_state_rest_resp(struct connectdata *conn,
+                                    int ftpcode,
+                                    ftpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  switch(instate) {
+  case FTP_REST:
+  default:
+#ifdef CURL_FTP_HTTPSTYLE_HEAD
+    if(ftpcode == 350) {
+      char buffer[24]= { "Accept-ranges: bytes\r\n" };
+      result = Curl_client_write(conn, CLIENTWRITE_BOTH, buffer, 0);
+      if(result)
+        return result;
+    }
+#endif
+    result = ftp_state_prepare_transfer(conn);
+    break;
+
+  case FTP_RETR_REST:
+    if(ftpcode != 350) {
+      failf(conn->data, "Couldn't use REST");
+      result = CURLE_FTP_COULDNT_USE_REST;
+    }
+    else {
+      PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
+      state(conn, FTP_RETR);
+    }
+    break;
+  }
+
+  return result;
+}
+
+static CURLcode ftp_state_stor_resp(struct connectdata *conn,
+                                    int ftpcode, ftpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  if(ftpcode>=400) {
+    failf(data, "Failed FTP upload: %0d", ftpcode);
+    state(conn, FTP_STOP);
+    /* oops, we never close the sockets! */
+    return CURLE_UPLOAD_FAILED;
+  }
+
+  conn->proto.ftpc.state_saved = instate;
+
+  /* PORT means we are now awaiting the server to connect to us. */
+  if(data->set.ftp_use_port) {
+    bool connected;
+
+    state(conn, FTP_STOP); /* no longer in STOR state */
+
+    result = AllowServerConnect(conn, &connected);
+    if(result)
+      return result;
+
+    if(!connected) {
+      struct ftp_conn *ftpc = &conn->proto.ftpc;
+      infof(data, "Data conn was not available immediately\n");
+      ftpc->wait_data_conn = TRUE;
+    }
+
+    return CURLE_OK;
+  }
+  else
+    return InitiateTransfer(conn);
+}
+
+/* for LIST and RETR responses */
+static CURLcode ftp_state_get_resp(struct connectdata *conn,
+                                    int ftpcode,
+                                    ftpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct FTP *ftp = data->req.protop;
+  char *buf = data->state.buffer;
+
+  if((ftpcode == 150) || (ftpcode == 125)) {
+
+    /*
+      A;
+      150 Opening BINARY mode data connection for /etc/passwd (2241
+      bytes).  (ok, the file is being transferred)
+
+      B:
+      150 Opening ASCII mode data connection for /bin/ls
+
+      C:
+      150 ASCII data connection for /bin/ls (137.167.104.91,37445) (0 bytes).
+
+      D:
+      150 Opening ASCII mode data connection for [file] (0.0.0.0,0) (545 bytes)
+
+      E:
+      125 Data connection already open; Transfer starting. */
+
+    curl_off_t size=-1; /* default unknown size */
+
+
+    /*
+     * It appears that there are FTP-servers that return size 0 for files when
+     * SIZE is used on the file while being in BINARY mode. To work around
+     * that (stupid) behavior, we attempt to parse the RETR response even if
+     * the SIZE returned size zero.
+     *
+     * Debugging help from Salvatore Sorrentino on February 26, 2003.
+     */
+
+    if((instate != FTP_LIST) &&
+       !data->set.prefer_ascii &&
+       (ftp->downloadsize < 1)) {
+      /*
+       * It seems directory listings either don't show the size or very
+       * often uses size 0 anyway. ASCII transfers may very well turn out
+       * that the transferred amount of data is not the same as this line
+       * tells, why using this number in those cases only confuses us.
+       *
+       * Example D above makes this parsing a little tricky */
+      char *bytes;
+      bytes=strstr(buf, " bytes");
+      if(bytes--) {
+        long in=(long)(bytes-buf);
+        /* this is a hint there is size information in there! ;-) */
+        while(--in) {
+          /* scan for the left parenthesis and break there */
+          if('(' == *bytes)
+            break;
+          /* skip only digits */
+          if(!ISDIGIT(*bytes)) {
+            bytes=NULL;
+            break;
+          }
+          /* one more estep backwards */
+          bytes--;
+        }
+        /* if we have nothing but digits: */
+        if(bytes++) {
+          /* get the number! */
+          size = curlx_strtoofft(bytes, NULL, 0);
+        }
+      }
+    }
+    else if(ftp->downloadsize > -1)
+      size = ftp->downloadsize;
+
+    if(size > data->req.maxdownload && data->req.maxdownload > 0)
+      size = data->req.size = data->req.maxdownload;
+    else if((instate != FTP_LIST) && (data->set.prefer_ascii))
+      size = -1; /* kludge for servers that understate ASCII mode file size */
+
+    infof(data, "Maxdownload = %" CURL_FORMAT_CURL_OFF_T "\n",
+          data->req.maxdownload);
+
+    if(instate != FTP_LIST)
+      infof(data, "Getting file with size: %" CURL_FORMAT_CURL_OFF_T "\n",
+            size);
+
+    /* FTP download: */
+    conn->proto.ftpc.state_saved = instate;
+    conn->proto.ftpc.retr_size_saved = size;
+
+    if(data->set.ftp_use_port) {
+      bool connected;
+
+      result = AllowServerConnect(conn, &connected);
+      if(result)
+        return result;
+
+      if(!connected) {
+        struct ftp_conn *ftpc = &conn->proto.ftpc;
+        infof(data, "Data conn was not available immediately\n");
+        state(conn, FTP_STOP);
+        ftpc->wait_data_conn = TRUE;
+      }
+    }
+    else
+      return InitiateTransfer(conn);
+  }
+  else {
+    if((instate == FTP_LIST) && (ftpcode == 450)) {
+      /* simply no matching files in the dir listing */
+      ftp->transfer = FTPTRANSFER_NONE; /* don't download anything */
+      state(conn, FTP_STOP); /* this phase is over */
+    }
+    else {
+      failf(data, "RETR response: %03d", ftpcode);
+      return instate == FTP_RETR && ftpcode == 550?
+        CURLE_REMOTE_FILE_NOT_FOUND:
+        CURLE_FTP_COULDNT_RETR_FILE;
+    }
+  }
+
+  return result;
+}
+
+/* after USER, PASS and ACCT */
+static CURLcode ftp_state_loggedin(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  if(conn->ssl[FIRSTSOCKET].use) {
+    /* PBSZ = PROTECTION BUFFER SIZE.
+
+    The 'draft-murray-auth-ftp-ssl' (draft 12, page 7) says:
+
+    Specifically, the PROT command MUST be preceded by a PBSZ
+    command and a PBSZ command MUST be preceded by a successful
+    security data exchange (the TLS negotiation in this case)
+
+    ... (and on page 8):
+
+    Thus the PBSZ command must still be issued, but must have a
+    parameter of '0' to indicate that no buffering is taking place
+    and the data connection should not be encapsulated.
+    */
+    PPSENDF(&conn->proto.ftpc.pp, "PBSZ %d", 0);
+    state(conn, FTP_PBSZ);
+  }
+  else {
+    result = ftp_state_pwd(conn);
+  }
+  return result;
+}
+
+/* for USER and PASS responses */
+static CURLcode ftp_state_user_resp(struct connectdata *conn,
+                                    int ftpcode,
+                                    ftpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct FTP *ftp = data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  (void)instate; /* no use for this yet */
+
+  /* some need password anyway, and others just return 2xx ignored */
+  if((ftpcode == 331) && (ftpc->state == FTP_USER)) {
+    /* 331 Password required for ...
+       (the server requires to send the user's password too) */
+    PPSENDF(&ftpc->pp, "PASS %s", ftp->passwd?ftp->passwd:"");
+    state(conn, FTP_PASS);
+  }
+  else if(ftpcode/100 == 2) {
+    /* 230 User ... logged in.
+       (the user logged in with or without password) */
+    result = ftp_state_loggedin(conn);
+  }
+  else if(ftpcode == 332) {
+    if(data->set.str[STRING_FTP_ACCOUNT]) {
+      PPSENDF(&ftpc->pp, "ACCT %s", data->set.str[STRING_FTP_ACCOUNT]);
+      state(conn, FTP_ACCT);
+    }
+    else {
+      failf(data, "ACCT requested but none available");
+      result = CURLE_LOGIN_DENIED;
+    }
+  }
+  else {
+    /* All other response codes, like:
+
+    530 User ... access denied
+    (the server denies to log the specified user) */
+
+    if(conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] &&
+        !conn->data->state.ftp_trying_alternative) {
+      /* Ok, USER failed.  Let's try the supplied command. */
+      PPSENDF(&conn->proto.ftpc.pp, "%s",
+              conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
+      conn->data->state.ftp_trying_alternative = TRUE;
+      state(conn, FTP_USER);
+      result = CURLE_OK;
+    }
+    else {
+      failf(data, "Access denied: %03d", ftpcode);
+      result = CURLE_LOGIN_DENIED;
+    }
+  }
+  return result;
+}
+
+/* for ACCT response */
+static CURLcode ftp_state_acct_resp(struct connectdata *conn,
+                                    int ftpcode)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  if(ftpcode != 230) {
+    failf(data, "ACCT rejected by server: %03d", ftpcode);
+    result = CURLE_FTP_WEIRD_PASS_REPLY; /* FIX */
+  }
+  else
+    result = ftp_state_loggedin(conn);
+
+  return result;
+}
+
+
+static CURLcode ftp_statemach_act(struct connectdata *conn)
+{
+  CURLcode result;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  struct SessionHandle *data=conn->data;
+  int ftpcode;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+  static const char ftpauth[][4]  = { "SSL", "TLS" };
+  size_t nread = 0;
+
+  if(pp->sendleft)
+    return Curl_pp_flushsend(pp);
+
+  result = ftp_readresp(sock, pp, &ftpcode, &nread);
+  if(result)
+    return result;
+
+  if(ftpcode) {
+    /* we have now received a full FTP server response */
+    switch(ftpc->state) {
+    case FTP_WAIT220:
+      if(ftpcode == 230)
+        /* 230 User logged in - already! */
+        return ftp_state_user_resp(conn, ftpcode, ftpc->state);
+      else if(ftpcode != 220) {
+        failf(data, "Got a %03d ftp-server response when 220 was expected",
+              ftpcode);
+        return CURLE_FTP_WEIRD_SERVER_REPLY;
+      }
+
+      /* We have received a 220 response fine, now we proceed. */
+#ifdef HAVE_GSSAPI
+      if(data->set.krb) {
+        /* If not anonymous login, try a secure login. Note that this
+           procedure is still BLOCKING. */
+
+        Curl_sec_request_prot(conn, "private");
+        /* We set private first as default, in case the line below fails to
+           set a valid level */
+        Curl_sec_request_prot(conn, data->set.str[STRING_KRB_LEVEL]);
+
+        if(Curl_sec_login(conn))
+          infof(data, "Logging in with password in cleartext!\n");
+        else
+          infof(data, "Authentication successful\n");
+      }
+#endif
+
+      if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+        /* We don't have a SSL/TLS connection yet, but FTPS is
+           requested. Try a FTPS connection now */
+
+        ftpc->count3=0;
+        switch(data->set.ftpsslauth) {
+        case CURLFTPAUTH_DEFAULT:
+        case CURLFTPAUTH_SSL:
+          ftpc->count2 = 1; /* add one to get next */
+          ftpc->count1 = 0;
+          break;
+        case CURLFTPAUTH_TLS:
+          ftpc->count2 = -1; /* subtract one to get next */
+          ftpc->count1 = 1;
+          break;
+        default:
+          failf(data, "unsupported parameter to CURLOPT_FTPSSLAUTH: %d",
+                (int)data->set.ftpsslauth);
+          return CURLE_UNKNOWN_OPTION; /* we don't know what to do */
+        }
+        PPSENDF(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]);
+        state(conn, FTP_AUTH);
+      }
+      else {
+        result = ftp_state_user(conn);
+        if(result)
+          return result;
+      }
+
+      break;
+
+    case FTP_AUTH:
+      /* we have gotten the response to a previous AUTH command */
+
+      /* RFC2228 (page 5) says:
+       *
+       * If the server is willing to accept the named security mechanism,
+       * and does not require any security data, it must respond with
+       * reply code 234/334.
+       */
+
+      if((ftpcode == 234) || (ftpcode == 334)) {
+        /* Curl_ssl_connect is BLOCKING */
+        result = Curl_ssl_connect(conn, FIRSTSOCKET);
+        if(!result) {
+          conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */
+          result = ftp_state_user(conn);
+        }
+      }
+      else if(ftpc->count3 < 1) {
+        ftpc->count3++;
+        ftpc->count1 += ftpc->count2; /* get next attempt */
+        result = Curl_pp_sendf(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]);
+        /* remain in this same state */
+      }
+      else {
+        if(data->set.use_ssl > CURLUSESSL_TRY)
+          /* we failed and CURLUSESSL_CONTROL or CURLUSESSL_ALL is set */
+          result = CURLE_USE_SSL_FAILED;
+        else
+          /* ignore the failure and continue */
+          result = ftp_state_user(conn);
+      }
+
+      if(result)
+        return result;
+      break;
+
+    case FTP_USER:
+    case FTP_PASS:
+      result = ftp_state_user_resp(conn, ftpcode, ftpc->state);
+      break;
+
+    case FTP_ACCT:
+      result = ftp_state_acct_resp(conn, ftpcode);
+      break;
+
+    case FTP_PBSZ:
+      PPSENDF(&ftpc->pp, "PROT %c",
+              data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
+      state(conn, FTP_PROT);
+
+      break;
+
+    case FTP_PROT:
+      if(ftpcode/100 == 2)
+        /* We have enabled SSL for the data connection! */
+        conn->ssl[SECONDARYSOCKET].use =
+          (data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE;
+      /* FTP servers typically responds with 500 if they decide to reject
+         our 'P' request */
+      else if(data->set.use_ssl > CURLUSESSL_CONTROL)
+        /* we failed and bails out */
+        return CURLE_USE_SSL_FAILED;
+
+      if(data->set.ftp_ccc) {
+        /* CCC - Clear Command Channel
+         */
+        PPSENDF(&ftpc->pp, "%s", "CCC");
+        state(conn, FTP_CCC);
+      }
+      else {
+        result = ftp_state_pwd(conn);
+        if(result)
+          return result;
+      }
+      break;
+
+    case FTP_CCC:
+      if(ftpcode < 500) {
+        /* First shut down the SSL layer (note: this call will block) */
+        result = Curl_ssl_shutdown(conn, FIRSTSOCKET);
+
+        if(result) {
+          failf(conn->data, "Failed to clear the command channel (CCC)");
+          return result;
+        }
+      }
+
+      /* Then continue as normal */
+      result = ftp_state_pwd(conn);
+      if(result)
+        return result;
+      break;
+
+    case FTP_PWD:
+      if(ftpcode == 257) {
+        char *ptr=&data->state.buffer[4];  /* start on the first letter */
+        char *dir;
+        char *store;
+
+        dir = malloc(nread + 1);
+        if(!dir)
+          return CURLE_OUT_OF_MEMORY;
+
+        /* Reply format is like
+           257<space>[rubbish]"<directory-name>"<space><commentary> and the
+           RFC959 says
+
+           The directory name can contain any character; embedded
+           double-quotes should be escaped by double-quotes (the
+           "quote-doubling" convention).
+        */
+
+        /* scan for the first double-quote for non-standard responses */
+        while(ptr < &data->state.buffer[sizeof(data->state.buffer)]
+              && *ptr != '\n' && *ptr != '\0' && *ptr != '"')
+          ptr++;
+
+        if('\"' == *ptr) {
+          /* it started good */
+          ptr++;
+          for(store = dir; *ptr;) {
+            if('\"' == *ptr) {
+              if('\"' == ptr[1]) {
+                /* "quote-doubling" */
+                *store = ptr[1];
+                ptr++;
+              }
+              else {
+                /* end of path */
+                *store = '\0'; /* zero terminate */
+                break; /* get out of this loop */
+              }
+            }
+            else
+              *store = *ptr;
+            store++;
+            ptr++;
+          }
+
+          /* If the path name does not look like an absolute path (i.e.: it
+             does not start with a '/'), we probably need some server-dependent
+             adjustments. For example, this is the case when connecting to
+             an OS400 FTP server: this server supports two name syntaxes,
+             the default one being incompatible with standard pathes. In
+             addition, this server switches automatically to the regular path
+             syntax when one is encountered in a command: this results in
+             having an entrypath in the wrong syntax when later used in CWD.
+               The method used here is to check the server OS: we do it only
+             if the path name looks strange to minimize overhead on other
+             systems. */
+
+          if(!ftpc->server_os && dir[0] != '/') {
+
+            result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST");
+            if(result) {
+              free(dir);
+              return result;
+            }
+            Curl_safefree(ftpc->entrypath);
+            ftpc->entrypath = dir; /* remember this */
+            infof(data, "Entry path is '%s'\n", ftpc->entrypath);
+            /* also save it where getinfo can access it: */
+            data->state.most_recent_ftp_entrypath = ftpc->entrypath;
+            state(conn, FTP_SYST);
+            break;
+          }
+
+          Curl_safefree(ftpc->entrypath);
+          ftpc->entrypath = dir; /* remember this */
+          infof(data, "Entry path is '%s'\n", ftpc->entrypath);
+          /* also save it where getinfo can access it: */
+          data->state.most_recent_ftp_entrypath = ftpc->entrypath;
+        }
+        else {
+          /* couldn't get the path */
+          free(dir);
+          infof(data, "Failed to figure out path\n");
+        }
+      }
+      state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
+      DEBUGF(infof(data, "protocol connect phase DONE\n"));
+      break;
+
+    case FTP_SYST:
+      if(ftpcode == 215) {
+        char *ptr=&data->state.buffer[4];  /* start on the first letter */
+        char *os;
+        char *store;
+
+        os = malloc(nread + 1);
+        if(!os)
+          return CURLE_OUT_OF_MEMORY;
+
+        /* Reply format is like
+           215<space><OS-name><space><commentary>
+        */
+        while(*ptr == ' ')
+          ptr++;
+        for(store = os; *ptr && *ptr != ' ';)
+          *store++ = *ptr++;
+        *store = '\0'; /* zero terminate */
+
+        /* Check for special servers here. */
+
+        if(strequal(os, "OS/400")) {
+          /* Force OS400 name format 1. */
+          result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1");
+          if(result) {
+            free(os);
+            return result;
+          }
+          /* remember target server OS */
+          Curl_safefree(ftpc->server_os);
+          ftpc->server_os = os;
+          state(conn, FTP_NAMEFMT);
+          break;
+        }
+        else {
+          /* Nothing special for the target server. */
+          /* remember target server OS */
+          Curl_safefree(ftpc->server_os);
+          ftpc->server_os = os;
+        }
+      }
+      else {
+        /* Cannot identify server OS. Continue anyway and cross fingers. */
+      }
+
+      state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
+      DEBUGF(infof(data, "protocol connect phase DONE\n"));
+      break;
+
+    case FTP_NAMEFMT:
+      if(ftpcode == 250) {
+        /* Name format change successful: reload initial path. */
+        ftp_state_pwd(conn);
+        break;
+      }
+
+      state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
+      DEBUGF(infof(data, "protocol connect phase DONE\n"));
+      break;
+
+    case FTP_QUOTE:
+    case FTP_POSTQUOTE:
+    case FTP_RETR_PREQUOTE:
+    case FTP_STOR_PREQUOTE:
+      if((ftpcode >= 400) && !ftpc->count2) {
+        /* failure response code, and not allowed to fail */
+        failf(conn->data, "QUOT command failed with %03d", ftpcode);
+        return CURLE_QUOTE_ERROR;
+      }
+      result = ftp_state_quote(conn, FALSE, ftpc->state);
+      if(result)
+        return result;
+
+      break;
+
+    case FTP_CWD:
+      if(ftpcode/100 != 2) {
+        /* failure to CWD there */
+        if(conn->data->set.ftp_create_missing_dirs &&
+           ftpc->count1 && !ftpc->count2) {
+          /* try making it */
+          ftpc->count2++; /* counter to prevent CWD-MKD loops */
+          PPSENDF(&ftpc->pp, "MKD %s", ftpc->dirs[ftpc->count1 - 1]);
+          state(conn, FTP_MKD);
+        }
+        else {
+          /* return failure */
+          failf(data, "Server denied you to change to the given directory");
+          ftpc->cwdfail = TRUE; /* don't remember this path as we failed
+                                   to enter it */
+          return CURLE_REMOTE_ACCESS_DENIED;
+        }
+      }
+      else {
+        /* success */
+        ftpc->count2=0;
+        if(++ftpc->count1 <= ftpc->dirdepth) {
+          /* send next CWD */
+          PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->count1 - 1]);
+        }
+        else {
+          result = ftp_state_mdtm(conn);
+          if(result)
+            return result;
+        }
+      }
+      break;
+
+    case FTP_MKD:
+      if((ftpcode/100 != 2) && !ftpc->count3--) {
+        /* failure to MKD the dir */
+        failf(data, "Failed to MKD dir: %03d", ftpcode);
+        return CURLE_REMOTE_ACCESS_DENIED;
+      }
+      state(conn, FTP_CWD);
+      /* send CWD */
+      PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->count1 - 1]);
+      break;
+
+    case FTP_MDTM:
+      result = ftp_state_mdtm_resp(conn, ftpcode);
+      break;
+
+    case FTP_TYPE:
+    case FTP_LIST_TYPE:
+    case FTP_RETR_TYPE:
+    case FTP_STOR_TYPE:
+      result = ftp_state_type_resp(conn, ftpcode, ftpc->state);
+      break;
+
+    case FTP_SIZE:
+    case FTP_RETR_SIZE:
+    case FTP_STOR_SIZE:
+      result = ftp_state_size_resp(conn, ftpcode, ftpc->state);
+      break;
+
+    case FTP_REST:
+    case FTP_RETR_REST:
+      result = ftp_state_rest_resp(conn, ftpcode, ftpc->state);
+      break;
+
+    case FTP_PRET:
+      if(ftpcode != 200) {
+        /* there only is this one standard OK return code. */
+        failf(data, "PRET command not accepted: %03d", ftpcode);
+        return CURLE_FTP_PRET_FAILED;
+      }
+      result = ftp_state_use_pasv(conn);
+      break;
+
+    case FTP_PASV:
+      result = ftp_state_pasv_resp(conn, ftpcode);
+      break;
+
+    case FTP_PORT:
+      result = ftp_state_port_resp(conn, ftpcode);
+      break;
+
+    case FTP_LIST:
+    case FTP_RETR:
+      result = ftp_state_get_resp(conn, ftpcode, ftpc->state);
+      break;
+
+    case FTP_STOR:
+      result = ftp_state_stor_resp(conn, ftpcode, ftpc->state);
+      break;
+
+    case FTP_QUIT:
+      /* fallthrough, just stop! */
+    default:
+      /* internal error */
+      state(conn, FTP_STOP);
+      break;
+    }
+  } /* if(ftpcode) */
+
+  return result;
+}
+
+
+/* called repeatedly until done from multi.c */
+static CURLcode ftp_multi_statemach(struct connectdata *conn,
+                                    bool *done)
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE);
+
+  /* Check for the state outside of the Curl_socket_ready() return code checks
+     since at times we are in fact already in this state when this function
+     gets called. */
+  *done = (ftpc->state == FTP_STOP) ? TRUE : FALSE;
+
+  return result;
+}
+
+static CURLcode ftp_block_statemach(struct connectdata *conn)
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+  CURLcode result = CURLE_OK;
+
+  while(ftpc->state != FTP_STOP) {
+    result = Curl_pp_statemach(pp, TRUE);
+    if(result)
+      break;
+  }
+
+  return result;
+}
+
+/*
+ * ftp_connect() should do everything that is to be considered a part of
+ * the connection phase.
+ *
+ * The variable 'done' points to will be TRUE if the protocol-layer connect
+ * phase is done when this function returns, or FALSE if not.
+ *
+ */
+static CURLcode ftp_connect(struct connectdata *conn,
+                                 bool *done) /* see description above */
+{
+  CURLcode result;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+
+  *done = FALSE; /* default to not done yet */
+
+  /* We always support persistent connections on ftp */
+  connkeep(conn, "FTP default");
+
+  pp->response_time = RESP_TIMEOUT; /* set default response time-out */
+  pp->statemach_act = ftp_statemach_act;
+  pp->endofresp = ftp_endofresp;
+  pp->conn = conn;
+
+  if(conn->handler->flags & PROTOPT_SSL) {
+    /* BLOCKING */
+    result = Curl_ssl_connect(conn, FIRSTSOCKET);
+    if(result)
+      return result;
+  }
+
+  Curl_pp_init(pp); /* init the generic pingpong data */
+
+  /* When we connect, we start in the state where we await the 220
+     response */
+  state(conn, FTP_WAIT220);
+
+  result = ftp_multi_statemach(conn, done);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_done()
+ *
+ * The DONE function. This does what needs to be done after a single DO has
+ * performed.
+ *
+ * Input argument is already checked for validity.
+ */
+static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
+                              bool premature)
+{
+  struct SessionHandle *data = conn->data;
+  struct FTP *ftp = data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+  ssize_t nread;
+  int ftpcode;
+  CURLcode result = CURLE_OK;
+  bool was_ctl_valid = ftpc->ctl_valid;
+  char *path;
+  const char *path_to_use = data->state.path;
+
+  if(!ftp)
+    /* When the easy handle is removed from the multi while libcurl is still
+     * trying to resolve the host name, it seems that the ftp struct is not
+     * yet initialized, but the removal action calls Curl_done() which calls
+     * this function. So we simply return success if no ftp pointer is set.
+     */
+    return CURLE_OK;
+
+  switch(status) {
+  case CURLE_BAD_DOWNLOAD_RESUME:
+  case CURLE_FTP_WEIRD_PASV_REPLY:
+  case CURLE_FTP_PORT_FAILED:
+  case CURLE_FTP_ACCEPT_FAILED:
+  case CURLE_FTP_ACCEPT_TIMEOUT:
+  case CURLE_FTP_COULDNT_SET_TYPE:
+  case CURLE_FTP_COULDNT_RETR_FILE:
+  case CURLE_PARTIAL_FILE:
+  case CURLE_UPLOAD_FAILED:
+  case CURLE_REMOTE_ACCESS_DENIED:
+  case CURLE_FILESIZE_EXCEEDED:
+  case CURLE_REMOTE_FILE_NOT_FOUND:
+  case CURLE_WRITE_ERROR:
+    /* the connection stays alive fine even though this happened */
+    /* fall-through */
+  case CURLE_OK: /* doesn't affect the control connection's status */
+    if(!premature) {
+      ftpc->ctl_valid = was_ctl_valid;
+      break;
+    }
+    /* until we cope better with prematurely ended requests, let them
+     * fallback as if in complete failure */
+  default:       /* by default, an error means the control connection is
+                    wedged and should not be used anymore */
+    ftpc->ctl_valid = FALSE;
+    ftpc->cwdfail = TRUE; /* set this TRUE to prevent us to remember the
+                             current path, as this connection is going */
+    connclose(conn, "FTP ended with bad error code");
+    result = status;      /* use the already set error code */
+    break;
+  }
+
+  /* now store a copy of the directory we are in */
+  free(ftpc->prevpath);
+
+  if(data->set.wildcardmatch) {
+    if(data->set.chunk_end && ftpc->file) {
+      data->set.chunk_end(data->wildcard.customptr);
+    }
+    ftpc->known_filesize = -1;
+  }
+
+  /* get the "raw" path */
+  path = curl_easy_unescape(data, path_to_use, 0, NULL);
+  if(!path) {
+    /* out of memory, but we can limp along anyway (and should try to
+     * since we may already be in the out of memory cleanup path) */
+    if(!result)
+      result = CURLE_OUT_OF_MEMORY;
+    ftpc->ctl_valid = FALSE; /* mark control connection as bad */
+    connclose(conn, "FTP: out of memory!"); /* mark for connection closure */
+    ftpc->prevpath = NULL; /* no path remembering */
+  }
+  else {
+    size_t flen = ftpc->file?strlen(ftpc->file):0; /* file is "raw" already */
+    size_t dlen = strlen(path)-flen;
+    if(!ftpc->cwdfail) {
+      if(dlen && (data->set.ftp_filemethod != FTPFILE_NOCWD)) {
+        ftpc->prevpath = path;
+        if(flen)
+          /* if 'path' is not the whole string */
+          ftpc->prevpath[dlen]=0; /* terminate */
+      }
+      else {
+        /* we never changed dir */
+        ftpc->prevpath=strdup("");
+        free(path);
+      }
+      if(ftpc->prevpath)
+        infof(data, "Remembering we are in dir \"%s\"\n", ftpc->prevpath);
+    }
+    else {
+      ftpc->prevpath = NULL; /* no path */
+      free(path);
+    }
+  }
+  /* free the dir tree and file parts */
+  freedirs(ftpc);
+
+  /* shut down the socket to inform the server we're done */
+
+#ifdef _WIN32_WCE
+  shutdown(conn->sock[SECONDARYSOCKET], 2);  /* SD_BOTH */
+#endif
+
+  if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
+    if(!result && ftpc->dont_check && data->req.maxdownload > 0) {
+      /* partial download completed */
+      result = Curl_pp_sendf(pp, "%s", "ABOR");
+      if(result) {
+        failf(data, "Failure sending ABOR command: %s",
+              curl_easy_strerror(result));
+        ftpc->ctl_valid = FALSE; /* mark control connection as bad */
+        connclose(conn, "ABOR command failed"); /* connection closure */
+      }
+    }
+
+    if(conn->ssl[SECONDARYSOCKET].use) {
+      /* The secondary socket is using SSL so we must close down that part
+         first before we close the socket for real */
+      Curl_ssl_close(conn, SECONDARYSOCKET);
+
+      /* Note that we keep "use" set to TRUE since that (next) connection is
+         still requested to use SSL */
+    }
+    if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
+      Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
+      conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
+      conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
+    }
+  }
+
+  if(!result && (ftp->transfer == FTPTRANSFER_BODY) && ftpc->ctl_valid &&
+     pp->pending_resp && !premature) {
+    /*
+     * Let's see what the server says about the transfer we just performed,
+     * but lower the timeout as sometimes this connection has died while the
+     * data has been transferred. This happens when doing through NATs etc that
+     * abandon old silent connections.
+     */
+    long old_time = pp->response_time;
+
+    pp->response_time = 60*1000; /* give it only a minute for now */
+    pp->response = Curl_tvnow(); /* timeout relative now */
+
+    result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+
+    pp->response_time = old_time; /* set this back to previous value */
+
+    if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) {
+      failf(data, "control connection looks dead");
+      ftpc->ctl_valid = FALSE; /* mark control connection as bad */
+      connclose(conn, "Timeout or similar in FTP DONE operation"); /* close */
+    }
+
+    if(result)
+      return result;
+
+    if(ftpc->dont_check && data->req.maxdownload > 0) {
+      /* we have just sent ABOR and there is no reliable way to check if it was
+       * successful or not; we have to close the connection now */
+      infof(data, "partial download completed, closing connection\n");
+      connclose(conn, "Partial download with no ability to check");
+      return result;
+    }
+
+    if(!ftpc->dont_check) {
+      /* 226 Transfer complete, 250 Requested file action okay, completed. */
+      if((ftpcode != 226) && (ftpcode != 250)) {
+        failf(data, "server did not report OK, got %d", ftpcode);
+        result = CURLE_PARTIAL_FILE;
+      }
+    }
+  }
+
+  if(result || premature)
+    /* the response code from the transfer showed an error already so no
+       use checking further */
+    ;
+  else if(data->set.upload) {
+    if((-1 != data->state.infilesize) &&
+       (data->state.infilesize != *ftp->bytecountp) &&
+       !data->set.crlf &&
+       (ftp->transfer == FTPTRANSFER_BODY)) {
+      failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T
+            " out of %" CURL_FORMAT_CURL_OFF_T " bytes)",
+            *ftp->bytecountp, data->state.infilesize);
+      result = CURLE_PARTIAL_FILE;
+    }
+  }
+  else {
+    if((-1 != data->req.size) &&
+       (data->req.size != *ftp->bytecountp) &&
+#ifdef CURL_DO_LINEEND_CONV
+       /* Most FTP servers don't adjust their file SIZE response for CRLFs, so
+        * we'll check to see if the discrepancy can be explained by the number
+        * of CRLFs we've changed to LFs.
+        */
+       ((data->req.size + data->state.crlf_conversions) !=
+        *ftp->bytecountp) &&
+#endif /* CURL_DO_LINEEND_CONV */
+       (data->req.maxdownload != *ftp->bytecountp)) {
+      failf(data, "Received only partial file: %" CURL_FORMAT_CURL_OFF_T
+            " bytes", *ftp->bytecountp);
+      result = CURLE_PARTIAL_FILE;
+    }
+    else if(!ftpc->dont_check &&
+            !*ftp->bytecountp &&
+            (data->req.size>0)) {
+      failf(data, "No data was received!");
+      result = CURLE_FTP_COULDNT_RETR_FILE;
+    }
+  }
+
+  /* clear these for next connection */
+  ftp->transfer = FTPTRANSFER_BODY;
+  ftpc->dont_check = FALSE;
+
+  /* Send any post-transfer QUOTE strings? */
+  if(!status && !result && !premature && data->set.postquote)
+    result = ftp_sendquote(conn, data->set.postquote);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_sendquote()
+ *
+ * Where a 'quote' means a list of custom commands to send to the server.
+ * The quote list is passed as an argument.
+ *
+ * BLOCKING
+ */
+
+static
+CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote)
+{
+  struct curl_slist *item;
+  ssize_t nread;
+  int ftpcode;
+  CURLcode result;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+
+  item = quote;
+  while(item) {
+    if(item->data) {
+      char *cmd = item->data;
+      bool acceptfail = FALSE;
+
+      /* if a command starts with an asterisk, which a legal FTP command never
+         can, the command will be allowed to fail without it causing any
+         aborts or cancels etc. It will cause libcurl to act as if the command
+         is successful, whatever the server reponds. */
+
+      if(cmd[0] == '*') {
+        cmd++;
+        acceptfail = TRUE;
+      }
+
+      PPSENDF(&conn->proto.ftpc.pp, "%s", cmd);
+
+      pp->response = Curl_tvnow(); /* timeout relative now */
+
+      result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+      if(result)
+        return result;
+
+      if(!acceptfail && (ftpcode >= 400)) {
+        failf(conn->data, "QUOT string not accepted: %s", cmd);
+        return CURLE_QUOTE_ERROR;
+      }
+    }
+
+    item = item->next;
+  }
+
+  return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * ftp_need_type()
+ *
+ * Returns TRUE if we in the current situation should send TYPE
+ */
+static int ftp_need_type(struct connectdata *conn,
+                         bool ascii_wanted)
+{
+  return conn->proto.ftpc.transfertype != (ascii_wanted?'A':'I');
+}
+
+/***********************************************************************
+ *
+ * ftp_nb_type()
+ *
+ * Set TYPE. We only deal with ASCII or BINARY so this function
+ * sets one of them.
+ * If the transfer type is not sent, simulate on OK response in newstate
+ */
+static CURLcode ftp_nb_type(struct connectdata *conn,
+                            bool ascii, ftpstate newstate)
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  CURLcode result;
+  char want = (char)(ascii?'A':'I');
+
+  if(ftpc->transfertype == want) {
+    state(conn, newstate);
+    return ftp_state_type_resp(conn, 200, newstate);
+  }
+
+  PPSENDF(&ftpc->pp, "TYPE %c", want);
+  state(conn, newstate);
+
+  /* keep track of our current transfer type */
+  ftpc->transfertype = want;
+  return CURLE_OK;
+}
+
+/***************************************************************************
+ *
+ * ftp_pasv_verbose()
+ *
+ * This function only outputs some informationals about this second connection
+ * when we've issued a PASV command before and thus we have connected to a
+ * possibly new IP address.
+ *
+ */
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static void
+ftp_pasv_verbose(struct connectdata *conn,
+                 Curl_addrinfo *ai,
+                 char *newhost, /* ascii version */
+                 int port)
+{
+  char buf[256];
+  Curl_printable_address(ai, buf, sizeof(buf));
+  infof(conn->data, "Connecting to %s (%s) port %d\n", newhost, buf, port);
+}
+#endif
+
+/*
+  Check if this is a range download, and if so, set the internal variables
+  properly.
+ */
+
+static CURLcode ftp_range(struct connectdata *conn)
+{
+  curl_off_t from, to;
+  char *ptr;
+  char *ptr2;
+  struct SessionHandle *data = conn->data;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  if(data->state.use_range && data->state.range) {
+    from=curlx_strtoofft(data->state.range, &ptr, 0);
+    while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
+      ptr++;
+    to=curlx_strtoofft(ptr, &ptr2, 0);
+    if(ptr == ptr2) {
+      /* we didn't get any digit */
+      to=-1;
+    }
+    if((-1 == to) && (from>=0)) {
+      /* X - */
+      data->state.resume_from = from;
+      DEBUGF(infof(conn->data, "FTP RANGE %" CURL_FORMAT_CURL_OFF_T
+                   " to end of file\n", from));
+    }
+    else if(from < 0) {
+      /* -Y */
+      data->req.maxdownload = -from;
+      data->state.resume_from = from;
+      DEBUGF(infof(conn->data, "FTP RANGE the last %" CURL_FORMAT_CURL_OFF_T
+                   " bytes\n", -from));
+    }
+    else {
+      /* X-Y */
+      data->req.maxdownload = (to-from)+1; /* include last byte */
+      data->state.resume_from = from;
+      DEBUGF(infof(conn->data, "FTP RANGE from %" CURL_FORMAT_CURL_OFF_T
+                   " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n",
+                   from, data->req.maxdownload));
+    }
+    DEBUGF(infof(conn->data, "range-download from %" CURL_FORMAT_CURL_OFF_T
+                 " to %" CURL_FORMAT_CURL_OFF_T ", totally %"
+                 CURL_FORMAT_CURL_OFF_T " bytes\n",
+                 from, to, data->req.maxdownload));
+    ftpc->dont_check = TRUE; /* dont check for successful transfer */
+  }
+  else
+    data->req.maxdownload = -1;
+  return CURLE_OK;
+}
+
+
+/*
+ * ftp_do_more()
+ *
+ * This function shall be called when the second FTP (data) connection is
+ * connected.
+ *
+ * 'complete' can return 0 for incomplete, 1 for done and -1 for go back
+ * (which basically is only for when PASV is being sent to retry a failed
+ * EPSV).
+ */
+
+static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
+{
+  struct SessionHandle *data=conn->data;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  CURLcode result = CURLE_OK;
+  bool connected = FALSE;
+  bool complete = FALSE;
+
+  /* the ftp struct is inited in ftp_connect() */
+  struct FTP *ftp = data->req.protop;
+
+  /* if the second connection isn't done yet, wait for it */
+  if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
+    if(conn->tunnel_state[SECONDARYSOCKET] == TUNNEL_CONNECT) {
+      /* As we're in TUNNEL_CONNECT state now, we know the proxy name and port
+         aren't used so we blank their arguments. TODO: make this nicer */
+      result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0, FALSE);
+
+      return result;
+    }
+
+    result = Curl_is_connected(conn, SECONDARYSOCKET, &connected);
+
+    /* Ready to do more? */
+    if(connected) {
+      DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
+      if(conn->bits.proxy) {
+        infof(data, "Connection to proxy confirmed\n");
+        result = proxy_magic(conn, ftpc->newhost, ftpc->newport, &connected);
+      }
+    }
+    else {
+      if(result && (ftpc->count1 == 0)) {
+        *completep = -1; /* go back to DOING please */
+        /* this is a EPSV connect failing, try PASV instead */
+        return ftp_epsv_disable(conn);
+      }
+      return result;
+    }
+  }
+
+  if(ftpc->state) {
+    /* already in a state so skip the intial commands.
+       They are only done to kickstart the do_more state */
+    result = ftp_multi_statemach(conn, &complete);
+
+    *completep = (int)complete;
+
+    /* if we got an error or if we don't wait for a data connection return
+       immediately */
+    if(result || (ftpc->wait_data_conn != TRUE))
+      return result;
+
+    if(ftpc->wait_data_conn)
+      /* if we reach the end of the FTP state machine here, *complete will be
+         TRUE but so is ftpc->wait_data_conn, which says we need to wait for
+         the data connection and therefore we're not actually complete */
+      *completep = 0;
+  }
+
+  if(ftp->transfer <= FTPTRANSFER_INFO) {
+    /* a transfer is about to take place, or if not a file name was given
+       so we'll do a SIZE on it later and then we need the right TYPE first */
+
+    if(ftpc->wait_data_conn == TRUE) {
+      bool serv_conned;
+
+      result = ReceivedServerConnect(conn, &serv_conned);
+      if(result)
+        return result; /* Failed to accept data connection */
+
+      if(serv_conned) {
+        /* It looks data connection is established */
+        result = AcceptServerConnect(conn);
+        ftpc->wait_data_conn = FALSE;
+        if(!result)
+          result = InitiateTransfer(conn);
+
+        if(result)
+          return result;
+
+        *completep = 1; /* this state is now complete when the server has
+                           connected back to us */
+      }
+    }
+    else if(data->set.upload) {
+      result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_STOR_TYPE);
+      if(result)
+        return result;
+
+      result = ftp_multi_statemach(conn, &complete);
+      if(ftpc->wait_data_conn)
+        /* if we reach the end of the FTP state machine here, *complete will be
+           TRUE but so is ftpc->wait_data_conn, which says we need to wait for
+           the data connection and therefore we're not actually complete */
+        *completep = 0;
+      else
+        *completep = (int)complete;
+    }
+    else {
+      /* download */
+      ftp->downloadsize = -1; /* unknown as of yet */
+
+      result = ftp_range(conn);
+      if(result)
+        ;
+      else if(data->set.ftp_list_only || !ftpc->file) {
+        /* The specified path ends with a slash, and therefore we think this
+           is a directory that is requested, use LIST. But before that we
+           need to set ASCII transfer mode. */
+
+        /* But only if a body transfer was requested. */
+        if(ftp->transfer == FTPTRANSFER_BODY) {
+          result = ftp_nb_type(conn, TRUE, FTP_LIST_TYPE);
+          if(result)
+            return result;
+        }
+        /* otherwise just fall through */
+      }
+      else {
+        result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_RETR_TYPE);
+        if(result)
+          return result;
+      }
+
+      result = ftp_multi_statemach(conn, &complete);
+      *completep = (int)complete;
+    }
+    return result;
+  }
+
+  if(!result && (ftp->transfer != FTPTRANSFER_BODY))
+    /* no data to transfer. FIX: it feels like a kludge to have this here
+       too! */
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+  if(!ftpc->wait_data_conn) {
+    /* no waiting for the data connection so this is now complete */
+    *completep = 1;
+    DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result));
+  }
+
+  return result;
+}
+
+
+
+/***********************************************************************
+ *
+ * ftp_perform()
+ *
+ * This is the actual DO function for FTP. Get a file/directory according to
+ * the options previously setup.
+ */
+
+static
+CURLcode ftp_perform(struct connectdata *conn,
+                     bool *connected,  /* connect status after PASV / PORT */
+                     bool *dophase_done)
+{
+  /* this is FTP and no proxy */
+  CURLcode result=CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  if(conn->data->set.opt_no_body) {
+    /* requested no body means no transfer... */
+    struct FTP *ftp = conn->data->req.protop;
+    ftp->transfer = FTPTRANSFER_INFO;
+  }
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* start the first command in the DO phase */
+  result = ftp_state_quote(conn, TRUE, FTP_QUOTE);
+  if(result)
+    return result;
+
+  /* run the state-machine */
+  result = ftp_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[SECONDARYSOCKET];
+
+  infof(conn->data, "ftp_perform ends with SECONDARY: %d\n", *connected);
+
+  if(*dophase_done)
+    DEBUGF(infof(conn->data, "DO phase is complete1\n"));
+
+  return result;
+}
+
+static void wc_data_dtor(void *ptr)
+{
+  struct ftp_wc_tmpdata *tmp = ptr;
+  if(tmp)
+    Curl_ftp_parselist_data_free(&tmp->parser);
+  free(tmp);
+}
+
+static CURLcode init_wc_data(struct connectdata *conn)
+{
+  char *last_slash;
+  char *path = conn->data->state.path;
+  struct WildcardData *wildcard = &(conn->data->wildcard);
+  CURLcode result = CURLE_OK;
+  struct ftp_wc_tmpdata *ftp_tmp;
+
+  last_slash = strrchr(conn->data->state.path, '/');
+  if(last_slash) {
+    last_slash++;
+    if(last_slash[0] == '\0') {
+      wildcard->state = CURLWC_CLEAN;
+      result = ftp_parse_url_path(conn);
+      return result;
+    }
+    else {
+      wildcard->pattern = strdup(last_slash);
+      if(!wildcard->pattern)
+        return CURLE_OUT_OF_MEMORY;
+      last_slash[0] = '\0'; /* cut file from path */
+    }
+  }
+  else { /* there is only 'wildcard pattern' or nothing */
+    if(path[0]) {
+      wildcard->pattern = strdup(path);
+      if(!wildcard->pattern)
+        return CURLE_OUT_OF_MEMORY;
+      path[0] = '\0';
+    }
+    else { /* only list */
+      wildcard->state = CURLWC_CLEAN;
+      result = ftp_parse_url_path(conn);
+      return result;
+    }
+  }
+
+  /* program continues only if URL is not ending with slash, allocate needed
+     resources for wildcard transfer */
+
+  /* allocate ftp protocol specific temporary wildcard data */
+  ftp_tmp = calloc(1, sizeof(struct ftp_wc_tmpdata));
+  if(!ftp_tmp) {
+    Curl_safefree(wildcard->pattern);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* INITIALIZE parselist structure */
+  ftp_tmp->parser = Curl_ftp_parselist_data_alloc();
+  if(!ftp_tmp->parser) {
+    Curl_safefree(wildcard->pattern);
+    free(ftp_tmp);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  wildcard->tmp = ftp_tmp; /* put it to the WildcardData tmp pointer */
+  wildcard->tmp_dtor = wc_data_dtor;
+
+  /* wildcard does not support NOCWD option (assert it?) */
+  if(conn->data->set.ftp_filemethod == FTPFILE_NOCWD)
+    conn->data->set.ftp_filemethod = FTPFILE_MULTICWD;
+
+  /* try to parse ftp url */
+  result = ftp_parse_url_path(conn);
+  if(result) {
+    Curl_safefree(wildcard->pattern);
+    wildcard->tmp_dtor(wildcard->tmp);
+    wildcard->tmp_dtor = ZERO_NULL;
+    wildcard->tmp = NULL;
+    return result;
+  }
+
+  wildcard->path = strdup(conn->data->state.path);
+  if(!wildcard->path) {
+    Curl_safefree(wildcard->pattern);
+    wildcard->tmp_dtor(wildcard->tmp);
+    wildcard->tmp_dtor = ZERO_NULL;
+    wildcard->tmp = NULL;
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* backup old write_function */
+  ftp_tmp->backup.write_function = conn->data->set.fwrite_func;
+  /* parsing write function */
+  conn->data->set.fwrite_func = Curl_ftp_parselist;
+  /* backup old file descriptor */
+  ftp_tmp->backup.file_descriptor = conn->data->set.out;
+  /* let the writefunc callback know what curl pointer is working with */
+  conn->data->set.out = conn;
+
+  infof(conn->data, "Wildcard - Parsing started\n");
+  return CURLE_OK;
+}
+
+/* This is called recursively */
+static CURLcode wc_statemach(struct connectdata *conn)
+{
+  struct WildcardData * const wildcard = &(conn->data->wildcard);
+  CURLcode result = CURLE_OK;
+
+  switch (wildcard->state) {
+  case CURLWC_INIT:
+    result = init_wc_data(conn);
+    if(wildcard->state == CURLWC_CLEAN)
+      /* only listing! */
+      break;
+    else
+      wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
+    break;
+
+  case CURLWC_MATCHING: {
+    /* In this state is LIST response successfully parsed, so lets restore
+       previous WRITEFUNCTION callback and WRITEDATA pointer */
+    struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
+    conn->data->set.fwrite_func = ftp_tmp->backup.write_function;
+    conn->data->set.out = ftp_tmp->backup.file_descriptor;
+    ftp_tmp->backup.write_function = ZERO_NULL;
+    ftp_tmp->backup.file_descriptor = NULL;
+    wildcard->state = CURLWC_DOWNLOADING;
+
+    if(Curl_ftp_parselist_geterror(ftp_tmp->parser)) {
+      /* error found in LIST parsing */
+      wildcard->state = CURLWC_CLEAN;
+      return wc_statemach(conn);
+    }
+    else if(wildcard->filelist->size == 0) {
+      /* no corresponding file */
+      wildcard->state = CURLWC_CLEAN;
+      return CURLE_REMOTE_FILE_NOT_FOUND;
+    }
+    return wc_statemach(conn);
+  }
+
+  case CURLWC_DOWNLOADING: {
+    /* filelist has at least one file, lets get first one */
+    struct ftp_conn *ftpc = &conn->proto.ftpc;
+    struct curl_fileinfo *finfo = wildcard->filelist->head->ptr;
+
+    char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
+    if(!tmp_path)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* switch default "state.pathbuffer" and tmp_path, good to see
+       ftp_parse_url_path function to understand this trick */
+    Curl_safefree(conn->data->state.pathbuffer);
+    conn->data->state.pathbuffer = tmp_path;
+    conn->data->state.path = tmp_path;
+
+    infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
+    if(conn->data->set.chunk_bgn) {
+      long userresponse = conn->data->set.chunk_bgn(
+          finfo, wildcard->customptr, (int)wildcard->filelist->size);
+      switch(userresponse) {
+      case CURL_CHUNK_BGN_FUNC_SKIP:
+        infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
+              finfo->filename);
+        wildcard->state = CURLWC_SKIP;
+        return wc_statemach(conn);
+      case CURL_CHUNK_BGN_FUNC_FAIL:
+        return CURLE_CHUNK_FAILED;
+      }
+    }
+
+    if(finfo->filetype != CURLFILETYPE_FILE) {
+      wildcard->state = CURLWC_SKIP;
+      return wc_statemach(conn);
+    }
+
+    if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
+      ftpc->known_filesize = finfo->size;
+
+    result = ftp_parse_url_path(conn);
+    if(result)
+      return result;
+
+    /* we don't need the Curl_fileinfo of first file anymore */
+    Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
+
+    if(wildcard->filelist->size == 0) { /* remains only one file to down. */
+      wildcard->state = CURLWC_CLEAN;
+      /* after that will be ftp_do called once again and no transfer
+         will be done because of CURLWC_CLEAN state */
+      return CURLE_OK;
+    }
+  } break;
+
+  case CURLWC_SKIP: {
+    if(conn->data->set.chunk_end)
+      conn->data->set.chunk_end(conn->data->wildcard.customptr);
+    Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
+    wildcard->state = (wildcard->filelist->size == 0) ?
+                      CURLWC_CLEAN : CURLWC_DOWNLOADING;
+    return wc_statemach(conn);
+  }
+
+  case CURLWC_CLEAN: {
+    struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
+    result = CURLE_OK;
+    if(ftp_tmp)
+      result = Curl_ftp_parselist_geterror(ftp_tmp->parser);
+
+    wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE;
+  } break;
+
+  case CURLWC_DONE:
+  case CURLWC_ERROR:
+    break;
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_do()
+ *
+ * This function is registered as 'curl_do' function. It decodes the path
+ * parts etc as a wrapper to the actual DO function (ftp_perform).
+ *
+ * The input argument is already checked for validity.
+ */
+static CURLcode ftp_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  *done = FALSE; /* default to false */
+  ftpc->wait_data_conn = FALSE; /* default to no such wait */
+
+  if(conn->data->set.wildcardmatch) {
+    result = wc_statemach(conn);
+    if(conn->data->wildcard.state == CURLWC_SKIP ||
+      conn->data->wildcard.state == CURLWC_DONE) {
+      /* do not call ftp_regular_transfer */
+      return CURLE_OK;
+    }
+    if(result) /* error, loop or skipping the file */
+      return result;
+  }
+  else { /* no wildcard FSM needed */
+    result = ftp_parse_url_path(conn);
+    if(result)
+      return result;
+  }
+
+  result = ftp_regular_transfer(conn, done);
+
+  return result;
+}
+
+
+CURLcode Curl_ftpsendf(struct connectdata *conn,
+                       const char *fmt, ...)
+{
+  ssize_t bytes_written;
+#define SBUF_SIZE 1024
+  char s[SBUF_SIZE];
+  size_t write_len;
+  char *sptr=s;
+  CURLcode result = CURLE_OK;
+#ifdef HAVE_GSSAPI
+  enum protection_level data_sec = conn->data_prot;
+#endif
+
+  va_list ap;
+  va_start(ap, fmt);
+  write_len = vsnprintf(s, SBUF_SIZE-3, fmt, ap);
+  va_end(ap);
+
+  strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */
+  write_len +=2;
+
+  bytes_written=0;
+
+  result = Curl_convert_to_network(conn->data, s, write_len);
+  /* Curl_convert_to_network calls failf if unsuccessful */
+  if(result)
+    return result;
+
+  for(;;) {
+#ifdef HAVE_GSSAPI
+    conn->data_prot = PROT_CMD;
+#endif
+    result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
+                        &bytes_written);
+#ifdef HAVE_GSSAPI
+    DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
+    conn->data_prot = data_sec;
+#endif
+
+    if(result)
+      break;
+
+    if(conn->data->set.verbose)
+      Curl_debug(conn->data, CURLINFO_HEADER_OUT,
+                 sptr, (size_t)bytes_written, conn);
+
+    if(bytes_written != (ssize_t)write_len) {
+      write_len -= bytes_written;
+      sptr += bytes_written;
+    }
+    else
+      break;
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_quit()
+ *
+ * This should be called before calling sclose() on an ftp control connection
+ * (not data connections). We should then wait for the response from the
+ * server before returning. The calling code should then try to close the
+ * connection.
+ *
+ */
+static CURLcode ftp_quit(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  if(conn->proto.ftpc.ctl_valid) {
+    result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "QUIT");
+    if(result) {
+      failf(conn->data, "Failure sending QUIT command: %s",
+            curl_easy_strerror(result));
+      conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */
+      connclose(conn, "QUIT command failed"); /* mark for connection closure */
+      state(conn, FTP_STOP);
+      return result;
+    }
+
+    state(conn, FTP_QUIT);
+
+    result = ftp_block_statemach(conn);
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_disconnect()
+ *
+ * Disconnect from an FTP server. Cleanup protocol-specific per-connection
+ * resources. BLOCKING.
+ */
+static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  struct ftp_conn *ftpc= &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+
+  /* We cannot send quit unconditionally. If this connection is stale or
+     bad in any way, sending quit and waiting around here will make the
+     disconnect wait in vain and cause more problems than we need to.
+
+     ftp_quit() will check the state of ftp->ctl_valid. If it's ok it
+     will try to send the QUIT command, otherwise it will just return.
+  */
+  if(dead_connection)
+    ftpc->ctl_valid = FALSE;
+
+  /* The FTP session may or may not have been allocated/setup at this point! */
+  (void)ftp_quit(conn); /* ignore errors on the QUIT */
+
+  if(ftpc->entrypath) {
+    struct SessionHandle *data = conn->data;
+    if(data->state.most_recent_ftp_entrypath == ftpc->entrypath) {
+      data->state.most_recent_ftp_entrypath = NULL;
+    }
+    free(ftpc->entrypath);
+    ftpc->entrypath = NULL;
+  }
+
+  freedirs(ftpc);
+  free(ftpc->prevpath);
+  ftpc->prevpath = NULL;
+  free(ftpc->server_os);
+  ftpc->server_os = NULL;
+
+  Curl_pp_disconnect(pp);
+
+#ifdef HAVE_GSSAPI
+  Curl_sec_end(conn);
+#endif
+
+  return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * ftp_parse_url_path()
+ *
+ * Parse the URL path into separate path components.
+ *
+ */
+static
+CURLcode ftp_parse_url_path(struct connectdata *conn)
+{
+  struct SessionHandle *data = conn->data;
+  /* the ftp struct is already inited in ftp_connect() */
+  struct FTP *ftp = data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  const char *slash_pos;  /* position of the first '/' char in curpos */
+  const char *path_to_use = data->state.path;
+  const char *cur_pos;
+  const char *filename = NULL;
+
+  cur_pos = path_to_use; /* current position in path. point at the begin
+                            of next path component */
+
+  ftpc->ctl_valid = FALSE;
+  ftpc->cwdfail = FALSE;
+
+  switch(data->set.ftp_filemethod) {
+  case FTPFILE_NOCWD:
+    /* fastest, but less standard-compliant */
+
+    /*
+      The best time to check whether the path is a file or directory is right
+      here. so:
+
+      the first condition in the if() right here, is there just in case
+      someone decides to set path to NULL one day
+   */
+    if(data->state.path &&
+       data->state.path[0] &&
+       (data->state.path[strlen(data->state.path) - 1] != '/') )
+      filename = data->state.path;  /* this is a full file path */
+      /*
+        ftpc->file is not used anywhere other than for operations on a file.
+        In other words, never for directory operations.
+        So we can safely leave filename as NULL here and use it as a
+        argument in dir/file decisions.
+      */
+    break;
+
+  case FTPFILE_SINGLECWD:
+    /* get the last slash */
+    if(!path_to_use[0]) {
+      /* no dir, no file */
+      ftpc->dirdepth = 0;
+      break;
+    }
+    slash_pos=strrchr(cur_pos, '/');
+    if(slash_pos || !*cur_pos) {
+      size_t dirlen = slash_pos-cur_pos;
+
+      ftpc->dirs = calloc(1, sizeof(ftpc->dirs[0]));
+      if(!ftpc->dirs)
+        return CURLE_OUT_OF_MEMORY;
+
+      if(!dirlen)
+        dirlen++;
+
+      ftpc->dirs[0] = curl_easy_unescape(conn->data, slash_pos ? cur_pos : "/",
+                                         slash_pos ? curlx_uztosi(dirlen) : 1,
+                                         NULL);
+      if(!ftpc->dirs[0]) {
+        freedirs(ftpc);
+        return CURLE_OUT_OF_MEMORY;
+      }
+      ftpc->dirdepth = 1; /* we consider it to be a single dir */
+      filename = slash_pos ? slash_pos+1 : cur_pos; /* rest is file name */
+    }
+    else
+      filename = cur_pos;  /* this is a file name only */
+    break;
+
+  default: /* allow pretty much anything */
+  case FTPFILE_MULTICWD:
+    ftpc->dirdepth = 0;
+    ftpc->diralloc = 5; /* default dir depth to allocate */
+    ftpc->dirs = calloc(ftpc->diralloc, sizeof(ftpc->dirs[0]));
+    if(!ftpc->dirs)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* we have a special case for listing the root dir only */
+    if(strequal(path_to_use, "/")) {
+      cur_pos++; /* make it point to the zero byte */
+      ftpc->dirs[0] = strdup("/");
+      ftpc->dirdepth++;
+    }
+    else {
+      /* parse the URL path into separate path components */
+      while((slash_pos = strchr(cur_pos, '/')) != NULL) {
+        /* 1 or 0 pointer offset to indicate absolute directory */
+        ssize_t absolute_dir = ((cur_pos - data->state.path > 0) &&
+                                (ftpc->dirdepth == 0))?1:0;
+
+        /* seek out the next path component */
+        if(slash_pos-cur_pos) {
+          /* we skip empty path components, like "x//y" since the FTP command
+             CWD requires a parameter and a non-existent parameter a) doesn't
+             work on many servers and b) has no effect on the others. */
+          int len = curlx_sztosi(slash_pos - cur_pos + absolute_dir);
+          ftpc->dirs[ftpc->dirdepth] =
+            curl_easy_unescape(conn->data, cur_pos - absolute_dir, len, NULL);
+          if(!ftpc->dirs[ftpc->dirdepth]) { /* run out of memory ... */
+            failf(data, "no memory");
+            freedirs(ftpc);
+            return CURLE_OUT_OF_MEMORY;
+          }
+          if(isBadFtpString(ftpc->dirs[ftpc->dirdepth])) {
+            free(ftpc->dirs[ftpc->dirdepth]);
+            freedirs(ftpc);
+            return CURLE_URL_MALFORMAT;
+          }
+        }
+        else {
+          cur_pos = slash_pos + 1; /* jump to the rest of the string */
+          if(!ftpc->dirdepth) {
+            /* path starts with a slash, add that as a directory */
+            ftpc->dirs[ftpc->dirdepth] = strdup("/");
+            if(!ftpc->dirs[ftpc->dirdepth++]) { /* run out of memory ... */
+              failf(data, "no memory");
+              freedirs(ftpc);
+              return CURLE_OUT_OF_MEMORY;
+            }
+          }
+          continue;
+        }
+
+        cur_pos = slash_pos + 1; /* jump to the rest of the string */
+        if(++ftpc->dirdepth >= ftpc->diralloc) {
+          /* enlarge array */
+          char **bigger;
+          ftpc->diralloc *= 2; /* double the size each time */
+          bigger = realloc(ftpc->dirs, ftpc->diralloc * sizeof(ftpc->dirs[0]));
+          if(!bigger) {
+            freedirs(ftpc);
+            return CURLE_OUT_OF_MEMORY;
+          }
+          ftpc->dirs = bigger;
+        }
+      }
+    }
+    filename = cur_pos;  /* the rest is the file name */
+    break;
+  } /* switch */
+
+  if(filename && *filename) {
+    ftpc->file = curl_easy_unescape(conn->data, filename, 0, NULL);
+    if(NULL == ftpc->file) {
+      freedirs(ftpc);
+      failf(data, "no memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+    if(isBadFtpString(ftpc->file)) {
+      freedirs(ftpc);
+      return CURLE_URL_MALFORMAT;
+    }
+  }
+  else
+    ftpc->file=NULL; /* instead of point to a zero byte, we make it a NULL
+                       pointer */
+
+  if(data->set.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) {
+    /* We need a file name when uploading. Return error! */
+    failf(data, "Uploading to a URL without a file name!");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  ftpc->cwddone = FALSE; /* default to not done */
+
+  if(ftpc->prevpath) {
+    /* prevpath is "raw" so we convert the input path before we compare the
+       strings */
+    int dlen;
+    char *path = curl_easy_unescape(conn->data, data->state.path, 0, &dlen);
+    if(!path) {
+      freedirs(ftpc);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    dlen -= ftpc->file?curlx_uztosi(strlen(ftpc->file)):0;
+    if((dlen == curlx_uztosi(strlen(ftpc->prevpath))) &&
+       strnequal(path, ftpc->prevpath, dlen)) {
+      infof(data, "Request has same path as previous transfer\n");
+      ftpc->cwddone = TRUE;
+    }
+    free(path);
+  }
+
+  return CURLE_OK;
+}
+
+/* call this when the DO phase has completed */
+static CURLcode ftp_dophase_done(struct connectdata *conn,
+                                 bool connected)
+{
+  struct FTP *ftp = conn->data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  if(connected) {
+    int completed;
+    CURLcode result = ftp_do_more(conn, &completed);
+
+    if(result) {
+      if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
+        /* close the second socket if it was created already */
+        Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
+        conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
+      }
+      return result;
+    }
+  }
+
+  if(ftp->transfer != FTPTRANSFER_BODY)
+    /* no data to transfer */
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+  else if(!connected)
+    /* since we didn't connect now, we want do_more to get called */
+    conn->bits.do_more = TRUE;
+
+  ftpc->ctl_valid = TRUE; /* seems good */
+
+  return CURLE_OK;
+}
+
+/* called from multi.c while DOing */
+static CURLcode ftp_doing(struct connectdata *conn,
+                          bool *dophase_done)
+{
+  CURLcode result = ftp_multi_statemach(conn, dophase_done);
+
+  if(result)
+    DEBUGF(infof(conn->data, "DO phase failed\n"));
+  else if(*dophase_done) {
+    result = ftp_dophase_done(conn, FALSE /* not connected */);
+
+    DEBUGF(infof(conn->data, "DO phase is complete2\n"));
+  }
+  return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_regular_transfer()
+ *
+ * The input argument is already checked for validity.
+ *
+ * Performs all commands done before a regular transfer between a local and a
+ * remote host.
+ *
+ * ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the
+ * ftp_done() function without finding any major problem.
+ */
+static
+CURLcode ftp_regular_transfer(struct connectdata *conn,
+                              bool *dophase_done)
+{
+  CURLcode result=CURLE_OK;
+  bool connected=FALSE;
+  struct SessionHandle *data = conn->data;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  data->req.size = -1; /* make sure this is unknown at this point */
+
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  ftpc->ctl_valid = TRUE; /* starts good */
+
+  result = ftp_perform(conn,
+                       &connected, /* have we connected after PASV/PORT */
+                       dophase_done); /* all commands in the DO-phase done? */
+
+  if(!result) {
+
+    if(!*dophase_done)
+      /* the DO phase has not completed yet */
+      return CURLE_OK;
+
+    result = ftp_dophase_done(conn, connected);
+
+    if(result)
+      return result;
+  }
+  else
+    freedirs(ftpc);
+
+  return result;
+}
+
+static CURLcode ftp_setup_connection(struct connectdata *conn)
+{
+  struct SessionHandle *data = conn->data;
+  char *type;
+  char command;
+  struct FTP *ftp;
+
+  if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
+    /* Unless we have asked to tunnel ftp operations through the proxy, we
+       switch and use HTTP operations only */
+#ifndef CURL_DISABLE_HTTP
+    if(conn->handler == &Curl_handler_ftp)
+      conn->handler = &Curl_handler_ftp_proxy;
+    else {
+#ifdef USE_SSL
+      conn->handler = &Curl_handler_ftps_proxy;
+#else
+      failf(data, "FTPS not supported!");
+      return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+    }
+    /* set it up as a HTTP connection instead */
+    return conn->handler->setup_connection(conn);
+#else
+    failf(data, "FTP over http proxy requires HTTP support built-in!");
+    return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+  }
+
+  conn->data->req.protop = ftp = malloc(sizeof(struct FTP));
+  if(NULL == ftp)
+    return CURLE_OUT_OF_MEMORY;
+
+  data->state.path++;   /* don't include the initial slash */
+  data->state.slash_removed = TRUE; /* we've skipped the slash */
+
+  /* FTP URLs support an extension like ";type=<typecode>" that
+   * we'll try to get now! */
+  type = strstr(data->state.path, ";type=");
+
+  if(!type)
+    type = strstr(conn->host.rawalloc, ";type=");
+
+  if(type) {
+    *type = 0;                     /* it was in the middle of the hostname */
+    command = Curl_raw_toupper(type[6]);
+    conn->bits.type_set = TRUE;
+
+    switch (command) {
+    case 'A': /* ASCII mode */
+      data->set.prefer_ascii = TRUE;
+      break;
+
+    case 'D': /* directory mode */
+      data->set.ftp_list_only = TRUE;
+      break;
+
+    case 'I': /* binary mode */
+    default:
+      /* switch off ASCII */
+      data->set.prefer_ascii = FALSE;
+      break;
+    }
+  }
+
+  /* get some initial data into the ftp struct */
+  ftp->bytecountp = &conn->data->req.bytecount;
+  ftp->transfer = FTPTRANSFER_BODY;
+  ftp->downloadsize = 0;
+
+  /* No need to duplicate user+password, the connectdata struct won't change
+     during a session, but we re-init them here since on subsequent inits
+     since the conn struct may have changed or been replaced.
+  */
+  ftp->user = conn->user;
+  ftp->passwd = conn->passwd;
+  if(isBadFtpString(ftp->user))
+    return CURLE_URL_MALFORMAT;
+  if(isBadFtpString(ftp->passwd))
+    return CURLE_URL_MALFORMAT;
+
+  conn->proto.ftpc.known_filesize = -1; /* unknown size for now */
+
+  return CURLE_OK;
+}
+
+#endif /* CURL_DISABLE_FTP */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/ftp.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/ftp.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/ftp.h	(revision 164)
@@ -0,0 +1,159 @@
+#ifndef HEADER_CURL_FTP_H
+#define HEADER_CURL_FTP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "pingpong.h"
+
+#ifndef CURL_DISABLE_FTP
+extern const struct Curl_handler Curl_handler_ftp;
+
+#ifdef USE_SSL
+extern const struct Curl_handler Curl_handler_ftps;
+#endif
+
+CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
+CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
+                             int *ftpcode);
+#endif /* CURL_DISABLE_FTP */
+
+/****************************************************************************
+ * FTP unique setup
+ ***************************************************************************/
+typedef enum {
+  FTP_STOP,    /* do nothing state, stops the state machine */
+  FTP_WAIT220, /* waiting for the initial 220 response immediately after
+                  a connect */
+  FTP_AUTH,
+  FTP_USER,
+  FTP_PASS,
+  FTP_ACCT,
+  FTP_PBSZ,
+  FTP_PROT,
+  FTP_CCC,
+  FTP_PWD,
+  FTP_SYST,
+  FTP_NAMEFMT,
+  FTP_QUOTE, /* waiting for a response to a command sent in a quote list */
+  FTP_RETR_PREQUOTE,
+  FTP_STOR_PREQUOTE,
+  FTP_POSTQUOTE,
+  FTP_CWD,  /* change dir */
+  FTP_MKD,  /* if the dir didn't exist */
+  FTP_MDTM, /* to figure out the datestamp */
+  FTP_TYPE, /* to set type when doing a head-like request */
+  FTP_LIST_TYPE, /* set type when about to do a dir list */
+  FTP_RETR_TYPE, /* set type when about to RETR a file */
+  FTP_STOR_TYPE, /* set type when about to STOR a file */
+  FTP_SIZE, /* get the remote file's size for head-like request */
+  FTP_RETR_SIZE, /* get the remote file's size for RETR */
+  FTP_STOR_SIZE, /* get the size for STOR */
+  FTP_REST, /* when used to check if the server supports it in head-like */
+  FTP_RETR_REST, /* when asking for "resume" in for RETR */
+  FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */
+  FTP_PRET, /* generic state for PRET RETR, PRET STOR and PRET LIST/NLST */
+  FTP_PASV, /* generic state for PASV and EPSV, check count1 */
+  FTP_LIST, /* generic state for LIST, NLST or a custom list command */
+  FTP_RETR,
+  FTP_STOR, /* generic state for STOR and APPE */
+  FTP_QUIT,
+  FTP_LAST  /* never used */
+} ftpstate;
+
+struct ftp_parselist_data; /* defined later in ftplistparser.c */
+
+struct ftp_wc_tmpdata {
+  struct ftp_parselist_data *parser;
+
+  struct {
+    curl_write_callback write_function;
+    FILE *file_descriptor;
+  } backup;
+};
+
+typedef enum {
+  FTPFILE_MULTICWD  = 1, /* as defined by RFC1738 */
+  FTPFILE_NOCWD     = 2, /* use SIZE / RETR / STOR on the full path */
+  FTPFILE_SINGLECWD = 3  /* make one CWD, then SIZE / RETR / STOR on the
+                            file */
+} curl_ftpfile;
+
+/* This FTP struct is used in the SessionHandle. All FTP data that is
+   connection-oriented must be in FTP_conn to properly deal with the fact that
+   perhaps the SessionHandle is changed between the times the connection is
+   used. */
+struct FTP {
+  curl_off_t *bytecountp;
+  char *user;    /* user name string */
+  char *passwd;  /* password string */
+
+  /* transfer a file/body or not, done as a typedefed enum just to make
+     debuggers display the full symbol and not just the numerical value */
+  curl_pp_transfer transfer;
+  curl_off_t downloadsize;
+};
+
+
+/* ftp_conn is used for struct connection-oriented data in the connectdata
+   struct */
+struct ftp_conn {
+  struct pingpong pp;
+  char *entrypath; /* the PWD reply when we logged on */
+  char **dirs;   /* realloc()ed array for path components */
+  int dirdepth;  /* number of entries used in the 'dirs' array */
+  int diralloc;  /* number of entries allocated for the 'dirs' array */
+  char *file;    /* decoded file */
+  bool dont_check;  /* Set to TRUE to prevent the final (post-transfer)
+                       file size and 226/250 status check. It should still
+                       read the line, just ignore the result. */
+  bool ctl_valid;   /* Tells Curl_ftp_quit() whether or not to do anything. If
+                       the connection has timed out or been closed, this
+                       should be FALSE when it gets to Curl_ftp_quit() */
+  bool cwddone;     /* if it has been determined that the proper CWD combo
+                       already has been done */
+  bool cwdfail;     /* set TRUE if a CWD command fails, as then we must prevent
+                       caching the current directory */
+  bool wait_data_conn; /* this is set TRUE if data connection is waited */
+  char *prevpath;   /* conn->path from the previous transfer */
+  char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a
+                        and others (A/I or zero) */
+  int count1; /* general purpose counter for the state machine */
+  int count2; /* general purpose counter for the state machine */
+  int count3; /* general purpose counter for the state machine */
+  ftpstate state; /* always use ftp.c:state() to change state! */
+  ftpstate state_saved; /* transfer type saved to be reloaded after
+                           data connection is established */
+  curl_off_t retr_size_saved; /* Size of retrieved file saved */
+  char * server_os;     /* The target server operating system. */
+  curl_off_t known_filesize; /* file size is different from -1, if wildcard
+                                LIST parsing was done and wc_statemach set
+                                it */
+  /* newhost is the (allocated) IP addr or host name to connect the data
+     connection to */
+  char *newhost;          /* this is the pair to connect the DATA... */
+  unsigned short newport; /* connection to */
+
+};
+
+#define DEFAULT_ACCEPT_TIMEOUT   60000 /* milliseconds == one minute */
+
+#endif /* HEADER_CURL_FTP_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/ftplistparser.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/ftplistparser.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/ftplistparser.c	(revision 164)
@@ -0,0 +1,1028 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/**
+ * Now implemented:
+ *
+ * 1) Unix version 1
+ * drwxr-xr-x 1 user01 ftp  512 Jan 29 23:32 prog
+ * 2) Unix version 2
+ * drwxr-xr-x 1 user01 ftp  512 Jan 29 1997  prog
+ * 3) Unix version 3
+ * drwxr-xr-x 1      1   1  512 Jan 29 23:32 prog
+ * 4) Unix symlink
+ * lrwxr-xr-x 1 user01 ftp  512 Jan 29 23:32 prog -> prog2000
+ * 5) DOS style
+ * 01-29-97 11:32PM <DIR> prog
+ */
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FTP
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "fileinfo.h"
+#include "llist.h"
+#include "strtoofft.h"
+#include "rawstr.h"
+#include "ftp.h"
+#include "ftplistparser.h"
+#include "curl_fnmatch.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* allocs buffer which will contain one line of LIST command response */
+#define FTP_BUFFER_ALLOCSIZE 160
+
+typedef enum {
+  PL_UNIX_TOTALSIZE = 0,
+  PL_UNIX_FILETYPE,
+  PL_UNIX_PERMISSION,
+  PL_UNIX_HLINKS,
+  PL_UNIX_USER,
+  PL_UNIX_GROUP,
+  PL_UNIX_SIZE,
+  PL_UNIX_TIME,
+  PL_UNIX_FILENAME,
+  PL_UNIX_SYMLINK
+} pl_unix_mainstate;
+
+typedef union {
+  enum {
+    PL_UNIX_TOTALSIZE_INIT = 0,
+    PL_UNIX_TOTALSIZE_READING
+  } total_dirsize;
+
+  enum {
+    PL_UNIX_HLINKS_PRESPACE = 0,
+    PL_UNIX_HLINKS_NUMBER
+  } hlinks;
+
+  enum {
+    PL_UNIX_USER_PRESPACE = 0,
+    PL_UNIX_USER_PARSING
+  } user;
+
+  enum {
+    PL_UNIX_GROUP_PRESPACE = 0,
+    PL_UNIX_GROUP_NAME
+  } group;
+
+  enum {
+    PL_UNIX_SIZE_PRESPACE = 0,
+    PL_UNIX_SIZE_NUMBER
+  } size;
+
+  enum {
+    PL_UNIX_TIME_PREPART1 = 0,
+    PL_UNIX_TIME_PART1,
+    PL_UNIX_TIME_PREPART2,
+    PL_UNIX_TIME_PART2,
+    PL_UNIX_TIME_PREPART3,
+    PL_UNIX_TIME_PART3
+  } time;
+
+  enum {
+    PL_UNIX_FILENAME_PRESPACE = 0,
+    PL_UNIX_FILENAME_NAME,
+    PL_UNIX_FILENAME_WINDOWSEOL
+  } filename;
+
+  enum {
+    PL_UNIX_SYMLINK_PRESPACE = 0,
+    PL_UNIX_SYMLINK_NAME,
+    PL_UNIX_SYMLINK_PRETARGET1,
+    PL_UNIX_SYMLINK_PRETARGET2,
+    PL_UNIX_SYMLINK_PRETARGET3,
+    PL_UNIX_SYMLINK_PRETARGET4,
+    PL_UNIX_SYMLINK_TARGET,
+    PL_UNIX_SYMLINK_WINDOWSEOL
+  } symlink;
+} pl_unix_substate;
+
+typedef enum {
+  PL_WINNT_DATE = 0,
+  PL_WINNT_TIME,
+  PL_WINNT_DIRORSIZE,
+  PL_WINNT_FILENAME
+} pl_winNT_mainstate;
+
+typedef union {
+  enum {
+    PL_WINNT_TIME_PRESPACE = 0,
+    PL_WINNT_TIME_TIME
+  } time;
+  enum {
+    PL_WINNT_DIRORSIZE_PRESPACE = 0,
+    PL_WINNT_DIRORSIZE_CONTENT
+  } dirorsize;
+  enum {
+    PL_WINNT_FILENAME_PRESPACE = 0,
+    PL_WINNT_FILENAME_CONTENT,
+    PL_WINNT_FILENAME_WINEOL
+  } filename;
+} pl_winNT_substate;
+
+/* This struct is used in wildcard downloading - for parsing LIST response */
+struct ftp_parselist_data {
+  enum {
+    OS_TYPE_UNKNOWN = 0,
+    OS_TYPE_UNIX,
+    OS_TYPE_WIN_NT
+  } os_type;
+
+  union {
+    struct {
+      pl_unix_mainstate main;
+      pl_unix_substate sub;
+    } UNIX;
+
+    struct {
+      pl_winNT_mainstate main;
+      pl_winNT_substate sub;
+    } NT;
+  } state;
+
+  CURLcode error;
+  struct curl_fileinfo *file_data;
+  unsigned int item_length;
+  size_t item_offset;
+  struct {
+    size_t filename;
+    size_t user;
+    size_t group;
+    size_t time;
+    size_t perm;
+    size_t symlink_target;
+  } offsets;
+};
+
+struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void)
+{
+  return calloc(1, sizeof(struct ftp_parselist_data));
+}
+
+
+void Curl_ftp_parselist_data_free(struct ftp_parselist_data **pl_data)
+{
+  free(*pl_data);
+  *pl_data = NULL;
+}
+
+
+CURLcode Curl_ftp_parselist_geterror(struct ftp_parselist_data *pl_data)
+{
+  return pl_data->error;
+}
+
+
+#define FTP_LP_MALFORMATED_PERM 0x01000000
+
+static int ftp_pl_get_permission(const char *str)
+{
+  int permissions = 0;
+  /* USER */
+  if(str[0] == 'r')
+    permissions |= 1 << 8;
+  else if(str[0] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+  if(str[1] == 'w')
+    permissions |= 1 << 7;
+  else if(str[1] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+
+  if(str[2] == 'x')
+    permissions |= 1 << 6;
+  else if(str[2] == 's') {
+    permissions |= 1 << 6;
+    permissions |= 1 << 11;
+  }
+  else if(str[2] == 'S')
+    permissions |= 1 << 11;
+  else if(str[2] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+  /* GROUP */
+  if(str[3] == 'r')
+    permissions |= 1 << 5;
+  else if(str[3] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+  if(str[4] == 'w')
+    permissions |= 1 << 4;
+  else if(str[4] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+  if(str[5] == 'x')
+    permissions |= 1 << 3;
+  else if(str[5] == 's') {
+    permissions |= 1 << 3;
+    permissions |= 1 << 10;
+  }
+  else if(str[5] == 'S')
+    permissions |= 1 << 10;
+  else if(str[5] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+  /* others */
+  if(str[6] == 'r')
+    permissions |= 1 << 2;
+  else if(str[6] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+  if(str[7] == 'w')
+    permissions |= 1 << 1;
+  else if(str[7] != '-')
+      permissions |= FTP_LP_MALFORMATED_PERM;
+  if(str[8] == 'x')
+    permissions |= 1;
+  else if(str[8] == 't') {
+    permissions |= 1;
+    permissions |= 1 << 9;
+  }
+  else if(str[8] == 'T')
+    permissions |= 1 << 9;
+  else if(str[8] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+
+  return permissions;
+}
+
+static void PL_ERROR(struct connectdata *conn, CURLcode err)
+{
+  struct ftp_wc_tmpdata *tmpdata = conn->data->wildcard.tmp;
+  struct ftp_parselist_data *parser = tmpdata->parser;
+  if(parser->file_data)
+    Curl_fileinfo_dtor(NULL, parser->file_data);
+  parser->file_data = NULL;
+  parser->error = err;
+}
+
+static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
+                                    struct curl_fileinfo *finfo)
+{
+  curl_fnmatch_callback compare;
+  struct WildcardData *wc = &conn->data->wildcard;
+  struct ftp_wc_tmpdata *tmpdata = wc->tmp;
+  struct curl_llist *llist = wc->filelist;
+  struct ftp_parselist_data *parser = tmpdata->parser;
+  bool add = TRUE;
+
+  /* move finfo pointers to b_data */
+  char *str = finfo->b_data;
+  finfo->filename       = str + parser->offsets.filename;
+  finfo->strings.group  = parser->offsets.group ?
+                          str + parser->offsets.group : NULL;
+  finfo->strings.perm   = parser->offsets.perm ?
+                          str + parser->offsets.perm : NULL;
+  finfo->strings.target = parser->offsets.symlink_target ?
+                          str + parser->offsets.symlink_target : NULL;
+  finfo->strings.time   = str + parser->offsets.time;
+  finfo->strings.user   = parser->offsets.user ?
+                          str + parser->offsets.user : NULL;
+
+  /* get correct fnmatch callback */
+  compare = conn->data->set.fnmatch;
+  if(!compare)
+    compare = Curl_fnmatch;
+
+  /* filter pattern-corresponding filenames */
+  if(compare(conn->data->set.fnmatch_data, wc->pattern,
+             finfo->filename) == 0) {
+    /* discard symlink which is containing multiple " -> " */
+    if((finfo->filetype == CURLFILETYPE_SYMLINK) && finfo->strings.target &&
+       (strstr(finfo->strings.target, " -> "))) {
+      add = FALSE;
+    }
+  }
+  else {
+    add = FALSE;
+  }
+
+  if(add) {
+    if(!Curl_llist_insert_next(llist, llist->tail, finfo)) {
+      Curl_fileinfo_dtor(NULL, finfo);
+      tmpdata->parser->file_data = NULL;
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+  else {
+    Curl_fileinfo_dtor(NULL, finfo);
+  }
+
+  tmpdata->parser->file_data = NULL;
+  return CURLE_OK;
+}
+
+size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
+                          void *connptr)
+{
+  size_t bufflen = size*nmemb;
+  struct connectdata *conn = (struct connectdata *)connptr;
+  struct ftp_wc_tmpdata *tmpdata = conn->data->wildcard.tmp;
+  struct ftp_parselist_data *parser = tmpdata->parser;
+  struct curl_fileinfo *finfo;
+  unsigned long i = 0;
+  CURLcode result;
+
+  if(parser->error) { /* error in previous call */
+    /* scenario:
+     * 1. call => OK..
+     * 2. call => OUT_OF_MEMORY (or other error)
+     * 3. (last) call => is skipped RIGHT HERE and the error is hadled later
+     *    in wc_statemach()
+     */
+    return bufflen;
+  }
+
+  if(parser->os_type == OS_TYPE_UNKNOWN && bufflen > 0) {
+    /* considering info about FILE response format */
+    parser->os_type = (buffer[0] >= '0' && buffer[0] <= '9') ?
+                       OS_TYPE_WIN_NT : OS_TYPE_UNIX;
+  }
+
+  while(i < bufflen) { /* FSM */
+
+    char c = buffer[i];
+    if(!parser->file_data) { /* tmp file data is not allocated yet */
+      parser->file_data = Curl_fileinfo_alloc();
+      if(!parser->file_data) {
+        parser->error = CURLE_OUT_OF_MEMORY;
+        return bufflen;
+      }
+      parser->file_data->b_data = malloc(FTP_BUFFER_ALLOCSIZE);
+      if(!parser->file_data->b_data) {
+        PL_ERROR(conn, CURLE_OUT_OF_MEMORY);
+        return bufflen;
+      }
+      parser->file_data->b_size = FTP_BUFFER_ALLOCSIZE;
+      parser->item_offset = 0;
+      parser->item_length = 0;
+    }
+
+    finfo = parser->file_data;
+    finfo->b_data[finfo->b_used++] = c;
+
+    if(finfo->b_used >= finfo->b_size - 1) {
+      /* if it is important, extend buffer space for file data */
+      char *tmp = realloc(finfo->b_data,
+                          finfo->b_size + FTP_BUFFER_ALLOCSIZE);
+      if(tmp) {
+        finfo->b_size += FTP_BUFFER_ALLOCSIZE;
+        finfo->b_data = tmp;
+      }
+      else {
+        Curl_fileinfo_dtor(NULL, parser->file_data);
+        parser->file_data = NULL;
+        parser->error = CURLE_OUT_OF_MEMORY;
+        PL_ERROR(conn, CURLE_OUT_OF_MEMORY);
+        return bufflen;
+      }
+    }
+
+    switch (parser->os_type) {
+    case OS_TYPE_UNIX:
+      switch (parser->state.UNIX.main) {
+      case PL_UNIX_TOTALSIZE:
+        switch(parser->state.UNIX.sub.total_dirsize) {
+        case PL_UNIX_TOTALSIZE_INIT:
+          if(c == 't') {
+            parser->state.UNIX.sub.total_dirsize = PL_UNIX_TOTALSIZE_READING;
+            parser->item_length++;
+          }
+          else {
+            parser->state.UNIX.main = PL_UNIX_FILETYPE;
+            /* start FSM again not considering size of directory */
+            finfo->b_used = 0;
+            i--;
+          }
+          break;
+        case PL_UNIX_TOTALSIZE_READING:
+          parser->item_length++;
+          if(c == '\r') {
+            parser->item_length--;
+            finfo->b_used--;
+          }
+          else if(c == '\n') {
+            finfo->b_data[parser->item_length - 1] = 0;
+            if(strncmp("total ", finfo->b_data, 6) == 0) {
+              char *endptr = finfo->b_data+6;
+              /* here we can deal with directory size, pass the leading white
+                 spaces and then the digits */
+              while(ISSPACE(*endptr))
+                endptr++;
+              while(ISDIGIT(*endptr))
+                endptr++;
+              if(*endptr != 0) {
+                PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+                return bufflen;
+              }
+              else {
+                parser->state.UNIX.main = PL_UNIX_FILETYPE;
+                finfo->b_used = 0;
+              }
+            }
+            else {
+              PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+              return bufflen;
+            }
+          }
+          break;
+        }
+        break;
+      case PL_UNIX_FILETYPE:
+        switch (c) {
+        case '-':
+          finfo->filetype = CURLFILETYPE_FILE;
+          break;
+        case 'd':
+          finfo->filetype = CURLFILETYPE_DIRECTORY;
+          break;
+        case 'l':
+          finfo->filetype = CURLFILETYPE_SYMLINK;
+          break;
+        case 'p':
+          finfo->filetype = CURLFILETYPE_NAMEDPIPE;
+          break;
+        case 's':
+          finfo->filetype = CURLFILETYPE_SOCKET;
+          break;
+        case 'c':
+          finfo->filetype = CURLFILETYPE_DEVICE_CHAR;
+          break;
+        case 'b':
+          finfo->filetype = CURLFILETYPE_DEVICE_BLOCK;
+          break;
+        case 'D':
+          finfo->filetype = CURLFILETYPE_DOOR;
+          break;
+        default:
+          PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+          return bufflen;
+        }
+        parser->state.UNIX.main = PL_UNIX_PERMISSION;
+        parser->item_length = 0;
+        parser->item_offset = 1;
+        break;
+      case PL_UNIX_PERMISSION:
+        parser->item_length++;
+        if(parser->item_length <= 9) {
+          if(!strchr("rwx-tTsS", c)) {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+        }
+        else if(parser->item_length == 10) {
+          unsigned int perm;
+          if(c != ' ') {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          finfo->b_data[10] = 0; /* terminate permissions */
+          perm = ftp_pl_get_permission(finfo->b_data + parser->item_offset);
+          if(perm & FTP_LP_MALFORMATED_PERM) {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          parser->file_data->flags |= CURLFINFOFLAG_KNOWN_PERM;
+          parser->file_data->perm = perm;
+          parser->offsets.perm = parser->item_offset;
+
+          parser->item_length = 0;
+          parser->state.UNIX.main = PL_UNIX_HLINKS;
+          parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_PRESPACE;
+        }
+        break;
+      case PL_UNIX_HLINKS:
+        switch(parser->state.UNIX.sub.hlinks) {
+        case PL_UNIX_HLINKS_PRESPACE:
+          if(c != ' ') {
+            if(c >= '0' && c <= '9') {
+              parser->item_offset = finfo->b_used - 1;
+              parser->item_length = 1;
+              parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_NUMBER;
+            }
+            else {
+              PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+              return bufflen;
+            }
+          }
+          break;
+        case PL_UNIX_HLINKS_NUMBER:
+          parser->item_length ++;
+          if(c == ' ') {
+            char *p;
+            long int hlinks;
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            hlinks = strtol(finfo->b_data + parser->item_offset, &p, 10);
+            if(p[0] == '\0' && hlinks != LONG_MAX && hlinks != LONG_MIN) {
+              parser->file_data->flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT;
+              parser->file_data->hardlinks = hlinks;
+            }
+            parser->item_length = 0;
+            parser->item_offset = 0;
+            parser->state.UNIX.main = PL_UNIX_USER;
+            parser->state.UNIX.sub.user = PL_UNIX_USER_PRESPACE;
+          }
+          else if(c < '0' || c > '9') {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          break;
+        }
+        break;
+      case PL_UNIX_USER:
+        switch(parser->state.UNIX.sub.user) {
+        case PL_UNIX_USER_PRESPACE:
+          if(c != ' ') {
+            parser->item_offset = finfo->b_used - 1;
+            parser->item_length = 1;
+            parser->state.UNIX.sub.user = PL_UNIX_USER_PARSING;
+          }
+          break;
+        case PL_UNIX_USER_PARSING:
+          parser->item_length++;
+          if(c == ' ') {
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            parser->offsets.user = parser->item_offset;
+            parser->state.UNIX.main = PL_UNIX_GROUP;
+            parser->state.UNIX.sub.group = PL_UNIX_GROUP_PRESPACE;
+            parser->item_offset = 0;
+            parser->item_length = 0;
+          }
+          break;
+        }
+        break;
+      case PL_UNIX_GROUP:
+        switch(parser->state.UNIX.sub.group) {
+        case PL_UNIX_GROUP_PRESPACE:
+          if(c != ' ') {
+            parser->item_offset = finfo->b_used - 1;
+            parser->item_length = 1;
+            parser->state.UNIX.sub.group = PL_UNIX_GROUP_NAME;
+          }
+          break;
+        case PL_UNIX_GROUP_NAME:
+          parser->item_length++;
+          if(c == ' ') {
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            parser->offsets.group = parser->item_offset;
+            parser->state.UNIX.main = PL_UNIX_SIZE;
+            parser->state.UNIX.sub.size = PL_UNIX_SIZE_PRESPACE;
+            parser->item_offset = 0;
+            parser->item_length = 0;
+          }
+          break;
+        }
+        break;
+      case PL_UNIX_SIZE:
+        switch(parser->state.UNIX.sub.size) {
+        case PL_UNIX_SIZE_PRESPACE:
+          if(c != ' ') {
+            if(c >= '0' && c <= '9') {
+              parser->item_offset = finfo->b_used - 1;
+              parser->item_length = 1;
+              parser->state.UNIX.sub.size = PL_UNIX_SIZE_NUMBER;
+            }
+            else {
+              PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+              return bufflen;
+            }
+          }
+          break;
+        case PL_UNIX_SIZE_NUMBER:
+          parser->item_length++;
+          if(c == ' ') {
+            char *p;
+            curl_off_t fsize;
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            fsize = curlx_strtoofft(finfo->b_data+parser->item_offset, &p, 10);
+            if(p[0] == '\0' && fsize != CURL_OFF_T_MAX &&
+                               fsize != CURL_OFF_T_MIN) {
+              parser->file_data->flags |= CURLFINFOFLAG_KNOWN_SIZE;
+              parser->file_data->size = fsize;
+            }
+            parser->item_length = 0;
+            parser->item_offset = 0;
+            parser->state.UNIX.main = PL_UNIX_TIME;
+            parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART1;
+          }
+          else if(!ISDIGIT(c)) {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          break;
+        }
+        break;
+      case PL_UNIX_TIME:
+        switch(parser->state.UNIX.sub.time) {
+        case PL_UNIX_TIME_PREPART1:
+          if(c != ' ') {
+            if(ISALNUM(c)) {
+              parser->item_offset = finfo->b_used -1;
+              parser->item_length = 1;
+              parser->state.UNIX.sub.time = PL_UNIX_TIME_PART1;
+            }
+            else {
+              PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+              return bufflen;
+            }
+          }
+          break;
+        case PL_UNIX_TIME_PART1:
+          parser->item_length++;
+          if(c == ' ') {
+            parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART2;
+          }
+          else if(!ISALNUM(c) && c != '.') {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          break;
+        case PL_UNIX_TIME_PREPART2:
+          parser->item_length++;
+          if(c != ' ') {
+            if(ISALNUM(c)) {
+              parser->state.UNIX.sub.time = PL_UNIX_TIME_PART2;
+            }
+            else {
+              PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+              return bufflen;
+            }
+          }
+          break;
+        case PL_UNIX_TIME_PART2:
+          parser->item_length++;
+          if(c == ' ') {
+            parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART3;
+          }
+          else if(!ISALNUM(c) && c != '.') {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          break;
+        case PL_UNIX_TIME_PREPART3:
+          parser->item_length++;
+          if(c != ' ') {
+            if(ISALNUM(c)) {
+              parser->state.UNIX.sub.time = PL_UNIX_TIME_PART3;
+            }
+            else {
+              PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+              return bufflen;
+            }
+          }
+          break;
+        case PL_UNIX_TIME_PART3:
+          parser->item_length++;
+          if(c == ' ') {
+            finfo->b_data[parser->item_offset + parser->item_length -1] = 0;
+            parser->offsets.time = parser->item_offset;
+            /*
+              if(ftp_pl_gettime(parser, finfo->b_data + parser->item_offset)) {
+                parser->file_data->flags |= CURLFINFOFLAG_KNOWN_TIME;
+              }
+            */
+            if(finfo->filetype == CURLFILETYPE_SYMLINK) {
+              parser->state.UNIX.main = PL_UNIX_SYMLINK;
+              parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRESPACE;
+            }
+            else {
+              parser->state.UNIX.main = PL_UNIX_FILENAME;
+              parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_PRESPACE;
+            }
+          }
+          else if(!ISALNUM(c) && c != '.' && c != ':') {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          break;
+        }
+        break;
+      case PL_UNIX_FILENAME:
+        switch(parser->state.UNIX.sub.filename) {
+        case PL_UNIX_FILENAME_PRESPACE:
+          if(c != ' ') {
+            parser->item_offset = finfo->b_used - 1;
+            parser->item_length = 1;
+            parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_NAME;
+          }
+          break;
+        case PL_UNIX_FILENAME_NAME:
+          parser->item_length++;
+          if(c == '\r') {
+            parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_WINDOWSEOL;
+          }
+          else if(c == '\n') {
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            parser->offsets.filename = parser->item_offset;
+            parser->state.UNIX.main = PL_UNIX_FILETYPE;
+            result = ftp_pl_insert_finfo(conn, finfo);
+            if(result) {
+              PL_ERROR(conn, result);
+              return bufflen;
+            }
+          }
+          break;
+        case PL_UNIX_FILENAME_WINDOWSEOL:
+          if(c == '\n') {
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            parser->offsets.filename = parser->item_offset;
+            parser->state.UNIX.main = PL_UNIX_FILETYPE;
+            result = ftp_pl_insert_finfo(conn, finfo);
+            if(result) {
+              PL_ERROR(conn, result);
+              return bufflen;
+            }
+          }
+          else {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          break;
+        }
+        break;
+      case PL_UNIX_SYMLINK:
+        switch(parser->state.UNIX.sub.symlink) {
+        case PL_UNIX_SYMLINK_PRESPACE:
+          if(c != ' ') {
+            parser->item_offset = finfo->b_used - 1;
+            parser->item_length = 1;
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
+          }
+          break;
+        case PL_UNIX_SYMLINK_NAME:
+          parser->item_length++;
+          if(c == ' ') {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET1;
+          }
+          else if(c == '\r' || c == '\n') {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          break;
+        case PL_UNIX_SYMLINK_PRETARGET1:
+          parser->item_length++;
+          if(c == '-') {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET2;
+          }
+          else if(c == '\r' || c == '\n') {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          else {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
+          }
+          break;
+        case PL_UNIX_SYMLINK_PRETARGET2:
+          parser->item_length++;
+          if(c == '>') {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET3;
+          }
+          else if(c == '\r' || c == '\n') {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          else {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
+          }
+          break;
+        case PL_UNIX_SYMLINK_PRETARGET3:
+          parser->item_length++;
+          if(c == ' ') {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET4;
+            /* now place where is symlink following */
+            finfo->b_data[parser->item_offset + parser->item_length - 4] = 0;
+            parser->offsets.filename = parser->item_offset;
+            parser->item_length = 0;
+            parser->item_offset = 0;
+          }
+          else if(c == '\r' || c == '\n') {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          else {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
+          }
+          break;
+        case PL_UNIX_SYMLINK_PRETARGET4:
+          if(c != '\r' && c != '\n') {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_TARGET;
+            parser->item_offset = finfo->b_used - 1;
+            parser->item_length = 1;
+          }
+          else {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          break;
+        case PL_UNIX_SYMLINK_TARGET:
+          parser->item_length++;
+          if(c == '\r') {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_WINDOWSEOL;
+          }
+          else if(c == '\n') {
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            parser->offsets.symlink_target = parser->item_offset;
+            result = ftp_pl_insert_finfo(conn, finfo);
+            if(result) {
+              PL_ERROR(conn, result);
+              return bufflen;
+            }
+            parser->state.UNIX.main = PL_UNIX_FILETYPE;
+          }
+          break;
+        case PL_UNIX_SYMLINK_WINDOWSEOL:
+          if(c == '\n') {
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            parser->offsets.symlink_target = parser->item_offset;
+            result = ftp_pl_insert_finfo(conn, finfo);
+            if(result) {
+              PL_ERROR(conn, result);
+              return bufflen;
+            }
+            parser->state.UNIX.main = PL_UNIX_FILETYPE;
+          }
+          else {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case OS_TYPE_WIN_NT:
+      switch(parser->state.NT.main) {
+      case PL_WINNT_DATE:
+        parser->item_length++;
+        if(parser->item_length < 9) {
+          if(!strchr("0123456789-", c)) { /* only simple control */
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+        }
+        else if(parser->item_length == 9) {
+          if(c == ' ') {
+            parser->state.NT.main = PL_WINNT_TIME;
+            parser->state.NT.sub.time = PL_WINNT_TIME_PRESPACE;
+          }
+          else {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+        }
+        else {
+          PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+          return bufflen;
+        }
+        break;
+      case PL_WINNT_TIME:
+        parser->item_length++;
+        switch(parser->state.NT.sub.time) {
+        case PL_WINNT_TIME_PRESPACE:
+          if(!ISSPACE(c)) {
+            parser->state.NT.sub.time = PL_WINNT_TIME_TIME;
+          }
+          break;
+        case PL_WINNT_TIME_TIME:
+          if(c == ' ') {
+            parser->offsets.time = parser->item_offset;
+            finfo->b_data[parser->item_offset + parser->item_length -1] = 0;
+            parser->state.NT.main = PL_WINNT_DIRORSIZE;
+            parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_PRESPACE;
+            parser->item_length = 0;
+          }
+          else if(!strchr("APM0123456789:", c)) {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          break;
+        }
+        break;
+      case PL_WINNT_DIRORSIZE:
+        switch(parser->state.NT.sub.dirorsize) {
+        case PL_WINNT_DIRORSIZE_PRESPACE:
+          if(c == ' ') {
+
+          }
+          else {
+            parser->item_offset = finfo->b_used - 1;
+            parser->item_length = 1;
+            parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_CONTENT;
+          }
+          break;
+        case PL_WINNT_DIRORSIZE_CONTENT:
+          parser->item_length ++;
+          if(c == ' ') {
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            if(strcmp("<DIR>", finfo->b_data + parser->item_offset) == 0) {
+              finfo->filetype = CURLFILETYPE_DIRECTORY;
+              finfo->size = 0;
+            }
+            else {
+              char *endptr;
+              finfo->size = curlx_strtoofft(finfo->b_data +
+                                            parser->item_offset,
+                                            &endptr, 10);
+              if(!*endptr) {
+                if(finfo->size == CURL_OFF_T_MAX ||
+                   finfo->size == CURL_OFF_T_MIN) {
+                  if(errno == ERANGE) {
+                    PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+                    return bufflen;
+                  }
+                }
+              }
+              else {
+                PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+                return bufflen;
+              }
+              /* correct file type */
+              parser->file_data->filetype = CURLFILETYPE_FILE;
+            }
+
+            parser->file_data->flags |= CURLFINFOFLAG_KNOWN_SIZE;
+            parser->item_length = 0;
+            parser->state.NT.main = PL_WINNT_FILENAME;
+            parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE;
+          }
+          break;
+        }
+        break;
+      case PL_WINNT_FILENAME:
+        switch (parser->state.NT.sub.filename) {
+        case PL_WINNT_FILENAME_PRESPACE:
+          if(c != ' ') {
+            parser->item_offset = finfo->b_used -1;
+            parser->item_length = 1;
+            parser->state.NT.sub.filename = PL_WINNT_FILENAME_CONTENT;
+          }
+          break;
+        case PL_WINNT_FILENAME_CONTENT:
+          parser->item_length++;
+          if(c == '\r') {
+            parser->state.NT.sub.filename = PL_WINNT_FILENAME_WINEOL;
+            finfo->b_data[finfo->b_used - 1] = 0;
+          }
+          else if(c == '\n') {
+            parser->offsets.filename = parser->item_offset;
+            finfo->b_data[finfo->b_used - 1] = 0;
+            parser->offsets.filename = parser->item_offset;
+            result = ftp_pl_insert_finfo(conn, finfo);
+            if(result) {
+              PL_ERROR(conn, result);
+              return bufflen;
+            }
+            parser->state.NT.main = PL_WINNT_DATE;
+            parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE;
+          }
+          break;
+        case PL_WINNT_FILENAME_WINEOL:
+          if(c == '\n') {
+            parser->offsets.filename = parser->item_offset;
+            result = ftp_pl_insert_finfo(conn, finfo);
+            if(result) {
+              PL_ERROR(conn, result);
+              return bufflen;
+            }
+            parser->state.NT.main = PL_WINNT_DATE;
+            parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE;
+          }
+          else {
+            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+            return bufflen;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    default:
+      return bufflen + 1;
+    }
+
+    i++;
+  }
+
+  return bufflen;
+}
+
+#endif /* CURL_DISABLE_FTP */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/ftplistparser.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/ftplistparser.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/ftplistparser.h	(revision 164)
@@ -0,0 +1,41 @@
+#ifndef HEADER_CURL_FTPLISTPARSER_H
+#define HEADER_CURL_FTPLISTPARSER_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FTP
+
+/* WRITEFUNCTION callback for parsing LIST responses */
+size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
+                          void *connptr);
+
+struct ftp_parselist_data; /* defined inside ftplibparser.c */
+
+CURLcode Curl_ftp_parselist_geterror(struct ftp_parselist_data *pl_data);
+
+struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void);
+
+void Curl_ftp_parselist_data_free(struct ftp_parselist_data **pl_data);
+
+#endif /* CURL_DISABLE_FTP */
+#endif /* HEADER_CURL_FTPLISTPARSER_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/getenv.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/getenv.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/getenv.c	(revision 164)
@@ -0,0 +1,53 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "curl_memory.h"
+
+#include "memdebug.h"
+
+static
+char *GetEnv(const char *variable)
+{
+#ifdef _WIN32_WCE
+  return NULL;
+#else
+#if 0//def WIN32
+  char env[MAX_PATH]; /* MAX_PATH is from windef.h */
+  char *temp = getenv(variable);
+  env[0] = '\0';
+  if(temp != NULL)
+    ExpandEnvironmentStringsA(temp, env, sizeof(env));
+  return (env[0] != '\0')?strdup(env):NULL;
+#else
+  char *env = getenv(variable);
+  return (env && env[0])?strdup(env):NULL;
+#endif
+#endif
+}
+
+char *curl_getenv(const char *v)
+{
+  return GetEnv(v);
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/getinfo.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/getinfo.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/getinfo.c	(revision 164)
@@ -0,0 +1,399 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "getinfo.h"
+
+#include "vtls/vtls.h"
+#include "connect.h" /* Curl_getconnectinfo() */
+#include "progress.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * This is supposed to be called in the beginning of a perform() session
+ * and should reset all session-info variables
+ */
+CURLcode Curl_initinfo(struct SessionHandle *data)
+{
+  struct Progress *pro = &data->progress;
+  struct PureInfo *info = &data->info;
+
+  pro->t_nslookup = 0;
+  pro->t_connect = 0;
+  pro->t_appconnect = 0;
+  pro->t_pretransfer = 0;
+  pro->t_starttransfer = 0;
+  pro->timespent = 0;
+  pro->t_redirect = 0;
+
+  info->httpcode = 0;
+  info->httpproxycode = 0;
+  info->httpversion = 0;
+  info->filetime = -1; /* -1 is an illegal time and thus means unknown */
+  info->timecond = FALSE;
+
+  free(info->contenttype);
+  info->contenttype = NULL;
+
+  info->header_size = 0;
+  info->request_size = 0;
+  info->numconnects = 0;
+
+  info->conn_primary_ip[0] = '\0';
+  info->conn_local_ip[0] = '\0';
+  info->conn_primary_port = 0;
+  info->conn_local_port = 0;
+
+  return CURLE_OK;
+}
+
+static CURLcode getinfo_char(struct SessionHandle *data, CURLINFO info,
+                             char **param_charp)
+{
+  switch(info) {
+  case CURLINFO_EFFECTIVE_URL:
+    *param_charp = data->change.url?data->change.url:(char *)"";
+    break;
+  case CURLINFO_CONTENT_TYPE:
+    *param_charp = data->info.contenttype;
+    break;
+  case CURLINFO_PRIVATE:
+    *param_charp = (char *) data->set.private_data;
+    break;
+  case CURLINFO_FTP_ENTRY_PATH:
+    /* Return the entrypath string from the most recent connection.
+       This pointer was copied from the connectdata structure by FTP.
+       The actual string may be free()ed by subsequent libcurl calls so
+       it must be copied to a safer area before the next libcurl call.
+       Callers must never free it themselves. */
+    *param_charp = data->state.most_recent_ftp_entrypath;
+    break;
+  case CURLINFO_REDIRECT_URL:
+    /* Return the URL this request would have been redirected to if that
+       option had been enabled! */
+    *param_charp = data->info.wouldredirect;
+    break;
+  case CURLINFO_PRIMARY_IP:
+    /* Return the ip address of the most recent (primary) connection */
+    *param_charp = data->info.conn_primary_ip;
+    break;
+  case CURLINFO_LOCAL_IP:
+    /* Return the source/local ip address of the most recent (primary)
+       connection */
+    *param_charp = data->info.conn_local_ip;
+    break;
+  case CURLINFO_RTSP_SESSION_ID:
+    *param_charp = data->set.str[STRING_RTSP_SESSION_ID];
+    break;
+
+  default:
+    return CURLE_UNKNOWN_OPTION;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
+                             long *param_longp)
+{
+  curl_socket_t sockfd;
+
+  union {
+    unsigned long *to_ulong;
+    long          *to_long;
+  } lptr;
+
+  switch(info) {
+  case CURLINFO_RESPONSE_CODE:
+    *param_longp = data->info.httpcode;
+    break;
+  case CURLINFO_HTTP_CONNECTCODE:
+    *param_longp = data->info.httpproxycode;
+    break;
+  case CURLINFO_FILETIME:
+    *param_longp = data->info.filetime;
+    break;
+  case CURLINFO_HEADER_SIZE:
+    *param_longp = data->info.header_size;
+    break;
+  case CURLINFO_REQUEST_SIZE:
+    *param_longp = data->info.request_size;
+    break;
+  case CURLINFO_SSL_VERIFYRESULT:
+    *param_longp = data->set.ssl.certverifyresult;
+    break;
+  case CURLINFO_REDIRECT_COUNT:
+    *param_longp = data->set.followlocation;
+    break;
+  case CURLINFO_HTTPAUTH_AVAIL:
+    lptr.to_long = param_longp;
+    *lptr.to_ulong = data->info.httpauthavail;
+    break;
+  case CURLINFO_PROXYAUTH_AVAIL:
+    lptr.to_long = param_longp;
+    *lptr.to_ulong = data->info.proxyauthavail;
+    break;
+  case CURLINFO_OS_ERRNO:
+    *param_longp = data->state.os_errno;
+    break;
+  case CURLINFO_NUM_CONNECTS:
+    *param_longp = data->info.numconnects;
+    break;
+  case CURLINFO_LASTSOCKET:
+    sockfd = Curl_getconnectinfo(data, NULL);
+
+    /* note: this is not a good conversion for systems with 64 bit sockets and
+       32 bit longs */
+    if(sockfd != CURL_SOCKET_BAD)
+      *param_longp = (long)sockfd;
+    else
+      /* this interface is documented to return -1 in case of badness, which
+         may not be the same as the CURL_SOCKET_BAD value */
+      *param_longp = -1;
+    break;
+  case CURLINFO_PRIMARY_PORT:
+    /* Return the (remote) port of the most recent (primary) connection */
+    *param_longp = data->info.conn_primary_port;
+    break;
+  case CURLINFO_LOCAL_PORT:
+    /* Return the local port of the most recent (primary) connection */
+    *param_longp = data->info.conn_local_port;
+    break;
+  case CURLINFO_CONDITION_UNMET:
+    /* return if the condition prevented the document to get transferred */
+    *param_longp = data->info.timecond ? 1L : 0L;
+    break;
+  case CURLINFO_RTSP_CLIENT_CSEQ:
+    *param_longp = data->state.rtsp_next_client_CSeq;
+    break;
+  case CURLINFO_RTSP_SERVER_CSEQ:
+    *param_longp = data->state.rtsp_next_server_CSeq;
+    break;
+  case CURLINFO_RTSP_CSEQ_RECV:
+    *param_longp = data->state.rtsp_CSeq_recv;
+    break;
+
+  default:
+    return CURLE_UNKNOWN_OPTION;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode getinfo_double(struct SessionHandle *data, CURLINFO info,
+                               double *param_doublep)
+{
+  switch(info) {
+  case CURLINFO_TOTAL_TIME:
+    *param_doublep = data->progress.timespent;
+    break;
+  case CURLINFO_NAMELOOKUP_TIME:
+    *param_doublep = data->progress.t_nslookup;
+    break;
+  case CURLINFO_CONNECT_TIME:
+    *param_doublep = data->progress.t_connect;
+    break;
+  case CURLINFO_APPCONNECT_TIME:
+    *param_doublep = data->progress.t_appconnect;
+    break;
+  case CURLINFO_PRETRANSFER_TIME:
+    *param_doublep =  data->progress.t_pretransfer;
+    break;
+  case CURLINFO_STARTTRANSFER_TIME:
+    *param_doublep = data->progress.t_starttransfer;
+    break;
+  case CURLINFO_SIZE_UPLOAD:
+    *param_doublep =  (double)data->progress.uploaded;
+    break;
+  case CURLINFO_SIZE_DOWNLOAD:
+    *param_doublep = (double)data->progress.downloaded;
+    break;
+  case CURLINFO_SPEED_DOWNLOAD:
+    *param_doublep =  (double)data->progress.dlspeed;
+    break;
+  case CURLINFO_SPEED_UPLOAD:
+    *param_doublep = (double)data->progress.ulspeed;
+    break;
+  case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
+    *param_doublep = (data->progress.flags & PGRS_DL_SIZE_KNOWN)?
+      (double)data->progress.size_dl:-1;
+    break;
+  case CURLINFO_CONTENT_LENGTH_UPLOAD:
+    *param_doublep = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
+      (double)data->progress.size_ul:-1;
+    break;
+  case CURLINFO_REDIRECT_TIME:
+    *param_doublep =  data->progress.t_redirect;
+    break;
+
+  default:
+    return CURLE_UNKNOWN_OPTION;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
+                              struct curl_slist **param_slistp)
+{
+  union {
+    struct curl_certinfo *to_certinfo;
+    struct curl_slist    *to_slist;
+  } ptr;
+
+  switch(info) {
+  case CURLINFO_SSL_ENGINES:
+    *param_slistp = Curl_ssl_engines_list(data);
+    break;
+  case CURLINFO_COOKIELIST:
+    *param_slistp = Curl_cookie_list(data);
+    break;
+  case CURLINFO_CERTINFO:
+    /* Return the a pointer to the certinfo struct. Not really an slist
+       pointer but we can pretend it is here */
+    ptr.to_certinfo = &data->info.certs;
+    *param_slistp = ptr.to_slist;
+    break;
+  case CURLINFO_TLS_SESSION:
+    {
+      struct curl_tlssessioninfo **tsip = (struct curl_tlssessioninfo **)
+                                          param_slistp;
+      struct curl_tlssessioninfo *tsi = &data->tsi;
+      struct connectdata *conn = data->easy_conn;
+      unsigned int sockindex = 0;
+      void *internals = NULL;
+
+      *tsip = tsi;
+      tsi->backend = Curl_ssl_backend();
+      tsi->internals = NULL;
+
+      if(!conn)
+        break;
+
+      /* Find the active ("in use") SSL connection, if any */
+      while((sockindex < sizeof(conn->ssl) / sizeof(conn->ssl[0])) &&
+            (!conn->ssl[sockindex].use))
+        sockindex++;
+
+      if(sockindex == sizeof(conn->ssl) / sizeof(conn->ssl[0]))
+        break; /* no SSL session found */
+
+      /* Return the TLS session information from the relevant backend */
+#ifdef USE_OPENSSL
+      internals = conn->ssl[sockindex].ctx;
+#endif
+#ifdef USE_GNUTLS
+      internals = conn->ssl[sockindex].session;
+#endif
+#ifdef USE_NSS
+      internals = conn->ssl[sockindex].handle;
+#endif
+#ifdef USE_GSKIT
+      internals = conn->ssl[sockindex].handle;
+#endif
+      if(internals) {
+        tsi->internals = internals;
+      }
+      /* NOTE: For other SSL backends, it is not immediately clear what data
+         to return from 'struct ssl_connect_data'; thus we keep 'internals' to
+         NULL which should be interpreted as "not supported" */
+    }
+    break;
+  default:
+    return CURLE_UNKNOWN_OPTION;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode getinfo_socket(struct SessionHandle *data, CURLINFO info,
+                               curl_socket_t *param_socketp)
+{
+  switch(info) {
+  case CURLINFO_ACTIVESOCKET:
+    *param_socketp = Curl_getconnectinfo(data, NULL);
+    break;
+  default:
+    return CURLE_UNKNOWN_OPTION;
+  }
+
+  return CURLE_OK;
+}
+
+CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
+{
+  va_list arg;
+  long *param_longp = NULL;
+  double *param_doublep = NULL;
+  char **param_charp = NULL;
+  struct curl_slist **param_slistp = NULL;
+  curl_socket_t *param_socketp = NULL;
+  int type;
+  CURLcode result = CURLE_UNKNOWN_OPTION;
+
+  if(!data)
+    return result;
+
+  va_start(arg, info);
+
+  type = CURLINFO_TYPEMASK & (int)info;
+  switch(type) {
+  case CURLINFO_STRING:
+    param_charp = va_arg(arg, char **);
+    if(param_charp)
+      result = getinfo_char(data, info, param_charp);
+    break;
+  case CURLINFO_LONG:
+    param_longp = va_arg(arg, long *);
+    if(param_longp)
+      result = getinfo_long(data, info, param_longp);
+    break;
+  case CURLINFO_DOUBLE:
+    param_doublep = va_arg(arg, double *);
+    if(param_doublep)
+      result = getinfo_double(data, info, param_doublep);
+    break;
+  case CURLINFO_SLIST:
+    param_slistp = va_arg(arg, struct curl_slist **);
+    if(param_slistp)
+      result = getinfo_slist(data, info, param_slistp);
+    break;
+  case CURLINFO_SOCKET:
+    param_socketp = va_arg(arg, curl_socket_t *);
+    if(param_socketp)
+      result = getinfo_socket(data, info, param_socketp);
+    break;
+  default:
+    break;
+  }
+
+  va_end(arg);
+
+  return result;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/getinfo.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/getinfo.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/getinfo.h	(revision 164)
@@ -0,0 +1,27 @@
+#ifndef HEADER_CURL_GETINFO_H
+#define HEADER_CURL_GETINFO_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...);
+CURLcode Curl_initinfo(struct SessionHandle *data);
+
+#endif /* HEADER_CURL_GETINFO_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/gopher.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/gopher.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/gopher.c	(revision 164)
@@ -0,0 +1,167 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_GOPHER
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+
+#include "progress.h"
+#include "strequal.h"
+#include "gopher.h"
+#include "rawstr.h"
+#include "select.h"
+#include "url.h"
+#include "warnless.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Forward declarations.
+ */
+
+static CURLcode gopher_do(struct connectdata *conn, bool *done);
+
+/*
+ * Gopher protocol handler.
+ * This is also a nice simple template to build off for simple
+ * connect-command-download protocols.
+ */
+
+const struct Curl_handler Curl_handler_gopher = {
+  "GOPHER",                             /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  gopher_do,                            /* do_it */
+  ZERO_NULL,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_GOPHER,                          /* defport */
+  CURLPROTO_GOPHER,                     /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+static CURLcode gopher_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result=CURLE_OK;
+  struct SessionHandle *data=conn->data;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+
+  curl_off_t *bytecount = &data->req.bytecount;
+  char *path = data->state.path;
+  char *sel;
+  char *sel_org = NULL;
+  ssize_t amount, k;
+  int len;
+
+  *done = TRUE; /* unconditionally */
+
+  /* Create selector. Degenerate cases: / and /1 => convert to "" */
+  if(strlen(path) <= 2) {
+    sel = (char *)"";
+    len = (int)strlen(sel);
+  }
+  else {
+    char *newp;
+    size_t j, i;
+
+    /* Otherwise, drop / and the first character (i.e., item type) ... */
+    newp = path;
+    newp+=2;
+
+    /* ... then turn ? into TAB for search servers, Veronica, etc. ... */
+    j = strlen(newp);
+    for(i=0; i<j; i++)
+      if(newp[i] == '?')
+        newp[i] = '\x09';
+
+    /* ... and finally unescape */
+    sel = curl_easy_unescape(data, newp, 0, &len);
+    if(!sel)
+      return CURLE_OUT_OF_MEMORY;
+    sel_org = sel;
+  }
+
+  /* We use Curl_write instead of Curl_sendf to make sure the entire buffer is
+     sent, which could be sizeable with long selectors. */
+  k = curlx_uztosz(len);
+
+  for(;;) {
+    result = Curl_write(conn, sockfd, sel, k, &amount);
+    if(!result) { /* Which may not have written it all! */
+      result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
+      if(result) {
+        free(sel_org);
+        return result;
+      }
+      k -= amount;
+      sel += amount;
+      if(k < 1)
+        break; /* but it did write it all */
+    }
+    else {
+      failf(data, "Failed sending Gopher request");
+      free(sel_org);
+      return result;
+    }
+    /* Don't busyloop. The entire loop thing is a work-around as it causes a
+       BLOCKING behavior which is a NO-NO. This function should rather be
+       split up in a do and a doing piece where the pieces that aren't
+       possible to send now will be sent in the doing function repeatedly
+       until the entire request is sent.
+
+       Wait a while for the socket to be writable. Note that this doesn't
+       acknowledge the timeout.
+    */
+    Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 100);
+  }
+
+  free(sel_org);
+
+  /* We can use Curl_sendf to send the terminal \r\n relatively safely and
+     save allocing another string/doing another _write loop. */
+  result = Curl_sendf(sockfd, conn, "\r\n");
+  if(result) {
+    failf(data, "Failed sending Gopher request");
+    return result;
+  }
+  result = Curl_client_write(conn, CLIENTWRITE_HEADER, (char *)"\r\n", 2);
+  if(result)
+    return result;
+
+  Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
+                      -1, NULL); /* no upload */
+  return CURLE_OK;
+}
+#endif /*CURL_DISABLE_GOPHER*/
Index: UsbWattMeter/trunk/curl-7.47.1/lib/gopher.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/gopher.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/gopher.h	(revision 164)
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_GOPHER_H
+#define HEADER_CURL_GOPHER_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifndef CURL_DISABLE_GOPHER
+extern const struct Curl_handler Curl_handler_gopher;
+#endif
+
+#endif /* HEADER_CURL_GOPHER_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/hash.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/hash.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/hash.c	(revision 164)
@@ -0,0 +1,387 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "hash.h"
+#include "llist.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+static void
+hash_element_dtor(void *user, void *element)
+{
+  struct curl_hash *h = (struct curl_hash *) user;
+  struct curl_hash_element *e = (struct curl_hash_element *) element;
+
+  Curl_safefree(e->key);
+
+  if(e->ptr) {
+    h->dtor(e->ptr);
+    e->ptr = NULL;
+  }
+
+  e->key_len = 0;
+
+  free(e);
+}
+
+/* Initializes a hash structure.
+ * Return 1 on error, 0 is fine.
+ *
+ * @unittest: 1602
+ * @unittest: 1603
+ */
+int
+Curl_hash_init(struct curl_hash *h,
+               int slots,
+               hash_function hfunc,
+               comp_function comparator,
+               curl_hash_dtor dtor)
+{
+  int i;
+
+  if(!slots || !hfunc || !comparator ||!dtor) {
+    return 1; /* failure */
+  }
+
+  h->hash_func = hfunc;
+  h->comp_func = comparator;
+  h->dtor = dtor;
+  h->size = 0;
+  h->slots = slots;
+
+  h->table = malloc(slots * sizeof(struct curl_llist *));
+  if(h->table) {
+    for(i = 0; i < slots; ++i) {
+      h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
+      if(!h->table[i]) {
+        while(i--) {
+          Curl_llist_destroy(h->table[i], NULL);
+          h->table[i] = NULL;
+        }
+        free(h->table);
+        h->table = NULL;
+        h->slots = 0;
+        return 1; /* failure */
+      }
+    }
+    return 0; /* fine */
+  }
+  else {
+    h->slots = 0;
+    return 1; /* failure */
+  }
+}
+
+static struct curl_hash_element *
+mk_hash_element(const void *key, size_t key_len, const void *p)
+{
+  struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element));
+
+  if(he) {
+    void *dupkey = malloc(key_len);
+    if(dupkey) {
+      /* copy the key */
+      memcpy(dupkey, key, key_len);
+
+      he->key = dupkey;
+      he->key_len = key_len;
+      he->ptr = (void *) p;
+    }
+    else {
+      /* failed to duplicate the key, free memory and fail */
+      free(he);
+      he = NULL;
+    }
+  }
+  return he;
+}
+
+#define FETCH_LIST(x,y,z) x->table[x->hash_func(y, z, x->slots)]
+
+/* Insert the data in the hash. If there already was a match in the hash,
+ * that data is replaced.
+ *
+ * @unittest: 1305
+ * @unittest: 1602
+ * @unittest: 1603
+ */
+void *
+Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
+{
+  struct curl_hash_element  *he;
+  struct curl_llist_element *le;
+  struct curl_llist *l = FETCH_LIST (h, key, key_len);
+
+  for(le = l->head; le; le = le->next) {
+    he = (struct curl_hash_element *) le->ptr;
+    if(h->comp_func(he->key, he->key_len, key, key_len)) {
+      Curl_llist_remove(l, le, (void *)h);
+      --h->size;
+      break;
+    }
+  }
+
+  he = mk_hash_element(key, key_len, p);
+  if(he) {
+    if(Curl_llist_insert_next(l, l->tail, he)) {
+      ++h->size;
+      return p; /* return the new entry */
+    }
+    /*
+     * Couldn't insert it, destroy the 'he' element and the key again. We
+     * don't call hash_element_dtor() since that would also call the
+     * "destructor" for the actual data 'p'. When we fail, we shall not touch
+     * that data.
+     */
+    free(he->key);
+    free(he);
+  }
+
+  return NULL; /* failure */
+}
+
+/* Remove the identified hash entry.
+ * Returns non-zero on failure.
+ *
+ * @unittest: 1603
+ */
+int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len)
+{
+  struct curl_llist_element *le;
+  struct curl_hash_element  *he;
+  struct curl_llist *l = FETCH_LIST(h, key, key_len);
+
+  for(le = l->head; le; le = le->next) {
+    he = le->ptr;
+    if(h->comp_func(he->key, he->key_len, key, key_len)) {
+      Curl_llist_remove(l, le, (void *) h);
+      --h->size;
+      return 0;
+    }
+  }
+  return 1;
+}
+
+/* Retrieves a hash element.
+ *
+ * @unittest: 1603
+ */
+void *
+Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len)
+{
+  struct curl_llist_element *le;
+  struct curl_hash_element  *he;
+  struct curl_llist *l;
+
+  if(h) {
+    l = FETCH_LIST(h, key, key_len);
+    for(le = l->head; le; le = le->next) {
+      he = le->ptr;
+      if(h->comp_func(he->key, he->key_len, key, key_len)) {
+        return he->ptr;
+      }
+    }
+  }
+
+  return NULL;
+}
+
+#if defined(DEBUGBUILD) && defined(AGGRESIVE_TEST)
+void
+Curl_hash_apply(curl_hash *h, void *user,
+                void (*cb)(void *user, void *ptr))
+{
+  struct curl_llist_element  *le;
+  int                  i;
+
+  for(i = 0; i < h->slots; ++i) {
+    for(le = (h->table[i])->head;
+        le;
+        le = le->next) {
+      curl_hash_element *el = le->ptr;
+      cb(user, el->ptr);
+    }
+  }
+}
+#endif
+
+/* Destroys all the entries in the given hash and resets its attributes,
+ * prepping the given hash for [static|dynamic] deallocation.
+ *
+ * @unittest: 1305
+ * @unittest: 1602
+ * @unittest: 1603
+ */
+void
+Curl_hash_destroy(struct curl_hash *h)
+{
+  int i;
+
+  for(i = 0; i < h->slots; ++i) {
+    Curl_llist_destroy(h->table[i], (void *) h);
+    h->table[i] = NULL;
+  }
+
+  Curl_safefree(h->table);
+  h->size = 0;
+  h->slots = 0;
+}
+
+/* Removes all the entries in the given hash.
+ *
+ * @unittest: 1602
+ */
+void
+Curl_hash_clean(struct curl_hash *h)
+{
+  Curl_hash_clean_with_criterium(h, NULL, NULL);
+}
+
+/* Cleans all entries that pass the comp function criteria. */
+void
+Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
+                               int (*comp)(void *, void *))
+{
+  struct curl_llist_element *le;
+  struct curl_llist_element *lnext;
+  struct curl_llist *list;
+  int i;
+
+  if(!h)
+    return;
+
+  for(i = 0; i < h->slots; ++i) {
+    list = h->table[i];
+    le = list->head; /* get first list entry */
+    while(le) {
+      struct curl_hash_element *he = le->ptr;
+      lnext = le->next;
+      /* ask the callback function if we shall remove this entry or not */
+      if(comp == NULL || comp(user, he->ptr)) {
+        Curl_llist_remove(list, le, (void *) h);
+        --h->size; /* one less entry in the hash now */
+      }
+      le = lnext;
+    }
+  }
+}
+
+size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num)
+{
+  const char* key_str = (const char *) key;
+  const char *end = key_str + key_length;
+  unsigned long h = 5381;
+
+  while(key_str < end) {
+    h += h << 5;
+    h ^= (unsigned long) *key_str++;
+  }
+
+  return (h % slots_num);
+}
+
+size_t Curl_str_key_compare(void *k1, size_t key1_len,
+                            void *k2, size_t key2_len)
+{
+  if((key1_len == key2_len) && !memcmp(k1, k2, key1_len))
+    return 1;
+
+  return 0;
+}
+
+void Curl_hash_start_iterate(struct curl_hash *hash,
+                             struct curl_hash_iterator *iter)
+{
+  iter->hash = hash;
+  iter->slot_index = 0;
+  iter->current_element = NULL;
+}
+
+struct curl_hash_element *
+Curl_hash_next_element(struct curl_hash_iterator *iter)
+{
+  int i;
+  struct curl_hash *h = iter->hash;
+
+  /* Get the next element in the current list, if any */
+  if(iter->current_element)
+    iter->current_element = iter->current_element->next;
+
+  /* If we have reached the end of the list, find the next one */
+  if(!iter->current_element) {
+    for(i = iter->slot_index;i < h->slots;i++) {
+      if(h->table[i]->head) {
+        iter->current_element = h->table[i]->head;
+        iter->slot_index = i+1;
+        break;
+      }
+    }
+  }
+
+  if(iter->current_element) {
+    struct curl_hash_element *he = iter->current_element->ptr;
+    return he;
+  }
+  else {
+    iter->current_element = NULL;
+    return NULL;
+  }
+}
+
+#if 0 /* useful function for debugging hashes and their contents */
+void Curl_hash_print(struct curl_hash *h,
+                     void (*func)(void *))
+{
+  struct curl_hash_iterator iter;
+  struct curl_hash_element *he;
+  int last_index = -1;
+
+  if(!h)
+    return;
+
+  fprintf(stderr, "=Hash dump=\n");
+
+  Curl_hash_start_iterate(h, &iter);
+
+  he = Curl_hash_next_element(&iter);
+  while(he) {
+    if(iter.slot_index != last_index) {
+      fprintf(stderr, "index %d:", iter.slot_index);
+      if(last_index >= 0) {
+        fprintf(stderr, "\n");
+      }
+      last_index = iter.slot_index;
+    }
+
+    if(func)
+      func(he->ptr);
+    else
+      fprintf(stderr, " [%p]", (void *)he->ptr);
+
+    he = Curl_hash_next_element(&iter);
+  }
+  fprintf(stderr, "\n");
+}
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/lib/hash.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/hash.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/hash.h	(revision 164)
@@ -0,0 +1,100 @@
+#ifndef HEADER_CURL_HASH_H
+#define HEADER_CURL_HASH_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <stddef.h>
+
+#include "llist.h"
+
+/* Hash function prototype */
+typedef size_t (*hash_function) (void* key,
+                                 size_t key_length,
+                                 size_t slots_num);
+
+/*
+   Comparator function prototype. Compares two keys.
+*/
+typedef size_t (*comp_function) (void* key1,
+                                 size_t key1_len,
+                                 void*key2,
+                                 size_t key2_len);
+
+typedef void (*curl_hash_dtor)(void *);
+
+struct curl_hash {
+  struct curl_llist **table;
+
+  /* Hash function to be used for this hash table */
+  hash_function hash_func;
+
+  /* Comparator function to compare keys */
+  comp_function comp_func;
+  curl_hash_dtor   dtor;
+  int slots;
+  size_t size;
+};
+
+struct curl_hash_element {
+  void   *ptr;
+  char   *key;
+  size_t key_len;
+};
+
+struct curl_hash_iterator {
+  struct curl_hash *hash;
+  int slot_index;
+  struct curl_llist_element *current_element;
+};
+
+int Curl_hash_init(struct curl_hash *h,
+                   int slots,
+                   hash_function hfunc,
+                   comp_function comparator,
+                   curl_hash_dtor dtor);
+
+void *Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p);
+int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len);
+void *Curl_hash_pick(struct curl_hash *, void * key, size_t key_len);
+void Curl_hash_apply(struct curl_hash *h, void *user,
+                     void (*cb)(void *user, void *ptr));
+int Curl_hash_count(struct curl_hash *h);
+void Curl_hash_destroy(struct curl_hash *h);
+void Curl_hash_clean(struct curl_hash *h);
+void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
+                                    int (*comp)(void *, void *));
+size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num);
+size_t Curl_str_key_compare(void*k1, size_t key1_len, void*k2,
+                            size_t key2_len);
+
+void Curl_hash_start_iterate(struct curl_hash *hash,
+                             struct curl_hash_iterator *iter);
+struct curl_hash_element *
+Curl_hash_next_element(struct curl_hash_iterator *iter);
+
+void Curl_hash_print(struct curl_hash *h,
+                     void (*func)(void *));
+
+
+#endif /* HEADER_CURL_HASH_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/hmac.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/hmac.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/hmac.c	(revision 164)
@@ -0,0 +1,129 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC2104 Keyed-Hashing for Message Authentication
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+
+#include "curl_hmac.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Generic HMAC algorithm.
+ *
+ *   This module computes HMAC digests based on any hash function. Parameters
+ * and computing procedures are set-up dynamically at HMAC computation
+ * context initialisation.
+ */
+
+static const unsigned char hmac_ipad = 0x36;
+static const unsigned char hmac_opad = 0x5C;
+
+
+
+HMAC_context *
+Curl_HMAC_init(const HMAC_params * hashparams,
+               const unsigned char * key,
+               unsigned int keylen)
+{
+  size_t i;
+  HMAC_context * ctxt;
+  unsigned char * hkey;
+  unsigned char b;
+
+  /* Create HMAC context. */
+  i = sizeof *ctxt + 2 * hashparams->hmac_ctxtsize +
+    hashparams->hmac_resultlen;
+  ctxt = malloc(i);
+
+  if(!ctxt)
+    return ctxt;
+
+  ctxt->hmac_hash = hashparams;
+  ctxt->hmac_hashctxt1 = (void *) (ctxt + 1);
+  ctxt->hmac_hashctxt2 = (void *) ((char *) ctxt->hmac_hashctxt1 +
+      hashparams->hmac_ctxtsize);
+
+  /* If the key is too long, replace it by its hash digest. */
+  if(keylen > hashparams->hmac_maxkeylen) {
+    (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1);
+    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, key, keylen);
+    hkey = (unsigned char *) ctxt->hmac_hashctxt2 + hashparams->hmac_ctxtsize;
+    (*hashparams->hmac_hfinal)(hkey, ctxt->hmac_hashctxt1);
+    key = hkey;
+    keylen = hashparams->hmac_resultlen;
+  }
+
+  /* Prime the two hash contexts with the modified key. */
+  (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1);
+  (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt2);
+
+  for(i = 0; i < keylen; i++) {
+    b = (unsigned char)(*key ^ hmac_ipad);
+    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &b, 1);
+    b = (unsigned char)(*key++ ^ hmac_opad);
+    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &b, 1);
+  }
+
+  for(; i < hashparams->hmac_maxkeylen; i++) {
+    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &hmac_ipad, 1);
+    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &hmac_opad, 1);
+  }
+
+  /* Done, return pointer to HMAC context. */
+  return ctxt;
+}
+
+int Curl_HMAC_update(HMAC_context * ctxt,
+                     const unsigned char * data,
+                     unsigned int len)
+{
+  /* Update first hash calculation. */
+  (*ctxt->hmac_hash->hmac_hupdate)(ctxt->hmac_hashctxt1, data, len);
+  return 0;
+}
+
+
+int Curl_HMAC_final(HMAC_context * ctxt, unsigned char * result)
+{
+  const HMAC_params * hashparams = ctxt->hmac_hash;
+
+  /* Do not get result if called with a null parameter: only release
+     storage. */
+
+  if(!result)
+    result = (unsigned char *) ctxt->hmac_hashctxt2 +
+     ctxt->hmac_hash->hmac_ctxtsize;
+
+  (*hashparams->hmac_hfinal)(result, ctxt->hmac_hashctxt1);
+  (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2,
+   result, hashparams->hmac_resultlen);
+  (*hashparams->hmac_hfinal)(result, ctxt->hmac_hashctxt2);
+  free((char *) ctxt);
+  return 0;
+}
+
+#endif /* CURL_DISABLE_CRYPTO_AUTH */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/hostasyn.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/hostasyn.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/hostasyn.c	(revision 164)
@@ -0,0 +1,153 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/***********************************************************************
+ * Only for builds using asynchronous name resolves
+ **********************************************************************/
+#ifdef CURLRES_ASYNCH
+
+/*
+ * Curl_addrinfo_callback() gets called by ares, gethostbyname_thread()
+ * or getaddrinfo_thread() when we got the name resolved (or not!).
+ *
+ * If the status argument is CURL_ASYNC_SUCCESS, this function takes
+ * ownership of the Curl_addrinfo passed, storing the resolved data
+ * in the DNS cache.
+ *
+ * The storage operation locks and unlocks the DNS cache.
+ */
+CURLcode Curl_addrinfo_callback(struct connectdata *conn,
+                                int status,
+                                struct Curl_addrinfo *ai)
+{
+  struct Curl_dns_entry *dns = NULL;
+  CURLcode result = CURLE_OK;
+
+  conn->async.status = status;
+
+  if(CURL_ASYNC_SUCCESS == status) {
+    if(ai) {
+      struct SessionHandle *data = conn->data;
+
+      if(data->share)
+        Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+      dns = Curl_cache_addr(data, ai,
+                            conn->async.hostname,
+                            conn->async.port);
+      if(!dns) {
+        /* failed to store, cleanup and return error */
+        Curl_freeaddrinfo(ai);
+        result = CURLE_OUT_OF_MEMORY;
+      }
+
+      if(data->share)
+        Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+    }
+    else {
+      result = CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  conn->async.dns = dns;
+
+ /* Set async.done TRUE last in this function since it may be used multi-
+    threaded and once this is TRUE the other thread may read fields from the
+    async struct */
+  conn->async.done = TRUE;
+
+  /* IPv4: The input hostent struct will be freed by ares when we return from
+     this function */
+  return result;
+}
+
+/* Call this function after Curl_connect() has returned async=TRUE and
+   then a successful name resolve has been received.
+
+   Note: this function disconnects and frees the conn data in case of
+   resolve failure */
+CURLcode Curl_async_resolved(struct connectdata *conn,
+                             bool *protocol_done)
+{
+  CURLcode result;
+
+  if(conn->async.dns) {
+    conn->dns_entry = conn->async.dns;
+    conn->async.dns = NULL;
+  }
+
+  result = Curl_setup_conn(conn, protocol_done);
+
+  if(result)
+    /* We're not allowed to return failure with memory left allocated
+       in the connectdata struct, free those here */
+    Curl_disconnect(conn, FALSE); /* close the connection */
+
+  return result;
+}
+
+/*
+ * Curl_getaddrinfo() is the generic low-level name resolve API within this
+ * source file. There are several versions of this function - for different
+ * name resolve layers (selected at build-time). They all take this same set
+ * of arguments
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                const char *hostname,
+                                int port,
+                                int *waitp)
+{
+  return Curl_resolver_getaddrinfo(conn, hostname, port, waitp);
+}
+
+#endif /* CURLRES_ASYNCH */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/hostcheck.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/hostcheck.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/hostcheck.c	(revision 164)
@@ -0,0 +1,147 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_OPENSSL) || defined(USE_AXTLS) || defined(USE_GSKIT)
+/* these backends use functions from this file */
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "hostcheck.h"
+#include "rawstr.h"
+#include "inet_pton.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Match a hostname against a wildcard pattern.
+ * E.g.
+ *  "foo.host.com" matches "*.host.com".
+ *
+ * We use the matching rule described in RFC6125, section 6.4.3.
+ * https://tools.ietf.org/html/rfc6125#section-6.4.3
+ *
+ * In addition: ignore trailing dots in the host names and wildcards, so that
+ * the names are used normalized. This is what the browsers do.
+ *
+ * Do not allow wildcard matching on IP numbers. There are apparently
+ * certificates being used with an IP address in the CN field, thus making no
+ * apparent distinction between a name and an IP. We need to detect the use of
+ * an IP address and not wildcard match on such names.
+ *
+ * NOTE: hostmatch() gets called with copied buffers so that it can modify the
+ * contents at will.
+ */
+
+static int hostmatch(char *hostname, char *pattern)
+{
+  const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
+  int wildcard_enabled;
+  size_t prefixlen, suffixlen;
+  struct in_addr ignored;
+#ifdef ENABLE_IPV6
+  struct sockaddr_in6 si6;
+#endif
+
+  /* normalize pattern and hostname by stripping off trailing dots */
+  size_t len = strlen(hostname);
+  if(hostname[len-1]=='.')
+    hostname[len-1]=0;
+  len = strlen(pattern);
+  if(pattern[len-1]=='.')
+    pattern[len-1]=0;
+
+  pattern_wildcard = strchr(pattern, '*');
+  if(pattern_wildcard == NULL)
+    return Curl_raw_equal(pattern, hostname) ?
+      CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+
+  /* detect IP address as hostname and fail the match if so */
+  if(Curl_inet_pton(AF_INET, hostname, &ignored) > 0)
+    return CURL_HOST_NOMATCH;
+#ifdef ENABLE_IPV6
+  else if(Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0)
+    return CURL_HOST_NOMATCH;
+#endif
+
+  /* We require at least 2 dots in pattern to avoid too wide wildcard
+     match. */
+  wildcard_enabled = 1;
+  pattern_label_end = strchr(pattern, '.');
+  if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL ||
+     pattern_wildcard > pattern_label_end ||
+     Curl_raw_nequal(pattern, "xn--", 4)) {
+    wildcard_enabled = 0;
+  }
+  if(!wildcard_enabled)
+    return Curl_raw_equal(pattern, hostname) ?
+      CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+
+  hostname_label_end = strchr(hostname, '.');
+  if(hostname_label_end == NULL ||
+     !Curl_raw_equal(pattern_label_end, hostname_label_end))
+    return CURL_HOST_NOMATCH;
+
+  /* The wildcard must match at least one character, so the left-most
+     label of the hostname is at least as large as the left-most label
+     of the pattern. */
+  if(hostname_label_end - hostname < pattern_label_end - pattern)
+    return CURL_HOST_NOMATCH;
+
+  prefixlen = pattern_wildcard - pattern;
+  suffixlen = pattern_label_end - (pattern_wildcard+1);
+  return Curl_raw_nequal(pattern, hostname, prefixlen) &&
+    Curl_raw_nequal(pattern_wildcard+1, hostname_label_end - suffixlen,
+                    suffixlen) ?
+    CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+}
+
+int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
+{
+  char *matchp;
+  char *hostp;
+  int res = 0;
+  if(!match_pattern || !*match_pattern ||
+      !hostname || !*hostname) /* sanity check */
+    ;
+  else {
+    matchp = strdup(match_pattern);
+    if(matchp) {
+      hostp = strdup(hostname);
+      if(hostp) {
+        if(hostmatch(hostp, matchp) == CURL_HOST_MATCH)
+          res= 1;
+        free(hostp);
+      }
+      free(matchp);
+    }
+  }
+
+  return res;
+}
+
+#endif /* OPENSSL or AXTLS or GSKIT */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/hostcheck.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/hostcheck.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/hostcheck.h	(revision 164)
@@ -0,0 +1,32 @@
+#ifndef HEADER_CURL_HOSTCHECK_H
+#define HEADER_CURL_HOSTCHECK_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+#define CURL_HOST_NOMATCH 0
+#define CURL_HOST_MATCH   1
+int Curl_cert_hostcheck(const char *match_pattern, const char *hostname);
+
+#endif /* HEADER_CURL_HOSTCHECK_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/hostip.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/hostip.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/hostip.c	(revision 164)
@@ -0,0 +1,880 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "inet_ntop.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#if defined(CURLRES_SYNCH) && \
+    defined(HAVE_ALARM) && defined(SIGALRM) && defined(HAVE_SIGSETJMP)
+/* alarm-based timeouts can only be used with all the dependencies satisfied */
+#define USE_ALARM_TIMEOUT
+#endif
+
+/*
+ * hostip.c explained
+ * ==================
+ *
+ * The main COMPILE-TIME DEFINES to keep in mind when reading the host*.c
+ * source file are these:
+ *
+ * CURLRES_IPV6 - this host has getaddrinfo() and family, and thus we use
+ * that. The host may not be able to resolve IPv6, but we don't really have to
+ * take that into account. Hosts that aren't IPv6-enabled have CURLRES_IPV4
+ * defined.
+ *
+ * CURLRES_ARES - is defined if libcurl is built to use c-ares for
+ * asynchronous name resolves. This can be Windows or *nix.
+ *
+ * CURLRES_THREADED - is defined if libcurl is built to run under (native)
+ * Windows, and then the name resolve will be done in a new thread, and the
+ * supported API will be the same as for ares-builds.
+ *
+ * If any of the two previous are defined, CURLRES_ASYNCH is defined too. If
+ * libcurl is not built to use an asynchronous resolver, CURLRES_SYNCH is
+ * defined.
+ *
+ * The host*.c sources files are split up like this:
+ *
+ * hostip.c   - method-independent resolver functions and utility functions
+ * hostasyn.c - functions for asynchronous name resolves
+ * hostsyn.c  - functions for synchronous name resolves
+ * hostip4.c  - IPv4 specific functions
+ * hostip6.c  - IPv6 specific functions
+ *
+ * The two asynchronous name resolver backends are implemented in:
+ * asyn-ares.c   - functions for ares-using name resolves
+ * asyn-thread.c - functions for threaded name resolves
+
+ * The hostip.h is the united header file for all this. It defines the
+ * CURLRES_* defines based on the config*.h and curl_setup.h defines.
+ */
+
+/* These two symbols are for the global DNS cache */
+static struct curl_hash hostname_cache;
+static int host_cache_initialized;
+
+static void freednsentry(void *freethis);
+
+/*
+ * Curl_global_host_cache_init() initializes and sets up a global DNS cache.
+ * Global DNS cache is general badness. Do not use. This will be removed in
+ * a future version. Use the share interface instead!
+ *
+ * Returns a struct curl_hash pointer on success, NULL on failure.
+ */
+struct curl_hash *Curl_global_host_cache_init(void)
+{
+  int rc = 0;
+  if(!host_cache_initialized) {
+    rc = Curl_hash_init(&hostname_cache, 7, Curl_hash_str,
+                        Curl_str_key_compare, freednsentry);
+    if(!rc)
+      host_cache_initialized = 1;
+  }
+  return rc?NULL:&hostname_cache;
+}
+
+/*
+ * Destroy and cleanup the global DNS cache
+ */
+void Curl_global_host_cache_dtor(void)
+{
+  if(host_cache_initialized) {
+    Curl_hash_destroy(&hostname_cache);
+    host_cache_initialized = 0;
+  }
+}
+
+/*
+ * Return # of adresses in a Curl_addrinfo struct
+ */
+int Curl_num_addresses(const Curl_addrinfo *addr)
+{
+  int i = 0;
+  while(addr) {
+    addr = addr->ai_next;
+    i++;
+  }
+  return i;
+}
+
+/*
+ * Curl_printable_address() returns a printable version of the 1st address
+ * given in the 'ai' argument. The result will be stored in the buf that is
+ * bufsize bytes big.
+ *
+ * If the conversion fails, it returns NULL.
+ */
+const char *
+Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize)
+{
+  const struct sockaddr_in *sa4;
+  const struct in_addr *ipaddr4;
+#ifdef ENABLE_IPV6
+  const struct sockaddr_in6 *sa6;
+  const struct in6_addr *ipaddr6;
+#endif
+
+  switch (ai->ai_family) {
+    case AF_INET:
+      sa4 = (const void *)ai->ai_addr;
+      ipaddr4 = &sa4->sin_addr;
+      return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf,
+                            bufsize);
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      sa6 = (const void *)ai->ai_addr;
+      ipaddr6 = &sa6->sin6_addr;
+      return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf,
+                            bufsize);
+#endif
+    default:
+      break;
+  }
+  return NULL;
+}
+
+/*
+ * Return a hostcache id string for the provided host + port, to be used by
+ * the DNS caching.
+ */
+static char *
+create_hostcache_id(const char *name, int port)
+{
+  /* create and return the new allocated entry */
+  char *id = aprintf("%s:%d", name, port);
+  char *ptr = id;
+  if(ptr) {
+    /* lower case the name part */
+    while(*ptr && (*ptr != ':')) {
+      *ptr = (char)TOLOWER(*ptr);
+      ptr++;
+    }
+  }
+  return id;
+}
+
+struct hostcache_prune_data {
+  long cache_timeout;
+  time_t now;
+};
+
+/*
+ * This function is set as a callback to be called for every entry in the DNS
+ * cache when we want to prune old unused entries.
+ *
+ * Returning non-zero means remove the entry, return 0 to keep it in the
+ * cache.
+ */
+static int
+hostcache_timestamp_remove(void *datap, void *hc)
+{
+  struct hostcache_prune_data *data =
+    (struct hostcache_prune_data *) datap;
+  struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc;
+
+  return (0 != c->timestamp)
+    && (data->now - c->timestamp >= data->cache_timeout);
+}
+
+/*
+ * Prune the DNS cache. This assumes that a lock has already been taken.
+ */
+static void
+hostcache_prune(struct curl_hash *hostcache, long cache_timeout, time_t now)
+{
+  struct hostcache_prune_data user;
+
+  user.cache_timeout = cache_timeout;
+  user.now = now;
+
+  Curl_hash_clean_with_criterium(hostcache,
+                                 (void *) &user,
+                                 hostcache_timestamp_remove);
+}
+
+/*
+ * Library-wide function for pruning the DNS cache. This function takes and
+ * returns the appropriate locks.
+ */
+void Curl_hostcache_prune(struct SessionHandle *data)
+{
+  time_t now;
+
+  if((data->set.dns_cache_timeout == -1) || !data->dns.hostcache)
+    /* cache forever means never prune, and NULL hostcache means
+       we can't do it */
+    return;
+
+  if(data->share)
+    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+  time(&now);
+
+  /* Remove outdated and unused entries from the hostcache */
+  hostcache_prune(data->dns.hostcache,
+                  data->set.dns_cache_timeout,
+                  now);
+
+  if(data->share)
+    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+}
+
+#ifdef HAVE_SIGSETJMP
+/* Beware this is a global and unique instance. This is used to store the
+   return address that we can jump back to from inside a signal handler. This
+   is not thread-safe stuff. */
+sigjmp_buf curl_jmpenv;
+#endif
+
+/* lookup address, returns entry if found and not stale */
+static struct Curl_dns_entry *
+fetch_addr(struct connectdata *conn,
+                const char *hostname,
+                int port)
+{
+  char *entry_id = NULL;
+  struct Curl_dns_entry *dns = NULL;
+  size_t entry_len;
+  struct SessionHandle *data = conn->data;
+
+  /* Create an entry id, based upon the hostname and port */
+  entry_id = create_hostcache_id(hostname, port);
+  /* If we can't create the entry id, fail */
+  if(!entry_id)
+    return dns;
+
+  entry_len = strlen(entry_id);
+
+  /* See if its already in our dns cache */
+  dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1);
+
+  if(dns && (data->set.dns_cache_timeout != -1))  {
+    /* See whether the returned entry is stale. Done before we release lock */
+    struct hostcache_prune_data user;
+
+    time(&user.now);
+    user.cache_timeout = data->set.dns_cache_timeout;
+
+    if(hostcache_timestamp_remove(&user, dns)) {
+      infof(data, "Hostname in DNS cache was stale, zapped\n");
+      dns = NULL; /* the memory deallocation is being handled by the hash */
+      Curl_hash_delete(data->dns.hostcache, entry_id, entry_len+1);
+    }
+  }
+
+  /* free the allocated entry_id again */
+  free(entry_id);
+
+  return dns;
+}
+
+/*
+ * Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
+ *
+ * Curl_resolv() checks initially and multi_runsingle() checks each time
+ * it discovers the handle in the state WAITRESOLVE whether the hostname
+ * has already been resolved and the address has already been stored in
+ * the DNS cache. This short circuits waiting for a lot of pending
+ * lookups for the same hostname requested by different handles.
+ *
+ * Returns the Curl_dns_entry entry pointer or NULL if not in the cache.
+ *
+ * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
+ * use, or we'll leak memory!
+ */
+struct Curl_dns_entry *
+Curl_fetch_addr(struct connectdata *conn,
+                const char *hostname,
+                int port)
+{
+  struct SessionHandle *data = conn->data;
+  struct Curl_dns_entry *dns = NULL;
+
+  if(data->share)
+    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+  dns = fetch_addr(conn, hostname, port);
+
+  if(dns) dns->inuse++; /* we use it! */
+
+  if(data->share)
+    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+  return dns;
+}
+
+/*
+ * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
+ *
+ * When calling Curl_resolv() has resulted in a response with a returned
+ * address, we call this function to store the information in the dns
+ * cache etc
+ *
+ * Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
+ */
+struct Curl_dns_entry *
+Curl_cache_addr(struct SessionHandle *data,
+                Curl_addrinfo *addr,
+                const char *hostname,
+                int port)
+{
+  char *entry_id;
+  size_t entry_len;
+  struct Curl_dns_entry *dns;
+  struct Curl_dns_entry *dns2;
+
+  /* Create an entry id, based upon the hostname and port */
+  entry_id = create_hostcache_id(hostname, port);
+  /* If we can't create the entry id, fail */
+  if(!entry_id)
+    return NULL;
+  entry_len = strlen(entry_id);
+
+  /* Create a new cache entry */
+  dns = calloc(1, sizeof(struct Curl_dns_entry));
+  if(!dns) {
+    free(entry_id);
+    return NULL;
+  }
+
+  dns->inuse = 1;   /* the cache has the first reference */
+  dns->addr = addr; /* this is the address(es) */
+  time(&dns->timestamp);
+  if(dns->timestamp == 0)
+    dns->timestamp = 1;   /* zero indicates CURLOPT_RESOLVE entry */
+
+  /* Store the resolved data in our DNS cache. */
+  dns2 = Curl_hash_add(data->dns.hostcache, entry_id, entry_len+1,
+                       (void *)dns);
+  if(!dns2) {
+    free(dns);
+    free(entry_id);
+    return NULL;
+  }
+
+  dns = dns2;
+  dns->inuse++;         /* mark entry as in-use */
+
+  /* free the allocated entry_id */
+  free(entry_id);
+
+  return dns;
+}
+
+/*
+ * Curl_resolv() is the main name resolve function within libcurl. It resolves
+ * a name and returns a pointer to the entry in the 'entry' argument (if one
+ * is provided). This function might return immediately if we're using asynch
+ * resolves. See the return codes.
+ *
+ * The cache entry we return will get its 'inuse' counter increased when this
+ * function is used. You MUST call Curl_resolv_unlock() later (when you're
+ * done using this struct) to decrease the counter again.
+ *
+ * In debug mode, we specifically test for an interface name "LocalHost"
+ * and resolve "localhost" instead as a means to permit test cases
+ * to connect to a local test server with any host name.
+ *
+ * Return codes:
+ *
+ * CURLRESOLV_ERROR   (-1) = error, no pointer
+ * CURLRESOLV_RESOLVED (0) = OK, pointer provided
+ * CURLRESOLV_PENDING  (1) = waiting for response, no pointer
+ */
+
+int Curl_resolv(struct connectdata *conn,
+                const char *hostname,
+                int port,
+                struct Curl_dns_entry **entry)
+{
+  struct Curl_dns_entry *dns = NULL;
+  struct SessionHandle *data = conn->data;
+  CURLcode result;
+  int rc = CURLRESOLV_ERROR; /* default to failure */
+
+  *entry = NULL;
+
+  if(data->share)
+    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+  dns = fetch_addr(conn, hostname, port);
+
+  if(dns) {
+    infof(data, "Hostname %s was found in DNS cache\n", hostname);
+    dns->inuse++; /* we use it! */
+    rc = CURLRESOLV_RESOLVED;
+  }
+
+  if(data->share)
+    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+  if(!dns) {
+    /* The entry was not in the cache. Resolve it to IP address */
+
+    Curl_addrinfo *addr;
+    int respwait;
+
+    /* Check what IP specifics the app has requested and if we can provide it.
+     * If not, bail out. */
+    if(!Curl_ipvalid(conn))
+      return CURLRESOLV_ERROR;
+
+    /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
+       non-zero value indicating that we need to wait for the response to the
+       resolve call */
+    addr = Curl_getaddrinfo(conn,
+#ifdef DEBUGBUILD
+                            (data->set.str[STRING_DEVICE]
+                             && !strcmp(data->set.str[STRING_DEVICE],
+                                        "LocalHost"))?"localhost":
+#endif
+                            hostname, port, &respwait);
+
+    if(!addr) {
+      if(respwait) {
+        /* the response to our resolve call will come asynchronously at
+           a later time, good or bad */
+        /* First, check that we haven't received the info by now */
+        result = Curl_resolver_is_resolved(conn, &dns);
+        if(result) /* error detected */
+          return CURLRESOLV_ERROR;
+        if(dns)
+          rc = CURLRESOLV_RESOLVED; /* pointer provided */
+        else
+          rc = CURLRESOLV_PENDING; /* no info yet */
+      }
+    }
+    else {
+      if(data->share)
+        Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+      /* we got a response, store it in the cache */
+      dns = Curl_cache_addr(data, addr, hostname, port);
+
+      if(data->share)
+        Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+      if(!dns)
+        /* returned failure, bail out nicely */
+        Curl_freeaddrinfo(addr);
+      else
+        rc = CURLRESOLV_RESOLVED;
+    }
+  }
+
+  *entry = dns;
+
+  return rc;
+}
+
+#ifdef USE_ALARM_TIMEOUT
+/*
+ * This signal handler jumps back into the main libcurl code and continues
+ * execution.  This effectively causes the remainder of the application to run
+ * within a signal handler which is nonportable and could lead to problems.
+ */
+static
+RETSIGTYPE alarmfunc(int sig)
+{
+  /* this is for "-ansi -Wall -pedantic" to stop complaining!   (rabe) */
+  (void)sig;
+  siglongjmp(curl_jmpenv, 1);
+  return;
+}
+#endif /* USE_ALARM_TIMEOUT */
+
+/*
+ * Curl_resolv_timeout() is the same as Curl_resolv() but specifies a
+ * timeout.  This function might return immediately if we're using asynch
+ * resolves. See the return codes.
+ *
+ * The cache entry we return will get its 'inuse' counter increased when this
+ * function is used. You MUST call Curl_resolv_unlock() later (when you're
+ * done using this struct) to decrease the counter again.
+ *
+ * If built with a synchronous resolver and use of signals is not
+ * disabled by the application, then a nonzero timeout will cause a
+ * timeout after the specified number of milliseconds. Otherwise, timeout
+ * is ignored.
+ *
+ * Return codes:
+ *
+ * CURLRESOLV_TIMEDOUT(-2) = warning, time too short or previous alarm expired
+ * CURLRESOLV_ERROR   (-1) = error, no pointer
+ * CURLRESOLV_RESOLVED (0) = OK, pointer provided
+ * CURLRESOLV_PENDING  (1) = waiting for response, no pointer
+ */
+
+int Curl_resolv_timeout(struct connectdata *conn,
+                        const char *hostname,
+                        int port,
+                        struct Curl_dns_entry **entry,
+                        long timeoutms)
+{
+#ifdef USE_ALARM_TIMEOUT
+#ifdef HAVE_SIGACTION
+  struct sigaction keep_sigact;   /* store the old struct here */
+  volatile bool keep_copysig = FALSE; /* wether old sigact has been saved */
+  struct sigaction sigact;
+#else
+#ifdef HAVE_SIGNAL
+  void (*keep_sigact)(int);       /* store the old handler here */
+#endif /* HAVE_SIGNAL */
+#endif /* HAVE_SIGACTION */
+  volatile long timeout;
+  volatile unsigned int prev_alarm = 0;
+  struct SessionHandle *data = conn->data;
+#endif /* USE_ALARM_TIMEOUT */
+  int rc;
+
+  *entry = NULL;
+
+  if(timeoutms < 0)
+    /* got an already expired timeout */
+    return CURLRESOLV_TIMEDOUT;
+
+#ifdef USE_ALARM_TIMEOUT
+  if(data->set.no_signal)
+    /* Ignore the timeout when signals are disabled */
+    timeout = 0;
+  else
+    timeout = timeoutms;
+
+  if(!timeout)
+    /* USE_ALARM_TIMEOUT defined, but no timeout actually requested */
+    return Curl_resolv(conn, hostname, port, entry);
+
+  if(timeout < 1000)
+    /* The alarm() function only provides integer second resolution, so if
+       we want to wait less than one second we must bail out already now. */
+    return CURLRESOLV_TIMEDOUT;
+
+  /* This allows us to time-out from the name resolver, as the timeout
+     will generate a signal and we will siglongjmp() from that here.
+     This technique has problems (see alarmfunc).
+     This should be the last thing we do before calling Curl_resolv(),
+     as otherwise we'd have to worry about variables that get modified
+     before we invoke Curl_resolv() (and thus use "volatile"). */
+  if(sigsetjmp(curl_jmpenv, 1)) {
+    /* this is coming from a siglongjmp() after an alarm signal */
+    failf(data, "name lookup timed out");
+    rc = CURLRESOLV_ERROR;
+    goto clean_up;
+  }
+  else {
+    /*************************************************************
+     * Set signal handler to catch SIGALRM
+     * Store the old value to be able to set it back later!
+     *************************************************************/
+#ifdef HAVE_SIGACTION
+    sigaction(SIGALRM, NULL, &sigact);
+    keep_sigact = sigact;
+    keep_copysig = TRUE; /* yes, we have a copy */
+    sigact.sa_handler = alarmfunc;
+#ifdef SA_RESTART
+    /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
+    sigact.sa_flags &= ~SA_RESTART;
+#endif
+    /* now set the new struct */
+    sigaction(SIGALRM, &sigact, NULL);
+#else /* HAVE_SIGACTION */
+    /* no sigaction(), revert to the much lamer signal() */
+#ifdef HAVE_SIGNAL
+    keep_sigact = signal(SIGALRM, alarmfunc);
+#endif
+#endif /* HAVE_SIGACTION */
+
+    /* alarm() makes a signal get sent when the timeout fires off, and that
+       will abort system calls */
+    prev_alarm = alarm(curlx_sltoui(timeout/1000L));
+  }
+
+#else
+#ifndef CURLRES_ASYNCH
+  if(timeoutms)
+    infof(conn->data, "timeout on name lookup is not supported\n");
+#else
+  (void)timeoutms; /* timeoutms not used with an async resolver */
+#endif
+#endif /* USE_ALARM_TIMEOUT */
+
+  /* Perform the actual name resolution. This might be interrupted by an
+   * alarm if it takes too long.
+   */
+  rc = Curl_resolv(conn, hostname, port, entry);
+
+#ifdef USE_ALARM_TIMEOUT
+clean_up:
+
+  if(!prev_alarm)
+    /* deactivate a possibly active alarm before uninstalling the handler */
+    alarm(0);
+
+#ifdef HAVE_SIGACTION
+  if(keep_copysig) {
+    /* we got a struct as it looked before, now put that one back nice
+       and clean */
+    sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
+  }
+#else
+#ifdef HAVE_SIGNAL
+  /* restore the previous SIGALRM handler */
+  signal(SIGALRM, keep_sigact);
+#endif
+#endif /* HAVE_SIGACTION */
+
+  /* switch back the alarm() to either zero or to what it was before minus
+     the time we spent until now! */
+  if(prev_alarm) {
+    /* there was an alarm() set before us, now put it back */
+    unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created);
+
+    /* the alarm period is counted in even number of seconds */
+    unsigned long alarm_set = prev_alarm - elapsed_ms/1000;
+
+    if(!alarm_set ||
+       ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) {
+      /* if the alarm time-left reached zero or turned "negative" (counted
+         with unsigned values), we should fire off a SIGALRM here, but we
+         won't, and zero would be to switch it off so we never set it to
+         less than 1! */
+      alarm(1);
+      rc = CURLRESOLV_TIMEDOUT;
+      failf(data, "Previous alarm fired off!");
+    }
+    else
+      alarm((unsigned int)alarm_set);
+  }
+#endif /* USE_ALARM_TIMEOUT */
+
+  return rc;
+}
+
+/*
+ * Curl_resolv_unlock() unlocks the given cached DNS entry. When this has been
+ * made, the struct may be destroyed due to pruning. It is important that only
+ * one unlock is made for each Curl_resolv() call.
+ *
+ * May be called with 'data' == NULL for global cache.
+ */
+void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
+{
+  if(data && data->share)
+    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+  freednsentry(dns);
+
+  if(data && data->share)
+    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+}
+
+/*
+ * File-internal: release cache dns entry reference, free if inuse drops to 0
+ */
+static void freednsentry(void *freethis)
+{
+  struct Curl_dns_entry *dns = (struct Curl_dns_entry *) freethis;
+  DEBUGASSERT(dns && (dns->inuse>0));
+
+  dns->inuse--;
+  if(dns->inuse == 0) {
+    Curl_freeaddrinfo(dns->addr);
+    free(dns);
+  }
+}
+
+/*
+ * Curl_mk_dnscache() inits a new DNS cache and returns success/failure.
+ */
+int Curl_mk_dnscache(struct curl_hash *hash)
+{
+  return Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare,
+                        freednsentry);
+}
+
+/*
+ * Curl_hostcache_clean()
+ *
+ * This _can_ be called with 'data' == NULL but then of course no locking
+ * can be done!
+ */
+
+void Curl_hostcache_clean(struct SessionHandle *data,
+                          struct curl_hash *hash)
+{
+  if(data && data->share)
+    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+  Curl_hash_clean(hash);
+
+  if(data && data->share)
+    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+}
+
+
+CURLcode Curl_loadhostpairs(struct SessionHandle *data)
+{
+  struct curl_slist *hostp;
+  char hostname[256];
+  char address[256];
+  int port;
+
+  for(hostp = data->change.resolve; hostp; hostp = hostp->next ) {
+    if(!hostp->data)
+      continue;
+    if(hostp->data[0] == '-') {
+      char *entry_id;
+      size_t entry_len;
+
+      if(2 != sscanf(hostp->data + 1, "%255[^:]:%d", hostname, &port)) {
+        infof(data, "Couldn't parse CURLOPT_RESOLVE removal entry '%s'!\n",
+              hostp->data);
+        continue;
+      }
+
+      /* Create an entry id, based upon the hostname and port */
+      entry_id = create_hostcache_id(hostname, port);
+      /* If we can't create the entry id, fail */
+      if(!entry_id) {
+        return CURLE_OUT_OF_MEMORY;
+      }
+
+      entry_len = strlen(entry_id);
+
+      if(data->share)
+        Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+      /* delete entry, ignore if it didn't exist */
+      Curl_hash_delete(data->dns.hostcache, entry_id, entry_len+1);
+
+      if(data->share)
+        Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+      /* free the allocated entry_id again */
+      free(entry_id);
+    }
+    else {
+      struct Curl_dns_entry *dns;
+      Curl_addrinfo *addr;
+      char *entry_id;
+      size_t entry_len;
+
+      if(3 != sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port,
+                     address)) {
+        infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n",
+              hostp->data);
+        continue;
+      }
+
+      addr = Curl_str2addr(address, port);
+      if(!addr) {
+        infof(data, "Address in '%s' found illegal!\n", hostp->data);
+        continue;
+      }
+
+      /* Create an entry id, based upon the hostname and port */
+      entry_id = create_hostcache_id(hostname, port);
+      /* If we can't create the entry id, fail */
+      if(!entry_id) {
+        Curl_freeaddrinfo(addr);
+        return CURLE_OUT_OF_MEMORY;
+      }
+
+      entry_len = strlen(entry_id);
+
+      if(data->share)
+        Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+      /* See if its already in our dns cache */
+      dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1);
+
+      /* free the allocated entry_id again */
+      free(entry_id);
+
+      if(!dns) {
+        /* if not in the cache already, put this host in the cache */
+        dns = Curl_cache_addr(data, addr, hostname, port);
+        if(dns) {
+          dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */
+          /* release the returned reference; the cache itself will keep the
+           * entry alive: */
+          dns->inuse--;
+        }
+      }
+      else
+        /* this is a duplicate, free it again */
+        Curl_freeaddrinfo(addr);
+
+      if(data->share)
+        Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+      if(!dns) {
+        Curl_freeaddrinfo(addr);
+        return CURLE_OUT_OF_MEMORY;
+      }
+      infof(data, "Added %s:%d:%s to DNS cache\n",
+            hostname, port, address);
+    }
+  }
+  data->change.resolve = NULL; /* dealt with now */
+
+  return CURLE_OK;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/hostip.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/hostip.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/hostip.h	(revision 164)
@@ -0,0 +1,250 @@
+#ifndef HEADER_CURL_HOSTIP_H
+#define HEADER_CURL_HOSTIP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "hash.h"
+#include "curl_addrinfo.h"
+#include "asyn.h"
+
+#ifdef HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+
+#ifdef NETWARE
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+/* Allocate enough memory to hold the full name information structs and
+ * everything. OSF1 is known to require at least 8872 bytes. The buffer
+ * required for storing all possible aliases and IP numbers is according to
+ * Stevens' Unix Network Programming 2nd edition, p. 304: 8192 bytes!
+ */
+#define CURL_HOSTENT_SIZE 9000
+
+#define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this
+                                    many seconds for a name resolve */
+
+#define CURL_ASYNC_SUCCESS CURLE_OK
+
+struct addrinfo;
+struct hostent;
+struct SessionHandle;
+struct connectdata;
+
+/*
+ * Curl_global_host_cache_init() initializes and sets up a global DNS cache.
+ * Global DNS cache is general badness. Do not use. This will be removed in
+ * a future version. Use the share interface instead!
+ *
+ * Returns a struct curl_hash pointer on success, NULL on failure.
+ */
+struct curl_hash *Curl_global_host_cache_init(void);
+void Curl_global_host_cache_dtor(void);
+
+struct Curl_dns_entry {
+  Curl_addrinfo *addr;
+  /* timestamp == 0 -- CURLOPT_RESOLVE entry, doesn't timeout */
+  time_t timestamp;
+  /* use-counter, use Curl_resolv_unlock to release reference */
+  long inuse;
+};
+
+/*
+ * Curl_resolv() returns an entry with the info for the specified host
+ * and port.
+ *
+ * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
+ * use, or we'll leak memory!
+ */
+/* return codes */
+#define CURLRESOLV_TIMEDOUT -2
+#define CURLRESOLV_ERROR    -1
+#define CURLRESOLV_RESOLVED  0
+#define CURLRESOLV_PENDING   1
+int Curl_resolv(struct connectdata *conn, const char *hostname,
+                int port, struct Curl_dns_entry **dnsentry);
+int Curl_resolv_timeout(struct connectdata *conn, const char *hostname,
+                        int port, struct Curl_dns_entry **dnsentry,
+                        long timeoutms);
+
+#ifdef CURLRES_IPV6
+/*
+ * Curl_ipv6works() returns TRUE if IPv6 seems to work.
+ */
+bool Curl_ipv6works(void);
+#else
+#define Curl_ipv6works() FALSE
+#endif
+
+/*
+ * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
+ * been set and returns TRUE if they are OK.
+ */
+bool Curl_ipvalid(struct connectdata *conn);
+
+
+/*
+ * Curl_getaddrinfo() is the generic low-level name resolve API within this
+ * source file. There are several versions of this function - for different
+ * name resolve layers (selected at build-time). They all take this same set
+ * of arguments
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                const char *hostname,
+                                int port,
+                                int *waitp);
+
+
+/* unlock a previously resolved dns entry */
+void Curl_resolv_unlock(struct SessionHandle *data,
+                        struct Curl_dns_entry *dns);
+
+/* for debugging purposes only: */
+void Curl_scan_cache_used(void *user, void *ptr);
+
+/* init a new dns cache and return success */
+int Curl_mk_dnscache(struct curl_hash *hash);
+
+/* prune old entries from the DNS cache */
+void Curl_hostcache_prune(struct SessionHandle *data);
+
+/* Return # of adresses in a Curl_addrinfo struct */
+int Curl_num_addresses (const Curl_addrinfo *addr);
+
+#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
+int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
+                       GETNAMEINFO_TYPE_ARG2 salen,
+                       char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
+                       char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
+                       GETNAMEINFO_TYPE_ARG7 flags,
+                       int line, const char *source);
+#endif
+
+/* IPv4 threadsafe resolve function used for synch and asynch builds */
+Curl_addrinfo *Curl_ipv4_resolve_r(const char * hostname, int port);
+
+CURLcode Curl_async_resolved(struct connectdata *conn,
+                             bool *protocol_connect);
+
+#ifndef CURLRES_ASYNCH
+#define Curl_async_resolved(x,y) CURLE_OK
+#endif
+
+/*
+ * Curl_addrinfo_callback() is used when we build with any asynch specialty.
+ * Handles end of async request processing. Inserts ai into hostcache when
+ * status is CURL_ASYNC_SUCCESS. Twiddles fields in conn to indicate async
+ * request completed whether successful or failed.
+ */
+CURLcode Curl_addrinfo_callback(struct connectdata *conn,
+                                int status,
+                                Curl_addrinfo *ai);
+
+/*
+ * Curl_printable_address() returns a printable version of the 1st address
+ * given in the 'ip' argument. The result will be stored in the buf that is
+ * bufsize bytes big.
+ */
+const char *Curl_printable_address(const Curl_addrinfo *ip,
+                                   char *buf, size_t bufsize);
+
+/*
+ * Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
+ *
+ * Returns the Curl_dns_entry entry pointer or NULL if not in the cache.
+ *
+ * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
+ * use, or we'll leak memory!
+ */
+struct Curl_dns_entry *
+Curl_fetch_addr(struct connectdata *conn,
+                const char *hostname,
+                int port);
+/*
+ * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
+ *
+ * Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
+ */
+struct Curl_dns_entry *
+Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr,
+                const char *hostname, int port);
+
+#ifndef INADDR_NONE
+#define CURL_INADDR_NONE (in_addr_t) ~0
+#else
+#define CURL_INADDR_NONE INADDR_NONE
+#endif
+
+#ifdef HAVE_SIGSETJMP
+/* Forward-declaration of variable defined in hostip.c. Beware this
+ * is a global and unique instance. This is used to store the return
+ * address that we can jump back to from inside a signal handler.
+ * This is not thread-safe stuff.
+ */
+extern sigjmp_buf curl_jmpenv;
+#endif
+
+/*
+ * Function provided by the resolver backend to set DNS servers to use.
+ */
+CURLcode Curl_set_dns_servers(struct SessionHandle *data, char *servers);
+
+/*
+ * Function provided by the resolver backend to set
+ * outgoing interface to use for DNS requests
+ */
+CURLcode Curl_set_dns_interface(struct SessionHandle *data,
+                                const char *interf);
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv4 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
+                                const char *local_ip4);
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv6 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
+                                const char *local_ip6);
+
+/*
+ * Clean off entries from the cache
+ */
+void Curl_hostcache_clean(struct SessionHandle *data, struct curl_hash *hash);
+
+/*
+ * Destroy the hostcache of this handle.
+ */
+void Curl_hostcache_destroy(struct SessionHandle *data);
+
+/*
+ * Populate the cache with specified entries from CURLOPT_RESOLVE.
+ */
+CURLcode Curl_loadhostpairs(struct SessionHandle *data);
+
+#endif /* HEADER_CURL_HOSTIP_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/hostip4.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/hostip4.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/hostip4.c	(revision 164)
@@ -0,0 +1,307 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "inet_pton.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/***********************************************************************
+ * Only for plain IPv4 builds
+ **********************************************************************/
+#ifdef CURLRES_IPV4 /* plain IPv4 code coming up */
+/*
+ * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
+ * been set and returns TRUE if they are OK.
+ */
+bool Curl_ipvalid(struct connectdata *conn)
+{
+  if(conn->ip_version == CURL_IPRESOLVE_V6)
+    /* An IPv6 address was requested and we can't get/use one */
+    return FALSE;
+
+  return TRUE; /* OK, proceed */
+}
+
+#ifdef CURLRES_SYNCH
+
+/*
+ * Curl_getaddrinfo() - the IPv4 synchronous version.
+ *
+ * The original code to this function was from the Dancer source code, written
+ * by Bjorn Reese, it has since been patched and modified considerably.
+ *
+ * gethostbyname_r() is the thread-safe version of the gethostbyname()
+ * function. When we build for plain IPv4, we attempt to use this
+ * function. There are _three_ different gethostbyname_r() versions, and we
+ * detect which one this platform supports in the configure script and set up
+ * the HAVE_GETHOSTBYNAME_R_3, HAVE_GETHOSTBYNAME_R_5 or
+ * HAVE_GETHOSTBYNAME_R_6 defines accordingly. Note that HAVE_GETADDRBYNAME
+ * has the corresponding rules. This is primarily on *nix. Note that some unix
+ * flavours have thread-safe versions of the plain gethostbyname() etc.
+ *
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                const char *hostname,
+                                int port,
+                                int *waitp)
+{
+  Curl_addrinfo *ai = NULL;
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+  (void)conn;
+#endif
+
+  *waitp = 0; /* synchronous response only */
+
+  ai = Curl_ipv4_resolve_r(hostname, port);
+  if(!ai)
+    infof(conn->data, "Curl_ipv4_resolve_r failed for %s\n", hostname);
+
+  return ai;
+}
+#endif /* CURLRES_SYNCH */
+#endif /* CURLRES_IPV4 */
+
+#if defined(CURLRES_IPV4) && !defined(CURLRES_ARES)
+
+/*
+ * Curl_ipv4_resolve_r() - ipv4 threadsafe resolver function.
+ *
+ * This is used for both synchronous and asynchronous resolver builds,
+ * implying that only threadsafe code and function calls may be used.
+ *
+ */
+Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
+                                   int port)
+{
+#if !defined(HAVE_GETADDRINFO_THREADSAFE) && defined(HAVE_GETHOSTBYNAME_R_3)
+  int res;
+#endif
+  Curl_addrinfo *ai = NULL;
+  struct hostent *h = NULL;
+  struct in_addr in;
+  struct hostent *buf = NULL;
+
+  if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+    /* This is a dotted IP address 123.123.123.123-style */
+    return Curl_ip2addr(AF_INET, &in, hostname, port);
+
+#if defined(HAVE_GETADDRINFO_THREADSAFE)
+  else {
+    struct addrinfo hints;
+    char sbuf[12];
+    char *sbufptr = NULL;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = PF_INET;
+    hints.ai_socktype = SOCK_STREAM;
+    if(port) {
+      snprintf(sbuf, sizeof(sbuf), "%d", port);
+      sbufptr = sbuf;
+    }
+
+    (void)Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &ai);
+
+#elif defined(HAVE_GETHOSTBYNAME_R)
+  /*
+   * gethostbyname_r() is the preferred resolve function for many platforms.
+   * Since there are three different versions of it, the following code is
+   * somewhat #ifdef-ridden.
+   */
+  else {
+    int h_errnop;
+
+    buf = calloc(1, CURL_HOSTENT_SIZE);
+    if(!buf)
+      return NULL; /* major failure */
+    /*
+     * The clearing of the buffer is a workaround for a gethostbyname_r bug in
+     * qnx nto and it is also _required_ for some of these functions on some
+     * platforms.
+     */
+
+#if defined(HAVE_GETHOSTBYNAME_R_5)
+    /* Solaris, IRIX and more */
+    h = gethostbyname_r(hostname,
+                        (struct hostent *)buf,
+                        (char *)buf + sizeof(struct hostent),
+                        CURL_HOSTENT_SIZE - sizeof(struct hostent),
+                        &h_errnop);
+
+    /* If the buffer is too small, it returns NULL and sets errno to
+     * ERANGE. The errno is thread safe if this is compiled with
+     * -D_REENTRANT as then the 'errno' variable is a macro defined to get
+     * used properly for threads.
+     */
+
+    if(h) {
+      ;
+    }
+    else
+#elif defined(HAVE_GETHOSTBYNAME_R_6)
+    /* Linux */
+
+    (void)gethostbyname_r(hostname,
+                        (struct hostent *)buf,
+                        (char *)buf + sizeof(struct hostent),
+                        CURL_HOSTENT_SIZE - sizeof(struct hostent),
+                        &h, /* DIFFERENCE */
+                        &h_errnop);
+    /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
+     * sudden this function returns EAGAIN if the given buffer size is too
+     * small. Previous versions are known to return ERANGE for the same
+     * problem.
+     *
+     * This wouldn't be such a big problem if older versions wouldn't
+     * sometimes return EAGAIN on a common failure case. Alas, we can't
+     * assume that EAGAIN *or* ERANGE means ERANGE for any given version of
+     * glibc.
+     *
+     * For now, we do that and thus we may call the function repeatedly and
+     * fail for older glibc versions that return EAGAIN, until we run out of
+     * buffer size (step_size grows beyond CURL_HOSTENT_SIZE).
+     *
+     * If anyone has a better fix, please tell us!
+     *
+     * -------------------------------------------------------------------
+     *
+     * On October 23rd 2003, Dan C dug up more details on the mysteries of
+     * gethostbyname_r() in glibc:
+     *
+     * In glibc 2.2.5 the interface is different (this has also been
+     * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't
+     * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32
+     * (shipped/upgraded by Redhat 7.2) don't show this behavior!
+     *
+     * In this "buggy" version, the return code is -1 on error and 'errno'
+     * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a
+     * thread-safe variable.
+     */
+
+    if(!h) /* failure */
+#elif defined(HAVE_GETHOSTBYNAME_R_3)
+    /* AIX, Digital Unix/Tru64, HPUX 10, more? */
+
+    /* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of
+     * the plain fact that it does not return unique full buffers on each
+     * call, but instead several of the pointers in the hostent structs will
+     * point to the same actual data! This have the unfortunate down-side that
+     * our caching system breaks down horribly. Luckily for us though, AIX 4.3
+     * and more recent versions have a "completely thread-safe"[*] libc where
+     * all the data is stored in thread-specific memory areas making calls to
+     * the plain old gethostbyname() work fine even for multi-threaded
+     * programs.
+     *
+     * This AIX 4.3 or later detection is all made in the configure script.
+     *
+     * Troels Walsted Hansen helped us work this out on March 3rd, 2003.
+     *
+     * [*] = much later we've found out that it isn't at all "completely
+     * thread-safe", but at least the gethostbyname() function is.
+     */
+
+    if(CURL_HOSTENT_SIZE >=
+       (sizeof(struct hostent)+sizeof(struct hostent_data))) {
+
+      /* August 22nd, 2000: Albert Chin-A-Young brought an updated version
+       * that should work! September 20: Richard Prescott worked on the buffer
+       * size dilemma.
+       */
+
+      res = gethostbyname_r(hostname,
+                            (struct hostent *)buf,
+                            (struct hostent_data *)((char *)buf +
+                                                    sizeof(struct hostent)));
+      h_errnop = SOCKERRNO; /* we don't deal with this, but set it anyway */
+    }
+    else
+      res = -1; /* failure, too smallish buffer size */
+
+    if(!res) { /* success */
+
+      h = buf; /* result expected in h */
+
+      /* This is the worst kind of the different gethostbyname_r() interfaces.
+       * Since we don't know how big buffer this particular lookup required,
+       * we can't realloc down the huge alloc without doing closer analysis of
+       * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every
+       * name lookup. Fixing this would require an extra malloc() and then
+       * calling Curl_addrinfo_copy() that subsequent realloc()s down the new
+       * memory area to the actually used amount.
+       */
+    }
+    else
+#endif /* HAVE_...BYNAME_R_5 || HAVE_...BYNAME_R_6 || HAVE_...BYNAME_R_3 */
+    {
+      h = NULL; /* set return code to NULL */
+      free(buf);
+    }
+#else /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
+    /*
+     * Here is code for platforms that don't have a thread safe
+     * getaddrinfo() nor gethostbyname_r() function or for which
+     * gethostbyname() is the preferred one.
+     */
+  else {
+    h = gethostbyname((void*)hostname);
+#endif /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
+  }
+
+  if(h) {
+    ai = Curl_he2ai(h, port);
+
+    if(buf) /* used a *_r() function */
+      free(buf);
+  }
+
+  return ai;
+}
+#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/hostip6.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/hostip6.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/hostip6.c	(revision 164)
@@ -0,0 +1,221 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "inet_pton.h"
+#include "connect.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/***********************************************************************
+ * Only for IPv6-enabled builds
+ **********************************************************************/
+#ifdef CURLRES_IPV6
+
+
+#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
+/* These are strictly for memory tracing and are using the same style as the
+ * family otherwise present in memdebug.c. I put these ones here since they
+ * require a bunch of structs I didn't want to include in memdebug.c
+ */
+
+/*
+ * For CURLRES_ARS, this should be written using ares_gethostbyaddr()
+ * (ignoring the fact c-ares doesn't return 'serv').
+ */
+
+int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
+                       GETNAMEINFO_TYPE_ARG2 salen,
+                       char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
+                       char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
+                       GETNAMEINFO_TYPE_ARG7 flags,
+                       int line, const char *source)
+{
+  int res = (getnameinfo)(sa, salen,
+                          host, hostlen,
+                          serv, servlen,
+                          flags);
+  if(0 == res)
+    /* success */
+    curl_memlog("GETNAME %s:%d getnameinfo()\n",
+                source, line);
+  else
+    curl_memlog("GETNAME %s:%d getnameinfo() failed = %d\n",
+                source, line, res);
+  return res;
+}
+#endif /* defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO) */
+
+/*
+ * Curl_ipv6works() returns TRUE if IPv6 seems to work.
+ */
+bool Curl_ipv6works(void)
+{
+  /* the nature of most system is that IPv6 status doesn't come and go
+     during a program's lifetime so we only probe the first time and then we
+     have the info kept for fast re-use */
+  static int ipv6_works = -1;
+  if(-1 == ipv6_works) {
+    /* probe to see if we have a working IPv6 stack */
+    curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
+    if(s == CURL_SOCKET_BAD)
+      /* an IPv6 address was requested but we can't get/use one */
+      ipv6_works = 0;
+    else {
+      ipv6_works = 1;
+      Curl_closesocket(NULL, s);
+    }
+  }
+  return (ipv6_works>0)?TRUE:FALSE;
+}
+
+/*
+ * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
+ * been set and returns TRUE if they are OK.
+ */
+bool Curl_ipvalid(struct connectdata *conn)
+{
+  if(conn->ip_version == CURL_IPRESOLVE_V6)
+    return Curl_ipv6works();
+  return TRUE;
+}
+
+#if defined(CURLRES_SYNCH)
+
+#ifdef DEBUG_ADDRINFO
+static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
+{
+  printf("dump_addrinfo:\n");
+  for(; ai; ai = ai->ai_next) {
+    char  buf[INET6_ADDRSTRLEN];
+
+    printf("    fam %2d, CNAME %s, ",
+           ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
+    if(Curl_printable_address(ai, buf, sizeof(buf)))
+      printf("%s\n", buf);
+    else
+      printf("failed; %s\n", Curl_strerror(conn, SOCKERRNO));
+  }
+}
+#else
+#define dump_addrinfo(x,y) Curl_nop_stmt
+#endif
+
+/*
+ * Curl_getaddrinfo() when built IPv6-enabled (non-threading and
+ * non-ares version).
+ *
+ * Returns name information about the given hostname and port number. If
+ * successful, the 'addrinfo' is returned and the forth argument will point to
+ * memory we need to free after use. That memory *MUST* be freed with
+ * Curl_freeaddrinfo(), nothing else.
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                const char *hostname,
+                                int port,
+                                int *waitp)
+{
+  struct addrinfo hints;
+  Curl_addrinfo *res;
+  int error;
+  char sbuf[12];
+  char *sbufptr = NULL;
+  char addrbuf[128];
+  int pf;
+  struct SessionHandle *data = conn->data;
+
+  *waitp = 0; /* synchronous response only */
+
+  /*
+   * Check if a limited name resolve has been requested.
+   */
+  switch(conn->ip_version) {
+  case CURL_IPRESOLVE_V4:
+    pf = PF_INET;
+    break;
+  case CURL_IPRESOLVE_V6:
+    pf = PF_INET6;
+    break;
+  default:
+    pf = PF_UNSPEC;
+    break;
+  }
+
+  if((pf != PF_INET) && !Curl_ipv6works())
+    /* The stack seems to be a non-IPv6 one */
+    pf = PF_INET;
+
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = pf;
+  hints.ai_socktype = conn->socktype;
+
+  if((1 == Curl_inet_pton(AF_INET, hostname, addrbuf)) ||
+     (1 == Curl_inet_pton(AF_INET6, hostname, addrbuf))) {
+    /* the given address is numerical only, prevent a reverse lookup */
+    hints.ai_flags = AI_NUMERICHOST;
+  }
+
+  if(port) {
+    snprintf(sbuf, sizeof(sbuf), "%d", port);
+    sbufptr=sbuf;
+  }
+  error = Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &res);
+  if(error) {
+    infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);
+    return NULL;
+  }
+
+  dump_addrinfo(conn, res);
+
+  return res;
+}
+#endif /* CURLRES_SYNCH */
+#endif /* CURLRES_IPV6 */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/hostsyn.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/hostsyn.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/hostsyn.c	(revision 164)
@@ -0,0 +1,107 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/***********************************************************************
+ * Only for builds using synchronous name resolves
+ **********************************************************************/
+#ifdef CURLRES_SYNCH
+
+/*
+ * Function provided by the resolver backend to set DNS servers to use.
+ */
+CURLcode Curl_set_dns_servers(struct SessionHandle *data,
+                              char *servers)
+{
+  (void)data;
+  (void)servers;
+  return CURLE_NOT_BUILT_IN;
+
+}
+
+/*
+ * Function provided by the resolver backend to set
+ * outgoing interface to use for DNS requests
+ */
+CURLcode Curl_set_dns_interface(struct SessionHandle *data,
+                                const char *interf)
+{
+  (void)data;
+  (void)interf;
+  return CURLE_NOT_BUILT_IN;
+}
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv4 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
+                                const char *local_ip4)
+{
+  (void)data;
+  (void)local_ip4;
+  return CURLE_NOT_BUILT_IN;
+}
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv6 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
+                                const char *local_ip6)
+{
+  (void)data;
+  (void)local_ip6;
+  return CURLE_NOT_BUILT_IN;
+}
+
+#endif /* truly sync */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/http.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/http.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/http.c	(revision 164)
@@ -0,0 +1,3759 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_HTTP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "formdata.h"
+#include "progress.h"
+#include "curl_base64.h"
+#include "cookie.h"
+#include "strequal.h"
+#include "vtls/vtls.h"
+#include "http_digest.h"
+#include "curl_ntlm.h"
+#include "curl_ntlm_wb.h"
+#include "http_negotiate.h"
+#include "url.h"
+#include "share.h"
+#include "hostip.h"
+#include "http.h"
+#include "select.h"
+#include "parsedate.h" /* for the week day and month names */
+#include "strtoofft.h"
+#include "multiif.h"
+#include "rawstr.h"
+#include "content_encoding.h"
+#include "http_proxy.h"
+#include "warnless.h"
+#include "non-ascii.h"
+#include "conncache.h"
+#include "pipeline.h"
+#include "http2.h"
+#include "connect.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Forward declarations.
+ */
+
+static int http_getsock_do(struct connectdata *conn,
+                           curl_socket_t *socks,
+                           int numsocks);
+static int http_should_fail(struct connectdata *conn);
+
+#ifdef USE_SSL
+static CURLcode https_connecting(struct connectdata *conn, bool *done);
+static int https_getsock(struct connectdata *conn,
+                         curl_socket_t *socks,
+                         int numsocks);
+#else
+#define https_connecting(x,y) CURLE_COULDNT_CONNECT
+#endif
+
+/*
+ * HTTP handler interface.
+ */
+const struct Curl_handler Curl_handler_http = {
+  "HTTP",                               /* scheme */
+  Curl_http_setup_conn,                 /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  Curl_http_connect,                    /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  http_getsock_do,                      /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_HTTP,                            /* defport */
+  CURLPROTO_HTTP,                       /* protocol */
+  PROTOPT_CREDSPERREQUEST               /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * HTTPS handler interface.
+ */
+const struct Curl_handler Curl_handler_https = {
+  "HTTPS",                              /* scheme */
+  Curl_http_setup_conn,                 /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  Curl_http_connect,                    /* connect_it */
+  https_connecting,                     /* connecting */
+  ZERO_NULL,                            /* doing */
+  https_getsock,                        /* proto_getsock */
+  http_getsock_do,                      /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_HTTPS,                           /* defport */
+  CURLPROTO_HTTPS,                      /* protocol */
+  PROTOPT_SSL | PROTOPT_CREDSPERREQUEST /* flags */
+};
+#endif
+
+
+CURLcode Curl_http_setup_conn(struct connectdata *conn)
+{
+  /* allocate the HTTP-specific struct for the SessionHandle, only to survive
+     during this request */
+  struct HTTP *http;
+  DEBUGASSERT(conn->data->req.protop == NULL);
+
+  http = calloc(1, sizeof(struct HTTP));
+  if(!http)
+    return CURLE_OUT_OF_MEMORY;
+
+  conn->data->req.protop = http;
+
+  Curl_http2_setup_conn(conn);
+  Curl_http2_setup_req(conn->data);
+
+  return CURLE_OK;
+}
+
+/*
+ * checkheaders() checks the linked list of custom HTTP headers for a
+ * particular header (prefix).
+ *
+ * Returns a pointer to the first matching header or NULL if none matched.
+ */
+char *Curl_checkheaders(const struct connectdata *conn,
+                        const char *thisheader)
+{
+  struct curl_slist *head;
+  size_t thislen = strlen(thisheader);
+  struct SessionHandle *data = conn->data;
+
+  for(head = data->set.headers;head; head=head->next) {
+    if(Curl_raw_nequal(head->data, thisheader, thislen))
+      return head->data;
+  }
+  return NULL;
+}
+
+/*
+ * checkProxyHeaders() checks the linked list of custom proxy headers
+ * if proxy headers are not available, then it will lookup into http header
+ * link list
+ *
+ * It takes a connectdata struct as input instead of the SessionHandle simply
+ * to know if this is a proxy request or not, as it then might check a
+ * different header list.
+ *
+ */
+char *Curl_checkProxyheaders(const struct connectdata *conn,
+                             const char *thisheader)
+{
+  struct curl_slist *head;
+  size_t thislen = strlen(thisheader);
+  struct SessionHandle *data = conn->data;
+
+  for(head = (conn->bits.proxy && data->set.sep_headers)?
+        data->set.proxyheaders:data->set.headers;
+      head; head=head->next) {
+    if(Curl_raw_nequal(head->data, thisheader, thislen))
+      return head->data;
+  }
+  return NULL;
+}
+
+/*
+ * Strip off leading and trailing whitespace from the value in the
+ * given HTTP header line and return a strdupped copy. Returns NULL in
+ * case of allocation failure. Returns an empty string if the header value
+ * consists entirely of whitespace.
+ */
+char *Curl_copy_header_value(const char *header)
+{
+  const char *start;
+  const char *end;
+  char *value;
+  size_t len;
+
+  DEBUGASSERT(header);
+
+  /* Find the end of the header name */
+  while(*header && (*header != ':'))
+    ++header;
+
+  if(*header)
+    /* Skip over colon */
+    ++header;
+
+  /* Find the first non-space letter */
+  start = header;
+  while(*start && ISSPACE(*start))
+    start++;
+
+  /* data is in the host encoding so
+     use '\r' and '\n' instead of 0x0d and 0x0a */
+  end = strchr(start, '\r');
+  if(!end)
+    end = strchr(start, '\n');
+  if(!end)
+    end = strchr(start, '\0');
+  if(!end)
+    return NULL;
+
+  /* skip all trailing space letters */
+  while((end > start) && ISSPACE(*end))
+    end--;
+
+  /* get length of the type */
+  len = end - start + 1;
+
+  value = malloc(len + 1);
+  if(!value)
+    return NULL;
+
+  memcpy(value, start, len);
+  value[len] = 0; /* zero terminate */
+
+  return value;
+}
+
+/*
+ * http_output_basic() sets up an Authorization: header (or the proxy version)
+ * for HTTP Basic authentication.
+ *
+ * Returns CURLcode.
+ */
+static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
+{
+  size_t size = 0;
+  char *authorization = NULL;
+  struct SessionHandle *data = conn->data;
+  char **userp;
+  const char *user;
+  const char *pwd;
+  CURLcode result;
+
+  if(proxy) {
+    userp = &conn->allocptr.proxyuserpwd;
+    user = conn->proxyuser;
+    pwd = conn->proxypasswd;
+  }
+  else {
+    userp = &conn->allocptr.userpwd;
+    user = conn->user;
+    pwd = conn->passwd;
+  }
+
+  snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
+
+  result = Curl_base64_encode(data,
+                              data->state.buffer, strlen(data->state.buffer),
+                              &authorization, &size);
+  if(result)
+    return result;
+
+  if(!authorization)
+    return CURLE_REMOTE_ACCESS_DENIED;
+
+  free(*userp);
+  *userp = aprintf("%sAuthorization: Basic %s\r\n",
+                   proxy?"Proxy-":"",
+                   authorization);
+  free(authorization);
+  if(!*userp)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+/* pickoneauth() selects the most favourable authentication method from the
+ * ones available and the ones we want.
+ *
+ * return TRUE if one was picked
+ */
+static bool pickoneauth(struct auth *pick)
+{
+  bool picked;
+  /* only deal with authentication we want */
+  unsigned long avail = pick->avail & pick->want;
+  picked = TRUE;
+
+  /* The order of these checks is highly relevant, as this will be the order
+     of preference in case of the existence of multiple accepted types. */
+  if(avail & CURLAUTH_NEGOTIATE)
+    pick->picked = CURLAUTH_NEGOTIATE;
+  else if(avail & CURLAUTH_DIGEST)
+    pick->picked = CURLAUTH_DIGEST;
+  else if(avail & CURLAUTH_NTLM)
+    pick->picked = CURLAUTH_NTLM;
+  else if(avail & CURLAUTH_NTLM_WB)
+    pick->picked = CURLAUTH_NTLM_WB;
+  else if(avail & CURLAUTH_BASIC)
+    pick->picked = CURLAUTH_BASIC;
+  else {
+    pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
+    picked = FALSE;
+  }
+  pick->avail = CURLAUTH_NONE; /* clear it here */
+
+  return picked;
+}
+
+/*
+ * Curl_http_perhapsrewind()
+ *
+ * If we are doing POST or PUT {
+ *   If we have more data to send {
+ *     If we are doing NTLM {
+ *       Keep sending since we must not disconnect
+ *     }
+ *     else {
+ *       If there is more than just a little data left to send, close
+ *       the current connection by force.
+ *     }
+ *   }
+ *   If we have sent any data {
+ *     If we don't have track of all the data {
+ *       call app to tell it to rewind
+ *     }
+ *     else {
+ *       rewind internally so that the operation can restart fine
+ *     }
+ *   }
+ * }
+ */
+static CURLcode http_perhapsrewind(struct connectdata *conn)
+{
+  struct SessionHandle *data = conn->data;
+  struct HTTP *http = data->req.protop;
+  curl_off_t bytessent;
+  curl_off_t expectsend = -1; /* default is unknown */
+
+  if(!http)
+    /* If this is still NULL, we have not reach very far and we can safely
+       skip this rewinding stuff */
+    return CURLE_OK;
+
+  switch(data->set.httpreq) {
+  case HTTPREQ_GET:
+  case HTTPREQ_HEAD:
+    return CURLE_OK;
+  default:
+    break;
+  }
+
+  bytessent = http->writebytecount;
+
+  if(conn->bits.authneg) {
+    /* This is a state where we are known to be negotiating and we don't send
+       any data then. */
+    expectsend = 0;
+  }
+  else if(!conn->bits.protoconnstart) {
+    /* HTTP CONNECT in progress: there is no body */
+    expectsend = 0;
+  }
+  else {
+    /* figure out how much data we are expected to send */
+    switch(data->set.httpreq) {
+    case HTTPREQ_POST:
+      if(data->state.infilesize != -1)
+        expectsend = data->state.infilesize;
+      else if(data->set.postfields)
+        expectsend = (curl_off_t)strlen(data->set.postfields);
+      break;
+    case HTTPREQ_PUT:
+      if(data->state.infilesize != -1)
+        expectsend = data->state.infilesize;
+      break;
+    case HTTPREQ_POST_FORM:
+      expectsend = http->postsize;
+      break;
+    default:
+      break;
+    }
+  }
+
+  conn->bits.rewindaftersend = FALSE; /* default */
+
+  if((expectsend == -1) || (expectsend > bytessent)) {
+#if defined(USE_NTLM)
+    /* There is still data left to send */
+    if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
+       (data->state.authhost.picked == CURLAUTH_NTLM) ||
+       (data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
+       (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
+      if(((expectsend - bytessent) < 2000) ||
+         (conn->ntlm.state != NTLMSTATE_NONE) ||
+         (conn->proxyntlm.state != NTLMSTATE_NONE)) {
+        /* The NTLM-negotiation has started *OR* there is just a little (<2K)
+           data left to send, keep on sending. */
+
+        /* rewind data when completely done sending! */
+        if(!conn->bits.authneg) {
+          conn->bits.rewindaftersend = TRUE;
+          infof(data, "Rewind stream after send\n");
+        }
+
+        return CURLE_OK;
+      }
+
+      if(conn->bits.close)
+        /* this is already marked to get closed */
+        return CURLE_OK;
+
+      infof(data, "NTLM send, close instead of sending %"
+            CURL_FORMAT_CURL_OFF_T " bytes\n",
+            (curl_off_t)(expectsend - bytessent));
+    }
+#endif
+
+    /* This is not NTLM or many bytes left to send: close */
+    connclose(conn, "Mid-auth HTTP and much data left to send");
+    data->req.size = 0; /* don't download any more than 0 bytes */
+
+    /* There still is data left to send, but this connection is marked for
+       closure so we can safely do the rewind right now */
+  }
+
+  if(bytessent)
+    /* we rewind now at once since if we already sent something */
+    return Curl_readrewind(conn);
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_http_auth_act() gets called when all HTTP headers have been received
+ * and it checks what authentication methods that are available and decides
+ * which one (if any) to use. It will set 'newurl' if an auth method was
+ * picked.
+ */
+
+CURLcode Curl_http_auth_act(struct connectdata *conn)
+{
+  struct SessionHandle *data = conn->data;
+  bool pickhost = FALSE;
+  bool pickproxy = FALSE;
+  CURLcode result = CURLE_OK;
+
+  if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
+    /* this is a transient response code, ignore */
+    return CURLE_OK;
+
+  if(data->state.authproblem)
+    return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
+
+  if(conn->bits.user_passwd &&
+     ((data->req.httpcode == 401) ||
+      (conn->bits.authneg && data->req.httpcode < 300))) {
+    pickhost = pickoneauth(&data->state.authhost);
+    if(!pickhost)
+      data->state.authproblem = TRUE;
+  }
+  if(conn->bits.proxy_user_passwd &&
+     ((data->req.httpcode == 407) ||
+      (conn->bits.authneg && data->req.httpcode < 300))) {
+    pickproxy = pickoneauth(&data->state.authproxy);
+    if(!pickproxy)
+      data->state.authproblem = TRUE;
+  }
+
+  if(pickhost || pickproxy) {
+    /* In case this is GSS auth, the newurl field is already allocated so
+       we must make sure to free it before allocating a new one. As figured
+       out in bug #2284386 */
+    Curl_safefree(data->req.newurl);
+    data->req.newurl = strdup(data->change.url); /* clone URL */
+    if(!data->req.newurl)
+      return CURLE_OUT_OF_MEMORY;
+
+    if((data->set.httpreq != HTTPREQ_GET) &&
+       (data->set.httpreq != HTTPREQ_HEAD) &&
+       !conn->bits.rewindaftersend) {
+      result = http_perhapsrewind(conn);
+      if(result)
+        return result;
+    }
+  }
+
+  else if((data->req.httpcode < 300) &&
+          (!data->state.authhost.done) &&
+          conn->bits.authneg) {
+    /* no (known) authentication available,
+       authentication is not "done" yet and
+       no authentication seems to be required and
+       we didn't try HEAD or GET */
+    if((data->set.httpreq != HTTPREQ_GET) &&
+       (data->set.httpreq != HTTPREQ_HEAD)) {
+      data->req.newurl = strdup(data->change.url); /* clone URL */
+      if(!data->req.newurl)
+        return CURLE_OUT_OF_MEMORY;
+      data->state.authhost.done = TRUE;
+    }
+  }
+  if(http_should_fail(conn)) {
+    failf (data, "The requested URL returned error: %d",
+           data->req.httpcode);
+    result = CURLE_HTTP_RETURNED_ERROR;
+  }
+
+  return result;
+}
+
+
+/*
+ * Output the correct authentication header depending on the auth type
+ * and whether or not it is to a proxy.
+ */
+static CURLcode
+output_auth_headers(struct connectdata *conn,
+                    struct auth *authstatus,
+                    const char *request,
+                    const char *path,
+                    bool proxy)
+{
+  const char *auth = NULL;
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+#ifdef USE_SPNEGO
+  struct negotiatedata *negdata = proxy?
+    &data->state.proxyneg:&data->state.negotiate;
+#endif
+
+#ifdef CURL_DISABLE_CRYPTO_AUTH
+  (void)request;
+  (void)path;
+#endif
+
+#ifdef USE_SPNEGO
+  negdata->state = GSS_AUTHNONE;
+  if((authstatus->picked == CURLAUTH_NEGOTIATE) &&
+     negdata->context && !GSS_ERROR(negdata->status)) {
+    auth="Negotiate";
+    result = Curl_output_negotiate(conn, proxy);
+    if(result)
+      return result;
+    authstatus->done = TRUE;
+    negdata->state = GSS_AUTHSENT;
+  }
+  else
+#endif
+#ifdef USE_NTLM
+  if(authstatus->picked == CURLAUTH_NTLM) {
+    auth="NTLM";
+    result = Curl_output_ntlm(conn, proxy);
+    if(result)
+      return result;
+  }
+  else
+#endif
+#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
+  if(authstatus->picked == CURLAUTH_NTLM_WB) {
+    auth="NTLM_WB";
+    result = Curl_output_ntlm_wb(conn, proxy);
+    if(result)
+      return result;
+  }
+  else
+#endif
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+  if(authstatus->picked == CURLAUTH_DIGEST) {
+    auth="Digest";
+    result = Curl_output_digest(conn,
+                                proxy,
+                                (const unsigned char *)request,
+                                (const unsigned char *)path);
+    if(result)
+      return result;
+  }
+  else
+#endif
+  if(authstatus->picked == CURLAUTH_BASIC) {
+    /* Basic */
+    if((proxy && conn->bits.proxy_user_passwd &&
+        !Curl_checkProxyheaders(conn, "Proxy-authorization:")) ||
+       (!proxy && conn->bits.user_passwd &&
+        !Curl_checkheaders(conn, "Authorization:"))) {
+      auth="Basic";
+      result = http_output_basic(conn, proxy);
+      if(result)
+        return result;
+    }
+    /* NOTE: this function should set 'done' TRUE, as the other auth
+       functions work that way */
+    authstatus->done = TRUE;
+  }
+
+  if(auth) {
+    infof(data, "%s auth using %s with user '%s'\n",
+          proxy?"Proxy":"Server", auth,
+          proxy?(conn->proxyuser?conn->proxyuser:""):
+                (conn->user?conn->user:""));
+    authstatus->multi = (!authstatus->done) ? TRUE : FALSE;
+  }
+  else
+    authstatus->multi = FALSE;
+
+  return CURLE_OK;
+}
+
+/**
+ * Curl_http_output_auth() setups the authentication headers for the
+ * host/proxy and the correct authentication
+ * method. conn->data->state.authdone is set to TRUE when authentication is
+ * done.
+ *
+ * @param conn all information about the current connection
+ * @param request pointer to the request keyword
+ * @param path pointer to the requested path
+ * @param proxytunnel boolean if this is the request setting up a "proxy
+ * tunnel"
+ *
+ * @returns CURLcode
+ */
+CURLcode
+Curl_http_output_auth(struct connectdata *conn,
+                      const char *request,
+                      const char *path,
+                      bool proxytunnel) /* TRUE if this is the request setting
+                                           up the proxy tunnel */
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct auth *authhost;
+  struct auth *authproxy;
+
+  DEBUGASSERT(data);
+
+  authhost = &data->state.authhost;
+  authproxy = &data->state.authproxy;
+
+  if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
+     conn->bits.user_passwd)
+    /* continue please */;
+  else {
+    authhost->done = TRUE;
+    authproxy->done = TRUE;
+    return CURLE_OK; /* no authentication with no user or password */
+  }
+
+  if(authhost->want && !authhost->picked)
+    /* The app has selected one or more methods, but none has been picked
+       so far by a server round-trip. Then we set the picked one to the
+       want one, and if this is one single bit it'll be used instantly. */
+    authhost->picked = authhost->want;
+
+  if(authproxy->want && !authproxy->picked)
+    /* The app has selected one or more methods, but none has been picked so
+       far by a proxy round-trip. Then we set the picked one to the want one,
+       and if this is one single bit it'll be used instantly. */
+    authproxy->picked = authproxy->want;
+
+#ifndef CURL_DISABLE_PROXY
+  /* Send proxy authentication header if needed */
+  if(conn->bits.httpproxy &&
+      (conn->bits.tunnel_proxy == proxytunnel)) {
+    result = output_auth_headers(conn, authproxy, request, path, TRUE);
+    if(result)
+      return result;
+  }
+  else
+#else
+  (void)proxytunnel;
+#endif /* CURL_DISABLE_PROXY */
+    /* we have no proxy so let's pretend we're done authenticating
+       with it */
+    authproxy->done = TRUE;
+
+  /* To prevent the user+password to get sent to other than the original
+     host due to a location-follow, we do some weirdo checks here */
+  if(!data->state.this_is_a_follow ||
+     conn->bits.netrc ||
+     !data->state.first_host ||
+     data->set.http_disable_hostname_check_before_authentication ||
+     Curl_raw_equal(data->state.first_host, conn->host.name)) {
+    result = output_auth_headers(conn, authhost, request, path, FALSE);
+  }
+  else
+    authhost->done = TRUE;
+
+  return result;
+}
+
+
+/*
+ * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
+ * headers. They are dealt with both in the transfer.c main loop and in the
+ * proxy CONNECT loop.
+ */
+
+CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
+                              const char *auth) /* the first non-space */
+{
+  /*
+   * This resource requires authentication
+   */
+  struct SessionHandle *data = conn->data;
+
+#ifdef USE_SPNEGO
+  struct negotiatedata *negdata = proxy?
+    &data->state.proxyneg:&data->state.negotiate;
+#endif
+  unsigned long *availp;
+  struct auth *authp;
+
+  if(proxy) {
+    availp = &data->info.proxyauthavail;
+    authp = &data->state.authproxy;
+  }
+  else {
+    availp = &data->info.httpauthavail;
+    authp = &data->state.authhost;
+  }
+
+  /*
+   * Here we check if we want the specific single authentication (using ==) and
+   * if we do, we initiate usage of it.
+   *
+   * If the provided authentication is wanted as one out of several accepted
+   * types (using &), we OR this authentication type to the authavail
+   * variable.
+   *
+   * Note:
+   *
+   * ->picked is first set to the 'want' value (one or more bits) before the
+   * request is sent, and then it is again set _after_ all response 401/407
+   * headers have been received but then only to a single preferred method
+   * (bit).
+   *
+   */
+
+  while(*auth) {
+#ifdef USE_SPNEGO
+    if(checkprefix("Negotiate", auth)) {
+      *availp |= CURLAUTH_NEGOTIATE;
+      authp->avail |= CURLAUTH_NEGOTIATE;
+
+      if(authp->picked == CURLAUTH_NEGOTIATE) {
+        if(negdata->state == GSS_AUTHSENT || negdata->state == GSS_AUTHNONE) {
+          CURLcode result = Curl_input_negotiate(conn, proxy, auth);
+          if(!result) {
+            DEBUGASSERT(!data->req.newurl);
+            data->req.newurl = strdup(data->change.url);
+            if(!data->req.newurl)
+              return CURLE_OUT_OF_MEMORY;
+            data->state.authproblem = FALSE;
+            /* we received a GSS auth token and we dealt with it fine */
+            negdata->state = GSS_AUTHRECV;
+          }
+          else
+            data->state.authproblem = TRUE;
+        }
+      }
+    }
+    else
+#endif
+#ifdef USE_NTLM
+      /* NTLM support requires the SSL crypto libs */
+      if(checkprefix("NTLM", auth)) {
+        *availp |= CURLAUTH_NTLM;
+        authp->avail |= CURLAUTH_NTLM;
+        if(authp->picked == CURLAUTH_NTLM ||
+           authp->picked == CURLAUTH_NTLM_WB) {
+          /* NTLM authentication is picked and activated */
+          CURLcode result = Curl_input_ntlm(conn, proxy, auth);
+          if(!result) {
+            data->state.authproblem = FALSE;
+#ifdef NTLM_WB_ENABLED
+            if(authp->picked == CURLAUTH_NTLM_WB) {
+              *availp &= ~CURLAUTH_NTLM;
+              authp->avail &= ~CURLAUTH_NTLM;
+              *availp |= CURLAUTH_NTLM_WB;
+              authp->avail |= CURLAUTH_NTLM_WB;
+
+              /* Get the challenge-message which will be passed to
+               * ntlm_auth for generating the type 3 message later */
+              while(*auth && ISSPACE(*auth))
+                auth++;
+              if(checkprefix("NTLM", auth)) {
+                auth += strlen("NTLM");
+                while(*auth && ISSPACE(*auth))
+                  auth++;
+                if(*auth)
+                  if((conn->challenge_header = strdup(auth)) == NULL)
+                    return CURLE_OUT_OF_MEMORY;
+              }
+            }
+#endif
+          }
+          else {
+            infof(data, "Authentication problem. Ignoring this.\n");
+            data->state.authproblem = TRUE;
+          }
+        }
+      }
+      else
+#endif
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+        if(checkprefix("Digest", auth)) {
+          if((authp->avail & CURLAUTH_DIGEST) != 0) {
+            infof(data, "Ignoring duplicate digest auth header.\n");
+          }
+          else {
+            CURLcode result;
+            *availp |= CURLAUTH_DIGEST;
+            authp->avail |= CURLAUTH_DIGEST;
+
+            /* We call this function on input Digest headers even if Digest
+             * authentication isn't activated yet, as we need to store the
+             * incoming data from this header in case we are gonna use
+             * Digest. */
+            result = Curl_input_digest(conn, proxy, auth);
+            if(result) {
+              infof(data, "Authentication problem. Ignoring this.\n");
+              data->state.authproblem = TRUE;
+            }
+          }
+        }
+        else
+#endif
+          if(checkprefix("Basic", auth)) {
+            *availp |= CURLAUTH_BASIC;
+            authp->avail |= CURLAUTH_BASIC;
+            if(authp->picked == CURLAUTH_BASIC) {
+              /* We asked for Basic authentication but got a 40X back
+                 anyway, which basically means our name+password isn't
+                 valid. */
+              authp->avail = CURLAUTH_NONE;
+              infof(data, "Authentication problem. Ignoring this.\n");
+              data->state.authproblem = TRUE;
+            }
+          }
+
+    /* there may be multiple methods on one line, so keep reading */
+    while(*auth && *auth != ',') /* read up to the next comma */
+      auth++;
+    if(*auth == ',') /* if we're on a comma, skip it */
+      auth++;
+    while(*auth && ISSPACE(*auth))
+      auth++;
+  }
+  return CURLE_OK;
+}
+
+/**
+ * http_should_fail() determines whether an HTTP response has gotten us
+ * into an error state or not.
+ *
+ * @param conn all information about the current connection
+ *
+ * @retval 0 communications should continue
+ *
+ * @retval 1 communications should not continue
+ */
+static int http_should_fail(struct connectdata *conn)
+{
+  struct SessionHandle *data;
+  int httpcode;
+
+  DEBUGASSERT(conn);
+  data = conn->data;
+  DEBUGASSERT(data);
+
+  httpcode = data->req.httpcode;
+
+  /*
+  ** If we haven't been asked to fail on error,
+  ** don't fail.
+  */
+  if(!data->set.http_fail_on_error)
+    return 0;
+
+  /*
+  ** Any code < 400 is never terminal.
+  */
+  if(httpcode < 400)
+    return 0;
+
+  /*
+  ** Any code >= 400 that's not 401 or 407 is always
+  ** a terminal error
+  */
+  if((httpcode != 401) &&
+      (httpcode != 407))
+    return 1;
+
+  /*
+  ** All we have left to deal with is 401 and 407
+  */
+  DEBUGASSERT((httpcode == 401) || (httpcode == 407));
+
+  /*
+  ** Examine the current authentication state to see if this
+  ** is an error.  The idea is for this function to get
+  ** called after processing all the headers in a response
+  ** message.  So, if we've been to asked to authenticate a
+  ** particular stage, and we've done it, we're OK.  But, if
+  ** we're already completely authenticated, it's not OK to
+  ** get another 401 or 407.
+  **
+  ** It is possible for authentication to go stale such that
+  ** the client needs to reauthenticate.  Once that info is
+  ** available, use it here.
+  */
+
+  /*
+  ** Either we're not authenticating, or we're supposed to
+  ** be authenticating something else.  This is an error.
+  */
+  if((httpcode == 401) && !conn->bits.user_passwd)
+    return TRUE;
+  if((httpcode == 407) && !conn->bits.proxy_user_passwd)
+    return TRUE;
+
+  return data->state.authproblem;
+}
+
+/*
+ * readmoredata() is a "fread() emulation" to provide POST and/or request
+ * data. It is used when a huge POST is to be made and the entire chunk wasn't
+ * sent in the first send(). This function will then be called from the
+ * transfer.c loop when more data is to be sent to the peer.
+ *
+ * Returns the amount of bytes it filled the buffer with.
+ */
+static size_t readmoredata(char *buffer,
+                           size_t size,
+                           size_t nitems,
+                           void *userp)
+{
+  struct connectdata *conn = (struct connectdata *)userp;
+  struct HTTP *http = conn->data->req.protop;
+  size_t fullsize = size * nitems;
+
+  if(0 == http->postsize)
+    /* nothing to return */
+    return 0;
+
+  /* make sure that a HTTP request is never sent away chunked! */
+  conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
+
+  if(http->postsize <= (curl_off_t)fullsize) {
+    memcpy(buffer, http->postdata, (size_t)http->postsize);
+    fullsize = (size_t)http->postsize;
+
+    if(http->backup.postsize) {
+      /* move backup data into focus and continue on that */
+      http->postdata = http->backup.postdata;
+      http->postsize = http->backup.postsize;
+      conn->data->state.fread_func = http->backup.fread_func;
+      conn->data->state.in = http->backup.fread_in;
+
+      http->sending++; /* move one step up */
+
+      http->backup.postsize=0;
+    }
+    else
+      http->postsize = 0;
+
+    return fullsize;
+  }
+
+  memcpy(buffer, http->postdata, fullsize);
+  http->postdata += fullsize;
+  http->postsize -= fullsize;
+
+  return fullsize;
+}
+
+/* ------------------------------------------------------------------------- */
+/* add_buffer functions */
+
+/*
+ * Curl_add_buffer_init() sets up and returns a fine buffer struct
+ */
+Curl_send_buffer *Curl_add_buffer_init(void)
+{
+  return calloc(1, sizeof(Curl_send_buffer));
+}
+
+/*
+ * Curl_add_buffer_free() frees all associated resources.
+ */
+void Curl_add_buffer_free(Curl_send_buffer *buff)
+{
+  if(buff) /* deal with NULL input */
+    free(buff->buffer);
+  free(buff);
+}
+
+/*
+ * Curl_add_buffer_send() sends a header buffer and frees all associated
+ * memory.  Body data may be appended to the header data if desired.
+ *
+ * Returns CURLcode
+ */
+CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
+                              struct connectdata *conn,
+
+                               /* add the number of sent bytes to this
+                                  counter */
+                              long *bytes_written,
+
+                               /* how much of the buffer contains body data */
+                              size_t included_body_bytes,
+                              int socketindex)
+
+{
+  ssize_t amount;
+  CURLcode result;
+  char *ptr;
+  size_t size;
+  struct HTTP *http = conn->data->req.protop;
+  size_t sendsize;
+  curl_socket_t sockfd;
+  size_t headersize;
+
+  DEBUGASSERT(socketindex <= SECONDARYSOCKET);
+
+  sockfd = conn->sock[socketindex];
+
+  /* The looping below is required since we use non-blocking sockets, but due
+     to the circumstances we will just loop and try again and again etc */
+
+  ptr = in->buffer;
+  size = in->size_used;
+
+  headersize = size - included_body_bytes; /* the initial part that isn't body
+                                              is header */
+
+  DEBUGASSERT(size > included_body_bytes);
+
+  result = Curl_convert_to_network(conn->data, ptr, headersize);
+  /* Curl_convert_to_network calls failf if unsuccessful */
+  if(result) {
+    /* conversion failed, free memory and return to the caller */
+    Curl_add_buffer_free(in);
+    return result;
+  }
+
+
+  if(conn->handler->flags & PROTOPT_SSL) {
+    /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
+       when we speak HTTPS, as if only a fraction of it is sent now, this data
+       needs to fit into the normal read-callback buffer later on and that
+       buffer is using this size.
+    */
+
+    sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size;
+
+    /* OpenSSL is very picky and we must send the SAME buffer pointer to the
+       library when we attempt to re-send this buffer. Sending the same data
+       is not enough, we must use the exact same address. For this reason, we
+       must copy the data to the uploadbuffer first, since that is the buffer
+       we will be using if this send is retried later.
+    */
+    memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
+    ptr = conn->data->state.uploadbuffer;
+  }
+  else
+    sendsize = size;
+
+  result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
+
+  if(!result) {
+    /*
+     * Note that we may not send the entire chunk at once, and we have a set
+     * number of data bytes at the end of the big buffer (out of which we may
+     * only send away a part).
+     */
+    /* how much of the header that was sent */
+    size_t headlen = (size_t)amount>headersize?headersize:(size_t)amount;
+    size_t bodylen = amount - headlen;
+
+    if(conn->data->set.verbose) {
+      /* this data _may_ contain binary stuff */
+      Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
+      if(bodylen) {
+        /* there was body data sent beyond the initial header part, pass that
+           on to the debug callback too */
+        Curl_debug(conn->data, CURLINFO_DATA_OUT,
+                   ptr+headlen, bodylen, conn);
+      }
+    }
+    if(bodylen)
+      /* since we sent a piece of the body here, up the byte counter for it
+         accordingly */
+      http->writebytecount += bodylen;
+
+    /* 'amount' can never be a very large value here so typecasting it so a
+       signed 31 bit value should not cause problems even if ssize_t is
+       64bit */
+    *bytes_written += (long)amount;
+
+    if(http) {
+      if((size_t)amount != size) {
+        /* The whole request could not be sent in one system call. We must
+           queue it up and send it later when we get the chance. We must not
+           loop here and wait until it might work again. */
+
+        size -= amount;
+
+        ptr = in->buffer + amount;
+
+        /* backup the currently set pointers */
+        http->backup.fread_func = conn->data->state.fread_func;
+        http->backup.fread_in = conn->data->state.in;
+        http->backup.postdata = http->postdata;
+        http->backup.postsize = http->postsize;
+
+        /* set the new pointers for the request-sending */
+        conn->data->state.fread_func = (curl_read_callback)readmoredata;
+        conn->data->state.in = (void *)conn;
+        http->postdata = ptr;
+        http->postsize = (curl_off_t)size;
+
+        http->send_buffer = in;
+        http->sending = HTTPSEND_REQUEST;
+
+        return CURLE_OK;
+      }
+      http->sending = HTTPSEND_BODY;
+      /* the full buffer was sent, clean up and return */
+    }
+    else {
+      if((size_t)amount != size)
+        /* We have no continue-send mechanism now, fail. This can only happen
+           when this function is used from the CONNECT sending function. We
+           currently (stupidly) assume that the whole request is always sent
+           away in the first single chunk.
+
+           This needs FIXing.
+        */
+        return CURLE_SEND_ERROR;
+      else
+        Curl_pipeline_leave_write(conn);
+    }
+  }
+  Curl_add_buffer_free(in);
+
+  return result;
+}
+
+
+/*
+ * add_bufferf() add the formatted input to the buffer.
+ */
+CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
+{
+  char *s;
+  va_list ap;
+  va_start(ap, fmt);
+  s = vaprintf(fmt, ap); /* this allocs a new string to append */
+  va_end(ap);
+
+  if(s) {
+    CURLcode result = Curl_add_buffer(in, s, strlen(s));
+    free(s);
+    return result;
+  }
+  /* If we failed, we cleanup the whole buffer and return error */
+  free(in->buffer);
+  free(in);
+  return CURLE_OUT_OF_MEMORY;
+}
+
+/*
+ * add_buffer() appends a memory chunk to the existing buffer
+ */
+CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
+{
+  char *new_rb;
+  size_t new_size;
+
+  if(~size < in->size_used) {
+    /* If resulting used size of send buffer would wrap size_t, cleanup
+       the whole buffer and return error. Otherwise the required buffer
+       size will fit into a single allocatable memory chunk */
+    Curl_safefree(in->buffer);
+    free(in);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(!in->buffer ||
+     ((in->size_used + size) > (in->size_max - 1))) {
+
+    /* If current buffer size isn't enough to hold the result, use a
+       buffer size that doubles the required size. If this new size
+       would wrap size_t, then just use the largest possible one */
+
+    if((size > (size_t)-1/2) || (in->size_used > (size_t)-1/2) ||
+       (~(size*2) < (in->size_used*2)))
+      new_size = (size_t)-1;
+    else
+      new_size = (in->size_used+size)*2;
+
+    if(in->buffer)
+      /* we have a buffer, enlarge the existing one */
+      new_rb = realloc(in->buffer, new_size);
+    else
+      /* create a new buffer */
+      new_rb = malloc(new_size);
+
+    if(!new_rb) {
+      /* If we failed, we cleanup the whole buffer and return error */
+      Curl_safefree(in->buffer);
+      free(in);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    in->buffer = new_rb;
+    in->size_max = new_size;
+  }
+  memcpy(&in->buffer[in->size_used], inptr, size);
+
+  in->size_used += size;
+
+  return CURLE_OK;
+}
+
+/* end of the add_buffer functions */
+/* ------------------------------------------------------------------------- */
+
+
+
+/*
+ * Curl_compareheader()
+ *
+ * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
+ * Pass headers WITH the colon.
+ */
+bool
+Curl_compareheader(const char *headerline, /* line to check */
+                   const char *header,  /* header keyword _with_ colon */
+                   const char *content) /* content string to find */
+{
+  /* RFC2616, section 4.2 says: "Each header field consists of a name followed
+   * by a colon (":") and the field value. Field names are case-insensitive.
+   * The field value MAY be preceded by any amount of LWS, though a single SP
+   * is preferred." */
+
+  size_t hlen = strlen(header);
+  size_t clen;
+  size_t len;
+  const char *start;
+  const char *end;
+
+  if(!Curl_raw_nequal(headerline, header, hlen))
+    return FALSE; /* doesn't start with header */
+
+  /* pass the header */
+  start = &headerline[hlen];
+
+  /* pass all white spaces */
+  while(*start && ISSPACE(*start))
+    start++;
+
+  /* find the end of the header line */
+  end = strchr(start, '\r'); /* lines end with CRLF */
+  if(!end) {
+    /* in case there's a non-standard compliant line here */
+    end = strchr(start, '\n');
+
+    if(!end)
+      /* hm, there's no line ending here, use the zero byte! */
+      end = strchr(start, '\0');
+  }
+
+  len = end-start; /* length of the content part of the input line */
+  clen = strlen(content); /* length of the word to find */
+
+  /* find the content string in the rest of the line */
+  for(;len>=clen;len--, start++) {
+    if(Curl_raw_nequal(start, content, clen))
+      return TRUE; /* match! */
+  }
+
+  return FALSE; /* no match */
+}
+
+/*
+ * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
+ * the generic Curl_connect().
+ */
+CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
+{
+  CURLcode result;
+
+  /* We default to persistent connections. We set this already in this connect
+     function to make the re-use checks properly be able to check this bit. */
+  connkeep(conn, "HTTP default");
+
+  /* the CONNECT procedure might not have been completed */
+  result = Curl_proxy_connect(conn);
+  if(result)
+    return result;
+
+  if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
+    /* nothing else to do except wait right now - we're not done here. */
+    return CURLE_OK;
+
+  if(conn->given->flags & PROTOPT_SSL) {
+    /* perform SSL initialization */
+    result = https_connecting(conn, done);
+    if(result)
+      return result;
+  }
+  else
+    *done = TRUE;
+
+  return CURLE_OK;
+}
+
+/* this returns the socket to wait for in the DO and DOING state for the multi
+   interface and then we're always _sending_ a request and thus we wait for
+   the single socket to become writable only */
+static int http_getsock_do(struct connectdata *conn,
+                           curl_socket_t *socks,
+                           int numsocks)
+{
+  /* write mode */
+  (void)numsocks; /* unused, we trust it to be at least 1 */
+  socks[0] = conn->sock[FIRSTSOCKET];
+  return GETSOCK_WRITESOCK(0);
+}
+
+#ifdef USE_SSL
+static CURLcode https_connecting(struct connectdata *conn, bool *done)
+{
+  CURLcode result;
+  DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
+
+  /* perform SSL initialization for this socket */
+  result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
+  if(result)
+    connclose(conn, "Failed HTTPS connection");
+
+  return result;
+}
+#endif
+
+#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
+    defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) || \
+    defined(USE_MBEDTLS)
+/* This function is for OpenSSL, GnuTLS, darwinssl, schannel and polarssl only.
+   It should be made to query the generic SSL layer instead. */
+static int https_getsock(struct connectdata *conn,
+                         curl_socket_t *socks,
+                         int numsocks)
+{
+  if(conn->handler->flags & PROTOPT_SSL) {
+    struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+
+    if(!numsocks)
+      return GETSOCK_BLANK;
+
+    if(connssl->connecting_state == ssl_connect_2_writing) {
+      /* write mode */
+      socks[0] = conn->sock[FIRSTSOCKET];
+      return GETSOCK_WRITESOCK(0);
+    }
+    else if(connssl->connecting_state == ssl_connect_2_reading) {
+      /* read mode */
+      socks[0] = conn->sock[FIRSTSOCKET];
+      return GETSOCK_READSOCK(0);
+    }
+  }
+  return CURLE_OK;
+}
+#else
+#ifdef USE_SSL
+static int https_getsock(struct connectdata *conn,
+                         curl_socket_t *socks,
+                         int numsocks)
+{
+  (void)conn;
+  (void)socks;
+  (void)numsocks;
+  return GETSOCK_BLANK;
+}
+#endif /* USE_SSL */
+#endif /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL */
+
+/*
+ * Curl_http_done() gets called from Curl_done() after a single HTTP request
+ * has been performed.
+ */
+
+CURLcode Curl_http_done(struct connectdata *conn,
+                        CURLcode status, bool premature)
+{
+  struct SessionHandle *data = conn->data;
+  struct HTTP *http = data->req.protop;
+#ifdef USE_NGHTTP2
+  struct http_conn *httpc = &conn->proto.httpc;
+#endif
+
+  Curl_unencode_cleanup(conn);
+
+#ifdef USE_SPNEGO
+  if(data->state.proxyneg.state == GSS_AUTHSENT ||
+     data->state.negotiate.state == GSS_AUTHSENT) {
+    /* add forbid re-use if http-code != 401/407 as a WA only needed for
+     * 401/407 that signal auth failure (empty) otherwise state will be RECV
+     * with current code */
+    if((data->req.httpcode != 401) && (data->req.httpcode != 407))
+      connclose(conn, "Negotiate transfer completed");
+    Curl_cleanup_negotiate(data);
+  }
+#endif
+
+  /* set the proper values (possibly modified on POST) */
+  conn->seek_func = data->set.seek_func; /* restore */
+  conn->seek_client = data->set.seek_client; /* restore */
+
+  if(http == NULL)
+    return CURLE_OK;
+
+  if(http->send_buffer) {
+    Curl_add_buffer_free(http->send_buffer);
+    http->send_buffer = NULL; /* clear the pointer */
+  }
+
+#ifdef USE_NGHTTP2
+  if(http->header_recvbuf) {
+    DEBUGF(infof(data, "free header_recvbuf!!\n"));
+    Curl_add_buffer_free(http->header_recvbuf);
+    http->header_recvbuf = NULL; /* clear the pointer */
+    Curl_add_buffer_free(http->trailer_recvbuf);
+    http->trailer_recvbuf = NULL; /* clear the pointer */
+    if(http->push_headers) {
+      /* if they weren't used and then freed before */
+      for(; http->push_headers_used > 0; --http->push_headers_used) {
+        free(http->push_headers[http->push_headers_used - 1]);
+      }
+      free(http->push_headers);
+      http->push_headers = NULL;
+    }
+  }
+  if(http->stream_id) {
+    nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
+    http->stream_id = 0;
+  }
+#endif
+
+  if(HTTPREQ_POST_FORM == data->set.httpreq) {
+    data->req.bytecount = http->readbytecount + http->writebytecount;
+
+    Curl_formclean(&http->sendit); /* Now free that whole lot */
+    if(http->form.fp) {
+      /* a file being uploaded was left opened, close it! */
+      fclose(http->form.fp);
+      http->form.fp = NULL;
+    }
+  }
+  else if(HTTPREQ_PUT == data->set.httpreq)
+    data->req.bytecount = http->readbytecount + http->writebytecount;
+
+  if(status)
+    return status;
+
+  if(!premature && /* this check is pointless when DONE is called before the
+                      entire operation is complete */
+     !conn->bits.retry &&
+     !data->set.connect_only &&
+     ((http->readbytecount +
+       data->req.headerbytecount -
+       data->req.deductheadercount)) <= 0) {
+    /* If this connection isn't simply closed to be retried, AND nothing was
+       read from the HTTP server (that counts), this can't be right so we
+       return an error here */
+    failf(data, "Empty reply from server");
+    return CURLE_GOT_NOTHING;
+  }
+
+  return CURLE_OK;
+}
+
+
+/*
+ * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons
+ * to avoid it include:
+ *
+ * - if the user specifically requested HTTP 1.0
+ * - if the server we are connected to only supports 1.0
+ * - if any server previously contacted to handle this request only supports
+ * 1.0.
+ */
+static bool use_http_1_1plus(const struct SessionHandle *data,
+                             const struct connectdata *conn)
+{
+  if((data->state.httpversion == 10) || (conn->httpversion == 10))
+    return FALSE;
+  if((data->set.httpversion == CURL_HTTP_VERSION_1_0) &&
+     (conn->httpversion <= 10))
+    return FALSE;
+  return ((data->set.httpversion == CURL_HTTP_VERSION_NONE) ||
+          (data->set.httpversion >= CURL_HTTP_VERSION_1_1));
+}
+
+/* check and possibly add an Expect: header */
+static CURLcode expect100(struct SessionHandle *data,
+                          struct connectdata *conn,
+                          Curl_send_buffer *req_buffer)
+{
+  CURLcode result = CURLE_OK;
+  const char *ptr;
+  data->state.expect100header = FALSE; /* default to false unless it is set
+                                          to TRUE below */
+  if(use_http_1_1plus(data, conn) &&
+     (conn->httpversion != 20)) {
+    /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
+       Expect: 100-continue to the headers which actually speeds up post
+       operations (as there is one packet coming back from the web server) */
+    ptr = Curl_checkheaders(conn, "Expect:");
+    if(ptr) {
+      data->state.expect100header =
+        Curl_compareheader(ptr, "Expect:", "100-continue");
+    }
+    else {
+      result = Curl_add_bufferf(req_buffer,
+                         "Expect: 100-continue\r\n");
+      if(!result)
+        data->state.expect100header = TRUE;
+    }
+  }
+  return result;
+}
+
+enum proxy_use {
+  HEADER_SERVER,  /* direct to server */
+  HEADER_PROXY,   /* regular request to proxy */
+  HEADER_CONNECT  /* sending CONNECT to a proxy */
+};
+
+CURLcode Curl_add_custom_headers(struct connectdata *conn,
+                                 bool is_connect,
+                                 Curl_send_buffer *req_buffer)
+{
+  char *ptr;
+  struct curl_slist *h[2];
+  struct curl_slist *headers;
+  int numlists=1; /* by default */
+  struct SessionHandle *data = conn->data;
+  int i;
+
+  enum proxy_use proxy;
+
+  if(is_connect)
+    proxy = HEADER_CONNECT;
+  else
+    proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy?
+      HEADER_PROXY:HEADER_SERVER;
+
+  switch(proxy) {
+  case HEADER_SERVER:
+    h[0] = data->set.headers;
+    break;
+  case HEADER_PROXY:
+    h[0] = data->set.headers;
+    if(data->set.sep_headers) {
+      h[1] = data->set.proxyheaders;
+      numlists++;
+    }
+    break;
+  case HEADER_CONNECT:
+    if(data->set.sep_headers)
+      h[0] = data->set.proxyheaders;
+    else
+      h[0] = data->set.headers;
+    break;
+  }
+
+  /* loop through one or two lists */
+  for(i=0; i < numlists; i++) {
+    headers = h[i];
+
+    while(headers) {
+      ptr = strchr(headers->data, ':');
+      if(ptr) {
+        /* we require a colon for this to be a true header */
+
+        ptr++; /* pass the colon */
+        while(*ptr && ISSPACE(*ptr))
+          ptr++;
+
+        if(*ptr) {
+          /* only send this if the contents was non-blank */
+
+          if(conn->allocptr.host &&
+             /* a Host: header was sent already, don't pass on any custom Host:
+                header as that will produce *two* in the same request! */
+             checkprefix("Host:", headers->data))
+            ;
+          else if(data->set.httpreq == HTTPREQ_POST_FORM &&
+                  /* this header (extended by formdata.c) is sent later */
+                  checkprefix("Content-Type:", headers->data))
+            ;
+          else if(conn->bits.authneg &&
+                  /* while doing auth neg, don't allow the custom length since
+                     we will force length zero then */
+                  checkprefix("Content-Length", headers->data))
+            ;
+          else if(conn->allocptr.te &&
+                  /* when asking for Transfer-Encoding, don't pass on a custom
+                     Connection: */
+                  checkprefix("Connection", headers->data))
+            ;
+          else {
+            CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
+                                               headers->data);
+            if(result)
+              return result;
+          }
+        }
+      }
+      else {
+        ptr = strchr(headers->data, ';');
+        if(ptr) {
+
+          ptr++; /* pass the semicolon */
+          while(*ptr && ISSPACE(*ptr))
+            ptr++;
+
+          if(*ptr) {
+            /* this may be used for something else in the future */
+          }
+          else {
+            if(*(--ptr) == ';') {
+              CURLcode result;
+
+              /* send no-value custom header if terminated by semicolon */
+              *ptr = ':';
+              result = Curl_add_bufferf(req_buffer, "%s\r\n",
+                                        headers->data);
+              if(result)
+                return result;
+            }
+          }
+        }
+      }
+      headers = headers->next;
+    }
+  }
+  return CURLE_OK;
+}
+
+CURLcode Curl_add_timecondition(struct SessionHandle *data,
+                                Curl_send_buffer *req_buffer)
+{
+  const struct tm *tm;
+  char *buf = data->state.buffer;
+  struct tm keeptime;
+  CURLcode result;
+
+  if(data->set.timecondition == CURL_TIMECOND_NONE)
+    /* no condition was asked for */
+    return CURLE_OK;
+
+  result = Curl_gmtime(data->set.timevalue, &keeptime);
+  if(result) {
+    failf(data, "Invalid TIMEVALUE");
+    return result;
+  }
+  tm = &keeptime;
+
+  /* The If-Modified-Since header family should have their times set in
+   * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
+   * represented in Greenwich Mean Time (GMT), without exception. For the
+   * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
+   * Time)." (see page 20 of RFC2616).
+   */
+
+  /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
+  snprintf(buf, BUFSIZE-1,
+           "%s, %02d %s %4d %02d:%02d:%02d GMT",
+           Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+           tm->tm_mday,
+           Curl_month[tm->tm_mon],
+           tm->tm_year + 1900,
+           tm->tm_hour,
+           tm->tm_min,
+           tm->tm_sec);
+
+  switch(data->set.timecondition) {
+  default:
+    break;
+  case CURL_TIMECOND_IFMODSINCE:
+    result = Curl_add_bufferf(req_buffer,
+                              "If-Modified-Since: %s\r\n", buf);
+    break;
+  case CURL_TIMECOND_IFUNMODSINCE:
+    result = Curl_add_bufferf(req_buffer,
+                              "If-Unmodified-Since: %s\r\n", buf);
+    break;
+  case CURL_TIMECOND_LASTMOD:
+    result = Curl_add_bufferf(req_buffer,
+                              "Last-Modified: %s\r\n", buf);
+    break;
+  }
+
+  return result;
+}
+
+/*
+ * Curl_http() gets called from the generic Curl_do() function when a HTTP
+ * request is to be performed. This creates and sends a properly constructed
+ * HTTP request.
+ */
+CURLcode Curl_http(struct connectdata *conn, bool *done)
+{
+  struct SessionHandle *data = conn->data;
+  CURLcode result = CURLE_OK;
+  struct HTTP *http;
+  const char *ppath = data->state.path;
+  bool paste_ftp_userpwd = FALSE;
+  char ftp_typecode[sizeof("/;type=?")] = "";
+  const char *host = conn->host.name;
+  const char *te = ""; /* transfer-encoding */
+  const char *ptr;
+  const char *request;
+  Curl_HttpReq httpreq = data->set.httpreq;
+#if !defined(CURL_DISABLE_COOKIES)
+  char *addcookies = NULL;
+#endif
+  curl_off_t included_body = 0;
+  const char *httpstring;
+  Curl_send_buffer *req_buffer;
+  curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
+  int seekerr = CURL_SEEKFUNC_OK;
+
+  /* Always consider the DO phase done after this function call, even if there
+     may be parts of the request that is not yet sent, since we can deal with
+     the rest of the request in the PERFORM phase. */
+  *done = TRUE;
+
+  if(conn->httpversion < 20) { /* unless the connection is re-used and already
+                                  http2 */
+    switch(conn->negnpn) {
+    case CURL_HTTP_VERSION_2:
+      conn->httpversion = 20; /* we know we're on HTTP/2 now */
+      result = Curl_http2_init(conn);
+      if(result)
+        return result;
+
+      result = Curl_http2_setup(conn);
+      if(result)
+        return result;
+
+      result = Curl_http2_switched(conn, NULL, 0);
+      if(result)
+        return result;
+      break;
+    case CURL_HTTP_VERSION_1_1:
+      /* continue with HTTP/1.1 when explicitly requested */
+      break;
+    default:
+      /* and as fallback */
+      break;
+    }
+  }
+  else {
+    /* prepare for a http2 request */
+    result = Curl_http2_setup(conn);
+    if(result)
+      return result;
+  }
+
+  http = data->req.protop;
+
+  if(!data->state.this_is_a_follow) {
+    /* Free to avoid leaking memory on multiple requests*/
+    free(data->state.first_host);
+
+    data->state.first_host = strdup(conn->host.name);
+    if(!data->state.first_host)
+      return CURLE_OUT_OF_MEMORY;
+  }
+  http->writebytecount = http->readbytecount = 0;
+
+  if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
+     data->set.upload) {
+    httpreq = HTTPREQ_PUT;
+  }
+
+  /* Now set the 'request' pointer to the proper request string */
+  if(data->set.str[STRING_CUSTOMREQUEST])
+    request = data->set.str[STRING_CUSTOMREQUEST];
+  else {
+    if(data->set.opt_no_body)
+      request = "HEAD";
+    else {
+      DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
+      switch(httpreq) {
+      case HTTPREQ_POST:
+      case HTTPREQ_POST_FORM:
+        request = "POST";
+        break;
+      case HTTPREQ_PUT:
+        request = "PUT";
+        break;
+      default: /* this should never happen */
+      case HTTPREQ_GET:
+        request = "GET";
+        break;
+      case HTTPREQ_HEAD:
+        request = "HEAD";
+        break;
+      }
+    }
+  }
+
+  /* The User-Agent string might have been allocated in url.c already, because
+     it might have been used in the proxy connect, but if we have got a header
+     with the user-agent string specified, we erase the previously made string
+     here. */
+  if(Curl_checkheaders(conn, "User-Agent:")) {
+    free(conn->allocptr.uagent);
+    conn->allocptr.uagent=NULL;
+  }
+
+  /* setup the authentication headers */
+  result = Curl_http_output_auth(conn, request, ppath, FALSE);
+  if(result)
+    return result;
+
+  if((data->state.authhost.multi || data->state.authproxy.multi) &&
+     (httpreq != HTTPREQ_GET) &&
+     (httpreq != HTTPREQ_HEAD)) {
+    /* Auth is required and we are not authenticated yet. Make a PUT or POST
+       with content-length zero as a "probe". */
+    conn->bits.authneg = TRUE;
+  }
+  else
+    conn->bits.authneg = FALSE;
+
+  Curl_safefree(conn->allocptr.ref);
+  if(data->change.referer && !Curl_checkheaders(conn, "Referer:")) {
+    conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
+    if(!conn->allocptr.ref)
+      return CURLE_OUT_OF_MEMORY;
+  }
+  else
+    conn->allocptr.ref = NULL;
+
+#if !defined(CURL_DISABLE_COOKIES)
+  if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie:"))
+    addcookies = data->set.str[STRING_COOKIE];
+#endif
+
+  if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
+     data->set.str[STRING_ENCODING]) {
+    Curl_safefree(conn->allocptr.accept_encoding);
+    conn->allocptr.accept_encoding =
+      aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
+    if(!conn->allocptr.accept_encoding)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+#ifdef HAVE_LIBZ
+  /* we only consider transfer-encoding magic if libz support is built-in */
+
+  if(!Curl_checkheaders(conn, "TE:") &&
+     data->set.http_transfer_encoding) {
+    /* When we are to insert a TE: header in the request, we must also insert
+       TE in a Connection: header, so we need to merge the custom provided
+       Connection: header and prevent the original to get sent. Note that if
+       the user has inserted his/hers own TE: header we don't do this magic
+       but then assume that the user will handle it all! */
+    char *cptr = Curl_checkheaders(conn, "Connection:");
+#define TE_HEADER "TE: gzip\r\n"
+
+    Curl_safefree(conn->allocptr.te);
+
+    /* Create the (updated) Connection: header */
+    conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
+      strdup("Connection: TE\r\n" TE_HEADER);
+
+    if(!conn->allocptr.te)
+      return CURLE_OUT_OF_MEMORY;
+  }
+#endif
+
+  if(conn->httpversion == 20)
+    /* In HTTP2 forbids Transfer-Encoding: chunked */
+    ptr = NULL;
+  else {
+    ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
+    if(ptr) {
+      /* Some kind of TE is requested, check if 'chunked' is chosen */
+      data->req.upload_chunky =
+        Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
+    }
+    else {
+      if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
+         data->set.upload &&
+         (data->state.infilesize == -1)) {
+        if(conn->bits.authneg)
+          /* don't enable chunked during auth neg */
+          ;
+        else if(use_http_1_1plus(data, conn)) {
+          /* HTTP, upload, unknown file size and not HTTP 1.0 */
+          data->req.upload_chunky = TRUE;
+        }
+        else {
+          failf(data, "Chunky upload is not supported by HTTP 1.0");
+          return CURLE_UPLOAD_FAILED;
+        }
+      }
+      else {
+        /* else, no chunky upload */
+        data->req.upload_chunky = FALSE;
+      }
+
+      if(data->req.upload_chunky)
+        te = "Transfer-Encoding: chunked\r\n";
+    }
+  }
+
+  Curl_safefree(conn->allocptr.host);
+
+  ptr = Curl_checkheaders(conn, "Host:");
+  if(ptr && (!data->state.this_is_a_follow ||
+             Curl_raw_equal(data->state.first_host, conn->host.name))) {
+#if !defined(CURL_DISABLE_COOKIES)
+    /* If we have a given custom Host: header, we extract the host name in
+       order to possibly use it for cookie reasons later on. We only allow the
+       custom Host: header if this is NOT a redirect, as setting Host: in the
+       redirected request is being out on thin ice. Except if the host name
+       is the same as the first one! */
+    char *cookiehost = Curl_copy_header_value(ptr);
+    if(!cookiehost)
+      return CURLE_OUT_OF_MEMORY;
+    if(!*cookiehost)
+      /* ignore empty data */
+      free(cookiehost);
+    else {
+      /* If the host begins with '[', we start searching for the port after
+         the bracket has been closed */
+      int startsearch = 0;
+      if(*cookiehost == '[') {
+        char *closingbracket;
+        /* since the 'cookiehost' is an allocated memory area that will be
+           freed later we cannot simply increment the pointer */
+        memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
+        closingbracket = strchr(cookiehost, ']');
+        if(closingbracket)
+          *closingbracket = 0;
+      }
+      else {
+        char *colon = strchr(cookiehost + startsearch, ':');
+        if(colon)
+          *colon = 0; /* The host must not include an embedded port number */
+      }
+      Curl_safefree(conn->allocptr.cookiehost);
+      conn->allocptr.cookiehost = cookiehost;
+    }
+#endif
+
+    if(strcmp("Host:", ptr)) {
+      conn->allocptr.host = aprintf("%s\r\n", ptr);
+      if(!conn->allocptr.host)
+        return CURLE_OUT_OF_MEMORY;
+    }
+    else
+      /* when clearing the header */
+      conn->allocptr.host = NULL;
+  }
+  else {
+    /* When building Host: headers, we must put the host name within
+       [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
+
+    if(((conn->given->protocol&CURLPROTO_HTTPS) &&
+        (conn->remote_port == PORT_HTTPS)) ||
+       ((conn->given->protocol&CURLPROTO_HTTP) &&
+        (conn->remote_port == PORT_HTTP)) )
+      /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
+         the port number in the host string */
+      conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
+                                    conn->bits.ipv6_ip?"[":"",
+                                    host,
+                                    conn->bits.ipv6_ip?"]":"");
+    else
+      conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
+                                    conn->bits.ipv6_ip?"[":"",
+                                    host,
+                                    conn->bits.ipv6_ip?"]":"",
+                                    conn->remote_port);
+
+    if(!conn->allocptr.host)
+      /* without Host: we can't make a nice request */
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+#ifndef CURL_DISABLE_PROXY
+  if(conn->bits.httpproxy && !conn->bits.tunnel_proxy)  {
+    /* Using a proxy but does not tunnel through it */
+
+    /* The path sent to the proxy is in fact the entire URL. But if the remote
+       host is a IDN-name, we must make sure that the request we produce only
+       uses the encoded host name! */
+    if(conn->host.dispname != conn->host.name) {
+      char *url = data->change.url;
+      ptr = strstr(url, conn->host.dispname);
+      if(ptr) {
+        /* This is where the display name starts in the URL, now replace this
+           part with the encoded name. TODO: This method of replacing the host
+           name is rather crude as I believe there's a slight risk that the
+           user has entered a user name or password that contain the host name
+           string. */
+        size_t currlen = strlen(conn->host.dispname);
+        size_t newlen = strlen(conn->host.name);
+        size_t urllen = strlen(url);
+
+        char *newurl;
+
+        newurl = malloc(urllen + newlen - currlen + 1);
+        if(newurl) {
+          /* copy the part before the host name */
+          memcpy(newurl, url, ptr - url);
+          /* append the new host name instead of the old */
+          memcpy(newurl + (ptr - url), conn->host.name, newlen);
+          /* append the piece after the host name */
+          memcpy(newurl + newlen + (ptr - url),
+                 ptr + currlen, /* copy the trailing zero byte too */
+                 urllen - (ptr-url) - currlen + 1);
+          if(data->change.url_alloc) {
+            Curl_safefree(data->change.url);
+            data->change.url_alloc = FALSE;
+          }
+          data->change.url = newurl;
+          data->change.url_alloc = TRUE;
+        }
+        else
+          return CURLE_OUT_OF_MEMORY;
+      }
+    }
+    ppath = data->change.url;
+    if(checkprefix("ftp://", ppath)) {
+      if(data->set.proxy_transfer_mode) {
+        /* when doing ftp, append ;type=<a|i> if not present */
+        char *type = strstr(ppath, ";type=");
+        if(type && type[6] && type[7] == 0) {
+          switch (Curl_raw_toupper(type[6])) {
+          case 'A':
+          case 'D':
+          case 'I':
+            break;
+          default:
+            type = NULL;
+          }
+        }
+        if(!type) {
+          char *p = ftp_typecode;
+          /* avoid sending invalid URLs like ftp://example.com;type=i if the
+           * user specified ftp://example.com without the slash */
+          if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
+            *p++ = '/';
+          }
+          snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
+                   data->set.prefer_ascii ? 'a' : 'i');
+        }
+      }
+      if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
+        paste_ftp_userpwd = TRUE;
+    }
+  }
+#endif /* CURL_DISABLE_PROXY */
+
+  if(HTTPREQ_POST_FORM == httpreq) {
+    /* we must build the whole post sequence first, so that we have a size of
+       the whole transfer before we start to send it */
+    result = Curl_getformdata(data, &http->sendit, data->set.httppost,
+                              Curl_checkheaders(conn, "Content-Type:"),
+                              &http->postsize);
+    if(result)
+      return result;
+  }
+
+  http->p_accept = Curl_checkheaders(conn, "Accept:")?NULL:"Accept: */*\r\n";
+
+  if(( (HTTPREQ_POST == httpreq) ||
+       (HTTPREQ_POST_FORM == httpreq) ||
+       (HTTPREQ_PUT == httpreq) ) &&
+     data->state.resume_from) {
+    /**********************************************************************
+     * Resuming upload in HTTP means that we PUT or POST and that we have
+     * got a resume_from value set. The resume value has already created
+     * a Range: header that will be passed along. We need to "fast forward"
+     * the file the given number of bytes and decrease the assume upload
+     * file size before we continue this venture in the dark lands of HTTP.
+     *********************************************************************/
+
+    if(data->state.resume_from < 0 ) {
+      /*
+       * This is meant to get the size of the present remote-file by itself.
+       * We don't support this now. Bail out!
+       */
+      data->state.resume_from = 0;
+    }
+
+    if(data->state.resume_from && !data->state.this_is_a_follow) {
+      /* do we still game? */
+
+      /* Now, let's read off the proper amount of bytes from the
+         input. */
+      if(conn->seek_func) {
+        seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+                                  SEEK_SET);
+      }
+
+      if(seekerr != CURL_SEEKFUNC_OK) {
+        if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+          failf(data, "Could not seek stream");
+          return CURLE_READ_ERROR;
+        }
+        /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+        else {
+          curl_off_t passed=0;
+          do {
+            size_t readthisamountnow =
+              (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
+              BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
+
+            size_t actuallyread =
+              data->state.fread_func(data->state.buffer, 1, readthisamountnow,
+                                     data->state.in);
+
+            passed += actuallyread;
+            if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+              /* this checks for greater-than only to make sure that the
+                 CURL_READFUNC_ABORT return code still aborts */
+              failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
+                    " bytes from the input", passed);
+              return CURLE_READ_ERROR;
+            }
+          } while(passed < data->state.resume_from);
+        }
+      }
+
+      /* now, decrease the size of the read */
+      if(data->state.infilesize>0) {
+        data->state.infilesize -= data->state.resume_from;
+
+        if(data->state.infilesize <= 0) {
+          failf(data, "File already completely uploaded");
+          return CURLE_PARTIAL_FILE;
+        }
+      }
+      /* we've passed, proceed as normal */
+    }
+  }
+  if(data->state.use_range) {
+    /*
+     * A range is selected. We use different headers whether we're downloading
+     * or uploading and we always let customized headers override our internal
+     * ones if any such are specified.
+     */
+    if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
+       !Curl_checkheaders(conn, "Range:")) {
+      /* if a line like this was already allocated, free the previous one */
+      free(conn->allocptr.rangeline);
+      conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
+                                         data->state.range);
+    }
+    else if((httpreq != HTTPREQ_GET) &&
+            !Curl_checkheaders(conn, "Content-Range:")) {
+
+      /* if a line like this was already allocated, free the previous one */
+      free(conn->allocptr.rangeline);
+
+      if(data->set.set_resume_from < 0) {
+        /* Upload resume was asked for, but we don't know the size of the
+           remote part so we tell the server (and act accordingly) that we
+           upload the whole file (again) */
+        conn->allocptr.rangeline =
+          aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
+                  "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
+                  data->state.infilesize - 1, data->state.infilesize);
+
+      }
+      else if(data->state.resume_from) {
+        /* This is because "resume" was selected */
+        curl_off_t total_expected_size=
+          data->state.resume_from + data->state.infilesize;
+        conn->allocptr.rangeline =
+          aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
+                  "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
+                  data->state.range, total_expected_size-1,
+                  total_expected_size);
+      }
+      else {
+        /* Range was selected and then we just pass the incoming range and
+           append total size */
+        conn->allocptr.rangeline =
+          aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
+                  data->state.range, data->state.infilesize);
+      }
+      if(!conn->allocptr.rangeline)
+        return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* Use 1.1 unless the user specifically asked for 1.0 or the server only
+     supports 1.0 */
+  httpstring= use_http_1_1plus(data, conn)?"1.1":"1.0";
+
+  /* initialize a dynamic send-buffer */
+  req_buffer = Curl_add_buffer_init();
+
+  if(!req_buffer)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* add the main request stuff */
+  /* GET/HEAD/POST/PUT */
+  result = Curl_add_bufferf(req_buffer, "%s ", request);
+  if(result)
+    return result;
+
+  /* url */
+  if(paste_ftp_userpwd)
+    result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
+                              conn->user, conn->passwd,
+                              ppath + sizeof("ftp://") - 1);
+  else
+    result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
+  if(result)
+    return result;
+
+  result =
+    Curl_add_bufferf(req_buffer,
+                     "%s" /* ftp typecode (;type=x) */
+                     " HTTP/%s\r\n" /* HTTP version */
+                     "%s" /* host */
+                     "%s" /* proxyuserpwd */
+                     "%s" /* userpwd */
+                     "%s" /* range */
+                     "%s" /* user agent */
+                     "%s" /* accept */
+                     "%s" /* TE: */
+                     "%s" /* accept-encoding */
+                     "%s" /* referer */
+                     "%s" /* Proxy-Connection */
+                     "%s",/* transfer-encoding */
+
+                     ftp_typecode,
+                     httpstring,
+                     (conn->allocptr.host?conn->allocptr.host:""),
+                     conn->allocptr.proxyuserpwd?
+                     conn->allocptr.proxyuserpwd:"",
+                     conn->allocptr.userpwd?conn->allocptr.userpwd:"",
+                     (data->state.use_range && conn->allocptr.rangeline)?
+                     conn->allocptr.rangeline:"",
+                     (data->set.str[STRING_USERAGENT] &&
+                      *data->set.str[STRING_USERAGENT] &&
+                      conn->allocptr.uagent)?
+                     conn->allocptr.uagent:"",
+                     http->p_accept?http->p_accept:"",
+                     conn->allocptr.te?conn->allocptr.te:"",
+                     (data->set.str[STRING_ENCODING] &&
+                      *data->set.str[STRING_ENCODING] &&
+                      conn->allocptr.accept_encoding)?
+                     conn->allocptr.accept_encoding:"",
+                     (data->change.referer && conn->allocptr.ref)?
+                     conn->allocptr.ref:"" /* Referer: <data> */,
+                     (conn->bits.httpproxy &&
+                      !conn->bits.tunnel_proxy &&
+                      !Curl_checkProxyheaders(conn, "Proxy-Connection:"))?
+                     "Proxy-Connection: Keep-Alive\r\n":"",
+                     te
+      );
+
+  /* clear userpwd to avoid re-using credentials from re-used connections */
+  Curl_safefree(conn->allocptr.userpwd);
+
+  /*
+   * Free proxyuserpwd for Negotiate/NTLM. Cannot reuse as it is associated
+   * with the connection and shouldn't be repeated over it either.
+   */
+  switch (data->state.authproxy.picked) {
+  case CURLAUTH_NEGOTIATE:
+  case CURLAUTH_NTLM:
+  case CURLAUTH_NTLM_WB:
+    Curl_safefree(conn->allocptr.proxyuserpwd);
+    break;
+  }
+
+  if(result)
+    return result;
+
+  if(!(conn->handler->flags&PROTOPT_SSL) &&
+     conn->httpversion != 20 &&
+     (data->set.httpversion == CURL_HTTP_VERSION_2)) {
+    /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
+       over SSL */
+    result = Curl_http2_request_upgrade(req_buffer, conn);
+    if(result)
+      return result;
+  }
+
+#if !defined(CURL_DISABLE_COOKIES)
+  if(data->cookies || addcookies) {
+    struct Cookie *co=NULL; /* no cookies from start */
+    int count=0;
+
+    if(data->cookies) {
+      Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+      co = Curl_cookie_getlist(data->cookies,
+                               conn->allocptr.cookiehost?
+                               conn->allocptr.cookiehost:host,
+                               data->state.path,
+                               (conn->handler->protocol&CURLPROTO_HTTPS)?
+                               TRUE:FALSE);
+      Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+    }
+    if(co) {
+      struct Cookie *store=co;
+      /* now loop through all cookies that matched */
+      while(co) {
+        if(co->value) {
+          if(0 == count) {
+            result = Curl_add_bufferf(req_buffer, "Cookie: ");
+            if(result)
+              break;
+          }
+          result = Curl_add_bufferf(req_buffer,
+                                    "%s%s=%s", count?"; ":"",
+                                    co->name, co->value);
+          if(result)
+            break;
+          count++;
+        }
+        co = co->next; /* next cookie please */
+      }
+      Curl_cookie_freelist(store, FALSE); /* free the cookie list */
+    }
+    if(addcookies && !result) {
+      if(!count)
+        result = Curl_add_bufferf(req_buffer, "Cookie: ");
+      if(!result) {
+        result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"",
+                                  addcookies);
+        count++;
+      }
+    }
+    if(count && !result)
+      result = Curl_add_buffer(req_buffer, "\r\n", 2);
+
+    if(result)
+      return result;
+  }
+#endif
+
+  result = Curl_add_timecondition(data, req_buffer);
+  if(result)
+    return result;
+
+  result = Curl_add_custom_headers(conn, FALSE, req_buffer);
+  if(result)
+    return result;
+
+  http->postdata = NULL;  /* nothing to post at this point */
+  Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */
+
+  /* If 'authdone' is FALSE, we must not set the write socket index to the
+     Curl_transfer() call below, as we're not ready to actually upload any
+     data yet. */
+
+  switch(httpreq) {
+
+  case HTTPREQ_POST_FORM:
+    if(!http->sendit || conn->bits.authneg) {
+      /* nothing to post! */
+      result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
+      if(result)
+        return result;
+
+      result = Curl_add_buffer_send(req_buffer, conn,
+                                    &data->info.request_size, 0, FIRSTSOCKET);
+      if(result)
+        failf(data, "Failed sending POST request");
+      else
+        /* setup variables for the upcoming transfer */
+        Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
+                            -1, NULL);
+      break;
+    }
+
+    if(Curl_FormInit(&http->form, http->sendit)) {
+      failf(data, "Internal HTTP POST error!");
+      return CURLE_HTTP_POST_ERROR;
+    }
+
+    /* Get the currently set callback function pointer and store that in the
+       form struct since we might want the actual user-provided callback later
+       on. The data->set.fread_func pointer itself will be changed for the
+       multipart case to the function that returns a multipart formatted
+       stream. */
+    http->form.fread_func = data->state.fread_func;
+
+    /* Set the read function to read from the generated form data */
+    data->state.fread_func = (curl_read_callback)Curl_FormReader;
+    data->state.in = &http->form;
+
+    http->sending = HTTPSEND_BODY;
+
+    if(!data->req.upload_chunky &&
+       !Curl_checkheaders(conn, "Content-Length:")) {
+      /* only add Content-Length if not uploading chunked */
+      result = Curl_add_bufferf(req_buffer,
+                                "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+                                "\r\n", http->postsize);
+      if(result)
+        return result;
+    }
+
+    result = expect100(data, conn, req_buffer);
+    if(result)
+      return result;
+
+    {
+
+      /* Get Content-Type: line from Curl_formpostheader.
+       */
+      char *contentType;
+      size_t linelength=0;
+      contentType = Curl_formpostheader((void *)&http->form,
+                                        &linelength);
+      if(!contentType) {
+        failf(data, "Could not get Content-Type header line!");
+        return CURLE_HTTP_POST_ERROR;
+      }
+
+      result = Curl_add_buffer(req_buffer, contentType, linelength);
+      if(result)
+        return result;
+    }
+
+    /* make the request end in a true CRLF */
+    result = Curl_add_buffer(req_buffer, "\r\n", 2);
+    if(result)
+      return result;
+
+    /* set upload size to the progress meter */
+    Curl_pgrsSetUploadSize(data, http->postsize);
+
+    /* fire away the whole request to the server */
+    result = Curl_add_buffer_send(req_buffer, conn,
+                                  &data->info.request_size, 0, FIRSTSOCKET);
+    if(result)
+      failf(data, "Failed sending POST request");
+    else
+      /* setup variables for the upcoming transfer */
+      Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
+                          &http->readbytecount, FIRSTSOCKET,
+                          &http->writebytecount);
+
+    if(result) {
+      Curl_formclean(&http->sendit); /* free that whole lot */
+      return result;
+    }
+
+    /* convert the form data */
+    result = Curl_convert_form(data, http->sendit);
+    if(result) {
+      Curl_formclean(&http->sendit); /* free that whole lot */
+      return result;
+    }
+
+    break;
+
+  case HTTPREQ_PUT: /* Let's PUT the data to the server! */
+
+    if(conn->bits.authneg)
+      postsize = 0;
+    else
+      postsize = data->state.infilesize;
+
+    if((postsize != -1) && !data->req.upload_chunky &&
+       !Curl_checkheaders(conn, "Content-Length:")) {
+      /* only add Content-Length if not uploading chunked */
+      result = Curl_add_bufferf(req_buffer,
+                                "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+                                "\r\n", postsize);
+      if(result)
+        return result;
+    }
+
+    if(postsize != 0) {
+      result = expect100(data, conn, req_buffer);
+      if(result)
+        return result;
+    }
+
+    result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
+    if(result)
+      return result;
+
+    /* set the upload size to the progress meter */
+    Curl_pgrsSetUploadSize(data, postsize);
+
+    /* this sends the buffer and frees all the buffer resources */
+    result = Curl_add_buffer_send(req_buffer, conn,
+                                  &data->info.request_size, 0, FIRSTSOCKET);
+    if(result)
+      failf(data, "Failed sending PUT request");
+    else
+      /* prepare for transfer */
+      Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
+                          &http->readbytecount, postsize?FIRSTSOCKET:-1,
+                          postsize?&http->writebytecount:NULL);
+    if(result)
+      return result;
+    break;
+
+  case HTTPREQ_POST:
+    /* this is the simple POST, using x-www-form-urlencoded style */
+
+    if(conn->bits.authneg)
+      postsize = 0;
+    else {
+      /* figure out the size of the postfields */
+      postsize = (data->state.infilesize != -1)?
+        data->state.infilesize:
+        (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
+    }
+
+    /* We only set Content-Length and allow a custom Content-Length if
+       we don't upload data chunked, as RFC2616 forbids us to set both
+       kinds of headers (Transfer-Encoding: chunked and Content-Length) */
+    if((postsize != -1) && !data->req.upload_chunky &&
+       !Curl_checkheaders(conn, "Content-Length:")) {
+      /* we allow replacing this header if not during auth negotiation,
+         although it isn't very wise to actually set your own */
+      result = Curl_add_bufferf(req_buffer,
+                                "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+                                "\r\n", postsize);
+      if(result)
+        return result;
+    }
+
+    if(!Curl_checkheaders(conn, "Content-Type:")) {
+      result = Curl_add_bufferf(req_buffer,
+                                "Content-Type: application/"
+                                "x-www-form-urlencoded\r\n");
+      if(result)
+        return result;
+    }
+
+    /* For really small posts we don't use Expect: headers at all, and for
+       the somewhat bigger ones we allow the app to disable it. Just make
+       sure that the expect100header is always set to the preferred value
+       here. */
+    ptr = Curl_checkheaders(conn, "Expect:");
+    if(ptr) {
+      data->state.expect100header =
+        Curl_compareheader(ptr, "Expect:", "100-continue");
+    }
+    else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) {
+      result = expect100(data, conn, req_buffer);
+      if(result)
+        return result;
+    }
+    else
+      data->state.expect100header = FALSE;
+
+    if(data->set.postfields) {
+
+      /* In HTTP2, we send request body in DATA frame regardless of
+         its size. */
+      if(conn->httpversion != 20 &&
+         !data->state.expect100header &&
+         (postsize < MAX_INITIAL_POST_SIZE))  {
+        /* if we don't use expect: 100  AND
+           postsize is less than MAX_INITIAL_POST_SIZE
+
+           then append the post data to the HTTP request header. This limit
+           is no magic limit but only set to prevent really huge POSTs to
+           get the data duplicated with malloc() and family. */
+
+        result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
+        if(result)
+          return result;
+
+        if(!data->req.upload_chunky) {
+          /* We're not sending it 'chunked', append it to the request
+             already now to reduce the number if send() calls */
+          result = Curl_add_buffer(req_buffer, data->set.postfields,
+                                   (size_t)postsize);
+          included_body = postsize;
+        }
+        else {
+          if(postsize) {
+            /* Append the POST data chunky-style */
+            result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
+            if(!result) {
+              result = Curl_add_buffer(req_buffer, data->set.postfields,
+                                       (size_t)postsize);
+              if(!result)
+                result = Curl_add_buffer(req_buffer, "\r\n", 2);
+              included_body = postsize + 2;
+            }
+          }
+          if(!result)
+            result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
+          /* 0  CR  LF  CR  LF */
+          included_body += 5;
+        }
+        if(result)
+          return result;
+        /* Make sure the progress information is accurate */
+        Curl_pgrsSetUploadSize(data, postsize);
+      }
+      else {
+        /* A huge POST coming up, do data separate from the request */
+        http->postsize = postsize;
+        http->postdata = data->set.postfields;
+
+        http->sending = HTTPSEND_BODY;
+
+        data->state.fread_func = (curl_read_callback)readmoredata;
+        data->state.in = (void *)conn;
+
+        /* set the upload size to the progress meter */
+        Curl_pgrsSetUploadSize(data, http->postsize);
+
+        result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
+        if(result)
+          return result;
+      }
+    }
+    else {
+      result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
+      if(result)
+        return result;
+
+      if(data->req.upload_chunky && conn->bits.authneg) {
+        /* Chunky upload is selected and we're negotiating auth still, send
+           end-of-data only */
+        result = Curl_add_buffer(req_buffer,
+                                 "\x30\x0d\x0a\x0d\x0a", 5);
+        /* 0  CR  LF  CR  LF */
+        if(result)
+          return result;
+      }
+
+      else if(data->state.infilesize) {
+        /* set the upload size to the progress meter */
+        Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
+
+        /* set the pointer to mark that we will send the post body using the
+           read callback, but only if we're not in authenticate
+           negotiation  */
+        if(!conn->bits.authneg) {
+          http->postdata = (char *)&http->postdata;
+          http->postsize = postsize;
+        }
+      }
+    }
+    /* issue the request */
+    result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
+                                  (size_t)included_body, FIRSTSOCKET);
+
+    if(result)
+      failf(data, "Failed sending HTTP POST request");
+    else
+      Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
+                          &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
+                          http->postdata?&http->writebytecount:NULL);
+    break;
+
+  default:
+    result = Curl_add_buffer(req_buffer, "\r\n", 2);
+    if(result)
+      return result;
+
+    /* issue the request */
+    result = Curl_add_buffer_send(req_buffer, conn,
+                                  &data->info.request_size, 0, FIRSTSOCKET);
+
+    if(result)
+      failf(data, "Failed sending HTTP request");
+    else
+      /* HTTP GET/HEAD download: */
+      Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
+                          http->postdata?FIRSTSOCKET:-1,
+                          http->postdata?&http->writebytecount:NULL);
+  }
+  if(result)
+    return result;
+
+  if(http->writebytecount) {
+    /* if a request-body has been sent off, we make sure this progress is noted
+       properly */
+    Curl_pgrsSetUploadCounter(data, http->writebytecount);
+    if(Curl_pgrsUpdate(conn))
+      result = CURLE_ABORTED_BY_CALLBACK;
+
+    if(http->writebytecount >= postsize) {
+      /* already sent the entire request body, mark the "upload" as
+         complete */
+      infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
+            " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
+            http->writebytecount, postsize);
+      data->req.upload_done = TRUE;
+      data->req.keepon &= ~KEEP_SEND; /* we're done writing */
+      data->req.exp100 = EXP100_SEND_DATA; /* already sent */
+    }
+  }
+
+  return result;
+}
+
+/*
+ * checkhttpprefix()
+ *
+ * Returns TRUE if member of the list matches prefix of string
+ */
+static bool
+checkhttpprefix(struct SessionHandle *data,
+                const char *s)
+{
+  struct curl_slist *head = data->set.http200aliases;
+  bool rc = FALSE;
+#ifdef CURL_DOES_CONVERSIONS
+  /* convert from the network encoding using a scratch area */
+  char *scratch = strdup(s);
+  if(NULL == scratch) {
+    failf (data, "Failed to allocate memory for conversion!");
+    return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
+  }
+  if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
+    /* Curl_convert_from_network calls failf if unsuccessful */
+    free(scratch);
+    return FALSE; /* can't return CURLE_foobar so return FALSE */
+  }
+  s = scratch;
+#endif /* CURL_DOES_CONVERSIONS */
+
+  while(head) {
+    if(checkprefix(head->data, s)) {
+      rc = TRUE;
+      break;
+    }
+    head = head->next;
+  }
+
+  if(!rc && (checkprefix("HTTP/", s)))
+    rc = TRUE;
+
+#ifdef CURL_DOES_CONVERSIONS
+  free(scratch);
+#endif /* CURL_DOES_CONVERSIONS */
+  return rc;
+}
+
+#ifndef CURL_DISABLE_RTSP
+static bool
+checkrtspprefix(struct SessionHandle *data,
+                const char *s)
+{
+
+#ifdef CURL_DOES_CONVERSIONS
+  /* convert from the network encoding using a scratch area */
+  char *scratch = strdup(s);
+  if(NULL == scratch) {
+    failf (data, "Failed to allocate memory for conversion!");
+    return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
+  }
+  if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
+    /* Curl_convert_from_network calls failf if unsuccessful */
+    free(scratch);
+    return FALSE; /* can't return CURLE_foobar so return FALSE */
+  }
+  s = scratch;
+#else
+  (void)data; /* unused */
+#endif /* CURL_DOES_CONVERSIONS */
+  if(checkprefix("RTSP/", s))
+    return TRUE;
+  else
+    return FALSE;
+}
+#endif /* CURL_DISABLE_RTSP */
+
+static bool
+checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
+                 const char *s)
+{
+#ifndef CURL_DISABLE_RTSP
+  if(conn->handler->protocol & CURLPROTO_RTSP)
+    return checkrtspprefix(data, s);
+#else
+  (void)conn;
+#endif /* CURL_DISABLE_RTSP */
+
+  return checkhttpprefix(data, s);
+}
+
+/*
+ * header_append() copies a chunk of data to the end of the already received
+ * header. We make sure that the full string fit in the allocated header
+ * buffer, or else we enlarge it.
+ */
+static CURLcode header_append(struct SessionHandle *data,
+                              struct SingleRequest *k,
+                              size_t length)
+{
+  if(k->hbuflen + length >= data->state.headersize) {
+    /* We enlarge the header buffer as it is too small */
+    char *newbuff;
+    size_t hbufp_index;
+    size_t newsize;
+
+    if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
+      /* The reason to have a max limit for this is to avoid the risk of a bad
+         server feeding libcurl with a never-ending header that will cause
+         reallocs infinitely */
+      failf (data, "Avoided giant realloc for header (max is %d)!",
+             CURL_MAX_HTTP_HEADER);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2);
+    hbufp_index = k->hbufp - data->state.headerbuff;
+    newbuff = realloc(data->state.headerbuff, newsize);
+    if(!newbuff) {
+      failf (data, "Failed to alloc memory for big header!");
+      return CURLE_OUT_OF_MEMORY;
+    }
+    data->state.headersize=newsize;
+    data->state.headerbuff = newbuff;
+    k->hbufp = data->state.headerbuff + hbufp_index;
+  }
+  memcpy(k->hbufp, k->str_start, length);
+  k->hbufp += length;
+  k->hbuflen += length;
+  *k->hbufp = 0;
+
+  return CURLE_OK;
+}
+
+static void print_http_error(struct SessionHandle *data)
+{
+  struct SingleRequest *k = &data->req;
+  char *beg = k->p;
+
+  /* make sure that data->req.p points to the HTTP status line */
+  if(!strncmp(beg, "HTTP", 4)) {
+
+    /* skip to HTTP status code */
+    beg = strchr(beg, ' ');
+    if(beg && *++beg) {
+
+      /* find trailing CR */
+      char end_char = '\r';
+      char *end = strchr(beg, end_char);
+      if(!end) {
+        /* try to find LF (workaround for non-compliant HTTP servers) */
+        end_char = '\n';
+        end = strchr(beg, end_char);
+      }
+
+      if(end) {
+        /* temporarily replace CR or LF by NUL and print the error message */
+        *end = '\0';
+        failf(data, "The requested URL returned error: %s", beg);
+
+        /* restore the previously replaced CR or LF */
+        *end = end_char;
+        return;
+      }
+    }
+  }
+
+  /* fall-back to printing the HTTP status code only */
+  failf(data, "The requested URL returned error: %d", k->httpcode);
+}
+
+/*
+ * Read any HTTP header lines from the server and pass them to the client app.
+ */
+CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
+                                       struct connectdata *conn,
+                                       ssize_t *nread,
+                                       bool *stop_reading)
+{
+  CURLcode result;
+  struct SingleRequest *k = &data->req;
+
+  /* header line within buffer loop */
+  do {
+    size_t rest_length;
+    size_t full_length;
+    int writetype;
+
+    /* str_start is start of line within buf */
+    k->str_start = k->str;
+
+    /* data is in network encoding so use 0x0a instead of '\n' */
+    k->end_ptr = memchr(k->str_start, 0x0a, *nread);
+
+    if(!k->end_ptr) {
+      /* Not a complete header line within buffer, append the data to
+         the end of the headerbuff. */
+      result = header_append(data, k, *nread);
+      if(result)
+        return result;
+
+      if(!k->headerline && (k->hbuflen>5)) {
+        /* make a first check that this looks like a protocol header */
+        if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
+          /* this is not the beginning of a protocol first header line */
+          k->header = FALSE;
+          k->badheader = HEADER_ALLBAD;
+          break;
+        }
+      }
+
+      break; /* read more and try again */
+    }
+
+    /* decrease the size of the remaining (supposed) header line */
+    rest_length = (k->end_ptr - k->str)+1;
+    *nread -= (ssize_t)rest_length;
+
+    k->str = k->end_ptr + 1; /* move past new line */
+
+    full_length = k->str - k->str_start;
+
+    result = header_append(data, k, full_length);
+    if(result)
+      return result;
+
+    k->end_ptr = k->hbufp;
+    k->p = data->state.headerbuff;
+
+    /****
+     * We now have a FULL header line that p points to
+     *****/
+
+    if(!k->headerline) {
+      /* the first read header */
+      if((k->hbuflen>5) &&
+         !checkprotoprefix(data, conn, data->state.headerbuff)) {
+        /* this is not the beginning of a protocol first header line */
+        k->header = FALSE;
+        if(*nread)
+          /* since there's more, this is a partial bad header */
+          k->badheader = HEADER_PARTHEADER;
+        else {
+          /* this was all we read so it's all a bad header */
+          k->badheader = HEADER_ALLBAD;
+          *nread = (ssize_t)rest_length;
+        }
+        break;
+      }
+    }
+
+    /* headers are in network encoding so
+       use 0x0a and 0x0d instead of '\n' and '\r' */
+    if((0x0a == *k->p) || (0x0d == *k->p)) {
+      size_t headerlen;
+      /* Zero-length header line means end of headers! */
+
+#ifdef CURL_DOES_CONVERSIONS
+      if(0x0d == *k->p) {
+        *k->p = '\r'; /* replace with CR in host encoding */
+        k->p++;       /* pass the CR byte */
+      }
+      if(0x0a == *k->p) {
+        *k->p = '\n'; /* replace with LF in host encoding */
+        k->p++;       /* pass the LF byte */
+      }
+#else
+      if('\r' == *k->p)
+        k->p++; /* pass the \r byte */
+      if('\n' == *k->p)
+        k->p++; /* pass the \n byte */
+#endif /* CURL_DOES_CONVERSIONS */
+
+      if(100 <= k->httpcode && 199 >= k->httpcode) {
+        /*
+         * We have made a HTTP PUT or POST and this is 1.1-lingo
+         * that tells us that the server is OK with this and ready
+         * to receive the data.
+         * However, we'll get more headers now so we must get
+         * back into the header-parsing state!
+         */
+        k->header = TRUE;
+        k->headerline = 0; /* restart the header line counter */
+
+        /* "A user agent MAY ignore unexpected 1xx status responses." */
+        switch(k->httpcode) {
+        case 100:
+          /* if we did wait for this do enable write now! */
+          if(k->exp100) {
+            k->exp100 = EXP100_SEND_DATA;
+            k->keepon |= KEEP_SEND;
+          }
+          break;
+        case 101:
+          /* Switching Protocols */
+          if(k->upgr101 == UPGR101_REQUESTED) {
+            infof(data, "Received 101\n");
+            k->upgr101 = UPGR101_RECEIVED;
+
+            /* switch to http2 now. The bytes after response headers
+               are also processed here, otherwise they are lost. */
+            result = Curl_http2_switched(conn, k->str, *nread);
+            if(result)
+              return result;
+            *nread = 0;
+          }
+          break;
+        default:
+          break;
+        }
+      }
+      else {
+        k->header = FALSE; /* no more header to parse! */
+
+        if((k->size == -1) && !k->chunk && !conn->bits.close &&
+           (conn->httpversion == 11) &&
+           !(conn->handler->protocol & CURLPROTO_RTSP) &&
+           data->set.httpreq != HTTPREQ_HEAD) {
+          /* On HTTP 1.1, when connection is not to get closed, but no
+             Content-Length nor Content-Encoding chunked have been
+             received, according to RFC2616 section 4.4 point 5, we
+             assume that the server will close the connection to
+             signal the end of the document. */
+          infof(data, "no chunk, no close, no size. Assume close to "
+                "signal end\n");
+          connclose(conn, "HTTP: No end-of-message indicator");
+        }
+      }
+
+      /* At this point we have some idea about the fate of the connection.
+         If we are closing the connection it may result auth failure. */
+#if defined(USE_NTLM)
+      if(conn->bits.close &&
+         (((data->req.httpcode == 401) &&
+           (conn->ntlm.state == NTLMSTATE_TYPE2)) ||
+          ((data->req.httpcode == 407) &&
+           (conn->proxyntlm.state == NTLMSTATE_TYPE2)))) {
+        infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
+        data->state.authproblem = TRUE;
+      }
+#endif
+
+      /*
+       * When all the headers have been parsed, see if we should give
+       * up and return an error.
+       */
+      if(http_should_fail(conn)) {
+        failf (data, "The requested URL returned error: %d",
+               k->httpcode);
+        return CURLE_HTTP_RETURNED_ERROR;
+      }
+
+      /* now, only output this if the header AND body are requested:
+       */
+      writetype = CLIENTWRITE_HEADER;
+      if(data->set.include_header)
+        writetype |= CLIENTWRITE_BODY;
+
+      headerlen = k->p - data->state.headerbuff;
+
+      result = Curl_client_write(conn, writetype,
+                                 data->state.headerbuff,
+                                 headerlen);
+      if(result)
+        return result;
+
+      data->info.header_size += (long)headerlen;
+      data->req.headerbytecount += (long)headerlen;
+
+      data->req.deductheadercount =
+        (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
+
+      if(!*stop_reading) {
+        /* Curl_http_auth_act() checks what authentication methods
+         * that are available and decides which one (if any) to
+         * use. It will set 'newurl' if an auth method was picked. */
+        result = Curl_http_auth_act(conn);
+
+        if(result)
+          return result;
+
+        if(k->httpcode >= 300) {
+          if((!conn->bits.authneg) && !conn->bits.close &&
+             !conn->bits.rewindaftersend) {
+            /*
+             * General treatment of errors when about to send data. Including :
+             * "417 Expectation Failed", while waiting for 100-continue.
+             *
+             * The check for close above is done simply because of something
+             * else has already deemed the connection to get closed then
+             * something else should've considered the big picture and we
+             * avoid this check.
+             *
+             * rewindaftersend indicates that something has told libcurl to
+             * continue sending even if it gets discarded
+             */
+
+            switch(data->set.httpreq) {
+            case HTTPREQ_PUT:
+            case HTTPREQ_POST:
+            case HTTPREQ_POST_FORM:
+              /* We got an error response. If this happened before the whole
+               * request body has been sent we stop sending and mark the
+               * connection for closure after we've read the entire response.
+               */
+              if(!k->upload_done) {
+                infof(data, "HTTP error before end of send, stop sending\n");
+                connclose(conn, "Stop sending data before everything sent");
+                k->upload_done = TRUE;
+                k->keepon &= ~KEEP_SEND; /* don't send */
+                if(data->state.expect100header)
+                  k->exp100 = EXP100_FAILED;
+              }
+              break;
+
+            default: /* default label present to avoid compiler warnings */
+              break;
+            }
+          }
+        }
+
+        if(conn->bits.rewindaftersend) {
+          /* We rewind after a complete send, so thus we continue
+             sending now */
+          infof(data, "Keep sending data to get tossed away!\n");
+          k->keepon |= KEEP_SEND;
+        }
+      }
+
+      if(!k->header) {
+        /*
+         * really end-of-headers.
+         *
+         * If we requested a "no body", this is a good time to get
+         * out and return home.
+         */
+        if(data->set.opt_no_body)
+          *stop_reading = TRUE;
+#ifndef CURL_DISABLE_RTSP
+        else if((conn->handler->protocol & CURLPROTO_RTSP) &&
+                (data->set.rtspreq == RTSPREQ_DESCRIBE) &&
+                (k->size <= -1))
+          /* Respect section 4.4 of rfc2326: If the Content-Length header is
+             absent, a length 0 must be assumed.  It will prevent libcurl from
+             hanging on DECRIBE request that got refused for whatever
+             reason */
+          *stop_reading = TRUE;
+#endif
+        else {
+          /* If we know the expected size of this document, we set the
+             maximum download size to the size of the expected
+             document or else, we won't know when to stop reading!
+
+             Note that we set the download maximum even if we read a
+             "Connection: close" header, to make sure that
+             "Content-Length: 0" still prevents us from attempting to
+             read the (missing) response-body.
+          */
+          /* According to RFC2616 section 4.4, we MUST ignore
+             Content-Length: headers if we are now receiving data
+             using chunked Transfer-Encoding.
+          */
+          if(k->chunk)
+            k->maxdownload = k->size = -1;
+        }
+        if(-1 != k->size) {
+          /* We do this operation even if no_body is true, since this
+             data might be retrieved later with curl_easy_getinfo()
+             and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
+
+          Curl_pgrsSetDownloadSize(data, k->size);
+          k->maxdownload = k->size;
+        }
+
+        /* If max download size is *zero* (nothing) we already
+           have nothing and can safely return ok now! */
+        if(0 == k->maxdownload)
+          *stop_reading = TRUE;
+
+        if(*stop_reading) {
+          /* we make sure that this socket isn't read more now */
+          k->keepon &= ~KEEP_RECV;
+        }
+
+        if(data->set.verbose)
+          Curl_debug(data, CURLINFO_HEADER_IN,
+                     k->str_start, headerlen, conn);
+        break;          /* exit header line loop */
+      }
+
+      /* We continue reading headers, so reset the line-based
+         header parsing variables hbufp && hbuflen */
+      k->hbufp = data->state.headerbuff;
+      k->hbuflen = 0;
+      continue;
+    }
+
+    /*
+     * Checks for special headers coming up.
+     */
+
+    if(!k->headerline++) {
+      /* This is the first header, it MUST be the error code line
+         or else we consider this to be the body right away! */
+      int httpversion_major;
+      int rtspversion_major;
+      int nc = 0;
+#ifdef CURL_DOES_CONVERSIONS
+#define HEADER1 scratch
+#define SCRATCHSIZE 21
+      CURLcode res;
+      char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
+      /* We can't really convert this yet because we
+         don't know if it's the 1st header line or the body.
+         So we do a partial conversion into a scratch area,
+         leaving the data at k->p as-is.
+      */
+      strncpy(&scratch[0], k->p, SCRATCHSIZE);
+      scratch[SCRATCHSIZE] = 0; /* null terminate */
+      res = Curl_convert_from_network(data,
+                                      &scratch[0],
+                                      SCRATCHSIZE);
+      if(res)
+        /* Curl_convert_from_network calls failf if unsuccessful */
+        return res;
+#else
+#define HEADER1 k->p /* no conversion needed, just use k->p */
+#endif /* CURL_DOES_CONVERSIONS */
+
+      if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
+        /*
+         * https://tools.ietf.org/html/rfc7230#section-3.1.2
+         *
+         * The reponse code is always a three-digit number in HTTP as the spec
+         * says. We try to allow any number here, but we cannot make
+         * guarantees on future behaviors since it isn't within the protocol.
+         */
+        nc = sscanf(HEADER1,
+                    " HTTP/%d.%d %d",
+                    &httpversion_major,
+                    &conn->httpversion,
+                    &k->httpcode);
+        if(nc==3) {
+          conn->httpversion += 10 * httpversion_major;
+
+          if(k->upgr101 == UPGR101_RECEIVED) {
+            /* supposedly upgraded to http2 now */
+            if(conn->httpversion != 20)
+              infof(data, "Lying server, not serving HTTP/2\n");
+          }
+        }
+        else {
+          /* this is the real world, not a Nirvana
+             NCSA 1.5.x returns this crap when asked for HTTP/1.1
+          */
+          nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
+          conn->httpversion = 10;
+
+          /* If user has set option HTTP200ALIASES,
+             compare header line against list of aliases
+          */
+          if(!nc) {
+            if(checkhttpprefix(data, k->p)) {
+              nc = 1;
+              k->httpcode = 200;
+              conn->httpversion = 10;
+            }
+          }
+        }
+      }
+      else if(conn->handler->protocol & CURLPROTO_RTSP) {
+        nc = sscanf(HEADER1,
+                    " RTSP/%d.%d %3d",
+                    &rtspversion_major,
+                    &conn->rtspversion,
+                    &k->httpcode);
+        if(nc==3) {
+          conn->rtspversion += 10 * rtspversion_major;
+          conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
+        }
+        else {
+          /* TODO: do we care about the other cases here? */
+          nc = 0;
+        }
+      }
+
+      if(nc) {
+        data->info.httpcode = k->httpcode;
+
+        data->info.httpversion = conn->httpversion;
+        if(!data->state.httpversion ||
+           data->state.httpversion > conn->httpversion)
+          /* store the lowest server version we encounter */
+          data->state.httpversion = conn->httpversion;
+
+        /*
+         * This code executes as part of processing the header.  As a
+         * result, it's not totally clear how to interpret the
+         * response code yet as that depends on what other headers may
+         * be present.  401 and 407 may be errors, but may be OK
+         * depending on how authentication is working.  Other codes
+         * are definitely errors, so give up here.
+         */
+        if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
+           ((k->httpcode != 401) || !conn->bits.user_passwd) &&
+           ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
+
+          if(data->state.resume_from &&
+             (data->set.httpreq==HTTPREQ_GET) &&
+             (k->httpcode == 416)) {
+            /* "Requested Range Not Satisfiable", just proceed and
+               pretend this is no error */
+          }
+          else {
+            /* serious error, go home! */
+            print_http_error(data);
+            return CURLE_HTTP_RETURNED_ERROR;
+          }
+        }
+
+        if(conn->httpversion == 10) {
+          /* Default action for HTTP/1.0 must be to close, unless
+             we get one of those fancy headers that tell us the
+             server keeps it open for us! */
+          infof(data, "HTTP 1.0, assume close after body\n");
+          connclose(conn, "HTTP/1.0 close after body");
+        }
+        else if(conn->httpversion == 20 ||
+                (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
+          DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
+
+          /* HTTP/2 cannot blacklist multiplexing since it is a core
+             functionality of the protocol */
+          conn->bundle->multiuse = BUNDLE_MULTIPLEX;
+        }
+        else if(conn->httpversion >= 11 &&
+                !conn->bits.close) {
+          /* If HTTP version is >= 1.1 and connection is persistent
+             server supports pipelining. */
+          DEBUGF(infof(data,
+                       "HTTP 1.1 or later with persistent connection, "
+                       "pipelining supported\n"));
+          /* Activate pipelining if needed */
+          if(conn->bundle) {
+            if(!Curl_pipeline_site_blacklisted(data, conn))
+              conn->bundle->multiuse = BUNDLE_PIPELINING;
+          }
+        }
+
+        switch(k->httpcode) {
+        case 204:
+          /* (quote from RFC2616, section 10.2.5): The server has
+           * fulfilled the request but does not need to return an
+           * entity-body ... The 204 response MUST NOT include a
+           * message-body, and thus is always terminated by the first
+           * empty line after the header fields. */
+          /* FALLTHROUGH */
+        case 304:
+          /* (quote from RFC2616, section 10.3.5): The 304 response
+           * MUST NOT contain a message-body, and thus is always
+           * terminated by the first empty line after the header
+           * fields.  */
+          if(data->set.timecondition)
+            data->info.timecond = TRUE;
+          k->size=0;
+          k->maxdownload=0;
+          k->ignorecl = TRUE; /* ignore Content-Length headers */
+          break;
+        default:
+          /* nothing */
+          break;
+        }
+      }
+      else {
+        k->header = FALSE;   /* this is not a header line */
+        break;
+      }
+    }
+
+    result = Curl_convert_from_network(data, k->p, strlen(k->p));
+    /* Curl_convert_from_network calls failf if unsuccessful */
+    if(result)
+      return result;
+
+    /* Check for Content-Length: header lines to get size */
+    if(!k->ignorecl && !data->set.ignorecl &&
+       checkprefix("Content-Length:", k->p)) {
+      curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
+      if(data->set.max_filesize &&
+         contentlength > data->set.max_filesize) {
+        failf(data, "Maximum file size exceeded");
+        return CURLE_FILESIZE_EXCEEDED;
+      }
+      if(contentlength >= 0) {
+        k->size = contentlength;
+        k->maxdownload = k->size;
+        /* we set the progress download size already at this point
+           just to make it easier for apps/callbacks to extract this
+           info as soon as possible */
+        Curl_pgrsSetDownloadSize(data, k->size);
+      }
+      else {
+        /* Negative Content-Length is really odd, and we know it
+           happens for example when older Apache servers send large
+           files */
+        connclose(conn, "negative content-length");
+        infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T
+              ", closing after transfer\n", contentlength);
+      }
+    }
+    /* check for Content-Type: header lines to get the MIME-type */
+    else if(checkprefix("Content-Type:", k->p)) {
+      char *contenttype = Curl_copy_header_value(k->p);
+      if(!contenttype)
+        return CURLE_OUT_OF_MEMORY;
+      if(!*contenttype)
+        /* ignore empty data */
+        free(contenttype);
+      else {
+        Curl_safefree(data->info.contenttype);
+        data->info.contenttype = contenttype;
+      }
+    }
+    else if(checkprefix("Server:", k->p)) {
+      if(conn->httpversion < 20) {
+        /* only do this for non-h2 servers */
+        char *server_name = Curl_copy_header_value(k->p);
+
+        /* Turn off pipelining if the server version is blacklisted  */
+        if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) {
+          if(Curl_pipeline_server_blacklisted(data, server_name))
+            conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
+        }
+        free(server_name);
+      }
+    }
+    else if((conn->httpversion == 10) &&
+            conn->bits.httpproxy &&
+            Curl_compareheader(k->p,
+                               "Proxy-Connection:", "keep-alive")) {
+      /*
+       * When a HTTP/1.0 reply comes when using a proxy, the
+       * 'Proxy-Connection: keep-alive' line tells us the
+       * connection will be kept alive for our pleasure.
+       * Default action for 1.0 is to close.
+       */
+      connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */
+      infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
+    }
+    else if((conn->httpversion == 11) &&
+            conn->bits.httpproxy &&
+            Curl_compareheader(k->p,
+                               "Proxy-Connection:", "close")) {
+      /*
+       * We get a HTTP/1.1 response from a proxy and it says it'll
+       * close down after this transfer.
+       */
+      connclose(conn, "Proxy-Connection: asked to close after done");
+      infof(data, "HTTP/1.1 proxy connection set close!\n");
+    }
+    else if((conn->httpversion == 10) &&
+            Curl_compareheader(k->p, "Connection:", "keep-alive")) {
+      /*
+       * A HTTP/1.0 reply with the 'Connection: keep-alive' line
+       * tells us the connection will be kept alive for our
+       * pleasure.  Default action for 1.0 is to close.
+       *
+       * [RFC2068, section 19.7.1] */
+      connkeep(conn, "Connection keep-alive");
+      infof(data, "HTTP/1.0 connection set to keep alive!\n");
+    }
+    else if(Curl_compareheader(k->p, "Connection:", "close")) {
+      /*
+       * [RFC 2616, section 8.1.2.1]
+       * "Connection: close" is HTTP/1.1 language and means that
+       * the connection will close when this request has been
+       * served.
+       */
+      connclose(conn, "Connection: close used");
+    }
+    else if(checkprefix("Transfer-Encoding:", k->p)) {
+      /* One or more encodings. We check for chunked and/or a compression
+         algorithm. */
+      /*
+       * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
+       * means that the server will send a series of "chunks". Each
+       * chunk starts with line with info (including size of the
+       * coming block) (terminated with CRLF), then a block of data
+       * with the previously mentioned size. There can be any amount
+       * of chunks, and a chunk-data set to zero signals the
+       * end-of-chunks. */
+
+      char *start;
+
+      /* Find the first non-space letter */
+      start = k->p + 18;
+
+      for(;;) {
+        /* skip whitespaces and commas */
+        while(*start && (ISSPACE(*start) || (*start == ',')))
+          start++;
+
+        if(checkprefix("chunked", start)) {
+          k->chunk = TRUE; /* chunks coming our way */
+
+          /* init our chunky engine */
+          Curl_httpchunk_init(conn);
+
+          start += 7;
+        }
+
+        if(k->auto_decoding)
+          /* TODO: we only support the first mentioned compression for now */
+          break;
+
+        if(checkprefix("identity", start)) {
+          k->auto_decoding = IDENTITY;
+          start += 8;
+        }
+        else if(checkprefix("deflate", start)) {
+          k->auto_decoding = DEFLATE;
+          start += 7;
+        }
+        else if(checkprefix("gzip", start)) {
+          k->auto_decoding = GZIP;
+          start += 4;
+        }
+        else if(checkprefix("x-gzip", start)) {
+          k->auto_decoding = GZIP;
+          start += 6;
+        }
+        else
+          /* unknown! */
+          break;
+
+      }
+
+    }
+    else if(checkprefix("Content-Encoding:", k->p) &&
+            (data->set.str[STRING_ENCODING] ||
+             conn->httpversion == 20)) {
+      /*
+       * Process Content-Encoding. Look for the values: identity,
+       * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
+       * x-compress are the same as gzip and compress. (Sec 3.5 RFC
+       * 2616). zlib cannot handle compress.  However, errors are
+       * handled further down when the response body is processed
+       */
+      char *start;
+
+      /* Find the first non-space letter */
+      start = k->p + 17;
+      while(*start && ISSPACE(*start))
+        start++;
+
+      /* Record the content-encoding for later use */
+      if(checkprefix("identity", start))
+        k->auto_decoding = IDENTITY;
+      else if(checkprefix("deflate", start))
+        k->auto_decoding = DEFLATE;
+      else if(checkprefix("gzip", start)
+              || checkprefix("x-gzip", start))
+        k->auto_decoding = GZIP;
+    }
+    else if(checkprefix("Content-Range:", k->p)) {
+      /* Content-Range: bytes [num]-
+         Content-Range: bytes: [num]-
+         Content-Range: [num]-
+         Content-Range: [asterisk]/[total]
+
+         The second format was added since Sun's webserver
+         JavaWebServer/1.1.1 obviously sends the header this way!
+         The third added since some servers use that!
+         The forth means the requested range was unsatisfied.
+      */
+
+      char *ptr = k->p + 14;
+
+      /* Move forward until first digit or asterisk */
+      while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
+        ptr++;
+
+      /* if it truly stopped on a digit */
+      if(ISDIGIT(*ptr)) {
+        k->offset = curlx_strtoofft(ptr, NULL, 10);
+
+        if(data->state.resume_from == k->offset)
+          /* we asked for a resume and we got it */
+          k->content_range = TRUE;
+      }
+      else
+        data->state.resume_from = 0; /* get everything */
+    }
+#if !defined(CURL_DISABLE_COOKIES)
+    else if(data->cookies &&
+            checkprefix("Set-Cookie:", k->p)) {
+      Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
+                      CURL_LOCK_ACCESS_SINGLE);
+      Curl_cookie_add(data,
+                      data->cookies, TRUE, k->p+11,
+                      /* If there is a custom-set Host: name, use it
+                         here, or else use real peer host name. */
+                      conn->allocptr.cookiehost?
+                      conn->allocptr.cookiehost:conn->host.name,
+                      data->state.path);
+      Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+    }
+#endif
+    else if(checkprefix("Last-Modified:", k->p) &&
+            (data->set.timecondition || data->set.get_filetime) ) {
+      time_t secs=time(NULL);
+      k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
+                                  &secs);
+      if(data->set.get_filetime)
+        data->info.filetime = (long)k->timeofdoc;
+    }
+    else if((checkprefix("WWW-Authenticate:", k->p) &&
+             (401 == k->httpcode)) ||
+            (checkprefix("Proxy-authenticate:", k->p) &&
+             (407 == k->httpcode))) {
+
+      bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
+      char *auth = Curl_copy_header_value(k->p);
+      if(!auth)
+        return CURLE_OUT_OF_MEMORY;
+
+      result = Curl_http_input_auth(conn, proxy, auth);
+
+      free(auth);
+
+      if(result)
+        return result;
+    }
+    else if((k->httpcode >= 300 && k->httpcode < 400) &&
+            checkprefix("Location:", k->p) &&
+            !data->req.location) {
+      /* this is the URL that the server advises us to use instead */
+      char *location = Curl_copy_header_value(k->p);
+      if(!location)
+        return CURLE_OUT_OF_MEMORY;
+      if(!*location)
+        /* ignore empty data */
+        free(location);
+      else {
+        data->req.location = location;
+
+        if(data->set.http_follow_location) {
+          DEBUGASSERT(!data->req.newurl);
+          data->req.newurl = strdup(data->req.location); /* clone */
+          if(!data->req.newurl)
+            return CURLE_OUT_OF_MEMORY;
+
+          /* some cases of POST and PUT etc needs to rewind the data
+             stream at this point */
+          result = http_perhapsrewind(conn);
+          if(result)
+            return result;
+        }
+      }
+    }
+    else if(conn->handler->protocol & CURLPROTO_RTSP) {
+      result = Curl_rtsp_parseheader(conn, k->p);
+      if(result)
+        return result;
+    }
+
+    /*
+     * End of header-checks. Write them to the client.
+     */
+
+    writetype = CLIENTWRITE_HEADER;
+    if(data->set.include_header)
+      writetype |= CLIENTWRITE_BODY;
+
+    if(data->set.verbose)
+      Curl_debug(data, CURLINFO_HEADER_IN,
+                 k->p, (size_t)k->hbuflen, conn);
+
+    result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
+    if(result)
+      return result;
+
+    data->info.header_size += (long)k->hbuflen;
+    data->req.headerbytecount += (long)k->hbuflen;
+
+    /* reset hbufp pointer && hbuflen */
+    k->hbufp = data->state.headerbuff;
+    k->hbuflen = 0;
+  }
+  while(!*stop_reading && *k->str); /* header line within buffer */
+
+  /* We might have reached the end of the header part here, but
+     there might be a non-header part left in the end of the read
+     buffer. */
+
+  return CURLE_OK;
+}
+
+#endif /* CURL_DISABLE_HTTP */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/http.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/http.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/http.h	(revision 164)
@@ -0,0 +1,252 @@
+#ifndef HEADER_CURL_HTTP_H
+#define HEADER_CURL_HTTP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_HTTP
+
+#ifdef USE_NGHTTP2
+#include <nghttp2/nghttp2.h>
+#endif
+
+extern const struct Curl_handler Curl_handler_http;
+
+#ifdef USE_SSL
+extern const struct Curl_handler Curl_handler_https;
+#endif
+
+/* Header specific functions */
+bool Curl_compareheader(const char *headerline,  /* line to check */
+                        const char *header,   /* header keyword _with_ colon */
+                        const char *content); /* content string to find */
+
+char *Curl_checkheaders(const struct connectdata *conn,
+                        const char *thisheader);
+char *Curl_copy_header_value(const char *header);
+
+char *Curl_checkProxyheaders(const struct connectdata *conn,
+                             const char *thisheader);
+/* ------------------------------------------------------------------------- */
+/*
+ * The add_buffer series of functions are used to build one large memory chunk
+ * from repeated function invokes. Used so that the entire HTTP request can
+ * be sent in one go.
+ */
+struct Curl_send_buffer {
+  char *buffer;
+  size_t size_max;
+  size_t size_used;
+};
+typedef struct Curl_send_buffer Curl_send_buffer;
+
+Curl_send_buffer *Curl_add_buffer_init(void);
+void Curl_add_buffer_free(Curl_send_buffer *buff);
+CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...);
+CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size);
+CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
+                              struct connectdata *conn,
+                              long *bytes_written,
+                              size_t included_body_bytes,
+                              int socketindex);
+
+CURLcode Curl_add_timecondition(struct SessionHandle *data,
+                                Curl_send_buffer *buf);
+CURLcode Curl_add_custom_headers(struct connectdata *conn,
+                                 bool is_connect,
+                                 Curl_send_buffer *req_buffer);
+
+/* protocol-specific functions set up to be called by the main engine */
+CURLcode Curl_http(struct connectdata *conn, bool *done);
+CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
+CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
+CURLcode Curl_http_setup_conn(struct connectdata *conn);
+
+/* The following functions are defined in http_chunks.c */
+void Curl_httpchunk_init(struct connectdata *conn);
+CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
+                              ssize_t length, ssize_t *wrote);
+
+/* These functions are in http.c */
+void Curl_http_auth_stage(struct SessionHandle *data, int stage);
+CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
+                              const char *auth);
+CURLcode Curl_http_auth_act(struct connectdata *conn);
+CURLcode Curl_http_perhapsrewind(struct connectdata *conn);
+
+/* If only the PICKNONE bit is set, there has been a round-trip and we
+   selected to use no auth at all. Ie, we actively select no auth, as opposed
+   to not having one selected. The other CURLAUTH_* defines are present in the
+   public curl/curl.h header. */
+#define CURLAUTH_PICKNONE (1<<30) /* don't use auth */
+
+/* MAX_INITIAL_POST_SIZE indicates the number of bytes that will make the POST
+   data get included in the initial data chunk sent to the server. If the
+   data is larger than this, it will automatically get split up in multiple
+   system calls.
+
+   This value used to be fairly big (100K), but we must take into account that
+   if the server rejects the POST due for authentication reasons, this data
+   will always be uncondtionally sent and thus it may not be larger than can
+   always be afforded to send twice.
+
+   It must not be greater than 64K to work on VMS.
+*/
+#ifndef MAX_INITIAL_POST_SIZE
+#define MAX_INITIAL_POST_SIZE (64*1024)
+#endif
+
+#ifndef TINY_INITIAL_POST_SIZE
+#define TINY_INITIAL_POST_SIZE 1024
+#endif
+
+#endif /* CURL_DISABLE_HTTP */
+
+/****************************************************************************
+ * HTTP unique setup
+ ***************************************************************************/
+struct HTTP {
+  struct FormData *sendit;
+  curl_off_t postsize; /* off_t to handle large file sizes */
+  const char *postdata;
+
+  const char *p_pragma;      /* Pragma: string */
+  const char *p_accept;      /* Accept: string */
+  curl_off_t readbytecount;
+  curl_off_t writebytecount;
+
+  /* For FORM posting */
+  struct Form form;
+
+  struct back {
+    curl_read_callback fread_func; /* backup storage for fread pointer */
+    void *fread_in;           /* backup storage for fread_in pointer */
+    const char *postdata;
+    curl_off_t postsize;
+  } backup;
+
+  enum {
+    HTTPSEND_NADA,    /* init */
+    HTTPSEND_REQUEST, /* sending a request */
+    HTTPSEND_BODY,    /* sending body */
+    HTTPSEND_LAST     /* never use this */
+  } sending;
+
+  void *send_buffer; /* used if the request couldn't be sent in one chunk,
+                        points to an allocated send_buffer struct */
+
+#ifdef USE_NGHTTP2
+  /*********** for HTTP/2 we store stream-local data here *************/
+  int32_t stream_id; /* stream we are interested in */
+
+  bool bodystarted;
+  /* We store non-final and final response headers here, per-stream */
+  Curl_send_buffer *header_recvbuf;
+  size_t nread_header_recvbuf; /* number of bytes in header_recvbuf fed into
+                                  upper layer */
+  Curl_send_buffer *trailer_recvbuf;
+  int status_code; /* HTTP status code */
+  const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
+  size_t pauselen; /* the number of bytes left in data */
+  bool closed; /* TRUE on HTTP2 stream close */
+  uint32_t error_code; /* HTTP/2 error code */
+
+  char *mem;     /* points to a buffer in memory to store received data */
+  size_t len;    /* size of the buffer 'mem' points to */
+  size_t memlen; /* size of data copied to mem */
+
+  const uint8_t *upload_mem; /* points to a buffer to read from */
+  size_t upload_len; /* size of the buffer 'upload_mem' points to */
+  curl_off_t upload_left; /* number of bytes left to upload */
+
+  char **push_headers;       /* allocated array */
+  size_t push_headers_used;  /* number of entries filled in */
+  size_t push_headers_alloc; /* number of entries allocated */
+#endif
+};
+
+typedef int (*sending)(void); /* Curl_send */
+typedef int (*recving)(void); /* Curl_recv */
+
+#ifdef USE_NGHTTP2
+/* h2 settings for this connection */
+struct h2settings {
+  uint32_t max_concurrent_streams;
+  bool enable_push;
+};
+#endif
+
+
+struct http_conn {
+#ifdef USE_NGHTTP2
+#define H2_BINSETTINGS_LEN 80
+  nghttp2_session *h2;
+  uint8_t binsettings[H2_BINSETTINGS_LEN];
+  size_t  binlen; /* length of the binsettings data */
+  sending send_underlying; /* underlying send Curl_send callback */
+  recving recv_underlying; /* underlying recv Curl_recv callback */
+  char *inbuf; /* buffer to receive data from underlying socket */
+  size_t inbuflen; /* number of bytes filled in inbuf */
+  size_t nread_inbuf; /* number of bytes read from in inbuf */
+  /* We need separate buffer for transmission and reception because we
+     may call nghttp2_session_send() after the
+     nghttp2_session_mem_recv() but mem buffer is still not full. In
+     this case, we wrongly sends the content of mem buffer if we share
+     them for both cases. */
+  int32_t pause_stream_id; /* stream ID which paused
+                              nghttp2_session_mem_recv */
+
+  /* this is a hash of all individual streams (SessionHandle structs) */
+  struct h2settings settings;
+#else
+  int unused; /* prevent a compiler warning */
+#endif
+};
+
+CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
+                                     struct connectdata *conn,
+                                     ssize_t *nread,
+                                     bool *stop_reading);
+
+/**
+ * Curl_http_output_auth() setups the authentication headers for the
+ * host/proxy and the correct authentication
+ * method. conn->data->state.authdone is set to TRUE when authentication is
+ * done.
+ *
+ * @param conn all information about the current connection
+ * @param request pointer to the request keyword
+ * @param path pointer to the requested path
+ * @param proxytunnel boolean if this is the request setting up a "proxy
+ * tunnel"
+ *
+ * @returns CURLcode
+ */
+CURLcode
+Curl_http_output_auth(struct connectdata *conn,
+                      const char *request,
+                      const char *path,
+                      bool proxytunnel); /* TRUE if this is the request setting
+                                            up the proxy tunnel */
+
+#endif /* HEADER_CURL_HTTP_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/http2.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/http2.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/http2.c	(revision 164)
@@ -0,0 +1,1709 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_NGHTTP2
+#include "curl_printf.h"
+#include <nghttp2/nghttp2.h>
+#include "urldata.h"
+#include "http2.h"
+#include "http.h"
+#include "sendf.h"
+#include "curl_base64.h"
+#include "rawstr.h"
+#include "multiif.h"
+#include "conncache.h"
+#include "url.h"
+#include "connect.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define MIN(x,y) ((x)<(y)?(x):(y))
+
+#if (NGHTTP2_VERSION_NUM < 0x010000)
+#error too old nghttp2 version, upgrade!
+#endif
+
+/*
+ * Curl_http2_init_state() is called when the easy handle is created and
+ * allows for HTTP/2 specific init of state.
+ */
+void Curl_http2_init_state(struct UrlState *state)
+{
+  state->stream_weight = NGHTTP2_DEFAULT_WEIGHT;
+}
+
+/*
+ * Curl_http2_init_userset() is called when the easy handle is created and
+ * allows for HTTP/2 specific user-set fields.
+ */
+void Curl_http2_init_userset(struct UserDefined *set)
+{
+  set->stream_weight = NGHTTP2_DEFAULT_WEIGHT;
+}
+
+static int http2_perform_getsock(const struct connectdata *conn,
+                                 curl_socket_t *sock, /* points to
+                                                         numsocks
+                                                         number of
+                                                         sockets */
+                                 int numsocks)
+{
+  const struct http_conn *c = &conn->proto.httpc;
+  int bitmap = GETSOCK_BLANK;
+  (void)numsocks;
+
+  /* TODO We should check underlying socket state if it is SSL socket
+     because of renegotiation. */
+  sock[0] = conn->sock[FIRSTSOCKET];
+
+  if(nghttp2_session_want_read(c->h2))
+    bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+
+  if(nghttp2_session_want_write(c->h2))
+    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
+
+  return bitmap;
+}
+
+static int http2_getsock(struct connectdata *conn,
+                         curl_socket_t *sock, /* points to numsocks
+                                                 number of sockets */
+                         int numsocks)
+{
+  return http2_perform_getsock(conn, sock, numsocks);
+}
+
+static CURLcode http2_disconnect(struct connectdata *conn,
+                                 bool dead_connection)
+{
+  struct HTTP *http = conn->data->req.protop;
+  struct http_conn *c = &conn->proto.httpc;
+  (void)dead_connection;
+
+  DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));
+
+  nghttp2_session_del(c->h2);
+  Curl_safefree(c->inbuf);
+
+  if(http) {
+    Curl_add_buffer_free(http->header_recvbuf);
+    http->header_recvbuf = NULL; /* clear the pointer */
+    Curl_add_buffer_free(http->trailer_recvbuf);
+    http->trailer_recvbuf = NULL; /* clear the pointer */
+    for(; http->push_headers_used > 0; --http->push_headers_used) {
+      free(http->push_headers[http->push_headers_used - 1]);
+    }
+    free(http->push_headers);
+    http->push_headers = NULL;
+  }
+
+  DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
+
+  return CURLE_OK;
+}
+
+/* called from Curl_http_setup_conn */
+void Curl_http2_setup_req(struct SessionHandle *data)
+{
+  struct HTTP *http = data->req.protop;
+
+  http->nread_header_recvbuf = 0;
+  http->bodystarted = FALSE;
+  http->status_code = -1;
+  http->pausedata = NULL;
+  http->pauselen = 0;
+  http->error_code = NGHTTP2_NO_ERROR;
+  http->closed = FALSE;
+  http->mem = data->state.buffer;
+  http->len = BUFSIZE;
+  http->memlen = 0;
+}
+
+/* called from Curl_http_setup_conn */
+void Curl_http2_setup_conn(struct connectdata *conn)
+{
+  conn->proto.httpc.settings.max_concurrent_streams =
+    DEFAULT_MAX_CONCURRENT_STREAMS;
+}
+
+/*
+ * HTTP2 handler interface. This isn't added to the general list of protocols
+ * but will be used at run-time when the protocol is dynamically switched from
+ * HTTP to HTTP2.
+ */
+const struct Curl_handler Curl_handler_http2 = {
+  "HTTP2",                              /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  http2_getsock,                        /* proto_getsock */
+  http2_getsock,                        /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  http2_perform_getsock,                /* perform_getsock */
+  http2_disconnect,                     /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_HTTP,                            /* defport */
+  CURLPROTO_HTTP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+const struct Curl_handler Curl_handler_http2_ssl = {
+  "HTTP2",                              /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  http2_getsock,                        /* proto_getsock */
+  http2_getsock,                        /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  http2_perform_getsock,                /* perform_getsock */
+  http2_disconnect,                     /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_HTTP,                            /* defport */
+  CURLPROTO_HTTPS,                      /* protocol */
+  PROTOPT_SSL                           /* flags */
+};
+
+/*
+ * Store nghttp2 version info in this buffer, Prefix with a space.  Return
+ * total length written.
+ */
+int Curl_http2_ver(char *p, size_t len)
+{
+  nghttp2_info *h2 = nghttp2_version(0);
+  return snprintf(p, len, " nghttp2/%s", h2->version_str);
+}
+
+/*
+ * The implementation of nghttp2_send_callback type. Here we write |data| with
+ * size |length| to the network and return the number of bytes actually
+ * written. See the documentation of nghttp2_send_callback for the details.
+ */
+static ssize_t send_callback(nghttp2_session *h2,
+                             const uint8_t *data, size_t length, int flags,
+                             void *userp)
+{
+  struct connectdata *conn = (struct connectdata *)userp;
+  struct http_conn *c = &conn->proto.httpc;
+  ssize_t written;
+  CURLcode result = CURLE_OK;
+
+  (void)h2;
+  (void)flags;
+
+  written = ((Curl_send*)c->send_underlying)(conn, FIRSTSOCKET,
+                                             data, length, &result);
+
+  if(result == CURLE_AGAIN) {
+    return NGHTTP2_ERR_WOULDBLOCK;
+  }
+
+  if(written == -1) {
+    failf(conn->data, "Failed sending HTTP2 data");
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+
+  if(!written)
+    return NGHTTP2_ERR_WOULDBLOCK;
+
+  return written;
+}
+
+
+/* We pass a pointer to this struct in the push callback, but the contents of
+   the struct are hidden from the user. */
+struct curl_pushheaders {
+  struct SessionHandle *data;
+  const nghttp2_push_promise *frame;
+};
+
+/*
+ * push header access function. Only to be used from within the push callback
+ */
+char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
+{
+  /* Verify that we got a good easy handle in the push header struct, mostly to
+     detect rubbish input fast(er). */
+  if(!h || !GOOD_EASY_HANDLE(h->data))
+    return NULL;
+  else {
+    struct HTTP *stream = h->data->req.protop;
+    if(num < stream->push_headers_used)
+      return stream->push_headers[num];
+  }
+  return NULL;
+}
+
+/*
+ * push header access function. Only to be used from within the push callback
+ */
+char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
+{
+  /* Verify that we got a good easy handle in the push header struct,
+     mostly to detect rubbish input fast(er). Also empty header name
+     is just a rubbish too. We have to allow ":" at the beginning of
+     the header, but header == ":" must be rejected. If we have ':' in
+     the middle of header, it could be matched in middle of the value,
+     this is because we do prefix match.*/
+  if(!h || !GOOD_EASY_HANDLE(h->data) || !header || !header[0] ||
+     Curl_raw_equal(header, ":") || strchr(header + 1, ':'))
+    return NULL;
+  else {
+    struct HTTP *stream = h->data->req.protop;
+    size_t len = strlen(header);
+    size_t i;
+    for(i=0; i<stream->push_headers_used; i++) {
+      if(!strncmp(header, stream->push_headers[i], len)) {
+        /* sub-match, make sure that it is followed by a colon */
+        if(stream->push_headers[i][len] != ':')
+          continue;
+        return &stream->push_headers[i][len+1];
+      }
+    }
+  }
+  return NULL;
+}
+
+static CURL *duphandle(struct SessionHandle *data)
+{
+  struct SessionHandle *second = curl_easy_duphandle(data);
+  if(second) {
+    /* setup the request struct */
+    struct HTTP *http = calloc(1, sizeof(struct HTTP));
+    if(!http) {
+      (void)Curl_close(second);
+      second = NULL;
+    }
+    else {
+      second->req.protop = http;
+      http->header_recvbuf = Curl_add_buffer_init();
+      if(!http->header_recvbuf) {
+        free(http);
+        (void)Curl_close(second);
+        second = NULL;
+      }
+      else {
+        Curl_http2_setup_req(second);
+        second->state.stream_weight = data->state.stream_weight;
+      }
+    }
+  }
+  return second;
+}
+
+
+static int push_promise(struct SessionHandle *data,
+                        struct connectdata *conn,
+                        const nghttp2_push_promise *frame)
+{
+  int rv;
+  DEBUGF(infof(data, "PUSH_PROMISE received, stream %u!\n",
+               frame->promised_stream_id));
+  if(data->multi->push_cb) {
+    struct HTTP *stream;
+    struct HTTP *newstream;
+    struct curl_pushheaders heads;
+    CURLMcode rc;
+    struct http_conn *httpc;
+    size_t i;
+    /* clone the parent */
+    struct SessionHandle *newhandle = duphandle(data);
+    if(!newhandle) {
+      infof(data, "failed to duplicate handle\n");
+      rv = 1; /* FAIL HARD */
+      goto fail;
+    }
+
+    heads.data = data;
+    heads.frame = frame;
+    /* ask the application */
+    DEBUGF(infof(data, "Got PUSH_PROMISE, ask application!\n"));
+
+    stream = data->req.protop;
+    if(!stream) {
+      failf(data, "Internal NULL stream!\n");
+      rv = 1;
+      goto fail;
+    }
+
+    rv = data->multi->push_cb(data, newhandle,
+                              stream->push_headers_used, &heads,
+                              data->multi->push_userp);
+
+    /* free the headers again */
+    for(i=0; i<stream->push_headers_used; i++)
+      free(stream->push_headers[i]);
+    free(stream->push_headers);
+    stream->push_headers = NULL;
+
+    if(rv) {
+      /* denied, kill off the new handle again */
+      (void)Curl_close(newhandle);
+      goto fail;
+    }
+
+    newstream = newhandle->req.protop;
+    newstream->stream_id = frame->promised_stream_id;
+    newhandle->req.maxdownload = -1;
+    newhandle->req.size = -1;
+
+    /* approved, add to the multi handle and immediately switch to PERFORM
+       state with the given connection !*/
+    rc = Curl_multi_add_perform(data->multi, newhandle, conn);
+    if(rc) {
+      infof(data, "failed to add handle to multi\n");
+      Curl_close(newhandle);
+      rv = 1;
+      goto fail;
+    }
+
+    httpc = &conn->proto.httpc;
+    nghttp2_session_set_stream_user_data(httpc->h2,
+                                         frame->promised_stream_id, newhandle);
+  }
+  else {
+    DEBUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
+    rv = 1;
+  }
+  fail:
+  return rv;
+}
+
+static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
+                         void *userp)
+{
+  struct connectdata *conn = (struct connectdata *)userp;
+  struct http_conn *httpc = &conn->proto.httpc;
+  struct SessionHandle *data_s = NULL;
+  struct HTTP *stream = NULL;
+  static int lastStream = -1;
+  int rv;
+  size_t left, ncopy;
+  int32_t stream_id = frame->hd.stream_id;
+
+  if(!stream_id) {
+    /* stream ID zero is for connection-oriented stuff */
+    if(frame->hd.type == NGHTTP2_SETTINGS) {
+      uint32_t max_conn = httpc->settings.max_concurrent_streams;
+      DEBUGF(infof(conn->data, "Got SETTINGS\n"));
+      httpc->settings.max_concurrent_streams =
+        nghttp2_session_get_remote_settings(
+          session, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS);
+      httpc->settings.enable_push =
+        nghttp2_session_get_remote_settings(
+          session, NGHTTP2_SETTINGS_ENABLE_PUSH);
+      DEBUGF(infof(conn->data, "MAX_CONCURRENT_STREAMS == %d\n",
+                   httpc->settings.max_concurrent_streams));
+      DEBUGF(infof(conn->data, "ENABLE_PUSH == %s\n",
+                   httpc->settings.enable_push?"TRUE":"false"));
+      if(max_conn != httpc->settings.max_concurrent_streams) {
+        /* only signal change if the value actually changed */
+        infof(conn->data,
+              "Connection state changed (MAX_CONCURRENT_STREAMS updated)!\n");
+        Curl_multi_connchanged(conn->data->multi);
+      }
+    }
+    return 0;
+  }
+  data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+  if(lastStream != stream_id) {
+    lastStream = stream_id;
+  }
+  if(!data_s) {
+    DEBUGF(infof(conn->data,
+                 "No SessionHandle associated with stream: %x\n",
+                 stream_id));
+    return 0;
+  }
+
+  stream = data_s->req.protop;
+  if(!stream)
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+  DEBUGF(infof(data_s, "on_frame_recv() header %x stream %x\n",
+               frame->hd.type, stream_id));
+
+  switch(frame->hd.type) {
+  case NGHTTP2_DATA:
+    /* If body started on this stream, then receiving DATA is illegal. */
+    if(!stream->bodystarted) {
+      rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
+                                     stream_id, NGHTTP2_PROTOCOL_ERROR);
+
+      if(nghttp2_is_fatal(rv)) {
+        return NGHTTP2_ERR_CALLBACK_FAILURE;
+      }
+    }
+    break;
+  case NGHTTP2_HEADERS:
+    if(stream->bodystarted) {
+      /* Only valid HEADERS after body started is trailer HEADERS.  We
+         buffer them in on_header callback. */
+      break;
+    }
+
+    /* nghttp2 guarantees that :status is received, and we store it to
+       stream->status_code */
+    DEBUGASSERT(stream->status_code != -1);
+
+    /* Only final status code signals the end of header */
+    if(stream->status_code / 100 != 1) {
+      stream->bodystarted = TRUE;
+      stream->status_code = -1;
+    }
+
+    Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
+
+    left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
+    ncopy = MIN(stream->len, left);
+
+    memcpy(&stream->mem[stream->memlen],
+           stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
+           ncopy);
+    stream->nread_header_recvbuf += ncopy;
+
+    DEBUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p\n",
+                 ncopy, stream_id, stream->mem));
+
+    stream->len -= ncopy;
+    stream->memlen += ncopy;
+
+    data_s->state.drain++;
+    {
+      /* get the pointer from userp again since it was re-assigned above */
+      struct connectdata *conn_s = (struct connectdata *)userp;
+
+      /* if we receive data for another handle, wake that up */
+      if(conn_s->data != data_s)
+        Curl_expire(data_s, 1);
+    }
+    break;
+  case NGHTTP2_PUSH_PROMISE:
+    rv = push_promise(data_s, conn, &frame->push_promise);
+    if(rv) { /* deny! */
+      rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
+                                     frame->push_promise.promised_stream_id,
+                                     NGHTTP2_CANCEL);
+      if(nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+    }
+    break;
+  default:
+    DEBUGF(infof(conn->data, "Got frame type %x for stream %u!\n",
+                 frame->hd.type, stream_id));
+    break;
+  }
+  return 0;
+}
+
+static int on_invalid_frame_recv(nghttp2_session *session,
+                                 const nghttp2_frame *frame,
+                                 int lib_error_code, void *userp)
+{
+  struct SessionHandle *data_s = NULL;
+  (void)userp;
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(data_s) {
+    DEBUGF(infof(data_s,
+                 "on_invalid_frame_recv() was called, error=%d:%s\n",
+                 lib_error_code, nghttp2_strerror(lib_error_code)));
+  }
+  return 0;
+}
+
+static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
+                              int32_t stream_id,
+                              const uint8_t *data, size_t len, void *userp)
+{
+  struct HTTP *stream;
+  struct SessionHandle *data_s;
+  size_t nread;
+  struct connectdata *conn = (struct connectdata *)userp;
+  (void)session;
+  (void)flags;
+  (void)data;
+
+  DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
+
+  /* get the stream from the hash based on Stream ID */
+  data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+  if(!data_s)
+    /* Receiving a Stream ID not in the hash should not happen, this is an
+       internal error more than anything else! */
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+  stream = data_s->req.protop;
+  if(!stream)
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+  nread = MIN(stream->len, len);
+  memcpy(&stream->mem[stream->memlen], data, nread);
+
+  stream->len -= nread;
+  stream->memlen += nread;
+
+  data_s->state.drain++;
+
+  /* if we receive data for another handle, wake that up */
+  if(conn->data != data_s)
+    Curl_expire(data_s, 1); /* TODO: fix so that this can be set to 0 for
+                               immediately? */
+
+  DEBUGF(infof(data_s, "%zu data received for stream %u "
+               "(%zu left in buffer %p, total %zu)\n",
+               nread, stream_id,
+               stream->len, stream->mem,
+               stream->memlen));
+
+  if(nread < len) {
+    stream->pausedata = data + nread;
+    stream->pauselen = len - nread;
+    DEBUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer"
+                 ", stream %u\n",
+                 len - nread, stream_id));
+    data_s->easy_conn->proto.httpc.pause_stream_id = stream_id;
+    return NGHTTP2_ERR_PAUSE;
+  }
+  return 0;
+}
+
+static int before_frame_send(nghttp2_session *session,
+                             const nghttp2_frame *frame,
+                             void *userp)
+{
+  struct SessionHandle *data_s;
+  (void)userp;
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(data_s) {
+    DEBUGF(infof(data_s, "before_frame_send() was called\n"));
+  }
+
+  return 0;
+}
+static int on_frame_send(nghttp2_session *session,
+                         const nghttp2_frame *frame,
+                         void *userp)
+{
+  struct SessionHandle *data_s;
+  (void)userp;
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(data_s) {
+    DEBUGF(infof(data_s, "on_frame_send() was called, length = %zd\n",
+                 frame->hd.length));
+  }
+  return 0;
+}
+static int on_frame_not_send(nghttp2_session *session,
+                             const nghttp2_frame *frame,
+                             int lib_error_code, void *userp)
+{
+  struct SessionHandle *data_s;
+  (void)userp;
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(data_s) {
+    DEBUGF(infof(data_s,
+                 "on_frame_not_send() was called, lib_error_code = %d\n",
+                 lib_error_code));
+  }
+  return 0;
+}
+static int on_stream_close(nghttp2_session *session, int32_t stream_id,
+                           uint32_t error_code, void *userp)
+{
+  struct SessionHandle *data_s;
+  struct HTTP *stream;
+  (void)session;
+  (void)stream_id;
+  (void)userp;
+
+  if(stream_id) {
+    /* get the stream from the hash based on Stream ID, stream ID zero is for
+       connection-oriented stuff */
+    data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+    if(!data_s) {
+      /* We could get stream ID not in the hash.  For example, if we
+         decided to reject stream (e.g., PUSH_PROMISE). */
+      return 0;
+    }
+    DEBUGF(infof(data_s, "on_stream_close(), error_code = %d, stream %u\n",
+                 error_code, stream_id));
+    stream = data_s->req.protop;
+    if(!stream)
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+    stream->error_code = error_code;
+    stream->closed = TRUE;
+
+    /* remove the entry from the hash as the stream is now gone */
+    nghttp2_session_set_stream_user_data(session, stream_id, 0);
+    DEBUGF(infof(data_s, "Removed stream %u hash!\n", stream_id));
+  }
+  return 0;
+}
+
+static int on_begin_headers(nghttp2_session *session,
+                            const nghttp2_frame *frame, void *userp)
+{
+  struct HTTP *stream;
+  struct SessionHandle *data_s = NULL;
+  (void)userp;
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(!data_s) {
+    return 0;
+  }
+
+  DEBUGF(infof(data_s, "on_begin_headers() was called\n"));
+
+  if(frame->hd.type != NGHTTP2_HEADERS) {
+    return 0;
+  }
+
+  stream = data_s->req.protop;
+  if(!stream || !stream->bodystarted) {
+    return 0;
+  }
+
+  /* This is trailer HEADERS started.  Allocate buffer for them. */
+  DEBUGF(infof(data_s, "trailer field started\n"));
+
+  assert(stream->trailer_recvbuf == NULL);
+
+  stream->trailer_recvbuf = Curl_add_buffer_init();
+  if(!stream->trailer_recvbuf) {
+    return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+
+/* Decode HTTP status code.  Returns -1 if no valid status code was
+   decoded. */
+static int decode_status_code(const uint8_t *value, size_t len)
+{
+  int i;
+  int res;
+
+  if(len != 3) {
+    return -1;
+  }
+
+  res = 0;
+
+  for(i = 0; i < 3; ++i) {
+    char c = value[i];
+
+    if(c < '0' || c > '9') {
+      return -1;
+    }
+
+    res *= 10;
+    res += c - '0';
+  }
+
+  return res;
+}
+
+/* frame->hd.type is either NGHTTP2_HEADERS or NGHTTP2_PUSH_PROMISE */
+static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
+                     const uint8_t *name, size_t namelen,
+                     const uint8_t *value, size_t valuelen,
+                     uint8_t flags,
+                     void *userp)
+{
+  struct HTTP *stream;
+  struct SessionHandle *data_s;
+  int32_t stream_id = frame->hd.stream_id;
+  struct connectdata *conn = (struct connectdata *)userp;
+  (void)flags;
+
+  DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
+
+  /* get the stream from the hash based on Stream ID */
+  data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+  if(!data_s)
+    /* Receiving a Stream ID not in the hash should not happen, this is an
+       internal error more than anything else! */
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+  stream = data_s->req.protop;
+  if(!stream) {
+    failf(data_s, "Internal NULL stream! 5\n");
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+
+  /* Store received PUSH_PROMISE headers to be used when the subsequent
+     PUSH_PROMISE callback comes */
+  if(frame->hd.type == NGHTTP2_PUSH_PROMISE) {
+    char *h;
+
+    if(!stream->push_headers) {
+      stream->push_headers_alloc = 10;
+      stream->push_headers = malloc(stream->push_headers_alloc *
+                                    sizeof(char *));
+      stream->push_headers_used = 0;
+    }
+    else if(stream->push_headers_used ==
+            stream->push_headers_alloc) {
+      char **headp;
+      stream->push_headers_alloc *= 2;
+      headp = realloc(stream->push_headers,
+                      stream->push_headers_alloc * sizeof(char *));
+      if(!headp) {
+        free(stream->push_headers);
+        stream->push_headers = NULL;
+        return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+      }
+      stream->push_headers = headp;
+    }
+    h = aprintf("%s:%s", name, value);
+    if(h)
+      stream->push_headers[stream->push_headers_used++] = h;
+    return 0;
+  }
+
+  if(stream->bodystarted) {
+    /* This is trailer fields. */
+    /* 3 is for ":" and "\r\n". */
+    uint32_t n = (uint32_t)(namelen + valuelen + 3);
+
+    DEBUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen,
+                 value));
+
+    Curl_add_buffer(stream->trailer_recvbuf, &n, sizeof(n));
+    Curl_add_buffer(stream->trailer_recvbuf, name, namelen);
+    Curl_add_buffer(stream->trailer_recvbuf, ":", 1);
+    Curl_add_buffer(stream->trailer_recvbuf, value, valuelen);
+    Curl_add_buffer(stream->trailer_recvbuf, "\r\n\0", 3);
+
+    return 0;
+  }
+
+  if(namelen == sizeof(":status") - 1 &&
+     memcmp(":status", name, namelen) == 0) {
+    /* nghttp2 guarantees :status is received first and only once, and
+       value is 3 digits status code, and decode_status_code always
+       succeeds. */
+    stream->status_code = decode_status_code(value, valuelen);
+    DEBUGASSERT(stream->status_code != -1);
+
+    Curl_add_buffer(stream->header_recvbuf, "HTTP/2.0 ", 9);
+    Curl_add_buffer(stream->header_recvbuf, value, valuelen);
+    Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
+    data_s->state.drain++;
+    /* if we receive data for another handle, wake that up */
+    if(conn->data != data_s)
+      Curl_expire(data_s, 1);
+
+    DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n",
+                 stream->status_code, data_s));
+    return 0;
+  }
+
+  /* nghttp2 guarantees that namelen > 0, and :status was already
+     received, and this is not pseudo-header field . */
+  /* convert to a HTTP1-style header */
+  Curl_add_buffer(stream->header_recvbuf, name, namelen);
+  Curl_add_buffer(stream->header_recvbuf, ":", 1);
+  Curl_add_buffer(stream->header_recvbuf, value, valuelen);
+  Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
+  data_s->state.drain++;
+  /* if we receive data for another handle, wake that up */
+  if(conn->data != data_s)
+    Curl_expire(data_s, 1);
+
+  DEBUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen,
+               value));
+
+  return 0; /* 0 is successful */
+}
+
+static ssize_t data_source_read_callback(nghttp2_session *session,
+                                         int32_t stream_id,
+                                         uint8_t *buf, size_t length,
+                                         uint32_t *data_flags,
+                                         nghttp2_data_source *source,
+                                         void *userp)
+{
+  struct SessionHandle *data_s;
+  struct HTTP *stream = NULL;
+  size_t nread;
+  (void)source;
+  (void)userp;
+
+  if(stream_id) {
+    /* get the stream from the hash based on Stream ID, stream ID zero is for
+       connection-oriented stuff */
+    data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+    if(!data_s)
+      /* Receiving a Stream ID not in the hash should not happen, this is an
+         internal error more than anything else! */
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+    stream = data_s->req.protop;
+    if(!stream)
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+  else
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+
+  nread = MIN(stream->upload_len, length);
+  if(nread > 0) {
+    memcpy(buf, stream->upload_mem, nread);
+    stream->upload_mem += nread;
+    stream->upload_len -= nread;
+    stream->upload_left -= nread;
+  }
+
+  if(stream->upload_left == 0)
+    *data_flags = 1;
+  else if(nread == 0)
+    return NGHTTP2_ERR_DEFERRED;
+
+  DEBUGF(infof(data_s, "data_source_read_callback: "
+               "returns %zu bytes stream %u\n",
+               nread, stream_id));
+
+  return nread;
+}
+
+/*
+ * The HTTP2 settings we send in the Upgrade request
+ */
+static nghttp2_settings_entry settings[] = {
+  { NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100 },
+  { NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, NGHTTP2_INITIAL_WINDOW_SIZE },
+};
+
+#define H2_BUFSIZE 32768
+
+/*
+ * Initialize nghttp2 for a Curl connection
+ */
+CURLcode Curl_http2_init(struct connectdata *conn)
+{
+  if(!conn->proto.httpc.h2) {
+    int rc;
+    nghttp2_session_callbacks *callbacks;
+
+    conn->proto.httpc.inbuf = malloc(H2_BUFSIZE);
+    if(conn->proto.httpc.inbuf == NULL)
+      return CURLE_OUT_OF_MEMORY;
+
+    rc = nghttp2_session_callbacks_new(&callbacks);
+
+    if(rc) {
+      failf(conn->data, "Couldn't initialize nghttp2 callbacks!");
+      return CURLE_OUT_OF_MEMORY; /* most likely at least */
+    }
+
+    /* nghttp2_send_callback */
+    nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
+    /* nghttp2_on_frame_recv_callback */
+    nghttp2_session_callbacks_set_on_frame_recv_callback
+      (callbacks, on_frame_recv);
+    /* nghttp2_on_invalid_frame_recv_callback */
+    nghttp2_session_callbacks_set_on_invalid_frame_recv_callback
+      (callbacks, on_invalid_frame_recv);
+    /* nghttp2_on_data_chunk_recv_callback */
+    nghttp2_session_callbacks_set_on_data_chunk_recv_callback
+      (callbacks, on_data_chunk_recv);
+    /* nghttp2_before_frame_send_callback */
+    nghttp2_session_callbacks_set_before_frame_send_callback
+      (callbacks, before_frame_send);
+    /* nghttp2_on_frame_send_callback */
+    nghttp2_session_callbacks_set_on_frame_send_callback
+      (callbacks, on_frame_send);
+    /* nghttp2_on_frame_not_send_callback */
+    nghttp2_session_callbacks_set_on_frame_not_send_callback
+      (callbacks, on_frame_not_send);
+    /* nghttp2_on_stream_close_callback */
+    nghttp2_session_callbacks_set_on_stream_close_callback
+      (callbacks, on_stream_close);
+    /* nghttp2_on_begin_headers_callback */
+    nghttp2_session_callbacks_set_on_begin_headers_callback
+      (callbacks, on_begin_headers);
+    /* nghttp2_on_header_callback */
+    nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header);
+
+    /* The nghttp2 session is not yet setup, do it */
+    rc = nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn);
+
+    nghttp2_session_callbacks_del(callbacks);
+
+    if(rc) {
+      failf(conn->data, "Couldn't initialize nghttp2!");
+      return CURLE_OUT_OF_MEMORY; /* most likely at least */
+    }
+  }
+  return CURLE_OK;
+}
+
+/*
+ * Append headers to ask for a HTTP1.1 to HTTP2 upgrade.
+ */
+CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
+                                    struct connectdata *conn)
+{
+  CURLcode result;
+  ssize_t binlen;
+  char *base64;
+  size_t blen;
+  struct SingleRequest *k = &conn->data->req;
+  uint8_t *binsettings = conn->proto.httpc.binsettings;
+
+  /* As long as we have a fixed set of settings, we don't have to dynamically
+   * figure out the base64 strings since it'll always be the same. However,
+   * the settings will likely not be fixed every time in the future.
+   */
+
+  /* this returns number of bytes it wrote */
+  binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN,
+                                         settings,
+                                         sizeof(settings)/sizeof(settings[0]));
+  if(!binlen) {
+    failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
+    return CURLE_FAILED_INIT;
+  }
+  conn->proto.httpc.binlen = binlen;
+
+  result = Curl_base64url_encode(conn->data, (const char *)binsettings, binlen,
+                                 &base64, &blen);
+  if(result)
+    return result;
+
+  result = Curl_add_bufferf(req,
+                            "Connection: Upgrade, HTTP2-Settings\r\n"
+                            "Upgrade: %s\r\n"
+                            "HTTP2-Settings: %s\r\n",
+                            NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64);
+  free(base64);
+
+  k->upgr101 = UPGR101_REQUESTED;
+
+  return result;
+}
+
+static ssize_t http2_handle_stream_close(struct connectdata *conn,
+                                         struct SessionHandle *data,
+                                         struct HTTP *stream, CURLcode *err) {
+  char *trailer_pos, *trailer_end;
+  CURLcode result;
+  struct http_conn *httpc = &conn->proto.httpc;
+
+  if(httpc->pause_stream_id == stream->stream_id) {
+    httpc->pause_stream_id = 0;
+  }
+  /* Reset to FALSE to prevent infinite loop in readwrite_data
+   function. */
+  stream->closed = FALSE;
+  if(stream->error_code != NGHTTP2_NO_ERROR) {
+    failf(data, "HTTP/2 stream %u was not closed cleanly: error_code = %d",
+          stream->stream_id, stream->error_code);
+    *err = CURLE_HTTP2;
+    return -1;
+  }
+
+  if(stream->trailer_recvbuf && stream->trailer_recvbuf->buffer) {
+    trailer_pos = stream->trailer_recvbuf->buffer;
+    trailer_end = trailer_pos + stream->trailer_recvbuf->size_used;
+
+    for(; trailer_pos < trailer_end;) {
+      uint32_t n;
+      memcpy(&n, trailer_pos, sizeof(n));
+      trailer_pos += sizeof(n);
+
+      result = Curl_client_write(conn, CLIENTWRITE_HEADER, trailer_pos, n);
+      if(result) {
+        *err = result;
+        return -1;
+      }
+
+      trailer_pos += n + 1;
+    }
+  }
+
+  DEBUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
+  return 0;
+}
+
+/*
+ * h2_pri_spec() fills in the pri_spec struct, used by nghttp2 to send weight
+ * and dependency to the peer. It also stores the updated values in the state
+ * struct.
+ */
+
+static void h2_pri_spec(struct SessionHandle *data,
+                        nghttp2_priority_spec *pri_spec)
+{
+  struct HTTP *depstream = (data->set.stream_depends_on?
+                            data->set.stream_depends_on->req.protop:NULL);
+  int32_t depstream_id = depstream? depstream->stream_id:0;
+  nghttp2_priority_spec_init(pri_spec, depstream_id, data->set.stream_weight,
+                             data->set.stream_depends_e);
+  data->state.stream_weight = data->set.stream_weight;
+  data->state.stream_depends_e = data->set.stream_depends_e;
+  data->state.stream_depends_on = data->set.stream_depends_on;
+}
+
+/*
+ * h2_session_send() checks if there's been an update in the priority /
+ * dependency settings and if so it submits a PRIORITY frame with the updated
+ * info.
+ */
+static int h2_session_send(struct SessionHandle *data,
+                           nghttp2_session *h2)
+{
+  struct HTTP *stream = data->req.protop;
+  if((data->set.stream_weight != data->state.stream_weight) ||
+     (data->set.stream_depends_e != data->state.stream_depends_e) ||
+     (data->set.stream_depends_on != data->state.stream_depends_on) ) {
+    /* send new weight and/or dependency */
+    nghttp2_priority_spec pri_spec;
+    int rv;
+
+    h2_pri_spec(data, &pri_spec);
+
+    DEBUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)\n",
+                 stream->stream_id, data));
+    rv = nghttp2_submit_priority(h2, NGHTTP2_FLAG_NONE, stream->stream_id,
+                                 &pri_spec);
+    if(rv)
+      return rv;
+  }
+
+  return nghttp2_session_send(h2);
+}
+
+/*
+ * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
+ * a regular CURLcode value.
+ */
+static ssize_t http2_recv(struct connectdata *conn, int sockindex,
+                          char *mem, size_t len, CURLcode *err)
+{
+  CURLcode result = CURLE_OK;
+  ssize_t rv;
+  ssize_t nread;
+  struct http_conn *httpc = &conn->proto.httpc;
+  struct SessionHandle *data = conn->data;
+  struct HTTP *stream = data->req.protop;
+
+  (void)sockindex; /* we always do HTTP2 on sockindex 0 */
+
+  /* If stream is closed, return 0 to signal the http routine to close
+     the connection.  We need to handle stream closure here,
+     otherwise, we may be going to read from underlying connection,
+     and gets EAGAIN, and we will get stuck there. */
+  if(stream->memlen == 0 && stream->closed) {
+    return http2_handle_stream_close(conn, data, stream, err);
+  }
+
+  /* Nullify here because we call nghttp2_session_send() and they
+     might refer to the old buffer. */
+  stream->upload_mem = NULL;
+  stream->upload_len = 0;
+
+  /*
+   * At this point 'stream' is just in the SessionHandle the connection
+   * identifies as its owner at this time.
+   */
+
+  if(stream->bodystarted &&
+     stream->nread_header_recvbuf < stream->header_recvbuf->size_used) {
+    /* If there is body data pending for this stream to return, do that */
+    size_t left =
+      stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
+    size_t ncopy = MIN(len, left);
+    memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
+           ncopy);
+    stream->nread_header_recvbuf += ncopy;
+
+    DEBUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n",
+                 (int)ncopy));
+    return ncopy;
+  }
+
+  DEBUGF(infof(data, "http2_recv: easy %p (stream %u)\n",
+               data, stream->stream_id));
+
+  if((data->state.drain) && stream->memlen) {
+    DEBUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n",
+                 stream->memlen, stream->stream_id,
+                 stream->mem, mem));
+    if(mem != stream->mem) {
+      /* if we didn't get the same buffer this time, we must move the data to
+         the beginning */
+      memmove(mem, stream->mem, stream->memlen);
+      stream->len = len - stream->memlen;
+      stream->mem = mem;
+    }
+  }
+  else if(stream->pausedata) {
+    nread = MIN(len, stream->pauselen);
+    memcpy(mem, stream->pausedata, nread);
+
+    stream->pausedata += nread;
+    stream->pauselen -= nread;
+
+    infof(data, "%zu data bytes written\n", nread);
+    if(stream->pauselen == 0) {
+      DEBUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id));
+      assert(httpc->pause_stream_id == stream->stream_id);
+      httpc->pause_stream_id = 0;
+
+      stream->pausedata = NULL;
+      stream->pauselen = 0;
+
+      /* When NGHTTP2_ERR_PAUSE is returned from
+         data_source_read_callback, we might not process DATA frame
+         fully.  Calling nghttp2_session_mem_recv() again will
+         continue to process DATA frame, but if there is no incoming
+         frames, then we have to call it again with 0-length data.
+         Without this, on_stream_close callback will not be called,
+         and stream could be hanged. */
+      nghttp2_session_mem_recv(httpc->h2, NULL, 0);
+    }
+    DEBUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n",
+                 nread, stream->stream_id));
+    return nread;
+  }
+  else if(httpc->pause_stream_id) {
+    /* If a stream paused nghttp2_session_mem_recv previously, and has
+       not processed all data, it still refers to the buffer in
+       nghttp2_session.  If we call nghttp2_session_mem_recv(), we may
+       overwrite that buffer.  To avoid that situation, just return
+       here with CURLE_AGAIN.  This could be busy loop since data in
+       socket is not read.  But it seems that usually streams are
+       notified with its drain property, and socket is read again
+       quickly. */
+    *err = CURLE_AGAIN;
+    return -1;
+  }
+  else {
+    char *inbuf;
+    /* remember where to store incoming data for this stream and how big the
+       buffer is */
+    stream->mem = mem;
+    stream->len = len;
+    stream->memlen = 0;
+
+    if(httpc->inbuflen == 0) {
+      nread = ((Curl_recv *)httpc->recv_underlying)(
+          conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
+
+      if(nread == -1) {
+        if(result != CURLE_AGAIN)
+          failf(data, "Failed receiving HTTP2 data");
+        *err = result;
+        return -1;
+      }
+
+      if(nread == 0) {
+        failf(data, "Unexpected EOF");
+        *err = CURLE_RECV_ERROR;
+        return -1;
+      }
+
+      DEBUGF(infof(data, "nread=%zd\n", nread));
+
+      httpc->inbuflen = nread;
+      inbuf = httpc->inbuf;
+    }
+    else {
+      nread = httpc->inbuflen - httpc->nread_inbuf;
+      inbuf = httpc->inbuf + httpc->nread_inbuf;
+
+      DEBUGF(infof(data, "Use data left in connection buffer, nread=%zd\n",
+                   nread));
+    }
+    rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
+
+    if(nghttp2_is_fatal((int)rv)) {
+      failf(data, "nghttp2_session_mem_recv() returned %d:%s\n",
+            rv, nghttp2_strerror((int)rv));
+      *err = CURLE_RECV_ERROR;
+      return 0;
+    }
+    DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv));
+    if(nread == rv) {
+      DEBUGF(infof(data, "All data in connection buffer processed\n"));
+      httpc->inbuflen = 0;
+      httpc->nread_inbuf = 0;
+    }
+    else {
+      httpc->nread_inbuf += rv;
+      DEBUGF(infof(data, "%zu bytes left in connection buffer\n",
+                   httpc->inbuflen - httpc->nread_inbuf));
+    }
+    /* Always send pending frames in nghttp2 session, because
+       nghttp2_session_mem_recv() may queue new frame */
+    rv = h2_session_send(data, httpc->h2);
+    if(rv != 0) {
+      *err = CURLE_SEND_ERROR;
+      return 0;
+    }
+  }
+  if(stream->memlen) {
+    ssize_t retlen = stream->memlen;
+    DEBUGF(infof(data, "http2_recv: returns %zd for stream %u\n",
+                 retlen, stream->stream_id));
+    stream->memlen = 0;
+
+    if(httpc->pause_stream_id == stream->stream_id) {
+      /* data for this stream is returned now, but this stream caused a pause
+         already so we need it called again asap */
+      DEBUGF(infof(data, "Data returned for PAUSED stream %u\n",
+                   stream->stream_id));
+    }
+    else
+      data->state.drain = 0; /* this stream is hereby drained */
+
+    return retlen;
+  }
+  /* If stream is closed, return 0 to signal the http routine to close
+     the connection */
+  if(stream->closed) {
+    return http2_handle_stream_close(conn, data, stream, err);
+  }
+  *err = CURLE_AGAIN;
+  DEBUGF(infof(data, "http2_recv returns AGAIN for stream %u\n",
+               stream->stream_id));
+  return -1;
+}
+
+/* Index where :authority header field will appear in request header
+   field list. */
+#define AUTHORITY_DST_IDX 3
+
+/* return number of received (decrypted) bytes */
+static ssize_t http2_send(struct connectdata *conn, int sockindex,
+                          const void *mem, size_t len, CURLcode *err)
+{
+  /*
+   * BIG TODO: Currently, we send request in this function, but this
+   * function is also used to send request body. It would be nice to
+   * add dedicated function for request.
+   */
+  int rv;
+  struct http_conn *httpc = &conn->proto.httpc;
+  struct HTTP *stream = conn->data->req.protop;
+  nghttp2_nv *nva;
+  size_t nheader;
+  size_t i;
+  size_t authority_idx;
+  char *hdbuf = (char*)mem;
+  char *end;
+  nghttp2_data_provider data_prd;
+  int32_t stream_id;
+  nghttp2_session *h2 = httpc->h2;
+  nghttp2_priority_spec pri_spec;
+
+  (void)sockindex;
+
+  DEBUGF(infof(conn->data, "http2_send len=%zu\n", len));
+
+  if(stream->stream_id != -1) {
+    /* If stream_id != -1, we have dispatched request HEADERS, and now
+       are going to send or sending request body in DATA frame */
+    stream->upload_mem = mem;
+    stream->upload_len = len;
+    nghttp2_session_resume_data(h2, stream->stream_id);
+    rv = h2_session_send(conn->data, h2);
+    if(nghttp2_is_fatal(rv)) {
+      *err = CURLE_SEND_ERROR;
+      return -1;
+    }
+    len -= stream->upload_len;
+
+    /* Nullify here because we call nghttp2_session_send() and they
+       might refer to the old buffer. */
+    stream->upload_mem = NULL;
+    stream->upload_len = 0;
+
+    if(stream->upload_left) {
+      /* we are sure that we have more data to send here.  Calling the
+         following API will make nghttp2_session_want_write() return
+         nonzero if remote window allows it, which then libcurl checks
+         socket is writable or not.  See http2_perform_getsock(). */
+      nghttp2_session_resume_data(h2, stream->stream_id);
+    }
+
+    DEBUGF(infof(conn->data, "http2_send returns %zu for stream %u\n", len,
+                 stream->stream_id));
+    return len;
+  }
+
+  /* Calculate number of headers contained in [mem, mem + len) */
+  /* Here, we assume the curl http code generate *correct* HTTP header
+     field block */
+  nheader = 0;
+  for(i = 0; i < len; ++i) {
+    if(hdbuf[i] == 0x0a) {
+      ++nheader;
+    }
+  }
+  /* We counted additional 2 \n in the first and last line. We need 3
+     new headers: :method, :path and :scheme. Therefore we need one
+     more space. */
+  nheader += 1;
+  nva = malloc(sizeof(nghttp2_nv) * nheader);
+  if(nva == NULL) {
+    *err = CURLE_OUT_OF_MEMORY;
+    return -1;
+  }
+  /* Extract :method, :path from request line */
+  end = strchr(hdbuf, ' ');
+  if(!end)
+    goto fail;
+  nva[0].name = (unsigned char *)":method";
+  nva[0].namelen = (uint16_t)strlen((char *)nva[0].name);
+  nva[0].value = (unsigned char *)hdbuf;
+  nva[0].valuelen = (uint16_t)(end - hdbuf);
+  nva[0].flags = NGHTTP2_NV_FLAG_NONE;
+
+  hdbuf = end + 1;
+
+  end = strchr(hdbuf, ' ');
+  if(!end)
+    goto fail;
+  nva[1].name = (unsigned char *)":path";
+  nva[1].namelen = (uint16_t)strlen((char *)nva[1].name);
+  nva[1].value = (unsigned char *)hdbuf;
+  nva[1].valuelen = (uint16_t)(end - hdbuf);
+  nva[1].flags = NGHTTP2_NV_FLAG_NONE;
+
+  nva[2].name = (unsigned char *)":scheme";
+  nva[2].namelen = (uint16_t)strlen((char *)nva[2].name);
+  if(conn->handler->flags & PROTOPT_SSL)
+    nva[2].value = (unsigned char *)"https";
+  else
+    nva[2].value = (unsigned char *)"http";
+  nva[2].valuelen = (uint16_t)strlen((char *)nva[2].value);
+  nva[2].flags = NGHTTP2_NV_FLAG_NONE;
+
+  hdbuf = strchr(hdbuf, 0x0a);
+  if(!hdbuf)
+    goto fail;
+  ++hdbuf;
+
+  authority_idx = 0;
+
+  i = 3;
+  while(i < nheader) {
+    size_t hlen;
+    int skip = 0;
+    end = strchr(hdbuf, ':');
+    if(!end)
+      goto fail;
+    hlen = end - hdbuf;
+    if(hlen == 10 && Curl_raw_nequal("connection", hdbuf, 10)) {
+      /* skip Connection: headers! */
+      skip = 1;
+      --nheader;
+    }
+    else if(hlen == 4 && Curl_raw_nequal("host", hdbuf, 4)) {
+      authority_idx = i;
+      nva[i].name = (unsigned char *)":authority";
+      nva[i].namelen = (uint16_t)strlen((char *)nva[i].name);
+    }
+    else {
+      nva[i].name = (unsigned char *)hdbuf;
+      nva[i].namelen = (uint16_t)(end - hdbuf);
+    }
+    hdbuf = end + 1;
+    for(; *hdbuf == ' '; ++hdbuf);
+    end = strchr(hdbuf, 0x0d);
+    if(!end)
+      goto fail;
+    if(!skip) {
+      nva[i].value = (unsigned char *)hdbuf;
+      nva[i].valuelen = (uint16_t)(end - hdbuf);
+      nva[i].flags = NGHTTP2_NV_FLAG_NONE;
+      /* Inspect Content-Length header field and retrieve the request
+         entity length so that we can set END_STREAM to the last DATA
+         frame. */
+      if(nva[i].namelen == 14 &&
+         Curl_raw_nequal("content-length", (char*)nva[i].name, 14)) {
+        size_t j;
+        stream->upload_left = 0;
+        for(j = 0; j < nva[i].valuelen; ++j) {
+          stream->upload_left *= 10;
+          stream->upload_left += nva[i].value[j] - '0';
+        }
+        DEBUGF(infof(conn->data,
+                     "request content-length=%"
+                     CURL_FORMAT_CURL_OFF_T
+                     "\n", stream->upload_left));
+      }
+      ++i;
+    }
+    hdbuf = end + 2;
+  }
+
+  /* :authority must come before non-pseudo header fields */
+  if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) {
+    nghttp2_nv authority = nva[authority_idx];
+    for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) {
+      nva[i] = nva[i - 1];
+    }
+    nva[i] = authority;
+  }
+
+  h2_pri_spec(conn->data, &pri_spec);
+
+  switch(conn->data->set.httpreq) {
+  case HTTPREQ_POST:
+  case HTTPREQ_POST_FORM:
+  case HTTPREQ_PUT:
+    data_prd.read_callback = data_source_read_callback;
+    data_prd.source.ptr = NULL;
+    stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader,
+                                       &data_prd, conn->data);
+    break;
+  default:
+    stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader,
+                                       NULL, conn->data);
+  }
+
+  Curl_safefree(nva);
+
+  if(stream_id < 0) {
+    DEBUGF(infof(conn->data, "http2_send() send error\n"));
+    *err = CURLE_SEND_ERROR;
+    return -1;
+  }
+
+  infof(conn->data, "Using Stream ID: %x (easy handle %p)\n",
+        stream_id, conn->data);
+  stream->stream_id = stream_id;
+
+  /* this does not call h2_session_send() since there can not have been any
+   * priority upodate since the nghttp2_submit_request() call above */
+  rv = nghttp2_session_send(h2);
+
+  if(rv != 0) {
+    *err = CURLE_SEND_ERROR;
+    return -1;
+  }
+
+  if(stream->stream_id != -1) {
+    /* If whole HEADERS frame was sent off to the underlying socket,
+       the nghttp2 library calls data_source_read_callback. But only
+       it found that no data available, so it deferred the DATA
+       transmission. Which means that nghttp2_session_want_write()
+       returns 0 on http2_perform_getsock(), which results that no
+       writable socket check is performed. To workaround this, we
+       issue nghttp2_session_resume_data() here to bring back DATA
+       transmission from deferred state. */
+    nghttp2_session_resume_data(h2, stream->stream_id);
+  }
+
+  return len;
+
+fail:
+  free(nva);
+  *err = CURLE_SEND_ERROR;
+  return -1;
+}
+
+CURLcode Curl_http2_setup(struct connectdata *conn)
+{
+  CURLcode result;
+  struct http_conn *httpc = &conn->proto.httpc;
+  struct HTTP *stream = conn->data->req.protop;
+
+  stream->stream_id = -1;
+
+  if(!stream->header_recvbuf)
+    stream->header_recvbuf = Curl_add_buffer_init();
+
+  if((conn->handler == &Curl_handler_http2_ssl) ||
+     (conn->handler == &Curl_handler_http2))
+    return CURLE_OK; /* already done */
+
+  if(conn->handler->flags & PROTOPT_SSL)
+    conn->handler = &Curl_handler_http2_ssl;
+  else
+    conn->handler = &Curl_handler_http2;
+
+  result = Curl_http2_init(conn);
+  if(result)
+    return result;
+
+  infof(conn->data, "Using HTTP2, server supports multi-use\n");
+  stream->upload_left = 0;
+  stream->upload_mem = NULL;
+  stream->upload_len = 0;
+
+  httpc->inbuflen = 0;
+  httpc->nread_inbuf = 0;
+
+  httpc->pause_stream_id = 0;
+
+  conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
+  conn->httpversion = 20;
+  conn->bundle->multiuse = BUNDLE_MULTIPLEX;
+
+  infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n");
+  Curl_multi_connchanged(conn->data->multi);
+
+  /* switch on TCP_NODELAY as we need to send off packets without delay for
+     maximum throughput */
+  Curl_tcpnodelay(conn, conn->sock[FIRSTSOCKET]);
+
+  return CURLE_OK;
+}
+
+CURLcode Curl_http2_switched(struct connectdata *conn,
+                             const char *mem, size_t nread)
+{
+  CURLcode result;
+  struct http_conn *httpc = &conn->proto.httpc;
+  int rv;
+  ssize_t nproc;
+  struct SessionHandle *data = conn->data;
+  struct HTTP *stream = conn->data->req.protop;
+
+  result = Curl_http2_setup(conn);
+  if(result)
+    return result;
+
+  httpc->recv_underlying = (recving)conn->recv[FIRSTSOCKET];
+  httpc->send_underlying = (sending)conn->send[FIRSTSOCKET];
+  conn->recv[FIRSTSOCKET] = http2_recv;
+  conn->send[FIRSTSOCKET] = http2_send;
+
+  if(conn->data->req.upgr101 == UPGR101_RECEIVED) {
+    /* stream 1 is opened implicitly on upgrade */
+    stream->stream_id = 1;
+    /* queue SETTINGS frame (again) */
+    rv = nghttp2_session_upgrade(httpc->h2, httpc->binsettings,
+                                 httpc->binlen, NULL);
+    if(rv != 0) {
+      failf(data, "nghttp2_session_upgrade() failed: %s(%d)",
+            nghttp2_strerror(rv), rv);
+      return CURLE_HTTP2;
+    }
+
+    nghttp2_session_set_stream_user_data(httpc->h2,
+                                         stream->stream_id,
+                                         conn->data);
+  }
+  else {
+    /* stream ID is unknown at this point */
+    stream->stream_id = -1;
+    rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, NULL, 0);
+    if(rv != 0) {
+      failf(data, "nghttp2_submit_settings() failed: %s(%d)",
+            nghttp2_strerror(rv), rv);
+      return CURLE_HTTP2;
+    }
+  }
+
+  /* we are going to copy mem to httpc->inbuf.  This is required since
+     mem is part of buffer pointed by stream->mem, and callbacks
+     called by nghttp2_session_mem_recv() will write stream specific
+     data into stream->mem, overwriting data already there. */
+  if(H2_BUFSIZE < nread) {
+    failf(data, "connection buffer size is too small to store data following "
+                "HTTP Upgrade response header: buflen=%zu, datalen=%zu",
+          H2_BUFSIZE, nread);
+    return CURLE_HTTP2;
+  }
+
+  infof(conn->data, "Copying HTTP/2 data in stream buffer to connection buffer"
+                    " after upgrade: len=%zu\n",
+        nread);
+
+  memcpy(httpc->inbuf, mem, nread);
+  httpc->inbuflen = nread;
+
+  nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf,
+                                   httpc->inbuflen);
+
+  if(nghttp2_is_fatal((int)nproc)) {
+    failf(data, "nghttp2_session_mem_recv() failed: %s(%d)",
+          nghttp2_strerror((int)nproc), (int)nproc);
+    return CURLE_HTTP2;
+  }
+
+  DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc));
+
+  if((ssize_t)nread == nproc) {
+    httpc->inbuflen = 0;
+    httpc->nread_inbuf = 0;
+  }
+  else {
+    httpc->nread_inbuf += nproc;
+  }
+
+  /* Try to send some frames since we may read SETTINGS already. */
+  rv = h2_session_send(data, httpc->h2);
+
+  if(rv != 0) {
+    failf(data, "nghttp2_session_send() failed: %s(%d)",
+          nghttp2_strerror(rv), rv);
+    return CURLE_HTTP2;
+  }
+
+  return CURLE_OK;
+}
+
+#else /* !USE_NGHTTP2 */
+
+/* Satisfy external references even if http2 is not compiled in. */
+
+#define CURL_DISABLE_TYPECHECK
+#include <curl/curl.h>
+
+char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
+{
+  (void) h;
+  (void) num;
+  return NULL;
+}
+
+char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
+{
+  (void) h;
+  (void) header;
+  return NULL;
+}
+
+#endif /* USE_NGHTTP2 */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/http2.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/http2.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/http2.h	(revision 164)
@@ -0,0 +1,65 @@
+#ifndef HEADER_CURL_HTTP2_H
+#define HEADER_CURL_HTTP2_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_NGHTTP2
+#include "http.h"
+
+/* value for MAX_CONCURRENT_STREAMS we use until we get an updated setting
+   from the peer */
+#define DEFAULT_MAX_CONCURRENT_STREAMS 13
+
+/*
+ * Store nghttp2 version info in this buffer, Prefix with a space.  Return
+ * total length written.
+ */
+int Curl_http2_ver(char *p, size_t len);
+
+CURLcode Curl_http2_init(struct connectdata *conn);
+void Curl_http2_init_state(struct UrlState *state);
+void Curl_http2_init_userset(struct UserDefined *set);
+CURLcode Curl_http2_send_request(struct connectdata *conn);
+CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
+                                    struct connectdata *conn);
+CURLcode Curl_http2_setup(struct connectdata *conn);
+CURLcode Curl_http2_switched(struct connectdata *conn,
+                             const char *data, size_t nread);
+/* called from Curl_http_setup_conn */
+void Curl_http2_setup_conn(struct connectdata *conn);
+void Curl_http2_setup_req(struct SessionHandle *data);
+#else /* USE_NGHTTP2 */
+#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_setup_conn(x)
+#define Curl_http2_setup_req(x)
+#define Curl_http2_init_state(x)
+#define Curl_http2_init_userset(x)
+#endif
+
+#endif /* HEADER_CURL_HTTP2_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/http_chunks.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/http_chunks.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/http_chunks.c	(revision 164)
@@ -0,0 +1,381 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_HTTP
+
+#include "urldata.h" /* it includes http_chunks.h */
+#include "sendf.h"   /* for the client write stuff */
+
+#include "content_encoding.h"
+#include "http.h"
+#include "non-ascii.h" /* for Curl_convert_to_network prototype */
+#include "strtoofft.h"
+#include "warnless.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Chunk format (simplified):
+ *
+ * <HEX SIZE>[ chunk extension ] CRLF
+ * <DATA> CRLF
+ *
+ * Highlights from RFC2616 section 3.6 say:
+
+   The chunked encoding modifies the body of a message in order to
+   transfer it as a series of chunks, each with its own size indicator,
+   followed by an OPTIONAL trailer containing entity-header fields. This
+   allows dynamically produced content to be transferred along with the
+   information necessary for the recipient to verify that it has
+   received the full message.
+
+       Chunked-Body   = *chunk
+                        last-chunk
+                        trailer
+                        CRLF
+
+       chunk          = chunk-size [ chunk-extension ] CRLF
+                        chunk-data CRLF
+       chunk-size     = 1*HEX
+       last-chunk     = 1*("0") [ chunk-extension ] CRLF
+
+       chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
+       chunk-ext-name = token
+       chunk-ext-val  = token | quoted-string
+       chunk-data     = chunk-size(OCTET)
+       trailer        = *(entity-header CRLF)
+
+   The chunk-size field is a string of hex digits indicating the size of
+   the chunk. The chunked encoding is ended by any chunk whose size is
+   zero, followed by the trailer, which is terminated by an empty line.
+
+ */
+
+/* Check for an ASCII hex digit.
+ We avoid the use of isxdigit to accommodate non-ASCII hosts. */
+static bool Curl_isxdigit(char digit)
+{
+  return ( (digit >= 0x30 && digit <= 0x39) /* 0-9 */
+        || (digit >= 0x41 && digit <= 0x46) /* A-F */
+        || (digit >= 0x61 && digit <= 0x66) /* a-f */ ) ? TRUE : FALSE;
+}
+
+void Curl_httpchunk_init(struct connectdata *conn)
+{
+  struct Curl_chunker *chunk = &conn->chunk;
+  chunk->hexindex=0;        /* start at 0 */
+  chunk->dataleft=0;        /* no data left yet! */
+  chunk->state = CHUNK_HEX; /* we get hex first! */
+}
+
+/*
+ * chunk_read() returns a OK for normal operations, or a positive return code
+ * for errors. STOP means this sequence of chunks is complete.  The 'wrote'
+ * argument is set to tell the caller how many bytes we actually passed to the
+ * client (for byte-counting and whatever).
+ *
+ * The states and the state-machine is further explained in the header file.
+ *
+ * This function always uses ASCII hex values to accommodate non-ASCII hosts.
+ * For example, 0x0d and 0x0a are used instead of '\r' and '\n'.
+ */
+CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
+                              char *datap,
+                              ssize_t datalen,
+                              ssize_t *wrotep)
+{
+  CURLcode result=CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct Curl_chunker *ch = &conn->chunk;
+  struct SingleRequest *k = &data->req;
+  size_t piece;
+  curl_off_t length = (curl_off_t)datalen;
+  size_t *wrote = (size_t *)wrotep;
+
+  *wrote = 0; /* nothing's written yet */
+
+  /* the original data is written to the client, but we go on with the
+     chunk read process, to properly calculate the content length*/
+  if(data->set.http_te_skip && !k->ignorebody) {
+    result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, datalen);
+    if(result)
+      return CHUNKE_WRITE_ERROR;
+  }
+
+  while(length) {
+    switch(ch->state) {
+    case CHUNK_HEX:
+      if(Curl_isxdigit(*datap)) {
+        if(ch->hexindex < MAXNUM_SIZE) {
+          ch->hexbuffer[ch->hexindex] = *datap;
+          datap++;
+          length--;
+          ch->hexindex++;
+        }
+        else {
+          return CHUNKE_TOO_LONG_HEX; /* longer hex than we support */
+        }
+      }
+      else {
+        char *endptr;
+        if(0 == ch->hexindex)
+          /* This is illegal data, we received junk where we expected
+             a hexadecimal digit. */
+          return CHUNKE_ILLEGAL_HEX;
+
+        /* length and datap are unmodified */
+        ch->hexbuffer[ch->hexindex]=0;
+
+        /* convert to host encoding before calling strtoul */
+        result = Curl_convert_from_network(conn->data, ch->hexbuffer,
+                                           ch->hexindex);
+        if(result) {
+          /* Curl_convert_from_network calls failf if unsuccessful */
+          /* Treat it as a bad hex character */
+          return CHUNKE_ILLEGAL_HEX;
+        }
+
+        ch->datasize=curlx_strtoofft(ch->hexbuffer, &endptr, 16);
+        if((ch->datasize == CURL_OFF_T_MAX) && (errno == ERANGE))
+          /* overflow is an error */
+          return CHUNKE_ILLEGAL_HEX;
+        ch->state = CHUNK_LF; /* now wait for the CRLF */
+      }
+      break;
+
+    case CHUNK_LF:
+      /* waiting for the LF after a chunk size */
+      if(*datap == 0x0a) {
+        /* we're now expecting data to come, unless size was zero! */
+        if(0 == ch->datasize) {
+          ch->state = CHUNK_TRAILER; /* now check for trailers */
+          conn->trlPos=0;
+        }
+        else
+          ch->state = CHUNK_DATA;
+      }
+
+      datap++;
+      length--;
+      break;
+
+    case CHUNK_DATA:
+      /* We expect 'datasize' of data. We have 'length' right now, it can be
+         more or less than 'datasize'. Get the smallest piece.
+      */
+      piece = curlx_sotouz((ch->datasize >= length)?length:ch->datasize);
+
+      /* Write the data portion available */
+#ifdef HAVE_LIBZ
+      switch (conn->data->set.http_ce_skip?
+              IDENTITY : data->req.auto_decoding) {
+      case IDENTITY:
+#endif
+        if(!k->ignorebody) {
+          if(!data->set.http_te_skip)
+            result = Curl_client_write(conn, CLIENTWRITE_BODY, datap,
+                                       piece);
+          else
+            result = CURLE_OK;
+        }
+#ifdef HAVE_LIBZ
+        break;
+
+      case DEFLATE:
+        /* update data->req.keep.str to point to the chunk data. */
+        data->req.str = datap;
+        result = Curl_unencode_deflate_write(conn, &data->req,
+                                             (ssize_t)piece);
+        break;
+
+      case GZIP:
+        /* update data->req.keep.str to point to the chunk data. */
+        data->req.str = datap;
+        result = Curl_unencode_gzip_write(conn, &data->req,
+                                          (ssize_t)piece);
+        break;
+
+      default:
+        failf (conn->data,
+               "Unrecognized content encoding type. "
+               "libcurl understands `identity', `deflate' and `gzip' "
+               "content encodings.");
+        return CHUNKE_BAD_ENCODING;
+      }
+#endif
+
+      if(result)
+        return CHUNKE_WRITE_ERROR;
+
+      *wrote += piece;
+
+      ch->datasize -= piece; /* decrease amount left to expect */
+      datap += piece;    /* move read pointer forward */
+      length -= piece;   /* decrease space left in this round */
+
+      if(0 == ch->datasize)
+        /* end of data this round, we now expect a trailing CRLF */
+        ch->state = CHUNK_POSTLF;
+      break;
+
+    case CHUNK_POSTLF:
+      if(*datap == 0x0a) {
+        /* The last one before we go back to hex state and start all over. */
+        Curl_httpchunk_init(conn); /* sets state back to CHUNK_HEX */
+      }
+      else if(*datap != 0x0d)
+        return CHUNKE_BAD_CHUNK;
+      datap++;
+      length--;
+      break;
+
+    case CHUNK_TRAILER:
+      if((*datap == 0x0d) || (*datap == 0x0a)) {
+        /* this is the end of a trailer, but if the trailer was zero bytes
+           there was no trailer and we move on */
+
+        if(conn->trlPos) {
+          /* we allocate trailer with 3 bytes extra room to fit this */
+          conn->trailer[conn->trlPos++]=0x0d;
+          conn->trailer[conn->trlPos++]=0x0a;
+          conn->trailer[conn->trlPos]=0;
+
+          /* Convert to host encoding before calling Curl_client_write */
+          result = Curl_convert_from_network(conn->data, conn->trailer,
+                                             conn->trlPos);
+          if(result)
+            /* Curl_convert_from_network calls failf if unsuccessful */
+            /* Treat it as a bad chunk */
+            return CHUNKE_BAD_CHUNK;
+
+          if(!data->set.http_te_skip) {
+            result = Curl_client_write(conn, CLIENTWRITE_HEADER,
+                                       conn->trailer, conn->trlPos);
+            if(result)
+              return CHUNKE_WRITE_ERROR;
+          }
+          conn->trlPos=0;
+          ch->state = CHUNK_TRAILER_CR;
+          if(*datap == 0x0a)
+            /* already on the LF */
+            break;
+        }
+        else {
+          /* no trailer, we're on the final CRLF pair */
+          ch->state = CHUNK_TRAILER_POSTCR;
+          break; /* don't advance the pointer */
+        }
+      }
+      else {
+        /* conn->trailer is assumed to be freed in url.c on a
+           connection basis */
+        if(conn->trlPos >= conn->trlMax) {
+          /* we always allocate three extra bytes, just because when the full
+             header has been received we append CRLF\0 */
+          char *ptr;
+          if(conn->trlMax) {
+            conn->trlMax *= 2;
+            ptr = realloc(conn->trailer, conn->trlMax + 3);
+          }
+          else {
+            conn->trlMax=128;
+            ptr = malloc(conn->trlMax + 3);
+          }
+          if(!ptr)
+            return CHUNKE_OUT_OF_MEMORY;
+          conn->trailer = ptr;
+        }
+        conn->trailer[conn->trlPos++]=*datap;
+      }
+      datap++;
+      length--;
+      break;
+
+    case CHUNK_TRAILER_CR:
+      if(*datap == 0x0a) {
+        ch->state = CHUNK_TRAILER_POSTCR;
+        datap++;
+        length--;
+      }
+      else
+        return CHUNKE_BAD_CHUNK;
+      break;
+
+    case CHUNK_TRAILER_POSTCR:
+      /* We enter this state when a CR should arrive so we expect to
+         have to first pass a CR before we wait for LF */
+      if((*datap != 0x0d) && (*datap != 0x0a)) {
+        /* not a CR then it must be another header in the trailer */
+        ch->state = CHUNK_TRAILER;
+        break;
+      }
+      if(*datap == 0x0d) {
+        /* skip if CR */
+        datap++;
+        length--;
+      }
+      /* now wait for the final LF */
+      ch->state = CHUNK_STOP;
+      break;
+
+    case CHUNK_STOP:
+      if(*datap == 0x0a) {
+        length--;
+
+        /* Record the length of any data left in the end of the buffer
+           even if there's no more chunks to read */
+        ch->dataleft = curlx_sotouz(length);
+
+        return CHUNKE_STOP; /* return stop */
+      }
+      else
+        return CHUNKE_BAD_CHUNK;
+    }
+  }
+  return CHUNKE_OK;
+}
+
+const char *Curl_chunked_strerror(CHUNKcode code)
+{
+  switch (code) {
+  default:
+    return "OK";
+  case CHUNKE_TOO_LONG_HEX:
+    return "Too long hexadecimal number";
+  case CHUNKE_ILLEGAL_HEX:
+    return "Illegal or missing hexadecimal sequence";
+  case CHUNKE_BAD_CHUNK:
+    return "Malformed encoding found";
+  case CHUNKE_WRITE_ERROR:
+    return "Write error";
+  case CHUNKE_BAD_ENCODING:
+    return "Bad content-encoding found";
+  case CHUNKE_OUT_OF_MEMORY:
+    return "Out of memory";
+  }
+}
+
+#endif /* CURL_DISABLE_HTTP */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/http_chunks.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/http_chunks.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/http_chunks.h	(revision 164)
@@ -0,0 +1,91 @@
+#ifndef HEADER_CURL_HTTP_CHUNKS_H
+#define HEADER_CURL_HTTP_CHUNKS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+ * The longest possible hexadecimal number we support in a chunked transfer.
+ * Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul()
+ * to convert it, we "only" support 2^32 bytes chunk data.
+ */
+#define MAXNUM_SIZE 16
+
+typedef enum {
+  /* await and buffer all hexadecimal digits until we get one that isn't a
+     hexadecimal digit. When done, we go CHUNK_LF */
+  CHUNK_HEX,
+
+  /* wait for LF, ignore all else */
+  CHUNK_LF,
+
+  /* We eat the amount of data specified. When done, we move on to the
+     POST_CR state. */
+  CHUNK_DATA,
+
+  /* POSTLF should get a CR and then a LF and nothing else, then move back to
+     HEX as the CRLF combination marks the end of a chunk. A missing CR is no
+     big deal. */
+  CHUNK_POSTLF,
+
+  /* Used to mark that we're out of the game.  NOTE: that there's a 'dataleft'
+     field in the struct that will tell how many bytes that were not passed to
+     the client in the end of the last buffer! */
+  CHUNK_STOP,
+
+  /* At this point optional trailer headers can be found, unless the next line
+     is CRLF */
+  CHUNK_TRAILER,
+
+  /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR.
+     Next char must be a LF */
+  CHUNK_TRAILER_CR,
+
+  /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be
+     signalled If this is an empty trailer CHUNKE_STOP will be signalled.
+     Otherwise the trailer will be broadcasted via Curl_client_write() and the
+     next state will be CHUNK_TRAILER */
+  CHUNK_TRAILER_POSTCR
+} ChunkyState;
+
+typedef enum {
+  CHUNKE_STOP = -1,
+  CHUNKE_OK = 0,
+  CHUNKE_TOO_LONG_HEX = 1,
+  CHUNKE_ILLEGAL_HEX,
+  CHUNKE_BAD_CHUNK,
+  CHUNKE_WRITE_ERROR,
+  CHUNKE_BAD_ENCODING,
+  CHUNKE_OUT_OF_MEMORY,
+  CHUNKE_LAST
+} CHUNKcode;
+
+const char *Curl_chunked_strerror(CHUNKcode code);
+
+struct Curl_chunker {
+  char hexbuffer[ MAXNUM_SIZE + 1];
+  int hexindex;
+  ChunkyState state;
+  curl_off_t datasize;
+  size_t dataleft; /* untouched data amount at the end of the last buffer */
+};
+
+#endif /* HEADER_CURL_HTTP_CHUNKS_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/http_digest.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/http_digest.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/http_digest.c	(revision 164)
@@ -0,0 +1,179 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+
+#include "urldata.h"
+#include "rawstr.h"
+#include "curl_sasl.h"
+#include "http_digest.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Test example headers:
+
+WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
+Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598"
+
+*/
+
+CURLcode Curl_input_digest(struct connectdata *conn,
+                           bool proxy,
+                           const char *header) /* rest of the *-authenticate:
+                                                  header */
+{
+  struct SessionHandle *data = conn->data;
+
+  /* Point to the correct struct with this */
+  struct digestdata *digest;
+
+  if(proxy) {
+    digest = &data->state.proxydigest;
+  }
+  else {
+    digest = &data->state.digest;
+  }
+
+  if(!checkprefix("Digest", header))
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  header += strlen("Digest");
+  while(*header && ISSPACE(*header))
+    header++;
+
+  return Curl_sasl_decode_digest_http_message(header, digest);
+}
+
+CURLcode Curl_output_digest(struct connectdata *conn,
+                            bool proxy,
+                            const unsigned char *request,
+                            const unsigned char *uripath)
+{
+  CURLcode result;
+  struct SessionHandle *data = conn->data;
+  unsigned char *path;
+  char *tmp;
+  char *response;
+  size_t len;
+  bool have_chlg;
+
+  /* Point to the address of the pointer that holds the string to send to the
+     server, which is for a plain host or for a HTTP proxy */
+  char **allocuserpwd;
+
+  /* Point to the name and password for this */
+  const char *userp;
+  const char *passwdp;
+
+  /* Point to the correct struct with this */
+  struct digestdata *digest;
+  struct auth *authp;
+
+  if(proxy) {
+    digest = &data->state.proxydigest;
+    allocuserpwd = &conn->allocptr.proxyuserpwd;
+    userp = conn->proxyuser;
+    passwdp = conn->proxypasswd;
+    authp = &data->state.authproxy;
+  }
+  else {
+    digest = &data->state.digest;
+    allocuserpwd = &conn->allocptr.userpwd;
+    userp = conn->user;
+    passwdp = conn->passwd;
+    authp = &data->state.authhost;
+  }
+
+  Curl_safefree(*allocuserpwd);
+
+  /* not set means empty */
+  if(!userp)
+    userp = "";
+
+  if(!passwdp)
+    passwdp = "";
+
+#if defined(USE_WINDOWS_SSPI)
+  have_chlg = digest->input_token ? TRUE : FALSE;
+#else
+  have_chlg = digest->nonce ? TRUE : FALSE;
+#endif
+
+  if(!have_chlg) {
+    authp->done = FALSE;
+    return CURLE_OK;
+  }
+
+  /* So IE browsers < v7 cut off the URI part at the query part when they
+     evaluate the MD5 and some (IIS?) servers work with them so we may need to
+     do the Digest IE-style. Note that the different ways cause different MD5
+     sums to get sent.
+
+     Apache servers can be set to do the Digest IE-style automatically using
+     the BrowserMatch feature:
+     https://httpd.apache.org/docs/2.2/mod/mod_auth_digest.html#msie
+
+     Further details on Digest implementation differences:
+     http://www.fngtps.com/2006/09/http-authentication
+  */
+
+  if(authp->iestyle && ((tmp = strchr((char *)uripath, '?')) != NULL)) {
+    size_t urilen = tmp - (char *)uripath;
+
+    path = (unsigned char *) aprintf("%.*s", urilen, uripath);
+  }
+  else
+    path = (unsigned char *) strdup((char *) uripath);
+
+  if(!path)
+    return CURLE_OUT_OF_MEMORY;
+
+  result = Curl_sasl_create_digest_http_message(data, userp, passwdp, request,
+                                                path, digest, &response, &len);
+  free(path);
+  if(result)
+    return result;
+
+  *allocuserpwd = aprintf("%sAuthorization: Digest %s\r\n",
+                          proxy ? "Proxy-" : "",
+                          response);
+  free(response);
+  if(!*allocuserpwd)
+    return CURLE_OUT_OF_MEMORY;
+
+  authp->done = TRUE;
+
+  return CURLE_OK;
+}
+
+void Curl_digest_cleanup(struct SessionHandle *data)
+{
+  Curl_sasl_digest_cleanup(&data->state.digest);
+  Curl_sasl_digest_cleanup(&data->state.proxydigest);
+}
+
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/lib/http_digest.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/http_digest.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/http_digest.h	(revision 164)
@@ -0,0 +1,42 @@
+#ifndef HEADER_CURL_HTTP_DIGEST_H
+#define HEADER_CURL_HTTP_DIGEST_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/* this is for digest header input */
+CURLcode Curl_input_digest(struct connectdata *conn,
+                           bool proxy, const char *header);
+
+/* this is for creating digest header output */
+CURLcode Curl_output_digest(struct connectdata *conn,
+                            bool proxy,
+                            const unsigned char *request,
+                            const unsigned char *uripath);
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+void Curl_digest_cleanup(struct SessionHandle *data);
+#else
+#define Curl_digest_cleanup(x) Curl_nop_stmt
+#endif
+
+#endif /* HEADER_CURL_HTTP_DIGEST_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/http_negotiate.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/http_negotiate.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/http_negotiate.c	(revision 164)
@@ -0,0 +1,210 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
+
+#include "urldata.h"
+#include "sendf.h"
+#include "curl_gssapi.h"
+#include "rawstr.h"
+#include "curl_base64.h"
+#include "http_negotiate.h"
+#include "curl_sasl.h"
+#include "url.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
+                              const char *header)
+{
+  struct SessionHandle *data = conn->data;
+  struct negotiatedata *neg_ctx = proxy?&data->state.proxyneg:
+    &data->state.negotiate;
+  OM_uint32 major_status, minor_status, discard_st;
+  gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+  size_t len;
+  size_t rawlen = 0;
+  CURLcode result;
+
+  if(neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) {
+    /* We finished successfully our part of authentication, but server
+     * rejected it (since we're again here). Exit with an error since we
+     * can't invent anything better */
+    Curl_cleanup_negotiate(data);
+    return CURLE_LOGIN_DENIED;
+  }
+
+  if(!neg_ctx->server_name) {
+    /* Generate our SPN */
+    char *spn = Curl_sasl_build_gssapi_spn(
+      proxy ? data->set.str[STRING_PROXY_SERVICE_NAME] :
+      data->set.str[STRING_SERVICE_NAME],
+      proxy ? conn->proxy.name : conn->host.name);
+    if(!spn)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Populate the SPN structure */
+    spn_token.value = spn;
+    spn_token.length = strlen(spn);
+
+    /* Import the SPN */
+    major_status = gss_import_name(&minor_status, &spn_token,
+                                   GSS_C_NT_HOSTBASED_SERVICE,
+                                   &neg_ctx->server_name);
+    if(GSS_ERROR(major_status)) {
+      Curl_gss_log_error(data, minor_status, "gss_import_name() failed: ");
+
+      free(spn);
+
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    free(spn);
+  }
+
+  header += strlen("Negotiate");
+  while(*header && ISSPACE(*header))
+    header++;
+
+  len = strlen(header);
+  if(len > 0) {
+    result = Curl_base64_decode(header, (unsigned char **)&input_token.value,
+                                &rawlen);
+    if(result)
+      return result;
+
+    if(!rawlen) {
+      infof(data, "Negotiate handshake failure (empty challenge message)\n");
+
+      return CURLE_BAD_CONTENT_ENCODING;
+    }
+
+    input_token.length = rawlen;
+
+    DEBUGASSERT(input_token.value != NULL);
+  }
+
+  major_status = Curl_gss_init_sec_context(data,
+                                           &minor_status,
+                                           &neg_ctx->context,
+                                           neg_ctx->server_name,
+                                           &Curl_spnego_mech_oid,
+                                           GSS_C_NO_CHANNEL_BINDINGS,
+                                           &input_token,
+                                           &output_token,
+                                           TRUE,
+                                           NULL);
+  Curl_safefree(input_token.value);
+
+  neg_ctx->status = major_status;
+  if(GSS_ERROR(major_status)) {
+    if(output_token.value)
+      gss_release_buffer(&discard_st, &output_token);
+    Curl_gss_log_error(conn->data, minor_status,
+                       "gss_init_sec_context() failed: ");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(!output_token.value || !output_token.length) {
+    if(output_token.value)
+      gss_release_buffer(&discard_st, &output_token);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  neg_ctx->output_token = output_token;
+
+  return CURLE_OK;
+}
+
+CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
+{
+  struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
+    &conn->data->state.negotiate;
+  char *encoded = NULL;
+  size_t len = 0;
+  char *userp;
+  CURLcode result;
+  OM_uint32 discard_st;
+
+  result = Curl_base64_encode(conn->data,
+                              neg_ctx->output_token.value,
+                              neg_ctx->output_token.length,
+                              &encoded, &len);
+  if(result) {
+    gss_release_buffer(&discard_st, &neg_ctx->output_token);
+    neg_ctx->output_token.value = NULL;
+    neg_ctx->output_token.length = 0;
+    return result;
+  }
+
+  if(!encoded || !len) {
+    gss_release_buffer(&discard_st, &neg_ctx->output_token);
+    neg_ctx->output_token.value = NULL;
+    neg_ctx->output_token.length = 0;
+    return CURLE_REMOTE_ACCESS_DENIED;
+  }
+
+  userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
+                  encoded);
+  if(proxy) {
+    Curl_safefree(conn->allocptr.proxyuserpwd);
+    conn->allocptr.proxyuserpwd = userp;
+  }
+  else {
+    Curl_safefree(conn->allocptr.userpwd);
+    conn->allocptr.userpwd = userp;
+  }
+
+  free(encoded);
+
+  return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
+}
+
+static void cleanup(struct negotiatedata *neg_ctx)
+{
+  OM_uint32 minor_status;
+  if(neg_ctx->context != GSS_C_NO_CONTEXT)
+    gss_delete_sec_context(&minor_status, &neg_ctx->context, GSS_C_NO_BUFFER);
+
+  if(neg_ctx->output_token.value)
+    gss_release_buffer(&minor_status, &neg_ctx->output_token);
+
+  if(neg_ctx->server_name != GSS_C_NO_NAME)
+    gss_release_name(&minor_status, &neg_ctx->server_name);
+
+  memset(neg_ctx, 0, sizeof(*neg_ctx));
+}
+
+void Curl_cleanup_negotiate(struct SessionHandle *data)
+{
+  cleanup(&data->state.negotiate);
+  cleanup(&data->state.proxyneg);
+}
+
+#endif /* HAVE_GSSAPI && !CURL_DISABLE_HTTP && USE_SPNEGO */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/http_negotiate.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/http_negotiate.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/http_negotiate.h	(revision 164)
@@ -0,0 +1,42 @@
+#ifndef HEADER_CURL_HTTP_NEGOTIATE_H
+#define HEADER_CURL_HTTP_NEGOTIATE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef USE_SPNEGO
+
+/* this is for Negotiate header input */
+CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
+                              const char *header);
+
+/* this is for creating Negotiate header output */
+CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy);
+
+void Curl_cleanup_negotiate(struct SessionHandle *data);
+
+#ifdef USE_WINDOWS_SSPI
+#define GSS_ERROR(status) (status & 0x80000000)
+#endif
+
+#endif /* USE_SPNEGO */
+
+#endif /* HEADER_CURL_HTTP_NEGOTIATE_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/http_negotiate_sspi.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/http_negotiate_sspi.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/http_negotiate_sspi.c	(revision 164)
@@ -0,0 +1,300 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_WINDOWS_SSPI
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
+
+#include "urldata.h"
+#include "sendf.h"
+#include "rawstr.h"
+#include "warnless.h"
+#include "curl_base64.h"
+#include "curl_sasl.h"
+#include "http_negotiate.h"
+#include "curl_multibyte.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
+                              const char *header)
+{
+  struct SessionHandle *data = conn->data;
+  BYTE              *input_token = NULL;
+  SecBufferDesc     out_buff_desc;
+  SecBuffer         out_sec_buff;
+  SecBufferDesc     in_buff_desc;
+  SecBuffer         in_sec_buff;
+  SECURITY_STATUS   status;
+  unsigned long     attrs;
+  TimeStamp         expiry; /* For Windows 9x compatibility of SSPI calls */
+  size_t len = 0, input_token_len = 0;
+  CURLcode result;
+
+  /* Point to the username and password */
+  const char *userp;
+  const char *passwdp;
+
+  /* Point to the correct struct with this */
+  struct negotiatedata *neg_ctx;
+
+  if(proxy) {
+    userp = conn->proxyuser;
+    passwdp = conn->proxypasswd;
+    neg_ctx = &data->state.proxyneg;
+  }
+  else {
+    userp = conn->user;
+    passwdp = conn->passwd;
+    neg_ctx = &data->state.negotiate;
+  }
+
+  /* Not set means empty */
+  if(!userp)
+    userp = "";
+
+  if(!passwdp)
+    passwdp = "";
+
+  if(neg_ctx->context && neg_ctx->status == SEC_E_OK) {
+    /* We finished successfully our part of authentication, but server
+     * rejected it (since we're again here). Exit with an error since we
+     * can't invent anything better */
+    Curl_cleanup_negotiate(data);
+    return CURLE_LOGIN_DENIED;
+  }
+
+  if(!neg_ctx->server_name) {
+    /* Check proxy auth requested but no given proxy name */
+    if(proxy && !conn->proxy.name)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+
+    /* Generate our SPN */
+    neg_ctx->server_name = Curl_sasl_build_spn(
+      proxy ? data->set.str[STRING_PROXY_SERVICE_NAME] :
+      data->set.str[STRING_SERVICE_NAME],
+      proxy ? conn->proxy.name : conn->host.name);
+    if(!neg_ctx->server_name)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(!neg_ctx->output_token) {
+    PSecPkgInfo SecurityPackage;
+    status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
+                                                TEXT(SP_NAME_NEGOTIATE),
+                                                &SecurityPackage);
+    if(status != SEC_E_OK)
+      return CURLE_NOT_BUILT_IN;
+
+    /* Allocate input and output buffers according to the max token size
+       as indicated by the security package */
+    neg_ctx->token_max = SecurityPackage->cbMaxToken;
+    neg_ctx->output_token = malloc(neg_ctx->token_max);
+    s_pSecFn->FreeContextBuffer(SecurityPackage);
+  }
+
+  /* Obtain the input token, if any */
+  header += strlen("Negotiate");
+  while(*header && ISSPACE(*header))
+    header++;
+
+  len = strlen(header);
+  if(!len) {
+    /* Is this the first call in a new negotiation? */
+    if(neg_ctx->context) {
+      /* The server rejected our authentication and hasn't suppled any more
+         negotiation mechanisms */
+      return CURLE_LOGIN_DENIED;
+    }
+
+    /* We have to acquire credentials and allocate memory for the context */
+    neg_ctx->credentials = malloc(sizeof(CredHandle));
+    neg_ctx->context = malloc(sizeof(CtxtHandle));
+
+    if(!neg_ctx->credentials || !neg_ctx->context)
+      return CURLE_OUT_OF_MEMORY;
+
+    if(userp && *userp) {
+      /* Populate our identity structure */
+      result = Curl_create_sspi_identity(userp, passwdp, &neg_ctx->identity);
+      if(result)
+        return result;
+
+      /* Allow proper cleanup of the identity structure */
+      neg_ctx->p_identity = &neg_ctx->identity;
+    }
+    else
+      /* Use the current Windows user */
+      neg_ctx->p_identity = NULL;
+
+    /* Acquire our credientials handle */
+    neg_ctx->status =
+      s_pSecFn->AcquireCredentialsHandle(NULL,
+                                         (TCHAR *) TEXT(SP_NAME_NEGOTIATE),
+                                         SECPKG_CRED_OUTBOUND, NULL,
+                                         neg_ctx->p_identity, NULL, NULL,
+                                         neg_ctx->credentials, &expiry);
+    if(neg_ctx->status != SEC_E_OK)
+      return CURLE_LOGIN_DENIED;
+  }
+  else {
+    result = Curl_base64_decode(header,
+                                (unsigned char **)&input_token,
+                                &input_token_len);
+    if(result)
+      return result;
+
+    if(!input_token_len) {
+      infof(data,
+            "Negotiate handshake failure (empty challenge message)\n");
+
+      return CURLE_BAD_CONTENT_ENCODING;
+    }
+  }
+
+  /* Setup the "output" security buffer */
+  out_buff_desc.ulVersion = SECBUFFER_VERSION;
+  out_buff_desc.cBuffers  = 1;
+  out_buff_desc.pBuffers  = &out_sec_buff;
+  out_sec_buff.BufferType = SECBUFFER_TOKEN;
+  out_sec_buff.pvBuffer   = neg_ctx->output_token;
+  out_sec_buff.cbBuffer   = curlx_uztoul(neg_ctx->token_max);
+
+  /* Setup the "input" security buffer if present */
+  if(input_token) {
+    in_buff_desc.ulVersion = SECBUFFER_VERSION;
+    in_buff_desc.cBuffers  = 1;
+    in_buff_desc.pBuffers  = &in_sec_buff;
+    in_sec_buff.BufferType = SECBUFFER_TOKEN;
+    in_sec_buff.pvBuffer   = input_token;
+    in_sec_buff.cbBuffer   = curlx_uztoul(input_token_len);
+  }
+
+  /* Generate our message */
+  neg_ctx->status = s_pSecFn->InitializeSecurityContext(
+    neg_ctx->credentials,
+    input_token ? neg_ctx->context : NULL,
+    neg_ctx->server_name,
+    ISC_REQ_CONFIDENTIALITY,
+    0,
+    SECURITY_NATIVE_DREP,
+    input_token ? &in_buff_desc : NULL,
+    0,
+    neg_ctx->context,
+    &out_buff_desc,
+    &attrs,
+    &expiry);
+
+  free(input_token);
+
+  if(GSS_ERROR(neg_ctx->status))
+    return CURLE_OUT_OF_MEMORY;
+
+  if(neg_ctx->status == SEC_I_COMPLETE_NEEDED ||
+     neg_ctx->status == SEC_I_COMPLETE_AND_CONTINUE) {
+    neg_ctx->status = s_pSecFn->CompleteAuthToken(neg_ctx->context,
+                                                  &out_buff_desc);
+    if(GSS_ERROR(neg_ctx->status))
+      return CURLE_RECV_ERROR;
+  }
+
+  neg_ctx->output_token_length = out_sec_buff.cbBuffer;
+
+  return CURLE_OK;
+}
+
+CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
+{
+  struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
+    &conn->data->state.negotiate;
+  char *encoded = NULL;
+  size_t len = 0;
+  char *userp;
+  CURLcode error;
+
+  error = Curl_base64_encode(conn->data,
+                             (const char*)neg_ctx->output_token,
+                             neg_ctx->output_token_length,
+                             &encoded, &len);
+  if(error)
+    return error;
+
+  if(!len)
+    return CURLE_REMOTE_ACCESS_DENIED;
+
+  userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
+                  encoded);
+
+  if(proxy) {
+    Curl_safefree(conn->allocptr.proxyuserpwd);
+    conn->allocptr.proxyuserpwd = userp;
+  }
+  else {
+    Curl_safefree(conn->allocptr.userpwd);
+    conn->allocptr.userpwd = userp;
+  }
+  free(encoded);
+  return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
+}
+
+static void cleanup(struct negotiatedata *neg_ctx)
+{
+  /* Free our security context */
+  if(neg_ctx->context) {
+    s_pSecFn->DeleteSecurityContext(neg_ctx->context);
+    free(neg_ctx->context);
+    neg_ctx->context = NULL;
+  }
+
+  /* Free our credentials handle */
+  if(neg_ctx->credentials) {
+    s_pSecFn->FreeCredentialsHandle(neg_ctx->credentials);
+    free(neg_ctx->credentials);
+    neg_ctx->credentials = NULL;
+  }
+
+  /* Free our identity */
+  Curl_sspi_free_identity(neg_ctx->p_identity);
+  neg_ctx->p_identity = NULL;
+
+  /* Free the SPN and output token */
+  Curl_safefree(neg_ctx->server_name);
+  Curl_safefree(neg_ctx->output_token);
+
+  /* Reset any variables */
+  neg_ctx->token_max = 0;
+}
+
+void Curl_cleanup_negotiate(struct SessionHandle *data)
+{
+  cleanup(&data->state.negotiate);
+  cleanup(&data->state.proxyneg);
+}
+
+#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */
+
+#endif /* USE_WINDOWS_SSPI */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/http_proxy.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/http_proxy.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/http_proxy.c	(revision 164)
@@ -0,0 +1,596 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "http_proxy.h"
+#include "sendf.h"
+#include "http.h"
+#include "url.h"
+#include "select.h"
+#include "rawstr.h"
+#include "progress.h"
+#include "non-ascii.h"
+#include "connect.h"
+#include "curl_printf.h"
+#include "curlx.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+CURLcode Curl_proxy_connect(struct connectdata *conn)
+{
+  if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
+#ifndef CURL_DISABLE_PROXY
+    /* for [protocol] tunneled through HTTP proxy */
+    struct HTTP http_proxy;
+    void *prot_save;
+    CURLcode result;
+
+    /* BLOCKING */
+    /* We want "seamless" operations through HTTP proxy tunnel */
+
+    /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
+     * member conn->proto.http; we want [protocol] through HTTP and we have
+     * to change the member temporarily for connecting to the HTTP
+     * proxy. After Curl_proxyCONNECT we have to set back the member to the
+     * original pointer
+     *
+     * This function might be called several times in the multi interface case
+     * if the proxy's CONNTECT response is not instant.
+     */
+    prot_save = conn->data->req.protop;
+    memset(&http_proxy, 0, sizeof(http_proxy));
+    conn->data->req.protop = &http_proxy;
+    connkeep(conn, "HTTP proxy CONNECT");
+    result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
+                               conn->host.name, conn->remote_port, FALSE);
+    conn->data->req.protop = prot_save;
+    if(CURLE_OK != result)
+      return result;
+    Curl_safefree(conn->allocptr.proxyuserpwd);
+#else
+    return CURLE_NOT_BUILT_IN;
+#endif
+  }
+  /* no HTTP tunnel proxy, just return */
+  return CURLE_OK;
+}
+
+/*
+ * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This
+ * function will issue the necessary commands to get a seamless tunnel through
+ * this proxy. After that, the socket can be used just as a normal socket.
+ *
+ * 'blocking' set to TRUE means that this function will do the entire CONNECT
+ * + response in a blocking fashion. Should be avoided!
+ */
+
+CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+                           int sockindex,
+                           const char *hostname,
+                           int remote_port,
+                           bool blocking)
+{
+  int subversion=0;
+  struct SessionHandle *data=conn->data;
+  struct SingleRequest *k = &data->req;
+  CURLcode result;
+  curl_socket_t tunnelsocket = conn->sock[sockindex];
+  curl_off_t cl=0;
+  bool closeConnection = FALSE;
+  bool chunked_encoding = FALSE;
+  long check;
+
+#define SELECT_OK      0
+#define SELECT_ERROR   1
+#define SELECT_TIMEOUT 2
+  int error = SELECT_OK;
+
+  if(conn->tunnel_state[sockindex] == TUNNEL_COMPLETE)
+    return CURLE_OK; /* CONNECT is already completed */
+
+  conn->bits.proxy_connect_closed = FALSE;
+
+  do {
+    if(TUNNEL_INIT == conn->tunnel_state[sockindex]) {
+      /* BEGIN CONNECT PHASE */
+      char *host_port;
+      Curl_send_buffer *req_buffer;
+
+      infof(data, "Establish HTTP proxy tunnel to %s:%hu\n",
+            hostname, remote_port);
+
+        /* This only happens if we've looped here due to authentication
+           reasons, and we don't really use the newly cloned URL here
+           then. Just free() it. */
+      free(data->req.newurl);
+      data->req.newurl = NULL;
+
+      /* initialize a dynamic send-buffer */
+      req_buffer = Curl_add_buffer_init();
+
+      if(!req_buffer)
+        return CURLE_OUT_OF_MEMORY;
+
+      host_port = aprintf("%s:%hu", hostname, remote_port);
+      if(!host_port) {
+        Curl_add_buffer_free(req_buffer);
+        return CURLE_OUT_OF_MEMORY;
+      }
+
+      /* Setup the proxy-authorization header, if any */
+      result = Curl_http_output_auth(conn, "CONNECT", host_port, TRUE);
+
+      free(host_port);
+
+      if(!result) {
+        char *host=(char *)"";
+        const char *proxyconn="";
+        const char *useragent="";
+        const char *http = (conn->proxytype == CURLPROXY_HTTP_1_0) ?
+          "1.0" : "1.1";
+        char *hostheader= /* host:port with IPv6 support */
+          aprintf("%s%s%s:%hu", conn->bits.ipv6_ip?"[":"",
+                  hostname, conn->bits.ipv6_ip?"]":"",
+                  remote_port);
+        if(!hostheader) {
+          Curl_add_buffer_free(req_buffer);
+          return CURLE_OUT_OF_MEMORY;
+        }
+
+        if(!Curl_checkProxyheaders(conn, "Host:")) {
+          host = aprintf("Host: %s\r\n", hostheader);
+          if(!host) {
+            free(hostheader);
+            Curl_add_buffer_free(req_buffer);
+            return CURLE_OUT_OF_MEMORY;
+          }
+        }
+        if(!Curl_checkProxyheaders(conn, "Proxy-Connection:"))
+          proxyconn = "Proxy-Connection: Keep-Alive\r\n";
+
+        if(!Curl_checkProxyheaders(conn, "User-Agent:") &&
+           data->set.str[STRING_USERAGENT])
+          useragent = conn->allocptr.uagent;
+
+        result =
+          Curl_add_bufferf(req_buffer,
+                           "CONNECT %s HTTP/%s\r\n"
+                           "%s"  /* Host: */
+                           "%s"  /* Proxy-Authorization */
+                           "%s"  /* User-Agent */
+                           "%s", /* Proxy-Connection */
+                           hostheader,
+                           http,
+                           host,
+                           conn->allocptr.proxyuserpwd?
+                           conn->allocptr.proxyuserpwd:"",
+                           useragent,
+                           proxyconn);
+
+        if(host && *host)
+          free(host);
+        free(hostheader);
+
+        if(!result)
+          result = Curl_add_custom_headers(conn, TRUE, req_buffer);
+
+        if(!result)
+          /* CRLF terminate the request */
+          result = Curl_add_bufferf(req_buffer, "\r\n");
+
+        if(!result) {
+          /* Send the connect request to the proxy */
+          /* BLOCKING */
+          result =
+            Curl_add_buffer_send(req_buffer, conn,
+                                 &data->info.request_size, 0, sockindex);
+        }
+        req_buffer = NULL;
+        if(result)
+          failf(data, "Failed sending CONNECT to proxy");
+      }
+
+      Curl_add_buffer_free(req_buffer);
+      if(result)
+        return result;
+
+      conn->tunnel_state[sockindex] = TUNNEL_CONNECT;
+    } /* END CONNECT PHASE */
+
+    check = Curl_timeleft(data, NULL, TRUE);
+    if(check <= 0) {
+      failf(data, "Proxy CONNECT aborted due to timeout");
+      return CURLE_RECV_ERROR;
+    }
+
+    if(!blocking) {
+      if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0))
+        /* return so we'll be called again polling-style */
+        return CURLE_OK;
+      else {
+        DEBUGF(infof(data,
+               "Read response immediately from proxy CONNECT\n"));
+      }
+    }
+
+    /* at this point, the tunnel_connecting phase is over. */
+
+    { /* READING RESPONSE PHASE */
+      size_t nread;   /* total size read */
+      int perline; /* count bytes per line */
+      int keepon=TRUE;
+      ssize_t gotbytes;
+      char *ptr;
+      char *line_start;
+
+      ptr=data->state.buffer;
+      line_start = ptr;
+
+      nread=0;
+      perline=0;
+
+      while((nread<BUFSIZE) && (keepon && !error)) {
+
+        check = Curl_timeleft(data, NULL, TRUE);
+        if(check <= 0) {
+          failf(data, "Proxy CONNECT aborted due to timeout");
+          error = SELECT_TIMEOUT; /* already too little time */
+          break;
+        }
+
+        /* loop every second at least, less if the timeout is near */
+        switch (Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD,
+                                  check<1000L?check:1000)) {
+        case -1: /* select() error, stop reading */
+          error = SELECT_ERROR;
+          failf(data, "Proxy CONNECT aborted due to select/poll error");
+          break;
+        case 0: /* timeout */
+          break;
+        default:
+          DEBUGASSERT(ptr+BUFSIZE-nread <= data->state.buffer+BUFSIZE+1);
+          result = Curl_read(conn, tunnelsocket, ptr, BUFSIZE-nread,
+                             &gotbytes);
+          if(result==CURLE_AGAIN)
+            continue; /* go loop yourself */
+          else if(result)
+            keepon = FALSE;
+          else if(gotbytes <= 0) {
+            keepon = FALSE;
+            if(data->set.proxyauth && data->state.authproxy.avail) {
+              /* proxy auth was requested and there was proxy auth available,
+                 then deem this as "mere" proxy disconnect */
+              conn->bits.proxy_connect_closed = TRUE;
+              infof(data, "Proxy CONNECT connection closed\n");
+            }
+            else {
+              error = SELECT_ERROR;
+              failf(data, "Proxy CONNECT aborted");
+            }
+          }
+          else {
+            /*
+             * We got a whole chunk of data, which can be anything from one
+             * byte to a set of lines and possibly just a piece of the last
+             * line.
+             */
+            int i;
+
+            nread += gotbytes;
+
+            if(keepon > TRUE) {
+              /* This means we are currently ignoring a response-body */
+
+              nread = 0; /* make next read start over in the read buffer */
+              ptr=data->state.buffer;
+              if(cl) {
+                /* A Content-Length based body: simply count down the counter
+                   and make sure to break out of the loop when we're done! */
+                cl -= gotbytes;
+                if(cl<=0) {
+                  keepon = FALSE;
+                  break;
+                }
+              }
+              else {
+                /* chunked-encoded body, so we need to do the chunked dance
+                   properly to know when the end of the body is reached */
+                CHUNKcode r;
+                ssize_t tookcareof=0;
+
+                /* now parse the chunked piece of data so that we can
+                   properly tell when the stream ends */
+                r = Curl_httpchunk_read(conn, ptr, gotbytes, &tookcareof);
+                if(r == CHUNKE_STOP) {
+                  /* we're done reading chunks! */
+                  infof(data, "chunk reading DONE\n");
+                  keepon = FALSE;
+                  /* we did the full CONNECT treatment, go COMPLETE */
+                  conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
+                }
+                else
+                  infof(data, "Read %zd bytes of chunk, continue\n",
+                        tookcareof);
+              }
+            }
+            else
+              for(i = 0; i < gotbytes; ptr++, i++) {
+                perline++; /* amount of bytes in this line so far */
+                if(*ptr == 0x0a) {
+                  char letter;
+                  int writetype;
+
+                  /* convert from the network encoding */
+                  result = Curl_convert_from_network(data, line_start,
+                                                     perline);
+                  /* Curl_convert_from_network calls failf if unsuccessful */
+                  if(result)
+                    return result;
+
+                  /* output debug if that is requested */
+                  if(data->set.verbose)
+                    Curl_debug(data, CURLINFO_HEADER_IN,
+                               line_start, (size_t)perline, conn);
+
+                  /* send the header to the callback */
+                  writetype = CLIENTWRITE_HEADER;
+                  if(data->set.include_header)
+                    writetype |= CLIENTWRITE_BODY;
+
+                  result = Curl_client_write(conn, writetype, line_start,
+                                             perline);
+
+                  data->info.header_size += (long)perline;
+                  data->req.headerbytecount += (long)perline;
+
+                  if(result)
+                    return result;
+
+                  /* Newlines are CRLF, so the CR is ignored as the line isn't
+                     really terminated until the LF comes. Treat a following CR
+                     as end-of-headers as well.*/
+
+                  if(('\r' == line_start[0]) ||
+                     ('\n' == line_start[0])) {
+                    /* end of response-headers from the proxy */
+                    nread = 0; /* make next read start over in the read
+                                  buffer */
+                    ptr=data->state.buffer;
+                    if((407 == k->httpcode) && !data->state.authproblem) {
+                      /* If we get a 407 response code with content length
+                         when we have no auth problem, we must ignore the
+                         whole response-body */
+                      keepon = 2;
+
+                      if(cl) {
+                        infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T
+                              " bytes of response-body\n", cl);
+
+                        /* remove the remaining chunk of what we already
+                           read */
+                        cl -= (gotbytes - i);
+
+                        if(cl<=0)
+                          /* if the whole thing was already read, we are done!
+                           */
+                          keepon=FALSE;
+                      }
+                      else if(chunked_encoding) {
+                        CHUNKcode r;
+                        /* We set ignorebody true here since the chunked
+                           decoder function will acknowledge that. Pay
+                           attention so that this is cleared again when this
+                           function returns! */
+                        k->ignorebody = TRUE;
+                        infof(data, "%zd bytes of chunk left\n", gotbytes-i);
+
+                        if(line_start[1] == '\n') {
+                          /* this can only be a LF if the letter at index 0
+                             was a CR */
+                          line_start++;
+                          i++;
+                        }
+
+                        /* now parse the chunked piece of data so that we can
+                           properly tell when the stream ends */
+                        r = Curl_httpchunk_read(conn, line_start+1,
+                                                  gotbytes -i, &gotbytes);
+                        if(r == CHUNKE_STOP) {
+                          /* we're done reading chunks! */
+                          infof(data, "chunk reading DONE\n");
+                          keepon = FALSE;
+                          /* we did the full CONNECT treatment, go to
+                             COMPLETE */
+                          conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
+                        }
+                        else
+                          infof(data, "Read %zd bytes of chunk, continue\n",
+                                gotbytes);
+                      }
+                      else {
+                        /* without content-length or chunked encoding, we
+                           can't keep the connection alive since the close is
+                           the end signal so we bail out at once instead */
+                        keepon=FALSE;
+                      }
+                    }
+                    else {
+                      keepon = FALSE;
+                      if(200 == data->info.httpproxycode) {
+                        if(gotbytes - (i+1))
+                          failf(data, "Proxy CONNECT followed by %zd bytes "
+                                "of opaque data. Data ignored (known bug #39)",
+                                gotbytes - (i+1));
+                      }
+                    }
+                    /* we did the full CONNECT treatment, go to COMPLETE */
+                    conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
+                    break; /* breaks out of for-loop, not switch() */
+                  }
+
+                  /* keep a backup of the position we are about to blank */
+                  letter = line_start[perline];
+                  line_start[perline]=0; /* zero terminate the buffer */
+                  if((checkprefix("WWW-Authenticate:", line_start) &&
+                      (401 == k->httpcode)) ||
+                     (checkprefix("Proxy-authenticate:", line_start) &&
+                      (407 == k->httpcode))) {
+
+                    bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
+                    char *auth = Curl_copy_header_value(line_start);
+                    if(!auth)
+                      return CURLE_OUT_OF_MEMORY;
+
+                    result = Curl_http_input_auth(conn, proxy, auth);
+
+                    free(auth);
+
+                    if(result)
+                      return result;
+                  }
+                  else if(checkprefix("Content-Length:", line_start)) {
+                    cl = curlx_strtoofft(line_start +
+                                         strlen("Content-Length:"), NULL, 10);
+                  }
+                  else if(Curl_compareheader(line_start,
+                                             "Connection:", "close"))
+                    closeConnection = TRUE;
+                  else if(Curl_compareheader(line_start,
+                                             "Transfer-Encoding:",
+                                             "chunked")) {
+                    infof(data, "CONNECT responded chunked\n");
+                    chunked_encoding = TRUE;
+                    /* init our chunky engine */
+                    Curl_httpchunk_init(conn);
+                  }
+                  else if(Curl_compareheader(line_start,
+                                             "Proxy-Connection:", "close"))
+                    closeConnection = TRUE;
+                  else if(2 == sscanf(line_start, "HTTP/1.%d %d",
+                                      &subversion,
+                                      &k->httpcode)) {
+                    /* store the HTTP code from the proxy */
+                    data->info.httpproxycode = k->httpcode;
+                  }
+                  /* put back the letter we blanked out before */
+                  line_start[perline]= letter;
+
+                  perline=0; /* line starts over here */
+                  line_start = ptr+1; /* this skips the zero byte we wrote */
+                }
+              }
+          }
+          break;
+        } /* switch */
+        if(Curl_pgrsUpdate(conn))
+          return CURLE_ABORTED_BY_CALLBACK;
+      } /* while there's buffer left and loop is requested */
+
+      if(error)
+        return CURLE_RECV_ERROR;
+
+      if(data->info.httpproxycode != 200) {
+        /* Deal with the possibly already received authenticate
+           headers. 'newurl' is set to a new URL if we must loop. */
+        result = Curl_http_auth_act(conn);
+        if(result)
+          return result;
+
+        if(conn->bits.close)
+          /* the connection has been marked for closure, most likely in the
+             Curl_http_auth_act() function and thus we can kill it at once
+             below
+          */
+          closeConnection = TRUE;
+      }
+
+      if(closeConnection && data->req.newurl) {
+        /* Connection closed by server. Don't use it anymore */
+        Curl_closesocket(conn, conn->sock[sockindex]);
+        conn->sock[sockindex] = CURL_SOCKET_BAD;
+        break;
+      }
+    } /* END READING RESPONSE PHASE */
+
+    /* If we are supposed to continue and request a new URL, which basically
+     * means the HTTP authentication is still going on so if the tunnel
+     * is complete we start over in INIT state */
+    if(data->req.newurl &&
+       (TUNNEL_COMPLETE == conn->tunnel_state[sockindex])) {
+      conn->tunnel_state[sockindex] = TUNNEL_INIT;
+      infof(data, "TUNNEL_STATE switched to: %d\n",
+            conn->tunnel_state[sockindex]);
+    }
+
+  } while(data->req.newurl);
+
+  if(200 != data->req.httpcode) {
+    if(closeConnection && data->req.newurl) {
+      conn->bits.proxy_connect_closed = TRUE;
+      infof(data, "Connect me again please\n");
+    }
+    else {
+      free(data->req.newurl);
+      data->req.newurl = NULL;
+      /* failure, close this connection to avoid re-use */
+      connclose(conn, "proxy CONNECT failure");
+      Curl_closesocket(conn, conn->sock[sockindex]);
+      conn->sock[sockindex] = CURL_SOCKET_BAD;
+    }
+
+    /* to back to init state */
+    conn->tunnel_state[sockindex] = TUNNEL_INIT;
+
+    if(conn->bits.proxy_connect_closed)
+      /* this is not an error, just part of the connection negotiation */
+      return CURLE_OK;
+    else {
+      failf(data, "Received HTTP code %d from proxy after CONNECT",
+            data->req.httpcode);
+      return CURLE_RECV_ERROR;
+    }
+  }
+
+  conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
+
+  /* If a proxy-authorization header was used for the proxy, then we should
+     make sure that it isn't accidentally used for the document request
+     after we've connected. So let's free and clear it here. */
+  Curl_safefree(conn->allocptr.proxyuserpwd);
+  conn->allocptr.proxyuserpwd = NULL;
+
+  data->state.authproxy.done = TRUE;
+
+  infof (data, "Proxy replied OK to CONNECT request\n");
+  data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */
+  conn->bits.rewindaftersend = FALSE; /* make sure this isn't set for the
+                                         document request  */
+  return CURLE_OK;
+}
+#endif /* CURL_DISABLE_PROXY */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/http_proxy.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/http_proxy.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/http_proxy.h	(revision 164)
@@ -0,0 +1,42 @@
+#ifndef HEADER_CURL_HTTP_PROXY_H
+#define HEADER_CURL_HTTP_PROXY_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
+/* ftp can use this as well */
+CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+                           int tunnelsocket,
+                           const char *hostname, int remote_port,
+                           bool blocking);
+
+/* Default proxy timeout in milliseconds */
+#define PROXY_TIMEOUT (3600*1000)
+
+CURLcode Curl_proxy_connect(struct connectdata *conn);
+
+#else
+#define Curl_proxyCONNECT(x,y,z,w,v) CURLE_NOT_BUILT_IN
+#define Curl_proxy_connect(x) CURLE_OK
+#endif
+
+#endif /* HEADER_CURL_HTTP_PROXY_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/idn_win32.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/idn_win32.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/idn_win32.c	(revision 164)
@@ -0,0 +1,104 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+ /*
+  * IDN conversions using Windows kernel32 and normaliz libraries.
+  */
+
+#include "curl_setup.h"
+
+#ifdef USE_WIN32_IDN
+
+#include "curl_multibyte.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifdef WANT_IDN_PROTOTYPES
+#  if defined(_SAL_VERSION)
+WINNORMALIZEAPI int WINAPI
+IdnToAscii(_In_                           DWORD    dwFlags,
+           _In_reads_(cchUnicodeChar)     LPCWSTR  lpUnicodeCharStr,
+           _In_                           int      cchUnicodeChar,
+           _Out_writes_opt_(cchASCIIChar) LPWSTR   lpASCIICharStr,
+           _In_                           int      cchASCIIChar);
+WINNORMALIZEAPI int WINAPI
+IdnToUnicode(_In_                             DWORD   dwFlags,
+             _In_reads_(cchASCIIChar)         LPCWSTR lpASCIICharStr,
+             _In_                             int     cchASCIIChar,
+             _Out_writes_opt_(cchUnicodeChar) LPWSTR  lpUnicodeCharStr,
+             _In_                             int     cchUnicodeChar);
+#  else
+WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags,
+                                 const WCHAR *lpUnicodeCharStr,
+                                 int cchUnicodeChar,
+                                 WCHAR *lpASCIICharStr,
+                                 int cchASCIIChar);
+WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags,
+                                   const WCHAR *lpASCIICharStr,
+                                   int cchASCIIChar,
+                                   WCHAR *lpUnicodeCharStr,
+                                   int cchUnicodeChar);
+#  endif
+#endif
+
+#define IDN_MAX_LENGTH 255
+
+int curl_win32_idn_to_ascii(const char *in, char **out);
+int curl_win32_ascii_to_idn(const char *in, char **out);
+
+int curl_win32_idn_to_ascii(const char *in, char **out)
+{
+  int ret = 0;
+  wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
+  if(in_w) {
+    wchar_t punycode[IDN_MAX_LENGTH];
+    int chars = IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH);
+    free(in_w);
+    if(chars) {
+      *out = Curl_convert_wchar_to_UTF8(punycode);
+      if(*out)
+        ret = 1; /* success */
+    }
+  }
+  return ret;
+}
+
+int curl_win32_ascii_to_idn(const char *in, char **out)
+{
+  int ret = 0;
+  wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
+  if(in_w) {
+    wchar_t unicode[IDN_MAX_LENGTH];
+    int chars = IdnToUnicode(0, in_w, wcslen(in_w)+1, unicode, IDN_MAX_LENGTH);
+    free(in_w);
+    if(chars) {
+      *out = Curl_convert_wchar_to_UTF8(unicode);
+      if(*out)
+        ret = 1; /* success */
+    }
+  }
+  return ret;
+}
+
+#endif /* USE_WIN32_IDN */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/if2ip.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/if2ip.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/if2ip.c	(revision 164)
@@ -0,0 +1,273 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#  include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#  include <sys/ioctl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+#  include <sys/sockio.h>
+#endif
+#ifdef HAVE_IFADDRS_H
+#  include <ifaddrs.h>
+#endif
+#ifdef HAVE_STROPTS_H
+#  include <stropts.h>
+#endif
+#ifdef __VMS
+#  include <inet.h>
+#endif
+
+#include "inet_ntop.h"
+#include "strequal.h"
+#include "if2ip.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* ------------------------------------------------------------------ */
+
+/* Return the scope of the given address. */
+unsigned int Curl_ipv6_scope(const struct sockaddr *sa)
+{
+#ifndef ENABLE_IPV6
+  (void) sa;
+#else
+  if(sa->sa_family == AF_INET6) {
+    const struct sockaddr_in6 * sa6 = (const struct sockaddr_in6 *)(void *) sa;
+    const unsigned char * b = sa6->sin6_addr.s6_addr;
+    unsigned short w = (unsigned short) ((b[0] << 8) | b[1]);
+
+    switch(w & 0xFFC0) {
+    case 0xFE80:
+      return IPV6_SCOPE_LINKLOCAL;
+    case 0xFEC0:
+      return IPV6_SCOPE_SITELOCAL;
+    case 0x0000:
+      w = b[1] | b[2] | b[3] | b[4] | b[5] | b[6] | b[7] | b[8] | b[9] |
+          b[10] | b[11] | b[12] | b[13] | b[14];
+      if(w || b[15] != 0x01)
+        break;
+      return IPV6_SCOPE_NODELOCAL;
+    default:
+      break;
+    }
+  }
+#endif
+
+  return IPV6_SCOPE_GLOBAL;
+}
+
+
+#if defined(HAVE_GETIFADDRS)
+
+bool Curl_if_is_interface_name(const char *interf)
+{
+  bool result = FALSE;
+
+  struct ifaddrs *iface, *head;
+
+  if(getifaddrs(&head) >= 0) {
+    for(iface=head; iface != NULL; iface=iface->ifa_next) {
+      if(curl_strequal(iface->ifa_name, interf)) {
+        result = TRUE;
+        break;
+      }
+    }
+    freeifaddrs(head);
+  }
+  return result;
+}
+
+if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
+                          unsigned int remote_scope_id, const char *interf,
+                          char *buf, int buf_size)
+{
+  struct ifaddrs *iface, *head;
+  if2ip_result_t res = IF2IP_NOT_FOUND;
+
+#ifndef ENABLE_IPV6
+  (void) remote_scope;
+
+#ifndef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+  (void) remote_scope_id;
+#endif
+
+#endif
+
+  if(getifaddrs(&head) >= 0) {
+    for(iface = head; iface != NULL; iface=iface->ifa_next) {
+      if(iface->ifa_addr != NULL) {
+        if(iface->ifa_addr->sa_family == af) {
+          if(curl_strequal(iface->ifa_name, interf)) {
+            void *addr;
+            char *ip;
+            char scope[12] = "";
+            char ipstr[64];
+#ifdef ENABLE_IPV6
+            if(af == AF_INET6) {
+              unsigned int scopeid = 0;
+              unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr);
+
+              if(ifscope != remote_scope) {
+                /* We are interested only in interface addresses whose
+                   scope matches the remote address we want to
+                   connect to: global for global, link-local for
+                   link-local, etc... */
+                if(res == IF2IP_NOT_FOUND) res = IF2IP_AF_NOT_SUPPORTED;
+                continue;
+              }
+
+              addr =
+                &((struct sockaddr_in6 *)(void *)iface->ifa_addr)->sin6_addr;
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+              /* Include the scope of this interface as part of the address */
+              scopeid = ((struct sockaddr_in6 *)(void *)iface->ifa_addr)
+                            ->sin6_scope_id;
+
+              /* If given, scope id should match. */
+              if(remote_scope_id && scopeid != remote_scope_id) {
+                if(res == IF2IP_NOT_FOUND)
+                  res = IF2IP_AF_NOT_SUPPORTED;
+
+                continue;
+              }
+#endif
+              if(scopeid)
+                snprintf(scope, sizeof(scope), "%%%u", scopeid);
+            }
+            else
+#endif
+              addr =
+                  &((struct sockaddr_in *)(void *)iface->ifa_addr)->sin_addr;
+            res = IF2IP_FOUND;
+            ip = (char *) Curl_inet_ntop(af, addr, ipstr, sizeof(ipstr));
+            snprintf(buf, buf_size, "%s%s", ip, scope);
+            break;
+          }
+        }
+        else if((res == IF2IP_NOT_FOUND) &&
+                curl_strequal(iface->ifa_name, interf)) {
+          res = IF2IP_AF_NOT_SUPPORTED;
+        }
+      }
+    }
+
+    freeifaddrs(head);
+  }
+
+  return res;
+}
+
+#elif defined(HAVE_IOCTL_SIOCGIFADDR)
+
+bool Curl_if_is_interface_name(const char *interf)
+{
+  /* This is here just to support the old interfaces */
+  char buf[256];
+
+  return (Curl_if2ip(AF_INET, 0 /* unused */, 0, interf, buf, sizeof(buf)) ==
+          IF2IP_NOT_FOUND) ? FALSE : TRUE;
+}
+
+if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
+                          unsigned int remote_scope_id, const char *interf,
+                          char *buf, int buf_size)
+{
+  struct ifreq req;
+  struct in_addr in;
+  struct sockaddr_in *s;
+  curl_socket_t dummy;
+  size_t len;
+
+  (void)remote_scope;
+  (void)remote_scope_id;
+
+  if(!interf || (af != AF_INET))
+    return IF2IP_NOT_FOUND;
+
+  len = strlen(interf);
+  if(len >= sizeof(req.ifr_name))
+    return IF2IP_NOT_FOUND;
+
+  dummy = socket(AF_INET, SOCK_STREAM, 0);
+  if(CURL_SOCKET_BAD == dummy)
+    return IF2IP_NOT_FOUND;
+
+  memset(&req, 0, sizeof(req));
+  memcpy(req.ifr_name, interf, len+1);
+  req.ifr_addr.sa_family = AF_INET;
+
+  if(ioctl(dummy, SIOCGIFADDR, &req) < 0) {
+    sclose(dummy);
+    /* With SIOCGIFADDR, we cannot tell the difference between an interface
+       that does not exist and an interface that has no address of the
+       correct family. Assume the interface does not exist */
+    return IF2IP_NOT_FOUND;
+  }
+
+  s = (struct sockaddr_in *)&req.ifr_addr;
+  memcpy(&in, &s->sin_addr, sizeof(in));
+  Curl_inet_ntop(s->sin_family, &in, buf, buf_size);
+
+  sclose(dummy);
+  return IF2IP_FOUND;
+}
+
+#else
+
+bool Curl_if_is_interface_name(const char *interf)
+{
+  (void) interf;
+
+  return FALSE;
+}
+
+if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
+                          unsigned int remote_scope_id, const char *interf,
+                          char *buf, int buf_size)
+{
+    (void) af;
+    (void) remote_scope;
+    (void) remote_scope_id;
+    (void) interf;
+    (void) buf;
+    (void) buf_size;
+    return IF2IP_NOT_FOUND;
+}
+
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/lib/if2ip.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/if2ip.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/if2ip.h	(revision 164)
@@ -0,0 +1,83 @@
+#ifndef HEADER_CURL_IF2IP_H
+#define HEADER_CURL_IF2IP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/* IPv6 address scopes. */
+#define IPV6_SCOPE_GLOBAL       0       /* Global scope. */
+#define IPV6_SCOPE_LINKLOCAL    1       /* Link-local scope. */
+#define IPV6_SCOPE_SITELOCAL    2       /* Site-local scope (deprecated). */
+#define IPV6_SCOPE_NODELOCAL    3       /* Loopback. */
+
+unsigned int Curl_ipv6_scope(const struct sockaddr *sa);
+
+bool Curl_if_is_interface_name(const char *interf);
+
+typedef enum {
+  IF2IP_NOT_FOUND = 0, /* Interface not found */
+  IF2IP_AF_NOT_SUPPORTED = 1, /* Int. exists but has no address for this af */
+  IF2IP_FOUND = 2 /* The address has been stored in "buf" */
+} if2ip_result_t;
+
+if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
+                          unsigned int remote_scope_id, const char *interf,
+                          char *buf, int buf_size);
+
+#ifdef __INTERIX
+
+/* Nedelcho Stanev's work-around for SFU 3.0 */
+struct ifreq {
+#define IFNAMSIZ 16
+#define IFHWADDRLEN 6
+  union {
+    char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+  } ifr_ifrn;
+
+ union {
+   struct sockaddr ifru_addr;
+   struct sockaddr ifru_broadaddr;
+   struct sockaddr ifru_netmask;
+   struct sockaddr ifru_hwaddr;
+   short ifru_flags;
+   int ifru_metric;
+   int ifru_mtu;
+ } ifr_ifru;
+};
+
+/* This define was added by Daniel to avoid an extra #ifdef INTERIX in the
+   C code. */
+
+#define ifr_name ifr_ifrn.ifrn_name /* interface name */
+#define ifr_addr ifr_ifru.ifru_addr /* address */
+#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
+#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
+#define ifr_flags ifr_ifru.ifru_flags /* flags */
+#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
+#define ifr_metric ifr_ifru.ifru_metric /* metric */
+#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
+
+#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */
+
+#endif /* __INTERIX */
+
+#endif /* HEADER_CURL_IF2IP_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/imap.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/imap.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/imap.c	(revision 164)
@@ -0,0 +1,2152 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC2195 CRAM-MD5 authentication
+ * RFC2595 Using TLS with IMAP, POP3 and ACAP
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC3501 IMAPv4 protocol
+ * RFC4422 Simple Authentication and Security Layer (SASL)
+ * RFC4616 PLAIN authentication
+ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
+ * RFC4959 IMAP Extension for SASL Initial Client Response
+ * RFC5092 IMAP URL Scheme
+ * RFC6749 OAuth 2.0 Authorization Framework
+ * Draft   LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_IMAP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "socks.h"
+#include "imap.h"
+
+#include "strtoofft.h"
+#include "strequal.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "select.h"
+#include "multiif.h"
+#include "url.h"
+#include "rawstr.h"
+#include "curl_sasl.h"
+#include "warnless.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* Local API functions */
+static CURLcode imap_regular_transfer(struct connectdata *conn, bool *done);
+static CURLcode imap_do(struct connectdata *conn, bool *done);
+static CURLcode imap_done(struct connectdata *conn, CURLcode status,
+                          bool premature);
+static CURLcode imap_connect(struct connectdata *conn, bool *done);
+static CURLcode imap_disconnect(struct connectdata *conn, bool dead);
+static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done);
+static int imap_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks);
+static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done);
+static CURLcode imap_setup_connection(struct connectdata *conn);
+static char *imap_atom(const char *str, bool escape_only);
+static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...);
+static CURLcode imap_parse_url_options(struct connectdata *conn);
+static CURLcode imap_parse_url_path(struct connectdata *conn);
+static CURLcode imap_parse_custom_request(struct connectdata *conn);
+static CURLcode imap_perform_authenticate(struct connectdata *conn,
+                                          const char *mech,
+                                          const char *initresp);
+static CURLcode imap_continue_authenticate(struct connectdata *conn,
+                                           const char *resp);
+static void imap_get_message(char *buffer, char** outptr);
+
+/*
+ * IMAP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_imap = {
+  "IMAP",                           /* scheme */
+  imap_setup_connection,            /* setup_connection */
+  imap_do,                          /* do_it */
+  imap_done,                        /* done */
+  ZERO_NULL,                        /* do_more */
+  imap_connect,                     /* connect_it */
+  imap_multi_statemach,             /* connecting */
+  imap_doing,                       /* doing */
+  imap_getsock,                     /* proto_getsock */
+  imap_getsock,                     /* doing_getsock */
+  ZERO_NULL,                        /* domore_getsock */
+  ZERO_NULL,                        /* perform_getsock */
+  imap_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
+  PORT_IMAP,                        /* defport */
+  CURLPROTO_IMAP,                   /* protocol */
+  PROTOPT_CLOSEACTION               /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * IMAPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_imaps = {
+  "IMAPS",                          /* scheme */
+  imap_setup_connection,            /* setup_connection */
+  imap_do,                          /* do_it */
+  imap_done,                        /* done */
+  ZERO_NULL,                        /* do_more */
+  imap_connect,                     /* connect_it */
+  imap_multi_statemach,             /* connecting */
+  imap_doing,                       /* doing */
+  imap_getsock,                     /* proto_getsock */
+  imap_getsock,                     /* doing_getsock */
+  ZERO_NULL,                        /* domore_getsock */
+  ZERO_NULL,                        /* perform_getsock */
+  imap_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
+  PORT_IMAPS,                       /* defport */
+  CURLPROTO_IMAPS,                  /* protocol */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
+};
+#endif
+
+#ifndef CURL_DISABLE_HTTP
+/*
+ * HTTP-proxyed IMAP protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_imap_proxy = {
+  "IMAP",                               /* scheme */
+  Curl_http_setup_conn,                 /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_IMAP,                            /* defport */
+  CURLPROTO_HTTP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * HTTP-proxyed IMAPS protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_imaps_proxy = {
+  "IMAPS",                              /* scheme */
+  Curl_http_setup_conn,                 /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_IMAPS,                           /* defport */
+  CURLPROTO_HTTP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+#endif
+#endif
+
+/* SASL parameters for the imap protocol */
+static const struct SASLproto saslimap = {
+  "imap",                     /* The service name */
+  '+',                        /* Code received when continuation is expected */
+  'O',                        /* Code to receive upon authentication success */
+  0,                          /* Maximum initial response length (no max) */
+  imap_perform_authenticate,  /* Send authentication command */
+  imap_continue_authenticate, /* Send authentication continuation */
+  imap_get_message            /* Get SASL response message */
+};
+
+
+#ifdef USE_SSL
+static void imap_to_imaps(struct connectdata *conn)
+{
+  conn->handler = &Curl_handler_imaps;
+}
+#else
+#define imap_to_imaps(x) Curl_nop_stmt
+#endif
+
+/***********************************************************************
+ *
+ * imap_matchresp()
+ *
+ * Determines whether the untagged response is related to the specified
+ * command by checking if it is in format "* <command-name> ..." or
+ * "* <number> <command-name> ...".
+ *
+ * The "* " marker is assumed to have already been checked by the caller.
+ */
+static bool imap_matchresp(const char *line, size_t len, const char *cmd)
+{
+  const char *end = line + len;
+  size_t cmd_len = strlen(cmd);
+
+  /* Skip the untagged response marker */
+  line += 2;
+
+  /* Do we have a number after the marker? */
+  if(line < end && ISDIGIT(*line)) {
+    /* Skip the number */
+    do
+      line++;
+    while(line < end && ISDIGIT(*line));
+
+    /* Do we have the space character? */
+    if(line == end || *line != ' ')
+      return FALSE;
+
+    line++;
+  }
+
+  /* Does the command name match and is it followed by a space character or at
+     the end of line? */
+  if(line + cmd_len <= end && Curl_raw_nequal(line, cmd, cmd_len) &&
+     (line[cmd_len] == ' ' || line + cmd_len + 2 == end))
+    return TRUE;
+
+  return FALSE;
+}
+
+/***********************************************************************
+ *
+ * imap_endofresp()
+ *
+ * Checks whether the given string is a valid tagged, untagged or continuation
+ * response which can be processed by the response handler.
+ */
+static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,
+                           int *resp)
+{
+  struct IMAP *imap = conn->data->req.protop;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  const char *id = imapc->resptag;
+  size_t id_len = strlen(id);
+
+  /* Do we have a tagged command response? */
+  if(len >= id_len + 1 && !memcmp(id, line, id_len) && line[id_len] == ' ') {
+    line += id_len + 1;
+    len -= id_len + 1;
+
+    if(len >= 2 && !memcmp(line, "OK", 2))
+      *resp = 'O';
+    else if(len >= 2 && !memcmp(line, "NO", 2))
+      *resp = 'N';
+    else if(len >= 3 && !memcmp(line, "BAD", 3))
+      *resp = 'B';
+    else {
+      failf(conn->data, "Bad tagged response");
+      *resp = -1;
+    }
+
+    return TRUE;
+  }
+
+  /* Do we have an untagged command response? */
+  if(len >= 2 && !memcmp("* ", line, 2)) {
+    switch(imapc->state) {
+      /* States which are interested in untagged responses */
+      case IMAP_CAPABILITY:
+        if(!imap_matchresp(line, len, "CAPABILITY"))
+          return FALSE;
+        break;
+
+      case IMAP_LIST:
+        if((!imap->custom && !imap_matchresp(line, len, "LIST")) ||
+          (imap->custom && !imap_matchresp(line, len, imap->custom) &&
+           (strcmp(imap->custom, "STORE") ||
+            !imap_matchresp(line, len, "FETCH")) &&
+           strcmp(imap->custom, "SELECT") &&
+           strcmp(imap->custom, "EXAMINE") &&
+           strcmp(imap->custom, "SEARCH") &&
+           strcmp(imap->custom, "EXPUNGE") &&
+           strcmp(imap->custom, "LSUB") &&
+           strcmp(imap->custom, "UID") &&
+           strcmp(imap->custom, "NOOP")))
+          return FALSE;
+        break;
+
+      case IMAP_SELECT:
+        /* SELECT is special in that its untagged responses do not have a
+           common prefix so accept anything! */
+        break;
+
+      case IMAP_FETCH:
+        if(!imap_matchresp(line, len, "FETCH"))
+          return FALSE;
+        break;
+
+      case IMAP_SEARCH:
+        if(!imap_matchresp(line, len, "SEARCH"))
+          return FALSE;
+        break;
+
+      /* Ignore other untagged responses */
+      default:
+        return FALSE;
+    }
+
+    *resp = '*';
+    return TRUE;
+  }
+
+  /* Do we have a continuation response? This should be a + symbol followed by
+     a space and optionally some text as per RFC-3501 for the AUTHENTICATE and
+     APPEND commands and as outlined in Section 4. Examples of RFC-4959 but
+     some e-mail servers ignore this and only send a single + instead. */
+  if(!imap->custom && ((len == 3 && !memcmp("+", line, 1)) ||
+     (len >= 2 && !memcmp("+ ", line, 2)))) {
+    switch(imapc->state) {
+      /* States which are interested in continuation responses */
+      case IMAP_AUTHENTICATE:
+      case IMAP_APPEND:
+        *resp = '+';
+        break;
+
+      default:
+        failf(conn->data, "Unexpected continuation response");
+        *resp = -1;
+        break;
+    }
+
+    return TRUE;
+  }
+
+  return FALSE; /* Nothing for us */
+}
+
+/***********************************************************************
+ *
+ * imap_get_message()
+ *
+ * Gets the authentication message from the response buffer.
+ */
+static void imap_get_message(char *buffer, char** outptr)
+{
+  size_t len = 0;
+  char* message = NULL;
+
+  /* Find the start of the message */
+  for(message = buffer + 2; *message == ' ' || *message == '\t'; message++)
+    ;
+
+  /* Find the end of the message */
+  for(len = strlen(message); len--;)
+    if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' &&
+        message[len] != '\t')
+      break;
+
+  /* Terminate the message */
+  if(++len) {
+    message[len] = '\0';
+  }
+
+  *outptr = message;
+}
+
+/***********************************************************************
+ *
+ * state()
+ *
+ * This is the ONLY way to change IMAP state!
+ */
+static void state(struct connectdata *conn, imapstate newstate)
+{
+  struct imap_conn *imapc = &conn->proto.imapc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[]={
+    "STOP",
+    "SERVERGREET",
+    "CAPABILITY",
+    "STARTTLS",
+    "UPGRADETLS",
+    "AUTHENTICATE",
+    "LOGIN",
+    "LIST",
+    "SELECT",
+    "FETCH",
+    "FETCH_FINAL",
+    "APPEND",
+    "APPEND_FINAL",
+    "SEARCH",
+    "LOGOUT",
+    /* LAST */
+  };
+
+  if(imapc->state != newstate)
+    infof(conn->data, "IMAP %p state change from %s to %s\n",
+          (void *)imapc, names[imapc->state], names[newstate]);
+#endif
+
+  imapc->state = newstate;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_capability()
+ *
+ * Sends the CAPABILITY command in order to obtain a list of server side
+ * supported capabilities.
+ */
+static CURLcode imap_perform_capability(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+
+  imapc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */
+  imapc->sasl.authused = SASL_AUTH_NONE;  /* Clear the auth. mechanism used */
+  imapc->tls_supported = FALSE;           /* Clear the TLS capability */
+
+  /* Send the CAPABILITY command */
+  result = imap_sendf(conn, "CAPABILITY");
+
+  if(!result)
+    state(conn, IMAP_CAPABILITY);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_starttls()
+ *
+ * Sends the STARTTLS command to start the upgrade to TLS.
+ */
+static CURLcode imap_perform_starttls(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Send the STARTTLS command */
+  result = imap_sendf(conn, "STARTTLS");
+
+  if(!result)
+    state(conn, IMAP_STARTTLS);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_upgrade_tls()
+ *
+ * Performs the upgrade to TLS.
+ */
+static CURLcode imap_perform_upgrade_tls(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+
+  /* Start the SSL connection */
+  result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone);
+
+  if(!result) {
+    if(imapc->state != IMAP_UPGRADETLS)
+      state(conn, IMAP_UPGRADETLS);
+
+    if(imapc->ssldone) {
+      imap_to_imaps(conn);
+      result = imap_perform_capability(conn);
+    }
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_login()
+ *
+ * Sends a clear text LOGIN command to authenticate with.
+ */
+static CURLcode imap_perform_login(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  char *user;
+  char *passwd;
+
+  /* Check we have a username and password to authenticate with and end the
+     connect phase if we don't */
+  if(!conn->bits.user_passwd) {
+    state(conn, IMAP_STOP);
+
+    return result;
+  }
+
+  /* Make sure the username and password are in the correct atom format */
+  user = imap_atom(conn->user, false);
+  passwd = imap_atom(conn->passwd, false);
+
+  /* Send the LOGIN command */
+  result = imap_sendf(conn, "LOGIN %s %s", user ? user : "",
+                      passwd ? passwd : "");
+
+  free(user);
+  free(passwd);
+
+  if(!result)
+    state(conn, IMAP_LOGIN);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_authenticate()
+ *
+ * Sends an AUTHENTICATE command allowing the client to login with the given
+ * SASL authentication mechanism.
+ */
+static CURLcode imap_perform_authenticate(struct connectdata *conn,
+                                          const char *mech,
+                                          const char *initresp)
+{
+  CURLcode result = CURLE_OK;
+
+  if(initresp) {
+    /* Send the AUTHENTICATE command with the initial response */
+    result = imap_sendf(conn, "AUTHENTICATE %s %s", mech, initresp);
+  }
+  else {
+    /* Send the AUTHENTICATE command */
+    result = imap_sendf(conn, "AUTHENTICATE %s", mech);
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_continue_authenticate()
+ *
+ * Sends SASL continuation data or cancellation.
+ */
+static CURLcode imap_continue_authenticate(struct connectdata *conn,
+                                           const char *resp)
+{
+  struct imap_conn *imapc = &conn->proto.imapc;
+
+  return Curl_pp_sendf(&imapc->pp, "%s", resp);
+}
+
+/***********************************************************************
+ *
+ * imap_perform_authentication()
+ *
+ * Initiates the authentication sequence, with the appropriate SASL
+ * authentication mechanism, falling back to clear text should a common
+ * mechanism not be available between the client and server.
+ */
+static CURLcode imap_perform_authentication(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  saslprogress progress;
+
+  /* Check we have enough data to authenticate with and end the
+     connect phase if we don't */
+  if(!Curl_sasl_can_authenticate(&imapc->sasl, conn)) {
+    state(conn, IMAP_STOP);
+    return result;
+  }
+
+  /* Calculate the SASL login details */
+  result = Curl_sasl_start(&imapc->sasl, conn, imapc->ir_supported, &progress);
+
+  if(!result) {
+    if(progress == SASL_INPROGRESS)
+      state(conn, IMAP_AUTHENTICATE);
+    else if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
+      /* Perform clear text authentication */
+      result = imap_perform_login(conn);
+    else {
+      /* Other mechanisms not supported */
+      infof(conn->data, "No known authentication mechanisms supported!\n");
+      result = CURLE_LOGIN_DENIED;
+    }
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_list()
+ *
+ * Sends a LIST command or an alternative custom request.
+ */
+static CURLcode imap_perform_list(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct IMAP *imap = data->req.protop;
+  char *mailbox;
+
+  if(imap->custom)
+    /* Send the custom request */
+    result = imap_sendf(conn, "%s%s", imap->custom,
+                        imap->custom_params ? imap->custom_params : "");
+  else {
+    /* Make sure the mailbox is in the correct atom format if necessary */
+    mailbox = imap->mailbox ? imap_atom(imap->mailbox, true) : strdup("");
+    if(!mailbox)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Send the LIST command */
+    result = imap_sendf(conn, "LIST \"%s\" *", mailbox);
+
+    free(mailbox);
+  }
+
+  if(!result)
+    state(conn, IMAP_LIST);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_select()
+ *
+ * Sends a SELECT command to ask the server to change the selected mailbox.
+ */
+static CURLcode imap_perform_select(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct IMAP *imap = data->req.protop;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  char *mailbox;
+
+  /* Invalidate old information as we are switching mailboxes */
+  Curl_safefree(imapc->mailbox);
+  Curl_safefree(imapc->mailbox_uidvalidity);
+
+  /* Check we have a mailbox */
+  if(!imap->mailbox) {
+    failf(conn->data, "Cannot SELECT without a mailbox.");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /* Make sure the mailbox is in the correct atom format */
+  mailbox = imap_atom(imap->mailbox, false);
+  if(!mailbox)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Send the SELECT command */
+  result = imap_sendf(conn, "SELECT %s", mailbox);
+
+  free(mailbox);
+
+  if(!result)
+    state(conn, IMAP_SELECT);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_fetch()
+ *
+ * Sends a FETCH command to initiate the download of a message.
+ */
+static CURLcode imap_perform_fetch(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct IMAP *imap = conn->data->req.protop;
+
+  /* Check we have a UID */
+  if(!imap->uid) {
+    failf(conn->data, "Cannot FETCH without a UID.");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /* Send the FETCH command */
+  if(imap->partial)
+    result = imap_sendf(conn, "FETCH %s BODY[%s]<%s>",
+                        imap->uid,
+                        imap->section ? imap->section : "",
+                        imap->partial);
+  else
+    result = imap_sendf(conn, "FETCH %s BODY[%s]",
+                        imap->uid,
+                        imap->section ? imap->section : "");
+
+  if(!result)
+    state(conn, IMAP_FETCH);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_append()
+ *
+ * Sends an APPEND command to initiate the upload of a message.
+ */
+static CURLcode imap_perform_append(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct IMAP *imap = conn->data->req.protop;
+  char *mailbox;
+
+  /* Check we have a mailbox */
+  if(!imap->mailbox) {
+    failf(conn->data, "Cannot APPEND without a mailbox.");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /* Check we know the size of the upload */
+  if(conn->data->state.infilesize < 0) {
+    failf(conn->data, "Cannot APPEND with unknown input file size\n");
+    return CURLE_UPLOAD_FAILED;
+  }
+
+  /* Make sure the mailbox is in the correct atom format */
+  mailbox = imap_atom(imap->mailbox, false);
+  if(!mailbox)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Send the APPEND command */
+  result = imap_sendf(conn, "APPEND %s (\\Seen) {%" CURL_FORMAT_CURL_OFF_T "}",
+                      mailbox, conn->data->state.infilesize);
+
+  free(mailbox);
+
+  if(!result)
+    state(conn, IMAP_APPEND);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_search()
+ *
+ * Sends a SEARCH command.
+ */
+static CURLcode imap_perform_search(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct IMAP *imap = conn->data->req.protop;
+
+  /* Check we have a query string */
+  if(!imap->query) {
+    failf(conn->data, "Cannot SEARCH without a query string.");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /* Send the SEARCH command */
+  result = imap_sendf(conn, "SEARCH %s", imap->query);
+
+  if(!result)
+    state(conn, IMAP_SEARCH);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_logout()
+ *
+ * Performs the logout action prior to sclose() being called.
+ */
+static CURLcode imap_perform_logout(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Send the LOGOUT command */
+  result = imap_sendf(conn, "LOGOUT");
+
+  if(!result)
+    state(conn, IMAP_LOGOUT);
+
+  return result;
+}
+
+/* For the initial server greeting */
+static CURLcode imap_state_servergreet_resp(struct connectdata *conn,
+                                            int imapcode,
+                                            imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(imapcode != 'O') {
+    failf(data, "Got unexpected imap-server response");
+    result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: fix this code */
+  }
+  else
+    result = imap_perform_capability(conn);
+
+  return result;
+}
+
+/* For CAPABILITY responses */
+static CURLcode imap_state_capability_resp(struct connectdata *conn,
+                                           int imapcode,
+                                           imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  const char *line = data->state.buffer;
+  size_t wordlen;
+
+  (void)instate; /* no use for this yet */
+
+  /* Do we have a untagged response? */
+  if(imapcode == '*') {
+    line += 2;
+
+    /* Loop through the data line */
+    for(;;) {
+      while(*line &&
+            (*line == ' ' || *line == '\t' ||
+              *line == '\r' || *line == '\n')) {
+
+        line++;
+      }
+
+      if(!*line)
+        break;
+
+      /* Extract the word */
+      for(wordlen = 0; line[wordlen] && line[wordlen] != ' ' &&
+            line[wordlen] != '\t' && line[wordlen] != '\r' &&
+            line[wordlen] != '\n';)
+        wordlen++;
+
+      /* Does the server support the STARTTLS capability? */
+      if(wordlen == 8 && !memcmp(line, "STARTTLS", 8))
+        imapc->tls_supported = TRUE;
+
+      /* Has the server explicitly disabled clear text authentication? */
+      else if(wordlen == 13 && !memcmp(line, "LOGINDISABLED", 13))
+        imapc->login_disabled = TRUE;
+
+      /* Does the server support the SASL-IR capability? */
+      else if(wordlen == 7 && !memcmp(line, "SASL-IR", 7))
+        imapc->ir_supported = TRUE;
+
+      /* Do we have a SASL based authentication mechanism? */
+      else if(wordlen > 5 && !memcmp(line, "AUTH=", 5)) {
+        size_t llen;
+        unsigned int mechbit;
+
+        line += 5;
+        wordlen -= 5;
+
+        /* Test the word for a matching authentication mechanism */
+        if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
+           llen == wordlen)
+          imapc->sasl.authmechs |= mechbit;
+      }
+
+      line += wordlen;
+    }
+  }
+  else if(imapcode == 'O') {
+    if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+      /* We don't have a SSL/TLS connection yet, but SSL is requested */
+      if(imapc->tls_supported)
+        /* Switch to TLS connection now */
+        result = imap_perform_starttls(conn);
+      else if(data->set.use_ssl == CURLUSESSL_TRY)
+        /* Fallback and carry on with authentication */
+        result = imap_perform_authentication(conn);
+      else {
+        failf(data, "STARTTLS not supported.");
+        result = CURLE_USE_SSL_FAILED;
+      }
+    }
+    else
+      result = imap_perform_authentication(conn);
+  }
+  else
+    result = imap_perform_authentication(conn);
+
+  return result;
+}
+
+/* For STARTTLS responses */
+static CURLcode imap_state_starttls_resp(struct connectdata *conn,
+                                         int imapcode,
+                                         imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(imapcode != 'O') {
+    if(data->set.use_ssl != CURLUSESSL_TRY) {
+      failf(data, "STARTTLS denied. %c", imapcode);
+      result = CURLE_USE_SSL_FAILED;
+    }
+    else
+      result = imap_perform_authentication(conn);
+  }
+  else
+    result = imap_perform_upgrade_tls(conn);
+
+  return result;
+}
+
+/* For SASL authentication responses */
+static CURLcode imap_state_auth_resp(struct connectdata *conn,
+                                     int imapcode,
+                                     imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  saslprogress progress;
+
+  (void)instate; /* no use for this yet */
+
+  result = Curl_sasl_continue(&imapc->sasl, conn, imapcode, &progress);
+  if(!result)
+    switch(progress) {
+    case SASL_DONE:
+      state(conn, IMAP_STOP);  /* Authenticated */
+      break;
+    case SASL_IDLE:            /* No mechanism left after cancellation */
+      if((!imapc->login_disabled) && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
+        /* Perform clear text authentication */
+        result = imap_perform_login(conn);
+      else {
+        failf(data, "Authentication cancelled");
+        result = CURLE_LOGIN_DENIED;
+      }
+      break;
+    default:
+      break;
+    }
+
+  return result;
+}
+
+/* For LOGIN responses */
+static CURLcode imap_state_login_resp(struct connectdata *conn,
+                                      int imapcode,
+                                      imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(imapcode != 'O') {
+    failf(data, "Access denied. %c", imapcode);
+    result = CURLE_LOGIN_DENIED;
+  }
+  else
+    /* End of connect phase */
+    state(conn, IMAP_STOP);
+
+  return result;
+}
+
+/* For LIST responses */
+static CURLcode imap_state_list_resp(struct connectdata *conn, int imapcode,
+                                     imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  char *line = conn->data->state.buffer;
+  size_t len = strlen(line);
+
+  (void)instate; /* No use for this yet */
+
+  if(imapcode == '*') {
+    /* Temporarily add the LF character back and send as body to the client */
+    line[len] = '\n';
+    result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1);
+    line[len] = '\0';
+  }
+  else if(imapcode != 'O')
+    result = CURLE_QUOTE_ERROR; /* TODO: Fix error code */
+  else
+    /* End of DO phase */
+    state(conn, IMAP_STOP);
+
+  return result;
+}
+
+/* For SELECT responses */
+static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode,
+                                       imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct IMAP *imap = conn->data->req.protop;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  const char *line = data->state.buffer;
+  char tmp[20];
+
+  (void)instate; /* no use for this yet */
+
+  if(imapcode == '*') {
+    /* See if this is an UIDVALIDITY response */
+    if(sscanf(line + 2, "OK [UIDVALIDITY %19[0123456789]]", tmp) == 1) {
+      Curl_safefree(imapc->mailbox_uidvalidity);
+      imapc->mailbox_uidvalidity = strdup(tmp);
+    }
+  }
+  else if(imapcode == 'O') {
+    /* Check if the UIDVALIDITY has been specified and matches */
+    if(imap->uidvalidity && imapc->mailbox_uidvalidity &&
+       strcmp(imap->uidvalidity, imapc->mailbox_uidvalidity)) {
+      failf(conn->data, "Mailbox UIDVALIDITY has changed");
+      result = CURLE_REMOTE_FILE_NOT_FOUND;
+    }
+    else {
+      /* Note the currently opened mailbox on this connection */
+      imapc->mailbox = strdup(imap->mailbox);
+
+      if(imap->custom)
+        result = imap_perform_list(conn);
+      else if(imap->query)
+        result = imap_perform_search(conn);
+      else
+        result = imap_perform_fetch(conn);
+    }
+  }
+  else {
+    failf(data, "Select failed");
+    result = CURLE_LOGIN_DENIED;
+  }
+
+  return result;
+}
+
+/* For the (first line of the) FETCH responses */
+static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
+                                      imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  struct pingpong *pp = &imapc->pp;
+  const char *ptr = data->state.buffer;
+  bool parsed = FALSE;
+  curl_off_t size;
+
+  (void)instate; /* no use for this yet */
+
+  if(imapcode != '*') {
+    Curl_pgrsSetDownloadSize(data, -1);
+    state(conn, IMAP_STOP);
+    return CURLE_REMOTE_FILE_NOT_FOUND; /* TODO: Fix error code */
+  }
+
+  /* Something like this is received "* 1 FETCH (BODY[TEXT] {2021}\r" so parse
+     the continuation data contained within the curly brackets */
+  while(*ptr && (*ptr != '{'))
+    ptr++;
+
+  if(*ptr == '{') {
+    char *endptr;
+    size = curlx_strtoofft(ptr + 1, &endptr, 10);
+    if(endptr - ptr > 1 && endptr[0] == '}' &&
+       endptr[1] == '\r' && endptr[2] == '\0')
+      parsed = TRUE;
+  }
+
+  if(parsed) {
+    infof(data, "Found %" CURL_FORMAT_CURL_OFF_TU " bytes to download\n",
+          size);
+    Curl_pgrsSetDownloadSize(data, size);
+
+    if(pp->cache) {
+      /* At this point there is a bunch of data in the header "cache" that is
+         actually body content, send it as body and then skip it. Do note
+         that there may even be additional "headers" after the body. */
+      size_t chunk = pp->cache_size;
+
+      if(chunk > (size_t)size)
+        /* The conversion from curl_off_t to size_t is always fine here */
+        chunk = (size_t)size;
+
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, pp->cache, chunk);
+      if(result)
+        return result;
+
+      data->req.bytecount += chunk;
+
+      infof(data, "Written %" CURL_FORMAT_CURL_OFF_TU
+            " bytes, %" CURL_FORMAT_CURL_OFF_TU
+            " bytes are left for transfer\n", (curl_off_t)chunk,
+            size - chunk);
+
+      /* Have we used the entire cache or just part of it?*/
+      if(pp->cache_size > chunk) {
+        /* Only part of it so shrink the cache to fit the trailing data */
+        memmove(pp->cache, pp->cache + chunk, pp->cache_size - chunk);
+        pp->cache_size -= chunk;
+      }
+      else {
+        /* Free the cache */
+        Curl_safefree(pp->cache);
+
+        /* Reset the cache size */
+        pp->cache_size = 0;
+      }
+    }
+
+    if(data->req.bytecount == size)
+      /* The entire data is already transferred! */
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+    else {
+      /* IMAP download */
+      data->req.maxdownload = size;
+      Curl_setup_transfer(conn, FIRSTSOCKET, size, FALSE, NULL, -1, NULL);
+    }
+  }
+  else {
+    /* We don't know how to parse this line */
+    failf(pp->conn->data, "Failed to parse FETCH response.");
+    result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: fix this code */
+  }
+
+  /* End of DO phase */
+  state(conn, IMAP_STOP);
+
+  return result;
+}
+
+/* For final FETCH responses performed after the download */
+static CURLcode imap_state_fetch_final_resp(struct connectdata *conn,
+                                            int imapcode,
+                                            imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+
+  (void)instate; /* No use for this yet */
+
+  if(imapcode != 'O')
+    result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: Fix error code */
+  else
+    /* End of DONE phase */
+    state(conn, IMAP_STOP);
+
+  return result;
+}
+
+/* For APPEND responses */
+static CURLcode imap_state_append_resp(struct connectdata *conn, int imapcode,
+                                       imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  (void)instate; /* No use for this yet */
+
+  if(imapcode != '+') {
+    result = CURLE_UPLOAD_FAILED;
+  }
+  else {
+    /* Set the progress upload size */
+    Curl_pgrsSetUploadSize(data, data->state.infilesize);
+
+    /* IMAP upload */
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+
+    /* End of DO phase */
+    state(conn, IMAP_STOP);
+  }
+
+  return result;
+}
+
+/* For final APPEND responses performed after the upload */
+static CURLcode imap_state_append_final_resp(struct connectdata *conn,
+                                             int imapcode,
+                                             imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+
+  (void)instate; /* No use for this yet */
+
+  if(imapcode != 'O')
+    result = CURLE_UPLOAD_FAILED;
+  else
+    /* End of DONE phase */
+    state(conn, IMAP_STOP);
+
+  return result;
+}
+
+/* For SEARCH responses */
+static CURLcode imap_state_search_resp(struct connectdata *conn, int imapcode,
+                                       imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  char *line = conn->data->state.buffer;
+  size_t len = strlen(line);
+
+  (void)instate; /* No use for this yet */
+
+  if(imapcode == '*') {
+    /* Temporarily add the LF character back and send as body to the client */
+    line[len] = '\n';
+    result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1);
+    line[len] = '\0';
+  }
+  else if(imapcode != 'O')
+    result = CURLE_QUOTE_ERROR; /* TODO: Fix error code */
+  else
+    /* End of DO phase */
+    state(conn, IMAP_STOP);
+
+  return result;
+}
+
+static CURLcode imap_statemach_act(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  int imapcode;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  struct pingpong *pp = &imapc->pp;
+  size_t nread = 0;
+
+  /* Busy upgrading the connection; right now all I/O is SSL/TLS, not IMAP */
+  if(imapc->state == IMAP_UPGRADETLS)
+    return imap_perform_upgrade_tls(conn);
+
+  /* Flush any data that needs to be sent */
+  if(pp->sendleft)
+    return Curl_pp_flushsend(pp);
+
+  do {
+    /* Read the response from the server */
+    result = Curl_pp_readresp(sock, pp, &imapcode, &nread);
+    if(result)
+      return result;
+
+    /* Was there an error parsing the response line? */
+    if(imapcode == -1)
+      return CURLE_FTP_WEIRD_SERVER_REPLY;
+
+    if(!imapcode)
+      break;
+
+    /* We have now received a full IMAP server response */
+    switch(imapc->state) {
+    case IMAP_SERVERGREET:
+      result = imap_state_servergreet_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_CAPABILITY:
+      result = imap_state_capability_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_STARTTLS:
+      result = imap_state_starttls_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_AUTHENTICATE:
+      result = imap_state_auth_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_LOGIN:
+      result = imap_state_login_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_LIST:
+      result = imap_state_list_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_SELECT:
+      result = imap_state_select_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_FETCH:
+      result = imap_state_fetch_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_FETCH_FINAL:
+      result = imap_state_fetch_final_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_APPEND:
+      result = imap_state_append_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_APPEND_FINAL:
+      result = imap_state_append_final_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_SEARCH:
+      result = imap_state_search_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_LOGOUT:
+      /* fallthrough, just stop! */
+    default:
+      /* internal error */
+      state(conn, IMAP_STOP);
+      break;
+    }
+  } while(!result && imapc->state != IMAP_STOP && Curl_pp_moredata(pp));
+
+  return result;
+}
+
+/* Called repeatedly until done from multi.c */
+static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+
+  if((conn->handler->flags & PROTOPT_SSL) && !imapc->ssldone) {
+    result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone);
+    if(result || !imapc->ssldone)
+      return result;
+  }
+
+  result = Curl_pp_statemach(&imapc->pp, FALSE);
+  *done = (imapc->state == IMAP_STOP) ? TRUE : FALSE;
+
+  return result;
+}
+
+static CURLcode imap_block_statemach(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+
+  while(imapc->state != IMAP_STOP && !result)
+    result = Curl_pp_statemach(&imapc->pp, TRUE);
+
+  return result;
+}
+
+/* Allocate and initialize the struct IMAP for the current SessionHandle if
+   required */
+static CURLcode imap_init(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct IMAP *imap;
+
+  imap = data->req.protop = calloc(sizeof(struct IMAP), 1);
+  if(!imap)
+    result = CURLE_OUT_OF_MEMORY;
+
+  return result;
+}
+
+/* For the IMAP "protocol connect" and "doing" phases only */
+static int imap_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks)
+{
+  return Curl_pp_getsock(&conn->proto.imapc.pp, socks, numsocks);
+}
+
+/***********************************************************************
+ *
+ * imap_connect()
+ *
+ * This function should do everything that is to be considered a part of the
+ * connection phase.
+ *
+ * The variable 'done' points to will be TRUE if the protocol-layer connect
+ * phase is done when this function returns, or FALSE if not.
+ */
+static CURLcode imap_connect(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  struct pingpong *pp = &imapc->pp;
+
+  *done = FALSE; /* default to not done yet */
+
+  /* We always support persistent connections in IMAP */
+  connkeep(conn, "IMAP default");
+
+  /* Set the default response time-out */
+  pp->response_time = RESP_TIMEOUT;
+  pp->statemach_act = imap_statemach_act;
+  pp->endofresp = imap_endofresp;
+  pp->conn = conn;
+
+  /* Set the default preferred authentication type and mechanism */
+  imapc->preftype = IMAP_TYPE_ANY;
+  Curl_sasl_init(&imapc->sasl, &saslimap);
+
+  /* Initialise the pingpong layer */
+  Curl_pp_init(pp);
+
+  /* Parse the URL options */
+  result = imap_parse_url_options(conn);
+  if(result)
+    return result;
+
+  /* Start off waiting for the server greeting response */
+  state(conn, IMAP_SERVERGREET);
+
+  /* Start off with an response id of '*' */
+  strcpy(imapc->resptag, "*");
+
+  result = imap_multi_statemach(conn, done);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_done()
+ *
+ * The DONE function. This does what needs to be done after a single DO has
+ * performed.
+ *
+ * Input argument is already checked for validity.
+ */
+static CURLcode imap_done(struct connectdata *conn, CURLcode status,
+                          bool premature)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct IMAP *imap = data->req.protop;
+
+  (void)premature;
+
+  if(!imap)
+    /* When the easy handle is removed from the multi interface while libcurl
+       is still trying to resolve the host name, the IMAP struct is not yet
+       initialized. However, the removal action calls Curl_done() which in
+       turn calls this function, so we simply return success. */
+    return CURLE_OK;
+
+  if(status) {
+    connclose(conn, "IMAP done with bad status"); /* marked for closure */
+    result = status;         /* use the already set error code */
+  }
+  else if(!data->set.connect_only && !imap->custom &&
+          (imap->uid || data->set.upload)) {
+    /* Handle responses after FETCH or APPEND transfer has finished */
+    if(!data->set.upload)
+      state(conn, IMAP_FETCH_FINAL);
+    else {
+      /* End the APPEND command first by sending an empty line */
+      result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "");
+      if(!result)
+        state(conn, IMAP_APPEND_FINAL);
+    }
+
+    /* Run the state-machine
+
+       TODO: when the multi interface is used, this _really_ should be using
+       the imap_multi_statemach function but we have no general support for
+       non-blocking DONE operations, not in the multi state machine and with
+       Curl_done() invokes on several places in the code!
+    */
+    if(!result)
+      result = imap_block_statemach(conn);
+  }
+
+  /* Cleanup our per-request based variables */
+  Curl_safefree(imap->mailbox);
+  Curl_safefree(imap->uidvalidity);
+  Curl_safefree(imap->uid);
+  Curl_safefree(imap->section);
+  Curl_safefree(imap->partial);
+  Curl_safefree(imap->query);
+  Curl_safefree(imap->custom);
+  Curl_safefree(imap->custom_params);
+
+  /* Clear the transfer mode for the next request */
+  imap->transfer = FTPTRANSFER_BODY;
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform()
+ *
+ * This is the actual DO function for IMAP. Fetch or append a message, or do
+ * other things according to the options previously setup.
+ */
+static CURLcode imap_perform(struct connectdata *conn, bool *connected,
+                             bool *dophase_done)
+{
+  /* This is IMAP and no proxy */
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct IMAP *imap = data->req.protop;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  bool selected = FALSE;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  if(conn->data->set.opt_no_body) {
+    /* Requested no body means no transfer */
+    imap->transfer = FTPTRANSFER_INFO;
+  }
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* Determine if the requested mailbox (with the same UIDVALIDITY if set)
+     has already been selected on this connection */
+  if(imap->mailbox && imapc->mailbox &&
+     !strcmp(imap->mailbox, imapc->mailbox) &&
+     (!imap->uidvalidity || !imapc->mailbox_uidvalidity ||
+      !strcmp(imap->uidvalidity, imapc->mailbox_uidvalidity)))
+    selected = TRUE;
+
+  /* Start the first command in the DO phase */
+  if(conn->data->set.upload)
+    /* APPEND can be executed directly */
+    result = imap_perform_append(conn);
+  else if(imap->custom && (selected || !imap->mailbox))
+    /* Custom command using the same mailbox or no mailbox */
+    result = imap_perform_list(conn);
+  else if(!imap->custom && selected && imap->uid)
+    /* FETCH from the same mailbox */
+    result = imap_perform_fetch(conn);
+  else if(!imap->custom && selected && imap->query)
+    /* SEARCH the current mailbox */
+    result = imap_perform_search(conn);
+  else if(imap->mailbox && !selected &&
+         (imap->custom || imap->uid || imap->query))
+    /* SELECT the mailbox */
+    result = imap_perform_select(conn);
+  else
+    /* LIST */
+    result = imap_perform_list(conn);
+
+  if(result)
+    return result;
+
+  /* Run the state-machine */
+  result = imap_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done)
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_do()
+ *
+ * This function is registered as 'curl_do' function. It decodes the path
+ * parts etc as a wrapper to the actual DO function (imap_perform).
+ *
+ * The input argument is already checked for validity.
+ */
+static CURLcode imap_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+
+  *done = FALSE; /* default to false */
+
+  /* Parse the URL path */
+  result = imap_parse_url_path(conn);
+  if(result)
+    return result;
+
+  /* Parse the custom request */
+  result = imap_parse_custom_request(conn);
+  if(result)
+    return result;
+
+  result = imap_regular_transfer(conn, done);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_disconnect()
+ *
+ * Disconnect from an IMAP server. Cleanup protocol-specific per-connection
+ * resources. BLOCKING.
+ */
+static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  struct imap_conn *imapc = &conn->proto.imapc;
+
+  /* We cannot send quit unconditionally. If this connection is stale or
+     bad in any way, sending quit and waiting around here will make the
+     disconnect wait in vain and cause more problems than we need to. */
+
+  /* The IMAP session may or may not have been allocated/setup at this
+     point! */
+  if(!dead_connection && imapc->pp.conn && imapc->pp.conn->bits.protoconnstart)
+    if(!imap_perform_logout(conn))
+      (void)imap_block_statemach(conn); /* ignore errors on LOGOUT */
+
+  /* Disconnect from the server */
+  Curl_pp_disconnect(&imapc->pp);
+
+  /* Cleanup the SASL module */
+  Curl_sasl_cleanup(conn, imapc->sasl.authused);
+
+  /* Cleanup our connection based variables */
+  Curl_safefree(imapc->mailbox);
+  Curl_safefree(imapc->mailbox_uidvalidity);
+
+  return CURLE_OK;
+}
+
+/* Call this when the DO phase has completed */
+static CURLcode imap_dophase_done(struct connectdata *conn, bool connected)
+{
+  struct IMAP *imap = conn->data->req.protop;
+
+  (void)connected;
+
+  if(imap->transfer != FTPTRANSFER_BODY)
+    /* no data to transfer */
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+  return CURLE_OK;
+}
+
+/* Called from multi.c while DOing */
+static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done)
+{
+  CURLcode result = imap_multi_statemach(conn, dophase_done);
+
+  if(result)
+    DEBUGF(infof(conn->data, "DO phase failed\n"));
+  else if(*dophase_done) {
+    result = imap_dophase_done(conn, FALSE /* not connected */);
+
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_regular_transfer()
+ *
+ * The input argument is already checked for validity.
+ *
+ * Performs all commands done before a regular transfer between a local and a
+ * remote host.
+ */
+static CURLcode imap_regular_transfer(struct connectdata *conn,
+                                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+  bool connected = FALSE;
+  struct SessionHandle *data = conn->data;
+
+  /* Make sure size is unknown at this point */
+  data->req.size = -1;
+
+  /* Set the progress data */
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  /* Carry out the perform */
+  result = imap_perform(conn, &connected, dophase_done);
+
+  /* Perform post DO phase operations if necessary */
+  if(!result && *dophase_done)
+    result = imap_dophase_done(conn, connected);
+
+  return result;
+}
+
+static CURLcode imap_setup_connection(struct connectdata *conn)
+{
+  struct SessionHandle *data = conn->data;
+
+  /* Initialise the IMAP layer */
+  CURLcode result = imap_init(conn);
+  if(result)
+    return result;
+
+  if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
+    /* Unless we have asked to tunnel IMAP operations through the proxy, we
+       switch and use HTTP operations only */
+#ifndef CURL_DISABLE_HTTP
+    if(conn->handler == &Curl_handler_imap)
+      conn->handler = &Curl_handler_imap_proxy;
+    else {
+#ifdef USE_SSL
+      conn->handler = &Curl_handler_imaps_proxy;
+#else
+      failf(data, "IMAPS not supported!");
+      return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+    }
+
+    /* set it up as an HTTP connection instead */
+    return conn->handler->setup_connection(conn);
+#else
+    failf(data, "IMAP over http proxy requires HTTP support built-in!");
+    return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+  }
+
+  data->state.path++;   /* don't include the initial slash */
+
+  return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * imap_sendf()
+ *
+ * Sends the formated string as an IMAP command to the server.
+ *
+ * Designed to never block.
+ */
+static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  char *taggedfmt;
+  va_list ap;
+
+  DEBUGASSERT(fmt);
+
+  /* Calculate the next command ID wrapping at 3 digits */
+  imapc->cmdid = (imapc->cmdid + 1) % 1000;
+
+  /* Calculate the tag based on the connection ID and command ID */
+  snprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
+           'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid);
+
+  /* Prefix the format with the tag */
+  taggedfmt = aprintf("%s %s", imapc->resptag, fmt);
+  if(!taggedfmt)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Send the data with the tag */
+  va_start(ap, fmt);
+  result = Curl_pp_vsendf(&imapc->pp, taggedfmt, ap);
+  va_end(ap);
+
+  free(taggedfmt);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_atom()
+ *
+ * Checks the input string for characters that need escaping and returns an
+ * atom ready for sending to the server.
+ *
+ * The returned string needs to be freed.
+ *
+ */
+static char *imap_atom(const char *str, bool escape_only)
+{
+  const char atom_specials[] = "(){ %*]";
+  const char *p1;
+  char *p2;
+  size_t backsp_count = 0;
+  size_t quote_count = 0;
+  bool others_exists = FALSE;
+  size_t newlen = 0;
+  char *newstr = NULL;
+
+  if(!str)
+    return NULL;
+
+  /* Look for "atom-specials", counting the backslash and quote characters as
+     these will need escapping */
+  p1 = str;
+  while(*p1) {
+    if(*p1 == '\\')
+      backsp_count++;
+    else if(*p1 == '"')
+      quote_count++;
+    else if(!escape_only) {
+      const char *p3 = atom_specials;
+
+      while(*p3 && !others_exists) {
+        if(*p1 == *p3)
+          others_exists = TRUE;
+
+        p3++;
+      }
+    }
+
+    p1++;
+  }
+
+  /* Does the input contain any "atom-special" characters? */
+  if(!backsp_count && !quote_count && !others_exists)
+    return strdup(str);
+
+  /* Calculate the new string length */
+  newlen = strlen(str) + backsp_count + quote_count + (others_exists ? 2 : 0);
+
+  /* Allocate the new string */
+  newstr = (char *) malloc((newlen + 1) * sizeof(char));
+  if(!newstr)
+    return NULL;
+
+  /* Surround the string in quotes if necessary */
+  p2 = newstr;
+  if(others_exists) {
+    newstr[0] = '"';
+    newstr[newlen - 1] = '"';
+    p2++;
+  }
+
+  /* Copy the string, escaping backslash and quote characters along the way */
+  p1 = str;
+  while(*p1) {
+    if(*p1 == '\\' || *p1 == '"') {
+      *p2 = '\\';
+      p2++;
+    }
+
+   *p2 = *p1;
+
+    p1++;
+    p2++;
+  }
+
+  /* Terminate the string */
+  newstr[newlen] = '\0';
+
+  return newstr;
+}
+
+/***********************************************************************
+ *
+ * imap_is_bchar()
+ *
+ * Portable test of whether the specified char is a "bchar" as defined in the
+ * grammar of RFC-5092.
+ */
+static bool imap_is_bchar(char ch)
+{
+  switch(ch) {
+    /* bchar */
+    case ':': case '@': case '/':
+    /* bchar -> achar */
+    case '&': case '=':
+    /* bchar -> achar -> uchar -> unreserved */
+    case '0': case '1': case '2': case '3': case '4': case '5': case '6':
+    case '7': case '8': case '9':
+    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
+    case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
+    case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
+    case 'V': case 'W': case 'X': case 'Y': case 'Z':
+    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
+    case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
+    case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
+    case 'v': case 'w': case 'x': case 'y': case 'z':
+    case '-': case '.': case '_': case '~':
+    /* bchar -> achar -> uchar -> sub-delims-sh */
+    case '!': case '$': case '\'': case '(': case ')': case '*':
+    case '+': case ',':
+    /* bchar -> achar -> uchar -> pct-encoded */
+    case '%': /* HEXDIG chars are already included above */
+      return true;
+
+    default:
+      return false;
+  }
+}
+
+/***********************************************************************
+ *
+ * imap_parse_url_options()
+ *
+ * Parse the URL login options.
+ */
+static CURLcode imap_parse_url_options(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  const char *ptr = conn->options;
+
+  imapc->sasl.resetprefs = TRUE;
+
+  while(!result && ptr && *ptr) {
+    const char *key = ptr;
+    const char *value;
+
+    while(*ptr && *ptr != '=')
+        ptr++;
+
+    value = ptr + 1;
+
+    while(*ptr && *ptr != ';')
+      ptr++;
+
+    if(strnequal(key, "AUTH=", 5))
+      result = Curl_sasl_parse_url_auth_option(&imapc->sasl,
+                                               value, ptr - value);
+    else
+      result = CURLE_URL_MALFORMAT;
+
+    if(*ptr == ';')
+      ptr++;
+  }
+
+  switch(imapc->sasl.prefmech) {
+  case SASL_AUTH_NONE:
+    imapc->preftype = IMAP_TYPE_NONE;
+    break;
+  case SASL_AUTH_DEFAULT:
+    imapc->preftype = IMAP_TYPE_ANY;
+    break;
+  default:
+    imapc->preftype = IMAP_TYPE_SASL;
+    break;
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_parse_url_path()
+ *
+ * Parse the URL path into separate path components.
+ *
+ */
+static CURLcode imap_parse_url_path(struct connectdata *conn)
+{
+  /* The imap struct is already initialised in imap_connect() */
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct IMAP *imap = data->req.protop;
+  const char *begin = data->state.path;
+  const char *ptr = begin;
+
+  /* See how much of the URL is a valid path and decode it */
+  while(imap_is_bchar(*ptr))
+    ptr++;
+
+  if(ptr != begin) {
+    /* Remove the trailing slash if present */
+    const char *end = ptr;
+    if(end > begin && end[-1] == '/')
+      end--;
+
+    result = Curl_urldecode(data, begin, end - begin, &imap->mailbox, NULL,
+                            TRUE);
+    if(result)
+      return result;
+  }
+  else
+    imap->mailbox = NULL;
+
+  /* There can be any number of parameters in the form ";NAME=VALUE" */
+  while(*ptr == ';') {
+    char *name;
+    char *value;
+    size_t valuelen;
+
+    /* Find the length of the name parameter */
+    begin = ++ptr;
+    while(*ptr && *ptr != '=')
+      ptr++;
+
+    if(!*ptr)
+      return CURLE_URL_MALFORMAT;
+
+    /* Decode the name parameter */
+    result = Curl_urldecode(data, begin, ptr - begin, &name, NULL, TRUE);
+    if(result)
+      return result;
+
+    /* Find the length of the value parameter */
+    begin = ++ptr;
+    while(imap_is_bchar(*ptr))
+      ptr++;
+
+    /* Decode the value parameter */
+    result = Curl_urldecode(data, begin, ptr - begin, &value, &valuelen, TRUE);
+    if(result) {
+      free(name);
+      return result;
+    }
+
+    DEBUGF(infof(conn->data, "IMAP URL parameter '%s' = '%s'\n", name, value));
+
+    /* Process the known hierarchical parameters (UIDVALIDITY, UID, SECTION and
+       PARTIAL) stripping of the trailing slash character if it is present.
+
+       Note: Unknown parameters trigger a URL_MALFORMAT error. */
+    if(Curl_raw_equal(name, "UIDVALIDITY") && !imap->uidvalidity) {
+      if(valuelen > 0 && value[valuelen - 1] == '/')
+        value[valuelen - 1] = '\0';
+
+      imap->uidvalidity = value;
+      value = NULL;
+    }
+    else if(Curl_raw_equal(name, "UID") && !imap->uid) {
+      if(valuelen > 0 && value[valuelen - 1] == '/')
+        value[valuelen - 1] = '\0';
+
+      imap->uid = value;
+      value = NULL;
+    }
+    else if(Curl_raw_equal(name, "SECTION") && !imap->section) {
+      if(valuelen > 0 && value[valuelen - 1] == '/')
+        value[valuelen - 1] = '\0';
+
+      imap->section = value;
+      value = NULL;
+    }
+    else if(Curl_raw_equal(name, "PARTIAL") && !imap->partial) {
+      if(valuelen > 0 && value[valuelen - 1] == '/')
+        value[valuelen - 1] = '\0';
+
+      imap->partial = value;
+      value = NULL;
+    }
+    else {
+      free(name);
+      free(value);
+
+      return CURLE_URL_MALFORMAT;
+    }
+
+    free(name);
+    free(value);
+  }
+
+  /* Does the URL contain a query parameter? Only valid when we have a mailbox
+     and no UID as per RFC-5092 */
+  if(imap->mailbox && !imap->uid && *ptr == '?') {
+    /* Find the length of the query parameter */
+    begin = ++ptr;
+    while(imap_is_bchar(*ptr))
+      ptr++;
+
+    /* Decode the query parameter */
+    result = Curl_urldecode(data, begin, ptr - begin, &imap->query, NULL,
+                            TRUE);
+    if(result)
+      return result;
+  }
+
+  /* Any extra stuff at the end of the URL is an error */
+  if(*ptr)
+    return CURLE_URL_MALFORMAT;
+
+  return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * imap_parse_custom_request()
+ *
+ * Parse the custom request.
+ */
+static CURLcode imap_parse_custom_request(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct IMAP *imap = data->req.protop;
+  const char *custom = data->set.str[STRING_CUSTOMREQUEST];
+
+  if(custom) {
+    /* URL decode the custom request */
+    result = Curl_urldecode(data, custom, 0, &imap->custom, NULL, TRUE);
+
+    /* Extract the parameters if specified */
+    if(!result) {
+      const char *params = imap->custom;
+
+      while(*params && *params != ' ')
+        params++;
+
+      if(*params) {
+        imap->custom_params = strdup(params);
+        imap->custom[params - imap->custom] = '\0';
+
+        if(!imap->custom_params)
+          result = CURLE_OUT_OF_MEMORY;
+      }
+    }
+  }
+
+  return result;
+}
+
+#endif /* CURL_DISABLE_IMAP */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/imap.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/imap.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/imap.h	(revision 164)
@@ -0,0 +1,96 @@
+#ifndef HEADER_CURL_IMAP_H
+#define HEADER_CURL_IMAP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2009 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "pingpong.h"
+#include "curl_sasl.h"
+
+/****************************************************************************
+ * IMAP unique setup
+ ***************************************************************************/
+typedef enum {
+  IMAP_STOP,         /* do nothing state, stops the state machine */
+  IMAP_SERVERGREET,  /* waiting for the initial greeting immediately after
+                        a connect */
+  IMAP_CAPABILITY,
+  IMAP_STARTTLS,
+  IMAP_UPGRADETLS,   /* asynchronously upgrade the connection to SSL/TLS
+                       (multi mode only) */
+  IMAP_AUTHENTICATE,
+  IMAP_LOGIN,
+  IMAP_LIST,
+  IMAP_SELECT,
+  IMAP_FETCH,
+  IMAP_FETCH_FINAL,
+  IMAP_APPEND,
+  IMAP_APPEND_FINAL,
+  IMAP_SEARCH,
+  IMAP_LOGOUT,
+  IMAP_LAST          /* never used */
+} imapstate;
+
+/* This IMAP struct is used in the SessionHandle. All IMAP data that is
+   connection-oriented must be in imap_conn to properly deal with the fact that
+   perhaps the SessionHandle is changed between the times the connection is
+   used. */
+struct IMAP {
+  curl_pp_transfer transfer;
+  char *mailbox;          /* Mailbox to select */
+  char *uidvalidity;      /* UIDVALIDITY to check in select */
+  char *uid;              /* Message UID to fetch */
+  char *section;          /* Message SECTION to fetch */
+  char *partial;          /* Message PARTIAL to fetch */
+  char *query;            /* Query to search for */
+  char *custom;           /* Custom request */
+  char *custom_params;    /* Parameters for the custom request */
+};
+
+/* imap_conn is used for struct connection-oriented data in the connectdata
+   struct */
+struct imap_conn {
+  struct pingpong pp;
+  imapstate state;            /* Always use imap.c:state() to change state! */
+  bool ssldone;               /* Is connect() over SSL done? */
+  struct SASL sasl;           /* SASL-related parameters */
+  unsigned int preftype;      /* Preferred authentication type */
+  int cmdid;                  /* Last used command ID */
+  char resptag[5];            /* Response tag to wait for */
+  bool tls_supported;         /* StartTLS capability supported by server */
+  bool login_disabled;        /* LOGIN command disabled by server */
+  bool ir_supported;          /* Initial response supported by server */
+  char *mailbox;              /* The last selected mailbox */
+  char *mailbox_uidvalidity;  /* UIDVALIDITY parsed from select response */
+};
+
+extern const struct Curl_handler Curl_handler_imap;
+extern const struct Curl_handler Curl_handler_imaps;
+
+/* Authentication type flags */
+#define IMAP_TYPE_CLEARTEXT (1 << 0)
+#define IMAP_TYPE_SASL      (1 << 1)
+
+/* Authentication type values */
+#define IMAP_TYPE_NONE      0
+#define IMAP_TYPE_ANY       ~0U
+
+#endif /* HEADER_CURL_IMAP_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/inet_ntop.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/inet_ntop.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/inet_ntop.c	(revision 164)
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 1996-2001  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 INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM 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.
+ */
+/*
+ * Original code by Paul Vixie. "curlified" by Gisle Vanem.
+ */
+
+#include "curl_setup.h"
+
+#ifndef HAVE_INET_NTOP
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include "curl_printf.h"
+
+#include "inet_ntop.h"
+
+#define IN6ADDRSZ       16
+#define INADDRSZ         4
+#define INT16SZ          2
+
+/*
+ * Format an IPv4 address, more or less like inet_ntoa().
+ *
+ * Returns `dst' (as a const)
+ * Note:
+ *  - uses no statics
+ *  - takes a unsigned char* not an in_addr as input
+ */
+static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size)
+{
+  char tmp[sizeof "255.255.255.255"];
+  size_t len;
+
+  DEBUGASSERT(size >= 16);
+
+  tmp[0] = '\0';
+  (void)snprintf(tmp, sizeof(tmp), "%d.%d.%d.%d",
+          ((int)((unsigned char)src[0])) & 0xff,
+          ((int)((unsigned char)src[1])) & 0xff,
+          ((int)((unsigned char)src[2])) & 0xff,
+          ((int)((unsigned char)src[3])) & 0xff);
+
+  len = strlen(tmp);
+  if(len == 0 || len >= size) {
+    SET_ERRNO(ENOSPC);
+    return (NULL);
+  }
+  strcpy(dst, tmp);
+  return dst;
+}
+
+#ifdef ENABLE_IPV6
+/*
+ * Convert IPv6 binary address into presentation (printable) format.
+ */
+static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
+{
+  /*
+   * Note that int32_t and int16_t need only be "at least" large enough
+   * to contain a value of the specified size.  On some systems, like
+   * Crays, there is no such thing as an integer variable with 16 bits.
+   * Keep this in mind if you think this function should have been coded
+   * to use pointer overlays.  All the world's not a VAX.
+   */
+  char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
+  char *tp;
+  struct {
+    long base;
+    long len;
+  } best, cur;
+  unsigned long words[IN6ADDRSZ / INT16SZ];
+  int i;
+
+  /* Preprocess:
+   *  Copy the input (bytewise) array into a wordwise array.
+   *  Find the longest run of 0x00's in src[] for :: shorthanding.
+   */
+  memset(words, '\0', sizeof(words));
+  for(i = 0; i < IN6ADDRSZ; i++)
+    words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
+
+  best.base = -1;
+  cur.base  = -1;
+  best.len = 0;
+  cur.len = 0;
+
+  for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+    if(words[i] == 0) {
+      if(cur.base == -1)
+        cur.base = i, cur.len = 1;
+      else
+        cur.len++;
+    }
+    else if(cur.base != -1) {
+      if(best.base == -1 || cur.len > best.len)
+        best = cur;
+      cur.base = -1;
+    }
+  }
+  if((cur.base != -1) && (best.base == -1 || cur.len > best.len))
+    best = cur;
+  if(best.base != -1 && best.len < 2)
+    best.base = -1;
+  /* Format the result. */
+  tp = tmp;
+  for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+    /* Are we inside the best run of 0x00's? */
+    if(best.base != -1 && i >= best.base && i < (best.base + best.len)) {
+      if(i == best.base)
+        *tp++ = ':';
+      continue;
+    }
+
+    /* Are we following an initial run of 0x00s or any real hex?
+     */
+    if(i != 0)
+      *tp++ = ':';
+
+    /* Is this address an encapsulated IPv4?
+     */
+    if(i == 6 && best.base == 0 &&
+        (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+      if(!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) {
+        SET_ERRNO(ENOSPC);
+        return (NULL);
+      }
+      tp += strlen(tp);
+      break;
+    }
+    tp += snprintf(tp, 5, "%lx", words[i]);
+  }
+
+  /* Was it a trailing run of 0x00's?
+   */
+  if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
+     *tp++ = ':';
+  *tp++ = '\0';
+
+  /* Check for overflow, copy, and we're done.
+   */
+  if((size_t)(tp - tmp) > size) {
+    SET_ERRNO(ENOSPC);
+    return (NULL);
+  }
+  strcpy(dst, tmp);
+  return dst;
+}
+#endif  /* ENABLE_IPV6 */
+
+/*
+ * Convert a network format address to presentation format.
+ *
+ * Returns pointer to presentation format address (`buf').
+ * Returns NULL on error and errno set with the specific
+ * error, EAFNOSUPPORT or ENOSPC.
+ *
+ * On Windows we store the error in the thread errno, not
+ * in the winsock error code. This is to avoid losing the
+ * actual last winsock error. So use macro ERRNO to fetch the
+ * errno this function sets when returning NULL, not SOCKERRNO.
+ */
+char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size)
+{
+  switch (af) {
+  case AF_INET:
+    return inet_ntop4((const unsigned char*)src, buf, size);
+#ifdef ENABLE_IPV6
+  case AF_INET6:
+    return inet_ntop6((const unsigned char*)src, buf, size);
+#endif
+  default:
+    SET_ERRNO(EAFNOSUPPORT);
+    return NULL;
+  }
+}
+#endif  /* HAVE_INET_NTOP */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/inet_ntop.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/inet_ntop.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/inet_ntop.h	(revision 164)
@@ -0,0 +1,38 @@
+#ifndef HEADER_CURL_INET_NTOP_H
+#define HEADER_CURL_INET_NTOP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+char *Curl_inet_ntop(int af, const void *addr, char *buf, size_t size);
+
+#ifdef HAVE_INET_NTOP
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#define Curl_inet_ntop(af,addr,buf,size) \
+        inet_ntop(af, addr, buf, (curl_socklen_t)size)
+#endif
+
+#endif /* HEADER_CURL_INET_NTOP_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/inet_pton.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/inet_pton.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/inet_pton.c	(revision 164)
@@ -0,0 +1,234 @@
+/* This is from the BIND 4.9.4 release, modified to compile by itself */
+
+/* Copyright (c) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM 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.
+ */
+
+#include "curl_setup.h"
+
+#ifndef HAVE_INET_PTON
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include "inet_pton.h"
+
+#define IN6ADDRSZ       16
+#define INADDRSZ         4
+#define INT16SZ          2
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int      inet_pton4(const char *src, unsigned char *dst);
+#ifdef ENABLE_IPV6
+static int      inet_pton6(const char *src, unsigned char *dst);
+#endif
+
+/* int
+ * inet_pton(af, src, dst)
+ *      convert from presentation format (which usually means ASCII printable)
+ *      to network format (which is usually some kind of binary format).
+ * return:
+ *      1 if the address was valid for the specified address family
+ *      0 if the address wasn't valid (`dst' is untouched in this case)
+ *      -1 if some other error occurred (`dst' is untouched in this case, too)
+ * notice:
+ *      On Windows we store the error in the thread errno, not
+ *      in the winsock error code. This is to avoid losing the
+ *      actual last winsock error. So use macro ERRNO to fetch the
+ *      errno this function sets when returning (-1), not SOCKERRNO.
+ * author:
+ *      Paul Vixie, 1996.
+ */
+int
+Curl_inet_pton(int af, const char *src, void *dst)
+{
+  switch (af) {
+  case AF_INET:
+    return (inet_pton4(src, (unsigned char *)dst));
+#ifdef ENABLE_IPV6
+  case AF_INET6:
+    return (inet_pton6(src, (unsigned char *)dst));
+#endif
+  default:
+    SET_ERRNO(EAFNOSUPPORT);
+    return (-1);
+  }
+  /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ *      like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ *      1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ *      does not touch `dst' unless it's returning 1.
+ * author:
+ *      Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, unsigned char *dst)
+{
+  static const char digits[] = "0123456789";
+  int saw_digit, octets, ch;
+  unsigned char tmp[INADDRSZ], *tp;
+
+  saw_digit = 0;
+  octets = 0;
+  tp = tmp;
+  *tp = 0;
+  while((ch = *src++) != '\0') {
+    const char *pch;
+
+    if((pch = strchr(digits, ch)) != NULL) {
+      unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
+
+      if(saw_digit && *tp == 0)
+        return (0);
+      if(val > 255)
+        return (0);
+      *tp = (unsigned char)val;
+      if(! saw_digit) {
+        if(++octets > 4)
+          return (0);
+        saw_digit = 1;
+      }
+    }
+    else if(ch == '.' && saw_digit) {
+      if(octets == 4)
+        return (0);
+      *++tp = 0;
+      saw_digit = 0;
+    }
+    else
+      return (0);
+  }
+  if(octets < 4)
+    return (0);
+  memcpy(dst, tmp, INADDRSZ);
+  return (1);
+}
+
+#ifdef ENABLE_IPV6
+/* int
+ * inet_pton6(src, dst)
+ *      convert presentation level address to network order binary form.
+ * return:
+ *      1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ *      (1) does not touch `dst' unless it's returning 1.
+ *      (2) :: in a full address is silently ignored.
+ * credit:
+ *      inspired by Mark Andrews.
+ * author:
+ *      Paul Vixie, 1996.
+ */
+static int
+inet_pton6(const char *src, unsigned char *dst)
+{
+  static const char xdigits_l[] = "0123456789abcdef",
+    xdigits_u[] = "0123456789ABCDEF";
+  unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+  const char *xdigits, *curtok;
+  int ch, saw_xdigit;
+  size_t val;
+
+  memset((tp = tmp), 0, IN6ADDRSZ);
+  endp = tp + IN6ADDRSZ;
+  colonp = NULL;
+  /* Leading :: requires some special handling. */
+  if(*src == ':')
+    if(*++src != ':')
+      return (0);
+  curtok = src;
+  saw_xdigit = 0;
+  val = 0;
+  while((ch = *src++) != '\0') {
+    const char *pch;
+
+    if((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+      pch = strchr((xdigits = xdigits_u), ch);
+    if(pch != NULL) {
+      val <<= 4;
+      val |= (pch - xdigits);
+      if(++saw_xdigit > 4)
+        return (0);
+      continue;
+    }
+    if(ch == ':') {
+      curtok = src;
+      if(!saw_xdigit) {
+        if(colonp)
+          return (0);
+        colonp = tp;
+        continue;
+      }
+      if(tp + INT16SZ > endp)
+        return (0);
+      *tp++ = (unsigned char) (val >> 8) & 0xff;
+      *tp++ = (unsigned char) (val & 0xff);
+      saw_xdigit = 0;
+      val = 0;
+      continue;
+    }
+    if(ch == '.' && ((tp + INADDRSZ) <= endp) &&
+        inet_pton4(curtok, tp) > 0) {
+      tp += INADDRSZ;
+      saw_xdigit = 0;
+      break;    /* '\0' was seen by inet_pton4(). */
+    }
+    return (0);
+  }
+  if(saw_xdigit) {
+    if(tp + INT16SZ > endp)
+      return (0);
+    *tp++ = (unsigned char) (val >> 8) & 0xff;
+    *tp++ = (unsigned char) (val & 0xff);
+  }
+  if(colonp != NULL) {
+    /*
+     * Since some memmove()'s erroneously fail to handle
+     * overlapping regions, we'll do the shift by hand.
+     */
+    const ssize_t n = tp - colonp;
+    ssize_t i;
+
+    if(tp == endp)
+      return (0);
+    for(i = 1; i <= n; i++) {
+      *(endp - i) = *(colonp + n - i);
+      *(colonp + n - i) = 0;
+    }
+    tp = endp;
+  }
+  if(tp != endp)
+    return (0);
+  memcpy(dst, tmp, IN6ADDRSZ);
+  return (1);
+}
+#endif /* ENABLE_IPV6 */
+
+#endif /* HAVE_INET_PTON */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/inet_pton.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/inet_pton.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/inet_pton.h	(revision 164)
@@ -0,0 +1,37 @@
+#ifndef HEADER_CURL_INET_PTON_H
+#define HEADER_CURL_INET_PTON_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+int Curl_inet_pton(int, const char *, void *);
+
+#ifdef HAVE_INET_PTON
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#define Curl_inet_pton(x,y,z) inet_pton(x,y,z)
+#endif
+
+#endif /* HEADER_CURL_INET_PTON_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/krb5.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/krb5.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/krb5.c	(revision 164)
@@ -0,0 +1,332 @@
+/* GSSAPI/krb5 support for FTP - loosely based on old krb4.c
+ *
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * Copyright (c) 2004 - 2015 Daniel Stenberg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.  */
+
+#include "curl_setup.h"
+
+#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_FTP)
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include "urldata.h"
+#include "curl_base64.h"
+#include "ftp.h"
+#include "curl_gssapi.h"
+#include "sendf.h"
+#include "curl_sec.h"
+#include "warnless.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define LOCAL_ADDR (&conn->local_addr)
+#define REMOTE_ADDR conn->ip_addr->ai_addr
+
+static int
+krb5_init(void *app_data)
+{
+  gss_ctx_id_t *context = app_data;
+  /* Make sure our context is initialized for krb5_end. */
+  *context = GSS_C_NO_CONTEXT;
+  return 0;
+}
+
+static int
+krb5_check_prot(void *app_data, int level)
+{
+  (void)app_data; /* unused */
+  if(level == PROT_CONFIDENTIAL)
+    return -1;
+  return 0;
+}
+
+static int
+krb5_decode(void *app_data, void *buf, int len,
+            int level UNUSED_PARAM,
+            struct connectdata *conn UNUSED_PARAM)
+{
+  gss_ctx_id_t *context = app_data;
+  OM_uint32 maj, min;
+  gss_buffer_desc enc, dec;
+
+  (void)level;
+  (void)conn;
+
+  enc.value = buf;
+  enc.length = len;
+  maj = gss_unseal(&min, *context, &enc, &dec, NULL, NULL);
+  if(maj != GSS_S_COMPLETE) {
+    if(len >= 4)
+      strcpy(buf, "599 ");
+    return -1;
+  }
+
+  memcpy(buf, dec.value, dec.length);
+  len = curlx_uztosi(dec.length);
+  gss_release_buffer(&min, &dec);
+
+  return len;
+}
+
+static int
+krb5_overhead(void *app_data, int level, int len)
+{
+  /* no arguments are used */
+  (void)app_data;
+  (void)level;
+  (void)len;
+  return 0;
+}
+
+static int
+krb5_encode(void *app_data, const void *from, int length, int level, void **to)
+{
+  gss_ctx_id_t *context = app_data;
+  gss_buffer_desc dec, enc;
+  OM_uint32 maj, min;
+  int state;
+  int len;
+
+  /* NOTE that the cast is safe, neither of the krb5, gnu gss and heimdal
+   * libraries modify the input buffer in gss_seal()
+   */
+  dec.value = (void*)from;
+  dec.length = length;
+  maj = gss_seal(&min, *context,
+                 level == PROT_PRIVATE,
+                 GSS_C_QOP_DEFAULT,
+                 &dec, &state, &enc);
+
+  if(maj != GSS_S_COMPLETE)
+    return -1;
+
+  /* malloc a new buffer, in case gss_release_buffer doesn't work as
+     expected */
+  *to = malloc(enc.length);
+  if(!*to)
+    return -1;
+  memcpy(*to, enc.value, enc.length);
+  len = curlx_uztosi(enc.length);
+  gss_release_buffer(&min, &enc);
+  return len;
+}
+
+static int
+krb5_auth(void *app_data, struct connectdata *conn)
+{
+  int ret = AUTH_OK;
+  char *p;
+  const char *host = conn->host.name;
+  ssize_t nread;
+  curl_socklen_t l = sizeof(conn->local_addr);
+  struct SessionHandle *data = conn->data;
+  CURLcode result;
+  const char *service = "ftp", *srv_host = "host";
+  gss_buffer_desc input_buffer, output_buffer, _gssresp, *gssresp;
+  OM_uint32 maj, min;
+  gss_name_t gssname;
+  gss_ctx_id_t *context = app_data;
+  struct gss_channel_bindings_struct chan;
+  size_t base64_sz = 0;
+
+  if(getsockname(conn->sock[FIRSTSOCKET],
+                 (struct sockaddr *)LOCAL_ADDR, &l) < 0)
+    perror("getsockname()");
+
+  chan.initiator_addrtype = GSS_C_AF_INET;
+  chan.initiator_address.length = l - 4;
+  chan.initiator_address.value =
+    &((struct sockaddr_in *)LOCAL_ADDR)->sin_addr.s_addr;
+  chan.acceptor_addrtype = GSS_C_AF_INET;
+  chan.acceptor_address.length = l - 4;
+  chan.acceptor_address.value =
+    &((struct sockaddr_in *)REMOTE_ADDR)->sin_addr.s_addr;
+  chan.application_data.length = 0;
+  chan.application_data.value = NULL;
+
+  /* this loop will execute twice (once for service, once for host) */
+  for(;;) {
+    /* this really shouldn't be repeated here, but can't help it */
+    if(service == srv_host) {
+      result = Curl_ftpsendf(conn, "AUTH GSSAPI");
+
+      if(result)
+        return -2;
+      if(Curl_GetFTPResponse(&nread, conn, NULL))
+        return -1;
+
+      if(data->state.buffer[0] != '3')
+        return -1;
+    }
+
+    input_buffer.value = data->state.buffer;
+    input_buffer.length = snprintf(input_buffer.value, BUFSIZE, "%s@%s",
+                                   service, host);
+    maj = gss_import_name(&min, &input_buffer, GSS_C_NT_HOSTBASED_SERVICE,
+                          &gssname);
+    if(maj != GSS_S_COMPLETE) {
+      gss_release_name(&min, &gssname);
+      if(service == srv_host) {
+        Curl_failf(data, "Error importing service name %s",
+                   input_buffer.value);
+        return AUTH_ERROR;
+      }
+      service = srv_host;
+      continue;
+    }
+    /* We pass NULL as |output_name_type| to avoid a leak. */
+    gss_display_name(&min, gssname, &output_buffer, NULL);
+    Curl_infof(data, "Trying against %s\n", output_buffer.value);
+    gssresp = GSS_C_NO_BUFFER;
+    *context = GSS_C_NO_CONTEXT;
+
+    do {
+      /* Release the buffer at each iteration to avoid leaking: the first time
+         we are releasing the memory from gss_display_name. The last item is
+         taken care by a final gss_release_buffer. */
+      gss_release_buffer(&min, &output_buffer);
+      ret = AUTH_OK;
+      maj = Curl_gss_init_sec_context(data,
+                                      &min,
+                                      context,
+                                      gssname,
+                                      &Curl_krb5_mech_oid,
+                                      &chan,
+                                      gssresp,
+                                      &output_buffer,
+                                      TRUE,
+                                      NULL);
+
+      if(gssresp) {
+        free(_gssresp.value);
+        gssresp = NULL;
+      }
+
+      if(GSS_ERROR(maj)) {
+        Curl_infof(data, "Error creating security context\n");
+        ret = AUTH_ERROR;
+        break;
+      }
+
+      if(output_buffer.length != 0) {
+        result = Curl_base64_encode(data, (char *)output_buffer.value,
+                                    output_buffer.length, &p, &base64_sz);
+        if(result) {
+          Curl_infof(data, "base64-encoding: %s\n",
+                     curl_easy_strerror(result));
+          ret = AUTH_CONTINUE;
+          break;
+        }
+
+        result = Curl_ftpsendf(conn, "ADAT %s", p);
+
+        free(p);
+
+        if(result) {
+          ret = -2;
+          break;
+        }
+
+        if(Curl_GetFTPResponse(&nread, conn, NULL)) {
+          ret = -1;
+          break;
+        }
+
+        if(data->state.buffer[0] != '2' && data->state.buffer[0] != '3') {
+          Curl_infof(data, "Server didn't accept auth data\n");
+          ret = AUTH_ERROR;
+          break;
+        }
+
+        p = data->state.buffer + 4;
+        p = strstr(p, "ADAT=");
+        if(p) {
+          result = Curl_base64_decode(p + 5,
+                                      (unsigned char **)&_gssresp.value,
+                                      &_gssresp.length);
+          if(result) {
+            Curl_failf(data, "base64-decoding: %s",
+                       curl_easy_strerror(result));
+            ret = AUTH_CONTINUE;
+            break;
+          }
+        }
+
+        gssresp = &_gssresp;
+      }
+    } while(maj == GSS_S_CONTINUE_NEEDED);
+
+    gss_release_name(&min, &gssname);
+    gss_release_buffer(&min, &output_buffer);
+
+    if(gssresp)
+      free(_gssresp.value);
+
+    if(ret == AUTH_OK || service == srv_host)
+      return ret;
+
+    service = srv_host;
+  }
+  return ret;
+}
+
+static void krb5_end(void *app_data)
+{
+    OM_uint32 min;
+    gss_ctx_id_t *context = app_data;
+    if(*context != GSS_C_NO_CONTEXT) {
+#ifdef DEBUGBUILD
+      OM_uint32 maj =
+#endif
+      gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER);
+      DEBUGASSERT(maj == GSS_S_COMPLETE);
+    }
+}
+
+struct Curl_sec_client_mech Curl_krb5_client_mech = {
+    "GSSAPI",
+    sizeof(gss_ctx_id_t),
+    krb5_init,
+    krb5_auth,
+    krb5_end,
+    krb5_check_prot,
+    krb5_overhead,
+    krb5_encode,
+    krb5_decode
+};
+
+#endif /* HAVE_GSSAPI && !CURL_DISABLE_FTP */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/ldap.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/ldap.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/ldap.c	(revision 164)
@@ -0,0 +1,1013 @@
+/***************************************************************************
+ *                      _   _ ____  _
+ *  Project         ___| | | |  _ \| |
+ *                 / __| | | | |_) | |
+ *                | (__| |_| |  _ <| |___
+ *                 \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_LDAP) && !defined(USE_OPENLDAP)
+
+/*
+ * Notice that USE_OPENLDAP is only a source code selection switch. When
+ * libcurl is built with USE_OPENLDAP defined the libcurl source code that
+ * gets compiled is the code from openldap.c, otherwise the code that gets
+ * compiled is the code from ldap.c.
+ *
+ * When USE_OPENLDAP is defined a recent version of the OpenLDAP library
+ * might be required for compilation and runtime. In order to use ancient
+ * OpenLDAP library versions, USE_OPENLDAP shall not be defined.
+ */
+
+#ifdef USE_WIN32_LDAP           /* Use Windows LDAP implementation. */
+# include <winldap.h>
+# ifndef LDAP_VENDOR_NAME
+#  error Your Platform SDK is NOT sufficient for LDAP support! \
+         Update your Platform SDK, or disable LDAP support!
+# else
+#  include <winber.h>
+# endif
+#else
+# define LDAP_DEPRECATED 1      /* Be sure ldap_init() is defined. */
+# ifdef HAVE_LBER_H
+#  include <lber.h>
+# endif
+# include <ldap.h>
+# if (defined(HAVE_LDAP_SSL) && defined(HAVE_LDAP_SSL_H))
+#  include <ldap_ssl.h>
+# endif /* HAVE_LDAP_SSL && HAVE_LDAP_SSL_H */
+#endif
+
+/* These are macros in both <wincrypt.h> (in above <winldap.h>) and typedefs
+ * in BoringSSL's <openssl/x509.h>
+ */
+#ifdef HAVE_BORINGSSL
+# undef X509_NAME
+# undef X509_CERT_PAIR
+# undef X509_EXTENSIONS
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "sendf.h"
+#include "escape.h"
+#include "progress.h"
+#include "transfer.h"
+#include "strequal.h"
+#include "strtok.h"
+#include "curl_ldap.h"
+#include "curl_multibyte.h"
+#include "curl_base64.h"
+#include "rawstr.h"
+#include "connect.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef HAVE_LDAP_URL_PARSE
+
+/* Use our own implementation. */
+
+typedef struct {
+  char   *lud_host;
+  int     lud_port;
+#if defined(USE_WIN32_LDAP)
+  TCHAR  *lud_dn;
+  TCHAR **lud_attrs;
+#else
+  char   *lud_dn;
+  char  **lud_attrs;
+#endif
+  int     lud_scope;
+#if defined(USE_WIN32_LDAP)
+  TCHAR  *lud_filter;
+#else
+  char   *lud_filter;
+#endif
+  char  **lud_exts;
+  size_t    lud_attrs_dups; /* how many were dup'ed, this field is not in the
+                               "real" struct so can only be used in code
+                               without HAVE_LDAP_URL_PARSE defined */
+} CURL_LDAPURLDesc;
+
+#undef LDAPURLDesc
+#define LDAPURLDesc             CURL_LDAPURLDesc
+
+static int  _ldap_url_parse (const struct connectdata *conn,
+                             LDAPURLDesc **ludp);
+static void _ldap_free_urldesc (LDAPURLDesc *ludp);
+
+#undef ldap_free_urldesc
+#define ldap_free_urldesc       _ldap_free_urldesc
+#endif
+
+#ifdef DEBUG_LDAP
+  #define LDAP_TRACE(x)   do { \
+                            _ldap_trace ("%u: ", __LINE__); \
+                            _ldap_trace x; \
+                          } WHILE_FALSE
+
+  static void _ldap_trace (const char *fmt, ...);
+#else
+  #define LDAP_TRACE(x)   Curl_nop_stmt
+#endif
+
+
+static CURLcode Curl_ldap(struct connectdata *conn, bool *done);
+
+/*
+ * LDAP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ldap = {
+  "LDAP",                               /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  Curl_ldap,                            /* do_it */
+  ZERO_NULL,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_LDAP,                            /* defport */
+  CURLPROTO_LDAP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+#ifdef HAVE_LDAP_SSL
+/*
+ * LDAPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ldaps = {
+  "LDAPS",                              /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  Curl_ldap,                            /* do_it */
+  ZERO_NULL,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_LDAPS,                           /* defport */
+  CURLPROTO_LDAPS,                      /* protocol */
+  PROTOPT_SSL                           /* flags */
+};
+#endif
+
+
+static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  int rc = 0;
+  LDAP *server = NULL;
+  LDAPURLDesc *ludp = NULL;
+  LDAPMessage *ldapmsg = NULL;
+  LDAPMessage *entryIterator;
+  int num = 0;
+  struct SessionHandle *data=conn->data;
+  int ldap_proto = LDAP_VERSION3;
+  int ldap_ssl = 0;
+  char *val_b64 = NULL;
+  size_t val_b64_sz = 0;
+  curl_off_t dlsize = 0;
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
+  struct timeval ldap_timeout = {10, 0}; /* 10 sec connection/search timeout */
+#endif
+#if defined(USE_WIN32_LDAP)
+  TCHAR *host = NULL;
+  TCHAR *user = NULL;
+  TCHAR *passwd = NULL;
+#else
+  char *host = NULL;
+  char *user = NULL;
+  char *passwd = NULL;
+#endif
+
+  *done = TRUE; /* unconditionally */
+  infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d\n",
+          LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION);
+  infof(data, "LDAP local: %s\n", data->change.url);
+
+#ifdef HAVE_LDAP_URL_PARSE
+  rc = ldap_url_parse(data->change.url, &ludp);
+#else
+  rc = _ldap_url_parse(conn, &ludp);
+#endif
+  if(rc != 0) {
+    failf(data, "LDAP local: %s", ldap_err2string(rc));
+    result = CURLE_LDAP_INVALID_URL;
+    goto quit;
+  }
+
+  /* Get the URL scheme ( either ldap or ldaps ) */
+  if(conn->given->flags & PROTOPT_SSL)
+    ldap_ssl = 1;
+  infof(data, "LDAP local: trying to establish %s connection\n",
+          ldap_ssl ? "encrypted" : "cleartext");
+
+#if defined(USE_WIN32_LDAP)
+  host = Curl_convert_UTF8_to_tchar(conn->host.name);
+  if(!host) {
+    result = CURLE_OUT_OF_MEMORY;
+
+    goto quit;
+  }
+
+  if(conn->bits.user_passwd) {
+    user = Curl_convert_UTF8_to_tchar(conn->user);
+    passwd = Curl_convert_UTF8_to_tchar(conn->passwd);
+    if(!user || !passwd) {
+      result = CURLE_OUT_OF_MEMORY;
+
+      goto quit;
+    }
+  }
+#else
+  host = conn->host.name;
+
+  if(conn->bits.user_passwd) {
+    user = conn->user;
+    passwd = conn->passwd;
+  }
+#endif
+
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
+  ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, &ldap_timeout);
+#endif
+  ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
+
+  if(ldap_ssl) {
+#ifdef HAVE_LDAP_SSL
+#ifdef USE_WIN32_LDAP
+    /* Win32 LDAP SDK doesn't support insecure mode without CA! */
+    server = ldap_sslinit(host, (int)conn->port, 1);
+    ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON);
+#else
+    int ldap_option;
+    char* ldap_ca = data->set.str[STRING_SSL_CAFILE];
+#if defined(CURL_HAS_NOVELL_LDAPSDK)
+    rc = ldapssl_client_init(NULL, NULL);
+    if(rc != LDAP_SUCCESS) {
+      failf(data, "LDAP local: ldapssl_client_init %s", ldap_err2string(rc));
+      result = CURLE_SSL_CERTPROBLEM;
+      goto quit;
+    }
+    if(data->set.ssl.verifypeer) {
+      /* Novell SDK supports DER or BASE64 files. */
+      int cert_type = LDAPSSL_CERT_FILETYPE_B64;
+      if((data->set.str[STRING_CERT_TYPE]) &&
+         (Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "DER")))
+        cert_type = LDAPSSL_CERT_FILETYPE_DER;
+      if(!ldap_ca) {
+        failf(data, "LDAP local: ERROR %s CA cert not set!",
+              (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"));
+        result = CURLE_SSL_CERTPROBLEM;
+        goto quit;
+      }
+      infof(data, "LDAP local: using %s CA cert '%s'\n",
+              (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
+              ldap_ca);
+      rc = ldapssl_add_trusted_cert(ldap_ca, cert_type);
+      if(rc != LDAP_SUCCESS) {
+        failf(data, "LDAP local: ERROR setting %s CA cert: %s",
+                (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
+                ldap_err2string(rc));
+        result = CURLE_SSL_CERTPROBLEM;
+        goto quit;
+      }
+      ldap_option = LDAPSSL_VERIFY_SERVER;
+    }
+    else
+      ldap_option = LDAPSSL_VERIFY_NONE;
+    rc = ldapssl_set_verify_mode(ldap_option);
+    if(rc != LDAP_SUCCESS) {
+      failf(data, "LDAP local: ERROR setting cert verify mode: %s",
+              ldap_err2string(rc));
+      result = CURLE_SSL_CERTPROBLEM;
+      goto quit;
+    }
+    server = ldapssl_init(host, (int)conn->port, 1);
+    if(server == NULL) {
+      failf(data, "LDAP local: Cannot connect to %s:%ld",
+            conn->host.dispname, conn->port);
+      result = CURLE_COULDNT_CONNECT;
+      goto quit;
+    }
+#elif defined(LDAP_OPT_X_TLS)
+    if(data->set.ssl.verifypeer) {
+      /* OpenLDAP SDK supports BASE64 files. */
+      if((data->set.str[STRING_CERT_TYPE]) &&
+         (!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) {
+        failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!");
+        result = CURLE_SSL_CERTPROBLEM;
+        goto quit;
+      }
+      if(!ldap_ca) {
+        failf(data, "LDAP local: ERROR PEM CA cert not set!");
+        result = CURLE_SSL_CERTPROBLEM;
+        goto quit;
+      }
+      infof(data, "LDAP local: using PEM CA cert: %s\n", ldap_ca);
+      rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_ca);
+      if(rc != LDAP_SUCCESS) {
+        failf(data, "LDAP local: ERROR setting PEM CA cert: %s",
+                ldap_err2string(rc));
+        result = CURLE_SSL_CERTPROBLEM;
+        goto quit;
+      }
+      ldap_option = LDAP_OPT_X_TLS_DEMAND;
+    }
+    else
+      ldap_option = LDAP_OPT_X_TLS_NEVER;
+
+    rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_option);
+    if(rc != LDAP_SUCCESS) {
+      failf(data, "LDAP local: ERROR setting cert verify mode: %s",
+              ldap_err2string(rc));
+      result = CURLE_SSL_CERTPROBLEM;
+      goto quit;
+    }
+    server = ldap_init(host, (int)conn->port);
+    if(server == NULL) {
+      failf(data, "LDAP local: Cannot connect to %s:%ld",
+            conn->host.dispname, conn->port);
+      result = CURLE_COULDNT_CONNECT;
+      goto quit;
+    }
+    ldap_option = LDAP_OPT_X_TLS_HARD;
+    rc = ldap_set_option(server, LDAP_OPT_X_TLS, &ldap_option);
+    if(rc != LDAP_SUCCESS) {
+      failf(data, "LDAP local: ERROR setting SSL/TLS mode: %s",
+              ldap_err2string(rc));
+      result = CURLE_SSL_CERTPROBLEM;
+      goto quit;
+    }
+/*
+    rc = ldap_start_tls_s(server, NULL, NULL);
+    if(rc != LDAP_SUCCESS) {
+      failf(data, "LDAP local: ERROR starting SSL/TLS mode: %s",
+              ldap_err2string(rc));
+      result = CURLE_SSL_CERTPROBLEM;
+      goto quit;
+    }
+*/
+#else
+    /* we should probably never come up to here since configure
+       should check in first place if we can support LDAP SSL/TLS */
+    failf(data, "LDAP local: SSL/TLS not supported with this version "
+            "of the OpenLDAP toolkit\n");
+    result = CURLE_SSL_CERTPROBLEM;
+    goto quit;
+#endif
+#endif
+#endif /* CURL_LDAP_USE_SSL */
+  }
+  else {
+    server = ldap_init(host, (int)conn->port);
+    if(server == NULL) {
+      failf(data, "LDAP local: Cannot connect to %s:%ld",
+            conn->host.dispname, conn->port);
+      result = CURLE_COULDNT_CONNECT;
+      goto quit;
+    }
+  }
+#ifdef USE_WIN32_LDAP
+  ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
+#endif
+
+  rc = ldap_simple_bind_s(server, user, passwd);
+  if(!ldap_ssl && rc != 0) {
+    ldap_proto = LDAP_VERSION2;
+    ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
+    rc = ldap_simple_bind_s(server, user, passwd);
+  }
+  if(rc != 0) {
+    failf(data, "LDAP local: ldap_simple_bind_s %s", ldap_err2string(rc));
+    result = CURLE_LDAP_CANNOT_BIND;
+    goto quit;
+  }
+
+  rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope,
+                     ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg);
+
+  if(rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) {
+    failf(data, "LDAP remote: %s", ldap_err2string(rc));
+    result = CURLE_LDAP_SEARCH_FAILED;
+    goto quit;
+  }
+
+  for(num = 0, entryIterator = ldap_first_entry(server, ldapmsg);
+      entryIterator;
+      entryIterator = ldap_next_entry(server, entryIterator), num++) {
+    BerElement *ber = NULL;
+#if defined(USE_WIN32_LDAP)
+    TCHAR *attribute;
+#else
+    char  *attribute;       /*! suspicious that this isn't 'const' */
+#endif
+    int i;
+
+    /* Get the DN and write it to the client */
+    {
+      char *name;
+      size_t name_len;
+#if defined(USE_WIN32_LDAP)
+      TCHAR *dn = ldap_get_dn(server, entryIterator);
+      name = Curl_convert_tchar_to_UTF8(dn);
+      if(!name) {
+        ldap_memfree(dn);
+
+        result = CURLE_OUT_OF_MEMORY;
+
+        goto quit;
+      }
+#else
+      char *dn = name = ldap_get_dn(server, entryIterator);
+#endif
+      name_len = strlen(name);
+
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
+      if(result) {
+#if defined(USE_WIN32_LDAP)
+        Curl_unicodefree(name);
+#endif
+        ldap_memfree(dn);
+
+        goto quit;
+      }
+
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *) name,
+                                 name_len);
+      if(result) {
+#if defined(USE_WIN32_LDAP)
+        Curl_unicodefree(name);
+#endif
+        ldap_memfree(dn);
+
+        goto quit;
+      }
+
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+      if(result) {
+#if defined(USE_WIN32_LDAP)
+        Curl_unicodefree(name);
+#endif
+        ldap_memfree(dn);
+
+        goto quit;
+      }
+
+      dlsize += name_len + 5;
+
+#if defined(USE_WIN32_LDAP)
+      Curl_unicodefree(name);
+#endif
+      ldap_memfree(dn);
+    }
+
+    /* Get the attributes and write them to the client */
+    for(attribute = ldap_first_attribute(server, entryIterator, &ber);
+        attribute;
+        attribute = ldap_next_attribute(server, entryIterator, ber)) {
+      BerValue **vals;
+      size_t attr_len;
+#if defined(USE_WIN32_LDAP)
+      char *attr = Curl_convert_tchar_to_UTF8(attribute);
+      if(!attr) {
+        if(ber)
+          ber_free(ber, 0);
+
+        result = CURLE_OUT_OF_MEMORY;
+
+        goto quit;
+    }
+#else
+      char *attr = attribute;
+#endif
+      attr_len = strlen(attr);
+
+      vals = ldap_get_values_len(server, entryIterator, attribute);
+      if(vals != NULL) {
+        for(i = 0; (vals[i] != NULL); i++) {
+          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
+          if(result) {
+            ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+            Curl_unicodefree(attr);
+#endif
+            ldap_memfree(attribute);
+            if(ber)
+              ber_free(ber, 0);
+
+            goto quit;
+          }
+
+          result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                     (char *) attr, attr_len);
+          if(result) {
+            ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+            Curl_unicodefree(attr);
+#endif
+            ldap_memfree(attribute);
+            if(ber)
+              ber_free(ber, 0);
+
+            goto quit;
+          }
+
+          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
+          if(result) {
+            ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+            Curl_unicodefree(attr);
+#endif
+            ldap_memfree(attribute);
+            if(ber)
+              ber_free(ber, 0);
+
+            goto quit;
+          }
+
+          dlsize += attr_len + 3;
+
+          if((attr_len > 7) &&
+             (strcmp(";binary", (char *) attr + (attr_len - 7)) == 0)) {
+            /* Binary attribute, encode to base64. */
+            result = Curl_base64_encode(data,
+                                        vals[i]->bv_val,
+                                        vals[i]->bv_len,
+                                        &val_b64,
+                                        &val_b64_sz);
+            if(result) {
+              ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+              Curl_unicodefree(attr);
+#endif
+              ldap_memfree(attribute);
+              if(ber)
+                ber_free(ber, 0);
+
+              goto quit;
+            }
+
+            if(val_b64_sz > 0) {
+              result = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
+                                         val_b64_sz);
+              free(val_b64);
+              if(result) {
+                ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+                Curl_unicodefree(attr);
+#endif
+                ldap_memfree(attribute);
+                if(ber)
+                  ber_free(ber, 0);
+
+                goto quit;
+              }
+
+              dlsize += val_b64_sz;
+            }
+          }
+          else {
+            result = Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val,
+                                       vals[i]->bv_len);
+            if(result) {
+              ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+              Curl_unicodefree(attr);
+#endif
+              ldap_memfree(attribute);
+              if(ber)
+                ber_free(ber, 0);
+
+              goto quit;
+            }
+
+            dlsize += vals[i]->bv_len;
+          }
+
+          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+          if(result) {
+            ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+            Curl_unicodefree(attr);
+#endif
+            ldap_memfree(attribute);
+            if(ber)
+              ber_free(ber, 0);
+
+            goto quit;
+          }
+
+          dlsize++;
+        }
+
+        /* Free memory used to store values */
+        ldap_value_free_len(vals);
+      }
+
+      /* Free the attribute as we are done with it */
+#if defined(USE_WIN32_LDAP)
+      Curl_unicodefree(attr);
+#endif
+      ldap_memfree(attribute);
+
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+      if(result)
+        goto quit;
+      dlsize++;
+      Curl_pgrsSetDownloadCounter(data, dlsize);
+    }
+
+    if(ber)
+       ber_free(ber, 0);
+  }
+
+quit:
+  if(ldapmsg) {
+    ldap_msgfree(ldapmsg);
+    LDAP_TRACE (("Received %d entries\n", num));
+  }
+  if(rc == LDAP_SIZELIMIT_EXCEEDED)
+    infof(data, "There are more than %d entries\n", num);
+  if(ludp)
+    ldap_free_urldesc(ludp);
+  if(server)
+    ldap_unbind_s(server);
+#if defined(HAVE_LDAP_SSL) && defined(CURL_HAS_NOVELL_LDAPSDK)
+  if(ldap_ssl)
+    ldapssl_client_deinit();
+#endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */
+
+#if defined(USE_WIN32_LDAP)
+  Curl_unicodefree(passwd);
+  Curl_unicodefree(user);
+  Curl_unicodefree(host);
+#endif
+
+  /* no data to transfer */
+  Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+  connclose(conn, "LDAP connection always disable re-use");
+
+  return result;
+}
+
+#ifdef DEBUG_LDAP
+static void _ldap_trace (const char *fmt, ...)
+{
+  static int do_trace = -1;
+  va_list args;
+
+  if(do_trace == -1) {
+    const char *env = getenv("CURL_TRACE");
+    do_trace = (env && strtol(env, NULL, 10) > 0);
+  }
+  if(!do_trace)
+    return;
+
+  va_start (args, fmt);
+  vfprintf (stderr, fmt, args);
+  va_end (args);
+}
+#endif
+
+#ifndef HAVE_LDAP_URL_PARSE
+
+/*
+ * Return scope-value for a scope-string.
+ */
+static int str2scope (const char *p)
+{
+  if(strequal(p, "one"))
+     return LDAP_SCOPE_ONELEVEL;
+  if(strequal(p, "onetree"))
+     return LDAP_SCOPE_ONELEVEL;
+  if(strequal(p, "base"))
+     return LDAP_SCOPE_BASE;
+  if(strequal(p, "sub"))
+     return LDAP_SCOPE_SUBTREE;
+  if(strequal( p, "subtree"))
+     return LDAP_SCOPE_SUBTREE;
+  return (-1);
+}
+
+/*
+ * Split 'str' into strings separated by commas.
+ * Note: out[] points into 'str'.
+ */
+static bool split_str(char *str, char ***out, size_t *count)
+{
+  char **res;
+  char *lasts;
+  char *s;
+  size_t  i;
+  size_t items = 1;
+
+  s = strchr(str, ',');
+  while(s) {
+    items++;
+    s = strchr(++s, ',');
+  }
+
+  res = calloc(items, sizeof(char *));
+  if(!res)
+    return FALSE;
+
+  for(i = 0, s = strtok_r(str, ",", &lasts); s && i < items;
+      s = strtok_r(NULL, ",", &lasts), i++)
+    res[i] = s;
+
+  *out = res;
+  *count = items;
+
+  return TRUE;
+}
+
+/*
+ * Break apart the pieces of an LDAP URL.
+ * Syntax:
+ *   ldap://<hostname>:<port>/<base_dn>?<attributes>?<scope>?<filter>?<ext>
+ *
+ * <hostname> already known from 'conn->host.name'.
+ * <port>     already known from 'conn->remote_port'.
+ * extract the rest from 'conn->data->state.path+1'. All fields are optional.
+ * e.g.
+ *   ldap://<hostname>:<port>/?<attributes>?<scope>?<filter>
+ * yields ludp->lud_dn = "".
+ *
+ * Defined in RFC4516 section 2.
+ */
+static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
+{
+  int rc = LDAP_SUCCESS;
+  char *path;
+  char *p;
+  char *q;
+  size_t i;
+
+  if(!conn->data ||
+      !conn->data->state.path ||
+      conn->data->state.path[0] != '/' ||
+      !checkprefix("LDAP", conn->data->change.url))
+    return LDAP_INVALID_SYNTAX;
+
+  ludp->lud_scope = LDAP_SCOPE_BASE;
+  ludp->lud_port  = conn->remote_port;
+  ludp->lud_host  = conn->host.name;
+
+  /* Duplicate the path */
+  p = path = strdup(conn->data->state.path + 1);
+  if(!path)
+    return LDAP_NO_MEMORY;
+
+  /* Parse the DN (Distinguished Name) */
+  q = strchr(p, '?');
+  if(q)
+    *q++ = '\0';
+
+  if(*p) {
+    char *dn = p;
+    char *unescaped;
+
+    LDAP_TRACE (("DN '%s'\n", dn));
+
+    /* Unescape the DN */
+    unescaped = curl_easy_unescape(conn->data, dn, 0, NULL);
+    if(!unescaped) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+
+#if defined(USE_WIN32_LDAP)
+    /* Convert the unescaped string to a tchar */
+    ludp->lud_dn = Curl_convert_UTF8_to_tchar(unescaped);
+
+    /* Free the unescaped string as we are done with it */
+    Curl_unicodefree(unescaped);
+
+    if(!ludp->lud_dn) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+#else
+    ludp->lud_dn = unescaped;
+#endif
+  }
+
+  p = q;
+  if(!p)
+    goto quit;
+
+  /* Parse the attributes. skip "??" */
+  q = strchr(p, '?');
+  if(q)
+    *q++ = '\0';
+
+  if(*p) {
+    char **attributes;
+    size_t count = 0;
+
+    /* Split the string into an array of attributes */
+    if(!split_str(p, &attributes, &count)) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+
+    /* Allocate our array (+1 for the NULL entry) */
+#if defined(USE_WIN32_LDAP)
+    ludp->lud_attrs = calloc(count + 1, sizeof(TCHAR *));
+#else
+    ludp->lud_attrs = calloc(count + 1, sizeof(char *));
+#endif
+    if(!ludp->lud_attrs) {
+      free(attributes);
+
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+
+    for(i = 0; i < count; i++) {
+      char *unescaped;
+
+      LDAP_TRACE (("attr[%d] '%s'\n", i, attributes[i]));
+
+      /* Unescape the attribute */
+      unescaped = curl_easy_unescape(conn->data, attributes[i], 0, NULL);
+      if(!unescaped) {
+        free(attributes);
+
+        rc = LDAP_NO_MEMORY;
+
+        goto quit;
+      }
+
+#if defined(USE_WIN32_LDAP)
+      /* Convert the unescaped string to a tchar */
+      ludp->lud_attrs[i] = Curl_convert_UTF8_to_tchar(unescaped);
+
+      /* Free the unescaped string as we are done with it */
+      Curl_unicodefree(unescaped);
+
+      if(!ludp->lud_attrs[i]) {
+        free(attributes);
+
+        rc = LDAP_NO_MEMORY;
+
+        goto quit;
+      }
+#else
+      ludp->lud_attrs[i] = unescaped;
+#endif
+
+      ludp->lud_attrs_dups++;
+    }
+
+    free(attributes);
+  }
+
+  p = q;
+  if(!p)
+    goto quit;
+
+  /* Parse the scope. skip "??" */
+  q = strchr(p, '?');
+  if(q)
+    *q++ = '\0';
+
+  if(*p) {
+    ludp->lud_scope = str2scope(p);
+    if(ludp->lud_scope == -1) {
+      rc = LDAP_INVALID_SYNTAX;
+
+      goto quit;
+    }
+    LDAP_TRACE (("scope %d\n", ludp->lud_scope));
+  }
+
+  p = q;
+  if(!p)
+    goto quit;
+
+  /* Parse the filter */
+  q = strchr(p, '?');
+  if(q)
+    *q++ = '\0';
+
+  if(*p) {
+    char *filter = p;
+    char *unescaped;
+
+    LDAP_TRACE (("filter '%s'\n", filter));
+
+    /* Unescape the filter */
+    unescaped = curl_easy_unescape(conn->data, filter, 0, NULL);
+    if(!unescaped) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+
+#if defined(USE_WIN32_LDAP)
+    /* Convert the unescaped string to a tchar */
+    ludp->lud_filter = Curl_convert_UTF8_to_tchar(unescaped);
+
+    /* Free the unescaped string as we are done with it */
+    Curl_unicodefree(unescaped);
+
+    if(!ludp->lud_filter) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+#else
+    ludp->lud_filter = unescaped;
+#endif
+  }
+
+  p = q;
+  if(p && !*p) {
+    rc = LDAP_INVALID_SYNTAX;
+
+    goto quit;
+  }
+
+quit:
+  free(path);
+
+  return rc;
+}
+
+static int _ldap_url_parse (const struct connectdata *conn,
+                            LDAPURLDesc **ludpp)
+{
+  LDAPURLDesc *ludp = calloc(1, sizeof(*ludp));
+  int rc;
+
+  *ludpp = NULL;
+  if(!ludp)
+     return LDAP_NO_MEMORY;
+
+  rc = _ldap_url_parse2 (conn, ludp);
+  if(rc != LDAP_SUCCESS) {
+    _ldap_free_urldesc(ludp);
+    ludp = NULL;
+  }
+  *ludpp = ludp;
+  return (rc);
+}
+
+static void _ldap_free_urldesc (LDAPURLDesc *ludp)
+{
+  size_t i;
+
+  if(!ludp)
+    return;
+
+  free(ludp->lud_dn);
+  free(ludp->lud_filter);
+
+  if(ludp->lud_attrs) {
+    for(i = 0; i < ludp->lud_attrs_dups; i++)
+      free(ludp->lud_attrs[i]);
+    free(ludp->lud_attrs);
+  }
+
+  free (ludp);
+}
+#endif  /* !HAVE_LDAP_URL_PARSE */
+#endif  /* !CURL_DISABLE_LDAP && !USE_OPENLDAP */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/llist.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/llist.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/llist.c	(revision 164)
@@ -0,0 +1,212 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "llist.h"
+#include "curl_memory.h"
+
+/* this must be the last include file */
+#include "memdebug.h"
+
+/*
+ * @unittest: 1300
+ */
+static void
+llist_init(struct curl_llist *l, curl_llist_dtor dtor)
+{
+  l->size = 0;
+  l->dtor = dtor;
+  l->head = NULL;
+  l->tail = NULL;
+}
+
+struct curl_llist *
+Curl_llist_alloc(curl_llist_dtor dtor)
+{
+  struct curl_llist *list;
+
+  list = malloc(sizeof(struct curl_llist));
+  if(!list)
+    return NULL;
+
+  llist_init(list, dtor);
+
+  return list;
+}
+
+/*
+ * Curl_llist_insert_next()
+ *
+ * Inserts a new list element after the given one 'e'. If the given existing
+ * entry is NULL and the list already has elements, the new one will be
+ * inserted first in the list.
+ *
+ * Returns: 1 on success and 0 on failure.
+ *
+ * @unittest: 1300
+ */
+int
+Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
+                       const void *p)
+{
+  struct curl_llist_element *ne = malloc(sizeof(struct curl_llist_element));
+  if(!ne)
+    return 0;
+
+  ne->ptr = (void *) p;
+  if(list->size == 0) {
+    list->head = ne;
+    list->head->prev = NULL;
+    list->head->next = NULL;
+    list->tail = ne;
+  }
+  else {
+    /* if 'e' is NULL here, we insert the new element first in the list */
+    ne->next = e?e->next:list->head;
+    ne->prev = e;
+    if(!e) {
+      list->head->prev = ne;
+      list->head = ne;
+    }
+    else if(e->next) {
+      e->next->prev = ne;
+    }
+    else {
+      list->tail = ne;
+    }
+    if(e)
+      e->next = ne;
+  }
+
+  ++list->size;
+
+  return 1;
+}
+
+/*
+ * @unittest: 1300
+ */
+int
+Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
+                  void *user)
+{
+  if(e == NULL || list->size == 0)
+    return 1;
+
+  if(e == list->head) {
+    list->head = e->next;
+
+    if(list->head == NULL)
+      list->tail = NULL;
+    else
+      e->next->prev = NULL;
+  }
+  else {
+    e->prev->next = e->next;
+    if(!e->next)
+      list->tail = e->prev;
+    else
+      e->next->prev = e->prev;
+  }
+
+  list->dtor(user, e->ptr);
+
+  e->ptr  = NULL;
+  e->prev = NULL;
+  e->next = NULL;
+
+  free(e);
+  --list->size;
+
+  return 1;
+}
+
+void
+Curl_llist_destroy(struct curl_llist *list, void *user)
+{
+  if(list) {
+    while(list->size > 0)
+      Curl_llist_remove(list, list->tail, user);
+
+    free(list);
+  }
+}
+
+size_t
+Curl_llist_count(struct curl_llist *list)
+{
+  return list->size;
+}
+
+/*
+ * @unittest: 1300
+ */
+int Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e,
+                    struct curl_llist *to_list,
+                    struct curl_llist_element *to_e)
+{
+  /* Remove element from list */
+  if(e == NULL || list->size == 0)
+    return 0;
+
+  if(e == list->head) {
+    list->head = e->next;
+
+    if(list->head == NULL)
+      list->tail = NULL;
+    else
+      e->next->prev = NULL;
+  }
+  else {
+    e->prev->next = e->next;
+    if(!e->next)
+      list->tail = e->prev;
+    else
+      e->next->prev = e->prev;
+  }
+
+  --list->size;
+
+  /* Add element to to_list after to_e */
+  if(to_list->size == 0) {
+    to_list->head = e;
+    to_list->head->prev = NULL;
+    to_list->head->next = NULL;
+    to_list->tail = e;
+  }
+  else {
+    e->next = to_e->next;
+    e->prev = to_e;
+    if(to_e->next) {
+      to_e->next->prev = e;
+    }
+    else {
+      to_list->tail = e;
+    }
+    to_e->next = e;
+  }
+
+  ++to_list->size;
+
+  return 1;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/llist.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/llist.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/llist.h	(revision 164)
@@ -0,0 +1,57 @@
+#ifndef HEADER_CURL_LLIST_H
+#define HEADER_CURL_LLIST_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include <stddef.h>
+
+typedef void (*curl_llist_dtor)(void *, void *);
+
+struct curl_llist_element {
+  void *ptr;
+
+  struct curl_llist_element *prev;
+  struct curl_llist_element *next;
+};
+
+struct curl_llist {
+  struct curl_llist_element *head;
+  struct curl_llist_element *tail;
+
+  curl_llist_dtor dtor;
+
+  size_t size;
+};
+
+struct curl_llist *Curl_llist_alloc(curl_llist_dtor);
+int Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *,
+                           const void *);
+int Curl_llist_remove(struct curl_llist *, struct curl_llist_element *,
+                      void *);
+size_t Curl_llist_count(struct curl_llist *);
+void Curl_llist_destroy(struct curl_llist *, void *);
+int Curl_llist_move(struct curl_llist *, struct curl_llist_element *,
+                    struct curl_llist *, struct curl_llist_element *);
+
+#endif /* HEADER_CURL_LLIST_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/md4.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/md4.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/md4.c	(revision 164)
@@ -0,0 +1,304 @@
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD4 Message-Digest Algorithm (RFC 1320).
+ *
+ * Homepage:
+ http://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001.  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) 2001
+ * Alexander Peslyak 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.
+ *
+ * (This is a heavily cut-down "BSD license".)
+ *
+ * This differs from Colin Plumb's older public domain implementation in that
+ * no exactly 32-bit integer data type is required (any 32-bit or wider
+ * unsigned integer data type will do), there's no compile-time endianness
+ * configuration, and the function prototypes match OpenSSL's.  No code from
+ * Colin Plumb's implementation has been reused; this comment merely compares
+ * the properties of the two independent implementations.
+ *
+ * The primary goals of this implementation are portability and ease of use.
+ * It is meant to be fast, but not as fast as possible.  Some known
+ * optimizations are not included to reduce source code size and avoid
+ * compile-time configuration.
+ */
+
+#include "curl_setup.h"
+
+/* NSS and OS/400 crypto library do not provide the MD4 hash algorithm, so
+ * that we have a local implementation of it */
+#if defined(USE_NSS) || defined(USE_OS400CRYPTO)
+
+#include "curl_md4.h"
+#include "warnless.h"
+
+#ifndef HAVE_OPENSSL
+
+#include <string.h>
+
+/* Any 32-bit or wider unsigned integer data type will do */
+typedef unsigned int MD4_u32plus;
+
+typedef struct {
+  MD4_u32plus lo, hi;
+  MD4_u32plus a, b, c, d;
+  unsigned char buffer[64];
+  MD4_u32plus block[16];
+} MD4_CTX;
+
+static void MD4_Init(MD4_CTX *ctx);
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx);
+
+/*
+ * The basic MD4 functions.
+ *
+ * F and G are optimized compared to their RFC 1320 definitions, with the
+ * optimization for F borrowed from Colin Plumb's MD5 implementation.
+ */
+#define F(x, y, z)                      ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z)                      (((x) & ((y) | (z))) | ((y) & (z)))
+#define H(x, y, z)                      ((x) ^ (y) ^ (z))
+
+/*
+ * The MD4 transformation for all three rounds.
+ */
+#define STEP(f, a, b, c, d, x, s) \
+        (a) += f((b), (c), (d)) + (x); \
+        (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));
+
+/*
+ * SET reads 4 input bytes in little-endian byte order and stores them
+ * in a properly aligned word in host byte order.
+ *
+ * The check for little-endian architectures that tolerate unaligned
+ * memory accesses is just an optimization.  Nothing will break if it
+ * doesn't work.
+ */
+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
+#define SET(n) \
+        (*(MD4_u32plus *)&ptr[(n) * 4])
+#define GET(n) \
+        SET(n)
+#else
+#define SET(n) \
+        (ctx->block[(n)] = \
+        (MD4_u32plus)ptr[(n) * 4] | \
+        ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \
+        ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \
+        ((MD4_u32plus)ptr[(n) * 4 + 3] << 24))
+#define GET(n) \
+        (ctx->block[(n)])
+#endif
+
+/*
+ * This processes one or more 64-byte data blocks, but does NOT update
+ * the bit counters.  There are no alignment requirements.
+ */
+static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+  const unsigned char *ptr;
+  MD4_u32plus a, b, c, d;
+  MD4_u32plus saved_a, saved_b, saved_c, saved_d;
+
+  ptr = (const unsigned char *)data;
+
+  a = ctx->a;
+  b = ctx->b;
+  c = ctx->c;
+  d = ctx->d;
+
+  do {
+    saved_a = a;
+    saved_b = b;
+    saved_c = c;
+    saved_d = d;
+
+/* Round 1 */
+    STEP(F, a, b, c, d, SET(0), 3)
+      STEP(F, d, a, b, c, SET(1), 7)
+      STEP(F, c, d, a, b, SET(2), 11)
+      STEP(F, b, c, d, a, SET(3), 19)
+      STEP(F, a, b, c, d, SET(4), 3)
+      STEP(F, d, a, b, c, SET(5), 7)
+      STEP(F, c, d, a, b, SET(6), 11)
+      STEP(F, b, c, d, a, SET(7), 19)
+      STEP(F, a, b, c, d, SET(8), 3)
+      STEP(F, d, a, b, c, SET(9), 7)
+      STEP(F, c, d, a, b, SET(10), 11)
+      STEP(F, b, c, d, a, SET(11), 19)
+      STEP(F, a, b, c, d, SET(12), 3)
+      STEP(F, d, a, b, c, SET(13), 7)
+      STEP(F, c, d, a, b, SET(14), 11)
+      STEP(F, b, c, d, a, SET(15), 19)
+
+/* Round 2 */
+      STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
+      STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
+      STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
+      STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
+      STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
+      STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
+      STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
+      STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
+      STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
+      STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
+      STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
+      STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
+      STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
+      STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
+      STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
+      STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
+
+/* Round 3 */
+      STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
+      STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
+      STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
+      STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
+      STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
+      STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
+      STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
+      STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
+      STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
+      STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
+      STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
+      STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
+      STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
+      STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
+      STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
+      STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
+
+      a += saved_a;
+    b += saved_b;
+    c += saved_c;
+    d += saved_d;
+
+    ptr += 64;
+  } while(size -= 64);
+
+  ctx->a = a;
+  ctx->b = b;
+  ctx->c = c;
+  ctx->d = d;
+
+  return ptr;
+}
+
+static void MD4_Init(MD4_CTX *ctx)
+{
+  ctx->a = 0x67452301;
+  ctx->b = 0xefcdab89;
+  ctx->c = 0x98badcfe;
+  ctx->d = 0x10325476;
+
+  ctx->lo = 0;
+  ctx->hi = 0;
+}
+
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+  MD4_u32plus saved_lo;
+  unsigned long used, available;
+
+  saved_lo = ctx->lo;
+  if((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
+    ctx->hi++;
+  ctx->hi += (MD4_u32plus)size >> 29;
+
+  used = saved_lo & 0x3f;
+
+  if(used) {
+    available = 64 - used;
+
+    if(size < available) {
+      memcpy(&ctx->buffer[used], data, size);
+      return;
+    }
+
+    memcpy(&ctx->buffer[used], data, available);
+    data = (const unsigned char *)data + available;
+    size -= available;
+    body(ctx, ctx->buffer, 64);
+  }
+
+  if(size >= 64) {
+    data = body(ctx, data, size & ~(unsigned long)0x3f);
+    size &= 0x3f;
+  }
+
+  memcpy(ctx->buffer, data, size);
+}
+
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
+{
+  unsigned long used, available;
+
+  used = ctx->lo & 0x3f;
+
+  ctx->buffer[used++] = 0x80;
+
+  available = 64 - used;
+
+  if(available < 8) {
+    memset(&ctx->buffer[used], 0, available);
+    body(ctx, ctx->buffer, 64);
+    used = 0;
+    available = 64;
+  }
+
+  memset(&ctx->buffer[used], 0, available - 8);
+
+  ctx->lo <<= 3;
+  ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
+  ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
+  ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
+  ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff);
+  ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
+  ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
+  ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
+  ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
+
+  body(ctx, ctx->buffer, 64);
+
+  result[0] = curlx_ultouc((ctx->a)&0xff);
+  result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
+  result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
+  result[3] = curlx_ultouc(ctx->a >> 24);
+  result[4] = curlx_ultouc((ctx->b)&0xff);
+  result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
+  result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
+  result[7] = curlx_ultouc(ctx->b >> 24);
+  result[8] = curlx_ultouc((ctx->c)&0xff);
+  result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
+  result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
+  result[11] = curlx_ultouc(ctx->c >> 24);
+  result[12] = curlx_ultouc((ctx->d)&0xff);
+  result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
+  result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
+  result[15] = curlx_ultouc(ctx->d >> 24);
+
+  memset(ctx, 0, sizeof(*ctx));
+}
+
+#endif
+
+void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len)
+{
+  MD4_CTX ctx;
+  MD4_Init(&ctx);
+  MD4_Update(&ctx, input, curlx_uztoui(len));
+  MD4_Final(output, &ctx);
+}
+#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/md5.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/md5.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/md5.c	(revision 164)
@@ -0,0 +1,560 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+
+#include "curl_md5.h"
+#include "curl_hmac.h"
+#include "warnless.h"
+
+#if defined(USE_GNUTLS_NETTLE)
+
+#include <nettle/md5.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct md5_ctx MD5_CTX;
+
+static void MD5_Init(MD5_CTX * ctx)
+{
+  md5_init(ctx);
+}
+
+static void MD5_Update(MD5_CTX * ctx,
+                       const unsigned char * input,
+                       unsigned int inputLen)
+{
+  md5_update(ctx, inputLen, input);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
+{
+  md5_digest(ctx, 16, digest);
+}
+
+#elif defined(USE_GNUTLS)
+
+#include <gcrypt.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef gcry_md_hd_t MD5_CTX;
+
+static void MD5_Init(MD5_CTX * ctx)
+{
+  gcry_md_open(ctx, GCRY_MD_MD5, 0);
+}
+
+static void MD5_Update(MD5_CTX * ctx,
+                       const unsigned char * input,
+                       unsigned int inputLen)
+{
+  gcry_md_write(*ctx, input, inputLen);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
+{
+  memcpy(digest, gcry_md_read(*ctx, 0), 16);
+  gcry_md_close(*ctx);
+}
+
+#elif defined(USE_OPENSSL) || defined(USE_CYASSL)
+/* When OpenSSL is available we use the MD5-function from OpenSSL */
+#include <openssl/md5.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
+              (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
+      (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
+              (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
+
+/* For Apple operating systems: CommonCrypto has the functions we need.
+   These functions are available on Tiger and later, as well as iOS 2.0
+   and later. If you're building for an older cat, well, sorry.
+
+   Declaring the functions as static like this seems to be a bit more
+   reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */
+#  include <CommonCrypto/CommonDigest.h>
+#  define MD5_CTX CC_MD5_CTX
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+static void MD5_Init(MD5_CTX *ctx)
+{
+  CC_MD5_Init(ctx);
+}
+
+static void MD5_Update(MD5_CTX *ctx,
+                       const unsigned char *input,
+                       unsigned int inputLen)
+{
+  CC_MD5_Update(ctx, input, inputLen);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+{
+  CC_MD5_Final(digest, ctx);
+}
+
+#elif defined(_WIN32)
+
+#include <wincrypt.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct {
+  HCRYPTPROV hCryptProv;
+  HCRYPTHASH hHash;
+} MD5_CTX;
+
+static void MD5_Init(MD5_CTX *ctx)
+{
+  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
+                         PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+    CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
+  }
+}
+
+static void MD5_Update(MD5_CTX *ctx,
+                       const unsigned char *input,
+                       unsigned int inputLen)
+{
+  CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+{
+  unsigned long length = 0;
+  CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
+  if(length == 16)
+    CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
+  if(ctx->hHash)
+    CryptDestroyHash(ctx->hHash);
+  if(ctx->hCryptProv)
+    CryptReleaseContext(ctx->hCryptProv, 0);
+}
+
+#elif defined(USE_AXTLS)
+#include <axTLS/config.h>
+#include <axTLS/os_int.h>
+#include <axTLS/crypto.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+#else
+/* When no other crypto library is available we use this code segment */
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD5 Message-Digest Algorithm (RFC 1321).
+ *
+ * Homepage:
+ http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001.  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) 2001 Alexander Peslyak 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.
+ *
+ * (This is a heavily cut-down "BSD license".)
+ *
+ * This differs from Colin Plumb's older public domain implementation in that
+ * no exactly 32-bit integer data type is required (any 32-bit or wider
+ * unsigned integer data type will do), there's no compile-time endianness
+ * configuration, and the function prototypes match OpenSSL's.  No code from
+ * Colin Plumb's implementation has been reused; this comment merely compares
+ * the properties of the two independent implementations.
+ *
+ * The primary goals of this implementation are portability and ease of use.
+ * It is meant to be fast, but not as fast as possible.  Some known
+ * optimizations are not included to reduce source code size and avoid
+ * compile-time configuration.
+ */
+
+#include <string.h>
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Any 32-bit or wider unsigned integer data type will do */
+typedef unsigned int MD5_u32plus;
+
+typedef struct {
+  MD5_u32plus lo, hi;
+  MD5_u32plus a, b, c, d;
+  unsigned char buffer[64];
+  MD5_u32plus block[16];
+} MD5_CTX;
+
+static void MD5_Init(MD5_CTX *ctx);
+static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
+static void MD5_Final(unsigned char *result, MD5_CTX *ctx);
+
+/*
+ * The basic MD5 functions.
+ *
+ * F and G are optimized compared to their RFC 1321 definitions for
+ * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
+ * implementation.
+ */
+#define F(x, y, z)                      ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z)                      ((y) ^ ((z) & ((x) ^ (y))))
+#define H(x, y, z)                      (((x) ^ (y)) ^ (z))
+#define H2(x, y, z)                     ((x) ^ ((y) ^ (z)))
+#define I(x, y, z)                      ((y) ^ ((x) | ~(z)))
+
+/*
+ * The MD5 transformation for all four rounds.
+ */
+#define STEP(f, a, b, c, d, x, t, s) \
+        (a) += f((b), (c), (d)) + (x) + (t); \
+        (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
+        (a) += (b);
+
+/*
+ * SET reads 4 input bytes in little-endian byte order and stores them
+ * in a properly aligned word in host byte order.
+ *
+ * The check for little-endian architectures that tolerate unaligned
+ * memory accesses is just an optimization.  Nothing will break if it
+ * doesn't work.
+ */
+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
+#define SET(n) \
+        (*(MD5_u32plus *)&ptr[(n) * 4])
+#define GET(n) \
+        SET(n)
+#else
+#define SET(n) \
+        (ctx->block[(n)] = \
+        (MD5_u32plus)ptr[(n) * 4] | \
+        ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
+        ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
+        ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
+#define GET(n) \
+        (ctx->block[(n)])
+#endif
+
+/*
+ * This processes one or more 64-byte data blocks, but does NOT update
+ * the bit counters.  There are no alignment requirements.
+ */
+static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
+{
+  const unsigned char *ptr;
+  MD5_u32plus a, b, c, d;
+  MD5_u32plus saved_a, saved_b, saved_c, saved_d;
+
+  ptr = (const unsigned char *)data;
+
+  a = ctx->a;
+  b = ctx->b;
+  c = ctx->c;
+  d = ctx->d;
+
+  do {
+    saved_a = a;
+    saved_b = b;
+    saved_c = c;
+    saved_d = d;
+
+/* Round 1 */
+    STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
+      STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
+      STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
+      STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
+      STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
+      STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
+      STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
+      STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
+      STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
+      STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
+      STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
+      STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
+      STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
+      STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
+      STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
+      STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
+
+/* Round 2 */
+      STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
+      STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
+      STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
+      STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
+      STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
+      STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
+      STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
+      STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
+      STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
+      STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
+      STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
+      STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
+      STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
+      STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
+      STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
+      STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
+
+/* Round 3 */
+      STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
+      STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
+      STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
+      STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
+      STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
+      STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
+      STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
+      STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
+      STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
+      STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
+      STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
+      STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
+      STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
+      STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
+      STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
+      STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
+
+/* Round 4 */
+      STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
+      STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
+      STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
+      STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
+      STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
+      STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
+      STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
+      STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
+      STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
+      STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
+      STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
+      STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
+      STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
+      STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
+      STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
+      STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
+
+      a += saved_a;
+    b += saved_b;
+    c += saved_c;
+    d += saved_d;
+
+    ptr += 64;
+  } while(size -= 64);
+
+  ctx->a = a;
+  ctx->b = b;
+  ctx->c = c;
+  ctx->d = d;
+
+  return ptr;
+}
+
+static void MD5_Init(MD5_CTX *ctx)
+{
+  ctx->a = 0x67452301;
+  ctx->b = 0xefcdab89;
+  ctx->c = 0x98badcfe;
+  ctx->d = 0x10325476;
+
+  ctx->lo = 0;
+  ctx->hi = 0;
+}
+
+static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
+{
+  MD5_u32plus saved_lo;
+  unsigned long used, available;
+
+  saved_lo = ctx->lo;
+  if((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
+    ctx->hi++;
+  ctx->hi += (MD5_u32plus)size >> 29;
+
+  used = saved_lo & 0x3f;
+
+  if(used) {
+    available = 64 - used;
+
+    if(size < available) {
+      memcpy(&ctx->buffer[used], data, size);
+      return;
+    }
+
+    memcpy(&ctx->buffer[used], data, available);
+    data = (const unsigned char *)data + available;
+    size -= available;
+    body(ctx, ctx->buffer, 64);
+  }
+
+  if(size >= 64) {
+    data = body(ctx, data, size & ~(unsigned long)0x3f);
+    size &= 0x3f;
+  }
+
+  memcpy(ctx->buffer, data, size);
+}
+
+static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
+{
+  unsigned long used, available;
+
+  used = ctx->lo & 0x3f;
+
+  ctx->buffer[used++] = 0x80;
+
+  available = 64 - used;
+
+  if(available < 8) {
+    memset(&ctx->buffer[used], 0, available);
+    body(ctx, ctx->buffer, 64);
+    used = 0;
+    available = 64;
+  }
+
+  memset(&ctx->buffer[used], 0, available - 8);
+
+  ctx->lo <<= 3;
+  ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
+  ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
+  ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
+  ctx->buffer[59] = curlx_ultouc(ctx->lo >> 24);
+  ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
+  ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
+  ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
+  ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
+
+  body(ctx, ctx->buffer, 64);
+
+  result[0] = curlx_ultouc((ctx->a)&0xff);
+  result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
+  result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
+  result[3] = curlx_ultouc(ctx->a >> 24);
+  result[4] = curlx_ultouc((ctx->b)&0xff);
+  result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
+  result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
+  result[7] = curlx_ultouc(ctx->b >> 24);
+  result[8] = curlx_ultouc((ctx->c)&0xff);
+  result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
+  result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
+  result[11] = curlx_ultouc(ctx->c >> 24);
+  result[12] = curlx_ultouc((ctx->d)&0xff);
+  result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
+  result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
+  result[15] = curlx_ultouc(ctx->d >> 24);
+
+  memset(ctx, 0, sizeof(*ctx));
+}
+
+#endif /* CRYPTO LIBS */
+
+const HMAC_params Curl_HMAC_MD5[] = {
+  {
+    (HMAC_hinit_func) MD5_Init,           /* Hash initialization function. */
+    (HMAC_hupdate_func) MD5_Update,       /* Hash update function. */
+    (HMAC_hfinal_func) MD5_Final,         /* Hash computation end function. */
+    sizeof(MD5_CTX),                      /* Size of hash context structure. */
+    64,                                   /* Maximum key length. */
+    16                                    /* Result size. */
+  }
+};
+
+const MD5_params Curl_DIGEST_MD5[] = {
+  {
+    (Curl_MD5_init_func) MD5_Init,      /* Digest initialization function */
+    (Curl_MD5_update_func) MD5_Update,  /* Digest update function */
+    (Curl_MD5_final_func) MD5_Final,    /* Digest computation end function */
+    sizeof(MD5_CTX),                    /* Size of digest context struct */
+    16                                  /* Result size */
+  }
+};
+
+/*
+ * @unittest: 1601
+ */
+void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
+                const unsigned char *input)
+{
+  MD5_CTX ctx;
+  MD5_Init(&ctx);
+  MD5_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
+  MD5_Final(outbuffer, &ctx);
+}
+
+MD5_context *Curl_MD5_init(const MD5_params *md5params)
+{
+  MD5_context *ctxt;
+
+  /* Create MD5 context */
+  ctxt = malloc(sizeof *ctxt);
+
+  if(!ctxt)
+    return ctxt;
+
+  ctxt->md5_hashctx = malloc(md5params->md5_ctxtsize);
+
+  if(!ctxt->md5_hashctx) {
+    free(ctxt);
+    return NULL;
+  }
+
+  ctxt->md5_hash = md5params;
+
+  (*md5params->md5_init_func)(ctxt->md5_hashctx);
+
+  return ctxt;
+}
+
+int Curl_MD5_update(MD5_context *context,
+                    const unsigned char *data,
+                    unsigned int len)
+{
+  (*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len);
+
+  return 0;
+}
+
+int Curl_MD5_final(MD5_context *context, unsigned char *result)
+{
+  (*context->md5_hash->md5_final_func)(result, context->md5_hashctx);
+
+  free(context->md5_hashctx);
+  free(context);
+
+  return 0;
+}
+
+#endif /* CURL_DISABLE_CRYPTO_AUTH */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/memdebug.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/memdebug.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/memdebug.c	(revision 164)
@@ -0,0 +1,489 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef CURLDEBUG
+
+#include <curl/curl.h>
+
+#include "curl_printf.h"
+#include "urldata.h"
+
+#define MEMDEBUG_NODEFINES /* don't redefine the standard functions */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef HAVE_ASSERT_H
+#  define assert(x) Curl_nop_stmt
+#endif
+
+/*
+ * Until 2011-08-17 libcurl's Memory Tracking feature also performed
+ * automatic malloc and free filling operations using 0xA5 and 0x13
+ * values. Our own preinitialization of dynamically allocated memory
+ * might be useful when not using third party memory debuggers, but
+ * on the other hand this would fool memory debuggers into thinking
+ * that all dynamically allocated memory is properly initialized.
+ *
+ * As a default setting, libcurl's Memory Tracking feature no longer
+ * performs preinitialization of dynamically allocated memory on its
+ * own. If you know what you are doing, and really want to retain old
+ * behavior, you can achieve this compiling with preprocessor symbols
+ * CURL_MT_MALLOC_FILL and CURL_MT_FREE_FILL defined with appropriate
+ * values.
+ */
+
+#ifdef CURL_MT_MALLOC_FILL
+# if (CURL_MT_MALLOC_FILL < 0) || (CURL_MT_MALLOC_FILL > 0xff)
+#   error "invalid CURL_MT_MALLOC_FILL or out of range"
+# endif
+#endif
+
+#ifdef CURL_MT_FREE_FILL
+# if (CURL_MT_FREE_FILL < 0) || (CURL_MT_FREE_FILL > 0xff)
+#   error "invalid CURL_MT_FREE_FILL or out of range"
+# endif
+#endif
+
+#if defined(CURL_MT_MALLOC_FILL) && defined(CURL_MT_FREE_FILL)
+# if (CURL_MT_MALLOC_FILL == CURL_MT_FREE_FILL)
+#   error "CURL_MT_MALLOC_FILL same as CURL_MT_FREE_FILL"
+# endif
+#endif
+
+#ifdef CURL_MT_MALLOC_FILL
+#  define mt_malloc_fill(buf,len) memset((buf), CURL_MT_MALLOC_FILL, (len))
+#else
+#  define mt_malloc_fill(buf,len) Curl_nop_stmt
+#endif
+
+#ifdef CURL_MT_FREE_FILL
+#  define mt_free_fill(buf,len) memset((buf), CURL_MT_FREE_FILL, (len))
+#else
+#  define mt_free_fill(buf,len) Curl_nop_stmt
+#endif
+
+struct memdebug {
+  size_t size;
+  union {
+    curl_off_t o;
+    double d;
+    void * p;
+  } mem[1];
+  /* I'm hoping this is the thing with the strictest alignment
+   * requirements.  That also means we waste some space :-( */
+};
+
+/*
+ * Note that these debug functions are very simple and they are meant to
+ * remain so. For advanced analysis, record a log file and write perl scripts
+ * to analyze them!
+ *
+ * Don't use these with multithreaded test programs!
+ */
+
+#define logfile curl_debuglogfile
+FILE *curl_debuglogfile = NULL;
+static bool memlimit = FALSE; /* enable memory limit */
+static long memsize = 0;  /* set number of mallocs allowed */
+
+/* this sets the log file name */
+void curl_memdebug(const char *logname)
+{
+  if(!logfile) {
+    if(logname && *logname)
+      logfile = fopen(logname, FOPEN_WRITETEXT);
+    else
+      logfile = stderr;
+#ifdef MEMDEBUG_LOG_SYNC
+    /* Flush the log file after every line so the log isn't lost in a crash */
+    setvbuf(logfile, (char *)NULL, _IOLBF, 0);
+#endif
+  }
+}
+
+/* This function sets the number of malloc() calls that should return
+   successfully! */
+void curl_memlimit(long limit)
+{
+  if(!memlimit) {
+    memlimit = TRUE;
+    memsize = limit;
+  }
+}
+
+/* returns TRUE if this isn't allowed! */
+static bool countcheck(const char *func, int line, const char *source)
+{
+  /* if source is NULL, then the call is made internally and this check
+     should not be made */
+  if(memlimit && source) {
+    if(!memsize) {
+      if(source) {
+        /* log to file */
+        curl_memlog("LIMIT %s:%d %s reached memlimit\n",
+                    source, line, func);
+        /* log to stderr also */
+        fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n",
+                source, line, func);
+      }
+      SET_ERRNO(ENOMEM);
+      return TRUE; /* RETURN ERROR! */
+    }
+    else
+      memsize--; /* countdown */
+
+    /* log the countdown */
+    if(source)
+      curl_memlog("LIMIT %s:%d %ld ALLOCS left\n",
+                  source, line, memsize);
+
+  }
+
+  return FALSE; /* allow this */
+}
+
+void *curl_domalloc(size_t wantedsize, int line, const char *source)
+{
+  struct memdebug *mem;
+  size_t size;
+
+  assert(wantedsize != 0);
+
+  if(countcheck("malloc", line, source))
+    return NULL;
+
+  /* alloc at least 64 bytes */
+  size = sizeof(struct memdebug)+wantedsize;
+
+  mem = (Curl_cmalloc)(size);
+  if(mem) {
+    /* fill memory with junk */
+    mt_malloc_fill(mem->mem, wantedsize);
+    mem->size = wantedsize;
+  }
+
+  if(source)
+    curl_memlog("MEM %s:%d malloc(%zu) = %p\n",
+                source, line, wantedsize,
+                mem ? (void *)mem->mem : (void *)0);
+
+  return (mem ? mem->mem : NULL);
+}
+
+void *curl_docalloc(size_t wanted_elements, size_t wanted_size,
+                    int line, const char *source)
+{
+  struct memdebug *mem;
+  size_t size, user_size;
+
+  assert(wanted_elements != 0);
+  assert(wanted_size != 0);
+
+  if(countcheck("calloc", line, source))
+    return NULL;
+
+  /* alloc at least 64 bytes */
+  user_size = wanted_size * wanted_elements;
+  size = sizeof(struct memdebug) + user_size;
+
+  mem = (Curl_ccalloc)(1, size);
+  if(mem)
+    mem->size = user_size;
+
+  if(source)
+    curl_memlog("MEM %s:%d calloc(%zu,%zu) = %p\n",
+                source, line, wanted_elements, wanted_size,
+                mem ? (void *)mem->mem : (void *)0);
+
+  return (mem ? mem->mem : NULL);
+}
+
+char *curl_dostrdup(const char *str, int line, const char *source)
+{
+  char *mem;
+  size_t len;
+
+  assert(str != NULL);
+
+  if(countcheck("strdup", line, source))
+    return NULL;
+
+  len=strlen(str)+1;
+
+  mem=curl_domalloc(len, 0, NULL); /* NULL prevents logging */
+  if(mem)
+    memcpy(mem, str, len);
+
+  if(source)
+    curl_memlog("MEM %s:%d strdup(%p) (%zu) = %p\n",
+                source, line, (void *)str, len, (void *)mem);
+
+  return mem;
+}
+
+#if defined(WIN32) && defined(UNICODE)
+wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source)
+{
+  wchar_t *mem;
+  size_t wsiz, bsiz;
+
+  assert(str != NULL);
+
+  if(countcheck("wcsdup", line, source))
+    return NULL;
+
+  wsiz = wcslen(str) + 1;
+  bsiz = wsiz * sizeof(wchar_t);
+
+  mem = curl_domalloc(bsiz, 0, NULL); /* NULL prevents logging */
+  if(mem)
+    memcpy(mem, str, bsiz);
+
+  if(source)
+    curl_memlog("MEM %s:%d wcsdup(%p) (%zu) = %p\n",
+                source, line, (void *)str, bsiz, (void *)mem);
+
+  return mem;
+}
+#endif
+
+/* We provide a realloc() that accepts a NULL as pointer, which then
+   performs a malloc(). In order to work with ares. */
+void *curl_dorealloc(void *ptr, size_t wantedsize,
+                     int line, const char *source)
+{
+  struct memdebug *mem=NULL;
+
+  size_t size = sizeof(struct memdebug)+wantedsize;
+
+  assert(wantedsize != 0);
+
+  if(countcheck("realloc", line, source))
+    return NULL;
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:1684)
+   /* 1684: conversion from pointer to same-sized integral type */
+#endif
+
+  if(ptr)
+    mem = (void *)((char *)ptr - offsetof(struct memdebug, mem));
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+
+  mem = (Curl_crealloc)(mem, size);
+  if(source)
+    curl_memlog("MEM %s:%d realloc(%p, %zu) = %p\n",
+                source, line, (void *)ptr, wantedsize,
+                mem ? (void *)mem->mem : (void *)0);
+
+  if(mem) {
+    mem->size = wantedsize;
+    return mem->mem;
+  }
+
+  return NULL;
+}
+
+void curl_dofree(void *ptr, int line, const char *source)
+{
+  struct memdebug *mem;
+
+  if(ptr) {
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:1684)
+   /* 1684: conversion from pointer to same-sized integral type */
+#endif
+
+    mem = (void *)((char *)ptr - offsetof(struct memdebug, mem));
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+
+    /* destroy */
+    mt_free_fill(mem->mem, mem->size);
+
+    /* free for real */
+    (Curl_cfree)(mem);
+  }
+
+  if(source)
+    curl_memlog("MEM %s:%d free(%p)\n", source, line, (void *)ptr);
+}
+
+curl_socket_t curl_socket(int domain, int type, int protocol,
+                          int line, const char *source)
+{
+  const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
+    "FD %s:%d socket() = %d\n" :
+    (sizeof(curl_socket_t) == sizeof(long)) ?
+    "FD %s:%d socket() = %ld\n" :
+    "FD %s:%d socket() = %zd\n";
+
+  curl_socket_t sockfd = socket(domain, type, protocol);
+
+  if(source && (sockfd != CURL_SOCKET_BAD))
+    curl_memlog(fmt, source, line, sockfd);
+
+  return sockfd;
+}
+
+#ifdef HAVE_SOCKETPAIR
+int curl_socketpair(int domain, int type, int protocol,
+                    curl_socket_t socket_vector[2],
+                    int line, const char *source)
+{
+  const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
+    "FD %s:%d socketpair() = %d %d\n" :
+    (sizeof(curl_socket_t) == sizeof(long)) ?
+    "FD %s:%d socketpair() = %ld %ld\n" :
+    "FD %s:%d socketpair() = %zd %zd\n";
+
+  int res = socketpair(domain, type, protocol, socket_vector);
+
+  if(source && (0 == res))
+    curl_memlog(fmt, source, line, socket_vector[0], socket_vector[1]);
+
+  return res;
+}
+#endif
+
+curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen,
+                          int line, const char *source)
+{
+  const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
+    "FD %s:%d accept() = %d\n" :
+    (sizeof(curl_socket_t) == sizeof(long)) ?
+    "FD %s:%d accept() = %ld\n" :
+    "FD %s:%d accept() = %zd\n";
+
+  struct sockaddr *addr = (struct sockaddr *)saddr;
+  curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen;
+
+  curl_socket_t sockfd = accept(s, addr, addrlen);
+
+  if(source && (sockfd != CURL_SOCKET_BAD))
+    curl_memlog(fmt, source, line, sockfd);
+
+  return sockfd;
+}
+
+/* separate function to allow libcurl to mark a "faked" close */
+void curl_mark_sclose(curl_socket_t sockfd, int line, const char *source)
+{
+  const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
+    "FD %s:%d sclose(%d)\n":
+    (sizeof(curl_socket_t) == sizeof(long)) ?
+    "FD %s:%d sclose(%ld)\n":
+    "FD %s:%d sclose(%zd)\n";
+
+  if(source)
+    curl_memlog(fmt, source, line, sockfd);
+}
+
+/* this is our own defined way to close sockets on *ALL* platforms */
+int curl_sclose(curl_socket_t sockfd, int line, const char *source)
+{
+  int res=sclose(sockfd);
+  curl_mark_sclose(sockfd, line, source);
+  return res;
+}
+
+FILE *curl_fopen(const char *file, const char *mode,
+                 int line, const char *source)
+{
+  FILE *res=fopen(file, mode);
+
+  if(source)
+    curl_memlog("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n",
+                source, line, file, mode, (void *)res);
+
+  return res;
+}
+
+#ifdef HAVE_FDOPEN
+FILE *curl_fdopen(int filedes, const char *mode,
+                  int line, const char *source)
+{
+  FILE *res=fdopen(filedes, mode);
+
+  if(source)
+    curl_memlog("FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n",
+                source, line, filedes, mode, (void *)res);
+
+  return res;
+}
+#endif
+
+int curl_fclose(FILE *file, int line, const char *source)
+{
+  int res;
+
+  assert(file != NULL);
+
+  res=fclose(file);
+
+  if(source)
+    curl_memlog("FILE %s:%d fclose(%p)\n",
+                source, line, (void *)file);
+
+  return res;
+}
+
+#define LOGLINE_BUFSIZE  1024
+
+/* this does the writting to the memory tracking log file */
+void curl_memlog(const char *format, ...)
+{
+  char *buf;
+  int nchars;
+  va_list ap;
+
+  if(!logfile)
+    return;
+
+  buf = (Curl_cmalloc)(LOGLINE_BUFSIZE);
+  if(!buf)
+    return;
+
+  va_start(ap, format);
+  nchars = vsnprintf(buf, LOGLINE_BUFSIZE, format, ap);
+  va_end(ap);
+
+  if(nchars > LOGLINE_BUFSIZE - 1)
+    nchars = LOGLINE_BUFSIZE - 1;
+
+  if(nchars > 0)
+    fwrite(buf, 1, nchars, logfile);
+
+  (Curl_cfree)(buf);
+}
+
+#endif /* CURLDEBUG */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/memdebug.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/memdebug.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/memdebug.h	(revision 164)
@@ -0,0 +1,177 @@
+#ifndef HEADER_CURL_MEMDEBUG_H
+#define HEADER_CURL_MEMDEBUG_H
+#ifdef CURLDEBUG
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * CAUTION: this header is designed to work when included by the app-side
+ * as well as the library. Do not mix with library internals!
+ */
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#define CURL_MT_LOGFNAME_BUFSIZE 512
+
+#define logfile curl_debuglogfile
+
+extern FILE *logfile;
+
+/* memory functions */
+CURL_EXTERN void *curl_domalloc(size_t size, int line, const char *source);
+CURL_EXTERN void *curl_docalloc(size_t elements, size_t size, int line,
+                                const char *source);
+CURL_EXTERN void *curl_dorealloc(void *ptr, size_t size, int line,
+                                 const char *source);
+CURL_EXTERN void curl_dofree(void *ptr, int line, const char *source);
+CURL_EXTERN char *curl_dostrdup(const char *str, int line, const char *source);
+#if defined(WIN32) && defined(UNICODE)
+CURL_EXTERN wchar_t *curl_dowcsdup(const wchar_t *str, int line,
+                                   const char *source);
+#endif
+
+CURL_EXTERN void curl_memdebug(const char *logname);
+CURL_EXTERN void curl_memlimit(long limit);
+CURL_EXTERN void curl_memlog(const char *format, ...);
+
+/* file descriptor manipulators */
+CURL_EXTERN curl_socket_t curl_socket(int domain, int type, int protocol,
+                                      int line , const char *source);
+CURL_EXTERN void curl_mark_sclose(curl_socket_t sockfd,
+                                  int line , const char *source);
+CURL_EXTERN int curl_sclose(curl_socket_t sockfd,
+                            int line , const char *source);
+CURL_EXTERN curl_socket_t curl_accept(curl_socket_t s, void *a, void *alen,
+                                      int line, const char *source);
+#ifdef HAVE_SOCKETPAIR
+CURL_EXTERN int curl_socketpair(int domain, int type, int protocol,
+                                curl_socket_t socket_vector[2],
+                                int line , const char *source);
+#endif
+
+/* FILE functions */
+CURL_EXTERN FILE *curl_fopen(const char *file, const char *mode, int line,
+                             const char *source);
+#ifdef HAVE_FDOPEN
+CURL_EXTERN FILE *curl_fdopen(int filedes, const char *mode, int line,
+                              const char *source);
+#endif
+CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
+
+#ifndef MEMDEBUG_NODEFINES
+
+/* Set this symbol on the command-line, recompile all lib-sources */
+#undef strdup
+#define strdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
+#define malloc(size) curl_domalloc(size, __LINE__, __FILE__)
+#define calloc(nbelem,size) curl_docalloc(nbelem, size, __LINE__, __FILE__)
+#define realloc(ptr,size) curl_dorealloc(ptr, size, __LINE__, __FILE__)
+#define free(ptr) curl_dofree(ptr, __LINE__, __FILE__)
+
+#ifdef WIN32
+#  ifdef UNICODE
+#    undef wcsdup
+#    define wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
+#    undef _wcsdup
+#    define _wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
+#    undef _tcsdup
+#    define _tcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
+#  else
+#    undef _tcsdup
+#    define _tcsdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
+#  endif
+#endif
+
+#undef socket
+#define socket(domain,type,protocol)\
+ curl_socket(domain, type, protocol, __LINE__, __FILE__)
+#undef accept /* for those with accept as a macro */
+#define accept(sock,addr,len)\
+ curl_accept(sock, addr, len, __LINE__, __FILE__)
+#ifdef HAVE_SOCKETPAIR
+#define socketpair(domain,type,protocol,socket_vector)\
+ curl_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__)
+#endif
+
+#ifdef HAVE_GETADDRINFO
+#if defined(getaddrinfo) && defined(__osf__)
+/* OSF/1 and Tru64 have getaddrinfo as a define already, so we cannot define
+   our macro as for other platforms. Instead, we redefine the new name they
+   define getaddrinfo to become! */
+#define ogetaddrinfo(host,serv,hint,res) \
+  curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
+#else
+#undef getaddrinfo
+#define getaddrinfo(host,serv,hint,res) \
+  curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
+#endif
+#endif /* HAVE_GETADDRINFO */
+
+#ifdef HAVE_GETNAMEINFO
+#undef getnameinfo
+#define getnameinfo(sa,salen,host,hostlen,serv,servlen,flags) \
+  curl_dogetnameinfo(sa, salen, host, hostlen, serv, servlen, flags, \
+                     __LINE__, __FILE__)
+#endif /* HAVE_GETNAMEINFO */
+
+#ifdef HAVE_FREEADDRINFO
+#undef freeaddrinfo
+#define freeaddrinfo(data) \
+  curl_dofreeaddrinfo(data, __LINE__, __FILE__)
+#endif /* HAVE_FREEADDRINFO */
+
+/* sclose is probably already defined, redefine it! */
+#undef sclose
+#define sclose(sockfd) curl_sclose(sockfd,__LINE__,__FILE__)
+
+#define fake_sclose(sockfd) curl_mark_sclose(sockfd,__LINE__,__FILE__)
+
+#undef fopen
+#define fopen(file,mode) curl_fopen(file,mode,__LINE__,__FILE__)
+#undef fdopen
+#define fdopen(file,mode) curl_fdopen(file,mode,__LINE__,__FILE__)
+#define fclose(file) curl_fclose(file,__LINE__,__FILE__)
+
+#endif /* MEMDEBUG_NODEFINES */
+
+#endif /* CURLDEBUG */
+
+/*
+** Following section applies even when CURLDEBUG is not defined.
+*/
+
+#ifndef fake_sclose
+#define fake_sclose(x)  Curl_nop_stmt
+#endif
+
+/*
+ * Curl_safefree defined as a macro to allow MemoryTracking feature
+ * to log free() calls at same location where Curl_safefree is used.
+ * This macro also assigns NULL to given pointer when free'd.
+ */
+
+#define Curl_safefree(ptr) \
+  do { free((ptr)); (ptr) = NULL;} WHILE_FALSE
+
+#endif /* HEADER_CURL_MEMDEBUG_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/mprintf.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/mprintf.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/mprintf.c	(revision 164)
@@ -0,0 +1,1241 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1999 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ *
+ * Purpose:
+ *  A merge of Bjorn Reese's format() function and Daniel's dsprintf()
+ *  1.0. A full blooded printf() clone with full support for <num>$
+ *  everywhere (parameters, widths and precisions) including variabled
+ *  sized parameters (like doubles, long longs, long doubles and even
+ *  void * in 64-bit architectures).
+ *
+ * Current restrictions:
+ * - Max 128 parameters
+ * - No 'long double' support.
+ *
+ * If you ever want truly portable and good *printf() clones, the project that
+ * took on from here is named 'Trio' and you find more details on the trio web
+ * page at https://daniel.haxx.se/trio/
+ */
+
+#include "curl_setup.h"
+
+#if defined(DJGPP) && (DJGPP_MINOR < 4)
+#undef _MPRINTF_REPLACE /* don't use x_was_used() here */
+#endif
+
+#include <curl/mprintf.h>
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifndef SIZEOF_LONG_DOUBLE
+#define SIZEOF_LONG_DOUBLE 0
+#endif
+
+/*
+ * If SIZEOF_SIZE_T has not been defined, default to the size of long.
+ */
+
+#ifndef SIZEOF_SIZE_T
+#  define SIZEOF_SIZE_T CURL_SIZEOF_LONG
+#endif
+
+#ifdef HAVE_LONGLONG
+#  define LONG_LONG_TYPE long long
+#  define HAVE_LONG_LONG_TYPE
+#else
+#  if defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
+#    define LONG_LONG_TYPE __int64
+#    define HAVE_LONG_LONG_TYPE
+#  else
+#    undef LONG_LONG_TYPE
+#    undef HAVE_LONG_LONG_TYPE
+#  endif
+#endif
+
+/*
+ * Non-ANSI integer extensions
+ */
+
+#if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x520)) || \
+    (defined(__WATCOMC__) && defined(__386__)) || \
+    (defined(__POCC__) && defined(_MSC_VER)) || \
+    (defined(_WIN32_WCE)) || \
+    (defined(__MINGW32__)) || \
+    (defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64))
+#  define MP_HAVE_INT_EXTENSIONS
+#endif
+
+/*
+ * Max integer data types that mprintf.c is capable
+ */
+
+#ifdef HAVE_LONG_LONG_TYPE
+#  define mp_intmax_t LONG_LONG_TYPE
+#  define mp_uintmax_t unsigned LONG_LONG_TYPE
+#else
+#  define mp_intmax_t long
+#  define mp_uintmax_t unsigned long
+#endif
+
+#define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */
+#define MAX_PARAMETERS 128 /* lame static limit */
+
+#ifdef __AMIGA__
+# undef FORMAT_INT
+#endif
+
+/* Lower-case digits.  */
+static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+/* Upper-case digits.  */
+static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+#define OUTCHAR(x) \
+  do{ \
+    if(stream((unsigned char)(x), (FILE *)data) != -1) \
+      done++; \
+    else \
+     return done; /* return immediately on failure */ \
+  } WHILE_FALSE
+
+/* Data type to read from the arglist */
+typedef enum  {
+  FORMAT_UNKNOWN = 0,
+  FORMAT_STRING,
+  FORMAT_PTR,
+  FORMAT_INT,
+  FORMAT_INTPTR,
+  FORMAT_LONG,
+  FORMAT_LONGLONG,
+  FORMAT_DOUBLE,
+  FORMAT_LONGDOUBLE,
+  FORMAT_WIDTH /* For internal use */
+} FormatType;
+
+/* conversion and display flags */
+enum {
+  FLAGS_NEW        = 0,
+  FLAGS_SPACE      = 1<<0,
+  FLAGS_SHOWSIGN   = 1<<1,
+  FLAGS_LEFT       = 1<<2,
+  FLAGS_ALT        = 1<<3,
+  FLAGS_SHORT      = 1<<4,
+  FLAGS_LONG       = 1<<5,
+  FLAGS_LONGLONG   = 1<<6,
+  FLAGS_LONGDOUBLE = 1<<7,
+  FLAGS_PAD_NIL    = 1<<8,
+  FLAGS_UNSIGNED   = 1<<9,
+  FLAGS_OCTAL      = 1<<10,
+  FLAGS_HEX        = 1<<11,
+  FLAGS_UPPER      = 1<<12,
+  FLAGS_WIDTH      = 1<<13, /* '*' or '*<num>$' used */
+  FLAGS_WIDTHPARAM = 1<<14, /* width PARAMETER was specified */
+  FLAGS_PREC       = 1<<15, /* precision was specified */
+  FLAGS_PRECPARAM  = 1<<16, /* precision PARAMETER was specified */
+  FLAGS_CHAR       = 1<<17, /* %c story */
+  FLAGS_FLOATE     = 1<<18, /* %e or %E */
+  FLAGS_FLOATG     = 1<<19  /* %g or %G */
+};
+
+typedef struct {
+  FormatType type;
+  int flags;
+  long width;     /* width OR width parameter number */
+  long precision; /* precision OR precision parameter number */
+  union {
+    char *str;
+    void *ptr;
+    union {
+      mp_intmax_t as_signed;
+      mp_uintmax_t as_unsigned;
+    } num;
+    double dnum;
+  } data;
+} va_stack_t;
+
+struct nsprintf {
+  char *buffer;
+  size_t length;
+  size_t max;
+};
+
+struct asprintf {
+  char *buffer; /* allocated buffer */
+  size_t len;   /* length of string */
+  size_t alloc; /* length of alloc */
+  int fail;     /* (!= 0) if an alloc has failed and thus
+                   the output is not the complete data */
+};
+
+static long dprintf_DollarString(char *input, char **end)
+{
+  int number=0;
+  while(ISDIGIT(*input)) {
+    number *= 10;
+    number += *input-'0';
+    input++;
+  }
+  if(number && ('$'==*input++)) {
+    *end = input;
+    return number;
+  }
+  return 0;
+}
+
+static bool dprintf_IsQualifierNoDollar(const char *fmt)
+{
+#if defined(MP_HAVE_INT_EXTENSIONS)
+  if(!strncmp(fmt, "I32", 3) || !strncmp(fmt, "I64", 3)) {
+    return TRUE;
+  }
+#endif
+
+  switch(*fmt) {
+  case '-': case '+': case ' ': case '#': case '.':
+  case '0': case '1': case '2': case '3': case '4':
+  case '5': case '6': case '7': case '8': case '9':
+  case 'h': case 'l': case 'L': case 'z': case 'q':
+  case '*': case 'O':
+#if defined(MP_HAVE_INT_EXTENSIONS)
+  case 'I':
+#endif
+    return TRUE;
+
+  default:
+    return FALSE;
+  }
+}
+#if 0
+/******************************************************************
+ *
+ * Pass 1:
+ * Create an index with the type of each parameter entry and its
+ * value (may vary in size)
+ *
+ ******************************************************************/
+
+static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
+                          va_list arglist)
+{
+  char *fmt = (char *)format;
+  int param_num = 0;
+  long this_param;
+  long width;
+  long precision;
+  int flags;
+  long max_param=0;
+  long i;
+
+  while(*fmt) {
+    if(*fmt++ == '%') {
+      if(*fmt == '%') {
+        fmt++;
+        continue; /* while */
+      }
+
+      flags = FLAGS_NEW;
+
+      /* Handle the positional case (N$) */
+
+      param_num++;
+
+      this_param = dprintf_DollarString(fmt, &fmt);
+      if(0 == this_param)
+        /* we got no positional, get the next counter */
+        this_param = param_num;
+
+      if(this_param > max_param)
+        max_param = this_param;
+
+      /*
+       * The parameter with number 'i' should be used. Next, we need
+       * to get SIZE and TYPE of the parameter. Add the information
+       * to our array.
+       */
+
+      width = 0;
+      precision = 0;
+
+      /* Handle the flags */
+
+      while(dprintf_IsQualifierNoDollar(fmt)) {
+#if defined(MP_HAVE_INT_EXTENSIONS)
+        if(!strncmp(fmt, "I32", 3)) {
+          flags |= FLAGS_LONG;
+          fmt += 3;
+        }
+        else if(!strncmp(fmt, "I64", 3)) {
+          flags |= FLAGS_LONGLONG;
+          fmt += 3;
+        }
+        else
+#endif
+
+        switch(*fmt++) {
+        case ' ':
+          flags |= FLAGS_SPACE;
+          break;
+        case '+':
+          flags |= FLAGS_SHOWSIGN;
+          break;
+        case '-':
+          flags |= FLAGS_LEFT;
+          flags &= ~FLAGS_PAD_NIL;
+          break;
+        case '#':
+          flags |= FLAGS_ALT;
+          break;
+        case '.':
+          flags |= FLAGS_PREC;
+          if('*' == *fmt) {
+            /* The precision is picked from a specified parameter */
+
+            flags |= FLAGS_PRECPARAM;
+            fmt++;
+            param_num++;
+
+            i = dprintf_DollarString(fmt, &fmt);
+            if(i)
+              precision = i;
+            else
+              precision = param_num;
+
+            if(precision > max_param)
+              max_param = precision;
+          }
+          else {
+            flags |= FLAGS_PREC;
+            precision = strtol(fmt, &fmt, 10);
+          }
+          break;
+        case 'h':
+          flags |= FLAGS_SHORT;
+          break;
+#if defined(MP_HAVE_INT_EXTENSIONS)
+        case 'I':
+#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
+          flags |= FLAGS_LONGLONG;
+#else
+          flags |= FLAGS_LONG;
+#endif
+          break;
+#endif
+        case 'l':
+          if(flags & FLAGS_LONG)
+            flags |= FLAGS_LONGLONG;
+          else
+            flags |= FLAGS_LONG;
+          break;
+        case 'L':
+          flags |= FLAGS_LONGDOUBLE;
+          break;
+        case 'q':
+          flags |= FLAGS_LONGLONG;
+          break;
+        case 'z':
+          /* the code below generates a warning if -Wunreachable-code is
+             used */
+#if (SIZEOF_SIZE_T > CURL_SIZEOF_LONG)
+          flags |= FLAGS_LONGLONG;
+#else
+          flags |= FLAGS_LONG;
+#endif
+          break;
+        case 'O':
+#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
+          flags |= FLAGS_LONGLONG;
+#else
+          flags |= FLAGS_LONG;
+#endif
+          break;
+        case '0':
+          if(!(flags & FLAGS_LEFT))
+            flags |= FLAGS_PAD_NIL;
+          /* FALLTHROUGH */
+        case '1': case '2': case '3': case '4':
+        case '5': case '6': case '7': case '8': case '9':
+          flags |= FLAGS_WIDTH;
+          width = strtol(fmt-1, &fmt, 10);
+          break;
+        case '*':  /* Special case */
+          flags |= FLAGS_WIDTHPARAM;
+          param_num++;
+
+          i = dprintf_DollarString(fmt, &fmt);
+          if(i)
+            width = i;
+          else
+            width = param_num;
+          if(width > max_param)
+            max_param=width;
+          break;
+        default:
+          break;
+        }
+      } /* switch */
+
+      /* Handle the specifier */
+
+      i = this_param - 1;
+
+      switch (*fmt) {
+      case 'S':
+        flags |= FLAGS_ALT;
+        /* FALLTHROUGH */
+      case 's':
+        vto[i].type = FORMAT_STRING;
+        break;
+      case 'n':
+        vto[i].type = FORMAT_INTPTR;
+        break;
+      case 'p':
+        vto[i].type = FORMAT_PTR;
+        break;
+      case 'd': case 'i':
+        vto[i].type = FORMAT_INT;
+        break;
+      case 'u':
+        vto[i].type = FORMAT_INT;
+        flags |= FLAGS_UNSIGNED;
+        break;
+      case 'o':
+        vto[i].type = FORMAT_INT;
+        flags |= FLAGS_OCTAL;
+        break;
+      case 'x':
+        vto[i].type = FORMAT_INT;
+        flags |= FLAGS_HEX|FLAGS_UNSIGNED;
+        break;
+      case 'X':
+        vto[i].type = FORMAT_INT;
+        flags |= FLAGS_HEX|FLAGS_UPPER|FLAGS_UNSIGNED;
+        break;
+      case 'c':
+        vto[i].type = FORMAT_INT;
+        flags |= FLAGS_CHAR;
+        break;
+      case 'f':
+        vto[i].type = FORMAT_DOUBLE;
+        break;
+      case 'e':
+        vto[i].type = FORMAT_DOUBLE;
+        flags |= FLAGS_FLOATE;
+        break;
+      case 'E':
+        vto[i].type = FORMAT_DOUBLE;
+        flags |= FLAGS_FLOATE|FLAGS_UPPER;
+        break;
+      case 'g':
+        vto[i].type = FORMAT_DOUBLE;
+        flags |= FLAGS_FLOATG;
+        break;
+      case 'G':
+        vto[i].type = FORMAT_DOUBLE;
+        flags |= FLAGS_FLOATG|FLAGS_UPPER;
+        break;
+      default:
+        vto[i].type = FORMAT_UNKNOWN;
+        break;
+      } /* switch */
+
+      vto[i].flags = flags;
+      vto[i].width = width;
+      vto[i].precision = precision;
+
+      if(flags & FLAGS_WIDTHPARAM) {
+        /* we have the width specified from a parameter, so we make that
+           parameter's info setup properly */
+        vto[i].width = width - 1;
+        i = width - 1;
+        vto[i].type = FORMAT_WIDTH;
+        vto[i].flags = FLAGS_NEW;
+        vto[i].precision = vto[i].width = 0; /* can't use width or precision
+                                                of width! */
+      }
+      if(flags & FLAGS_PRECPARAM) {
+        /* we have the precision specified from a parameter, so we make that
+           parameter's info setup properly */
+        vto[i].precision = precision - 1;
+        i = precision - 1;
+        vto[i].type = FORMAT_WIDTH;
+        vto[i].flags = FLAGS_NEW;
+        vto[i].precision = vto[i].width = 0; /* can't use width or precision
+                                                of width! */
+      }
+      *endpos++ = fmt + 1; /* end of this sequence */
+    }
+  }
+
+  /* Read the arg list parameters into our data list */
+  for(i=0; i<max_param; i++) {
+    if((i + 1 < max_param) && (vto[i + 1].type == FORMAT_WIDTH)) {
+      /* Width/precision arguments must be read before the main argument
+       * they are attached to
+       */
+      vto[i + 1].data.num.as_signed = (mp_intmax_t)va_arg(arglist, int);
+    }
+
+    switch (vto[i].type) {
+    case FORMAT_STRING:
+      vto[i].data.str = va_arg(arglist, char *);
+      break;
+
+    case FORMAT_INTPTR:
+    case FORMAT_UNKNOWN:
+    case FORMAT_PTR:
+      vto[i].data.ptr = va_arg(arglist, void *);
+      break;
+
+    case FORMAT_INT:
+#ifdef HAVE_LONG_LONG_TYPE
+      if((vto[i].flags & FLAGS_LONGLONG) && (vto[i].flags & FLAGS_UNSIGNED))
+        vto[i].data.num.as_unsigned =
+          (mp_uintmax_t)va_arg(arglist, mp_uintmax_t);
+      else if(vto[i].flags & FLAGS_LONGLONG)
+        vto[i].data.num.as_signed =
+          (mp_intmax_t)va_arg(arglist, mp_intmax_t);
+      else
+#endif
+      {
+        if((vto[i].flags & FLAGS_LONG) && (vto[i].flags & FLAGS_UNSIGNED))
+          vto[i].data.num.as_unsigned =
+            (mp_uintmax_t)va_arg(arglist, unsigned long);
+        else if(vto[i].flags & FLAGS_LONG)
+          vto[i].data.num.as_signed =
+            (mp_intmax_t)va_arg(arglist, long);
+        else if(vto[i].flags & FLAGS_UNSIGNED)
+          vto[i].data.num.as_unsigned =
+            (mp_uintmax_t)va_arg(arglist, unsigned int);
+        else
+          vto[i].data.num.as_signed =
+            (mp_intmax_t)va_arg(arglist, int);
+      }
+      break;
+
+    case FORMAT_DOUBLE:
+      vto[i].data.dnum = va_arg(arglist, double);
+      break;
+
+    case FORMAT_WIDTH:
+      /* Argument has been read. Silently convert it into an integer
+       * for later use
+       */
+      vto[i].type = FORMAT_INT;
+      break;
+
+    default:
+      break;
+    }
+  }
+
+  return max_param;
+
+}
+
+static int dprintf_formatf(
+  void *data, /* untouched by format(), just sent to the stream() function in
+                 the second argument */
+  /* function pointer called for each output character */
+  int (*stream)(int, FILE *),
+  const char *format,    /* %-formatted string */
+  va_list ap_save) /* list of parameters */
+{
+  /* Base-36 digits for numbers.  */
+  const char *digits = lower_digits;
+
+  /* Pointer into the format string.  */
+  char *f;
+
+  /* Number of characters written.  */
+  int done = 0;
+
+  long param; /* current parameter to read */
+  long param_num=0; /* parameter counter */
+
+  va_stack_t vto[MAX_PARAMETERS];
+  char *endpos[MAX_PARAMETERS];
+  char **end;
+
+  char work[BUFFSIZE];
+
+  va_stack_t *p;
+
+  /* Do the actual %-code parsing */
+  dprintf_Pass1(format, vto, endpos, ap_save);
+
+  end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1()
+                       created for us */
+
+  f = (char *)format;
+  while(*f != '\0') {
+    /* Format spec modifiers.  */
+    int is_alt;
+
+    /* Width of a field.  */
+    long width;
+
+    /* Precision of a field.  */
+    long prec;
+
+    /* Decimal integer is negative.  */
+    int is_neg;
+
+    /* Base of a number to be written.  */
+    long base;
+
+    /* Integral values to be written.  */
+    mp_uintmax_t num;
+
+    /* Used to convert negative in positive.  */
+    mp_intmax_t signed_num;
+
+    if(*f != '%') {
+      /* This isn't a format spec, so write everything out until the next one
+         OR end of string is reached.  */
+      do {
+        OUTCHAR(*f);
+      } while(*++f && ('%' != *f));
+      continue;
+    }
+
+    ++f;
+
+    /* Check for "%%".  Note that although the ANSI standard lists
+       '%' as a conversion specifier, it says "The complete format
+       specification shall be `%%'," so we can avoid all the width
+       and precision processing.  */
+    if(*f == '%') {
+      ++f;
+      OUTCHAR('%');
+      continue;
+    }
+
+    /* If this is a positional parameter, the position must follow immediately
+       after the %, thus create a %<num>$ sequence */
+    param=dprintf_DollarString(f, &f);
+
+    if(!param)
+      param = param_num;
+    else
+      --param;
+
+    param_num++; /* increase this always to allow "%2$s %1$s %s" and then the
+                    third %s will pick the 3rd argument */
+
+    p = &vto[param];
+
+    /* pick up the specified width */
+    if(p->flags & FLAGS_WIDTHPARAM)
+      width = (long)vto[p->width].data.num.as_signed;
+    else
+      width = p->width;
+
+    /* pick up the specified precision */
+    if(p->flags & FLAGS_PRECPARAM) {
+      prec = (long)vto[p->precision].data.num.as_signed;
+      param_num++; /* since the precision is extraced from a parameter, we
+                      must skip that to get to the next one properly */
+    }
+    else if(p->flags & FLAGS_PREC)
+      prec = p->precision;
+    else
+      prec = -1;
+
+    is_alt = (p->flags & FLAGS_ALT) ? 1 : 0;
+
+    switch (p->type) {
+    case FORMAT_INT:
+      num = p->data.num.as_unsigned;
+      if(p->flags & FLAGS_CHAR) {
+        /* Character.  */
+        if(!(p->flags & FLAGS_LEFT))
+          while(--width > 0)
+            OUTCHAR(' ');
+        OUTCHAR((char) num);
+        if(p->flags & FLAGS_LEFT)
+          while(--width > 0)
+            OUTCHAR(' ');
+        break;
+      }
+      if(p->flags & FLAGS_OCTAL) {
+        /* Octal unsigned integer.  */
+        base = 8;
+        goto unsigned_number;
+      }
+      else if(p->flags & FLAGS_HEX) {
+        /* Hexadecimal unsigned integer.  */
+
+        digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
+        base = 16;
+        goto unsigned_number;
+      }
+      else if(p->flags & FLAGS_UNSIGNED) {
+        /* Decimal unsigned integer.  */
+        base = 10;
+        goto unsigned_number;
+      }
+
+      /* Decimal integer.  */
+      base = 10;
+
+      is_neg = (p->data.num.as_signed < (mp_intmax_t)0) ? 1 : 0;
+      if(is_neg) {
+        /* signed_num might fail to hold absolute negative minimum by 1 */
+        signed_num = p->data.num.as_signed + (mp_intmax_t)1;
+        signed_num = -signed_num;
+        num = (mp_uintmax_t)signed_num;
+        num += (mp_uintmax_t)1;
+      }
+
+      goto number;
+
+      unsigned_number:
+      /* Unsigned number of base BASE.  */
+      is_neg = 0;
+
+      number:
+      /* Number of base BASE.  */
+      {
+        char *workend = &work[sizeof(work) - 1];
+        char *w;
+
+        /* Supply a default precision if none was given.  */
+        if(prec == -1)
+          prec = 1;
+
+        /* Put the number in WORK.  */
+        w = workend;
+        while(num > 0) {
+          *w-- = digits[num % base];
+          num /= base;
+        }
+        width -= (long)(workend - w);
+        prec -= (long)(workend - w);
+
+        if(is_alt && base == 8 && prec <= 0) {
+          *w-- = '0';
+          --width;
+        }
+
+        if(prec > 0) {
+          width -= prec;
+          while(prec-- > 0)
+            *w-- = '0';
+        }
+
+        if(is_alt && base == 16)
+          width -= 2;
+
+        if(is_neg || (p->flags & FLAGS_SHOWSIGN) || (p->flags & FLAGS_SPACE))
+          --width;
+
+        if(!(p->flags & FLAGS_LEFT) && !(p->flags & FLAGS_PAD_NIL))
+          while(width-- > 0)
+            OUTCHAR(' ');
+
+        if(is_neg)
+          OUTCHAR('-');
+        else if(p->flags & FLAGS_SHOWSIGN)
+          OUTCHAR('+');
+        else if(p->flags & FLAGS_SPACE)
+          OUTCHAR(' ');
+
+        if(is_alt && base == 16) {
+          OUTCHAR('0');
+          if(p->flags & FLAGS_UPPER)
+            OUTCHAR('X');
+          else
+            OUTCHAR('x');
+        }
+
+        if(!(p->flags & FLAGS_LEFT) && (p->flags & FLAGS_PAD_NIL))
+          while(width-- > 0)
+            OUTCHAR('0');
+
+        /* Write the number.  */
+        while(++w <= workend) {
+          OUTCHAR(*w);
+        }
+
+        if(p->flags & FLAGS_LEFT)
+          while(width-- > 0)
+            OUTCHAR(' ');
+      }
+      break;
+
+    case FORMAT_STRING:
+            /* String.  */
+      {
+        static const char null[] = "(nil)";
+        const char *str;
+        size_t len;
+
+        str = (char *) p->data.str;
+        if(str == NULL) {
+          /* Write null[] if there's space.  */
+          if(prec == -1 || prec >= (long) sizeof(null) - 1) {
+            str = null;
+            len = sizeof(null) - 1;
+            /* Disable quotes around (nil) */
+            p->flags &= (~FLAGS_ALT);
+          }
+          else {
+            str = "";
+            len = 0;
+          }
+        }
+        else if(prec != -1)
+          len = (size_t)prec;
+        else
+          len = strlen(str);
+
+        width -= (long)len;
+
+        if(p->flags & FLAGS_ALT)
+          OUTCHAR('"');
+
+        if(!(p->flags&FLAGS_LEFT))
+          while(width-- > 0)
+            OUTCHAR(' ');
+
+        while((len-- > 0) && *str)
+          OUTCHAR(*str++);
+        if(p->flags&FLAGS_LEFT)
+          while(width-- > 0)
+            OUTCHAR(' ');
+
+        if(p->flags & FLAGS_ALT)
+          OUTCHAR('"');
+      }
+      break;
+
+    case FORMAT_PTR:
+      /* Generic pointer.  */
+      {
+        void *ptr;
+        ptr = (void *) p->data.ptr;
+        if(ptr != NULL) {
+          /* If the pointer is not NULL, write it as a %#x spec.  */
+          base = 16;
+          digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
+          is_alt = 1;
+          num = (size_t) ptr;
+          is_neg = 0;
+          goto number;
+        }
+        else {
+          /* Write "(nil)" for a nil pointer.  */
+          static const char strnil[] = "(nil)";
+          const char *point;
+
+          width -= (long)(sizeof(strnil) - 1);
+          if(p->flags & FLAGS_LEFT)
+            while(width-- > 0)
+              OUTCHAR(' ');
+          for(point = strnil; *point != '\0'; ++point)
+            OUTCHAR(*point);
+          if(! (p->flags & FLAGS_LEFT))
+            while(width-- > 0)
+              OUTCHAR(' ');
+        }
+      }
+      break;
+
+    case FORMAT_DOUBLE:
+      {
+        char formatbuf[32]="%";
+        char *fptr = &formatbuf[1];
+        size_t left = sizeof(formatbuf)-strlen(formatbuf);
+        int len;
+
+        width = -1;
+        if(p->flags & FLAGS_WIDTH)
+          width = p->width;
+        else if(p->flags & FLAGS_WIDTHPARAM)
+          width = (long)vto[p->width].data.num.as_signed;
+
+        prec = -1;
+        if(p->flags & FLAGS_PREC)
+          prec = p->precision;
+        else if(p->flags & FLAGS_PRECPARAM)
+          prec = (long)vto[p->precision].data.num.as_signed;
+
+        if(p->flags & FLAGS_LEFT)
+          *fptr++ = '-';
+        if(p->flags & FLAGS_SHOWSIGN)
+          *fptr++ = '+';
+        if(p->flags & FLAGS_SPACE)
+          *fptr++ = ' ';
+        if(p->flags & FLAGS_ALT)
+          *fptr++ = '#';
+
+        *fptr = 0;
+
+        if(width >= 0) {
+          /* RECURSIVE USAGE */
+          len = curl_msnprintf(fptr, left, "%ld", width);
+          fptr += len;
+          left -= len;
+        }
+        if(prec >= 0) {
+          /* RECURSIVE USAGE */
+          len = curl_msnprintf(fptr, left, ".%ld", prec);
+          fptr += len;
+        }
+        if(p->flags & FLAGS_LONG)
+          *fptr++ = 'l';
+
+        if(p->flags & FLAGS_FLOATE)
+          *fptr++ = (char)((p->flags & FLAGS_UPPER) ? 'E' : 'e');
+        else if(p->flags & FLAGS_FLOATG)
+          *fptr++ = (char)((p->flags & FLAGS_UPPER) ? 'G' : 'g');
+        else
+          *fptr++ = 'f';
+
+        *fptr = 0; /* and a final zero termination */
+
+        /* NOTE NOTE NOTE!! Not all sprintf implementations return number of
+           output characters */
+        (sprintf)(work, formatbuf, p->data.dnum);
+
+        for(fptr=work; *fptr; fptr++)
+          OUTCHAR(*fptr);
+      }
+      break;
+
+    case FORMAT_INTPTR:
+      /* Answer the count of characters written.  */
+#ifdef HAVE_LONG_LONG_TYPE
+      if(p->flags & FLAGS_LONGLONG)
+        *(LONG_LONG_TYPE *) p->data.ptr = (LONG_LONG_TYPE)done;
+      else
+#endif
+        if(p->flags & FLAGS_LONG)
+          *(long *) p->data.ptr = (long)done;
+      else if(!(p->flags & FLAGS_SHORT))
+        *(int *) p->data.ptr = (int)done;
+      else
+        *(short *) p->data.ptr = (short)done;
+      break;
+
+    default:
+      break;
+    }
+    f = *end++; /* goto end of %-code */
+
+  }
+  return done;
+}
+#else
+/*------------------------------------------------------------------------/
+/  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.
+/
+/-------------------------------------------------------------------------*/
+static int dprintf_formatf(
+	void *data,
+	int(*stream)(int, FILE *),
+	const char *fmt,
+	va_list arp)
+{
+	unsigned int r, i, j, w, f;
+	unsigned long v;
+	char s[16], c, d, *p;
+
+	/* Number of characters written.  */
+	int done = 0;
+
+	for (;;) {
+		c = *fmt++;					/* Get a char */
+		if (!c) break;				/* End of format? */
+		if (c != '%') {				/* Pass through it if not a % sequense */
+			OUTCHAR(c); continue;
+		}
+		f = 0;
+		c = *fmt++;					/* Get first char of the sequense */
+		if (c == '0') {				/* Flag: '0' padded */
+			f = 1; c = *fmt++;
+		}
+		else {
+			if (c == '-') {			/* Flag: left justified */
+				f = 2; c = *fmt++;
+			}
+		}
+		for (w = 0; c >= '0' && c <= '9'; c = *fmt++)	/* Minimum width */
+			w = w * 10 + c - '0';
+		if (c == 'l' || c == 'L') {	/* Prefix: Size is long int */
+			f |= 4; c = *fmt++;
+		}
+		else if (c == 'h') {	/* Prefix: Size is short int */
+			f |= 16; c = *fmt++;
+		}
+		if (!c) break;				/* End of format? */
+		d = c;
+		if (d >= 'a') d -= 0x20;
+		switch (d) {				/* Type is... */
+		case 'S':					/* String */
+			p = va_arg(arp, char*);
+			for (j = 0; p[j]; j++);
+			while (!(f & 2) && j++ < w) OUTCHAR(' ');
+			for (; *p; p++)
+				OUTCHAR(*p);
+			while (j++ < w) OUTCHAR(' ');
+			continue;
+		case 'C':					/* Character */
+			OUTCHAR((char)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 (passthrough) */
+			OUTCHAR(c); continue;
+		}
+
+		/* Get an argument and put it in numeral */
+		v = (f & 4) ? va_arg(arp, long)
+			: ((f & 16) ? ((d == 'D') ? (long)va_arg(arp, short) : (long)va_arg(arp, unsigned short))
+				: ((d == 'D') ? (long)va_arg(arp, int) : (long)va_arg(arp, unsigned int)));
+		if (d == 'D' && (v & 0x80000000)) {
+			v = 0 - v;
+			f |= 8;
+		}
+		i = 0;
+		do {
+			d = (char)(v % r); v /= r;
+			if (d > 9) d += (c == 'x') ? 0x27 : 0x07;
+			s[i++] = d + '0';
+		} while (v && i < sizeof(s));
+		if (f & 8) s[i++] = '-';
+		j = i; d = (f & 1) ? '0' : ' ';
+		while (!(f & 2) && j++ < w) OUTCHAR(d);
+		do OUTCHAR(s[--i]); while (i);
+		while (j++ < w) OUTCHAR(' ');
+	}
+	return done;
+}
+#endif
+/* fputc() look-alike */
+static int addbyter(int output, FILE *data)
+{
+  struct nsprintf *infop=(struct nsprintf *)data;
+  unsigned char outc = (unsigned char)output;
+
+  if(infop->length < infop->max) {
+    /* only do this if we haven't reached max length yet */
+    infop->buffer[0] = outc; /* store */
+    infop->buffer++; /* increase pointer */
+    infop->length++; /* we are now one byte larger */
+    return outc;     /* fputc() returns like this on success */
+  }
+  return -1;
+}
+
+int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format,
+                    va_list ap_save)
+{
+  int retcode;
+  struct nsprintf info;
+
+  info.buffer = buffer;
+  info.length = 0;
+  info.max = maxlength;
+
+  retcode = dprintf_formatf(&info, addbyter, format, ap_save);
+  if(info.max) {
+    /* we terminate this with a zero byte */
+    if(info.max == info.length)
+      /* we're at maximum, scrap the last letter */
+      info.buffer[-1] = 0;
+    else
+      info.buffer[0] = 0;
+  }
+  return retcode;
+}
+
+int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...)
+{
+  int retcode;
+  va_list ap_save; /* argument pointer */
+  va_start(ap_save, format);
+  retcode = curl_mvsnprintf(buffer, maxlength, format, ap_save);
+  va_end(ap_save);
+  return retcode;
+}
+
+/* fputc() look-alike */
+static int alloc_addbyter(int output, FILE *data)
+{
+  struct asprintf *infop=(struct asprintf *)data;
+  unsigned char outc = (unsigned char)output;
+
+  if(!infop->buffer) {
+    infop->buffer = malloc(32);
+    if(!infop->buffer) {
+      infop->fail = 1;
+      return -1; /* fail */
+    }
+    infop->alloc = 32;
+    infop->len =0;
+  }
+  else if(infop->len+1 >= infop->alloc) {
+    char *newptr;
+
+    newptr = realloc(infop->buffer, infop->alloc*2);
+
+    if(!newptr) {
+      infop->fail = 1;
+      return -1; /* fail */
+    }
+    infop->buffer = newptr;
+    infop->alloc *= 2;
+  }
+
+  infop->buffer[ infop->len ] = outc;
+
+  infop->len++;
+
+  return outc; /* fputc() returns like this on success */
+}
+
+char *curl_maprintf(const char *format, ...)
+{
+  va_list ap_save; /* argument pointer */
+  int retcode;
+  struct asprintf info;
+
+  info.buffer = NULL;
+  info.len = 0;
+  info.alloc = 0;
+  info.fail = 0;
+
+  va_start(ap_save, format);
+  retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
+  va_end(ap_save);
+  if((-1 == retcode) || info.fail) {
+    if(info.alloc)
+      free(info.buffer);
+    return NULL;
+  }
+  if(info.alloc) {
+    info.buffer[info.len] = 0; /* we terminate this with a zero byte */
+    return info.buffer;
+  }
+  else
+    return strdup("");
+}
+
+char *curl_mvaprintf(const char *format, va_list ap_save)
+{
+  int retcode;
+  struct asprintf info;
+
+  info.buffer = NULL;
+  info.len = 0;
+  info.alloc = 0;
+  info.fail = 0;
+
+  retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
+  if((-1 == retcode) || info.fail) {
+    if(info.alloc)
+      free(info.buffer);
+    return NULL;
+  }
+
+  if(info.alloc) {
+    info.buffer[info.len] = 0; /* we terminate this with a zero byte */
+    return info.buffer;
+  }
+  else
+    return strdup("");
+}
+
+static int storebuffer(int output, FILE *data)
+{
+  char **buffer = (char **)data;
+  unsigned char outc = (unsigned char)output;
+  **buffer = outc;
+  (*buffer)++;
+  return outc; /* act like fputc() ! */
+}
+
+int curl_msprintf(char *buffer, const char *format, ...)
+{
+  va_list ap_save; /* argument pointer */
+  int retcode;
+  va_start(ap_save, format);
+  retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save);
+  va_end(ap_save);
+  *buffer=0; /* we terminate this with a zero byte */
+  return retcode;
+}
+
+int curl_mprintf(const char *format, ...)
+{
+  int retcode;
+  va_list ap_save; /* argument pointer */
+  va_start(ap_save, format);
+
+  retcode = dprintf_formatf(stdout, fputc, format, ap_save);
+  va_end(ap_save);
+  return retcode;
+}
+
+int curl_mfprintf(FILE *whereto, const char *format, ...)
+{
+  int retcode;
+  va_list ap_save; /* argument pointer */
+  va_start(ap_save, format);
+  retcode = dprintf_formatf(whereto, fputc, format, ap_save);
+  va_end(ap_save);
+  return retcode;
+}
+
+int curl_mvsprintf(char *buffer, const char *format, va_list ap_save)
+{
+  int retcode;
+  retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save);
+  *buffer=0; /* we terminate this with a zero byte */
+  return retcode;
+}
+
+int curl_mvprintf(const char *format, va_list ap_save)
+{
+  return dprintf_formatf(stdout, fputc, format, ap_save);
+}
+
+int curl_mvfprintf(FILE *whereto, const char *format, va_list ap_save)
+{
+  return dprintf_formatf(whereto, fputc, format, ap_save);
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/multi.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/multi.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/multi.c	(revision 164)
@@ -0,0 +1,2837 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "transfer.h"
+#include "url.h"
+#include "connect.h"
+#include "progress.h"
+#include "easyif.h"
+#include "share.h"
+#include "multiif.h"
+#include "sendf.h"
+#include "timeval.h"
+#include "http.h"
+#include "select.h"
+#include "warnless.h"
+#include "speedcheck.h"
+#include "conncache.h"
+#include "multihandle.h"
+#include "pipeline.h"
+#include "sigpipe.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+  CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97
+  to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes.  Still, every
+  CURL handle takes 45-50 K memory, therefore this 3K are not significant.
+*/
+#ifndef CURL_SOCKET_HASH_TABLE_SIZE
+#define CURL_SOCKET_HASH_TABLE_SIZE 911
+#endif
+
+#define CURL_CONNECTION_HASH_SIZE 97
+
+#define CURL_MULTI_HANDLE 0x000bab1e
+
+#define GOOD_MULTI_HANDLE(x) \
+  ((x) && (((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE))
+
+static void singlesocket(struct Curl_multi *multi,
+                         struct SessionHandle *data);
+static int update_timer(struct Curl_multi *multi);
+
+static CURLMcode add_next_timeout(struct timeval now,
+                                  struct Curl_multi *multi,
+                                  struct SessionHandle *d);
+static CURLMcode multi_timeout(struct Curl_multi *multi,
+                               long *timeout_ms);
+
+#ifdef DEBUGBUILD
+static const char * const statename[]={
+  "INIT",
+  "CONNECT_PEND",
+  "CONNECT",
+  "WAITRESOLVE",
+  "WAITCONNECT",
+  "WAITPROXYCONNECT",
+  "SENDPROTOCONNECT",
+  "PROTOCONNECT",
+  "WAITDO",
+  "DO",
+  "DOING",
+  "DO_MORE",
+  "DO_DONE",
+  "WAITPERFORM",
+  "PERFORM",
+  "TOOFAST",
+  "DONE",
+  "COMPLETED",
+  "MSGSENT",
+};
+#endif
+
+static void multi_freetimeout(void *a, void *b);
+
+/* function pointer called once when switching TO a state */
+typedef void (*init_multistate_func)(struct SessionHandle *data);
+
+/* always use this function to change state, to make debugging easier */
+static void mstate(struct SessionHandle *data, CURLMstate state
+#ifdef DEBUGBUILD
+                   , int lineno
+#endif
+)
+{
+  CURLMstate oldstate = data->mstate;
+  static const init_multistate_func finit[CURLM_STATE_LAST] = {
+    NULL,
+    NULL,
+    Curl_init_CONNECT, /* CONNECT */
+    /* the rest is NULL too */
+  };
+
+#if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) lineno;
+#endif
+
+  if(oldstate == state)
+    /* don't bother when the new state is the same as the old state */
+    return;
+
+  data->mstate = state;
+
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  if(data->mstate >= CURLM_STATE_CONNECT_PEND &&
+     data->mstate < CURLM_STATE_COMPLETED) {
+    long connection_id = -5000;
+
+    if(data->easy_conn)
+      connection_id = data->easy_conn->connection_id;
+
+    infof(data,
+          "STATE: %s => %s handle %p; line %d (connection #%ld) \n",
+          statename[oldstate], statename[data->mstate],
+          (void *)data, lineno, connection_id);
+  }
+#endif
+
+  if(state == CURLM_STATE_COMPLETED)
+    /* changing to COMPLETED means there's one less easy handle 'alive' */
+    data->multi->num_alive--;
+
+  /* if this state has an init-function, run it */
+  if(finit[state])
+    finit[state](data);
+}
+
+#ifndef DEBUGBUILD
+#define multistate(x,y) mstate(x,y)
+#else
+#define multistate(x,y) mstate(x,y, __LINE__)
+#endif
+
+/*
+ * We add one of these structs to the sockhash for a particular socket
+ */
+
+struct Curl_sh_entry {
+  struct SessionHandle *easy;
+  int action;  /* what action READ/WRITE this socket waits for */
+  curl_socket_t socket; /* mainly to ease debugging */
+  void *socketp; /* settable by users with curl_multi_assign() */
+};
+/* bits for 'action' having no bits means this socket is not expecting any
+   action */
+#define SH_READ  1
+#define SH_WRITE 2
+
+/* make sure this socket is present in the hash for this handle */
+static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
+                                         curl_socket_t s,
+                                         struct SessionHandle *data)
+{
+  struct Curl_sh_entry *there =
+    Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
+  struct Curl_sh_entry *check;
+
+  if(there)
+    /* it is present, return fine */
+    return there;
+
+  /* not present, add it */
+  check = calloc(1, sizeof(struct Curl_sh_entry));
+  if(!check)
+    return NULL; /* major failure */
+
+  check->easy = data;
+  check->socket = s;
+
+  /* make/add new hash entry */
+  if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
+    free(check);
+    return NULL; /* major failure */
+  }
+
+  return check; /* things are good in sockhash land */
+}
+
+
+/* delete the given socket + handle from the hash */
+static void sh_delentry(struct curl_hash *sh, curl_socket_t s)
+{
+  struct Curl_sh_entry *there =
+    Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
+
+  if(there) {
+    /* this socket is in the hash */
+    /* We remove the hash entry. (This'll end up in a call to
+       sh_freeentry().) */
+    Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
+  }
+}
+
+/*
+ * free a sockhash entry
+ */
+static void sh_freeentry(void *freethis)
+{
+  struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis;
+
+  free(p);
+}
+
+static size_t fd_key_compare(void *k1, size_t k1_len, void *k2, size_t k2_len)
+{
+  (void) k1_len; (void) k2_len;
+
+  return (*((int *) k1)) == (*((int *) k2));
+}
+
+static size_t hash_fd(void *key, size_t key_length, size_t slots_num)
+{
+  int fd = *((int *) key);
+  (void) key_length;
+
+  return (fd % (int)slots_num);
+}
+
+/*
+ * sh_init() creates a new socket hash and returns the handle for it.
+ *
+ * Quote from README.multi_socket:
+ *
+ * "Some tests at 7000 and 9000 connections showed that the socket hash lookup
+ * is somewhat of a bottle neck. Its current implementation may be a bit too
+ * limiting. It simply has a fixed-size array, and on each entry in the array
+ * it has a linked list with entries. So the hash only checks which list to
+ * scan through. The code I had used so for used a list with merely 7 slots
+ * (as that is what the DNS hash uses) but with 7000 connections that would
+ * make an average of 1000 nodes in each list to run through. I upped that to
+ * 97 slots (I believe a prime is suitable) and noticed a significant speed
+ * increase.  I need to reconsider the hash implementation or use a rather
+ * large default value like this. At 9000 connections I was still below 10us
+ * per call."
+ *
+ */
+static int sh_init(struct curl_hash *hash, int hashsize)
+{
+  return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
+                        sh_freeentry);
+}
+
+/*
+ * multi_addmsg()
+ *
+ * Called when a transfer is completed. Adds the given msg pointer to
+ * the list kept in the multi handle.
+ */
+static CURLMcode multi_addmsg(struct Curl_multi *multi,
+                              struct Curl_message *msg)
+{
+  if(!Curl_llist_insert_next(multi->msglist, multi->msglist->tail, msg))
+    return CURLM_OUT_OF_MEMORY;
+
+  return CURLM_OK;
+}
+
+/*
+ * multi_freeamsg()
+ *
+ * Callback used by the llist system when a single list entry is destroyed.
+ */
+static void multi_freeamsg(void *a, void *b)
+{
+  (void)a;
+  (void)b;
+}
+
+struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
+                                     int chashsize) /* connection hash */
+{
+  struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi));
+
+  if(!multi)
+    return NULL;
+
+  multi->type = CURL_MULTI_HANDLE;
+
+  if(Curl_mk_dnscache(&multi->hostcache))
+    goto error;
+
+  if(sh_init(&multi->sockhash, hashsize))
+    goto error;
+
+  if(Curl_conncache_init(&multi->conn_cache, chashsize))
+    goto error;
+
+  multi->msglist = Curl_llist_alloc(multi_freeamsg);
+  if(!multi->msglist)
+    goto error;
+
+  multi->pending = Curl_llist_alloc(multi_freeamsg);
+  if(!multi->pending)
+    goto error;
+
+  /* allocate a new easy handle to use when closing cached connections */
+  multi->closure_handle = curl_easy_init();
+  if(!multi->closure_handle)
+    goto error;
+
+  multi->closure_handle->multi = multi;
+  multi->closure_handle->state.conn_cache = &multi->conn_cache;
+
+  multi->max_pipeline_length = 5;
+
+  /* -1 means it not set by user, use the default value */
+  multi->maxconnects = -1;
+  return (CURLM *) multi;
+
+  error:
+
+  Curl_hash_destroy(&multi->sockhash);
+  Curl_hash_destroy(&multi->hostcache);
+  Curl_conncache_destroy(&multi->conn_cache);
+  Curl_close(multi->closure_handle);
+  multi->closure_handle = NULL;
+  Curl_llist_destroy(multi->msglist, NULL);
+  Curl_llist_destroy(multi->pending, NULL);
+
+  free(multi);
+  return NULL;
+}
+
+CURLM *curl_multi_init(void)
+{
+  return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE,
+                           CURL_CONNECTION_HASH_SIZE);
+}
+
+CURLMcode curl_multi_add_handle(CURLM *multi_handle,
+                                CURL *easy_handle)
+{
+  struct curl_llist *timeoutlist;
+  struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
+  struct SessionHandle *data = (struct SessionHandle *)easy_handle;
+
+  /* First, make some basic checks that the CURLM handle is a good handle */
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+  /* Verify that we got a somewhat good easy handle too */
+  if(!GOOD_EASY_HANDLE(easy_handle))
+    return CURLM_BAD_EASY_HANDLE;
+
+  /* Prevent users from adding same easy handle more than once and prevent
+     adding to more than one multi stack */
+  if(data->multi)
+    return CURLM_ADDED_ALREADY;
+
+  /* Allocate and initialize timeout list for easy handle */
+  timeoutlist = Curl_llist_alloc(multi_freetimeout);
+  if(!timeoutlist)
+    return CURLM_OUT_OF_MEMORY;
+
+  /*
+   * No failure allowed in this function beyond this point. And no
+   * modification of easy nor multi handle allowed before this except for
+   * potential multi's connection cache growing which won't be undone in this
+   * function no matter what.
+   */
+
+  /* Make easy handle use timeout list initialized above */
+  data->state.timeoutlist = timeoutlist;
+  timeoutlist = NULL;
+
+  /* set the easy handle */
+  multistate(data, CURLM_STATE_INIT);
+
+  if((data->set.global_dns_cache) &&
+     (data->dns.hostcachetype != HCACHE_GLOBAL)) {
+    /* global dns cache was requested but still isn't */
+    struct curl_hash *global = Curl_global_host_cache_init();
+    if(global) {
+      /* only do this if the global cache init works */
+      data->dns.hostcache = global;
+      data->dns.hostcachetype = HCACHE_GLOBAL;
+    }
+  }
+  /* for multi interface connections, we share DNS cache automatically if the
+     easy handle's one is currently not set. */
+  else if(!data->dns.hostcache ||
+     (data->dns.hostcachetype == HCACHE_NONE)) {
+    data->dns.hostcache = &multi->hostcache;
+    data->dns.hostcachetype = HCACHE_MULTI;
+  }
+
+  /* Point to the multi's connection cache */
+  data->state.conn_cache = &multi->conn_cache;
+
+  /* This adds the new entry at the 'end' of the doubly-linked circular
+     list of SessionHandle structs to try and maintain a FIFO queue so
+     the pipelined requests are in order. */
+
+  /* We add this new entry last in the list. */
+
+  data->next = NULL; /* end of the line */
+  if(multi->easyp) {
+    struct SessionHandle *last = multi->easylp;
+    last->next = data;
+    data->prev = last;
+    multi->easylp = data; /* the new last node */
+  }
+  else {
+    /* first node, make prev NULL! */
+    data->prev = NULL;
+    multi->easylp = multi->easyp = data; /* both first and last */
+  }
+
+  /* make the SessionHandle refer back to this multi handle */
+  data->multi = multi_handle;
+
+  /* Set the timeout for this handle to expire really soon so that it will
+     be taken care of even when this handle is added in the midst of operation
+     when only the curl_multi_socket() API is used. During that flow, only
+     sockets that time-out or have actions will be dealt with. Since this
+     handle has no action yet, we make sure it times out to get things to
+     happen. */
+  Curl_expire(data, 1);
+
+  /* increase the node-counter */
+  multi->num_easy++;
+
+  /* increase the alive-counter */
+  multi->num_alive++;
+
+  /* A somewhat crude work-around for a little glitch in update_timer() that
+     happens if the lastcall time is set to the same time when the handle is
+     removed as when the next handle is added, as then the check in
+     update_timer() that prevents calling the application multiple times with
+     the same timer infor will not trigger and then the new handle's timeout
+     will not be notified to the app.
+
+     The work-around is thus simply to clear the 'lastcall' variable to force
+     update_timer() to always trigger a callback to the app when a new easy
+     handle is added */
+  memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
+
+  update_timer(multi);
+  return CURLM_OK;
+}
+
+#if 0
+/* Debug-function, used like this:
+ *
+ * Curl_hash_print(multi->sockhash, debug_print_sock_hash);
+ *
+ * Enable the hash print function first by editing hash.c
+ */
+static void debug_print_sock_hash(void *p)
+{
+  struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p;
+
+  fprintf(stderr, " [easy %p/magic %x/socket %d]",
+          (void *)sh->data, sh->data->magic, (int)sh->socket);
+}
+#endif
+
+CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
+                                   CURL *curl_handle)
+{
+  struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+  struct SessionHandle *easy = curl_handle;
+  struct SessionHandle *data = easy;
+  bool premature;
+  bool easy_owns_conn;
+  struct curl_llist_element *e;
+
+  /* First, make some basic checks that the CURLM handle is a good handle */
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+  /* Verify that we got a somewhat good easy handle too */
+  if(!GOOD_EASY_HANDLE(curl_handle))
+    return CURLM_BAD_EASY_HANDLE;
+
+  /* Prevent users from trying to remove same easy handle more than once */
+  if(!data->multi)
+    return CURLM_OK; /* it is already removed so let's say it is fine! */
+
+  premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE;
+  easy_owns_conn = (data->easy_conn && (data->easy_conn->data == easy)) ?
+    TRUE : FALSE;
+
+  /* If the 'state' is not INIT or COMPLETED, we might need to do something
+     nice to put the easy_handle in a good known state when this returns. */
+  if(premature) {
+    /* this handle is "alive" so we need to count down the total number of
+       alive connections when this is removed */
+    multi->num_alive--;
+
+    /* When this handle gets removed, other handles may be able to get the
+       connection */
+    Curl_multi_process_pending_handles(multi);
+  }
+
+  if(data->easy_conn &&
+     data->mstate > CURLM_STATE_DO &&
+     data->mstate < CURLM_STATE_COMPLETED) {
+    /* If the handle is in a pipeline and has started sending off its
+       request but not received its response yet, we need to close
+       connection. */
+    connclose(data->easy_conn, "Removed with partial response");
+    /* Set connection owner so that Curl_done() closes it.
+       We can safely do this here since connection is killed. */
+    data->easy_conn->data = easy;
+    easy_owns_conn = TRUE;
+  }
+
+  /* The timer must be shut down before data->multi is set to NULL,
+     else the timenode will remain in the splay tree after
+     curl_easy_cleanup is called. */
+  Curl_expire(data, 0);
+
+  /* destroy the timeout list that is held in the easy handle */
+  if(data->state.timeoutlist) {
+    Curl_llist_destroy(data->state.timeoutlist, NULL);
+    data->state.timeoutlist = NULL;
+  }
+
+  if(data->dns.hostcachetype == HCACHE_MULTI) {
+    /* stop using the multi handle's DNS cache */
+    data->dns.hostcache = NULL;
+    data->dns.hostcachetype = HCACHE_NONE;
+  }
+
+  if(data->easy_conn) {
+
+    /* we must call Curl_done() here (if we still "own it") so that we don't
+       leave a half-baked one around */
+    if(easy_owns_conn) {
+
+      /* Curl_done() clears the conn->data field to lose the association
+         between the easy handle and the connection
+
+         Note that this ignores the return code simply because there's
+         nothing really useful to do with it anyway! */
+      (void)Curl_done(&data->easy_conn, data->result, premature);
+    }
+    else
+      /* Clear connection pipelines, if Curl_done above was not called */
+      Curl_getoff_all_pipelines(data, data->easy_conn);
+  }
+
+  Curl_wildcard_dtor(&data->wildcard);
+
+  /* as this was using a shared connection cache we clear the pointer to that
+     since we're not part of that multi handle anymore */
+  data->state.conn_cache = NULL;
+
+  /* change state without using multistate(), only to make singlesocket() do
+     what we want */
+  data->mstate = CURLM_STATE_COMPLETED;
+  singlesocket(multi, easy); /* to let the application know what sockets that
+                                vanish with this handle */
+
+  /* Remove the association between the connection and the handle */
+  if(data->easy_conn) {
+    data->easy_conn->data = NULL;
+    data->easy_conn = NULL;
+  }
+
+  data->multi = NULL; /* clear the association to this multi handle */
+
+  /* make sure there's no pending message in the queue sent from this easy
+     handle */
+
+  for(e = multi->msglist->head; e; e = e->next) {
+    struct Curl_message *msg = e->ptr;
+
+    if(msg->extmsg.easy_handle == easy) {
+      Curl_llist_remove(multi->msglist, e, NULL);
+      /* there can only be one from this specific handle */
+      break;
+    }
+  }
+
+  /* make the previous node point to our next */
+  if(data->prev)
+    data->prev->next = data->next;
+  else
+    multi->easyp = data->next; /* point to first node */
+
+  /* make our next point to our previous node */
+  if(data->next)
+    data->next->prev = data->prev;
+  else
+    multi->easylp = data->prev; /* point to last node */
+
+  /* NOTE NOTE NOTE
+     We do not touch the easy handle here! */
+  multi->num_easy--; /* one less to care about now */
+
+  update_timer(multi);
+  return CURLM_OK;
+}
+
+/* Return TRUE if the application asked for a certain set of pipelining */
+bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits)
+{
+  return (multi && (multi->pipelining & bits)) ? TRUE : FALSE;
+}
+
+void Curl_multi_handlePipeBreak(struct SessionHandle *data)
+{
+  data->easy_conn = NULL;
+}
+
+static int waitconnect_getsock(struct connectdata *conn,
+                               curl_socket_t *sock,
+                               int numsocks)
+{
+  int i;
+  int s=0;
+  int rc=0;
+
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  for(i=0; i<2; i++) {
+    if(conn->tempsock[i] != CURL_SOCKET_BAD) {
+      sock[s] = conn->tempsock[i];
+      rc |= GETSOCK_WRITESOCK(s++);
+    }
+  }
+
+  return rc;
+}
+
+static int waitproxyconnect_getsock(struct connectdata *conn,
+                                    curl_socket_t *sock,
+                                    int numsocks)
+{
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  sock[0] = conn->sock[FIRSTSOCKET];
+
+  /* when we've sent a CONNECT to a proxy, we should rather wait for the
+     socket to become readable to be able to get the response headers */
+  if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
+    return GETSOCK_READSOCK(0);
+
+  return GETSOCK_WRITESOCK(0);
+}
+
+static int domore_getsock(struct connectdata *conn,
+                          curl_socket_t *socks,
+                          int numsocks)
+{
+  if(conn && conn->handler->domore_getsock)
+    return conn->handler->domore_getsock(conn, socks, numsocks);
+  return GETSOCK_BLANK;
+}
+
+/* returns bitmapped flags for this handle and its sockets */
+static int multi_getsock(struct SessionHandle *data,
+                         curl_socket_t *socks, /* points to numsocks number
+                                                  of sockets */
+                         int numsocks)
+{
+  /* If the pipe broke, or if there's no connection left for this easy handle,
+     then we MUST bail out now with no bitmask set. The no connection case can
+     happen when this is called from curl_multi_remove_handle() =>
+     singlesocket() => multi_getsock().
+  */
+  if(data->state.pipe_broke || !data->easy_conn)
+    return 0;
+
+  if(data->mstate > CURLM_STATE_CONNECT &&
+     data->mstate < CURLM_STATE_COMPLETED) {
+    /* Set up ownership correctly */
+    data->easy_conn->data = data;
+  }
+
+  switch(data->mstate) {
+  default:
+#if 0 /* switch back on these cases to get the compiler to check for all enums
+         to be present */
+  case CURLM_STATE_TOOFAST:  /* returns 0, so will not select. */
+  case CURLM_STATE_COMPLETED:
+  case CURLM_STATE_MSGSENT:
+  case CURLM_STATE_INIT:
+  case CURLM_STATE_CONNECT:
+  case CURLM_STATE_WAITDO:
+  case CURLM_STATE_DONE:
+  case CURLM_STATE_LAST:
+    /* this will get called with CURLM_STATE_COMPLETED when a handle is
+       removed */
+#endif
+    return 0;
+
+  case CURLM_STATE_WAITRESOLVE:
+    return Curl_resolver_getsock(data->easy_conn, socks, numsocks);
+
+  case CURLM_STATE_PROTOCONNECT:
+  case CURLM_STATE_SENDPROTOCONNECT:
+    return Curl_protocol_getsock(data->easy_conn, socks, numsocks);
+
+  case CURLM_STATE_DO:
+  case CURLM_STATE_DOING:
+    return Curl_doing_getsock(data->easy_conn, socks, numsocks);
+
+  case CURLM_STATE_WAITPROXYCONNECT:
+    return waitproxyconnect_getsock(data->easy_conn, socks, numsocks);
+
+  case CURLM_STATE_WAITCONNECT:
+    return waitconnect_getsock(data->easy_conn, socks, numsocks);
+
+  case CURLM_STATE_DO_MORE:
+    return domore_getsock(data->easy_conn, socks, numsocks);
+
+  case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch
+                               to waiting for the same as the *PERFORM
+                               states */
+  case CURLM_STATE_PERFORM:
+  case CURLM_STATE_WAITPERFORM:
+    return Curl_single_getsock(data->easy_conn, socks, numsocks);
+  }
+
+}
+
+CURLMcode curl_multi_fdset(CURLM *multi_handle,
+                           fd_set *read_fd_set, fd_set *write_fd_set,
+                           fd_set *exc_fd_set, int *max_fd)
+{
+  /* Scan through all the easy handles to get the file descriptors set.
+     Some easy handles may not have connected to the remote host yet,
+     and then we must make sure that is done. */
+  struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+  struct SessionHandle *data;
+  int this_max_fd=-1;
+  curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
+  int bitmap;
+  int i;
+  (void)exc_fd_set; /* not used */
+
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+  data=multi->easyp;
+  while(data) {
+    bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+
+    for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
+      curl_socket_t s = CURL_SOCKET_BAD;
+
+      if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
+        FD_SET(sockbunch[i], read_fd_set);
+        s = sockbunch[i];
+      }
+      if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
+        FD_SET(sockbunch[i], write_fd_set);
+        s = sockbunch[i];
+      }
+      if(s == CURL_SOCKET_BAD)
+        /* this socket is unused, break out of loop */
+        break;
+      else {
+        if((int)s > this_max_fd)
+          this_max_fd = (int)s;
+      }
+    }
+
+    data = data->next; /* check next handle */
+  }
+
+  *max_fd = this_max_fd;
+
+  return CURLM_OK;
+}
+
+CURLMcode curl_multi_wait(CURLM *multi_handle,
+                          struct curl_waitfd extra_fds[],
+                          unsigned int extra_nfds,
+                          int timeout_ms,
+                          int *ret)
+{
+  struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+  struct SessionHandle *data;
+  curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
+  int bitmap;
+  unsigned int i;
+  unsigned int nfds = 0;
+  unsigned int curlfds;
+  struct pollfd *ufds = NULL;
+  long timeout_internal;
+
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+  /* If the internally desired timeout is actually shorter than requested from
+     the outside, then use the shorter time! But only if the internal timer
+     is actually larger than -1! */
+  (void)multi_timeout(multi, &timeout_internal);
+  if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms))
+    timeout_ms = (int)timeout_internal;
+
+  /* Count up how many fds we have from the multi handle */
+  data=multi->easyp;
+  while(data) {
+    bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+
+    for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
+      curl_socket_t s = CURL_SOCKET_BAD;
+
+      if(bitmap & GETSOCK_READSOCK(i)) {
+        ++nfds;
+        s = sockbunch[i];
+      }
+      if(bitmap & GETSOCK_WRITESOCK(i)) {
+        ++nfds;
+        s = sockbunch[i];
+      }
+      if(s == CURL_SOCKET_BAD) {
+        break;
+      }
+    }
+
+    data = data->next; /* check next handle */
+  }
+
+  curlfds = nfds; /* number of internal file descriptors */
+  nfds += extra_nfds; /* add the externally provided ones */
+
+  if(nfds || extra_nfds) {
+    ufds = malloc(nfds * sizeof(struct pollfd));
+    if(!ufds)
+      return CURLM_OUT_OF_MEMORY;
+  }
+  nfds = 0;
+
+  /* only do the second loop if we found descriptors in the first stage run
+     above */
+
+  if(curlfds) {
+    /* Add the curl handles to our pollfds first */
+    data=multi->easyp;
+    while(data) {
+      bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+
+      for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
+        curl_socket_t s = CURL_SOCKET_BAD;
+
+        if(bitmap & GETSOCK_READSOCK(i)) {
+          ufds[nfds].fd = sockbunch[i];
+          ufds[nfds].events = POLLIN;
+          ++nfds;
+          s = sockbunch[i];
+        }
+        if(bitmap & GETSOCK_WRITESOCK(i)) {
+          ufds[nfds].fd = sockbunch[i];
+          ufds[nfds].events = POLLOUT;
+          ++nfds;
+          s = sockbunch[i];
+        }
+        if(s == CURL_SOCKET_BAD) {
+          break;
+        }
+      }
+
+      data = data->next; /* check next handle */
+    }
+  }
+
+  /* Add external file descriptions from poll-like struct curl_waitfd */
+  for(i = 0; i < extra_nfds; i++) {
+    ufds[nfds].fd = extra_fds[i].fd;
+    ufds[nfds].events = 0;
+    if(extra_fds[i].events & CURL_WAIT_POLLIN)
+      ufds[nfds].events |= POLLIN;
+    if(extra_fds[i].events & CURL_WAIT_POLLPRI)
+      ufds[nfds].events |= POLLPRI;
+    if(extra_fds[i].events & CURL_WAIT_POLLOUT)
+      ufds[nfds].events |= POLLOUT;
+    ++nfds;
+  }
+
+  if(nfds) {
+    /* wait... */
+    infof(data, "Curl_poll(%d ds, %d ms)\n", nfds, timeout_ms);
+    i = Curl_poll(ufds, nfds, timeout_ms);
+
+    if(i) {
+      unsigned int j;
+      /* copy revents results from the poll to the curl_multi_wait poll
+         struct, the bit values of the actual underlying poll() implementation
+         may not be the same as the ones in the public libcurl API! */
+      for(j = 0; j < extra_nfds; j++) {
+        unsigned short mask = 0;
+        unsigned r = ufds[curlfds + j].revents;
+
+        if(r & POLLIN)
+          mask |= CURL_WAIT_POLLIN;
+        if(r & POLLOUT)
+          mask |= CURL_WAIT_POLLOUT;
+        if(r & POLLPRI)
+          mask |= CURL_WAIT_POLLPRI;
+
+        extra_fds[j].revents = mask;
+      }
+    }
+  }
+  else
+    i = 0;
+
+  free(ufds);
+  if(ret)
+    *ret = i;
+  return CURLM_OK;
+}
+
+/*
+ * Curl_multi_connchanged() is called to tell that there is a connection in
+ * this multi handle that has changed state (pipelining become possible, the
+ * number of allowed streams changed or similar), and a subsequent use of this
+ * multi handle should move CONNECT_PEND handles back to CONNECT to have them
+ * retry.
+ */
+void Curl_multi_connchanged(struct Curl_multi *multi)
+{
+  multi->recheckstate = TRUE;
+}
+
+/*
+ * multi_ischanged() is called
+ *
+ * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND
+ * => CONNECT action.
+ *
+ * Set 'clear' to TRUE to have it also clear the state variable.
+ */
+static bool multi_ischanged(struct Curl_multi *multi, bool clear)
+{
+  bool retval = multi->recheckstate;
+  if(clear)
+    multi->recheckstate = FALSE;
+  return retval;
+}
+
+CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
+                                 struct SessionHandle *data,
+                                 struct connectdata *conn)
+{
+  CURLMcode rc;
+
+  rc = curl_multi_add_handle(multi, data);
+  if(!rc) {
+    struct SingleRequest *k = &data->req;
+
+    /* pass in NULL for 'conn' here since we don't want to init the
+       connection, only this transfer */
+    Curl_init_do(data, NULL);
+
+    /* take this handle to the perform state right away */
+    multistate(data, CURLM_STATE_PERFORM);
+    data->easy_conn = conn;
+    k->keepon |= KEEP_RECV; /* setup to receive! */
+  }
+  return rc;
+}
+
+static CURLMcode multi_runsingle(struct Curl_multi *multi,
+                                 struct timeval now,
+                                 struct SessionHandle *data)
+{
+  struct Curl_message *msg = NULL;
+  bool connected;
+  bool async;
+  bool protocol_connect = FALSE;
+  bool dophase_done = FALSE;
+  bool done = FALSE;
+  CURLMcode rc;
+  CURLcode result = CURLE_OK;
+  struct SingleRequest *k;
+  long timeout_ms;
+  int control;
+
+  if(!GOOD_EASY_HANDLE(data))
+    return CURLM_BAD_EASY_HANDLE;
+
+  do {
+    bool disconnect_conn = FALSE;
+    rc = CURLM_OK;
+
+    /* Handle the case when the pipe breaks, i.e., the connection
+       we're using gets cleaned up and we're left with nothing. */
+    if(data->state.pipe_broke) {
+      infof(data, "Pipe broke: handle %p, url = %s\n",
+            (void *)data, data->state.path);
+
+      if(data->mstate < CURLM_STATE_COMPLETED) {
+        /* Head back to the CONNECT state */
+        multistate(data, CURLM_STATE_CONNECT);
+        rc = CURLM_CALL_MULTI_PERFORM;
+        result = CURLE_OK;
+      }
+
+      data->state.pipe_broke = FALSE;
+      data->easy_conn = NULL;
+      continue;
+    }
+
+    if(!data->easy_conn &&
+       data->mstate > CURLM_STATE_CONNECT &&
+       data->mstate < CURLM_STATE_DONE) {
+      /* In all these states, the code will blindly access 'data->easy_conn'
+         so this is precaution that it isn't NULL. And it silences static
+         analyzers. */
+      failf(data, "In state %d with no easy_conn, bail out!\n", data->mstate);
+      return CURLM_INTERNAL_ERROR;
+    }
+
+    if(multi_ischanged(multi, TRUE)) {
+      DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n"));
+      Curl_multi_process_pending_handles(multi);
+    }
+
+    if(data->easy_conn && data->mstate > CURLM_STATE_CONNECT &&
+       data->mstate < CURLM_STATE_COMPLETED)
+      /* Make sure we set the connection's current owner */
+      data->easy_conn->data = data;
+
+    if(data->easy_conn &&
+       (data->mstate >= CURLM_STATE_CONNECT) &&
+       (data->mstate < CURLM_STATE_COMPLETED)) {
+      /* we need to wait for the connect state as only then is the start time
+         stored, but we must not check already completed handles */
+
+      timeout_ms = Curl_timeleft(data, &now,
+                                 (data->mstate <= CURLM_STATE_WAITDO)?
+                                 TRUE:FALSE);
+
+      if(timeout_ms < 0) {
+        /* Handle timed out */
+        if(data->mstate == CURLM_STATE_WAITRESOLVE)
+          failf(data, "Resolving timed out after %ld milliseconds",
+                Curl_tvdiff(now, data->progress.t_startsingle));
+        else if(data->mstate == CURLM_STATE_WAITCONNECT)
+          failf(data, "Connection timed out after %ld milliseconds",
+                Curl_tvdiff(now, data->progress.t_startsingle));
+        else {
+          k = &data->req;
+          if(k->size != -1) {
+            failf(data, "Operation timed out after %ld milliseconds with %"
+                  CURL_FORMAT_CURL_OFF_T " out of %"
+                  CURL_FORMAT_CURL_OFF_T " bytes received",
+                  Curl_tvdiff(k->now, data->progress.t_startsingle),
+                  k->bytecount, k->size);
+          }
+          else {
+            failf(data, "Operation timed out after %ld milliseconds with %"
+                  CURL_FORMAT_CURL_OFF_T " bytes received",
+                  Curl_tvdiff(now, data->progress.t_startsingle),
+                  k->bytecount);
+          }
+        }
+
+        /* Force connection closed if the connection has indeed been used */
+        if(data->mstate > CURLM_STATE_DO) {
+          connclose(data->easy_conn, "Disconnected with pending data");
+          disconnect_conn = TRUE;
+        }
+        result = CURLE_OPERATION_TIMEDOUT;
+        (void)Curl_done(&data->easy_conn, result, TRUE);
+        /* Skip the statemachine and go directly to error handling section. */
+        goto statemachine_end;
+      }
+    }
+
+    switch(data->mstate) {
+    case CURLM_STATE_INIT:
+      /* init this transfer. */
+      result=Curl_pretransfer(data);
+
+      if(!result) {
+        /* after init, go CONNECT */
+        multistate(data, CURLM_STATE_CONNECT);
+        Curl_pgrsTime(data, TIMER_STARTOP);
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+      break;
+
+    case CURLM_STATE_CONNECT_PEND:
+      /* We will stay here until there is a connection available. Then
+         we try again in the CURLM_STATE_CONNECT state. */
+      break;
+
+    case CURLM_STATE_CONNECT:
+      /* Connect. We want to get a connection identifier filled in. */
+      Curl_pgrsTime(data, TIMER_STARTSINGLE);
+      result = Curl_connect(data, &data->easy_conn,
+                            &async, &protocol_connect);
+      if(CURLE_NO_CONNECTION_AVAILABLE == result) {
+        /* There was no connection available. We will go to the pending
+           state and wait for an available connection. */
+        multistate(data, CURLM_STATE_CONNECT_PEND);
+
+        /* add this handle to the list of connect-pending handles */
+        if(!Curl_llist_insert_next(multi->pending, multi->pending->tail, data))
+          result = CURLE_OUT_OF_MEMORY;
+        else
+          result = CURLE_OK;
+        break;
+      }
+
+      if(!result) {
+        /* Add this handle to the send or pend pipeline */
+        result = Curl_add_handle_to_pipeline(data, data->easy_conn);
+        if(result)
+          disconnect_conn = TRUE;
+        else {
+          if(async)
+            /* We're now waiting for an asynchronous name lookup */
+            multistate(data, CURLM_STATE_WAITRESOLVE);
+          else {
+            /* after the connect has been sent off, go WAITCONNECT unless the
+               protocol connect is already done and we can go directly to
+               WAITDO or DO! */
+            rc = CURLM_CALL_MULTI_PERFORM;
+
+            if(protocol_connect)
+              multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
+                         CURLM_STATE_WAITDO:CURLM_STATE_DO);
+            else {
+#ifndef CURL_DISABLE_HTTP
+              if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
+                multistate(data, CURLM_STATE_WAITPROXYCONNECT);
+              else
+#endif
+                multistate(data, CURLM_STATE_WAITCONNECT);
+            }
+          }
+        }
+      }
+      break;
+
+    case CURLM_STATE_WAITRESOLVE:
+      /* awaiting an asynch name resolve to complete */
+    {
+      struct Curl_dns_entry *dns = NULL;
+      struct connectdata *conn = data->easy_conn;
+
+      /* check if we have the name resolved by now */
+      dns = Curl_fetch_addr(conn, conn->host.name, (int)conn->port);
+
+      if(dns) {
+#ifdef CURLRES_ASYNCH
+        conn->async.dns = dns;
+        conn->async.done = TRUE;
+#endif
+        result = CURLE_OK;
+        infof(data, "Hostname was found in DNS cache\n");
+      }
+
+      if(!dns)
+        result = Curl_resolver_is_resolved(data->easy_conn, &dns);
+
+      /* Update sockets here, because the socket(s) may have been
+         closed and the application thus needs to be told, even if it
+         is likely that the same socket(s) will again be used further
+         down.  If the name has not yet been resolved, it is likely
+         that new sockets have been opened in an attempt to contact
+         another resolver. */
+      singlesocket(multi, data);
+
+      if(dns) {
+        /* Perform the next step in the connection phase, and then move on
+           to the WAITCONNECT state */
+        result = Curl_async_resolved(data->easy_conn, &protocol_connect);
+
+        if(result)
+          /* if Curl_async_resolved() returns failure, the connection struct
+             is already freed and gone */
+          data->easy_conn = NULL;           /* no more connection */
+        else {
+          /* call again please so that we get the next socket setup */
+          rc = CURLM_CALL_MULTI_PERFORM;
+          if(protocol_connect)
+            multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
+                       CURLM_STATE_WAITDO:CURLM_STATE_DO);
+          else {
+#ifndef CURL_DISABLE_HTTP
+            if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
+              multistate(data, CURLM_STATE_WAITPROXYCONNECT);
+            else
+#endif
+              multistate(data, CURLM_STATE_WAITCONNECT);
+          }
+        }
+      }
+
+      if(result) {
+        /* failure detected */
+        disconnect_conn = TRUE;
+        break;
+      }
+    }
+    break;
+
+#ifndef CURL_DISABLE_HTTP
+    case CURLM_STATE_WAITPROXYCONNECT:
+      /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
+      result = Curl_http_connect(data->easy_conn, &protocol_connect);
+
+      rc = CURLM_CALL_MULTI_PERFORM;
+      if(data->easy_conn->bits.proxy_connect_closed) {
+        /* connect back to proxy again */
+        result = CURLE_OK;
+        Curl_done(&data->easy_conn, CURLE_OK, FALSE);
+        multistate(data, CURLM_STATE_CONNECT);
+      }
+      else if(!result) {
+        if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_COMPLETE)
+          /* initiate protocol connect phase */
+          multistate(data, CURLM_STATE_SENDPROTOCONNECT);
+      }
+      break;
+#endif
+
+    case CURLM_STATE_WAITCONNECT:
+      /* awaiting a completion of an asynch TCP connect */
+      result = Curl_is_connected(data->easy_conn, FIRSTSOCKET, &connected);
+      if(connected && !result) {
+        rc = CURLM_CALL_MULTI_PERFORM;
+        multistate(data, data->easy_conn->bits.tunnel_proxy?
+                   CURLM_STATE_WAITPROXYCONNECT:
+                   CURLM_STATE_SENDPROTOCONNECT);
+      }
+      else if(result) {
+        /* failure detected */
+        /* Just break, the cleaning up is handled all in one place */
+        disconnect_conn = TRUE;
+        break;
+      }
+      break;
+
+    case CURLM_STATE_SENDPROTOCONNECT:
+      result = Curl_protocol_connect(data->easy_conn, &protocol_connect);
+      if(!protocol_connect)
+        /* switch to waiting state */
+        multistate(data, CURLM_STATE_PROTOCONNECT);
+      else if(!result) {
+        /* protocol connect has completed, go WAITDO or DO */
+        multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
+                   CURLM_STATE_WAITDO:CURLM_STATE_DO);
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+      else if(result) {
+        /* failure detected */
+        Curl_posttransfer(data);
+        Curl_done(&data->easy_conn, result, TRUE);
+        disconnect_conn = TRUE;
+      }
+      break;
+
+    case CURLM_STATE_PROTOCONNECT:
+      /* protocol-specific connect phase */
+      result = Curl_protocol_connecting(data->easy_conn, &protocol_connect);
+      if(!result && protocol_connect) {
+        /* after the connect has completed, go WAITDO or DO */
+        multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
+                   CURLM_STATE_WAITDO:CURLM_STATE_DO);
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+      else if(result) {
+        /* failure detected */
+        Curl_posttransfer(data);
+        Curl_done(&data->easy_conn, result, TRUE);
+        disconnect_conn = TRUE;
+      }
+      break;
+
+    case CURLM_STATE_WAITDO:
+      /* Wait for our turn to DO when we're pipelining requests */
+      if(Curl_pipeline_checkget_write(data, data->easy_conn)) {
+        /* Grabbed the channel */
+        multistate(data, CURLM_STATE_DO);
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+      break;
+
+    case CURLM_STATE_DO:
+      if(data->set.connect_only) {
+        /* keep connection open for application to use the socket */
+        connkeep(data->easy_conn, "CONNECT_ONLY");
+        multistate(data, CURLM_STATE_DONE);
+        result = CURLE_OK;
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+      else {
+        /* Perform the protocol's DO action */
+        result = Curl_do(&data->easy_conn, &dophase_done);
+
+        /* When Curl_do() returns failure, data->easy_conn might be NULL! */
+
+        if(!result) {
+          if(!dophase_done) {
+            /* some steps needed for wildcard matching */
+            if(data->set.wildcardmatch) {
+              struct WildcardData *wc = &data->wildcard;
+              if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
+                /* skip some states if it is important */
+                Curl_done(&data->easy_conn, CURLE_OK, FALSE);
+                multistate(data, CURLM_STATE_DONE);
+                rc = CURLM_CALL_MULTI_PERFORM;
+                break;
+              }
+            }
+            /* DO was not completed in one function call, we must continue
+               DOING... */
+            multistate(data, CURLM_STATE_DOING);
+            rc = CURLM_OK;
+          }
+
+          /* after DO, go DO_DONE... or DO_MORE */
+          else if(data->easy_conn->bits.do_more) {
+            /* we're supposed to do more, but we need to sit down, relax
+               and wait a little while first */
+            multistate(data, CURLM_STATE_DO_MORE);
+            rc = CURLM_OK;
+          }
+          else {
+            /* we're done with the DO, now DO_DONE */
+            multistate(data, CURLM_STATE_DO_DONE);
+            rc = CURLM_CALL_MULTI_PERFORM;
+          }
+        }
+        else if((CURLE_SEND_ERROR == result) &&
+                data->easy_conn->bits.reuse) {
+          /*
+           * In this situation, a connection that we were trying to use
+           * may have unexpectedly died.  If possible, send the connection
+           * back to the CONNECT phase so we can try again.
+           */
+          char *newurl = NULL;
+          followtype follow=FOLLOW_NONE;
+          CURLcode drc;
+          bool retry = FALSE;
+
+          drc = Curl_retry_request(data->easy_conn, &newurl);
+          if(drc) {
+            /* a failure here pretty much implies an out of memory */
+            result = drc;
+            disconnect_conn = TRUE;
+          }
+          else
+            retry = (newurl)?TRUE:FALSE;
+
+          Curl_posttransfer(data);
+          drc = Curl_done(&data->easy_conn, result, FALSE);
+
+          /* When set to retry the connection, we must to go back to
+           * the CONNECT state */
+          if(retry) {
+            if(!drc || (drc == CURLE_SEND_ERROR)) {
+              follow = FOLLOW_RETRY;
+              drc = Curl_follow(data, newurl, follow);
+              if(!drc) {
+                multistate(data, CURLM_STATE_CONNECT);
+                rc = CURLM_CALL_MULTI_PERFORM;
+                result = CURLE_OK;
+              }
+              else {
+                /* Follow failed */
+                result = drc;
+                free(newurl);
+              }
+            }
+            else {
+              /* done didn't return OK or SEND_ERROR */
+              result = drc;
+              free(newurl);
+            }
+          }
+          else {
+            /* Have error handler disconnect conn if we can't retry */
+            disconnect_conn = TRUE;
+            free(newurl);
+          }
+        }
+        else {
+          /* failure detected */
+          Curl_posttransfer(data);
+          if(data->easy_conn)
+            Curl_done(&data->easy_conn, result, FALSE);
+          disconnect_conn = TRUE;
+        }
+      }
+      break;
+
+    case CURLM_STATE_DOING:
+      /* we continue DOING until the DO phase is complete */
+      result = Curl_protocol_doing(data->easy_conn,
+                                   &dophase_done);
+      if(!result) {
+        if(dophase_done) {
+          /* after DO, go DO_DONE or DO_MORE */
+          multistate(data, data->easy_conn->bits.do_more?
+                     CURLM_STATE_DO_MORE:
+                     CURLM_STATE_DO_DONE);
+          rc = CURLM_CALL_MULTI_PERFORM;
+        } /* dophase_done */
+      }
+      else {
+        /* failure detected */
+        Curl_posttransfer(data);
+        Curl_done(&data->easy_conn, result, FALSE);
+        disconnect_conn = TRUE;
+      }
+      break;
+
+    case CURLM_STATE_DO_MORE:
+      /*
+       * When we are connected, DO MORE and then go DO_DONE
+       */
+      result = Curl_do_more(data->easy_conn, &control);
+
+      /* No need to remove this handle from the send pipeline here since that
+         is done in Curl_done() */
+      if(!result) {
+        if(control) {
+          /* if positive, advance to DO_DONE
+             if negative, go back to DOING */
+          multistate(data, control==1?
+                     CURLM_STATE_DO_DONE:
+                     CURLM_STATE_DOING);
+          rc = CURLM_CALL_MULTI_PERFORM;
+        }
+        else
+          /* stay in DO_MORE */
+          rc = CURLM_OK;
+      }
+      else {
+        /* failure detected */
+        Curl_posttransfer(data);
+        Curl_done(&data->easy_conn, result, FALSE);
+        disconnect_conn = TRUE;
+      }
+      break;
+
+    case CURLM_STATE_DO_DONE:
+      /* Move ourselves from the send to recv pipeline */
+      Curl_move_handle_from_send_to_recv_pipe(data, data->easy_conn);
+      /* Check if we can move pending requests to send pipe */
+      Curl_multi_process_pending_handles(multi);
+
+      /* Only perform the transfer if there's a good socket to work with.
+         Having both BAD is a signal to skip immediately to DONE */
+      if((data->easy_conn->sockfd != CURL_SOCKET_BAD) ||
+         (data->easy_conn->writesockfd != CURL_SOCKET_BAD))
+        multistate(data, CURLM_STATE_WAITPERFORM);
+      else
+        multistate(data, CURLM_STATE_DONE);
+      rc = CURLM_CALL_MULTI_PERFORM;
+      break;
+
+    case CURLM_STATE_WAITPERFORM:
+      /* Wait for our turn to PERFORM */
+      if(Curl_pipeline_checkget_read(data, data->easy_conn)) {
+        /* Grabbed the channel */
+        multistate(data, CURLM_STATE_PERFORM);
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+      break;
+
+    case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
+      /* if both rates are within spec, resume transfer */
+      if(Curl_pgrsUpdate(data->easy_conn))
+        result = CURLE_ABORTED_BY_CALLBACK;
+      else
+        result = Curl_speedcheck(data, now);
+
+      if(( (data->set.max_send_speed == 0) ||
+           (data->progress.ulspeed < data->set.max_send_speed ))  &&
+         ( (data->set.max_recv_speed == 0) ||
+           (data->progress.dlspeed < data->set.max_recv_speed)))
+        multistate(data, CURLM_STATE_PERFORM);
+      break;
+
+    case CURLM_STATE_PERFORM:
+    {
+      char *newurl = NULL;
+      bool retry = FALSE;
+
+      /* check if over send speed */
+      if((data->set.max_send_speed > 0) &&
+         (data->progress.ulspeed > data->set.max_send_speed)) {
+        int buffersize;
+
+        multistate(data, CURLM_STATE_TOOFAST);
+
+        /* calculate upload rate-limitation timeout. */
+        buffersize = (int)(data->set.buffer_size ?
+                           data->set.buffer_size : BUFSIZE);
+        timeout_ms = Curl_sleep_time(data->set.max_send_speed,
+                                     data->progress.ulspeed, buffersize);
+        Curl_expire_latest(data, timeout_ms);
+        break;
+      }
+
+      /* check if over recv speed */
+      if((data->set.max_recv_speed > 0) &&
+         (data->progress.dlspeed > data->set.max_recv_speed)) {
+        int buffersize;
+
+        multistate(data, CURLM_STATE_TOOFAST);
+
+        /* Calculate download rate-limitation timeout. */
+        buffersize = (int)(data->set.buffer_size ?
+                           data->set.buffer_size : BUFSIZE);
+        timeout_ms = Curl_sleep_time(data->set.max_recv_speed,
+                                     data->progress.dlspeed, buffersize);
+        Curl_expire_latest(data, timeout_ms);
+        break;
+      }
+
+      /* read/write data if it is ready to do so */
+      result = Curl_readwrite(data->easy_conn, data, &done);
+
+      k = &data->req;
+
+      if(!(k->keepon & KEEP_RECV))
+        /* We're done receiving */
+        Curl_pipeline_leave_read(data->easy_conn);
+
+      if(!(k->keepon & KEEP_SEND))
+        /* We're done sending */
+        Curl_pipeline_leave_write(data->easy_conn);
+
+      if(done || (result == CURLE_RECV_ERROR)) {
+        /* If CURLE_RECV_ERROR happens early enough, we assume it was a race
+         * condition and the server closed the re-used connection exactly when
+         * we wanted to use it, so figure out if that is indeed the case.
+         */
+        CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
+        if(!ret)
+          retry = (newurl)?TRUE:FALSE;
+
+        if(retry) {
+          /* if we are to retry, set the result to OK and consider the
+             request as done */
+          result = CURLE_OK;
+          done = TRUE;
+        }
+      }
+
+      if(result) {
+        /*
+         * The transfer phase returned error, we mark the connection to get
+         * closed to prevent being re-used. This is because we can't possibly
+         * know if the connection is in a good shape or not now.  Unless it is
+         * a protocol which uses two "channels" like FTP, as then the error
+         * happened in the data connection.
+         */
+
+        if(!(data->easy_conn->handler->flags & PROTOPT_DUAL))
+          connclose(data->easy_conn, "Transfer returned error");
+
+        Curl_posttransfer(data);
+        Curl_done(&data->easy_conn, result, FALSE);
+      }
+      else if(done) {
+        followtype follow=FOLLOW_NONE;
+
+        /* call this even if the readwrite function returned error */
+        Curl_posttransfer(data);
+
+        /* we're no longer receiving */
+        Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
+
+        /* expire the new receiving pipeline head */
+        if(data->easy_conn->recv_pipe->head)
+          Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 1);
+
+        /* Check if we can move pending requests to send pipe */
+        Curl_multi_process_pending_handles(multi);
+
+        /* When we follow redirects or is set to retry the connection, we must
+           to go back to the CONNECT state */
+        if(data->req.newurl || retry) {
+          if(!retry) {
+            /* if the URL is a follow-location and not just a retried request
+               then figure out the URL here */
+            free(newurl);
+            newurl = data->req.newurl;
+            data->req.newurl = NULL;
+            follow = FOLLOW_REDIR;
+          }
+          else
+            follow = FOLLOW_RETRY;
+          result = Curl_done(&data->easy_conn, CURLE_OK, FALSE);
+          if(!result) {
+            result = Curl_follow(data, newurl, follow);
+            if(!result) {
+              multistate(data, CURLM_STATE_CONNECT);
+              rc = CURLM_CALL_MULTI_PERFORM;
+              newurl = NULL; /* handed over the memory ownership to
+                                Curl_follow(), make sure we don't free() it
+                                here */
+            }
+          }
+        }
+        else {
+          /* after the transfer is done, go DONE */
+
+          /* but first check to see if we got a location info even though we're
+             not following redirects */
+          if(data->req.location) {
+            free(newurl);
+            newurl = data->req.location;
+            data->req.location = NULL;
+            result = Curl_follow(data, newurl, FOLLOW_FAKE);
+            if(!result)
+              newurl = NULL; /* allocation was handed over Curl_follow() */
+            else
+              disconnect_conn = TRUE;
+          }
+
+          multistate(data, CURLM_STATE_DONE);
+          rc = CURLM_CALL_MULTI_PERFORM;
+        }
+      }
+
+      free(newurl);
+      break;
+    }
+
+    case CURLM_STATE_DONE:
+      /* this state is highly transient, so run another loop after this */
+      rc = CURLM_CALL_MULTI_PERFORM;
+
+      if(data->easy_conn) {
+        CURLcode res;
+
+        /* Remove ourselves from the receive pipeline, if we are there. */
+        Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
+        /* Check if we can move pending requests to send pipe */
+        Curl_multi_process_pending_handles(multi);
+
+        /* post-transfer command */
+        res = Curl_done(&data->easy_conn, result, FALSE);
+
+        /* allow a previously set error code take precedence */
+        if(!result)
+          result = res;
+
+        /*
+         * If there are other handles on the pipeline, Curl_done won't set
+         * easy_conn to NULL.  In such a case, curl_multi_remove_handle() can
+         * access free'd data, if the connection is free'd and the handle
+         * removed before we perform the processing in CURLM_STATE_COMPLETED
+         */
+        if(data->easy_conn)
+          data->easy_conn = NULL;
+      }
+
+      if(data->set.wildcardmatch) {
+        if(data->wildcard.state != CURLWC_DONE) {
+          /* if a wildcard is set and we are not ending -> lets start again
+             with CURLM_STATE_INIT */
+          multistate(data, CURLM_STATE_INIT);
+          break;
+        }
+      }
+
+      /* after we have DONE what we're supposed to do, go COMPLETED, and
+         it doesn't matter what the Curl_done() returned! */
+      multistate(data, CURLM_STATE_COMPLETED);
+      break;
+
+    case CURLM_STATE_COMPLETED:
+      /* this is a completed transfer, it is likely to still be connected */
+
+      /* This node should be delinked from the list now and we should post
+         an information message that we are complete. */
+
+      /* Important: reset the conn pointer so that we don't point to memory
+         that could be freed anytime */
+      data->easy_conn = NULL;
+
+      Curl_expire(data, 0); /* stop all timers */
+      break;
+
+    case CURLM_STATE_MSGSENT:
+      data->result = result;
+      return CURLM_OK; /* do nothing */
+
+    default:
+      return CURLM_INTERNAL_ERROR;
+    }
+    statemachine_end:
+
+    if(data->mstate < CURLM_STATE_COMPLETED) {
+      if(result) {
+        /*
+         * If an error was returned, and we aren't in completed state now,
+         * then we go to completed and consider this transfer aborted.
+         */
+
+        /* NOTE: no attempt to disconnect connections must be made
+           in the case blocks above - cleanup happens only here */
+
+        data->state.pipe_broke = FALSE;
+
+        /* Check if we can move pending requests to send pipe */
+        Curl_multi_process_pending_handles(multi);
+
+        if(data->easy_conn) {
+          /* if this has a connection, unsubscribe from the pipelines */
+          Curl_pipeline_leave_write(data->easy_conn);
+          Curl_pipeline_leave_read(data->easy_conn);
+          Curl_removeHandleFromPipeline(data, data->easy_conn->send_pipe);
+          Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
+
+          if(disconnect_conn) {
+            /* Don't attempt to send data over a connection that timed out */
+            bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
+            /* disconnect properly */
+            Curl_disconnect(data->easy_conn, dead_connection);
+
+            /* This is where we make sure that the easy_conn pointer is reset.
+               We don't have to do this in every case block above where a
+               failure is detected */
+            data->easy_conn = NULL;
+          }
+        }
+        else if(data->mstate == CURLM_STATE_CONNECT) {
+          /* Curl_connect() failed */
+          (void)Curl_posttransfer(data);
+        }
+
+        multistate(data, CURLM_STATE_COMPLETED);
+      }
+      /* if there's still a connection to use, call the progress function */
+      else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) {
+        /* aborted due to progress callback return code must close the
+           connection */
+        result = CURLE_ABORTED_BY_CALLBACK;
+        connclose(data->easy_conn, "Aborted by callback");
+
+        /* if not yet in DONE state, go there, otherwise COMPLETED */
+        multistate(data, (data->mstate < CURLM_STATE_DONE)?
+                   CURLM_STATE_DONE: CURLM_STATE_COMPLETED);
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+    }
+
+    if(CURLM_STATE_COMPLETED == data->mstate) {
+      /* now fill in the Curl_message with this info */
+      msg = &data->msg;
+
+      msg->extmsg.msg = CURLMSG_DONE;
+      msg->extmsg.easy_handle = data;
+      msg->extmsg.data.result = result;
+
+      rc = multi_addmsg(multi, msg);
+
+      multistate(data, CURLM_STATE_MSGSENT);
+    }
+  } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
+
+  data->result = result;
+
+
+  return rc;
+}
+
+
+CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
+{
+  struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+  struct SessionHandle *data;
+  CURLMcode returncode=CURLM_OK;
+  struct Curl_tree *t;
+  struct timeval now = Curl_tvnow();
+
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+  data=multi->easyp;
+  while(data) {
+    CURLMcode result;
+    struct WildcardData *wc = &data->wildcard;
+    SIGPIPE_VARIABLE(pipe_st);
+
+    if(data->set.wildcardmatch) {
+      if(!wc->filelist) {
+        CURLcode ret = Curl_wildcard_init(wc); /* init wildcard structures */
+        if(ret)
+          return CURLM_OUT_OF_MEMORY;
+      }
+    }
+
+    sigpipe_ignore(data, &pipe_st);
+    result = multi_runsingle(multi, now, data);
+    sigpipe_restore(&pipe_st);
+
+    if(data->set.wildcardmatch) {
+      /* destruct wildcard structures if it is needed */
+      if(wc->state == CURLWC_DONE || result)
+        Curl_wildcard_dtor(wc);
+    }
+
+    if(result)
+      returncode = result;
+
+    data = data->next; /* operate on next handle */
+  }
+
+  /*
+   * Simply remove all expired timers from the splay since handles are dealt
+   * with unconditionally by this function and curl_multi_timeout() requires
+   * that already passed/handled expire times are removed from the splay.
+   *
+   * It is important that the 'now' value is set at the entry of this function
+   * and not for the current time as it may have ticked a little while since
+   * then and then we risk this loop to remove timers that actually have not
+   * been handled!
+   */
+  do {
+    multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
+    if(t)
+      /* the removed may have another timeout in queue */
+      (void)add_next_timeout(now, multi, t->payload);
+
+  } while(t);
+
+  *running_handles = multi->num_alive;
+
+  if(CURLM_OK >= returncode)
+    update_timer(multi);
+
+  return returncode;
+}
+
+static void close_all_connections(struct Curl_multi *multi)
+{
+  struct connectdata *conn;
+
+  conn = Curl_conncache_find_first_connection(&multi->conn_cache);
+  while(conn) {
+    SIGPIPE_VARIABLE(pipe_st);
+    conn->data = multi->closure_handle;
+
+    sigpipe_ignore(conn->data, &pipe_st);
+    /* This will remove the connection from the cache */
+    (void)Curl_disconnect(conn, FALSE);
+    sigpipe_restore(&pipe_st);
+
+    conn = Curl_conncache_find_first_connection(&multi->conn_cache);
+  }
+}
+
+CURLMcode curl_multi_cleanup(CURLM *multi_handle)
+{
+  struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+  struct SessionHandle *data;
+  struct SessionHandle *nextdata;
+
+  if(GOOD_MULTI_HANDLE(multi)) {
+    bool restore_pipe = FALSE;
+    SIGPIPE_VARIABLE(pipe_st);
+
+    multi->type = 0; /* not good anymore */
+
+    /* Close all the connections in the connection cache */
+    close_all_connections(multi);
+
+    if(multi->closure_handle) {
+      sigpipe_ignore(multi->closure_handle, &pipe_st);
+      restore_pipe = TRUE;
+
+      multi->closure_handle->dns.hostcache = &multi->hostcache;
+      Curl_hostcache_clean(multi->closure_handle,
+                           multi->closure_handle->dns.hostcache);
+
+      Curl_close(multi->closure_handle);
+    }
+
+    Curl_hash_destroy(&multi->sockhash);
+    Curl_conncache_destroy(&multi->conn_cache);
+    Curl_llist_destroy(multi->msglist, NULL);
+    Curl_llist_destroy(multi->pending, NULL);
+
+    /* remove all easy handles */
+    data = multi->easyp;
+    while(data) {
+      nextdata=data->next;
+      if(data->dns.hostcachetype == HCACHE_MULTI) {
+        /* clear out the usage of the shared DNS cache */
+        Curl_hostcache_clean(data, data->dns.hostcache);
+        data->dns.hostcache = NULL;
+        data->dns.hostcachetype = HCACHE_NONE;
+      }
+
+      /* Clear the pointer to the connection cache */
+      data->state.conn_cache = NULL;
+      data->multi = NULL; /* clear the association */
+
+      data = nextdata;
+    }
+
+    Curl_hash_destroy(&multi->hostcache);
+
+    /* Free the blacklists by setting them to NULL */
+    Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
+    Curl_pipeline_set_server_blacklist(NULL, &multi->pipelining_server_bl);
+
+    free(multi);
+    if(restore_pipe)
+      sigpipe_restore(&pipe_st);
+
+    return CURLM_OK;
+  }
+  else
+    return CURLM_BAD_HANDLE;
+}
+
+/*
+ * curl_multi_info_read()
+ *
+ * This function is the primary way for a multi/multi_socket application to
+ * figure out if a transfer has ended. We MUST make this function as fast as
+ * possible as it will be polled frequently and we MUST NOT scan any lists in
+ * here to figure out things. We must scale fine to thousands of handles and
+ * beyond. The current design is fully O(1).
+ */
+
+CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue)
+{
+  struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+  struct Curl_message *msg;
+
+  *msgs_in_queue = 0; /* default to none */
+
+  if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(multi->msglist)) {
+    /* there is one or more messages in the list */
+    struct curl_llist_element *e;
+
+    /* extract the head of the list to return */
+    e = multi->msglist->head;
+
+    msg = e->ptr;
+
+    /* remove the extracted entry */
+    Curl_llist_remove(multi->msglist, e, NULL);
+
+    *msgs_in_queue = curlx_uztosi(Curl_llist_count(multi->msglist));
+
+    return &msg->extmsg;
+  }
+  else
+    return NULL;
+}
+
+/*
+ * singlesocket() checks what sockets we deal with and their "action state"
+ * and if we have a different state in any of those sockets from last time we
+ * call the callback accordingly.
+ */
+static void singlesocket(struct Curl_multi *multi,
+                         struct SessionHandle *data)
+{
+  curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
+  int i;
+  struct Curl_sh_entry *entry;
+  curl_socket_t s;
+  int num;
+  unsigned int curraction;
+  bool remove_sock_from_hash;
+
+  for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++)
+    socks[i] = CURL_SOCKET_BAD;
+
+  /* Fill in the 'current' struct with the state as it is now: what sockets to
+     supervise and for what actions */
+  curraction = multi_getsock(data, socks, MAX_SOCKSPEREASYHANDLE);
+
+  /* We have 0 .. N sockets already and we get to know about the 0 .. M
+     sockets we should have from now on. Detect the differences, remove no
+     longer supervised ones and add new ones */
+
+  /* walk over the sockets we got right now */
+  for(i=0; (i< MAX_SOCKSPEREASYHANDLE) &&
+        (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i)));
+      i++) {
+    int action = CURL_POLL_NONE;
+
+    s = socks[i];
+
+    /* get it from the hash */
+    entry = Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
+
+    if(curraction & GETSOCK_READSOCK(i))
+      action |= CURL_POLL_IN;
+    if(curraction & GETSOCK_WRITESOCK(i))
+      action |= CURL_POLL_OUT;
+
+    if(entry) {
+      /* yeps, already present so check if it has the same action set */
+      if(entry->action == action)
+        /* same, continue */
+        continue;
+    }
+    else {
+      /* this is a socket we didn't have before, add it! */
+      entry = sh_addentry(&multi->sockhash, s, data);
+      if(!entry)
+        /* fatal */
+        return;
+    }
+
+    /* we know (entry != NULL) at this point, see the logic above */
+    if(multi->socket_cb)
+      multi->socket_cb(data,
+                       s,
+                       action,
+                       multi->socket_userp,
+                       entry->socketp);
+
+    entry->action = action; /* store the current action state */
+  }
+
+  num = i; /* number of sockets */
+
+  /* when we've walked over all the sockets we should have right now, we must
+     make sure to detect sockets that are removed */
+  for(i=0; i< data->numsocks; i++) {
+    int j;
+    s = data->sockets[i];
+    for(j=0; j<num; j++) {
+      if(s == socks[j]) {
+        /* this is still supervised */
+        s = CURL_SOCKET_BAD;
+        break;
+      }
+    }
+    if(s != CURL_SOCKET_BAD) {
+
+      /* this socket has been removed. Tell the app to remove it */
+      remove_sock_from_hash = TRUE;
+
+      entry = Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
+      if(entry) {
+        /* check if the socket to be removed serves a connection which has
+           other easy-s in a pipeline. In this case the socket should not be
+           removed. */
+        struct connectdata *easy_conn = data->easy_conn;
+        if(easy_conn) {
+          if(easy_conn->recv_pipe && easy_conn->recv_pipe->size > 1) {
+            /* the handle should not be removed from the pipe yet */
+            remove_sock_from_hash = FALSE;
+
+            /* Update the sockhash entry to instead point to the next in line
+               for the recv_pipe, or the first (in case this particular easy
+               isn't already) */
+            if(entry->easy == data) {
+              if(Curl_recvpipe_head(data, easy_conn))
+                entry->easy = easy_conn->recv_pipe->head->next->ptr;
+              else
+                entry->easy = easy_conn->recv_pipe->head->ptr;
+            }
+          }
+          if(easy_conn->send_pipe  && easy_conn->send_pipe->size > 1) {
+            /* the handle should not be removed from the pipe yet */
+            remove_sock_from_hash = FALSE;
+
+            /* Update the sockhash entry to instead point to the next in line
+               for the send_pipe, or the first (in case this particular easy
+               isn't already) */
+            if(entry->easy == data) {
+              if(Curl_sendpipe_head(data, easy_conn))
+                entry->easy = easy_conn->send_pipe->head->next->ptr;
+              else
+                entry->easy = easy_conn->send_pipe->head->ptr;
+            }
+          }
+          /* Don't worry about overwriting recv_pipe head with send_pipe_head,
+             when action will be asked on the socket (see multi_socket()), the
+             head of the correct pipe will be taken according to the
+             action. */
+        }
+      }
+      else
+        /* just a precaution, this socket really SHOULD be in the hash already
+           but in case it isn't, we don't have to tell the app to remove it
+           either since it never got to know about it */
+        remove_sock_from_hash = FALSE;
+
+      if(remove_sock_from_hash) {
+        /* in this case 'entry' is always non-NULL */
+        if(multi->socket_cb)
+          multi->socket_cb(data,
+                           s,
+                           CURL_POLL_REMOVE,
+                           multi->socket_userp,
+                           entry->socketp);
+        sh_delentry(&multi->sockhash, s);
+      }
+
+    }
+  }
+
+  memcpy(data->sockets, socks, num*sizeof(curl_socket_t));
+  data->numsocks = num;
+}
+
+/*
+ * Curl_multi_closed()
+ *
+ * Used by the connect code to tell the multi_socket code that one of the
+ * sockets we were using is about to be closed.  This function will then
+ * remove it from the sockethash for this handle to make the multi_socket API
+ * behave properly, especially for the case when libcurl will create another
+ * socket again and it gets the same file descriptor number.
+ */
+
+void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
+{
+  struct Curl_multi *multi = conn->data->multi;
+  if(multi) {
+    /* this is set if this connection is part of a handle that is added to
+       a multi handle, and only then this is necessary */
+    struct Curl_sh_entry *entry =
+      Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
+
+    if(entry) {
+      if(multi->socket_cb)
+        multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
+                         multi->socket_userp,
+                         entry->socketp);
+
+      /* now remove it from the socket hash */
+      sh_delentry(&multi->sockhash, s);
+    }
+  }
+}
+
+
+
+/*
+ * add_next_timeout()
+ *
+ * Each SessionHandle has a list of timeouts. The add_next_timeout() is called
+ * when it has just been removed from the splay tree because the timeout has
+ * expired. This function is then to advance in the list to pick the next
+ * timeout to use (skip the already expired ones) and add this node back to
+ * the splay tree again.
+ *
+ * The splay tree only has each sessionhandle as a single node and the nearest
+ * timeout is used to sort it on.
+ */
+static CURLMcode add_next_timeout(struct timeval now,
+                                  struct Curl_multi *multi,
+                                  struct SessionHandle *d)
+{
+  struct timeval *tv = &d->state.expiretime;
+  struct curl_llist *list = d->state.timeoutlist;
+  struct curl_llist_element *e;
+
+  /* move over the timeout list for this specific handle and remove all
+     timeouts that are now passed tense and store the next pending
+     timeout in *tv */
+  for(e = list->head; e; ) {
+    struct curl_llist_element *n = e->next;
+    long diff = curlx_tvdiff(*(struct timeval *)e->ptr, now);
+    if(diff <= 0)
+      /* remove outdated entry */
+      Curl_llist_remove(list, e, NULL);
+    else
+      /* the list is sorted so get out on the first mismatch */
+      break;
+    e = n;
+  }
+  e = list->head;
+  if(!e) {
+    /* clear the expire times within the handles that we remove from the
+       splay tree */
+    tv->tv_sec = 0;
+    tv->tv_usec = 0;
+  }
+  else {
+    /* copy the first entry to 'tv' */
+    memcpy(tv, e->ptr, sizeof(*tv));
+
+    /* remove first entry from list */
+    Curl_llist_remove(list, e, NULL);
+
+    /* insert this node again into the splay */
+    multi->timetree = Curl_splayinsert(*tv, multi->timetree,
+                                       &d->state.timenode);
+  }
+  return CURLM_OK;
+}
+
+static CURLMcode multi_socket(struct Curl_multi *multi,
+                              bool checkall,
+                              curl_socket_t s,
+                              int ev_bitmask,
+                              int *running_handles)
+{
+  CURLMcode result = CURLM_OK;
+  struct SessionHandle *data = NULL;
+  struct Curl_tree *t;
+  struct timeval now = Curl_tvnow();
+
+  if(checkall) {
+    /* *perform() deals with running_handles on its own */
+    result = curl_multi_perform(multi, running_handles);
+
+    /* walk through each easy handle and do the socket state change magic
+       and callbacks */
+    if(result != CURLM_BAD_HANDLE) {
+      data=multi->easyp;
+      while(data) {
+        singlesocket(multi, data);
+        data = data->next;
+      }
+    }
+
+    /* or should we fall-through and do the timer-based stuff? */
+    return result;
+  }
+  else if(s != CURL_SOCKET_TIMEOUT) {
+
+    struct Curl_sh_entry *entry =
+      Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
+
+    if(!entry)
+      /* Unmatched socket, we can't act on it but we ignore this fact.  In
+         real-world tests it has been proved that libevent can in fact give
+         the application actions even though the socket was just previously
+         asked to get removed, so thus we better survive stray socket actions
+         and just move on. */
+      ;
+    else {
+      SIGPIPE_VARIABLE(pipe_st);
+
+      data = entry->easy;
+
+      if(data->magic != CURLEASY_MAGIC_NUMBER)
+        /* bad bad bad bad bad bad bad */
+        return CURLM_INTERNAL_ERROR;
+
+      /* If the pipeline is enabled, take the handle which is in the head of
+         the pipeline. If we should write into the socket, take the send_pipe
+         head.  If we should read from the socket, take the recv_pipe head. */
+      if(data->easy_conn) {
+        if((ev_bitmask & CURL_POLL_OUT) &&
+           data->easy_conn->send_pipe &&
+           data->easy_conn->send_pipe->head)
+          data = data->easy_conn->send_pipe->head->ptr;
+        else if((ev_bitmask & CURL_POLL_IN) &&
+                data->easy_conn->recv_pipe &&
+                data->easy_conn->recv_pipe->head)
+          data = data->easy_conn->recv_pipe->head->ptr;
+      }
+
+      if(data->easy_conn &&
+         !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
+        /* set socket event bitmask if they're not locked */
+        data->easy_conn->cselect_bits = ev_bitmask;
+
+      sigpipe_ignore(data, &pipe_st);
+      result = multi_runsingle(multi, now, data);
+      sigpipe_restore(&pipe_st);
+
+      if(data->easy_conn &&
+         !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
+        /* clear the bitmask only if not locked */
+        data->easy_conn->cselect_bits = 0;
+
+      if(CURLM_OK >= result)
+        /* get the socket(s) and check if the state has been changed since
+           last */
+        singlesocket(multi, data);
+
+      /* Now we fall-through and do the timer-based stuff, since we don't want
+         to force the user to have to deal with timeouts as long as at least
+         one connection in fact has traffic. */
+
+      data = NULL; /* set data to NULL again to avoid calling
+                      multi_runsingle() in case there's no need to */
+      now = Curl_tvnow(); /* get a newer time since the multi_runsingle() loop
+                             may have taken some time */
+    }
+  }
+  else {
+    /* Asked to run due to time-out. Clear the 'lastcall' variable to force
+       update_timer() to trigger a callback to the app again even if the same
+       timeout is still the one to run after this call. That handles the case
+       when the application asks libcurl to run the timeout prematurely. */
+    memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
+  }
+
+  /*
+   * The loop following here will go on as long as there are expire-times left
+   * to process in the splay and 'data' will be re-assigned for every expired
+   * handle we deal with.
+   */
+  do {
+    /* the first loop lap 'data' can be NULL */
+    if(data) {
+      SIGPIPE_VARIABLE(pipe_st);
+
+      sigpipe_ignore(data, &pipe_st);
+      result = multi_runsingle(multi, now, data);
+      sigpipe_restore(&pipe_st);
+
+      if(CURLM_OK >= result)
+        /* get the socket(s) and check if the state has been changed since
+           last */
+        singlesocket(multi, data);
+    }
+
+    /* Check if there's one (more) expired timer to deal with! This function
+       extracts a matching node if there is one */
+
+    multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
+    if(t) {
+      data = t->payload; /* assign this for next loop */
+      (void)add_next_timeout(now, multi, t->payload);
+    }
+
+  } while(t);
+
+  *running_handles = multi->num_alive;
+  return result;
+}
+
+#undef curl_multi_setopt
+CURLMcode curl_multi_setopt(CURLM *multi_handle,
+                            CURLMoption option, ...)
+{
+  struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+  CURLMcode res = CURLM_OK;
+  va_list param;
+
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+  va_start(param, option);
+
+  switch(option) {
+  case CURLMOPT_SOCKETFUNCTION:
+    multi->socket_cb = va_arg(param, curl_socket_callback);
+    break;
+  case CURLMOPT_SOCKETDATA:
+    multi->socket_userp = va_arg(param, void *);
+    break;
+  case CURLMOPT_PUSHFUNCTION:
+    multi->push_cb = va_arg(param, curl_push_callback);
+    break;
+  case CURLMOPT_PUSHDATA:
+    multi->push_userp = va_arg(param, void *);
+    break;
+  case CURLMOPT_PIPELINING:
+    multi->pipelining = va_arg(param, long);
+    break;
+  case CURLMOPT_TIMERFUNCTION:
+    multi->timer_cb = va_arg(param, curl_multi_timer_callback);
+    break;
+  case CURLMOPT_TIMERDATA:
+    multi->timer_userp = va_arg(param, void *);
+    break;
+  case CURLMOPT_MAXCONNECTS:
+    multi->maxconnects = va_arg(param, long);
+    break;
+  case CURLMOPT_MAX_HOST_CONNECTIONS:
+    multi->max_host_connections = va_arg(param, long);
+    break;
+  case CURLMOPT_MAX_PIPELINE_LENGTH:
+    multi->max_pipeline_length = va_arg(param, long);
+    break;
+  case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
+    multi->content_length_penalty_size = va_arg(param, long);
+    break;
+  case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
+    multi->chunk_length_penalty_size = va_arg(param, long);
+    break;
+  case CURLMOPT_PIPELINING_SITE_BL:
+    res = Curl_pipeline_set_site_blacklist(va_arg(param, char **),
+                                           &multi->pipelining_site_bl);
+    break;
+  case CURLMOPT_PIPELINING_SERVER_BL:
+    res = Curl_pipeline_set_server_blacklist(va_arg(param, char **),
+                                             &multi->pipelining_server_bl);
+    break;
+  case CURLMOPT_MAX_TOTAL_CONNECTIONS:
+    multi->max_total_connections = va_arg(param, long);
+    break;
+  default:
+    res = CURLM_UNKNOWN_OPTION;
+    break;
+  }
+  va_end(param);
+  return res;
+}
+
+/* we define curl_multi_socket() in the public multi.h header */
+#undef curl_multi_socket
+
+CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
+                            int *running_handles)
+{
+  CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
+                                  0, running_handles);
+  if(CURLM_OK >= result)
+    update_timer((struct Curl_multi *)multi_handle);
+  return result;
+}
+
+CURLMcode curl_multi_socket_action(CURLM *multi_handle, curl_socket_t s,
+                                   int ev_bitmask, int *running_handles)
+{
+  CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
+                                  ev_bitmask, running_handles);
+  if(CURLM_OK >= result)
+    update_timer((struct Curl_multi *)multi_handle);
+  return result;
+}
+
+CURLMcode curl_multi_socket_all(CURLM *multi_handle, int *running_handles)
+
+{
+  CURLMcode result = multi_socket((struct Curl_multi *)multi_handle,
+                                  TRUE, CURL_SOCKET_BAD, 0, running_handles);
+  if(CURLM_OK >= result)
+    update_timer((struct Curl_multi *)multi_handle);
+  return result;
+}
+
+static CURLMcode multi_timeout(struct Curl_multi *multi,
+                               long *timeout_ms)
+{
+  static struct timeval tv_zero = {0, 0};
+
+  if(multi->timetree) {
+    /* we have a tree of expire times */
+    struct timeval now = Curl_tvnow();
+
+    /* splay the lowest to the bottom */
+    multi->timetree = Curl_splay(tv_zero, multi->timetree);
+
+    if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
+      /* some time left before expiration */
+      *timeout_ms = curlx_tvdiff(multi->timetree->key, now);
+      if(!*timeout_ms)
+        /*
+         * Since we only provide millisecond resolution on the returned value
+         * and the diff might be less than one millisecond here, we don't
+         * return zero as that may cause short bursts of busyloops on fast
+         * processors while the diff is still present but less than one
+         * millisecond! instead we return 1 until the time is ripe.
+         */
+        *timeout_ms=1;
+    }
+    else
+      /* 0 means immediately */
+      *timeout_ms = 0;
+  }
+  else
+    *timeout_ms = -1;
+
+  return CURLM_OK;
+}
+
+CURLMcode curl_multi_timeout(CURLM *multi_handle,
+                             long *timeout_ms)
+{
+  struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+
+  /* First, make some basic checks that the CURLM handle is a good handle */
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+  return multi_timeout(multi, timeout_ms);
+}
+
+/*
+ * Tell the application it should update its timers, if it subscribes to the
+ * update timer callback.
+ */
+static int update_timer(struct Curl_multi *multi)
+{
+  long timeout_ms;
+
+  if(!multi->timer_cb)
+    return 0;
+  if(multi_timeout(multi, &timeout_ms)) {
+    return -1;
+  }
+  if(timeout_ms < 0) {
+    static const struct timeval none={0, 0};
+    if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
+      multi->timer_lastcall = none;
+      /* there's no timeout now but there was one previously, tell the app to
+         disable it */
+      return multi->timer_cb((CURLM*)multi, -1, multi->timer_userp);
+    }
+    return 0;
+  }
+
+  /* When multi_timeout() is done, multi->timetree points to the node with the
+   * timeout we got the (relative) time-out time for. We can thus easily check
+   * if this is the same (fixed) time as we got in a previous call and then
+   * avoid calling the callback again. */
+  if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
+    return 0;
+
+  multi->timer_lastcall = multi->timetree->key;
+
+  return multi->timer_cb((CURLM*)multi, timeout_ms, multi->timer_userp);
+}
+
+/*
+ * multi_freetimeout()
+ *
+ * Callback used by the llist system when a single timeout list entry is
+ * destroyed.
+ */
+static void multi_freetimeout(void *user, void *entryptr)
+{
+  (void)user;
+
+  /* the entry was plain malloc()'ed */
+  free(entryptr);
+}
+
+/*
+ * multi_addtimeout()
+ *
+ * Add a timestamp to the list of timeouts. Keep the list sorted so that head
+ * of list is always the timeout nearest in time.
+ *
+ */
+static CURLMcode
+multi_addtimeout(struct curl_llist *timeoutlist,
+                 struct timeval *stamp)
+{
+  struct curl_llist_element *e;
+  struct timeval *timedup;
+  struct curl_llist_element *prev = NULL;
+
+  timedup = malloc(sizeof(*timedup));
+  if(!timedup)
+    return CURLM_OUT_OF_MEMORY;
+
+  /* copy the timestamp */
+  memcpy(timedup, stamp, sizeof(*timedup));
+
+  if(Curl_llist_count(timeoutlist)) {
+    /* find the correct spot in the list */
+    for(e = timeoutlist->head; e; e = e->next) {
+      struct timeval *checktime = e->ptr;
+      long diff = curlx_tvdiff(*checktime, *timedup);
+      if(diff > 0)
+        break;
+      prev = e;
+    }
+
+  }
+  /* else
+     this is the first timeout on the list */
+
+  if(!Curl_llist_insert_next(timeoutlist, prev, timedup)) {
+    free(timedup);
+    return CURLM_OUT_OF_MEMORY;
+  }
+
+  return CURLM_OK;
+}
+
+/*
+ * Curl_expire()
+ *
+ * given a number of milliseconds from now to use to set the 'act before
+ * this'-time for the transfer, to be extracted by curl_multi_timeout()
+ *
+ * Note that the timeout will be added to a queue of timeouts if it defines a
+ * moment in time that is later than the current head of queue.
+ *
+ * Pass zero to clear all timeout values for this handle.
+*/
+void Curl_expire(struct SessionHandle *data, long milli)
+{
+  struct Curl_multi *multi = data->multi;
+  struct timeval *nowp = &data->state.expiretime;
+  int rc;
+
+  /* this is only interesting while there is still an associated multi struct
+     remaining! */
+  if(!multi)
+    return;
+
+  if(!milli) {
+    /* No timeout, clear the time data. */
+    if(nowp->tv_sec || nowp->tv_usec) {
+      /* Since this is an cleared time, we must remove the previous entry from
+         the splay tree */
+      struct curl_llist *list = data->state.timeoutlist;
+
+      rc = Curl_splayremovebyaddr(multi->timetree,
+                                  &data->state.timenode,
+                                  &multi->timetree);
+      if(rc)
+        infof(data, "Internal error clearing splay node = %d\n", rc);
+
+      /* flush the timeout list too */
+      while(list->size > 0)
+        Curl_llist_remove(list, list->tail, NULL);
+
+#ifdef DEBUGBUILD
+      infof(data, "Expire cleared\n");
+#endif
+      nowp->tv_sec = 0;
+      nowp->tv_usec = 0;
+    }
+  }
+  else {
+    struct timeval set;
+
+    set = Curl_tvnow();
+    set.tv_sec += milli/1000;
+    set.tv_usec += (milli%1000)*1000;
+
+    if(set.tv_usec >= 1000000) {
+      set.tv_sec++;
+      set.tv_usec -= 1000000;
+    }
+
+    if(nowp->tv_sec || nowp->tv_usec) {
+      /* This means that the struct is added as a node in the splay tree.
+         Compare if the new time is earlier, and only remove-old/add-new if it
+         is. */
+      long diff = curlx_tvdiff(set, *nowp);
+      if(diff > 0) {
+        /* the new expire time was later so just add it to the queue
+           and get out */
+        multi_addtimeout(data->state.timeoutlist, &set);
+        return;
+      }
+
+      /* the new time is newer than the presently set one, so add the current
+         to the queue and update the head */
+      multi_addtimeout(data->state.timeoutlist, nowp);
+
+      /* Since this is an updated time, we must remove the previous entry from
+         the splay tree first and then re-add the new value */
+      rc = Curl_splayremovebyaddr(multi->timetree,
+                                  &data->state.timenode,
+                                  &multi->timetree);
+      if(rc)
+        infof(data, "Internal error removing splay node = %d\n", rc);
+    }
+
+    *nowp = set;
+    data->state.timenode.payload = data;
+    multi->timetree = Curl_splayinsert(*nowp,
+                                       multi->timetree,
+                                       &data->state.timenode);
+  }
+#if 0
+  Curl_splayprint(multi->timetree, 0, TRUE);
+#endif
+}
+
+/*
+ * Curl_expire_latest()
+ *
+ * This is like Curl_expire() but will only add a timeout node to the list of
+ * timers if there is no timeout that will expire before the given time.
+ *
+ * Use this function if the code logic risks calling this function many times
+ * or if there's no particular conditional wait in the code for this specific
+ * time-out period to expire.
+ *
+ */
+void Curl_expire_latest(struct SessionHandle *data, long milli)
+{
+  struct timeval *expire = &data->state.expiretime;
+
+  struct timeval set;
+
+  set = Curl_tvnow();
+  set.tv_sec += milli / 1000;
+  set.tv_usec += (milli % 1000) * 1000;
+
+  if(set.tv_usec >= 1000000) {
+    set.tv_sec++;
+    set.tv_usec -= 1000000;
+  }
+
+  if(expire->tv_sec || expire->tv_usec) {
+    /* This means that the struct is added as a node in the splay tree.
+       Compare if the new time is earlier, and only remove-old/add-new if it
+         is. */
+    long diff = curlx_tvdiff(set, *expire);
+    if(diff > 0)
+      /* the new expire time was later than the top time, so just skip this */
+      return;
+  }
+
+  /* Just add the timeout like normal */
+  Curl_expire(data, milli);
+}
+
+CURLMcode curl_multi_assign(CURLM *multi_handle,
+                            curl_socket_t s, void *hashp)
+{
+  struct Curl_sh_entry *there = NULL;
+  struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
+
+  if(s != CURL_SOCKET_BAD)
+    there = Curl_hash_pick(&multi->sockhash, (char *)&s,
+                           sizeof(curl_socket_t));
+
+  if(!there)
+    return CURLM_BAD_SOCKET;
+
+  there->socketp = hashp;
+
+  return CURLM_OK;
+}
+
+size_t Curl_multi_max_host_connections(struct Curl_multi *multi)
+{
+  return multi ? multi->max_host_connections : 0;
+}
+
+size_t Curl_multi_max_total_connections(struct Curl_multi *multi)
+{
+  return multi ? multi->max_total_connections : 0;
+}
+
+curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi)
+{
+  return multi ? multi->content_length_penalty_size : 0;
+}
+
+curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi)
+{
+  return multi ? multi->chunk_length_penalty_size : 0;
+}
+
+struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi)
+{
+  return multi->pipelining_site_bl;
+}
+
+struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi)
+{
+  return multi->pipelining_server_bl;
+}
+
+void Curl_multi_process_pending_handles(struct Curl_multi *multi)
+{
+  struct curl_llist_element *e = multi->pending->head;
+
+  while(e) {
+    struct SessionHandle *data = e->ptr;
+    struct curl_llist_element *next = e->next;
+
+    if(data->mstate == CURLM_STATE_CONNECT_PEND) {
+      multistate(data, CURLM_STATE_CONNECT);
+
+      /* Remove this node from the list */
+      Curl_llist_remove(multi->pending, e, NULL);
+
+      /* Make sure that the handle will be processed soonish. */
+      Curl_expire_latest(data, 1);
+    }
+
+    e = next; /* operate on next handle */
+  }
+}
+
+#ifdef DEBUGBUILD
+void Curl_multi_dump(const struct Curl_multi *multi_handle)
+{
+  struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+  struct SessionHandle *data;
+  int i;
+  fprintf(stderr, "* Multi status: %d handles, %d alive\n",
+          multi->num_easy, multi->num_alive);
+  for(data=multi->easyp; data; data = data->next) {
+    if(data->mstate < CURLM_STATE_COMPLETED) {
+      /* only display handles that are not completed */
+      fprintf(stderr, "handle %p, state %s, %d sockets\n",
+              (void *)data,
+              statename[data->mstate], data->numsocks);
+      for(i=0; i < data->numsocks; i++) {
+        curl_socket_t s = data->sockets[i];
+        struct Curl_sh_entry *entry =
+          Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
+
+        fprintf(stderr, "%d ", (int)s);
+        if(!entry) {
+          fprintf(stderr, "INTERNAL CONFUSION\n");
+          continue;
+        }
+        fprintf(stderr, "[%s %s] ",
+                entry->action&CURL_POLL_IN?"RECVING":"",
+                entry->action&CURL_POLL_OUT?"SENDING":"");
+      }
+      if(data->numsocks)
+        fprintf(stderr, "\n");
+    }
+  }
+}
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/lib/multihandle.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/multihandle.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/multihandle.h	(revision 164)
@@ -0,0 +1,152 @@
+#ifndef HEADER_CURL_MULTIHANDLE_H
+#define HEADER_CURL_MULTIHANDLE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "conncache.h"
+
+struct Curl_message {
+  /* the 'CURLMsg' is the part that is visible to the external user */
+  struct CURLMsg extmsg;
+};
+
+/* NOTE: if you add a state here, add the name to the statename[] array as
+   well!
+*/
+typedef enum {
+  CURLM_STATE_INIT,         /* 0 - start in this state */
+  CURLM_STATE_CONNECT_PEND, /* 1 - no connections, waiting for one */
+  CURLM_STATE_CONNECT,      /* 2 - resolve/connect has been sent off */
+  CURLM_STATE_WAITRESOLVE,  /* 3 - awaiting the resolve to finalize */
+  CURLM_STATE_WAITCONNECT,  /* 4 - awaiting the TCP connect to finalize */
+  CURLM_STATE_WAITPROXYCONNECT, /* 5 - awaiting proxy CONNECT to finalize */
+  CURLM_STATE_SENDPROTOCONNECT, /* 6 - initiate protocol connect procedure */
+  CURLM_STATE_PROTOCONNECT, /* 7 - completing the protocol-specific connect
+                                   phase */
+  CURLM_STATE_WAITDO,       /* 8 - wait for our turn to send the request */
+  CURLM_STATE_DO,           /* 9 - start send off the request (part 1) */
+  CURLM_STATE_DOING,        /* 10 - sending off the request (part 1) */
+  CURLM_STATE_DO_MORE,      /* 11 - send off the request (part 2) */
+  CURLM_STATE_DO_DONE,      /* 12 - done sending off request */
+  CURLM_STATE_WAITPERFORM,  /* 13 - wait for our turn to read the response */
+  CURLM_STATE_PERFORM,      /* 14 - transfer data */
+  CURLM_STATE_TOOFAST,      /* 15 - wait because limit-rate exceeded */
+  CURLM_STATE_DONE,         /* 16 - post data transfer operation */
+  CURLM_STATE_COMPLETED,    /* 17 - operation complete */
+  CURLM_STATE_MSGSENT,      /* 18 - the operation complete message is sent */
+  CURLM_STATE_LAST          /* 19 - not a true state, never use this */
+} CURLMstate;
+
+/* we support N sockets per easy handle. Set the corresponding bit to what
+   action we should wait for */
+#define MAX_SOCKSPEREASYHANDLE 5
+#define GETSOCK_READABLE (0x00ff)
+#define GETSOCK_WRITABLE (0xff00)
+
+#define CURLPIPE_ANY (CURLPIPE_HTTP1 | CURLPIPE_MULTIPLEX)
+
+/* This is the struct known as CURLM on the outside */
+struct Curl_multi {
+  /* First a simple identifier to easier detect if a user mix up
+     this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */
+  long type;
+
+  /* We have a doubly-linked circular list with easy handles */
+  struct SessionHandle *easyp;
+  struct SessionHandle *easylp; /* last node */
+
+  int num_easy; /* amount of entries in the linked list above. */
+  int num_alive; /* amount of easy handles that are added but have not yet
+                    reached COMPLETE state */
+
+  struct curl_llist *msglist; /* a list of messages from completed transfers */
+
+  struct curl_llist *pending; /* SessionHandles that are in the
+                                 CURLM_STATE_CONNECT_PEND state */
+
+  /* callback function and user data pointer for the *socket() API */
+  curl_socket_callback socket_cb;
+  void *socket_userp;
+
+  /* callback function and user data pointer for server push */
+  curl_push_callback push_cb;
+  void *push_userp;
+
+  /* Hostname cache */
+  struct curl_hash hostcache;
+
+  /* timetree points to the splay-tree of time nodes to figure out expire
+     times of all currently set timers */
+  struct Curl_tree *timetree;
+
+  /* 'sockhash' is the lookup hash for socket descriptor => easy handles (note
+     the pluralis form, there can be more than one easy handle waiting on the
+     same actual socket) */
+  struct curl_hash sockhash;
+
+  /* pipelining wanted bits (CURLPIPE*) */
+  long pipelining;
+
+  bool recheckstate; /* see Curl_multi_connchanged */
+
+  /* Shared connection cache (bundles)*/
+  struct conncache conn_cache;
+
+  /* This handle will be used for closing the cached connections in
+     curl_multi_cleanup() */
+  struct SessionHandle *closure_handle;
+
+  long maxconnects; /* if >0, a fixed limit of the maximum number of entries
+                       we're allowed to grow the connection cache to */
+
+  long max_host_connections; /* if >0, a fixed limit of the maximum number
+                                of connections per host */
+
+  long max_total_connections; /* if >0, a fixed limit of the maximum number
+                                 of connections in total */
+
+  long max_pipeline_length; /* if >0, maximum number of requests in a
+                               pipeline */
+
+  long content_length_penalty_size; /* a connection with a
+                                       content-length bigger than
+                                       this is not considered
+                                       for pipelining */
+
+  long chunk_length_penalty_size; /* a connection with a chunk length
+                                     bigger than this is not
+                                     considered for pipelining */
+
+  struct curl_llist *pipelining_site_bl; /* List of sites that are blacklisted
+                                            from pipelining */
+
+  struct curl_llist *pipelining_server_bl; /* List of server types that are
+                                              blacklisted from pipelining */
+
+  /* timer callback and user data pointer for the *socket() API */
+  curl_multi_timer_callback timer_cb;
+  void *timer_userp;
+  struct timeval timer_lastcall; /* the fixed time for the timeout for the
+                                    previous callback */
+};
+
+#endif /* HEADER_CURL_MULTIHANDLE_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/multiif.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/multiif.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/multiif.h	(revision 164)
@@ -0,0 +1,97 @@
+#ifndef HEADER_CURL_MULTIIF_H
+#define HEADER_CURL_MULTIIF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Prototypes for library-wide functions provided by multi.c
+ */
+void Curl_expire(struct SessionHandle *data, long milli);
+void Curl_expire_latest(struct SessionHandle *data, long milli);
+bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits);
+void Curl_multi_handlePipeBreak(struct SessionHandle *data);
+
+/* Internal version of curl_multi_init() accepts size parameters for the
+   socket and connection hashes */
+struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize);
+
+/* the write bits start at bit 16 for the *getsock() bitmap */
+#define GETSOCK_WRITEBITSTART 16
+
+#define GETSOCK_BLANK 0 /* no bits set */
+
+/* set the bit for the given sock number to make the bitmap for writable */
+#define GETSOCK_WRITESOCK(x) (1 << (GETSOCK_WRITEBITSTART + (x)))
+
+/* set the bit for the given sock number to make the bitmap for readable */
+#define GETSOCK_READSOCK(x) (1 << (x))
+
+#ifdef DEBUGBUILD
+ /*
+  * Curl_multi_dump is not a stable public function, this is only meant to
+  * allow easier tracking of the internal handle's state and what sockets
+  * they use. Only for research and development DEBUGBUILD enabled builds.
+  */
+void Curl_multi_dump(const struct Curl_multi *multi_handle);
+#endif
+
+void Curl_multi_process_pending_handles(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_MAX_HOST_CONNECTIONS option */
+size_t Curl_multi_max_host_connections(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE option */
+curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE option */
+curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_PIPELINING_SITE_BL option */
+struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_PIPELINING_SERVER_BL option */
+struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */
+size_t Curl_multi_max_total_connections(struct Curl_multi *multi);
+
+void Curl_multi_connchanged(struct Curl_multi *multi);
+
+/*
+ * Curl_multi_closed()
+ *
+ * Used by the connect code to tell the multi_socket code that one of the
+ * sockets we were using is about to be closed.  This function will then
+ * remove it from the sockethash for this handle to make the multi_socket API
+ * behave properly, especially for the case when libcurl will create another
+ * socket again and it gets the same file descriptor number.
+ */
+
+void Curl_multi_closed(struct connectdata *conn, curl_socket_t s);
+
+/*
+ * Add a handle and move it into PERFORM state at once. For pushed streams.
+ */
+CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
+                                 struct SessionHandle *data,
+                                 struct connectdata *conn);
+#endif /* HEADER_CURL_MULTIIF_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/netrc.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/netrc.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/netrc.c	(revision 164)
@@ -0,0 +1,203 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#include <curl/curl.h>
+#include "netrc.h"
+
+#include "strequal.h"
+#include "strtok.h"
+#include "rawstr.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Get user and password from .netrc when given a machine name */
+
+enum host_lookup_state {
+  NOTHING,
+  HOSTFOUND,    /* the 'machine' keyword was found */
+  HOSTVALID     /* this is "our" machine! */
+};
+
+/*
+ * @unittest: 1304
+ *
+ * *loginp and *passwordp MUST be allocated if they aren't NULL when passed
+ * in.
+ */
+int Curl_parsenetrc(const char *host,
+                    char **loginp,
+                    char **passwordp,
+                    char *netrcfile)
+{
+  FILE *file;
+  int retcode=1;
+  int specific_login = (*loginp && **loginp != 0);
+  bool netrc_alloc = FALSE;
+  enum host_lookup_state state=NOTHING;
+
+  char state_login=0;      /* Found a login keyword */
+  char state_password=0;   /* Found a password keyword */
+  int state_our_login=FALSE;  /* With specific_login, found *our* login name */
+
+#define NETRC DOT_CHAR "netrc"
+
+  if(!netrcfile) {
+    bool home_alloc = FALSE;
+    char *home = curl_getenv("HOME"); /* portable environment reader */
+    if(home) {
+      home_alloc = TRUE;
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
+    }
+    else {
+      struct passwd pw, *pw_res;
+      char pwbuf[1024];
+      if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res)
+         && pw_res) {
+        home = strdup(pw.pw_dir);
+        if(!home)
+          return CURLE_OUT_OF_MEMORY;
+        home_alloc = TRUE;
+      }
+#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
+    }
+    else {
+      struct passwd *pw;
+      pw= getpwuid(geteuid());
+      if(pw) {
+        home = pw->pw_dir;
+      }
+#endif
+    }
+
+    if(!home)
+      return retcode; /* no home directory found (or possibly out of memory) */
+
+    netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC);
+    if(home_alloc)
+      free(home);
+    if(!netrcfile) {
+      return -1;
+    }
+    netrc_alloc = TRUE;
+  }
+
+  file = fopen(netrcfile, FOPEN_READTEXT);
+  if(netrc_alloc)
+    free(netrcfile);
+  if(file) {
+    char *tok;
+    char *tok_buf;
+    bool done=FALSE;
+    char netrcbuffer[256];
+    int  netrcbuffsize = (int)sizeof(netrcbuffer);
+
+    while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {
+      tok=strtok_r(netrcbuffer, " \t\n", &tok_buf);
+      while(!done && tok) {
+
+        if((*loginp && **loginp) && (*passwordp && **passwordp)) {
+          done=TRUE;
+          break;
+        }
+
+        switch(state) {
+        case NOTHING:
+          if(Curl_raw_equal("machine", tok)) {
+            /* the next tok is the machine name, this is in itself the
+               delimiter that starts the stuff entered for this machine,
+               after this we need to search for 'login' and
+               'password'. */
+            state=HOSTFOUND;
+          }
+          else if(Curl_raw_equal("default", tok)) {
+            state=HOSTVALID;
+            retcode=0; /* we did find our host */
+          }
+          break;
+        case HOSTFOUND:
+          if(Curl_raw_equal(host, tok)) {
+            /* and yes, this is our host! */
+            state=HOSTVALID;
+            retcode=0; /* we did find our host */
+          }
+          else
+            /* not our host */
+            state=NOTHING;
+          break;
+        case HOSTVALID:
+          /* we are now parsing sub-keywords concerning "our" host */
+          if(state_login) {
+            if(specific_login) {
+              state_our_login = Curl_raw_equal(*loginp, tok);
+            }
+            else {
+              free(*loginp);
+              *loginp = strdup(tok);
+              if(!*loginp) {
+                retcode = -1; /* allocation failed */
+                goto out;
+              }
+            }
+            state_login=0;
+          }
+          else if(state_password) {
+            if(state_our_login || !specific_login) {
+              free(*passwordp);
+              *passwordp = strdup(tok);
+              if(!*passwordp) {
+                retcode = -1; /* allocation failed */
+                goto out;
+              }
+            }
+            state_password=0;
+          }
+          else if(Curl_raw_equal("login", tok))
+            state_login=1;
+          else if(Curl_raw_equal("password", tok))
+            state_password=1;
+          else if(Curl_raw_equal("machine", tok)) {
+            /* ok, there's machine here go => */
+            state = HOSTFOUND;
+            state_our_login = FALSE;
+          }
+          break;
+        } /* switch (state) */
+
+        tok = strtok_r(NULL, " \t\n", &tok_buf);
+      } /* while(tok) */
+    } /* while fgets() */
+
+    out:
+    fclose(file);
+  }
+
+  return retcode;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/netrc.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/netrc.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/netrc.h	(revision 164)
@@ -0,0 +1,36 @@
+#ifndef HEADER_CURL_NETRC_H
+#define HEADER_CURL_NETRC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
+int Curl_parsenetrc(const char *host,
+                    char **loginp,
+                    char **passwordp,
+                    char *filename);
+  /* Assume: (*passwordp)[0]=0, host[0] != 0.
+   * If (*loginp)[0] = 0, search for login and password within a machine
+   * section in the netrc.
+   * If (*loginp)[0] != 0, search for password within machine and login.
+   */
+
+#endif /* HEADER_CURL_NETRC_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/non-ascii.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/non-ascii.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/non-ascii.c	(revision 164)
@@ -0,0 +1,338 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef CURL_DOES_CONVERSIONS
+
+#include <curl/curl.h>
+
+#include "non-ascii.h"
+#include "formdata.h"
+#include "sendf.h"
+#include "urldata.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifdef HAVE_ICONV
+#include <iconv.h>
+/* set default codesets for iconv */
+#ifndef CURL_ICONV_CODESET_OF_NETWORK
+#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
+#endif
+#ifndef CURL_ICONV_CODESET_FOR_UTF8
+#define CURL_ICONV_CODESET_FOR_UTF8   "UTF-8"
+#endif
+#define ICONV_ERROR  (size_t)-1
+#endif /* HAVE_ICONV */
+
+/*
+ * Curl_convert_clone() returns a malloced copy of the source string (if
+ * returning CURLE_OK), with the data converted to network format.
+ */
+CURLcode Curl_convert_clone(struct SessionHandle *data,
+                           const char *indata,
+                           size_t insize,
+                           char **outbuf)
+{
+  char *convbuf;
+  CURLcode result;
+
+  convbuf = malloc(insize);
+  if(!convbuf)
+    return CURLE_OUT_OF_MEMORY;
+
+  memcpy(convbuf, indata, insize);
+  result = Curl_convert_to_network(data, convbuf, insize);
+  if(result) {
+    free(convbuf);
+    return result;
+  }
+
+  *outbuf = convbuf; /* return the converted buffer */
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_convert_to_network() is an internal function for performing ASCII
+ * conversions on non-ASCII platforms. It convers the buffer _in place_.
+ */
+CURLcode Curl_convert_to_network(struct SessionHandle *data,
+                                 char *buffer, size_t length)
+{
+  if(data->set.convtonetwork) {
+    /* use translation callback */
+    CURLcode result = data->set.convtonetwork(buffer, length);
+    if(result) {
+      failf(data,
+            "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s",
+            (int)result, curl_easy_strerror(result));
+    }
+
+    return result;
+  }
+  else {
+#ifdef HAVE_ICONV
+    /* do the translation ourselves */
+    char *input_ptr, *output_ptr;
+    size_t in_bytes, out_bytes, rc;
+    int error;
+
+    /* open an iconv conversion descriptor if necessary */
+    if(data->outbound_cd == (iconv_t)-1) {
+      data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
+                                     CURL_ICONV_CODESET_OF_HOST);
+      if(data->outbound_cd == (iconv_t)-1) {
+        error = ERRNO;
+        failf(data,
+              "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
+              CURL_ICONV_CODESET_OF_NETWORK,
+              CURL_ICONV_CODESET_OF_HOST,
+              error, strerror(error));
+        return CURLE_CONV_FAILED;
+      }
+    }
+    /* call iconv */
+    input_ptr = output_ptr = buffer;
+    in_bytes = out_bytes = length;
+    rc = iconv(data->outbound_cd, (const char**)&input_ptr, &in_bytes,
+               &output_ptr, &out_bytes);
+    if((rc == ICONV_ERROR) || (in_bytes != 0)) {
+      error = ERRNO;
+      failf(data,
+            "The Curl_convert_to_network iconv call failed with errno %i: %s",
+            error, strerror(error));
+      return CURLE_CONV_FAILED;
+    }
+#else
+    failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
+    return CURLE_CONV_REQD;
+#endif /* HAVE_ICONV */
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_convert_from_network() is an internal function for performing ASCII
+ * conversions on non-ASCII platforms. It convers the buffer _in place_.
+ */
+CURLcode Curl_convert_from_network(struct SessionHandle *data,
+                                   char *buffer, size_t length)
+{
+  if(data->set.convfromnetwork) {
+    /* use translation callback */
+    CURLcode result = data->set.convfromnetwork(buffer, length);
+    if(result) {
+      failf(data,
+            "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s",
+            (int)result, curl_easy_strerror(result));
+    }
+
+    return result;
+  }
+  else {
+#ifdef HAVE_ICONV
+    /* do the translation ourselves */
+    char *input_ptr, *output_ptr;
+    size_t in_bytes, out_bytes, rc;
+    int error;
+
+    /* open an iconv conversion descriptor if necessary */
+    if(data->inbound_cd == (iconv_t)-1) {
+      data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+                                    CURL_ICONV_CODESET_OF_NETWORK);
+      if(data->inbound_cd == (iconv_t)-1) {
+        error = ERRNO;
+        failf(data,
+              "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
+              CURL_ICONV_CODESET_OF_HOST,
+              CURL_ICONV_CODESET_OF_NETWORK,
+              error, strerror(error));
+        return CURLE_CONV_FAILED;
+      }
+    }
+    /* call iconv */
+    input_ptr = output_ptr = buffer;
+    in_bytes = out_bytes = length;
+    rc = iconv(data->inbound_cd, (const char **)&input_ptr, &in_bytes,
+               &output_ptr, &out_bytes);
+    if((rc == ICONV_ERROR) || (in_bytes != 0)) {
+      error = ERRNO;
+      failf(data,
+            "Curl_convert_from_network iconv call failed with errno %i: %s",
+            error, strerror(error));
+      return CURLE_CONV_FAILED;
+    }
+#else
+    failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
+    return CURLE_CONV_REQD;
+#endif /* HAVE_ICONV */
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_convert_from_utf8() is an internal function for performing UTF-8
+ * conversions on non-ASCII platforms.
+ */
+CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
+                                char *buffer, size_t length)
+{
+  if(data->set.convfromutf8) {
+    /* use translation callback */
+    CURLcode result = data->set.convfromutf8(buffer, length);
+    if(result) {
+      failf(data,
+            "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s",
+            (int)result, curl_easy_strerror(result));
+    }
+
+    return result;
+  }
+  else {
+#ifdef HAVE_ICONV
+    /* do the translation ourselves */
+    const char *input_ptr;
+    char *output_ptr;
+    size_t in_bytes, out_bytes, rc;
+    int error;
+
+    /* open an iconv conversion descriptor if necessary */
+    if(data->utf8_cd == (iconv_t)-1) {
+      data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+                                 CURL_ICONV_CODESET_FOR_UTF8);
+      if(data->utf8_cd == (iconv_t)-1) {
+        error = ERRNO;
+        failf(data,
+              "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
+              CURL_ICONV_CODESET_OF_HOST,
+              CURL_ICONV_CODESET_FOR_UTF8,
+              error, strerror(error));
+        return CURLE_CONV_FAILED;
+      }
+    }
+    /* call iconv */
+    input_ptr = output_ptr = buffer;
+    in_bytes = out_bytes = length;
+    rc = iconv(data->utf8_cd, &input_ptr, &in_bytes,
+               &output_ptr, &out_bytes);
+    if((rc == ICONV_ERROR) || (in_bytes != 0)) {
+      error = ERRNO;
+      failf(data,
+            "The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
+            error, strerror(error));
+      return CURLE_CONV_FAILED;
+    }
+    if(output_ptr < input_ptr) {
+      /* null terminate the now shorter output string */
+      *output_ptr = 0x00;
+    }
+#else
+    failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
+    return CURLE_CONV_REQD;
+#endif /* HAVE_ICONV */
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Init conversion stuff for a SessionHandle
+ */
+void Curl_convert_init(struct SessionHandle *data)
+{
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+  /* conversion descriptors for iconv calls */
+  data->outbound_cd = (iconv_t)-1;
+  data->inbound_cd  = (iconv_t)-1;
+  data->utf8_cd     = (iconv_t)-1;
+#else
+  (void)data;
+#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
+}
+
+/*
+ * Setup conversion stuff for a SessionHandle
+ */
+void Curl_convert_setup(struct SessionHandle *data)
+{
+  data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+                                CURL_ICONV_CODESET_OF_NETWORK);
+  data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
+                                 CURL_ICONV_CODESET_OF_HOST);
+  data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+                             CURL_ICONV_CODESET_FOR_UTF8);
+}
+
+/*
+ * Close conversion stuff for a SessionHandle
+ */
+
+void Curl_convert_close(struct SessionHandle *data)
+{
+#ifdef HAVE_ICONV
+  /* close iconv conversion descriptors */
+  if(data->inbound_cd != (iconv_t)-1) {
+    iconv_close(data->inbound_cd);
+  }
+  if(data->outbound_cd != (iconv_t)-1) {
+    iconv_close(data->outbound_cd);
+  }
+  if(data->utf8_cd != (iconv_t)-1) {
+    iconv_close(data->utf8_cd);
+  }
+#else
+  (void)data;
+#endif /* HAVE_ICONV */
+}
+
+/*
+ * Curl_convert_form() is used from http.c, this converts any form items that
+   need to be sent in the network encoding.  Returns CURLE_OK on success.
+ */
+CURLcode Curl_convert_form(struct SessionHandle *data, struct FormData *form)
+{
+  CURLcode result;
+
+  if(!data)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  while(form) {
+    if(form->type == FORM_DATA) {
+      result = Curl_convert_to_network(data, form->line, form->length);
+      /* Curl_convert_to_network calls failf if unsuccessful */
+      if(result)
+        return result;
+    }
+
+    form = form->next;
+  }
+
+  return CURLE_OK;
+}
+
+#endif /* CURL_DOES_CONVERSIONS */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/non-ascii.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/non-ascii.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/non-ascii.h	(revision 164)
@@ -0,0 +1,63 @@
+#ifndef HEADER_CURL_NON_ASCII_H
+#define HEADER_CURL_NON_ASCII_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef CURL_DOES_CONVERSIONS
+
+#include "urldata.h"
+
+/*
+ * Curl_convert_clone() returns a malloced copy of the source string (if
+ * returning CURLE_OK), with the data converted to network format.
+ *
+ * If no conversion was needed *outbuf may be NULL.
+ */
+CURLcode Curl_convert_clone(struct SessionHandle *data,
+                            const char *indata,
+                            size_t insize,
+                            char **outbuf);
+
+void Curl_convert_init(struct SessionHandle *data);
+void Curl_convert_setup(struct SessionHandle *data);
+void Curl_convert_close(struct SessionHandle *data);
+
+CURLcode Curl_convert_to_network(struct SessionHandle *data,
+                                 char *buffer, size_t length);
+CURLcode Curl_convert_from_network(struct SessionHandle *data,
+                                 char *buffer, size_t length);
+CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
+                                 char *buffer, size_t length);
+CURLcode Curl_convert_form(struct SessionHandle *data, struct FormData *form);
+#else
+#define Curl_convert_clone(a,b,c,d) ((void)a, CURLE_OK)
+#define Curl_convert_init(x) Curl_nop_stmt
+#define Curl_convert_setup(x) Curl_nop_stmt
+#define Curl_convert_close(x) Curl_nop_stmt
+#define Curl_convert_to_network(a,b,c) ((void)a, CURLE_OK)
+#define Curl_convert_from_network(a,b,c) ((void)a, CURLE_OK)
+#define Curl_convert_from_utf8(a,b,c) ((void)a, CURLE_OK)
+#define Curl_convert_form(a,b) CURLE_OK
+#endif
+
+#endif /* HEADER_CURL_NON_ASCII_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/nonblock.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/nonblock.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/nonblock.c	(revision 164)
@@ -0,0 +1,91 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE))
+#include <sys/filio.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#include "nonblock.h"
+
+/*
+ * curlx_nonblock() set the given socket to either blocking or non-blocking
+ * mode based on the 'nonblock' boolean argument. This function is highly
+ * portable.
+ */
+int curlx_nonblock(curl_socket_t sockfd,    /* operate on this */
+                   int nonblock   /* TRUE or FALSE */)
+{
+#if defined(USE_BLOCKING_SOCKETS)
+
+  return 0; /* returns success */
+
+#elif defined(HAVE_FCNTL_O_NONBLOCK)
+
+  /* most recent unix versions */
+  int flags;
+  flags = sfcntl(sockfd, F_GETFL, 0);
+  if(nonblock)
+    return sfcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
+  else
+    return sfcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
+
+#elif defined(HAVE_IOCTL_FIONBIO)
+
+  /* older unix versions */
+  int flags = nonblock ? 1 : 0;
+  return ioctl(sockfd, FIONBIO, &flags);
+
+#elif defined(HAVE_IOCTLSOCKET_FIONBIO)
+
+  /* Windows */
+  unsigned long flags = nonblock ? 1UL : 0UL;
+  return ioctlsocket(sockfd, FIONBIO, &flags);
+
+#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
+
+  /* Amiga */
+  long flags = nonblock ? 1L : 0L;
+  return IoctlSocket(sockfd, FIONBIO, (char *)&flags);
+
+#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
+
+  /* BeOS */
+  long b = nonblock ? 1L : 0L;
+  return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
+
+#else
+#  error "no non-blocking method was found/used/set"
+#endif
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/nonblock.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/nonblock.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/nonblock.h	(revision 164)
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_NONBLOCK_H
+#define HEADER_CURL_NONBLOCK_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h> /* for curl_socket_t */
+
+int curlx_nonblock(curl_socket_t sockfd,    /* operate on this */
+                   int nonblock   /* TRUE or FALSE */);
+
+#endif /* HEADER_CURL_NONBLOCK_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/nwlib.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/nwlib.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/nwlib.c	(revision 164)
@@ -0,0 +1,325 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef NETWARE /* Novell NetWare */
+
+#ifdef __NOVELL_LIBC__
+/* For native LibC-based NLM we need to register as a real lib. */
+#include <library.h>
+#include <netware.h>
+#include <screen.h>
+#include <nks/thread.h>
+#include <nks/synch.h>
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct
+{
+  int     _errno;
+  void    *twentybytes;
+} libthreaddata_t;
+
+typedef struct
+{
+  int         x;
+  int         y;
+  int         z;
+  void        *tenbytes;
+  NXKey_t     perthreadkey;   /* if -1, no key obtained... */
+  NXMutex_t   *lock;
+} libdata_t;
+
+int         gLibId      = -1;
+void        *gLibHandle = (void *) NULL;
+rtag_t      gAllocTag   = (rtag_t) NULL;
+NXMutex_t   *gLibLock   = (NXMutex_t *) NULL;
+
+/* internal library function prototypes... */
+int  DisposeLibraryData( void * );
+void DisposeThreadData( void * );
+int  GetOrSetUpData( int id, libdata_t **data, libthreaddata_t **threaddata );
+
+
+int _NonAppStart( void        *NLMHandle,
+                  void        *errorScreen,
+                  const char  *cmdLine,
+                  const char  *loadDirPath,
+                  size_t      uninitializedDataLength,
+                  void        *NLMFileHandle,
+                  int         (*readRoutineP)( int conn,
+                                               void *fileHandle, size_t offset,
+                                               size_t nbytes,
+                                               size_t *bytesRead,
+                                               void *buffer ),
+                  size_t      customDataOffset,
+                  size_t      customDataSize,
+                  int         messageCount,
+                  const char  **messages )
+{
+  NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0);
+
+#ifndef __GNUC__
+#pragma unused(cmdLine)
+#pragma unused(loadDirPath)
+#pragma unused(uninitializedDataLength)
+#pragma unused(NLMFileHandle)
+#pragma unused(readRoutineP)
+#pragma unused(customDataOffset)
+#pragma unused(customDataSize)
+#pragma unused(messageCount)
+#pragma unused(messages)
+#endif
+
+  /*
+   * Here we process our command line, post errors (to the error screen),
+   * perform initializations and anything else we need to do before being able
+   * to accept calls into us. If we succeed, we return non-zero and the NetWare
+   * Loader will leave us up, otherwise we fail to load and get dumped.
+   */
+  gAllocTag = AllocateResourceTag(NLMHandle,
+                                  "<library-name> memory allocations",
+                                  AllocSignature);
+
+  if(!gAllocTag) {
+    OutputToScreen(errorScreen, "Unable to allocate resource tag for "
+                   "library memory allocations.\n");
+    return -1;
+  }
+
+  gLibId = register_library(DisposeLibraryData);
+
+  if(gLibId < -1) {
+    OutputToScreen(errorScreen, "Unable to register library with kernel.\n");
+    return -1;
+  }
+
+  gLibHandle = NLMHandle;
+
+  gLibLock = NXMutexAlloc(0, 0, &liblock);
+
+  if(!gLibLock) {
+    OutputToScreen(errorScreen, "Unable to allocate library data lock.\n");
+    return -1;
+  }
+
+  return 0;
+}
+
+/*
+ * Here we clean up any resources we allocated. Resource tags is a big part
+ * of what we created, but NetWare doesn't ask us to free those.
+ */
+void _NonAppStop( void )
+{
+  (void) unregister_library(gLibId);
+  NXMutexFree(gLibLock);
+}
+
+/*
+ * This function cannot be the first in the file for if the file is linked
+ * first, then the check-unload function's offset will be nlmname.nlm+0
+ * which is how to tell that there isn't one. When the check function is
+ * first in the linked objects, it is ambiguous. For this reason, we will
+ * put it inside this file after the stop function.
+ *
+ * Here we check to see if it's alright to ourselves to be unloaded. If not,
+ * we return a non-zero value. Right now, there isn't any reason not to allow
+ * it.
+ */
+int _NonAppCheckUnload( void )
+{
+    return 0;
+}
+
+int GetOrSetUpData(int id, libdata_t **appData,
+                   libthreaddata_t **threadData )
+{
+  int                 err;
+  libdata_t           *app_data;
+  libthreaddata_t *thread_data;
+  NXKey_t             key;
+  NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);
+
+  err         = 0;
+  thread_data = (libthreaddata_t *) NULL;
+
+  /*
+   * Attempt to get our data for the application calling us. This is where we
+   * store whatever application-specific information we need to carry in
+   * support of calling applications.
+   */
+  app_data = (libdata_t *) get_app_data(id);
+
+  if(!app_data) {
+    /*
+     * This application hasn't called us before; set up application AND
+     * per-thread data. Of course, just in case a thread from this same
+     * application is calling us simultaneously, we better lock our application
+     * data-creation mutex. We also need to recheck for data after we acquire
+     * the lock because WE might be that other thread that was too late to
+     * create the data and the first thread in will have created it.
+     */
+    NXLock(gLibLock);
+
+    if(!(app_data = (libdata_t *) get_app_data(id))) {
+      app_data = malloc(sizeof(libdata_t));
+
+      if(app_data) {
+        memset(app_data, 0, sizeof(libdata_t));
+
+        app_data->tenbytes = malloc(10);
+        app_data->lock     = NXMutexAlloc(0, 0, &liblock);
+
+        if(!app_data->tenbytes || !app_data->lock) {
+          if(app_data->lock)
+            NXMutexFree(app_data->lock);
+
+          free(app_data);
+          app_data = (libdata_t *) NULL;
+          err      = ENOMEM;
+        }
+
+        if(app_data) {
+          /*
+           * Here we burn in the application data that we were trying to get
+           * by calling get_app_data(). Next time we call the first function,
+           * we'll get this data we're just now setting. We also go on here to
+           * establish the per-thread data for the calling thread, something
+           * we'll have to do on each application thread the first time
+           * it calls us.
+           */
+          err = set_app_data(gLibId, app_data);
+
+          if(err) {
+            free(app_data);
+            app_data = (libdata_t *) NULL;
+            err      = ENOMEM;
+          }
+          else {
+            /* create key for thread-specific data... */
+            err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key);
+
+            if(err)                /* (no more keys left?) */
+              key = -1;
+
+            app_data->perthreadkey = key;
+          }
+        }
+      }
+    }
+
+    NXUnlock(gLibLock);
+  }
+
+  if(app_data) {
+    key = app_data->perthreadkey;
+
+    if(key != -1 /* couldn't create a key? no thread data */
+        && !(err = NXKeyGetValue(key, (void **) &thread_data))
+        && !thread_data) {
+      /*
+       * Allocate the per-thread data for the calling thread. Regardless of
+       * whether there was already application data or not, this may be the
+       * first call by a new thread. The fact that we allocation 20 bytes on
+       * a pointer is not very important, this just helps to demonstrate that
+       * we can have arbitrarily complex per-thread data.
+       */
+      thread_data = malloc(sizeof(libthreaddata_t));
+
+      if(thread_data) {
+        thread_data->_errno      = 0;
+        thread_data->twentybytes = malloc(20);
+
+        if(!thread_data->twentybytes) {
+          free(thread_data);
+          thread_data = (libthreaddata_t *) NULL;
+          err         = ENOMEM;
+        }
+
+        if((err = NXKeySetValue(key, thread_data))) {
+          free(thread_data->twentybytes);
+          free(thread_data);
+          thread_data = (libthreaddata_t *) NULL;
+        }
+      }
+    }
+  }
+
+  if(appData)
+    *appData = app_data;
+
+  if(threadData)
+    *threadData = thread_data;
+
+  return err;
+}
+
+int DisposeLibraryData( void *data )
+{
+  if(data) {
+    void *tenbytes = ((libdata_t *) data)->tenbytes;
+
+    free(tenbytes);
+    free(data);
+  }
+
+  return 0;
+}
+
+void DisposeThreadData( void *data )
+{
+  if(data) {
+    void *twentybytes = ((libthreaddata_t *) data)->twentybytes;
+
+    free(twentybytes);
+    free(data);
+  }
+}
+
+#else /* __NOVELL_LIBC__ */
+/* For native CLib-based NLM seems we can do a bit more simple. */
+#include <nwthread.h>
+
+int main ( void )
+{
+  /* initialize any globals here... */
+
+  /* do this if any global initializing was done
+  SynchronizeStart();
+  */
+  ExitThread (TSR_THREAD, 0);
+  return 0;
+}
+
+#endif /* __NOVELL_LIBC__ */
+
+#else /* NETWARE */
+
+#ifdef __POCC__
+#  pragma warn(disable:2024)  /* Disable warning #2024: Empty input file */
+#endif
+
+#endif /* NETWARE */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/nwos.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/nwos.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/nwos.c	(revision 164)
@@ -0,0 +1,88 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef NETWARE /* Novell NetWare */
+
+#ifdef __NOVELL_LIBC__
+/* For native LibC-based NLM we need to do nothing. */
+int netware_init ( void )
+{
+  return 0;
+}
+
+#else /* __NOVELL_LIBC__ */
+
+/* For native CLib-based NLM we need to initialize the LONG namespace. */
+#include <nwnspace.h>
+#include <nwthread.h>
+#include <nwadv.h>
+/* Make the CLIB Ctx stuff link */
+#include <netdb.h>
+NETDB_DEFINE_CONTEXT
+/* Make the CLIB Inet stuff link */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+NETINET_DEFINE_CONTEXT
+
+int netware_init ( void )
+{
+  int rc = 0;
+  unsigned int myHandle = GetNLMHandle();
+  /* import UnAugmentAsterisk dynamically for NW4.x compatibility */
+  void (*pUnAugmentAsterisk)(int) = (void(*)(int))
+          ImportSymbol(myHandle, "UnAugmentAsterisk");
+  /* import UseAccurateCaseForPaths dynamically for NW3.x compatibility */
+  void (*pUseAccurateCaseForPaths)(int) = (void(*)(int))
+          ImportSymbol(myHandle, "UseAccurateCaseForPaths");
+  if(pUnAugmentAsterisk)
+    pUnAugmentAsterisk(1);
+  if(pUseAccurateCaseForPaths)
+    pUseAccurateCaseForPaths(1);
+  UnimportSymbol(myHandle, "UnAugmentAsterisk");
+  UnimportSymbol(myHandle, "UseAccurateCaseForPaths");
+  /* set long name space */
+  if((SetCurrentNameSpace(4) == 255)) {
+    rc = 1;
+  }
+  if((SetTargetNameSpace(4) == 255)) {
+    rc = rc + 2;
+  }
+  return rc;
+}
+
+/* dummy function to satisfy newer prelude */
+int __init_environment ( void )
+{
+  return 0;
+}
+
+/* dummy function to satisfy newer prelude */
+int __deinit_environment ( void )
+{
+  return 0;
+}
+
+#endif /* __NOVELL_LIBC__ */
+
+#endif /* NETWARE */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/openldap.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/openldap.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/openldap.c	(revision 164)
@@ -0,0 +1,712 @@
+/***************************************************************************
+ *                      _   _ ____  _
+ *  Project         ___| | | |  _ \| |
+ *                 / __| | | | |_) | |
+ *                | (__| |_| |  _ <| |___
+ *                 \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, Howard Chu, <hyc@openldap.org>
+ * Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_LDAP) && defined(USE_OPENLDAP)
+
+/*
+ * Notice that USE_OPENLDAP is only a source code selection switch. When
+ * libcurl is built with USE_OPENLDAP defined the libcurl source code that
+ * gets compiled is the code from openldap.c, otherwise the code that gets
+ * compiled is the code from ldap.c.
+ *
+ * When USE_OPENLDAP is defined a recent version of the OpenLDAP library
+ * might be required for compilation and runtime. In order to use ancient
+ * OpenLDAP library versions, USE_OPENLDAP shall not be defined.
+ */
+
+#include <ldap.h>
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "sendf.h"
+#include "vtls/vtls.h"
+#include "transfer.h"
+#include "curl_ldap.h"
+#include "curl_base64.h"
+#include "connect.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef _LDAP_PVT_H
+extern int ldap_pvt_url_scheme2proto(const char *);
+extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url,
+                        LDAP **ld);
+#endif
+
+static CURLcode ldap_setup_connection(struct connectdata *conn);
+static CURLcode ldap_do(struct connectdata *conn, bool *done);
+static CURLcode ldap_done(struct connectdata *conn, CURLcode, bool);
+static CURLcode ldap_connect(struct connectdata *conn, bool *done);
+static CURLcode ldap_connecting(struct connectdata *conn, bool *done);
+static CURLcode ldap_disconnect(struct connectdata *conn, bool dead);
+
+static Curl_recv ldap_recv;
+
+/*
+ * LDAP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ldap = {
+  "LDAP",                               /* scheme */
+  ldap_setup_connection,                /* setup_connection */
+  ldap_do,                              /* do_it */
+  ldap_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ldap_connect,                         /* connect_it */
+  ldap_connecting,                      /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ldap_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_LDAP,                            /* defport */
+  CURLPROTO_LDAP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * LDAPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ldaps = {
+  "LDAPS",                              /* scheme */
+  ldap_setup_connection,                /* setup_connection */
+  ldap_do,                              /* do_it */
+  ldap_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ldap_connect,                         /* connect_it */
+  ldap_connecting,                      /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ldap_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_LDAPS,                           /* defport */
+  CURLPROTO_LDAP,                       /* protocol */
+  PROTOPT_SSL                           /* flags */
+};
+#endif
+
+static const char *url_errs[] = {
+  "success",
+  "out of memory",
+  "bad parameter",
+  "unrecognized scheme",
+  "unbalanced delimiter",
+  "bad URL",
+  "bad host or port",
+  "bad or missing attributes",
+  "bad or missing scope",
+  "bad or missing filter",
+  "bad or missing extensions"
+};
+
+typedef struct ldapconninfo {
+  LDAP *ld;
+  Curl_recv *recv;  /* for stacking SSL handler */
+  Curl_send *send;
+  int proto;
+  int msgid;
+  bool ssldone;
+  bool sslinst;
+  bool didbind;
+} ldapconninfo;
+
+typedef struct ldapreqinfo {
+  int msgid;
+  int nument;
+} ldapreqinfo;
+
+static CURLcode ldap_setup_connection(struct connectdata *conn)
+{
+  ldapconninfo *li;
+  LDAPURLDesc *lud;
+  struct SessionHandle *data=conn->data;
+  int rc, proto;
+  CURLcode status;
+
+  rc = ldap_url_parse(data->change.url, &lud);
+  if(rc != LDAP_URL_SUCCESS) {
+    const char *msg = "url parsing problem";
+    status = CURLE_URL_MALFORMAT;
+    if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
+      if(rc == LDAP_URL_ERR_MEM)
+        status = CURLE_OUT_OF_MEMORY;
+      msg = url_errs[rc];
+    }
+    failf(conn->data, "LDAP local: %s", msg);
+    return status;
+  }
+  proto = ldap_pvt_url_scheme2proto(lud->lud_scheme);
+  ldap_free_urldesc(lud);
+
+  li = calloc(1, sizeof(ldapconninfo));
+  if(!li)
+    return CURLE_OUT_OF_MEMORY;
+  li->proto = proto;
+  conn->proto.generic = li;
+  connkeep(conn, "OpenLDAP default");
+  /* TODO:
+   * - provide option to choose SASL Binds instead of Simple
+   */
+  return CURLE_OK;
+}
+
+#ifdef USE_SSL
+static Sockbuf_IO ldapsb_tls;
+#endif
+
+static CURLcode ldap_connect(struct connectdata *conn, bool *done)
+{
+  ldapconninfo *li = conn->proto.generic;
+  struct SessionHandle *data = conn->data;
+  int rc, proto = LDAP_VERSION3;
+  char hosturl[1024];
+  char *ptr;
+
+  (void)done;
+
+  strcpy(hosturl, "ldap");
+  ptr = hosturl+4;
+  if(conn->handler->flags & PROTOPT_SSL)
+    *ptr++ = 's';
+  snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
+    conn->host.name, conn->remote_port);
+
+  rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld);
+  if(rc) {
+    failf(data, "LDAP local: Cannot connect to %s, %s",
+          hosturl, ldap_err2string(rc));
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
+
+#ifdef USE_SSL
+  if(conn->handler->flags & PROTOPT_SSL) {
+    CURLcode result;
+    result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone);
+    if(result)
+      return result;
+  }
+#endif
+
+  return CURLE_OK;
+}
+
+static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
+{
+  ldapconninfo *li = conn->proto.generic;
+  struct SessionHandle *data = conn->data;
+  LDAPMessage *msg = NULL;
+  struct timeval tv = {0, 1}, *tvp;
+  int rc, err;
+  char *info = NULL;
+
+#ifdef USE_SSL
+  if(conn->handler->flags & PROTOPT_SSL) {
+    /* Is the SSL handshake complete yet? */
+    if(!li->ssldone) {
+      CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET,
+                                                     &li->ssldone);
+      if(result || !li->ssldone)
+        return result;
+    }
+
+    /* Have we installed the libcurl SSL handlers into the sockbuf yet? */
+    if(!li->sslinst) {
+      Sockbuf *sb;
+      ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
+      ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, conn);
+      li->sslinst = TRUE;
+      li->recv = conn->recv[FIRSTSOCKET];
+      li->send = conn->send[FIRSTSOCKET];
+    }
+  }
+#endif
+
+  tvp = &tv;
+
+retry:
+  if(!li->didbind) {
+    char *binddn;
+    struct berval passwd;
+
+    if(conn->bits.user_passwd) {
+      binddn = conn->user;
+      passwd.bv_val = conn->passwd;
+      passwd.bv_len = strlen(passwd.bv_val);
+    }
+    else {
+      binddn = NULL;
+      passwd.bv_val = NULL;
+      passwd.bv_len = 0;
+    }
+    rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd,
+                        NULL, NULL, &li->msgid);
+    if(rc)
+      return CURLE_LDAP_CANNOT_BIND;
+    li->didbind = TRUE;
+    if(tvp)
+      return CURLE_OK;
+  }
+
+  rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &msg);
+  if(rc < 0) {
+    failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc));
+    return CURLE_LDAP_CANNOT_BIND;
+  }
+  if(rc == 0) {
+    /* timed out */
+    return CURLE_OK;
+  }
+
+  rc = ldap_parse_result(li->ld, msg, &err, NULL, &info, NULL, NULL, 1);
+  if(rc) {
+    failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc));
+    return CURLE_LDAP_CANNOT_BIND;
+  }
+
+  /* Try to fallback to LDAPv2? */
+  if(err == LDAP_PROTOCOL_ERROR) {
+    int proto;
+    ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
+    if(proto == LDAP_VERSION3) {
+      if(info) {
+        ldap_memfree(info);
+        info = NULL;
+      }
+      proto = LDAP_VERSION2;
+      ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
+      li->didbind = FALSE;
+      goto retry;
+    }
+  }
+
+  if(err) {
+    failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc),
+          info ? info : "");
+    if(info)
+      ldap_memfree(info);
+    return CURLE_LOGIN_DENIED;
+  }
+
+  if(info)
+    ldap_memfree(info);
+  conn->recv[FIRSTSOCKET] = ldap_recv;
+  *done = TRUE;
+
+  return CURLE_OK;
+}
+
+static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  ldapconninfo *li = conn->proto.generic;
+  (void) dead_connection;
+
+  if(li) {
+    if(li->ld) {
+      ldap_unbind_ext(li->ld, NULL, NULL);
+      li->ld = NULL;
+    }
+    conn->proto.generic = NULL;
+    free(li);
+  }
+  return CURLE_OK;
+}
+
+static CURLcode ldap_do(struct connectdata *conn, bool *done)
+{
+  ldapconninfo *li = conn->proto.generic;
+  ldapreqinfo *lr;
+  CURLcode status = CURLE_OK;
+  int rc = 0;
+  LDAPURLDesc *ludp = NULL;
+  int msgid;
+  struct SessionHandle *data=conn->data;
+
+  connkeep(conn, "OpenLDAP do");
+
+  infof(data, "LDAP local: %s\n", data->change.url);
+
+  rc = ldap_url_parse(data->change.url, &ludp);
+  if(rc != LDAP_URL_SUCCESS) {
+    const char *msg = "url parsing problem";
+    status = CURLE_URL_MALFORMAT;
+    if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
+      if(rc == LDAP_URL_ERR_MEM)
+        status = CURLE_OUT_OF_MEMORY;
+      msg = url_errs[rc];
+    }
+    failf(conn->data, "LDAP local: %s", msg);
+    return status;
+  }
+
+  rc = ldap_search_ext(li->ld, ludp->lud_dn, ludp->lud_scope,
+                       ludp->lud_filter, ludp->lud_attrs, 0,
+                       NULL, NULL, NULL, 0, &msgid);
+  ldap_free_urldesc(ludp);
+  if(rc != LDAP_SUCCESS) {
+    failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
+    return CURLE_LDAP_SEARCH_FAILED;
+  }
+  lr = calloc(1, sizeof(ldapreqinfo));
+  if(!lr)
+    return CURLE_OUT_OF_MEMORY;
+  lr->msgid = msgid;
+  data->req.protop = lr;
+  Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
+  *done = TRUE;
+  return CURLE_OK;
+}
+
+static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
+                          bool premature)
+{
+  ldapreqinfo *lr = conn->data->req.protop;
+
+  (void)res;
+  (void)premature;
+
+  if(lr) {
+    /* if there was a search in progress, abandon it */
+    if(lr->msgid) {
+      ldapconninfo *li = conn->proto.generic;
+      ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL);
+      lr->msgid = 0;
+    }
+    conn->data->req.protop = NULL;
+    free(lr);
+  }
+
+  return CURLE_OK;
+}
+
+static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
+                         size_t len, CURLcode *err)
+{
+  ldapconninfo *li = conn->proto.generic;
+  struct SessionHandle *data = conn->data;
+  ldapreqinfo *lr = data->req.protop;
+  int rc, ret;
+  LDAPMessage *msg = NULL;
+  LDAPMessage *ent;
+  BerElement *ber = NULL;
+  struct timeval tv = {0, 1};
+
+  (void)len;
+  (void)buf;
+  (void)sockindex;
+
+  rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &msg);
+  if(rc < 0) {
+    failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc));
+    *err = CURLE_RECV_ERROR;
+    return -1;
+  }
+
+  *err = CURLE_AGAIN;
+  ret = -1;
+
+  /* timed out */
+  if(!msg)
+    return ret;
+
+  for(ent = ldap_first_message(li->ld, msg); ent;
+    ent = ldap_next_message(li->ld, ent)) {
+    struct berval bv, *bvals, **bvp = &bvals;
+    int binary = 0, msgtype;
+    CURLcode writeerr;
+
+    msgtype = ldap_msgtype(ent);
+    if(msgtype == LDAP_RES_SEARCH_RESULT) {
+      int code;
+      char *info = NULL;
+      rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0);
+      if(rc) {
+        failf(data, "LDAP local: search ldap_parse_result %s",
+              ldap_err2string(rc));
+        *err = CURLE_LDAP_SEARCH_FAILED;
+      }
+      else if(code && code != LDAP_SIZELIMIT_EXCEEDED) {
+        failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc),
+              info ? info : "");
+        *err = CURLE_LDAP_SEARCH_FAILED;
+      }
+      else {
+        /* successful */
+        if(code == LDAP_SIZELIMIT_EXCEEDED)
+          infof(data, "There are more than %d entries\n", lr->nument);
+        data->req.size = data->req.bytecount;
+        *err = CURLE_OK;
+        ret = 0;
+      }
+      lr->msgid = 0;
+      ldap_memfree(info);
+      break;
+    }
+    else if(msgtype != LDAP_RES_SEARCH_ENTRY)
+      continue;
+
+    lr->nument++;
+    rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv);
+    if(rc < 0) {
+      /* TODO: verify that this is really how this return code should be
+         handled */
+      *err = CURLE_RECV_ERROR;
+      return -1;
+    }
+    writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
+    if(writeerr) {
+      *err = writeerr;
+      return -1;
+    }
+
+    writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
+                                 bv.bv_len);
+    if(writeerr) {
+      *err = writeerr;
+      return -1;
+    }
+
+    writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+    if(writeerr) {
+      *err = writeerr;
+      return -1;
+    }
+    data->req.bytecount += bv.bv_len + 5;
+
+    for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp);
+      rc == LDAP_SUCCESS;
+      rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) {
+      int i;
+
+      if(bv.bv_val == NULL) break;
+
+      if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7))
+        binary = 1;
+      else
+        binary = 0;
+
+      for(i=0; bvals[i].bv_val != NULL; i++) {
+        int binval = 0;
+        writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
+        if(writeerr) {
+          *err = writeerr;
+          return -1;
+        }
+
+       writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
+                                    bv.bv_len);
+       if(writeerr) {
+         *err = writeerr;
+         return -1;
+       }
+
+        writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
+       if(writeerr) {
+         *err = writeerr;
+         return -1;
+       }
+        data->req.bytecount += bv.bv_len + 2;
+
+        if(!binary) {
+          /* check for leading or trailing whitespace */
+          if(ISSPACE(bvals[i].bv_val[0]) ||
+              ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1]))
+            binval = 1;
+          else {
+            /* check for unprintable characters */
+            unsigned int j;
+            for(j=0; j<bvals[i].bv_len; j++)
+              if(!ISPRINT(bvals[i].bv_val[j])) {
+                binval = 1;
+                break;
+              }
+          }
+        }
+        if(binary || binval) {
+          char *val_b64 = NULL;
+          size_t val_b64_sz = 0;
+          /* Binary value, encode to base64. */
+          CURLcode error = Curl_base64_encode(data,
+                                              bvals[i].bv_val,
+                                              bvals[i].bv_len,
+                                              &val_b64,
+                                              &val_b64_sz);
+          if(error) {
+            ber_memfree(bvals);
+            ber_free(ber, 0);
+            ldap_msgfree(msg);
+            *err = error;
+            return -1;
+          }
+          writeerr = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                       (char *)": ", 2);
+          if(writeerr) {
+            *err = writeerr;
+            return -1;
+          }
+
+          data->req.bytecount += 2;
+          if(val_b64_sz > 0) {
+            writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
+                                     val_b64_sz);
+            if(writeerr) {
+              *err = writeerr;
+              return -1;
+            }
+            free(val_b64);
+            data->req.bytecount += val_b64_sz;
+          }
+        }
+        else {
+          writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
+          if(writeerr) {
+            *err = writeerr;
+            return -1;
+          }
+
+          writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
+                                       bvals[i].bv_len);
+          if(writeerr) {
+            *err = writeerr;
+            return -1;
+          }
+
+          data->req.bytecount += bvals[i].bv_len + 1;
+        }
+        writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+        if(writeerr) {
+          *err = writeerr;
+          return -1;
+        }
+
+        data->req.bytecount++;
+      }
+      ber_memfree(bvals);
+      writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+      if(writeerr) {
+        *err = writeerr;
+        return -1;
+      }
+      data->req.bytecount++;
+    }
+    writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+    if(writeerr) {
+      *err = writeerr;
+      return -1;
+    }
+    data->req.bytecount++;
+    ber_free(ber, 0);
+  }
+  ldap_msgfree(msg);
+  return ret;
+}
+
+#ifdef USE_SSL
+static int
+ldapsb_tls_setup(Sockbuf_IO_Desc *sbiod, void *arg)
+{
+  sbiod->sbiod_pvt = arg;
+  return 0;
+}
+
+static int
+ldapsb_tls_remove(Sockbuf_IO_Desc *sbiod)
+{
+  sbiod->sbiod_pvt = NULL;
+  return 0;
+}
+
+/* We don't need to do anything because libcurl does it already */
+static int
+ldapsb_tls_close(Sockbuf_IO_Desc *sbiod)
+{
+  (void)sbiod;
+  return 0;
+}
+
+static int
+ldapsb_tls_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg)
+{
+  (void)arg;
+  if(opt == LBER_SB_OPT_DATA_READY) {
+    struct connectdata *conn = sbiod->sbiod_pvt;
+    return Curl_ssl_data_pending(conn, FIRSTSOCKET);
+  }
+  return 0;
+}
+
+static ber_slen_t
+ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+{
+  struct connectdata *conn = sbiod->sbiod_pvt;
+  ldapconninfo *li = conn->proto.generic;
+  ber_slen_t ret;
+  CURLcode err = CURLE_RECV_ERROR;
+
+  ret = li->recv(conn, FIRSTSOCKET, buf, len, &err);
+  if(ret < 0 && err == CURLE_AGAIN) {
+    SET_SOCKERRNO(EWOULDBLOCK);
+  }
+  return ret;
+}
+
+static ber_slen_t
+ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+{
+  struct connectdata *conn = sbiod->sbiod_pvt;
+  ldapconninfo *li = conn->proto.generic;
+  ber_slen_t ret;
+  CURLcode err = CURLE_SEND_ERROR;
+
+  ret = li->send(conn, FIRSTSOCKET, buf, len, &err);
+  if(ret < 0 && err == CURLE_AGAIN) {
+    SET_SOCKERRNO(EWOULDBLOCK);
+  }
+  return ret;
+}
+
+static Sockbuf_IO ldapsb_tls =
+{
+  ldapsb_tls_setup,
+  ldapsb_tls_remove,
+  ldapsb_tls_ctrl,
+  ldapsb_tls_read,
+  ldapsb_tls_write,
+  ldapsb_tls_close
+};
+#endif /* USE_SSL */
+
+#endif /* !CURL_DISABLE_LDAP && USE_OPENLDAP */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/parsedate.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/parsedate.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/parsedate.c	(revision 164)
@@ -0,0 +1,583 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+  A brief summary of the date string formats this parser groks:
+
+  RFC 2616 3.3.1
+
+  Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
+  Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
+  Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
+
+  we support dates without week day name:
+
+  06 Nov 1994 08:49:37 GMT
+  06-Nov-94 08:49:37 GMT
+  Nov  6 08:49:37 1994
+
+  without the time zone:
+
+  06 Nov 1994 08:49:37
+  06-Nov-94 08:49:37
+
+  weird order:
+
+  1994 Nov 6 08:49:37  (GNU date fails)
+  GMT 08:49:37 06-Nov-94 Sunday
+  94 6 Nov 08:49:37    (GNU date fails)
+
+  time left out:
+
+  1994 Nov 6
+  06-Nov-94
+  Sun Nov 6 94
+
+  unusual separators:
+
+  1994.Nov.6
+  Sun/Nov/6/94/GMT
+
+  commonly used time zone names:
+
+  Sun, 06 Nov 1994 08:49:37 CET
+  06 Nov 1994 08:49:37 EST
+
+  time zones specified using RFC822 style:
+
+  Sun, 12 Sep 2004 15:05:58 -0700
+  Sat, 11 Sep 2004 21:32:11 +0200
+
+  compact numerical date strings:
+
+  20040912 15:05:58 -0700
+  20040911 +0200
+
+*/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <curl/curl.h>
+#include "rawstr.h"
+#include "warnless.h"
+#include "parsedate.h"
+
+const char * const Curl_wkday[] =
+{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
+static const char * const weekday[] =
+{ "Monday", "Tuesday", "Wednesday", "Thursday",
+  "Friday", "Saturday", "Sunday" };
+const char * const Curl_month[]=
+{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+struct tzinfo {
+  char name[5];
+  int offset; /* +/- in minutes */
+};
+
+/*
+ * parsedate()
+ *
+ * Returns:
+ *
+ * PARSEDATE_OK     - a fine conversion
+ * PARSEDATE_FAIL   - failed to convert
+ * PARSEDATE_LATER  - time overflow at the far end of time_t
+ * PARSEDATE_SOONER - time underflow at the low end of time_t
+ */
+
+static int parsedate(const char *date, time_t *output);
+
+#define PARSEDATE_OK     0
+#define PARSEDATE_FAIL   -1
+#define PARSEDATE_LATER  1
+#define PARSEDATE_SOONER 2
+
+/* Here's a bunch of frequently used time zone names. These were supported
+   by the old getdate parser. */
+#define tDAYZONE -60       /* offset for daylight savings time */
+static const struct tzinfo tz[]= {
+  {"GMT", 0},              /* Greenwich Mean */
+  {"UTC", 0},              /* Universal (Coordinated) */
+  {"WET", 0},              /* Western European */
+  {"BST", 0 tDAYZONE},     /* British Summer */
+  {"WAT", 60},             /* West Africa */
+  {"AST", 240},            /* Atlantic Standard */
+  {"ADT", 240 tDAYZONE},   /* Atlantic Daylight */
+  {"EST", 300},            /* Eastern Standard */
+  {"EDT", 300 tDAYZONE},   /* Eastern Daylight */
+  {"CST", 360},            /* Central Standard */
+  {"CDT", 360 tDAYZONE},   /* Central Daylight */
+  {"MST", 420},            /* Mountain Standard */
+  {"MDT", 420 tDAYZONE},   /* Mountain Daylight */
+  {"PST", 480},            /* Pacific Standard */
+  {"PDT", 480 tDAYZONE},   /* Pacific Daylight */
+  {"YST", 540},            /* Yukon Standard */
+  {"YDT", 540 tDAYZONE},   /* Yukon Daylight */
+  {"HST", 600},            /* Hawaii Standard */
+  {"HDT", 600 tDAYZONE},   /* Hawaii Daylight */
+  {"CAT", 600},            /* Central Alaska */
+  {"AHST", 600},           /* Alaska-Hawaii Standard */
+  {"NT",  660},            /* Nome */
+  {"IDLW", 720},           /* International Date Line West */
+  {"CET", -60},            /* Central European */
+  {"MET", -60},            /* Middle European */
+  {"MEWT", -60},           /* Middle European Winter */
+  {"MEST", -60 tDAYZONE},  /* Middle European Summer */
+  {"CEST", -60 tDAYZONE},  /* Central European Summer */
+  {"MESZ", -60 tDAYZONE},  /* Middle European Summer */
+  {"FWT", -60},            /* French Winter */
+  {"FST", -60 tDAYZONE},   /* French Summer */
+  {"EET", -120},           /* Eastern Europe, USSR Zone 1 */
+  {"WAST", -420},          /* West Australian Standard */
+  {"WADT", -420 tDAYZONE}, /* West Australian Daylight */
+  {"CCT", -480},           /* China Coast, USSR Zone 7 */
+  {"JST", -540},           /* Japan Standard, USSR Zone 8 */
+  {"EAST", -600},          /* Eastern Australian Standard */
+  {"EADT", -600 tDAYZONE}, /* Eastern Australian Daylight */
+  {"GST", -600},           /* Guam Standard, USSR Zone 9 */
+  {"NZT", -720},           /* New Zealand */
+  {"NZST", -720},          /* New Zealand Standard */
+  {"NZDT", -720 tDAYZONE}, /* New Zealand Daylight */
+  {"IDLE", -720},          /* International Date Line East */
+  /* Next up: Military timezone names. RFC822 allowed these, but (as noted in
+     RFC 1123) had their signs wrong. Here we use the correct signs to match
+     actual military usage.
+   */
+  {"A",  +1 * 60},         /* Alpha */
+  {"B",  +2 * 60},         /* Bravo */
+  {"C",  +3 * 60},         /* Charlie */
+  {"D",  +4 * 60},         /* Delta */
+  {"E",  +5 * 60},         /* Echo */
+  {"F",  +6 * 60},         /* Foxtrot */
+  {"G",  +7 * 60},         /* Golf */
+  {"H",  +8 * 60},         /* Hotel */
+  {"I",  +9 * 60},         /* India */
+  /* "J", Juliet is not used as a timezone, to indicate the observer's local
+     time */
+  {"K", +10 * 60},         /* Kilo */
+  {"L", +11 * 60},         /* Lima */
+  {"M", +12 * 60},         /* Mike */
+  {"N",  -1 * 60},         /* November */
+  {"O",  -2 * 60},         /* Oscar */
+  {"P",  -3 * 60},         /* Papa */
+  {"Q",  -4 * 60},         /* Quebec */
+  {"R",  -5 * 60},         /* Romeo */
+  {"S",  -6 * 60},         /* Sierra */
+  {"T",  -7 * 60},         /* Tango */
+  {"U",  -8 * 60},         /* Uniform */
+  {"V",  -9 * 60},         /* Victor */
+  {"W", -10 * 60},         /* Whiskey */
+  {"X", -11 * 60},         /* X-ray */
+  {"Y", -12 * 60},         /* Yankee */
+  {"Z", 0},                /* Zulu, zero meridian, a.k.a. UTC */
+};
+
+/* returns:
+   -1 no day
+   0 monday - 6 sunday
+*/
+
+static int checkday(const char *check, size_t len)
+{
+  int i;
+  const char * const *what;
+  bool found= FALSE;
+  if(len > 3)
+    what = &weekday[0];
+  else
+    what = &Curl_wkday[0];
+  for(i=0; i<7; i++) {
+    if(Curl_raw_equal(check, what[0])) {
+      found=TRUE;
+      break;
+    }
+    what++;
+  }
+  return found?i:-1;
+}
+
+static int checkmonth(const char *check)
+{
+  int i;
+  const char * const *what;
+  bool found= FALSE;
+
+  what = &Curl_month[0];
+  for(i=0; i<12; i++) {
+    if(Curl_raw_equal(check, what[0])) {
+      found=TRUE;
+      break;
+    }
+    what++;
+  }
+  return found?i:-1; /* return the offset or -1, no real offset is -1 */
+}
+
+/* return the time zone offset between GMT and the input one, in number
+   of seconds or -1 if the timezone wasn't found/legal */
+
+static int checktz(const char *check)
+{
+  unsigned int i;
+  const struct tzinfo *what;
+  bool found= FALSE;
+
+  what = tz;
+  for(i=0; i< sizeof(tz)/sizeof(tz[0]); i++) {
+    if(Curl_raw_equal(check, what->name)) {
+      found=TRUE;
+      break;
+    }
+    what++;
+  }
+  return found?what->offset*60:-1;
+}
+
+static void skip(const char **date)
+{
+  /* skip everything that aren't letters or digits */
+  while(**date && !ISALNUM(**date))
+    (*date)++;
+}
+
+enum assume {
+  DATE_MDAY,
+  DATE_YEAR,
+  DATE_TIME
+};
+
+/* this is a clone of 'struct tm' but with all fields we don't need or use
+   cut out */
+struct my_tm {
+  int tm_sec;
+  int tm_min;
+  int tm_hour;
+  int tm_mday;
+  int tm_mon;
+  int tm_year;
+};
+
+/* struct tm to time since epoch in GMT time zone.
+ * This is similar to the standard mktime function but for GMT only, and
+ * doesn't suffer from the various bugs and portability problems that
+ * some systems' implementations have.
+ */
+static time_t my_timegm(struct my_tm *tm)
+{
+  static const int month_days_cumulative [12] =
+    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+  int month, year, leap_days;
+
+  if(tm->tm_year < 70)
+    /* we don't support years before 1970 as they will cause this function
+       to return a negative value */
+    return -1;
+
+  year = tm->tm_year + 1900;
+  month = tm->tm_mon;
+  if(month < 0) {
+    year += (11 - month) / 12;
+    month = 11 - (11 - month) % 12;
+  }
+  else if(month >= 12) {
+    year -= month / 12;
+    month = month % 12;
+  }
+
+  leap_days = year - (tm->tm_mon <= 1);
+  leap_days = ((leap_days / 4) - (leap_days / 100) + (leap_days / 400)
+               - (1969 / 4) + (1969 / 100) - (1969 / 400));
+
+  return ((((time_t) (year - 1970) * 365
+            + leap_days + month_days_cumulative [month] + tm->tm_mday - 1) * 24
+           + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec;
+}
+
+/*
+ * parsedate()
+ *
+ * Returns:
+ *
+ * PARSEDATE_OK     - a fine conversion
+ * PARSEDATE_FAIL   - failed to convert
+ * PARSEDATE_LATER  - time overflow at the far end of time_t
+ * PARSEDATE_SOONER - time underflow at the low end of time_t
+ */
+
+static int parsedate(const char *date, time_t *output)
+{
+  time_t t = 0;
+  int wdaynum=-1;  /* day of the week number, 0-6 (mon-sun) */
+  int monnum=-1;   /* month of the year number, 0-11 */
+  int mdaynum=-1; /* day of month, 1 - 31 */
+  int hournum=-1;
+  int minnum=-1;
+  int secnum=-1;
+  int yearnum=-1;
+  int tzoff=-1;
+  struct my_tm tm;
+  enum assume dignext = DATE_MDAY;
+  const char *indate = date; /* save the original pointer */
+  int part = 0; /* max 6 parts */
+
+  while(*date && (part < 6)) {
+    bool found=FALSE;
+
+    skip(&date);
+
+    if(ISALPHA(*date)) {
+      /* a name coming up */
+      char buf[32]="";
+      size_t len;
+      if(sscanf(date, "%31[ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                          "abcdefghijklmnopqrstuvwxyz]", buf))
+        len = strlen(buf);
+      else
+        len = 0;
+
+      if(wdaynum == -1) {
+        wdaynum = checkday(buf, len);
+        if(wdaynum != -1)
+          found = TRUE;
+      }
+      if(!found && (monnum == -1)) {
+        monnum = checkmonth(buf);
+        if(monnum != -1)
+          found = TRUE;
+      }
+
+      if(!found && (tzoff == -1)) {
+        /* this just must be a time zone string */
+        tzoff = checktz(buf);
+        if(tzoff != -1)
+          found = TRUE;
+      }
+
+      if(!found)
+        return PARSEDATE_FAIL; /* bad string */
+
+      date += len;
+    }
+    else if(ISDIGIT(*date)) {
+      /* a digit */
+      int val;
+      char *end;
+      if((secnum == -1) &&
+         (3 == sscanf(date, "%02d:%02d:%02d", &hournum, &minnum, &secnum))) {
+        /* time stamp! */
+        date += 8;
+      }
+      else if((secnum == -1) &&
+              (2 == sscanf(date, "%02d:%02d", &hournum, &minnum))) {
+        /* time stamp without seconds */
+        date += 5;
+        secnum = 0;
+      }
+      else {
+        long lval;
+        int error;
+        int old_errno;
+
+        old_errno = ERRNO;
+        SET_ERRNO(0);
+        lval = strtol(date, &end, 10);
+        error = ERRNO;
+        if(error != old_errno)
+          SET_ERRNO(old_errno);
+
+        if(error)
+          return PARSEDATE_FAIL;
+
+#if LONG_MAX != INT_MAX
+        if((lval > (long)INT_MAX) || (lval < (long)INT_MIN))
+          return PARSEDATE_FAIL;
+#endif
+
+        val = curlx_sltosi(lval);
+
+        if((tzoff == -1) &&
+           ((end - date) == 4) &&
+           (val <= 1400) &&
+           (indate< date) &&
+           ((date[-1] == '+' || date[-1] == '-'))) {
+          /* four digits and a value less than or equal to 1400 (to take into
+             account all sorts of funny time zone diffs) and it is preceded
+             with a plus or minus. This is a time zone indication.  1400 is
+             picked since +1300 is frequently used and +1400 is mentioned as
+             an edge number in the document "ISO C 200X Proposal: Timezone
+             Functions" at http://david.tribble.com/text/c0xtimezone.html If
+             anyone has a more authoritative source for the exact maximum time
+             zone offsets, please speak up! */
+          found = TRUE;
+          tzoff = (val/100 * 60 + val%100)*60;
+
+          /* the + and - prefix indicates the local time compared to GMT,
+             this we need ther reversed math to get what we want */
+          tzoff = date[-1]=='+'?-tzoff:tzoff;
+        }
+
+        if(((end - date) == 8) &&
+           (yearnum == -1) &&
+           (monnum == -1) &&
+           (mdaynum == -1)) {
+          /* 8 digits, no year, month or day yet. This is YYYYMMDD */
+          found = TRUE;
+          yearnum = val/10000;
+          monnum = (val%10000)/100-1; /* month is 0 - 11 */
+          mdaynum = val%100;
+        }
+
+        if(!found && (dignext == DATE_MDAY) && (mdaynum == -1)) {
+          if((val > 0) && (val<32)) {
+            mdaynum = val;
+            found = TRUE;
+          }
+          dignext = DATE_YEAR;
+        }
+
+        if(!found && (dignext == DATE_YEAR) && (yearnum == -1)) {
+          yearnum = val;
+          found = TRUE;
+          if(yearnum < 1900) {
+            if(yearnum > 70)
+              yearnum += 1900;
+            else
+              yearnum += 2000;
+          }
+          if(mdaynum == -1)
+            dignext = DATE_MDAY;
+        }
+
+        if(!found)
+          return PARSEDATE_FAIL;
+
+        date = end;
+      }
+    }
+
+    part++;
+  }
+
+  if(-1 == secnum)
+    secnum = minnum = hournum = 0; /* no time, make it zero */
+
+  if((-1 == mdaynum) ||
+     (-1 == monnum) ||
+     (-1 == yearnum))
+    /* lacks vital info, fail */
+    return PARSEDATE_FAIL;
+
+#if SIZEOF_TIME_T < 5
+  /* 32 bit time_t can only hold dates to the beginning of 2038 */
+  if(yearnum > 2037) {
+    *output = 0x7fffffff;
+    return PARSEDATE_LATER;
+  }
+#endif
+
+  if(yearnum < 1970) {
+    *output = 0;
+    return PARSEDATE_SOONER;
+  }
+
+  if((mdaynum > 31) || (monnum > 11) ||
+     (hournum > 23) || (minnum > 59) || (secnum > 60))
+    return PARSEDATE_FAIL; /* clearly an illegal date */
+
+  tm.tm_sec = secnum;
+  tm.tm_min = minnum;
+  tm.tm_hour = hournum;
+  tm.tm_mday = mdaynum;
+  tm.tm_mon = monnum;
+  tm.tm_year = yearnum - 1900;
+
+  /* my_timegm() returns a time_t. time_t is often 32 bits, even on many
+     architectures that feature 64 bit 'long'.
+
+     Some systems have 64 bit time_t and deal with years beyond 2038. However,
+     even on some of the systems with 64 bit time_t mktime() returns -1 for
+     dates beyond 03:14:07 UTC, January 19, 2038. (Such as AIX 5100-06)
+  */
+  t = my_timegm(&tm);
+
+  /* time zone adjust (cast t to int to compare to negative one) */
+  if(-1 != (int)t) {
+
+    /* Add the time zone diff between local time zone and GMT. */
+    long delta = (long)(tzoff!=-1?tzoff:0);
+
+    if((delta>0) && (t > LONG_MAX - delta)) {
+      *output = 0x7fffffff;
+      return PARSEDATE_LATER; /* time_t overflow */
+    }
+
+    t += delta;
+  }
+
+  *output = t;
+
+  return PARSEDATE_OK;
+}
+
+time_t curl_getdate(const char *p, const time_t *now)
+{
+  time_t parsed = -1;
+  int rc = parsedate(p, &parsed);
+  (void)now; /* legacy argument from the past that we ignore */
+
+  switch(rc) {
+  case PARSEDATE_OK:
+  case PARSEDATE_LATER:
+  case PARSEDATE_SOONER:
+    return parsed;
+  }
+  /* everything else is fail */
+  return -1;
+}
+
+/*
+ * Curl_gmtime() is a gmtime() replacement for portability. Do not use the
+ * gmtime_r() or gmtime() functions anywhere else but here.
+ *
+ */
+
+CURLcode Curl_gmtime(time_t intime, struct tm *store)
+{
+  const struct tm *tm;
+#ifdef HAVE_GMTIME_R
+  /* thread-safe version */
+  tm = (struct tm *)gmtime_r(&intime, store);
+#else
+  tm = gmtime(&intime);
+  if(tm)
+    *store = *tm; /* copy the pointed struct to the local copy */
+#endif
+
+  if(!tm)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+  return CURLE_OK;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/parsedate.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/parsedate.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/parsedate.h	(revision 164)
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_PARSEDATE_H
+#define HEADER_CURL_PARSEDATE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+extern const char * const Curl_wkday[7];
+extern const char * const Curl_month[12];
+
+CURLcode Curl_gmtime(time_t intime, struct tm *store);
+
+#endif /* HEADER_CURL_PARSEDATE_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/pingpong.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/pingpong.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/pingpong.c	(revision 164)
@@ -0,0 +1,507 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ *   'pingpong' is for generic back-and-forth support functions used by FTP,
+ *   IMAP, POP3, SMTP and whatever more that likes them.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "urldata.h"
+#include "sendf.h"
+#include "select.h"
+#include "progress.h"
+#include "speedcheck.h"
+#include "pingpong.h"
+#include "multiif.h"
+#include "non-ascii.h"
+#include "vtls/vtls.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifdef USE_PINGPONG
+
+/* Returns timeout in ms. 0 or negative number means the timeout has already
+   triggered */
+long Curl_pp_state_timeout(struct pingpong *pp)
+{
+  struct connectdata *conn = pp->conn;
+  struct SessionHandle *data=conn->data;
+  long timeout_ms; /* in milliseconds */
+  long timeout2_ms; /* in milliseconds */
+  long response_time= (data->set.server_response_timeout)?
+    data->set.server_response_timeout: pp->response_time;
+
+  /* if CURLOPT_SERVER_RESPONSE_TIMEOUT is set, use that to determine
+     remaining time, or use pp->response because SERVER_RESPONSE_TIMEOUT is
+     supposed to govern the response for any given server response, not for
+     the time from connect to the given server response. */
+
+  /* Without a requested timeout, we only wait 'response_time' seconds for the
+     full response to arrive before we bail out */
+  timeout_ms = response_time -
+    Curl_tvdiff(Curl_tvnow(), pp->response); /* spent time */
+
+  if(data->set.timeout) {
+    /* if timeout is requested, find out how much remaining time we have */
+    timeout2_ms = data->set.timeout - /* timeout time */
+      Curl_tvdiff(Curl_tvnow(), conn->now); /* spent time */
+
+    /* pick the lowest number */
+    timeout_ms = CURLMIN(timeout_ms, timeout2_ms);
+  }
+
+  return timeout_ms;
+}
+
+/*
+ * Curl_pp_statemach()
+ */
+CURLcode Curl_pp_statemach(struct pingpong *pp, bool block)
+{
+  struct connectdata *conn = pp->conn;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  int rc;
+  long interval_ms;
+  long timeout_ms = Curl_pp_state_timeout(pp);
+  struct SessionHandle *data=conn->data;
+  CURLcode result = CURLE_OK;
+
+  if(timeout_ms <=0 ) {
+    failf(data, "server response timeout");
+    return CURLE_OPERATION_TIMEDOUT; /* already too little time */
+  }
+
+  if(block) {
+    interval_ms = 1000;  /* use 1 second timeout intervals */
+    if(timeout_ms < interval_ms)
+      interval_ms = timeout_ms;
+  }
+  else
+    interval_ms = 0; /* immediate */
+
+  if(Curl_pp_moredata(pp))
+    /* We are receiving and there is data in the cache so just read it */
+    rc = 1;
+  else if(!pp->sendleft && Curl_ssl_data_pending(conn, FIRSTSOCKET))
+    /* We are receiving and there is data ready in the SSL library */
+    rc = 1;
+  else
+    rc = Curl_socket_ready(pp->sendleft?CURL_SOCKET_BAD:sock, /* reading */
+                           pp->sendleft?sock:CURL_SOCKET_BAD, /* writing */
+                           interval_ms);
+
+  if(block) {
+    /* if we didn't wait, we don't have to spend time on this now */
+    if(Curl_pgrsUpdate(conn))
+      result = CURLE_ABORTED_BY_CALLBACK;
+    else
+      result = Curl_speedcheck(data, Curl_tvnow());
+
+    if(result)
+      return result;
+  }
+
+  if(rc == -1) {
+    failf(data, "select/poll error");
+    result = CURLE_OUT_OF_MEMORY;
+  }
+  else if(rc)
+    result = pp->statemach_act(conn);
+
+  return result;
+}
+
+/* initialize stuff to prepare for reading a fresh new response */
+void Curl_pp_init(struct pingpong *pp)
+{
+  struct connectdata *conn = pp->conn;
+  pp->nread_resp = 0;
+  pp->linestart_resp = conn->data->state.buffer;
+  pp->pending_resp = TRUE;
+  pp->response = Curl_tvnow(); /* start response time-out now! */
+}
+
+
+
+/***********************************************************************
+ *
+ * Curl_pp_vsendf()
+ *
+ * Send the formated string as a command to a pingpong server. Note that
+ * the string should not have any CRLF appended, as this function will
+ * append the necessary things itself.
+ *
+ * made to never block
+ */
+CURLcode Curl_pp_vsendf(struct pingpong *pp,
+                        const char *fmt,
+                        va_list args)
+{
+  ssize_t bytes_written;
+  size_t write_len;
+  char *fmt_crlf;
+  char *s;
+  CURLcode result;
+  struct connectdata *conn = pp->conn;
+  struct SessionHandle *data = conn->data;
+
+#ifdef HAVE_GSSAPI
+  enum protection_level data_sec = conn->data_prot;
+#endif
+
+  DEBUGASSERT(pp->sendleft == 0);
+  DEBUGASSERT(pp->sendsize == 0);
+  DEBUGASSERT(pp->sendthis == NULL);
+
+  fmt_crlf = aprintf("%s\r\n", fmt); /* append a trailing CRLF */
+  if(!fmt_crlf)
+    return CURLE_OUT_OF_MEMORY;
+
+  s = vaprintf(fmt_crlf, args); /* trailing CRLF appended */
+  free(fmt_crlf);
+  if(!s)
+    return CURLE_OUT_OF_MEMORY;
+
+  bytes_written = 0;
+  write_len = strlen(s);
+
+  Curl_pp_init(pp);
+
+  result = Curl_convert_to_network(data, s, write_len);
+  /* Curl_convert_to_network calls failf if unsuccessful */
+  if(result) {
+    free(s);
+    return result;
+  }
+
+#ifdef HAVE_GSSAPI
+  conn->data_prot = PROT_CMD;
+#endif
+  result = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len,
+                     &bytes_written);
+#ifdef HAVE_GSSAPI
+  DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
+  conn->data_prot = data_sec;
+#endif
+
+  if(result) {
+    free(s);
+    return result;
+  }
+
+  if(conn->data->set.verbose)
+    Curl_debug(conn->data, CURLINFO_HEADER_OUT,
+               s, (size_t)bytes_written, conn);
+
+  if(bytes_written != (ssize_t)write_len) {
+    /* the whole chunk was not sent, keep it around and adjust sizes */
+    pp->sendthis = s;
+    pp->sendsize = write_len;
+    pp->sendleft = write_len - bytes_written;
+  }
+  else {
+    free(s);
+    pp->sendthis = NULL;
+    pp->sendleft = pp->sendsize = 0;
+    pp->response = Curl_tvnow();
+  }
+
+  return CURLE_OK;
+}
+
+
+/***********************************************************************
+ *
+ * Curl_pp_sendf()
+ *
+ * Send the formated string as a command to a pingpong server. Note that
+ * the string should not have any CRLF appended, as this function will
+ * append the necessary things itself.
+ *
+ * made to never block
+ */
+CURLcode Curl_pp_sendf(struct pingpong *pp,
+                       const char *fmt, ...)
+{
+  CURLcode result;
+  va_list ap;
+  va_start(ap, fmt);
+
+  result = Curl_pp_vsendf(pp, fmt, ap);
+
+  va_end(ap);
+
+  return result;
+}
+
+/*
+ * Curl_pp_readresp()
+ *
+ * Reads a piece of a server response.
+ */
+CURLcode Curl_pp_readresp(curl_socket_t sockfd,
+                          struct pingpong *pp,
+                          int *code, /* return the server code if done */
+                          size_t *size) /* size of the response */
+{
+  ssize_t perline; /* count bytes per line */
+  bool keepon=TRUE;
+  ssize_t gotbytes;
+  char *ptr;
+  struct connectdata *conn = pp->conn;
+  struct SessionHandle *data = conn->data;
+  char * const buf = data->state.buffer;
+  CURLcode result = CURLE_OK;
+
+  *code = 0; /* 0 for errors or not done */
+  *size = 0;
+
+  ptr=buf + pp->nread_resp;
+
+  /* number of bytes in the current line, so far */
+  perline = (ssize_t)(ptr-pp->linestart_resp);
+
+  while((pp->nread_resp<BUFSIZE) && (keepon && !result)) {
+
+    if(pp->cache) {
+      /* we had data in the "cache", copy that instead of doing an actual
+       * read
+       *
+       * pp->cache_size is cast to ssize_t here.  This should be safe, because
+       * it would have been populated with something of size int to begin
+       * with, even though its datatype may be larger than an int.
+       */
+      DEBUGASSERT((ptr+pp->cache_size) <= (buf+BUFSIZE+1));
+      memcpy(ptr, pp->cache, pp->cache_size);
+      gotbytes = (ssize_t)pp->cache_size;
+      free(pp->cache);    /* free the cache */
+      pp->cache = NULL;   /* clear the pointer */
+      pp->cache_size = 0; /* zero the size just in case */
+    }
+    else {
+#ifdef HAVE_GSSAPI
+      enum protection_level prot = conn->data_prot;
+      conn->data_prot = PROT_CLEAR;
+#endif
+      DEBUGASSERT((ptr+BUFSIZE-pp->nread_resp) <= (buf+BUFSIZE+1));
+      result = Curl_read(conn, sockfd, ptr, BUFSIZE-pp->nread_resp,
+                         &gotbytes);
+#ifdef HAVE_GSSAPI
+      DEBUGASSERT(prot  > PROT_NONE && prot < PROT_LAST);
+      conn->data_prot = prot;
+#endif
+      if(result == CURLE_AGAIN)
+        return CURLE_OK; /* return */
+
+      if(!result && (gotbytes > 0))
+        /* convert from the network encoding */
+        result = Curl_convert_from_network(data, ptr, gotbytes);
+      /* Curl_convert_from_network calls failf if unsuccessful */
+
+      if(result)
+        /* Set outer result variable to this error. */
+        keepon = FALSE;
+    }
+
+    if(!keepon)
+      ;
+    else if(gotbytes <= 0) {
+      keepon = FALSE;
+      result = CURLE_RECV_ERROR;
+      failf(data, "response reading failed");
+    }
+    else {
+      /* we got a whole chunk of data, which can be anything from one
+       * byte to a set of lines and possible just a piece of the last
+       * line */
+      ssize_t i;
+      ssize_t clipamount = 0;
+      bool restart = FALSE;
+
+      data->req.headerbytecount += (long)gotbytes;
+
+      pp->nread_resp += gotbytes;
+      for(i = 0; i < gotbytes; ptr++, i++) {
+        perline++;
+        if(*ptr=='\n') {
+          /* a newline is CRLF in pp-talk, so the CR is ignored as
+             the line isn't really terminated until the LF comes */
+
+          /* output debug output if that is requested */
+#ifdef HAVE_GSSAPI
+          if(!conn->sec_complete)
+#endif
+            if(data->set.verbose)
+              Curl_debug(data, CURLINFO_HEADER_IN,
+                         pp->linestart_resp, (size_t)perline, conn);
+
+          /*
+           * We pass all response-lines to the callback function registered
+           * for "headers". The response lines can be seen as a kind of
+           * headers.
+           */
+          result = Curl_client_write(conn, CLIENTWRITE_HEADER,
+                                     pp->linestart_resp, perline);
+          if(result)
+            return result;
+
+          if(pp->endofresp(conn, pp->linestart_resp, perline, code)) {
+            /* This is the end of the last line, copy the last line to the
+               start of the buffer and zero terminate, for old times sake */
+            size_t n = ptr - pp->linestart_resp;
+            memmove(buf, pp->linestart_resp, n);
+            buf[n]=0; /* zero terminate */
+            keepon=FALSE;
+            pp->linestart_resp = ptr+1; /* advance pointer */
+            i++; /* skip this before getting out */
+
+            *size = pp->nread_resp; /* size of the response */
+            pp->nread_resp = 0; /* restart */
+            break;
+          }
+          perline=0; /* line starts over here */
+          pp->linestart_resp = ptr+1;
+        }
+      }
+
+      if(!keepon && (i != gotbytes)) {
+        /* We found the end of the response lines, but we didn't parse the
+           full chunk of data we have read from the server. We therefore need
+           to store the rest of the data to be checked on the next invoke as
+           it may actually contain another end of response already! */
+        clipamount = gotbytes - i;
+        restart = TRUE;
+        DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
+                     "server response left\n",
+                     (int)clipamount));
+      }
+      else if(keepon) {
+
+        if((perline == gotbytes) && (gotbytes > BUFSIZE/2)) {
+          /* We got an excessive line without newlines and we need to deal
+             with it. We keep the first bytes of the line then we throw
+             away the rest. */
+          infof(data, "Excessive server response line length received, "
+                "%zd bytes. Stripping\n", gotbytes);
+          restart = TRUE;
+
+          /* we keep 40 bytes since all our pingpong protocols are only
+             interested in the first piece */
+          clipamount = 40;
+        }
+        else if(pp->nread_resp > BUFSIZE/2) {
+          /* We got a large chunk of data and there's potentially still
+             trailing data to take care of, so we put any such part in the
+             "cache", clear the buffer to make space and restart. */
+          clipamount = perline;
+          restart = TRUE;
+        }
+      }
+      else if(i == gotbytes)
+        restart = TRUE;
+
+      if(clipamount) {
+        pp->cache_size = clipamount;
+        pp->cache = malloc(pp->cache_size);
+        if(pp->cache)
+          memcpy(pp->cache, pp->linestart_resp, pp->cache_size);
+        else
+          return CURLE_OUT_OF_MEMORY;
+      }
+      if(restart) {
+        /* now reset a few variables to start over nicely from the start of
+           the big buffer */
+        pp->nread_resp = 0; /* start over from scratch in the buffer */
+        ptr = pp->linestart_resp = buf;
+        perline = 0;
+      }
+
+    } /* there was data */
+
+  } /* while there's buffer left and loop is requested */
+
+  pp->pending_resp = FALSE;
+
+  return result;
+}
+
+int Curl_pp_getsock(struct pingpong *pp,
+                    curl_socket_t *socks,
+                    int numsocks)
+{
+  struct connectdata *conn = pp->conn;
+
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  socks[0] = conn->sock[FIRSTSOCKET];
+
+  if(pp->sendleft) {
+    /* write mode */
+    return GETSOCK_WRITESOCK(0);
+  }
+
+  /* read mode */
+  return GETSOCK_READSOCK(0);
+}
+
+CURLcode Curl_pp_flushsend(struct pingpong *pp)
+{
+  /* we have a piece of a command still left to send */
+  struct connectdata *conn = pp->conn;
+  ssize_t written;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  CURLcode result = Curl_write(conn, sock, pp->sendthis + pp->sendsize -
+                               pp->sendleft, pp->sendleft, &written);
+  if(result)
+    return result;
+
+  if(written != (ssize_t)pp->sendleft) {
+    /* only a fraction was sent */
+    pp->sendleft -= written;
+  }
+  else {
+    free(pp->sendthis);
+    pp->sendthis=NULL;
+    pp->sendleft = pp->sendsize = 0;
+    pp->response = Curl_tvnow();
+  }
+  return CURLE_OK;
+}
+
+CURLcode Curl_pp_disconnect(struct pingpong *pp)
+{
+  free(pp->cache);
+  pp->cache = NULL;
+  return CURLE_OK;
+}
+
+bool Curl_pp_moredata(struct pingpong *pp)
+{
+  return (!pp->sendleft && pp->cache && pp->nread_resp < pp->cache_size) ?
+         TRUE : FALSE;
+}
+
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/lib/pingpong.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/pingpong.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/pingpong.h	(revision 164)
@@ -0,0 +1,150 @@
+#ifndef HEADER_CURL_PINGPONG_H
+#define HEADER_CURL_PINGPONG_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_FTP) || \
+  !defined(CURL_DISABLE_POP3) || !defined(CURL_DISABLE_SMTP)
+#define USE_PINGPONG
+#endif
+
+/* forward-declaration, this is defined in urldata.h */
+struct connectdata;
+
+typedef enum {
+  FTPTRANSFER_BODY, /* yes do transfer a body */
+  FTPTRANSFER_INFO, /* do still go through to get info/headers */
+  FTPTRANSFER_NONE, /* don't get anything and don't get info */
+  FTPTRANSFER_LAST  /* end of list marker, never used */
+} curl_pp_transfer;
+
+/*
+ * 'pingpong' is the generic struct used for protocols doing server<->client
+ * conversations in a back-and-forth style such as FTP, IMAP, POP3, SMTP etc.
+ *
+ * It holds response cache and non-blocking sending data.
+ */
+struct pingpong {
+  char *cache;     /* data cache between getresponse()-calls */
+  size_t cache_size;  /* size of cache in bytes */
+  size_t nread_resp;  /* number of bytes currently read of a server response */
+  char *linestart_resp; /* line start pointer for the server response
+                           reader function */
+  bool pending_resp;  /* set TRUE when a server response is pending or in
+                         progress, and is cleared once the last response is
+                         read */
+  char *sendthis; /* allocated pointer to a buffer that is to be sent to the
+                     server */
+  size_t sendleft; /* number of bytes left to send from the sendthis buffer */
+  size_t sendsize; /* total size of the sendthis buffer */
+  struct timeval response; /* set to Curl_tvnow() when a command has been sent
+                              off, used to time-out response reading */
+  long response_time; /* When no timeout is given, this is the amount of
+                         milliseconds we await for a server response. */
+
+  struct connectdata *conn; /* points to the connectdata struct that this
+                               belongs to */
+
+  /* Function pointers the protocols MUST implement and provide for the
+     pingpong layer to function */
+
+  CURLcode (*statemach_act)(struct connectdata *conn);
+
+  bool (*endofresp)(struct connectdata *conn, char *ptr, size_t len,
+                    int *code);
+};
+
+/*
+ * Curl_pp_statemach()
+ *
+ * called repeatedly until done. Set 'wait' to make it wait a while on the
+ * socket if there's no traffic.
+ */
+CURLcode Curl_pp_statemach(struct pingpong *pp, bool block);
+
+/* initialize stuff to prepare for reading a fresh new response */
+void Curl_pp_init(struct pingpong *pp);
+
+/* Returns timeout in ms. 0 or negative number means the timeout has already
+   triggered */
+long Curl_pp_state_timeout(struct pingpong *pp);
+
+
+/***********************************************************************
+ *
+ * Curl_pp_sendf()
+ *
+ * Send the formated string as a command to a pingpong server. Note that
+ * the string should not have any CRLF appended, as this function will
+ * append the necessary things itself.
+ *
+ * made to never block
+ */
+CURLcode Curl_pp_sendf(struct pingpong *pp,
+                       const char *fmt, ...);
+
+/***********************************************************************
+ *
+ * Curl_pp_vsendf()
+ *
+ * Send the formated string as a command to a pingpong server. Note that
+ * the string should not have any CRLF appended, as this function will
+ * append the necessary things itself.
+ *
+ * made to never block
+ */
+CURLcode Curl_pp_vsendf(struct pingpong *pp,
+                        const char *fmt,
+                        va_list args);
+
+/*
+ * Curl_pp_readresp()
+ *
+ * Reads a piece of a server response.
+ */
+CURLcode Curl_pp_readresp(curl_socket_t sockfd,
+                          struct pingpong *pp,
+                          int *code, /* return the server code if done */
+                          size_t *size); /* size of the response */
+
+
+CURLcode Curl_pp_flushsend(struct pingpong *pp);
+
+/* call this when a pingpong connection is disconnected */
+CURLcode Curl_pp_disconnect(struct pingpong *pp);
+
+int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks,
+                    int numsocks);
+
+
+/***********************************************************************
+ *
+ * Curl_pp_moredata()
+ *
+ * Returns whether there are still more data in the cache and so a call
+ * to Curl_pp_readresp() will not block.
+ */
+bool Curl_pp_moredata(struct pingpong *pp);
+
+#endif /* HEADER_CURL_PINGPONG_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/pipeline.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/pipeline.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/pipeline.c	(revision 164)
@@ -0,0 +1,433 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
+ * Copyright (C) 2013-2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "url.h"
+#include "progress.h"
+#include "multiif.h"
+#include "pipeline.h"
+#include "sendf.h"
+#include "rawstr.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+struct site_blacklist_entry {
+  char *hostname;
+  unsigned short port;
+};
+
+static void site_blacklist_llist_dtor(void *user, void *element)
+{
+  struct site_blacklist_entry *entry = element;
+  (void)user;
+
+  Curl_safefree(entry->hostname);
+  free(entry);
+}
+
+static void server_blacklist_llist_dtor(void *user, void *element)
+{
+  (void)user;
+  free(element);
+}
+
+bool Curl_pipeline_penalized(struct SessionHandle *data,
+                             struct connectdata *conn)
+{
+  if(data) {
+    bool penalized = FALSE;
+    curl_off_t penalty_size =
+      Curl_multi_content_length_penalty_size(data->multi);
+    curl_off_t chunk_penalty_size =
+      Curl_multi_chunk_length_penalty_size(data->multi);
+    curl_off_t recv_size = -2; /* Make it easy to spot in the log */
+
+    /* Find the head of the recv pipe, if any */
+    if(conn->recv_pipe && conn->recv_pipe->head) {
+      struct SessionHandle *recv_handle = conn->recv_pipe->head->ptr;
+
+      recv_size = recv_handle->req.size;
+
+      if(penalty_size > 0 && recv_size > penalty_size)
+        penalized = TRUE;
+    }
+
+    if(chunk_penalty_size > 0 &&
+       (curl_off_t)conn->chunk.datasize > chunk_penalty_size)
+      penalized = TRUE;
+
+    infof(data, "Conn: %ld (%p) Receive pipe weight: (%"
+          CURL_FORMAT_CURL_OFF_T "/%zu), penalized: %s\n",
+          conn->connection_id, (void *)conn, recv_size,
+          conn->chunk.datasize, penalized?"TRUE":"FALSE");
+    return penalized;
+  }
+  return FALSE;
+}
+
+static CURLcode addHandleToPipeline(struct SessionHandle *data,
+                                    struct curl_llist *pipeline)
+{
+  if(!Curl_llist_insert_next(pipeline, pipeline->tail, data))
+    return CURLE_OUT_OF_MEMORY;
+  return CURLE_OK;
+}
+
+
+CURLcode Curl_add_handle_to_pipeline(struct SessionHandle *handle,
+                                     struct connectdata *conn)
+{
+  struct curl_llist_element *sendhead = conn->send_pipe->head;
+  struct curl_llist *pipeline;
+  CURLcode result;
+
+  pipeline = conn->send_pipe;
+
+  result = addHandleToPipeline(handle, pipeline);
+
+  if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
+    /* this is a new one as head, expire it */
+    Curl_pipeline_leave_write(conn); /* not in use yet */
+    Curl_expire(conn->send_pipe->head->ptr, 1);
+  }
+
+#if 0 /* enable for pipeline debugging */
+  print_pipeline(conn);
+#endif
+
+  return result;
+}
+
+/* Move this transfer from the sending list to the receiving list.
+
+   Pay special attention to the new sending list "leader" as it needs to get
+   checked to update what sockets it acts on.
+
+*/
+void Curl_move_handle_from_send_to_recv_pipe(struct SessionHandle *handle,
+                                             struct connectdata *conn)
+{
+  struct curl_llist_element *curr;
+
+  curr = conn->send_pipe->head;
+  while(curr) {
+    if(curr->ptr == handle) {
+      Curl_llist_move(conn->send_pipe, curr,
+                      conn->recv_pipe, conn->recv_pipe->tail);
+
+      if(conn->send_pipe->head) {
+        /* Since there's a new easy handle at the start of the send pipeline,
+           set its timeout value to 1ms to make it trigger instantly */
+        Curl_pipeline_leave_write(conn); /* not used now */
+#ifdef DEBUGBUILD
+        infof(conn->data, "%p is at send pipe head B!\n",
+              (void *)conn->send_pipe->head->ptr);
+#endif
+        Curl_expire(conn->send_pipe->head->ptr, 1);
+      }
+
+      /* The receiver's list is not really interesting here since either this
+         handle is now first in the list and we'll deal with it soon, or
+         another handle is already first and thus is already taken care of */
+
+      break; /* we're done! */
+    }
+    curr = curr->next;
+  }
+}
+
+bool Curl_pipeline_site_blacklisted(struct SessionHandle *handle,
+                                    struct connectdata *conn)
+{
+  if(handle->multi) {
+    struct curl_llist *blacklist =
+      Curl_multi_pipelining_site_bl(handle->multi);
+
+    if(blacklist) {
+      struct curl_llist_element *curr;
+
+      curr = blacklist->head;
+      while(curr) {
+        struct site_blacklist_entry *site;
+
+        site = curr->ptr;
+        if(Curl_raw_equal(site->hostname, conn->host.name) &&
+           site->port == conn->remote_port) {
+          infof(handle, "Site %s:%d is pipeline blacklisted\n",
+                conn->host.name, conn->remote_port);
+          return TRUE;
+        }
+        curr = curr->next;
+      }
+    }
+  }
+  return FALSE;
+}
+
+CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
+                                           struct curl_llist **list_ptr)
+{
+  struct curl_llist *old_list = *list_ptr;
+  struct curl_llist *new_list = NULL;
+
+  if(sites) {
+    new_list = Curl_llist_alloc((curl_llist_dtor) site_blacklist_llist_dtor);
+    if(!new_list)
+      return CURLM_OUT_OF_MEMORY;
+
+    /* Parse the URLs and populate the list */
+    while(*sites) {
+      char *hostname;
+      char *port;
+      struct site_blacklist_entry *entry;
+
+      hostname = strdup(*sites);
+      if(!hostname) {
+        Curl_llist_destroy(new_list, NULL);
+        return CURLM_OUT_OF_MEMORY;
+      }
+
+      entry = malloc(sizeof(struct site_blacklist_entry));
+      if(!entry) {
+        free(hostname);
+        Curl_llist_destroy(new_list, NULL);
+        return CURLM_OUT_OF_MEMORY;
+      }
+
+      port = strchr(hostname, ':');
+      if(port) {
+        *port = '\0';
+        port++;
+        entry->port = (unsigned short)strtol(port, NULL, 10);
+      }
+      else {
+        /* Default port number for HTTP */
+        entry->port = 80;
+      }
+
+      entry->hostname = hostname;
+
+      if(!Curl_llist_insert_next(new_list, new_list->tail, entry)) {
+        site_blacklist_llist_dtor(NULL, entry);
+        Curl_llist_destroy(new_list, NULL);
+        return CURLM_OUT_OF_MEMORY;
+      }
+
+      sites++;
+    }
+  }
+
+  /* Free the old list */
+  if(old_list) {
+    Curl_llist_destroy(old_list, NULL);
+  }
+
+  /* This might be NULL if sites == NULL, i.e the blacklist is cleared */
+  *list_ptr = new_list;
+
+  return CURLM_OK;
+}
+
+bool Curl_pipeline_server_blacklisted(struct SessionHandle *handle,
+                                      char *server_name)
+{
+  if(handle->multi && server_name) {
+    struct curl_llist *blacklist =
+      Curl_multi_pipelining_server_bl(handle->multi);
+
+    if(blacklist) {
+      struct curl_llist_element *curr;
+
+      curr = blacklist->head;
+      while(curr) {
+        char *bl_server_name;
+
+        bl_server_name = curr->ptr;
+        if(Curl_raw_nequal(bl_server_name, server_name,
+                           strlen(bl_server_name))) {
+          infof(handle, "Server %s is blacklisted\n", server_name);
+          return TRUE;
+        }
+        curr = curr->next;
+      }
+    }
+
+    DEBUGF(infof(handle, "Server %s is not blacklisted\n", server_name));
+  }
+  return FALSE;
+}
+
+CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
+                                             struct curl_llist **list_ptr)
+{
+  struct curl_llist *old_list = *list_ptr;
+  struct curl_llist *new_list = NULL;
+
+  if(servers) {
+    new_list = Curl_llist_alloc((curl_llist_dtor) server_blacklist_llist_dtor);
+    if(!new_list)
+      return CURLM_OUT_OF_MEMORY;
+
+    /* Parse the URLs and populate the list */
+    while(*servers) {
+      char *server_name;
+
+      server_name = strdup(*servers);
+      if(!server_name)
+        return CURLM_OUT_OF_MEMORY;
+
+      if(!Curl_llist_insert_next(new_list, new_list->tail, server_name))
+        return CURLM_OUT_OF_MEMORY;
+
+      servers++;
+    }
+  }
+
+  /* Free the old list */
+  if(old_list) {
+    Curl_llist_destroy(old_list, NULL);
+  }
+
+  /* This might be NULL if sites == NULL, i.e the blacklist is cleared */
+  *list_ptr = new_list;
+
+  return CURLM_OK;
+}
+
+static bool pipe_head(struct SessionHandle *data,
+                      struct curl_llist *pipeline)
+{
+  struct curl_llist_element *curr = pipeline->head;
+  if(curr)
+    return (curr->ptr == data) ? TRUE : FALSE;
+
+  return FALSE;
+}
+
+/* returns TRUE if the given handle is head of the recv pipe */
+bool Curl_recvpipe_head(struct SessionHandle *data,
+                        struct connectdata *conn)
+{
+  return pipe_head(data, conn->recv_pipe);
+}
+
+/* returns TRUE if the given handle is head of the send pipe */
+bool Curl_sendpipe_head(struct SessionHandle *data,
+                        struct connectdata *conn)
+{
+  return pipe_head(data, conn->send_pipe);
+}
+
+
+/*
+ * Check if the write channel is available and this handle as at the head,
+ * then grab the channel and return TRUE.
+ *
+ * If not available, return FALSE.
+ */
+
+bool Curl_pipeline_checkget_write(struct SessionHandle *data,
+                                  struct connectdata *conn)
+{
+  if(conn->bits.multiplex)
+    /* when multiplexing, we can use it at once */
+    return TRUE;
+
+  if(!conn->writechannel_inuse && Curl_sendpipe_head(data, conn)) {
+    /* Grab the channel */
+    conn->writechannel_inuse = TRUE;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+/*
+ * Check if the read channel is available and this handle as at the head, then
+ * grab the channel and return TRUE.
+ *
+ * If not available, return FALSE.
+ */
+
+bool Curl_pipeline_checkget_read(struct SessionHandle *data,
+                                 struct connectdata *conn)
+{
+  if(conn->bits.multiplex)
+    /* when multiplexing, we can use it at once */
+    return TRUE;
+
+  if(!conn->readchannel_inuse && Curl_recvpipe_head(data, conn)) {
+    /* Grab the channel */
+    conn->readchannel_inuse = TRUE;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/*
+ * The current user of the pipeline write channel gives it up.
+ */
+void Curl_pipeline_leave_write(struct connectdata *conn)
+{
+  conn->writechannel_inuse = FALSE;
+}
+
+/*
+ * The current user of the pipeline read channel gives it up.
+ */
+void Curl_pipeline_leave_read(struct connectdata *conn)
+{
+  conn->readchannel_inuse = FALSE;
+}
+
+
+#if 0
+void print_pipeline(struct connectdata *conn)
+{
+  struct curl_llist_element *curr;
+  struct connectbundle *cb_ptr;
+  struct SessionHandle *data = conn->data;
+
+  cb_ptr = conn->bundle;
+
+  if(cb_ptr) {
+    curr = cb_ptr->conn_list->head;
+    while(curr) {
+      conn = curr->ptr;
+      infof(data, "- Conn %ld (%p) send_pipe: %zu, recv_pipe: %zu\n",
+            conn->connection_id,
+            (void *)conn,
+            conn->send_pipe->size,
+            conn->recv_pipe->size);
+      curr = curr->next;
+    }
+  }
+}
+
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/lib/pipeline.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/pipeline.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/pipeline.h	(revision 164)
@@ -0,0 +1,56 @@
+#ifndef HEADER_CURL_PIPELINE_H
+#define HEADER_CURL_PIPELINE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2013 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+CURLcode Curl_add_handle_to_pipeline(struct SessionHandle *handle,
+                                     struct connectdata *conn);
+void Curl_move_handle_from_send_to_recv_pipe(struct SessionHandle *handle,
+                                             struct connectdata *conn);
+bool Curl_pipeline_penalized(struct SessionHandle *data,
+                             struct connectdata *conn);
+
+bool Curl_pipeline_site_blacklisted(struct SessionHandle *handle,
+                                    struct connectdata *conn);
+
+CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
+                                           struct curl_llist **list_ptr);
+
+bool Curl_pipeline_server_blacklisted(struct SessionHandle *handle,
+                                      char *server_name);
+
+CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
+                                             struct curl_llist **list_ptr);
+
+bool Curl_pipeline_checkget_write(struct SessionHandle *data,
+                                  struct connectdata *conn);
+bool Curl_pipeline_checkget_read(struct SessionHandle *data,
+                                 struct connectdata *conn);
+void Curl_pipeline_leave_write(struct connectdata *conn);
+void Curl_pipeline_leave_read(struct connectdata *conn);
+bool Curl_recvpipe_head(struct SessionHandle *data,
+                        struct connectdata *conn);
+bool Curl_sendpipe_head(struct SessionHandle *data,
+                        struct connectdata *conn);
+
+#endif /* HEADER_CURL_PIPELINE_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/pop3.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/pop3.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/pop3.c	(revision 164)
@@ -0,0 +1,1609 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC1734 POP3 Authentication
+ * RFC1939 POP3 protocol
+ * RFC2195 CRAM-MD5 authentication
+ * RFC2384 POP URL Scheme
+ * RFC2449 POP3 Extension Mechanism
+ * RFC2595 Using TLS with IMAP, POP3 and ACAP
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC4422 Simple Authentication and Security Layer (SASL)
+ * RFC4616 PLAIN authentication
+ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
+ * RFC5034 POP3 SASL Authentication Mechanism
+ * RFC6749 OAuth 2.0 Authorization Framework
+ * Draft   LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_POP3
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "socks.h"
+#include "pop3.h"
+
+#include "strtoofft.h"
+#include "strequal.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "select.h"
+#include "multiif.h"
+#include "url.h"
+#include "rawstr.h"
+#include "curl_sasl.h"
+#include "curl_md5.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* Local API functions */
+static CURLcode pop3_regular_transfer(struct connectdata *conn, bool *done);
+static CURLcode pop3_do(struct connectdata *conn, bool *done);
+static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
+                          bool premature);
+static CURLcode pop3_connect(struct connectdata *conn, bool *done);
+static CURLcode pop3_disconnect(struct connectdata *conn, bool dead);
+static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done);
+static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks);
+static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done);
+static CURLcode pop3_setup_connection(struct connectdata *conn);
+static CURLcode pop3_parse_url_options(struct connectdata *conn);
+static CURLcode pop3_parse_url_path(struct connectdata *conn);
+static CURLcode pop3_parse_custom_request(struct connectdata *conn);
+static CURLcode pop3_perform_auth(struct connectdata *conn, const char *mech,
+                                  const char *initresp);
+static CURLcode pop3_continue_auth(struct connectdata *conn, const char *resp);
+static void pop3_get_message(char *buffer, char** outptr);
+
+/*
+ * POP3 protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_pop3 = {
+  "POP3",                           /* scheme */
+  pop3_setup_connection,            /* setup_connection */
+  pop3_do,                          /* do_it */
+  pop3_done,                        /* done */
+  ZERO_NULL,                        /* do_more */
+  pop3_connect,                     /* connect_it */
+  pop3_multi_statemach,             /* connecting */
+  pop3_doing,                       /* doing */
+  pop3_getsock,                     /* proto_getsock */
+  pop3_getsock,                     /* doing_getsock */
+  ZERO_NULL,                        /* domore_getsock */
+  ZERO_NULL,                        /* perform_getsock */
+  pop3_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
+  PORT_POP3,                        /* defport */
+  CURLPROTO_POP3,                   /* protocol */
+  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * POP3S protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_pop3s = {
+  "POP3S",                          /* scheme */
+  pop3_setup_connection,            /* setup_connection */
+  pop3_do,                          /* do_it */
+  pop3_done,                        /* done */
+  ZERO_NULL,                        /* do_more */
+  pop3_connect,                     /* connect_it */
+  pop3_multi_statemach,             /* connecting */
+  pop3_doing,                       /* doing */
+  pop3_getsock,                     /* proto_getsock */
+  pop3_getsock,                     /* doing_getsock */
+  ZERO_NULL,                        /* domore_getsock */
+  ZERO_NULL,                        /* perform_getsock */
+  pop3_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
+  PORT_POP3S,                       /* defport */
+  CURLPROTO_POP3S,                  /* protocol */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL
+  | PROTOPT_NOURLQUERY              /* flags */
+};
+#endif
+
+#ifndef CURL_DISABLE_HTTP
+/*
+ * HTTP-proxyed POP3 protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_pop3_proxy = {
+  "POP3",                               /* scheme */
+  Curl_http_setup_conn,                 /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_POP3,                            /* defport */
+  CURLPROTO_HTTP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * HTTP-proxyed POP3S protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_pop3s_proxy = {
+  "POP3S",                              /* scheme */
+  Curl_http_setup_conn,                 /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_POP3S,                           /* defport */
+  CURLPROTO_HTTP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+#endif
+#endif
+
+/* SASL parameters for the pop3 protocol */
+static const struct SASLproto saslpop3 = {
+  "pop",                      /* The service name */
+  '*',                        /* Code received when continuation is expected */
+  '+',                        /* Code to receive upon authentication success */
+  255 - 8,                    /* Maximum initial response length (no max) */
+  pop3_perform_auth,          /* Send authentication command */
+  pop3_continue_auth,         /* Send authentication continuation */
+  pop3_get_message            /* Get SASL response message */
+};
+
+#ifdef USE_SSL
+static void pop3_to_pop3s(struct connectdata *conn)
+{
+  conn->handler = &Curl_handler_pop3s;
+}
+#else
+#define pop3_to_pop3s(x) Curl_nop_stmt
+#endif
+
+/***********************************************************************
+ *
+ * pop3_endofresp()
+ *
+ * Checks for an ending POP3 status code at the start of the given string, but
+ * also detects the APOP timestamp from the server greeting and various
+ * capabilities from the CAPA response including the supported authentication
+ * types and allowed SASL mechanisms.
+ */
+static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len,
+                           int *resp)
+{
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  /* Do we have an error response? */
+  if(len >= 4 && !memcmp("-ERR", line, 4)) {
+    *resp = '-';
+
+    return TRUE;
+  }
+
+  /* Are we processing CAPA command responses? */
+  if(pop3c->state == POP3_CAPA) {
+    /* Do we have the terminating line? */
+    if(len >= 1 && !memcmp(line, ".", 1))
+      /* Treat the response as a success */
+      *resp = '+';
+    else
+      /* Treat the response as an untagged continuation */
+      *resp = '*';
+
+    return TRUE;
+  }
+
+  /* Do we have a success response? */
+  if(len >= 3 && !memcmp("+OK", line, 3)) {
+    *resp = '+';
+
+    return TRUE;
+  }
+
+  /* Do we have a continuation response? */
+  if(len >= 1 && !memcmp("+", line, 1)) {
+    *resp = '*';
+
+    return TRUE;
+  }
+
+  return FALSE; /* Nothing for us */
+}
+
+/***********************************************************************
+ *
+ * pop3_get_message()
+ *
+ * Gets the authentication message from the response buffer.
+ */
+static void pop3_get_message(char *buffer, char** outptr)
+{
+  size_t len = 0;
+  char* message = NULL;
+
+  /* Find the start of the message */
+  for(message = buffer + 2; *message == ' ' || *message == '\t'; message++)
+    ;
+
+  /* Find the end of the message */
+  for(len = strlen(message); len--;)
+    if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' &&
+        message[len] != '\t')
+      break;
+
+  /* Terminate the message */
+  if(++len) {
+    message[len] = '\0';
+  }
+
+  *outptr = message;
+}
+
+/***********************************************************************
+ *
+ * state()
+ *
+ * This is the ONLY way to change POP3 state!
+ */
+static void state(struct connectdata *conn, pop3state newstate)
+{
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[] = {
+    "STOP",
+    "SERVERGREET",
+    "CAPA",
+    "STARTTLS",
+    "UPGRADETLS",
+    "AUTH",
+    "APOP",
+    "USER",
+    "PASS",
+    "COMMAND",
+    "QUIT",
+    /* LAST */
+  };
+
+  if(pop3c->state != newstate)
+    infof(conn->data, "POP3 %p state change from %s to %s\n",
+          (void *)pop3c, names[pop3c->state], names[newstate]);
+#endif
+
+  pop3c->state = newstate;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_capa()
+ *
+ * Sends the CAPA command in order to obtain a list of server side supported
+ * capabilities.
+ */
+static CURLcode pop3_perform_capa(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  pop3c->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */
+  pop3c->sasl.authused = SASL_AUTH_NONE;  /* Clear the auth. mechanism used */
+  pop3c->tls_supported = FALSE;           /* Clear the TLS capability */
+
+  /* Send the CAPA command */
+  result = Curl_pp_sendf(&pop3c->pp, "%s", "CAPA");
+
+  if(!result)
+    state(conn, POP3_CAPA);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_starttls()
+ *
+ * Sends the STLS command to start the upgrade to TLS.
+ */
+static CURLcode pop3_perform_starttls(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Send the STLS command */
+  result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "STLS");
+
+  if(!result)
+    state(conn, POP3_STARTTLS);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_upgrade_tls()
+ *
+ * Performs the upgrade to TLS.
+ */
+static CURLcode pop3_perform_upgrade_tls(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  /* Start the SSL connection */
+  result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone);
+
+  if(!result) {
+    if(pop3c->state != POP3_UPGRADETLS)
+      state(conn, POP3_UPGRADETLS);
+
+    if(pop3c->ssldone) {
+      pop3_to_pop3s(conn);
+      result = pop3_perform_capa(conn);
+    }
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_user()
+ *
+ * Sends a clear text USER command to authenticate with.
+ */
+static CURLcode pop3_perform_user(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Check we have a username and password to authenticate with and end the
+     connect phase if we don't */
+  if(!conn->bits.user_passwd) {
+    state(conn, POP3_STOP);
+
+    return result;
+  }
+
+  /* Send the USER command */
+  result = Curl_pp_sendf(&conn->proto.pop3c.pp, "USER %s",
+                         conn->user ? conn->user : "");
+  if(!result)
+    state(conn, POP3_USER);
+
+  return result;
+}
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+/***********************************************************************
+ *
+ * pop3_perform_apop()
+ *
+ * Sends an APOP command to authenticate with.
+ */
+static CURLcode pop3_perform_apop(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  size_t i;
+  MD5_context *ctxt;
+  unsigned char digest[MD5_DIGEST_LEN];
+  char secret[2 * MD5_DIGEST_LEN + 1];
+
+  /* Check we have a username and password to authenticate with and end the
+     connect phase if we don't */
+  if(!conn->bits.user_passwd) {
+    state(conn, POP3_STOP);
+
+    return result;
+  }
+
+  /* Create the digest */
+  ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+  if(!ctxt)
+    return CURLE_OUT_OF_MEMORY;
+
+  Curl_MD5_update(ctxt, (const unsigned char *) pop3c->apoptimestamp,
+                  curlx_uztoui(strlen(pop3c->apoptimestamp)));
+
+  Curl_MD5_update(ctxt, (const unsigned char *) conn->passwd,
+                  curlx_uztoui(strlen(conn->passwd)));
+
+  /* Finalise the digest */
+  Curl_MD5_final(ctxt, digest);
+
+  /* Convert the calculated 16 octet digest into a 32 byte hex string */
+  for(i = 0; i < MD5_DIGEST_LEN; i++)
+    snprintf(&secret[2 * i], 3, "%02x", digest[i]);
+
+  result = Curl_pp_sendf(&pop3c->pp, "APOP %s %s", conn->user, secret);
+
+  if(!result)
+    state(conn, POP3_APOP);
+
+  return result;
+}
+#endif
+
+/***********************************************************************
+ *
+ * pop3_perform_auth()
+ *
+ * Sends an AUTH command allowing the client to login with the given SASL
+ * authentication mechanism.
+ */
+static CURLcode pop3_perform_auth(struct connectdata *conn,
+                                  const char *mech,
+                                  const char *initresp)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  if(initresp) {                                  /* AUTH <mech> ...<crlf> */
+    /* Send the AUTH command with the initial response */
+    result = Curl_pp_sendf(&pop3c->pp, "AUTH %s %s", mech, initresp);
+  }
+  else {
+    /* Send the AUTH command */
+    result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech);
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_continue_auth()
+ *
+ * Sends SASL continuation data or cancellation.
+ */
+static CURLcode pop3_continue_auth(struct connectdata *conn,
+                                   const char *resp)
+{
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  return Curl_pp_sendf(&pop3c->pp, "%s", resp);
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_authentication()
+ *
+ * Initiates the authentication sequence, with the appropriate SASL
+ * authentication mechanism, falling back to APOP and clear text should a
+ * common mechanism not be available between the client and server.
+ */
+static CURLcode pop3_perform_authentication(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  saslprogress progress = SASL_IDLE;
+
+  /* Check we have enough data to authenticate with and end the
+     connect phase if we don't */
+  if(!Curl_sasl_can_authenticate(&pop3c->sasl, conn)) {
+    state(conn, POP3_STOP);
+    return result;
+  }
+
+  if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_SASL) {
+    /* Calculate the SASL login details */
+    result = Curl_sasl_start(&pop3c->sasl, conn, FALSE, &progress);
+
+    if(!result)
+      if(progress == SASL_INPROGRESS)
+        state(conn, POP3_AUTH);
+  }
+
+  if(!result && progress == SASL_IDLE) {
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+    if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP)
+      /* Perform APOP authentication */
+      result = pop3_perform_apop(conn);
+    else
+#endif
+    if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT)
+      /* Perform clear text authentication */
+      result = pop3_perform_user(conn);
+    else {
+      /* Other mechanisms not supported */
+      infof(conn->data, "No known authentication mechanisms supported!\n");
+      result = CURLE_LOGIN_DENIED;
+    }
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_command()
+ *
+ * Sends a POP3 based command.
+ */
+static CURLcode pop3_perform_command(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct POP3 *pop3 = data->req.protop;
+  const char *command = NULL;
+
+  /* Calculate the default command */
+  if(pop3->id[0] == '\0' || conn->data->set.ftp_list_only) {
+    command = "LIST";
+
+    if(pop3->id[0] != '\0')
+      /* Message specific LIST so skip the BODY transfer */
+      pop3->transfer = FTPTRANSFER_INFO;
+  }
+  else
+    command = "RETR";
+
+  /* Send the command */
+  if(pop3->id[0] != '\0')
+    result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s",
+                           (pop3->custom && pop3->custom[0] != '\0' ?
+                            pop3->custom : command), pop3->id);
+  else
+    result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s",
+                           (pop3->custom && pop3->custom[0] != '\0' ?
+                            pop3->custom : command));
+
+  if(!result)
+    state(conn, POP3_COMMAND);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_quit()
+ *
+ * Performs the quit action prior to sclose() be called.
+ */
+static CURLcode pop3_perform_quit(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Send the QUIT command */
+  result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "QUIT");
+
+  if(!result)
+    state(conn, POP3_QUIT);
+
+  return result;
+}
+
+/* For the initial server greeting */
+static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
+                                            int pop3code,
+                                            pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  const char *line = data->state.buffer;
+  size_t len = strlen(line);
+  size_t i;
+
+  (void)instate; /* no use for this yet */
+
+  if(pop3code != '+') {
+    failf(data, "Got unexpected pop3-server response");
+    result = CURLE_FTP_WEIRD_SERVER_REPLY;
+  }
+  else {
+    /* Does the server support APOP authentication? */
+    if(len >= 4 && line[len - 2] == '>') {
+      /* Look for the APOP timestamp */
+      for(i = 3; i < len - 2; ++i) {
+        if(line[i] == '<') {
+          /* Calculate the length of the timestamp */
+          size_t timestamplen = len - 1 - i;
+          if(!timestamplen)
+            break;
+
+          /* Allocate some memory for the timestamp */
+          pop3c->apoptimestamp = (char *)calloc(1, timestamplen + 1);
+
+          if(!pop3c->apoptimestamp)
+            break;
+
+          /* Copy the timestamp */
+          memcpy(pop3c->apoptimestamp, line + i, timestamplen);
+          pop3c->apoptimestamp[timestamplen] = '\0';
+
+          /* Store the APOP capability */
+          pop3c->authtypes |= POP3_TYPE_APOP;
+          break;
+        }
+      }
+    }
+
+    result = pop3_perform_capa(conn);
+  }
+
+  return result;
+}
+
+/* For CAPA responses */
+static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
+                                     pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  const char *line = data->state.buffer;
+  size_t len = strlen(line);
+  size_t wordlen;
+
+  (void)instate; /* no use for this yet */
+
+  /* Do we have a untagged continuation response? */
+  if(pop3code == '*') {
+    /* Does the server support the STLS capability? */
+    if(len >= 4 && !memcmp(line, "STLS", 4))
+      pop3c->tls_supported = TRUE;
+
+    /* Does the server support clear text authentication? */
+    else if(len >= 4 && !memcmp(line, "USER", 4))
+      pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
+
+    /* Does the server support SASL based authentication? */
+    else if(len >= 5 && !memcmp(line, "SASL ", 5)) {
+      pop3c->authtypes |= POP3_TYPE_SASL;
+
+      /* Advance past the SASL keyword */
+      line += 5;
+      len -= 5;
+
+      /* Loop through the data line */
+      for(;;) {
+        size_t llen;
+        unsigned int mechbit;
+
+        while(len &&
+              (*line == ' ' || *line == '\t' ||
+               *line == '\r' || *line == '\n')) {
+
+          line++;
+          len--;
+        }
+
+        if(!len)
+          break;
+
+        /* Extract the word */
+        for(wordlen = 0; wordlen < len && line[wordlen] != ' ' &&
+              line[wordlen] != '\t' && line[wordlen] != '\r' &&
+              line[wordlen] != '\n';)
+          wordlen++;
+
+        /* Test the word for a matching authentication mechanism */
+        if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
+           llen == wordlen)
+          pop3c->sasl.authmechs |= mechbit;
+
+        line += wordlen;
+        len -= wordlen;
+      }
+    }
+  }
+  else if(pop3code == '+') {
+    if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+      /* We don't have a SSL/TLS connection yet, but SSL is requested */
+      if(pop3c->tls_supported)
+        /* Switch to TLS connection now */
+        result = pop3_perform_starttls(conn);
+      else if(data->set.use_ssl == CURLUSESSL_TRY)
+        /* Fallback and carry on with authentication */
+        result = pop3_perform_authentication(conn);
+      else {
+        failf(data, "STLS not supported.");
+        result = CURLE_USE_SSL_FAILED;
+      }
+    }
+    else
+      result = pop3_perform_authentication(conn);
+  }
+  else {
+    /* Clear text is supported when CAPA isn't recognised */
+    pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
+
+    result = pop3_perform_authentication(conn);
+  }
+
+  return result;
+}
+
+/* For STARTTLS responses */
+static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
+                                         int pop3code,
+                                         pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(pop3code != '+') {
+    if(data->set.use_ssl != CURLUSESSL_TRY) {
+      failf(data, "STARTTLS denied. %c", pop3code);
+      result = CURLE_USE_SSL_FAILED;
+    }
+    else
+      result = pop3_perform_authentication(conn);
+  }
+  else
+    result = pop3_perform_upgrade_tls(conn);
+
+  return result;
+}
+
+/* For SASL authentication responses */
+static CURLcode pop3_state_auth_resp(struct connectdata *conn,
+                                     int pop3code,
+                                     pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  saslprogress progress;
+
+  (void)instate; /* no use for this yet */
+
+  result = Curl_sasl_continue(&pop3c->sasl, conn, pop3code, &progress);
+  if(!result)
+    switch(progress) {
+    case SASL_DONE:
+      state(conn, POP3_STOP);  /* Authenticated */
+      break;
+    case SASL_IDLE:            /* No mechanism left after cancellation */
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+      if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP)
+        /* Perform APOP authentication */
+        result = pop3_perform_apop(conn);
+      else
+#endif
+      if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT)
+        /* Perform clear text authentication */
+        result = pop3_perform_user(conn);
+      else {
+        failf(data, "Authentication cancelled");
+        result = CURLE_LOGIN_DENIED;
+      }
+      break;
+    default:
+      break;
+    }
+
+  return result;
+}
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+/* For APOP responses */
+static CURLcode pop3_state_apop_resp(struct connectdata *conn, int pop3code,
+                                     pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(pop3code != '+') {
+    failf(data, "Authentication failed: %d", pop3code);
+    result = CURLE_LOGIN_DENIED;
+  }
+  else
+    /* End of connect phase */
+    state(conn, POP3_STOP);
+
+  return result;
+}
+#endif
+
+/* For USER responses */
+static CURLcode pop3_state_user_resp(struct connectdata *conn, int pop3code,
+                                     pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(pop3code != '+') {
+    failf(data, "Access denied. %c", pop3code);
+    result = CURLE_LOGIN_DENIED;
+  }
+  else
+    /* Send the PASS command */
+    result = Curl_pp_sendf(&conn->proto.pop3c.pp, "PASS %s",
+                           conn->passwd ? conn->passwd : "");
+  if(!result)
+    state(conn, POP3_PASS);
+
+  return result;
+}
+
+/* For PASS responses */
+static CURLcode pop3_state_pass_resp(struct connectdata *conn, int pop3code,
+                                     pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(pop3code != '+') {
+    failf(data, "Access denied. %c", pop3code);
+    result = CURLE_LOGIN_DENIED;
+  }
+  else
+    /* End of connect phase */
+    state(conn, POP3_STOP);
+
+  return result;
+}
+
+/* For command responses */
+static CURLcode pop3_state_command_resp(struct connectdata *conn,
+                                        int pop3code,
+                                        pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct POP3 *pop3 = data->req.protop;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  struct pingpong *pp = &pop3c->pp;
+
+  (void)instate; /* no use for this yet */
+
+  if(pop3code != '+') {
+    state(conn, POP3_STOP);
+    return CURLE_RECV_ERROR;
+  }
+
+  /* This 'OK' line ends with a CR LF pair which is the two first bytes of the
+     EOB string so count this is two matching bytes. This is necessary to make
+     the code detect the EOB if the only data than comes now is %2e CR LF like
+     when there is no body to return. */
+  pop3c->eob = 2;
+
+  /* But since this initial CR LF pair is not part of the actual body, we set
+     the strip counter here so that these bytes won't be delivered. */
+  pop3c->strip = 2;
+
+  if(pop3->transfer == FTPTRANSFER_BODY) {
+    /* POP3 download */
+    Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
+
+    if(pp->cache) {
+      /* The header "cache" contains a bunch of data that is actually body
+         content so send it as such. Note that there may even be additional
+         "headers" after the body */
+
+      if(!data->set.opt_no_body) {
+        result = Curl_pop3_write(conn, pp->cache, pp->cache_size);
+        if(result)
+          return result;
+      }
+
+      /* Free the cache */
+      Curl_safefree(pp->cache);
+
+      /* Reset the cache size */
+      pp->cache_size = 0;
+    }
+  }
+
+  /* End of DO phase */
+  state(conn, POP3_STOP);
+
+  return result;
+}
+
+static CURLcode pop3_statemach_act(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  int pop3code;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  struct pingpong *pp = &pop3c->pp;
+  size_t nread = 0;
+
+  /* Busy upgrading the connection; right now all I/O is SSL/TLS, not POP3 */
+  if(pop3c->state == POP3_UPGRADETLS)
+    return pop3_perform_upgrade_tls(conn);
+
+  /* Flush any data that needs to be sent */
+  if(pp->sendleft)
+    return Curl_pp_flushsend(pp);
+
+ do {
+    /* Read the response from the server */
+    result = Curl_pp_readresp(sock, pp, &pop3code, &nread);
+    if(result)
+      return result;
+
+    if(!pop3code)
+      break;
+
+    /* We have now received a full POP3 server response */
+    switch(pop3c->state) {
+    case POP3_SERVERGREET:
+      result = pop3_state_servergreet_resp(conn, pop3code, pop3c->state);
+      break;
+
+    case POP3_CAPA:
+      result = pop3_state_capa_resp(conn, pop3code, pop3c->state);
+      break;
+
+    case POP3_STARTTLS:
+      result = pop3_state_starttls_resp(conn, pop3code, pop3c->state);
+      break;
+
+    case POP3_AUTH:
+      result = pop3_state_auth_resp(conn, pop3code, pop3c->state);
+      break;
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+    case POP3_APOP:
+      result = pop3_state_apop_resp(conn, pop3code, pop3c->state);
+      break;
+#endif
+
+    case POP3_USER:
+      result = pop3_state_user_resp(conn, pop3code, pop3c->state);
+      break;
+
+    case POP3_PASS:
+      result = pop3_state_pass_resp(conn, pop3code, pop3c->state);
+      break;
+
+    case POP3_COMMAND:
+      result = pop3_state_command_resp(conn, pop3code, pop3c->state);
+      break;
+
+    case POP3_QUIT:
+      /* fallthrough, just stop! */
+    default:
+      /* internal error */
+      state(conn, POP3_STOP);
+      break;
+    }
+  } while(!result && pop3c->state != POP3_STOP && Curl_pp_moredata(pp));
+
+  return result;
+}
+
+/* Called repeatedly until done from multi.c */
+static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) {
+    result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone);
+    if(result || !pop3c->ssldone)
+      return result;
+  }
+
+  result = Curl_pp_statemach(&pop3c->pp, FALSE);
+  *done = (pop3c->state == POP3_STOP) ? TRUE : FALSE;
+
+  return result;
+}
+
+static CURLcode pop3_block_statemach(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  while(pop3c->state != POP3_STOP && !result)
+    result = Curl_pp_statemach(&pop3c->pp, TRUE);
+
+  return result;
+}
+
+/* Allocate and initialize the POP3 struct for the current SessionHandle if
+   required */
+static CURLcode pop3_init(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct POP3 *pop3;
+
+  pop3 = data->req.protop = calloc(sizeof(struct POP3), 1);
+  if(!pop3)
+    result = CURLE_OUT_OF_MEMORY;
+
+  return result;
+}
+
+/* For the POP3 "protocol connect" and "doing" phases only */
+static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks)
+{
+  return Curl_pp_getsock(&conn->proto.pop3c.pp, socks, numsocks);
+}
+
+/***********************************************************************
+ *
+ * pop3_connect()
+ *
+ * This function should do everything that is to be considered a part of the
+ * connection phase.
+ *
+ * The variable 'done' points to will be TRUE if the protocol-layer connect
+ * phase is done when this function returns, or FALSE if not.
+ */
+static CURLcode pop3_connect(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  struct pingpong *pp = &pop3c->pp;
+
+  *done = FALSE; /* default to not done yet */
+
+  /* We always support persistent connections in POP3 */
+  connkeep(conn, "POP3 default");
+
+  /* Set the default response time-out */
+  pp->response_time = RESP_TIMEOUT;
+  pp->statemach_act = pop3_statemach_act;
+  pp->endofresp = pop3_endofresp;
+  pp->conn = conn;
+
+  /* Set the default preferred authentication type and mechanism */
+  pop3c->preftype = POP3_TYPE_ANY;
+  Curl_sasl_init(&pop3c->sasl, &saslpop3);
+
+  /* Initialise the pingpong layer */
+  Curl_pp_init(pp);
+
+  /* Parse the URL options */
+  result = pop3_parse_url_options(conn);
+  if(result)
+    return result;
+
+  /* Start off waiting for the server greeting response */
+  state(conn, POP3_SERVERGREET);
+
+  result = pop3_multi_statemach(conn, done);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_done()
+ *
+ * The DONE function. This does what needs to be done after a single DO has
+ * performed.
+ *
+ * Input argument is already checked for validity.
+ */
+static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
+                          bool premature)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct POP3 *pop3 = data->req.protop;
+
+  (void)premature;
+
+  if(!pop3)
+    /* When the easy handle is removed from the multi interface while libcurl
+       is still trying to resolve the host name, the POP3 struct is not yet
+       initialized. However, the removal action calls Curl_done() which in
+       turn calls this function, so we simply return success. */
+    return CURLE_OK;
+
+  if(status) {
+    connclose(conn, "POP3 done with bad status");
+    result = status;         /* use the already set error code */
+  }
+
+  /* Cleanup our per-request based variables */
+  Curl_safefree(pop3->id);
+  Curl_safefree(pop3->custom);
+
+  /* Clear the transfer mode for the next request */
+  pop3->transfer = FTPTRANSFER_BODY;
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform()
+ *
+ * This is the actual DO function for POP3. Get a message/listing according to
+ * the options previously setup.
+ */
+static CURLcode pop3_perform(struct connectdata *conn, bool *connected,
+                             bool *dophase_done)
+{
+  /* This is POP3 and no proxy */
+  CURLcode result = CURLE_OK;
+  struct POP3 *pop3 = conn->data->req.protop;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  if(conn->data->set.opt_no_body) {
+    /* Requested no body means no transfer */
+    pop3->transfer = FTPTRANSFER_INFO;
+  }
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* Start the first command in the DO phase */
+  result = pop3_perform_command(conn);
+  if(result)
+    return result;
+
+  /* Run the state-machine */
+  result = pop3_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done)
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_do()
+ *
+ * This function is registered as 'curl_do' function. It decodes the path
+ * parts etc as a wrapper to the actual DO function (pop3_perform).
+ *
+ * The input argument is already checked for validity.
+ */
+static CURLcode pop3_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+
+  *done = FALSE; /* default to false */
+
+  /* Parse the URL path */
+  result = pop3_parse_url_path(conn);
+  if(result)
+    return result;
+
+  /* Parse the custom request */
+  result = pop3_parse_custom_request(conn);
+  if(result)
+    return result;
+
+  result = pop3_regular_transfer(conn, done);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_disconnect()
+ *
+ * Disconnect from an POP3 server. Cleanup protocol-specific per-connection
+ * resources. BLOCKING.
+ */
+static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  /* We cannot send quit unconditionally. If this connection is stale or
+     bad in any way, sending quit and waiting around here will make the
+     disconnect wait in vain and cause more problems than we need to. */
+
+  /* The POP3 session may or may not have been allocated/setup at this
+     point! */
+  if(!dead_connection && pop3c->pp.conn && pop3c->pp.conn->bits.protoconnstart)
+    if(!pop3_perform_quit(conn))
+      (void)pop3_block_statemach(conn); /* ignore errors on QUIT */
+
+  /* Disconnect from the server */
+  Curl_pp_disconnect(&pop3c->pp);
+
+  /* Cleanup the SASL module */
+  Curl_sasl_cleanup(conn, pop3c->sasl.authused);
+
+  /* Cleanup our connection based variables */
+  Curl_safefree(pop3c->apoptimestamp);
+
+  return CURLE_OK;
+}
+
+/* Call this when the DO phase has completed */
+static CURLcode pop3_dophase_done(struct connectdata *conn, bool connected)
+{
+  (void)conn;
+  (void)connected;
+
+  return CURLE_OK;
+}
+
+/* Called from multi.c while DOing */
+static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done)
+{
+  CURLcode result = pop3_multi_statemach(conn, dophase_done);
+
+  if(result)
+    DEBUGF(infof(conn->data, "DO phase failed\n"));
+  else if(*dophase_done) {
+    result = pop3_dophase_done(conn, FALSE /* not connected */);
+
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_regular_transfer()
+ *
+ * The input argument is already checked for validity.
+ *
+ * Performs all commands done before a regular transfer between a local and a
+ * remote host.
+ */
+static CURLcode pop3_regular_transfer(struct connectdata *conn,
+                                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+  bool connected = FALSE;
+  struct SessionHandle *data = conn->data;
+
+  /* Make sure size is unknown at this point */
+  data->req.size = -1;
+
+  /* Set the progress data */
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  /* Carry out the perform */
+  result = pop3_perform(conn, &connected, dophase_done);
+
+  /* Perform post DO phase operations if necessary */
+  if(!result && *dophase_done)
+    result = pop3_dophase_done(conn, connected);
+
+  return result;
+}
+
+static CURLcode pop3_setup_connection(struct connectdata *conn)
+{
+  struct SessionHandle *data = conn->data;
+
+  /* Initialise the POP3 layer */
+  CURLcode result = pop3_init(conn);
+  if(result)
+    return result;
+
+  if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
+    /* Unless we have asked to tunnel POP3 operations through the proxy, we
+       switch and use HTTP operations only */
+#ifndef CURL_DISABLE_HTTP
+    if(conn->handler == &Curl_handler_pop3)
+      conn->handler = &Curl_handler_pop3_proxy;
+    else {
+#ifdef USE_SSL
+      conn->handler = &Curl_handler_pop3s_proxy;
+#else
+      failf(data, "POP3S not supported!");
+      return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+    }
+
+    /* set it up as an HTTP connection instead */
+    return conn->handler->setup_connection(conn);
+#else
+    failf(data, "POP3 over http proxy requires HTTP support built-in!");
+    return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+  }
+
+  data->state.path++;   /* don't include the initial slash */
+
+  return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * pop3_parse_url_options()
+ *
+ * Parse the URL login options.
+ */
+static CURLcode pop3_parse_url_options(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  const char *ptr = conn->options;
+
+  pop3c->sasl.resetprefs = TRUE;
+
+  while(!result && ptr && *ptr) {
+    const char *key = ptr;
+    const char *value;
+
+    while(*ptr && *ptr != '=')
+        ptr++;
+
+    value = ptr + 1;
+
+    while(*ptr && *ptr != ';')
+      ptr++;
+
+    if(strnequal(key, "AUTH=", 5)) {
+      result = Curl_sasl_parse_url_auth_option(&pop3c->sasl,
+                                               value, ptr - value);
+
+      if(result && strnequal(value, "+APOP", ptr - value)) {
+        pop3c->preftype = POP3_TYPE_APOP;
+        pop3c->sasl.prefmech = SASL_AUTH_NONE;
+        result = CURLE_OK;
+      }
+    }
+    else
+      result = CURLE_URL_MALFORMAT;
+
+    if(*ptr == ';')
+      ptr++;
+  }
+
+  if(pop3c->preftype != POP3_TYPE_APOP)
+    switch(pop3c->sasl.prefmech) {
+    case SASL_AUTH_NONE:
+      pop3c->preftype = POP3_TYPE_NONE;
+      break;
+    case SASL_AUTH_DEFAULT:
+      pop3c->preftype = POP3_TYPE_ANY;
+      break;
+    default:
+      pop3c->preftype = POP3_TYPE_SASL;
+      break;
+    }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_parse_url_path()
+ *
+ * Parse the URL path into separate path components.
+ */
+static CURLcode pop3_parse_url_path(struct connectdata *conn)
+{
+  /* The POP3 struct is already initialised in pop3_connect() */
+  struct SessionHandle *data = conn->data;
+  struct POP3 *pop3 = data->req.protop;
+  const char *path = data->state.path;
+
+  /* URL decode the path for the message ID */
+  return Curl_urldecode(data, path, 0, &pop3->id, NULL, TRUE);
+}
+
+/***********************************************************************
+ *
+ * pop3_parse_custom_request()
+ *
+ * Parse the custom request.
+ */
+static CURLcode pop3_parse_custom_request(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct POP3 *pop3 = data->req.protop;
+  const char *custom = data->set.str[STRING_CUSTOMREQUEST];
+
+  /* URL decode the custom request */
+  if(custom)
+    result = Curl_urldecode(data, custom, 0, &pop3->custom, NULL, TRUE);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * Curl_pop3_write()
+ *
+ * This function scans the body after the end-of-body and writes everything
+ * until the end is found.
+ */
+CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread)
+{
+  /* This code could be made into a special function in the handler struct */
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct SingleRequest *k = &data->req;
+
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  bool strip_dot = FALSE;
+  size_t last = 0;
+  size_t i;
+
+  /* Search through the buffer looking for the end-of-body marker which is
+     5 bytes (0d 0a 2e 0d 0a). Note that a line starting with a dot matches
+     the eob so the server will have prefixed it with an extra dot which we
+     need to strip out. Additionally the marker could of course be spread out
+     over 5 different data chunks. */
+  for(i = 0; i < nread; i++) {
+    size_t prev = pop3c->eob;
+
+    switch(str[i]) {
+    case 0x0d:
+      if(pop3c->eob == 0) {
+        pop3c->eob++;
+
+        if(i) {
+          /* Write out the body part that didn't match */
+          result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last],
+                                     i - last);
+
+          if(result)
+            return result;
+
+          last = i;
+        }
+      }
+      else if(pop3c->eob == 3)
+        pop3c->eob++;
+      else
+        /* If the character match wasn't at position 0 or 3 then restart the
+           pattern matching */
+        pop3c->eob = 1;
+      break;
+
+    case 0x0a:
+      if(pop3c->eob == 1 || pop3c->eob == 4)
+        pop3c->eob++;
+      else
+        /* If the character match wasn't at position 1 or 4 then start the
+           search again */
+        pop3c->eob = 0;
+      break;
+
+    case 0x2e:
+      if(pop3c->eob == 2)
+        pop3c->eob++;
+      else if(pop3c->eob == 3) {
+        /* We have an extra dot after the CRLF which we need to strip off */
+        strip_dot = TRUE;
+        pop3c->eob = 0;
+      }
+      else
+        /* If the character match wasn't at position 2 then start the search
+           again */
+        pop3c->eob = 0;
+      break;
+
+    default:
+      pop3c->eob = 0;
+      break;
+    }
+
+    /* Did we have a partial match which has subsequently failed? */
+    if(prev && prev >= pop3c->eob) {
+      /* Strip can only be non-zero for the very first mismatch after CRLF
+         and then both prev and strip are equal and nothing will be output
+         below */
+      while(prev && pop3c->strip) {
+        prev--;
+        pop3c->strip--;
+      }
+
+      if(prev) {
+        /* If the partial match was the CRLF and dot then only write the CRLF
+           as the server would have inserted the dot */
+        result = Curl_client_write(conn, CLIENTWRITE_BODY, (char*)POP3_EOB,
+                                   strip_dot ? prev - 1 : prev);
+
+        if(result)
+          return result;
+
+        last = i;
+        strip_dot = FALSE;
+      }
+    }
+  }
+
+  if(pop3c->eob == POP3_EOB_LEN) {
+    /* We have a full match so the transfer is done, however we must transfer
+    the CRLF at the start of the EOB as this is considered to be part of the
+    message as per RFC-1939, sect. 3 */
+    result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)POP3_EOB, 2);
+
+    k->keepon &= ~KEEP_RECV;
+    pop3c->eob = 0;
+
+    return result;
+  }
+
+  if(pop3c->eob)
+    /* While EOB is matching nothing should be output */
+    return CURLE_OK;
+
+  if(nread - last) {
+    result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last],
+                               nread - last);
+  }
+
+  return result;
+}
+
+#endif /* CURL_DISABLE_POP3 */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/pop3.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/pop3.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/pop3.h	(revision 164)
@@ -0,0 +1,95 @@
+#ifndef HEADER_CURL_POP3_H
+#define HEADER_CURL_POP3_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2009 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "pingpong.h"
+#include "curl_sasl.h"
+
+/****************************************************************************
+ * POP3 unique setup
+ ***************************************************************************/
+typedef enum {
+  POP3_STOP,         /* do nothing state, stops the state machine */
+  POP3_SERVERGREET,  /* waiting for the initial greeting immediately after
+                        a connect */
+  POP3_CAPA,
+  POP3_STARTTLS,
+  POP3_UPGRADETLS,   /* asynchronously upgrade the connection to SSL/TLS
+                       (multi mode only) */
+  POP3_AUTH,
+  POP3_APOP,
+  POP3_USER,
+  POP3_PASS,
+  POP3_COMMAND,
+  POP3_QUIT,
+  POP3_LAST          /* never used */
+} pop3state;
+
+/* This POP3 struct is used in the SessionHandle. All POP3 data that is
+   connection-oriented must be in pop3_conn to properly deal with the fact that
+   perhaps the SessionHandle is changed between the times the connection is
+   used. */
+struct POP3 {
+  curl_pp_transfer transfer;
+  char *id;               /* Message ID */
+  char *custom;           /* Custom Request */
+};
+
+/* pop3_conn is used for struct connection-oriented data in the connectdata
+   struct */
+struct pop3_conn {
+  struct pingpong pp;
+  pop3state state;        /* Always use pop3.c:state() to change state! */
+  bool ssldone;           /* Is connect() over SSL done? */
+  size_t eob;             /* Number of bytes of the EOB (End Of Body) that
+                             have been received so far */
+  size_t strip;           /* Number of bytes from the start to ignore as
+                             non-body */
+  struct SASL sasl;       /* SASL-related storage */
+  unsigned int authtypes; /* Accepted authentication types */
+  unsigned int preftype;  /* Preferred authentication type */
+  char *apoptimestamp;    /* APOP timestamp from the server greeting */
+  bool tls_supported;     /* StartTLS capability supported by server */
+};
+
+extern const struct Curl_handler Curl_handler_pop3;
+extern const struct Curl_handler Curl_handler_pop3s;
+
+/* Authentication type flags */
+#define POP3_TYPE_CLEARTEXT (1 << 0)
+#define POP3_TYPE_APOP      (1 << 1)
+#define POP3_TYPE_SASL      (1 << 2)
+
+/* Authentication type values */
+#define POP3_TYPE_NONE      0
+#define POP3_TYPE_ANY       ~0U
+
+/* This is the 5-bytes End-Of-Body marker for POP3 */
+#define POP3_EOB "\x0d\x0a\x2e\x0d\x0a"
+#define POP3_EOB_LEN 5
+
+/* This function scans the body after the end-of-body and writes everything
+ * until the end is found */
+CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread);
+
+#endif /* HEADER_CURL_POP3_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/progress.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/progress.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/progress.c	(revision 164)
@@ -0,0 +1,492 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "urldata.h"
+#include "sendf.h"
+#include "progress.h"
+#include "curl_printf.h"
+
+/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
+   byte) */
+static void time2str(char *r, curl_off_t seconds)
+{
+  curl_off_t d, h, m, s;
+  if(seconds <= 0) {
+    strcpy(r, "--:--:--");
+    return;
+  }
+  h = seconds / CURL_OFF_T_C(3600);
+  if(h <= CURL_OFF_T_C(99)) {
+    m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60);
+    s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60));
+    snprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T ":%02" CURL_FORMAT_CURL_OFF_T
+             ":%02" CURL_FORMAT_CURL_OFF_T, h, m, s);
+  }
+  else {
+    /* this equals to more than 99 hours, switch to a more suitable output
+       format to fit within the limits. */
+    d = seconds / CURL_OFF_T_C(86400);
+    h = (seconds - (d*CURL_OFF_T_C(86400))) / CURL_OFF_T_C(3600);
+    if(d <= CURL_OFF_T_C(999))
+      snprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T
+               "d %02" CURL_FORMAT_CURL_OFF_T "h", d, h);
+    else
+      snprintf(r, 9, "%7" CURL_FORMAT_CURL_OFF_T "d", d);
+  }
+}
+
+/* The point of this function would be to return a string of the input data,
+   but never longer than 5 columns (+ one zero byte).
+   Add suffix k, M, G when suitable... */
+static char *max5data(curl_off_t bytes, char *max5)
+{
+#define ONE_KILOBYTE  CURL_OFF_T_C(1024)
+#define ONE_MEGABYTE (CURL_OFF_T_C(1024) * ONE_KILOBYTE)
+#define ONE_GIGABYTE (CURL_OFF_T_C(1024) * ONE_MEGABYTE)
+#define ONE_TERABYTE (CURL_OFF_T_C(1024) * ONE_GIGABYTE)
+#define ONE_PETABYTE (CURL_OFF_T_C(1024) * ONE_TERABYTE)
+
+  if(bytes < CURL_OFF_T_C(100000))
+    snprintf(max5, 6, "%5" CURL_FORMAT_CURL_OFF_T, bytes);
+
+  else if(bytes < CURL_OFF_T_C(10000) * ONE_KILOBYTE)
+    snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "k", bytes/ONE_KILOBYTE);
+
+  else if(bytes < CURL_OFF_T_C(100) * ONE_MEGABYTE)
+    /* 'XX.XM' is good as long as we're less than 100 megs */
+    snprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
+             CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE,
+             (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/CURL_OFF_T_C(10)) );
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+
+  else if(bytes < CURL_OFF_T_C(10000) * ONE_MEGABYTE)
+    /* 'XXXXM' is good until we're at 10000MB or above */
+    snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE);
+
+  else if(bytes < CURL_OFF_T_C(100) * ONE_GIGABYTE)
+    /* 10000 MB - 100 GB, we show it as XX.XG */
+    snprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
+             CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE,
+             (bytes%ONE_GIGABYTE) / (ONE_GIGABYTE/CURL_OFF_T_C(10)) );
+
+  else if(bytes < CURL_OFF_T_C(10000) * ONE_GIGABYTE)
+    /* up to 10000GB, display without decimal: XXXXG */
+    snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE);
+
+  else if(bytes < CURL_OFF_T_C(10000) * ONE_TERABYTE)
+    /* up to 10000TB, display without decimal: XXXXT */
+    snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "T", bytes/ONE_TERABYTE);
+
+  else
+    /* up to 10000PB, display without decimal: XXXXP */
+    snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "P", bytes/ONE_PETABYTE);
+
+    /* 16384 petabytes (16 exabytes) is the maximum a 64 bit unsigned number
+       can hold, but our data type is signed so 8192PB will be the maximum. */
+
+#else
+
+  else
+    snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE);
+
+#endif
+
+  return max5;
+}
+
+/*
+
+   New proposed interface, 9th of February 2000:
+
+   pgrsStartNow() - sets start time
+   pgrsSetDownloadSize(x) - known expected download size
+   pgrsSetUploadSize(x) - known expected upload size
+   pgrsSetDownloadCounter() - amount of data currently downloaded
+   pgrsSetUploadCounter() - amount of data currently uploaded
+   pgrsUpdate() - show progress
+   pgrsDone() - transfer complete
+
+*/
+
+int Curl_pgrsDone(struct connectdata *conn)
+{
+  int rc;
+  struct SessionHandle *data = conn->data;
+  data->progress.lastshow=0;
+  rc = Curl_pgrsUpdate(conn); /* the final (forced) update */
+  if(rc)
+    return rc;
+
+  if(!(data->progress.flags & PGRS_HIDE) &&
+     !data->progress.callback)
+    /* only output if we don't use a progress callback and we're not
+     * hidden */
+    fprintf(data->set.err, "\n");
+
+  data->progress.speeder_c = 0; /* reset the progress meter display */
+  return 0;
+}
+
+/* reset all times except redirect, and reset the known transfer sizes */
+void Curl_pgrsResetTimesSizes(struct SessionHandle *data)
+{
+  data->progress.t_nslookup = 0.0;
+  data->progress.t_connect = 0.0;
+  data->progress.t_pretransfer = 0.0;
+  data->progress.t_starttransfer = 0.0;
+
+  Curl_pgrsSetDownloadSize(data, -1);
+  Curl_pgrsSetUploadSize(data, -1);
+}
+
+void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
+{
+  struct timeval now = Curl_tvnow();
+
+  switch(timer) {
+  default:
+  case TIMER_NONE:
+    /* mistake filter */
+    break;
+  case TIMER_STARTOP:
+    /* This is set at the start of a transfer */
+    data->progress.t_startop = now;
+    break;
+  case TIMER_STARTSINGLE:
+    /* This is set at the start of each single fetch */
+    data->progress.t_startsingle = now;
+    break;
+
+  case TIMER_STARTACCEPT:
+    data->progress.t_acceptdata = Curl_tvnow();
+    break;
+
+  case TIMER_NAMELOOKUP:
+    data->progress.t_nslookup =
+      Curl_tvdiff_secs(now, data->progress.t_startsingle);
+    break;
+  case TIMER_CONNECT:
+    data->progress.t_connect =
+      Curl_tvdiff_secs(now, data->progress.t_startsingle);
+    break;
+  case TIMER_APPCONNECT:
+    data->progress.t_appconnect =
+      Curl_tvdiff_secs(now, data->progress.t_startsingle);
+    break;
+  case TIMER_PRETRANSFER:
+    data->progress.t_pretransfer =
+      Curl_tvdiff_secs(now, data->progress.t_startsingle);
+    break;
+  case TIMER_STARTTRANSFER:
+    data->progress.t_starttransfer =
+      Curl_tvdiff_secs(now, data->progress.t_startsingle);
+    break;
+  case TIMER_POSTRANSFER:
+    /* this is the normal end-of-transfer thing */
+    break;
+  case TIMER_REDIRECT:
+    data->progress.t_redirect = Curl_tvdiff_secs(now, data->progress.start);
+    break;
+  }
+}
+
+void Curl_pgrsStartNow(struct SessionHandle *data)
+{
+  data->progress.speeder_c = 0; /* reset the progress meter display */
+  data->progress.start = Curl_tvnow();
+  /* clear all bits except HIDE and HEADERS_OUT */
+  data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT;
+}
+
+void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, curl_off_t size)
+{
+  data->progress.downloaded = size;
+}
+
+void Curl_pgrsSetUploadCounter(struct SessionHandle *data, curl_off_t size)
+{
+  data->progress.uploaded = size;
+}
+
+void Curl_pgrsSetDownloadSize(struct SessionHandle *data, curl_off_t size)
+{
+  if(size >= 0) {
+    data->progress.size_dl = size;
+    data->progress.flags |= PGRS_DL_SIZE_KNOWN;
+  }
+  else {
+    data->progress.size_dl = 0;
+    data->progress.flags &= ~PGRS_DL_SIZE_KNOWN;
+  }
+}
+
+void Curl_pgrsSetUploadSize(struct SessionHandle *data, curl_off_t size)
+{
+  if(size >= 0) {
+    data->progress.size_ul = size;
+    data->progress.flags |= PGRS_UL_SIZE_KNOWN;
+  }
+  else {
+    data->progress.size_ul = 0;
+    data->progress.flags &= ~PGRS_UL_SIZE_KNOWN;
+  }
+}
+
+/*
+ * Curl_pgrsUpdate() returns 0 for success or the value returned by the
+ * progress callback!
+ */
+int Curl_pgrsUpdate(struct connectdata *conn)
+{
+  struct timeval now;
+  int result;
+  char max5[6][10];
+  curl_off_t dlpercen=0;
+  curl_off_t ulpercen=0;
+  curl_off_t total_percen=0;
+  curl_off_t total_transfer;
+  curl_off_t total_expected_transfer;
+  curl_off_t timespent;
+  struct SessionHandle *data = conn->data;
+  int nowindex = data->progress.speeder_c% CURR_TIME;
+  int checkindex;
+  int countindex; /* amount of seconds stored in the speeder array */
+  char time_left[10];
+  char time_total[10];
+  char time_spent[10];
+  curl_off_t ulestimate=0;
+  curl_off_t dlestimate=0;
+  curl_off_t total_estimate;
+  bool shownow=FALSE;
+
+  now = Curl_tvnow(); /* what time is it */
+
+  /* The time spent so far (from the start) */
+  data->progress.timespent =
+    (double)(now.tv_sec - data->progress.start.tv_sec) +
+    (double)(now.tv_usec - data->progress.start.tv_usec)/1000000.0;
+  timespent = (curl_off_t)data->progress.timespent;
+
+  /* The average download speed this far */
+  data->progress.dlspeed = (curl_off_t)
+    ((double)data->progress.downloaded/
+     (data->progress.timespent>0?data->progress.timespent:1));
+
+  /* The average upload speed this far */
+  data->progress.ulspeed = (curl_off_t)
+    ((double)data->progress.uploaded/
+     (data->progress.timespent>0?data->progress.timespent:1));
+
+  /* Calculations done at most once a second, unless end is reached */
+  if(data->progress.lastshow != (long)now.tv_sec) {
+    shownow = TRUE;
+
+    data->progress.lastshow = now.tv_sec;
+
+    /* Let's do the "current speed" thing, which should use the fastest
+       of the dl/ul speeds. Store the faster speed at entry 'nowindex'. */
+    data->progress.speeder[ nowindex ] =
+      data->progress.downloaded>data->progress.uploaded?
+      data->progress.downloaded:data->progress.uploaded;
+
+    /* remember the exact time for this moment */
+    data->progress.speeder_time [ nowindex ] = now;
+
+    /* advance our speeder_c counter, which is increased every time we get
+       here and we expect it to never wrap as 2^32 is a lot of seconds! */
+    data->progress.speeder_c++;
+
+    /* figure out how many index entries of data we have stored in our speeder
+       array. With N_ENTRIES filled in, we have about N_ENTRIES-1 seconds of
+       transfer. Imagine, after one second we have filled in two entries,
+       after two seconds we've filled in three entries etc. */
+    countindex = ((data->progress.speeder_c>=CURR_TIME)?
+                  CURR_TIME:data->progress.speeder_c) - 1;
+
+    /* first of all, we don't do this if there's no counted seconds yet */
+    if(countindex) {
+      long span_ms;
+
+      /* Get the index position to compare with the 'nowindex' position.
+         Get the oldest entry possible. While we have less than CURR_TIME
+         entries, the first entry will remain the oldest. */
+      checkindex = (data->progress.speeder_c>=CURR_TIME)?
+        data->progress.speeder_c%CURR_TIME:0;
+
+      /* Figure out the exact time for the time span */
+      span_ms = Curl_tvdiff(now,
+                            data->progress.speeder_time[checkindex]);
+      if(0 == span_ms)
+        span_ms=1; /* at least one millisecond MUST have passed */
+
+      /* Calculate the average speed the last 'span_ms' milliseconds */
+      {
+        curl_off_t amount = data->progress.speeder[nowindex]-
+          data->progress.speeder[checkindex];
+
+        if(amount > CURL_OFF_T_C(4294967) /* 0xffffffff/1000 */)
+          /* the 'amount' value is bigger than would fit in 32 bits if
+             multiplied with 1000, so we use the double math for this */
+          data->progress.current_speed = (curl_off_t)
+            ((double)amount/((double)span_ms/1000.0));
+        else
+          /* the 'amount' value is small enough to fit within 32 bits even
+             when multiplied with 1000 */
+          data->progress.current_speed = amount*CURL_OFF_T_C(1000)/span_ms;
+      }
+    }
+    else
+      /* the first second we use the main average */
+      data->progress.current_speed =
+        (data->progress.ulspeed>data->progress.dlspeed)?
+        data->progress.ulspeed:data->progress.dlspeed;
+
+  } /* Calculations end */
+
+  if(!(data->progress.flags & PGRS_HIDE)) {
+    /* progress meter has not been shut off */
+
+    if(data->set.fxferinfo) {
+      /* There's a callback set, call that */
+      result= data->set.fxferinfo(data->set.progress_client,
+                                  data->progress.size_dl,
+                                  data->progress.downloaded,
+                                  data->progress.size_ul,
+                                  data->progress.uploaded);
+      if(result)
+        failf(data, "Callback aborted");
+      return result;
+    }
+    else if(data->set.fprogress) {
+      /* The older deprecated callback is set, call that */
+      result= data->set.fprogress(data->set.progress_client,
+                                  (double)data->progress.size_dl,
+                                  (double)data->progress.downloaded,
+                                  (double)data->progress.size_ul,
+                                  (double)data->progress.uploaded);
+      if(result)
+        failf(data, "Callback aborted");
+      return result;
+    }
+
+    if(!shownow)
+      /* only show the internal progress meter once per second */
+      return 0;
+
+    /* If there's no external callback set, use internal code to show
+       progress */
+
+    if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
+      if(data->state.resume_from) {
+        fprintf(data->set.err,
+                "** Resuming transfer from byte position %"
+                CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from);
+      }
+      fprintf(data->set.err,
+              "  %% Total    %% Received %% Xferd  Average Speed   "
+              "Time    Time     Time  Current\n"
+              "                                 Dload  Upload   "
+              "Total   Spent    Left  Speed\n");
+      data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */
+    }
+
+    /* Figure out the estimated time of arrival for the upload */
+    if((data->progress.flags & PGRS_UL_SIZE_KNOWN) &&
+       (data->progress.ulspeed > CURL_OFF_T_C(0))) {
+      ulestimate = data->progress.size_ul / data->progress.ulspeed;
+
+      if(data->progress.size_ul > CURL_OFF_T_C(10000))
+        ulpercen = data->progress.uploaded /
+          (data->progress.size_ul/CURL_OFF_T_C(100));
+      else if(data->progress.size_ul > CURL_OFF_T_C(0))
+        ulpercen = (data->progress.uploaded*100) /
+          data->progress.size_ul;
+    }
+
+    /* ... and the download */
+    if((data->progress.flags & PGRS_DL_SIZE_KNOWN) &&
+       (data->progress.dlspeed > CURL_OFF_T_C(0))) {
+      dlestimate = data->progress.size_dl / data->progress.dlspeed;
+
+      if(data->progress.size_dl > CURL_OFF_T_C(10000))
+        dlpercen = data->progress.downloaded /
+          (data->progress.size_dl/CURL_OFF_T_C(100));
+      else if(data->progress.size_dl > CURL_OFF_T_C(0))
+        dlpercen = (data->progress.downloaded*100) /
+          data->progress.size_dl;
+    }
+
+    /* Now figure out which of them is slower and use that one for the
+       total estimate! */
+    total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
+
+    /* create the three time strings */
+    time2str(time_left, total_estimate > 0?(total_estimate - timespent):0);
+    time2str(time_total, total_estimate);
+    time2str(time_spent, timespent);
+
+    /* Get the total amount of data expected to get transferred */
+    total_expected_transfer =
+      (data->progress.flags & PGRS_UL_SIZE_KNOWN?
+       data->progress.size_ul:data->progress.uploaded)+
+      (data->progress.flags & PGRS_DL_SIZE_KNOWN?
+       data->progress.size_dl:data->progress.downloaded);
+
+    /* We have transferred this much so far */
+    total_transfer = data->progress.downloaded + data->progress.uploaded;
+
+    /* Get the percentage of data transferred so far */
+    if(total_expected_transfer > CURL_OFF_T_C(10000))
+      total_percen = total_transfer /
+        (total_expected_transfer/CURL_OFF_T_C(100));
+    else if(total_expected_transfer > CURL_OFF_T_C(0))
+      total_percen = (total_transfer*100) / total_expected_transfer;
+
+    fprintf(data->set.err,
+            "\r"
+            "%3" CURL_FORMAT_CURL_OFF_T " %s  "
+            "%3" CURL_FORMAT_CURL_OFF_T " %s  "
+            "%3" CURL_FORMAT_CURL_OFF_T " %s  %s  %s %s %s %s %s",
+            total_percen,  /* 3 letters */                /* total % */
+            max5data(total_expected_transfer, max5[2]),   /* total size */
+            dlpercen,      /* 3 letters */                /* rcvd % */
+            max5data(data->progress.downloaded, max5[0]), /* rcvd size */
+            ulpercen,      /* 3 letters */                /* xfer % */
+            max5data(data->progress.uploaded, max5[1]),   /* xfer size */
+            max5data(data->progress.dlspeed, max5[3]),    /* avrg dl speed */
+            max5data(data->progress.ulspeed, max5[4]),    /* avrg ul speed */
+            time_total,    /* 8 letters */                /* total time */
+            time_spent,    /* 8 letters */                /* time spent */
+            time_left,     /* 8 letters */                /* time left */
+            max5data(data->progress.current_speed, max5[5]) /* current speed */
+            );
+
+    /* we flush the output stream to make it appear as soon as possible */
+    fflush(data->set.err);
+
+  } /* !(data->progress.flags & PGRS_HIDE) */
+
+  return 0;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/progress.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/progress.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/progress.h	(revision 164)
@@ -0,0 +1,73 @@
+#ifndef HEADER_CURL_PROGRESS_H
+#define HEADER_CURL_PROGRESS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "timeval.h"
+
+
+typedef enum {
+  TIMER_NONE,
+  TIMER_STARTOP,
+  TIMER_STARTSINGLE,
+  TIMER_NAMELOOKUP,
+  TIMER_CONNECT,
+  TIMER_APPCONNECT,
+  TIMER_PRETRANSFER,
+  TIMER_STARTTRANSFER,
+  TIMER_POSTRANSFER,
+  TIMER_STARTACCEPT,
+  TIMER_REDIRECT,
+  TIMER_LAST /* must be last */
+} timerid;
+
+int Curl_pgrsDone(struct connectdata *);
+void Curl_pgrsStartNow(struct SessionHandle *data);
+void Curl_pgrsSetDownloadSize(struct SessionHandle *data, curl_off_t size);
+void Curl_pgrsSetUploadSize(struct SessionHandle *data, curl_off_t size);
+void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, curl_off_t size);
+void Curl_pgrsSetUploadCounter(struct SessionHandle *data, curl_off_t size);
+int Curl_pgrsUpdate(struct connectdata *);
+void Curl_pgrsResetTimesSizes(struct SessionHandle *data);
+void Curl_pgrsTime(struct SessionHandle *data, timerid timer);
+
+
+/* Don't show progress for sizes smaller than: */
+#define LEAST_SIZE_PROGRESS BUFSIZE
+
+#define PROGRESS_DOWNLOAD (1<<0)
+#define PROGRESS_UPLOAD   (1<<1)
+#define PROGRESS_DOWN_AND_UP (PROGRESS_UPLOAD | PROGRESS_DOWNLOAD)
+
+#define PGRS_SHOW_DL (1<<0)
+#define PGRS_SHOW_UL (1<<1)
+#define PGRS_DONE_DL (1<<2)
+#define PGRS_DONE_UL (1<<3)
+#define PGRS_HIDE    (1<<4)
+#define PGRS_UL_SIZE_KNOWN (1<<5)
+#define PGRS_DL_SIZE_KNOWN (1<<6)
+
+#define PGRS_HEADERS_OUT (1<<7) /* set when the headers have been written */
+
+
+#endif /* HEADER_CURL_PROGRESS_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/rawstr.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/rawstr.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/rawstr.c	(revision 164)
@@ -0,0 +1,148 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "rawstr.h"
+
+/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
+   its behavior is altered by the current locale. */
+char Curl_raw_toupper(char in)
+{
+#if !defined(CURL_DOES_CONVERSIONS)
+  if(in >= 'a' && in <= 'z')
+    return (char)('A' + in - 'a');
+#else
+  switch (in) {
+  case 'a':
+    return 'A';
+  case 'b':
+    return 'B';
+  case 'c':
+    return 'C';
+  case 'd':
+    return 'D';
+  case 'e':
+    return 'E';
+  case 'f':
+    return 'F';
+  case 'g':
+    return 'G';
+  case 'h':
+    return 'H';
+  case 'i':
+    return 'I';
+  case 'j':
+    return 'J';
+  case 'k':
+    return 'K';
+  case 'l':
+    return 'L';
+  case 'm':
+    return 'M';
+  case 'n':
+    return 'N';
+  case 'o':
+    return 'O';
+  case 'p':
+    return 'P';
+  case 'q':
+    return 'Q';
+  case 'r':
+    return 'R';
+  case 's':
+    return 'S';
+  case 't':
+    return 'T';
+  case 'u':
+    return 'U';
+  case 'v':
+    return 'V';
+  case 'w':
+    return 'W';
+  case 'x':
+    return 'X';
+  case 'y':
+    return 'Y';
+  case 'z':
+    return 'Z';
+  }
+#endif
+
+  return in;
+}
+
+/*
+ * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant
+ * to be locale independent and only compare strings we know are safe for
+ * this.  See https://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for
+ * some further explanation to why this function is necessary.
+ *
+ * The function is capable of comparing a-z case insensitively even for
+ * non-ascii.
+ */
+
+int Curl_raw_equal(const char *first, const char *second)
+{
+  while(*first && *second) {
+    if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
+      /* get out of the loop as soon as they don't match */
+      break;
+    first++;
+    second++;
+  }
+  /* we do the comparison here (possibly again), just to make sure that if the
+     loop above is skipped because one of the strings reached zero, we must not
+     return this as a successful match */
+  return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
+}
+
+int Curl_raw_nequal(const char *first, const char *second, size_t max)
+{
+  while(*first && *second && max) {
+    if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
+      break;
+    }
+    max--;
+    first++;
+    second++;
+  }
+  if(0 == max)
+    return 1; /* they are equal this far */
+
+  return Curl_raw_toupper(*first) == Curl_raw_toupper(*second);
+}
+
+/* Copy an upper case version of the string from src to dest.  The
+ * strings may overlap.  No more than n characters of the string are copied
+ * (including any NUL) and the destination string will NOT be
+ * NUL-terminated if that limit is reached.
+ */
+void Curl_strntoupper(char *dest, const char *src, size_t n)
+{
+  if(n < 1)
+    return;
+
+  do {
+    *dest++ = Curl_raw_toupper(*src);
+  } while(*src++ && --n);
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/rawstr.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/rawstr.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/rawstr.h	(revision 164)
@@ -0,0 +1,47 @@
+#ifndef HEADER_CURL_RAWSTR_H
+#define HEADER_CURL_RAWSTR_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+/*
+ * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant
+ * to be locale independent and only compare strings we know are safe for
+ * this.
+ *
+ * The function is capable of comparing a-z case insensitively even for
+ * non-ascii.
+ */
+int Curl_raw_equal(const char *first, const char *second);
+int Curl_raw_nequal(const char *first, const char *second, size_t max);
+
+char Curl_raw_toupper(char in);
+
+/* checkprefix() is a shorter version of the above, used when the first
+   argument is zero-byte terminated */
+#define checkprefix(a,b)    Curl_raw_nequal(a,b,strlen(a))
+
+void Curl_strntoupper(char *dest, const char *src, size_t n);
+
+#endif /* HEADER_CURL_RAWSTR_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/rtsp.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/rtsp.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/rtsp.c	(revision 164)
@@ -0,0 +1,826 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_RTSP
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "multiif.h"
+#include "http.h"
+#include "url.h"
+#include "progress.h"
+#include "rtsp.h"
+#include "rawstr.h"
+#include "select.h"
+#include "connect.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * TODO (general)
+ *  -incoming server requests
+ *      -server CSeq counter
+ *  -digest authentication
+ *  -connect thru proxy
+ *  -pipelining?
+ */
+
+
+#define RTP_PKT_CHANNEL(p)   ((int)((unsigned char)((p)[1])))
+
+#define RTP_PKT_LENGTH(p)  ((((int)((unsigned char)((p)[2]))) << 8) | \
+                             ((int)((unsigned char)((p)[3]))))
+
+/* protocol-specific functions set up to be called by the main engine */
+static CURLcode rtsp_do(struct connectdata *conn, bool *done);
+static CURLcode rtsp_done(struct connectdata *conn, CURLcode, bool premature);
+static CURLcode rtsp_connect(struct connectdata *conn, bool *done);
+static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead);
+
+static int rtsp_getsock_do(struct connectdata *conn,
+                           curl_socket_t *socks,
+                           int numsocks);
+
+/*
+ * Parse and write out any available RTP data.
+ *
+ * nread: amount of data left after k->str. will be modified if RTP
+ *        data is parsed and k->str is moved up
+ * readmore: whether or not the RTP parser needs more data right away
+ */
+static CURLcode rtsp_rtp_readwrite(struct SessionHandle *data,
+                                   struct connectdata *conn,
+                                   ssize_t *nread,
+                                   bool *readmore);
+
+static CURLcode rtsp_setup_connection(struct connectdata *conn);
+
+
+/* this returns the socket to wait for in the DO and DOING state for the multi
+   interface and then we're always _sending_ a request and thus we wait for
+   the single socket to become writable only */
+static int rtsp_getsock_do(struct connectdata *conn,
+                           curl_socket_t *socks,
+                           int numsocks)
+{
+  /* write mode */
+  (void)numsocks; /* unused, we trust it to be at least 1 */
+  socks[0] = conn->sock[FIRSTSOCKET];
+  return GETSOCK_WRITESOCK(0);
+}
+
+static
+CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len);
+
+
+/*
+ * RTSP handler interface.
+ */
+const struct Curl_handler Curl_handler_rtsp = {
+  "RTSP",                               /* scheme */
+  rtsp_setup_connection,                /* setup_connection */
+  rtsp_do,                              /* do_it */
+  rtsp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  rtsp_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  rtsp_getsock_do,                      /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  rtsp_disconnect,                      /* disconnect */
+  rtsp_rtp_readwrite,                   /* readwrite */
+  PORT_RTSP,                            /* defport */
+  CURLPROTO_RTSP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+
+static CURLcode rtsp_setup_connection(struct connectdata *conn)
+{
+  struct RTSP *rtsp;
+
+  conn->data->req.protop = rtsp = calloc(1, sizeof(struct RTSP));
+  if(!rtsp)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+
+/*
+ * The server may send us RTP data at any point, and RTSPREQ_RECEIVE does not
+ * want to block the application forever while receiving a stream. Therefore,
+ * we cannot assume that an RTSP socket is dead just because it is readable.
+ *
+ * Instead, if it is readable, run Curl_getconnectinfo() to peek at the socket
+ * and distinguish between closed and data.
+ */
+bool Curl_rtsp_connisdead(struct connectdata *check)
+{
+  int sval;
+  bool ret_val = TRUE;
+
+  sval = Curl_socket_ready(check->sock[FIRSTSOCKET], CURL_SOCKET_BAD, 0);
+  if(sval == 0) {
+    /* timeout */
+    ret_val = FALSE;
+  }
+  else if(sval & CURL_CSELECT_ERR) {
+    /* socket is in an error state */
+    ret_val = TRUE;
+  }
+  else if((sval & CURL_CSELECT_IN) && check->data) {
+    /* readable with no error. could be closed or could be alive but we can
+       only check if we have a proper SessionHandle for the connection */
+    curl_socket_t connectinfo = Curl_getconnectinfo(check->data, &check);
+    if(connectinfo != CURL_SOCKET_BAD)
+      ret_val = FALSE;
+  }
+
+  return ret_val;
+}
+
+static CURLcode rtsp_connect(struct connectdata *conn, bool *done)
+{
+  CURLcode httpStatus;
+  struct SessionHandle *data = conn->data;
+
+  httpStatus = Curl_http_connect(conn, done);
+
+  /* Initialize the CSeq if not already done */
+  if(data->state.rtsp_next_client_CSeq == 0)
+    data->state.rtsp_next_client_CSeq = 1;
+  if(data->state.rtsp_next_server_CSeq == 0)
+    data->state.rtsp_next_server_CSeq = 1;
+
+  conn->proto.rtspc.rtp_channel = -1;
+
+  return httpStatus;
+}
+
+static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead)
+{
+  (void) dead;
+  Curl_safefree(conn->proto.rtspc.rtp_buf);
+  return CURLE_OK;
+}
+
+
+static CURLcode rtsp_done(struct connectdata *conn,
+                          CURLcode status, bool premature)
+{
+  struct SessionHandle *data = conn->data;
+  struct RTSP *rtsp = data->req.protop;
+  CURLcode httpStatus;
+  long CSeq_sent;
+  long CSeq_recv;
+
+  /* Bypass HTTP empty-reply checks on receive */
+  if(data->set.rtspreq == RTSPREQ_RECEIVE)
+    premature = TRUE;
+
+  httpStatus = Curl_http_done(conn, status, premature);
+
+  if(rtsp) {
+    /* Check the sequence numbers */
+    CSeq_sent = rtsp->CSeq_sent;
+    CSeq_recv = rtsp->CSeq_recv;
+    if((data->set.rtspreq != RTSPREQ_RECEIVE) && (CSeq_sent != CSeq_recv)) {
+      failf(data,
+            "The CSeq of this request %ld did not match the response %ld",
+            CSeq_sent, CSeq_recv);
+      return CURLE_RTSP_CSEQ_ERROR;
+    }
+    else if(data->set.rtspreq == RTSPREQ_RECEIVE &&
+            (conn->proto.rtspc.rtp_channel == -1)) {
+      infof(data, "Got an RTP Receive with a CSeq of %ld\n", CSeq_recv);
+      /* TODO CPC: Server -> Client logic here */
+    }
+  }
+
+  return httpStatus;
+}
+
+static CURLcode rtsp_do(struct connectdata *conn, bool *done)
+{
+  struct SessionHandle *data = conn->data;
+  CURLcode result=CURLE_OK;
+  Curl_RtspReq rtspreq = data->set.rtspreq;
+  struct RTSP *rtsp = data->req.protop;
+  struct HTTP *http;
+  Curl_send_buffer *req_buffer;
+  curl_off_t postsize = 0; /* for ANNOUNCE and SET_PARAMETER */
+  curl_off_t putsize = 0; /* for ANNOUNCE and SET_PARAMETER */
+
+  const char *p_request = NULL;
+  const char *p_session_id = NULL;
+  const char *p_accept = NULL;
+  const char *p_accept_encoding = NULL;
+  const char *p_range = NULL;
+  const char *p_referrer = NULL;
+  const char *p_stream_uri = NULL;
+  const char *p_transport = NULL;
+  const char *p_uagent = NULL;
+  const char *p_proxyuserpwd = NULL;
+  const char *p_userpwd = NULL;
+
+  *done = TRUE;
+
+  http = &(rtsp->http_wrapper);
+  /* Assert that no one has changed the RTSP struct in an evil way */
+  DEBUGASSERT((void *)http == (void *)rtsp);
+
+  rtsp->CSeq_sent = data->state.rtsp_next_client_CSeq;
+  rtsp->CSeq_recv = 0;
+
+  /* Setup the 'p_request' pointer to the proper p_request string
+   * Since all RTSP requests are included here, there is no need to
+   * support custom requests like HTTP.
+   **/
+  data->set.opt_no_body = TRUE; /* most requests don't contain a body */
+  switch(rtspreq) {
+  default:
+    failf(data, "Got invalid RTSP request");
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+  case RTSPREQ_OPTIONS:
+    p_request = "OPTIONS";
+    break;
+  case RTSPREQ_DESCRIBE:
+    p_request = "DESCRIBE";
+    data->set.opt_no_body = FALSE;
+    break;
+  case RTSPREQ_ANNOUNCE:
+    p_request = "ANNOUNCE";
+    break;
+  case RTSPREQ_SETUP:
+    p_request = "SETUP";
+    break;
+  case RTSPREQ_PLAY:
+    p_request = "PLAY";
+    break;
+  case RTSPREQ_PAUSE:
+    p_request = "PAUSE";
+    break;
+  case RTSPREQ_TEARDOWN:
+    p_request = "TEARDOWN";
+    break;
+  case RTSPREQ_GET_PARAMETER:
+    /* GET_PARAMETER's no_body status is determined later */
+    p_request = "GET_PARAMETER";
+    data->set.opt_no_body = FALSE;
+    break;
+  case RTSPREQ_SET_PARAMETER:
+    p_request = "SET_PARAMETER";
+    break;
+  case RTSPREQ_RECORD:
+    p_request = "RECORD";
+    break;
+  case RTSPREQ_RECEIVE:
+    p_request = "";
+    /* Treat interleaved RTP as body*/
+    data->set.opt_no_body = FALSE;
+    break;
+  case RTSPREQ_LAST:
+    failf(data, "Got invalid RTSP request: RTSPREQ_LAST");
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+  }
+
+  if(rtspreq == RTSPREQ_RECEIVE) {
+    Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
+                        &http->readbytecount, -1, NULL);
+
+    return result;
+  }
+
+  p_session_id = data->set.str[STRING_RTSP_SESSION_ID];
+  if(!p_session_id &&
+     (rtspreq & ~(RTSPREQ_OPTIONS | RTSPREQ_DESCRIBE | RTSPREQ_SETUP))) {
+    failf(data, "Refusing to issue an RTSP request [%s] without a session ID.",
+          p_request);
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+  }
+
+  /* TODO: proxy? */
+
+  /* Stream URI. Default to server '*' if not specified */
+  if(data->set.str[STRING_RTSP_STREAM_URI]) {
+    p_stream_uri = data->set.str[STRING_RTSP_STREAM_URI];
+  }
+  else {
+    p_stream_uri = "*";
+  }
+
+  /* Transport Header for SETUP requests */
+  p_transport = Curl_checkheaders(conn, "Transport:");
+  if(rtspreq == RTSPREQ_SETUP && !p_transport) {
+    /* New Transport: setting? */
+    if(data->set.str[STRING_RTSP_TRANSPORT]) {
+      Curl_safefree(conn->allocptr.rtsp_transport);
+
+      conn->allocptr.rtsp_transport =
+        aprintf("Transport: %s\r\n",
+                data->set.str[STRING_RTSP_TRANSPORT]);
+      if(!conn->allocptr.rtsp_transport)
+        return CURLE_OUT_OF_MEMORY;
+    }
+    else {
+      failf(data,
+            "Refusing to issue an RTSP SETUP without a Transport: header.");
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+
+    p_transport = conn->allocptr.rtsp_transport;
+  }
+
+  /* Accept Headers for DESCRIBE requests */
+  if(rtspreq == RTSPREQ_DESCRIBE) {
+    /* Accept Header */
+    p_accept = Curl_checkheaders(conn, "Accept:")?
+      NULL:"Accept: application/sdp\r\n";
+
+    /* Accept-Encoding header */
+    if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
+       data->set.str[STRING_ENCODING]) {
+      Curl_safefree(conn->allocptr.accept_encoding);
+      conn->allocptr.accept_encoding =
+        aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
+
+      if(!conn->allocptr.accept_encoding)
+        return CURLE_OUT_OF_MEMORY;
+
+      p_accept_encoding = conn->allocptr.accept_encoding;
+    }
+  }
+
+  /* The User-Agent string might have been allocated in url.c already, because
+     it might have been used in the proxy connect, but if we have got a header
+     with the user-agent string specified, we erase the previously made string
+     here. */
+  if(Curl_checkheaders(conn, "User-Agent:") && conn->allocptr.uagent) {
+    Curl_safefree(conn->allocptr.uagent);
+    conn->allocptr.uagent = NULL;
+  }
+  else if(!Curl_checkheaders(conn, "User-Agent:") &&
+          data->set.str[STRING_USERAGENT]) {
+    p_uagent = conn->allocptr.uagent;
+  }
+
+  /* setup the authentication headers */
+  result = Curl_http_output_auth(conn, p_request, p_stream_uri, FALSE);
+  if(result)
+    return result;
+
+  p_proxyuserpwd = conn->allocptr.proxyuserpwd;
+  p_userpwd = conn->allocptr.userpwd;
+
+  /* Referrer */
+  Curl_safefree(conn->allocptr.ref);
+  if(data->change.referer && !Curl_checkheaders(conn, "Referer:"))
+    conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
+  else
+    conn->allocptr.ref = NULL;
+
+  p_referrer = conn->allocptr.ref;
+
+  /*
+   * Range Header
+   * Only applies to PLAY, PAUSE, RECORD
+   *
+   * Go ahead and use the Range stuff supplied for HTTP
+   */
+  if(data->state.use_range &&
+     (rtspreq  & (RTSPREQ_PLAY | RTSPREQ_PAUSE | RTSPREQ_RECORD))) {
+
+    /* Check to see if there is a range set in the custom headers */
+    if(!Curl_checkheaders(conn, "Range:") && data->state.range) {
+      Curl_safefree(conn->allocptr.rangeline);
+      conn->allocptr.rangeline = aprintf("Range: %s\r\n", data->state.range);
+      p_range = conn->allocptr.rangeline;
+    }
+  }
+
+  /*
+   * Sanity check the custom headers
+   */
+  if(Curl_checkheaders(conn, "CSeq:")) {
+    failf(data, "CSeq cannot be set as a custom header.");
+    return CURLE_RTSP_CSEQ_ERROR;
+  }
+  if(Curl_checkheaders(conn, "Session:")) {
+    failf(data, "Session ID cannot be set as a custom header.");
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+  }
+
+  /* Initialize a dynamic send buffer */
+  req_buffer = Curl_add_buffer_init();
+
+  if(!req_buffer)
+    return CURLE_OUT_OF_MEMORY;
+
+  result =
+    Curl_add_bufferf(req_buffer,
+                     "%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */
+                     "CSeq: %ld\r\n", /* CSeq */
+                     p_request, p_stream_uri, rtsp->CSeq_sent);
+  if(result)
+    return result;
+
+  /*
+   * Rather than do a normal alloc line, keep the session_id unformatted
+   * to make comparison easier
+   */
+  if(p_session_id) {
+    result = Curl_add_bufferf(req_buffer, "Session: %s\r\n", p_session_id);
+    if(result)
+      return result;
+  }
+
+  /*
+   * Shared HTTP-like options
+   */
+  result = Curl_add_bufferf(req_buffer,
+                            "%s" /* transport */
+                            "%s" /* accept */
+                            "%s" /* accept-encoding */
+                            "%s" /* range */
+                            "%s" /* referrer */
+                            "%s" /* user-agent */
+                            "%s" /* proxyuserpwd */
+                            "%s" /* userpwd */
+                            ,
+                            p_transport ? p_transport : "",
+                            p_accept ? p_accept : "",
+                            p_accept_encoding ? p_accept_encoding : "",
+                            p_range ? p_range : "",
+                            p_referrer ? p_referrer : "",
+                            p_uagent ? p_uagent : "",
+                            p_proxyuserpwd ? p_proxyuserpwd : "",
+                            p_userpwd ? p_userpwd : "");
+
+  /*
+   * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
+   * with basic and digest, it will be freed anyway by the next request
+   */
+  Curl_safefree (conn->allocptr.userpwd);
+  conn->allocptr.userpwd = NULL;
+
+  if(result)
+    return result;
+
+  if((rtspreq == RTSPREQ_SETUP) || (rtspreq == RTSPREQ_DESCRIBE)) {
+    result = Curl_add_timecondition(data, req_buffer);
+    if(result)
+      return result;
+  }
+
+  result = Curl_add_custom_headers(conn, FALSE, req_buffer);
+  if(result)
+    return result;
+
+  if(rtspreq == RTSPREQ_ANNOUNCE ||
+     rtspreq == RTSPREQ_SET_PARAMETER ||
+     rtspreq == RTSPREQ_GET_PARAMETER) {
+
+    if(data->set.upload) {
+      putsize = data->state.infilesize;
+      data->set.httpreq = HTTPREQ_PUT;
+
+    }
+    else {
+      postsize = (data->state.infilesize != -1)?
+        data->state.infilesize:
+        (data->set.postfields? (curl_off_t)strlen(data->set.postfields):0);
+      data->set.httpreq = HTTPREQ_POST;
+    }
+
+    if(putsize > 0 || postsize > 0) {
+      /* As stated in the http comments, it is probably not wise to
+       * actually set a custom Content-Length in the headers */
+      if(!Curl_checkheaders(conn, "Content-Length:")) {
+        result = Curl_add_bufferf(req_buffer,
+            "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
+            (data->set.upload ? putsize : postsize));
+        if(result)
+          return result;
+      }
+
+      if(rtspreq == RTSPREQ_SET_PARAMETER ||
+         rtspreq == RTSPREQ_GET_PARAMETER) {
+        if(!Curl_checkheaders(conn, "Content-Type:")) {
+          result = Curl_add_bufferf(req_buffer,
+              "Content-Type: text/parameters\r\n");
+          if(result)
+            return result;
+        }
+      }
+
+      if(rtspreq == RTSPREQ_ANNOUNCE) {
+        if(!Curl_checkheaders(conn, "Content-Type:")) {
+          result = Curl_add_bufferf(req_buffer,
+              "Content-Type: application/sdp\r\n");
+          if(result)
+            return result;
+        }
+      }
+
+      data->state.expect100header = FALSE; /* RTSP posts are simple/small */
+    }
+    else if(rtspreq == RTSPREQ_GET_PARAMETER) {
+      /* Check for an empty GET_PARAMETER (heartbeat) request */
+      data->set.httpreq = HTTPREQ_HEAD;
+      data->set.opt_no_body = TRUE;
+    }
+  }
+
+  /* RTSP never allows chunked transfer */
+  data->req.forbidchunk = TRUE;
+  /* Finish the request buffer */
+  result = Curl_add_buffer(req_buffer, "\r\n", 2);
+  if(result)
+    return result;
+
+  if(postsize > 0) {
+    result = Curl_add_buffer(req_buffer, data->set.postfields,
+                             (size_t)postsize);
+    if(result)
+      return result;
+  }
+
+  /* issue the request */
+  result = Curl_add_buffer_send(req_buffer, conn,
+                                &data->info.request_size, 0, FIRSTSOCKET);
+  if(result) {
+    failf(data, "Failed sending RTSP request");
+    return result;
+  }
+
+  Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
+                      putsize?FIRSTSOCKET:-1,
+                      putsize?&http->writebytecount:NULL);
+
+  /* Increment the CSeq on success */
+  data->state.rtsp_next_client_CSeq++;
+
+  if(http->writebytecount) {
+    /* if a request-body has been sent off, we make sure this progress is
+       noted properly */
+    Curl_pgrsSetUploadCounter(data, http->writebytecount);
+    if(Curl_pgrsUpdate(conn))
+      result = CURLE_ABORTED_BY_CALLBACK;
+  }
+
+  return result;
+}
+
+
+static CURLcode rtsp_rtp_readwrite(struct SessionHandle *data,
+                                   struct connectdata *conn,
+                                   ssize_t *nread,
+                                   bool *readmore) {
+  struct SingleRequest *k = &data->req;
+  struct rtsp_conn *rtspc = &(conn->proto.rtspc);
+
+  char *rtp; /* moving pointer to rtp data */
+  ssize_t rtp_dataleft; /* how much data left to parse in this round */
+  char *scratch;
+  CURLcode result;
+
+  if(rtspc->rtp_buf) {
+    /* There was some leftover data the last time. Merge buffers */
+    char *newptr = realloc(rtspc->rtp_buf, rtspc->rtp_bufsize + *nread);
+    if(!newptr) {
+      Curl_safefree(rtspc->rtp_buf);
+      rtspc->rtp_buf = NULL;
+      rtspc->rtp_bufsize = 0;
+      return CURLE_OUT_OF_MEMORY;
+    }
+    rtspc->rtp_buf = newptr;
+    memcpy(rtspc->rtp_buf + rtspc->rtp_bufsize, k->str, *nread);
+    rtspc->rtp_bufsize += *nread;
+    rtp = rtspc->rtp_buf;
+    rtp_dataleft = rtspc->rtp_bufsize;
+  }
+  else {
+    /* Just parse the request buffer directly */
+    rtp = k->str;
+    rtp_dataleft = *nread;
+  }
+
+  while((rtp_dataleft > 0) &&
+        (rtp[0] == '$')) {
+    if(rtp_dataleft > 4) {
+      int rtp_length;
+
+      /* Parse the header */
+      /* The channel identifier immediately follows and is 1 byte */
+      rtspc->rtp_channel = RTP_PKT_CHANNEL(rtp);
+
+      /* The length is two bytes */
+      rtp_length = RTP_PKT_LENGTH(rtp);
+
+      if(rtp_dataleft < rtp_length + 4) {
+        /* Need more - incomplete payload*/
+        *readmore = TRUE;
+        break;
+      }
+      else {
+        /* We have the full RTP interleaved packet
+         * Write out the header including the leading '$' */
+        DEBUGF(infof(data, "RTP write channel %d rtp_length %d\n",
+              rtspc->rtp_channel, rtp_length));
+        result = rtp_client_write(conn, &rtp[0], rtp_length + 4);
+        if(result) {
+          failf(data, "Got an error writing an RTP packet");
+          *readmore = FALSE;
+          Curl_safefree(rtspc->rtp_buf);
+          rtspc->rtp_buf = NULL;
+          rtspc->rtp_bufsize = 0;
+          return result;
+        }
+
+        /* Move forward in the buffer */
+        rtp_dataleft -= rtp_length + 4;
+        rtp += rtp_length + 4;
+
+        if(data->set.rtspreq == RTSPREQ_RECEIVE) {
+          /* If we are in a passive receive, give control back
+           * to the app as often as we can.
+           */
+          k->keepon &= ~KEEP_RECV;
+        }
+      }
+    }
+    else {
+      /* Need more - incomplete header */
+      *readmore = TRUE;
+      break;
+    }
+  }
+
+  if(rtp_dataleft != 0 && rtp[0] == '$') {
+    DEBUGF(infof(data, "RTP Rewinding %zd %s\n", rtp_dataleft,
+          *readmore ? "(READMORE)" : ""));
+
+    /* Store the incomplete RTP packet for a "rewind" */
+    scratch = malloc(rtp_dataleft);
+    if(!scratch) {
+      Curl_safefree(rtspc->rtp_buf);
+      rtspc->rtp_buf = NULL;
+      rtspc->rtp_bufsize = 0;
+      return CURLE_OUT_OF_MEMORY;
+    }
+    memcpy(scratch, rtp, rtp_dataleft);
+    Curl_safefree(rtspc->rtp_buf);
+    rtspc->rtp_buf = scratch;
+    rtspc->rtp_bufsize = rtp_dataleft;
+
+    /* As far as the transfer is concerned, this data is consumed */
+    *nread = 0;
+    return CURLE_OK;
+  }
+  else {
+    /* Fix up k->str to point just after the last RTP packet */
+    k->str += *nread - rtp_dataleft;
+
+    /* either all of the data has been read or...
+     * rtp now points at the next byte to parse
+     */
+    if(rtp_dataleft > 0)
+      DEBUGASSERT(k->str[0] == rtp[0]);
+
+    DEBUGASSERT(rtp_dataleft <= *nread); /* sanity check */
+
+    *nread = rtp_dataleft;
+  }
+
+  /* If we get here, we have finished with the leftover/merge buffer */
+  Curl_safefree(rtspc->rtp_buf);
+  rtspc->rtp_buf = NULL;
+  rtspc->rtp_bufsize = 0;
+
+  return CURLE_OK;
+}
+
+static
+CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len)
+{
+  struct SessionHandle *data = conn->data;
+  size_t wrote;
+  curl_write_callback writeit;
+
+  if(len == 0) {
+    failf (data, "Cannot write a 0 size RTP packet.");
+    return CURLE_WRITE_ERROR;
+  }
+
+  writeit = data->set.fwrite_rtp?data->set.fwrite_rtp:data->set.fwrite_func;
+  wrote = writeit(ptr, 1, len, data->set.rtp_out);
+
+  if(CURL_WRITEFUNC_PAUSE == wrote) {
+    failf (data, "Cannot pause RTP");
+    return CURLE_WRITE_ERROR;
+  }
+
+  if(wrote != len) {
+    failf (data, "Failed writing RTP data");
+    return CURLE_WRITE_ERROR;
+  }
+
+  return CURLE_OK;
+}
+
+CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
+                               char *header)
+{
+  struct SessionHandle *data = conn->data;
+  long CSeq = 0;
+
+  if(checkprefix("CSeq:", header)) {
+    /* Store the received CSeq. Match is verified in rtsp_done */
+    int nc = sscanf(&header[4], ": %ld", &CSeq);
+    if(nc == 1) {
+      struct RTSP *rtsp = data->req.protop;
+      rtsp->CSeq_recv = CSeq; /* mark the request */
+      data->state.rtsp_CSeq_recv = CSeq; /* update the handle */
+    }
+    else {
+      failf(data, "Unable to read the CSeq header: [%s]", header);
+      return CURLE_RTSP_CSEQ_ERROR;
+    }
+  }
+  else if(checkprefix("Session:", header)) {
+    char *start;
+
+    /* Find the first non-space letter */
+    start = header + 8;
+    while(*start && ISSPACE(*start))
+      start++;
+
+    if(!*start) {
+      failf(data, "Got a blank Session ID");
+    }
+    else if(data->set.str[STRING_RTSP_SESSION_ID]) {
+      /* If the Session ID is set, then compare */
+      if(strncmp(start, data->set.str[STRING_RTSP_SESSION_ID],
+                 strlen(data->set.str[STRING_RTSP_SESSION_ID]))  != 0) {
+        failf(data, "Got RTSP Session ID Line [%s], but wanted ID [%s]",
+              start, data->set.str[STRING_RTSP_SESSION_ID]);
+        return CURLE_RTSP_SESSION_ERROR;
+      }
+    }
+    else {
+      /* If the Session ID is not set, and we find it in a response, then
+         set it */
+
+      /* The session ID can be an alphanumeric or a 'safe' character
+       *
+       * RFC 2326 15.1 Base Syntax:
+       * safe =  "\$" | "-" | "_" | "." | "+"
+       * */
+      char *end = start;
+      while(*end &&
+            (ISALNUM(*end) || *end == '-' || *end == '_' || *end == '.' ||
+             *end == '+' ||
+             (*end == '\\' && *(end + 1) && *(end + 1) == '$' && (++end, 1))))
+        end++;
+
+      /* Copy the id substring into a new buffer */
+      data->set.str[STRING_RTSP_SESSION_ID] = malloc(end - start + 1);
+      if(data->set.str[STRING_RTSP_SESSION_ID] == NULL)
+        return CURLE_OUT_OF_MEMORY;
+      memcpy(data->set.str[STRING_RTSP_SESSION_ID], start, end - start);
+      (data->set.str[STRING_RTSP_SESSION_ID])[end - start] = '\0';
+    }
+  }
+  return CURLE_OK;
+}
+
+#endif /* CURL_DISABLE_RTSP */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/rtsp.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/rtsp.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/rtsp.h	(revision 164)
@@ -0,0 +1,69 @@
+#ifndef HEADER_CURL_RTSP_H
+#define HEADER_CURL_RTSP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_RTSP
+
+extern const struct Curl_handler Curl_handler_rtsp;
+
+bool Curl_rtsp_connisdead(struct connectdata *check);
+CURLcode Curl_rtsp_parseheader(struct connectdata *conn, char *header);
+
+#else
+/* disabled */
+#define Curl_rtsp_parseheader(x,y) CURLE_NOT_BUILT_IN
+#define Curl_rtsp_connisdead(x) TRUE
+
+#endif /* CURL_DISABLE_RTSP */
+
+/*
+ * RTSP Connection data
+ *
+ * Currently, only used for tracking incomplete RTP data reads
+ */
+struct rtsp_conn {
+  char *rtp_buf;
+  ssize_t rtp_bufsize;
+  int rtp_channel;
+};
+
+/****************************************************************************
+ * RTSP unique setup
+ ***************************************************************************/
+struct RTSP {
+  /*
+   * http_wrapper MUST be the first element of this structure for the wrap
+   * logic to work. In this way, we get a cheap polymorphism because
+   * &(data->state.proto.rtsp) == &(data->state.proto.http) per the C spec
+   *
+   * HTTP functions can safely treat this as an HTTP struct, but RTSP aware
+   * functions can also index into the later elements.
+   */
+  struct HTTP http_wrapper; /*wrap HTTP to do the heavy lifting */
+
+  long CSeq_sent; /* CSeq of this request */
+  long CSeq_recv; /* CSeq received */
+};
+
+
+#endif /* HEADER_CURL_RTSP_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/security.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/security.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/security.c	(revision 164)
@@ -0,0 +1,580 @@
+/* This source code was modified by Martin Hedenfalk <mhe@stacken.kth.se> for
+ * use in Curl. His latest changes were done 2000-09-18.
+ *
+ * It has since been patched and modified a lot by Daniel Stenberg
+ * <daniel@haxx.se> to make it better applied to curl conditions, and to make
+ * it not use globals, pollute name space and more. This source code awaits a
+ * rewrite to work around the paragraph 2 in the BSD licenses as explained
+ * below.
+ *
+ * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ *
+ * Copyright (C) 2001 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.  */
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FTP
+#ifdef HAVE_GSSAPI
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "urldata.h"
+#include "curl_base64.h"
+#include "curl_memory.h"
+#include "curl_sec.h"
+#include "ftp.h"
+#include "sendf.h"
+#include "rawstr.h"
+#include "warnless.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+static const struct {
+  enum protection_level level;
+  const char *name;
+} level_names[] = {
+  { PROT_CLEAR, "clear" },
+  { PROT_SAFE, "safe" },
+  { PROT_CONFIDENTIAL, "confidential" },
+  { PROT_PRIVATE, "private" }
+};
+
+static enum protection_level
+name_to_level(const char *name)
+{
+  int i;
+  for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++)
+    if(checkprefix(name, level_names[i].name))
+      return level_names[i].level;
+  return PROT_NONE;
+}
+
+/* Convert a protocol |level| to its char representation.
+   We take an int to catch programming mistakes. */
+static char level_to_char(int level) {
+  switch(level) {
+  case PROT_CLEAR:
+    return 'C';
+  case PROT_SAFE:
+    return 'S';
+  case PROT_CONFIDENTIAL:
+    return 'E';
+  case PROT_PRIVATE:
+    return 'P';
+  case PROT_CMD:
+    /* Fall through */
+  default:
+    /* Those 2 cases should not be reached! */
+    break;
+  }
+  DEBUGASSERT(0);
+  /* Default to the most secure alternative. */
+  return 'P';
+}
+
+/* Send an FTP command defined by |message| and the optional arguments. The
+   function returns the ftp_code. If an error occurs, -1 is returned. */
+static int ftp_send_command(struct connectdata *conn, const char *message, ...)
+{
+  int ftp_code;
+  ssize_t nread=0;
+  va_list args;
+  char print_buffer[50];
+
+  va_start(args, message);
+  vsnprintf(print_buffer, sizeof(print_buffer), message, args);
+  va_end(args);
+
+  if(Curl_ftpsendf(conn, print_buffer)) {
+    ftp_code = -1;
+  }
+  else {
+    if(Curl_GetFTPResponse(&nread, conn, &ftp_code))
+      ftp_code = -1;
+  }
+
+  (void)nread; /* Unused */
+  return ftp_code;
+}
+
+/* Read |len| from the socket |fd| and store it in |to|. Return a CURLcode
+   saying whether an error occurred or CURLE_OK if |len| was read. */
+static CURLcode
+socket_read(curl_socket_t fd, void *to, size_t len)
+{
+  char *to_p = to;
+  CURLcode result;
+  ssize_t nread;
+
+  while(len > 0) {
+    result = Curl_read_plain(fd, to_p, len, &nread);
+    if(!result) {
+      len -= nread;
+      to_p += nread;
+    }
+    else {
+      /* FIXME: We are doing a busy wait */
+      if(result == CURLE_AGAIN)
+        continue;
+      return result;
+    }
+  }
+  return CURLE_OK;
+}
+
+
+/* Write |len| bytes from the buffer |to| to the socket |fd|. Return a
+   CURLcode saying whether an error occurred or CURLE_OK if |len| was
+   written. */
+static CURLcode
+socket_write(struct connectdata *conn, curl_socket_t fd, const void *to,
+             size_t len)
+{
+  const char *to_p = to;
+  CURLcode result;
+  ssize_t written;
+
+  while(len > 0) {
+    result = Curl_write_plain(conn, fd, to_p, len, &written);
+    if(!result) {
+      len -= written;
+      to_p += written;
+    }
+    else {
+      /* FIXME: We are doing a busy wait */
+      if(result == CURLE_AGAIN)
+        continue;
+      return result;
+    }
+  }
+  return CURLE_OK;
+}
+
+static CURLcode read_data(struct connectdata *conn,
+                          curl_socket_t fd,
+                          struct krb5buffer *buf)
+{
+  int len;
+  void* tmp;
+  CURLcode result;
+
+  result = socket_read(fd, &len, sizeof(len));
+  if(result)
+    return result;
+
+  len = ntohl(len);
+  tmp = realloc(buf->data, len);
+  if(tmp == NULL)
+    return CURLE_OUT_OF_MEMORY;
+
+  buf->data = tmp;
+  result = socket_read(fd, buf->data, len);
+  if(result)
+    return result;
+  buf->size = conn->mech->decode(conn->app_data, buf->data, len,
+                                 conn->data_prot, conn);
+  buf->index = 0;
+  return CURLE_OK;
+}
+
+static size_t
+buffer_read(struct krb5buffer *buf, void *data, size_t len)
+{
+  if(buf->size - buf->index < len)
+    len = buf->size - buf->index;
+  memcpy(data, (char*)buf->data + buf->index, len);
+  buf->index += len;
+  return len;
+}
+
+/* Matches Curl_recv signature */
+static ssize_t sec_recv(struct connectdata *conn, int sockindex,
+                        char *buffer, size_t len, CURLcode *err)
+{
+  size_t bytes_read;
+  size_t total_read = 0;
+  curl_socket_t fd = conn->sock[sockindex];
+
+  *err = CURLE_OK;
+
+  /* Handle clear text response. */
+  if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR)
+      return read(fd, buffer, len);
+
+  if(conn->in_buffer.eof_flag) {
+    conn->in_buffer.eof_flag = 0;
+    return 0;
+  }
+
+  bytes_read = buffer_read(&conn->in_buffer, buffer, len);
+  len -= bytes_read;
+  total_read += bytes_read;
+  buffer += bytes_read;
+
+  while(len > 0) {
+    if(read_data(conn, fd, &conn->in_buffer))
+      return -1;
+    if(conn->in_buffer.size == 0) {
+      if(bytes_read > 0)
+        conn->in_buffer.eof_flag = 1;
+      return bytes_read;
+    }
+    bytes_read = buffer_read(&conn->in_buffer, buffer, len);
+    len -= bytes_read;
+    total_read += bytes_read;
+    buffer += bytes_read;
+  }
+  /* FIXME: Check for overflow */
+  return total_read;
+}
+
+/* Send |length| bytes from |from| to the |fd| socket taking care of encoding
+   and negociating with the server. |from| can be NULL. */
+/* FIXME: We don't check for errors nor report any! */
+static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
+                        const char *from, int length)
+{
+  int bytes, htonl_bytes; /* 32-bit integers for htonl */
+  char *buffer = NULL;
+  char *cmd_buffer;
+  size_t cmd_size = 0;
+  CURLcode error;
+  enum protection_level prot_level = conn->data_prot;
+  bool iscmd = (prot_level == PROT_CMD)?TRUE:FALSE;
+
+  DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST);
+
+  if(iscmd) {
+    if(!strncmp(from, "PASS ", 5) || !strncmp(from, "ACCT ", 5))
+      prot_level = PROT_PRIVATE;
+    else
+      prot_level = conn->command_prot;
+  }
+  bytes = conn->mech->encode(conn->app_data, from, length, prot_level,
+                             (void**)&buffer);
+  if(!buffer || bytes <= 0)
+    return; /* error */
+
+  if(iscmd) {
+    error = Curl_base64_encode(conn->data, buffer, curlx_sitouz(bytes),
+                               &cmd_buffer, &cmd_size);
+    if(error) {
+      free(buffer);
+      return; /* error */
+    }
+    if(cmd_size > 0) {
+      static const char *enc = "ENC ";
+      static const char *mic = "MIC ";
+      if(prot_level == PROT_PRIVATE)
+        socket_write(conn, fd, enc, 4);
+      else
+        socket_write(conn, fd, mic, 4);
+
+      socket_write(conn, fd, cmd_buffer, cmd_size);
+      socket_write(conn, fd, "\r\n", 2);
+      infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic,
+            cmd_buffer);
+      free(cmd_buffer);
+    }
+  }
+  else {
+    htonl_bytes = htonl(bytes);
+    socket_write(conn, fd, &htonl_bytes, sizeof(htonl_bytes));
+    socket_write(conn, fd, buffer, curlx_sitouz(bytes));
+  }
+  free(buffer);
+}
+
+static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
+                         const char *buffer, size_t length)
+{
+  ssize_t tx = 0, len = conn->buffer_size;
+
+  len -= conn->mech->overhead(conn->app_data, conn->data_prot,
+                              curlx_sztosi(len));
+  if(len <= 0)
+    len = length;
+  while(length) {
+    if(length < (size_t)len)
+      len = length;
+
+    do_sec_send(conn, fd, buffer, curlx_sztosi(len));
+    length -= len;
+    buffer += len;
+    tx += len;
+  }
+  return tx;
+}
+
+/* Matches Curl_send signature */
+static ssize_t sec_send(struct connectdata *conn, int sockindex,
+                        const void *buffer, size_t len, CURLcode *err)
+{
+  curl_socket_t fd = conn->sock[sockindex];
+  *err = CURLE_OK;
+  return sec_write(conn, fd, buffer, len);
+}
+
+int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
+                      enum protection_level level)
+{
+  /* decoded_len should be size_t or ssize_t but conn->mech->decode returns an
+     int */
+  int decoded_len;
+  char *buf;
+  int ret_code = 0;
+  size_t decoded_sz = 0;
+  CURLcode error;
+
+  DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
+
+  error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz);
+  if(error || decoded_sz == 0)
+    return -1;
+
+  if(decoded_sz > (size_t)INT_MAX) {
+    free(buf);
+    return -1;
+  }
+  decoded_len = curlx_uztosi(decoded_sz);
+
+  decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len,
+                                   level, conn);
+  if(decoded_len <= 0) {
+    free(buf);
+    return -1;
+  }
+
+  if(conn->data->set.verbose) {
+    buf[decoded_len] = '\n';
+    Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1, conn);
+  }
+
+  buf[decoded_len] = '\0';
+  if(decoded_len <= 3)
+    /* suspiciously short */
+    return 0;
+
+  if(buf[3] != '-')
+    /* safe to ignore return code */
+    (void)sscanf(buf, "%d", &ret_code);
+
+  if(buf[decoded_len - 1] == '\n')
+    buf[decoded_len - 1] = '\0';
+  /* FIXME: Is |buffer| length always greater than |decoded_len|? */
+  strcpy(buffer, buf);
+  free(buf);
+  return ret_code;
+}
+
+/* FIXME: The error code returned here is never checked. */
+static int sec_set_protection_level(struct connectdata *conn)
+{
+  int code;
+  char* pbsz;
+  static unsigned int buffer_size = 1 << 20; /* 1048576 */
+  enum protection_level level = conn->request_data_prot;
+
+  DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
+
+  if(!conn->sec_complete) {
+    infof(conn->data, "Trying to change the protection level after the"
+                      "completion of the data exchange.\n");
+    return -1;
+  }
+
+  /* Bail out if we try to set up the same level */
+  if(conn->data_prot == level)
+    return 0;
+
+  if(level) {
+    code = ftp_send_command(conn, "PBSZ %u", buffer_size);
+    if(code < 0)
+      return -1;
+
+    if(code/100 != 2) {
+      failf(conn->data, "Failed to set the protection's buffer size.");
+      return -1;
+    }
+    conn->buffer_size = buffer_size;
+
+    pbsz = strstr(conn->data->state.buffer, "PBSZ=");
+    if(pbsz) {
+      /* ignore return code, use default value if it fails */
+      (void)sscanf(pbsz, "PBSZ=%u", &buffer_size);
+      if(buffer_size < conn->buffer_size)
+        conn->buffer_size = buffer_size;
+    }
+  }
+
+  /* Now try to negiociate the protection level. */
+  code = ftp_send_command(conn, "PROT %c", level_to_char(level));
+
+  if(code < 0)
+    return -1;
+
+  if(code/100 != 2) {
+    failf(conn->data, "Failed to set the protection level.");
+    return -1;
+  }
+
+  conn->data_prot = level;
+  if(level == PROT_PRIVATE)
+    conn->command_prot = level;
+
+  return 0;
+}
+
+int
+Curl_sec_request_prot(struct connectdata *conn, const char *level)
+{
+  enum protection_level l = name_to_level(level);
+  if(l == PROT_NONE)
+    return -1;
+  DEBUGASSERT(l > PROT_NONE && l < PROT_LAST);
+  conn->request_data_prot = l;
+  return 0;
+}
+
+static CURLcode choose_mech(struct connectdata *conn)
+{
+  int ret;
+  struct SessionHandle *data = conn->data;
+  void *tmp_allocation;
+  const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech;
+
+  tmp_allocation = realloc(conn->app_data, mech->size);
+  if(tmp_allocation == NULL) {
+    failf(data, "Failed realloc of size %u", mech->size);
+    mech = NULL;
+    return CURLE_OUT_OF_MEMORY;
+  }
+  conn->app_data = tmp_allocation;
+
+  if(mech->init) {
+    ret = mech->init(conn->app_data);
+    if(ret) {
+      infof(data, "Failed initialization for %s. Skipping it.\n",
+            mech->name);
+      return CURLE_FAILED_INIT;
+    }
+  }
+
+  infof(data, "Trying mechanism %s...\n", mech->name);
+  ret = ftp_send_command(conn, "AUTH %s", mech->name);
+  if(ret < 0)
+    /* FIXME: This error is too generic but it is OK for now. */
+    return CURLE_COULDNT_CONNECT;
+
+  if(ret/100 != 3) {
+    switch(ret) {
+    case 504:
+      infof(data, "Mechanism %s is not supported by the server (server "
+            "returned ftp code: 504).\n", mech->name);
+      break;
+    case 534:
+      infof(data, "Mechanism %s was rejected by the server (server returned "
+            "ftp code: 534).\n", mech->name);
+      break;
+    default:
+      if(ret/100 == 5) {
+        infof(data, "server does not support the security extensions\n");
+        return CURLE_USE_SSL_FAILED;
+      }
+      break;
+    }
+    return CURLE_LOGIN_DENIED;
+  }
+
+  /* Authenticate */
+  ret = mech->auth(conn->app_data, conn);
+
+  if(ret != AUTH_CONTINUE) {
+    if(ret != AUTH_OK) {
+      /* Mechanism has dumped the error to stderr, don't error here. */
+      return -1;
+    }
+    DEBUGASSERT(ret == AUTH_OK);
+
+    conn->mech = mech;
+    conn->sec_complete = 1;
+    conn->recv[FIRSTSOCKET] = sec_recv;
+    conn->send[FIRSTSOCKET] = sec_send;
+    conn->recv[SECONDARYSOCKET] = sec_recv;
+    conn->send[SECONDARYSOCKET] = sec_send;
+    conn->command_prot = PROT_SAFE;
+    /* Set the requested protection level */
+    /* BLOCKING */
+    (void)sec_set_protection_level(conn);
+  }
+
+  return CURLE_OK;
+}
+
+CURLcode
+Curl_sec_login(struct connectdata *conn)
+{
+  return choose_mech(conn);
+}
+
+
+void
+Curl_sec_end(struct connectdata *conn)
+{
+  if(conn->mech != NULL && conn->mech->end)
+    conn->mech->end(conn->app_data);
+  free(conn->app_data);
+  conn->app_data = NULL;
+  if(conn->in_buffer.data) {
+    free(conn->in_buffer.data);
+    conn->in_buffer.data = NULL;
+    conn->in_buffer.size = 0;
+    conn->in_buffer.index = 0;
+    /* FIXME: Is this really needed? */
+    conn->in_buffer.eof_flag = 0;
+  }
+  conn->sec_complete = 0;
+  conn->data_prot = PROT_CLEAR;
+  conn->mech = NULL;
+}
+
+#endif /* HAVE_GSSAPI */
+
+#endif /* CURL_DISABLE_FTP */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/select.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/select.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/select.c	(revision 164)
@@ -0,0 +1,578 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE)
+#error "We can't compile without select() or poll() support."
+#endif
+
+#if defined(__BEOS__) && !defined(__HAIKU__)
+/* BeOS has FD_SET defined in socket.h */
+#include <socket.h>
+#endif
+
+#ifdef MSDOS
+#include <dos.h>  /* delay() */
+#endif
+
+#ifdef __VXWORKS__
+#include <strings.h>  /* bzero() in FD_SET */
+#endif
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "connect.h"
+#include "select.h"
+#include "warnless.h"
+
+/* Convenience local macros */
+
+#define elapsed_ms  (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
+
+int Curl_ack_eintr = 0;
+#define error_not_EINTR (Curl_ack_eintr || error != EINTR)
+
+/*
+ * Internal function used for waiting a specific amount of ms
+ * in Curl_socket_ready() and Curl_poll() when no file descriptor
+ * is provided to wait on, just being used to delay execution.
+ * WinSock select() and poll() timeout mechanisms need a valid
+ * socket descriptor in a not null file descriptor set to work.
+ * Waiting indefinitely with this function is not allowed, a
+ * zero or negative timeout value will return immediately.
+ * Timeout resolution, accuracy, as well as maximum supported
+ * value is system dependent, neither factor is a citical issue
+ * for the intended use of this function in the library.
+ *
+ * Return values:
+ *   -1 = system call error, invalid timeout value, or interrupted
+ *    0 = specified timeout has elapsed
+ */
+int Curl_wait_ms(int timeout_ms)
+{
+#if !defined(MSDOS) && !defined(USE_WINSOCK)
+#ifndef HAVE_POLL_FINE
+  struct timeval pending_tv;
+#endif
+  struct timeval initial_tv;
+  int pending_ms;
+  int error;
+#endif
+  int r = 0;
+
+  if(!timeout_ms)
+    return 0;
+  if(timeout_ms < 0) {
+    SET_SOCKERRNO(EINVAL);
+    return -1;
+  }
+#if defined(MSDOS)
+  delay(timeout_ms);
+#elif defined(USE_WINSOCK)
+  Sleep(timeout_ms);
+#else
+  pending_ms = timeout_ms;
+  initial_tv = curlx_tvnow();
+  do {
+#if defined(HAVE_POLL_FINE)
+    r = poll(NULL, 0, pending_ms);
+#else
+    pending_tv.tv_sec = pending_ms / 1000;
+    pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+    r = select(0, NULL, NULL, NULL, &pending_tv);
+#endif /* HAVE_POLL_FINE */
+    if(r != -1)
+      break;
+    error = SOCKERRNO;
+    if(error && error_not_EINTR)
+      break;
+    pending_ms = timeout_ms - elapsed_ms;
+    if(pending_ms <= 0) {
+      r = 0;  /* Simulate a "call timed out" case */
+      break;
+    }
+  } while(r == -1);
+#endif /* USE_WINSOCK */
+  if(r)
+    r = -1;
+  return r;
+}
+
+/*
+ * Wait for read or write events on a set of file descriptors. It uses poll()
+ * when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
+ * otherwise select() is used.  An error is returned if select() is being used
+ * and a file descriptor is too large for FD_SETSIZE.
+ *
+ * A negative timeout value makes this function wait indefinitely,
+ * unles no valid file descriptor is given, when this happens the
+ * negative timeout is ignored and the function times out immediately.
+ *
+ * Return values:
+ *   -1 = system call error or fd >= FD_SETSIZE
+ *    0 = timeout
+ *    [bitmask] = action as described below
+ *
+ * CURL_CSELECT_IN - first socket is readable
+ * CURL_CSELECT_IN2 - second socket is readable
+ * CURL_CSELECT_OUT - write socket is writable
+ * CURL_CSELECT_ERR - an error condition occurred
+ */
+int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
+                      curl_socket_t readfd1,
+                      curl_socket_t writefd, /* socket to write to */
+                      long timeout_ms)       /* milliseconds to wait */
+{
+#ifdef HAVE_POLL_FINE
+  struct pollfd pfd[3];
+  int num;
+#else
+  struct timeval pending_tv;
+  struct timeval *ptimeout;
+  fd_set fds_read;
+  fd_set fds_write;
+  fd_set fds_err;
+  curl_socket_t maxfd;
+#endif
+  struct timeval initial_tv = {0, 0};
+  int pending_ms = 0;
+  int error;
+  int r;
+  int ret;
+
+  if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
+     (writefd == CURL_SOCKET_BAD)) {
+    /* no sockets, just wait */
+    r = Curl_wait_ms((int)timeout_ms);
+    return r;
+  }
+
+  /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
+     time in this function does not need to be measured. This happens
+     when function is called with a zero timeout or a negative timeout
+     value indicating a blocking call should be performed. */
+
+  if(timeout_ms > 0) {
+    pending_ms = (int)timeout_ms;
+    initial_tv = curlx_tvnow();
+  }
+
+#ifdef HAVE_POLL_FINE
+
+  num = 0;
+  if(readfd0 != CURL_SOCKET_BAD) {
+    pfd[num].fd = readfd0;
+    pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
+    pfd[num].revents = 0;
+    num++;
+  }
+  if(readfd1 != CURL_SOCKET_BAD) {
+    pfd[num].fd = readfd1;
+    pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
+    pfd[num].revents = 0;
+    num++;
+  }
+  if(writefd != CURL_SOCKET_BAD) {
+    pfd[num].fd = writefd;
+    pfd[num].events = POLLWRNORM|POLLOUT;
+    pfd[num].revents = 0;
+    num++;
+  }
+
+  do {
+    if(timeout_ms < 0)
+      pending_ms = -1;
+    else if(!timeout_ms)
+      pending_ms = 0;
+    r = poll(pfd, num, pending_ms);
+    if(r != -1)
+      break;
+    error = SOCKERRNO;
+    if(error && error_not_EINTR)
+      break;
+    if(timeout_ms > 0) {
+      pending_ms = (int)(timeout_ms - elapsed_ms);
+      if(pending_ms <= 0) {
+        r = 0;  /* Simulate a "call timed out" case */
+        break;
+      }
+    }
+  } while(r == -1);
+
+  if(r < 0)
+    return -1;
+  if(r == 0)
+    return 0;
+
+  ret = 0;
+  num = 0;
+  if(readfd0 != CURL_SOCKET_BAD) {
+    if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
+      ret |= CURL_CSELECT_IN;
+    if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
+      ret |= CURL_CSELECT_ERR;
+    num++;
+  }
+  if(readfd1 != CURL_SOCKET_BAD) {
+    if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
+      ret |= CURL_CSELECT_IN2;
+    if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
+      ret |= CURL_CSELECT_ERR;
+    num++;
+  }
+  if(writefd != CURL_SOCKET_BAD) {
+    if(pfd[num].revents & (POLLWRNORM|POLLOUT))
+      ret |= CURL_CSELECT_OUT;
+    if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
+      ret |= CURL_CSELECT_ERR;
+  }
+
+  return ret;
+
+#else  /* HAVE_POLL_FINE */
+
+  FD_ZERO(&fds_err);
+  maxfd = (curl_socket_t)-1;
+
+  FD_ZERO(&fds_read);
+  if(readfd0 != CURL_SOCKET_BAD) {
+    VERIFY_SOCK(readfd0);
+    FD_SET(readfd0, &fds_read);
+    FD_SET(readfd0, &fds_err);
+    maxfd = readfd0;
+  }
+  if(readfd1 != CURL_SOCKET_BAD) {
+    VERIFY_SOCK(readfd1);
+    FD_SET(readfd1, &fds_read);
+    FD_SET(readfd1, &fds_err);
+    if(readfd1 > maxfd)
+      maxfd = readfd1;
+  }
+
+  FD_ZERO(&fds_write);
+  if(writefd != CURL_SOCKET_BAD) {
+    VERIFY_SOCK(writefd);
+    FD_SET(writefd, &fds_write);
+    FD_SET(writefd, &fds_err);
+    if(writefd > maxfd)
+      maxfd = writefd;
+  }
+
+  ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
+
+  do {
+    if(timeout_ms > 0) {
+      pending_tv.tv_sec = pending_ms / 1000;
+      pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+    }
+    else if(!timeout_ms) {
+      pending_tv.tv_sec = 0;
+      pending_tv.tv_usec = 0;
+    }
+
+    /* WinSock select() must not be called with an fd_set that contains zero
+       fd flags, or it will return WSAEINVAL.  But, it also can't be called
+       with no fd_sets at all!  From the documentation:
+
+         Any two of the parameters, readfds, writefds, or exceptfds, can be
+         given as null. At least one must be non-null, and any non-null
+         descriptor set must contain at least one handle to a socket.
+
+       We know that we have at least one bit set in at least two fd_sets in
+       this case, but we may have no bits set in either fds_read or fd_write,
+       so check for that and handle it.  Luckily, with WinSock, we can _also_
+       ask how many bits are set on an fd_set.
+
+       It is unclear why WinSock doesn't just handle this for us instead of
+       calling this an error.
+
+       Note also that WinSock ignores the first argument, so we don't worry
+       about the fact that maxfd is computed incorrectly with WinSock (since
+       curl_socket_t is unsigned in such cases and thus -1 is the largest
+       value).
+    */
+#ifdef USE_WINSOCK
+    r = select((int)maxfd + 1,
+               fds_read.fd_count ? &fds_read : NULL,
+               fds_write.fd_count ? &fds_write : NULL,
+               &fds_err, ptimeout);
+#else
+    r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
+#endif
+
+    if(r != -1)
+      break;
+    error = SOCKERRNO;
+    if(error && error_not_EINTR)
+      break;
+    if(timeout_ms > 0) {
+      pending_ms = timeout_ms - elapsed_ms;
+      if(pending_ms <= 0) {
+        r = 0;  /* Simulate a "call timed out" case */
+        break;
+      }
+    }
+  } while(r == -1);
+
+  if(r < 0)
+    return -1;
+  if(r == 0)
+    return 0;
+
+  ret = 0;
+  if(readfd0 != CURL_SOCKET_BAD) {
+    if(FD_ISSET(readfd0, &fds_read))
+      ret |= CURL_CSELECT_IN;
+    if(FD_ISSET(readfd0, &fds_err))
+      ret |= CURL_CSELECT_ERR;
+  }
+  if(readfd1 != CURL_SOCKET_BAD) {
+    if(FD_ISSET(readfd1, &fds_read))
+      ret |= CURL_CSELECT_IN2;
+    if(FD_ISSET(readfd1, &fds_err))
+      ret |= CURL_CSELECT_ERR;
+  }
+  if(writefd != CURL_SOCKET_BAD) {
+    if(FD_ISSET(writefd, &fds_write))
+      ret |= CURL_CSELECT_OUT;
+    if(FD_ISSET(writefd, &fds_err))
+      ret |= CURL_CSELECT_ERR;
+  }
+
+  return ret;
+
+#endif  /* HAVE_POLL_FINE */
+
+}
+
+/*
+ * This is a wrapper around poll().  If poll() does not exist, then
+ * select() is used instead.  An error is returned if select() is
+ * being used and a file descriptor is too large for FD_SETSIZE.
+ * A negative timeout value makes this function wait indefinitely,
+ * unles no valid file descriptor is given, when this happens the
+ * negative timeout is ignored and the function times out immediately.
+ *
+ * Return values:
+ *   -1 = system call error or fd >= FD_SETSIZE
+ *    0 = timeout
+ *    N = number of structures with non zero revent fields
+ */
+int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
+{
+#ifndef HAVE_POLL_FINE
+  struct timeval pending_tv;
+  struct timeval *ptimeout;
+  fd_set fds_read;
+  fd_set fds_write;
+  fd_set fds_err;
+  curl_socket_t maxfd;
+#endif
+  struct timeval initial_tv = {0, 0};
+  bool fds_none = TRUE;
+  unsigned int i;
+  int pending_ms = 0;
+  int error;
+  int r;
+
+  if(ufds) {
+    for(i = 0; i < nfds; i++) {
+      if(ufds[i].fd != CURL_SOCKET_BAD) {
+        fds_none = FALSE;
+        break;
+      }
+    }
+  }
+  if(fds_none) {
+    r = Curl_wait_ms(timeout_ms);
+    return r;
+  }
+
+  /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
+     time in this function does not need to be measured. This happens
+     when function is called with a zero timeout or a negative timeout
+     value indicating a blocking call should be performed. */
+
+  if(timeout_ms > 0) {
+    pending_ms = timeout_ms;
+    initial_tv = curlx_tvnow();
+  }
+
+#ifdef HAVE_POLL_FINE
+
+  do {
+    if(timeout_ms < 0)
+      pending_ms = -1;
+    else if(!timeout_ms)
+      pending_ms = 0;
+    r = poll(ufds, nfds, pending_ms);
+    if(r != -1)
+      break;
+    error = SOCKERRNO;
+    if(error && error_not_EINTR)
+      break;
+    if(timeout_ms > 0) {
+      pending_ms = timeout_ms - elapsed_ms;
+      if(pending_ms <= 0) {
+        r = 0;  /* Simulate a "call timed out" case */
+        break;
+      }
+    }
+  } while(r == -1);
+
+  if(r < 0)
+    return -1;
+  if(r == 0)
+    return 0;
+
+  for(i = 0; i < nfds; i++) {
+    if(ufds[i].fd == CURL_SOCKET_BAD)
+      continue;
+    if(ufds[i].revents & POLLHUP)
+      ufds[i].revents |= POLLIN;
+    if(ufds[i].revents & POLLERR)
+      ufds[i].revents |= (POLLIN|POLLOUT);
+  }
+
+#else  /* HAVE_POLL_FINE */
+
+  FD_ZERO(&fds_read);
+  FD_ZERO(&fds_write);
+  FD_ZERO(&fds_err);
+  maxfd = (curl_socket_t)-1;
+
+  for(i = 0; i < nfds; i++) {
+    ufds[i].revents = 0;
+    if(ufds[i].fd == CURL_SOCKET_BAD)
+      continue;
+    VERIFY_SOCK(ufds[i].fd);
+    if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
+                          POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
+      if(ufds[i].fd > maxfd)
+        maxfd = ufds[i].fd;
+      if(ufds[i].events & (POLLRDNORM|POLLIN))
+        FD_SET(ufds[i].fd, &fds_read);
+      if(ufds[i].events & (POLLWRNORM|POLLOUT))
+        FD_SET(ufds[i].fd, &fds_write);
+      if(ufds[i].events & (POLLRDBAND|POLLPRI))
+        FD_SET(ufds[i].fd, &fds_err);
+    }
+  }
+
+#ifdef USE_WINSOCK
+  /* WinSock select() can't handle zero events.  See the comment about this in
+     Curl_check_socket(). */
+  if(fds_read.fd_count == 0 && fds_write.fd_count == 0
+     && fds_err.fd_count == 0) {
+    r = Curl_wait_ms(timeout_ms);
+    return r;
+  }
+#endif
+
+  ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
+
+  do {
+    if(timeout_ms > 0) {
+      pending_tv.tv_sec = pending_ms / 1000;
+      pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+    }
+    else if(!timeout_ms) {
+      pending_tv.tv_sec = 0;
+      pending_tv.tv_usec = 0;
+    }
+
+#ifdef USE_WINSOCK
+    r = select((int)maxfd + 1,
+               /* WinSock select() can't handle fd_sets with zero bits set, so
+                  don't give it such arguments.  See the comment about this in
+                  Curl_check_socket().
+               */
+               fds_read.fd_count ? &fds_read : NULL,
+               fds_write.fd_count ? &fds_write : NULL,
+               fds_err.fd_count ? &fds_err : NULL, ptimeout);
+#else
+    r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
+#endif
+    if(r != -1)
+      break;
+    error = SOCKERRNO;
+    if(error && error_not_EINTR)
+      break;
+    if(timeout_ms > 0) {
+      pending_ms = timeout_ms - elapsed_ms;
+      if(pending_ms <= 0) {
+        r = 0;  /* Simulate a "call timed out" case */
+        break;
+      }
+    }
+  } while(r == -1);
+
+  if(r < 0)
+    return -1;
+  if(r == 0)
+    return 0;
+
+  r = 0;
+  for(i = 0; i < nfds; i++) {
+    ufds[i].revents = 0;
+    if(ufds[i].fd == CURL_SOCKET_BAD)
+      continue;
+    if(FD_ISSET(ufds[i].fd, &fds_read))
+      ufds[i].revents |= POLLIN;
+    if(FD_ISSET(ufds[i].fd, &fds_write))
+      ufds[i].revents |= POLLOUT;
+    if(FD_ISSET(ufds[i].fd, &fds_err))
+      ufds[i].revents |= POLLPRI;
+    if(ufds[i].revents != 0)
+      r++;
+  }
+
+#endif  /* HAVE_POLL_FINE */
+
+  return r;
+}
+
+#ifdef TPF
+/*
+ * This is a replacement for select() on the TPF platform.
+ * It is used whenever libcurl calls select().
+ * The call below to tpf_process_signals() is required because
+ * TPF's select calls are not signal interruptible.
+ *
+ * Return values are the same as select's.
+ */
+int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
+                       fd_set* excepts, struct timeval* tv)
+{
+   int rc;
+
+   rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
+   tpf_process_signals();
+   return rc;
+}
+#endif /* TPF */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/select.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/select.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/select.h	(revision 164)
@@ -0,0 +1,114 @@
+#ifndef HEADER_CURL_SELECT_H
+#define HEADER_CURL_SELECT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_SYS_POLL_H
+#include <sys/poll.h>
+#elif defined(HAVE_POLL_H)
+#include <poll.h>
+#endif
+
+/*
+ * Definition of pollfd struct and constants for platforms lacking them.
+ */
+
+#if !defined(HAVE_STRUCT_POLLFD) && \
+    !defined(HAVE_SYS_POLL_H) && \
+    !defined(HAVE_POLL_H)
+
+#define POLLIN      0x01
+#define POLLPRI     0x02
+#define POLLOUT     0x04
+#define POLLERR     0x08
+#define POLLHUP     0x10
+#define POLLNVAL    0x20
+
+struct pollfd
+{
+    curl_socket_t fd;
+    short   events;
+    short   revents;
+};
+
+#endif
+
+#ifndef POLLRDNORM
+#define POLLRDNORM POLLIN
+#endif
+
+#ifndef POLLWRNORM
+#define POLLWRNORM POLLOUT
+#endif
+
+#ifndef POLLRDBAND
+#define POLLRDBAND POLLPRI
+#endif
+
+/* there are three CSELECT defines that are defined in the public header that
+   are exposed to users, but this *IN2 bit is only ever used internally and
+   therefore defined here */
+#define CURL_CSELECT_IN2 (CURL_CSELECT_ERR << 1)
+
+int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
+                      curl_socket_t writefd,
+                      long timeout_ms);
+
+/* provide the former API internally */
+#define Curl_socket_ready(x,y,z) \
+  Curl_socket_check(x, CURL_SOCKET_BAD, y, z)
+
+int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
+
+/* On non-DOS and non-Winsock platforms, when Curl_ack_eintr is set,
+ * EINTR condition is honored and function might exit early without
+ * awaiting full timeout.  Otherwise EINTR will be ignored and full
+ * timeout will elapse. */
+extern int Curl_ack_eintr;
+
+int Curl_wait_ms(int timeout_ms);
+
+#ifdef TPF
+int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
+                       fd_set* excepts, struct timeval* tv);
+#endif
+
+/* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1], which
+   unfortunately makes it impossible for us to easily check if they're valid
+*/
+#if defined(USE_WINSOCK) || defined(TPF)
+#define VALID_SOCK(x) 1
+#define VERIFY_SOCK(x) Curl_nop_stmt
+#else
+#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
+#define VERIFY_SOCK(x) do { \
+  if(!VALID_SOCK(x)) { \
+    SET_SOCKERRNO(EINVAL); \
+    return -1; \
+  } \
+} WHILE_FALSE
+#endif
+
+#endif /* HEADER_CURL_SELECT_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/sendf.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/sendf.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/sendf.c	(revision 164)
@@ -0,0 +1,712 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "sendf.h"
+#include "connect.h"
+#include "vtls/vtls.h"
+#include "ssh.h"
+#include "multiif.h"
+#include "non-ascii.h"
+#include "curl_printf.h"
+#include "strerror.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifdef CURL_DO_LINEEND_CONV
+/*
+ * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
+ * (\n), with special processing for CRLF sequences that are split between two
+ * blocks of data.  Remaining, bare CRs are changed to LFs.  The possibly new
+ * size of the data is returned.
+ */
+static size_t convert_lineends(struct SessionHandle *data,
+                               char *startPtr, size_t size)
+{
+  char *inPtr, *outPtr;
+
+  /* sanity check */
+  if((startPtr == NULL) || (size < 1)) {
+    return size;
+  }
+
+  if(data->state.prev_block_had_trailing_cr) {
+    /* The previous block of incoming data
+       had a trailing CR, which was turned into a LF. */
+    if(*startPtr == '\n') {
+      /* This block of incoming data starts with the
+         previous block's LF so get rid of it */
+      memmove(startPtr, startPtr+1, size-1);
+      size--;
+      /* and it wasn't a bare CR but a CRLF conversion instead */
+      data->state.crlf_conversions++;
+    }
+    data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
+  }
+
+  /* find 1st CR, if any */
+  inPtr = outPtr = memchr(startPtr, '\r', size);
+  if(inPtr) {
+    /* at least one CR, now look for CRLF */
+    while(inPtr < (startPtr+size-1)) {
+      /* note that it's size-1, so we'll never look past the last byte */
+      if(memcmp(inPtr, "\r\n", 2) == 0) {
+        /* CRLF found, bump past the CR and copy the NL */
+        inPtr++;
+        *outPtr = *inPtr;
+        /* keep track of how many CRLFs we converted */
+        data->state.crlf_conversions++;
+      }
+      else {
+        if(*inPtr == '\r') {
+          /* lone CR, move LF instead */
+          *outPtr = '\n';
+        }
+        else {
+          /* not a CRLF nor a CR, just copy whatever it is */
+          *outPtr = *inPtr;
+        }
+      }
+      outPtr++;
+      inPtr++;
+    } /* end of while loop */
+
+    if(inPtr < startPtr+size) {
+      /* handle last byte */
+      if(*inPtr == '\r') {
+        /* deal with a CR at the end of the buffer */
+        *outPtr = '\n'; /* copy a NL instead */
+        /* note that a CRLF might be split across two blocks */
+        data->state.prev_block_had_trailing_cr = TRUE;
+      }
+      else {
+        /* copy last byte */
+        *outPtr = *inPtr;
+      }
+      outPtr++;
+    }
+    if(outPtr < startPtr+size)
+      /* tidy up by null terminating the now shorter data */
+      *outPtr = '\0';
+
+    return (outPtr - startPtr);
+  }
+  return size;
+}
+#endif /* CURL_DO_LINEEND_CONV */
+
+/* Curl_infof() is for info message along the way */
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
+{
+  if(data && data->set.verbose) {
+    va_list ap;
+    size_t len;
+    char print_buffer[2048 + 1];
+    va_start(ap, fmt);
+    vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
+    va_end(ap);
+    len = strlen(print_buffer);
+    Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
+  }
+}
+#endif
+/* Curl_failf() is for messages stating why we failed.
+ * The message SHALL NOT include any LF or CR.
+ */
+
+void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
+{
+  va_list ap;
+  size_t len;
+  va_start(ap, fmt);
+
+  vsnprintf(data->state.buffer, BUFSIZE, fmt, ap);
+
+  if(data->set.errorbuffer && !data->state.errorbuf) {
+    snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer);
+    data->state.errorbuf = TRUE; /* wrote error string */
+  }
+  if(data->set.verbose) {
+    len = strlen(data->state.buffer);
+    if(len < BUFSIZE - 1) {
+      data->state.buffer[len] = '\n';
+      data->state.buffer[++len] = '\0';
+    }
+    Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
+  }
+
+  va_end(ap);
+}
+
+/* Curl_sendf() sends formated data to the server */
+CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
+                    const char *fmt, ...)
+{
+  struct SessionHandle *data = conn->data;
+  ssize_t bytes_written;
+  size_t write_len;
+  CURLcode result = CURLE_OK;
+  char *s;
+  char *sptr;
+  va_list ap;
+  va_start(ap, fmt);
+  s = vaprintf(fmt, ap); /* returns an allocated string */
+  va_end(ap);
+  if(!s)
+    return CURLE_OUT_OF_MEMORY; /* failure */
+
+  bytes_written=0;
+  write_len = strlen(s);
+  sptr = s;
+
+  for(;;) {
+    /* Write the buffer to the socket */
+    result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
+
+    if(result)
+      break;
+
+    if(data->set.verbose)
+      Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
+
+    if((size_t)bytes_written != write_len) {
+      /* if not all was written at once, we must advance the pointer, decrease
+         the size left and try again! */
+      write_len -= bytes_written;
+      sptr += bytes_written;
+    }
+    else
+      break;
+  }
+
+  free(s); /* free the output string */
+
+  return result;
+}
+
+/*
+ * Curl_write() is an internal write function that sends data to the
+ * server. Works with plain sockets, SCP, SSL or kerberos.
+ *
+ * If the write would block (CURLE_AGAIN), we return CURLE_OK and
+ * (*written == 0). Otherwise we return regular CURLcode value.
+ */
+CURLcode Curl_write(struct connectdata *conn,
+                    curl_socket_t sockfd,
+                    const void *mem,
+                    size_t len,
+                    ssize_t *written)
+{
+  ssize_t bytes_written;
+  CURLcode result = CURLE_OK;
+  int num = (sockfd == conn->sock[SECONDARYSOCKET]);
+
+  bytes_written = conn->send[num](conn, num, mem, len, &result);
+
+  *written = bytes_written;
+  if(bytes_written >= 0)
+    /* we completely ignore the curlcode value when subzero is not returned */
+    return CURLE_OK;
+
+  /* handle CURLE_AGAIN or a send failure */
+  switch(result) {
+  case CURLE_AGAIN:
+    *written = 0;
+    return CURLE_OK;
+
+  case CURLE_OK:
+    /* general send failure */
+    return CURLE_SEND_ERROR;
+
+  default:
+    /* we got a specific curlcode, forward it */
+    return result;
+  }
+}
+
+ssize_t Curl_send_plain(struct connectdata *conn, int num,
+                        const void *mem, size_t len, CURLcode *code)
+{
+  curl_socket_t sockfd = conn->sock[num];
+  ssize_t bytes_written = swrite(sockfd, mem, len);
+
+  *code = CURLE_OK;
+  if(-1 == bytes_written) {
+    int err = SOCKERRNO;
+
+    if(
+#ifdef WSAEWOULDBLOCK
+      /* This is how Windows does it */
+      (WSAEWOULDBLOCK == err)
+#else
+      /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
+         due to its inability to send off data without blocking. We therefor
+         treat both error codes the same here */
+      (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
+#endif
+      ) {
+      /* this is just a case of EWOULDBLOCK */
+      bytes_written=0;
+      *code = CURLE_AGAIN;
+    }
+    else {
+      failf(conn->data, "Send failure: %s",
+            Curl_strerror(conn, err));
+      conn->data->state.os_errno = err;
+      *code = CURLE_SEND_ERROR;
+    }
+  }
+  return bytes_written;
+}
+
+/*
+ * Curl_write_plain() is an internal write function that sends data to the
+ * server using plain sockets only. Otherwise meant to have the exact same
+ * proto as Curl_write()
+ */
+CURLcode Curl_write_plain(struct connectdata *conn,
+                          curl_socket_t sockfd,
+                          const void *mem,
+                          size_t len,
+                          ssize_t *written)
+{
+  ssize_t bytes_written;
+  CURLcode result;
+  int num = (sockfd == conn->sock[SECONDARYSOCKET]);
+
+  bytes_written = Curl_send_plain(conn, num, mem, len, &result);
+
+  *written = bytes_written;
+
+  return result;
+}
+
+ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
+                        size_t len, CURLcode *code)
+{
+  curl_socket_t sockfd = conn->sock[num];
+  ssize_t nread = sread(sockfd, buf, len);
+
+  *code = CURLE_OK;
+  if(-1 == nread) {
+    int err = SOCKERRNO;
+
+    if(
+#ifdef WSAEWOULDBLOCK
+      /* This is how Windows does it */
+      (WSAEWOULDBLOCK == err)
+#else
+      /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
+         due to its inability to send off data without blocking. We therefor
+         treat both error codes the same here */
+      (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
+#endif
+      ) {
+      /* this is just a case of EWOULDBLOCK */
+      *code = CURLE_AGAIN;
+    }
+    else {
+      failf(conn->data, "Recv failure: %s",
+            Curl_strerror(conn, err));
+      conn->data->state.os_errno = err;
+      *code = CURLE_RECV_ERROR;
+    }
+  }
+  return nread;
+}
+
+static CURLcode pausewrite(struct SessionHandle *data,
+                           int type, /* what type of data */
+                           const char *ptr,
+                           size_t len)
+{
+  /* signalled to pause sending on this connection, but since we have data
+     we want to send we need to dup it to save a copy for when the sending
+     is again enabled */
+  struct SingleRequest *k = &data->req;
+  char *dupl = malloc(len);
+  if(!dupl)
+    return CURLE_OUT_OF_MEMORY;
+
+  memcpy(dupl, ptr, len);
+
+  /* store this information in the state struct for later use */
+  data->state.tempwrite = dupl;
+  data->state.tempwritesize = len;
+  data->state.tempwritetype = type;
+
+  /* mark the connection as RECV paused */
+  k->keepon |= KEEP_RECV_PAUSE;
+
+  DEBUGF(infof(data, "Pausing with %zu bytes in buffer for type %02x\n",
+               len, type));
+
+  return CURLE_OK;
+}
+
+
+/* Curl_client_chop_write() writes chunks of data not larger than
+ * CURL_MAX_WRITE_SIZE via client write callback(s) and
+ * takes care of pause requests from the callbacks.
+ */
+CURLcode Curl_client_chop_write(struct connectdata *conn,
+                                int type,
+                                char * ptr,
+                                size_t len)
+{
+  struct SessionHandle *data = conn->data;
+  curl_write_callback writeheader = NULL;
+  curl_write_callback writebody = NULL;
+
+  if(!len)
+    return CURLE_OK;
+
+  /* If reading is actually paused, we're forced to append this chunk of data
+     to the already held data, but only if it is the same type as otherwise it
+     can't work and it'll return error instead. */
+  if(data->req.keepon & KEEP_RECV_PAUSE) {
+    size_t newlen;
+    char *newptr;
+    if(type != data->state.tempwritetype)
+      /* major internal confusion */
+      return CURLE_RECV_ERROR;
+
+    DEBUGASSERT(data->state.tempwrite);
+
+    /* figure out the new size of the data to save */
+    newlen = len + data->state.tempwritesize;
+    /* allocate the new memory area */
+    newptr = realloc(data->state.tempwrite, newlen);
+    if(!newptr)
+      return CURLE_OUT_OF_MEMORY;
+    /* copy the new data to the end of the new area */
+    memcpy(newptr + data->state.tempwritesize, ptr, len);
+    /* update the pointer and the size */
+    data->state.tempwrite = newptr;
+    data->state.tempwritesize = newlen;
+    return CURLE_OK;
+  }
+
+  /* Determine the callback(s) to use. */
+  if(type & CLIENTWRITE_BODY)
+    writebody = data->set.fwrite_func;
+  if((type & CLIENTWRITE_HEADER) &&
+     (data->set.fwrite_header || data->set.writeheader)) {
+    /*
+     * Write headers to the same callback or to the especially setup
+     * header callback function (added after version 7.7.1).
+     */
+    writeheader =
+      data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func;
+  }
+
+  /* Chop data, write chunks. */
+  while(len) {
+    size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE;
+
+    if(writebody) {
+      size_t wrote = writebody(ptr, 1, chunklen, data->set.out);
+
+      if(CURL_WRITEFUNC_PAUSE == wrote) {
+        if(conn->handler->flags & PROTOPT_NONETWORK) {
+          /* Protocols that work without network cannot be paused. This is
+             actually only FILE:// just now, and it can't pause since the
+             transfer isn't done using the "normal" procedure. */
+          failf(data, "Write callback asked for PAUSE when not supported!");
+          return CURLE_WRITE_ERROR;
+        }
+        else
+          return pausewrite(data, type, ptr, len);
+      }
+      else if(wrote != chunklen) {
+        failf(data, "Failed writing body (%zu != %zu)", wrote, chunklen);
+        return CURLE_WRITE_ERROR;
+      }
+    }
+
+    if(writeheader) {
+      size_t wrote = writeheader(ptr, 1, chunklen, data->set.writeheader);
+
+      if(CURL_WRITEFUNC_PAUSE == wrote)
+        /* here we pass in the HEADER bit only since if this was body as well
+           then it was passed already and clearly that didn't trigger the
+           pause, so this is saved for later with the HEADER bit only */
+        return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
+
+      if(wrote != chunklen) {
+        failf (data, "Failed writing header");
+        return CURLE_WRITE_ERROR;
+      }
+    }
+
+    ptr += chunklen;
+    len -= chunklen;
+  }
+
+  return CURLE_OK;
+}
+
+
+/* Curl_client_write() sends data to the write callback(s)
+
+   The bit pattern defines to what "streams" to write to. Body and/or header.
+   The defines are in sendf.h of course.
+
+   If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
+   local character encoding.  This is a problem and should be changed in
+   the future to leave the original data alone.
+ */
+CURLcode Curl_client_write(struct connectdata *conn,
+                           int type,
+                           char *ptr,
+                           size_t len)
+{
+  struct SessionHandle *data = conn->data;
+
+  if(0 == len)
+    len = strlen(ptr);
+
+  /* FTP data may need conversion. */
+  if((type & CLIENTWRITE_BODY) &&
+    (conn->handler->protocol & PROTO_FAMILY_FTP) &&
+    conn->proto.ftpc.transfertype == 'A') {
+    /* convert from the network encoding */
+    CURLcode result = Curl_convert_from_network(data, ptr, len);
+    /* Curl_convert_from_network calls failf if unsuccessful */
+    if(result)
+      return result;
+
+#ifdef CURL_DO_LINEEND_CONV
+    /* convert end-of-line markers */
+    len = convert_lineends(data, ptr, len);
+#endif /* CURL_DO_LINEEND_CONV */
+    }
+
+  return Curl_client_chop_write(conn, type, ptr, len);
+}
+
+CURLcode Curl_read_plain(curl_socket_t sockfd,
+                         char *buf,
+                         size_t bytesfromsocket,
+                         ssize_t *n)
+{
+  ssize_t nread = sread(sockfd, buf, bytesfromsocket);
+
+  if(-1 == nread) {
+    int err = SOCKERRNO;
+    int return_error;
+#ifdef USE_WINSOCK
+    return_error = WSAEWOULDBLOCK == err;
+#else
+    return_error = EWOULDBLOCK == err || EAGAIN == err || EINTR == err;
+#endif
+    if(return_error)
+      return CURLE_AGAIN;
+    else
+      return CURLE_RECV_ERROR;
+  }
+
+  /* we only return number of bytes read when we return OK */
+  *n = nread;
+  return CURLE_OK;
+}
+
+/*
+ * Internal read-from-socket function. This is meant to deal with plain
+ * sockets, SSL sockets and kerberos sockets.
+ *
+ * Returns a regular CURLcode value.
+ */
+CURLcode Curl_read(struct connectdata *conn, /* connection data */
+                   curl_socket_t sockfd,     /* read from this socket */
+                   char *buf,                /* store read data here */
+                   size_t sizerequested,     /* max amount to read */
+                   ssize_t *n)               /* amount bytes read */
+{
+  CURLcode result = CURLE_RECV_ERROR;
+  ssize_t nread = 0;
+  size_t bytesfromsocket = 0;
+  char *buffertofill = NULL;
+  bool pipelining = Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1);
+
+  /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
+     If it is the second socket, we set num to 1. Otherwise to 0. This lets
+     us use the correct ssl handle. */
+  int num = (sockfd == conn->sock[SECONDARYSOCKET]);
+
+  *n=0; /* reset amount to zero */
+
+  /* If session can pipeline, check connection buffer  */
+  if(pipelining) {
+    size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
+                                 sizerequested);
+
+    /* Copy from our master buffer first if we have some unread data there*/
+    if(bytestocopy > 0) {
+      memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
+      conn->read_pos += bytestocopy;
+      conn->bits.stream_was_rewound = FALSE;
+
+      *n = (ssize_t)bytestocopy;
+      return CURLE_OK;
+    }
+    /* If we come here, it means that there is no data to read from the buffer,
+     * so we read from the socket */
+    bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char));
+    buffertofill = conn->master_buffer;
+  }
+  else {
+    bytesfromsocket = CURLMIN((long)sizerequested,
+                              conn->data->set.buffer_size ?
+                              conn->data->set.buffer_size : BUFSIZE);
+    buffertofill = buf;
+  }
+
+  nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result);
+  if(nread < 0)
+    return result;
+
+  if(pipelining) {
+    memcpy(buf, conn->master_buffer, nread);
+    conn->buf_len = nread;
+    conn->read_pos = nread;
+  }
+
+  *n += nread;
+
+  return CURLE_OK;
+}
+
+/* return 0 on success */
+static int showit(struct SessionHandle *data, curl_infotype type,
+                  char *ptr, size_t size)
+{
+  static const char s_infotype[CURLINFO_END][3] = {
+    "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
+
+#ifdef CURL_DOES_CONVERSIONS
+  char buf[BUFSIZE+1];
+  size_t conv_size = 0;
+
+  switch(type) {
+  case CURLINFO_HEADER_OUT:
+    /* assume output headers are ASCII */
+    /* copy the data into my buffer so the original is unchanged */
+    if(size > BUFSIZE) {
+      size = BUFSIZE; /* truncate if necessary */
+      buf[BUFSIZE] = '\0';
+    }
+    conv_size = size;
+    memcpy(buf, ptr, size);
+    /* Special processing is needed for this block if it
+     * contains both headers and data (separated by CRLFCRLF).
+     * We want to convert just the headers, leaving the data as-is.
+     */
+    if(size > 4) {
+      size_t i;
+      for(i = 0; i < size-4; i++) {
+        if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
+          /* convert everything through this CRLFCRLF but no further */
+          conv_size = i + 4;
+          break;
+        }
+      }
+    }
+
+    Curl_convert_from_network(data, buf, conv_size);
+    /* Curl_convert_from_network calls failf if unsuccessful */
+    /* we might as well continue even if it fails...   */
+    ptr = buf; /* switch pointer to use my buffer instead */
+    break;
+  default:
+    /* leave everything else as-is */
+    break;
+  }
+#endif /* CURL_DOES_CONVERSIONS */
+
+  if(data->set.fdebug)
+    return (*data->set.fdebug)(data, type, ptr, size,
+                               data->set.debugdata);
+
+  switch(type) {
+  case CURLINFO_TEXT:
+  case CURLINFO_HEADER_OUT:
+  case CURLINFO_HEADER_IN:
+    fwrite(s_infotype[type], 2, 1, data->set.err);
+    fwrite(ptr, size, 1, data->set.err);
+#ifdef CURL_DOES_CONVERSIONS
+    if(size != conv_size) {
+      /* we had untranslated data so we need an explicit newline */
+      fwrite("\n", 1, 1, data->set.err);
+    }
+#endif
+    break;
+  default: /* nada */
+    break;
+  }
+  return 0;
+}
+
+int Curl_debug(struct SessionHandle *data, curl_infotype type,
+               char *ptr, size_t size,
+               struct connectdata *conn)
+{
+  int rc;
+  if(data->set.printhost && conn && conn->host.dispname) {
+    char buffer[160];
+    const char *t=NULL;
+    const char *w="Data";
+    switch (type) {
+    case CURLINFO_HEADER_IN:
+      w = "Header";
+      /* FALLTHROUGH */
+    case CURLINFO_DATA_IN:
+      t = "from";
+      break;
+    case CURLINFO_HEADER_OUT:
+      w = "Header";
+      /* FALLTHROUGH */
+    case CURLINFO_DATA_OUT:
+      t = "to";
+      break;
+    default:
+      break;
+    }
+
+    if(t) {
+      snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
+               conn->host.dispname);
+      rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
+      if(rc)
+        return rc;
+    }
+  }
+  rc = showit(data, type, ptr, size);
+  return rc;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/sendf.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/sendf.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/sendf.h	(revision 164)
@@ -0,0 +1,92 @@
+#ifndef HEADER_CURL_SENDF_H
+#define HEADER_CURL_SENDF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *,
+                    const char *fmt, ...);
+void Curl_infof(struct SessionHandle *, const char *fmt, ...);
+void Curl_failf(struct SessionHandle *, const char *fmt, ...);
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+
+#if defined(HAVE_VARIADIC_MACROS_C99)
+#define infof(...)  Curl_nop_stmt
+#elif defined(HAVE_VARIADIC_MACROS_GCC)
+#define infof(x...)  Curl_nop_stmt
+#else
+#define infof (void)
+#endif
+
+#else /* CURL_DISABLE_VERBOSE_STRINGS */
+
+#define infof Curl_infof
+
+#endif /* CURL_DISABLE_VERBOSE_STRINGS */
+
+#define failf Curl_failf
+
+#define CLIENTWRITE_BODY   (1<<0)
+#define CLIENTWRITE_HEADER (1<<1)
+#define CLIENTWRITE_BOTH   (CLIENTWRITE_BODY|CLIENTWRITE_HEADER)
+
+CURLcode Curl_client_chop_write(struct connectdata *conn, int type, char *ptr,
+                                size_t len) WARN_UNUSED_RESULT;
+CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr,
+                           size_t len) WARN_UNUSED_RESULT;
+
+/* internal read-function, does plain socket only */
+CURLcode Curl_read_plain(curl_socket_t sockfd,
+                         char *buf,
+                         size_t bytesfromsocket,
+                         ssize_t *n);
+
+ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
+                        size_t len, CURLcode *code);
+ssize_t Curl_send_plain(struct connectdata *conn, int num,
+                        const void *mem, size_t len, CURLcode *code);
+
+/* internal read-function, does plain socket, SSL and krb4 */
+CURLcode Curl_read(struct connectdata *conn, curl_socket_t sockfd,
+                   char *buf, size_t buffersize,
+                   ssize_t *n);
+/* internal write-function, does plain socket, SSL, SCP, SFTP and krb4 */
+CURLcode Curl_write(struct connectdata *conn,
+                    curl_socket_t sockfd,
+                    const void *mem, size_t len,
+                    ssize_t *written);
+
+/* internal write-function, does plain sockets ONLY */
+CURLcode Curl_write_plain(struct connectdata *conn,
+                          curl_socket_t sockfd,
+                          const void *mem, size_t len,
+                          ssize_t *written);
+
+/* the function used to output verbose information */
+int Curl_debug(struct SessionHandle *handle, curl_infotype type,
+               char *data, size_t size,
+               struct connectdata *conn);
+
+
+#endif /* HEADER_CURL_SENDF_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/setup-os400.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/setup-os400.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/setup-os400.h	(revision 164)
@@ -0,0 +1,223 @@
+#ifndef HEADER_CURL_SETUP_OS400_H
+#define HEADER_CURL_SETUP_OS400_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+
+/* OS/400 netdb.h does not define NI_MAXHOST. */
+#define NI_MAXHOST      1025
+
+/* OS/400 netdb.h does not define NI_MAXSERV. */
+#define NI_MAXSERV      32
+
+/* No OS/400 header file defines u_int32_t. */
+typedef unsigned long   u_int32_t;
+
+
+/* System API wrapper prototypes & definitions to support ASCII parameters. */
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <gskssl.h>
+#include <qsoasync.h>
+#include <gssapi.h>
+
+extern int      Curl_getaddrinfo_a(const char * nodename,
+                                   const char * servname,
+                                   const struct addrinfo * hints,
+                                   struct addrinfo * * res);
+#define getaddrinfo             Curl_getaddrinfo_a
+
+
+extern int      Curl_getnameinfo_a(const struct sockaddr * sa,
+                                   curl_socklen_t salen,
+                                   char * nodename, curl_socklen_t nodenamelen,
+                                   char * servname, curl_socklen_t servnamelen,
+                                   int flags);
+#define getnameinfo             Curl_getnameinfo_a
+
+
+/* GSKit wrappers. */
+
+extern int      Curl_gsk_environment_open(gsk_handle * my_env_handle);
+#define gsk_environment_open    Curl_gsk_environment_open
+
+extern int      Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
+                                         gsk_handle * my_session_handle);
+#define gsk_secure_soc_open     Curl_gsk_secure_soc_open
+
+extern int      Curl_gsk_environment_close(gsk_handle * my_env_handle);
+#define gsk_environment_close   Curl_gsk_environment_close
+
+extern int      Curl_gsk_secure_soc_close(gsk_handle * my_session_handle);
+#define gsk_secure_soc_close    Curl_gsk_secure_soc_close
+
+extern int      Curl_gsk_environment_init(gsk_handle my_env_handle);
+#define gsk_environment_init    Curl_gsk_environment_init
+
+extern int      Curl_gsk_secure_soc_init(gsk_handle my_session_handle);
+#define gsk_secure_soc_init     Curl_gsk_secure_soc_init
+
+extern int      Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle,
+                                                GSK_BUF_ID bufID,
+                                                const char * buffer,
+                                                int bufSize);
+#define gsk_attribute_set_buffer        Curl_gsk_attribute_set_buffer_a
+
+extern int      Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle,
+                                            GSK_ENUM_ID enumID,
+                                            GSK_ENUM_VALUE enumValue);
+#define gsk_attribute_set_enum  Curl_gsk_attribute_set_enum
+
+extern int      Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
+                                                     GSK_NUM_ID numID,
+                                                     int numValue);
+#define gsk_attribute_set_numeric_value Curl_gsk_attribute_set_numeric_value
+
+extern int      Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
+                                                GSK_CALLBACK_ID callBackID,
+                                                void * callBackAreaPtr);
+#define gsk_attribute_set_callback      Curl_gsk_attribute_set_callback
+
+extern int      Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle,
+                                                GSK_BUF_ID bufID,
+                                                const char * * buffer,
+                                                int * bufSize);
+#define gsk_attribute_get_buffer        Curl_gsk_attribute_get_buffer_a
+
+extern int      Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle,
+                                            GSK_ENUM_ID enumID,
+                                            GSK_ENUM_VALUE * enumValue);
+#define gsk_attribute_get_enum  Curl_gsk_attribute_get_enum
+
+extern int      Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
+                                                     GSK_NUM_ID numID,
+                                                     int * numValue);
+#define gsk_attribute_get_numeric_value Curl_gsk_attribute_get_numeric_value
+
+extern int      Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
+                                 GSK_CERT_ID certID,
+                                 const gsk_cert_data_elem * * certDataElem,
+                                 int * certDataElementCount);
+#define gsk_attribute_get_cert_info     Curl_gsk_attribute_get_cert_info
+
+extern int      Curl_gsk_secure_soc_misc(gsk_handle my_session_handle,
+                                         GSK_MISC_ID miscID);
+#define gsk_secure_soc_misc     Curl_gsk_secure_soc_misc
+
+extern int      Curl_gsk_secure_soc_read(gsk_handle my_session_handle,
+                                         char * readBuffer,
+                                         int readBufSize, int * amtRead);
+#define gsk_secure_soc_read     Curl_gsk_secure_soc_read
+
+extern int      Curl_gsk_secure_soc_write(gsk_handle my_session_handle,
+                                          char * writeBuffer,
+                                          int writeBufSize, int * amtWritten);
+#define gsk_secure_soc_write    Curl_gsk_secure_soc_write
+
+extern const char *     Curl_gsk_strerror_a(int gsk_return_value);
+#define gsk_strerror    Curl_gsk_strerror_a
+
+extern int      Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
+                                      int IOCompletionPort,
+                                      Qso_OverlappedIO_t * communicationsArea);
+#define gsk_secure_soc_startInit        Curl_gsk_secure_soc_startInit
+
+
+/* GSSAPI wrappers. */
+
+extern OM_uint32 Curl_gss_import_name_a(OM_uint32 * minor_status,
+                                        gss_buffer_t in_name,
+                                        gss_OID in_name_type,
+                                        gss_name_t * out_name);
+#define gss_import_name         Curl_gss_import_name_a
+
+
+extern OM_uint32 Curl_gss_display_status_a(OM_uint32 * minor_status,
+                                           OM_uint32 status_value,
+                                           int status_type, gss_OID mech_type,
+                                           gss_msg_ctx_t * message_context,
+                                           gss_buffer_t status_string);
+#define gss_display_status      Curl_gss_display_status_a
+
+
+extern OM_uint32 Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
+                                             gss_cred_id_t cred_handle,
+                                             gss_ctx_id_t * context_handle,
+                                             gss_name_t target_name,
+                                             gss_OID mech_type,
+                                             gss_flags_t req_flags,
+                                             OM_uint32 time_req,
+                                             gss_channel_bindings_t
+                                             input_chan_bindings,
+                                             gss_buffer_t input_token,
+                                             gss_OID * actual_mech_type,
+                                             gss_buffer_t output_token,
+                                             gss_flags_t * ret_flags,
+                                             OM_uint32 * time_rec);
+#define gss_init_sec_context    Curl_gss_init_sec_context_a
+
+
+extern OM_uint32 Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
+                                               gss_ctx_id_t * context_handle,
+                                               gss_buffer_t output_token);
+#define gss_delete_sec_context  Curl_gss_delete_sec_context_a
+
+
+/* LDAP wrappers. */
+
+#define BerValue                struct berval
+
+#define ldap_url_parse          ldap_url_parse_utf8
+#define ldap_init               Curl_ldap_init_a
+#define ldap_simple_bind_s      Curl_ldap_simple_bind_s_a
+#define ldap_search_s           Curl_ldap_search_s_a
+#define ldap_get_values_len     Curl_ldap_get_values_len_a
+#define ldap_err2string         Curl_ldap_err2string_a
+#define ldap_get_dn             Curl_ldap_get_dn_a
+#define ldap_first_attribute    Curl_ldap_first_attribute_a
+#define ldap_next_attribute     Curl_ldap_next_attribute_a
+
+/* Some socket functions must be wrapped to process textual addresses
+   like AF_UNIX. */
+
+extern int Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen);
+extern int Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen);
+extern int Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
+            struct sockaddr * dstaddr, int addrlen);
+extern int Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
+                                struct sockaddr * fromaddr, int * addrlen);
+
+#define connect                 Curl_os400_connect
+#define bind                    Curl_os400_bind
+#define sendto                  Curl_os400_sendto
+#define recvfrom                Curl_os400_recvfrom
+
+#ifdef HAVE_LIBZ
+#define zlibVersion             Curl_os400_zlibVersion
+#define inflateInit_            Curl_os400_inflateInit_
+#define inflateInit2_           Curl_os400_inflateInit2_
+#define inflate                 Curl_os400_inflate
+#define inflateEnd              Curl_os400_inflateEnd
+#endif
+
+#endif /* HEADER_CURL_SETUP_OS400_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/setup-vms.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/setup-vms.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/setup-vms.h	(revision 164)
@@ -0,0 +1,442 @@
+#ifndef HEADER_CURL_SETUP_VMS_H
+#define HEADER_CURL_SETUP_VMS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*                                                                         */
+/* JEM, 12/30/12, VMS now generates config.h, so only define wrappers for  */
+/*                getenv(), getpwuid() and provide is_vms_shell()          */
+/*                Also need upper case symbols for system services, and    */
+/*                OpenSSL, and some Kerberos image                         */
+
+#ifdef __DECC
+#pragma message save
+#pragma message disable dollarid
+#endif
+
+/* Hide the stuff we are overriding */
+#define getenv decc_getenv
+#ifdef __DECC
+#   if __INITIAL_POINTER_SIZE != 64
+#       define getpwuid decc_getpwuid
+#   endif
+#endif
+#include <stdlib.h>
+    char * decc$getenv(const char * __name);
+#include <pwd.h>
+
+#include <string.h>
+#include <unixlib.h>
+
+#undef getenv
+#undef getpwuid
+#define getenv vms_getenv
+#define getpwuid vms_getpwuid
+
+/* VAX needs these in upper case when compiling exact case */
+#define sys$assign SYS$ASSIGN
+#define sys$dassgn SYS$DASSGN
+#define sys$qiow SYS$QIOW
+
+#ifdef __DECC
+#   if __INITIAL_POINTER_SIZE
+#       pragma __pointer_size __save
+#   endif
+#endif
+
+#if __USE_LONG_GID_T
+#   define decc_getpwuid DECC$__LONG_GID_GETPWUID
+#else
+#   if __INITIAL_POINTER_SIZE
+#       define decc_getpwuid decc$__32_getpwuid
+#   else
+#       define decc_getpwuid decc$getpwuid
+#   endif
+#endif
+
+    struct passwd * decc_getpwuid(uid_t uid);
+
+#ifdef __DECC
+#   if __INITIAL_POINTER_SIZE == 32
+/* Translate the path, but only if the path is a VMS file specification */
+/* The translation is usually only needed for older versions of VMS */
+static char * vms_translate_path(const char * path) {
+char * unix_path;
+char * test_str;
+
+    /* See if the result is in VMS format, if not, we are done */
+    /* Assume that this is a PATH, not just some data */
+    test_str = strpbrk(path, ":[<^");
+    if(test_str == NULL) {
+      return (char *)path;
+    }
+
+    unix_path = decc$translate_vms(path);
+
+    if((int)unix_path <= 0) {
+      /* We can not translate it, so return the original string */
+      return (char *)path;
+    }
+}
+#   else
+    /* VMS translate path is actually not needed on the current 64 bit */
+    /* VMS platforms, so instead of figuring out the pointer settings */
+    /* Change it to a noop */
+#   define vms_translate_path(__path) __path
+#   endif
+#endif
+
+#ifdef __DECC
+#   if __INITIAL_POINTER_SIZE
+#       pragma __pointer_size __restore
+#   endif
+#endif
+
+static char * vms_getenv(const char * envvar) {
+
+char * result;
+char * vms_path;
+
+    /* first use the DECC getenv() function */
+    result = decc$getenv(envvar);
+    if(result == NULL) {
+      return result;
+    }
+
+    vms_path = result;
+    result = vms_translate_path(vms_path);
+
+    /* note that if you backport this to use VAX C RTL, that the VAX C RTL */
+    /* may do a malloc(2048) for each call to getenv(), so you will need   */
+    /* to add a free(vms_path) */
+    /* Do not do a free() for DEC C RTL builds, which should be used for */
+    /* VMS 5.5-2 and later, even if using GCC */
+
+    return result;
+}
+
+
+static struct passwd vms_passwd_cache;
+
+static struct passwd * vms_getpwuid(uid_t uid) {
+
+struct passwd * my_passwd;
+
+/* Hack needed to support 64 bit builds, decc_getpwnam is 32 bit only */
+#ifdef __DECC
+#   if __INITIAL_POINTER_SIZE
+__char_ptr32 unix_path;
+#   else
+char * unix_path;
+#   endif
+#else
+char * unix_path;
+#endif
+
+    my_passwd = decc_getpwuid(uid);
+    if(my_passwd == NULL) {
+      return my_passwd;
+    }
+
+    unix_path = vms_translate_path(my_passwd->pw_dir);
+
+    if((long)unix_path <= 0) {
+      /* We can not translate it, so return the original string */
+      return my_passwd;
+    }
+
+    /* If no changes needed just return it */
+    if(unix_path == my_passwd->pw_dir) {
+      return my_passwd;
+    }
+
+    /* Need to copy the structure returned */
+    /* Since curl is only using pw_dir, no need to fix up *
+    /* the pw_shell when running under Bash */
+    vms_passwd_cache.pw_name = my_passwd->pw_name;
+    vms_passwd_cache.pw_uid = my_passwd->pw_uid;
+    vms_passwd_cache.pw_gid = my_passwd->pw_uid;
+    vms_passwd_cache.pw_dir = unix_path;
+    vms_passwd_cache.pw_shell = my_passwd->pw_shell;
+
+    return &vms_passwd_cache;
+}
+
+#ifdef __DECC
+#pragma message restore
+#endif
+
+/* Bug - VMS OpenSSL and Kerberos universal symbols are in uppercase only */
+/* VMS libraries should have universal symbols in exact and uppercase */
+
+#define ASN1_INTEGER_get ASN1_INTEGER_GET
+#define ASN1_STRING_data ASN1_STRING_DATA
+#define ASN1_STRING_length ASN1_STRING_LENGTH
+#define ASN1_STRING_print ASN1_STRING_PRINT
+#define ASN1_STRING_to_UTF8 ASN1_STRING_TO_UTF8
+#define ASN1_STRING_type ASN1_STRING_TYPE
+#define BIO_ctrl BIO_CTRL
+#define BIO_free BIO_FREE
+#define BIO_new BIO_NEW
+#define BIO_s_mem BIO_S_MEM
+#define BN_bn2bin BN_BN2BIN
+#define BN_num_bits BN_NUM_BITS
+#define CRYPTO_cleanup_all_ex_data CRYPTO_CLEANUP_ALL_EX_DATA
+#define CRYPTO_free CRYPTO_FREE
+#define CRYPTO_malloc CRYPTO_MALLOC
+#define CONF_modules_load_file CONF_MODULES_LOAD_FILE
+#ifdef __VAX
+#  ifdef VMS_OLD_SSL
+  /* Ancient OpenSSL on VAX/VMS missing this constant */
+#    define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10
+#    undef CONF_modules_load_file
+     static int CONF_modules_load_file(const char *filename,
+                                       const char *appname,
+                                       unsigned long flags) {
+             return 1;
+     }
+#  endif
+#endif
+#define DES_ecb_encrypt DES_ECB_ENCRYPT
+#define DES_set_key DES_SET_KEY
+#define DES_set_odd_parity DES_SET_ODD_PARITY
+#define ENGINE_ctrl ENGINE_CTRL
+#define ENGINE_ctrl_cmd ENGINE_CTRL_CMD
+#define ENGINE_finish ENGINE_FINISH
+#define ENGINE_free ENGINE_FREE
+#define ENGINE_get_first ENGINE_GET_FIRST
+#define ENGINE_get_id ENGINE_GET_ID
+#define ENGINE_get_next ENGINE_GET_NEXT
+#define ENGINE_init ENGINE_INIT
+#define ENGINE_load_builtin_engines ENGINE_LOAD_BUILTIN_ENGINES
+#define ENGINE_load_private_key ENGINE_LOAD_PRIVATE_KEY
+#define ENGINE_set_default ENGINE_SET_DEFAULT
+#define ERR_clear_error ERR_CLEAR_ERROR
+#define ERR_error_string ERR_ERROR_STRING
+#define ERR_error_string_n ERR_ERROR_STRING_N
+#define ERR_free_strings ERR_FREE_STRINGS
+#define ERR_get_error ERR_GET_ERROR
+#define ERR_peek_error ERR_PEEK_ERROR
+#define ERR_remove_state ERR_REMOVE_STATE
+#define EVP_PKEY_copy_parameters EVP_PKEY_COPY_PARAMETERS
+#define EVP_PKEY_free EVP_PKEY_FREE
+#define EVP_cleanup EVP_CLEANUP
+#define GENERAL_NAMES_free GENERAL_NAMES_FREE
+#define i2d_X509_PUBKEY I2D_X509_PUBKEY
+#define MD4_Final MD4_FINAL
+#define MD4_Init MD4_INIT
+#define MD4_Update MD4_UPDATE
+#define MD5_Final MD5_FINAL
+#define MD5_Init MD5_INIT
+#define MD5_Update MD5_UPDATE
+#define OPENSSL_add_all_algo_noconf OPENSSL_ADD_ALL_ALGO_NOCONF
+#ifndef __VAX
+#define OPENSSL_load_builtin_modules OPENSSL_LOAD_BUILTIN_MODULES
+#endif
+#define PEM_read_X509 PEM_READ_X509
+#define PEM_write_bio_X509 PEM_WRITE_BIO_X509
+#define PKCS12_PBE_add PKCS12_PBE_ADD
+#define PKCS12_free PKCS12_FREE
+#define PKCS12_parse PKCS12_PARSE
+#define RAND_add RAND_ADD
+#define RAND_bytes RAND_BYTES
+#define RAND_egd RAND_EGD
+#define RAND_file_name RAND_FILE_NAME
+#define RAND_load_file RAND_LOAD_FILE
+#define RAND_status RAND_STATUS
+#define SSL_CIPHER_get_name SSL_CIPHER_GET_NAME
+#define SSL_CTX_add_client_CA SSL_CTX_ADD_CLIENT_CA
+#define SSL_CTX_callback_ctrl SSL_CTX_CALLBACK_CTRL
+#define SSL_CTX_check_private_key SSL_CTX_CHECK_PRIVATE_KEY
+#define SSL_CTX_ctrl SSL_CTX_CTRL
+#define SSL_CTX_free SSL_CTX_FREE
+#define SSL_CTX_get_cert_store SSL_CTX_GET_CERT_STORE
+#define SSL_CTX_load_verify_locations SSL_CTX_LOAD_VERIFY_LOCATIONS
+#define SSL_CTX_new SSL_CTX_NEW
+#define SSL_CTX_set_cipher_list SSL_CTX_SET_CIPHER_LIST
+#define SSL_CTX_set_def_passwd_cb_ud SSL_CTX_SET_DEF_PASSWD_CB_UD
+#define SSL_CTX_set_default_passwd_cb SSL_CTX_SET_DEFAULT_PASSWD_CB
+#define SSL_CTX_set_msg_callback SSL_CTX_SET_MSG_CALLBACK
+#define SSL_CTX_set_verify SSL_CTX_SET_VERIFY
+#define SSL_CTX_use_PrivateKey SSL_CTX_USE_PRIVATEKEY
+#define SSL_CTX_use_PrivateKey_file SSL_CTX_USE_PRIVATEKEY_FILE
+#define SSL_CTX_use_cert_chain_file SSL_CTX_USE_CERT_CHAIN_FILE
+#define SSL_CTX_use_certificate SSL_CTX_USE_CERTIFICATE
+#define SSL_CTX_use_certificate_file SSL_CTX_USE_CERTIFICATE_FILE
+#define SSL_SESSION_free SSL_SESSION_FREE
+#define SSL_connect SSL_CONNECT
+#define SSL_free SSL_FREE
+#define SSL_get1_session SSL_GET1_SESSION
+#define SSL_get_certificate SSL_GET_CERTIFICATE
+#define SSL_get_current_cipher SSL_GET_CURRENT_CIPHER
+#define SSL_get_error SSL_GET_ERROR
+#define SSL_get_peer_cert_chain SSL_GET_PEER_CERT_CHAIN
+#define SSL_get_peer_certificate SSL_GET_PEER_CERTIFICATE
+#define SSL_get_privatekey SSL_GET_PRIVATEKEY
+#define SSL_get_session SSL_GET_SESSION
+#define SSL_get_shutdown SSL_GET_SHUTDOWN
+#define SSL_get_verify_result SSL_GET_VERIFY_RESULT
+#define SSL_library_init SSL_LIBRARY_INIT
+#define SSL_load_error_strings SSL_LOAD_ERROR_STRINGS
+#define SSL_new SSL_NEW
+#define SSL_peek SSL_PEEK
+#define SSL_pending SSL_PENDING
+#define SSL_read SSL_READ
+#define SSL_set_connect_state SSL_SET_CONNECT_STATE
+#define SSL_set_fd SSL_SET_FD
+#define SSL_set_session SSL_SET_SESSION
+#define SSL_shutdown SSL_SHUTDOWN
+#define SSL_version SSL_VERSION
+#define SSL_write SSL_WRITE
+#define SSLeay SSLEAY
+#define SSLv23_client_method SSLV23_CLIENT_METHOD
+#define SSLv3_client_method SSLV3_CLIENT_METHOD
+#define TLSv1_client_method TLSV1_CLIENT_METHOD
+#define UI_create_method UI_CREATE_METHOD
+#define UI_destroy_method UI_DESTROY_METHOD
+#define UI_get0_user_data UI_GET0_USER_DATA
+#define UI_get_input_flags UI_GET_INPUT_FLAGS
+#define UI_get_string_type UI_GET_STRING_TYPE
+#define UI_create_method UI_CREATE_METHOD
+#define UI_destroy_method UI_DESTROY_METHOD
+#define UI_method_get_closer UI_METHOD_GET_CLOSER
+#define UI_method_get_opener UI_METHOD_GET_OPENER
+#define UI_method_get_reader UI_METHOD_GET_READER
+#define UI_method_get_writer UI_METHOD_GET_WRITER
+#define UI_method_set_closer UI_METHOD_SET_CLOSER
+#define UI_method_set_opener UI_METHOD_SET_OPENER
+#define UI_method_set_reader UI_METHOD_SET_READER
+#define UI_method_set_writer UI_METHOD_SET_WRITER
+#define UI_OpenSSL UI_OPENSSL
+#define UI_set_result UI_SET_RESULT
+#define X509V3_EXT_print X509V3_EXT_PRINT
+#define X509_EXTENSION_get_critical X509_EXTENSION_GET_CRITICAL
+#define X509_EXTENSION_get_data X509_EXTENSION_GET_DATA
+#define X509_EXTENSION_get_object X509_EXTENSION_GET_OBJECT
+#define X509_LOOKUP_file X509_LOOKUP_FILE
+#define X509_NAME_ENTRY_get_data X509_NAME_ENTRY_GET_DATA
+#define X509_NAME_get_entry X509_NAME_GET_ENTRY
+#define X509_NAME_get_index_by_NID X509_NAME_GET_INDEX_BY_NID
+#define X509_NAME_print_ex X509_NAME_PRINT_EX
+#define X509_STORE_CTX_get_current_cert X509_STORE_CTX_GET_CURRENT_CERT
+#define X509_STORE_add_lookup X509_STORE_ADD_LOOKUP
+#define X509_STORE_set_flags X509_STORE_SET_FLAGS
+#define X509_check_issued X509_CHECK_ISSUED
+#define X509_free X509_FREE
+#define X509_get_ext_d2i X509_GET_EXT_D2I
+#define X509_get_issuer_name X509_GET_ISSUER_NAME
+#define X509_get_pubkey X509_GET_PUBKEY
+#define X509_get_serialNumber X509_GET_SERIALNUMBER
+#define X509_get_subject_name X509_GET_SUBJECT_NAME
+#define X509_load_crl_file X509_LOAD_CRL_FILE
+#define X509_verify_cert_error_string X509_VERIFY_CERT_ERROR_STRING
+#define d2i_PKCS12_fp D2I_PKCS12_FP
+#define i2t_ASN1_OBJECT I2T_ASN1_OBJECT
+#define sk_num SK_NUM
+#define sk_pop SK_POP
+#define sk_pop_free SK_POP_FREE
+#define sk_value SK_VALUE
+#ifdef __VAX
+#define OPENSSL_NO_SHA256
+#endif
+#define SHA256_Final SHA256_FINAL
+#define SHA256_Init SHA256_INIT
+#define SHA256_Update SHA256_UPDATE
+
+#define USE_UPPERCASE_GSSAPI 1
+#define gss_seal GSS_SEAL
+#define gss_unseal GSS_UNSEAL
+
+#define USE_UPPERCASE_KRBAPI 1
+
+/* AI_NUMERICHOST needed for IP V6 support in Curl */
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#ifndef AI_NUMERICHOST
+#ifdef ENABLE_IPV6
+#undef ENABLE_IPV6
+#endif
+#endif
+#endif
+
+/* VAX symbols are always in uppercase */
+#ifdef __VAX
+#define inflate INFLATE
+#define inflateEnd INFLATEEND
+#define inflateInit2_ INFLATEINIT2_
+#define inflateInit_ INFLATEINIT_
+#define zlibVersion ZLIBVERSION
+#endif
+
+/* Older VAX OpenSSL port defines these as Macros */
+/* Need to include the headers first and then redefine */
+/* that way a newer port will also work if some one has one */
+#ifdef __VAX
+
+#   if (OPENSSL_VERSION_NUMBER < 0x00907001L)
+#       define des_set_odd_parity DES_SET_ODD_PARITY
+#       define des_set_key DES_SET_KEY
+#       define des_ecb_encrypt DES_ECB_ENCRYPT
+
+#   endif
+#   include <openssl/evp.h>
+#   ifndef OpenSSL_add_all_algorithms
+#       define OpenSSL_add_all_algorithms OPENSSL_ADD_ALL_ALGORITHMS
+        void OPENSSL_ADD_ALL_ALGORITHMS(void);
+#   endif
+
+    /* Curl defines these to lower case and VAX needs them in upper case */
+    /* So we need static routines */
+#   if (OPENSSL_VERSION_NUMBER < 0x00907001L)
+
+#       undef des_set_odd_parity
+#       undef DES_set_odd_parity
+#       undef des_set_key
+#       undef DES_set_key
+#       undef des_ecb_encrypt
+#       undef DES_ecb_encrypt
+
+        static void des_set_odd_parity(des_cblock *key) {
+            DES_SET_ODD_PARITY(key);
+        }
+
+        static int des_set_key(const_des_cblock *key,
+                               des_key_schedule schedule) {
+            return DES_SET_KEY(key, schedule);
+        }
+
+        static void des_ecb_encrypt(const_des_cblock *input,
+                                    des_cblock *output,
+                                    des_key_schedule ks, int enc) {
+            DES_ECB_ENCRYPT(input, output, ks, enc);
+        }
+#endif
+/* Need this to stop a macro redefinition error */
+#if OPENSSL_VERSION_NUMBER < 0x00907000L
+#   ifdef X509_STORE_set_flags
+#       undef X509_STORE_set_flags
+#       define X509_STORE_set_flags(x,y) Curl_nop_stmt
+#   endif
+#endif
+#endif
+
+#endif /* HEADER_CURL_SETUP_VMS_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/share.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/share.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/share.c	(revision 164)
@@ -0,0 +1,247 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "share.h"
+#include "vtls/vtls.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+CURLSH *
+curl_share_init(void)
+{
+  struct Curl_share *share = calloc(1, sizeof(struct Curl_share));
+  if(share) {
+    share->specifier |= (1<<CURL_LOCK_DATA_SHARE);
+
+    if(Curl_mk_dnscache(&share->hostcache)) {
+      free(share);
+      return NULL;
+    }
+  }
+
+  return share;
+}
+
+#undef curl_share_setopt
+CURLSHcode
+curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
+{
+  struct Curl_share *share = (struct Curl_share *)sh;
+  va_list param;
+  int type;
+  curl_lock_function lockfunc;
+  curl_unlock_function unlockfunc;
+  void *ptr;
+  CURLSHcode res = CURLSHE_OK;
+
+  if(share->dirty)
+    /* don't allow setting options while one or more handles are already
+       using this share */
+    return CURLSHE_IN_USE;
+
+  va_start(param, option);
+
+  switch(option) {
+  case CURLSHOPT_SHARE:
+    /* this is a type this share will share */
+    type = va_arg(param, int);
+    share->specifier |= (1<<type);
+    switch( type ) {
+    case CURL_LOCK_DATA_DNS:
+      break;
+
+    case CURL_LOCK_DATA_COOKIE:
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+      if(!share->cookies) {
+        share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE );
+        if(!share->cookies)
+          res = CURLSHE_NOMEM;
+      }
+#else   /* CURL_DISABLE_HTTP */
+      res = CURLSHE_NOT_BUILT_IN;
+#endif
+      break;
+
+    case CURL_LOCK_DATA_SSL_SESSION:
+#ifdef USE_SSL
+      if(!share->sslsession) {
+        share->max_ssl_sessions = 8;
+        share->sslsession = calloc(share->max_ssl_sessions,
+                                   sizeof(struct curl_ssl_session));
+        share->sessionage = 0;
+        if(!share->sslsession)
+          res = CURLSHE_NOMEM;
+      }
+#else
+      res = CURLSHE_NOT_BUILT_IN;
+#endif
+      break;
+
+    case CURL_LOCK_DATA_CONNECT:     /* not supported (yet) */
+      break;
+
+    default:
+      res = CURLSHE_BAD_OPTION;
+    }
+    break;
+
+  case CURLSHOPT_UNSHARE:
+    /* this is a type this share will no longer share */
+    type = va_arg(param, int);
+    share->specifier &= ~(1<<type);
+    switch( type ) {
+    case CURL_LOCK_DATA_DNS:
+      break;
+
+    case CURL_LOCK_DATA_COOKIE:
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+      if(share->cookies) {
+        Curl_cookie_cleanup(share->cookies);
+        share->cookies = NULL;
+      }
+#else   /* CURL_DISABLE_HTTP */
+      res = CURLSHE_NOT_BUILT_IN;
+#endif
+      break;
+
+    case CURL_LOCK_DATA_SSL_SESSION:
+#ifdef USE_SSL
+      Curl_safefree(share->sslsession);
+#else
+      res = CURLSHE_NOT_BUILT_IN;
+#endif
+      break;
+
+    case CURL_LOCK_DATA_CONNECT:
+      break;
+
+    default:
+      res = CURLSHE_BAD_OPTION;
+      break;
+    }
+    break;
+
+  case CURLSHOPT_LOCKFUNC:
+    lockfunc = va_arg(param, curl_lock_function);
+    share->lockfunc = lockfunc;
+    break;
+
+  case CURLSHOPT_UNLOCKFUNC:
+    unlockfunc = va_arg(param, curl_unlock_function);
+    share->unlockfunc = unlockfunc;
+    break;
+
+  case CURLSHOPT_USERDATA:
+    ptr = va_arg(param, void *);
+    share->clientdata = ptr;
+    break;
+
+  default:
+    res = CURLSHE_BAD_OPTION;
+    break;
+  }
+
+  va_end(param);
+
+  return res;
+}
+
+CURLSHcode
+curl_share_cleanup(CURLSH *sh)
+{
+  struct Curl_share *share = (struct Curl_share *)sh;
+
+  if(share == NULL)
+    return CURLSHE_INVALID;
+
+  if(share->lockfunc)
+    share->lockfunc(NULL, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE,
+                    share->clientdata);
+
+  if(share->dirty) {
+    if(share->unlockfunc)
+      share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
+    return CURLSHE_IN_USE;
+  }
+
+  Curl_hash_destroy(&share->hostcache);
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+  Curl_cookie_cleanup(share->cookies);
+#endif
+
+#ifdef USE_SSL
+  if(share->sslsession) {
+    size_t i;
+    for(i = 0; i < share->max_ssl_sessions; i++)
+      Curl_ssl_kill_session(&(share->sslsession[i]));
+    free(share->sslsession);
+  }
+#endif
+
+  if(share->unlockfunc)
+    share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
+  free(share);
+
+  return CURLSHE_OK;
+}
+
+
+CURLSHcode
+Curl_share_lock(struct SessionHandle *data, curl_lock_data type,
+                curl_lock_access accesstype)
+{
+  struct Curl_share *share = data->share;
+
+  if(share == NULL)
+    return CURLSHE_INVALID;
+
+  if(share->specifier & (1<<type)) {
+    if(share->lockfunc) /* only call this if set! */
+      share->lockfunc(data, type, accesstype, share->clientdata);
+  }
+  /* else if we don't share this, pretend successful lock */
+
+  return CURLSHE_OK;
+}
+
+CURLSHcode
+Curl_share_unlock(struct SessionHandle *data, curl_lock_data type)
+{
+  struct Curl_share *share = data->share;
+
+  if(share == NULL)
+    return CURLSHE_INVALID;
+
+  if(share->specifier & (1<<type)) {
+    if(share->unlockfunc) /* only call this if set! */
+      share->unlockfunc (data, type, share->clientdata);
+  }
+
+  return CURLSHE_OK;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/share.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/share.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/share.h	(revision 164)
@@ -0,0 +1,61 @@
+#ifndef HEADER_CURL_SHARE_H
+#define HEADER_CURL_SHARE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include <curl/curl.h>
+#include "cookie.h"
+#include "urldata.h"
+
+/* SalfordC says "A structure member may not be volatile". Hence:
+ */
+#ifdef __SALFORDC__
+#define CURL_VOLATILE
+#else
+#define CURL_VOLATILE volatile
+#endif
+
+/* this struct is libcurl-private, don't export details */
+struct Curl_share {
+  unsigned int specifier;
+  CURL_VOLATILE unsigned int dirty;
+
+  curl_lock_function lockfunc;
+  curl_unlock_function unlockfunc;
+  void *clientdata;
+
+  struct curl_hash hostcache;
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+  struct CookieInfo *cookies;
+#endif
+
+  struct curl_ssl_session *sslsession;
+  size_t max_ssl_sessions;
+  long sessionage;
+};
+
+CURLSHcode Curl_share_lock (struct SessionHandle *, curl_lock_data,
+                            curl_lock_access);
+CURLSHcode Curl_share_unlock (struct SessionHandle *, curl_lock_data);
+
+#endif /* HEADER_CURL_SHARE_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/sigpipe.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/sigpipe.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/sigpipe.h	(revision 164)
@@ -0,0 +1,78 @@
+#ifndef HEADER_CURL_SIGPIPE_H
+#define HEADER_CURL_SIGPIPE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && defined(USE_OPENSSL)
+#include <signal.h>
+
+struct sigpipe_ignore {
+  struct sigaction old_pipe_act;
+  bool no_signal;
+};
+
+#define SIGPIPE_VARIABLE(x) struct sigpipe_ignore x
+
+/*
+ * sigpipe_ignore() makes sure we ignore SIGPIPE while running libcurl
+ * internals, and then sigpipe_restore() will restore the situation when we
+ * return from libcurl again.
+ */
+static void sigpipe_ignore(struct SessionHandle *data,
+                           struct sigpipe_ignore *ig)
+{
+  /* get a local copy of no_signal because the SessionHandle might not be
+     around when we restore */
+  ig->no_signal = data->set.no_signal;
+  if(!data->set.no_signal) {
+    struct sigaction action;
+    /* first, extract the existing situation */
+    memset(&ig->old_pipe_act, 0, sizeof(struct sigaction));
+    sigaction(SIGPIPE, NULL, &ig->old_pipe_act);
+    action = ig->old_pipe_act;
+    /* ignore this signal */
+    action.sa_handler = SIG_IGN;
+    sigaction(SIGPIPE, &action, NULL);
+  }
+}
+
+/*
+ * sigpipe_restore() puts back the outside world's opinion of signal handler
+ * and SIGPIPE handling. It MUST only be called after a corresponding
+ * sigpipe_ignore() was used.
+ */
+static void sigpipe_restore(struct sigpipe_ignore *ig)
+{
+  if(!ig->no_signal)
+    /* restore the outside state */
+    sigaction(SIGPIPE, &ig->old_pipe_act, NULL);
+}
+
+#else
+/* for systems without sigaction */
+#define sigpipe_ignore(x,y) Curl_nop_stmt
+#define sigpipe_restore(x)  Curl_nop_stmt
+#define SIGPIPE_VARIABLE(x)
+#endif
+
+#endif /* HEADER_CURL_SIGPIPE_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/slist.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/slist.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/slist.c	(revision 164)
@@ -0,0 +1,143 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "slist.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* returns last node in linked list */
+static struct curl_slist *slist_get_last(struct curl_slist *list)
+{
+  struct curl_slist     *item;
+
+  /* if caller passed us a NULL, return now */
+  if(!list)
+    return NULL;
+
+  /* loop through to find the last item */
+  item = list;
+  while(item->next) {
+    item = item->next;
+  }
+  return item;
+}
+
+/*
+ * Curl_slist_append_nodup() appends a string to the linked list. Rather than
+ * copying the string in dynamic storage, it takes its ownership. The string
+ * should have been malloc()ated. Curl_slist_append_nodup always returns
+ * the address of the first record, so that you can use this function as an
+ * initialization function as well as an append function.
+ * If an error occurs, NULL is returned and the string argument is NOT
+ * released.
+ */
+struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list, char *data)
+{
+  struct curl_slist     *last;
+  struct curl_slist     *new_item;
+
+  DEBUGASSERT(data);
+
+  new_item = malloc(sizeof(struct curl_slist));
+  if(!new_item)
+    return NULL;
+
+  new_item->next = NULL;
+  new_item->data = data;
+
+  /* if this is the first item, then new_item *is* the list */
+  if(!list)
+    return new_item;
+
+  last = slist_get_last(list);
+  last->next = new_item;
+  return list;
+}
+
+/*
+ * curl_slist_append() appends a string to the linked list. It always returns
+ * the address of the first record, so that you can use this function as an
+ * initialization function as well as an append function. If you find this
+ * bothersome, then simply create a separate _init function and call it
+ * appropriately from within the program.
+ */
+struct curl_slist *curl_slist_append(struct curl_slist *list,
+                                     const char *data)
+{
+  char *dupdata = strdup(data);
+
+  if(!dupdata)
+    return NULL;
+
+  list = Curl_slist_append_nodup(list, dupdata);
+  if(!list)
+    free(dupdata);
+
+  return list;
+}
+
+/*
+ * Curl_slist_duplicate() duplicates a linked list. It always returns the
+ * address of the first record of the cloned list or NULL in case of an
+ * error (or if the input list was NULL).
+ */
+struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist)
+{
+  struct curl_slist *outlist = NULL;
+  struct curl_slist *tmp;
+
+  while(inlist) {
+    tmp = curl_slist_append(outlist, inlist->data);
+
+    if(!tmp) {
+      curl_slist_free_all(outlist);
+      return NULL;
+    }
+
+    outlist = tmp;
+    inlist = inlist->next;
+  }
+  return outlist;
+}
+
+/* be nice and clean up resources */
+void curl_slist_free_all(struct curl_slist *list)
+{
+  struct curl_slist     *next;
+  struct curl_slist     *item;
+
+  if(!list)
+    return;
+
+  item = list;
+  do {
+    next = item->next;
+    Curl_safefree(item->data);
+    free(item);
+    item = next;
+  } while(next);
+}
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/slist.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/slist.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/slist.h	(revision 164)
@@ -0,0 +1,40 @@
+#ifndef HEADER_CURL_SLIST_H
+#define HEADER_CURL_SLIST_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Curl_slist_duplicate() duplicates a linked list. It always returns the
+ * address of the first record of the cloned list or NULL in case of an
+ * error (or if the input list was NULL).
+ */
+struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist);
+
+/*
+ * Curl_slist_append_nodup() takes ownership of the given string and appends
+ * it to the list.
+ */
+struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list,
+                                           char *data);
+
+#endif /* HEADER_CURL_SLIST_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/smb.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/smb.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/smb.c	(revision 164)
@@ -0,0 +1,978 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
+ * Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+    (CURL_SIZEOF_CURL_OFF_T > 4)
+
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+#define BUILDING_CURL_SMB_C
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#define getpid _getpid
+#endif
+
+#include "smb.h"
+#include "urldata.h"
+#include "sendf.h"
+#include "multiif.h"
+#include "connect.h"
+#include "progress.h"
+#include "transfer.h"
+#include "vtls/vtls.h"
+#include "curl_ntlm_core.h"
+#include "escape.h"
+#include "curl_endian.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Local API functions */
+static CURLcode smb_setup_connection(struct connectdata *conn);
+static CURLcode smb_connect(struct connectdata *conn, bool *done);
+static CURLcode smb_connection_state(struct connectdata *conn, bool *done);
+static CURLcode smb_request_state(struct connectdata *conn, bool *done);
+static CURLcode smb_done(struct connectdata *conn, CURLcode status,
+                         bool premature);
+static CURLcode smb_disconnect(struct connectdata *conn, bool dead);
+static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
+                       int numsocks);
+static CURLcode smb_parse_url_path(struct connectdata *conn);
+
+/*
+ * SMB handler interface
+ */
+const struct Curl_handler Curl_handler_smb = {
+  "SMB",                                /* scheme */
+  smb_setup_connection,                 /* setup_connection */
+  ZERO_NULL,                            /* do_it */
+  smb_done,                             /* done */
+  ZERO_NULL,                            /* do_more */
+  smb_connect,                          /* connect_it */
+  smb_connection_state,                 /* connecting */
+  smb_request_state,                    /* doing */
+  smb_getsock,                          /* proto_getsock */
+  smb_getsock,                          /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  smb_disconnect,                       /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_SMB,                             /* defport */
+  CURLPROTO_SMB,                        /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * SMBS handler interface
+ */
+const struct Curl_handler Curl_handler_smbs = {
+  "SMBS",                               /* scheme */
+  smb_setup_connection,                 /* setup_connection */
+  ZERO_NULL,                            /* do_it */
+  smb_done,                             /* done */
+  ZERO_NULL,                            /* do_more */
+  smb_connect,                          /* connect_it */
+  smb_connection_state,                 /* connecting */
+  smb_request_state,                    /* doing */
+  smb_getsock,                          /* proto_getsock */
+  smb_getsock,                          /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  smb_disconnect,                       /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_SMBS,                            /* defport */
+  CURLPROTO_SMBS,                       /* protocol */
+  PROTOPT_SSL                           /* flags */
+};
+#endif
+
+#define MAX_PAYLOAD_SIZE  0x8000
+#define MAX_MESSAGE_SIZE  (MAX_PAYLOAD_SIZE + 0x1000)
+#define CLIENTNAME        "curl"
+#define SERVICENAME       "?????"
+
+/* Append a string to an SMB message */
+#define MSGCAT(str) \
+  strcpy(p, (str)); \
+  p += strlen(str);
+
+/* Append a null-terminated string to an SMB message */
+#define MSGCATNULL(str) \
+  strcpy(p, (str)); \
+  p += strlen(str) + 1;
+
+/* SMB is mostly little endian */
+#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
+   defined(__OS400__)
+static unsigned short smb_swap16(unsigned short x)
+{
+  return (unsigned short) ((x << 8) | ((x >> 8) & 0xff));
+}
+
+static unsigned int smb_swap32(unsigned int x)
+{
+  return (x << 24) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) |
+         ((x >> 24) & 0xff);
+}
+
+#ifdef HAVE_LONGLONG
+static unsigned long long smb_swap64(unsigned long long x)
+{
+  return ((unsigned long long) smb_swap32((unsigned int) x) << 32) |
+          smb_swap32((unsigned int) (x >> 32));
+}
+#else
+static unsigned __int64 smb_swap64(unsigned __int64 x)
+{
+  return ((unsigned __int64) smb_swap32((unsigned int) x) << 32) |
+          smb_swap32((unsigned int) (x >> 32));
+}
+#endif
+#else
+#  define smb_swap16(x) (x)
+#  define smb_swap32(x) (x)
+#  define smb_swap64(x) (x)
+#endif
+
+/* SMB request state */
+enum smb_req_state {
+  SMB_REQUESTING,
+  SMB_TREE_CONNECT,
+  SMB_OPEN,
+  SMB_DOWNLOAD,
+  SMB_UPLOAD,
+  SMB_CLOSE,
+  SMB_TREE_DISCONNECT,
+  SMB_DONE
+};
+
+/* SMB request data */
+struct smb_request {
+  enum smb_req_state state;
+  char *share;
+  char *path;
+  unsigned short tid; /* Even if we connect to the same tree as another */
+  unsigned short fid; /* request, the tid will be different */
+  CURLcode result;
+};
+
+static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
+{
+  struct smb_conn *smb = &conn->proto.smbc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* For debug purposes */
+  static const char * const names[] = {
+    "SMB_NOT_CONNECTED",
+    "SMB_CONNECTING",
+    "SMB_NEGOTIATE",
+    "SMB_SETUP",
+    "SMB_CONNECTED",
+    /* LAST */
+  };
+
+  if(smb->state != newstate)
+    infof(conn->data, "SMB conn %p state change from %s to %s\n",
+    (void *)smb, names[smb->state], names[newstate]);
+#endif
+
+  smb->state = newstate;
+}
+
+static void request_state(struct connectdata *conn,
+                          enum smb_req_state newstate)
+{
+  struct smb_request *req = conn->data->req.protop;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* For debug purposes */
+  static const char * const names[] = {
+    "SMB_REQUESTING",
+    "SMB_TREE_CONNECT",
+    "SMB_OPEN",
+    "SMB_DOWNLOAD",
+    "SMB_UPLOAD",
+    "SMB_CLOSE",
+    "SMB_TREE_DISCONNECT",
+    "SMB_DONE",
+    /* LAST */
+  };
+
+  if(req->state != newstate)
+    infof(conn->data, "SMB request %p state change from %s to %s\n",
+    (void *)req, names[req->state], names[newstate]);
+#endif
+
+  req->state = newstate;
+}
+
+static CURLcode smb_setup_connection(struct connectdata *conn)
+{
+  struct smb_request *req;
+
+  /* Initialize the request state */
+  conn->data->req.protop = req = calloc(1, sizeof(struct smb_request));
+  if(!req)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Parse the URL path */
+  return smb_parse_url_path(conn);
+}
+
+static CURLcode smb_connect(struct connectdata *conn, bool *done)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  char *slash;
+
+  (void) done;
+
+  /* Check we have a username and password to authenticate with */
+  if(!conn->bits.user_passwd)
+    return CURLE_LOGIN_DENIED;
+
+  /* Initialize the connection state */
+  memset(smbc, 0, sizeof(*smbc));
+  smbc->state = SMB_CONNECTING;
+  smbc->recv_buf = malloc(MAX_MESSAGE_SIZE);
+  if(!smbc->recv_buf)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Multiple requests are allowed with this connection */
+  connkeep(conn, "SMB default");
+
+  /* Parse the username, domain, and password */
+  slash = strchr(conn->user, '/');
+  if(!slash)
+    slash = strchr(conn->user, '\\');
+
+  if(slash) {
+    smbc->user = slash + 1;
+    smbc->domain = strdup(conn->user);
+    if(!smbc->domain)
+      return CURLE_OUT_OF_MEMORY;
+    smbc->domain[slash - conn->user] = 0;
+  }
+  else {
+    smbc->user = conn->user;
+    smbc->domain = strdup(conn->host.name);
+    if(!smbc->domain)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode smb_recv_message(struct connectdata *conn, void **msg)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  char *buf = smbc->recv_buf;
+  ssize_t bytes_read;
+  size_t nbt_size;
+  size_t msg_size;
+  size_t len = MAX_MESSAGE_SIZE - smbc->got;
+  CURLcode result;
+
+  result = Curl_read(conn, FIRSTSOCKET, buf + smbc->got, len, &bytes_read);
+  if(result)
+    return result;
+
+  if(!bytes_read)
+    return CURLE_OK;
+
+  smbc->got += bytes_read;
+
+  /* Check for a 32-bit nbt header */
+  if(smbc->got < sizeof(unsigned int))
+    return CURLE_OK;
+
+  nbt_size = Curl_read16_be((unsigned char *)(buf + sizeof(unsigned short))) +
+             sizeof(unsigned int);
+  if(smbc->got < nbt_size)
+    return CURLE_OK;
+
+  msg_size = sizeof(struct smb_header);
+  if(nbt_size >= msg_size + 1) {
+    /* Add the word count */
+    msg_size += 1 + ((unsigned char) buf[msg_size]) * sizeof(unsigned short);
+    if(nbt_size >= msg_size + sizeof(unsigned short)) {
+      /* Add the byte count */
+      msg_size += sizeof(unsigned short) +
+                  Curl_read16_le((unsigned char *)&buf[msg_size]);
+      if(nbt_size < msg_size)
+        return CURLE_READ_ERROR;
+    }
+  }
+
+  *msg = buf;
+
+  return CURLE_OK;
+}
+
+static void smb_pop_message(struct connectdata *conn)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+
+  smbc->got = 0;
+}
+
+static void smb_format_message(struct connectdata *conn, struct smb_header *h,
+                               unsigned char cmd, size_t len)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_request *req = conn->data->req.protop;
+  unsigned int pid;
+
+  memset(h, 0, sizeof(*h));
+  h->nbt_length = htons((unsigned short) (sizeof(*h) - sizeof(unsigned int) +
+                                          len));
+  memcpy((char *)h->magic, "\xffSMB", 4);
+  h->command = cmd;
+  h->flags = SMB_FLAGS_CANONICAL_PATHNAMES | SMB_FLAGS_CASELESS_PATHNAMES;
+  h->flags2 = smb_swap16(SMB_FLAGS2_IS_LONG_NAME | SMB_FLAGS2_KNOWS_LONG_NAME);
+  h->uid = smb_swap16(smbc->uid);
+  h->tid = smb_swap16(req->tid);
+  pid = getpid();
+  h->pid_high = smb_swap16((unsigned short)(pid >> 16));
+  h->pid = smb_swap16((unsigned short) pid);
+}
+
+static CURLcode smb_send(struct connectdata *conn, ssize_t len,
+                         size_t upload_size)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  ssize_t bytes_written;
+  CURLcode result;
+
+  result = Curl_write(conn, FIRSTSOCKET, conn->data->state.uploadbuffer,
+                      len, &bytes_written);
+  if(result)
+    return result;
+
+  if(bytes_written != len) {
+    smbc->send_size = len;
+    smbc->sent = bytes_written;
+  }
+
+  smbc->upload_size = upload_size;
+
+  return CURLE_OK;
+}
+
+static CURLcode smb_flush(struct connectdata *conn)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  ssize_t bytes_written;
+  ssize_t len = smbc->send_size - smbc->sent;
+  CURLcode result;
+
+  if(!smbc->send_size)
+    return CURLE_OK;
+
+  result = Curl_write(conn, FIRSTSOCKET,
+                      conn->data->state.uploadbuffer + smbc->sent,
+                      len, &bytes_written);
+  if(result)
+    return result;
+
+  if(bytes_written != len)
+    smbc->sent += bytes_written;
+  else
+    smbc->send_size = 0;
+
+  return CURLE_OK;
+}
+
+static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd,
+                                 const void *msg, size_t msg_len)
+{
+  smb_format_message(conn, (struct smb_header *)conn->data->state.uploadbuffer,
+                     cmd, msg_len);
+  memcpy(conn->data->state.uploadbuffer + sizeof(struct smb_header),
+         msg, msg_len);
+
+  return smb_send(conn, sizeof(struct smb_header) + msg_len, 0);
+}
+
+static CURLcode smb_send_negotiate(struct connectdata *conn)
+{
+  const char *msg = "\x00\x0c\x00\x02NT LM 0.12";
+
+  return smb_send_message(conn, SMB_COM_NEGOTIATE, msg, 15);
+}
+
+static CURLcode smb_send_setup(struct connectdata *conn)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_setup msg;
+  char *p = msg.bytes;
+  unsigned char lm_hash[21];
+  unsigned char lm[24];
+  unsigned char nt_hash[21];
+  unsigned char nt[24];
+
+  size_t byte_count = sizeof(lm) + sizeof(nt);
+  byte_count += strlen(smbc->user) + strlen(smbc->domain);
+  byte_count += strlen(OS) + strlen(CLIENTNAME) + 4; /* 4 null chars */
+  if(byte_count > sizeof(msg.bytes))
+    return CURLE_FILESIZE_EXCEEDED;
+
+  Curl_ntlm_core_mk_lm_hash(conn->data, conn->passwd, lm_hash);
+  Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm);
+#if USE_NTRESPONSES
+  Curl_ntlm_core_mk_nt_hash(conn->data, conn->passwd, nt_hash);
+  Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt);
+#else
+  memset(nt, 0, sizeof(nt));
+#endif
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_SETUP_ANDX;
+  msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+  msg.max_buffer_size = smb_swap16(MAX_MESSAGE_SIZE);
+  msg.max_mpx_count = smb_swap16(1);
+  msg.vc_number = smb_swap16(1);
+  msg.session_key = smb_swap32(smbc->session_key);
+  msg.capabilities = smb_swap32(SMB_CAP_LARGE_FILES);
+  msg.lengths[0] = smb_swap16(sizeof(lm));
+  msg.lengths[1] = smb_swap16(sizeof(nt));
+  memcpy(p, lm, sizeof(lm));
+  p += sizeof(lm);
+  memcpy(p, nt, sizeof(nt));
+  p += sizeof(nt);
+  MSGCATNULL(smbc->user);
+  MSGCATNULL(smbc->domain);
+  MSGCATNULL(OS);
+  MSGCATNULL(CLIENTNAME);
+  byte_count = p - msg.bytes;
+  msg.byte_count = smb_swap16((unsigned short)byte_count);
+
+  return smb_send_message(conn, SMB_COM_SETUP_ANDX, &msg,
+                          sizeof(msg) - sizeof(msg.bytes) + byte_count);
+}
+
+static CURLcode smb_send_tree_connect(struct connectdata *conn)
+{
+  struct smb_request *req = conn->data->req.protop;
+  struct smb_tree_connect msg;
+  char *p = msg.bytes;
+
+  size_t byte_count = strlen(conn->host.name) + strlen(req->share);
+  byte_count += strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */
+  if(byte_count > sizeof(msg.bytes))
+    return CURLE_FILESIZE_EXCEEDED;
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_TREE_CONNECT_ANDX;
+  msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+  msg.pw_len = 0;
+  MSGCAT("\\\\");
+  MSGCAT(conn->host.name);
+  MSGCAT("\\");
+  MSGCATNULL(req->share);
+  MSGCATNULL(SERVICENAME); /* Match any type of service */
+  byte_count = p - msg.bytes;
+  msg.byte_count = smb_swap16((unsigned short)byte_count);
+
+  return smb_send_message(conn, SMB_COM_TREE_CONNECT_ANDX, &msg,
+                          sizeof(msg) - sizeof(msg.bytes) + byte_count);
+}
+
+static CURLcode smb_send_open(struct connectdata *conn)
+{
+  struct smb_request *req = conn->data->req.protop;
+  struct smb_nt_create msg;
+  size_t byte_count;
+
+  if((strlen(req->path) + 1) > sizeof(msg.bytes))
+    return CURLE_FILESIZE_EXCEEDED;
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_NT_CREATE_ANDX;
+  msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+  byte_count = strlen(req->path);
+  msg.name_length = smb_swap16((unsigned short)byte_count);
+  msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL);
+  if(conn->data->set.upload) {
+    msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE);
+    msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF);
+  }
+  else {
+    msg.access = smb_swap32(SMB_GENERIC_READ);
+    msg.create_disposition = smb_swap32(SMB_FILE_OPEN);
+  }
+  msg.byte_count = smb_swap16((unsigned short) ++byte_count);
+  strcpy(msg.bytes, req->path);
+
+  return smb_send_message(conn, SMB_COM_NT_CREATE_ANDX, &msg,
+                          sizeof(msg) - sizeof(msg.bytes) + byte_count);
+}
+
+static CURLcode smb_send_close(struct connectdata *conn)
+{
+  struct smb_request *req = conn->data->req.protop;
+  struct smb_close msg;
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_CLOSE;
+  msg.fid = smb_swap16(req->fid);
+
+  return smb_send_message(conn, SMB_COM_CLOSE, &msg, sizeof(msg));
+}
+
+static CURLcode smb_send_tree_disconnect(struct connectdata *conn)
+{
+  struct smb_tree_disconnect msg;
+
+  memset(&msg, 0, sizeof(msg));
+
+  return smb_send_message(conn, SMB_COM_TREE_DISCONNECT, &msg, sizeof(msg));
+}
+
+static CURLcode smb_send_read(struct connectdata *conn)
+{
+  struct smb_request *req = conn->data->req.protop;
+  curl_off_t offset = conn->data->req.offset;
+  struct smb_read msg;
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_READ_ANDX;
+  msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+  msg.fid = smb_swap16(req->fid);
+  msg.offset = smb_swap32((unsigned int) offset);
+  msg.offset_high = smb_swap32((unsigned int) (offset >> 32));
+  msg.min_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
+  msg.max_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
+
+  return smb_send_message(conn, SMB_COM_READ_ANDX, &msg, sizeof(msg));
+}
+
+static CURLcode smb_send_write(struct connectdata *conn)
+{
+  struct smb_write *msg = (struct smb_write *)conn->data->state.uploadbuffer;
+  struct smb_request *req = conn->data->req.protop;
+  curl_off_t offset = conn->data->req.offset;
+
+  curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount;
+  if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */
+    upload_size = MAX_PAYLOAD_SIZE - 1;
+
+  memset(msg, 0, sizeof(*msg));
+  msg->word_count = SMB_WC_WRITE_ANDX;
+  msg->andx.command = SMB_COM_NO_ANDX_COMMAND;
+  msg->fid = smb_swap16(req->fid);
+  msg->offset = smb_swap32((unsigned int) offset);
+  msg->offset_high = smb_swap32((unsigned int) (offset >> 32));
+  msg->data_length = smb_swap16((unsigned short) upload_size);
+  msg->data_offset = smb_swap16(sizeof(*msg) - sizeof(unsigned int));
+  msg->byte_count = smb_swap16((unsigned short) (upload_size + 1));
+
+  smb_format_message(conn, &msg->h, SMB_COM_WRITE_ANDX,
+                     sizeof(*msg) - sizeof(msg->h) + (size_t) upload_size);
+
+  return smb_send(conn, sizeof(*msg), (size_t) upload_size);
+}
+
+static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  CURLcode result;
+
+  /* Check if there is data in the transfer buffer */
+  if(!smbc->send_size && smbc->upload_size) {
+    int nread = smbc->upload_size > BUFSIZE ? BUFSIZE :
+                                              (int) smbc->upload_size;
+    conn->data->req.upload_fromhere = conn->data->state.uploadbuffer;
+    result = Curl_fillreadbuffer(conn, nread, &nread);
+    if(result && result != CURLE_AGAIN)
+      return result;
+    if(!nread)
+      return CURLE_OK;
+
+    smbc->upload_size -= nread;
+    smbc->send_size = nread;
+    smbc->sent = 0;
+  }
+
+  /* Check if there is data to send */
+  if(smbc->send_size) {
+    result = smb_flush(conn);
+    if(result)
+      return result;
+  }
+
+  /* Check if there is still data to be sent */
+  if(smbc->send_size || smbc->upload_size)
+    return CURLE_AGAIN;
+
+  return smb_recv_message(conn, msg);
+}
+
+static CURLcode smb_connection_state(struct connectdata *conn, bool *done)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_negotiate_response *nrsp;
+  struct smb_header *h;
+  CURLcode result;
+  void *msg = NULL;
+
+  if(smbc->state == SMB_CONNECTING) {
+#ifdef USE_SSL
+    if((conn->handler->flags & PROTOPT_SSL)) {
+      bool ssl_done;
+      result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &ssl_done);
+      if(result && result != CURLE_AGAIN)
+        return result;
+      if(!ssl_done)
+        return CURLE_OK;
+    }
+#endif
+
+    result = smb_send_negotiate(conn);
+    if(result) {
+      connclose(conn, "SMB: failed to send negotiate message");
+      return result;
+    }
+
+    conn_state(conn, SMB_NEGOTIATE);
+  }
+
+  /* Send the previous message and check for a response */
+  result = smb_send_and_recv(conn, &msg);
+  if(result && result != CURLE_AGAIN) {
+    connclose(conn, "SMB: failed to communicate");
+    return result;
+  }
+
+  if(!msg)
+    return CURLE_OK;
+
+  h = msg;
+
+  switch(smbc->state) {
+  case SMB_NEGOTIATE:
+    if(h->status) {
+      connclose(conn, "SMB: negotiation failed");
+      return CURLE_COULDNT_CONNECT;
+    }
+    nrsp = msg;
+    memcpy(smbc->challenge, nrsp->bytes, sizeof(smbc->challenge));
+    smbc->session_key = smb_swap32(nrsp->session_key);
+    result = smb_send_setup(conn);
+    if(result) {
+      connclose(conn, "SMB: failed to send setup message");
+      return result;
+    }
+    conn_state(conn, SMB_SETUP);
+    break;
+
+  case SMB_SETUP:
+    if(h->status) {
+      connclose(conn, "SMB: authentication failed");
+      return CURLE_LOGIN_DENIED;
+    }
+    smbc->uid = smb_swap16(h->uid);
+    conn_state(conn, SMB_CONNECTED);
+    *done = true;
+    break;
+
+  default:
+    smb_pop_message(conn);
+    return CURLE_OK; /* ignore */
+  }
+
+  smb_pop_message(conn);
+
+  return CURLE_OK;
+}
+
+static CURLcode smb_request_state(struct connectdata *conn, bool *done)
+{
+  struct smb_request *req = conn->data->req.protop;
+  struct smb_header *h;
+  enum smb_req_state next_state = SMB_DONE;
+  unsigned short len;
+  unsigned short off;
+  CURLcode result;
+  void *msg = NULL;
+
+  /* Start the request */
+  if(req->state == SMB_REQUESTING) {
+    result = smb_send_tree_connect(conn);
+    if(result) {
+      connclose(conn, "SMB: failed to send tree connect message");
+      return result;
+    }
+
+    request_state(conn, SMB_TREE_CONNECT);
+  }
+
+  /* Send the previous message and check for a response */
+  result = smb_send_and_recv(conn, &msg);
+  if(result && result != CURLE_AGAIN) {
+    connclose(conn, "SMB: failed to communicate");
+    return result;
+  }
+
+  if(!msg)
+    return CURLE_OK;
+
+  h = msg;
+
+  switch(req->state) {
+  case SMB_TREE_CONNECT:
+    if(h->status) {
+      req->result = CURLE_REMOTE_FILE_NOT_FOUND;
+      if(h->status == smb_swap32(SMB_ERR_NOACCESS))
+        req->result = CURLE_REMOTE_ACCESS_DENIED;
+      break;
+    }
+    req->tid = smb_swap16(h->tid);
+    next_state = SMB_OPEN;
+    break;
+
+  case SMB_OPEN:
+    if(h->status) {
+      req->result = CURLE_REMOTE_FILE_NOT_FOUND;
+      next_state = SMB_TREE_DISCONNECT;
+      break;
+    }
+    req->fid = smb_swap16(((struct smb_nt_create_response *)msg)->fid);
+    conn->data->req.offset = 0;
+    if(conn->data->set.upload) {
+      conn->data->req.size = conn->data->state.infilesize;
+      Curl_pgrsSetUploadSize(conn->data, conn->data->req.size);
+      next_state = SMB_UPLOAD;
+    }
+    else {
+      conn->data->req.size =
+        smb_swap64(((struct smb_nt_create_response *)msg)->end_of_file);
+      Curl_pgrsSetDownloadSize(conn->data, conn->data->req.size);
+      next_state = SMB_DOWNLOAD;
+    }
+    break;
+
+  case SMB_DOWNLOAD:
+    if(h->status) {
+      req->result = CURLE_RECV_ERROR;
+      next_state = SMB_CLOSE;
+      break;
+    }
+    len = Curl_read16_le(((unsigned char *) msg) +
+                         sizeof(struct smb_header) + 11);
+    off = Curl_read16_le(((unsigned char *) msg) +
+                         sizeof(struct smb_header) + 13);
+    if(len > 0) {
+      struct smb_conn *smbc = &conn->proto.smbc;
+      if(off + sizeof(unsigned int) + len > smbc->got) {
+        failf(conn->data, "Invalid input packet");
+        result = CURLE_RECV_ERROR;
+      }
+      else
+        result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                   (char *)msg + off + sizeof(unsigned int),
+                                   len);
+      if(result) {
+        req->result = result;
+        next_state = SMB_CLOSE;
+        break;
+      }
+    }
+    conn->data->req.bytecount += len;
+    conn->data->req.offset += len;
+    Curl_pgrsSetDownloadCounter(conn->data, conn->data->req.bytecount);
+    next_state = (len < MAX_PAYLOAD_SIZE) ? SMB_CLOSE : SMB_DOWNLOAD;
+    break;
+
+  case SMB_UPLOAD:
+    if(h->status) {
+      req->result = CURLE_UPLOAD_FAILED;
+      next_state = SMB_CLOSE;
+      break;
+    }
+    len = Curl_read16_le(((unsigned char *) msg) +
+                         sizeof(struct smb_header) + 5);
+    conn->data->req.bytecount += len;
+    conn->data->req.offset += len;
+    Curl_pgrsSetUploadCounter(conn->data, conn->data->req.bytecount);
+    if(conn->data->req.bytecount >= conn->data->req.size)
+      next_state = SMB_CLOSE;
+    else
+      next_state = SMB_UPLOAD;
+    break;
+
+  case SMB_CLOSE:
+    /* We don't care if the close failed, proceed to tree disconnect anyway */
+    next_state = SMB_TREE_DISCONNECT;
+    break;
+
+  case SMB_TREE_DISCONNECT:
+    next_state = SMB_DONE;
+    break;
+
+  default:
+    smb_pop_message(conn);
+    return CURLE_OK; /* ignore */
+  }
+
+  smb_pop_message(conn);
+
+  switch(next_state) {
+  case SMB_OPEN:
+    result = smb_send_open(conn);
+    break;
+
+  case SMB_DOWNLOAD:
+    result = smb_send_read(conn);
+    break;
+
+  case SMB_UPLOAD:
+    result = smb_send_write(conn);
+    break;
+
+  case SMB_CLOSE:
+    result = smb_send_close(conn);
+    break;
+
+  case SMB_TREE_DISCONNECT:
+    result = smb_send_tree_disconnect(conn);
+    break;
+
+  case SMB_DONE:
+    result = req->result;
+    *done = true;
+    break;
+
+  default:
+    break;
+  }
+
+  if(result) {
+    connclose(conn, "SMB: failed to send message");
+    return result;
+  }
+
+  request_state(conn, next_state);
+
+  return CURLE_OK;
+}
+
+static CURLcode smb_done(struct connectdata *conn, CURLcode status,
+                         bool premature)
+{
+  struct smb_request *req = conn->data->req.protop;
+
+  (void) premature;
+
+  Curl_safefree(req->share);
+  Curl_safefree(conn->data->req.protop);
+
+  return status;
+}
+
+static CURLcode smb_disconnect(struct connectdata *conn, bool dead)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_request *req = conn->data->req.protop;
+
+  (void) dead;
+
+  Curl_safefree(smbc->domain);
+  Curl_safefree(smbc->recv_buf);
+
+  /* smb_done is not always called, so cleanup the request */
+  if(req) {
+    Curl_safefree(req->share);
+    Curl_safefree(conn->data->req.protop);
+  }
+
+  return CURLE_OK;
+}
+
+static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
+                       int numsocks)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  socks[0] = conn->sock[FIRSTSOCKET];
+
+  if(smbc->send_size || smbc->upload_size)
+    return GETSOCK_WRITESOCK(0);
+
+  return GETSOCK_READSOCK(0);
+}
+
+static CURLcode smb_parse_url_path(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct smb_request *req = data->req.protop;
+  char *path;
+  char *slash;
+
+  /* URL decode the path */
+  result = Curl_urldecode(data, data->state.path, 0, &path, NULL, TRUE);
+  if(result)
+    return result;
+
+  /* Parse the path for the share */
+  req->share = strdup((*path == '/' || *path == '\\') ? path + 1 : path);
+  if(!req->share) {
+    free(path);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  slash = strchr(req->share, '/');
+  if(!slash)
+    slash = strchr(req->share, '\\');
+
+  /* The share must be present */
+  if(!slash) {
+    free(path);
+
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /* Parse the path for the file path converting any forward slashes into
+     backslashes */
+  *slash++ = 0;
+  req->path = slash;
+  for(; *slash; slash++) {
+    if(*slash == '/')
+      *slash = '\\';
+  }
+
+  free(path);
+
+  return CURLE_OK;
+}
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/smb.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/smb.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/smb.h	(revision 164)
@@ -0,0 +1,271 @@
+#ifndef HEADER_CURL_SMB_H
+#define HEADER_CURL_SMB_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+enum smb_conn_state {
+  SMB_NOT_CONNECTED = 0,
+  SMB_CONNECTING,
+  SMB_NEGOTIATE,
+  SMB_SETUP,
+  SMB_CONNECTED
+};
+
+struct smb_conn {
+  enum smb_conn_state state;
+  char *user;
+  char *domain;
+  unsigned char challenge[8];
+  unsigned int session_key;
+  unsigned short uid;
+  char *recv_buf;
+  size_t upload_size;
+  size_t send_size;
+  size_t sent;
+  size_t got;
+};
+
+/*
+ * Definitions for SMB protocol data structures
+ */
+#ifdef BUILDING_CURL_SMB_C
+
+#if defined(_MSC_VER) || defined(__ILEC400__)
+#  define PACK
+#  pragma pack(push)
+#  pragma pack(1)
+#elif defined(__GNUC__)
+#  define PACK __attribute__((packed))
+#else
+#  define PACK
+#endif
+
+#define SMB_COM_CLOSE                 0x04
+#define SMB_COM_READ_ANDX             0x2e
+#define SMB_COM_WRITE_ANDX            0x2f
+#define SMB_COM_TREE_DISCONNECT       0x71
+#define SMB_COM_NEGOTIATE             0x72
+#define SMB_COM_SETUP_ANDX            0x73
+#define SMB_COM_TREE_CONNECT_ANDX     0x75
+#define SMB_COM_NT_CREATE_ANDX        0xa2
+#define SMB_COM_NO_ANDX_COMMAND       0xff
+
+#define SMB_WC_CLOSE                  0x03
+#define SMB_WC_READ_ANDX              0x0c
+#define SMB_WC_WRITE_ANDX             0x0e
+#define SMB_WC_SETUP_ANDX             0x0d
+#define SMB_WC_TREE_CONNECT_ANDX      0x04
+#define SMB_WC_NT_CREATE_ANDX         0x18
+
+#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10
+#define SMB_FLAGS_CASELESS_PATHNAMES  0x08
+#define SMB_FLAGS2_UNICODE_STRINGS    0x8000
+#define SMB_FLAGS2_IS_LONG_NAME       0x0040
+#define SMB_FLAGS2_KNOWS_LONG_NAME    0x0001
+
+#define SMB_CAP_LARGE_FILES           0x08
+#define SMB_GENERIC_WRITE             0x40000000
+#define SMB_GENERIC_READ              0x80000000
+#define SMB_FILE_SHARE_ALL            0x07
+#define SMB_FILE_OPEN                 0x01
+#define SMB_FILE_OVERWRITE_IF         0x05
+
+#define SMB_ERR_NOACCESS              0x00050001
+
+struct smb_header {
+  unsigned char nbt_type;
+  unsigned char nbt_flags;
+  unsigned short nbt_length;
+  unsigned char magic[4];
+  unsigned char command;
+  unsigned int status;
+  unsigned char flags;
+  unsigned short flags2;
+  unsigned short pid_high;
+  unsigned char signature[8];
+  unsigned short pad;
+  unsigned short tid;
+  unsigned short pid;
+  unsigned short uid;
+  unsigned short mid;
+} PACK;
+
+struct smb_negotiate_response {
+  struct smb_header h;
+  unsigned char word_count;
+  unsigned short dialect_index;
+  unsigned char security_mode;
+  unsigned short max_mpx_count;
+  unsigned short max_number_vcs;
+  unsigned int max_buffer_size;
+  unsigned int max_raw_size;
+  unsigned int session_key;
+  unsigned int capabilities;
+  unsigned int system_time_low;
+  unsigned int system_time_high;
+  unsigned short server_time_zone;
+  unsigned char encryption_key_length;
+  unsigned short byte_count;
+  char bytes[1];
+} PACK;
+
+struct andx {
+  unsigned char command;
+  unsigned char pad;
+  unsigned short offset;
+} PACK;
+
+struct smb_setup {
+  unsigned char word_count;
+  struct andx andx;
+  unsigned short max_buffer_size;
+  unsigned short max_mpx_count;
+  unsigned short vc_number;
+  unsigned int session_key;
+  unsigned short lengths[2];
+  unsigned int pad;
+  unsigned int capabilities;
+  unsigned short byte_count;
+  char bytes[1024];
+} PACK;
+
+struct smb_tree_connect {
+  unsigned char word_count;
+  struct andx andx;
+  unsigned short flags;
+  unsigned short pw_len;
+  unsigned short byte_count;
+  char bytes[1024];
+} PACK;
+
+struct smb_nt_create {
+  unsigned char word_count;
+  struct andx andx;
+  unsigned char pad;
+  unsigned short name_length;
+  unsigned int flags;
+  unsigned int root_fid;
+  unsigned int access;
+#ifdef HAVE_LONGLONG
+  unsigned long long allocation_size;
+#else
+  unsigned __int64 allocation_size;
+#endif
+  unsigned int ext_file_attributes;
+  unsigned int share_access;
+  unsigned int create_disposition;
+  unsigned int create_options;
+  unsigned int impersonation_level;
+  unsigned char security_flags;
+  unsigned short byte_count;
+  char bytes[1024];
+} PACK;
+
+struct smb_nt_create_response {
+  struct smb_header h;
+  unsigned char word_count;
+  struct andx andx;
+  unsigned char op_lock_level;
+  unsigned short fid;
+  unsigned int create_disposition;
+#ifdef HAVE_LONGLONG
+  unsigned long long create_time;
+  unsigned long long last_access_time;
+  unsigned long long last_write_time;
+  unsigned long long last_change_time;
+#else
+  unsigned __int64 create_time;
+  unsigned __int64 last_access_time;
+  unsigned __int64 last_write_time;
+  unsigned __int64 last_change_time;
+#endif
+  unsigned int ext_file_attributes;
+#ifdef HAVE_LONGLONG
+  unsigned long long allocation_size;
+  unsigned long long end_of_file;
+#else
+  unsigned __int64 allocation_size;
+  unsigned __int64 end_of_file;
+#endif
+} PACK;
+
+struct smb_read {
+  unsigned char word_count;
+  struct andx andx;
+  unsigned short fid;
+  unsigned int offset;
+  unsigned short max_bytes;
+  unsigned short min_bytes;
+  unsigned int timeout;
+  unsigned short remaining;
+  unsigned int offset_high;
+  unsigned short byte_count;
+} PACK;
+
+struct smb_write {
+  struct smb_header h;
+  unsigned char word_count;
+  struct andx andx;
+  unsigned short fid;
+  unsigned int offset;
+  unsigned int timeout;
+  unsigned short write_mode;
+  unsigned short remaining;
+  unsigned short pad;
+  unsigned short data_length;
+  unsigned short data_offset;
+  unsigned int offset_high;
+  unsigned short byte_count;
+  unsigned char pad2;
+} PACK;
+
+struct smb_close {
+  unsigned char word_count;
+  unsigned short fid;
+  unsigned int last_mtime;
+  unsigned short byte_count;
+} PACK;
+
+struct smb_tree_disconnect {
+  unsigned char word_count;
+  unsigned short byte_count;
+} PACK;
+
+#if defined(_MSC_VER) || defined(__ILEC400__)
+#  pragma pack(pop)
+#endif
+
+#endif /* BUILDING_CURL_SMB_C */
+
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+    (CURL_SIZEOF_CURL_OFF_T > 4)
+
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+extern const struct Curl_handler Curl_handler_smb;
+extern const struct Curl_handler Curl_handler_smbs;
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */
+
+#endif /* HEADER_CURL_SMB_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/smtp.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/smtp.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/smtp.c	(revision 164)
@@ -0,0 +1,1671 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC1870 SMTP Service Extension for Message Size
+ * RFC2195 CRAM-MD5 authentication
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC3207 SMTP over TLS
+ * RFC4422 Simple Authentication and Security Layer (SASL)
+ * RFC4616 PLAIN authentication
+ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
+ * RFC4954 SMTP Authentication
+ * RFC5321 SMTP protocol
+ * RFC6749 OAuth 2.0 Authorization Framework
+ * Draft   SMTP URL Interface   <draft-earhart-url-smtp-00.txt>
+ * Draft   LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_SMTP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "socks.h"
+#include "smtp.h"
+
+#include "strtoofft.h"
+#include "strequal.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "select.h"
+#include "multiif.h"
+#include "url.h"
+#include "rawstr.h"
+#include "curl_gethostname.h"
+#include "curl_sasl.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* Local API functions */
+static CURLcode smtp_regular_transfer(struct connectdata *conn, bool *done);
+static CURLcode smtp_do(struct connectdata *conn, bool *done);
+static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
+                          bool premature);
+static CURLcode smtp_connect(struct connectdata *conn, bool *done);
+static CURLcode smtp_disconnect(struct connectdata *conn, bool dead);
+static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done);
+static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks);
+static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done);
+static CURLcode smtp_setup_connection(struct connectdata *conn);
+static CURLcode smtp_parse_url_options(struct connectdata *conn);
+static CURLcode smtp_parse_url_path(struct connectdata *conn);
+static CURLcode smtp_parse_custom_request(struct connectdata *conn);
+static CURLcode smtp_perform_auth(struct connectdata *conn, const char *mech,
+                                  const char *initresp);
+static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp);
+static void smtp_get_message(char *buffer, char** outptr);
+
+/*
+ * SMTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_smtp = {
+  "SMTP",                           /* scheme */
+  smtp_setup_connection,            /* setup_connection */
+  smtp_do,                          /* do_it */
+  smtp_done,                        /* done */
+  ZERO_NULL,                        /* do_more */
+  smtp_connect,                     /* connect_it */
+  smtp_multi_statemach,             /* connecting */
+  smtp_doing,                       /* doing */
+  smtp_getsock,                     /* proto_getsock */
+  smtp_getsock,                     /* doing_getsock */
+  ZERO_NULL,                        /* domore_getsock */
+  ZERO_NULL,                        /* perform_getsock */
+  smtp_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
+  PORT_SMTP,                        /* defport */
+  CURLPROTO_SMTP,                   /* protocol */
+  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * SMTPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_smtps = {
+  "SMTPS",                          /* scheme */
+  smtp_setup_connection,            /* setup_connection */
+  smtp_do,                          /* do_it */
+  smtp_done,                        /* done */
+  ZERO_NULL,                        /* do_more */
+  smtp_connect,                     /* connect_it */
+  smtp_multi_statemach,             /* connecting */
+  smtp_doing,                       /* doing */
+  smtp_getsock,                     /* proto_getsock */
+  smtp_getsock,                     /* doing_getsock */
+  ZERO_NULL,                        /* domore_getsock */
+  ZERO_NULL,                        /* perform_getsock */
+  smtp_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
+  PORT_SMTPS,                       /* defport */
+  CURLPROTO_SMTPS,                  /* protocol */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL
+  | PROTOPT_NOURLQUERY              /* flags */
+};
+#endif
+
+#ifndef CURL_DISABLE_HTTP
+/*
+ * HTTP-proxyed SMTP protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_smtp_proxy = {
+  "SMTP",                               /* scheme */
+  Curl_http_setup_conn,                 /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_SMTP,                            /* defport */
+  CURLPROTO_HTTP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * HTTP-proxyed SMTPS protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_smtps_proxy = {
+  "SMTPS",                              /* scheme */
+  Curl_http_setup_conn,                 /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_SMTPS,                           /* defport */
+  CURLPROTO_HTTP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+#endif
+#endif
+
+/* SASL parameters for the smtp protocol */
+static const struct SASLproto saslsmtp = {
+  "smtp",                     /* The service name */
+  334,                        /* Code received when continuation is expected */
+  235,                        /* Code to receive upon authentication success */
+  512 - 8,                    /* Maximum initial response length (no max) */
+  smtp_perform_auth,          /* Send authentication command */
+  smtp_continue_auth,         /* Send authentication continuation */
+  smtp_get_message            /* Get SASL response message */
+};
+
+#ifdef USE_SSL
+static void smtp_to_smtps(struct connectdata *conn)
+{
+  conn->handler = &Curl_handler_smtps;
+}
+#else
+#define smtp_to_smtps(x) Curl_nop_stmt
+#endif
+
+/***********************************************************************
+ *
+ * smtp_endofresp()
+ *
+ * Checks for an ending SMTP status code at the start of the given string, but
+ * also detects various capabilities from the EHLO response including the
+ * supported authentication mechanisms.
+ */
+static bool smtp_endofresp(struct connectdata *conn, char *line, size_t len,
+                           int *resp)
+{
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  bool result = FALSE;
+
+  /* Nothing for us */
+  if(len < 4 || !ISDIGIT(line[0]) || !ISDIGIT(line[1]) || !ISDIGIT(line[2]))
+    return FALSE;
+
+  /* Do we have a command response? This should be the response code followed
+     by a space and optionally some text as per RFC-5321 and as outlined in
+     Section 4. Examples of RFC-4954 but some e-mail servers ignore this and
+     only send the response code instead as per Section 4.2. */
+  if(line[3] == ' ' || len == 5) {
+    result = TRUE;
+    *resp = curlx_sltosi(strtol(line, NULL, 10));
+
+    /* Make sure real server never sends internal value */
+    if(*resp == 1)
+      *resp = 0;
+  }
+  /* Do we have a multiline (continuation) response? */
+  else if(line[3] == '-' &&
+          (smtpc->state == SMTP_EHLO || smtpc->state == SMTP_COMMAND)) {
+    result = TRUE;
+    *resp = 1;  /* Internal response code */
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_get_message()
+ *
+ * Gets the authentication message from the response buffer.
+ */
+static void smtp_get_message(char *buffer, char** outptr)
+{
+  size_t len = 0;
+  char* message = NULL;
+
+  /* Find the start of the message */
+  for(message = buffer + 4; *message == ' ' || *message == '\t'; message++)
+    ;
+
+  /* Find the end of the message */
+  for(len = strlen(message); len--;)
+    if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' &&
+        message[len] != '\t')
+      break;
+
+  /* Terminate the message */
+  if(++len) {
+    message[len] = '\0';
+  }
+
+  *outptr = message;
+}
+
+/***********************************************************************
+ *
+ * state()
+ *
+ * This is the ONLY way to change SMTP state!
+ */
+static void state(struct connectdata *conn, smtpstate newstate)
+{
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[] = {
+    "STOP",
+    "SERVERGREET",
+    "EHLO",
+    "HELO",
+    "STARTTLS",
+    "UPGRADETLS",
+    "AUTH",
+    "COMMAND",
+    "MAIL",
+    "RCPT",
+    "DATA",
+    "POSTDATA",
+    "QUIT",
+    /* LAST */
+  };
+
+  if(smtpc->state != newstate)
+    infof(conn->data, "SMTP %p state change from %s to %s\n",
+          (void *)smtpc, names[smtpc->state], names[newstate]);
+#endif
+
+  smtpc->state = newstate;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_ehlo()
+ *
+ * Sends the EHLO command to not only initialise communication with the ESMTP
+ * server but to also obtain a list of server side supported capabilities.
+ */
+static CURLcode smtp_perform_ehlo(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  smtpc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanism yet */
+  smtpc->sasl.authused = SASL_AUTH_NONE;  /* Clear the authentication mechanism
+                                             used for esmtp connections */
+  smtpc->tls_supported = FALSE;           /* Clear the TLS capability */
+  smtpc->auth_supported = FALSE;          /* Clear the AUTH capability */
+
+  /* Send the EHLO command */
+  result = Curl_pp_sendf(&smtpc->pp, "EHLO %s", smtpc->domain);
+
+  if(!result)
+    state(conn, SMTP_EHLO);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_helo()
+ *
+ * Sends the HELO command to initialise communication with the SMTP server.
+ */
+static CURLcode smtp_perform_helo(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  smtpc->sasl.authused = SASL_AUTH_NONE; /* No authentication mechanism used
+                                            in smtp connections */
+
+  /* Send the HELO command */
+  result = Curl_pp_sendf(&smtpc->pp, "HELO %s", smtpc->domain);
+
+  if(!result)
+    state(conn, SMTP_HELO);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_starttls()
+ *
+ * Sends the STLS command to start the upgrade to TLS.
+ */
+static CURLcode smtp_perform_starttls(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Send the STARTTLS command */
+  result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "STARTTLS");
+
+  if(!result)
+    state(conn, SMTP_STARTTLS);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_upgrade_tls()
+ *
+ * Performs the upgrade to TLS.
+ */
+static CURLcode smtp_perform_upgrade_tls(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  /* Start the SSL connection */
+  result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone);
+
+  if(!result) {
+    if(smtpc->state != SMTP_UPGRADETLS)
+      state(conn, SMTP_UPGRADETLS);
+
+    if(smtpc->ssldone) {
+      smtp_to_smtps(conn);
+      result = smtp_perform_ehlo(conn);
+    }
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_auth()
+ *
+ * Sends an AUTH command allowing the client to login with the given SASL
+ * authentication mechanism.
+ */
+static CURLcode smtp_perform_auth(struct connectdata *conn,
+                                  const char *mech,
+                                  const char *initresp)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  if(initresp) {                                  /* AUTH <mech> ...<crlf> */
+    /* Send the AUTH command with the initial response */
+    result = Curl_pp_sendf(&smtpc->pp, "AUTH %s %s", mech, initresp);
+  }
+  else {
+    /* Send the AUTH command */
+    result = Curl_pp_sendf(&smtpc->pp, "AUTH %s", mech);
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_continue_auth()
+ *
+ * Sends SASL continuation data or cancellation.
+ */
+static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp)
+{
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  return Curl_pp_sendf(&smtpc->pp, "%s", resp);
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_authentication()
+ *
+ * Initiates the authentication sequence, with the appropriate SASL
+ * authentication mechanism.
+ */
+static CURLcode smtp_perform_authentication(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  saslprogress progress;
+
+  /* Check we have enough data to authenticate with, and the
+     server supports authentiation, and end the connect phase if not */
+  if(!smtpc->auth_supported ||
+      !Curl_sasl_can_authenticate(&smtpc->sasl, conn)) {
+    state(conn, SMTP_STOP);
+    return result;
+  }
+
+  /* Calculate the SASL login details */
+  result = Curl_sasl_start(&smtpc->sasl, conn, FALSE, &progress);
+
+  if(!result) {
+    if(progress == SASL_INPROGRESS)
+      state(conn, SMTP_AUTH);
+    else {
+      /* Other mechanisms not supported */
+      infof(conn->data, "No known authentication mechanisms supported!\n");
+      result = CURLE_LOGIN_DENIED;
+    }
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_command()
+ *
+ * Sends a SMTP based command.
+ */
+static CURLcode smtp_perform_command(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+
+  /* Send the command */
+  if(smtp->rcpt)
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s %s",
+                            smtp->custom && smtp->custom[0] != '\0' ?
+                            smtp->custom : "VRFY",
+                            smtp->rcpt->data);
+  else
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s",
+                           smtp->custom && smtp->custom[0] != '\0' ?
+                           smtp->custom : "HELP");
+
+  if(!result)
+    state(conn, SMTP_COMMAND);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_mail()
+ *
+ * Sends an MAIL command to initiate the upload of a message.
+ */
+static CURLcode smtp_perform_mail(struct connectdata *conn)
+{
+  char *from = NULL;
+  char *auth = NULL;
+  char *size = NULL;
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  /* Calculate the FROM parameter */
+  if(!data->set.str[STRING_MAIL_FROM])
+    /* Null reverse-path, RFC-5321, sect. 3.6.3 */
+    from = strdup("<>");
+  else if(data->set.str[STRING_MAIL_FROM][0] == '<')
+    from = aprintf("%s", data->set.str[STRING_MAIL_FROM]);
+  else
+    from = aprintf("<%s>", data->set.str[STRING_MAIL_FROM]);
+
+  if(!from)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Calculate the optional AUTH parameter */
+  if(data->set.str[STRING_MAIL_AUTH] && conn->proto.smtpc.sasl.authused) {
+    if(data->set.str[STRING_MAIL_AUTH][0] != '\0')
+      auth = aprintf("%s", data->set.str[STRING_MAIL_AUTH]);
+    else
+      /* Empty AUTH, RFC-2554, sect. 5 */
+      auth = strdup("<>");
+
+    if(!auth) {
+      free(from);
+
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* Calculate the optional SIZE parameter */
+  if(conn->proto.smtpc.size_supported && conn->data->state.infilesize > 0) {
+    size = aprintf("%" CURL_FORMAT_CURL_OFF_T, data->state.infilesize);
+
+    if(!size) {
+      free(from);
+      free(auth);
+
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* Send the MAIL command */
+  if(!auth && !size)
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+                           "MAIL FROM:%s", from);
+  else if(auth && !size)
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+                           "MAIL FROM:%s AUTH=%s", from, auth);
+  else if(auth && size)
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+                           "MAIL FROM:%s AUTH=%s SIZE=%s", from, auth, size);
+  else
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+                           "MAIL FROM:%s SIZE=%s", from, size);
+
+  free(from);
+  free(auth);
+  free(size);
+
+  if(!result)
+    state(conn, SMTP_MAIL);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_rcpt_to()
+ *
+ * Sends a RCPT TO command for a given recipient as part of the message upload
+ * process.
+ */
+static CURLcode smtp_perform_rcpt_to(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+
+  /* Send the RCPT TO command */
+  if(smtp->rcpt->data[0] == '<')
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:%s",
+                            smtp->rcpt->data);
+  else
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s>",
+                            smtp->rcpt->data);
+  if(!result)
+    state(conn, SMTP_RCPT);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_quit()
+ *
+ * Performs the quit action prior to sclose() being called.
+ */
+static CURLcode smtp_perform_quit(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Send the QUIT command */
+  result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "QUIT");
+
+  if(!result)
+    state(conn, SMTP_QUIT);
+
+  return result;
+}
+
+/* For the initial server greeting */
+static CURLcode smtp_state_servergreet_resp(struct connectdata *conn,
+                                            int smtpcode,
+                                            smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode/100 != 2) {
+    failf(data, "Got unexpected smtp-server response: %d", smtpcode);
+    result = CURLE_FTP_WEIRD_SERVER_REPLY;
+  }
+  else
+    result = smtp_perform_ehlo(conn);
+
+  return result;
+}
+
+/* For STARTTLS responses */
+static CURLcode smtp_state_starttls_resp(struct connectdata *conn,
+                                         int smtpcode,
+                                         smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode != 220) {
+    if(data->set.use_ssl != CURLUSESSL_TRY) {
+      failf(data, "STARTTLS denied. %c", smtpcode);
+      result = CURLE_USE_SSL_FAILED;
+    }
+    else
+      result = smtp_perform_authentication(conn);
+  }
+  else
+    result = smtp_perform_upgrade_tls(conn);
+
+  return result;
+}
+
+/* For EHLO responses */
+static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
+                                     smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  const char *line = data->state.buffer;
+  size_t len = strlen(line);
+  size_t wordlen;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode/100 != 2 && smtpcode != 1) {
+    if(data->set.use_ssl <= CURLUSESSL_TRY || conn->ssl[FIRSTSOCKET].use)
+      result = smtp_perform_helo(conn);
+    else {
+      failf(data, "Remote access denied: %d", smtpcode);
+      result = CURLE_REMOTE_ACCESS_DENIED;
+    }
+  }
+  else {
+    line += 4;
+    len -= 4;
+
+    /* Does the server support the STARTTLS capability? */
+    if(len >= 8 && !memcmp(line, "STARTTLS", 8))
+      smtpc->tls_supported = TRUE;
+
+    /* Does the server support the SIZE capability? */
+    else if(len >= 4 && !memcmp(line, "SIZE", 4))
+      smtpc->size_supported = TRUE;
+
+    /* Does the server support authentication? */
+    else if(len >= 5 && !memcmp(line, "AUTH ", 5)) {
+      smtpc->auth_supported = TRUE;
+
+      /* Advance past the AUTH keyword */
+      line += 5;
+      len -= 5;
+
+      /* Loop through the data line */
+      for(;;) {
+        size_t llen;
+        unsigned int mechbit;
+
+        while(len &&
+              (*line == ' ' || *line == '\t' ||
+               *line == '\r' || *line == '\n')) {
+
+          line++;
+          len--;
+        }
+
+        if(!len)
+          break;
+
+        /* Extract the word */
+        for(wordlen = 0; wordlen < len && line[wordlen] != ' ' &&
+              line[wordlen] != '\t' && line[wordlen] != '\r' &&
+              line[wordlen] != '\n';)
+          wordlen++;
+
+        /* Test the word for a matching authentication mechanism */
+        if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
+           llen == wordlen)
+          smtpc->sasl.authmechs |= mechbit;
+
+        line += wordlen;
+        len -= wordlen;
+      }
+    }
+
+    if(smtpcode != 1) {
+      if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+        /* We don't have a SSL/TLS connection yet, but SSL is requested */
+        if(smtpc->tls_supported)
+          /* Switch to TLS connection now */
+          result = smtp_perform_starttls(conn);
+        else if(data->set.use_ssl == CURLUSESSL_TRY)
+          /* Fallback and carry on with authentication */
+          result = smtp_perform_authentication(conn);
+        else {
+          failf(data, "STARTTLS not supported.");
+          result = CURLE_USE_SSL_FAILED;
+        }
+      }
+      else
+        result = smtp_perform_authentication(conn);
+    }
+  }
+
+  return result;
+}
+
+/* For HELO responses */
+static CURLcode smtp_state_helo_resp(struct connectdata *conn, int smtpcode,
+                                     smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode/100 != 2) {
+    failf(data, "Remote access denied: %d", smtpcode);
+    result = CURLE_REMOTE_ACCESS_DENIED;
+  }
+  else
+    /* End of connect phase */
+    state(conn, SMTP_STOP);
+
+  return result;
+}
+
+/* For SASL authentication responses */
+static CURLcode smtp_state_auth_resp(struct connectdata *conn,
+                                     int smtpcode,
+                                     smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  saslprogress progress;
+
+  (void)instate; /* no use for this yet */
+
+  result = Curl_sasl_continue(&smtpc->sasl, conn, smtpcode, &progress);
+  if(!result)
+    switch(progress) {
+    case SASL_DONE:
+      state(conn, SMTP_STOP);  /* Authenticated */
+      break;
+    case SASL_IDLE:            /* No mechanism left after cancellation */
+      failf(data, "Authentication cancelled");
+      result = CURLE_LOGIN_DENIED;
+      break;
+    default:
+      break;
+    }
+
+  return result;
+}
+
+/* For command responses */
+static CURLcode smtp_state_command_resp(struct connectdata *conn, int smtpcode,
+                                        smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+  char *line = data->state.buffer;
+  size_t len = strlen(line);
+
+  (void)instate; /* no use for this yet */
+
+  if((smtp->rcpt && smtpcode/100 != 2 && smtpcode != 553 && smtpcode != 1) ||
+     (!smtp->rcpt && smtpcode/100 != 2 && smtpcode != 1)) {
+    failf(data, "Command failed: %d", smtpcode);
+    result = CURLE_RECV_ERROR;
+  }
+  else {
+    /* Temporarily add the LF character back and send as body to the client */
+    if(!data->set.opt_no_body) {
+      line[len] = '\n';
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1);
+      line[len] = '\0';
+    }
+
+    if(smtpcode != 1) {
+      if(smtp->rcpt) {
+        smtp->rcpt = smtp->rcpt->next;
+
+        if(smtp->rcpt) {
+          /* Send the next command */
+          result = smtp_perform_command(conn);
+        }
+        else
+          /* End of DO phase */
+          state(conn, SMTP_STOP);
+      }
+      else
+        /* End of DO phase */
+        state(conn, SMTP_STOP);
+    }
+  }
+
+  return result;
+}
+
+/* For MAIL responses */
+static CURLcode smtp_state_mail_resp(struct connectdata *conn, int smtpcode,
+                                     smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode/100 != 2) {
+    failf(data, "MAIL failed: %d", smtpcode);
+    result = CURLE_SEND_ERROR;
+  }
+  else
+    /* Start the RCPT TO command */
+    result = smtp_perform_rcpt_to(conn);
+
+  return result;
+}
+
+/* For RCPT responses */
+static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode,
+                                     smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode/100 != 2) {
+    failf(data, "RCPT failed: %d", smtpcode);
+    result = CURLE_SEND_ERROR;
+  }
+  else {
+    smtp->rcpt = smtp->rcpt->next;
+
+    if(smtp->rcpt)
+      /* Send the next RCPT TO command */
+      result = smtp_perform_rcpt_to(conn);
+    else {
+      /* Send the DATA command */
+      result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "DATA");
+
+      if(!result)
+        state(conn, SMTP_DATA);
+    }
+  }
+
+  return result;
+}
+
+/* For DATA response */
+static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode,
+                                     smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode != 354) {
+    failf(data, "DATA failed: %d", smtpcode);
+    result = CURLE_SEND_ERROR;
+  }
+  else {
+    /* Set the progress upload size */
+    Curl_pgrsSetUploadSize(data, data->state.infilesize);
+
+    /* SMTP upload */
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+
+    /* End of DO phase */
+    state(conn, SMTP_STOP);
+  }
+
+  return result;
+}
+
+/* For POSTDATA responses, which are received after the entire DATA
+   part has been sent to the server */
+static CURLcode smtp_state_postdata_resp(struct connectdata *conn,
+                                         int smtpcode,
+                                         smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode != 250)
+    result = CURLE_RECV_ERROR;
+
+  /* End of DONE phase */
+  state(conn, SMTP_STOP);
+
+  return result;
+}
+
+static CURLcode smtp_statemach_act(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  struct SessionHandle *data = conn->data;
+  int smtpcode;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  struct pingpong *pp = &smtpc->pp;
+  size_t nread = 0;
+
+  /* Busy upgrading the connection; right now all I/O is SSL/TLS, not SMTP */
+  if(smtpc->state == SMTP_UPGRADETLS)
+    return smtp_perform_upgrade_tls(conn);
+
+  /* Flush any data that needs to be sent */
+  if(pp->sendleft)
+    return Curl_pp_flushsend(pp);
+
+  do {
+    /* Read the response from the server */
+    result = Curl_pp_readresp(sock, pp, &smtpcode, &nread);
+    if(result)
+      return result;
+
+    /* Store the latest response for later retrieval if necessary */
+    if(smtpc->state != SMTP_QUIT && smtpcode != 1)
+      data->info.httpcode = smtpcode;
+
+    if(!smtpcode)
+      break;
+
+    /* We have now received a full SMTP server response */
+    switch(smtpc->state) {
+    case SMTP_SERVERGREET:
+      result = smtp_state_servergreet_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_EHLO:
+      result = smtp_state_ehlo_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_HELO:
+      result = smtp_state_helo_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_STARTTLS:
+      result = smtp_state_starttls_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_AUTH:
+      result = smtp_state_auth_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_COMMAND:
+      result = smtp_state_command_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_MAIL:
+      result = smtp_state_mail_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_RCPT:
+      result = smtp_state_rcpt_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_DATA:
+      result = smtp_state_data_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_POSTDATA:
+      result = smtp_state_postdata_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_QUIT:
+      /* fallthrough, just stop! */
+    default:
+      /* internal error */
+      state(conn, SMTP_STOP);
+      break;
+    }
+  } while(!result && smtpc->state != SMTP_STOP && Curl_pp_moredata(pp));
+
+  return result;
+}
+
+/* Called repeatedly until done from multi.c */
+static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  if((conn->handler->flags & PROTOPT_SSL) && !smtpc->ssldone) {
+    result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone);
+    if(result || !smtpc->ssldone)
+      return result;
+  }
+
+  result = Curl_pp_statemach(&smtpc->pp, FALSE);
+  *done = (smtpc->state == SMTP_STOP) ? TRUE : FALSE;
+
+  return result;
+}
+
+static CURLcode smtp_block_statemach(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  while(smtpc->state != SMTP_STOP && !result)
+    result = Curl_pp_statemach(&smtpc->pp, TRUE);
+
+  return result;
+}
+
+/* Allocate and initialize the SMTP struct for the current SessionHandle if
+   required */
+static CURLcode smtp_init(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct SMTP *smtp;
+
+  smtp = data->req.protop = calloc(sizeof(struct SMTP), 1);
+  if(!smtp)
+    result = CURLE_OUT_OF_MEMORY;
+
+  return result;
+}
+
+/* For the SMTP "protocol connect" and "doing" phases only */
+static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks)
+{
+  return Curl_pp_getsock(&conn->proto.smtpc.pp, socks, numsocks);
+}
+
+/***********************************************************************
+ *
+ * smtp_connect()
+ *
+ * This function should do everything that is to be considered a part of
+ * the connection phase.
+ *
+ * The variable pointed to by 'done' will be TRUE if the protocol-layer
+ * connect phase is done when this function returns, or FALSE if not.
+ */
+static CURLcode smtp_connect(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  struct pingpong *pp = &smtpc->pp;
+
+  *done = FALSE; /* default to not done yet */
+
+  /* We always support persistent connections in SMTP */
+  connkeep(conn, "SMTP default");
+
+  /* Set the default response time-out */
+  pp->response_time = RESP_TIMEOUT;
+  pp->statemach_act = smtp_statemach_act;
+  pp->endofresp = smtp_endofresp;
+  pp->conn = conn;
+
+  /* Initialize the SASL storage */
+  Curl_sasl_init(&smtpc->sasl, &saslsmtp);
+
+  /* Initialise the pingpong layer */
+  Curl_pp_init(pp);
+
+  /* Parse the URL options */
+  result = smtp_parse_url_options(conn);
+  if(result)
+    return result;
+
+  /* Parse the URL path */
+  result = smtp_parse_url_path(conn);
+  if(result)
+    return result;
+
+  /* Start off waiting for the server greeting response */
+  state(conn, SMTP_SERVERGREET);
+
+  result = smtp_multi_statemach(conn, done);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_done()
+ *
+ * The DONE function. This does what needs to be done after a single DO has
+ * performed.
+ *
+ * Input argument is already checked for validity.
+ */
+static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
+                          bool premature)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+  struct pingpong *pp = &conn->proto.smtpc.pp;
+  char *eob;
+  ssize_t len;
+  ssize_t bytes_written;
+
+  (void)premature;
+
+  if(!smtp || !pp->conn)
+    /* When the easy handle is removed from the multi interface while libcurl
+       is still trying to resolve the host name, the SMTP struct is not yet
+       initialized. However, the removal action calls Curl_done() which in
+       turn calls this function, so we simply return success. */
+    return CURLE_OK;
+
+  if(status) {
+    connclose(conn, "SMTP done with bad status"); /* marked for closure */
+    result = status;         /* use the already set error code */
+  }
+  else if(!data->set.connect_only && data->set.upload && data->set.mail_rcpt) {
+    /* Calculate the EOB taking into account any terminating CRLF from the
+       previous line of the email or the CRLF of the DATA command when there
+       is "no mail data". RFC-5321, sect. 4.1.1.4.
+
+       Note: As some SSL backends, such as OpenSSL, will cause Curl_write() to
+       fail when using a different pointer following a previous write, that
+       returned CURLE_AGAIN, we duplicate the EOB now rather than when the
+       bytes written doesn't equal len. */
+    if(smtp->trailing_crlf || !conn->data->state.infilesize) {
+      eob = strdup(SMTP_EOB + 2);
+      len = SMTP_EOB_LEN - 2;
+    }
+    else {
+      eob = strdup(SMTP_EOB);
+      len = SMTP_EOB_LEN;
+    }
+
+    if(!eob)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Send the end of block data */
+    result = Curl_write(conn, conn->writesockfd, eob, len, &bytes_written);
+    if(result) {
+      free(eob);
+      return result;
+    }
+
+    if(bytes_written != len) {
+      /* The whole chunk was not sent so keep it around and adjust the
+         pingpong structure accordingly */
+      pp->sendthis = eob;
+      pp->sendsize = len;
+      pp->sendleft = len - bytes_written;
+    }
+    else {
+      /* Successfully sent so adjust the response timeout relative to now */
+      pp->response = Curl_tvnow();
+
+      free(eob);
+    }
+
+    state(conn, SMTP_POSTDATA);
+
+    /* Run the state-machine
+
+       TODO: when the multi interface is used, this _really_ should be using
+       the smtp_multi_statemach function but we have no general support for
+       non-blocking DONE operations, not in the multi state machine and with
+       Curl_done() invokes on several places in the code!
+    */
+    result = smtp_block_statemach(conn);
+  }
+
+  /* Cleanup our per-request based variables */
+  Curl_safefree(smtp->custom);
+
+  /* Clear the transfer mode for the next request */
+  smtp->transfer = FTPTRANSFER_BODY;
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform()
+ *
+ * This is the actual DO function for SMTP. Transfer a mail, send a command
+ * or get some data according to the options previously setup.
+ */
+static CURLcode smtp_perform(struct connectdata *conn, bool *connected,
+                             bool *dophase_done)
+{
+  /* This is SMTP and no proxy */
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  if(data->set.opt_no_body) {
+    /* Requested no body means no transfer */
+    smtp->transfer = FTPTRANSFER_INFO;
+  }
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* Store the first recipient (or NULL if not specified) */
+  smtp->rcpt = data->set.mail_rcpt;
+
+  /* Start the first command in the DO phase */
+  if(data->set.upload && data->set.mail_rcpt)
+    /* MAIL transfer */
+    result = smtp_perform_mail(conn);
+  else
+    /* SMTP based command (VRFY, EXPN, NOOP, RSET or HELP) */
+    result = smtp_perform_command(conn);
+
+  if(result)
+    return result;
+
+  /* Run the state-machine */
+  result = smtp_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done)
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_do()
+ *
+ * This function is registered as 'curl_do' function. It decodes the path
+ * parts etc as a wrapper to the actual DO function (smtp_perform).
+ *
+ * The input argument is already checked for validity.
+ */
+static CURLcode smtp_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+
+  *done = FALSE; /* default to false */
+
+  /* Parse the custom request */
+  result = smtp_parse_custom_request(conn);
+  if(result)
+    return result;
+
+  result = smtp_regular_transfer(conn, done);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_disconnect()
+ *
+ * Disconnect from an SMTP server. Cleanup protocol-specific per-connection
+ * resources. BLOCKING.
+ */
+static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  /* We cannot send quit unconditionally. If this connection is stale or
+     bad in any way, sending quit and waiting around here will make the
+     disconnect wait in vain and cause more problems than we need to. */
+
+  /* The SMTP session may or may not have been allocated/setup at this
+     point! */
+  if(!dead_connection && smtpc->pp.conn && smtpc->pp.conn->bits.protoconnstart)
+    if(!smtp_perform_quit(conn))
+      (void)smtp_block_statemach(conn); /* ignore errors on QUIT */
+
+  /* Disconnect from the server */
+  Curl_pp_disconnect(&smtpc->pp);
+
+  /* Cleanup the SASL module */
+  Curl_sasl_cleanup(conn, smtpc->sasl.authused);
+
+  /* Cleanup our connection based variables */
+  Curl_safefree(smtpc->domain);
+
+  return CURLE_OK;
+}
+
+/* Call this when the DO phase has completed */
+static CURLcode smtp_dophase_done(struct connectdata *conn, bool connected)
+{
+  struct SMTP *smtp = conn->data->req.protop;
+
+  (void)connected;
+
+  if(smtp->transfer != FTPTRANSFER_BODY)
+    /* no data to transfer */
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+  return CURLE_OK;
+}
+
+/* Called from multi.c while DOing */
+static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done)
+{
+  CURLcode result = smtp_multi_statemach(conn, dophase_done);
+
+  if(result)
+    DEBUGF(infof(conn->data, "DO phase failed\n"));
+  else if(*dophase_done) {
+    result = smtp_dophase_done(conn, FALSE /* not connected */);
+
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_regular_transfer()
+ *
+ * The input argument is already checked for validity.
+ *
+ * Performs all commands done before a regular transfer between a local and a
+ * remote host.
+ */
+static CURLcode smtp_regular_transfer(struct connectdata *conn,
+                                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+  bool connected = FALSE;
+  struct SessionHandle *data = conn->data;
+
+  /* Make sure size is unknown at this point */
+  data->req.size = -1;
+
+  /* Set the progress data */
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  /* Carry out the perform */
+  result = smtp_perform(conn, &connected, dophase_done);
+
+  /* Perform post DO phase operations if necessary */
+  if(!result && *dophase_done)
+    result = smtp_dophase_done(conn, connected);
+
+  return result;
+}
+
+static CURLcode smtp_setup_connection(struct connectdata *conn)
+{
+  struct SessionHandle *data = conn->data;
+  CURLcode result;
+
+  if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
+    /* Unless we have asked to tunnel SMTP operations through the proxy, we
+       switch and use HTTP operations only */
+#ifndef CURL_DISABLE_HTTP
+    if(conn->handler == &Curl_handler_smtp)
+      conn->handler = &Curl_handler_smtp_proxy;
+    else {
+#ifdef USE_SSL
+      conn->handler = &Curl_handler_smtps_proxy;
+#else
+      failf(data, "SMTPS not supported!");
+      return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+    }
+    /* set it up as a HTTP connection instead */
+    return conn->handler->setup_connection(conn);
+
+#else
+    failf(data, "SMTP over http proxy requires HTTP support built-in!");
+    return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+  }
+
+  /* Initialise the SMTP layer */
+  result = smtp_init(conn);
+  if(result)
+    return result;
+
+  data->state.path++;   /* don't include the initial slash */
+
+  return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * smtp_parse_url_options()
+ *
+ * Parse the URL login options.
+ */
+static CURLcode smtp_parse_url_options(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  const char *ptr = conn->options;
+
+  smtpc->sasl.resetprefs = TRUE;
+
+  while(!result && ptr && *ptr) {
+    const char *key = ptr;
+    const char *value;
+
+    while(*ptr && *ptr != '=')
+        ptr++;
+
+    value = ptr + 1;
+
+    while(*ptr && *ptr != ';')
+      ptr++;
+
+    if(strnequal(key, "AUTH=", 5))
+      result = Curl_sasl_parse_url_auth_option(&smtpc->sasl,
+                                               value, ptr - value);
+    else
+      result = CURLE_URL_MALFORMAT;
+
+    if(*ptr == ';')
+      ptr++;
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_parse_url_path()
+ *
+ * Parse the URL path into separate path components.
+ */
+static CURLcode smtp_parse_url_path(struct connectdata *conn)
+{
+  /* The SMTP struct is already initialised in smtp_connect() */
+  struct SessionHandle *data = conn->data;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  const char *path = data->state.path;
+  char localhost[HOSTNAME_MAX + 1];
+
+  /* Calculate the path if necessary */
+  if(!*path) {
+    if(!Curl_gethostname(localhost, sizeof(localhost)))
+      path = localhost;
+    else
+      path = "localhost";
+  }
+
+  /* URL decode the path and use it as the domain in our EHLO */
+  return Curl_urldecode(conn->data, path, 0, &smtpc->domain, NULL, TRUE);
+}
+
+/***********************************************************************
+ *
+ * smtp_parse_custom_request()
+ *
+ * Parse the custom request.
+ */
+static CURLcode smtp_parse_custom_request(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+  const char *custom = data->set.str[STRING_CUSTOMREQUEST];
+
+  /* URL decode the custom request */
+  if(custom)
+    result = Curl_urldecode(data, custom, 0, &smtp->custom, NULL, TRUE);
+
+  return result;
+}
+
+CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread)
+{
+  /* When sending a SMTP payload we must detect CRLF. sequences making sure
+     they are sent as CRLF.. instead, as a . on the beginning of a line will
+     be deleted by the server when not part of an EOB terminator and a
+     genuine CRLF.CRLF which isn't escaped will wrongly be detected as end of
+     data by the server
+  */
+  ssize_t i;
+  ssize_t si;
+  struct SessionHandle *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+  char *scratch = data->state.scratch;
+  char *newscratch = NULL;
+  char *oldscratch = NULL;
+  size_t eob_sent;
+
+  /* Do we need to allocate a scratch buffer? */
+  if(!scratch || data->set.crlf) {
+    oldscratch = scratch;
+
+    scratch = newscratch = malloc(2 * BUFSIZE);
+    if(!newscratch) {
+      failf(data, "Failed to alloc scratch buffer!");
+
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* Have we already sent part of the EOB? */
+  eob_sent = smtp->eob;
+
+  /* This loop can be improved by some kind of Boyer-Moore style of
+     approach but that is saved for later... */
+  for(i = 0, si = 0; i < nread; i++) {
+    if(SMTP_EOB[smtp->eob] == data->req.upload_fromhere[i]) {
+      smtp->eob++;
+
+      /* Is the EOB potentially the terminating CRLF? */
+      if(2 == smtp->eob || SMTP_EOB_LEN == smtp->eob)
+        smtp->trailing_crlf = TRUE;
+      else
+        smtp->trailing_crlf = FALSE;
+    }
+    else if(smtp->eob) {
+      /* A previous substring matched so output that first */
+      memcpy(&scratch[si], &SMTP_EOB[eob_sent], smtp->eob - eob_sent);
+      si += smtp->eob - eob_sent;
+
+      /* Then compare the first byte */
+      if(SMTP_EOB[0] == data->req.upload_fromhere[i])
+        smtp->eob = 1;
+      else
+        smtp->eob = 0;
+
+      eob_sent = 0;
+
+      /* Reset the trailing CRLF flag as there was more data */
+      smtp->trailing_crlf = FALSE;
+    }
+
+    /* Do we have a match for CRLF. as per RFC-5321, sect. 4.5.2 */
+    if(SMTP_EOB_FIND_LEN == smtp->eob) {
+      /* Copy the replacement data to the target buffer */
+      memcpy(&scratch[si], &SMTP_EOB_REPL[eob_sent],
+             SMTP_EOB_REPL_LEN - eob_sent);
+      si += SMTP_EOB_REPL_LEN - eob_sent;
+      smtp->eob = 0;
+      eob_sent = 0;
+    }
+    else if(!smtp->eob)
+      scratch[si++] = data->req.upload_fromhere[i];
+  }
+
+  if(smtp->eob - eob_sent) {
+    /* A substring matched before processing ended so output that now */
+    memcpy(&scratch[si], &SMTP_EOB[eob_sent], smtp->eob - eob_sent);
+    si += smtp->eob - eob_sent;
+  }
+
+  /* Only use the new buffer if we replaced something */
+  if(si != nread) {
+    /* Upload from the new (replaced) buffer instead */
+    data->req.upload_fromhere = scratch;
+
+    /* Save the buffer so it can be freed later */
+    data->state.scratch = scratch;
+
+    /* Free the old scratch buffer */
+    free(oldscratch);
+
+    /* Set the new amount too */
+    data->req.upload_present = si;
+  }
+  else
+    free(newscratch);
+
+  return CURLE_OK;
+}
+
+#endif /* CURL_DISABLE_SMTP */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/smtp.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/smtp.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/smtp.h	(revision 164)
@@ -0,0 +1,91 @@
+#ifndef HEADER_CURL_SMTP_H
+#define HEADER_CURL_SMTP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2009 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "pingpong.h"
+#include "curl_sasl.h"
+
+/****************************************************************************
+ * SMTP unique setup
+ ***************************************************************************/
+typedef enum {
+  SMTP_STOP,        /* do nothing state, stops the state machine */
+  SMTP_SERVERGREET, /* waiting for the initial greeting immediately after
+                       a connect */
+  SMTP_EHLO,
+  SMTP_HELO,
+  SMTP_STARTTLS,
+  SMTP_UPGRADETLS,  /* asynchronously upgrade the connection to SSL/TLS
+                       (multi mode only) */
+  SMTP_AUTH,
+  SMTP_COMMAND,     /* VRFY, EXPN, NOOP, RSET and HELP */
+  SMTP_MAIL,        /* MAIL FROM */
+  SMTP_RCPT,        /* RCPT TO */
+  SMTP_DATA,
+  SMTP_POSTDATA,
+  SMTP_QUIT,
+  SMTP_LAST         /* never used */
+} smtpstate;
+
+/* This SMTP struct is used in the SessionHandle. All SMTP data that is
+   connection-oriented must be in smtp_conn to properly deal with the fact that
+   perhaps the SessionHandle is changed between the times the connection is
+   used. */
+struct SMTP {
+  curl_pp_transfer transfer;
+  char *custom;            /* Custom Request */
+  struct curl_slist *rcpt; /* Recipient list */
+  size_t eob;              /* Number of bytes of the EOB (End Of Body) that
+                              have been received so far */
+  bool trailing_crlf;      /* Specifies if the tailing CRLF is present */
+};
+
+/* smtp_conn is used for struct connection-oriented data in the connectdata
+   struct */
+struct smtp_conn {
+  struct pingpong pp;
+  smtpstate state;         /* Always use smtp.c:state() to change state! */
+  bool ssldone;            /* Is connect() over SSL done? */
+  char *domain;            /* Client address/name to send in the EHLO */
+  struct SASL sasl;        /* SASL-related storage */
+  bool tls_supported;      /* StartTLS capability supported by server */
+  bool size_supported;     /* If server supports SIZE extension according to
+                              RFC 1870 */
+  bool auth_supported;     /* AUTH capability supported by server */
+};
+
+extern const struct Curl_handler Curl_handler_smtp;
+extern const struct Curl_handler Curl_handler_smtps;
+
+/* this is the 5-bytes End-Of-Body marker for SMTP */
+#define SMTP_EOB "\x0d\x0a\x2e\x0d\x0a"
+#define SMTP_EOB_LEN 5
+#define SMTP_EOB_FIND_LEN 3
+
+/* if found in data, replace it with this string instead */
+#define SMTP_EOB_REPL "\x0d\x0a\x2e\x2e"
+#define SMTP_EOB_REPL_LEN 4
+
+CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread);
+
+#endif /* HEADER_CURL_SMTP_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/sockaddr.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/sockaddr.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/sockaddr.h	(revision 164)
@@ -0,0 +1,43 @@
+#ifndef HEADER_CURL_SOCKADDR_H
+#define HEADER_CURL_SOCKADDR_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+struct Curl_sockaddr_storage {
+  union {
+    struct sockaddr sa;
+    struct sockaddr_in sa_in;
+#ifdef ENABLE_IPV6
+    struct sockaddr_in6 sa_in6;
+#endif
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
+    struct sockaddr_storage sa_stor;
+#else
+    char cbuf[256];   /* this should be big enough to fit a lot */
+#endif
+  } buffer;
+};
+
+#endif /* HEADER_CURL_SOCKADDR_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/socks.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/socks.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/socks.c	(revision 164)
@@ -0,0 +1,755 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_PROXY)
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "strequal.h"
+#include "select.h"
+#include "connect.h"
+#include "timeval.h"
+#include "socks.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Helper read-from-socket functions. Does the same as Curl_read() but it
+ * blocks until all bytes amount of buffersize will be read. No more, no less.
+ *
+ * This is STUPID BLOCKING behaviour which we frown upon, but right now this
+ * is what we have...
+ */
+int Curl_blockread_all(struct connectdata *conn, /* connection data */
+                       curl_socket_t sockfd,     /* read from this socket */
+                       char *buf,                /* store read data here */
+                       ssize_t buffersize,       /* max amount to read */
+                       ssize_t *n)               /* amount bytes read */
+{
+  ssize_t nread;
+  ssize_t allread = 0;
+  int result;
+  long timeleft;
+  *n = 0;
+  for(;;) {
+    timeleft = Curl_timeleft(conn->data, NULL, TRUE);
+    if(timeleft < 0) {
+      /* we already got the timeout */
+      result = CURLE_OPERATION_TIMEDOUT;
+      break;
+    }
+    if(Curl_socket_ready(sockfd, CURL_SOCKET_BAD, timeleft) <= 0) {
+      result = ~CURLE_OK;
+      break;
+    }
+    result = Curl_read_plain(sockfd, buf, buffersize, &nread);
+    if(CURLE_AGAIN == result)
+      continue;
+    else if(result)
+      break;
+
+    if(buffersize == nread) {
+      allread += nread;
+      *n = allread;
+      result = CURLE_OK;
+      break;
+    }
+    if(!nread) {
+      result = ~CURLE_OK;
+      break;
+    }
+
+    buffersize -= nread;
+    buf += nread;
+    allread += nread;
+  }
+  return result;
+}
+
+/*
+* This function logs in to a SOCKS4 proxy and sends the specifics to the final
+* destination server.
+*
+* Reference :
+*   http://socks.permeo.com/protocol/socks4.protocol
+*
+* Note :
+*   Set protocol4a=true for  "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)"
+*   Nonsupport "Identification Protocol (RFC1413)"
+*/
+CURLcode Curl_SOCKS4(const char *proxy_name,
+                     const char *hostname,
+                     int remote_port,
+                     int sockindex,
+                     struct connectdata *conn,
+                     bool protocol4a)
+{
+#define SOCKS4REQLEN 262
+  unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user
+                                           id */
+  int result;
+  CURLcode code;
+  curl_socket_t sock = conn->sock[sockindex];
+  struct SessionHandle *data = conn->data;
+
+  if(Curl_timeleft(data, NULL, TRUE) < 0) {
+    /* time-out, bail out, go home */
+    failf(data, "Connection time-out");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  (void)curlx_nonblock(sock, FALSE);
+
+  infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
+
+  /*
+   * Compose socks4 request
+   *
+   * Request format
+   *
+   *     +----+----+----+----+----+----+----+----+----+----+....+----+
+   *     | VN | CD | DSTPORT |      DSTIP        | USERID       |NULL|
+   *     +----+----+----+----+----+----+----+----+----+----+....+----+
+   * # of bytes:  1    1      2              4           variable       1
+   */
+
+  socksreq[0] = 4; /* version (SOCKS4) */
+  socksreq[1] = 1; /* connect */
+  socksreq[2] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
+  socksreq[3] = (unsigned char)(remote_port & 0xff);        /* PORT LSB */
+
+  /* DNS resolve only for SOCKS4, not SOCKS4a */
+  if(!protocol4a) {
+    struct Curl_dns_entry *dns;
+    Curl_addrinfo *hp=NULL;
+    int rc;
+
+    rc = Curl_resolv(conn, hostname, remote_port, &dns);
+
+    if(rc == CURLRESOLV_ERROR)
+      return CURLE_COULDNT_RESOLVE_PROXY;
+
+    if(rc == CURLRESOLV_PENDING)
+      /* ignores the return code, but 'dns' remains NULL on failure */
+      (void)Curl_resolver_wait_resolv(conn, &dns);
+
+    /*
+     * We cannot use 'hostent' as a struct that Curl_resolv() returns.  It
+     * returns a Curl_addrinfo pointer that may not always look the same.
+     */
+    if(dns)
+      hp=dns->addr;
+    if(hp) {
+      char buf[64];
+      unsigned short ip[4];
+      Curl_printable_address(hp, buf, sizeof(buf));
+
+      if(4 == sscanf( buf, "%hu.%hu.%hu.%hu",
+                      &ip[0], &ip[1], &ip[2], &ip[3])) {
+        /* Set DSTIP */
+        socksreq[4] = (unsigned char)ip[0];
+        socksreq[5] = (unsigned char)ip[1];
+        socksreq[6] = (unsigned char)ip[2];
+        socksreq[7] = (unsigned char)ip[3];
+      }
+      else
+        hp = NULL; /* fail! */
+
+      infof(data, "SOCKS4 connect to %s (locally resolved)\n", buf);
+
+      Curl_resolv_unlock(data, dns); /* not used anymore from now on */
+
+    }
+    if(!hp) {
+      failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.",
+            hostname);
+      return CURLE_COULDNT_RESOLVE_HOST;
+    }
+  }
+
+  /*
+   * This is currently not supporting "Identification Protocol (RFC1413)".
+   */
+  socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
+  if(proxy_name) {
+    size_t plen = strlen(proxy_name);
+    if(plen >= sizeof(socksreq) - 8) {
+      failf(data, "Too long SOCKS proxy name, can't use!\n");
+      return CURLE_COULDNT_CONNECT;
+    }
+    /* copy the proxy name WITH trailing zero */
+    memcpy(socksreq + 8, proxy_name, plen+1);
+  }
+
+  /*
+   * Make connection
+   */
+  {
+    ssize_t actualread;
+    ssize_t written;
+    ssize_t hostnamelen = 0;
+    int packetsize = 9 +
+      (int)strlen((char*)socksreq + 8); /* size including NUL */
+
+    /* If SOCKS4a, set special invalid IP address 0.0.0.x */
+    if(protocol4a) {
+      socksreq[4] = 0;
+      socksreq[5] = 0;
+      socksreq[6] = 0;
+      socksreq[7] = 1;
+      /* If still enough room in buffer, also append hostname */
+      hostnamelen = (ssize_t)strlen(hostname) + 1; /* length including NUL */
+      if(packetsize + hostnamelen <= SOCKS4REQLEN)
+        strcpy((char*)socksreq + packetsize, hostname);
+      else
+        hostnamelen = 0; /* Flag: hostname did not fit in buffer */
+    }
+
+    /* Send request */
+    code = Curl_write_plain(conn, sock, (char *)socksreq,
+                            packetsize + hostnamelen,
+                            &written);
+    if(code || (written != packetsize + hostnamelen)) {
+      failf(data, "Failed to send SOCKS4 connect request.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    if(protocol4a && hostnamelen == 0) {
+      /* SOCKS4a with very long hostname - send that name separately */
+      hostnamelen = (ssize_t)strlen(hostname) + 1;
+      code = Curl_write_plain(conn, sock, (char *)hostname, hostnamelen,
+                              &written);
+      if(code || (written != hostnamelen)) {
+        failf(data, "Failed to send SOCKS4 connect request.");
+        return CURLE_COULDNT_CONNECT;
+      }
+    }
+
+    packetsize = 8; /* receive data size */
+
+    /* Receive response */
+    result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
+                                &actualread);
+    if(result || (actualread != packetsize)) {
+      failf(data, "Failed to receive SOCKS4 connect request ack.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    /*
+     * Response format
+     *
+     *     +----+----+----+----+----+----+----+----+
+     *     | VN | CD | DSTPORT |      DSTIP        |
+     *     +----+----+----+----+----+----+----+----+
+     * # of bytes:  1    1      2              4
+     *
+     * VN is the version of the reply code and should be 0. CD is the result
+     * code with one of the following values:
+     *
+     * 90: request granted
+     * 91: request rejected or failed
+     * 92: request rejected because SOCKS server cannot connect to
+     *     identd on the client
+     * 93: request rejected because the client program and identd
+     *     report different user-ids
+     */
+
+    /* wrong version ? */
+    if(socksreq[0] != 0) {
+      failf(data,
+            "SOCKS4 reply has wrong version, version should be 4.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    /* Result */
+    switch(socksreq[1]) {
+    case 90:
+      infof(data, "SOCKS4%s request granted.\n", protocol4a?"a":"");
+      break;
+    case 91:
+      failf(data,
+            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+            ", request rejected or failed.",
+            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+            (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
+            (unsigned char)socksreq[1]);
+      return CURLE_COULDNT_CONNECT;
+    case 92:
+      failf(data,
+            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+            ", request rejected because SOCKS server cannot connect to "
+            "identd on the client.",
+            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+            (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
+            (unsigned char)socksreq[1]);
+      return CURLE_COULDNT_CONNECT;
+    case 93:
+      failf(data,
+            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+            ", request rejected because the client program and identd "
+            "report different user-ids.",
+            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+            (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
+            (unsigned char)socksreq[1]);
+      return CURLE_COULDNT_CONNECT;
+    default:
+      failf(data,
+            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+            ", Unknown.",
+            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+            (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
+            (unsigned char)socksreq[1]);
+      return CURLE_COULDNT_CONNECT;
+    }
+  }
+
+  (void)curlx_nonblock(sock, TRUE);
+
+  return CURLE_OK; /* Proxy was successful! */
+}
+
+/*
+ * This function logs in to a SOCKS5 proxy and sends the specifics to the final
+ * destination server.
+ */
+CURLcode Curl_SOCKS5(const char *proxy_name,
+                     const char *proxy_password,
+                     const char *hostname,
+                     int remote_port,
+                     int sockindex,
+                     struct connectdata *conn)
+{
+  /*
+    According to the RFC1928, section "6.  Replies". This is what a SOCK5
+    replies:
+
+        +----+-----+-------+------+----------+----------+
+        |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
+        +----+-----+-------+------+----------+----------+
+        | 1  |  1  | X'00' |  1   | Variable |    2     |
+        +----+-----+-------+------+----------+----------+
+
+    Where:
+
+    o  VER    protocol version: X'05'
+    o  REP    Reply field:
+    o  X'00' succeeded
+  */
+
+  unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
+  ssize_t actualread;
+  ssize_t written;
+  int result;
+  CURLcode code;
+  curl_socket_t sock = conn->sock[sockindex];
+  struct SessionHandle *data = conn->data;
+  long timeout;
+  bool socks5_resolve_local = (conn->proxytype == CURLPROXY_SOCKS5)?TRUE:FALSE;
+  const size_t hostname_len = strlen(hostname);
+  ssize_t len = 0;
+
+  /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
+  if(!socks5_resolve_local && hostname_len > 255) {
+    infof(conn->data, "SOCKS5: server resolving disabled for hostnames of "
+          "length > 255 [actual len=%zu]\n", hostname_len);
+    socks5_resolve_local = TRUE;
+  }
+
+  /* get timeout */
+  timeout = Curl_timeleft(data, NULL, TRUE);
+
+  if(timeout < 0) {
+    /* time-out, bail out, go home */
+    failf(data, "Connection time-out");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  (void)curlx_nonblock(sock, TRUE);
+
+  /* wait until socket gets connected */
+  result = Curl_socket_ready(CURL_SOCKET_BAD, sock, timeout);
+
+  if(-1 == result) {
+    failf(conn->data, "SOCKS5: no connection here");
+    return CURLE_COULDNT_CONNECT;
+  }
+  else if(0 == result) {
+    failf(conn->data, "SOCKS5: connection timeout");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  if(result & CURL_CSELECT_ERR) {
+    failf(conn->data, "SOCKS5: error occurred during connection");
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  socksreq[0] = 5; /* version */
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  socksreq[1] = (char)(proxy_name ? 3 : 2); /* number of methods (below) */
+  socksreq[2] = 0; /* no authentication */
+  socksreq[3] = 1; /* GSS-API */
+  socksreq[4] = 2; /* username/password */
+#else
+  socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
+  socksreq[2] = 0; /* no authentication */
+  socksreq[3] = 2; /* username/password */
+#endif
+
+  (void)curlx_nonblock(sock, FALSE);
+
+  code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
+                          &written);
+  if(code || (written != (2 + (int)socksreq[1]))) {
+    failf(data, "Unable to send initial SOCKS5 request.");
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  (void)curlx_nonblock(sock, TRUE);
+
+  result = Curl_socket_ready(sock, CURL_SOCKET_BAD, timeout);
+
+  if(-1 == result) {
+    failf(conn->data, "SOCKS5 nothing to read");
+    return CURLE_COULDNT_CONNECT;
+  }
+  else if(0 == result) {
+    failf(conn->data, "SOCKS5 read timeout");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  if(result & CURL_CSELECT_ERR) {
+    failf(conn->data, "SOCKS5 read error occurred");
+    return CURLE_RECV_ERROR;
+  }
+
+  (void)curlx_nonblock(sock, FALSE);
+
+  result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
+  if(result || (actualread != 2)) {
+    failf(data, "Unable to receive initial SOCKS5 response.");
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(socksreq[0] != 5) {
+    failf(data, "Received invalid version in initial SOCKS5 response.");
+    return CURLE_COULDNT_CONNECT;
+  }
+  if(socksreq[1] == 0) {
+    /* Nothing to do, no authentication needed */
+    ;
+  }
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  else if(socksreq[1] == 1) {
+    code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
+    if(code) {
+      failf(data, "Unable to negotiate SOCKS5 GSS-API context.");
+      return CURLE_COULDNT_CONNECT;
+    }
+  }
+#endif
+  else if(socksreq[1] == 2) {
+    /* Needs user name and password */
+    size_t proxy_name_len, proxy_password_len;
+    if(proxy_name && proxy_password) {
+      proxy_name_len = strlen(proxy_name);
+      proxy_password_len = strlen(proxy_password);
+    }
+    else {
+      proxy_name_len = 0;
+      proxy_password_len = 0;
+    }
+
+    /*   username/password request looks like
+     * +----+------+----------+------+----------+
+     * |VER | ULEN |  UNAME   | PLEN |  PASSWD  |
+     * +----+------+----------+------+----------+
+     * | 1  |  1   | 1 to 255 |  1   | 1 to 255 |
+     * +----+------+----------+------+----------+
+     */
+    len = 0;
+    socksreq[len++] = 1;    /* username/pw subnegotiation version */
+    socksreq[len++] = (unsigned char) proxy_name_len;
+    if(proxy_name && proxy_name_len)
+      memcpy(socksreq + len, proxy_name, proxy_name_len);
+    len += proxy_name_len;
+    socksreq[len++] = (unsigned char) proxy_password_len;
+    if(proxy_password && proxy_password_len)
+      memcpy(socksreq + len, proxy_password, proxy_password_len);
+    len += proxy_password_len;
+
+    code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
+    if(code || (len != written)) {
+      failf(data, "Failed to send SOCKS5 sub-negotiation request.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
+    if(result || (actualread != 2)) {
+      failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    /* ignore the first (VER) byte */
+    if(socksreq[1] != 0) { /* status */
+      failf(data, "User was rejected by the SOCKS5 server (%d %d).",
+            socksreq[0], socksreq[1]);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    /* Everything is good so far, user was authenticated! */
+  }
+  else {
+    /* error */
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+    if(socksreq[1] == 255) {
+#else
+    if(socksreq[1] == 1) {
+      failf(data,
+            "SOCKS5 GSSAPI per-message authentication is not supported.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    else if(socksreq[1] == 255) {
+#endif
+      if(!proxy_name || !*proxy_name) {
+        failf(data,
+              "No authentication method was acceptable. (It is quite likely"
+              " that the SOCKS5 server wanted a username/password, since none"
+              " was supplied to the server on this connection.)");
+      }
+      else {
+        failf(data, "No authentication method was acceptable.");
+      }
+      return CURLE_COULDNT_CONNECT;
+    }
+    else {
+      failf(data,
+            "Undocumented SOCKS5 mode attempted to be used by server.");
+      return CURLE_COULDNT_CONNECT;
+    }
+  }
+
+  /* Authentication is complete, now specify destination to the proxy */
+  len = 0;
+  socksreq[len++] = 5; /* version (SOCKS5) */
+  socksreq[len++] = 1; /* connect */
+  socksreq[len++] = 0; /* must be zero */
+
+  if(!socks5_resolve_local) {
+    socksreq[len++] = 3; /* ATYP: domain name = 3 */
+    socksreq[len++] = (char) hostname_len; /* address length */
+    memcpy(&socksreq[len], hostname, hostname_len); /* address str w/o NULL */
+    len += hostname_len;
+  }
+  else {
+    struct Curl_dns_entry *dns;
+    Curl_addrinfo *hp = NULL;
+    int rc = Curl_resolv(conn, hostname, remote_port, &dns);
+
+    if(rc == CURLRESOLV_ERROR)
+      return CURLE_COULDNT_RESOLVE_HOST;
+
+    if(rc == CURLRESOLV_PENDING) {
+      /* this requires that we're in "wait for resolve" state */
+      code = Curl_resolver_wait_resolv(conn, &dns);
+      if(code)
+        return code;
+    }
+
+    /*
+     * We cannot use 'hostent' as a struct that Curl_resolv() returns.  It
+     * returns a Curl_addrinfo pointer that may not always look the same.
+     */
+    if(dns)
+      hp=dns->addr;
+    if(hp) {
+      struct sockaddr_in *saddr_in;
+#ifdef ENABLE_IPV6
+      struct sockaddr_in6 *saddr_in6;
+#endif
+      int i;
+
+      if(hp->ai_family == AF_INET) {
+        socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
+
+        saddr_in = (struct sockaddr_in*)(void*)hp->ai_addr;
+        for(i = 0; i < 4; i++) {
+          socksreq[len++] = ((unsigned char*)&saddr_in->sin_addr.s_addr)[i];
+          infof(data, "%d\n", socksreq[len-1]);
+        }
+      }
+#ifdef ENABLE_IPV6
+      else if(hp->ai_family == AF_INET6) {
+        socksreq[len++] = 4; /* ATYP: IPv6 = 4 */
+
+        saddr_in6 = (struct sockaddr_in6*)(void*)hp->ai_addr;
+        for(i = 0; i < 16; i++) {
+          socksreq[len++] = ((unsigned char*)&saddr_in6->sin6_addr.s6_addr)[i];
+        }
+      }
+#endif
+      else
+        hp = NULL; /* fail! */
+
+      Curl_resolv_unlock(data, dns); /* not used anymore from now on */
+    }
+    if(!hp) {
+      failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.",
+            hostname);
+      return CURLE_COULDNT_RESOLVE_HOST;
+    }
+  }
+
+  socksreq[len++] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
+  socksreq[len++] = (unsigned char)(remote_port & 0xff);        /* PORT LSB */
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  if(conn->socks5_gssapi_enctype) {
+    failf(data, "SOCKS5 GSS-API protection not yet implemented.");
+  }
+  else
+#endif
+    code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
+
+  if(code || (len != written)) {
+    failf(data, "Failed to send SOCKS5 connect request.");
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  len = 10; /* minimum packet size is 10 */
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  if(conn->socks5_gssapi_enctype) {
+    failf(data, "SOCKS5 GSS-API protection not yet implemented.");
+  }
+  else
+#endif
+    result = Curl_blockread_all(conn, sock, (char *)socksreq,
+                                len, &actualread);
+
+  if(result || (len != actualread)) {
+    failf(data, "Failed to receive SOCKS5 connect request ack.");
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(socksreq[0] != 5) { /* version */
+    failf(data,
+          "SOCKS5 reply has wrong version, version should be 5.");
+    return CURLE_COULDNT_CONNECT;
+  }
+  if(socksreq[1] != 0) { /* Anything besides 0 is an error */
+    if(socksreq[3] == 1) {
+      failf(data,
+            "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
+            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+            (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
+            (unsigned char)socksreq[1]);
+    }
+    else if(socksreq[3] == 3) {
+      failf(data,
+            "Can't complete SOCKS5 connection to %s:%d. (%d)",
+            hostname,
+            (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
+            (unsigned char)socksreq[1]);
+    }
+    else if(socksreq[3] == 4) {
+      failf(data,
+            "Can't complete SOCKS5 connection to %02x%02x:%02x%02x:"
+            "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%d. (%d)",
+            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+            (unsigned char)socksreq[8], (unsigned char)socksreq[9],
+            (unsigned char)socksreq[10], (unsigned char)socksreq[11],
+            (unsigned char)socksreq[12], (unsigned char)socksreq[13],
+            (unsigned char)socksreq[14], (unsigned char)socksreq[15],
+            (unsigned char)socksreq[16], (unsigned char)socksreq[17],
+            (unsigned char)socksreq[18], (unsigned char)socksreq[19],
+            (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
+            (unsigned char)socksreq[1]);
+    }
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  /* Fix: in general, returned BND.ADDR is variable length parameter by RFC
+     1928, so the reply packet should be read until the end to avoid errors at
+     subsequent protocol level.
+
+    +----+-----+-------+------+----------+----------+
+    |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
+    +----+-----+-------+------+----------+----------+
+    | 1  |  1  | X'00' |  1   | Variable |    2     |
+    +----+-----+-------+------+----------+----------+
+
+     ATYP:
+     o  IP v4 address: X'01', BND.ADDR = 4 byte
+     o  domain name:  X'03', BND.ADDR = [ 1 byte length, string ]
+     o  IP v6 address: X'04', BND.ADDR = 16 byte
+     */
+
+  /* Calculate real packet size */
+  if(socksreq[3] == 3) {
+    /* domain name */
+    int addrlen = (int) socksreq[4];
+    len = 5 + addrlen + 2;
+  }
+  else if(socksreq[3] == 4) {
+    /* IPv6 */
+    len = 4 + 16 + 2;
+  }
+
+  /* At this point we already read first 10 bytes */
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  if(!conn->socks5_gssapi_enctype) {
+    /* decrypt_gssapi_blockread already read the whole packet */
+#endif
+    if(len > 10) {
+      len -= 10;
+      result = Curl_blockread_all(conn, sock, (char *)&socksreq[10],
+                                  len, &actualread);
+      if(result || (len != actualread)) {
+        failf(data, "Failed to receive SOCKS5 connect request ack.");
+        return CURLE_COULDNT_CONNECT;
+      }
+    }
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  }
+#endif
+
+  (void)curlx_nonblock(sock, TRUE);
+  return CURLE_OK; /* Proxy was successful! */
+}
+
+#endif /* CURL_DISABLE_PROXY */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/socks.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/socks.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/socks.h	(revision 164)
@@ -0,0 +1,77 @@
+#ifndef HEADER_CURL_SOCKS_H
+#define HEADER_CURL_SOCKS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef CURL_DISABLE_PROXY
+#define Curl_SOCKS4(a,b,c,d,e,f) CURLE_NOT_BUILT_IN
+#define Curl_SOCKS5(a,b,c,d,e,f) CURLE_NOT_BUILT_IN
+#else
+/*
+ * Helper read-from-socket functions. Does the same as Curl_read() but it
+ * blocks until all bytes amount of buffersize will be read. No more, no less.
+ *
+ * This is STUPID BLOCKING behaviour which we frown upon, but right now this
+ * is what we have...
+ */
+int Curl_blockread_all(struct connectdata *conn,
+                       curl_socket_t sockfd,
+                       char *buf,
+                       ssize_t buffersize,
+                       ssize_t *n);
+
+/*
+ * This function logs in to a SOCKS4(a) proxy and sends the specifics to the
+ * final destination server.
+ */
+CURLcode Curl_SOCKS4(const char *proxy_name,
+                     const char *hostname,
+                     int remote_port,
+                     int sockindex,
+                     struct connectdata *conn,
+                     bool protocol4a);
+
+/*
+ * This function logs in to a SOCKS5 proxy and sends the specifics to the
+ * final destination server.
+ */
+CURLcode Curl_SOCKS5(const char *proxy_name,
+                     const char *proxy_password,
+                     const char *hostname,
+                     int remote_port,
+                     int sockindex,
+                     struct connectdata *conn);
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+/*
+ * This function handles the SOCKS5 GSS-API negotiation and initialisation
+ */
+CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
+                                      struct connectdata *conn);
+#endif
+
+#endif /* CURL_DISABLE_PROXY */
+
+#endif  /* HEADER_CURL_SOCKS_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/socks_gssapi.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/socks_gssapi.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/socks_gssapi.c	(revision 164)
@@ -0,0 +1,522 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_PROXY)
+
+#include "curl_gssapi.h"
+#include "urldata.h"
+#include "sendf.h"
+#include "connect.h"
+#include "timeval.h"
+#include "socks.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+static gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
+
+/*
+ * Helper GSS-API error functions.
+ */
+static int check_gss_err(struct SessionHandle *data,
+                         OM_uint32 major_status,
+                         OM_uint32 minor_status,
+                         const char* function)
+{
+  if(GSS_ERROR(major_status)) {
+    OM_uint32 maj_stat, min_stat;
+    OM_uint32 msg_ctx = 0;
+    gss_buffer_desc status_string;
+    char buf[1024];
+    size_t len;
+
+    len = 0;
+    msg_ctx = 0;
+    while(!msg_ctx) {
+      /* convert major status code (GSS-API error) to text */
+      maj_stat = gss_display_status(&min_stat, major_status,
+                                    GSS_C_GSS_CODE,
+                                    GSS_C_NULL_OID,
+                                    &msg_ctx, &status_string);
+      if(maj_stat == GSS_S_COMPLETE) {
+        if(sizeof(buf) > len + status_string.length + 1) {
+          strcpy(buf+len, (char*) status_string.value);
+          len += status_string.length;
+        }
+        gss_release_buffer(&min_stat, &status_string);
+        break;
+      }
+      gss_release_buffer(&min_stat, &status_string);
+    }
+    if(sizeof(buf) > len + 3) {
+      strcpy(buf+len, ".\n");
+      len += 2;
+    }
+    msg_ctx = 0;
+    while(!msg_ctx) {
+      /* convert minor status code (underlying routine error) to text */
+      maj_stat = gss_display_status(&min_stat, minor_status,
+                                    GSS_C_MECH_CODE,
+                                    GSS_C_NULL_OID,
+                                    &msg_ctx, &status_string);
+      if(maj_stat == GSS_S_COMPLETE) {
+        if(sizeof(buf) > len + status_string.length)
+          strcpy(buf+len, (char*) status_string.value);
+        gss_release_buffer(&min_stat, &status_string);
+        break;
+      }
+      gss_release_buffer(&min_stat, &status_string);
+    }
+    failf(data, "GSS-API error: %s failed:\n%s", function, buf);
+    return 1;
+  }
+
+  return 0;
+}
+
+CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
+                                      struct connectdata *conn)
+{
+  struct SessionHandle *data = conn->data;
+  curl_socket_t sock = conn->sock[sockindex];
+  CURLcode code;
+  ssize_t actualread;
+  ssize_t written;
+  int result;
+  OM_uint32 gss_major_status, gss_minor_status, gss_status;
+  OM_uint32 gss_ret_flags;
+  int gss_conf_state, gss_enc;
+  gss_buffer_desc  service = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc  gss_send_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc  gss_recv_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc  gss_w_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc* gss_token = GSS_C_NO_BUFFER;
+  gss_name_t       server = GSS_C_NO_NAME;
+  gss_name_t       gss_client_name = GSS_C_NO_NAME;
+  unsigned short   us_length;
+  char             *user=NULL;
+  unsigned char socksreq[4]; /* room for GSS-API exchange header only */
+  char *serviceptr = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE];
+
+  /*   GSS-API request looks like
+   * +----+------+-----+----------------+
+   * |VER | MTYP | LEN |     TOKEN      |
+   * +----+------+----------------------+
+   * | 1  |  1   |  2  | up to 2^16 - 1 |
+   * +----+------+-----+----------------+
+   */
+
+  /* prepare service name */
+  if(strchr(serviceptr, '/')) {
+    service.value = malloc(strlen(serviceptr));
+    if(!service.value)
+      return CURLE_OUT_OF_MEMORY;
+    service.length = strlen(serviceptr);
+    memcpy(service.value, serviceptr, service.length);
+
+    gss_major_status = gss_import_name(&gss_minor_status, &service,
+                                       (gss_OID) GSS_C_NULL_OID, &server);
+  }
+  else {
+    service.value = malloc(strlen(serviceptr) +strlen(conn->proxy.name)+2);
+    if(!service.value)
+      return CURLE_OUT_OF_MEMORY;
+    service.length = strlen(serviceptr) +strlen(conn->proxy.name)+1;
+    snprintf(service.value, service.length+1, "%s@%s",
+             serviceptr, conn->proxy.name);
+
+    gss_major_status = gss_import_name(&gss_minor_status, &service,
+                                       GSS_C_NT_HOSTBASED_SERVICE, &server);
+  }
+
+  gss_release_buffer(&gss_status, &service); /* clear allocated memory */
+
+  if(check_gss_err(data, gss_major_status,
+                   gss_minor_status, "gss_import_name()")) {
+    failf(data, "Failed to create service name.");
+    gss_release_name(&gss_status, &server);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  /* As long as we need to keep sending some context info, and there's no  */
+  /* errors, keep sending it...                                            */
+  for(;;) {
+    gss_major_status = Curl_gss_init_sec_context(data,
+                                                 &gss_minor_status,
+                                                 &gss_context,
+                                                 server,
+                                                 &Curl_krb5_mech_oid,
+                                                 NULL,
+                                                 gss_token,
+                                                 &gss_send_token,
+                                                 TRUE,
+                                                 &gss_ret_flags);
+
+    if(gss_token != GSS_C_NO_BUFFER)
+      gss_release_buffer(&gss_status, &gss_recv_token);
+    if(check_gss_err(data, gss_major_status,
+                     gss_minor_status, "gss_init_sec_context")) {
+      gss_release_name(&gss_status, &server);
+      gss_release_buffer(&gss_status, &gss_recv_token);
+      gss_release_buffer(&gss_status, &gss_send_token);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      failf(data, "Failed to initial GSS-API token.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    if(gss_send_token.length != 0) {
+      socksreq[0] = 1;    /* GSS-API subnegotiation version */
+      socksreq[1] = 1;    /* authentication message type */
+      us_length = htons((short)gss_send_token.length);
+      memcpy(socksreq+2, &us_length, sizeof(short));
+
+      code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+      if(code || (4 != written)) {
+        failf(data, "Failed to send GSS-API authentication request.");
+        gss_release_name(&gss_status, &server);
+        gss_release_buffer(&gss_status, &gss_recv_token);
+        gss_release_buffer(&gss_status, &gss_send_token);
+        gss_delete_sec_context(&gss_status, &gss_context, NULL);
+        return CURLE_COULDNT_CONNECT;
+      }
+
+      code = Curl_write_plain(conn, sock, (char *)gss_send_token.value,
+                              gss_send_token.length, &written);
+
+      if(code || ((ssize_t)gss_send_token.length != written)) {
+        failf(data, "Failed to send GSS-API authentication token.");
+        gss_release_name(&gss_status, &server);
+        gss_release_buffer(&gss_status, &gss_recv_token);
+        gss_release_buffer(&gss_status, &gss_send_token);
+        gss_delete_sec_context(&gss_status, &gss_context, NULL);
+        return CURLE_COULDNT_CONNECT;
+      }
+
+    }
+
+    gss_release_buffer(&gss_status, &gss_send_token);
+    gss_release_buffer(&gss_status, &gss_recv_token);
+    if(gss_major_status != GSS_S_CONTINUE_NEEDED) break;
+
+    /* analyse response */
+
+    /*   GSS-API response looks like
+     * +----+------+-----+----------------+
+     * |VER | MTYP | LEN |     TOKEN      |
+     * +----+------+----------------------+
+     * | 1  |  1   |  2  | up to 2^16 - 1 |
+     * +----+------+-----+----------------+
+     */
+
+    result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
+    if(result || (actualread != 4)) {
+      failf(data, "Failed to receive GSS-API authentication response.");
+      gss_release_name(&gss_status, &server);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    /* ignore the first (VER) byte */
+    if(socksreq[1] == 255) { /* status / message type */
+      failf(data, "User was rejected by the SOCKS5 server (%d %d).",
+            socksreq[0], socksreq[1]);
+      gss_release_name(&gss_status, &server);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    if(socksreq[1] != 1) { /* status / messgae type */
+      failf(data, "Invalid GSS-API authentication response type (%d %d).",
+            socksreq[0], socksreq[1]);
+      gss_release_name(&gss_status, &server);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    memcpy(&us_length, socksreq+2, sizeof(short));
+    us_length = ntohs(us_length);
+
+    gss_recv_token.length=us_length;
+    gss_recv_token.value=malloc(us_length);
+    if(!gss_recv_token.value) {
+      failf(data,
+            "Could not allocate memory for GSS-API authentication "
+            "response token.");
+      gss_release_name(&gss_status, &server);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value,
+                              gss_recv_token.length, &actualread);
+
+    if(result || (actualread != us_length)) {
+      failf(data, "Failed to receive GSS-API authentication token.");
+      gss_release_name(&gss_status, &server);
+      gss_release_buffer(&gss_status, &gss_recv_token);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    gss_token = &gss_recv_token;
+  }
+
+  gss_release_name(&gss_status, &server);
+
+  /* Everything is good so far, user was authenticated! */
+  gss_major_status = gss_inquire_context (&gss_minor_status, gss_context,
+                                          &gss_client_name, NULL, NULL, NULL,
+                                          NULL, NULL, NULL);
+  if(check_gss_err(data, gss_major_status,
+                   gss_minor_status, "gss_inquire_context")) {
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    gss_release_name(&gss_status, &gss_client_name);
+    failf(data, "Failed to determine user name.");
+    return CURLE_COULDNT_CONNECT;
+  }
+  gss_major_status = gss_display_name(&gss_minor_status, gss_client_name,
+                                      &gss_send_token, NULL);
+  if(check_gss_err(data, gss_major_status,
+                   gss_minor_status, "gss_display_name")) {
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    gss_release_name(&gss_status, &gss_client_name);
+    gss_release_buffer(&gss_status, &gss_send_token);
+    failf(data, "Failed to determine user name.");
+    return CURLE_COULDNT_CONNECT;
+  }
+  user=malloc(gss_send_token.length+1);
+  if(!user) {
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    gss_release_name(&gss_status, &gss_client_name);
+    gss_release_buffer(&gss_status, &gss_send_token);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  memcpy(user, gss_send_token.value, gss_send_token.length);
+  user[gss_send_token.length] = '\0';
+  gss_release_name(&gss_status, &gss_client_name);
+  gss_release_buffer(&gss_status, &gss_send_token);
+  infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",user);
+  free(user);
+  user=NULL;
+
+  /* Do encryption */
+  socksreq[0] = 1;    /* GSS-API subnegotiation version */
+  socksreq[1] = 2;    /* encryption message type */
+
+  gss_enc = 0; /* no data protection */
+  /* do confidentiality protection if supported */
+  if(gss_ret_flags & GSS_C_CONF_FLAG)
+    gss_enc = 2;
+  /* else do integrity protection */
+  else if(gss_ret_flags & GSS_C_INTEG_FLAG)
+    gss_enc = 1;
+
+  infof(data, "SOCKS5 server supports GSS-API %s data protection.\n",
+        (gss_enc==0)?"no":((gss_enc==1)?"integrity":"confidentiality"));
+  /* force for the moment to no data protection */
+  gss_enc = 0;
+  /*
+   * Sending the encryption type in clear seems wrong. It should be
+   * protected with gss_seal()/gss_wrap(). See RFC1961 extract below
+   * The NEC reference implementations on which this is based is
+   * therefore at fault
+   *
+   *  +------+------+------+.......................+
+   *  + ver  | mtyp | len  |   token               |
+   *  +------+------+------+.......................+
+   *  + 0x01 | 0x02 | 0x02 | up to 2^16 - 1 octets |
+   *  +------+------+------+.......................+
+   *
+   *   Where:
+   *
+   *  - "ver" is the protocol version number, here 1 to represent the
+   *    first version of the SOCKS/GSS-API protocol
+   *
+   *  - "mtyp" is the message type, here 2 to represent a protection
+   *    -level negotiation message
+   *
+   *  - "len" is the length of the "token" field in octets
+   *
+   *  - "token" is the GSS-API encapsulated protection level
+   *
+   * The token is produced by encapsulating an octet containing the
+   * required protection level using gss_seal()/gss_wrap() with conf_req
+   * set to FALSE.  The token is verified using gss_unseal()/
+   * gss_unwrap().
+   *
+   */
+  if(data->set.socks5_gssapi_nec) {
+    us_length = htons((short)1);
+    memcpy(socksreq+2, &us_length, sizeof(short));
+  }
+  else {
+    gss_send_token.length = 1;
+    gss_send_token.value = malloc(1);
+    if(!gss_send_token.value) {
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    memcpy(gss_send_token.value, &gss_enc, 1);
+
+    gss_major_status = gss_wrap(&gss_minor_status, gss_context, 0,
+                                GSS_C_QOP_DEFAULT, &gss_send_token,
+                                &gss_conf_state, &gss_w_token);
+
+    if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_wrap")) {
+      gss_release_buffer(&gss_status, &gss_send_token);
+      gss_release_buffer(&gss_status, &gss_w_token);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      failf(data, "Failed to wrap GSS-API encryption value into token.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    gss_release_buffer(&gss_status, &gss_send_token);
+
+    us_length = htons((short)gss_w_token.length);
+    memcpy(socksreq+2, &us_length, sizeof(short));
+  }
+
+  code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+  if(code  || (4 != written)) {
+    failf(data, "Failed to send GSS-API encryption request.");
+    gss_release_buffer(&gss_status, &gss_w_token);
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(data->set.socks5_gssapi_nec) {
+    memcpy(socksreq, &gss_enc, 1);
+    code = Curl_write_plain(conn, sock, socksreq, 1, &written);
+    if(code || ( 1 != written)) {
+      failf(data, "Failed to send GSS-API encryption type.");
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+  }
+  else {
+    code = Curl_write_plain(conn, sock, (char *)gss_w_token.value,
+                            gss_w_token.length, &written);
+    if(code || ((ssize_t)gss_w_token.length != written)) {
+      failf(data, "Failed to send GSS-API encryption type.");
+      gss_release_buffer(&gss_status, &gss_w_token);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+    gss_release_buffer(&gss_status, &gss_w_token);
+  }
+
+  result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
+  if(result || (actualread != 4)) {
+    failf(data, "Failed to receive GSS-API encryption response.");
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  /* ignore the first (VER) byte */
+  if(socksreq[1] == 255) { /* status / message type */
+    failf(data, "User was rejected by the SOCKS5 server (%d %d).",
+          socksreq[0], socksreq[1]);
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(socksreq[1] != 2) { /* status / messgae type */
+    failf(data, "Invalid GSS-API encryption response type (%d %d).",
+          socksreq[0], socksreq[1]);
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  memcpy(&us_length, socksreq+2, sizeof(short));
+  us_length = ntohs(us_length);
+
+  gss_recv_token.length= us_length;
+  gss_recv_token.value=malloc(gss_recv_token.length);
+  if(!gss_recv_token.value) {
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value,
+                            gss_recv_token.length, &actualread);
+
+  if(result || (actualread != us_length)) {
+    failf(data, "Failed to receive GSS-API encryptrion type.");
+    gss_release_buffer(&gss_status, &gss_recv_token);
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(!data->set.socks5_gssapi_nec) {
+    gss_major_status = gss_unwrap(&gss_minor_status, gss_context,
+                                  &gss_recv_token, &gss_w_token,
+                                  0, GSS_C_QOP_DEFAULT);
+
+    if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_unwrap")) {
+      gss_release_buffer(&gss_status, &gss_recv_token);
+      gss_release_buffer(&gss_status, &gss_w_token);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      failf(data, "Failed to unwrap GSS-API encryption value into token.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    gss_release_buffer(&gss_status, &gss_recv_token);
+
+    if(gss_w_token.length != 1) {
+      failf(data, "Invalid GSS-API encryption response length (%d).",
+            gss_w_token.length);
+      gss_release_buffer(&gss_status, &gss_w_token);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    memcpy(socksreq, gss_w_token.value, gss_w_token.length);
+    gss_release_buffer(&gss_status, &gss_w_token);
+  }
+  else {
+    if(gss_recv_token.length != 1) {
+      failf(data, "Invalid GSS-API encryption response length (%d).",
+            gss_recv_token.length);
+      gss_release_buffer(&gss_status, &gss_recv_token);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    memcpy(socksreq, gss_recv_token.value, gss_recv_token.length);
+    gss_release_buffer(&gss_status, &gss_recv_token);
+  }
+
+  infof(data, "SOCKS5 access with%s protection granted.\n",
+        (socksreq[0]==0)?"out GSS-API data":
+        ((socksreq[0]==1)?" GSS-API integrity":" GSS-API confidentiality"));
+
+  conn->socks5_gssapi_enctype = socksreq[0];
+  if(socksreq[0] == 0)
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+
+  return CURLE_OK;
+}
+
+#endif /* HAVE_GSSAPI && !CURL_DISABLE_PROXY */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/socks_sspi.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/socks_sspi.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/socks_sspi.c	(revision 164)
@@ -0,0 +1,601 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_PROXY)
+
+#include "urldata.h"
+#include "sendf.h"
+#include "connect.h"
+#include "strerror.h"
+#include "timeval.h"
+#include "socks.h"
+#include "curl_sspi.h"
+#include "curl_multibyte.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Helper sspi error functions.
+ */
+static int check_sspi_err(struct connectdata *conn,
+                          SECURITY_STATUS status,
+                          const char* function)
+{
+  if(status != SEC_E_OK &&
+     status != SEC_I_COMPLETE_AND_CONTINUE &&
+     status != SEC_I_COMPLETE_NEEDED &&
+     status != SEC_I_CONTINUE_NEEDED) {
+    failf(conn->data, "SSPI error: %s failed: %s", function,
+          Curl_sspi_strerror(conn, status));
+    return 1;
+  }
+  return 0;
+}
+
+/* This is the SSPI-using version of this function */
+CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
+                                      struct connectdata *conn)
+{
+  struct SessionHandle *data = conn->data;
+  curl_socket_t sock = conn->sock[sockindex];
+  CURLcode code;
+  ssize_t actualread;
+  ssize_t written;
+  int result;
+  /* Needs GSS-API authentication */
+  SECURITY_STATUS status;
+  unsigned long sspi_ret_flags = 0;
+  int gss_enc;
+  SecBuffer sspi_send_token, sspi_recv_token, sspi_w_token[3];
+  SecBufferDesc input_desc, output_desc, wrap_desc;
+  SecPkgContext_Sizes sspi_sizes;
+  CredHandle cred_handle;
+  CtxtHandle sspi_context;
+  PCtxtHandle context_handle = NULL;
+  SecPkgCredentials_Names names;
+  TimeStamp expiry;
+  char *service_name = NULL;
+  unsigned short us_length;
+  unsigned long qop;
+  unsigned char socksreq[4]; /* room for GSS-API exchange header only */
+  char *service = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE];
+
+  /*   GSS-API request looks like
+   * +----+------+-----+----------------+
+   * |VER | MTYP | LEN |     TOKEN      |
+   * +----+------+----------------------+
+   * | 1  |  1   |  2  | up to 2^16 - 1 |
+   * +----+------+-----+----------------+
+   */
+
+  /* prepare service name */
+  if(strchr(service, '/')) {
+    service_name = malloc(strlen(service));
+    if(!service_name)
+      return CURLE_OUT_OF_MEMORY;
+    memcpy(service_name, service, strlen(service));
+  }
+  else {
+    service_name = malloc(strlen(service) + strlen(conn->proxy.name) + 2);
+    if(!service_name)
+      return CURLE_OUT_OF_MEMORY;
+    snprintf(service_name, strlen(service) +strlen(conn->proxy.name)+2,
+             "%s/%s", service, conn->proxy.name);
+  }
+
+  input_desc.cBuffers = 1;
+  input_desc.pBuffers = &sspi_recv_token;
+  input_desc.ulVersion = SECBUFFER_VERSION;
+
+  sspi_recv_token.BufferType = SECBUFFER_TOKEN;
+  sspi_recv_token.cbBuffer = 0;
+  sspi_recv_token.pvBuffer = NULL;
+
+  output_desc.cBuffers = 1;
+  output_desc.pBuffers = &sspi_send_token;
+  output_desc.ulVersion = SECBUFFER_VERSION;
+
+  sspi_send_token.BufferType = SECBUFFER_TOKEN;
+  sspi_send_token.cbBuffer = 0;
+  sspi_send_token.pvBuffer = NULL;
+
+  wrap_desc.cBuffers = 3;
+  wrap_desc.pBuffers = sspi_w_token;
+  wrap_desc.ulVersion = SECBUFFER_VERSION;
+
+  cred_handle.dwLower = 0;
+  cred_handle.dwUpper = 0;
+
+  status = s_pSecFn->AcquireCredentialsHandle(NULL,
+                                              (TCHAR *) TEXT("Kerberos"),
+                                              SECPKG_CRED_OUTBOUND,
+                                              NULL,
+                                              NULL,
+                                              NULL,
+                                              NULL,
+                                              &cred_handle,
+                                              &expiry);
+
+  if(check_sspi_err(conn, status, "AcquireCredentialsHandle")) {
+    failf(data, "Failed to acquire credentials.");
+    free(service_name);
+    s_pSecFn->FreeCredentialsHandle(&cred_handle);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  /* As long as we need to keep sending some context info, and there's no  */
+  /* errors, keep sending it...                                            */
+  for(;;) {
+    TCHAR *sname;
+
+    sname = Curl_convert_UTF8_to_tchar(service_name);
+    if(!sname)
+      return CURLE_OUT_OF_MEMORY;
+
+    status = s_pSecFn->InitializeSecurityContext(&cred_handle,
+                                                 context_handle,
+                                                 sname,
+                                                 ISC_REQ_MUTUAL_AUTH |
+                                                 ISC_REQ_ALLOCATE_MEMORY |
+                                                 ISC_REQ_CONFIDENTIALITY |
+                                                 ISC_REQ_REPLAY_DETECT,
+                                                 0,
+                                                 SECURITY_NATIVE_DREP,
+                                                 &input_desc,
+                                                 0,
+                                                 &sspi_context,
+                                                 &output_desc,
+                                                 &sspi_ret_flags,
+                                                 &expiry);
+
+    Curl_unicodefree(sname);
+
+    if(sspi_recv_token.pvBuffer) {
+      s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+      sspi_recv_token.pvBuffer = NULL;
+      sspi_recv_token.cbBuffer = 0;
+    }
+
+    if(check_sspi_err(conn, status, "InitializeSecurityContext")) {
+      free(service_name);
+      s_pSecFn->FreeCredentialsHandle(&cred_handle);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      if(sspi_recv_token.pvBuffer)
+        s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+      failf(data, "Failed to initialise security context.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    if(sspi_send_token.cbBuffer != 0) {
+      socksreq[0] = 1;    /* GSS-API subnegotiation version */
+      socksreq[1] = 1;    /* authentication message type */
+      us_length = htons((short)sspi_send_token.cbBuffer);
+      memcpy(socksreq+2, &us_length, sizeof(short));
+
+      code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+      if(code || (4 != written)) {
+        failf(data, "Failed to send SSPI authentication request.");
+        free(service_name);
+        if(sspi_send_token.pvBuffer)
+          s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+        if(sspi_recv_token.pvBuffer)
+          s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+        s_pSecFn->FreeCredentialsHandle(&cred_handle);
+        s_pSecFn->DeleteSecurityContext(&sspi_context);
+        return CURLE_COULDNT_CONNECT;
+      }
+
+      code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
+                              sspi_send_token.cbBuffer, &written);
+      if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
+        failf(data, "Failed to send SSPI authentication token.");
+        free(service_name);
+        if(sspi_send_token.pvBuffer)
+          s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+        if(sspi_recv_token.pvBuffer)
+          s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+        s_pSecFn->FreeCredentialsHandle(&cred_handle);
+        s_pSecFn->DeleteSecurityContext(&sspi_context);
+        return CURLE_COULDNT_CONNECT;
+      }
+
+    }
+
+    if(sspi_send_token.pvBuffer) {
+      s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+      sspi_send_token.pvBuffer = NULL;
+    }
+    sspi_send_token.cbBuffer = 0;
+
+    if(sspi_recv_token.pvBuffer) {
+      s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+      sspi_recv_token.pvBuffer = NULL;
+    }
+    sspi_recv_token.cbBuffer = 0;
+
+    if(status != SEC_I_CONTINUE_NEEDED)
+      break;
+
+    /* analyse response */
+
+    /*   GSS-API response looks like
+     * +----+------+-----+----------------+
+     * |VER | MTYP | LEN |     TOKEN      |
+     * +----+------+----------------------+
+     * | 1  |  1   |  2  | up to 2^16 - 1 |
+     * +----+------+-----+----------------+
+     */
+
+    result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
+    if(result || (actualread != 4)) {
+      failf(data, "Failed to receive SSPI authentication response.");
+      free(service_name);
+      s_pSecFn->FreeCredentialsHandle(&cred_handle);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    /* ignore the first (VER) byte */
+    if(socksreq[1] == 255) { /* status / message type */
+      failf(data, "User was rejected by the SOCKS5 server (%u %u).",
+            (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
+      free(service_name);
+      s_pSecFn->FreeCredentialsHandle(&cred_handle);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    if(socksreq[1] != 1) { /* status / messgae type */
+      failf(data, "Invalid SSPI authentication response type (%u %u).",
+            (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
+      free(service_name);
+      s_pSecFn->FreeCredentialsHandle(&cred_handle);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    memcpy(&us_length, socksreq+2, sizeof(short));
+    us_length = ntohs(us_length);
+
+    sspi_recv_token.cbBuffer = us_length;
+    sspi_recv_token.pvBuffer = malloc(us_length);
+
+    if(!sspi_recv_token.pvBuffer) {
+      free(service_name);
+      s_pSecFn->FreeCredentialsHandle(&cred_handle);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    result = Curl_blockread_all(conn, sock, (char *)sspi_recv_token.pvBuffer,
+                                sspi_recv_token.cbBuffer, &actualread);
+
+    if(result || (actualread != us_length)) {
+      failf(data, "Failed to receive SSPI authentication token.");
+      free(service_name);
+      if(sspi_recv_token.pvBuffer)
+        s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+      s_pSecFn->FreeCredentialsHandle(&cred_handle);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    context_handle = &sspi_context;
+  }
+
+  free(service_name);
+
+  /* Everything is good so far, user was authenticated! */
+  status = s_pSecFn->QueryCredentialsAttributes(&cred_handle,
+                                                SECPKG_CRED_ATTR_NAMES,
+                                                &names);
+  s_pSecFn->FreeCredentialsHandle(&cred_handle);
+  if(check_sspi_err(conn, status, "QueryCredentialAttributes")) {
+    s_pSecFn->DeleteSecurityContext(&sspi_context);
+    s_pSecFn->FreeContextBuffer(names.sUserName);
+    failf(data, "Failed to determine user name.");
+    return CURLE_COULDNT_CONNECT;
+  }
+  infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",
+        names.sUserName);
+  s_pSecFn->FreeContextBuffer(names.sUserName);
+
+  /* Do encryption */
+  socksreq[0] = 1;    /* GSS-API subnegotiation version */
+  socksreq[1] = 2;    /* encryption message type */
+
+  gss_enc = 0; /* no data protection */
+  /* do confidentiality protection if supported */
+  if(sspi_ret_flags & ISC_REQ_CONFIDENTIALITY)
+    gss_enc = 2;
+  /* else do integrity protection */
+  else if(sspi_ret_flags & ISC_REQ_INTEGRITY)
+    gss_enc = 1;
+
+  infof(data, "SOCKS5 server supports GSS-API %s data protection.\n",
+        (gss_enc==0)?"no":((gss_enc==1)?"integrity":"confidentiality") );
+  /* force to no data protection, avoid encryption/decryption for now */
+  gss_enc = 0;
+  /*
+   * Sending the encryption type in clear seems wrong. It should be
+   * protected with gss_seal()/gss_wrap(). See RFC1961 extract below
+   * The NEC reference implementations on which this is based is
+   * therefore at fault
+   *
+   *  +------+------+------+.......................+
+   *  + ver  | mtyp | len  |   token               |
+   *  +------+------+------+.......................+
+   *  + 0x01 | 0x02 | 0x02 | up to 2^16 - 1 octets |
+   *  +------+------+------+.......................+
+   *
+   *   Where:
+   *
+   *  - "ver" is the protocol version number, here 1 to represent the
+   *    first version of the SOCKS/GSS-API protocol
+   *
+   *  - "mtyp" is the message type, here 2 to represent a protection
+   *    -level negotiation message
+   *
+   *  - "len" is the length of the "token" field in octets
+   *
+   *  - "token" is the GSS-API encapsulated protection level
+   *
+   * The token is produced by encapsulating an octet containing the
+   * required protection level using gss_seal()/gss_wrap() with conf_req
+   * set to FALSE.  The token is verified using gss_unseal()/
+   * gss_unwrap().
+   *
+   */
+
+  if(data->set.socks5_gssapi_nec) {
+    us_length = htons((short)1);
+    memcpy(socksreq+2, &us_length, sizeof(short));
+  }
+  else {
+    status = s_pSecFn->QueryContextAttributes(&sspi_context,
+                                              SECPKG_ATTR_SIZES,
+                                              &sspi_sizes);
+    if(check_sspi_err(conn, status, "QueryContextAttributes")) {
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      failf(data, "Failed to query security context attributes.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    sspi_w_token[0].cbBuffer = sspi_sizes.cbSecurityTrailer;
+    sspi_w_token[0].BufferType = SECBUFFER_TOKEN;
+    sspi_w_token[0].pvBuffer = malloc(sspi_sizes.cbSecurityTrailer);
+
+    if(!sspi_w_token[0].pvBuffer) {
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    sspi_w_token[1].cbBuffer = 1;
+    sspi_w_token[1].pvBuffer = malloc(1);
+    if(!sspi_w_token[1].pvBuffer) {
+      s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    memcpy(sspi_w_token[1].pvBuffer, &gss_enc, 1);
+    sspi_w_token[2].BufferType = SECBUFFER_PADDING;
+    sspi_w_token[2].cbBuffer = sspi_sizes.cbBlockSize;
+    sspi_w_token[2].pvBuffer = malloc(sspi_sizes.cbBlockSize);
+    if(!sspi_w_token[2].pvBuffer) {
+      s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+      s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    status = s_pSecFn->EncryptMessage(&sspi_context,
+                                      KERB_WRAP_NO_ENCRYPT,
+                                      &wrap_desc,
+                                      0);
+    if(check_sspi_err(conn, status, "EncryptMessage")) {
+      s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+      s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+      s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      failf(data, "Failed to query security context attributes.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    sspi_send_token.cbBuffer = sspi_w_token[0].cbBuffer
+      + sspi_w_token[1].cbBuffer
+      + sspi_w_token[2].cbBuffer;
+    sspi_send_token.pvBuffer = malloc(sspi_send_token.cbBuffer);
+    if(!sspi_send_token.pvBuffer) {
+      s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+      s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+      s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    memcpy(sspi_send_token.pvBuffer, sspi_w_token[0].pvBuffer,
+           sspi_w_token[0].cbBuffer);
+    memcpy((PUCHAR) sspi_send_token.pvBuffer +(int)sspi_w_token[0].cbBuffer,
+           sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer);
+    memcpy((PUCHAR) sspi_send_token.pvBuffer
+           +sspi_w_token[0].cbBuffer
+           +sspi_w_token[1].cbBuffer,
+           sspi_w_token[2].pvBuffer, sspi_w_token[2].cbBuffer);
+
+    s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+    sspi_w_token[0].pvBuffer = NULL;
+    sspi_w_token[0].cbBuffer = 0;
+    s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+    sspi_w_token[1].pvBuffer = NULL;
+    sspi_w_token[1].cbBuffer = 0;
+    s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
+    sspi_w_token[2].pvBuffer = NULL;
+    sspi_w_token[2].cbBuffer = 0;
+
+    us_length = htons((short)sspi_send_token.cbBuffer);
+    memcpy(socksreq+2, &us_length, sizeof(short));
+  }
+
+  code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+  if(code || (4 != written)) {
+    failf(data, "Failed to send SSPI encryption request.");
+    if(sspi_send_token.pvBuffer)
+      s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+    s_pSecFn->DeleteSecurityContext(&sspi_context);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(data->set.socks5_gssapi_nec) {
+    memcpy(socksreq, &gss_enc, 1);
+    code = Curl_write_plain(conn, sock, (char *)socksreq, 1, &written);
+    if(code || (1 != written)) {
+      failf(data, "Failed to send SSPI encryption type.");
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+  }
+  else {
+    code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
+                            sspi_send_token.cbBuffer, &written);
+    if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
+      failf(data, "Failed to send SSPI encryption type.");
+      if(sspi_send_token.pvBuffer)
+        s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+    if(sspi_send_token.pvBuffer)
+      s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+  }
+
+  result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
+  if(result || (actualread != 4)) {
+    failf(data, "Failed to receive SSPI encryption response.");
+    s_pSecFn->DeleteSecurityContext(&sspi_context);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  /* ignore the first (VER) byte */
+  if(socksreq[1] == 255) { /* status / message type */
+    failf(data, "User was rejected by the SOCKS5 server (%u %u).",
+          (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
+    s_pSecFn->DeleteSecurityContext(&sspi_context);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(socksreq[1] != 2) { /* status / message type */
+    failf(data, "Invalid SSPI encryption response type (%u %u).",
+          (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
+    s_pSecFn->DeleteSecurityContext(&sspi_context);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  memcpy(&us_length, socksreq+2, sizeof(short));
+  us_length = ntohs(us_length);
+
+  sspi_w_token[0].cbBuffer = us_length;
+  sspi_w_token[0].pvBuffer = malloc(us_length);
+  if(!sspi_w_token[0].pvBuffer) {
+    s_pSecFn->DeleteSecurityContext(&sspi_context);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  result = Curl_blockread_all(conn, sock, (char *)sspi_w_token[0].pvBuffer,
+                              sspi_w_token[0].cbBuffer, &actualread);
+
+  if(result || (actualread != us_length)) {
+    failf(data, "Failed to receive SSPI encryption type.");
+    s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+    s_pSecFn->DeleteSecurityContext(&sspi_context);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+
+  if(!data->set.socks5_gssapi_nec) {
+    wrap_desc.cBuffers = 2;
+    sspi_w_token[0].BufferType = SECBUFFER_STREAM;
+    sspi_w_token[1].BufferType = SECBUFFER_DATA;
+    sspi_w_token[1].cbBuffer = 0;
+    sspi_w_token[1].pvBuffer = NULL;
+
+    status = s_pSecFn->DecryptMessage(&sspi_context,
+                                      &wrap_desc,
+                                      0,
+                                      &qop);
+
+    if(check_sspi_err(conn, status, "DecryptMessage")) {
+      if(sspi_w_token[0].pvBuffer)
+        s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+      if(sspi_w_token[1].pvBuffer)
+        s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      failf(data, "Failed to query security context attributes.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    if(sspi_w_token[1].cbBuffer != 1) {
+      failf(data, "Invalid SSPI encryption response length (%lu).",
+            (unsigned long)sspi_w_token[1].cbBuffer);
+      if(sspi_w_token[0].pvBuffer)
+        s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+      if(sspi_w_token[1].pvBuffer)
+        s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    memcpy(socksreq, sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer);
+    s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+    s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+  }
+  else {
+    if(sspi_w_token[0].cbBuffer != 1) {
+      failf(data, "Invalid SSPI encryption response length (%lu).",
+            (unsigned long)sspi_w_token[0].cbBuffer);
+      s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+    memcpy(socksreq, sspi_w_token[0].pvBuffer, sspi_w_token[0].cbBuffer);
+    s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+  }
+
+  infof(data, "SOCKS5 access with%s protection granted.\n",
+        (socksreq[0]==0)?"out GSS-API data":
+        ((socksreq[0]==1)?" GSS-API integrity":" GSS-API confidentiality"));
+
+  /* For later use if encryption is required
+     conn->socks5_gssapi_enctype = socksreq[0];
+     if(socksreq[0] != 0)
+       conn->socks5_sspi_context = sspi_context;
+     else {
+       s_pSecFn->DeleteSecurityContext(&sspi_context);
+       conn->socks5_sspi_context = sspi_context;
+     }
+  */
+  return CURLE_OK;
+}
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/lib/speedcheck.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/speedcheck.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/speedcheck.c	(revision 164)
@@ -0,0 +1,74 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "multiif.h"
+#include "speedcheck.h"
+
+void Curl_speedinit(struct SessionHandle *data)
+{
+  memset(&data->state.keeps_speed, 0, sizeof(struct timeval));
+}
+
+CURLcode Curl_speedcheck(struct SessionHandle *data,
+                         struct timeval now)
+{
+  if((data->progress.current_speed >= 0) &&
+     data->set.low_speed_time &&
+     (Curl_tvlong(data->state.keeps_speed) != 0) &&
+     (data->progress.current_speed < data->set.low_speed_limit)) {
+    long howlong = Curl_tvdiff(now, data->state.keeps_speed);
+    long nextcheck = (data->set.low_speed_time * 1000) - howlong;
+
+    /* We are now below the "low speed limit". If we are below it
+       for "low speed time" seconds we consider that enough reason
+       to abort the download. */
+    if(nextcheck <= 0) {
+      /* we have been this slow for long enough, now die */
+      failf(data,
+            "Operation too slow. "
+            "Less than %ld bytes/sec transferred the last %ld seconds",
+            data->set.low_speed_limit,
+            data->set.low_speed_time);
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+    else {
+      /* wait complete low_speed_time */
+      Curl_expire_latest(data, nextcheck);
+    }
+  }
+  else {
+    /* we keep up the required speed all right */
+    data->state.keeps_speed = now;
+
+    if(data->set.low_speed_limit)
+      /* if there is a low speed limit enabled, we set the expire timer to
+         make this connection's speed get checked again no later than when
+         this time is up */
+      Curl_expire_latest(data, data->set.low_speed_time*1000);
+  }
+  return CURLE_OK;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/speedcheck.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/speedcheck.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/speedcheck.h	(revision 164)
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_SPEEDCHECK_H
+#define HEADER_CURL_SPEEDCHECK_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "timeval.h"
+
+void Curl_speedinit(struct SessionHandle *data);
+CURLcode Curl_speedcheck(struct SessionHandle *data,
+                         struct timeval now);
+
+#endif /* HEADER_CURL_SPEEDCHECK_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/splay.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/splay.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/splay.c	(revision 164)
@@ -0,0 +1,288 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1997 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "splay.h"
+
+/*
+ * This macro compares two node keys i and j and returns:
+ *
+ *  negative value: when i is smaller than j
+ *  zero          : when i is equal   to   j
+ *  positive when : when i is larger  than j
+ */
+#define compare(i,j) Curl_splaycomparekeys((i),(j))
+
+/*
+ * Splay using the key i (which may or may not be in the tree.) The starting
+ * root is t.
+ */
+struct Curl_tree *Curl_splay(struct timeval i,
+                             struct Curl_tree *t)
+{
+  struct Curl_tree N, *l, *r, *y;
+  long comp;
+
+  if(t == NULL)
+    return t;
+  N.smaller = N.larger = NULL;
+  l = r = &N;
+
+  for(;;) {
+    comp = compare(i, t->key);
+    if(comp < 0) {
+      if(t->smaller == NULL)
+        break;
+      if(compare(i, t->smaller->key) < 0) {
+        y = t->smaller;                           /* rotate smaller */
+        t->smaller = y->larger;
+        y->larger = t;
+        t = y;
+        if(t->smaller == NULL)
+          break;
+      }
+      r->smaller = t;                               /* link smaller */
+      r = t;
+      t = t->smaller;
+    }
+    else if(comp > 0) {
+      if(t->larger == NULL)
+        break;
+      if(compare(i, t->larger->key) > 0) {
+        y = t->larger;                          /* rotate larger */
+        t->larger = y->smaller;
+        y->smaller = t;
+        t = y;
+        if(t->larger == NULL)
+          break;
+      }
+      l->larger = t;                              /* link larger */
+      l = t;
+      t = t->larger;
+    }
+    else
+      break;
+  }
+
+  l->larger = t->smaller;                                /* assemble */
+  r->smaller = t->larger;
+  t->smaller = N.larger;
+  t->larger = N.smaller;
+
+  return t;
+}
+
+/* Insert key i into the tree t.  Return a pointer to the resulting tree or
+ * NULL if something went wrong.
+ *
+ * @unittest: 1309
+ */
+struct Curl_tree *Curl_splayinsert(struct timeval i,
+                                   struct Curl_tree *t,
+                                   struct Curl_tree *node)
+{
+  static const struct timeval KEY_NOTUSED = {-1, -1}; /* will *NEVER* appear */
+
+  if(node == NULL)
+    return t;
+
+  if(t != NULL) {
+    t = Curl_splay(i, t);
+    if(compare(i, t->key)==0) {
+      /* There already exists a node in the tree with the very same key. Build
+         a linked list of nodes. We make the new 'node' struct the new master
+         node and make the previous node the first one in the 'same' list. */
+
+      node->same = t;
+      node->key = i;
+      node->smaller = t->smaller;
+      node->larger = t->larger;
+
+      t->smaller = node; /* in the sub node for this same key, we use the
+                            smaller pointer to point back to the master
+                            node */
+
+      t->key = KEY_NOTUSED; /* and we set the key in the sub node to NOTUSED
+                               to quickly identify this node as a subnode */
+
+      return node; /* new root node */
+    }
+  }
+
+  if(t == NULL) {
+    node->smaller = node->larger = NULL;
+  }
+  else if(compare(i, t->key) < 0) {
+    node->smaller = t->smaller;
+    node->larger = t;
+    t->smaller = NULL;
+
+  }
+  else {
+    node->larger = t->larger;
+    node->smaller = t;
+    t->larger = NULL;
+  }
+  node->key = i;
+
+  node->same = NULL; /* no identical node (yet) */
+  return node;
+}
+
+/* Finds and deletes the best-fit node from the tree. Return a pointer to the
+   resulting tree.  best-fit means the node with the given or lower key */
+struct Curl_tree *Curl_splaygetbest(struct timeval i,
+                                    struct Curl_tree *t,
+                                    struct Curl_tree **removed)
+{
+  struct Curl_tree *x;
+
+  if(!t) {
+    *removed = NULL; /* none removed since there was no root */
+    return NULL;
+  }
+
+  t = Curl_splay(i, t);
+  if(compare(i, t->key) < 0) {
+    /* too big node, try the smaller chain */
+    if(t->smaller)
+      t=Curl_splay(t->smaller->key, t);
+    else {
+      /* fail */
+      *removed = NULL;
+      return t;
+    }
+  }
+
+  if(compare(i, t->key) >= 0) {               /* found it */
+    /* FIRST! Check if there is a list with identical keys */
+    x = t->same;
+    if(x) {
+      /* there is, pick one from the list */
+
+      /* 'x' is the new root node */
+
+      x->key = t->key;
+      x->larger = t->larger;
+      x->smaller = t->smaller;
+
+      *removed = t;
+      return x; /* new root */
+    }
+
+    if(t->smaller == NULL) {
+      x = t->larger;
+    }
+    else {
+      x = Curl_splay(i, t->smaller);
+      x->larger = t->larger;
+    }
+    *removed = t;
+
+    return x;
+  }
+  else {
+    *removed = NULL; /* no match */
+    return t;        /* It wasn't there */
+  }
+}
+
+
+/* Deletes the very node we point out from the tree if it's there. Stores a
+ * pointer to the new resulting tree in 'newroot'.
+ *
+ * Returns zero on success and non-zero on errors! TODO: document error codes.
+ * When returning error, it does not touch the 'newroot' pointer.
+ *
+ * NOTE: when the last node of the tree is removed, there's no tree left so
+ * 'newroot' will be made to point to NULL.
+ *
+ * @unittest: 1309
+ */
+int Curl_splayremovebyaddr(struct Curl_tree *t,
+                           struct Curl_tree *removenode,
+                           struct Curl_tree **newroot)
+{
+  static const struct timeval KEY_NOTUSED = {-1, -1}; /* will *NEVER* appear */
+  struct Curl_tree *x;
+
+  if(!t || !removenode)
+    return 1;
+
+  if(compare(KEY_NOTUSED, removenode->key) == 0) {
+    /* Key set to NOTUSED means it is a subnode within a 'same' linked list
+       and thus we can unlink it easily. The 'smaller' link of a subnode
+       links to the parent node. */
+    if(removenode->smaller == NULL)
+      return 3;
+
+    removenode->smaller->same = removenode->same;
+    if(removenode->same)
+      removenode->same->smaller = removenode->smaller;
+
+    /* Ensures that double-remove gets caught. */
+    removenode->smaller = NULL;
+
+    /* voila, we're done! */
+    *newroot = t; /* return the same root */
+    return 0;
+  }
+
+  t = Curl_splay(removenode->key, t);
+
+  /* First make sure that we got the same root node as the one we want
+     to remove, as otherwise we might be trying to remove a node that
+     isn't actually in the tree.
+
+     We cannot just compare the keys here as a double remove in quick
+     succession of a node with key != KEY_NOTUSED && same != NULL
+     could return the same key but a different node. */
+  if(t != removenode)
+    return 2;
+
+  /* Check if there is a list with identical sizes, as then we're trying to
+     remove the root node of a list of nodes with identical keys. */
+  x = t->same;
+  if(x) {
+    /* 'x' is the new root node, we just make it use the root node's
+       smaller/larger links */
+
+    x->key = t->key;
+    x->larger = t->larger;
+    x->smaller = t->smaller;
+  }
+  else {
+    /* Remove the root node */
+    if(t->smaller == NULL)
+      x = t->larger;
+    else {
+      x = Curl_splay(removenode->key, t->smaller);
+      x->larger = t->larger;
+    }
+  }
+
+  *newroot = x; /* store new root pointer */
+
+  return 0;
+}
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/splay.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/splay.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/splay.h	(revision 164)
@@ -0,0 +1,66 @@
+#ifndef HEADER_CURL_SPLAY_H
+#define HEADER_CURL_SPLAY_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1997 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+struct Curl_tree {
+  struct Curl_tree *smaller; /* smaller node */
+  struct Curl_tree *larger;  /* larger node */
+  struct Curl_tree *same;    /* points to a node with identical key */
+  struct timeval key;        /* this node's "sort" key */
+  void *payload;             /* data the splay code doesn't care about */
+};
+
+struct Curl_tree *Curl_splay(struct timeval i,
+                             struct Curl_tree *t);
+
+struct Curl_tree *Curl_splayinsert(struct timeval key,
+                                   struct Curl_tree *t,
+                                   struct Curl_tree *newnode);
+
+#if 0
+struct Curl_tree *Curl_splayremove(struct timeval key,
+                                   struct Curl_tree *t,
+                                   struct Curl_tree **removed);
+#endif
+
+struct Curl_tree *Curl_splaygetbest(struct timeval key,
+                                    struct Curl_tree *t,
+                                    struct Curl_tree **removed);
+
+int Curl_splayremovebyaddr(struct Curl_tree *t,
+                           struct Curl_tree *removenode,
+                           struct Curl_tree **newroot);
+
+#define Curl_splaycomparekeys(i,j) ( ((i.tv_sec)  < (j.tv_sec))  ? -1 : \
+                                   ( ((i.tv_sec)  > (j.tv_sec))  ?  1 : \
+                                   ( ((i.tv_usec) < (j.tv_usec)) ? -1 : \
+                                   ( ((i.tv_usec) > (j.tv_usec)) ?  1 : 0 ))))
+
+#ifdef DEBUGBUILD
+void Curl_splayprint(struct Curl_tree * t, int d, char output);
+#else
+#define Curl_splayprint(x,y,z) Curl_nop_stmt
+#endif
+
+#endif /* HEADER_CURL_SPLAY_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/ssh.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/ssh.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/ssh.c	(revision 164)
@@ -0,0 +1,3347 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* #define CURL_LIBSSH2_DEBUG */
+
+#include "curl_setup.h"
+
+#ifdef USE_LIBSSH2
+
+#ifdef HAVE_LIMITS_H
+#  include <limits.h>
+#endif
+
+#include <libssh2.h>
+#include <libssh2_sftp.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "ssh.h"
+#include "url.h"
+#include "speedcheck.h"
+#include "getinfo.h"
+
+#include "strequal.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "inet_ntop.h"
+#include "parsedate.h" /* for the week day and month names */
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "strtoofft.h"
+#include "multiif.h"
+#include "select.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifdef WIN32
+#  undef  PATH_MAX
+#  define PATH_MAX MAX_PATH
+#  ifndef R_OK
+#    define R_OK 4
+#  endif
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024 /* just an extra precaution since there are systems that
+                         have their definition hidden well */
+#endif
+
+#define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
+
+#define sftp_libssh2_realpath(s,p,t,m) \
+        libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
+                                (t), (m), LIBSSH2_SFTP_REALPATH)
+
+/* Local functions: */
+static const char *sftp_libssh2_strerror(int err);
+static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
+static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
+static LIBSSH2_FREE_FUNC(my_libssh2_free);
+
+static CURLcode get_pathname(const char **cpp, char **path);
+
+static CURLcode ssh_connect(struct connectdata *conn, bool *done);
+static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
+static CURLcode ssh_do(struct connectdata *conn, bool *done);
+
+static CURLcode ssh_getworkingpath(struct connectdata *conn,
+                                   char *homedir, /* when SFTP is used */
+                                   char **path);
+
+static CURLcode scp_done(struct connectdata *conn,
+                         CURLcode, bool premature);
+static CURLcode scp_doing(struct connectdata *conn,
+                          bool *dophase_done);
+static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
+
+static CURLcode sftp_done(struct connectdata *conn,
+                          CURLcode, bool premature);
+static CURLcode sftp_doing(struct connectdata *conn,
+                           bool *dophase_done);
+static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
+static
+CURLcode sftp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done);
+
+static int ssh_getsock(struct connectdata *conn,
+                       curl_socket_t *sock, /* points to numsocks number
+                                               of sockets */
+                       int numsocks);
+
+static int ssh_perform_getsock(const struct connectdata *conn,
+                               curl_socket_t *sock, /* points to numsocks
+                                                       number of sockets */
+                               int numsocks);
+
+static CURLcode ssh_setup_connection(struct connectdata *conn);
+
+/*
+ * SCP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_scp = {
+  "SCP",                                /* scheme */
+  ssh_setup_connection,                 /* setup_connection */
+  ssh_do,                               /* do_it */
+  scp_done,                             /* done */
+  ZERO_NULL,                            /* do_more */
+  ssh_connect,                          /* connect_it */
+  ssh_multi_statemach,                  /* connecting */
+  scp_doing,                            /* doing */
+  ssh_getsock,                          /* proto_getsock */
+  ssh_getsock,                          /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ssh_perform_getsock,                  /* perform_getsock */
+  scp_disconnect,                       /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_SSH,                             /* defport */
+  CURLPROTO_SCP,                        /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+  | PROTOPT_NOURLQUERY                  /* flags */
+};
+
+
+/*
+ * SFTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_sftp = {
+  "SFTP",                               /* scheme */
+  ssh_setup_connection,                 /* setup_connection */
+  ssh_do,                               /* do_it */
+  sftp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ssh_connect,                          /* connect_it */
+  ssh_multi_statemach,                  /* connecting */
+  sftp_doing,                           /* doing */
+  ssh_getsock,                          /* proto_getsock */
+  ssh_getsock,                          /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ssh_perform_getsock,                  /* perform_getsock */
+  sftp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_SSH,                             /* defport */
+  CURLPROTO_SFTP,                       /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+  | PROTOPT_NOURLQUERY                  /* flags */
+};
+
+static void
+kbd_callback(const char *name, int name_len, const char *instruction,
+             int instruction_len, int num_prompts,
+             const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
+             LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
+             void **abstract)
+{
+  struct connectdata *conn = (struct connectdata *)*abstract;
+
+#ifdef CURL_LIBSSH2_DEBUG
+  fprintf(stderr, "name=%s\n", name);
+  fprintf(stderr, "name_len=%d\n", name_len);
+  fprintf(stderr, "instruction=%s\n", instruction);
+  fprintf(stderr, "instruction_len=%d\n", instruction_len);
+  fprintf(stderr, "num_prompts=%d\n", num_prompts);
+#else
+  (void)name;
+  (void)name_len;
+  (void)instruction;
+  (void)instruction_len;
+#endif  /* CURL_LIBSSH2_DEBUG */
+  if(num_prompts == 1) {
+    responses[0].text = strdup(conn->passwd);
+    responses[0].length = curlx_uztoui(strlen(conn->passwd));
+  }
+  (void)prompts;
+  (void)abstract;
+} /* kbd_callback */
+
+static CURLcode sftp_libssh2_error_to_CURLE(int err)
+{
+  switch (err) {
+    case LIBSSH2_FX_OK:
+      return CURLE_OK;
+
+    case LIBSSH2_FX_NO_SUCH_FILE:
+    case LIBSSH2_FX_NO_SUCH_PATH:
+      return CURLE_REMOTE_FILE_NOT_FOUND;
+
+    case LIBSSH2_FX_PERMISSION_DENIED:
+    case LIBSSH2_FX_WRITE_PROTECT:
+    case LIBSSH2_FX_LOCK_CONFlICT:
+      return CURLE_REMOTE_ACCESS_DENIED;
+
+    case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
+    case LIBSSH2_FX_QUOTA_EXCEEDED:
+      return CURLE_REMOTE_DISK_FULL;
+
+    case LIBSSH2_FX_FILE_ALREADY_EXISTS:
+      return CURLE_REMOTE_FILE_EXISTS;
+
+    case LIBSSH2_FX_DIR_NOT_EMPTY:
+      return CURLE_QUOTE_ERROR;
+
+    default:
+      break;
+  }
+
+  return CURLE_SSH;
+}
+
+static CURLcode libssh2_session_error_to_CURLE(int err)
+{
+  switch (err) {
+    /* Ordered by order of appearance in libssh2.h */
+    case LIBSSH2_ERROR_NONE:
+      return CURLE_OK;
+
+    case LIBSSH2_ERROR_SOCKET_NONE:
+      return CURLE_COULDNT_CONNECT;
+
+    case LIBSSH2_ERROR_ALLOC:
+      return CURLE_OUT_OF_MEMORY;
+
+    case LIBSSH2_ERROR_SOCKET_SEND:
+      return CURLE_SEND_ERROR;
+
+    case LIBSSH2_ERROR_HOSTKEY_INIT:
+    case LIBSSH2_ERROR_HOSTKEY_SIGN:
+    case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
+    case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
+      return CURLE_PEER_FAILED_VERIFICATION;
+
+    case LIBSSH2_ERROR_PASSWORD_EXPIRED:
+      return CURLE_LOGIN_DENIED;
+
+    case LIBSSH2_ERROR_SOCKET_TIMEOUT:
+    case LIBSSH2_ERROR_TIMEOUT:
+      return CURLE_OPERATION_TIMEDOUT;
+
+    case LIBSSH2_ERROR_EAGAIN:
+      return CURLE_AGAIN;
+  }
+
+  /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
+     error code, and possibly add a few new SSH-related one. We must however
+     not return or even depend on libssh2 errors in the public libcurl API */
+
+  return CURLE_SSH;
+}
+
+static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
+{
+  (void)abstract; /* arg not used */
+  return malloc(count);
+}
+
+static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
+{
+  (void)abstract; /* arg not used */
+  return realloc(ptr, count);
+}
+
+static LIBSSH2_FREE_FUNC(my_libssh2_free)
+{
+  (void)abstract; /* arg not used */
+  if(ptr) /* ssh2 agent sometimes call free with null ptr */
+    free(ptr);
+}
+
+/*
+ * SSH State machine related code
+ */
+/* This is the ONLY way to change SSH state! */
+static void state(struct connectdata *conn, sshstate nowstate)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[] = {
+    "SSH_STOP",
+    "SSH_INIT",
+    "SSH_S_STARTUP",
+    "SSH_HOSTKEY",
+    "SSH_AUTHLIST",
+    "SSH_AUTH_PKEY_INIT",
+    "SSH_AUTH_PKEY",
+    "SSH_AUTH_PASS_INIT",
+    "SSH_AUTH_PASS",
+    "SSH_AUTH_AGENT_INIT",
+    "SSH_AUTH_AGENT_LIST",
+    "SSH_AUTH_AGENT",
+    "SSH_AUTH_HOST_INIT",
+    "SSH_AUTH_HOST",
+    "SSH_AUTH_KEY_INIT",
+    "SSH_AUTH_KEY",
+    "SSH_AUTH_DONE",
+    "SSH_SFTP_INIT",
+    "SSH_SFTP_REALPATH",
+    "SSH_SFTP_QUOTE_INIT",
+    "SSH_SFTP_POSTQUOTE_INIT",
+    "SSH_SFTP_QUOTE",
+    "SSH_SFTP_NEXT_QUOTE",
+    "SSH_SFTP_QUOTE_STAT",
+    "SSH_SFTP_QUOTE_SETSTAT",
+    "SSH_SFTP_QUOTE_SYMLINK",
+    "SSH_SFTP_QUOTE_MKDIR",
+    "SSH_SFTP_QUOTE_RENAME",
+    "SSH_SFTP_QUOTE_RMDIR",
+    "SSH_SFTP_QUOTE_UNLINK",
+    "SSH_SFTP_TRANS_INIT",
+    "SSH_SFTP_UPLOAD_INIT",
+    "SSH_SFTP_CREATE_DIRS_INIT",
+    "SSH_SFTP_CREATE_DIRS",
+    "SSH_SFTP_CREATE_DIRS_MKDIR",
+    "SSH_SFTP_READDIR_INIT",
+    "SSH_SFTP_READDIR",
+    "SSH_SFTP_READDIR_LINK",
+    "SSH_SFTP_READDIR_BOTTOM",
+    "SSH_SFTP_READDIR_DONE",
+    "SSH_SFTP_DOWNLOAD_INIT",
+    "SSH_SFTP_DOWNLOAD_STAT",
+    "SSH_SFTP_CLOSE",
+    "SSH_SFTP_SHUTDOWN",
+    "SSH_SCP_TRANS_INIT",
+    "SSH_SCP_UPLOAD_INIT",
+    "SSH_SCP_DOWNLOAD_INIT",
+    "SSH_SCP_DONE",
+    "SSH_SCP_SEND_EOF",
+    "SSH_SCP_WAIT_EOF",
+    "SSH_SCP_WAIT_CLOSE",
+    "SSH_SCP_CHANNEL_FREE",
+    "SSH_SESSION_DISCONNECT",
+    "SSH_SESSION_FREE",
+    "QUIT"
+  };
+
+  if(sshc->state != nowstate) {
+    infof(conn->data, "SFTP %p state change from %s to %s\n",
+          (void *)sshc, names[sshc->state], names[nowstate]);
+  }
+#endif
+
+  sshc->state = nowstate;
+}
+
+/* figure out the path to work with in this particular request */
+static CURLcode ssh_getworkingpath(struct connectdata *conn,
+                                   char *homedir,  /* when SFTP is used */
+                                   char **path) /* returns the  allocated
+                                                   real path to work with */
+{
+  struct SessionHandle *data = conn->data;
+  char *real_path = NULL;
+  char *working_path;
+  int working_path_len;
+
+  working_path = curl_easy_unescape(data, data->state.path, 0,
+                                    &working_path_len);
+  if(!working_path)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Check for /~/ , indicating relative to the user's home directory */
+  if(conn->handler->protocol & CURLPROTO_SCP) {
+    real_path = malloc(working_path_len+1);
+    if(real_path == NULL) {
+      free(working_path);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
+      /* It is referenced to the home directory, so strip the leading '/~/' */
+      memcpy(real_path, working_path+3, 4 + working_path_len-3);
+    else
+      memcpy(real_path, working_path, 1 + working_path_len);
+  }
+  else if(conn->handler->protocol & CURLPROTO_SFTP) {
+    if((working_path_len > 1) && (working_path[1] == '~')) {
+      size_t homelen = strlen(homedir);
+      real_path = malloc(homelen + working_path_len + 1);
+      if(real_path == NULL) {
+        free(working_path);
+        return CURLE_OUT_OF_MEMORY;
+      }
+      /* It is referenced to the home directory, so strip the
+         leading '/' */
+      memcpy(real_path, homedir, homelen);
+      real_path[homelen] = '/';
+      real_path[homelen+1] = '\0';
+      if(working_path_len > 3) {
+        memcpy(real_path+homelen+1, working_path + 3,
+               1 + working_path_len -3);
+      }
+    }
+    else {
+      real_path = malloc(working_path_len+1);
+      if(real_path == NULL) {
+        free(working_path);
+        return CURLE_OUT_OF_MEMORY;
+      }
+      memcpy(real_path, working_path, 1+working_path_len);
+    }
+  }
+
+  free(working_path);
+
+  /* store the pointer for the caller to receive */
+  *path = real_path;
+
+  return CURLE_OK;
+}
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+static int sshkeycallback(CURL *easy,
+                          const struct curl_khkey *knownkey, /* known */
+                          const struct curl_khkey *foundkey, /* found */
+                          enum curl_khmatch match,
+                          void *clientp)
+{
+  (void)easy;
+  (void)knownkey;
+  (void)foundkey;
+  (void)clientp;
+
+  /* we only allow perfect matches, and we reject everything else */
+  return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
+}
+#endif
+
+/*
+ * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
+ * with 32bit size_t.
+ */
+#ifdef HAVE_LIBSSH2_SFTP_SEEK64
+#define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
+#else
+#define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
+#endif
+
+/*
+ * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
+ * architectures so we check of the necessary function is present.
+ */
+#ifndef HAVE_LIBSSH2_SCP_SEND64
+#define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
+#else
+#define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c),            \
+                                             (libssh2_uint64_t)d, 0, 0)
+#endif
+
+/*
+ * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
+ */
+#ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
+#define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
+#endif
+
+static CURLcode ssh_knownhost(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+  struct SessionHandle *data = conn->data;
+
+  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
+    /* we're asked to verify the host against a file */
+    struct ssh_conn *sshc = &conn->proto.sshc;
+    int rc;
+    int keytype;
+    size_t keylen;
+    const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
+                                                    &keylen, &keytype);
+    int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
+    int keybit = 0;
+
+    if(remotekey) {
+      /*
+       * A subject to figure out is what host name we need to pass in here.
+       * What host name does OpenSSH store in its file if an IDN name is
+       * used?
+       */
+      struct libssh2_knownhost *host;
+      enum curl_khmatch keymatch;
+      curl_sshkeycallback func =
+        data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
+      struct curl_khkey knownkey;
+      struct curl_khkey *knownkeyp = NULL;
+      struct curl_khkey foundkey;
+
+      keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
+        LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
+      keycheck = libssh2_knownhost_checkp(sshc->kh,
+                                          conn->host.name,
+                                          (conn->remote_port != PORT_SSH)?
+                                          conn->remote_port:-1,
+                                          remotekey, keylen,
+                                          LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+                                          LIBSSH2_KNOWNHOST_KEYENC_RAW|
+                                          keybit,
+                                          &host);
+#else
+      keycheck = libssh2_knownhost_check(sshc->kh,
+                                         conn->host.name,
+                                         remotekey, keylen,
+                                         LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+                                         LIBSSH2_KNOWNHOST_KEYENC_RAW|
+                                         keybit,
+                                         &host);
+#endif
+
+      infof(data, "SSH host check: %d, key: %s\n", keycheck,
+            (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
+            host->key:"<none>");
+
+      /* setup 'knownkey' */
+      if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
+        knownkey.key = host->key;
+        knownkey.len = 0;
+        knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
+          CURLKHTYPE_RSA : CURLKHTYPE_DSS;
+        knownkeyp = &knownkey;
+      }
+
+      /* setup 'foundkey' */
+      foundkey.key = remotekey;
+      foundkey.len = keylen;
+      foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
+        CURLKHTYPE_RSA : CURLKHTYPE_DSS;
+
+      /*
+       * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
+       * curl_khmatch enum are ever modified, we need to introduce a
+       * translation table here!
+       */
+      keymatch = (enum curl_khmatch)keycheck;
+
+      /* Ask the callback how to behave */
+      rc = func(data, knownkeyp, /* from the knownhosts file */
+                &foundkey, /* from the remote host */
+                keymatch, data->set.ssh_keyfunc_userp);
+    }
+    else
+      /* no remotekey means failure! */
+      rc = CURLKHSTAT_REJECT;
+
+    switch(rc) {
+    default: /* unknown return codes will equal reject */
+      /* FALLTHROUGH */
+    case CURLKHSTAT_REJECT:
+      state(conn, SSH_SESSION_FREE);
+      /* FALLTHROUGH */
+    case CURLKHSTAT_DEFER:
+      /* DEFER means bail out but keep the SSH_HOSTKEY state */
+      result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
+      break;
+    case CURLKHSTAT_FINE:
+    case CURLKHSTAT_FINE_ADD_TO_FILE:
+      /* proceed */
+      if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
+        /* the found host+key didn't match but has been told to be fine
+           anyway so we add it in memory */
+        int addrc = libssh2_knownhost_add(sshc->kh,
+                                          conn->host.name, NULL,
+                                          remotekey, keylen,
+                                          LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+                                          LIBSSH2_KNOWNHOST_KEYENC_RAW|
+                                          keybit, NULL);
+        if(addrc)
+          infof(data, "Warning adding the known host %s failed!\n",
+                conn->host.name);
+        else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
+          /* now we write the entire in-memory list of known hosts to the
+             known_hosts file */
+          int wrc =
+            libssh2_knownhost_writefile(sshc->kh,
+                                        data->set.str[STRING_SSH_KNOWNHOSTS],
+                                        LIBSSH2_KNOWNHOST_FILE_OPENSSH);
+          if(wrc) {
+            infof(data, "Warning, writing %s failed!\n",
+                  data->set.str[STRING_SSH_KNOWNHOSTS]);
+          }
+        }
+      }
+      break;
+    }
+  }
+#else /* HAVE_LIBSSH2_KNOWNHOST_API */
+  (void)conn;
+#endif
+  return result;
+}
+
+static CURLcode ssh_check_fingerprint(struct connectdata *conn)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  struct SessionHandle *data = conn->data;
+  const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
+  char md5buffer[33];
+  int i;
+
+  const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
+      LIBSSH2_HOSTKEY_HASH_MD5);
+
+  if(fingerprint) {
+    /* The fingerprint points to static storage (!), don't free() it. */
+    for(i = 0; i < 16; i++)
+      snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
+    infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
+  }
+
+  /* Before we authenticate we check the hostkey's MD5 fingerprint
+   * against a known fingerprint, if available.
+   */
+  if(pubkey_md5 && strlen(pubkey_md5) == 32) {
+    if(!fingerprint || !strequal(md5buffer, pubkey_md5)) {
+      if(fingerprint)
+        failf(data,
+            "Denied establishing ssh session: mismatch md5 fingerprint. "
+            "Remote %s is not equal to %s", md5buffer, pubkey_md5);
+      else
+        failf(data,
+            "Denied establishing ssh session: md5 fingerprint not available");
+      state(conn, SSH_SESSION_FREE);
+      sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
+      return sshc->actualcode;
+    }
+    else {
+      infof(data, "MD5 checksum match!\n");
+      /* as we already matched, we skip the check for known hosts */
+      return CURLE_OK;
+    }
+  }
+  else
+    return ssh_knownhost(conn);
+}
+
+/*
+ * ssh_statemach_act() runs the SSH state machine as far as it can without
+ * blocking and without reaching the end.  The data the pointer 'block' points
+ * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
+ * meaning it wants to be called again when the socket is ready
+ */
+
+static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct SSHPROTO *sftp_scp = data->req.protop;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  char *new_readdir_line;
+  int rc = LIBSSH2_ERROR_NONE;
+  int err;
+  int seekerr = CURL_SEEKFUNC_OK;
+  *block = 0; /* we're not blocking by default */
+
+  do {
+
+    switch(sshc->state) {
+    case SSH_INIT:
+      sshc->secondCreateDirs = 0;
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = CURLE_OK;
+
+      /* Set libssh2 to non-blocking, since everything internally is
+         non-blocking */
+      libssh2_session_set_blocking(sshc->ssh_session, 0);
+
+      state(conn, SSH_S_STARTUP);
+      /* fall-through */
+
+    case SSH_S_STARTUP:
+      rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      else if(rc) {
+        failf(data, "Failure establishing ssh session");
+        state(conn, SSH_SESSION_FREE);
+        sshc->actualcode = CURLE_FAILED_INIT;
+        break;
+      }
+
+      state(conn, SSH_HOSTKEY);
+
+      /* fall-through */
+    case SSH_HOSTKEY:
+      /*
+       * Before we authenticate we should check the hostkey's fingerprint
+       * against our known hosts. How that is handled (reading from file,
+       * whatever) is up to us.
+       */
+      result = ssh_check_fingerprint(conn);
+      if(!result)
+        state(conn, SSH_AUTHLIST);
+      /* ssh_check_fingerprint sets state appropriately on error */
+      break;
+
+    case SSH_AUTHLIST:
+      /*
+       * Figure out authentication methods
+       * NB: As soon as we have provided a username to an openssh server we
+       * must never change it later. Thus, always specify the correct username
+       * here, even though the libssh2 docs kind of indicate that it should be
+       * possible to get a 'generic' list (not user-specific) of authentication
+       * methods, presumably with a blank username. That won't work in my
+       * experience.
+       * So always specify it here.
+       */
+      sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
+                                             conn->user,
+                                             curlx_uztoui(strlen(conn->user)));
+
+      if(!sshc->authlist) {
+        if(libssh2_userauth_authenticated(sshc->ssh_session)) {
+          sshc->authed = TRUE;
+          infof(data, "SSH user accepted with no authentication\n");
+          state(conn, SSH_AUTH_DONE);
+          break;
+        }
+        else if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+        else {
+          state(conn, SSH_SESSION_FREE);
+          sshc->actualcode = libssh2_session_error_to_CURLE(err);
+          break;
+        }
+      }
+      infof(data, "SSH authentication methods available: %s\n",
+            sshc->authlist);
+
+      state(conn, SSH_AUTH_PKEY_INIT);
+      break;
+
+    case SSH_AUTH_PKEY_INIT:
+      /*
+       * Check the supported auth types in the order I feel is most secure
+       * with the requested type of authentication
+       */
+      sshc->authed = FALSE;
+
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
+         (strstr(sshc->authlist, "publickey") != NULL)) {
+        char *home = NULL;
+        bool out_of_memory = FALSE;
+
+        sshc->rsa_pub = sshc->rsa = NULL;
+
+        /* To ponder about: should really the lib be messing about with the
+           HOME environment variable etc? */
+        home = curl_getenv("HOME");
+
+        if(data->set.str[STRING_SSH_PRIVATE_KEY])
+          sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
+        else {
+          /* If no private key file is specified, try some common paths. */
+          if(home) {
+            /* Try ~/.ssh first. */
+            sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
+            if(!sshc->rsa)
+              out_of_memory = TRUE;
+            else if(access(sshc->rsa, R_OK) != 0) {
+              Curl_safefree(sshc->rsa);
+              sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
+              if(!sshc->rsa)
+                out_of_memory = TRUE;
+              else if(access(sshc->rsa, R_OK) != 0) {
+                Curl_safefree(sshc->rsa);
+              }
+            }
+          }
+          if(!out_of_memory && !sshc->rsa) {
+            /* Nothing found; try the current dir. */
+            sshc->rsa = strdup("id_rsa");
+            if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
+              Curl_safefree(sshc->rsa);
+              sshc->rsa = strdup("id_dsa");
+              if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
+                Curl_safefree(sshc->rsa);
+                /* Out of guesses. Set to the empty string to avoid
+                 * surprising info messages. */
+                sshc->rsa = strdup("");
+              }
+            }
+          }
+        }
+
+        /*
+         * Unless the user explicitly specifies a public key file, let
+         * libssh2 extract the public key from the private key file.
+         * This is done by simply passing sshc->rsa_pub = NULL.
+         */
+        if(data->set.str[STRING_SSH_PUBLIC_KEY]
+            /* treat empty string the same way as NULL */
+            && data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
+          sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
+          if(!sshc->rsa_pub)
+            out_of_memory = TRUE;
+        }
+
+        if(out_of_memory || sshc->rsa == NULL) {
+          free(home);
+          Curl_safefree(sshc->rsa);
+          Curl_safefree(sshc->rsa_pub);
+          state(conn, SSH_SESSION_FREE);
+          sshc->actualcode = CURLE_OUT_OF_MEMORY;
+          break;
+        }
+
+        sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
+        if(!sshc->passphrase)
+          sshc->passphrase = "";
+
+        free(home);
+
+        if(sshc->rsa_pub)
+          infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
+        infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
+
+        state(conn, SSH_AUTH_PKEY);
+      }
+      else {
+        state(conn, SSH_AUTH_PASS_INIT);
+      }
+      break;
+
+    case SSH_AUTH_PKEY:
+      /* The function below checks if the files exists, no need to stat() here.
+       */
+      rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
+                                                  conn->user,
+                                                  curlx_uztoui(
+                                                    strlen(conn->user)),
+                                                  sshc->rsa_pub,
+                                                  sshc->rsa, sshc->passphrase);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+
+      Curl_safefree(sshc->rsa_pub);
+      Curl_safefree(sshc->rsa);
+
+      if(rc == 0) {
+        sshc->authed = TRUE;
+        infof(data, "Initialized SSH public key authentication\n");
+        state(conn, SSH_AUTH_DONE);
+      }
+      else {
+        char *err_msg;
+        (void)libssh2_session_last_error(sshc->ssh_session,
+                                         &err_msg, NULL, 0);
+        infof(data, "SSH public key authentication failed: %s\n", err_msg);
+        state(conn, SSH_AUTH_PASS_INIT);
+      }
+      break;
+
+    case SSH_AUTH_PASS_INIT:
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
+         (strstr(sshc->authlist, "password") != NULL)) {
+        state(conn, SSH_AUTH_PASS);
+      }
+      else {
+        state(conn, SSH_AUTH_HOST_INIT);
+      }
+      break;
+
+    case SSH_AUTH_PASS:
+      rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
+                                        curlx_uztoui(strlen(conn->user)),
+                                        conn->passwd,
+                                        curlx_uztoui(strlen(conn->passwd)),
+                                        NULL);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      else if(rc == 0) {
+        sshc->authed = TRUE;
+        infof(data, "Initialized password authentication\n");
+        state(conn, SSH_AUTH_DONE);
+      }
+      else {
+        state(conn, SSH_AUTH_HOST_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+      break;
+
+    case SSH_AUTH_HOST_INIT:
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
+         (strstr(sshc->authlist, "hostbased") != NULL)) {
+        state(conn, SSH_AUTH_HOST);
+      }
+      else {
+        state(conn, SSH_AUTH_AGENT_INIT);
+      }
+      break;
+
+    case SSH_AUTH_HOST:
+      state(conn, SSH_AUTH_AGENT_INIT);
+      break;
+
+    case SSH_AUTH_AGENT_INIT:
+#ifdef HAVE_LIBSSH2_AGENT_API
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
+         && (strstr(sshc->authlist, "publickey") != NULL)) {
+
+        /* Connect to the ssh-agent */
+        /* The agent could be shared by a curl thread i believe
+           but nothing obvious as keys can be added/removed at any time */
+        if(!sshc->ssh_agent) {
+          sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
+          if(!sshc->ssh_agent) {
+            infof(data, "Could not create agent object\n");
+
+            state(conn, SSH_AUTH_KEY_INIT);
+            break;
+          }
+        }
+
+        rc = libssh2_agent_connect(sshc->ssh_agent);
+        if(rc == LIBSSH2_ERROR_EAGAIN)
+          break;
+        if(rc < 0) {
+          infof(data, "Failure connecting to agent\n");
+          state(conn, SSH_AUTH_KEY_INIT);
+        }
+        else {
+          state(conn, SSH_AUTH_AGENT_LIST);
+        }
+      }
+      else
+#endif /* HAVE_LIBSSH2_AGENT_API */
+        state(conn, SSH_AUTH_KEY_INIT);
+      break;
+
+    case SSH_AUTH_AGENT_LIST:
+#ifdef HAVE_LIBSSH2_AGENT_API
+      rc = libssh2_agent_list_identities(sshc->ssh_agent);
+
+      if(rc == LIBSSH2_ERROR_EAGAIN)
+        break;
+      if(rc < 0) {
+        infof(data, "Failure requesting identities to agent\n");
+        state(conn, SSH_AUTH_KEY_INIT);
+      }
+      else {
+        state(conn, SSH_AUTH_AGENT);
+        sshc->sshagent_prev_identity = NULL;
+      }
+#endif
+      break;
+
+    case SSH_AUTH_AGENT:
+#ifdef HAVE_LIBSSH2_AGENT_API
+      /* as prev_identity evolves only after an identity user auth finished we
+         can safely request it again as long as EAGAIN is returned here or by
+         libssh2_agent_userauth */
+      rc = libssh2_agent_get_identity(sshc->ssh_agent,
+                                      &sshc->sshagent_identity,
+                                      sshc->sshagent_prev_identity);
+      if(rc == LIBSSH2_ERROR_EAGAIN)
+        break;
+
+      if(rc == 0) {
+        rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
+                                    sshc->sshagent_identity);
+
+        if(rc < 0) {
+          if(rc != LIBSSH2_ERROR_EAGAIN)
+            /* tried and failed? go to next identity */
+            sshc->sshagent_prev_identity = sshc->sshagent_identity;
+          else
+            break;
+        }
+      }
+
+      if(rc < 0)
+        infof(data, "Failure requesting identities to agent\n");
+      else if(rc == 1)
+        infof(data, "No identity would match\n");
+
+      if(rc == LIBSSH2_ERROR_NONE) {
+        sshc->authed = TRUE;
+        infof(data, "Agent based authentication successful\n");
+        state(conn, SSH_AUTH_DONE);
+      }
+      else {
+        state(conn, SSH_AUTH_KEY_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+#endif
+      break;
+
+    case SSH_AUTH_KEY_INIT:
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
+         && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
+        state(conn, SSH_AUTH_KEY);
+      }
+      else {
+        state(conn, SSH_AUTH_DONE);
+      }
+      break;
+
+    case SSH_AUTH_KEY:
+      /* Authentication failed. Continue with keyboard-interactive now. */
+      rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
+                                                    conn->user,
+                                                    curlx_uztoui(
+                                                      strlen(conn->user)),
+                                                    &kbd_callback);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      else if(rc == 0) {
+        sshc->authed = TRUE;
+        infof(data, "Initialized keyboard interactive authentication\n");
+      }
+      state(conn, SSH_AUTH_DONE);
+      break;
+
+    case SSH_AUTH_DONE:
+      if(!sshc->authed) {
+        failf(data, "Authentication failure");
+        state(conn, SSH_SESSION_FREE);
+        sshc->actualcode = CURLE_LOGIN_DENIED;
+        break;
+      }
+
+      /*
+       * At this point we have an authenticated ssh session.
+       */
+      infof(data, "Authentication complete\n");
+
+      Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
+
+      conn->sockfd = sock;
+      conn->writesockfd = CURL_SOCKET_BAD;
+
+      if(conn->handler->protocol == CURLPROTO_SFTP) {
+        state(conn, SSH_SFTP_INIT);
+        break;
+      }
+      infof(data, "SSH CONNECT phase done\n");
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_SFTP_INIT:
+      /*
+       * Start the libssh2 sftp session
+       */
+      sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
+      if(!sshc->sftp_session) {
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+        else {
+          char *err_msg;
+
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          failf(data, "Failure initializing sftp session: %s", err_msg);
+          state(conn, SSH_SESSION_FREE);
+          sshc->actualcode = CURLE_FAILED_INIT;
+          break;
+        }
+      }
+      state(conn, SSH_SFTP_REALPATH);
+      break;
+
+    case SSH_SFTP_REALPATH:
+    {
+      char tempHome[PATH_MAX];
+
+      /*
+       * Get the "home" directory
+       */
+      rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
+                                 tempHome, PATH_MAX-1);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      else if(rc > 0) {
+        /* It seems that this string is not always NULL terminated */
+        tempHome[rc] = '\0';
+        sshc->homedir = strdup(tempHome);
+        if(!sshc->homedir) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->actualcode = CURLE_OUT_OF_MEMORY;
+          break;
+        }
+        conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
+      }
+      else {
+        /* Return the error type */
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        result = sftp_libssh2_error_to_CURLE(err);
+        sshc->actualcode = result?result:CURLE_SSH;
+        DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
+                     err, (int)result));
+        state(conn, SSH_STOP);
+        break;
+      }
+    }
+    /* This is the last step in the SFTP connect phase. Do note that while
+       we get the homedir here, we get the "workingpath" in the DO action
+       since the homedir will remain the same between request but the
+       working path will not. */
+    DEBUGF(infof(data, "SSH CONNECT phase done\n"));
+    state(conn, SSH_STOP);
+    break;
+
+    case SSH_SFTP_QUOTE_INIT:
+
+      result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
+      if(result) {
+        sshc->actualcode = result;
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      if(data->set.quote) {
+        infof(data, "Sending quote commands\n");
+        sshc->quote_item = data->set.quote;
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        state(conn, SSH_SFTP_TRANS_INIT);
+      }
+      break;
+
+    case SSH_SFTP_POSTQUOTE_INIT:
+      if(data->set.postquote) {
+        infof(data, "Sending quote commands\n");
+        sshc->quote_item = data->set.postquote;
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        state(conn, SSH_STOP);
+      }
+      break;
+
+    case SSH_SFTP_QUOTE:
+      /* Send any quote commands */
+    {
+      const char *cp;
+
+      /*
+       * Support some of the "FTP" commands
+       */
+      char *cmd = sshc->quote_item->data;
+      sshc->acceptfail = FALSE;
+
+      /* if a command starts with an asterisk, which a legal SFTP command never
+         can, the command will be allowed to fail without it causing any
+         aborts or cancels etc. It will cause libcurl to act as if the command
+         is successful, whatever the server reponds. */
+
+      if(cmd[0] == '*') {
+        cmd++;
+        sshc->acceptfail = TRUE;
+      }
+
+      if(curl_strequal("pwd", cmd)) {
+        /* output debug output if that is requested */
+        char *tmp = aprintf("257 \"%s\" is current directory.\n",
+                            sftp_scp->path);
+        if(!tmp) {
+          result = CURLE_OUT_OF_MEMORY;
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          break;
+        }
+        if(data->set.verbose) {
+          Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
+          Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
+        }
+        /* this sends an FTP-like "header" to the header callback so that the
+           current directory can be read very similar to how it is read when
+           using ordinary FTP. */
+        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+        free(tmp);
+        if(result) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = result;
+        }
+        else
+          state(conn, SSH_SFTP_NEXT_QUOTE);
+        break;
+      }
+      else if(cmd) {
+        /*
+         * the arguments following the command must be separated from the
+         * command with a space so we can check for it unconditionally
+         */
+        cp = strchr(cmd, ' ');
+        if(cp == NULL) {
+          failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+
+        /*
+         * also, every command takes at least one argument so we get that
+         * first argument right now
+         */
+        result = get_pathname(&cp, &sshc->quote_path1);
+        if(result) {
+          if(result == CURLE_OUT_OF_MEMORY)
+            failf(data, "Out of memory");
+          else
+            failf(data, "Syntax error: Bad first parameter");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = result;
+          break;
+        }
+
+        /*
+         * SFTP is a binary protocol, so we don't send text commands
+         * to the server. Instead, we scan for commands used by
+         * OpenSSH's sftp program and call the appropriate libssh2
+         * functions.
+         */
+        if(curl_strnequal(cmd, "chgrp ", 6) ||
+           curl_strnequal(cmd, "chmod ", 6) ||
+           curl_strnequal(cmd, "chown ", 6) ) {
+          /* attribute change */
+
+          /* sshc->quote_path1 contains the mode to set */
+          /* get the destination */
+          result = get_pathname(&cp, &sshc->quote_path2);
+          if(result) {
+            if(result == CURLE_OUT_OF_MEMORY)
+              failf(data, "Out of memory");
+            else
+              failf(data, "Syntax error in chgrp/chmod/chown: "
+                    "Bad second parameter");
+            Curl_safefree(sshc->quote_path1);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->nextstate = SSH_NO_STATE;
+            sshc->actualcode = result;
+            break;
+          }
+          memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
+          state(conn, SSH_SFTP_QUOTE_STAT);
+          break;
+        }
+        else if(curl_strnequal(cmd, "ln ", 3) ||
+                curl_strnequal(cmd, "symlink ", 8)) {
+          /* symbolic linking */
+          /* sshc->quote_path1 is the source */
+          /* get the destination */
+          result = get_pathname(&cp, &sshc->quote_path2);
+          if(result) {
+            if(result == CURLE_OUT_OF_MEMORY)
+              failf(data, "Out of memory");
+            else
+              failf(data,
+                    "Syntax error in ln/symlink: Bad second parameter");
+            Curl_safefree(sshc->quote_path1);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->nextstate = SSH_NO_STATE;
+            sshc->actualcode = result;
+            break;
+          }
+          state(conn, SSH_SFTP_QUOTE_SYMLINK);
+          break;
+        }
+        else if(curl_strnequal(cmd, "mkdir ", 6)) {
+          /* create dir */
+          state(conn, SSH_SFTP_QUOTE_MKDIR);
+          break;
+        }
+        else if(curl_strnequal(cmd, "rename ", 7)) {
+          /* rename file */
+          /* first param is the source path */
+          /* second param is the dest. path */
+          result = get_pathname(&cp, &sshc->quote_path2);
+          if(result) {
+            if(result == CURLE_OUT_OF_MEMORY)
+              failf(data, "Out of memory");
+            else
+              failf(data, "Syntax error in rename: Bad second parameter");
+            Curl_safefree(sshc->quote_path1);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->nextstate = SSH_NO_STATE;
+            sshc->actualcode = result;
+            break;
+          }
+          state(conn, SSH_SFTP_QUOTE_RENAME);
+          break;
+        }
+        else if(curl_strnequal(cmd, "rmdir ", 6)) {
+          /* delete dir */
+          state(conn, SSH_SFTP_QUOTE_RMDIR);
+          break;
+        }
+        else if(curl_strnequal(cmd, "rm ", 3)) {
+          state(conn, SSH_SFTP_QUOTE_UNLINK);
+          break;
+        }
+
+        failf(data, "Unknown SFTP command");
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+    }
+    if(!sshc->quote_item) {
+      state(conn, SSH_SFTP_TRANS_INIT);
+    }
+    break;
+
+    case SSH_SFTP_NEXT_QUOTE:
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+
+      sshc->quote_item = sshc->quote_item->next;
+
+      if(sshc->quote_item) {
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        if(sshc->nextstate != SSH_NO_STATE) {
+          state(conn, sshc->nextstate);
+          sshc->nextstate = SSH_NO_STATE;
+        }
+        else {
+          state(conn, SSH_SFTP_TRANS_INIT);
+        }
+      }
+      break;
+
+    case SSH_SFTP_QUOTE_STAT:
+    {
+      char *cmd = sshc->quote_item->data;
+      sshc->acceptfail = FALSE;
+
+      /* if a command starts with an asterisk, which a legal SFTP command never
+         can, the command will be allowed to fail without it causing any
+         aborts or cancels etc. It will cause libcurl to act as if the command
+         is successful, whatever the server reponds. */
+
+      if(cmd[0] == '*') {
+        cmd++;
+        sshc->acceptfail = TRUE;
+      }
+
+      if(!curl_strnequal(cmd, "chmod", 5)) {
+        /* Since chown and chgrp only set owner OR group but libssh2 wants to
+         * set them both at once, we need to obtain the current ownership
+         * first.  This takes an extra protocol round trip.
+         */
+        rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
+                                  curlx_uztoui(strlen(sshc->quote_path2)),
+                                  LIBSSH2_SFTP_STAT,
+                                  &sshc->quote_attrs);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
+          err = sftp_libssh2_last_error(sshc->sftp_session);
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Attempt to get SFTP stats failed: %s",
+                sftp_libssh2_strerror(err));
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+
+      /* Now set the new attributes... */
+      if(curl_strnequal(cmd, "chgrp", 5)) {
+        sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
+        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
+        if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
+           !sshc->acceptfail) {
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Syntax error: chgrp gid not a number");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+      else if(curl_strnequal(cmd, "chmod", 5)) {
+        sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
+        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
+        /* permissions are octal */
+        if(sshc->quote_attrs.permissions == 0 &&
+           !ISDIGIT(sshc->quote_path1[0])) {
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Syntax error: chmod permissions not a number");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+      else if(curl_strnequal(cmd, "chown", 5)) {
+        sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
+        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
+        if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
+           !sshc->acceptfail) {
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Syntax error: chown uid not a number");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+
+      /* Now send the completed structure... */
+      state(conn, SSH_SFTP_QUOTE_SETSTAT);
+      break;
+    }
+
+    case SSH_SFTP_QUOTE_SETSTAT:
+      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
+                                curlx_uztoui(strlen(sshc->quote_path2)),
+                                LIBSSH2_SFTP_SETSTAT,
+                                &sshc->quote_attrs);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      else if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "Attempt to set SFTP stats failed: %s",
+              sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_SYMLINK:
+      rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
+                                   curlx_uztoui(strlen(sshc->quote_path1)),
+                                   sshc->quote_path2,
+                                   curlx_uztoui(strlen(sshc->quote_path2)),
+                                   LIBSSH2_SFTP_SYMLINK);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      else if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "symlink command failed: %s",
+              sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_MKDIR:
+      rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
+                                 curlx_uztoui(strlen(sshc->quote_path1)),
+                                 data->set.new_directory_perms);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      else if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_RENAME:
+      rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
+                                  curlx_uztoui(strlen(sshc->quote_path1)),
+                                  sshc->quote_path2,
+                                  curlx_uztoui(strlen(sshc->quote_path2)),
+                                  LIBSSH2_SFTP_RENAME_OVERWRITE |
+                                  LIBSSH2_SFTP_RENAME_ATOMIC |
+                                  LIBSSH2_SFTP_RENAME_NATIVE);
+
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      else if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_RMDIR:
+      rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
+                                 curlx_uztoui(strlen(sshc->quote_path1)));
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      else if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_UNLINK:
+      rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
+                                  curlx_uztoui(strlen(sshc->quote_path1)));
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      else if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_TRANS_INIT:
+      if(data->set.upload)
+        state(conn, SSH_SFTP_UPLOAD_INIT);
+      else {
+        if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
+          state(conn, SSH_SFTP_READDIR_INIT);
+        else
+          state(conn, SSH_SFTP_DOWNLOAD_INIT);
+      }
+      break;
+
+    case SSH_SFTP_UPLOAD_INIT:
+    {
+      unsigned long flags;
+      /*
+       * NOTE!!!  libssh2 requires that the destination path is a full path
+       *          that includes the destination file and name OR ends in a "/"
+       *          If this is not done the destination file will be named the
+       *          same name as the last directory in the path.
+       */
+
+      if(data->state.resume_from != 0) {
+        LIBSSH2_SFTP_ATTRIBUTES attrs;
+        if(data->state.resume_from < 0) {
+          rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
+                                    curlx_uztoui(strlen(sftp_scp->path)),
+                                    LIBSSH2_SFTP_STAT, &attrs);
+          if(rc == LIBSSH2_ERROR_EAGAIN) {
+            break;
+          }
+          else if(rc) {
+            data->state.resume_from = 0;
+          }
+          else {
+            curl_off_t size = attrs.filesize;
+            if(size < 0) {
+              failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+              return CURLE_BAD_DOWNLOAD_RESUME;
+            }
+            data->state.resume_from = attrs.filesize;
+          }
+        }
+      }
+
+      if(data->set.ftp_append)
+        /* Try to open for append, but create if nonexisting */
+        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
+      else if(data->state.resume_from > 0)
+        /* If we have restart position then open for append */
+        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
+      else
+        /* Clear file before writing (normal behaviour) */
+        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
+
+      sshc->sftp_handle =
+        libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
+                             curlx_uztoui(strlen(sftp_scp->path)),
+                             flags, data->set.new_file_perms,
+                             LIBSSH2_SFTP_OPENFILE);
+
+      if(!sshc->sftp_handle) {
+        rc = libssh2_session_last_errno(sshc->ssh_session);
+
+        if(LIBSSH2_ERROR_EAGAIN == rc)
+          break;
+        else {
+          if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
+            /* only when there was an SFTP protocol error can we extract
+               the sftp error! */
+            err = sftp_libssh2_last_error(sshc->sftp_session);
+          else
+            err = -1; /* not an sftp error at all */
+
+          if(sshc->secondCreateDirs) {
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->actualcode = err>= LIBSSH2_FX_OK?
+              sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
+            failf(data, "Creating the dir/file failed: %s",
+                  sftp_libssh2_strerror(err));
+            break;
+          }
+          else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
+                   (err == LIBSSH2_FX_FAILURE) ||
+                   (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
+                  (data->set.ftp_create_missing_dirs &&
+                   (strlen(sftp_scp->path) > 1))) {
+            /* try to create the path remotely */
+            sshc->secondCreateDirs = 1;
+            state(conn, SSH_SFTP_CREATE_DIRS_INIT);
+            break;
+          }
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->actualcode = err>= LIBSSH2_FX_OK?
+            sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
+          if(!sshc->actualcode) {
+            /* Sometimes, for some reason libssh2_sftp_last_error() returns
+               zero even though libssh2_sftp_open() failed previously! We need
+               to work around that! */
+            sshc->actualcode = CURLE_SSH;
+            err=-1;
+          }
+          failf(data, "Upload failed: %s (%d/%d)",
+                err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
+                err, rc);
+          break;
+        }
+      }
+
+      /* If we have a restart point then we need to seek to the correct
+         position. */
+      if(data->state.resume_from > 0) {
+        /* Let's read off the proper amount of bytes from the input. */
+        if(conn->seek_func) {
+          seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+                                    SEEK_SET);
+        }
+
+        if(seekerr != CURL_SEEKFUNC_OK) {
+
+          if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+            failf(data, "Could not seek stream");
+            return CURLE_FTP_COULDNT_USE_REST;
+          }
+          /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+          else {
+            curl_off_t passed=0;
+            do {
+              size_t readthisamountnow =
+                (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
+                BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
+
+              size_t actuallyread =
+                data->state.fread_func(data->state.buffer, 1,
+                                       readthisamountnow, data->state.in);
+
+              passed += actuallyread;
+              if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+                /* this checks for greater-than only to make sure that the
+                   CURL_READFUNC_ABORT return code still aborts */
+                failf(data, "Failed to read data");
+                return CURLE_FTP_COULDNT_USE_REST;
+              }
+            } while(passed < data->state.resume_from);
+          }
+        }
+
+        /* now, decrease the size of the read */
+        if(data->state.infilesize > 0) {
+          data->state.infilesize -= data->state.resume_from;
+          data->req.size = data->state.infilesize;
+          Curl_pgrsSetUploadSize(data, data->state.infilesize);
+        }
+
+        SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
+      }
+      if(data->state.infilesize > 0) {
+        data->req.size = data->state.infilesize;
+        Curl_pgrsSetUploadSize(data, data->state.infilesize);
+      }
+      /* upload data */
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->sockfd = conn->writesockfd;
+
+      if(result) {
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = result;
+      }
+      else {
+        /* store this original bitmask setup to use later on if we can't
+           figure out a "real" bitmask */
+        sshc->orig_waitfor = data->req.keepon;
+
+        /* we want to use the _sending_ function even when the socket turns
+           out readable as the underlying libssh2 sftp send function will deal
+           with both accordingly */
+        conn->cselect_bits = CURL_CSELECT_OUT;
+
+        /* since we don't really wait for anything at this point, we want the
+           state machine to move on as soon as possible so we set a very short
+           timeout here */
+        Curl_expire(data, 1);
+
+        state(conn, SSH_STOP);
+      }
+      break;
+    }
+
+    case SSH_SFTP_CREATE_DIRS_INIT:
+      if(strlen(sftp_scp->path) > 1) {
+        sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
+        state(conn, SSH_SFTP_CREATE_DIRS);
+      }
+      else {
+        state(conn, SSH_SFTP_UPLOAD_INIT);
+      }
+      break;
+
+    case SSH_SFTP_CREATE_DIRS:
+      sshc->slash_pos = strchr(sshc->slash_pos, '/');
+      if(sshc->slash_pos) {
+        *sshc->slash_pos = 0;
+
+        infof(data, "Creating directory '%s'\n", sftp_scp->path);
+        state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
+        break;
+      }
+      else {
+        state(conn, SSH_SFTP_UPLOAD_INIT);
+      }
+      break;
+
+    case SSH_SFTP_CREATE_DIRS_MKDIR:
+      /* 'mode' - parameter is preliminary - default to 0644 */
+      rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
+                                 curlx_uztoui(strlen(sftp_scp->path)),
+                                 data->set.new_directory_perms);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      *sshc->slash_pos = '/';
+      ++sshc->slash_pos;
+      if(rc == -1) {
+        /*
+         * Abort if failure wasn't that the dir already exists or the
+         * permission was denied (creation might succeed further down the
+         * path) - retry on unspecific FAILURE also
+         */
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
+           (err != LIBSSH2_FX_FAILURE) &&
+           (err != LIBSSH2_FX_PERMISSION_DENIED)) {
+          result = sftp_libssh2_error_to_CURLE(err);
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->actualcode = result?result:CURLE_SSH;
+          break;
+        }
+      }
+      state(conn, SSH_SFTP_CREATE_DIRS);
+      break;
+
+    case SSH_SFTP_READDIR_INIT:
+      Curl_pgrsSetDownloadSize(data, -1);
+      if(data->set.opt_no_body) {
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      /*
+       * This is a directory that we are trying to get, so produce a directory
+       * listing
+       */
+      sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
+                                               sftp_scp->path,
+                                               curlx_uztoui(
+                                                 strlen(sftp_scp->path)),
+                                               0, 0, LIBSSH2_SFTP_OPENDIR);
+      if(!sshc->sftp_handle) {
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+        else {
+          err = sftp_libssh2_last_error(sshc->sftp_session);
+          failf(data, "Could not open directory for reading: %s",
+                sftp_libssh2_strerror(err));
+          state(conn, SSH_SFTP_CLOSE);
+          result = sftp_libssh2_error_to_CURLE(err);
+          sshc->actualcode = result?result:CURLE_SSH;
+          break;
+        }
+      }
+      if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+      if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
+        Curl_safefree(sshc->readdir_filename);
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+      state(conn, SSH_SFTP_READDIR);
+      break;
+
+    case SSH_SFTP_READDIR:
+      sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
+                                                  sshc->readdir_filename,
+                                                  PATH_MAX,
+                                                  sshc->readdir_longentry,
+                                                  PATH_MAX,
+                                                  &sshc->readdir_attrs);
+      if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
+        rc = LIBSSH2_ERROR_EAGAIN;
+        break;
+      }
+      if(sshc->readdir_len > 0) {
+        sshc->readdir_filename[sshc->readdir_len] = '\0';
+
+        if(data->set.ftp_list_only) {
+          char *tmpLine;
+
+          tmpLine = aprintf("%s\n", sshc->readdir_filename);
+          if(tmpLine == NULL) {
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->actualcode = CURLE_OUT_OF_MEMORY;
+            break;
+          }
+          result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                     tmpLine, sshc->readdir_len+1);
+          free(tmpLine);
+
+          if(result) {
+            state(conn, SSH_STOP);
+            break;
+          }
+          /* since this counts what we send to the client, we include the
+             newline in this counter */
+          data->req.bytecount += sshc->readdir_len+1;
+
+          /* output debug output if that is requested */
+          if(data->set.verbose) {
+            Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
+                       sshc->readdir_len, conn);
+          }
+        }
+        else {
+          sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
+          sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
+          sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
+          if(!sshc->readdir_line) {
+            Curl_safefree(sshc->readdir_filename);
+            Curl_safefree(sshc->readdir_longentry);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->actualcode = CURLE_OUT_OF_MEMORY;
+            break;
+          }
+
+          memcpy(sshc->readdir_line, sshc->readdir_longentry,
+                 sshc->readdir_currLen);
+          if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
+             ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
+              LIBSSH2_SFTP_S_IFLNK)) {
+            sshc->readdir_linkPath = malloc(PATH_MAX + 1);
+            if(sshc->readdir_linkPath == NULL) {
+              Curl_safefree(sshc->readdir_filename);
+              Curl_safefree(sshc->readdir_longentry);
+              state(conn, SSH_SFTP_CLOSE);
+              sshc->actualcode = CURLE_OUT_OF_MEMORY;
+              break;
+            }
+
+            snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
+                     sshc->readdir_filename);
+            state(conn, SSH_SFTP_READDIR_LINK);
+            break;
+          }
+          state(conn, SSH_SFTP_READDIR_BOTTOM);
+          break;
+        }
+      }
+      else if(sshc->readdir_len == 0) {
+        Curl_safefree(sshc->readdir_filename);
+        Curl_safefree(sshc->readdir_longentry);
+        state(conn, SSH_SFTP_READDIR_DONE);
+        break;
+      }
+      else if(sshc->readdir_len <= 0) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        result = sftp_libssh2_error_to_CURLE(err);
+        sshc->actualcode = result?result:CURLE_SSH;
+        failf(data, "Could not open remote file for reading: %s :: %d",
+              sftp_libssh2_strerror(err),
+              libssh2_session_last_errno(sshc->ssh_session));
+        Curl_safefree(sshc->readdir_filename);
+        Curl_safefree(sshc->readdir_longentry);
+        state(conn, SSH_SFTP_CLOSE);
+        break;
+      }
+      break;
+
+    case SSH_SFTP_READDIR_LINK:
+      sshc->readdir_len =
+        libssh2_sftp_symlink_ex(sshc->sftp_session,
+                                sshc->readdir_linkPath,
+                                curlx_uztoui(strlen(sshc->readdir_linkPath)),
+                                sshc->readdir_filename,
+                                PATH_MAX, LIBSSH2_SFTP_READLINK);
+      if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
+        rc = LIBSSH2_ERROR_EAGAIN;
+        break;
+      }
+      Curl_safefree(sshc->readdir_linkPath);
+
+      /* get room for the filename and extra output */
+      sshc->readdir_totalLen += 4 + sshc->readdir_len;
+      new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
+      if(!new_readdir_line) {
+        Curl_safefree(sshc->readdir_line);
+        Curl_safefree(sshc->readdir_filename);
+        Curl_safefree(sshc->readdir_longentry);
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+      sshc->readdir_line = new_readdir_line;
+
+      sshc->readdir_currLen += snprintf(sshc->readdir_line +
+                                        sshc->readdir_currLen,
+                                        sshc->readdir_totalLen -
+                                        sshc->readdir_currLen,
+                                        " -> %s",
+                                        sshc->readdir_filename);
+
+      state(conn, SSH_SFTP_READDIR_BOTTOM);
+      break;
+
+    case SSH_SFTP_READDIR_BOTTOM:
+      sshc->readdir_currLen += snprintf(sshc->readdir_line +
+                                        sshc->readdir_currLen,
+                                        sshc->readdir_totalLen -
+                                        sshc->readdir_currLen, "\n");
+      result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                 sshc->readdir_line,
+                                 sshc->readdir_currLen);
+
+      if(!result) {
+
+        /* output debug output if that is requested */
+        if(data->set.verbose) {
+          Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
+                     sshc->readdir_currLen, conn);
+        }
+        data->req.bytecount += sshc->readdir_currLen;
+      }
+      Curl_safefree(sshc->readdir_line);
+      if(result) {
+        state(conn, SSH_STOP);
+      }
+      else
+        state(conn, SSH_SFTP_READDIR);
+      break;
+
+    case SSH_SFTP_READDIR_DONE:
+      if(libssh2_sftp_closedir(sshc->sftp_handle) ==
+         LIBSSH2_ERROR_EAGAIN) {
+        rc = LIBSSH2_ERROR_EAGAIN;
+        break;
+      }
+      sshc->sftp_handle = NULL;
+      Curl_safefree(sshc->readdir_filename);
+      Curl_safefree(sshc->readdir_longentry);
+
+      /* no data to transfer */
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_SFTP_DOWNLOAD_INIT:
+      /*
+       * Work on getting the specified file
+       */
+      sshc->sftp_handle =
+        libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
+                             curlx_uztoui(strlen(sftp_scp->path)),
+                             LIBSSH2_FXF_READ, data->set.new_file_perms,
+                             LIBSSH2_SFTP_OPENFILE);
+      if(!sshc->sftp_handle) {
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+        else {
+          err = sftp_libssh2_last_error(sshc->sftp_session);
+          failf(data, "Could not open remote file for reading: %s",
+                sftp_libssh2_strerror(err));
+          state(conn, SSH_SFTP_CLOSE);
+          result = sftp_libssh2_error_to_CURLE(err);
+          sshc->actualcode = result?result:CURLE_SSH;
+          break;
+        }
+      }
+      state(conn, SSH_SFTP_DOWNLOAD_STAT);
+      break;
+
+    case SSH_SFTP_DOWNLOAD_STAT:
+    {
+      LIBSSH2_SFTP_ATTRIBUTES attrs;
+
+      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
+                                curlx_uztoui(strlen(sftp_scp->path)),
+                                LIBSSH2_SFTP_STAT, &attrs);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      else if(rc ||
+              !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
+              (attrs.filesize == 0)) {
+        /*
+         * libssh2_sftp_open() didn't return an error, so maybe the server
+         * just doesn't support stat()
+         * OR the server doesn't return a file size with a stat()
+         * OR file size is 0
+         */
+        data->req.size = -1;
+        data->req.maxdownload = -1;
+        Curl_pgrsSetDownloadSize(data, -1);
+      }
+      else {
+        curl_off_t size = attrs.filesize;
+
+        if(size < 0) {
+          failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+          return CURLE_BAD_DOWNLOAD_RESUME;
+        }
+        if(conn->data->state.use_range) {
+          curl_off_t from, to;
+          char *ptr;
+          char *ptr2;
+
+          from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
+          while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
+            ptr++;
+          to=curlx_strtoofft(ptr, &ptr2, 0);
+          if((ptr == ptr2) /* no "to" value given */
+             || (to >= size)) {
+            to = size - 1;
+          }
+          if(from < 0) {
+            /* from is relative to end of file */
+            from += size;
+          }
+          if(from > size) {
+            failf(data, "Offset (%"
+                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
+                  CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+          if(from > to) {
+            from = to;
+            size = 0;
+          }
+          else {
+            size = to - from + 1;
+          }
+
+          SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
+        }
+        data->req.size = size;
+        data->req.maxdownload = size;
+        Curl_pgrsSetDownloadSize(data, size);
+      }
+
+      /* We can resume if we can seek to the resume position */
+      if(data->state.resume_from) {
+        if(data->state.resume_from < 0) {
+          /* We're supposed to download the last abs(from) bytes */
+          if((curl_off_t)attrs.filesize < -data->state.resume_from) {
+            failf(data, "Offset (%"
+                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
+                  CURL_FORMAT_CURL_OFF_T ")",
+                  data->state.resume_from, attrs.filesize);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+          /* download from where? */
+          data->state.resume_from += attrs.filesize;
+        }
+        else {
+          if((curl_off_t)attrs.filesize < data->state.resume_from) {
+            failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
+                  ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
+                  data->state.resume_from, attrs.filesize);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+        }
+        /* Does a completed file need to be seeked and started or closed ? */
+        /* Now store the number of bytes we are expected to download */
+        data->req.size = attrs.filesize - data->state.resume_from;
+        data->req.maxdownload = attrs.filesize - data->state.resume_from;
+        Curl_pgrsSetDownloadSize(data,
+                                 attrs.filesize - data->state.resume_from);
+        SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
+      }
+    }
+
+    /* Setup the actual download */
+    if(data->req.size == 0) {
+      /* no data to transfer */
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+      infof(data, "File already completely downloaded\n");
+      state(conn, SSH_STOP);
+      break;
+    }
+    else {
+      Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
+                          FALSE, NULL, -1, NULL);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->writesockfd = conn->sockfd;
+
+      /* we want to use the _receiving_ function even when the socket turns
+         out writableable as the underlying libssh2 recv function will deal
+         with both accordingly */
+      conn->cselect_bits = CURL_CSELECT_IN;
+    }
+    if(result) {
+      /* this should never occur; the close state should be entered
+         at the time the error occurs */
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->actualcode = result;
+    }
+    else {
+      state(conn, SSH_STOP);
+    }
+    break;
+
+    case SSH_SFTP_CLOSE:
+      if(sshc->sftp_handle) {
+        rc = libssh2_sftp_close(sshc->sftp_handle);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        else if(rc < 0) {
+          infof(data, "Failed to close libssh2 file\n");
+        }
+        sshc->sftp_handle = NULL;
+      }
+      if(sftp_scp)
+        Curl_safefree(sftp_scp->path);
+
+      DEBUGF(infof(data, "SFTP DONE done\n"));
+
+      /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
+         After nextstate is executed, the control should come back to
+         SSH_SFTP_CLOSE to pass the correct result back  */
+      if(sshc->nextstate != SSH_NO_STATE &&
+         sshc->nextstate != SSH_SFTP_CLOSE) {
+        state(conn, sshc->nextstate);
+        sshc->nextstate = SSH_SFTP_CLOSE;
+      }
+      else {
+        state(conn, SSH_STOP);
+        result = sshc->actualcode;
+      }
+      break;
+
+    case SSH_SFTP_SHUTDOWN:
+      /* during times we get here due to a broken transfer and then the
+         sftp_handle might not have been taken down so make sure that is done
+         before we proceed */
+
+      if(sshc->sftp_handle) {
+        rc = libssh2_sftp_close(sshc->sftp_handle);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        else if(rc < 0) {
+          infof(data, "Failed to close libssh2 file\n");
+        }
+        sshc->sftp_handle = NULL;
+      }
+      if(sshc->sftp_session) {
+        rc = libssh2_sftp_shutdown(sshc->sftp_session);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        else if(rc < 0) {
+          infof(data, "Failed to stop libssh2 sftp subsystem\n");
+        }
+        sshc->sftp_session = NULL;
+      }
+
+      Curl_safefree(sshc->homedir);
+      conn->data->state.most_recent_ftp_entrypath = NULL;
+
+      state(conn, SSH_SESSION_DISCONNECT);
+      break;
+
+    case SSH_SCP_TRANS_INIT:
+      result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
+      if(result) {
+        sshc->actualcode = result;
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      if(data->set.upload) {
+        if(data->state.infilesize < 0) {
+          failf(data, "SCP requires a known file size for upload");
+          sshc->actualcode = CURLE_UPLOAD_FAILED;
+          state(conn, SSH_SCP_CHANNEL_FREE);
+          break;
+        }
+        state(conn, SSH_SCP_UPLOAD_INIT);
+      }
+      else {
+        state(conn, SSH_SCP_DOWNLOAD_INIT);
+      }
+      break;
+
+    case SSH_SCP_UPLOAD_INIT:
+      /*
+       * libssh2 requires that the destination path is a full path that
+       * includes the destination file and name OR ends in a "/" .  If this is
+       * not done the destination file will be named the same name as the last
+       * directory in the path.
+       */
+      sshc->ssh_channel =
+        SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
+                 data->state.infilesize);
+      if(!sshc->ssh_channel) {
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+        else {
+          int ssh_err;
+          char *err_msg;
+
+          ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
+                                                     &err_msg, NULL, 0));
+          failf(conn->data, "%s", err_msg);
+          state(conn, SSH_SCP_CHANNEL_FREE);
+          sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
+          break;
+        }
+      }
+
+      /* upload data */
+      Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
+                          FIRSTSOCKET, NULL);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->sockfd = conn->writesockfd;
+
+      if(result) {
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = result;
+      }
+      else {
+        /* store this original bitmask setup to use later on if we can't
+           figure out a "real" bitmask */
+        sshc->orig_waitfor = data->req.keepon;
+
+        /* we want to use the _sending_ function even when the socket turns
+           out readable as the underlying libssh2 scp send function will deal
+           with both accordingly */
+        conn->cselect_bits = CURL_CSELECT_OUT;
+
+        state(conn, SSH_STOP);
+      }
+      break;
+
+    case SSH_SCP_DOWNLOAD_INIT:
+    {
+      /*
+       * We must check the remote file; if it is a directory no values will
+       * be set in sb
+       */
+      struct stat sb;
+      curl_off_t bytecount;
+
+      /* clear the struct scp recv will fill in */
+      memset(&sb, 0, sizeof(struct stat));
+
+      /* get a fresh new channel from the ssh layer */
+      sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
+                                           sftp_scp->path, &sb);
+      if(!sshc->ssh_channel) {
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+        else {
+          int ssh_err;
+          char *err_msg;
+
+          ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
+                                                     &err_msg, NULL, 0));
+          failf(conn->data, "%s", err_msg);
+          state(conn, SSH_SCP_CHANNEL_FREE);
+          sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
+          break;
+        }
+      }
+
+      /* download data */
+      bytecount = (curl_off_t)sb.st_size;
+      data->req.maxdownload =  (curl_off_t)sb.st_size;
+      Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->writesockfd = conn->sockfd;
+
+      /* we want to use the _receiving_ function even when the socket turns
+         out writableable as the underlying libssh2 recv function will deal
+         with both accordingly */
+      conn->cselect_bits = CURL_CSELECT_IN;
+
+      if(result) {
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = result;
+      }
+      else
+        state(conn, SSH_STOP);
+    }
+    break;
+
+    case SSH_SCP_DONE:
+      if(data->set.upload)
+        state(conn, SSH_SCP_SEND_EOF);
+      else
+        state(conn, SSH_SCP_CHANNEL_FREE);
+      break;
+
+    case SSH_SCP_SEND_EOF:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_send_eof(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        else if(rc) {
+          infof(data, "Failed to send libssh2 channel EOF\n");
+        }
+      }
+      state(conn, SSH_SCP_WAIT_EOF);
+      break;
+
+    case SSH_SCP_WAIT_EOF:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_wait_eof(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        else if(rc) {
+          infof(data, "Failed to get channel EOF: %d\n", rc);
+        }
+      }
+      state(conn, SSH_SCP_WAIT_CLOSE);
+      break;
+
+    case SSH_SCP_WAIT_CLOSE:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_wait_closed(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        else if(rc) {
+          infof(data, "Channel failed to close: %d\n", rc);
+        }
+      }
+      state(conn, SSH_SCP_CHANNEL_FREE);
+      break;
+
+    case SSH_SCP_CHANNEL_FREE:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_free(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        else if(rc < 0) {
+          infof(data, "Failed to free libssh2 scp subsystem\n");
+        }
+        sshc->ssh_channel = NULL;
+      }
+      DEBUGF(infof(data, "SCP DONE phase complete\n"));
+#if 0 /* PREV */
+      state(conn, SSH_SESSION_DISCONNECT);
+#endif
+      state(conn, SSH_STOP);
+      result = sshc->actualcode;
+      break;
+
+    case SSH_SESSION_DISCONNECT:
+      /* during weird times when we've been prematurely aborted, the channel
+         is still alive when we reach this state and we MUST kill the channel
+         properly first */
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_free(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        else if(rc < 0) {
+          infof(data, "Failed to free libssh2 scp subsystem\n");
+        }
+        sshc->ssh_channel = NULL;
+      }
+
+      if(sshc->ssh_session) {
+        rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        else if(rc < 0) {
+          infof(data, "Failed to disconnect libssh2 session\n");
+        }
+      }
+
+      Curl_safefree(sshc->homedir);
+      conn->data->state.most_recent_ftp_entrypath = NULL;
+
+      state(conn, SSH_SESSION_FREE);
+      break;
+
+    case SSH_SESSION_FREE:
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+      if(sshc->kh) {
+        libssh2_knownhost_free(sshc->kh);
+        sshc->kh = NULL;
+      }
+#endif
+
+#ifdef HAVE_LIBSSH2_AGENT_API
+      if(sshc->ssh_agent) {
+        rc = libssh2_agent_disconnect(sshc->ssh_agent);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        else if(rc < 0) {
+          infof(data, "Failed to disconnect from libssh2 agent\n");
+        }
+        libssh2_agent_free (sshc->ssh_agent);
+        sshc->ssh_agent = NULL;
+
+        /* NB: there is no need to free identities, they are part of internal
+           agent stuff */
+        sshc->sshagent_identity = NULL;
+        sshc->sshagent_prev_identity = NULL;
+      }
+#endif
+
+      if(sshc->ssh_session) {
+        rc = libssh2_session_free(sshc->ssh_session);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        else if(rc < 0) {
+          infof(data, "Failed to free libssh2 session\n");
+        }
+        sshc->ssh_session = NULL;
+      }
+
+      /* worst-case scenario cleanup */
+
+      DEBUGASSERT(sshc->ssh_session == NULL);
+      DEBUGASSERT(sshc->ssh_channel == NULL);
+      DEBUGASSERT(sshc->sftp_session == NULL);
+      DEBUGASSERT(sshc->sftp_handle == NULL);
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+      DEBUGASSERT(sshc->kh == NULL);
+#endif
+#ifdef HAVE_LIBSSH2_AGENT_API
+      DEBUGASSERT(sshc->ssh_agent == NULL);
+#endif
+
+      Curl_safefree(sshc->rsa_pub);
+      Curl_safefree(sshc->rsa);
+
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+
+      Curl_safefree(sshc->homedir);
+
+      Curl_safefree(sshc->readdir_filename);
+      Curl_safefree(sshc->readdir_longentry);
+      Curl_safefree(sshc->readdir_line);
+      Curl_safefree(sshc->readdir_linkPath);
+
+      /* the code we are about to return */
+      result = sshc->actualcode;
+
+      memset(sshc, 0, sizeof(struct ssh_conn));
+
+      connclose(conn, "SSH session free");
+      sshc->state = SSH_SESSION_FREE; /* current */
+      sshc->nextstate = SSH_NO_STATE;
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_QUIT:
+      /* fallthrough, just stop! */
+    default:
+      /* internal error */
+      sshc->nextstate = SSH_NO_STATE;
+      state(conn, SSH_STOP);
+      break;
+    }
+
+  } while(!rc && (sshc->state != SSH_STOP));
+
+  if(rc == LIBSSH2_ERROR_EAGAIN) {
+    /* we would block, we need to wait for the socket to be ready (in the
+       right direction too)! */
+    *block = TRUE;
+  }
+
+  return result;
+}
+
+/* called by the multi interface to figure out what socket(s) to wait for and
+   for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
+static int ssh_perform_getsock(const struct connectdata *conn,
+                               curl_socket_t *sock, /* points to numsocks
+                                                       number of sockets */
+                               int numsocks)
+{
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+  int bitmap = GETSOCK_BLANK;
+  (void)numsocks;
+
+  sock[0] = conn->sock[FIRSTSOCKET];
+
+  if(conn->waitfor & KEEP_RECV)
+    bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+
+  if(conn->waitfor & KEEP_SEND)
+    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
+
+  return bitmap;
+#else
+  /* if we don't know the direction we can use the generic *_getsock()
+     function even for the protocol_connect and doing states */
+  return Curl_single_getsock(conn, sock, numsocks);
+#endif
+}
+
+/* Generic function called by the multi interface to figure out what socket(s)
+   to wait for and for what actions during the DOING and PROTOCONNECT states*/
+static int ssh_getsock(struct connectdata *conn,
+                       curl_socket_t *sock, /* points to numsocks number
+                                               of sockets */
+                       int numsocks)
+{
+#ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+  (void)conn;
+  (void)sock;
+  (void)numsocks;
+  /* if we don't know any direction we can just play along as we used to and
+     not provide any sensible info */
+  return GETSOCK_BLANK;
+#else
+  /* if we know the direction we can use the generic *_getsock() function even
+     for the protocol_connect and doing states */
+  return ssh_perform_getsock(conn, sock, numsocks);
+#endif
+}
+
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+/*
+ * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
+ * function is used to figure out in what direction and stores this info so
+ * that the multi interface can take advantage of it. Make sure to call this
+ * function in all cases so that when it _doesn't_ return EAGAIN we can
+ * restore the default wait bits.
+ */
+static void ssh_block2waitfor(struct connectdata *conn, bool block)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  int dir;
+  if(block && (dir = libssh2_session_block_directions(sshc->ssh_session))) {
+    /* translate the libssh2 define bits into our own bit defines */
+    conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
+      ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
+  }
+  else
+    /* It didn't block or libssh2 didn't reveal in which direction, put back
+       the original set */
+    conn->waitfor = sshc->orig_waitfor;
+}
+#else
+  /* no libssh2 directional support so we simply don't know */
+#define ssh_block2waitfor(x,y) Curl_nop_stmt
+#endif
+
+/* called repeatedly until done from multi.c */
+static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  CURLcode result = CURLE_OK;
+  bool block; /* we store the status and use that to provide a ssh_getsock()
+                 implementation */
+
+  result = ssh_statemach_act(conn, &block);
+  *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
+  ssh_block2waitfor(conn, block);
+
+  return result;
+}
+
+static CURLcode ssh_block_statemach(struct connectdata *conn,
+                                   bool duringconnect)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  while((sshc->state != SSH_STOP) && !result) {
+    bool block;
+    long left;
+
+    result = ssh_statemach_act(conn, &block);
+    if(result)
+      break;
+
+    if(Curl_pgrsUpdate(conn))
+      return CURLE_ABORTED_BY_CALLBACK;
+    else {
+      struct timeval now = Curl_tvnow();
+      result = Curl_speedcheck(data, now);
+      if(result)
+        break;
+    }
+
+    left = Curl_timeleft(data, NULL, duringconnect);
+    if(left < 0) {
+      failf(data, "Operation timed out");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+    if(!result && block) {
+      int dir = libssh2_session_block_directions(sshc->ssh_session);
+      curl_socket_t sock = conn->sock[FIRSTSOCKET];
+      curl_socket_t fd_read = CURL_SOCKET_BAD;
+      curl_socket_t fd_write = CURL_SOCKET_BAD;
+      if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
+        fd_read = sock;
+      if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
+        fd_write = sock;
+      /* wait for the socket to become ready */
+      Curl_socket_ready(fd_read, fd_write,
+                        left>1000?1000:left); /* ignore result */
+    }
+#endif
+
+  }
+
+  return result;
+}
+
+/*
+ * SSH setup and connection
+ */
+static CURLcode ssh_setup_connection(struct connectdata *conn)
+{
+  struct SSHPROTO *ssh;
+
+  conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+  if(!ssh)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+static Curl_recv scp_recv, sftp_recv;
+static Curl_send scp_send, sftp_send;
+
+/*
+ * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
+ * do protocol-specific actions at connect-time.
+ */
+static CURLcode ssh_connect(struct connectdata *conn, bool *done)
+{
+#ifdef CURL_LIBSSH2_DEBUG
+  curl_socket_t sock;
+#endif
+  struct ssh_conn *ssh;
+  CURLcode result;
+  struct SessionHandle *data = conn->data;
+
+  /* initialize per-handle data if not already */
+  if(!data->req.protop)
+    ssh_setup_connection(conn);
+
+  /* We default to persistent connections. We set this already in this connect
+     function to make the re-use checks properly be able to check this bit. */
+  connkeep(conn, "SSH default");
+
+  if(conn->handler->protocol & CURLPROTO_SCP) {
+    conn->recv[FIRSTSOCKET] = scp_recv;
+    conn->send[FIRSTSOCKET] = scp_send;
+  }
+  else {
+    conn->recv[FIRSTSOCKET] = sftp_recv;
+    conn->send[FIRSTSOCKET] = sftp_send;
+  }
+  ssh = &conn->proto.sshc;
+
+#ifdef CURL_LIBSSH2_DEBUG
+  if(conn->user) {
+    infof(data, "User: %s\n", conn->user);
+  }
+  if(conn->passwd) {
+    infof(data, "Password: %s\n", conn->passwd);
+  }
+  sock = conn->sock[FIRSTSOCKET];
+#endif /* CURL_LIBSSH2_DEBUG */
+
+  ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
+                                             my_libssh2_free,
+                                             my_libssh2_realloc, conn);
+  if(ssh->ssh_session == NULL) {
+    failf(data, "Failure initialising ssh session");
+    return CURLE_FAILED_INIT;
+  }
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
+    int rc;
+    ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
+    if(!ssh->kh) {
+      /* eeek. TODO: free the ssh_session! */
+      return CURLE_FAILED_INIT;
+    }
+
+    /* read all known hosts from there */
+    rc = libssh2_knownhost_readfile(ssh->kh,
+                                    data->set.str[STRING_SSH_KNOWNHOSTS],
+                                    LIBSSH2_KNOWNHOST_FILE_OPENSSH);
+    if(rc < 0)
+      infof(data, "Failed to read known hosts from %s\n",
+            data->set.str[STRING_SSH_KNOWNHOSTS]);
+  }
+#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
+
+#ifdef CURL_LIBSSH2_DEBUG
+  libssh2_trace(ssh->ssh_session, ~0);
+  infof(data, "SSH socket: %d\n", (int)sock);
+#endif /* CURL_LIBSSH2_DEBUG */
+
+  state(conn, SSH_INIT);
+
+  result = ssh_multi_statemach(conn, done);
+
+  return result;
+}
+
+/*
+ ***********************************************************************
+ *
+ * scp_perform()
+ *
+ * This is the actual DO function for SCP. Get a file according to
+ * the options previously setup.
+ */
+
+static
+CURLcode scp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* start the first command in the DO phase */
+  state(conn, SSH_SCP_TRANS_INIT);
+
+  /* run the state-machine */
+  result = ssh_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/* called from multi.c while DOing */
+static CURLcode scp_doing(struct connectdata *conn,
+                               bool *dophase_done)
+{
+  CURLcode result;
+  result = ssh_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  return result;
+}
+
+/*
+ * The DO function is generic for both protocols. There was previously two
+ * separate ones but this way means less duplicated code.
+ */
+
+static CURLcode ssh_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result;
+  bool connected = 0;
+  struct SessionHandle *data = conn->data;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  *done = FALSE; /* default to false */
+
+  data->req.size = -1; /* make sure this is unknown at this point */
+
+  sshc->actualcode = CURLE_OK; /* reset error code */
+  sshc->secondCreateDirs =0;   /* reset the create dir attempt state
+                                  variable */
+
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  if(conn->handler->protocol & CURLPROTO_SCP)
+    result = scp_perform(conn, &connected,  done);
+  else
+    result = sftp_perform(conn, &connected,  done);
+
+  return result;
+}
+
+/* BLOCKING, but the function is using the state machine so the only reason
+   this is still blocking is that the multi interface code has no support for
+   disconnecting operations that takes a while */
+static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  CURLcode result = CURLE_OK;
+  struct ssh_conn *ssh = &conn->proto.sshc;
+  (void) dead_connection;
+
+  Curl_safefree(conn->data->req.protop);
+
+  if(ssh->ssh_session) {
+    /* only if there's a session still around to use! */
+
+    state(conn, SSH_SESSION_DISCONNECT);
+
+    result = ssh_block_statemach(conn, FALSE);
+  }
+
+  return result;
+}
+
+/* generic done function for both SCP and SFTP called from their specific
+   done functions */
+static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
+{
+  CURLcode result = CURLE_OK;
+  struct SSHPROTO *sftp_scp = conn->data->req.protop;
+
+  if(!status) {
+    /* run the state-machine
+
+       TODO: when the multi interface is used, this _really_ should be using
+       the ssh_multi_statemach function but we have no general support for
+       non-blocking DONE operations, not in the multi state machine and with
+       Curl_done() invokes on several places in the code!
+    */
+    result = ssh_block_statemach(conn, FALSE);
+  }
+  else
+    result = status;
+
+  if(sftp_scp)
+    Curl_safefree(sftp_scp->path);
+  if(Curl_pgrsDone(conn))
+    return CURLE_ABORTED_BY_CALLBACK;
+
+  conn->data->req.keepon = 0; /* clear all bits */
+  return result;
+}
+
+
+static CURLcode scp_done(struct connectdata *conn, CURLcode status,
+                         bool premature)
+{
+  (void)premature; /* not used */
+
+  if(!status)
+    state(conn, SSH_SCP_DONE);
+
+  return ssh_done(conn, status);
+
+}
+
+/* return number of received (decrypted) bytes */
+static ssize_t scp_send(struct connectdata *conn, int sockindex,
+                        const void *mem, size_t len, CURLcode *err)
+{
+  ssize_t nwrite;
+  (void)sockindex; /* we only support SCP on the fixed known primary socket */
+
+  /* libssh2_channel_write() returns int! */
+  nwrite = (ssize_t)
+    libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
+
+  ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+  if(nwrite == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nwrite = 0;
+  }
+  else if(nwrite < LIBSSH2_ERROR_NONE) {
+    *err = libssh2_session_error_to_CURLE((int)nwrite);
+    nwrite = -1;
+  }
+
+  return nwrite;
+}
+
+/*
+ * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
+ * a regular CURLcode value.
+ */
+static ssize_t scp_recv(struct connectdata *conn, int sockindex,
+                        char *mem, size_t len, CURLcode *err)
+{
+  ssize_t nread;
+  (void)sockindex; /* we only support SCP on the fixed known primary socket */
+
+  /* libssh2_channel_read() returns int */
+  nread = (ssize_t)
+    libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
+
+  ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+  if(nread == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nread = -1;
+  }
+
+  return nread;
+}
+
+/*
+ * =============== SFTP ===============
+ */
+
+/*
+ ***********************************************************************
+ *
+ * sftp_perform()
+ *
+ * This is the actual DO function for SFTP. Get a file/directory according to
+ * the options previously setup.
+ */
+
+static
+CURLcode sftp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* start the first command in the DO phase */
+  state(conn, SSH_SFTP_QUOTE_INIT);
+
+  /* run the state-machine */
+  result = ssh_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/* called from multi.c while DOing */
+static CURLcode sftp_doing(struct connectdata *conn,
+                           bool *dophase_done)
+{
+  CURLcode result = ssh_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  return result;
+}
+
+/* BLOCKING, but the function is using the state machine so the only reason
+   this is still blocking is that the multi interface code has no support for
+   disconnecting operations that takes a while */
+static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  CURLcode result = CURLE_OK;
+  (void) dead_connection;
+
+  DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
+
+  Curl_safefree(conn->data->req.protop);
+
+  if(conn->proto.sshc.ssh_session) {
+    /* only if there's a session still around to use! */
+    state(conn, SSH_SFTP_SHUTDOWN);
+    result = ssh_block_statemach(conn, FALSE);
+  }
+
+  DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
+
+  return result;
+
+}
+
+static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
+                               bool premature)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  if(!status) {
+    /* Post quote commands are executed after the SFTP_CLOSE state to avoid
+       errors that could happen due to open file handles during POSTQUOTE
+       operation */
+    if(!status && !premature && conn->data->set.postquote) {
+      sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
+      state(conn, SSH_SFTP_CLOSE);
+    }
+    else
+      state(conn, SSH_SFTP_CLOSE);
+  }
+  return ssh_done(conn, status);
+}
+
+/* return number of sent bytes */
+static ssize_t sftp_send(struct connectdata *conn, int sockindex,
+                         const void *mem, size_t len, CURLcode *err)
+{
+  ssize_t nwrite;   /* libssh2_sftp_write() used to return size_t in 0.14
+                       but is changed to ssize_t in 0.15. These days we don't
+                       support libssh2 0.15*/
+  (void)sockindex;
+
+  nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
+
+  ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+  if(nwrite == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nwrite = 0;
+  }
+  else if(nwrite < LIBSSH2_ERROR_NONE) {
+    *err = libssh2_session_error_to_CURLE((int)nwrite);
+    nwrite = -1;
+  }
+
+  return nwrite;
+}
+
+/*
+ * Return number of received (decrypted) bytes
+ * or <0 on error
+ */
+static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
+                         char *mem, size_t len, CURLcode *err)
+{
+  ssize_t nread;
+  (void)sockindex;
+
+  nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
+
+  ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+  if(nread == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nread = -1;
+
+  }
+  else if(nread < 0) {
+    *err = libssh2_session_error_to_CURLE((int)nread);
+  }
+  return nread;
+}
+
+/* The get_pathname() function is being borrowed from OpenSSH sftp.c
+   version 4.6p1. */
+/*
+ * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
+ *
+ * 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.
+ */
+static CURLcode
+get_pathname(const char **cpp, char **path)
+{
+  const char *cp = *cpp, *end;
+  char quot;
+  unsigned int i, j;
+  static const char WHITESPACE[] = " \t\r\n";
+
+  cp += strspn(cp, WHITESPACE);
+  if(!*cp) {
+    *cpp = cp;
+    *path = NULL;
+    return CURLE_QUOTE_ERROR;
+  }
+
+  *path = malloc(strlen(cp) + 1);
+  if(*path == NULL)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Check for quoted filenames */
+  if(*cp == '\"' || *cp == '\'') {
+    quot = *cp++;
+
+    /* Search for terminating quote, unescape some chars */
+    for(i = j = 0; i <= strlen(cp); i++) {
+      if(cp[i] == quot) {  /* Found quote */
+        i++;
+        (*path)[j] = '\0';
+        break;
+      }
+      if(cp[i] == '\0') {  /* End of string */
+        /*error("Unterminated quote");*/
+        goto fail;
+      }
+      if(cp[i] == '\\') {  /* Escaped characters */
+        i++;
+        if(cp[i] != '\'' && cp[i] != '\"' &&
+            cp[i] != '\\') {
+          /*error("Bad escaped character '\\%c'",
+              cp[i]);*/
+          goto fail;
+        }
+      }
+      (*path)[j++] = cp[i];
+    }
+
+    if(j == 0) {
+      /*error("Empty quotes");*/
+      goto fail;
+    }
+    *cpp = cp + i + strspn(cp + i, WHITESPACE);
+  }
+  else {
+    /* Read to end of filename */
+    end = strpbrk(cp, WHITESPACE);
+    if(end == NULL)
+      end = strchr(cp, '\0');
+    *cpp = end + strspn(end, WHITESPACE);
+
+    memcpy(*path, cp, end - cp);
+    (*path)[end - cp] = '\0';
+  }
+  return CURLE_OK;
+
+  fail:
+  Curl_safefree(*path);
+  return CURLE_QUOTE_ERROR;
+}
+
+
+static const char *sftp_libssh2_strerror(int err)
+{
+  switch (err) {
+    case LIBSSH2_FX_NO_SUCH_FILE:
+      return "No such file or directory";
+
+    case LIBSSH2_FX_PERMISSION_DENIED:
+      return "Permission denied";
+
+    case LIBSSH2_FX_FAILURE:
+      return "Operation failed";
+
+    case LIBSSH2_FX_BAD_MESSAGE:
+      return "Bad message from SFTP server";
+
+    case LIBSSH2_FX_NO_CONNECTION:
+      return "Not connected to SFTP server";
+
+    case LIBSSH2_FX_CONNECTION_LOST:
+      return "Connection to SFTP server lost";
+
+    case LIBSSH2_FX_OP_UNSUPPORTED:
+      return "Operation not supported by SFTP server";
+
+    case LIBSSH2_FX_INVALID_HANDLE:
+      return "Invalid handle";
+
+    case LIBSSH2_FX_NO_SUCH_PATH:
+      return "No such file or directory";
+
+    case LIBSSH2_FX_FILE_ALREADY_EXISTS:
+      return "File already exists";
+
+    case LIBSSH2_FX_WRITE_PROTECT:
+      return "File is write protected";
+
+    case LIBSSH2_FX_NO_MEDIA:
+      return "No media";
+
+    case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
+      return "Disk full";
+
+    case LIBSSH2_FX_QUOTA_EXCEEDED:
+      return "User quota exceeded";
+
+    case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
+      return "Unknown principle";
+
+    case LIBSSH2_FX_LOCK_CONFlICT:
+      return "File lock conflict";
+
+    case LIBSSH2_FX_DIR_NOT_EMPTY:
+      return "Directory not empty";
+
+    case LIBSSH2_FX_NOT_A_DIRECTORY:
+      return "Not a directory";
+
+    case LIBSSH2_FX_INVALID_FILENAME:
+      return "Invalid filename";
+
+    case LIBSSH2_FX_LINK_LOOP:
+      return "Link points to itself";
+  }
+  return "Unknown error in libssh2";
+}
+
+#endif /* USE_LIBSSH2 */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/ssh.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/ssh.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/ssh.h	(revision 164)
@@ -0,0 +1,195 @@
+#ifndef HEADER_CURL_SSH_H
+#define HEADER_CURL_SSH_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_LIBSSH2_H
+#include <libssh2.h>
+#include <libssh2_sftp.h>
+#endif /* HAVE_LIBSSH2_H */
+
+/****************************************************************************
+ * SSH unique setup
+ ***************************************************************************/
+typedef enum {
+  SSH_NO_STATE = -1,  /* Used for "nextState" so say there is none */
+  SSH_STOP = 0,       /* do nothing state, stops the state machine */
+
+  SSH_INIT,           /* First state in SSH-CONNECT */
+  SSH_S_STARTUP,      /* Session startup */
+  SSH_HOSTKEY,        /* verify hostkey */
+  SSH_AUTHLIST,
+  SSH_AUTH_PKEY_INIT,
+  SSH_AUTH_PKEY,
+  SSH_AUTH_PASS_INIT,
+  SSH_AUTH_PASS,
+  SSH_AUTH_AGENT_INIT, /* initialize then wait for connection to agent */
+  SSH_AUTH_AGENT_LIST, /* ask for list then wait for entire list to come */
+  SSH_AUTH_AGENT,      /* attempt one key at a time */
+  SSH_AUTH_HOST_INIT,
+  SSH_AUTH_HOST,
+  SSH_AUTH_KEY_INIT,
+  SSH_AUTH_KEY,
+  SSH_AUTH_DONE,
+  SSH_SFTP_INIT,
+  SSH_SFTP_REALPATH,   /* Last state in SSH-CONNECT */
+
+  SSH_SFTP_QUOTE_INIT, /* First state in SFTP-DO */
+  SSH_SFTP_POSTQUOTE_INIT, /* (Possibly) First state in SFTP-DONE */
+  SSH_SFTP_QUOTE,
+  SSH_SFTP_NEXT_QUOTE,
+  SSH_SFTP_QUOTE_STAT,
+  SSH_SFTP_QUOTE_SETSTAT,
+  SSH_SFTP_QUOTE_SYMLINK,
+  SSH_SFTP_QUOTE_MKDIR,
+  SSH_SFTP_QUOTE_RENAME,
+  SSH_SFTP_QUOTE_RMDIR,
+  SSH_SFTP_QUOTE_UNLINK,
+  SSH_SFTP_TRANS_INIT,
+  SSH_SFTP_UPLOAD_INIT,
+  SSH_SFTP_CREATE_DIRS_INIT,
+  SSH_SFTP_CREATE_DIRS,
+  SSH_SFTP_CREATE_DIRS_MKDIR,
+  SSH_SFTP_READDIR_INIT,
+  SSH_SFTP_READDIR,
+  SSH_SFTP_READDIR_LINK,
+  SSH_SFTP_READDIR_BOTTOM,
+  SSH_SFTP_READDIR_DONE,
+  SSH_SFTP_DOWNLOAD_INIT,
+  SSH_SFTP_DOWNLOAD_STAT, /* Last state in SFTP-DO */
+  SSH_SFTP_CLOSE,    /* Last state in SFTP-DONE */
+  SSH_SFTP_SHUTDOWN, /* First state in SFTP-DISCONNECT */
+  SSH_SCP_TRANS_INIT, /* First state in SCP-DO */
+  SSH_SCP_UPLOAD_INIT,
+  SSH_SCP_DOWNLOAD_INIT,
+  SSH_SCP_DONE,
+  SSH_SCP_SEND_EOF,
+  SSH_SCP_WAIT_EOF,
+  SSH_SCP_WAIT_CLOSE,
+  SSH_SCP_CHANNEL_FREE,   /* Last state in SCP-DONE */
+  SSH_SESSION_DISCONNECT, /* First state in SCP-DISCONNECT */
+  SSH_SESSION_FREE,       /* Last state in SCP/SFTP-DISCONNECT */
+  SSH_QUIT,
+  SSH_LAST  /* never used */
+} sshstate;
+
+/* this struct is used in the HandleData struct which is part of the
+   SessionHandle, which means this is used on a per-easy handle basis.
+   Everything that is strictly related to a connection is banned from this
+   struct. */
+struct SSHPROTO {
+  char *path;                  /* the path we operate on */
+};
+
+/* ssh_conn is used for struct connection-oriented data in the connectdata
+   struct */
+struct ssh_conn {
+  const char *authlist;       /* List of auth. methods, managed by libssh2 */
+#ifdef USE_LIBSSH2
+  const char *passphrase;     /* pass-phrase to use */
+  char *rsa_pub;              /* path name */
+  char *rsa;                  /* path name */
+  bool authed;                /* the connection has been authenticated fine */
+  sshstate state;             /* always use ssh.c:state() to change state! */
+  sshstate nextstate;         /* the state to goto after stopping */
+  CURLcode actualcode;        /* the actual error code */
+  struct curl_slist *quote_item; /* for the quote option */
+  char *quote_path1;          /* two generic pointers for the QUOTE stuff */
+  char *quote_path2;
+  LIBSSH2_SFTP_ATTRIBUTES quote_attrs; /* used by the SFTP_QUOTE state */
+  bool acceptfail;            /* used by the SFTP_QUOTE (continue if
+                                 quote command fails) */
+  char *homedir;              /* when doing SFTP we figure out home dir in the
+                                 connect phase */
+
+  /* Here's a set of struct members used by the SFTP_READDIR state */
+  LIBSSH2_SFTP_ATTRIBUTES readdir_attrs;
+  char *readdir_filename;
+  char *readdir_longentry;
+  int readdir_len, readdir_totalLen, readdir_currLen;
+  char *readdir_line;
+  char *readdir_linkPath;
+  /* end of READDIR stuff */
+
+  int secondCreateDirs;         /* counter use by the code to see if the
+                                   second attempt has been made to change
+                                   to/create a directory */
+  char *slash_pos;              /* used by the SFTP_CREATE_DIRS state */
+  LIBSSH2_SESSION *ssh_session; /* Secure Shell session */
+  LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */
+  LIBSSH2_SFTP *sftp_session;   /* SFTP handle */
+  LIBSSH2_SFTP_HANDLE *sftp_handle;
+  int orig_waitfor;             /* default READ/WRITE bits wait for */
+
+#ifdef HAVE_LIBSSH2_AGENT_API
+  LIBSSH2_AGENT *ssh_agent;     /* proxy to ssh-agent/pageant */
+  struct libssh2_agent_publickey *sshagent_identity,
+                                 *sshagent_prev_identity;
+#endif
+
+  /* note that HAVE_LIBSSH2_KNOWNHOST_API is a define set in the libssh2.h
+     header */
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+  LIBSSH2_KNOWNHOSTS *kh;
+#endif
+#endif /* USE_LIBSSH2 */
+};
+
+#ifdef USE_LIBSSH2
+
+/* Feature detection based on version numbers to better work with
+   non-configure platforms */
+
+#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x001000)
+#  error "SCP/SFTP protocols require libssh2 0.16 or later"
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010000
+#define HAVE_LIBSSH2_SFTP_SEEK64 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010100
+#define HAVE_LIBSSH2_VERSION 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010205
+#define HAVE_LIBSSH2_INIT 1
+#define HAVE_LIBSSH2_EXIT 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010206
+#define HAVE_LIBSSH2_KNOWNHOST_CHECKP 1
+#define HAVE_LIBSSH2_SCP_SEND64 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010208
+#define HAVE_LIBSSH2_SESSION_HANDSHAKE 1
+#endif
+
+extern const struct Curl_handler Curl_handler_scp;
+extern const struct Curl_handler Curl_handler_sftp;
+
+#endif /* USE_LIBSSH2 */
+
+#endif /* HEADER_CURL_SSH_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/strdup.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/strdup.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/strdup.c	(revision 164)
@@ -0,0 +1,73 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+#include "strdup.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifndef HAVE_STRDUP
+char *curlx_strdup(const char *str)
+{
+  size_t len;
+  char *newstr;
+
+  if(!str)
+    return (char *)NULL;
+
+  len = strlen(str);
+
+  if(len >= ((size_t)-1) / sizeof(char))
+    return (char *)NULL;
+
+  newstr = malloc((len+1)*sizeof(char));
+  if(!newstr)
+    return (char *)NULL;
+
+  memcpy(newstr, str, (len+1)*sizeof(char));
+
+  return newstr;
+
+}
+#endif
+
+/***************************************************************************
+ *
+ * Curl_memdup(source, length)
+ *
+ * Copies the 'source' data to a newly allocated buffer (that is
+ * returned). Copies 'length' bytes.
+ *
+ * Returns the new pointer or NULL on failure.
+ *
+ ***************************************************************************/
+char *Curl_memdup(const char *src, size_t length)
+{
+  char *buffer = malloc(length);
+  if(!buffer)
+    return NULL; /* fail */
+
+  memcpy(buffer, src, length);
+
+  return buffer;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/strdup.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/strdup.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/strdup.h	(revision 164)
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_STRDUP_H
+#define HEADER_CURL_STRDUP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifndef HAVE_STRDUP
+extern char *curlx_strdup(const char *str);
+#endif
+char *Curl_memdup(const char *src, size_t buffer_length);
+
+#endif /* HEADER_CURL_STRDUP_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/strequal.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/strequal.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/strequal.c	(revision 164)
@@ -0,0 +1,79 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include "strequal.h"
+
+/*
+ * @unittest: 1301
+ */
+int curl_strequal(const char *first, const char *second)
+{
+#if defined(HAVE_STRCASECMP)
+  return !(strcasecmp)(first, second);
+#elif defined(HAVE_STRCMPI)
+  return !(strcmpi)(first, second);
+#elif defined(HAVE_STRICMP)
+  return !(stricmp)(first, second);
+#else
+  while(*first && *second) {
+    if(toupper(*first) != toupper(*second)) {
+      break;
+    }
+    first++;
+    second++;
+  }
+  return toupper(*first) == toupper(*second);
+#endif
+}
+
+/*
+ * @unittest: 1301
+ */
+int curl_strnequal(const char *first, const char *second, size_t max)
+{
+#if defined(HAVE_STRNCASECMP)
+  return !strncasecmp(first, second, max);
+#elif defined(HAVE_STRNCMPI)
+  return !strncmpi(first, second, max);
+#elif defined(HAVE_STRNICMP)
+  return !strnicmp(first, second, max);
+#else
+  while(*first && *second && max) {
+    if(toupper(*first) != toupper(*second)) {
+      break;
+    }
+    max--;
+    first++;
+    second++;
+  }
+  if(0 == max)
+    return 1; /* they are equal this far */
+
+  return toupper(*first) == toupper(*second);
+#endif
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/strequal.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/strequal.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/strequal.h	(revision 164)
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_STREQUAL_H
+#define HEADER_CURL_STREQUAL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+#define strequal(a,b) curl_strequal(a,b)
+#define strnequal(a,b,c) curl_strnequal(a,b,c)
+
+#endif /* HEADER_CURL_STREQUAL_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/strerror.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/strerror.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/strerror.c	(revision 164)
@@ -0,0 +1,1143 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2004 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_STRERROR_R
+#  if (!defined(HAVE_POSIX_STRERROR_R) && \
+       !defined(HAVE_GLIBC_STRERROR_R) && \
+       !defined(HAVE_VXWORKS_STRERROR_R)) || \
+      (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \
+      (defined(HAVE_GLIBC_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \
+      (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R))
+#    error "strerror_r MUST be either POSIX, glibc or vxworks-style"
+#  endif
+#endif
+
+#include <curl/curl.h>
+
+#ifdef USE_LIBIDN
+#include <idna.h>
+#endif
+
+#ifdef USE_WINDOWS_SSPI
+#include "curl_sspi.h"
+#endif
+
+#include "strerror.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+const char *
+curl_easy_strerror(CURLcode error)
+{
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  switch (error) {
+  case CURLE_OK:
+    return "No error";
+
+  case CURLE_UNSUPPORTED_PROTOCOL:
+    return "Unsupported protocol";
+
+  case CURLE_FAILED_INIT:
+    return "Failed initialization";
+
+  case CURLE_URL_MALFORMAT:
+    return "URL using bad/illegal format or missing URL";
+
+  case CURLE_NOT_BUILT_IN:
+    return "A requested feature, protocol or option was not found built-in in"
+      " this libcurl due to a build-time decision.";
+
+  case CURLE_COULDNT_RESOLVE_PROXY:
+    return "Couldn't resolve proxy name";
+
+  case CURLE_COULDNT_RESOLVE_HOST:
+    return "Couldn't resolve host name";
+
+  case CURLE_COULDNT_CONNECT:
+    return "Couldn't connect to server";
+
+  case CURLE_FTP_WEIRD_SERVER_REPLY:
+    return "FTP: weird server reply";
+
+  case CURLE_REMOTE_ACCESS_DENIED:
+    return "Access denied to remote resource";
+
+  case CURLE_FTP_ACCEPT_FAILED:
+    return "FTP: The server failed to connect to data port";
+
+  case CURLE_FTP_ACCEPT_TIMEOUT:
+    return "FTP: Accepting server connect has timed out";
+
+  case CURLE_FTP_PRET_FAILED:
+    return "FTP: The server did not accept the PRET command.";
+
+  case CURLE_FTP_WEIRD_PASS_REPLY:
+    return "FTP: unknown PASS reply";
+
+  case CURLE_FTP_WEIRD_PASV_REPLY:
+    return "FTP: unknown PASV reply";
+
+  case CURLE_FTP_WEIRD_227_FORMAT:
+    return "FTP: unknown 227 response format";
+
+  case CURLE_FTP_CANT_GET_HOST:
+    return "FTP: can't figure out the host in the PASV response";
+
+  case CURLE_HTTP2:
+    return "Error in the HTTP2 framing layer";
+
+  case CURLE_FTP_COULDNT_SET_TYPE:
+    return "FTP: couldn't set file type";
+
+  case CURLE_PARTIAL_FILE:
+    return "Transferred a partial file";
+
+  case CURLE_FTP_COULDNT_RETR_FILE:
+    return "FTP: couldn't retrieve (RETR failed) the specified file";
+
+  case CURLE_QUOTE_ERROR:
+    return "Quote command returned error";
+
+  case CURLE_HTTP_RETURNED_ERROR:
+    return "HTTP response code said error";
+
+  case CURLE_WRITE_ERROR:
+    return "Failed writing received data to disk/application";
+
+  case CURLE_UPLOAD_FAILED:
+    return "Upload failed (at start/before it took off)";
+
+  case CURLE_READ_ERROR:
+    return "Failed to open/read local data from file/application";
+
+  case CURLE_OUT_OF_MEMORY:
+    return "Out of memory";
+
+  case CURLE_OPERATION_TIMEDOUT:
+    return "Timeout was reached";
+
+  case CURLE_FTP_PORT_FAILED:
+    return "FTP: command PORT failed";
+
+  case CURLE_FTP_COULDNT_USE_REST:
+    return "FTP: command REST failed";
+
+  case CURLE_RANGE_ERROR:
+    return "Requested range was not delivered by the server";
+
+  case CURLE_HTTP_POST_ERROR:
+    return "Internal problem setting up the POST";
+
+  case CURLE_SSL_CONNECT_ERROR:
+    return "SSL connect error";
+
+  case CURLE_BAD_DOWNLOAD_RESUME:
+    return "Couldn't resume download";
+
+  case CURLE_FILE_COULDNT_READ_FILE:
+    return "Couldn't read a file:// file";
+
+  case CURLE_LDAP_CANNOT_BIND:
+    return "LDAP: cannot bind";
+
+  case CURLE_LDAP_SEARCH_FAILED:
+    return "LDAP: search failed";
+
+  case CURLE_FUNCTION_NOT_FOUND:
+    return "A required function in the library was not found";
+
+  case CURLE_ABORTED_BY_CALLBACK:
+    return "Operation was aborted by an application callback";
+
+  case CURLE_BAD_FUNCTION_ARGUMENT:
+    return "A libcurl function was given a bad argument";
+
+  case CURLE_INTERFACE_FAILED:
+    return "Failed binding local connection end";
+
+  case CURLE_TOO_MANY_REDIRECTS :
+    return "Number of redirects hit maximum amount";
+
+  case CURLE_UNKNOWN_OPTION:
+    return "An unknown option was passed in to libcurl";
+
+  case CURLE_TELNET_OPTION_SYNTAX :
+    return "Malformed telnet option";
+
+  case CURLE_PEER_FAILED_VERIFICATION:
+    return "SSL peer certificate or SSH remote key was not OK";
+
+  case CURLE_GOT_NOTHING:
+    return "Server returned nothing (no headers, no data)";
+
+  case CURLE_SSL_ENGINE_NOTFOUND:
+    return "SSL crypto engine not found";
+
+  case CURLE_SSL_ENGINE_SETFAILED:
+    return "Can not set SSL crypto engine as default";
+
+  case CURLE_SSL_ENGINE_INITFAILED:
+    return "Failed to initialise SSL crypto engine";
+
+  case CURLE_SEND_ERROR:
+    return "Failed sending data to the peer";
+
+  case CURLE_RECV_ERROR:
+    return "Failure when receiving data from the peer";
+
+  case CURLE_SSL_CERTPROBLEM:
+    return "Problem with the local SSL certificate";
+
+  case CURLE_SSL_CIPHER:
+    return "Couldn't use specified SSL cipher";
+
+  case CURLE_SSL_CACERT:
+    return "Peer certificate cannot be authenticated with given CA "
+      "certificates";
+
+  case CURLE_SSL_CACERT_BADFILE:
+    return "Problem with the SSL CA cert (path? access rights?)";
+
+  case CURLE_BAD_CONTENT_ENCODING:
+    return "Unrecognized or bad HTTP Content or Transfer-Encoding";
+
+  case CURLE_LDAP_INVALID_URL:
+    return "Invalid LDAP URL";
+
+  case CURLE_FILESIZE_EXCEEDED:
+    return "Maximum file size exceeded";
+
+  case CURLE_USE_SSL_FAILED:
+    return "Requested SSL level failed";
+
+  case CURLE_SSL_SHUTDOWN_FAILED:
+    return "Failed to shut down the SSL connection";
+
+  case CURLE_SSL_CRL_BADFILE:
+    return "Failed to load CRL file (path? access rights?, format?)";
+
+  case CURLE_SSL_ISSUER_ERROR:
+    return "Issuer check against peer certificate failed";
+
+  case CURLE_SEND_FAIL_REWIND:
+    return "Send failed since rewinding of the data stream failed";
+
+  case CURLE_LOGIN_DENIED:
+    return "Login denied";
+
+  case CURLE_TFTP_NOTFOUND:
+    return "TFTP: File Not Found";
+
+  case CURLE_TFTP_PERM:
+    return "TFTP: Access Violation";
+
+  case CURLE_REMOTE_DISK_FULL:
+    return "Disk full or allocation exceeded";
+
+  case CURLE_TFTP_ILLEGAL:
+    return "TFTP: Illegal operation";
+
+  case CURLE_TFTP_UNKNOWNID:
+    return "TFTP: Unknown transfer ID";
+
+  case CURLE_REMOTE_FILE_EXISTS:
+    return "Remote file already exists";
+
+  case CURLE_TFTP_NOSUCHUSER:
+    return "TFTP: No such user";
+
+  case CURLE_CONV_FAILED:
+    return "Conversion failed";
+
+  case CURLE_CONV_REQD:
+    return "Caller must register CURLOPT_CONV_ callback options";
+
+  case CURLE_REMOTE_FILE_NOT_FOUND:
+    return "Remote file not found";
+
+  case CURLE_SSH:
+    return "Error in the SSH layer";
+
+  case CURLE_AGAIN:
+    return "Socket not ready for send/recv";
+
+  case CURLE_RTSP_CSEQ_ERROR:
+    return "RTSP CSeq mismatch or invalid CSeq";
+
+  case CURLE_RTSP_SESSION_ERROR:
+    return "RTSP session error";
+
+  case CURLE_FTP_BAD_FILE_LIST:
+    return "Unable to parse FTP file list";
+
+  case CURLE_CHUNK_FAILED:
+    return "Chunk callback failed";
+
+  case CURLE_NO_CONNECTION_AVAILABLE:
+    return "The max connection limit is reached";
+
+  case CURLE_SSL_PINNEDPUBKEYNOTMATCH:
+    return "SSL public key does not match pinned public key";
+
+  case CURLE_SSL_INVALIDCERTSTATUS:
+    return "SSL server certificate status verification FAILED";
+
+    /* error codes not used by current libcurl */
+  case CURLE_OBSOLETE20:
+  case CURLE_OBSOLETE24:
+  case CURLE_OBSOLETE29:
+  case CURLE_OBSOLETE32:
+  case CURLE_OBSOLETE40:
+  case CURLE_OBSOLETE44:
+  case CURLE_OBSOLETE46:
+  case CURLE_OBSOLETE50:
+  case CURLE_OBSOLETE57:
+  case CURL_LAST:
+    break;
+  }
+  /*
+   * By using a switch, gcc -Wall will complain about enum values
+   * which do not appear, helping keep this function up-to-date.
+   * By using gcc -Wall -Werror, you can't forget.
+   *
+   * A table would not have the same benefit.  Most compilers will
+   * generate code very similar to a table in any case, so there
+   * is little performance gain from a table.  And something is broken
+   * for the user's application, anyways, so does it matter how fast
+   * it _doesn't_ work?
+   *
+   * The line number for the error will be near this comment, which
+   * is why it is here, and not at the start of the switch.
+   */
+  return "Unknown error";
+#else
+  if(!error)
+    return "No error";
+  else
+    return "Error";
+#endif
+}
+
+const char *
+curl_multi_strerror(CURLMcode error)
+{
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  switch (error) {
+  case CURLM_CALL_MULTI_PERFORM:
+    return "Please call curl_multi_perform() soon";
+
+  case CURLM_OK:
+    return "No error";
+
+  case CURLM_BAD_HANDLE:
+    return "Invalid multi handle";
+
+  case CURLM_BAD_EASY_HANDLE:
+    return "Invalid easy handle";
+
+  case CURLM_OUT_OF_MEMORY:
+    return "Out of memory";
+
+  case CURLM_INTERNAL_ERROR:
+    return "Internal error";
+
+  case CURLM_BAD_SOCKET:
+    return "Invalid socket argument";
+
+  case CURLM_UNKNOWN_OPTION:
+    return "Unknown option";
+
+  case CURLM_ADDED_ALREADY:
+    return "The easy handle is already added to a multi handle";
+
+  case CURLM_LAST:
+    break;
+  }
+
+  return "Unknown error";
+#else
+  if(error == CURLM_OK)
+    return "No error";
+  else
+    return "Error";
+#endif
+}
+
+const char *
+curl_share_strerror(CURLSHcode error)
+{
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  switch (error) {
+  case CURLSHE_OK:
+    return "No error";
+
+  case CURLSHE_BAD_OPTION:
+    return "Unknown share option";
+
+  case CURLSHE_IN_USE:
+    return "Share currently in use";
+
+  case CURLSHE_INVALID:
+    return "Invalid share handle";
+
+  case CURLSHE_NOMEM:
+    return "Out of memory";
+
+  case CURLSHE_NOT_BUILT_IN:
+    return "Feature not enabled in this library";
+
+  case CURLSHE_LAST:
+    break;
+  }
+
+  return "CURLSHcode unknown";
+#else
+  if(error == CURLSHE_OK)
+    return "No error";
+  else
+    return "Error";
+#endif
+}
+
+#ifdef USE_WINSOCK
+
+/* This function handles most / all (?) Winsock errors cURL is able to produce.
+ */
+static const char *
+get_winsock_error (int err, char *buf, size_t len)
+{
+  const char *p;
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  switch (err) {
+  case WSAEINTR:
+    p = "Call interrupted";
+    break;
+  case WSAEBADF:
+    p = "Bad file";
+    break;
+  case WSAEACCES:
+    p = "Bad access";
+    break;
+  case WSAEFAULT:
+    p = "Bad argument";
+    break;
+  case WSAEINVAL:
+    p = "Invalid arguments";
+    break;
+  case WSAEMFILE:
+    p = "Out of file descriptors";
+    break;
+  case WSAEWOULDBLOCK:
+    p = "Call would block";
+    break;
+  case WSAEINPROGRESS:
+  case WSAEALREADY:
+    p = "Blocking call in progress";
+    break;
+  case WSAENOTSOCK:
+    p = "Descriptor is not a socket";
+    break;
+  case WSAEDESTADDRREQ:
+    p = "Need destination address";
+    break;
+  case WSAEMSGSIZE:
+    p = "Bad message size";
+    break;
+  case WSAEPROTOTYPE:
+    p = "Bad protocol";
+    break;
+  case WSAENOPROTOOPT:
+    p = "Protocol option is unsupported";
+    break;
+  case WSAEPROTONOSUPPORT:
+    p = "Protocol is unsupported";
+    break;
+  case WSAESOCKTNOSUPPORT:
+    p = "Socket is unsupported";
+    break;
+  case WSAEOPNOTSUPP:
+    p = "Operation not supported";
+    break;
+  case WSAEAFNOSUPPORT:
+    p = "Address family not supported";
+    break;
+  case WSAEPFNOSUPPORT:
+    p = "Protocol family not supported";
+    break;
+  case WSAEADDRINUSE:
+    p = "Address already in use";
+    break;
+  case WSAEADDRNOTAVAIL:
+    p = "Address not available";
+    break;
+  case WSAENETDOWN:
+    p = "Network down";
+    break;
+  case WSAENETUNREACH:
+    p = "Network unreachable";
+    break;
+  case WSAENETRESET:
+    p = "Network has been reset";
+    break;
+  case WSAECONNABORTED:
+    p = "Connection was aborted";
+    break;
+  case WSAECONNRESET:
+    p = "Connection was reset";
+    break;
+  case WSAENOBUFS:
+    p = "No buffer space";
+    break;
+  case WSAEISCONN:
+    p = "Socket is already connected";
+    break;
+  case WSAENOTCONN:
+    p = "Socket is not connected";
+    break;
+  case WSAESHUTDOWN:
+    p = "Socket has been shut down";
+    break;
+  case WSAETOOMANYREFS:
+    p = "Too many references";
+    break;
+  case WSAETIMEDOUT:
+    p = "Timed out";
+    break;
+  case WSAECONNREFUSED:
+    p = "Connection refused";
+    break;
+  case WSAELOOP:
+    p = "Loop??";
+    break;
+  case WSAENAMETOOLONG:
+    p = "Name too long";
+    break;
+  case WSAEHOSTDOWN:
+    p = "Host down";
+    break;
+  case WSAEHOSTUNREACH:
+    p = "Host unreachable";
+    break;
+  case WSAENOTEMPTY:
+    p = "Not empty";
+    break;
+  case WSAEPROCLIM:
+    p = "Process limit reached";
+    break;
+  case WSAEUSERS:
+    p = "Too many users";
+    break;
+  case WSAEDQUOT:
+    p = "Bad quota";
+    break;
+  case WSAESTALE:
+    p = "Something is stale";
+    break;
+  case WSAEREMOTE:
+    p = "Remote error";
+    break;
+#ifdef WSAEDISCON  /* missing in SalfordC! */
+  case WSAEDISCON:
+    p = "Disconnected";
+    break;
+#endif
+    /* Extended Winsock errors */
+  case WSASYSNOTREADY:
+    p = "Winsock library is not ready";
+    break;
+  case WSANOTINITIALISED:
+    p = "Winsock library not initialised";
+    break;
+  case WSAVERNOTSUPPORTED:
+    p = "Winsock version not supported";
+    break;
+
+    /* getXbyY() errors (already handled in herrmsg):
+     * Authoritative Answer: Host not found */
+  case WSAHOST_NOT_FOUND:
+    p = "Host not found";
+    break;
+
+    /* Non-Authoritative: Host not found, or SERVERFAIL */
+  case WSATRY_AGAIN:
+    p = "Host not found, try again";
+    break;
+
+    /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+  case WSANO_RECOVERY:
+    p = "Unrecoverable error in call to nameserver";
+    break;
+
+    /* Valid name, no data record of requested type */
+  case WSANO_DATA:
+    p = "No data record of requested type";
+    break;
+
+  default:
+    return NULL;
+  }
+#else
+  if(!err)
+    return NULL;
+  else
+    p = "error";
+#endif
+  strncpy (buf, p, len);
+  buf [len-1] = '\0';
+  return buf;
+}
+#endif   /* USE_WINSOCK */
+
+/*
+ * Our thread-safe and smart strerror() replacement.
+ *
+ * The 'err' argument passed in to this function MUST be a true errno number
+ * as reported on this system. We do no range checking on the number before
+ * we pass it to the "number-to-message" conversion function and there might
+ * be systems that don't do proper range checking in there themselves.
+ *
+ * We don't do range checking (on systems other than Windows) since there is
+ * no good reliable and portable way to do it.
+ */
+const char *Curl_strerror(struct connectdata *conn, int err)
+{
+  char *buf, *p;
+  size_t max;
+  int old_errno = ERRNO;
+
+  DEBUGASSERT(conn);
+  DEBUGASSERT(err >= 0);
+
+  buf = conn->syserr_buf;
+  max = sizeof(conn->syserr_buf)-1;
+  *buf = '\0';
+
+#ifdef USE_WINSOCK
+
+#ifdef _WIN32_WCE
+  {
+    wchar_t wbuf[256];
+    wbuf[0] = L'\0';
+
+    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
+                  LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL);
+    wcstombs(buf, wbuf, max);
+  }
+#else
+  /* 'sys_nerr' is the maximum errno number, it is not widely portable */
+  if(err >= 0 && err < sys_nerr)
+    strncpy(buf, strerror(err), max);
+  else {
+    if(!get_winsock_error(err, buf, max) &&
+       !FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
+                       LANG_NEUTRAL, buf, (DWORD)max, NULL))
+      snprintf(buf, max, "Unknown error %d (%#x)", err, err);
+  }
+#endif
+
+#else /* not USE_WINSOCK coming up */
+
+#if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R)
+ /*
+  * The POSIX-style strerror_r() may set errno to ERANGE if insufficient
+  * storage is supplied via 'strerrbuf' and 'buflen' to hold the generated
+  * message string, or EINVAL if 'errnum' is not a valid error number.
+  */
+  if(0 != strerror_r(err, buf, max)) {
+    if('\0' == buf[0])
+      snprintf(buf, max, "Unknown error %d", err);
+  }
+#elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R)
+ /*
+  * The glibc-style strerror_r() only *might* use the buffer we pass to
+  * the function, but it always returns the error message as a pointer,
+  * so we must copy that string unconditionally (if non-NULL).
+  */
+  {
+    char buffer[256];
+    char *msg = strerror_r(err, buffer, sizeof(buffer));
+    if(msg)
+      strncpy(buf, msg, max);
+    else
+      snprintf(buf, max, "Unknown error %d", err);
+  }
+#elif defined(HAVE_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)
+ /*
+  * The vxworks-style strerror_r() does use the buffer we pass to the function.
+  * The buffer size should be at least NAME_MAX (256)
+  */
+  {
+    char buffer[256];
+    if(OK == strerror_r(err, buffer))
+      strncpy(buf, buffer, max);
+    else
+      snprintf(buf, max, "Unknown error %d", err);
+  }
+#else
+  {
+    char *msg = strerror(err);
+    if(msg)
+      strncpy(buf, msg, max);
+    else
+      snprintf(buf, max, "Unknown error %d", err);
+  }
+#endif
+
+#endif /* end of ! USE_WINSOCK */
+
+  buf[max] = '\0'; /* make sure the string is zero terminated */
+
+  /* strip trailing '\r\n' or '\n'. */
+  if((p = strrchr(buf, '\n')) != NULL && (p - buf) >= 2)
+     *p = '\0';
+  if((p = strrchr(buf, '\r')) != NULL && (p - buf) >= 1)
+     *p = '\0';
+
+  if(old_errno != ERRNO)
+    SET_ERRNO(old_errno);
+
+  return buf;
+}
+
+#ifdef USE_LIBIDN
+/*
+ * Return error-string for libidn status as returned from idna_to_ascii_lz().
+ */
+const char *Curl_idn_strerror (struct connectdata *conn, int err)
+{
+#ifdef HAVE_IDNA_STRERROR
+  (void)conn;
+  return idna_strerror((Idna_rc) err);
+#else
+  const char *str;
+  char *buf;
+  size_t max;
+
+  DEBUGASSERT(conn);
+
+  buf = conn->syserr_buf;
+  max = sizeof(conn->syserr_buf)-1;
+  *buf = '\0';
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  switch ((Idna_rc)err) {
+    case IDNA_SUCCESS:
+      str = "No error";
+      break;
+    case IDNA_STRINGPREP_ERROR:
+      str = "Error in string preparation";
+      break;
+    case IDNA_PUNYCODE_ERROR:
+      str = "Error in Punycode operation";
+      break;
+    case IDNA_CONTAINS_NON_LDH:
+      str = "Illegal ASCII characters";
+      break;
+    case IDNA_CONTAINS_MINUS:
+      str = "Contains minus";
+      break;
+    case IDNA_INVALID_LENGTH:
+      str = "Invalid output length";
+      break;
+    case IDNA_NO_ACE_PREFIX:
+      str = "No ACE prefix (\"xn--\")";
+      break;
+    case IDNA_ROUNDTRIP_VERIFY_ERROR:
+      str = "Round trip verify error";
+      break;
+    case IDNA_CONTAINS_ACE_PREFIX:
+      str = "Already have ACE prefix (\"xn--\")";
+      break;
+    case IDNA_ICONV_ERROR:
+      str = "Locale conversion failed";
+      break;
+    case IDNA_MALLOC_ERROR:
+      str = "Allocation failed";
+      break;
+    case IDNA_DLOPEN_ERROR:
+      str = "dlopen() error";
+      break;
+    default:
+      snprintf(buf, max, "error %d", err);
+      str = NULL;
+      break;
+  }
+#else
+  if((Idna_rc)err == IDNA_SUCCESS)
+    str = "No error";
+  else
+    str = "Error";
+#endif
+  if(str)
+    strncpy(buf, str, max);
+  buf[max] = '\0';
+  return (buf);
+#endif
+}
+#endif  /* USE_LIBIDN */
+
+#ifdef USE_WINDOWS_SSPI
+const char *Curl_sspi_strerror (struct connectdata *conn, int err)
+{
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  char txtbuf[80];
+  char msgbuf[sizeof(conn->syserr_buf)];
+  char *p, *str, *msg = NULL;
+  bool msg_formatted = FALSE;
+  int old_errno;
+#endif
+  const char *txt;
+  char *outbuf;
+  size_t outmax;
+
+  DEBUGASSERT(conn);
+
+  outbuf = conn->syserr_buf;
+  outmax = sizeof(conn->syserr_buf)-1;
+  *outbuf = '\0';
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+
+  old_errno = ERRNO;
+
+  switch (err) {
+    case SEC_E_OK:
+      txt = "No error";
+      break;
+    case CRYPT_E_REVOKED:
+      txt = "CRYPT_E_REVOKED";
+      break;
+    case SEC_E_ALGORITHM_MISMATCH:
+      txt = "SEC_E_ALGORITHM_MISMATCH";
+      break;
+    case SEC_E_BAD_BINDINGS:
+      txt = "SEC_E_BAD_BINDINGS";
+      break;
+    case SEC_E_BAD_PKGID:
+      txt = "SEC_E_BAD_PKGID";
+      break;
+    case SEC_E_BUFFER_TOO_SMALL:
+      txt = "SEC_E_BUFFER_TOO_SMALL";
+      break;
+    case SEC_E_CANNOT_INSTALL:
+      txt = "SEC_E_CANNOT_INSTALL";
+      break;
+    case SEC_E_CANNOT_PACK:
+      txt = "SEC_E_CANNOT_PACK";
+      break;
+    case SEC_E_CERT_EXPIRED:
+      txt = "SEC_E_CERT_EXPIRED";
+      break;
+    case SEC_E_CERT_UNKNOWN:
+      txt = "SEC_E_CERT_UNKNOWN";
+      break;
+    case SEC_E_CERT_WRONG_USAGE:
+      txt = "SEC_E_CERT_WRONG_USAGE";
+      break;
+    case SEC_E_CONTEXT_EXPIRED:
+      txt = "SEC_E_CONTEXT_EXPIRED";
+      break;
+    case SEC_E_CROSSREALM_DELEGATION_FAILURE:
+      txt = "SEC_E_CROSSREALM_DELEGATION_FAILURE";
+      break;
+    case SEC_E_CRYPTO_SYSTEM_INVALID:
+      txt = "SEC_E_CRYPTO_SYSTEM_INVALID";
+      break;
+    case SEC_E_DECRYPT_FAILURE:
+      txt = "SEC_E_DECRYPT_FAILURE";
+      break;
+    case SEC_E_DELEGATION_POLICY:
+      txt = "SEC_E_DELEGATION_POLICY";
+      break;
+    case SEC_E_DELEGATION_REQUIRED:
+      txt = "SEC_E_DELEGATION_REQUIRED";
+      break;
+    case SEC_E_DOWNGRADE_DETECTED:
+      txt = "SEC_E_DOWNGRADE_DETECTED";
+      break;
+    case SEC_E_ENCRYPT_FAILURE:
+      txt = "SEC_E_ENCRYPT_FAILURE";
+      break;
+    case SEC_E_ILLEGAL_MESSAGE:
+      txt = "SEC_E_ILLEGAL_MESSAGE";
+      break;
+    case SEC_E_INCOMPLETE_CREDENTIALS:
+      txt = "SEC_E_INCOMPLETE_CREDENTIALS";
+      break;
+    case SEC_E_INCOMPLETE_MESSAGE:
+      txt = "SEC_E_INCOMPLETE_MESSAGE";
+      break;
+    case SEC_E_INSUFFICIENT_MEMORY:
+      txt = "SEC_E_INSUFFICIENT_MEMORY";
+      break;
+    case SEC_E_INTERNAL_ERROR:
+      txt = "SEC_E_INTERNAL_ERROR";
+      break;
+    case SEC_E_INVALID_HANDLE:
+      txt = "SEC_E_INVALID_HANDLE";
+      break;
+    case SEC_E_INVALID_PARAMETER:
+      txt = "SEC_E_INVALID_PARAMETER";
+      break;
+    case SEC_E_INVALID_TOKEN:
+      txt = "SEC_E_INVALID_TOKEN";
+      break;
+    case SEC_E_ISSUING_CA_UNTRUSTED:
+      txt = "SEC_E_ISSUING_CA_UNTRUSTED";
+      break;
+    case SEC_E_ISSUING_CA_UNTRUSTED_KDC:
+      txt = "SEC_E_ISSUING_CA_UNTRUSTED_KDC";
+      break;
+    case SEC_E_KDC_CERT_EXPIRED:
+      txt = "SEC_E_KDC_CERT_EXPIRED";
+      break;
+    case SEC_E_KDC_CERT_REVOKED:
+      txt = "SEC_E_KDC_CERT_REVOKED";
+      break;
+    case SEC_E_KDC_INVALID_REQUEST:
+      txt = "SEC_E_KDC_INVALID_REQUEST";
+      break;
+    case SEC_E_KDC_UNABLE_TO_REFER:
+      txt = "SEC_E_KDC_UNABLE_TO_REFER";
+      break;
+    case SEC_E_KDC_UNKNOWN_ETYPE:
+      txt = "SEC_E_KDC_UNKNOWN_ETYPE";
+      break;
+    case SEC_E_LOGON_DENIED:
+      txt = "SEC_E_LOGON_DENIED";
+      break;
+    case SEC_E_MAX_REFERRALS_EXCEEDED:
+      txt = "SEC_E_MAX_REFERRALS_EXCEEDED";
+      break;
+    case SEC_E_MESSAGE_ALTERED:
+      txt = "SEC_E_MESSAGE_ALTERED";
+      break;
+    case SEC_E_MULTIPLE_ACCOUNTS:
+      txt = "SEC_E_MULTIPLE_ACCOUNTS";
+      break;
+    case SEC_E_MUST_BE_KDC:
+      txt = "SEC_E_MUST_BE_KDC";
+      break;
+    case SEC_E_NOT_OWNER:
+      txt = "SEC_E_NOT_OWNER";
+      break;
+    case SEC_E_NO_AUTHENTICATING_AUTHORITY:
+      txt = "SEC_E_NO_AUTHENTICATING_AUTHORITY";
+      break;
+    case SEC_E_NO_CREDENTIALS:
+      txt = "SEC_E_NO_CREDENTIALS";
+      break;
+    case SEC_E_NO_IMPERSONATION:
+      txt = "SEC_E_NO_IMPERSONATION";
+      break;
+    case SEC_E_NO_IP_ADDRESSES:
+      txt = "SEC_E_NO_IP_ADDRESSES";
+      break;
+    case SEC_E_NO_KERB_KEY:
+      txt = "SEC_E_NO_KERB_KEY";
+      break;
+    case SEC_E_NO_PA_DATA:
+      txt = "SEC_E_NO_PA_DATA";
+      break;
+    case SEC_E_NO_S4U_PROT_SUPPORT:
+      txt = "SEC_E_NO_S4U_PROT_SUPPORT";
+      break;
+    case SEC_E_NO_TGT_REPLY:
+      txt = "SEC_E_NO_TGT_REPLY";
+      break;
+    case SEC_E_OUT_OF_SEQUENCE:
+      txt = "SEC_E_OUT_OF_SEQUENCE";
+      break;
+    case SEC_E_PKINIT_CLIENT_FAILURE:
+      txt = "SEC_E_PKINIT_CLIENT_FAILURE";
+      break;
+    case SEC_E_PKINIT_NAME_MISMATCH:
+      txt = "SEC_E_PKINIT_NAME_MISMATCH";
+      break;
+    case SEC_E_POLICY_NLTM_ONLY:
+      txt = "SEC_E_POLICY_NLTM_ONLY";
+      break;
+    case SEC_E_QOP_NOT_SUPPORTED:
+      txt = "SEC_E_QOP_NOT_SUPPORTED";
+      break;
+    case SEC_E_REVOCATION_OFFLINE_C:
+      txt = "SEC_E_REVOCATION_OFFLINE_C";
+      break;
+    case SEC_E_REVOCATION_OFFLINE_KDC:
+      txt = "SEC_E_REVOCATION_OFFLINE_KDC";
+      break;
+    case SEC_E_SECPKG_NOT_FOUND:
+      txt = "SEC_E_SECPKG_NOT_FOUND";
+      break;
+    case SEC_E_SECURITY_QOS_FAILED:
+      txt = "SEC_E_SECURITY_QOS_FAILED";
+      break;
+    case SEC_E_SHUTDOWN_IN_PROGRESS:
+      txt = "SEC_E_SHUTDOWN_IN_PROGRESS";
+      break;
+    case SEC_E_SMARTCARD_CERT_EXPIRED:
+      txt = "SEC_E_SMARTCARD_CERT_EXPIRED";
+      break;
+    case SEC_E_SMARTCARD_CERT_REVOKED:
+      txt = "SEC_E_SMARTCARD_CERT_REVOKED";
+      break;
+    case SEC_E_SMARTCARD_LOGON_REQUIRED:
+      txt = "SEC_E_SMARTCARD_LOGON_REQUIRED";
+      break;
+    case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED:
+      txt = "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED";
+      break;
+    case SEC_E_TARGET_UNKNOWN:
+      txt = "SEC_E_TARGET_UNKNOWN";
+      break;
+    case SEC_E_TIME_SKEW:
+      txt = "SEC_E_TIME_SKEW";
+      break;
+    case SEC_E_TOO_MANY_PRINCIPALS:
+      txt = "SEC_E_TOO_MANY_PRINCIPALS";
+      break;
+    case SEC_E_UNFINISHED_CONTEXT_DELETED:
+      txt = "SEC_E_UNFINISHED_CONTEXT_DELETED";
+      break;
+    case SEC_E_UNKNOWN_CREDENTIALS:
+      txt = "SEC_E_UNKNOWN_CREDENTIALS";
+      break;
+    case SEC_E_UNSUPPORTED_FUNCTION:
+      txt = "SEC_E_UNSUPPORTED_FUNCTION";
+      break;
+    case SEC_E_UNSUPPORTED_PREAUTH:
+      txt = "SEC_E_UNSUPPORTED_PREAUTH";
+      break;
+    case SEC_E_UNTRUSTED_ROOT:
+      txt = "SEC_E_UNTRUSTED_ROOT";
+      break;
+    case SEC_E_WRONG_CREDENTIAL_HANDLE:
+      txt = "SEC_E_WRONG_CREDENTIAL_HANDLE";
+      break;
+    case SEC_E_WRONG_PRINCIPAL:
+      txt = "SEC_E_WRONG_PRINCIPAL";
+      break;
+    case SEC_I_COMPLETE_AND_CONTINUE:
+      txt = "SEC_I_COMPLETE_AND_CONTINUE";
+      break;
+    case SEC_I_COMPLETE_NEEDED:
+      txt = "SEC_I_COMPLETE_NEEDED";
+      break;
+    case SEC_I_CONTEXT_EXPIRED:
+      txt = "SEC_I_CONTEXT_EXPIRED";
+      break;
+    case SEC_I_CONTINUE_NEEDED:
+      txt = "SEC_I_CONTINUE_NEEDED";
+      break;
+    case SEC_I_INCOMPLETE_CREDENTIALS:
+      txt = "SEC_I_INCOMPLETE_CREDENTIALS";
+      break;
+    case SEC_I_LOCAL_LOGON:
+      txt = "SEC_I_LOCAL_LOGON";
+      break;
+    case SEC_I_NO_LSA_CONTEXT:
+      txt = "SEC_I_NO_LSA_CONTEXT";
+      break;
+    case SEC_I_RENEGOTIATE:
+      txt = "SEC_I_RENEGOTIATE";
+      break;
+    case SEC_I_SIGNATURE_NEEDED:
+      txt = "SEC_I_SIGNATURE_NEEDED";
+      break;
+    default:
+      txt = "Unknown error";
+  }
+
+  if(err == SEC_E_OK)
+    strncpy(outbuf, txt, outmax);
+  else if(err == SEC_E_ILLEGAL_MESSAGE)
+    snprintf(outbuf, outmax,
+             "SEC_E_ILLEGAL_MESSAGE (0x%04X%04X) - This error usually occurs "
+             "when a fatal SSL/TLS alert is received (e.g. handshake failed). "
+             "More detail may be available in the Windows System event log.",
+             (err >> 16) & 0xffff, err & 0xffff);
+  else {
+    str = txtbuf;
+    snprintf(txtbuf, sizeof(txtbuf), "%s (0x%04X%04X)",
+             txt, (err >> 16) & 0xffff, err & 0xffff);
+    txtbuf[sizeof(txtbuf)-1] = '\0';
+
+#ifdef _WIN32_WCE
+    {
+      wchar_t wbuf[256];
+      wbuf[0] = L'\0';
+
+      if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+                       FORMAT_MESSAGE_IGNORE_INSERTS,
+                       NULL, err, LANG_NEUTRAL,
+                       wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
+        wcstombs(msgbuf, wbuf, sizeof(msgbuf)-1);
+        msg_formatted = TRUE;
+      }
+    }
+#else
+    if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
+                      FORMAT_MESSAGE_IGNORE_INSERTS,
+                      NULL, err, LANG_NEUTRAL,
+                      msgbuf, sizeof(msgbuf)-1, NULL)) {
+      msg_formatted = TRUE;
+    }
+#endif
+    if(msg_formatted) {
+      msgbuf[sizeof(msgbuf)-1] = '\0';
+      /* strip trailing '\r\n' or '\n' */
+      if((p = strrchr(msgbuf, '\n')) != NULL && (p - msgbuf) >= 2)
+         *p = '\0';
+      if((p = strrchr(msgbuf, '\r')) != NULL && (p - msgbuf) >= 1)
+         *p = '\0';
+      msg = msgbuf;
+    }
+    if(msg)
+      snprintf(outbuf, outmax, "%s - %s", str, msg);
+    else
+      strncpy(outbuf, str, outmax);
+  }
+
+  if(old_errno != ERRNO)
+    SET_ERRNO(old_errno);
+
+#else
+
+  if(err == SEC_E_OK)
+    txt = "No error";
+  else
+    txt = "Error";
+
+  strncpy(outbuf, txt, outmax);
+
+#endif
+
+  outbuf[outmax] = '\0';
+
+  return outbuf;
+}
+#endif /* USE_WINDOWS_SSPI */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/strerror.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/strerror.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/strerror.h	(revision 164)
@@ -0,0 +1,37 @@
+#ifndef HEADER_CURL_STRERROR_H
+#define HEADER_CURL_STRERROR_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "urldata.h"
+
+const char *Curl_strerror (struct connectdata *conn, int err);
+
+#ifdef USE_LIBIDN
+const char *Curl_idn_strerror (struct connectdata *conn, int err);
+#endif
+
+#ifdef USE_WINDOWS_SSPI
+const char *Curl_sspi_strerror (struct connectdata *conn, int err);
+#endif
+
+#endif /* HEADER_CURL_STRERROR_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/strtok.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/strtok.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/strtok.c	(revision 164)
@@ -0,0 +1,66 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef HAVE_STRTOK_R
+#include <stddef.h>
+
+#include "strtok.h"
+
+char *
+Curl_strtok_r(char *ptr, const char *sep, char **end)
+{
+  if(!ptr)
+    /* we got NULL input so then we get our last position instead */
+    ptr = *end;
+
+  /* pass all letters that are including in the separator string */
+  while(*ptr && strchr(sep, *ptr))
+    ++ptr;
+
+  if(*ptr) {
+    /* so this is where the next piece of string starts */
+    char *start = ptr;
+
+    /* set the end pointer to the first byte after the start */
+    *end = start + 1;
+
+    /* scan through the string to find where it ends, it ends on a
+       null byte or a character that exists in the separator string */
+    while(**end && !strchr(sep, **end))
+      ++*end;
+
+    if(**end) {
+      /* the end is not a null byte */
+      **end = '\0';  /* zero terminate it! */
+      ++*end;        /* advance the last pointer to beyond the null byte */
+    }
+
+    return start; /* return the position where the string starts */
+  }
+
+  /* we ended up on a null byte, there are no more strings to find! */
+  return NULL;
+}
+
+#endif /* this was only compiled if strtok_r wasn't present */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/strtok.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/strtok.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/strtok.h	(revision 164)
@@ -0,0 +1,34 @@
+#ifndef HEADER_CURL_STRTOK_H
+#define HEADER_CURL_STRTOK_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+#include <stddef.h>
+
+#ifndef HAVE_STRTOK_R
+char *Curl_strtok_r(char *s, const char *delim, char **last);
+#define strtok_r Curl_strtok_r
+#else
+#include <string.h>
+#endif
+
+#endif /* HEADER_CURL_STRTOK_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/strtoofft.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/strtoofft.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/strtoofft.c	(revision 164)
@@ -0,0 +1,188 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "strtoofft.h"
+
+/*
+ * NOTE:
+ *
+ * In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we
+ * could use in case strtoll() doesn't exist...  See
+ * http://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
+ */
+
+#ifdef NEED_CURL_STRTOLL
+
+/* Range tests can be used for alphanum decoding if characters are consecutive,
+   like in ASCII. Else an array is scanned. Determine this condition now. */
+
+#if('9' - '0') != 9 || ('Z' - 'A') != 25 || ('z' - 'a') != 25
+
+#define NO_RANGE_TEST
+
+static const char valchars[] =
+            "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+#endif
+
+static int get_char(char c, int base);
+
+/**
+ * Emulated version of the strtoll function.  This extracts a long long
+ * value from the given input string and returns it.
+ */
+curl_off_t
+curlx_strtoll(const char *nptr, char **endptr, int base)
+{
+  char *end;
+  int is_negative = 0;
+  int overflow;
+  int i;
+  curl_off_t value = 0;
+  curl_off_t newval;
+
+  /* Skip leading whitespace. */
+  end = (char *)nptr;
+  while(ISSPACE(end[0])) {
+    end++;
+  }
+
+  /* Handle the sign, if any. */
+  if(end[0] == '-') {
+    is_negative = 1;
+    end++;
+  }
+  else if(end[0] == '+') {
+    end++;
+  }
+  else if(end[0] == '\0') {
+    /* We had nothing but perhaps some whitespace -- there was no number. */
+    if(endptr) {
+      *endptr = end;
+    }
+    return 0;
+  }
+
+  /* Handle special beginnings, if present and allowed. */
+  if(end[0] == '0' && end[1] == 'x') {
+    if(base == 16 || base == 0) {
+      end += 2;
+      base = 16;
+    }
+  }
+  else if(end[0] == '0') {
+    if(base == 8 || base == 0) {
+      end++;
+      base = 8;
+    }
+  }
+
+  /* Matching strtol, if the base is 0 and it doesn't look like
+   * the number is octal or hex, we assume it's base 10.
+   */
+  if(base == 0) {
+    base = 10;
+  }
+
+  /* Loop handling digits. */
+  value = 0;
+  overflow = 0;
+  for(i = get_char(end[0], base);
+      i != -1;
+      end++, i = get_char(end[0], base)) {
+    newval = base * value + i;
+    if(newval < value) {
+      /* We've overflowed. */
+      overflow = 1;
+      break;
+    }
+    else
+      value = newval;
+  }
+
+  if(!overflow) {
+    if(is_negative) {
+      /* Fix the sign. */
+      value *= -1;
+    }
+  }
+  else {
+    if(is_negative)
+      value = CURL_OFF_T_MIN;
+    else
+      value = CURL_OFF_T_MAX;
+
+    SET_ERRNO(ERANGE);
+  }
+
+  if(endptr)
+    *endptr = end;
+
+  return value;
+}
+
+/**
+ * Returns the value of c in the given base, or -1 if c cannot
+ * be interpreted properly in that base (i.e., is out of range,
+ * is a null, etc.).
+ *
+ * @param c     the character to interpret according to base
+ * @param base  the base in which to interpret c
+ *
+ * @return  the value of c in base, or -1 if c isn't in range
+ */
+static int get_char(char c, int base)
+{
+#ifndef NO_RANGE_TEST
+  int value = -1;
+  if(c <= '9' && c >= '0') {
+    value = c - '0';
+  }
+  else if(c <= 'Z' && c >= 'A') {
+    value = c - 'A' + 10;
+  }
+  else if(c <= 'z' && c >= 'a') {
+    value = c - 'a' + 10;
+  }
+#else
+  const char * cp;
+  int value;
+
+  cp = memchr(valchars, c, 10 + 26 + 26);
+
+  if(!cp)
+    return -1;
+
+  value = cp - valchars;
+
+  if(value >= 10 + 26)
+    value -= 26;                /* Lowercase. */
+#endif
+
+  if(value >= base) {
+    value = -1;
+  }
+
+  return value;
+}
+#endif  /* Only present if we need strtoll, but don't have it. */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/strtoofft.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/strtoofft.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/strtoofft.h	(revision 164)
@@ -0,0 +1,75 @@
+#ifndef HEADER_CURL_STRTOOFFT_H
+#define HEADER_CURL_STRTOOFFT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/*
+ * Determine which string to integral data type conversion function we use
+ * to implement string conversion to our curl_off_t integral data type.
+ *
+ * Notice that curl_off_t might be 64 or 32 bit wide, and that it might use
+ * an underlying data type which might be 'long', 'int64_t', 'long long' or
+ * '__int64' and more remotely other data types.
+ *
+ * On systems where the size of curl_off_t is greater than the size of 'long'
+ * the conversion function to use is strtoll() if it is available, otherwise,
+ * we emulate its functionality with our own clone.
+ *
+ * On systems where the size of curl_off_t is smaller or equal than the size
+ * of 'long' the conversion function to use is strtol().
+ */
+
+#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
+#  ifdef HAVE_STRTOLL
+#    define curlx_strtoofft strtoll
+#  else
+#    if defined(_MSC_VER) && (_MSC_VER >= 1300) && (_INTEGRAL_MAX_BITS >= 64)
+#      if defined(_SAL_VERSION)
+         _Check_return_ _CRTIMP __int64 __cdecl _strtoi64(
+             _In_z_ const char *_String,
+             _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix);
+#      else
+         _CRTIMP __int64 __cdecl _strtoi64(const char *_String,
+                                           char **_EndPtr, int _Radix);
+#      endif
+#      define curlx_strtoofft _strtoi64
+#    else
+       curl_off_t curlx_strtoll(const char *nptr, char **endptr, int base);
+#      define curlx_strtoofft curlx_strtoll
+#      define NEED_CURL_STRTOLL 1
+#    endif
+#  endif
+#else
+#  define curlx_strtoofft strtol
+#endif
+
+#if (CURL_SIZEOF_CURL_OFF_T == 4)
+#  define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFF)
+#else
+   /* assume CURL_SIZEOF_CURL_OFF_T == 8 */
+#  define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF)
+#endif
+#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - CURL_OFF_T_C(1))
+
+#endif /* HEADER_CURL_STRTOOFFT_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/telnet.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/telnet.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/telnet.c	(revision 164)
@@ -0,0 +1,1676 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_TELNET
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "telnet.h"
+#include "connect.h"
+#include "progress.h"
+#include "curl_printf.h"
+
+#define  TELOPTS
+#define  TELCMDS
+
+#include "arpa_telnet.h"
+#include "select.h"
+#include "strequal.h"
+#include "rawstr.h"
+#include "warnless.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define SUBBUFSIZE 512
+
+#define CURL_SB_CLEAR(x)  x->subpointer = x->subbuffer
+#define CURL_SB_TERM(x)                                 \
+  do {                                                  \
+    x->subend = x->subpointer;                          \
+    CURL_SB_CLEAR(x);                                   \
+  } WHILE_FALSE
+#define CURL_SB_ACCUM(x,c)                                   \
+  do {                                                       \
+    if(x->subpointer < (x->subbuffer+sizeof x->subbuffer))   \
+      *x->subpointer++ = (c);                                \
+  } WHILE_FALSE
+
+#define  CURL_SB_GET(x) ((*x->subpointer++)&0xff)
+#define  CURL_SB_PEEK(x)   ((*x->subpointer)&0xff)
+#define  CURL_SB_EOF(x) (x->subpointer >= x->subend)
+#define  CURL_SB_LEN(x) (x->subend - x->subpointer)
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+#define printoption(a,b,c,d)  Curl_nop_stmt
+#endif
+
+#ifdef USE_WINSOCK
+typedef FARPROC WSOCK2_FUNC;
+static CURLcode check_wsock2 ( struct SessionHandle *data );
+#endif
+
+static
+CURLcode telrcv(struct connectdata *,
+                const unsigned char *inbuf, /* Data received from socket */
+                ssize_t count);             /* Number of bytes received */
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static void printoption(struct SessionHandle *data,
+                        const char *direction,
+                        int cmd, int option);
+#endif
+
+static void negotiate(struct connectdata *);
+static void send_negotiation(struct connectdata *, int cmd, int option);
+static void set_local_option(struct connectdata *, int cmd, int option);
+static void set_remote_option(struct connectdata *, int cmd, int option);
+
+static void printsub(struct SessionHandle *data,
+                     int direction, unsigned char *pointer,
+                     size_t length);
+static void suboption(struct connectdata *);
+static void sendsuboption(struct connectdata *conn, int option);
+
+static CURLcode telnet_do(struct connectdata *conn, bool *done);
+static CURLcode telnet_done(struct connectdata *conn,
+                                 CURLcode, bool premature);
+static CURLcode send_telnet_data(struct connectdata *conn,
+                                 char *buffer, ssize_t nread);
+
+/* For negotiation compliant to RFC 1143 */
+#define CURL_NO          0
+#define CURL_YES         1
+#define CURL_WANTYES     2
+#define CURL_WANTNO      3
+
+#define CURL_EMPTY       0
+#define CURL_OPPOSITE    1
+
+/*
+ * Telnet receiver states for fsm
+ */
+typedef enum
+{
+   CURL_TS_DATA = 0,
+   CURL_TS_IAC,
+   CURL_TS_WILL,
+   CURL_TS_WONT,
+   CURL_TS_DO,
+   CURL_TS_DONT,
+   CURL_TS_CR,
+   CURL_TS_SB,   /* sub-option collection */
+   CURL_TS_SE   /* looking for sub-option end */
+} TelnetReceive;
+
+struct TELNET {
+  int please_negotiate;
+  int already_negotiated;
+  int us[256];
+  int usq[256];
+  int us_preferred[256];
+  int him[256];
+  int himq[256];
+  int him_preferred[256];
+  int subnegotiation[256];
+  char subopt_ttype[32];             /* Set with suboption TTYPE */
+  char subopt_xdisploc[128];         /* Set with suboption XDISPLOC */
+  unsigned short subopt_wsx;         /* Set with suboption NAWS */
+  unsigned short subopt_wsy;         /* Set with suboption NAWS */
+  struct curl_slist *telnet_vars;    /* Environment variables */
+
+  /* suboptions */
+  unsigned char subbuffer[SUBBUFSIZE];
+  unsigned char *subpointer, *subend;      /* buffer for sub-options */
+
+  TelnetReceive telrcv_state;
+};
+
+
+/*
+ * TELNET protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_telnet = {
+  "TELNET",                             /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  telnet_do,                            /* do_it */
+  telnet_done,                          /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_TELNET,                          /* defport */
+  CURLPROTO_TELNET,                     /* protocol */
+  PROTOPT_NONE | PROTOPT_NOURLQUERY     /* flags */
+};
+
+
+#ifdef USE_WINSOCK
+static CURLcode
+check_wsock2 ( struct SessionHandle *data )
+{
+  int err;
+  WORD wVersionRequested;
+  WSADATA wsaData;
+
+  DEBUGASSERT(data);
+
+  /* telnet requires at least WinSock 2.0 so ask for it. */
+  wVersionRequested = MAKEWORD(2, 0);
+
+  err = WSAStartup(wVersionRequested, &wsaData);
+
+  /* We must've called this once already, so this call */
+  /* should always succeed.  But, just in case... */
+  if(err != 0) {
+    failf(data,"WSAStartup failed (%d)",err);
+    return CURLE_FAILED_INIT;
+  }
+
+  /* We have to have a WSACleanup call for every successful */
+  /* WSAStartup call. */
+  WSACleanup();
+
+  /* Check that our version is supported */
+  if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
+      HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) {
+      /* Our version isn't supported */
+    failf(data, "insufficient winsock version to support "
+          "telnet");
+    return CURLE_FAILED_INIT;
+  }
+
+  /* Our version is supported */
+  return CURLE_OK;
+}
+#endif
+
+static
+CURLcode init_telnet(struct connectdata *conn)
+{
+  struct TELNET *tn;
+
+  tn = calloc(1, sizeof(struct TELNET));
+  if(!tn)
+    return CURLE_OUT_OF_MEMORY;
+
+  conn->data->req.protop = tn; /* make us known */
+
+  tn->telrcv_state = CURL_TS_DATA;
+
+  /* Init suboptions */
+  CURL_SB_CLEAR(tn);
+
+  /* Set the options we want by default */
+  tn->us_preferred[CURL_TELOPT_SGA] = CURL_YES;
+  tn->him_preferred[CURL_TELOPT_SGA] = CURL_YES;
+
+  /* To be compliant with previous releases of libcurl
+     we enable this option by default. This behaviour
+         can be changed thanks to the "BINARY" option in
+         CURLOPT_TELNETOPTIONS
+  */
+  tn->us_preferred[CURL_TELOPT_BINARY] = CURL_YES;
+  tn->him_preferred[CURL_TELOPT_BINARY] = CURL_YES;
+
+  /* We must allow the server to echo what we sent
+         but it is not necessary to request the server
+         to do so (it might forces the server to close
+         the connection). Hence, we ignore ECHO in the
+         negotiate function
+  */
+  tn->him_preferred[CURL_TELOPT_ECHO] = CURL_YES;
+
+  /* Set the subnegotiation fields to send information
+    just after negotiation passed (do/will)
+
+     Default values are (0,0) initialized by calloc.
+     According to the RFC1013 it is valid:
+     A value equal to zero is acceptable for the width (or height),
+         and means that no character width (or height) is being sent.
+         In this case, the width (or height) that will be assumed by the
+         Telnet server is operating system specific (it will probably be
+         based upon the terminal type information that may have been sent
+         using the TERMINAL TYPE Telnet option). */
+  tn->subnegotiation[CURL_TELOPT_NAWS] = CURL_YES;
+  return CURLE_OK;
+}
+
+static void negotiate(struct connectdata *conn)
+{
+  int i;
+  struct TELNET *tn = (struct TELNET *) conn->data->req.protop;
+
+  for(i = 0;i < CURL_NTELOPTS;i++) {
+    if(i==CURL_TELOPT_ECHO)
+      continue;
+
+    if(tn->us_preferred[i] == CURL_YES)
+      set_local_option(conn, i, CURL_YES);
+
+    if(tn->him_preferred[i] == CURL_YES)
+      set_remote_option(conn, i, CURL_YES);
+  }
+}
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static void printoption(struct SessionHandle *data,
+                        const char *direction, int cmd, int option)
+{
+  const char *fmt;
+  const char *opt;
+
+  if(data->set.verbose) {
+    if(cmd == CURL_IAC) {
+      if(CURL_TELCMD_OK(option))
+        infof(data, "%s IAC %s\n", direction, CURL_TELCMD(option));
+      else
+        infof(data, "%s IAC %d\n", direction, option);
+    }
+    else {
+      fmt = (cmd == CURL_WILL) ? "WILL" : (cmd == CURL_WONT) ? "WONT" :
+        (cmd == CURL_DO) ? "DO" : (cmd == CURL_DONT) ? "DONT" : 0;
+      if(fmt) {
+        if(CURL_TELOPT_OK(option))
+          opt = CURL_TELOPT(option);
+        else if(option == CURL_TELOPT_EXOPL)
+          opt = "EXOPL";
+        else
+          opt = NULL;
+
+        if(opt)
+          infof(data, "%s %s %s\n", direction, fmt, opt);
+        else
+          infof(data, "%s %s %d\n", direction, fmt, option);
+      }
+      else
+        infof(data, "%s %d %d\n", direction, cmd, option);
+    }
+  }
+}
+#endif
+
+static void send_negotiation(struct connectdata *conn, int cmd, int option)
+{
+   unsigned char buf[3];
+   ssize_t bytes_written;
+   int err;
+   struct SessionHandle *data = conn->data;
+
+   buf[0] = CURL_IAC;
+   buf[1] = (unsigned char)cmd;
+   buf[2] = (unsigned char)option;
+
+   bytes_written = swrite(conn->sock[FIRSTSOCKET], buf, 3);
+   if(bytes_written < 0) {
+     err = SOCKERRNO;
+     failf(data,"Sending data failed (%d)",err);
+   }
+
+   printoption(conn->data, "SENT", cmd, option);
+}
+
+static
+void set_remote_option(struct connectdata *conn, int option, int newstate)
+{
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  if(newstate == CURL_YES) {
+    switch(tn->him[option]) {
+    case CURL_NO:
+      tn->him[option] = CURL_WANTYES;
+      send_negotiation(conn, CURL_DO, option);
+      break;
+
+    case CURL_YES:
+      /* Already enabled */
+      break;
+
+    case CURL_WANTNO:
+      switch(tn->himq[option]) {
+      case CURL_EMPTY:
+        /* Already negotiating for CURL_YES, queue the request */
+        tn->himq[option] = CURL_OPPOSITE;
+        break;
+      case CURL_OPPOSITE:
+        /* Error: already queued an enable request */
+        break;
+      }
+      break;
+
+    case CURL_WANTYES:
+      switch(tn->himq[option]) {
+      case CURL_EMPTY:
+        /* Error: already negotiating for enable */
+        break;
+      case CURL_OPPOSITE:
+        tn->himq[option] = CURL_EMPTY;
+        break;
+      }
+      break;
+    }
+  }
+  else { /* NO */
+    switch(tn->him[option]) {
+    case CURL_NO:
+      /* Already disabled */
+      break;
+
+    case CURL_YES:
+      tn->him[option] = CURL_WANTNO;
+      send_negotiation(conn, CURL_DONT, option);
+      break;
+
+    case CURL_WANTNO:
+      switch(tn->himq[option]) {
+      case CURL_EMPTY:
+        /* Already negotiating for NO */
+        break;
+      case CURL_OPPOSITE:
+        tn->himq[option] = CURL_EMPTY;
+        break;
+      }
+      break;
+
+    case CURL_WANTYES:
+      switch(tn->himq[option]) {
+      case CURL_EMPTY:
+        tn->himq[option] = CURL_OPPOSITE;
+        break;
+      case CURL_OPPOSITE:
+        break;
+      }
+      break;
+    }
+  }
+}
+
+static
+void rec_will(struct connectdata *conn, int option)
+{
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  switch(tn->him[option]) {
+  case CURL_NO:
+    if(tn->him_preferred[option] == CURL_YES) {
+      tn->him[option] = CURL_YES;
+      send_negotiation(conn, CURL_DO, option);
+    }
+    else
+      send_negotiation(conn, CURL_DONT, option);
+
+    break;
+
+  case CURL_YES:
+    /* Already enabled */
+    break;
+
+  case CURL_WANTNO:
+    switch(tn->himq[option]) {
+    case CURL_EMPTY:
+      /* Error: DONT answered by WILL */
+      tn->him[option] = CURL_NO;
+      break;
+    case CURL_OPPOSITE:
+      /* Error: DONT answered by WILL */
+      tn->him[option] = CURL_YES;
+      tn->himq[option] = CURL_EMPTY;
+      break;
+    }
+    break;
+
+  case CURL_WANTYES:
+    switch(tn->himq[option]) {
+    case CURL_EMPTY:
+      tn->him[option] = CURL_YES;
+      break;
+    case CURL_OPPOSITE:
+      tn->him[option] = CURL_WANTNO;
+      tn->himq[option] = CURL_EMPTY;
+      send_negotiation(conn, CURL_DONT, option);
+      break;
+    }
+    break;
+  }
+}
+
+static
+void rec_wont(struct connectdata *conn, int option)
+{
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  switch(tn->him[option]) {
+  case CURL_NO:
+    /* Already disabled */
+    break;
+
+  case CURL_YES:
+    tn->him[option] = CURL_NO;
+    send_negotiation(conn, CURL_DONT, option);
+    break;
+
+  case CURL_WANTNO:
+    switch(tn->himq[option]) {
+    case CURL_EMPTY:
+      tn->him[option] = CURL_NO;
+      break;
+
+    case CURL_OPPOSITE:
+      tn->him[option] = CURL_WANTYES;
+      tn->himq[option] = CURL_EMPTY;
+      send_negotiation(conn, CURL_DO, option);
+      break;
+    }
+    break;
+
+  case CURL_WANTYES:
+    switch(tn->himq[option]) {
+    case CURL_EMPTY:
+      tn->him[option] = CURL_NO;
+      break;
+    case CURL_OPPOSITE:
+      tn->him[option] = CURL_NO;
+      tn->himq[option] = CURL_EMPTY;
+      break;
+    }
+    break;
+  }
+}
+
+static void
+set_local_option(struct connectdata *conn, int option, int newstate)
+{
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  if(newstate == CURL_YES) {
+    switch(tn->us[option]) {
+    case CURL_NO:
+      tn->us[option] = CURL_WANTYES;
+      send_negotiation(conn, CURL_WILL, option);
+      break;
+
+    case CURL_YES:
+      /* Already enabled */
+      break;
+
+    case CURL_WANTNO:
+      switch(tn->usq[option]) {
+      case CURL_EMPTY:
+        /* Already negotiating for CURL_YES, queue the request */
+        tn->usq[option] = CURL_OPPOSITE;
+        break;
+      case CURL_OPPOSITE:
+        /* Error: already queued an enable request */
+        break;
+      }
+      break;
+
+    case CURL_WANTYES:
+      switch(tn->usq[option]) {
+      case CURL_EMPTY:
+        /* Error: already negotiating for enable */
+        break;
+      case CURL_OPPOSITE:
+        tn->usq[option] = CURL_EMPTY;
+        break;
+      }
+      break;
+    }
+  }
+  else { /* NO */
+    switch(tn->us[option]) {
+    case CURL_NO:
+      /* Already disabled */
+      break;
+
+    case CURL_YES:
+      tn->us[option] = CURL_WANTNO;
+      send_negotiation(conn, CURL_WONT, option);
+      break;
+
+    case CURL_WANTNO:
+      switch(tn->usq[option]) {
+      case CURL_EMPTY:
+        /* Already negotiating for NO */
+        break;
+      case CURL_OPPOSITE:
+        tn->usq[option] = CURL_EMPTY;
+        break;
+      }
+      break;
+
+    case CURL_WANTYES:
+      switch(tn->usq[option]) {
+      case CURL_EMPTY:
+        tn->usq[option] = CURL_OPPOSITE;
+        break;
+      case CURL_OPPOSITE:
+        break;
+      }
+      break;
+    }
+  }
+}
+
+static
+void rec_do(struct connectdata *conn, int option)
+{
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  switch(tn->us[option]) {
+  case CURL_NO:
+    if(tn->us_preferred[option] == CURL_YES) {
+      tn->us[option] = CURL_YES;
+      send_negotiation(conn, CURL_WILL, option);
+      if(tn->subnegotiation[option] == CURL_YES)
+        /* transmission of data option */
+        sendsuboption(conn, option);
+    }
+    else if(tn->subnegotiation[option] == CURL_YES) {
+      /* send information to achieve this option*/
+      tn->us[option] = CURL_YES;
+      send_negotiation(conn, CURL_WILL, option);
+      sendsuboption(conn, option);
+    }
+    else
+      send_negotiation(conn, CURL_WONT, option);
+    break;
+
+  case CURL_YES:
+    /* Already enabled */
+    break;
+
+  case CURL_WANTNO:
+    switch(tn->usq[option]) {
+    case CURL_EMPTY:
+      /* Error: DONT answered by WILL */
+      tn->us[option] = CURL_NO;
+      break;
+    case CURL_OPPOSITE:
+      /* Error: DONT answered by WILL */
+      tn->us[option] = CURL_YES;
+      tn->usq[option] = CURL_EMPTY;
+      break;
+    }
+    break;
+
+  case CURL_WANTYES:
+    switch(tn->usq[option]) {
+    case CURL_EMPTY:
+      tn->us[option] = CURL_YES;
+      if(tn->subnegotiation[option] == CURL_YES) {
+        /* transmission of data option */
+        sendsuboption(conn, option);
+      }
+      break;
+    case CURL_OPPOSITE:
+      tn->us[option] = CURL_WANTNO;
+      tn->himq[option] = CURL_EMPTY;
+      send_negotiation(conn, CURL_WONT, option);
+      break;
+    }
+    break;
+  }
+}
+
+static
+void rec_dont(struct connectdata *conn, int option)
+{
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  switch(tn->us[option]) {
+  case CURL_NO:
+    /* Already disabled */
+    break;
+
+  case CURL_YES:
+    tn->us[option] = CURL_NO;
+    send_negotiation(conn, CURL_WONT, option);
+    break;
+
+  case CURL_WANTNO:
+    switch(tn->usq[option]) {
+    case CURL_EMPTY:
+      tn->us[option] = CURL_NO;
+      break;
+
+    case CURL_OPPOSITE:
+      tn->us[option] = CURL_WANTYES;
+      tn->usq[option] = CURL_EMPTY;
+      send_negotiation(conn, CURL_WILL, option);
+      break;
+    }
+    break;
+
+  case CURL_WANTYES:
+    switch(tn->usq[option]) {
+    case CURL_EMPTY:
+      tn->us[option] = CURL_NO;
+      break;
+    case CURL_OPPOSITE:
+      tn->us[option] = CURL_NO;
+      tn->usq[option] = CURL_EMPTY;
+      break;
+    }
+    break;
+  }
+}
+
+
+static void printsub(struct SessionHandle *data,
+                     int direction,             /* '<' or '>' */
+                     unsigned char *pointer,    /* where suboption data is */
+                     size_t length)             /* length of suboption data */
+{
+  unsigned int i = 0;
+
+  if(data->set.verbose) {
+    if(direction) {
+      infof(data, "%s IAC SB ", (direction == '<')? "RCVD":"SENT");
+      if(length >= 3) {
+        int j;
+
+        i = pointer[length-2];
+        j = pointer[length-1];
+
+        if(i != CURL_IAC || j != CURL_SE) {
+          infof(data, "(terminated by ");
+          if(CURL_TELOPT_OK(i))
+            infof(data, "%s ", CURL_TELOPT(i));
+          else if(CURL_TELCMD_OK(i))
+            infof(data, "%s ", CURL_TELCMD(i));
+          else
+            infof(data, "%u ", i);
+          if(CURL_TELOPT_OK(j))
+            infof(data, "%s", CURL_TELOPT(j));
+          else if(CURL_TELCMD_OK(j))
+            infof(data, "%s", CURL_TELCMD(j));
+          else
+            infof(data, "%d", j);
+          infof(data, ", not IAC SE!) ");
+        }
+      }
+      length -= 2;
+    }
+    if(length < 1) {
+      infof(data, "(Empty suboption?)");
+      return;
+    }
+
+    if(CURL_TELOPT_OK(pointer[0])) {
+      switch(pointer[0]) {
+      case CURL_TELOPT_TTYPE:
+      case CURL_TELOPT_XDISPLOC:
+      case CURL_TELOPT_NEW_ENVIRON:
+      case CURL_TELOPT_NAWS:
+        infof(data, "%s", CURL_TELOPT(pointer[0]));
+        break;
+      default:
+        infof(data, "%s (unsupported)", CURL_TELOPT(pointer[0]));
+        break;
+      }
+    }
+    else
+      infof(data, "%d (unknown)", pointer[i]);
+
+    switch(pointer[0]) {
+    case CURL_TELOPT_NAWS:
+      if(length > 4)
+        infof(data, "Width: %hu ; Height: %hu", (pointer[1]<<8) | pointer[2],
+              (pointer[3]<<8) | pointer[4]);
+      break;
+    default:
+      switch(pointer[1]) {
+      case CURL_TELQUAL_IS:
+        infof(data, " IS");
+        break;
+      case CURL_TELQUAL_SEND:
+        infof(data, " SEND");
+        break;
+      case CURL_TELQUAL_INFO:
+        infof(data, " INFO/REPLY");
+        break;
+      case CURL_TELQUAL_NAME:
+        infof(data, " NAME");
+        break;
+      }
+
+      switch(pointer[0]) {
+      case CURL_TELOPT_TTYPE:
+      case CURL_TELOPT_XDISPLOC:
+        pointer[length] = 0;
+        infof(data, " \"%s\"", &pointer[2]);
+        break;
+      case CURL_TELOPT_NEW_ENVIRON:
+        if(pointer[1] == CURL_TELQUAL_IS) {
+          infof(data, " ");
+          for(i = 3;i < length;i++) {
+            switch(pointer[i]) {
+            case CURL_NEW_ENV_VAR:
+              infof(data, ", ");
+              break;
+            case CURL_NEW_ENV_VALUE:
+              infof(data, " = ");
+              break;
+            default:
+              infof(data, "%c", pointer[i]);
+              break;
+            }
+          }
+        }
+        break;
+      default:
+        for(i = 2; i < length; i++)
+          infof(data, " %.2x", pointer[i]);
+        break;
+      }
+    }
+    if(direction)
+      infof(data, "\n");
+  }
+}
+
+static CURLcode check_telnet_options(struct connectdata *conn)
+{
+  struct curl_slist *head;
+  struct curl_slist *beg;
+  char option_keyword[128] = "";
+  char option_arg[256] = "";
+  struct SessionHandle *data = conn->data;
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  CURLcode result = CURLE_OK;
+  int binary_option;
+
+  /* Add the user name as an environment variable if it
+     was given on the command line */
+  if(conn->bits.user_passwd) {
+    snprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user);
+    beg = curl_slist_append(tn->telnet_vars, option_arg);
+    if(!beg) {
+      curl_slist_free_all(tn->telnet_vars);
+      tn->telnet_vars = NULL;
+      return CURLE_OUT_OF_MEMORY;
+    }
+    tn->telnet_vars = beg;
+    tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
+  }
+
+  for(head = data->set.telnet_options; head; head=head->next) {
+    if(sscanf(head->data, "%127[^= ]%*[ =]%255s",
+              option_keyword, option_arg) == 2) {
+
+      /* Terminal type */
+      if(Curl_raw_equal(option_keyword, "TTYPE")) {
+        strncpy(tn->subopt_ttype, option_arg, 31);
+        tn->subopt_ttype[31] = 0; /* String termination */
+        tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES;
+        continue;
+      }
+
+      /* Display variable */
+      if(Curl_raw_equal(option_keyword, "XDISPLOC")) {
+        strncpy(tn->subopt_xdisploc, option_arg, 127);
+        tn->subopt_xdisploc[127] = 0; /* String termination */
+        tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES;
+        continue;
+      }
+
+      /* Environment variable */
+      if(Curl_raw_equal(option_keyword, "NEW_ENV")) {
+        beg = curl_slist_append(tn->telnet_vars, option_arg);
+        if(!beg) {
+          result = CURLE_OUT_OF_MEMORY;
+          break;
+        }
+        tn->telnet_vars = beg;
+        tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
+        continue;
+      }
+
+          /* Window Size */
+      if(Curl_raw_equal(option_keyword, "WS")) {
+        if(sscanf(option_arg, "%hu%*[xX]%hu",
+                  &tn->subopt_wsx, &tn->subopt_wsy) == 2)
+          tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES;
+        else {
+          failf(data, "Syntax error in telnet option: %s", head->data);
+          result = CURLE_TELNET_OPTION_SYNTAX;
+          break;
+        }
+        continue;
+      }
+
+      /* To take care or not of the 8th bit in data exchange */
+      if(Curl_raw_equal(option_keyword, "BINARY")) {
+        binary_option=atoi(option_arg);
+        if(binary_option!=1) {
+          tn->us_preferred[CURL_TELOPT_BINARY] = CURL_NO;
+          tn->him_preferred[CURL_TELOPT_BINARY] = CURL_NO;
+        }
+        continue;
+      }
+
+      failf(data, "Unknown telnet option %s", head->data);
+      result = CURLE_UNKNOWN_TELNET_OPTION;
+      break;
+    }
+    else {
+      failf(data, "Syntax error in telnet option: %s", head->data);
+      result = CURLE_TELNET_OPTION_SYNTAX;
+      break;
+    }
+  }
+
+  if(result) {
+    curl_slist_free_all(tn->telnet_vars);
+    tn->telnet_vars = NULL;
+  }
+
+  return result;
+}
+
+/*
+ * suboption()
+ *
+ * Look at the sub-option buffer, and try to be helpful to the other
+ * side.
+ */
+
+static void suboption(struct connectdata *conn)
+{
+  struct curl_slist *v;
+  unsigned char temp[2048];
+  ssize_t bytes_written;
+  size_t len;
+  size_t tmplen;
+  int err;
+  char varname[128] = "";
+  char varval[128] = "";
+  struct SessionHandle *data = conn->data;
+  struct TELNET *tn = (struct TELNET *)data->req.protop;
+
+  printsub(data, '<', (unsigned char *)tn->subbuffer, CURL_SB_LEN(tn)+2);
+  switch (CURL_SB_GET(tn)) {
+    case CURL_TELOPT_TTYPE:
+      len = strlen(tn->subopt_ttype) + 4 + 2;
+      snprintf((char *)temp, sizeof(temp),
+               "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_TTYPE,
+               CURL_TELQUAL_IS, tn->subopt_ttype, CURL_IAC, CURL_SE);
+      bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
+      if(bytes_written < 0) {
+        err = SOCKERRNO;
+        failf(data,"Sending data failed (%d)",err);
+      }
+      printsub(data, '>', &temp[2], len-2);
+      break;
+    case CURL_TELOPT_XDISPLOC:
+      len = strlen(tn->subopt_xdisploc) + 4 + 2;
+      snprintf((char *)temp, sizeof(temp),
+               "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_XDISPLOC,
+               CURL_TELQUAL_IS, tn->subopt_xdisploc, CURL_IAC, CURL_SE);
+      bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
+      if(bytes_written < 0) {
+        err = SOCKERRNO;
+        failf(data,"Sending data failed (%d)",err);
+      }
+      printsub(data, '>', &temp[2], len-2);
+      break;
+    case CURL_TELOPT_NEW_ENVIRON:
+      snprintf((char *)temp, sizeof(temp),
+               "%c%c%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_NEW_ENVIRON,
+               CURL_TELQUAL_IS);
+      len = 4;
+
+      for(v = tn->telnet_vars;v;v = v->next) {
+        tmplen = (strlen(v->data) + 1);
+        /* Add the variable only if it fits */
+        if(len + tmplen < (int)sizeof(temp)-6) {
+          if(sscanf(v->data, "%127[^,],%127s", varname, varval)) {
+            snprintf((char *)&temp[len], sizeof(temp) - len,
+                     "%c%s%c%s", CURL_NEW_ENV_VAR, varname,
+                     CURL_NEW_ENV_VALUE, varval);
+            len += tmplen;
+          }
+        }
+      }
+      snprintf((char *)&temp[len], sizeof(temp) - len,
+               "%c%c", CURL_IAC, CURL_SE);
+      len += 2;
+      bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
+      if(bytes_written < 0) {
+        err = SOCKERRNO;
+        failf(data,"Sending data failed (%d)",err);
+      }
+      printsub(data, '>', &temp[2], len-2);
+      break;
+  }
+  return;
+}
+
+
+/*
+ * sendsuboption()
+ *
+ * Send suboption information to the server side.
+ */
+
+static void sendsuboption(struct connectdata *conn, int option)
+{
+  ssize_t bytes_written;
+  int err;
+  unsigned short x, y;
+  unsigned char*uc1, *uc2;
+
+  struct SessionHandle *data = conn->data;
+  struct TELNET *tn = (struct TELNET *)data->req.protop;
+
+  switch (option) {
+  case CURL_TELOPT_NAWS:
+    /* We prepare data to be sent */
+    CURL_SB_CLEAR(tn);
+    CURL_SB_ACCUM(tn, CURL_IAC);
+    CURL_SB_ACCUM(tn, CURL_SB);
+    CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS);
+    /* We must deal either with litte or big endien processors */
+    /* Window size must be sent according to the 'network order' */
+    x=htons(tn->subopt_wsx);
+    y=htons(tn->subopt_wsy);
+    uc1 = (unsigned char*)&x;
+    uc2 = (unsigned char*)&y;
+    CURL_SB_ACCUM(tn, uc1[0]);
+    CURL_SB_ACCUM(tn, uc1[1]);
+    CURL_SB_ACCUM(tn, uc2[0]);
+    CURL_SB_ACCUM(tn, uc2[1]);
+
+    CURL_SB_ACCUM(tn, CURL_IAC);
+    CURL_SB_ACCUM(tn, CURL_SE);
+    CURL_SB_TERM(tn);
+    /* data suboption is now ready */
+
+    printsub(data, '>', (unsigned char *)tn->subbuffer+2,
+             CURL_SB_LEN(tn)-2);
+
+    /* we send the header of the suboption... */
+    bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer, 3);
+    if(bytes_written < 0) {
+      err = SOCKERRNO;
+      failf(data, "Sending data failed (%d)", err);
+    }
+    /* ... then the window size with the send_telnet_data() function
+       to deal with 0xFF cases ... */
+    send_telnet_data(conn, (char *)tn->subbuffer+3, 4);
+    /* ... and the footer */
+    bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer+7, 2);
+    if(bytes_written < 0) {
+      err = SOCKERRNO;
+      failf(data, "Sending data failed (%d)", err);
+    }
+    break;
+  }
+}
+
+
+static
+CURLcode telrcv(struct connectdata *conn,
+                const unsigned char *inbuf, /* Data received from socket */
+                ssize_t count)              /* Number of bytes received */
+{
+  unsigned char c;
+  CURLcode result;
+  int in = 0;
+  int startwrite=-1;
+  struct SessionHandle *data = conn->data;
+  struct TELNET *tn = (struct TELNET *)data->req.protop;
+
+#define startskipping()                                       \
+  if(startwrite >= 0) {                                       \
+    result = Curl_client_write(conn,                          \
+                               CLIENTWRITE_BODY,              \
+                               (char *)&inbuf[startwrite],    \
+                               in-startwrite);                \
+    if(result)                                                \
+      return result;                                          \
+  }                                                           \
+  startwrite = -1
+
+#define writebyte() \
+    if(startwrite < 0) \
+      startwrite = in
+
+#define bufferflush() startskipping()
+
+  while(count--) {
+    c = inbuf[in];
+
+    switch (tn->telrcv_state) {
+    case CURL_TS_CR:
+      tn->telrcv_state = CURL_TS_DATA;
+      if(c == '\0') {
+        startskipping();
+        break;   /* Ignore \0 after CR */
+      }
+      writebyte();
+      break;
+
+    case CURL_TS_DATA:
+      if(c == CURL_IAC) {
+        tn->telrcv_state = CURL_TS_IAC;
+        startskipping();
+        break;
+      }
+      else if(c == '\r')
+        tn->telrcv_state = CURL_TS_CR;
+      writebyte();
+      break;
+
+    case CURL_TS_IAC:
+    process_iac:
+      DEBUGASSERT(startwrite < 0);
+      switch (c) {
+      case CURL_WILL:
+        tn->telrcv_state = CURL_TS_WILL;
+        break;
+      case CURL_WONT:
+        tn->telrcv_state = CURL_TS_WONT;
+        break;
+      case CURL_DO:
+        tn->telrcv_state = CURL_TS_DO;
+        break;
+      case CURL_DONT:
+        tn->telrcv_state = CURL_TS_DONT;
+        break;
+      case CURL_SB:
+        CURL_SB_CLEAR(tn);
+        tn->telrcv_state = CURL_TS_SB;
+        break;
+      case CURL_IAC:
+        tn->telrcv_state = CURL_TS_DATA;
+        writebyte();
+        break;
+      case CURL_DM:
+      case CURL_NOP:
+      case CURL_GA:
+      default:
+        tn->telrcv_state = CURL_TS_DATA;
+        printoption(data, "RCVD", CURL_IAC, c);
+        break;
+      }
+      break;
+
+      case CURL_TS_WILL:
+        printoption(data, "RCVD", CURL_WILL, c);
+        tn->please_negotiate = 1;
+        rec_will(conn, c);
+        tn->telrcv_state = CURL_TS_DATA;
+        break;
+
+      case CURL_TS_WONT:
+        printoption(data, "RCVD", CURL_WONT, c);
+        tn->please_negotiate = 1;
+        rec_wont(conn, c);
+        tn->telrcv_state = CURL_TS_DATA;
+        break;
+
+      case CURL_TS_DO:
+        printoption(data, "RCVD", CURL_DO, c);
+        tn->please_negotiate = 1;
+        rec_do(conn, c);
+        tn->telrcv_state = CURL_TS_DATA;
+        break;
+
+      case CURL_TS_DONT:
+        printoption(data, "RCVD", CURL_DONT, c);
+        tn->please_negotiate = 1;
+        rec_dont(conn, c);
+        tn->telrcv_state = CURL_TS_DATA;
+        break;
+
+      case CURL_TS_SB:
+        if(c == CURL_IAC)
+          tn->telrcv_state = CURL_TS_SE;
+        else
+          CURL_SB_ACCUM(tn, c);
+        break;
+
+      case CURL_TS_SE:
+        if(c != CURL_SE) {
+          if(c != CURL_IAC) {
+            /*
+             * This is an error.  We only expect to get "IAC IAC" or "IAC SE".
+             * Several things may have happened.  An IAC was not doubled, the
+             * IAC SE was left off, or another option got inserted into the
+             * suboption are all possibilities.  If we assume that the IAC was
+             * not doubled, and really the IAC SE was left off, we could get
+             * into an infinate loop here.  So, instead, we terminate the
+             * suboption, and process the partial suboption if we can.
+             */
+            CURL_SB_ACCUM(tn, CURL_IAC);
+            CURL_SB_ACCUM(tn, c);
+            tn->subpointer -= 2;
+            CURL_SB_TERM(tn);
+
+            printoption(data, "In SUBOPTION processing, RCVD", CURL_IAC, c);
+            suboption(conn);   /* handle sub-option */
+            tn->telrcv_state = CURL_TS_IAC;
+            goto process_iac;
+          }
+          CURL_SB_ACCUM(tn, c);
+          tn->telrcv_state = CURL_TS_SB;
+        }
+        else
+        {
+          CURL_SB_ACCUM(tn, CURL_IAC);
+          CURL_SB_ACCUM(tn, CURL_SE);
+          tn->subpointer -= 2;
+          CURL_SB_TERM(tn);
+          suboption(conn);   /* handle sub-option */
+          tn->telrcv_state = CURL_TS_DATA;
+        }
+        break;
+    }
+    ++in;
+  }
+  bufferflush();
+  return CURLE_OK;
+}
+
+/* Escape and send a telnet data block */
+/* TODO: write large chunks of data instead of one byte at a time */
+static CURLcode send_telnet_data(struct connectdata *conn,
+                                 char *buffer, ssize_t nread)
+{
+  unsigned char outbuf[2];
+  ssize_t bytes_written, total_written;
+  int out_count;
+  CURLcode result = CURLE_OK;
+
+  while(!result && nread--) {
+    outbuf[0] = *buffer++;
+    out_count = 1;
+    if(outbuf[0] == CURL_IAC)
+      outbuf[out_count++] = CURL_IAC;
+
+    total_written = 0;
+    do {
+      /* Make sure socket is writable to avoid EWOULDBLOCK condition */
+      struct pollfd pfd[1];
+      pfd[0].fd = conn->sock[FIRSTSOCKET];
+      pfd[0].events = POLLOUT;
+      switch (Curl_poll(pfd, 1, -1)) {
+        case -1:                    /* error, abort writing */
+        case 0:                     /* timeout (will never happen) */
+          result = CURLE_SEND_ERROR;
+          break;
+        default:                    /* write! */
+          bytes_written = 0;
+          result = Curl_write(conn, conn->sock[FIRSTSOCKET],
+                              outbuf+total_written, out_count-total_written,
+                              &bytes_written);
+          total_written += bytes_written;
+          break;
+      }
+      /* handle partial write */
+    } while(!result && total_written < out_count);
+  }
+  return result;
+}
+
+static CURLcode telnet_done(struct connectdata *conn,
+                                 CURLcode status, bool premature)
+{
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  (void)status; /* unused */
+  (void)premature; /* not used */
+
+  if(!tn)
+    return CURLE_OK;
+
+  curl_slist_free_all(tn->telnet_vars);
+  tn->telnet_vars = NULL;
+
+  Curl_safefree(conn->data->req.protop);
+
+  return CURLE_OK;
+}
+
+static CURLcode telnet_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result;
+  struct SessionHandle *data = conn->data;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+#ifdef USE_WINSOCK
+  HMODULE wsock2;
+  WSOCK2_FUNC close_event_func;
+  WSOCK2_FUNC create_event_func;
+  WSOCK2_FUNC event_select_func;
+  WSOCK2_FUNC enum_netevents_func;
+  WSAEVENT event_handle;
+  WSANETWORKEVENTS events;
+  HANDLE stdin_handle;
+  HANDLE objs[2];
+  DWORD  obj_count;
+  DWORD  wait_timeout;
+  DWORD waitret;
+  DWORD readfile_read;
+  int err;
+#else
+  int interval_ms;
+  struct pollfd pfd[2];
+  int poll_cnt;
+  curl_off_t total_dl = 0;
+  curl_off_t total_ul = 0;
+#endif
+  ssize_t nread;
+  struct timeval now;
+  bool keepon = TRUE;
+  char *buf = data->state.buffer;
+  struct TELNET *tn;
+
+  *done = TRUE; /* unconditionally */
+
+  result = init_telnet(conn);
+  if(result)
+    return result;
+
+  tn = (struct TELNET *)data->req.protop;
+
+  result = check_telnet_options(conn);
+  if(result)
+    return result;
+
+#ifdef USE_WINSOCK
+  /*
+  ** This functionality only works with WinSock >= 2.0.  So,
+  ** make sure have it.
+  */
+  result = check_wsock2(data);
+  if(result)
+    return result;
+
+  /* OK, so we have WinSock 2.0.  We need to dynamically */
+  /* load ws2_32.dll and get the function pointers we need. */
+  wsock2 = LoadLibrary(TEXT("WS2_32.DLL"));
+  if(wsock2 == NULL) {
+    failf(data, "failed to load WS2_32.DLL (%d)", ERRNO);
+    return CURLE_FAILED_INIT;
+  }
+
+  /* Grab a pointer to WSACreateEvent */
+  create_event_func = GetProcAddress(wsock2, "WSACreateEvent");
+  if(create_event_func == NULL) {
+    failf(data, "failed to find WSACreateEvent function (%d)", ERRNO);
+    FreeLibrary(wsock2);
+    return CURLE_FAILED_INIT;
+  }
+
+  /* And WSACloseEvent */
+  close_event_func = GetProcAddress(wsock2, "WSACloseEvent");
+  if(close_event_func == NULL) {
+    failf(data, "failed to find WSACloseEvent function (%d)", ERRNO);
+    FreeLibrary(wsock2);
+    return CURLE_FAILED_INIT;
+  }
+
+  /* And WSAEventSelect */
+  event_select_func = GetProcAddress(wsock2, "WSAEventSelect");
+  if(event_select_func == NULL) {
+    failf(data, "failed to find WSAEventSelect function (%d)", ERRNO);
+    FreeLibrary(wsock2);
+    return CURLE_FAILED_INIT;
+  }
+
+  /* And WSAEnumNetworkEvents */
+  enum_netevents_func = GetProcAddress(wsock2, "WSAEnumNetworkEvents");
+  if(enum_netevents_func == NULL) {
+    failf(data, "failed to find WSAEnumNetworkEvents function (%d)", ERRNO);
+    FreeLibrary(wsock2);
+    return CURLE_FAILED_INIT;
+  }
+
+  /* We want to wait for both stdin and the socket. Since
+  ** the select() function in winsock only works on sockets
+  ** we have to use the WaitForMultipleObjects() call.
+  */
+
+  /* First, create a sockets event object */
+  event_handle = (WSAEVENT)create_event_func();
+  if(event_handle == WSA_INVALID_EVENT) {
+    failf(data, "WSACreateEvent failed (%d)", SOCKERRNO);
+    FreeLibrary(wsock2);
+    return CURLE_FAILED_INIT;
+  }
+
+  /* Tell winsock what events we want to listen to */
+  if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) ==
+     SOCKET_ERROR) {
+    close_event_func(event_handle);
+    FreeLibrary(wsock2);
+    return CURLE_OK;
+  }
+
+  /* The get the Windows file handle for stdin */
+  stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
+
+  /* Create the list of objects to wait for */
+  objs[0] = event_handle;
+  objs[1] = stdin_handle;
+
+  /* If stdin_handle is a pipe, use PeekNamedPipe() method to check it,
+     else use the old WaitForMultipleObjects() way */
+  if(GetFileType(stdin_handle) == FILE_TYPE_PIPE ||
+     data->set.is_fread_set) {
+    /* Don't wait for stdin_handle, just wait for event_handle */
+    obj_count = 1;
+    /* Check stdin_handle per 100 milliseconds */
+    wait_timeout = 100;
+  }
+  else {
+    obj_count = 2;
+    wait_timeout = 1000;
+  }
+
+  /* Keep on listening and act on events */
+  while(keepon) {
+    waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
+    switch(waitret) {
+    case WAIT_TIMEOUT:
+    {
+      for(;;) {
+        if(data->set.is_fread_set) {
+          /* read from user-supplied method */
+          result = (int)data->state.fread_func(buf, 1, BUFSIZE - 1,
+                                               data->state.in);
+          if(result == CURL_READFUNC_ABORT) {
+            keepon = FALSE;
+            result = CURLE_READ_ERROR;
+            break;
+          }
+
+          if(result == CURL_READFUNC_PAUSE)
+            break;
+
+          if(result == 0)                        /* no bytes */
+            break;
+
+          readfile_read = result; /* fall thru with number of bytes read */
+        }
+        else {
+          /* read from stdin */
+          if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL,
+                            &readfile_read, NULL)) {
+            keepon = FALSE;
+            result = CURLE_READ_ERROR;
+            break;
+          }
+
+          if(!readfile_read)
+            break;
+
+          if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
+                       &readfile_read, NULL)) {
+            keepon = FALSE;
+            result = CURLE_READ_ERROR;
+            break;
+          }
+        }
+
+        result = send_telnet_data(conn, buf, readfile_read);
+        if(result) {
+          keepon = FALSE;
+          break;
+        }
+      }
+    }
+    break;
+
+    case WAIT_OBJECT_0 + 1:
+    {
+      if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
+                   &readfile_read, NULL)) {
+        keepon = FALSE;
+        result = CURLE_READ_ERROR;
+        break;
+      }
+
+      result = send_telnet_data(conn, buf, readfile_read);
+      if(result) {
+        keepon = FALSE;
+        break;
+      }
+    }
+    break;
+
+    case WAIT_OBJECT_0:
+
+      events.lNetworkEvents = 0;
+      if(SOCKET_ERROR == enum_netevents_func(sockfd, event_handle, &events)) {
+        if((err = SOCKERRNO) != EINPROGRESS) {
+          infof(data, "WSAEnumNetworkEvents failed (%d)", err);
+          keepon = FALSE;
+          result = CURLE_READ_ERROR;
+        }
+        break;
+      }
+      if(events.lNetworkEvents & FD_READ) {
+        /* read data from network */
+        result = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
+        /* read would've blocked. Loop again */
+        if(result == CURLE_AGAIN)
+          break;
+        /* returned not-zero, this an error */
+        else if(result) {
+          keepon = FALSE;
+          break;
+        }
+        /* returned zero but actually received 0 or less here,
+           the server closed the connection and we bail out */
+        else if(nread <= 0) {
+          keepon = FALSE;
+          break;
+        }
+
+        result = telrcv(conn, (unsigned char *) buf, nread);
+        if(result) {
+          keepon = FALSE;
+          break;
+        }
+
+        /* Negotiate if the peer has started negotiating,
+           otherwise don't. We don't want to speak telnet with
+           non-telnet servers, like POP or SMTP. */
+        if(tn->please_negotiate && !tn->already_negotiated) {
+          negotiate(conn);
+          tn->already_negotiated = 1;
+        }
+      }
+      if(events.lNetworkEvents & FD_CLOSE) {
+        keepon = FALSE;
+      }
+      break;
+
+    }
+
+    if(data->set.timeout) {
+      now = Curl_tvnow();
+      if(Curl_tvdiff(now, conn->created) >= data->set.timeout) {
+        failf(data, "Time-out");
+        result = CURLE_OPERATION_TIMEDOUT;
+        keepon = FALSE;
+      }
+    }
+  }
+
+  /* We called WSACreateEvent, so call WSACloseEvent */
+  if(!close_event_func(event_handle)) {
+    infof(data, "WSACloseEvent failed (%d)", SOCKERRNO);
+  }
+
+  /* "Forget" pointers into the library we're about to free */
+  create_event_func = NULL;
+  close_event_func = NULL;
+  event_select_func = NULL;
+  enum_netevents_func = NULL;
+
+  /* We called LoadLibrary, so call FreeLibrary */
+  if(!FreeLibrary(wsock2))
+    infof(data, "FreeLibrary(wsock2) failed (%d)", ERRNO);
+#else
+  pfd[0].fd = sockfd;
+  pfd[0].events = POLLIN;
+
+  if(data->set.is_fread_set) {
+    poll_cnt = 1;
+    interval_ms = 100; /* poll user-supplied read function */
+  }
+  else {
+    /* really using fread, so infile is a FILE* */
+    pfd[1].fd = fileno((FILE *)data->state.in);
+    pfd[1].events = POLLIN;
+    poll_cnt = 2;
+    interval_ms = 1 * 1000;
+  }
+
+  while(keepon) {
+    switch (Curl_poll(pfd, poll_cnt, interval_ms)) {
+    case -1:                    /* error, stop reading */
+      keepon = FALSE;
+      continue;
+    case 0:                     /* timeout */
+      pfd[0].revents = 0;
+      pfd[1].revents = 0;
+      /* fall through */
+    default:                    /* read! */
+      if(pfd[0].revents & POLLIN) {
+        /* read data from network */
+        result = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
+        /* read would've blocked. Loop again */
+        if(result == CURLE_AGAIN)
+          break;
+        /* returned not-zero, this an error */
+        else if(result) {
+          keepon = FALSE;
+          break;
+        }
+        /* returned zero but actually received 0 or less here,
+           the server closed the connection and we bail out */
+        else if(nread <= 0) {
+          keepon = FALSE;
+          break;
+        }
+
+        total_dl += nread;
+        Curl_pgrsSetDownloadCounter(data, total_dl);
+        result = telrcv(conn, (unsigned char *)buf, nread);
+        if(result) {
+          keepon = FALSE;
+          break;
+        }
+
+        /* Negotiate if the peer has started negotiating,
+           otherwise don't. We don't want to speak telnet with
+           non-telnet servers, like POP or SMTP. */
+        if(tn->please_negotiate && !tn->already_negotiated) {
+          negotiate(conn);
+          tn->already_negotiated = 1;
+        }
+      }
+
+      nread = 0;
+      if(poll_cnt == 2) {
+        if(pfd[1].revents & POLLIN) { /* read from in file */
+          nread = read(pfd[1].fd, buf, BUFSIZE - 1);
+        }
+      }
+      else {
+        /* read from user-supplied method */
+        nread = (int)data->state.fread_func(buf, 1, BUFSIZE - 1,
+                                            data->state.in);
+        if(nread == CURL_READFUNC_ABORT) {
+          keepon = FALSE;
+          break;
+        }
+        if(nread == CURL_READFUNC_PAUSE)
+          break;
+      }
+
+      if(nread > 0) {
+        result = send_telnet_data(conn, buf, nread);
+        if(result) {
+          keepon = FALSE;
+          break;
+        }
+        total_ul += nread;
+        Curl_pgrsSetUploadCounter(data, total_ul);
+      }
+      else if(nread < 0)
+        keepon = FALSE;
+
+      break;
+    } /* poll switch statement */
+
+    if(data->set.timeout) {
+      now = Curl_tvnow();
+      if(Curl_tvdiff(now, conn->created) >= data->set.timeout) {
+        failf(data, "Time-out");
+        result = CURLE_OPERATION_TIMEDOUT;
+        keepon = FALSE;
+      }
+    }
+
+    if(Curl_pgrsUpdate(conn)) {
+      result = CURLE_ABORTED_BY_CALLBACK;
+      break;
+    }
+  }
+#endif
+  /* mark this as "no further transfer wanted" */
+  Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+  return result;
+}
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/lib/telnet.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/telnet.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/telnet.h	(revision 164)
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_TELNET_H
+#define HEADER_CURL_TELNET_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_TELNET
+extern const struct Curl_handler Curl_handler_telnet;
+#endif
+
+#endif /* HEADER_CURL_TELNET_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/tftp.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/tftp.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/tftp.c	(revision 164)
@@ -0,0 +1,1376 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_TFTP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "tftp.h"
+#include "progress.h"
+#include "connect.h"
+#include "strerror.h"
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "multiif.h"
+#include "url.h"
+#include "rawstr.h"
+#include "speedcheck.h"
+#include "curl_printf.h"
+#include "select.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* RFC2348 allows the block size to be negotiated */
+#define TFTP_BLKSIZE_DEFAULT 512
+#define TFTP_BLKSIZE_MIN 8
+#define TFTP_BLKSIZE_MAX 65464
+#define TFTP_OPTION_BLKSIZE "blksize"
+
+/* from RFC2349: */
+#define TFTP_OPTION_TSIZE    "tsize"
+#define TFTP_OPTION_INTERVAL "timeout"
+
+typedef enum {
+  TFTP_MODE_NETASCII=0,
+  TFTP_MODE_OCTET
+} tftp_mode_t;
+
+typedef enum {
+  TFTP_STATE_START=0,
+  TFTP_STATE_RX,
+  TFTP_STATE_TX,
+  TFTP_STATE_FIN
+} tftp_state_t;
+
+typedef enum {
+  TFTP_EVENT_NONE = -1,
+  TFTP_EVENT_INIT = 0,
+  TFTP_EVENT_RRQ = 1,
+  TFTP_EVENT_WRQ = 2,
+  TFTP_EVENT_DATA = 3,
+  TFTP_EVENT_ACK = 4,
+  TFTP_EVENT_ERROR = 5,
+  TFTP_EVENT_OACK = 6,
+  TFTP_EVENT_TIMEOUT
+} tftp_event_t;
+
+typedef enum {
+  TFTP_ERR_UNDEF=0,
+  TFTP_ERR_NOTFOUND,
+  TFTP_ERR_PERM,
+  TFTP_ERR_DISKFULL,
+  TFTP_ERR_ILLEGAL,
+  TFTP_ERR_UNKNOWNID,
+  TFTP_ERR_EXISTS,
+  TFTP_ERR_NOSUCHUSER,  /* This will never be triggered by this code */
+
+  /* The remaining error codes are internal to curl */
+  TFTP_ERR_NONE = -100,
+  TFTP_ERR_TIMEOUT,
+  TFTP_ERR_NORESPONSE
+} tftp_error_t;
+
+typedef struct tftp_packet {
+  unsigned char *data;
+} tftp_packet_t;
+
+typedef struct tftp_state_data {
+  tftp_state_t    state;
+  tftp_mode_t     mode;
+  tftp_error_t    error;
+  tftp_event_t    event;
+  struct connectdata      *conn;
+  curl_socket_t   sockfd;
+  int             retries;
+  int             retry_time;
+  int             retry_max;
+  time_t          start_time;
+  time_t          max_time;
+  time_t          rx_time;
+  unsigned short  block;
+  struct Curl_sockaddr_storage   local_addr;
+  struct Curl_sockaddr_storage   remote_addr;
+  curl_socklen_t  remote_addrlen;
+  int             rbytes;
+  int             sbytes;
+  int             blksize;
+  int             requested_blksize;
+  tftp_packet_t   rpacket;
+  tftp_packet_t   spacket;
+} tftp_state_data_t;
+
+
+/* Forward declarations */
+static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event);
+static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event);
+static CURLcode tftp_connect(struct connectdata *conn, bool *done);
+static CURLcode tftp_disconnect(struct connectdata *conn,
+                                bool dead_connection);
+static CURLcode tftp_do(struct connectdata *conn, bool *done);
+static CURLcode tftp_done(struct connectdata *conn,
+                          CURLcode, bool premature);
+static CURLcode tftp_setup_connection(struct connectdata * conn);
+static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done);
+static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done);
+static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks);
+static CURLcode tftp_translate_code(tftp_error_t error);
+
+
+/*
+ * TFTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_tftp = {
+  "TFTP",                               /* scheme */
+  tftp_setup_connection,                /* setup_connection */
+  tftp_do,                              /* do_it */
+  tftp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  tftp_connect,                         /* connect_it */
+  tftp_multi_statemach,                 /* connecting */
+  tftp_doing,                           /* doing */
+  tftp_getsock,                         /* proto_getsock */
+  tftp_getsock,                         /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  tftp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_TFTP,                            /* defport */
+  CURLPROTO_TFTP,                       /* protocol */
+  PROTOPT_NONE | PROTOPT_NOURLQUERY     /* flags */
+};
+
+/**********************************************************
+ *
+ * tftp_set_timeouts -
+ *
+ * Set timeouts based on state machine state.
+ * Use user provided connect timeouts until DATA or ACK
+ * packet is received, then use user-provided transfer timeouts
+ *
+ *
+ **********************************************************/
+static CURLcode tftp_set_timeouts(tftp_state_data_t *state)
+{
+  time_t maxtime, timeout;
+  long timeout_ms;
+  bool start = (state->state == TFTP_STATE_START) ? TRUE : FALSE;
+
+  time(&state->start_time);
+
+  /* Compute drop-dead time */
+  timeout_ms = Curl_timeleft(state->conn->data, NULL, start);
+
+  if(timeout_ms < 0) {
+    /* time-out, bail out, go home */
+    failf(state->conn->data, "Connection time-out");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  if(start) {
+
+    maxtime = (time_t)(timeout_ms + 500) / 1000;
+    state->max_time = state->start_time+maxtime;
+
+    /* Set per-block timeout to total */
+    timeout = maxtime;
+
+    /* Average restart after 5 seconds */
+    state->retry_max = (int)timeout/5;
+
+    if(state->retry_max < 1)
+      /* avoid division by zero below */
+      state->retry_max = 1;
+
+    /* Compute the re-start interval to suit the timeout */
+    state->retry_time = (int)timeout/state->retry_max;
+    if(state->retry_time<1)
+      state->retry_time=1;
+
+  }
+  else {
+    if(timeout_ms > 0)
+      maxtime = (time_t)(timeout_ms + 500) / 1000;
+    else
+      maxtime = 3600;
+
+    state->max_time = state->start_time+maxtime;
+
+    /* Set per-block timeout to total */
+    timeout = maxtime;
+
+    /* Average reposting an ACK after 5 seconds */
+    state->retry_max = (int)timeout/5;
+  }
+  /* But bound the total number */
+  if(state->retry_max<3)
+    state->retry_max=3;
+
+  if(state->retry_max>50)
+    state->retry_max=50;
+
+  /* Compute the re-ACK interval to suit the timeout */
+  state->retry_time = (int)(timeout/state->retry_max);
+  if(state->retry_time<1)
+    state->retry_time=1;
+
+  infof(state->conn->data,
+        "set timeouts for state %d; Total %ld, retry %d maxtry %d\n",
+        (int)state->state, (long)(state->max_time-state->start_time),
+        state->retry_time, state->retry_max);
+
+  /* init RX time */
+  time(&state->rx_time);
+
+  return CURLE_OK;
+}
+
+/**********************************************************
+ *
+ * tftp_set_send_first
+ *
+ * Event handler for the START state
+ *
+ **********************************************************/
+
+static void setpacketevent(tftp_packet_t *packet, unsigned short num)
+{
+  packet->data[0] = (unsigned char)(num >> 8);
+  packet->data[1] = (unsigned char)(num & 0xff);
+}
+
+
+static void setpacketblock(tftp_packet_t *packet, unsigned short num)
+{
+  packet->data[2] = (unsigned char)(num >> 8);
+  packet->data[3] = (unsigned char)(num & 0xff);
+}
+
+static unsigned short getrpacketevent(const tftp_packet_t *packet)
+{
+  return (unsigned short)((packet->data[0] << 8) | packet->data[1]);
+}
+
+static unsigned short getrpacketblock(const tftp_packet_t *packet)
+{
+  return (unsigned short)((packet->data[2] << 8) | packet->data[3]);
+}
+
+static size_t Curl_strnlen(const char *string, size_t maxlen)
+{
+  const char *end = memchr (string, '\0', maxlen);
+  return end ? (size_t) (end - string) : maxlen;
+}
+
+static const char *tftp_option_get(const char *buf, size_t len,
+                                   const char **option, const char **value)
+{
+  size_t loc;
+
+  loc = Curl_strnlen( buf, len );
+  loc++; /* NULL term */
+
+  if(loc >= len)
+    return NULL;
+  *option = buf;
+
+  loc += Curl_strnlen( buf+loc, len-loc );
+  loc++; /* NULL term */
+
+  if(loc > len)
+    return NULL;
+  *value = &buf[strlen(*option) + 1];
+
+  return &buf[loc];
+}
+
+static CURLcode tftp_parse_option_ack(tftp_state_data_t *state,
+                                      const char *ptr, int len)
+{
+  const char *tmp = ptr;
+  struct SessionHandle *data = state->conn->data;
+
+  /* if OACK doesn't contain blksize option, the default (512) must be used */
+  state->blksize = TFTP_BLKSIZE_DEFAULT;
+
+  while(tmp < ptr + len) {
+    const char *option, *value;
+
+    tmp = tftp_option_get(tmp, ptr + len - tmp, &option, &value);
+    if(tmp == NULL) {
+      failf(data, "Malformed ACK packet, rejecting");
+      return CURLE_TFTP_ILLEGAL;
+    }
+
+    infof(data, "got option=(%s) value=(%s)\n", option, value);
+
+    if(checkprefix(option, TFTP_OPTION_BLKSIZE)) {
+      long blksize;
+
+      blksize = strtol( value, NULL, 10 );
+
+      if(!blksize) {
+        failf(data, "invalid blocksize value in OACK packet");
+        return CURLE_TFTP_ILLEGAL;
+      }
+      else if(blksize > TFTP_BLKSIZE_MAX) {
+        failf(data, "%s (%d)", "blksize is larger than max supported",
+              TFTP_BLKSIZE_MAX);
+        return CURLE_TFTP_ILLEGAL;
+      }
+      else if(blksize < TFTP_BLKSIZE_MIN) {
+        failf(data, "%s (%d)", "blksize is smaller than min supported",
+              TFTP_BLKSIZE_MIN);
+        return CURLE_TFTP_ILLEGAL;
+      }
+      else if(blksize > state->requested_blksize) {
+        /* could realloc pkt buffers here, but the spec doesn't call out
+         * support for the server requesting a bigger blksize than the client
+         * requests */
+        failf(data, "%s (%ld)",
+              "server requested blksize larger than allocated", blksize);
+        return CURLE_TFTP_ILLEGAL;
+      }
+
+      state->blksize = (int)blksize;
+      infof(data, "%s (%d) %s (%d)\n", "blksize parsed from OACK",
+            state->blksize, "requested", state->requested_blksize);
+    }
+    else if(checkprefix(option, TFTP_OPTION_TSIZE)) {
+      long tsize = 0;
+
+      tsize = strtol( value, NULL, 10 );
+      infof(data, "%s (%ld)\n", "tsize parsed from OACK", tsize);
+
+      /* tsize should be ignored on upload: Who cares about the size of the
+         remote file? */
+      if(!data->set.upload) {
+        if(!tsize) {
+          failf(data, "invalid tsize -:%s:- value in OACK packet", value);
+          return CURLE_TFTP_ILLEGAL;
+        }
+        Curl_pgrsSetDownloadSize(data, tsize);
+      }
+    }
+  }
+
+  return CURLE_OK;
+}
+
+static size_t tftp_option_add(tftp_state_data_t *state, size_t csize,
+                              char *buf, const char *option)
+{
+  if(( strlen(option) + csize + 1 ) > (size_t)state->blksize)
+    return 0;
+  strcpy(buf, option);
+  return strlen(option) + 1;
+}
+
+static CURLcode tftp_connect_for_tx(tftp_state_data_t *state,
+                                    tftp_event_t event)
+{
+  CURLcode result;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  struct SessionHandle *data = state->conn->data;
+
+  infof(data, "%s\n", "Connected for transmit");
+#endif
+  state->state = TFTP_STATE_TX;
+  result = tftp_set_timeouts(state);
+  if(result)
+    return result;
+  return tftp_tx(state, event);
+}
+
+static CURLcode tftp_connect_for_rx(tftp_state_data_t *state,
+                                    tftp_event_t event)
+{
+  CURLcode result;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  struct SessionHandle *data = state->conn->data;
+
+  infof(data, "%s\n", "Connected for receive");
+#endif
+  state->state = TFTP_STATE_RX;
+  result = tftp_set_timeouts(state);
+  if(result)
+    return result;
+  return tftp_rx(state, event);
+}
+
+static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
+{
+  size_t sbytes;
+  ssize_t senddata;
+  const char *mode = "octet";
+  char *filename;
+  char buf[64];
+  struct SessionHandle *data = state->conn->data;
+  CURLcode result = CURLE_OK;
+
+  /* Set ascii mode if -B flag was used */
+  if(data->set.prefer_ascii)
+    mode = "netascii";
+
+  switch(event) {
+
+  case TFTP_EVENT_INIT:    /* Send the first packet out */
+  case TFTP_EVENT_TIMEOUT: /* Resend the first packet out */
+    /* Increment the retry counter, quit if over the limit */
+    state->retries++;
+    if(state->retries>state->retry_max) {
+      state->error = TFTP_ERR_NORESPONSE;
+      state->state = TFTP_STATE_FIN;
+      return result;
+    }
+
+    if(data->set.upload) {
+      /* If we are uploading, send an WRQ */
+      setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
+      state->conn->data->req.upload_fromhere =
+        (char *)state->spacket.data+4;
+      if(data->state.infilesize != -1)
+        Curl_pgrsSetUploadSize(data, data->state.infilesize);
+    }
+    else {
+      /* If we are downloading, send an RRQ */
+      setpacketevent(&state->spacket, TFTP_EVENT_RRQ);
+    }
+    /* As RFC3617 describes the separator slash is not actually part of the
+       file name so we skip the always-present first letter of the path
+       string. */
+    filename = curl_easy_unescape(data, &state->conn->data->state.path[1], 0,
+                                  NULL);
+    if(!filename)
+      return CURLE_OUT_OF_MEMORY;
+
+    snprintf((char *)state->spacket.data+2,
+             state->blksize,
+             "%s%c%s%c", filename, '\0',  mode, '\0');
+    sbytes = 4 + strlen(filename) + strlen(mode);
+
+    /* add tsize option */
+    if(data->set.upload && (data->state.infilesize != -1))
+      snprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
+               data->state.infilesize);
+    else
+      strcpy(buf, "0"); /* the destination is large enough */
+
+    sbytes += tftp_option_add(state, sbytes,
+                              (char *)state->spacket.data+sbytes,
+                              TFTP_OPTION_TSIZE);
+    sbytes += tftp_option_add(state, sbytes,
+                              (char *)state->spacket.data+sbytes, buf);
+    /* add blksize option */
+    snprintf( buf, sizeof(buf), "%d", state->requested_blksize );
+    sbytes += tftp_option_add(state, sbytes,
+                              (char *)state->spacket.data+sbytes,
+                              TFTP_OPTION_BLKSIZE);
+    sbytes += tftp_option_add(state, sbytes,
+                              (char *)state->spacket.data+sbytes, buf );
+
+    /* add timeout option */
+    snprintf( buf, sizeof(buf), "%d", state->retry_time);
+    sbytes += tftp_option_add(state, sbytes,
+                              (char *)state->spacket.data+sbytes,
+                              TFTP_OPTION_INTERVAL);
+    sbytes += tftp_option_add(state, sbytes,
+                              (char *)state->spacket.data+sbytes, buf );
+
+    /* the typecase for the 3rd argument is mostly for systems that do
+       not have a size_t argument, like older unixes that want an 'int' */
+    senddata = sendto(state->sockfd, (void *)state->spacket.data,
+                      (SEND_TYPE_ARG3)sbytes, 0,
+                      state->conn->ip_addr->ai_addr,
+                      state->conn->ip_addr->ai_addrlen);
+    if(senddata != (ssize_t)sbytes) {
+      failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+    }
+    free(filename);
+    break;
+
+  case TFTP_EVENT_OACK:
+    if(data->set.upload) {
+      result = tftp_connect_for_tx(state, event);
+    }
+    else {
+      result = tftp_connect_for_rx(state, event);
+    }
+    break;
+
+  case TFTP_EVENT_ACK: /* Connected for transmit */
+    result = tftp_connect_for_tx(state, event);
+    break;
+
+  case TFTP_EVENT_DATA: /* Connected for receive */
+    result = tftp_connect_for_rx(state, event);
+    break;
+
+  case TFTP_EVENT_ERROR:
+    state->state = TFTP_STATE_FIN;
+    break;
+
+  default:
+    failf(state->conn->data, "tftp_send_first: internal error");
+    break;
+  }
+
+  return result;
+}
+
+/* the next blocknum is x + 1 but it needs to wrap at an unsigned 16bit
+   boundary */
+#define NEXT_BLOCKNUM(x) (((x)+1)&0xffff)
+
+/**********************************************************
+ *
+ * tftp_rx
+ *
+ * Event handler for the RX state
+ *
+ **********************************************************/
+static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
+{
+  ssize_t sbytes;
+  int rblock;
+  struct SessionHandle *data = state->conn->data;
+
+  switch(event) {
+
+  case TFTP_EVENT_DATA:
+    /* Is this the block we expect? */
+    rblock = getrpacketblock(&state->rpacket);
+    if(NEXT_BLOCKNUM(state->block) == rblock) {
+      /* This is the expected block.  Reset counters and ACK it. */
+      state->retries = 0;
+    }
+    else if(state->block == rblock) {
+      /* This is the last recently received block again. Log it and ACK it
+         again. */
+      infof(data, "Received last DATA packet block %d again.\n", rblock);
+    }
+    else {
+      /* totally unexpected, just log it */
+      infof(data,
+            "Received unexpected DATA packet block %d, expecting block %d\n",
+            rblock, NEXT_BLOCKNUM(state->block));
+      break;
+    }
+
+    /* ACK this block. */
+    state->block = (unsigned short)rblock;
+    setpacketevent(&state->spacket, TFTP_EVENT_ACK);
+    setpacketblock(&state->spacket, state->block);
+    sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+                    4, SEND_4TH_ARG,
+                    (struct sockaddr *)&state->remote_addr,
+                    state->remote_addrlen);
+    if(sbytes < 0) {
+      failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+      return CURLE_SEND_ERROR;
+    }
+
+    /* Check if completed (That is, a less than full packet is received) */
+    if(state->rbytes < (ssize_t)state->blksize+4) {
+      state->state = TFTP_STATE_FIN;
+    }
+    else {
+      state->state = TFTP_STATE_RX;
+    }
+    time(&state->rx_time);
+    break;
+
+  case TFTP_EVENT_OACK:
+    /* ACK option acknowledgement so we can move on to data */
+    state->block = 0;
+    state->retries = 0;
+    setpacketevent(&state->spacket, TFTP_EVENT_ACK);
+    setpacketblock(&state->spacket, state->block);
+    sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+                    4, SEND_4TH_ARG,
+                    (struct sockaddr *)&state->remote_addr,
+                    state->remote_addrlen);
+    if(sbytes < 0) {
+      failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+      return CURLE_SEND_ERROR;
+    }
+
+    /* we're ready to RX data */
+    state->state = TFTP_STATE_RX;
+    time(&state->rx_time);
+    break;
+
+  case TFTP_EVENT_TIMEOUT:
+    /* Increment the retry count and fail if over the limit */
+    state->retries++;
+    infof(data,
+          "Timeout waiting for block %d ACK.  Retries = %d\n",
+          NEXT_BLOCKNUM(state->block), state->retries);
+    if(state->retries > state->retry_max) {
+      state->error = TFTP_ERR_TIMEOUT;
+      state->state = TFTP_STATE_FIN;
+    }
+    else {
+      /* Resend the previous ACK */
+      sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+                      4, SEND_4TH_ARG,
+                      (struct sockaddr *)&state->remote_addr,
+                      state->remote_addrlen);
+      if(sbytes<0) {
+        failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+        return CURLE_SEND_ERROR;
+      }
+    }
+    break;
+
+  case TFTP_EVENT_ERROR:
+    setpacketevent(&state->spacket, TFTP_EVENT_ERROR);
+    setpacketblock(&state->spacket, state->block);
+    (void)sendto(state->sockfd, (void *)state->spacket.data,
+                 4, SEND_4TH_ARG,
+                 (struct sockaddr *)&state->remote_addr,
+                 state->remote_addrlen);
+    /* don't bother with the return code, but if the socket is still up we
+     * should be a good TFTP client and let the server know we're done */
+    state->state = TFTP_STATE_FIN;
+    break;
+
+  default:
+    failf(data, "%s", "tftp_rx: internal error");
+    return CURLE_TFTP_ILLEGAL; /* not really the perfect return code for
+                                  this */
+  }
+  return CURLE_OK;
+}
+
+/**********************************************************
+ *
+ * tftp_tx
+ *
+ * Event handler for the TX state
+ *
+ **********************************************************/
+static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
+{
+  struct SessionHandle *data = state->conn->data;
+  ssize_t sbytes;
+  int rblock;
+  CURLcode result = CURLE_OK;
+  struct SingleRequest *k = &data->req;
+
+  switch(event) {
+
+  case TFTP_EVENT_ACK:
+  case TFTP_EVENT_OACK:
+    if(event == TFTP_EVENT_ACK) {
+      /* Ack the packet */
+      rblock = getrpacketblock(&state->rpacket);
+
+      if(rblock != state->block &&
+         /* There's a bug in tftpd-hpa that causes it to send us an ack for
+          * 65535 when the block number wraps to 0. So when we're expecting
+          * 0, also accept 65535. See
+          * http://syslinux.zytor.com/archives/2010-September/015253.html
+          * */
+         !(state->block == 0 && rblock == 65535)) {
+        /* This isn't the expected block.  Log it and up the retry counter */
+        infof(data, "Received ACK for block %d, expecting %d\n",
+              rblock, state->block);
+        state->retries++;
+        /* Bail out if over the maximum */
+        if(state->retries>state->retry_max) {
+          failf(data, "tftp_tx: giving up waiting for block %d ack",
+                state->block);
+          result = CURLE_SEND_ERROR;
+        }
+        else {
+          /* Re-send the data packet */
+          sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+                          4+state->sbytes, SEND_4TH_ARG,
+                          (struct sockaddr *)&state->remote_addr,
+                          state->remote_addrlen);
+          /* Check all sbytes were sent */
+          if(sbytes<0) {
+            failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+            result = CURLE_SEND_ERROR;
+          }
+        }
+
+        return result;
+      }
+      /* This is the expected packet.  Reset the counters and send the next
+         block */
+      time(&state->rx_time);
+      state->block++;
+    }
+    else
+      state->block = 1; /* first data block is 1 when using OACK */
+
+    state->retries = 0;
+    setpacketevent(&state->spacket, TFTP_EVENT_DATA);
+    setpacketblock(&state->spacket, state->block);
+    if(state->block > 1 && state->sbytes < (int)state->blksize) {
+      state->state = TFTP_STATE_FIN;
+      return CURLE_OK;
+    }
+
+    result = Curl_fillreadbuffer(state->conn, state->blksize, &state->sbytes);
+    if(result)
+      return result;
+
+    sbytes = sendto(state->sockfd, (void *) state->spacket.data,
+                    4 + state->sbytes, SEND_4TH_ARG,
+                    (struct sockaddr *)&state->remote_addr,
+                    state->remote_addrlen);
+    /* Check all sbytes were sent */
+    if(sbytes<0) {
+      failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+      return CURLE_SEND_ERROR;
+    }
+    /* Update the progress meter */
+    k->writebytecount += state->sbytes;
+    Curl_pgrsSetUploadCounter(data, k->writebytecount);
+    break;
+
+  case TFTP_EVENT_TIMEOUT:
+    /* Increment the retry counter and log the timeout */
+    state->retries++;
+    infof(data, "Timeout waiting for block %d ACK. "
+          " Retries = %d\n", NEXT_BLOCKNUM(state->block), state->retries);
+    /* Decide if we've had enough */
+    if(state->retries > state->retry_max) {
+      state->error = TFTP_ERR_TIMEOUT;
+      state->state = TFTP_STATE_FIN;
+    }
+    else {
+      /* Re-send the data packet */
+      sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+                      4+state->sbytes, SEND_4TH_ARG,
+                      (struct sockaddr *)&state->remote_addr,
+                      state->remote_addrlen);
+      /* Check all sbytes were sent */
+      if(sbytes<0) {
+        failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+        return CURLE_SEND_ERROR;
+      }
+      /* since this was a re-send, we remain at the still byte position */
+      Curl_pgrsSetUploadCounter(data, k->writebytecount);
+    }
+    break;
+
+  case TFTP_EVENT_ERROR:
+    state->state = TFTP_STATE_FIN;
+    setpacketevent(&state->spacket, TFTP_EVENT_ERROR);
+    setpacketblock(&state->spacket, state->block);
+    (void)sendto(state->sockfd, (void *)state->spacket.data, 4, SEND_4TH_ARG,
+                 (struct sockaddr *)&state->remote_addr,
+                 state->remote_addrlen);
+    /* don't bother with the return code, but if the socket is still up we
+     * should be a good TFTP client and let the server know we're done */
+    state->state = TFTP_STATE_FIN;
+    break;
+
+  default:
+    failf(data, "tftp_tx: internal error, event: %i", (int)(event));
+    break;
+  }
+
+  return result;
+}
+
+/**********************************************************
+ *
+ * tftp_translate_code
+ *
+ * Translate internal error codes to CURL error codes
+ *
+ **********************************************************/
+static CURLcode tftp_translate_code(tftp_error_t error)
+{
+  CURLcode result = CURLE_OK;
+
+  if(error != TFTP_ERR_NONE) {
+    switch(error) {
+    case TFTP_ERR_NOTFOUND:
+      result = CURLE_TFTP_NOTFOUND;
+      break;
+    case TFTP_ERR_PERM:
+      result = CURLE_TFTP_PERM;
+      break;
+    case TFTP_ERR_DISKFULL:
+      result = CURLE_REMOTE_DISK_FULL;
+      break;
+    case TFTP_ERR_UNDEF:
+    case TFTP_ERR_ILLEGAL:
+      result = CURLE_TFTP_ILLEGAL;
+      break;
+    case TFTP_ERR_UNKNOWNID:
+      result = CURLE_TFTP_UNKNOWNID;
+      break;
+    case TFTP_ERR_EXISTS:
+      result = CURLE_REMOTE_FILE_EXISTS;
+      break;
+    case TFTP_ERR_NOSUCHUSER:
+      result = CURLE_TFTP_NOSUCHUSER;
+      break;
+    case TFTP_ERR_TIMEOUT:
+      result = CURLE_OPERATION_TIMEDOUT;
+      break;
+    case TFTP_ERR_NORESPONSE:
+      result = CURLE_COULDNT_CONNECT;
+      break;
+    default:
+      result = CURLE_ABORTED_BY_CALLBACK;
+      break;
+    }
+  }
+  else
+    result = CURLE_OK;
+
+  return result;
+}
+
+/**********************************************************
+ *
+ * tftp_state_machine
+ *
+ * The tftp state machine event dispatcher
+ *
+ **********************************************************/
+static CURLcode tftp_state_machine(tftp_state_data_t *state,
+                                   tftp_event_t event)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = state->conn->data;
+
+  switch(state->state) {
+  case TFTP_STATE_START:
+    DEBUGF(infof(data, "TFTP_STATE_START\n"));
+    result = tftp_send_first(state, event);
+    break;
+  case TFTP_STATE_RX:
+    DEBUGF(infof(data, "TFTP_STATE_RX\n"));
+    result = tftp_rx(state, event);
+    break;
+  case TFTP_STATE_TX:
+    DEBUGF(infof(data, "TFTP_STATE_TX\n"));
+    result = tftp_tx(state, event);
+    break;
+  case TFTP_STATE_FIN:
+    infof(data, "%s\n", "TFTP finished");
+    break;
+  default:
+    DEBUGF(infof(data, "STATE: %d\n", state->state));
+    failf(data, "%s", "Internal state machine error");
+    result = CURLE_TFTP_ILLEGAL;
+    break;
+  }
+
+  return result;
+}
+
+/**********************************************************
+ *
+ * tftp_disconnect
+ *
+ * The disconnect callback
+ *
+ **********************************************************/
+static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  tftp_state_data_t *state = conn->proto.tftpc;
+  (void) dead_connection;
+
+  /* done, free dynamically allocated pkt buffers */
+  if(state) {
+    Curl_safefree(state->rpacket.data);
+    Curl_safefree(state->spacket.data);
+    free(state);
+  }
+
+  return CURLE_OK;
+}
+
+/**********************************************************
+ *
+ * tftp_connect
+ *
+ * The connect callback
+ *
+ **********************************************************/
+static CURLcode tftp_connect(struct connectdata *conn, bool *done)
+{
+  tftp_state_data_t *state;
+  int blksize, rc;
+
+  blksize = TFTP_BLKSIZE_DEFAULT;
+
+  state = conn->proto.tftpc = calloc(1, sizeof(tftp_state_data_t));
+  if(!state)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* alloc pkt buffers based on specified blksize */
+  if(conn->data->set.tftp_blksize) {
+    blksize = (int)conn->data->set.tftp_blksize;
+    if(blksize > TFTP_BLKSIZE_MAX || blksize < TFTP_BLKSIZE_MIN )
+      return CURLE_TFTP_ILLEGAL;
+  }
+
+  if(!state->rpacket.data) {
+    state->rpacket.data = calloc(1, blksize + 2 + 2);
+
+    if(!state->rpacket.data)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(!state->spacket.data) {
+    state->spacket.data = calloc(1, blksize + 2 + 2);
+
+    if(!state->spacket.data)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* we don't keep TFTP connections up bascially because there's none or very
+   * little gain for UDP */
+  connclose(conn, "TFTP");
+
+  state->conn = conn;
+  state->sockfd = state->conn->sock[FIRSTSOCKET];
+  state->state = TFTP_STATE_START;
+  state->error = TFTP_ERR_NONE;
+  state->blksize = TFTP_BLKSIZE_DEFAULT;
+  state->requested_blksize = blksize;
+
+  ((struct sockaddr *)&state->local_addr)->sa_family =
+    (unsigned short)(conn->ip_addr->ai_family);
+
+  tftp_set_timeouts(state);
+
+  if(!conn->bits.bound) {
+    /* If not already bound, bind to any interface, random UDP port. If it is
+     * reused or a custom local port was desired, this has already been done!
+     *
+     * We once used the size of the local_addr struct as the third argument
+     * for bind() to better work with IPv6 or whatever size the struct could
+     * have, but we learned that at least Tru64, AIX and IRIX *requires* the
+     * size of that argument to match the exact size of a 'sockaddr_in' struct
+     * when running IPv4-only.
+     *
+     * Therefore we use the size from the address we connected to, which we
+     * assume uses the same IP version and thus hopefully this works for both
+     * IPv4 and IPv6...
+     */
+    rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
+              conn->ip_addr->ai_addrlen);
+    if(rc) {
+      failf(conn->data, "bind() failed; %s",
+            Curl_strerror(conn, SOCKERRNO));
+      return CURLE_COULDNT_CONNECT;
+    }
+    conn->bits.bound = TRUE;
+  }
+
+  Curl_pgrsStartNow(conn->data);
+
+  *done = TRUE;
+
+  return CURLE_OK;
+}
+
+/**********************************************************
+ *
+ * tftp_done
+ *
+ * The done callback
+ *
+ **********************************************************/
+static CURLcode tftp_done(struct connectdata *conn, CURLcode status,
+                          bool premature)
+{
+  CURLcode result = CURLE_OK;
+  tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
+
+  (void)status; /* unused */
+  (void)premature; /* not used */
+
+  if(Curl_pgrsDone(conn))
+    return CURLE_ABORTED_BY_CALLBACK;
+
+  /* If we have encountered an error */
+  if(state)
+    result = tftp_translate_code(state->error);
+
+  return result;
+}
+
+/**********************************************************
+ *
+ * tftp_getsock
+ *
+ * The getsock callback
+ *
+ **********************************************************/
+static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks)
+{
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  socks[0] = conn->sock[FIRSTSOCKET];
+
+  return GETSOCK_READSOCK(0);
+}
+
+/**********************************************************
+ *
+ * tftp_receive_packet
+ *
+ * Called once select fires and data is ready on the socket
+ *
+ **********************************************************/
+static CURLcode tftp_receive_packet(struct connectdata *conn)
+{
+  struct Curl_sockaddr_storage fromaddr;
+  curl_socklen_t        fromlen;
+  CURLcode              result = CURLE_OK;
+  struct SessionHandle  *data = conn->data;
+  tftp_state_data_t     *state = (tftp_state_data_t *)conn->proto.tftpc;
+  struct SingleRequest  *k = &data->req;
+
+  /* Receive the packet */
+  fromlen = sizeof(fromaddr);
+  state->rbytes = (int)recvfrom(state->sockfd,
+                                (void *)state->rpacket.data,
+                                state->blksize+4,
+                                0,
+                                (struct sockaddr *)&fromaddr,
+                                &fromlen);
+  if(state->remote_addrlen==0) {
+    memcpy(&state->remote_addr, &fromaddr, fromlen);
+    state->remote_addrlen = fromlen;
+  }
+
+  /* Sanity check packet length */
+  if(state->rbytes < 4) {
+    failf(data, "Received too short packet");
+    /* Not a timeout, but how best to handle it? */
+    state->event = TFTP_EVENT_TIMEOUT;
+  }
+  else {
+    /* The event is given by the TFTP packet time */
+    state->event = (tftp_event_t)getrpacketevent(&state->rpacket);
+
+    switch(state->event) {
+    case TFTP_EVENT_DATA:
+      /* Don't pass to the client empty or retransmitted packets */
+      if(state->rbytes > 4 &&
+         (NEXT_BLOCKNUM(state->block) == getrpacketblock(&state->rpacket))) {
+        result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                   (char *)state->rpacket.data+4,
+                                   state->rbytes-4);
+        if(result) {
+          tftp_state_machine(state, TFTP_EVENT_ERROR);
+          return result;
+        }
+        k->bytecount += state->rbytes-4;
+        Curl_pgrsSetDownloadCounter(data, (curl_off_t) k->bytecount);
+      }
+      break;
+    case TFTP_EVENT_ERROR:
+      state->error = (tftp_error_t)getrpacketblock(&state->rpacket);
+      infof(data, "%s\n", (const char *)state->rpacket.data+4);
+      break;
+    case TFTP_EVENT_ACK:
+      break;
+    case TFTP_EVENT_OACK:
+      result = tftp_parse_option_ack(state,
+                                     (const char *)state->rpacket.data+2,
+                                     state->rbytes-2);
+      if(result)
+        return result;
+      break;
+    case TFTP_EVENT_RRQ:
+    case TFTP_EVENT_WRQ:
+    default:
+      failf(data, "%s", "Internal error: Unexpected packet");
+      break;
+    }
+
+    /* Update the progress meter */
+    if(Curl_pgrsUpdate(conn)) {
+      tftp_state_machine(state, TFTP_EVENT_ERROR);
+      return CURLE_ABORTED_BY_CALLBACK;
+    }
+  }
+  return result;
+}
+
+/**********************************************************
+ *
+ * tftp_state_timeout
+ *
+ * Check if timeouts have been reached
+ *
+ **********************************************************/
+static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
+{
+  time_t                current;
+  tftp_state_data_t     *state = (tftp_state_data_t *)conn->proto.tftpc;
+
+  if(event)
+    *event = TFTP_EVENT_NONE;
+
+  time(&current);
+  if(current > state->max_time) {
+    DEBUGF(infof(conn->data, "timeout: %ld > %ld\n",
+                 (long)current, (long)state->max_time));
+    state->error = TFTP_ERR_TIMEOUT;
+    state->state = TFTP_STATE_FIN;
+    return 0;
+  }
+  else if(current > state->rx_time+state->retry_time) {
+    if(event)
+      *event = TFTP_EVENT_TIMEOUT;
+    time(&state->rx_time); /* update even though we received nothing */
+  }
+
+  /* there's a typecast below here since 'time_t' may in fact be larger than
+     'long', but we estimate that a 'long' will still be able to hold number
+     of seconds even if "only" 32 bit */
+  return (long)(state->max_time - current);
+}
+
+/**********************************************************
+ *
+ * tftp_multi_statemach
+ *
+ * Handle single RX socket event and return
+ *
+ **********************************************************/
+static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
+{
+  int                   rc;
+  tftp_event_t          event;
+  CURLcode              result = CURLE_OK;
+  struct SessionHandle  *data = conn->data;
+  tftp_state_data_t     *state = (tftp_state_data_t *)conn->proto.tftpc;
+  long                  timeout_ms = tftp_state_timeout(conn, &event);
+
+  *done = FALSE;
+
+  if(timeout_ms <= 0) {
+    failf(data, "TFTP response timeout");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+  else if(event != TFTP_EVENT_NONE) {
+    result = tftp_state_machine(state, event);
+    if(result)
+      return result;
+    *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
+    if(*done)
+      /* Tell curl we're done */
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+  }
+  else {
+    /* no timeouts to handle, check our socket */
+    rc = Curl_socket_ready(state->sockfd, CURL_SOCKET_BAD, 0);
+
+    if(rc == -1) {
+      /* bail out */
+      int error = SOCKERRNO;
+      failf(data, "%s", Curl_strerror(conn, error));
+      state->event = TFTP_EVENT_ERROR;
+    }
+    else if(rc != 0) {
+      result = tftp_receive_packet(conn);
+      if(result)
+        return result;
+      result = tftp_state_machine(state, state->event);
+      if(result)
+        return result;
+      *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
+      if(*done)
+        /* Tell curl we're done */
+        Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+    }
+    /* if rc == 0, then select() timed out */
+  }
+
+  return result;
+}
+
+/**********************************************************
+ *
+ * tftp_doing
+ *
+ * Called from multi.c while DOing
+ *
+ **********************************************************/
+static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done)
+{
+  CURLcode result;
+  result = tftp_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  else if(!result) {
+    /* The multi code doesn't have this logic for the DOING state so we
+       provide it for TFTP since it may do the entire transfer in this
+       state. */
+    if(Curl_pgrsUpdate(conn))
+      result = CURLE_ABORTED_BY_CALLBACK;
+    else
+      result = Curl_speedcheck(conn->data, Curl_tvnow());
+  }
+  return result;
+}
+
+/**********************************************************
+ *
+ * tftp_peform
+ *
+ * Entry point for transfer from tftp_do, sarts state mach
+ *
+ **********************************************************/
+static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done)
+{
+  CURLcode              result = CURLE_OK;
+  tftp_state_data_t     *state = (tftp_state_data_t *)conn->proto.tftpc;
+
+  *dophase_done = FALSE;
+
+  result = tftp_state_machine(state, TFTP_EVENT_INIT);
+
+  if((state->state == TFTP_STATE_FIN) || result)
+    return result;
+
+  tftp_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done)
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+
+  return result;
+}
+
+
+/**********************************************************
+ *
+ * tftp_do
+ *
+ * The do callback
+ *
+ * This callback initiates the TFTP transfer
+ *
+ **********************************************************/
+
+static CURLcode tftp_do(struct connectdata *conn, bool *done)
+{
+  tftp_state_data_t *state;
+  CURLcode result;
+
+  *done = FALSE;
+
+  if(!conn->proto.tftpc) {
+    result = tftp_connect(conn, done);
+    if(result)
+      return result;
+  }
+
+  state = (tftp_state_data_t *)conn->proto.tftpc;
+  if(!state)
+    return CURLE_BAD_CALLING_ORDER;
+
+  result = tftp_perform(conn, done);
+
+  /* If tftp_perform() returned an error, use that for return code. If it
+     was OK, see if tftp_translate_code() has an error. */
+  if(!result)
+    /* If we have encountered an internal tftp error, translate it. */
+    result = tftp_translate_code(state->error);
+
+  return result;
+}
+
+static CURLcode tftp_setup_connection(struct connectdata * conn)
+{
+  struct SessionHandle *data = conn->data;
+  char * type;
+  char command;
+
+  conn->socktype = SOCK_DGRAM;   /* UDP datagram based */
+
+  /* TFTP URLs support an extension like ";mode=<typecode>" that
+   * we'll try to get now! */
+  type = strstr(data->state.path, ";mode=");
+
+  if(!type)
+    type = strstr(conn->host.rawalloc, ";mode=");
+
+  if(type) {
+    *type = 0;                   /* it was in the middle of the hostname */
+    command = Curl_raw_toupper(type[6]);
+
+    switch (command) {
+    case 'A': /* ASCII mode */
+    case 'N': /* NETASCII mode */
+      data->set.prefer_ascii = TRUE;
+      break;
+
+    case 'O': /* octet mode */
+    case 'I': /* binary mode */
+    default:
+      /* switch off ASCII */
+      data->set.prefer_ascii = FALSE;
+      break;
+    }
+  }
+
+  return CURLE_OK;
+}
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/lib/tftp.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/tftp.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/tftp.h	(revision 164)
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_TFTP_H
+#define HEADER_CURL_TFTP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_TFTP
+extern const struct Curl_handler Curl_handler_tftp;
+#endif
+
+#endif /* HEADER_CURL_TFTP_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/timeval.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/timeval.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/timeval.c	(revision 164)
@@ -0,0 +1,142 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "timeval.h"
+
+#if 0//defined(WIN32) && !defined(MSDOS)
+
+struct timeval curlx_tvnow(void)
+{
+  /*
+  ** GetTickCount() is available on _all_ Windows versions from W95 up
+  ** to nowadays. Returns milliseconds elapsed since last system boot,
+  ** increases monotonically and wraps once 49.7 days have elapsed.
+  */
+  struct timeval now;
+#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
+    (_WIN32_WINNT < _WIN32_WINNT_VISTA)
+  DWORD milliseconds = GetTickCount();
+  now.tv_sec = milliseconds / 1000;
+  now.tv_usec = (milliseconds % 1000) * 1000;
+#else
+  ULONGLONG milliseconds = GetTickCount64();
+  now.tv_sec = (long) (milliseconds / 1000);
+  now.tv_usec = (long) (milliseconds % 1000) * 1000;
+#endif
+
+  return now;
+}
+
+#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
+
+struct timeval curlx_tvnow(void)
+{
+  /*
+  ** clock_gettime() is granted to be increased monotonically when the
+  ** monotonic clock is queried. Time starting point is unspecified, it
+  ** could be the system start-up time, the Epoch, or something else,
+  ** in any case the time starting point does not change once that the
+  ** system has started up.
+  */
+  struct timeval now;
+  struct timespec tsnow;
+  if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
+    now.tv_sec = tsnow.tv_sec;
+    now.tv_usec = tsnow.tv_nsec / 1000;
+  }
+  /*
+  ** Even when the configure process has truly detected monotonic clock
+  ** availability, it might happen that it is not actually available at
+  ** run-time. When this occurs simply fallback to other time source.
+  */
+#ifdef HAVE_GETTIMEOFDAY
+  else
+    (void)gettimeofday(&now, NULL);
+#else
+  else {
+    now.tv_sec = (long)time(NULL);
+    now.tv_usec = 0;
+  }
+#endif
+  return now;
+}
+
+#elif defined(HAVE_GETTIMEOFDAY)
+
+struct timeval curlx_tvnow(void)
+{
+  /*
+  ** gettimeofday() is not granted to be increased monotonically, due to
+  ** clock drifting and external source time synchronization it can jump
+  ** forward or backward in time.
+  */
+  struct timeval now;
+  (void)gettimeofday(&now, NULL);
+  return now;
+}
+
+#else
+
+struct timeval curlx_tvnow(void)
+{
+  /*
+  ** time() returns the value of time in seconds since the Epoch.
+  */
+  struct timeval now;
+  now.tv_sec = (long)time(NULL);
+  now.tv_usec = 0;
+  return now;
+}
+
+#endif
+
+/*
+ * Make sure that the first argument is the more recent time, as otherwise
+ * we'll get a weird negative time-diff back...
+ *
+ * Returns: the time difference in number of milliseconds.
+ */
+long curlx_tvdiff(struct timeval newer, struct timeval older)
+{
+  return (newer.tv_sec-older.tv_sec)*1000+
+    (long)(newer.tv_usec-older.tv_usec)/1000;
+}
+
+/*
+ * Same as curlx_tvdiff but with full usec resolution.
+ *
+ * Returns: the time difference in seconds with subsecond resolution.
+ */
+double curlx_tvdiff_secs(struct timeval newer, struct timeval older)
+{
+  if(newer.tv_sec != older.tv_sec)
+    return (double)(newer.tv_sec-older.tv_sec)+
+      (double)(newer.tv_usec-older.tv_usec)/1000000.0;
+  else
+    return (double)(newer.tv_usec-older.tv_usec)/1000000.0;
+}
+
+/* return the number of seconds in the given input timeval struct */
+long Curl_tvlong(struct timeval t1)
+{
+  return t1.tv_sec;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/timeval.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/timeval.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/timeval.h	(revision 164)
@@ -0,0 +1,58 @@
+#ifndef HEADER_CURL_TIMEVAL_H
+#define HEADER_CURL_TIMEVAL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * CAUTION: this header is designed to work when included by the app-side
+ * as well as the library. Do not mix with library internals!
+ */
+
+#include "curl_setup.h"
+
+struct timeval curlx_tvnow(void);
+
+/*
+ * Make sure that the first argument (t1) is the more recent time and t2 is
+ * the older time, as otherwise you get a weird negative time-diff back...
+ *
+ * Returns: the time difference in number of milliseconds.
+ */
+long curlx_tvdiff(struct timeval t1, struct timeval t2);
+
+/*
+ * Same as curlx_tvdiff but with full usec resolution.
+ *
+ * Returns: the time difference in seconds with subsecond resolution.
+ */
+double curlx_tvdiff_secs(struct timeval t1, struct timeval t2);
+
+long Curl_tvlong(struct timeval t1);
+
+/* These two defines below exist to provide the older API for library
+   internals only. */
+#define Curl_tvnow() curlx_tvnow()
+#define Curl_tvdiff(x,y) curlx_tvdiff(x,y)
+#define Curl_tvdiff_secs(x,y) curlx_tvdiff_secs(x,y)
+
+#endif /* HEADER_CURL_TIMEVAL_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/transfer.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/transfer.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/transfer.c	(revision 164)
@@ -0,0 +1,2034 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "strtoofft.h"
+#include "strequal.h"
+#include "rawstr.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#ifndef HAVE_SOCKET
+#error "We can't compile without socket() support!"
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "netrc.h"
+
+#include "content_encoding.h"
+#include "hostip.h"
+#include "transfer.h"
+#include "sendf.h"
+#include "speedcheck.h"
+#include "progress.h"
+#include "http.h"
+#include "url.h"
+#include "getinfo.h"
+#include "vtls/vtls.h"
+#include "http_digest.h"
+#include "curl_ntlm.h"
+#include "http_negotiate.h"
+#include "share.h"
+#include "select.h"
+#include "multiif.h"
+#include "connect.h"
+#include "non-ascii.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * This function will call the read callback to fill our buffer with data
+ * to upload.
+ */
+CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
+{
+  struct SessionHandle *data = conn->data;
+  size_t buffersize = (size_t)bytes;
+  int nread;
+#ifdef CURL_DOES_CONVERSIONS
+  bool sending_http_headers = FALSE;
+
+  if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
+    const struct HTTP *http = data->req.protop;
+
+    if(http->sending == HTTPSEND_REQUEST)
+      /* We're sending the HTTP request headers, not the data.
+         Remember that so we don't re-translate them into garbage. */
+      sending_http_headers = TRUE;
+  }
+#endif
+
+  if(data->req.upload_chunky) {
+    /* if chunked Transfer-Encoding */
+    buffersize -= (8 + 2 + 2);   /* 32bit hex + CRLF + CRLF */
+    data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */
+  }
+
+  /* this function returns a size_t, so we typecast to int to prevent warnings
+     with picky compilers */
+  nread = (int)data->state.fread_func(data->req.upload_fromhere, 1,
+                                      buffersize, data->state.in);
+
+  if(nread == CURL_READFUNC_ABORT) {
+    failf(data, "operation aborted by callback");
+    *nreadp = 0;
+    return CURLE_ABORTED_BY_CALLBACK;
+  }
+  else if(nread == CURL_READFUNC_PAUSE) {
+
+    if(conn->handler->flags & PROTOPT_NONETWORK) {
+      /* protocols that work without network cannot be paused. This is
+         actually only FILE:// just now, and it can't pause since the transfer
+         isn't done using the "normal" procedure. */
+      failf(data, "Read callback asked for PAUSE when not supported!");
+      return CURLE_READ_ERROR;
+    }
+    else {
+      struct SingleRequest *k = &data->req;
+      /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */
+      k->keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */
+      if(data->req.upload_chunky) {
+        /* Back out the preallocation done above */
+        data->req.upload_fromhere -= (8 + 2);
+      }
+      *nreadp = 0;
+    }
+    return CURLE_OK; /* nothing was read */
+  }
+  else if((size_t)nread > buffersize) {
+    /* the read function returned a too large value */
+    *nreadp = 0;
+    failf(data, "read function returned funny value");
+    return CURLE_READ_ERROR;
+  }
+
+  if(!data->req.forbidchunk && data->req.upload_chunky) {
+    /* if chunked Transfer-Encoding
+     *    build chunk:
+     *
+     *        <HEX SIZE> CRLF
+     *        <DATA> CRLF
+     */
+    /* On non-ASCII platforms the <DATA> may or may not be
+       translated based on set.prefer_ascii while the protocol
+       portion must always be translated to the network encoding.
+       To further complicate matters, line end conversion might be
+       done later on, so we need to prevent CRLFs from becoming
+       CRCRLFs if that's the case.  To do this we use bare LFs
+       here, knowing they'll become CRLFs later on.
+     */
+
+    char hexbuffer[11];
+    const char *endofline_native;
+    const char *endofline_network;
+    int hexlen;
+
+    if(
+#ifdef CURL_DO_LINEEND_CONV
+       (data->set.prefer_ascii) ||
+#endif
+       (data->set.crlf)) {
+      /* \n will become \r\n later on */
+      endofline_native  = "\n";
+      endofline_network = "\x0a";
+    }
+    else {
+      endofline_native  = "\r\n";
+      endofline_network = "\x0d\x0a";
+    }
+    hexlen = snprintf(hexbuffer, sizeof(hexbuffer),
+                      "%x%s", nread, endofline_native);
+
+    /* move buffer pointer */
+    data->req.upload_fromhere -= hexlen;
+    nread += hexlen;
+
+    /* copy the prefix to the buffer, leaving out the NUL */
+    memcpy(data->req.upload_fromhere, hexbuffer, hexlen);
+
+    /* always append ASCII CRLF to the data */
+    memcpy(data->req.upload_fromhere + nread,
+           endofline_network,
+           strlen(endofline_network));
+
+#ifdef CURL_DOES_CONVERSIONS
+    CURLcode result;
+    int length;
+    if(data->set.prefer_ascii) {
+      /* translate the protocol and data */
+      length = nread;
+    }
+    else {
+      /* just translate the protocol portion */
+      length = strlen(hexbuffer);
+    }
+    result = Curl_convert_to_network(data, data->req.upload_fromhere, length);
+    /* Curl_convert_to_network calls failf if unsuccessful */
+    if(result)
+      return result;
+#endif /* CURL_DOES_CONVERSIONS */
+
+    if((nread - hexlen) == 0)
+      /* mark this as done once this chunk is transferred */
+      data->req.upload_done = TRUE;
+
+    nread+=(int)strlen(endofline_native); /* for the added end of line */
+  }
+#ifdef CURL_DOES_CONVERSIONS
+  else if((data->set.prefer_ascii) && (!sending_http_headers)) {
+    CURLcode result;
+    result = Curl_convert_to_network(data, data->req.upload_fromhere, nread);
+    /* Curl_convert_to_network calls failf if unsuccessful */
+    if(result)
+      return result;
+  }
+#endif /* CURL_DOES_CONVERSIONS */
+
+  *nreadp = nread;
+
+  return CURLE_OK;
+}
+
+
+/*
+ * Curl_readrewind() rewinds the read stream. This is typically used for HTTP
+ * POST/PUT with multi-pass authentication when a sending was denied and a
+ * resend is necessary.
+ */
+CURLcode Curl_readrewind(struct connectdata *conn)
+{
+  struct SessionHandle *data = conn->data;
+
+  conn->bits.rewindaftersend = FALSE; /* we rewind now */
+
+  /* explicitly switch off sending data on this connection now since we are
+     about to restart a new transfer and thus we want to avoid inadvertently
+     sending more data on the existing connection until the next transfer
+     starts */
+  data->req.keepon &= ~KEEP_SEND;
+
+  /* We have sent away data. If not using CURLOPT_POSTFIELDS or
+     CURLOPT_HTTPPOST, call app to rewind
+  */
+  if(data->set.postfields ||
+     (data->set.httpreq == HTTPREQ_POST_FORM))
+    ; /* do nothing */
+  else {
+    if(data->set.seek_func) {
+      int err;
+
+      err = (data->set.seek_func)(data->set.seek_client, 0, SEEK_SET);
+      if(err) {
+        failf(data, "seek callback returned error %d", (int)err);
+        return CURLE_SEND_FAIL_REWIND;
+      }
+    }
+    else if(data->set.ioctl_func) {
+      curlioerr err;
+
+      err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD,
+                                   data->set.ioctl_client);
+      infof(data, "the ioctl callback returned %d\n", (int)err);
+
+      if(err) {
+        /* FIXME: convert to a human readable error message */
+        failf(data, "ioctl callback returned error %d", (int)err);
+        return CURLE_SEND_FAIL_REWIND;
+      }
+    }
+    else {
+      /* If no CURLOPT_READFUNCTION is used, we know that we operate on a
+         given FILE * stream and we can actually attempt to rewind that
+         ourselves with fseek() */
+      if(data->state.fread_func == (curl_read_callback)fread) {
+        if(-1 != fseek(data->state.in, 0, SEEK_SET))
+          /* successful rewind */
+          return CURLE_OK;
+      }
+
+      /* no callback set or failure above, makes us fail at once */
+      failf(data, "necessary data rewind wasn't possible");
+      return CURLE_SEND_FAIL_REWIND;
+    }
+  }
+  return CURLE_OK;
+}
+
+static int data_pending(const struct connectdata *conn)
+{
+  /* in the case of libssh2, we can never be really sure that we have emptied
+     its internal buffers so we MUST always try until we get EAGAIN back */
+  return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) ||
+#if defined(USE_NGHTTP2)
+    Curl_ssl_data_pending(conn, FIRSTSOCKET) ||
+    /* For HTTP/2, we may read up everything including responde body
+       with header fields in Curl_http_readwrite_headers. If no
+       content-length is provided, curl waits for the connection
+       close, which we emulate it using conn->proto.httpc.closed =
+       TRUE. The thing is if we read everything, then http2_recv won't
+       be called and we cannot signal the HTTP/2 stream has closed. As
+       a workaround, we return nonzero here to call http2_recv. */
+    ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion == 20);
+#else
+    Curl_ssl_data_pending(conn, FIRSTSOCKET);
+#endif
+}
+
+static void read_rewind(struct connectdata *conn,
+                        size_t thismuch)
+{
+  DEBUGASSERT(conn->read_pos >= thismuch);
+
+  conn->read_pos -= thismuch;
+  conn->bits.stream_was_rewound = TRUE;
+
+#ifdef DEBUGBUILD
+  {
+    char buf[512 + 1];
+    size_t show;
+
+    show = CURLMIN(conn->buf_len - conn->read_pos, sizeof(buf)-1);
+    if(conn->master_buffer) {
+      memcpy(buf, conn->master_buffer + conn->read_pos, show);
+      buf[show] = '\0';
+    }
+    else {
+      buf[0] = '\0';
+    }
+
+    DEBUGF(infof(conn->data,
+                 "Buffer after stream rewind (read_pos = %zu): [%s]\n",
+                 conn->read_pos, buf));
+  }
+#endif
+}
+
+/*
+ * Check to see if CURLOPT_TIMECONDITION was met by comparing the time of the
+ * remote document with the time provided by CURLOPT_TIMEVAL
+ */
+bool Curl_meets_timecondition(struct SessionHandle *data, time_t timeofdoc)
+{
+  if((timeofdoc == 0) || (data->set.timevalue == 0))
+    return TRUE;
+
+  switch(data->set.timecondition) {
+  case CURL_TIMECOND_IFMODSINCE:
+  default:
+    if(timeofdoc <= data->set.timevalue) {
+      infof(data,
+            "The requested document is not new enough\n");
+      data->info.timecond = TRUE;
+      return FALSE;
+    }
+    break;
+  case CURL_TIMECOND_IFUNMODSINCE:
+    if(timeofdoc >= data->set.timevalue) {
+      infof(data,
+            "The requested document is not old enough\n");
+      data->info.timecond = TRUE;
+      return FALSE;
+    }
+    break;
+  }
+
+  return TRUE;
+}
+
+/*
+ * Go ahead and do a read if we have a readable socket or if
+ * the stream was rewound (in which case we have data in a
+ * buffer)
+ */
+static CURLcode readwrite_data(struct SessionHandle *data,
+                               struct connectdata *conn,
+                               struct SingleRequest *k,
+                               int *didwhat, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  ssize_t nread; /* number of bytes read */
+  size_t excess = 0; /* excess bytes read */
+  bool is_empty_data = FALSE;
+  bool readmore = FALSE; /* used by RTP to signal for more data */
+  int maxloops = 100;
+
+  *done = FALSE;
+
+  /* This is where we loop until we have read everything there is to
+     read or we get a CURLE_AGAIN */
+  do {
+    size_t buffersize = data->set.buffer_size?
+      data->set.buffer_size : BUFSIZE;
+    size_t bytestoread = buffersize;
+
+    if(
+#if defined(USE_NGHTTP2)
+       /* For HTTP/2, read data without caring about the content
+          length. This is safe because body in HTTP/2 is always
+          segmented thanks to its framing layer. Meanwhile, we have to
+          call Curl_read to ensure that http2_handle_stream_close is
+          called when we read all incoming bytes for a particular
+          stream. */
+       !((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
+         conn->httpversion == 20) &&
+#endif
+       k->size != -1 && !k->header) {
+      /* make sure we don't read "too much" if we can help it since we
+         might be pipelining and then someone else might want to read what
+         follows! */
+      curl_off_t totalleft = k->size - k->bytecount;
+      if(totalleft < (curl_off_t)bytestoread)
+        bytestoread = (size_t)totalleft;
+    }
+
+    if(bytestoread) {
+      /* receive data from the network! */
+      result = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread);
+
+      /* read would've blocked */
+      if(CURLE_AGAIN == result)
+        break; /* get out of loop */
+
+      if(result>0)
+        return result;
+    }
+    else {
+      /* read nothing but since we wanted nothing we consider this an OK
+         situation to proceed from */
+      DEBUGF(infof(data, "readwrite_data: we're done!\n"));
+      nread = 0;
+    }
+
+    if((k->bytecount == 0) && (k->writebytecount == 0)) {
+      Curl_pgrsTime(data, TIMER_STARTTRANSFER);
+      if(k->exp100 > EXP100_SEND_DATA)
+        /* set time stamp to compare with when waiting for the 100 */
+        k->start100 = Curl_tvnow();
+    }
+
+    *didwhat |= KEEP_RECV;
+    /* indicates data of zero size, i.e. empty file */
+    is_empty_data = ((nread == 0) && (k->bodywrites == 0)) ? TRUE : FALSE;
+
+    /* NUL terminate, allowing string ops to be used */
+    if(0 < nread || is_empty_data) {
+      k->buf[nread] = 0;
+    }
+    else if(0 >= nread) {
+      /* if we receive 0 or less here, the server closed the connection
+         and we bail out from this! */
+      DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n"));
+      k->keepon &= ~KEEP_RECV;
+      break;
+    }
+
+    /* Default buffer to use when we write the buffer, it may be changed
+       in the flow below before the actual storing is done. */
+    k->str = k->buf;
+
+    if(conn->handler->readwrite) {
+      result = conn->handler->readwrite(data, conn, &nread, &readmore);
+      if(result)
+        return result;
+      if(readmore)
+        break;
+    }
+
+#ifndef CURL_DISABLE_HTTP
+    /* Since this is a two-state thing, we check if we are parsing
+       headers at the moment or not. */
+    if(k->header) {
+      /* we are in parse-the-header-mode */
+      bool stop_reading = FALSE;
+      result = Curl_http_readwrite_headers(data, conn, &nread, &stop_reading);
+      if(result)
+        return result;
+
+      if(conn->handler->readwrite &&
+         (k->maxdownload <= 0 && nread > 0)) {
+        result = conn->handler->readwrite(data, conn, &nread, &readmore);
+        if(result)
+          return result;
+        if(readmore)
+          break;
+      }
+
+      if(stop_reading) {
+        /* We've stopped dealing with input, get out of the do-while loop */
+
+        if(nread > 0) {
+          if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
+            infof(data,
+                  "Rewinding stream by : %zd"
+                  " bytes on url %s (zero-length body)\n",
+                  nread, data->state.path);
+            read_rewind(conn, (size_t)nread);
+          }
+          else {
+            infof(data,
+                  "Excess found in a non pipelined read:"
+                  " excess = %zd"
+                  " url = %s (zero-length body)\n",
+                  nread, data->state.path);
+          }
+        }
+
+        break;
+      }
+    }
+#endif /* CURL_DISABLE_HTTP */
+
+
+    /* This is not an 'else if' since it may be a rest from the header
+       parsing, where the beginning of the buffer is headers and the end
+       is non-headers. */
+    if(k->str && !k->header && (nread > 0 || is_empty_data)) {
+
+#ifndef CURL_DISABLE_HTTP
+      if(0 == k->bodywrites && !is_empty_data) {
+        /* These checks are only made the first time we are about to
+           write a piece of the body */
+        if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
+          /* HTTP-only checks */
+
+          if(data->req.newurl) {
+            if(conn->bits.close) {
+              /* Abort after the headers if "follow Location" is set
+                 and we're set to close anyway. */
+              k->keepon &= ~KEEP_RECV;
+              *done = TRUE;
+              return CURLE_OK;
+            }
+            /* We have a new url to load, but since we want to be able
+               to re-use this connection properly, we read the full
+               response in "ignore more" */
+            k->ignorebody = TRUE;
+            infof(data, "Ignoring the response-body\n");
+          }
+          if(data->state.resume_from && !k->content_range &&
+             (data->set.httpreq==HTTPREQ_GET) &&
+             !k->ignorebody) {
+
+            if(k->size == data->state.resume_from) {
+              /* The resume point is at the end of file, consider this fine
+                 even if it doesn't allow resume from here. */
+              infof(data, "The entire document is already downloaded");
+              connclose(conn, "already downloaded");
+              /* Abort download */
+              k->keepon &= ~KEEP_RECV;
+              *done = TRUE;
+              return CURLE_OK;
+            }
+
+            /* we wanted to resume a download, although the server doesn't
+             * seem to support this and we did this with a GET (if it
+             * wasn't a GET we did a POST or PUT resume) */
+            failf(data, "HTTP server doesn't seem to support "
+                  "byte ranges. Cannot resume.");
+            return CURLE_RANGE_ERROR;
+          }
+
+          if(data->set.timecondition && !data->state.range) {
+            /* A time condition has been set AND no ranges have been
+               requested. This seems to be what chapter 13.3.4 of
+               RFC 2616 defines to be the correct action for a
+               HTTP/1.1 client */
+
+            if(!Curl_meets_timecondition(data, k->timeofdoc)) {
+              *done = TRUE;
+              /* We're simulating a http 304 from server so we return
+                 what should have been returned from the server */
+              data->info.httpcode = 304;
+              infof(data, "Simulate a HTTP 304 response!\n");
+              /* we abort the transfer before it is completed == we ruin the
+                 re-use ability. Close the connection */
+              connclose(conn, "Simulated 304 handling");
+              return CURLE_OK;
+            }
+          } /* we have a time condition */
+
+        } /* this is HTTP or RTSP */
+      } /* this is the first time we write a body part */
+#endif /* CURL_DISABLE_HTTP */
+
+      k->bodywrites++;
+
+      /* pass data to the debug function before it gets "dechunked" */
+      if(data->set.verbose) {
+        if(k->badheader) {
+          Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
+                     (size_t)k->hbuflen, conn);
+          if(k->badheader == HEADER_PARTHEADER)
+            Curl_debug(data, CURLINFO_DATA_IN,
+                       k->str, (size_t)nread, conn);
+        }
+        else
+          Curl_debug(data, CURLINFO_DATA_IN,
+                     k->str, (size_t)nread, conn);
+      }
+
+#ifndef CURL_DISABLE_HTTP
+      if(k->chunk) {
+        /*
+         * Here comes a chunked transfer flying and we need to decode this
+         * properly.  While the name says read, this function both reads
+         * and writes away the data. The returned 'nread' holds the number
+         * of actual data it wrote to the client.
+         */
+
+        CHUNKcode res =
+          Curl_httpchunk_read(conn, k->str, nread, &nread);
+
+        if(CHUNKE_OK < res) {
+          if(CHUNKE_WRITE_ERROR == res) {
+            failf(data, "Failed writing data");
+            return CURLE_WRITE_ERROR;
+          }
+          failf(data, "%s in chunked-encoding", Curl_chunked_strerror(res));
+          return CURLE_RECV_ERROR;
+        }
+        else if(CHUNKE_STOP == res) {
+          size_t dataleft;
+          /* we're done reading chunks! */
+          k->keepon &= ~KEEP_RECV; /* read no more */
+
+          /* There are now possibly N number of bytes at the end of the
+             str buffer that weren't written to the client.
+
+             We DO care about this data if we are pipelining.
+             Push it back to be read on the next pass. */
+
+          dataleft = conn->chunk.dataleft;
+          if(dataleft != 0) {
+            infof(conn->data, "Leftovers after chunking: %zu bytes\n",
+                  dataleft);
+            if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
+              /* only attempt the rewind if we truly are pipelining */
+              infof(conn->data, "Rewinding %zu bytes\n",dataleft);
+              read_rewind(conn, dataleft);
+            }
+          }
+        }
+        /* If it returned OK, we just keep going */
+      }
+#endif   /* CURL_DISABLE_HTTP */
+
+      /* Account for body content stored in the header buffer */
+      if(k->badheader && !k->ignorebody) {
+        DEBUGF(infof(data, "Increasing bytecount by %zu from hbuflen\n",
+                     k->hbuflen));
+        k->bytecount += k->hbuflen;
+      }
+
+      if((-1 != k->maxdownload) &&
+         (k->bytecount + nread >= k->maxdownload)) {
+
+        excess = (size_t)(k->bytecount + nread - k->maxdownload);
+        if(excess > 0 && !k->ignorebody) {
+          if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
+            /* The 'excess' amount below can't be more than BUFSIZE which
+               always will fit in a size_t */
+            infof(data,
+                  "Rewinding stream by : %zu"
+                  " bytes on url %s (size = %" CURL_FORMAT_CURL_OFF_T
+                  ", maxdownload = %" CURL_FORMAT_CURL_OFF_T
+                  ", bytecount = %" CURL_FORMAT_CURL_OFF_T ", nread = %zd)\n",
+                  excess, data->state.path,
+                  k->size, k->maxdownload, k->bytecount, nread);
+            read_rewind(conn, excess);
+          }
+          else {
+            infof(data,
+                  "Excess found in a non pipelined read:"
+                  " excess = %zu"
+                  ", size = %" CURL_FORMAT_CURL_OFF_T
+                  ", maxdownload = %" CURL_FORMAT_CURL_OFF_T
+                  ", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n",
+                  excess, k->size, k->maxdownload, k->bytecount);
+          }
+        }
+
+        nread = (ssize_t) (k->maxdownload - k->bytecount);
+        if(nread < 0 ) /* this should be unusual */
+          nread = 0;
+
+        k->keepon &= ~KEEP_RECV; /* we're done reading */
+      }
+
+      k->bytecount += nread;
+
+      Curl_pgrsSetDownloadCounter(data, k->bytecount);
+
+      if(!k->chunk && (nread || k->badheader || is_empty_data)) {
+        /* If this is chunky transfer, it was already written */
+
+        if(k->badheader && !k->ignorebody) {
+          /* we parsed a piece of data wrongly assuming it was a header
+             and now we output it as body instead */
+
+          /* Don't let excess data pollute body writes */
+          if(k->maxdownload == -1 || (curl_off_t)k->hbuflen <= k->maxdownload)
+            result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                       data->state.headerbuff,
+                                       k->hbuflen);
+          else
+            result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                       data->state.headerbuff,
+                                       (size_t)k->maxdownload);
+
+          if(result)
+            return result;
+        }
+        if(k->badheader < HEADER_ALLBAD) {
+          /* This switch handles various content encodings. If there's an
+             error here, be sure to check over the almost identical code
+             in http_chunks.c.
+             Make sure that ALL_CONTENT_ENCODINGS contains all the
+             encodings handled here. */
+#ifdef HAVE_LIBZ
+          switch (conn->data->set.http_ce_skip ?
+                  IDENTITY : k->auto_decoding) {
+          case IDENTITY:
+#endif
+            /* This is the default when the server sends no
+               Content-Encoding header. See Curl_readwrite_init; the
+               memset() call initializes k->auto_decoding to zero. */
+            if(!k->ignorebody) {
+
+#ifndef CURL_DISABLE_POP3
+              if(conn->handler->protocol&PROTO_FAMILY_POP3)
+                result = Curl_pop3_write(conn, k->str, nread);
+              else
+#endif /* CURL_DISABLE_POP3 */
+
+                result = Curl_client_write(conn, CLIENTWRITE_BODY, k->str,
+                                           nread);
+            }
+#ifdef HAVE_LIBZ
+            break;
+
+          case DEFLATE:
+            /* Assume CLIENTWRITE_BODY; headers are not encoded. */
+            if(!k->ignorebody)
+              result = Curl_unencode_deflate_write(conn, k, nread);
+            break;
+
+          case GZIP:
+            /* Assume CLIENTWRITE_BODY; headers are not encoded. */
+            if(!k->ignorebody)
+              result = Curl_unencode_gzip_write(conn, k, nread);
+            break;
+
+          default:
+            failf (data, "Unrecognized content encoding type. "
+                   "libcurl understands `identity', `deflate' and `gzip' "
+                   "content encodings.");
+            result = CURLE_BAD_CONTENT_ENCODING;
+            break;
+          }
+#endif
+        }
+        k->badheader = HEADER_NORMAL; /* taken care of now */
+
+        if(result)
+          return result;
+      }
+
+    } /* if(! header and data to read ) */
+
+    if(conn->handler->readwrite &&
+       (excess > 0 && !conn->bits.stream_was_rewound)) {
+      /* Parse the excess data */
+      k->str += nread;
+      nread = (ssize_t)excess;
+
+      result = conn->handler->readwrite(data, conn, &nread, &readmore);
+      if(result)
+        return result;
+
+      if(readmore)
+        k->keepon |= KEEP_RECV; /* we're not done reading */
+      break;
+    }
+
+    if(is_empty_data) {
+      /* if we received nothing, the server closed the connection and we
+         are done */
+      k->keepon &= ~KEEP_RECV;
+    }
+
+  } while(data_pending(conn) && maxloops--);
+
+  if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) &&
+     conn->bits.close ) {
+    /* When we've read the entire thing and the close bit is set, the server
+       may now close the connection. If there's now any kind of sending going
+       on from our side, we need to stop that immediately. */
+    infof(data, "we are done reading and this is set to close, stop send\n");
+    k->keepon &= ~KEEP_SEND; /* no writing anymore either */
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Send data to upload to the server, when the socket is writable.
+ */
+static CURLcode readwrite_upload(struct SessionHandle *data,
+                                 struct connectdata *conn,
+                                 struct SingleRequest *k,
+                                 int *didwhat)
+{
+  ssize_t i, si;
+  ssize_t bytes_written;
+  CURLcode result;
+  ssize_t nread; /* number of bytes read */
+  bool sending_http_headers = FALSE;
+
+  if((k->bytecount == 0) && (k->writebytecount == 0))
+    Curl_pgrsTime(data, TIMER_STARTTRANSFER);
+
+  *didwhat |= KEEP_SEND;
+
+  do {
+
+    /* only read more data if there's no upload data already
+       present in the upload buffer */
+    if(0 == data->req.upload_present) {
+      /* init the "upload from here" pointer */
+      data->req.upload_fromhere = k->uploadbuf;
+
+      if(!k->upload_done) {
+        /* HTTP pollution, this should be written nicer to become more
+           protocol agnostic. */
+        int fillcount;
+        struct HTTP *http = data->req.protop;
+
+        if((k->exp100 == EXP100_SENDING_REQUEST) &&
+           (http->sending == HTTPSEND_BODY)) {
+          /* If this call is to send body data, we must take some action:
+             We have sent off the full HTTP 1.1 request, and we shall now
+             go into the Expect: 100 state and await such a header */
+          k->exp100 = EXP100_AWAITING_CONTINUE; /* wait for the header */
+          k->keepon &= ~KEEP_SEND;         /* disable writing */
+          k->start100 = Curl_tvnow();       /* timeout count starts now */
+          *didwhat &= ~KEEP_SEND;  /* we didn't write anything actually */
+
+          /* set a timeout for the multi interface */
+          Curl_expire(data, data->set.expect_100_timeout);
+          break;
+        }
+
+        if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
+          if(http->sending == HTTPSEND_REQUEST)
+            /* We're sending the HTTP request headers, not the data.
+               Remember that so we don't change the line endings. */
+            sending_http_headers = TRUE;
+          else
+            sending_http_headers = FALSE;
+        }
+
+        result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount);
+        if(result)
+          return result;
+
+        nread = (ssize_t)fillcount;
+      }
+      else
+        nread = 0; /* we're done uploading/reading */
+
+      if(!nread && (k->keepon & KEEP_SEND_PAUSE)) {
+        /* this is a paused transfer */
+        break;
+      }
+      else if(nread<=0) {
+        /* done */
+        k->keepon &= ~KEEP_SEND; /* we're done writing */
+
+        if(conn->bits.rewindaftersend) {
+          result = Curl_readrewind(conn);
+          if(result)
+            return result;
+        }
+        break;
+      }
+
+      /* store number of bytes available for upload */
+      data->req.upload_present = nread;
+
+      /* convert LF to CRLF if so asked */
+      if((!sending_http_headers) && (
+#ifdef CURL_DO_LINEEND_CONV
+         /* always convert if we're FTPing in ASCII mode */
+         (data->set.prefer_ascii) ||
+#endif
+         (data->set.crlf))) {
+        /* Do we need to allocate a scratch buffer? */
+        if(!data->state.scratch) {
+          data->state.scratch = malloc(2 * BUFSIZE);
+          if(!data->state.scratch) {
+            failf(data, "Failed to alloc scratch buffer!");
+
+            return CURLE_OUT_OF_MEMORY;
+          }
+        }
+
+        /*
+         * ASCII/EBCDIC Note: This is presumably a text (not binary)
+         * transfer so the data should already be in ASCII.
+         * That means the hex values for ASCII CR (0x0d) & LF (0x0a)
+         * must be used instead of the escape sequences \r & \n.
+         */
+        for(i = 0, si = 0; i < nread; i++, si++) {
+          if(data->req.upload_fromhere[i] == 0x0a) {
+            data->state.scratch[si++] = 0x0d;
+            data->state.scratch[si] = 0x0a;
+            if(!data->set.crlf) {
+              /* we're here only because FTP is in ASCII mode...
+                 bump infilesize for the LF we just added */
+              if(data->state.infilesize != -1)
+                data->state.infilesize++;
+            }
+          }
+          else
+            data->state.scratch[si] = data->req.upload_fromhere[i];
+        }
+
+        if(si != nread) {
+          /* only perform the special operation if we really did replace
+             anything */
+          nread = si;
+
+          /* upload from the new (replaced) buffer instead */
+          data->req.upload_fromhere = data->state.scratch;
+
+          /* set the new amount too */
+          data->req.upload_present = nread;
+        }
+      }
+
+#ifndef CURL_DISABLE_SMTP
+      if(conn->handler->protocol & PROTO_FAMILY_SMTP) {
+        result = Curl_smtp_escape_eob(conn, nread);
+        if(result)
+          return result;
+      }
+#endif /* CURL_DISABLE_SMTP */
+    } /* if 0 == data->req.upload_present */
+    else {
+      /* We have a partial buffer left from a previous "round". Use
+         that instead of reading more data */
+    }
+
+    /* write to socket (send away data) */
+    result = Curl_write(conn,
+                        conn->writesockfd,     /* socket to send to */
+                        data->req.upload_fromhere, /* buffer pointer */
+                        data->req.upload_present,  /* buffer size */
+                        &bytes_written);           /* actually sent */
+
+    if(result)
+      return result;
+
+    if(data->set.verbose)
+      /* show the data before we change the pointer upload_fromhere */
+      Curl_debug(data, CURLINFO_DATA_OUT, data->req.upload_fromhere,
+                 (size_t)bytes_written, conn);
+
+    k->writebytecount += bytes_written;
+
+    if(k->writebytecount == data->state.infilesize) {
+      /* we have sent all data we were supposed to */
+      k->upload_done = TRUE;
+      infof(data, "We are completely uploaded and fine\n");
+    }
+
+    if(data->req.upload_present != bytes_written) {
+      /* we only wrote a part of the buffer (if anything), deal with it! */
+
+      /* store the amount of bytes left in the buffer to write */
+      data->req.upload_present -= bytes_written;
+
+      /* advance the pointer where to find the buffer when the next send
+         is to happen */
+      data->req.upload_fromhere += bytes_written;
+    }
+    else {
+      /* we've uploaded that buffer now */
+      data->req.upload_fromhere = k->uploadbuf;
+      data->req.upload_present = 0; /* no more bytes left */
+
+      if(k->upload_done) {
+        /* switch off writing, we're done! */
+        k->keepon &= ~KEEP_SEND; /* we're done writing */
+      }
+    }
+
+    Curl_pgrsSetUploadCounter(data, k->writebytecount);
+
+  } WHILE_FALSE; /* just to break out from! */
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_readwrite() is the low-level function to be called when data is to
+ * be read and written to/from the connection.
+ */
+CURLcode Curl_readwrite(struct connectdata *conn,
+                        struct SessionHandle *data,
+                        bool *done)
+{
+  struct SingleRequest *k = &data->req;
+  CURLcode result;
+  int didwhat=0;
+
+  curl_socket_t fd_read;
+  curl_socket_t fd_write;
+  int select_res = conn->cselect_bits;
+
+  conn->cselect_bits = 0;
+
+  /* only use the proper socket if the *_HOLD bit is not set simultaneously as
+     then we are in rate limiting state in that transfer direction */
+
+  if((k->keepon & KEEP_RECVBITS) == KEEP_RECV)
+    fd_read = conn->sockfd;
+  else
+    fd_read = CURL_SOCKET_BAD;
+
+  if((k->keepon & KEEP_SENDBITS) == KEEP_SEND)
+    fd_write = conn->writesockfd;
+  else
+    fd_write = CURL_SOCKET_BAD;
+
+  if(conn->data->state.drain) {
+    select_res |= CURL_CSELECT_IN;
+    DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data\n"));
+  }
+
+  if(!select_res) /* Call for select()/poll() only, if read/write/error
+                     status is not known. */
+    select_res = Curl_socket_ready(fd_read, fd_write, 0);
+
+  if(select_res == CURL_CSELECT_ERR) {
+    failf(data, "select/poll returned error");
+    return CURLE_SEND_ERROR;
+  }
+
+  /* We go ahead and do a read if we have a readable socket or if
+     the stream was rewound (in which case we have data in a
+     buffer) */
+  if((k->keepon & KEEP_RECV) &&
+     ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) {
+
+    result = readwrite_data(data, conn, k, &didwhat, done);
+    if(result || *done)
+      return result;
+  }
+
+  /* If we still have writing to do, we check if we have a writable socket. */
+  if((k->keepon & KEEP_SEND) && (select_res & CURL_CSELECT_OUT)) {
+    /* write */
+
+    result = readwrite_upload(data, conn, k, &didwhat);
+    if(result)
+      return result;
+  }
+
+  k->now = Curl_tvnow();
+  if(didwhat) {
+    /* Update read/write counters */
+    if(k->bytecountp)
+      *k->bytecountp = k->bytecount; /* read count */
+    if(k->writebytecountp)
+      *k->writebytecountp = k->writebytecount; /* write count */
+  }
+  else {
+    /* no read no write, this is a timeout? */
+    if(k->exp100 == EXP100_AWAITING_CONTINUE) {
+      /* This should allow some time for the header to arrive, but only a
+         very short time as otherwise it'll be too much wasted time too
+         often. */
+
+      /* Quoting RFC2616, section "8.2.3 Use of the 100 (Continue) Status":
+
+         Therefore, when a client sends this header field to an origin server
+         (possibly via a proxy) from which it has never seen a 100 (Continue)
+         status, the client SHOULD NOT wait for an indefinite period before
+         sending the request body.
+
+      */
+
+      long ms = Curl_tvdiff(k->now, k->start100);
+      if(ms >= data->set.expect_100_timeout) {
+        /* we've waited long enough, continue anyway */
+        k->exp100 = EXP100_SEND_DATA;
+        k->keepon |= KEEP_SEND;
+        infof(data, "Done waiting for 100-continue\n");
+      }
+    }
+  }
+
+  if(Curl_pgrsUpdate(conn))
+    result = CURLE_ABORTED_BY_CALLBACK;
+  else
+    result = Curl_speedcheck(data, k->now);
+  if(result)
+    return result;
+
+  if(k->keepon) {
+    if(0 > Curl_timeleft(data, &k->now, FALSE)) {
+      if(k->size != -1) {
+        failf(data, "Operation timed out after %ld milliseconds with %"
+              CURL_FORMAT_CURL_OFF_T " out of %"
+              CURL_FORMAT_CURL_OFF_T " bytes received",
+              Curl_tvdiff(k->now, data->progress.t_startsingle), k->bytecount,
+              k->size);
+      }
+      else {
+        failf(data, "Operation timed out after %ld milliseconds with %"
+              CURL_FORMAT_CURL_OFF_T " bytes received",
+              Curl_tvdiff(k->now, data->progress.t_startsingle), k->bytecount);
+      }
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+  }
+  else {
+    /*
+     * The transfer has been performed. Just make some general checks before
+     * returning.
+     */
+
+    if(!(data->set.opt_no_body) && (k->size != -1) &&
+       (k->bytecount != k->size) &&
+#ifdef CURL_DO_LINEEND_CONV
+       /* Most FTP servers don't adjust their file SIZE response for CRLFs,
+          so we'll check to see if the discrepancy can be explained
+          by the number of CRLFs we've changed to LFs.
+       */
+       (k->bytecount != (k->size + data->state.crlf_conversions)) &&
+#endif /* CURL_DO_LINEEND_CONV */
+       !data->req.newurl) {
+      failf(data, "transfer closed with %" CURL_FORMAT_CURL_OFF_T
+            " bytes remaining to read",
+            k->size - k->bytecount);
+      return CURLE_PARTIAL_FILE;
+    }
+    else if(!(data->set.opt_no_body) &&
+            k->chunk &&
+            (conn->chunk.state != CHUNK_STOP)) {
+      /*
+       * In chunked mode, return an error if the connection is closed prior to
+       * the empty (terminating) chunk is read.
+       *
+       * The condition above used to check for
+       * conn->proto.http->chunk.datasize != 0 which is true after reading
+       * *any* chunk, not just the empty chunk.
+       *
+       */
+      failf(data, "transfer closed with outstanding read data remaining");
+      return CURLE_PARTIAL_FILE;
+    }
+    if(Curl_pgrsUpdate(conn))
+      return CURLE_ABORTED_BY_CALLBACK;
+  }
+
+  /* Now update the "done" boolean we return */
+  *done = (0 == (k->keepon&(KEEP_RECV|KEEP_SEND|
+                            KEEP_RECV_PAUSE|KEEP_SEND_PAUSE))) ? TRUE : FALSE;
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_single_getsock() gets called by the multi interface code when the app
+ * has requested to get the sockets for the current connection. This function
+ * will then be called once for every connection that the multi interface
+ * keeps track of. This function will only be called for connections that are
+ * in the proper state to have this information available.
+ */
+int Curl_single_getsock(const struct connectdata *conn,
+                        curl_socket_t *sock, /* points to numsocks number
+                                                of sockets */
+                        int numsocks)
+{
+  const struct SessionHandle *data = conn->data;
+  int bitmap = GETSOCK_BLANK;
+  unsigned sockindex = 0;
+
+  if(conn->handler->perform_getsock)
+    return conn->handler->perform_getsock(conn, sock, numsocks);
+
+  if(numsocks < 2)
+    /* simple check but we might need two slots */
+    return GETSOCK_BLANK;
+
+  /* don't include HOLD and PAUSE connections */
+  if((data->req.keepon & KEEP_RECVBITS) == KEEP_RECV) {
+
+    DEBUGASSERT(conn->sockfd != CURL_SOCKET_BAD);
+
+    bitmap |= GETSOCK_READSOCK(sockindex);
+    sock[sockindex] = conn->sockfd;
+  }
+
+  /* don't include HOLD and PAUSE connections */
+  if((data->req.keepon & KEEP_SENDBITS) == KEEP_SEND) {
+
+    if((conn->sockfd != conn->writesockfd) ||
+       bitmap == GETSOCK_BLANK) {
+      /* only if they are not the same socket and we have a readable
+         one, we increase index */
+      if(bitmap != GETSOCK_BLANK)
+        sockindex++; /* increase index if we need two entries */
+
+      DEBUGASSERT(conn->writesockfd != CURL_SOCKET_BAD);
+
+      sock[sockindex] = conn->writesockfd;
+    }
+
+    bitmap |= GETSOCK_WRITESOCK(sockindex);
+  }
+
+  return bitmap;
+}
+
+/*
+ * Determine optimum sleep time based on configured rate, current rate,
+ * and packet size.
+ * Returns value in milliseconds.
+ *
+ * The basic idea is to adjust the desired rate up/down in this method
+ * based on whether we are running too slow or too fast.  Then, calculate
+ * how many milliseconds to wait for the next packet to achieve this new
+ * rate.
+ */
+long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps,
+                             int pkt_size)
+{
+  curl_off_t min_sleep = 0;
+  curl_off_t rv = 0;
+
+  if(rate_bps == 0)
+    return 0;
+
+  /* If running faster than about .1% of the desired speed, slow
+   * us down a bit.  Use shift instead of division as the 0.1%
+   * cutoff is arbitrary anyway.
+   */
+  if(cur_rate_bps > (rate_bps + (rate_bps >> 10))) {
+    /* running too fast, decrease target rate by 1/64th of rate */
+    rate_bps -= rate_bps >> 6;
+    min_sleep = 1;
+  }
+  else if(cur_rate_bps < (rate_bps - (rate_bps >> 10))) {
+    /* running too slow, increase target rate by 1/64th of rate */
+    rate_bps += rate_bps >> 6;
+  }
+
+  /* Determine number of milliseconds to wait until we do
+   * the next packet at the adjusted rate.  We should wait
+   * longer when using larger packets, for instance.
+   */
+  rv = ((curl_off_t)(pkt_size * 1000) / rate_bps);
+
+  /* Catch rounding errors and always slow down at least 1ms if
+   * we are running too fast.
+   */
+  if(rv < min_sleep)
+    rv = min_sleep;
+
+  /* Bound value to fit in 'long' on 32-bit platform.  That's
+   * plenty long enough anyway!
+   */
+  if(rv > 0x7fffffff)
+    rv = 0x7fffffff;
+
+  return (long)rv;
+}
+
+/* Curl_init_CONNECT() gets called each time the handle switches to CONNECT
+   which means this gets called once for each subsequent redirect etc */
+void Curl_init_CONNECT(struct SessionHandle *data)
+{
+  data->state.fread_func = data->set.fread_func_set;
+  data->state.in = data->set.in_set;
+}
+
+/*
+ * Curl_pretransfer() is called immediately before a transfer starts, and only
+ * once for one transfer no matter if it has redirects or do multi-pass
+ * authentication etc.
+ */
+CURLcode Curl_pretransfer(struct SessionHandle *data)
+{
+  CURLcode result;
+  if(!data->change.url) {
+    /* we can't do anything without URL */
+    failf(data, "No URL set!");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /* Init the SSL session ID cache here. We do it here since we want to do it
+     after the *_setopt() calls (that could specify the size of the cache) but
+     before any transfer takes place. */
+  result = Curl_ssl_initsessions(data, data->set.ssl.max_ssl_sessions);
+  if(result)
+    return result;
+
+  data->set.followlocation=0; /* reset the location-follow counter */
+  data->state.this_is_a_follow = FALSE; /* reset this */
+  data->state.errorbuf = FALSE; /* no error has occurred */
+  data->state.httpversion = 0; /* don't assume any particular server version */
+
+  data->state.authproblem = FALSE;
+  data->state.authhost.want = data->set.httpauth;
+  data->state.authproxy.want = data->set.proxyauth;
+  Curl_safefree(data->info.wouldredirect);
+  data->info.wouldredirect = NULL;
+
+  if(data->set.httpreq == HTTPREQ_PUT)
+    data->state.infilesize = data->set.filesize;
+  else
+    data->state.infilesize = data->set.postfieldsize;
+
+  /* If there is a list of cookie files to read, do it now! */
+  if(data->change.cookielist)
+    Curl_cookie_loadfiles(data);
+
+  /* If there is a list of host pairs to deal with */
+  if(data->change.resolve)
+    result = Curl_loadhostpairs(data);
+
+  if(!result) {
+    /* Allow data->set.use_port to set which port to use. This needs to be
+     * disabled for example when we follow Location: headers to URLs using
+     * different ports! */
+    data->state.allow_port = TRUE;
+
+#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
+    /*************************************************************
+     * Tell signal handler to ignore SIGPIPE
+     *************************************************************/
+    if(!data->set.no_signal)
+      data->state.prev_signal = signal(SIGPIPE, SIG_IGN);
+#endif
+
+    Curl_initinfo(data); /* reset session-specific information "variables" */
+    Curl_pgrsResetTimesSizes(data);
+    Curl_pgrsStartNow(data);
+
+    if(data->set.timeout)
+      Curl_expire(data, data->set.timeout);
+
+    if(data->set.connecttimeout)
+      Curl_expire(data, data->set.connecttimeout);
+
+    /* In case the handle is re-used and an authentication method was picked
+       in the session we need to make sure we only use the one(s) we now
+       consider to be fine */
+    data->state.authhost.picked &= data->state.authhost.want;
+    data->state.authproxy.picked &= data->state.authproxy.want;
+  }
+
+  return result;
+}
+
+/*
+ * Curl_posttransfer() is called immediately after a transfer ends
+ */
+CURLcode Curl_posttransfer(struct SessionHandle *data)
+{
+#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
+  /* restore the signal handler for SIGPIPE before we get back */
+  if(!data->set.no_signal)
+    signal(SIGPIPE, data->state.prev_signal);
+#else
+  (void)data; /* unused parameter */
+#endif
+
+  return CURLE_OK;
+}
+
+#ifndef CURL_DISABLE_HTTP
+/*
+ * strlen_url() returns the length of the given URL if the spaces within the
+ * URL were properly URL encoded.
+ */
+static size_t strlen_url(const char *url)
+{
+  const unsigned char *ptr;
+  size_t newlen=0;
+  bool left=TRUE; /* left side of the ? */
+
+  for(ptr=(unsigned char *)url; *ptr; ptr++) {
+    switch(*ptr) {
+    case '?':
+      left=FALSE;
+      /* fall through */
+    default:
+      if(*ptr >= 0x80)
+        newlen += 2;
+      newlen++;
+      break;
+    case ' ':
+      if(left)
+        newlen+=3;
+      else
+        newlen++;
+      break;
+    }
+  }
+  return newlen;
+}
+
+/* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in
+ * the source URL accordingly.
+ */
+static void strcpy_url(char *output, const char *url)
+{
+  /* we must add this with whitespace-replacing */
+  bool left=TRUE;
+  const unsigned char *iptr;
+  char *optr = output;
+  for(iptr = (unsigned char *)url;    /* read from here */
+      *iptr;         /* until zero byte */
+      iptr++) {
+    switch(*iptr) {
+    case '?':
+      left=FALSE;
+      /* fall through */
+    default:
+      if(*iptr >= 0x80) {
+        snprintf(optr, 4, "%%%02x", *iptr);
+        optr += 3;
+      }
+      else
+        *optr++=*iptr;
+      break;
+    case ' ':
+      if(left) {
+        *optr++='%'; /* add a '%' */
+        *optr++='2'; /* add a '2' */
+        *optr++='0'; /* add a '0' */
+      }
+      else
+        *optr++='+'; /* add a '+' here */
+      break;
+    }
+  }
+  *optr=0; /* zero terminate output buffer */
+
+}
+
+/*
+ * Returns true if the given URL is absolute (as opposed to relative)
+ */
+static bool is_absolute_url(const char *url)
+{
+  char prot[16]; /* URL protocol string storage */
+  char letter;   /* used for a silly sscanf */
+
+  return (2 == sscanf(url, "%15[^?&/:]://%c", prot, &letter)) ? TRUE : FALSE;
+}
+
+/*
+ * Concatenate a relative URL to a base URL making it absolute.
+ * URL-encodes any spaces.
+ * The returned pointer must be freed by the caller unless NULL
+ * (returns NULL on out of memory).
+ */
+static char *concat_url(const char *base, const char *relurl)
+{
+  /***
+   TRY to append this new path to the old URL
+   to the right of the host part. Oh crap, this is doomed to cause
+   problems in the future...
+  */
+  char *newest;
+  char *protsep;
+  char *pathsep;
+  size_t newlen;
+
+  const char *useurl = relurl;
+  size_t urllen;
+
+  /* we must make our own copy of the URL to play with, as it may
+     point to read-only data */
+  char *url_clone=strdup(base);
+
+  if(!url_clone)
+    return NULL; /* skip out of this NOW */
+
+  /* protsep points to the start of the host name */
+  protsep=strstr(url_clone, "//");
+  if(!protsep)
+    protsep=url_clone;
+  else
+    protsep+=2; /* pass the slashes */
+
+  if('/' != relurl[0]) {
+    int level=0;
+
+    /* First we need to find out if there's a ?-letter in the URL,
+       and cut it and the right-side of that off */
+    pathsep = strchr(protsep, '?');
+    if(pathsep)
+      *pathsep=0;
+
+    /* we have a relative path to append to the last slash if there's one
+       available, or if the new URL is just a query string (starts with a
+       '?')  we append the new one at the end of the entire currently worked
+       out URL */
+    if(useurl[0] != '?') {
+      pathsep = strrchr(protsep, '/');
+      if(pathsep)
+        *pathsep=0;
+    }
+
+    /* Check if there's any slash after the host name, and if so, remember
+       that position instead */
+    pathsep = strchr(protsep, '/');
+    if(pathsep)
+      protsep = pathsep+1;
+    else
+      protsep = NULL;
+
+    /* now deal with one "./" or any amount of "../" in the newurl
+       and act accordingly */
+
+    if((useurl[0] == '.') && (useurl[1] == '/'))
+      useurl+=2; /* just skip the "./" */
+
+    while((useurl[0] == '.') &&
+          (useurl[1] == '.') &&
+          (useurl[2] == '/')) {
+      level++;
+      useurl+=3; /* pass the "../" */
+    }
+
+    if(protsep) {
+      while(level--) {
+        /* cut off one more level from the right of the original URL */
+        pathsep = strrchr(protsep, '/');
+        if(pathsep)
+          *pathsep=0;
+        else {
+          *protsep=0;
+          break;
+        }
+      }
+    }
+  }
+  else {
+    /* We got a new absolute path for this server */
+
+    if((relurl[0] == '/') && (relurl[1] == '/')) {
+      /* the new URL starts with //, just keep the protocol part from the
+         original one */
+      *protsep=0;
+      useurl = &relurl[2]; /* we keep the slashes from the original, so we
+                              skip the new ones */
+    }
+    else {
+      /* cut off the original URL from the first slash, or deal with URLs
+         without slash */
+      pathsep = strchr(protsep, '/');
+      if(pathsep) {
+        /* When people use badly formatted URLs, such as
+           "http://www.url.com?dir=/home/daniel" we must not use the first
+           slash, if there's a ?-letter before it! */
+        char *sep = strchr(protsep, '?');
+        if(sep && (sep < pathsep))
+          pathsep = sep;
+        *pathsep=0;
+      }
+      else {
+        /* There was no slash. Now, since we might be operating on a badly
+           formatted URL, such as "http://www.url.com?id=2380" which doesn't
+           use a slash separator as it is supposed to, we need to check for a
+           ?-letter as well! */
+        pathsep = strchr(protsep, '?');
+        if(pathsep)
+          *pathsep=0;
+      }
+    }
+  }
+
+  /* If the new part contains a space, this is a mighty stupid redirect
+     but we still make an effort to do "right". To the left of a '?'
+     letter we replace each space with %20 while it is replaced with '+'
+     on the right side of the '?' letter.
+  */
+  newlen = strlen_url(useurl);
+
+  urllen = strlen(url_clone);
+
+  newest = malloc(urllen + 1 + /* possible slash */
+                  newlen + 1 /* zero byte */);
+
+  if(!newest) {
+    free(url_clone); /* don't leak this */
+    return NULL;
+  }
+
+  /* copy over the root url part */
+  memcpy(newest, url_clone, urllen);
+
+  /* check if we need to append a slash */
+  if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0]))
+    ;
+  else
+    newest[urllen++]='/';
+
+  /* then append the new piece on the right side */
+  strcpy_url(&newest[urllen], useurl);
+
+  free(url_clone);
+
+  return newest;
+}
+#endif /* CURL_DISABLE_HTTP */
+
+/*
+ * Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string
+ * as given by the remote server and set up the new URL to request.
+ */
+CURLcode Curl_follow(struct SessionHandle *data,
+                     char *newurl, /* this 'newurl' is the Location: string,
+                                      and it must be malloc()ed before passed
+                                      here */
+                     followtype type) /* see transfer.h */
+{
+#ifdef CURL_DISABLE_HTTP
+  (void)data;
+  (void)newurl;
+  (void)type;
+  /* Location: following will not happen when HTTP is disabled */
+  return CURLE_TOO_MANY_REDIRECTS;
+#else
+
+  /* Location: redirect */
+  bool disallowport = FALSE;
+
+  if(type == FOLLOW_REDIR) {
+    if((data->set.maxredirs != -1) &&
+        (data->set.followlocation >= data->set.maxredirs)) {
+      failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs);
+      return CURLE_TOO_MANY_REDIRECTS;
+    }
+
+    /* mark the next request as a followed location: */
+    data->state.this_is_a_follow = TRUE;
+
+    data->set.followlocation++; /* count location-followers */
+
+    if(data->set.http_auto_referer) {
+      /* We are asked to automatically set the previous URL as the referer
+         when we get the next URL. We pick the ->url field, which may or may
+         not be 100% correct */
+
+      if(data->change.referer_alloc) {
+        Curl_safefree(data->change.referer);
+        data->change.referer_alloc = FALSE;
+      }
+
+      data->change.referer = strdup(data->change.url);
+      if(!data->change.referer)
+        return CURLE_OUT_OF_MEMORY;
+      data->change.referer_alloc = TRUE; /* yes, free this later */
+    }
+  }
+
+  if(!is_absolute_url(newurl))  {
+    /***
+     *DANG* this is an RFC 2068 violation. The URL is supposed
+     to be absolute and this doesn't seem to be that!
+     */
+    char *absolute = concat_url(data->change.url, newurl);
+    if(!absolute)
+      return CURLE_OUT_OF_MEMORY;
+    free(newurl);
+    newurl = absolute;
+  }
+  else {
+    /* The new URL MAY contain space or high byte values, that means a mighty
+       stupid redirect URL but we still make an effort to do "right". */
+    char *newest;
+    size_t newlen = strlen_url(newurl);
+
+    /* This is an absolute URL, don't allow the custom port number */
+    disallowport = TRUE;
+
+    newest = malloc(newlen+1); /* get memory for this */
+    if(!newest)
+      return CURLE_OUT_OF_MEMORY;
+    strcpy_url(newest, newurl); /* create a space-free URL */
+
+    free(newurl); /* that was no good */
+    newurl = newest; /* use this instead now */
+
+  }
+
+  if(type == FOLLOW_FAKE) {
+    /* we're only figuring out the new url if we would've followed locations
+       but now we're done so we can get out! */
+    data->info.wouldredirect = newurl;
+    return CURLE_OK;
+  }
+
+  if(disallowport)
+    data->state.allow_port = FALSE;
+
+  if(data->change.url_alloc) {
+    Curl_safefree(data->change.url);
+    data->change.url_alloc = FALSE;
+  }
+
+  data->change.url = newurl;
+  data->change.url_alloc = TRUE;
+  newurl = NULL; /* don't free! */
+
+  infof(data, "Issue another request to this URL: '%s'\n", data->change.url);
+
+  /*
+   * We get here when the HTTP code is 300-399 (and 401). We need to perform
+   * differently based on exactly what return code there was.
+   *
+   * News from 7.10.6: we can also get here on a 401 or 407, in case we act on
+   * a HTTP (proxy-) authentication scheme other than Basic.
+   */
+  switch(data->info.httpcode) {
+    /* 401 - Act on a WWW-Authenticate, we keep on moving and do the
+       Authorization: XXXX header in the HTTP request code snippet */
+    /* 407 - Act on a Proxy-Authenticate, we keep on moving and do the
+       Proxy-Authorization: XXXX header in the HTTP request code snippet */
+    /* 300 - Multiple Choices */
+    /* 306 - Not used */
+    /* 307 - Temporary Redirect */
+  default:  /* for all above (and the unknown ones) */
+    /* Some codes are explicitly mentioned since I've checked RFC2616 and they
+     * seem to be OK to POST to.
+     */
+    break;
+  case 301: /* Moved Permanently */
+    /* (quote from RFC7231, section 6.4.2)
+     *
+     * Note: For historical reasons, a user agent MAY change the request
+     * method from POST to GET for the subsequent request.  If this
+     * behavior is undesired, the 307 (Temporary Redirect) status code
+     * can be used instead.
+     *
+     * ----
+     *
+     * Many webservers expect this, so these servers often answers to a POST
+     * request with an error page. To be sure that libcurl gets the page that
+     * most user agents would get, libcurl has to force GET.
+     *
+     * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and
+     * can be overridden with CURLOPT_POSTREDIR.
+     */
+    if((data->set.httpreq == HTTPREQ_POST
+        || data->set.httpreq == HTTPREQ_POST_FORM)
+       && !(data->set.keep_post & CURL_REDIR_POST_301)) {
+      infof(data, "Switch from POST to GET\n");
+      data->set.httpreq = HTTPREQ_GET;
+    }
+    break;
+  case 302: /* Found */
+    /* (quote from RFC7231, section 6.4.3)
+     *
+     * Note: For historical reasons, a user agent MAY change the request
+     * method from POST to GET for the subsequent request.  If this
+     * behavior is undesired, the 307 (Temporary Redirect) status code
+     * can be used instead.
+     *
+     * ----
+     *
+     * Many webservers expect this, so these servers often answers to a POST
+     * request with an error page. To be sure that libcurl gets the page that
+     * most user agents would get, libcurl has to force GET.
+     *
+     * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and
+     * can be overridden with CURLOPT_POSTREDIR.
+     */
+    if((data->set.httpreq == HTTPREQ_POST
+        || data->set.httpreq == HTTPREQ_POST_FORM)
+       && !(data->set.keep_post & CURL_REDIR_POST_302)) {
+      infof(data, "Switch from POST to GET\n");
+      data->set.httpreq = HTTPREQ_GET;
+    }
+    break;
+
+  case 303: /* See Other */
+    /* Disable both types of POSTs, unless the user explicitely
+       asks for POST after POST */
+    if(data->set.httpreq != HTTPREQ_GET
+      && !(data->set.keep_post & CURL_REDIR_POST_303)) {
+      data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
+      infof(data, "Disables POST, goes with %s\n",
+            data->set.opt_no_body?"HEAD":"GET");
+    }
+    break;
+  case 304: /* Not Modified */
+    /* 304 means we did a conditional request and it was "Not modified".
+     * We shouldn't get any Location: header in this response!
+     */
+    break;
+  case 305: /* Use Proxy */
+    /* (quote from RFC2616, section 10.3.6):
+     * "The requested resource MUST be accessed through the proxy given
+     * by the Location field. The Location field gives the URI of the
+     * proxy.  The recipient is expected to repeat this single request
+     * via the proxy. 305 responses MUST only be generated by origin
+     * servers."
+     */
+    break;
+  }
+  Curl_pgrsTime(data, TIMER_REDIRECT);
+  Curl_pgrsResetTimesSizes(data);
+
+  return CURLE_OK;
+#endif /* CURL_DISABLE_HTTP */
+}
+
+CURLcode
+Curl_reconnect_request(struct connectdata **connp)
+{
+  CURLcode result = CURLE_OK;
+  struct connectdata *conn = *connp;
+  struct SessionHandle *data = conn->data;
+
+  /* This was a re-use of a connection and we got a write error in the
+   * DO-phase. Then we DISCONNECT this connection and have another attempt to
+   * CONNECT and then DO again! The retry cannot possibly find another
+   * connection to re-use, since we only keep one possible connection for
+   * each.  */
+
+  infof(data, "Re-used connection seems dead, get a new one\n");
+
+  connclose(conn, "Reconnect dead connection"); /* enforce close */
+  result = Curl_done(&conn, result, FALSE); /* we are so done with this */
+
+  /* conn may no longer be a good pointer, clear it to avoid mistakes by
+     parent functions */
+  *connp = NULL;
+
+  /*
+   * According to bug report #1330310. We need to check for CURLE_SEND_ERROR
+   * here as well. I figure this could happen when the request failed on a FTP
+   * connection and thus Curl_done() itself tried to use the connection
+   * (again). Slight Lack of feedback in the report, but I don't think this
+   * extra check can do much harm.
+   */
+  if(!result || (CURLE_SEND_ERROR == result)) {
+    bool async;
+    bool protocol_done = TRUE;
+
+    /* Now, redo the connect and get a new connection */
+    result = Curl_connect(data, connp, &async, &protocol_done);
+    if(!result) {
+      /* We have connected or sent away a name resolve query fine */
+
+      conn = *connp; /* setup conn to again point to something nice */
+      if(async) {
+        /* Now, if async is TRUE here, we need to wait for the name
+           to resolve */
+        result = Curl_resolver_wait_resolv(conn, NULL);
+        if(result)
+          return result;
+
+        /* Resolved, continue with the connection */
+        result = Curl_async_resolved(conn, &protocol_done);
+        if(result)
+          return result;
+      }
+    }
+  }
+
+  return result;
+}
+
+/* Returns CURLE_OK *and* sets '*url' if a request retry is wanted.
+
+   NOTE: that the *url is malloc()ed. */
+CURLcode Curl_retry_request(struct connectdata *conn,
+                            char **url)
+{
+  struct SessionHandle *data = conn->data;
+
+  *url = NULL;
+
+  /* if we're talking upload, we can't do the checks below, unless the protocol
+     is HTTP as when uploading over HTTP we will still get a response */
+  if(data->set.upload &&
+     !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)))
+    return CURLE_OK;
+
+  if((data->req.bytecount + data->req.headerbytecount == 0) &&
+      conn->bits.reuse &&
+      !data->set.opt_no_body &&
+      (data->set.rtspreq != RTSPREQ_RECEIVE)) {
+    /* We got no data, we attempted to re-use a connection and yet we want a
+       "body". This might happen if the connection was left alive when we were
+       done using it before, but that was closed when we wanted to read from
+       it again. Bad luck. Retry the same request on a fresh connect! */
+    infof(conn->data, "Connection died, retrying a fresh connect\n");
+    *url = strdup(conn->data->change.url);
+    if(!*url)
+      return CURLE_OUT_OF_MEMORY;
+
+    connclose(conn, "retry"); /* close this connection */
+    conn->bits.retry = TRUE; /* mark this as a connection we're about
+                                to retry. Marking it this way should
+                                prevent i.e HTTP transfers to return
+                                error just because nothing has been
+                                transferred! */
+
+
+    if(conn->handler->protocol&PROTO_FAMILY_HTTP) {
+      struct HTTP *http = data->req.protop;
+      if(http->writebytecount)
+        return Curl_readrewind(conn);
+    }
+  }
+  return CURLE_OK;
+}
+
+/*
+ * Curl_setup_transfer() is called to setup some basic properties for the
+ * upcoming transfer.
+ */
+void
+Curl_setup_transfer(
+  struct connectdata *conn, /* connection data */
+  int sockindex,            /* socket index to read from or -1 */
+  curl_off_t size,          /* -1 if unknown at this point */
+  bool getheader,           /* TRUE if header parsing is wanted */
+  curl_off_t *bytecountp,   /* return number of bytes read or NULL */
+  int writesockindex,       /* socket index to write to, it may very well be
+                               the same we read from. -1 disables */
+  curl_off_t *writecountp   /* return number of bytes written or NULL */
+  )
+{
+  struct SessionHandle *data;
+  struct SingleRequest *k;
+
+  DEBUGASSERT(conn != NULL);
+
+  data = conn->data;
+  k = &data->req;
+
+  DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
+
+  /* now copy all input parameters */
+  conn->sockfd = sockindex == -1 ?
+      CURL_SOCKET_BAD : conn->sock[sockindex];
+  conn->writesockfd = writesockindex == -1 ?
+      CURL_SOCKET_BAD:conn->sock[writesockindex];
+  k->getheader = getheader;
+
+  k->size = size;
+  k->bytecountp = bytecountp;
+  k->writebytecountp = writecountp;
+
+  /* The code sequence below is placed in this function just because all
+     necessary input is not always known in do_complete() as this function may
+     be called after that */
+
+  if(!k->getheader) {
+    k->header = FALSE;
+    if(size > 0)
+      Curl_pgrsSetDownloadSize(data, size);
+  }
+  /* we want header and/or body, if neither then don't do this! */
+  if(k->getheader || !data->set.opt_no_body) {
+
+    if(conn->sockfd != CURL_SOCKET_BAD)
+      k->keepon |= KEEP_RECV;
+
+    if(conn->writesockfd != CURL_SOCKET_BAD) {
+      struct HTTP *http = data->req.protop;
+      /* HTTP 1.1 magic:
+
+         Even if we require a 100-return code before uploading data, we might
+         need to write data before that since the REQUEST may not have been
+         finished sent off just yet.
+
+         Thus, we must check if the request has been sent before we set the
+         state info where we wait for the 100-return code
+      */
+      if((data->state.expect100header) &&
+         (conn->handler->protocol&PROTO_FAMILY_HTTP) &&
+         (http->sending == HTTPSEND_BODY)) {
+        /* wait with write until we either got 100-continue or a timeout */
+        k->exp100 = EXP100_AWAITING_CONTINUE;
+        k->start100 = Curl_tvnow();
+
+        /* Set a timeout for the multi interface. Add the inaccuracy margin so
+           that we don't fire slightly too early and get denied to run. */
+        Curl_expire(data, data->set.expect_100_timeout);
+      }
+      else {
+        if(data->state.expect100header)
+          /* when we've sent off the rest of the headers, we must await a
+             100-continue but first finish sending the request */
+          k->exp100 = EXP100_SENDING_REQUEST;
+
+        /* enable the write bit when we're not waiting for continue */
+        k->keepon |= KEEP_SEND;
+      }
+    } /* if(conn->writesockfd != CURL_SOCKET_BAD) */
+  } /* if(k->getheader || !data->set.opt_no_body) */
+
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/transfer.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/transfer.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/transfer.h	(revision 164)
@@ -0,0 +1,73 @@
+#ifndef HEADER_CURL_TRANSFER_H
+#define HEADER_CURL_TRANSFER_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+void Curl_init_CONNECT(struct SessionHandle *data);
+
+CURLcode Curl_pretransfer(struct SessionHandle *data);
+CURLcode Curl_second_connect(struct connectdata *conn);
+CURLcode Curl_posttransfer(struct SessionHandle *data);
+
+typedef enum {
+  FOLLOW_NONE,  /* not used within the function, just a placeholder to
+                   allow initing to this */
+  FOLLOW_FAKE,  /* only records stuff, not actually following */
+  FOLLOW_RETRY, /* set if this is a request retry as opposed to a real
+                          redirect following */
+  FOLLOW_REDIR, /* a full true redirect */
+  FOLLOW_LAST   /* never used */
+} followtype;
+
+CURLcode Curl_follow(struct SessionHandle *data, char *newurl,
+                     followtype type);
+
+
+CURLcode Curl_readwrite(struct connectdata *conn,
+                        struct SessionHandle *data, bool *done);
+int Curl_single_getsock(const struct connectdata *conn,
+                        curl_socket_t *socks,
+                        int numsocks);
+CURLcode Curl_readrewind(struct connectdata *conn);
+CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
+CURLcode Curl_reconnect_request(struct connectdata **connp);
+CURLcode Curl_retry_request(struct connectdata *conn, char **url);
+bool Curl_meets_timecondition(struct SessionHandle *data, time_t timeofdoc);
+
+/* This sets up a forthcoming transfer */
+void
+Curl_setup_transfer (struct connectdata *data,
+               int sockindex,           /* socket index to read from or -1 */
+               curl_off_t size,         /* -1 if unknown at this point */
+               bool getheader,          /* TRUE if header parsing is wanted */
+               curl_off_t *bytecountp,  /* return number of bytes read */
+               int writesockindex,      /* socket index to write to, it may
+                                           very well be the same we read from.
+                                           -1 disables */
+               curl_off_t *writecountp /* return number of bytes written */
+);
+
+long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps,
+                     int pkt_size);
+
+#endif /* HEADER_CURL_TRANSFER_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/url.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/url.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/url.c	(revision 164)
@@ -0,0 +1,6354 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+
+#ifndef HAVE_SOCKET
+#error "We can't compile without socket() support!"
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifdef USE_LIBIDN
+#include <idna.h>
+#include <tld.h>
+#include <stringprep.h>
+#ifdef HAVE_IDN_FREE_H
+#include <idn-free.h>
+#else
+/* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */
+void idn_free (void *ptr);
+#endif
+#ifndef HAVE_IDN_FREE
+/* if idn_free() was not found in this version of libidn use free() instead */
+#define idn_free(x) (free)(x)
+#endif
+#elif defined(USE_WIN32_IDN)
+/* prototype for curl_win32_idn_to_ascii() */
+int curl_win32_idn_to_ascii(const char *in, char **out);
+#endif  /* USE_LIBIDN */
+
+#include "urldata.h"
+#include "netrc.h"
+
+#include "formdata.h"
+#include "vtls/vtls.h"
+#include "hostip.h"
+#include "transfer.h"
+#include "sendf.h"
+#include "progress.h"
+#include "cookie.h"
+#include "strequal.h"
+#include "strerror.h"
+#include "escape.h"
+#include "strtok.h"
+#include "share.h"
+#include "content_encoding.h"
+#include "http_digest.h"
+#include "http_negotiate.h"
+#include "select.h"
+#include "multiif.h"
+#include "easyif.h"
+#include "speedcheck.h"
+#include "rawstr.h"
+#include "warnless.h"
+#include "non-ascii.h"
+#include "inet_pton.h"
+
+/* And now for the protocols */
+#include "ftp.h"
+#include "dict.h"
+#include "telnet.h"
+#include "tftp.h"
+#include "http.h"
+#include "http2.h"
+#include "file.h"
+#include "curl_ldap.h"
+#include "ssh.h"
+#include "imap.h"
+#include "url.h"
+#include "connect.h"
+#include "inet_ntop.h"
+#include "curl_ntlm.h"
+#include "curl_ntlm_wb.h"
+#include "socks.h"
+#include "curl_rtmp.h"
+#include "gopher.h"
+#include "http_proxy.h"
+#include "conncache.h"
+#include "multihandle.h"
+#include "pipeline.h"
+#include "dotdot.h"
+#include "strdup.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* Local static prototypes */
+static struct connectdata *
+find_oldest_idle_connection(struct SessionHandle *data);
+static struct connectdata *
+find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
+                                      struct connectbundle *bundle);
+static void conn_free(struct connectdata *conn);
+static void free_fixed_hostname(struct hostname *host);
+static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
+static CURLcode parse_url_login(struct SessionHandle *data,
+                                struct connectdata *conn,
+                                char **userptr, char **passwdptr,
+                                char **optionsptr);
+static CURLcode parse_login_details(const char *login, const size_t len,
+                                    char **userptr, char **passwdptr,
+                                    char **optionsptr);
+/*
+ * Protocol table.
+ */
+
+static const struct Curl_handler * const protocols[] = {
+
+#ifndef CURL_DISABLE_HTTP
+  &Curl_handler_http,
+#endif
+
+#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
+  &Curl_handler_https,
+#endif
+
+#ifndef CURL_DISABLE_FTP
+  &Curl_handler_ftp,
+#endif
+
+#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
+  &Curl_handler_ftps,
+#endif
+
+#ifndef CURL_DISABLE_TELNET
+  &Curl_handler_telnet,
+#endif
+
+#ifndef CURL_DISABLE_DICT
+  &Curl_handler_dict,
+#endif
+
+#ifndef CURL_DISABLE_LDAP
+  &Curl_handler_ldap,
+#if !defined(CURL_DISABLE_LDAPS) && \
+    ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
+     (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
+  &Curl_handler_ldaps,
+#endif
+#endif
+
+#ifndef CURL_DISABLE_FILE
+  &Curl_handler_file,
+#endif
+
+#ifndef CURL_DISABLE_TFTP
+  &Curl_handler_tftp,
+#endif
+
+#ifdef USE_LIBSSH2
+  &Curl_handler_scp,
+  &Curl_handler_sftp,
+#endif
+
+#ifndef CURL_DISABLE_IMAP
+  &Curl_handler_imap,
+#ifdef USE_SSL
+  &Curl_handler_imaps,
+#endif
+#endif
+
+#ifndef CURL_DISABLE_POP3
+  &Curl_handler_pop3,
+#ifdef USE_SSL
+  &Curl_handler_pop3s,
+#endif
+#endif
+
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+   (CURL_SIZEOF_CURL_OFF_T > 4) && \
+   (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
+  &Curl_handler_smb,
+#ifdef USE_SSL
+  &Curl_handler_smbs,
+#endif
+#endif
+
+#ifndef CURL_DISABLE_SMTP
+  &Curl_handler_smtp,
+#ifdef USE_SSL
+  &Curl_handler_smtps,
+#endif
+#endif
+
+#ifndef CURL_DISABLE_RTSP
+  &Curl_handler_rtsp,
+#endif
+
+#ifndef CURL_DISABLE_GOPHER
+  &Curl_handler_gopher,
+#endif
+
+#ifdef USE_LIBRTMP
+  &Curl_handler_rtmp,
+  &Curl_handler_rtmpt,
+  &Curl_handler_rtmpe,
+  &Curl_handler_rtmpte,
+  &Curl_handler_rtmps,
+  &Curl_handler_rtmpts,
+#endif
+
+  (struct Curl_handler *) NULL
+};
+
+/*
+ * Dummy handler for undefined protocol schemes.
+ */
+
+static const struct Curl_handler Curl_handler_dummy = {
+  "<no protocol>",                      /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  ZERO_NULL,                            /* do_it */
+  ZERO_NULL,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  0,                                    /* defport */
+  0,                                    /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+void Curl_freeset(struct SessionHandle *data)
+{
+  /* Free all dynamic strings stored in the data->set substructure. */
+  enum dupstring i;
+  for(i=(enum dupstring)0; i < STRING_LAST; i++) {
+    Curl_safefree(data->set.str[i]);
+  }
+
+  if(data->change.referer_alloc) {
+    Curl_safefree(data->change.referer);
+    data->change.referer_alloc = FALSE;
+  }
+  data->change.referer = NULL;
+  if(data->change.url_alloc) {
+    Curl_safefree(data->change.url);
+    data->change.url_alloc = FALSE;
+  }
+  data->change.url = NULL;
+}
+
+static CURLcode setstropt(char **charp, const char *s)
+{
+  /* Release the previous storage at `charp' and replace by a dynamic storage
+     copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
+
+  Curl_safefree(*charp);
+
+  if(s) {
+    char *str = strdup(s);
+
+    if(!str)
+      return CURLE_OUT_OF_MEMORY;
+
+    *charp = str;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
+{
+  CURLcode result = CURLE_OK;
+  char *user = NULL;
+  char *passwd = NULL;
+
+  /* Parse the login details if specified. It not then we treat NULL as a hint
+     to clear the existing data */
+  if(option) {
+    result = parse_login_details(option, strlen(option),
+                                 (userp ? &user : NULL),
+                                 (passwdp ? &passwd : NULL),
+                                 NULL);
+  }
+
+  if(!result) {
+    /* Store the username part of option if required */
+    if(userp) {
+      if(!user && option && option[0] == ':') {
+        /* Allocate an empty string instead of returning NULL as user name */
+        user = strdup("");
+        if(!user)
+          result = CURLE_OUT_OF_MEMORY;
+      }
+
+      Curl_safefree(*userp);
+      *userp = user;
+    }
+
+    /* Store the password part of option if required */
+    if(passwdp) {
+      Curl_safefree(*passwdp);
+      *passwdp = passwd;
+    }
+  }
+
+  return result;
+}
+
+CURLcode Curl_dupset(struct SessionHandle *dst, struct SessionHandle *src)
+{
+  CURLcode result = CURLE_OK;
+  enum dupstring i;
+
+  /* Copy src->set into dst->set first, then deal with the strings
+     afterwards */
+  dst->set = src->set;
+
+  /* clear all string pointers first */
+  memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
+
+  /* duplicate all strings */
+  for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) {
+    result = setstropt(&dst->set.str[i], src->set.str[i]);
+    if(result)
+      return result;
+  }
+
+  /* duplicate memory areas pointed to */
+  i = STRING_COPYPOSTFIELDS;
+  if(src->set.postfieldsize && src->set.str[i]) {
+    /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */
+    dst->set.str[i] = Curl_memdup(src->set.str[i],
+                                  curlx_sotouz(src->set.postfieldsize));
+    if(!dst->set.str[i])
+      return CURLE_OUT_OF_MEMORY;
+    /* point to the new copy */
+    dst->set.postfields = dst->set.str[i];
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * This is the internal function curl_easy_cleanup() calls. This should
+ * cleanup and free all resources associated with this sessionhandle.
+ *
+ * NOTE: if we ever add something that attempts to write to a socket or
+ * similar here, we must ignore SIGPIPE first. It is currently only done
+ * when curl_easy_perform() is invoked.
+ */
+
+CURLcode Curl_close(struct SessionHandle *data)
+{
+  struct Curl_multi *m;
+
+  if(!data)
+    return CURLE_OK;
+
+  Curl_expire(data, 0); /* shut off timers */
+
+  m = data->multi;
+
+  if(m)
+    /* This handle is still part of a multi handle, take care of this first
+       and detach this handle from there. */
+    curl_multi_remove_handle(data->multi, data);
+
+  if(data->multi_easy)
+    /* when curl_easy_perform() is used, it creates its own multi handle to
+       use and this is the one */
+    curl_multi_cleanup(data->multi_easy);
+
+  /* Destroy the timeout list that is held in the easy handle. It is
+     /normally/ done by curl_multi_remove_handle() but this is "just in
+     case" */
+  if(data->state.timeoutlist) {
+    Curl_llist_destroy(data->state.timeoutlist, NULL);
+    data->state.timeoutlist = NULL;
+  }
+
+  data->magic = 0; /* force a clear AFTER the possibly enforced removal from
+                      the multi handle, since that function uses the magic
+                      field! */
+
+  if(data->state.rangestringalloc)
+    free(data->state.range);
+
+  /* Free the pathbuffer */
+  Curl_safefree(data->state.pathbuffer);
+  data->state.path = NULL;
+
+  /* freed here just in case DONE wasn't called */
+  Curl_free_request_state(data);
+
+  /* Close down all open SSL info and sessions */
+  Curl_ssl_close_all(data);
+  Curl_safefree(data->state.first_host);
+  Curl_safefree(data->state.scratch);
+  Curl_ssl_free_certinfo(data);
+
+  /* Cleanup possible redirect junk */
+  free(data->req.newurl);
+  data->req.newurl = NULL;
+
+  if(data->change.referer_alloc) {
+    Curl_safefree(data->change.referer);
+    data->change.referer_alloc = FALSE;
+  }
+  data->change.referer = NULL;
+
+  if(data->change.url_alloc) {
+    Curl_safefree(data->change.url);
+    data->change.url_alloc = FALSE;
+  }
+  data->change.url = NULL;
+
+  Curl_safefree(data->state.headerbuff);
+
+  Curl_flush_cookies(data, 1);
+
+  Curl_digest_cleanup(data);
+
+  Curl_safefree(data->info.contenttype);
+  Curl_safefree(data->info.wouldredirect);
+
+  /* this destroys the channel and we cannot use it anymore after this */
+  Curl_resolver_cleanup(data->state.resolver);
+
+  Curl_convert_close(data);
+
+  /* No longer a dirty share, if it exists */
+  if(data->share) {
+    Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
+    data->share->dirty--;
+    Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
+  }
+
+  Curl_freeset(data);
+  free(data);
+  return CURLE_OK;
+}
+
+/*
+ * Initialize the UserDefined fields within a SessionHandle.
+ * This may be safely called on a new or existing SessionHandle.
+ */
+CURLcode Curl_init_userdefined(struct UserDefined *set)
+{
+  CURLcode result = CURLE_OK;
+
+  set->out = stdout; /* default output to stdout */
+  set->in_set = stdin;  /* default input from stdin */
+  set->err  = stderr;  /* default stderr to stderr */
+
+  /* use fwrite as default function to store output */
+  set->fwrite_func = (curl_write_callback)fwrite;
+
+  /* use fread as default function to read input */
+  set->fread_func_set = (curl_read_callback)fread;
+  set->is_fread_set = 0;
+  set->is_fwrite_set = 0;
+
+  set->seek_func = ZERO_NULL;
+  set->seek_client = ZERO_NULL;
+
+  /* conversion callbacks for non-ASCII hosts */
+  set->convfromnetwork = ZERO_NULL;
+  set->convtonetwork   = ZERO_NULL;
+  set->convfromutf8    = ZERO_NULL;
+
+  set->filesize = -1;        /* we don't know the size */
+  set->postfieldsize = -1;   /* unknown size */
+  set->maxredirs = -1;       /* allow any amount by default */
+
+  set->httpreq = HTTPREQ_GET; /* Default HTTP request */
+  set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
+  set->ftp_use_epsv = TRUE;   /* FTP defaults to EPSV operations */
+  set->ftp_use_eprt = TRUE;   /* FTP defaults to EPRT operations */
+  set->ftp_use_pret = FALSE;  /* mainly useful for drftpd servers */
+  set->ftp_filemethod = FTPFILE_MULTICWD;
+
+  set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
+
+  /* Set the default size of the SSL session ID cache */
+  set->ssl.max_ssl_sessions = 5;
+
+  set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */
+  set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
+  set->httpauth = CURLAUTH_BASIC;  /* defaults to basic */
+  set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
+
+  /* make libcurl quiet by default: */
+  set->hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */
+
+  /*
+   * libcurl 7.10 introduced SSL verification *by default*! This needs to be
+   * switched off unless wanted.
+   */
+  set->ssl.verifypeer = TRUE;
+  set->ssl.verifyhost = TRUE;
+#ifdef USE_TLS_SRP
+  set->ssl.authtype = CURL_TLSAUTH_NONE;
+#endif
+  set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
+                                                      type */
+  set->ssl.sessionid = TRUE; /* session ID caching enabled by default */
+
+  set->new_file_perms = 0644;    /* Default permissions */
+  set->new_directory_perms = 0755; /* Default permissions */
+
+  /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
+     define since we internally only use the lower 16 bits for the passed
+     in bitmask to not conflict with the private bits */
+  set->allowed_protocols = CURLPROTO_ALL;
+  set->redir_protocols = CURLPROTO_ALL &  /* All except FILE, SCP and SMB */
+                          ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB |
+                            CURLPROTO_SMBS);
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  /*
+   * disallow unprotected protection negotiation NEC reference implementation
+   * seem not to follow rfc1961 section 4.3/4.4
+   */
+  set->socks5_gssapi_nec = FALSE;
+  /* set default GSS-API service name */
+  result = setstropt(&set->str[STRING_SOCKS5_GSSAPI_SERVICE],
+                     CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE);
+  if(result)
+    return result;
+
+  /* set default negotiate proxy service name */
+  result = setstropt(&set->str[STRING_PROXY_SERVICE_NAME],
+                     CURL_DEFAULT_PROXY_SERVICE_NAME);
+  if(result)
+    return result;
+
+  /* set default negotiate service name */
+  result = setstropt(&set->str[STRING_SERVICE_NAME],
+                     CURL_DEFAULT_SERVICE_NAME);
+  if(result)
+    return result;
+#endif
+
+  /* This is our preferred CA cert bundle/path since install time */
+#if defined(CURL_CA_BUNDLE)
+  result = setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE);
+  if(result)
+    return result;
+#endif
+#if defined(CURL_CA_PATH)
+  result = setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH);
+  if(result)
+    return result;
+#endif
+
+  set->wildcardmatch  = FALSE;
+  set->chunk_bgn      = ZERO_NULL;
+  set->chunk_end      = ZERO_NULL;
+
+  /* tcp keepalives are disabled by default, but provide reasonable values for
+   * the interval and idle times.
+   */
+  set->tcp_keepalive = FALSE;
+  set->tcp_keepintvl = 60;
+  set->tcp_keepidle = 60;
+
+  set->ssl_enable_npn = TRUE;
+  set->ssl_enable_alpn = TRUE;
+
+  set->expect_100_timeout = 1000L; /* Wait for a second by default. */
+  set->sep_headers = TRUE; /* separated header lists by default */
+
+  Curl_http2_init_userset(set);
+  return result;
+}
+
+/**
+ * Curl_open()
+ *
+ * @param curl is a pointer to a sessionhandle pointer that gets set by this
+ * function.
+ * @return CURLcode
+ */
+
+CURLcode Curl_open(struct SessionHandle **curl)
+{
+  CURLcode result;
+  struct SessionHandle *data;
+
+  /* Very simple start-up: alloc the struct, init it with zeroes and return */
+  data = calloc(1, sizeof(struct SessionHandle));
+  if(!data) {
+    /* this is a very serious error */
+    DEBUGF(fprintf(stderr, "Error: calloc of SessionHandle failed\n"));
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  data->magic = CURLEASY_MAGIC_NUMBER;
+
+  result = Curl_resolver_init(&data->state.resolver);
+  if(result) {
+    DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
+    free(data);
+    return result;
+  }
+
+  /* We do some initial setup here, all those fields that can't be just 0 */
+
+  data->state.headerbuff = malloc(HEADERSIZE);
+  if(!data->state.headerbuff) {
+    DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
+    result = CURLE_OUT_OF_MEMORY;
+  }
+  else {
+    result = Curl_init_userdefined(&data->set);
+
+    data->state.headersize=HEADERSIZE;
+
+    Curl_convert_init(data);
+
+    /* most recent connection is not yet defined */
+    data->state.lastconnect = NULL;
+
+    data->progress.flags |= PGRS_HIDE;
+    data->state.current_speed = -1; /* init to negative == impossible */
+
+    data->wildcard.state = CURLWC_INIT;
+    data->wildcard.filelist = NULL;
+    data->set.fnmatch = ZERO_NULL;
+    data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
+
+    Curl_http2_init_state(&data->state);
+  }
+
+  if(result) {
+    Curl_resolver_cleanup(data->state.resolver);
+    free(data->state.headerbuff);
+    Curl_freeset(data);
+    free(data);
+    data = NULL;
+  }
+  else
+    *curl = data;
+
+  return result;
+}
+
+CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
+                     va_list param)
+{
+  char *argptr;
+  CURLcode result = CURLE_OK;
+  long arg;
+#ifndef CURL_DISABLE_HTTP
+  curl_off_t bigsize;
+#endif
+
+  switch(option) {
+  case CURLOPT_DNS_CACHE_TIMEOUT:
+    data->set.dns_cache_timeout = va_arg(param, long);
+    break;
+  case CURLOPT_DNS_USE_GLOBAL_CACHE:
+    /* remember we want this enabled */
+    arg = va_arg(param, long);
+    data->set.global_dns_cache = (0 != arg)?TRUE:FALSE;
+    break;
+  case CURLOPT_SSL_CIPHER_LIST:
+    /* set a list of cipher we want to use in the SSL connection */
+    result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_RANDOM_FILE:
+    /*
+     * This is the path name to a file that contains random data to seed
+     * the random SSL stuff with. The file is only used for reading.
+     */
+    result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_EGDSOCKET:
+    /*
+     * The Entropy Gathering Daemon socket pathname
+     */
+    result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_MAXCONNECTS:
+    /*
+     * Set the absolute number of maximum simultaneous alive connection that
+     * libcurl is allowed to have.
+     */
+    data->set.maxconnects = va_arg(param, long);
+    break;
+  case CURLOPT_FORBID_REUSE:
+    /*
+     * When this transfer is done, it must not be left to be reused by a
+     * subsequent transfer but shall be closed immediately.
+     */
+    data->set.reuse_forbid = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_FRESH_CONNECT:
+    /*
+     * This transfer shall not use a previously cached connection but
+     * should be made with a fresh new connect!
+     */
+    data->set.reuse_fresh = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_VERBOSE:
+    /*
+     * Verbose means infof() calls that give a lot of information about
+     * the connection and transfer procedures as well as internal choices.
+     */
+    data->set.verbose = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_HEADER:
+    /*
+     * Set to include the header in the general data output stream.
+     */
+    data->set.include_header = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_NOPROGRESS:
+    /*
+     * Shut off the internal supported progress meter
+     */
+    data->set.hide_progress = (0 != va_arg(param, long))?TRUE:FALSE;
+    if(data->set.hide_progress)
+      data->progress.flags |= PGRS_HIDE;
+    else
+      data->progress.flags &= ~PGRS_HIDE;
+    break;
+  case CURLOPT_NOBODY:
+    /*
+     * Do not include the body part in the output data stream.
+     */
+    data->set.opt_no_body = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_FAILONERROR:
+    /*
+     * Don't output the >=400 error code HTML-page, but instead only
+     * return error.
+     */
+    data->set.http_fail_on_error = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_UPLOAD:
+  case CURLOPT_PUT:
+    /*
+     * We want to sent data to the remote host. If this is HTTP, that equals
+     * using the PUT request.
+     */
+    data->set.upload = (0 != va_arg(param, long))?TRUE:FALSE;
+    if(data->set.upload) {
+      /* If this is HTTP, PUT is what's needed to "upload" */
+      data->set.httpreq = HTTPREQ_PUT;
+      data->set.opt_no_body = FALSE; /* this is implied */
+    }
+    else
+      /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
+         then this can be changed to HEAD later on) */
+      data->set.httpreq = HTTPREQ_GET;
+    break;
+  case CURLOPT_FILETIME:
+    /*
+     * Try to get the file time of the remote document. The time will
+     * later (possibly) become available using curl_easy_getinfo().
+     */
+    data->set.get_filetime = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_FTP_CREATE_MISSING_DIRS:
+    /*
+     * An FTP option that modifies an upload to create missing directories on
+     * the server.
+     */
+    switch(va_arg(param, long)) {
+    case 0:
+      data->set.ftp_create_missing_dirs = 0;
+      break;
+    case 1:
+      data->set.ftp_create_missing_dirs = 1;
+      break;
+    case 2:
+      data->set.ftp_create_missing_dirs = 2;
+      break;
+    default:
+      /* reserve other values for future use */
+      result = CURLE_UNKNOWN_OPTION;
+      break;
+    }
+    break;
+  case CURLOPT_SERVER_RESPONSE_TIMEOUT:
+    /*
+     * Option that specifies how quickly an server response must be obtained
+     * before it is considered failure. For pingpong protocols.
+     */
+    data->set.server_response_timeout = va_arg( param , long ) * 1000;
+    break;
+  case CURLOPT_TFTP_BLKSIZE:
+    /*
+     * TFTP option that specifies the block size to use for data transmission
+     */
+    data->set.tftp_blksize = va_arg(param, long);
+    break;
+  case CURLOPT_DIRLISTONLY:
+    /*
+     * An option that changes the command to one that asks for a list
+     * only, no file info details.
+     */
+    data->set.ftp_list_only = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_APPEND:
+    /*
+     * We want to upload and append to an existing file.
+     */
+    data->set.ftp_append = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_FTP_FILEMETHOD:
+    /*
+     * How do access files over FTP.
+     */
+    data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long);
+    break;
+  case CURLOPT_NETRC:
+    /*
+     * Parse the $HOME/.netrc file
+     */
+    data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
+    break;
+  case CURLOPT_NETRC_FILE:
+    /*
+     * Use this file instead of the $HOME/.netrc file
+     */
+    result = setstropt(&data->set.str[STRING_NETRC_FILE],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_TRANSFERTEXT:
+    /*
+     * This option was previously named 'FTPASCII'. Renamed to work with
+     * more protocols than merely FTP.
+     *
+     * Transfer using ASCII (instead of BINARY).
+     */
+    data->set.prefer_ascii = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_TIMECONDITION:
+    /*
+     * Set HTTP time condition. This must be one of the defines in the
+     * curl/curl.h header file.
+     */
+    data->set.timecondition = (curl_TimeCond)va_arg(param, long);
+    break;
+  case CURLOPT_TIMEVALUE:
+    /*
+     * This is the value to compare with the remote document with the
+     * method set with CURLOPT_TIMECONDITION
+     */
+    data->set.timevalue = (time_t)va_arg(param, long);
+    break;
+  case CURLOPT_SSLVERSION:
+    /*
+     * Set explicit SSL version to try to connect with, as some SSL
+     * implementations are lame.
+     */
+#ifdef USE_SSL
+    data->set.ssl.version = va_arg(param, long);
+#else
+    result = CURLE_UNKNOWN_OPTION;
+#endif
+    break;
+
+#ifndef CURL_DISABLE_HTTP
+  case CURLOPT_AUTOREFERER:
+    /*
+     * Switch on automatic referer that gets set if curl follows locations.
+     */
+    data->set.http_auto_referer = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_ACCEPT_ENCODING:
+    /*
+     * String to use at the value of Accept-Encoding header.
+     *
+     * If the encoding is set to "" we use an Accept-Encoding header that
+     * encompasses all the encodings we support.
+     * If the encoding is set to NULL we don't send an Accept-Encoding header
+     * and ignore an received Content-Encoding header.
+     *
+     */
+    argptr = va_arg(param, char *);
+    result = setstropt(&data->set.str[STRING_ENCODING],
+                       (argptr && !*argptr)?
+                       ALL_CONTENT_ENCODINGS: argptr);
+    break;
+
+  case CURLOPT_TRANSFER_ENCODING:
+    data->set.http_transfer_encoding = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_FOLLOWLOCATION:
+    /*
+     * Follow Location: header hints on a HTTP-server.
+     */
+    data->set.http_follow_location = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_UNRESTRICTED_AUTH:
+    /*
+     * Send authentication (user+password) when following locations, even when
+     * hostname changed.
+     */
+    data->set.http_disable_hostname_check_before_authentication =
+      (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_MAXREDIRS:
+    /*
+     * The maximum amount of hops you allow curl to follow Location:
+     * headers. This should mostly be used to detect never-ending loops.
+     */
+    data->set.maxredirs = va_arg(param, long);
+    break;
+
+  case CURLOPT_POSTREDIR:
+  {
+    /*
+     * Set the behaviour of POST when redirecting
+     * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
+     * CURL_REDIR_POST_301 - POST is kept as POST after 301
+     * CURL_REDIR_POST_302 - POST is kept as POST after 302
+     * CURL_REDIR_POST_303 - POST is kept as POST after 303
+     * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
+     * other - POST is kept as POST after 301 and 302
+     */
+    int postRedir = curlx_sltosi(va_arg(param, long));
+    data->set.keep_post = postRedir & CURL_REDIR_POST_ALL;
+  }
+  break;
+
+  case CURLOPT_POST:
+    /* Does this option serve a purpose anymore? Yes it does, when
+       CURLOPT_POSTFIELDS isn't used and the POST data is read off the
+       callback! */
+    if(va_arg(param, long)) {
+      data->set.httpreq = HTTPREQ_POST;
+      data->set.opt_no_body = FALSE; /* this is implied */
+    }
+    else
+      data->set.httpreq = HTTPREQ_GET;
+    break;
+
+  case CURLOPT_COPYPOSTFIELDS:
+    /*
+     * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
+     * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to
+     *  CURLOPT_COPYPOSTFIELDS and not altered later.
+     */
+    argptr = va_arg(param, char *);
+
+    if(!argptr || data->set.postfieldsize == -1)
+      result = setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr);
+    else {
+      /*
+       *  Check that requested length does not overflow the size_t type.
+       */
+
+      if((data->set.postfieldsize < 0) ||
+         ((sizeof(curl_off_t) != sizeof(size_t)) &&
+          (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
+        result = CURLE_OUT_OF_MEMORY;
+      else {
+        char * p;
+
+        (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
+
+        /* Allocate even when size == 0. This satisfies the need of possible
+           later address compare to detect the COPYPOSTFIELDS mode, and
+           to mark that postfields is used rather than read function or
+           form data.
+        */
+        p = malloc((size_t)(data->set.postfieldsize?
+                            data->set.postfieldsize:1));
+
+        if(!p)
+          result = CURLE_OUT_OF_MEMORY;
+        else {
+          if(data->set.postfieldsize)
+            memcpy(p, argptr, (size_t)data->set.postfieldsize);
+
+          data->set.str[STRING_COPYPOSTFIELDS] = p;
+        }
+      }
+    }
+
+    data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
+    data->set.httpreq = HTTPREQ_POST;
+    break;
+
+  case CURLOPT_POSTFIELDS:
+    /*
+     * Like above, but use static data instead of copying it.
+     */
+    data->set.postfields = va_arg(param, void *);
+    /* Release old copied data. */
+    (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
+    data->set.httpreq = HTTPREQ_POST;
+    break;
+
+  case CURLOPT_POSTFIELDSIZE:
+    /*
+     * The size of the POSTFIELD data to prevent libcurl to do strlen() to
+     * figure it out. Enables binary posts.
+     */
+    bigsize = va_arg(param, long);
+
+    if(data->set.postfieldsize < bigsize &&
+       data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
+      /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
+      (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
+      data->set.postfields = NULL;
+    }
+
+    data->set.postfieldsize = bigsize;
+    break;
+
+  case CURLOPT_POSTFIELDSIZE_LARGE:
+    /*
+     * The size of the POSTFIELD data to prevent libcurl to do strlen() to
+     * figure it out. Enables binary posts.
+     */
+    bigsize = va_arg(param, curl_off_t);
+
+    if(data->set.postfieldsize < bigsize &&
+       data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
+      /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
+      (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
+      data->set.postfields = NULL;
+    }
+
+    data->set.postfieldsize = bigsize;
+    break;
+
+  case CURLOPT_HTTPPOST:
+    /*
+     * Set to make us do HTTP POST
+     */
+    data->set.httppost = va_arg(param, struct curl_httppost *);
+    data->set.httpreq = HTTPREQ_POST_FORM;
+    data->set.opt_no_body = FALSE; /* this is implied */
+    break;
+
+  case CURLOPT_REFERER:
+    /*
+     * String to set in the HTTP Referer: field.
+     */
+    if(data->change.referer_alloc) {
+      Curl_safefree(data->change.referer);
+      data->change.referer_alloc = FALSE;
+    }
+    result = setstropt(&data->set.str[STRING_SET_REFERER],
+                       va_arg(param, char *));
+    data->change.referer = data->set.str[STRING_SET_REFERER];
+    break;
+
+  case CURLOPT_USERAGENT:
+    /*
+     * String to use in the HTTP User-Agent field
+     */
+    result = setstropt(&data->set.str[STRING_USERAGENT],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_HTTPHEADER:
+    /*
+     * Set a list with HTTP headers to use (or replace internals with)
+     */
+    data->set.headers = va_arg(param, struct curl_slist *);
+    break;
+
+  case CURLOPT_PROXYHEADER:
+    /*
+     * Set a list with proxy headers to use (or replace internals with)
+     *
+     * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a
+     * long time we remain doing it this way until CURLOPT_PROXYHEADER is
+     * used. As soon as this option has been used, if set to anything but
+     * NULL, custom headers for proxies are only picked from this list.
+     *
+     * Set this option to NULL to restore the previous behavior.
+     */
+    data->set.proxyheaders = va_arg(param, struct curl_slist *);
+    break;
+
+  case CURLOPT_HEADEROPT:
+    /*
+     * Set header option.
+     */
+    arg = va_arg(param, long);
+    data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE;
+    break;
+
+  case CURLOPT_HTTP200ALIASES:
+    /*
+     * Set a list of aliases for HTTP 200 in response header
+     */
+    data->set.http200aliases = va_arg(param, struct curl_slist *);
+    break;
+
+#if !defined(CURL_DISABLE_COOKIES)
+  case CURLOPT_COOKIE:
+    /*
+     * Cookie string to send to the remote server in the request.
+     */
+    result = setstropt(&data->set.str[STRING_COOKIE],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_COOKIEFILE:
+    /*
+     * Set cookie file to read and parse. Can be used multiple times.
+     */
+    argptr = (char *)va_arg(param, void *);
+    if(argptr) {
+      struct curl_slist *cl;
+      /* append the cookie file name to the list of file names, and deal with
+         them later */
+      cl = curl_slist_append(data->change.cookielist, argptr);
+      if(!cl) {
+        curl_slist_free_all(data->change.cookielist);
+        data->change.cookielist = NULL;
+        return CURLE_OUT_OF_MEMORY;
+      }
+      data->change.cookielist = cl; /* store the list for later use */
+    }
+    break;
+
+  case CURLOPT_COOKIEJAR:
+    /*
+     * Set cookie file name to dump all cookies to when we're done.
+     */
+  {
+    struct CookieInfo *newcookies;
+    result = setstropt(&data->set.str[STRING_COOKIEJAR],
+                       va_arg(param, char *));
+
+    /*
+     * Activate the cookie parser. This may or may not already
+     * have been made.
+     */
+    newcookies = Curl_cookie_init(data, NULL, data->cookies,
+                                  data->set.cookiesession);
+    if(!newcookies)
+      result = CURLE_OUT_OF_MEMORY;
+    data->cookies = newcookies;
+  }
+    break;
+
+  case CURLOPT_COOKIESESSION:
+    /*
+     * Set this option to TRUE to start a new "cookie session". It will
+     * prevent the forthcoming read-cookies-from-file actions to accept
+     * cookies that are marked as being session cookies, as they belong to a
+     * previous session.
+     *
+     * In the original Netscape cookie spec, "session cookies" are cookies
+     * with no expire date set. RFC2109 describes the same action if no
+     * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
+     * a 'Discard' action that can enforce the discard even for cookies that
+     * have a Max-Age.
+     *
+     * We run mostly with the original cookie spec, as hardly anyone implements
+     * anything else.
+     */
+    data->set.cookiesession = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_COOKIELIST:
+    argptr = va_arg(param, char *);
+
+    if(argptr == NULL)
+      break;
+
+    if(Curl_raw_equal(argptr, "ALL")) {
+      /* clear all cookies */
+      Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+      Curl_cookie_clearall(data->cookies);
+      Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+    }
+    else if(Curl_raw_equal(argptr, "SESS")) {
+      /* clear session cookies */
+      Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+      Curl_cookie_clearsess(data->cookies);
+      Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+    }
+    else if(Curl_raw_equal(argptr, "FLUSH")) {
+      /* flush cookies to file, takes care of the locking */
+      Curl_flush_cookies(data, 0);
+    }
+    else if(Curl_raw_equal(argptr, "RELOAD")) {
+      /* reload cookies from file */
+      Curl_cookie_loadfiles(data);
+      break;
+    }
+    else {
+      if(!data->cookies)
+        /* if cookie engine was not running, activate it */
+        data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
+
+      argptr = strdup(argptr);
+      if(!argptr || !data->cookies) {
+        result = CURLE_OUT_OF_MEMORY;
+        free(argptr);
+      }
+      else {
+        Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+
+        if(checkprefix("Set-Cookie:", argptr))
+          /* HTTP Header format line */
+          Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
+
+        else
+          /* Netscape format line */
+          Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
+
+        Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+        free(argptr);
+      }
+    }
+
+    break;
+#endif /* CURL_DISABLE_COOKIES */
+
+  case CURLOPT_HTTPGET:
+    /*
+     * Set to force us do HTTP GET
+     */
+    if(va_arg(param, long)) {
+      data->set.httpreq = HTTPREQ_GET;
+      data->set.upload = FALSE; /* switch off upload */
+      data->set.opt_no_body = FALSE; /* this is implied */
+    }
+    break;
+
+  case CURLOPT_HTTP_VERSION:
+    /*
+     * This sets a requested HTTP version to be used. The value is one of
+     * the listed enums in curl/curl.h.
+     */
+    arg = va_arg(param, long);
+#ifndef USE_NGHTTP2
+    if(arg >= CURL_HTTP_VERSION_2)
+      return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+    data->set.httpversion = arg;
+    break;
+
+  case CURLOPT_HTTPAUTH:
+    /*
+     * Set HTTP Authentication type BITMASK.
+     */
+  {
+    int bitcheck;
+    bool authbits;
+    unsigned long auth = va_arg(param, unsigned long);
+
+    if(auth == CURLAUTH_NONE) {
+      data->set.httpauth = auth;
+      break;
+    }
+
+    /* the DIGEST_IE bit is only used to set a special marker, for all the
+       rest we need to handle it as normal DIGEST */
+    data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
+
+    if(auth & CURLAUTH_DIGEST_IE) {
+      auth |= CURLAUTH_DIGEST; /* set standard digest bit */
+      auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
+    }
+
+    /* switch off bits we can't support */
+#ifndef USE_NTLM
+    auth &= ~CURLAUTH_NTLM;    /* no NTLM support */
+    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
+#elif !defined(NTLM_WB_ENABLED)
+    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
+#endif
+#ifndef USE_SPNEGO
+    auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
+                                    GSS-API or SSPI */
+#endif
+
+    /* check if any auth bit lower than CURLAUTH_ONLY is still set */
+    bitcheck = 0;
+    authbits = FALSE;
+    while(bitcheck < 31) {
+      if(auth & (1UL << bitcheck++)) {
+        authbits = TRUE;
+        break;
+      }
+    }
+    if(!authbits)
+      return CURLE_NOT_BUILT_IN; /* no supported types left! */
+
+    data->set.httpauth = auth;
+  }
+  break;
+
+  case CURLOPT_EXPECT_100_TIMEOUT_MS:
+    /*
+     * Time to wait for a response to a HTTP request containing an
+     * Expect: 100-continue header before sending the data anyway.
+     */
+    data->set.expect_100_timeout = va_arg(param, long);
+    break;
+
+#endif   /* CURL_DISABLE_HTTP */
+
+  case CURLOPT_CUSTOMREQUEST:
+    /*
+     * Set a custom string to use as request
+     */
+    result = setstropt(&data->set.str[STRING_CUSTOMREQUEST],
+                       va_arg(param, char *));
+
+    /* we don't set
+       data->set.httpreq = HTTPREQ_CUSTOM;
+       here, we continue as if we were using the already set type
+       and this just changes the actual request keyword */
+    break;
+
+#ifndef CURL_DISABLE_PROXY
+  case CURLOPT_HTTPPROXYTUNNEL:
+    /*
+     * Tunnel operations through the proxy instead of normal proxy use
+     */
+    data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_PROXYPORT:
+    /*
+     * Explicitly set HTTP proxy port number.
+     */
+    data->set.proxyport = va_arg(param, long);
+    break;
+
+  case CURLOPT_PROXYAUTH:
+    /*
+     * Set HTTP Authentication type BITMASK.
+     */
+  {
+    int bitcheck;
+    bool authbits;
+    unsigned long auth = va_arg(param, unsigned long);
+
+    if(auth == CURLAUTH_NONE) {
+      data->set.proxyauth = auth;
+      break;
+    }
+
+    /* the DIGEST_IE bit is only used to set a special marker, for all the
+       rest we need to handle it as normal DIGEST */
+    data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
+
+    if(auth & CURLAUTH_DIGEST_IE) {
+      auth |= CURLAUTH_DIGEST; /* set standard digest bit */
+      auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
+    }
+    /* switch off bits we can't support */
+#ifndef USE_NTLM
+    auth &= ~CURLAUTH_NTLM;    /* no NTLM support */
+    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
+#elif !defined(NTLM_WB_ENABLED)
+    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
+#endif
+#ifndef USE_SPNEGO
+    auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
+                                    GSS-API or SSPI */
+#endif
+
+    /* check if any auth bit lower than CURLAUTH_ONLY is still set */
+    bitcheck = 0;
+    authbits = FALSE;
+    while(bitcheck < 31) {
+      if(auth & (1UL << bitcheck++)) {
+        authbits = TRUE;
+        break;
+      }
+    }
+    if(!authbits)
+      return CURLE_NOT_BUILT_IN; /* no supported types left! */
+
+    data->set.proxyauth = auth;
+  }
+  break;
+
+  case CURLOPT_PROXY:
+    /*
+     * Set proxy server:port to use as HTTP proxy.
+     *
+     * If the proxy is set to "" we explicitly say that we don't want to use a
+     * proxy (even though there might be environment variables saying so).
+     *
+     * Setting it to NULL, means no proxy but allows the environment variables
+     * to decide for us.
+     */
+    result = setstropt(&data->set.str[STRING_PROXY],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_PROXYTYPE:
+    /*
+     * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
+     */
+    data->set.proxytype = (curl_proxytype)va_arg(param, long);
+    break;
+
+  case CURLOPT_PROXY_TRANSFER_MODE:
+    /*
+     * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
+     */
+    switch (va_arg(param, long)) {
+    case 0:
+      data->set.proxy_transfer_mode = FALSE;
+      break;
+    case 1:
+      data->set.proxy_transfer_mode = TRUE;
+      break;
+    default:
+      /* reserve other values for future use */
+      result = CURLE_UNKNOWN_OPTION;
+      break;
+    }
+    break;
+#endif   /* CURL_DISABLE_PROXY */
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  case CURLOPT_SOCKS5_GSSAPI_SERVICE:
+    /*
+     * Set GSS-API service name
+     */
+    result = setstropt(&data->set.str[STRING_SOCKS5_GSSAPI_SERVICE],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_PROXY_SERVICE_NAME:
+    /*
+     * Set negotiate proxy service name
+     */
+    result = setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_SOCKS5_GSSAPI_NEC:
+    /*
+     * set flag for nec socks5 support
+     */
+    data->set.socks5_gssapi_nec = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_SERVICE_NAME:
+    /*
+     * Set negotiate service identity
+     */
+    result = setstropt(&data->set.str[STRING_SERVICE_NAME],
+                       va_arg(param, char *));
+    break;
+
+#endif
+
+  case CURLOPT_HEADERDATA:
+    /*
+     * Custom pointer to pass the header write callback function
+     */
+    data->set.writeheader = (void *)va_arg(param, void *);
+    break;
+  case CURLOPT_ERRORBUFFER:
+    /*
+     * Error buffer provided by the caller to get the human readable
+     * error string in.
+     */
+    data->set.errorbuffer = va_arg(param, char *);
+    break;
+  case CURLOPT_WRITEDATA:
+    /*
+     * FILE pointer to write to. Or possibly
+     * used as argument to the write callback.
+     */
+    data->set.out = va_arg(param, void *);
+    break;
+  case CURLOPT_FTPPORT:
+    /*
+     * Use FTP PORT, this also specifies which IP address to use
+     */
+    result = setstropt(&data->set.str[STRING_FTPPORT],
+                       va_arg(param, char *));
+    data->set.ftp_use_port = (NULL != data->set.str[STRING_FTPPORT]) ?
+                             TRUE:FALSE;
+    break;
+
+  case CURLOPT_FTP_USE_EPRT:
+    data->set.ftp_use_eprt = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_FTP_USE_EPSV:
+    data->set.ftp_use_epsv = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_FTP_USE_PRET:
+    data->set.ftp_use_pret = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_FTP_SSL_CCC:
+    data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long);
+    break;
+
+  case CURLOPT_FTP_SKIP_PASV_IP:
+    /*
+     * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
+     * bypass of the IP address in PASV responses.
+     */
+    data->set.ftp_skip_ip = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_READDATA:
+    /*
+     * FILE pointer to read the file to be uploaded from. Or possibly
+     * used as argument to the read callback.
+     */
+    data->set.in_set = va_arg(param, void *);
+    break;
+  case CURLOPT_INFILESIZE:
+    /*
+     * If known, this should inform curl about the file size of the
+     * to-be-uploaded file.
+     */
+    data->set.filesize = va_arg(param, long);
+    break;
+  case CURLOPT_INFILESIZE_LARGE:
+    /*
+     * If known, this should inform curl about the file size of the
+     * to-be-uploaded file.
+     */
+    data->set.filesize = va_arg(param, curl_off_t);
+    break;
+  case CURLOPT_LOW_SPEED_LIMIT:
+    /*
+     * The low speed limit that if transfers are below this for
+     * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
+     */
+    data->set.low_speed_limit=va_arg(param, long);
+    break;
+  case CURLOPT_MAX_SEND_SPEED_LARGE:
+    /*
+     * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
+     * bytes per second the transfer is throttled..
+     */
+    data->set.max_send_speed=va_arg(param, curl_off_t);
+    break;
+  case CURLOPT_MAX_RECV_SPEED_LARGE:
+    /*
+     * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
+     * second the transfer is throttled..
+     */
+    data->set.max_recv_speed=va_arg(param, curl_off_t);
+    break;
+  case CURLOPT_LOW_SPEED_TIME:
+    /*
+     * The low speed time that if transfers are below the set
+     * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
+     */
+    data->set.low_speed_time=va_arg(param, long);
+    break;
+  case CURLOPT_URL:
+    /*
+     * The URL to fetch.
+     */
+    if(data->change.url_alloc) {
+      /* the already set URL is allocated, free it first! */
+      Curl_safefree(data->change.url);
+      data->change.url_alloc = FALSE;
+    }
+    result = setstropt(&data->set.str[STRING_SET_URL],
+                       va_arg(param, char *));
+    data->change.url = data->set.str[STRING_SET_URL];
+    break;
+  case CURLOPT_PORT:
+    /*
+     * The port number to use when getting the URL
+     */
+    data->set.use_port = va_arg(param, long);
+    break;
+  case CURLOPT_TIMEOUT:
+    /*
+     * The maximum time you allow curl to use for a single transfer
+     * operation.
+     */
+    data->set.timeout = va_arg(param, long) * 1000L;
+    break;
+
+  case CURLOPT_TIMEOUT_MS:
+    data->set.timeout = va_arg(param, long);
+    break;
+
+  case CURLOPT_CONNECTTIMEOUT:
+    /*
+     * The maximum time you allow curl to use to connect.
+     */
+    data->set.connecttimeout = va_arg(param, long) * 1000L;
+    break;
+
+  case CURLOPT_CONNECTTIMEOUT_MS:
+    data->set.connecttimeout = va_arg(param, long);
+    break;
+
+  case CURLOPT_ACCEPTTIMEOUT_MS:
+    /*
+     * The maximum time you allow curl to wait for server connect
+     */
+    data->set.accepttimeout = va_arg(param, long);
+    break;
+
+  case CURLOPT_USERPWD:
+    /*
+     * user:password to use in the operation
+     */
+    result = setstropt_userpwd(va_arg(param, char *),
+                               &data->set.str[STRING_USERNAME],
+                               &data->set.str[STRING_PASSWORD]);
+    break;
+
+  case CURLOPT_USERNAME:
+    /*
+     * authentication user name to use in the operation
+     */
+    result = setstropt(&data->set.str[STRING_USERNAME],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_PASSWORD:
+    /*
+     * authentication password to use in the operation
+     */
+    result = setstropt(&data->set.str[STRING_PASSWORD],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_LOGIN_OPTIONS:
+    /*
+     * authentication options to use in the operation
+     */
+    result = setstropt(&data->set.str[STRING_OPTIONS],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_XOAUTH2_BEARER:
+    /*
+     * OAuth 2.0 bearer token to use in the operation
+     */
+    result = setstropt(&data->set.str[STRING_BEARER],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_POSTQUOTE:
+    /*
+     * List of RAW FTP commands to use after a transfer
+     */
+    data->set.postquote = va_arg(param, struct curl_slist *);
+    break;
+  case CURLOPT_PREQUOTE:
+    /*
+     * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
+     */
+    data->set.prequote = va_arg(param, struct curl_slist *);
+    break;
+  case CURLOPT_QUOTE:
+    /*
+     * List of RAW FTP commands to use before a transfer
+     */
+    data->set.quote = va_arg(param, struct curl_slist *);
+    break;
+  case CURLOPT_RESOLVE:
+    /*
+     * List of NAME:[address] names to populate the DNS cache with
+     * Prefix the NAME with dash (-) to _remove_ the name from the cache.
+     *
+     * Names added with this API will remain in the cache until explicitly
+     * removed or the handle is cleaned up.
+     *
+     * This API can remove any name from the DNS cache, but only entries
+     * that aren't actually in use right now will be pruned immediately.
+     */
+    data->set.resolve = va_arg(param, struct curl_slist *);
+    data->change.resolve = data->set.resolve;
+    break;
+  case CURLOPT_PROGRESSFUNCTION:
+    /*
+     * Progress callback function
+     */
+    data->set.fprogress = va_arg(param, curl_progress_callback);
+    if(data->set.fprogress)
+      data->progress.callback = TRUE; /* no longer internal */
+    else
+      data->progress.callback = FALSE; /* NULL enforces internal */
+    break;
+
+  case CURLOPT_XFERINFOFUNCTION:
+    /*
+     * Transfer info callback function
+     */
+    data->set.fxferinfo = va_arg(param, curl_xferinfo_callback);
+    if(data->set.fxferinfo)
+      data->progress.callback = TRUE; /* no longer internal */
+    else
+      data->progress.callback = FALSE; /* NULL enforces internal */
+
+    break;
+
+  case CURLOPT_PROGRESSDATA:
+    /*
+     * Custom client data to pass to the progress callback
+     */
+    data->set.progress_client = va_arg(param, void *);
+    break;
+
+#ifndef CURL_DISABLE_PROXY
+  case CURLOPT_PROXYUSERPWD:
+    /*
+     * user:password needed to use the proxy
+     */
+    result = setstropt_userpwd(va_arg(param, char *),
+                               &data->set.str[STRING_PROXYUSERNAME],
+                               &data->set.str[STRING_PROXYPASSWORD]);
+    break;
+  case CURLOPT_PROXYUSERNAME:
+    /*
+     * authentication user name to use in the operation
+     */
+    result = setstropt(&data->set.str[STRING_PROXYUSERNAME],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_PROXYPASSWORD:
+    /*
+     * authentication password to use in the operation
+     */
+    result = setstropt(&data->set.str[STRING_PROXYPASSWORD],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_NOPROXY:
+    /*
+     * proxy exception list
+     */
+    result = setstropt(&data->set.str[STRING_NOPROXY],
+                       va_arg(param, char *));
+    break;
+#endif
+
+  case CURLOPT_RANGE:
+    /*
+     * What range of the file you want to transfer
+     */
+    result = setstropt(&data->set.str[STRING_SET_RANGE],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_RESUME_FROM:
+    /*
+     * Resume transfer at the give file position
+     */
+    data->set.set_resume_from = va_arg(param, long);
+    break;
+  case CURLOPT_RESUME_FROM_LARGE:
+    /*
+     * Resume transfer at the give file position
+     */
+    data->set.set_resume_from = va_arg(param, curl_off_t);
+    break;
+  case CURLOPT_DEBUGFUNCTION:
+    /*
+     * stderr write callback.
+     */
+    data->set.fdebug = va_arg(param, curl_debug_callback);
+    /*
+     * if the callback provided is NULL, it'll use the default callback
+     */
+    break;
+  case CURLOPT_DEBUGDATA:
+    /*
+     * Set to a void * that should receive all error writes. This
+     * defaults to CURLOPT_STDERR for normal operations.
+     */
+    data->set.debugdata = va_arg(param, void *);
+    break;
+  case CURLOPT_STDERR:
+    /*
+     * Set to a FILE * that should receive all error writes. This
+     * defaults to stderr for normal operations.
+     */
+    data->set.err = va_arg(param, FILE *);
+    if(!data->set.err)
+      data->set.err = stderr;
+    break;
+  case CURLOPT_HEADERFUNCTION:
+    /*
+     * Set header write callback
+     */
+    data->set.fwrite_header = va_arg(param, curl_write_callback);
+    break;
+  case CURLOPT_WRITEFUNCTION:
+    /*
+     * Set data write callback
+     */
+    data->set.fwrite_func = va_arg(param, curl_write_callback);
+    if(!data->set.fwrite_func) {
+      data->set.is_fwrite_set = 0;
+      /* When set to NULL, reset to our internal default function */
+      data->set.fwrite_func = (curl_write_callback)fwrite;
+    }
+    else
+      data->set.is_fwrite_set = 1;
+    break;
+  case CURLOPT_READFUNCTION:
+    /*
+     * Read data callback
+     */
+    data->set.fread_func_set = va_arg(param, curl_read_callback);
+    if(!data->set.fread_func_set) {
+      data->set.is_fread_set = 0;
+      /* When set to NULL, reset to our internal default function */
+      data->set.fread_func_set = (curl_read_callback)fread;
+    }
+    else
+      data->set.is_fread_set = 1;
+    break;
+  case CURLOPT_SEEKFUNCTION:
+    /*
+     * Seek callback. Might be NULL.
+     */
+    data->set.seek_func = va_arg(param, curl_seek_callback);
+    break;
+  case CURLOPT_SEEKDATA:
+    /*
+     * Seek control callback. Might be NULL.
+     */
+    data->set.seek_client = va_arg(param, void *);
+    break;
+  case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
+    /*
+     * "Convert from network encoding" callback
+     */
+    data->set.convfromnetwork = va_arg(param, curl_conv_callback);
+    break;
+  case CURLOPT_CONV_TO_NETWORK_FUNCTION:
+    /*
+     * "Convert to network encoding" callback
+     */
+    data->set.convtonetwork = va_arg(param, curl_conv_callback);
+    break;
+  case CURLOPT_CONV_FROM_UTF8_FUNCTION:
+    /*
+     * "Convert from UTF-8 encoding" callback
+     */
+    data->set.convfromutf8 = va_arg(param, curl_conv_callback);
+    break;
+  case CURLOPT_IOCTLFUNCTION:
+    /*
+     * I/O control callback. Might be NULL.
+     */
+    data->set.ioctl_func = va_arg(param, curl_ioctl_callback);
+    break;
+  case CURLOPT_IOCTLDATA:
+    /*
+     * I/O control data pointer. Might be NULL.
+     */
+    data->set.ioctl_client = va_arg(param, void *);
+    break;
+  case CURLOPT_SSLCERT:
+    /*
+     * String that holds file name of the SSL certificate to use
+     */
+    result = setstropt(&data->set.str[STRING_CERT],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_SSLCERTTYPE:
+    /*
+     * String that holds file type of the SSL certificate to use
+     */
+    result = setstropt(&data->set.str[STRING_CERT_TYPE],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_SSLKEY:
+    /*
+     * String that holds file name of the SSL key to use
+     */
+    result = setstropt(&data->set.str[STRING_KEY],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_SSLKEYTYPE:
+    /*
+     * String that holds file type of the SSL key to use
+     */
+    result = setstropt(&data->set.str[STRING_KEY_TYPE],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_KEYPASSWD:
+    /*
+     * String that holds the SSL or SSH private key password.
+     */
+    result = setstropt(&data->set.str[STRING_KEY_PASSWD],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_SSLENGINE:
+    /*
+     * String that holds the SSL crypto engine.
+     */
+    argptr = va_arg(param, char *);
+    if(argptr && argptr[0])
+      result = Curl_ssl_set_engine(data, argptr);
+    break;
+
+  case CURLOPT_SSLENGINE_DEFAULT:
+    /*
+     * flag to set engine as default.
+     */
+    result = Curl_ssl_set_engine_default(data);
+    break;
+  case CURLOPT_CRLF:
+    /*
+     * Kludgy option to enable CRLF conversions. Subject for removal.
+     */
+    data->set.crlf = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_INTERFACE:
+    /*
+     * Set what interface or address/hostname to bind the socket to when
+     * performing an operation and thus what from-IP your connection will use.
+     */
+    result = setstropt(&data->set.str[STRING_DEVICE],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_LOCALPORT:
+    /*
+     * Set what local port to bind the socket to when performing an operation.
+     */
+    data->set.localport = curlx_sltous(va_arg(param, long));
+    break;
+  case CURLOPT_LOCALPORTRANGE:
+    /*
+     * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
+     */
+    data->set.localportrange = curlx_sltosi(va_arg(param, long));
+    break;
+  case CURLOPT_KRBLEVEL:
+    /*
+     * A string that defines the kerberos security level.
+     */
+    result = setstropt(&data->set.str[STRING_KRB_LEVEL],
+                       va_arg(param, char *));
+    data->set.krb = (NULL != data->set.str[STRING_KRB_LEVEL])?TRUE:FALSE;
+    break;
+  case CURLOPT_GSSAPI_DELEGATION:
+    /*
+     * GSS-API credential delegation
+     */
+    data->set.gssapi_delegation = va_arg(param, long);
+    break;
+  case CURLOPT_SSL_VERIFYPEER:
+    /*
+     * Enable peer SSL verifying.
+     */
+    data->set.ssl.verifypeer = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_SSL_VERIFYHOST:
+    /*
+     * Enable verification of the host name in the peer certificate
+     */
+    arg = va_arg(param, long);
+
+    /* Obviously people are not reading documentation and too many thought
+       this argument took a boolean when it wasn't and misused it. We thus ban
+       1 as a sensible input and we warn about its use. Then we only have the
+       2 action internally stored as TRUE. */
+
+    if(1 == arg) {
+      failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+
+    data->set.ssl.verifyhost = (0 != arg)?TRUE:FALSE;
+    break;
+  case CURLOPT_SSL_VERIFYSTATUS:
+    /*
+     * Enable certificate status verifying.
+     */
+    if(!Curl_ssl_cert_status_request()) {
+      result = CURLE_NOT_BUILT_IN;
+      break;
+    }
+
+    data->set.ssl.verifystatus = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_SSL_CTX_FUNCTION:
+#ifdef have_curlssl_ssl_ctx
+    /*
+     * Set a SSL_CTX callback
+     */
+    data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
+#else
+    result = CURLE_NOT_BUILT_IN;
+#endif
+    break;
+  case CURLOPT_SSL_CTX_DATA:
+#ifdef have_curlssl_ssl_ctx
+    /*
+     * Set a SSL_CTX callback parameter pointer
+     */
+    data->set.ssl.fsslctxp = va_arg(param, void *);
+#else
+    result = CURLE_NOT_BUILT_IN;
+#endif
+    break;
+  case CURLOPT_SSL_FALSESTART:
+    /*
+     * Enable TLS false start.
+     */
+    if(!Curl_ssl_false_start()) {
+      result = CURLE_NOT_BUILT_IN;
+      break;
+    }
+
+    data->set.ssl.falsestart = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_CERTINFO:
+#ifdef have_curlssl_certinfo
+    data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;
+#else
+    result = CURLE_NOT_BUILT_IN;
+#endif
+    break;
+  case CURLOPT_PINNEDPUBLICKEY:
+    /*
+     * Set pinned public key for SSL connection.
+     * Specify file name of the public key in DER format.
+     */
+    result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_CAINFO:
+    /*
+     * Set CA info for SSL connection. Specify file name of the CA certificate
+     */
+    result = setstropt(&data->set.str[STRING_SSL_CAFILE],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_CAPATH:
+#ifdef have_curlssl_ca_path /* not supported by all backends */
+    /*
+     * Set CA path info for SSL connection. Specify directory name of the CA
+     * certificates which have been prepared using openssl c_rehash utility.
+     */
+    /* This does not work on windows. */
+    result = setstropt(&data->set.str[STRING_SSL_CAPATH],
+                       va_arg(param, char *));
+#else
+    result = CURLE_NOT_BUILT_IN;
+#endif
+    break;
+  case CURLOPT_CRLFILE:
+    /*
+     * Set CRL file info for SSL connection. Specify file name of the CRL
+     * to check certificates revocation
+     */
+    result = setstropt(&data->set.str[STRING_SSL_CRLFILE],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_ISSUERCERT:
+    /*
+     * Set Issuer certificate file
+     * to check certificates issuer
+     */
+    result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_TELNETOPTIONS:
+    /*
+     * Set a linked list of telnet options
+     */
+    data->set.telnet_options = va_arg(param, struct curl_slist *);
+    break;
+
+  case CURLOPT_BUFFERSIZE:
+    /*
+     * The application kindly asks for a differently sized receive buffer.
+     * If it seems reasonable, we'll use it.
+     */
+    data->set.buffer_size = va_arg(param, long);
+
+    if((data->set.buffer_size> (BUFSIZE -1 )) ||
+       (data->set.buffer_size < 1))
+      data->set.buffer_size = 0; /* huge internal default */
+
+    break;
+
+  case CURLOPT_NOSIGNAL:
+    /*
+     * The application asks not to set any signal() or alarm() handlers,
+     * even when using a timeout.
+     */
+    data->set.no_signal = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_SHARE:
+  {
+    struct Curl_share *set;
+    set = va_arg(param, struct Curl_share *);
+
+    /* disconnect from old share, if any */
+    if(data->share) {
+      Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
+
+      if(data->dns.hostcachetype == HCACHE_SHARED) {
+        data->dns.hostcache = NULL;
+        data->dns.hostcachetype = HCACHE_NONE;
+      }
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+      if(data->share->cookies == data->cookies)
+        data->cookies = NULL;
+#endif
+
+      if(data->share->sslsession == data->state.session)
+        data->state.session = NULL;
+
+      data->share->dirty--;
+
+      Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
+      data->share = NULL;
+    }
+
+    /* use new share if it set */
+    data->share = set;
+    if(data->share) {
+
+      Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
+
+      data->share->dirty++;
+
+      if(data->share->specifier & (1<< CURL_LOCK_DATA_DNS)) {
+        /* use shared host cache */
+        data->dns.hostcache = &data->share->hostcache;
+        data->dns.hostcachetype = HCACHE_SHARED;
+      }
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+      if(data->share->cookies) {
+        /* use shared cookie list, first free own one if any */
+        Curl_cookie_cleanup(data->cookies);
+        /* enable cookies since we now use a share that uses cookies! */
+        data->cookies = data->share->cookies;
+      }
+#endif   /* CURL_DISABLE_HTTP */
+      if(data->share->sslsession) {
+        data->set.ssl.max_ssl_sessions = data->share->max_ssl_sessions;
+        data->state.session = data->share->sslsession;
+      }
+      Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
+
+    }
+    /* check for host cache not needed,
+     * it will be done by curl_easy_perform */
+  }
+  break;
+
+  case CURLOPT_PRIVATE:
+    /*
+     * Set private data pointer.
+     */
+    data->set.private_data = va_arg(param, void *);
+    break;
+
+  case CURLOPT_MAXFILESIZE:
+    /*
+     * Set the maximum size of a file to download.
+     */
+    data->set.max_filesize = va_arg(param, long);
+    break;
+
+#ifdef USE_SSL
+  case CURLOPT_USE_SSL:
+    /*
+     * Make transfers attempt to use SSL/TLS.
+     */
+    data->set.use_ssl = (curl_usessl)va_arg(param, long);
+    break;
+
+  case CURLOPT_SSL_OPTIONS:
+    arg = va_arg(param, long);
+    data->set.ssl_enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST);
+    data->set.ssl_no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
+    break;
+
+#endif
+  case CURLOPT_FTPSSLAUTH:
+    /*
+     * Set a specific auth for FTP-SSL transfers.
+     */
+    data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
+    break;
+
+  case CURLOPT_IPRESOLVE:
+    data->set.ipver = va_arg(param, long);
+    break;
+
+  case CURLOPT_MAXFILESIZE_LARGE:
+    /*
+     * Set the maximum size of a file to download.
+     */
+    data->set.max_filesize = va_arg(param, curl_off_t);
+    break;
+
+  case CURLOPT_TCP_NODELAY:
+    /*
+     * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
+     * algorithm
+     */
+    data->set.tcp_nodelay = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_FTP_ACCOUNT:
+    result = setstropt(&data->set.str[STRING_FTP_ACCOUNT],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_IGNORE_CONTENT_LENGTH:
+    data->set.ignorecl = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_CONNECT_ONLY:
+    /*
+     * No data transfer, set up connection and let application use the socket
+     */
+    data->set.connect_only = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_FTP_ALTERNATIVE_TO_USER:
+    result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_SOCKOPTFUNCTION:
+    /*
+     * socket callback function: called after socket() but before connect()
+     */
+    data->set.fsockopt = va_arg(param, curl_sockopt_callback);
+    break;
+
+  case CURLOPT_SOCKOPTDATA:
+    /*
+     * socket callback data pointer. Might be NULL.
+     */
+    data->set.sockopt_client = va_arg(param, void *);
+    break;
+
+  case CURLOPT_OPENSOCKETFUNCTION:
+    /*
+     * open/create socket callback function: called instead of socket(),
+     * before connect()
+     */
+    data->set.fopensocket = va_arg(param, curl_opensocket_callback);
+    break;
+
+  case CURLOPT_OPENSOCKETDATA:
+    /*
+     * socket callback data pointer. Might be NULL.
+     */
+    data->set.opensocket_client = va_arg(param, void *);
+    break;
+
+  case CURLOPT_CLOSESOCKETFUNCTION:
+    /*
+     * close socket callback function: called instead of close()
+     * when shutting down a connection
+     */
+    data->set.fclosesocket = va_arg(param, curl_closesocket_callback);
+    break;
+
+  case CURLOPT_CLOSESOCKETDATA:
+    /*
+     * socket callback data pointer. Might be NULL.
+     */
+    data->set.closesocket_client = va_arg(param, void *);
+    break;
+
+  case CURLOPT_SSL_SESSIONID_CACHE:
+    data->set.ssl.sessionid = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+#ifdef USE_LIBSSH2
+    /* we only include SSH options if explicitly built to support SSH */
+  case CURLOPT_SSH_AUTH_TYPES:
+    data->set.ssh_auth_types = va_arg(param, long);
+    break;
+
+  case CURLOPT_SSH_PUBLIC_KEYFILE:
+    /*
+     * Use this file instead of the $HOME/.ssh/id_dsa.pub file
+     */
+    result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_SSH_PRIVATE_KEYFILE:
+    /*
+     * Use this file instead of the $HOME/.ssh/id_dsa file
+     */
+    result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
+    /*
+     * Option to allow for the MD5 of the host public key to be checked
+     * for validation purposes.
+     */
+    result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
+                       va_arg(param, char *));
+    break;
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+  case CURLOPT_SSH_KNOWNHOSTS:
+    /*
+     * Store the file name to read known hosts from.
+     */
+    result = setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_SSH_KEYFUNCTION:
+    /* setting to NULL is fine since the ssh.c functions themselves will
+       then rever to use the internal default */
+    data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
+    break;
+
+  case CURLOPT_SSH_KEYDATA:
+    /*
+     * Custom client data to pass to the SSH keyfunc callback
+     */
+    data->set.ssh_keyfunc_userp = va_arg(param, void *);
+    break;
+#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
+
+#endif /* USE_LIBSSH2 */
+
+  case CURLOPT_HTTP_TRANSFER_DECODING:
+    /*
+     * disable libcurl transfer encoding is used
+     */
+    data->set.http_te_skip = (0 == va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_HTTP_CONTENT_DECODING:
+    /*
+     * raw data passed to the application when content encoding is used
+     */
+    data->set.http_ce_skip = (0 == va_arg(param, long))?TRUE:FALSE;
+    break;
+
+  case CURLOPT_NEW_FILE_PERMS:
+    /*
+     * Uses these permissions instead of 0644
+     */
+    data->set.new_file_perms = va_arg(param, long);
+    break;
+
+  case CURLOPT_NEW_DIRECTORY_PERMS:
+    /*
+     * Uses these permissions instead of 0755
+     */
+    data->set.new_directory_perms = va_arg(param, long);
+    break;
+
+  case CURLOPT_ADDRESS_SCOPE:
+    /*
+     * We always get longs when passed plain numericals, but for this value we
+     * know that an unsigned int will always hold the value so we blindly
+     * typecast to this type
+     */
+    data->set.scope_id = curlx_sltoui(va_arg(param, long));
+    break;
+
+  case CURLOPT_PROTOCOLS:
+    /* set the bitmask for the protocols that are allowed to be used for the
+       transfer, which thus helps the app which takes URLs from users or other
+       external inputs and want to restrict what protocol(s) to deal
+       with. Defaults to CURLPROTO_ALL. */
+    data->set.allowed_protocols = va_arg(param, long);
+    break;
+
+  case CURLOPT_REDIR_PROTOCOLS:
+    /* set the bitmask for the protocols that libcurl is allowed to follow to,
+       as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+       to be set in both bitmasks to be allowed to get redirected to. Defaults
+       to all protocols except FILE and SCP. */
+    data->set.redir_protocols = va_arg(param, long);
+    break;
+
+  case CURLOPT_DEFAULT_PROTOCOL:
+    /* Set the protocol to use when the URL doesn't include any protocol */
+    result = setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_MAIL_FROM:
+    /* Set the SMTP mail originator */
+    result = setstropt(&data->set.str[STRING_MAIL_FROM],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_MAIL_AUTH:
+    /* Set the SMTP auth originator */
+    result = setstropt(&data->set.str[STRING_MAIL_AUTH],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_MAIL_RCPT:
+    /* Set the list of mail recipients */
+    data->set.mail_rcpt = va_arg(param, struct curl_slist *);
+    break;
+
+  case CURLOPT_SASL_IR:
+    /* Enable/disable SASL initial response */
+    data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_RTSP_REQUEST:
+    {
+      /*
+       * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
+       * Would this be better if the RTSPREQ_* were just moved into here?
+       */
+      long curl_rtspreq = va_arg(param, long);
+      Curl_RtspReq rtspreq = RTSPREQ_NONE;
+      switch(curl_rtspreq) {
+        case CURL_RTSPREQ_OPTIONS:
+          rtspreq = RTSPREQ_OPTIONS;
+          break;
+
+        case CURL_RTSPREQ_DESCRIBE:
+          rtspreq = RTSPREQ_DESCRIBE;
+          break;
+
+        case CURL_RTSPREQ_ANNOUNCE:
+          rtspreq = RTSPREQ_ANNOUNCE;
+          break;
+
+        case CURL_RTSPREQ_SETUP:
+          rtspreq = RTSPREQ_SETUP;
+          break;
+
+        case CURL_RTSPREQ_PLAY:
+          rtspreq = RTSPREQ_PLAY;
+          break;
+
+        case CURL_RTSPREQ_PAUSE:
+          rtspreq = RTSPREQ_PAUSE;
+          break;
+
+        case CURL_RTSPREQ_TEARDOWN:
+          rtspreq = RTSPREQ_TEARDOWN;
+          break;
+
+        case CURL_RTSPREQ_GET_PARAMETER:
+          rtspreq = RTSPREQ_GET_PARAMETER;
+          break;
+
+        case CURL_RTSPREQ_SET_PARAMETER:
+          rtspreq = RTSPREQ_SET_PARAMETER;
+          break;
+
+        case CURL_RTSPREQ_RECORD:
+          rtspreq = RTSPREQ_RECORD;
+          break;
+
+        case CURL_RTSPREQ_RECEIVE:
+          rtspreq = RTSPREQ_RECEIVE;
+          break;
+        default:
+          rtspreq = RTSPREQ_NONE;
+      }
+
+      data->set.rtspreq = rtspreq;
+    break;
+    }
+
+
+  case CURLOPT_RTSP_SESSION_ID:
+    /*
+     * Set the RTSP Session ID manually. Useful if the application is
+     * resuming a previously established RTSP session
+     */
+    result = setstropt(&data->set.str[STRING_RTSP_SESSION_ID],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_RTSP_STREAM_URI:
+    /*
+     * Set the Stream URI for the RTSP request. Unless the request is
+     * for generic server options, the application will need to set this.
+     */
+    result = setstropt(&data->set.str[STRING_RTSP_STREAM_URI],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_RTSP_TRANSPORT:
+    /*
+     * The content of the Transport: header for the RTSP request
+     */
+    result = setstropt(&data->set.str[STRING_RTSP_TRANSPORT],
+                       va_arg(param, char *));
+    break;
+
+  case CURLOPT_RTSP_CLIENT_CSEQ:
+    /*
+     * Set the CSEQ number to issue for the next RTSP request. Useful if the
+     * application is resuming a previously broken connection. The CSEQ
+     * will increment from this new number henceforth.
+     */
+    data->state.rtsp_next_client_CSeq = va_arg(param, long);
+    break;
+
+  case CURLOPT_RTSP_SERVER_CSEQ:
+    /* Same as the above, but for server-initiated requests */
+    data->state.rtsp_next_client_CSeq = va_arg(param, long);
+    break;
+
+  case CURLOPT_INTERLEAVEDATA:
+    data->set.rtp_out = va_arg(param, void *);
+    break;
+  case CURLOPT_INTERLEAVEFUNCTION:
+    /* Set the user defined RTP write function */
+    data->set.fwrite_rtp = va_arg(param, curl_write_callback);
+    break;
+
+  case CURLOPT_WILDCARDMATCH:
+    data->set.wildcardmatch = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_CHUNK_BGN_FUNCTION:
+    data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
+    break;
+  case CURLOPT_CHUNK_END_FUNCTION:
+    data->set.chunk_end = va_arg(param, curl_chunk_end_callback);
+    break;
+  case CURLOPT_FNMATCH_FUNCTION:
+    data->set.fnmatch = va_arg(param, curl_fnmatch_callback);
+    break;
+  case CURLOPT_CHUNK_DATA:
+    data->wildcard.customptr = va_arg(param, void *);
+    break;
+  case CURLOPT_FNMATCH_DATA:
+    data->set.fnmatch_data = va_arg(param, void *);
+    break;
+#ifdef USE_TLS_SRP
+  case CURLOPT_TLSAUTH_USERNAME:
+    result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME],
+                       va_arg(param, char *));
+    if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
+      data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+    break;
+  case CURLOPT_TLSAUTH_PASSWORD:
+    result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD],
+                       va_arg(param, char *));
+    if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
+      data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+    break;
+  case CURLOPT_TLSAUTH_TYPE:
+    if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP")))
+      data->set.ssl.authtype = CURL_TLSAUTH_SRP;
+    else
+      data->set.ssl.authtype = CURL_TLSAUTH_NONE;
+    break;
+#endif
+  case CURLOPT_DNS_SERVERS:
+    result = Curl_set_dns_servers(data, va_arg(param, char *));
+    break;
+  case CURLOPT_DNS_INTERFACE:
+    result = Curl_set_dns_interface(data, va_arg(param, char *));
+    break;
+  case CURLOPT_DNS_LOCAL_IP4:
+    result = Curl_set_dns_local_ip4(data, va_arg(param, char *));
+    break;
+  case CURLOPT_DNS_LOCAL_IP6:
+    result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
+    break;
+
+  case CURLOPT_TCP_KEEPALIVE:
+    data->set.tcp_keepalive = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_TCP_KEEPIDLE:
+    data->set.tcp_keepidle = va_arg(param, long);
+    break;
+  case CURLOPT_TCP_KEEPINTVL:
+    data->set.tcp_keepintvl = va_arg(param, long);
+    break;
+  case CURLOPT_SSL_ENABLE_NPN:
+    data->set.ssl_enable_npn = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_SSL_ENABLE_ALPN:
+    data->set.ssl_enable_alpn = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+
+#ifdef USE_UNIX_SOCKETS
+  case CURLOPT_UNIX_SOCKET_PATH:
+    result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
+                       va_arg(param, char *));
+    break;
+#endif
+
+  case CURLOPT_PATH_AS_IS:
+    data->set.path_as_is = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_PIPEWAIT:
+    data->set.pipewait = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_STREAM_WEIGHT:
+#ifndef USE_NGHTTP2
+    return CURLE_NOT_BUILT_IN;
+#else
+    arg = va_arg(param, long);
+    if((arg>=1) && (arg <= 256))
+      data->set.stream_weight = (int)arg;
+    break;
+#endif
+  case CURLOPT_STREAM_DEPENDS:
+  case CURLOPT_STREAM_DEPENDS_E:
+  {
+#ifndef USE_NGHTTP2
+    return CURLE_NOT_BUILT_IN;
+#else
+    struct SessionHandle *dep = va_arg(param, struct SessionHandle *);
+    if(dep && GOOD_EASY_HANDLE(dep)) {
+      data->set.stream_depends_on = dep;
+      data->set.stream_depends_e = (option == CURLOPT_STREAM_DEPENDS_E);
+    }
+    break;
+#endif
+  }
+  default:
+    /* unknown tag and its companion, just ignore: */
+    result = CURLE_UNKNOWN_OPTION;
+    break;
+  }
+
+  return result;
+}
+
+static void conn_free(struct connectdata *conn)
+{
+  if(!conn)
+    return;
+
+  /* possible left-overs from the async name resolvers */
+  Curl_resolver_cancel(conn);
+
+  /* close the SSL stuff before we close any sockets since they will/may
+     write to the sockets */
+  Curl_ssl_close(conn, FIRSTSOCKET);
+  Curl_ssl_close(conn, SECONDARYSOCKET);
+
+  /* close possibly still open sockets */
+  if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
+    Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
+  if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
+    Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
+  if(CURL_SOCKET_BAD != conn->tempsock[0])
+    Curl_closesocket(conn, conn->tempsock[0]);
+  if(CURL_SOCKET_BAD != conn->tempsock[1])
+    Curl_closesocket(conn, conn->tempsock[1]);
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+    defined(NTLM_WB_ENABLED)
+  Curl_ntlm_wb_cleanup(conn);
+#endif
+
+  Curl_safefree(conn->user);
+  Curl_safefree(conn->passwd);
+  Curl_safefree(conn->oauth_bearer);
+  Curl_safefree(conn->options);
+  Curl_safefree(conn->proxyuser);
+  Curl_safefree(conn->proxypasswd);
+  Curl_safefree(conn->allocptr.proxyuserpwd);
+  Curl_safefree(conn->allocptr.uagent);
+  Curl_safefree(conn->allocptr.userpwd);
+  Curl_safefree(conn->allocptr.accept_encoding);
+  Curl_safefree(conn->allocptr.te);
+  Curl_safefree(conn->allocptr.rangeline);
+  Curl_safefree(conn->allocptr.ref);
+  Curl_safefree(conn->allocptr.host);
+  Curl_safefree(conn->allocptr.cookiehost);
+  Curl_safefree(conn->allocptr.rtsp_transport);
+  Curl_safefree(conn->trailer);
+  Curl_safefree(conn->host.rawalloc); /* host name buffer */
+  Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
+  Curl_safefree(conn->master_buffer);
+
+  Curl_llist_destroy(conn->send_pipe, NULL);
+  Curl_llist_destroy(conn->recv_pipe, NULL);
+
+  conn->send_pipe = NULL;
+  conn->recv_pipe = NULL;
+
+  Curl_safefree(conn->localdev);
+  Curl_free_ssl_config(&conn->ssl_config);
+
+  free(conn); /* free all the connection oriented data */
+}
+
+/*
+ * Disconnects the given connection. Note the connection may not be the
+ * primary connection, like when freeing room in the connection cache or
+ * killing of a dead old connection.
+ *
+ * This function MUST NOT reset state in the SessionHandle struct if that
+ * isn't strictly bound to the life-time of *this* particular connection.
+ *
+ */
+
+CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  struct SessionHandle *data;
+  if(!conn)
+    return CURLE_OK; /* this is closed and fine already */
+  data = conn->data;
+
+  if(!data) {
+    DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
+    return CURLE_OK;
+  }
+
+  if(conn->dns_entry != NULL) {
+    Curl_resolv_unlock(data, conn->dns_entry);
+    conn->dns_entry = NULL;
+  }
+
+  Curl_hostcache_prune(data); /* kill old DNS cache entries */
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
+  /* Cleanup NTLM connection-related data */
+  Curl_http_ntlm_cleanup(conn);
+#endif
+
+  if(conn->handler->disconnect)
+    /* This is set if protocol-specific cleanups should be made */
+    conn->handler->disconnect(conn, dead_connection);
+
+    /* unlink ourselves! */
+  infof(data, "Closing connection %ld\n", conn->connection_id);
+  Curl_conncache_remove_conn(data->state.conn_cache, conn);
+
+  free_fixed_hostname(&conn->host);
+  free_fixed_hostname(&conn->proxy);
+
+  Curl_ssl_close(conn, FIRSTSOCKET);
+
+  /* Indicate to all handles on the pipe that we're dead */
+  if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
+    signalPipeClose(conn->send_pipe, TRUE);
+    signalPipeClose(conn->recv_pipe, TRUE);
+  }
+
+  conn_free(conn);
+
+  return CURLE_OK;
+}
+
+/*
+ * This function should return TRUE if the socket is to be assumed to
+ * be dead. Most commonly this happens when the server has closed the
+ * connection due to inactivity.
+ */
+static bool SocketIsDead(curl_socket_t sock)
+{
+  int sval;
+  bool ret_val = TRUE;
+
+  sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0);
+  if(sval == 0)
+    /* timeout */
+    ret_val = FALSE;
+
+  return ret_val;
+}
+
+/*
+ * IsPipeliningPossible() returns TRUE if the options set would allow
+ * pipelining/multiplexing and the connection is using a HTTP protocol.
+ */
+static bool IsPipeliningPossible(const struct SessionHandle *handle,
+                                 const struct connectdata *conn)
+{
+  /* If a HTTP protocol and pipelining is enabled */
+  if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
+
+    if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
+       (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
+       (handle->set.httpreq == HTTPREQ_GET ||
+        handle->set.httpreq == HTTPREQ_HEAD))
+      /* didn't ask for HTTP/1.0 and a GET or HEAD */
+      return TRUE;
+
+    if(Curl_pipeline_wanted(handle->multi, CURLPIPE_MULTIPLEX) &&
+       (handle->set.httpversion >= CURL_HTTP_VERSION_2))
+      /* allows HTTP/2 */
+      return TRUE;
+  }
+  return FALSE;
+}
+
+int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
+                                  struct curl_llist *pipeline)
+{
+  struct curl_llist_element *curr;
+
+  curr = pipeline->head;
+  while(curr) {
+    if(curr->ptr == handle) {
+      Curl_llist_remove(pipeline, curr, NULL);
+      return 1; /* we removed a handle */
+    }
+    curr = curr->next;
+  }
+
+  return 0;
+}
+
+#if 0 /* this code is saved here as it is useful for debugging purposes */
+static void Curl_printPipeline(struct curl_llist *pipeline)
+{
+  struct curl_llist_element *curr;
+
+  curr = pipeline->head;
+  while(curr) {
+    struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
+    infof(data, "Handle in pipeline: %s\n", data->state.path);
+    curr = curr->next;
+  }
+}
+#endif
+
+static struct SessionHandle* gethandleathead(struct curl_llist *pipeline)
+{
+  struct curl_llist_element *curr = pipeline->head;
+  if(curr) {
+    return (struct SessionHandle *) curr->ptr;
+  }
+
+  return NULL;
+}
+
+/* remove the specified connection from all (possible) pipelines and related
+   queues */
+void Curl_getoff_all_pipelines(struct SessionHandle *data,
+                               struct connectdata *conn)
+{
+  bool recv_head = (conn->readchannel_inuse &&
+                    Curl_recvpipe_head(data, conn));
+  bool send_head = (conn->writechannel_inuse &&
+                    Curl_sendpipe_head(data, conn));
+
+  if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
+    Curl_pipeline_leave_read(conn);
+  if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head)
+    Curl_pipeline_leave_write(conn);
+}
+
+static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
+{
+  struct curl_llist_element *curr;
+
+  if(!pipeline)
+    return;
+
+  curr = pipeline->head;
+  while(curr) {
+    struct curl_llist_element *next = curr->next;
+    struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
+
+#ifdef DEBUGBUILD /* debug-only code */
+    if(data->magic != CURLEASY_MAGIC_NUMBER) {
+      /* MAJOR BADNESS */
+      infof(data, "signalPipeClose() found BAAD easy handle\n");
+    }
+#endif
+
+    if(pipe_broke)
+      data->state.pipe_broke = TRUE;
+    Curl_multi_handlePipeBreak(data);
+    Curl_llist_remove(pipeline, curr, NULL);
+    curr = next;
+  }
+}
+
+/*
+ * This function finds the connection in the connection
+ * cache that has been unused for the longest time.
+ *
+ * Returns the pointer to the oldest idle connection, or NULL if none was
+ * found.
+ */
+static struct connectdata *
+find_oldest_idle_connection(struct SessionHandle *data)
+{
+  struct conncache *bc = data->state.conn_cache;
+  struct curl_hash_iterator iter;
+  struct curl_llist_element *curr;
+  struct curl_hash_element *he;
+  long highscore=-1;
+  long score;
+  struct timeval now;
+  struct connectdata *conn_candidate = NULL;
+  struct connectbundle *bundle;
+
+  now = Curl_tvnow();
+
+  Curl_hash_start_iterate(&bc->hash, &iter);
+
+  he = Curl_hash_next_element(&iter);
+  while(he) {
+    struct connectdata *conn;
+
+    bundle = he->ptr;
+
+    curr = bundle->conn_list->head;
+    while(curr) {
+      conn = curr->ptr;
+
+      if(!conn->inuse) {
+        /* Set higher score for the age passed since the connection was used */
+        score = Curl_tvdiff(now, conn->now);
+
+        if(score > highscore) {
+          highscore = score;
+          conn_candidate = conn;
+        }
+      }
+      curr = curr->next;
+    }
+
+    he = Curl_hash_next_element(&iter);
+  }
+
+  return conn_candidate;
+}
+
+/*
+ * This function finds the connection in the connection
+ * bundle that has been unused for the longest time.
+ *
+ * Returns the pointer to the oldest idle connection, or NULL if none was
+ * found.
+ */
+static struct connectdata *
+find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
+                                      struct connectbundle *bundle)
+{
+  struct curl_llist_element *curr;
+  long highscore=-1;
+  long score;
+  struct timeval now;
+  struct connectdata *conn_candidate = NULL;
+  struct connectdata *conn;
+
+  (void)data;
+
+  now = Curl_tvnow();
+
+  curr = bundle->conn_list->head;
+  while(curr) {
+    conn = curr->ptr;
+
+    if(!conn->inuse) {
+      /* Set higher score for the age passed since the connection was used */
+      score = Curl_tvdiff(now, conn->now);
+
+      if(score > highscore) {
+        highscore = score;
+        conn_candidate = conn;
+      }
+    }
+    curr = curr->next;
+  }
+
+  return conn_candidate;
+}
+
+/*
+ * This function checks if given connection is dead and disconnects if so.
+ * (That also removes it from the connection cache.)
+ *
+ * Returns TRUE if the connection actually was dead and disconnected.
+ */
+static bool disconnect_if_dead(struct connectdata *conn,
+                               struct SessionHandle *data)
+{
+  size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
+  if(!pipeLen && !conn->inuse) {
+    /* The check for a dead socket makes sense only if there are no
+       handles in pipeline and the connection isn't already marked in
+       use */
+    bool dead;
+    if(conn->handler->protocol & CURLPROTO_RTSP)
+      /* RTSP is a special case due to RTP interleaving */
+      dead = Curl_rtsp_connisdead(conn);
+    else
+      dead = SocketIsDead(conn->sock[FIRSTSOCKET]);
+
+    if(dead) {
+      conn->data = data;
+      infof(data, "Connection %ld seems to be dead!\n", conn->connection_id);
+
+      /* disconnect resources */
+      Curl_disconnect(conn, /* dead_connection */TRUE);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/*
+ * Wrapper to use disconnect_if_dead() function in Curl_conncache_foreach()
+ *
+ * Returns always 0.
+ */
+static int call_disconnect_if_dead(struct connectdata *conn,
+                                      void *param)
+{
+  struct SessionHandle* data = (struct SessionHandle*)param;
+  disconnect_if_dead(conn, data);
+  return 0; /* continue iteration */
+}
+
+/*
+ * This function scans the connection cache for half-open/dead connections,
+ * closes and removes them.
+ * The cleanup is done at most once per second.
+ */
+static void prune_dead_connections(struct SessionHandle *data)
+{
+  struct timeval now = Curl_tvnow();
+  long elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup);
+
+  if(elapsed >= 1000L) {
+    Curl_conncache_foreach(data->state.conn_cache, data,
+                           call_disconnect_if_dead);
+    data->state.conn_cache->last_cleanup = now;
+  }
+}
+
+
+static size_t max_pipeline_length(struct Curl_multi *multi)
+{
+  return multi ? multi->max_pipeline_length : 0;
+}
+
+
+/*
+ * Given one filled in connection struct (named needle), this function should
+ * detect if there already is one that has all the significant details
+ * exactly the same and thus should be used instead.
+ *
+ * If there is a match, this function returns TRUE - and has marked the
+ * connection as 'in-use'. It must later be called with ConnectionDone() to
+ * return back to 'idle' (unused) state.
+ *
+ * The force_reuse flag is set if the connection must be used, even if
+ * the pipelining strategy wants to open a new connection instead of reusing.
+ */
+static bool
+ConnectionExists(struct SessionHandle *data,
+                 struct connectdata *needle,
+                 struct connectdata **usethis,
+                 bool *force_reuse,
+                 bool *waitpipe)
+{
+  struct connectdata *check;
+  struct connectdata *chosen = 0;
+  bool foundPendingCandidate = FALSE;
+  bool canPipeline = IsPipeliningPossible(data, needle);
+  struct connectbundle *bundle;
+
+#ifdef USE_NTLM
+  bool wantNTLMhttp = ((data->state.authhost.want &
+                      (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
+                      (needle->handler->protocol & PROTO_FAMILY_HTTP));
+  bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd &&
+                           ((data->state.authproxy.want &
+                           (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
+                           (needle->handler->protocol & PROTO_FAMILY_HTTP)));
+#endif
+
+  *force_reuse = FALSE;
+  *waitpipe = FALSE;
+
+  /* We can't pipe if the site is blacklisted */
+  if(canPipeline && Curl_pipeline_site_blacklisted(data, needle)) {
+    canPipeline = FALSE;
+  }
+
+  /* Look up the bundle with all the connections to this
+     particular host */
+  bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache);
+  if(bundle) {
+    /* Max pipe length is zero (unlimited) for multiplexed connections */
+    size_t max_pipe_len = (bundle->multiuse != BUNDLE_MULTIPLEX)?
+      max_pipeline_length(data->multi):0;
+    size_t best_pipe_len = max_pipe_len;
+    struct curl_llist_element *curr;
+
+    infof(data, "Found bundle for host %s: %p [%s]\n",
+          needle->host.name, (void *)bundle,
+          (bundle->multiuse== BUNDLE_PIPELINING?
+           "can pipeline":
+           (bundle->multiuse== BUNDLE_MULTIPLEX?
+            "can multiplex":"serially")));
+
+    /* We can't pipe if we don't know anything about the server */
+    if(canPipeline) {
+      if(bundle->multiuse <= BUNDLE_UNKNOWN) {
+        if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) {
+          infof(data, "Server doesn't support multi-use yet, wait\n");
+          *waitpipe = TRUE;
+          return FALSE; /* no re-use */
+        }
+
+        infof(data, "Server doesn't support multi-use (yet)\n");
+        canPipeline = FALSE;
+      }
+      if((bundle->multiuse == BUNDLE_PIPELINING) &&
+         !Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1)) {
+        /* not asked for, switch off */
+        infof(data, "Could pipeline, but not asked to!\n");
+        canPipeline = FALSE;
+      }
+      else if((bundle->multiuse == BUNDLE_MULTIPLEX) &&
+              !Curl_pipeline_wanted(data->multi, CURLPIPE_MULTIPLEX)) {
+        infof(data, "Could multiplex, but not asked to!\n");
+        canPipeline = FALSE;
+      }
+    }
+
+    curr = bundle->conn_list->head;
+    while(curr) {
+      bool match = FALSE;
+      size_t pipeLen;
+
+      /*
+       * Note that if we use a HTTP proxy, we check connections to that
+       * proxy and not to the actual remote server.
+       */
+      check = curr->ptr;
+      curr = curr->next;
+
+      if(disconnect_if_dead(check, data))
+        continue;
+
+      pipeLen = check->send_pipe->size + check->recv_pipe->size;
+
+      if(canPipeline) {
+
+        if(!check->bits.multiplex) {
+          /* If not multiplexing, make sure the pipe has only GET requests */
+          struct SessionHandle* sh = gethandleathead(check->send_pipe);
+          struct SessionHandle* rh = gethandleathead(check->recv_pipe);
+          if(sh) {
+            if(!IsPipeliningPossible(sh, check))
+              continue;
+          }
+          else if(rh) {
+            if(!IsPipeliningPossible(rh, check))
+              continue;
+          }
+        }
+      }
+      else {
+        if(pipeLen > 0) {
+          /* can only happen within multi handles, and means that another easy
+             handle is using this connection */
+          continue;
+        }
+
+        if(Curl_resolver_asynch()) {
+          /* ip_addr_str[0] is NUL only if the resolving of the name hasn't
+             completed yet and until then we don't re-use this connection */
+          if(!check->ip_addr_str[0]) {
+            infof(data,
+                  "Connection #%ld is still name resolving, can't reuse\n",
+                  check->connection_id);
+            continue;
+          }
+        }
+
+        if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) ||
+           check->bits.close) {
+          if(!check->bits.close)
+            foundPendingCandidate = TRUE;
+          /* Don't pick a connection that hasn't connected yet or that is going
+             to get closed. */
+          infof(data, "Connection #%ld isn't open enough, can't reuse\n",
+                check->connection_id);
+#ifdef DEBUGBUILD
+          if(check->recv_pipe->size > 0) {
+            infof(data,
+                  "BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
+                  check->connection_id);
+          }
+#endif
+          continue;
+        }
+      }
+
+      if((needle->handler->flags&PROTOPT_SSL) !=
+         (check->handler->flags&PROTOPT_SSL))
+        /* don't do mixed SSL and non-SSL connections */
+        if(!(needle->handler->protocol & check->handler->protocol))
+          /* except protocols that have been upgraded via TLS */
+          continue;
+
+      if(needle->handler->flags&PROTOPT_SSL) {
+        if((data->set.ssl.verifypeer != check->verifypeer) ||
+           (data->set.ssl.verifyhost != check->verifyhost))
+          continue;
+      }
+
+      if(needle->bits.proxy != check->bits.proxy)
+        /* don't do mixed proxy and non-proxy connections */
+        continue;
+
+      if(!canPipeline && check->inuse)
+        /* this request can't be pipelined but the checked connection is
+           already in use so we skip it */
+        continue;
+
+      if(needle->localdev || needle->localport) {
+        /* If we are bound to a specific local end (IP+port), we must not
+           re-use a random other one, although if we didn't ask for a
+           particular one we can reuse one that was bound.
+
+           This comparison is a bit rough and too strict. Since the input
+           parameters can be specified in numerous ways and still end up the
+           same it would take a lot of processing to make it really accurate.
+           Instead, this matching will assume that re-uses of bound connections
+           will most likely also re-use the exact same binding parameters and
+           missing out a few edge cases shouldn't hurt anyone very much.
+        */
+        if((check->localport != needle->localport) ||
+           (check->localportrange != needle->localportrange) ||
+           !check->localdev ||
+           !needle->localdev ||
+           strcmp(check->localdev, needle->localdev))
+          continue;
+      }
+
+      if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
+        /* This protocol requires credentials per connection,
+           so verify that we're using the same name and password as well */
+        if(!strequal(needle->user, check->user) ||
+           !strequal(needle->passwd, check->passwd)) {
+          /* one of them was different */
+          continue;
+        }
+      }
+
+      if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
+         (needle->bits.httpproxy && check->bits.httpproxy &&
+          needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
+          Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
+          (needle->port == check->port))) {
+        /* The requested connection does not use a HTTP proxy or it uses SSL or
+           it is a non-SSL protocol tunneled over the same http proxy name and
+           port number or it is a non-SSL protocol which is allowed to be
+           upgraded via TLS */
+
+        if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) ||
+            needle->handler->protocol & check->handler->protocol) &&
+           Curl_raw_equal(needle->host.name, check->host.name) &&
+           needle->remote_port == check->remote_port) {
+          if(needle->handler->flags & PROTOPT_SSL) {
+            /* This is a SSL connection so verify that we're using the same
+               SSL options as well */
+            if(!Curl_ssl_config_matches(&needle->ssl_config,
+                                        &check->ssl_config)) {
+              DEBUGF(infof(data,
+                           "Connection #%ld has different SSL parameters, "
+                           "can't reuse\n",
+                           check->connection_id));
+              continue;
+            }
+            else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
+              foundPendingCandidate = TRUE;
+              DEBUGF(infof(data,
+                           "Connection #%ld has not started SSL connect, "
+                           "can't reuse\n",
+                           check->connection_id));
+              continue;
+            }
+          }
+          match = TRUE;
+        }
+      }
+      else { /* The requested needle connection is using a proxy,
+                is the checked one using the same host, port and type? */
+        if(check->bits.proxy &&
+           (needle->proxytype == check->proxytype) &&
+           (needle->bits.tunnel_proxy == check->bits.tunnel_proxy) &&
+           Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
+           needle->port == check->port) {
+          /* This is the same proxy connection, use it! */
+          match = TRUE;
+        }
+      }
+
+      if(match) {
+#if defined(USE_NTLM)
+        /* If we are looking for an HTTP+NTLM connection, check if this is
+           already authenticating with the right credentials. If not, keep
+           looking so that we can reuse NTLM connections if
+           possible. (Especially we must not reuse the same connection if
+           partway through a handshake!) */
+        if(wantNTLMhttp) {
+          if(!strequal(needle->user, check->user) ||
+             !strequal(needle->passwd, check->passwd))
+            continue;
+        }
+        else if(check->ntlm.state != NTLMSTATE_NONE) {
+          /* Connection is using NTLM auth but we don't want NTLM */
+          continue;
+        }
+
+        /* Same for Proxy NTLM authentication */
+        if(wantProxyNTLMhttp) {
+          if(!strequal(needle->proxyuser, check->proxyuser) ||
+             !strequal(needle->proxypasswd, check->proxypasswd))
+            continue;
+        }
+        else if(check->proxyntlm.state != NTLMSTATE_NONE) {
+          /* Proxy connection is using NTLM auth but we don't want NTLM */
+          continue;
+        }
+
+        if(wantNTLMhttp || wantProxyNTLMhttp) {
+          /* Credentials are already checked, we can use this connection */
+          chosen = check;
+
+          if((wantNTLMhttp &&
+             (check->ntlm.state != NTLMSTATE_NONE)) ||
+              (wantProxyNTLMhttp &&
+               (check->proxyntlm.state != NTLMSTATE_NONE))) {
+            /* We must use this connection, no other */
+            *force_reuse = TRUE;
+            break;
+          }
+
+          /* Continue look up for a better connection */
+          continue;
+        }
+#endif
+        if(canPipeline) {
+          /* We can pipeline if we want to. Let's continue looking for
+             the optimal connection to use, i.e the shortest pipe that is not
+             blacklisted. */
+
+          if(pipeLen == 0) {
+            /* We have the optimal connection. Let's stop looking. */
+            chosen = check;
+            break;
+          }
+
+          /* We can't use the connection if the pipe is full */
+          if(max_pipe_len && (pipeLen >= max_pipe_len)) {
+            infof(data, "Pipe is full, skip (%zu)\n", pipeLen);
+            continue;
+          }
+#ifdef USE_NGHTTP2
+          /* If multiplexed, make sure we don't go over concurrency limit */
+          if(check->bits.multiplex) {
+            /* Multiplexed connections can only be HTTP/2 for now */
+            struct http_conn *httpc = &check->proto.httpc;
+            if(pipeLen >= httpc->settings.max_concurrent_streams) {
+              infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n",
+                    pipeLen);
+              continue;
+            }
+          }
+#endif
+          /* We can't use the connection if the pipe is penalized */
+          if(Curl_pipeline_penalized(data, check)) {
+            infof(data, "Penalized, skip\n");
+            continue;
+          }
+
+          if(max_pipe_len) {
+            if(pipeLen < best_pipe_len) {
+              /* This connection has a shorter pipe so far. We'll pick this
+                 and continue searching */
+              chosen = check;
+              best_pipe_len = pipeLen;
+              continue;
+            }
+          }
+          else {
+            /* When not pipelining (== multiplexed), we have a match here! */
+            chosen = check;
+            infof(data, "Multiplexed connection found!\n");
+            break;
+          }
+        }
+        else {
+          /* We have found a connection. Let's stop searching. */
+          chosen = check;
+          break;
+        }
+      }
+    }
+  }
+
+  if(chosen) {
+    *usethis = chosen;
+    return TRUE; /* yes, we found one to use! */
+  }
+
+  if(foundPendingCandidate && data->set.pipewait) {
+    infof(data,
+          "Found pending candidate for reuse and CURLOPT_PIPEWAIT is set\n");
+    *waitpipe = TRUE;
+  }
+
+  return FALSE; /* no matching connecting exists */
+}
+
+/* Mark the connection as 'idle', or close it if the cache is full.
+   Returns TRUE if the connection is kept, or FALSE if it was closed. */
+static bool
+ConnectionDone(struct SessionHandle *data, struct connectdata *conn)
+{
+  /* data->multi->maxconnects can be negative, deal with it. */
+  size_t maxconnects =
+    (data->multi->maxconnects < 0) ? data->multi->num_easy * 4:
+    data->multi->maxconnects;
+  struct connectdata *conn_candidate = NULL;
+
+  /* Mark the current connection as 'unused' */
+  conn->inuse = FALSE;
+
+  if(maxconnects > 0 &&
+     data->state.conn_cache->num_connections > maxconnects) {
+    infof(data, "Connection cache is full, closing the oldest one.\n");
+
+    conn_candidate = find_oldest_idle_connection(data);
+
+    if(conn_candidate) {
+      /* Set the connection's owner correctly */
+      conn_candidate->data = data;
+
+      /* the winner gets the honour of being disconnected */
+      (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
+    }
+  }
+
+  return (conn_candidate == conn) ? FALSE : TRUE;
+}
+
+/* after a TCP connection to the proxy has been verified, this function does
+   the next magic step.
+
+   Note: this function's sub-functions call failf()
+
+*/
+CURLcode Curl_connected_proxy(struct connectdata *conn,
+                              int sockindex)
+{
+  if(!conn->bits.proxy || sockindex)
+    /* this magic only works for the primary socket as the secondary is used
+       for FTP only and it has FTP specific magic in ftp.c */
+    return CURLE_OK;
+
+  switch(conn->proxytype) {
+#ifndef CURL_DISABLE_PROXY
+  case CURLPROXY_SOCKS5:
+  case CURLPROXY_SOCKS5_HOSTNAME:
+    return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
+                       conn->host.name, conn->remote_port,
+                       FIRSTSOCKET, conn);
+
+  case CURLPROXY_SOCKS4:
+    return Curl_SOCKS4(conn->proxyuser, conn->host.name,
+                       conn->remote_port, FIRSTSOCKET, conn, FALSE);
+
+  case CURLPROXY_SOCKS4A:
+    return Curl_SOCKS4(conn->proxyuser, conn->host.name,
+                       conn->remote_port, FIRSTSOCKET, conn, TRUE);
+
+#endif /* CURL_DISABLE_PROXY */
+  case CURLPROXY_HTTP:
+  case CURLPROXY_HTTP_1_0:
+    /* do nothing here. handled later. */
+    break;
+  default:
+    break;
+  } /* switch proxytype */
+
+  return CURLE_OK;
+}
+
+/*
+ * verboseconnect() displays verbose information after a connect
+ */
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+void Curl_verboseconnect(struct connectdata *conn)
+{
+  if(conn->data->set.verbose)
+    infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
+          conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname,
+          conn->ip_addr_str, conn->port, conn->connection_id);
+}
+#endif
+
+int Curl_protocol_getsock(struct connectdata *conn,
+                          curl_socket_t *socks,
+                          int numsocks)
+{
+  if(conn->handler->proto_getsock)
+    return conn->handler->proto_getsock(conn, socks, numsocks);
+  return GETSOCK_BLANK;
+}
+
+int Curl_doing_getsock(struct connectdata *conn,
+                       curl_socket_t *socks,
+                       int numsocks)
+{
+  if(conn && conn->handler->doing_getsock)
+    return conn->handler->doing_getsock(conn, socks, numsocks);
+  return GETSOCK_BLANK;
+}
+
+/*
+ * We are doing protocol-specific connecting and this is being called over and
+ * over from the multi interface until the connection phase is done on
+ * protocol layer.
+ */
+
+CURLcode Curl_protocol_connecting(struct connectdata *conn,
+                                  bool *done)
+{
+  CURLcode result=CURLE_OK;
+
+  if(conn && conn->handler->connecting) {
+    *done = FALSE;
+    result = conn->handler->connecting(conn, done);
+  }
+  else
+    *done = TRUE;
+
+  return result;
+}
+
+/*
+ * We are DOING this is being called over and over from the multi interface
+ * until the DOING phase is done on protocol layer.
+ */
+
+CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
+{
+  CURLcode result=CURLE_OK;
+
+  if(conn && conn->handler->doing) {
+    *done = FALSE;
+    result = conn->handler->doing(conn, done);
+  }
+  else
+    *done = TRUE;
+
+  return result;
+}
+
+/*
+ * We have discovered that the TCP connection has been successful, we can now
+ * proceed with some action.
+ *
+ */
+CURLcode Curl_protocol_connect(struct connectdata *conn,
+                               bool *protocol_done)
+{
+  CURLcode result=CURLE_OK;
+
+  *protocol_done = FALSE;
+
+  if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
+    /* We already are connected, get back. This may happen when the connect
+       worked fine in the first call, like when we connect to a local server
+       or proxy. Note that we don't know if the protocol is actually done.
+
+       Unless this protocol doesn't have any protocol-connect callback, as
+       then we know we're done. */
+    if(!conn->handler->connecting)
+      *protocol_done = TRUE;
+
+    return CURLE_OK;
+  }
+
+  if(!conn->bits.protoconnstart) {
+
+    result = Curl_proxy_connect(conn);
+    if(result)
+      return result;
+
+    if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
+       (conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE))
+      /* when using an HTTP tunnel proxy, await complete tunnel establishment
+         before proceeding further. Return CURLE_OK so we'll be called again */
+      return CURLE_OK;
+
+    if(conn->handler->connect_it) {
+      /* is there a protocol-specific connect() procedure? */
+
+      /* Call the protocol-specific connect function */
+      result = conn->handler->connect_it(conn, protocol_done);
+    }
+    else
+      *protocol_done = TRUE;
+
+    /* it has started, possibly even completed but that knowledge isn't stored
+       in this bit! */
+    if(!result)
+      conn->bits.protoconnstart = TRUE;
+  }
+
+  return result; /* pass back status */
+}
+
+/*
+ * Helpers for IDNA convertions.
+ */
+static bool is_ASCII_name(const char *hostname)
+{
+  const unsigned char *ch = (const unsigned char*)hostname;
+
+  while(*ch) {
+    if(*ch++ & 0x80)
+      return FALSE;
+  }
+  return TRUE;
+}
+
+#ifdef USE_LIBIDN
+/*
+ * Check if characters in hostname is allowed in Top Level Domain.
+ */
+static bool tld_check_name(struct SessionHandle *data,
+                           const char *ace_hostname)
+{
+  size_t err_pos;
+  char *uc_name = NULL;
+  int rc;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  const char *tld_errmsg = "<no msg>";
+#else
+  (void)data;
+#endif
+
+  /* Convert (and downcase) ACE-name back into locale's character set */
+  rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
+  if(rc != IDNA_SUCCESS)
+    return FALSE;
+
+  rc = tld_check_lz(uc_name, &err_pos, NULL);
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+#ifdef HAVE_TLD_STRERROR
+  if(rc != TLD_SUCCESS)
+    tld_errmsg = tld_strerror((Tld_rc)rc);
+#endif
+  if(rc == TLD_INVALID)
+    infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
+          tld_errmsg, err_pos, uc_name[err_pos],
+          uc_name[err_pos] & 255);
+  else if(rc != TLD_SUCCESS)
+    infof(data, "WARNING: TLD check for %s failed; %s\n",
+          uc_name, tld_errmsg);
+#endif /* CURL_DISABLE_VERBOSE_STRINGS */
+  if(uc_name)
+     idn_free(uc_name);
+  if(rc != TLD_SUCCESS)
+    return FALSE;
+
+  return TRUE;
+}
+#endif
+
+/*
+ * Perform any necessary IDN conversion of hostname
+ */
+static void fix_hostname(struct SessionHandle *data,
+                         struct connectdata *conn, struct hostname *host)
+{
+  size_t len;
+
+#ifndef USE_LIBIDN
+  (void)data;
+  (void)conn;
+#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void)conn;
+#endif
+
+  /* set the name we use to display the host name */
+  host->dispname = host->name;
+
+  len = strlen(host->name);
+  if(len && (host->name[len-1] == '.'))
+    /* strip off a single trailing dot if present, primarily for SNI but
+       there's no use for it */
+    host->name[len-1]=0;
+
+  if(!is_ASCII_name(host->name)) {
+#ifdef USE_LIBIDN
+  /*************************************************************
+   * Check name for non-ASCII and convert hostname to ACE form.
+   *************************************************************/
+  if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
+    char *ace_hostname = NULL;
+    int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
+    infof (data, "Input domain encoded as `%s'\n",
+           stringprep_locale_charset ());
+    if(rc != IDNA_SUCCESS)
+      infof(data, "Failed to convert %s to ACE; %s\n",
+            host->name, Curl_idn_strerror(conn, rc));
+    else {
+      /* tld_check_name() displays a warning if the host name contains
+         "illegal" characters for this TLD */
+      (void)tld_check_name(data, ace_hostname);
+
+      host->encalloc = ace_hostname;
+      /* change the name pointer to point to the encoded hostname */
+      host->name = host->encalloc;
+    }
+  }
+#elif defined(USE_WIN32_IDN)
+  /*************************************************************
+   * Check name for non-ASCII and convert hostname to ACE form.
+   *************************************************************/
+    char *ace_hostname = NULL;
+    int rc = curl_win32_idn_to_ascii(host->name, &ace_hostname);
+    if(rc == 0)
+      infof(data, "Failed to convert %s to ACE;\n",
+            host->name);
+    else {
+      host->encalloc = ace_hostname;
+      /* change the name pointer to point to the encoded hostname */
+      host->name = host->encalloc;
+    }
+#else
+    infof(data, "IDN support not present, can't parse Unicode domains\n");
+#endif
+  }
+}
+
+/*
+ * Frees data allocated by fix_hostname()
+ */
+static void free_fixed_hostname(struct hostname *host)
+{
+#if defined(USE_LIBIDN)
+  if(host->encalloc) {
+    idn_free(host->encalloc); /* must be freed with idn_free() since this was
+                                 allocated by libidn */
+    host->encalloc = NULL;
+  }
+#elif defined(USE_WIN32_IDN)
+  free(host->encalloc); /* must be freed withidn_free() since this was
+                           allocated by curl_win32_idn_to_ascii */
+  host->encalloc = NULL;
+#else
+  (void)host;
+#endif
+}
+
+static void llist_dtor(void *user, void *element)
+{
+  (void)user;
+  (void)element;
+  /* Do nothing */
+}
+
+/*
+ * Allocate and initialize a new connectdata object.
+ */
+static struct connectdata *allocate_conn(struct SessionHandle *data)
+{
+  struct connectdata *conn = calloc(1, sizeof(struct connectdata));
+  if(!conn)
+    return NULL;
+
+  conn->handler = &Curl_handler_dummy;  /* Be sure we have a handler defined
+                                           already from start to avoid NULL
+                                           situations and checks */
+
+  /* and we setup a few fields in case we end up actually using this struct */
+
+  conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD;     /* no file descriptor */
+  conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
+  conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */
+  conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
+  conn->connection_id = -1;    /* no ID */
+  conn->port = -1; /* unknown at this point */
+  conn->remote_port = -1; /* unknown */
+
+  /* Default protocol-independent behavior doesn't support persistent
+     connections, so we set this to force-close. Protocols that support
+     this need to set this to FALSE in their "curl_do" functions. */
+  connclose(conn, "Default to force-close");
+
+  /* Store creation time to help future close decision making */
+  conn->created = Curl_tvnow();
+
+  conn->data = data; /* Setup the association between this connection
+                        and the SessionHandle */
+
+  conn->proxytype = data->set.proxytype; /* type */
+
+#ifdef CURL_DISABLE_PROXY
+
+  conn->bits.proxy = FALSE;
+  conn->bits.httpproxy = FALSE;
+  conn->bits.proxy_user_passwd = FALSE;
+  conn->bits.tunnel_proxy = FALSE;
+
+#else /* CURL_DISABLE_PROXY */
+
+  /* note that these two proxy bits are now just on what looks to be
+     requested, they may be altered down the road */
+  conn->bits.proxy = (data->set.str[STRING_PROXY] &&
+                      *data->set.str[STRING_PROXY])?TRUE:FALSE;
+  conn->bits.httpproxy = (conn->bits.proxy &&
+                          (conn->proxytype == CURLPROXY_HTTP ||
+                           conn->proxytype == CURLPROXY_HTTP_1_0))?TRUE:FALSE;
+  conn->bits.proxy_user_passwd =
+    (NULL != data->set.str[STRING_PROXYUSERNAME])?TRUE:FALSE;
+  conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
+
+#endif /* CURL_DISABLE_PROXY */
+
+  conn->bits.user_passwd = (NULL != data->set.str[STRING_USERNAME])?TRUE:FALSE;
+  conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
+  conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
+
+  conn->verifypeer = data->set.ssl.verifypeer;
+  conn->verifyhost = data->set.ssl.verifyhost;
+
+  conn->ip_version = data->set.ipver;
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+    defined(NTLM_WB_ENABLED)
+  conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
+  conn->ntlm_auth_hlpr_pid = 0;
+  conn->challenge_header = NULL;
+  conn->response_header = NULL;
+#endif
+
+  if(Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
+     !conn->master_buffer) {
+    /* Allocate master_buffer to be used for HTTP/1 pipelining */
+    conn->master_buffer = calloc(BUFSIZE, sizeof (char));
+    if(!conn->master_buffer)
+      goto error;
+  }
+
+  /* Initialize the pipeline lists */
+  conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
+  conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
+  if(!conn->send_pipe || !conn->recv_pipe)
+    goto error;
+
+#ifdef HAVE_GSSAPI
+  conn->data_prot = PROT_CLEAR;
+#endif
+
+  /* Store the local bind parameters that will be used for this connection */
+  if(data->set.str[STRING_DEVICE]) {
+    conn->localdev = strdup(data->set.str[STRING_DEVICE]);
+    if(!conn->localdev)
+      goto error;
+  }
+  conn->localportrange = data->set.localportrange;
+  conn->localport = data->set.localport;
+
+  /* the close socket stuff needs to be copied to the connection struct as
+     it may live on without (this specific) SessionHandle */
+  conn->fclosesocket = data->set.fclosesocket;
+  conn->closesocket_client = data->set.closesocket_client;
+
+  return conn;
+  error:
+
+  Curl_llist_destroy(conn->send_pipe, NULL);
+  Curl_llist_destroy(conn->recv_pipe, NULL);
+
+  conn->send_pipe = NULL;
+  conn->recv_pipe = NULL;
+
+  free(conn->master_buffer);
+  free(conn->localdev);
+  free(conn);
+  return NULL;
+}
+
+static CURLcode findprotocol(struct SessionHandle *data,
+                             struct connectdata *conn,
+                             const char *protostr)
+{
+  const struct Curl_handler * const *pp;
+  const struct Curl_handler *p;
+
+  /* Scan protocol handler table and match against 'protostr' to set a few
+     variables based on the URL. Now that the handler may be changed later
+     when the protocol specific setup function is called. */
+  for(pp = protocols; (p = *pp) != NULL; pp++) {
+    if(Curl_raw_equal(p->scheme, protostr)) {
+      /* Protocol found in table. Check if allowed */
+      if(!(data->set.allowed_protocols & p->protocol))
+        /* nope, get out */
+        break;
+
+      /* it is allowed for "normal" request, now do an extra check if this is
+         the result of a redirect */
+      if(data->state.this_is_a_follow &&
+         !(data->set.redir_protocols & p->protocol))
+        /* nope, get out */
+        break;
+
+      /* Perform setup complement if some. */
+      conn->handler = conn->given = p;
+
+      /* 'port' and 'remote_port' are set in setup_connection_internals() */
+      return CURLE_OK;
+    }
+  }
+
+
+  /* The protocol was not found in the table, but we don't have to assign it
+     to anything since it is already assigned to a dummy-struct in the
+     create_conn() function when the connectdata struct is allocated. */
+  failf(data, "Protocol \"%s\" not supported or disabled in " LIBCURL_NAME,
+        protostr);
+
+  return CURLE_UNSUPPORTED_PROTOCOL;
+}
+
+/*
+ * Parse URL and fill in the relevant members of the connection struct.
+ */
+static CURLcode parseurlandfillconn(struct SessionHandle *data,
+                                    struct connectdata *conn,
+                                    bool *prot_missing,
+                                    char **userp, char **passwdp,
+                                    char **optionsp)
+{
+  char *at;
+  char *fragment;
+  char *path = data->state.path;
+  char *query;
+  int rc;
+  char protobuf[16] = "";
+  const char *protop = "";
+  CURLcode result;
+  bool rebuild_url = FALSE;
+
+  *prot_missing = FALSE;
+
+  /* We might pass the entire URL into the request so we need to make sure
+   * there are no bad characters in there.*/
+  if(strpbrk(data->change.url, "\r\n")) {
+    failf(data, "Illegal characters found in URL");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /*************************************************************
+   * Parse the URL.
+   *
+   * We need to parse the url even when using the proxy, because we will need
+   * the hostname and port in case we are trying to SSL connect through the
+   * proxy -- and we don't know if we will need to use SSL until we parse the
+   * url ...
+   ************************************************************/
+  if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
+                  protobuf, path)) &&
+     Curl_raw_equal(protobuf, "file")) {
+    if(path[0] == '/' && path[1] == '/') {
+      /* Allow omitted hostname (e.g. file:/<path>).  This is not strictly
+       * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
+       * file://localhost/<path> is similar to how other schemes treat missing
+       * hostnames.  See RFC 1808. */
+
+      /* This cannot be done with strcpy() in a portable manner, since the
+         memory areas overlap! */
+      memmove(path, path + 2, strlen(path + 2)+1);
+    }
+    /*
+     * we deal with file://<host>/<path> differently since it supports no
+     * hostname other than "localhost" and "127.0.0.1", which is unique among
+     * the URL protocols specified in RFC 1738
+     */
+    if(path[0] != '/') {
+      /* the URL included a host name, we ignore host names in file:// URLs
+         as the standards don't define what to do with them */
+      char *ptr=strchr(path, '/');
+      if(ptr) {
+        /* there was a slash present
+
+           RFC1738 (section 3.1, page 5) says:
+
+           The rest of the locator consists of data specific to the scheme,
+           and is known as the "url-path". It supplies the details of how the
+           specified resource can be accessed. Note that the "/" between the
+           host (or port) and the url-path is NOT part of the url-path.
+
+           As most agents use file://localhost/foo to get '/foo' although the
+           slash preceding foo is a separator and not a slash for the path,
+           a URL as file://localhost//foo must be valid as well, to refer to
+           the same file with an absolute path.
+        */
+
+        if(ptr[1] && ('/' == ptr[1]))
+          /* if there was two slashes, we skip the first one as that is then
+             used truly as a separator */
+          ptr++;
+
+        /* This cannot be made with strcpy, as the memory chunks overlap! */
+        memmove(path, ptr, strlen(ptr)+1);
+      }
+    }
+
+    protop = "file"; /* protocol string */
+  }
+  else {
+    /* clear path */
+    path[0]=0;
+
+    if(2 > sscanf(data->change.url,
+                   "%15[^\n:]://%[^\n/?]%[^\n]",
+                   protobuf,
+                   conn->host.name, path)) {
+
+      /*
+       * The URL was badly formatted, let's try the browser-style _without_
+       * protocol specified like 'http://'.
+       */
+      rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path);
+      if(1 > rc) {
+        /*
+         * We couldn't even get this format.
+         * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is
+         * assigned, but the return value is EOF!
+         */
+#if defined(__DJGPP__) && (DJGPP_MINOR == 4)
+        if(!(rc == -1 && *conn->host.name))
+#endif
+        {
+          failf(data, "<url> malformed");
+          return CURLE_URL_MALFORMAT;
+        }
+      }
+
+      /*
+       * Since there was no protocol part specified in the URL use the
+       * user-specified default protocol. If we weren't given a default make a
+       * guess by matching some protocols against the host's outermost
+       * sub-domain name. Finally if there was no match use HTTP.
+       */
+
+      protop = data->set.str[STRING_DEFAULT_PROTOCOL];
+      if(!protop) {
+        /* Note: if you add a new protocol, please update the list in
+         * lib/version.c too! */
+        if(checkprefix("FTP.", conn->host.name))
+          protop = "ftp";
+        else if(checkprefix("DICT.", conn->host.name))
+          protop = "DICT";
+        else if(checkprefix("LDAP.", conn->host.name))
+          protop = "LDAP";
+        else if(checkprefix("IMAP.", conn->host.name))
+          protop = "IMAP";
+        else if(checkprefix("SMTP.", conn->host.name))
+          protop = "smtp";
+        else if(checkprefix("POP3.", conn->host.name))
+          protop = "pop3";
+        else
+          protop = "http";
+      }
+
+      *prot_missing = TRUE; /* not given in URL */
+    }
+    else
+      protop = protobuf;
+  }
+
+  /* We search for '?' in the host name (but only on the right side of a
+   * @-letter to allow ?-letters in username and password) to handle things
+   * like http://example.com?param= (notice the missing '/').
+   */
+  at = strchr(conn->host.name, '@');
+  if(at)
+    query = strchr(at+1, '?');
+  else
+    query = strchr(conn->host.name, '?');
+
+  if(query) {
+    /* We must insert a slash before the '?'-letter in the URL. If the URL had
+       a slash after the '?', that is where the path currently begins and the
+       '?string' is still part of the host name.
+
+       We must move the trailing part from the host name and put it first in
+       the path. And have it all prefixed with a slash.
+    */
+
+    size_t hostlen = strlen(query);
+    size_t pathlen = strlen(path);
+
+    /* move the existing path plus the zero byte forward, to make room for
+       the host-name part */
+    memmove(path+hostlen+1, path, pathlen+1);
+
+     /* now copy the trailing host part in front of the existing path */
+    memcpy(path+1, query, hostlen);
+
+    path[0]='/'; /* prepend the missing slash */
+    rebuild_url = TRUE;
+
+    *query=0; /* now cut off the hostname at the ? */
+  }
+  else if(!path[0]) {
+    /* if there's no path set, use a single slash */
+    strcpy(path, "/");
+    rebuild_url = TRUE;
+  }
+
+  /* If the URL is malformatted (missing a '/' after hostname before path) we
+   * insert a slash here. The only letter except '/' we accept to start a path
+   * is '?'.
+   */
+  if(path[0] == '?') {
+    /* We need this function to deal with overlapping memory areas. We know
+       that the memory area 'path' points to is 'urllen' bytes big and that
+       is bigger than the path. Use +1 to move the zero byte too. */
+    memmove(&path[1], path, strlen(path)+1);
+    path[0] = '/';
+    rebuild_url = TRUE;
+  }
+  else if(!data->set.path_as_is) {
+    /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */
+    char *newp = Curl_dedotdotify(path);
+    if(!newp)
+      return CURLE_OUT_OF_MEMORY;
+
+    if(strcmp(newp, path)) {
+      rebuild_url = TRUE;
+      free(data->state.pathbuffer);
+      data->state.pathbuffer = newp;
+      data->state.path = newp;
+      path = newp;
+    }
+    else
+      free(newp);
+  }
+
+  /*
+   * "rebuild_url" means that one or more URL components have been modified so
+   * we need to generate an updated full version.  We need the corrected URL
+   * when communicating over HTTP proxy and we don't know at this point if
+   * we're using a proxy or not.
+   */
+  if(rebuild_url) {
+    char *reurl;
+
+    size_t plen = strlen(path); /* new path, should be 1 byte longer than
+                                   the original */
+    size_t urllen = strlen(data->change.url); /* original URL length */
+
+    size_t prefixlen = strlen(conn->host.name);
+
+    if(!*prot_missing)
+      prefixlen += strlen(protop) + strlen("://");
+
+    reurl = malloc(urllen + 2); /* 2 for zerobyte + slash */
+    if(!reurl)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* copy the prefix */
+    memcpy(reurl, data->change.url, prefixlen);
+
+    /* append the trailing piece + zerobyte */
+    memcpy(&reurl[prefixlen], path, plen + 1);
+
+    /* possible free the old one */
+    if(data->change.url_alloc) {
+      Curl_safefree(data->change.url);
+      data->change.url_alloc = FALSE;
+    }
+
+    infof(data, "Rebuilt URL to: %s\n", reurl);
+
+    data->change.url = reurl;
+    data->change.url_alloc = TRUE; /* free this later */
+  }
+
+  /*
+   * Parse the login details from the URL and strip them out of
+   * the host name
+   */
+  result = parse_url_login(data, conn, userp, passwdp, optionsp);
+  if(result)
+    return result;
+
+  if(conn->host.name[0] == '[') {
+    /* This looks like an IPv6 address literal.  See if there is an address
+       scope if there is no location header */
+    char *percent = strchr(conn->host.name, '%');
+    if(percent) {
+      unsigned int identifier_offset = 3;
+      char *endp;
+      unsigned long scope;
+      if(strncmp("%25", percent, 3) != 0) {
+        infof(data,
+              "Please URL encode %% as %%25, see RFC 6874.\n");
+        identifier_offset = 1;
+      }
+      scope = strtoul(percent + identifier_offset, &endp, 10);
+      if(*endp == ']') {
+        /* The address scope was well formed.  Knock it out of the
+           hostname. */
+        memmove(percent, endp, strlen(endp)+1);
+        conn->scope_id = (unsigned int)scope;
+      }
+      else {
+        /* Zone identifier is not numeric */
+#if defined(HAVE_NET_IF_H) && defined(IFNAMSIZ) && defined(HAVE_IF_NAMETOINDEX)
+        char ifname[IFNAMSIZ + 2];
+        char *square_bracket;
+        unsigned int scopeidx = 0;
+        strncpy(ifname, percent + identifier_offset, IFNAMSIZ + 2);
+        /* Ensure nullbyte termination */
+        ifname[IFNAMSIZ + 1] = '\0';
+        square_bracket = strchr(ifname, ']');
+        if(square_bracket) {
+          /* Remove ']' */
+          *square_bracket = '\0';
+          scopeidx = if_nametoindex(ifname);
+          if(scopeidx == 0) {
+            infof(data, "Invalid network interface: %s; %s\n", ifname,
+                  strerror(errno));
+          }
+        }
+        if(scopeidx > 0) {
+          char *p = percent + identifier_offset + strlen(ifname);
+
+          /* Remove zone identifier from hostname */
+          memmove(percent, p, strlen(p) + 1);
+          conn->scope_id = scopeidx;
+        }
+        else
+#endif /* HAVE_NET_IF_H && IFNAMSIZ */
+          infof(data, "Invalid IPv6 address format\n");
+      }
+    }
+  }
+
+  if(data->set.scope_id)
+    /* Override any scope that was set above.  */
+    conn->scope_id = data->set.scope_id;
+
+  /* Remove the fragment part of the path. Per RFC 2396, this is always the
+     last part of the URI. We are looking for the first '#' so that we deal
+     gracefully with non conformant URI such as http://example.com#foo#bar. */
+  fragment = strchr(path, '#');
+  if(fragment) {
+    *fragment = 0;
+
+    /* we know the path part ended with a fragment, so we know the full URL
+       string does too and we need to cut it off from there so it isn't used
+       over proxy */
+    fragment = strchr(data->change.url, '#');
+    if(fragment)
+      *fragment = 0;
+  }
+
+  /*
+   * So if the URL was A://B/C#D,
+   *   protop is A
+   *   conn->host.name is B
+   *   data->state.path is /C
+   */
+
+  return findprotocol(data, conn, protop);
+}
+
+/*
+ * If we're doing a resumed transfer, we need to setup our stuff
+ * properly.
+ */
+static CURLcode setup_range(struct SessionHandle *data)
+{
+  struct UrlState *s = &data->state;
+  s->resume_from = data->set.set_resume_from;
+  if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
+    if(s->rangestringalloc)
+      free(s->range);
+
+    if(s->resume_from)
+      s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from);
+    else
+      s->range = strdup(data->set.str[STRING_SET_RANGE]);
+
+    s->rangestringalloc = (s->range)?TRUE:FALSE;
+
+    if(!s->range)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* tell ourselves to fetch this range */
+    s->use_range = TRUE;        /* enable range download */
+  }
+  else
+    s->use_range = FALSE; /* disable range download */
+
+  return CURLE_OK;
+}
+
+
+/*
+ * setup_connection_internals() -
+ *
+ * Setup connection internals specific to the requested protocol in the
+ * SessionHandle. This is inited and setup before the connection is made but
+ * is about the particular protocol that is to be used.
+ *
+ * This MUST get called after proxy magic has been figured out.
+ */
+static CURLcode setup_connection_internals(struct connectdata *conn)
+{
+  const struct Curl_handler * p;
+  CURLcode result;
+  struct SessionHandle *data = conn->data;
+
+  /* in some case in the multi state-machine, we go back to the CONNECT state
+     and then a second (or third or...) call to this function will be made
+     without doing a DISCONNECT or DONE in between (since the connection is
+     yet in place) and therefore this function needs to first make sure
+     there's no lingering previous data allocated. */
+  Curl_free_request_state(data);
+
+  memset(&data->req, 0, sizeof(struct SingleRequest));
+  data->req.maxdownload = -1;
+
+  conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
+
+  /* Perform setup complement if some. */
+  p = conn->handler;
+
+  if(p->setup_connection) {
+    result = (*p->setup_connection)(conn);
+
+    if(result)
+      return result;
+
+    p = conn->handler;              /* May have changed. */
+  }
+
+  if(conn->port < 0)
+    /* we check for -1 here since if proxy was detected already, this
+       was very likely already set to the proxy port */
+    conn->port = p->defport;
+
+  /* only if remote_port was not already parsed off the URL we use the
+     default port number */
+  if(conn->remote_port < 0)
+    conn->remote_port = (unsigned short)conn->given->defport;
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_free_request_state() should free temp data that was allocated in the
+ * SessionHandle for this single request.
+ */
+
+void Curl_free_request_state(struct SessionHandle *data)
+{
+  Curl_safefree(data->req.protop);
+  Curl_safefree(data->req.newurl);
+}
+
+
+#ifndef CURL_DISABLE_PROXY
+/****************************************************************
+* Checks if the host is in the noproxy list. returns true if it matches
+* and therefore the proxy should NOT be used.
+****************************************************************/
+static bool check_noproxy(const char* name, const char* no_proxy)
+{
+  /* no_proxy=domain1.dom,host.domain2.dom
+   *   (a comma-separated list of hosts which should
+   *   not be proxied, or an asterisk to override
+   *   all proxy variables)
+   */
+  size_t tok_start;
+  size_t tok_end;
+  const char* separator = ", ";
+  size_t no_proxy_len;
+  size_t namelen;
+  char *endptr;
+
+  if(no_proxy && no_proxy[0]) {
+    if(Curl_raw_equal("*", no_proxy)) {
+      return TRUE;
+    }
+
+    /* NO_PROXY was specified and it wasn't just an asterisk */
+
+    no_proxy_len = strlen(no_proxy);
+    endptr = strchr(name, ':');
+    if(endptr)
+      namelen = endptr - name;
+    else
+      namelen = strlen(name);
+
+    for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
+      while(tok_start < no_proxy_len &&
+            strchr(separator, no_proxy[tok_start]) != NULL) {
+        /* Look for the beginning of the token. */
+        ++tok_start;
+      }
+
+      if(tok_start == no_proxy_len)
+        break; /* It was all trailing separator chars, no more tokens. */
+
+      for(tok_end = tok_start; tok_end < no_proxy_len &&
+            strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end)
+        /* Look for the end of the token. */
+        ;
+
+      /* To match previous behaviour, where it was necessary to specify
+       * ".local.com" to prevent matching "notlocal.com", we will leave
+       * the '.' off.
+       */
+      if(no_proxy[tok_start] == '.')
+        ++tok_start;
+
+      if((tok_end - tok_start) <= namelen) {
+        /* Match the last part of the name to the domain we are checking. */
+        const char *checkn = name + namelen - (tok_end - tok_start);
+        if(Curl_raw_nequal(no_proxy + tok_start, checkn,
+                           tok_end - tok_start)) {
+          if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
+            /* We either have an exact match, or the previous character is a .
+             * so it is within the same domain, so no proxy for this host.
+             */
+            return TRUE;
+          }
+        }
+      } /* if((tok_end - tok_start) <= namelen) */
+    } /* for(tok_start = 0; tok_start < no_proxy_len;
+         tok_start = tok_end + 1) */
+  } /* NO_PROXY was specified and it wasn't just an asterisk */
+
+  return FALSE;
+}
+
+/****************************************************************
+* Detect what (if any) proxy to use. Remember that this selects a host
+* name and is not limited to HTTP proxies only.
+* The returned pointer must be freed by the caller (unless NULL)
+****************************************************************/
+static char *detect_proxy(struct connectdata *conn)
+{
+  char *proxy = NULL;
+
+#ifndef CURL_DISABLE_HTTP
+  /* If proxy was not specified, we check for default proxy environment
+   * variables, to enable i.e Lynx compliance:
+   *
+   * http_proxy=http://some.server.dom:port/
+   * https_proxy=http://some.server.dom:port/
+   * ftp_proxy=http://some.server.dom:port/
+   * no_proxy=domain1.dom,host.domain2.dom
+   *   (a comma-separated list of hosts which should
+   *   not be proxied, or an asterisk to override
+   *   all proxy variables)
+   * all_proxy=http://some.server.dom:port/
+   *   (seems to exist for the CERN www lib. Probably
+   *   the first to check for.)
+   *
+   * For compatibility, the all-uppercase versions of these variables are
+   * checked if the lowercase versions don't exist.
+   */
+  char *no_proxy=NULL;
+  char proxy_env[128];
+
+  no_proxy=curl_getenv("no_proxy");
+  if(!no_proxy)
+    no_proxy=curl_getenv("NO_PROXY");
+
+  if(!check_noproxy(conn->host.name, no_proxy)) {
+    /* It was not listed as without proxy */
+    const char *protop = conn->handler->scheme;
+    char *envp = proxy_env;
+    char *prox;
+
+    /* Now, build <protocol>_proxy and check for such a one to use */
+    while(*protop)
+      *envp++ = (char)tolower((int)*protop++);
+
+    /* append _proxy */
+    strcpy(envp, "_proxy");
+
+    /* read the protocol proxy: */
+    prox=curl_getenv(proxy_env);
+
+    /*
+     * We don't try the uppercase version of HTTP_PROXY because of
+     * security reasons:
+     *
+     * When curl is used in a webserver application
+     * environment (cgi or php), this environment variable can
+     * be controlled by the web server user by setting the
+     * http header 'Proxy:' to some value.
+     *
+     * This can cause 'internal' http/ftp requests to be
+     * arbitrarily redirected by any external attacker.
+     */
+    if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) {
+      /* There was no lowercase variable, try the uppercase version: */
+      Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
+      prox=curl_getenv(proxy_env);
+    }
+
+    if(prox)
+      proxy = prox; /* use this */
+    else {
+      proxy = curl_getenv("all_proxy"); /* default proxy to use */
+      if(!proxy)
+        proxy=curl_getenv("ALL_PROXY");
+    }
+  } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified
+       non-proxy */
+  free(no_proxy);
+
+#else /* !CURL_DISABLE_HTTP */
+
+  (void)conn;
+#endif /* CURL_DISABLE_HTTP */
+
+  return proxy;
+}
+
+/*
+ * If this is supposed to use a proxy, we need to figure out the proxy
+ * host name, so that we can re-use an existing connection
+ * that may exist registered to the same proxy host.
+ */
+static CURLcode parse_proxy(struct SessionHandle *data,
+                            struct connectdata *conn, char *proxy)
+{
+  char *prox_portno;
+  char *endofprot;
+
+  /* We use 'proxyptr' to point to the proxy name from now on... */
+  char *proxyptr;
+  char *portptr;
+  char *atsign;
+
+  /* We do the proxy host string parsing here. We want the host name and the
+   * port name. Accept a protocol:// prefix
+   */
+
+  /* Parse the protocol part if present */
+  endofprot = strstr(proxy, "://");
+  if(endofprot) {
+    proxyptr = endofprot+3;
+    if(checkprefix("socks5h", proxy))
+      conn->proxytype = CURLPROXY_SOCKS5_HOSTNAME;
+    else if(checkprefix("socks5", proxy))
+      conn->proxytype = CURLPROXY_SOCKS5;
+    else if(checkprefix("socks4a", proxy))
+      conn->proxytype = CURLPROXY_SOCKS4A;
+    else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
+      conn->proxytype = CURLPROXY_SOCKS4;
+    /* Any other xxx:// : change to http proxy */
+  }
+  else
+    proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
+
+  /* Is there a username and password given in this proxy url? */
+  atsign = strchr(proxyptr, '@');
+  if(atsign) {
+    char *proxyuser = NULL;
+    char *proxypasswd = NULL;
+    CURLcode result =
+      parse_login_details(proxyptr, atsign - proxyptr,
+                          &proxyuser, &proxypasswd, NULL);
+    if(!result) {
+      /* found user and password, rip them out.  note that we are
+         unescaping them, as there is otherwise no way to have a
+         username or password with reserved characters like ':' in
+         them. */
+      Curl_safefree(conn->proxyuser);
+      if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH)
+        conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
+      else
+        conn->proxyuser = strdup("");
+
+      if(!conn->proxyuser)
+        result = CURLE_OUT_OF_MEMORY;
+      else {
+        Curl_safefree(conn->proxypasswd);
+        if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
+          conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
+        else
+          conn->proxypasswd = strdup("");
+
+        if(!conn->proxypasswd)
+          result = CURLE_OUT_OF_MEMORY;
+      }
+
+      if(!result) {
+        conn->bits.proxy_user_passwd = TRUE; /* enable it */
+        atsign++; /* the right side of the @-letter */
+
+        proxyptr = atsign; /* now use this instead */
+      }
+    }
+
+    free(proxyuser);
+    free(proxypasswd);
+
+    if(result)
+      return result;
+  }
+
+  /* start scanning for port number at this point */
+  portptr = proxyptr;
+
+  /* detect and extract RFC6874-style IPv6-addresses */
+  if(*proxyptr == '[') {
+    char *ptr = ++proxyptr; /* advance beyond the initial bracket */
+    while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
+      ptr++;
+    if(*ptr == '%') {
+      /* There might be a zone identifier */
+      if(strncmp("%25", ptr, 3))
+        infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
+      ptr++;
+      /* Allow unresered characters as defined in RFC 3986 */
+      while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
+                     (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
+        ptr++;
+    }
+    if(*ptr == ']')
+      /* yeps, it ended nicely with a bracket as well */
+      *ptr++ = 0;
+    else
+      infof(data, "Invalid IPv6 address format\n");
+    portptr = ptr;
+    /* Note that if this didn't end with a bracket, we still advanced the
+     * proxyptr first, but I can't see anything wrong with that as no host
+     * name nor a numeric can legally start with a bracket.
+     */
+  }
+
+  /* Get port number off proxy.server.com:1080 */
+  prox_portno = strchr(portptr, ':');
+  if(prox_portno) {
+    char *endp = NULL;
+    long port = 0;
+    *prox_portno = 0x0; /* cut off number from host name */
+    prox_portno ++;
+    /* now set the local port number */
+    port = strtol(prox_portno, &endp, 10);
+    if((endp && *endp && (*endp != '/') && (*endp != ' ')) ||
+       (port >= 65536) ) {
+      /* meant to detect for example invalid IPv6 numerical addresses without
+         brackets: "2a00:fac0:a000::7:13". Accept a trailing slash only
+         because we then allow "URL style" with the number followed by a
+         slash, used in curl test cases already. Space is also an acceptable
+         terminating symbol. */
+      infof(data, "No valid port number in proxy string (%s)\n",
+            prox_portno);
+    }
+    else
+      conn->port = port;
+  }
+  else {
+    if(proxyptr[0]=='/')
+      /* If the first character in the proxy string is a slash, fail
+         immediately. The following code will otherwise clear the string which
+         will lead to code running as if no proxy was set! */
+      return CURLE_COULDNT_RESOLVE_PROXY;
+
+    /* without a port number after the host name, some people seem to use
+       a slash so we strip everything from the first slash */
+    atsign = strchr(proxyptr, '/');
+    if(atsign)
+      *atsign = 0x0; /* cut off path part from host name */
+
+    if(data->set.proxyport)
+      /* None given in the proxy string, then get the default one if it is
+         given */
+      conn->port = data->set.proxyport;
+  }
+
+  /* now, clone the cleaned proxy host name */
+  conn->proxy.rawalloc = strdup(proxyptr);
+  conn->proxy.name = conn->proxy.rawalloc;
+
+  if(!conn->proxy.rawalloc)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+/*
+ * Extract the user and password from the authentication string
+ */
+static CURLcode parse_proxy_auth(struct SessionHandle *data,
+                                 struct connectdata *conn)
+{
+  char proxyuser[MAX_CURL_USER_LENGTH]="";
+  char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
+
+  if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
+    strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
+            MAX_CURL_USER_LENGTH);
+    proxyuser[MAX_CURL_USER_LENGTH-1] = '\0';   /*To be on safe side*/
+  }
+  if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
+    strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
+            MAX_CURL_PASSWORD_LENGTH);
+    proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
+  }
+
+  conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
+  if(!conn->proxyuser)
+    return CURLE_OUT_OF_MEMORY;
+
+  conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
+  if(!conn->proxypasswd)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+#endif /* CURL_DISABLE_PROXY */
+
+/*
+ * parse_url_login()
+ *
+ * Parse the login details (user name, password and options) from the URL and
+ * strip them out of the host name
+ *
+ * Inputs: data->set.use_netrc (CURLOPT_NETRC)
+ *         conn->host.name
+ *
+ * Outputs: (almost :- all currently undefined)
+ *          conn->bits.user_passwd  - non-zero if non-default passwords exist
+ *          user                    - non-zero length if defined
+ *          passwd                  - non-zero length if defined
+ *          options                 - non-zero length if defined
+ *          conn->host.name         - remove user name and password
+ */
+static CURLcode parse_url_login(struct SessionHandle *data,
+                                struct connectdata *conn,
+                                char **user, char **passwd, char **options)
+{
+  CURLcode result = CURLE_OK;
+  char *userp = NULL;
+  char *passwdp = NULL;
+  char *optionsp = NULL;
+
+  /* At this point, we're hoping all the other special cases have
+   * been taken care of, so conn->host.name is at most
+   *    [user[:password][;options]]@]hostname
+   *
+   * We need somewhere to put the embedded details, so do that first.
+   */
+
+  char *ptr = strchr(conn->host.name, '@');
+  char *login = conn->host.name;
+
+  DEBUGASSERT(!**user);
+  DEBUGASSERT(!**passwd);
+  DEBUGASSERT(!**options);
+
+  if(!ptr)
+    goto out;
+
+  /* We will now try to extract the
+   * possible login information in a string like:
+   * ftp://user:password@ftp.my.site:8021/README */
+  conn->host.name = ++ptr;
+
+  /* So the hostname is sane.  Only bother interpreting the
+   * results if we could care.  It could still be wasted
+   * work because it might be overtaken by the programmatically
+   * set user/passwd, but doing that first adds more cases here :-(
+   */
+
+  if(data->set.use_netrc == CURL_NETRC_REQUIRED)
+    goto out;
+
+  /* We could use the login information in the URL so extract it */
+  result = parse_login_details(login, ptr - login - 1,
+                               &userp, &passwdp, &optionsp);
+  if(result)
+    goto out;
+
+  if(userp) {
+    char *newname;
+
+    /* We have a user in the URL */
+    conn->bits.userpwd_in_url = TRUE;
+    conn->bits.user_passwd = TRUE; /* enable user+password */
+
+    /* Decode the user */
+    newname = curl_easy_unescape(data, userp, 0, NULL);
+    if(!newname) {
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+
+    free(*user);
+    *user = newname;
+  }
+
+  if(passwdp) {
+    /* We have a password in the URL so decode it */
+    char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
+    if(!newpasswd) {
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+
+    free(*passwd);
+    *passwd = newpasswd;
+  }
+
+  if(optionsp) {
+    /* We have an options list in the URL so decode it */
+    char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
+    if(!newoptions) {
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+
+    free(*options);
+    *options = newoptions;
+  }
+
+
+  out:
+
+  free(userp);
+  free(passwdp);
+  free(optionsp);
+
+  return result;
+}
+
+/*
+ * parse_login_details()
+ *
+ * This is used to parse a login string for user name, password and options in
+ * the following formats:
+ *
+ *   user
+ *   user:password
+ *   user:password;options
+ *   user;options
+ *   user;options:password
+ *   :password
+ *   :password;options
+ *   ;options
+ *   ;options:password
+ *
+ * Parameters:
+ *
+ * login    [in]     - The login string.
+ * len      [in]     - The length of the login string.
+ * userp    [in/out] - The address where a pointer to newly allocated memory
+ *                     holding the user will be stored upon completion.
+ * passdwp  [in/out] - The address where a pointer to newly allocated memory
+ *                     holding the password will be stored upon completion.
+ * optionsp [in/out] - The address where a pointer to newly allocated memory
+ *                     holding the options will be stored upon completion.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode parse_login_details(const char *login, const size_t len,
+                                    char **userp, char **passwdp,
+                                    char **optionsp)
+{
+  CURLcode result = CURLE_OK;
+  char *ubuf = NULL;
+  char *pbuf = NULL;
+  char *obuf = NULL;
+  const char *psep = NULL;
+  const char *osep = NULL;
+  size_t ulen;
+  size_t plen;
+  size_t olen;
+
+  /* Attempt to find the password separator */
+  if(passwdp) {
+    psep = strchr(login, ':');
+
+    /* Within the constraint of the login string */
+    if(psep >= login + len)
+      psep = NULL;
+  }
+
+  /* Attempt to find the options separator */
+  if(optionsp) {
+    osep = strchr(login, ';');
+
+    /* Within the constraint of the login string */
+    if(osep >= login + len)
+      osep = NULL;
+  }
+
+  /* Calculate the portion lengths */
+  ulen = (psep ?
+          (size_t)(osep && psep > osep ? osep - login : psep - login) :
+          (osep ? (size_t)(osep - login) : len));
+  plen = (psep ?
+          (osep && osep > psep ? (size_t)(osep - psep) :
+                                 (size_t)(login + len - psep)) - 1 : 0);
+  olen = (osep ?
+          (psep && psep > osep ? (size_t)(psep - osep) :
+                                 (size_t)(login + len - osep)) - 1 : 0);
+
+  /* Allocate the user portion buffer */
+  if(userp && ulen) {
+    ubuf = malloc(ulen + 1);
+    if(!ubuf)
+      result = CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Allocate the password portion buffer */
+  if(!result && passwdp && plen) {
+    pbuf = malloc(plen + 1);
+    if(!pbuf) {
+      free(ubuf);
+      result = CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* Allocate the options portion buffer */
+  if(!result && optionsp && olen) {
+    obuf = malloc(olen + 1);
+    if(!obuf) {
+      free(pbuf);
+      free(ubuf);
+      result = CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  if(!result) {
+    /* Store the user portion if necessary */
+    if(ubuf) {
+      memcpy(ubuf, login, ulen);
+      ubuf[ulen] = '\0';
+      Curl_safefree(*userp);
+      *userp = ubuf;
+    }
+
+    /* Store the password portion if necessary */
+    if(pbuf) {
+      memcpy(pbuf, psep + 1, plen);
+      pbuf[plen] = '\0';
+      Curl_safefree(*passwdp);
+      *passwdp = pbuf;
+    }
+
+    /* Store the options portion if necessary */
+    if(obuf) {
+      memcpy(obuf, osep + 1, olen);
+      obuf[olen] = '\0';
+      Curl_safefree(*optionsp);
+      *optionsp = obuf;
+    }
+  }
+
+  return result;
+}
+
+/*************************************************************
+ * Figure out the remote port number and fix it in the URL
+ *
+ * No matter if we use a proxy or not, we have to figure out the remote
+ * port number of various reasons.
+ *
+ * To be able to detect port number flawlessly, we must not confuse them
+ * IPv6-specified addresses in the [0::1] style. (RFC2732)
+ *
+ * The conn->host.name is currently [user:passwd@]host[:port] where host
+ * could be a hostname, IPv4 address or IPv6 address.
+ *
+ * The port number embedded in the URL is replaced, if necessary.
+ *************************************************************/
+static CURLcode parse_remote_port(struct SessionHandle *data,
+                                  struct connectdata *conn)
+{
+  char *portptr;
+  char endbracket;
+
+  /* Note that at this point, the IPv6 address cannot contain any scope
+     suffix as that has already been removed in the parseurlandfillconn()
+     function */
+  if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
+                  &endbracket)) &&
+     (']' == endbracket)) {
+    /* this is a RFC2732-style specified IP-address */
+    conn->bits.ipv6_ip = TRUE;
+
+    conn->host.name++; /* skip over the starting bracket */
+    portptr = strchr(conn->host.name, ']');
+    if(portptr) {
+      *portptr++ = '\0'; /* zero terminate, killing the bracket */
+      if(':' != *portptr)
+        portptr = NULL; /* no port number available */
+    }
+  }
+  else {
+#ifdef ENABLE_IPV6
+    struct in6_addr in6;
+    if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) {
+      /* This is a numerical IPv6 address, meaning this is a wrongly formatted
+         URL */
+      failf(data, "IPv6 numerical address used in URL without brackets");
+      return CURLE_URL_MALFORMAT;
+    }
+#endif
+
+    portptr = strrchr(conn->host.name, ':');
+  }
+
+  if(data->set.use_port && data->state.allow_port) {
+    /* if set, we use this and ignore the port possibly given in the URL */
+    conn->remote_port = (unsigned short)data->set.use_port;
+    if(portptr)
+      *portptr = '\0'; /* cut off the name there anyway - if there was a port
+                      number - since the port number is to be ignored! */
+    if(conn->bits.httpproxy) {
+      /* we need to create new URL with the new port number */
+      char *url;
+      char type[12]="";
+
+      if(conn->bits.type_set)
+        snprintf(type, sizeof(type), ";type=%c",
+                 data->set.prefer_ascii?'A':
+                 (data->set.ftp_list_only?'D':'I'));
+
+      /*
+       * This synthesized URL isn't always right--suffixes like ;type=A are
+       * stripped off. It would be better to work directly from the original
+       * URL and simply replace the port part of it.
+       */
+      url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme,
+                    conn->bits.ipv6_ip?"[":"", conn->host.name,
+                    conn->bits.ipv6_ip?"]":"", conn->remote_port,
+                    data->state.slash_removed?"/":"", data->state.path,
+                    type);
+      if(!url)
+        return CURLE_OUT_OF_MEMORY;
+
+      if(data->change.url_alloc) {
+        Curl_safefree(data->change.url);
+        data->change.url_alloc = FALSE;
+      }
+
+      data->change.url = url;
+      data->change.url_alloc = TRUE;
+    }
+  }
+  else if(portptr) {
+    /* no CURLOPT_PORT given, extract the one from the URL */
+
+    char *rest;
+    long port;
+
+    port=strtol(portptr+1, &rest, 10);  /* Port number must be decimal */
+
+    if((port < 0) || (port > 0xffff)) {
+      /* Single unix standard says port numbers are 16 bits long */
+      failf(data, "Port number out of range");
+      return CURLE_URL_MALFORMAT;
+    }
+
+    else if(rest != &portptr[1]) {
+      *portptr = '\0'; /* cut off the name there */
+      conn->remote_port = curlx_ultous(port);
+    }
+    else
+      /* Browser behavior adaptation. If there's a colon with no digits after,
+         just cut off the name there which makes us ignore the colon and just
+         use the default port. Firefox and Chrome both do that. */
+      *portptr = '\0';
+  }
+  return CURLE_OK;
+}
+
+/*
+ * Override the login details from the URL with that in the CURLOPT_USERPWD
+ * option or a .netrc file, if applicable.
+ */
+static CURLcode override_login(struct SessionHandle *data,
+                               struct connectdata *conn,
+                               char **userp, char **passwdp, char **optionsp)
+{
+  if(data->set.str[STRING_USERNAME]) {
+    free(*userp);
+    *userp = strdup(data->set.str[STRING_USERNAME]);
+    if(!*userp)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(data->set.str[STRING_PASSWORD]) {
+    free(*passwdp);
+    *passwdp = strdup(data->set.str[STRING_PASSWORD]);
+    if(!*passwdp)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(data->set.str[STRING_OPTIONS]) {
+    free(*optionsp);
+    *optionsp = strdup(data->set.str[STRING_OPTIONS]);
+    if(!*optionsp)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  conn->bits.netrc = FALSE;
+  if(data->set.use_netrc != CURL_NETRC_IGNORED) {
+    int ret = Curl_parsenetrc(conn->host.name,
+                              userp, passwdp,
+                              data->set.str[STRING_NETRC_FILE]);
+    if(ret > 0) {
+      infof(data, "Couldn't find host %s in the "
+            DOT_CHAR "netrc file; using defaults\n",
+            conn->host.name);
+    }
+    else if(ret < 0 ) {
+      return CURLE_OUT_OF_MEMORY;
+    }
+    else {
+      /* set bits.netrc TRUE to remember that we got the name from a .netrc
+         file, so that it is safe to use even if we followed a Location: to a
+         different host or similar. */
+      conn->bits.netrc = TRUE;
+
+      conn->bits.user_passwd = TRUE; /* enable user+password */
+    }
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Set the login details so they're available in the connection
+ */
+static CURLcode set_login(struct connectdata *conn,
+                          const char *user, const char *passwd,
+                          const char *options)
+{
+  CURLcode result = CURLE_OK;
+
+  /* If our protocol needs a password and we have none, use the defaults */
+  if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) {
+    /* Store the default user */
+    conn->user = strdup(CURL_DEFAULT_USER);
+
+    /* Store the default password */
+    if(conn->user)
+      conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
+    else
+      conn->passwd = NULL;
+
+    /* This is the default password, so DON'T set conn->bits.user_passwd */
+  }
+  else {
+    /* Store the user, zero-length if not set */
+    conn->user = strdup(user);
+
+    /* Store the password (only if user is present), zero-length if not set */
+    if(conn->user)
+      conn->passwd = strdup(passwd);
+    else
+      conn->passwd = NULL;
+  }
+
+  if(!conn->user || !conn->passwd)
+    result = CURLE_OUT_OF_MEMORY;
+
+  /* Store the options, null if not set */
+  if(!result && options[0]) {
+    conn->options = strdup(options);
+
+    if(!conn->options)
+      result = CURLE_OUT_OF_MEMORY;
+  }
+
+  return result;
+}
+
+/*************************************************************
+ * Resolve the address of the server or proxy
+ *************************************************************/
+static CURLcode resolve_server(struct SessionHandle *data,
+                               struct connectdata *conn,
+                               bool *async)
+{
+  CURLcode result=CURLE_OK;
+  long timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+  /*************************************************************
+   * Resolve the name of the server or proxy
+   *************************************************************/
+  if(conn->bits.reuse)
+    /* We're reusing the connection - no need to resolve anything, and
+       fix_hostname() was called already in create_conn() for the re-use
+       case. */
+    *async = FALSE;
+
+  else {
+    /* this is a fresh connect */
+    int rc;
+    struct Curl_dns_entry *hostaddr;
+
+#ifdef USE_UNIX_SOCKETS
+    if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
+      /* Unix domain sockets are local. The host gets ignored, just use the
+       * specified domain socket address. Do not cache "DNS entries". There is
+       * no DNS involved and we already have the filesystem path available */
+      const char *path = data->set.str[STRING_UNIX_SOCKET_PATH];
+
+      hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
+      if(!hostaddr)
+        result = CURLE_OUT_OF_MEMORY;
+      else if((hostaddr->addr = Curl_unix2addr(path)) != NULL)
+        hostaddr->inuse++;
+      else {
+        /* Long paths are not supported for now */
+        if(strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) {
+          failf(data, "Unix socket path too long: '%s'", path);
+          result = CURLE_COULDNT_RESOLVE_HOST;
+        }
+        else
+          result = CURLE_OUT_OF_MEMORY;
+        free(hostaddr);
+        hostaddr = NULL;
+      }
+    }
+    else
+#endif
+    if(!conn->proxy.name || !*conn->proxy.name) {
+      /* If not connecting via a proxy, extract the port from the URL, if it is
+       * there, thus overriding any defaults that might have been set above. */
+      conn->port =  conn->remote_port; /* it is the same port */
+
+      /* Resolve target host right on */
+      rc = Curl_resolv_timeout(conn, conn->host.name, (int)conn->port,
+                               &hostaddr, timeout_ms);
+      if(rc == CURLRESOLV_PENDING)
+        *async = TRUE;
+
+      else if(rc == CURLRESOLV_TIMEDOUT)
+        result = CURLE_OPERATION_TIMEDOUT;
+
+      else if(!hostaddr) {
+        failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
+        result =  CURLE_COULDNT_RESOLVE_HOST;
+        /* don't return yet, we need to clean up the timeout first */
+      }
+    }
+    else {
+      /* This is a proxy that hasn't been resolved yet. */
+
+      /* resolve proxy */
+      rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port,
+                               &hostaddr, timeout_ms);
+
+      if(rc == CURLRESOLV_PENDING)
+        *async = TRUE;
+
+      else if(rc == CURLRESOLV_TIMEDOUT)
+        result = CURLE_OPERATION_TIMEDOUT;
+
+      else if(!hostaddr) {
+        failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
+        result = CURLE_COULDNT_RESOLVE_PROXY;
+        /* don't return yet, we need to clean up the timeout first */
+      }
+    }
+    DEBUGASSERT(conn->dns_entry == NULL);
+    conn->dns_entry = hostaddr;
+  }
+
+  return result;
+}
+
+/*
+ * Cleanup the connection just allocated before we can move along and use the
+ * previously existing one.  All relevant data is copied over and old_conn is
+ * ready for freeing once this function returns.
+ */
+static void reuse_conn(struct connectdata *old_conn,
+                       struct connectdata *conn)
+{
+  free_fixed_hostname(&old_conn->proxy);
+  free(old_conn->proxy.rawalloc);
+
+  /* free the SSL config struct from this connection struct as this was
+     allocated in vain and is targeted for destruction */
+  Curl_free_ssl_config(&old_conn->ssl_config);
+
+  conn->data = old_conn->data;
+
+  /* get the user+password information from the old_conn struct since it may
+   * be new for this request even when we re-use an existing connection */
+  conn->bits.user_passwd = old_conn->bits.user_passwd;
+  if(conn->bits.user_passwd) {
+    /* use the new user name and password though */
+    Curl_safefree(conn->user);
+    Curl_safefree(conn->passwd);
+    conn->user = old_conn->user;
+    conn->passwd = old_conn->passwd;
+    old_conn->user = NULL;
+    old_conn->passwd = NULL;
+  }
+
+  conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
+  if(conn->bits.proxy_user_passwd) {
+    /* use the new proxy user name and proxy password though */
+    Curl_safefree(conn->proxyuser);
+    Curl_safefree(conn->proxypasswd);
+    conn->proxyuser = old_conn->proxyuser;
+    conn->proxypasswd = old_conn->proxypasswd;
+    old_conn->proxyuser = NULL;
+    old_conn->proxypasswd = NULL;
+  }
+
+  /* host can change, when doing keepalive with a proxy or if the case is
+     different this time etc */
+  free_fixed_hostname(&conn->host);
+  Curl_safefree(conn->host.rawalloc);
+  conn->host=old_conn->host;
+
+  /* persist connection info in session handle */
+  Curl_persistconninfo(conn);
+
+  /* re-use init */
+  conn->bits.reuse = TRUE; /* yes, we're re-using here */
+
+  Curl_safefree(old_conn->user);
+  Curl_safefree(old_conn->passwd);
+  Curl_safefree(old_conn->proxyuser);
+  Curl_safefree(old_conn->proxypasswd);
+  Curl_safefree(old_conn->localdev);
+
+  Curl_llist_destroy(old_conn->send_pipe, NULL);
+  Curl_llist_destroy(old_conn->recv_pipe, NULL);
+
+  old_conn->send_pipe = NULL;
+  old_conn->recv_pipe = NULL;
+
+  Curl_safefree(old_conn->master_buffer);
+}
+
+/**
+ * create_conn() sets up a new connectdata struct, or re-uses an already
+ * existing one, and resolves host name.
+ *
+ * if this function returns CURLE_OK and *async is set to TRUE, the resolve
+ * response will be coming asynchronously. If *async is FALSE, the name is
+ * already resolved.
+ *
+ * @param data The sessionhandle pointer
+ * @param in_connect is set to the next connection data pointer
+ * @param async is set TRUE when an async DNS resolution is pending
+ * @see Curl_setup_conn()
+ *
+ * *NOTE* this function assigns the conn->data pointer!
+ */
+
+static CURLcode create_conn(struct SessionHandle *data,
+                            struct connectdata **in_connect,
+                            bool *async)
+{
+  CURLcode result = CURLE_OK;
+  struct connectdata *conn;
+  struct connectdata *conn_temp = NULL;
+  size_t urllen;
+  char *user = NULL;
+  char *passwd = NULL;
+  char *options = NULL;
+  bool reuse;
+  char *proxy = NULL;
+  bool prot_missing = FALSE;
+  bool connections_available = TRUE;
+  bool force_reuse = FALSE;
+  bool waitpipe = FALSE;
+  size_t max_host_connections = Curl_multi_max_host_connections(data->multi);
+  size_t max_total_connections = Curl_multi_max_total_connections(data->multi);
+
+  *async = FALSE;
+
+  /*************************************************************
+   * Check input data
+   *************************************************************/
+
+  if(!data->change.url) {
+    result = CURLE_URL_MALFORMAT;
+    goto out;
+  }
+
+  /* First, split up the current URL in parts so that we can use the
+     parts for checking against the already present connections. In order
+     to not have to modify everything at once, we allocate a temporary
+     connection data struct and fill in for comparison purposes. */
+  conn = allocate_conn(data);
+
+  if(!conn) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto out;
+  }
+
+  /* We must set the return variable as soon as possible, so that our
+     parent can cleanup any possible allocs we may have done before
+     any failure */
+  *in_connect = conn;
+
+  /* This initing continues below, see the comment "Continue connectdata
+   * initialization here" */
+
+  /***********************************************************
+   * We need to allocate memory to store the path in. We get the size of the
+   * full URL to be sure, and we need to make it at least 256 bytes since
+   * other parts of the code will rely on this fact
+   ***********************************************************/
+#define LEAST_PATH_ALLOC 256
+  urllen=strlen(data->change.url);
+  if(urllen < LEAST_PATH_ALLOC)
+    urllen=LEAST_PATH_ALLOC;
+
+  /*
+   * We malloc() the buffers below urllen+2 to make room for 2 possibilities:
+   * 1 - an extra terminating zero
+   * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
+   */
+
+  Curl_safefree(data->state.pathbuffer);
+  data->state.path = NULL;
+
+  data->state.pathbuffer = malloc(urllen+2);
+  if(NULL == data->state.pathbuffer) {
+    result = CURLE_OUT_OF_MEMORY; /* really bad error */
+    goto out;
+  }
+  data->state.path = data->state.pathbuffer;
+
+  conn->host.rawalloc = malloc(urllen+2);
+  if(NULL == conn->host.rawalloc) {
+    Curl_safefree(data->state.pathbuffer);
+    data->state.path = NULL;
+    result = CURLE_OUT_OF_MEMORY;
+    goto out;
+  }
+
+  conn->host.name = conn->host.rawalloc;
+  conn->host.name[0] = 0;
+
+  user = strdup("");
+  passwd = strdup("");
+  options = strdup("");
+  if(!user || !passwd || !options) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto out;
+  }
+
+  result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd,
+                               &options);
+  if(result)
+    goto out;
+
+  /*************************************************************
+   * No protocol part in URL was used, add it!
+   *************************************************************/
+  if(prot_missing) {
+    /* We're guessing prefixes here and if we're told to use a proxy or if
+       we're gonna follow a Location: later or... then we need the protocol
+       part added so that we have a valid URL. */
+    char *reurl;
+    char *ch_lower;
+
+    reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url);
+
+    if(!reurl) {
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+
+    /* Change protocol prefix to lower-case */
+    for(ch_lower = reurl; *ch_lower != ':'; ch_lower++)
+      *ch_lower = (char)TOLOWER(*ch_lower);
+
+    if(data->change.url_alloc) {
+      Curl_safefree(data->change.url);
+      data->change.url_alloc = FALSE;
+    }
+
+    data->change.url = reurl;
+    data->change.url_alloc = TRUE; /* free this later */
+  }
+
+  /*************************************************************
+   * If the protocol can't handle url query strings, then cut
+   * off the unhandable part
+   *************************************************************/
+  if((conn->given->flags&PROTOPT_NOURLQUERY)) {
+    char *path_q_sep = strchr(conn->data->state.path, '?');
+    if(path_q_sep) {
+      /* according to rfc3986, allow the query (?foo=bar)
+         also on protocols that can't handle it.
+
+         cut the string-part after '?'
+      */
+
+      /* terminate the string */
+      path_q_sep[0] = 0;
+    }
+  }
+
+  if(data->set.str[STRING_BEARER]) {
+    conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
+    if(!conn->oauth_bearer) {
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+  }
+
+#ifndef CURL_DISABLE_PROXY
+  /*************************************************************
+   * Extract the user and password from the authentication string
+   *************************************************************/
+  if(conn->bits.proxy_user_passwd) {
+    result = parse_proxy_auth(data, conn);
+    if(result)
+      goto out;
+  }
+
+  /*************************************************************
+   * Detect what (if any) proxy to use
+   *************************************************************/
+  if(data->set.str[STRING_PROXY]) {
+    proxy = strdup(data->set.str[STRING_PROXY]);
+    /* if global proxy is set, this is it */
+    if(NULL == proxy) {
+      failf(data, "memory shortage");
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+  }
+
+  if(data->set.str[STRING_NOPROXY] &&
+     check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) {
+    free(proxy);  /* proxy is in exception list */
+    proxy = NULL;
+  }
+  else if(!proxy)
+    proxy = detect_proxy(conn);
+
+#ifdef USE_UNIX_SOCKETS
+  if(proxy && data->set.str[STRING_UNIX_SOCKET_PATH]) {
+    free(proxy);  /* Unix domain sockets cannot be proxied, so disable it */
+    proxy = NULL;
+  }
+#endif
+
+  if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
+    free(proxy);  /* Don't bother with an empty proxy string or if the
+                     protocol doesn't work with network */
+    proxy = NULL;
+  }
+
+  /***********************************************************************
+   * If this is supposed to use a proxy, we need to figure out the proxy host
+   * name, proxy type and port number, so that we can re-use an existing
+   * connection that may exist registered to the same proxy host.
+   ***********************************************************************/
+  if(proxy) {
+    result = parse_proxy(data, conn, proxy);
+
+    free(proxy); /* parse_proxy copies the proxy string */
+    proxy = NULL;
+
+    if(result)
+      goto out;
+
+    if((conn->proxytype == CURLPROXY_HTTP) ||
+       (conn->proxytype == CURLPROXY_HTTP_1_0)) {
+#ifdef CURL_DISABLE_HTTP
+      /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
+      result = CURLE_UNSUPPORTED_PROTOCOL;
+      goto out;
+#else
+      /* force this connection's protocol to become HTTP if not already
+         compatible - if it isn't tunneling through */
+      if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) &&
+         !conn->bits.tunnel_proxy)
+        conn->handler = &Curl_handler_http;
+
+      conn->bits.httpproxy = TRUE;
+#endif
+    }
+    else {
+      conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
+      conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
+    }
+    conn->bits.proxy = TRUE;
+  }
+  else {
+    /* we aren't using the proxy after all... */
+    conn->bits.proxy = FALSE;
+    conn->bits.httpproxy = FALSE;
+    conn->bits.proxy_user_passwd = FALSE;
+    conn->bits.tunnel_proxy = FALSE;
+  }
+
+#endif /* CURL_DISABLE_PROXY */
+
+  /*************************************************************
+   * If the protocol is using SSL and HTTP proxy is used, we set
+   * the tunnel_proxy bit.
+   *************************************************************/
+  if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
+    conn->bits.tunnel_proxy = TRUE;
+
+  /*************************************************************
+   * Figure out the remote port number and fix it in the URL
+   *************************************************************/
+  result = parse_remote_port(data, conn);
+  if(result)
+    goto out;
+
+  /* Check for overridden login details and set them accordingly so they
+     they are known when protocol->setup_connection is called! */
+  result = override_login(data, conn, &user, &passwd, &options);
+  if(result)
+    goto out;
+  result = set_login(conn, user, passwd, options);
+  if(result)
+    goto out;
+
+  /*************************************************************
+   * IDN-fix the hostnames
+   *************************************************************/
+  fix_hostname(data, conn, &conn->host);
+  if(conn->proxy.name && *conn->proxy.name)
+    fix_hostname(data, conn, &conn->proxy);
+
+  /*************************************************************
+   * Setup internals depending on protocol. Needs to be done after
+   * we figured out what/if proxy to use.
+   *************************************************************/
+  result = setup_connection_internals(conn);
+  if(result)
+    goto out;
+
+  conn->recv[FIRSTSOCKET] = Curl_recv_plain;
+  conn->send[FIRSTSOCKET] = Curl_send_plain;
+  conn->recv[SECONDARYSOCKET] = Curl_recv_plain;
+  conn->send[SECONDARYSOCKET] = Curl_send_plain;
+
+  /***********************************************************************
+   * file: is a special case in that it doesn't need a network connection
+   ***********************************************************************/
+#ifndef CURL_DISABLE_FILE
+  if(conn->handler->flags & PROTOPT_NONETWORK) {
+    bool done;
+    /* this is supposed to be the connect function so we better at least check
+       that the file is present here! */
+    DEBUGASSERT(conn->handler->connect_it);
+    result = conn->handler->connect_it(conn, &done);
+
+    /* Setup a "faked" transfer that'll do nothing */
+    if(!result) {
+      conn->data = data;
+      conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
+
+      Curl_conncache_add_conn(data->state.conn_cache, conn);
+
+      /*
+       * Setup whatever necessary for a resumed transfer
+       */
+      result = setup_range(data);
+      if(result) {
+        DEBUGASSERT(conn->handler->done);
+        /* we ignore the return code for the protocol-specific DONE */
+        (void)conn->handler->done(conn, result, FALSE);
+        goto out;
+      }
+
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
+                          -1, NULL); /* no upload */
+    }
+
+    /* since we skip do_init() */
+    Curl_init_do(data, conn);
+
+    goto out;
+  }
+#endif
+
+  /* Get a cloned copy of the SSL config situation stored in the
+     connection struct. But to get this going nicely, we must first make
+     sure that the strings in the master copy are pointing to the correct
+     strings in the session handle strings array!
+
+     Keep in mind that the pointers in the master copy are pointing to strings
+     that will be freed as part of the SessionHandle struct, but all cloned
+     copies will be separately allocated.
+  */
+  data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH];
+  data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE];
+  data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
+  data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
+  data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
+  data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
+  data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST];
+#ifdef USE_TLS_SRP
+  data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME];
+  data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
+#endif
+
+  if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto out;
+  }
+
+  prune_dead_connections(data);
+
+  /*************************************************************
+   * Check the current list of connections to see if we can
+   * re-use an already existing one or if we have to create a
+   * new one.
+   *************************************************************/
+
+  /* reuse_fresh is TRUE if we are told to use a new connection by force, but
+     we only acknowledge this option if this is not a re-used connection
+     already (which happens due to follow-location or during a HTTP
+     authentication phase). */
+  if(data->set.reuse_fresh && !data->state.this_is_a_follow)
+    reuse = FALSE;
+  else
+    reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe);
+
+  /* If we found a reusable connection, we may still want to
+     open a new connection if we are pipelining. */
+  if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
+    size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size;
+    if(pipelen > 0) {
+      infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
+            conn_temp->connection_id, pipelen);
+
+      if(conn_temp->bundle->num_connections < max_host_connections &&
+         data->state.conn_cache->num_connections < max_total_connections) {
+        /* We want a new connection anyway */
+        reuse = FALSE;
+
+        infof(data, "We can reuse, but we want a new connection anyway\n");
+      }
+    }
+  }
+
+  if(reuse) {
+    /*
+     * We already have a connection for this, we got the former connection
+     * in the conn_temp variable and thus we need to cleanup the one we
+     * just allocated before we can move along and use the previously
+     * existing one.
+     */
+    conn_temp->inuse = TRUE; /* mark this as being in use so that no other
+                                handle in a multi stack may nick it */
+    reuse_conn(conn, conn_temp);
+    free(conn);          /* we don't need this anymore */
+    conn = conn_temp;
+    *in_connect = conn;
+
+    infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
+          conn->connection_id,
+          conn->bits.proxy?"proxy":"host",
+          conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
+  }
+  else {
+    /* We have decided that we want a new connection. However, we may not
+       be able to do that if we have reached the limit of how many
+       connections we are allowed to open. */
+    struct connectbundle *bundle = NULL;
+
+    if(waitpipe)
+      /* There is a connection that *might* become usable for pipelining
+         "soon", and we wait for that */
+      connections_available = FALSE;
+    else
+      bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
+
+    if(max_host_connections > 0 && bundle &&
+       (bundle->num_connections >= max_host_connections)) {
+      struct connectdata *conn_candidate;
+
+      /* The bundle is full. Let's see if we can kill a connection. */
+      conn_candidate = find_oldest_idle_connection_in_bundle(data, bundle);
+
+      if(conn_candidate) {
+        /* Set the connection's owner correctly, then kill it */
+        conn_candidate->data = data;
+        (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
+      }
+      else {
+        infof(data, "No more connections allowed to host: %d\n",
+              max_host_connections);
+        connections_available = FALSE;
+      }
+    }
+
+    if(connections_available &&
+       (max_total_connections > 0) &&
+       (data->state.conn_cache->num_connections >= max_total_connections)) {
+      struct connectdata *conn_candidate;
+
+      /* The cache is full. Let's see if we can kill a connection. */
+      conn_candidate = find_oldest_idle_connection(data);
+
+      if(conn_candidate) {
+        /* Set the connection's owner correctly, then kill it */
+        conn_candidate->data = data;
+        (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
+      }
+      else {
+        infof(data, "No connections available in cache\n");
+        connections_available = FALSE;
+      }
+    }
+
+    if(!connections_available) {
+      infof(data, "No connections available.\n");
+
+      conn_free(conn);
+      *in_connect = NULL;
+
+      result = CURLE_NO_CONNECTION_AVAILABLE;
+      goto out;
+    }
+    else {
+      /*
+       * This is a brand new connection, so let's store it in the connection
+       * cache of ours!
+       */
+      Curl_conncache_add_conn(data->state.conn_cache, conn);
+    }
+
+#if defined(USE_NTLM)
+    /* If NTLM is requested in a part of this connection, make sure we don't
+       assume the state is fine as this is a fresh connection and NTLM is
+       connection based. */
+    if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
+       data->state.authhost.done) {
+      infof(data, "NTLM picked AND auth done set, clear picked!\n");
+      data->state.authhost.picked = CURLAUTH_NONE;
+      data->state.authhost.done = FALSE;
+    }
+
+    if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
+       data->state.authproxy.done) {
+      infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n");
+      data->state.authproxy.picked = CURLAUTH_NONE;
+      data->state.authproxy.done = FALSE;
+    }
+#endif
+  }
+
+  /* Mark the connection as used */
+  conn->inuse = TRUE;
+
+  /* Setup and init stuff before DO starts, in preparing for the transfer. */
+  Curl_init_do(data, conn);
+
+  /*
+   * Setup whatever necessary for a resumed transfer
+   */
+  result = setup_range(data);
+  if(result)
+    goto out;
+
+  /* Continue connectdata initialization here. */
+
+  /*
+   * Inherit the proper values from the urldata struct AFTER we have arranged
+   * the persistent connection stuff
+   */
+  conn->seek_func = data->set.seek_func;
+  conn->seek_client = data->set.seek_client;
+
+  /*************************************************************
+   * Resolve the address of the server or proxy
+   *************************************************************/
+  result = resolve_server(data, conn, async);
+
+  out:
+
+  free(options);
+  free(passwd);
+  free(user);
+  free(proxy);
+  return result;
+}
+
+/* Curl_setup_conn() is called after the name resolve initiated in
+ * create_conn() is all done.
+ *
+ * Curl_setup_conn() also handles reused connections
+ *
+ * conn->data MUST already have been setup fine (in create_conn)
+ */
+
+CURLcode Curl_setup_conn(struct connectdata *conn,
+                         bool *protocol_done)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  Curl_pgrsTime(data, TIMER_NAMELOOKUP);
+
+  if(conn->handler->flags & PROTOPT_NONETWORK) {
+    /* nothing to setup when not using a network */
+    *protocol_done = TRUE;
+    return result;
+  }
+  *protocol_done = FALSE; /* default to not done */
+
+  /* set proxy_connect_closed to false unconditionally already here since it
+     is used strictly to provide extra information to a parent function in the
+     case of proxy CONNECT failures and we must make sure we don't have it
+     lingering set from a previous invoke */
+  conn->bits.proxy_connect_closed = FALSE;
+
+  /*
+   * Set user-agent. Used for HTTP, but since we can attempt to tunnel
+   * basically anything through a http proxy we can't limit this based on
+   * protocol.
+   */
+  if(data->set.str[STRING_USERAGENT]) {
+    Curl_safefree(conn->allocptr.uagent);
+    conn->allocptr.uagent =
+      aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
+    if(!conn->allocptr.uagent)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  data->req.headerbytecount = 0;
+
+#ifdef CURL_DO_LINEEND_CONV
+  data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
+#endif /* CURL_DO_LINEEND_CONV */
+
+  /* set start time here for timeout purposes in the connect procedure, it
+     is later set again for the progress meter purpose */
+  conn->now = Curl_tvnow();
+
+  if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
+    conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
+    result = Curl_connecthost(conn, conn->dns_entry);
+    if(result)
+      return result;
+  }
+  else {
+    Curl_pgrsTime(data, TIMER_CONNECT);    /* we're connected already */
+    Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
+    conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
+    *protocol_done = TRUE;
+    Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
+    Curl_verboseconnect(conn);
+  }
+
+  conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
+                               set this here perhaps a second time */
+
+#ifdef __EMX__
+  /*
+   * This check is quite a hack. We're calling _fsetmode to fix the problem
+   * with fwrite converting newline characters (you get mangled text files,
+   * and corrupted binary files when you download to stdout and redirect it to
+   * a file).
+   */
+
+  if((data->set.out)->_handle == NULL) {
+    _fsetmode(stdout, "b");
+  }
+#endif
+
+  return result;
+}
+
+CURLcode Curl_connect(struct SessionHandle *data,
+                      struct connectdata **in_connect,
+                      bool *asyncp,
+                      bool *protocol_done)
+{
+  CURLcode result;
+
+  *asyncp = FALSE; /* assume synchronous resolves by default */
+
+  /* call the stuff that needs to be called */
+  result = create_conn(data, in_connect, asyncp);
+
+  if(!result) {
+    /* no error */
+    if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size)
+      /* pipelining */
+      *protocol_done = TRUE;
+    else if(!*asyncp) {
+      /* DNS resolution is done: that's either because this is a reused
+         connection, in which case DNS was unnecessary, or because DNS
+         really did finish already (synch resolver/fast async resolve) */
+      result = Curl_setup_conn(*in_connect, protocol_done);
+    }
+  }
+
+  if(result == CURLE_NO_CONNECTION_AVAILABLE) {
+    *in_connect = NULL;
+    return result;
+  }
+
+  if(result && *in_connect) {
+    /* We're not allowed to return failure with memory left allocated
+       in the connectdata struct, free those here */
+    Curl_disconnect(*in_connect, FALSE); /* close the connection */
+    *in_connect = NULL;           /* return a NULL */
+  }
+
+  return result;
+}
+
+CURLcode Curl_done(struct connectdata **connp,
+                   CURLcode status,  /* an error if this is called after an
+                                        error was detected */
+                   bool premature)
+{
+  CURLcode result;
+  struct connectdata *conn;
+  struct SessionHandle *data;
+
+  DEBUGASSERT(*connp);
+
+  conn = *connp;
+  data = conn->data;
+
+  DEBUGF(infof(data, "Curl_done\n"));
+
+  if(data->state.done)
+    /* Stop if Curl_done() has already been called */
+    return CURLE_OK;
+
+  Curl_getoff_all_pipelines(data, conn);
+
+  /* Cleanup possible redirect junk */
+  free(data->req.newurl);
+  data->req.newurl = NULL;
+  free(data->req.location);
+  data->req.location = NULL;
+
+  switch(status) {
+  case CURLE_ABORTED_BY_CALLBACK:
+  case CURLE_READ_ERROR:
+  case CURLE_WRITE_ERROR:
+    /* When we're aborted due to a callback return code it basically have to
+       be counted as premature as there is trouble ahead if we don't. We have
+       many callbacks and protocols work differently, we could potentially do
+       this more fine-grained in the future. */
+    premature = TRUE;
+  default:
+    break;
+  }
+
+  /* this calls the protocol-specific function pointer previously set */
+  if(conn->handler->done)
+    result = conn->handler->done(conn, status, premature);
+  else
+    result = status;
+
+  if(CURLE_ABORTED_BY_CALLBACK != result) {
+    /* avoid this if we already aborted by callback to avoid this calling
+       another callback */
+    CURLcode rc = Curl_pgrsDone(conn);
+    if(!result && rc)
+      result = CURLE_ABORTED_BY_CALLBACK;
+  }
+
+  if((conn->send_pipe->size + conn->recv_pipe->size != 0 &&
+      !data->set.reuse_forbid &&
+      !conn->bits.close)) {
+    /* Stop if pipeline is not empty and we do not have to close
+       connection. */
+    DEBUGF(infof(data, "Connection still in use, no more Curl_done now!\n"));
+    return CURLE_OK;
+  }
+
+  data->state.done = TRUE; /* called just now! */
+  Curl_resolver_cancel(conn);
+
+  if(conn->dns_entry) {
+    Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
+    conn->dns_entry = NULL;
+  }
+
+  /* if the transfer was completed in a paused state there can be buffered
+     data left to write and then kill */
+  free(data->state.tempwrite);
+  data->state.tempwrite = NULL;
+
+  /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
+     forced us to close this connection. This is ignored for requests taking
+     place in a NTLM authentication handshake
+
+     if conn->bits.close is TRUE, it means that the connection should be
+     closed in spite of all our efforts to be nice, due to protocol
+     restrictions in our or the server's end
+
+     if premature is TRUE, it means this connection was said to be DONE before
+     the entire request operation is complete and thus we can't know in what
+     state it is for re-using, so we're forced to close it. In a perfect world
+     we can add code that keep track of if we really must close it here or not,
+     but currently we have no such detail knowledge.
+  */
+
+  if((data->set.reuse_forbid
+#if defined(USE_NTLM)
+      && !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
+           conn->proxyntlm.state == NTLMSTATE_TYPE2)
+#endif
+     ) || conn->bits.close || premature) {
+    CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
+
+    /* If we had an error already, make sure we return that one. But
+       if we got a new error, return that. */
+    if(!result && res2)
+      result = res2;
+  }
+  else {
+    /* the connection is no longer in use */
+    if(ConnectionDone(data, conn)) {
+      /* remember the most recently used connection */
+      data->state.lastconnect = conn;
+
+      infof(data, "Connection #%ld to host %s left intact\n",
+            conn->connection_id,
+            conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
+    }
+    else
+      data->state.lastconnect = NULL;
+  }
+
+  *connp = NULL; /* to make the caller of this function better detect that
+                    this was either closed or handed over to the connection
+                    cache here, and therefore cannot be used from this point on
+                 */
+  Curl_free_request_state(data);
+
+  return result;
+}
+
+/*
+ * Curl_init_do() inits the readwrite session. This is inited each time (in
+ * the DO function before the protocol-specific DO functions are invoked) for
+ * a transfer, sometimes multiple times on the same SessionHandle. Make sure
+ * nothing in here depends on stuff that are setup dynamically for the
+ * transfer.
+ *
+ * Allow this function to get called with 'conn' set to NULL.
+ */
+
+CURLcode Curl_init_do(struct SessionHandle *data, struct connectdata *conn)
+{
+  struct SingleRequest *k = &data->req;
+
+  if(conn)
+    conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
+                                 * use */
+
+  data->state.done = FALSE; /* Curl_done() is not called yet */
+  data->state.expect100header = FALSE;
+
+  if(data->set.opt_no_body)
+    /* in HTTP lingo, no body means using the HEAD request... */
+    data->set.httpreq = HTTPREQ_HEAD;
+  else if(HTTPREQ_HEAD == data->set.httpreq)
+    /* ... but if unset there really is no perfect method that is the
+       "opposite" of HEAD but in reality most people probably think GET
+       then. The important thing is that we can't let it remain HEAD if the
+       opt_no_body is set FALSE since then we'll behave wrong when getting
+       HTTP. */
+    data->set.httpreq = HTTPREQ_GET;
+
+  k->start = Curl_tvnow(); /* start time */
+  k->now = k->start;   /* current time is now */
+  k->header = TRUE; /* assume header */
+
+  k->bytecount = 0;
+
+  k->buf = data->state.buffer;
+  k->uploadbuf = data->state.uploadbuffer;
+  k->hbufp = data->state.headerbuff;
+  k->ignorebody=FALSE;
+
+  Curl_speedinit(data);
+
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+
+  return CURLE_OK;
+}
+
+/*
+ * do_complete is called when the DO actions are complete.
+ *
+ * We init chunking and trailer bits to their default values here immediately
+ * before receiving any header data for the current request in the pipeline.
+ */
+static void do_complete(struct connectdata *conn)
+{
+  conn->data->req.chunk=FALSE;
+  conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
+                           conn->sockfd:conn->writesockfd)+1;
+  Curl_pgrsTime(conn->data, TIMER_PRETRANSFER);
+}
+
+CURLcode Curl_do(struct connectdata **connp, bool *done)
+{
+  CURLcode result=CURLE_OK;
+  struct connectdata *conn = *connp;
+  struct SessionHandle *data = conn->data;
+
+  if(conn->handler->do_it) {
+    /* generic protocol-specific function pointer set in curl_connect() */
+    result = conn->handler->do_it(conn, done);
+
+    /* This was formerly done in transfer.c, but we better do it here */
+    if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
+      /*
+       * If the connection is using an easy handle, call reconnect
+       * to re-establish the connection.  Otherwise, let the multi logic
+       * figure out how to re-establish the connection.
+       */
+      if(!data->multi) {
+        result = Curl_reconnect_request(connp);
+
+        if(!result) {
+          /* ... finally back to actually retry the DO phase */
+          conn = *connp; /* re-assign conn since Curl_reconnect_request
+                            creates a new connection */
+          result = conn->handler->do_it(conn, done);
+        }
+      }
+      else
+        return result;
+    }
+
+    if(!result && *done)
+      /* do_complete must be called after the protocol-specific DO function */
+      do_complete(conn);
+  }
+  return result;
+}
+
+/*
+ * Curl_do_more() is called during the DO_MORE multi state. It is basically a
+ * second stage DO state which (wrongly) was introduced to support FTP's
+ * second connection.
+ *
+ * TODO: A future libcurl should be able to work away this state.
+ *
+ * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
+ * DOING state there's more work to do!
+ */
+
+CURLcode Curl_do_more(struct connectdata *conn, int *complete)
+{
+  CURLcode result=CURLE_OK;
+
+  *complete = 0;
+
+  if(conn->handler->do_more)
+    result = conn->handler->do_more(conn, complete);
+
+  if(!result && (*complete == 1))
+    /* do_complete must be called after the protocol-specific DO function */
+    do_complete(conn);
+
+  return result;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/url.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/url.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/url.h	(revision 164)
@@ -0,0 +1,86 @@
+#ifndef HEADER_CURL_URL_H
+#define HEADER_CURL_URL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/*
+ * Prototypes for library-wide functions provided by url.c
+ */
+
+CURLcode Curl_init_do(struct SessionHandle *data, struct connectdata *conn);
+CURLcode Curl_open(struct SessionHandle **curl);
+CURLcode Curl_init_userdefined(struct UserDefined *set);
+CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
+                     va_list arg);
+CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src);
+void Curl_freeset(struct SessionHandle * data);
+CURLcode Curl_close(struct SessionHandle *data); /* opposite of curl_open() */
+CURLcode Curl_connect(struct SessionHandle *, struct connectdata **,
+                      bool *async, bool *protocol_connect);
+CURLcode Curl_do(struct connectdata **, bool *done);
+CURLcode Curl_do_more(struct connectdata *, int *completed);
+CURLcode Curl_done(struct connectdata **, CURLcode, bool premature);
+CURLcode Curl_disconnect(struct connectdata *, bool dead_connection);
+CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
+CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
+CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
+CURLcode Curl_setup_conn(struct connectdata *conn,
+                         bool *protocol_done);
+void Curl_free_request_state(struct SessionHandle *data);
+
+int Curl_protocol_getsock(struct connectdata *conn,
+                          curl_socket_t *socks,
+                          int numsocks);
+int Curl_doing_getsock(struct connectdata *conn,
+                       curl_socket_t *socks,
+                       int numsocks);
+
+bool Curl_isPipeliningEnabled(const struct SessionHandle *handle);
+CURLcode Curl_addHandleToPipeline(struct SessionHandle *handle,
+                                  struct curl_llist *pipeline);
+int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
+                                  struct curl_llist *pipeline);
+/* remove the specified connection from all (possible) pipelines and related
+   queues */
+void Curl_getoff_all_pipelines(struct SessionHandle *data,
+                               struct connectdata *conn);
+
+void Curl_close_connections(struct SessionHandle *data);
+
+#define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */
+#define CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE "rcmd" /* default socks5 gssapi
+                                                     service */
+#define CURL_DEFAULT_PROXY_SERVICE_NAME "HTTP" /* default negotiate proxy
+                                                  service */
+#define CURL_DEFAULT_SERVICE_NAME "HTTP"  /* default negotiate service */
+
+CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex);
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+#define Curl_verboseconnect(x)  Curl_nop_stmt
+#else
+void Curl_verboseconnect(struct connectdata *conn);
+#endif
+
+
+#endif /* HEADER_CURL_URL_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/urldata.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/urldata.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/urldata.h	(revision 164)
@@ -0,0 +1,1721 @@
+#ifndef HEADER_CURL_URLDATA_H
+#define HEADER_CURL_URLDATA_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This file is for lib internal stuff */
+
+#include "curl_setup.h"
+
+#define PORT_FTP 21
+#define PORT_FTPS 990
+#define PORT_TELNET 23
+#define PORT_HTTP 80
+#define PORT_HTTPS 443
+#define PORT_DICT 2628
+#define PORT_LDAP 389
+#define PORT_LDAPS 636
+#define PORT_TFTP 69
+#define PORT_SSH 22
+#define PORT_IMAP 143
+#define PORT_IMAPS 993
+#define PORT_POP3 110
+#define PORT_POP3S 995
+#define PORT_SMB 445
+#define PORT_SMBS 445
+#define PORT_SMTP 25
+#define PORT_SMTPS 465 /* sometimes called SSMTP */
+#define PORT_RTSP 554
+#define PORT_RTMP 1935
+#define PORT_RTMPT PORT_HTTP
+#define PORT_RTMPS PORT_HTTPS
+#define PORT_GOPHER 70
+
+#define DICT_MATCH "/MATCH:"
+#define DICT_MATCH2 "/M:"
+#define DICT_MATCH3 "/FIND:"
+#define DICT_DEFINE "/DEFINE:"
+#define DICT_DEFINE2 "/D:"
+#define DICT_DEFINE3 "/LOOKUP:"
+
+#define CURL_DEFAULT_USER "anonymous"
+#define CURL_DEFAULT_PASSWORD "ftp@example.com"
+
+/* Convenience defines for checking protocols or their SSL based version. Each
+   protocol handler should only ever have a single CURLPROTO_ in its protocol
+   field. */
+#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP|CURLPROTO_HTTPS)
+#define PROTO_FAMILY_FTP  (CURLPROTO_FTP|CURLPROTO_FTPS)
+#define PROTO_FAMILY_POP3 (CURLPROTO_POP3|CURLPROTO_POP3S)
+#define PROTO_FAMILY_SMB  (CURLPROTO_SMB|CURLPROTO_SMBS)
+#define PROTO_FAMILY_SMTP (CURLPROTO_SMTP|CURLPROTO_SMTPS)
+
+#define DEFAULT_CONNCACHE_SIZE 5
+
+/* length of longest IPv6 address string including the trailing null */
+#define MAX_IPADR_LEN sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")
+
+/* Default FTP/IMAP etc response timeout in milliseconds.
+   Symbian OS panics when given a timeout much greater than 1/2 hour.
+*/
+#define RESP_TIMEOUT (1800*1000)
+
+#include "cookie.h"
+#include "formdata.h"
+
+#ifdef USE_OPENSSL
+#include <openssl/ssl.h>
+#ifdef HAVE_OPENSSL_ENGINE_H
+#include <openssl/engine.h>
+#endif
+#endif /* USE_OPENSSL */
+
+#ifdef USE_GNUTLS
+#include <gnutls/gnutls.h>
+#endif
+
+#ifdef USE_MBEDTLS
+
+#include <mbedtls/ssl.h>
+#include <mbedtls/version.h>
+#include <mbedtls/entropy.h>
+#include <mbedtls/ctr_drbg.h>
+
+#elif defined USE_POLARSSL
+
+#include <polarssl/ssl.h>
+#include <polarssl/version.h>
+#if POLARSSL_VERSION_NUMBER<0x01010000
+#include <polarssl/havege.h>
+#else
+#include <polarssl/entropy.h>
+#include <polarssl/ctr_drbg.h>
+#endif /* POLARSSL_VERSION_NUMBER<0x01010000 */
+
+#endif /* USE_POLARSSL */
+
+#ifdef USE_CYASSL
+#undef OCSP_REQUEST  /* avoid cyassl/openssl/ssl.h clash with wincrypt.h */
+#undef OCSP_RESPONSE /* avoid cyassl/openssl/ssl.h clash with wincrypt.h */
+#include <cyassl/openssl/ssl.h>
+#endif
+
+#ifdef USE_NSS
+#include <nspr.h>
+#include <pk11pub.h>
+#endif
+
+#ifdef USE_GSKIT
+#include <gskssl.h>
+#endif
+
+#ifdef USE_AXTLS
+#include <axTLS/config.h>
+#include <axTLS/ssl.h>
+#undef malloc
+#undef calloc
+#undef realloc
+#endif /* USE_AXTLS */
+
+#ifdef USE_SCHANNEL
+#include "curl_sspi.h"
+#include <schnlsp.h>
+#include <schannel.h>
+#endif
+
+#ifdef USE_DARWINSSL
+#include <Security/Security.h>
+/* For some reason, when building for iOS, the omnibus header above does
+ * not include SecureTransport.h as of iOS SDK 5.1. */
+#include <Security/SecureTransport.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "timeval.h"
+
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>               /* for content-encoding */
+#ifdef __SYMBIAN32__
+/* zlib pollutes the namespace with this definition */
+#undef WIN32
+#endif
+#endif
+
+#include <curl/curl.h>
+
+#include "http_chunks.h" /* for the structs and enum stuff */
+#include "hostip.h"
+#include "hash.h"
+#include "splay.h"
+
+#include "imap.h"
+#include "pop3.h"
+#include "smtp.h"
+#include "ftp.h"
+#include "file.h"
+#include "ssh.h"
+#include "http.h"
+#include "rtsp.h"
+#include "smb.h"
+#include "wildcard.h"
+#include "multihandle.h"
+
+#ifdef HAVE_GSSAPI
+# ifdef HAVE_GSSGNU
+#  include <gss.h>
+# elif defined HAVE_GSSMIT
+#  include <gssapi/gssapi.h>
+#  include <gssapi/gssapi_generic.h>
+# else
+#  include <gssapi.h>
+# endif
+#endif
+
+#ifdef HAVE_LIBSSH2_H
+#include <libssh2.h>
+#include <libssh2_sftp.h>
+#endif /* HAVE_LIBSSH2_H */
+
+/* Download buffer size, keep it fairly big for speed reasons */
+#undef BUFSIZE
+#define BUFSIZE CURL_MAX_WRITE_SIZE
+
+/* Initial size of the buffer to store headers in, it'll be enlarged in case
+   of need. */
+#define HEADERSIZE 256
+
+#define CURLEASY_MAGIC_NUMBER 0xc0dedbadU
+#define GOOD_EASY_HANDLE(x) \
+  ((x) && (((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER))
+
+/* Some convenience macros to get the larger/smaller value out of two given.
+   We prefix with CURL to prevent name collisions. */
+#define CURLMAX(x,y) ((x)>(y)?(x):(y))
+#define CURLMIN(x,y) ((x)<(y)?(x):(y))
+
+
+#ifdef HAVE_GSSAPI
+/* Types needed for krb5-ftp connections */
+struct krb5buffer {
+  void *data;
+  size_t size;
+  size_t index;
+  int eof_flag;
+};
+
+enum protection_level {
+  PROT_NONE, /* first in list */
+  PROT_CLEAR,
+  PROT_SAFE,
+  PROT_CONFIDENTIAL,
+  PROT_PRIVATE,
+  PROT_CMD,
+  PROT_LAST /* last in list */
+};
+#endif
+
+#ifdef USE_SCHANNEL
+/* Structs to store Schannel handles */
+struct curl_schannel_cred {
+  CredHandle cred_handle;
+  TimeStamp time_stamp;
+  int refcount;
+  bool cached;
+};
+
+struct curl_schannel_ctxt {
+  CtxtHandle ctxt_handle;
+  TimeStamp time_stamp;
+};
+#endif
+
+/* enum for the nonblocking SSL connection state machine */
+typedef enum {
+  ssl_connect_1,
+  ssl_connect_2,
+  ssl_connect_2_reading,
+  ssl_connect_2_writing,
+  ssl_connect_3,
+  ssl_connect_done
+} ssl_connect_state;
+
+typedef enum {
+  ssl_connection_none,
+  ssl_connection_negotiating,
+  ssl_connection_complete
+} ssl_connection_state;
+
+/* struct for data related to each SSL connection */
+struct ssl_connect_data {
+  /* Use ssl encrypted communications TRUE/FALSE, not necessarily using it atm
+     but at least asked to or meaning to use it. See 'state' for the exact
+     current state of the connection. */
+  bool use;
+  ssl_connection_state state;
+  ssl_connect_state connecting_state;
+#if defined(USE_OPENSSL)
+  /* these ones requires specific SSL-types */
+  SSL_CTX* ctx;
+  SSL*     handle;
+  X509*    server_cert;
+#elif defined(USE_GNUTLS)
+  gnutls_session_t session;
+  gnutls_certificate_credentials_t cred;
+#ifdef USE_TLS_SRP
+  gnutls_srp_client_credentials_t srp_client_cred;
+#endif
+#elif defined(USE_MBEDTLS)
+  mbedtls_ctr_drbg_context ctr_drbg;
+  mbedtls_entropy_context entropy;
+  mbedtls_ssl_context ssl;
+  mbedtls_ssl_session ssn;
+  int server_fd;
+  mbedtls_x509_crt cacert;
+  mbedtls_x509_crt clicert;
+  mbedtls_x509_crl crl;
+  mbedtls_pk_context pk;
+  mbedtls_ssl_config config;
+#elif defined(USE_POLARSSL)
+  ctr_drbg_context ctr_drbg;
+  entropy_context entropy;
+  ssl_context ssl;
+  ssl_session ssn;
+  int server_fd;
+  x509_crt cacert;
+  x509_crt clicert;
+  x509_crl crl;
+  rsa_context rsa;
+#elif defined(USE_CYASSL)
+  SSL_CTX* ctx;
+  SSL*     handle;
+#elif defined(USE_NSS)
+  PRFileDesc *handle;
+  char *client_nickname;
+  struct SessionHandle *data;
+  struct curl_llist *obj_list;
+  PK11GenericObject *obj_clicert;
+#elif defined(USE_GSKIT)
+  gsk_handle handle;
+  int iocport;
+#elif defined(USE_AXTLS)
+  SSL_CTX* ssl_ctx;
+  SSL*     ssl;
+#elif defined(USE_SCHANNEL)
+  struct curl_schannel_cred *cred;
+  struct curl_schannel_ctxt *ctxt;
+  SecPkgContext_StreamSizes stream_sizes;
+  size_t encdata_length, decdata_length;
+  size_t encdata_offset, decdata_offset;
+  unsigned char *encdata_buffer, *decdata_buffer;
+  unsigned long req_flags, ret_flags;
+  CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
+  bool recv_sspi_close_notify; /* true if connection closed by close_notify */
+  bool recv_connection_closed; /* true if connection closed, regardless how */
+#elif defined(USE_DARWINSSL)
+  SSLContextRef ssl_ctx;
+  curl_socket_t ssl_sockfd;
+  bool ssl_direction; /* true if writing, false if reading */
+  size_t ssl_write_buffered_length;
+#elif defined(USE_SSL)
+#error "SSL backend specific information missing from ssl_connect_data"
+#endif
+};
+
+struct ssl_config_data {
+  long version;          /* what version the client wants to use */
+  long certverifyresult; /* result from the certificate verification */
+
+  bool verifypeer;       /* set TRUE if this is desired */
+  bool verifyhost;       /* set TRUE if CN/SAN must match hostname */
+  bool verifystatus;     /* set TRUE if certificate status must be checked */
+  char *CApath;          /* certificate dir (doesn't work on windows) */
+  char *CAfile;          /* certificate to verify peer against */
+  const char *CRLfile;   /* CRL to check certificate revocation */
+  const char *issuercert;/* optional issuer certificate filename */
+  char *random_file;     /* path to file containing "random" data */
+  char *egdsocket;       /* path to file containing the EGD daemon socket */
+  char *cipher_list;     /* list of ciphers to use */
+  size_t max_ssl_sessions; /* SSL session id cache size */
+  curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
+  void *fsslctxp;        /* parameter for call back */
+  bool sessionid;        /* cache session IDs or not */
+  bool certinfo;         /* gather lots of certificate info */
+  bool falsestart;
+
+#ifdef USE_TLS_SRP
+  char *username; /* TLS username (for, e.g., SRP) */
+  char *password; /* TLS password (for, e.g., SRP) */
+  enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */
+#endif
+};
+
+/* information stored about one single SSL session */
+struct curl_ssl_session {
+  char *name;       /* host name for which this ID was used */
+  void *sessionid;  /* as returned from the SSL layer */
+  size_t idsize;    /* if known, otherwise 0 */
+  long age;         /* just a number, the higher the more recent */
+  int remote_port;  /* remote port to connect to */
+  struct ssl_config_data ssl_config; /* setup for this session */
+};
+
+/* Struct used for Digest challenge-response authentication */
+struct digestdata {
+#if defined(USE_WINDOWS_SSPI)
+  BYTE *input_token;
+  size_t input_token_len;
+#else
+  char *nonce;
+  char *cnonce;
+  char *realm;
+  int algo;
+  bool stale; /* set true for re-negotiation */
+  char *opaque;
+  char *qop;
+  char *algorithm;
+  int nc; /* nounce count */
+#endif
+};
+
+typedef enum {
+  NTLMSTATE_NONE,
+  NTLMSTATE_TYPE1,
+  NTLMSTATE_TYPE2,
+  NTLMSTATE_TYPE3,
+  NTLMSTATE_LAST
+} curlntlm;
+
+#ifdef USE_WINDOWS_SSPI
+#include "curl_sspi.h"
+#endif
+
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+#include <iconv.h>
+#endif
+
+/* Struct used for GSSAPI (Kerberos V5) authentication */
+#if defined(USE_KERBEROS5)
+struct kerberos5data {
+#if defined(USE_WINDOWS_SSPI)
+  CredHandle *credentials;
+  CtxtHandle *context;
+  TCHAR *spn;
+  SEC_WINNT_AUTH_IDENTITY identity;
+  SEC_WINNT_AUTH_IDENTITY *p_identity;
+  size_t token_max;
+  BYTE *output_token;
+#else
+  gss_ctx_id_t context;
+  gss_name_t spn;
+#endif
+};
+#endif
+
+/* Struct used for NTLM challenge-response authentication */
+#if defined(USE_NTLM)
+struct ntlmdata {
+  curlntlm state;
+#ifdef USE_WINDOWS_SSPI
+  CredHandle *credentials;
+  CtxtHandle *context;
+  SEC_WINNT_AUTH_IDENTITY identity;
+  SEC_WINNT_AUTH_IDENTITY *p_identity;
+  size_t token_max;
+  BYTE *output_token;
+  BYTE *input_token;
+  size_t input_token_len;
+#else
+  unsigned int flags;
+  unsigned char nonce[8];
+  void* target_info; /* TargetInfo received in the ntlm type-2 message */
+  unsigned int target_info_len;
+#endif
+};
+#endif
+
+#ifdef USE_SPNEGO
+struct negotiatedata {
+  /* When doing Negotiate (SPNEGO) auth, we first need to send a token
+     and then validate the received one. */
+  enum { GSS_AUTHNONE, GSS_AUTHRECV, GSS_AUTHSENT } state;
+#ifdef HAVE_GSSAPI
+  OM_uint32 status;
+  gss_ctx_id_t context;
+  gss_name_t server_name;
+  gss_buffer_desc output_token;
+#else
+#ifdef USE_WINDOWS_SSPI
+  DWORD status;
+  CredHandle *credentials;
+  CtxtHandle *context;
+  SEC_WINNT_AUTH_IDENTITY identity;
+  SEC_WINNT_AUTH_IDENTITY *p_identity;
+  TCHAR *server_name;
+  size_t token_max;
+  BYTE *output_token;
+  size_t output_token_length;
+#endif
+#endif
+};
+#endif
+
+
+/*
+ * Boolean values that concerns this connection.
+ */
+struct ConnectBits {
+  /* always modify bits.close with the connclose() and connkeep() macros! */
+  bool close; /* if set, we close the connection after this request */
+  bool reuse; /* if set, this is a re-used connection */
+  bool proxy; /* if set, this transfer is done through a proxy - any type */
+  bool httpproxy;    /* if set, this transfer is done through a http proxy */
+  bool user_passwd;    /* do we use user+password for this connection? */
+  bool proxy_user_passwd; /* user+password for the proxy? */
+  bool ipv6_ip; /* we communicate with a remote site specified with pure IPv6
+                   IP address */
+  bool ipv6;    /* we communicate with a site using an IPv6 address */
+
+  bool do_more; /* this is set TRUE if the ->curl_do_more() function is
+                   supposed to be called, after ->curl_do() */
+  bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set
+                         the first time on the first connect function call */
+  bool protoconnstart;/* the protocol layer has STARTED its operation after
+                         the TCP layer connect */
+
+  bool retry;         /* this connection is about to get closed and then
+                         re-attempted at another connection. */
+  bool tunnel_proxy;  /* if CONNECT is used to "tunnel" through the proxy.
+                         This is implicit when SSL-protocols are used through
+                         proxies, but can also be enabled explicitly by
+                         apps */
+  bool authneg;       /* TRUE when the auth phase has started, which means
+                         that we are creating a request with an auth header,
+                         but it is not the final request in the auth
+                         negotiation. */
+  bool rewindaftersend;/* TRUE when the sending couldn't be stopped even
+                          though it will be discarded. When the whole send
+                          operation is done, we must call the data rewind
+                          callback. */
+  bool ftp_use_epsv;  /* As set with CURLOPT_FTP_USE_EPSV, but if we find out
+                         EPSV doesn't work we disable it for the forthcoming
+                         requests */
+
+  bool ftp_use_eprt;  /* As set with CURLOPT_FTP_USE_EPRT, but if we find out
+                         EPRT doesn't work we disable it for the forthcoming
+                         requests */
+  bool netrc;         /* name+password provided by netrc */
+  bool userpwd_in_url; /* name+password found in url */
+  bool stream_was_rewound; /* Indicates that the stream was rewound after a
+                              request read past the end of its response byte
+                              boundary */
+  bool proxy_connect_closed; /* set true if a proxy disconnected the
+                                connection in a CONNECT request with auth, so
+                                that libcurl should reconnect and continue. */
+  bool bound; /* set true if bind() has already been done on this socket/
+                 connection */
+  bool type_set;  /* type= was used in the URL */
+  bool multiplex; /* connection is multiplexed */
+};
+
+struct hostname {
+  char *rawalloc; /* allocated "raw" version of the name */
+  char *encalloc; /* allocated IDN-encoded version of the name */
+  char *name;     /* name to use internally, might be encoded, might be raw */
+  const char *dispname; /* name to display, as 'name' might be encoded */
+};
+
+/*
+ * Flags on the keepon member of the Curl_transfer_keeper
+ */
+
+#define KEEP_NONE  0
+#define KEEP_RECV  (1<<0)     /* there is or may be data to read */
+#define KEEP_SEND (1<<1)     /* there is or may be data to write */
+#define KEEP_RECV_HOLD (1<<2) /* when set, no reading should be done but there
+                                 might still be data to read */
+#define KEEP_SEND_HOLD (1<<3) /* when set, no writing should be done but there
+                                  might still be data to write */
+#define KEEP_RECV_PAUSE (1<<4) /* reading is paused */
+#define KEEP_SEND_PAUSE (1<<5) /* writing is paused */
+
+#define KEEP_RECVBITS (KEEP_RECV | KEEP_RECV_HOLD | KEEP_RECV_PAUSE)
+#define KEEP_SENDBITS (KEEP_SEND | KEEP_SEND_HOLD | KEEP_SEND_PAUSE)
+
+
+#ifdef HAVE_LIBZ
+typedef enum {
+  ZLIB_UNINIT,          /* uninitialized */
+  ZLIB_INIT,            /* initialized */
+  ZLIB_GZIP_HEADER,     /* reading gzip header */
+  ZLIB_GZIP_INFLATING,  /* inflating gzip stream */
+  ZLIB_INIT_GZIP        /* initialized in transparent gzip mode */
+} zlibInitState;
+#endif
+
+#ifdef CURLRES_ASYNCH
+struct Curl_async {
+  char *hostname;
+  int port;
+  struct Curl_dns_entry *dns;
+  bool done;  /* set TRUE when the lookup is complete */
+  int status; /* if done is TRUE, this is the status from the callback */
+  void *os_specific;  /* 'struct thread_data' for Windows */
+};
+#endif
+
+#define FIRSTSOCKET     0
+#define SECONDARYSOCKET 1
+
+/* These function pointer types are here only to allow easier typecasting
+   within the source when we need to cast between data pointers (such as NULL)
+   and function pointers. */
+typedef CURLcode (*Curl_do_more_func)(struct connectdata *, int *);
+typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool);
+
+enum expect100 {
+  EXP100_SEND_DATA,           /* enough waiting, just send the body now */
+  EXP100_AWAITING_CONTINUE,   /* waiting for the 100 Continue header */
+  EXP100_SENDING_REQUEST,     /* still sending the request but will wait for
+                                 the 100 header once done with the request */
+  EXP100_FAILED               /* used on 417 Expectation Failed */
+};
+
+enum upgrade101 {
+  UPGR101_INIT,               /* default state */
+  UPGR101_REQUESTED,          /* upgrade requested */
+  UPGR101_RECEIVED,           /* response received */
+  UPGR101_WORKING             /* talking upgraded protocol */
+};
+
+/*
+ * Request specific data in the easy handle (SessionHandle).  Previously,
+ * these members were on the connectdata struct but since a conn struct may
+ * now be shared between different SessionHandles, we store connection-specific
+ * data here. This struct only keeps stuff that's interesting for *this*
+ * request, as it will be cleared between multiple ones
+ */
+struct SingleRequest {
+  curl_off_t size;        /* -1 if unknown at this point */
+  curl_off_t *bytecountp; /* return number of bytes read or NULL */
+
+  curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch,
+                             -1 means unlimited */
+  curl_off_t *writebytecountp; /* return number of bytes written or NULL */
+
+  curl_off_t bytecount;         /* total number of bytes read */
+  curl_off_t writebytecount;    /* number of bytes written */
+
+  long headerbytecount;         /* only count received headers */
+  long deductheadercount; /* this amount of bytes doesn't count when we check
+                             if anything has been transferred at the end of a
+                             connection. We use this counter to make only a
+                             100 reply (without a following second response
+                             code) result in a CURLE_GOT_NOTHING error code */
+
+  struct timeval start;         /* transfer started at this time */
+  struct timeval now;           /* current time */
+  bool header;                  /* incoming data has HTTP header */
+  enum {
+    HEADER_NORMAL,              /* no bad header at all */
+    HEADER_PARTHEADER,          /* part of the chunk is a bad header, the rest
+                                   is normal data */
+    HEADER_ALLBAD               /* all was believed to be header */
+  } badheader;                  /* the header was deemed bad and will be
+                                   written as body */
+  int headerline;               /* counts header lines to better track the
+                                   first one */
+  char *hbufp;                  /* points at *end* of header line */
+  size_t hbuflen;
+  char *str;                    /* within buf */
+  char *str_start;              /* within buf */
+  char *end_ptr;                /* within buf */
+  char *p;                      /* within headerbuff */
+  bool content_range;           /* set TRUE if Content-Range: was found */
+  curl_off_t offset;            /* possible resume offset read from the
+                                   Content-Range: header */
+  int httpcode;                 /* error code from the 'HTTP/1.? XXX' or
+                                   'RTSP/1.? XXX' line */
+  struct timeval start100;      /* time stamp to wait for the 100 code from */
+  enum expect100 exp100;        /* expect 100 continue state */
+  enum upgrade101 upgr101;      /* 101 upgrade state */
+
+  int auto_decoding;            /* What content encoding. sec 3.5, RFC2616. */
+
+#define IDENTITY 0              /* No encoding */
+#define DEFLATE 1               /* zlib deflate [RFC 1950 & 1951] */
+#define GZIP 2                  /* gzip algorithm [RFC 1952] */
+
+#ifdef HAVE_LIBZ
+  zlibInitState zlib_init;      /* possible zlib init state;
+                                   undefined if Content-Encoding header. */
+  z_stream z;                   /* State structure for zlib. */
+#endif
+
+  time_t timeofdoc;
+  long bodywrites;
+
+  char *buf;
+  char *uploadbuf;
+  curl_socket_t maxfd;
+
+  int keepon;
+
+  bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
+                       and we're uploading the last chunk */
+
+  bool ignorebody;  /* we read a response-body but we ignore it! */
+  bool ignorecl;    /* This HTTP response has no body so we ignore the Content-
+                       Length: header */
+
+  char *location;   /* This points to an allocated version of the Location:
+                       header data */
+  char *newurl;     /* Set to the new URL to use when a redirect or a retry is
+                       wanted */
+
+  /* 'upload_present' is used to keep a byte counter of how much data there is
+     still left in the buffer, aimed for upload. */
+  ssize_t upload_present;
+
+   /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a
+      buffer, so the next read should read from where this pointer points to,
+      and the 'upload_present' contains the number of bytes available at this
+      position */
+  char *upload_fromhere;
+
+  bool chunk; /* if set, this is a chunked transfer-encoding */
+  bool upload_chunky; /* set TRUE if we are doing chunked transfer-encoding
+                         on upload */
+  bool getheader;     /* TRUE if header parsing is wanted */
+
+  bool forbidchunk;   /* used only to explicitly forbid chunk-upload for
+                         specific upload buffers. See readmoredata() in
+                         http.c for details. */
+
+  void *protop;       /* Allocated protocol-specific data. Each protocol
+                         handler makes sure this points to data it needs. */
+};
+
+/*
+ * Specific protocol handler.
+ */
+
+struct Curl_handler {
+  const char * scheme;        /* URL scheme name. */
+
+  /* Complement to setup_connection_internals(). */
+  CURLcode (*setup_connection)(struct connectdata *);
+
+  /* These two functions MUST be set to be protocol dependent */
+  CURLcode (*do_it)(struct connectdata *, bool *done);
+  Curl_done_func done;
+
+  /* If the curl_do() function is better made in two halves, this
+   * curl_do_more() function will be called afterwards, if set. For example
+   * for doing the FTP stuff after the PASV/PORT command.
+   */
+  Curl_do_more_func do_more;
+
+  /* This function *MAY* be set to a protocol-dependent function that is run
+   * after the connect() and everything is done, as a step in the connection.
+   * The 'done' pointer points to a bool that should be set to TRUE if the
+   * function completes before return. If it doesn't complete, the caller
+   * should call the curl_connecting() function until it is.
+   */
+  CURLcode (*connect_it)(struct connectdata *, bool *done);
+
+  /* See above. Currently only used for FTP. */
+  CURLcode (*connecting)(struct connectdata *, bool *done);
+  CURLcode (*doing)(struct connectdata *, bool *done);
+
+  /* Called from the multi interface during the PROTOCONNECT phase, and it
+     should then return a proper fd set */
+  int (*proto_getsock)(struct connectdata *conn,
+                       curl_socket_t *socks,
+                       int numsocks);
+
+  /* Called from the multi interface during the DOING phase, and it should
+     then return a proper fd set */
+  int (*doing_getsock)(struct connectdata *conn,
+                       curl_socket_t *socks,
+                       int numsocks);
+
+  /* Called from the multi interface during the DO_MORE phase, and it should
+     then return a proper fd set */
+  int (*domore_getsock)(struct connectdata *conn,
+                        curl_socket_t *socks,
+                        int numsocks);
+
+  /* Called from the multi interface during the DO_DONE, PERFORM and
+     WAITPERFORM phases, and it should then return a proper fd set. Not setting
+     this will make libcurl use the generic default one. */
+  int (*perform_getsock)(const struct connectdata *conn,
+                         curl_socket_t *socks,
+                         int numsocks);
+
+  /* This function *MAY* be set to a protocol-dependent function that is run
+   * by the curl_disconnect(), as a step in the disconnection.  If the handler
+   * is called because the connection has been considered dead, dead_connection
+   * is set to TRUE.
+   */
+  CURLcode (*disconnect)(struct connectdata *, bool dead_connection);
+
+  /* If used, this function gets called from transfer.c:readwrite_data() to
+     allow the protocol to do extra reads/writes */
+  CURLcode (*readwrite)(struct SessionHandle *data, struct connectdata *conn,
+                        ssize_t *nread, bool *readmore);
+
+  long defport;           /* Default port. */
+  unsigned int protocol;  /* See CURLPROTO_* - this needs to be the single
+                             specific protocol bit */
+  unsigned int flags;     /* Extra particular characteristics, see PROTOPT_* */
+};
+
+#define PROTOPT_NONE 0             /* nothing extra */
+#define PROTOPT_SSL (1<<0)         /* uses SSL */
+#define PROTOPT_DUAL (1<<1)        /* this protocol uses two connections */
+#define PROTOPT_CLOSEACTION (1<<2) /* need action before socket close */
+/* some protocols will have to call the underlying functions without regard to
+   what exact state the socket signals. IE even if the socket says "readable",
+   the send function might need to be called while uploading, or vice versa.
+*/
+#define PROTOPT_DIRLOCK (1<<3)
+#define PROTOPT_NONETWORK (1<<4)   /* protocol doesn't use the network! */
+#define PROTOPT_NEEDSPWD (1<<5)    /* needs a password, and if none is set it
+                                      gets a default */
+#define PROTOPT_NOURLQUERY (1<<6)   /* protocol can't handle
+                                        url query strings (?foo=bar) ! */
+#define PROTOPT_CREDSPERREQUEST (1<<7) /* requires login credentials per
+                                          request instead of per connection */
+
+
+/* return the count of bytes sent, or -1 on error */
+typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */
+                            int sockindex,            /* socketindex */
+                            const void *buf,          /* data to write */
+                            size_t len,               /* max amount to write */
+                            CURLcode *err);           /* error to return */
+
+/* return the count of bytes read, or -1 on error */
+typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
+                            int sockindex,            /* socketindex */
+                            char *buf,                /* store data here */
+                            size_t len,               /* max amount to read */
+                            CURLcode *err);           /* error to return */
+
+/*
+ * The connectdata struct contains all fields and variables that should be
+ * unique for an entire connection.
+ */
+struct connectdata {
+  /* 'data' is the CURRENT SessionHandle using this connection -- take great
+     caution that this might very well vary between different times this
+     connection is used! */
+  struct SessionHandle *data;
+
+  /* chunk is for HTTP chunked encoding, but is in the general connectdata
+     struct only because we can do just about any protocol through a HTTP proxy
+     and a HTTP proxy may in fact respond using chunked encoding */
+  struct Curl_chunker chunk;
+
+  curl_closesocket_callback fclosesocket; /* function closing the socket(s) */
+  void *closesocket_client;
+
+  bool inuse; /* This is a marker for the connection cache logic. If this is
+                 TRUE this handle is being used by an easy handle and cannot
+                 be used by any other easy handle without careful
+                 consideration (== only for pipelining). */
+
+  /**** Fields set when inited and not modified again */
+  long connection_id; /* Contains a unique number to make it easier to
+                         track the connections in the log output */
+
+  /* 'dns_entry' is the particular host we use. This points to an entry in the
+     DNS cache and it will not get pruned while locked. It gets unlocked in
+     Curl_done(). This entry will be NULL if the connection is re-used as then
+     there is no name resolve done. */
+  struct Curl_dns_entry *dns_entry;
+
+  /* 'ip_addr' is the particular IP we connected to. It points to a struct
+     within the DNS cache, so this pointer is only valid as long as the DNS
+     cache entry remains locked. It gets unlocked in Curl_done() */
+  Curl_addrinfo *ip_addr;
+  Curl_addrinfo *tempaddr[2]; /* for happy eyeballs */
+
+  /* 'ip_addr_str' is the ip_addr data as a human readable string.
+     It remains available as long as the connection does, which is longer than
+     the ip_addr itself. */
+  char ip_addr_str[MAX_IPADR_LEN];
+
+  unsigned int scope_id;  /* Scope id for IPv6 */
+
+  int socktype;  /* SOCK_STREAM or SOCK_DGRAM */
+
+  struct hostname host;
+  struct hostname proxy;
+
+  long port;       /* which port to use locally */
+  int remote_port; /* what remote port to connect to, not the proxy port! */
+
+  /* 'primary_ip' and 'primary_port' get filled with peer's numerical
+     ip address and port number whenever an outgoing connection is
+     *attempted* from the primary socket to a remote address. When more
+     than one address is tried for a connection these will hold data
+     for the last attempt. When the connection is actually established
+     these are updated with data which comes directly from the socket. */
+
+  char primary_ip[MAX_IPADR_LEN];
+  long primary_port;
+
+  /* 'local_ip' and 'local_port' get filled with local's numerical
+     ip address and port number whenever an outgoing connection is
+     **established** from the primary socket to a remote address. */
+
+  char local_ip[MAX_IPADR_LEN];
+  long local_port;
+
+  char *user;    /* user name string, allocated */
+  char *passwd;  /* password string, allocated */
+  char *options; /* options string, allocated */
+
+  char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */
+
+  char *proxyuser;    /* proxy user name string, allocated */
+  char *proxypasswd;  /* proxy password string, allocated */
+  curl_proxytype proxytype; /* what kind of proxy that is in use */
+
+  int httpversion;        /* the HTTP version*10 reported by the server */
+  int rtspversion;        /* the RTSP version*10 reported by the server */
+
+  struct timeval now;     /* "current" time */
+  struct timeval created; /* creation time */
+  curl_socket_t sock[2]; /* two sockets, the second is used for the data
+                            transfer when doing FTP */
+  curl_socket_t tempsock[2]; /* temporary sockets for happy eyeballs */
+  bool sock_accepted[2]; /* TRUE if the socket on this index was created with
+                            accept() */
+  Curl_recv *recv[2];
+  Curl_send *send[2];
+
+  struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */
+  struct ssl_config_data ssl_config;
+
+  struct ConnectBits bits;    /* various state-flags for this connection */
+
+ /* connecttime: when connect() is called on the current IP address. Used to
+    be able to track when to move on to try next IP - but only when the multi
+    interface is used. */
+  struct timeval connecttime;
+  /* The two fields below get set in Curl_connecthost */
+  int num_addr; /* number of addresses to try to connect to */
+  long timeoutms_per_addr; /* how long time in milliseconds to spend on
+                              trying to connect to each IP address */
+
+  const struct Curl_handler *handler; /* Connection's protocol handler */
+  const struct Curl_handler *given;   /* The protocol first given */
+
+  long ip_version; /* copied from the SessionHandle at creation time */
+
+  /**** curl_get() phase fields */
+
+  curl_socket_t sockfd;   /* socket to read from or CURL_SOCKET_BAD */
+  curl_socket_t writesockfd; /* socket to write to, it may very
+                                well be the same we read from.
+                                CURL_SOCKET_BAD disables */
+
+  /** Dynamicly allocated strings, MUST be freed before this **/
+  /** struct is killed.                                      **/
+  struct dynamically_allocated_data {
+    char *proxyuserpwd;
+    char *uagent;
+    char *accept_encoding;
+    char *userpwd;
+    char *rangeline;
+    char *ref;
+    char *host;
+    char *cookiehost;
+    char *rtsp_transport;
+    char *te; /* TE: request header */
+  } allocptr;
+
+#ifdef HAVE_GSSAPI
+  int sec_complete; /* if Kerberos is enabled for this connection */
+  enum protection_level command_prot;
+  enum protection_level data_prot;
+  enum protection_level request_data_prot;
+  size_t buffer_size;
+  struct krb5buffer in_buffer;
+  void *app_data;
+  const struct Curl_sec_client_mech *mech;
+  struct sockaddr_in local_addr;
+#endif
+
+#if defined(USE_KERBEROS5)    /* Consider moving some of the above GSS-API */
+  struct kerberos5data krb5;  /* variables into the structure definition, */
+#endif                        /* however, some of them are ftp specific. */
+
+  /* the two following *_inuse fields are only flags, not counters in any way.
+     If TRUE it means the channel is in use, and if FALSE it means the channel
+     is up for grabs by one. */
+
+  bool readchannel_inuse;  /* whether the read channel is in use by an easy
+                              handle */
+  bool writechannel_inuse; /* whether the write channel is in use by an easy
+                              handle */
+  struct curl_llist *send_pipe; /* List of handles waiting to
+                                   send on this pipeline */
+  struct curl_llist *recv_pipe; /* List of handles waiting to read
+                                   their responses on this pipeline */
+  char* master_buffer; /* The master buffer allocated on-demand;
+                          used for pipelining. */
+  size_t read_pos; /* Current read position in the master buffer */
+  size_t buf_len; /* Length of the buffer?? */
+
+
+  curl_seek_callback seek_func; /* function that seeks the input */
+  void *seek_client;            /* pointer to pass to the seek() above */
+
+  /*************** Request - specific items ************/
+
+#if defined(USE_NTLM)
+  struct ntlmdata ntlm;     /* NTLM differs from other authentication schemes
+                               because it authenticates connections, not
+                               single requests! */
+  struct ntlmdata proxyntlm; /* NTLM data for proxy */
+
+#if defined(NTLM_WB_ENABLED)
+  /* used for communication with Samba's winbind daemon helper ntlm_auth */
+  curl_socket_t ntlm_auth_hlpr_socket;
+  pid_t ntlm_auth_hlpr_pid;
+  char* challenge_header;
+  char* response_header;
+#endif
+#endif
+
+  char syserr_buf [256]; /* buffer for Curl_strerror() */
+
+#ifdef CURLRES_ASYNCH
+  /* data used for the asynch name resolve callback */
+  struct Curl_async async;
+#endif
+
+  /* These three are used for chunked-encoding trailer support */
+  char *trailer; /* allocated buffer to store trailer in */
+  int trlMax;    /* allocated buffer size */
+  int trlPos;    /* index of where to store data */
+
+  union {
+    struct ftp_conn ftpc;
+    struct http_conn httpc;
+    struct ssh_conn sshc;
+    struct tftp_state_data *tftpc;
+    struct imap_conn imapc;
+    struct pop3_conn pop3c;
+    struct smtp_conn smtpc;
+    struct rtsp_conn rtspc;
+    struct smb_conn smbc;
+    void *generic; /* RTMP and LDAP use this */
+  } proto;
+
+  int cselect_bits; /* bitmask of socket events */
+  int waitfor;      /* current READ/WRITE bits to wait for */
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  int socks5_gssapi_enctype;
+#endif
+
+  bool verifypeer;
+  bool verifyhost;
+
+  /* When this connection is created, store the conditions for the local end
+     bind. This is stored before the actual bind and before any connection is
+     made and will serve the purpose of being used for comparison reasons so
+     that subsequent bound-requested connections aren't accidentally re-using
+     wrong connections. */
+  char *localdev;
+  unsigned short localport;
+  int localportrange;
+
+  /* tunnel as in tunnel through a HTTP proxy with CONNECT */
+  enum {
+    TUNNEL_INIT,    /* init/default/no tunnel state */
+    TUNNEL_CONNECT, /* CONNECT has been sent off */
+    TUNNEL_COMPLETE /* CONNECT response received completely */
+  } tunnel_state[2]; /* two separate ones to allow FTP */
+  struct connectbundle *bundle; /* The bundle we are member of */
+
+  int negnpn; /* APLN or NPN TLS negotiated protocol, CURL_HTTP_VERSION* */
+};
+
+/* The end of connectdata. */
+
+/*
+ * Struct to keep statistical and informational data.
+ */
+struct PureInfo {
+  int httpcode;  /* Recent HTTP, FTP, or RTSP response code */
+  int httpproxycode; /* response code from proxy when received separate */
+  int httpversion; /* the http version number X.Y = X*10+Y */
+  long filetime; /* If requested, this is might get set. Set to -1 if the time
+                    was unretrievable. We cannot have this of type time_t,
+                    since time_t is unsigned on several platforms such as
+                    OpenVMS. */
+  bool timecond;  /* set to TRUE if the time condition didn't match, which
+                     thus made the document NOT get fetched */
+  long header_size;  /* size of read header(s) in bytes */
+  long request_size; /* the amount of bytes sent in the request(s) */
+  unsigned long proxyauthavail; /* what proxy auth types were announced */
+  unsigned long httpauthavail;  /* what host auth types were announced */
+  long numconnects; /* how many new connection did libcurl created */
+  char *contenttype; /* the content type of the object */
+  char *wouldredirect; /* URL this would've been redirected to if asked to */
+
+  /* PureInfo members 'conn_primary_ip', 'conn_primary_port', 'conn_local_ip'
+     and, 'conn_local_port' are copied over from the connectdata struct in
+     order to allow curl_easy_getinfo() to return this information even when
+     the session handle is no longer associated with a connection, and also
+     allow curl_easy_reset() to clear this information from the session handle
+     without disturbing information which is still alive, and that might be
+     reused, in the connection cache. */
+
+  char conn_primary_ip[MAX_IPADR_LEN];
+  long conn_primary_port;
+
+  char conn_local_ip[MAX_IPADR_LEN];
+  long conn_local_port;
+
+  struct curl_certinfo certs; /* info about the certs, only populated in
+                                 OpenSSL builds. Asked for with
+                                 CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+};
+
+
+struct Progress {
+  long lastshow; /* time() of the last displayed progress meter or NULL to
+                    force redraw at next call */
+  curl_off_t size_dl; /* total expected size */
+  curl_off_t size_ul; /* total expected size */
+  curl_off_t downloaded; /* transferred so far */
+  curl_off_t uploaded; /* transferred so far */
+
+  curl_off_t current_speed; /* uses the currently fastest transfer */
+
+  bool callback;  /* set when progress callback is used */
+  int width; /* screen width at download start */
+  int flags; /* see progress.h */
+
+  double timespent;
+
+  curl_off_t dlspeed;
+  curl_off_t ulspeed;
+
+  double t_nslookup;
+  double t_connect;
+  double t_appconnect;
+  double t_pretransfer;
+  double t_starttransfer;
+  double t_redirect;
+
+  struct timeval start;
+  struct timeval t_startsingle;
+  struct timeval t_startop;
+  struct timeval t_acceptdata;
+#define CURR_TIME (5+1) /* 6 entries for 5 seconds */
+
+  curl_off_t speeder[ CURR_TIME ];
+  struct timeval speeder_time[ CURR_TIME ];
+  int speeder_c;
+};
+
+typedef enum {
+  HTTPREQ_NONE, /* first in list */
+  HTTPREQ_GET,
+  HTTPREQ_POST,
+  HTTPREQ_POST_FORM, /* we make a difference internally */
+  HTTPREQ_PUT,
+  HTTPREQ_HEAD,
+  HTTPREQ_CUSTOM,
+  HTTPREQ_LAST /* last in list */
+} Curl_HttpReq;
+
+typedef enum {
+    RTSPREQ_NONE, /* first in list */
+    RTSPREQ_OPTIONS,
+    RTSPREQ_DESCRIBE,
+    RTSPREQ_ANNOUNCE,
+    RTSPREQ_SETUP,
+    RTSPREQ_PLAY,
+    RTSPREQ_PAUSE,
+    RTSPREQ_TEARDOWN,
+    RTSPREQ_GET_PARAMETER,
+    RTSPREQ_SET_PARAMETER,
+    RTSPREQ_RECORD,
+    RTSPREQ_RECEIVE,
+    RTSPREQ_LAST /* last in list */
+} Curl_RtspReq;
+
+/*
+ * Values that are generated, temporary or calculated internally for a
+ * "session handle" must be defined within the 'struct UrlState'.  This struct
+ * will be used within the SessionHandle struct. When the 'SessionHandle'
+ * struct is cloned, this data MUST NOT be copied.
+ *
+ * Remember that any "state" information goes globally for the curl handle.
+ * Session-data MUST be put in the connectdata struct and here.  */
+#define MAX_CURL_USER_LENGTH 256
+#define MAX_CURL_PASSWORD_LENGTH 256
+
+struct auth {
+  unsigned long want;  /* Bitmask set to the authentication methods wanted by
+                          app (with CURLOPT_HTTPAUTH or CURLOPT_PROXYAUTH). */
+  unsigned long picked;
+  unsigned long avail; /* Bitmask for what the server reports to support for
+                          this resource */
+  bool done;  /* TRUE when the auth phase is done and ready to do the *actual*
+                 request */
+  bool multi; /* TRUE if this is not yet authenticated but within the auth
+                 multipass negotiation */
+  bool iestyle; /* TRUE if digest should be done IE-style or FALSE if it should
+                   be RFC compliant */
+};
+
+struct UrlState {
+
+  /* Points to the connection cache */
+  struct conncache *conn_cache;
+
+  /* when curl_easy_perform() is called, the multi handle is "owned" by
+     the easy handle so curl_easy_cleanup() on such an easy handle will
+     also close the multi handle! */
+  bool multi_owned_by_easy;
+
+  /* buffers to store authentication data in, as parsed from input options */
+  struct timeval keeps_speed; /* for the progress meter really */
+
+  struct connectdata *lastconnect; /* The last connection, NULL if undefined */
+
+  char *headerbuff; /* allocated buffer to store headers in */
+  size_t headersize;   /* size of the allocation */
+
+  char buffer[BUFSIZE+1]; /* download buffer */
+  char uploadbuffer[BUFSIZE+1]; /* upload buffer */
+  curl_off_t current_speed;  /* the ProgressShow() funcion sets this,
+                                bytes / second */
+  bool this_is_a_follow; /* this is a followed Location: request */
+
+  char *first_host; /* if set, this should be the host name that we will
+                       sent authorization to, no else. Used to make Location:
+                       following not keep sending user+password... This is
+                       strdup() data.
+                    */
+  struct curl_ssl_session *session; /* array of 'max_ssl_sessions' size */
+  long sessionage;                  /* number of the most recent session */
+  char *tempwrite;      /* allocated buffer to keep data in when a write
+                           callback returns to make the connection paused */
+  size_t tempwritesize; /* size of the 'tempwrite' allocated buffer */
+  int tempwritetype;    /* type of the 'tempwrite' buffer as a bitmask that is
+                           used with Curl_client_write() */
+  char *scratch; /* huge buffer[BUFSIZE*2] when doing upload CRLF replacing */
+  bool errorbuf; /* Set to TRUE if the error buffer is already filled in.
+                    This must be set to FALSE every time _easy_perform() is
+                    called. */
+  int os_errno;  /* filled in with errno whenever an error occurs */
+#ifdef HAVE_SIGNAL
+  /* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */
+  void (*prev_signal)(int sig);
+#endif
+  bool allow_port; /* Is set.use_port allowed to take effect or not. This
+                      is always set TRUE when curl_easy_perform() is called. */
+  struct digestdata digest;      /* state data for host Digest auth */
+  struct digestdata proxydigest; /* state data for proxy Digest auth */
+
+#ifdef USE_SPNEGO
+  struct negotiatedata negotiate; /* state data for host Negotiate auth */
+  struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */
+#endif
+
+  struct auth authhost;  /* auth details for host */
+  struct auth authproxy; /* auth details for proxy */
+
+  bool authproblem; /* TRUE if there's some problem authenticating */
+
+  void *resolver; /* resolver state, if it is used in the URL state -
+                     ares_channel f.e. */
+
+#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+  ENGINE *engine;
+#endif /* USE_OPENSSL */
+  struct timeval expiretime; /* set this with Curl_expire() only */
+  struct Curl_tree timenode; /* for the splay stuff */
+  struct curl_llist *timeoutlist; /* list of pending timeouts */
+
+  /* a place to store the most recently set FTP entrypath */
+  char *most_recent_ftp_entrypath;
+
+  /* set after initial USER failure, to prevent an authentication loop */
+  bool ftp_trying_alternative;
+
+  int httpversion;       /* the lowest HTTP version*10 reported by any server
+                            involved in this request */
+  bool expect100header;  /* TRUE if we added Expect: 100-continue */
+
+  bool pipe_broke; /* TRUE if the connection we were pipelined on broke
+                      and we need to restart from the beginning */
+
+#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \
+    !defined(__SYMBIAN32__)
+/* do FTP line-end conversions on most platforms */
+#define CURL_DO_LINEEND_CONV
+  /* for FTP downloads: track CRLF sequences that span blocks */
+  bool prev_block_had_trailing_cr;
+  /* for FTP downloads: how many CRLFs did we converted to LFs? */
+  curl_off_t crlf_conversions;
+#endif
+  char *pathbuffer;/* allocated buffer to store the URL's path part in */
+  char *path;      /* path to use, points to somewhere within the pathbuffer
+                      area */
+  bool slash_removed; /* set TRUE if the 'path' points to a path where the
+                         initial URL slash separator has been taken off */
+  bool use_range;
+  bool rangestringalloc; /* the range string is malloc()'ed */
+
+  char *range; /* range, if used. See README for detailed specification on
+                  this syntax. */
+  curl_off_t resume_from; /* continue [ftp] transfer from here */
+
+  /* This RTSP state information survives requests and connections */
+  long rtsp_next_client_CSeq; /* the session's next client CSeq */
+  long rtsp_next_server_CSeq; /* the session's next server CSeq */
+  long rtsp_CSeq_recv; /* most recent CSeq received */
+
+  curl_off_t infilesize; /* size of file to upload, -1 means unknown.
+                            Copied from set.filesize at start of operation */
+
+  int drain; /* Increased when this stream has data to read, even if its
+                socket not necessarily is readable. Decreased when
+                checked. */
+  bool done; /* set to FALSE when Curl_do() is called and set to TRUE when
+                Curl_done() is called, to prevent Curl_done() to get invoked
+                twice when the multi interface is used. */
+
+  curl_read_callback fread_func; /* read callback/function */
+  void *in;                      /* CURLOPT_READDATA */
+
+  struct SessionHandle *stream_depends_on;
+  bool stream_depends_e; /* set or don't set the Exclusive bit */
+  int stream_weight;
+};
+
+
+/*
+ * This 'DynamicStatic' struct defines dynamic states that actually change
+ * values in the 'UserDefined' area, which MUST be taken into consideration
+ * if the UserDefined struct is cloned or similar. You can probably just
+ * copy these, but each one indicate a special action on other data.
+ */
+
+struct DynamicStatic {
+  char *url;        /* work URL, copied from UserDefined */
+  bool url_alloc;   /* URL string is malloc()'ed */
+  char *referer;    /* referer string */
+  bool referer_alloc; /* referer sting is malloc()ed */
+  struct curl_slist *cookielist; /* list of cookie files set by
+                                    curl_easy_setopt(COOKIEFILE) calls */
+  struct curl_slist *resolve; /* set to point to the set.resolve list when
+                                 this should be dealt with in pretransfer */
+};
+
+/*
+ * This 'UserDefined' struct must only contain data that is set once to go
+ * for many (perhaps) independent connections. Values that are generated or
+ * calculated internally for the "session handle" MUST be defined within the
+ * 'struct UrlState' instead. The only exceptions MUST note the changes in
+ * the 'DynamicStatic' struct.
+ * Character pointer fields point to dynamic storage, unless otherwise stated.
+ */
+
+struct Curl_multi;    /* declared and used only in multi.c */
+
+enum dupstring {
+  STRING_CERT,            /* client certificate file name */
+  STRING_CERT_TYPE,       /* format for certificate (default: PEM)*/
+  STRING_COOKIE,          /* HTTP cookie string to send */
+  STRING_COOKIEJAR,       /* dump all cookies to this file */
+  STRING_CUSTOMREQUEST,   /* HTTP/FTP/RTSP request/method to use */
+  STRING_DEFAULT_PROTOCOL, /* Protocol to use when the URL doesn't specify */
+  STRING_DEVICE,          /* local network interface/address to use */
+  STRING_ENCODING,        /* Accept-Encoding string */
+  STRING_FTP_ACCOUNT,     /* ftp account data */
+  STRING_FTP_ALTERNATIVE_TO_USER, /* command to send if USER/PASS fails */
+  STRING_FTPPORT,         /* port to send with the FTP PORT command */
+  STRING_KEY,             /* private key file name */
+  STRING_KEY_PASSWD,      /* plain text private key password */
+  STRING_KEY_TYPE,        /* format for private key (default: PEM) */
+  STRING_KRB_LEVEL,       /* krb security level */
+  STRING_NETRC_FILE,      /* if not NULL, use this instead of trying to find
+                             $HOME/.netrc */
+  STRING_PROXY,           /* proxy to use */
+  STRING_SET_RANGE,       /* range, if used */
+  STRING_SET_REFERER,     /* custom string for the HTTP referer field */
+  STRING_SET_URL,         /* what original URL to work on */
+  STRING_SSL_CAPATH,      /* CA directory name (doesn't work on windows) */
+  STRING_SSL_CAFILE,      /* certificate file to verify peer against */
+  STRING_SSL_PINNEDPUBLICKEY, /* public key file to verify peer against */
+  STRING_SSL_CIPHER_LIST, /* list of ciphers to use */
+  STRING_SSL_EGDSOCKET,   /* path to file containing the EGD daemon socket */
+  STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */
+  STRING_USERAGENT,       /* User-Agent string */
+  STRING_SSL_CRLFILE,     /* crl file to check certificate */
+  STRING_SSL_ISSUERCERT,  /* issuer cert file to check certificate */
+  STRING_USERNAME,        /* <username>, if used */
+  STRING_PASSWORD,        /* <password>, if used */
+  STRING_OPTIONS,         /* <options>, if used */
+  STRING_PROXYUSERNAME,   /* Proxy <username>, if used */
+  STRING_PROXYPASSWORD,   /* Proxy <password>, if used */
+  STRING_NOPROXY,         /* List of hosts which should not use the proxy, if
+                             used */
+  STRING_RTSP_SESSION_ID, /* Session ID to use */
+  STRING_RTSP_STREAM_URI, /* Stream URI for this request */
+  STRING_RTSP_TRANSPORT,  /* Transport for this session */
+#ifdef USE_LIBSSH2
+  STRING_SSH_PRIVATE_KEY, /* path to the private key file for auth */
+  STRING_SSH_PUBLIC_KEY,  /* path to the public key file for auth */
+  STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */
+  STRING_SSH_KNOWNHOSTS,  /* file name of knownhosts file */
+#endif
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  STRING_SOCKS5_GSSAPI_SERVICE, /* GSSAPI service name */
+  STRING_PROXY_SERVICE_NAME, /* Proxy service name */
+  STRING_SERVICE_NAME,    /* Service name */
+#endif
+  STRING_MAIL_FROM,
+  STRING_MAIL_AUTH,
+
+#ifdef USE_TLS_SRP
+  STRING_TLSAUTH_USERNAME,      /* TLS auth <username> */
+  STRING_TLSAUTH_PASSWORD,      /* TLS auth <password> */
+#endif
+  STRING_BEARER,                /* <bearer>, if used */
+#ifdef USE_UNIX_SOCKETS
+  STRING_UNIX_SOCKET_PATH,      /* path to Unix socket, if used */
+#endif
+
+  /* -- end of zero-terminated strings -- */
+
+  STRING_LASTZEROTERMINATED,
+
+  /* -- below this are pointers to binary data that cannot be strdup'ed.
+     Each such pointer must be added manually to Curl_dupset() --- */
+
+  STRING_COPYPOSTFIELDS,  /* if POST, set the fields' values here */
+
+  STRING_LAST /* not used, just an end-of-list marker */
+};
+
+struct UserDefined {
+  FILE *err;         /* the stderr user data goes here */
+  void *debugdata;   /* the data that will be passed to fdebug */
+  char *errorbuffer; /* (Static) store failure messages in here */
+  long proxyport; /* If non-zero, use this port number by default. If the
+                     proxy string features a ":[port]" that one will override
+                     this. */
+  void *out;         /* CURLOPT_WRITEDATA */
+  void *in_set;      /* CURLOPT_READDATA */
+  void *writeheader; /* write the header to this if non-NULL */
+  void *rtp_out;     /* write RTP to this if non-NULL */
+  long use_port;     /* which port to use (when not using default) */
+  unsigned long httpauth;  /* kind of HTTP authentication to use (bitmask) */
+  unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */
+  long followlocation; /* as in HTTP Location: */
+  long maxredirs;    /* maximum no. of http(s) redirects to follow, set to -1
+                        for infinity */
+
+  int keep_post;     /* keep POSTs as POSTs after a 30x request; each
+                        bit represents a request, from 301 to 303 */
+  bool free_referer; /* set TRUE if 'referer' points to a string we
+                        allocated */
+  void *postfields;  /* if POST, set the fields' values here */
+  curl_seek_callback seek_func;      /* function that seeks the input */
+  curl_off_t postfieldsize; /* if POST, this might have a size to use instead
+                               of strlen(), and then the data *may* be binary
+                               (contain zero bytes) */
+  unsigned short localport; /* local port number to bind to */
+  int localportrange; /* number of additional port numbers to test in case the
+                         'localport' one can't be bind()ed */
+  curl_write_callback fwrite_func;   /* function that stores the output */
+  curl_write_callback fwrite_header; /* function that stores headers */
+  curl_write_callback fwrite_rtp;    /* function that stores interleaved RTP */
+  curl_read_callback fread_func_set; /* function that reads the input */
+  int is_fread_set; /* boolean, has read callback been set to non-NULL? */
+  int is_fwrite_set; /* boolean, has write callback been set to non-NULL? */
+  curl_progress_callback fprogress; /* OLD and deprecated progress callback  */
+  curl_xferinfo_callback fxferinfo; /* progress callback */
+  curl_debug_callback fdebug;      /* function that write informational data */
+  curl_ioctl_callback ioctl_func;  /* function for I/O control */
+  curl_sockopt_callback fsockopt;  /* function for setting socket options */
+  void *sockopt_client; /* pointer to pass to the socket options callback */
+  curl_opensocket_callback fopensocket; /* function for checking/translating
+                                           the address and opening the
+                                           socket */
+  void* opensocket_client;
+  curl_closesocket_callback fclosesocket; /* function for closing the
+                                             socket */
+  void* closesocket_client;
+
+  void *seek_client;    /* pointer to pass to the seek callback */
+  /* the 3 curl_conv_callback functions below are used on non-ASCII hosts */
+  /* function to convert from the network encoding: */
+  curl_conv_callback convfromnetwork;
+  /* function to convert to the network encoding: */
+  curl_conv_callback convtonetwork;
+  /* function to convert from UTF-8 encoding: */
+  curl_conv_callback convfromutf8;
+
+  void *progress_client; /* pointer to pass to the progress callback */
+  void *ioctl_client;   /* pointer to pass to the ioctl callback */
+  long timeout;         /* in milliseconds, 0 means no timeout */
+  long connecttimeout;  /* in milliseconds, 0 means no timeout */
+  long accepttimeout;   /* in milliseconds, 0 means no timeout */
+  long server_response_timeout; /* in milliseconds, 0 means no timeout */
+  long tftp_blksize ; /* in bytes, 0 means use default */
+  curl_off_t filesize;  /* size of file to upload, -1 means unknown */
+  long low_speed_limit; /* bytes/second */
+  long low_speed_time;  /* number of seconds */
+  curl_off_t max_send_speed; /* high speed limit in bytes/second for upload */
+  curl_off_t max_recv_speed; /* high speed limit in bytes/second for
+                                download */
+  curl_off_t set_resume_from;  /* continue [ftp] transfer from here */
+  struct curl_slist *headers; /* linked list of extra headers */
+  struct curl_slist *proxyheaders; /* linked list of extra CONNECT headers */
+  struct curl_httppost *httppost;  /* linked list of POST data */
+  bool sep_headers;     /* handle host and proxy headers separately */
+  bool cookiesession;   /* new cookie session? */
+  bool crlf;            /* convert crlf on ftp upload(?) */
+  struct curl_slist *quote;     /* after connection is established */
+  struct curl_slist *postquote; /* after the transfer */
+  struct curl_slist *prequote; /* before the transfer, after type */
+  struct curl_slist *source_quote;  /* 3rd party quote */
+  struct curl_slist *source_prequote;  /* in 3rd party transfer mode - before
+                                          the transfer on source host */
+  struct curl_slist *source_postquote; /* in 3rd party transfer mode - after
+                                          the transfer on source host */
+  struct curl_slist *telnet_options; /* linked list of telnet options */
+  struct curl_slist *resolve;     /* list of names to add/remove from
+                                     DNS cache */
+  curl_TimeCond timecondition; /* kind of time/date comparison */
+  time_t timevalue;       /* what time to compare with */
+  Curl_HttpReq httpreq;   /* what kind of HTTP request (if any) is this */
+  long httpversion; /* when non-zero, a specific HTTP version requested to
+                       be used in the library's request(s) */
+  struct ssl_config_data ssl;  /* user defined SSL stuff */
+  curl_proxytype proxytype; /* what kind of proxy that is in use */
+  long dns_cache_timeout; /* DNS cache timeout */
+  long buffer_size;      /* size of receive buffer to use */
+  void *private_data; /* application-private data */
+
+  struct curl_slist *http200aliases; /* linked list of aliases for http200 */
+
+  long ipver; /* the CURL_IPRESOLVE_* defines in the public header file
+                 0 - whatever, 1 - v2, 2 - v6 */
+
+  curl_off_t max_filesize; /* Maximum file size to download */
+
+  curl_ftpfile ftp_filemethod; /* how to get to a file when FTP is used  */
+
+  int ftp_create_missing_dirs; /* 1 - create directories that don't exist
+                                  2 - the same but also allow MKD to fail once
+                               */
+
+  curl_sshkeycallback ssh_keyfunc; /* key matching callback */
+  void *ssh_keyfunc_userp;         /* custom pointer to callback */
+
+/* Here follows boolean settings that define how to behave during
+   this session. They are STATIC, set by libcurl users or at least initially
+   and they don't change during operations. */
+
+  bool printhost;        /* printing host name in debug info */
+  bool get_filetime;     /* get the time and get of the remote file */
+  bool tunnel_thru_httpproxy; /* use CONNECT through a HTTP proxy */
+  bool prefer_ascii;     /* ASCII rather than binary */
+  bool ftp_append;       /* append, not overwrite, on upload */
+  bool ftp_list_only;    /* switch FTP command for listing directories */
+  bool ftp_use_port;     /* use the FTP PORT command */
+  bool hide_progress;    /* don't use the progress meter */
+  bool http_fail_on_error;  /* fail on HTTP error codes >= 400 */
+  bool http_follow_location; /* follow HTTP redirects */
+  bool http_transfer_encoding; /* request compressed HTTP transfer-encoding */
+  bool http_disable_hostname_check_before_authentication;
+  bool include_header;   /* include received protocol headers in data output */
+  bool http_set_referer; /* is a custom referer used */
+  bool http_auto_referer; /* set "correct" referer when following location: */
+  bool opt_no_body;      /* as set with CURLOPT_NOBODY */
+  bool set_port;         /* custom port number used */
+  bool upload;           /* upload request */
+  enum CURL_NETRC_OPTION
+       use_netrc;        /* defined in include/curl.h */
+  bool verbose;          /* output verbosity */
+  bool krb;              /* Kerberos connection requested */
+  bool reuse_forbid;     /* forbidden to be reused, close after use */
+  bool reuse_fresh;      /* do not re-use an existing connection  */
+  bool ftp_use_epsv;     /* if EPSV is to be attempted or not */
+  bool ftp_use_eprt;     /* if EPRT is to be attempted or not */
+  bool ftp_use_pret;     /* if PRET is to be used before PASV or not */
+
+  curl_usessl use_ssl;   /* if AUTH TLS is to be attempted etc, for FTP or
+                            IMAP or POP3 or others! */
+  curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */
+  curl_ftpccc ftp_ccc;   /* FTP CCC options */
+  bool no_signal;        /* do not use any signal/alarm handler */
+  bool global_dns_cache; /* subject for future removal */
+  bool tcp_nodelay;      /* whether to enable TCP_NODELAY or not */
+  bool ignorecl;         /* ignore content length */
+  bool ftp_skip_ip;      /* skip the IP address the FTP server passes on to
+                            us */
+  bool connect_only;     /* make connection, let application use the socket */
+  bool ssl_enable_beast; /* especially allow this flaw for interoperability's
+                            sake*/
+  bool ssl_no_revoke;    /* disable SSL certificate revocation checks */
+  long ssh_auth_types;   /* allowed SSH auth types */
+  bool http_te_skip;     /* pass the raw body data to the user, even when
+                            transfer-encoded (chunked, compressed) */
+  bool http_ce_skip;     /* pass the raw body data to the user, even when
+                            content-encoded (chunked, compressed) */
+  long new_file_perms;    /* Permissions to use when creating remote files */
+  long new_directory_perms; /* Permissions to use when creating remote dirs */
+  bool proxy_transfer_mode; /* set transfer mode (;type=<a|i>) when doing FTP
+                               via an HTTP proxy */
+  char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */
+  unsigned int scope_id;  /* Scope id for IPv6 */
+  long allowed_protocols;
+  long redir_protocols;
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  long socks5_gssapi_nec; /* flag to support nec socks5 server */
+#endif
+  struct curl_slist *mail_rcpt; /* linked list of mail recipients */
+  bool sasl_ir;         /* Enable/disable SASL initial response */
+  /* Common RTSP header options */
+  Curl_RtspReq rtspreq; /* RTSP request type */
+  long rtspversion; /* like httpversion, for RTSP */
+  bool wildcardmatch; /* enable wildcard matching */
+  curl_chunk_bgn_callback chunk_bgn; /* called before part of transfer
+                                        starts */
+  curl_chunk_end_callback chunk_end; /* called after part transferring
+                                        stopped */
+  curl_fnmatch_callback fnmatch; /* callback to decide which file corresponds
+                                    to pattern (e.g. if WILDCARDMATCH is on) */
+  void *fnmatch_data;
+
+  long gssapi_delegation; /* GSS-API credential delegation, see the
+                             documentation of CURLOPT_GSSAPI_DELEGATION */
+
+  bool tcp_keepalive;    /* use TCP keepalives */
+  long tcp_keepidle;     /* seconds in idle before sending keepalive probe */
+  long tcp_keepintvl;    /* seconds between TCP keepalive probes */
+
+  size_t maxconnects;  /* Max idle connections in the connection cache */
+
+  bool ssl_enable_npn;  /* TLS NPN extension? */
+  bool ssl_enable_alpn; /* TLS ALPN extension? */
+  bool path_as_is;      /* allow dotdots? */
+  bool pipewait;        /* wait for pipe/multiplex status before starting a
+                           new connection */
+  long expect_100_timeout; /* in milliseconds */
+
+  struct SessionHandle *stream_depends_on;
+  bool stream_depends_e; /* set or don't set the Exclusive bit */
+  int stream_weight;
+};
+
+struct Names {
+  struct curl_hash *hostcache;
+  enum {
+    HCACHE_NONE,    /* not pointing to anything */
+    HCACHE_GLOBAL,  /* points to the (shrug) global one */
+    HCACHE_MULTI,   /* points to a shared one in the multi handle */
+    HCACHE_SHARED   /* points to a shared one in a shared object */
+  } hostcachetype;
+};
+
+/*
+ * The 'connectdata' struct MUST have all the connection oriented stuff as we
+ * may have several simultaneous connections and connection structs in memory.
+ *
+ * The 'struct UserDefined' must only contain data that is set once to go for
+ * many (perhaps) independent connections. Values that are generated or
+ * calculated internally for the "session handle" must be defined within the
+ * 'struct UrlState' instead.
+ */
+
+struct SessionHandle {
+  /* first, two fields for the linked list of these */
+  struct SessionHandle *next;
+  struct SessionHandle *prev;
+
+  struct connectdata *easy_conn;     /* the "unit's" connection */
+
+  CURLMstate mstate;  /* the handle's state */
+  CURLcode result;   /* previous result */
+
+  struct Curl_message msg; /* A single posted message. */
+
+  /* Array with the plain socket numbers this handle takes care of, in no
+     particular order. Note that all sockets are added to the sockhash, where
+     the state etc are also kept. This array is mostly used to detect when a
+     socket is to be removed from the hash. See singlesocket(). */
+  curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE];
+  int numsocks;
+
+  struct Names dns;
+  struct Curl_multi *multi;    /* if non-NULL, points to the multi handle
+                                  struct to which this "belongs" when used by
+                                  the multi interface */
+  struct Curl_multi *multi_easy; /* if non-NULL, points to the multi handle
+                                    struct to which this "belongs" when used
+                                    by the easy interface */
+  struct Curl_share *share;    /* Share, handles global variable mutexing */
+  struct SingleRequest req;    /* Request-specific data */
+  struct UserDefined set;      /* values set by the libcurl user */
+  struct DynamicStatic change; /* possibly modified userdefined data */
+  struct CookieInfo *cookies;  /* the cookies, read from files and servers.
+                                  NOTE that the 'cookie' field in the
+                                  UserDefined struct defines if the "engine"
+                                  is to be used or not. */
+  struct Progress progress;    /* for all the progress meter data */
+  struct UrlState state;       /* struct for fields used for state info and
+                                  other dynamic purposes */
+  struct WildcardData wildcard; /* wildcard download state info */
+  struct PureInfo info;        /* stats, reports and info data */
+  struct curl_tlssessioninfo tsi; /* Information about the TLS session, only
+                                     valid after a client has asked for it */
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+  iconv_t outbound_cd;         /* for translating to the network encoding */
+  iconv_t inbound_cd;          /* for translating from the network encoding */
+  iconv_t utf8_cd;             /* for translating to UTF8 */
+#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
+  unsigned int magic;          /* set to a CURLEASY_MAGIC_NUMBER */
+};
+
+#define LIBCURL_NAME "libcurl"
+
+#endif /* HEADER_CURL_URLDATA_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/version.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/version.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/version.c	(revision 164)
@@ -0,0 +1,374 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "vtls/vtls.h"
+#include "http2.h"
+#include "curl_printf.h"
+
+#ifdef USE_ARES
+#  if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
+     (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
+#    define CARES_STATICLIB
+#  endif
+#  include <ares.h>
+#endif
+
+#ifdef USE_LIBIDN
+#include <stringprep.h>
+#endif
+
+#ifdef USE_LIBPSL
+#include <libpsl.h>
+#endif
+
+#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
+#include <iconv.h>
+#endif
+
+#ifdef USE_LIBRTMP
+#include <librtmp/rtmp.h>
+#endif
+
+#ifdef USE_LIBSSH2
+#include <libssh2.h>
+#endif
+
+#ifdef HAVE_LIBSSH2_VERSION
+/* get it run-time if possible */
+#define CURL_LIBSSH2_VERSION libssh2_version(0)
+#else
+/* use build-time if run-time not possible */
+#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION
+#endif
+
+char *curl_version(void)
+{
+  static char version[200];
+  char *ptr = version;
+  size_t len;
+  size_t left = sizeof(version);
+
+  strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION);
+  len = strlen(ptr);
+  left -= len;
+  ptr += len;
+
+  if(left > 1) {
+    len = Curl_ssl_version(ptr + 1, left - 1);
+
+    if(len > 0) {
+      *ptr = ' ';
+      left -= ++len;
+      ptr += len;
+    }
+  }
+
+#ifdef HAVE_LIBZ
+  len = snprintf(ptr, left, " zlib/%s", zlibVersion());
+  left -= len;
+  ptr += len;
+#endif
+#ifdef USE_ARES
+  /* this function is only present in c-ares, not in the original ares */
+  len = snprintf(ptr, left, " c-ares/%s", ares_version(NULL));
+  left -= len;
+  ptr += len;
+#endif
+#ifdef USE_LIBIDN
+  if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
+    len = snprintf(ptr, left, " libidn/%s", stringprep_check_version(NULL));
+    left -= len;
+    ptr += len;
+  }
+#endif
+#ifdef USE_LIBPSL
+  len = snprintf(ptr, left, " libpsl/%s", psl_get_version());
+  left -= len;
+  ptr += len;
+#endif
+#ifdef USE_WIN32_IDN
+  len = snprintf(ptr, left, " WinIDN");
+  left -= len;
+  ptr += len;
+#endif
+#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
+#ifdef _LIBICONV_VERSION
+  len = snprintf(ptr, left, " iconv/%d.%d",
+                 _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255);
+#else
+  /* version unknown */
+  len = snprintf(ptr, left, " iconv");
+#endif /* _LIBICONV_VERSION */
+  left -= len;
+  ptr += len;
+#endif
+#ifdef USE_LIBSSH2
+  len = snprintf(ptr, left, " libssh2/%s", CURL_LIBSSH2_VERSION);
+  left -= len;
+  ptr += len;
+#endif
+#ifdef USE_NGHTTP2
+  len = Curl_http2_ver(ptr, left);
+  left -= len;
+  ptr += len;
+#endif
+#ifdef USE_LIBRTMP
+  {
+    char suff[2];
+    if(RTMP_LIB_VERSION & 0xff) {
+      suff[0] = (RTMP_LIB_VERSION & 0xff) + 'a' - 1;
+      suff[1] = '\0';
+    }
+    else
+      suff[0] = '\0';
+
+    snprintf(ptr, left, " librtmp/%d.%d%s",
+             RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff,
+             suff);
+/*
+  If another lib version is added below this one, this code would
+  also have to do:
+
+    len = what snprintf() returned
+
+    left -= len;
+    ptr += len;
+*/
+  }
+#endif
+
+  return version;
+}
+
+/* data for curl_version_info
+
+   Keep the list sorted alphabetically. It is also written so that each
+   protocol line has its own #if line to make things easier on the eye.
+ */
+
+static const char * const protocols[] = {
+#ifndef CURL_DISABLE_DICT
+  "dict",
+#endif
+#ifndef CURL_DISABLE_FILE
+  "file",
+#endif
+#ifndef CURL_DISABLE_FTP
+  "ftp",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
+  "ftps",
+#endif
+#ifndef CURL_DISABLE_GOPHER
+  "gopher",
+#endif
+#ifndef CURL_DISABLE_HTTP
+  "http",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
+  "https",
+#endif
+#ifndef CURL_DISABLE_IMAP
+  "imap",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP)
+  "imaps",
+#endif
+#ifndef CURL_DISABLE_LDAP
+  "ldap",
+#if !defined(CURL_DISABLE_LDAPS) && \
+    ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
+     (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
+  "ldaps",
+#endif
+#endif
+#ifndef CURL_DISABLE_POP3
+  "pop3",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3)
+  "pop3s",
+#endif
+#ifdef USE_LIBRTMP
+  "rtmp",
+#endif
+#ifndef CURL_DISABLE_RTSP
+  "rtsp",
+#endif
+#ifdef USE_LIBSSH2
+  "scp",
+#endif
+#ifdef USE_LIBSSH2
+  "sftp",
+#endif
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+   (CURL_SIZEOF_CURL_OFF_T > 4) && \
+   (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
+  "smb",
+#  ifdef USE_SSL
+  "smbs",
+#  endif
+#endif
+#ifndef CURL_DISABLE_SMTP
+  "smtp",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP)
+  "smtps",
+#endif
+#ifndef CURL_DISABLE_TELNET
+  "telnet",
+#endif
+#ifndef CURL_DISABLE_TFTP
+  "tftp",
+#endif
+
+  NULL
+};
+
+static curl_version_info_data version_info = {
+  CURLVERSION_NOW,
+  LIBCURL_VERSION,
+  LIBCURL_VERSION_NUM,
+  OS, /* as found by configure or set by hand at build-time */
+  0 /* features is 0 by default */
+#ifdef ENABLE_IPV6
+  | CURL_VERSION_IPV6
+#endif
+#ifdef USE_SSL
+  | CURL_VERSION_SSL
+#endif
+#ifdef USE_NTLM
+  | CURL_VERSION_NTLM
+#endif
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+  defined(NTLM_WB_ENABLED)
+  | CURL_VERSION_NTLM_WB
+#endif
+#ifdef USE_SPNEGO
+  | CURL_VERSION_SPNEGO
+#endif
+#ifdef USE_KERBEROS5
+  | CURL_VERSION_KERBEROS5
+#endif
+#ifdef HAVE_GSSAPI
+  | CURL_VERSION_GSSAPI
+#endif
+#ifdef USE_WINDOWS_SSPI
+  | CURL_VERSION_SSPI
+#endif
+#ifdef HAVE_LIBZ
+  | CURL_VERSION_LIBZ
+#endif
+#ifdef DEBUGBUILD
+  | CURL_VERSION_DEBUG
+#endif
+#ifdef CURLDEBUG
+  | CURL_VERSION_CURLDEBUG
+#endif
+#ifdef CURLRES_ASYNCH
+  | CURL_VERSION_ASYNCHDNS
+#endif
+#if (CURL_SIZEOF_CURL_OFF_T > 4) && \
+    ( (SIZEOF_OFF_T > 4) || defined(USE_WIN32_LARGE_FILES) )
+  | CURL_VERSION_LARGEFILE
+#endif
+#if defined(CURL_DOES_CONVERSIONS)
+  | CURL_VERSION_CONV
+#endif
+#if defined(USE_TLS_SRP)
+  | CURL_VERSION_TLSAUTH_SRP
+#endif
+#if defined(USE_NGHTTP2)
+  | CURL_VERSION_HTTP2
+#endif
+#if defined(USE_UNIX_SOCKETS)
+  | CURL_VERSION_UNIX_SOCKETS
+#endif
+#if defined(USE_LIBPSL)
+  | CURL_VERSION_PSL
+#endif
+  ,
+  NULL, /* ssl_version */
+  0,    /* ssl_version_num, this is kept at zero */
+  NULL, /* zlib_version */
+  protocols,
+  NULL, /* c-ares version */
+  0,    /* c-ares version numerical */
+  NULL, /* libidn version */
+  0,    /* iconv version */
+  NULL, /* ssh lib version */
+};
+
+curl_version_info_data *curl_version_info(CURLversion stamp)
+{
+#ifdef USE_LIBSSH2
+  static char ssh_buffer[80];
+#endif
+
+#ifdef USE_SSL
+  static char ssl_buffer[80];
+  Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer));
+  version_info.ssl_version = ssl_buffer;
+#endif
+
+#ifdef HAVE_LIBZ
+  version_info.libz_version = zlibVersion();
+  /* libz left NULL if non-existing */
+#endif
+#ifdef USE_ARES
+  {
+    int aresnum;
+    version_info.ares = ares_version(&aresnum);
+    version_info.ares_num = aresnum;
+  }
+#endif
+#ifdef USE_LIBIDN
+  /* This returns a version string if we use the given version or later,
+     otherwise it returns NULL */
+  version_info.libidn = stringprep_check_version(LIBIDN_REQUIRED_VERSION);
+  if(version_info.libidn)
+    version_info.features |= CURL_VERSION_IDN;
+#elif defined(USE_WIN32_IDN)
+  version_info.features |= CURL_VERSION_IDN;
+#endif
+
+#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
+#ifdef _LIBICONV_VERSION
+  version_info.iconv_ver_num = _LIBICONV_VERSION;
+#else
+  /* version unknown */
+  version_info.iconv_ver_num = -1;
+#endif /* _LIBICONV_VERSION */
+#endif
+
+#ifdef USE_LIBSSH2
+  snprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION);
+  version_info.libssh_version = ssh_buffer;
+#endif
+
+  (void)stamp; /* avoid compiler warnings, we don't use this */
+
+  return &version_info;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/axtls.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/axtls.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/axtls.c	(revision 164)
@@ -0,0 +1,690 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, DirecTV, Contact: Eric Hu, <ehu@directv.com>.
+ * Copyright (C) 2010 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all axTLS-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_AXTLS
+#include <axTLS/config.h>
+#include <axTLS/ssl.h>
+#include "axtls.h"
+
+#include "sendf.h"
+#include "inet_pton.h"
+#include "vtls.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "curl_printf.h"
+#include "hostcheck.h"
+#include <unistd.h>
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+
+/* Global axTLS init, called from Curl_ssl_init() */
+int Curl_axtls_init(void)
+{
+/* axTLS has no global init.  Everything is done through SSL and SSL_CTX
+ * structs stored in connectdata structure.  Perhaps can move to axtls.h.
+ */
+  return 1;
+}
+
+int Curl_axtls_cleanup(void)
+{
+  /* axTLS has no global cleanup.  Perhaps can move this to axtls.h. */
+  return 1;
+}
+
+static CURLcode map_error_to_curl(int axtls_err)
+{
+  switch (axtls_err) {
+  case SSL_ERROR_NOT_SUPPORTED:
+  case SSL_ERROR_INVALID_VERSION:
+  case -70:                       /* protocol version alert from server */
+    return CURLE_UNSUPPORTED_PROTOCOL;
+    break;
+  case SSL_ERROR_NO_CIPHER:
+    return CURLE_SSL_CIPHER;
+    break;
+  case SSL_ERROR_BAD_CERTIFICATE: /* this may be bad server cert too */
+  case SSL_ERROR_NO_CERT_DEFINED:
+  case -42:                       /* bad certificate alert from server */
+  case -43:                       /* unsupported cert alert from server */
+  case -44:                       /* cert revoked alert from server */
+  case -45:                       /* cert expired alert from server */
+  case -46:                       /* cert unknown alert from server */
+    return CURLE_SSL_CERTPROBLEM;
+    break;
+  case SSL_X509_ERROR(X509_NOT_OK):
+  case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT):
+  case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE):
+  case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID):
+  case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED):
+  case SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED):
+  case SSL_X509_ERROR(X509_VFY_ERROR_INVALID_CHAIN):
+  case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST):
+  case SSL_X509_ERROR(X509_INVALID_PRIV_KEY):
+    return CURLE_PEER_FAILED_VERIFICATION;
+    break;
+  case -48:                       /* unknown ca alert from server */
+    return CURLE_SSL_CACERT;
+    break;
+  case -49:                       /* access denied alert from server */
+    return CURLE_REMOTE_ACCESS_DENIED;
+    break;
+  case SSL_ERROR_CONN_LOST:
+  case SSL_ERROR_SOCK_SETUP_FAILURE:
+  case SSL_ERROR_INVALID_HANDSHAKE:
+  case SSL_ERROR_INVALID_PROT_MSG:
+  case SSL_ERROR_INVALID_HMAC:
+  case SSL_ERROR_INVALID_SESSION:
+  case SSL_ERROR_INVALID_KEY:     /* it's too bad this doesn't map better */
+  case SSL_ERROR_FINISHED_INVALID:
+  case SSL_ERROR_NO_CLIENT_RENOG:
+  default:
+    return CURLE_SSL_CONNECT_ERROR;
+    break;
+  }
+}
+
+static Curl_recv axtls_recv;
+static Curl_send axtls_send;
+
+static void free_ssl_structs(struct ssl_connect_data *connssl)
+{
+  if(connssl->ssl) {
+    ssl_free (connssl->ssl);
+    connssl->ssl = NULL;
+  }
+  if(connssl->ssl_ctx) {
+    ssl_ctx_free(connssl->ssl_ctx);
+    connssl->ssl_ctx = NULL;
+  }
+}
+
+/*
+ * For both blocking and non-blocking connects, this function sets up the
+ * ssl context and state.  This function is called after the TCP connect
+ * has completed.
+ */
+static CURLcode connect_prep(struct connectdata *conn, int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  SSL_CTX *ssl_ctx;
+  SSL *ssl = NULL;
+  int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
+  int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
+  int i, ssl_fcn_return;
+  const uint8_t *ssl_sessionid;
+  size_t ssl_idsize;
+
+  /* Assuming users will not compile in custom key/cert to axTLS.
+  *  Also, even for blocking connects, use axTLS non-blocking feature.
+  */
+  uint32_t client_option = SSL_NO_DEFAULT_KEY |
+    SSL_SERVER_VERIFY_LATER |
+    SSL_CONNECT_IN_PARTS;
+
+  if(conn->ssl[sockindex].state == ssl_connection_complete)
+    /* to make us tolerant against being called more than once for the
+       same connection */
+    return CURLE_OK;
+
+  /* axTLS only supports TLSv1 */
+  /* check to see if we've been told to use an explicit SSL/TLS version */
+  switch(data->set.ssl.version) {
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+    break;
+  default:
+    failf(data, "axTLS only supports TLS 1.0 and 1.1, "
+          "and it cannot be specified which one to use");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+#ifdef  AXTLSDEBUG
+  client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS;
+#endif /* AXTLSDEBUG */
+
+  /* Allocate an SSL_CTX struct */
+  ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS);
+  if(ssl_ctx == NULL) {
+    failf(data, "unable to create client SSL context");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  conn->ssl[sockindex].ssl_ctx = ssl_ctx;
+  conn->ssl[sockindex].ssl = NULL;
+
+  /* Load the trusted CA cert bundle file */
+  if(data->set.ssl.CAfile) {
+    if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, data->set.ssl.CAfile, NULL)
+       != SSL_OK) {
+      infof(data, "error reading ca cert file %s \n",
+            data->set.ssl.CAfile);
+      if(data->set.ssl.verifypeer) {
+        return CURLE_SSL_CACERT_BADFILE;
+      }
+    }
+    else
+      infof(data, "found certificates in %s\n", data->set.ssl.CAfile);
+  }
+
+  /* gtls.c tasks we're skipping for now:
+   * 1) certificate revocation list checking
+   * 2) dns name assignment to host
+   * 3) set protocol priority.  axTLS is TLSv1 only, so can probably ignore
+   * 4) set certificate priority.  axTLS ignores type and sends certs in
+   *  order added.  can probably ignore this.
+   */
+
+  /* Load client certificate */
+  if(data->set.str[STRING_CERT]) {
+    i=0;
+    /* Instead of trying to analyze cert type here, let axTLS try them all. */
+    while(cert_types[i] != 0) {
+      ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
+                                    data->set.str[STRING_CERT], NULL);
+      if(ssl_fcn_return == SSL_OK) {
+        infof(data, "successfully read cert file %s \n",
+              data->set.str[STRING_CERT]);
+        break;
+      }
+      i++;
+    }
+    /* Tried all cert types, none worked. */
+    if(cert_types[i] == 0) {
+      failf(data, "%s is not x509 or pkcs12 format",
+            data->set.str[STRING_CERT]);
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  /* Load client key.
+     If a pkcs12 file successfully loaded a cert, then there's nothing to do
+     because the key has already been loaded. */
+  if(data->set.str[STRING_KEY] && cert_types[i] != SSL_OBJ_PKCS12) {
+    i=0;
+    /* Instead of trying to analyze key type here, let axTLS try them all. */
+    while(key_types[i] != 0) {
+      ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
+                                    data->set.str[STRING_KEY], NULL);
+      if(ssl_fcn_return == SSL_OK) {
+        infof(data, "successfully read key file %s \n",
+              data->set.str[STRING_KEY]);
+        break;
+      }
+      i++;
+    }
+    /* Tried all key types, none worked. */
+    if(key_types[i] == 0) {
+      failf(data, "Failure: %s is not a supported key file",
+            data->set.str[STRING_KEY]);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  /* gtls.c does more here that is being left out for now
+   * 1) set session credentials.  can probably ignore since axtls puts this
+   *    info in the ssl_ctx struct
+   * 2) setting up callbacks.  these seem gnutls specific
+   */
+
+  /* In axTLS, handshaking happens inside ssl_client_new. */
+  if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize)) {
+    /* we got a session id, use it! */
+    infof (data, "SSL re-using session ID\n");
+    ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
+                         ssl_sessionid, (uint8_t)ssl_idsize);
+  }
+  else
+    ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0);
+
+  conn->ssl[sockindex].ssl = ssl;
+  return CURLE_OK;
+}
+
+/*
+ * For both blocking and non-blocking connects, this function finalizes the
+ * SSL connection.
+ */
+static CURLcode connect_finish(struct connectdata *conn, int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  SSL *ssl = conn->ssl[sockindex].ssl;
+  const uint8_t *ssl_sessionid;
+  size_t ssl_idsize;
+  const char *peer_CN;
+  uint32_t dns_altname_index;
+  const char *dns_altname;
+  int8_t found_subject_alt_names = 0;
+  int8_t found_subject_alt_name_matching_conn = 0;
+
+  /* Here, gtls.c gets the peer certificates and fails out depending on
+   * settings in "data."  axTLS api doesn't have get cert chain fcn, so omit?
+   */
+
+  /* Verify server's certificate */
+  if(data->set.ssl.verifypeer) {
+    if(ssl_verify_cert(ssl) != SSL_OK) {
+      Curl_axtls_close(conn, sockindex);
+      failf(data, "server cert verify failed");
+      return CURLE_PEER_FAILED_VERIFICATION;
+    }
+  }
+  else
+    infof(data, "\t server certificate verification SKIPPED\n");
+
+  /* Here, gtls.c does issuer verification. axTLS has no straightforward
+   * equivalent, so omitting for now.*/
+
+  /* Here, gtls.c does the following
+   * 1) x509 hostname checking per RFC2818.  axTLS doesn't support this, but
+   *    it seems useful. This is now implemented, by Oscar Koeroo
+   * 2) checks cert validity based on time.  axTLS does this in ssl_verify_cert
+   * 3) displays a bunch of cert information.  axTLS doesn't support most of
+   *    this, but a couple fields are available.
+   */
+
+  /* There is no (DNS) Altnames count in the version 1.4.8 API. There is a
+     risk of an inifite loop */
+  for(dns_altname_index = 0; ; dns_altname_index++) {
+    dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index);
+    if(dns_altname == NULL) {
+      break;
+    }
+    found_subject_alt_names = 1;
+
+    infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n",
+          dns_altname, conn->host.name);
+    if(Curl_cert_hostcheck(dns_altname, conn->host.name)) {
+      found_subject_alt_name_matching_conn = 1;
+      break;
+    }
+  }
+
+  /* RFC2818 checks */
+  if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
+    if(data->set.ssl.verifyhost) {
+      /* Break connection ! */
+      Curl_axtls_close(conn, sockindex);
+      failf(data, "\tsubjectAltName(s) do not match %s\n",
+            conn->host.dispname);
+      return CURLE_PEER_FAILED_VERIFICATION;
+    }
+    else
+      infof(data, "\tsubjectAltName(s) do not match %s\n",
+            conn->host.dispname);
+  }
+  else if(found_subject_alt_names == 0) {
+    /* Per RFC2818, when no Subject Alt Names were available, examine the peer
+       CN as a legacy fallback */
+    peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
+    if(peer_CN == NULL) {
+      if(data->set.ssl.verifyhost) {
+        Curl_axtls_close(conn, sockindex);
+        failf(data, "unable to obtain common name from peer certificate");
+        return CURLE_PEER_FAILED_VERIFICATION;
+      }
+      else
+        infof(data, "unable to obtain common name from peer certificate");
+    }
+    else {
+      if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
+        if(data->set.ssl.verifyhost) {
+          /* Break connection ! */
+          Curl_axtls_close(conn, sockindex);
+          failf(data, "\tcommon name \"%s\" does not match \"%s\"\n",
+                peer_CN, conn->host.dispname);
+          return CURLE_PEER_FAILED_VERIFICATION;
+        }
+        else
+          infof(data, "\tcommon name \"%s\" does not match \"%s\"\n",
+                peer_CN, conn->host.dispname);
+      }
+    }
+  }
+
+  /* General housekeeping */
+  conn->ssl[sockindex].state = ssl_connection_complete;
+  conn->recv[sockindex] = axtls_recv;
+  conn->send[sockindex] = axtls_send;
+
+  /* Put our freshly minted SSL session in cache */
+  ssl_idsize = ssl_get_session_id_size(ssl);
+  ssl_sessionid = ssl_get_session_id(ssl);
+  if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize)
+     != CURLE_OK)
+    infof (data, "failed to add session to cache\n");
+
+  return CURLE_OK;
+}
+
+/*
+ * Use axTLS's non-blocking connection feature to open an SSL connection.
+ * This is called after a TCP connection is already established.
+ */
+CURLcode Curl_axtls_connect_nonblocking(
+    struct connectdata *conn,
+    int sockindex,
+    bool *done)
+{
+  CURLcode conn_step;
+  int ssl_fcn_return;
+  int i;
+
+ *done = FALSE;
+  /* connectdata is calloc'd and connecting_state is only changed in this
+     function, so this is safe, as the state is effectively initialized. */
+  if(conn->ssl[sockindex].connecting_state == ssl_connect_1) {
+    conn_step = connect_prep(conn, sockindex);
+    if(conn_step != CURLE_OK) {
+      Curl_axtls_close(conn, sockindex);
+      return conn_step;
+    }
+    conn->ssl[sockindex].connecting_state = ssl_connect_2;
+  }
+
+  if(conn->ssl[sockindex].connecting_state == ssl_connect_2) {
+    /* Check to make sure handshake was ok. */
+    if(ssl_handshake_status(conn->ssl[sockindex].ssl) != SSL_OK) {
+      /* Loop to perform more work in between sleeps. This is work around the
+         fact that axtls does not expose any knowledge about when work needs
+         to be performed. This can save ~25% of time on SSL handshakes. */
+      for(i=0; i<5; i++) {
+        ssl_fcn_return = ssl_read(conn->ssl[sockindex].ssl, NULL);
+        if(ssl_fcn_return < 0) {
+          Curl_axtls_close(conn, sockindex);
+          ssl_display_error(ssl_fcn_return); /* goes to stdout. */
+          return map_error_to_curl(ssl_fcn_return);
+        }
+        return CURLE_OK;
+      }
+    }
+    infof (conn->data, "handshake completed successfully\n");
+    conn->ssl[sockindex].connecting_state = ssl_connect_3;
+  }
+
+  if(conn->ssl[sockindex].connecting_state == ssl_connect_3) {
+    conn_step = connect_finish(conn, sockindex);
+    if(conn_step != CURLE_OK) {
+      Curl_axtls_close(conn, sockindex);
+      return conn_step;
+    }
+
+    /* Reset connect state */
+    conn->ssl[sockindex].connecting_state = ssl_connect_1;
+
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  /* Unrecognized state.  Things are very bad. */
+  conn->ssl[sockindex].state  = ssl_connection_none;
+  conn->ssl[sockindex].connecting_state = ssl_connect_1;
+  /* Return value perhaps not strictly correct, but distinguishes the issue.*/
+  return CURLE_BAD_FUNCTION_ARGUMENT;
+}
+
+
+/*
+ * This function is called after the TCP connect has completed. Setup the TLS
+ * layer and do all necessary magic for a blocking connect.
+ */
+CURLcode
+Curl_axtls_connect(struct connectdata *conn,
+                  int sockindex)
+
+{
+  struct SessionHandle *data = conn->data;
+  CURLcode conn_step = connect_prep(conn, sockindex);
+  int ssl_fcn_return;
+  SSL *ssl = conn->ssl[sockindex].ssl;
+  long timeout_ms;
+
+  if(conn_step != CURLE_OK) {
+    Curl_axtls_close(conn, sockindex);
+    return conn_step;
+  }
+
+  /* Check to make sure handshake was ok. */
+  while(ssl_handshake_status(ssl) != SSL_OK) {
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    ssl_fcn_return = ssl_read(ssl, NULL);
+    if(ssl_fcn_return < 0) {
+      Curl_axtls_close(conn, sockindex);
+      ssl_display_error(ssl_fcn_return); /* goes to stdout. */
+      return map_error_to_curl(ssl_fcn_return);
+    }
+    /* TODO: avoid polling */
+    usleep(10000);
+  }
+  infof (conn->data, "handshake completed successfully\n");
+
+  conn_step = connect_finish(conn, sockindex);
+  if(conn_step != CURLE_OK) {
+    Curl_axtls_close(conn, sockindex);
+    return conn_step;
+  }
+
+  return CURLE_OK;
+}
+
+/* return number of sent (non-SSL) bytes */
+static ssize_t axtls_send(struct connectdata *conn,
+                          int sockindex,
+                          const void *mem,
+                          size_t len,
+                          CURLcode *err)
+{
+  /* ssl_write() returns 'int' while write() and send() returns 'size_t' */
+  int rc = ssl_write(conn->ssl[sockindex].ssl, mem, (int)len);
+
+  infof(conn->data, "  axtls_send\n");
+
+  if(rc < 0 ) {
+    *err = map_error_to_curl(rc);
+    rc = -1; /* generic error code for send failure */
+  }
+
+  *err = CURLE_OK;
+  return rc;
+}
+
+void Curl_axtls_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  infof(conn->data, "  Curl_axtls_close\n");
+
+    /* line from openssl.c: (void)SSL_shutdown(connssl->ssl);
+       axTLS compat layer does nothing for SSL_shutdown */
+
+    /* The following line is from openssl.c.  There seems to be no axTLS
+       equivalent.  ssl_free and ssl_ctx_free close things.
+       SSL_set_connect_state(connssl->handle); */
+
+  free_ssl_structs(connssl);
+}
+
+/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
+{
+  /* Outline taken from openssl.c since functions are in axTLS compat layer.
+     axTLS's error set is much smaller, so a lot of error-handling was removed.
+   */
+  int retval = 0;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct SessionHandle *data = conn->data;
+  uint8_t *buf;
+  ssize_t nread;
+
+  infof(conn->data, "  Curl_axtls_shutdown\n");
+
+  /* This has only been tested on the proftpd server, and the mod_tls code
+     sends a close notify alert without waiting for a close notify alert in
+     response. Thus we wait for a close notify alert from the server, but
+     we do not send one. Let's hope other servers do the same... */
+
+  /* axTLS compat layer does nothing for SSL_shutdown, so we do nothing too
+  if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
+      (void)SSL_shutdown(connssl->ssl);
+  */
+
+  if(connssl->ssl) {
+    int what = Curl_socket_ready(conn->sock[sockindex],
+                                 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+    if(what > 0) {
+      /* Something to read, let's do it and hope that it is the close
+         notify alert from the server.  buf is managed internally by
+         axTLS and will be released upon calling ssl_free via
+         free_ssl_structs. */
+      nread = (ssize_t)ssl_read(connssl->ssl, &buf);
+
+      if(nread < SSL_OK) {
+        failf(data, "close notify alert not received during shutdown");
+        retval = -1;
+      }
+    }
+    else if(0 == what) {
+      /* timeout */
+      failf(data, "SSL shutdown timeout");
+    }
+    else {
+      /* anything that gets here is fatally bad */
+      failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+      retval = -1;
+    }
+
+    free_ssl_structs(connssl);
+  }
+  return retval;
+}
+
+static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
+                          int num,                  /* socketindex */
+                          char *buf,                /* store read data here */
+                          size_t buffersize,        /* max amount to read */
+                          CURLcode *err)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[num];
+  ssize_t ret = 0;
+  uint8_t *read_buf;
+
+  infof(conn->data, "  axtls_recv\n");
+
+  *err = CURLE_OK;
+  if(connssl) {
+    ret = ssl_read(connssl->ssl, &read_buf);
+    if(ret > SSL_OK) {
+      /* ssl_read returns SSL_OK if there is more data to read, so if it is
+         larger, then all data has been read already.  */
+      memcpy(buf, read_buf,
+             (size_t)ret > buffersize ? buffersize : (size_t)ret);
+    }
+    else if(ret == SSL_OK) {
+      /* more data to be read, signal caller to call again */
+      *err = CURLE_AGAIN;
+      ret = -1;
+    }
+    else if(ret == -3) {
+      /* With patched axTLS, SSL_CLOSE_NOTIFY=-3.  Hard-coding until axTLS
+         team approves proposed fix. */
+      Curl_axtls_close(conn, num);
+    }
+    else {
+      failf(conn->data, "axTLS recv error (%d)", ret);
+      *err = map_error_to_curl((int) ret);
+      ret = -1;
+    }
+  }
+
+  return ret;
+}
+
+/*
+ * Return codes:
+ *     1 means the connection is still in place
+ *     0 means the connection has been closed
+ *    -1 means the connection status is unknown
+ */
+int Curl_axtls_check_cxn(struct connectdata *conn)
+{
+  /* openssl.c line: rc = SSL_peek(conn->ssl[FIRSTSOCKET].ssl, (void*)&buf, 1);
+     axTLS compat layer always returns the last argument, so connection is
+     always alive? */
+
+  infof(conn->data, "  Curl_axtls_check_cxn\n");
+   return 1; /* connection still in place */
+}
+
+void Curl_axtls_session_free(void *ptr)
+{
+  (void)ptr;
+  /* free the ID */
+  /* both openssl.c and gtls.c do something here, but axTLS's OpenSSL
+     compatibility layer does nothing, so we do nothing too. */
+}
+
+size_t Curl_axtls_version(char *buffer, size_t size)
+{
+  return snprintf(buffer, size, "axTLS/%s", ssl_version());
+}
+
+int Curl_axtls_random(struct SessionHandle *data,
+                      unsigned char *entropy,
+                      size_t length)
+{
+  static bool ssl_seeded = FALSE;
+  (void)data;
+  if(!ssl_seeded) {
+    ssl_seeded = TRUE;
+    /* Initialize the seed if not already done. This call is not exactly thread
+     * safe (and neither is the ssl_seeded check), but the worst effect of a
+     * race condition is that some global resources will leak. */
+    RNG_initialize();
+  }
+  get_random((int)length, entropy);
+  return 0;
+}
+
+#endif /* USE_AXTLS */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/axtls.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/axtls.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/axtls.h	(revision 164)
@@ -0,0 +1,71 @@
+#ifndef HEADER_CURL_AXTLS_H
+#define HEADER_CURL_AXTLS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, DirecTV, Contact: Eric Hu <ehu@directv.com>
+ * Copyright (C) 2010 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef USE_AXTLS
+#include "curl/curl.h"
+#include "urldata.h"
+
+int Curl_axtls_init(void);
+int Curl_axtls_cleanup(void);
+CURLcode Curl_axtls_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_axtls_connect_nonblocking(
+    struct connectdata *conn,
+    int sockindex,
+    bool *done);
+
+ /* close a SSL connection */
+void Curl_axtls_close(struct connectdata *conn, int sockindex);
+
+void Curl_axtls_session_free(void *ptr);
+size_t Curl_axtls_version(char *buffer, size_t size);
+int Curl_axtls_shutdown(struct connectdata *conn, int sockindex);
+int Curl_axtls_check_cxn(struct connectdata *conn);
+int Curl_axtls_random(struct SessionHandle *data,
+                      unsigned char *entropy,
+                      size_t length);
+
+/* Set the API backend definition to axTLS */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_AXTLS
+
+/* API setup for axTLS */
+#define curlssl_init Curl_axtls_init
+#define curlssl_cleanup Curl_axtls_cleanup
+#define curlssl_connect Curl_axtls_connect
+#define curlssl_connect_nonblocking Curl_axtls_connect_nonblocking
+#define curlssl_session_free(x)  Curl_axtls_session_free(x)
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_axtls_close
+#define curlssl_shutdown(x,y) Curl_axtls_shutdown(x,y)
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_axtls_version
+#define curlssl_check_cxn(x) Curl_axtls_check_cxn(x)
+#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
+#define curlssl_random(x,y,z) Curl_axtls_random(x,y,z)
+
+#endif /* USE_AXTLS */
+#endif /* HEADER_CURL_AXTLS_H */
+
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/cyassl.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/cyassl.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/cyassl.c	(revision 164)
@@ -0,0 +1,833 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all CyaSSL-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_CYASSL
+
+#define WOLFSSL_OPTIONS_IGNORE_SYS
+/* CyaSSL's version.h, which should contain only the version, should come
+before all other CyaSSL includes and be immediately followed by build config
+aka options.h. https://curl.haxx.se/mail/lib-2015-04/0069.html */
+#include <cyassl/version.h>
+#if defined(HAVE_CYASSL_OPTIONS_H) && (LIBCYASSL_VERSION_HEX > 0x03004008)
+#if defined(CYASSL_API) || defined(WOLFSSL_API)
+/* Safety measure. If either is defined some API include was already included
+and that's a problem since options.h hasn't been included yet. */
+#error "CyaSSL API was included before the CyaSSL build options."
+#endif
+#include <cyassl/options.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "cyassl.h"
+#include "vtls.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "rawstr.h"
+#include "x509asn1.h"
+#include "curl_printf.h"
+
+#include <cyassl/ssl.h>
+#ifdef HAVE_CYASSL_ERROR_SSL_H
+#include <cyassl/error-ssl.h>
+#else
+#include <cyassl/error.h>
+#endif
+#include <cyassl/ctaocrypt/random.h>
+#include <cyassl/ctaocrypt/sha256.h>
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if LIBCYASSL_VERSION_HEX < 0x02007002 /* < 2.7.2 */
+#define CYASSL_MAX_ERROR_SZ 80
+#endif
+
+static Curl_recv cyassl_recv;
+static Curl_send cyassl_send;
+
+
+static int do_file_type(const char *type)
+{
+  if(!type || !type[0])
+    return SSL_FILETYPE_PEM;
+  if(Curl_raw_equal(type, "PEM"))
+    return SSL_FILETYPE_PEM;
+  if(Curl_raw_equal(type, "DER"))
+    return SSL_FILETYPE_ASN1;
+  return -1;
+}
+
+/*
+ * This function loads all the client/CA certificates and CRLs. Setup the TLS
+ * layer and do all necessary magic.
+ */
+static CURLcode
+cyassl_connect_step1(struct connectdata *conn,
+                     int sockindex)
+{
+  char error_buffer[CYASSL_MAX_ERROR_SZ];
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data* conssl = &conn->ssl[sockindex];
+  SSL_METHOD* req_method = NULL;
+  void* ssl_sessionid = NULL;
+  curl_socket_t sockfd = conn->sock[sockindex];
+#ifdef HAVE_SNI
+  bool sni = FALSE;
+#define use_sni(x)  sni = (x)
+#else
+#define use_sni(x)  Curl_nop_stmt
+#endif
+
+  if(conssl->state == ssl_connection_complete)
+    return CURLE_OK;
+
+  /* check to see if we've been told to use an explicit SSL/TLS version */
+  switch(data->set.ssl.version) {
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+#if LIBCYASSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */
+    /* minimum protocol version is set later after the CTX object is created */
+    req_method = SSLv23_client_method();
+#else
+    infof(data, "CyaSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, "
+          "TLS 1.0 is used exclusively\n");
+    req_method = TLSv1_client_method();
+#endif
+    use_sni(TRUE);
+    break;
+  case CURL_SSLVERSION_TLSv1_0:
+    req_method = TLSv1_client_method();
+    use_sni(TRUE);
+    break;
+  case CURL_SSLVERSION_TLSv1_1:
+    req_method = TLSv1_1_client_method();
+    use_sni(TRUE);
+    break;
+  case CURL_SSLVERSION_TLSv1_2:
+    req_method = TLSv1_2_client_method();
+    use_sni(TRUE);
+    break;
+  case CURL_SSLVERSION_SSLv3:
+    /* before WolfSSL SSLv3 was enabled by default, and starting in WolfSSL
+       we check for its presence since it is built without it by default */
+#if !defined(WOLFSSL_VERSION) || defined(HAVE_WOLFSSLV3_CLIENT_METHOD)
+    req_method = SSLv3_client_method();
+    use_sni(FALSE);
+#else
+    failf(data, "No support for SSLv3");
+    return CURLE_NOT_BUILT_IN;
+#endif
+    break;
+  case CURL_SSLVERSION_SSLv2:
+    failf(data, "CyaSSL does not support SSLv2");
+    return CURLE_SSL_CONNECT_ERROR;
+  default:
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  if(!req_method) {
+    failf(data, "SSL: couldn't create a method!");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(conssl->ctx)
+    SSL_CTX_free(conssl->ctx);
+  conssl->ctx = SSL_CTX_new(req_method);
+
+  if(!conssl->ctx) {
+    failf(data, "SSL: couldn't create a context!");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  switch(data->set.ssl.version) {
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+#if LIBCYASSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */
+    /* Versions 3.3.0 to 3.4.6 we know the minimum protocol version is whatever
+    minimum version of TLS was built in and at least TLS 1.0. For later library
+    versions that could change (eg TLS 1.0 built in but defaults to TLS 1.1) so
+    we have this short circuit evaluation to find the minimum supported TLS
+    version. We use wolfSSL_CTX_SetMinVersion and not CyaSSL_SetMinVersion
+    because only the former will work before the user's CTX callback is called.
+    */
+    if((wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1) != 1) &&
+       (wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1_1) != 1) &&
+       (wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1_2) != 1)) {
+      failf(data, "SSL: couldn't set the minimum protocol version");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+#endif
+    break;
+  }
+
+#ifndef NO_FILESYSTEM
+  /* load trusted cacert */
+  if(data->set.str[STRING_SSL_CAFILE]) {
+    if(1 != SSL_CTX_load_verify_locations(conssl->ctx,
+                                          data->set.str[STRING_SSL_CAFILE],
+                                          data->set.str[STRING_SSL_CAPATH])) {
+      if(data->set.ssl.verifypeer) {
+        /* Fail if we insist on successfully verifying the server. */
+        failf(data, "error setting certificate verify locations:\n"
+              "  CAfile: %s\n  CApath: %s",
+              data->set.str[STRING_SSL_CAFILE]?
+              data->set.str[STRING_SSL_CAFILE]: "none",
+              data->set.str[STRING_SSL_CAPATH]?
+              data->set.str[STRING_SSL_CAPATH] : "none");
+        return CURLE_SSL_CACERT_BADFILE;
+      }
+      else {
+        /* Just continue with a warning if no strict certificate
+           verification is required. */
+        infof(data, "error setting certificate verify locations,"
+              " continuing anyway:\n");
+      }
+    }
+    else {
+      /* Everything is fine. */
+      infof(data, "successfully set certificate verify locations:\n");
+    }
+    infof(data,
+          "  CAfile: %s\n"
+          "  CApath: %s\n",
+          data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]:
+          "none",
+          data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]:
+          "none");
+  }
+
+  /* Load the client certificate, and private key */
+  if(data->set.str[STRING_CERT] && data->set.str[STRING_KEY]) {
+    int file_type = do_file_type(data->set.str[STRING_CERT_TYPE]);
+
+    if(SSL_CTX_use_certificate_file(conssl->ctx, data->set.str[STRING_CERT],
+                                     file_type) != 1) {
+      failf(data, "unable to use client certificate (no key or wrong pass"
+            " phrase?)");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    file_type = do_file_type(data->set.str[STRING_KEY_TYPE]);
+    if(SSL_CTX_use_PrivateKey_file(conssl->ctx, data->set.str[STRING_KEY],
+                                    file_type) != 1) {
+      failf(data, "unable to set private key");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+#endif /* !NO_FILESYSTEM */
+
+  /* SSL always tries to verify the peer, this only says whether it should
+   * fail to connect if the verification fails, or if it should continue
+   * anyway. In the latter case the result of the verification is checked with
+   * SSL_get_verify_result() below. */
+  SSL_CTX_set_verify(conssl->ctx,
+                     data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
+                     NULL);
+
+#ifdef HAVE_SNI
+  if(sni) {
+    struct in_addr addr4;
+#ifdef ENABLE_IPV6
+    struct in6_addr addr6;
+#endif
+    size_t hostname_len = strlen(conn->host.name);
+    if((hostname_len < USHRT_MAX) &&
+       (0 == Curl_inet_pton(AF_INET, conn->host.name, &addr4)) &&
+#ifdef ENABLE_IPV6
+       (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr6)) &&
+#endif
+       (CyaSSL_CTX_UseSNI(conssl->ctx, CYASSL_SNI_HOST_NAME, conn->host.name,
+                          (unsigned short)hostname_len) != 1)) {
+      infof(data, "WARNING: failed to configure server name indication (SNI) "
+            "TLS extension\n");
+    }
+  }
+#endif
+
+  /* give application a chance to interfere with SSL set up. */
+  if(data->set.ssl.fsslctx) {
+    CURLcode result = CURLE_OK;
+    result = (*data->set.ssl.fsslctx)(data, conssl->ctx,
+                                      data->set.ssl.fsslctxp);
+    if(result) {
+      failf(data, "error signaled by ssl ctx callback");
+      return result;
+    }
+  }
+#ifdef NO_FILESYSTEM
+  else if(data->set.ssl.verifypeer) {
+    failf(data, "SSL: Certificates couldn't be loaded because CyaSSL was built"
+          " with \"no filesystem\". Either disable peer verification"
+          " (insecure) or if you are building an application with libcurl you"
+          " can load certificates via CURLOPT_SSL_CTX_FUNCTION.");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+#endif
+
+  /* Let's make an SSL structure */
+  if(conssl->handle)
+    SSL_free(conssl->handle);
+  conssl->handle = SSL_new(conssl->ctx);
+  if(!conssl->handle) {
+    failf(data, "SSL: couldn't create a context (handle)!");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Check if there's a cached ID we can/should use here! */
+  if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
+    /* we got a session id, use it! */
+    if(!SSL_set_session(conssl->handle, ssl_sessionid)) {
+      failf(data, "SSL: SSL_set_session failed: %s",
+            ERR_error_string(SSL_get_error(conssl->handle, 0), error_buffer));
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    /* Informational message */
+    infof (data, "SSL re-using session ID\n");
+  }
+
+  /* pass the raw socket into the SSL layer */
+  if(!SSL_set_fd(conssl->handle, (int)sockfd)) {
+    failf(data, "SSL: SSL_set_fd failed");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  conssl->connecting_state = ssl_connect_2;
+  return CURLE_OK;
+}
+
+
+static CURLcode
+cyassl_connect_step2(struct connectdata *conn,
+                     int sockindex)
+{
+  int ret = -1;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data* conssl = &conn->ssl[sockindex];
+
+  conn->recv[sockindex] = cyassl_recv;
+  conn->send[sockindex] = cyassl_send;
+
+  /* Enable RFC2818 checks */
+  if(data->set.ssl.verifyhost) {
+    ret = CyaSSL_check_domain_name(conssl->handle, conn->host.name);
+    if(ret == SSL_FAILURE)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  ret = SSL_connect(conssl->handle);
+  if(ret != 1) {
+    char error_buffer[CYASSL_MAX_ERROR_SZ];
+    int  detail = SSL_get_error(conssl->handle, ret);
+
+    if(SSL_ERROR_WANT_READ == detail) {
+      conssl->connecting_state = ssl_connect_2_reading;
+      return CURLE_OK;
+    }
+    else if(SSL_ERROR_WANT_WRITE == detail) {
+      conssl->connecting_state = ssl_connect_2_writing;
+      return CURLE_OK;
+    }
+    /* There is no easy way to override only the CN matching.
+     * This will enable the override of both mismatching SubjectAltNames
+     * as also mismatching CN fields */
+    else if(DOMAIN_NAME_MISMATCH == detail) {
+#if 1
+      failf(data, "\tsubject alt name(s) or common name do not match \"%s\"\n",
+            conn->host.dispname);
+      return CURLE_PEER_FAILED_VERIFICATION;
+#else
+      /* When the CyaSSL_check_domain_name() is used and you desire to continue
+       * on a DOMAIN_NAME_MISMATCH, i.e. 'data->set.ssl.verifyhost == 0',
+       * CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA error. The only
+       * way to do this is currently to switch the CyaSSL_check_domain_name()
+       * in and out based on the 'data->set.ssl.verifyhost' value. */
+      if(data->set.ssl.verifyhost) {
+        failf(data,
+              "\tsubject alt name(s) or common name do not match \"%s\"\n",
+              conn->host.dispname);
+        return CURLE_PEER_FAILED_VERIFICATION;
+      }
+      else {
+        infof(data,
+              "\tsubject alt name(s) and/or common name do not match \"%s\"\n",
+              conn->host.dispname);
+        return CURLE_OK;
+      }
+#endif
+    }
+#if LIBCYASSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */
+    else if(ASN_NO_SIGNER_E == detail) {
+      if(data->set.ssl.verifypeer) {
+        failf(data, "\tCA signer not available for verification\n");
+        return CURLE_SSL_CACERT_BADFILE;
+      }
+      else {
+        /* Just continue with a warning if no strict certificate
+           verification is required. */
+        infof(data, "CA signer not available for verification, "
+                    "continuing anyway\n");
+      }
+    }
+#endif
+    else {
+      failf(data, "SSL_connect failed with error %d: %s", detail,
+          ERR_error_string(detail, error_buffer));
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
+#if defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) ||       \
+  defined(HAVE_CYASSL_GET_PEER_CERTIFICATE)
+    X509 *x509;
+    const char *x509_der;
+    int x509_der_len;
+    curl_X509certificate x509_parsed;
+    curl_asn1Element *pubkey;
+    CURLcode result;
+
+    x509 = SSL_get_peer_certificate(conssl->handle);
+    if(!x509) {
+      failf(data, "SSL: failed retrieving server certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    x509_der = (const char *)CyaSSL_X509_get_der(x509, &x509_der_len);
+    if(!x509_der) {
+      failf(data, "SSL: failed retrieving ASN.1 server certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    memset(&x509_parsed, 0, sizeof x509_parsed);
+    Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len);
+
+    pubkey = &x509_parsed.subjectPublicKeyInfo;
+    if(!pubkey->header || pubkey->end <= pubkey->header) {
+      failf(data, "SSL: failed retrieving public key from server certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    result = Curl_pin_peer_pubkey(data,
+                                  data->set.str[STRING_SSL_PINNEDPUBLICKEY],
+                                  (const unsigned char *)pubkey->header,
+                                  (size_t)(pubkey->end - pubkey->header));
+    if(result) {
+      failf(data, "SSL: public key does not match pinned public key!");
+      return result;
+    }
+#else
+    failf(data, "Library lacks pinning support built-in");
+    return CURLE_NOT_BUILT_IN;
+#endif
+  }
+
+  conssl->connecting_state = ssl_connect_3;
+  infof(data, "SSL connected\n");
+
+  return CURLE_OK;
+}
+
+
+static CURLcode
+cyassl_connect_step3(struct connectdata *conn,
+                     int sockindex)
+{
+  CURLcode result = CURLE_OK;
+  void *old_ssl_sessionid=NULL;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  bool incache;
+  SSL_SESSION *our_ssl_sessionid;
+
+  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+  our_ssl_sessionid = SSL_get_session(connssl->handle);
+
+  incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
+  if(incache) {
+    if(old_ssl_sessionid != our_ssl_sessionid) {
+      infof(data, "old SSL session ID is stale, removing\n");
+      Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+      incache = FALSE;
+    }
+  }
+
+  if(!incache) {
+    result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
+                                   0 /* unknown size */);
+    if(result) {
+      failf(data, "failed to store ssl session");
+      return result;
+    }
+  }
+
+  connssl->connecting_state = ssl_connect_done;
+
+  return result;
+}
+
+
+static ssize_t cyassl_send(struct connectdata *conn,
+                           int sockindex,
+                           const void *mem,
+                           size_t len,
+                           CURLcode *curlcode)
+{
+  char error_buffer[CYASSL_MAX_ERROR_SZ];
+  int  memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
+  int  rc     = SSL_write(conn->ssl[sockindex].handle, mem, memlen);
+
+  if(rc < 0) {
+    int err = SSL_get_error(conn->ssl[sockindex].handle, rc);
+
+    switch(err) {
+    case SSL_ERROR_WANT_READ:
+    case SSL_ERROR_WANT_WRITE:
+      /* there's data pending, re-invoke SSL_write() */
+      *curlcode = CURLE_AGAIN;
+      return -1;
+    default:
+      failf(conn->data, "SSL write: %s, errno %d",
+            ERR_error_string(err, error_buffer),
+            SOCKERRNO);
+      *curlcode = CURLE_SEND_ERROR;
+      return -1;
+    }
+  }
+  return rc;
+}
+
+void Curl_cyassl_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *conssl = &conn->ssl[sockindex];
+
+  if(conssl->handle) {
+    (void)SSL_shutdown(conssl->handle);
+    SSL_free (conssl->handle);
+    conssl->handle = NULL;
+  }
+  if(conssl->ctx) {
+    SSL_CTX_free (conssl->ctx);
+    conssl->ctx = NULL;
+  }
+}
+
+static ssize_t cyassl_recv(struct connectdata *conn,
+                           int num,
+                           char *buf,
+                           size_t buffersize,
+                           CURLcode *curlcode)
+{
+  char error_buffer[CYASSL_MAX_ERROR_SZ];
+  int  buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
+  int  nread    = SSL_read(conn->ssl[num].handle, buf, buffsize);
+
+  if(nread < 0) {
+    int err = SSL_get_error(conn->ssl[num].handle, nread);
+
+    switch(err) {
+    case SSL_ERROR_ZERO_RETURN: /* no more data */
+      break;
+    case SSL_ERROR_WANT_READ:
+    case SSL_ERROR_WANT_WRITE:
+      /* there's data pending, re-invoke SSL_read() */
+      *curlcode = CURLE_AGAIN;
+      return -1;
+    default:
+      failf(conn->data, "SSL read: %s, errno %d",
+            ERR_error_string(err, error_buffer),
+            SOCKERRNO);
+      *curlcode = CURLE_RECV_ERROR;
+      return -1;
+    }
+  }
+  return nread;
+}
+
+
+void Curl_cyassl_session_free(void *ptr)
+{
+  (void)ptr;
+  /* CyaSSL reuses sessions on own, no free */
+}
+
+
+size_t Curl_cyassl_version(char *buffer, size_t size)
+{
+#ifdef WOLFSSL_VERSION
+  return snprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION);
+#elif defined(CYASSL_VERSION)
+  return snprintf(buffer, size, "CyaSSL/%s", CYASSL_VERSION);
+#else
+  return snprintf(buffer, size, "CyaSSL/%s", "<1.8.8");
+#endif
+}
+
+
+int Curl_cyassl_init(void)
+{
+  return (CyaSSL_Init() == SSL_SUCCESS);
+}
+
+
+bool Curl_cyassl_data_pending(const struct connectdata* conn, int connindex)
+{
+  if(conn->ssl[connindex].handle)   /* SSL is in use */
+    return (0 != SSL_pending(conn->ssl[connindex].handle)) ? TRUE : FALSE;
+  else
+    return FALSE;
+}
+
+
+/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+int Curl_cyassl_shutdown(struct connectdata *conn, int sockindex)
+{
+  int retval = 0;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  if(connssl->handle) {
+    SSL_free (connssl->handle);
+    connssl->handle = NULL;
+  }
+  return retval;
+}
+
+
+static CURLcode
+cyassl_connect_common(struct connectdata *conn,
+                      int sockindex,
+                      bool nonblocking,
+                      bool *done)
+{
+  CURLcode result;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  long timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1==connssl->connecting_state) {
+    /* Find out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    result = cyassl_connect_step1(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading
+       || connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if
+     * this connection is part of a multi handle and this loop would
+     * execute again. This permits the owner of a multi handle to
+     * abort a connection attempt before step2 has completed while
+     * ensuring that a client using select() or epoll() will always
+     * have a valid fdset to wait on.
+     */
+    result = cyassl_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
+  } /* repeat step2 until all transactions are done. */
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = cyassl_connect_step3(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = cyassl_recv;
+    conn->send[sockindex] = cyassl_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* Reset our connect state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+
+CURLcode
+Curl_cyassl_connect_nonblocking(struct connectdata *conn,
+                                int sockindex,
+                                bool *done)
+{
+  return cyassl_connect_common(conn, sockindex, TRUE, done);
+}
+
+
+CURLcode
+Curl_cyassl_connect(struct connectdata *conn,
+                    int sockindex)
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = cyassl_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+int Curl_cyassl_random(struct SessionHandle *data,
+                       unsigned char *entropy,
+                       size_t length)
+{
+  RNG rng;
+  (void)data;
+  if(InitRng(&rng))
+    return 1;
+  if(length > UINT_MAX)
+    return 1;
+  if(RNG_GenerateBlock(&rng, entropy, (unsigned)length))
+    return 1;
+  return 0;
+}
+
+void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */
+                      size_t tmplen,
+                      unsigned char *sha256sum /* output */,
+                      size_t unused)
+{
+  Sha256 SHA256pw;
+  (void)unused;
+  InitSha256(&SHA256pw);
+  Sha256Update(&SHA256pw, tmp, (word32)tmplen);
+  Sha256Final(&SHA256pw, sha256sum);
+}
+
+#ifndef OPENSSL_EXTRA
+#include <wolfssl/wolfcrypt/wc_port.h>
+#include <wolfssl/ssl.h>
+#include <wolfssl/openssl/md5.h>
+#include <wolfssl/wolfcrypt/md5.h>
+
+#define WOLFSSL_ENTER(a)
+
+void wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5)
+{
+	typedef char md5_test[sizeof(MD5_CTX) >= sizeof(Md5) ? 1 : -1];
+	(void)sizeof(md5_test);
+
+	WOLFSSL_ENTER("MD5_Init");
+	wc_InitMd5((Md5*)md5);
+}
+
+
+void wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input,
+	unsigned long sz)
+{
+	WOLFSSL_ENTER("wolfSSL_MD5_Update");
+	wc_Md5Update((Md5*)md5, (const byte*)input, (word32)sz);
+}
+
+
+void wolfSSL_MD5_Final(byte* input, WOLFSSL_MD5_CTX* md5)
+{
+	WOLFSSL_ENTER("MD5_Final");
+	wc_Md5Final((Md5*)md5, input);
+}
+#endif
+
+#endif
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/cyassl.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/cyassl.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/cyassl.h	(revision 164)
@@ -0,0 +1,75 @@
+#ifndef HEADER_CURL_CYASSL_H
+#define HEADER_CURL_CYASSL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_CYASSL
+
+CURLcode Curl_cyassl_connect(struct connectdata *conn, int sockindex);
+bool Curl_cyassl_data_pending(const struct connectdata* conn, int connindex);
+int Curl_cyassl_shutdown(struct connectdata* conn, int sockindex);
+
+ /* close a SSL connection */
+void Curl_cyassl_close(struct connectdata *conn, int sockindex);
+
+void Curl_cyassl_session_free(void *ptr);
+size_t Curl_cyassl_version(char *buffer, size_t size);
+int Curl_cyassl_shutdown(struct connectdata *conn, int sockindex);
+int Curl_cyassl_init(void);
+CURLcode Curl_cyassl_connect_nonblocking(struct connectdata *conn,
+                                         int sockindex,
+                                         bool *done);
+int Curl_cyassl_random(struct SessionHandle *data,
+                       unsigned char *entropy,
+                       size_t length);
+void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */
+                     size_t tmplen,
+                     unsigned char *sha256sum, /* output */
+                     size_t unused);
+
+/* Set the API backend definition to Schannel */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_CYASSL
+
+/* this backend supports CURLOPT_SSL_CTX_* */
+#define have_curlssl_ssl_ctx 1
+
+/* API setup for CyaSSL */
+#define curlssl_init Curl_cyassl_init
+#define curlssl_cleanup() Curl_nop_stmt
+#define curlssl_connect Curl_cyassl_connect
+#define curlssl_connect_nonblocking Curl_cyassl_connect_nonblocking
+#define curlssl_session_free(x)  Curl_cyassl_session_free(x)
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_cyassl_close
+#define curlssl_shutdown(x,y) Curl_cyassl_shutdown(x,y)
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_cyassl_version
+#define curlssl_check_cxn(x) ((void)x, -1)
+#define curlssl_data_pending(x,y) Curl_cyassl_data_pending(x,y)
+#define curlssl_random(x,y,z) Curl_cyassl_random(x,y,z)
+#define curlssl_sha256sum(a,b,c,d) Curl_cyassl_sha256sum(a,b,c,d)
+
+#endif /* USE_CYASSL */
+#endif /* HEADER_CURL_CYASSL_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/darwinssl.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/darwinssl.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/darwinssl.c	(revision 164)
@@ -0,0 +1,2484 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all iOS and Mac OS X SecureTransport-specific code for the
+ * TLS/SSL layer. No code but vtls.c should ever call or use these functions.
+ */
+
+#include "curl_setup.h"
+
+#include "urldata.h" /* for the SessionHandle definition */
+#include "curl_base64.h"
+#include "strtok.h"
+
+#ifdef USE_DARWINSSL
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <Security/Security.h>
+#include <Security/SecureTransport.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CommonCrypto/CommonDigest.h>
+
+/* The Security framework has changed greatly between iOS and different OS X
+   versions, and we will try to support as many of them as we can (back to
+   Leopard and iOS 5) by using macros and weak-linking.
+
+   IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
+   you must build this project against the 10.8 SDK or later. */
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
+#error "The darwinssl back-end requires Leopard or later."
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
+
+#define CURL_BUILD_IOS 0
+#define CURL_BUILD_IOS_7 0
+#define CURL_BUILD_MAC 1
+/* This is the maximum API level we are allowed to use when building: */
+#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
+#define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
+#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
+/* These macros mean "the following code is present to allow runtime backward
+   compatibility with at least this cat or earlier":
+   (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
+   environmental variable.) */
+#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
+#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
+#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
+#define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
+#define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
+
+#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
+#define CURL_BUILD_IOS 1
+#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
+#define CURL_BUILD_MAC 0
+#define CURL_BUILD_MAC_10_5 0
+#define CURL_BUILD_MAC_10_6 0
+#define CURL_BUILD_MAC_10_7 0
+#define CURL_BUILD_MAC_10_8 0
+#define CURL_SUPPORT_MAC_10_5 0
+#define CURL_SUPPORT_MAC_10_6 0
+#define CURL_SUPPORT_MAC_10_7 0
+#define CURL_SUPPORT_MAC_10_8 0
+#define CURL_SUPPORT_MAC_10_9 0
+
+#else
+#error "The darwinssl back-end requires iOS or OS X."
+#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
+
+#if CURL_BUILD_MAC
+#include <sys/sysctl.h>
+#endif /* CURL_BUILD_MAC */
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "connect.h"
+#include "select.h"
+#include "vtls.h"
+#include "darwinssl.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* From MacTypes.h (which we can't include because it isn't present in iOS: */
+#define ioErr -36
+#define paramErr -50
+
+/* The following two functions were ripped from Apple sample code,
+ * with some modifications: */
+static OSStatus SocketRead(SSLConnectionRef connection,
+                           void *data,          /* owned by
+                                                 * caller, data
+                                                 * RETURNED */
+                           size_t *dataLength)  /* IN/OUT */
+{
+  size_t bytesToGo = *dataLength;
+  size_t initLen = bytesToGo;
+  UInt8 *currData = (UInt8 *)data;
+  /*int sock = *(int *)connection;*/
+  struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
+  int sock = connssl->ssl_sockfd;
+  OSStatus rtn = noErr;
+  size_t bytesRead;
+  ssize_t rrtn;
+  int theErr;
+
+  *dataLength = 0;
+
+  for(;;) {
+    bytesRead = 0;
+    rrtn = read(sock, currData, bytesToGo);
+    if(rrtn <= 0) {
+      /* this is guesswork... */
+      theErr = errno;
+      if(rrtn == 0) { /* EOF = server hung up */
+        /* the framework will turn this into errSSLClosedNoNotify */
+        rtn = errSSLClosedGraceful;
+      }
+      else /* do the switch */
+        switch(theErr) {
+          case ENOENT:
+            /* connection closed */
+            rtn = errSSLClosedGraceful;
+            break;
+          case ECONNRESET:
+            rtn = errSSLClosedAbort;
+            break;
+          case EAGAIN:
+            rtn = errSSLWouldBlock;
+            connssl->ssl_direction = false;
+            break;
+          default:
+            rtn = ioErr;
+            break;
+        }
+      break;
+    }
+    else {
+      bytesRead = rrtn;
+    }
+    bytesToGo -= bytesRead;
+    currData  += bytesRead;
+
+    if(bytesToGo == 0) {
+      /* filled buffer with incoming data, done */
+      break;
+    }
+  }
+  *dataLength = initLen - bytesToGo;
+
+  return rtn;
+}
+
+static OSStatus SocketWrite(SSLConnectionRef connection,
+                            const void *data,
+                            size_t *dataLength)  /* IN/OUT */
+{
+  size_t bytesSent = 0;
+  /*int sock = *(int *)connection;*/
+  struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
+  int sock = connssl->ssl_sockfd;
+  ssize_t length;
+  size_t dataLen = *dataLength;
+  const UInt8 *dataPtr = (UInt8 *)data;
+  OSStatus ortn;
+  int theErr;
+
+  *dataLength = 0;
+
+  do {
+    length = write(sock,
+                   (char*)dataPtr + bytesSent,
+                   dataLen - bytesSent);
+  } while((length > 0) &&
+           ( (bytesSent += length) < dataLen) );
+
+  if(length <= 0) {
+    theErr = errno;
+    if(theErr == EAGAIN) {
+      ortn = errSSLWouldBlock;
+      connssl->ssl_direction = true;
+    }
+    else {
+      ortn = ioErr;
+    }
+  }
+  else {
+    ortn = noErr;
+  }
+  *dataLength = bytesSent;
+  return ortn;
+}
+
+CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
+  switch (cipher) {
+    /* SSL version 3.0 */
+    case SSL_RSA_WITH_NULL_MD5:
+      return "SSL_RSA_WITH_NULL_MD5";
+      break;
+    case SSL_RSA_WITH_NULL_SHA:
+      return "SSL_RSA_WITH_NULL_SHA";
+      break;
+    case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
+      return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
+      break;
+    case SSL_RSA_WITH_RC4_128_MD5:
+      return "SSL_RSA_WITH_RC4_128_MD5";
+      break;
+    case SSL_RSA_WITH_RC4_128_SHA:
+      return "SSL_RSA_WITH_RC4_128_SHA";
+      break;
+    case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
+      return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
+      break;
+    case SSL_RSA_WITH_IDEA_CBC_SHA:
+      return "SSL_RSA_WITH_IDEA_CBC_SHA";
+      break;
+    case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_RSA_WITH_DES_CBC_SHA:
+      return "SSL_RSA_WITH_DES_CBC_SHA";
+      break;
+    case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DH_DSS_WITH_DES_CBC_SHA:
+      return "SSL_DH_DSS_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DH_RSA_WITH_DES_CBC_SHA:
+      return "SSL_DH_RSA_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DHE_DSS_WITH_DES_CBC_SHA:
+      return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DHE_RSA_WITH_DES_CBC_SHA:
+      return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
+      return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
+      break;
+    case SSL_DH_anon_WITH_RC4_128_MD5:
+      return "SSL_DH_anon_WITH_RC4_128_MD5";
+      break;
+    case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DH_anon_WITH_DES_CBC_SHA:
+      return "SSL_DH_anon_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
+      return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
+      break;
+    case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
+      return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
+      break;
+    /* TLS 1.0 with AES (RFC 3268)
+       (Apparently these are used in SSLv3 implementations as well.) */
+    case TLS_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
+      break;
+    /* SSL version 2.0 */
+    case SSL_RSA_WITH_RC2_CBC_MD5:
+      return "SSL_RSA_WITH_RC2_CBC_MD5";
+      break;
+    case SSL_RSA_WITH_IDEA_CBC_MD5:
+      return "SSL_RSA_WITH_IDEA_CBC_MD5";
+      break;
+    case SSL_RSA_WITH_DES_CBC_MD5:
+      return "SSL_RSA_WITH_DES_CBC_MD5";
+      break;
+    case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
+      return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
+      break;
+  }
+  return "SSL_NULL_WITH_NULL_NULL";
+}
+
+CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
+  switch(cipher) {
+    /* TLS 1.0 with AES (RFC 3268) */
+    case TLS_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
+      break;
+#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
+    /* TLS 1.0 with ECDSA (RFC 4492) */
+    case TLS_ECDH_ECDSA_WITH_NULL_SHA:
+      return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
+      break;
+    case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
+      return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_NULL_SHA:
+      return "TLS_ECDH_RSA_WITH_NULL_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_RC4_128_SHA:
+      return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_NULL_SHA:
+      return "TLS_ECDHE_RSA_WITH_NULL_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
+      return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_NULL_SHA:
+      return "TLS_ECDH_anon_WITH_NULL_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_RC4_128_SHA:
+      return "TLS_ECDH_anon_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
+      break;
+#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+    /* TLS 1.2 (RFC 5246) */
+    case TLS_RSA_WITH_NULL_MD5:
+      return "TLS_RSA_WITH_NULL_MD5";
+      break;
+    case TLS_RSA_WITH_NULL_SHA:
+      return "TLS_RSA_WITH_NULL_SHA";
+      break;
+    case TLS_RSA_WITH_RC4_128_MD5:
+      return "TLS_RSA_WITH_RC4_128_MD5";
+      break;
+    case TLS_RSA_WITH_RC4_128_SHA:
+      return "TLS_RSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_RSA_WITH_NULL_SHA256:
+      return "TLS_RSA_WITH_NULL_SHA256";
+      break;
+    case TLS_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_RSA_WITH_AES_256_CBC_SHA256:
+      return "TLS_RSA_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
+      return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
+      return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
+      return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
+      return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
+      return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
+      return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DH_anon_WITH_RC4_128_MD5:
+      return "TLS_DH_anon_WITH_RC4_128_MD5";
+      break;
+    case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
+      return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
+      return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
+      break;
+    /* TLS 1.2 with AES GCM (RFC 5288) */
+    case TLS_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
+      return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
+      return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
+      return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
+      return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
+      return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
+      return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
+      break;
+    /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
+    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+      return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
+      return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
+      return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
+      return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
+      return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
+      break;
+#else
+    case SSL_RSA_WITH_NULL_MD5:
+      return "TLS_RSA_WITH_NULL_MD5";
+      break;
+    case SSL_RSA_WITH_NULL_SHA:
+      return "TLS_RSA_WITH_NULL_SHA";
+      break;
+    case SSL_RSA_WITH_RC4_128_MD5:
+      return "TLS_RSA_WITH_RC4_128_MD5";
+      break;
+    case SSL_RSA_WITH_RC4_128_SHA:
+      return "TLS_RSA_WITH_RC4_128_SHA";
+      break;
+    case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DH_anon_WITH_RC4_128_MD5:
+      return "TLS_DH_anon_WITH_RC4_128_MD5";
+      break;
+    case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
+      break;
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+    /* TLS PSK (RFC 4279): */
+    case TLS_PSK_WITH_RC4_128_SHA:
+      return "TLS_PSK_WITH_RC4_128_SHA";
+      break;
+    case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_PSK_WITH_AES_128_CBC_SHA:
+      return "TLS_PSK_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_PSK_WITH_AES_256_CBC_SHA:
+      return "TLS_PSK_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_RC4_128_SHA:
+      return "TLS_DHE_PSK_WITH_RC4_128_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_RC4_128_SHA:
+      return "TLS_RSA_PSK_WITH_RC4_128_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
+      return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
+      return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
+      break;
+    /* More TLS PSK (RFC 4785): */
+    case TLS_PSK_WITH_NULL_SHA:
+      return "TLS_PSK_WITH_NULL_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_NULL_SHA:
+      return "TLS_DHE_PSK_WITH_NULL_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_NULL_SHA:
+      return "TLS_RSA_PSK_WITH_NULL_SHA";
+      break;
+    /* Even more TLS PSK (RFC 5487): */
+    case TLS_PSK_WITH_AES_128_GCM_SHA256:
+      return "TLS_PSK_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_PSK_WITH_AES_256_GCM_SHA384:
+      return "TLS_PSK_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
+      return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
+      return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
+      return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
+      return "TLS_PSK_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_PSK_WITH_AES_128_CBC_SHA256:
+      return "TLS_PSK_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_PSK_WITH_AES_256_CBC_SHA384:
+      return "TLS_PSK_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_PSK_WITH_NULL_SHA256:
+      return "TLS_PSK_WITH_NULL_SHA256";
+      break;
+    case TLS_PSK_WITH_NULL_SHA384:
+      return "TLS_PSK_WITH_NULL_SHA384";
+      break;
+    case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
+      return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
+      return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_DHE_PSK_WITH_NULL_SHA256:
+      return "TLS_DHE_PSK_WITH_NULL_SHA256";
+      break;
+    case TLS_DHE_PSK_WITH_NULL_SHA384:
+      return "TLS_RSA_PSK_WITH_NULL_SHA384";
+      break;
+    case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
+      return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
+      return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_RSA_PSK_WITH_NULL_SHA256:
+      return "TLS_RSA_PSK_WITH_NULL_SHA256";
+      break;
+    case TLS_RSA_PSK_WITH_NULL_SHA384:
+      return "TLS_RSA_PSK_WITH_NULL_SHA384";
+      break;
+#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
+  }
+  return "TLS_NULL_WITH_NULL_NULL";
+}
+
+#if CURL_BUILD_MAC
+CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
+{
+  int mib[2];
+  char *os_version;
+  size_t os_version_len;
+  char *os_version_major, *os_version_minor/*, *os_version_point*/;
+  char *tok_buf;
+
+  /* Get the Darwin kernel version from the kernel using sysctl(): */
+  mib[0] = CTL_KERN;
+  mib[1] = KERN_OSRELEASE;
+  if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
+    return;
+  os_version = malloc(os_version_len*sizeof(char));
+  if(!os_version)
+    return;
+  if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
+    free(os_version);
+    return;
+  }
+
+  /* Parse the version: */
+  os_version_major = strtok_r(os_version, ".", &tok_buf);
+  os_version_minor = strtok_r(NULL, ".", &tok_buf);
+  /*os_version_point = strtok_r(NULL, ".", &tok_buf);*/
+  *major = atoi(os_version_major);
+  *minor = atoi(os_version_minor);
+  free(os_version);
+}
+#endif /* CURL_BUILD_MAC */
+
+/* Apple provides a myriad of ways of getting information about a certificate
+   into a string. Some aren't available under iOS or newer cats. So here's
+   a unified function for getting a string describing the certificate that
+   ought to work in all cats starting with Leopard. */
+CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
+{
+  CFStringRef server_cert_summary = CFSTR("(null)");
+
+#if CURL_BUILD_IOS
+  /* iOS: There's only one way to do this. */
+  server_cert_summary = SecCertificateCopySubjectSummary(cert);
+#else
+#if CURL_BUILD_MAC_10_7
+  /* Lion & later: Get the long description if we can. */
+  if(SecCertificateCopyLongDescription != NULL)
+    server_cert_summary =
+      SecCertificateCopyLongDescription(NULL, cert, NULL);
+  else
+#endif /* CURL_BUILD_MAC_10_7 */
+#if CURL_BUILD_MAC_10_6
+  /* Snow Leopard: Get the certificate summary. */
+  if(SecCertificateCopySubjectSummary != NULL)
+    server_cert_summary = SecCertificateCopySubjectSummary(cert);
+  else
+#endif /* CURL_BUILD_MAC_10_6 */
+  /* Leopard is as far back as we go... */
+  (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
+#endif /* CURL_BUILD_IOS */
+  return server_cert_summary;
+}
+
+#if CURL_SUPPORT_MAC_10_6
+/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
+   deprecation warnings, so let's not compile this unless it's necessary: */
+static OSStatus CopyIdentityWithLabelOldSchool(char *label,
+                                               SecIdentityRef *out_c_a_k)
+{
+  OSStatus status = errSecItemNotFound;
+  SecKeychainAttributeList attr_list;
+  SecKeychainAttribute attr;
+  SecKeychainSearchRef search = NULL;
+  SecCertificateRef cert = NULL;
+
+  /* Set up the attribute list: */
+  attr_list.count = 1L;
+  attr_list.attr = &attr;
+
+  /* Set up our lone search criterion: */
+  attr.tag = kSecLabelItemAttr;
+  attr.data = label;
+  attr.length = (UInt32)strlen(label);
+
+  /* Start searching: */
+  status = SecKeychainSearchCreateFromAttributes(NULL,
+                                                 kSecCertificateItemClass,
+                                                 &attr_list,
+                                                 &search);
+  if(status == noErr) {
+    status = SecKeychainSearchCopyNext(search,
+                                       (SecKeychainItemRef *)&cert);
+    if(status == noErr && cert) {
+      /* If we found a certificate, does it have a private key? */
+      status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
+      CFRelease(cert);
+    }
+  }
+
+  if(search)
+    CFRelease(search);
+  return status;
+}
+#endif /* CURL_SUPPORT_MAC_10_6 */
+
+static OSStatus CopyIdentityWithLabel(char *label,
+                                      SecIdentityRef *out_cert_and_key)
+{
+  OSStatus status = errSecItemNotFound;
+
+#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
+  /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
+     kSecClassIdentity was introduced in Lion. If both exist, let's use them
+     to find the certificate. */
+  if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
+    CFTypeRef keys[4];
+    CFTypeRef values[4];
+    CFDictionaryRef query_dict;
+    CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
+      kCFStringEncodingUTF8);
+
+    /* Set up our search criteria and expected results: */
+    values[0] = kSecClassIdentity; /* we want a certificate and a key */
+    keys[0] = kSecClass;
+    values[1] = kCFBooleanTrue;    /* we want a reference */
+    keys[1] = kSecReturnRef;
+    values[2] = kSecMatchLimitOne; /* one is enough, thanks */
+    keys[2] = kSecMatchLimit;
+    /* identity searches need a SecPolicyRef in order to work */
+    values[3] = SecPolicyCreateSSL(false, label_cf);
+    keys[3] = kSecMatchPolicy;
+    query_dict = CFDictionaryCreate(NULL, (const void **)keys,
+                                   (const void **)values, 4L,
+                                   &kCFCopyStringDictionaryKeyCallBacks,
+                                   &kCFTypeDictionaryValueCallBacks);
+    CFRelease(values[3]);
+    CFRelease(label_cf);
+
+    /* Do we have a match? */
+    status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
+    CFRelease(query_dict);
+  }
+  else {
+#if CURL_SUPPORT_MAC_10_6
+    /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
+    status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
+#endif /* CURL_SUPPORT_MAC_10_7 */
+  }
+#elif CURL_SUPPORT_MAC_10_6
+  /* For developers building on older cats, we have no choice but to fall back
+     to SecKeychainSearch. */
+  status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
+#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
+  return status;
+}
+
+static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
+                                           const char *cPassword,
+                                           SecIdentityRef *out_cert_and_key)
+{
+  OSStatus status = errSecItemNotFound;
+  CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
+    (const UInt8 *)cPath, strlen(cPath), false);
+  CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
+    cPassword, kCFStringEncodingUTF8) : NULL;
+  CFDataRef pkcs_data = NULL;
+
+  /* We can import P12 files on iOS or OS X 10.7 or later: */
+  /* These constants are documented as having first appeared in 10.6 but they
+     raise linker errors when used on that cat for some reason. */
+#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
+  if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
+    NULL, NULL, &status)) {
+    const void *cKeys[] = {kSecImportExportPassphrase};
+    const void *cValues[] = {password};
+    CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
+      password ? 1L : 0L, NULL, NULL);
+    CFArrayRef items = NULL;
+
+    /* Here we go: */
+    status = SecPKCS12Import(pkcs_data, options, &items);
+    if(status == noErr && items && CFArrayGetCount(items)) {
+      CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
+      const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
+        kSecImportItemIdentity);
+
+      /* Retain the identity; we don't care about any other data... */
+      CFRetain(temp_identity);
+      *out_cert_and_key = (SecIdentityRef)temp_identity;
+    }
+
+    if(items)
+      CFRelease(items);
+    CFRelease(options);
+    CFRelease(pkcs_data);
+  }
+#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
+  if(password)
+    CFRelease(password);
+  CFRelease(pkcs_url);
+  return status;
+}
+
+/* This code was borrowed from nss.c, with some modifications:
+ * Determine whether the nickname passed in is a filename that needs to
+ * be loaded as a PEM or a regular NSS nickname.
+ *
+ * returns 1 for a file
+ * returns 0 for not a file
+ */
+CF_INLINE bool is_file(const char *filename)
+{
+  struct_stat st;
+
+  if(filename == NULL)
+    return false;
+
+  if(stat(filename, &st) == 0)
+    return S_ISREG(st.st_mode);
+  return false;
+}
+
+static CURLcode darwinssl_connect_step1(struct connectdata *conn,
+                                        int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  curl_socket_t sockfd = conn->sock[sockindex];
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif /* ENABLE_IPV6 */
+  size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
+  SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
+  char *ssl_sessionid;
+  size_t ssl_sessionid_len;
+  OSStatus err = noErr;
+#if CURL_BUILD_MAC
+  int darwinver_maj = 0, darwinver_min = 0;
+
+  GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
+#endif /* CURL_BUILD_MAC */
+
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+  if(SSLCreateContext != NULL) {  /* use the newer API if avaialble */
+    if(connssl->ssl_ctx)
+      CFRelease(connssl->ssl_ctx);
+    connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
+    if(!connssl->ssl_ctx) {
+      failf(data, "SSL: couldn't create a context!");
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+  else {
+  /* The old ST API does not exist under iOS, so don't compile it: */
+#if CURL_SUPPORT_MAC_10_8
+    if(connssl->ssl_ctx)
+      (void)SSLDisposeContext(connssl->ssl_ctx);
+    err = SSLNewContext(false, &(connssl->ssl_ctx));
+    if(err != noErr) {
+      failf(data, "SSL: couldn't create a context: OSStatus %d", err);
+      return CURLE_OUT_OF_MEMORY;
+    }
+#endif /* CURL_SUPPORT_MAC_10_8 */
+  }
+#else
+  if(connssl->ssl_ctx)
+    (void)SSLDisposeContext(connssl->ssl_ctx);
+  err = SSLNewContext(false, &(connssl->ssl_ctx));
+  if(err != noErr) {
+    failf(data, "SSL: couldn't create a context: OSStatus %d", err);
+    return CURLE_OUT_OF_MEMORY;
+  }
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+  connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
+
+  /* check to see if we've been told to use an explicit SSL/TLS version */
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+  if(SSLSetProtocolVersionMax != NULL) {
+    switch(data->set.ssl.version) {
+      default:
+      case CURL_SSLVERSION_DEFAULT:
+      case CURL_SSLVERSION_TLSv1:
+        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
+        break;
+      case CURL_SSLVERSION_TLSv1_0:
+        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
+        break;
+      case CURL_SSLVERSION_TLSv1_1:
+        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
+        break;
+      case CURL_SSLVERSION_TLSv1_2:
+        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
+        break;
+      case CURL_SSLVERSION_SSLv3:
+        err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
+        if(err != noErr) {
+          failf(data, "Your version of the OS does not support SSLv3");
+          return CURLE_SSL_CONNECT_ERROR;
+        }
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
+        break;
+      case CURL_SSLVERSION_SSLv2:
+        err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
+        if(err != noErr) {
+          failf(data, "Your version of the OS does not support SSLv2");
+          return CURLE_SSL_CONNECT_ERROR;
+        }
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
+    }
+  }
+  else {
+#if CURL_SUPPORT_MAC_10_8
+    (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                       kSSLProtocolAll,
+                                       false);
+    switch (data->set.ssl.version) {
+      default:
+      case CURL_SSLVERSION_DEFAULT:
+      case CURL_SSLVERSION_TLSv1:
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol1,
+                                           true);
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol11,
+                                           true);
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol12,
+                                           true);
+        break;
+      case CURL_SSLVERSION_TLSv1_0:
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol1,
+                                           true);
+        break;
+      case CURL_SSLVERSION_TLSv1_1:
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol11,
+                                           true);
+        break;
+      case CURL_SSLVERSION_TLSv1_2:
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol12,
+                                           true);
+        break;
+      case CURL_SSLVERSION_SSLv3:
+        err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kSSLProtocol3,
+                                           true);
+        if(err != noErr) {
+          failf(data, "Your version of the OS does not support SSLv3");
+          return CURLE_SSL_CONNECT_ERROR;
+        }
+        break;
+      case CURL_SSLVERSION_SSLv2:
+        err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kSSLProtocol2,
+                                           true);
+        if(err != noErr) {
+          failf(data, "Your version of the OS does not support SSLv2");
+          return CURLE_SSL_CONNECT_ERROR;
+        }
+        break;
+    }
+#endif  /* CURL_SUPPORT_MAC_10_8 */
+  }
+#else
+  (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
+  switch(data->set.ssl.version) {
+    default:
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+    case CURL_SSLVERSION_TLSv1_0:
+      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                         kTLSProtocol1,
+                                         true);
+      break;
+    case CURL_SSLVERSION_TLSv1_1:
+      failf(data, "Your version of the OS does not support TLSv1.1");
+      return CURLE_SSL_CONNECT_ERROR;
+    case CURL_SSLVERSION_TLSv1_2:
+      failf(data, "Your version of the OS does not support TLSv1.2");
+      return CURLE_SSL_CONNECT_ERROR;
+    case CURL_SSLVERSION_SSLv2:
+      err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                         kSSLProtocol2,
+                                         true);
+      if(err != noErr) {
+        failf(data, "Your version of the OS does not support SSLv2");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      break;
+    case CURL_SSLVERSION_SSLv3:
+      err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                         kSSLProtocol3,
+                                         true);
+      if(err != noErr) {
+        failf(data, "Your version of the OS does not support SSLv3");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      break;
+  }
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+
+  if(data->set.str[STRING_KEY]) {
+    infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
+                "Transport. The private key must be in the Keychain.\n");
+  }
+
+  if(data->set.str[STRING_CERT]) {
+    SecIdentityRef cert_and_key = NULL;
+    bool is_cert_file = is_file(data->set.str[STRING_CERT]);
+
+    /* User wants to authenticate with a client cert. Look for it:
+       If we detect that this is a file on disk, then let's load it.
+       Otherwise, assume that the user wants to use an identity loaded
+       from the Keychain. */
+    if(is_cert_file) {
+      if(!data->set.str[STRING_CERT_TYPE])
+        infof(data, "WARNING: SSL: Certificate type not set, assuming "
+                    "PKCS#12 format.\n");
+      else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12",
+        strlen(data->set.str[STRING_CERT_TYPE])) != 0)
+        infof(data, "WARNING: SSL: The Security framework only supports "
+                    "loading identities that are in PKCS#12 format.\n");
+
+      err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT],
+        data->set.str[STRING_KEY_PASSWD], &cert_and_key);
+    }
+    else
+      err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
+
+    if(err == noErr) {
+      SecCertificateRef cert = NULL;
+      CFTypeRef certs_c[1];
+      CFArrayRef certs;
+
+      /* If we found one, print it out: */
+      err = SecIdentityCopyCertificate(cert_and_key, &cert);
+      if(err == noErr) {
+        CFStringRef cert_summary = CopyCertSubject(cert);
+        char cert_summary_c[128];
+
+        if(cert_summary) {
+          memset(cert_summary_c, 0, 128);
+          if(CFStringGetCString(cert_summary,
+                                cert_summary_c,
+                                128,
+                                kCFStringEncodingUTF8)) {
+            infof(data, "Client certificate: %s\n", cert_summary_c);
+          }
+          CFRelease(cert_summary);
+          CFRelease(cert);
+        }
+      }
+      certs_c[0] = cert_and_key;
+      certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
+                            &kCFTypeArrayCallBacks);
+      err = SSLSetCertificate(connssl->ssl_ctx, certs);
+      if(certs)
+        CFRelease(certs);
+      if(err != noErr) {
+        failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
+        return CURLE_SSL_CERTPROBLEM;
+      }
+      CFRelease(cert_and_key);
+    }
+    else {
+      switch(err) {
+        case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
+          failf(data, "SSL: Incorrect password for the certificate \"%s\" "
+                      "and its private key.", data->set.str[STRING_CERT]);
+          break;
+        case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
+          failf(data, "SSL: Couldn't make sense of the data in the "
+                      "certificate \"%s\" and its private key.",
+                      data->set.str[STRING_CERT]);
+          break;
+        case -25260: /* errSecPassphraseRequired */
+          failf(data, "SSL The certificate \"%s\" requires a password.",
+                      data->set.str[STRING_CERT]);
+          break;
+        case errSecItemNotFound:
+          failf(data, "SSL: Can't find the certificate \"%s\" and its private "
+                      "key in the Keychain.", data->set.str[STRING_CERT]);
+          break;
+        default:
+          failf(data, "SSL: Can't load the certificate \"%s\" and its private "
+                      "key: OSStatus %d", data->set.str[STRING_CERT], err);
+          break;
+      }
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  /* SSL always tries to verify the peer, this only says whether it should
+   * fail to connect if the verification fails, or if it should continue
+   * anyway. In the latter case the result of the verification is checked with
+   * SSL_get_verify_result() below. */
+#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
+  /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
+     a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
+     works, it doesn't work as expected under Snow Leopard or Lion.
+     So we need to call SSLSetEnableCertVerify() on those older cats in order
+     to disable certificate validation if the user turned that off.
+     (SecureTransport will always validate the certificate chain by
+     default.) */
+  /* (Note: Darwin 12.x.x is Mountain Lion.) */
+#if CURL_BUILD_MAC
+  if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
+#else
+  if(SSLSetSessionOption != NULL) {
+#endif /* CURL_BUILD_MAC */
+    bool break_on_auth = !data->set.ssl.verifypeer ||
+      data->set.str[STRING_SSL_CAFILE];
+    err = SSLSetSessionOption(connssl->ssl_ctx,
+                              kSSLSessionOptionBreakOnServerAuth,
+                              break_on_auth);
+    if(err != noErr) {
+      failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  else {
+#if CURL_SUPPORT_MAC_10_8
+    err = SSLSetEnableCertVerify(connssl->ssl_ctx,
+                                 data->set.ssl.verifypeer?true:false);
+    if(err != noErr) {
+      failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+#endif /* CURL_SUPPORT_MAC_10_8 */
+  }
+#else
+  err = SSLSetEnableCertVerify(connssl->ssl_ctx,
+                               data->set.ssl.verifypeer?true:false);
+  if(err != noErr) {
+    failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
+
+  if(data->set.str[STRING_SSL_CAFILE]) {
+    bool is_cert_file = is_file(data->set.str[STRING_SSL_CAFILE]);
+
+    if(!is_cert_file) {
+      failf(data, "SSL: can't load CA certificate file %s",
+            data->set.str[STRING_SSL_CAFILE]);
+      return CURLE_SSL_CACERT_BADFILE;
+    }
+    if(!data->set.ssl.verifypeer) {
+      failf(data, "SSL: CA certificate set, but certificate verification "
+            "is disabled");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  /* Configure hostname check. SNI is used if available.
+   * Both hostname check and SNI require SSLSetPeerDomainName().
+   * Also: the verifyhost setting influences SNI usage */
+  if(data->set.ssl.verifyhost) {
+    err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
+    strlen(conn->host.name));
+
+    if(err != noErr) {
+      infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
+            err);
+    }
+
+    if((Curl_inet_pton(AF_INET, conn->host.name, &addr))
+  #ifdef ENABLE_IPV6
+    || (Curl_inet_pton(AF_INET6, conn->host.name, &addr))
+  #endif
+       ) {
+         infof(data, "WARNING: using IP address, SNI is being disabled by "
+         "the OS.\n");
+    }
+  }
+
+  /* Disable cipher suites that ST supports but are not safe. These ciphers
+     are unlikely to be used in any case since ST gives other ciphers a much
+     higher priority, but it's probably better that we not connect at all than
+     to give the user a false sense of security if the server only supports
+     insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
+  (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
+  all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
+  allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
+  if(all_ciphers && allowed_ciphers &&
+     SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
+       &all_ciphers_count) == noErr) {
+    for(i = 0UL ; i < all_ciphers_count ; i++) {
+#if CURL_BUILD_MAC
+     /* There's a known bug in early versions of Mountain Lion where ST's ECC
+        ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
+        Work around the problem here by disabling those ciphers if we are
+        running in an affected version of OS X. */
+      if(darwinver_maj == 12 && darwinver_min <= 3 &&
+         all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
+           continue;
+      }
+#endif /* CURL_BUILD_MAC */
+      switch(all_ciphers[i]) {
+        /* Disable NULL ciphersuites: */
+        case SSL_NULL_WITH_NULL_NULL:
+        case SSL_RSA_WITH_NULL_MD5:
+        case SSL_RSA_WITH_NULL_SHA:
+        case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
+        case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
+        case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
+        case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
+        case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
+        case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
+        case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
+        case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
+        case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
+        case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
+        case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
+        case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
+        case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
+        case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
+        case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
+        /* Disable anonymous ciphersuites: */
+        case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
+        case SSL_DH_anon_WITH_RC4_128_MD5:
+        case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DH_anon_WITH_DES_CBC_SHA:
+        case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
+        case TLS_DH_anon_WITH_AES_128_CBC_SHA:
+        case TLS_DH_anon_WITH_AES_256_CBC_SHA:
+        case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
+        case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
+        case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
+        case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
+        case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
+        case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
+        case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
+        case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
+        case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
+        /* Disable weak key ciphersuites: */
+        case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
+        case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
+        case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_RSA_WITH_DES_CBC_SHA:
+        case SSL_DH_DSS_WITH_DES_CBC_SHA:
+        case SSL_DH_RSA_WITH_DES_CBC_SHA:
+        case SSL_DHE_DSS_WITH_DES_CBC_SHA:
+        case SSL_DHE_RSA_WITH_DES_CBC_SHA:
+        /* Disable IDEA: */
+        case SSL_RSA_WITH_IDEA_CBC_SHA:
+        case SSL_RSA_WITH_IDEA_CBC_MD5:
+          break;
+        default: /* enable everything else */
+          allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
+          break;
+      }
+    }
+    err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
+                               allowed_ciphers_count);
+    if(err != noErr) {
+      failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  else {
+    Curl_safefree(all_ciphers);
+    Curl_safefree(allowed_ciphers);
+    failf(data, "SSL: Failed to allocate memory for allowed ciphers");
+    return CURLE_OUT_OF_MEMORY;
+  }
+  Curl_safefree(all_ciphers);
+  Curl_safefree(allowed_ciphers);
+
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+  /* We want to enable 1/n-1 when using a CBC cipher unless the user
+     specifically doesn't want us doing that: */
+  if(SSLSetSessionOption != NULL) {
+    SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
+                      !data->set.ssl_enable_beast);
+    SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionFalseStart,
+                      data->set.ssl.falsestart); /* false start support */
+  }
+#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
+
+  /* Check if there's a cached ID we can/should use here! */
+  if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
+                            &ssl_sessionid_len)) {
+    /* we got a session id, use it! */
+    err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
+    if(err != noErr) {
+      failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    /* Informational message */
+    infof(data, "SSL re-using session ID\n");
+  }
+  /* If there isn't one, then let's make one up! This has to be done prior
+     to starting the handshake. */
+  else {
+    CURLcode result;
+    ssl_sessionid =
+      aprintf("%s:%d:%d:%s:%hu", data->set.str[STRING_SSL_CAFILE],
+              data->set.ssl.verifypeer, data->set.ssl.verifyhost,
+              conn->host.name, conn->remote_port);
+    ssl_sessionid_len = strlen(ssl_sessionid);
+
+    err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
+    if(err != noErr) {
+      failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
+    if(result) {
+      failf(data, "failed to store ssl session");
+      return result;
+    }
+  }
+
+  err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
+  if(err != noErr) {
+    failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  /* pass the raw socket into the SSL layers */
+  /* We need to store the FD in a constant memory address, because
+   * SSLSetConnection() will not copy that address. I've found that
+   * conn->sock[sockindex] may change on its own. */
+  connssl->ssl_sockfd = sockfd;
+  err = SSLSetConnection(connssl->ssl_ctx, connssl);
+  if(err != noErr) {
+    failf(data, "SSL: SSLSetConnection() failed: %d", err);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  connssl->connecting_state = ssl_connect_2;
+  return CURLE_OK;
+}
+
+static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
+{
+  char *sep_start, *sep_end, *cert_start, *cert_end;
+  size_t i, j, err;
+  size_t len;
+  unsigned char *b64;
+
+  /* Jump through the separators at the beginning of the certificate. */
+  sep_start = strstr(in, "-----");
+  if(sep_start == NULL)
+    return 0;
+  cert_start = strstr(sep_start + 1, "-----");
+  if(cert_start == NULL)
+    return -1;
+
+  cert_start += 5;
+
+  /* Find separator after the end of the certificate. */
+  cert_end = strstr(cert_start, "-----");
+  if(cert_end == NULL)
+    return -1;
+
+  sep_end = strstr(cert_end + 1, "-----");
+  if(sep_end == NULL)
+    return -1;
+  sep_end += 5;
+
+  len = cert_end - cert_start;
+  b64 = malloc(len + 1);
+  if(!b64)
+    return -1;
+
+  /* Create base64 string without linefeeds. */
+  for(i = 0, j = 0; i < len; i++) {
+    if(cert_start[i] != '\r' && cert_start[i] != '\n')
+      b64[j++] = cert_start[i];
+  }
+  b64[j] = '\0';
+
+  err = Curl_base64_decode((const char *)b64, out, outlen);
+  free(b64);
+  if(err) {
+    free(*out);
+    return -1;
+  }
+
+  return sep_end - in;
+}
+
+static int read_cert(const char *file, unsigned char **out, size_t *outlen)
+{
+  int fd;
+  ssize_t n, len = 0, cap = 512;
+  unsigned char buf[cap], *data;
+
+  fd = open(file, 0);
+  if(fd < 0)
+    return -1;
+
+  data = malloc(cap);
+  if(!data) {
+    close(fd);
+    return -1;
+  }
+
+  for(;;) {
+    n = read(fd, buf, sizeof(buf));
+    if(n < 0) {
+      close(fd);
+      free(data);
+      return -1;
+    }
+    else if(n == 0) {
+      close(fd);
+      break;
+    }
+
+    if(len + n >= cap) {
+      cap *= 2;
+      data = realloc(data, cap);
+      if(!data) {
+        close(fd);
+        return -1;
+      }
+    }
+
+    memcpy(data + len, buf, n);
+    len += n;
+  }
+  data[len] = '\0';
+
+  *out = data;
+  *outlen = len;
+
+  return 0;
+}
+
+static int sslerr_to_curlerr(struct SessionHandle *data, int err)
+{
+  switch(err) {
+    case errSSLXCertChainInvalid:
+      failf(data, "SSL certificate problem: Invalid certificate chain");
+      return CURLE_SSL_CACERT;
+    case errSSLUnknownRootCert:
+      failf(data, "SSL certificate problem: Untrusted root certificate");
+      return CURLE_SSL_CACERT;
+    case errSSLNoRootCert:
+      failf(data, "SSL certificate problem: No root certificate");
+      return CURLE_SSL_CACERT;
+    case errSSLCertExpired:
+      failf(data, "SSL certificate problem: Certificate chain had an "
+            "expired certificate");
+      return CURLE_SSL_CACERT;
+    case errSSLBadCert:
+      failf(data, "SSL certificate problem: Couldn't understand the server "
+            "certificate format");
+      return CURLE_SSL_CONNECT_ERROR;
+    case errSSLHostNameMismatch:
+      failf(data, "SSL certificate peer hostname mismatch");
+      return CURLE_PEER_FAILED_VERIFICATION;
+    default:
+      failf(data, "SSL unexpected certificate error %d", err);
+      return CURLE_SSL_CACERT;
+  }
+}
+
+static int append_cert_to_array(struct SessionHandle *data,
+                                unsigned char *buf, size_t buflen,
+                                CFMutableArrayRef array)
+{
+    CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
+    if(!certdata) {
+      failf(data, "SSL: failed to allocate array for CA certificate");
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    SecCertificateRef cacert =
+      SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
+    CFRelease(certdata);
+    if(!cacert) {
+      failf(data, "SSL: failed to create SecCertificate from CA certificate");
+      return CURLE_SSL_CACERT;
+    }
+
+    /* Check if cacert is valid. */
+    CFStringRef subject = CopyCertSubject(cacert);
+    if(subject) {
+      char subject_cbuf[128];
+      memset(subject_cbuf, 0, 128);
+      if(!CFStringGetCString(subject,
+                            subject_cbuf,
+                            128,
+                            kCFStringEncodingUTF8)) {
+        CFRelease(cacert);
+        failf(data, "SSL: invalid CA certificate subject");
+        return CURLE_SSL_CACERT;
+      }
+      CFRelease(subject);
+    }
+    else {
+      CFRelease(cacert);
+      failf(data, "SSL: invalid CA certificate");
+      return CURLE_SSL_CACERT;
+    }
+
+    CFArrayAppendValue(array, cacert);
+    CFRelease(cacert);
+
+    return CURLE_OK;
+}
+
+static int verify_cert(const char *cafile, struct SessionHandle *data,
+                       SSLContextRef ctx)
+{
+  int n = 0, rc;
+  long res;
+  unsigned char *certbuf, *der;
+  size_t buflen, derlen, offset = 0;
+
+  if(read_cert(cafile, &certbuf, &buflen) < 0) {
+    failf(data, "SSL: failed to read or invalid CA certificate");
+    return CURLE_SSL_CACERT;
+  }
+
+  /*
+   * Certbuf now contains the contents of the certificate file, which can be
+   * - a single DER certificate,
+   * - a single PEM certificate or
+   * - a bunch of PEM certificates (certificate bundle).
+   *
+   * Go through certbuf, and convert any PEM certificate in it into DER
+   * format.
+   */
+  CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
+                                                 &kCFTypeArrayCallBacks);
+  if(array == NULL) {
+    free(certbuf);
+    failf(data, "SSL: out of memory creating CA certificate array");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  while(offset < buflen) {
+    n++;
+
+    /*
+     * Check if the certificate is in PEM format, and convert it to DER. If
+     * this fails, we assume the certificate is in DER format.
+     */
+    res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
+    if(res < 0) {
+      free(certbuf);
+      CFRelease(array);
+      failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
+            n, offset);
+      return CURLE_SSL_CACERT;
+    }
+    offset += res;
+
+    if(res == 0 && offset == 0) {
+      /* This is not a PEM file, probably a certificate in DER format. */
+      rc = append_cert_to_array(data, certbuf, buflen, array);
+      free(certbuf);
+      if(rc != CURLE_OK) {
+        CFRelease(array);
+        return rc;
+      }
+      break;
+    }
+    else if(res == 0) {
+      /* No more certificates in the bundle. */
+      free(certbuf);
+      break;
+    }
+
+    rc = append_cert_to_array(data, der, derlen, array);
+    free(der);
+    if(rc != CURLE_OK) {
+      free(certbuf);
+      CFRelease(array);
+      return rc;
+    }
+  }
+
+  SecTrustRef trust;
+  OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
+  if(trust == NULL) {
+    failf(data, "SSL: error getting certificate chain");
+    CFRelease(array);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  else if(ret != noErr) {
+    CFRelease(array);
+    return sslerr_to_curlerr(data, ret);
+  }
+
+  ret = SecTrustSetAnchorCertificates(trust, array);
+  if(ret != noErr) {
+    CFRelease(trust);
+    return sslerr_to_curlerr(data, ret);
+  }
+  ret = SecTrustSetAnchorCertificatesOnly(trust, true);
+  if(ret != noErr) {
+    CFRelease(trust);
+    return sslerr_to_curlerr(data, ret);
+  }
+
+  SecTrustResultType trust_eval = 0;
+  ret = SecTrustEvaluate(trust, &trust_eval);
+  CFRelease(array);
+  CFRelease(trust);
+  if(ret != noErr) {
+    return sslerr_to_curlerr(data, ret);
+  }
+
+  switch (trust_eval) {
+    case kSecTrustResultUnspecified:
+    case kSecTrustResultProceed:
+      return CURLE_OK;
+
+    case kSecTrustResultRecoverableTrustFailure:
+    case kSecTrustResultDeny:
+    default:
+      failf(data, "SSL: certificate verification failed (result: %d)",
+            trust_eval);
+      return CURLE_PEER_FAILED_VERIFICATION;
+  }
+}
+
+static CURLcode
+darwinssl_connect_step2(struct connectdata *conn, int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  OSStatus err;
+  SSLCipherSuite cipher;
+  SSLProtocol protocol = 0;
+
+  DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
+              || ssl_connect_2_reading == connssl->connecting_state
+              || ssl_connect_2_writing == connssl->connecting_state);
+
+  /* Here goes nothing: */
+  err = SSLHandshake(connssl->ssl_ctx);
+
+  if(err != noErr) {
+    switch (err) {
+      case errSSLWouldBlock:  /* they're not done with us yet */
+        connssl->connecting_state = connssl->ssl_direction ?
+            ssl_connect_2_writing : ssl_connect_2_reading;
+        return CURLE_OK;
+
+      /* The below is errSSLServerAuthCompleted; it's not defined in
+        Leopard's headers */
+      case -9841:
+        if(data->set.str[STRING_SSL_CAFILE]) {
+          int res = verify_cert(data->set.str[STRING_SSL_CAFILE], data,
+                                connssl->ssl_ctx);
+          if(res != CURLE_OK)
+            return res;
+        }
+        /* the documentation says we need to call SSLHandshake() again */
+        return darwinssl_connect_step2(conn, sockindex);
+
+      /* These are all certificate problems with the server: */
+      case errSSLXCertChainInvalid:
+        failf(data, "SSL certificate problem: Invalid certificate chain");
+        return CURLE_SSL_CACERT;
+      case errSSLUnknownRootCert:
+        failf(data, "SSL certificate problem: Untrusted root certificate");
+        return CURLE_SSL_CACERT;
+      case errSSLNoRootCert:
+        failf(data, "SSL certificate problem: No root certificate");
+        return CURLE_SSL_CACERT;
+      case errSSLCertExpired:
+        failf(data, "SSL certificate problem: Certificate chain had an "
+              "expired certificate");
+        return CURLE_SSL_CACERT;
+      case errSSLBadCert:
+        failf(data, "SSL certificate problem: Couldn't understand the server "
+              "certificate format");
+        return CURLE_SSL_CONNECT_ERROR;
+
+      /* These are all certificate problems with the client: */
+      case errSecAuthFailed:
+        failf(data, "SSL authentication failed");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLPeerHandshakeFail:
+        failf(data, "SSL peer handshake failed, the server most likely "
+              "requires a client certificate to connect");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLPeerUnknownCA:
+        failf(data, "SSL server rejected the client certificate due to "
+              "the certificate being signed by an unknown certificate "
+              "authority");
+        return CURLE_SSL_CONNECT_ERROR;
+
+      /* This error is raised if the server's cert didn't match the server's
+         host name: */
+      case errSSLHostNameMismatch:
+        failf(data, "SSL certificate peer verification failed, the "
+              "certificate did not match \"%s\"\n", conn->host.dispname);
+        return CURLE_PEER_FAILED_VERIFICATION;
+
+      /* Generic handshake errors: */
+      case errSSLConnectionRefused:
+        failf(data, "Server dropped the connection during the SSL handshake");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLClosedAbort:
+        failf(data, "Server aborted the SSL handshake");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLNegotiation:
+        failf(data, "Could not negotiate an SSL cipher suite with the server");
+        return CURLE_SSL_CONNECT_ERROR;
+      /* Sometimes paramErr happens with buggy ciphers: */
+      case paramErr: case errSSLInternal:
+        failf(data, "Internal SSL engine error encountered during the "
+              "SSL handshake");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLFatalAlert:
+        failf(data, "Fatal SSL engine error encountered during the SSL "
+              "handshake");
+        return CURLE_SSL_CONNECT_ERROR;
+      default:
+        failf(data, "Unknown SSL protocol error in connection to %s:%d",
+              conn->host.name, err);
+        return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  else {
+    /* we have been connected fine, we're not waiting for anything else. */
+    connssl->connecting_state = ssl_connect_3;
+
+    /* Informational message */
+    (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
+    (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
+    switch (protocol) {
+      case kSSLProtocol2:
+        infof(data, "SSL 2.0 connection using %s\n",
+              SSLCipherNameForNumber(cipher));
+        break;
+      case kSSLProtocol3:
+        infof(data, "SSL 3.0 connection using %s\n",
+              SSLCipherNameForNumber(cipher));
+        break;
+      case kTLSProtocol1:
+        infof(data, "TLS 1.0 connection using %s\n",
+              TLSCipherNameForNumber(cipher));
+        break;
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+      case kTLSProtocol11:
+        infof(data, "TLS 1.1 connection using %s\n",
+              TLSCipherNameForNumber(cipher));
+        break;
+      case kTLSProtocol12:
+        infof(data, "TLS 1.2 connection using %s\n",
+              TLSCipherNameForNumber(cipher));
+        break;
+#endif
+      default:
+        infof(data, "Unknown protocol connection\n");
+        break;
+    }
+
+    return CURLE_OK;
+  }
+}
+
+static CURLcode
+darwinssl_connect_step3(struct connectdata *conn,
+                        int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  CFStringRef server_cert_summary;
+  char server_cert_summary_c[128];
+  CFArrayRef server_certs = NULL;
+  SecCertificateRef server_cert;
+  OSStatus err;
+  CFIndex i, count;
+  SecTrustRef trust = NULL;
+
+  /* There is no step 3!
+   * Well, okay, if verbose mode is on, let's print the details of the
+   * server certificates. */
+#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
+#if CURL_BUILD_IOS
+#pragma unused(server_certs)
+  err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
+  /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
+     a null trust, so be on guard for that: */
+  if(err == noErr && trust) {
+    count = SecTrustGetCertificateCount(trust);
+    for(i = 0L ; i < count ; i++) {
+      server_cert = SecTrustGetCertificateAtIndex(trust, i);
+      server_cert_summary = CopyCertSubject(server_cert);
+      memset(server_cert_summary_c, 0, 128);
+      if(CFStringGetCString(server_cert_summary,
+                            server_cert_summary_c,
+                            128,
+                            kCFStringEncodingUTF8)) {
+        infof(data, "Server certificate: %s\n", server_cert_summary_c);
+      }
+      CFRelease(server_cert_summary);
+    }
+    CFRelease(trust);
+  }
+#else
+  /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
+     The function SecTrustGetCertificateAtIndex() is officially present
+     in Lion, but it is unfortunately also present in Snow Leopard as
+     private API and doesn't work as expected. So we have to look for
+     a different symbol to make sure this code is only executed under
+     Lion or later. */
+  if(SecTrustEvaluateAsync != NULL) {
+#pragma unused(server_certs)
+    err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
+    /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
+       a null trust, so be on guard for that: */
+    if(err == noErr && trust) {
+      count = SecTrustGetCertificateCount(trust);
+      for(i = 0L ; i < count ; i++) {
+        server_cert = SecTrustGetCertificateAtIndex(trust, i);
+        server_cert_summary = CopyCertSubject(server_cert);
+        memset(server_cert_summary_c, 0, 128);
+        if(CFStringGetCString(server_cert_summary,
+                              server_cert_summary_c,
+                              128,
+                              kCFStringEncodingUTF8)) {
+          infof(data, "Server certificate: %s\n", server_cert_summary_c);
+        }
+        CFRelease(server_cert_summary);
+      }
+      CFRelease(trust);
+    }
+  }
+  else {
+#if CURL_SUPPORT_MAC_10_8
+    err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
+    /* Just in case SSLCopyPeerCertificates() returns null too... */
+    if(err == noErr && server_certs) {
+      count = CFArrayGetCount(server_certs);
+      for(i = 0L ; i < count ; i++) {
+        server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
+                                                                i);
+
+        server_cert_summary = CopyCertSubject(server_cert);
+        memset(server_cert_summary_c, 0, 128);
+        if(CFStringGetCString(server_cert_summary,
+                              server_cert_summary_c,
+                              128,
+                              kCFStringEncodingUTF8)) {
+          infof(data, "Server certificate: %s\n", server_cert_summary_c);
+        }
+        CFRelease(server_cert_summary);
+      }
+      CFRelease(server_certs);
+    }
+#endif /* CURL_SUPPORT_MAC_10_8 */
+  }
+#endif /* CURL_BUILD_IOS */
+#else
+#pragma unused(trust)
+  err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
+  if(err == noErr) {
+    count = CFArrayGetCount(server_certs);
+    for(i = 0L ; i < count ; i++) {
+      server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
+      server_cert_summary = CopyCertSubject(server_cert);
+      memset(server_cert_summary_c, 0, 128);
+      if(CFStringGetCString(server_cert_summary,
+                            server_cert_summary_c,
+                            128,
+                            kCFStringEncodingUTF8)) {
+        infof(data, "Server certificate: %s\n", server_cert_summary_c);
+      }
+      CFRelease(server_cert_summary);
+    }
+    CFRelease(server_certs);
+  }
+#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
+
+  connssl->connecting_state = ssl_connect_done;
+  return CURLE_OK;
+}
+
+static Curl_recv darwinssl_recv;
+static Curl_send darwinssl_send;
+
+static CURLcode
+darwinssl_connect_common(struct connectdata *conn,
+                         int sockindex,
+                         bool nonblocking,
+                         bool *done)
+{
+  CURLcode result;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  long timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1==connssl->connecting_state) {
+    /* Find out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    result = darwinssl_connect_step1(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading ||
+       connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing ==
+      connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading ==
+      connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if this
+     * connection is done nonblocking and this loop would execute again. This
+     * permits the owner of a multi handle to abort a connection attempt
+     * before step2 has completed while ensuring that a client using select()
+     * or epoll() will always have a valid fdset to wait on.
+     */
+    result = darwinssl_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
+
+  } /* repeat step2 until all transactions are done. */
+
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = darwinssl_connect_step3(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = darwinssl_recv;
+    conn->send[sockindex] = darwinssl_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* Reset our connect state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+CURLcode
+Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
+                                   int sockindex,
+                                   bool *done)
+{
+  return darwinssl_connect_common(conn, sockindex, TRUE, done);
+}
+
+CURLcode
+Curl_darwinssl_connect(struct connectdata *conn,
+                       int sockindex)
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = darwinssl_connect_common(conn, sockindex, FALSE, &done);
+
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  if(connssl->ssl_ctx) {
+    (void)SSLClose(connssl->ssl_ctx);
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+    if(SSLCreateContext != NULL)
+      CFRelease(connssl->ssl_ctx);
+#if CURL_SUPPORT_MAC_10_8
+    else
+      (void)SSLDisposeContext(connssl->ssl_ctx);
+#endif  /* CURL_SUPPORT_MAC_10_8 */
+#else
+    (void)SSLDisposeContext(connssl->ssl_ctx);
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+    connssl->ssl_ctx = NULL;
+  }
+  connssl->ssl_sockfd = 0;
+}
+
+int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct SessionHandle *data = conn->data;
+  ssize_t nread;
+  int what;
+  int rc;
+  char buf[120];
+
+  if(!connssl->ssl_ctx)
+    return 0;
+
+  if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
+    return 0;
+
+  Curl_darwinssl_close(conn, sockindex);
+
+  rc = 0;
+
+  what = Curl_socket_ready(conn->sock[sockindex],
+                           CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+
+  for(;;) {
+    if(what < 0) {
+      /* anything that gets here is fatally bad */
+      failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+      rc = -1;
+      break;
+    }
+
+    if(!what) {                                /* timeout */
+      failf(data, "SSL shutdown timeout");
+      break;
+    }
+
+    /* Something to read, let's do it and hope that it is the close
+     notify alert from the server. No way to SSL_Read now, so use read(). */
+
+    nread = read(conn->sock[sockindex], buf, sizeof(buf));
+
+    if(nread < 0) {
+      failf(data, "read: %s", strerror(errno));
+      rc = -1;
+    }
+
+    if(nread <= 0)
+      break;
+
+    what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
+  }
+
+  return rc;
+}
+
+void Curl_darwinssl_session_free(void *ptr)
+{
+  /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
+     cached session ID inside the Security framework. There is a private
+     function that does this, but I don't want to have to explain to you why I
+     got your application rejected from the App Store due to the use of a
+     private API, so the best we can do is free up our own char array that we
+     created way back in darwinssl_connect_step1... */
+  Curl_safefree(ptr);
+}
+
+size_t Curl_darwinssl_version(char *buffer, size_t size)
+{
+  return snprintf(buffer, size, "SecureTransport");
+}
+
+/*
+ * This function uses SSLGetSessionState to determine connection status.
+ *
+ * Return codes:
+ *     1 means the connection is still in place
+ *     0 means the connection has been closed
+ *    -1 means the connection status is unknown
+ */
+int Curl_darwinssl_check_cxn(struct connectdata *conn)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+  OSStatus err;
+  SSLSessionState state;
+
+  if(connssl->ssl_ctx) {
+    err = SSLGetSessionState(connssl->ssl_ctx, &state);
+    if(err == noErr)
+      return state == kSSLConnected || state == kSSLHandshake;
+    return -1;
+  }
+  return 0;
+}
+
+bool Curl_darwinssl_data_pending(const struct connectdata *conn,
+                                 int connindex)
+{
+  const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+  OSStatus err;
+  size_t buffer;
+
+  if(connssl->ssl_ctx) {  /* SSL is in use */
+    err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
+    if(err == noErr)
+      return buffer > 0UL;
+    return false;
+  }
+  else
+    return false;
+}
+
+int Curl_darwinssl_random(unsigned char *entropy,
+                          size_t length)
+{
+  /* arc4random_buf() isn't available on cats older than Lion, so let's
+     do this manually for the benefit of the older cats. */
+  size_t i;
+  u_int32_t random_number = 0;
+
+  for(i = 0 ; i < length ; i++) {
+    if(i % sizeof(u_int32_t) == 0)
+      random_number = arc4random();
+    entropy[i] = random_number & 0xFF;
+    random_number >>= 8;
+  }
+  i = random_number = 0;
+  return 0;
+}
+
+void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
+                           size_t tmplen,
+                           unsigned char *md5sum, /* output */
+                           size_t md5len)
+{
+  (void)md5len;
+  (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
+}
+
+bool Curl_darwinssl_false_start(void) {
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+  if(SSLSetSessionOption != NULL)
+    return TRUE;
+#endif
+  return FALSE;
+}
+
+static ssize_t darwinssl_send(struct connectdata *conn,
+                              int sockindex,
+                              const void *mem,
+                              size_t len,
+                              CURLcode *curlcode)
+{
+  /*struct SessionHandle *data = conn->data;*/
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  size_t processed = 0UL;
+  OSStatus err;
+
+  /* The SSLWrite() function works a little differently than expected. The
+     fourth argument (processed) is currently documented in Apple's
+     documentation as: "On return, the length, in bytes, of the data actually
+     written."
+
+     Now, one could interpret that as "written to the socket," but actually,
+     it returns the amount of data that was written to a buffer internal to
+     the SSLContextRef instead. So it's possible for SSLWrite() to return
+     errSSLWouldBlock and a number of bytes "written" because those bytes were
+     encrypted and written to a buffer, not to the socket.
+
+     So if this happens, then we need to keep calling SSLWrite() over and
+     over again with no new data until it quits returning errSSLWouldBlock. */
+
+  /* Do we have buffered data to write from the last time we were called? */
+  if(connssl->ssl_write_buffered_length) {
+    /* Write the buffered data: */
+    err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
+    switch (err) {
+      case noErr:
+        /* processed is always going to be 0 because we didn't write to
+           the buffer, so return how much was written to the socket */
+        processed = connssl->ssl_write_buffered_length;
+        connssl->ssl_write_buffered_length = 0UL;
+        break;
+      case errSSLWouldBlock: /* argh, try again */
+        *curlcode = CURLE_AGAIN;
+        return -1L;
+      default:
+        failf(conn->data, "SSLWrite() returned error %d", err);
+        *curlcode = CURLE_SEND_ERROR;
+        return -1L;
+    }
+  }
+  else {
+    /* We've got new data to write: */
+    err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
+    if(err != noErr) {
+      switch (err) {
+        case errSSLWouldBlock:
+          /* Data was buffered but not sent, we have to tell the caller
+             to try sending again, and remember how much was buffered */
+          connssl->ssl_write_buffered_length = len;
+          *curlcode = CURLE_AGAIN;
+          return -1L;
+        default:
+          failf(conn->data, "SSLWrite() returned error %d", err);
+          *curlcode = CURLE_SEND_ERROR;
+          return -1L;
+      }
+    }
+  }
+  return (ssize_t)processed;
+}
+
+static ssize_t darwinssl_recv(struct connectdata *conn,
+                              int num,
+                              char *buf,
+                              size_t buffersize,
+                              CURLcode *curlcode)
+{
+  /*struct SessionHandle *data = conn->data;*/
+  struct ssl_connect_data *connssl = &conn->ssl[num];
+  size_t processed = 0UL;
+  OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
+
+  if(err != noErr) {
+    switch (err) {
+      case errSSLWouldBlock:  /* return how much we read (if anything) */
+        if(processed)
+          return (ssize_t)processed;
+        *curlcode = CURLE_AGAIN;
+        return -1L;
+        break;
+
+      /* errSSLClosedGraceful - server gracefully shut down the SSL session
+         errSSLClosedNoNotify - server hung up on us instead of sending a
+           closure alert notice, read() is returning 0
+         Either way, inform the caller that the server disconnected. */
+      case errSSLClosedGraceful:
+      case errSSLClosedNoNotify:
+        *curlcode = CURLE_OK;
+        return -1L;
+        break;
+
+      default:
+        failf(conn->data, "SSLRead() return error %d", err);
+        *curlcode = CURLE_RECV_ERROR;
+        return -1L;
+        break;
+    }
+  }
+  return (ssize_t)processed;
+}
+
+#endif /* USE_DARWINSSL */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/darwinssl.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/darwinssl.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/darwinssl.h	(revision 164)
@@ -0,0 +1,76 @@
+#ifndef HEADER_CURL_DARWINSSL_H
+#define HEADER_CURL_DARWINSSL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_DARWINSSL
+
+CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex);
+
+CURLcode Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
+                                            int sockindex,
+                                            bool *done);
+
+/* close a SSL connection */
+void Curl_darwinssl_close(struct connectdata *conn, int sockindex);
+
+void Curl_darwinssl_session_free(void *ptr);
+size_t Curl_darwinssl_version(char *buffer, size_t size);
+int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex);
+int Curl_darwinssl_check_cxn(struct connectdata *conn);
+bool Curl_darwinssl_data_pending(const struct connectdata *conn,
+                                 int connindex);
+
+int Curl_darwinssl_random(unsigned char *entropy,
+                          size_t length);
+void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
+                           size_t tmplen,
+                           unsigned char *md5sum, /* output */
+                           size_t md5len);
+bool Curl_darwinssl_false_start(void);
+
+/* Set the API backend definition to SecureTransport */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_DARWINSSL
+
+/* API setup for SecureTransport */
+#define curlssl_init() (1)
+#define curlssl_cleanup() Curl_nop_stmt
+#define curlssl_connect Curl_darwinssl_connect
+#define curlssl_connect_nonblocking Curl_darwinssl_connect_nonblocking
+#define curlssl_session_free(x) Curl_darwinssl_session_free(x)
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_darwinssl_close
+#define curlssl_shutdown(x,y) 0
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_darwinssl_version
+#define curlssl_check_cxn Curl_darwinssl_check_cxn
+#define curlssl_data_pending(x,y) Curl_darwinssl_data_pending(x, y)
+#define curlssl_random(x,y,z) ((void)x, Curl_darwinssl_random(y,z))
+#define curlssl_md5sum(a,b,c,d) Curl_darwinssl_md5sum(a,b,c,d)
+#define curlssl_false_start() Curl_darwinssl_false_start()
+
+#endif /* USE_DARWINSSL */
+#endif /* HEADER_CURL_DARWINSSL_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/gskit.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/gskit.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/gskit.c	(revision 164)
@@ -0,0 +1,1069 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_GSKIT
+
+#include <gskssl.h>
+#include <qsoasync.h>
+
+/* Some symbols are undefined/unsupported on OS400 versions < V7R1. */
+#ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST
+#define GSK_SSL_EXTN_SERVERNAME_REQUEST         230
+#endif
+
+#ifndef GSK_TLSV10_CIPHER_SPECS
+#define GSK_TLSV10_CIPHER_SPECS                 236
+#endif
+
+#ifndef GSK_TLSV11_CIPHER_SPECS
+#define GSK_TLSV11_CIPHER_SPECS                 237
+#endif
+
+#ifndef GSK_TLSV12_CIPHER_SPECS
+#define GSK_TLSV12_CIPHER_SPECS                 238
+#endif
+
+#ifndef GSK_PROTOCOL_TLSV11
+#define GSK_PROTOCOL_TLSV11                     437
+#endif
+
+#ifndef GSK_PROTOCOL_TLSV12
+#define GSK_PROTOCOL_TLSV12                     438
+#endif
+
+#ifndef GSK_FALSE
+#define GSK_FALSE                               0
+#endif
+
+#ifndef GSK_TRUE
+#define GSK_TRUE                                1
+#endif
+
+
+#ifdef HAVE_LIMITS_H
+#  include <limits.h>
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "gskit.h"
+#include "vtls.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "strequal.h"
+#include "x509asn1.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+
+/* SSL version flags. */
+#define CURL_GSKPROTO_SSLV2     0
+#define CURL_GSKPROTO_SSLV2_MASK        (1 << CURL_GSKPROTO_SSLV2)
+#define CURL_GSKPROTO_SSLV3     1
+#define CURL_GSKPROTO_SSLV3_MASK        (1 << CURL_GSKPROTO_SSLV3)
+#define CURL_GSKPROTO_TLSV10    2
+#define CURL_GSKPROTO_TLSV10_MASK        (1 << CURL_GSKPROTO_TLSV10)
+#define CURL_GSKPROTO_TLSV11    3
+#define CURL_GSKPROTO_TLSV11_MASK        (1 << CURL_GSKPROTO_TLSV11)
+#define CURL_GSKPROTO_TLSV12    4
+#define CURL_GSKPROTO_TLSV12_MASK        (1 << CURL_GSKPROTO_TLSV12)
+#define CURL_GSKPROTO_LAST      5
+
+
+/* Supported ciphers. */
+typedef struct {
+  const char *name;            /* Cipher name. */
+  const char *gsktoken;        /* Corresponding token for GSKit String. */
+  unsigned int versions;       /* SSL version flags. */
+}  gskit_cipher;
+
+static const gskit_cipher  ciphertable[] = {
+  { "null-md5",         "01",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+      CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+  { "null-sha",         "02",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+      CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+  { "exp-rc4-md5",      "03",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
+  { "rc4-md5",          "04",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+      CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+  { "rc4-sha",          "05",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+      CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+  { "exp-rc2-cbc-md5",  "06",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
+  { "exp-des-cbc-sha",  "09",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+      CURL_GSKPROTO_TLSV11_MASK },
+  { "des-cbc3-sha",     "0A",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+      CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+  { "aes128-sha",       "2F",
+      CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
+      CURL_GSKPROTO_TLSV12_MASK },
+  { "aes256-sha",       "35",
+      CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
+      CURL_GSKPROTO_TLSV12_MASK },
+  { "null-sha256",      "3B",   CURL_GSKPROTO_TLSV12_MASK },
+  { "aes128-sha256",    "3C",   CURL_GSKPROTO_TLSV12_MASK },
+  { "aes256-sha256",    "3D",   CURL_GSKPROTO_TLSV12_MASK },
+  { "aes128-gcm-sha256",
+                        "9C",   CURL_GSKPROTO_TLSV12_MASK },
+  { "aes256-gcm-sha384",
+                        "9D",   CURL_GSKPROTO_TLSV12_MASK },
+  { "rc4-md5",          "1",    CURL_GSKPROTO_SSLV2_MASK },
+  { "exp-rc4-md5",      "2",    CURL_GSKPROTO_SSLV2_MASK },
+  { "rc2-md5",          "3",    CURL_GSKPROTO_SSLV2_MASK },
+  { "exp-rc2-md5",      "4",    CURL_GSKPROTO_SSLV2_MASK },
+  { "des-cbc-md5",      "6",    CURL_GSKPROTO_SSLV2_MASK },
+  { "des-cbc3-md5",     "7",    CURL_GSKPROTO_SSLV2_MASK },
+  { (const char *) NULL, (const char *) NULL, 0       }
+};
+
+
+static bool is_separator(char c)
+{
+  /* Return whether character is a cipher list separator. */
+  switch (c) {
+  case ' ':
+  case '\t':
+  case ':':
+  case ',':
+  case ';':
+    return true;
+  }
+  return false;
+}
+
+
+static CURLcode gskit_status(struct SessionHandle *data, int rc,
+                             const char *procname, CURLcode defcode)
+{
+  /* Process GSKit status and map it to a CURLcode. */
+  switch (rc) {
+  case GSK_OK:
+  case GSK_OS400_ASYNCHRONOUS_SOC_INIT:
+    return CURLE_OK;
+  case GSK_KEYRING_OPEN_ERROR:
+  case GSK_OS400_ERROR_NO_ACCESS:
+    return CURLE_SSL_CACERT_BADFILE;
+  case GSK_INSUFFICIENT_STORAGE:
+    return CURLE_OUT_OF_MEMORY;
+  case GSK_ERROR_BAD_V2_CIPHER:
+  case GSK_ERROR_BAD_V3_CIPHER:
+  case GSK_ERROR_NO_CIPHERS:
+    return CURLE_SSL_CIPHER;
+  case GSK_OS400_ERROR_NOT_TRUSTED_ROOT:
+  case GSK_ERROR_CERT_VALIDATION:
+    return CURLE_PEER_FAILED_VERIFICATION;
+  case GSK_OS400_ERROR_TIMED_OUT:
+    return CURLE_OPERATION_TIMEDOUT;
+  case GSK_WOULD_BLOCK:
+    return CURLE_AGAIN;
+  case GSK_OS400_ERROR_NOT_REGISTERED:
+    break;
+  case GSK_ERROR_IO:
+    switch (errno) {
+    case ENOMEM:
+      return CURLE_OUT_OF_MEMORY;
+    default:
+      failf(data, "%s I/O error: %s", procname, strerror(errno));
+      break;
+    }
+    break;
+  default:
+    failf(data, "%s: %s", procname, gsk_strerror(rc));
+    break;
+  }
+  return defcode;
+}
+
+
+static CURLcode set_enum(struct SessionHandle *data, gsk_handle h,
+                GSK_ENUM_ID id, GSK_ENUM_VALUE value, bool unsupported_ok)
+{
+  int rc = gsk_attribute_set_enum(h, id, value);
+
+  switch (rc) {
+  case GSK_OK:
+    return CURLE_OK;
+  case GSK_ERROR_IO:
+    failf(data, "gsk_attribute_set_enum() I/O error: %s", strerror(errno));
+    break;
+  case GSK_ATTRIBUTE_INVALID_ID:
+    if(unsupported_ok)
+      return CURLE_UNSUPPORTED_PROTOCOL;
+  default:
+    failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc));
+    break;
+  }
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+
+static CURLcode set_buffer(struct SessionHandle *data, gsk_handle h,
+                        GSK_BUF_ID id, const char *buffer, bool unsupported_ok)
+{
+  int rc = gsk_attribute_set_buffer(h, id, buffer, 0);
+
+  switch (rc) {
+  case GSK_OK:
+    return CURLE_OK;
+  case GSK_ERROR_IO:
+    failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
+    break;
+  case GSK_ATTRIBUTE_INVALID_ID:
+    if(unsupported_ok)
+      return CURLE_UNSUPPORTED_PROTOCOL;
+  default:
+    failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
+    break;
+  }
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+
+static CURLcode set_numeric(struct SessionHandle *data,
+                            gsk_handle h, GSK_NUM_ID id, int value)
+{
+  int rc = gsk_attribute_set_numeric_value(h, id, value);
+
+  switch (rc) {
+  case GSK_OK:
+    return CURLE_OK;
+  case GSK_ERROR_IO:
+    failf(data, "gsk_attribute_set_numeric_value() I/O error: %s",
+          strerror(errno));
+    break;
+  default:
+    failf(data, "gsk_attribute_set_numeric_value(): %s", gsk_strerror(rc));
+    break;
+  }
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+
+static CURLcode set_callback(struct SessionHandle *data,
+                             gsk_handle h, GSK_CALLBACK_ID id, void *info)
+{
+  int rc = gsk_attribute_set_callback(h, id, info);
+
+  switch (rc) {
+  case GSK_OK:
+    return CURLE_OK;
+  case GSK_ERROR_IO:
+    failf(data, "gsk_attribute_set_callback() I/O error: %s", strerror(errno));
+    break;
+  default:
+    failf(data, "gsk_attribute_set_callback(): %s", gsk_strerror(rc));
+    break;
+  }
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+
+static CURLcode set_ciphers(struct SessionHandle *data,
+                                        gsk_handle h, unsigned int *protoflags)
+{
+  const char *cipherlist = data->set.str[STRING_SSL_CIPHER_LIST];
+  const char *clp;
+  const gskit_cipher *ctp;
+  int i;
+  int l;
+  bool unsupported;
+  CURLcode result;
+  struct {
+    char *buf;
+    char *ptr;
+  } ciphers[CURL_GSKPROTO_LAST];
+
+  /* Compile cipher list into GSKit-compatible cipher lists. */
+
+  if(!cipherlist)
+    return CURLE_OK;
+  while(is_separator(*cipherlist))     /* Skip initial separators. */
+    cipherlist++;
+  if(!*cipherlist)
+    return CURLE_OK;
+
+  /* We allocate GSKit buffers of the same size as the input string: since
+     GSKit tokens are always shorter than their cipher names, allocated buffers
+     will always be large enough to accomodate the result. */
+  l = strlen(cipherlist) + 1;
+  memset((char *) ciphers, 0, sizeof ciphers);
+  for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
+    ciphers[i].buf = malloc(l);
+    if(!ciphers[i].buf) {
+      while(i--)
+        free(ciphers[i].buf);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    ciphers[i].ptr = ciphers[i].buf;
+    *ciphers[i].ptr = '\0';
+  }
+
+  /* Process each cipher in input string. */
+  unsupported = FALSE;
+  result = CURLE_OK;
+  for(;;) {
+    for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
+      cipherlist++;
+    l = cipherlist - clp;
+    if(!l)
+      break;
+    /* Search the cipher in our table. */
+    for(ctp = ciphertable; ctp->name; ctp++)
+      if(strnequal(ctp->name, clp, l) && !ctp->name[l])
+        break;
+    if(!ctp->name) {
+      failf(data, "Unknown cipher %.*s", l, clp);
+      result = CURLE_SSL_CIPHER;
+    }
+    else {
+      unsupported |= !(ctp->versions & (CURL_GSKPROTO_SSLV2_MASK |
+                        CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK));
+      for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
+        if(ctp->versions & (1 << i)) {
+          strcpy(ciphers[i].ptr, ctp->gsktoken);
+          ciphers[i].ptr += strlen(ctp->gsktoken);
+        }
+      }
+    }
+
+   /* Advance to next cipher name or end of string. */
+    while(is_separator(*cipherlist))
+      cipherlist++;
+  }
+
+  /* Disable protocols with empty cipher lists. */
+  for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
+    if(!(*protoflags & (1 << i)) || !ciphers[i].buf[0]) {
+      *protoflags &= ~(1 << i);
+      ciphers[i].buf[0] = '\0';
+    }
+  }
+
+  /* Try to set-up TLSv1.1 and TLSv2.1 ciphers. */
+  if(*protoflags & CURL_GSKPROTO_TLSV11_MASK) {
+    result = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
+      if(unsupported) {
+        failf(data, "TLSv1.1-only ciphers are not yet supported");
+        result = CURLE_SSL_CIPHER;
+      }
+    }
+  }
+  if(!result && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) {
+    result = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
+      if(unsupported) {
+        failf(data, "TLSv1.2-only ciphers are not yet supported");
+        result = CURLE_SSL_CIPHER;
+      }
+    }
+  }
+
+  /* Try to set-up TLSv1.0 ciphers. If not successful, concatenate them to
+     the SSLv3 ciphers. OS/400 prior to version 7.1 will understand it. */
+  if(!result && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) {
+    result = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
+      strcpy(ciphers[CURL_GSKPROTO_SSLV3].ptr,
+             ciphers[CURL_GSKPROTO_TLSV10].ptr);
+    }
+  }
+
+  /* Set-up other ciphers. */
+  if(!result && (*protoflags & CURL_GSKPROTO_SSLV3_MASK))
+    result = set_buffer(data, h, GSK_V3_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_SSLV3].buf, FALSE);
+  if(!result && (*protoflags & CURL_GSKPROTO_SSLV2_MASK))
+    result = set_buffer(data, h, GSK_V2_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_SSLV2].buf, FALSE);
+
+  /* Clean-up. */
+  for(i = 0; i < CURL_GSKPROTO_LAST; i++)
+    free(ciphers[i].buf);
+
+  return result;
+}
+
+
+int Curl_gskit_init(void)
+{
+  /* No initialisation needed. */
+
+  return 1;
+}
+
+
+void Curl_gskit_cleanup(void)
+{
+  /* Nothing to do. */
+}
+
+
+static CURLcode init_environment(struct SessionHandle *data,
+                                 gsk_handle *envir, const char *appid,
+                                 const char *file, const char *label,
+                                 const char *password)
+{
+  int rc;
+  CURLcode result;
+  gsk_handle h;
+
+  /* Creates the GSKit environment. */
+
+  rc = gsk_environment_open(&h);
+  switch (rc) {
+  case GSK_OK:
+    break;
+  case GSK_INSUFFICIENT_STORAGE:
+    return CURLE_OUT_OF_MEMORY;
+  default:
+    failf(data, "gsk_environment_open(): %s", gsk_strerror(rc));
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  result = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION, FALSE);
+  if(!result && appid)
+    result = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid, FALSE);
+  if(!result && file)
+    result = set_buffer(data, h, GSK_KEYRING_FILE, file, FALSE);
+  if(!result && label)
+    result = set_buffer(data, h, GSK_KEYRING_LABEL, label, FALSE);
+  if(!result && password)
+    result = set_buffer(data, h, GSK_KEYRING_PW, password, FALSE);
+
+  if(!result) {
+    /* Locate CAs, Client certificate and key according to our settings.
+       Note: this call may be blocking for some tenths of seconds. */
+    result = gskit_status(data, gsk_environment_init(h),
+                          "gsk_environment_init()", CURLE_SSL_CERTPROBLEM);
+    if(!result) {
+      *envir = h;
+      return result;
+    }
+  }
+  /* Error: rollback. */
+  gsk_environment_close(&h);
+  return result;
+}
+
+
+static void cancel_async_handshake(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  Qso_OverlappedIO_t cstat;
+
+  if(QsoCancelOperation(conn->sock[sockindex], 0) > 0)
+    QsoWaitForIOCompletion(connssl->iocport, &cstat, (struct timeval *) NULL);
+}
+
+
+static void close_async_handshake(struct ssl_connect_data *connssl)
+{
+  QsoDestroyIOCompletionPort(connssl->iocport);
+  connssl->iocport = -1;
+}
+
+
+static void close_one(struct ssl_connect_data *conn,
+                      struct SessionHandle *data)
+{
+  if(conn->handle) {
+    gskit_status(data, gsk_secure_soc_close(&conn->handle),
+              "gsk_secure_soc_close()", 0);
+    conn->handle = (gsk_handle) NULL;
+  }
+  if(conn->iocport >= 0)
+    close_async_handshake(conn);
+}
+
+
+static ssize_t gskit_send(struct connectdata *conn, int sockindex,
+                           const void *mem, size_t len, CURLcode *curlcode)
+{
+  struct SessionHandle *data = conn->data;
+  CURLcode cc;
+  int written;
+
+  cc = gskit_status(data,
+                    gsk_secure_soc_write(conn->ssl[sockindex].handle,
+                                         (char *) mem, (int) len, &written),
+                    "gsk_secure_soc_write()", CURLE_SEND_ERROR);
+  if(cc != CURLE_OK) {
+    *curlcode = cc;
+    written = -1;
+  }
+  return (ssize_t) written; /* number of bytes */
+}
+
+
+static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
+                           size_t buffersize, CURLcode *curlcode)
+{
+  struct SessionHandle *data = conn->data;
+  int buffsize;
+  int nread;
+  CURLcode cc;
+
+  buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
+  cc = gskit_status(data, gsk_secure_soc_read(conn->ssl[num].handle,
+                                              buf, buffsize, &nread),
+                    "gsk_secure_soc_read()", CURLE_RECV_ERROR);
+  if(cc != CURLE_OK) {
+    *curlcode = cc;
+    nread = -1;
+  }
+  return (ssize_t) nread;
+}
+
+
+static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  gsk_handle envir;
+  CURLcode result;
+  int rc;
+  char *keyringfile;
+  char *keyringpwd;
+  char *keyringlabel;
+  char *sni;
+  unsigned int protoflags;
+  long timeout;
+  Qso_OverlappedIO_t commarea;
+
+  /* Create SSL environment, start (preferably asynchronous) handshake. */
+
+  connssl->handle = (gsk_handle) NULL;
+  connssl->iocport = -1;
+
+  /* GSKit supports two ways of specifying an SSL context: either by
+   *  application identifier (that should have been defined at the system
+   *  level) or by keyring file, password and certificate label.
+   * Local certificate name (CURLOPT_SSLCERT) is used to hold either the
+   *  application identifier of the certificate label.
+   * Key password (CURLOPT_KEYPASSWD) holds the keyring password.
+   * It is not possible to have different keyrings for the CAs and the
+   *  local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify
+   *  the keyring file.
+   * If no key password is given and the keyring is the system keyring,
+   *  application identifier mode is tried first, as recommended in IBM doc.
+   */
+
+  keyringfile = data->set.str[STRING_SSL_CAFILE];
+  keyringpwd = data->set.str[STRING_KEY_PASSWD];
+  keyringlabel = data->set.str[STRING_CERT];
+  envir = (gsk_handle) NULL;
+
+  if(keyringlabel && *keyringlabel && !keyringpwd &&
+      !strcmp(keyringfile, CURL_CA_BUNDLE)) {
+    /* Try application identifier mode. */
+    init_environment(data, &envir, keyringlabel, (const char *) NULL,
+                     (const char *) NULL, (const char *) NULL);
+  }
+
+  if(!envir) {
+    /* Use keyring mode. */
+    result = init_environment(data, &envir, (const char *) NULL,
+                              keyringfile, keyringlabel, keyringpwd);
+    if(result)
+      return result;
+  }
+
+  /* Create secure session. */
+  result = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle),
+                        "gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
+  gsk_environment_close(&envir);
+  if(result)
+    return result;
+
+  /* Determine which SSL/TLS version should be enabled. */
+  protoflags = CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
+               CURL_GSKPROTO_TLSV12_MASK;
+  sni = conn->host.name;
+  switch (data->set.ssl.version) {
+  case CURL_SSLVERSION_SSLv2:
+    protoflags = CURL_GSKPROTO_SSLV2_MASK;
+    sni = (char *) NULL;
+    break;
+  case CURL_SSLVERSION_SSLv3:
+    protoflags = CURL_GSKPROTO_SSLV3_MASK;
+    sni = (char *) NULL;
+    break;
+  case CURL_SSLVERSION_TLSv1:
+    protoflags = CURL_GSKPROTO_TLSV10_MASK |
+                 CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
+    break;
+  case CURL_SSLVERSION_TLSv1_0:
+    protoflags = CURL_GSKPROTO_TLSV10_MASK;
+    break;
+  case CURL_SSLVERSION_TLSv1_1:
+    protoflags = CURL_GSKPROTO_TLSV11_MASK;
+    break;
+  case CURL_SSLVERSION_TLSv1_2:
+    protoflags = CURL_GSKPROTO_TLSV12_MASK;
+    break;
+  }
+
+  /* Process SNI. Ignore if not supported (on OS400 < V7R1). */
+  if(sni) {
+    result = set_buffer(data, connssl->handle,
+                        GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL)
+      result = CURLE_OK;
+  }
+
+  /* Set session parameters. */
+  if(!result) {
+    /* Compute the handshake timeout. Since GSKit granularity is 1 second,
+       we round up the required value. */
+    timeout = Curl_timeleft(data, NULL, TRUE);
+    if(timeout < 0)
+      result = CURLE_OPERATION_TIMEDOUT;
+    else
+      result = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT,
+                           (timeout + 999) / 1000);
+  }
+  if(!result)
+    result = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
+  if(!result)
+    result = set_ciphers(data, connssl->handle, &protoflags);
+  if(!protoflags) {
+    failf(data, "No SSL protocol/cipher combination enabled");
+    result = CURLE_SSL_CIPHER;
+  }
+  if(!result)
+    result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
+                      (protoflags & CURL_GSKPROTO_SSLV2_MASK)?
+                      GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE);
+  if(!result)
+    result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
+                      (protoflags & CURL_GSKPROTO_SSLV3_MASK)?
+                      GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE);
+  if(!result)
+    result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
+                      (protoflags & CURL_GSKPROTO_TLSV10_MASK)?
+                      GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE);
+  if(!result) {
+    result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV11,
+                      (protoflags & CURL_GSKPROTO_TLSV11_MASK)?
+                      GSK_TRUE: GSK_FALSE, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
+      if(protoflags == CURL_GSKPROTO_TLSV11_MASK) {
+        failf(data, "TLS 1.1 not yet supported");
+        result = CURLE_SSL_CIPHER;
+      }
+    }
+  }
+  if(!result) {
+    result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV12,
+                      (protoflags & CURL_GSKPROTO_TLSV12_MASK)?
+                      GSK_TRUE: GSK_FALSE, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
+      if(protoflags == CURL_GSKPROTO_TLSV12_MASK) {
+        failf(data, "TLS 1.2 not yet supported");
+        result = CURLE_SSL_CIPHER;
+      }
+    }
+  }
+  if(!result)
+    result = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
+                      data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
+                      GSK_SERVER_AUTH_PASSTHRU, FALSE);
+
+  if(!result) {
+    /* Start handshake. Try asynchronous first. */
+    memset(&commarea, 0, sizeof commarea);
+    connssl->iocport = QsoCreateIOCompletionPort();
+    if(connssl->iocport != -1) {
+      result = gskit_status(data,
+                            gsk_secure_soc_startInit(connssl->handle,
+                                                     connssl->iocport,
+                                                     &commarea),
+                            "gsk_secure_soc_startInit()",
+                            CURLE_SSL_CONNECT_ERROR);
+      if(!result) {
+        connssl->connecting_state = ssl_connect_2;
+        return CURLE_OK;
+      }
+      else
+        close_async_handshake(connssl);
+    }
+    else if(errno != ENOBUFS)
+      result = gskit_status(data, GSK_ERROR_IO,
+                            "QsoCreateIOCompletionPort()", 0);
+    else {
+      /* No more completion port available. Use synchronous IO. */
+      result = gskit_status(data, gsk_secure_soc_init(connssl->handle),
+                            "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
+      if(!result) {
+        connssl->connecting_state = ssl_connect_3;
+        return CURLE_OK;
+      }
+    }
+  }
+
+  /* Error: rollback. */
+  close_one(connssl, data);
+  return result;
+}
+
+
+static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
+                                    bool nonblocking)
+{
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  Qso_OverlappedIO_t cstat;
+  long timeout_ms;
+  struct timeval stmv;
+  CURLcode result;
+
+  /* Poll or wait for end of SSL asynchronous handshake. */
+
+  for(;;) {
+    timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
+    if(timeout_ms < 0)
+      timeout_ms = 0;
+    stmv.tv_sec = timeout_ms / 1000;
+    stmv.tv_usec = (timeout_ms - stmv.tv_sec * 1000) * 1000;
+    switch (QsoWaitForIOCompletion(connssl->iocport, &cstat, &stmv)) {
+    case 1:             /* Operation complete. */
+      break;
+    case -1:            /* An error occurred: handshake still in progress. */
+      if(errno == EINTR) {
+        if(nonblocking)
+          return CURLE_OK;
+        continue;       /* Retry. */
+      }
+      if(errno != ETIME) {
+        failf(data, "QsoWaitForIOCompletion() I/O error: %s", strerror(errno));
+        cancel_async_handshake(conn, sockindex);
+        close_async_handshake(connssl);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      /* FALL INTO... */
+    case 0:             /* Handshake in progress, timeout occurred. */
+      if(nonblocking)
+        return CURLE_OK;
+      cancel_async_handshake(conn, sockindex);
+      close_async_handshake(connssl);
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+    break;
+  }
+  result = gskit_status(data, cstat.returnValue, "SSL handshake",
+                        CURLE_SSL_CONNECT_ERROR);
+  if(!result)
+    connssl->connecting_state = ssl_connect_3;
+  close_async_handshake(connssl);
+  return result;
+}
+
+
+static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  const gsk_cert_data_elem *cdev;
+  int cdec;
+  const gsk_cert_data_elem *p;
+  const char *cert = (const char *) NULL;
+  const char *certend;
+  const char *ptr;
+  int i;
+  CURLcode result;
+
+  /* SSL handshake done: gather certificate info and verify host. */
+
+  if(gskit_status(data, gsk_attribute_get_cert_info(connssl->handle,
+                                                    GSK_PARTNER_CERT_INFO,
+                                                    &cdev, &cdec),
+                  "gsk_attribute_get_cert_info()", CURLE_SSL_CONNECT_ERROR) ==
+     CURLE_OK) {
+    infof(data, "Server certificate:\n");
+    p = cdev;
+    for(i = 0; i++ < cdec; p++)
+      switch (p->cert_data_id) {
+      case CERT_BODY_DER:
+        cert = p->cert_data_p;
+        certend = cert + cdev->cert_data_l;
+        break;
+      case CERT_DN_PRINTABLE:
+        infof(data, "\t subject: %.*s\n", p->cert_data_l, p->cert_data_p);
+        break;
+      case CERT_ISSUER_DN_PRINTABLE:
+        infof(data, "\t issuer: %.*s\n", p->cert_data_l, p->cert_data_p);
+        break;
+      case CERT_VALID_FROM:
+        infof(data, "\t start date: %.*s\n", p->cert_data_l, p->cert_data_p);
+        break;
+      case CERT_VALID_TO:
+        infof(data, "\t expire date: %.*s\n", p->cert_data_l, p->cert_data_p);
+        break;
+    }
+  }
+
+  /* Verify host. */
+  result = Curl_verifyhost(conn, cert, certend);
+  if(result)
+    return result;
+
+  /* The only place GSKit can get the whole CA chain is a validation
+     callback where no user data pointer is available. Therefore it's not
+     possible to copy this chain into our structures for CAINFO.
+     However the server certificate may be available, thus we can return
+     info about it. */
+  if(data->set.ssl.certinfo) {
+    result = Curl_ssl_init_certinfo(data, 1);
+    if(result)
+      return result;
+
+    if(cert) {
+      result = Curl_extract_certinfo(conn, 0, cert, certend);
+      if(result)
+        return result;
+    }
+  }
+
+  /* Check pinned public key. */
+  ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
+  if(!result && ptr) {
+    curl_X509certificate x509;
+    curl_asn1Element *p;
+
+    if(!cert)
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    Curl_parseX509(&x509, cert, certend);
+    p = &x509.subjectPublicKeyInfo;
+    result = Curl_pin_peer_pubkey(data, ptr, p->header, p->end - p->header);
+    if(result) {
+      failf(data, "SSL: public key does not match pinned public key!");
+      return result;
+    }
+  }
+
+  connssl->connecting_state = ssl_connect_done;
+  return CURLE_OK;
+}
+
+
+static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
+                                     bool nonblocking, bool *done)
+{
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  long timeout_ms;
+  Qso_OverlappedIO_t cstat;
+  CURLcode result = CURLE_OK;
+
+  *done = connssl->state == ssl_connection_complete;
+  if(*done)
+    return CURLE_OK;
+
+  /* Step 1: create session, start handshake. */
+  if(connssl->connecting_state == ssl_connect_1) {
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      result = CURLE_OPERATION_TIMEDOUT;
+    }
+    else
+      result = gskit_connect_step1(conn, sockindex);
+  }
+
+  /* Step 2: check if handshake is over. */
+  if(!result && connssl->connecting_state == ssl_connect_2) {
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      result = CURLE_OPERATION_TIMEDOUT;
+    }
+    else
+      result = gskit_connect_step2(conn, sockindex, nonblocking);
+  }
+
+  /* Step 3: gather certificate info, verify host. */
+  if(!result && connssl->connecting_state == ssl_connect_3)
+    result = gskit_connect_step3(conn, sockindex);
+
+  if(result)
+    close_one(connssl, data);
+  else if(connssl->connecting_state == ssl_connect_done) {
+    connssl->state = ssl_connection_complete;
+    connssl->connecting_state = ssl_connect_1;
+    conn->recv[sockindex] = gskit_recv;
+    conn->send[sockindex] = gskit_send;
+    *done = TRUE;
+  }
+
+  return result;
+}
+
+
+CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn,
+                                        int sockindex,
+                                        bool *done)
+{
+  CURLcode result;
+
+  result = gskit_connect_common(conn, sockindex, TRUE, done);
+  if(*done || result)
+    conn->ssl[sockindex].connecting_state = ssl_connect_1;
+  return result;
+}
+
+
+CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode result;
+  bool done;
+
+  conn->ssl[sockindex].connecting_state = ssl_connect_1;
+  result = gskit_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+
+void Curl_gskit_close(struct connectdata *conn, int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  if(connssl->use)
+    close_one(connssl, data);
+}
+
+
+int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct SessionHandle *data = conn->data;
+  ssize_t nread;
+  int what;
+  int rc;
+  char buf[120];
+
+  if(!connssl->handle)
+    return 0;
+
+  if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
+    return 0;
+
+  close_one(connssl, data);
+  rc = 0;
+  what = Curl_socket_ready(conn->sock[sockindex],
+                           CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+
+  for(;;) {
+    if(what < 0) {
+      /* anything that gets here is fatally bad */
+      failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+      rc = -1;
+      break;
+    }
+
+    if(!what) {                                /* timeout */
+      failf(data, "SSL shutdown timeout");
+      break;
+    }
+
+    /* Something to read, let's do it and hope that it is the close
+       notify alert from the server. No way to gsk_secure_soc_read() now, so
+       use read(). */
+
+    nread = read(conn->sock[sockindex], buf, sizeof(buf));
+
+    if(nread < 0) {
+      failf(data, "read: %s", strerror(errno));
+      rc = -1;
+    }
+
+    if(nread <= 0)
+      break;
+
+    what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
+  }
+
+  return rc;
+}
+
+
+size_t Curl_gskit_version(char *buffer, size_t size)
+{
+  strncpy(buffer, "GSKit", size);
+  return strlen(buffer);
+}
+
+
+int Curl_gskit_check_cxn(struct connectdata *cxn)
+{
+  int err;
+  int errlen;
+
+  /* The only thing that can be tested here is at the socket level. */
+
+  if(!cxn->ssl[FIRSTSOCKET].handle)
+    return 0; /* connection has been closed */
+
+  err = 0;
+  errlen = sizeof err;
+
+  if(getsockopt(cxn->sock[FIRSTSOCKET], SOL_SOCKET, SO_ERROR,
+                 (unsigned char *) &err, &errlen) ||
+     errlen != sizeof err || err)
+    return 0; /* connection has been closed */
+
+  return -1;  /* connection status unknown */
+}
+
+#endif /* USE_GSKIT */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/gskit.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/gskit.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/gskit.h	(revision 164)
@@ -0,0 +1,71 @@
+#ifndef HEADER_CURL_GSKIT_H
+#define HEADER_CURL_GSKIT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/*
+ * This header should only be needed to get included by vtls.c and gskit.c
+ */
+
+#include "urldata.h"
+
+#ifdef USE_GSKIT
+int Curl_gskit_init(void);
+void Curl_gskit_cleanup(void);
+CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn,
+                                        int sockindex, bool *done);
+void Curl_gskit_close(struct connectdata *conn, int sockindex);
+int Curl_gskit_shutdown(struct connectdata *conn, int sockindex);
+
+size_t Curl_gskit_version(char *buffer, size_t size);
+int Curl_gskit_check_cxn(struct connectdata *cxn);
+
+/* Set the API backend definition to GSKit */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_GSKIT
+
+/* this backend supports CURLOPT_CERTINFO */
+#define have_curlssl_certinfo 1
+
+/* API setup for GSKit */
+#define curlssl_init Curl_gskit_init
+#define curlssl_cleanup Curl_gskit_cleanup
+#define curlssl_connect Curl_gskit_connect
+#define curlssl_connect_nonblocking Curl_gskit_connect_nonblocking
+
+/*  No session handling for GSKit */
+#define curlssl_session_free(x) Curl_nop_stmt
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_gskit_close
+#define curlssl_shutdown(x,y) Curl_gskit_shutdown(x,y)
+#define curlssl_set_engine(x,y) CURLE_NOT_BUILT_IN
+#define curlssl_set_engine_default(x) CURLE_NOT_BUILT_IN
+#define curlssl_engines_list(x) NULL
+#define curlssl_version Curl_gskit_version
+#define curlssl_check_cxn(x) Curl_gskit_check_cxn(x)
+#define curlssl_data_pending(x,y) 0
+#define curlssl_random(x,y,z) -1
+
+#endif /* USE_GSKIT */
+
+#endif /* HEADER_CURL_GSKIT_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/gtls.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/gtls.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/gtls.c	(revision 164)
@@ -0,0 +1,1619 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all GnuTLS-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ * Note: don't use the GnuTLS' *_t variable type names in this source code,
+ * since they were not present in 1.0.X.
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_GNUTLS
+
+#include <gnutls/abstract.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+
+#ifdef USE_GNUTLS_NETTLE
+#include <gnutls/crypto.h>
+#include <nettle/md5.h>
+#include <nettle/sha2.h>
+#else
+#include <gcrypt.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "gtls.h"
+#include "vtls.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "rawstr.h"
+#include "warnless.h"
+#include "x509asn1.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ Some hackish cast macros based on:
+ https://developer.gnome.org/glib/unstable/glib-Type-Conversion-Macros.html
+*/
+#ifndef GNUTLS_POINTER_TO_INT_CAST
+#define GNUTLS_POINTER_TO_INT_CAST(p) ((int) (long) (p))
+#endif
+#ifndef GNUTLS_INT_TO_POINTER_CAST
+#define GNUTLS_INT_TO_POINTER_CAST(i) ((void*) (long) (i))
+#endif
+
+/* Enable GnuTLS debugging by defining GTLSDEBUG */
+/*#define GTLSDEBUG */
+
+#ifdef GTLSDEBUG
+static void tls_log_func(int level, const char *str)
+{
+    fprintf(stderr, "|<%d>| %s", level, str);
+}
+#endif
+static bool gtls_inited = FALSE;
+
+#if defined(GNUTLS_VERSION_NUMBER)
+#  if (GNUTLS_VERSION_NUMBER >= 0x020c00)
+#    undef gnutls_transport_set_lowat
+#    define gnutls_transport_set_lowat(A,B) Curl_nop_stmt
+#    define USE_GNUTLS_PRIORITY_SET_DIRECT 1
+#  endif
+#  if (GNUTLS_VERSION_NUMBER >= 0x020c03)
+#    define GNUTLS_MAPS_WINSOCK_ERRORS 1
+#  endif
+
+#  if (GNUTLS_VERSION_NUMBER >= 0x030200)
+#    define HAS_ALPN
+#  endif
+
+#  if (GNUTLS_VERSION_NUMBER >= 0x03020d)
+#    define HAS_OCSP
+#  endif
+
+#  if (GNUTLS_VERSION_NUMBER >= 0x030306)
+#    define HAS_CAPATH
+#  endif
+#endif
+
+#ifdef HAS_OCSP
+# include <gnutls/ocsp.h>
+#endif
+
+/*
+ * Custom push and pull callback functions used by GNU TLS to read and write
+ * to the socket.  These functions are simple wrappers to send() and recv()
+ * (although here using the sread/swrite macros as defined by
+ * curl_setup_once.h).
+ * We use custom functions rather than the GNU TLS defaults because it allows
+ * us to get specific about the fourth "flags" argument, and to use arbitrary
+ * private data with gnutls_transport_set_ptr if we wish.
+ *
+ * When these custom push and pull callbacks fail, GNU TLS checks its own
+ * session-specific error variable, and when not set also its own global
+ * errno variable, in order to take appropriate action. GNU TLS does not
+ * require that the transport is actually a socket. This implies that for
+ * Windows builds these callbacks should ideally set the session-specific
+ * error variable using function gnutls_transport_set_errno or as a last
+ * resort global errno variable using gnutls_transport_set_global_errno,
+ * with a transport agnostic error value. This implies that some winsock
+ * error translation must take place in these callbacks.
+ *
+ * Paragraph above applies to GNU TLS versions older than 2.12.3, since
+ * this version GNU TLS does its own internal winsock error translation
+ * using system_errno() function.
+ */
+
+#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
+#  define gtls_EINTR  4
+#  define gtls_EIO    5
+#  define gtls_EAGAIN 11
+static int gtls_mapped_sockerrno(void)
+{
+  switch(SOCKERRNO) {
+  case WSAEWOULDBLOCK:
+    return gtls_EAGAIN;
+  case WSAEINTR:
+    return gtls_EINTR;
+  default:
+    break;
+  }
+  return gtls_EIO;
+}
+#endif
+
+static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
+{
+  ssize_t ret = swrite(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
+#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
+  if(ret < 0)
+    gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
+#endif
+  return ret;
+}
+
+static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len)
+{
+  ssize_t ret = sread(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
+#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
+  if(ret < 0)
+    gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
+#endif
+  return ret;
+}
+
+/* Curl_gtls_init()
+ *
+ * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that
+ * are not thread-safe and thus this function itself is not thread-safe and
+ * must only be called from within curl_global_init() to keep the thread
+ * situation under control!
+ */
+int Curl_gtls_init(void)
+{
+  int ret = 1;
+  if(!gtls_inited) {
+    ret = gnutls_global_init()?0:1;
+#ifdef GTLSDEBUG
+    gnutls_global_set_log_function(tls_log_func);
+    gnutls_global_set_log_level(2);
+#endif
+    gtls_inited = TRUE;
+  }
+  return ret;
+}
+
+int Curl_gtls_cleanup(void)
+{
+  if(gtls_inited) {
+    gnutls_global_deinit();
+    gtls_inited = FALSE;
+  }
+  return 1;
+}
+
+static void showtime(struct SessionHandle *data,
+                     const char *text,
+                     time_t stamp)
+{
+  struct tm buffer;
+  const struct tm *tm = &buffer;
+  CURLcode result = Curl_gmtime(stamp, &buffer);
+  if(result)
+    return;
+
+  snprintf(data->state.buffer,
+           BUFSIZE,
+           "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT",
+           text,
+           Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+           tm->tm_mday,
+           Curl_month[tm->tm_mon],
+           tm->tm_year + 1900,
+           tm->tm_hour,
+           tm->tm_min,
+           tm->tm_sec);
+  infof(data, "%s\n", data->state.buffer);
+}
+
+static gnutls_datum_t load_file (const char *file)
+{
+  FILE *f;
+  gnutls_datum_t loaded_file = { NULL, 0 };
+  long filelen;
+  void *ptr;
+
+  if(!(f = fopen(file, "rb")))
+    return loaded_file;
+  if(fseek(f, 0, SEEK_END) != 0
+     || (filelen = ftell(f)) < 0
+     || fseek(f, 0, SEEK_SET) != 0
+     || !(ptr = malloc((size_t)filelen)))
+    goto out;
+  if(fread(ptr, 1, (size_t)filelen, f) < (size_t)filelen) {
+    free(ptr);
+    goto out;
+  }
+
+  loaded_file.data = ptr;
+  loaded_file.size = (unsigned int)filelen;
+out:
+  fclose(f);
+  return loaded_file;
+}
+
+static void unload_file(gnutls_datum_t data) {
+  free(data.data);
+}
+
+
+/* this function does a SSL/TLS (re-)handshake */
+static CURLcode handshake(struct connectdata *conn,
+                          int sockindex,
+                          bool duringconnect,
+                          bool nonblocking)
+{
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  gnutls_session_t session = conn->ssl[sockindex].session;
+  curl_socket_t sockfd = conn->sock[sockindex];
+  long timeout_ms;
+  int rc;
+  int what;
+
+  for(;;) {
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, duringconnect);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading
+       || connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_ready(readfd, writefd,
+                               nonblocking?0:
+                               timeout_ms?timeout_ms:1000);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking)
+          return CURLE_OK;
+        else if(timeout_ms) {
+          /* timeout */
+          failf(data, "SSL connection timeout at %ld", timeout_ms);
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    rc = gnutls_handshake(session);
+
+    if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) {
+      connssl->connecting_state =
+        gnutls_record_get_direction(session)?
+        ssl_connect_2_writing:ssl_connect_2_reading;
+      continue;
+    }
+    else if((rc < 0) && !gnutls_error_is_fatal(rc)) {
+      const char *strerr = NULL;
+
+      if(rc == GNUTLS_E_WARNING_ALERT_RECEIVED) {
+        int alert = gnutls_alert_get(session);
+        strerr = gnutls_alert_get_name(alert);
+      }
+
+      if(strerr == NULL)
+        strerr = gnutls_strerror(rc);
+
+      infof(data, "gnutls_handshake() warning: %s\n", strerr);
+      continue;
+    }
+    else if(rc < 0) {
+      const char *strerr = NULL;
+
+      if(rc == GNUTLS_E_FATAL_ALERT_RECEIVED) {
+        int alert = gnutls_alert_get(session);
+        strerr = gnutls_alert_get_name(alert);
+      }
+
+      if(strerr == NULL)
+        strerr = gnutls_strerror(rc);
+
+      failf(data, "gnutls_handshake() failed: %s", strerr);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    /* Reset our connect state machine */
+    connssl->connecting_state = ssl_connect_1;
+    return CURLE_OK;
+  }
+}
+
+static gnutls_x509_crt_fmt_t do_file_type(const char *type)
+{
+  if(!type || !type[0])
+    return GNUTLS_X509_FMT_PEM;
+  if(Curl_raw_equal(type, "PEM"))
+    return GNUTLS_X509_FMT_PEM;
+  if(Curl_raw_equal(type, "DER"))
+    return GNUTLS_X509_FMT_DER;
+  return -1;
+}
+
+static CURLcode
+gtls_connect_step1(struct connectdata *conn,
+                   int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  gnutls_session_t session;
+  int rc;
+  void *ssl_sessionid;
+  size_t ssl_idsize;
+  bool sni = TRUE; /* default is SNI enabled */
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif
+#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
+  static const int cipher_priority[] = {
+  /* These two ciphers were added to GnuTLS as late as ver. 3.0.1,
+     but this code path is only ever used for ver. < 2.12.0.
+     GNUTLS_CIPHER_AES_128_GCM,
+     GNUTLS_CIPHER_AES_256_GCM,
+  */
+    GNUTLS_CIPHER_AES_128_CBC,
+    GNUTLS_CIPHER_AES_256_CBC,
+    GNUTLS_CIPHER_CAMELLIA_128_CBC,
+    GNUTLS_CIPHER_CAMELLIA_256_CBC,
+    GNUTLS_CIPHER_3DES_CBC,
+  };
+  static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
+  static int protocol_priority[] = { 0, 0, 0, 0 };
+#else
+#define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
+/* If GnuTLS was compiled without support for SRP it will error out if SRP is
+   requested in the priority string, so treat it specially
+ */
+#define GNUTLS_SRP "+SRP"
+  const char* prioritylist;
+  const char *err = NULL;
+#endif
+
+  if(conn->ssl[sockindex].state == ssl_connection_complete)
+    /* to make us tolerant against being called more than once for the
+       same connection */
+    return CURLE_OK;
+
+  if(!gtls_inited)
+    Curl_gtls_init();
+
+  /* GnuTLS only supports SSLv3 and TLSv1 */
+  if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
+    failf(data, "GnuTLS does not support SSLv2");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+  else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
+    sni = FALSE; /* SSLv3 has no SNI */
+
+  /* allocate a cred struct */
+  rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred);
+  if(rc != GNUTLS_E_SUCCESS) {
+    failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+#ifdef USE_TLS_SRP
+  if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
+    infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
+
+    rc = gnutls_srp_allocate_client_credentials(
+           &conn->ssl[sockindex].srp_client_cred);
+    if(rc != GNUTLS_E_SUCCESS) {
+      failf(data, "gnutls_srp_allocate_client_cred() failed: %s",
+            gnutls_strerror(rc));
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex].
+                                           srp_client_cred,
+                                           data->set.ssl.username,
+                                           data->set.ssl.password);
+    if(rc != GNUTLS_E_SUCCESS) {
+      failf(data, "gnutls_srp_set_client_cred() failed: %s",
+            gnutls_strerror(rc));
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+  }
+#endif
+
+  if(data->set.ssl.CAfile) {
+    /* set the trusted CA cert bundle file */
+    gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
+                                        GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
+
+    rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
+                                                data->set.ssl.CAfile,
+                                                GNUTLS_X509_FMT_PEM);
+    if(rc < 0) {
+      infof(data, "error reading ca cert file %s (%s)\n",
+            data->set.ssl.CAfile, gnutls_strerror(rc));
+      if(data->set.ssl.verifypeer)
+        return CURLE_SSL_CACERT_BADFILE;
+    }
+    else
+      infof(data, "found %d certificates in %s\n",
+            rc, data->set.ssl.CAfile);
+  }
+
+#ifdef HAS_CAPATH
+  if(data->set.ssl.CApath) {
+    /* set the trusted CA cert directory */
+    rc = gnutls_certificate_set_x509_trust_dir(conn->ssl[sockindex].cred,
+                                                data->set.ssl.CApath,
+                                                GNUTLS_X509_FMT_PEM);
+    if(rc < 0) {
+      infof(data, "error reading ca cert file %s (%s)\n",
+            data->set.ssl.CAfile, gnutls_strerror(rc));
+      if(data->set.ssl.verifypeer)
+        return CURLE_SSL_CACERT_BADFILE;
+    }
+    else
+      infof(data, "found %d certificates in %s\n",
+            rc, data->set.ssl.CApath);
+  }
+#endif
+
+  if(data->set.ssl.CRLfile) {
+    /* set the CRL list file */
+    rc = gnutls_certificate_set_x509_crl_file(conn->ssl[sockindex].cred,
+                                              data->set.ssl.CRLfile,
+                                              GNUTLS_X509_FMT_PEM);
+    if(rc < 0) {
+      failf(data, "error reading crl file %s (%s)",
+            data->set.ssl.CRLfile, gnutls_strerror(rc));
+      return CURLE_SSL_CRL_BADFILE;
+    }
+    else
+      infof(data, "found %d CRL in %s\n",
+            rc, data->set.ssl.CRLfile);
+  }
+
+  /* Initialize TLS session as a client */
+  rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
+  if(rc != GNUTLS_E_SUCCESS) {
+    failf(data, "gnutls_init() failed: %d", rc);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  /* convenient assign */
+  session = conn->ssl[sockindex].session;
+
+  if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
+#ifdef ENABLE_IPV6
+     (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
+#endif
+     sni &&
+     (gnutls_server_name_set(session, GNUTLS_NAME_DNS, conn->host.name,
+                             strlen(conn->host.name)) < 0))
+    infof(data, "WARNING: failed to configure server name indication (SNI) "
+          "TLS extension\n");
+
+  /* Use default priorities */
+  rc = gnutls_set_default_priority(session);
+  if(rc != GNUTLS_E_SUCCESS)
+    return CURLE_SSL_CONNECT_ERROR;
+
+#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
+  rc = gnutls_cipher_set_priority(session, cipher_priority);
+  if(rc != GNUTLS_E_SUCCESS)
+    return CURLE_SSL_CONNECT_ERROR;
+
+  /* Sets the priority on the certificate types supported by gnutls. Priority
+   is higher for types specified before others. After specifying the types
+   you want, you must append a 0. */
+  rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
+  if(rc != GNUTLS_E_SUCCESS)
+    return CURLE_SSL_CONNECT_ERROR;
+
+  if(data->set.ssl.cipher_list != NULL) {
+    failf(data, "can't pass a custom cipher list to older GnuTLS"
+          " versions");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  switch (data->set.ssl.version) {
+    case CURL_SSLVERSION_SSLv3:
+      protocol_priority[0] = GNUTLS_SSL3;
+      break;
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      protocol_priority[0] = GNUTLS_TLS1_0;
+      protocol_priority[1] = GNUTLS_TLS1_1;
+      protocol_priority[2] = GNUTLS_TLS1_2;
+      break;
+    case CURL_SSLVERSION_TLSv1_0:
+      protocol_priority[0] = GNUTLS_TLS1_0;
+      break;
+    case CURL_SSLVERSION_TLSv1_1:
+      protocol_priority[0] = GNUTLS_TLS1_1;
+      break;
+    case CURL_SSLVERSION_TLSv1_2:
+      protocol_priority[0] = GNUTLS_TLS1_2;
+    break;
+      case CURL_SSLVERSION_SSLv2:
+    default:
+      failf(data, "GnuTLS does not support SSLv2");
+      return CURLE_SSL_CONNECT_ERROR;
+      break;
+  }
+  rc = gnutls_protocol_set_priority(session, protocol_priority);
+  if(rc != GNUTLS_E_SUCCESS) {
+    failf(data, "Did you pass a valid GnuTLS cipher list?");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+#else
+  /* Ensure +SRP comes at the *end* of all relevant strings so that it can be
+   * removed if a run-time error indicates that SRP is not supported by this
+   * GnuTLS version */
+  switch (data->set.ssl.version) {
+    case CURL_SSLVERSION_SSLv3:
+      prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0";
+      sni = false;
+      break;
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:" GNUTLS_SRP;
+      break;
+    case CURL_SSLVERSION_TLSv1_0:
+      prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                     "+VERS-TLS1.0:" GNUTLS_SRP;
+      break;
+    case CURL_SSLVERSION_TLSv1_1:
+      prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                     "+VERS-TLS1.1:" GNUTLS_SRP;
+      break;
+    case CURL_SSLVERSION_TLSv1_2:
+      prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                     "+VERS-TLS1.2:" GNUTLS_SRP;
+      break;
+    case CURL_SSLVERSION_SSLv2:
+    default:
+      failf(data, "GnuTLS does not support SSLv2");
+      return CURLE_SSL_CONNECT_ERROR;
+      break;
+  }
+  rc = gnutls_priority_set_direct(session, prioritylist, &err);
+  if((rc == GNUTLS_E_INVALID_REQUEST) && err) {
+    if(!strcmp(err, GNUTLS_SRP)) {
+      /* This GnuTLS was probably compiled without support for SRP.
+       * Note that fact and try again without it. */
+      int validprioritylen = curlx_uztosi(err - prioritylist);
+      char *prioritycopy = strdup(prioritylist);
+      if(!prioritycopy)
+        return CURLE_OUT_OF_MEMORY;
+
+      infof(data, "This GnuTLS does not support SRP\n");
+      if(validprioritylen)
+        /* Remove the :+SRP */
+        prioritycopy[validprioritylen - 1] = 0;
+      rc = gnutls_priority_set_direct(session, prioritycopy, &err);
+      free(prioritycopy);
+    }
+  }
+  if(rc != GNUTLS_E_SUCCESS) {
+    failf(data, "Error %d setting GnuTLS cipher list starting with %s",
+          rc, err);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+#endif
+
+#ifdef HAS_ALPN
+  if(data->set.ssl_enable_alpn) {
+    int cur = 0;
+    gnutls_datum_t protocols[2];
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
+      protocols[cur].data = (unsigned char *)NGHTTP2_PROTO_VERSION_ID;
+      protocols[cur].size = NGHTTP2_PROTO_VERSION_ID_LEN;
+      cur++;
+      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+    }
+#endif
+
+    protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1;
+    protocols[cur].size = ALPN_HTTP_1_1_LENGTH;
+    cur++;
+    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+    gnutls_alpn_set_protocols(session, protocols, cur, 0);
+  }
+#endif
+
+  if(data->set.str[STRING_CERT]) {
+    if(data->set.str[STRING_KEY_PASSWD]) {
+#if HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2
+      const unsigned int supported_key_encryption_algorithms =
+        GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
+        GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES |
+        GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 |
+        GNUTLS_PKCS_USE_PBES2_AES_256;
+      rc = gnutls_certificate_set_x509_key_file2(
+           conn->ssl[sockindex].cred,
+           data->set.str[STRING_CERT],
+           data->set.str[STRING_KEY] ?
+           data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
+           do_file_type(data->set.str[STRING_CERT_TYPE]),
+           data->set.str[STRING_KEY_PASSWD],
+           supported_key_encryption_algorithms);
+      if(rc != GNUTLS_E_SUCCESS) {
+        failf(data,
+              "error reading X.509 potentially-encrypted key file: %s",
+              gnutls_strerror(rc));
+        return CURLE_SSL_CONNECT_ERROR;
+#else
+        failf(data, "gnutls lacks support for encrypted key files");
+        return CURLE_SSL_CONNECT_ERROR;
+#endif
+      }
+    }
+    else {
+      rc = gnutls_certificate_set_x509_key_file(
+           conn->ssl[sockindex].cred,
+           data->set.str[STRING_CERT],
+           data->set.str[STRING_KEY] ?
+           data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
+           do_file_type(data->set.str[STRING_CERT_TYPE]) );
+      if(rc != GNUTLS_E_SUCCESS) {
+        failf(data, "error reading X.509 key or certificate file: %s",
+              gnutls_strerror(rc));
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+    }
+  }
+
+#ifdef USE_TLS_SRP
+  /* put the credentials to the current session */
+  if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
+    rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
+                                conn->ssl[sockindex].srp_client_cred);
+    if(rc != GNUTLS_E_SUCCESS) {
+      failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  else
+#endif
+  {
+    rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
+                                conn->ssl[sockindex].cred);
+    if(rc != GNUTLS_E_SUCCESS) {
+      failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  /* set the connection handle (file descriptor for the socket) */
+  gnutls_transport_set_ptr(session,
+                           GNUTLS_INT_TO_POINTER_CAST(conn->sock[sockindex]));
+
+  /* register callback functions to send and receive data. */
+  gnutls_transport_set_push_function(session, Curl_gtls_push);
+  gnutls_transport_set_pull_function(session, Curl_gtls_pull);
+
+  /* lowat must be set to zero when using custom push and pull functions. */
+  gnutls_transport_set_lowat(session, 0);
+
+#ifdef HAS_OCSP
+  if(data->set.ssl.verifystatus) {
+    rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL);
+    if(rc != GNUTLS_E_SUCCESS) {
+      failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+#endif
+
+  /* This might be a reconnect, so we check for a session ID in the cache
+     to speed up things */
+
+  if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) {
+    /* we got a session id, use it! */
+    gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
+
+    /* Informational message */
+    infof (data, "SSL re-using session ID\n");
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode pkp_pin_peer_pubkey(struct SessionHandle *data,
+                                    gnutls_x509_crt_t cert,
+                                    const char *pinnedpubkey)
+{
+  /* Scratch */
+  size_t len1 = 0, len2 = 0;
+  unsigned char *buff1 = NULL;
+
+  gnutls_pubkey_t key = NULL;
+
+  /* Result is returned to caller */
+  int ret = 0;
+  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+
+  /* if a path wasn't specified, don't pin */
+  if(NULL == pinnedpubkey)
+    return CURLE_OK;
+
+  if(NULL == cert)
+    return result;
+
+  do {
+    /* Begin Gyrations to get the public key     */
+    gnutls_pubkey_init(&key);
+
+    ret = gnutls_pubkey_import_x509(key, cert, 0);
+    if(ret < 0)
+      break; /* failed */
+
+    ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, NULL, &len1);
+    if(ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0)
+      break; /* failed */
+
+    buff1 = malloc(len1);
+    if(NULL == buff1)
+      break; /* failed */
+
+    len2 = len1;
+
+    ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, buff1, &len2);
+    if(ret < 0 || len1 != len2)
+      break; /* failed */
+
+    /* End Gyrations */
+
+    /* The one good exit point */
+    result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
+  } while(0);
+
+  if(NULL != key)
+    gnutls_pubkey_deinit(key);
+
+  Curl_safefree(buff1);
+
+  return result;
+}
+
+static Curl_recv gtls_recv;
+static Curl_send gtls_send;
+
+static CURLcode
+gtls_connect_step3(struct connectdata *conn,
+                   int sockindex)
+{
+  unsigned int cert_list_size;
+  const gnutls_datum_t *chainp;
+  unsigned int verify_status = 0;
+  gnutls_x509_crt_t x509_cert, x509_issuer;
+  gnutls_datum_t issuerp;
+  char certbuf[256] = ""; /* big enough? */
+  size_t size;
+  unsigned int algo;
+  unsigned int bits;
+  time_t certclock;
+  const char *ptr;
+  struct SessionHandle *data = conn->data;
+  gnutls_session_t session = conn->ssl[sockindex].session;
+  int rc;
+  bool incache;
+  void *ssl_sessionid;
+#ifdef HAS_ALPN
+  gnutls_datum_t proto;
+#endif
+  CURLcode result = CURLE_OK;
+
+  gnutls_protocol_t version = gnutls_protocol_get_version(session);
+
+  /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
+  ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
+                                     gnutls_cipher_get(session),
+                                     gnutls_mac_get(session));
+
+  infof(data, "SSL connection using %s / %s\n",
+        gnutls_protocol_get_name(version), ptr);
+
+  /* This function will return the peer's raw certificate (chain) as sent by
+     the peer. These certificates are in raw format (DER encoded for
+     X.509). In case of a X.509 then a certificate list may be present. The
+     first certificate in the list is the peer's certificate, following the
+     issuer's certificate, then the issuer's issuer etc. */
+
+  chainp = gnutls_certificate_get_peers(session, &cert_list_size);
+  if(!chainp) {
+    if(data->set.ssl.verifypeer ||
+       data->set.ssl.verifyhost ||
+       data->set.ssl.issuercert) {
+#ifdef USE_TLS_SRP
+      if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
+         && data->set.ssl.username != NULL
+         && !data->set.ssl.verifypeer
+         && gnutls_cipher_get(session)) {
+        /* no peer cert, but auth is ok if we have SRP user and cipher and no
+           peer verify */
+      }
+      else {
+#endif
+        failf(data, "failed to get server cert");
+        return CURLE_PEER_FAILED_VERIFICATION;
+#ifdef USE_TLS_SRP
+      }
+#endif
+    }
+    infof(data, "\t common name: WARNING couldn't obtain\n");
+  }
+
+  if(data->set.ssl.certinfo && chainp) {
+    unsigned int i;
+
+    result = Curl_ssl_init_certinfo(data, cert_list_size);
+    if(result)
+      return result;
+
+    for(i = 0; i < cert_list_size; i++) {
+      const char *beg = (const char *) chainp[i].data;
+      const char *end = beg + chainp[i].size;
+
+      result = Curl_extract_certinfo(conn, i, beg, end);
+      if(result)
+        return result;
+    }
+  }
+
+  if(data->set.ssl.verifypeer) {
+    /* This function will try to verify the peer's certificate and return its
+       status (trusted, invalid etc.). The value of status should be one or
+       more of the gnutls_certificate_status_t enumerated elements bitwise
+       or'd. To avoid denial of service attacks some default upper limits
+       regarding the certificate key size and chain size are set. To override
+       them use gnutls_certificate_set_verify_limits(). */
+
+    rc = gnutls_certificate_verify_peers2(session, &verify_status);
+    if(rc < 0) {
+      failf(data, "server cert verify failed: %d", rc);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    /* verify_status is a bitmask of gnutls_certificate_status bits */
+    if(verify_status & GNUTLS_CERT_INVALID) {
+      if(data->set.ssl.verifypeer) {
+        failf(data, "server certificate verification failed. CAfile: %s "
+              "CRLfile: %s", data->set.ssl.CAfile?data->set.ssl.CAfile:"none",
+              data->set.ssl.CRLfile?data->set.ssl.CRLfile:"none");
+        return CURLE_SSL_CACERT;
+      }
+      else
+        infof(data, "\t server certificate verification FAILED\n");
+    }
+    else
+      infof(data, "\t server certificate verification OK\n");
+  }
+  else
+    infof(data, "\t server certificate verification SKIPPED\n");
+
+#ifdef HAS_OCSP
+  if(data->set.ssl.verifystatus) {
+    if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
+      gnutls_datum_t status_request;
+      gnutls_ocsp_resp_t ocsp_resp;
+
+      gnutls_ocsp_cert_status_t status;
+      gnutls_x509_crl_reason_t reason;
+
+      rc = gnutls_ocsp_status_request_get(session, &status_request);
+
+      infof(data, "\t server certificate status verification FAILED\n");
+
+      if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+        failf(data, "No OCSP response received");
+        return CURLE_SSL_INVALIDCERTSTATUS;
+      }
+
+      if(rc < 0) {
+        failf(data, "Invalid OCSP response received");
+        return CURLE_SSL_INVALIDCERTSTATUS;
+      }
+
+      gnutls_ocsp_resp_init(&ocsp_resp);
+
+      rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
+      if(rc < 0) {
+        failf(data, "Invalid OCSP response received");
+        return CURLE_SSL_INVALIDCERTSTATUS;
+      }
+
+      rc = gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
+                                       &status, NULL, NULL, NULL, &reason);
+
+      switch(status) {
+      case GNUTLS_OCSP_CERT_GOOD:
+        break;
+
+      case GNUTLS_OCSP_CERT_REVOKED: {
+        const char *crl_reason;
+
+        switch(reason) {
+          default:
+          case GNUTLS_X509_CRLREASON_UNSPECIFIED:
+            crl_reason = "unspecified reason";
+            break;
+
+          case GNUTLS_X509_CRLREASON_KEYCOMPROMISE:
+            crl_reason = "private key compromised";
+            break;
+
+          case GNUTLS_X509_CRLREASON_CACOMPROMISE:
+            crl_reason = "CA compromised";
+            break;
+
+          case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
+            crl_reason = "affiliation has changed";
+            break;
+
+          case GNUTLS_X509_CRLREASON_SUPERSEDED:
+            crl_reason = "certificate superseded";
+            break;
+
+          case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
+            crl_reason = "operation has ceased";
+            break;
+
+          case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
+            crl_reason = "certificate is on hold";
+            break;
+
+          case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
+            crl_reason = "will be removed from delta CRL";
+            break;
+
+          case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
+            crl_reason = "privilege withdrawn";
+            break;
+
+          case GNUTLS_X509_CRLREASON_AACOMPROMISE:
+            crl_reason = "AA compromised";
+            break;
+        }
+
+        failf(data, "Server certificate was revoked: %s", crl_reason);
+        break;
+      }
+
+      default:
+      case GNUTLS_OCSP_CERT_UNKNOWN:
+        failf(data, "Server certificate status is unknown");
+        break;
+      }
+
+      gnutls_ocsp_resp_deinit(ocsp_resp);
+
+      return CURLE_SSL_INVALIDCERTSTATUS;
+    }
+    else
+      infof(data, "\t server certificate status verification OK\n");
+  }
+  else
+    infof(data, "\t server certificate status verification SKIPPED\n");
+#endif
+
+  /* initialize an X.509 certificate structure. */
+  gnutls_x509_crt_init(&x509_cert);
+
+  if(chainp)
+    /* convert the given DER or PEM encoded Certificate to the native
+       gnutls_x509_crt_t format */
+    gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
+
+  if(data->set.ssl.issuercert) {
+    gnutls_x509_crt_init(&x509_issuer);
+    issuerp = load_file(data->set.ssl.issuercert);
+    gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
+    rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
+    gnutls_x509_crt_deinit(x509_issuer);
+    unload_file(issuerp);
+    if(rc <= 0) {
+      failf(data, "server certificate issuer check failed (IssuerCert: %s)",
+            data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
+      gnutls_x509_crt_deinit(x509_cert);
+      return CURLE_SSL_ISSUER_ERROR;
+    }
+    infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n",
+          data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
+  }
+
+  size=sizeof(certbuf);
+  rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
+                                     0, /* the first and only one */
+                                     FALSE,
+                                     certbuf,
+                                     &size);
+  if(rc) {
+    infof(data, "error fetching CN from cert:%s\n",
+          gnutls_strerror(rc));
+  }
+
+  /* This function will check if the given certificate's subject matches the
+     given hostname. This is a basic implementation of the matching described
+     in RFC2818 (HTTPS), which takes into account wildcards, and the subject
+     alternative name PKIX extension. Returns non zero on success, and zero on
+     failure. */
+  rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);
+#if GNUTLS_VERSION_NUMBER < 0x030306
+  /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP
+     addresses. */
+  if(!rc) {
+#ifdef ENABLE_IPV6
+    #define use_addr in6_addr
+#else
+    #define use_addr in_addr
+#endif
+    unsigned char addrbuf[sizeof(struct use_addr)];
+    unsigned char certaddr[sizeof(struct use_addr)];
+    size_t addrlen = 0, certaddrlen;
+    int i;
+    int ret = 0;
+
+    if(Curl_inet_pton(AF_INET, conn->host.name, addrbuf) > 0)
+      addrlen = 4;
+#ifdef ENABLE_IPV6
+    else if(Curl_inet_pton(AF_INET6, conn->host.name, addrbuf) > 0)
+      addrlen = 16;
+#endif
+
+    if(addrlen) {
+      for(i=0; ; i++) {
+        certaddrlen = sizeof(certaddr);
+        ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr,
+                                                   &certaddrlen, NULL);
+        /* If this happens, it wasn't an IP address. */
+        if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
+          continue;
+        if(ret < 0)
+          break;
+        if(ret != GNUTLS_SAN_IPADDRESS)
+          continue;
+        if(certaddrlen == addrlen && !memcmp(addrbuf, certaddr, addrlen)) {
+          rc = 1;
+          break;
+        }
+      }
+    }
+  }
+#endif
+  if(!rc) {
+    if(data->set.ssl.verifyhost) {
+      failf(data, "SSL: certificate subject name (%s) does not match "
+            "target host name '%s'", certbuf, conn->host.dispname);
+      gnutls_x509_crt_deinit(x509_cert);
+      return CURLE_PEER_FAILED_VERIFICATION;
+    }
+    else
+      infof(data, "\t common name: %s (does not match '%s')\n",
+            certbuf, conn->host.dispname);
+  }
+  else
+    infof(data, "\t common name: %s (matched)\n", certbuf);
+
+  /* Check for time-based validity */
+  certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
+
+  if(certclock == (time_t)-1) {
+    if(data->set.ssl.verifypeer) {
+      failf(data, "server cert expiration date verify failed");
+      gnutls_x509_crt_deinit(x509_cert);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    else
+      infof(data, "\t server certificate expiration date verify FAILED\n");
+  }
+  else {
+    if(certclock < time(NULL)) {
+      if(data->set.ssl.verifypeer) {
+        failf(data, "server certificate expiration date has passed.");
+        gnutls_x509_crt_deinit(x509_cert);
+        return CURLE_PEER_FAILED_VERIFICATION;
+      }
+      else
+        infof(data, "\t server certificate expiration date FAILED\n");
+    }
+    else
+      infof(data, "\t server certificate expiration date OK\n");
+  }
+
+  certclock = gnutls_x509_crt_get_activation_time(x509_cert);
+
+  if(certclock == (time_t)-1) {
+    if(data->set.ssl.verifypeer) {
+      failf(data, "server cert activation date verify failed");
+      gnutls_x509_crt_deinit(x509_cert);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    else
+      infof(data, "\t server certificate activation date verify FAILED\n");
+  }
+  else {
+    if(certclock > time(NULL)) {
+      if(data->set.ssl.verifypeer) {
+        failf(data, "server certificate not activated yet.");
+        gnutls_x509_crt_deinit(x509_cert);
+        return CURLE_PEER_FAILED_VERIFICATION;
+      }
+      else
+        infof(data, "\t server certificate activation date FAILED\n");
+    }
+    else
+      infof(data, "\t server certificate activation date OK\n");
+  }
+
+  ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
+  if(ptr) {
+    result = pkp_pin_peer_pubkey(data, x509_cert, ptr);
+    if(result != CURLE_OK) {
+      failf(data, "SSL: public key does not match pinned public key!");
+      gnutls_x509_crt_deinit(x509_cert);
+      return result;
+    }
+  }
+
+  /* Show:
+
+  - subject
+  - start date
+  - expire date
+  - common name
+  - issuer
+
+  */
+
+  /* public key algorithm's parameters */
+  algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
+  infof(data, "\t certificate public key: %s\n",
+        gnutls_pk_algorithm_get_name(algo));
+
+  /* version of the X.509 certificate. */
+  infof(data, "\t certificate version: #%d\n",
+        gnutls_x509_crt_get_version(x509_cert));
+
+
+  size = sizeof(certbuf);
+  gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
+  infof(data, "\t subject: %s\n", certbuf);
+
+  certclock = gnutls_x509_crt_get_activation_time(x509_cert);
+  showtime(data, "start date", certclock);
+
+  certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
+  showtime(data, "expire date", certclock);
+
+  size = sizeof(certbuf);
+  gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
+  infof(data, "\t issuer: %s\n", certbuf);
+
+  gnutls_x509_crt_deinit(x509_cert);
+
+  /* compression algorithm (if any) */
+  ptr = gnutls_compression_get_name(gnutls_compression_get(session));
+  /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
+  infof(data, "\t compression: %s\n", ptr);
+
+#ifdef HAS_ALPN
+  if(data->set.ssl_enable_alpn) {
+    rc = gnutls_alpn_get_selected_protocol(session, &proto);
+    if(rc == 0) {
+      infof(data, "ALPN, server accepted to use %.*s\n", proto.size,
+          proto.data);
+
+#ifdef USE_NGHTTP2
+      if(proto.size == NGHTTP2_PROTO_VERSION_ID_LEN &&
+         !memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data,
+                 NGHTTP2_PROTO_VERSION_ID_LEN)) {
+        conn->negnpn = CURL_HTTP_VERSION_2;
+      }
+      else
+#endif
+      if(proto.size == ALPN_HTTP_1_1_LENGTH &&
+         !memcmp(ALPN_HTTP_1_1, proto.data, ALPN_HTTP_1_1_LENGTH)) {
+        conn->negnpn = CURL_HTTP_VERSION_1_1;
+      }
+    }
+    else
+      infof(data, "ALPN, server did not agree to a protocol\n");
+  }
+#endif
+
+  conn->ssl[sockindex].state = ssl_connection_complete;
+  conn->recv[sockindex] = gtls_recv;
+  conn->send[sockindex] = gtls_send;
+
+  {
+    /* we always unconditionally get the session id here, as even if we
+       already got it from the cache and asked to use it in the connection, it
+       might've been rejected and then a new one is in use now and we need to
+       detect that. */
+    void *connect_sessionid;
+    size_t connect_idsize = 0;
+
+    /* get the session ID data size */
+    gnutls_session_get_data(session, NULL, &connect_idsize);
+    connect_sessionid = malloc(connect_idsize); /* get a buffer for it */
+
+    if(connect_sessionid) {
+      /* extract session ID to the allocated buffer */
+      gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
+
+      incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL));
+      if(incache) {
+        /* there was one before in the cache, so instead of risking that the
+           previous one was rejected, we just kill that and store the new */
+        Curl_ssl_delsessionid(conn, ssl_sessionid);
+      }
+
+      /* store this session id */
+      result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize);
+      if(result) {
+        free(connect_sessionid);
+        result = CURLE_OUT_OF_MEMORY;
+      }
+    }
+    else
+      result = CURLE_OUT_OF_MEMORY;
+  }
+
+  return result;
+}
+
+
+/*
+ * This function is called after the TCP connect has completed. Setup the TLS
+ * layer and do all necessary magic.
+ */
+/* We use connssl->connecting_state to keep track of the connection status;
+   there are three states: 'ssl_connect_1' (not started yet or complete),
+   'ssl_connect_2_reading' (waiting for data from server), and
+   'ssl_connect_2_writing' (waiting to be able to write).
+ */
+static CURLcode
+gtls_connect_common(struct connectdata *conn,
+                    int sockindex,
+                    bool nonblocking,
+                    bool *done)
+{
+  int rc;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  /* Initiate the connection, if not already done */
+  if(ssl_connect_1==connssl->connecting_state) {
+    rc = gtls_connect_step1 (conn, sockindex);
+    if(rc)
+      return rc;
+  }
+
+  rc = handshake(conn, sockindex, TRUE, nonblocking);
+  if(rc)
+    /* handshake() sets its own error message with failf() */
+    return rc;
+
+  /* Finish connecting once the handshake is done */
+  if(ssl_connect_1==connssl->connecting_state) {
+    rc = gtls_connect_step3(conn, sockindex);
+    if(rc)
+      return rc;
+  }
+
+  *done = ssl_connect_1==connssl->connecting_state;
+
+  return CURLE_OK;
+}
+
+CURLcode
+Curl_gtls_connect_nonblocking(struct connectdata *conn,
+                              int sockindex,
+                              bool *done)
+{
+  return gtls_connect_common(conn, sockindex, TRUE, done);
+}
+
+CURLcode
+Curl_gtls_connect(struct connectdata *conn,
+                  int sockindex)
+
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = gtls_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+static ssize_t gtls_send(struct connectdata *conn,
+                         int sockindex,
+                         const void *mem,
+                         size_t len,
+                         CURLcode *curlcode)
+{
+  ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
+
+  if(rc < 0 ) {
+    *curlcode = (rc == GNUTLS_E_AGAIN)
+      ? CURLE_AGAIN
+      : CURLE_SEND_ERROR;
+
+    rc = -1;
+  }
+
+  return rc;
+}
+
+static void close_one(struct connectdata *conn,
+                      int idx)
+{
+  if(conn->ssl[idx].session) {
+    gnutls_bye(conn->ssl[idx].session, GNUTLS_SHUT_RDWR);
+    gnutls_deinit(conn->ssl[idx].session);
+    conn->ssl[idx].session = NULL;
+  }
+  if(conn->ssl[idx].cred) {
+    gnutls_certificate_free_credentials(conn->ssl[idx].cred);
+    conn->ssl[idx].cred = NULL;
+  }
+#ifdef USE_TLS_SRP
+  if(conn->ssl[idx].srp_client_cred) {
+    gnutls_srp_free_client_credentials(conn->ssl[idx].srp_client_cred);
+    conn->ssl[idx].srp_client_cred = NULL;
+  }
+#endif
+}
+
+void Curl_gtls_close(struct connectdata *conn, int sockindex)
+{
+  close_one(conn, sockindex);
+}
+
+/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
+{
+  ssize_t result;
+  int retval = 0;
+  struct SessionHandle *data = conn->data;
+  int done = 0;
+  char buf[120];
+
+  /* This has only been tested on the proftpd server, and the mod_tls code
+     sends a close notify alert without waiting for a close notify alert in
+     response. Thus we wait for a close notify alert from the server, but
+     we do not send one. Let's hope other servers do the same... */
+
+  if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
+      gnutls_bye(conn->ssl[sockindex].session, GNUTLS_SHUT_WR);
+
+  if(conn->ssl[sockindex].session) {
+    while(!done) {
+      int what = Curl_socket_ready(conn->sock[sockindex],
+                                   CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+      if(what > 0) {
+        /* Something to read, let's do it and hope that it is the close
+           notify alert from the server */
+        result = gnutls_record_recv(conn->ssl[sockindex].session,
+                                    buf, sizeof(buf));
+        switch(result) {
+        case 0:
+          /* This is the expected response. There was no data but only
+             the close notify alert */
+          done = 1;
+          break;
+        case GNUTLS_E_AGAIN:
+        case GNUTLS_E_INTERRUPTED:
+          infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n");
+          break;
+        default:
+          retval = -1;
+          done = 1;
+          break;
+        }
+      }
+      else if(0 == what) {
+        /* timeout */
+        failf(data, "SSL shutdown timeout");
+        done = 1;
+        break;
+      }
+      else {
+        /* anything that gets here is fatally bad */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        retval = -1;
+        done = 1;
+      }
+    }
+    gnutls_deinit(conn->ssl[sockindex].session);
+  }
+  gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
+
+#ifdef USE_TLS_SRP
+  if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
+     && data->set.ssl.username != NULL)
+    gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred);
+#endif
+
+  conn->ssl[sockindex].cred = NULL;
+  conn->ssl[sockindex].session = NULL;
+
+  return retval;
+}
+
+static ssize_t gtls_recv(struct connectdata *conn, /* connection data */
+                         int num,                  /* socketindex */
+                         char *buf,                /* store read data here */
+                         size_t buffersize,        /* max amount to read */
+                         CURLcode *curlcode)
+{
+  ssize_t ret;
+
+  ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
+  if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
+    *curlcode = CURLE_AGAIN;
+    return -1;
+  }
+
+  if(ret == GNUTLS_E_REHANDSHAKE) {
+    /* BLOCKING call, this is bad but a work-around for now. Fixing this "the
+       proper way" takes a whole lot of work. */
+    CURLcode result = handshake(conn, num, FALSE, FALSE);
+    if(result)
+      /* handshake() writes error message on its own */
+      *curlcode = result;
+    else
+      *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */
+    return -1;
+  }
+
+  if(ret < 0) {
+    failf(conn->data, "GnuTLS recv error (%d): %s",
+          (int)ret, gnutls_strerror((int)ret));
+    *curlcode = CURLE_RECV_ERROR;
+    return -1;
+  }
+
+  return ret;
+}
+
+void Curl_gtls_session_free(void *ptr)
+{
+  free(ptr);
+}
+
+size_t Curl_gtls_version(char *buffer, size_t size)
+{
+  return snprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
+}
+
+#ifndef USE_GNUTLS_NETTLE
+static int Curl_gtls_seed(struct SessionHandle *data)
+{
+  /* we have the "SSL is seeded" boolean static to prevent multiple
+     time-consuming seedings in vain */
+  static bool ssl_seeded = FALSE;
+
+  /* Quickly add a bit of entropy */
+  gcry_fast_random_poll();
+
+  if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
+     data->set.str[STRING_SSL_EGDSOCKET]) {
+
+    /* TODO: to a good job seeding the RNG
+       This may involve the gcry_control function and these options:
+       GCRYCTL_SET_RANDOM_SEED_FILE
+       GCRYCTL_SET_RNDEGD_SOCKET
+    */
+    ssl_seeded = TRUE;
+  }
+  return 0;
+}
+#endif
+
+/* data might be NULL! */
+int Curl_gtls_random(struct SessionHandle *data,
+                     unsigned char *entropy,
+                     size_t length)
+{
+#if defined(USE_GNUTLS_NETTLE)
+  (void)data;
+  gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
+#elif defined(USE_GNUTLS)
+  if(data)
+    Curl_gtls_seed(data); /* Initiate the seed if not already done */
+  gcry_randomize(entropy, length, GCRY_STRONG_RANDOM);
+#endif
+  return 0;
+}
+
+void Curl_gtls_md5sum(unsigned char *tmp, /* input */
+                      size_t tmplen,
+                      unsigned char *md5sum, /* output */
+                      size_t md5len)
+{
+#if defined(USE_GNUTLS_NETTLE)
+  struct md5_ctx MD5pw;
+  md5_init(&MD5pw);
+  md5_update(&MD5pw, (unsigned int)tmplen, tmp);
+  md5_digest(&MD5pw, (unsigned int)md5len, md5sum);
+#elif defined(USE_GNUTLS)
+  gcry_md_hd_t MD5pw;
+  gcry_md_open(&MD5pw, GCRY_MD_MD5, 0);
+  gcry_md_write(MD5pw, tmp, tmplen);
+  memcpy(md5sum, gcry_md_read (MD5pw, 0), md5len);
+  gcry_md_close(MD5pw);
+#endif
+}
+
+void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */
+                      size_t tmplen,
+                      unsigned char *sha256sum, /* output */
+                      size_t sha256len)
+{
+#if defined(USE_GNUTLS_NETTLE)
+  struct sha256_ctx SHA256pw;
+  sha256_init(&SHA256pw);
+  sha256_update(&SHA256pw, (unsigned int)tmplen, tmp);
+  sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum);
+#elif defined(USE_GNUTLS)
+  gcry_md_hd_t SHA256pw;
+  gcry_md_open(&SHA256pw, GCRY_MD_SHA256, 0);
+  gcry_md_write(SHA256pw, tmp, tmplen);
+  memcpy(sha256sum, gcry_md_read (SHA256pw, 0), sha256len);
+  gcry_md_close(SHA256pw);
+#endif
+}
+
+bool Curl_gtls_cert_status_request(void)
+{
+#ifdef HAS_OCSP
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
+#endif /* USE_GNUTLS */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/gtls.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/gtls.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/gtls.h	(revision 164)
@@ -0,0 +1,88 @@
+#ifndef HEADER_CURL_GTLS_H
+#define HEADER_CURL_GTLS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_GNUTLS
+
+#include "urldata.h"
+
+int Curl_gtls_init(void);
+int Curl_gtls_cleanup(void);
+CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_gtls_connect_nonblocking(struct connectdata *conn,
+                                       int sockindex,
+                                       bool *done);
+
+ /* close a SSL connection */
+void Curl_gtls_close(struct connectdata *conn, int sockindex);
+
+void Curl_gtls_session_free(void *ptr);
+size_t Curl_gtls_version(char *buffer, size_t size);
+int Curl_gtls_shutdown(struct connectdata *conn, int sockindex);
+int Curl_gtls_random(struct SessionHandle *data,
+                     unsigned char *entropy,
+                     size_t length);
+void Curl_gtls_md5sum(unsigned char *tmp, /* input */
+                      size_t tmplen,
+                      unsigned char *md5sum, /* output */
+                      size_t md5len);
+void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */
+                      size_t tmplen,
+                      unsigned char *sha256sum, /* output */
+                      size_t sha256len);
+
+bool Curl_gtls_cert_status_request(void);
+
+/* Set the API backend definition to GnuTLS */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_GNUTLS
+
+/* this backend supports the CAPATH option */
+#define have_curlssl_ca_path 1
+
+/* this backend supports CURLOPT_CERTINFO */
+#define have_curlssl_certinfo 1
+
+/* API setup for GnuTLS */
+#define curlssl_init Curl_gtls_init
+#define curlssl_cleanup Curl_gtls_cleanup
+#define curlssl_connect Curl_gtls_connect
+#define curlssl_connect_nonblocking Curl_gtls_connect_nonblocking
+#define curlssl_session_free(x)  Curl_gtls_session_free(x)
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_gtls_close
+#define curlssl_shutdown(x,y) Curl_gtls_shutdown(x,y)
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_gtls_version
+#define curlssl_check_cxn(x) ((void)x, -1)
+#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
+#define curlssl_random(x,y,z) Curl_gtls_random(x,y,z)
+#define curlssl_md5sum(a,b,c,d) Curl_gtls_md5sum(a,b,c,d)
+#define curlssl_sha256sum(a,b,c,d) Curl_gtls_sha256sum(a,b,c,d)
+#define curlssl_cert_status_request() Curl_gtls_cert_status_request()
+
+#endif /* USE_GNUTLS */
+#endif /* HEADER_CURL_GTLS_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/mbedtls.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/mbedtls.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/mbedtls.c	(revision 164)
@@ -0,0 +1,845 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all mbedTSL-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_MBEDTLS
+
+#include <mbedtls/net.h>
+#include <mbedtls/ssl.h>
+#include <mbedtls/certs.h>
+#include <mbedtls/x509.h>
+#include <mbedtls/version.h>
+
+#include <mbedtls/error.h>
+#include <mbedtls/entropy.h>
+#include <mbedtls/ctr_drbg.h>
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "mbedtls.h"
+#include "vtls.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "rawstr.h"
+#include "polarssl_threadlock.h"
+
+#define _MPRINTF_REPLACE /* use our functions only */
+#include <curl/mprintf.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* apply threading? */
+#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+#define THREADING_SUPPORT
+#endif
+
+#if defined(THREADING_SUPPORT)
+static mbedtls_entropy_context entropy;
+
+static int  entropy_init_initialized  = 0;
+
+/* start of entropy_init_mutex() */
+static void entropy_init_mutex(mbedtls_entropy_context *ctx)
+{
+  /* lock 0 = entropy_init_mutex() */
+  Curl_polarsslthreadlock_lock_function(0);
+  if(entropy_init_initialized == 0) {
+    mbedtls_entropy_init(ctx);
+    entropy_init_initialized = 1;
+  }
+  Curl_polarsslthreadlock_unlock_function(0);
+}
+/* end of entropy_init_mutex() */
+
+/* start of entropy_func_mutex() */
+static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
+{
+  int ret;
+  /* lock 1 = entropy_func_mutex() */
+  Curl_polarsslthreadlock_lock_function(1);
+  ret = mbedtls_entropy_func(data, output, len);
+  Curl_polarsslthreadlock_unlock_function(1);
+
+  return ret;
+}
+/* end of entropy_func_mutex() */
+
+#endif /* THREADING_SUPPORT */
+
+/* Define this to enable lots of debugging for mbedTLS */
+#undef MBEDTLS_DEBUG
+
+#ifdef MBEDTLS_DEBUG
+static void mbedtls_debug(void *context, int level, const char *line)
+{
+  struct SessionHandle *data = NULL;
+
+  if(!context)
+    return;
+
+  data = (struct SessionHandle *)context;
+
+  infof(data, "%s", line);
+  (void) level;
+}
+#else
+#endif
+
+/* ALPN for http2? */
+#ifdef USE_NGHTTP2
+#  undef HAS_ALPN
+#  ifdef MBEDTLS_SSL_ALPN
+#    define HAS_ALPN
+#  endif
+#endif
+
+
+/*
+ *  profile
+ */
+const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr =
+{
+    /* Hashes from SHA-1 and above */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) |
+    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     */
+    1024,      /* RSA min key len */
+};
+
+/* See https://tls.mbed.org/discussions/generic/
+   howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der
+*/
+#define RSA_PUB_DER_MAX_BYTES   (38 + 2 * MBEDTLS_MPI_MAX_SIZE)
+#define ECP_PUB_DER_MAX_BYTES   (30 + 2 * MBEDTLS_ECP_MAX_BYTES)
+
+#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)
+
+static Curl_recv mbedtls_recv;
+static Curl_send mbedtls_send;
+
+static CURLcode
+mbedtls_connect_step1(struct connectdata *conn,
+                     int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+
+  bool sni = TRUE; /* default is SNI enabled */
+  int ret = -1;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif
+  void *old_session = NULL;
+  size_t old_session_size = 0;
+  char errorbuf[128];
+  errorbuf[0]=0;
+
+  /* mbedTLS only supports SSLv3 and TLSv1 */
+  if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
+    failf(data, "mbedTLS does not support SSLv2");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+  else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
+    sni = FALSE; /* SSLv3 has no SNI */
+
+#ifdef THREADING_SUPPORT
+  entropy_init_mutex(&entropy);
+  mbedtls_ctr_drbg_init(&connssl->ctr_drbg);
+
+  ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, entropy_func_mutex,
+                              &entropy, connssl->ssn.id,
+                              connssl->ssn.id_len);
+  if(ret) {
+#ifdef MBEDTLS_ERROR_C
+    mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+    failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
+          -ret, errorbuf);
+  }
+#else
+  mbedtls_entropy_init(&connssl->entropy);
+  mbedtls_ctr_drbg_init(&connssl->ctr_drbg);
+
+  ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, mbedtls_entropy_func,
+                              &connssl->entropy, connssl->ssn.id,
+                              connssl->ssn.id_len);
+  if(ret) {
+#ifdef MBEDTLS_ERROR_C
+    mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+    failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
+          -ret, errorbuf);
+  }
+#endif /* THREADING_SUPPORT */
+
+  /* Load the trusted CA */
+  memset(&connssl->cacert, 0, sizeof(mbedtls_x509_crt));
+
+  if(data->set.str[STRING_SSL_CAFILE]) {
+    ret = mbedtls_x509_crt_parse_file(&connssl->cacert,
+                                      data->set.str[STRING_SSL_CAFILE]);
+
+    if(ret<0) {
+#ifdef MBEDTLS_ERROR_C
+      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+      failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s",
+            data->set.str[STRING_SSL_CAFILE], -ret, errorbuf);
+
+      if(data->set.ssl.verifypeer)
+        return CURLE_SSL_CACERT_BADFILE;
+    }
+  }
+
+  if(data->set.str[STRING_SSL_CAPATH]) {
+    ret = mbedtls_x509_crt_parse_path(&connssl->cacert,
+                                      data->set.str[STRING_SSL_CAPATH]);
+
+    if(ret<0) {
+#ifdef MBEDTLS_ERROR_C
+      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+      failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s",
+            data->set.str[STRING_SSL_CAPATH], -ret, errorbuf);
+
+      if(data->set.ssl.verifypeer)
+        return CURLE_SSL_CACERT_BADFILE;
+    }
+  }
+
+  /* Load the client certificate */
+  memset(&connssl->clicert, 0, sizeof(mbedtls_x509_crt));
+
+  if(data->set.str[STRING_CERT]) {
+    ret = mbedtls_x509_crt_parse_file(&connssl->clicert,
+                                      data->set.str[STRING_CERT]);
+
+    if(ret) {
+#ifdef MBEDTLS_ERROR_C
+      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+      failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s",
+            data->set.str[STRING_CERT], -ret, errorbuf);
+
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  /* Load the client private key */
+  if(data->set.str[STRING_KEY]) {
+    mbedtls_pk_init(&connssl->pk);
+    ret = mbedtls_pk_parse_keyfile(&connssl->pk, data->set.str[STRING_KEY],
+                                   data->set.str[STRING_KEY_PASSWD]);
+    if(ret == 0 && !mbedtls_pk_can_do(&connssl->pk, MBEDTLS_PK_RSA))
+      ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
+
+    if(ret) {
+#ifdef MBEDTLS_ERROR_C
+      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+      failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s",
+            data->set.str[STRING_KEY], -ret, errorbuf);
+
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  /* Load the CRL */
+  memset(&connssl->crl, 0, sizeof(mbedtls_x509_crl));
+
+  if(data->set.str[STRING_SSL_CRLFILE]) {
+    ret = mbedtls_x509_crl_parse_file(&connssl->crl,
+                              data->set.str[STRING_SSL_CRLFILE]);
+
+    if(ret) {
+#ifdef MBEDTLS_ERROR_C
+      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+      failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s",
+            data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf);
+
+      return CURLE_SSL_CRL_BADFILE;
+    }
+  }
+
+  infof(data, "mbedTLS: Connecting to %s:%d\n",
+        conn->host.name, conn->remote_port);
+
+  mbedtls_ssl_config_init(&connssl->config);
+
+  mbedtls_ssl_init(&connssl->ssl);
+  if(mbedtls_ssl_setup(&connssl->ssl, &connssl->config)) {
+    failf(data, "mbedTLS: ssl_init failed");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+  ret = mbedtls_ssl_config_defaults(&connssl->config,
+                                    MBEDTLS_SSL_IS_CLIENT,
+                                    MBEDTLS_SSL_TRANSPORT_STREAM,
+                                    MBEDTLS_SSL_PRESET_DEFAULT);
+  if(ret) {
+    failf(data, "mbedTLS: ssl_config failed");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  /* new profile with RSA min key len = 1024 ... */
+  mbedtls_ssl_conf_cert_profile( &connssl->config,
+                                 &mbedtls_x509_crt_profile_fr);
+
+  switch(data->set.ssl.version) {
+  case CURL_SSLVERSION_SSLv3:
+    mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+                                 MBEDTLS_SSL_MINOR_VERSION_0);
+    infof(data, "mbedTLS: Forced min. SSL Version to be SSLv3\n");
+    break;
+  case CURL_SSLVERSION_TLSv1_0:
+    mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+                                 MBEDTLS_SSL_MINOR_VERSION_1);
+    infof(data, "mbedTLS: Forced min. SSL Version to be TLS 1.0\n");
+    break;
+  case CURL_SSLVERSION_TLSv1_1:
+    mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+                                 MBEDTLS_SSL_MINOR_VERSION_2);
+    infof(data, "mbedTLS: Forced min. SSL Version to be TLS 1.1\n");
+    break;
+  case CURL_SSLVERSION_TLSv1_2:
+    mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+                                 MBEDTLS_SSL_MINOR_VERSION_3);
+    infof(data, "mbedTLS: Forced min. SSL Version to be TLS 1.2\n");
+    break;
+  }
+
+  mbedtls_ssl_conf_authmode(&connssl->config, MBEDTLS_SSL_VERIFY_OPTIONAL);
+
+  mbedtls_ssl_conf_rng(&connssl->config, mbedtls_ctr_drbg_random,
+              &connssl->ctr_drbg);
+  mbedtls_ssl_set_bio(&connssl->ssl, &conn->sock[sockindex],
+              mbedtls_net_send,
+              mbedtls_net_recv,
+              NULL /*  rev_timeout() */);
+
+  mbedtls_ssl_conf_ciphersuites(&connssl->config,
+                                mbedtls_ssl_list_ciphersuites());
+  if(!Curl_ssl_getsessionid(conn, &old_session, &old_session_size)) {
+    memcpy(&connssl->ssn, old_session, old_session_size);
+    infof(data, "mbedTLS re-using session\n");
+  }
+
+  mbedtls_ssl_set_session(&connssl->ssl,
+                  &connssl->ssn);
+
+  mbedtls_ssl_conf_ca_chain(&connssl->config,
+                   &connssl->cacert,
+                   &connssl->crl);
+
+  if(data->set.str[STRING_KEY]) {
+    mbedtls_ssl_conf_own_cert(&connssl->config,
+                         &connssl->clicert, &connssl->pk);
+  }
+  if(!Curl_inet_pton(AF_INET, conn->host.name, &addr) &&
+#ifdef ENABLE_IPV6
+     !Curl_inet_pton(AF_INET6, conn->host.name, &addr) &&
+#endif
+     sni && mbedtls_ssl_set_hostname(&connssl->ssl, conn->host.name)) {
+     infof(data, "WARNING: failed to configure "
+                 "server name indication (SNI) TLS extension\n");
+  }
+
+#ifdef HAS_ALPN
+  if(data->set.ssl_enable_alpn) {
+    const char *protocols[3];
+    const char **p = protocols;
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2)
+      *p++ = NGHTTP2_PROTO_VERSION_ID;
+#endif
+    *p++ = ALPN_HTTP_1_1;
+    *p = NULL;
+    if(mbedtls_ssl_conf_alpn_protocols(&connssl->config, protocols)) {
+      failf(data, "Failed setting ALPN protocols");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    for(p = protocols; *p; ++p)
+      infof(data, "ALPN, offering %s\n", *p);
+  }
+#endif
+
+#ifdef MBEDTLS_DEBUG
+  mbedtls_ssl_conf_dbg(&connssl->ssl, mbedtls_debug, data);
+#endif
+
+  connssl->connecting_state = ssl_connect_2;
+
+  return CURLE_OK;
+}
+
+static CURLcode
+mbedtls_connect_step2(struct connectdata *conn,
+                     int sockindex)
+{
+  int ret;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  const mbedtls_x509_crt *peercert;
+
+#ifdef HAS_ALPN
+  const char* next_protocol;
+#endif
+
+  char errorbuf[128];
+  errorbuf[0] = 0;
+
+  conn->recv[sockindex] = mbedtls_recv;
+  conn->send[sockindex] = mbedtls_send;
+
+  ret = mbedtls_ssl_handshake(&connssl->ssl);
+
+  if(ret == MBEDTLS_ERR_SSL_WANT_READ) {
+    connssl->connecting_state = ssl_connect_2_reading;
+    return CURLE_OK;
+  }
+  else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
+    connssl->connecting_state = ssl_connect_2_writing;
+    return CURLE_OK;
+  }
+  else if(ret) {
+#ifdef MBEDTLS_ERROR_C
+    mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+    failf(data, "ssl_handshake returned - mbedTLS: (-0x%04X) %s",
+          -ret, errorbuf);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  infof(data, "mbedTLS: Handshake complete, cipher is %s\n",
+        mbedtls_ssl_get_ciphersuite(&conn->ssl[sockindex].ssl)
+    );
+
+  ret = mbedtls_ssl_get_verify_result(&conn->ssl[sockindex].ssl);
+
+  if(ret && data->set.ssl.verifypeer) {
+    if(ret & MBEDTLS_X509_BADCERT_EXPIRED)
+      failf(data, "Cert verify failed: BADCERT_EXPIRED");
+
+    if(ret & MBEDTLS_X509_BADCERT_REVOKED) {
+      failf(data, "Cert verify failed: BADCERT_REVOKED");
+      return CURLE_SSL_CACERT;
+    }
+
+    if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH)
+      failf(data, "Cert verify failed: BADCERT_CN_MISMATCH");
+
+    if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED)
+      failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED");
+
+    return CURLE_PEER_FAILED_VERIFICATION;
+  }
+
+  peercert = mbedtls_ssl_get_peer_cert(&connssl->ssl);
+
+  if(peercert && data->set.verbose) {
+    const size_t bufsize = 16384;
+    char *buffer = malloc(bufsize);
+
+    if(!buffer)
+      return CURLE_OUT_OF_MEMORY;
+
+    if(mbedtls_x509_crt_info(buffer, bufsize, "* ", peercert) > 0)
+      infof(data, "Dumping cert info:\n%s\n", buffer);
+    else
+      infof(data, "Unable to dump certificate information.\n");
+
+    free(buffer);
+  }
+
+  if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
+    int size;
+    CURLcode result;
+    mbedtls_x509_crt *p;
+    unsigned char pubkey[PUB_DER_MAX_BYTES];
+
+    if(!peercert || !peercert->raw.p || !peercert->raw.len) {
+      failf(data, "Failed due to missing peer certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    p = calloc(1, sizeof(*p));
+
+    if(!p)
+      return CURLE_OUT_OF_MEMORY;
+
+    mbedtls_x509_crt_init(p);
+
+    /* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der
+       needs a non-const key, for now.
+       https://github.com/ARMmbed/mbedtls/issues/396 */
+    if(mbedtls_x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) {
+      failf(data, "Failed copying peer certificate");
+      mbedtls_x509_crt_free(p);
+      free(p);
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    size = mbedtls_pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES);
+
+    if(size <= 0) {
+      failf(data, "Failed copying public key from peer certificate");
+      mbedtls_x509_crt_free(p);
+      free(p);
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    /* mbedtls_pk_write_pubkey_der writes data at the end of the buffer. */
+    result = Curl_pin_peer_pubkey(data,
+                                  data->set.str[STRING_SSL_PINNEDPUBLICKEY],
+                                  &pubkey[PUB_DER_MAX_BYTES - size], size);
+    if(result) {
+      mbedtls_x509_crt_free(p);
+      free(p);
+      return result;
+    }
+
+    mbedtls_x509_crt_free(p);
+    free(p);
+  }
+
+#ifdef HAS_ALPN
+  if(data->set.ssl_enable_alpn) {
+    next_protocol = mbedtls_ssl_get_alpn_protocol(&connssl->ssl);
+
+    if(next_protocol) {
+      infof(data, "ALPN, server accepted to use %s\n", next_protocol);
+#ifdef USE_NGHTTP2
+      if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
+                  NGHTTP2_PROTO_VERSION_ID_LEN) &&
+         !next_protocol[NGHTTP2_PROTO_VERSION_ID_LEN]) {
+        conn->negnpn = CURL_HTTP_VERSION_2;
+      }
+      else
+#endif
+      if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH) &&
+         !next_protocol[ALPN_HTTP_1_1_LENGTH]) {
+        conn->negnpn = CURL_HTTP_VERSION_1_1;
+      }
+    }
+    else {
+      infof(data, "ALPN, server did not agree to a protocol\n");
+    }
+  }
+#endif
+
+  connssl->connecting_state = ssl_connect_3;
+  infof(data, "SSL connected\n");
+
+  return CURLE_OK;
+}
+
+static CURLcode
+mbedtls_connect_step3(struct connectdata *conn,
+                     int sockindex)
+{
+  CURLcode retcode = CURLE_OK;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct SessionHandle *data = conn->data;
+  void *old_ssl_sessionid = NULL;
+  mbedtls_ssl_session *our_ssl_sessionid = &conn->ssl[sockindex].ssn;
+  int incache;
+
+  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+  /* Save the current session data for possible re-use */
+  incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
+  if(incache) {
+    if(old_ssl_sessionid != our_ssl_sessionid) {
+      infof(data, "old SSL session ID is stale, removing\n");
+      Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+      incache = FALSE;
+    }
+  }
+  if(!incache) {
+    void *new_session = malloc(sizeof(mbedtls_ssl_session));
+
+    if(new_session) {
+      memcpy(new_session, our_ssl_sessionid,
+             sizeof(mbedtls_ssl_session));
+
+      retcode = Curl_ssl_addsessionid(conn, new_session,
+                                   sizeof(mbedtls_ssl_session));
+    }
+    else {
+      retcode = CURLE_OUT_OF_MEMORY;
+    }
+
+    if(retcode) {
+      failf(data, "failed to store ssl session");
+      return retcode;
+    }
+  }
+
+  connssl->connecting_state = ssl_connect_done;
+
+  return CURLE_OK;
+}
+
+static ssize_t mbedtls_send(struct connectdata *conn,
+                             int sockindex,
+                             const void *mem,
+                             size_t len,
+                             CURLcode *curlcode)
+{
+  int ret = -1;
+
+  ret = mbedtls_ssl_write(&conn->ssl[sockindex].ssl,
+                  (unsigned char *)mem, len);
+
+  if(ret < 0) {
+    *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_WRITE) ?
+      CURLE_AGAIN : CURLE_SEND_ERROR;
+    ret = -1;
+  }
+
+  return ret;
+}
+
+void Curl_mbedtls_close_all(struct SessionHandle *data)
+{
+  (void)data;
+}
+
+void Curl_mbedtls_close(struct connectdata *conn, int sockindex)
+{
+  /* mbedtls_rsa_free(&conn->ssl[sockindex].rsa); */
+  mbedtls_x509_crt_free(&conn->ssl[sockindex].clicert);
+  mbedtls_x509_crt_free(&conn->ssl[sockindex].cacert);
+  mbedtls_x509_crl_free(&conn->ssl[sockindex].crl);
+  mbedtls_ssl_free(&conn->ssl[sockindex].ssl);
+}
+
+static ssize_t mbedtls_recv(struct connectdata *conn,
+                             int num,
+                             char *buf,
+                             size_t buffersize,
+                             CURLcode *curlcode)
+{
+  int ret = -1;
+  ssize_t len = -1;
+
+  memset(buf, 0, buffersize);
+  ret = mbedtls_ssl_read(&conn->ssl[num].ssl, (unsigned char *)buf,
+                         buffersize);
+
+  if(ret <= 0) {
+    if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
+      return 0;
+
+    *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_READ) ?
+      CURLE_AGAIN : CURLE_RECV_ERROR;
+    return -1;
+  }
+
+  len = ret;
+
+  return len;
+}
+
+void Curl_mbedtls_session_free(void *ptr)
+{
+  free(ptr);
+}
+
+size_t Curl_mbedtls_version(char *buffer, size_t size)
+{
+  unsigned int version = mbedtls_version_get_number();
+  return snprintf(buffer, size, "mbedTLS/%d.%d.%d", version>>24,
+                  (version>>16)&0xff, (version>>8)&0xff);
+}
+
+static CURLcode
+mbedtls_connect_common(struct connectdata *conn,
+                        int sockindex,
+                        bool nonblocking,
+                        bool *done)
+{
+  CURLcode retcode;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  long timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1==connssl->connecting_state) {
+    /* Find out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+    retcode = mbedtls_connect_step1(conn, sockindex);
+    if(retcode)
+      return retcode;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading
+       || connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_ready(readfd, writefd, nonblocking ? 0 : timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if
+     * this connection is part of a multi handle and this loop would
+     * execute again. This permits the owner of a multi handle to
+     * abort a connection attempt before step2 has completed while
+     * ensuring that a client using select() or epoll() will always
+     * have a valid fdset to wait on.
+     */
+    retcode = mbedtls_connect_step2(conn, sockindex);
+    if(retcode || (nonblocking &&
+                   (ssl_connect_2 == connssl->connecting_state ||
+                    ssl_connect_2_reading == connssl->connecting_state ||
+                    ssl_connect_2_writing == connssl->connecting_state)))
+      return retcode;
+
+  } /* repeat step2 until all transactions are done. */
+
+  if(ssl_connect_3==connssl->connecting_state) {
+    retcode = mbedtls_connect_step3(conn, sockindex);
+    if(retcode)
+      return retcode;
+  }
+
+  if(ssl_connect_done==connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = mbedtls_recv;
+    conn->send[sockindex] = mbedtls_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* Reset our connect state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+CURLcode
+Curl_mbedtls_connect_nonblocking(struct connectdata *conn,
+                                int sockindex,
+                                bool *done)
+{
+  return mbedtls_connect_common(conn, sockindex, TRUE, done);
+}
+
+
+CURLcode
+Curl_mbedtls_connect(struct connectdata *conn,
+                    int sockindex)
+{
+  CURLcode retcode;
+  bool done = FALSE;
+
+  retcode = mbedtls_connect_common(conn, sockindex, FALSE, &done);
+  if(retcode)
+    return retcode;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+/*
+ * return 0 error initializing SSL
+ * return 1 SSL initialized successfully
+ */
+int mbedtls_init(void)
+{
+  return Curl_polarsslthreadlock_thread_setup();
+}
+
+void mbedtls_cleanup(void)
+{
+  (void)Curl_polarsslthreadlock_thread_cleanup();
+}
+
+#endif /* USE_MBEDTLS */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/mbedtls.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/mbedtls.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/mbedtls.h	(revision 164)
@@ -0,0 +1,75 @@
+#ifndef HEADER_CURL_MBEDTLS_H
+#define HEADER_CURL_MBEDTLS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_MBEDTLS
+
+/* Called on first use mbedTLS, setup threading if supported */
+int  mbedtls_init(void);
+void mbedtls_cleanup(void);
+
+
+CURLcode Curl_mbedtls_connect(struct connectdata *conn, int sockindex);
+
+CURLcode Curl_mbedtls_connect_nonblocking(struct connectdata *conn,
+                                           int sockindex,
+                                           bool *done);
+
+/* tell mbedTLS to close down all open information regarding connections (and
+   thus session ID caching etc) */
+void Curl_mbedtls_close_all(struct SessionHandle *data);
+
+ /* close a SSL connection */
+void Curl_mbedtls_close(struct connectdata *conn, int sockindex);
+
+void Curl_mbedtls_session_free(void *ptr);
+size_t Curl_mbedtls_version(char *buffer, size_t size);
+int Curl_mbedtls_shutdown(struct connectdata *conn, int sockindex);
+
+/* API setup for mbedTLS */
+#define curlssl_init() mbedtls_init()
+#define curlssl_cleanup() mbedtls_cleanup()
+#define curlssl_connect Curl_mbedtls_connect
+#define curlssl_connect_nonblocking Curl_mbedtls_connect_nonblocking
+#define curlssl_session_free(x)  Curl_mbedtls_session_free(x)
+#define curlssl_close_all Curl_mbedtls_close_all
+#define curlssl_close Curl_mbedtls_close
+#define curlssl_shutdown(x,y) 0
+#define curlssl_set_engine(x,y) (x=x, y=y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) (x=x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_mbedtls_version
+#define curlssl_check_cxn(x) (x=x, -1)
+#define curlssl_data_pending(x,y) (x=x, y=y, 0)
+#define CURL_SSL_BACKEND CURLSSLBACKEND_MBEDTLS
+#define curlssl_sha256sum(a,b,c,d) mbedtls_sha256(a,b,c,0)
+
+/* This might cause libcurl to use a weeker random!
+   TODO: implement proper use of Polarssl's CTR-DRBG or HMAC-DRBG and use that
+*/
+#define curlssl_random(x,y,z) (x=x, y=y, z=z, CURLE_NOT_BUILT_IN)
+
+#endif /* USE_MBEDTLS */
+#endif /* HEADER_CURL_MBEDTLS_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/nss.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/nss.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/nss.c	(revision 164)
@@ -0,0 +1,2087 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all NSS-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_NSS
+
+#include "urldata.h"
+#include "sendf.h"
+#include "formdata.h" /* for the boundary function */
+#include "url.h" /* for the ssl config check function */
+#include "connect.h"
+#include "strequal.h"
+#include "select.h"
+#include "vtls.h"
+#include "llist.h"
+#include "curl_printf.h"
+#include "nssg.h"
+#include <nspr.h>
+#include <nss.h>
+#include <ssl.h>
+#include <sslerr.h>
+#include <secerr.h>
+#include <secmod.h>
+#include <sslproto.h>
+#include <prtypes.h>
+#include <pk11pub.h>
+#include <prio.h>
+#include <secitem.h>
+#include <secport.h>
+#include <certdb.h>
+#include <base64.h>
+#include <cert.h>
+#include <prerror.h>
+#include <keyhi.h>        /* for SECKEY_DestroyPublicKey() */
+
+#define NSSVERNUM ((NSS_VMAJOR<<16)|(NSS_VMINOR<<8)|NSS_VPATCH)
+
+#if NSSVERNUM >= 0x030f00 /* 3.15.0 */
+#include <ocsp.h>
+#endif
+
+#include "rawstr.h"
+#include "warnless.h"
+#include "x509asn1.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define SSL_DIR "/etc/pki/nssdb"
+
+/* enough to fit the string "PEM Token #[0|1]" */
+#define SLOTSIZE 13
+
+PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd);
+
+PRLock * nss_initlock = NULL;
+PRLock * nss_crllock = NULL;
+struct curl_llist *nss_crl_list = NULL;
+NSSInitContext * nss_context = NULL;
+
+volatile int initialized = 0;
+
+typedef struct {
+  const char *name;
+  int num;
+} cipher_s;
+
+#define PK11_SETATTRS(_attr, _idx, _type, _val, _len) do {  \
+  CK_ATTRIBUTE *ptr = (_attr) + ((_idx)++);                 \
+  ptr->type = (_type);                                      \
+  ptr->pValue = (_val);                                     \
+  ptr->ulValueLen = (_len);                                 \
+} WHILE_FALSE
+
+#define CERT_NewTempCertificate __CERT_NewTempCertificate
+
+#define NUM_OF_CIPHERS sizeof(cipherlist)/sizeof(cipherlist[0])
+static const cipher_s cipherlist[] = {
+  /* SSL2 cipher suites */
+  {"rc4",                        SSL_EN_RC4_128_WITH_MD5},
+  {"rc4-md5",                    SSL_EN_RC4_128_WITH_MD5},
+  {"rc4export",                  SSL_EN_RC4_128_EXPORT40_WITH_MD5},
+  {"rc2",                        SSL_EN_RC2_128_CBC_WITH_MD5},
+  {"rc2export",                  SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5},
+  {"des",                        SSL_EN_DES_64_CBC_WITH_MD5},
+  {"desede3",                    SSL_EN_DES_192_EDE3_CBC_WITH_MD5},
+  /* SSL3/TLS cipher suites */
+  {"rsa_rc4_128_md5",            SSL_RSA_WITH_RC4_128_MD5},
+  {"rsa_rc4_128_sha",            SSL_RSA_WITH_RC4_128_SHA},
+  {"rsa_3des_sha",               SSL_RSA_WITH_3DES_EDE_CBC_SHA},
+  {"rsa_des_sha",                SSL_RSA_WITH_DES_CBC_SHA},
+  {"rsa_rc4_40_md5",             SSL_RSA_EXPORT_WITH_RC4_40_MD5},
+  {"rsa_rc2_40_md5",             SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5},
+  {"rsa_null_md5",               SSL_RSA_WITH_NULL_MD5},
+  {"rsa_null_sha",               SSL_RSA_WITH_NULL_SHA},
+  {"fips_3des_sha",              SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA},
+  {"fips_des_sha",               SSL_RSA_FIPS_WITH_DES_CBC_SHA},
+  {"fortezza",                   SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA},
+  {"fortezza_rc4_128_sha",       SSL_FORTEZZA_DMS_WITH_RC4_128_SHA},
+  {"fortezza_null",              SSL_FORTEZZA_DMS_WITH_NULL_SHA},
+  /* TLS 1.0: Exportable 56-bit Cipher Suites. */
+  {"rsa_des_56_sha",             TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA},
+  {"rsa_rc4_56_sha",             TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
+  /* AES ciphers. */
+  {"dhe_dss_aes_128_cbc_sha",    TLS_DHE_DSS_WITH_AES_128_CBC_SHA},
+  {"dhe_dss_aes_256_cbc_sha",    TLS_DHE_DSS_WITH_AES_256_CBC_SHA},
+  {"dhe_rsa_aes_128_cbc_sha",    TLS_DHE_RSA_WITH_AES_128_CBC_SHA},
+  {"dhe_rsa_aes_256_cbc_sha",    TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
+  {"rsa_aes_128_sha",            TLS_RSA_WITH_AES_128_CBC_SHA},
+  {"rsa_aes_256_sha",            TLS_RSA_WITH_AES_256_CBC_SHA},
+  /* ECC ciphers. */
+  {"ecdh_ecdsa_null_sha",        TLS_ECDH_ECDSA_WITH_NULL_SHA},
+  {"ecdh_ecdsa_rc4_128_sha",     TLS_ECDH_ECDSA_WITH_RC4_128_SHA},
+  {"ecdh_ecdsa_3des_sha",        TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA},
+  {"ecdh_ecdsa_aes_128_sha",     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA},
+  {"ecdh_ecdsa_aes_256_sha",     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA},
+  {"ecdhe_ecdsa_null_sha",       TLS_ECDHE_ECDSA_WITH_NULL_SHA},
+  {"ecdhe_ecdsa_rc4_128_sha",    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
+  {"ecdhe_ecdsa_3des_sha",       TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA},
+  {"ecdhe_ecdsa_aes_128_sha",    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
+  {"ecdhe_ecdsa_aes_256_sha",    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
+  {"ecdh_rsa_null_sha",          TLS_ECDH_RSA_WITH_NULL_SHA},
+  {"ecdh_rsa_128_sha",           TLS_ECDH_RSA_WITH_RC4_128_SHA},
+  {"ecdh_rsa_3des_sha",          TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA},
+  {"ecdh_rsa_aes_128_sha",       TLS_ECDH_RSA_WITH_AES_128_CBC_SHA},
+  {"ecdh_rsa_aes_256_sha",       TLS_ECDH_RSA_WITH_AES_256_CBC_SHA},
+  {"echde_rsa_null",             TLS_ECDHE_RSA_WITH_NULL_SHA},
+  {"ecdhe_rsa_rc4_128_sha",      TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+  {"ecdhe_rsa_3des_sha",         TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA},
+  {"ecdhe_rsa_aes_128_sha",      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
+  {"ecdhe_rsa_aes_256_sha",      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
+  {"ecdh_anon_null_sha",         TLS_ECDH_anon_WITH_NULL_SHA},
+  {"ecdh_anon_rc4_128sha",       TLS_ECDH_anon_WITH_RC4_128_SHA},
+  {"ecdh_anon_3des_sha",         TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA},
+  {"ecdh_anon_aes_128_sha",      TLS_ECDH_anon_WITH_AES_128_CBC_SHA},
+  {"ecdh_anon_aes_256_sha",      TLS_ECDH_anon_WITH_AES_256_CBC_SHA},
+#ifdef TLS_RSA_WITH_NULL_SHA256
+  /* new HMAC-SHA256 cipher suites specified in RFC */
+  {"rsa_null_sha_256",                TLS_RSA_WITH_NULL_SHA256},
+  {"rsa_aes_128_cbc_sha_256",         TLS_RSA_WITH_AES_128_CBC_SHA256},
+  {"rsa_aes_256_cbc_sha_256",         TLS_RSA_WITH_AES_256_CBC_SHA256},
+  {"dhe_rsa_aes_128_cbc_sha_256",     TLS_DHE_RSA_WITH_AES_128_CBC_SHA256},
+  {"dhe_rsa_aes_256_cbc_sha_256",     TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},
+  {"ecdhe_ecdsa_aes_128_cbc_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
+  {"ecdhe_rsa_aes_128_cbc_sha_256",   TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
+#endif
+#ifdef TLS_RSA_WITH_AES_128_GCM_SHA256
+  /* AES GCM cipher suites in RFC 5288 and RFC 5289 */
+  {"rsa_aes_128_gcm_sha_256",         TLS_RSA_WITH_AES_128_GCM_SHA256},
+  {"dhe_rsa_aes_128_gcm_sha_256",     TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
+  {"dhe_dss_aes_128_gcm_sha_256",     TLS_DHE_DSS_WITH_AES_128_GCM_SHA256},
+  {"ecdhe_ecdsa_aes_128_gcm_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+  {"ecdh_ecdsa_aes_128_gcm_sha_256",  TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256},
+  {"ecdhe_rsa_aes_128_gcm_sha_256",   TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+  {"ecdh_rsa_aes_128_gcm_sha_256",    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256},
+#endif
+};
+
+static const char* pem_library = "libnsspem.so";
+SECMODModule* mod = NULL;
+
+/* NSPR I/O layer we use to detect blocking direction during SSL handshake */
+static PRDescIdentity nspr_io_identity = PR_INVALID_IO_LAYER;
+static PRIOMethods nspr_io_methods;
+
+static const char* nss_error_to_name(PRErrorCode code)
+{
+  const char *name = PR_ErrorToName(code);
+  if(name)
+    return name;
+
+  return "unknown error";
+}
+
+static void nss_print_error_message(struct SessionHandle *data, PRUint32 err)
+{
+  failf(data, "%s", PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT));
+}
+
+static SECStatus set_ciphers(struct SessionHandle *data, PRFileDesc * model,
+                             char *cipher_list)
+{
+  unsigned int i;
+  PRBool cipher_state[NUM_OF_CIPHERS];
+  PRBool found;
+  char *cipher;
+
+  /* use accessors to avoid dynamic linking issues after an update of NSS */
+  const PRUint16 num_implemented_ciphers = SSL_GetNumImplementedCiphers();
+  const PRUint16 *implemented_ciphers = SSL_GetImplementedCiphers();
+  if(!implemented_ciphers)
+    return SECFailure;
+
+  /* First disable all ciphers. This uses a different max value in case
+   * NSS adds more ciphers later we don't want them available by
+   * accident
+   */
+  for(i = 0; i < num_implemented_ciphers; i++) {
+    SSL_CipherPrefSet(model, implemented_ciphers[i], PR_FALSE);
+  }
+
+  /* Set every entry in our list to false */
+  for(i = 0; i < NUM_OF_CIPHERS; i++) {
+    cipher_state[i] = PR_FALSE;
+  }
+
+  cipher = cipher_list;
+
+  while(cipher_list && (cipher_list[0])) {
+    while((*cipher) && (ISSPACE(*cipher)))
+      ++cipher;
+
+    if((cipher_list = strchr(cipher, ','))) {
+      *cipher_list++ = '\0';
+    }
+
+    found = PR_FALSE;
+
+    for(i=0; i<NUM_OF_CIPHERS; i++) {
+      if(Curl_raw_equal(cipher, cipherlist[i].name)) {
+        cipher_state[i] = PR_TRUE;
+        found = PR_TRUE;
+        break;
+      }
+    }
+
+    if(found == PR_FALSE) {
+      failf(data, "Unknown cipher in list: %s", cipher);
+      return SECFailure;
+    }
+
+    if(cipher_list) {
+      cipher = cipher_list;
+    }
+  }
+
+  /* Finally actually enable the selected ciphers */
+  for(i=0; i<NUM_OF_CIPHERS; i++) {
+    if(!cipher_state[i])
+      continue;
+
+    if(SSL_CipherPrefSet(model, cipherlist[i].num, PR_TRUE) != SECSuccess) {
+      failf(data, "cipher-suite not supported by NSS: %s", cipherlist[i].name);
+      return SECFailure;
+    }
+  }
+
+  return SECSuccess;
+}
+
+/*
+ * Get the number of ciphers that are enabled. We use this to determine
+ * if we need to call NSS_SetDomesticPolicy() to enable the default ciphers.
+ */
+static int num_enabled_ciphers(void)
+{
+  PRInt32 policy = 0;
+  int count = 0;
+  unsigned int i;
+
+  for(i=0; i<NUM_OF_CIPHERS; i++) {
+    SSL_CipherPolicyGet(cipherlist[i].num, &policy);
+    if(policy)
+      count++;
+  }
+  return count;
+}
+
+/*
+ * Determine whether the nickname passed in is a filename that needs to
+ * be loaded as a PEM or a regular NSS nickname.
+ *
+ * returns 1 for a file
+ * returns 0 for not a file (NSS nickname)
+ */
+static int is_file(const char *filename)
+{
+  struct_stat st;
+
+  if(filename == NULL)
+    return 0;
+
+  if(stat(filename, &st) == 0)
+    if(S_ISREG(st.st_mode))
+      return 1;
+
+  return 0;
+}
+
+/* Check if the given string is filename or nickname of a certificate.  If the
+ * given string is recognized as filename, return NULL.  If the given string is
+ * recognized as nickname, return a duplicated string.  The returned string
+ * should be later deallocated using free().  If the OOM failure occurs, we
+ * return NULL, too.
+ */
+static char* dup_nickname(struct SessionHandle *data, enum dupstring cert_kind)
+{
+  const char *str = data->set.str[cert_kind];
+  const char *n;
+
+  if(!is_file(str))
+    /* no such file exists, use the string as nickname */
+    return strdup(str);
+
+  /* search the last slash; we require at least one slash in a file name */
+  n = strrchr(str, '/');
+  if(!n) {
+    infof(data, "warning: certificate file name \"%s\" handled as nickname; "
+          "please use \"./%s\" to force file name\n", str, str);
+    return strdup(str);
+  }
+
+  /* we'll use the PEM reader to read the certificate from file */
+  return NULL;
+}
+
+/* Call PK11_CreateGenericObject() with the given obj_class and filename.  If
+ * the call succeeds, append the object handle to the list of objects so that
+ * the object can be destroyed in Curl_nss_close(). */
+static CURLcode nss_create_object(struct ssl_connect_data *ssl,
+                                  CK_OBJECT_CLASS obj_class,
+                                  const char *filename, bool cacert)
+{
+  PK11SlotInfo *slot;
+  PK11GenericObject *obj;
+  CK_BBOOL cktrue = CK_TRUE;
+  CK_BBOOL ckfalse = CK_FALSE;
+  CK_ATTRIBUTE attrs[/* max count of attributes */ 4];
+  int attr_cnt = 0;
+  CURLcode result = (cacert)
+    ? CURLE_SSL_CACERT_BADFILE
+    : CURLE_SSL_CERTPROBLEM;
+
+  const int slot_id = (cacert) ? 0 : 1;
+  char *slot_name = aprintf("PEM Token #%d", slot_id);
+  if(!slot_name)
+    return CURLE_OUT_OF_MEMORY;
+
+  slot = PK11_FindSlotByName(slot_name);
+  free(slot_name);
+  if(!slot)
+    return result;
+
+  PK11_SETATTRS(attrs, attr_cnt, CKA_CLASS, &obj_class, sizeof(obj_class));
+  PK11_SETATTRS(attrs, attr_cnt, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL));
+  PK11_SETATTRS(attrs, attr_cnt, CKA_LABEL, (unsigned char *)filename,
+                strlen(filename) + 1);
+
+  if(CKO_CERTIFICATE == obj_class) {
+    CK_BBOOL *pval = (cacert) ? (&cktrue) : (&ckfalse);
+    PK11_SETATTRS(attrs, attr_cnt, CKA_TRUST, pval, sizeof(*pval));
+  }
+
+  obj = PK11_CreateGenericObject(slot, attrs, attr_cnt, PR_FALSE);
+  PK11_FreeSlot(slot);
+  if(!obj)
+    return result;
+
+  if(!Curl_llist_insert_next(ssl->obj_list, ssl->obj_list->tail, obj)) {
+    PK11_DestroyGenericObject(obj);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(!cacert && CKO_CERTIFICATE == obj_class)
+    /* store reference to a client certificate */
+    ssl->obj_clicert = obj;
+
+  return CURLE_OK;
+}
+
+/* Destroy the NSS object whose handle is given by ptr.  This function is
+ * a callback of Curl_llist_alloc() used by Curl_llist_destroy() to destroy
+ * NSS objects in Curl_nss_close() */
+static void nss_destroy_object(void *user, void *ptr)
+{
+  PK11GenericObject *obj = (PK11GenericObject *)ptr;
+  (void) user;
+  PK11_DestroyGenericObject(obj);
+}
+
+/* same as nss_destroy_object() but for CRL items */
+static void nss_destroy_crl_item(void *user, void *ptr)
+{
+  SECItem *crl_der = (SECItem *)ptr;
+  (void) user;
+  SECITEM_FreeItem(crl_der, PR_TRUE);
+}
+
+static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
+                              const char *filename, PRBool cacert)
+{
+  CURLcode result = (cacert)
+    ? CURLE_SSL_CACERT_BADFILE
+    : CURLE_SSL_CERTPROBLEM;
+
+  /* libnsspem.so leaks memory if the requested file does not exist.  For more
+   * details, go to <https://bugzilla.redhat.com/734760>. */
+  if(is_file(filename))
+    result = nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert);
+
+  if(!result && !cacert) {
+    /* we have successfully loaded a client certificate */
+    CERTCertificate *cert;
+    char *nickname = NULL;
+    char *n = strrchr(filename, '/');
+    if(n)
+      n++;
+
+    /* The following undocumented magic helps to avoid a SIGSEGV on call
+     * of PK11_ReadRawAttribute() from SelectClientCert() when using an
+     * immature version of libnsspem.so.  For more details, go to
+     * <https://bugzilla.redhat.com/733685>. */
+    nickname = aprintf("PEM Token #1:%s", n);
+    if(nickname) {
+      cert = PK11_FindCertFromNickname(nickname, NULL);
+      if(cert)
+        CERT_DestroyCertificate(cert);
+
+      free(nickname);
+    }
+  }
+
+  return result;
+}
+
+/* add given CRL to cache if it is not already there */
+static CURLcode nss_cache_crl(SECItem *crl_der)
+{
+  CERTCertDBHandle *db = CERT_GetDefaultCertDB();
+  CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crl_der, 0);
+  if(crl) {
+    /* CRL already cached */
+    SEC_DestroyCrl(crl);
+    SECITEM_FreeItem(crl_der, PR_TRUE);
+    return CURLE_OK;
+  }
+
+  /* acquire lock before call of CERT_CacheCRL() and accessing nss_crl_list */
+  PR_Lock(nss_crllock);
+
+  /* store the CRL item so that we can free it in Curl_nss_cleanup() */
+  if(!Curl_llist_insert_next(nss_crl_list, nss_crl_list->tail, crl_der)) {
+    SECITEM_FreeItem(crl_der, PR_TRUE);
+    PR_Unlock(nss_crllock);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(SECSuccess != CERT_CacheCRL(db, crl_der)) {
+    /* unable to cache CRL */
+    PR_Unlock(nss_crllock);
+    return CURLE_SSL_CRL_BADFILE;
+  }
+
+  /* we need to clear session cache, so that the CRL could take effect */
+  SSL_ClearSessionCache();
+  PR_Unlock(nss_crllock);
+  return CURLE_OK;
+}
+
+static CURLcode nss_load_crl(const char* crlfilename)
+{
+  PRFileDesc *infile;
+  PRFileInfo  info;
+  SECItem filedata = { 0, NULL, 0 };
+  SECItem *crl_der = NULL;
+  char *body;
+
+  infile = PR_Open(crlfilename, PR_RDONLY, 0);
+  if(!infile)
+    return CURLE_SSL_CRL_BADFILE;
+
+  if(PR_SUCCESS != PR_GetOpenFileInfo(infile, &info))
+    goto fail;
+
+  if(!SECITEM_AllocItem(NULL, &filedata, info.size + /* zero ended */ 1))
+    goto fail;
+
+  if(info.size != PR_Read(infile, filedata.data, info.size))
+    goto fail;
+
+  crl_der = SECITEM_AllocItem(NULL, NULL, 0U);
+  if(!crl_der)
+    goto fail;
+
+  /* place a trailing zero right after the visible data */
+  body = (char*)filedata.data;
+  body[--filedata.len] = '\0';
+
+  body = strstr(body, "-----BEGIN");
+  if(body) {
+    /* assume ASCII */
+    char *trailer;
+    char *begin = PORT_Strchr(body, '\n');
+    if(!begin)
+      begin = PORT_Strchr(body, '\r');
+    if(!begin)
+      goto fail;
+
+    trailer = strstr(++begin, "-----END");
+    if(!trailer)
+      goto fail;
+
+    /* retrieve DER from ASCII */
+    *trailer = '\0';
+    if(ATOB_ConvertAsciiToItem(crl_der, begin))
+      goto fail;
+
+    SECITEM_FreeItem(&filedata, PR_FALSE);
+  }
+  else
+    /* assume DER */
+    *crl_der = filedata;
+
+  PR_Close(infile);
+  return nss_cache_crl(crl_der);
+
+fail:
+  PR_Close(infile);
+  SECITEM_FreeItem(crl_der, PR_TRUE);
+  SECITEM_FreeItem(&filedata, PR_FALSE);
+  return CURLE_SSL_CRL_BADFILE;
+}
+
+static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
+                             char *key_file)
+{
+  PK11SlotInfo *slot;
+  SECStatus status;
+  CURLcode result;
+  struct ssl_connect_data *ssl = conn->ssl;
+
+  (void)sockindex; /* unused */
+
+  result = nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE);
+  if(result) {
+    PR_SetError(SEC_ERROR_BAD_KEY, 0);
+    return result;
+  }
+
+  slot = PK11_FindSlotByName("PEM Token #1");
+  if(!slot)
+    return CURLE_SSL_CERTPROBLEM;
+
+  /* This will force the token to be seen as re-inserted */
+  SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
+  PK11_IsPresent(slot);
+
+  status = PK11_Authenticate(slot, PR_TRUE,
+                             conn->data->set.str[STRING_KEY_PASSWD]);
+  PK11_FreeSlot(slot);
+
+  return (SECSuccess == status) ? CURLE_OK : CURLE_SSL_CERTPROBLEM;
+}
+
+static int display_error(struct connectdata *conn, PRInt32 err,
+                         const char *filename)
+{
+  switch(err) {
+  case SEC_ERROR_BAD_PASSWORD:
+    failf(conn->data, "Unable to load client key: Incorrect password");
+    return 1;
+  case SEC_ERROR_UNKNOWN_CERT:
+    failf(conn->data, "Unable to load certificate %s", filename);
+    return 1;
+  default:
+    break;
+  }
+  return 0; /* The caller will print a generic error */
+}
+
+static CURLcode cert_stuff(struct connectdata *conn, int sockindex,
+                           char *cert_file, char *key_file)
+{
+  struct SessionHandle *data = conn->data;
+  CURLcode result;
+
+  if(cert_file) {
+    result = nss_load_cert(&conn->ssl[sockindex], cert_file, PR_FALSE);
+    if(result) {
+      const PRErrorCode err = PR_GetError();
+      if(!display_error(conn, err, cert_file)) {
+        const char *err_name = nss_error_to_name(err);
+        failf(data, "unable to load client cert: %d (%s)", err, err_name);
+      }
+
+      return result;
+    }
+  }
+
+  if(key_file || (is_file(cert_file))) {
+    if(key_file)
+      result = nss_load_key(conn, sockindex, key_file);
+    else
+      /* In case the cert file also has the key */
+      result = nss_load_key(conn, sockindex, cert_file);
+    if(result) {
+      const PRErrorCode err = PR_GetError();
+      if(!display_error(conn, err, key_file)) {
+        const char *err_name = nss_error_to_name(err);
+        failf(data, "unable to load client key: %d (%s)", err, err_name);
+      }
+
+      return result;
+    }
+  }
+
+  return CURLE_OK;
+}
+
+static char * nss_get_password(PK11SlotInfo * slot, PRBool retry, void *arg)
+{
+  (void)slot; /* unused */
+
+  if(retry || NULL == arg)
+    return NULL;
+  else
+    return (char *)PORT_Strdup((char *)arg);
+}
+
+/* bypass the default SSL_AuthCertificate() hook in case we do not want to
+ * verify peer */
+static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
+                                    PRBool isServer)
+{
+  struct connectdata *conn = (struct connectdata *)arg;
+
+#ifdef SSL_ENABLE_OCSP_STAPLING
+  if(conn->data->set.ssl.verifystatus) {
+    SECStatus cacheResult;
+
+    const SECItemArray *csa = SSL_PeerStapledOCSPResponses(fd);
+    if(!csa) {
+      failf(conn->data, "Invalid OCSP response");
+      return SECFailure;
+    }
+
+    if(csa->len == 0) {
+      failf(conn->data, "No OCSP response received");
+      return SECFailure;
+    }
+
+    cacheResult = CERT_CacheOCSPResponseFromSideChannel(
+      CERT_GetDefaultCertDB(), SSL_PeerCertificate(fd),
+      PR_Now(), &csa->items[0], arg
+    );
+
+    if(cacheResult != SECSuccess) {
+      failf(conn->data, "Invalid OCSP response");
+      return cacheResult;
+    }
+  }
+#endif
+
+  if(!conn->data->set.ssl.verifypeer) {
+    infof(conn->data, "skipping SSL peer certificate verification\n");
+    return SECSuccess;
+  }
+
+  return SSL_AuthCertificate(CERT_GetDefaultCertDB(), fd, checksig, isServer);
+}
+
+/**
+ * Inform the application that the handshake is complete.
+ */
+static void HandshakeCallback(PRFileDesc *sock, void *arg)
+{
+  struct connectdata *conn = (struct connectdata*) arg;
+  unsigned int buflenmax = 50;
+  unsigned char buf[50];
+  unsigned int buflen;
+  SSLNextProtoState state;
+
+  if(!conn->data->set.ssl_enable_npn && !conn->data->set.ssl_enable_alpn) {
+    return;
+  }
+
+  if(SSL_GetNextProto(sock, &state, buf, &buflen, buflenmax) == SECSuccess) {
+
+    switch(state) {
+    case SSL_NEXT_PROTO_NO_SUPPORT:
+    case SSL_NEXT_PROTO_NO_OVERLAP:
+      infof(conn->data, "ALPN/NPN, server did not agree to a protocol\n");
+      return;
+#ifdef SSL_ENABLE_ALPN
+    case SSL_NEXT_PROTO_SELECTED:
+      infof(conn->data, "ALPN, server accepted to use %.*s\n", buflen, buf);
+      break;
+#endif
+    case SSL_NEXT_PROTO_NEGOTIATED:
+      infof(conn->data, "NPN, server accepted to use %.*s\n", buflen, buf);
+      break;
+    }
+
+#ifdef USE_NGHTTP2
+    if(buflen == NGHTTP2_PROTO_VERSION_ID_LEN &&
+       !memcmp(NGHTTP2_PROTO_VERSION_ID, buf, NGHTTP2_PROTO_VERSION_ID_LEN)) {
+      conn->negnpn = CURL_HTTP_VERSION_2;
+    }
+    else
+#endif
+    if(buflen == ALPN_HTTP_1_1_LENGTH &&
+       !memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) {
+      conn->negnpn = CURL_HTTP_VERSION_1_1;
+    }
+  }
+}
+
+#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
+static SECStatus CanFalseStartCallback(PRFileDesc *sock, void *client_data,
+                                       PRBool *canFalseStart)
+{
+  struct connectdata *conn = client_data;
+  struct SessionHandle *data = conn->data;
+
+  SSLChannelInfo channelInfo;
+  SSLCipherSuiteInfo cipherInfo;
+
+  SECStatus rv;
+  PRBool negotiatedExtension;
+
+  *canFalseStart = PR_FALSE;
+
+  if(SSL_GetChannelInfo(sock, &channelInfo, sizeof(channelInfo)) != SECSuccess)
+    return SECFailure;
+
+  if(SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
+                            sizeof(cipherInfo)) != SECSuccess)
+    return SECFailure;
+
+  /* Prevent version downgrade attacks from TLS 1.2, and avoid False Start for
+   * TLS 1.3 and later. See https://bugzilla.mozilla.org/show_bug.cgi?id=861310
+   */
+  if(channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_2)
+    goto end;
+
+  /* Only allow ECDHE key exchange algorithm.
+   * See https://bugzilla.mozilla.org/show_bug.cgi?id=952863 */
+  if(cipherInfo.keaType != ssl_kea_ecdh)
+    goto end;
+
+  /* Prevent downgrade attacks on the symmetric cipher. We do not allow CBC
+   * mode due to BEAST, POODLE, and other attacks on the MAC-then-Encrypt
+   * design. See https://bugzilla.mozilla.org/show_bug.cgi?id=1109766 */
+  if(cipherInfo.symCipher != ssl_calg_aes_gcm)
+    goto end;
+
+  /* Enforce ALPN or NPN to do False Start, as an indicator of server
+   * compatibility. */
+  rv = SSL_HandshakeNegotiatedExtension(sock, ssl_app_layer_protocol_xtn,
+                                        &negotiatedExtension);
+  if(rv != SECSuccess || !negotiatedExtension) {
+    rv = SSL_HandshakeNegotiatedExtension(sock, ssl_next_proto_nego_xtn,
+                                          &negotiatedExtension);
+  }
+
+  if(rv != SECSuccess || !negotiatedExtension)
+    goto end;
+
+  *canFalseStart = PR_TRUE;
+
+  infof(data, "Trying TLS False Start\n");
+
+end:
+  return SECSuccess;
+}
+#endif
+
+static void display_cert_info(struct SessionHandle *data,
+                              CERTCertificate *cert)
+{
+  char *subject, *issuer, *common_name;
+  PRExplodedTime printableTime;
+  char timeString[256];
+  PRTime notBefore, notAfter;
+
+  subject = CERT_NameToAscii(&cert->subject);
+  issuer = CERT_NameToAscii(&cert->issuer);
+  common_name = CERT_GetCommonName(&cert->subject);
+  infof(data, "\tsubject: %s\n", subject);
+
+  CERT_GetCertTimes(cert, &notBefore, &notAfter);
+  PR_ExplodeTime(notBefore, PR_GMTParameters, &printableTime);
+  PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
+  infof(data, "\tstart date: %s\n", timeString);
+  PR_ExplodeTime(notAfter, PR_GMTParameters, &printableTime);
+  PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
+  infof(data, "\texpire date: %s\n", timeString);
+  infof(data, "\tcommon name: %s\n", common_name);
+  infof(data, "\tissuer: %s\n", issuer);
+
+  PR_Free(subject);
+  PR_Free(issuer);
+  PR_Free(common_name);
+}
+
+static CURLcode display_conn_info(struct connectdata *conn, PRFileDesc *sock)
+{
+  CURLcode result = CURLE_OK;
+  SSLChannelInfo channel;
+  SSLCipherSuiteInfo suite;
+  CERTCertificate *cert;
+  CERTCertificate *cert2;
+  CERTCertificate *cert3;
+  PRTime now;
+  int i;
+
+  if(SSL_GetChannelInfo(sock, &channel, sizeof channel) ==
+     SECSuccess && channel.length == sizeof channel &&
+     channel.cipherSuite) {
+    if(SSL_GetCipherSuiteInfo(channel.cipherSuite,
+                              &suite, sizeof suite) == SECSuccess) {
+      infof(conn->data, "SSL connection using %s\n", suite.cipherSuiteName);
+    }
+  }
+
+  cert = SSL_PeerCertificate(sock);
+  if(cert) {
+    infof(conn->data, "Server certificate:\n");
+
+    if(!conn->data->set.ssl.certinfo) {
+      display_cert_info(conn->data, cert);
+      CERT_DestroyCertificate(cert);
+    }
+    else {
+      /* Count certificates in chain. */
+      now = PR_Now();
+      i = 1;
+      if(!cert->isRoot) {
+        cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
+        while(cert2) {
+          i++;
+          if(cert2->isRoot) {
+            CERT_DestroyCertificate(cert2);
+            break;
+          }
+          cert3 = CERT_FindCertIssuer(cert2, now, certUsageSSLCA);
+          CERT_DestroyCertificate(cert2);
+          cert2 = cert3;
+        }
+      }
+
+      result = Curl_ssl_init_certinfo(conn->data, i);
+      if(!result) {
+        for(i = 0; cert; cert = cert2) {
+          result = Curl_extract_certinfo(conn, i++, (char *)cert->derCert.data,
+                                         (char *)cert->derCert.data +
+                                                 cert->derCert.len);
+          if(result)
+            break;
+
+          if(cert->isRoot) {
+            CERT_DestroyCertificate(cert);
+            break;
+          }
+
+          cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
+          CERT_DestroyCertificate(cert);
+        }
+      }
+    }
+  }
+
+  return result;
+}
+
+static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
+{
+  struct connectdata *conn = (struct connectdata *)arg;
+  struct SessionHandle *data = conn->data;
+  PRErrorCode err = PR_GetError();
+  CERTCertificate *cert;
+
+  /* remember the cert verification result */
+  data->set.ssl.certverifyresult = err;
+
+  if(err == SSL_ERROR_BAD_CERT_DOMAIN && !data->set.ssl.verifyhost)
+    /* we are asked not to verify the host name */
+    return SECSuccess;
+
+  /* print only info about the cert, the error is printed off the callback */
+  cert = SSL_PeerCertificate(sock);
+  if(cert) {
+    infof(data, "Server certificate:\n");
+    display_cert_info(data, cert);
+    CERT_DestroyCertificate(cert);
+  }
+
+  return SECFailure;
+}
+
+/**
+ *
+ * Check that the Peer certificate's issuer certificate matches the one found
+ * by issuer_nickname.  This is not exactly the way OpenSSL and GNU TLS do the
+ * issuer check, so we provide comments that mimic the OpenSSL
+ * X509_check_issued function (in x509v3/v3_purp.c)
+ */
+static SECStatus check_issuer_cert(PRFileDesc *sock,
+                                   char *issuer_nickname)
+{
+  CERTCertificate *cert, *cert_issuer, *issuer;
+  SECStatus res=SECSuccess;
+  void *proto_win = NULL;
+
+  /*
+    PRArenaPool   *tmpArena = NULL;
+    CERTAuthKeyID *authorityKeyID = NULL;
+    SECITEM       *caname = NULL;
+  */
+
+  cert = SSL_PeerCertificate(sock);
+  cert_issuer = CERT_FindCertIssuer(cert, PR_Now(), certUsageObjectSigner);
+
+  proto_win = SSL_RevealPinArg(sock);
+  issuer = PK11_FindCertFromNickname(issuer_nickname, proto_win);
+
+  if((!cert_issuer) || (!issuer))
+    res = SECFailure;
+  else if(SECITEM_CompareItem(&cert_issuer->derCert,
+                              &issuer->derCert)!=SECEqual)
+    res = SECFailure;
+
+  CERT_DestroyCertificate(cert);
+  CERT_DestroyCertificate(issuer);
+  CERT_DestroyCertificate(cert_issuer);
+  return res;
+}
+
+static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
+                                const char *pinnedpubkey)
+{
+  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+  struct SessionHandle *data = connssl->data;
+  CERTCertificate *cert;
+
+  if(!pinnedpubkey)
+    /* no pinned public key specified */
+    return CURLE_OK;
+
+  /* get peer certificate */
+  cert = SSL_PeerCertificate(connssl->handle);
+  if(cert) {
+    /* extract public key from peer certificate */
+    SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert);
+    if(pubkey) {
+      /* encode the public key as DER */
+      SECItem *cert_der = PK11_DEREncodePublicKey(pubkey);
+      if(cert_der) {
+        /* compare the public key with the pinned public key */
+        result = Curl_pin_peer_pubkey(data, pinnedpubkey, cert_der->data,
+                                      cert_der->len);
+        SECITEM_FreeItem(cert_der, PR_TRUE);
+      }
+      SECKEY_DestroyPublicKey(pubkey);
+    }
+    CERT_DestroyCertificate(cert);
+  }
+
+  /* report the resulting status */
+  switch(result) {
+  case CURLE_OK:
+    infof(data, "pinned public key verified successfully!\n");
+    break;
+  case CURLE_SSL_PINNEDPUBKEYNOTMATCH:
+    failf(data, "failed to verify pinned public key");
+    break;
+  default:
+    /* OOM, etc. */
+    break;
+  }
+
+  return result;
+}
+
+/**
+ *
+ * Callback to pick the SSL client certificate.
+ */
+static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
+                                  struct CERTDistNamesStr *caNames,
+                                  struct CERTCertificateStr **pRetCert,
+                                  struct SECKEYPrivateKeyStr **pRetKey)
+{
+  struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
+  struct SessionHandle *data = connssl->data;
+  const char *nickname = connssl->client_nickname;
+
+  if(connssl->obj_clicert) {
+    /* use the cert/key provided by PEM reader */
+    static const char pem_slotname[] = "PEM Token #1";
+    SECItem cert_der = { 0, NULL, 0 };
+    void *proto_win = SSL_RevealPinArg(sock);
+    struct CERTCertificateStr *cert;
+    struct SECKEYPrivateKeyStr *key;
+
+    PK11SlotInfo *slot = PK11_FindSlotByName(pem_slotname);
+    if(NULL == slot) {
+      failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
+      return SECFailure;
+    }
+
+    if(PK11_ReadRawAttribute(PK11_TypeGeneric, connssl->obj_clicert, CKA_VALUE,
+                             &cert_der) != SECSuccess) {
+      failf(data, "NSS: CKA_VALUE not found in PK11 generic object");
+      PK11_FreeSlot(slot);
+      return SECFailure;
+    }
+
+    cert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win);
+    SECITEM_FreeItem(&cert_der, PR_FALSE);
+    if(NULL == cert) {
+      failf(data, "NSS: client certificate from file not found");
+      PK11_FreeSlot(slot);
+      return SECFailure;
+    }
+
+    key = PK11_FindPrivateKeyFromCert(slot, cert, NULL);
+    PK11_FreeSlot(slot);
+    if(NULL == key) {
+      failf(data, "NSS: private key from file not found");
+      CERT_DestroyCertificate(cert);
+      return SECFailure;
+    }
+
+    infof(data, "NSS: client certificate from file\n");
+    display_cert_info(data, cert);
+
+    *pRetCert = cert;
+    *pRetKey = key;
+    return SECSuccess;
+  }
+
+  /* use the default NSS hook */
+  if(SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
+                                          pRetCert, pRetKey)
+      || NULL == *pRetCert) {
+
+    if(NULL == nickname)
+      failf(data, "NSS: client certificate not found (nickname not "
+            "specified)");
+    else
+      failf(data, "NSS: client certificate not found: %s", nickname);
+
+    return SECFailure;
+  }
+
+  /* get certificate nickname if any */
+  nickname = (*pRetCert)->nickname;
+  if(NULL == nickname)
+    nickname = "[unknown]";
+
+  if(NULL == *pRetKey) {
+    failf(data, "NSS: private key not found for certificate: %s", nickname);
+    return SECFailure;
+  }
+
+  infof(data, "NSS: using client certificate: %s\n", nickname);
+  display_cert_info(data, *pRetCert);
+  return SECSuccess;
+}
+
+/* update blocking direction in case of PR_WOULD_BLOCK_ERROR */
+static void nss_update_connecting_state(ssl_connect_state state, void *secret)
+{
+  struct ssl_connect_data *connssl = (struct ssl_connect_data *)secret;
+  if(PR_GetError() != PR_WOULD_BLOCK_ERROR)
+    /* an unrelated error is passing by */
+    return;
+
+  switch(connssl->connecting_state) {
+  case ssl_connect_2:
+  case ssl_connect_2_reading:
+  case ssl_connect_2_writing:
+    break;
+  default:
+    /* we are not called from an SSL handshake */
+    return;
+  }
+
+  /* update the state accordingly */
+  connssl->connecting_state = state;
+}
+
+/* recv() wrapper we use to detect blocking direction during SSL handshake */
+static PRInt32 nspr_io_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
+                            PRIntn flags, PRIntervalTime timeout)
+{
+  const PRRecvFN recv_fn = fd->lower->methods->recv;
+  const PRInt32 rv = recv_fn(fd->lower, buf, amount, flags, timeout);
+  if(rv < 0)
+    /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */
+    nss_update_connecting_state(ssl_connect_2_reading, fd->secret);
+  return rv;
+}
+
+/* send() wrapper we use to detect blocking direction during SSL handshake */
+static PRInt32 nspr_io_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
+                            PRIntn flags, PRIntervalTime timeout)
+{
+  const PRSendFN send_fn = fd->lower->methods->send;
+  const PRInt32 rv = send_fn(fd->lower, buf, amount, flags, timeout);
+  if(rv < 0)
+    /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */
+    nss_update_connecting_state(ssl_connect_2_writing, fd->secret);
+  return rv;
+}
+
+/* close() wrapper to avoid assertion failure due to fd->secret != NULL */
+static PRStatus nspr_io_close(PRFileDesc *fd)
+{
+  const PRCloseFN close_fn = PR_GetDefaultIOMethods()->close;
+  fd->secret = NULL;
+  return close_fn(fd);
+}
+
+/* data might be NULL */
+static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
+{
+  NSSInitParameters initparams;
+
+  if(nss_context != NULL)
+    return CURLE_OK;
+
+  memset((void *) &initparams, '\0', sizeof(initparams));
+  initparams.length = sizeof(initparams);
+
+  if(cert_dir) {
+    char *certpath = aprintf("sql:%s", cert_dir);
+    if(!certpath)
+      return CURLE_OUT_OF_MEMORY;
+
+    infof(data, "Initializing NSS with certpath: %s\n", certpath);
+    nss_context = NSS_InitContext(certpath, "", "", "", &initparams,
+            NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
+    free(certpath);
+
+    if(nss_context != NULL)
+      return CURLE_OK;
+
+    infof(data, "Unable to initialize NSS database\n");
+  }
+
+  infof(data, "Initializing NSS with certpath: none\n");
+  nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY
+         | NSS_INIT_NOCERTDB   | NSS_INIT_NOMODDB       | NSS_INIT_FORCEOPEN
+         | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
+  if(nss_context != NULL)
+    return CURLE_OK;
+
+  infof(data, "Unable to initialize NSS\n");
+  return CURLE_SSL_CACERT_BADFILE;
+}
+
+/* data might be NULL */
+static CURLcode nss_init(struct SessionHandle *data)
+{
+  char *cert_dir;
+  struct_stat st;
+  CURLcode result;
+
+  if(initialized)
+    return CURLE_OK;
+
+  /* list of all CRL items we need to destroy in Curl_nss_cleanup() */
+  nss_crl_list = Curl_llist_alloc(nss_destroy_crl_item);
+  if(!nss_crl_list)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* First we check if $SSL_DIR points to a valid dir */
+  cert_dir = getenv("SSL_DIR");
+  if(cert_dir) {
+    if((stat(cert_dir, &st) != 0) ||
+        (!S_ISDIR(st.st_mode))) {
+      cert_dir = NULL;
+    }
+  }
+
+  /* Now we check if the default location is a valid dir */
+  if(!cert_dir) {
+    if((stat(SSL_DIR, &st) == 0) &&
+        (S_ISDIR(st.st_mode))) {
+      cert_dir = (char *)SSL_DIR;
+    }
+  }
+
+  if(nspr_io_identity == PR_INVALID_IO_LAYER) {
+    /* allocate an identity for our own NSPR I/O layer */
+    nspr_io_identity = PR_GetUniqueIdentity("libcurl");
+    if(nspr_io_identity == PR_INVALID_IO_LAYER)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* the default methods just call down to the lower I/O layer */
+    memcpy(&nspr_io_methods, PR_GetDefaultIOMethods(), sizeof nspr_io_methods);
+
+    /* override certain methods in the table by our wrappers */
+    nspr_io_methods.recv  = nspr_io_recv;
+    nspr_io_methods.send  = nspr_io_send;
+    nspr_io_methods.close = nspr_io_close;
+  }
+
+  result = nss_init_core(data, cert_dir);
+  if(result)
+    return result;
+
+  if(num_enabled_ciphers() == 0)
+    NSS_SetDomesticPolicy();
+
+  initialized = 1;
+
+  return CURLE_OK;
+}
+
+/**
+ * Global SSL init
+ *
+ * @retval 0 error initializing SSL
+ * @retval 1 SSL initialized successfully
+ */
+int Curl_nss_init(void)
+{
+  /* curl_global_init() is not thread-safe so this test is ok */
+  if(nss_initlock == NULL) {
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
+    nss_initlock = PR_NewLock();
+    nss_crllock = PR_NewLock();
+  }
+
+  /* We will actually initialize NSS later */
+
+  return 1;
+}
+
+/* data might be NULL */
+CURLcode Curl_nss_force_init(struct SessionHandle *data)
+{
+  CURLcode result;
+  if(!nss_initlock) {
+    if(data)
+      failf(data, "unable to initialize NSS, curl_global_init() should have "
+                  "been called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL");
+    return CURLE_FAILED_INIT;
+  }
+
+  PR_Lock(nss_initlock);
+  result = nss_init(data);
+  PR_Unlock(nss_initlock);
+
+  return result;
+}
+
+/* Global cleanup */
+void Curl_nss_cleanup(void)
+{
+  /* This function isn't required to be threadsafe and this is only done
+   * as a safety feature.
+   */
+  PR_Lock(nss_initlock);
+  if(initialized) {
+    /* Free references to client certificates held in the SSL session cache.
+     * Omitting this hampers destruction of the security module owning
+     * the certificates. */
+    SSL_ClearSessionCache();
+
+    if(mod && SECSuccess == SECMOD_UnloadUserModule(mod)) {
+      SECMOD_DestroyModule(mod);
+      mod = NULL;
+    }
+    NSS_ShutdownContext(nss_context);
+    nss_context = NULL;
+  }
+
+  /* destroy all CRL items */
+  Curl_llist_destroy(nss_crl_list, NULL);
+  nss_crl_list = NULL;
+
+  PR_Unlock(nss_initlock);
+
+  PR_DestroyLock(nss_initlock);
+  PR_DestroyLock(nss_crllock);
+  nss_initlock = NULL;
+
+  initialized = 0;
+}
+
+/*
+ * This function uses SSL_peek to determine connection status.
+ *
+ * Return codes:
+ *     1 means the connection is still in place
+ *     0 means the connection has been closed
+ *    -1 means the connection status is unknown
+ */
+int
+Curl_nss_check_cxn(struct connectdata *conn)
+{
+  int rc;
+  char buf;
+
+  rc =
+    PR_Recv(conn->ssl[FIRSTSOCKET].handle, (void *)&buf, 1, PR_MSG_PEEK,
+            PR_SecondsToInterval(1));
+  if(rc > 0)
+    return 1; /* connection still in place */
+
+  if(rc == 0)
+    return 0; /* connection has been closed */
+
+  return -1;  /* connection status unknown */
+}
+
+/*
+ * This function is called when an SSL connection is closed.
+ */
+void Curl_nss_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  if(connssl->handle) {
+    /* NSS closes the socket we previously handed to it, so we must mark it
+       as closed to avoid double close */
+    fake_sclose(conn->sock[sockindex]);
+    conn->sock[sockindex] = CURL_SOCKET_BAD;
+
+    if((connssl->client_nickname != NULL) || (connssl->obj_clicert != NULL))
+      /* A server might require different authentication based on the
+       * particular path being requested by the client.  To support this
+       * scenario, we must ensure that a connection will never reuse the
+       * authentication data from a previous connection. */
+      SSL_InvalidateSession(connssl->handle);
+
+    free(connssl->client_nickname);
+    connssl->client_nickname = NULL;
+    /* destroy all NSS objects in order to avoid failure of NSS shutdown */
+    Curl_llist_destroy(connssl->obj_list, NULL);
+    connssl->obj_list = NULL;
+    connssl->obj_clicert = NULL;
+
+    PR_Close(connssl->handle);
+    connssl->handle = NULL;
+  }
+}
+
+/* return true if NSS can provide error code (and possibly msg) for the
+   error */
+static bool is_nss_error(CURLcode err)
+{
+  switch(err) {
+  case CURLE_PEER_FAILED_VERIFICATION:
+  case CURLE_SSL_CACERT:
+  case CURLE_SSL_CERTPROBLEM:
+  case CURLE_SSL_CONNECT_ERROR:
+  case CURLE_SSL_ISSUER_ERROR:
+    return true;
+
+  default:
+    return false;
+  }
+}
+
+/* return true if the given error code is related to a client certificate */
+static bool is_cc_error(PRInt32 err)
+{
+  switch(err) {
+  case SSL_ERROR_BAD_CERT_ALERT:
+  case SSL_ERROR_EXPIRED_CERT_ALERT:
+  case SSL_ERROR_REVOKED_CERT_ALERT:
+    return true;
+
+  default:
+    return false;
+  }
+}
+
+static Curl_recv nss_recv;
+static Curl_send nss_send;
+
+static CURLcode nss_load_ca_certificates(struct connectdata *conn,
+                                         int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  const char *cafile = data->set.ssl.CAfile;
+  const char *capath = data->set.ssl.CApath;
+
+  if(cafile) {
+    CURLcode result = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE);
+    if(result)
+      return result;
+  }
+
+  if(capath) {
+    struct_stat st;
+    if(stat(capath, &st) == -1)
+      return CURLE_SSL_CACERT_BADFILE;
+
+    if(S_ISDIR(st.st_mode)) {
+      PRDirEntry *entry;
+      PRDir *dir = PR_OpenDir(capath);
+      if(!dir)
+        return CURLE_SSL_CACERT_BADFILE;
+
+      while((entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN))) {
+        char *fullpath = aprintf("%s/%s", capath, entry->name);
+        if(!fullpath) {
+          PR_CloseDir(dir);
+          return CURLE_OUT_OF_MEMORY;
+        }
+
+        if(CURLE_OK != nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE))
+          /* This is purposefully tolerant of errors so non-PEM files can
+           * be in the same directory */
+          infof(data, "failed to load '%s' from CURLOPT_CAPATH\n", fullpath);
+
+        free(fullpath);
+      }
+
+      PR_CloseDir(dir);
+    }
+    else
+      infof(data, "warning: CURLOPT_CAPATH not a directory (%s)\n", capath);
+  }
+
+  infof(data, "  CAfile: %s\n  CApath: %s\n",
+      cafile ? cafile : "none",
+      capath ? capath : "none");
+
+  return CURLE_OK;
+}
+
+static CURLcode nss_init_sslver(SSLVersionRange *sslver,
+                                struct SessionHandle *data)
+{
+  switch(data->set.ssl.version) {
+  default:
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+    sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+#ifdef SSL_LIBRARY_VERSION_TLS_1_2
+    sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
+#elif defined SSL_LIBRARY_VERSION_TLS_1_1
+    sslver->max = SSL_LIBRARY_VERSION_TLS_1_1;
+#else
+    sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
+#endif
+    return CURLE_OK;
+
+  case CURL_SSLVERSION_SSLv2:
+    sslver->min = SSL_LIBRARY_VERSION_2;
+    sslver->max = SSL_LIBRARY_VERSION_2;
+    return CURLE_OK;
+
+  case CURL_SSLVERSION_SSLv3:
+    sslver->min = SSL_LIBRARY_VERSION_3_0;
+    sslver->max = SSL_LIBRARY_VERSION_3_0;
+    return CURLE_OK;
+
+  case CURL_SSLVERSION_TLSv1_0:
+    sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+    sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
+    return CURLE_OK;
+
+  case CURL_SSLVERSION_TLSv1_1:
+#ifdef SSL_LIBRARY_VERSION_TLS_1_1
+    sslver->min = SSL_LIBRARY_VERSION_TLS_1_1;
+    sslver->max = SSL_LIBRARY_VERSION_TLS_1_1;
+    return CURLE_OK;
+#endif
+    break;
+
+  case CURL_SSLVERSION_TLSv1_2:
+#ifdef SSL_LIBRARY_VERSION_TLS_1_2
+    sslver->min = SSL_LIBRARY_VERSION_TLS_1_2;
+    sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
+    return CURLE_OK;
+#endif
+    break;
+  }
+
+  failf(data, "TLS minor version cannot be set");
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
+                                 struct SessionHandle *data,
+                                 CURLcode curlerr)
+{
+  PRErrorCode err = 0;
+
+  if(is_nss_error(curlerr)) {
+    /* read NSPR error code */
+    err = PR_GetError();
+    if(is_cc_error(err))
+      curlerr = CURLE_SSL_CERTPROBLEM;
+
+    /* print the error number and error string */
+    infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err));
+
+    /* print a human-readable message describing the error if available */
+    nss_print_error_message(data, err);
+  }
+
+  /* cleanup on connection failure */
+  Curl_llist_destroy(connssl->obj_list, NULL);
+  connssl->obj_list = NULL;
+
+  return curlerr;
+}
+
+/* Switch the SSL socket into non-blocking mode. */
+static CURLcode nss_set_nonblock(struct ssl_connect_data *connssl,
+                                 struct SessionHandle *data)
+{
+  static PRSocketOptionData sock_opt;
+  sock_opt.option = PR_SockOpt_Nonblocking;
+  sock_opt.value.non_blocking = PR_TRUE;
+
+  if(PR_SetSocketOption(connssl->handle, &sock_opt) != PR_SUCCESS)
+    return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR);
+
+  return CURLE_OK;
+}
+
+static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
+{
+  PRFileDesc *model = NULL;
+  PRFileDesc *nspr_io = NULL;
+  PRFileDesc *nspr_io_stub = NULL;
+  PRBool ssl_no_cache;
+  PRBool ssl_cbc_random_iv;
+  struct SessionHandle *data = conn->data;
+  curl_socket_t sockfd = conn->sock[sockindex];
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  CURLcode result;
+
+  SSLVersionRange sslver = {
+    SSL_LIBRARY_VERSION_TLS_1_0,  /* min */
+    SSL_LIBRARY_VERSION_TLS_1_0   /* max */
+  };
+
+  connssl->data = data;
+
+  /* list of all NSS objects we need to destroy in Curl_nss_close() */
+  connssl->obj_list = Curl_llist_alloc(nss_destroy_object);
+  if(!connssl->obj_list)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* FIXME. NSS doesn't support multiple databases open at the same time. */
+  PR_Lock(nss_initlock);
+  result = nss_init(conn->data);
+  if(result) {
+    PR_Unlock(nss_initlock);
+    goto error;
+  }
+
+  result = CURLE_SSL_CONNECT_ERROR;
+
+  if(!mod) {
+    char *configstring = aprintf("library=%s name=PEM", pem_library);
+    if(!configstring) {
+      PR_Unlock(nss_initlock);
+      goto error;
+    }
+    mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE);
+    free(configstring);
+
+    if(!mod || !mod->loaded) {
+      if(mod) {
+        SECMOD_DestroyModule(mod);
+        mod = NULL;
+      }
+      infof(data, "WARNING: failed to load NSS PEM library %s. Using "
+                  "OpenSSL PEM certificates will not work.\n", pem_library);
+    }
+  }
+
+  PK11_SetPasswordFunc(nss_get_password);
+  PR_Unlock(nss_initlock);
+
+  model = PR_NewTCPSocket();
+  if(!model)
+    goto error;
+  model = SSL_ImportFD(NULL, model);
+
+  if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess)
+    goto error;
+  if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess)
+    goto error;
+  if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess)
+    goto error;
+
+  /* do not use SSL cache if disabled or we are not going to verify peer */
+  ssl_no_cache = (conn->ssl_config.sessionid && data->set.ssl.verifypeer) ?
+    PR_FALSE : PR_TRUE;
+  if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
+    goto error;
+
+  /* enable/disable the requested SSL version(s) */
+  if(nss_init_sslver(&sslver, data) != CURLE_OK)
+    goto error;
+  if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
+    goto error;
+
+  ssl_cbc_random_iv = !data->set.ssl_enable_beast;
+#ifdef SSL_CBC_RANDOM_IV
+  /* unless the user explicitly asks to allow the protocol vulnerability, we
+     use the work-around */
+  if(SSL_OptionSet(model, SSL_CBC_RANDOM_IV, ssl_cbc_random_iv) != SECSuccess)
+    infof(data, "warning: failed to set SSL_CBC_RANDOM_IV = %d\n",
+          ssl_cbc_random_iv);
+#else
+  if(ssl_cbc_random_iv)
+    infof(data, "warning: support for SSL_CBC_RANDOM_IV not compiled in\n");
+#endif
+
+  if(data->set.ssl.cipher_list) {
+    if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) {
+      result = CURLE_SSL_CIPHER;
+      goto error;
+    }
+  }
+
+  if(!data->set.ssl.verifypeer && data->set.ssl.verifyhost)
+    infof(data, "warning: ignoring value of ssl.verifyhost\n");
+
+  /* bypass the default SSL_AuthCertificate() hook in case we do not want to
+   * verify peer */
+  if(SSL_AuthCertificateHook(model, nss_auth_cert_hook, conn) != SECSuccess)
+    goto error;
+
+  data->set.ssl.certverifyresult=0; /* not checked yet */
+  if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess)
+    goto error;
+
+  if(SSL_HandshakeCallback(model, HandshakeCallback, conn) != SECSuccess)
+    goto error;
+
+  if(data->set.ssl.verifypeer) {
+    const CURLcode rv = nss_load_ca_certificates(conn, sockindex);
+    if(rv) {
+      result = rv;
+      goto error;
+    }
+  }
+
+  if(data->set.ssl.CRLfile) {
+    const CURLcode rv = nss_load_crl(data->set.ssl.CRLfile);
+    if(rv) {
+      result = rv;
+      goto error;
+    }
+    infof(data, "  CRLfile: %s\n", data->set.ssl.CRLfile);
+  }
+
+  if(data->set.str[STRING_CERT]) {
+    char *nickname = dup_nickname(data, STRING_CERT);
+    if(nickname) {
+      /* we are not going to use libnsspem.so to read the client cert */
+      connssl->obj_clicert = NULL;
+    }
+    else {
+      CURLcode rv = cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
+                               data->set.str[STRING_KEY]);
+      if(rv) {
+        /* failf() is already done in cert_stuff() */
+        result = rv;
+        goto error;
+      }
+    }
+
+    /* store the nickname for SelectClientCert() called during handshake */
+    connssl->client_nickname = nickname;
+  }
+  else
+    connssl->client_nickname = NULL;
+
+  if(SSL_GetClientAuthDataHook(model, SelectClientCert,
+                               (void *)connssl) != SECSuccess) {
+    result = CURLE_SSL_CERTPROBLEM;
+    goto error;
+  }
+
+  /* wrap OS file descriptor by NSPR's file descriptor abstraction */
+  nspr_io = PR_ImportTCPSocket(sockfd);
+  if(!nspr_io)
+    goto error;
+
+  /* create our own NSPR I/O layer */
+  nspr_io_stub = PR_CreateIOLayerStub(nspr_io_identity, &nspr_io_methods);
+  if(!nspr_io_stub) {
+    PR_Close(nspr_io);
+    goto error;
+  }
+
+  /* make the per-connection data accessible from NSPR I/O callbacks */
+  nspr_io_stub->secret = (void *)connssl;
+
+  /* push our new layer to the NSPR I/O stack */
+  if(PR_PushIOLayer(nspr_io, PR_TOP_IO_LAYER, nspr_io_stub) != PR_SUCCESS) {
+    PR_Close(nspr_io);
+    PR_Close(nspr_io_stub);
+    goto error;
+  }
+
+  /* import our model socket onto the current I/O stack */
+  connssl->handle = SSL_ImportFD(model, nspr_io);
+  if(!connssl->handle) {
+    PR_Close(nspr_io);
+    goto error;
+  }
+
+  PR_Close(model); /* We don't need this any more */
+  model = NULL;
+
+  /* This is the password associated with the cert that we're using */
+  if(data->set.str[STRING_KEY_PASSWD]) {
+    SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]);
+  }
+
+#ifdef SSL_ENABLE_OCSP_STAPLING
+  if(data->set.ssl.verifystatus) {
+    if(SSL_OptionSet(connssl->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
+        != SECSuccess)
+      goto error;
+  }
+#endif
+
+#ifdef SSL_ENABLE_NPN
+  if(SSL_OptionSet(connssl->handle, SSL_ENABLE_NPN, data->set.ssl_enable_npn
+        ? PR_TRUE : PR_FALSE) != SECSuccess)
+    goto error;
+#endif
+
+#ifdef SSL_ENABLE_ALPN
+  if(SSL_OptionSet(connssl->handle, SSL_ENABLE_ALPN, data->set.ssl_enable_alpn
+        ? PR_TRUE : PR_FALSE) != SECSuccess)
+    goto error;
+#endif
+
+#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
+  if(data->set.ssl.falsestart) {
+    if(SSL_OptionSet(connssl->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
+        != SECSuccess)
+      goto error;
+
+    if(SSL_SetCanFalseStartCallback(connssl->handle, CanFalseStartCallback,
+        conn) != SECSuccess)
+      goto error;
+  }
+#endif
+
+#if defined(SSL_ENABLE_NPN) || defined(SSL_ENABLE_ALPN)
+  if(data->set.ssl_enable_npn || data->set.ssl_enable_alpn) {
+    int cur = 0;
+    unsigned char protocols[128];
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
+      protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
+      memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
+          NGHTTP2_PROTO_VERSION_ID_LEN);
+      cur += NGHTTP2_PROTO_VERSION_ID_LEN;
+    }
+#endif
+    protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
+    memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
+    cur += ALPN_HTTP_1_1_LENGTH;
+
+    if(SSL_SetNextProtoNego(connssl->handle, protocols, cur) != SECSuccess)
+      goto error;
+  }
+#endif
+
+
+  /* Force handshake on next I/O */
+  if(SSL_ResetHandshake(connssl->handle, /* asServer */ PR_FALSE)
+      != SECSuccess)
+    goto error;
+
+  /* propagate hostname to the TLS layer */
+  if(SSL_SetURL(connssl->handle, conn->host.name) != SECSuccess)
+    goto error;
+
+  /* prevent NSS from re-using the session for a different hostname */
+  if(SSL_SetSockPeerID(connssl->handle, conn->host.name) != SECSuccess)
+    goto error;
+
+  return CURLE_OK;
+
+error:
+  if(model)
+    PR_Close(model);
+
+  return nss_fail_connect(connssl, data, result);
+}
+
+static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct SessionHandle *data = conn->data;
+  CURLcode result = CURLE_SSL_CONNECT_ERROR;
+  PRUint32 timeout;
+
+  /* check timeout situation */
+  const long time_left = Curl_timeleft(data, NULL, TRUE);
+  if(time_left < 0L) {
+    failf(data, "timed out before SSL handshake");
+    result = CURLE_OPERATION_TIMEDOUT;
+    goto error;
+  }
+
+  /* Force the handshake now */
+  timeout = PR_MillisecondsToInterval((PRUint32) time_left);
+  if(SSL_ForceHandshakeWithTimeout(connssl->handle, timeout) != SECSuccess) {
+    if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
+      /* blocking direction is updated by nss_update_connecting_state() */
+      return CURLE_AGAIN;
+    else if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
+      result = CURLE_PEER_FAILED_VERIFICATION;
+    else if(conn->data->set.ssl.certverifyresult!=0)
+      result = CURLE_SSL_CACERT;
+    goto error;
+  }
+
+  result = display_conn_info(conn, connssl->handle);
+  if(result)
+    goto error;
+
+  if(data->set.str[STRING_SSL_ISSUERCERT]) {
+    SECStatus ret = SECFailure;
+    char *nickname = dup_nickname(data, STRING_SSL_ISSUERCERT);
+    if(nickname) {
+      /* we support only nicknames in case of STRING_SSL_ISSUERCERT for now */
+      ret = check_issuer_cert(connssl->handle, nickname);
+      free(nickname);
+    }
+
+    if(SECFailure == ret) {
+      infof(data, "SSL certificate issuer check failed\n");
+      result = CURLE_SSL_ISSUER_ERROR;
+      goto error;
+    }
+    else {
+      infof(data, "SSL certificate issuer check ok\n");
+    }
+  }
+
+  result = cmp_peer_pubkey(connssl, data->set.str[STRING_SSL_PINNEDPUBLICKEY]);
+  if(result)
+    /* status already printed */
+    goto error;
+
+  return CURLE_OK;
+
+error:
+  return nss_fail_connect(connssl, data, result);
+}
+
+static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
+                                   bool *done)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct SessionHandle *data = conn->data;
+  const bool blocking = (done == NULL);
+  CURLcode result;
+
+  if(connssl->state == ssl_connection_complete)
+    return CURLE_OK;
+
+  if(connssl->connecting_state == ssl_connect_1) {
+    result = nss_setup_connect(conn, sockindex);
+    if(result)
+      /* we do not expect CURLE_AGAIN from nss_setup_connect() */
+      return result;
+
+    if(!blocking) {
+      /* in non-blocking mode, set NSS non-blocking mode before handshake */
+      result = nss_set_nonblock(connssl, data);
+      if(result)
+        return result;
+    }
+
+    connssl->connecting_state = ssl_connect_2;
+  }
+
+  result = nss_do_connect(conn, sockindex);
+  switch(result) {
+  case CURLE_OK:
+    break;
+  case CURLE_AGAIN:
+    if(!blocking)
+      /* CURLE_AGAIN in non-blocking mode is not an error */
+      return CURLE_OK;
+    /* fall through */
+  default:
+    return result;
+  }
+
+  if(blocking) {
+    /* in blocking mode, set NSS non-blocking mode _after_ SSL handshake */
+    result = nss_set_nonblock(connssl, data);
+    if(result)
+      return result;
+  }
+  else
+    /* signal completed SSL handshake */
+    *done = TRUE;
+
+  connssl->state = ssl_connection_complete;
+  conn->recv[sockindex] = nss_recv;
+  conn->send[sockindex] = nss_send;
+
+  /* ssl_connect_done is never used outside, go back to the initial state */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
+{
+  return nss_connect_common(conn, sockindex, /* blocking */ NULL);
+}
+
+CURLcode Curl_nss_connect_nonblocking(struct connectdata *conn,
+                                      int sockindex, bool *done)
+{
+  return nss_connect_common(conn, sockindex, done);
+}
+
+static ssize_t nss_send(struct connectdata *conn,  /* connection data */
+                        int sockindex,             /* socketindex */
+                        const void *mem,           /* send this data */
+                        size_t len,                /* amount to write */
+                        CURLcode *curlcode)
+{
+  ssize_t rc = PR_Send(conn->ssl[sockindex].handle, mem, (int)len, 0,
+                       PR_INTERVAL_NO_WAIT);
+  if(rc < 0) {
+    PRInt32 err = PR_GetError();
+    if(err == PR_WOULD_BLOCK_ERROR)
+      *curlcode = CURLE_AGAIN;
+    else {
+      /* print the error number and error string */
+      const char *err_name = nss_error_to_name(err);
+      infof(conn->data, "SSL write: error %d (%s)\n", err, err_name);
+
+      /* print a human-readable message describing the error if available */
+      nss_print_error_message(conn->data, err);
+
+      *curlcode = (is_cc_error(err))
+        ? CURLE_SSL_CERTPROBLEM
+        : CURLE_SEND_ERROR;
+    }
+
+    return -1;
+  }
+
+  return rc; /* number of bytes */
+}
+
+static ssize_t nss_recv(struct connectdata * conn, /* connection data */
+                        int num,                   /* socketindex */
+                        char *buf,                 /* store read data here */
+                        size_t buffersize,         /* max amount to read */
+                        CURLcode *curlcode)
+{
+  ssize_t nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0,
+                          PR_INTERVAL_NO_WAIT);
+  if(nread < 0) {
+    /* failed SSL read */
+    PRInt32 err = PR_GetError();
+
+    if(err == PR_WOULD_BLOCK_ERROR)
+      *curlcode = CURLE_AGAIN;
+    else {
+      /* print the error number and error string */
+      const char *err_name = nss_error_to_name(err);
+      infof(conn->data, "SSL read: errno %d (%s)\n", err, err_name);
+
+      /* print a human-readable message describing the error if available */
+      nss_print_error_message(conn->data, err);
+
+      *curlcode = (is_cc_error(err))
+        ? CURLE_SSL_CERTPROBLEM
+        : CURLE_RECV_ERROR;
+    }
+
+    return -1;
+  }
+
+  return nread;
+}
+
+size_t Curl_nss_version(char *buffer, size_t size)
+{
+  return snprintf(buffer, size, "NSS/%s", NSS_VERSION);
+}
+
+/* data might be NULL */
+int Curl_nss_seed(struct SessionHandle *data)
+{
+  /* make sure that NSS is initialized */
+  return !!Curl_nss_force_init(data);
+}
+
+/* data might be NULL */
+int Curl_nss_random(struct SessionHandle *data,
+                    unsigned char *entropy,
+                    size_t length)
+{
+  Curl_nss_seed(data);  /* Initiate the seed if not already done */
+
+  if(SECSuccess != PK11_GenerateRandom(entropy, curlx_uztosi(length)))
+    /* signal a failure */
+    return -1;
+
+  return 0;
+}
+
+void Curl_nss_md5sum(unsigned char *tmp, /* input */
+                     size_t tmplen,
+                     unsigned char *md5sum, /* output */
+                     size_t md5len)
+{
+  PK11Context *MD5pw = PK11_CreateDigestContext(SEC_OID_MD5);
+  unsigned int MD5out;
+
+  PK11_DigestOp(MD5pw, tmp, curlx_uztoui(tmplen));
+  PK11_DigestFinal(MD5pw, md5sum, &MD5out, curlx_uztoui(md5len));
+  PK11_DestroyContext(MD5pw, PR_TRUE);
+}
+
+void Curl_nss_sha256sum(const unsigned char *tmp, /* input */
+                     size_t tmplen,
+                     unsigned char *sha256sum, /* output */
+                     size_t sha256len)
+{
+  PK11Context *SHA256pw = PK11_CreateDigestContext(SEC_OID_SHA256);
+  unsigned int SHA256out;
+
+  PK11_DigestOp(SHA256pw, tmp, curlx_uztoui(tmplen));
+  PK11_DigestFinal(SHA256pw, sha256sum, &SHA256out, curlx_uztoui(sha256len));
+  PK11_DestroyContext(SHA256pw, PR_TRUE);
+}
+
+bool Curl_nss_cert_status_request(void)
+{
+#ifdef SSL_ENABLE_OCSP_STAPLING
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
+bool Curl_nss_false_start(void) {
+#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
+#endif /* USE_NSS */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/nssg.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/nssg.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/nssg.h	(revision 164)
@@ -0,0 +1,102 @@
+#ifndef HEADER_CURL_NSSG_H
+#define HEADER_CURL_NSSG_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_NSS
+/*
+ * This header should only be needed to get included by vtls.c and nss.c
+ */
+
+#include "urldata.h"
+
+CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_nss_connect_nonblocking(struct connectdata *conn,
+                                      int sockindex,
+                                      bool *done);
+/* close a SSL connection */
+void Curl_nss_close(struct connectdata *conn, int sockindex);
+
+int Curl_nss_init(void);
+void Curl_nss_cleanup(void);
+
+size_t Curl_nss_version(char *buffer, size_t size);
+int Curl_nss_check_cxn(struct connectdata *cxn);
+int Curl_nss_seed(struct SessionHandle *data);
+
+/* initialize NSS library if not already */
+CURLcode Curl_nss_force_init(struct SessionHandle *data);
+
+int Curl_nss_random(struct SessionHandle *data,
+                    unsigned char *entropy,
+                    size_t length);
+
+void Curl_nss_md5sum(unsigned char *tmp, /* input */
+                     size_t tmplen,
+                     unsigned char *md5sum, /* output */
+                     size_t md5len);
+
+void Curl_nss_sha256sum(const unsigned char *tmp, /* input */
+                     size_t tmplen,
+                     unsigned char *sha256sum, /* output */
+                     size_t sha256len);
+
+bool Curl_nss_cert_status_request(void);
+
+bool Curl_nss_false_start(void);
+
+/* Set the API backend definition to NSS */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_NSS
+
+/* this backend supports the CAPATH option */
+#define have_curlssl_ca_path 1
+
+/* this backend supports CURLOPT_CERTINFO */
+#define have_curlssl_certinfo 1
+
+/* API setup for NSS */
+#define curlssl_init Curl_nss_init
+#define curlssl_cleanup Curl_nss_cleanup
+#define curlssl_connect Curl_nss_connect
+#define curlssl_connect_nonblocking Curl_nss_connect_nonblocking
+
+/* NSS has its own session ID cache */
+#define curlssl_session_free(x) Curl_nop_stmt
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_nss_close
+/* NSS has no shutdown function provided and thus always fail */
+#define curlssl_shutdown(x,y) ((void)x, (void)y, 1)
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_nss_version
+#define curlssl_check_cxn(x) Curl_nss_check_cxn(x)
+#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
+#define curlssl_random(x,y,z) Curl_nss_random(x,y,z)
+#define curlssl_md5sum(a,b,c,d) Curl_nss_md5sum(a,b,c,d)
+#define curlssl_sha256sum(a,b,c,d) Curl_nss_sha256sum(a,b,c,d)
+#define curlssl_cert_status_request() Curl_nss_cert_status_request()
+#define curlssl_false_start() Curl_nss_false_start()
+
+#endif /* USE_NSS */
+#endif /* HEADER_CURL_NSSG_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/openssl.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/openssl.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/openssl.c	(revision 164)
@@ -0,0 +1,3057 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all OpenSSL-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ */
+
+/*
+ * The original SSLeay-using code for curl was written by Linas Vepstas and
+ * Sampo Kellomaki 1998.
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_OPENSSL
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "formdata.h" /* for the boundary function */
+#include "url.h" /* for the ssl config check function */
+#include "inet_pton.h"
+#include "openssl.h"
+#include "connect.h"
+#include "slist.h"
+#include "strequal.h"
+#include "select.h"
+#include "vtls.h"
+#include "rawstr.h"
+#include "hostcheck.h"
+#include "curl_printf.h"
+
+#include <openssl/ssl.h>
+#include <openssl/rand.h>
+#include <openssl/x509v3.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
+#include <openssl/err.h>
+#include <openssl/md5.h>
+#include <openssl/conf.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+
+#ifdef HAVE_OPENSSL_PKCS12_H
+#include <openssl/pkcs12.h>
+#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_IS_BORINGSSL)
+#include <openssl/ocsp.h>
+#endif
+
+#include "warnless.h"
+#include "non-ascii.h" /* for Curl_convert_from_utf8 prototype */
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef OPENSSL_VERSION_NUMBER
+#error "OPENSSL_VERSION_NUMBER not defined"
+#endif
+
+#if !defined(OPENSSL_IS_BORINGSSL)
+/* ENGINE_load_private_key() takes four arguments */
+#define HAVE_ENGINE_LOAD_FOUR_ARGS
+#include <openssl/ui.h>
+#else
+/* ENGINE_load_private_key() takes three arguments */
+#undef HAVE_ENGINE_LOAD_FOUR_ARGS
+#endif
+
+#if defined(HAVE_OPENSSL_PKCS12_H) && !defined(OPENSSL_IS_BORINGSSL)
+/* OpenSSL has PKCS 12 support, BoringSSL does not */
+#define HAVE_PKCS12_SUPPORT
+#else
+/* OpenSSL does not have PKCS12 support */
+#undef HAVE_PKCS12_SUPPORT
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x00909000L
+#define SSL_METHOD_QUAL const
+#else
+#define SSL_METHOD_QUAL
+#endif
+
+#ifdef OPENSSL_IS_BORINGSSL
+/* BoringSSL has no ERR_remove_state() */
+#define ERR_remove_state(x)
+#elif (OPENSSL_VERSION_NUMBER >= 0x10000000L)
+#define HAVE_ERR_REMOVE_THREAD_STATE 1
+#endif
+
+#if !defined(HAVE_SSLV2_CLIENT_METHOD) || \
+  OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0+ has no SSLv2 */
+#undef OPENSSL_NO_SSL2 /* undef first to avoid compiler warnings */
+#define OPENSSL_NO_SSL2
+#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && /* OpenSSL 1.1.0+ */ \
+  !defined(LIBRESSL_VERSION_NUMBER)
+#define SSLeay_add_ssl_algorithms() SSL_library_init()
+#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER
+#define HAVE_X509_GET0_EXTENSIONS 1 /* added in 1.1.0 -pre1 */
+#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* 1.0.2 or later */ \
+  !defined(LIBRESSL_VERSION_NUMBER)
+#define HAVE_X509_GET0_SIGNATURE 1
+#endif
+
+#if defined(OPENSSL_IS_BORINGSSL)
+#define NO_RAND_SEED 1
+/* In BoringSSL OpenSSL_add_all_algorithms does nothing */
+#define OpenSSL_add_all_algorithms()
+/* BoringSSL does not have CONF_modules_load_file, CONF_modules_free */
+#define CONF_modules_load_file(a,b,c)
+#define CONF_modules_free()
+#endif
+
+#if (OPENSSL_VERSION_NUMBER < 0x0090808fL) || defined(OPENSSL_IS_BORINGSSL)
+/* not present in BoringSSL  or older OpenSSL */
+#define OPENSSL_load_builtin_modules(x)
+#endif
+
+/*
+ * Number of bytes to read from the random number seed file. This must be
+ * a finite value (because some entropy "files" like /dev/urandom have
+ * an infinite length), but must be large enough to provide enough
+ * entopy to properly seed OpenSSL's PRNG.
+ */
+#define RAND_LOAD_LENGTH 1024
+
+static int passwd_callback(char *buf, int num, int encrypting,
+                           void *global_passwd)
+{
+  DEBUGASSERT(0 == encrypting);
+
+  if(!encrypting) {
+    int klen = curlx_uztosi(strlen((char *)global_passwd));
+    if(num > klen) {
+      memcpy(buf, global_passwd, klen+1);
+      return klen;
+    }
+  }
+  return 0;
+}
+
+/*
+ * rand_enough() is a function that returns TRUE if we have seeded the random
+ * engine properly. We use some preprocessor magic to provide a seed_enough()
+ * macro to use, just to prevent a compiler warning on this function if we
+ * pass in an argument that is never used.
+ */
+
+#ifndef NO_RAND_SEED
+#ifdef HAVE_RAND_STATUS
+#define seed_enough(x) rand_enough()
+static bool rand_enough(void)
+{
+  return (0 != RAND_status()) ? TRUE : FALSE;
+}
+#else
+#define seed_enough(x) rand_enough(x)
+static bool rand_enough(int nread)
+{
+  /* this is a very silly decision to make */
+  return (nread > 500) ? TRUE : FALSE;
+}
+#endif
+
+static int ossl_seed(struct SessionHandle *data)
+{
+  char *buf = data->state.buffer; /* point to the big buffer */
+  int nread=0;
+
+  /* Q: should we add support for a random file name as a libcurl option?
+     A: Yes, it is here */
+
+#ifndef RANDOM_FILE
+  /* if RANDOM_FILE isn't defined, we only perform this if an option tells
+     us to! */
+  if(data->set.ssl.random_file)
+#define RANDOM_FILE "" /* doesn't matter won't be used */
+#endif
+  {
+    /* let the option override the define */
+    nread += RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]?
+                             data->set.str[STRING_SSL_RANDOM_FILE]:
+                             RANDOM_FILE),
+                            RAND_LOAD_LENGTH);
+    if(seed_enough(nread))
+      return nread;
+  }
+
+#if defined(HAVE_RAND_EGD)
+  /* only available in OpenSSL 0.9.5 and later */
+  /* EGD_SOCKET is set at configure time or not at all */
+#ifndef EGD_SOCKET
+  /* If we don't have the define set, we only do this if the egd-option
+     is set */
+  if(data->set.str[STRING_SSL_EGDSOCKET])
+#define EGD_SOCKET "" /* doesn't matter won't be used */
+#endif
+  {
+    /* If there's an option and a define, the option overrides the
+       define */
+    int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]?
+                       data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET);
+    if(-1 != ret) {
+      nread += ret;
+      if(seed_enough(nread))
+        return nread;
+    }
+  }
+#endif
+
+  /* If we get here, it means we need to seed the PRNG using a "silly"
+     approach! */
+  do {
+    unsigned char randb[64];
+    int len = sizeof(randb);
+    RAND_bytes(randb, len);
+    RAND_add(randb, len, (len >> 1));
+  } while(!RAND_status());
+
+  /* generates a default path for the random seed file */
+  buf[0]=0; /* blank it first */
+  RAND_file_name(buf, BUFSIZE);
+  if(buf[0]) {
+    /* we got a file name to try */
+    nread += RAND_load_file(buf, RAND_LOAD_LENGTH);
+    if(seed_enough(nread))
+      return nread;
+  }
+
+  infof(data, "libcurl is now using a weak random seed!\n");
+  return nread;
+}
+
+static void Curl_ossl_seed(struct SessionHandle *data)
+{
+  /* we have the "SSL is seeded" boolean static to prevent multiple
+     time-consuming seedings in vain */
+  static bool ssl_seeded = FALSE;
+
+  if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
+     data->set.str[STRING_SSL_EGDSOCKET]) {
+    ossl_seed(data);
+    ssl_seeded = TRUE;
+  }
+}
+#else
+/* BoringSSL needs no seeding */
+#define Curl_ossl_seed(x)
+#endif
+
+
+#ifndef SSL_FILETYPE_ENGINE
+#define SSL_FILETYPE_ENGINE 42
+#endif
+#ifndef SSL_FILETYPE_PKCS12
+#define SSL_FILETYPE_PKCS12 43
+#endif
+static int do_file_type(const char *type)
+{
+  if(!type || !type[0])
+    return SSL_FILETYPE_PEM;
+  if(Curl_raw_equal(type, "PEM"))
+    return SSL_FILETYPE_PEM;
+  if(Curl_raw_equal(type, "DER"))
+    return SSL_FILETYPE_ASN1;
+  if(Curl_raw_equal(type, "ENG"))
+    return SSL_FILETYPE_ENGINE;
+  if(Curl_raw_equal(type, "P12"))
+    return SSL_FILETYPE_PKCS12;
+  return -1;
+}
+
+#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_LOAD_FOUR_ARGS)
+/*
+ * Supply default password to the engine user interface conversation.
+ * The password is passed by OpenSSL engine from ENGINE_load_private_key()
+ * last argument to the ui and can be obtained by UI_get0_user_data(ui) here.
+ */
+static int ssl_ui_reader(UI *ui, UI_STRING *uis)
+{
+  const char *password;
+  switch(UI_get_string_type(uis)) {
+  case UIT_PROMPT:
+  case UIT_VERIFY:
+    password = (const char*)UI_get0_user_data(ui);
+    if(password && (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) {
+      UI_set_result(ui, uis, password);
+      return 1;
+    }
+  default:
+    break;
+  }
+  return (UI_method_get_reader(UI_OpenSSL()))(ui, uis);
+}
+
+/*
+ * Suppress interactive request for a default password if available.
+ */
+static int ssl_ui_writer(UI *ui, UI_STRING *uis)
+{
+  switch(UI_get_string_type(uis)) {
+  case UIT_PROMPT:
+  case UIT_VERIFY:
+    if(UI_get0_user_data(ui) &&
+       (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) {
+      return 1;
+    }
+  default:
+    break;
+  }
+  return (UI_method_get_writer(UI_OpenSSL()))(ui, uis);
+}
+#endif
+
+static
+int cert_stuff(struct connectdata *conn,
+               SSL_CTX* ctx,
+               char *cert_file,
+               const char *cert_type,
+               char *key_file,
+               const char *key_type)
+{
+  struct SessionHandle *data = conn->data;
+
+  int file_type = do_file_type(cert_type);
+
+  if(cert_file || (file_type == SSL_FILETYPE_ENGINE)) {
+    SSL *ssl;
+    X509 *x509;
+    int cert_done = 0;
+
+    if(data->set.str[STRING_KEY_PASSWD]) {
+      /* set the password in the callback userdata */
+      SSL_CTX_set_default_passwd_cb_userdata(ctx,
+                                             data->set.str[STRING_KEY_PASSWD]);
+      /* Set passwd callback: */
+      SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
+    }
+
+
+    switch(file_type) {
+    case SSL_FILETYPE_PEM:
+      /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
+      if(SSL_CTX_use_certificate_chain_file(ctx,
+                                            cert_file) != 1) {
+        failf(data,
+              "could not load PEM client certificate, OpenSSL error %s, "
+              "(no key found, wrong pass phrase, or wrong file format?)",
+              ERR_error_string(ERR_get_error(), NULL) );
+        return 0;
+      }
+      break;
+
+    case SSL_FILETYPE_ASN1:
+      /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
+         we use the case above for PEM so this can only be performed with
+         ASN1 files. */
+      if(SSL_CTX_use_certificate_file(ctx,
+                                      cert_file,
+                                      file_type) != 1) {
+        failf(data,
+              "could not load ASN1 client certificate, OpenSSL error %s, "
+              "(no key found, wrong pass phrase, or wrong file format?)",
+              ERR_error_string(ERR_get_error(), NULL) );
+        return 0;
+      }
+      break;
+    case SSL_FILETYPE_ENGINE:
+#if defined(HAVE_OPENSSL_ENGINE_H) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME)
+      {
+        if(data->state.engine) {
+          const char *cmd_name = "LOAD_CERT_CTRL";
+          struct {
+            const char *cert_id;
+            X509 *cert;
+          } params;
+
+          params.cert_id = cert_file;
+          params.cert = NULL;
+
+          /* Does the engine supports LOAD_CERT_CTRL ? */
+          if(!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME,
+                          0, (void *)cmd_name, NULL)) {
+            failf(data, "ssl engine does not support loading certificates");
+            return 0;
+          }
+
+          /* Load the certificate from the engine */
+          if(!ENGINE_ctrl_cmd(data->state.engine, cmd_name,
+                              0, &params, NULL, 1)) {
+            failf(data, "ssl engine cannot load client cert with id"
+                  " '%s' [%s]", cert_file,
+                  ERR_error_string(ERR_get_error(), NULL));
+            return 0;
+          }
+
+          if(!params.cert) {
+            failf(data, "ssl engine didn't initialized the certificate "
+                  "properly.");
+            return 0;
+          }
+
+          if(SSL_CTX_use_certificate(ctx, params.cert) != 1) {
+            failf(data, "unable to set client certificate");
+            X509_free(params.cert);
+            return 0;
+          }
+          X509_free(params.cert); /* we don't need the handle any more... */
+        }
+        else {
+          failf(data, "crypto engine not set, can't load certificate");
+          return 0;
+        }
+      }
+      break;
+#else
+      failf(data, "file type ENG for certificate not implemented");
+      return 0;
+#endif
+
+    case SSL_FILETYPE_PKCS12:
+    {
+#ifdef HAVE_PKCS12_SUPPORT
+      FILE *f;
+      PKCS12 *p12;
+      EVP_PKEY *pri;
+      STACK_OF(X509) *ca = NULL;
+
+      f = fopen(cert_file, "rb");
+      if(!f) {
+        failf(data, "could not open PKCS12 file '%s'", cert_file);
+        return 0;
+      }
+      p12 = d2i_PKCS12_fp(f, NULL);
+      fclose(f);
+
+      if(!p12) {
+        failf(data, "error reading PKCS12 file '%s'", cert_file);
+        return 0;
+      }
+
+      PKCS12_PBE_add();
+
+      if(!PKCS12_parse(p12, data->set.str[STRING_KEY_PASSWD], &pri, &x509,
+                       &ca)) {
+        failf(data,
+              "could not parse PKCS12 file, check password, OpenSSL error %s",
+              ERR_error_string(ERR_get_error(), NULL) );
+        PKCS12_free(p12);
+        return 0;
+      }
+
+      PKCS12_free(p12);
+
+      if(SSL_CTX_use_certificate(ctx, x509) != 1) {
+        failf(data,
+              "could not load PKCS12 client certificate, OpenSSL error %s",
+              ERR_error_string(ERR_get_error(), NULL) );
+        goto fail;
+      }
+
+      if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) {
+        failf(data, "unable to use private key from PKCS12 file '%s'",
+              cert_file);
+        goto fail;
+      }
+
+      if(!SSL_CTX_check_private_key (ctx)) {
+        failf(data, "private key from PKCS12 file '%s' "
+              "does not match certificate in same file", cert_file);
+        goto fail;
+      }
+      /* Set Certificate Verification chain */
+      if(ca) {
+        while(sk_X509_num(ca)) {
+          /*
+           * Note that sk_X509_pop() is used below to make sure the cert is
+           * removed from the stack properly before getting passed to
+           * SSL_CTX_add_extra_chain_cert(). Previously we used
+           * sk_X509_value() instead, but then we'd clean it in the subsequent
+           * sk_X509_pop_free() call.
+           */
+          X509 *x = sk_X509_pop(ca);
+          if(!SSL_CTX_add_extra_chain_cert(ctx, x)) {
+            X509_free(x);
+            failf(data, "cannot add certificate to certificate chain");
+            goto fail;
+          }
+          /* SSL_CTX_add_client_CA() seems to work with either sk_* function,
+           * presumably because it duplicates what we pass to it.
+           */
+          if(!SSL_CTX_add_client_CA(ctx, x)) {
+            failf(data, "cannot add certificate to client CA list");
+            goto fail;
+          }
+        }
+      }
+
+      cert_done = 1;
+  fail:
+      EVP_PKEY_free(pri);
+      X509_free(x509);
+      sk_X509_pop_free(ca, X509_free);
+
+      if(!cert_done)
+        return 0; /* failure! */
+      break;
+#else
+      failf(data, "file type P12 for certificate not supported");
+      return 0;
+#endif
+    }
+    default:
+      failf(data, "not supported file type '%s' for certificate", cert_type);
+      return 0;
+    }
+
+    file_type = do_file_type(key_type);
+
+    switch(file_type) {
+    case SSL_FILETYPE_PEM:
+      if(cert_done)
+        break;
+      if(!key_file)
+        /* cert & key can only be in PEM case in the same file */
+        key_file=cert_file;
+    case SSL_FILETYPE_ASN1:
+      if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
+        failf(data, "unable to set private key file: '%s' type %s",
+              key_file, key_type?key_type:"PEM");
+        return 0;
+      }
+      break;
+    case SSL_FILETYPE_ENGINE:
+#ifdef HAVE_OPENSSL_ENGINE_H
+      {                         /* XXXX still needs some work */
+        EVP_PKEY *priv_key = NULL;
+        if(data->state.engine) {
+#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
+          UI_METHOD *ui_method =
+            UI_create_method((char *)"cURL user interface");
+          if(!ui_method) {
+            failf(data, "unable do create OpenSSL user-interface method");
+            return 0;
+          }
+          UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL()));
+          UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL()));
+          UI_method_set_reader(ui_method, ssl_ui_reader);
+          UI_method_set_writer(ui_method, ssl_ui_writer);
+#endif
+          /* the typecast below was added to please mingw32 */
+          priv_key = (EVP_PKEY *)
+            ENGINE_load_private_key(data->state.engine, key_file,
+#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
+                                    ui_method,
+#endif
+                                    data->set.str[STRING_KEY_PASSWD]);
+#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
+          UI_destroy_method(ui_method);
+#endif
+          if(!priv_key) {
+            failf(data, "failed to load private key from crypto engine");
+            return 0;
+          }
+          if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) {
+            failf(data, "unable to set private key");
+            EVP_PKEY_free(priv_key);
+            return 0;
+          }
+          EVP_PKEY_free(priv_key);  /* we don't need the handle any more... */
+        }
+        else {
+          failf(data, "crypto engine not set, can't load private key");
+          return 0;
+        }
+      }
+      break;
+#else
+      failf(data, "file type ENG for private key not supported");
+      return 0;
+#endif
+    case SSL_FILETYPE_PKCS12:
+      if(!cert_done) {
+        failf(data, "file type P12 for private key not supported");
+        return 0;
+      }
+      break;
+    default:
+      failf(data, "not supported file type for private key");
+      return 0;
+    }
+
+    ssl=SSL_new(ctx);
+    if(!ssl) {
+      failf(data, "unable to create an SSL structure");
+      return 0;
+    }
+
+    x509=SSL_get_certificate(ssl);
+
+    /* This version was provided by Evan Jordan and is supposed to not
+       leak memory as the previous version: */
+    if(x509) {
+      EVP_PKEY *pktmp = X509_get_pubkey(x509);
+      EVP_PKEY_copy_parameters(pktmp, SSL_get_privatekey(ssl));
+      EVP_PKEY_free(pktmp);
+    }
+
+    SSL_free(ssl);
+
+    /* If we are using DSA, we can copy the parameters from
+     * the private key */
+
+
+    /* Now we know that a key and cert have been set against
+     * the SSL context */
+    if(!SSL_CTX_check_private_key(ctx)) {
+      failf(data, "Private key does not match the certificate public key");
+      return 0;
+    }
+  }
+  return 1;
+}
+
+/* returns non-zero on failure */
+static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
+{
+#if 0
+  return X509_NAME_oneline(a, buf, size);
+#else
+  BIO *bio_out = BIO_new(BIO_s_mem());
+  BUF_MEM *biomem;
+  int rc;
+
+  if(!bio_out)
+    return 1; /* alloc failed! */
+
+  rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_SPLUS_SPC);
+  BIO_get_mem_ptr(bio_out, &biomem);
+
+  if((size_t)biomem->length < size)
+    size = biomem->length;
+  else
+    size--; /* don't overwrite the buffer end */
+
+  memcpy(buf, biomem->data, size);
+  buf[size]=0;
+
+  BIO_free(bio_out);
+
+  return !rc;
+#endif
+}
+
+/* Return error string for last OpenSSL error
+ */
+static char *SSL_strerror(unsigned long error, char *buf, size_t size)
+{
+  /* OpenSSL 0.9.6 and later has a function named
+     ERR_error_string_n() that takes the size of the buffer as a
+     third argument */
+  ERR_error_string_n(error, buf, size);
+  return buf;
+}
+
+/**
+ * Global SSL init
+ *
+ * @retval 0 error initializing SSL
+ * @retval 1 SSL initialized successfully
+ */
+int Curl_ossl_init(void)
+{
+  OPENSSL_load_builtin_modules();
+
+#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
+  ENGINE_load_builtin_engines();
+#endif
+
+  /* OPENSSL_config(NULL); is "strongly recommended" to use but unfortunately
+     that function makes an exit() call on wrongly formatted config files
+     which makes it hard to use in some situations. OPENSSL_config() itself
+     calls CONF_modules_load_file() and we use that instead and we ignore
+     its return code! */
+
+  /* CONF_MFLAGS_DEFAULT_SECTION introduced some time between 0.9.8b and
+     0.9.8e */
+#ifndef CONF_MFLAGS_DEFAULT_SECTION
+#define CONF_MFLAGS_DEFAULT_SECTION 0x0
+#endif
+
+  CONF_modules_load_file(NULL, NULL,
+                         CONF_MFLAGS_DEFAULT_SECTION|
+                         CONF_MFLAGS_IGNORE_MISSING_FILE);
+
+  /* Lets get nice error messages */
+  SSL_load_error_strings();
+
+  /* Init the global ciphers and digests */
+  if(!SSLeay_add_ssl_algorithms())
+    return 0;
+
+  OpenSSL_add_all_algorithms();
+
+  return 1;
+}
+
+/* Global cleanup */
+void Curl_ossl_cleanup(void)
+{
+  /* Free ciphers and digests lists */
+  EVP_cleanup();
+
+#ifdef HAVE_ENGINE_CLEANUP
+  /* Free engine list */
+  ENGINE_cleanup();
+#endif
+
+#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
+  /* Free OpenSSL ex_data table */
+  CRYPTO_cleanup_all_ex_data();
+#endif
+
+  /* Free OpenSSL error strings */
+  ERR_free_strings();
+
+  /* Free thread local error state, destroying hash upon zero refcount */
+#ifdef HAVE_ERR_REMOVE_THREAD_STATE
+  ERR_remove_thread_state(NULL);
+#else
+  ERR_remove_state(0);
+#endif
+
+  /* Free all memory allocated by all configuration modules */
+  CONF_modules_free();
+}
+
+/*
+ * This function uses SSL_peek to determine connection status.
+ *
+ * Return codes:
+ *     1 means the connection is still in place
+ *     0 means the connection has been closed
+ *    -1 means the connection status is unknown
+ */
+int Curl_ossl_check_cxn(struct connectdata *conn)
+{
+  int rc;
+  char buf;
+
+  rc = SSL_peek(conn->ssl[FIRSTSOCKET].handle, (void*)&buf, 1);
+  if(rc > 0)
+    return 1; /* connection still in place */
+
+  if(rc == 0)
+    return 0; /* connection has been closed */
+
+  return -1; /* connection status unknown */
+}
+
+/* Selects an OpenSSL crypto engine
+ */
+CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine)
+{
+#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+  ENGINE *e;
+
+#if OPENSSL_VERSION_NUMBER >= 0x00909000L
+  e = ENGINE_by_id(engine);
+#else
+  /* avoid memory leak */
+  for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
+    const char *e_id = ENGINE_get_id(e);
+    if(!strcmp(engine, e_id))
+      break;
+  }
+#endif
+
+  if(!e) {
+    failf(data, "SSL Engine '%s' not found", engine);
+    return CURLE_SSL_ENGINE_NOTFOUND;
+  }
+
+  if(data->state.engine) {
+    ENGINE_finish(data->state.engine);
+    ENGINE_free(data->state.engine);
+    data->state.engine = NULL;
+  }
+  if(!ENGINE_init(e)) {
+    char buf[256];
+
+    ENGINE_free(e);
+    failf(data, "Failed to initialise SSL Engine '%s':\n%s",
+          engine, SSL_strerror(ERR_get_error(), buf, sizeof(buf)));
+    return CURLE_SSL_ENGINE_INITFAILED;
+  }
+  data->state.engine = e;
+  return CURLE_OK;
+#else
+  (void)engine;
+  failf(data, "SSL Engine not supported");
+  return CURLE_SSL_ENGINE_NOTFOUND;
+#endif
+}
+
+/* Sets engine as default for all SSL operations
+ */
+CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data)
+{
+#ifdef HAVE_OPENSSL_ENGINE_H
+  if(data->state.engine) {
+    if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
+      infof(data, "set default crypto engine '%s'\n",
+            ENGINE_get_id(data->state.engine));
+    }
+    else {
+      failf(data, "set default crypto engine '%s' failed",
+            ENGINE_get_id(data->state.engine));
+      return CURLE_SSL_ENGINE_SETFAILED;
+    }
+  }
+#else
+  (void) data;
+#endif
+  return CURLE_OK;
+}
+
+/* Return list of OpenSSL crypto engine names.
+ */
+struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data)
+{
+  struct curl_slist *list = NULL;
+#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+  struct curl_slist *beg;
+  ENGINE *e;
+
+  for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
+    beg = curl_slist_append(list, ENGINE_get_id(e));
+    if(!beg) {
+      curl_slist_free_all(list);
+      return NULL;
+    }
+    list = beg;
+  }
+#endif
+  (void) data;
+  return list;
+}
+
+
+/*
+ * This function is called when an SSL connection is closed.
+ */
+void Curl_ossl_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  if(connssl->handle) {
+    (void)SSL_shutdown(connssl->handle);
+    SSL_set_connect_state(connssl->handle);
+
+    SSL_free (connssl->handle);
+    connssl->handle = NULL;
+  }
+  if(connssl->ctx) {
+    SSL_CTX_free (connssl->ctx);
+    connssl->ctx = NULL;
+  }
+}
+
+/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
+{
+  int retval = 0;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct SessionHandle *data = conn->data;
+  char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
+                    to be at least 120 bytes long. */
+  unsigned long sslerror;
+  ssize_t nread;
+  int buffsize;
+  int err;
+  int done = 0;
+
+  /* This has only been tested on the proftpd server, and the mod_tls code
+     sends a close notify alert without waiting for a close notify alert in
+     response. Thus we wait for a close notify alert from the server, but
+     we do not send one. Let's hope other servers do the same... */
+
+  if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
+      (void)SSL_shutdown(connssl->handle);
+
+  if(connssl->handle) {
+    buffsize = (int)sizeof(buf);
+    while(!done) {
+      int what = Curl_socket_ready(conn->sock[sockindex],
+                                   CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+      if(what > 0) {
+        ERR_clear_error();
+
+        /* Something to read, let's do it and hope that it is the close
+           notify alert from the server */
+        nread = (ssize_t)SSL_read(conn->ssl[sockindex].handle, buf,
+                                  buffsize);
+        err = SSL_get_error(conn->ssl[sockindex].handle, (int)nread);
+
+        switch(err) {
+        case SSL_ERROR_NONE: /* this is not an error */
+        case SSL_ERROR_ZERO_RETURN: /* no more data */
+          /* This is the expected response. There was no data but only
+             the close notify alert */
+          done = 1;
+          break;
+        case SSL_ERROR_WANT_READ:
+          /* there's data pending, re-invoke SSL_read() */
+          infof(data, "SSL_ERROR_WANT_READ\n");
+          break;
+        case SSL_ERROR_WANT_WRITE:
+          /* SSL wants a write. Really odd. Let's bail out. */
+          infof(data, "SSL_ERROR_WANT_WRITE\n");
+          done = 1;
+          break;
+        default:
+          /* openssl/ssl.h says "look at error stack/return value/errno" */
+          sslerror = ERR_get_error();
+          failf(conn->data, "SSL read: %s, errno %d",
+                ERR_error_string(sslerror, buf),
+                SOCKERRNO);
+          done = 1;
+          break;
+        }
+      }
+      else if(0 == what) {
+        /* timeout */
+        failf(data, "SSL shutdown timeout");
+        done = 1;
+      }
+      else {
+        /* anything that gets here is fatally bad */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        retval = -1;
+        done = 1;
+      }
+    } /* while()-loop for the select() */
+
+    if(data->set.verbose) {
+#ifdef HAVE_SSL_GET_SHUTDOWN
+      switch(SSL_get_shutdown(connssl->handle)) {
+      case SSL_SENT_SHUTDOWN:
+        infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n");
+        break;
+      case SSL_RECEIVED_SHUTDOWN:
+        infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n");
+        break;
+      case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN:
+        infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|"
+              "SSL_RECEIVED__SHUTDOWN\n");
+        break;
+      }
+#endif
+    }
+
+    SSL_free (connssl->handle);
+    connssl->handle = NULL;
+  }
+  return retval;
+}
+
+void Curl_ossl_session_free(void *ptr)
+{
+  /* free the ID */
+  SSL_SESSION_free(ptr);
+}
+
+/*
+ * This function is called when the 'data' struct is going away. Close
+ * down everything and free all resources!
+ */
+void Curl_ossl_close_all(struct SessionHandle *data)
+{
+#ifdef HAVE_OPENSSL_ENGINE_H
+  if(data->state.engine) {
+    ENGINE_finish(data->state.engine);
+    ENGINE_free(data->state.engine);
+    data->state.engine = NULL;
+  }
+#else
+  (void)data;
+#endif
+}
+
+/* ====================================================== */
+
+
+/* Quote from RFC2818 section 3.1 "Server Identity"
+
+   If a subjectAltName extension of type dNSName is present, that MUST
+   be used as the identity. Otherwise, the (most specific) Common Name
+   field in the Subject field of the certificate MUST be used. Although
+   the use of the Common Name is existing practice, it is deprecated and
+   Certification Authorities are encouraged to use the dNSName instead.
+
+   Matching is performed using the matching rules specified by
+   [RFC2459].  If more than one identity of a given type is present in
+   the certificate (e.g., more than one dNSName name, a match in any one
+   of the set is considered acceptable.) Names may contain the wildcard
+   character * which is considered to match any single domain name
+   component or component fragment. E.g., *.a.com matches foo.a.com but
+   not bar.foo.a.com. f*.com matches foo.com but not bar.com.
+
+   In some cases, the URI is specified as an IP address rather than a
+   hostname. In this case, the iPAddress subjectAltName must be present
+   in the certificate and must exactly match the IP in the URI.
+
+*/
+static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
+{
+  int matched = -1; /* -1 is no alternative match yet, 1 means match and 0
+                       means mismatch */
+  int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */
+  size_t addrlen = 0;
+  struct SessionHandle *data = conn->data;
+  STACK_OF(GENERAL_NAME) *altnames;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif
+  CURLcode result = CURLE_OK;
+
+#ifdef ENABLE_IPV6
+  if(conn->bits.ipv6_ip &&
+     Curl_inet_pton(AF_INET6, conn->host.name, &addr)) {
+    target = GEN_IPADD;
+    addrlen = sizeof(struct in6_addr);
+  }
+  else
+#endif
+    if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) {
+      target = GEN_IPADD;
+      addrlen = sizeof(struct in_addr);
+    }
+
+  /* get a "list" of alternative names */
+  altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL);
+
+  if(altnames) {
+    int numalts;
+    int i;
+
+    /* get amount of alternatives, RFC2459 claims there MUST be at least
+       one, but we don't depend on it... */
+    numalts = sk_GENERAL_NAME_num(altnames);
+
+    /* loop through all alternatives while none has matched */
+    for(i=0; (i<numalts) && (matched != 1); i++) {
+      /* get a handle to alternative name number i */
+      const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
+
+      /* only check alternatives of the same type the target is */
+      if(check->type == target) {
+        /* get data and length */
+        const char *altptr = (char *)ASN1_STRING_data(check->d.ia5);
+        size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5);
+
+        switch(target) {
+        case GEN_DNS: /* name/pattern comparison */
+          /* The OpenSSL man page explicitly says: "In general it cannot be
+             assumed that the data returned by ASN1_STRING_data() is null
+             terminated or does not contain embedded nulls." But also that
+             "The actual format of the data will depend on the actual string
+             type itself: for example for and IA5String the data will be ASCII"
+
+             Gisle researched the OpenSSL sources:
+             "I checked the 0.9.6 and 0.9.8 sources before my patch and
+             it always 0-terminates an IA5String."
+          */
+          if((altlen == strlen(altptr)) &&
+             /* if this isn't true, there was an embedded zero in the name
+                string and we cannot match it. */
+             Curl_cert_hostcheck(altptr, conn->host.name))
+            matched = 1;
+          else
+            matched = 0;
+          break;
+
+        case GEN_IPADD: /* IP address comparison */
+          /* compare alternative IP address if the data chunk is the same size
+             our server IP address is */
+          if((altlen == addrlen) && !memcmp(altptr, &addr, altlen))
+            matched = 1;
+          else
+            matched = 0;
+          break;
+        }
+      }
+    }
+    GENERAL_NAMES_free(altnames);
+  }
+
+  if(matched == 1)
+    /* an alternative name matched the server hostname */
+    infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname);
+  else if(matched == 0) {
+    /* an alternative name field existed, but didn't match and then
+       we MUST fail */
+    infof(data, "\t subjectAltName does not match %s\n", conn->host.dispname);
+    failf(data, "SSL: no alternative certificate subject name matches "
+          "target host name '%s'", conn->host.dispname);
+    result = CURLE_PEER_FAILED_VERIFICATION;
+  }
+  else {
+    /* we have to look to the last occurrence of a commonName in the
+       distinguished one to get the most significant one. */
+    int j, i=-1;
+
+/* The following is done because of a bug in 0.9.6b */
+
+    unsigned char *nulstr = (unsigned char *)"";
+    unsigned char *peer_CN = nulstr;
+
+    X509_NAME *name = X509_get_subject_name(server_cert);
+    if(name)
+      while((j = X509_NAME_get_index_by_NID(name, NID_commonName, i))>=0)
+        i=j;
+
+    /* we have the name entry and we will now convert this to a string
+       that we can use for comparison. Doing this we support BMPstring,
+       UTF8 etc. */
+
+    if(i>=0) {
+      ASN1_STRING *tmp =
+        X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
+
+      /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input
+         is already UTF-8 encoded. We check for this case and copy the raw
+         string manually to avoid the problem. This code can be made
+         conditional in the future when OpenSSL has been fixed. Work-around
+         brought by Alexis S. L. Carvalho. */
+      if(tmp) {
+        if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
+          j = ASN1_STRING_length(tmp);
+          if(j >= 0) {
+            peer_CN = OPENSSL_malloc(j+1);
+            if(peer_CN) {
+              memcpy(peer_CN, ASN1_STRING_data(tmp), j);
+              peer_CN[j] = '\0';
+            }
+          }
+        }
+        else /* not a UTF8 name */
+          j = ASN1_STRING_to_UTF8(&peer_CN, tmp);
+
+        if(peer_CN && (curlx_uztosi(strlen((char *)peer_CN)) != j)) {
+          /* there was a terminating zero before the end of string, this
+             cannot match and we return failure! */
+          failf(data, "SSL: illegal cert name field");
+          result = CURLE_PEER_FAILED_VERIFICATION;
+        }
+      }
+    }
+
+    if(peer_CN == nulstr)
+       peer_CN = NULL;
+    else {
+      /* convert peer_CN from UTF8 */
+      CURLcode rc = Curl_convert_from_utf8(data, peer_CN, strlen(peer_CN));
+      /* Curl_convert_from_utf8 calls failf if unsuccessful */
+      if(rc) {
+        OPENSSL_free(peer_CN);
+        return rc;
+      }
+    }
+
+    if(result)
+      /* error already detected, pass through */
+      ;
+    else if(!peer_CN) {
+      failf(data,
+            "SSL: unable to obtain common name from peer certificate");
+      result = CURLE_PEER_FAILED_VERIFICATION;
+    }
+    else if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
+      failf(data, "SSL: certificate subject name '%s' does not match "
+            "target host name '%s'", peer_CN, conn->host.dispname);
+      result = CURLE_PEER_FAILED_VERIFICATION;
+    }
+    else {
+      infof(data, "\t common name: %s (matched)\n", peer_CN);
+    }
+    if(peer_CN)
+      OPENSSL_free(peer_CN);
+  }
+
+  return result;
+}
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+    !defined(OPENSSL_IS_BORINGSSL)
+static CURLcode verifystatus(struct connectdata *conn,
+                             struct ssl_connect_data *connssl)
+{
+  int i, ocsp_status;
+  const unsigned char *p;
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  OCSP_RESPONSE *rsp = NULL;
+  OCSP_BASICRESP *br = NULL;
+  X509_STORE     *st = NULL;
+  STACK_OF(X509) *ch = NULL;
+
+  long len = SSL_get_tlsext_status_ocsp_resp(connssl->handle, &p);
+
+  if(!p) {
+    failf(data, "No OCSP response received");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
+  if(!rsp) {
+    failf(data, "Invalid OCSP response");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  ocsp_status = OCSP_response_status(rsp);
+  if(ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+    failf(data, "Invalid OCSP response status: %s (%d)",
+          OCSP_response_status_str(ocsp_status), ocsp_status);
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  br = OCSP_response_get1_basic(rsp);
+  if(!br) {
+    failf(data, "Invalid OCSP response");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  ch = SSL_get_peer_cert_chain(connssl->handle);
+  st = SSL_CTX_get_cert_store(connssl->ctx);
+
+#if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \
+     defined(LIBRESSL_VERSION_NUMBER))
+  /* The authorized responder cert in the OCSP response MUST be signed by the
+     peer cert's issuer (see RFC6960 section 4.2.2.2). If that's a root cert,
+     no problem, but if it's an intermediate cert OpenSSL has a bug where it
+     expects this issuer to be present in the chain embedded in the OCSP
+     response. So we add it if necessary. */
+
+  /* First make sure the peer cert chain includes both a peer and an issuer,
+     and the OCSP response contains a responder cert. */
+  if(sk_X509_num(ch) >= 2 && sk_X509_num(br->certs) >= 1) {
+    X509 *responder = sk_X509_value(br->certs, sk_X509_num(br->certs) - 1);
+
+    /* Find issuer of responder cert and add it to the OCSP response chain */
+    for(i = 0; i < sk_X509_num(ch); i++) {
+      X509 *issuer = sk_X509_value(ch, i);
+      if(X509_check_issued(issuer, responder) == X509_V_OK) {
+        if(!OCSP_basic_add1_cert(br, issuer)) {
+          failf(data, "Could not add issuer cert to OCSP response");
+          result = CURLE_SSL_INVALIDCERTSTATUS;
+          goto end;
+        }
+      }
+    }
+  }
+#endif
+
+  if(OCSP_basic_verify(br, ch, st, 0) <= 0) {
+    failf(data, "OCSP response verification failed");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  for(i = 0; i < OCSP_resp_count(br); i++) {
+    int cert_status, crl_reason;
+    OCSP_SINGLERESP *single = NULL;
+
+    ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+
+    if(!(single = OCSP_resp_get0(br, i)))
+      continue;
+
+    cert_status = OCSP_single_get0_status(single, &crl_reason, &rev,
+                                          &thisupd, &nextupd);
+
+    if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) {
+      failf(data, "OCSP response has expired");
+      result = CURLE_SSL_INVALIDCERTSTATUS;
+      goto end;
+    }
+
+    infof(data, "SSL certificate status: %s (%d)\n",
+          OCSP_cert_status_str(cert_status), cert_status);
+
+    switch(cert_status) {
+      case V_OCSP_CERTSTATUS_GOOD:
+        break;
+
+      case V_OCSP_CERTSTATUS_REVOKED:
+        result = CURLE_SSL_INVALIDCERTSTATUS;
+
+        failf(data, "SSL certificate revocation reason: %s (%d)",
+              OCSP_crl_reason_str(crl_reason), crl_reason);
+        goto end;
+
+      case V_OCSP_CERTSTATUS_UNKNOWN:
+        result = CURLE_SSL_INVALIDCERTSTATUS;
+        goto end;
+    }
+  }
+
+end:
+  if(br) OCSP_BASICRESP_free(br);
+  OCSP_RESPONSE_free(rsp);
+
+  return result;
+}
+#endif
+
+#endif /* USE_OPENSSL */
+
+/* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions
+   and thus this cannot be done there. */
+#ifdef SSL_CTRL_SET_MSG_CALLBACK
+
+static const char *ssl_msg_type(int ssl_ver, int msg)
+{
+#ifdef SSL2_VERSION_MAJOR
+  if(ssl_ver == SSL2_VERSION_MAJOR) {
+    switch (msg) {
+      case SSL2_MT_ERROR:
+        return "Error";
+      case SSL2_MT_CLIENT_HELLO:
+        return "Client hello";
+      case SSL2_MT_CLIENT_MASTER_KEY:
+        return "Client key";
+      case SSL2_MT_CLIENT_FINISHED:
+        return "Client finished";
+      case SSL2_MT_SERVER_HELLO:
+        return "Server hello";
+      case SSL2_MT_SERVER_VERIFY:
+        return "Server verify";
+      case SSL2_MT_SERVER_FINISHED:
+        return "Server finished";
+      case SSL2_MT_REQUEST_CERTIFICATE:
+        return "Request CERT";
+      case SSL2_MT_CLIENT_CERTIFICATE:
+        return "Client CERT";
+    }
+  }
+  else
+#endif
+  if(ssl_ver == SSL3_VERSION_MAJOR) {
+    switch (msg) {
+      case SSL3_MT_HELLO_REQUEST:
+        return "Hello request";
+      case SSL3_MT_CLIENT_HELLO:
+        return "Client hello";
+      case SSL3_MT_SERVER_HELLO:
+        return "Server hello";
+#ifdef SSL3_MT_NEWSESSION_TICKET
+      case SSL3_MT_NEWSESSION_TICKET:
+        return "Newsession Ticket";
+#endif
+      case SSL3_MT_CERTIFICATE:
+        return "Certificate";
+      case SSL3_MT_SERVER_KEY_EXCHANGE:
+        return "Server key exchange";
+      case SSL3_MT_CLIENT_KEY_EXCHANGE:
+        return "Client key exchange";
+      case SSL3_MT_CERTIFICATE_REQUEST:
+        return "Request CERT";
+      case SSL3_MT_SERVER_DONE:
+        return "Server finished";
+      case SSL3_MT_CERTIFICATE_VERIFY:
+        return "CERT verify";
+      case SSL3_MT_FINISHED:
+        return "Finished";
+#ifdef SSL3_MT_CERTIFICATE_STATUS
+      case SSL3_MT_CERTIFICATE_STATUS:
+        return "Certificate Status";
+#endif
+    }
+  }
+  return "Unknown";
+}
+
+static const char *tls_rt_type(int type)
+{
+  switch(type) {
+#ifdef SSL3_RT_HEADER
+  case SSL3_RT_HEADER:
+    return "TLS header";
+#endif
+  case SSL3_RT_CHANGE_CIPHER_SPEC:
+    return "TLS change cipher";
+  case SSL3_RT_ALERT:
+    return "TLS alert";
+  case SSL3_RT_HANDSHAKE:
+    return "TLS handshake";
+  case SSL3_RT_APPLICATION_DATA:
+    return "TLS app data";
+  default:
+    return "TLS Unknown";
+  }
+}
+
+
+/*
+ * Our callback from the SSL/TLS layers.
+ */
+static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
+                          const void *buf, size_t len, SSL *ssl,
+                          void *userp)
+{
+  struct SessionHandle *data;
+  const char *msg_name, *tls_rt_name;
+  char ssl_buf[1024];
+  char unknown[32];
+  int msg_type, txt_len;
+  const char *verstr = NULL;
+  struct connectdata *conn = userp;
+
+  if(!conn || !conn->data || !conn->data->set.fdebug ||
+     (direction != 0 && direction != 1))
+    return;
+
+  data = conn->data;
+
+  switch(ssl_ver) {
+#ifdef SSL2_VERSION /* removed in recent versions */
+  case SSL2_VERSION:
+    verstr = "SSLv2";
+    break;
+#endif
+#ifdef SSL3_VERSION
+  case SSL3_VERSION:
+    verstr = "SSLv3";
+    break;
+#endif
+  case TLS1_VERSION:
+    verstr = "TLSv1.0";
+    break;
+#ifdef TLS1_1_VERSION
+  case TLS1_1_VERSION:
+    verstr = "TLSv1.1";
+    break;
+#endif
+#ifdef TLS1_2_VERSION
+  case TLS1_2_VERSION:
+    verstr = "TLSv1.2";
+    break;
+#endif
+  case 0:
+    break;
+  default:
+    snprintf(unknown, sizeof(unknown), "(%x)", ssl_ver);
+    verstr = unknown;
+    break;
+  }
+
+  if(ssl_ver) {
+    /* the info given when the version is zero is not that useful for us */
+
+    ssl_ver >>= 8; /* check the upper 8 bits only below */
+
+    /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL
+     * always pass-up content-type as 0. But the interesting message-type
+     * is at 'buf[0]'.
+     */
+    if(ssl_ver == SSL3_VERSION_MAJOR && content_type)
+      tls_rt_name = tls_rt_type(content_type);
+    else
+      tls_rt_name = "";
+
+    msg_type = *(char*)buf;
+    msg_name = ssl_msg_type(ssl_ver, msg_type);
+
+    txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "%s (%s), %s, %s (%d):\n",
+                       verstr, direction?"OUT":"IN",
+                       tls_rt_name, msg_name, msg_type);
+    Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL);
+  }
+
+  Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT :
+             CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL);
+  (void) ssl;
+}
+#endif
+
+#ifdef USE_OPENSSL
+/* ====================================================== */
+
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+#  define use_sni(x)  sni = (x)
+#else
+#  define use_sni(x)  Curl_nop_stmt
+#endif
+
+/* Check for OpenSSL 1.0.2 which has ALPN support. */
+#undef HAS_ALPN
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L \
+    && !defined(OPENSSL_NO_TLSEXT)
+#  define HAS_ALPN 1
+#endif
+
+/* Check for OpenSSL 1.0.1 which has NPN support. */
+#undef HAS_NPN
+#if OPENSSL_VERSION_NUMBER >= 0x10001000L \
+    && !defined(OPENSSL_NO_TLSEXT) \
+    && !defined(OPENSSL_NO_NEXTPROTONEG)
+#  define HAS_NPN 1
+#endif
+
+#ifdef HAS_NPN
+
+/*
+ * in is a list of lenght prefixed strings. this function has to select
+ * the protocol we want to use from the list and write its string into out.
+ */
+
+static int
+select_next_protocol(unsigned char **out, unsigned char *outlen,
+                     const unsigned char *in, unsigned int inlen,
+                     const char *key, unsigned int keylen)
+{
+  unsigned int i;
+  for(i = 0; i + keylen <= inlen; i += in[i] + 1) {
+    if(memcmp(&in[i + 1], key, keylen) == 0) {
+      *out = (unsigned char *) &in[i + 1];
+      *outlen = in[i];
+      return 0;
+    }
+  }
+  return -1;
+}
+
+static int
+select_next_proto_cb(SSL *ssl,
+                     unsigned char **out, unsigned char *outlen,
+                     const unsigned char *in, unsigned int inlen,
+                     void *arg)
+{
+  struct connectdata *conn = (struct connectdata*) arg;
+
+  (void)ssl;
+
+#ifdef USE_NGHTTP2
+  if(conn->data->set.httpversion >= CURL_HTTP_VERSION_2 &&
+     !select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_VERSION_ID,
+                           NGHTTP2_PROTO_VERSION_ID_LEN)) {
+    infof(conn->data, "NPN, negotiated HTTP2 (%s)\n",
+          NGHTTP2_PROTO_VERSION_ID);
+    conn->negnpn = CURL_HTTP_VERSION_2;
+    return SSL_TLSEXT_ERR_OK;
+  }
+#endif
+
+  if(!select_next_protocol(out, outlen, in, inlen, ALPN_HTTP_1_1,
+                           ALPN_HTTP_1_1_LENGTH)) {
+    infof(conn->data, "NPN, negotiated HTTP1.1\n");
+    conn->negnpn = CURL_HTTP_VERSION_1_1;
+    return SSL_TLSEXT_ERR_OK;
+  }
+
+  infof(conn->data, "NPN, no overlap, use HTTP1.1\n");
+  *out = (unsigned char *)ALPN_HTTP_1_1;
+  *outlen = ALPN_HTTP_1_1_LENGTH;
+  conn->negnpn = CURL_HTTP_VERSION_1_1;
+
+  return SSL_TLSEXT_ERR_OK;
+}
+#endif /* HAS_NPN */
+
+static const char *
+get_ssl_version_txt(SSL *ssl)
+{
+  if(!ssl)
+    return "";
+
+  switch(SSL_version(ssl)) {
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+  case TLS1_2_VERSION:
+    return "TLSv1.2";
+  case TLS1_1_VERSION:
+    return "TLSv1.1";
+#endif
+  case TLS1_VERSION:
+    return "TLSv1.0";
+  case SSL3_VERSION:
+    return "SSLv3";
+  case SSL2_VERSION:
+    return "SSLv2";
+  }
+  return "unknown";
+}
+
+static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
+{
+  CURLcode result = CURLE_OK;
+  char *ciphers;
+  struct SessionHandle *data = conn->data;
+  SSL_METHOD_QUAL SSL_METHOD *req_method = NULL;
+  void *ssl_sessionid = NULL;
+  X509_LOOKUP *lookup = NULL;
+  curl_socket_t sockfd = conn->sock[sockindex];
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  long ctx_options;
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+  bool sni;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif
+#endif
+
+  DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
+
+  /* Make funny stuff to get random input */
+  Curl_ossl_seed(data);
+
+  data->set.ssl.certverifyresult = !X509_V_OK;
+
+  /* check to see if we've been told to use an explicit SSL/TLS version */
+
+  switch(data->set.ssl.version) {
+  default:
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+  case CURL_SSLVERSION_TLSv1_0:
+  case CURL_SSLVERSION_TLSv1_1:
+  case CURL_SSLVERSION_TLSv1_2:
+    /* it will be handled later with the context options */
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+    !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL)
+    req_method = TLS_client_method();
+#else
+    req_method = SSLv23_client_method();
+#endif
+    use_sni(TRUE);
+    break;
+  case CURL_SSLVERSION_SSLv2:
+#ifdef OPENSSL_NO_SSL2
+    failf(data, "OpenSSL was built without SSLv2 support");
+    return CURLE_NOT_BUILT_IN;
+#else
+#ifdef USE_TLS_SRP
+    if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
+      return CURLE_SSL_CONNECT_ERROR;
+#endif
+    req_method = SSLv2_client_method();
+    use_sni(FALSE);
+    break;
+#endif
+  case CURL_SSLVERSION_SSLv3:
+#ifdef OPENSSL_NO_SSL3_METHOD
+    failf(data, "OpenSSL was built without SSLv3 support");
+    return CURLE_NOT_BUILT_IN;
+#else
+#ifdef USE_TLS_SRP
+    if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
+      return CURLE_SSL_CONNECT_ERROR;
+#endif
+    req_method = SSLv3_client_method();
+    use_sni(FALSE);
+    break;
+#endif
+  }
+
+  if(connssl->ctx)
+    SSL_CTX_free(connssl->ctx);
+  connssl->ctx = SSL_CTX_new(req_method);
+
+  if(!connssl->ctx) {
+    failf(data, "SSL: couldn't create a context: %s",
+          ERR_error_string(ERR_peek_error(), NULL));
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+#ifdef SSL_MODE_RELEASE_BUFFERS
+  SSL_CTX_set_mode(connssl->ctx, SSL_MODE_RELEASE_BUFFERS);
+#endif
+
+#ifdef SSL_CTRL_SET_MSG_CALLBACK
+  if(data->set.fdebug && data->set.verbose) {
+    /* the SSL trace callback is only used for verbose logging */
+    SSL_CTX_set_msg_callback(connssl->ctx, ssl_tls_trace);
+    SSL_CTX_set_msg_callback_arg(connssl->ctx, conn);
+  }
+#endif
+
+  /* OpenSSL contains code to work-around lots of bugs and flaws in various
+     SSL-implementations. SSL_CTX_set_options() is used to enabled those
+     work-arounds. The man page for this option states that SSL_OP_ALL enables
+     all the work-arounds and that "It is usually safe to use SSL_OP_ALL to
+     enable the bug workaround options if compatibility with somewhat broken
+     implementations is desired."
+
+     The "-no_ticket" option was introduced in Openssl0.9.8j. It's a flag to
+     disable "rfc4507bis session ticket support".  rfc4507bis was later turned
+     into the proper RFC5077 it seems: https://tools.ietf.org/html/rfc5077
+
+     The enabled extension concerns the session management. I wonder how often
+     libcurl stops a connection and then resumes a TLS session. also, sending
+     the session data is some overhead. .I suggest that you just use your
+     proposed patch (which explicitly disables TICKET).
+
+     If someone writes an application with libcurl and openssl who wants to
+     enable the feature, one can do this in the SSL callback.
+
+     SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper
+     interoperability with web server Netscape Enterprise Server 2.0.1 which
+     was released back in 1996.
+
+     Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has
+     become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate
+     CVE-2010-4180 when using previous OpenSSL versions we no longer enable
+     this option regardless of OpenSSL version and SSL_OP_ALL definition.
+
+     OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability
+     (https://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to
+     SSL_OP_ALL that _disables_ that work-around despite the fact that
+     SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to
+     keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit
+     must not be set.
+  */
+
+  ctx_options = SSL_OP_ALL;
+
+#ifdef SSL_OP_NO_TICKET
+  ctx_options |= SSL_OP_NO_TICKET;
+#endif
+
+#ifdef SSL_OP_NO_COMPRESSION
+  ctx_options |= SSL_OP_NO_COMPRESSION;
+#endif
+
+#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
+  /* mitigate CVE-2010-4180 */
+  ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
+#endif
+
+#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
+  /* unless the user explicitly ask to allow the protocol vulnerability we
+     use the work-around */
+  if(!conn->data->set.ssl_enable_beast)
+    ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
+#endif
+
+  switch(data->set.ssl.version) {
+  case CURL_SSLVERSION_SSLv3:
+#ifdef USE_TLS_SRP
+    if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
+      infof(data, "Set version TLSv1.x for SRP authorisation\n");
+    }
+#endif
+    ctx_options |= SSL_OP_NO_SSLv2;
+    ctx_options |= SSL_OP_NO_TLSv1;
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+    ctx_options |= SSL_OP_NO_TLSv1_1;
+    ctx_options |= SSL_OP_NO_TLSv1_2;
+#endif
+    break;
+
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+    ctx_options |= SSL_OP_NO_SSLv2;
+    ctx_options |= SSL_OP_NO_SSLv3;
+    break;
+
+  case CURL_SSLVERSION_TLSv1_0:
+    ctx_options |= SSL_OP_NO_SSLv2;
+    ctx_options |= SSL_OP_NO_SSLv3;
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+    ctx_options |= SSL_OP_NO_TLSv1_1;
+    ctx_options |= SSL_OP_NO_TLSv1_2;
+#endif
+    break;
+
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+  case CURL_SSLVERSION_TLSv1_1:
+    ctx_options |= SSL_OP_NO_SSLv2;
+    ctx_options |= SSL_OP_NO_SSLv3;
+    ctx_options |= SSL_OP_NO_TLSv1;
+    ctx_options |= SSL_OP_NO_TLSv1_2;
+    break;
+
+  case CURL_SSLVERSION_TLSv1_2:
+    ctx_options |= SSL_OP_NO_SSLv2;
+    ctx_options |= SSL_OP_NO_SSLv3;
+    ctx_options |= SSL_OP_NO_TLSv1;
+    ctx_options |= SSL_OP_NO_TLSv1_1;
+    break;
+#endif
+
+#ifndef OPENSSL_NO_SSL2
+  case CURL_SSLVERSION_SSLv2:
+    ctx_options |= SSL_OP_NO_SSLv3;
+    ctx_options |= SSL_OP_NO_TLSv1;
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+    ctx_options |= SSL_OP_NO_TLSv1_1;
+    ctx_options |= SSL_OP_NO_TLSv1_2;
+#endif
+    break;
+#endif
+
+  default:
+    failf(data, "Unsupported SSL protocol version");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  SSL_CTX_set_options(connssl->ctx, ctx_options);
+
+#ifdef HAS_NPN
+  if(data->set.ssl_enable_npn)
+    SSL_CTX_set_next_proto_select_cb(connssl->ctx, select_next_proto_cb, conn);
+#endif
+
+#ifdef HAS_ALPN
+  if(data->set.ssl_enable_alpn) {
+    int cur = 0;
+    unsigned char protocols[128];
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
+      protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
+
+      memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
+          NGHTTP2_PROTO_VERSION_ID_LEN);
+      cur += NGHTTP2_PROTO_VERSION_ID_LEN;
+      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+    }
+#endif
+
+    protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
+    memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
+    cur += ALPN_HTTP_1_1_LENGTH;
+    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+    /* expects length prefixed preference ordered list of protocols in wire
+     * format
+     */
+    SSL_CTX_set_alpn_protos(connssl->ctx, protocols, cur);
+  }
+#endif
+
+  if(data->set.str[STRING_CERT] || data->set.str[STRING_CERT_TYPE]) {
+    if(!cert_stuff(conn,
+                   connssl->ctx,
+                   data->set.str[STRING_CERT],
+                   data->set.str[STRING_CERT_TYPE],
+                   data->set.str[STRING_KEY],
+                   data->set.str[STRING_KEY_TYPE])) {
+      /* failf() is already done in cert_stuff() */
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  ciphers = data->set.str[STRING_SSL_CIPHER_LIST];
+  if(!ciphers)
+    ciphers = (char *)DEFAULT_CIPHER_SELECTION;
+  if(!SSL_CTX_set_cipher_list(connssl->ctx, ciphers)) {
+    failf(data, "failed setting cipher list: %s", ciphers);
+    return CURLE_SSL_CIPHER;
+  }
+  infof(data, "Cipher selection: %s\n", ciphers);
+
+#ifdef USE_TLS_SRP
+  if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
+    infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
+
+    if(!SSL_CTX_set_srp_username(connssl->ctx, data->set.ssl.username)) {
+      failf(data, "Unable to set SRP user name");
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+    if(!SSL_CTX_set_srp_password(connssl->ctx, data->set.ssl.password)) {
+      failf(data, "failed setting SRP password");
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+    if(!data->set.str[STRING_SSL_CIPHER_LIST]) {
+      infof(data, "Setting cipher list SRP\n");
+
+      if(!SSL_CTX_set_cipher_list(connssl->ctx, "SRP")) {
+        failf(data, "failed setting SRP cipher list");
+        return CURLE_SSL_CIPHER;
+      }
+    }
+  }
+#endif
+  if(data->set.str[STRING_SSL_CAFILE] || data->set.str[STRING_SSL_CAPATH]) {
+    /* tell SSL where to find CA certificates that are used to verify
+       the servers certificate. */
+    if(!SSL_CTX_load_verify_locations(connssl->ctx,
+                                       data->set.str[STRING_SSL_CAFILE],
+                                       data->set.str[STRING_SSL_CAPATH])) {
+      if(data->set.ssl.verifypeer) {
+        /* Fail if we insist on successfully verifying the server. */
+        failf(data, "error setting certificate verify locations:\n"
+              "  CAfile: %s\n  CApath: %s",
+              data->set.str[STRING_SSL_CAFILE]?
+              data->set.str[STRING_SSL_CAFILE]: "none",
+              data->set.str[STRING_SSL_CAPATH]?
+              data->set.str[STRING_SSL_CAPATH] : "none");
+        return CURLE_SSL_CACERT_BADFILE;
+      }
+      else {
+        /* Just continue with a warning if no strict  certificate verification
+           is required. */
+        infof(data, "error setting certificate verify locations,"
+              " continuing anyway:\n");
+      }
+    }
+    else {
+      /* Everything is fine. */
+      infof(data, "successfully set certificate verify locations:\n");
+    }
+    infof(data,
+          "  CAfile: %s\n"
+          "  CApath: %s\n",
+          data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]:
+          "none",
+          data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]:
+          "none");
+  }
+
+  if(data->set.str[STRING_SSL_CRLFILE]) {
+    /* tell SSL where to find CRL file that is used to check certificate
+     * revocation */
+    lookup=X509_STORE_add_lookup(SSL_CTX_get_cert_store(connssl->ctx),
+                                 X509_LOOKUP_file());
+    if(!lookup ||
+       (!X509_load_crl_file(lookup, data->set.str[STRING_SSL_CRLFILE],
+                            X509_FILETYPE_PEM)) ) {
+      failf(data, "error loading CRL file: %s",
+            data->set.str[STRING_SSL_CRLFILE]);
+      return CURLE_SSL_CRL_BADFILE;
+    }
+    else {
+      /* Everything is fine. */
+      infof(data, "successfully load CRL file:\n");
+      X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
+                           X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
+    }
+    infof(data,
+          "  CRLfile: %s\n", data->set.str[STRING_SSL_CRLFILE] ?
+          data->set.str[STRING_SSL_CRLFILE]: "none");
+  }
+
+  /* Try building a chain using issuers in the trusted store first to avoid
+  problems with server-sent legacy intermediates.
+  Newer versions of OpenSSL do alternate chain checking by default which
+  gives us the same fix without as much of a performance hit (slight), so we
+  prefer that if available.
+  https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest
+  */
+#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS)
+  if(data->set.ssl.verifypeer) {
+    X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
+                         X509_V_FLAG_TRUSTED_FIRST);
+  }
+#endif
+
+  /* SSL always tries to verify the peer, this only says whether it should
+   * fail to connect if the verification fails, or if it should continue
+   * anyway. In the latter case the result of the verification is checked with
+   * SSL_get_verify_result() below. */
+  SSL_CTX_set_verify(connssl->ctx,
+                     data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
+                     NULL);
+
+  /* give application a chance to interfere with SSL set up. */
+  if(data->set.ssl.fsslctx) {
+    result = (*data->set.ssl.fsslctx)(data, connssl->ctx,
+                                      data->set.ssl.fsslctxp);
+    if(result) {
+      failf(data, "error signaled by ssl ctx callback");
+      return result;
+    }
+  }
+
+  /* Lets make an SSL structure */
+  if(connssl->handle)
+    SSL_free(connssl->handle);
+  connssl->handle = SSL_new(connssl->ctx);
+  if(!connssl->handle) {
+    failf(data, "SSL: couldn't create a context (handle)!");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+    !defined(OPENSSL_IS_BORINGSSL)
+  if(data->set.ssl.verifystatus)
+    SSL_set_tlsext_status_type(connssl->handle, TLSEXT_STATUSTYPE_ocsp);
+#endif
+
+  SSL_set_connect_state(connssl->handle);
+
+  connssl->server_cert = 0x0;
+
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+  if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
+#ifdef ENABLE_IPV6
+     (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
+#endif
+     sni &&
+     !SSL_set_tlsext_host_name(connssl->handle, conn->host.name))
+    infof(data, "WARNING: failed to configure server name indication (SNI) "
+          "TLS extension\n");
+#endif
+
+  /* Check if there's a cached ID we can/should use here! */
+  if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
+    /* we got a session id, use it! */
+    if(!SSL_set_session(connssl->handle, ssl_sessionid)) {
+      failf(data, "SSL: SSL_set_session failed: %s",
+            ERR_error_string(ERR_get_error(), NULL));
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    /* Informational message */
+    infof (data, "SSL re-using session ID\n");
+  }
+
+  /* pass the raw socket into the SSL layers */
+  if(!SSL_set_fd(connssl->handle, (int)sockfd)) {
+    failf(data, "SSL: SSL_set_fd failed: %s",
+          ERR_error_string(ERR_get_error(), NULL));
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  connssl->connecting_state = ssl_connect_2;
+
+  return CURLE_OK;
+}
+
+static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  int err;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
+             || ssl_connect_2_reading == connssl->connecting_state
+             || ssl_connect_2_writing == connssl->connecting_state);
+
+  ERR_clear_error();
+
+  err = SSL_connect(connssl->handle);
+
+  /* 1  is fine
+     0  is "not successful but was shut down controlled"
+     <0 is "handshake was not successful, because a fatal error occurred" */
+  if(1 != err) {
+    int detail = SSL_get_error(connssl->handle, err);
+
+    if(SSL_ERROR_WANT_READ == detail) {
+      connssl->connecting_state = ssl_connect_2_reading;
+      return CURLE_OK;
+    }
+    else if(SSL_ERROR_WANT_WRITE == detail) {
+      connssl->connecting_state = ssl_connect_2_writing;
+      return CURLE_OK;
+    }
+    else {
+      /* untreated error */
+      unsigned long errdetail;
+      char error_buffer[256]=""; /* OpenSSL documents that this must be at
+                                    least 256 bytes long. */
+      CURLcode result;
+      long lerr;
+      int lib;
+      int reason;
+
+      /* the connection failed, we're not waiting for anything else. */
+      connssl->connecting_state = ssl_connect_2;
+
+      /* Get the earliest error code from the thread's error queue and removes
+         the entry. */
+      errdetail = ERR_get_error();
+
+      /* Extract which lib and reason */
+      lib = ERR_GET_LIB(errdetail);
+      reason = ERR_GET_REASON(errdetail);
+
+      if((lib == ERR_LIB_SSL) &&
+         (reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) {
+        result = CURLE_SSL_CACERT;
+
+        lerr = SSL_get_verify_result(connssl->handle);
+        if(lerr != X509_V_OK) {
+          snprintf(error_buffer, sizeof(error_buffer),
+                   "SSL certificate problem: %s",
+                   X509_verify_cert_error_string(lerr));
+        }
+        else
+          /* strcpy() is fine here as long as the string fits within
+             error_buffer */
+          strcpy(error_buffer, "SSL certificate verification failed");
+      }
+      else {
+        result = CURLE_SSL_CONNECT_ERROR;
+        SSL_strerror(errdetail, error_buffer, sizeof(error_buffer));
+      }
+
+      /* detail is already set to the SSL error above */
+
+      /* If we e.g. use SSLv2 request-method and the server doesn't like us
+       * (RST connection etc.), OpenSSL gives no explanation whatsoever and
+       * the SO_ERROR is also lost.
+       */
+      if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
+        failf(data, "Unknown SSL protocol error in connection to %s:%ld ",
+              conn->host.name, conn->remote_port);
+        return result;
+      }
+
+      /* Could be a CERT problem */
+      failf(data, "%s", error_buffer);
+
+      return result;
+    }
+  }
+  else {
+    /* we have been connected fine, we're not waiting for anything else. */
+    connssl->connecting_state = ssl_connect_3;
+
+    /* Informational message */
+    infof(data, "SSL connection using %s / %s\n",
+          get_ssl_version_txt(connssl->handle),
+          SSL_get_cipher(connssl->handle));
+
+#ifdef HAS_ALPN
+    /* Sets data and len to negotiated protocol, len is 0 if no protocol was
+     * negotiated
+     */
+    if(data->set.ssl_enable_alpn) {
+      const unsigned char* neg_protocol;
+      unsigned int len;
+      SSL_get0_alpn_selected(connssl->handle, &neg_protocol, &len);
+      if(len != 0) {
+        infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol);
+
+#ifdef USE_NGHTTP2
+        if(len == NGHTTP2_PROTO_VERSION_ID_LEN &&
+           !memcmp(NGHTTP2_PROTO_VERSION_ID, neg_protocol, len)) {
+          conn->negnpn = CURL_HTTP_VERSION_2;
+        }
+        else
+#endif
+        if(len == ALPN_HTTP_1_1_LENGTH &&
+           !memcmp(ALPN_HTTP_1_1, neg_protocol, ALPN_HTTP_1_1_LENGTH)) {
+          conn->negnpn = CURL_HTTP_VERSION_1_1;
+        }
+      }
+      else
+        infof(data, "ALPN, server did not agree to a protocol\n");
+    }
+#endif
+
+    return CURLE_OK;
+  }
+}
+
+static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len)
+{
+  int i, ilen;
+
+  if((ilen = (int)len) < 0)
+    return 1; /* buffer too big */
+
+  i = i2t_ASN1_OBJECT(buf, ilen, a);
+
+  if(i >= ilen)
+    return 1; /* buffer too small */
+
+  return 0;
+}
+
+#define push_certinfo(_label, _num) \
+do {                              \
+  long info_len = BIO_get_mem_data(mem, &ptr); \
+  Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \
+  if(1!=BIO_reset(mem))                                          \
+    break;                                                       \
+} WHILE_FALSE
+
+static void pubkey_show(struct SessionHandle *data,
+                        BIO *mem,
+                        int num,
+                        const char *type,
+                        const char *name,
+                        BIGNUM *bn)
+{
+  char *ptr;
+  char namebuf[32];
+
+  snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
+
+  BN_print(mem, bn);
+  push_certinfo(namebuf, num);
+}
+
+#define print_pubkey_BN(_type, _name, _num)    \
+do {                              \
+  if(pubkey->pkey._type->_name) { \
+    pubkey_show(data, mem, _num, #_type, #_name, pubkey->pkey._type->_name); \
+  } \
+} WHILE_FALSE
+
+static int X509V3_ext(struct SessionHandle *data,
+                      int certnum,
+                      STACK_OF(X509_EXTENSION) *exts)
+{
+  int i;
+  size_t j;
+
+  if((int)sk_X509_EXTENSION_num(exts) <= 0)
+    /* no extensions, bail out */
+    return 1;
+
+  for(i=0; i < (int)sk_X509_EXTENSION_num(exts); i++) {
+    ASN1_OBJECT *obj;
+    X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
+    BUF_MEM *biomem;
+    char buf[512];
+    char *ptr=buf;
+    char namebuf[128];
+    BIO *bio_out = BIO_new(BIO_s_mem());
+
+    if(!bio_out)
+      return 1;
+
+    obj = X509_EXTENSION_get_object(ext);
+
+    asn1_object_dump(obj, namebuf, sizeof(namebuf));
+
+    if(!X509V3_EXT_print(bio_out, ext, 0, 0))
+      ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext));
+
+    BIO_get_mem_ptr(bio_out, &biomem);
+
+    for(j = 0; j < (size_t)biomem->length; j++) {
+      const char *sep="";
+      if(biomem->data[j] == '\n') {
+        sep=", ";
+        j++; /* skip the newline */
+      };
+      while((j<(size_t)biomem->length) && (biomem->data[j] == ' '))
+        j++;
+      if(j<(size_t)biomem->length)
+        ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep,
+                      biomem->data[j]);
+    }
+
+    Curl_ssl_push_certinfo(data, certnum, namebuf, buf);
+
+    BIO_free(bio_out);
+
+  }
+  return 0; /* all is fine */
+}
+
+static CURLcode get_cert_chain(struct connectdata *conn,
+                               struct ssl_connect_data *connssl)
+
+{
+  CURLcode result;
+  STACK_OF(X509) *sk;
+  int i;
+  struct SessionHandle *data = conn->data;
+  int numcerts;
+  BIO *mem;
+
+  sk = SSL_get_peer_cert_chain(connssl->handle);
+  if(!sk) {
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  numcerts = sk_X509_num(sk);
+
+  result = Curl_ssl_init_certinfo(data, numcerts);
+  if(result) {
+    return result;
+  }
+
+  mem = BIO_new(BIO_s_mem());
+
+  for(i = 0; i < numcerts; i++) {
+    ASN1_INTEGER *num;
+    X509 *x = sk_X509_value(sk, i);
+    EVP_PKEY *pubkey=NULL;
+    int j;
+    char *ptr;
+    ASN1_BIT_STRING *psig;
+
+    X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
+    push_certinfo("Subject", i);
+
+    X509_NAME_print_ex(mem, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
+    push_certinfo("Issuer", i);
+
+    BIO_printf(mem, "%lx", X509_get_version(x));
+    push_certinfo("Version", i);
+
+    num = X509_get_serialNumber(x);
+    if(num->type == V_ASN1_NEG_INTEGER)
+      BIO_puts(mem, "-");
+    for(j = 0; j < num->length; j++)
+      BIO_printf(mem, "%02x", num->data[j]);
+    push_certinfo("Serial Number", i);
+
+#if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS)
+    {
+      X509_ALGOR *palg;
+      ASN1_STRING *a = ASN1_STRING_new();
+      if(a) {
+        X509_get0_signature(&psig, &palg, x);
+        X509_signature_print(mem, palg, a);
+        ASN1_STRING_free(a);
+      }
+      i2a_ASN1_OBJECT(mem, palg->algorithm);
+      push_certinfo("Public Key Algorithm", i);
+
+      X509V3_ext(data, i, X509_get0_extensions(x));
+    }
+#else
+    {
+      /* before OpenSSL 1.0.2 */
+      X509_CINF *cinf = x->cert_info;
+
+      i2a_ASN1_OBJECT(mem, cinf->signature->algorithm);
+      push_certinfo("Signature Algorithm", i);
+
+      i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm);
+      push_certinfo("Public Key Algorithm", i);
+
+      X509V3_ext(data, i, cinf->extensions);
+
+      psig = x->signature;
+    }
+#endif
+
+    ASN1_TIME_print(mem, X509_get_notBefore(x));
+    push_certinfo("Start date", i);
+
+    ASN1_TIME_print(mem, X509_get_notAfter(x));
+    push_certinfo("Expire date", i);
+
+    pubkey = X509_get_pubkey(x);
+    if(!pubkey)
+      infof(data, "   Unable to load public key\n");
+    else {
+      switch(pubkey->type) {
+      case EVP_PKEY_RSA:
+        BIO_printf(mem, "%d", BN_num_bits(pubkey->pkey.rsa->n));
+        push_certinfo("RSA Public Key", i);
+
+        print_pubkey_BN(rsa, n, i);
+        print_pubkey_BN(rsa, e, i);
+        print_pubkey_BN(rsa, d, i);
+        print_pubkey_BN(rsa, p, i);
+        print_pubkey_BN(rsa, q, i);
+        print_pubkey_BN(rsa, dmp1, i);
+        print_pubkey_BN(rsa, dmq1, i);
+        print_pubkey_BN(rsa, iqmp, i);
+        break;
+      case EVP_PKEY_DSA:
+        print_pubkey_BN(dsa, p, i);
+        print_pubkey_BN(dsa, q, i);
+        print_pubkey_BN(dsa, g, i);
+        print_pubkey_BN(dsa, priv_key, i);
+        print_pubkey_BN(dsa, pub_key, i);
+        break;
+      case EVP_PKEY_DH:
+        print_pubkey_BN(dh, p, i);
+        print_pubkey_BN(dh, g, i);
+        print_pubkey_BN(dh, priv_key, i);
+        print_pubkey_BN(dh, pub_key, i);
+        break;
+#if 0
+      case EVP_PKEY_EC: /* symbol not present in OpenSSL 0.9.6 */
+        /* left TODO */
+        break;
+#endif
+      }
+      EVP_PKEY_free(pubkey);
+    }
+
+    for(j = 0; j < psig->length; j++)
+      BIO_printf(mem, "%02x:", psig->data[j]);
+    push_certinfo("Signature", i);
+
+    PEM_write_bio_X509(mem, x);
+    push_certinfo("Cert", i);
+  }
+
+  BIO_free(mem);
+
+  return CURLE_OK;
+}
+
+/*
+ * Heavily modified from:
+ * https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
+ */
+static CURLcode pkp_pin_peer_pubkey(struct SessionHandle *data, X509* cert,
+                                    const char *pinnedpubkey)
+{
+  /* Scratch */
+  int len1 = 0, len2 = 0;
+  unsigned char *buff1 = NULL, *temp = NULL;
+
+  /* Result is returned to caller */
+  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+
+  /* if a path wasn't specified, don't pin */
+  if(!pinnedpubkey)
+    return CURLE_OK;
+
+  if(!cert)
+    return result;
+
+  do {
+    /* Begin Gyrations to get the subjectPublicKeyInfo     */
+    /* Thanks to Viktor Dukhovni on the OpenSSL mailing list */
+
+    /* https://groups.google.com/group/mailing.openssl.users/browse_thread
+     /thread/d61858dae102c6c7 */
+    len1 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL);
+    if(len1 < 1)
+      break; /* failed */
+
+    /* https://www.openssl.org/docs/crypto/buffer.html */
+    buff1 = temp = OPENSSL_malloc(len1);
+    if(!buff1)
+      break; /* failed */
+
+    /* https://www.openssl.org/docs/crypto/d2i_X509.html */
+    len2 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &temp);
+
+    /*
+     * These checks are verifying we got back the same values as when we
+     * sized the buffer. It's pretty weak since they should always be the
+     * same. But it gives us something to test.
+     */
+    if((len1 != len2) || !temp || ((temp - buff1) != len1))
+      break; /* failed */
+
+    /* End Gyrations */
+
+    /* The one good exit point */
+    result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
+  } while(0);
+
+  /* https://www.openssl.org/docs/crypto/buffer.html */
+  if(buff1)
+    OPENSSL_free(buff1);
+
+  return result;
+}
+
+/*
+ * Get the server cert, verify it and show it etc, only call failf() if the
+ * 'strict' argument is TRUE as otherwise all this is for informational
+ * purposes only!
+ *
+ * We check certificates to authenticate the server; otherwise we risk
+ * man-in-the-middle attack.
+ */
+static CURLcode servercert(struct connectdata *conn,
+                           struct ssl_connect_data *connssl,
+                           bool strict)
+{
+  CURLcode result = CURLE_OK;
+  int rc;
+  long lerr, len;
+  struct SessionHandle *data = conn->data;
+  X509 *issuer;
+  FILE *fp;
+  char *buffer = data->state.buffer;
+  const char *ptr;
+  BIO *mem = BIO_new(BIO_s_mem());
+
+  if(data->set.ssl.certinfo)
+    /* we've been asked to gather certificate info! */
+    (void)get_cert_chain(conn, connssl);
+
+  connssl->server_cert = SSL_get_peer_certificate(connssl->handle);
+  if(!connssl->server_cert) {
+    if(!strict)
+      return CURLE_OK;
+
+    failf(data, "SSL: couldn't get peer certificate!");
+    return CURLE_PEER_FAILED_VERIFICATION;
+  }
+
+  infof(data, "Server certificate:\n");
+
+  rc = x509_name_oneline(X509_get_subject_name(connssl->server_cert),
+                         buffer, BUFSIZE);
+  infof(data, "\t subject: %s\n", rc?"[NONE]":buffer);
+
+  ASN1_TIME_print(mem, X509_get_notBefore(connssl->server_cert));
+  len = BIO_get_mem_data(mem, (char **) &ptr);
+  infof(data, "\t start date: %.*s\n", len, ptr);
+  rc = BIO_reset(mem);
+
+  ASN1_TIME_print(mem, X509_get_notAfter(connssl->server_cert));
+  len = BIO_get_mem_data(mem, (char **) &ptr);
+  infof(data, "\t expire date: %.*s\n", len, ptr);
+  rc = BIO_reset(mem);
+
+  BIO_free(mem);
+
+  if(data->set.ssl.verifyhost) {
+    result = verifyhost(conn, connssl->server_cert);
+    if(result) {
+      X509_free(connssl->server_cert);
+      connssl->server_cert = NULL;
+      return result;
+    }
+  }
+
+  rc = x509_name_oneline(X509_get_issuer_name(connssl->server_cert),
+                         buffer, BUFSIZE);
+  if(rc) {
+    if(strict)
+      failf(data, "SSL: couldn't get X509-issuer name!");
+    result = CURLE_SSL_CONNECT_ERROR;
+  }
+  else {
+    infof(data, "\t issuer: %s\n", buffer);
+
+    /* We could do all sorts of certificate verification stuff here before
+       deallocating the certificate. */
+
+    /* e.g. match issuer name with provided issuer certificate */
+    if(data->set.str[STRING_SSL_ISSUERCERT]) {
+      fp = fopen(data->set.str[STRING_SSL_ISSUERCERT], FOPEN_READTEXT);
+      if(!fp) {
+        if(strict)
+          failf(data, "SSL: Unable to open issuer cert (%s)",
+                data->set.str[STRING_SSL_ISSUERCERT]);
+        X509_free(connssl->server_cert);
+        connssl->server_cert = NULL;
+        return CURLE_SSL_ISSUER_ERROR;
+      }
+
+      issuer = PEM_read_X509(fp, NULL, ZERO_NULL, NULL);
+      if(!issuer) {
+        if(strict)
+          failf(data, "SSL: Unable to read issuer cert (%s)",
+                data->set.str[STRING_SSL_ISSUERCERT]);
+        X509_free(connssl->server_cert);
+        X509_free(issuer);
+        fclose(fp);
+        return CURLE_SSL_ISSUER_ERROR;
+      }
+
+      fclose(fp);
+
+      if(X509_check_issued(issuer, connssl->server_cert) != X509_V_OK) {
+        if(strict)
+          failf(data, "SSL: Certificate issuer check failed (%s)",
+                data->set.str[STRING_SSL_ISSUERCERT]);
+        X509_free(connssl->server_cert);
+        X509_free(issuer);
+        connssl->server_cert = NULL;
+        return CURLE_SSL_ISSUER_ERROR;
+      }
+
+      infof(data, "\t SSL certificate issuer check ok (%s)\n",
+            data->set.str[STRING_SSL_ISSUERCERT]);
+      X509_free(issuer);
+    }
+
+    lerr = data->set.ssl.certverifyresult =
+      SSL_get_verify_result(connssl->handle);
+
+    if(data->set.ssl.certverifyresult != X509_V_OK) {
+      if(data->set.ssl.verifypeer) {
+        /* We probably never reach this, because SSL_connect() will fail
+           and we return earlier if verifypeer is set? */
+        if(strict)
+          failf(data, "SSL certificate verify result: %s (%ld)",
+                X509_verify_cert_error_string(lerr), lerr);
+        result = CURLE_PEER_FAILED_VERIFICATION;
+      }
+      else
+        infof(data, "\t SSL certificate verify result: %s (%ld),"
+              " continuing anyway.\n",
+              X509_verify_cert_error_string(lerr), lerr);
+    }
+    else
+      infof(data, "\t SSL certificate verify ok.\n");
+  }
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+    !defined(OPENSSL_IS_BORINGSSL)
+  if(data->set.ssl.verifystatus) {
+    result = verifystatus(conn, connssl);
+    if(result) {
+      X509_free(connssl->server_cert);
+      connssl->server_cert = NULL;
+      return result;
+    }
+  }
+#endif
+
+  if(!strict)
+    /* when not strict, we don't bother about the verify cert problems */
+    result = CURLE_OK;
+
+  ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
+  if(!result && ptr) {
+    result = pkp_pin_peer_pubkey(data, connssl->server_cert, ptr);
+    if(result)
+      failf(data, "SSL: public key does not match pinned public key!");
+  }
+
+  X509_free(connssl->server_cert);
+  connssl->server_cert = NULL;
+  connssl->connecting_state = ssl_connect_done;
+
+  return result;
+}
+
+static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
+{
+  CURLcode result = CURLE_OK;
+  void *old_ssl_sessionid = NULL;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  bool incache;
+  SSL_SESSION *our_ssl_sessionid;
+
+  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+  our_ssl_sessionid = SSL_get1_session(connssl->handle);
+
+  /* SSL_get1_session() will increment the reference count and the session
+     will stay in memory until explicitly freed with SSL_SESSION_free(3),
+     regardless of its state. */
+
+  incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
+  if(incache) {
+    if(old_ssl_sessionid != our_ssl_sessionid) {
+      infof(data, "old SSL session ID is stale, removing\n");
+      Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+      incache = FALSE;
+    }
+  }
+
+  if(!incache) {
+    result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
+                                   0 /* unknown size */);
+    if(result) {
+      failf(data, "failed to store ssl session");
+      return result;
+    }
+  }
+  else {
+    /* Session was incache, so refcount already incremented earlier.
+     * Avoid further increments with each SSL_get1_session() call.
+     * This does not free the session as refcount remains > 0
+     */
+    SSL_SESSION_free(our_ssl_sessionid);
+  }
+
+  /*
+   * We check certificates to authenticate the server; otherwise we risk
+   * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to
+   * verify the peer ignore faults and failures from the server cert
+   * operations.
+   */
+
+  result = servercert(conn, connssl,
+                      (data->set.ssl.verifypeer || data->set.ssl.verifyhost));
+
+  if(!result)
+    connssl->connecting_state = ssl_connect_done;
+
+  return result;
+}
+
+static Curl_recv ossl_recv;
+static Curl_send ossl_send;
+
+static CURLcode ossl_connect_common(struct connectdata *conn,
+                                    int sockindex,
+                                    bool nonblocking,
+                                    bool *done)
+{
+  CURLcode result;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  long timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1 == connssl->connecting_state) {
+    /* Find out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    result = ossl_connect_step1(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading ||
+       connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if this
+     * connection is done nonblocking and this loop would execute again. This
+     * permits the owner of a multi handle to abort a connection attempt
+     * before step2 has completed while ensuring that a client using select()
+     * or epoll() will always have a valid fdset to wait on.
+     */
+    result = ossl_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
+
+  } /* repeat step2 until all transactions are done. */
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = ossl_connect_step3(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = ossl_recv;
+    conn->send[sockindex] = ossl_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* Reset our connect state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn,
+                                       int sockindex,
+                                       bool *done)
+{
+  return ossl_connect_common(conn, sockindex, TRUE, done);
+}
+
+CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = ossl_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+bool Curl_ossl_data_pending(const struct connectdata *conn, int connindex)
+{
+  if(conn->ssl[connindex].handle)
+    /* SSL is in use */
+    return (0 != SSL_pending(conn->ssl[connindex].handle)) ? TRUE : FALSE;
+  else
+    return FALSE;
+}
+
+static ssize_t ossl_send(struct connectdata *conn,
+                         int sockindex,
+                         const void *mem,
+                         size_t len,
+                         CURLcode *curlcode)
+{
+  /* SSL_write() is said to return 'int' while write() and send() returns
+     'size_t' */
+  int err;
+  char error_buffer[120]; /* OpenSSL documents that this must be at least 120
+                             bytes long. */
+  unsigned long sslerror;
+  int memlen;
+  int rc;
+
+  ERR_clear_error();
+
+  memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
+  rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen);
+
+  if(rc <= 0) {
+    err = SSL_get_error(conn->ssl[sockindex].handle, rc);
+
+    switch(err) {
+    case SSL_ERROR_WANT_READ:
+    case SSL_ERROR_WANT_WRITE:
+      /* The operation did not complete; the same TLS/SSL I/O function
+         should be called again later. This is basically an EWOULDBLOCK
+         equivalent. */
+      *curlcode = CURLE_AGAIN;
+      return -1;
+    case SSL_ERROR_SYSCALL:
+      failf(conn->data, "SSL_write() returned SYSCALL, errno = %d",
+            SOCKERRNO);
+      *curlcode = CURLE_SEND_ERROR;
+      return -1;
+    case SSL_ERROR_SSL:
+      /*  A failure in the SSL library occurred, usually a protocol error.
+          The OpenSSL error queue contains more information on the error. */
+      sslerror = ERR_get_error();
+      failf(conn->data, "SSL_write() error: %s",
+            ERR_error_string(sslerror, error_buffer));
+      *curlcode = CURLE_SEND_ERROR;
+      return -1;
+    }
+    /* a true error */
+    failf(conn->data, "SSL_write() return error %d", err);
+    *curlcode = CURLE_SEND_ERROR;
+    return -1;
+  }
+  *curlcode = CURLE_OK;
+  return (ssize_t)rc; /* number of bytes */
+}
+
+static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
+                         int num,                  /* socketindex */
+                         char *buf,                /* store read data here */
+                         size_t buffersize,        /* max amount to read */
+                         CURLcode *curlcode)
+{
+  char error_buffer[120]; /* OpenSSL documents that this must be at
+                             least 120 bytes long. */
+  unsigned long sslerror;
+  ssize_t nread;
+  int buffsize;
+
+  ERR_clear_error();
+
+  buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
+  nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, buffsize);
+  if(nread <= 0) {
+    /* failed SSL_read */
+    int err = SSL_get_error(conn->ssl[num].handle, (int)nread);
+
+    switch(err) {
+    case SSL_ERROR_NONE: /* this is not an error */
+    case SSL_ERROR_ZERO_RETURN: /* no more data */
+      break;
+    case SSL_ERROR_WANT_READ:
+    case SSL_ERROR_WANT_WRITE:
+      /* there's data pending, re-invoke SSL_read() */
+      *curlcode = CURLE_AGAIN;
+      return -1;
+    default:
+      /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return
+         value/errno" */
+      /* https://www.openssl.org/docs/crypto/ERR_get_error.html */
+      sslerror = ERR_get_error();
+      if((nread < 0) || sslerror) {
+        /* If the return code was negative or there actually is an error in the
+           queue */
+        failf(conn->data, "SSL read: %s, errno %d",
+              ERR_error_string(sslerror, error_buffer),
+              SOCKERRNO);
+        *curlcode = CURLE_RECV_ERROR;
+        return -1;
+      }
+    }
+  }
+  return nread;
+}
+
+size_t Curl_ossl_version(char *buffer, size_t size)
+{
+#ifdef OPENSSL_IS_BORINGSSL
+  return snprintf(buffer, size, "BoringSSL");
+#else /* OPENSSL_IS_BORINGSSL */
+  char sub[3];
+  unsigned long ssleay_value;
+  sub[2]='\0';
+  sub[1]='\0';
+  ssleay_value=SSLeay();
+  if(ssleay_value < 0x906000) {
+    ssleay_value=SSLEAY_VERSION_NUMBER;
+    sub[0]='\0';
+  }
+  else {
+    if(ssleay_value&0xff0) {
+      int minor_ver = (ssleay_value >> 4) & 0xff;
+      if(minor_ver > 26) {
+        /* handle extended version introduced for 0.9.8za */
+        sub[1] = (char) ((minor_ver - 1) % 26 + 'a' + 1);
+        sub[0] = 'z';
+      }
+      else {
+        sub[0]=(char)(((ssleay_value>>4)&0xff) + 'a' -1);
+      }
+    }
+    else
+      sub[0]='\0';
+  }
+
+  return snprintf(buffer, size, "%s/%lx.%lx.%lx%s",
+#ifdef LIBRESSL_VERSION_NUMBER
+                  "LibreSSL"
+#else
+                  "OpenSSL"
+#endif
+                  , (ssleay_value>>28)&0xf,
+                  (ssleay_value>>20)&0xff,
+                  (ssleay_value>>12)&0xff,
+                  sub);
+#endif /* OPENSSL_IS_BORINGSSL */
+}
+
+/* can be called with data == NULL */
+int Curl_ossl_random(struct SessionHandle *data, unsigned char *entropy,
+                     size_t length)
+{
+  if(data) {
+    Curl_ossl_seed(data); /* Initiate the seed if not already done */
+  }
+  RAND_bytes(entropy, curlx_uztosi(length));
+  return 0; /* 0 as in no problem */
+}
+
+void Curl_ossl_md5sum(unsigned char *tmp, /* input */
+                      size_t tmplen,
+                      unsigned char *md5sum /* output */,
+                      size_t unused)
+{
+  MD5_CTX MD5pw;
+  (void)unused;
+  MD5_Init(&MD5pw);
+  MD5_Update(&MD5pw, tmp, tmplen);
+  MD5_Final(md5sum, &MD5pw);
+}
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256)
+void Curl_ossl_sha256sum(const unsigned char *tmp, /* input */
+                      size_t tmplen,
+                      unsigned char *sha256sum /* output */,
+                      size_t unused)
+{
+  SHA256_CTX SHA256pw;
+  (void)unused;
+  SHA256_Init(&SHA256pw);
+  SHA256_Update(&SHA256pw, tmp, tmplen);
+  SHA256_Final(sha256sum, &SHA256pw);
+}
+#endif
+
+bool Curl_ossl_cert_status_request(void)
+{
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+    !defined(OPENSSL_IS_BORINGSSL)
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+#endif /* USE_OPENSSL */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/openssl.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/openssl.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/openssl.h	(revision 164)
@@ -0,0 +1,120 @@
+#ifndef HEADER_CURL_SSLUSE_H
+#define HEADER_CURL_SSLUSE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_OPENSSL
+/*
+ * This header should only be needed to get included by vtls.c and openssl.c
+ */
+
+#include "urldata.h"
+
+CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn,
+                                       int sockindex,
+                                       bool *done);
+
+/* close a SSL connection */
+void Curl_ossl_close(struct connectdata *conn, int sockindex);
+
+/* tell OpenSSL to close down all open information regarding connections (and
+   thus session ID caching etc) */
+void Curl_ossl_close_all(struct SessionHandle *data);
+
+/* Sets an OpenSSL engine */
+CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine);
+
+/* function provided for the generic SSL-layer, called when a session id
+   should be freed */
+void Curl_ossl_session_free(void *ptr);
+
+/* Sets engine as default for all SSL operations */
+CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data);
+
+/* Build list of OpenSSL engines */
+struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data);
+
+int Curl_ossl_init(void);
+void Curl_ossl_cleanup(void);
+
+size_t Curl_ossl_version(char *buffer, size_t size);
+int Curl_ossl_check_cxn(struct connectdata *cxn);
+int Curl_ossl_shutdown(struct connectdata *conn, int sockindex);
+bool Curl_ossl_data_pending(const struct connectdata *conn,
+                            int connindex);
+
+/* return 0 if a find random is filled in */
+int Curl_ossl_random(struct SessionHandle *data, unsigned char *entropy,
+                     size_t length);
+void Curl_ossl_md5sum(unsigned char *tmp, /* input */
+                      size_t tmplen,
+                      unsigned char *md5sum /* output */,
+                      size_t unused);
+void Curl_ossl_sha256sum(const unsigned char *tmp, /* input */
+                      size_t tmplen,
+                      unsigned char *sha256sum /* output */,
+                      size_t unused);
+
+bool Curl_ossl_cert_status_request(void);
+
+/* Set the API backend definition to OpenSSL */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_OPENSSL
+
+/* this backend supports the CAPATH option */
+#define have_curlssl_ca_path 1
+
+/* this backend supports CURLOPT_CERTINFO */
+#define have_curlssl_certinfo 1
+
+/* this backend suppots CURLOPT_SSL_CTX_* */
+#define have_curlssl_ssl_ctx 1
+
+/* API setup for OpenSSL */
+#define curlssl_init Curl_ossl_init
+#define curlssl_cleanup Curl_ossl_cleanup
+#define curlssl_connect Curl_ossl_connect
+#define curlssl_connect_nonblocking Curl_ossl_connect_nonblocking
+#define curlssl_session_free(x) Curl_ossl_session_free(x)
+#define curlssl_close_all Curl_ossl_close_all
+#define curlssl_close Curl_ossl_close
+#define curlssl_shutdown(x,y) Curl_ossl_shutdown(x,y)
+#define curlssl_set_engine(x,y) Curl_ossl_set_engine(x,y)
+#define curlssl_set_engine_default(x) Curl_ossl_set_engine_default(x)
+#define curlssl_engines_list(x) Curl_ossl_engines_list(x)
+#define curlssl_version Curl_ossl_version
+#define curlssl_check_cxn Curl_ossl_check_cxn
+#define curlssl_data_pending(x,y) Curl_ossl_data_pending(x,y)
+#define curlssl_random(x,y,z) Curl_ossl_random(x,y,z)
+#define curlssl_md5sum(a,b,c,d) Curl_ossl_md5sum(a,b,c,d)
+#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256)
+#define curlssl_sha256sum(a,b,c,d) Curl_ossl_sha256sum(a,b,c,d)
+#endif
+#define curlssl_cert_status_request() Curl_ossl_cert_status_request()
+
+#define DEFAULT_CIPHER_SELECTION \
+  "ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH"
+
+#endif /* USE_OPENSSL */
+#endif /* HEADER_CURL_SSLUSE_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/polarssl.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/polarssl.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/polarssl.c	(revision 164)
@@ -0,0 +1,753 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all PolarSSL-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_POLARSSL
+
+#include <polarssl/net.h>
+#include <polarssl/ssl.h>
+#include <polarssl/certs.h>
+#include <polarssl/x509.h>
+#include <polarssl/version.h>
+
+#if POLARSSL_VERSION_NUMBER < 0x01030000
+#error too old PolarSSL
+#endif
+
+#include <polarssl/error.h>
+#include <polarssl/entropy.h>
+#include <polarssl/ctr_drbg.h>
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "polarssl.h"
+#include "vtls.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "rawstr.h"
+#include "polarssl_threadlock.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* apply threading? */
+#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+#define THREADING_SUPPORT
+#endif
+
+#if defined(THREADING_SUPPORT)
+static entropy_context entropy;
+
+static int  entropy_init_initialized  = 0;
+
+/* start of entropy_init_mutex() */
+static void entropy_init_mutex(entropy_context *ctx)
+{
+  /* lock 0 = entropy_init_mutex() */
+  Curl_polarsslthreadlock_lock_function(0);
+  if(entropy_init_initialized == 0) {
+    entropy_init(ctx);
+    entropy_init_initialized = 1;
+  }
+  Curl_polarsslthreadlock_unlock_function(0);
+}
+/* end of entropy_init_mutex() */
+
+/* start of entropy_func_mutex() */
+static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
+{
+    int ret;
+    /* lock 1 = entropy_func_mutex() */
+    Curl_polarsslthreadlock_lock_function(1);
+    ret = entropy_func(data, output, len);
+    Curl_polarsslthreadlock_unlock_function(1);
+
+    return ret;
+}
+/* end of entropy_func_mutex() */
+
+#endif /* THREADING_SUPPORT */
+
+/* Define this to enable lots of debugging for PolarSSL */
+#undef POLARSSL_DEBUG
+
+#ifdef POLARSSL_DEBUG
+static void polarssl_debug(void *context, int level, const char *line)
+{
+  struct SessionHandle *data = NULL;
+
+  if(!context)
+    return;
+
+  data = (struct SessionHandle *)context;
+
+  infof(data, "%s", line);
+  (void) level;
+}
+#else
+#endif
+
+/* ALPN for http2? */
+#ifdef POLARSSL_SSL_ALPN
+#  define HAS_ALPN
+#endif
+
+static Curl_recv polarssl_recv;
+static Curl_send polarssl_send;
+
+
+static CURLcode
+polarssl_connect_step1(struct connectdata *conn,
+                     int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+
+  bool sni = TRUE; /* default is SNI enabled */
+  int ret = -1;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif
+  void *old_session = NULL;
+  size_t old_session_size = 0;
+  char errorbuf[128];
+  errorbuf[0]=0;
+
+  /* PolarSSL only supports SSLv3 and TLSv1 */
+  if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
+    failf(data, "PolarSSL does not support SSLv2");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+  else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
+    sni = FALSE; /* SSLv3 has no SNI */
+
+#ifdef THREADING_SUPPORT
+  entropy_init_mutex(&entropy);
+
+  if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func_mutex, &entropy,
+                               connssl->ssn.id, connssl->ssn.length)) != 0) {
+#ifdef POLARSSL_ERROR_C
+     error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+     failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
+                                                            -ret, errorbuf);
+  }
+#else
+  entropy_init(&connssl->entropy);
+
+  if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func, &connssl->entropy,
+                                connssl->ssn.id, connssl->ssn.length)) != 0) {
+#ifdef POLARSSL_ERROR_C
+     error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+     failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
+                                                            -ret, errorbuf);
+  }
+#endif /* THREADING_SUPPORT */
+
+  /* Load the trusted CA */
+  memset(&connssl->cacert, 0, sizeof(x509_crt));
+
+  if(data->set.str[STRING_SSL_CAFILE]) {
+    ret = x509_crt_parse_file(&connssl->cacert,
+                              data->set.str[STRING_SSL_CAFILE]);
+
+    if(ret<0) {
+#ifdef POLARSSL_ERROR_C
+      error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+      failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s",
+            data->set.str[STRING_SSL_CAFILE], -ret, errorbuf);
+
+      if(data->set.ssl.verifypeer)
+        return CURLE_SSL_CACERT_BADFILE;
+    }
+  }
+
+  if(data->set.str[STRING_SSL_CAPATH]) {
+    ret = x509_crt_parse_path(&connssl->cacert,
+                              data->set.str[STRING_SSL_CAPATH]);
+
+    if(ret<0) {
+#ifdef POLARSSL_ERROR_C
+      error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+      failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s",
+            data->set.str[STRING_SSL_CAPATH], -ret, errorbuf);
+
+      if(data->set.ssl.verifypeer)
+        return CURLE_SSL_CACERT_BADFILE;
+    }
+  }
+
+  /* Load the client certificate */
+  memset(&connssl->clicert, 0, sizeof(x509_crt));
+
+  if(data->set.str[STRING_CERT]) {
+    ret = x509_crt_parse_file(&connssl->clicert,
+                              data->set.str[STRING_CERT]);
+
+    if(ret) {
+#ifdef POLARSSL_ERROR_C
+      error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+      failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s",
+            data->set.str[STRING_CERT], -ret, errorbuf);
+
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  /* Load the client private key */
+  if(data->set.str[STRING_KEY]) {
+    pk_context pk;
+    pk_init(&pk);
+    ret = pk_parse_keyfile(&pk, data->set.str[STRING_KEY],
+                           data->set.str[STRING_KEY_PASSWD]);
+    if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA))
+      ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
+    if(ret == 0)
+      rsa_copy(&connssl->rsa, pk_rsa(pk));
+    else
+      rsa_free(&connssl->rsa);
+    pk_free(&pk);
+
+    if(ret) {
+#ifdef POLARSSL_ERROR_C
+      error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+      failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s",
+            data->set.str[STRING_KEY], -ret, errorbuf);
+
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  /* Load the CRL */
+  memset(&connssl->crl, 0, sizeof(x509_crl));
+
+  if(data->set.str[STRING_SSL_CRLFILE]) {
+    ret = x509_crl_parse_file(&connssl->crl,
+                              data->set.str[STRING_SSL_CRLFILE]);
+
+    if(ret) {
+#ifdef POLARSSL_ERROR_C
+      error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+      failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s",
+            data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf);
+
+      return CURLE_SSL_CRL_BADFILE;
+    }
+  }
+
+  infof(data, "PolarSSL: Connecting to %s:%d\n",
+        conn->host.name, conn->remote_port);
+
+  if(ssl_init(&connssl->ssl)) {
+    failf(data, "PolarSSL: ssl_init failed");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  switch(data->set.ssl.version) {
+  default:
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+    ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_1);
+    break;
+  case CURL_SSLVERSION_SSLv3:
+    ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_0);
+    ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_0);
+    infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n");
+    break;
+  case CURL_SSLVERSION_TLSv1_0:
+    ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_1);
+    ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_1);
+    infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.0\n");
+    break;
+  case CURL_SSLVERSION_TLSv1_1:
+    ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_2);
+    ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_2);
+    infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.1\n");
+    break;
+  case CURL_SSLVERSION_TLSv1_2:
+    ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_3);
+    ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_3);
+    infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.2\n");
+    break;
+  }
+
+  ssl_set_endpoint(&connssl->ssl, SSL_IS_CLIENT);
+  ssl_set_authmode(&connssl->ssl, SSL_VERIFY_OPTIONAL);
+
+  ssl_set_rng(&connssl->ssl, ctr_drbg_random,
+              &connssl->ctr_drbg);
+  ssl_set_bio(&connssl->ssl,
+              net_recv, &conn->sock[sockindex],
+              net_send, &conn->sock[sockindex]);
+
+  ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites());
+  if(!Curl_ssl_getsessionid(conn, &old_session, &old_session_size)) {
+    memcpy(&connssl->ssn, old_session, old_session_size);
+    infof(data, "PolarSSL re-using session\n");
+  }
+
+  ssl_set_session(&connssl->ssl,
+                  &connssl->ssn);
+
+  ssl_set_ca_chain(&connssl->ssl,
+                   &connssl->cacert,
+                   &connssl->crl,
+                   conn->host.name);
+
+  ssl_set_own_cert_rsa(&connssl->ssl,
+                       &connssl->clicert, &connssl->rsa);
+
+  if(!Curl_inet_pton(AF_INET, conn->host.name, &addr) &&
+#ifdef ENABLE_IPV6
+     !Curl_inet_pton(AF_INET6, conn->host.name, &addr) &&
+#endif
+     sni && ssl_set_hostname(&connssl->ssl, conn->host.name)) {
+     infof(data, "WARNING: failed to configure "
+                 "server name indication (SNI) TLS extension\n");
+  }
+
+#ifdef HAS_ALPN
+  if(data->set.ssl_enable_alpn) {
+    static const char* protocols[3];
+    int cur = 0;
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
+      protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
+      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+    }
+#endif
+
+    protocols[cur++] = ALPN_HTTP_1_1;
+    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+    protocols[cur] = NULL;
+
+    ssl_set_alpn_protocols(&connssl->ssl, protocols);
+  }
+#endif
+
+#ifdef POLARSSL_DEBUG
+  ssl_set_dbg(&connssl->ssl, polarssl_debug, data);
+#endif
+
+  connssl->connecting_state = ssl_connect_2;
+
+  return CURLE_OK;
+}
+
+static CURLcode
+polarssl_connect_step2(struct connectdata *conn,
+                     int sockindex)
+{
+  int ret;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  char buffer[1024];
+
+  char errorbuf[128];
+  errorbuf[0] = 0;
+
+  conn->recv[sockindex] = polarssl_recv;
+  conn->send[sockindex] = polarssl_send;
+
+  ret = ssl_handshake(&connssl->ssl);
+
+  switch(ret) {
+  case 0:
+    break;
+
+  case POLARSSL_ERR_NET_WANT_READ:
+    connssl->connecting_state = ssl_connect_2_reading;
+    return CURLE_OK;
+
+  case POLARSSL_ERR_NET_WANT_WRITE:
+    connssl->connecting_state = ssl_connect_2_writing;
+    return CURLE_OK;
+
+  default:
+#ifdef POLARSSL_ERROR_C
+    error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+    failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s",
+          -ret, errorbuf);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  infof(data, "PolarSSL: Handshake complete, cipher is %s\n",
+        ssl_get_ciphersuite(&conn->ssl[sockindex].ssl) );
+
+  ret = ssl_get_verify_result(&conn->ssl[sockindex].ssl);
+
+  if(ret && data->set.ssl.verifypeer) {
+    if(ret & BADCERT_EXPIRED)
+      failf(data, "Cert verify failed: BADCERT_EXPIRED");
+
+    if(ret & BADCERT_REVOKED) {
+      failf(data, "Cert verify failed: BADCERT_REVOKED");
+      return CURLE_SSL_CACERT;
+    }
+
+    if(ret & BADCERT_CN_MISMATCH)
+      failf(data, "Cert verify failed: BADCERT_CN_MISMATCH");
+
+    if(ret & BADCERT_NOT_TRUSTED)
+      failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED");
+
+    return CURLE_PEER_FAILED_VERIFICATION;
+  }
+
+  if(ssl_get_peer_cert(&(connssl->ssl))) {
+    /* If the session was resumed, there will be no peer certs */
+    memset(buffer, 0, sizeof(buffer));
+
+    if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ",
+                     ssl_get_peer_cert(&(connssl->ssl))) != -1)
+      infof(data, "Dumping cert info:\n%s\n", buffer);
+  }
+
+#ifdef HAS_ALPN
+  if(data->set.ssl_enable_alpn) {
+    const char *next_protocol = ssl_get_alpn_protocol(&connssl->ssl);
+
+    if(next_protocol != NULL) {
+      infof(data, "ALPN, server accepted to use %s\n", next_protocol);
+
+#ifdef USE_NGHTTP2
+      if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
+                  NGHTTP2_PROTO_VERSION_ID_LEN)) {
+        conn->negnpn = CURL_HTTP_VERSION_2;
+      }
+      else
+#endif
+      if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) {
+        conn->negnpn = CURL_HTTP_VERSION_1_1;
+      }
+    }
+    else
+      infof(data, "ALPN, server did not agree to a protocol\n");
+  }
+#endif
+
+  connssl->connecting_state = ssl_connect_3;
+  infof(data, "SSL connected\n");
+
+  return CURLE_OK;
+}
+
+static CURLcode
+polarssl_connect_step3(struct connectdata *conn,
+                     int sockindex)
+{
+  CURLcode result = CURLE_OK;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct SessionHandle *data = conn->data;
+  void *old_ssl_sessionid = NULL;
+  ssl_session *our_ssl_sessionid = &conn->ssl[sockindex].ssn;
+  bool incache;
+
+  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+  /* Save the current session data for possible re-use */
+  incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
+  if(incache) {
+    if(old_ssl_sessionid != our_ssl_sessionid) {
+      infof(data, "old SSL session ID is stale, removing\n");
+      Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+      incache = FALSE;
+    }
+  }
+
+  if(!incache) {
+    void *new_session = malloc(sizeof(ssl_session));
+
+    if(new_session) {
+      memcpy(new_session, our_ssl_sessionid, sizeof(ssl_session));
+
+      result = Curl_ssl_addsessionid(conn, new_session, sizeof(ssl_session));
+    }
+    else
+      result = CURLE_OUT_OF_MEMORY;
+
+    if(result) {
+      failf(data, "failed to store ssl session");
+      return result;
+    }
+  }
+
+  connssl->connecting_state = ssl_connect_done;
+
+  return CURLE_OK;
+}
+
+static ssize_t polarssl_send(struct connectdata *conn,
+                             int sockindex,
+                             const void *mem,
+                             size_t len,
+                             CURLcode *curlcode)
+{
+  int ret = -1;
+
+  ret = ssl_write(&conn->ssl[sockindex].ssl,
+                  (unsigned char *)mem, len);
+
+  if(ret < 0) {
+    *curlcode = (ret == POLARSSL_ERR_NET_WANT_WRITE) ?
+      CURLE_AGAIN : CURLE_SEND_ERROR;
+    ret = -1;
+  }
+
+  return ret;
+}
+
+void Curl_polarssl_close(struct connectdata *conn, int sockindex)
+{
+  rsa_free(&conn->ssl[sockindex].rsa);
+  x509_crt_free(&conn->ssl[sockindex].clicert);
+  x509_crt_free(&conn->ssl[sockindex].cacert);
+  x509_crl_free(&conn->ssl[sockindex].crl);
+  ssl_free(&conn->ssl[sockindex].ssl);
+}
+
+static ssize_t polarssl_recv(struct connectdata *conn,
+                             int num,
+                             char *buf,
+                             size_t buffersize,
+                             CURLcode *curlcode)
+{
+  int ret = -1;
+  ssize_t len = -1;
+
+  memset(buf, 0, buffersize);
+  ret = ssl_read(&conn->ssl[num].ssl, (unsigned char *)buf, buffersize);
+
+  if(ret <= 0) {
+    if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY)
+      return 0;
+
+    *curlcode = (ret == POLARSSL_ERR_NET_WANT_READ) ?
+      CURLE_AGAIN : CURLE_RECV_ERROR;
+    return -1;
+  }
+
+  len = ret;
+
+  return len;
+}
+
+void Curl_polarssl_session_free(void *ptr)
+{
+  free(ptr);
+}
+
+/* 1.3.10 was the first rebranded version. All new releases (in 1.3 branch and
+   higher) will be mbed TLS branded.. */
+
+size_t Curl_polarssl_version(char *buffer, size_t size)
+{
+  unsigned int version = version_get_number();
+  return snprintf(buffer, size, "%s/%d.%d.%d",
+                  version >= 0x01030A00?"mbedTLS":"PolarSSL",
+                  version>>24, (version>>16)&0xff, (version>>8)&0xff);
+}
+
+static CURLcode
+polarssl_connect_common(struct connectdata *conn,
+                        int sockindex,
+                        bool nonblocking,
+                        bool *done)
+{
+  CURLcode result;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  long timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1 == connssl->connecting_state) {
+    /* Find out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    result = polarssl_connect_step1(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading ||
+       connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if
+     * this connection is part of a multi handle and this loop would
+     * execute again. This permits the owner of a multi handle to
+     * abort a connection attempt before step2 has completed while
+     * ensuring that a client using select() or epoll() will always
+     * have a valid fdset to wait on.
+     */
+    result = polarssl_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
+
+  } /* repeat step2 until all transactions are done. */
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = polarssl_connect_step3(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = polarssl_recv;
+    conn->send[sockindex] = polarssl_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* Reset our connect state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+CURLcode
+Curl_polarssl_connect_nonblocking(struct connectdata *conn,
+                                int sockindex,
+                                bool *done)
+{
+  return polarssl_connect_common(conn, sockindex, TRUE, done);
+}
+
+
+CURLcode
+Curl_polarssl_connect(struct connectdata *conn,
+                    int sockindex)
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = polarssl_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+/*
+ * return 0 error initializing SSL
+ * return 1 SSL initialized successfully
+ */
+int Curl_polarssl_init(void)
+{
+  return Curl_polarsslthreadlock_thread_setup();
+}
+
+void Curl_polarssl_cleanup(void)
+{
+  (void)Curl_polarsslthreadlock_thread_cleanup();
+}
+
+#endif /* USE_POLARSSL */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/polarssl.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/polarssl.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/polarssl.h	(revision 164)
@@ -0,0 +1,75 @@
+#ifndef HEADER_CURL_POLARSSL_H
+#define HEADER_CURL_POLARSSL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_POLARSSL
+
+/* Called on first use PolarSSL, setup threading if supported */
+int  Curl_polarssl_init(void);
+void Curl_polarssl_cleanup(void);
+
+
+CURLcode Curl_polarssl_connect(struct connectdata *conn, int sockindex);
+
+CURLcode Curl_polarssl_connect_nonblocking(struct connectdata *conn,
+                                           int sockindex,
+                                           bool *done);
+
+ /* close a SSL connection */
+void Curl_polarssl_close(struct connectdata *conn, int sockindex);
+
+void Curl_polarssl_session_free(void *ptr);
+size_t Curl_polarssl_version(char *buffer, size_t size);
+int Curl_polarssl_shutdown(struct connectdata *conn, int sockindex);
+
+/* Set the API backend definition to PolarSSL */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_POLARSSL
+
+/* this backend supports the CAPATH option */
+#define have_curlssl_ca_path 1
+
+/* API setup for PolarSSL */
+#define curlssl_init() Curl_polarssl_init()
+#define curlssl_cleanup() Curl_polarssl_cleanup()
+#define curlssl_connect Curl_polarssl_connect
+#define curlssl_connect_nonblocking Curl_polarssl_connect_nonblocking
+#define curlssl_session_free(x)  Curl_polarssl_session_free(x)
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_polarssl_close
+#define curlssl_shutdown(x,y) 0
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_polarssl_version
+#define curlssl_check_cxn(x) ((void)x, -1)
+#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
+
+/* This might cause libcurl to use a weeker random!
+   TODO: implement proper use of Polarssl's CTR-DRBG or HMAC-DRBG and use that
+*/
+#define curlssl_random(x,y,z) ((void)x, (void)y, (void)z, CURLE_NOT_BUILT_IN)
+
+#endif /* USE_POLARSSL */
+#endif /* HEADER_CURL_POLARSSL_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/polarssl_threadlock.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/polarssl_threadlock.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/polarssl_threadlock.c	(revision 164)
@@ -0,0 +1,153 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2013-2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if (defined(USE_POLARSSL) || defined(USE_MBEDTLS)) && \
+    (defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32))
+
+#if defined(USE_THREADS_POSIX)
+#  ifdef HAVE_PTHREAD_H
+#    include <pthread.h>
+#  endif
+#elif defined(USE_THREADS_WIN32)
+#  ifdef HAVE_PROCESS_H
+#    include <process.h>
+#  endif
+#endif
+
+#include "polarssl_threadlock.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* number of thread locks */
+#define NUMT                    2
+
+/* This array will store all of the mutexes available to PolarSSL. */
+static POLARSSL_MUTEX_T *mutex_buf = NULL;
+
+int Curl_polarsslthreadlock_thread_setup(void)
+{
+  int i;
+  int ret;
+
+  mutex_buf = malloc(NUMT * sizeof(POLARSSL_MUTEX_T));
+  if(!mutex_buf)
+    return 0;     /* error, no number of threads defined */
+
+#ifdef HAVE_PTHREAD_H
+  for(i = 0;  i < NUMT;  i++) {
+    ret = pthread_mutex_init(&mutex_buf[i], NULL);
+    if(ret)
+      return 0; /* pthread_mutex_init failed */
+  }
+#elif defined(HAVE_PROCESS_H)
+  for(i = 0;  i < NUMT;  i++) {
+    mutex_buf[i] = CreateMutex(0, FALSE, 0);
+    if(mutex_buf[i] == 0)
+      return 0;  /* CreateMutex failed */
+  }
+#endif /* HAVE_PTHREAD_H */
+
+  return 1; /* OK */
+}
+
+int Curl_polarsslthreadlock_thread_cleanup(void)
+{
+  int i;
+  int ret;
+
+  if(!mutex_buf)
+    return 0; /* error, no threads locks defined */
+
+#ifdef HAVE_PTHREAD_H
+  for(i = 0; i < NUMT; i++) {
+    ret = pthread_mutex_destroy(&mutex_buf[i]);
+    if(ret)
+      return 0; /* pthread_mutex_destroy failed */
+  }
+#elif defined(HAVE_PROCESS_H)
+  for(i = 0; i < NUMT; i++) {
+    ret = CloseHandle(mutex_buf[i]);
+    if(!ret)
+      return 0; /* CloseHandle failed */
+  }
+#endif /* HAVE_PTHREAD_H */
+  free(mutex_buf);
+  mutex_buf = NULL;
+
+  return 1; /* OK */
+}
+
+int Curl_polarsslthreadlock_lock_function(int n)
+{
+  int ret;
+#ifdef HAVE_PTHREAD_H
+  if(n < NUMT) {
+    ret = pthread_mutex_lock(&mutex_buf[n]);
+    if(ret) {
+      DEBUGF(fprintf(stderr,
+                     "Error: polarsslthreadlock_lock_function failed\n"));
+      return 0; /* pthread_mutex_lock failed */
+    }
+  }
+#elif defined(HAVE_PROCESS_H)
+  if(n < NUMT) {
+    ret = (WaitForSingleObject(mutex_buf[n], INFINITE)==WAIT_FAILED?1:0);
+    if(ret) {
+      DEBUGF(fprintf(stderr,
+                     "Error: polarsslthreadlock_lock_function failed\n"));
+      return 0; /* pthread_mutex_lock failed */
+    }
+  }
+#endif /* HAVE_PTHREAD_H */
+  return 1; /* OK */
+}
+
+int Curl_polarsslthreadlock_unlock_function(int n)
+{
+  int ret;
+#ifdef HAVE_PTHREAD_H
+  if(n < NUMT) {
+    ret = pthread_mutex_unlock(&mutex_buf[n]);
+    if(ret) {
+      DEBUGF(fprintf(stderr,
+                     "Error: polarsslthreadlock_unlock_function failed\n"));
+      return 0; /* pthread_mutex_unlock failed */
+    }
+  }
+#elif defined(HAVE_PROCESS_H)
+  if(n < NUMT) {
+    ret = ReleaseMutex(mutex_buf[n]);
+    if(!ret) {
+      DEBUGF(fprintf(stderr,
+                     "Error: polarsslthreadlock_unlock_function failed\n"));
+      return 0; /* pthread_mutex_lock failed */
+    }
+  }
+#endif /* HAVE_PTHREAD_H */
+  return 1; /* OK */
+}
+
+#endif /* USE_POLARSSL || USE_MBEDTLS */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/polarssl_threadlock.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/polarssl_threadlock.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/polarssl_threadlock.h	(revision 164)
@@ -0,0 +1,53 @@
+#ifndef HEADER_CURL_POLARSSL_THREADLOCK_H
+#define HEADER_CURL_POLARSSL_THREADLOCK_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2013-2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if (defined USE_POLARSSL) || (defined USE_MBEDTLS)
+
+#if defined(USE_THREADS_POSIX)
+#  define POLARSSL_MUTEX_T       pthread_mutex_t
+#elif defined(USE_THREADS_WIN32)
+#  define POLARSSL_MUTEX_T       HANDLE
+#endif
+
+#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+
+int Curl_polarsslthreadlock_thread_setup(void);
+int Curl_polarsslthreadlock_thread_cleanup(void);
+int Curl_polarsslthreadlock_lock_function(int n);
+int Curl_polarsslthreadlock_unlock_function(int n);
+
+#else
+
+#define Curl_polarsslthreadlock_thread_setup() 1
+#define Curl_polarsslthreadlock_thread_cleanup() 1
+#define Curl_polarsslthreadlock_lock_function(x) 1
+#define Curl_polarsslthreadlock_unlock_function(x) 1
+
+#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */
+
+#endif /* USE_POLARSSL */
+
+#endif /* HEADER_CURL_POLARSSL_THREADLOCK_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/schannel.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/schannel.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/schannel.c	(revision 164)
@@ -0,0 +1,1519 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2015, Marc Hoersken, <info@marc-hoersken.de>
+ * Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com>
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all SChannel-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ */
+
+/*
+ * Based upon the PolarSSL implementation in polarssl.c and polarssl.h:
+ *   Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * Based upon the CyaSSL implementation in cyassl.c and cyassl.h:
+ *   Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * Thanks for code and inspiration!
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_SCHANNEL
+
+#ifndef USE_WINDOWS_SSPI
+#  error "Can't compile SCHANNEL support without SSPI."
+#endif
+
+#include "curl_sspi.h"
+#include "schannel.h"
+#include "vtls.h"
+#include "sendf.h"
+#include "connect.h" /* for the connect timeout */
+#include "strerror.h"
+#include "select.h" /* for the socket readyness */
+#include "inet_pton.h" /* for IP addr SNI check */
+#include "curl_multibyte.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* Uncomment to force verbose output
+ * #define infof(x, y, ...) printf(y, __VA_ARGS__)
+ * #define failf(x, y, ...) printf(y, __VA_ARGS__)
+ */
+
+static Curl_recv schannel_recv;
+static Curl_send schannel_send;
+
+#ifdef _WIN32_WCE
+static CURLcode verify_certificate(struct connectdata *conn, int sockindex);
+#endif
+
+static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType,
+                          void *BufDataPtr, unsigned long BufByteSize)
+{
+  buffer->cbBuffer = BufByteSize;
+  buffer->BufferType = BufType;
+  buffer->pvBuffer = BufDataPtr;
+}
+
+static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr,
+                              unsigned long NumArrElem)
+{
+  desc->ulVersion = SECBUFFER_VERSION;
+  desc->pBuffers = BufArr;
+  desc->cBuffers = NumArrElem;
+}
+
+static CURLcode
+schannel_connect_step1(struct connectdata *conn, int sockindex)
+{
+  ssize_t written = -1;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  SecBuffer outbuf;
+  SecBufferDesc outbuf_desc;
+  SCHANNEL_CRED schannel_cred;
+  SECURITY_STATUS sspi_status = SEC_E_OK;
+  struct curl_schannel_cred *old_cred = NULL;
+  struct in_addr addr;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr6;
+#endif
+  TCHAR *host_name;
+  CURLcode result;
+
+  infof(data, "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n",
+        conn->host.name, conn->remote_port);
+
+  /* check for an existing re-usable credential handle */
+  if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL)) {
+    connssl->cred = old_cred;
+    infof(data, "schannel: re-using existing credential handle\n");
+  }
+  else {
+    /* setup Schannel API options */
+    memset(&schannel_cred, 0, sizeof(schannel_cred));
+    schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
+
+    if(data->set.ssl.verifypeer) {
+#ifdef _WIN32_WCE
+      /* certificate validation on CE doesn't seem to work right; we'll
+         do it following a more manual process. */
+      schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
+        SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+        SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+#else
+      schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION;
+      if(data->set.ssl_no_revoke)
+        schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+                                 SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+      else
+        schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
+#endif
+      if(data->set.ssl_no_revoke)
+        infof(data, "schannel: disabled server certificate revocation "
+                    "checks\n");
+      else
+        infof(data, "schannel: checking server certificate revocation\n");
+    }
+    else {
+      schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
+        SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+        SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+      infof(data, "schannel: disabled server certificate revocation checks\n");
+    }
+
+    if(!data->set.ssl.verifyhost) {
+      schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
+      infof(data, "schannel: verifyhost setting prevents Schannel from "
+            "comparing the supplied target name with the subject "
+            "names in server certificates. Also disables SNI.\n");
+    }
+
+    switch(data->set.ssl.version) {
+    default:
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT |
+        SP_PROT_TLS1_1_CLIENT |
+        SP_PROT_TLS1_2_CLIENT;
+      break;
+    case CURL_SSLVERSION_TLSv1_0:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT;
+      break;
+    case CURL_SSLVERSION_TLSv1_1:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_1_CLIENT;
+      break;
+    case CURL_SSLVERSION_TLSv1_2:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT;
+      break;
+    case CURL_SSLVERSION_SSLv3:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
+      break;
+    case CURL_SSLVERSION_SSLv2:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_SSL2_CLIENT;
+      break;
+    }
+
+    /* allocate memory for the re-usable credential handle */
+    connssl->cred = (struct curl_schannel_cred *)
+      malloc(sizeof(struct curl_schannel_cred));
+    if(!connssl->cred) {
+      failf(data, "schannel: unable to allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+    memset(connssl->cred, 0, sizeof(struct curl_schannel_cred));
+
+    /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx
+       */
+    sspi_status =
+      s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
+                                         SECPKG_CRED_OUTBOUND, NULL,
+                                         &schannel_cred, NULL, NULL,
+                                         &connssl->cred->cred_handle,
+                                         &connssl->cred->time_stamp);
+
+    if(sspi_status != SEC_E_OK) {
+      if(sspi_status == SEC_E_WRONG_PRINCIPAL)
+        failf(data, "schannel: SNI or certificate check failed: %s",
+              Curl_sspi_strerror(conn, sspi_status));
+      else
+        failf(data, "schannel: AcquireCredentialsHandle failed: %s",
+              Curl_sspi_strerror(conn, sspi_status));
+      Curl_safefree(connssl->cred);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  /* Warn if SNI is disabled due to use of an IP address */
+  if(Curl_inet_pton(AF_INET, conn->host.name, &addr)
+#ifdef ENABLE_IPV6
+     || Curl_inet_pton(AF_INET6, conn->host.name, &addr6)
+#endif
+    ) {
+    infof(data, "schannel: using IP address, SNI is not supported by OS.\n");
+  }
+
+  /* setup output buffer */
+  InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
+  InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
+
+  /* setup request flags */
+  connssl->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
+    ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
+    ISC_REQ_STREAM;
+
+  /* allocate memory for the security context handle */
+  connssl->ctxt = (struct curl_schannel_ctxt *)
+    malloc(sizeof(struct curl_schannel_ctxt));
+  if(!connssl->ctxt) {
+    failf(data, "schannel: unable to allocate memory");
+    return CURLE_OUT_OF_MEMORY;
+  }
+  memset(connssl->ctxt, 0, sizeof(struct curl_schannel_ctxt));
+
+  host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
+  if(!host_name)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */
+
+  sspi_status = s_pSecFn->InitializeSecurityContext(
+    &connssl->cred->cred_handle, NULL, host_name,
+    connssl->req_flags, 0, 0, NULL, 0, &connssl->ctxt->ctxt_handle,
+    &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
+
+  Curl_unicodefree(host_name);
+
+  if(sspi_status != SEC_I_CONTINUE_NEEDED) {
+    if(sspi_status == SEC_E_WRONG_PRINCIPAL)
+      failf(data, "schannel: SNI or certificate check failed: %s",
+            Curl_sspi_strerror(conn, sspi_status));
+    else
+      failf(data, "schannel: initial InitializeSecurityContext failed: %s",
+            Curl_sspi_strerror(conn, sspi_status));
+    Curl_safefree(connssl->ctxt);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  infof(data, "schannel: sending initial handshake data: "
+        "sending %lu bytes...\n", outbuf.cbBuffer);
+
+  /* send initial handshake data which is now stored in output buffer */
+  result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
+                            outbuf.cbBuffer, &written);
+  s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
+  if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) {
+    failf(data, "schannel: failed to send initial handshake data: "
+          "sent %zd of %lu bytes", written, outbuf.cbBuffer);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  infof(data, "schannel: sent initial handshake data: "
+        "sent %zd bytes\n", written);
+
+  connssl->recv_unrecoverable_err = CURLE_OK;
+  connssl->recv_sspi_close_notify = false;
+  connssl->recv_connection_closed = false;
+
+  /* continue to second handshake step */
+  connssl->connecting_state = ssl_connect_2;
+
+  return CURLE_OK;
+}
+
+static CURLcode
+schannel_connect_step2(struct connectdata *conn, int sockindex)
+{
+  int i;
+  ssize_t nread = -1, written = -1;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  unsigned char *reallocated_buffer;
+  size_t reallocated_length;
+  SecBuffer outbuf[3];
+  SecBufferDesc outbuf_desc;
+  SecBuffer inbuf[2];
+  SecBufferDesc inbuf_desc;
+  SECURITY_STATUS sspi_status = SEC_E_OK;
+  TCHAR *host_name;
+  CURLcode result;
+  bool doread;
+
+  doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
+
+  infof(data, "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n",
+        conn->host.name, conn->remote_port);
+
+  if(!connssl->cred || !connssl->ctxt)
+    return CURLE_SSL_CONNECT_ERROR;
+
+  /* buffer to store previously received and decrypted data */
+  if(connssl->decdata_buffer == NULL) {
+    connssl->decdata_offset = 0;
+    connssl->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+    connssl->decdata_buffer = malloc(connssl->decdata_length);
+    if(connssl->decdata_buffer == NULL) {
+      failf(data, "schannel: unable to allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* buffer to store previously received and encrypted data */
+  if(connssl->encdata_buffer == NULL) {
+    connssl->encdata_offset = 0;
+    connssl->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+    connssl->encdata_buffer = malloc(connssl->encdata_length);
+    if(connssl->encdata_buffer == NULL) {
+      failf(data, "schannel: unable to allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* if we need a bigger buffer to read a full message, increase buffer now */
+  if(connssl->encdata_length - connssl->encdata_offset <
+     CURL_SCHANNEL_BUFFER_FREE_SIZE) {
+    /* increase internal encrypted data buffer */
+    reallocated_length = connssl->encdata_offset +
+      CURL_SCHANNEL_BUFFER_FREE_SIZE;
+    reallocated_buffer = realloc(connssl->encdata_buffer,
+                                 reallocated_length);
+
+    if(reallocated_buffer == NULL) {
+      failf(data, "schannel: unable to re-allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+    else {
+      connssl->encdata_buffer = reallocated_buffer;
+      connssl->encdata_length = reallocated_length;
+    }
+  }
+
+  for(;;) {
+    if(doread) {
+      /* read encrypted handshake data from socket */
+      result = Curl_read_plain(conn->sock[sockindex],
+                               (char *) (connssl->encdata_buffer +
+                                         connssl->encdata_offset),
+                               connssl->encdata_length -
+                               connssl->encdata_offset,
+                               &nread);
+      if(result == CURLE_AGAIN) {
+        if(connssl->connecting_state != ssl_connect_2_writing)
+          connssl->connecting_state = ssl_connect_2_reading;
+        infof(data, "schannel: failed to receive handshake, "
+              "need more data\n");
+        return CURLE_OK;
+      }
+      else if((result != CURLE_OK) || (nread == 0)) {
+        failf(data, "schannel: failed to receive handshake, "
+              "SSL/TLS connection failed");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+
+      /* increase encrypted data buffer offset */
+      connssl->encdata_offset += nread;
+    }
+
+    infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+          connssl->encdata_offset, connssl->encdata_length);
+
+    /* setup input buffers */
+    InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(connssl->encdata_offset),
+                  curlx_uztoul(connssl->encdata_offset));
+    InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBufferDesc(&inbuf_desc, inbuf, 2);
+
+    /* setup output buffers */
+    InitSecBuffer(&outbuf[0], SECBUFFER_TOKEN, NULL, 0);
+    InitSecBuffer(&outbuf[1], SECBUFFER_ALERT, NULL, 0);
+    InitSecBuffer(&outbuf[2], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBufferDesc(&outbuf_desc, outbuf, 3);
+
+    if(inbuf[0].pvBuffer == NULL) {
+      failf(data, "schannel: unable to allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    /* copy received handshake data into input buffer */
+    memcpy(inbuf[0].pvBuffer, connssl->encdata_buffer,
+           connssl->encdata_offset);
+
+    host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
+    if(!host_name)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx
+       */
+    sspi_status = s_pSecFn->InitializeSecurityContext(
+      &connssl->cred->cred_handle, &connssl->ctxt->ctxt_handle,
+      host_name, connssl->req_flags, 0, 0, &inbuf_desc, 0, NULL,
+      &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
+
+    Curl_unicodefree(host_name);
+
+    /* free buffer for received handshake data */
+    Curl_safefree(inbuf[0].pvBuffer);
+
+    /* check if the handshake was incomplete */
+    if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
+      connssl->connecting_state = ssl_connect_2_reading;
+      infof(data, "schannel: received incomplete message, need more data\n");
+      return CURLE_OK;
+    }
+
+    /* If the server has requested a client certificate, attempt to continue
+       the handshake without one. This will allow connections to servers which
+       request a client certificate but do not require it. */
+    if(sspi_status == SEC_I_INCOMPLETE_CREDENTIALS &&
+       !(connssl->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
+      connssl->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
+      connssl->connecting_state = ssl_connect_2_writing;
+      infof(data, "schannel: a client certificate has been requested\n");
+      return CURLE_OK;
+    }
+
+    /* check if the handshake needs to be continued */
+    if(sspi_status == SEC_I_CONTINUE_NEEDED || sspi_status == SEC_E_OK) {
+      for(i = 0; i < 3; i++) {
+        /* search for handshake tokens that need to be send */
+        if(outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) {
+          infof(data, "schannel: sending next handshake data: "
+                "sending %lu bytes...\n", outbuf[i].cbBuffer);
+
+          /* send handshake token to server */
+          result = Curl_write_plain(conn, conn->sock[sockindex],
+                                    outbuf[i].pvBuffer, outbuf[i].cbBuffer,
+                                    &written);
+          if((result != CURLE_OK) ||
+             (outbuf[i].cbBuffer != (size_t) written)) {
+            failf(data, "schannel: failed to send next handshake data: "
+                  "sent %zd of %lu bytes", written, outbuf[i].cbBuffer);
+            return CURLE_SSL_CONNECT_ERROR;
+          }
+        }
+
+        /* free obsolete buffer */
+        if(outbuf[i].pvBuffer != NULL) {
+          s_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer);
+        }
+      }
+    }
+    else {
+      if(sspi_status == SEC_E_WRONG_PRINCIPAL)
+        failf(data, "schannel: SNI or certificate check failed: %s",
+              Curl_sspi_strerror(conn, sspi_status));
+      else
+        failf(data, "schannel: next InitializeSecurityContext failed: %s",
+              Curl_sspi_strerror(conn, sspi_status));
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    /* check if there was additional remaining encrypted data */
+    if(inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) {
+      infof(data, "schannel: encrypted data length: %lu\n", inbuf[1].cbBuffer);
+      /*
+        There are two cases where we could be getting extra data here:
+        1) If we're renegotiating a connection and the handshake is already
+        complete (from the server perspective), it can encrypted app data
+        (not handshake data) in an extra buffer at this point.
+        2) (sspi_status == SEC_I_CONTINUE_NEEDED) We are negotiating a
+        connection and this extra data is part of the handshake.
+        We should process the data immediately; waiting for the socket to
+        be ready may fail since the server is done sending handshake data.
+      */
+      /* check if the remaining data is less than the total amount
+         and therefore begins after the already processed data */
+      if(connssl->encdata_offset > inbuf[1].cbBuffer) {
+        memmove(connssl->encdata_buffer,
+                (connssl->encdata_buffer + connssl->encdata_offset) -
+                inbuf[1].cbBuffer, inbuf[1].cbBuffer);
+        connssl->encdata_offset = inbuf[1].cbBuffer;
+        if(sspi_status == SEC_I_CONTINUE_NEEDED) {
+          doread = FALSE;
+          continue;
+        }
+      }
+    }
+    else {
+      connssl->encdata_offset = 0;
+    }
+    break;
+  }
+
+  /* check if the handshake needs to be continued */
+  if(sspi_status == SEC_I_CONTINUE_NEEDED) {
+    connssl->connecting_state = ssl_connect_2_reading;
+    return CURLE_OK;
+  }
+
+  /* check if the handshake is complete */
+  if(sspi_status == SEC_E_OK) {
+    connssl->connecting_state = ssl_connect_3;
+    infof(data, "schannel: SSL/TLS handshake complete\n");
+  }
+
+#ifdef _WIN32_WCE
+  /* Windows CE doesn't do any server certificate validation.
+     We have to do it manually. */
+  if(data->set.ssl.verifypeer)
+    return verify_certificate(conn, sockindex);
+#endif
+
+  return CURLE_OK;
+}
+
+static CURLcode
+schannel_connect_step3(struct connectdata *conn, int sockindex)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct curl_schannel_cred *old_cred = NULL;
+  bool incache;
+
+  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+  infof(data, "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n",
+        conn->host.name, conn->remote_port);
+
+  if(!connssl->cred)
+    return CURLE_SSL_CONNECT_ERROR;
+
+  /* check if the required context attributes are met */
+  if(connssl->ret_flags != connssl->req_flags) {
+    if(!(connssl->ret_flags & ISC_RET_SEQUENCE_DETECT))
+      failf(data, "schannel: failed to setup sequence detection");
+    if(!(connssl->ret_flags & ISC_RET_REPLAY_DETECT))
+      failf(data, "schannel: failed to setup replay detection");
+    if(!(connssl->ret_flags & ISC_RET_CONFIDENTIALITY))
+      failf(data, "schannel: failed to setup confidentiality");
+    if(!(connssl->ret_flags & ISC_RET_ALLOCATED_MEMORY))
+      failf(data, "schannel: failed to setup memory allocation");
+    if(!(connssl->ret_flags & ISC_RET_STREAM))
+      failf(data, "schannel: failed to setup stream orientation");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  /* increment the reference counter of the credential/session handle */
+  if(connssl->cred && connssl->ctxt) {
+    connssl->cred->refcount++;
+    infof(data, "schannel: incremented credential handle refcount = %d\n",
+          connssl->cred->refcount);
+  }
+
+  /* save the current session data for possible re-use */
+  incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL));
+  if(incache) {
+    if(old_cred != connssl->cred) {
+      infof(data, "schannel: old credential handle is stale, removing\n");
+      Curl_ssl_delsessionid(conn, (void *)old_cred);
+      incache = FALSE;
+    }
+  }
+
+  if(!incache) {
+    result = Curl_ssl_addsessionid(conn, (void *)connssl->cred,
+                                   sizeof(struct curl_schannel_cred));
+    if(result) {
+      failf(data, "schannel: failed to store credential handle");
+      return result;
+    }
+    else {
+      connssl->cred->cached = TRUE;
+      infof(data, "schannel: stored credential handle in session cache\n");
+    }
+  }
+
+  connssl->connecting_state = ssl_connect_done;
+
+  return CURLE_OK;
+}
+
+static CURLcode
+schannel_connect_common(struct connectdata *conn, int sockindex,
+                        bool nonblocking, bool *done)
+{
+  CURLcode result;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  long timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1 == connssl->connecting_state) {
+    /* check out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL/TLS connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    result = schannel_connect_step1(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL/TLS connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading
+       || connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing ==
+        connssl->connecting_state ? sockfd : CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading ==
+        connssl->connecting_state ? sockfd : CURL_SOCKET_BAD;
+
+      what = Curl_socket_ready(readfd, writefd, nonblocking ? 0 : timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL/TLS socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL/TLS connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if
+     * this connection is part of a multi handle and this loop would
+     * execute again. This permits the owner of a multi handle to
+     * abort a connection attempt before step2 has completed while
+     * ensuring that a client using select() or epoll() will always
+     * have a valid fdset to wait on.
+     */
+    result = schannel_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
+
+  } /* repeat step2 until all transactions are done. */
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = schannel_connect_step3(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = schannel_recv;
+    conn->send[sockindex] = schannel_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* reset our connection state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+static ssize_t
+schannel_send(struct connectdata *conn, int sockindex,
+              const void *buf, size_t len, CURLcode *err)
+{
+  ssize_t written = -1;
+  size_t data_len = 0;
+  unsigned char *data = NULL;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  SecBuffer outbuf[4];
+  SecBufferDesc outbuf_desc;
+  SECURITY_STATUS sspi_status = SEC_E_OK;
+  CURLcode result;
+
+  /* check if the maximum stream sizes were queried */
+  if(connssl->stream_sizes.cbMaximumMessage == 0) {
+    sspi_status = s_pSecFn->QueryContextAttributes(
+      &connssl->ctxt->ctxt_handle,
+      SECPKG_ATTR_STREAM_SIZES,
+      &connssl->stream_sizes);
+    if(sspi_status != SEC_E_OK) {
+      *err = CURLE_SEND_ERROR;
+      return -1;
+    }
+  }
+
+  /* check if the buffer is longer than the maximum message length */
+  if(len > connssl->stream_sizes.cbMaximumMessage) {
+    *err = CURLE_SEND_ERROR;
+    return -1;
+  }
+
+  /* calculate the complete message length and allocate a buffer for it */
+  data_len = connssl->stream_sizes.cbHeader + len +
+    connssl->stream_sizes.cbTrailer;
+  data = (unsigned char *) malloc(data_len);
+  if(data == NULL) {
+    *err = CURLE_OUT_OF_MEMORY;
+    return -1;
+  }
+
+  /* setup output buffers (header, data, trailer, empty) */
+  InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
+                data, connssl->stream_sizes.cbHeader);
+  InitSecBuffer(&outbuf[1], SECBUFFER_DATA,
+                data + connssl->stream_sizes.cbHeader, curlx_uztoul(len));
+  InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
+                data + connssl->stream_sizes.cbHeader + len,
+                connssl->stream_sizes.cbTrailer);
+  InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
+  InitSecBufferDesc(&outbuf_desc, outbuf, 4);
+
+  /* copy data into output buffer */
+  memcpy(outbuf[1].pvBuffer, buf, len);
+
+  /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */
+  sspi_status = s_pSecFn->EncryptMessage(&connssl->ctxt->ctxt_handle, 0,
+                                         &outbuf_desc, 0);
+
+  /* check if the message was encrypted */
+  if(sspi_status == SEC_E_OK) {
+    written = 0;
+
+    /* send the encrypted message including header, data and trailer */
+    len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;
+
+    /*
+      It's important to send the full message which includes the header,
+      encrypted payload, and trailer.  Until the client receives all the
+      data a coherent message has not been delivered and the client
+      can't read any of it.
+
+      If we wanted to buffer the unwritten encrypted bytes, we would
+      tell the client that all data it has requested to be sent has been
+      sent. The unwritten encrypted bytes would be the first bytes to
+      send on the next invocation.
+      Here's the catch with this - if we tell the client that all the
+      bytes have been sent, will the client call this method again to
+      send the buffered data?  Looking at who calls this function, it
+      seems the answer is NO.
+    */
+
+    /* send entire message or fail */
+    while(len > (size_t)written) {
+      ssize_t this_write;
+      long timeleft;
+      int what;
+
+      this_write = 0;
+
+      timeleft = Curl_timeleft(conn->data, NULL, FALSE);
+      if(timeleft < 0) {
+        /* we already got the timeout */
+        failf(conn->data, "schannel: timed out sending data "
+              "(bytes sent: %zd)", written);
+        *err = CURLE_OPERATION_TIMEDOUT;
+        written = -1;
+        break;
+      }
+
+      what = Curl_socket_ready(CURL_SOCKET_BAD, conn->sock[sockindex],
+                               timeleft);
+      if(what < 0) {
+        /* fatal error */
+        failf(conn->data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        *err = CURLE_SEND_ERROR;
+        written = -1;
+        break;
+      }
+      else if(0 == what) {
+        failf(conn->data, "schannel: timed out sending data "
+              "(bytes sent: %zd)", written);
+        *err = CURLE_OPERATION_TIMEDOUT;
+        written = -1;
+        break;
+      }
+      /* socket is writable */
+
+      result = Curl_write_plain(conn, conn->sock[sockindex], data + written,
+                                len - written, &this_write);
+      if(result == CURLE_AGAIN)
+        continue;
+      else if(result != CURLE_OK) {
+        *err = result;
+        written = -1;
+        break;
+      }
+
+      written += this_write;
+    }
+  }
+  else if(sspi_status == SEC_E_INSUFFICIENT_MEMORY) {
+    *err = CURLE_OUT_OF_MEMORY;
+  }
+  else{
+    *err = CURLE_SEND_ERROR;
+  }
+
+  Curl_safefree(data);
+
+  if(len == (size_t)written)
+    /* Encrypted message including header, data and trailer entirely sent.
+       The return value is the number of unencrypted bytes that were sent. */
+    written = outbuf[1].cbBuffer;
+
+  return written;
+}
+
+static ssize_t
+schannel_recv(struct connectdata *conn, int sockindex,
+              char *buf, size_t len, CURLcode *err)
+{
+  size_t size = 0;
+  ssize_t nread = -1;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  unsigned char *reallocated_buffer;
+  size_t reallocated_length;
+  bool done = FALSE;
+  SecBuffer inbuf[4];
+  SecBufferDesc inbuf_desc;
+  SECURITY_STATUS sspi_status = SEC_E_OK;
+  /* we want the length of the encrypted buffer to be at least large enough
+     that it can hold all the bytes requested and some TLS record overhead. */
+  size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
+
+  /****************************************************************************
+   * Don't return or set connssl->recv_unrecoverable_err unless in the cleanup.
+   * The pattern for return error is set *err, optional infof, goto cleanup.
+   *
+   * Our priority is to always return as much decrypted data to the caller as
+   * possible, even if an error occurs. The state of the decrypted buffer must
+   * always be valid. Transfer of decrypted data to the caller's buffer is
+   * handled in the cleanup.
+   */
+
+  infof(data, "schannel: client wants to read %zu bytes\n", len);
+  *err = CURLE_OK;
+
+  if(len && len <= connssl->decdata_offset) {
+    infof(data, "schannel: enough decrypted data is already available\n");
+    goto cleanup;
+  }
+  else if(connssl->recv_unrecoverable_err) {
+    *err = connssl->recv_unrecoverable_err;
+    infof(data, "schannel: an unrecoverable error occurred in a prior call\n");
+    goto cleanup;
+  }
+  else if(connssl->recv_sspi_close_notify) {
+    /* once a server has indicated shutdown there is no more encrypted data */
+    infof(data, "schannel: server indicated shutdown in a prior call\n");
+    goto cleanup;
+  }
+  else if(!len) {
+    /* It's debatable what to return when !len. Regardless we can't return
+    immediately because there may be data to decrypt (in the case we want to
+    decrypt all encrypted cached data) so handle !len later in cleanup.
+    */
+    ; /* do nothing */
+  }
+  else if(!connssl->recv_connection_closed) {
+    /* increase enc buffer in order to fit the requested amount of data */
+    size = connssl->encdata_length - connssl->encdata_offset;
+    if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE ||
+       connssl->encdata_length < min_encdata_length) {
+      reallocated_length = connssl->encdata_offset +
+                           CURL_SCHANNEL_BUFFER_FREE_SIZE;
+      if(reallocated_length < min_encdata_length) {
+        reallocated_length = min_encdata_length;
+      }
+      reallocated_buffer = realloc(connssl->encdata_buffer,
+                                   reallocated_length);
+      if(reallocated_buffer == NULL) {
+        *err = CURLE_OUT_OF_MEMORY;
+        failf(data, "schannel: unable to re-allocate memory");
+        goto cleanup;
+      }
+
+      connssl->encdata_buffer = reallocated_buffer;
+      connssl->encdata_length = reallocated_length;
+      size = connssl->encdata_length - connssl->encdata_offset;
+      infof(data, "schannel: encdata_buffer resized %zu\n",
+            connssl->encdata_length);
+    }
+
+    infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+          connssl->encdata_offset, connssl->encdata_length);
+
+    /* read encrypted data from socket */
+    *err = Curl_read_plain(conn->sock[sockindex],
+                           (char *)(connssl->encdata_buffer +
+                                    connssl->encdata_offset),
+                           size, &nread);
+    if(*err) {
+      nread = -1;
+      if(*err == CURLE_AGAIN)
+        infof(data, "schannel: Curl_read_plain returned CURLE_AGAIN\n");
+      else if(*err == CURLE_RECV_ERROR)
+        infof(data, "schannel: Curl_read_plain returned CURLE_RECV_ERROR\n");
+      else
+        infof(data, "schannel: Curl_read_plain returned error %d\n", *err);
+    }
+    else if(nread == 0) {
+      connssl->recv_connection_closed = true;
+      infof(data, "schannel: server closed the connection\n");
+    }
+    else if(nread > 0) {
+      connssl->encdata_offset += (size_t)nread;
+      infof(data, "schannel: encrypted data got %zd\n", nread);
+    }
+  }
+
+  infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+        connssl->encdata_offset, connssl->encdata_length);
+
+  /* decrypt loop */
+  while(connssl->encdata_offset > 0 && sspi_status == SEC_E_OK &&
+        (!len || connssl->decdata_offset < len ||
+         connssl->recv_connection_closed)) {
+    /* prepare data buffer for DecryptMessage call */
+    InitSecBuffer(&inbuf[0], SECBUFFER_DATA, connssl->encdata_buffer,
+                  curlx_uztoul(connssl->encdata_offset));
+
+    /* we need 3 more empty input buffers for possible output */
+    InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBuffer(&inbuf[2], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBuffer(&inbuf[3], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBufferDesc(&inbuf_desc, inbuf, 4);
+
+    /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx
+       */
+    sspi_status = s_pSecFn->DecryptMessage(&connssl->ctxt->ctxt_handle,
+                                           &inbuf_desc, 0, NULL);
+
+    /* check if everything went fine (server may want to renegotiate
+       or shutdown the connection context) */
+    if(sspi_status == SEC_E_OK || sspi_status == SEC_I_RENEGOTIATE ||
+       sspi_status == SEC_I_CONTEXT_EXPIRED) {
+      /* check for successfully decrypted data, even before actual
+         renegotiation or shutdown of the connection context */
+      if(inbuf[1].BufferType == SECBUFFER_DATA) {
+        infof(data, "schannel: decrypted data length: %lu\n",
+              inbuf[1].cbBuffer);
+
+        /* increase buffer in order to fit the received amount of data */
+        size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ?
+               inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
+        if(connssl->decdata_length - connssl->decdata_offset < size ||
+           connssl->decdata_length < len) {
+          /* increase internal decrypted data buffer */
+          reallocated_length = connssl->decdata_offset + size;
+          /* make sure that the requested amount of data fits */
+          if(reallocated_length < len) {
+            reallocated_length = len;
+          }
+          reallocated_buffer = realloc(connssl->decdata_buffer,
+                                       reallocated_length);
+          if(reallocated_buffer == NULL) {
+            *err = CURLE_OUT_OF_MEMORY;
+            failf(data, "schannel: unable to re-allocate memory");
+            goto cleanup;
+          }
+          connssl->decdata_buffer = reallocated_buffer;
+          connssl->decdata_length = reallocated_length;
+        }
+
+        /* copy decrypted data to internal buffer */
+        size = inbuf[1].cbBuffer;
+        if(size) {
+          memcpy(connssl->decdata_buffer + connssl->decdata_offset,
+                 inbuf[1].pvBuffer, size);
+          connssl->decdata_offset += size;
+        }
+
+        infof(data, "schannel: decrypted data added: %zu\n", size);
+        infof(data, "schannel: decrypted data cached: offset %zu length %zu\n",
+              connssl->decdata_offset, connssl->decdata_length);
+      }
+
+      /* check for remaining encrypted data */
+      if(inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) {
+        infof(data, "schannel: encrypted data length: %lu\n",
+              inbuf[3].cbBuffer);
+
+        /* check if the remaining data is less than the total amount
+         * and therefore begins after the already processed data
+         */
+        if(connssl->encdata_offset > inbuf[3].cbBuffer) {
+          /* move remaining encrypted data forward to the beginning of
+             buffer */
+          memmove(connssl->encdata_buffer,
+                  (connssl->encdata_buffer + connssl->encdata_offset) -
+                  inbuf[3].cbBuffer, inbuf[3].cbBuffer);
+          connssl->encdata_offset = inbuf[3].cbBuffer;
+        }
+
+        infof(data, "schannel: encrypted data cached: offset %zu length %zu\n",
+              connssl->encdata_offset, connssl->encdata_length);
+      }
+      else {
+        /* reset encrypted buffer offset, because there is no data remaining */
+        connssl->encdata_offset = 0;
+      }
+
+      /* check if server wants to renegotiate the connection context */
+      if(sspi_status == SEC_I_RENEGOTIATE) {
+        infof(data, "schannel: remote party requests renegotiation\n");
+        if(*err && *err != CURLE_AGAIN) {
+          infof(data, "schannel: can't renogotiate, an error is pending\n");
+          goto cleanup;
+        }
+        if(connssl->encdata_offset) {
+          *err = CURLE_RECV_ERROR;
+          infof(data, "schannel: can't renogotiate, "
+                      "encrypted data available\n");
+          goto cleanup;
+        }
+        /* begin renegotiation */
+        infof(data, "schannel: renegotiating SSL/TLS connection\n");
+        connssl->state = ssl_connection_negotiating;
+        connssl->connecting_state = ssl_connect_2_writing;
+        *err = schannel_connect_common(conn, sockindex, FALSE, &done);
+        if(*err) {
+          infof(data, "schannel: renegotiation failed\n");
+          goto cleanup;
+        }
+        /* now retry receiving data */
+        sspi_status = SEC_E_OK;
+        infof(data, "schannel: SSL/TLS connection renegotiated\n");
+        continue;
+      }
+      /* check if the server closed the connection */
+      else if(sspi_status == SEC_I_CONTEXT_EXPIRED) {
+        /* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not
+           returned so we have to work around that in cleanup. */
+        connssl->recv_sspi_close_notify = true;
+        if(!connssl->recv_connection_closed) {
+          connssl->recv_connection_closed = true;
+          infof(data, "schannel: server closed the connection\n");
+        }
+        goto cleanup;
+      }
+    }
+    else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
+      if(!*err)
+        *err = CURLE_AGAIN;
+      infof(data, "schannel: failed to decrypt data, need more data\n");
+      goto cleanup;
+    }
+    else {
+      *err = CURLE_RECV_ERROR;
+      infof(data, "schannel: failed to read data from server: %s\n",
+            Curl_sspi_strerror(conn, sspi_status));
+      goto cleanup;
+    }
+  }
+
+  infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+        connssl->encdata_offset, connssl->encdata_length);
+
+  infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
+        connssl->decdata_offset, connssl->decdata_length);
+
+cleanup:
+  /* Warning- there is no guarantee the encdata state is valid at this point */
+  infof(data, "schannel: schannel_recv cleanup\n");
+
+  /* Error if the connection has closed without a close_notify.
+  Behavior here is a matter of debate. We don't want to be vulnerable to a
+  truncation attack however there's some browser precedent for ignoring the
+  close_notify for compatibility reasons.
+  Additionally, Windows 2000 (v5.0) is a special case since it seems it doesn't
+  return close_notify. In that case if the connection was closed we assume it
+  was graceful (close_notify) since there doesn't seem to be a way to tell.
+  */
+  if(len && !connssl->decdata_offset && connssl->recv_connection_closed &&
+     !connssl->recv_sspi_close_notify) {
+    bool isWin2k = FALSE;
+
+#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
+    (_WIN32_WINNT < _WIN32_WINNT_WIN2K)
+    OSVERSIONINFO osver;
+
+    memset(&osver, 0, sizeof(osver));
+    osver.dwOSVersionInfoSize = sizeof(osver);
+
+    /* Find out the Windows version */
+    if(GetVersionEx(&osver)) {
+      /* Verify the version number is 5.0 */
+      if(osver.dwMajorVersion == 5 && osver.dwMinorVersion == 0)
+        isWin2k = TRUE;
+    }
+#else
+    ULONGLONG cm;
+    OSVERSIONINFOEX osver;
+
+    memset(&osver, 0, sizeof(osver));
+    osver.dwOSVersionInfoSize = sizeof(osver);
+    osver.dwMajorVersion = 5;
+
+    cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
+
+    if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
+                                  VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
+                         cm))
+      isWin2k = TRUE;
+#endif
+
+    if(isWin2k && sspi_status == SEC_E_OK)
+      connssl->recv_sspi_close_notify = true;
+    else {
+      *err = CURLE_RECV_ERROR;
+      infof(data, "schannel: server closed abruptly (missing close_notify)\n");
+    }
+  }
+
+  /* Any error other than CURLE_AGAIN is an unrecoverable error. */
+  if(*err && *err != CURLE_AGAIN)
+      connssl->recv_unrecoverable_err = *err;
+
+  size = len < connssl->decdata_offset ? len : connssl->decdata_offset;
+  if(size) {
+    memcpy(buf, connssl->decdata_buffer, size);
+    memmove(connssl->decdata_buffer, connssl->decdata_buffer + size,
+            connssl->decdata_offset - size);
+    connssl->decdata_offset -= size;
+
+    infof(data, "schannel: decrypted data returned %zu\n", size);
+    infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
+          connssl->decdata_offset, connssl->decdata_length);
+    *err = CURLE_OK;
+    return (ssize_t)size;
+  }
+
+  if(!*err && !connssl->recv_connection_closed)
+      *err = CURLE_AGAIN;
+
+  /* It's debatable what to return when !len. We could return whatever error we
+  got from decryption but instead we override here so the return is consistent.
+  */
+  if(!len)
+    *err = CURLE_OK;
+
+  return *err ? -1 : 0;
+}
+
+CURLcode
+Curl_schannel_connect_nonblocking(struct connectdata *conn, int sockindex,
+                                  bool *done)
+{
+  return schannel_connect_common(conn, sockindex, TRUE, done);
+}
+
+CURLcode
+Curl_schannel_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = schannel_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+bool Curl_schannel_data_pending(const struct connectdata *conn, int sockindex)
+{
+  const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  if(connssl->use) /* SSL/TLS is in use */
+    return (connssl->encdata_offset > 0 ||
+            connssl->decdata_offset > 0 ) ? TRUE : FALSE;
+  else
+    return FALSE;
+}
+
+void Curl_schannel_close(struct connectdata *conn, int sockindex)
+{
+  if(conn->ssl[sockindex].use)
+    /* if the SSL/TLS channel hasn't been shut down yet, do that now. */
+    Curl_ssl_shutdown(conn, sockindex);
+}
+
+int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
+{
+  /* See https://msdn.microsoft.com/en-us/library/windows/desktop/aa380138.aspx
+   * Shutting Down an Schannel Connection
+   */
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
+        conn->host.name, conn->remote_port);
+
+  if(connssl->cred && connssl->ctxt) {
+    SecBufferDesc BuffDesc;
+    SecBuffer Buffer;
+    SECURITY_STATUS sspi_status;
+    SecBuffer outbuf;
+    SecBufferDesc outbuf_desc;
+    CURLcode result;
+    TCHAR *host_name;
+    DWORD dwshut = SCHANNEL_SHUTDOWN;
+
+    InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut));
+    InitSecBufferDesc(&BuffDesc, &Buffer, 1);
+
+    sspi_status = s_pSecFn->ApplyControlToken(&connssl->ctxt->ctxt_handle,
+                                              &BuffDesc);
+
+    if(sspi_status != SEC_E_OK)
+      failf(data, "schannel: ApplyControlToken failure: %s",
+            Curl_sspi_strerror(conn, sspi_status));
+
+    host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
+    if(!host_name)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* setup output buffer */
+    InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
+    InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
+
+    sspi_status = s_pSecFn->InitializeSecurityContext(
+      &connssl->cred->cred_handle,
+      &connssl->ctxt->ctxt_handle,
+      host_name,
+      connssl->req_flags,
+      0,
+      0,
+      NULL,
+      0,
+      &connssl->ctxt->ctxt_handle,
+      &outbuf_desc,
+      &connssl->ret_flags,
+      &connssl->ctxt->time_stamp);
+
+    Curl_unicodefree(host_name);
+
+    if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) {
+      /* send close message which is in output buffer */
+      ssize_t written;
+      result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
+                                outbuf.cbBuffer, &written);
+
+      s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
+      if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) {
+        infof(data, "schannel: failed to send close msg: %s"
+              " (bytes written: %zd)\n", curl_easy_strerror(result), written);
+      }
+    }
+  }
+
+  /* free SSPI Schannel API security context handle */
+  if(connssl->ctxt) {
+    infof(data, "schannel: clear security context handle\n");
+    s_pSecFn->DeleteSecurityContext(&connssl->ctxt->ctxt_handle);
+    Curl_safefree(connssl->ctxt);
+  }
+
+  /* free SSPI Schannel API credential handle */
+  if(connssl->cred) {
+    /* decrement the reference counter of the credential/session handle */
+    if(connssl->cred->refcount > 0) {
+      connssl->cred->refcount--;
+      infof(data, "schannel: decremented credential handle refcount = %d\n",
+            connssl->cred->refcount);
+    }
+
+    /* if the handle was not cached and the refcount is zero */
+    if(!connssl->cred->cached && connssl->cred->refcount == 0) {
+      infof(data, "schannel: clear credential handle\n");
+      s_pSecFn->FreeCredentialsHandle(&connssl->cred->cred_handle);
+      Curl_safefree(connssl->cred);
+    }
+  }
+
+  /* free internal buffer for received encrypted data */
+  if(connssl->encdata_buffer != NULL) {
+    Curl_safefree(connssl->encdata_buffer);
+    connssl->encdata_length = 0;
+    connssl->encdata_offset = 0;
+  }
+
+  /* free internal buffer for received decrypted data */
+  if(connssl->decdata_buffer != NULL) {
+    Curl_safefree(connssl->decdata_buffer);
+    connssl->decdata_length = 0;
+    connssl->decdata_offset = 0;
+  }
+
+  return CURLE_OK;
+}
+
+void Curl_schannel_session_free(void *ptr)
+{
+  struct curl_schannel_cred *cred = ptr;
+
+  if(cred && cred->cached) {
+    if(cred->refcount == 0) {
+      s_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
+      Curl_safefree(cred);
+    }
+    else {
+      cred->cached = FALSE;
+    }
+  }
+}
+
+int Curl_schannel_init(void)
+{
+  return (Curl_sspi_global_init() == CURLE_OK ? 1 : 0);
+}
+
+void Curl_schannel_cleanup(void)
+{
+  Curl_sspi_global_cleanup();
+}
+
+size_t Curl_schannel_version(char *buffer, size_t size)
+{
+  size = snprintf(buffer, size, "WinSSL");
+
+  return size;
+}
+
+int Curl_schannel_random(unsigned char *entropy, size_t length)
+{
+  HCRYPTPROV hCryptProv = 0;
+
+  if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
+                          CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
+    return 1;
+
+  if(!CryptGenRandom(hCryptProv, (DWORD)length, entropy)) {
+    CryptReleaseContext(hCryptProv, 0UL);
+    return 1;
+  }
+
+  CryptReleaseContext(hCryptProv, 0UL);
+  return 0;
+}
+
+#ifdef _WIN32_WCE
+static CURLcode verify_certificate(struct connectdata *conn, int sockindex)
+{
+  SECURITY_STATUS status;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  CURLcode result = CURLE_OK;
+  CERT_CONTEXT *pCertContextServer = NULL;
+  const CERT_CHAIN_CONTEXT *pChainContext = NULL;
+
+  status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle,
+                                            SECPKG_ATTR_REMOTE_CERT_CONTEXT,
+                                            &pCertContextServer);
+
+  if((status != SEC_E_OK) || (pCertContextServer == NULL)) {
+    failf(data, "schannel: Failed to read remote certificate context: %s",
+          Curl_sspi_strerror(conn, status));
+    result = CURLE_PEER_FAILED_VERIFICATION;
+  }
+
+  if(result == CURLE_OK) {
+    CERT_CHAIN_PARA ChainPara;
+    memset(&ChainPara, 0, sizeof(ChainPara));
+    ChainPara.cbSize = sizeof(ChainPara);
+
+    if(!CertGetCertificateChain(NULL,
+                                pCertContextServer,
+                                NULL,
+                                pCertContextServer->hCertStore,
+                                &ChainPara,
+                                (data->set.ssl_no_revoke ? 0 :
+                                 CERT_CHAIN_REVOCATION_CHECK_CHAIN),
+                                NULL,
+                                &pChainContext)) {
+      failf(data, "schannel: CertGetCertificateChain failed: %s",
+            Curl_sspi_strerror(conn, GetLastError()));
+      pChainContext = NULL;
+      result = CURLE_PEER_FAILED_VERIFICATION;
+    }
+
+    if(result == CURLE_OK) {
+      CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0];
+      DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED);
+      dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus;
+      if(dwTrustErrorMask) {
+        if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED)
+          failf(data, "schannel: CertGetCertificateChain trust error"
+                " CERT_TRUST_IS_REVOKED");
+        else if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN)
+          failf(data, "schannel: CertGetCertificateChain trust error"
+                " CERT_TRUST_IS_PARTIAL_CHAIN");
+        else if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT)
+          failf(data, "schannel: CertGetCertificateChain trust error"
+                " CERT_TRUST_IS_UNTRUSTED_ROOT");
+        else if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID)
+          failf(data, "schannel: CertGetCertificateChain trust error"
+                " CERT_TRUST_IS_NOT_TIME_VALID");
+        else
+          failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x",
+                dwTrustErrorMask);
+        result = CURLE_PEER_FAILED_VERIFICATION;
+      }
+    }
+  }
+
+  if(result == CURLE_OK) {
+    if(data->set.ssl.verifyhost) {
+      TCHAR cert_hostname_buff[128];
+      xcharp_u hostname;
+      xcharp_u cert_hostname;
+      DWORD len;
+
+      cert_hostname.const_tchar_ptr = cert_hostname_buff;
+      hostname.tchar_ptr = Curl_convert_UTF8_to_tchar(conn->host.name);
+
+      /* TODO: Fix this for certificates with multiple alternative names.
+      Right now we're only asking for the first preferred alternative name.
+      Instead we'd need to do all via CERT_NAME_SEARCH_ALL_NAMES_FLAG
+      (if WinCE supports that?) and run this section in a loop for each.
+      https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx
+      curl: (51) schannel: CertGetNameString() certificate hostname
+      (.google.com) did not match connection (google.com)
+      */
+      len = CertGetNameString(pCertContextServer,
+                              CERT_NAME_DNS_TYPE,
+                              0,
+                              NULL,
+                              cert_hostname.tchar_ptr,
+                              128);
+      if(len > 0 && *cert_hostname.tchar_ptr == '*') {
+        /* this is a wildcard cert.  try matching the last len - 1 chars */
+        int hostname_len = strlen(conn->host.name);
+        cert_hostname.tchar_ptr++;
+        if(_tcsicmp(cert_hostname.const_tchar_ptr,
+                    hostname.const_tchar_ptr + hostname_len - len + 2) != 0)
+          result = CURLE_PEER_FAILED_VERIFICATION;
+      }
+      else if(len == 0 || _tcsicmp(hostname.const_tchar_ptr,
+                                   cert_hostname.const_tchar_ptr) != 0) {
+        result = CURLE_PEER_FAILED_VERIFICATION;
+      }
+      if(result == CURLE_PEER_FAILED_VERIFICATION) {
+        char *_cert_hostname;
+        _cert_hostname = Curl_convert_tchar_to_UTF8(cert_hostname.tchar_ptr);
+        failf(data, "schannel: CertGetNameString() certificate hostname "
+              "(%s) did not match connection (%s)",
+              _cert_hostname, conn->host.name);
+        Curl_unicodefree(_cert_hostname);
+      }
+      Curl_unicodefree(hostname.tchar_ptr);
+    }
+  }
+
+  if(pChainContext)
+    CertFreeCertificateChain(pChainContext);
+
+  if(pCertContextServer)
+    CertFreeCertificateContext(pCertContextServer);
+
+  return result;
+}
+#endif /* _WIN32_WCE */
+
+#endif /* USE_SCHANNEL */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/schannel.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/schannel.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/schannel.h	(revision 164)
@@ -0,0 +1,118 @@
+#ifndef HEADER_CURL_SCHANNEL_H
+#define HEADER_CURL_SCHANNEL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012, Marc Hoersken, <info@marc-hoersken.de>, et al.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_SCHANNEL
+
+#include "urldata.h"
+
+#ifndef UNISP_NAME_A
+#define UNISP_NAME_A "Microsoft Unified Security Protocol Provider"
+#endif
+
+#ifndef UNISP_NAME_W
+#define UNISP_NAME_W L"Microsoft Unified Security Protocol Provider"
+#endif
+
+#ifndef UNISP_NAME
+#ifdef UNICODE
+#define UNISP_NAME  UNISP_NAME_W
+#else
+#define UNISP_NAME  UNISP_NAME_A
+#endif
+#endif
+
+#ifndef SP_PROT_SSL2_CLIENT
+#define SP_PROT_SSL2_CLIENT             0x00000008
+#endif
+
+#ifndef SP_PROT_SSL3_CLIENT
+#define SP_PROT_SSL3_CLIENT             0x00000008
+#endif
+
+#ifndef SP_PROT_TLS1_CLIENT
+#define SP_PROT_TLS1_CLIENT             0x00000080
+#endif
+
+#ifndef SP_PROT_TLS1_0_CLIENT
+#define SP_PROT_TLS1_0_CLIENT           SP_PROT_TLS1_CLIENT
+#endif
+
+#ifndef SP_PROT_TLS1_1_CLIENT
+#define SP_PROT_TLS1_1_CLIENT           0x00000200
+#endif
+
+#ifndef SP_PROT_TLS1_2_CLIENT
+#define SP_PROT_TLS1_2_CLIENT           0x00000800
+#endif
+
+#ifndef SECBUFFER_ALERT
+#define SECBUFFER_ALERT                 17
+#endif
+
+/* Both schannel buffer sizes must be > 0 */
+#define CURL_SCHANNEL_BUFFER_INIT_SIZE   4096
+#define CURL_SCHANNEL_BUFFER_FREE_SIZE   1024
+
+
+CURLcode Curl_schannel_connect(struct connectdata *conn, int sockindex);
+
+CURLcode Curl_schannel_connect_nonblocking(struct connectdata *conn,
+                                           int sockindex,
+                                           bool *done);
+
+bool Curl_schannel_data_pending(const struct connectdata *conn, int sockindex);
+void Curl_schannel_close(struct connectdata *conn, int sockindex);
+int Curl_schannel_shutdown(struct connectdata *conn, int sockindex);
+void Curl_schannel_session_free(void *ptr);
+
+int Curl_schannel_init(void);
+void Curl_schannel_cleanup(void);
+size_t Curl_schannel_version(char *buffer, size_t size);
+
+int Curl_schannel_random(unsigned char *entropy, size_t length);
+
+/* Set the API backend definition to Schannel */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_SCHANNEL
+
+/* API setup for Schannel */
+#define curlssl_init Curl_schannel_init
+#define curlssl_cleanup Curl_schannel_cleanup
+#define curlssl_connect Curl_schannel_connect
+#define curlssl_connect_nonblocking Curl_schannel_connect_nonblocking
+#define curlssl_session_free Curl_schannel_session_free
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_schannel_close
+#define curlssl_shutdown Curl_schannel_shutdown
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_schannel_version
+#define curlssl_check_cxn(x) ((void)x, -1)
+#define curlssl_data_pending Curl_schannel_data_pending
+#define curlssl_random(x,y,z) ((void)x, Curl_schannel_random(y,z))
+
+#endif /* USE_SCHANNEL */
+#endif /* HEADER_CURL_SCHANNEL_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/vtls.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/vtls.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/vtls.c	(revision 164)
@@ -0,0 +1,965 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This file is for implementing all "generic" SSL functions that all libcurl
+   internals should use. It is then responsible for calling the proper
+   "backend" function.
+
+   SSL-functions in libcurl should call functions in this source file, and not
+   to any specific SSL-layer.
+
+   Curl_ssl_ - prefix for generic ones
+   Curl_ossl_ - prefix for OpenSSL ones
+   Curl_gtls_ - prefix for GnuTLS ones
+   Curl_nss_ - prefix for NSS ones
+   Curl_gskit_ - prefix for GSKit ones
+   Curl_polarssl_ - prefix for PolarSSL ones
+   Curl_cyassl_ - prefix for CyaSSL ones
+   Curl_schannel_ - prefix for Schannel SSPI ones
+   Curl_darwinssl_ - prefix for SecureTransport (Darwin) ones
+
+   Note that this source code uses curlssl_* functions, and they are all
+   defines/macros #defined by the lib-specific header files.
+
+   "SSL/TLS Strong Encryption: An Introduction"
+   https://httpd.apache.org/docs/2.0/ssl/ssl_intro.html
+*/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include "urldata.h"
+
+#include "vtls.h" /* generic SSL protos etc */
+#include "slist.h"
+#include "sendf.h"
+#include "rawstr.h"
+#include "url.h"
+#include "progress.h"
+#include "share.h"
+#include "timeval.h"
+#include "curl_md5.h"
+#include "warnless.h"
+#include "curl_base64.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* convenience macro to check if this handle is using a shared SSL session */
+#define SSLSESSION_SHARED(data) (data->share &&                        \
+                                 (data->share->specifier &             \
+                                  (1<<CURL_LOCK_DATA_SSL_SESSION)))
+
+static bool safe_strequal(char* str1, char* str2)
+{
+  if(str1 && str2)
+    /* both pointers point to something then compare them */
+    return (0 != Curl_raw_equal(str1, str2)) ? TRUE : FALSE;
+  else
+    /* if both pointers are NULL then treat them as equal */
+    return (!str1 && !str2) ? TRUE : FALSE;
+}
+
+bool
+Curl_ssl_config_matches(struct ssl_config_data* data,
+                        struct ssl_config_data* needle)
+{
+  if((data->version == needle->version) &&
+     (data->verifypeer == needle->verifypeer) &&
+     (data->verifyhost == needle->verifyhost) &&
+     safe_strequal(data->CApath, needle->CApath) &&
+     safe_strequal(data->CAfile, needle->CAfile) &&
+     safe_strequal(data->random_file, needle->random_file) &&
+     safe_strequal(data->egdsocket, needle->egdsocket) &&
+     safe_strequal(data->cipher_list, needle->cipher_list))
+    return TRUE;
+
+  return FALSE;
+}
+
+bool
+Curl_clone_ssl_config(struct ssl_config_data *source,
+                      struct ssl_config_data *dest)
+{
+  dest->sessionid = source->sessionid;
+  dest->verifyhost = source->verifyhost;
+  dest->verifypeer = source->verifypeer;
+  dest->version = source->version;
+
+  if(source->CAfile) {
+    dest->CAfile = strdup(source->CAfile);
+    if(!dest->CAfile)
+      return FALSE;
+  }
+  else
+    dest->CAfile = NULL;
+
+  if(source->CApath) {
+    dest->CApath = strdup(source->CApath);
+    if(!dest->CApath)
+      return FALSE;
+  }
+  else
+    dest->CApath = NULL;
+
+  if(source->cipher_list) {
+    dest->cipher_list = strdup(source->cipher_list);
+    if(!dest->cipher_list)
+      return FALSE;
+  }
+  else
+    dest->cipher_list = NULL;
+
+  if(source->egdsocket) {
+    dest->egdsocket = strdup(source->egdsocket);
+    if(!dest->egdsocket)
+      return FALSE;
+  }
+  else
+    dest->egdsocket = NULL;
+
+  if(source->random_file) {
+    dest->random_file = strdup(source->random_file);
+    if(!dest->random_file)
+      return FALSE;
+  }
+  else
+    dest->random_file = NULL;
+
+  return TRUE;
+}
+
+void Curl_free_ssl_config(struct ssl_config_data* sslc)
+{
+  Curl_safefree(sslc->CAfile);
+  Curl_safefree(sslc->CApath);
+  Curl_safefree(sslc->cipher_list);
+  Curl_safefree(sslc->egdsocket);
+  Curl_safefree(sslc->random_file);
+}
+
+
+/*
+ * Curl_rand() returns a random unsigned integer, 32bit.
+ *
+ * This non-SSL function is put here only because this file is the only one
+ * with knowledge of what the underlying SSL libraries provide in terms of
+ * randomizers.
+ *
+ * NOTE: 'data' may be passed in as NULL when coming from external API without
+ * easy handle!
+ *
+ */
+
+unsigned int Curl_rand(struct SessionHandle *data)
+{
+  unsigned int r = 0;
+  static unsigned int randseed;
+  static bool seeded = FALSE;
+
+#ifdef CURLDEBUG
+  char *force_entropy = getenv("CURL_ENTROPY");
+  if(force_entropy) {
+    if(!seeded) {
+      size_t elen = strlen(force_entropy);
+      size_t clen = sizeof(randseed);
+      size_t min = elen < clen ? elen : clen;
+      memcpy((char *)&randseed, force_entropy, min);
+      seeded = TRUE;
+    }
+    else
+      randseed++;
+    return randseed;
+  }
+#endif
+
+  /* data may be NULL! */
+  if(!Curl_ssl_random(data, (unsigned char *)&r, sizeof(r)))
+    return r;
+
+  /* If Curl_ssl_random() returns non-zero it couldn't offer randomness and we
+     instead perform a "best effort" */
+
+#ifdef RANDOM_FILE
+  if(!seeded) {
+    /* if there's a random file to read a seed from, use it */
+    int fd = open(RANDOM_FILE, O_RDONLY);
+    if(fd > -1) {
+      /* read random data into the randseed variable */
+      ssize_t nread = read(fd, &randseed, sizeof(randseed));
+      if(nread == sizeof(randseed))
+        seeded = TRUE;
+      close(fd);
+    }
+  }
+#endif
+
+  if(!seeded) {
+    struct timeval now = curlx_tvnow();
+    infof(data, "WARNING: Using weak random seed\n");
+    randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec;
+    randseed = randseed * 1103515245 + 12345;
+    randseed = randseed * 1103515245 + 12345;
+    randseed = randseed * 1103515245 + 12345;
+    seeded = TRUE;
+  }
+
+  /* Return an unsigned 32-bit pseudo-random number. */
+  r = randseed = randseed * 1103515245 + 12345;
+  return (r << 16) | ((r >> 16) & 0xFFFF);
+}
+
+int Curl_ssl_backend(void)
+{
+  return (int)CURL_SSL_BACKEND;
+}
+
+#ifdef USE_SSL
+
+/* "global" init done? */
+static bool init_ssl=FALSE;
+
+/**
+ * Global SSL init
+ *
+ * @retval 0 error initializing SSL
+ * @retval 1 SSL initialized successfully
+ */
+int Curl_ssl_init(void)
+{
+  /* make sure this is only done once */
+  if(init_ssl)
+    return 1;
+  init_ssl = TRUE; /* never again */
+
+  return curlssl_init();
+}
+
+
+/* Global cleanup */
+void Curl_ssl_cleanup(void)
+{
+  if(init_ssl) {
+    /* only cleanup if we did a previous init */
+    curlssl_cleanup();
+    init_ssl = FALSE;
+  }
+}
+
+static bool ssl_prefs_check(struct SessionHandle *data)
+{
+  /* check for CURLOPT_SSLVERSION invalid parameter value */
+  if((data->set.ssl.version < 0)
+     || (data->set.ssl.version >= CURL_SSLVERSION_LAST)) {
+    failf(data, "Unrecognized parameter value passed via CURLOPT_SSLVERSION");
+    return FALSE;
+  }
+  return TRUE;
+}
+
+CURLcode
+Curl_ssl_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode result;
+
+  if(!ssl_prefs_check(conn->data))
+    return CURLE_SSL_CONNECT_ERROR;
+
+  /* mark this is being ssl-enabled from here on. */
+  conn->ssl[sockindex].use = TRUE;
+  conn->ssl[sockindex].state = ssl_connection_negotiating;
+
+  result = curlssl_connect(conn, sockindex);
+
+  if(!result)
+    Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */
+
+  return result;
+}
+
+CURLcode
+Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex,
+                             bool *done)
+{
+  CURLcode result;
+
+  if(!ssl_prefs_check(conn->data))
+    return CURLE_SSL_CONNECT_ERROR;
+
+  /* mark this is being ssl requested from here on. */
+  conn->ssl[sockindex].use = TRUE;
+#ifdef curlssl_connect_nonblocking
+  result = curlssl_connect_nonblocking(conn, sockindex, done);
+#else
+  *done = TRUE; /* fallback to BLOCKING */
+  result = curlssl_connect(conn, sockindex);
+#endif /* non-blocking connect support */
+  if(!result && *done)
+    Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */
+  return result;
+}
+
+/*
+ * Check if there's a session ID for the given connection in the cache, and if
+ * there's one suitable, it is provided. Returns TRUE when no entry matched.
+ */
+bool Curl_ssl_getsessionid(struct connectdata *conn,
+                           void **ssl_sessionid,
+                           size_t *idsize) /* set 0 if unknown */
+{
+  struct curl_ssl_session *check;
+  struct SessionHandle *data = conn->data;
+  size_t i;
+  long *general_age;
+  bool no_match = TRUE;
+
+  *ssl_sessionid = NULL;
+
+  if(!conn->ssl_config.sessionid)
+    /* session ID re-use is disabled */
+    return TRUE;
+
+  /* Lock if shared */
+  if(SSLSESSION_SHARED(data)) {
+    Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE);
+    general_age = &data->share->sessionage;
+  }
+  else
+    general_age = &data->state.sessionage;
+
+  for(i = 0; i < data->set.ssl.max_ssl_sessions; i++) {
+    check = &data->state.session[i];
+    if(!check->sessionid)
+      /* not session ID means blank entry */
+      continue;
+    if(Curl_raw_equal(conn->host.name, check->name) &&
+       (conn->remote_port == check->remote_port) &&
+       Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) {
+      /* yes, we have a session ID! */
+      (*general_age)++;          /* increase general age */
+      check->age = *general_age; /* set this as used in this age */
+      *ssl_sessionid = check->sessionid;
+      if(idsize)
+        *idsize = check->idsize;
+      no_match = FALSE;
+      break;
+    }
+  }
+
+  /* Unlock */
+  if(SSLSESSION_SHARED(data))
+    Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION);
+
+  return no_match;
+}
+
+/*
+ * Kill a single session ID entry in the cache.
+ */
+void Curl_ssl_kill_session(struct curl_ssl_session *session)
+{
+  if(session->sessionid) {
+    /* defensive check */
+
+    /* free the ID the SSL-layer specific way */
+    curlssl_session_free(session->sessionid);
+
+    session->sessionid = NULL;
+    session->age = 0; /* fresh */
+
+    Curl_free_ssl_config(&session->ssl_config);
+
+    Curl_safefree(session->name);
+  }
+}
+
+/*
+ * Delete the given session ID from the cache.
+ */
+void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid)
+{
+  size_t i;
+  struct SessionHandle *data=conn->data;
+
+  if(SSLSESSION_SHARED(data))
+    Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE);
+
+  for(i = 0; i < data->set.ssl.max_ssl_sessions; i++) {
+    struct curl_ssl_session *check = &data->state.session[i];
+
+    if(check->sessionid == ssl_sessionid) {
+      Curl_ssl_kill_session(check);
+      break;
+    }
+  }
+
+  if(SSLSESSION_SHARED(data))
+    Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION);
+}
+
+/*
+ * Store session id in the session cache. The ID passed on to this function
+ * must already have been extracted and allocated the proper way for the SSL
+ * layer. Curl_XXXX_session_free() will be called to free/kill the session ID
+ * later on.
+ */
+CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
+                               void *ssl_sessionid,
+                               size_t idsize)
+{
+  size_t i;
+  struct SessionHandle *data=conn->data; /* the mother of all structs */
+  struct curl_ssl_session *store = &data->state.session[0];
+  long oldest_age=data->state.session[0].age; /* zero if unused */
+  char *clone_host;
+  long *general_age;
+
+  /* Even though session ID re-use might be disabled, that only disables USING
+     IT. We still store it here in case the re-using is again enabled for an
+     upcoming transfer */
+
+  clone_host = strdup(conn->host.name);
+  if(!clone_host)
+    return CURLE_OUT_OF_MEMORY; /* bail out */
+
+  /* Now we should add the session ID and the host name to the cache, (remove
+     the oldest if necessary) */
+
+  /* If using shared SSL session, lock! */
+  if(SSLSESSION_SHARED(data)) {
+    Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE);
+    general_age = &data->share->sessionage;
+  }
+  else {
+    general_age = &data->state.sessionage;
+  }
+
+  /* find an empty slot for us, or find the oldest */
+  for(i = 1; (i < data->set.ssl.max_ssl_sessions) &&
+        data->state.session[i].sessionid; i++) {
+    if(data->state.session[i].age < oldest_age) {
+      oldest_age = data->state.session[i].age;
+      store = &data->state.session[i];
+    }
+  }
+  if(i == data->set.ssl.max_ssl_sessions)
+    /* cache is full, we must "kill" the oldest entry! */
+    Curl_ssl_kill_session(store);
+  else
+    store = &data->state.session[i]; /* use this slot */
+
+  /* now init the session struct wisely */
+  store->sessionid = ssl_sessionid;
+  store->idsize = idsize;
+  store->age = *general_age;    /* set current age */
+    /* free it if there's one already present */
+  free(store->name);
+  store->name = clone_host;               /* clone host name */
+  store->remote_port = conn->remote_port; /* port number */
+
+
+  /* Unlock */
+  if(SSLSESSION_SHARED(data))
+    Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION);
+
+  if(!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config)) {
+    store->sessionid = NULL; /* let caller free sessionid */
+    free(clone_host);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  return CURLE_OK;
+}
+
+
+void Curl_ssl_close_all(struct SessionHandle *data)
+{
+  size_t i;
+  /* kill the session ID cache if not shared */
+  if(data->state.session && !SSLSESSION_SHARED(data)) {
+    for(i = 0; i < data->set.ssl.max_ssl_sessions; i++)
+      /* the single-killer function handles empty table slots */
+      Curl_ssl_kill_session(&data->state.session[i]);
+
+    /* free the cache data */
+    Curl_safefree(data->state.session);
+  }
+
+  curlssl_close_all(data);
+}
+
+void Curl_ssl_close(struct connectdata *conn, int sockindex)
+{
+  DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
+  curlssl_close(conn, sockindex);
+}
+
+CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex)
+{
+  if(curlssl_shutdown(conn, sockindex))
+    return CURLE_SSL_SHUTDOWN_FAILED;
+
+  conn->ssl[sockindex].use = FALSE; /* get back to ordinary socket usage */
+  conn->ssl[sockindex].state = ssl_connection_none;
+
+  conn->recv[sockindex] = Curl_recv_plain;
+  conn->send[sockindex] = Curl_send_plain;
+
+  return CURLE_OK;
+}
+
+/* Selects an SSL crypto engine
+ */
+CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine)
+{
+  return curlssl_set_engine(data, engine);
+}
+
+/* Selects the default SSL crypto engine
+ */
+CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data)
+{
+  return curlssl_set_engine_default(data);
+}
+
+/* Return list of OpenSSL crypto engine names. */
+struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data)
+{
+  return curlssl_engines_list(data);
+}
+
+/*
+ * This sets up a session ID cache to the specified size. Make sure this code
+ * is agnostic to what underlying SSL technology we use.
+ */
+CURLcode Curl_ssl_initsessions(struct SessionHandle *data, size_t amount)
+{
+  struct curl_ssl_session *session;
+
+  if(data->state.session)
+    /* this is just a precaution to prevent multiple inits */
+    return CURLE_OK;
+
+  session = calloc(amount, sizeof(struct curl_ssl_session));
+  if(!session)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* store the info in the SSL section */
+  data->set.ssl.max_ssl_sessions = amount;
+  data->state.session = session;
+  data->state.sessionage = 1; /* this is brand new */
+  return CURLE_OK;
+}
+
+size_t Curl_ssl_version(char *buffer, size_t size)
+{
+  return curlssl_version(buffer, size);
+}
+
+/*
+ * This function tries to determine connection status.
+ *
+ * Return codes:
+ *     1 means the connection is still in place
+ *     0 means the connection has been closed
+ *    -1 means the connection status is unknown
+ */
+int Curl_ssl_check_cxn(struct connectdata *conn)
+{
+  return curlssl_check_cxn(conn);
+}
+
+bool Curl_ssl_data_pending(const struct connectdata *conn,
+                           int connindex)
+{
+  return curlssl_data_pending(conn, connindex);
+}
+
+void Curl_ssl_free_certinfo(struct SessionHandle *data)
+{
+  int i;
+  struct curl_certinfo *ci = &data->info.certs;
+
+  if(ci->num_of_certs) {
+    /* free all individual lists used */
+    for(i=0; i<ci->num_of_certs; i++) {
+      curl_slist_free_all(ci->certinfo[i]);
+      ci->certinfo[i] = NULL;
+    }
+
+    free(ci->certinfo); /* free the actual array too */
+    ci->certinfo = NULL;
+    ci->num_of_certs = 0;
+  }
+}
+
+CURLcode Curl_ssl_init_certinfo(struct SessionHandle *data, int num)
+{
+  struct curl_certinfo *ci = &data->info.certs;
+  struct curl_slist **table;
+
+  /* Free any previous certificate information structures */
+  Curl_ssl_free_certinfo(data);
+
+  /* Allocate the required certificate information structures */
+  table = calloc((size_t) num, sizeof(struct curl_slist *));
+  if(!table)
+    return CURLE_OUT_OF_MEMORY;
+
+  ci->num_of_certs = num;
+  ci->certinfo = table;
+
+  return CURLE_OK;
+}
+
+/*
+ * 'value' is NOT a zero terminated string
+ */
+CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle *data,
+                                    int certnum,
+                                    const char *label,
+                                    const char *value,
+                                    size_t valuelen)
+{
+  struct curl_certinfo * ci = &data->info.certs;
+  char * output;
+  struct curl_slist * nl;
+  CURLcode result = CURLE_OK;
+  size_t labellen = strlen(label);
+  size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */
+
+  output = malloc(outlen);
+  if(!output)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* sprintf the label and colon */
+  snprintf(output, outlen, "%s:", label);
+
+  /* memcpy the value (it might not be zero terminated) */
+  memcpy(&output[labellen+1], value, valuelen);
+
+  /* zero terminate the output */
+  output[labellen + 1 + valuelen] = 0;
+
+  nl = Curl_slist_append_nodup(ci->certinfo[certnum], output);
+  if(!nl) {
+    free(output);
+    curl_slist_free_all(ci->certinfo[certnum]);
+    result = CURLE_OUT_OF_MEMORY;
+  }
+
+  ci->certinfo[certnum] = nl;
+  return result;
+}
+
+/*
+ * This is a convenience function for push_certinfo_len that takes a zero
+ * terminated value.
+ */
+CURLcode Curl_ssl_push_certinfo(struct SessionHandle *data,
+                                int certnum,
+                                const char *label,
+                                const char *value)
+{
+  size_t valuelen = strlen(value);
+
+  return Curl_ssl_push_certinfo_len(data, certnum, label, value, valuelen);
+}
+
+int Curl_ssl_random(struct SessionHandle *data,
+                     unsigned char *entropy,
+                     size_t length)
+{
+  return curlssl_random(data, entropy, length);
+}
+
+/*
+ * Public key pem to der conversion
+ */
+
+static CURLcode pubkey_pem_to_der(const char *pem,
+                                  unsigned char **der, size_t *der_len)
+{
+  char *stripped_pem, *begin_pos, *end_pos;
+  size_t pem_count, stripped_pem_count = 0, pem_len;
+  CURLcode result;
+
+  /* if no pem, exit. */
+  if(!pem)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  begin_pos = strstr(pem, "-----BEGIN PUBLIC KEY-----");
+  if(!begin_pos)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  pem_count = begin_pos - pem;
+  /* Invalid if not at beginning AND not directly following \n */
+  if(0 != pem_count && '\n' != pem[pem_count - 1])
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* 26 is length of "-----BEGIN PUBLIC KEY-----" */
+  pem_count += 26;
+
+  /* Invalid if not directly following \n */
+  end_pos = strstr(pem + pem_count, "\n-----END PUBLIC KEY-----");
+  if(!end_pos)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  pem_len = end_pos - pem;
+
+  stripped_pem = malloc(pem_len - pem_count + 1);
+  if(!stripped_pem)
+    return CURLE_OUT_OF_MEMORY;
+
+  /*
+   * Here we loop through the pem array one character at a time between the
+   * correct indices, and place each character that is not '\n' or '\r'
+   * into the stripped_pem array, which should represent the raw base64 string
+   */
+  while(pem_count < pem_len) {
+    if('\n' != pem[pem_count] && '\r' != pem[pem_count])
+      stripped_pem[stripped_pem_count++] = pem[pem_count];
+    ++pem_count;
+  }
+  /* Place the null terminator in the correct place */
+  stripped_pem[stripped_pem_count] = '\0';
+
+  result = Curl_base64_decode(stripped_pem, der, der_len);
+
+  Curl_safefree(stripped_pem);
+
+  return result;
+}
+
+/*
+ * Generic pinned public key check.
+ */
+
+CURLcode Curl_pin_peer_pubkey(struct SessionHandle *data,
+                              const char *pinnedpubkey,
+                              const unsigned char *pubkey, size_t pubkeylen)
+{
+  FILE *fp;
+  unsigned char *buf = NULL, *pem_ptr = NULL;
+  long filesize;
+  size_t size, pem_len;
+  CURLcode pem_read;
+  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+#ifdef curlssl_sha256sum
+  CURLcode encode;
+  size_t encodedlen, pinkeylen;
+  char *encoded, *pinkeycopy, *begin_pos, *end_pos;
+  unsigned char *sha256sumdigest = NULL;
+#endif
+
+  /* if a path wasn't specified, don't pin */
+  if(!pinnedpubkey)
+    return CURLE_OK;
+  if(!pubkey || !pubkeylen)
+    return result;
+
+#ifdef curlssl_sha256sum
+  /* only do this if pinnedpubkey starts with "sha256//", length 8 */
+  if(strncmp(pinnedpubkey, "sha256//", 8) == 0) {
+    /* compute sha256sum of public key */
+    sha256sumdigest = malloc(SHA256_DIGEST_LENGTH);
+    if(!sha256sumdigest)
+      return CURLE_OUT_OF_MEMORY;
+    curlssl_sha256sum(pubkey, pubkeylen,
+                      sha256sumdigest, SHA256_DIGEST_LENGTH);
+    encode = Curl_base64_encode(data, (char *)sha256sumdigest,
+                                SHA256_DIGEST_LENGTH, &encoded, &encodedlen);
+    Curl_safefree(sha256sumdigest);
+
+    if(encode)
+      return encode;
+
+    infof(data, "\t public key hash: sha256//%s\n", encoded);
+
+    /* it starts with sha256//, copy so we can modify it */
+    pinkeylen = strlen(pinnedpubkey) + 1;
+    pinkeycopy = malloc(pinkeylen);
+    if(!pinkeycopy) {
+      Curl_safefree(encoded);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    memcpy(pinkeycopy, pinnedpubkey, pinkeylen);
+    /* point begin_pos to the copy, and start extracting keys */
+    begin_pos = pinkeycopy;
+    do {
+      end_pos = strstr(begin_pos, ";sha256//");
+      /*
+       * if there is an end_pos, null terminate,
+       * otherwise it'll go to the end of the original string
+       */
+      if(end_pos)
+        end_pos[0] = '\0';
+
+      /* compare base64 sha256 digests, 8 is the length of "sha256//" */
+      if(encodedlen == strlen(begin_pos + 8) &&
+         !memcmp(encoded, begin_pos + 8, encodedlen)) {
+        result = CURLE_OK;
+        break;
+      }
+
+      /*
+       * change back the null-terminator we changed earlier,
+       * and look for next begin
+       */
+      if(end_pos) {
+        end_pos[0] = ';';
+        begin_pos = strstr(end_pos, "sha256//");
+      }
+    } while(end_pos && begin_pos);
+    Curl_safefree(encoded);
+    Curl_safefree(pinkeycopy);
+    return result;
+  }
+#else
+  (void)data;
+#endif
+
+  fp = fopen(pinnedpubkey, "rb");
+  if(!fp)
+    return result;
+
+  do {
+    /* Determine the file's size */
+    if(fseek(fp, 0, SEEK_END))
+      break;
+    filesize = ftell(fp);
+    if(fseek(fp, 0, SEEK_SET))
+      break;
+    if(filesize < 0 || filesize > MAX_PINNED_PUBKEY_SIZE)
+      break;
+
+    /*
+     * if the size of our certificate is bigger than the file
+     * size then it can't match
+     */
+    size = curlx_sotouz((curl_off_t) filesize);
+    if(pubkeylen > size)
+      break;
+
+    /*
+     * Allocate buffer for the pinned key
+     * With 1 additional byte for null terminator in case of PEM key
+     */
+    buf = malloc(size + 1);
+    if(!buf)
+      break;
+
+    /* Returns number of elements read, which should be 1 */
+    if((int) fread(buf, size, 1, fp) != 1)
+      break;
+
+    /* If the sizes are the same, it can't be base64 encoded, must be der */
+    if(pubkeylen == size) {
+      if(!memcmp(pubkey, buf, pubkeylen))
+        result = CURLE_OK;
+      break;
+    }
+
+    /*
+     * Otherwise we will assume it's PEM and try to decode it
+     * after placing null terminator
+     */
+    buf[size] = '\0';
+    pem_read = pubkey_pem_to_der((const char *)buf, &pem_ptr, &pem_len);
+    /* if it wasn't read successfully, exit */
+    if(pem_read)
+      break;
+
+    /*
+     * if the size of our certificate doesn't match the size of
+     * the decoded file, they can't be the same, otherwise compare
+     */
+    if(pubkeylen == pem_len && !memcmp(pubkey, pem_ptr, pubkeylen))
+      result = CURLE_OK;
+  } while(0);
+
+  Curl_safefree(buf);
+  Curl_safefree(pem_ptr);
+  fclose(fp);
+
+  return result;
+}
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */
+                         size_t tmplen,
+                         unsigned char *md5sum, /* output */
+                         size_t md5len)
+{
+#ifdef curlssl_md5sum
+  curlssl_md5sum(tmp, tmplen, md5sum, md5len);
+#else
+  MD5_context *MD5pw;
+
+  (void) md5len;
+
+  MD5pw = Curl_MD5_init(Curl_DIGEST_MD5);
+  if(!MD5pw)
+    return CURLE_OUT_OF_MEMORY;
+  Curl_MD5_update(MD5pw, tmp, curlx_uztoui(tmplen));
+  Curl_MD5_final(MD5pw, md5sum);
+#endif
+  return CURLE_OK;
+}
+#endif
+
+/*
+ * Check whether the SSL backend supports the status_request extension.
+ */
+bool Curl_ssl_cert_status_request(void)
+{
+#ifdef curlssl_cert_status_request
+  return curlssl_cert_status_request();
+#else
+  return FALSE;
+#endif
+}
+
+/*
+ * Check whether the SSL backend supports false start.
+ */
+bool Curl_ssl_false_start(void)
+{
+#ifdef curlssl_false_start
+  return curlssl_false_start();
+#else
+  return FALSE;
+#endif
+}
+
+#endif /* USE_SSL */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/vtls.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/vtls/vtls.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/vtls/vtls.h	(revision 164)
@@ -0,0 +1,159 @@
+#ifndef HEADER_CURL_VTLS_H
+#define HEADER_CURL_VTLS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#include "openssl.h"        /* OpenSSL versions */
+#include "gtls.h"           /* GnuTLS versions */
+#include "nssg.h"           /* NSS versions */
+#include "gskit.h"          /* Global Secure ToolKit versions */
+#include "polarssl.h"       /* PolarSSL versions */
+#include "axtls.h"          /* axTLS versions */
+#include "cyassl.h"         /* CyaSSL versions */
+#include "schannel.h"       /* Schannel SSPI version */
+#include "darwinssl.h"      /* SecureTransport (Darwin) version */
+#include "mbedtls.h"        /* mbedTLS versions */
+
+#ifndef MAX_PINNED_PUBKEY_SIZE
+#define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */
+#endif
+
+#ifndef MD5_DIGEST_LENGTH
+#define MD5_DIGEST_LENGTH 16 /* fixed size */
+#endif
+
+#ifndef SHA256_DIGEST_LENGTH
+#define SHA256_DIGEST_LENGTH 32 /* fixed size */
+#endif
+
+/* see https://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-04 */
+#define ALPN_HTTP_1_1_LENGTH 8
+#define ALPN_HTTP_1_1 "http/1.1"
+
+bool Curl_ssl_config_matches(struct ssl_config_data* data,
+                             struct ssl_config_data* needle);
+bool Curl_clone_ssl_config(struct ssl_config_data* source,
+                           struct ssl_config_data* dest);
+void Curl_free_ssl_config(struct ssl_config_data* sslc);
+
+unsigned int Curl_rand(struct SessionHandle *);
+
+int Curl_ssl_backend(void);
+
+#ifdef USE_SSL
+int Curl_ssl_init(void);
+void Curl_ssl_cleanup(void);
+CURLcode Curl_ssl_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_ssl_connect_nonblocking(struct connectdata *conn,
+                                      int sockindex,
+                                      bool *done);
+/* tell the SSL stuff to close down all open information regarding
+   connections (and thus session ID caching etc) */
+void Curl_ssl_close_all(struct SessionHandle *data);
+void Curl_ssl_close(struct connectdata *conn, int sockindex);
+CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex);
+CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine);
+/* Sets engine as default for all SSL operations */
+CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data);
+struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data);
+
+/* init the SSL session ID cache */
+CURLcode Curl_ssl_initsessions(struct SessionHandle *, size_t);
+size_t Curl_ssl_version(char *buffer, size_t size);
+bool Curl_ssl_data_pending(const struct connectdata *conn,
+                           int connindex);
+int Curl_ssl_check_cxn(struct connectdata *conn);
+
+/* Certificate information list handling. */
+
+void Curl_ssl_free_certinfo(struct SessionHandle *data);
+CURLcode Curl_ssl_init_certinfo(struct SessionHandle * data, int num);
+CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle * data, int certnum,
+                                    const char * label, const char * value,
+                                    size_t valuelen);
+CURLcode Curl_ssl_push_certinfo(struct SessionHandle * data, int certnum,
+                                const char * label, const char * value);
+
+/* Functions to be used by SSL library adaptation functions */
+
+/* extract a session ID */
+bool Curl_ssl_getsessionid(struct connectdata *conn,
+                           void **ssl_sessionid,
+                           size_t *idsize) /* set 0 if unknown */;
+/* add a new session ID */
+CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
+                               void *ssl_sessionid,
+                               size_t idsize);
+/* Kill a single session ID entry in the cache */
+void Curl_ssl_kill_session(struct curl_ssl_session *session);
+/* delete a session from the cache */
+void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid);
+
+/* get N random bytes into the buffer, return 0 if a find random is filled
+   in */
+int Curl_ssl_random(struct SessionHandle *data, unsigned char *buffer,
+                    size_t length);
+CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */
+                         size_t tmplen,
+                         unsigned char *md5sum, /* output */
+                         size_t md5len);
+/* Check pinned public key. */
+CURLcode Curl_pin_peer_pubkey(struct SessionHandle *data,
+                              const char *pinnedpubkey,
+                              const unsigned char *pubkey, size_t pubkeylen);
+
+bool Curl_ssl_cert_status_request(void);
+
+bool Curl_ssl_false_start(void);
+
+#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */
+
+#else
+/* Set the API backend definition to none */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_NONE
+
+/* When SSL support is not present, just define away these function calls */
+#define Curl_ssl_init() 1
+#define Curl_ssl_cleanup() Curl_nop_stmt
+#define Curl_ssl_connect(x,y) CURLE_NOT_BUILT_IN
+#define Curl_ssl_close_all(x) Curl_nop_stmt
+#define Curl_ssl_close(x,y) Curl_nop_stmt
+#define Curl_ssl_shutdown(x,y) CURLE_NOT_BUILT_IN
+#define Curl_ssl_set_engine(x,y) CURLE_NOT_BUILT_IN
+#define Curl_ssl_set_engine_default(x) CURLE_NOT_BUILT_IN
+#define Curl_ssl_engines_list(x) NULL
+#define Curl_ssl_send(a,b,c,d,e) -1
+#define Curl_ssl_recv(a,b,c,d,e) -1
+#define Curl_ssl_initsessions(x,y) CURLE_OK
+#define Curl_ssl_version(x,y) 0
+#define Curl_ssl_data_pending(x,y) 0
+#define Curl_ssl_check_cxn(x) 0
+#define Curl_ssl_free_certinfo(x) Curl_nop_stmt
+#define Curl_ssl_connect_nonblocking(x,y,z) CURLE_NOT_BUILT_IN
+#define Curl_ssl_kill_session(x) Curl_nop_stmt
+#define Curl_ssl_random(x,y,z) ((void)x, CURLE_NOT_BUILT_IN)
+#define Curl_ssl_cert_status_request() FALSE
+#define Curl_ssl_false_start() FALSE
+#endif
+
+#endif /* HEADER_CURL_VTLS_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/warnless.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/warnless.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/warnless.c	(revision 164)
@@ -0,0 +1,486 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(__INTEL_COMPILER) && defined(__unix__)
+
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+
+#endif /* __INTEL_COMPILER && __unix__ */
+
+#define BUILDING_WARNLESS_C 1
+
+#include "warnless.h"
+
+#define CURL_MASK_SCHAR  0x7F
+#define CURL_MASK_UCHAR  0xFF
+
+#if (SIZEOF_SHORT == 2)
+#  define CURL_MASK_SSHORT  0x7FFF
+#  define CURL_MASK_USHORT  0xFFFF
+#elif (SIZEOF_SHORT == 4)
+#  define CURL_MASK_SSHORT  0x7FFFFFFF
+#  define CURL_MASK_USHORT  0xFFFFFFFF
+#elif (SIZEOF_SHORT == 8)
+#  define CURL_MASK_SSHORT  0x7FFFFFFFFFFFFFFF
+#  define CURL_MASK_USHORT  0xFFFFFFFFFFFFFFFF
+#else
+#  error "SIZEOF_SHORT not defined"
+#endif
+
+#if (SIZEOF_INT == 2)
+#  define CURL_MASK_SINT  0x7FFF
+#  define CURL_MASK_UINT  0xFFFF
+#elif (SIZEOF_INT == 4)
+#  define CURL_MASK_SINT  0x7FFFFFFF
+#  define CURL_MASK_UINT  0xFFFFFFFF
+#elif (SIZEOF_INT == 8)
+#  define CURL_MASK_SINT  0x7FFFFFFFFFFFFFFF
+#  define CURL_MASK_UINT  0xFFFFFFFFFFFFFFFF
+#elif (SIZEOF_INT == 16)
+#  define CURL_MASK_SINT  0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+#  define CURL_MASK_UINT  0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+#else
+#  error "SIZEOF_INT not defined"
+#endif
+
+#if (CURL_SIZEOF_LONG == 2)
+#  define CURL_MASK_SLONG  0x7FFFL
+#  define CURL_MASK_ULONG  0xFFFFUL
+#elif (CURL_SIZEOF_LONG == 4)
+#  define CURL_MASK_SLONG  0x7FFFFFFFL
+#  define CURL_MASK_ULONG  0xFFFFFFFFUL
+#elif (CURL_SIZEOF_LONG == 8)
+#  define CURL_MASK_SLONG  0x7FFFFFFFFFFFFFFFL
+#  define CURL_MASK_ULONG  0xFFFFFFFFFFFFFFFFUL
+#elif (CURL_SIZEOF_LONG == 16)
+#  define CURL_MASK_SLONG  0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFL
+#  define CURL_MASK_ULONG  0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFUL
+#else
+#  error "CURL_SIZEOF_LONG not defined"
+#endif
+
+#if (CURL_SIZEOF_CURL_OFF_T == 2)
+#  define CURL_MASK_SCOFFT  CURL_OFF_T_C(0x7FFF)
+#  define CURL_MASK_UCOFFT  CURL_OFF_TU_C(0xFFFF)
+#elif (CURL_SIZEOF_CURL_OFF_T == 4)
+#  define CURL_MASK_SCOFFT  CURL_OFF_T_C(0x7FFFFFFF)
+#  define CURL_MASK_UCOFFT  CURL_OFF_TU_C(0xFFFFFFFF)
+#elif (CURL_SIZEOF_CURL_OFF_T == 8)
+#  define CURL_MASK_SCOFFT  CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF)
+#  define CURL_MASK_UCOFFT  CURL_OFF_TU_C(0xFFFFFFFFFFFFFFFF)
+#elif (CURL_SIZEOF_CURL_OFF_T == 16)
+#  define CURL_MASK_SCOFFT  CURL_OFF_T_C(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
+#  define CURL_MASK_UCOFFT  CURL_OFF_TU_C(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
+#else
+#  error "CURL_SIZEOF_CURL_OFF_T not defined"
+#endif
+
+#if (SIZEOF_SIZE_T == SIZEOF_SHORT)
+#  define CURL_MASK_SSIZE_T  CURL_MASK_SSHORT
+#  define CURL_MASK_USIZE_T  CURL_MASK_USHORT
+#elif (SIZEOF_SIZE_T == SIZEOF_INT)
+#  define CURL_MASK_SSIZE_T  CURL_MASK_SINT
+#  define CURL_MASK_USIZE_T  CURL_MASK_UINT
+#elif (SIZEOF_SIZE_T == CURL_SIZEOF_LONG)
+#  define CURL_MASK_SSIZE_T  CURL_MASK_SLONG
+#  define CURL_MASK_USIZE_T  CURL_MASK_ULONG
+#elif (SIZEOF_SIZE_T == CURL_SIZEOF_CURL_OFF_T)
+#  define CURL_MASK_SSIZE_T  CURL_MASK_SCOFFT
+#  define CURL_MASK_USIZE_T  CURL_MASK_UCOFFT
+#else
+#  error "SIZEOF_SIZE_T not defined"
+#endif
+
+/*
+** unsigned long to unsigned short
+*/
+
+unsigned short curlx_ultous(unsigned long ulnum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_USHORT);
+  return (unsigned short)(ulnum & (unsigned long) CURL_MASK_USHORT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned long to unsigned char
+*/
+
+unsigned char curlx_ultouc(unsigned long ulnum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_UCHAR);
+  return (unsigned char)(ulnum & (unsigned long) CURL_MASK_UCHAR);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned long to signed int
+*/
+
+int curlx_ultosi(unsigned long ulnum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_SINT);
+  return (int)(ulnum & (unsigned long) CURL_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to signed curl_off_t
+*/
+
+curl_off_t curlx_uztoso(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(uznum <= (size_t) CURL_MASK_SCOFFT);
+  return (curl_off_t)(uznum & (size_t) CURL_MASK_SCOFFT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to signed int
+*/
+
+int curlx_uztosi(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(uznum <= (size_t) CURL_MASK_SINT);
+  return (int)(uznum & (size_t) CURL_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to unsigned long
+*/
+
+unsigned long curlx_uztoul(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+#if (CURL_SIZEOF_LONG < SIZEOF_SIZE_T)
+  DEBUGASSERT(uznum <= (size_t) CURL_MASK_ULONG);
+#endif
+  return (unsigned long)(uznum & (size_t) CURL_MASK_ULONG);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to unsigned int
+*/
+
+unsigned int curlx_uztoui(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+#if (SIZEOF_INT < SIZEOF_SIZE_T)
+  DEBUGASSERT(uznum <= (size_t) CURL_MASK_UINT);
+#endif
+  return (unsigned int)(uznum & (size_t) CURL_MASK_UINT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** signed long to signed int
+*/
+
+int curlx_sltosi(long slnum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(slnum >= 0);
+#if (SIZEOF_INT < CURL_SIZEOF_LONG)
+  DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_SINT);
+#endif
+  return (int)(slnum & (long) CURL_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** signed long to unsigned int
+*/
+
+unsigned int curlx_sltoui(long slnum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(slnum >= 0);
+#if (SIZEOF_INT < CURL_SIZEOF_LONG)
+  DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_UINT);
+#endif
+  return (unsigned int)(slnum & (long) CURL_MASK_UINT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** signed long to unsigned short
+*/
+
+unsigned short curlx_sltous(long slnum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(slnum >= 0);
+  DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_USHORT);
+  return (unsigned short)(slnum & (long) CURL_MASK_USHORT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to signed ssize_t
+*/
+
+ssize_t curlx_uztosz(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(uznum <= (size_t) CURL_MASK_SSIZE_T);
+  return (ssize_t)(uznum & (size_t) CURL_MASK_SSIZE_T);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** signed curl_off_t to unsigned size_t
+*/
+
+size_t curlx_sotouz(curl_off_t sonum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(sonum >= 0);
+  return (size_t)(sonum & (curl_off_t) CURL_MASK_USIZE_T);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** signed ssize_t to signed int
+*/
+
+int curlx_sztosi(ssize_t sznum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(sznum >= 0);
+#if (SIZEOF_INT < SIZEOF_SIZE_T)
+  DEBUGASSERT((size_t) sznum <= (size_t) CURL_MASK_SINT);
+#endif
+  return (int)(sznum & (ssize_t) CURL_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** signed int to unsigned size_t
+*/
+
+size_t curlx_sitouz(int sinum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(sinum >= 0);
+  return (size_t) sinum;
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+#ifdef USE_WINSOCK
+
+/*
+** curl_socket_t to signed int
+*/
+
+int curlx_sktosi(curl_socket_t s)
+{
+  return (int)((ssize_t) s);
+}
+
+/*
+** signed int to curl_socket_t
+*/
+
+curl_socket_t curlx_sitosk(int i)
+{
+  return (curl_socket_t)((ssize_t) i);
+}
+
+#endif /* USE_WINSOCK */
+
+#if defined(WIN32) || defined(_WIN32)
+
+ssize_t curlx_read(int fd, void *buf, size_t count)
+{
+  return (ssize_t)read(fd, buf, curlx_uztoui(count));
+}
+
+ssize_t curlx_write(int fd, const void *buf, size_t count)
+{
+  return (ssize_t)write(fd, buf, curlx_uztoui(count));
+}
+
+#endif /* WIN32 || _WIN32 */
+
+#if defined(__INTEL_COMPILER) && defined(__unix__)
+
+int curlx_FD_ISSET(int fd, fd_set *fdset)
+{
+  #pragma warning(push)
+  #pragma warning(disable:1469) /* clobber ignored */
+  return FD_ISSET(fd, fdset);
+  #pragma warning(pop)
+}
+
+void curlx_FD_SET(int fd, fd_set *fdset)
+{
+  #pragma warning(push)
+  #pragma warning(disable:1469) /* clobber ignored */
+  FD_SET(fd, fdset);
+  #pragma warning(pop)
+}
+
+void curlx_FD_ZERO(fd_set *fdset)
+{
+  #pragma warning(push)
+  #pragma warning(disable:593) /* variable was set but never used */
+  FD_ZERO(fdset);
+  #pragma warning(pop)
+}
+
+unsigned short curlx_htons(unsigned short usnum)
+{
+#if (__INTEL_COMPILER == 910) && defined(__i386__)
+  return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF));
+#else
+  #pragma warning(push)
+  #pragma warning(disable:810) /* conversion may lose significant bits */
+  return htons(usnum);
+  #pragma warning(pop)
+#endif
+}
+
+unsigned short curlx_ntohs(unsigned short usnum)
+{
+#if (__INTEL_COMPILER == 910) && defined(__i386__)
+  return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF));
+#else
+  #pragma warning(push)
+  #pragma warning(disable:810) /* conversion may lose significant bits */
+  return ntohs(usnum);
+  #pragma warning(pop)
+#endif
+}
+
+#endif /* __INTEL_COMPILER && __unix__ */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/warnless.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/warnless.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/warnless.h	(revision 164)
@@ -0,0 +1,107 @@
+#ifndef HEADER_CURL_WARNLESS_H
+#define HEADER_CURL_WARNLESS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef USE_WINSOCK
+#include <curl/curl.h> /* for curl_socket_t */
+#endif
+
+unsigned short curlx_ultous(unsigned long ulnum);
+
+unsigned char curlx_ultouc(unsigned long ulnum);
+
+int curlx_ultosi(unsigned long ulnum);
+
+int curlx_uztosi(size_t uznum);
+
+curl_off_t curlx_uztoso(size_t uznum);
+
+unsigned long curlx_uztoul(size_t uznum);
+
+unsigned int curlx_uztoui(size_t uznum);
+
+int curlx_sltosi(long slnum);
+
+unsigned int curlx_sltoui(long slnum);
+
+unsigned short curlx_sltous(long slnum);
+
+ssize_t curlx_uztosz(size_t uznum);
+
+size_t curlx_sotouz(curl_off_t sonum);
+
+int curlx_sztosi(ssize_t sznum);
+
+size_t curlx_sitouz(int sinum);
+
+#ifdef USE_WINSOCK
+
+int curlx_sktosi(curl_socket_t s);
+
+curl_socket_t curlx_sitosk(int i);
+
+#endif /* USE_WINSOCK */
+
+#if defined(WIN32) || defined(_WIN32)
+
+ssize_t curlx_read(int fd, void *buf, size_t count);
+
+ssize_t curlx_write(int fd, const void *buf, size_t count);
+
+#ifndef BUILDING_WARNLESS_C
+#  undef  read
+#  define read(fd, buf, count)  curlx_read(fd, buf, count)
+#  undef  write
+#  define write(fd, buf, count) curlx_write(fd, buf, count)
+#endif
+
+#endif /* WIN32 || _WIN32 */
+
+#if defined(__INTEL_COMPILER) && defined(__unix__)
+
+int curlx_FD_ISSET(int fd, fd_set *fdset);
+
+void curlx_FD_SET(int fd, fd_set *fdset);
+
+void curlx_FD_ZERO(fd_set *fdset);
+
+unsigned short curlx_htons(unsigned short usnum);
+
+unsigned short curlx_ntohs(unsigned short usnum);
+
+#ifndef BUILDING_WARNLESS_C
+#  undef  FD_ISSET
+#  define FD_ISSET(a,b) curlx_FD_ISSET((a),(b))
+#  undef  FD_SET
+#  define FD_SET(a,b)   curlx_FD_SET((a),(b))
+#  undef  FD_ZERO
+#  define FD_ZERO(a)    curlx_FD_ZERO((a))
+#  undef  htons
+#  define htons(a)      curlx_htons((a))
+#  undef  ntohs
+#  define ntohs(a)      curlx_ntohs((a))
+#endif
+
+#endif /* __INTEL_COMPILER && __unix__ */
+
+#endif /* HEADER_CURL_WARNLESS_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/wildcard.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/wildcard.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/wildcard.c	(revision 164)
@@ -0,0 +1,69 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "wildcard.h"
+#include "llist.h"
+#include "fileinfo.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+CURLcode Curl_wildcard_init(struct WildcardData *wc)
+{
+  DEBUGASSERT(wc->filelist == NULL);
+  /* now allocate only wc->filelist, everything else
+     will be allocated if it is needed. */
+  wc->filelist = Curl_llist_alloc(Curl_fileinfo_dtor);
+  if(!wc->filelist) {;
+    return CURLE_OUT_OF_MEMORY;
+  }
+  return CURLE_OK;
+}
+
+void Curl_wildcard_dtor(struct WildcardData *wc)
+{
+  if(!wc)
+    return;
+
+  if(wc->tmp_dtor) {
+    wc->tmp_dtor(wc->tmp);
+    wc->tmp_dtor = ZERO_NULL;
+    wc->tmp = NULL;
+  }
+  DEBUGASSERT(wc->tmp == NULL);
+
+  if(wc->filelist) {
+    Curl_llist_destroy(wc->filelist, NULL);
+    wc->filelist = NULL;
+  }
+
+  free(wc->path);
+  wc->path = NULL;
+  free(wc->pattern);
+  wc->pattern = NULL;
+
+  wc->customptr = NULL;
+  wc->state = CURLWC_INIT;
+}
Index: UsbWattMeter/trunk/curl-7.47.1/lib/wildcard.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/wildcard.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/wildcard.h	(revision 164)
@@ -0,0 +1,58 @@
+#ifndef HEADER_CURL_WILDCARD_H
+#define HEADER_CURL_WILDCARD_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+/* list of wildcard process states */
+typedef enum {
+  CURLWC_INIT = 0,
+  CURLWC_MATCHING, /* library is trying to get list of addresses for
+                      downloading */
+  CURLWC_DOWNLOADING,
+  CURLWC_CLEAN, /* deallocate resources and reset settings */
+  CURLWC_SKIP,  /* skip over concrete file */
+  CURLWC_ERROR, /* error cases */
+  CURLWC_DONE   /* if is wildcard->state == CURLWC_DONE wildcard loop
+                   will end */
+} curl_wildcard_states;
+
+typedef void (*curl_wildcard_tmp_dtor)(void *ptr);
+
+/* struct keeping information about wildcard download process */
+struct WildcardData {
+  curl_wildcard_states state;
+  char *path; /* path to the directory, where we trying wildcard-match */
+  char *pattern; /* wildcard pattern */
+  struct curl_llist *filelist; /* llist with struct Curl_fileinfo */
+  void *tmp; /* pointer to protocol specific temporary data */
+  curl_wildcard_tmp_dtor tmp_dtor;
+  void *customptr;  /* for CURLOPT_CHUNK_DATA pointer */
+};
+
+CURLcode Curl_wildcard_init(struct WildcardData *wc);
+void Curl_wildcard_dtor(struct WildcardData *wc);
+
+struct SessionHandle;
+
+#endif /* HEADER_CURL_WILDCARD_H */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/x509asn1.c
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/x509asn1.c	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/x509asn1.c	(revision 164)
@@ -0,0 +1,1184 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
+    defined(USE_CYASSL)
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "strequal.h"
+#include "hostcheck.h"
+#include "vtls/vtls.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "curl_base64.h"
+#include "x509asn1.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+
+/* ASN.1 OIDs. */
+static const char       cnOID[] = "2.5.4.3";    /* Common name. */
+static const char       sanOID[] = "2.5.29.17"; /* Subject alternative name. */
+
+static const curl_OID   OIDtable[] = {
+  { "1.2.840.10040.4.1",        "dsa" },
+  { "1.2.840.10040.4.3",        "dsa-with-sha1" },
+  { "1.2.840.10045.2.1",        "ecPublicKey" },
+  { "1.2.840.10045.3.0.1",      "c2pnb163v1" },
+  { "1.2.840.10045.4.1",        "ecdsa-with-SHA1" },
+  { "1.2.840.10046.2.1",        "dhpublicnumber" },
+  { "1.2.840.113549.1.1.1",     "rsaEncryption" },
+  { "1.2.840.113549.1.1.2",     "md2WithRSAEncryption" },
+  { "1.2.840.113549.1.1.4",     "md5WithRSAEncryption" },
+  { "1.2.840.113549.1.1.5",     "sha1WithRSAEncryption" },
+  { "1.2.840.113549.1.1.10",    "RSASSA-PSS" },
+  { "1.2.840.113549.1.1.14",    "sha224WithRSAEncryption" },
+  { "1.2.840.113549.1.1.11",    "sha256WithRSAEncryption" },
+  { "1.2.840.113549.1.1.12",    "sha384WithRSAEncryption" },
+  { "1.2.840.113549.1.1.13",    "sha512WithRSAEncryption" },
+  { "1.2.840.113549.2.2",       "md2" },
+  { "1.2.840.113549.2.5",       "md5" },
+  { "1.3.14.3.2.26",            "sha1" },
+  { cnOID,                      "CN" },
+  { "2.5.4.4",                  "SN" },
+  { "2.5.4.5",                  "serialNumber" },
+  { "2.5.4.6",                  "C" },
+  { "2.5.4.7",                  "L" },
+  { "2.5.4.8",                  "ST" },
+  { "2.5.4.9",                  "streetAddress" },
+  { "2.5.4.10",                 "O" },
+  { "2.5.4.11",                 "OU" },
+  { "2.5.4.12",                 "title" },
+  { "2.5.4.13",                 "description" },
+  { "2.5.4.17",                 "postalCode" },
+  { "2.5.4.41",                 "name" },
+  { "2.5.4.42",                 "givenName" },
+  { "2.5.4.43",                 "initials" },
+  { "2.5.4.44",                 "generationQualifier" },
+  { "2.5.4.45",                 "X500UniqueIdentifier" },
+  { "2.5.4.46",                 "dnQualifier" },
+  { "2.5.4.65",                 "pseudonym" },
+  { "1.2.840.113549.1.9.1",     "emailAddress" },
+  { "2.5.4.72",                 "role" },
+  { sanOID,                     "subjectAltName" },
+  { "2.5.29.18",                "issuerAltName" },
+  { "2.5.29.19",                "basicConstraints" },
+  { "2.16.840.1.101.3.4.2.4",   "sha224" },
+  { "2.16.840.1.101.3.4.2.1",   "sha256" },
+  { "2.16.840.1.101.3.4.2.2",   "sha384" },
+  { "2.16.840.1.101.3.4.2.3",   "sha512" },
+  { (const char *) NULL,        (const char *) NULL }
+};
+
+/*
+ * Lightweight ASN.1 parser.
+ * In particular, it does not check for syntactic/lexical errors.
+ * It is intended to support certificate information gathering for SSL backends
+ * that offer a mean to get certificates as a whole, but do not supply
+ * entry points to get particular certificate sub-fields.
+ * Please note there is no pretention here to rewrite a full SSL library.
+ */
+
+
+const char * Curl_getASN1Element(curl_asn1Element * elem,
+                                 const char * beg, const char * end)
+{
+  unsigned char b;
+  unsigned long len;
+  curl_asn1Element lelem;
+
+  /* Get a single ASN.1 element into `elem', parse ASN.1 string at `beg'
+     ending at `end'.
+     Returns a pointer in source string after the parsed element, or NULL
+     if an error occurs. */
+
+  if(beg >= end || !*beg)
+    return (const char *) NULL;
+
+  /* Process header byte. */
+  elem->header = beg;
+  b = (unsigned char) *beg++;
+  elem->constructed = (b & 0x20) != 0;
+  elem->class = (b >> 6) & 3;
+  b &= 0x1F;
+  if(b == 0x1F)
+    return (const char *) NULL; /* Long tag values not supported here. */
+  elem->tag = b;
+
+  /* Process length. */
+  if(beg >= end)
+    return (const char *) NULL;
+  b = (unsigned char) *beg++;
+  if(!(b & 0x80))
+    len = b;
+  else if(!(b &= 0x7F)) {
+    /* Unspecified length. Since we have all the data, we can determine the
+       effective length by skipping element until an end element is found. */
+    if(!elem->constructed)
+      return (const char *) NULL;
+    elem->beg = beg;
+    while(beg < end && *beg) {
+      beg = Curl_getASN1Element(&lelem, beg, end);
+      if(!beg)
+        return (const char *) NULL;
+    }
+    if(beg >= end)
+      return (const char *) NULL;
+    elem->end = beg;
+    return beg + 1;
+  }
+  else if(beg + b > end)
+    return (const char *) NULL; /* Does not fit in source. */
+  else {
+    /* Get long length. */
+    len = 0;
+    do {
+      if(len & 0xFF000000L)
+        return (const char *) NULL;  /* Lengths > 32 bits are not supported. */
+      len = (len << 8) | (unsigned char) *beg++;
+    } while(--b);
+  }
+  if((unsigned long) (end - beg) < len)
+    return (const char *) NULL;  /* Element data does not fit in source. */
+  elem->beg = beg;
+  elem->end = beg + len;
+  return elem->end;
+}
+
+static const curl_OID * searchOID(const char * oid)
+{
+  const curl_OID * op;
+
+  /* Search the null terminated OID or OID identifier in local table.
+     Return the table entry pointer or NULL if not found. */
+
+  for(op = OIDtable; op->numoid; op++)
+    if(!strcmp(op->numoid, oid) || curl_strequal(op->textoid, oid))
+      return op;
+
+  return (const curl_OID *) NULL;
+}
+
+static const char * bool2str(const char * beg, const char * end)
+{
+  /* Convert an ASN.1 Boolean value into its string representation.
+     Return the dynamically allocated string, or NULL if source is not an
+     ASN.1 Boolean value. */
+
+  if(end - beg != 1)
+    return (const char *) NULL;
+  return strdup(*beg? "TRUE": "FALSE");
+}
+
+static const char * octet2str(const char * beg, const char * end)
+{
+  size_t n = end - beg;
+  char * buf;
+
+  /* Convert an ASN.1 octet string to a printable string.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  buf = malloc(3 * n + 1);
+  if(buf)
+    for(n = 0; beg < end; n += 3)
+      snprintf(buf + n, 4, "%02x:", *(const unsigned char *) beg++);
+  return buf;
+}
+
+static const char * bit2str(const char * beg, const char * end)
+{
+  /* Convert an ASN.1 bit string to a printable string.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  if(++beg > end)
+    return (const char *) NULL;
+  return octet2str(beg, end);
+}
+
+static const char * int2str(const char * beg, const char * end)
+{
+  long val = 0;
+  size_t n = end - beg;
+
+  /* Convert an ASN.1 integer value into its string representation.
+     Return the dynamically allocated string, or NULL if source is not an
+     ASN.1 integer value. */
+
+  if(!n)
+    return (const char *) NULL;
+
+  if(n > 4)
+    return octet2str(beg, end);
+
+  /* Represent integers <= 32-bit as a single value. */
+  if(*beg & 0x80)
+    val = ~val;
+
+  do
+    val = (val << 8) | *(const unsigned char *) beg++;
+  while(beg < end);
+  return curl_maprintf("%s%lx", (val < 0 || val >= 10)? "0x": "", val);
+}
+
+static ssize_t
+utf8asn1str(char * * to, int type, const char * from, const char * end)
+{
+  size_t inlength = end - from;
+  int size = 1;
+  size_t outlength;
+  int charsize;
+  unsigned int wc;
+  char * buf;
+
+  /* Perform a lazy conversion from an ASN.1 typed string to UTF8. Allocate the
+     destination buffer dynamically. The allocation size will normally be too
+     large: this is to avoid buffer overflows.
+     Terminate the string with a nul byte and return the converted
+     string length. */
+
+  *to = (char *) NULL;
+  switch (type) {
+  case CURL_ASN1_BMP_STRING:
+    size = 2;
+    break;
+  case CURL_ASN1_UNIVERSAL_STRING:
+    size = 4;
+    break;
+  case CURL_ASN1_NUMERIC_STRING:
+  case CURL_ASN1_PRINTABLE_STRING:
+  case CURL_ASN1_TELETEX_STRING:
+  case CURL_ASN1_IA5_STRING:
+  case CURL_ASN1_VISIBLE_STRING:
+  case CURL_ASN1_UTF8_STRING:
+    break;
+  default:
+    return -1;  /* Conversion not supported. */
+  }
+
+  if(inlength % size)
+    return -1;  /* Length inconsistent with character size. */
+  buf = malloc(4 * (inlength / size) + 1);
+  if(!buf)
+    return -1;  /* Not enough memory. */
+
+  if(type == CURL_ASN1_UTF8_STRING) {
+    /* Just copy. */
+    outlength = inlength;
+    if(outlength)
+      memcpy(buf, from, outlength);
+  }
+  else {
+    for(outlength = 0; from < end;) {
+      wc = 0;
+      switch (size) {
+      case 4:
+        wc = (wc << 8) | *(const unsigned char *) from++;
+        wc = (wc << 8) | *(const unsigned char *) from++;
+        /* fallthrough */
+      case 2:
+        wc = (wc << 8) | *(const unsigned char *) from++;
+        /* fallthrough */
+      default: /* case 1: */
+        wc = (wc << 8) | *(const unsigned char *) from++;
+      }
+      charsize = 1;
+      if(wc >= 0x00000080) {
+        if(wc >= 0x00000800) {
+          if(wc >= 0x00010000) {
+            if(wc >= 0x00200000) {
+              free(buf);
+              return -1;        /* Invalid char. size for target encoding. */
+            }
+            buf[outlength + 3] = (char) (0x80 | (wc & 0x3F));
+            wc = (wc >> 6) | 0x00010000;
+            charsize++;
+          }
+          buf[outlength + 2] = (char) (0x80 | (wc & 0x3F));
+          wc = (wc >> 6) | 0x00000800;
+          charsize++;
+        }
+        buf[outlength + 1] = (char) (0x80 | (wc & 0x3F));
+        wc = (wc >> 6) | 0x000000C0;
+        charsize++;
+      }
+      buf[outlength] = (char) wc;
+      outlength += charsize;
+    }
+  }
+  buf[outlength] = '\0';
+  *to = buf;
+  return outlength;
+}
+
+static const char * string2str(int type, const char * beg, const char * end)
+{
+  char * buf;
+
+  /* Convert an ASN.1 String into its UTF-8 string representation.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  if(utf8asn1str(&buf, type, beg, end) < 0)
+    return (const char *) NULL;
+  return buf;
+}
+
+static int encodeUint(char * buf, int n, unsigned int x)
+{
+  int i = 0;
+  unsigned int y = x / 10;
+
+  /* Decimal ASCII encode unsigned integer `x' in the `n'-byte buffer at `buf'.
+     Return the total number of encoded digits, even if larger than `n'. */
+
+  if(y) {
+    i += encodeUint(buf, n, y);
+    x -= y * 10;
+  }
+  if(i < n)
+    buf[i] = (char) ('0' + x);
+  i++;
+  if(i < n)
+    buf[i] = '\0';      /* Store a terminator if possible. */
+  return i;
+}
+
+static int encodeOID(char * buf, int n, const char * beg, const char * end)
+{
+  int i = 0;
+  unsigned int x;
+  unsigned int y;
+
+  /* Convert an ASN.1 OID into its dotted string representation.
+     Store the result in th `n'-byte buffer at `buf'.
+     Return the converted string length, or -1 if an error occurs. */
+
+  /* Process the first two numbers. */
+  y = *(const unsigned char *) beg++;
+  x = y / 40;
+  y -= x * 40;
+  i += encodeUint(buf + i, n - i, x);
+  if(i < n)
+    buf[i] = '.';
+  i++;
+  i += encodeUint(buf + i, n - i, y);
+
+  /* Process the trailing numbers. */
+  while(beg < end) {
+    if(i < n)
+      buf[i] = '.';
+    i++;
+    x = 0;
+    do {
+      if(x & 0xFF000000)
+        return -1;
+      y = *(const unsigned char *) beg++;
+      x = (x << 7) | (y & 0x7F);
+    } while(y & 0x80);
+    i += encodeUint(buf + i, n - i, x);
+  }
+  if(i < n)
+    buf[i] = '\0';
+  return i;
+}
+
+static const char * OID2str(const char * beg, const char * end, bool symbolic)
+{
+  char * buf = (char *) NULL;
+  const curl_OID * op;
+  int n;
+
+  /* Convert an ASN.1 OID into its dotted or symbolic string representation.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  if(beg < end) {
+    n = encodeOID((char *) NULL, -1, beg, end);
+    if(n >= 0) {
+      buf = malloc(n + 1);
+      if(buf) {
+        encodeOID(buf, n, beg, end);
+        buf[n] = '\0';
+
+        if(symbolic) {
+          op = searchOID(buf);
+          if(op) {
+            free(buf);
+            buf = strdup(op->textoid);
+          }
+        }
+      }
+    }
+  }
+  return buf;
+}
+
+static const char * GTime2str(const char * beg, const char * end)
+{
+  const char * tzp;
+  const char * fracp;
+  char sec1, sec2;
+  size_t fracl;
+  size_t tzl;
+  const char * sep = "";
+
+  /* Convert an ASN.1 Generalized time to a printable string.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  for(fracp = beg; fracp < end && *fracp >= '0' && *fracp <= '9'; fracp++)
+    ;
+
+  /* Get seconds digits. */
+  sec1 = '0';
+  switch (fracp - beg - 12) {
+  case 0:
+    sec2 = '0';
+    break;
+  case 2:
+    sec1 = fracp[-2];
+  case 1:
+    sec2 = fracp[-1];
+    break;
+  default:
+    return (const char *) NULL;
+  }
+
+  /* Scan for timezone, measure fractional seconds. */
+  tzp = fracp;
+  fracl = 0;
+  if(fracp < end && (*fracp == '.' || *fracp == ',')) {
+    fracp++;
+    do
+      tzp++;
+    while(tzp < end && *tzp >= '0' && *tzp <= '9');
+    /* Strip leading zeroes in fractional seconds. */
+    for(fracl = tzp - fracp - 1; fracl && fracp[fracl - 1] == '0'; fracl--)
+      ;
+  }
+
+  /* Process timezone. */
+  if(tzp >= end)
+    ;           /* Nothing to do. */
+  else if(*tzp == 'Z') {
+    tzp = " GMT";
+    end = tzp + 4;
+  }
+  else {
+    sep = " ";
+    tzp++;
+  }
+
+  tzl = end - tzp;
+  return curl_maprintf("%.4s-%.2s-%.2s %.2s:%.2s:%c%c%s%.*s%s%.*s",
+                       beg, beg + 4, beg + 6,
+                       beg + 8, beg + 10, sec1, sec2,
+                       fracl? ".": "", fracl, fracp,
+                       sep, tzl, tzp);
+}
+
+static const char * UTime2str(const char * beg, const char * end)
+{
+  const char * tzp;
+  size_t tzl;
+  const char * sec;
+
+  /* Convert an ASN.1 UTC time to a printable string.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  for(tzp = beg; tzp < end && *tzp >= '0' && *tzp <= '9'; tzp++)
+    ;
+  /* Get the seconds. */
+  sec = beg + 10;
+  switch (tzp - sec) {
+  case 0:
+    sec = "00";
+  case 2:
+    break;
+  default:
+    return (const char *) NULL;
+  }
+
+  /* Process timezone. */
+  if(tzp >= end)
+    return (const char *) NULL;
+  if(*tzp == 'Z') {
+    tzp = "GMT";
+    end = tzp + 3;
+  }
+  else
+    tzp++;
+
+  tzl = end - tzp;
+  return curl_maprintf("%u%.2s-%.2s-%.2s %.2s:%.2s:%.2s %.*s",
+                       20 - (*beg >= '5'), beg, beg + 2, beg + 4,
+                       beg + 6, beg + 8, sec,
+                       tzl, tzp);
+}
+
+const char * Curl_ASN1tostr(curl_asn1Element * elem, int type)
+{
+  /* Convert an ASN.1 element to a printable string.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  if(elem->constructed)
+    return (const char *) NULL; /* No conversion of structured elements. */
+
+  if(!type)
+    type = elem->tag;   /* Type not forced: use element tag as type. */
+
+  switch (type) {
+  case CURL_ASN1_BOOLEAN:
+    return bool2str(elem->beg, elem->end);
+  case CURL_ASN1_INTEGER:
+  case CURL_ASN1_ENUMERATED:
+    return int2str(elem->beg, elem->end);
+  case CURL_ASN1_BIT_STRING:
+    return bit2str(elem->beg, elem->end);
+  case CURL_ASN1_OCTET_STRING:
+    return octet2str(elem->beg, elem->end);
+  case CURL_ASN1_NULL:
+    return strdup("");
+  case CURL_ASN1_OBJECT_IDENTIFIER:
+    return OID2str(elem->beg, elem->end, TRUE);
+  case CURL_ASN1_UTC_TIME:
+    return UTime2str(elem->beg, elem->end);
+  case CURL_ASN1_GENERALIZED_TIME:
+    return GTime2str(elem->beg, elem->end);
+  case CURL_ASN1_UTF8_STRING:
+  case CURL_ASN1_NUMERIC_STRING:
+  case CURL_ASN1_PRINTABLE_STRING:
+  case CURL_ASN1_TELETEX_STRING:
+  case CURL_ASN1_IA5_STRING:
+  case CURL_ASN1_VISIBLE_STRING:
+  case CURL_ASN1_UNIVERSAL_STRING:
+  case CURL_ASN1_BMP_STRING:
+    return string2str(type, elem->beg, elem->end);
+  }
+
+  return (const char *) NULL;   /* Unsupported. */
+}
+
+static ssize_t encodeDN(char * buf, size_t n, curl_asn1Element * dn)
+{
+  curl_asn1Element rdn;
+  curl_asn1Element atv;
+  curl_asn1Element oid;
+  curl_asn1Element value;
+  size_t l = 0;
+  const char * p1;
+  const char * p2;
+  const char * p3;
+  const char * str;
+
+  /* ASCII encode distinguished name at `dn' into the `n'-byte buffer at `buf'.
+     Return the total string length, even if larger than `n'. */
+
+  for(p1 = dn->beg; p1 < dn->end;) {
+    p1 = Curl_getASN1Element(&rdn, p1, dn->end);
+    for(p2 = rdn.beg; p2 < rdn.end;) {
+      p2 = Curl_getASN1Element(&atv, p2, rdn.end);
+      p3 = Curl_getASN1Element(&oid, atv.beg, atv.end);
+      Curl_getASN1Element(&value, p3, atv.end);
+      str = Curl_ASN1tostr(&oid, 0);
+      if(!str)
+        return -1;
+
+      /* Encode delimiter.
+         If attribute has a short uppercase name, delimiter is ", ". */
+      if(l) {
+        for(p3 = str; isupper(*p3); p3++)
+          ;
+        for(p3 = (*p3 || p3 - str > 2)? "/": ", "; *p3; p3++) {
+          if(l < n)
+            buf[l] = *p3;
+          l++;
+        }
+      }
+
+      /* Encode attribute name. */
+      for(p3 = str; *p3; p3++) {
+        if(l < n)
+          buf[l] = *p3;
+        l++;
+      }
+      free((char *) str);
+
+      /* Generate equal sign. */
+      if(l < n)
+        buf[l] = '=';
+      l++;
+
+      /* Generate value. */
+      str = Curl_ASN1tostr(&value, 0);
+      if(!str)
+        return -1;
+      for(p3 = str; *p3; p3++) {
+        if(l < n)
+          buf[l] = *p3;
+        l++;
+      }
+      free((char *) str);
+    }
+  }
+
+  return l;
+}
+
+const char * Curl_DNtostr(curl_asn1Element * dn)
+{
+  char * buf = (char *) NULL;
+  ssize_t n = encodeDN(buf, 0, dn);
+
+  /* Convert an ASN.1 distinguished name into a printable string.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  if(n >= 0) {
+    buf = malloc(n + 1);
+    if(buf) {
+      encodeDN(buf, n + 1, dn);
+      buf[n] = '\0';
+    }
+  }
+  return (const char *) buf;
+}
+
+/*
+ * X509 parser.
+ */
+
+void Curl_parseX509(curl_X509certificate * cert,
+                    const char * beg, const char * end)
+{
+  curl_asn1Element elem;
+  curl_asn1Element tbsCertificate;
+  const char * ccp;
+  static const char defaultVersion = 0;  /* v1. */
+
+  /* ASN.1 parse an X509 certificate into structure subfields.
+     Syntax is assumed to have already been checked by the SSL backend.
+     See RFC 5280. */
+
+  cert->certificate.header = NULL;
+  cert->certificate.beg = beg;
+  cert->certificate.end = end;
+
+  /* Get the sequence content. */
+  Curl_getASN1Element(&elem, beg, end);
+  beg = elem.beg;
+  end = elem.end;
+
+  /* Get tbsCertificate. */
+  beg = Curl_getASN1Element(&tbsCertificate, beg, end);
+  /* Skip the signatureAlgorithm. */
+  beg = Curl_getASN1Element(&cert->signatureAlgorithm, beg, end);
+  /* Get the signatureValue. */
+  Curl_getASN1Element(&cert->signature, beg, end);
+
+  /* Parse TBSCertificate. */
+  beg = tbsCertificate.beg;
+  end = tbsCertificate.end;
+  /* Get optional version, get serialNumber. */
+  cert->version.header = NULL;
+  cert->version.beg = &defaultVersion;
+  cert->version.end = &defaultVersion + sizeof defaultVersion;;
+  beg = Curl_getASN1Element(&elem, beg, end);
+  if(elem.tag == 0) {
+    Curl_getASN1Element(&cert->version, elem.beg, elem.end);
+    beg = Curl_getASN1Element(&elem, beg, end);
+  }
+  cert->serialNumber = elem;
+  /* Get signature algorithm. */
+  beg = Curl_getASN1Element(&cert->signatureAlgorithm, beg, end);
+  /* Get issuer. */
+  beg = Curl_getASN1Element(&cert->issuer, beg, end);
+  /* Get notBefore and notAfter. */
+  beg = Curl_getASN1Element(&elem, beg, end);
+  ccp = Curl_getASN1Element(&cert->notBefore, elem.beg, elem.end);
+  Curl_getASN1Element(&cert->notAfter, ccp, elem.end);
+  /* Get subject. */
+  beg = Curl_getASN1Element(&cert->subject, beg, end);
+  /* Get subjectPublicKeyAlgorithm and subjectPublicKey. */
+  beg = Curl_getASN1Element(&cert->subjectPublicKeyInfo, beg, end);
+  ccp = Curl_getASN1Element(&cert->subjectPublicKeyAlgorithm,
+                            cert->subjectPublicKeyInfo.beg,
+                            cert->subjectPublicKeyInfo.end);
+  Curl_getASN1Element(&cert->subjectPublicKey, ccp,
+                      cert->subjectPublicKeyInfo.end);
+  /* Get optional issuerUiqueID, subjectUniqueID and extensions. */
+  cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0;
+  cert->extensions.tag = elem.tag = 0;
+  cert->issuerUniqueID.header = cert->subjectUniqueID.header = NULL;
+  cert->issuerUniqueID.beg = cert->issuerUniqueID.end = "";
+  cert->subjectUniqueID.beg = cert->subjectUniqueID.end = "";
+  cert->extensions.header = NULL;
+  cert->extensions.beg = cert->extensions.end = "";
+  if(beg < end)
+    beg = Curl_getASN1Element(&elem, beg, end);
+  if(elem.tag == 1) {
+    cert->issuerUniqueID = elem;
+    if(beg < end)
+      beg = Curl_getASN1Element(&elem, beg, end);
+  }
+  if(elem.tag == 2) {
+    cert->subjectUniqueID = elem;
+    if(beg < end)
+      beg = Curl_getASN1Element(&elem, beg, end);
+  }
+  if(elem.tag == 3)
+    Curl_getASN1Element(&cert->extensions, elem.beg, elem.end);
+}
+
+static size_t copySubstring(char * to, const char * from)
+{
+  size_t i;
+
+  /* Copy at most 64-characters, terminate with a newline and returns the
+     effective number of stored characters. */
+
+  for(i = 0; i < 64; i++) {
+    to[i] = *from;
+    if(!*from++)
+      break;
+  }
+
+  to[i++] = '\n';
+  return i;
+}
+
+static const char * dumpAlgo(curl_asn1Element * param,
+                             const char * beg, const char * end)
+{
+  curl_asn1Element oid;
+
+  /* Get algorithm parameters and return algorithm name. */
+
+  beg = Curl_getASN1Element(&oid, beg, end);
+  param->header = NULL;
+  param->tag = 0;
+  param->beg = param->end = end;
+  if(beg < end)
+    Curl_getASN1Element(param, beg, end);
+  return OID2str(oid.beg, oid.end, TRUE);
+}
+
+static void do_pubkey_field(struct SessionHandle * data, int certnum,
+                            const char * label, curl_asn1Element * elem)
+{
+  const char * output;
+
+  /* Generate a certificate information record for the public key. */
+
+  output = Curl_ASN1tostr(elem, 0);
+  if(output) {
+    if(data->set.ssl.certinfo)
+      Curl_ssl_push_certinfo(data, certnum, label, output);
+    if(!certnum)
+      infof(data, "   %s: %s\n", label, output);
+    free((char *) output);
+  }
+}
+
+static void do_pubkey(struct SessionHandle * data, int certnum,
+                      const char * algo, curl_asn1Element * param,
+                      curl_asn1Element * pubkey)
+{
+  curl_asn1Element elem;
+  curl_asn1Element pk;
+  const char * p;
+  const char * q;
+  unsigned long len;
+  unsigned int i;
+
+  /* Generate all information records for the public key. */
+
+  /* Get the public key (single element). */
+  Curl_getASN1Element(&pk, pubkey->beg + 1, pubkey->end);
+
+  if(curl_strequal(algo, "rsaEncryption")) {
+    p = Curl_getASN1Element(&elem, pk.beg, pk.end);
+    /* Compute key length. */
+    for(q = elem.beg; !*q && q < elem.end; q++)
+      ;
+    len = (unsigned long)((elem.end - q) * 8);
+    if(len)
+      for(i = *(unsigned char *) q; !(i & 0x80); i <<= 1)
+        len--;
+    if(len > 32)
+      elem.beg = q;     /* Strip leading zero bytes. */
+    if(!certnum)
+      infof(data, "   RSA Public Key (%lu bits)\n", len);
+    if(data->set.ssl.certinfo) {
+      q = curl_maprintf("%lu", len);
+      if(q) {
+        Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q);
+        free((char *) q);
+      }
+    }
+    /* Generate coefficients. */
+    do_pubkey_field(data, certnum, "rsa(n)", &elem);
+    Curl_getASN1Element(&elem, p, pk.end);
+    do_pubkey_field(data, certnum, "rsa(e)", &elem);
+  }
+  else if(curl_strequal(algo, "dsa")) {
+    p = Curl_getASN1Element(&elem, param->beg, param->end);
+    do_pubkey_field(data, certnum, "dsa(p)", &elem);
+    p = Curl_getASN1Element(&elem, p, param->end);
+    do_pubkey_field(data, certnum, "dsa(q)", &elem);
+    Curl_getASN1Element(&elem, p, param->end);
+    do_pubkey_field(data, certnum, "dsa(g)", &elem);
+    do_pubkey_field(data, certnum, "dsa(pub_key)", &pk);
+  }
+  else if(curl_strequal(algo, "dhpublicnumber")) {
+    p = Curl_getASN1Element(&elem, param->beg, param->end);
+    do_pubkey_field(data, certnum, "dh(p)", &elem);
+    Curl_getASN1Element(&elem, param->beg, param->end);
+    do_pubkey_field(data, certnum, "dh(g)", &elem);
+    do_pubkey_field(data, certnum, "dh(pub_key)", &pk);
+  }
+#if 0 /* Patent-encumbered. */
+  else if(curl_strequal(algo, "ecPublicKey")) {
+    /* Left TODO. */
+  }
+#endif
+}
+
+CURLcode Curl_extract_certinfo(struct connectdata * conn,
+                               int certnum,
+                               const char * beg,
+                               const char * end)
+{
+  curl_X509certificate cert;
+  struct SessionHandle * data = conn->data;
+  curl_asn1Element param;
+  const char * ccp;
+  char * cp1;
+  size_t cl1;
+  char * cp2;
+  CURLcode result;
+  unsigned long version;
+  size_t i;
+  size_t j;
+
+  if(!data->set.ssl.certinfo)
+    if(certnum)
+      return CURLE_OK;
+
+  /* Prepare the certificate information for curl_easy_getinfo(). */
+
+  /* Extract the certificate ASN.1 elements. */
+  Curl_parseX509(&cert, beg, end);
+
+  /* Subject. */
+  ccp = Curl_DNtostr(&cert.subject);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Subject", ccp);
+  if(!certnum)
+    infof(data, "%2d Subject: %s\n", certnum, ccp);
+  free((char *) ccp);
+
+  /* Issuer. */
+  ccp = Curl_DNtostr(&cert.issuer);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp);
+  if(!certnum)
+    infof(data, "   Issuer: %s\n", ccp);
+  free((char *) ccp);
+
+  /* Version (always fits in less than 32 bits). */
+  version = 0;
+  for(ccp = cert.version.beg; ccp < cert.version.end; ccp++)
+    version = (version << 8) | *(const unsigned char *) ccp;
+  if(data->set.ssl.certinfo) {
+    ccp = curl_maprintf("%lx", version);
+    if(!ccp)
+      return CURLE_OUT_OF_MEMORY;
+    Curl_ssl_push_certinfo(data, certnum, "Version", ccp);
+    free((char *) ccp);
+  }
+  if(!certnum)
+    infof(data, "   Version: %lu (0x%lx)\n", version + 1, version);
+
+  /* Serial number. */
+  ccp = Curl_ASN1tostr(&cert.serialNumber, 0);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp);
+  if(!certnum)
+    infof(data, "   Serial Number: %s\n", ccp);
+  free((char *) ccp);
+
+  /* Signature algorithm .*/
+  ccp = dumpAlgo(&param, cert.signatureAlgorithm.beg,
+                 cert.signatureAlgorithm.end);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp);
+  if(!certnum)
+    infof(data, "   Signature Algorithm: %s\n", ccp);
+  free((char *) ccp);
+
+  /* Start Date. */
+  ccp = Curl_ASN1tostr(&cert.notBefore, 0);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp);
+  if(!certnum)
+    infof(data, "   Start Date: %s\n", ccp);
+  free((char *) ccp);
+
+  /* Expire Date. */
+  ccp = Curl_ASN1tostr(&cert.notAfter, 0);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp);
+  if(!certnum)
+    infof(data, "   Expire Date: %s\n", ccp);
+  free((char *) ccp);
+
+  /* Public Key Algorithm. */
+  ccp = dumpAlgo(&param, cert.subjectPublicKeyAlgorithm.beg,
+                 cert.subjectPublicKeyAlgorithm.end);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp);
+  if(!certnum)
+    infof(data, "   Public Key Algorithm: %s\n", ccp);
+  do_pubkey(data, certnum, ccp, &param, &cert.subjectPublicKey);
+  free((char *) ccp);
+
+/* TODO: extensions. */
+
+  /* Signature. */
+  ccp = Curl_ASN1tostr(&cert.signature, 0);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Signature", ccp);
+  if(!certnum)
+    infof(data, "   Signature: %s\n", ccp);
+  free((char *) ccp);
+
+  /* Generate PEM certificate. */
+  result = Curl_base64_encode(data, cert.certificate.beg,
+                              cert.certificate.end - cert.certificate.beg,
+                              &cp1, &cl1);
+  if(result)
+    return result;
+  /* Compute the number of characters in final certificate string. Format is:
+     -----BEGIN CERTIFICATE-----\n
+     <max 64 base64 characters>\n
+     .
+     .
+     .
+     -----END CERTIFICATE-----\n
+   */
+  i = 28 + cl1 + (cl1 + 64 - 1) / 64 + 26;
+  cp2 = malloc(i + 1);
+  if(!cp2) {
+    free(cp1);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  /* Build the certificate string. */
+  i = copySubstring(cp2, "-----BEGIN CERTIFICATE-----");
+  for(j = 0; j < cl1; j += 64)
+    i += copySubstring(cp2 + i, cp1 + j);
+  i += copySubstring(cp2 + i, "-----END CERTIFICATE-----");
+  cp2[i] = '\0';
+  free(cp1);
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Cert", cp2);
+  if(!certnum)
+    infof(data, "%s\n", cp2);
+  free(cp2);
+  return CURLE_OK;
+}
+
+#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL */
+
+#if defined(USE_GSKIT)
+
+static const char * checkOID(const char * beg, const char * end,
+                             const char * oid)
+{
+  curl_asn1Element e;
+  const char * ccp;
+  const char * p;
+  bool matched;
+
+  /* Check if first ASN.1 element at `beg' is the given OID.
+     Return a pointer in the source after the OID if found, else NULL. */
+
+  ccp = Curl_getASN1Element(&e, beg, end);
+  if(!ccp || e.tag != CURL_ASN1_OBJECT_IDENTIFIER)
+    return (const char *) NULL;
+
+  p = OID2str(e.beg, e.end, FALSE);
+  if(!p)
+    return (const char *) NULL;
+
+  matched = !strcmp(p, oid);
+  free((char *) p);
+  return matched? ccp: (const char *) NULL;
+}
+
+CURLcode Curl_verifyhost(struct connectdata * conn,
+                         const char * beg, const char * end)
+{
+  struct SessionHandle * data = conn->data;
+  curl_X509certificate cert;
+  curl_asn1Element dn;
+  curl_asn1Element elem;
+  curl_asn1Element ext;
+  curl_asn1Element name;
+  const char * p;
+  const char * q;
+  char * dnsname;
+  int matched = -1;
+  size_t addrlen = (size_t) -1;
+  ssize_t len;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif
+
+  /* Verify that connection server matches info in X509 certificate at
+     `beg'..`end'. */
+
+  if(!data->set.ssl.verifyhost)
+    return CURLE_OK;
+
+  if(!beg)
+    return CURLE_PEER_FAILED_VERIFICATION;
+  Curl_parseX509(&cert, beg, end);
+
+  /* Get the server IP address. */
+#ifdef ENABLE_IPV6
+  if(conn->bits.ipv6_ip && Curl_inet_pton(AF_INET6, conn->host.name, &addr))
+    addrlen = sizeof(struct in6_addr);
+  else
+#endif
+  if(Curl_inet_pton(AF_INET, conn->host.name, &addr))
+    addrlen = sizeof(struct in_addr);
+
+  /* Process extensions. */
+  for(p = cert.extensions.beg; p < cert.extensions.end && matched != 1;) {
+    p = Curl_getASN1Element(&ext, p, cert.extensions.end);
+    /* Check if extension is a subjectAlternativeName. */
+    ext.beg = checkOID(ext.beg, ext.end, sanOID);
+    if(ext.beg) {
+      ext.beg = Curl_getASN1Element(&elem, ext.beg, ext.end);
+      /* Skip critical if present. */
+      if(elem.tag == CURL_ASN1_BOOLEAN)
+        ext.beg = Curl_getASN1Element(&elem, ext.beg, ext.end);
+      /* Parse the octet string contents: is a single sequence. */
+      Curl_getASN1Element(&elem, elem.beg, elem.end);
+      /* Check all GeneralNames. */
+      for(q = elem.beg; matched != 1 && q < elem.end;) {
+        q = Curl_getASN1Element(&name, q, elem.end);
+        switch (name.tag) {
+        case 2: /* DNS name. */
+          len = utf8asn1str(&dnsname, CURL_ASN1_IA5_STRING,
+                            name.beg, name.end);
+          if(len > 0 && (size_t)len == strlen(dnsname))
+            matched = Curl_cert_hostcheck(dnsname, conn->host.name);
+          else
+            matched = 0;
+          free(dnsname);
+          break;
+
+        case 7: /* IP address. */
+          matched = (size_t) (name.end - q) == addrlen &&
+                    !memcmp(&addr, q, addrlen);
+          break;
+        }
+      }
+    }
+  }
+
+  switch (matched) {
+  case 1:
+    /* an alternative name matched the server hostname */
+    infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname);
+    return CURLE_OK;
+  case 0:
+    /* an alternative name field existed, but didn't match and then
+       we MUST fail */
+    infof(data, "\t subjectAltName does not match %s\n", conn->host.dispname);
+    return CURLE_PEER_FAILED_VERIFICATION;
+  }
+
+  /* Process subject. */
+  name.header = NULL;
+  name.beg = name.end = "";
+  q = cert.subject.beg;
+  /* we have to look to the last occurrence of a commonName in the
+     distinguished one to get the most significant one. */
+  while(q < cert.subject.end) {
+    q = Curl_getASN1Element(&dn, q, cert.subject.end);
+    for(p = dn.beg; p < dn.end;) {
+      p = Curl_getASN1Element(&elem, p, dn.end);
+      /* We have a DN's AttributeTypeAndValue: check it in case it's a CN. */
+      elem.beg = checkOID(elem.beg, elem.end, cnOID);
+      if(elem.beg)
+        name = elem;    /* Latch CN. */
+    }
+  }
+
+  /* Check the CN if found. */
+  if(!Curl_getASN1Element(&elem, name.beg, name.end))
+    failf(data, "SSL: unable to obtain common name from peer certificate");
+  else {
+    len = utf8asn1str(&dnsname, elem.tag, elem.beg, elem.end);
+    if(len < 0) {
+      free(dnsname);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    if(strlen(dnsname) != (size_t) len)         /* Nul byte in string ? */
+      failf(data, "SSL: illegal cert name field");
+    else if(Curl_cert_hostcheck((const char *) dnsname, conn->host.name)) {
+      infof(data, "\t common name: %s (matched)\n", dnsname);
+      free(dnsname);
+      return CURLE_OK;
+    }
+    else
+      failf(data, "SSL: certificate subject name '%s' does not match "
+            "target host name '%s'", dnsname, conn->host.dispname);
+    free(dnsname);
+  }
+
+  return CURLE_PEER_FAILED_VERIFICATION;
+}
+
+#endif /* USE_GSKIT */
Index: UsbWattMeter/trunk/curl-7.47.1/lib/x509asn1.h
===================================================================
--- UsbWattMeter/trunk/curl-7.47.1/lib/x509asn1.h	(revision 164)
+++ UsbWattMeter/trunk/curl-7.47.1/lib/x509asn1.h	(revision 164)
@@ -0,0 +1,132 @@
+#ifndef HEADER_CURL_X509ASN1_H
+#define HEADER_CURL_X509ASN1_H
+
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
+    defined(USE_CYASSL)
+
+#include "urldata.h"
+
+/*
+ * Constants.
+ */
+
+/* ASN.1 classes. */
+#define CURL_ASN1_UNIVERSAL             0
+#define CURL_ASN1_APPLICATION           1
+#define CURL_ASN1_CONTEXT_SPECIFIC      2
+#define CURL_ASN1_PRIVATE               3
+
+/* ASN.1 types. */
+#define CURL_ASN1_BOOLEAN               1
+#define CURL_ASN1_INTEGER               2
+#define CURL_ASN1_BIT_STRING            3
+#define CURL_ASN1_OCTET_STRING          4
+#define CURL_ASN1_NULL                  5
+#define CURL_ASN1_OBJECT_IDENTIFIER     6
+#define CURL_ASN1_OBJECT_DESCRIPTOR     7
+#define CURL_ASN1_INSTANCE_OF           8
+#define CURL_ASN1_REAL                  9
+#define CURL_ASN1_ENUMERATED            10
+#define CURL_ASN1_EMBEDDED              11
+#define CURL_ASN1_UTF8_STRING           12
+#define CURL_ASN1_RELATIVE_OID          13
+#define CURL_ASN1_SEQUENCE              16
+#define CURL_ASN1_SET                   17
+#define CURL_ASN1_NUMERIC_STRING        18
+#define CURL_ASN1_PRINTABLE_STRING      19
+#define CURL_ASN1_TELETEX_STRING        20
+#define CURL_ASN1_VIDEOTEX_STRING       21
+#define CURL_ASN1_IA5_STRING            22
+#define CURL_ASN1_UTC_TIME              23
+#define CURL_ASN1_GENERALIZED_TIME      24
+#define CURL_ASN1_GRAPHIC_STRING        25
+#define CURL_ASN1_VISIBLE_STRING        26
+#define CURL_ASN1_GENERAL_STRING        27
+#define CURL_ASN1_UNIVERSAL_STRING      28
+#define CURL_ASN1_CHARACTER_STRING      29
+#define CURL_ASN1_BMP_STRING            30
+
+
+/*
+ * Types.
+ */
+
+/* ASN.1 parsed element. */
+typedef struct {
+  const char *  header;         /* Pointer to header byte. */
+  const char *  beg;            /* Pointer to element data. */
+  const char *  end;            /* Pointer to 1st byte after element. */
+  unsigned char class;          /* ASN.1 element class. */
+  unsigned char tag;            /* ASN.1 element tag. */
+  bool          constructed;    /* Element is constructed. */
+}  curl_asn1Element;
+
+
+/* ASN.1 OID table entry. */
+typedef struct {
+  const char *  numoid;         /* Dotted-numeric OID. */
+  const char *  textoid;        /* OID name. */
+}  curl_OID;
+
+
+/* X509 certificate: RFC 5280. */
+typedef struct {
+  curl_asn1Element      certificate;
+  curl_asn1Element      version;
+  curl_asn1Element      serialNumber;
+  curl_asn1Element      signatureAlgorithm;
+  curl_asn1Element      signature;
+  curl_asn1Element      issuer;
+  curl_asn1Element      notBefore;
+  curl_asn1Element      notAfter;
+  curl_asn1Element      subject;
+  curl_asn1Element      subjectPublicKeyInfo;
+  curl_asn1Element      subjectPublicKeyAlgorithm;
+  curl_asn1Element      subjectPublicKey;
+  curl_asn1Element      issuerUniqueID;
+  curl_asn1Element      subjectUniqueID;
+  curl_asn1Element      extensions;
+}  curl_X509certificate;
+
+
+/*
+ * Prototypes.
+ */
+
+const char * Curl_getASN1Element(curl_asn1Element * elem,
+                                 const char * beg, const char * end);
+const char * Curl_ASN1tostr(curl_asn1Element * elem, int type);
+const char * Curl_DNtostr(curl_asn1Element * dn);
+void Curl_parseX509(curl_X509certificate * cert,
+                    const char * beg, const char * end);
+CURLcode Curl_extract_certinfo(struct connectdata * conn, int certnum,
+                               const char * beg, const char * end);
+CURLcode Curl_verifyhost(struct connectdata * conn,
+                         const char * beg, const char * end);
+
+#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL */
+#endif /* HEADER_CURL_X509ASN1_H */
Index: UsbWattMeter/trunk/ecnl_lwip/MANIFEST
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/MANIFEST	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/MANIFEST	(revision 164)
@@ -0,0 +1,26 @@
+PACKAGE ecnl
+
+MANIFEST
+echonet.c
+echonet.h
+echonet.tf
+echonet_api.csv
+echonet_asp.cfg
+echonet_chk.tf
+echonet_class.h
+echonet_dbg.c
+echonet_dbg.cfg
+echonet_dbg.h
+echonet_def.csv
+echonet_fbs.c
+echonet_fbs.h
+echonet_lcl_task.h
+echonet_rename.h
+echonet_task.c
+echonet_task.h
+echonet_udp.cfg
+echonet_udp6_task.c
+echonet_udp6_task.h
+echonet_udp_task.c
+echonet_udp_task.h
+../doc/ecnl_manual.pdf
Index: UsbWattMeter/trunk/ecnl_lwip/echonet.c
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet.c	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet.c	(revision 164)
@@ -0,0 +1,706 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+#include <kernel.h>
+#include <stdio.h>
+#include <string.h>
+#include <t_stdlib.h>
+
+#include "echonet.h"
+#include "echonet_fbs.h"
+#include "echonet_task.h"
+#include "echonet_dbg.h"
+#include "echonet_agent.h"
+
+/*
+ * ECHONET LiteT[rXJn
+ */
+ER ecn_sta_svc()
+{
+	return act_tsk(ecn_udp_taskid);
+}
+
+/*
+ * ECHONETIuWFNgQÆ
+ * ø
+ * ID		fa_eobjid	ECHONETIuWFNgID
+ * T_REOBJ	*fp_eobj	ECHONETIuWFNgÌÝèàeRs[æ
+ *
+ * eobjidÅwèµ½ECHONETIuWFNgÌÝèàeðQÆ·éB
+ * QÆµ½ÝèàeÍpk_eobjÉwèµ½ÉÔ³êéB
+ */
+ER ecn_ref_eobj(ID fa_eobjid, T_REOBJ *fp_eobj)
+{
+	const EOBJINIB	*p_obj;
+
+	if (!fp_eobj)
+		return E_PAR;	/* p[^G[ */
+
+	if ((fa_eobjid <= 0) || (fa_eobjid > tmax_eobjid))
+		return E_OBJ;	/* IuWFNg¢o^ */
+
+	p_obj = &eobjinib_table[fa_eobjid - 1];
+
+	*fp_eobj = *p_obj;
+
+	return E_OK;
+}
+
+/*
+ * ECHONETvpeBQÆ
+ * ø
+ * ID			fa_eobjid	ECHONETIuWFNgID
+ * uint8_t		fa_epc		vpeBR[h
+ * T_RPRP		*fp_eprp	ECHONETIuWFNgÌvpeBÝèàeRs[æ
+ *
+ * eobjidÅwèµ½ECHONETIuWFNgÌAepcÅwèµ½vpeBÌÝèàeðQÆ·éB
+ * QÆµ½ÝèàeÍpk_eprpÉwèµ½ÉÔ³êéB
+ */
+ER ecn_ref_eprp(ID fa_eobjid, uint8_t fa_epc, T_RPRP *fp_eprp)
+{
+	const EOBJINIB	*p_obj;
+	const EPRPINIB	*p;
+	uint_t			i;
+
+	if (!fp_eprp)
+		return E_PAR;	/* p[^G[ */
+
+	if ((fa_eobjid <= 0) || (fa_eobjid > tmax_eobjid))
+		return E_OBJ;	/* IuWFNg¢o^ */
+
+	p_obj = &eobjinib_table[fa_eobjid - 1];
+
+	/* eojÌÂvpeBú»è`zñ©çõ */
+	p = p_obj->eprp;
+	for (i = 0; i < p_obj->eprpcnt; i++, p++) {
+		if (p->eprpcd != fa_epc)
+			continue;
+		*fp_eprp = *p;
+		return E_OK;
+	}
+
+	return E_PAR;	/* p[^G[ */
+}
+
+/*
+ * vpeBl«Ývisvjd¶ì¬
+ * ø
+ * T_EDATA			**ppk_esv	æ¾µ½d¶Ìi[æ
+ * ID				fa_deoj		¶æÌECHONETIuWFNgID
+ * uint8_t			fa_epc		vpeBR[h
+ * uint8_t			fa_pdc		vpeBlf[^TCY
+ * const void		*p_edt		vpeBlf[^
+ *
+ *	vpeBl«Ývisvjd¶ðì¬·éB
+ *	d¶ÍdeojÅwèµ½ECHONETIuWFNgð¶æÆµA
+ *	d¶ÌßÌvpeBlÆµÄAepcÆpdcAp_edtÅwè³ê½
+ *	vpeBR[hAf[^TCYAf[^ðd¶ÉÝè·éB
+ *	ì¬µ½d¶ÌæªAhXÍ|C^oRÅÔ³êéB
+ */
+ER ecn_esv_seti(T_EDATA **ppk_esv, ID fa_deoj, uint8_t fa_epc, uint8_t fa_pdc,
+	const void *p_edt)
+{
+	return _ecn_tsk_mk_esv((ECN_FBS_ID *)ppk_esv, (ID)1, fa_deoj, fa_epc, fa_pdc, p_edt, ESV_SET_I);
+}
+
+/*
+ * vpeBl«Ývivjd¶ì¬
+ * ø
+ * T_EDATA			**ppk_esv	æ¾µ½d¶Ìi[æ
+ * ID				fa_deoj		¶æÌECHONETIuWFNgID
+ * uint8_t			fa_epc		vpeBR[h
+ * uint8_t			fa_pdc		vpeBlf[^TCY
+ * const void		*p_edt		vpeBlf[^
+ *
+ *	vpeBl«Ývivjd¶ðì¬·éB
+ *	d¶ÍdeojÅwèµ½ECHONETIuWFNgð¶æÆµA
+ *	d¶ÌßÌvpeBlÆµÄAepcÆpdcAp_edtÅwè³ê½
+ *	vpeBR[hAf[^TCYAf[^ðd¶ÉÝè·éB
+ *	ì¬µ½d¶ÌæªAhXÍ|C^oRÅÔ³êéB
+ */
+ER ecn_esv_setc(T_EDATA **ppk_esv, ID fa_deoj, uint8_t fa_epc, uint8_t fa_pdc,
+	const void *p_edt)
+{
+	return _ecn_tsk_mk_esv((ECN_FBS_ID *)ppk_esv, (ID)1, fa_deoj, fa_epc, fa_pdc, p_edt, ESV_SET_C);
+}
+
+/*
+ * vpeBlÇÝoµvd¶ì¬
+ * ø
+ * T_EDATA			**ppk_esv	æ¾µ½d¶Ìi[æ
+ * ID				fa_deoj		¶æÌECHONETIuWFNgID
+ * uint8_t			fa_epc		vpeBR[h
+ *
+ * vpeBlÇÝoµvd¶ðì¬·éB
+ * d¶ÍdeojÅwèµ½ECHONETIuWFNgð¶æÆµA
+ * d¶ÌßÌvpeBlÆµÄAepcÅwè³ê½
+ * vpeBR[hðd¶ÉÝè·éB
+ * ì¬µ½d¶ÌæªAhXÍ|C^oRÅÔ³êéB
+ */
+ER ecn_esv_get(T_EDATA **ppk_esv, ID fa_deoj, uint8_t fa_epc)
+{
+	return _ecn_tsk_mk_esv((ECN_FBS_ID *)ppk_esv, (ID)1, fa_deoj, fa_epc, 0, NULL, ESV_GET);
+}
+
+/*
+ * vpeBlÊmvd¶ì¬
+ * ø
+ * T_EDATA			**ppk_esv	æ¾µ½d¶Ìi[æ
+ * ID				fa_deoj		¶æÌECHONETIuWFNgID
+ * uint8_t			fa_epc		vpeBR[h
+ *
+ * vpeBlÊmvd¶ðì¬·éB
+ * d¶ÍdeojÅwèµ½ECHONETIuWFNgð¶æÆµA
+ * d¶ÌßÌvpeBlÆµÄAepcÅwè³ê½
+ * vpeBR[hðd¶ÉÝè·éB
+ * ì¬µ½d¶ÌæªAhXÍ|C^oRÅÔ³êéB
+ */
+ER ecn_esv_inf_req(T_EDATA **ppk_esv, ID fa_deoj, uint8_t fa_epc)
+{
+	return _ecn_tsk_mk_esv((ECN_FBS_ID *)ppk_esv, (ID)1, fa_deoj, fa_epc, 0, NULL, ESV_INF_REQ);
+}
+
+/*
+ * vpeBl«ÝEÇÝoµvd¶ì¬
+ * ø
+ * T_EDATA			**ppk_esv	æ¾µ½d¶Ìi[æ
+ * ID				fa_deoj		¶æÌECHONETIuWFNgID
+ * uint8_t			fa_epc		vpeBR[h
+ * uint8_t			fa_pdc		vpeBlf[^TCY
+ * const void		*p_edt		vpeBlf[^
+ *
+ * vpeBl«ÝEÇÝoµvd¶ðì¬·éB
+ * d¶ÍdeojÅwèµ½ECHONETIuWFNgð¶æÆµA
+ * d¶ÌßÌvpeBlÆµÄAepcÆpdcAp_edtÅwè³ê½
+ * vpeBR[hAf[^TCYAf[^ðd¶ÉÝè·éB
+ * ì¬µ½d¶ÌæªAhXÍ|C^oRÅÔ³êéB
+ */
+ER ecn_esv_set_get(T_EDATA **ppk_esv, ID fa_deoj, uint8_t fa_epc, uint8_t fa_pdc,
+	const void *p_edt)
+{
+	return _ecn_tsk_mk_esv((ECN_FBS_ID *)ppk_esv, (ID)1, fa_deoj, fa_epc, fa_pdc, p_edt, ESV_SET_GET);
+}
+
+/*
+ * vpeBl«ÝEÇÝoµvd¶ì¬FÜèÔµwè
+ * vpeBl«ÝEÇÝoµvd¶ì¬ÌA«ÝvpeBzñðI¦Ä
+ * ÇÝoµvpeBzñÉÚéÉp¢éB
+ */
+ER ecn_trn_set_get(T_EDATA *ppk_esv, int *p_trn_pos)
+{
+	ER	a_ret;
+
+	if (!ppk_esv)
+		return E_PAR;
+	if (!p_trn_pos)
+		return E_PAR;
+
+	/* vpeBÇÝÝ«ÝÌwbhîñðL^ */
+	*p_trn_pos = _ecn_fbs_get_datalen(*(ECN_FBS_ID *)&ppk_esv);
+
+	/* d¶pÉf[^ÇÁE±Ì_ÅÌd¶vpeBðL^ */
+	a_ret = _ecn_fbs_add_data_ex(*(ECN_FBS_ID *)&ppk_esv, &ppk_esv->hdr.edata.opc, 1);
+	if (a_ret) {
+		ECN_DBG_PUT( "ecn_trn_set_get(): _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) );
+		return a_ret;
+	}
+
+	/* d¶vpeBð 0 Éß·i¡ãAI¹wè·éÜÅÍÇÝoµvpeBÉÈéj */
+	ppk_esv->hdr.edata.opc = 0;
+
+	return E_OK;
+}
+
+/*
+ * vpeBl«ÝEÇÝoµvd¶ì¬FI¹wè
+ * vpeBl«ÝEÇÝoµvd¶ì¬ÌAÇÝoµvpeBzñðI¦éÉp¢éB
+ */
+ER ecn_end_set_get(T_EDATA *ppk_esv, int fa_trn_pos)
+{
+	ER		a_ret;
+	int		a_wr_opc;
+	uint8_t	a_rd_opc;
+
+	if (!ppk_esv)
+		return E_PAR;
+
+	/* ±Ì_ÅÌd¶vpeB(ÇÝoµvpeB)ðÛ */
+	a_rd_opc = ppk_esv->hdr.edata.opc;
+
+	/* d¶vpeB(«ÝvpeB)ðÛ¶Êu©çÇÝæè */
+	a_wr_opc = _ecn_fbs_peek(*(ECN_FBS_ID *)&ppk_esv, fa_trn_pos);
+	if (a_wr_opc < 0) {
+		ECN_DBG_PUT( "ecn_end_set_get(): _ecn_fbs_peek() result = %d:%s", a_wr_opc, itron_strerror(a_wr_opc) );
+		return a_wr_opc;
+	}
+
+	/* d¶vpeB(«ÝvpeB)ð³ */
+	ppk_esv->hdr.edata.opc = (uint8_t)a_wr_opc;
+
+	/* d¶vpeB(ÇÝoµvpeB)ðÛ¶ÊuÉ«Ý */
+	a_ret = _ecn_fbs_poke(*(ECN_FBS_ID *)&ppk_esv, fa_trn_pos, a_rd_opc);
+	if (a_ret) {
+		ECN_DBG_PUT( "ecn_end_set_get(): _ecn_fbs_poke() result = %d:%s", a_ret, itron_strerror(a_ret) );
+		return a_ret;
+	}
+
+	return E_OK;
+}
+
+/*
+ * vpeBlÊmivjd¶ì¬
+ * ø
+ * T_EDATA			**ppk_esv	æ¾µ½d¶Ìi[æ
+ * ID				fa_deoj		¶æÌECHONETIuWFNgID
+ * ID				fa_seoj		M³ÌECHONETIuWFNgID
+ * uint8_t			fa_sepc		M³ÌvpeBR[h
+ */
+ER ecn_esv_infc(T_EDATA **ppk_esv, ID fa_deoj, ID fa_seoj, uint8_t fa_sepc)
+{
+	return _ecn_tsk_mk_esv((ECN_FBS_ID *)ppk_esv, fa_seoj, fa_deoj, fa_sepc, 0, NULL, ESV_INFC);
+}
+
+/*
+ * vd¶ÖÌvpeBwèÇÁ (vpeBf[^ªtµÈ¢êÉp¢é)
+ */
+ER ecn_add_epc(T_EDATA *pk_esv, uint8_t epc)
+{
+	return ecn_add_edt(pk_esv, epc, 0, 0);
+}
+
+/*
+ * vd¶ÖÌvpeBf[^ÇÁ (vpeB¨æÑtf[^ðÇÁ·é)
+ */
+ER ecn_add_edt(T_EDATA *pk_esv, uint8_t fa_epc, uint8_t fa_pdc, const void *p_edt)
+{
+	ECN_FBS_ID	a_fbs_id;
+	ER			a_ret;
+	T_ECN_PRP	a_ecn_prp;
+
+	if (!pk_esv)
+		return E_PAR; /* æ¾µ½FBS_IDÌi[æªNULL */
+	if (ECHONET_MEMPOOL_BLOCK_SIZE <= fa_pdc)
+		return E_PAR; /* vpeBlTCYªå«·¬é */
+	if (!p_edt && 0 < fa_pdc)
+		return E_PAR; /* vpeBlTCYª1ÈãÈÌÉf[^|C^ªNULL */
+
+	a_fbs_id.ptr = (T_ECN_FST_BLK *)pk_esv;
+	if (((T_EDATA *)a_fbs_id.ptr)->hdr.edata.opc == 0xFF)
+		return E_PAR; /* vpeBª½·¬é */
+
+	/* vd¶pÉf[^ÇÁ */
+	memset(&a_ecn_prp, 0, sizeof(a_ecn_prp));
+	a_ecn_prp.epc = fa_epc;
+	a_ecn_prp.pdc = fa_pdc;
+	a_ret = _ecn_fbs_add_data_ex(a_fbs_id, &a_ecn_prp, sizeof(a_ecn_prp));
+	if (a_ret) {
+		ECN_DBG_PUT( "ecn_add_edt(): _ecn_fbs_add_data_ex(*, ecn_prp{epc:0x%02X}, %u) result = %d:%s",
+			a_ecn_prp.epc, sizeof(a_ecn_prp),
+			a_ret, itron_strerror(a_ret) );
+		goto lb_except;
+	}
+	if (0 < fa_pdc) {
+		/* tf[^ÇÁ */
+		a_ret = _ecn_fbs_add_data_ex(a_fbs_id, p_edt, fa_pdc);
+		if (a_ret) {
+			ECN_DBG_PUT( "ecn_add_edt(): _ecn_fbs_add_data_ex(*, ecn_prp{epc:0x%02X} edt, %u) result = %d:%s",
+				a_ecn_prp.epc, fa_pdc,
+				a_ret, itron_strerror(a_ret) );
+			goto lb_except;
+		}
+	}
+	/* vpeBCNg */
+	((T_EDATA *)a_fbs_id.ptr)->hdr.edata.opc++;
+
+lb_except:
+	return a_ret;
+}
+
+/*
+ * vd¶ÌM
+ * esvÅwè³ê½vd¶ðM·éB
+ * d¶Éwè³ê½¶æ©çIPAhXðÁèµAUDPpPbgÆµÄM·éB
+ */
+ER ecn_snd_esv(T_EDATA *pk_esv)
+{
+	ECN_FBS_ID a_rsp_fbs;
+	a_rsp_fbs.ptr = (T_ECN_FST_BLK *)pk_esv;
+	return _ecn_tsk_snd_mbx(a_rsp_fbs, true);
+}
+
+/*
+ * d¶ÌóMiÒ¿
+ * d¶ðóM·éÌðÒÂB
+ * óMµ½d¶Íppk_esvÅwèµ½|C^[ÉæªAhXªÔ³êéB
+ * vd¶Ì¶æÌECHONETIuWFNgªlbg[NÉ¶ÝµÈ¢êA
+ * d¶ÍÔ³êÈ¢ÌÅAiÉÒÂ±ÆÉÈéÌÅ^CAEgt«Ì
+ * ecn_trcv_esvðgp·é±Æð§·éB
+ */
+ER ecn_rcv_esv(T_EDATA **ppk_esv)
+{
+	return ecn_trcv_esv(ppk_esv, TMO_FEVR);
+}
+
+/*
+ * d¶ÌóMÒ¿^CAEg è
+ * d¶ðóM·éÌðÒÂB
+ * óMµ½d¶Íppk_esvÅwèµ½|C^[ÉæªAhXªÔ³êéB
+ * tmoÅwè³ê½^CAEgÔªoßµÄàd¶ðóMµÈ¢êA
+ * Ò¿ªð³êAßèlªE_TMOÅÔ³êéB
+ * tmoÉTMO_FEVRðwè·éÆecn_rcv_esvÆ¯¶Ué¢ð·éB
+ * tmoÉ0ðwè·éÆecn_prcv_esvÆ¯¶Ué¢ð·éB
+ */
+ER ecn_trcv_esv(T_EDATA **ppk_esv, TMO fa_tmout)
+{
+	T_MSG	*p_msg = 0;
+	ER		a_ret;
+
+	if (!ppk_esv)
+		return E_PAR;
+
+	a_ret = trcv_mbx(ecn_api_mailboxid, &p_msg, fa_tmout);
+	if (a_ret != E_OK) {
+		*ppk_esv = NULL;
+		return a_ret;
+	}
+
+	*ppk_esv = (T_EDATA *)p_msg;
+	return (((T_ECN_FST_BLK *)p_msg)->hdr.type == ECN_MSG_ECHONET) ? E_OK : E_WBLK;
+}
+
+/*
+ * d¶ÌóM|[O
+ * d¶ðóM·éÌðÒÂB
+ * óMµ½d¶Íppk_esvÅwèµ½|C^[ÉæªAhXªÔ³êéB
+ * d¶ÌóMÌL³É©©íç¸AÒ½¸ÉÖð²¯éB
+ */
+ER ecn_prcv_esv(T_EDATA **ppk_esv)
+{
+	return ecn_trcv_esv(ppk_esv, TMO_POL);
+}
+
+/*
+ * d¶Ìjü
+ */
+ER ecn_rel_esv(T_EDATA *pk_esv)
+{
+	ECN_FBS_ID	a_fbs;
+	ER			a_ret;
+
+	a_fbs.ptr = (T_ECN_FST_BLK *)pk_esv;
+	a_ret = _ecn_fbs_del(a_fbs);
+	return a_ret;
+}
+
+/*
+ * d¶ÌM³@íIuWFNgðæ¾·é
+ */
+ID ecn_get_eobj(T_EDATA *pk_esv)
+{
+	const EOBJCB	*p_snod;
+	const EOBJINIB	*p_sobj = NULL;
+	T_ECN_EDT_HDR	*p_esv;
+
+	p_esv = &pk_esv->hdr;
+	p_snod = _ecn_eno_fnd(((T_ECN_FST_BLK *)pk_esv)->hdr.sender.id);
+	if (p_snod != NULL) {
+		/* m[hvt@CÌê */
+		if ((p_esv->edata.seoj.eojx1 == EOJ_X1_PROFILE)
+			&& (p_esv->edata.seoj.eojx2 == EOJ_X2_NODE_PROFILE)) {
+			p_sobj = p_snod->profile;
+		}
+		/* @íIuWFNgÌê */
+		else {
+			p_sobj = _ecn_eoj_fnd(p_snod, &p_esv->edata.seoj);
+		}
+	}
+
+	if (p_sobj == NULL)
+		return EOBJ_NULL;
+#ifdef ECHONET_CONTROLLER_EXTENTION
+	if (p_sobj->eprpcnt == 0)
+		return ecn_agent_get_eobj(p_sobj);
+#endif
+	return 1 + (((intptr_t)p_sobj - (intptr_t)eobjinib_table) / sizeof(EOBJINIB));
+}
+
+/*
+ * d¶ðÍCe[^[ú»
+ */
+ER ecn_itr_ini(T_ENUM_EPC *pk_itr, T_EDATA *pk_esv)
+{
+	if (!pk_itr)
+		return E_PAR;
+	if (!pk_esv)
+		return E_PAR;
+
+	memset(pk_itr, 0, sizeof(*pk_itr));
+	pk_itr->pk_esv = pk_esv;
+	pk_itr->count = pk_esv->hdr.edata.opc;
+								/* ¡ÌubNÅÌvpeB */
+	pk_itr->got_ct = 0;			/* ¡ÌubNÅAÇÝæÁ½ */
+	pk_itr->next_blk_ct = 0;	/* ã±ubN */
+	pk_itr->is_eof = 0;			/* I[ÉBµ½Añ0 */
+	pk_itr->cur = offsetof(T_ECN_EDT_HDR, ecn_prp);
+
+	switch (pk_esv->hdr.edata.esv) {
+	case ESV_SET_GET:		/* 0x6E vpeBl«ÝEÇÝoµv		*/
+	case ESV_SET_GET_RES:	/* 0x7E vpeBl«ÝEÇÝoµ		*/
+	case ESV_SET_GET_SNA:	/* 0x5E	vpeBl«ÝEÇÝoµsÂ	*/
+		pk_itr->next_blk_ct ++;
+	default:
+		break;
+	}
+
+	return E_OK;
+}
+
+/*
+ * d¶ðÍCe[^[CNg
+ */
+ER ecn_itr_nxt(T_ENUM_EPC *pk_itr, uint8_t *p_epc, uint8_t *p_pdc, void *p_edt)
+{
+	ECN_FBS_ID		a_fbs_id;
+	int				a_rd_bak;
+	ER				a_ret;
+	ECN_FBS_SSIZE_T	a_rd_len;
+	T_ECN_PRP		a_ecn_prp;
+
+	if (!pk_itr)
+		return E_PAR;
+	if (!p_epc)
+		return E_PAR;
+	if (!p_pdc)
+		return E_PAR;
+	if (!p_edt)
+		return E_PAR;
+	if (!pk_itr->pk_esv)
+		return E_PAR;
+
+	if (pk_itr->is_eof)
+		return E_BOVR; /* f[^I¹ */
+	if (	pk_itr->count <= pk_itr->got_ct
+	&&	pk_itr->next_blk_ct < 1) {
+		pk_itr->is_eof = 1;			/* I[ÉBµ½Añ0 */
+		return E_BOVR; /* f[^I¹ */
+	}
+
+	a_fbs_id.ptr = (T_ECN_FST_BLK *)pk_itr->pk_esv;
+
+	/* ³ÌJ[\ÊuðÛ¶µACe[^ÌJ[\ÊuÉ·é */
+	a_rd_bak = a_fbs_id.ptr->hdr.rd;
+	a_fbs_id.ptr->hdr.rd = pk_itr->cur;
+
+#ifdef ECN_ENA_ITR_NXT_CARP
+	ECN_CAP_PUT( "ecn_itr_nxt() rd.cur=b%dp%d", pk_itr->cur.blk, pk_itr->cur.pos ECN_CAP_PUT(;
+#endif
+	if (pk_itr->count <= pk_itr->got_ct && 0 < pk_itr->next_blk_ct) {
+		/* ubNÉÚ® */
+		pk_itr->next_blk_ct --;
+		pk_itr->count = 0;		/* ¡ÌubNÅÌvpeB */
+		pk_itr->got_ct = 0;		/* ¡ÌubNÅAÇÝæÁ½ */
+
+		/* ubNÌvpeBðÇÝæé */
+		a_rd_len = 0;
+		a_ret = _ecn_fbs_get_data(a_fbs_id, &a_ecn_prp.pdc, 1, &a_rd_len);
+		if (a_ret != E_OK)
+			goto lb_except;
+		if (0 < a_rd_len) {
+			pk_itr->count = a_ecn_prp.pdc;	/* ¡ÌubNÅÌvpeB */
+		}
+		a_ret = E_BOVR;	/* f[^I¹ */
+		goto lb_finally;
+	}
+
+	/* vpeBR[hÆf[^TCYðÇÝæé */
+	memset(&a_ecn_prp, 0, sizeof(a_ecn_prp));
+	a_rd_len = 0;
+	a_ret = _ecn_fbs_get_data(a_fbs_id, &a_ecn_prp, sizeof(a_ecn_prp), &a_rd_len);
+	if (a_ret != E_OK)
+		goto lb_except;
+	if (a_rd_len < sizeof(a_ecn_prp)) {
+		ECN_DBG_PUT( "ecn_itr_nxt() ecn_prp read fault." 
+			" rd.cur=%d", pk_itr->cur );
+		pk_itr->is_eof = 1;			/* I[ÉBµ½Añ0 */
+		a_ret = E_BOVR;	/* f[^I¹ */
+		goto lb_finally;
+	}
+	*p_epc = a_ecn_prp.epc;
+	*p_pdc = a_ecn_prp.pdc;
+
+	if (0 < a_ecn_prp.pdc) {
+		/* tf[^ðÇÝæé */
+		a_rd_len = 0;
+		a_ret = _ecn_fbs_get_data(a_fbs_id, p_edt, a_ecn_prp.pdc, &a_rd_len);
+		if (a_ret != E_OK)
+			goto lb_except;
+		if (a_rd_len < (ECN_FBS_SSIZE_T)a_ecn_prp.pdc) {
+			ECN_DBG_PUT( "ecn_itr_nxt() edt read fault."
+				" rd.cur=%d,epc=0x%02X,pdc=%u", pk_itr->cur, a_ecn_prp.epc , a_ecn_prp.pdc );
+			pk_itr->is_eof = 1;			/* I[ÉBµ½Añ0 */
+			a_ret = E_BOVR;	/* f[^I¹ */
+			goto lb_finally;
+		}
+	}
+	pk_itr->got_ct++;
+
+#ifdef ECN_ENA_ITR_NXT_CARP
+	ECN_CAP_PUT( "ecn_itr_nxt() read: ct=%d/%d", pk_itr->got_ct, pk_itr->count ECN_CAP_PUT(;
+#endif
+
+lb_finally:
+	/* Ce[^ÌJ[\ÊuðXV */
+	pk_itr->cur = a_fbs_id.ptr->hdr.rd;
+
+lb_except:
+	/* ³ÌJ[\ÊuÉß· */
+	a_fbs_id.ptr->hdr.rd = a_rd_bak;
+	return a_ret;
+}
+
+/*
+ * d¶Ò¿ÌèÝM
+ */
+ER ecn_brk_wai(const void *p_dat, int fa_datsz)
+{
+	ER				a_ret;
+	ECN_FBS_ID		a_fbs_id = { 0 };	/* vd¶p	*/
+
+	/* d¶Ò¿ÌèÝd¶ì¬ */
+	a_ret = _ecn_mk_brk_wai(&a_fbs_id, p_dat, fa_datsz);
+	if (a_ret)
+		return a_ret;
+
+	/* èÝM */
+	a_ret = _ecn_tsk_snd_mbx(a_fbs_id, true);
+	if (a_ret) {
+		ECN_DBG_PUT( "_ecn_tsk_snd_mbx() result = %d:%s",
+			a_ret, itron_strerror(a_ret) );
+		goto lb_except;
+	}
+
+	/* ³íI¹ */
+	return a_ret;
+
+lb_except:
+	/* f[^ì¬¸sµ½çÌæðú */
+	if (a_fbs_id.ptr)
+		_ecn_fbs_del(a_fbs_id);
+
+	return a_ret;
+}
+
+/*
+ * èÝf[^Ìæ¾
+ */
+ER ecn_get_brk_dat(T_EDATA *pk_esv, void *p_buf, int fa_bufsz, int *p_datsz)
+{
+	ECN_FBS_ID	a_fbs;
+	ER			a_ret;
+	ECN_FBS_SSIZE_T		a_len;
+
+	if (p_datsz)
+		*p_datsz = 0;
+	if (!pk_esv)
+		return E_PAR;
+
+	a_fbs.ptr = (T_ECN_FST_BLK *)pk_esv;
+	if (a_fbs.ptr->hdr.type != ECN_MSG_USER_BREAK) {
+		ECN_DBG_PUT( "ecn_get_brk_dat: fbs-type:%d != ECN_MSG_USER_BREAK",
+			a_fbs.ptr->hdr.type );
+		return E_PAR;
+	}
+
+	/* ÇÝæèÊuðæªÉß· */
+	a_ret = _ecn_fbs_set_rpos(a_fbs, 0);
+	if (a_ret) {
+		ECN_DBG_PUT( "_ecn_fbs_set_rpos(*, 0) result = %d:%s",
+			a_ret, itron_strerror(a_ret) );
+		return a_ret;
+	}
+
+	/* tf[^ðÇÝÞ */
+	if (p_buf && 0 < fa_bufsz) {
+		a_len = 0;
+		a_ret = _ecn_fbs_get_data(a_fbs, p_buf, fa_bufsz, &a_len);
+		if (a_ret || !a_len) {
+			ECN_DBG_PUT( "_ecn_fbs_get_data(*, p_buf, fa_bufsz) result = %d:%s",
+				a_ret, itron_strerror(a_ret) );
+			return E_PAR;
+		}
+		*p_datsz = a_len;
+	}
+
+	return E_OK;
+}
+
+#ifndef ECN_USER_DATA_PROP_SET
+/*
+ * f[^ÝèÖ
+ */
+int ecn_data_prop_set(const EPRPINIB *item, const void *src, int size, bool_t *anno)
+{
+	if (size > item->eprpsz)
+		size = item->eprpsz;
+
+	if (*anno)
+		*anno = memcmp((uint8_t *)item->exinf, src, size) != 0;
+
+	memcpy((uint8_t *)item->exinf, src, size);
+
+	return size;
+}
+#endif
+
+#ifndef ECN_USER_DATA_PROP_GET
+/*
+ * f[^æ¾Ö
+ */
+int ecn_data_prop_get(const EPRPINIB *item, void *dst, int size)
+{
+	if (size > item->eprpsz)
+		size = item->eprpsz;
+
+	memcpy(dst, (uint8_t *)item->exinf, size);
+
+	return size;
+}
+#endif
Index: UsbWattMeter/trunk/ecnl_lwip/echonet.h
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet.h	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet.h	(revision 164)
@@ -0,0 +1,452 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef ECHONET_H
+#define ECHONET_H
+
+#include <t_stddef.h>
+#include <t_syslog.h>
+
+#include "echonet_rename.h"
+#include "echonet_class.h"
+#include "echonet_app_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define E_BRK		(-100)
+
+#define EOBJ_NULL 0x00
+#define EOBJ_LOCAL_NODE 0x01			/* ©m[h */
+#define EOBJ_SYNC_REMOTE_NODE 0x02		/* ¼m[h */
+#define EOBJ_ASYNC_REMOTE_NODE 0x04		/* ¼m[hiñ¯új */
+#define EOBJ_DEVICE 0x08				/* @íIuWFNg */
+
+#define EPC_NONE 0x00
+#define EPC_RULE_SET 0x01				/* ANZX[ Set */
+#define EPC_RULE_GET 0x02				/* ANZX[ Get */
+#define EPC_RULE_ANNO 0x04				/* ANZX[ Anno */
+#define EPC_ANNOUNCE 0x40				/* óÔÏ»Êm */
+#define EPC_VARIABLE 0x80				/* ÂÏ·f[^ */
+
+typedef enum _echonet_enod_id
+{
+	ENOD_NOT_MATCH_ID	= -1,
+	ENOD_MULTICAST_ID	= 0,			/* }`LXgAhXID */
+	ENOD_LOCAL_ID		= 1,			/* ©m[hAhXID */
+	ENOD_API_ID			= 2,			/* APIAhXID */
+	ENOD_REMOTE_ID		= 3,			/* ¼m[hAhXID */
+} ECN_ENOD_ID;
+
+/* ECHONET LiteKi */
+typedef enum
+{
+	ECN_EDH1_ECHONET_LITE	=	0x10
+} ECN_EHD1_ECL_VERSION;
+
+/* d¶`®1/2 */
+typedef enum
+{
+	ECN_EDH2_FORMAT_1 = 0x81,	/* d¶`®1 */
+	ECN_EDH2_FORMAT_2 = 0x82	/* d¶`®2 */
+} ECN_EHD2_FORMAT;
+
+/* ECHONET LiteT[rXR[h */
+typedef enum _echonet_service_code
+{
+	ESV_NOP				=	0,		/* (@\wèÈµ)							*/
+	ESV_SET_I			=	0x60,	/* vpeBl«Ývisvj		*/
+	ESV_SET_C			=	0x61,	/* vpeBl«Ývivj		*/
+	ESV_GET				=	0x62,	/* vpeBlÇÝoµv					*/
+	ESV_INF_REQ			=	0x63,	/* vpeBlÊmv						*/
+	ESV_SET_GET			=	0x6E,	/* vpeBl«ÝEÇÝoµv		*/
+	ESV_SET_RES			=	0x71,	/* vpeBl«Ý					*/
+	ESV_GET_RES			=	0x72,	/* vpeBlÇÝoµ					*/
+	ESV_INF				=	0x73,	/* vpeBlÊm							*/
+	ESV_INFC			=	0x74,	/* vpeBlÊmivj				*/
+	ESV_INFC_RES		=	0x7A,	/* vpeBlÊm						*/
+	ESV_SET_GET_RES		=	0x7E,	/* vpeBl«ÝEÇÝoµ		*/
+	ESV_SET_I_SNA		=	0x50,	/* vpeBl«ÝvsÂ			*/
+	ESV_SET_C_SNA		=	0x51,	/* vpeBl«ÝvsÂ			*/
+	ESV_GET_SNA			=	0x52,	/* vpeBlÇÝoµsÂ				*/
+	ESV_INF_SNA			=	0x53,	/* vpeBlÊmsÂ					*/
+	ESV_SET_GET_SNA		=	0x5E	/* vpeBl«ÝEÇÝoµsÂ	*/
+} ECN_SRV_CODE;
+
+#ifdef __CA850__
+#pragma pack(1)
+#elif __RX
+#pragma pack
+#elif _MSC_VER
+#pragma pack(push, 1)
+#endif
+
+/*
+ *  ECHONET Lited¶wb_[
+ */
+typedef struct
+{
+	uint8_t	ehd1;		/* ECHONET Lited¶wb_[1 ECN_EHD1_ECL_VERSION */
+	uint8_t	ehd2;		/* ECHONET Lited¶wb_[2 ECN_EHD2_FORMAT */
+	uint16_t	tid;	/* gUNVID */
+} T_ECN_HDR;
+
+/*
+ *  ECHONET LiteIuWFNgR[h
+ */
+typedef struct
+{
+	uint8_t	eojx1;		/* NXO[vR[h */
+	uint8_t	eojx2;		/* NXR[h */
+	uint8_t	eojx3;		/* CX^XR[h */
+} T_ECN_EOJ;
+
+/*
+ *  ECHONET Litef[^wb_[
+ */
+typedef struct
+{
+	T_ECN_EOJ	seoj;	/* M³ECHONET LiteIuWFNgwè */
+	T_ECN_EOJ	deoj;	/* èæECHONET LiteIuWFNgwè */
+	uint8_t	esv;		/* ECHONET LiteT[rX (ECN_SRV_CODE) */
+	uint8_t	opc;		/* vpeB */
+} T_ECN_EDATA_BODY;
+
+/*
+ *  ECHONET LitevpeB
+ */
+typedef struct
+{
+	uint8_t	epc;		/* ECHONET LitevpeBR[h */
+	uint8_t	pdc;		/* EDTÌoCg */
+	/*void	*p_edt;*/	/* vpeBlf[^ */
+} T_ECN_PRP;
+
+/*
+ *  ECHONET Litef[^
+ */
+typedef struct
+{
+	T_ECN_HDR			ecn_hdr;
+	T_ECN_EDATA_BODY	edata;
+	T_ECN_PRP			ecn_prp;
+} T_ECN_EDT_HDR;
+
+/*
+ *  ECHONET Lite d¶
+ */
+typedef struct echonet_object_data
+{
+	uint8_t _private1[192];
+	T_ECN_EDT_HDR hdr;
+	uint8_t _private2[64 - sizeof(T_ECN_EDT_HDR)];
+} T_EDATA;
+
+#ifdef __CA850__
+#pragma pack(8)
+#elif __RX
+#pragma unpack
+#elif _MSC_VER
+#pragma pack(pop)
+#endif
+
+/*
+ *  d¶ðÍCe[^[
+ */
+typedef struct echonet_epc_enumerator
+{
+	T_EDATA *pk_esv;
+	uint8_t count;			/* ¡ÇÝæèÌubNÉ évpeB */
+	uint8_t got_ct;			/* ¡ÇÝæèÌubNÅAÇÝæÁ½ */
+	uint8_t next_blk_ct;	/* ã±ubN */
+	uint8_t is_eof;			/* I[ÉBµ½Añ0 */
+	int cur;
+} T_ENUM_EPC;
+
+typedef struct echonet_property_initialization_block EPRPINIB;
+
+/*
+ * ECHONET Lite vpeBÌÝèÖ
+ */
+typedef int (EPRP_SETTER)(const EPRPINIB *item, const void *src, int size, bool_t *anno);
+
+/*
+ * ECHONET Lite vpeBÌæ¾Ö
+ */
+typedef int (EPRP_GETTER)(const EPRPINIB *item, void *dst, int size);
+
+/*
+ *  ECHONET Lite vpeBú»ubN
+ */
+struct echonet_property_initialization_block
+{
+	uint8_t		eprpcd;			/* ECHONET Lite vpeBR[h */
+	ATR			eprpatr;		/* ECHONET Lite vpeB®« */
+	uint8_t		eprpsz;			/* ECHONET Lite vpeBÌTCY */
+	intptr_t	exinf;			/* ECHONET Lite vpeBÌg£îñ */
+	EPRP_SETTER	*eprpset;		/* ECHONET Lite vpeBÌÝèÖ */
+	EPRP_GETTER	*eprpget;		/* ECHONET Lite vpeBÌæ¾Ö */
+};
+
+#define TMIN_EOBJID		1		/* ECHONET Lite IuWFNgIDÌÅ¬l */
+
+/*
+ *  ECHONET Lite IuWFNgú»ubN
+ */
+typedef struct echonet_object_initialization_block
+{
+	ATR			eobjatr;		/* ECHONET Lite IuWFNg®« */
+	ID			enodid;			/* ECHONET Lite m[hvt@CIuWFNgID */
+	intptr_t	exinf;			/* ECHONET Lite IuWFNgÌg£îñ */
+	uint8_t		eojx1;			/* ECHONET Lite IuWFNgÌNXO[vR[h */
+	uint8_t		eojx2;			/* ECHONET Lite IuWFNgÌNXR[h */
+	uint8_t		eojx3;			/* ECHONET Lite IuWFNgÌCX^XR[h */
+	const EPRPINIB *eprp;		/* ECHONET Lite vpeBú»ubN */
+	uint_t		eprpcnt;		/* ECHONET Lite vpeBú»ubN */
+} EOBJINIB;
+
+/*
+ *  ECHONET Lite m[hÇubN
+ */
+typedef struct echonet_object_control_block
+{
+	const EOBJINIB *profile;	/* ECHONET Lite m[hvt@CÖÌ|C^ */
+	const EOBJINIB **eobjs;		/* ECHONET Lite IuWFNgXgÖÌ|C^ */
+	uint_t		eobjcnt;		/* ECHONET Lite IuWFNg */
+} EOBJCB;
+
+/*
+ *  ECHONET Lite m[hÆIPAhXÌÎîñubNÌè`
+ */
+typedef struct echonet_node_address_block
+{
+	bool_t		inuse;			/* gpóµ */
+	uint8_t		ipaddr[16];		/* IPAhX */
+} ENODADRB;
+
+/*
+ *  ECHONET Lite IuWFNgIDÌÅåliechonet_cfg.cj
+ */
+extern const ID	tmax_eobjid;
+
+/*
+ *  ECHONET Lite IuWFNgú»ubNÌGAiechonet_cfg.cj
+ */
+extern const EOBJINIB	eobjinib_table[];
+
+/*
+ *  ECHONET Litem[hÇubNÌ
+ */
+extern const int tnum_enodid;
+
+/*
+ *  ECHONET Lite IuWFNgÇubNÌGAiechonet_cfg.cj
+ */
+extern EOBJCB	eobjcb_table[];
+
+/*
+ * ECHONET Litem[hÆIPAhXÌÎîñÌ
+ */
+extern const int tnum_enodadr;
+
+/*
+ *  ECHONET Lite m[hÆIPAhXÌÎîñubNÌGAiechonet_cfg.cj
+ */
+extern ENODADRB	enodadrb_table[];
+
+/*
+ * ECHONET Lite J[lIuWFNgID
+ */
+extern const ID ecn_svc_taskid;
+extern const ID ecn_udp_taskid;
+extern const ID ecn_api_mailboxid;
+extern const ID ecn_svc_mailboxid;
+extern const ID ecn_udp_mailboxid;
+extern const ID ecn_mempoolid;
+extern const ID ecn_udp_cepid;
+
+/*
+ *  ECHONET Lite IuWFNgÇubN©çECHONET Lite IuWFNgIDðæèo·½ßÌ}N
+ */
+#define	EOBJID(p_eobjcb)	((ID)(((p_eobjcb) - eobjcb_table) + TMIN_EOBJID))
+
+/*
+ *  ECHONET Lite IuWFNg@\Ìú»
+ */
+extern void	initialize_echonet_object(void);
+
+typedef EOBJINIB T_REOBJ;
+
+typedef EPRPINIB T_RPRP;
+
+typedef ENODADRB T_ENOD_ADDR;
+
+/*
+ * ECHONET LiteT[rXJn
+ */
+ER ecn_sta_svc();
+
+/*
+ * ECHONETIuWFNgQÆ
+ */
+ER ecn_ref_eobj(ID eobjid, T_REOBJ *pk_eobj);
+
+/*
+ * ECHONETvpeBQÆ
+ */
+ER ecn_ref_eprp(ID eobjid, uint8_t epc, T_RPRP *pk_eprp);
+
+/*
+ * vpeBl«Ývisvjd¶ì¬
+ */
+ER ecn_esv_seti(T_EDATA **ppk_esv, ID eobjid, uint8_t epc, uint8_t pdc, const void *p_edt);
+
+/*
+ * vpeBl«Ývivjd¶ì¬
+ */
+ER ecn_esv_setc(T_EDATA **ppk_esv, ID eobjid, uint8_t epc, uint8_t pdc, const void *p_edt);
+
+/*
+ * vpeBlÇÝoµvd¶ì¬
+ */
+ER ecn_esv_get(T_EDATA **ppk_esv, ID eobjid, uint8_t epc);
+
+/*
+ * vpeBlÊmvd¶ì¬
+ */
+ER ecn_esv_inf_req(T_EDATA **ppk_esv, ID eobjid, uint8_t epc);
+
+/*
+ * vpeBl«ÝEÇÝoµvd¶ì¬
+ */
+ER ecn_esv_set_get(T_EDATA **ppk_esv, ID eobjid, uint8_t epc, uint8_t pdc, const void *p_edt);
+
+/*
+ * vpeBl«ÝEÇÝoµvd¶ÜèÔµwè
+ */
+ER ecn_trn_set_get(T_EDATA *pk_esv, int *p_trn_pos);
+
+/*
+ * vpeBl«ÝEÇÝoµvd¶I¹wè
+ */
+ER ecn_end_set_get(T_EDATA *pk_esv, int trn_pos);
+
+/*
+ * vpeBlÊmivjd¶ì¬
+ */
+ER ecn_esv_infc(T_EDATA **ppk_esv, ID eobjid, ID seobjid, uint8_t sepc);
+
+/*
+ * vd¶ÖÌvpeBwèÇÁ
+ */
+ER ecn_add_epc(T_EDATA *pk_esv, uint8_t epc);
+
+/*
+ * vd¶ÖÌvpeBf[^ÇÁ
+ */
+ER ecn_add_edt(T_EDATA *pk_esv, uint8_t epc, uint8_t pdc, const void *p_edt);
+
+/*
+ * vd¶ÌM
+ */
+ER ecn_snd_esv(T_EDATA *pk_esv);
+
+/*
+ * d¶ÌóMiÒ¿
+ */
+ER ecn_rcv_esv(T_EDATA **ppk_esv);
+
+/*
+ * d¶ÌóMÒ¿^CAEg è
+ */
+ER ecn_trcv_esv(T_EDATA **ppk_esv, TMO tmout);
+
+/*
+ * d¶ÌóM|[O
+ */
+ER ecn_prcv_esv(T_EDATA **ppk_esv);
+
+/*
+ * d¶Ìjü
+ */
+ER ecn_rel_esv(T_EDATA *pk_esv);
+
+/*
+ * d¶ÌM³@íIuWFNgðæ¾·é
+ */
+ID ecn_get_eobj(T_EDATA *pk_esv);
+
+/*
+ * d¶ðÍCe[^[ú»
+ */
+ER ecn_itr_ini(T_ENUM_EPC *pk_itr, T_EDATA *pk_esv);
+
+/*
+ * d¶ðÍCe[^[CNg
+ */
+ER ecn_itr_nxt(T_ENUM_EPC *pk_itr, uint8_t *p_epc, uint8_t *p_pdc, void *p_edt);
+
+/*
+ * d¶Ò¿ÌèÝM
+ */
+ER ecn_brk_wai(const void *p_dat, int datsz);
+
+/*
+ * èÝf[^Ìæ¾
+ */
+ER ecn_get_brk_dat(T_EDATA *pk_esv, void *p_buf, int bufsz, int *p_datsz);
+
+/*
+ * f[^ÝèÖ
+ */
+int ecn_data_prop_set(const EPRPINIB *item, const void *src, int size, bool_t *anno);
+
+/*
+ * f[^æ¾Ö
+ */
+int ecn_data_prop_get(const EPRPINIB *item, void *dst, int size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ECHONET_H
Index: UsbWattMeter/trunk/ecnl_lwip/echonet.tf
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet.tf	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet.tf	(revision 164)
@@ -0,0 +1,617 @@
+$ =====================================================================
+$ 
+$  TOPPERS ECHONET Lite Communication Middleware
+$ 
+$  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+$ 
+$  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$      XR[hÉÜÜêÄ¢é±ÆD
+$  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$      Ì³ÛØKèðfÚ·é±ÆD
+$  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$      ÆD
+$    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$        ñ·é±ÆD
+$  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$      ÆÓ·é±ÆD
+$ 
+$  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$  ÌÓCðíÈ¢D
+$ 
+$  @(#) $Id$
+$ 
+$ =====================================================================
+
+$ =====================================================================
+$ echonet_cfg.hÌ¶¬
+$ =====================================================================
+
+$FILE "echonet_cfg.h"$
+/* echonet_cfg.h */$NL$
+#ifndef TOPPERS_ECHONET_CFG_H$NL$
+#define TOPPERS_ECHONET_CFG_H$NL$
+$NL$
+
+#include "echonet_app_config.h"$NL$
+$NL$
+
+$ m[hXgÌì¬
+$ENOD.LIST = {}$
+$LOCAL_NODE = {}$
+$REMOTE_NODE = {}$
+
+$FOREACH eobjid EOBJ.ORDER_LIST$
+$	// m[hvt@CIuWFNgÌê
+	$IF (EOBJ.EOBJATR[eobjid] & EOBJ_LOCAL_NODE) != 0$
+		$LOCAL_NODE = APPEND(LOCAL_NODE, eobjid)$
+$	// @íIuWFNgÌê
+	$ELIF (EOBJ.EOBJATR[eobjid] & (EOBJ_SYNC_REMOTE_NODE|EOBJ_ASYNC_REMOTE_NODE)) != 0$
+		$REMOTE_NODE = APPEND(REMOTE_NODE, eobjid)$
+	$END$
+$END$
+
+$	// [JÌm[hvt@CÍPÂ¾¯
+$IF LENGTH(LOCAL_NODE) != 1$
+	$ERROR$Local node must be only one.$END$
+$END$
+
+$ENOD.LIST = APPEND(LOCAL_NODE, REMOTE_NODE)$
+
+#define TNUM_ENODID	$LENGTH(ENOD.LIST)$$NL$
+$NL$
+
+#define TNUM_EOBJID	$LENGTH(EOBJ.ID_LIST)$$NL$
+$NL$
+$FOREACH id EOBJ.ID_LIST$
+	#define $id$	$+id$$NL$
+$END$
+$NL$
+
+$FOREACH eobjid EOBJ.ID_LIST$
+	$eprp_list = {}$
+	$prp_map_cnt = 3$
+$	// m[hvt@CÌê
+	$IF (EOBJ.EOBJATR[eobjid] & (EOBJ_LOCAL_NODE|EOBJ_SYNC_REMOTE_NODE|EOBJ_ASYNC_REMOTE_NODE)) != 0$
+		$prp_map_cnt = prp_map_cnt + 5$
+	$END$
+
+	$FOREACH eprpno EPRP.ID_LIST$
+		$IF EQ(EPRP.EOBJID[eprpno], eobjid)$
+			$eprp_list = APPEND(eprp_list, eprpno)$
+		$END$
+
+		$IF (EPRP.EPRPCD[eprpno] == 0x9D) || (EPRP.EPRPCD[eprpno] == 0x9E) || (EPRP.EPRPCD[eprpno] == 0x9F)$
+			$prp_map_cnt = prp_map_cnt - 1$
+		$END$
+
+$		// m[hvt@CÌê
+		$IF (EOBJ.EOBJATR[eobjid] & (EOBJ_LOCAL_NODE|EOBJ_SYNC_REMOTE_NODE|EOBJ_ASYNC_REMOTE_NODE)) != 0$
+			$IF (EPRP.EPRPCD[eprpno] >= 0xD3) && (EPRP.EPRPCD[eprpno] <= 0xD7)$
+				$prp_map_cnt = prp_map_cnt - 1$
+			$END$
+		$END$
+	$END$
+
+	#define TNUM_$EOBJ.EOBJID[eobjid]$_EPRPNO	$LENGTH(eprp_list) + prp_map_cnt$$NL$
+$END$$NL$
+
+$FOREACH enodid ENOD.LIST$
+	$eobj_count = 0$
+
+	$FOREACH eobjid EOBJ.ID_LIST$
+		$IF EQ(EOBJ.ENODID[eobjid], enodid)$
+			$eobj_count = eobj_count + 1$
+		$END$
+	$END$
+
+	#define TNUM_$EOBJ.EOBJID[enodid]$_EOBJNO	$eobj_count$$NL$
+$END$$NL$
+
+#ifndef TNUM_ENODADR$NL$
+#define TNUM_ENODADR 100$NL$
+#endif$NL$
+$NL$
+
+#endif /* TOPPERS_ECHONET_CFG_H */$NL$
+
+$ =====================================================================
+$ echonet_cfg.cÌ¶¬
+$ =====================================================================
+
+$FILE "echonet_cfg.c"$
+/* echonet_cfg.c */$NL$
+#include "echonet.h"$NL$
+#include "echonet_cfg.h"$NL$
+$NL$
+
+$ 
+$  CN[hfBNeBui#includej
+$ 
+/*$NL$
+$SPC$*  Include Directives (#include)$NL$
+$SPC$*/$NL$
+$NL$
+$INCLUDES$
+$NL$
+
+$ 
+$  IuWFNgÌIDÔðÛ·éÏ
+$ 
+$IF USE_EXTERNAL_ID$
+	/*$NL$
+	$SPC$*  Variables for Object ID$NL$
+	$SPC$*/$NL$
+	$NL$
+	$FOREACH id EOBJ.ID_LIST$
+		const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+	$END$
+$END$
+
+$ 
+$  ECHONET LitevpeB
+$ 
+/*$NL$
+$SPC$*  ECHONET Lite Property Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$INCLUDE "echonet_chk.tf"$
+
+$ ECHONET LitevpeBú»ubNÌ¶¬
+$IF LENGTH(EOBJ.ID_LIST) && LENGTH(EPRP.ID_LIST)$
+	$FOREACH enodid ENOD.LIST$
+		$INST_LIST = {}$
+		$CLASS_LIST = {}$
+
+		$FOREACH eobjid EOBJ.ID_LIST$
+			$IF EQ(EOBJ.ENODID[eobjid], enodid)$
+				$INST_LIST = APPEND(INST_LIST, eobjid)$
+
+				$M = -1$
+				$FOREACH id CLASS_LIST$
+					$IF (EOBJ.EOJX1[eobjid] == EOBJ.EOJX1[id]) && (EOBJ.EOJX2[eobjid] == EOBJ.EOJX2[id])$
+						$M = id$
+					$END$
+				$END$
+				$IF M == -1$
+					$CLASS_LIST = APPEND(CLASS_LIST, eobjid)$
+				$END$
+			$END$
+		$END$
+
+		/*$NL$
+		$SPC$* CX^X$NL$
+		$SPC$*/$NL$
+		$inst_list_len = LENGTH(INST_LIST)$
+		const uint8_t _echonet_$EOBJ.EOBJID[enodid]$_inst_count[] = {$NL$
+			$TAB$$FORMAT("0x%1$x, 0x%2$x, 0x%3$x", (inst_list_len & 0xFF0000) >> 16, (inst_list_len & 0xFF00) >> 8, inst_list_len & 0xFF)$$NL$
+		};$NL$
+		$NL$
+
+		/*$NL$
+		$SPC$* NX$NL$
+		$SPC$*/$NL$
+$		// m[hvt@CàÜßéi + 1j
+		$class_list_len = LENGTH(CLASS_LIST) + 1$
+		const uint8_t _echonet_$EOBJ.EOBJID[enodid]$_class_count[] = {$NL$
+			$TAB$$FORMAT("0x%1$x, 0x%2$x", (class_list_len & 0xFF00) >> 8, class_list_len & 0xFF)$$NL$
+		};$NL$
+		$NL$
+
+		/*$NL$
+		$SPC$* CX^XXg$NL$
+		$SPC$*/$NL$
+		$pos = 0$
+		$IF inst_list_len > 84$
+			$ERROR EPRP.TEXT_LINE[eprpno]$E_PAR: $FORMAT(_("instance list count overflow, %1% %2% > 84"), enodid, inst_list_len)$$END$
+		$END$
+		const uint8_t _echonet_$EOBJ.EOBJID[enodid]$_inst_list[] = {$NL$
+		$IF inst_list_len > 0xFE$
+			$TAB$0xFF, 
+		$ELSE$
+			$TAB$$FORMAT("0x%1$x, ", inst_list_len)$
+		$END$
+		$JOINEACH id INST_LIST ", "$
+			$FORMAT("0x%1$x, 0x%2$x, 0x%3$x", +EOBJ.EOJX1[id], +EOBJ.EOJX2[id], +EOBJ.EOJX3[id])$
+		$END$$NL$
+		};$NL$
+		$NL$
+
+		/*$NL$
+		$SPC$* NXXg$NL$
+		$SPC$*/$NL$
+		$pos = 0$
+		$class_list_len = LENGTH(CLASS_LIST)$
+		$IF class_list_len > 84$
+			$ERROR EPRP.TEXT_LINE[eprpno]$E_PAR: $FORMAT(_("class list count overflow, %1% %2% > 84"), enodid, class_list_len)$$END$
+		$END$
+		const uint8_t _echonet_$EOBJ.EOBJID[enodid]$_class_list[] = {$NL$
+		$IF class_list_len > 0xFE$
+			$TAB$0xFF, 
+		$ELSE$
+			$TAB$$FORMAT("0x%1$x, ", class_list_len)$
+		$END$
+		$JOINEACH id CLASS_LIST ", "$
+			$FORMAT("0x%1$x, 0x%2$x", +EOBJ.EOJX1[id], +EOBJ.EOJX2[id])$
+		$END$$NL$
+		};$NL$
+		$NL$
+	$END$
+
+	$FOREACH eobjid EOBJ.ID_LIST$
+		$eprp_list = {}$
+		$anno_list = {}$
+		$set_list = {}$
+		$get_list = { 0x9D, 0x9E, 0x9F }$
+		$FOREACH i { 0 , 1 , ... , 15 }$
+			$anno_map[i] = 0x00$
+			$set_map[i] = 0x00$
+			$get_map[i] = 0x00$
+		$END$
+$		// 0x9DA0x9EA0x9FÍONÉµÄ¨­
+		$FOREACH i { 13 , 14 , 15 }$
+			$anno_map[i] = anno_map[i] | 0x02$
+			$get_map[i] = get_map[i] | 0x02$
+		$END$
+$		// m[hvt@CÌê
+		$IF (EOBJ.EOBJATR[eobjid] & (EOBJ_LOCAL_NODE|EOBJ_SYNC_REMOTE_NODE|EOBJ_ASYNC_REMOTE_NODE)) != 0$
+			$anno_map[5] = anno_map[5] | 0x20$
+			$anno_list = APPEND(anno_list, { 0xD5 })$
+			$FOREACH i { 3 , 4 , 6 , 7 }$
+				$get_map[i] = get_map[i] | 0x20$
+			$END$
+			$get_list = APPEND(get_list, { 0xD3, 0xD4, 0xD6, 0xD7 })$
+		$END$
+
+		$FOREACH eprpno EPRP.ID_LIST$
+			$IF EQ(EPRP.EOBJID[eprpno], eobjid)$
+$				// (0x80 <= eprpcd && eprpcd <= 0xFF)ÅÈ¢êiE_PARj
+				$IF !(0x80 <= EPRP.EPRPCD[eprpno] && EPRP.EPRPCD[eprpno] <= 0xFF)$
+					$ERROR EPRP.TEXT_LINE[eprpno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "eprpcd", EPRP.EPRPCD[eprpno], eprpno, "ECN_DEF_EPRP")$$END$
+				$END$
+
+$				// eprpatrªimEPC_RULE_SET] | [EPC_RULE_GET] | [EPC_RULE_ANNO] | [EPC_ANNOUNCEn| [EPC_VARIABLE]jÅÈ¢êiE_RSATRj
+				$IF (EPRP.EPRPATR[eprpno] & ~(EPC_RULE_SET|EPC_RULE_GET|EPC_RULE_ANNO|EPC_ANNOUNCE|EPC_VARIABLE)) != 0$
+					$ERROR EPRP.TEXT_LINE[eprpno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "eprpatr", EPRP.EPRPATR[eprpno], eprpno, "ECN_DEF_EPRP")$$END$
+				$END$
+
+$				// (0 <= eprpsz && eprpsz <= 255)ÅÈ¢êiE_PARj
+				$IF !(0 <= EPRP.EPRPSZ[eprpno] && EPRP.EPRPSZ[eprpno] <= 255)$
+					$ERROR EPRP.TEXT_LINE[eprpno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "eprpsz", EPRP.EPRPSZ[eprpno], eprpno, "ECN_DEF_EPRP")$$END$
+				$END$
+
+$				// vpeB}bvÉÝè
+				$pos = EPRP.EPRPCD[eprpno] & 0xF$
+				$bit = (EPRP.EPRPCD[eprpno] >> 4) - 8$
+				$IF (EPRP.EPRPATR[eprpno] & EPC_ANNOUNCE) != 0$
+					$anno_list = APPEND(anno_list, EPRP.EPRPCD[eprpno])$
+					$anno_map[pos] = anno_map[pos] | (1 << bit)$
+				$END$
+				$IF (EPRP.EPRPATR[eprpno] & EPC_RULE_SET) != 0$
+					$set_list = APPEND(set_list, EPRP.EPRPCD[eprpno])$
+					$set_map[pos] = set_map[pos] | (1 << bit)$
+				$END$
+				$IF (EPRP.EPRPATR[eprpno] & EPC_RULE_GET) != 0$
+					$get_list = APPEND(get_list, EPRP.EPRPCD[eprpno])$
+					$get_map[pos] = get_map[pos] | (1 << bit)$
+				$END$
+
+				$eprp_list = APPEND(eprp_list, eprpno)$
+			$END$
+		$END$
+
+$		// K{AiEXvpeBª é©`FbN
+		$must_anno_map = GetPropertyInfo(EOBJ.EOJX1[eobjid], EOBJ.EOJX2[eobjid], EPC_ANNOUNCE)$
+		$i = 0$
+		$WHILE i < LENGTH(ResultOfGetPropertyInfo)$
+			$j = FIND(anno_list, +AT(ResultOfGetPropertyInfo, i))$
+			$IF !LENGTH(j)$
+				$ERROR$$FORMAT("Required announce property (0x%1$x) of %2% is not defined.", +AT(ResultOfGetPropertyInfo, i), eobjid)$$END$
+			$END$
+			$i = i + 1$
+		$END$
+
+$		// K{SETvpeBª é©`FbN
+		$must_set_map = GetPropertyInfo(EOBJ.EOJX1[eobjid], EOBJ.EOJX2[eobjid], EPC_RULE_SET)$
+		$i = 0$
+		$WHILE i < LENGTH(ResultOfGetPropertyInfo)$
+			$j = FIND(set_list, +AT(ResultOfGetPropertyInfo, i))$
+			$IF !LENGTH(j)$
+				$ERROR$$FORMAT("Required set property (0x%1$x) of %2% is not defined.", +AT(ResultOfGetPropertyInfo, i), eobjid)$$END$
+			$END$
+			$i = i + 1$
+		$END$
+
+$		// K{GETvpeBª é©`FbN
+		$must_get_map = GetPropertyInfo(EOBJ.EOJX1[eobjid], EOBJ.EOJX2[eobjid], EPC_RULE_GET)$
+		$i = 0$
+		$WHILE i < LENGTH(ResultOfGetPropertyInfo)$
+			$j = FIND(get_list, +AT(ResultOfGetPropertyInfo, i))$
+			$IF !LENGTH(j)$
+				$ERROR$$FORMAT("Required get property (0x%1$x) of %2% is not defined.", +AT(ResultOfGetPropertyInfo, i), eobjid)$$END$
+			$END$
+			$i = i + 1$
+		$END$
+
+		/*$NL$
+		$SPC$* AiEXvpeB}bv$NL$
+		$SPC$*/$NL$
+		$anno_list = LSORT(anno_list, "compare")$
+		$anno_len = LENGTH(anno_list)$
+		const uint8_t _echonet_$EOBJ.EOBJID[eobjid]$_anno_prpmap[] = {$NL$
+		$TAB$$FORMAT("0x%1$x" , +anno_len)$, 
+		$IF anno_len < 16$
+			$JOINEACH eprpcd anno_list ", "$
+				$FORMAT("0x%1$x" , +eprpcd)$
+			$END$$NL$
+			$anno_len = anno_len + 1$
+		$ELSE$
+			$JOINEACH i anno_map ", "$
+				$FORMAT("0x%1$x" , +anno_map[i])$
+			$END$$NL$
+			$anno_len = 17$
+		$END$
+		};$NL$
+		$NL$
+
+		/*$NL$
+		$SPC$* SETvpeB}bv$NL$
+		$SPC$*/$NL$
+		$set_list = LSORT(set_list, "compare")$
+		$set_len = LENGTH(set_list)$
+		const uint8_t _echonet_$EOBJ.EOBJID[eobjid]$_set_prpmap[] = {$NL$
+		$TAB$$FORMAT("0x%1$x" , +set_len)$, 
+		$IF set_len < 16$
+			$JOINEACH eprpcd set_list ", "$
+				$FORMAT("0x%1$x" , +eprpcd)$
+			$END$$NL$
+			$set_len = set_len + 1$
+		$ELSE$
+			$JOINEACH i set_map ", "$
+				$FORMAT("0x%1$x" , +set_map[i])$
+			$END$$NL$
+			$set_len = 17$
+		$END$
+		};$NL$
+		$NL$
+
+		/*$NL$
+		$SPC$* GETvpeB}bv$NL$
+		$SPC$*/$NL$
+		$get_list = LSORT(get_list, "compare")$
+		$get_len = LENGTH(get_list)$
+		const uint8_t _echonet_$EOBJ.EOBJID[eobjid]$_get_prpmap[] = {$NL$
+		$TAB$$FORMAT("0x%1$x" , +get_len)$, 
+		$IF get_len < 16$
+			$JOINEACH eprpcd get_list ", "$
+				$FORMAT("0x%1$x" , +eprpcd)$
+			$END$$NL$
+			$get_len = get_len + 1$
+		$ELSE$
+			$JOINEACH i { 0 , 1 , ... , 15 } ", "$
+				$FORMAT("0x%1$x" , +get_map[i])$
+			$END$$NL$
+			$get_len = 17$
+		$END$
+		};$NL$
+		$NL$
+
+		/*$NL$
+		$SPC$* vpeBè`$NL$
+		$SPC$*/$NL$
+		const EPRPINIB _echonet_$EOBJ.EOBJID[eobjid]$_eprpinib_table[TNUM_$EOBJ.EOBJID[eobjid]$_EPRPNO] = {$NL$
+		$FOREACH eprpno eprp_list$
+$			// ECHONET LitevpeBú»ubN
+			$TAB${ ($EPRP.EPRPCD[eprpno]$), ($EPRP.EPRPATR[eprpno]$), ($EPRP.EPRPSZ[eprpno]$), ($EPRP.EXINF[eprpno]$), ($EPRP.EPRPSET[eprpno]$), ($EPRP.EPRPGET[eprpno]$) },$NL$
+		$END$
+$		// óÔAiEXvpeB}bv
+		$TAB${ (0x9D), (EPC_RULE_GET), $FORMAT("0x%1$x" , +anno_len)$, (intptr_t)_echonet_$EOBJ.EOBJID[eobjid]$_anno_prpmap, ((EPRP_SETTER *)NULL), ((EPRP_GETTER *)ecn_data_prop_get) },$NL$
+$		// SetvpeB}bv
+		$TAB${ (0x9E), (EPC_RULE_GET), $FORMAT("0x%1$x" , +set_len)$, (intptr_t)_echonet_$EOBJ.EOBJID[eobjid]$_set_prpmap, ((EPRP_SETTER *)NULL), ((EPRP_GETTER *)ecn_data_prop_get) },$NL$
+$		// GetvpeB}bv
+		$TAB${ (0x9F), (EPC_RULE_GET), $FORMAT("0x%1$x" , +get_len)$, (intptr_t)_echonet_$EOBJ.EOBJID[eobjid]$_get_prpmap, ((EPRP_SETTER *)NULL), ((EPRP_GETTER *)ecn_data_prop_get) }
+$		// m[hvt@CÌê
+		$IF (EOBJ.EOBJATR[eobjid] & (EOBJ_LOCAL_NODE|EOBJ_SYNC_REMOTE_NODE|EOBJ_ASYNC_REMOTE_NODE)) != 0$
+			,$NL$
+$			// CX^X
+			$TAB${ (0xD3), (EPC_RULE_GET), (3), (intptr_t)_echonet_$EOBJ.EOBJID[eobjid]$_inst_count, ((EPRP_SETTER *)NULL), ((EPRP_GETTER *)ecn_data_prop_get) },$NL$
+$			// NX
+			$TAB${ (0xD4), (EPC_RULE_GET), (2), (intptr_t)_echonet_$EOBJ.EOBJID[eobjid]$_class_count, ((EPRP_SETTER *)NULL), ((EPRP_GETTER *)ecn_data_prop_get) },$NL$
+$			// CX^XXgÊm
+			$TAB${ (0xD5), (EPC_RULE_ANNO), sizeof(_echonet_$EOBJ.EOBJID[eobjid]$_inst_list), (intptr_t)_echonet_$EOBJ.EOBJID[eobjid]$_inst_list, ((EPRP_SETTER *)NULL), ((EPRP_GETTER *)ecn_data_prop_get) },$NL$
+$			// CX^XXgS
+			$TAB${ (0xD6), (EPC_RULE_GET), sizeof(_echonet_$EOBJ.EOBJID[eobjid]$_inst_list), (intptr_t)_echonet_$EOBJ.EOBJID[eobjid]$_inst_list, ((EPRP_SETTER *)NULL), ((EPRP_GETTER *)ecn_data_prop_get) },$NL$
+$			// NXXgS
+			$TAB${ (0xD7), (EPC_RULE_GET), sizeof(_echonet_$EOBJ.EOBJID[eobjid]$_class_list), (intptr_t)_echonet_$EOBJ.EOBJID[eobjid]$_class_list, ((EPRP_SETTER *)NULL), ((EPRP_GETTER *)ecn_data_prop_get) }$NL$
+		$ELSE$
+			$NL$
+		$END$
+		};$NL$
+		$NL$
+	$END$$NL$
+
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const EPRPINIB, _echonet_eprpinib_table);$NL$
+$END$
+
+$ 
+$  ECHONET LiteIuWFNg
+$ 
+/*$NL$
+$SPC$*  ECHONET Lite Object Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ ECHONET LiteIuWFNgIDÔÌÅål
+const ID _echonet_tmax_eobjid = (TMIN_EOBJID + TNUM_EOBJID - 1);$NL$
+$NL$
+
+$ ECHONET LiteIuWFNgú»ubNÌ¶¬
+$IF LENGTH(EOBJ.ID_LIST)$
+	const EOBJINIB _echonet_eobjinib_table[TNUM_EOBJID] = {$NL$
+	$JOINEACH eobjid EOBJ.ID_LIST ",\n"$
+$		// eobjatrªimEOBJ_LOCAL_NODE] | [EOBJ_SYNC_REMOTE_NODE] | [EOBJ_ASYNC_REMOTE_NODE] | [EOBJ_DEVICEnjÅÈ¢êiE_RSATRj
+		$IF (EOBJ.EOBJATR[eobjid] & ~(EOBJ_LOCAL_NODE|EOBJ_SYNC_REMOTE_NODE|EOBJ_ASYNC_REMOTE_NODE|EOBJ_DEVICE)) != 0$
+			$ERROR EOBJ.TEXT_LINE[eobjid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "eobjatr", EOBJ.EOBJATR[eobjid], eobjid, "ECN_CRE_EOBJ")$$END$
+		$END$
+
+$		// m[hvt@CIuWFNgÌê
+		$IF (EOBJ.EOBJATR[eobjid] & (EOBJ_LOCAL_NODE|EOBJ_SYNC_REMOTE_NODE|EOBJ_ASYNC_REMOTE_NODE)) != 0$
+$			// (enodid == EOBJ_NULL)ÅÈ¢êiE_PARj
+			$IF !EQ(EOBJ.ENODID[eobjid], EOBJ_NULL)$
+				$ERROR EOBJ.TEXT_LINE[eobjid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "enodid", EOBJ.ENODID[eobjid], eobjid, "ECN_CRE_EOBJ")$$END$
+			$END$
+
+$			// (eojx1 == EOJ_X1_PROFILE)ÅÈ¢êiE_PARj
+			$IF EOBJ.EOJX1[eobjid] != EOJ_X1_PROFILE$
+				$ERROR EOBJ.TEXT_LINE[eobjid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "eojx1", EOBJ.EOJX1[eobjid], eobjid, "ECN_CRE_EOBJ")$$END$
+			$END$
+
+$			// (eojx2 == EOJ_X2_NODE_PROFILE)ÅÈ¢êiE_PARj
+			$IF EOBJ.EOJX2[eobjid] != EOJ_X2_NODE_PROFILE$
+				$ERROR EOBJ.TEXT_LINE[eobjid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "eojx2", EOBJ.EOJX2[eobjid], eobjid, "ECN_CRE_EOBJ")$$END$
+			$END$
+
+$			// (1 <= eojx3 && eojx3 <= 2)ÅÈ¢êiE_PARj
+			$IF !(1 <= EOBJ.EOJX3[eobjid] && EOBJ.EOJX3[eobjid] <= 2)$
+				$ERROR EOBJ.TEXT_LINE[eobjid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "eojx3", EOBJ.EOJX3[eobjid], eobjid, "ECN_CRE_EOBJ")$$END$
+			$END$
+$		// @íIuWFNgÌê
+		$ELSE$
+$			// (enodid != EOBJ_NULL)ÅÈ¢êiE_PARj
+			$IF EQ(EOBJ.ENODID[eobjid], EOBJ_NULL)$
+				$ERROR EOBJ.TEXT_LINE[eobjid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "enodid", EOBJ.ENODID[eobjid], eobjid, "ECN_CRE_EOBJ")$$END$
+			$END$
+
+$			// (0 <= eojx1 && eojx1 <= 255)ÅÈ¢êiE_PARj
+			$IF !(0 <= EOBJ.EOJX1[eobjid] && EOBJ.EOJX1[eobjid] <= 255)$
+				$ERROR EOBJ.TEXT_LINE[eobjid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "eojx1", EOBJ.EOJX1[eobjid], eobjid, "ECN_CRE_EOBJ")$$END$
+			$END$
+
+$			// (0 <= eojx2 && eojx2 <= 255)ÅÈ¢êiE_PARj
+			$IF !(0 <= EOBJ.EOJX2[eobjid] && EOBJ.EOJX2[eobjid] <= 255)$
+				$ERROR EOBJ.TEXT_LINE[eobjid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "eojx2", EOBJ.EOJX2[eobjid], eobjid, "ECN_CRE_EOBJ")$$END$
+			$END$
+
+$			// (0 <= eojx3 && eojx3 <= 255)ÅÈ¢êiE_PARj
+			$IF !(0 <= EOBJ.EOJX3[eobjid] && EOBJ.EOJX3[eobjid] <= 255)$
+				$ERROR EOBJ.TEXT_LINE[eobjid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "eojx3", EOBJ.EOJX3[eobjid], eobjid, "ECN_CRE_EOBJ")$$END$
+			$END$
+		$END$
+
+$		// ECHONET LiteIuWFNgú»ubN
+		$TAB${ ($EOBJ.EOBJATR[eobjid]$), ($EOBJ.ENODID[eobjid]$), ($EOBJ.EXINF[eobjid]$), ($EOBJ.EOJX1[eobjid]$), ($EOBJ.EOJX2[eobjid]$), ($EOBJ.EOJX3[eobjid]$), _echonet_$EOBJ.EOBJID[eobjid]$_eprpinib_table, TNUM_$EOBJ.EOBJID[eobjid]$_EPRPNO }
+	$END$$NL$
+	};$NL$
+	$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(const EOBJINIB, _echonet_eobjinib_table);$NL$
+$END$
+$NL$
+
+$ ECHONET Litem[hÇubNÌ
+const int _echonet_tnum_enodid = TNUM_ENODID;$NL$
+$NL$
+
+$ 
+$  ECHONET Litem[hÇubN
+$ 
+/*$NL$
+$SPC$*  ECHONET Lite Node Functions$NL$
+$SPC$*/$NL$
+$NL$
+$ ECHONET Litem[hÆIPAhXÌÎîñubNÌ¶¬
+$FOREACH enodid ENOD.LIST$
+	$eobj_list = {}$
+	$FOREACH eobjid EOBJ.ID_LIST$
+		$IF EQ(EOBJ.ENODID[eobjid], enodid)$
+			$eobj_list = APPEND(eobj_list, eobjid)$
+		$END$
+	$END$
+	/*$NL$
+	$SPC$* m[hÉ®·é@íIuWFNgÌê$NL$
+	$SPC$*/$NL$
+	const EOBJINIB *_echonet_$EOBJ.EOBJID[enodid]$_eobjinib_table[TNUM_$EOBJ.EOBJID[enodid]$_EOBJNO] = {$NL$
+	$JOINEACH eobjid eobj_list ",\n"$
+		$TAB${ &_echonet_eobjinib_table[$eobjid$ - 1] }
+	$END$$NL$
+	};$NL$
+$END$$NL$
+
+$IF LENGTH(ENOD.LIST)$
+	/*$NL$
+	$SPC$* ECHONET Litem[hÇubN$NL$
+	$SPC$*/$NL$
+	EOBJCB _echonet_eobjcb_table[TNUM_ENODID] = {$NL$
+	$JOINEACH enodid ENOD.LIST ",\n"$
+		$TAB${ &_echonet_eobjinib_table[$enodid$ - 1], _echonet_$EOBJ.EOBJID[enodid]$_eobjinib_table, TNUM_$EOBJ.EOBJID[enodid]$_EOBJNO }
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(EOBJCB, _echonet_eobjcb_table);$NL$
+$END$
+$NL$
+
+$ ECHONET Litem[hÆIPAhXÌÎîñÌ
+const int _echonet_tnum_enodadr = TNUM_ENODADR;$NL$
+$NL$
+
+$ 
+$  ECHONET Litem[hÆIPAhXÌÎîñ
+$ 
+/*$NL$
+$SPC$*  ECHONET Lite Node Functions$NL$
+$SPC$*/$NL$
+$NL$
+$ ECHONET Litem[hÆIPAhXÌÎîñubNÌ¶¬
+$IF LENGTH(EOBJ.ID_LIST)$
+	ENODADRB _echonet_enodadrb_table[TNUM_ENODADR] = {$NL$
+	$JOINEACH enodid ENOD.LIST ",\n"$
+		$IF enodid == 1$
+			$TAB$/* ENOD_MULTICAST_ID $TAB$*/ { true, ECHONET_MULTICAST_ADDR },$NL$
+			$TAB$/* ENOD_LOCAL_ID     $TAB$*/ { true, },$NL$
+			$TAB$/* ENOD_API_ID       $TAB$*/ { true, }
+		$ELSE$
+			$TAB$/* ENOD_REMOTE_ID + $enodid - 4$$TAB$*/ { true, }
+		$END$
+	$END$$NL$
+	};$NL$
+$ELSE$
+	TOPPERS_EMPTY_LABEL(ENODADRB, _echonet_enodadrb_table);$NL$
+$END$
+$NL$
+
+$NL$
+#include "kernel_cfg.h"$NL$
+$NL$
+
+$
+$ ECHONET Lite J[lIuWFNgID
+$
+const ID _echonet_ecn_svc_taskid = ECHONET_SVC_TASK;$NL$
+const ID _echonet_ecn_udp_taskid = ECHONET_UDP_TASK;$NL$
+const ID _echonet_ecn_api_mailboxid = ECHONET_API_MAILBOX;$NL$
+const ID _echonet_ecn_svc_mailboxid = ECHONET_SVC_MAILBOX;$NL$
+const ID _echonet_ecn_udp_mailboxid = ECHONET_UDP_MAILBOX;$NL$
+const ID _echonet_ecn_mem_semid = ECHONET_MEM_SEMAPHORE;$NL$
+$NL$
+
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_agent.c
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_agent.c	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_agent.c	(revision 164)
@@ -0,0 +1,1162 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2015 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ECHONET Lite ®I¶¬m[h
+ */
+
+#include <kernel.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <t_syslog.h>
+#include "echonet.h"
+#include "echonet_fbs.h"
+#include "echonet_agent.h"
+#include "echonet_task.h"
+#include "echonet_lcl_task.h"
+
+typedef struct ecn_agent_buffer
+{
+	union{
+		struct ecn_agent_buffer *free;
+		ecn_agent_queue_t queue;
+	};
+	union{
+		ecn_obj_t obj;
+		ecn_node_t node;
+		ecn_device_t device;
+	};
+} ecn_agent_buffer_t;
+
+typedef struct ecn_agent
+{
+	EPRPINIB eprpinib;
+	ecn_agent_queue_t nodes;
+	ecn_node_t *current_node;
+	bool_t msg_proced;
+	int blkpos;
+	ecn_agent_buffer_t *free;
+	ecn_agent_buffer_t blockes[TNUM_AEOBJID];
+	int requestid;
+} ecn_agent_t;
+
+static ER ecn_agent_proc_get_device_list(ecn_agent_t *agent, ECN_FBS_ID req);
+static ER ecn_agent_proc_get_device_info(ecn_agent_t *agent, ECN_FBS_ID req);
+static void ecn_node_send_set_prop_map(ecn_node_t *node);
+static void ecn_node_send_get_prop_map(ecn_node_t *node);
+static void ecn_node_send_anno_prop_map(ecn_node_t *node);
+static void ecn_node_timeout_on_start(ecn_node_t *node);
+static void ecn_node_next_proc_on_set_prpmap_wait(ecn_node_t *node, ecn_obj_t *sobj);
+static void ecn_node_timeout_on_set_prpmap_wait(ecn_node_t *node);
+static void ecn_node_next_proc_on_get_prpmap_wait(ecn_node_t *node, ecn_obj_t *sobj);
+static void ecn_node_timeout_on_get_prpmap_wait(ecn_node_t *node);
+static void ecn_node_next_proc_on_anno_prpmap_wait(ecn_node_t *node, ecn_obj_t *sobj);
+static void ecn_node_timeout_on_anno_prpmap_wait(ecn_node_t *node);
+
+int ecn_agent_eprpset(const EPRPINIB *item, const void *src, int size, bool_t *anno);
+int ecn_agent_eprpget(const EPRPINIB *item, void *dst, int size);
+
+static ecn_agent_queue_t *cast_queue(ecn_obj_t *obj)
+{
+	return (ecn_agent_queue_t *)((intptr_t)obj - offsetof(ecn_agent_buffer_t, obj));
+}
+
+static ecn_obj_t *cast_obj(ecn_agent_queue_t *queue)
+{
+	return (ecn_obj_t *)((intptr_t)queue + offsetof(ecn_agent_buffer_t, obj));
+}
+
+static ecn_node_t *cast_node(const EOBJCB *eobj)
+{
+	return (ecn_node_t *)((intptr_t)eobj - offsetof(ecn_node_t, eobj));
+}
+
+static ecn_obj_t *cast_obj2(const EOBJINIB *inib)
+{
+	return (ecn_obj_t *)((intptr_t)inib - offsetof(ecn_obj_t, inib));
+}
+
+static ecn_agent_t *cast_agent(const EPRPINIB *inib)
+{
+	return (ecn_agent_t *)((intptr_t)inib - offsetof(ecn_agent_t, eprpinib));
+}
+
+ecn_agent_t g_ecn_agent = {
+	/*eprpinib*/{
+		0x00,
+		EPC_RULE_SET | EPC_RULE_GET,
+		255,
+		(intptr_t)&g_ecn_agent,
+		ecn_agent_eprpset,
+		ecn_agent_eprpget
+	},
+};
+
+ER get_buf(ecn_agent_t *agent, ecn_agent_buffer_t **buf)
+{
+	ER ret = E_OK;
+
+	loc_cpu();
+
+	if (agent->blkpos < TNUM_AEOBJID) {
+		*buf = &agent->blockes[agent->blkpos++];
+	}
+	else if (agent->free == NULL) {
+		ret = E_TMOUT;
+	}
+	else{
+		*buf = agent->free;
+		agent->free = agent->free->free;
+	}
+
+	unl_cpu();
+
+	return ret;
+}
+
+ER rel_buf(ecn_agent_t *agent, ecn_agent_buffer_t *buf)
+{
+	if ((buf < &agent->blockes[0]) || (buf >= &agent->blockes[TNUM_AEOBJID]))
+		return E_PAR;
+
+	if ((((intptr_t)buf - (intptr_t)&agent->blockes[0]) % sizeof(ecn_agent_buffer_t)) != 0)
+		return E_PAR;
+
+	loc_cpu();
+
+	if (agent->free == NULL) {
+		agent->free = buf;
+		agent->free->free = NULL;
+	}
+	else {
+		ecn_agent_buffer_t *next = agent->free;
+		agent->free = buf;
+		agent->free->free = next;
+	}
+
+	unl_cpu();
+
+	return E_OK;
+}
+
+/*
+ *  L
+[Ìú»
+ *
+ *  p_queueÉÍL
+[wb_ðwè·éD
+ */
+Inline void
+ecn_agent_queue_init(ecn_agent_queue_t *p_queue)
+{
+#ifdef _DEBUG
+	p_queue->p_parent = p_queue;
+#endif
+	p_queue->p_prev = p_queue;
+	p_queue->p_next = p_queue;
+}
+
+/*
+ *  L
+[ÌOGgÖÌ}ü
+ *
+ *  p_queueÌOÉp_entryð}ü·éDp_queueÉL
+[wb_ðwèµ½ê
+ *  ÉÍCL
+[ÌöÉp_entryð}ü·é±ÆÉÈéD
+ */
+Inline void
+ecn_agent_queue_add(ecn_agent_queue_t *p_queue, ecn_agent_queue_t *p_entry)
+{
+#ifdef _DEBUG
+	assert((p_queue->p_parent == p_queue) && (p_entry->p_parent == NULL));
+	p_entry->p_parent = p_queue;
+#endif
+	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;
+}
+
+/*
+ *  GgÌí
+ *
+ *  p_entryðL
+[©çí·éD
+ */
+Inline void
+ecn_agent_queue_remove(ecn_agent_queue_t *p_queue, ecn_agent_queue_t *p_entry)
+{
+#ifdef _DEBUG
+	assert((p_queue->p_parent == p_queue) && (p_entry->p_parent == p_queue));
+	p_entry->p_parent = NULL;
+#endif
+	p_entry->p_prev->p_next = p_entry->p_next;
+	p_entry->p_next->p_prev = p_entry->p_prev;
+}
+
+ecn_node_t *ecn_agent_find_node(ECN_ENOD_ID enodid)
+{
+	ecn_agent_t *agent = &g_ecn_agent;
+	ecn_agent_queue_t *queue = agent->nodes.p_next;
+#ifdef _DEBUG
+	assert(queue->p_parent == &agent->nodes);
+#endif
+	for (; queue != &agent->nodes; queue = queue->p_next) {
+		ecn_node_t *node = (ecn_node_t *)cast_obj(queue);
+		if(node->enodId == enodid)
+			return node;
+	}
+
+	return NULL;
+}
+
+ecn_node_t *ecn_agent_find_node2(const EOBJCB *pk_eobj)
+{
+	ecn_agent_t *agent = &g_ecn_agent;
+	ecn_agent_queue_t *queue;
+
+	if(pk_eobj == NULL)
+		return NULL;
+
+	queue = agent->nodes.p_next;
+#ifdef _DEBUG
+	assert(queue->p_parent == &agent->nodes);
+#endif
+	for (; queue != &agent->nodes; queue = queue->p_next) {
+		ecn_node_t *node = (ecn_node_t *)cast_obj(queue);
+		if(&node->eobj == pk_eobj)
+			return node;
+	}
+
+	return NULL;
+}
+
+ecn_obj_t *ecn_agent_find_eobj(const EOBJCB *pk_nod, T_ECN_EOJ eoj)
+{
+	ecn_agent_queue_t *devices = &cast_node(pk_nod)->devices;
+	ecn_agent_queue_t *queue = devices->p_next;
+#ifdef _DEBUG
+	assert(queue->p_parent == devices);
+#endif
+	for (; queue != devices; queue = queue->p_next) {
+		ecn_obj_t *obj = cast_obj(queue);
+		if (obj->inib.eojx1 != eoj.eojx1)
+			continue;
+		if (obj->inib.eojx2 != eoj.eojx2)
+			continue;
+		if (obj->inib.eojx3 != eoj.eojx3)
+			continue;
+
+		return obj;
+	}
+
+	return NULL;
+}
+
+ecn_obj_t *ecn_agent_find_obj2(ecn_node_t *pk_nod, const EOBJINIB *pk_obj)
+{
+	ecn_agent_queue_t *devices = &pk_nod->devices;
+	ecn_agent_queue_t *queue = devices->p_next;
+#ifdef _DEBUG
+	assert(queue->p_parent == devices);
+#endif
+	for (; queue != devices; queue = queue->p_next) {
+		ecn_obj_t *obj = cast_obj(queue);
+		if (&obj->inib == pk_obj)
+			return obj;
+	}
+
+	return NULL;
+}
+
+ID ecn_agent_get_eobj(const EOBJINIB *pk_obj)
+{
+	return cast_obj2(pk_obj)->eobjId;
+}
+
+const EOBJINIB *ecn_agent_next_eobj(const EOBJCB *pk_nod, const EOBJINIB *pk_obj)
+{
+	ecn_agent_queue_t *devices = &cast_node(pk_nod)->devices;
+	ecn_obj_t *device = (ecn_obj_t *)pk_obj->exinf;
+	ecn_agent_queue_t *queue = cast_queue(device);
+#ifdef _DEBUG
+	assert(queue->p_parent == devices);
+#endif
+	if (queue == devices)
+		return NULL;
+
+	return &cast_obj(queue->p_next)->inib;
+}
+
+bool_t ecn_agent_get_eoj_enodid(ID eobjid, T_ECN_EOJ *eoj, ECN_ENOD_ID *enodid)
+{
+	ecn_agent_t *agent = &g_ecn_agent;
+	ecn_agent_buffer_t *buf;
+	int i = eobjid;
+
+	/* IuWFNgID©çÀÌðæ¾ */
+	i -= (tmax_eobjid + 1);
+	if ((i < 0)
+		|| (i >= (sizeof(agent->blockes) / sizeof(agent->blockes[0])))){
+		return false;
+	}
+
+	buf = &agent->blockes[i];
+	if(buf->obj.eobjId != eobjid)
+		return false;
+
+	/* IuWFNgÌEOJðRs[ */
+	memcpy(eoj, &buf->obj.inib.eojx1, sizeof(*eoj));
+
+	/* ®·ém[hÌIuWFNgIDðæ¾ */
+	if(buf->obj.inib.enodid == 0)
+		i = buf->obj.eobjId;
+	else
+		i = buf->obj.inib.enodid;
+
+	i -= (tmax_eobjid + 1);
+	if ((i < 0)
+		|| (i >= (sizeof(agent->blockes) / sizeof(agent->blockes[0])))){
+		return false;
+	}
+
+	/* m[hIDðæ¾ */
+	buf = &agent->blockes[i];
+	*enodid = buf->node.enodId;
+
+	return true;
+}
+
+void ecn_agent_set_epc_to_prop_map(uint8_t epc, uint8_t *propMap)
+{
+	int i, j;
+	assert((epc & 0x80) != 0);
+	i = epc & 0xF;
+	j = (epc >> 4) - 8;
+	propMap[i] |= (1 << j);
+}
+
+bool_t ecn_agent_contains_epc_in_prop_map(uint8_t epc, uint8_t *propMap)
+{
+	int i, j;
+	assert((epc & 0x80) != 0);
+	i = epc & 0xF;
+	j = (epc >> 4) - 8;
+	return (propMap[i] & (1 << j)) != 0;
+}
+
+void ecn_agent_init(void)
+{
+	ecn_agent_queue_init(&g_ecn_agent.nodes);
+}
+
+ecn_node_t *ecn_agent_create_node(ecn_agent_t *agent, T_EDATA *esv)
+{
+	ecn_agent_buffer_t *result = NULL;
+	ecn_node_t *node;
+	uint8_t epc;
+	uint8_t pdc;
+	uint8_t edt[256];
+	T_ENUM_EPC enm;
+	ER ret;
+	T_ECN_EOJ *eoj, *end;
+
+	// vpeBÊm©æ¾ÅA
+	switch (esv->hdr.edata.esv) {
+	case ESV_GET_RES:
+	case ESV_GET_SNA:
+	case ESV_INF:
+		break;
+	default:
+		return NULL;
+	}
+
+	// m[hvt@C¶Ìê
+	eoj = &esv->hdr.edata.seoj;
+	if ((eoj->eojx1 != EOJ_X1_PROFILE) || (eoj->eojx2 != EOJ_X2_NODE_PROFILE)
+		|| (eoj->eojx3 != 0x01))
+		return NULL;
+
+	ret = ecn_itr_ini(&enm, esv);
+	if(ret != E_OK){
+		syslog(LOG_WARNING, "ecn_itr_ini");
+	}
+
+	while (ecn_itr_nxt(&enm, &epc, &pdc, &edt) == E_OK) {
+		switch (epc) {
+		// CX^XXgÊmÌê
+		case 0xD5:
+		// ©m[hCX^XXgrÊmÌê
+		case 0xD6:
+			// TCYªíÈ¢ê
+			if (pdc != (1 + edt[0] * sizeof(T_ECN_EOJ)))
+				return NULL;
+
+			ret = get_buf(agent, &result);
+			if(ret != E_OK){
+				syslog(LOG_WARNING, "get_buf");
+				return NULL;
+			}
+
+			memset(result, 0, sizeof(*result));
+			node = &result->node;
+			node->enodId = ((T_ECN_FST_BLK *)esv)->hdr.sender.id;
+			node->base.eobjId = tmax_eobjid + 1 + (((intptr_t)result - (intptr_t)agent->blockes) / sizeof(agent->blockes[0]));
+			node->base.inib.enodid = 0;
+			node->base.inib.eobjatr = EOBJ_SYNC_REMOTE_NODE;
+			node->base.inib.exinf = (intptr_t)node;
+			node->base.inib.eojx1 = eoj->eojx1;
+			node->base.inib.eojx2 = eoj->eojx2;
+			node->base.inib.eojx3 = eoj->eojx3;
+			node->base.inib.eprp = &agent->eprpinib;
+			node->base.inib.eprpcnt = 0;
+			ecn_agent_set_epc_to_prop_map(0xD5, node->base.pmapGet);
+			ecn_agent_set_epc_to_prop_map(0xD6, node->base.pmapGet);
+			ecn_agent_set_epc_to_prop_map(0x9D, node->base.pmapGet);
+			ecn_agent_set_epc_to_prop_map(0x9E, node->base.pmapGet);
+			ecn_agent_set_epc_to_prop_map(0x9F, node->base.pmapGet);
+			ecn_agent_queue_init(&node->devices);
+			node->eobj.profile = &node->base.inib;
+			node->eobj.eobjs = NULL;
+			node->eobj.eobjcnt = pdc / 3;
+			node->state = ecn_node_state_idle;
+			node->timer = TMO_FEVR;
+
+			end = (T_ECN_EOJ *)&edt[pdc];
+			for (eoj = (T_ECN_EOJ *)&edt[1]; eoj < end; eoj++) {
+				ecn_device_t *device;
+				ecn_agent_buffer_t *obj;
+
+				ret  = get_buf(agent, &obj);
+				if(ret != E_OK){
+					syslog(LOG_WARNING, "get_buf");
+					return NULL;
+				}
+
+				memset(obj, 0, sizeof(*obj));
+				device = &obj->device;
+				device->node = node;
+				device->base.eobjId = tmax_eobjid + 1 + (((intptr_t)obj - (intptr_t)agent->blockes) / sizeof(agent->blockes[0]));
+				device->base.inib.eobjatr = EOBJ_DEVICE;
+				device->base.inib.enodid = node->base.eobjId;
+				device->base.inib.exinf = (intptr_t)device;
+				device->base.inib.eojx1 = eoj->eojx1;
+				device->base.inib.eojx2 = eoj->eojx2;
+				device->base.inib.eojx3 = eoj->eojx3;
+				device->base.inib.eprp = &agent->eprpinib;
+				device->base.inib.eprpcnt = 0;
+				ecn_agent_set_epc_to_prop_map(0x9D, device->base.pmapGet);
+				ecn_agent_set_epc_to_prop_map(0x9E, device->base.pmapGet);
+				ecn_agent_set_epc_to_prop_map(0x9F, device->base.pmapGet);
+
+				ecn_agent_queue_add(&node->devices, &obj->queue);
+			}
+			break;
+		default:
+			continue;
+		}
+		break;
+	}
+
+	if (result == NULL)
+		return NULL;
+
+	ecn_agent_queue_add(&agent->nodes, &result->queue);
+
+	return node;
+}
+
+static ER ecn_agent_proc_get_device_list(ecn_agent_t *agent, ECN_FBS_ID req)
+{
+	ER ret;
+	ECN_FBS_ID res;
+	ecn_inm_get_device_list_req_t msg;
+	ECN_FBS_SSIZE_T len;
+	ecn_agent_buffer_t *pos, *end = &agent->blockes[TNUM_AEOBJID];
+	ecn_inm_get_device_item_t item;
+
+	ret = _ecn_fbs_get_data(req, &msg, sizeof(msg), &len);
+	if (ret != E_OK) {
+		return ret;
+	}
+
+	ret = _ecn_tsk_cre_res_fbs(req, ECN_INM_GET_DEVICE_LIST_RES, &res);
+	if (ret != E_OK) {
+		return ret;
+	}
+
+	ret = _ecn_fbs_add_data_ex(res, &msg.requestid, sizeof(((ecn_inm_get_device_list_res_t *)0)->requestid));
+	if (ret != E_OK) {
+		_ecn_fbs_del(res);
+		return ret;
+	}
+
+	for (pos = &agent->blockes[0]; pos < end; pos++){
+		if(pos->obj.eobjId == 0)
+			continue;
+
+		item.eobjid = pos->obj.eobjId;
+		item.enodid = pos->obj.inib.enodid;
+		item.eojx1 = pos->obj.inib.eojx1;
+		item.eojx2 = pos->obj.inib.eojx2;
+		item.eojx3 = pos->obj.inib.eojx3;
+
+		if(pos->device.node != NULL)
+			item.addrid = pos->device.node->enodId;
+		else
+			item.addrid = pos->node.enodId;
+
+		ret = _ecn_fbs_add_data_ex(res, &item, sizeof(item));
+		if (ret != E_OK) {
+			_ecn_fbs_del(res);
+			return ret;
+		}
+	}
+
+	ret = psnd_dtq(res.ptr->hdr.target.mbxid, (intptr_t)res.ptr);
+	if (ret != E_OK) {
+		_ecn_fbs_del(res);
+		return ret;
+	}
+
+	return E_OK;
+}
+
+static ER ecn_agent_proc_get_device_info(ecn_agent_t *agent, ECN_FBS_ID req)
+{
+	ER ret;
+	ECN_FBS_ID res;
+	ecn_inm_get_device_info_req_t msg;
+	ecn_inm_get_device_info_res_t rmsg;
+	ECN_FBS_SSIZE_T len;
+	int eobjId;
+	ecn_agent_buffer_t *pos;
+
+	ret = _ecn_fbs_get_data(req, &msg, sizeof(msg), &len);
+	if (ret != E_OK) {
+		return ret;
+	}
+
+	eobjId = msg.eobjid - tmax_eobjid - 1;
+	pos = &agent->blockes[eobjId];
+
+	ret = _ecn_tsk_cre_res_fbs(req, ECN_INM_GET_DEVICE_INFO_RES, &res);
+	if (ret != E_OK) {
+		return ret;
+	}
+
+	rmsg.requestid = msg.requestid;
+	rmsg.eobjid = pos->obj.eobjId;
+	memcpy(rmsg.pmapSet, pos->obj.pmapSet, sizeof(rmsg.pmapSet));
+	memcpy(rmsg.pmapGet, pos->obj.pmapGet, sizeof(rmsg.pmapGet));
+	memcpy(rmsg.pmapAnno, pos->obj.pmapAnno, sizeof(rmsg.pmapAnno));
+	rmsg.eprpcnt = pos->obj.eprpcnt;
+
+	ret = _ecn_fbs_add_data_ex(res, &rmsg, sizeof(rmsg));
+	if (ret != E_OK) {
+		_ecn_fbs_del(res);
+		return ret;
+	}
+
+	ret = psnd_dtq(res.ptr->hdr.target.mbxid, (intptr_t)res.ptr);
+	if (ret != E_OK) {
+		_ecn_fbs_del(res);
+		return ret;
+	}
+
+	return E_OK;
+}
+
+TMO ecn_agent_get_timer()
+{
+	TMO timer = TMO_FEVR, temp;
+	ecn_agent_t *agent = &g_ecn_agent;
+	ecn_node_t *node;
+	ecn_agent_queue_t *queue;
+
+	queue = &agent->nodes;
+	for (;;) {
+		queue = queue->p_next;
+#ifdef _DEBUG
+		assert(queue->p_parent == &agent->nodes);
+#endif
+		if(&agent->nodes == queue)
+			break;
+
+		node = (ecn_node_t *)cast_obj(queue);
+		temp = node->timer;
+		if (temp != TMO_FEVR) {
+			if ((timer == TMO_FEVR) || (temp < timer)) {
+				timer = temp;
+			}
+		}
+	}
+
+	return timer;
+}
+
+void ecn_agent_progress(TMO interval)
+{
+	ecn_agent_t *agent = &g_ecn_agent;
+	ecn_node_t *node;
+	ecn_agent_queue_t *queue;
+
+	queue = &agent->nodes;
+	for (;;) {
+		queue = queue->p_next;
+#ifdef _DEBUG
+		assert(queue->p_parent == &agent->nodes);
+#endif
+		if(&agent->nodes == queue)
+			break;
+
+		node = (ecn_node_t *)cast_obj(queue);
+		if (node->timer == TMO_FEVR)
+			continue;
+
+		node->timer -= interval;
+		if (node->timer <= 0) {
+			node->timer = 0;
+		}
+	}
+}
+
+void ecn_agent_timeout()
+{
+	ecn_agent_t *agent = &g_ecn_agent;
+	ecn_node_t *node;
+	ecn_agent_queue_t *queue;
+
+	queue = &agent->nodes;
+	for (;;) {
+		queue = queue->p_next;
+#ifdef _DEBUG
+		assert(queue->p_parent == &agent->nodes);
+#endif
+		if(&agent->nodes == queue)
+			break;
+
+		node = (ecn_node_t *)cast_obj(queue);
+		if (node->timer != 0)
+			continue;
+
+		switch (node->state) {
+		case ecn_node_state_start:
+			ecn_node_timeout_on_start(node);
+			break;
+		case ecn_node_state_set_prpmap_wait:
+			ecn_node_timeout_on_set_prpmap_wait(node);
+			break;
+		case ecn_node_state_get_prpmap_wait:
+			ecn_node_timeout_on_get_prpmap_wait(node);
+			break;
+		case ecn_node_state_anno_prpmap_wait:
+			ecn_node_timeout_on_anno_prpmap_wait(node);
+			break;
+		default:
+			assert(0);
+		}
+	}
+}
+
+bool_t ecn_agent_proc_int_msg(ECN_FBS_ID fbs, uint8_t cmd)
+{
+	ecn_agent_t *agent = &g_ecn_agent;
+
+	switch(cmd)
+	{
+	case ECN_INM_GET_DEVICE_LIST_REQ:
+		ecn_agent_proc_get_device_list(agent, fbs);
+		break;
+	case ECN_INM_GET_DEVICE_INFO_REQ:
+		ecn_agent_proc_get_device_info(agent, fbs);
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+void ecn_agent_proc_ecn_msg(const EOBJCB **ppk_snod, const EOBJINIB **ppk_sobj, T_EDATA *esv)
+{
+	ecn_agent_t *agent = &g_ecn_agent;
+	ecn_node_t *snod;
+	ecn_obj_t *sobj;
+
+	/* ÃIÉè`³ê½M³Ìê */
+	if ((*ppk_snod != NULL) && (*ppk_snod)->eobjs != NULL) {
+		/* µÈ¢ */
+		return;
+	}
+
+	snod = ecn_agent_find_node2(*ppk_snod);
+
+	/* M³ðmçÈ©Á½ç */
+	if (snod == NULL) {
+		/* M³Ìm[hîñðVKÉì¬ */
+		snod = ecn_agent_create_node(agent, esv);
+		if (snod == NULL)
+			return;
+	}
+
+	sobj = ecn_agent_find_obj2(snod, *ppk_sobj);
+
+	/* m[hvt@CÌê */
+	if ((esv->hdr.edata.seoj.eojx1 == EOJ_X1_PROFILE)
+		&& (esv->hdr.edata.seoj.eojx2 == EOJ_X2_NODE_PROFILE)) {
+		sobj = &snod->base;
+	}
+	/* @íIuWFNgÌê */
+	else {
+		sobj = ecn_agent_find_eobj(&snod->eobj, esv->hdr.edata.seoj);
+	}
+
+	*ppk_snod = &snod->eobj;
+	*ppk_sobj = &sobj->inib;
+
+	agent->current_node = snod;
+	agent->msg_proced = false;
+}
+
+void ecn_agent_proc_ecn_msg_end()
+{
+	ecn_agent_t *agent = &g_ecn_agent;
+	ecn_node_t *node = agent->current_node;
+	ecn_obj_t *sobj;
+
+	if(node == NULL)
+		return;
+
+	sobj = node->current;
+	if(sobj == NULL)
+		return;
+
+	if (agent->msg_proced) {
+		switch (node->state) {
+		case ecn_node_state_set_prpmap_wait:
+			ecn_node_next_proc_on_set_prpmap_wait(node, sobj);
+			break;
+		case ecn_node_state_get_prpmap_wait:
+			ecn_node_next_proc_on_get_prpmap_wait(node, sobj);
+			break;
+		case ecn_node_state_anno_prpmap_wait:
+			ecn_node_next_proc_on_anno_prpmap_wait(node, sobj);
+			break;
+		}
+	}
+}
+
+static void ecn_node_send_set_prop_map(ecn_node_t *node)
+{
+	T_EDATA *esv;
+	ecn_obj_t *obj = node->current;
+
+	// vpeBlÇÝoµv
+	ecn_esv_get(&esv, obj->eobjId, 0x9E);
+	ecn_snd_esv(esv);
+
+	node->state = ecn_node_state_set_prpmap_wait;
+	node->timer = (TMO)5000;
+}
+
+static void ecn_node_send_get_prop_map(ecn_node_t *node)
+{
+	T_EDATA *esv;
+	ecn_obj_t *obj = node->current;
+
+	// vpeBlÇÝoµv
+	ecn_esv_get(&esv, obj->eobjId, 0x9F);
+	ecn_snd_esv(esv);
+
+	node->state = ecn_node_state_get_prpmap_wait;
+	node->timer = (TMO)5000;
+}
+
+static void ecn_node_send_anno_prop_map(ecn_node_t *node)
+{
+	T_EDATA *esv;
+	ecn_obj_t *obj = node->current;
+
+	// vpeBlÇÝoµv
+	ecn_esv_get(&esv, obj->eobjId, 0x9D);
+	ecn_snd_esv(esv);
+
+	node->state = ecn_node_state_anno_prpmap_wait;
+	node->timer = (TMO)5000;
+}
+
+static void ecn_node_next_obj(ecn_node_t *node)
+{
+	ecn_obj_t *obj = node->current;
+	ecn_agent_queue_t *queue;
+	ecn_device_t *device;
+
+	/* objªwè³êÄ¢È¢ê */
+	if(obj == NULL){
+		/* ±Ìm[hðÔ· */
+		node->current = &node->base;
+		return;
+	}
+	/* m[hÌê */
+	else if((obj->inib.eojx1 == EOJ_X1_PROFILE) && (obj->inib.eojx2 == EOJ_X2_NODE_PROFILE)){
+		node = (ecn_node_t *)obj;
+
+		/* zºÌ@íðÔ· */
+		queue = node->devices.p_next;
+		device = (ecn_device_t *)cast_obj(queue);
+	}
+	/* @íÌê */
+	else{
+		/* Ì@íðÔ· */
+		node = ((ecn_device_t *)obj)->node;
+		queue = cast_queue(obj)->p_next;
+		device = (ecn_device_t *)cast_obj(queue);
+	}
+
+	/* »Ì@íªö¾Á½ê */
+	if(&node->devices == queue){
+		node->current = NULL;
+	}
+	else {
+		node->current = &device->base;
+	}
+}
+
+static void ecn_node_timeout_on_start(ecn_node_t *node)
+{
+	for (;;) {
+		ecn_obj_t *obj = node->current;
+		if (obj == NULL) {
+			node->state = ecn_node_state_idle;
+			node->timer = TMO_FEVR;
+			return;
+		}
+
+		if((obj->pmapFlag & PMAP_FLAG_SET) == 0){
+			ecn_node_send_set_prop_map(node);
+			break;
+		}
+		else if((obj->pmapFlag & PMAP_FLAG_GET) == 0){
+			ecn_node_send_get_prop_map(node);
+			break;
+		}
+		else if((obj->pmapFlag & PMAP_FLAG_ANNO) == 0){
+			ecn_node_send_anno_prop_map(node);
+			break;
+		}
+		else{
+			ecn_node_next_obj(node);
+		}
+	}
+}
+
+static void ecn_node_next_proc_on_set_prpmap_wait(ecn_node_t *node, ecn_obj_t *sobj)
+{
+	if((sobj->pmapFlag & PMAP_FLAG_GET) == 0){
+		ecn_node_send_get_prop_map(node);
+	}
+	else if((sobj->pmapFlag & PMAP_FLAG_ANNO) == 0){
+		ecn_node_send_anno_prop_map(node);
+	}
+	else if((sobj->pmapFlag & PMAP_FLAG_SET) == 0){
+		ecn_node_send_set_prop_map(node);
+	}
+	else{
+		ecn_node_next_obj(node);
+		ecn_node_timeout_on_start(node);
+	}
+}
+
+static void ecn_node_timeout_on_set_prpmap_wait(ecn_node_t *node)
+{
+	ecn_obj_t *obj = node->current;
+	if(obj == NULL){
+		node->state = ecn_node_state_idle;
+		node->timer = TMO_FEVR;
+		return;
+	}
+
+	ecn_node_next_proc_on_set_prpmap_wait(node, obj);
+}
+
+static void ecn_node_next_proc_on_get_prpmap_wait(ecn_node_t *node, ecn_obj_t *sobj)
+{
+	if((sobj->pmapFlag & PMAP_FLAG_ANNO) == 0){
+		ecn_node_send_anno_prop_map(node);
+	}
+	else if((sobj->pmapFlag & PMAP_FLAG_SET) == 0){
+		ecn_node_send_set_prop_map(node);
+	}
+	else if((sobj->pmapFlag & PMAP_FLAG_GET) == 0){
+		ecn_node_send_get_prop_map(node);
+	}
+	else{
+		ecn_node_next_obj(node);
+		ecn_node_timeout_on_start(node);
+	}
+}
+
+static void ecn_node_timeout_on_get_prpmap_wait(ecn_node_t *node)
+{
+	ecn_obj_t *obj = node->current;
+	if(obj == NULL){
+		node->state = ecn_node_state_idle;
+		node->timer = TMO_FEVR;
+		return;
+	}
+
+	ecn_node_next_proc_on_get_prpmap_wait(node, obj);
+}
+
+static void ecn_node_next_proc_on_anno_prpmap_wait(ecn_node_t *node, ecn_obj_t *sobj)
+{
+	if((sobj->pmapFlag & PMAP_FLAG_SET) == 0){
+		ecn_node_send_set_prop_map(node);
+	}
+	else if((sobj->pmapFlag & PMAP_FLAG_GET) == 0){
+		ecn_node_send_get_prop_map(node);
+	}
+	else if((sobj->pmapFlag & PMAP_FLAG_ANNO) == 0){
+		ecn_node_send_anno_prop_map(node);
+	}
+	else{
+		ecn_node_next_obj(node);
+		ecn_node_timeout_on_start(node);
+	}
+}
+
+static void ecn_node_timeout_on_anno_prpmap_wait(ecn_node_t *node)
+{
+	ecn_obj_t *obj = node->current;
+	if(obj == NULL){
+		node->state = ecn_node_state_idle;
+		node->timer = TMO_FEVR;
+		return;
+	}
+
+	ecn_node_next_proc_on_anno_prpmap_wait(node, obj);
+}
+
+const EPRPINIB *ecn_agent_get_property(const EOBJINIB *fp_obj, uint8_t fa_epc, const EPRPINIB *item)
+{
+	ecn_obj_t *obj = cast_obj2(fp_obj);
+	bool_t has = false;
+
+	/* m[hÌêÍCX^XXgÊmÆ©m[hCX^XXgrÊmðK{Åó¯æé */
+	if ((fp_obj->enodid == 0) && ((fa_epc == 0xD5) || (fa_epc == 0xD6)))
+		has = true;
+	else if (ecn_agent_contains_epc_in_prop_map(fa_epc, obj->pmapGet))
+		has = true;
+	else if (ecn_agent_contains_epc_in_prop_map(fa_epc, obj->pmapSet))
+		has = true;
+	else if (ecn_agent_contains_epc_in_prop_map(fa_epc, obj->pmapAnno))
+		has = true;
+
+	if(!has)
+		return NULL;
+
+	((EPRPINIB *)item)->eprpcd = fa_epc;
+	((EPRPINIB *)item)->exinf = (intptr_t)fp_obj;
+
+	return item;
+}
+
+int ecn_agent_eprpget(const EPRPINIB *item, void *dst, int size)
+{
+	return 0;
+}
+
+int ecn_agent_eprpset(const EPRPINIB *item, const void *src, int size, bool_t *anno)
+{
+	ecn_agent_t *agent = cast_agent(item);
+	ecn_node_t *node = agent->current_node;
+	const uint8_t *edt = (const uint8_t *)src;
+	ecn_obj_t *sobj = cast_obj2((const EOBJINIB *)item->exinf);
+	uint8_t eprpcnt;
+	int i;
+
+	switch (item->eprpcd) {
+	/* CX^XXgÊmÌê */
+	case 0xD5:
+	/* ©m[hCX^XXgrÊmÌê */
+	case 0xD6:
+		if ((node != NULL) && (node->state == ecn_node_state_idle)) {
+			ecn_agent_queue_t *devices = &node->devices;
+			ecn_agent_queue_t *queue = devices->p_next;
+#ifdef _DEBUG
+			assert(queue->p_parent == devices);
+#endif
+			for (; queue != devices; queue = queue->p_next) {
+				ecn_obj_t *obj = cast_obj(queue);
+				obj->pmapFlag = 0;
+			}
+			node->base.pmapFlag = 0;
+			node->state = ecn_node_state_start;
+			node->timer = (TMO)1000;
+			node->current = sobj;
+		}
+		break;
+	/* ÊmvpeB}bvÌê */
+	case 0x9D:
+		eprpcnt = edt[0];
+
+		if (eprpcnt < 16) {
+			/* TCY`FbN */
+			if (eprpcnt + 1 != size)
+				return 0;
+
+			for (i = 1; i < size; i++)
+				ecn_agent_set_epc_to_prop_map(edt[i], sobj->pmapAnno);
+		}
+		else {
+			/* TCY`FbN */
+			if (size != 17)
+				return 0;
+
+			memcpy(sobj->pmapAnno, &edt[1], 16);
+		}
+		sobj->eprpcnt = eprpcnt;
+		sobj->pmapFlag |= PMAP_FLAG_ANNO;
+		break;
+	/* SETvpeB}bvÌê */
+	case 0x9E:
+		eprpcnt = edt[0];
+
+		if (eprpcnt < 16) {
+			/* TCY`FbN */
+			if (eprpcnt + 1 != size)
+				return 0;
+
+			for (i = 1; i < size; i++)
+				ecn_agent_set_epc_to_prop_map(edt[i], sobj->pmapSet);
+		}
+		else {
+			/* TCY`FbN */
+			if (size != 17)
+				return 0;
+
+			memcpy(sobj->pmapSet, &edt[1], 16);
+		}
+		sobj->eprpcnt = eprpcnt;
+		sobj->pmapFlag |= PMAP_FLAG_SET;
+		break;
+	/* GETvpeB}bvÌê */
+	case 0x9F:
+		eprpcnt = edt[0];
+
+		if (eprpcnt < 16) {
+			/* TCY`FbN */
+			if (eprpcnt + 1 != size)
+				return 0;
+
+			for (i = 1; i < size; i++)
+				ecn_agent_set_epc_to_prop_map(edt[i], sobj->pmapGet);
+		}
+		else {
+			/* TCY`FbN */
+			if (size != 17)
+				return 0;
+
+			memcpy(sobj->pmapGet, &edt[1], 16);
+		}
+		sobj->eprpcnt = eprpcnt;
+		sobj->pmapFlag |= PMAP_FLAG_GET;
+		break;
+	default:
+		return 0;
+	}
+
+	agent->msg_proced = true;
+
+	return size;
+}
+
+ER ecn_agent_get_device_list(ID sender, int requestid, ECN_FBS_ID *pk_req)
+{
+	ER a_ret;
+	ECN_FBS_ID req;
+
+	a_ret = _ecn_tsk_cre_req_fbs(sender, ECN_INM_GET_DEVICE_LIST_REQ, &req);
+	if (a_ret != E_OK) {
+		return a_ret;
+	}
+
+	a_ret = _ecn_fbs_add_data_ex(req, &requestid, sizeof(((ecn_inm_get_device_list_req_t *)0)->requestid));
+	if (a_ret != E_OK) {
+		_ecn_fbs_del(req);
+		return a_ret;
+	}
+
+	*pk_req = req;
+
+	return E_OK;
+}
+
+ER ecn_agent_get_device_info(ID sender, int requestid, ID eobjid, ECN_FBS_ID *pk_req)
+{
+	ER a_ret;
+	ECN_FBS_ID req;
+
+	a_ret = _ecn_tsk_cre_req_fbs(sender, ECN_INM_GET_DEVICE_INFO_REQ, &req);
+	if (a_ret != E_OK) {
+		return a_ret;
+	}
+
+	a_ret = _ecn_fbs_add_data_ex(req, &requestid, sizeof(((ecn_inm_get_device_info_req_t *)0)->requestid));
+	if (a_ret != E_OK) {
+		_ecn_fbs_del(req);
+		return a_ret;
+	}
+
+	a_ret = _ecn_fbs_add_data_ex(req, &eobjid, sizeof(((ecn_inm_get_device_info_req_t *)0)->eobjid));
+	if (a_ret != E_OK) {
+		_ecn_fbs_del(req);
+		return a_ret;
+	}
+
+	*pk_req = req;
+
+	return E_OK;
+}
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_agent.h
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_agent.h	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_agent.h	(revision 164)
@@ -0,0 +1,182 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2015 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ECHONET Lite ®I¶¬m[h
+ */
+
+#ifndef ECHONET_NODE_H
+#define ECHONET_NODE_H
+
+#include "echonet.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TNUM_AEOBJID 50
+
+/*
+ *  L
+[Ìf[^\¢Ìè`
+ */
+typedef struct ecn_agent_queue {
+#ifdef _DEBUG
+	struct ecn_agent_queue *p_parent;	/* eL
+[ÖÌ|C^ */
+#endif
+	struct ecn_agent_queue *p_next;		/* GgÖÌ|C^ */
+	struct ecn_agent_queue *p_prev;		/* OGgÖÌ|C^ */
+} ecn_agent_queue_t;
+
+#define PMAP_FLAG_SET	0x01
+#define PMAP_FLAG_GET	0x02
+#define PMAP_FLAG_ANNO	0x04
+
+typedef struct ecn_obj
+{
+	ID eobjId;
+	EOBJINIB inib;
+	uint8_t pmapFlag;
+	uint8_t pmapSet[16];		/* SETvpeB}bv */
+	uint8_t pmapGet[16];		/* GETvpeB}bv */
+	uint8_t pmapAnno[16];		/* óÔÏ»ÊmvpeB}bv */
+	uint_t eprpcnt;				/* ECHONET Lite vpeB */
+} ecn_obj_t;
+
+typedef enum ecn_node_state
+{
+	ecn_node_state_idle,
+	ecn_node_state_start,
+	ecn_node_state_set_prpmap_wait,
+	ecn_node_state_get_prpmap_wait,
+	ecn_node_state_anno_prpmap_wait,
+} ecn_node_state_t;
+
+typedef struct ecn_node
+{
+	ecn_obj_t base;
+	EOBJCB eobj;
+	ECN_ENOD_ID enodId;
+	ecn_agent_queue_t devices;
+	ecn_node_state_t state;
+	TMO timer;
+	ecn_obj_t *current;
+} ecn_node_t;
+
+typedef struct ecn_device
+{
+	ecn_obj_t base;
+	ecn_node_t *node;
+} ecn_device_t;
+
+typedef struct ecn_inm_get_device_list_req
+{
+	unsigned int requestid;
+} ecn_inm_get_device_list_req_t;
+
+typedef struct ecn_inm_get_device_item
+{
+	ID			eobjid;			/* ECHONET Lite IuWFNgID */
+	ID			enodid;			/* ECHONET Lite m[hvt@CIuWFNgID */
+	uint8_t		eojx1;			/* ECHONET Lite IuWFNgÌNXO[vR[h */
+	uint8_t		eojx2;			/* ECHONET Lite IuWFNgÌNXR[h */
+	uint8_t		eojx3;			/* ECHONET Lite IuWFNgÌCX^XR[h */
+	ECN_ENOD_ID	addrid;			/* IPAhXæ¾pID */
+} ecn_inm_get_device_item_t;
+
+typedef struct ecn_inm_get_device_list_res
+{
+	unsigned int requestid;
+	ecn_inm_get_device_item_t devices[1];
+} ecn_inm_get_device_list_res_t;
+
+typedef struct ecn_inm_get_device_info_req
+{
+	unsigned int requestid;
+	ID eobjid;
+} ecn_inm_get_device_info_req_t;
+
+typedef struct ecn_inm_get_device_info_res
+{
+	unsigned int requestid;
+	ID eobjid;
+	uint8_t pmapSet[16];
+	uint8_t pmapGet[16];
+	uint8_t pmapAnno[16];
+	uint_t eprpcnt;
+} ecn_inm_get_device_info_res_t;
+
+/* ú» */
+void ecn_agent_init(void);
+/* m[hðõ */
+ecn_node_t *ecn_agent_find_node(ECN_ENOD_ID enodid);
+/* @íðõ */
+ecn_obj_t *ecn_agent_find_eobj(const EOBJCB *pk_nod, T_ECN_EOJ eoj);
+/* IuWFNgIDðæ¾ */
+ID ecn_agent_get_eobj(const EOBJINIB *pk_obj);
+/* Ì@íðæ¾ */
+const EOBJINIB *ecn_agent_next_eobj(const EOBJCB *pk_nod, const EOBJINIB *pk_obj);
+/* IuWFNgID©çEOJÆm[hIDðæ¾ */
+bool_t ecn_agent_get_eoj_enodid(ID eobjid, T_ECN_EOJ *eoj, ECN_ENOD_ID *enodid);
+/* ^CAEglðÔ· */
+TMO ecn_agent_get_timer();
+/* ^C}[ÌÔðißé */
+void ecn_agent_progress(TMO interval);
+/* ^CAEgiÌ½ßÌÄÑoµj */
+void ecn_agent_timeout();
+/* àbZ[W */
+bool_t ecn_agent_proc_int_msg(ECN_FBS_ID fbs, uint8_t cmd);
+/* ECHONETd¶óM */
+void ecn_agent_proc_ecn_msg(const EOBJCB **snod, const EOBJINIB **sobj, T_EDATA *esv);
+/* ECHONETd¶óMI¹ */
+void ecn_agent_proc_ecn_msg_end();
+/* vpeBðæ¾ */
+const EPRPINIB *ecn_agent_get_property(const EOBJINIB *fp_obj, uint8_t fa_epc, const EPRPINIB *item);
+
+ER ecn_agent_get_device_list(ID sender, int requestid, ECN_FBS_ID *pk_req);
+ER ecn_agent_get_device_info(ID sender, int requestid, ID eobjid, ECN_FBS_ID *pk_req);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ECHONET_NODE_H */
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_api.csv
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_api.csv	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_api.csv	(revision 164)
@@ -0,0 +1,2 @@
+eobj,ECN_CRE_EOBJ,#eobjid { .eobjatr &enodid &exinf .eojx1 .eojx2 .eojx3 },,
+eprp,ECN_DEF_EPRP,&eobjid { .eprpcd .eprpatr .eprpsz &exinf &eprpset &eprpget },-1,
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_asp.cfg
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_asp.cfg	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_asp.cfg	(revision 164)
@@ -0,0 +1,79 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ECHONET Lite RtBM
+[Vt@C
+ */
+
+#include "itron.h"
+#include "echonet_task.h"
+#include "echonet_lcl_task.h"
+
+/*
+ * ECHONET Lite d¶ppZ}tH
+ */
+CRE_SEM(ECHONET_MEM_SEMAPHORE, { TA_TPRI, 1, 1 });
+
+/*
+ * ECHONET Lite APIp[{bNX
+ */
+CRE_MBX(ECHONET_API_MAILBOX, { TA_TFIFO, 1, NULL });
+
+/*
+ * ECHONET Lite T[rX^XNp[{bNX
+ */
+CRE_MBX(ECHONET_SVC_MAILBOX, { TA_TFIFO, 1, NULL });
+
+/*
+ * ECHONET Lite T[rX^XN
+ */
+CRE_TSK(ECHONET_SVC_TASK, { TA_HLNG, 0, echonet_task, ECHONET_TASK_PRIORITY, ECHONET_TASK_STACK_SIZE, NULL });
+
+/*
+ * ECHONET Lite UDPÊMp[{bNX
+ */
+CRE_MBX(ECHONET_UDP_MAILBOX, { TA_TFIFO, 1, NULL });
+
+/*
+ * ECHONET Lite UDPÊM^XN
+ */
+CRE_TSK(ECHONET_UDP_TASK, { TA_HLNG, 0, echonet_udp_task, ECHONET_UDP_TASK_PRIORITY, ECHONET_UDP_TASK_STACK_SIZE, NULL });
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_chk.tf
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_chk.tf	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_chk.tf	(revision 164)
@@ -0,0 +1,178 @@
+$ =====================================================================
+$ 
+$  TOPPERS ECHONET Lite Communication Middleware
+$ 
+$  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+$ 
+$  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+$  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+$  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+$  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+$       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+$      XR[hÉÜÜêÄ¢é±ÆD
+$  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+$      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+$      Ì³ÛØKèðfÚ·é±ÆD
+$  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+$      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+$      ÆD
+$    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+$        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+$    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+$        ñ·é±ÆD
+$  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+$      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+$      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+$      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+$      ÆÓ·é±ÆD
+$ 
+$  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+$  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+$  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+$  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+$  ÌÓCðíÈ¢D
+$ 
+$  @(#) $Id$
+$ 
+$ =====================================================================
+
+$ =====================================================================
+$ K{vpeBÌ`FbN
+$ =====================================================================
+
+$FUNCTION compare$
+	$RESULT = ARGV[1] - ARGV[2]$
+$END$
+
+$ vt@CIuWFNgX[p[NX
+$ProfileObjectSuperClass.EPC = { 0x88, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x9D, 0x9E, 0x9F }$
+$ProfileObjectSuperClass.MUST = { EPC_NONE, EPC_RULE_GET, EPC_NONE, EPC_NONE, EPC_NONE, EPC_NONE, EPC_RULE_GET, EPC_RULE_GET, EPC_RULE_GET }$
+
+$ m[hvt@CNX
+$NodeProfileClass.EPC = { 0x80, 0x82, 0x83, 0x89, 0xBF, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7 }$
+$NodeProfileClass.MUST = { EPC_RULE_GET, EPC_RULE_GET, EPC_RULE_GET, EPC_NONE, EPC_NONE, EPC_RULE_GET, EPC_RULE_GET, EPC_RULE_ANNO, EPC_RULE_GET, EPC_RULE_GET }$
+
+$ @íIuWFNgX[p[NX
+$DeviceSuperClass.EPC = { 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x93, 0x97, 0x98, 0x99, 0x9A, 0x9D, 0x9E, 0x9F }$
+$DeviceSuperClass.MUST = { EPC_RULE_GET, EPC_RULE_SET|EPC_RULE_GET, EPC_RULE_GET, EPC_NONE, EPC_NONE, EPC_NONE, EPC_NONE, EPC_NONE, EPC_RULE_GET, EPC_NONE, EPC_RULE_GET, EPC_NONE, EPC_NONE, EPC_NONE, EPC_NONE, EPC_NONE, EPC_NONE, EPC_NONE, EPC_NONE, EPC_NONE, EPC_NONE, EPC_RULE_GET, EPC_RULE_GET, EPC_RULE_GET }$
+
+$ResultOfGetPropertyInfo = {}$
+
+$FUNCTION GetPropertyInfo$
+	$eoj.x1 = ARGV[1]$
+	$eoj.x2 = ARGV[2]$
+	$attr = ARGV[3]$
+	$list = {}$
+	$FOREACH i { 0 , 1 , ... , 15 }$
+		$map[i] = 0x00$
+	$END$
+
+	$IF (attr != EPC_ANNOUNCE) && (attr != EPC_RULE_SET) && (attr != EPC_RULE_GET)$
+		$ERROR$$FORMAT("%1% is illegal value, must be EPC_RULE_ANNO or EPC_RULE_SET or EPC_RULE_GET.", attr)$$END$
+	$END$
+
+	$IF eoj.x1 == EOJ_X1_SENSOR$
+		$i = 0$
+		$WHILE i < LENGTH(DeviceSuperClass.EPC)$
+			$IF (AT(DeviceSuperClass.MUST, i) & attr) != 0$
+				$list = APPEND(list, AT(DeviceSuperClass.EPC, i))$
+			$END$
+			$i = i + 1$
+		$END$
+	$ELIF eoj.x1 == EOJ_X1_AIR_CONDITIONER$
+		$i = 0$
+		$WHILE i < LENGTH(DeviceSuperClass.EPC)$
+			$IF (AT(DeviceSuperClass.MUST, i) & attr) != 0$
+				$list = APPEND(list, AT(DeviceSuperClass.EPC, i))$
+			$END$
+			$i = i + 1$
+		$END$
+	$ELIF eoj.x1 == EOJ_X1_AMENITY$
+		$i = 0$
+		$WHILE i < LENGTH(DeviceSuperClass.EPC)$
+			$IF (AT(DeviceSuperClass.MUST, i) & attr) != 0$
+				$list = APPEND(list, AT(DeviceSuperClass.EPC, i))$
+			$END$
+			$i = i + 1$
+		$END$
+	$ELIF eoj.x1 == EOJ_X1_HOUSEWORK$
+		$i = 0$
+		$WHILE i < LENGTH(DeviceSuperClass.EPC)$
+			$IF (AT(DeviceSuperClass.MUST, i) & attr) != 0$
+				$list = APPEND(list, AT(DeviceSuperClass.EPC, i))$
+			$END$
+			$i = i + 1$
+		$END$
+	$ELIF eoj.x1 == EOJ_X1_WELLNESS$
+		$i = 0$
+		$WHILE i < LENGTH(DeviceSuperClass.EPC)$
+			$IF (AT(DeviceSuperClass.MUST, i) & attr) != 0$
+				$list = APPEND(list, AT(DeviceSuperClass.EPC, i))$
+			$END$
+			$i = i + 1$
+		$END$
+	$ELIF eoj.x1 == EOJ_X1_CONTROLLER$
+		$i = 0$
+		$WHILE i < LENGTH(DeviceSuperClass.EPC)$
+			$IF (AT(DeviceSuperClass.MUST, i) & attr) != 0$
+				$list = APPEND(list, AT(DeviceSuperClass.EPC, i))$
+			$END$
+			$i = i + 1$
+		$END$
+	$ELIF eoj.x1 == EOJ_X1_AUDIO_VISUAL$
+		$i = 0$
+		$WHILE i < LENGTH(DeviceSuperClass.EPC)$
+			$IF (AT(DeviceSuperClass.MUST, i) & attr) != 0$
+				$list = APPEND(list, AT(DeviceSuperClass.EPC, i))$
+			$END$
+			$i = i + 1$
+		$END$
+	$ELIF eoj.x1 == EOJ_X1_PROFILE$
+		$i = 0$
+		$WHILE i < LENGTH(ProfileObjectSuperClass.EPC)$
+			$IF (AT(ProfileObjectSuperClass.MUST, i) & attr) != 0$
+				$list = APPEND(list, AT(ProfileObjectSuperClass.EPC, i))$
+			$END$
+			$i = i + 1$
+		$END$
+		$IF eoj.x2 == EOJ_X2_NODE_PROFILE$
+			$i = 0$
+			$WHILE i < LENGTH(NodeProfileClass.EPC)$
+				$IF (AT(NodeProfileClass.MUST, i) & attr) != 0$
+					$list = APPEND(list, AT(NodeProfileClass.EPC, i))$
+				$END$
+				$i = i + 1$
+			$END$
+		$END$
+	$ELIF eoj.x1 == EOJ_X1_USER_DEFINED$
+		$i = 0$
+		$WHILE i < LENGTH(DeviceSuperClass.EPC)$
+			$IF (AT(DeviceSuperClass.MUST, i) & attr) != 0$
+				$list = APPEND(list, AT(DeviceSuperClass.EPC, i))$
+			$END$
+			$i = i + 1$
+		$END$
+	$END$
+
+	$i = 0$
+	$WHILE i < LENGTH(list)$
+		$pos = AT(list, i) & 0xF$
+		$bit = (AT(list, i) >> 4) - 8$
+		$map[pos] = map[pos] | (1 << bit)$
+		$i = i + 1$
+	$END$
+
+	$ResultOfGetPropertyInfo = {}$
+	$i = 0$
+	$WHILE i < LENGTH(list)$
+		$ResultOfGetPropertyInfo = APPEND(ResultOfGetPropertyInfo, AT(list, i))$
+		$i = i + 1$
+	$END$
+
+	$RESULT = ResultOfGetPropertyInfo$
+$END$
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_class.h
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_class.h	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_class.h	(revision 164)
@@ -0,0 +1,618 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef ECHONET_CLASS_H
+#define ECHONET_CLASS_H
+
+/* ZT[ÖA@í */
+#define EOJ_X1_SENSOR 0x00
+
+/* ó²ÖA@í */
+#define EOJ_X1_AIR_CONDITIONER 0x01
+
+/* ZîEÝõÖA@í */
+#define EOJ_X1_AMENITY 0x02
+
+/* ²EÆÖA@í */
+#define EOJ_X1_HOUSEWORK 0x03
+
+/* NÖA@í */
+#define EOJ_X1_WELLNESS 0x04
+
+/* ÇEìÖA@í */
+#define EOJ_X1_CONTROLLER 0x05
+
+/* AVÖA@í */
+#define EOJ_X1_AUDIO_VISUAL 0x06
+
+/* vt@C */
+#define EOJ_X1_PROFILE 0x0E
+
+/* [U[è` */
+#define EOJ_X1_USER_DEFINED 0x0F
+
+/*
+ * ZTÖA@íNXO[v *
+ */
+/* KXRêZT */
+#define EOJ_X2_GAS_LEAK_SENSOR 0x01
+
+/* hÆZT */
+#define EOJ_X2_CRIME_PREVENTION_SENSOR 0x02
+
+/* ñí{^ */
+#define EOJ_X2_EMERGENCY_BUTTON 0x03
+
+/* ~}pZT */
+#define EOJ_X2_FIRST_AID_SENSOR 0x04
+
+/* nkZT */
+#define EOJ_X2_EARTHQUAKE_SENSOR 0x05
+
+/* RdZT */
+#define EOJ_X2_ELECTRIC_LEAK_SENSOR 0x06
+
+/* lÌmZT */
+#define EOJ_X2_HUMAN_DETECTION_SENSOR 0x07
+
+/* qZT */
+#define EOJ_X2_VISITOR_SENSOR 0x08
+
+/* ÄÑoµZT */
+#define EOJ_X2_CALL_SENSOR 0x09
+
+/* IZT */
+#define EOJ_X2_CONDENSATION_SENSOR 0x0A
+
+/* óCõZT */
+#define EOJ_X2_AIR_POLLUTION_SENSOR 0x0B
+
+/* _fZT */
+#define EOJ_X2_OXYGEN_SENSOR 0x0C
+
+/* ÆxZT */
+#define EOJ_X2_ILLUMINANCE_SENSOR 0x0D
+
+/* ¹ZT */
+#define EOJ_X2_SOUND_SENSOR 0x0E
+
+/* ZT */
+#define EOJ_X2_MAILING_SENSOR 0x0F
+
+/* d×ZT */
+#define EOJ_X2_WEIGHT_SENSOR 0x10
+
+/* ·xZT */
+#define EOJ_X2_TEMPERATURE_SENSOR 0x11
+
+/* ¼xZT */
+#define EOJ_X2_HUMIDITY_SENSOR 0x12
+
+/* JZT */
+#define EOJ_X2_RAIN_SENSOR 0x13
+
+/* 
+ÊZT */
+#define EOJ_X2_WATER_LEVEL_SENSOR 0x14
+
+/* C
+ÊZT */
+#define EOJ_X2_BATH_WATER_LEVEL_SENSOR 0x15
+
+/* C¦«ãªèZT */
+#define EOJ_X2_BATH_HEATING_STATUS_SENSOR 0x16
+
+/* 
+RêZT */
+#define EOJ_X2_WATER_LEAK_SENSOR 0x17
+
+/* 
+ ÓêZT */
+#define EOJ_X2_WATER_OVERFLOW_SENSOR 0x18
+
+/* ÎÐZT */
+#define EOJ_X2_FIRE_SENSOR 0x19
+
+/* ^oRZT */
+#define EOJ_X2_CIGARETTE_SMOKE_SENSOR 0x1A
+
+/* bnQZT */
+#define EOJ_X2_CO2_SENSOR 0x1B
+
+/* KXZT */
+#define EOJ_X2_GAS_SENSOR 0x1C
+
+/* unbZT */
+#define EOJ_X2_VOC_SENSOR 0x1D
+
+/* ·³ZT */
+#define EOJ_X2_DIFFERENTIAL_PRESSURE_SENSOR 0x1E
+
+/* ¬ZT */
+#define EOJ_X2_AIR_SPEED_SENSOR 0x1F
+
+/* L¢ZT */
+#define EOJ_X2_ODOR_SENSOR 0x20
+
+/* ZT */
+#define EOJ_X2_FLAME_SENSOR 0x21
+
+/* dÍÊZT */
+#define EOJ_X2_ELECTRIC_ENERGY_SENSOR 0x22
+
+/* d¬ÊZT */
+#define EOJ_X2_CURRENT_VALUE_SENSOR 0x23
+
+/* õZT */
+#define EOJ_X2_DAYLIGHT_SENSOR 0x24
+
+/* 
+¬ÊZT */
+#define EOJ_X2_WATER_FLOW_RATE_SENSOR 0x25
+
+/* ÷®ZT */
+#define EOJ_X2_MICROMOTION_SENSOR 0x26
+
+/* ÊßZT */
+#define EOJ_X2_PASSAGE_SENSOR 0x27
+
+/* Ý°ZT */
+#define EOJ_X2_BED_PRESENCE_SENSOR 0x28
+
+/* JÂZT */
+#define EOJ_X2_OPEN_CLOSE_SENSOR 0x29
+
+/* ®ÊZT */
+#define EOJ_X2_ACTIVITY_AMOUNT_SENSOR 0x2A
+
+/* lÌÊuZT */
+#define EOJ_X2_HUMAN_BODY_LOCATION_SENSOR 0x2B
+
+/* áZT */
+#define EOJ_X2_SNOW_SENSOR 0x2C
+
+/*
+ * ó²ÖA@íNXO[v *
+ */
+/* ÆëpGAR */
+#define EOJ_X2_HOME_AIR_CONDITIONER 0x30
+
+/* â@ */
+#define EOJ_X2_COLD_BLASTER 0x31
+
+/* î@ */
+#define EOJ_X2_ELECTRIC_FAN 0x32
+
+/* ·Cî */
+#define EOJ_X2_VENTILATION_FAN 0x33
+
+/* ó²·Cî */
+#define EOJ_X2_AIR_CONDITIONING_VENTILATION_FAN 0x34
+
+/* óC´òí */
+#define EOJ_X2_AIR_CLEANER 0x35
+
+/* âî */
+#define EOJ_X2_COLD_BLAST_FAN 0x36
+
+/* T[L
+[^ */
+#define EOJ_X2_CIRCULATOR 0x37
+
+/* ¼@ */
+#define EOJ_X2_DEHUMIDIFIER 0x38
+
+/* Á¼í */
+#define EOJ_X2_HUMIDIFIER 0x39
+
+/* Väî */
+#define EOJ_X2_CEILING_FAN 0x3A
+
+/* dC±½Â */
+#define EOJ_X2_ELECTRIC_KOTATSU 0x3B
+
+/* dC ñ© */
+#define EOJ_X2_ELECTRIC_HEATING_PAD 0x3C
+
+/* dCÑz */
+#define EOJ_X2_ELECTRIC_BLANKET 0x3D
+
+/* Xg[u */
+#define EOJ_X2_SPACE_HEATER 0x3E
+
+/* plq[^ */
+#define EOJ_X2_PANEL_HEATER 0x3F
+
+/* dCJ[ybg */
+#define EOJ_X2_ELECTRIC_CARPET 0x40
+
+/* tAq[^ */
+#define EOJ_X2_FLOOR_HEATER 0x41
+
+/* dCg[í */
+#define EOJ_X2_ELECTRIC_HEATER 0x42
+
+/* t@q[^ */
+#define EOJ_X2_FAN_HEATER 0x43
+
+/* [dí */
+#define EOJ_X2_BATTERY_CHARGER 0x44
+
+/* Æ±ppbP[WGARºà@ */
+#define EOJ_X2_PACKAGE_TYPE_COMMERCIAL_AIR_CONDITIONER_INDOOR_UNIT 0x45
+
+/* Æ±ppbP[WGARºO@ */
+#define EOJ_X2_PACKAGE_TYPE_COMMERCIAL_AIR_CONDITIONER_OUTDOOR_UNIT 0x46
+
+/* Æ±ppbP[WGAR~Mjbg */
+#define EOJ_X2_PACKAGE_TYPE_COMMERCIAL_AIR_CONDITIONER_THERMAL_STORAGE_UNIT 0x47
+
+/* Æ±pt@RCjbg */
+#define EOJ_X2_COMMERCIAL_FAN_COIL_UNIT 0x48
+
+/* Æ±pó²âM¹(`[) */
+#define EOJ_X2_COMMERCIAL_AIR_CONDITIONING_COLD_SOURCE_CHILLER 0x49
+
+/* Æ±pó²·M¹({C[) */
+#define EOJ_X2_COMMERCIAL_AIR_CONDITIONING_HEAT_SOURCE_BOILER 0x50
+
+/* Æ±pó²VAV */
+#define EOJ_X2_AIR_CONDITIONING_VAV_FOR_COMMERCIAL_APPLICATION 0x51
+
+/* Æ±pó²GAnhOjbg */
+#define EOJ_X2_AIR_HANDLING_UNIT_AIR_CONDITIONING_FOR_COMMERCIAL_APPLICATION 0x52
+
+/* jbgN[[ */
+#define EOJ_X2_UNIT_COOLER 0x53
+
+/* Æ±pRfVOjbg */
+#define EOJ_X2_CONDENSING_UNIT_FOR_COMMERCIAL_APPLICATION 0x54
+
+/*
+ * ZîEÝõÖA@íNXO[v *
+ */
+/* d®uCh */
+#define EOJ_X2_ELECTRICALLY_OPERATED_SHADE 0x60
+
+/* d®Vb^[ */
+#define EOJ_X2_ELECTRICALLY_OPERATED_SHUTTER 0x61
+
+/* d®J[e */
+#define EOJ_X2_ELECTRICALLY_OPERATED_CURTAIN 0x62
+
+/* d®JË */
+#define EOJ_X2_ELECTRICALLY_OPERATED_STORM_WINDOW 0x63
+
+/* d®K[W */
+#define EOJ_X2_ELECTRICALLY_OPERATED_DOOR 0x64
+
+/* d®V */
+#define EOJ_X2_ELECTRICALLY_OPERATED_SKYLIGHT 0x65
+
+/* I[jOiúæ¯j */
+#define EOJ_X2_AWNING 0x66
+
+/* U
+íiëpj */
+#define EOJ_X2_GARDEN_SPRINKLER 0x67
+
+/* U
+íiÎÐpj */
+#define EOJ_X2_FIRE_SPRINKLER 0x68
+
+/* ¬
+ */
+#define EOJ_X2_FOUNTAIN 0x69
+
+/* uÔ¦í */
+#define EOJ_X2_INSTANTANEOUS_WATER_HEATERS 0x6A
+
+/* dC·
+í */
+#define EOJ_X2_ELECTRIC_WATER_HEATER 0x6B
+
+/* ¾zM·
+í */
+#define EOJ_X2_SOLAR_WATER_HEATER 0x6C
+
+/* zÂ|v */
+#define EOJ_X2_CIRCULATION_PUMP 0x6D
+
+/* dCÖÀi·
+ôòÖÀAg[ÖÀÈÇj */
+#define EOJ_X2_BIDET_EQUIPPED_TOILET 0x6E
+
+/* dCù */
+#define EOJ_X2_ELECTRIC_KEY 0x6F
+
+/* KX³Ù */
+#define EOJ_X2_GAS_LINE_VALVE 0x70
+
+/* z[TEi */
+#define EOJ_X2_HOME_SAUNA 0x71
+
+/* uÔ®í */
+#define EOJ_X2_HOT_WATER_GENERATOR 0x72
+
+/* ºg[£@ */
+#define EOJ_X2_BATHROOM_DRYER 0x73
+
+/* z[Gx[^ */
+#define EOJ_X2_HOME_ELEVATOR 0x74
+
+/* d®ÔdØè */
+#define EOJ_X2_ELECTRICALLY_OPERATED_ROOM_DIVIDER 0x75
+
+/* 
+½gXt@ */
+#define EOJ_X2_HORIZONTAL_TRANSFER 0x76
+
+/* d®¨±µ */
+#define EOJ_X2_ELECTRICALLY_OPERATED_CLOTHES_DRYING_POLE 0x77
+
+/* ò»
+ */
+#define EOJ_X2_SEPTIC_TANK 0x78
+
+/* Zîp¾zõ­d */
+#define EOJ_X2_HOME_SOLAR_POWER_GENERATION 0x79
+
+/* â·
+M¹@ */
+#define EOJ_X2_COLD_AND_HOT_WATER_HEAT_SOURCE_EQUIPMENT 0x7A
+
+/* °g[ */
+#define EOJ_X2_FLOOR_HEATING 0x7B
+
+/* R¿dr */
+#define EOJ_X2_FUEL_CELL 0x7C
+
+/* ~dr */
+#define EOJ_X2_STORAGE_BATTERY 0x7D
+
+/* dC©®Ô[údVXe */
+#define EOJ_X2_ELECTRIC_VEHICLE 0x7E
+
+/* dÍÊ[^ */
+#define EOJ_X2_ELECTRIC_ENERGY_METER 0x80
+
+/* 
+¬Ê[^ */
+#define EOJ_X2_WATER_FLOW_METER 0x81
+
+/* KX[^ */
+#define EOJ_X2_GAS_METER 0x82
+
+/* LPKX[^ */
+#define EOJ_X2_LP_GAS_METERS 0x83
+
+/* v */
+#define EOJ_X2_CLOCK 0x84
+
+/* ©®hA */
+#define EOJ_X2_AUTOMATIC_DOOR 0x85
+
+/* Æ±pGx[^ */
+#define EOJ_X2_COMMERCIAL_ELEVATOR 0x86
+
+/* ªdÕ[^O */
+#define EOJ_X2_DISTRIBUTION_PANEL_METERING 0x87
+
+/* X}[gdÍÊ[^ */
+#define EOJ_X2_SMART_ELECTRIC_ENERGY_METER 0x88
+
+/* X}[gKX[^ */
+#define EOJ_X2_SMART_GAS_METER 0x89
+
+/* êÊÆ¾ */
+#define EOJ_X2_GENERAL_LIGHTING_CLASS 0x90
+
+/* ñíÆ¾ */
+#define EOJ_X2_EMERGENCY_LIGHTING 0x99
+
+/* ÝõÆ¾ */
+#define EOJ_X2_EQUIPMENT_LIGHT 0x9D
+
+/* uU[ */
+#define EOJ_X2_BUZZER 0xA0
+
+/*
+ * ²EÆÖA@íNXO[v *
+ */
+/* R[q[[J */
+#define EOJ_X2_COFFEE_MACHINE 0xB0
+
+/* R[q[~ */
+#define EOJ_X2_COFFEE_MILL 0xB1
+
+/* dC|bg */
+#define EOJ_X2_ELECTRIC_HOT_WATER_POT 0xB2
+
+/* dC±ñë */
+#define EOJ_X2_ELECTRIC_STOVE 0xB3
+
+/* g[X^ */
+#define EOJ_X2_TOASTER 0xB4
+
+/* W
+[TE~LT */
+#define EOJ_X2_JUICER_FOOD_MIXER 0xB5
+
+/* t[hvZbT */
+#define EOJ_X2_FOOD_PROCESSOR 0xB6
+
+/* ââ É */
+#define EOJ_X2_REFRIGERATOR_FREEZER 0xB7
+
+/* I[uW */
+#define EOJ_X2_COMBINATION_MICROWAVE_OVEN 0xB8
+
+/* NbLOq[^ */
+#define EOJ_X2_COOKING_HEATER 0xB9
+
+/* I[u */
+#define EOJ_X2_OVEN 0xBA
+
+/* Ñí */
+#define EOJ_X2_RICE_COOKER 0xBB
+
+/* dqW[ */
+#define EOJ_X2_ELECTRONIC_JAR 0xBC
+
+/* Híô¢@ */
+#define EOJ_X2_DISH_WASHER 0xBD
+
+/* Hí£@ */
+#define EOJ_X2_DISH_DRYER 0xBE
+
+/* dCà¿Â«@ */
+#define EOJ_X2_ELECTRIC_RICE_CAKE_COOKER 0xBF
+
+/* Û·@ */
+#define EOJ_X2_KEEP_WARM_MACHINE 0xC0
+
+/* ¸Ä@ */
+#define EOJ_X2_RICE_MILL 0xC1
+
+/* ©®»p@ */
+#define EOJ_X2_AUTOMATIC_BREAD_COOKER 0xC2
+
+/* X[NbJ[ */
+#define EOJ_X2_SLOW_COOKER 0xC3
+
+/* dCÐ¨@ */
+#define EOJ_X2_ELECTRIC_PICKLES_COOKER 0xC4
+
+/* ôó@ */
+#define EOJ_X2_WASHING_MACHINE 0xC5
+
+/* ßÞ£@ */
+#define EOJ_X2_CLOTH_DRYER 0xC6
+
+/* dCAC */
+#define EOJ_X2_ELECTRIC_IRON 0xC7
+
+/* Y{vbT */
+#define EOJ_X2_TROUSER_PRESS 0xC8
+
+/* ÓÆñ£@ */
+#define EOJ_X2_FUTON_DRYER 0xC9
+
+/* ¬¨E­Â£@ */
+#define EOJ_X2_SMALL_ARTICLE_SHOES_DRYER 0xCA
+
+/* dC|@iZgN[iÜÞj */
+#define EOJ_X2_ELECTRIC_VACUUM_CLEANER 0xCB
+
+/* fBX|[U */
+#define EOJ_X2_DISPOSER 0xCC
+
+/* dCáæè@ */
+#define EOJ_X2_ELECTRIC_MOSQUITO_CATCHER 0xCD
+
+/* Æ±pV[P[X */
+#define EOJ_X2_COMMERCIAL_SHOW_CASE 0xCE
+
+/* Æ±pâ É */
+#define EOJ_X2_COMMERCIAL_REFRIGERATOR 0xCF
+
+/* Æ±pzbgP[X */
+#define EOJ_X2_COMMERCIAL_HOT_CASE 0xD0
+
+/* Æ±ptC[ */
+#define EOJ_X2_COMMERCIAL_FRYER 0xD1
+
+/* Æ±pdqW */
+#define EOJ_X2_COMMERCIAL_MICROWAVE_OVEN 0xD2
+
+/* ôó£@ */
+#define EOJ_X2_WASHER_AND_DRYER 0xD3
+
+/*
+ * NÖA@íNXO[v *
+ */
+/* Ìdv */
+#define EOJ_X2_WEIGHING_MACHINE 0x01
+
+/* Ì·v */
+#define EOJ_X2_CLINICAL_THERMOMETER 0x02
+
+/* ³v */
+#define EOJ_X2_BLOOD_PRESSURE_METER 0x03
+
+/* lv */
+#define EOJ_X2_BLOOD_SUGAR_METER 0x04
+
+/* Ìbv */
+#define EOJ_X2_BODY_FAT_METER 0x05
+
+/*
+ * ÇEìÖA@íNXO[v *
+ */
+/* ZL
+AÊMp¤L®Ýèm[h */
+#define EOJ_X2_SECURE_COMMUNICATION_SHARED_KEY_SETUP_NODE 0xFC
+
+/* XCb`iJEMA/HA[qÎj */
+#define EOJ_X2_SWITCH 0xFD
+
+/* gÑ[ */
+#define EOJ_X2_PORTABLE_TERMINAL 0xFE
+
+/* Rg[ */
+#define EOJ_X2_CONTROLLER 0xFF
+
+/*
+ * `uÖA@íNXO[v *
+ */
+/* fBXv[ */
+#define EOJ_X2_DISPLAY 0x01
+
+/* er */
+#define EOJ_X2_TELEVISION 0x02
+
+/*
+ * vt@CNXO[v *
+ */
+/* m[hvt@C */
+#define EOJ_X2_NODE_PROFILE 0xF0
+
+#endif /* ECHONET_CLASS_H */
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_dbg.c
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_dbg.c	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_dbg.c	(revision 164)
@@ -0,0 +1,397 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ECHONET Lite ^XN fobOoÍ
+ */
+
+#include <kernel.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <ctype.h>
+
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+
+#include "echonet.h"
+#include "echonet_dbg.h"
+#include "echonet_fbs.h"
+#include "echonet_task.h"
+
+#ifdef ECN_DBG_WAI_ENA
+#define _ECN_DBG_WAI_SYSLOG _ecn_dbg_wai_syslog()
+#else
+#define _ECN_DBG_WAI_SYSLOG
+#endif
+
+#if defined(ECN_DBG_PUT_ENA) || defined(ECN_CAP_PUT_ENA)
+#if defined(ECN_DBG_WAI_ENA)
+static ER _ecn_dbg_wai_syslog(void);
+/*
+ *  syslog()obt@É]TªÅ«éÜÅÒÂ
+ */
+static ER _ecn_dbg_wai_syslog(void)
+{
+	T_SYSLOG_RLOG	a_rlog;
+	ER				a_ret;
+	int				a_ct = 0;
+#ifndef ECN_DBG_WAI_SYSLOG_RETRY
+ #ifdef LOGTASK
+  #define ECN_DBG_WAI_SYSLOG_RETRY 10
+ #else
+  #define ECN_DBG_WAI_SYSLOG_RETRY 0
+ #endif
+#endif
+
+	for (;;) {
+		a_ret = syslog_ref_log(&a_rlog);
+		if (a_ret < 0)
+			return a_ret;
+		if (1 <= a_rlog.count) {
+			a_ct = 0;
+		} else
+#if (defined ECN_DBG_WAI_SYSLOG_RETRY) && (0 < ECN_DBG_WAI_SYSLOG_RETRY)
+		if (ECN_DBG_WAI_SYSLOG_RETRY <= ++a_ct)
+#endif
+		{
+/*			a_ret = dly_tsk(100);
+			if (a_ret < 0 && a_ret != E_RLWAI)
+				return a_ret; // */
+			break;
+		}
+
+		a_ret = dly_tsk(1);
+		if (a_ret < 0 && a_ret != E_RLWAI)
+			return a_ret;
+	}
+	return 0;
+}
+#endif /* #if defined(ECN_DBG_WAI_ENA) */
+
+/*
+ * fobOoÍ
+ * áF		ECN_DBG_PUT( "task start" );
+ */
+int _ecn_dbg_dbgput(const char *fp_srcloc, const char *fp_form, ...)
+{
+	va_list v;
+	unsigned char	p_buf[256];
+	ID		tskid;
+#ifndef ECN_DBG_PUT_BUF_MAX
+ #define ECN_DBG_PUT_BUF_MAX 255
+#endif
+
+	get_tid(&tskid);
+
+	if (!fp_srcloc)
+		fp_srcloc = "(null)";
+
+#ifdef SEM_ECN_DBG_PUT
+	syscall(wai_sem(SEM_ECN_DBG_PUT));
+#endif
+
+	va_start(v, fp_form);
+
+#ifdef _MSC_VER
+	vsnprintf_s(p_buf, ECN_DBG_PUT_BUF_MAX, ECN_DBG_PUT_BUF_MAX, fp_form, v);
+#else
+	vsprintf(p_buf, fp_form, v);
+#endif
+
+	_ECN_DBG_WAI_SYSLOG; /* syslog()obt@É]TªÅ«éÜÅÒÂ */
+
+#ifdef SEM_ECN_DBG_PUT
+	syscall(sig_sem(SEM_ECN_DBG_PUT));
+#endif
+
+	syslog(LOG_NOTICE, "%s[%d]: %s", fp_srcloc, (int)tskid, p_buf);
+
+	va_end(v);
+
+	return 0;
+}
+
+/* ECN_ENOD_IDÌ¶ñÏ· */
+const char *_ecn_dbg_enod2str(ECN_ENOD_ID fa_enod_id)
+{
+/*	#define _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT (4)
+/*	*/
+#ifdef _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT
+	static volatile uint8_t a_idx_vol = 0;
+	static char a_buf[1 << _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT][sizeof("ENOD_REMOTE_ID()")+5];
+	uint8_t a_idx;
+#endif
+
+	if (fa_enod_id == ENOD_NOT_MATCH_ID)
+		return "ENOD_NOT_MATCH_ID";
+	if (fa_enod_id == ENOD_MULTICAST_ID)
+		return "ENOD_MULTICAST_ID";
+	if (fa_enod_id == ENOD_LOCAL_ID)
+		return "ENOD_LOCAL_ID";
+	if (fa_enod_id == ENOD_API_ID)
+		return "ENOD_API_ID";
+	if (fa_enod_id == ENOD_REMOTE_ID)
+		return "ENOD_REMOTE_ID(0)";
+	if (fa_enod_id == ((ENOD_REMOTE_ID) + 1))
+		return "ENOD_REMOTE_ID(1)";
+	if (fa_enod_id == ((ENOD_REMOTE_ID) + 2))
+		return "ENOD_REMOTE_ID(2)";
+	if (fa_enod_id == ((ENOD_REMOTE_ID) + 3))
+		return "ENOD_REMOTE_ID(3)";
+	if (fa_enod_id == ((ENOD_REMOTE_ID) + 4))
+		return "ENOD_REMOTE_ID(4)";
+	if (fa_enod_id == ((ENOD_REMOTE_ID) + 5))
+		return "ENOD_REMOTE_ID(5)";
+#ifdef _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT
+	if (ENOD_REMOTE_ID <= fa_enod_id) {
+		/* return "ENOD_REMOTE_ID"; */
+		a_idx = (++a_idx_vol) & ((1 << _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT) - 1);
+#ifdef _MSC_VER
+		sprintf_s(a_buf[a_idx], sizeof(*a_buf), "ENOD_REMOTE_ID(%d)", fa_enod_id - ENOD_REMOTE_ID);
+#else
+		sprintf(a_buf[a_idx], "ENOD_REMOTE_ID(%d)", fa_enod_id - ENOD_REMOTE_ID);
+#endif
+		return a_buf[a_idx];
+	}
+#endif
+
+	return "?";
+}
+
+/*
+ * oCi_voÍ
+ */
+void _ecn_dbg_bindmp(const T_ECN_FST_BLK *buffer, size_t len)
+{
+	/* staticÌæÌobt@ðØèÖ¦éÂ(2^n) */
+	#define _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT (4)
+/*	*/
+#ifdef SEM_ECN_DBG_BINDMP
+ #ifdef _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT
+  #undef _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT
+  /* Z}tH(SEM_ECN_DBG_BINDMP)ªè`³êÄ¢éêAobt@ØèÖ¦ÍsvÈÌÅundef */
+ #endif
+#endif
+#ifndef _ECN_FBS_DBG_BINDMP_BUFLEN
+ /* obt@TCY(bindmpÌ1sªûÜéTCY) */
+ #define _ECN_FBS_DBG_BINDMP_BUFLEN (80)
+#endif
+#ifdef _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT
+	/* staticÌæÌobt@ðØèÖ¦é½ßÌÇpÏ */
+	static volatile uint8_t a_idx_vol = 0;
+	/* staticÌæÌobt@ØèÖ¦Ìæ */
+	static char a_buf_area[1 << _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT][_ECN_FBS_DBG_BINDMP_BUFLEN];
+	uint8_t a_idx;
+	char *a_buf;
+#else
+	/* staticÌæÌobt@Ìæ */
+	static char a_buf[_ECN_FBS_DBG_BINDMP_BUFLEN];
+#endif
+	const uint8_t *p = buffer;			/* ÇÝæè|C^ */
+	int i, a_blk, a_blk_max, a_pos = 0;
+	const T_ECN_EDT_HDR *p_req_esv;
+	const T_ECN_INTERNAL_MSG *p_im;
+
+#ifdef SEM_ECN_DBG_BINDMP
+	syscall(wai_sem(SEM_ECN_DBG_BINDMP));
+#endif
+
+	if (len != 256) {
+		a_blk_max = 1;
+	} else {
+		a_blk_max = buffer->hdr.wr ? 1 : 0;
+		if (!a_blk_max)
+			a_blk_max = 1;
+	}
+	#ifndef ECN_DBG_BINDMP_MAXLEN
+	 /* bindmpoÍÌÅåTCY */
+	 #define ECN_DBG_BINDMP_MAXLEN 1600
+	#endif
+	if (ECN_DBG_BINDMP_MAXLEN < len) {
+		len = ECN_DBG_BINDMP_MAXLEN;
+	}
+
+#ifdef _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT
+	a_idx = (++a_idx_vol) & ((1 << _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT) - 1);
+	a_buf = a_buf_area[a_idx];
+	/* #define a_buf (a_buf_area[a_idx]) */
+#endif
+
+	for (a_blk = 0; p && a_blk < a_blk_max; p = buffer->lnk.p_sub[a_blk++]->payload) {
+		if (0 < a_blk) {
+			_ECN_DBG_WAI_SYSLOG; /* syslog()obt@É]TªÅ«éÜÅÒÂ */
+			syslog(LOG_NOTICE, "p_sub[%d] (0x%08X)", a_blk - 1, p);
+		}
+		memset(a_buf, 0, _ECN_FBS_DBG_BINDMP_BUFLEN);
+		for (i = 0; i < (int)len; i++) {
+			if (i % 16 == 0) {
+				if (a_buf[0]) {
+					_ECN_DBG_WAI_SYSLOG; /* syslog()obt@É]TªÅ«éÜÅÒÂ */
+					syslog(LOG_NOTICE, "%s", a_buf);
+				}
+#ifdef _MSC_VER
+				sprintf_s(a_buf, _ECN_FBS_DBG_BINDMP_BUFLEN, "[%08X]:", i);
+#else
+				sprintf(a_buf, "[%08X]:", i);
+#endif
+				a_pos = strlen(a_buf);
+			} else {
+				a_buf[a_pos++] = (i % 16 == 8 ? '-':' ');
+			}
+#ifdef _MSC_VER
+			sprintf_s(a_buf + a_pos, _ECN_FBS_DBG_BINDMP_BUFLEN - a_pos, "%02X", p[i]);
+#else
+			sprintf(a_buf + a_pos, "%02X", p[i]);
+#endif
+			a_pos += 2;
+		}
+		if (a_buf[0]) {
+			_ECN_DBG_WAI_SYSLOG; /* syslog()obt@É]TªÅ«éÜÅÒÂ */
+			syslog(LOG_NOTICE, "%s", a_buf);
+		}
+		if (a_blk_max == 1)
+			break;
+	}
+
+	if (len == 256) {
+		switch (buffer->hdr.type) {
+		case ECN_MSG_ECHONET:
+			p_req_esv = &((T_EDATA *)buffer)->hdr;
+			_ECN_DBG_WAI_SYSLOG; /* syslog()obt@É]TªÅ«éÜÅÒÂ */
+			syslog(LOG_NOTICE, " sender: %d %s, target: %d %s",
+				buffer->hdr.sender.id, _ecn_dbg_enod2str(buffer->hdr.sender.id),
+				buffer->hdr.target.id, _ecn_dbg_enod2str(buffer->hdr.target.id));
+			_ECN_DBG_WAI_SYSLOG; /* syslog()obt@É]TªÅ«éÜÅÒÂ */
+			syslog(LOG_NOTICE, " ecn_hdr: 0x%02X 0x%02X 0x%04X", p_req_esv->ecn_hdr.ehd1, p_req_esv->ecn_hdr.ehd2, p_req_esv->ecn_hdr.tid);
+			_ECN_DBG_WAI_SYSLOG; /* syslog()obt@É]TªÅ«éÜÅÒÂ */
+			syslog(LOG_NOTICE, " edata: 0x%06X 0x%06X 0x%02X 0x%02X (%s)",
+				p_req_esv->edata.seoj.eojx1 << 16 | p_req_esv->edata.seoj.eojx2 << 8 | p_req_esv->edata.seoj.eojx3,
+				p_req_esv->edata.deoj.eojx1 << 16 | p_req_esv->edata.deoj.eojx2 << 8 | p_req_esv->edata.deoj.eojx3,
+				p_req_esv->edata.esv, p_req_esv->edata.opc, _ecn_dbg_esv2str(p_req_esv->edata.esv));
+			_ECN_DBG_WAI_SYSLOG; /* syslog()obt@É]TªÅ«éÜÅÒÂ */
+			syslog(LOG_NOTICE, " ecn_prp: 0x%02X 0x%02X", p_req_esv->ecn_prp.epc, p_req_esv->ecn_prp.pdc);
+			_ECN_DBG_WAI_SYSLOG; /* syslog()obt@É]TªÅ«éÜÅÒÂ */
+			syslog(LOG_NOTICE, " cur(blk/pos): wr %d, rd %d",
+				(int)buffer->hdr.wr,
+				(int)buffer->hdr.rd);
+		break;
+		case ECN_MSG_INTERNAL:
+			p_im = (const T_ECN_INTERNAL_MSG *)&buffer->payload[0];
+			syslog(LOG_NOTICE, " a_im.command: %d:%s", p_im->command,
+				(p_im->command == ECN_INM_NOTIFY_INSTANCELIST ? "ECN_INM_NOTIFY_INSTANCELIST" :
+				(p_im->command == ECN_INM_GET_DEVICE_LIST_REQ ? "ECN_INM_GET_DEVICE_LIST_REQ" :
+				(p_im->command == ECN_INM_GET_DEVICE_LIST_RES ? "ECN_INM_GET_DEVICE_LIST_RES" :
+				(p_im->command == ECN_INM_GET_DEVICE_INFO_REQ ? "ECN_INM_GET_DEVICE_INFO_REQ" :
+				(p_im->command == ECN_INM_GET_DEVICE_INFO_RES ? "ECN_INM_GET_DEVICE_INFO_RES" :
+				(p_im->command == ECN_UDP_MSG_GET_IPADDR_REQ ? "ECN_UDP_MSG_GET_IPADDR_REQ" :
+				(p_im->command == ECN_UDP_MSG_GET_IPADDR_RES ? "ECN_UDP_MSG_GET_IPADDR_RES" :
+				(p_im->command == ECN_UDP_MSG_GET_IPADDR_ERROR ? "ECN_UDP_MSG_GET_IPADDR_ERROR" : "?")))))))));
+			memset(a_buf, 0, _ECN_FBS_DBG_BINDMP_BUFLEN);
+			a_blk_max = buffer->hdr.wr;
+			if (0 < a_blk_max) {
+				if (64 < a_blk_max)
+					a_blk_max = 64;
+				if (_ECN_FBS_DBG_BINDMP_BUFLEN < a_blk_max)
+					a_blk_max = _ECN_FBS_DBG_BINDMP_BUFLEN;
+				for (i = offsetof(T_ECN_INTERNAL_MSG, data); i < a_blk_max; i++) {
+					a_blk = buffer->payload[i];
+					if (!isprint(a_blk) || !isascii(a_blk))
+						a_blk = '.';
+					a_buf[i - 1] = a_blk;
+				}
+				syslog(LOG_NOTICE, " a_im.data: [%s]", &a_buf[offsetof(T_ECN_INTERNAL_MSG, data) - 1]);
+			}
+			break;
+		default:
+			syslog(LOG_NOTICE, " invalid type: %d", buffer->hdr.type);
+		}
+	}
+	else if (8 <= len
+		&& buffer->payload[0] == 0x10
+		&& buffer->payload[1] == 0x81) {
+		p_req_esv = (const T_ECN_EDT_HDR *)&buffer->payload[0];
+		_ECN_DBG_WAI_SYSLOG; /* syslog()obt@É]TªÅ«éÜÅÒÂ */
+		syslog(LOG_NOTICE, " ecn_hdr: 0x%02X 0x%02X 0x%04X", p_req_esv->ecn_hdr.ehd1, p_req_esv->ecn_hdr.ehd2, p_req_esv->ecn_hdr.tid);
+		_ECN_DBG_WAI_SYSLOG; /* syslog()obt@É]TªÅ«éÜÅÒÂ */
+		syslog(LOG_NOTICE, " edata: 0x%06X 0x%06X 0x%02X 0x%02X (%s)",
+			p_req_esv->edata.seoj.eojx1 << 16 | p_req_esv->edata.seoj.eojx2 << 8 | p_req_esv->edata.seoj.eojx3,
+			p_req_esv->edata.deoj.eojx1 << 16 | p_req_esv->edata.deoj.eojx2 << 8 | p_req_esv->edata.deoj.eojx3,
+			p_req_esv->edata.esv, p_req_esv->edata.opc, _ecn_dbg_esv2str(p_req_esv->edata.esv));
+		_ECN_DBG_WAI_SYSLOG; /* syslog()obt@É]TªÅ«éÜÅÒÂ */
+		syslog(LOG_NOTICE, " ecn_prp: 0x%02X 0x%02X", p_req_esv->ecn_prp.epc, p_req_esv->ecn_prp.pdc);
+	}
+#ifdef SEM_ECN_DBG_BINDMP
+	syscall(sig_sem(SEM_ECN_DBG_BINDMP));
+#endif
+}
+
+/*
+ * ECHONET LiteT[rXR[h¶ñÏ·
+ */
+const char *_ecn_dbg_esv2str(uint8_t fa_esv)
+{
+	switch (fa_esv) {
+	case ESV_SET_I_SNA:		return "vpeBl«ÝvsÂ";			/* 0x50 */
+	case ESV_SET_C_SNA:		return "vpeBl«ÝvsÂ";			/* 0x51	*/
+	case ESV_GET_SNA:		return "vpeBlÇÝoµsÂ";				/* 0x52	*/
+	case ESV_INF_SNA:		return "vpeBlÊmsÂ";					/* 0x53 */
+	case ESV_SET_GET_SNA:	return "vpeBl«ÝEÇÝoµsÂ";	/* 0x5E	*/
+	case ESV_SET_I:			return "vpeBl«Ývisvj";		/* 0x60 */
+	case ESV_SET_C:			return "vpeBl«Ývivj";		/* 0x61 */
+	case ESV_GET:			return "vpeBlÇÝoµv";					/* 0x62 */
+	case ESV_INF_REQ:		return "vpeBlÊmv";						/* 0x63 */
+	case ESV_SET_GET:		return "vpeBl«ÝEÇÝoµv";		/* 0x6E */
+	case ESV_SET_RES:		return "vpeBl«Ý";					/* 0x71 */
+	case ESV_GET_RES:		return "vpeBlÇÝoµ";					/* 0x72 */
+	case ESV_INF:			return "vpeBlÊm";							/* 0x73 */
+	case ESV_INFC:			return "vpeBlÊmivj";				/* 0x74 */
+	case ESV_SET_GET_RES:	return "vpeBl«ÝEÇÝoµ";		/* 0x7E */
+	case ESV_INFC_RES:		return "vpeBlÊm";						/* 0x7A */
+	default:
+		return "(unknown)";
+	}
+}
+#endif /* #if defined(ECN_DBG_PUT_ENA) || defined(ECN_CAP_PUT_ENA) */
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_dbg.cfg
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_dbg.cfg	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_dbg.cfg	(revision 164)
@@ -0,0 +1,66 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  lbg[NÎTvvO(1)Ì
+ *  VXeRtBM
+[Vt@C
+ */
+
+#include "echonet_task.h"
+#include "echonet_lcl_task.h"
+
+/* #include "echonet_dbg.h" // */
+
+/* INCLUDE("main.cfg"); */
+
+/* INCLUDE("tinet/tinet_asp.cfg"); // */
+
+/* Z}tH */
+
+CRE_SEM(SEM_ECN_DBG_PUT, { TA_TPRI, 1, 1 });
+
+CRE_SEM(SEM_ECN_DBG_BINDMP, { TA_TPRI, 1, 1 });
+
+
+/* ECHONET Lite DBG-UDP */
+/* INCLUDE("../echonet/echonet_dbg_udp.cfg"); */
+
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_dbg.h
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_dbg.h	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_dbg.h	(revision 164)
@@ -0,0 +1,117 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ECHONET Lite ^XN fobOoÍ
+ */
+
+#ifndef TOPPERS_ECHONET_DBG_H
+#define TOPPERS_ECHONET_DBG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef SEM_ECN_DBG_UDP_SYSLOG
+ #include "echonet_dbg_udp.h"
+#endif
+
+/*#include ".h"*/
+#include "echonet.h"
+#include "echonet_fbs.h"
+
+/* ECN_SRC_LOC: \[XÌt@C¼ÆsÔð¦·¶ñðìé}N */
+#ifndef ECN_SRC_LOC
+ #ifndef _ECN_BLD_BASE_DIR
+  #define __ECN_SRC_LOC(fnam, line) fnam "(" #line ")"
+ #else
+  #define ___ECN_SRC_LOC(fnam, line) fnam "(" #line ")"
+  #define __ECN_SRC_LOC(fnam, line) \
+	( \
+		sizeof(_ECN_BLD_BASE_DIR) < sizeof(___ECN_SRC_LOC(fnam, line)) ? \
+		(	&(___ECN_SRC_LOC(fnam, line))[sizeof(_ECN_BLD_BASE_DIR) - 1] \
+		) \
+		:	___ECN_SRC_LOC(fnam, line) \
+	)
+ #endif
+ #define _ECN_SRC_LOC(fnam, line) __ECN_SRC_LOC(fnam, line)
+ #define ECN_SRC_LOC _ECN_SRC_LOC(__FILE__, __LINE__)
+#endif
+
+#ifdef ECN_DBG_PUT_ENA
+#define ECN_DBG_PUT(...) _ecn_dbg_dbgput(ECN_SRC_LOC, __VA_ARGS__)
+#else
+#define ECN_DBG_PUT(...)
+#endif
+
+/* fobOoÍ(CARP) */
+#ifdef ECN_CAP_PUT_ENA
+#define ECN_CAP_PUT(...) _ecn_dbg_dbgput(ECN_SRC_LOC, __VA_ARGS__)
+#else
+#define ECN_CAP_PUT(...)
+#endif
+
+/*
+ * fobOoÍ
+ * áF		ECN_DBG_PUT( "task start" );
+ */
+int _ecn_dbg_dbgput(const char *, const char *, ...);
+
+/*
+ * oCi_voÍ
+ */
+void _ecn_dbg_bindmp(const T_ECN_FST_BLK *buffer, size_t len);
+
+/*
+ * ECHONET LiteT[rXR[h¶ñÏ·
+ */
+const char *_ecn_dbg_esv2str(uint8_t fa_esv);
+
+/*
+ * ECN_ENOD_IDÌ¶ñÏ·
+ */
+const char *_ecn_dbg_enod2str(ECN_ENOD_ID fa_enod_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_ECHONET_DBG_H */
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_def.csv
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_def.csv	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_def.csv	(revision 164)
@@ -0,0 +1,21 @@
+EOBJ_NULL,EOBJ_NULL
+EOBJ_LOCAL_NODE,EOBJ_LOCAL_NODE
+EOBJ_SYNC_REMOTE_NODE,EOBJ_SYNC_REMOTE_NODE
+EOBJ_ASYNC_REMOTE_NODE,EOBJ_ASYNC_REMOTE_NODE
+EOBJ_DEVICE,EOBJ_DEVICE
+EPC_NONE,EPC_NONE
+EPC_RULE_SET,EPC_RULE_SET
+EPC_RULE_GET,EPC_RULE_GET
+EPC_RULE_ANNO,EPC_RULE_ANNO
+EPC_ANNOUNCE,EPC_ANNOUNCE
+EPC_VARIABLE,EPC_VARIABLE
+EOJ_X1_SENSOR,EOJ_X1_SENSOR
+EOJ_X1_AIR_CONDITIONER,EOJ_X1_AIR_CONDITIONER
+EOJ_X1_AMENITY,EOJ_X1_AMENITY
+EOJ_X1_HOUSEWORK,EOJ_X1_HOUSEWORK
+EOJ_X1_WELLNESS,EOJ_X1_WELLNESS
+EOJ_X1_CONTROLLER,EOJ_X1_CONTROLLER
+EOJ_X1_AUDIO_VISUAL,EOJ_X1_AUDIO_VISUAL
+EOJ_X1_PROFILE,EOJ_X1_PROFILE
+EOJ_X1_USER_DEFINED,EOJ_X1_USER_DEFINED
+EOJ_X2_NODE_PROFILE,EOJ_X2_NODE_PROFILE
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_fbs.c
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_fbs.c	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_fbs.c	(revision 164)
@@ -0,0 +1,400 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Åè·obt@ÂÏ·Xg[
+ */
+
+#include <kernel.h>
+#include <string.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "echonet_fbs.h"
+#include "arch/sys_arch.h"
+
+uint8_t lwip_heap_buf[NUM_ECHONET_MEMPOOL_BLOCK * ECHONET_MEMPOOL_BLOCK_SIZE];
+void *lwip_heap = lwip_heap_buf;
+size_t lwip_heapsz = sizeof(lwip_heap_buf);
+
+static ER get_message(T_ECN_FST_BLK **ppk_msg, int size)
+{
+	void *blk;
+
+	*ppk_msg = NULL;
+
+	if ((size <= 0) || (size > DEF_ECN_FBS_BUF_MAXLEN))
+		return E_PAR;
+
+	blk = sys_malloc(ECHONET_MEMPOOL_BLOCK_SIZE);
+	if (blk == NULL)
+		return E_NOMEM;
+
+	memset(blk, 0, ECHONET_MEMPOOL_BLOCK_SIZE);
+	*ppk_msg = (T_ECN_FST_BLK *)(blk);
+	(*ppk_msg)->hdr.length = (uint16_t)size;
+
+	return E_OK;
+}
+
+static void * get_block(T_ECN_FST_BLK *pk_msg, int pos, bool_t exp, int *size)
+{
+	void *buf;
+	void *blk;
+	int no;
+	T_ECN_SUB_BLK *mblk;
+	int temp;
+
+	if ((pos < 0) || (!exp && (pos >= pk_msg->hdr.length))) {
+		return NULL;
+	}
+
+	if (pos < DEF_ECN_FBS_FST_DAT_LEN) {
+		buf = (void *)&pk_msg->payload[pos];
+		temp = DEF_ECN_FBS_FST_DAT_LEN - pos;
+		if (temp < *size) {
+			*size = temp;
+		}
+	}
+	else {
+		pos -= DEF_ECN_FBS_FST_DAT_LEN;
+		no = pos / DEF_ECN_FBS_SUB_BUF_LEN;
+
+		mblk = pk_msg->lnk.p_sub[no];
+
+		pos -= no * DEF_ECN_FBS_SUB_BUF_LEN;
+		temp = DEF_ECN_FBS_SUB_BUF_LEN - pos;
+		if (temp < *size) {
+			*size = temp;
+		}
+		if (exp) {
+			if (mblk == NULL) {
+				blk = sys_malloc(ECHONET_MEMPOOL_BLOCK_SIZE);
+				if (blk == NULL)
+					return NULL;
+
+				mblk = (T_ECN_SUB_BLK *)(blk);
+
+				pk_msg->lnk.p_sub[no] = mblk;
+			}
+
+			temp = pos + *size + no * DEF_ECN_FBS_SUB_BUF_LEN + DEF_ECN_FBS_FST_DAT_LEN;
+			if (pk_msg->hdr.length < temp) {
+				pk_msg->hdr.length = (uint16_t)temp;
+			}
+		}
+
+		buf = &mblk->payload[pos];
+	}
+
+	return buf;
+}
+
+static ER release_message(T_ECN_FST_BLK *pk_msg)
+{
+	int i;
+
+	for (i = 0; i < 32; i++) {
+		void *blk = pk_msg->lnk.p_sub[i];
+		if (blk == NULL)
+			continue;
+
+		sys_free(blk);
+	}
+
+	sys_free(pk_msg);
+
+	return E_OK;
+}
+
+static int read_message(T_ECN_FST_BLK *pk_msg, int pos, void * dst, int size)
+{
+	int len, rest = size;
+	void * buf;
+
+	if (size <= 0)
+		return 0;
+
+	len = rest;
+	buf = get_block(pk_msg, pos, false, &len);
+	if ((buf == NULL) || (len <= 0))
+		return 0;
+
+	if((pos + len) > pk_msg->hdr.length)
+		len = pk_msg->hdr.length - pos;
+
+	for (; ; ) {
+		memcpy(dst, buf, len);
+		dst = (void *)((intptr_t)dst + len);
+		rest -= len;
+		pos += len;
+
+		if (rest <= 0)
+			break;
+
+		len = rest;
+		buf = get_block(pk_msg, pos, false, &len);
+		if ((buf == NULL) || (len <= 0))
+			return size - rest;
+	}
+
+	return size;
+}
+
+static int write_message(const void * src, T_ECN_FST_BLK *pk_msg, int pos, int size)
+{
+	int len, rest = size;
+	void * buf;
+
+	if (size <= 0)
+		return 0;
+
+	len = rest;
+	buf = get_block(pk_msg, pos, true, &len);
+	if ((buf == NULL) || (len <= 0))
+		return 0;
+
+	for (; ; ) {
+		memcpy(buf, src, len);
+		src = (void *)((intptr_t)src +len);
+		rest -= len;
+		pos += len;
+
+		if (rest <= 0)
+			break;
+
+		len = rest;
+		buf = get_block(pk_msg, pos, true, &len);
+		if ((buf == NULL) || (len <= 0))
+			return size - rest;
+	}
+
+	if (pk_msg->hdr.length < pos)
+		pk_msg->hdr.length = (uint16_t)pos;
+
+	return size;
+}
+
+static int copy_message(T_ECN_FST_BLK *pk_src, int spos, T_ECN_FST_BLK *pk_dst, int dpos, int size)
+{
+	int dlen, slen, len, rest = size;
+	void * dbuf, *sbuf;
+
+	if (size <= 0)
+		return 0;
+
+	dlen = rest;
+	dbuf = get_block(pk_dst, dpos, true, &dlen);
+	if (dbuf == NULL)
+		return 0;
+
+	slen = rest;
+	sbuf = get_block(pk_src, spos, false, &slen);
+	if (sbuf == NULL)
+		return 0;
+
+	for (; ; ) {
+		len = (dlen < slen) ? dlen : slen;
+
+		if (len == 0)
+			return size - rest;
+
+		memcpy(dbuf, sbuf, len);
+
+		dpos += len;
+		spos += len;
+		rest -= len;
+
+		if (rest <= 0)
+			break;
+
+		dlen = rest;
+		dbuf = get_block(pk_dst, dpos, true, &dlen);
+		if (dbuf == NULL)
+			return size - rest;
+
+		slen = rest;
+		sbuf = get_block(pk_src, spos, false, &slen);
+		if (sbuf == NULL)
+			return size - rest;
+	}
+
+	return size;
+}
+
+/* ÌæmÛ */
+ER _ecn_fbs_cre(ECN_FBS_SIZE_T fa_req_size, ECN_FBS_ID *fp_id)
+{
+	return get_message(&fp_id->ptr, fa_req_size);
+}
+
+/* Ìæðú */
+ER _ecn_fbs_del(ECN_FBS_ID fa_id)
+{
+	return release_message(fa_id.ptr);
+}
+
+/* Ûf[^ÌL³ */
+bool_t _ecn_fbs_exist_data(ECN_FBS_ID fa_id)
+{
+	return fa_id.ptr->hdr.length > fa_id.ptr->hdr.wr;
+}
+
+/* Ûf[^·Ìæ¾ */
+ECN_FBS_SSIZE_T _ecn_fbs_get_datalen(ECN_FBS_ID fa_id)
+{
+	return fa_id.ptr->hdr.length;
+}
+
+/* ÇÝæèJ[\ÌÊuæ¾ */
+ECN_FBS_SSIZE_T _ecn_fbs_get_rpos(ECN_FBS_ID fa_id)
+{
+	return fa_id.ptr->hdr.rd;
+}
+
+/* ÇÝæèJ[\ÌÊuÝè */
+ER _ecn_fbs_set_rpos(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_pos)
+{
+	if (fa_id.ptr->hdr.length <= (unsigned int)fa_pos)	/* Êuwèªå«·¬é */
+		return E_PAR;
+
+	fa_id.ptr->hdr.rd = fa_pos;
+
+	return E_OK;
+}
+
+/* ÇÝæèJ[\ÌÊuÚ® */
+ER _ecn_fbs_seek_rpos(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek)
+{
+	fa_id.ptr->hdr.rd += fa_seek;
+	if (fa_id.ptr->hdr.rd > fa_id.ptr->hdr.length)
+		fa_id.ptr->hdr.rd = fa_id.ptr->hdr.length;
+
+	return E_OK;
+}
+
+/* CÓwèÊuÌ1byteÇÝæè */
+int _ecn_fbs_peek(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek)
+{
+	uint8_t result = 0;
+	int ret;
+
+	ret = read_message(fa_id.ptr, fa_seek, &result, 1);
+
+	return (ret == 1) ? result : -1;
+}
+
+/* CÓwèÊuÌ1byte«Ý */
+ER _ecn_fbs_poke(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek, int fa_val)
+{
+	uint8_t result = fa_val;
+	int ret;
+
+	ret = write_message(&result, fa_id.ptr, fa_seek, 1);
+
+	return (ret == 1) ? E_OK : E_PAR;
+}
+
+/* f[^ÇÁ */
+ER _ecn_fbs_add_data(ECN_FBS_ID fa_id, const void *fa_dat, ECN_FBS_SSIZE_T fa_len)
+{
+	if((fa_id.ptr->hdr.wr + fa_len) > fa_id.ptr->hdr.length)
+		return E_PAR;
+
+	fa_id.ptr->hdr.wr += write_message(fa_dat, fa_id.ptr, fa_id.ptr->hdr.wr, fa_len);
+	return E_OK;
+}
+
+/* f[^ÇÁ(Ìæð©®IÉg£·é) */
+ER _ecn_fbs_add_data_ex(ECN_FBS_ID fa_id, const void *fa_dat, ECN_FBS_SSIZE_T fa_len)
+{
+	fa_id.ptr->hdr.wr += write_message(fa_dat, fa_id.ptr, fa_id.ptr->hdr.wr, fa_len);
+	return E_OK;
+}
+
+/* f[^æ¾ */
+ER _ecn_fbs_get_data(ECN_FBS_ID fa_id, void *fa_buf, ECN_FBS_SSIZE_T fa_maxlen, ECN_FBS_SSIZE_T *p_len)
+{
+	int ret;
+	
+	ret = read_message(fa_id.ptr, fa_id.ptr->hdr.rd, fa_buf, fa_maxlen);
+	fa_id.ptr->hdr.rd += ret;
+	*p_len = ret;
+
+	return E_OK;
+}
+
+ER ecn_fbs_enqueue(T_ECN_FBS_QUEUE *pk_queue, T_ECN_FST_BLK *pk_buf)
+{
+	loc_cpu();
+
+	*((T_ECN_FST_BLK **)pk_buf->_msg) = NULL;
+	if (pk_queue->pk_head != NULL) {
+		*((T_ECN_FST_BLK **)pk_queue->pk_last->_msg) = pk_buf;
+	}
+	else {
+		pk_queue->pk_head = pk_buf;
+	}
+	pk_queue->pk_last = pk_buf;
+
+	unl_cpu();
+
+	return E_OK;
+}
+
+ER ecn_fbs_dequeue(T_ECN_FBS_QUEUE *pk_queue, T_ECN_FST_BLK **ppk_buf)
+{
+	ER ercd;
+
+	loc_cpu();
+
+	if (pk_queue->pk_head != NULL) {
+		*ppk_buf = pk_queue->pk_head;
+		pk_queue->pk_head = *((T_ECN_FST_BLK **)(*ppk_buf)->_msg);
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+
+	unl_cpu();
+
+	return ercd;
+}
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_fbs.h
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_fbs.h	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_fbs.h	(revision 164)
@@ -0,0 +1,280 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Åè·obt@ÂÏ·Xg[
+ */
+
+#ifndef TOPPERS_ECHONET_FBS_H
+#define TOPPERS_ECHONET_FBS_H
+
+#include <kernel.h>
+#include "echonet.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ECHONET_MEMPOOL_GET_TMO
+#define ECHONET_MEMPOOL_GET_TMO	(0)			/* v[æ¾Ì^CAEgwè */
+#endif /* ECHONET_MEMPOOL_GET_TMO */
+
+#ifndef NUM_ECHONET_MEMPOOL_BLOCK
+#define NUM_ECHONET_MEMPOOL_BLOCK (60)		/* d¶pubNÌ */
+#endif /* NUM_ECHONET_MEMPOOL_BLOCK */
+
+#ifndef ECHONET_MEMPOOL_BLOCK_SIZE
+#define ECHONET_MEMPOOL_BLOCK_SIZE (256)	/* d¶pubNÌTCY */
+#endif /* ECHONET_MEMPOOL_BLOCK_SIZE */
+
+typedef unsigned int ECN_FBS_SIZE_T;	/* size_t  */
+typedef int ECN_FBS_SSIZE_T;			/* ssize_t */
+
+/* T_EDATAÇÌæTCY */
+#ifdef TARGET_KERNEL_ASP
+#define DEF_ECN_EDT_HDR_LEN (sizeof(T_MSG))
+#else
+#define DEF_ECN_EDT_HDR_LEN (sizeof(intptr_t))
+#endif
+
+/* ÇÌæTCY(64byte - sizeof(T_MSG)) */
+/* #define DEF_ECN_FBS_LIB_HDR_LEN ((ECHONET_MEMPOOL_BLOCK_SIZE + sizeof(int) - 1)>> 2) // */
+#define DEF_ECN_FBS_LIB_HDR_LEN (64 - DEF_ECN_EDT_HDR_LEN)
+
+/* ÇÌæðÜÞubNÉÛ·éf[^TCY */
+#define DEF_ECN_FBS_FST_DAT_LEN (64)
+
+/* N|C^zñÌTCY(byte) */
+#define DEF_ECN_FBS_LNK_LEN (ECHONET_MEMPOOL_BLOCK_SIZE - DEF_ECN_EDT_HDR_LEN - DEF_ECN_FBS_LIB_HDR_LEN - DEF_ECN_FBS_FST_DAT_LEN)
+
+/* Åè·obt@ÅåTCY */
+#define DEF_ECN_FBS_BUF_MAXLEN ((DEF_ECN_FBS_LNK_LEN / sizeof(void *)) * ECHONET_MEMPOOL_BLOCK_SIZE + DEF_ECN_FBS_FST_DAT_LEN)
+
+/* qvfobt@ÌTCY */
+#define DEF_ECN_FBS_SUB_BUF_LEN ECHONET_MEMPOOL_BLOCK_SIZE
+
+/* d¶ÌíÊ(àeÍ¼) */
+typedef enum
+{
+	ECN_FBS_TYPE_BLANK		=	0,		/* ¢gpXg[ */
+	ECN_FBS_TYPE_INTERNAL	=	1,		/* àbZ[W */
+	ECN_FBS_TYPE_ECHONET	=	2		/* ECHONETd¶ */
+} TA_ECN_MSG_TYPE;
+
+/* N|C^zñÉñ³êéAqvfobt@ */
+typedef struct
+{
+	uint8_t	payload[ECHONET_MEMPOOL_BLOCK_SIZE];
+} T_ECN_SUB_BLK;
+
+/* N|C^zñ */
+typedef union
+{
+	T_ECN_SUB_BLK	*p_sub[DEF_ECN_FBS_LNK_LEN / sizeof(T_ECN_SUB_BLK *)];
+	uint8_t			bin[DEF_ECN_FBS_LNK_LEN];
+} T_ECN_FBS_LNK;
+
+/* ÇÌæ(64byte - sizeof(T_MSG)) */
+typedef struct
+{
+	uint16_t	length;			/* bZ[W· */
+	uint16_t	type;			/* bZ[W^Cv */
+	union{
+		ECN_ENOD_ID id;			/* M³m[hIDiECHONETd¶j */
+		ID mbxid;				/* M³[{bNXIDiàbZ[Wj */
+	}sender;
+	union{
+		ECN_ENOD_ID id;			/* Mæm[hIDiECHONETd¶j */
+		ID mbxid;				/* Mæ[{bNXIDiàbZ[Wj */
+	}target;
+	union{
+		ECN_ENOD_ID id;			/* ÔMæm[hIDiECHONETd¶j */
+		ID mbxid;				/* ÔMæ[{bNXIDiàbZ[Wj */
+	}reply;
+
+	int			rd;				/*	ÇÝæèwbhîñ	*/
+	int			wr;				/*	«Ýwbhîñ	*/
+} T_ECN_FBS_HDR;
+
+/* ÇÌæðÜÞubNÌ\¢ */
+typedef struct
+{
+	uint8_t	_msg[DEF_ECN_EDT_HDR_LEN];	/* T_MSG */
+	T_ECN_FBS_HDR	hdr;	/*	ÇÌæ  64byte  - sizeof(T_MSG)	*/
+	uint8_t			_gap[DEF_ECN_FBS_LIB_HDR_LEN - sizeof(T_ECN_FBS_HDR)];
+	T_ECN_FBS_LNK	lnk;	/*	N|C^zñ	128byte			*/
+	uint8_t			payload[DEF_ECN_FBS_FST_DAT_LEN];
+} T_ECN_FST_BLK;
+
+/* FBS-ID */
+typedef struct ecn_fbs_id_strc
+{
+	T_ECN_FST_BLK	*ptr;
+} ECN_FBS_ID;
+
+/* bZ[WL
+[ */
+typedef struct ecn_fbs_queue
+{
+	T_ECN_FST_BLK	*pk_head;		/* æªÌbZ[W */
+	T_ECN_FST_BLK	*pk_last;		/* öÌbZ[W */
+} T_ECN_FBS_QUEUE;
+
+/*
+ * ÌæmÛ
+ *	ø
+ *		ECN_FBS_SIZE_T	fa_req_size		vobt@TCY(byte)
+ *										max: DEF_ECN_FBS_BUF_MAXLEN
+ *		ECN_FBS_ID		*fp_id			mÛµ½FBS-IDÌi[æ
+ *	ßèl
+ *		ER				0:ok ñ0:NG
+ */
+ER _ecn_fbs_cre(ECN_FBS_SIZE_T fa_req_size, ECN_FBS_ID *fp_id);
+
+/*
+ * Ìæðú
+ *	ø
+ *		ecn_fbs_id^	mÛµ½FBS-ID
+ *	ßèl
+ *		ER				0:ok, ñ0:NG
+ */
+ER _ecn_fbs_del(ECN_FBS_ID fa_id);
+
+/*
+ * Ûf[^ÌL³
+ *	ø
+ *		ecn_fbs_id^	mÛµ½FBS-ID
+ *	ßèl
+ *		bool_t			0:³µ, 1: è
+ */
+bool_t _ecn_fbs_exist_data(ECN_FBS_ID fa_id);
+
+/*
+ * Ûf[^·Ìæ¾
+ *	ø
+ *		ecn_fbs_id^	mÛµ½FBS-ID
+ *	ßèl
+ *		ECN_FBS_SSIZE_T	ÛµÄ¢éf[^Ì·³(byte) -1:NG
+ */
+ECN_FBS_SSIZE_T _ecn_fbs_get_datalen(ECN_FBS_ID fa_id);
+
+/*
+ * ÇÝæèJ[\ÌÊuæ¾
+ *	ø
+ *		ecn_fbs_id^	mÛµ½FBS-ID
+ *	ßèl
+ *		ECN_FBS_SIZE_T	æª©çÌâÎÊu -1:NG
+ */
+ECN_FBS_SSIZE_T _ecn_fbs_get_rpos(ECN_FBS_ID fa_id);
+
+/*
+ * ÇÝæèJ[\ÌÊuÝè
+ *	ø
+ *		ecn_fbs_id^	mÛµ½FBS-ID
+ *		ECN_FBS_SIZE_T	fa_pos	Ýè·éÊu(æª©çÌâÎÊu)
+ *	ßèl
+ *		ER				0:ok, ñ0:NG
+ */
+ER _ecn_fbs_set_rpos(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_pos);
+
+/*
+ * ÇÝæèJ[\ÌÊuÚ®
+ *	ø
+ *		ecn_fbs_id^	mÛµ½FBS-ID
+ *		ECN_FBS_SIZE_T	fa_seek	Ú®Ê(»óAOiÌÝ)
+ *	ßèl
+ *		ER				0:ok, ñ0:NG
+ */
+ER _ecn_fbs_seek_rpos(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek);
+
+/*
+ * CÓwèÊuÌ1byteÇÝæè
+ */
+int _ecn_fbs_peek(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek);
+
+/*
+ * CÓwèÊuÌ1byte«Ý
+ */
+ER _ecn_fbs_poke(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek, int fa_val);
+
+/*
+ * f[^ÇÁ
+ *	ø
+ *		ecn_fbs_id^	mÛµ½FBS-ID
+ *		const void *	fa_dat	ÇÁ·éf[^
+ *		ECN_FBS_SSIZE_T	fa_len	ÇÁ·é·³(byte)
+ *	ßèl
+ *		ER				0:ok, ñ0:NG
+ */
+ER _ecn_fbs_add_data(ECN_FBS_ID fa_id, const void *fa_dat, ECN_FBS_SSIZE_T fa_len);
+
+/*
+ * f[^ÇÁ(Ìæð©®IÉg£·é)
+ *	ø
+ *		ecn_fbs_id^	mÛµ½FBS-ID
+ *		const void *	fa_dat	ÇÁ·éf[^
+ *		ECN_FBS_SSIZE_T	fa_len	ÇÁ·é·³(byte)
+ *	ßèl
+ *		ER				0:ok, ñ0:NG
+ */
+ER _ecn_fbs_add_data_ex(ECN_FBS_ID fa_id, const void *fa_dat, ECN_FBS_SSIZE_T fa_len);
+
+/*
+ * f[^æ¾
+ *	ø
+ *		ecn_fbs_id^	mÛµ½FBS-ID
+ *		void *			fa_buf		æ¾·éobt@
+ *		ECN_FBS_SSIZE_T	fa_maxlen	æ¾·é·³(byte)
+ *		ECN_FBS_SSIZE_T	*p_len		æ¾µ½·³(byte)
+ *	ßèl
+ *		ER				0:ok, ñ0:NG
+ */
+ER _ecn_fbs_get_data(ECN_FBS_ID fa_id, void *fa_buf, ECN_FBS_SSIZE_T fa_maxlen,
+	ECN_FBS_SSIZE_T *p_len);
+
+ER ecn_fbs_enqueue(T_ECN_FBS_QUEUE *pk_queue, T_ECN_FST_BLK *pk_buf);
+ER ecn_fbs_dequeue(T_ECN_FBS_QUEUE *pk_queue, T_ECN_FST_BLK **ppk_buf);
+
+#ifdef __cplusplus
+}   /* extern "C" */
+#endif
+
+#endif /* #ifndef TOPPERS_ECHONET_FBS_H */
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_lcl_task.h
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_lcl_task.h	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_lcl_task.h	(revision 164)
@@ -0,0 +1,82 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ECHONET Lite ºÊÊMC[^XN
+ */
+
+#ifndef TOPPERS_ECHONET_LCL_TASK_H
+#define TOPPERS_ECHONET_LCL_TASK_H
+
+#ifdef SUPPORT_INET4
+#include "echonet_udp_task.h"
+#endif
+
+#ifdef SUPPORT_INET6
+#include "echonet_udp6_task.h"
+#endif
+
+#ifdef SUPPORT_UIP
+#include "echonet_uip_task.h"
+#endif
+
+typedef struct ecn_udp_msg_get_ipaddr_req
+{
+	unsigned int requestid;
+	ECN_ENOD_ID enodid;
+} ecn_udp_msg_get_ipaddr_req_t;
+
+typedef struct ecn_udp_msg_get_ipaddr_res
+{
+	unsigned int requestid;
+	ECN_ENOD_ID enodid;
+	ENODADRB enodadrb;
+} ecn_udp_msg_get_ipaddr_res_t;
+
+typedef struct ecn_udp_msg_get_ipaddr_error
+{
+	unsigned int requestid;
+	ER error;
+} ecn_udp_msg_get_ipaddr_error_t;
+
+ER ecn_udp_get_ipaddr(ID sender, int requestid, ECN_ENOD_ID enodid, ECN_FBS_ID *pk_req);
+
+#endif /* TOPPERS_ECHONET_LCL_TASK_H */
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_rename.h
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_rename.h	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_rename.h	(revision 164)
@@ -0,0 +1,59 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef ECHONET_RENAME_H
+#define ECHONET_RENAME_H
+
+#define tmax_eobjid			_echonet_tmax_eobjid
+#define eobjinib_table		_echonet_eobjinib_table
+#define tnum_enodid			_echonet_tnum_enodid
+#define eobjcb_table		_echonet_eobjcb_table
+#define tnum_enodadr		_echonet_tnum_enodadr
+#define enodadrb_table		_echonet_enodadrb_table
+#define ecn_svc_taskid		_echonet_ecn_svc_taskid
+#define ecn_udp_taskid		_echonet_ecn_udp_taskid
+#define ecn_api_mailboxid	_echonet_ecn_api_mailboxid
+#define ecn_svc_mailboxid	_echonet_ecn_svc_mailboxid
+#define ecn_udp_mailboxid	_echonet_ecn_udp_mailboxid
+#define ecn_mem_semid		_echonet_ecn_mem_semid
+#define ecn_udp_cepid		_echonet_ecn_udp_cepid
+
+#endif	/* of #ifndef ECHONET_RENAME_H */
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_task.c
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_task.c	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_task.c	(revision 164)
@@ -0,0 +1,1931 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ECHONET Lite ^XN
+ */
+
+#include <kernel.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+
+#include "echonet.h"
+#include "echonet_fbs.h"
+#include "echonet_task.h"
+#include "echonet_dbg.h"
+#ifdef ECHONET_CONTROLLER_EXTENTION
+#include "echonet_agent.h"
+#endif
+
+#ifndef ECHONET_TASK_GET_TIMER
+#define ECHONET_TASK_GET_TIMER	TMO_FEVR
+#endif /* ECHONET_TASK_GET_TIMER */
+
+#ifndef ECHONET_TASK_PROGRESS
+#define ECHONET_TASK_PROGRESS(timer)
+#endif /* ECHONET_TASK_PROGRESS */
+
+#ifndef ECHONET_TASK_TIMEOUT
+#define ECHONET_TASK_TIMEOUT
+#endif /* ECHONET_TASK_TIMEOUT */
+
+/* AvP[Vªvµ½d¶ÌV[PXÔ */
+static uint16_t g_api_tid;
+
+/* óMbZ[WðJú·é©Û© */
+static bool_t g_release_esv;
+
+ER _ecn_tsk_ntf_inl(intptr_t fa_exinf);
+
+ER _ecn_tsk_snd_mbx(ECN_FBS_ID fa_rsp_fbs, bool_t from_app)
+{
+	ER	a_ret;
+	T_MSG *msg = (T_MSG *)fa_rsp_fbs.ptr;
+	ID mbxid = ecn_udp_mailboxid;
+	int i;
+#ifdef ECN_DBG_PUT_ENA
+	intptr_t a_fbs_sub1 = (intptr_t)fa_rsp_fbs.ptr->lnk.p_sub[0];
+#endif
+	if (from_app && (((T_EDATA *)fa_rsp_fbs.ptr)->hdr.edata.esv == ESV_INFC)) {
+		g_api_tid = ((T_EDATA *)fa_rsp_fbs.ptr)->hdr.ecn_hdr.tid;
+		mbxid = ecn_svc_mailboxid;
+	}
+	else {
+		switch (fa_rsp_fbs.ptr->hdr.target.id) {
+		case ENOD_MULTICAST_ID:
+			if (from_app)
+				g_api_tid = ((T_EDATA *)fa_rsp_fbs.ptr)->hdr.ecn_hdr.tid;
+
+			mbxid = ecn_udp_mailboxid;
+			break;
+		case ENOD_LOCAL_ID:
+			if (from_app)
+				mbxid = ecn_svc_mailboxid;
+			else
+				mbxid = ecn_api_mailboxid;
+			break;
+		case ENOD_API_ID:
+			mbxid = ecn_api_mailboxid;
+			break;
+		default:
+			if (from_app)
+				g_api_tid = ((T_EDATA *)fa_rsp_fbs.ptr)->hdr.ecn_hdr.tid;
+
+			i = fa_rsp_fbs.ptr->hdr.target.id;
+			if (i < ENOD_REMOTE_ID || tnum_enodadr <= i)
+				return E_NOEXS;
+			i += - ENOD_REMOTE_ID + 1;
+			if (from_app && (i < tnum_enodid)) {
+				/* ñ¯úÌ[gm[hÍT[rX^XNÅ·é */
+				switch (eobjcb_table[i].profile->eobjatr) {
+				case EOBJ_SYNC_REMOTE_NODE:
+					mbxid = ecn_udp_mailboxid;
+					break;
+				case EOBJ_ASYNC_REMOTE_NODE:
+					mbxid = ecn_svc_mailboxid;
+					break;
+				default:
+					return E_SYS;
+				}
+			}
+			else {
+				mbxid = ecn_udp_mailboxid;
+			}
+			break;
+		}
+	}
+#ifdef ECN_DBG_PUT_ENA
+	ECN_DBG_PUT( "snd_mbx(%d, 0x%08X-0x%08X)", mbxid, (intptr_t)msg, a_fbs_sub1 );
+	_ecn_dbg_bindmp(msg, 256);
+#endif
+	a_ret = snd_mbx(mbxid, msg);
+#ifdef ECN_DBG_PUT_ENA
+	ECN_DBG_PUT( "snd_mbx(%d, 0x%08X-0x%08X) result = %d:%s", mbxid, (intptr_t)msg, a_fbs_sub1, a_ret, itron_strerror(a_ret) );
+#endif
+	return a_ret;
+}
+
+static void _ecn_tsk_int_module_init(intptr_t fa_exinf);
+static void _ecn_tsk_int_startup(intptr_t fa_exinf);
+static uint16_t _ecn_tsk_new_tid(void);
+static void _ecn_tsk_int_msg(intptr_t fa_exinf, ECN_FBS_ID fa_fbs_id);
+static void _ecn_tsk_ecn_msg(intptr_t fa_exinf, ECN_FBS_ID fa_fbs_id);
+
+static void _ecn_tsk_eoj_set(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp, bool_t fa_update,
+	ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv,
+	ECN_FBS_ID *fa_fbs_anno);
+static void _ecn_tsk_eoj_get(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_forward, ATR fa_access,
+	ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv);
+static void _ecn_tsk_eoj_res(ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv,
+	ECN_SRV_CODE fa_sna_esv);
+static void _ecn_tsk_eoj_set_get(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp,
+	ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv,
+	ECN_FBS_ID *fa_fbs_anno);
+static void _ecn_tsk_eoj_set_get_res(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp,
+	ECN_FBS_ID fa_fbs_id, ECN_FBS_ID *fa_fbs_anno);
+
+/* W
+[ú»tO */
+static uint8_t		m_eobjlist_need_init = 1;
+
+/* V[PXÔ */
+static uint16_t		g_current_tid = 1;
+
+/*
+ *  ECHONET Lite ^XNÌú»iRXgN^j
+ */
+void echonet_task_init(intptr_t exinf)
+{
+	if (m_eobjlist_need_init)
+		_ecn_tsk_int_module_init(exinf);
+}
+
+/*
+ * W
+[ú»
+ */
+static void _ecn_tsk_int_module_init(intptr_t exinf)
+{
+	ID	tskid;
+
+	if (!m_eobjlist_need_init)
+		return;
+
+	get_tid(&tskid);
+	/* ECN_DBG_PUT( "[ECHONET MainTask:%d] started", tskid ); */
+	syslog(LOG_NOTICE, "[ECHONET MainTask:%d] started", tskid);
+
+	m_eobjlist_need_init = 0;
+
+#ifdef ECHONET_CONTROLLER_EXTENTION
+	ecn_agent_init();
+#endif
+}
+
+/*
+ *  ECHONET Lite ^XNÌ{Ì
+ */
+void echonet_task(intptr_t fa_exinf)
+{
+	ER a_ret, a_ret2;
+	union
+	{
+		T_MSG		*p_msg;
+		ECN_FBS_ID	fbs_id;
+	} a_mdt;
+	SYSTIM a_prev, a_now;
+	TMO a_timer;
+#ifdef ECHONET_CONTROLLER_EXTENTION
+	TMO a_timera;
+#endif
+
+	_ecn_tsk_int_startup(fa_exinf);
+
+	a_ret2 = get_tim(&a_now);
+	if (a_ret2 != E_OK) {
+		ECN_DBG_PUT( "get_tim() result = %d:%s", a_ret2, itron_strerror(a_ret2) );
+		return;
+	}
+
+	/* bZ[W[v */
+	for (;;) {
+		a_prev = a_now;
+
+		a_timer = ECHONET_TASK_GET_TIMER;
+#ifdef ECHONET_CONTROLLER_EXTENTION
+		a_timera = ecn_agent_get_timer();
+		if(a_timer == TMO_FEVR){
+			a_timer =a_timera;
+		}
+		else if((a_timera != TMO_FEVR) && (a_timera < a_timer)){
+			a_timer = a_timera;
+		}
+#endif
+
+		a_ret = trcv_mbx(ecn_svc_mailboxid, &a_mdt.p_msg, a_timer);
+		if ((a_ret != E_OK) && (a_ret != E_TMOUT)) {
+			ECN_DBG_PUT( "trcv_mbx() result = %d:%s", a_ret, itron_strerror(a_ret) );
+			break;
+		}
+
+		a_ret2 = get_tim(&a_now);
+		if (a_ret2 != E_OK) {
+			ECN_DBG_PUT( "get_tim() result = %d:%s", a_ret2, itron_strerror(a_ret2) );
+			break;
+		}
+
+		a_timer = a_now - a_prev;
+		ECHONET_TASK_PROGRESS(a_timer);
+#ifdef ECHONET_CONTROLLER_EXTENTION
+		ecn_agent_progress(a_timer);
+#endif
+
+		if (a_ret == E_OK) {
+			ECN_DBG_PUT( "trcv_mbx() mbx recv (%d byte)", _ecn_fbs_get_datalen(a_mdt.fbs_id) );
+			g_release_esv = true;
+
+			switch (a_mdt.fbs_id.ptr->hdr.type) {
+			/* àgpbZ[W */
+			case ECN_MSG_INTERNAL:
+				_ecn_tsk_int_msg(fa_exinf, a_mdt.fbs_id);
+				break;
+
+			/* ECHONETpbZ[W */
+			case ECN_MSG_ECHONET:
+				_ecn_tsk_ecn_msg(fa_exinf, a_mdt.fbs_id);
+				break;
+
+			default:
+				syslog(LOG_WARNING, "echonet_task() a_fbs_id.ptr->k.hdr.k.t_edt.type:0x%02X undefined.", a_mdt.fbs_id.ptr->hdr.type);
+			}
+
+			/* Ìæðú */
+			if (g_release_esv)
+				_ecn_fbs_del(a_mdt.fbs_id);
+		}
+
+		ECHONET_TASK_TIMEOUT;
+#ifdef ECHONET_CONTROLLER_EXTENTION
+		ecn_agent_timeout();
+#endif
+	}
+}
+
+/*
+ * V[PXÔ¶¬
+ */
+static uint16_t _ecn_tsk_new_tid(void)
+{
+	return g_current_tid++;
+}
+
+/*
+ * vd¶ì¬
+ * ø
+ * ECN_FBS_ID		*fp_fbs_id		æ¾µ½FBS_IDÌi[æ
+ * ID				fa_seoj			M³ÌECHONETIuWFNgID
+ * ID				fa_deoj			¶æÌECHONETIuWFNgID
+ * uint8_t			fa_epc			vpeBR[h
+ * uint8_t			fa_pdc			vpeBlf[^TCY
+ * const void		*p_edt			vpeBlf[^
+ * ECN_SRV_CODE		fa_esv			ECHONET Light T[rXR[h
+ */
+ER _ecn_tsk_mk_esv(ECN_FBS_ID *fp_fbs_id, ID fa_seoj, ID fa_deoj,
+	uint8_t fa_epc, uint8_t fa_pdc, const void *p_edt, ECN_SRV_CODE fa_esv)
+{
+	ER				a_ret;
+	int				a_size, i;
+	ECN_FBS_ID		a_fbs_id = { 0 };	/* vd¶p				*/
+	T_ECN_EDT_HDR	a_ecn_hdp;			/* ecn_hdr+edata+ecn_prp 14byte	*/
+	ID				a_enodid;
+	const EOBJINIB *a_eobj;
+	const EOBJINIB *a_enod;
+
+	if (!fp_fbs_id)
+		return E_PAR; /* æ¾µ½FBS_IDÌi[æªNULL */
+	if (ECHONET_MEMPOOL_BLOCK_SIZE <= fa_pdc)
+		return E_PAR; /* vpeBlTCYªå«·¬é */
+	if (!p_edt && 0 < fa_pdc)
+		return E_PAR; /* vpeBlTCYª1ÈãÈÌÉf[^|C^ªNULL */
+
+	if (fa_seoj <= EOBJ_NULL || tmax_eobjid < fa_seoj)
+		return E_NOEXS; /* ECHONETIuWFNgIDª¢è` */
+#ifndef ECHONET_CONTROLLER_EXTENTION
+	if (fa_deoj < EOBJ_NULL || tmax_eobjid < fa_deoj)
+		return E_NOEXS; /* ECHONETIuWFNgIDª¢è` */
+#else
+	if (fa_deoj < EOBJ_NULL || (tmax_eobjid + TNUM_AEOBJID) < fa_deoj)
+		return E_NOEXS; /* ECHONETIuWFNgIDª¢è` */
+#endif
+	if (fa_deoj == EOBJ_NULL && fa_esv == ESV_INFC)
+		return E_NOEXS; /* ECHONETIuWFNgIDª¢è` */
+
+	/* vÅ¬TCYÌæ¾ */
+	a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
+
+	/* vd¶pÌæ¾ */
+	a_ret = _ecn_fbs_cre(a_size, &a_fbs_id);
+	if (a_ret != E_OK || !a_fbs_id.ptr) { /* mÛ¸s */
+		ECN_DBG_PUT( "_ecn_fbs_cre(%d) result = %d:%s",
+			a_size,
+			a_ret, itron_strerror(a_ret) );
+		return E_NOMEM;
+	}
+
+	/* vd¶Ýè						*/
+	memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
+	a_ecn_hdp.ecn_hdr.ehd1 = ECN_EDH1_ECHONET_LITE;
+	a_ecn_hdp.ecn_hdr.ehd2 = ECN_EDH2_FORMAT_1;
+	a_ecn_hdp.ecn_hdr.tid = _ecn_tsk_new_tid();
+	memcpy(&a_ecn_hdp.edata.seoj, &eobjinib_table[fa_seoj - 1].eojx1, sizeof(a_ecn_hdp.edata.seoj));
+	a_ecn_hdp.edata.esv = fa_esv;
+	a_ecn_hdp.edata.opc = 1;		/* vpeB */
+	a_ecn_hdp.ecn_prp.epc = fa_epc;	/* vpeBR[h */
+	a_ecn_hdp.ecn_prp.pdc = fa_pdc;	/* tf[^TCY */
+
+	/* vd¶pÉf[^ÇÁ */
+	a_ret = _ecn_fbs_add_data_ex(a_fbs_id, &a_ecn_hdp, a_size);
+	if (a_ret) {
+		ECN_DBG_PUT( "_ecn_fbs_add_data_ex(*, ecn_hdp{esv:0x%02X,epc:0x%02X}, %d) result = %d:%s",
+			a_ecn_hdp.edata.esv, a_ecn_hdp.ecn_prp.epc, a_size,
+			a_ret, itron_strerror(a_ret) );
+		goto lb_except;
+	}
+	if (0 < fa_pdc) {
+		/* tf[^ÇÁ */
+		a_ret = _ecn_fbs_add_data_ex(a_fbs_id, p_edt, fa_pdc);
+		if (a_ret) {
+			ECN_DBG_PUT( "_ecn_fbs_add_data_ex(*, ecn_hdp{esv:0x%02X,epc:0x%02X} edt, %d) result = %d:%s",
+				a_ecn_hdp.edata.esv, a_ecn_hdp.ecn_prp.epc, fa_pdc,
+				a_ret, itron_strerror(a_ret) );
+			goto lb_except;
+		}
+	}
+	if (fa_deoj == 0) {
+		ECN_DBG_PUT( "%s", "}`LXg" );
+		/* fa_deoj == 0 : }`LXg */
+		((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx1 = EOJ_X1_PROFILE;
+		((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx2 = EOJ_X2_NODE_PROFILE;
+		((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx3 = 0x01;
+		a_fbs_id.ptr->hdr.target.id = ENOD_MULTICAST_ID;
+	}
+	else if (fa_deoj <= tmax_eobjid) {
+		ECN_DBG_PUT( "fa_deoj = %d", fa_deoj );
+		/* if (fa_deoj < 1 || tmax_eobjid < fa_deoj) cÌÙínÍÖ`ªÅOÏÝÆ·é */
+		a_eobj = &eobjinib_table[fa_deoj - 1];
+		memcpy(&((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj, &a_eobj->eojx1,
+			sizeof(((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj));
+
+		/* e[u©çõ */
+		a_fbs_id.ptr->hdr.target.id = ENOD_NOT_MATCH_ID;
+		a_enodid = (a_eobj->enodid == 0) ? fa_deoj : a_eobj->enodid;
+		a_enod = &eobjinib_table[a_enodid - 1];
+		if ((a_enod->eobjatr == EOBJ_LOCAL_NODE)
+			|| ((a_enod->eobjatr == EOBJ_ASYNC_REMOTE_NODE) && (fa_esv == ESV_GET))) {
+			a_fbs_id.ptr->hdr.target.id = ENOD_LOCAL_ID;
+		}
+		else{
+			for (i = 1; i < tnum_enodid; i++) {
+				const EOBJCB *temp = &eobjcb_table[i];
+				if (a_enod != temp->profile)
+					continue;
+
+				a_fbs_id.ptr->hdr.target.id = (ECN_ENOD_ID)(i + ENOD_REMOTE_ID - 1);
+				break;
+			}
+		}
+		if (a_fbs_id.ptr->hdr.target.id == ENOD_NOT_MATCH_ID) {
+			goto lb_except;
+			ECN_DBG_PUT( "deoj = %02X %02X %02x : enod not match",
+				((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx1,
+				((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx2,
+				((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx3 );
+		}
+#ifdef ECN_DBG_PUT_ENA
+		else {
+			ECN_DBG_PUT( "deoj = %02X %02X %02x : %s",
+				((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx1,
+				((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx2,
+				((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx3,
+				_ecn_dbg_enod2str(a_fbs_id.ptr->hdr.target.id) );
+		}
+#endif
+	}
+#ifdef ECHONET_CONTROLLER_EXTENTION
+	else{
+		T_ECN_EOJ eoj;
+		ECN_ENOD_ID enodid;
+		ECN_DBG_PUT( "fa_deoj = %d", fa_deoj );
+		/* IuWFNgID©çEOJÆm[hIDðæ¾ */
+		if(ecn_agent_get_eoj_enodid(fa_deoj, &eoj, &enodid)){
+			memcpy(&((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj, &eoj,
+				sizeof(((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj));
+			a_fbs_id.ptr->hdr.target.id = enodid;
+		}
+		else {
+			goto lb_except;
+			ECN_DBG_PUT( "deoj = %02X %02X %02x : enod not match",
+				((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx1,
+				((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx2,
+				((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx3 );
+		}
+#ifdef ECN_DBG_PUT_ENA
+		else {
+			ECN_DBG_PUT( "deoj = %02X %02X %02x : %s",
+				((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx1,
+				((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx2,
+				((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx3,
+				_ecn_dbg_enod2str(a_fbs_id.ptr->hdr.target) );
+		}
+#endif
+	}
+#endif
+	a_fbs_id.ptr->hdr.type = ECN_MSG_ECHONET;
+	a_fbs_id.ptr->hdr.sender.id = ENOD_API_ID;
+	if (fa_esv == ESV_INFC)
+		a_fbs_id.ptr->hdr.reply.id = a_fbs_id.ptr->hdr.target.id;
+	else if (fa_esv == ESV_INF_REQ)
+		a_fbs_id.ptr->hdr.reply.id = ENOD_MULTICAST_ID;
+	else
+		a_fbs_id.ptr->hdr.reply.id = ENOD_API_ID;
+
+	/* ³íI¹ */
+	*fp_fbs_id = a_fbs_id;
+	return E_OK;
+
+lb_except:
+	/* f[^ì¬¸sµ½çÌæðú */
+	if (a_fbs_id.ptr)
+		_ecn_fbs_del(a_fbs_id);
+
+	return a_ret;
+}
+
+/*
+ * àgpbZ[W
+ */
+static void _ecn_tsk_int_msg(intptr_t fa_exinf, ECN_FBS_ID fa_fbs_id)
+{
+	T_ECN_INTERNAL_MSG	a_im;
+	ECN_FBS_SSIZE_T		a_len;
+	int					a_ans;
+
+	a_im.command = 0;
+	a_len = 0;
+	a_ans = _ecn_fbs_get_data(fa_fbs_id, &a_im.command, sizeof(a_im.command), &a_len);
+	if (a_ans || !a_len) {
+		return;		/* NG */
+	}
+
+	switch (a_im.command) {
+	case ECN_INM_NOTIFY_INSTANCELIST:
+		ECN_DBG_PUT( "do _ecn_tsk_int_startup()" );
+		_ecn_tsk_int_startup(fa_exinf);
+		break;
+	default:
+#ifdef ECHONET_CONTROLLER_EXTENTION
+		if(ecn_agent_proc_int_msg(fa_fbs_id, a_im.command))
+			break;
+#endif
+		ECN_DBG_PUT( "recv: unefined internal-msg: %d", a_im.command );
+		break;
+	}
+}
+
+/*
+ * ^XNú»
+ */
+static void _ecn_tsk_int_startup(intptr_t fa_exinf)
+{
+	ER	a_ret;
+
+	if (m_eobjlist_need_init)
+		_ecn_tsk_int_module_init(fa_exinf);
+
+	/* CX^XXgÊmÌM */
+	a_ret = _ecn_tsk_ntf_inl(fa_exinf);
+	if (a_ret) {
+		syslog(LOG_WARNING, "_ecn_tsk_ntf_inl() result = %d:%s", a_ret, itron_strerror(a_ret));
+	}
+}
+
+/*
+ * CX^XXgÊmÌM
+ * ECHONET-Lite_Ver.1.10_02.pdf p.43 }4-1-4
+ */
+ER _ecn_tsk_ntf_inl(intptr_t fa_exinf)
+{
+	const T_ECN_EOJ	a_seoj =	/* 0x01 : êÊm[hA0x02FMêpm[h */
+		{ EOJ_X1_PROFILE, EOJ_X2_NODE_PROFILE, 0x01 };
+	const T_ECN_EOJ	a_deoj =
+		{ EOJ_X1_PROFILE, EOJ_X2_NODE_PROFILE, 0x01 };
+	T_ECN_EDT_HDR a_hdr;
+	ER			a_ret	=	E_OK;
+	ECN_FBS_ID	a_fbs	=	{ 0 };
+	int			a_eoj_ct =	0;
+	int			i;
+	uint8_t		a_count;
+	const EOBJCB	*enod = &eobjcb_table[0];	/* [Jm[h */
+	const EOBJINIB *eobj;
+
+	ECN_DBG_PUT( "do _ecn_tsk_ntf_inl()" );
+
+	memset(&a_hdr, 0, sizeof(a_hdr));
+	a_hdr.ecn_hdr.ehd1 = ECN_EDH1_ECHONET_LITE;
+	a_hdr.ecn_hdr.ehd2 = ECN_EDH2_FORMAT_1;
+	a_hdr.edata.seoj = a_seoj;
+	a_hdr.edata.deoj = a_deoj;
+	a_hdr.edata.esv = ESV_INF;
+	a_hdr.edata.opc = 1;
+	a_hdr.ecn_prp.epc = ECN_EPC_INL_BCS;
+
+	for (i = 0; i < enod->eobjcnt; i++) {
+		eobj = enod->eobjs[i];
+
+		if (!a_eoj_ct) {
+			/* mÛEwb_i[ */
+			a_hdr.ecn_hdr.tid = (uint8_t)_ecn_tsk_new_tid(); /* V[PXÔ¶¬ */
+			a_ret = _ecn_fbs_cre(sizeof(a_hdr), &a_fbs);
+			if (a_ret != E_OK) /* mÛ¸s */
+				goto lb_except;
+			a_ret = _ecn_fbs_add_data(a_fbs, &a_hdr, sizeof(a_hdr));
+			if (a_ret != E_OK) /* f[^ÇÁ¸s */
+				goto lb_except;
+
+			a_fbs.ptr->hdr.type = ECN_MSG_ECHONET;
+			a_fbs.ptr->hdr.sender.id = ENOD_LOCAL_ID;
+			a_fbs.ptr->hdr.target.id = ENOD_MULTICAST_ID;
+			a_fbs.ptr->hdr.reply.id = ENOD_LOCAL_ID;
+			((T_EDATA *)a_fbs.ptr)->hdr.ecn_prp.pdc = 1;	/*  */
+			/* ði[ */
+			a_count = (uint8_t)(enod->eobjcnt - i);
+			if (a_count >= ECN_IST_LST_EOJ_MAX_CT)
+				a_count = ECN_IST_LST_EOJ_MAX_CT;
+			a_ret = _ecn_fbs_add_data_ex(a_fbs, &a_count, sizeof(a_count));
+			if (a_ret != E_OK) /* f[^ÇÁ¸s */
+				goto lb_except;
+		}
+		/* ECHONETIuWFNgID(3byte)ði[ */
+		a_ret = _ecn_fbs_add_data_ex(a_fbs, &eobj->eojx1, sizeof(T_ECN_EOJ));
+		if (a_ret != E_OK) /* f[^ÇÁ¸s */
+			goto lb_except;
+
+		/* EedtTCYÁZ */
+		((T_EDATA *)a_fbs.ptr)->hdr.ecn_prp.pdc += sizeof(T_ECN_EOJ);
+		if (++a_eoj_ct < ECN_IST_LST_EOJ_MAX_CT)
+			continue;
+
+		/* 1AiEXÅÌãÀÉBµ½çAêUM */
+		a_ret = _ecn_tsk_snd_mbx(a_fbs, false);
+		if (a_ret != E_OK) /* f[^M¸s */
+			goto lb_except;
+		a_eoj_ct = 0;
+		a_fbs.ptr = 0;
+	}
+	if (a_eoj_ct) {
+		/* ¢Mf[^ª Á½çAM */
+		a_ret = _ecn_tsk_snd_mbx(a_fbs, false);
+		if (a_ret != E_OK) /* f[^M¸s */
+			goto lb_except;
+		a_fbs.ptr = 0;
+	}
+	goto lb_finally;
+
+lb_except:
+	if (a_fbs.ptr)
+		_ecn_fbs_del(a_fbs);
+
+lb_finally:
+	return a_ret;
+}
+
+const EOBJCB *_ecn_eno_fnd(ECN_ENOD_ID enodid)
+{
+	const EOBJCB *enod = NULL;
+	int i;
+
+	switch (enodid) {
+	case ENOD_MULTICAST_ID:
+	case ENOD_LOCAL_ID:
+	case ENOD_API_ID:
+		enod = &eobjcb_table[0];
+		break;
+	default:
+		i = enodid - ENOD_REMOTE_ID + 1;
+		if ((i >= 1) && (i < tnum_enodid))
+			enod = &eobjcb_table[i];
+#ifdef ECHONET_CONTROLLER_EXTENTION
+		else{
+			ecn_node_t *p_tmp = ecn_agent_find_node(enodid);
+			if (p_tmp == NULL)
+				return NULL;
+			return &p_tmp->eobj;
+		}
+#endif
+		break;
+	}
+
+	return enod;
+}
+
+/*
+ * 3byteÌeobjidÅzñðõ·é
+ */
+const EOBJINIB *_ecn_eoj_fnd(const EOBJCB *fp_nod, const T_ECN_EOJ *fp_eoj)
+{
+	const EOBJINIB	*p_obj;
+	int		i, count = fp_nod->eobjcnt;
+
+#ifdef ECHONET_CONTROLLER_EXTENTION
+	if (fp_nod->eobjs == NULL) {
+		ecn_obj_t *p_tmp = ecn_agent_find_eobj(fp_nod, *fp_eoj);
+		if(p_tmp == NULL)
+			return NULL;
+		return &p_tmp->inib;
+	}
+#endif
+
+	for (i = 0; i < count; i++) {
+		p_obj = fp_nod->eobjs[i];
+
+		if (p_obj->eojx1 != fp_eoj->eojx1)
+			continue;
+		if (p_obj->eojx2 != fp_eoj->eojx2)
+			continue;
+		if (p_obj->eojx3 != fp_eoj->eojx3)
+			continue;
+
+		return p_obj;
+	}
+
+	return 0;
+}
+
+static int _ecn_tsk_ecn_msg_main(ECN_FBS_ID fa_fbs_id, const EOBJINIB *p_obj, ATR eobjatr,
+	const EOBJINIB *p_sobj, ATR sobjatr);
+
+/*
+ * ECHONETpbZ[W
+ */
+static void _ecn_tsk_ecn_msg(intptr_t fa_exinf, ECN_FBS_ID fa_fbs_id)
+{
+	const EOBJCB	*p_nod, *p_snod;
+	const EOBJINIB	*p_obj, *p_sobj = NULL;
+	ATR eobjatr, sobjatr = EPC_NONE;
+	T_ECN_EDT_HDR	*p_esv;
+	ER				a_ret;
+	int				i, count;
+	T_ECN_EOJ		*p_eoj;
+	bool_t			a_prc;
+	bool_t			a_fwd;
+
+#ifdef ECN_DBG_PUT_ENA
+	syslog(LOG_NOTICE, "mbx recv:");
+	_ecn_dbg_bindmp(fa_fbs_id.ptr, fa_fbs_id.ptr->hdr.length);
+#endif
+
+	p_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
+
+	if (p_esv->ecn_hdr.ehd1 != ECN_EDH1_ECHONET_LITE
+	||	p_esv->ecn_hdr.ehd2 != ECN_EDH2_FORMAT_1) {
+		syslog(LOG_WARNING, "_ecn_tsk_ecn_msg() format fault: 0x%02X,0x%02X", p_esv->ecn_hdr.ehd1, p_esv->ecn_hdr.ehd2);
+		return;
+	}
+
+	/* M¶©çm[hðõ */
+	p_nod = _ecn_eno_fnd(fa_fbs_id.ptr->hdr.target.id);
+	/* M³©çm[hðõ */
+	p_snod = _ecn_eno_fnd(fa_fbs_id.ptr->hdr.sender.id);
+	if (p_snod != NULL) {
+		sobjatr = p_snod->profile->eobjatr;
+		/* m[hvt@CÌê */
+		if ((p_esv->edata.seoj.eojx1 == EOJ_X1_PROFILE)
+			&& (p_esv->edata.seoj.eojx2 == EOJ_X2_NODE_PROFILE)) {
+			p_sobj = p_snod->profile;
+		}
+		/* @íIuWFNgÌê */
+		else {
+			p_sobj = _ecn_eoj_fnd(p_snod, &p_esv->edata.seoj);
+		}
+	}
+
+#ifdef ECHONET_CONTROLLER_EXTENTION
+	ecn_agent_proc_ecn_msg(&p_snod, &p_sobj, (T_EDATA *)fa_fbs_id.ptr);
+#endif
+
+	/* m[hàÌ@íIuWFNgðõ */
+	a_prc = false;
+	a_fwd = false;
+	if (p_nod != NULL) {
+		eobjatr = p_nod->profile->eobjatr;
+		p_eoj = &p_esv->edata.deoj;
+		/* m[hvt@CÌê */
+		if ((p_eoj->eojx1 == EOJ_X1_PROFILE)
+			&& (p_eoj->eojx2 == EOJ_X2_NODE_PROFILE)) {
+			if ((p_eoj->eojx3 == p_nod->profile->eojx3)
+				|| (p_eoj->eojx3 == 0)) {
+				/* d¶Às */
+				if (_ecn_tsk_ecn_msg_main(fa_fbs_id, p_nod->profile, eobjatr, p_sobj, sobjatr) == 1)
+					a_fwd = true;
+				a_prc = true;
+			}
+			/* 0x74 vpeBlÊmivjÌêµ½±ÆÉ·é */
+			else if (p_esv->edata.esv == ESV_INFC) {
+				a_prc = true;
+			}
+		}
+		/* @íIuWFNgÌê */
+		else {
+			count = p_nod->eobjcnt;
+#ifdef ECHONET_CONTROLLER_EXTENTION
+			p_obj = NULL;
+#endif
+			for (i = 0; i < count; i++) {
+#ifdef ECHONET_CONTROLLER_EXTENTION
+				if(p_nod->eobjs == NULL)
+					p_obj = ecn_agent_next_eobj(p_nod, p_obj);
+				else
+					p_obj = p_nod->eobjs[i];
+#else
+				p_obj = p_nod->eobjs[i];
+#endif
+				if (p_obj->eojx1 != p_eoj->eojx1)
+					continue;
+				if (p_obj->eojx2 != p_eoj->eojx2)
+					continue;
+				/* CX^XR[hªOÌêA¯¶NXÌSÄÌCX^X¶ */
+				if ((p_obj->eojx3 != p_eoj->eojx3) && (p_eoj->eojx3 != 0))
+					continue;
+
+				/* d¶Às */
+				if (_ecn_tsk_ecn_msg_main(fa_fbs_id, p_obj, eobjatr, p_sobj, sobjatr) == 1)
+					a_fwd = true;
+				a_prc = true;
+			}
+		}
+	}
+	/* @íIuWFNgª©Â©çÈ¢êÅà */
+	if (!a_prc) {
+		/* d¶ÀsióMpj */
+		if (_ecn_tsk_ecn_msg_main(fa_fbs_id, NULL, EPC_NONE, p_sobj, sobjatr) == 1)
+			a_fwd = true;
+	}
+
+	/* ÌêAvP[VÉ]·é */
+	if (a_fwd && (p_esv->ecn_hdr.tid == g_api_tid)) {
+		g_release_esv = false;
+
+		ECN_CAP_PUT( "redirect ecn_svc_mailboxid ¨ ecn_api_mailboxid (esv:0x%02X)",
+			p_esv->edata.esv );
+		fa_fbs_id.ptr->hdr.target.id = ENOD_API_ID;
+		a_ret = snd_mbx(ecn_api_mailboxid, (T_MSG *)fa_fbs_id.ptr);
+		if (a_ret != E_OK) {
+			syslog(LOG_WARNING, "_ecn_tsk_ecn_msg() : snd_mbx() result = %d:%s", a_ret, itron_strerror(a_ret));
+			_ecn_fbs_del(fa_fbs_id);
+		}
+	}
+#ifdef ECHONET_CONTROLLER_EXTENTION
+	ecn_agent_proc_ecn_msg_end();
+#endif
+}
+
+static int _ecn_tsk_ecn_msg_main(ECN_FBS_ID fa_fbs_id, const EOBJINIB *p_obj, ATR eobjatr,
+	const EOBJINIB *p_sobj, ATR sobjatr)
+{
+	int result;
+	T_ECN_EDT_HDR	*p_esv;
+	ECN_FBS_ID		a_fbs_anno = { NULL };
+	bool_t fromapp = sobjatr == EOBJ_LOCAL_NODE;
+
+	p_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
+
+	switch (p_esv->edata.esv) {
+	/* 0x60 vpeBl«Ývisvj */
+	case ESV_SET_I:
+		if (!p_obj) {
+			ECN_DBG_PUT( "_ecn_tsk_ecn_msg_main() eoj %06X not found.",
+				p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3 );
+			result = -1;
+			break;
+		}
+		_ecn_tsk_eoj_set(p_obj, eobjatr, fromapp, false, fa_fbs_id, ESV_NOP, ESV_SET_I_SNA, &a_fbs_anno);	/* 0; 0x50 */
+		result = 0;
+		break;
+
+	/* 0x61 vpeBl«Ývivj */
+	case ESV_SET_C:
+		if (!p_obj) {
+			ECN_DBG_PUT( "_ecn_tsk_ecn_msg_main() eoj %06X not found.",
+				p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3 );
+			result = -1;
+			break;
+		}
+		_ecn_tsk_eoj_set(p_obj, eobjatr, fromapp, false, fa_fbs_id, ESV_SET_RES, ESV_SET_C_SNA, &a_fbs_anno); /* 0x71; 0x51 */
+		result = 0;
+		break;
+
+	/* 0x62 vpeBlÇÝoµv */
+	case ESV_GET:
+		if (!p_obj) {
+			ECN_DBG_PUT( "_ecn_tsk_ecn_msg_main() eoj %06X not found.",
+				p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3 );
+			result = -1;
+			break;
+		}
+		_ecn_tsk_eoj_get(p_obj, eobjatr, false, EPC_RULE_GET, fa_fbs_id, ESV_GET_RES, ESV_GET_SNA); /* 0x72; 0x52 */
+		result = 0;
+		break;
+
+	/* 0x63 vpeBlÊmv */
+	case ESV_INF_REQ:
+		if (!p_obj) {
+			ECN_DBG_PUT( "_ecn_tsk_ecn_msg_main() eoj %06X not found.",
+				p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3 );
+			result = -1;
+			break;
+		}
+		fa_fbs_id.ptr->hdr.reply.id = ENOD_MULTICAST_ID;
+		_ecn_tsk_eoj_get(p_obj, eobjatr, false, (EPC_RULE_GET|EPC_RULE_ANNO), fa_fbs_id, ESV_INF, ESV_INF_SNA); /* 0x73; 0x53 */
+		result = 0;
+		break;
+
+	/* 0x6E vpeBl«ÝEÇÝoµv */
+	case ESV_SET_GET:
+		if (!p_obj) {
+			ECN_DBG_PUT( "_ecn_tsk_ecn_msg_main() eoj %06X not found.",
+				p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3 );
+			result = -1;
+			break;
+		}
+		_ecn_tsk_eoj_set_get(p_obj, eobjatr, fromapp, fa_fbs_id, ESV_SET_GET_RES, ESV_SET_GET_SNA, &a_fbs_anno); /* 0x7E; 0x5E */
+		result = 0;
+		break;
+
+	/* 0x74 vpeBlÊmivj */
+	case ESV_INFC:
+		if (!p_sobj)
+			_ecn_tsk_eoj_res(fa_fbs_id, ESV_INFC_RES, ESV_INFC_RES); /* 0x74; 0 */
+		else if (fromapp)
+			_ecn_tsk_eoj_get(p_sobj, sobjatr, true, (EPC_RULE_GET|EPC_RULE_ANNO), fa_fbs_id, ESV_INFC, ESV_NOP); /* 0x74; 0 */
+		else
+			_ecn_tsk_eoj_set(p_sobj, sobjatr, fromapp, true, fa_fbs_id, ESV_INFC_RES, ESV_INFC_RES, &a_fbs_anno); /* 0x7A; 0 */
+		result = 0;
+		break;
+
+	/* 0x60 vpeBl«Ývisvj */
+	case ESV_SET_I_SNA:		/* 0x50 vpeBl«ÝvsÂ */
+		result = 1;
+		break;
+
+	/* 0x61 vpeBl«Ývivj */
+	case ESV_SET_RES:		/* 0x71 vpeBl«Ý */
+	case ESV_SET_C_SNA:		/* 0x51 vpeBl«ÝvsÂ */
+		result = 1;
+		break;
+
+	/* 0x62 vpeBlÇÝoµv */
+	case ESV_GET_RES:		/* 0x72 vpeBlÇÝoµ */
+	case ESV_GET_SNA:		/* 0x52 vpeBlÇÝoµsÂ */
+		if (!p_sobj) {
+			ECN_DBG_PUT( "_ecn_tsk_ecn_msg_main() eoj %06X not found.",
+				p_esv->edata.seoj.eojx1 << 16 | p_esv->edata.seoj.eojx2 << 8 | p_esv->edata.seoj.eojx3 );
+			result = -1;
+			break;
+		}
+		_ecn_tsk_eoj_set(p_sobj, sobjatr, fromapp, true, fa_fbs_id, ESV_NOP, ESV_NOP, &a_fbs_anno); /* 0; 0 */
+		result = 1;
+		break;
+
+	/* 0x63 vpeBlÊmv */
+	case ESV_INF:			/* 0x73 vpeBlÊm */
+	case ESV_INF_SNA:		/* 0x53 vpeBlÊmsÂ */
+		if (!p_sobj) {
+			ECN_DBG_PUT( "_ecn_tsk_ecn_msg_main() eoj %06X not found.",
+				p_esv->edata.seoj.eojx1 << 16 | p_esv->edata.seoj.eojx2 << 8 | p_esv->edata.seoj.eojx3 );
+			result = -1;
+			break;
+		}
+		_ecn_tsk_eoj_set(p_sobj, sobjatr, fromapp, true, fa_fbs_id, ESV_NOP, ESV_NOP, &a_fbs_anno); /* 0; 0 */
+		result = 1;
+		break;
+
+	/* 0x6E vpeBl«ÝEÇÝoµv */
+	case ESV_SET_GET_RES:	/* 0x7E vpeBl«ÝEÇÝoµ */
+	case ESV_SET_GET_SNA:	/* 0x5E vpeBl«ÝEÇÝoµsÂ */
+		if (!p_sobj) {
+			ECN_DBG_PUT( "_ecn_tsk_ecn_msg_main() eoj %06X not found.",
+				p_esv->edata.seoj.eojx1 << 16 | p_esv->edata.seoj.eojx2 << 8 | p_esv->edata.seoj.eojx3 );
+			result = -1;
+			break;
+		}
+		_ecn_tsk_eoj_set_get_res(p_sobj, sobjatr, fromapp, fa_fbs_id, &a_fbs_anno); /* 0x7A; 0 */
+		result = 1;
+		break;
+
+	/* 0x74 vpeBlÊmivj */
+	case ESV_INFC_RES:		/* 0x7A vpeBlÊm */
+		result = 1;
+		break;
+
+	default:
+		syslog(LOG_WARNING, "_ecn_tsk_ecn_msg_main() esv 0x%02X undefined.", p_esv->edata.esv);
+		result = -1;
+		break;
+	}
+
+	/* vpeBÊmvðM */
+	if (a_fbs_anno.ptr != NULL) {
+		ER a_ret = _ecn_tsk_snd_mbx(a_fbs_anno, true);
+		if (a_ret != E_OK)
+			_ecn_fbs_del(a_fbs_anno);
+	}
+
+	return result;
+}
+
+#ifdef ECN_DBG_PUT_ENA
+static void f_put_fbs_eoj(const char *fp_fncnm, const char *fp_varnm,
+	ECN_FBS_ID fa_fbs_id);
+static void f_put_fbs_eoj(const char *fp_fncnm, const char *fp_varnm,
+	ECN_FBS_ID fa_fbs_id)
+{
+	ECN_DBG_PUT( "%s() %s eoj src:%06X dest:%06X",
+		fp_fncnm, fp_varnm,
+		((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.seoj.eojx1 << 16 | ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.seoj.eojx2 << 8 | ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.seoj.eojx3,
+		((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.deoj.eojx1 << 16 | ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.deoj.eojx2 << 8 | ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.deoj.eojx3 );
+}
+#else
+#define f_put_fbs_eoj(f,v,r)
+#endif /* #ifdef ECN_DBG_PUT_ENA */
+
+static const EPRPINIB *_ecn_tsk_eoj_get_property(const EOBJINIB *fp_obj, uint8_t fa_epc);
+static const EPRPINIB *_ecn_tsk_eoj_get_property(const EOBJINIB *fp_obj, uint8_t fa_epc)
+{
+	const EPRPINIB	*p = fp_obj->eprp;
+	uint_t			i;
+#ifdef ECHONET_CONTROLLER_EXTENTION
+	if (fp_obj->eprpcnt == 0) {
+		return ecn_agent_get_property(fp_obj, fa_epc, p);
+	}
+#endif
+	for (i = 0; i < fp_obj->eprpcnt; i++, p++) {
+		if (p->eprpcd != fa_epc)
+			continue;
+
+		return p;
+	}
+	ECN_DBG_PUT( "_ecn_tsk_eoj_get_property(0x%02X-0x%02X-0x%02X, epc:0x%02X) not found.",
+		fp_obj->eojx1, fp_obj->eojx2, fp_obj->eojx3,
+		fa_epc );
+
+	return NULL;
+}
+
+static int _ecn_tsk_eoj_set_edt(const EPRPINIB *fp_prp, void *fp_src, int fa_srcsz,
+	bool_t *fa_anno);
+static int _ecn_tsk_eoj_set_edt(const EPRPINIB *fp_prp, void *fp_src, int fa_srcsz,
+	bool_t *fa_anno)
+{
+	if (!fp_prp->eprpset)
+		return -1;
+
+	ECN_DBG_PUT( "_ecn_tsk_eoj_set_edt(epc:0x%02X) call eprpset()",
+		fp_prp->eprpcd );
+
+	return fp_prp->eprpset(fp_prp, fp_src, fa_srcsz, fa_anno);
+}
+
+static int _ecn_tsk_eoj_get_edt(const EPRPINIB *fp_prp, void *fp_dst, int fa_dstsz);
+static int _ecn_tsk_eoj_get_edt(const EPRPINIB *fp_prp, void *fp_dst, int fa_dstsz)
+{
+	if (fa_dstsz < fp_prp->eprpsz)
+		return -1;
+	if (!fp_prp->eprpget)
+		return -1;
+
+	ECN_DBG_PUT( "_ecn_tsk_eoj_get_edt(epc:0x%02X) call eprpget()",
+		fp_prp->eprpcd );
+
+	return fp_prp->eprpget(fp_prp, fp_dst, fp_prp->eprpsz);
+}
+
+static ID _ecn_tsk_get_prp_pce(ECN_FBS_ID fa_fbs_id, T_ECN_PRP *fp_prp,
+	uint8_t *fp_blk);
+
+/*
+ * ECN_FBS_ID©çT_ECN_PRP1Æ»Ìtf[^(edt)ðoµAedtÌ|C^ðÔ·
+ * ø
+ * ECN_FBS_ID fa_fbs_id					ÇÝæéFBS
+ * T_ECN_PRP *fp_prp					epc+pdcÌi[æ
+ * uint8_t *fp_blk						ìÆpÌ|C^
+ * ³íF|C^ NG:0
+ */
+static ID _ecn_tsk_get_prp_pce(ECN_FBS_ID fa_fbs_id, T_ECN_PRP *fp_prp,
+	uint8_t *fp_blk)
+{
+	int		a_size;
+	ER		a_ret;
+
+	memset(fp_blk, 0, sizeof(T_ECN_SUB_BLK));
+
+	/* T_ECN_PRPª(epc,pdc)ðÇÝæé */
+	a_size = 0;
+	a_ret = _ecn_fbs_get_data(fa_fbs_id, fp_prp, sizeof(*fp_prp), &a_size);
+	if ((a_ret != 0) || a_size < (int)sizeof(*fp_prp)) {
+		ECN_DBG_PUT( "_ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret) );
+		return E_OBJ;
+	}
+
+	if (0 < fp_prp->pdc) {
+		/* tf[^ª(edt)ðÇÝæé */
+		a_size = 0;
+		a_ret = _ecn_fbs_get_data(fa_fbs_id, fp_blk, fp_prp->pdc, &a_size);
+		if ((a_ret != 0) || a_size < (int)fp_prp->pdc) {
+			ECN_DBG_PUT( "_ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret) );
+			return E_OBJ;
+		}
+	}
+
+	return E_OK;
+}
+
+static ER _ecn_tsk_eoj_set_main(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp, bool_t fa_update,
+	ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, ECN_FBS_ID *fa_fbs_anno, int a_count,
+	int *p_sw_ok);
+/* vpeBl«ÝÀs */
+static ER _ecn_tsk_eoj_set_main(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp, bool_t fa_update,
+	ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, ECN_FBS_ID *fa_fbs_anno, int a_count,
+	int *p_sw_ok)
+{
+	uint8_t p_edt[256];
+	T_ECN_PRP			a_prp;			/* epc+pdc */
+	const EPRPINIB		*a_eprp;
+	int			i, a_ans;
+	ER			a_ret;
+	uint8_t		a_size;
+	bool_t		a_anno = false, a_update;
+
+	((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = 0;
+
+	for (i = 0; i < a_count; i++) {
+		/* ECN_FBS_ID©çT_ECN_PRP1Æ»Ìtf[^ðoµA»Ì|C^ðÔ· */
+		a_ret = _ecn_tsk_get_prp_pce(fa_fbs_id, &a_prp, p_edt);
+		if (a_ret != E_OK) {
+			ECN_DBG_PUT( "_ecn_tsk_eoj_set_main(): _ecn_tsk_get_prp_pce() fault." );
+			goto lb_except;
+		}
+
+		/* vpeBÌÝè set_prp(obj, reqp, resp) */
+		a_size = a_prp.pdc;
+		/* obj,epcÉÎ·ésetÖðÄÔ */
+		a_eprp = _ecn_tsk_eoj_get_property(fp_obj, a_prp.epc);
+		if ((a_eprp != NULL)
+			&& (fa_update || (((a_eprp->eprpatr & EPC_RULE_SET) != 0) || fa_fromapp))) {
+			a_anno = (fa_eobjatr == EOBJ_LOCAL_NODE) && ((a_eprp->eprpatr & EPC_ANNOUNCE) != 0);
+			a_update = a_anno;
+			a_ans = _ecn_tsk_eoj_set_edt(a_eprp, p_edt, a_size, &a_update);
+			if (a_anno && (a_ans > 0))
+				a_anno = a_update;
+		}
+		else {
+			a_ans = -1;
+		}
+		if (a_ans == a_size) {
+			ECN_DBG_PUT( "_ecn_tsk_eoj_set_edt(0x%06X, 0x%02x, 0x%02X..., %u) ok.",
+				fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
+				a_prp.epc, p_edt[0], a_size );
+			a_prp.pdc = 0;
+		} else {
+			ECN_DBG_PUT( "_ecn_tsk_eoj_set_edt(0x%06X, 0x%02x, 0x%02X..., %u) fault.",
+				fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
+				a_prp.epc, p_edt[0], a_size );
+			*p_sw_ok = 0;	/* vpeBÝè¸s */
+			/* ÌêEDTÍÝèµÈ¢ */
+			if (fa_update)
+				a_prp.pdc = 0;
+		}
+
+		/* d¶pÉf[^ÇÁ(epc,pdcÌ2byte) */
+		a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &a_prp, sizeof(a_prp));
+		if (a_ret) {
+			ECN_DBG_PUT( "_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) );
+			goto lb_except;
+		}
+
+		if (0 < a_prp.pdc) {
+			/* d¶pÉf[^ÇÁ(edt n-byte) */
+			a_ret = _ecn_fbs_add_data_ex(a_fbs_res, p_edt, a_prp.pdc);
+			if (a_ret) {
+				ECN_DBG_PUT( "_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) );
+				goto lb_except;
+			}
+		}
+		((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc ++;
+
+		/* vpeBÊm èÌê */
+		if (a_anno && (a_ans == a_size)) {
+			if (fa_fbs_anno->ptr == NULL) {
+				_ecn_tsk_mk_esv(fa_fbs_anno, (ID)1, (((intptr_t)fp_obj - (intptr_t)eobjinib_table) / sizeof(EPRPINIB)) + 1,
+					a_prp.epc, 0, NULL, ESV_INF_REQ);
+			}
+			else{
+				ecn_add_edt((T_EDATA *)fa_fbs_anno->ptr, a_prp.epc, 0, 0);
+			}
+		}
+	}
+	a_ret = E_OK; /* ok */
+	goto lb_finally;
+
+lb_except:
+	a_ret = E_SYS;
+
+lb_finally:
+	return a_ret;
+}
+
+static ER _ecn_tsk_eoj_get_main(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_forward, ATR fa_access,
+	ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, int a_count, int *p_sw_ok);
+/* vpeBlÇÝoµÀs */
+static ER _ecn_tsk_eoj_get_main(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_forward, ATR fa_access,
+	ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, int a_count, int *p_sw_ok)
+{
+	uint8_t p_edt[256];	/* ìÆÌæ */
+	const EPRPINIB		*a_eprp;
+	ER					a_ret		=	E_SYS;
+	T_ECN_PRP			a_prp;			/* epc+pdc */
+	int		i, a_ans;
+
+	((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = 0;
+
+	for (i = 0; i < a_count; i++) {
+		/* ECN_FBS_ID©çT_ECN_PRP1Æ»Ìtf[^ðo */
+		a_ret = _ecn_tsk_get_prp_pce(fa_fbs_id, &a_prp, p_edt);
+		if (a_ret != E_OK) {
+			ECN_DBG_PUT( "_ecn_tsk_eoj_get_main(): _ecn_tsk_get_prp_pce() fault." );
+			goto lb_except;
+		}
+
+		/* vpeBÌæ¾ get_eprp(obj, reqp, resp, size) */
+		memset(p_edt, 0, sizeof(p_edt));
+		/* obj,epcÉÎ·égetÖðÄÔ */
+		a_eprp = _ecn_tsk_eoj_get_property(fp_obj, a_prp.epc);
+		if ((a_eprp != NULL) && (((a_eprp->eprpatr & fa_access) != 0) && (fa_eobjatr == EOBJ_LOCAL_NODE) || fa_forward)) {
+			a_ans = _ecn_tsk_eoj_get_edt(a_eprp, p_edt, sizeof(p_edt));
+		}
+		else {
+			a_ans = -1;
+		}
+		if (0 < a_ans && a_ans <= (int)UINT8_MAX) {
+			a_prp.pdc = (uint8_t)a_ans;
+		} else {
+			*p_sw_ok = 0;	/* vpeBæ¾¸s */
+			a_ans = 0;
+			a_prp.pdc = 0;
+		}
+
+		/* d¶pÉf[^ÇÁ(epc,pdcÌ2byte) */
+		a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &a_prp, sizeof(a_prp));
+		if (a_ret) {
+			ECN_DBG_PUT( "_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) );
+			goto lb_except;
+		}
+		if (0 < a_ans) {
+			/* tf[^ÇÁ */
+			a_ret = _ecn_fbs_add_data_ex(a_fbs_res, p_edt, a_ans);
+			if (a_ret) {
+				ECN_DBG_PUT( "_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) );
+				goto lb_except;
+			}
+		}
+		((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc ++;
+	}
+	a_ret = E_OK; /* ok */
+	goto lb_finally;
+
+lb_except:
+	a_ret = E_SYS;
+
+lb_finally:
+	return a_ret;
+}
+
+static ER _ecn_tsk_eoj_res_main(ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, int a_count, int *p_sw_ok);
+/* vpeBlÇÝoµÀs */
+static ER _ecn_tsk_eoj_res_main(ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, int a_count, int *p_sw_ok)
+{
+	uint8_t p_edt[256];
+	ER					a_ret		=	E_SYS;
+	T_ECN_PRP			a_prp;			/* epc+pdc */
+	int		i;
+
+	((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = 0;
+
+	for (i = 0; i < a_count; i++) {
+		/* ECN_FBS_ID©çT_ECN_PRP1Æ»Ìtf[^ðo */
+		a_ret = _ecn_tsk_get_prp_pce(fa_fbs_id, &a_prp, p_edt);
+		if (a_ret != E_OK) {
+			ECN_DBG_PUT( "_ecn_tsk_eoj_get_main(): _ecn_tsk_get_prp_pce() fault." );
+			goto lb_except;
+		}
+
+		a_prp.pdc = 0;
+
+		/* d¶pÉf[^ÇÁ(epc,pdcÌ2byte) */
+		a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &a_prp, sizeof(a_prp));
+		if (a_ret) {
+			ECN_DBG_PUT( "_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) );
+			goto lb_except;
+		}
+		((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc++;
+	}
+	a_ret = E_OK; /* ok */
+	goto lb_finally;
+
+lb_except:
+	a_ret = E_SYS;
+
+lb_finally:
+	return a_ret;
+}
+
+/* vpeBlÇÝòÎµÀs */
+static ER _ecn_tsk_eoj_skip_main(const EOBJINIB *fp_obj, ECN_FBS_ID fa_fbs_id,
+	int a_count);
+static ER _ecn_tsk_eoj_skip_main(const EOBJINIB *fp_obj, ECN_FBS_ID fa_fbs_id,
+	int a_count)
+{
+	T_ECN_PRP	a_prp;			/* epc+pdc */
+	int			i, a_size;
+	ER			a_ret;
+
+	for (i = 0; i < a_count; i++) {
+		/* T_ECN_PRPª(epc,pdc)ðÇÝæé */
+		a_size = 0;
+		a_ret = _ecn_fbs_get_data(fa_fbs_id, &a_prp, sizeof(a_prp), &a_size);
+		if (a_ret || a_size < (int)sizeof(a_prp)) {
+			ECN_DBG_PUT( "_ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret) );
+			goto lb_except;
+		}
+
+		/* pdcªÇÝòÎµ */
+		a_ret = _ecn_fbs_seek_rpos(fa_fbs_id, a_prp.pdc);
+		if (a_ret) {
+			ECN_DBG_PUT( "_ecn_fbs_seek_rpos() result = %d:%s", a_ret, itron_strerror(a_ret) );
+			goto lb_except;
+		}
+	}
+	a_ret = E_OK; /* ok */
+	goto lb_finally;
+
+lb_except:
+	a_ret = E_SYS;
+
+lb_finally:
+	return a_ret;
+}
+
+static void _ecn_tsk_mk_rsp_hdr(const EOBJINIB *fp_obj, T_ECN_EDT_HDR *fp_rsp_esv,
+	T_ECN_EDT_HDR const *fp_req_esv);
+/* d¶Ýè */
+static void _ecn_tsk_mk_rsp_hdr(const EOBJINIB *fp_obj, T_ECN_EDT_HDR *fp_rsp_esv,
+	T_ECN_EDT_HDR const *fp_req_esv)
+{
+	fp_rsp_esv->ecn_hdr.ehd1 = ECN_EDH1_ECHONET_LITE;
+	fp_rsp_esv->ecn_hdr.ehd2 = ECN_EDH2_FORMAT_1;
+	fp_rsp_esv->ecn_hdr.tid = fp_req_esv->ecn_hdr.tid;
+	fp_rsp_esv->edata.seoj.eojx1 = fp_obj->eojx1;
+	fp_rsp_esv->edata.seoj.eojx2 = fp_obj->eojx2;
+	fp_rsp_esv->edata.seoj.eojx3 = fp_obj->eojx3;
+	fp_rsp_esv->edata.deoj = fp_req_esv->edata.seoj;
+}
+
+static void _ecn_tsk_mk_rsp_hdr_res(T_ECN_EDT_HDR *fp_rsp_esv,
+	T_ECN_EDT_HDR const *fp_req_esv);
+static void _ecn_tsk_mk_rsp_hdr_res(T_ECN_EDT_HDR *fp_rsp_esv,
+	T_ECN_EDT_HDR const *fp_req_esv)
+{
+	fp_rsp_esv->ecn_hdr.ehd1 = ECN_EDH1_ECHONET_LITE;
+	fp_rsp_esv->ecn_hdr.ehd2 = ECN_EDH2_FORMAT_1;
+	fp_rsp_esv->ecn_hdr.tid = fp_req_esv->ecn_hdr.tid;
+	fp_rsp_esv->edata.seoj = fp_req_esv->edata.deoj;
+	fp_rsp_esv->edata.deoj = fp_req_esv->edata.seoj;
+}
+
+/* d¶pfbsÝè */
+static void _ecn_tsk_set_rsp_fbs(ECN_FBS_ID fa_rsp_fbs, T_ECN_FST_BLK const *fp_req_ptr);
+/* d¶pfbsÝè(sender/targetÌÝè) */
+static void _ecn_tsk_set_rsp_fbs(ECN_FBS_ID fa_rsp_fbs, T_ECN_FST_BLK const *fp_req_ptr)
+{
+	fa_rsp_fbs.ptr->hdr.type = ECN_MSG_ECHONET;
+	fa_rsp_fbs.ptr->hdr.sender.id = ENOD_LOCAL_ID;
+	fa_rsp_fbs.ptr->hdr.target.id = fp_req_ptr->hdr.reply.id;
+	fa_rsp_fbs.ptr->hdr.reply.id = ENOD_LOCAL_ID;
+}
+
+/* vpeBl«Ýv	*/
+static void _ecn_tsk_eoj_set(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp, bool_t fa_update,
+	ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv,
+	ECN_FBS_ID *fa_fbs_anno)
+{
+	T_ECN_EDT_HDR	const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
+	T_ECN_EDT_HDR	a_ecn_hdp;
+	ECN_FBS_ID		a_fbs_res	= { 0 };
+	ER		a_ret;
+	int		a_size;
+	int		a_sw_ok = 1;
+	T_ECN_EOJ	eoj;
+
+	memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
+
+	/* ÅåTCYÌæ¾ */
+	a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
+
+	/* d¶pÌæ¾ */
+	a_ret = _ecn_fbs_cre(a_size, &a_fbs_res);
+	if (a_ret != E_OK || !a_fbs_res.ptr) /* mÛ¸s */
+		return;
+
+	/* d¶Ýè */
+	if(p_req_esv->edata.deoj.eojx3 != 0)
+		_ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
+	else
+		_ecn_tsk_mk_rsp_hdr(fp_obj, &a_ecn_hdp, p_req_esv);
+
+	/* ³íÌd¶ªvpeBlÊmÌê */
+	if (fa_res_esv == ESV_INFC_RES) {
+		/* M³Æ¶æðüêÖ¦ */
+		eoj = a_ecn_hdp.edata.seoj;
+		a_ecn_hdp.edata.seoj = a_ecn_hdp.edata.deoj;
+		a_ecn_hdp.edata.deoj = eoj;
+	}
+
+	f_put_fbs_eoj("_ecn_tsk_eoj_set", "fa_fbs_id", fa_fbs_id); /* s/deoj fobOoÍ */
+
+	/* d¶pÉf[^ÇÁ */
+	a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &a_ecn_hdp,
+				sizeof(a_ecn_hdp.ecn_hdr) + sizeof(a_ecn_hdp.edata));
+	if (a_ret)
+		goto lb_except;
+
+	/* payloadæªÌT_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)ðÇÝòÎ· */
+	a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
+	if (a_ret)
+		goto lb_except;
+
+	/* d¶pfbsÝè */
+	_ecn_tsk_set_rsp_fbs(a_fbs_res, fa_fbs_id.ptr);
+
+	/* vpeBl«ÝÀs */
+	a_ret = _ecn_tsk_eoj_set_main(fp_obj, fa_eobjatr, fa_fromapp, fa_update, fa_fbs_id, a_fbs_res,
+		fa_fbs_anno, p_req_esv->edata.opc, &a_sw_ok);
+	if (a_ret)
+		goto lb_except;
+
+	/* vÌê */
+	if (a_sw_ok) {
+		if (!fa_res_esv) {
+			/* svÌê */
+			_ecn_fbs_del(a_fbs_res);
+			goto lb_finally;
+		}
+		/* Ýè¬÷ */
+		((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_res_esv;
+	} else {
+		if (!fa_sna_esv) {
+			/* svÌê */
+			_ecn_fbs_del(a_fbs_res);
+			goto lb_finally;
+		}
+		/* Ýè¸s */
+		((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_sna_esv;
+	}
+	/* M */
+	a_ret = _ecn_tsk_snd_mbx(a_fbs_res, false);
+	if (a_ret == E_OK)
+		goto lb_finally;
+
+lb_except:
+	/* f[^M¸sµ½çÌæðú */
+	if (a_fbs_res.ptr)
+		_ecn_fbs_del(a_fbs_res);
+
+lb_finally:
+	return;
+}
+
+/* vpeBlÇÝoµv	*/
+static void _ecn_tsk_eoj_get(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_forward, ATR fa_access,
+	ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv)
+{
+	T_ECN_EDT_HDR	const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
+	T_ECN_EDT_HDR	a_ecn_hdp;
+	ECN_FBS_ID		a_fbs_res	= { 0 };
+	ER		a_ret;
+	int		a_size;
+	int		a_sw_ok = 1;
+
+	memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
+
+	/* úæ¾TCY */
+	a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
+
+	/* d¶pÌæ¾ */
+	a_ret = _ecn_fbs_cre(a_size, &a_fbs_res);
+	if (a_ret != E_OK || !a_fbs_res.ptr) { /* mÛ¸s */
+		ECN_DBG_PUT( "_ecn_fbs_cre() result = %d:%s", a_ret, itron_strerror(a_ret) );
+		goto lb_finally;
+	}
+
+	/* d¶Ýè */
+	if(p_req_esv->edata.deoj.eojx3 != 0)
+		_ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
+	else
+		_ecn_tsk_mk_rsp_hdr(fp_obj, &a_ecn_hdp, p_req_esv);
+
+	f_put_fbs_eoj("_ecn_tsk_eoj_get", "fa_fbs_id", fa_fbs_id); /* s/deoj fobOoÍ */
+
+	/* d¶pÉf[^ÇÁ */
+	a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &a_ecn_hdp,
+			sizeof(a_ecn_hdp.ecn_hdr) + sizeof(a_ecn_hdp.edata));
+	if (a_ret) {
+		ECN_DBG_PUT( "_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) );
+		goto lb_except;
+	}
+
+	/* payloadæªÌT_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)ðÇÝòÎ· */
+	a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
+	if (a_ret) {
+		ECN_DBG_PUT( "_ecn_fbs_set_rpos() result = %d:%s", a_ret, itron_strerror(a_ret) );
+		goto lb_except;
+	}
+
+	/* d¶pfbsÝè */
+	_ecn_tsk_set_rsp_fbs(a_fbs_res, fa_fbs_id.ptr);
+
+	/* vpeBlÇÝÝÀs */
+	a_ret = _ecn_tsk_eoj_get_main(fp_obj, fa_eobjatr, fa_forward, fa_access, fa_fbs_id, a_fbs_res,
+		((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.opc, &a_sw_ok);
+	if (a_ret) {
+		ECN_DBG_PUT( "_ecn_tsk_eoj_get_main() result = %d:%s", a_ret, itron_strerror(a_ret) );
+		goto lb_except;
+	}
+
+	if (a_sw_ok) {
+		if (!fa_res_esv) {
+			/* svÌê */
+			_ecn_fbs_del(a_fbs_res);
+			goto lb_finally;
+		}
+		/* Ýè¬÷ */
+		((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_res_esv;
+	} else {
+		if (!fa_sna_esv) {
+			/* svÌê */
+			_ecn_fbs_del(a_fbs_res);
+			goto lb_finally;
+		}
+		/* Ýè¸s */
+		((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_sna_esv;
+	}
+	/* M */
+	a_ret = _ecn_tsk_snd_mbx(a_fbs_res, false);
+	if (a_ret != E_OK) {
+		ECN_DBG_PUT( "_ecn_tsk_snd_mbx() result = %d:%s", a_ret, itron_strerror(a_ret) );
+		goto lb_except;
+	}
+	goto lb_finally;
+
+lb_except:
+	/* f[^M¸sµ½çÌæðú */
+	if (a_fbs_res.ptr)
+		_ecn_fbs_del(a_fbs_res);
+
+lb_finally:
+	return;
+}
+
+/* vpeBlÇÝoµv	*/
+static void _ecn_tsk_eoj_res(ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv,
+	ECN_SRV_CODE fa_sna_esv)
+{
+	T_ECN_EDT_HDR	const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
+	T_ECN_EDT_HDR	a_ecn_hdp;
+	ECN_FBS_ID		a_fbs_res	= { 0 };
+	ER		a_ret;
+	int		a_size;
+	int		a_sw_ok = 1;
+
+	memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
+
+	/* úæ¾TCY */
+	a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
+
+	/* d¶pÌæ¾ */
+	a_ret = _ecn_fbs_cre(a_size, &a_fbs_res);
+	if (a_ret != E_OK || !a_fbs_res.ptr) { /* mÛ¸s */
+		ECN_DBG_PUT( "_ecn_fbs_cre() result = %d:%s", a_ret, itron_strerror(a_ret) );
+		goto lb_finally;
+	}
+
+	/* d¶Ýè						*/
+	_ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
+
+	f_put_fbs_eoj("_ecn_tsk_eoj_res", "fa_fbs_id", fa_fbs_id); /* s/deoj fobOoÍ */
+
+	/* d¶pÉf[^ÇÁ */
+	a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &a_ecn_hdp,
+			sizeof(a_ecn_hdp.ecn_hdr) + sizeof(a_ecn_hdp.edata));
+	if (a_ret) {
+		ECN_DBG_PUT( "_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) );
+		goto lb_except;
+	}
+
+	/* payloadæªÌT_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)ðÇÝòÎ· */
+	a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
+	if (a_ret) {
+		ECN_DBG_PUT( "_ecn_fbs_set_rpos() result = %d:%s", a_ret, itron_strerror(a_ret) );
+		goto lb_except;
+	}
+
+	/* d¶pfbsÝè */
+	_ecn_tsk_set_rsp_fbs(a_fbs_res, fa_fbs_id.ptr);
+
+	/* vpeBlÇÝÝÀs */
+	a_ret = _ecn_tsk_eoj_res_main(fa_fbs_id, a_fbs_res,
+		((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.opc, &a_sw_ok);
+	if (a_ret) {
+		ECN_DBG_PUT( "_ecn_tsk_eoj_res_main() result = %d:%s", a_ret, itron_strerror(a_ret) );
+		goto lb_except;
+	}
+
+	if (a_sw_ok) {
+		if (!fa_res_esv) {
+			/* svÌê */
+			_ecn_fbs_del(a_fbs_res);
+			goto lb_finally;
+		}
+		/* Ýè¬÷ */
+		((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_res_esv;
+	} else {
+		if (!fa_sna_esv) {
+			/* svÌê */
+			_ecn_fbs_del(a_fbs_res);
+			goto lb_finally;
+		}
+		/* Ýè¸s */
+		((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_sna_esv;
+	}
+	/* M */
+	a_ret = _ecn_tsk_snd_mbx(a_fbs_res, false);
+	if (a_ret != E_OK) {
+		ECN_DBG_PUT( "_ecn_tsk_snd_mbx() result = %d:%s", a_ret, itron_strerror(a_ret) );
+		goto lb_except;
+	}
+	goto lb_finally;
+
+lb_except:
+	/* f[^M¸sµ½çÌæðú */
+	if (a_fbs_res.ptr)
+		_ecn_fbs_del(a_fbs_res);
+
+lb_finally:
+	return;
+}
+
+static void _ecn_tsk_eoj_set_get(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp,
+	ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv,
+	ECN_FBS_ID *fa_fbs_anno)
+{
+	T_ECN_EDT_HDR	const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
+	T_ECN_EDT_HDR	a_ecn_hdp;
+	ECN_FBS_ID		a_fbs_res	= { 0 };
+	int				a_rdprp_wrpos;	/*	vpeBÇÝÝ«ÝÌwbhÊu	*/
+	ER		a_ret;
+	int		i, a_size, a_rdlen;
+	int		a_sw_ok = 1;
+	int		a_count = ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.opc;	/* vpeB */
+
+	memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
+
+	ECN_DBG_PUT( "_ecn_tsk_eoj_set_get() eoj:%06X",
+		fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3 );
+
+	/* úæ¾TCY */
+	a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
+
+	/* d¶pÌæ¾ */
+	a_ret = _ecn_fbs_cre(a_size, &a_fbs_res);
+	if (a_ret != E_OK || !a_fbs_res.ptr) /* mÛ¸s */
+		goto lb_finally;
+
+	/* d¶Ýè */
+	if(p_req_esv->edata.deoj.eojx3 != 0)
+		_ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
+	else
+		_ecn_tsk_mk_rsp_hdr(fp_obj, &a_ecn_hdp, p_req_esv);
+	a_size -= sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY);
+
+	f_put_fbs_eoj("_ecn_tsk_eoj_set_get", "fa_fbs_id", fa_fbs_id); /* s/deoj fobOoÍ */
+
+	/* d¶pÉf[^ÇÁ */
+	a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &a_ecn_hdp,
+				sizeof(a_ecn_hdp.ecn_hdr) + sizeof(a_ecn_hdp.edata));
+	if (a_ret)
+		goto lb_except;
+
+	/* payloadæªÌT_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)ðÇÝòÎ· */
+	a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
+	if (a_ret)
+		goto lb_except;
+
+	/* d¶pfbsÝè */
+	_ecn_tsk_set_rsp_fbs(a_fbs_res, fa_fbs_id.ptr);
+
+	/* vpeBl«ÝÀs */
+	a_ret = _ecn_tsk_eoj_set_main(fp_obj, fa_eobjatr, fa_fromapp, false, fa_fbs_id, a_fbs_res,
+		fa_fbs_anno, a_count, &a_sw_ok);
+	if (a_ret) {
+		syslog(LOG_WARNING, "_ecn_tsk_eoj_set_get() eoj:%06X _ecn_tsk_eoj_set_main() fault. result = %d",
+			fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
+			a_ret);
+		goto lb_except;
+	}
+	ECN_DBG_PUT( "_ecn_tsk_eoj_set_get() eoj:%06X _ecn_tsk_eoj_set_main() ok sw_ok:%s",
+		fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
+		(a_sw_ok ? "true" : "false") );
+
+	/* ÌðÇÝæé(1byte)						*/
+	/* ¨ ECHONET-Lite_Ver.1.10_02.pdf p.40 [OPCGet]	*/
+	a_rdlen = i = 0;
+	a_ret = _ecn_fbs_get_data(fa_fbs_id, &i, 1, &a_rdlen);
+	if (a_ret < 0 || a_rdlen < 1)
+		goto lb_except;	/* NG */
+	a_count = *(uint8_t *)&i;
+
+	/* vpeBÇÝÝ«ÝÌwbhîñðL^ */
+	a_rdprp_wrpos = _ecn_fbs_get_datalen(a_fbs_res);
+
+	/* d¶pÉf[^ÇÁ (OPCGet 1byte) */
+	a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &i, 1);
+	if (a_ret)
+		goto lb_except;
+
+	/* ±Ì_ÅÌd¶vpeBðL^ */
+	i = ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc;
+	((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = 0;
+
+	/* vpeBlÇÝÝÀs */
+	a_ret = _ecn_tsk_eoj_get_main(fp_obj, fa_eobjatr, false, EPC_RULE_GET, fa_fbs_id, a_fbs_res,
+		a_count, &a_sw_ok);
+	if (a_ret) {
+		syslog(LOG_WARNING, "%s _ecn_tsk_eoj_set_get() eoj:%06X _ecn_tsk_eoj_get_main() fault. result = %d",
+			ECN_SRC_LOC,
+			fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
+			a_ret);
+		goto lb_except;
+	}
+	ECN_DBG_PUT( "_ecn_tsk_eoj_set_get() eoj:%06X _ecn_tsk_eoj_get_main() ok sw_ok:%s",
+		fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
+		(a_sw_ok ? "true" : "false") );
+
+	/* vpeBÇÝÝ«ÝÌwbhîñÅAÇÝoµðL^ */
+	_ecn_fbs_poke(a_fbs_res, a_rdprp_wrpos, ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc);
+
+	/* L^µÄ¨¢½vpeBi«Ýjð«ß· */
+	((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = (uint8_t)i;
+
+	/* vÌê */
+	if (a_sw_ok) {
+		/* Ýè¬÷ */
+		((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_res_esv;
+	} else {
+		/* Ýè¸s */
+		((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_sna_esv;
+	}
+	/* M */
+	a_ret = _ecn_tsk_snd_mbx(a_fbs_res, false);
+	if (a_ret == E_OK)
+		goto lb_finally;
+
+lb_except:
+	/* f[^M¸sµ½çÌæðú */
+	if (a_fbs_res.ptr)
+		_ecn_fbs_del(a_fbs_res);
+
+lb_finally:
+	return;
+}
+
+static void _ecn_tsk_eoj_set_get_res(const EOBJINIB *fp_obj, ATR fa_eobjatr,
+	bool_t fa_fromapp, ECN_FBS_ID fa_fbs_id, ECN_FBS_ID *fa_fbs_anno)
+{
+	T_ECN_EDT_HDR	const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
+	T_ECN_EDT_HDR	a_ecn_hdp;
+	ECN_FBS_ID		a_fbs_dmy = { 0 };
+	ER		a_ret;
+	int		i, a_size, a_rdlen;
+	int		a_sw_ok = 1;
+	int		a_count = ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.opc;	/* vpeB */
+
+	memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
+
+	ECN_DBG_PUT( "_ecn_tsk_eoj_set_get_res() eoj:%06X",
+		fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3 );
+
+	/* úæ¾TCY */
+	a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
+
+	/* d¶pi_~[jÌæ¾ */
+	a_ret = _ecn_fbs_cre(a_size, &a_fbs_dmy);
+	if (a_ret != E_OK || !a_fbs_dmy.ptr) /* mÛ¸s */
+		goto lb_finally;
+
+	/* d¶Ýè						*/
+	_ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
+	a_size -= sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY);
+
+	/* payloadæªÌT_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)ðÇÝòÎ· */
+	a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
+	if (a_ret)
+		goto lb_except;
+
+	/* vpeBl«ÝÇÝòÎµÀs */
+	a_ret = _ecn_tsk_eoj_skip_main(fp_obj, fa_fbs_id, a_count);
+	if (a_ret) {
+		syslog(LOG_WARNING, "_ecn_tsk_eoj_set_get_res() eoj:%06X _ecn_tsk_eoj_set_main() fault. result = %d",
+			fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
+			a_ret);
+		goto lb_except;
+	}
+	ECN_DBG_PUT( "_ecn_tsk_eoj_set_get_res() eoj:%06X _ecn_tsk_eoj_set_main() ok sw_ok:%s",
+		fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
+		(a_sw_ok ? "true" : "false") );
+
+	/* ÌðÇÝæé(1byte)						*/
+	/* ¨ ECHONET-Lite_Ver.1.10_02.pdf p.40 [OPCGet]	*/
+	a_rdlen = i = 0;
+	a_ret = _ecn_fbs_get_data(fa_fbs_id, &i, 1, &a_rdlen);
+	if (a_ret < 0 || a_rdlen < 1)
+		goto lb_except;	/* NG */
+	a_count = *(uint8_t *)&i;
+
+	/* vpeBlÇÝoµÌ«ÝÀs */
+	a_ret = _ecn_tsk_eoj_set_main(fp_obj, fa_eobjatr, fa_fromapp, true, fa_fbs_id, a_fbs_dmy,
+		fa_fbs_anno, a_count, &a_sw_ok);
+	if (a_ret) {
+		syslog(LOG_WARNING, "%s _ecn_tsk_eoj_set_get_res() eoj:%06X _ecn_tsk_eoj_get_main() fault. result = %d",
+			ECN_SRC_LOC,
+			fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
+			a_ret);
+		goto lb_except;
+	}
+	ECN_DBG_PUT( "_ecn_tsk_eoj_set_get_res() eoj:%06X _ecn_tsk_eoj_get_main() ok sw_ok:%s",
+		fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
+		(a_sw_ok ? "true" : "false") );
+
+	goto lb_finally;
+
+lb_except:
+	/* f[^M¸sµ½çÌæðú */
+	if (a_fbs_dmy.ptr)
+		_ecn_fbs_del(a_fbs_dmy);
+
+lb_finally:
+	return;
+}
+
+/*
+ * d¶Ò¿ÌèÝd¶ì¬
+ */
+ER _ecn_mk_brk_wai(ECN_FBS_ID *pk_fbs_id, const void *p_dat, size_t fa_size)
+{
+	ER				a_ret;
+	ECN_FBS_ID		a_fbs_id = { 0 };	/* vd¶p	*/
+
+	if (!pk_fbs_id)
+		return E_PAR;
+	*pk_fbs_id = a_fbs_id;
+	if (sizeof(a_fbs_id.ptr->payload) <= fa_size)
+		return E_PAR; /* tf[^ªå«·¬é */
+	if (!p_dat && 0 < fa_size)
+		return E_PAR; /* tf[^TCYª1ÈãÈÌÉf[^|C^ªNULL */
+
+	/* vd¶pÌæ¾ */
+	a_ret = _ecn_fbs_cre((0 < fa_size ? fa_size : 1), &a_fbs_id);
+	if (a_ret != E_OK || !a_fbs_id.ptr) { /* mÛ¸s */
+		syslog(LOG_WARNING, "_ecn_fbs_cre(%d) result = %d:%s", fa_size, a_ret, itron_strerror(a_ret));
+		return a_ret;
+	}
+
+	/* vd¶Ýè */
+	a_fbs_id.ptr->hdr.type = ECN_MSG_USER_BREAK;
+	a_fbs_id.ptr->hdr.sender.id = ENOD_API_ID;
+	a_fbs_id.ptr->hdr.target.id = ENOD_API_ID;
+	a_fbs_id.ptr->hdr.reply.id = ENOD_API_ID;
+
+	if (0 < fa_size && p_dat) {
+		/* tf[^ÇÁ */
+		a_ret = _ecn_fbs_add_data_ex(a_fbs_id, p_dat, fa_size);
+		if (a_ret) {
+			syslog(LOG_WARNING, "_ecn_fbs_add_data_ex(*, dat, %lu) result = %d:%s",
+				fa_size,
+				a_ret, itron_strerror(a_ret));
+			goto lb_except;
+		}
+	}
+
+	*pk_fbs_id = a_fbs_id;
+
+	/* ³íI¹ */
+	return a_ret;
+
+lb_except:
+	/* f[^ì¬¸sµ½çÌæðú */
+	if (a_fbs_id.ptr)
+		_ecn_fbs_del(a_fbs_id);
+
+	return a_ret;
+}
+
+/* d¶pfbsÝè(sender/targetÌÝè) */
+ER _ecn_tsk_cre_req_fbs(ID sender, uint8_t cmd, ECN_FBS_ID *pk_req)
+{
+	ER ret;
+	ECN_FBS_ID req;
+
+	ret = _ecn_fbs_cre(1, &req);
+	if (ret != E_OK) {
+		ECN_DBG_PUT( "_ecn_tsk_cre_req_fbs() : _ecn_fbs_cre() result = %d:%s", ret, itron_strerror(ret) );
+		return ret;
+	}
+
+	ret = _ecn_fbs_add_data(req, &cmd, sizeof(cmd));
+	if (ret != E_OK) {
+		_ecn_fbs_del(req);
+		ECN_DBG_PUT( "_ecn_tsk_cre_req_fbs() : _ecn_fbs_add_data() result = %d:%s", ret, itron_strerror(ret) );
+		return ret;
+	}
+
+	req.ptr->hdr.type = ECN_MSG_INTERNAL;
+	req.ptr->hdr.sender.mbxid = sender;
+	req.ptr->hdr.target.mbxid = ecn_svc_mailboxid;
+	req.ptr->hdr.reply.mbxid = sender;
+
+	*pk_req = req;
+
+	return E_OK;
+}
+
+/* d¶pfbsÝè(sender/targetÌÝè) */
+ER _ecn_tsk_cre_res_fbs(ECN_FBS_ID req, uint8_t cmd, ECN_FBS_ID *pk_res)
+{
+	ER ret;
+	ECN_FBS_ID res;
+
+	ret = _ecn_fbs_cre(1, &res);
+	if (ret != E_OK) {
+		ECN_DBG_PUT( "_ecn_tsk_cre_res_fbs() : _ecn_fbs_cre() result = %d:%s", ret, itron_strerror(ret) );
+		return ret;
+	}
+
+	ret = _ecn_fbs_add_data(res, &cmd, sizeof(cmd));
+	if (ret != E_OK) {
+		_ecn_fbs_del(res);
+		ECN_DBG_PUT( "_ecn_tsk_cre_res_fbs() : _ecn_fbs_add_data() result = %d:%s", ret, itron_strerror(ret) );
+		return ret;
+	}
+
+	res.ptr->hdr.type = ECN_MSG_INTERNAL;
+	res.ptr->hdr.sender.mbxid = ecn_svc_mailboxid;
+	res.ptr->hdr.target.mbxid = req.ptr->hdr.reply.mbxid;
+	res.ptr->hdr.reply.mbxid = ecn_svc_mailboxid;
+
+	*pk_res = res;
+
+	return E_OK;
+}
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_task.h
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_task.h	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_task.h	(revision 164)
@@ -0,0 +1,141 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ECHONET Lite ^XN
+ */
+
+#ifndef TOPPERS_ECHONET_TASK_H
+#define TOPPERS_ECHONET_TASK_H
+
+/*#include ".h"*/
+
+#include "echonet_rename.h"
+#include "echonet.h"
+#include "echonet_fbs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  ECHONET Lite ^XNÖAÌèÌftHglÌè`
+ */ 
+#ifndef ECHONET_TASK_PRIORITY
+#define ECHONET_TASK_PRIORITY	3		/* úDæx */
+#endif /* ECHONET_TASK_PRIORITY */
+
+#ifndef ECHONET_TASK_STACK_SIZE
+#define ECHONET_TASK_STACK_SIZE	1024	/* X^bNÌæÌTCY */
+#endif /* ECHONET_TASK_STACK_SIZE */
+
+extern const EOBJINIB _echonet_eobjinib_table[];
+extern EOBJCB _echonet_eobjcb_table[];
+extern ENODADRB _echonet_enodadrb_table[];
+
+/*
+ *  ECHONET Lite ^XNÌ{Ì
+ */
+void echonet_task(intptr_t exinf);
+
+/* ECHONET Lite CX^XXgÌ1AiEX½èÅåm[h */
+#define ECN_IST_LST_EOJ_MAX_CT (84)
+
+/* ECHONET LiteIuWFNgR[h x1,x2,x3(T_ECN_EOJ)ð24bit®ÉÏ· */
+#define _ECN_EOJ2VALUE(s) (((s).eojx1 << 16) | ((s).eojx2 << 8) | (s).eojx3)
+
+enum ecn_epc_code
+{
+	ECN_EPC_INL_BCS		=	0xD5	/* CX^XXgÊmvpeB */
+};
+
+typedef enum
+{
+	ECN_MSG_UNDEF		=	0,
+	ECN_MSG_INTERNAL	=	1,
+	ECN_MSG_ECHONET		=	2,
+	ECN_MSG_USER_BREAK	=	3
+} ECN_MSG_TYPE;
+
+typedef enum
+{
+	ECN_INM_NOTIFY_INSTANCELIST = 1,
+	ECN_INM_GET_DEVICE_LIST_REQ,
+	ECN_INM_GET_DEVICE_LIST_RES,
+	ECN_INM_GET_DEVICE_INFO_REQ,
+	ECN_INM_GET_DEVICE_INFO_RES,
+	ECN_UDP_MSG_GET_IPADDR_REQ,
+	ECN_UDP_MSG_GET_IPADDR_RES,
+	ECN_UDP_MSG_GET_IPADDR_ERROR
+} ECN_INT_MSG_COMMAND;
+
+typedef struct
+{
+	uint8_t	command;
+	uint8_t	data[1];
+} T_ECN_INTERNAL_MSG;
+
+/*
+ * vd¶ì¬
+ */
+ER _ecn_tsk_mk_esv(ECN_FBS_ID *fp_fbs_id, ID fa_seoj, ID fa_deoj,
+	uint8_t fa_epc, uint8_t fa_pdc, const void *p_edt, ECN_SRV_CODE fa_esv);
+
+ER _ecn_tsk_snd_mbx(ECN_FBS_ID fa_rsp_fbs, bool_t from_app);
+
+/*
+ * d¶Ò¿ÌèÝd¶ì¬
+ */
+ER _ecn_mk_brk_wai(ECN_FBS_ID *pk_fbs_id, const void *p_dat, size_t fa_size);
+
+const EOBJCB *_ecn_eno_fnd(ECN_ENOD_ID enodid);
+
+const EOBJINIB *_ecn_eoj_fnd(const EOBJCB *fp_nod, const T_ECN_EOJ *fp_eoj);
+
+ER _ecn_tsk_cre_req_fbs(ID sender, uint8_t cmd, ECN_FBS_ID *pk_req);
+
+ER _ecn_tsk_cre_res_fbs(ECN_FBS_ID req, uint8_t cmd, ECN_FBS_ID *pk_res);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_ECHONET_TASK_H */
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_udp_task.c
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_udp_task.c	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_udp_task.c	(revision 164)
@@ -0,0 +1,782 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ *
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ *
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ *
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ *
+ *  @(#) $Id$
+ */
+
+/*
+ *		ECHONET Lite UDPÊM^XN
+ */
+#ifdef SUPPORT_INET4
+
+#include <kernel.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "echonet.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4005)
+#endif
+#include <lwip/udp.h>
+#include <lwip/igmp.h>
+#ifdef _MSC_VER
+#pragma warning(default : 4005)
+#endif
+
+#include "echonet_task.h"
+#include "echonet_lcl_task.h"
+#include "echonet_dbg.h"
+
+#ifndef ECHONET_UDP_TASK_GET_TIMER
+#define ECHONET_UDP_TASK_GET_TIMER	TMO_FEVR
+#endif /* ECHONET_UDP_TASK_GET_TIMER */
+
+#ifndef ECHONET_UDP_TASK_PROGRESS
+#define ECHONET_UDP_TASK_PROGRESS(timer)
+#endif /* ECHONET_UDP_TASK_PROGRESS */
+
+#ifndef ECHONET_UDP_TASK_TIMEOUT
+#define ECHONET_UDP_TASK_TIMEOUT
+#endif /* ECHONET_UDP_TASK_TIMEOUT */
+
+#ifndef ECHONET_UDP_SEND_TO_MBX
+#define ECHONET_UDP_SEND_TO_MBX
+#endif /* ECHONET_UDP_SEND_TO_MBX */
+
+#ifndef ECHONET_NODE_MATCH
+#define ECHONET_NODE_MATCH(enodcb, edata, ipaddr, portno) is_match(enodcb, edata, ipaddr, portno)
+#endif /* ECHONET_NODE_MATCH */
+
+static ip_addr_t localhost;
+static ip_addr_t multicast;
+static ip_addr_t zeroaddr;
+struct udp_pcb *UDP_CEPID;
+
+typedef struct ipv4ep_t {
+	ip_addr_t ipaddr;
+	uint16_t portno;
+} T_IPV4EP;
+
+static ECN_ENOD_ID udp_get_id(T_EDATA *edata, const ip_addr_t *ipaddr, uint16_t portno);
+static int udp_get_ip(T_IPV4EP *fp_ipep, ECN_ENOD_ID fa_enodid);
+void _ecn_int_msg(ECN_FBS_ID fbs_id, ECN_FBS_SSIZE_T a_snd_len);
+void _ecn_esv_msg(ECN_FBS_ID fbs_id);
+static void callback_nblk_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port);
+
+/*
+ * óMµ½UDPf[^ðMAILBOXÉé
+ */
+ER _ecn_udp2mbx(ECN_FBS_ID fbs_id, const T_IPV4EP *dst);
+ER _ecn_udp2mbx(ECN_FBS_ID fbs_id, const T_IPV4EP *dst)
+{
+	ER			a_ret = E_OK;
+	ECN_ENOD_ID	a_enod_id;
+	const T_ECN_EDT_HDR	*t_esv;
+
+	t_esv = (const T_ECN_EDT_HDR	*)fbs_id.ptr->payload;
+	if (t_esv->ecn_hdr.ehd1 != ECN_EDH1_ECHONET_LITE	/* ECHONET LiteKi	*/
+		|| t_esv->ecn_hdr.ehd2 != ECN_EDH2_FORMAT_1			/* d¶`®1		*/) {
+		ECN_DBG_PUT("[UDP ECHO SRV] illegal type (0x%02X,0x%02X)", t_esv->ecn_hdr.ehd1, t_esv->ecn_hdr.ehd2);
+		return E_PAR;
+	}
+
+#ifdef ECN_DBG_PUT_ENA
+	_ecn_dbg_bindmp(fbs_id.ptr, fbs_id.ptr->hdr.length);
+#endif
+
+	fbs_id.ptr->hdr.type = ECN_MSG_ECHONET;
+	fbs_id.ptr->hdr.target.id = ENOD_LOCAL_ID;
+	fbs_id.ptr->hdr.sender.id = ENOD_NOT_MATCH_ID;
+
+	/* IPAhX©ç[gECHONETm[hÖÏ· */
+	a_enod_id = udp_get_id((T_EDATA *)fbs_id.ptr, &dst->ipaddr, dst->portno);
+	if (a_enod_id < 0 || tnum_enodadr <= a_enod_id) {
+		ECN_DBG_PUT("[UDP ECHO SRV] udp src(%s) echonet-node not found.",
+			ipaddr_ntoa(&dst->ipaddr));
+	}
+	else {
+	 /* M³ECHONETm[hðL^ */
+		fbs_id.ptr->hdr.sender.id = a_enod_id;
+	}
+	fbs_id.ptr->hdr.reply.id = fbs_id.ptr->hdr.sender.id;
+
+	/* echonet_taskÉé */
+	a_ret = snd_mbx(ecn_svc_mailboxid, (T_MSG *)fbs_id.ptr);
+	if (a_ret != E_OK) {
+		ECN_DBG_PUT("[UDP ECHO SRV] snd_mbx(ecn_svc_mailboxid) result = %d:%s", a_ret, itron_strerror(a_ret));
+		goto lb_except;
+	}
+	return a_ret;
+lb_except:
+	_ecn_fbs_del(fbs_id);
+	return a_ret;
+}
+
+/*
+ *  ECHONET UDPÊM^XN
+ */
+void echonet_udp_task(intptr_t exinf)
+{
+	ip_addr_t	a_src;
+	ER			a_ret, a_ret2;
+	ID			tskid;
+	ECN_FBS_SSIZE_T	a_snd_len;
+	union {
+		T_MSG		*p_msg;
+		ECN_FBS_ID	fbs_id;
+	} a_mdt;
+	SYSTIM a_prev, a_now;
+	TMO a_timer;
+	err_t err;
+
+	IP4_ADDR(&localhost, 127, 0, 0, 1);
+	IP4_ADDR(&multicast, 224, 0, 23, 0);
+	IP4_ADDR(&zeroaddr, 0, 0, 0, 0);
+
+	get_tid(&tskid);
+	memcpy(&a_src, &netif_default->ip_addr, sizeof(ip_addr_t));
+	ECN_DBG_PUT("[UDP TSK:%d,%d] started, IP Address: %s",
+		tskid, exinf,
+		ipaddr_ntoa(&a_src));
+	memcpy(enodadrb_table[ENOD_LOCAL_ID].ipaddr, &a_src, sizeof(ip_addr_t));
+
+	UDP_CEPID = udp_new();
+	if (UDP_CEPID == NULL) {
+		ECN_DBG_PUT("udp_new()");
+		return;
+	}
+
+	err = udp_bind(UDP_CEPID, &a_src, 3610);
+	if (err != ERR_OK) {
+		ECN_DBG_PUT("udp_bind()");
+		return;
+	}
+
+	udp_recv(UDP_CEPID, callback_nblk_udp, NULL);
+
+	err = igmp_joingroup(&a_src, &multicast);
+	if (err != ERR_OK) {
+		ECN_DBG_PUT("igmp_joingroup()");
+		return;
+	}
+
+	a_ret = act_tsk(ecn_svc_taskid);
+	if (a_ret != E_OK) {
+		ECN_DBG_PUT("act_tsk(%d) result = %d:%s", ecn_svc_taskid, a_ret, itron_strerror(a_ret));
+		return;
+	}
+
+	a_ret = get_tim(&a_now);
+	if (a_ret != E_OK) {
+		ECN_DBG_PUT("get_tim() result = %d:%s", a_ret, itron_strerror(a_ret));
+		return;
+	}
+
+	/* bZ[W[v */
+	for (;;) {
+		a_prev = a_now;
+
+		a_timer = ECHONET_UDP_TASK_GET_TIMER;
+
+		a_ret = trcv_mbx(ecn_udp_mailboxid, &a_mdt.p_msg, a_timer);
+		if ((a_ret != E_OK) && (a_ret != E_TMOUT)) {
+			ECN_DBG_PUT("trcv_mbx() result = %d:%s", a_ret, itron_strerror(a_ret));
+			break;
+		}
+
+		a_ret2 = get_tim(&a_now);
+		if (a_ret2 != E_OK) {
+			ECN_DBG_PUT("get_tim() result = %d:%s", a_ret2, itron_strerror(a_ret2));
+			break;
+		}
+
+		a_timer = a_now - a_prev;
+		ECHONET_UDP_TASK_PROGRESS(a_timer);
+
+		if (a_ret == E_OK) {
+			/* Mf[^·ðæ¾ */
+			a_snd_len = _ecn_fbs_get_datalen(a_mdt.fbs_id);
+
+			ECN_DBG_PUT("[UDP TSK] trcv_mbx() mbx recv (%d byte)", _ecn_fbs_get_datalen(a_mdt.fbs_id));
+
+			if (0 < a_snd_len) {
+				switch (a_mdt.fbs_id.ptr->hdr.type) {
+				case ECN_MSG_INTERNAL:
+					_ecn_int_msg(a_mdt.fbs_id, a_snd_len);
+					break;
+				case ECN_MSG_ECHONET:
+					_ecn_esv_msg(a_mdt.fbs_id);
+					break;
+				}
+			}
+
+			_ecn_fbs_del(a_mdt.fbs_id);
+		}
+
+		ECHONET_UDP_TASK_TIMEOUT;
+	}
+}
+
+/* d¶pfbsÝè(sender/targetÌÝè) */
+static ER _ecn_udp_cre_req_fbs(ID sender, uint8_t cmd, ECN_FBS_ID *pk_req)
+{
+	ER ret;
+	ECN_FBS_ID req;
+
+	ret = _ecn_fbs_cre(1, &req);
+	if (ret != E_OK) {
+		ECN_DBG_PUT("_ecn_udp_cre_req_fbs() : _ecn_fbs_cre() result = %d:%s", ret, itron_strerror(ret));
+		return ret;
+	}
+
+	ret = _ecn_fbs_add_data(req, &cmd, sizeof(cmd));
+	if (ret != E_OK) {
+		_ecn_fbs_del(req);
+		ECN_DBG_PUT("_ecn_udp_cre_req_fbs() : _ecn_fbs_add_data() result = %d:%s", ret, itron_strerror(ret));
+		return ret;
+	}
+
+	req.ptr->hdr.type = ECN_MSG_INTERNAL;
+	req.ptr->hdr.sender.mbxid = sender;
+	req.ptr->hdr.target.mbxid = ecn_udp_mailboxid;
+	req.ptr->hdr.reply.mbxid = sender;
+
+	*pk_req = req;
+
+	return E_OK;
+}
+
+/* d¶pfbsÝè(sender/targetÌÝè) */
+static ER _ecn_udp_cre_res_fbs(ECN_FBS_ID req, uint8_t cmd, ECN_FBS_ID *pk_res)
+{
+	ER ret;
+	ECN_FBS_ID res;
+
+	ret = _ecn_fbs_cre(1, &res);
+	if (ret != E_OK) {
+		ECN_DBG_PUT("_ecn_udp_cre_res_fbs() : _ecn_fbs_cre() result = %d:%s", ret, itron_strerror(ret));
+		return ret;
+	}
+
+	ret = _ecn_fbs_add_data(res, &cmd, sizeof(cmd));
+	if (ret != E_OK) {
+		_ecn_fbs_del(res);
+		ECN_DBG_PUT("_ecn_udp_cre_res_fbs() : _ecn_fbs_add_data() result = %d:%s", ret, itron_strerror(ret));
+		return ret;
+	}
+
+	res.ptr->hdr.type = ECN_MSG_INTERNAL;
+	res.ptr->hdr.sender.mbxid = ecn_udp_mailboxid;
+	res.ptr->hdr.target.mbxid = req.ptr->hdr.reply.mbxid;
+	res.ptr->hdr.reply.mbxid = ecn_udp_mailboxid;
+
+	*pk_res = res;
+
+	return E_OK;
+}
+
+/*
+ *  àbZ[WóM
+ */
+void _ecn_int_msg(ECN_FBS_ID fbs_id, ECN_FBS_SSIZE_T a_snd_len)
+{
+	ER result = E_OK, a_ret;
+	ecn_udp_msg_get_ipaddr_req_t msg;
+	ecn_udp_msg_get_ipaddr_error_t err;
+	ECN_FBS_SSIZE_T len;
+	ECN_FBS_ID buf;
+	uint8_t cmd;
+	unsigned int requestid = 0;
+
+	a_ret = _ecn_fbs_get_data(fbs_id, &cmd, 1, &len);
+	if (a_ret != E_OK) {
+		ECN_DBG_PUT("[UDP TSK] _ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret));
+		return;
+	}
+
+	switch (cmd) {
+	// IPAhXðÔM
+	case ECN_UDP_MSG_GET_IPADDR_REQ:
+		if (a_snd_len < sizeof(msg)) {
+			result = E_PAR;
+			break;
+		}
+
+		a_snd_len = 0;
+		a_ret = _ecn_fbs_get_data(fbs_id, &msg, sizeof(msg), &a_snd_len);
+		if (a_ret != E_OK) {
+			ECN_DBG_PUT("[UDP TSK] _ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret));
+		}
+		requestid = msg.requestid;
+
+		if ((msg.enodid < 0) && (msg.enodid >= tnum_enodadr)) {
+			result = E_PAR;
+			break;
+		}
+
+		a_ret = _ecn_udp_cre_res_fbs(fbs_id, ECN_UDP_MSG_GET_IPADDR_RES, &buf);
+		if (a_ret != E_OK) {
+			return;
+		}
+
+		a_ret = _ecn_fbs_add_data_ex(buf, &msg.requestid, offsetof(ecn_udp_msg_get_ipaddr_res_t, enodadrb));
+		if (a_ret != E_OK) {
+			_ecn_fbs_del(buf);
+			ECN_DBG_PUT("_ecn_int_msg() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
+			return;
+		}
+
+		a_ret = _ecn_fbs_add_data_ex(buf, &enodadrb_table[msg.enodid], sizeof(enodadrb_table[msg.enodid]));
+		if (a_ret != E_OK) {
+			_ecn_fbs_del(buf);
+			ECN_DBG_PUT("_ecn_int_msg() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
+			return;
+		}
+
+		a_ret = psnd_dtq(buf.ptr->hdr.target.mbxid, (intptr_t)buf.ptr);
+		if (a_ret != E_OK) {
+			_ecn_fbs_del(buf);
+			ECN_DBG_PUT("_ecn_int_msg() : psnd_dtq() result = %d:%s", a_ret, itron_strerror(a_ret));
+			return;
+		}
+		return;
+	default:
+		a_ret = _ecn_fbs_get_data(fbs_id, &requestid, sizeof(requestid), &len);
+		if (a_ret != E_OK) {
+			ECN_DBG_PUT("[UDP TSK] _ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret));
+			return;
+		}
+		break;
+	}
+
+	if (requestid == 0)
+		return;
+
+	a_ret = _ecn_udp_cre_res_fbs(fbs_id, ECN_UDP_MSG_GET_IPADDR_ERROR, &buf);
+	if (a_ret != E_OK) {
+		return;
+	}
+
+	err.requestid = requestid;
+	err.error = result;
+	a_ret = _ecn_fbs_add_data_ex(buf, &err, sizeof(err));
+	if (a_ret != E_OK) {
+		_ecn_fbs_del(buf);
+		ECN_DBG_PUT("_ecn_int_msg() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
+		return;
+	}
+
+	a_ret = psnd_dtq(buf.ptr->hdr.target.mbxid, (intptr_t)buf.ptr);
+	if (a_ret != E_OK) {
+		_ecn_fbs_del(buf);
+		ECN_DBG_PUT("_ecn_int_msg() : psnd_dtq() result = %d:%s", a_ret, itron_strerror(a_ret));
+		return;
+	}
+}
+
+/*
+ *  ECHONET d¶óM
+ */
+void _ecn_esv_msg(ECN_FBS_ID fbs_id)
+{
+	struct pbuf *p, *q;
+	T_IPV4EP a_dst;
+	ER a_ret;
+	ECN_FBS_SSIZE_T a_snd_len = fbs_id.ptr->hdr.length;
+
+	IP4_ADDR(&a_dst.ipaddr, 0, 0, 0, 0);
+	a_dst.portno = 0;
+	/* MæIPAhX */
+	a_ret = udp_get_ip(&a_dst, fbs_id.ptr->hdr.target.id);
+	if (!a_ret) {
+		ECN_DBG_PUT("[UDP TSK] echonet-node 0x%02X-0x%02X-0x%02X ¨ udp dest(%s)",
+			((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx1,
+			((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx2,
+			((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx3,
+			ipaddr_ntoa(&a_dst.ipaddr));
+
+		if (ip_addr_cmp(&a_dst.ipaddr, &localhost)) {
+			/* Mæª127.0.0.1 ¨ mbxÉ] */
+			ECN_DBG_PUT("redirect ecn_udp_mailboxid ¨ ecn_svc_mailboxid (esv:0x%02X)",
+				((T_EDATA *)fbs_id.ptr)->hdr.edata.esv);
+
+			a_ret = _ecn_udp2mbx(fbs_id, &a_dst);
+			if (a_ret != E_OK) {
+				syslog(LOG_WARNING, "_ecn_esv_msg() : _ecn_udp2mbx() result = %d:%s", a_ret, itron_strerror(a_ret));
+			}
+		}
+		else {
+			ECN_DBG_PUT("[UDP TSK] udp_snd_dat() to:%s %ubyte(s)",
+				ipaddr_ntoa(&a_dst.ipaddr), a_snd_len);
+#ifdef ECN_DBG_PUT_ENA
+			_ecn_dbg_bindmp(fbs_id.ptr, a_snd_len);
+#endif
+			p = pbuf_alloc(PBUF_TRANSPORT, _ecn_fbs_get_datalen(fbs_id), PBUF_POOL);
+			if (p == NULL) {
+				ECN_DBG_PUT("[UDP TSK] pbuf_alloc()");
+				return;
+			}
+
+			/* fbs©çoÍÌæÉf[^ðo */
+			a_snd_len = 0;
+			for (q = p; q != NULL; q = q->next) {
+				ECN_FBS_SSIZE_T a_len;
+				a_ret = _ecn_fbs_get_data(fbs_id, q->payload, q->len, &a_len);
+				if (a_ret != E_OK) {
+					ECN_DBG_PUT("[UDP TSK] _ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret));
+					pbuf_free(p);
+					return;
+				}
+				a_snd_len += a_len;
+			}
+
+			/* UDPM */
+			a_ret = udp_sendto(UDP_CEPID, p, &a_dst.ipaddr, 3610);
+			if (a_ret < 0) {
+				ECN_DBG_PUT("[UDP TSK] send, error: %s", itron_strerror(a_ret));
+			}
+			pbuf_free(p);
+		}
+
+		/* f[^ª··¬Ä1pPbgÉûÜçÈ©Á½ê */
+		if (_ecn_fbs_exist_data(fbs_id)) {
+			ECN_DBG_PUT("[UDP TSK] send, data so long: %dbyte(s)", _ecn_fbs_get_datalen(fbs_id));
+		}
+	}
+	else {
+		ECN_DBG_PUT("[UDP TSK] echonet-node 0x%02X-0x%02X-0x%02X not found.",
+			((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx1,
+			((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx2,
+			((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx3);
+	}
+}
+
+/*
+ *  mubLOR[ÌR[obNÖ
+ */
+static void
+callback_nblk_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
+{
+	ECN_FBS_ID	a_fbs_id = {0};
+	ER			a_ret = E_OK;
+	ECN_ENOD_ID	a_enod_id;
+	const T_ECN_EDT_HDR *t_esv;
+	struct pbuf *q;
+
+	a_ret = _ecn_fbs_cre(p->tot_len, &a_fbs_id);
+	if (a_ret != E_OK) {
+		ECN_DBG_PUT("[UDP ECHO SRV] _ecn_fbs_cre() result = %d:%s", a_ret, itron_strerror(a_ret));
+		pbuf_free(p);
+		return;
+	}
+
+	for (q = p; q != NULL; q = q->next) {
+		a_ret = _ecn_fbs_add_data_ex(a_fbs_id, q->payload, q->len);
+		if (a_ret) {
+			ECN_DBG_PUT("[UDP ECHO SRV] _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
+			pbuf_free(p);
+			goto lb_except;
+		}
+	}
+
+	pbuf_free(p);
+
+	t_esv = (const T_ECN_EDT_HDR *)a_fbs_id.ptr->payload;
+	if (t_esv->ecn_hdr.ehd1 != ECN_EDH1_ECHONET_LITE	/* ECHONET LiteKi	*/
+		|| t_esv->ecn_hdr.ehd2 != ECN_EDH2_FORMAT_1			/* d¶`®1		*/) {
+		ECN_DBG_PUT("[UDP ECHO SRV] illegal type (0x%02X,0x%02X)", t_esv->ecn_hdr.ehd1, t_esv->ecn_hdr.ehd2);
+		goto lb_except;
+	}
+
+#ifdef ECN_DBG_PUT_ENA
+	_ecn_dbg_bindmp(a_fbs_id.ptr, a_fbs_id.ptr->hdr.length);
+#endif
+
+	a_fbs_id.ptr->hdr.type = ECN_MSG_ECHONET;
+	a_fbs_id.ptr->hdr.target.id = ENOD_LOCAL_ID;
+	a_fbs_id.ptr->hdr.sender.id = ENOD_NOT_MATCH_ID;
+
+	/* IPAhX©ç[gECHONETm[hÖÏ· */
+	a_enod_id = udp_get_id((T_EDATA *)a_fbs_id.ptr, addr, port);
+	if (a_enod_id < 0 || tnum_enodadr <= a_enod_id) {
+		ECN_DBG_PUT("[UDP ECHO SRV] udp src(%s) echonet-node not found.",
+			ipaddr_ntoa(addr));
+	}
+	else {
+		/* M³ECHONETm[hðL^ */
+		a_fbs_id.ptr->hdr.sender.id = a_enod_id;
+	}
+	a_fbs_id.ptr->hdr.reply.id = a_fbs_id.ptr->hdr.sender.id;
+
+	/* echonet_taskÉé */
+	a_ret = snd_mbx(ecn_svc_mailboxid, (T_MSG *)a_fbs_id.ptr);
+	if (a_ret != E_OK) {
+		ECN_DBG_PUT("[UDP ECHO SRV] snd_mbx(ecn_svc_mailboxid) result = %d:%s", a_ret, itron_strerror(a_ret));
+		goto lb_except;
+	}
+	return;
+lb_except:
+	_ecn_fbs_del(a_fbs_id);
+	return;
+}
+
+/*
+ *  [gECHONETm[hÌKmF
+ */
+bool_t is_match(const EOBJCB *enodcb, T_EDATA *edata, const void *_ipaddr, uint16_t portno)
+{
+	/*ip_addr_t *ipaddr = (ip_addr_t *)_ipaddr;*/
+	ER			ret;
+	T_ENUM_EPC	enm;
+	uint8_t		epc;
+	uint8_t		pdc;
+	uint8_t		p_edt[256];
+	int			i, j, k;
+	int			count;
+	const EOBJINIB	*p_eobj;
+	bool_t		match;
+
+	if (!edata)
+		return false;
+
+	/* m[hX^[gCX^XXgÊmÈOÍO */
+	if (edata->hdr.edata.esv != ESV_INF
+		|| edata->hdr.edata.deoj.eojx1 != EOJ_X1_PROFILE
+		|| edata->hdr.edata.deoj.eojx2 != EOJ_X2_NODE_PROFILE
+		|| edata->hdr.edata.deoj.eojx3 != 0x01
+		|| edata->hdr.edata.seoj.eojx1 != EOJ_X1_PROFILE
+		|| edata->hdr.edata.seoj.eojx2 != EOJ_X2_NODE_PROFILE
+		|| (edata->hdr.edata.seoj.eojx3 != 0x01
+			&& edata->hdr.edata.seoj.eojx3 != 0x02)) {
+		return false;
+	}
+
+	ret = ecn_itr_ini(&enm, edata);
+	if (ret) {
+		syslog(LOG_WARNING, "is_match(): ecn_itr_ini() result = %d:%s", ret, itron_strerror(ret));
+		return false;
+	}
+	while ((ret = ecn_itr_nxt(&enm, &epc, &pdc, p_edt)) == E_OK) {
+		if (enm.is_eof) {
+			break;
+		}
+		ECN_DBG_PUT("is_match(): ecn_itr_nxt() result: epc=0x%02X, pdc=%d", epc, pdc);
+		/* CX^XXgÊmÜ½Í©m[hCX^XXgrÈOÍO */
+		if ((epc != 0xD5) && (epc != 0xD6)) {
+			continue;
+		}
+
+		/* QoCgÚÈ~Éeojªñ³êÄ¢é */
+		count = (pdc - 1) / sizeof(T_ECN_EOJ);
+
+		/* m[hàÌ@íIuWFNgðõ */
+		for (k = 0; k < enodcb->eobjcnt; k++) {
+			p_eobj = enodcb->eobjs[k];
+
+			/* CX^XXgðmF */
+			match = false;
+			for (i = 0, j = 1; i < count; i++, j += sizeof(T_ECN_EOJ)) {
+				if (p_eobj->eojx1 != p_edt[j])
+					continue;
+				if (p_eobj->eojx2 != p_edt[j + 1])
+					continue;
+				if (p_eobj->eojx3 != p_edt[j + 2])
+					continue;
+
+				match = true;
+				break;
+			}
+
+			if (!match)
+				return false;
+		}
+
+		/* ·×ÄµÁÄ¢½çKiCX^XXgÌûª½­Äà¢¢±ÆÆ·éj */
+		return true;
+	}
+
+	return false;
+}
+
+/*
+ *  IPAhX©ç[gECHONETm[hÖÏ·
+ */
+ECN_ENOD_ID udp_get_id(T_EDATA *edata, const ip_addr_t *ipaddr, uint16_t portno)
+{
+	T_ENOD_ADDR	*ea;
+	int			i;
+
+	if (ip_addr_cmp(ipaddr, &localhost))
+		return ENOD_LOCAL_ID;
+	if (ip_addr_cmp(ipaddr, &multicast))
+		return ENOD_MULTICAST_ID;
+
+	/* IPAhXÌ¯¶àÌðõ */
+	for (i = 0, ea = enodadrb_table; i < tnum_enodadr; i++, ea++) {
+		if (!ea->inuse)
+			continue;
+		if (!ip_addr_cmp((ip_addr_t *)ea->ipaddr, ipaddr))
+			continue;
+
+		ECN_CAP_PUT("udp_get_id(): ip-found remote(%d) = %s",
+			i - ENOD_REMOTE_ID, ipaddr_ntoa(ipaddr));
+		return (ECN_ENOD_ID)i;
+	}
+
+	/* Î·é[gm[hðõ */
+	for (i = ENOD_REMOTE_ID, ea = &enodadrb_table[ENOD_REMOTE_ID]; i < tnum_enodadr; i++, ea++) {
+		if (!ea->inuse)
+			continue;
+		if ((i - ENOD_REMOTE_ID + 1) >= tnum_enodid)
+			break;
+		if (ip_addr_cmp((ip_addr_t *)&ea->ipaddr, &zeroaddr))
+			continue;
+		if (!ECHONET_NODE_MATCH(&eobjcb_table[i - ENOD_REMOTE_ID + 1], edata, ipaddr, portno))
+			continue;
+
+		/* Î·é[gm[hª êÎIPAhXðÝè */
+		*((ip_addr_t *)ea->ipaddr) = *ipaddr;
+
+		ECN_CAP_PUT("udp_get_id(): enod-found remote(%d) = %s",
+			i - ENOD_REMOTE_ID, ipaddr_ntoa(ipaddr));
+		return (ECN_ENOD_ID)i;
+	}
+
+	/* ó«ÌæðTµÄ©®o^ */
+	for (i = ENOD_REMOTE_ID, ea = &enodadrb_table[ENOD_REMOTE_ID]; i < tnum_enodadr; i++, ea++) {
+		if (ea->inuse)
+			continue;
+
+		ea->inuse = true;
+		*((ip_addr_t *)ea->ipaddr) = *ipaddr;
+
+		ECN_CAP_PUT("udp_get_id(): empty-found remote(%d) = %s",
+			i - ENOD_REMOTE_ID, ipaddr_ntoa(ipaddr));
+		return (ECN_ENOD_ID)i;
+	}
+
+	return ENOD_NOT_MATCH_ID;
+}
+
+/*
+ *  [gECHONETm[h©çIPAhXÖÏ·
+ */
+int udp_get_ip(T_IPV4EP *fp_ipep, ECN_ENOD_ID fa_enodid)
+{
+	T_ENOD_ADDR *ea;
+
+	if (!fp_ipep)
+		return -1;	/* NG */
+
+	fp_ipep->portno = 3610;
+
+	if (fa_enodid == ENOD_MULTICAST_ID) {
+		/* targetªENOD_MULTICAST_IDÌêA}`LXgðs¤ */
+		ip_addr_copy(fp_ipep->ipaddr, multicast);
+		return 0;	/* ok */
+	}
+
+	if (fa_enodid < ENOD_REMOTE_ID) {
+		/* targetª¢è`ELOCALEAPIÌêA[Jzðs¤ */
+		ip_addr_copy(fp_ipep->ipaddr, localhost);
+		return 0;	/* ok */
+	}
+
+	if (fa_enodid >= tnum_enodadr)
+		return -1;	/* NG */
+
+	ea = &enodadrb_table[fa_enodid];
+	if (!ea->inuse)
+		return -1;	/* NG */
+
+	if (ip_addr_cmp((ip_addr_t *)&ea->ipaddr, &zeroaddr))
+		return -1;	/* NG */
+
+	fp_ipep->ipaddr = *((ip_addr_t *)ea->ipaddr);
+	return 0;	/* ok */
+}
+
+ER ecn_udp_get_ipaddr(ID sender, int requestid, ECN_ENOD_ID enodid, ECN_FBS_ID *pk_req)
+{
+	ER a_ret;
+	ECN_FBS_ID req;
+
+	a_ret = _ecn_udp_cre_req_fbs(sender, ECN_UDP_MSG_GET_IPADDR_REQ, &req);
+	if (a_ret != E_OK) {
+		return a_ret;
+	}
+
+	a_ret = _ecn_fbs_add_data_ex(req, &requestid, sizeof(((ecn_udp_msg_get_ipaddr_res_t *)0)->requestid));
+	if (a_ret != E_OK) {
+		_ecn_fbs_del(req);
+		ECN_DBG_PUT("ecn_udp_get_ipaddr() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
+		return a_ret;
+	}
+
+	a_ret = _ecn_fbs_add_data_ex(req, &enodid, sizeof(((ecn_udp_msg_get_ipaddr_res_t *)0)->enodid));
+	if (a_ret != E_OK) {
+		_ecn_fbs_del(req);
+		ECN_DBG_PUT("ecn_udp_get_ipaddr() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
+		return a_ret;
+	}
+
+	a_ret = _ecn_fbs_add_data_ex(req, &enodadrb_table[enodid], sizeof(((ecn_udp_msg_get_ipaddr_res_t *)0)->enodadrb));
+	if (a_ret != E_OK) {
+		_ecn_fbs_del(req);
+		ECN_DBG_PUT("ecn_udp_get_ipaddr() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
+		return a_ret;
+	}
+
+	*pk_req = req;
+
+	return E_OK;
+}
+
+char *ipaddr2str(char *buf, int bubsz, uint8_t *ipaddr)
+{
+	return ipaddr_ntoa_r((ip_addr_t *)ipaddr, buf, bubsz);
+}
+
+#endif
Index: UsbWattMeter/trunk/ecnl_lwip/echonet_udp_task.h
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/echonet_udp_task.h	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/echonet_udp_task.h	(revision 164)
@@ -0,0 +1,98 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ECHONET Lite ^XN
+ */
+
+#ifndef TOPPERS_ECHONET_UDP_TASK_H
+#define TOPPERS_ECHONET_UDP_TASK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <kernel.h>
+#include "echonet.h"
+#include "echonet_fbs.h"
+
+/*
+ *  ECHONET Lite êÄ¯ñAhX
+ */
+#ifdef SIL_ENDIAN_LITTLE
+#define ECHONET_MULTICAST_ADDR {0,23,0,224}
+#else
+#define ECHONET_MULTICAST_ADDR {224,0,23,0}
+#endif
+
+/*
+ *  ECHONET Lite ^XNÖAÌèÌftHglÌè`
+ */
+#ifndef ECHONET_UDP_TASK_PRIORITY
+#define ECHONET_UDP_TASK_PRIORITY	3		/* úDæx */
+#endif /* ECHONET_UDP_TASK_PRIORITY */
+
+#ifndef ECHONET_UDP_TASK_STACK_SIZE
+#define ECHONET_UDP_TASK_STACK_SIZE	1024	/* X^bNÌæÌTCY */
+#endif /* ECHONET_UDP_TASK_STACK_SIZE */
+
+#ifndef NUM_ECHONET_UDP_MAILBOX
+#define NUM_ECHONET_UDP_MAILBOX	10
+#endif /* NUM_ECHONET_UDP_MAILBOX */
+
+/*
+ *  ECHONET Lite ^XNÌ{Ì
+ */
+void echonet_udp_task(intptr_t exinf);
+
+/*
+ *  [gECHONETm[hÌKmF
+ */
+bool_t is_match(const EOBJCB *eobjcb, T_EDATA *edata, const void *_ipaddr, uint16_t portno);
+
+/* IPAhXð¶ñÉÏ· */
+char *ipaddr2str(char *buf, int bubsz, uint8_t *ipaddr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_ECHONET_UDP_TASK_H */
Index: UsbWattMeter/trunk/ecnl_lwip/fbs_string.c
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/fbs_string.c	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/fbs_string.c	(revision 164)
@@ -0,0 +1,215 @@
+/*
+ *  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
+ *  Copyright (C) 2015 Cores Co., Ltd. Japan
+ *
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ *
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ *
+ *  @(#) $Id$
+ */
+
+#include <stdint.h>
+#include <limits.h>
+#include <stdarg.h>
+#include "fbs_string.h"
+
+/*
+ *  lð¶ñÉÏ·
+ */
+#define CONVERT_BUFLEN	((sizeof(uintptr_t) * CHAR_BIT + 2) / 3)
+										/* uintptr_t^ÌlÌÅå¶ */
+static ER
+convert(ECN_FBS_ID fbs, ECN_FBS_SSIZE_T *pos, uintptr_t val, uint_t radix, const char *radchar,
+			uint_t width, bool_t minus, bool_t padzero)
+{
+	char	buf[CONVERT_BUFLEN];
+	uint_t	i, j;
+	ER ret;
+
+	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) {
+		ret = _ecn_fbs_poke(fbs, *pos, '-');
+		if(ret != E_OK)
+			return ret;
+		(*pos)++;
+	}
+	for (j = i; j < width; j++) {
+		ret = _ecn_fbs_poke(fbs, *pos, padzero ? '0' : ' ');
+		if(ret != E_OK)
+			return ret;
+		(*pos)++;
+	}
+	if (minus && !padzero) {
+		ret = _ecn_fbs_poke(fbs, *pos, '-');
+		if(ret != E_OK)
+			return ret;
+		(*pos)++;
+	}
+	while (i > 0U) {
+		ret = _ecn_fbs_poke(fbs, *pos, buf[--i]);
+		if(ret != E_OK)
+			return ret;
+		(*pos)++;
+	}
+	return E_OK;
+}
+
+/*
+ *  ¶ñ®`oÍ
+ */
+static const char raddec[] = "0123456789";
+static const char radhex[] = "0123456789abcdef";
+static const char radHEX[] = "0123456789ABCDEF";
+
+ECN_FBS_SSIZE_T
+fbs_printf(ECN_FBS_ID fbs, ECN_FBS_SSIZE_T *pos, const char *format, ...)
+{
+	char		c;
+	bool_t		lflag;
+	uint_t		width;
+	bool_t		padzero;
+	intptr_t	val;
+	const char	*str, *head;
+	va_list	ap;
+	ER ret;
+
+	va_start(ap, format);
+
+	while ((c = *format++) != '\0') {
+		if (c != '%') {
+			ret = _ecn_fbs_poke(fbs, *pos, c);
+			if (ret != E_OK)
+				return ret;
+			(*pos)++;
+			continue;
+		}
+
+		lflag = false;
+		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') {
+			lflag = true;
+			c = *format++;
+		}
+		switch (c) {
+		case 'd':
+			val = lflag ? (intptr_t) va_arg(ap, long_t)
+						: (intptr_t) va_arg(ap, int_t);
+			if (val >= 0) {
+				ret = convert(fbs, pos, (uintptr_t) val, 10U, raddec,
+										width, false, padzero);
+				if (ret != E_OK)
+					return ret;
+			}
+			else {
+				ret = convert(fbs, pos, (uintptr_t)(-val), 10U, raddec,
+										width, true, padzero);
+				if (ret != E_OK)
+					return ret;
+			}
+			break;
+		case 'u':
+			val = lflag ? (intptr_t) va_arg(ap, ulong_t)
+						: (intptr_t) va_arg(ap, uint_t);
+			ret = convert(fbs, pos, (uintptr_t) val, 10U, raddec, width, false, padzero);
+			if (ret != E_OK)
+				return ret;
+			break;
+		case 'x':
+		case 'p':
+			val = lflag ? (intptr_t) va_arg(ap, ulong_t)
+						: (intptr_t) va_arg(ap, uint_t);
+			ret = convert(fbs, pos, (uintptr_t) val, 16U, radhex, width, false, padzero);
+			if (ret != E_OK)
+				return ret;
+			break;
+		case 'X':
+			val = (intptr_t)va_arg(ap, void *);
+			ret = convert(fbs, pos, (uintptr_t) val, 16U, radHEX, width, false, padzero);
+			if (ret != E_OK)
+				return ret;
+			break;
+		case 'c':
+			ret = _ecn_fbs_poke(fbs, *pos, (char)(intptr_t)va_arg(ap, int));
+			if (ret != E_OK)
+				return ret;
+			(*pos)++;
+			break;
+		case 's':
+			str = head = (const char *)va_arg(ap, const char *);
+			while ((c = *str++) != '\0') {
+				ret = _ecn_fbs_poke(fbs, *pos, c);
+				if (ret != E_OK)
+					return ret;
+				(*pos)++;
+			}
+			break;
+		case '%':
+			ret = _ecn_fbs_poke(fbs, *pos, '%');
+			if (ret != E_OK)
+				return ret;
+			(*pos)++;
+			break;
+		case '\0':
+			format--;
+			break;
+		default:
+			break;
+		}
+	}
+	va_end(ap);
+
+	return E_OK;
+}
Index: UsbWattMeter/trunk/ecnl_lwip/fbs_string.h
===================================================================
--- UsbWattMeter/trunk/ecnl_lwip/fbs_string.h	(revision 164)
+++ UsbWattMeter/trunk/ecnl_lwip/fbs_string.h	(revision 164)
@@ -0,0 +1,49 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ *
+ *  Copyright (C) 2015 Cores Co., Ltd. Japan
+ *
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ *
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ *
+ *  @(#) $Id$
+ */
+
+#ifndef FBS_STRING_H
+#define FBS_STRING_H
+
+#include "echonet_fbs.h"
+
+ECN_FBS_SSIZE_T fbs_printf(ECN_FBS_ID buf, ECN_FBS_SSIZE_T *pos, const char *format, ...);
+
+#endif // FBS_STRING_H
Index: UsbWattMeter/trunk/fatfs/00readme.txt
===================================================================
--- UsbWattMeter/trunk/fatfs/00readme.txt	(revision 164)
+++ UsbWattMeter/trunk/fatfs/00readme.txt	(revision 164)
@@ -0,0 +1,158 @@
+FatFs Module Source Files R0.10b                      (C)ChaN, 2014
+
+
+FILES
+
+  ffconf.h   Configuration file for FatFs module.
+  ff.h       Common include file for FatFs and application module.
+  ff.c       FatFs module.
+  diskio.h   Common include file for FatFs and disk I/O module.
+  diskio.c   An example of glue function to attach existing disk I/O module to FatFs.
+  integer.h  Integer type definitions for FatFs.
+  option     Optional external functions.
+
+  Low level disk I/O module is not included in this archive because the FatFs
+  module is only a generic file system layer and not depend on any specific
+  storage device. You have to provide a low level disk I/O module that written
+  to control your storage device.
+
+
+
+AGREEMENTS
+
+ FatFs module is an open source software to implement FAT file system to
+ small embedded systems. This is a free software and is opened for education,
+ research and commercial developments under license policy of following trems.
+
+  Copyright (C) 2014, ChaN, all right reserved.
+
+ * The FatFs module is a free software and there is NO WARRANTY.
+ * No restriction on use. You can use, modify and redistribute it for
+   personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
+ * Redistributions of source code must retain the above copyright notice.
+
+
+
+REVISION HISTORY
+
+  Feb 26, 2006  R0.00  Prototype
+
+  Apr 29, 2006  R0.01  First release.
+
+  Jun 01, 2006  R0.02  Added FAT12.
+                       Removed unbuffered mode.
+                       Fixed a problem on small (<32M) patition.
+
+  Jun 10, 2006  R0.02a Added a configuration option _FS_MINIMUM.
+
+  Sep 22, 2006  R0.03  Added f_rename.
+                       Changed option _FS_MINIMUM to _FS_MINIMIZE.
+
+  Dec 11, 2006  R0.03a Improved cluster scan algolithm to write files fast.
+                       Fixed f_mkdir creates incorrect directory on FAT32.
+
+  Feb 04, 2007  R0.04  Supported multiple drive system. (FatFs)
+                       Changed some APIs for multiple drive system.
+                       Added f_mkfs. (FatFs)
+                       Added _USE_FAT32 option. (Tiny-FatFs)
+
+  Apr 01, 2007  R0.04a Supported multiple partitions on a plysical drive. (FatFs)
+                       Fixed an endian sensitive code in f_mkfs. (FatFs)
+                       Added a capability of extending the file size to f_lseek.
+                       Added minimization level 3.
+                       Fixed a problem that can collapse a sector when recreate an
+                       existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs)
+
+  May 05, 2007  R0.04b Added _USE_NTFLAG option.
+                       Added FSInfo support.
+                       Fixed some problems corresponds to FAT32. (Tiny-FatFs)
+                       Fixed DBCS name can result FR_INVALID_NAME.
+                       Fixed short seek (0 < ofs <= csize) collapses the file object.
+
+  Aug 25, 2007  R0.05  Changed arguments of f_read, f_write.
+                       Changed arguments of f_mkfs. (FatFs)
+                       Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs)
+                       Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs)
+
+  Feb 03, 2008  R0.05a Added f_truncate().
+                       Added f_utime().
+                       Fixed off by one error at FAT sub-type determination.
+                       Fixed btr in f_read() can be mistruncated.
+                       Fixed cached sector is not flushed when create and close without write.
+
+  Apr 01, 2008  R0.06  Added f_forward(). (Tiny-FatFs)
+                       Added string functions: fputc(), fputs(), fprintf() and fgets().
+                       Improved performance of f_lseek() on move to the same or following cluster.
+
+  Apr 01, 2009, R0.07  Merged Tiny-FatFs as a buffer configuration option.
+                       Added long file name support.
+                       Added multiple code page support.
+                       Added re-entrancy for multitask operation.
+                       Added auto cluster size selection to f_mkfs().
+                       Added rewind option to f_readdir().
+                       Changed result code of critical errors.
+                       Renamed string functions to avoid name collision.
+
+  Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg.
+                       Added multiple sector size support.
+
+  Jun 21, 2009, R0.07c Fixed f_unlink() may return FR_OK on error.
+                       Fixed wrong cache control in f_lseek().
+                       Added relative path feature.
+                       Added f_chdir().
+                       Added f_chdrive().
+                       Added proper case conversion for extended characters.
+
+  Nov 03, 2009 R0.07e  Separated out configuration options from ff.h to ffconf.h.
+                       Added a configuration option, _LFN_UNICODE.
+                       Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH.
+                       Fixed name matching error on the 13 char boundary.
+                       Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
+
+  May 15, 2010, R0.08  Added a memory configuration option. (_USE_LFN)
+                       Added file lock feature. (_FS_SHARE)
+                       Added fast seek feature. (_USE_FASTSEEK)
+                       Changed some types on the API, XCHAR->TCHAR.
+                       Changed fname member in the FILINFO structure on Unicode cfg.
+                       String functions support UTF-8 encoding files on Unicode cfg.
+
+  Aug 16,'10 R0.08a    Added f_getcwd(). (_FS_RPATH = 2)
+                       Added sector erase feature. (_USE_ERASE)
+                       Moved file lock semaphore table from fs object to the bss.
+                       Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'.
+                       Fixed f_mkfs() creates wrong FAT32 volume.
+
+  Jan 15,'11 R0.08b    Fast seek feature is also applied to f_read() and f_write().
+                       f_lseek() reports required table size on creating CLMP.
+                       Extended format syntax of f_printf function.
+                       Ignores duplicated directory separators in given path names.
+
+  Sep 06,'11 R0.09     f_mkfs() supports multiple partition to finish the multiple partition feature.
+                       Added f_fdisk(). (_MULTI_PARTITION = 2)
+
+  Aug 27,'12 R0.09a    Fixed assertion failure due to OS/2 EA on FAT12/16.
+                       Changed f_open() and f_opendir() reject null object pointer to avoid crash.
+                       Changed option name _FS_SHARE to _FS_LOCK.
+
+  Jan 23,'13 R0.09b    Added f_getlabel() and f_setlabel(). (_USE_LABEL)
+
+  Oct 02,'13 R0.10     Added selection of character encoding on the file. (_STRF_ENCODE)
+                       Added f_closedir().
+                       Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
+                       Added forced mount feature with changes of f_mount().
+                       Improved behavior of volume auto detection.
+                       Improved write throughput of f_puts() and f_printf().
+                       Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
+                       Fixed f_write() can be truncated when the file size is close to 4GB.
+                       Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.
+
+  Jan 15,'14 R0.10a    Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
+                       Added a configuration option of minimum sector size. (_MIN_SS)
+                       2nd argument of f_rename() can have a drive number and it will be ignored.
+                       Fixed f_mount() with forced mount fails when drive number is >= 1.
+                       Fixed f_close() invalidates the file object without volume lock.
+                       Fixed f_closedir() returns but the volume lock is left acquired.
+                       Fixed creation of an entry with LFN fails on too many SFN collisions.
+
+  Mar 19,'14 R0.10b    Fixed a hard error in the disk I/O layer can collapse the directory entry.
+                       Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN.
Index: UsbWattMeter/trunk/fatfs/diskio.h
===================================================================
--- UsbWattMeter/trunk/fatfs/diskio.h	(revision 164)
+++ UsbWattMeter/trunk/fatfs/diskio.h	(revision 164)
@@ -0,0 +1,94 @@
+/*-----------------------------------------------------------------------
+/  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
+
+
+/* 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 _FS_READONLY == 0) */
+#define GET_SECTOR_COUNT	1	/* Get media size (needed at _USE_MKFS == 1) */
+#define GET_SECTOR_SIZE		2	/* Get sector size (needed at _MAX_SS != _MIN_SS) */
+#define GET_BLOCK_SIZE		3	/* Get erase block size (needed at _USE_MKFS == 1) */
+#define CTRL_TRIM			4	/* Inform device that the data on the block of sectors is no longer used (needed at _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
Index: UsbWattMeter/trunk/fatfs/ff.c
===================================================================
--- UsbWattMeter/trunk/fatfs/ff.c	(revision 164)
+++ UsbWattMeter/trunk/fatfs/ff.c	(revision 164)
@@ -0,0 +1,4688 @@
+/*----------------------------------------------------------------------------/
+/  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 "ff.h"			/* Declarations of FatFs API */
+#include "diskio.h"		/* Declarations of disk I/O functions */
+
+
+/*--------------------------------------------------------------------------
+
+   Module Private Definitions
+
+---------------------------------------------------------------------------*/
+
+#if _FATFS != 64180	/* Revision ID */
+#error Wrong include file (ff.h).
+#endif
+
+
+/* Reentrancy related */
+#if _FS_REENTRANT
+#if _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 (_MAX_SS < _MIN_SS) || (_MAX_SS != 512 && _MAX_SS != 1024 && _MAX_SS != 2048 && _MAX_SS != 4096) || (_MIN_SS != 512 && _MIN_SS != 1024 && _MIN_SS != 2048 && _MIN_SS != 4096)
+#error Wrong sector size configuration
+#endif
+#if _MAX_SS == _MIN_SS
+#define	SS(fs)	((UINT)_MAX_SS)	/* Fixed sector size */
+#else
+#define	SS(fs)	((fs)->ssize)	/* Variable sector size */
+#endif
+
+
+/* Timestamp feature */
+#if _FS_NORTC == 1
+#if _NORTC_YEAR < 1980 || _NORTC_YEAR > 2107 || _NORTC_MON < 1 || _NORTC_MON > 12 || _NORTC_MDAY < 1 || _NORTC_MDAY > 31
+#error Invalid _FS_NORTC settings
+#endif
+#define GET_FATTIME()	((DWORD)(_NORTC_YEAR - 1980) << 25 | (DWORD)_NORTC_MON << 21 | (DWORD)_NORTC_MDAY << 16)
+#else
+#define GET_FATTIME()	get_fattime()
+#endif
+
+
+/* File access control feature */
+#if _FS_LOCK
+#if _FS_READONLY
+#error _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _CODE_PAGE == 1	/* ASCII (for only non-LFN cfg) */
+#if _USE_LFN
+#error Cannot use LFN feature without valid code page.
+#endif
+#define _DF1S	0
+
+#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 _VOLUMES < 1 || _VOLUMES > 9
+#error Wrong _VOLUMES setting
+#endif
+static FATFS *FatFs[_VOLUMES];	/* Pointer to the file system objects (logical drives) */
+static WORD Fsid;				/* File system mount ID */
+
+#if _FS_RPATH && _VOLUMES >= 2
+static BYTE CurrVol;			/* Current drive */
+#endif
+
+#if _FS_LOCK
+static FILESEM Files[_FS_LOCK];	/* Open object lock semaphores */
+#endif
+
+#if _USE_LFN == 0			/* Non LFN feature */
+#define	DEFINE_NAMEBUF		BYTE sfn[12]
+#define INIT_BUF(dobj)		(dobj).fn = sfn
+#define	FREE_BUF()
+#else
+#if _MAX_LFN < 12 || _MAX_LFN > 255
+#error Wrong _MAX_LFN setting
+#endif
+#if _USE_LFN == 1			/* LFN feature with static working buffer */
+static WCHAR LfnBuf[_MAX_LFN + 1];
+#define	DEFINE_NAMEBUF		BYTE sfn[12]
+#define INIT_BUF(dobj)		{ (dobj).fn = sfn; (dobj).lfn = LfnBuf; }
+#define	FREE_BUF()
+#elif _USE_LFN == 2 		/* LFN feature with dynamic working buffer on the stack */
+#define	DEFINE_NAMEBUF		BYTE sfn[12]; WCHAR lbuf[_MAX_LFN + 1]
+#define INIT_BUF(dobj)		{ (dobj).fn = sfn; (dobj).lfn = lbuf; }
+#define	FREE_BUF()
+#elif _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((_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 _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 _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 _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 _FS_LOCK
+
+static
+FRESULT chk_lock (	/* Check if the file can be accessed */
+	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 < _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 == _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 < _FS_LOCK && Files[i].fs; i++) ;
+	return (i == _FS_LOCK) ? 0 : 1;
+}
+
+
+static
+UINT inc_lock (	/* Increment object open counter and returns its index (0:Internal error) */
+	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 < _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 == _FS_LOCK) {				/* Not opened. Register it as new. */
+		for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ;
+		if (i == _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 < _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 < _FS_LOCK; i++) {
+		if (Files[i].fs == fs) Files[i].fs = 0;
+	}
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Move/Flush disk access window in the file system object               */
+/*-----------------------------------------------------------------------*/
+#if !_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 !_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 !_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 !_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 /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* FAT handling - Remove a cluster chain                                 */
+/*-----------------------------------------------------------------------*/
+#if !_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 _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 _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 !_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 /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* FAT handling - Convert offset into cluster with link map table        */
+/*-----------------------------------------------------------------------*/
+
+#if _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	/* _USE_FASTSEEK */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Directory handling - Set directory index                              */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT dir_sdi (	/* FR_OK(0):succeeded, !=0:error */
+	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 */
+	DIR* dp,		/* Pointer to the directory object */
+	int stretch		/* 0: Do not stretch table, 1: Stretch table if needed */
+)
+{
+	DWORD clst;
+	UINT i;
+#if !_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 !_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 !_FS_READONLY
+static
+FRESULT dir_alloc (	/* FR_OK(0):succeeded, !=0:error */
+	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 !_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 _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 >= _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 >= _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 >= _MAX_LFN) return 0;		/* Buffer overflow? */
+		lfnbuf[i] = 0;
+	}
+
+	return 1;		/* The part of LFN is valid */
+}
+
+
+#if !_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 _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 _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 */
+	DIR* dp			/* Pointer to the directory object linked to the file name */
+)
+{
+	FRESULT res;
+	BYTE c, *dir;
+#if _USE_LFN
+	BYTE a, ord, sum;
+#endif
+
+	res = dir_sdi(dp, 0);			/* Rewind directory object */
+	if (res != FR_OK) return res;
+
+#if _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 _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 _FS_MINIMIZE <= 1 || _USE_LABEL || _FS_RPATH >= 2
+static
+FRESULT dir_read (
+	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 _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 _USE_LFN	/* LFN configuration */
+		if (c == DDEM || (!_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 && (_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	/* _FS_MINIMIZE <= 1 || _USE_LABEL || _FS_RPATH >= 2 */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Register an object to the directory                                   */
+/*-----------------------------------------------------------------------*/
+#if !_FS_READONLY
+static
+FRESULT dir_register (	/* FR_OK:succeeded, FR_DENIED:no free entry or too many SFN collision, FR_DISK_ERR:disk error */
+	DIR* dp				/* Target directory with object name to be created */
+)
+{
+	FRESULT res;
+#if _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 (_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 _USE_LFN
+			dp->dir[DIR_NTres] = dp->fn[NSFLAG] & (NS_BODY | NS_EXT);	/* Put NT flag */
+#endif
+			dp->fs->wflag = 1;
+		}
+	}
+
+	return res;
+}
+#endif /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Remove an object from the directory                                   */
+/*-----------------------------------------------------------------------*/
+#if !_FS_READONLY && !_FS_MINIMIZE
+static
+FRESULT dir_remove (	/* FR_OK:Succeeded, FR_DISK_ERR:A disk error */
+	DIR* dp				/* Directory object pointing the entry to be removed */
+)
+{
+	FRESULT res;
+#if _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 /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get file information from directory entry                             */
+/*-----------------------------------------------------------------------*/
+#if _FS_MINIMIZE <= 1 || _FS_RPATH >= 2
+static
+void get_fileinfo (		/* No return code */
+	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 _USE_LFN
+	WCHAR w, *lfn;
+#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 _USE_LFN
+			if (IsUpper(c) && (dir[DIR_NTres] & (i >= 9 ? NS_EXT : NS_BODY)))
+				c += 0x20;			/* To lower */
+#if _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 _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 !_LFN_UNICODE
+				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
+				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 /* _FS_MINIMIZE <= 1 || _FS_RPATH >= 2 */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Pattern matching                                                      */
+/*-----------------------------------------------------------------------*/
+#if _USE_FIND && _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 !_LFN_UNICODE
+	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)++;
+#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 /* _USE_FIND && _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 */
+	DIR* dp,			/* Pointer to the directory object */
+	const TCHAR** path	/* Pointer to pointer to the segment in the path string */
+)
+{
+#if _USE_LFN	/* LFN configuration */
+	BYTE b, cf;
+	WCHAR w, *lfn;
+	UINT i, ni, si, di;
+	const TCHAR *p;
+
+	/* 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 >= _MAX_LFN)				/* Reject too long name */
+			return FR_INVALID_NAME;
+#if !_LFN_UNICODE
+		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
+		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 _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
+			w = ff_convert(ff_wtoupper(w), 0);	/* Upper converted Unicode -> OEM code */
+#endif
+			cf |= NS_LFN;				/* Force create LFN entry */
+		}
+
+		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;
+	}
+
+	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 _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 */
+	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 _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 (_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 _STR_VOLUME_ID		/* Find string drive id */
+	static const char* const str[] = {_VOLUME_STRS};
+	const char *sp;
+	char c;
+	TCHAR tc;
+#endif
+
+
+	if (*path) {	/* If the pointer is not a null */
+		for (tt = *path; (UINT)*tt >= (_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 < _VOLUMES) {	/* If a drive id is found, get the value and strip it */
+					vol = (int)i;
+					*path = ++tt;
+				}
+			}
+#if _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 < _VOLUMES);	/* Repeat for each id until pattern match */
+				if (i < _VOLUMES) {	/* If a drive id is found, get the value and strip it */
+					vol = (int)i;
+					*path = tt;
+				}
+			}
+#endif
+			return vol;
+		}
+#if _FS_RPATH && _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 (!_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 (!_FS_READONLY && wmode && (stat & STA_PROTECT))	/* Check disk write protection if needed */
+		return FR_WRITE_PROTECTED;
+#if _MAX_SS != _MIN_SS						/* Get sector size (multiple sector size cfg only) */
+	if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK
+		|| SS(fs) < _MIN_SS || SS(fs) > _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 + 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 !_FS_READONLY
+	/* Initialize cluster allocation information */
+	fs->last_clust = fs->free_clust = 0xFFFFFFFF;
+
+	/* Get fsinfo if available */
+	fs->fsi_flag = 0x80;
+#if (_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 (_FS_NOFSINFO & 1) == 0
+			fs->free_clust = LD_DWORD(fs->win + FSI_Free_Count);
+#endif
+#if (_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 _FS_RPATH
+	fs->cdir = 0;		/* Set current directory to root */
+#endif
+#if _FS_LOCK			/* 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/DIR to check validity */
+)
+{
+	FIL *fil = (FIL*)obj;	/* Assuming offset of .fs and .id in the FIL/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 _FS_LOCK
+		clear_lock(cfs);
+#endif
+#if _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 _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;
+	DIR dj;
+	BYTE *dir;
+	DEFINE_NAMEBUF;
+#if !_FS_READONLY
+	DWORD dw, cl;
+#endif
+
+
+	if (!fp) return FR_INVALID_OBJECT;
+	fp->fs = 0;			/* Clear file object */
+
+	/* Get logical drive number */
+#if !_FS_READONLY
+	mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW;
+	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 !_FS_READONLY	/* R/W configuration */
+		if (res == FR_OK) {
+			if (!dir)	/* Default directory itself */
+				res = FR_INVALID_NAME;
+#if _FS_LOCK
+			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 _FS_LOCK
+					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 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__WRITTEN;
+			fp->dir_sect = dj.fs->winsect;		/* Pointer to the directory entry */
+			fp->dir_ptr = dir;
+#if _FS_LOCK
+			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 _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 _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 !_FS_READONLY && _FS_MINIMIZE <= 2			/* Replace one of the read sectors with cached data if it contains a dirty sector */
+#if _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 !_FS_TINY
+			if (fp->dsect != sect) {			/* Load data sector if not in cache */
+#if !_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 _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 !_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 _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 _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 _FS_MINIMIZE <= 2
+#if _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 _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 _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__WRITTEN;						/* 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__WRITTEN) {	/* Is there any change to the file? */
+#if !_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__WRITTEN;
+				fp->fs->wflag = 1;
+				res = sync_fs(fp->fs);
+			}
+		}
+	}
+
+	LEAVE_FF(fp->fs, res);
+}
+
+#endif /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Close File                                                            */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_close (
+	FIL *fp		/* Pointer to the file object to be closed */
+)
+{
+	FRESULT res;
+
+
+#if !_FS_READONLY
+	res = f_sync(fp);					/* Flush cached data */
+	if (res == FR_OK)
+#endif
+	{
+		res = validate(fp);				/* Lock volume */
+		if (res == FR_OK) {
+#if _FS_REENTRANT
+			FATFS *fs = fp->fs;
+#endif
+#if _FS_LOCK
+			res = dec_lock(fp->lockid);	/* Decrement file open counter */
+			if (res == FR_OK)
+#endif
+				fp->fs = 0;				/* Invalidate file object */
+#if _FS_REENTRANT
+			unlock_fs(fs, FR_OK);		/* Unlock volume */
+#endif
+		}
+	}
+	return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Change Current Directory or Current Drive, Get Current Directory      */
+/*-----------------------------------------------------------------------*/
+
+#if _FS_RPATH >= 1
+#if _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;
+	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 _FS_RPATH >= 2
+FRESULT f_getcwd (
+	TCHAR* buff,	/* Pointer to the directory path */
+	UINT len		/* Size of path */
+)
+{
+	FRESULT res;
+	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 _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 _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 _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 /* _FS_RPATH >= 2 */
+#endif /* _FS_RPATH >= 1 */
+
+
+
+#if _FS_MINIMIZE <= 2
+/*-----------------------------------------------------------------------*/
+/* Seek File R/W Pointer                                                 */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_lseek (
+	FIL* fp,		/* Pointer to the file object */
+	DWORD ofs		/* File pointer from top of file */
+)
+{
+	FRESULT res;
+	DWORD clst, bcs, nsect, ifptr;
+#if _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 _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 !_FS_TINY
+#if !_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 !_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 !_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 !_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 !_FS_TINY
+#if !_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 !_FS_READONLY
+		if (fp->fptr > fp->fsize) {			/* Set file change flag if the file size is extended */
+			fp->fsize = fp->fptr;
+			fp->flag |= FA__WRITTEN;
+		}
+#endif
+	}
+
+	LEAVE_FF(fp->fs, res);
+}
+
+
+
+#if _FS_MINIMIZE <= 1
+/*-----------------------------------------------------------------------*/
+/* Create a Directory Object                                             */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_opendir (
+	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 _FS_LOCK
+				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 (
+	DIR *dp		/* Pointer to the directory object to be closed */
+)
+{
+	FRESULT res;
+
+
+	res = validate(dp);
+	if (res == FR_OK) {
+#if _FS_REENTRANT
+		FATFS *fs = dp->fs;
+#endif
+#if _FS_LOCK
+		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 _FS_REENTRANT
+		unlock_fs(fs, FR_OK);		/* Unlock volume */
+#endif
+	}
+	return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read Directory Entries in Sequence                                    */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_readdir (
+	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 _USE_FIND
+/*-----------------------------------------------------------------------*/
+/* Find next file                                                        */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_findnext (
+	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 _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 (
+	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	/* _USE_FIND */
+
+
+
+#if _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;
+	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 !_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__WRITTEN;
+			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 !_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;
+	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 (_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT))
+			res = FR_INVALID_NAME;			/* Cannot remove dot entry */
+#if _FS_LOCK
+		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 _FS_RPATH
+					if (dclst == dj.fs->cdir) {		 		/* Is it the current directory? */
+						res = FR_DENIED;
+					} else
+#endif
+					{
+						mem_cpy(&sdj, &dj, sizeof (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;
+	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 (_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;
+	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 (_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;
+	DIR djo, djn;
+	BYTE buf[21], *dir;
+	DWORD dw;
+	DEFINE_NAMEBUF;
+
+
+	/* 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 (_FS_RPATH && res == FR_OK && (djo.fn[NSFLAG] & NS_DOT))
+			res = FR_INVALID_NAME;
+#if _FS_LOCK
+		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 (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 */
+				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();
+	}
+
+	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;
+	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 (_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 /* !_FS_READONLY */
+#endif /* _FS_MINIMIZE == 0 */
+#endif /* _FS_MINIMIZE <= 1 */
+#endif /* _FS_MINIMIZE <= 2 */
+
+
+
+
+#if _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;
+	DIR dj;
+	UINT i, j;
+#if _USE_LFN && _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 _USE_LFN && _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 !_FS_READONLY
+/*-----------------------------------------------------------------------*/
+/* Set volume label                                                      */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_setlabel (
+	const TCHAR* label	/* Pointer to the volume label to set */
+)
+{
+	FRESULT res;
+	DIR dj;
+	BYTE vn[11];
+	UINT i, j, sl;
+	WCHAR w;
+	DWORD tm;
+
+
+	/* 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 _USE_LFN && _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 _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;
+		} 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 /* !_FS_READONLY */
+#endif /* _USE_LABEL */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Forward data to the stream directly (available on only tiny cfg)      */
+/*-----------------------------------------------------------------------*/
+#if _USE_FORWARD && _FS_TINY
+
+FRESULT f_forward (
+	FIL* fp, 						/* Pointer to the file object */
+	UINT (*func)(const BYTE*,UINT),	/* Pointer to the streaming function */
+	UINT 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 /* _USE_FORWARD */
+
+
+
+#if _USE_MKFS && !_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 _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 _MAX_SS != _MIN_SS		/* Get disk sector size */
+	if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS || SS(fs) < _MIN_SS)
+		return FR_DISK_ERR;
+#endif
+	if (_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 >= _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 (_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 _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 _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, _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 /* _MULTI_PARTITION */
+#endif /* _USE_MKFS && !_FS_READONLY */
+
+
+
+
+#if _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 _USE_LFN && _LFN_UNICODE
+#if _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 _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 _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 (_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 !_FS_READONLY
+#include <stdarg.h>
+/*-----------------------------------------------------------------------*/
+/* 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 (_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 _USE_LFN && _LFN_UNICODE
+#if _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 _STRF_ENCODE == 2			/* Write a character in UTF-16BE */
+	pb->buf[i++] = (BYTE)(c >> 8);
+	pb->buf[i++] = (BYTE)c;
+#elif _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 /* !_FS_READONLY */
+#endif /* _USE_STRFUNC */
Index: UsbWattMeter/trunk/fatfs/ff.h
===================================================================
--- UsbWattMeter/trunk/fatfs/ff.h	(revision 164)
+++ UsbWattMeter/trunk/fatfs/ff.h	(revision 164)
@@ -0,0 +1,375 @@
+/*---------------------------------------------------------------------------/
+/  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 */
+#if _FATFS != _FFCONF
+#error Wrong configuration file (ffconf.h).
+#endif
+
+
+
+/* Definitions of volume management */
+
+#if _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 _LFN_UNICODE			/* Unicode string */
+#if !_USE_LFN
+#error _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 _MAX_SS != _MIN_SS
+	WORD	ssize;			/* Bytes per sector (512, 1024, 2048 or 4096) */
+#endif
+#if _FS_REENTRANT
+	_SYNC_t	sobj;			/* Identifier of sync object */
+#endif
+#if !_FS_READONLY
+	DWORD	last_clust;		/* Last allocated cluster */
+	DWORD	free_clust;		/* Number of free clusters */
+#endif
+#if _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[_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 !_FS_READONLY
+	DWORD	dir_sect;		/* Sector number containing the directory entry */
+	BYTE*	dir_ptr;		/* Pointer to the directory entry in the win[] */
+#endif
+#if _USE_FASTSEEK
+	DWORD*	cltbl;			/* Pointer to the cluster link map table (Nulled on file open) */
+#endif
+#if _FS_LOCK
+	UINT	lockid;			/* File lock ID origin from 1 (index of file semaphore table Files[]) */
+#endif
+#if !_FS_TINY
+	BYTE	buf[_MAX_SS];	/* File private data read/write window */
+#endif
+} FIL;
+
+
+
+/* Directory object structure (DIR) */
+
+typedef struct {
+	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 _FS_LOCK
+	UINT	lockid;			/* File lock ID (index of file semaphore table Files[]) */
+#endif
+#if _USE_LFN
+	WCHAR*	lfn;			/* Pointer to the LFN working buffer */
+	WORD	lfn_idx;		/* Last matched LFN index number (0xFFFF:No LFN) */
+#endif
+#if _USE_FIND
+	const TCHAR*	pat;	/* Pointer to the name matching pattern */
+#endif
+} 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 _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 > _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 (DIR* dp, const TCHAR* path);						/* Open a directory */
+FRESULT f_closedir (DIR* dp);										/* Close an open directory */
+FRESULT f_readdir (DIR* dp, FILINFO* fno);							/* Read a directory item */
+FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern);	/* Find first file */
+FRESULT f_findnext (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)
+
+#define F_SEEK_SET 1
+#define F_SEEK_CUR 2
+#define F_SEEK_END 3
+static FRESULT f_seek(FIL* fp, DWORD ofs, BYTE mode)
+{
+  switch (mode) {
+  case F_SEEK_SET:
+    f_lseek((fp), ofs);
+    break;
+  case F_SEEK_CUR:
+    f_lseek((fp), (fp)->fptr + ofs);
+    break;
+  case F_SEEK_END:
+    f_lseek((fp), (fp)->fsize - ofs);
+    break;
+  default:
+    return FR_INVALID_PARAMETER;
+  }
+
+  return FR_OK;
+}
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+
+
+
+
+/*--------------------------------------------------------------*/
+/* Additional user defined functions                            */
+
+/* RTC function */
+#if !_FS_READONLY && !_FS_NORTC
+DWORD get_fattime (void);
+#endif
+
+/* Unicode support functions */
+#if _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 _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 _FS_REENTRANT
+int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj);	/* Create a sync object */
+int ff_req_grant (_SYNC_t sobj);				/* Lock sync object */
+void ff_rel_grant (_SYNC_t sobj);				/* Unlock sync object */
+int ff_del_syncobj (_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 !_FS_READONLY
+#define	FA_WRITE			0x02
+#define	FA_CREATE_NEW		0x04
+#define	FA_CREATE_ALWAYS	0x08
+#define	FA_OPEN_ALWAYS		0x10
+#define FA__WRITTEN			0x20
+#define FA__DIRTY			0x40
+#endif
+
+
+/* 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 _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: UsbWattMeter/trunk/fatfs/ffconf.h
===================================================================
--- UsbWattMeter/trunk/fatfs/ffconf.h	(revision 164)
+++ UsbWattMeter/trunk/fatfs/ffconf.h	(revision 164)
@@ -0,0 +1,276 @@
+/*---------------------------------------------------------------------------/
+/  FatFs - FAT file system module configuration file  R0.11a (C)ChaN, 2015
+/---------------------------------------------------------------------------*/
+
+#define _FFCONF 64180	/* Revision ID */
+
+/*---------------------------------------------------------------------------/
+/ Function Configurations
+/---------------------------------------------------------------------------*/
+
+#define _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 _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	_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 _USE_FIND		1
+/* This option switches filtered directory read feature and related functions,
+/  f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
+
+
+#define	_USE_MKFS		1
+/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
+
+
+#define	_USE_FASTSEEK	0
+/* This option switches fast seek feature. (0:Disable or 1:Enable) */
+
+
+#define _USE_LABEL		1
+/* This option switches volume label functions, f_getlabel() and f_setlabel().
+/  (0:Disable or 1:Enable) */
+
+
+#define	_USE_FORWARD	1
+/* This option switches f_forward() function. (0:Disable or 1:Enable)
+/  To enable it, also _FS_TINY need to be set to 1. */
+
+
+/*---------------------------------------------------------------------------/
+/ Locale and Namespace Configurations
+/---------------------------------------------------------------------------*/
+
+#define _CODE_PAGE 437
+/* 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	_USE_LFN	1
+#define	_MAX_LFN	255
+/* The _USE_LFN option switches the LFN feature.
+/
+/   0: Disable LFN feature. _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 (_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	_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 _LFN_UNICODE
+/  to 1. This option also affects behavior of string I/O functions. */
+
+
+#define _STRF_ENCODE	3
+/* When _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 _LFN_UNICODE is 0, this option has no effect. */
+
+
+#define _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 _VOLUMES	1
+/* Number of volumes (logical drives) to be used. */
+
+
+#define _STR_VOLUME_ID	0
+#define _VOLUME_STRS	"RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
+/* _STR_VOLUME_ID option switches string volume ID feature.
+/  When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
+/  number in the path name. _VOLUME_STRS defines the drive ID strings for each
+/  logical drives. Number of items must be equal to _VOLUMES. Valid characters for
+/  the drive ID strings are: A-Z and 0-9. */
+
+
+#define	_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	_MIN_SS		512
+#define	_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 _MAX_SS is larger than _MIN_SS, FatFs is configured
+/  to variable sector size and GET_SECTOR_SIZE command must be implemented to the
+/  disk_ioctl() function. */
+
+
+#define	_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 _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	_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 _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 _FS_NORTC	0
+#define _NORTC_MON	1
+#define _NORTC_MDAY	1
+#define _NORTC_YEAR	2015
+/* The _FS_NORTC option switches timestamp feature. If the system does not have
+/  an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
+/  the timestamp feature. All objects modified by FatFs will have a fixed timestamp
+/  defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR.
+/  When timestamp feature is enabled (_FS_NORTC == 0), get_fattime() function need
+/  to be added to the project to read current time form RTC. _NORTC_MON,
+/  _NORTC_MDAY and _NORTC_YEAR have no effect. 
+/  These options have no effect at read-only configuration (_FS_READONLY == 1). */
+
+
+#define	_FS_LOCK	0
+/* The _FS_LOCK option switches file lock feature to control duplicated file open
+/  and illegal operation to open objects. This option must be 0 when _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 _FS_REENTRANT	0
+#define _FS_TIMEOUT		1000
+#define	_SYNC_t			HANDLE
+/* The _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. _FS_TIMEOUT and _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 _FS_TIMEOUT defines timeout period in unit of time tick.
+/  The _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 _WORD_ACCESS	1
+/* The _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, _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: UsbWattMeter/trunk/fatfs/integer.h
===================================================================
--- UsbWattMeter/trunk/fatfs/integer.h	(revision 164)
+++ UsbWattMeter/trunk/fatfs/integer.h	(revision 164)
@@ -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: UsbWattMeter/trunk/fatfs/mmc_rspi.c
===================================================================
--- UsbWattMeter/trunk/fatfs/mmc_rspi.c	(revision 164)
+++ UsbWattMeter/trunk/fatfs/mmc_rspi.c	(revision 164)
@@ -0,0 +1,793 @@
+/*------------------------------------------------------------------------*/
+/* 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>
+#ifdef __RX
+#include <rx630_ccrx/prc_rename.h>
+#else
+#include <rx630_msvc/prc_rename.h>
+#endif
+#include "target_config.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ðIð */
+	sil_wrb_mem(PORTC_ODR0_ADDR, 0x00);
+	/* CMOSðIð */
+	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()
+{
+	/*
+	 * W
+[Xgbv@\ÌÝè(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ÆµÄgp */
+	sil_wrb_mem(PORT1_PMR_ADDR,
+		sil_reb_mem(PORT1_PMR_ADDR) & ~PORT_PMR_B5_BIT);
+	/* PC0ðGPIOÆµÄgp */
+	sil_wrb_mem(PORTC_PMR_ADDR,
+		sil_reb_mem(PORTC_PMR_ADDR) & ~PORT_PMR_B0_BIT);
+	/* PC5, PC6, PC7ðüÓ@\ÆµÄgp */
+	sil_wrb_mem(PORTC_PMR_ADDR,
+		sil_reb_mem(PORTC_PMR_ADDR) | PORT_PMR_B5_BIT | PORT_PMR_B6_BIT | PORT_PMR_B7_BIT);
+
+	/* «ÝveNgWX^ÌÝè PFSWErbgÖÌ«ÝðÂ */
+	sil_wrb_mem(MPC_PWPR_ADDR, 0x00);
+	/* «ÝveNgWX^ÌÝè PxxFSWX^ÖÌ«ÝðÂ */
+	sil_wrb_mem(MPC_PWPR_ADDR, 0x40);
+
+	/* RSPCKAðIð */
+	sil_wrb_mem(MPC_PC5PFS_ADDR, 0x0d);
+	/* MOSIAðIð */
+	sil_wrb_mem(MPC_PC6PFS_ADDR, 0x0d);
+	/* MISOAðIð */
+	sil_wrb_mem(MPC_PC7PFS_ADDR, 0x0d);
+
+	/* «ÝveNgWX^ÌÝè «ÝðÖ~ */
+	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);
+	/* rbg[gÝè */
+	sil_wrb_mem(RSPI0_SPBR_ADDR, F_PCLK / 2 / SCLK_FAST - 1);
+	/* RSPI@\ðLø» */
+	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 */
+	wai_sem(MMC_RSPI_SEMAPHORE);
+	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 disk_initialize(
+	BYTE drv		/* Physical drive number (0) */
+	)
+{
+	BYTE n, cmd, ty, ocr[4];
+
+
+	if (drv) return STA_NOINIT;			/* Supports only drive 0 */
+
+	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 disk_status(
+	BYTE drv		/* Physical drive number (0) */
+	)
+{
+	if (drv) return STA_NOINIT;		/* Supports only drive 0 */
+
+	return Stat;	/* Return disk status */
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read sector(s)                                                        */
+/*-----------------------------------------------------------------------*/
+
+DRESULT disk_read(
+	BYTE drv,		/* Physical drive number (0) */
+	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 (drv || !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 disk_write(
+	BYTE drv,			/* Physical drive number (0) */
+	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 (drv || !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 disk_ioctl(
+	BYTE drv,		/* Physical drive number (0) */
+	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 (drv) return RES_PARERR;					/* Check parameter */
+	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 _USE_TRIM == 1) */
+		if (!(CardType & CT_SDC)) break;				/* Check if the card is SDC */
+		if (disk_ioctl(drv, 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 disk_timerproc(void)
+{
+	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);
+	Stat = s;
+}
+
+void mmc_rspi_spri_handler(void)
+{
+	i_begin_int(INTNO_MMC_RSPI_SPRI);
+
+	isig_sem(MMC_RSPI_SEMAPHORE);
+
+	i_end_int(INTNO_MMC_RSPI_SPRI);
+}
+
+void mmc_rspi_spti_handler(void)
+{
+	i_begin_int(INTNO_MMC_RSPI_SPTI);
+
+	i_end_int(INTNO_MMC_RSPI_SPTI);
+}
+
+void mmc_rspi_spii_handler(void)
+{
+	i_begin_int(INTNO_MMC_RSPI_SPII);
+
+	i_end_int(INTNO_MMC_RSPI_SPII);
+}
+
+void mmc_rspi_cychdr(intptr_t exinf)
+{
+	disk_timerproc();
+}
Index: UsbWattMeter/trunk/fatfs/mmc_rspi.cfg
===================================================================
--- UsbWattMeter/trunk/fatfs/mmc_rspi.cfg	(revision 164)
+++ UsbWattMeter/trunk/fatfs/mmc_rspi.cfg	(revision 164)
@@ -0,0 +1,58 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+#include "mmc_rspi.h"
+
+/* èÝnh */
+
+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, 0, mmc_rspi_cychdr, 1, 0 });
+
+CRE_SEM(MMC_RSPI_SEMAPHORE, { TA_TPRI, 0, 1 });
+
Index: UsbWattMeter/trunk/fatfs/mmc_rspi.h
===================================================================
--- UsbWattMeter/trunk/fatfs/mmc_rspi.h	(revision 164)
+++ UsbWattMeter/trunk/fatfs/mmc_rspi.h	(revision 164)
@@ -0,0 +1,67 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _MMC_RSPI_H_
+#define _MMC_RSPI_H_
+
+#include "t_stddef.h"
+
+#define INHNO_MMC_RSPI_SPRI		INT_RSPI0_SPRI0	/* óMèÝ */
+#define INTNO_MMC_RSPI_SPRI		INT_RSPI0_SPRI0	/* óMèÝ */
+#define INTATR_MMC_RSPI_SPRI	(TA_NULL)		/* Ý®«	*/
+#define INTPRI_MMC_RSPI_SPRI	(-1)			/* ÝDæx	*/
+
+#define INHNO_MMC_RSPI_SPTI		INT_RSPI0_SPTI0	/* MèÝ */
+#define INTNO_MMC_RSPI_SPTI		INT_RSPI0_SPTI0	/* MèÝ */
+#define INTATR_MMC_RSPI_SPTI	(TA_NULL)		/* Ý®«	*/
+#define INTPRI_MMC_RSPI_SPTI	(-1)			/* ÝDæx	*/
+
+#define INHNO_MMC_RSPI_SPII		INT_RSPI0_SPII0	/* AChèÝ */
+#define INTNO_MMC_RSPI_SPII		INT_RSPI0_SPII0	/* AChèÝ */
+#define INTATR_MMC_RSPI_SPII	(TA_NULL)		/* Ý®«	*/
+#define INTPRI_MMC_RSPI_SPII	(-1)			/* ÝDæx	*/
+
+extern void mmc_rspi_spri_handler(void);
+extern void mmc_rspi_spti_handler(void);
+extern void mmc_rspi_spii_handler(void);
+extern void mmc_rspi_cychdr(intptr_t exinf);
+
+#endif /* _MMC_RSPI_H_ */
Index: UsbWattMeter/trunk/fatfs/option/cc932.c
===================================================================
--- UsbWattMeter/trunk/fatfs/option/cc932.c	(revision 164)
+++ UsbWattMeter/trunk/fatfs/option/cc932.c	(revision 164)
@@ -0,0 +1,3829 @@
+/*------------------------------------------------------------------------*/
+/* Unicode - OEM code bidirectional converter  (C)ChaN, 2015              */
+/* CP932 (Japanese Shift-JIS)                                             */
+/*------------------------------------------------------------------------*/
+
+#include "../ff.h"
+
+#define _TINY_TABLE	0
+
+#if !_USE_LFN || _CODE_PAGE != 932
+#error This file is not needed in current configuration. Remove from the project.
+#endif
+
+
+static
+const WCHAR uni2sjis[] = {
+/*  Unicode - Sjis, Unicode - Sjis, Unicode - Sjis, Unicode - Sjis, */
+	0x00A7, 0x8198, 0x00A8, 0x814E, 0x00B0, 0x818B, 0x00B1, 0x817D,
+	0x00B4, 0x814C, 0x00B6, 0x81F7, 0x00D7, 0x817E, 0x00F7, 0x8180,
+	0x0391, 0x839F, 0x0392, 0x83A0, 0x0393, 0x83A1, 0x0394, 0x83A2,
+	0x0395, 0x83A3, 0x0396, 0x83A4, 0x0397, 0x83A5, 0x0398, 0x83A6,
+	0x0399, 0x83A7, 0x039A, 0x83A8, 0x039B, 0x83A9, 0x039C, 0x83AA,
+	0x039D, 0x83AB, 0x039E, 0x83AC, 0x039F, 0x83AD, 0x03A0, 0x83AE,
+	0x03A1, 0x83AF, 0x03A3, 0x83B0, 0x03A4, 0x83B1, 0x03A5, 0x83B2,
+	0x03A6, 0x83B3, 0x03A7, 0x83B4, 0x03A8, 0x83B5, 0x03A9, 0x83B6,
+	0x03B1, 0x83BF, 0x03B2, 0x83C0, 0x03B3, 0x83C1, 0x03B4, 0x83C2,
+	0x03B5, 0x83C3, 0x03B6, 0x83C4, 0x03B7, 0x83C5, 0x03B8, 0x83C6,
+	0x03B9, 0x83C7, 0x03BA, 0x83C8, 0x03BB, 0x83C9, 0x03BC, 0x83CA,
+	0x03BD, 0x83CB, 0x03BE, 0x83CC, 0x03BF, 0x83CD, 0x03C0, 0x83CE,
+	0x03C1, 0x83CF, 0x03C3, 0x83D0, 0x03C4, 0x83D1, 0x03C5, 0x83D2,
+	0x03C6, 0x83D3, 0x03C7, 0x83D4, 0x03C8, 0x83D5, 0x03C9, 0x83D6,
+	0x0401, 0x8446, 0x0410, 0x8440, 0x0411, 0x8441, 0x0412, 0x8442,
+	0x0413, 0x8443, 0x0414, 0x8444, 0x0415, 0x8445, 0x0416, 0x8447,
+	0x0417, 0x8448, 0x0418, 0x8449, 0x0419, 0x844A, 0x041A, 0x844B,
+	0x041B, 0x844C, 0x041C, 0x844D, 0x041D, 0x844E, 0x041E, 0x844F,
+	0x041F, 0x8450, 0x0420, 0x8451, 0x0421, 0x8452, 0x0422, 0x8453,
+	0x0423, 0x8454, 0x0424, 0x8455, 0x0425, 0x8456, 0x0426, 0x8457,
+	0x0427, 0x8458, 0x0428, 0x8459, 0x0429, 0x845A, 0x042A, 0x845B,
+	0x042B, 0x845C, 0x042C, 0x845D, 0x042D, 0x845E, 0x042E, 0x845F,
+	0x042F, 0x8460, 0x0430, 0x8470, 0x0431, 0x8471, 0x0432, 0x8472,
+	0x0433, 0x8473, 0x0434, 0x8474, 0x0435, 0x8475, 0x0436, 0x8477,
+	0x0437, 0x8478, 0x0438, 0x8479, 0x0439, 0x847A, 0x043A, 0x847B,
+	0x043B, 0x847C, 0x043C, 0x847D, 0x043D, 0x847E, 0x043E, 0x8480,
+	0x043F, 0x8481, 0x0440, 0x8482, 0x0441, 0x8483, 0x0442, 0x8484,
+	0x0443, 0x8485, 0x0444, 0x8486, 0x0445, 0x8487, 0x0446, 0x8488,
+	0x0447, 0x8489, 0x0448, 0x848A, 0x0449, 0x848B, 0x044A, 0x848C,
+	0x044B, 0x848D, 0x044C, 0x848E, 0x044D, 0x848F, 0x044E, 0x8490,
+	0x044F, 0x8491, 0x0451, 0x8476, 0x2010, 0x815D, 0x2015, 0x815C,
+	0x2018, 0x8165, 0x2019, 0x8166, 0x201C, 0x8167, 0x201D, 0x8168,
+	0x2020, 0x81F5, 0x2021, 0x81F6, 0x2025, 0x8164, 0x2026, 0x8163,
+	0x2030, 0x81F1, 0x2032, 0x818C, 0x2033, 0x818D, 0x203B, 0x81A6,
+	0x2103, 0x818E, 0x2116, 0x8782, 0x2121, 0x8784, 0x212B, 0x81F0,
+	0x2160, 0x8754, 0x2161, 0x8755, 0x2162, 0x8756, 0x2163, 0x8757,
+	0x2164, 0x8758, 0x2165, 0x8759, 0x2166, 0x875A, 0x2167, 0x875B,
+	0x2168, 0x875C, 0x2169, 0x875D, 0x2170, 0xFA40, 0x2171, 0xFA41,
+	0x2172, 0xFA42, 0x2173, 0xFA43, 0x2174, 0xFA44, 0x2175, 0xFA45,
+	0x2176, 0xFA46, 0x2177, 0xFA47, 0x2178, 0xFA48, 0x2179, 0xFA49,
+	0x2190, 0x81A9, 0x2191, 0x81AA, 0x2192, 0x81A8, 0x2193, 0x81AB,
+	0x21D2, 0x81CB, 0x21D4, 0x81CC, 0x2200, 0x81CD, 0x2202, 0x81DD,
+	0x2203, 0x81CE, 0x2207, 0x81DE, 0x2208, 0x81B8, 0x220B, 0x81B9,
+	0x2211, 0x8794, 0x221A, 0x81E3, 0x221D, 0x81E5, 0x221E, 0x8187,
+	0x221F, 0x8798, 0x2220, 0x81DA, 0x2225, 0x8161, 0x2227, 0x81C8,
+	0x2228, 0x81C9, 0x2229, 0x81BF, 0x222A, 0x81BE, 0x222B, 0x81E7,
+	0x222C, 0x81E8, 0x222E, 0x8793, 0x2234, 0x8188, 0x2235, 0x81E6,
+	0x223D, 0x81E4, 0x2252, 0x81E0, 0x2260, 0x8182, 0x2261, 0x81DF,
+	0x2266, 0x8185, 0x2267, 0x8186, 0x226A, 0x81E1, 0x226B, 0x81E2,
+	0x2282, 0x81BC, 0x2283, 0x81BD, 0x2286, 0x81BA, 0x2287, 0x81BB,
+	0x22A5, 0x81DB, 0x22BF, 0x8799, 0x2312, 0x81DC, 0x2460, 0x8740,
+	0x2461, 0x8741, 0x2462, 0x8742, 0x2463, 0x8743, 0x2464, 0x8744,
+	0x2465, 0x8745, 0x2466, 0x8746, 0x2467, 0x8747, 0x2468, 0x8748,
+	0x2469, 0x8749, 0x246A, 0x874A, 0x246B, 0x874B, 0x246C, 0x874C,
+	0x246D, 0x874D, 0x246E, 0x874E, 0x246F, 0x874F, 0x2470, 0x8750,
+	0x2471, 0x8751, 0x2472, 0x8752, 0x2473, 0x8753, 0x2500, 0x849F,
+	0x2501, 0x84AA, 0x2502, 0x84A0, 0x2503, 0x84AB, 0x250C, 0x84A1,
+	0x250F, 0x84AC, 0x2510, 0x84A2, 0x2513, 0x84AD, 0x2514, 0x84A4,
+	0x2517, 0x84AF, 0x2518, 0x84A3, 0x251B, 0x84AE, 0x251C, 0x84A5,
+	0x251D, 0x84BA, 0x2520, 0x84B5, 0x2523, 0x84B0, 0x2524, 0x84A7,
+	0x2525, 0x84BC, 0x2528, 0x84B7, 0x252B, 0x84B2, 0x252C, 0x84A6,
+	0x252F, 0x84B6, 0x2530, 0x84BB, 0x2533, 0x84B1, 0x2534, 0x84A8,
+	0x2537, 0x84B8, 0x2538, 0x84BD, 0x253B, 0x84B3, 0x253C, 0x84A9,
+	0x253F, 0x84B9, 0x2542, 0x84BE, 0x254B, 0x84B4, 0x25A0, 0x81A1,
+	0x25A1, 0x81A0, 0x25B2, 0x81A3, 0x25B3, 0x81A2, 0x25BC, 0x81A5,
+	0x25BD, 0x81A4, 0x25C6, 0x819F, 0x25C7, 0x819E, 0x25CB, 0x819B,
+	0x25CE, 0x819D, 0x25CF, 0x819C, 0x25EF, 0x81FC, 0x2605, 0x819A,
+	0x2606, 0x8199, 0x2640, 0x818A, 0x2642, 0x8189, 0x266A, 0x81F4,
+	0x266D, 0x81F3, 0x266F, 0x81F2, 0x3000, 0x8140, 0x3001, 0x8141,
+	0x3002, 0x8142, 0x3003, 0x8156, 0x3005, 0x8158, 0x3006, 0x8159,
+	0x3007, 0x815A, 0x3008, 0x8171, 0x3009, 0x8172, 0x300A, 0x8173,
+	0x300B, 0x8174, 0x300C, 0x8175, 0x300D, 0x8176, 0x300E, 0x8177,
+	0x300F, 0x8178, 0x3010, 0x8179, 0x3011, 0x817A, 0x3012, 0x81A7,
+	0x3013, 0x81AC, 0x3014, 0x816B, 0x3015, 0x816C, 0x301D, 0x8780,
+	0x301F, 0x8781, 0x3041, 0x829F, 0x3042, 0x82A0, 0x3043, 0x82A1,
+	0x3044, 0x82A2, 0x3045, 0x82A3, 0x3046, 0x82A4, 0x3047, 0x82A5,
+	0x3048, 0x82A6, 0x3049, 0x82A7, 0x304A, 0x82A8, 0x304B, 0x82A9,
+	0x304C, 0x82AA, 0x304D, 0x82AB, 0x304E, 0x82AC, 0x304F, 0x82AD,
+	0x3050, 0x82AE, 0x3051, 0x82AF, 0x3052, 0x82B0, 0x3053, 0x82B1,
+	0x3054, 0x82B2, 0x3055, 0x82B3, 0x3056, 0x82B4, 0x3057, 0x82B5,
+	0x3058, 0x82B6, 0x3059, 0x82B7, 0x305A, 0x82B8, 0x305B, 0x82B9,
+	0x305C, 0x82BA, 0x305D, 0x82BB, 0x305E, 0x82BC, 0x305F, 0x82BD,
+	0x3060, 0x82BE, 0x3061, 0x82BF, 0x3062, 0x82C0, 0x3063, 0x82C1,
+	0x3064, 0x82C2, 0x3065, 0x82C3, 0x3066, 0x82C4, 0x3067, 0x82C5,
+	0x3068, 0x82C6, 0x3069, 0x82C7, 0x306A, 0x82C8, 0x306B, 0x82C9,
+	0x306C, 0x82CA, 0x306D, 0x82CB, 0x306E, 0x82CC, 0x306F, 0x82CD,
+	0x3070, 0x82CE, 0x3071, 0x82CF, 0x3072, 0x82D0, 0x3073, 0x82D1,
+	0x3074, 0x82D2, 0x3075, 0x82D3, 0x3076, 0x82D4, 0x3077, 0x82D5,
+	0x3078, 0x82D6, 0x3079, 0x82D7, 0x307A, 0x82D8, 0x307B, 0x82D9,
+	0x307C, 0x82DA, 0x307D, 0x82DB, 0x307E, 0x82DC, 0x307F, 0x82DD,
+	0x3080, 0x82DE, 0x3081, 0x82DF, 0x3082, 0x82E0, 0x3083, 0x82E1,
+	0x3084, 0x82E2, 0x3085, 0x82E3, 0x3086, 0x82E4, 0x3087, 0x82E5,
+	0x3088, 0x82E6, 0x3089, 0x82E7, 0x308A, 0x82E8, 0x308B, 0x82E9,
+	0x308C, 0x82EA, 0x308D, 0x82EB, 0x308E, 0x82EC, 0x308F, 0x82ED,
+	0x3090, 0x82EE, 0x3091, 0x82EF, 0x3092, 0x82F0, 0x3093, 0x82F1,
+	0x309B, 0x814A, 0x309C, 0x814B, 0x309D, 0x8154, 0x309E, 0x8155,
+	0x30A1, 0x8340, 0x30A2, 0x8341, 0x30A3, 0x8342, 0x30A4, 0x8343,
+	0x30A5, 0x8344, 0x30A6, 0x8345, 0x30A7, 0x8346, 0x30A8, 0x8347,
+	0x30A9, 0x8348, 0x30AA, 0x8349, 0x30AB, 0x834A, 0x30AC, 0x834B,
+	0x30AD, 0x834C, 0x30AE, 0x834D, 0x30AF, 0x834E, 0x30B0, 0x834F,
+	0x30B1, 0x8350, 0x30B2, 0x8351, 0x30B3, 0x8352, 0x30B4, 0x8353,
+	0x30B5, 0x8354, 0x30B6, 0x8355, 0x30B7, 0x8356, 0x30B8, 0x8357,
+	0x30B9, 0x8358, 0x30BA, 0x8359, 0x30BB, 0x835A, 0x30BC, 0x835B,
+	0x30BD, 0x835C, 0x30BE, 0x835D, 0x30BF, 0x835E, 0x30C0, 0x835F,
+	0x30C1, 0x8360, 0x30C2, 0x8361, 0x30C3, 0x8362, 0x30C4, 0x8363,
+	0x30C5, 0x8364, 0x30C6, 0x8365, 0x30C7, 0x8366, 0x30C8, 0x8367,
+	0x30C9, 0x8368, 0x30CA, 0x8369, 0x30CB, 0x836A, 0x30CC, 0x836B,
+	0x30CD, 0x836C, 0x30CE, 0x836D, 0x30CF, 0x836E, 0x30D0, 0x836F,
+	0x30D1, 0x8370, 0x30D2, 0x8371, 0x30D3, 0x8372, 0x30D4, 0x8373,
+	0x30D5, 0x8374, 0x30D6, 0x8375, 0x30D7, 0x8376, 0x30D8, 0x8377,
+	0x30D9, 0x8378, 0x30DA, 0x8379, 0x30DB, 0x837A, 0x30DC, 0x837B,
+	0x30DD, 0x837C, 0x30DE, 0x837D, 0x30DF, 0x837E, 0x30E0, 0x8380,
+	0x30E1, 0x8381, 0x30E2, 0x8382, 0x30E3, 0x8383, 0x30E4, 0x8384,
+	0x30E5, 0x8385, 0x30E6, 0x8386, 0x30E7, 0x8387, 0x30E8, 0x8388,
+	0x30E9, 0x8389, 0x30EA, 0x838A, 0x30EB, 0x838B, 0x30EC, 0x838C,
+	0x30ED, 0x838D, 0x30EE, 0x838E, 0x30EF, 0x838F, 0x30F0, 0x8390,
+	0x30F1, 0x8391, 0x30F2, 0x8392, 0x30F3, 0x8393, 0x30F4, 0x8394,
+	0x30F5, 0x8395, 0x30F6, 0x8396, 0x30FB, 0x8145, 0x30FC, 0x815B,
+	0x30FD, 0x8152, 0x30FE, 0x8153, 0x3231, 0x878A, 0x3232, 0x878B,
+	0x3239, 0x878C, 0x32A4, 0x8785, 0x32A5, 0x8786, 0x32A6, 0x8787,
+	0x32A7, 0x8788, 0x32A8, 0x8789, 0x3303, 0x8765, 0x330D, 0x8769,
+	0x3314, 0x8760, 0x3318, 0x8763, 0x3322, 0x8761, 0x3323, 0x876B,
+	0x3326, 0x876A, 0x3327, 0x8764, 0x332B, 0x876C, 0x3336, 0x8766,
+	0x333B, 0x876E, 0x3349, 0x875F, 0x334A, 0x876D, 0x334D, 0x8762,
+	0x3351, 0x8767, 0x3357, 0x8768, 0x337B, 0x877E, 0x337C, 0x878F,
+	0x337D, 0x878E, 0x337E, 0x878D, 0x338E, 0x8772, 0x338F, 0x8773,
+	0x339C, 0x876F, 0x339D, 0x8770, 0x339E, 0x8771, 0x33A1, 0x8775,
+	0x33C4, 0x8774, 0x33CD, 0x8783, 0x4E00, 0x88EA, 0x4E01, 0x929A,
+	0x4E03, 0x8EB5, 0x4E07, 0x969C, 0x4E08, 0x8FE4, 0x4E09, 0x8E4F,
+	0x4E0A, 0x8FE3, 0x4E0B, 0x89BA, 0x4E0D, 0x9573, 0x4E0E, 0x975E,
+	0x4E10, 0x98A0, 0x4E11, 0x894E, 0x4E14, 0x8A8E, 0x4E15, 0x98A1,
+	0x4E16, 0x90A2, 0x4E17, 0x99C0, 0x4E18, 0x8B75, 0x4E19, 0x95B8,
+	0x4E1E, 0x8FE5, 0x4E21, 0x97BC, 0x4E26, 0x95C0, 0x4E28, 0xFA68,
+	0x4E2A, 0x98A2, 0x4E2D, 0x9286, 0x4E31, 0x98A3, 0x4E32, 0x8BF8,
+	0x4E36, 0x98A4, 0x4E38, 0x8ADB, 0x4E39, 0x924F, 0x4E3B, 0x8EE5,
+	0x4E3C, 0x98A5, 0x4E3F, 0x98A6, 0x4E42, 0x98A7, 0x4E43, 0x9454,
+	0x4E45, 0x8B76, 0x4E4B, 0x9456, 0x4E4D, 0x93E1, 0x4E4E, 0x8CC1,
+	0x4E4F, 0x9652, 0x4E55, 0xE568, 0x4E56, 0x98A8, 0x4E57, 0x8FE6,
+	0x4E58, 0x98A9, 0x4E59, 0x89B3, 0x4E5D, 0x8BE3, 0x4E5E, 0x8CEE,
+	0x4E5F, 0x96E7, 0x4E62, 0x9BA4, 0x4E71, 0x9790, 0x4E73, 0x93FB,
+	0x4E7E, 0x8AA3, 0x4E80, 0x8B54, 0x4E82, 0x98AA, 0x4E85, 0x98AB,
+	0x4E86, 0x97B9, 0x4E88, 0x975C, 0x4E89, 0x9188, 0x4E8A, 0x98AD,
+	0x4E8B, 0x8E96, 0x4E8C, 0x93F1, 0x4E8E, 0x98B0, 0x4E91, 0x895D,
+	0x4E92, 0x8CDD, 0x4E94, 0x8CDC, 0x4E95, 0x88E4, 0x4E98, 0x986A,
+	0x4E99, 0x9869, 0x4E9B, 0x8DB1, 0x4E9C, 0x889F, 0x4E9E, 0x98B1,
+	0x4E9F, 0x98B2, 0x4EA0, 0x98B3, 0x4EA1, 0x9653, 0x4EA2, 0x98B4,
+	0x4EA4, 0x8CF0, 0x4EA5, 0x88E5, 0x4EA6, 0x9692, 0x4EA8, 0x8B9C,
+	0x4EAB, 0x8B9D, 0x4EAC, 0x8B9E, 0x4EAD, 0x92E0, 0x4EAE, 0x97BA,
+	0x4EB0, 0x98B5, 0x4EB3, 0x98B6, 0x4EB6, 0x98B7, 0x4EBA, 0x906C,
+	0x4EC0, 0x8F59, 0x4EC1, 0x906D, 0x4EC2, 0x98BC, 0x4EC4, 0x98BA,
+	0x4EC6, 0x98BB, 0x4EC7, 0x8B77, 0x4ECA, 0x8DA1, 0x4ECB, 0x89EE,
+	0x4ECD, 0x98B9, 0x4ECE, 0x98B8, 0x4ECF, 0x95A7, 0x4ED4, 0x8E65,
+	0x4ED5, 0x8E64, 0x4ED6, 0x91BC, 0x4ED7, 0x98BD, 0x4ED8, 0x9574,
+	0x4ED9, 0x90E5, 0x4EDD, 0x8157, 0x4EDE, 0x98BE, 0x4EDF, 0x98C0,
+	0x4EE1, 0xFA69, 0x4EE3, 0x91E3, 0x4EE4, 0x97DF, 0x4EE5, 0x88C8,
+	0x4EED, 0x98BF, 0x4EEE, 0x89BC, 0x4EF0, 0x8BC2, 0x4EF2, 0x9287,
+	0x4EF6, 0x8C8F, 0x4EF7, 0x98C1, 0x4EFB, 0x9443, 0x4EFC, 0xFA6A,
+	0x4F00, 0xFA6B, 0x4F01, 0x8AE9, 0x4F03, 0xFA6C, 0x4F09, 0x98C2,
+	0x4F0A, 0x88C9, 0x4F0D, 0x8CDE, 0x4F0E, 0x8AEA, 0x4F0F, 0x959A,
+	0x4F10, 0x94B0, 0x4F11, 0x8B78, 0x4F1A, 0x89EF, 0x4F1C, 0x98E5,
+	0x4F1D, 0x9360, 0x4F2F, 0x948C, 0x4F30, 0x98C4, 0x4F34, 0x94BA,
+	0x4F36, 0x97E0, 0x4F38, 0x904C, 0x4F39, 0xFA6D, 0x4F3A, 0x8E66,
+	0x4F3C, 0x8E97, 0x4F3D, 0x89BE, 0x4F43, 0x92CF, 0x4F46, 0x9241,
+	0x4F47, 0x98C8, 0x4F4D, 0x88CA, 0x4F4E, 0x92E1, 0x4F4F, 0x8F5A,
+	0x4F50, 0x8DB2, 0x4F51, 0x9743, 0x4F53, 0x91CC, 0x4F55, 0x89BD,
+	0x4F56, 0xFA6E, 0x4F57, 0x98C7, 0x4F59, 0x975D, 0x4F5A, 0x98C3,
+	0x4F5B, 0x98C5, 0x4F5C, 0x8DEC, 0x4F5D, 0x98C6, 0x4F5E, 0x9B43,
+	0x4F69, 0x98CE, 0x4F6F, 0x98D1, 0x4F70, 0x98CF, 0x4F73, 0x89C0,
+	0x4F75, 0x95B9, 0x4F76, 0x98C9, 0x4F7B, 0x98CD, 0x4F7C, 0x8CF1,
+	0x4F7F, 0x8E67, 0x4F83, 0x8AA4, 0x4F86, 0x98D2, 0x4F88, 0x98CA,
+	0x4F8A, 0xFA70, 0x4F8B, 0x97E1, 0x4F8D, 0x8E98, 0x4F8F, 0x98CB,
+	0x4F91, 0x98D0, 0x4F92, 0xFA6F, 0x4F94, 0xFA72, 0x4F96, 0x98D3,
+	0x4F98, 0x98CC, 0x4F9A, 0xFA71, 0x4F9B, 0x8B9F, 0x4F9D, 0x88CB,
+	0x4FA0, 0x8BA0, 0x4FA1, 0x89BF, 0x4FAB, 0x9B44, 0x4FAD, 0x9699,
+	0x4FAE, 0x958E, 0x4FAF, 0x8CF2, 0x4FB5, 0x904E, 0x4FB6, 0x97B5,
+	0x4FBF, 0x95D6, 0x4FC2, 0x8C57, 0x4FC3, 0x91A3, 0x4FC4, 0x89E2,
+	0x4FC9, 0xFA61, 0x4FCA, 0x8F72, 0x4FCD, 0xFA73, 0x4FCE, 0x98D7,
+	0x4FD0, 0x98DC, 0x4FD1, 0x98DA, 0x4FD4, 0x98D5, 0x4FD7, 0x91AD,
+	0x4FD8, 0x98D8, 0x4FDA, 0x98DB, 0x4FDB, 0x98D9, 0x4FDD, 0x95DB,
+	0x4FDF, 0x98D6, 0x4FE1, 0x904D, 0x4FE3, 0x9693, 0x4FE4, 0x98DD,
+	0x4FE5, 0x98DE, 0x4FEE, 0x8F43, 0x4FEF, 0x98EB, 0x4FF3, 0x946F,
+	0x4FF5, 0x9555, 0x4FF6, 0x98E6, 0x4FF8, 0x95EE, 0x4FFA, 0x89B4,
+	0x4FFE, 0x98EA, 0x4FFF, 0xFA76, 0x5005, 0x98E4, 0x5006, 0x98ED,
+	0x5009, 0x9171, 0x500B, 0x8CC2, 0x500D, 0x947B, 0x500F, 0xE0C5,
+	0x5011, 0x98EC, 0x5012, 0x937C, 0x5014, 0x98E1, 0x5016, 0x8CF4,
+	0x5019, 0x8CF3, 0x501A, 0x98DF, 0x501E, 0xFA77, 0x501F, 0x8ED8,
+	0x5021, 0x98E7, 0x5022, 0xFA75, 0x5023, 0x95ED, 0x5024, 0x926C,
+	0x5025, 0x98E3, 0x5026, 0x8C91, 0x5028, 0x98E0, 0x5029, 0x98E8,
+	0x502A, 0x98E2, 0x502B, 0x97CF, 0x502C, 0x98E9, 0x502D, 0x9860,
+	0x5036, 0x8BE4, 0x5039, 0x8C90, 0x5040, 0xFA74, 0x5042, 0xFA7A,
+	0x5043, 0x98EE, 0x5046, 0xFA78, 0x5047, 0x98EF, 0x5048, 0x98F3,
+	0x5049, 0x88CC, 0x504F, 0x95CE, 0x5050, 0x98F2, 0x5055, 0x98F1,
+	0x5056, 0x98F5, 0x505A, 0x98F4, 0x505C, 0x92E2, 0x5065, 0x8C92,
+	0x506C, 0x98F6, 0x5070, 0xFA79, 0x5072, 0x8EC3, 0x5074, 0x91A4,
+	0x5075, 0x92E3, 0x5076, 0x8BF4, 0x5078, 0x98F7, 0x507D, 0x8B55,
+	0x5080, 0x98F8, 0x5085, 0x98FA, 0x508D, 0x9654, 0x5091, 0x8C86,
+	0x5094, 0xFA7B, 0x5098, 0x8E50, 0x5099, 0x94F5, 0x509A, 0x98F9,
+	0x50AC, 0x8DC3, 0x50AD, 0x9762, 0x50B2, 0x98FC, 0x50B3, 0x9942,
+	0x50B4, 0x98FB, 0x50B5, 0x8DC2, 0x50B7, 0x8F9D, 0x50BE, 0x8C58,
+	0x50C2, 0x9943, 0x50C5, 0x8BCD, 0x50C9, 0x9940, 0x50CA, 0x9941,
+	0x50CD, 0x93AD, 0x50CF, 0x919C, 0x50D1, 0x8BA1, 0x50D5, 0x966C,
+	0x50D6, 0x9944, 0x50D8, 0xFA7D, 0x50DA, 0x97BB, 0x50DE, 0x9945,
+	0x50E3, 0x9948, 0x50E5, 0x9946, 0x50E7, 0x916D, 0x50ED, 0x9947,
+	0x50EE, 0x9949, 0x50F4, 0xFA7C, 0x50F5, 0x994B, 0x50F9, 0x994A,
+	0x50FB, 0x95C6, 0x5100, 0x8B56, 0x5101, 0x994D, 0x5102, 0x994E,
+	0x5104, 0x89AD, 0x5109, 0x994C, 0x5112, 0x8EF2, 0x5114, 0x9951,
+	0x5115, 0x9950, 0x5116, 0x994F, 0x5118, 0x98D4, 0x511A, 0x9952,
+	0x511F, 0x8F9E, 0x5121, 0x9953, 0x512A, 0x9744, 0x5132, 0x96D7,
+	0x5137, 0x9955, 0x513A, 0x9954, 0x513B, 0x9957, 0x513C, 0x9956,
+	0x513F, 0x9958, 0x5140, 0x9959, 0x5141, 0x88F2, 0x5143, 0x8CB3,
+	0x5144, 0x8C5A, 0x5145, 0x8F5B, 0x5146, 0x929B, 0x5147, 0x8BA2,
+	0x5148, 0x90E6, 0x5149, 0x8CF5, 0x514A, 0xFA7E, 0x514B, 0x8D8E,
+	0x514C, 0x995B, 0x514D, 0x96C6, 0x514E, 0x9365, 0x5150, 0x8E99,
+	0x5152, 0x995A, 0x5154, 0x995C, 0x515A, 0x937D, 0x515C, 0x8A95,
+	0x5162, 0x995D, 0x5164, 0xFA80, 0x5165, 0x93FC, 0x5168, 0x9153,
+	0x5169, 0x995F, 0x516A, 0x9960, 0x516B, 0x94AA, 0x516C, 0x8CF6,
+	0x516D, 0x985A, 0x516E, 0x9961, 0x5171, 0x8BA4, 0x5175, 0x95BA,
+	0x5176, 0x91B4, 0x5177, 0x8BEF, 0x5178, 0x9354, 0x517C, 0x8C93,
+	0x5180, 0x9962, 0x5182, 0x9963, 0x5185, 0x93E0, 0x5186, 0x897E,
+	0x5189, 0x9966, 0x518A, 0x8DFB, 0x518C, 0x9965, 0x518D, 0x8DC4,
+	0x518F, 0x9967, 0x5190, 0xE3EC, 0x5191, 0x9968, 0x5192, 0x9660,
+	0x5193, 0x9969, 0x5195, 0x996A, 0x5196, 0x996B, 0x5197, 0x8FE7,
+	0x5199, 0x8ECA, 0x519D, 0xFA81, 0x51A0, 0x8AA5, 0x51A2, 0x996E,
+	0x51A4, 0x996C, 0x51A5, 0x96BB, 0x51A6, 0x996D, 0x51A8, 0x9579,
+	0x51A9, 0x996F, 0x51AA, 0x9970, 0x51AB, 0x9971, 0x51AC, 0x937E,
+	0x51B0, 0x9975, 0x51B1, 0x9973, 0x51B2, 0x9974, 0x51B3, 0x9972,
+	0x51B4, 0x8DE1, 0x51B5, 0x9976, 0x51B6, 0x96E8, 0x51B7, 0x97E2,
+	0x51BD, 0x9977, 0x51BE, 0xFA82, 0x51C4, 0x90A6, 0x51C5, 0x9978,
+	0x51C6, 0x8F79, 0x51C9, 0x9979, 0x51CB, 0x929C, 0x51CC, 0x97BD,
+	0x51CD, 0x9380, 0x51D6, 0x99C3, 0x51DB, 0x997A, 0x51DC, 0xEAA3,
+	0x51DD, 0x8BC3, 0x51E0, 0x997B, 0x51E1, 0x967D, 0x51E6, 0x8F88,
+	0x51E7, 0x91FA, 0x51E9, 0x997D, 0x51EA, 0x93E2, 0x51EC, 0xFA83,
+	0x51ED, 0x997E, 0x51F0, 0x9980, 0x51F1, 0x8A4D, 0x51F5, 0x9981,
+	0x51F6, 0x8BA5, 0x51F8, 0x93CA, 0x51F9, 0x899A, 0x51FA, 0x8F6F,
+	0x51FD, 0x949F, 0x51FE, 0x9982, 0x5200, 0x9381, 0x5203, 0x906E,
+	0x5204, 0x9983, 0x5206, 0x95AA, 0x5207, 0x90D8, 0x5208, 0x8AA0,
+	0x520A, 0x8AA7, 0x520B, 0x9984, 0x520E, 0x9986, 0x5211, 0x8C59,
+	0x5214, 0x9985, 0x5215, 0xFA84, 0x5217, 0x97F1, 0x521D, 0x8F89,
+	0x5224, 0x94BB, 0x5225, 0x95CA, 0x5227, 0x9987, 0x5229, 0x9798,
+	0x522A, 0x9988, 0x522E, 0x9989, 0x5230, 0x939E, 0x5233, 0x998A,
+	0x5236, 0x90A7, 0x5237, 0x8DFC, 0x5238, 0x8C94, 0x5239, 0x998B,
+	0x523A, 0x8E68, 0x523B, 0x8D8F, 0x5243, 0x92E4, 0x5244, 0x998D,
+	0x5247, 0x91A5, 0x524A, 0x8DED, 0x524B, 0x998E, 0x524C, 0x998F,
+	0x524D, 0x914F, 0x524F, 0x998C, 0x5254, 0x9991, 0x5256, 0x9655,
+	0x525B, 0x8D84, 0x525E, 0x9990, 0x5263, 0x8C95, 0x5264, 0x8DDC,
+	0x5265, 0x948D, 0x5269, 0x9994, 0x526A, 0x9992, 0x526F, 0x959B,
+	0x5270, 0x8FE8, 0x5271, 0x999B, 0x5272, 0x8A84, 0x5273, 0x9995,
+	0x5274, 0x9993, 0x5275, 0x916E, 0x527D, 0x9997, 0x527F, 0x9996,
+	0x5283, 0x8A63, 0x5287, 0x8C80, 0x5288, 0x999C, 0x5289, 0x97AB,
+	0x528D, 0x9998, 0x5291, 0x999D, 0x5292, 0x999A, 0x5294, 0x9999,
+	0x529B, 0x97CD, 0x529C, 0xFA85, 0x529F, 0x8CF7, 0x52A0, 0x89C1,
+	0x52A3, 0x97F2, 0x52A6, 0xFA86, 0x52A9, 0x8F95, 0x52AA, 0x9377,
+	0x52AB, 0x8D85, 0x52AC, 0x99A0, 0x52AD, 0x99A1, 0x52AF, 0xFB77,
+	0x52B1, 0x97E3, 0x52B4, 0x984A, 0x52B5, 0x99A3, 0x52B9, 0x8CF8,
+	0x52BC, 0x99A2, 0x52BE, 0x8A4E, 0x52C0, 0xFA87, 0x52C1, 0x99A4,
+	0x52C3, 0x9675, 0x52C5, 0x92BA, 0x52C7, 0x9745, 0x52C9, 0x95D7,
+	0x52CD, 0x99A5, 0x52D2, 0xE8D3, 0x52D5, 0x93AE, 0x52D7, 0x99A6,
+	0x52D8, 0x8AA8, 0x52D9, 0x96B1, 0x52DB, 0xFA88, 0x52DD, 0x8F9F,
+	0x52DE, 0x99A7, 0x52DF, 0x95E5, 0x52E0, 0x99AB, 0x52E2, 0x90A8,
+	0x52E3, 0x99A8, 0x52E4, 0x8BCE, 0x52E6, 0x99A9, 0x52E7, 0x8AA9,
+	0x52F2, 0x8C4D, 0x52F3, 0x99AC, 0x52F5, 0x99AD, 0x52F8, 0x99AE,
+	0x52F9, 0x99AF, 0x52FA, 0x8ED9, 0x52FE, 0x8CF9, 0x52FF, 0x96DC,
+	0x5300, 0xFA89, 0x5301, 0x96E6, 0x5302, 0x93F5, 0x5305, 0x95EF,
+	0x5306, 0x99B0, 0x5307, 0xFA8A, 0x5308, 0x99B1, 0x530D, 0x99B3,
+	0x530F, 0x99B5, 0x5310, 0x99B4, 0x5315, 0x99B6, 0x5316, 0x89BB,
+	0x5317, 0x966B, 0x5319, 0x8DFA, 0x531A, 0x99B7, 0x531D, 0x9178,
+	0x5320, 0x8FA0, 0x5321, 0x8BA7, 0x5323, 0x99B8, 0x5324, 0xFA8B,
+	0x532A, 0x94D9, 0x532F, 0x99B9, 0x5331, 0x99BA, 0x5333, 0x99BB,
+	0x5338, 0x99BC, 0x5339, 0x9543, 0x533A, 0x8BE6, 0x533B, 0x88E3,
+	0x533F, 0x93BD, 0x5340, 0x99BD, 0x5341, 0x8F5C, 0x5343, 0x90E7,
+	0x5345, 0x99BF, 0x5346, 0x99BE, 0x5347, 0x8FA1, 0x5348, 0x8CDF,
+	0x5349, 0x99C1, 0x534A, 0x94BC, 0x534D, 0x99C2, 0x5351, 0x94DA,
+	0x5352, 0x91B2, 0x5353, 0x91EC, 0x5354, 0x8BA6, 0x5357, 0x93EC,
+	0x5358, 0x9250, 0x535A, 0x948E, 0x535C, 0x966D, 0x535E, 0x99C4,
+	0x5360, 0x90E8, 0x5366, 0x8C54, 0x5369, 0x99C5, 0x536E, 0x99C6,
+	0x536F, 0x894B, 0x5370, 0x88F3, 0x5371, 0x8AEB, 0x5372, 0xFA8C,
+	0x5373, 0x91A6, 0x5374, 0x8B70, 0x5375, 0x9791, 0x5377, 0x99C9,
+	0x5378, 0x89B5, 0x537B, 0x99C8, 0x537F, 0x8BA8, 0x5382, 0x99CA,
+	0x5384, 0x96EF, 0x5393, 0xFA8D, 0x5396, 0x99CB, 0x5398, 0x97D0,
+	0x539A, 0x8CFA, 0x539F, 0x8CB4, 0x53A0, 0x99CC, 0x53A5, 0x99CE,
+	0x53A6, 0x99CD, 0x53A8, 0x907E, 0x53A9, 0x8958, 0x53AD, 0x897D,
+	0x53AE, 0x99CF, 0x53B0, 0x99D0, 0x53B2, 0xFA8E, 0x53B3, 0x8CB5,
+	0x53B6, 0x99D1, 0x53BB, 0x8B8E, 0x53C2, 0x8E51, 0x53C3, 0x99D2,
+	0x53C8, 0x9694, 0x53C9, 0x8DB3, 0x53CA, 0x8B79, 0x53CB, 0x9746,
+	0x53CC, 0x916F, 0x53CD, 0x94BD, 0x53CE, 0x8EFB, 0x53D4, 0x8F66,
+	0x53D6, 0x8EE6, 0x53D7, 0x8EF3, 0x53D9, 0x8F96, 0x53DB, 0x94BE,
+	0x53DD, 0xFA8F, 0x53DF, 0x99D5, 0x53E1, 0x8962, 0x53E2, 0x9170,
+	0x53E3, 0x8CFB, 0x53E4, 0x8CC3, 0x53E5, 0x8BE5, 0x53E8, 0x99D9,
+	0x53E9, 0x9240, 0x53EA, 0x91FC, 0x53EB, 0x8BA9, 0x53EC, 0x8FA2,
+	0x53ED, 0x99DA, 0x53EE, 0x99D8, 0x53EF, 0x89C2, 0x53F0, 0x91E4,
+	0x53F1, 0x8EB6, 0x53F2, 0x8E6A, 0x53F3, 0x8945, 0x53F6, 0x8A90,
+	0x53F7, 0x8D86, 0x53F8, 0x8E69, 0x53FA, 0x99DB, 0x5401, 0x99DC,
+	0x5403, 0x8B68, 0x5404, 0x8A65, 0x5408, 0x8D87, 0x5409, 0x8B67,
+	0x540A, 0x92DD, 0x540B, 0x8944, 0x540C, 0x93AF, 0x540D, 0x96BC,
+	0x540E, 0x8D40, 0x540F, 0x9799, 0x5410, 0x9366, 0x5411, 0x8CFC,
+	0x541B, 0x8C4E, 0x541D, 0x99E5, 0x541F, 0x8BE1, 0x5420, 0x9669,
+	0x5426, 0x94DB, 0x5429, 0x99E4, 0x542B, 0x8ADC, 0x542C, 0x99DF,
+	0x542D, 0x99E0, 0x542E, 0x99E2, 0x5436, 0x99E3, 0x5438, 0x8B7A,
+	0x5439, 0x9081, 0x543B, 0x95AB, 0x543C, 0x99E1, 0x543D, 0x99DD,
+	0x543E, 0x8CE1, 0x5440, 0x99DE, 0x5442, 0x9843, 0x5446, 0x95F0,
+	0x5448, 0x92E6, 0x5449, 0x8CE0, 0x544A, 0x8D90, 0x544E, 0x99E6,
+	0x5451, 0x93DB, 0x545F, 0x99EA, 0x5468, 0x8EFC, 0x546A, 0x8EF4,
+	0x5470, 0x99ED, 0x5471, 0x99EB, 0x5473, 0x96A1, 0x5475, 0x99E8,
+	0x5476, 0x99F1, 0x5477, 0x99EC, 0x547B, 0x99EF, 0x547C, 0x8CC4,
+	0x547D, 0x96BD, 0x5480, 0x99F0, 0x5484, 0x99F2, 0x5486, 0x99F4,
+	0x548A, 0xFA92, 0x548B, 0x8DEE, 0x548C, 0x9861, 0x548E, 0x99E9,
+	0x548F, 0x99E7, 0x5490, 0x99F3, 0x5492, 0x99EE, 0x549C, 0xFA91,
+	0x54A2, 0x99F6, 0x54A4, 0x9A42, 0x54A5, 0x99F8, 0x54A8, 0x99FC,
+	0x54A9, 0xFA93, 0x54AB, 0x9A40, 0x54AC, 0x99F9, 0x54AF, 0x9A5D,
+	0x54B2, 0x8DE7, 0x54B3, 0x8A50, 0x54B8, 0x99F7, 0x54BC, 0x9A44,
+	0x54BD, 0x88F4, 0x54BE, 0x9A43, 0x54C0, 0x88A3, 0x54C1, 0x9569,
+	0x54C2, 0x9A41, 0x54C4, 0x99FA, 0x54C7, 0x99F5, 0x54C8, 0x99FB,
+	0x54C9, 0x8DC6, 0x54D8, 0x9A45, 0x54E1, 0x88F5, 0x54E2, 0x9A4E,
+	0x54E5, 0x9A46, 0x54E6, 0x9A47, 0x54E8, 0x8FA3, 0x54E9, 0x9689,
+	0x54ED, 0x9A4C, 0x54EE, 0x9A4B, 0x54F2, 0x934E, 0x54FA, 0x9A4D,
+	0x54FD, 0x9A4A, 0x54FF, 0xFA94, 0x5504, 0x8953, 0x5506, 0x8DB4,
+	0x5507, 0x904F, 0x550F, 0x9A48, 0x5510, 0x9382, 0x5514, 0x9A49,
+	0x5516, 0x88A0, 0x552E, 0x9A53, 0x552F, 0x9742, 0x5531, 0x8FA5,
+	0x5533, 0x9A59, 0x5538, 0x9A58, 0x5539, 0x9A4F, 0x553E, 0x91C1,
+	0x5540, 0x9A50, 0x5544, 0x91ED, 0x5545, 0x9A55, 0x5546, 0x8FA4,
+	0x554C, 0x9A52, 0x554F, 0x96E2, 0x5553, 0x8C5B, 0x5556, 0x9A56,
+	0x5557, 0x9A57, 0x555C, 0x9A54, 0x555D, 0x9A5A, 0x5563, 0x9A51,
+	0x557B, 0x9A60, 0x557C, 0x9A65, 0x557E, 0x9A61, 0x5580, 0x9A5C,
+	0x5583, 0x9A66, 0x5584, 0x9150, 0x5586, 0xFA95, 0x5587, 0x9A68,
+	0x5589, 0x8D41, 0x558A, 0x9A5E, 0x558B, 0x929D, 0x5598, 0x9A62,
+	0x5599, 0x9A5B, 0x559A, 0x8AAB, 0x559C, 0x8AEC, 0x559D, 0x8A85,
+	0x559E, 0x9A63, 0x559F, 0x9A5F, 0x55A7, 0x8C96, 0x55A8, 0x9A69,
+	0x55A9, 0x9A67, 0x55AA, 0x9172, 0x55AB, 0x8B69, 0x55AC, 0x8BAA,
+	0x55AE, 0x9A64, 0x55B0, 0x8BF2, 0x55B6, 0x8963, 0x55C4, 0x9A6D,
+	0x55C5, 0x9A6B, 0x55C7, 0x9AA5, 0x55D4, 0x9A70, 0x55DA, 0x9A6A,
+	0x55DC, 0x9A6E, 0x55DF, 0x9A6C, 0x55E3, 0x8E6B, 0x55E4, 0x9A6F,
+	0x55F7, 0x9A72, 0x55F9, 0x9A77, 0x55FD, 0x9A75, 0x55FE, 0x9A74,
+	0x5606, 0x9251, 0x5609, 0x89C3, 0x5614, 0x9A71, 0x5616, 0x9A73,
+	0x5617, 0x8FA6, 0x5618, 0x8952, 0x561B, 0x9A76, 0x5629, 0x89DC,
+	0x562F, 0x9A82, 0x5631, 0x8FFA, 0x5632, 0x9A7D, 0x5634, 0x9A7B,
+	0x5636, 0x9A7C, 0x5638, 0x9A7E, 0x5642, 0x895C, 0x564C, 0x9158,
+	0x564E, 0x9A78, 0x5650, 0x9A79, 0x565B, 0x8A9A, 0x5664, 0x9A81,
+	0x5668, 0x8AED, 0x566A, 0x9A84, 0x566B, 0x9A80, 0x566C, 0x9A83,
+	0x5674, 0x95AC, 0x5678, 0x93D3, 0x567A, 0x94B6, 0x5680, 0x9A86,
+	0x5686, 0x9A85, 0x5687, 0x8A64, 0x568A, 0x9A87, 0x568F, 0x9A8A,
+	0x5694, 0x9A89, 0x56A0, 0x9A88, 0x56A2, 0x9458, 0x56A5, 0x9A8B,
+	0x56AE, 0x9A8C, 0x56B4, 0x9A8E, 0x56B6, 0x9A8D, 0x56BC, 0x9A90,
+	0x56C0, 0x9A93, 0x56C1, 0x9A91, 0x56C2, 0x9A8F, 0x56C3, 0x9A92,
+	0x56C8, 0x9A94, 0x56CE, 0x9A95, 0x56D1, 0x9A96, 0x56D3, 0x9A97,
+	0x56D7, 0x9A98, 0x56D8, 0x9964, 0x56DA, 0x8EFA, 0x56DB, 0x8E6C,
+	0x56DE, 0x89F1, 0x56E0, 0x88F6, 0x56E3, 0x9263, 0x56EE, 0x9A99,
+	0x56F0, 0x8DA2, 0x56F2, 0x88CD, 0x56F3, 0x907D, 0x56F9, 0x9A9A,
+	0x56FA, 0x8CC5, 0x56FD, 0x8D91, 0x56FF, 0x9A9C, 0x5700, 0x9A9B,
+	0x5703, 0x95DE, 0x5704, 0x9A9D, 0x5708, 0x9A9F, 0x5709, 0x9A9E,
+	0x570B, 0x9AA0, 0x570D, 0x9AA1, 0x570F, 0x8C97, 0x5712, 0x8980,
+	0x5713, 0x9AA2, 0x5716, 0x9AA4, 0x5718, 0x9AA3, 0x571C, 0x9AA6,
+	0x571F, 0x9379, 0x5726, 0x9AA7, 0x5727, 0x88B3, 0x5728, 0x8DDD,
+	0x572D, 0x8C5C, 0x5730, 0x926E, 0x5737, 0x9AA8, 0x5738, 0x9AA9,
+	0x573B, 0x9AAB, 0x5740, 0x9AAC, 0x5742, 0x8DE2, 0x5747, 0x8BCF,
+	0x574A, 0x9656, 0x574E, 0x9AAA, 0x574F, 0x9AAD, 0x5750, 0x8DBF,
+	0x5751, 0x8D42, 0x5759, 0xFA96, 0x5761, 0x9AB1, 0x5764, 0x8DA3,
+	0x5765, 0xFA97, 0x5766, 0x9252, 0x5769, 0x9AAE, 0x576A, 0x92D8,
+	0x577F, 0x9AB2, 0x5782, 0x9082, 0x5788, 0x9AB0, 0x5789, 0x9AB3,
+	0x578B, 0x8C5E, 0x5793, 0x9AB4, 0x57A0, 0x9AB5, 0x57A2, 0x8D43,
+	0x57A3, 0x8A5F, 0x57A4, 0x9AB7, 0x57AA, 0x9AB8, 0x57AC, 0xFA98,
+	0x57B0, 0x9AB9, 0x57B3, 0x9AB6, 0x57C0, 0x9AAF, 0x57C3, 0x9ABA,
+	0x57C6, 0x9ABB, 0x57C7, 0xFA9A, 0x57C8, 0xFA99, 0x57CB, 0x9684,
+	0x57CE, 0x8FE9, 0x57D2, 0x9ABD, 0x57D3, 0x9ABE, 0x57D4, 0x9ABC,
+	0x57D6, 0x9AC0, 0x57DC, 0x9457, 0x57DF, 0x88E6, 0x57E0, 0x9575,
+	0x57E3, 0x9AC1, 0x57F4, 0x8FFB, 0x57F7, 0x8EB7, 0x57F9, 0x947C,
+	0x57FA, 0x8AEE, 0x57FC, 0x8DE9, 0x5800, 0x9678, 0x5802, 0x93B0,
+	0x5805, 0x8C98, 0x5806, 0x91CD, 0x580A, 0x9ABF, 0x580B, 0x9AC2,
+	0x5815, 0x91C2, 0x5819, 0x9AC3, 0x581D, 0x9AC4, 0x5821, 0x9AC6,
+	0x5824, 0x92E7, 0x582A, 0x8AAC, 0x582F, 0xEA9F, 0x5830, 0x8981,
+	0x5831, 0x95F1, 0x5834, 0x8FEA, 0x5835, 0x9367, 0x583A, 0x8DE4,
+	0x583D, 0x9ACC, 0x5840, 0x95BB, 0x5841, 0x97DB, 0x584A, 0x89F2,
+	0x584B, 0x9AC8, 0x5851, 0x9159, 0x5852, 0x9ACB, 0x5854, 0x9383,
+	0x5857, 0x9368, 0x5858, 0x9384, 0x5859, 0x94B7, 0x585A, 0x92CB,
+	0x585E, 0x8DC7, 0x5862, 0x9AC7, 0x5869, 0x8996, 0x586B, 0x9355,
+	0x5870, 0x9AC9, 0x5872, 0x9AC5, 0x5875, 0x906F, 0x5879, 0x9ACD,
+	0x587E, 0x8F6D, 0x5883, 0x8BAB, 0x5885, 0x9ACE, 0x5893, 0x95E6,
+	0x5897, 0x919D, 0x589C, 0x92C4, 0x589E, 0xFA9D, 0x589F, 0x9AD0,
+	0x58A8, 0x966E, 0x58AB, 0x9AD1, 0x58AE, 0x9AD6, 0x58B2, 0xFA9E,
+	0x58B3, 0x95AD, 0x58B8, 0x9AD5, 0x58B9, 0x9ACF, 0x58BA, 0x9AD2,
+	0x58BB, 0x9AD4, 0x58BE, 0x8DA4, 0x58C1, 0x95C7, 0x58C5, 0x9AD7,
+	0x58C7, 0x9264, 0x58CA, 0x89F3, 0x58CC, 0x8FEB, 0x58D1, 0x9AD9,
+	0x58D3, 0x9AD8, 0x58D5, 0x8D88, 0x58D7, 0x9ADA, 0x58D8, 0x9ADC,
+	0x58D9, 0x9ADB, 0x58DC, 0x9ADE, 0x58DE, 0x9AD3, 0x58DF, 0x9AE0,
+	0x58E4, 0x9ADF, 0x58E5, 0x9ADD, 0x58EB, 0x8E6D, 0x58EC, 0x9070,
+	0x58EE, 0x9173, 0x58EF, 0x9AE1, 0x58F0, 0x90BA, 0x58F1, 0x88EB,
+	0x58F2, 0x9484, 0x58F7, 0x92D9, 0x58F9, 0x9AE3, 0x58FA, 0x9AE2,
+	0x58FB, 0x9AE4, 0x58FC, 0x9AE5, 0x58FD, 0x9AE6, 0x5902, 0x9AE7,
+	0x5909, 0x95CF, 0x590A, 0x9AE8, 0x590B, 0xFA9F, 0x590F, 0x89C4,
+	0x5910, 0x9AE9, 0x5915, 0x975B, 0x5916, 0x8A4F, 0x5918, 0x99C7,
+	0x5919, 0x8F67, 0x591A, 0x91BD, 0x591B, 0x9AEA, 0x591C, 0x96E9,
+	0x5922, 0x96B2, 0x5925, 0x9AEC, 0x5927, 0x91E5, 0x5929, 0x9356,
+	0x592A, 0x91BE, 0x592B, 0x9576, 0x592C, 0x9AED, 0x592D, 0x9AEE,
+	0x592E, 0x899B, 0x5931, 0x8EB8, 0x5932, 0x9AEF, 0x5937, 0x88CE,
+	0x5938, 0x9AF0, 0x593E, 0x9AF1, 0x5944, 0x8982, 0x5947, 0x8AEF,
+	0x5948, 0x93DE, 0x5949, 0x95F2, 0x594E, 0x9AF5, 0x594F, 0x9174,
+	0x5950, 0x9AF4, 0x5951, 0x8C5F, 0x5953, 0xFAA0, 0x5954, 0x967A,
+	0x5955, 0x9AF3, 0x5957, 0x9385, 0x5958, 0x9AF7, 0x595A, 0x9AF6,
+	0x595B, 0xFAA1, 0x595D, 0xFAA2, 0x5960, 0x9AF9, 0x5962, 0x9AF8,
+	0x5963, 0xFAA3, 0x5965, 0x899C, 0x5967, 0x9AFA, 0x5968, 0x8FA7,
+	0x5969, 0x9AFC, 0x596A, 0x9244, 0x596C, 0x9AFB, 0x596E, 0x95B1,
+	0x5973, 0x8F97, 0x5974, 0x937A, 0x5978, 0x9B40, 0x597D, 0x8D44,
+	0x5981, 0x9B41, 0x5982, 0x9440, 0x5983, 0x94DC, 0x5984, 0x96CF,
+	0x598A, 0x9444, 0x598D, 0x9B4A, 0x5993, 0x8B57, 0x5996, 0x9764,
+	0x5999, 0x96AD, 0x599B, 0x9BAA, 0x599D, 0x9B42, 0x59A3, 0x9B45,
+	0x59A4, 0xFAA4, 0x59A5, 0x91C3, 0x59A8, 0x9657, 0x59AC, 0x9369,
+	0x59B2, 0x9B46, 0x59B9, 0x9685, 0x59BA, 0xFAA5, 0x59BB, 0x8DC8,
+	0x59BE, 0x8FA8, 0x59C6, 0x9B47, 0x59C9, 0x8E6F, 0x59CB, 0x8E6E,
+	0x59D0, 0x88B7, 0x59D1, 0x8CC6, 0x59D3, 0x90A9, 0x59D4, 0x88CF,
+	0x59D9, 0x9B4B, 0x59DA, 0x9B4C, 0x59DC, 0x9B49, 0x59E5, 0x8957,
+	0x59E6, 0x8AAD, 0x59E8, 0x9B48, 0x59EA, 0x96C3, 0x59EB, 0x9550,
+	0x59F6, 0x88A6, 0x59FB, 0x88F7, 0x59FF, 0x8E70, 0x5A01, 0x88D0,
+	0x5A03, 0x88A1, 0x5A09, 0x9B51, 0x5A11, 0x9B4F, 0x5A18, 0x96BA,
+	0x5A1A, 0x9B52, 0x5A1C, 0x9B50, 0x5A1F, 0x9B4E, 0x5A20, 0x9050,
+	0x5A25, 0x9B4D, 0x5A29, 0x95D8, 0x5A2F, 0x8CE2, 0x5A35, 0x9B56,
+	0x5A36, 0x9B57, 0x5A3C, 0x8FA9, 0x5A40, 0x9B53, 0x5A41, 0x984B,
+	0x5A46, 0x946B, 0x5A49, 0x9B55, 0x5A5A, 0x8DA5, 0x5A62, 0x9B58,
+	0x5A66, 0x9577, 0x5A6A, 0x9B59, 0x5A6C, 0x9B54, 0x5A7F, 0x96B9,
+	0x5A92, 0x947D, 0x5A9A, 0x9B5A, 0x5A9B, 0x9551, 0x5ABC, 0x9B5B,
+	0x5ABD, 0x9B5F, 0x5ABE, 0x9B5C, 0x5AC1, 0x89C5, 0x5AC2, 0x9B5E,
+	0x5AC9, 0x8EB9, 0x5ACB, 0x9B5D, 0x5ACC, 0x8C99, 0x5AD0, 0x9B6B,
+	0x5AD6, 0x9B64, 0x5AD7, 0x9B61, 0x5AE1, 0x9284, 0x5AE3, 0x9B60,
+	0x5AE6, 0x9B62, 0x5AE9, 0x9B63, 0x5AFA, 0x9B65, 0x5AFB, 0x9B66,
+	0x5B09, 0x8AF0, 0x5B0B, 0x9B68, 0x5B0C, 0x9B67, 0x5B16, 0x9B69,
+	0x5B22, 0x8FEC, 0x5B2A, 0x9B6C, 0x5B2C, 0x92DA, 0x5B30, 0x8964,
+	0x5B32, 0x9B6A, 0x5B36, 0x9B6D, 0x5B3E, 0x9B6E, 0x5B40, 0x9B71,
+	0x5B43, 0x9B6F, 0x5B45, 0x9B70, 0x5B50, 0x8E71, 0x5B51, 0x9B72,
+	0x5B54, 0x8D45, 0x5B55, 0x9B73, 0x5B56, 0xFAA6, 0x5B57, 0x8E9A,
+	0x5B58, 0x91B6, 0x5B5A, 0x9B74, 0x5B5B, 0x9B75, 0x5B5C, 0x8E79,
+	0x5B5D, 0x8D46, 0x5B5F, 0x96D0, 0x5B63, 0x8B47, 0x5B64, 0x8CC7,
+	0x5B65, 0x9B76, 0x5B66, 0x8A77, 0x5B69, 0x9B77, 0x5B6B, 0x91B7,
+	0x5B70, 0x9B78, 0x5B71, 0x9BA1, 0x5B73, 0x9B79, 0x5B75, 0x9B7A,
+	0x5B78, 0x9B7B, 0x5B7A, 0x9B7D, 0x5B80, 0x9B7E, 0x5B83, 0x9B80,
+	0x5B85, 0x91EE, 0x5B87, 0x8946, 0x5B88, 0x8EE7, 0x5B89, 0x88C0,
+	0x5B8B, 0x9176, 0x5B8C, 0x8AAE, 0x5B8D, 0x8EB3, 0x5B8F, 0x8D47,
+	0x5B95, 0x9386, 0x5B97, 0x8F40, 0x5B98, 0x8AAF, 0x5B99, 0x9288,
+	0x5B9A, 0x92E8, 0x5B9B, 0x88B6, 0x5B9C, 0x8B58, 0x5B9D, 0x95F3,
+	0x5B9F, 0x8EC0, 0x5BA2, 0x8B71, 0x5BA3, 0x90E9, 0x5BA4, 0x8EBA,
+	0x5BA5, 0x9747, 0x5BA6, 0x9B81, 0x5BAE, 0x8B7B, 0x5BB0, 0x8DC9,
+	0x5BB3, 0x8A51, 0x5BB4, 0x8983, 0x5BB5, 0x8FAA, 0x5BB6, 0x89C6,
+	0x5BB8, 0x9B82, 0x5BB9, 0x9765, 0x5BBF, 0x8F68, 0x5BC0, 0xFAA7,
+	0x5BC2, 0x8EE2, 0x5BC3, 0x9B83, 0x5BC4, 0x8AF1, 0x5BC5, 0x93D0,
+	0x5BC6, 0x96A7, 0x5BC7, 0x9B84, 0x5BC9, 0x9B85, 0x5BCC, 0x9578,
+	0x5BD0, 0x9B87, 0x5BD2, 0x8AA6, 0x5BD3, 0x8BF5, 0x5BD4, 0x9B86,
+	0x5BD8, 0xFAA9, 0x5BDB, 0x8AB0, 0x5BDD, 0x9051, 0x5BDE, 0x9B8B,
+	0x5BDF, 0x8E40, 0x5BE1, 0x89C7, 0x5BE2, 0x9B8A, 0x5BE4, 0x9B88,
+	0x5BE5, 0x9B8C, 0x5BE6, 0x9B89, 0x5BE7, 0x944A, 0x5BE8, 0x9ECB,
+	0x5BE9, 0x9052, 0x5BEB, 0x9B8D, 0x5BEC, 0xFAAA, 0x5BEE, 0x97BE,
+	0x5BF0, 0x9B8E, 0x5BF3, 0x9B90, 0x5BF5, 0x929E, 0x5BF6, 0x9B8F,
+	0x5BF8, 0x90A1, 0x5BFA, 0x8E9B, 0x5BFE, 0x91CE, 0x5BFF, 0x8EF5,
+	0x5C01, 0x9595, 0x5C02, 0x90EA, 0x5C04, 0x8ECB, 0x5C05, 0x9B91,
+	0x5C06, 0x8FAB, 0x5C07, 0x9B92, 0x5C08, 0x9B93, 0x5C09, 0x88D1,
+	0x5C0A, 0x91B8, 0x5C0B, 0x9071, 0x5C0D, 0x9B94, 0x5C0E, 0x93B1,
+	0x5C0F, 0x8FAC, 0x5C11, 0x8FAD, 0x5C13, 0x9B95, 0x5C16, 0x90EB,
+	0x5C1A, 0x8FAE, 0x5C1E, 0xFAAB, 0x5C20, 0x9B96, 0x5C22, 0x9B97,
+	0x5C24, 0x96DE, 0x5C28, 0x9B98, 0x5C2D, 0x8BC4, 0x5C31, 0x8F41,
+	0x5C38, 0x9B99, 0x5C39, 0x9B9A, 0x5C3A, 0x8EDA, 0x5C3B, 0x904B,
+	0x5C3C, 0x93F2, 0x5C3D, 0x9073, 0x5C3E, 0x94F6, 0x5C3F, 0x9441,
+	0x5C40, 0x8BC7, 0x5C41, 0x9B9B, 0x5C45, 0x8B8F, 0x5C46, 0x9B9C,
+	0x5C48, 0x8BFC, 0x5C4A, 0x93CD, 0x5C4B, 0x89AE, 0x5C4D, 0x8E72,
+	0x5C4E, 0x9B9D, 0x5C4F, 0x9BA0, 0x5C50, 0x9B9F, 0x5C51, 0x8BFB,
+	0x5C53, 0x9B9E, 0x5C55, 0x9357, 0x5C5E, 0x91AE, 0x5C60, 0x936A,
+	0x5C61, 0x8EC6, 0x5C64, 0x9177, 0x5C65, 0x979A, 0x5C6C, 0x9BA2,
+	0x5C6E, 0x9BA3, 0x5C6F, 0x93D4, 0x5C71, 0x8E52, 0x5C76, 0x9BA5,
+	0x5C79, 0x9BA6, 0x5C8C, 0x9BA7, 0x5C90, 0x8AF2, 0x5C91, 0x9BA8,
+	0x5C94, 0x9BA9, 0x5CA1, 0x89AA, 0x5CA6, 0xFAAC, 0x5CA8, 0x915A,
+	0x5CA9, 0x8AE2, 0x5CAB, 0x9BAB, 0x5CAC, 0x96A6, 0x5CB1, 0x91D0,
+	0x5CB3, 0x8A78, 0x5CB6, 0x9BAD, 0x5CB7, 0x9BAF, 0x5CB8, 0x8ADD,
+	0x5CBA, 0xFAAD, 0x5CBB, 0x9BAC, 0x5CBC, 0x9BAE, 0x5CBE, 0x9BB1,
+	0x5CC5, 0x9BB0, 0x5CC7, 0x9BB2, 0x5CD9, 0x9BB3, 0x5CE0, 0x93BB,
+	0x5CE1, 0x8BAC, 0x5CE8, 0x89E3, 0x5CE9, 0x9BB4, 0x5CEA, 0x9BB9,
+	0x5CED, 0x9BB7, 0x5CEF, 0x95F5, 0x5CF0, 0x95F4, 0x5CF5, 0xFAAE,
+	0x5CF6, 0x9387, 0x5CFA, 0x9BB6, 0x5CFB, 0x8F73, 0x5CFD, 0x9BB5,
+	0x5D07, 0x9092, 0x5D0B, 0x9BBA, 0x5D0E, 0x8DE8, 0x5D11, 0x9BC0,
+	0x5D14, 0x9BC1, 0x5D15, 0x9BBB, 0x5D16, 0x8A52, 0x5D17, 0x9BBC,
+	0x5D18, 0x9BC5, 0x5D19, 0x9BC4, 0x5D1A, 0x9BC3, 0x5D1B, 0x9BBF,
+	0x5D1F, 0x9BBE, 0x5D22, 0x9BC2, 0x5D27, 0xFAAF, 0x5D29, 0x95F6,
+	0x5D42, 0xFAB2, 0x5D4B, 0x9BC9, 0x5D4C, 0x9BC6, 0x5D4E, 0x9BC8,
+	0x5D50, 0x9792, 0x5D52, 0x9BC7, 0x5D53, 0xFAB0, 0x5D5C, 0x9BBD,
+	0x5D69, 0x9093, 0x5D6C, 0x9BCA, 0x5D6D, 0xFAB3, 0x5D6F, 0x8DB5,
+	0x5D73, 0x9BCB, 0x5D76, 0x9BCC, 0x5D82, 0x9BCF, 0x5D84, 0x9BCE,
+	0x5D87, 0x9BCD, 0x5D8B, 0x9388, 0x5D8C, 0x9BB8, 0x5D90, 0x9BD5,
+	0x5D9D, 0x9BD1, 0x5DA2, 0x9BD0, 0x5DAC, 0x9BD2, 0x5DAE, 0x9BD3,
+	0x5DB7, 0x9BD6, 0x5DB8, 0xFAB4, 0x5DB9, 0xFAB5, 0x5DBA, 0x97E4,
+	0x5DBC, 0x9BD7, 0x5DBD, 0x9BD4, 0x5DC9, 0x9BD8, 0x5DCC, 0x8ADE,
+	0x5DCD, 0x9BD9, 0x5DD0, 0xFAB6, 0x5DD2, 0x9BDB, 0x5DD3, 0x9BDA,
+	0x5DD6, 0x9BDC, 0x5DDB, 0x9BDD, 0x5DDD, 0x90EC, 0x5DDE, 0x8F42,
+	0x5DE1, 0x8F84, 0x5DE3, 0x9183, 0x5DE5, 0x8D48, 0x5DE6, 0x8DB6,
+	0x5DE7, 0x8D49, 0x5DE8, 0x8B90, 0x5DEB, 0x9BDE, 0x5DEE, 0x8DB7,
+	0x5DF1, 0x8CC8, 0x5DF2, 0x9BDF, 0x5DF3, 0x96A4, 0x5DF4, 0x9462,
+	0x5DF5, 0x9BE0, 0x5DF7, 0x8D4A, 0x5DFB, 0x8AAA, 0x5DFD, 0x9246,
+	0x5DFE, 0x8BD0, 0x5E02, 0x8E73, 0x5E03, 0x957A, 0x5E06, 0x94BF,
+	0x5E0B, 0x9BE1, 0x5E0C, 0x8AF3, 0x5E11, 0x9BE4, 0x5E16, 0x929F,
+	0x5E19, 0x9BE3, 0x5E1A, 0x9BE2, 0x5E1B, 0x9BE5, 0x5E1D, 0x92E9,
+	0x5E25, 0x9083, 0x5E2B, 0x8E74, 0x5E2D, 0x90C8, 0x5E2F, 0x91D1,
+	0x5E30, 0x8B41, 0x5E33, 0x92A0, 0x5E36, 0x9BE6, 0x5E37, 0x9BE7,
+	0x5E38, 0x8FED, 0x5E3D, 0x9658, 0x5E40, 0x9BEA, 0x5E43, 0x9BE9,
+	0x5E44, 0x9BE8, 0x5E45, 0x959D, 0x5E47, 0x9BF1, 0x5E4C, 0x9679,
+	0x5E4E, 0x9BEB, 0x5E54, 0x9BED, 0x5E55, 0x968B, 0x5E57, 0x9BEC,
+	0x5E5F, 0x9BEE, 0x5E61, 0x94A6, 0x5E62, 0x9BEF, 0x5E63, 0x95BC,
+	0x5E64, 0x9BF0, 0x5E72, 0x8AB1, 0x5E73, 0x95BD, 0x5E74, 0x944E,
+	0x5E75, 0x9BF2, 0x5E76, 0x9BF3, 0x5E78, 0x8D4B, 0x5E79, 0x8AB2,
+	0x5E7A, 0x9BF4, 0x5E7B, 0x8CB6, 0x5E7C, 0x9763, 0x5E7D, 0x9748,
+	0x5E7E, 0x8AF4, 0x5E7F, 0x9BF6, 0x5E81, 0x92A1, 0x5E83, 0x8D4C,
+	0x5E84, 0x8FAF, 0x5E87, 0x94DD, 0x5E8A, 0x8FB0, 0x5E8F, 0x8F98,
+	0x5E95, 0x92EA, 0x5E96, 0x95F7, 0x5E97, 0x9358, 0x5E9A, 0x8D4D,
+	0x5E9C, 0x957B, 0x5EA0, 0x9BF7, 0x5EA6, 0x9378, 0x5EA7, 0x8DC0,
+	0x5EAB, 0x8CC9, 0x5EAD, 0x92EB, 0x5EB5, 0x88C1, 0x5EB6, 0x8F8E,
+	0x5EB7, 0x8D4E, 0x5EB8, 0x9766, 0x5EC1, 0x9BF8, 0x5EC2, 0x9BF9,
+	0x5EC3, 0x9470, 0x5EC8, 0x9BFA, 0x5EC9, 0x97F5, 0x5ECA, 0x984C,
+	0x5ECF, 0x9BFC, 0x5ED0, 0x9BFB, 0x5ED3, 0x8A66, 0x5ED6, 0x9C40,
+	0x5EDA, 0x9C43, 0x5EDB, 0x9C44, 0x5EDD, 0x9C42, 0x5EDF, 0x955F,
+	0x5EE0, 0x8FB1, 0x5EE1, 0x9C46, 0x5EE2, 0x9C45, 0x5EE3, 0x9C41,
+	0x5EE8, 0x9C47, 0x5EE9, 0x9C48, 0x5EEC, 0x9C49, 0x5EF0, 0x9C4C,
+	0x5EF1, 0x9C4A, 0x5EF3, 0x9C4B, 0x5EF4, 0x9C4D, 0x5EF6, 0x8984,
+	0x5EF7, 0x92EC, 0x5EF8, 0x9C4E, 0x5EFA, 0x8C9A, 0x5EFB, 0x89F4,
+	0x5EFC, 0x9455, 0x5EFE, 0x9C4F, 0x5EFF, 0x93F9, 0x5F01, 0x95D9,
+	0x5F03, 0x9C50, 0x5F04, 0x984D, 0x5F09, 0x9C51, 0x5F0A, 0x95BE,
+	0x5F0B, 0x9C54, 0x5F0C, 0x989F, 0x5F0D, 0x98AF, 0x5F0F, 0x8EAE,
+	0x5F10, 0x93F3, 0x5F11, 0x9C55, 0x5F13, 0x8B7C, 0x5F14, 0x92A2,
+	0x5F15, 0x88F8, 0x5F16, 0x9C56, 0x5F17, 0x95A4, 0x5F18, 0x8D4F,
+	0x5F1B, 0x926F, 0x5F1F, 0x92ED, 0x5F21, 0xFAB7, 0x5F25, 0x96ED,
+	0x5F26, 0x8CB7, 0x5F27, 0x8CCA, 0x5F29, 0x9C57, 0x5F2D, 0x9C58,
+	0x5F2F, 0x9C5E, 0x5F31, 0x8EE3, 0x5F34, 0xFAB8, 0x5F35, 0x92A3,
+	0x5F37, 0x8BAD, 0x5F38, 0x9C59, 0x5F3C, 0x954A, 0x5F3E, 0x9265,
+	0x5F41, 0x9C5A, 0x5F45, 0xFA67, 0x5F48, 0x9C5B, 0x5F4A, 0x8BAE,
+	0x5F4C, 0x9C5C, 0x5F4E, 0x9C5D, 0x5F51, 0x9C5F, 0x5F53, 0x9396,
+	0x5F56, 0x9C60, 0x5F57, 0x9C61, 0x5F59, 0x9C62, 0x5F5C, 0x9C53,
+	0x5F5D, 0x9C52, 0x5F61, 0x9C63, 0x5F62, 0x8C60, 0x5F66, 0x9546,
+	0x5F67, 0xFAB9, 0x5F69, 0x8DCA, 0x5F6A, 0x9556, 0x5F6B, 0x92A4,
+	0x5F6C, 0x956A, 0x5F6D, 0x9C64, 0x5F70, 0x8FB2, 0x5F71, 0x8965,
+	0x5F73, 0x9C65, 0x5F77, 0x9C66, 0x5F79, 0x96F0, 0x5F7C, 0x94DE,
+	0x5F7F, 0x9C69, 0x5F80, 0x899D, 0x5F81, 0x90AA, 0x5F82, 0x9C68,
+	0x5F83, 0x9C67, 0x5F84, 0x8C61, 0x5F85, 0x91D2, 0x5F87, 0x9C6D,
+	0x5F88, 0x9C6B, 0x5F8A, 0x9C6A, 0x5F8B, 0x97A5, 0x5F8C, 0x8CE3,
+	0x5F90, 0x8F99, 0x5F91, 0x9C6C, 0x5F92, 0x936B, 0x5F93, 0x8F5D,
+	0x5F97, 0x93BE, 0x5F98, 0x9C70, 0x5F99, 0x9C6F, 0x5F9E, 0x9C6E,
+	0x5FA0, 0x9C71, 0x5FA1, 0x8CE4, 0x5FA8, 0x9C72, 0x5FA9, 0x959C,
+	0x5FAA, 0x8F7A, 0x5FAD, 0x9C73, 0x5FAE, 0x94F7, 0x5FB3, 0x93BF,
+	0x5FB4, 0x92A5, 0x5FB7, 0xFABA, 0x5FB9, 0x934F, 0x5FBC, 0x9C74,
+	0x5FBD, 0x8B4A, 0x5FC3, 0x9053, 0x5FC5, 0x954B, 0x5FCC, 0x8AF5,
+	0x5FCD, 0x9445, 0x5FD6, 0x9C75, 0x5FD7, 0x8E75, 0x5FD8, 0x9659,
+	0x5FD9, 0x965A, 0x5FDC, 0x899E, 0x5FDD, 0x9C7A, 0x5FDE, 0xFABB,
+	0x5FE0, 0x9289, 0x5FE4, 0x9C77, 0x5FEB, 0x89F5, 0x5FF0, 0x9CAB,
+	0x5FF1, 0x9C79, 0x5FF5, 0x944F, 0x5FF8, 0x9C78, 0x5FFB, 0x9C76,
+	0x5FFD, 0x8D9A, 0x5FFF, 0x9C7C, 0x600E, 0x9C83, 0x600F, 0x9C89,
+	0x6010, 0x9C81, 0x6012, 0x937B, 0x6015, 0x9C86, 0x6016, 0x957C,
+	0x6019, 0x9C80, 0x601B, 0x9C85, 0x601C, 0x97E5, 0x601D, 0x8E76,
+	0x6020, 0x91D3, 0x6021, 0x9C7D, 0x6025, 0x8B7D, 0x6026, 0x9C88,
+	0x6027, 0x90AB, 0x6028, 0x8985, 0x6029, 0x9C82, 0x602A, 0x89F6,
+	0x602B, 0x9C87, 0x602F, 0x8BAF, 0x6031, 0x9C84, 0x603A, 0x9C8A,
+	0x6041, 0x9C8C, 0x6042, 0x9C96, 0x6043, 0x9C94, 0x6046, 0x9C91,
+	0x604A, 0x9C90, 0x604B, 0x97F6, 0x604D, 0x9C92, 0x6050, 0x8BB0,
+	0x6052, 0x8D50, 0x6055, 0x8F9A, 0x6059, 0x9C99, 0x605A, 0x9C8B,
+	0x605D, 0xFABC, 0x605F, 0x9C8F, 0x6060, 0x9C7E, 0x6062, 0x89F8,
+	0x6063, 0x9C93, 0x6064, 0x9C95, 0x6065, 0x9270, 0x6068, 0x8DA6,
+	0x6069, 0x89B6, 0x606A, 0x9C8D, 0x606B, 0x9C98, 0x606C, 0x9C97,
+	0x606D, 0x8BB1, 0x606F, 0x91A7, 0x6070, 0x8A86, 0x6075, 0x8C62,
+	0x6077, 0x9C8E, 0x6081, 0x9C9A, 0x6083, 0x9C9D, 0x6084, 0x9C9F,
+	0x6085, 0xFABD, 0x6089, 0x8EBB, 0x608A, 0xFABE, 0x608B, 0x9CA5,
+	0x608C, 0x92EE, 0x608D, 0x9C9B, 0x6092, 0x9CA3, 0x6094, 0x89F7,
+	0x6096, 0x9CA1, 0x6097, 0x9CA2, 0x609A, 0x9C9E, 0x609B, 0x9CA0,
+	0x609F, 0x8CE5, 0x60A0, 0x9749, 0x60A3, 0x8AB3, 0x60A6, 0x8978,
+	0x60A7, 0x9CA4, 0x60A9, 0x9459, 0x60AA, 0x88AB, 0x60B2, 0x94DF,
+	0x60B3, 0x9C7B, 0x60B4, 0x9CAA, 0x60B5, 0x9CAE, 0x60B6, 0x96E3,
+	0x60B8, 0x9CA7, 0x60BC, 0x9389, 0x60BD, 0x9CAC, 0x60C5, 0x8FEE,
+	0x60C6, 0x9CAD, 0x60C7, 0x93D5, 0x60D1, 0x9866, 0x60D3, 0x9CA9,
+	0x60D5, 0xFAC0, 0x60D8, 0x9CAF, 0x60DA, 0x8D9B, 0x60DC, 0x90C9,
+	0x60DE, 0xFABF, 0x60DF, 0x88D2, 0x60E0, 0x9CA8, 0x60E1, 0x9CA6,
+	0x60E3, 0x9179, 0x60E7, 0x9C9C, 0x60E8, 0x8E53, 0x60F0, 0x91C4,
+	0x60F1, 0x9CBB, 0x60F2, 0xFAC2, 0x60F3, 0x917A, 0x60F4, 0x9CB6,
+	0x60F6, 0x9CB3, 0x60F7, 0x9CB4, 0x60F9, 0x8EE4, 0x60FA, 0x9CB7,
+	0x60FB, 0x9CBA, 0x6100, 0x9CB5, 0x6101, 0x8F44, 0x6103, 0x9CB8,
+	0x6106, 0x9CB2, 0x6108, 0x96FA, 0x6109, 0x96F9, 0x610D, 0x9CBC,
+	0x610E, 0x9CBD, 0x610F, 0x88D3, 0x6111, 0xFAC3, 0x6115, 0x9CB1,
+	0x611A, 0x8BF0, 0x611B, 0x88A4, 0x611F, 0x8AB4, 0x6120, 0xFAC1,
+	0x6121, 0x9CB9, 0x6127, 0x9CC1, 0x6128, 0x9CC0, 0x612C, 0x9CC5,
+	0x6130, 0xFAC5, 0x6134, 0x9CC6, 0x6137, 0xFAC4, 0x613C, 0x9CC4,
+	0x613D, 0x9CC7, 0x613E, 0x9CBF, 0x613F, 0x9CC3, 0x6142, 0x9CC8,
+	0x6144, 0x9CC9, 0x6147, 0x9CBE, 0x6148, 0x8E9C, 0x614A, 0x9CC2,
+	0x614B, 0x91D4, 0x614C, 0x8D51, 0x614D, 0x9CB0, 0x614E, 0x9054,
+	0x6153, 0x9CD6, 0x6155, 0x95E7, 0x6158, 0x9CCC, 0x6159, 0x9CCD,
+	0x615A, 0x9CCE, 0x615D, 0x9CD5, 0x615F, 0x9CD4, 0x6162, 0x969D,
+	0x6163, 0x8AB5, 0x6165, 0x9CD2, 0x6167, 0x8C64, 0x6168, 0x8A53,
+	0x616B, 0x9CCF, 0x616E, 0x97B6, 0x616F, 0x9CD1, 0x6170, 0x88D4,
+	0x6171, 0x9CD3, 0x6173, 0x9CCA, 0x6174, 0x9CD0, 0x6175, 0x9CD7,
+	0x6176, 0x8C63, 0x6177, 0x9CCB, 0x617E, 0x977C, 0x6182, 0x974A,
+	0x6187, 0x9CDA, 0x618A, 0x9CDE, 0x618E, 0x919E, 0x6190, 0x97F7,
+	0x6191, 0x9CDF, 0x6194, 0x9CDC, 0x6196, 0x9CD9, 0x6198, 0xFAC6,
+	0x6199, 0x9CD8, 0x619A, 0x9CDD, 0x61A4, 0x95AE, 0x61A7, 0x93B2,
+	0x61A9, 0x8C65, 0x61AB, 0x9CE0, 0x61AC, 0x9CDB, 0x61AE, 0x9CE1,
+	0x61B2, 0x8C9B, 0x61B6, 0x89AF, 0x61BA, 0x9CE9, 0x61BE, 0x8AB6,
+	0x61C3, 0x9CE7, 0x61C6, 0x9CE8, 0x61C7, 0x8DA7, 0x61C8, 0x9CE6,
+	0x61C9, 0x9CE4, 0x61CA, 0x9CE3, 0x61CB, 0x9CEA, 0x61CC, 0x9CE2,
+	0x61CD, 0x9CEC, 0x61D0, 0x89F9, 0x61E3, 0x9CEE, 0x61E6, 0x9CED,
+	0x61F2, 0x92A6, 0x61F4, 0x9CF1, 0x61F6, 0x9CEF, 0x61F7, 0x9CE5,
+	0x61F8, 0x8C9C, 0x61FA, 0x9CF0, 0x61FC, 0x9CF4, 0x61FD, 0x9CF3,
+	0x61FE, 0x9CF5, 0x61FF, 0x9CF2, 0x6200, 0x9CF6, 0x6208, 0x9CF7,
+	0x6209, 0x9CF8, 0x620A, 0x95E8, 0x620C, 0x9CFA, 0x620D, 0x9CF9,
+	0x620E, 0x8F5E, 0x6210, 0x90AC, 0x6211, 0x89E4, 0x6212, 0x89FA,
+	0x6213, 0xFAC7, 0x6214, 0x9CFB, 0x6216, 0x88BD, 0x621A, 0x90CA,
+	0x621B, 0x9CFC, 0x621D, 0xE6C1, 0x621E, 0x9D40, 0x621F, 0x8C81,
+	0x6221, 0x9D41, 0x6226, 0x90ED, 0x622A, 0x9D42, 0x622E, 0x9D43,
+	0x622F, 0x8B59, 0x6230, 0x9D44, 0x6232, 0x9D45, 0x6233, 0x9D46,
+	0x6234, 0x91D5, 0x6238, 0x8CCB, 0x623B, 0x96DF, 0x623F, 0x965B,
+	0x6240, 0x8F8A, 0x6241, 0x9D47, 0x6247, 0x90EE, 0x6248, 0xE7BB,
+	0x6249, 0x94E0, 0x624B, 0x8EE8, 0x624D, 0x8DCB, 0x624E, 0x9D48,
+	0x6253, 0x91C5, 0x6255, 0x95A5, 0x6258, 0x91EF, 0x625B, 0x9D4B,
+	0x625E, 0x9D49, 0x6260, 0x9D4C, 0x6263, 0x9D4A, 0x6268, 0x9D4D,
+	0x626E, 0x95AF, 0x6271, 0x88B5, 0x6276, 0x957D, 0x6279, 0x94E1,
+	0x627C, 0x9D4E, 0x627E, 0x9D51, 0x627F, 0x8FB3, 0x6280, 0x8B5A,
+	0x6282, 0x9D4F, 0x6283, 0x9D56, 0x6284, 0x8FB4, 0x6289, 0x9D50,
+	0x628A, 0x9463, 0x6291, 0x977D, 0x6292, 0x9D52, 0x6293, 0x9D53,
+	0x6294, 0x9D57, 0x6295, 0x938A, 0x6296, 0x9D54, 0x6297, 0x8D52,
+	0x6298, 0x90DC, 0x629B, 0x9D65, 0x629C, 0x94B2, 0x629E, 0x91F0,
+	0x62A6, 0xFAC8, 0x62AB, 0x94E2, 0x62AC, 0x9DAB, 0x62B1, 0x95F8,
+	0x62B5, 0x92EF, 0x62B9, 0x9695, 0x62BB, 0x9D5A, 0x62BC, 0x899F,
+	0x62BD, 0x928A, 0x62C2, 0x9D63, 0x62C5, 0x9253, 0x62C6, 0x9D5D,
+	0x62C7, 0x9D64, 0x62C8, 0x9D5F, 0x62C9, 0x9D66, 0x62CA, 0x9D62,
+	0x62CC, 0x9D61, 0x62CD, 0x948F, 0x62CF, 0x9D5B, 0x62D0, 0x89FB,
+	0x62D1, 0x9D59, 0x62D2, 0x8B91, 0x62D3, 0x91F1, 0x62D4, 0x9D55,
+	0x62D7, 0x9D58, 0x62D8, 0x8D53, 0x62D9, 0x90D9, 0x62DB, 0x8FB5,
+	0x62DC, 0x9D60, 0x62DD, 0x9471, 0x62E0, 0x8B92, 0x62E1, 0x8A67,
+	0x62EC, 0x8A87, 0x62ED, 0x9040, 0x62EE, 0x9D68, 0x62EF, 0x9D6D,
+	0x62F1, 0x9D69, 0x62F3, 0x8C9D, 0x62F5, 0x9D6E, 0x62F6, 0x8E41,
+	0x62F7, 0x8D89, 0x62FE, 0x8F45, 0x62FF, 0x9D5C, 0x6301, 0x8E9D,
+	0x6302, 0x9D6B, 0x6307, 0x8E77, 0x6308, 0x9D6C, 0x6309, 0x88C2,
+	0x630C, 0x9D67, 0x6311, 0x92A7, 0x6319, 0x8B93, 0x631F, 0x8BB2,
+	0x6327, 0x9D6A, 0x6328, 0x88A5, 0x632B, 0x8DC1, 0x632F, 0x9055,
+	0x633A, 0x92F0, 0x633D, 0x94D2, 0x633E, 0x9D70, 0x633F, 0x917D,
+	0x6349, 0x91A8, 0x634C, 0x8E4A, 0x634D, 0x9D71, 0x634F, 0x9D73,
+	0x6350, 0x9D6F, 0x6355, 0x95DF, 0x6357, 0x92BB, 0x635C, 0x917B,
+	0x6367, 0x95F9, 0x6368, 0x8ECC, 0x6369, 0x9D80, 0x636B, 0x9D7E,
+	0x636E, 0x9098, 0x6372, 0x8C9E, 0x6376, 0x9D78, 0x6377, 0x8FB7,
+	0x637A, 0x93E6, 0x637B, 0x9450, 0x6380, 0x9D76, 0x6383, 0x917C,
+	0x6388, 0x8EF6, 0x6389, 0x9D7B, 0x638C, 0x8FB6, 0x638E, 0x9D75,
+	0x638F, 0x9D7A, 0x6392, 0x9472, 0x6396, 0x9D74, 0x6398, 0x8C40,
+	0x639B, 0x8A7C, 0x639F, 0x9D7C, 0x63A0, 0x97A9, 0x63A1, 0x8DCC,
+	0x63A2, 0x9254, 0x63A3, 0x9D79, 0x63A5, 0x90DA, 0x63A7, 0x8D54,
+	0x63A8, 0x9084, 0x63A9, 0x8986, 0x63AA, 0x915B, 0x63AB, 0x9D77,
+	0x63AC, 0x8B64, 0x63B2, 0x8C66, 0x63B4, 0x92CD, 0x63B5, 0x9D7D,
+	0x63BB, 0x917E, 0x63BE, 0x9D81, 0x63C0, 0x9D83, 0x63C3, 0x91B5,
+	0x63C4, 0x9D89, 0x63C6, 0x9D84, 0x63C9, 0x9D86, 0x63CF, 0x9560,
+	0x63D0, 0x92F1, 0x63D2, 0x9D87, 0x63D6, 0x974B, 0x63DA, 0x9767,
+	0x63DB, 0x8AB7, 0x63E1, 0x88AC, 0x63E3, 0x9D85, 0x63E9, 0x9D82,
+	0x63EE, 0x8AF6, 0x63F4, 0x8987, 0x63F5, 0xFAC9, 0x63F6, 0x9D88,
+	0x63FA, 0x9768, 0x6406, 0x9D8C, 0x640D, 0x91B9, 0x640F, 0x9D93,
+	0x6413, 0x9D8D, 0x6416, 0x9D8A, 0x6417, 0x9D91, 0x641C, 0x9D72,
+	0x6426, 0x9D8E, 0x6428, 0x9D92, 0x642C, 0x94C0, 0x642D, 0x938B,
+	0x6434, 0x9D8B, 0x6436, 0x9D8F, 0x643A, 0x8C67, 0x643E, 0x8DEF,
+	0x6442, 0x90DB, 0x644E, 0x9D97, 0x6458, 0x9345, 0x6460, 0xFACA,
+	0x6467, 0x9D94, 0x6469, 0x9680, 0x646F, 0x9D95, 0x6476, 0x9D96,
+	0x6478, 0x96CC, 0x647A, 0x90A0, 0x6483, 0x8C82, 0x6488, 0x9D9D,
+	0x6492, 0x8E54, 0x6493, 0x9D9A, 0x6495, 0x9D99, 0x649A, 0x9451,
+	0x649D, 0xFACB, 0x649E, 0x93B3, 0x64A4, 0x9350, 0x64A5, 0x9D9B,
+	0x64A9, 0x9D9C, 0x64AB, 0x958F, 0x64AD, 0x9464, 0x64AE, 0x8E42,
+	0x64B0, 0x90EF, 0x64B2, 0x966F, 0x64B9, 0x8A68, 0x64BB, 0x9DA3,
+	0x64BC, 0x9D9E, 0x64C1, 0x9769, 0x64C2, 0x9DA5, 0x64C5, 0x9DA1,
+	0x64C7, 0x9DA2, 0x64CD, 0x9180, 0x64CE, 0xFACC, 0x64D2, 0x9DA0,
+	0x64D4, 0x9D5E, 0x64D8, 0x9DA4, 0x64DA, 0x9D9F, 0x64E0, 0x9DA9,
+	0x64E1, 0x9DAA, 0x64E2, 0x9346, 0x64E3, 0x9DAC, 0x64E6, 0x8E43,
+	0x64E7, 0x9DA7, 0x64EC, 0x8B5B, 0x64EF, 0x9DAD, 0x64F1, 0x9DA6,
+	0x64F2, 0x9DB1, 0x64F4, 0x9DB0, 0x64F6, 0x9DAF, 0x64FA, 0x9DB2,
+	0x64FD, 0x9DB4, 0x64FE, 0x8FEF, 0x6500, 0x9DB3, 0x6505, 0x9DB7,
+	0x6518, 0x9DB5, 0x651C, 0x9DB6, 0x651D, 0x9D90, 0x6523, 0x9DB9,
+	0x6524, 0x9DB8, 0x652A, 0x9D98, 0x652B, 0x9DBA, 0x652C, 0x9DAE,
+	0x652F, 0x8E78, 0x6534, 0x9DBB, 0x6535, 0x9DBC, 0x6536, 0x9DBE,
+	0x6537, 0x9DBD, 0x6538, 0x9DBF, 0x6539, 0x89FC, 0x653B, 0x8D55,
+	0x653E, 0x95FA, 0x653F, 0x90AD, 0x6545, 0x8CCC, 0x6548, 0x9DC1,
+	0x654D, 0x9DC4, 0x654E, 0xFACD, 0x654F, 0x9571, 0x6551, 0x8B7E,
+	0x6555, 0x9DC3, 0x6556, 0x9DC2, 0x6557, 0x9473, 0x6558, 0x9DC5,
+	0x6559, 0x8BB3, 0x655D, 0x9DC7, 0x655E, 0x9DC6, 0x6562, 0x8AB8,
+	0x6563, 0x8E55, 0x6566, 0x93D6, 0x656C, 0x8C68, 0x6570, 0x9094,
+	0x6572, 0x9DC8, 0x6574, 0x90AE, 0x6575, 0x9347, 0x6577, 0x957E,
+	0x6578, 0x9DC9, 0x6582, 0x9DCA, 0x6583, 0x9DCB, 0x6587, 0x95B6,
+	0x6588, 0x9B7C, 0x6589, 0x90C4, 0x658C, 0x956B, 0x658E, 0x8DD6,
+	0x6590, 0x94E3, 0x6591, 0x94C1, 0x6597, 0x936C, 0x6599, 0x97BF,
+	0x659B, 0x9DCD, 0x659C, 0x8ECE, 0x659F, 0x9DCE, 0x65A1, 0x88B4,
+	0x65A4, 0x8BD2, 0x65A5, 0x90CB, 0x65A7, 0x9580, 0x65AB, 0x9DCF,
+	0x65AC, 0x8E61, 0x65AD, 0x9266, 0x65AF, 0x8E7A, 0x65B0, 0x9056,
+	0x65B7, 0x9DD0, 0x65B9, 0x95FB, 0x65BC, 0x8997, 0x65BD, 0x8E7B,
+	0x65C1, 0x9DD3, 0x65C3, 0x9DD1, 0x65C4, 0x9DD4, 0x65C5, 0x97B7,
+	0x65C6, 0x9DD2, 0x65CB, 0x90F9, 0x65CC, 0x9DD5, 0x65CF, 0x91B0,
+	0x65D2, 0x9DD6, 0x65D7, 0x8AF8, 0x65D9, 0x9DD8, 0x65DB, 0x9DD7,
+	0x65E0, 0x9DD9, 0x65E1, 0x9DDA, 0x65E2, 0x8AF9, 0x65E5, 0x93FA,
+	0x65E6, 0x9255, 0x65E7, 0x8B8C, 0x65E8, 0x8E7C, 0x65E9, 0x9181,
+	0x65EC, 0x8F7B, 0x65ED, 0x88AE, 0x65F1, 0x9DDB, 0x65FA, 0x89A0,
+	0x65FB, 0x9DDF, 0x6600, 0xFACE, 0x6602, 0x8D56, 0x6603, 0x9DDE,
+	0x6606, 0x8DA9, 0x6607, 0x8FB8, 0x6609, 0xFAD1, 0x660A, 0x9DDD,
+	0x660C, 0x8FB9, 0x660E, 0x96BE, 0x660F, 0x8DA8, 0x6613, 0x88D5,
+	0x6614, 0x90CC, 0x6615, 0xFACF, 0x661C, 0x9DE4, 0x661E, 0xFAD3,
+	0x661F, 0x90AF, 0x6620, 0x8966, 0x6624, 0xFAD4, 0x6625, 0x8F74,
+	0x6627, 0x9686, 0x6628, 0x8DF0, 0x662D, 0x8FBA, 0x662E, 0xFAD2,
+	0x662F, 0x90A5, 0x6631, 0xFA63, 0x6634, 0x9DE3, 0x6635, 0x9DE1,
+	0x6636, 0x9DE2, 0x663B, 0xFAD0, 0x663C, 0x928B, 0x663F, 0x9E45,
+	0x6641, 0x9DE8, 0x6642, 0x8E9E, 0x6643, 0x8D57, 0x6644, 0x9DE6,
+	0x6649, 0x9DE7, 0x664B, 0x9057, 0x664F, 0x9DE5, 0x6652, 0x8E4E,
+	0x6657, 0xFAD6, 0x6659, 0xFAD7, 0x665D, 0x9DEA, 0x665E, 0x9DE9,
+	0x665F, 0x9DEE, 0x6662, 0x9DEF, 0x6664, 0x9DEB, 0x6665, 0xFAD5,
+	0x6666, 0x8A41, 0x6667, 0x9DEC, 0x6668, 0x9DED, 0x6669, 0x94D3,
+	0x666E, 0x9581, 0x666F, 0x8C69, 0x6670, 0x9DF0, 0x6673, 0xFAD9,
+	0x6674, 0x90B0, 0x6676, 0x8FBB, 0x667A, 0x9271, 0x6681, 0x8BC5,
+	0x6683, 0x9DF1, 0x6684, 0x9DF5, 0x6687, 0x89C9, 0x6688, 0x9DF2,
+	0x6689, 0x9DF4, 0x668E, 0x9DF3, 0x6691, 0x8F8B, 0x6696, 0x9267,
+	0x6697, 0x88C3, 0x6698, 0x9DF6, 0x6699, 0xFADA, 0x669D, 0x9DF7,
+	0x66A0, 0xFADB, 0x66A2, 0x92A8, 0x66A6, 0x97EF, 0x66AB, 0x8E62,
+	0x66AE, 0x95E9, 0x66B2, 0xFADC, 0x66B4, 0x965C, 0x66B8, 0x9E41,
+	0x66B9, 0x9DF9, 0x66BC, 0x9DFC, 0x66BE, 0x9DFB, 0x66BF, 0xFADD,
+	0x66C1, 0x9DF8, 0x66C4, 0x9E40, 0x66C7, 0x93DC, 0x66C9, 0x9DFA,
+	0x66D6, 0x9E42, 0x66D9, 0x8F8C, 0x66DA, 0x9E43, 0x66DC, 0x976A,
+	0x66DD, 0x9498, 0x66E0, 0x9E44, 0x66E6, 0x9E46, 0x66E9, 0x9E47,
+	0x66F0, 0x9E48, 0x66F2, 0x8BC8, 0x66F3, 0x8967, 0x66F4, 0x8D58,
+	0x66F5, 0x9E49, 0x66F7, 0x9E4A, 0x66F8, 0x8F91, 0x66F9, 0x9182,
+	0x66FA, 0xFADE, 0x66FB, 0xFA66, 0x66FC, 0x99D6, 0x66FD, 0x915D,
+	0x66FE, 0x915C, 0x66FF, 0x91D6, 0x6700, 0x8DC5, 0x6703, 0x98F0,
+	0x6708, 0x8C8E, 0x6709, 0x974C, 0x670B, 0x95FC, 0x670D, 0x959E,
+	0x670E, 0xFADF, 0x670F, 0x9E4B, 0x6714, 0x8DF1, 0x6715, 0x92BD,
+	0x6716, 0x9E4C, 0x6717, 0x984E, 0x671B, 0x965D, 0x671D, 0x92A9,
+	0x671E, 0x9E4D, 0x671F, 0x8AFA, 0x6726, 0x9E4E, 0x6727, 0x9E4F,
+	0x6728, 0x96D8, 0x672A, 0x96A2, 0x672B, 0x9696, 0x672C, 0x967B,
+	0x672D, 0x8E44, 0x672E, 0x9E51, 0x6731, 0x8EE9, 0x6734, 0x9670,
+	0x6736, 0x9E53, 0x6737, 0x9E56, 0x6738, 0x9E55, 0x673A, 0x8AF7,
+	0x673D, 0x8B80, 0x673F, 0x9E52, 0x6741, 0x9E54, 0x6746, 0x9E57,
+	0x6749, 0x9099, 0x674E, 0x979B, 0x674F, 0x88C7, 0x6750, 0x8DDE,
+	0x6751, 0x91BA, 0x6753, 0x8EDB, 0x6756, 0x8FF1, 0x6759, 0x9E5A,
+	0x675C, 0x936D, 0x675E, 0x9E58, 0x675F, 0x91A9, 0x6760, 0x9E59,
+	0x6761, 0x8FF0, 0x6762, 0x96DB, 0x6763, 0x9E5B, 0x6764, 0x9E5C,
+	0x6765, 0x9788, 0x6766, 0xFAE1, 0x676A, 0x9E61, 0x676D, 0x8D59,
+	0x676F, 0x9474, 0x6770, 0x9E5E, 0x6771, 0x938C, 0x6772, 0x9DDC,
+	0x6773, 0x9DE0, 0x6775, 0x8B6E, 0x6777, 0x9466, 0x677C, 0x9E60,
+	0x677E, 0x8FBC, 0x677F, 0x94C2, 0x6785, 0x9E66, 0x6787, 0x94F8,
+	0x6789, 0x9E5D, 0x678B, 0x9E63, 0x678C, 0x9E62, 0x6790, 0x90CD,
+	0x6795, 0x968D, 0x6797, 0x97D1, 0x679A, 0x9687, 0x679C, 0x89CA,
+	0x679D, 0x8E7D, 0x67A0, 0x9867, 0x67A1, 0x9E65, 0x67A2, 0x9095,
+	0x67A6, 0x9E64, 0x67A9, 0x9E5F, 0x67AF, 0x8CCD, 0x67B3, 0x9E6B,
+	0x67B4, 0x9E69, 0x67B6, 0x89CB, 0x67B7, 0x9E67, 0x67B8, 0x9E6D,
+	0x67B9, 0x9E73, 0x67BB, 0xFAE2, 0x67C0, 0xFAE4, 0x67C1, 0x91C6,
+	0x67C4, 0x95BF, 0x67C6, 0x9E75, 0x67CA, 0x9541, 0x67CE, 0x9E74,
+	0x67CF, 0x9490, 0x67D0, 0x965E, 0x67D1, 0x8AB9, 0x67D3, 0x90F5,
+	0x67D4, 0x8F5F, 0x67D8, 0x92D1, 0x67DA, 0x974D, 0x67DD, 0x9E70,
+	0x67DE, 0x9E6F, 0x67E2, 0x9E71, 0x67E4, 0x9E6E, 0x67E7, 0x9E76,
+	0x67E9, 0x9E6C, 0x67EC, 0x9E6A, 0x67EE, 0x9E72, 0x67EF, 0x9E68,
+	0x67F1, 0x928C, 0x67F3, 0x96F6, 0x67F4, 0x8EC4, 0x67F5, 0x8DF2,
+	0x67FB, 0x8DB8, 0x67FE, 0x968F, 0x67FF, 0x8A60, 0x6801, 0xFAE5,
+	0x6802, 0x92CC, 0x6803, 0x93C8, 0x6804, 0x8968, 0x6813, 0x90F0,
+	0x6816, 0x90B2, 0x6817, 0x8C49, 0x681E, 0x9E78, 0x6821, 0x8D5A,
+	0x6822, 0x8A9C, 0x6829, 0x9E7A, 0x682A, 0x8A94, 0x682B, 0x9E81,
+	0x6832, 0x9E7D, 0x6834, 0x90F1, 0x6838, 0x8A6A, 0x6839, 0x8DAA,
+	0x683C, 0x8A69, 0x683D, 0x8DCD, 0x6840, 0x9E7B, 0x6841, 0x8C85,
+	0x6842, 0x8C6A, 0x6843, 0x938D, 0x6844, 0xFAE6, 0x6846, 0x9E79,
+	0x6848, 0x88C4, 0x684D, 0x9E7C, 0x684E, 0x9E7E, 0x6850, 0x8BCB,
+	0x6851, 0x8C4B, 0x6852, 0xFAE3, 0x6853, 0x8ABA, 0x6854, 0x8B6A,
+	0x6859, 0x9E82, 0x685C, 0x8DF7, 0x685D, 0x9691, 0x685F, 0x8E56,
+	0x6863, 0x9E83, 0x6867, 0x954F, 0x6874, 0x9E8F, 0x6876, 0x89B1,
+	0x6877, 0x9E84, 0x687E, 0x9E95, 0x687F, 0x9E85, 0x6881, 0x97C0,
+	0x6883, 0x9E8C, 0x6885, 0x947E, 0x688D, 0x9E94, 0x688F, 0x9E87,
+	0x6893, 0x88B2, 0x6894, 0x9E89, 0x6897, 0x8D5B, 0x689B, 0x9E8B,
+	0x689D, 0x9E8A, 0x689F, 0x9E86, 0x68A0, 0x9E91, 0x68A2, 0x8FBD,
+	0x68A6, 0x9AEB, 0x68A7, 0x8CE6, 0x68A8, 0x979C, 0x68AD, 0x9E88,
+	0x68AF, 0x92F2, 0x68B0, 0x8A42, 0x68B1, 0x8DAB, 0x68B3, 0x9E80,
+	0x68B5, 0x9E90, 0x68B6, 0x8A81, 0x68B9, 0x9E8E, 0x68BA, 0x9E92,
+	0x68BC, 0x938E, 0x68C4, 0x8AFC, 0x68C6, 0x9EB0, 0x68C8, 0xFA64,
+	0x68C9, 0x96C7, 0x68CA, 0x9E97, 0x68CB, 0x8AFB, 0x68CD, 0x9E9E,
+	0x68CF, 0xFAE7, 0x68D2, 0x965F, 0x68D4, 0x9E9F, 0x68D5, 0x9EA1,
+	0x68D7, 0x9EA5, 0x68D8, 0x9E99, 0x68DA, 0x9249, 0x68DF, 0x938F,
+	0x68E0, 0x9EA9, 0x68E1, 0x9E9C, 0x68E3, 0x9EA6, 0x68E7, 0x9EA0,
+	0x68EE, 0x9058, 0x68EF, 0x9EAA, 0x68F2, 0x90B1, 0x68F9, 0x9EA8,
+	0x68FA, 0x8ABB, 0x6900, 0x986F, 0x6901, 0x9E96, 0x6904, 0x9EA4,
+	0x6905, 0x88D6, 0x6908, 0x9E98, 0x690B, 0x96B8, 0x690C, 0x9E9D,
+	0x690D, 0x9041, 0x690E, 0x92C5, 0x690F, 0x9E93, 0x6912, 0x9EA3,
+	0x6919, 0x909A, 0x691A, 0x9EAD, 0x691B, 0x8A91, 0x691C, 0x8C9F,
+	0x6921, 0x9EAF, 0x6922, 0x9E9A, 0x6923, 0x9EAE, 0x6925, 0x9EA7,
+	0x6926, 0x9E9B, 0x6928, 0x9EAB, 0x692A, 0x9EAC, 0x6930, 0x9EBD,
+	0x6934, 0x93CC, 0x6936, 0x9EA2, 0x6939, 0x9EB9, 0x693D, 0x9EBB,
+	0x693F, 0x92D6, 0x694A, 0x976B, 0x6953, 0x9596, 0x6954, 0x9EB6,
+	0x6955, 0x91C8, 0x6959, 0x9EBC, 0x695A, 0x915E, 0x695C, 0x9EB3,
+	0x695D, 0x9EC0, 0x695E, 0x9EBF, 0x6960, 0x93ED, 0x6961, 0x9EBE,
+	0x6962, 0x93E8, 0x6968, 0xFAE9, 0x696A, 0x9EC2, 0x696B, 0x9EB5,
+	0x696D, 0x8BC6, 0x696E, 0x9EB8, 0x696F, 0x8F7C, 0x6973, 0x9480,
+	0x6974, 0x9EBA, 0x6975, 0x8BC9, 0x6977, 0x9EB2, 0x6978, 0x9EB4,
+	0x6979, 0x9EB1, 0x697C, 0x984F, 0x697D, 0x8A79, 0x697E, 0x9EB7,
+	0x6981, 0x9EC1, 0x6982, 0x8A54, 0x698A, 0x8DE5, 0x698E, 0x897C,
+	0x6991, 0x9ED2, 0x6994, 0x9850, 0x6995, 0x9ED5, 0x6998, 0xFAEB,
+	0x699B, 0x9059, 0x699C, 0x9ED4, 0x69A0, 0x9ED3, 0x69A7, 0x9ED0,
+	0x69AE, 0x9EC4, 0x69B1, 0x9EE1, 0x69B2, 0x9EC3, 0x69B4, 0x9ED6,
+	0x69BB, 0x9ECE, 0x69BE, 0x9EC9, 0x69BF, 0x9EC6, 0x69C1, 0x9EC7,
+	0x69C3, 0x9ECF, 0x69C7, 0xEAA0, 0x69CA, 0x9ECC, 0x69CB, 0x8D5C,
+	0x69CC, 0x92C6, 0x69CD, 0x9184, 0x69CE, 0x9ECA, 0x69D0, 0x9EC5,
+	0x69D3, 0x9EC8, 0x69D8, 0x976C, 0x69D9, 0x968A, 0x69DD, 0x9ECD,
+	0x69DE, 0x9ED7, 0x69E2, 0xFAEC, 0x69E7, 0x9EDF, 0x69E8, 0x9ED8,
+	0x69EB, 0x9EE5, 0x69ED, 0x9EE3, 0x69F2, 0x9EDE, 0x69F9, 0x9EDD,
+	0x69FB, 0x92CE, 0x69FD, 0x9185, 0x69FF, 0x9EDB, 0x6A02, 0x9ED9,
+	0x6A05, 0x9EE0, 0x6A0A, 0x9EE6, 0x6A0B, 0x94F3, 0x6A0C, 0x9EEC,
+	0x6A12, 0x9EE7, 0x6A13, 0x9EEA, 0x6A14, 0x9EE4, 0x6A17, 0x9294,
+	0x6A19, 0x9557, 0x6A1B, 0x9EDA, 0x6A1E, 0x9EE2, 0x6A1F, 0x8FBE,
+	0x6A21, 0x96CD, 0x6A22, 0x9EF6, 0x6A23, 0x9EE9, 0x6A29, 0x8CA0,
+	0x6A2A, 0x89A1, 0x6A2B, 0x8A7E, 0x6A2E, 0x9ED1, 0x6A30, 0xFAED,
+	0x6A35, 0x8FBF, 0x6A36, 0x9EEE, 0x6A38, 0x9EF5, 0x6A39, 0x8EF7,
+	0x6A3A, 0x8A92, 0x6A3D, 0x924D, 0x6A44, 0x9EEB, 0x6A46, 0xFAEF,
+	0x6A47, 0x9EF0, 0x6A48, 0x9EF4, 0x6A4B, 0x8BB4, 0x6A58, 0x8B6B,
+	0x6A59, 0x9EF2, 0x6A5F, 0x8B40, 0x6A61, 0x93C9, 0x6A62, 0x9EF1,
+	0x6A66, 0x9EF3, 0x6A6B, 0xFAEE, 0x6A72, 0x9EED, 0x6A73, 0xFAF0,
+	0x6A78, 0x9EEF, 0x6A7E, 0xFAF1, 0x6A7F, 0x8A80, 0x6A80, 0x9268,
+	0x6A84, 0x9EFA, 0x6A8D, 0x9EF8, 0x6A8E, 0x8CE7, 0x6A90, 0x9EF7,
+	0x6A97, 0x9F40, 0x6A9C, 0x9E77, 0x6AA0, 0x9EF9, 0x6AA2, 0x9EFB,
+	0x6AA3, 0x9EFC, 0x6AAA, 0x9F4B, 0x6AAC, 0x9F47, 0x6AAE, 0x9E8D,
+	0x6AB3, 0x9F46, 0x6AB8, 0x9F45, 0x6ABB, 0x9F42, 0x6AC1, 0x9EE8,
+	0x6AC2, 0x9F44, 0x6AC3, 0x9F43, 0x6AD1, 0x9F49, 0x6AD3, 0x9845,
+	0x6ADA, 0x9F4C, 0x6ADB, 0x8BF9, 0x6ADE, 0x9F48, 0x6ADF, 0x9F4A,
+	0x6AE2, 0xFAF2, 0x6AE4, 0xFAF3, 0x6AE8, 0x94A5, 0x6AEA, 0x9F4D,
+	0x6AFA, 0x9F51, 0x6AFB, 0x9F4E, 0x6B04, 0x9793, 0x6B05, 0x9F4F,
+	0x6B0A, 0x9EDC, 0x6B12, 0x9F52, 0x6B16, 0x9F53, 0x6B1D, 0x8954,
+	0x6B1F, 0x9F55, 0x6B20, 0x8C87, 0x6B21, 0x8E9F, 0x6B23, 0x8BD3,
+	0x6B27, 0x89A2, 0x6B32, 0x977E, 0x6B37, 0x9F57, 0x6B38, 0x9F56,
+	0x6B39, 0x9F59, 0x6B3A, 0x8B5C, 0x6B3D, 0x8BD4, 0x6B3E, 0x8ABC,
+	0x6B43, 0x9F5C, 0x6B47, 0x9F5B, 0x6B49, 0x9F5D, 0x6B4C, 0x89CC,
+	0x6B4E, 0x9256, 0x6B50, 0x9F5E, 0x6B53, 0x8ABD, 0x6B54, 0x9F60,
+	0x6B59, 0x9F5F, 0x6B5B, 0x9F61, 0x6B5F, 0x9F62, 0x6B61, 0x9F63,
+	0x6B62, 0x8E7E, 0x6B63, 0x90B3, 0x6B64, 0x8D9F, 0x6B66, 0x9590,
+	0x6B69, 0x95E0, 0x6B6A, 0x9863, 0x6B6F, 0x8E95, 0x6B73, 0x8DCE,
+	0x6B74, 0x97F0, 0x6B78, 0x9F64, 0x6B79, 0x9F65, 0x6B7B, 0x8E80,
+	0x6B7F, 0x9F66, 0x6B80, 0x9F67, 0x6B83, 0x9F69, 0x6B84, 0x9F68,
+	0x6B86, 0x9677, 0x6B89, 0x8F7D, 0x6B8A, 0x8EEA, 0x6B8B, 0x8E63,
+	0x6B8D, 0x9F6A, 0x6B95, 0x9F6C, 0x6B96, 0x9042, 0x6B98, 0x9F6B,
+	0x6B9E, 0x9F6D, 0x6BA4, 0x9F6E, 0x6BAA, 0x9F6F, 0x6BAB, 0x9F70,
+	0x6BAF, 0x9F71, 0x6BB1, 0x9F73, 0x6BB2, 0x9F72, 0x6BB3, 0x9F74,
+	0x6BB4, 0x89A3, 0x6BB5, 0x9269, 0x6BB7, 0x9F75, 0x6BBA, 0x8E45,
+	0x6BBB, 0x8A6B, 0x6BBC, 0x9F76, 0x6BBF, 0x9361, 0x6BC0, 0x9ACA,
+	0x6BC5, 0x8B42, 0x6BC6, 0x9F77, 0x6BCB, 0x9F78, 0x6BCD, 0x95EA,
+	0x6BCE, 0x9688, 0x6BD2, 0x93C5, 0x6BD3, 0x9F79, 0x6BD4, 0x94E4,
+	0x6BD6, 0xFAF4, 0x6BD8, 0x94F9, 0x6BDB, 0x96D1, 0x6BDF, 0x9F7A,
+	0x6BEB, 0x9F7C, 0x6BEC, 0x9F7B, 0x6BEF, 0x9F7E, 0x6BF3, 0x9F7D,
+	0x6C08, 0x9F81, 0x6C0F, 0x8E81, 0x6C11, 0x96AF, 0x6C13, 0x9F82,
+	0x6C14, 0x9F83, 0x6C17, 0x8B43, 0x6C1B, 0x9F84, 0x6C23, 0x9F86,
+	0x6C24, 0x9F85, 0x6C34, 0x9085, 0x6C37, 0x9558, 0x6C38, 0x8969,
+	0x6C3E, 0x94C3, 0x6C3F, 0xFAF5, 0x6C40, 0x92F3, 0x6C41, 0x8F60,
+	0x6C42, 0x8B81, 0x6C4E, 0x94C4, 0x6C50, 0x8EAC, 0x6C55, 0x9F88,
+	0x6C57, 0x8ABE, 0x6C5A, 0x8998, 0x6C5C, 0xFAF6, 0x6C5D, 0x93F0,
+	0x6C5E, 0x9F87, 0x6C5F, 0x8D5D, 0x6C60, 0x9272, 0x6C62, 0x9F89,
+	0x6C68, 0x9F91, 0x6C6A, 0x9F8A, 0x6C6F, 0xFAF8, 0x6C70, 0x91BF,
+	0x6C72, 0x8B82, 0x6C73, 0x9F92, 0x6C7A, 0x8C88, 0x6C7D, 0x8B44,
+	0x6C7E, 0x9F90, 0x6C81, 0x9F8E, 0x6C82, 0x9F8B, 0x6C83, 0x9780,
+	0x6C86, 0xFAF7, 0x6C88, 0x92BE, 0x6C8C, 0x93D7, 0x6C8D, 0x9F8C,
+	0x6C90, 0x9F94, 0x6C92, 0x9F93, 0x6C93, 0x8C42, 0x6C96, 0x89AB,
+	0x6C99, 0x8DB9, 0x6C9A, 0x9F8D, 0x6C9B, 0x9F8F, 0x6CA1, 0x9676,
+	0x6CA2, 0x91F2, 0x6CAB, 0x9697, 0x6CAE, 0x9F9C, 0x6CB1, 0x9F9D,
+	0x6CB3, 0x89CD, 0x6CB8, 0x95A6, 0x6CB9, 0x96FB, 0x6CBA, 0x9F9F,
+	0x6CBB, 0x8EA1, 0x6CBC, 0x8FC0, 0x6CBD, 0x9F98, 0x6CBE, 0x9F9E,
+	0x6CBF, 0x8988, 0x6CC1, 0x8BB5, 0x6CC4, 0x9F95, 0x6CC5, 0x9F9A,
+	0x6CC9, 0x90F2, 0x6CCA, 0x9491, 0x6CCC, 0x94E5, 0x6CD3, 0x9F97,
+	0x6CD5, 0x9640, 0x6CD7, 0x9F99, 0x6CD9, 0x9FA2, 0x6CDA, 0xFAF9,
+	0x6CDB, 0x9FA0, 0x6CDD, 0x9F9B, 0x6CE1, 0x9641, 0x6CE2, 0x9467,
+	0x6CE3, 0x8B83, 0x6CE5, 0x9344, 0x6CE8, 0x928D, 0x6CEA, 0x9FA3,
+	0x6CEF, 0x9FA1, 0x6CF0, 0x91D7, 0x6CF1, 0x9F96, 0x6CF3, 0x896A,
+	0x6D04, 0xFAFA, 0x6D0B, 0x976D, 0x6D0C, 0x9FAE, 0x6D12, 0x9FAD,
+	0x6D17, 0x90F4, 0x6D19, 0x9FAA, 0x6D1B, 0x978C, 0x6D1E, 0x93B4,
+	0x6D1F, 0x9FA4, 0x6D25, 0x92C3, 0x6D29, 0x896B, 0x6D2A, 0x8D5E,
+	0x6D2B, 0x9FA7, 0x6D32, 0x8F46, 0x6D33, 0x9FAC, 0x6D35, 0x9FAB,
+	0x6D36, 0x9FA6, 0x6D38, 0x9FA9, 0x6D3B, 0x8A88, 0x6D3D, 0x9FA8,
+	0x6D3E, 0x9468, 0x6D41, 0x97AC, 0x6D44, 0x8FF2, 0x6D45, 0x90F3,
+	0x6D59, 0x9FB4, 0x6D5A, 0x9FB2, 0x6D5C, 0x956C, 0x6D63, 0x9FAF,
+	0x6D64, 0x9FB1, 0x6D66, 0x8959, 0x6D69, 0x8D5F, 0x6D6A, 0x9851,
+	0x6D6C, 0x8A5C, 0x6D6E, 0x9582, 0x6D6F, 0xFAFC, 0x6D74, 0x9781,
+	0x6D77, 0x8A43, 0x6D78, 0x905A, 0x6D79, 0x9FB3, 0x6D85, 0x9FB8,
+	0x6D87, 0xFAFB, 0x6D88, 0x8FC1, 0x6D8C, 0x974F, 0x6D8E, 0x9FB5,
+	0x6D93, 0x9FB0, 0x6D95, 0x9FB6, 0x6D96, 0xFB40, 0x6D99, 0x97DC,
+	0x6D9B, 0x9393, 0x6D9C, 0x93C0, 0x6DAC, 0xFB41, 0x6DAF, 0x8A55,
+	0x6DB2, 0x8974, 0x6DB5, 0x9FBC, 0x6DB8, 0x9FBF, 0x6DBC, 0x97C1,
+	0x6DC0, 0x9784, 0x6DC5, 0x9FC6, 0x6DC6, 0x9FC0, 0x6DC7, 0x9FBD,
+	0x6DCB, 0x97D2, 0x6DCC, 0x9FC3, 0x6DCF, 0xFB42, 0x6DD1, 0x8F69,
+	0x6DD2, 0x9FC5, 0x6DD5, 0x9FCA, 0x6DD8, 0x9391, 0x6DD9, 0x9FC8,
+	0x6DDE, 0x9FC2, 0x6DE1, 0x9257, 0x6DE4, 0x9FC9, 0x6DE6, 0x9FBE,
+	0x6DE8, 0x9FC4, 0x6DEA, 0x9FCB, 0x6DEB, 0x88FA, 0x6DEC, 0x9FC1,
+	0x6DEE, 0x9FCC, 0x6DF1, 0x905B, 0x6DF2, 0xFB44, 0x6DF3, 0x8F7E,
+	0x6DF5, 0x95A3, 0x6DF7, 0x8DAC, 0x6DF8, 0xFB43, 0x6DF9, 0x9FB9,
+	0x6DFA, 0x9FC7, 0x6DFB, 0x9359, 0x6DFC, 0xFB45, 0x6E05, 0x90B4,
+	0x6E07, 0x8A89, 0x6E08, 0x8DCF, 0x6E09, 0x8FC2, 0x6E0A, 0x9FBB,
+	0x6E0B, 0x8F61, 0x6E13, 0x8C6B, 0x6E15, 0x9FBA, 0x6E19, 0x9FD0,
+	0x6E1A, 0x8F8D, 0x6E1B, 0x8CB8, 0x6E1D, 0x9FDF, 0x6E1F, 0x9FD9,
+	0x6E20, 0x8B94, 0x6E21, 0x936E, 0x6E23, 0x9FD4, 0x6E24, 0x9FDD,
+	0x6E25, 0x88AD, 0x6E26, 0x8951, 0x6E27, 0xFB48, 0x6E29, 0x89B7,
+	0x6E2B, 0x9FD6, 0x6E2C, 0x91AA, 0x6E2D, 0x9FCD, 0x6E2E, 0x9FCF,
+	0x6E2F, 0x8D60, 0x6E38, 0x9FE0, 0x6E39, 0xFB46, 0x6E3A, 0x9FDB,
+	0x6E3C, 0xFB49, 0x6E3E, 0x9FD3, 0x6E43, 0x9FDA, 0x6E4A, 0x96A9,
+	0x6E4D, 0x9FD8, 0x6E4E, 0x9FDC, 0x6E56, 0x8CCE, 0x6E58, 0x8FC3,
+	0x6E5B, 0x9258, 0x6E5C, 0xFB47, 0x6E5F, 0x9FD2, 0x6E67, 0x974E,
+	0x6E6B, 0x9FD5, 0x6E6E, 0x9FCE, 0x6E6F, 0x9392, 0x6E72, 0x9FD1,
+	0x6E76, 0x9FD7, 0x6E7E, 0x9870, 0x6E7F, 0x8EBC, 0x6E80, 0x969E,
+	0x6E82, 0x9FE1, 0x6E8C, 0x94AC, 0x6E8F, 0x9FED, 0x6E90, 0x8CB9,
+	0x6E96, 0x8F80, 0x6E98, 0x9FE3, 0x6E9C, 0x97AD, 0x6E9D, 0x8D61,
+	0x6E9F, 0x9FF0, 0x6EA2, 0x88EC, 0x6EA5, 0x9FEE, 0x6EAA, 0x9FE2,
+	0x6EAF, 0x9FE8, 0x6EB2, 0x9FEA, 0x6EB6, 0x976E, 0x6EB7, 0x9FE5,
+	0x6EBA, 0x934D, 0x6EBD, 0x9FE7, 0x6EBF, 0xFB4A, 0x6EC2, 0x9FEF,
+	0x6EC4, 0x9FE9, 0x6EC5, 0x96C5, 0x6EC9, 0x9FE4, 0x6ECB, 0x8EA0,
+	0x6ECC, 0x9FFC, 0x6ED1, 0x8A8A, 0x6ED3, 0x9FE6, 0x6ED4, 0x9FEB,
+	0x6ED5, 0x9FEC, 0x6EDD, 0x91EA, 0x6EDE, 0x91D8, 0x6EEC, 0x9FF4,
+	0x6EEF, 0x9FFA, 0x6EF2, 0x9FF8, 0x6EF4, 0x9348, 0x6EF7, 0xE042,
+	0x6EF8, 0x9FF5, 0x6EFE, 0x9FF6, 0x6EFF, 0x9FDE, 0x6F01, 0x8B99,
+	0x6F02, 0x9559, 0x6F06, 0x8EBD, 0x6F09, 0x8D97, 0x6F0F, 0x9852,
+	0x6F11, 0x9FF2, 0x6F13, 0xE041, 0x6F14, 0x8989, 0x6F15, 0x9186,
+	0x6F20, 0x9499, 0x6F22, 0x8ABF, 0x6F23, 0x97F8, 0x6F2B, 0x969F,
+	0x6F2C, 0x92D0, 0x6F31, 0x9FF9, 0x6F32, 0x9FFB, 0x6F38, 0x9151,
+	0x6F3E, 0xE040, 0x6F3F, 0x9FF7, 0x6F41, 0x9FF1, 0x6F45, 0x8AC1,
+	0x6F54, 0x8C89, 0x6F58, 0xE04E, 0x6F5B, 0xE049, 0x6F5C, 0x90F6,
+	0x6F5F, 0x8A83, 0x6F64, 0x8F81, 0x6F66, 0xE052, 0x6F6D, 0xE04B,
+	0x6F6E, 0x92AA, 0x6F6F, 0xE048, 0x6F70, 0x92D7, 0x6F74, 0xE06B,
+	0x6F78, 0xE045, 0x6F7A, 0xE044, 0x6F7C, 0xE04D, 0x6F80, 0xE047,
+	0x6F81, 0xE046, 0x6F82, 0xE04C, 0x6F84, 0x909F, 0x6F86, 0xE043,
+	0x6F88, 0xFB4B, 0x6F8E, 0xE04F, 0x6F91, 0xE050, 0x6F97, 0x8AC0,
+	0x6FA1, 0xE055, 0x6FA3, 0xE054, 0x6FA4, 0xE056, 0x6FAA, 0xE059,
+	0x6FB1, 0x9362, 0x6FB3, 0xE053, 0x6FB5, 0xFB4C, 0x6FB9, 0xE057,
+	0x6FC0, 0x8C83, 0x6FC1, 0x91F7, 0x6FC2, 0xE051, 0x6FC3, 0x945A,
+	0x6FC6, 0xE058, 0x6FD4, 0xE05D, 0x6FD5, 0xE05B, 0x6FD8, 0xE05E,
+	0x6FDB, 0xE061, 0x6FDF, 0xE05A, 0x6FE0, 0x8D8A, 0x6FE1, 0x9447,
+	0x6FE4, 0x9FB7, 0x6FEB, 0x9794, 0x6FEC, 0xE05C, 0x6FEE, 0xE060,
+	0x6FEF, 0x91F3, 0x6FF1, 0xE05F, 0x6FF3, 0xE04A, 0x6FF5, 0xFB4D,
+	0x6FF6, 0xE889, 0x6FFA, 0xE064, 0x6FFE, 0xE068, 0x7001, 0xE066,
+	0x7005, 0xFB4E, 0x7007, 0xFB4F, 0x7009, 0xE062, 0x700B, 0xE063,
+	0x700F, 0xE067, 0x7011, 0xE065, 0x7015, 0x956D, 0x7018, 0xE06D,
+	0x701A, 0xE06A, 0x701B, 0xE069, 0x701D, 0xE06C, 0x701E, 0x93D2,
+	0x701F, 0xE06E, 0x7026, 0x9295, 0x7027, 0x91EB, 0x7028, 0xFB50,
+	0x702C, 0x90A3, 0x7030, 0xE06F, 0x7032, 0xE071, 0x703E, 0xE070,
+	0x704C, 0x9FF3, 0x7051, 0xE072, 0x7058, 0x93E5, 0x7063, 0xE073,
+	0x706B, 0x89CE, 0x706F, 0x9394, 0x7070, 0x8A44, 0x7078, 0x8B84,
+	0x707C, 0x8EDC, 0x707D, 0x8DD0, 0x7085, 0xFB51, 0x7089, 0x9846,
+	0x708A, 0x9086, 0x708E, 0x898A, 0x7092, 0xE075, 0x7099, 0xE074,
+	0x70AB, 0xFB52, 0x70AC, 0xE078, 0x70AD, 0x9259, 0x70AE, 0xE07B,
+	0x70AF, 0xE076, 0x70B3, 0xE07A, 0x70B8, 0xE079, 0x70B9, 0x935F,
+	0x70BA, 0x88D7, 0x70BB, 0xFA62, 0x70C8, 0x97F3, 0x70CB, 0xE07D,
+	0x70CF, 0x8947, 0x70D9, 0xE080, 0x70DD, 0xE07E, 0x70DF, 0xE07C,
+	0x70F1, 0xE077, 0x70F9, 0x9642, 0x70FD, 0xE082, 0x7104, 0xFB54,
+	0x7109, 0xE081, 0x710F, 0xFB53, 0x7114, 0x898B, 0x7119, 0xE084,
+	0x711A, 0x95B0, 0x711C, 0xE083, 0x7121, 0x96B3, 0x7126, 0x8FC5,
+	0x7136, 0x9152, 0x713C, 0x8FC4, 0x7146, 0xFB56, 0x7147, 0xFB57,
+	0x7149, 0x97F9, 0x714C, 0xE08A, 0x714E, 0x90F7, 0x7155, 0xE086,
+	0x7156, 0xE08B, 0x7159, 0x898C, 0x715C, 0xFB55, 0x7162, 0xE089,
+	0x7164, 0x9481, 0x7165, 0xE085, 0x7166, 0xE088, 0x7167, 0x8FC6,
+	0x7169, 0x94CF, 0x716C, 0xE08C, 0x716E, 0x8ECF, 0x717D, 0x90F8,
+	0x7184, 0xE08F, 0x7188, 0xE087, 0x718A, 0x8C46, 0x718F, 0xE08D,
+	0x7194, 0x976F, 0x7195, 0xE090, 0x7199, 0xEAA4, 0x719F, 0x8F6E,
+	0x71A8, 0xE091, 0x71AC, 0xE092, 0x71B1, 0x944D, 0x71B9, 0xE094,
+	0x71BE, 0xE095, 0x71C1, 0xFB59, 0x71C3, 0x9452, 0x71C8, 0x9395,
+	0x71C9, 0xE097, 0x71CE, 0xE099, 0x71D0, 0x97D3, 0x71D2, 0xE096,
+	0x71D4, 0xE098, 0x71D5, 0x898D, 0x71D7, 0xE093, 0x71DF, 0x9A7A,
+	0x71E0, 0xE09A, 0x71E5, 0x9187, 0x71E6, 0x8E57, 0x71E7, 0xE09C,
+	0x71EC, 0xE09B, 0x71ED, 0x9043, 0x71EE, 0x99D7, 0x71F5, 0xE09D,
+	0x71F9, 0xE09F, 0x71FB, 0xE08E, 0x71FC, 0xE09E, 0x71FE, 0xFB5A,
+	0x71FF, 0xE0A0, 0x7206, 0x949A, 0x720D, 0xE0A1, 0x7210, 0xE0A2,
+	0x721B, 0xE0A3, 0x7228, 0xE0A4, 0x722A, 0x92DC, 0x722C, 0xE0A6,
+	0x722D, 0xE0A5, 0x7230, 0xE0A7, 0x7232, 0xE0A8, 0x7235, 0x8EDD,
+	0x7236, 0x9583, 0x723A, 0x96EA, 0x723B, 0xE0A9, 0x723C, 0xE0AA,
+	0x723D, 0x9175, 0x723E, 0x8EA2, 0x723F, 0xE0AB, 0x7240, 0xE0AC,
+	0x7246, 0xE0AD, 0x7247, 0x95D0, 0x7248, 0x94C5, 0x724B, 0xE0AE,
+	0x724C, 0x9476, 0x7252, 0x92AB, 0x7258, 0xE0AF, 0x7259, 0x89E5,
+	0x725B, 0x8B8D, 0x725D, 0x96C4, 0x725F, 0x96B4, 0x7261, 0x89B2,
+	0x7262, 0x9853, 0x7267, 0x9671, 0x7269, 0x95A8, 0x7272, 0x90B5,
+	0x7274, 0xE0B0, 0x7279, 0x93C1, 0x727D, 0x8CA1, 0x727E, 0xE0B1,
+	0x7280, 0x8DD2, 0x7281, 0xE0B3, 0x7282, 0xE0B2, 0x7287, 0xE0B4,
+	0x7292, 0xE0B5, 0x7296, 0xE0B6, 0x72A0, 0x8B5D, 0x72A2, 0xE0B7,
+	0x72A7, 0xE0B8, 0x72AC, 0x8CA2, 0x72AF, 0x94C6, 0x72B1, 0xFB5B,
+	0x72B2, 0xE0BA, 0x72B6, 0x8FF3, 0x72B9, 0xE0B9, 0x72BE, 0xFB5C,
+	0x72C2, 0x8BB6, 0x72C3, 0xE0BB, 0x72C4, 0xE0BD, 0x72C6, 0xE0BC,
+	0x72CE, 0xE0BE, 0x72D0, 0x8CCF, 0x72D2, 0xE0BF, 0x72D7, 0x8BE7,
+	0x72D9, 0x915F, 0x72DB, 0x8D9D, 0x72E0, 0xE0C1, 0x72E1, 0xE0C2,
+	0x72E2, 0xE0C0, 0x72E9, 0x8EEB, 0x72EC, 0x93C6, 0x72ED, 0x8BB7,
+	0x72F7, 0xE0C4, 0x72F8, 0x924B, 0x72F9, 0xE0C3, 0x72FC, 0x9854,
+	0x72FD, 0x9482, 0x730A, 0xE0C7, 0x7316, 0xE0C9, 0x7317, 0xE0C6,
+	0x731B, 0x96D2, 0x731C, 0xE0C8, 0x731D, 0xE0CA, 0x731F, 0x97C2,
+	0x7324, 0xFB5D, 0x7325, 0xE0CE, 0x7329, 0xE0CD, 0x732A, 0x9296,
+	0x732B, 0x944C, 0x732E, 0x8CA3, 0x732F, 0xE0CC, 0x7334, 0xE0CB,
+	0x7336, 0x9750, 0x7337, 0x9751, 0x733E, 0xE0CF, 0x733F, 0x898E,
+	0x7344, 0x8D96, 0x7345, 0x8E82, 0x734E, 0xE0D0, 0x734F, 0xE0D1,
+	0x7357, 0xE0D3, 0x7363, 0x8F62, 0x7368, 0xE0D5, 0x736A, 0xE0D4,
+	0x7370, 0xE0D6, 0x7372, 0x8A6C, 0x7375, 0xE0D8, 0x7377, 0xFB5F,
+	0x7378, 0xE0D7, 0x737A, 0xE0DA, 0x737B, 0xE0D9, 0x7384, 0x8CBA,
+	0x7387, 0x97A6, 0x7389, 0x8BCA, 0x738B, 0x89A4, 0x7396, 0x8BE8,
+	0x73A9, 0x8ADF, 0x73B2, 0x97E6, 0x73B3, 0xE0DC, 0x73BB, 0xE0DE,
+	0x73BD, 0xFB60, 0x73C0, 0xE0DF, 0x73C2, 0x89CF, 0x73C8, 0xE0DB,
+	0x73C9, 0xFB61, 0x73CA, 0x8E58, 0x73CD, 0x92BF, 0x73CE, 0xE0DD,
+	0x73D2, 0xFB64, 0x73D6, 0xFB62, 0x73DE, 0xE0E2, 0x73E0, 0x8EEC,
+	0x73E3, 0xFB63, 0x73E5, 0xE0E0, 0x73EA, 0x8C5D, 0x73ED, 0x94C7,
+	0x73EE, 0xE0E1, 0x73F1, 0xE0FC, 0x73F5, 0xFB66, 0x73F8, 0xE0E7,
+	0x73FE, 0x8CBB, 0x7403, 0x8B85, 0x7405, 0xE0E4, 0x7406, 0x979D,
+	0x7407, 0xFB65, 0x7409, 0x97AE, 0x7422, 0x91F4, 0x7425, 0xE0E6,
+	0x7426, 0xFB67, 0x7429, 0xFB69, 0x742A, 0xFB68, 0x742E, 0xFB6A,
+	0x7432, 0xE0E8, 0x7433, 0x97D4, 0x7434, 0x8BD5, 0x7435, 0x94FA,
+	0x7436, 0x9469, 0x743A, 0xE0E9, 0x743F, 0xE0EB, 0x7441, 0xE0EE,
+	0x7455, 0xE0EA, 0x7459, 0xE0ED, 0x745A, 0x8CE8, 0x745B, 0x896C,
+	0x745C, 0xE0EF, 0x745E, 0x9090, 0x745F, 0xE0EC, 0x7460, 0x97DA,
+	0x7462, 0xFB6B, 0x7463, 0xE0F2, 0x7464, 0xEAA2, 0x7469, 0xE0F0,
+	0x746A, 0xE0F3, 0x746F, 0xE0E5, 0x7470, 0xE0F1, 0x7473, 0x8DBA,
+	0x7476, 0xE0F4, 0x747E, 0xE0F5, 0x7483, 0x979E, 0x7489, 0xFB6C,
+	0x748B, 0xE0F6, 0x749E, 0xE0F7, 0x749F, 0xFB6D, 0x74A2, 0xE0E3,
+	0x74A7, 0xE0F8, 0x74B0, 0x8AC2, 0x74BD, 0x8EA3, 0x74CA, 0xE0F9,
+	0x74CF, 0xE0FA, 0x74D4, 0xE0FB, 0x74DC, 0x895A, 0x74E0, 0xE140,
+	0x74E2, 0x955A, 0x74E3, 0xE141, 0x74E6, 0x8AA2, 0x74E7, 0xE142,
+	0x74E9, 0xE143, 0x74EE, 0xE144, 0x74F0, 0xE146, 0x74F1, 0xE147,
+	0x74F2, 0xE145, 0x74F6, 0x9572, 0x74F7, 0xE149, 0x74F8, 0xE148,
+	0x7501, 0xFB6E, 0x7503, 0xE14B, 0x7504, 0xE14A, 0x7505, 0xE14C,
+	0x750C, 0xE14D, 0x750D, 0xE14F, 0x750E, 0xE14E, 0x7511, 0x8D99,
+	0x7513, 0xE151, 0x7515, 0xE150, 0x7518, 0x8AC3, 0x751A, 0x9072,
+	0x751C, 0x935B, 0x751E, 0xE152, 0x751F, 0x90B6, 0x7523, 0x8E59,
+	0x7525, 0x8999, 0x7526, 0xE153, 0x7528, 0x9770, 0x752B, 0x95E1,
+	0x752C, 0xE154, 0x752F, 0xFAA8, 0x7530, 0x9363, 0x7531, 0x9752,
+	0x7532, 0x8D62, 0x7533, 0x905C, 0x7537, 0x926A, 0x7538, 0x99B2,
+	0x753A, 0x92AC, 0x753B, 0x89E6, 0x753C, 0xE155, 0x7544, 0xE156,
+	0x7546, 0xE15B, 0x7549, 0xE159, 0x754A, 0xE158, 0x754B, 0x9DC0,
+	0x754C, 0x8A45, 0x754D, 0xE157, 0x754F, 0x88D8, 0x7551, 0x94A8,
+	0x7554, 0x94C8, 0x7559, 0x97AF, 0x755A, 0xE15C, 0x755B, 0xE15A,
+	0x755C, 0x927B, 0x755D, 0x90A4, 0x7560, 0x94A9, 0x7562, 0x954C,
+	0x7564, 0xE15E, 0x7565, 0x97AA, 0x7566, 0x8C6C, 0x7567, 0xE15F,
+	0x7569, 0xE15D, 0x756A, 0x94D4, 0x756B, 0xE160, 0x756D, 0xE161,
+	0x756F, 0xFB6F, 0x7570, 0x88D9, 0x7573, 0x8FF4, 0x7574, 0xE166,
+	0x7576, 0xE163, 0x7577, 0x93EB, 0x7578, 0xE162, 0x757F, 0x8B45,
+	0x7582, 0xE169, 0x7586, 0xE164, 0x7587, 0xE165, 0x7589, 0xE168,
+	0x758A, 0xE167, 0x758B, 0x9544, 0x758E, 0x9161, 0x758F, 0x9160,
+	0x7591, 0x8B5E, 0x7594, 0xE16A, 0x759A, 0xE16B, 0x759D, 0xE16C,
+	0x75A3, 0xE16E, 0x75A5, 0xE16D, 0x75AB, 0x8975, 0x75B1, 0xE176,
+	0x75B2, 0x94E6, 0x75B3, 0xE170, 0x75B5, 0xE172, 0x75B8, 0xE174,
+	0x75B9, 0x905D, 0x75BC, 0xE175, 0x75BD, 0xE173, 0x75BE, 0x8EBE,
+	0x75C2, 0xE16F, 0x75C3, 0xE171, 0x75C5, 0x9561, 0x75C7, 0x8FC7,
+	0x75CA, 0xE178, 0x75CD, 0xE177, 0x75D2, 0xE179, 0x75D4, 0x8EA4,
+	0x75D5, 0x8DAD, 0x75D8, 0x9397, 0x75D9, 0xE17A, 0x75DB, 0x92C9,
+	0x75DE, 0xE17C, 0x75E2, 0x979F, 0x75E3, 0xE17B, 0x75E9, 0x9189,
+	0x75F0, 0xE182, 0x75F2, 0xE184, 0x75F3, 0xE185, 0x75F4, 0x9273,
+	0x75FA, 0xE183, 0x75FC, 0xE180, 0x75FE, 0xE17D, 0x75FF, 0xE17E,
+	0x7601, 0xE181, 0x7609, 0xE188, 0x760B, 0xE186, 0x760D, 0xE187,
+	0x761F, 0xE189, 0x7620, 0xE18B, 0x7621, 0xE18C, 0x7622, 0xE18D,
+	0x7624, 0xE18E, 0x7627, 0xE18A, 0x7630, 0xE190, 0x7634, 0xE18F,
+	0x763B, 0xE191, 0x7642, 0x97C3, 0x7646, 0xE194, 0x7647, 0xE192,
+	0x7648, 0xE193, 0x764C, 0x8AE0, 0x7652, 0x96FC, 0x7656, 0x95C8,
+	0x7658, 0xE196, 0x765C, 0xE195, 0x7661, 0xE197, 0x7662, 0xE198,
+	0x7667, 0xE19C, 0x7668, 0xE199, 0x7669, 0xE19A, 0x766A, 0xE19B,
+	0x766C, 0xE19D, 0x7670, 0xE19E, 0x7672, 0xE19F, 0x7676, 0xE1A0,
+	0x7678, 0xE1A1, 0x767A, 0x94AD, 0x767B, 0x936F, 0x767C, 0xE1A2,
+	0x767D, 0x9492, 0x767E, 0x9553, 0x7680, 0xE1A3, 0x7682, 0xFB70,
+	0x7683, 0xE1A4, 0x7684, 0x9349, 0x7686, 0x8A46, 0x7687, 0x8D63,
+	0x7688, 0xE1A5, 0x768B, 0xE1A6, 0x768E, 0xE1A7, 0x7690, 0x8E48,
+	0x7693, 0xE1A9, 0x7696, 0xE1A8, 0x7699, 0xE1AA, 0x769A, 0xE1AB,
+	0x769B, 0xFB73, 0x769C, 0xFB71, 0x769E, 0xFB72, 0x76A6, 0xFB74,
+	0x76AE, 0x94E7, 0x76B0, 0xE1AC, 0x76B4, 0xE1AD, 0x76B7, 0xEA89,
+	0x76B8, 0xE1AE, 0x76B9, 0xE1AF, 0x76BA, 0xE1B0, 0x76BF, 0x8E4D,
+	0x76C2, 0xE1B1, 0x76C3, 0x9475, 0x76C6, 0x967E, 0x76C8, 0x896D,
+	0x76CA, 0x8976, 0x76CD, 0xE1B2, 0x76D2, 0xE1B4, 0x76D6, 0xE1B3,
+	0x76D7, 0x9390, 0x76DB, 0x90B7, 0x76DC, 0x9F58, 0x76DE, 0xE1B5,
+	0x76DF, 0x96BF, 0x76E1, 0xE1B6, 0x76E3, 0x8AC4, 0x76E4, 0x94D5,
+	0x76E5, 0xE1B7, 0x76E7, 0xE1B8, 0x76EA, 0xE1B9, 0x76EE, 0x96DA,
+	0x76F2, 0x96D3, 0x76F4, 0x92BC, 0x76F8, 0x918A, 0x76FB, 0xE1BB,
+	0x76FE, 0x8F82, 0x7701, 0x8FC8, 0x7704, 0xE1BE, 0x7707, 0xE1BD,
+	0x7708, 0xE1BC, 0x7709, 0x94FB, 0x770B, 0x8AC5, 0x770C, 0x8CA7,
+	0x771B, 0xE1C4, 0x771E, 0xE1C1, 0x771F, 0x905E, 0x7720, 0x96B0,
+	0x7724, 0xE1C0, 0x7725, 0xE1C2, 0x7726, 0xE1C3, 0x7729, 0xE1BF,
+	0x7737, 0xE1C5, 0x7738, 0xE1C6, 0x773A, 0x92AD, 0x773C, 0x8AE1,
+	0x7740, 0x9285, 0x7746, 0xFB76, 0x7747, 0xE1C7, 0x775A, 0xE1C8,
+	0x775B, 0xE1CB, 0x7761, 0x9087, 0x7763, 0x93C2, 0x7765, 0xE1CC,
+	0x7766, 0x9672, 0x7768, 0xE1C9, 0x776B, 0xE1CA, 0x7779, 0xE1CF,
+	0x777E, 0xE1CE, 0x777F, 0xE1CD, 0x778B, 0xE1D1, 0x778E, 0xE1D0,
+	0x7791, 0xE1D2, 0x779E, 0xE1D4, 0x77A0, 0xE1D3, 0x77A5, 0x95CB,
+	0x77AC, 0x8F75, 0x77AD, 0x97C4, 0x77B0, 0xE1D5, 0x77B3, 0x93B5,
+	0x77B6, 0xE1D6, 0x77B9, 0xE1D7, 0x77BB, 0xE1DB, 0x77BC, 0xE1D9,
+	0x77BD, 0xE1DA, 0x77BF, 0xE1D8, 0x77C7, 0xE1DC, 0x77CD, 0xE1DD,
+	0x77D7, 0xE1DE, 0x77DA, 0xE1DF, 0x77DB, 0x96B5, 0x77DC, 0xE1E0,
+	0x77E2, 0x96EE, 0x77E3, 0xE1E1, 0x77E5, 0x926D, 0x77E7, 0x948A,
+	0x77E9, 0x8BE9, 0x77ED, 0x925A, 0x77EE, 0xE1E2, 0x77EF, 0x8BB8,
+	0x77F3, 0x90CE, 0x77FC, 0xE1E3, 0x7802, 0x8DBB, 0x780C, 0xE1E4,
+	0x7812, 0xE1E5, 0x7814, 0x8CA4, 0x7815, 0x8DD3, 0x7820, 0xE1E7,
+	0x7821, 0xFB78, 0x7825, 0x9375, 0x7826, 0x8DD4, 0x7827, 0x8B6D,
+	0x7832, 0x9643, 0x7834, 0x946A, 0x783A, 0x9376, 0x783F, 0x8D7B,
+	0x7845, 0xE1E9, 0x784E, 0xFB79, 0x785D, 0x8FC9, 0x7864, 0xFB7A,
+	0x786B, 0x97B0, 0x786C, 0x8D64, 0x786F, 0x8CA5, 0x7872, 0x94A1,
+	0x7874, 0xE1EB, 0x787A, 0xFB7B, 0x787C, 0xE1ED, 0x7881, 0x8CE9,
+	0x7886, 0xE1EC, 0x7887, 0x92F4, 0x788C, 0xE1EF, 0x788D, 0x8A56,
+	0x788E, 0xE1EA, 0x7891, 0x94E8, 0x7893, 0x894F, 0x7895, 0x8DEA,
+	0x7897, 0x9871, 0x789A, 0xE1EE, 0x78A3, 0xE1F0, 0x78A7, 0x95C9,
+	0x78A9, 0x90D7, 0x78AA, 0xE1F2, 0x78AF, 0xE1F3, 0x78B5, 0xE1F1,
+	0x78BA, 0x8A6D, 0x78BC, 0xE1F9, 0x78BE, 0xE1F8, 0x78C1, 0x8EA5,
+	0x78C5, 0xE1FA, 0x78C6, 0xE1F5, 0x78CA, 0xE1FB, 0x78CB, 0xE1F6,
+	0x78D0, 0x94D6, 0x78D1, 0xE1F4, 0x78D4, 0xE1F7, 0x78DA, 0xE241,
+	0x78E7, 0xE240, 0x78E8, 0x9681, 0x78EC, 0xE1FC, 0x78EF, 0x88E9,
+	0x78F4, 0xE243, 0x78FD, 0xE242, 0x7901, 0x8FCA, 0x7907, 0xE244,
+	0x790E, 0x9162, 0x7911, 0xE246, 0x7912, 0xE245, 0x7919, 0xE247,
+	0x7926, 0xE1E6, 0x792A, 0xE1E8, 0x792B, 0xE249, 0x792C, 0xE248,
+	0x7930, 0xFB7C, 0x793A, 0x8EA6, 0x793C, 0x97E7, 0x793E, 0x8ED0,
+	0x7940, 0xE24A, 0x7941, 0x8C56, 0x7947, 0x8B5F, 0x7948, 0x8B46,
+	0x7949, 0x8E83, 0x7950, 0x9753, 0x7953, 0xE250, 0x7955, 0xE24F,
+	0x7956, 0x9163, 0x7957, 0xE24C, 0x795A, 0xE24E, 0x795D, 0x8F6A,
+	0x795E, 0x905F, 0x795F, 0xE24D, 0x7960, 0xE24B, 0x7962, 0x9449,
+	0x7965, 0x8FCB, 0x7968, 0x955B, 0x796D, 0x8DD5, 0x7977, 0x9398,
+	0x797A, 0xE251, 0x797F, 0xE252, 0x7980, 0xE268, 0x7981, 0x8BD6,
+	0x7984, 0x985C, 0x7985, 0x9154, 0x798A, 0xE253, 0x798D, 0x89D0,
+	0x798E, 0x92F5, 0x798F, 0x959F, 0x7994, 0xFB81, 0x799B, 0xFB83,
+	0x799D, 0xE254, 0x79A6, 0x8B9A, 0x79A7, 0xE255, 0x79AA, 0xE257,
+	0x79AE, 0xE258, 0x79B0, 0x9448, 0x79B3, 0xE259, 0x79B9, 0xE25A,
+	0x79BA, 0xE25B, 0x79BD, 0x8BD7, 0x79BE, 0x89D1, 0x79BF, 0x93C3,
+	0x79C0, 0x8F47, 0x79C1, 0x8E84, 0x79C9, 0xE25C, 0x79CB, 0x8F48,
+	0x79D1, 0x89C8, 0x79D2, 0x9562, 0x79D5, 0xE25D, 0x79D8, 0x94E9,
+	0x79DF, 0x9164, 0x79E1, 0xE260, 0x79E3, 0xE261, 0x79E4, 0x9489,
+	0x79E6, 0x9060, 0x79E7, 0xE25E, 0x79E9, 0x9281, 0x79EC, 0xE25F,
+	0x79F0, 0x8FCC, 0x79FB, 0x88DA, 0x7A00, 0x8B48, 0x7A08, 0xE262,
+	0x7A0B, 0x92F6, 0x7A0D, 0xE263, 0x7A0E, 0x90C5, 0x7A14, 0x96AB,
+	0x7A17, 0x9542, 0x7A18, 0xE264, 0x7A19, 0xE265, 0x7A1A, 0x9274,
+	0x7A1C, 0x97C5, 0x7A1F, 0xE267, 0x7A20, 0xE266, 0x7A2E, 0x8EED,
+	0x7A31, 0xE269, 0x7A32, 0x88EE, 0x7A37, 0xE26C, 0x7A3B, 0xE26A,
+	0x7A3C, 0x89D2, 0x7A3D, 0x8C6D, 0x7A3E, 0xE26B, 0x7A3F, 0x8D65,
+	0x7A40, 0x8D92, 0x7A42, 0x95E4, 0x7A43, 0xE26D, 0x7A46, 0x9673,
+	0x7A49, 0xE26F, 0x7A4D, 0x90CF, 0x7A4E, 0x896E, 0x7A4F, 0x89B8,
+	0x7A50, 0x88AA, 0x7A57, 0xE26E, 0x7A61, 0xE270, 0x7A62, 0xE271,
+	0x7A63, 0x8FF5, 0x7A69, 0xE272, 0x7A6B, 0x8A6E, 0x7A70, 0xE274,
+	0x7A74, 0x8C8A, 0x7A76, 0x8B86, 0x7A79, 0xE275, 0x7A7A, 0x8BF3,
+	0x7A7D, 0xE276, 0x7A7F, 0x90FA, 0x7A81, 0x93CB, 0x7A83, 0x90DE,
+	0x7A84, 0x8DF3, 0x7A88, 0xE277, 0x7A92, 0x9282, 0x7A93, 0x918B,
+	0x7A95, 0xE279, 0x7A96, 0xE27B, 0x7A97, 0xE278, 0x7A98, 0xE27A,
+	0x7A9F, 0x8C41, 0x7AA9, 0xE27C, 0x7AAA, 0x8C45, 0x7AAE, 0x8B87,
+	0x7AAF, 0x9771, 0x7AB0, 0xE27E, 0x7AB6, 0xE280, 0x7ABA, 0x894D,
+	0x7ABF, 0xE283, 0x7AC3, 0x8A96, 0x7AC4, 0xE282, 0x7AC5, 0xE281,
+	0x7AC7, 0xE285, 0x7AC8, 0xE27D, 0x7ACA, 0xE286, 0x7ACB, 0x97A7,
+	0x7ACD, 0xE287, 0x7ACF, 0xE288, 0x7AD1, 0xFB84, 0x7AD2, 0x9AF2,
+	0x7AD3, 0xE28A, 0x7AD5, 0xE289, 0x7AD9, 0xE28B, 0x7ADA, 0xE28C,
+	0x7ADC, 0x97B3, 0x7ADD, 0xE28D, 0x7ADF, 0xE8ED, 0x7AE0, 0x8FCD,
+	0x7AE1, 0xE28E, 0x7AE2, 0xE28F, 0x7AE3, 0x8F76, 0x7AE5, 0x93B6,
+	0x7AE6, 0xE290, 0x7AE7, 0xFB85, 0x7AEA, 0x9247, 0x7AEB, 0xFB87,
+	0x7AED, 0xE291, 0x7AEF, 0x925B, 0x7AF0, 0xE292, 0x7AF6, 0x8BA3,
+	0x7AF8, 0x995E, 0x7AF9, 0x927C, 0x7AFA, 0x8EB1, 0x7AFF, 0x8AC6,
+	0x7B02, 0xE293, 0x7B04, 0xE2A0, 0x7B06, 0xE296, 0x7B08, 0x8B88,
+	0x7B0A, 0xE295, 0x7B0B, 0xE2A2, 0x7B0F, 0xE294, 0x7B11, 0x8FCE,
+	0x7B18, 0xE298, 0x7B19, 0xE299, 0x7B1B, 0x934A, 0x7B1E, 0xE29A,
+	0x7B20, 0x8A7D, 0x7B25, 0x9079, 0x7B26, 0x9584, 0x7B28, 0xE29C,
+	0x7B2C, 0x91E6, 0x7B33, 0xE297, 0x7B35, 0xE29B, 0x7B36, 0xE29D,
+	0x7B39, 0x8DF9, 0x7B45, 0xE2A4, 0x7B46, 0x954D, 0x7B48, 0x94A4,
+	0x7B49, 0x9399, 0x7B4B, 0x8BD8, 0x7B4C, 0xE2A3, 0x7B4D, 0xE2A1,
+	0x7B4F, 0x94B3, 0x7B50, 0xE29E, 0x7B51, 0x927D, 0x7B52, 0x939B,
+	0x7B54, 0x939A, 0x7B56, 0x8DF4, 0x7B5D, 0xE2B6, 0x7B65, 0xE2A6,
+	0x7B67, 0xE2A8, 0x7B6C, 0xE2AB, 0x7B6E, 0xE2AC, 0x7B70, 0xE2A9,
+	0x7B71, 0xE2AA, 0x7B74, 0xE2A7, 0x7B75, 0xE2A5, 0x7B7A, 0xE29F,
+	0x7B86, 0x95CD, 0x7B87, 0x89D3, 0x7B8B, 0xE2B3, 0x7B8D, 0xE2B0,
+	0x7B8F, 0xE2B5, 0x7B92, 0xE2B4, 0x7B94, 0x9493, 0x7B95, 0x96A5,
+	0x7B97, 0x8E5A, 0x7B98, 0xE2AE, 0x7B99, 0xE2B7, 0x7B9A, 0xE2B2,
+	0x7B9C, 0xE2B1, 0x7B9D, 0xE2AD, 0x7B9E, 0xFB88, 0x7B9F, 0xE2AF,
+	0x7BA1, 0x8AC7, 0x7BAA, 0x925C, 0x7BAD, 0x90FB, 0x7BB1, 0x94A0,
+	0x7BB4, 0xE2BC, 0x7BB8, 0x94A2, 0x7BC0, 0x90DF, 0x7BC1, 0xE2B9,
+	0x7BC4, 0x94CD, 0x7BC6, 0xE2BD, 0x7BC7, 0x95D1, 0x7BC9, 0x927A,
+	0x7BCB, 0xE2B8, 0x7BCC, 0xE2BA, 0x7BCF, 0xE2BB, 0x7BDD, 0xE2BE,
+	0x7BE0, 0x8EC2, 0x7BE4, 0x93C4, 0x7BE5, 0xE2C3, 0x7BE6, 0xE2C2,
+	0x7BE9, 0xE2BF, 0x7BED, 0x9855, 0x7BF3, 0xE2C8, 0x7BF6, 0xE2CC,
+	0x7BF7, 0xE2C9, 0x7C00, 0xE2C5, 0x7C07, 0xE2C6, 0x7C0D, 0xE2CB,
+	0x7C11, 0xE2C0, 0x7C12, 0x99D3, 0x7C13, 0xE2C7, 0x7C14, 0xE2C1,
+	0x7C17, 0xE2CA, 0x7C1F, 0xE2D0, 0x7C21, 0x8AC8, 0x7C23, 0xE2CD,
+	0x7C27, 0xE2CE, 0x7C2A, 0xE2CF, 0x7C2B, 0xE2D2, 0x7C37, 0xE2D1,
+	0x7C38, 0x94F4, 0x7C3D, 0xE2D3, 0x7C3E, 0x97FA, 0x7C3F, 0x95EB,
+	0x7C40, 0xE2D8, 0x7C43, 0xE2D5, 0x7C4C, 0xE2D4, 0x7C4D, 0x90D0,
+	0x7C4F, 0xE2D7, 0x7C50, 0xE2D9, 0x7C54, 0xE2D6, 0x7C56, 0xE2DD,
+	0x7C58, 0xE2DA, 0x7C5F, 0xE2DB, 0x7C60, 0xE2C4, 0x7C64, 0xE2DC,
+	0x7C65, 0xE2DE, 0x7C6C, 0xE2DF, 0x7C73, 0x95C4, 0x7C75, 0xE2E0,
+	0x7C7E, 0x96E0, 0x7C81, 0x8BCC, 0x7C82, 0x8C48, 0x7C83, 0xE2E1,
+	0x7C89, 0x95B2, 0x7C8B, 0x9088, 0x7C8D, 0x96AE, 0x7C90, 0xE2E2,
+	0x7C92, 0x97B1, 0x7C95, 0x9494, 0x7C97, 0x9165, 0x7C98, 0x9453,
+	0x7C9B, 0x8F6C, 0x7C9F, 0x88BE, 0x7CA1, 0xE2E7, 0x7CA2, 0xE2E5,
+	0x7CA4, 0xE2E3, 0x7CA5, 0x8A9F, 0x7CA7, 0x8FCF, 0x7CA8, 0xE2E8,
+	0x7CAB, 0xE2E6, 0x7CAD, 0xE2E4, 0x7CAE, 0xE2EC, 0x7CB1, 0xE2EB,
+	0x7CB2, 0xE2EA, 0x7CB3, 0xE2E9, 0x7CB9, 0xE2ED, 0x7CBD, 0xE2EE,
+	0x7CBE, 0x90B8, 0x7CC0, 0xE2EF, 0x7CC2, 0xE2F1, 0x7CC5, 0xE2F0,
+	0x7CCA, 0x8CD0, 0x7CCE, 0x9157, 0x7CD2, 0xE2F3, 0x7CD6, 0x939C,
+	0x7CD8, 0xE2F2, 0x7CDC, 0xE2F4, 0x7CDE, 0x95B3, 0x7CDF, 0x918C,
+	0x7CE0, 0x8D66, 0x7CE2, 0xE2F5, 0x7CE7, 0x97C6, 0x7CEF, 0xE2F7,
+	0x7CF2, 0xE2F8, 0x7CF4, 0xE2F9, 0x7CF6, 0xE2FA, 0x7CF8, 0x8E85,
+	0x7CFA, 0xE2FB, 0x7CFB, 0x8C6E, 0x7CFE, 0x8B8A, 0x7D00, 0x8B49,
+	0x7D02, 0xE340, 0x7D04, 0x96F1, 0x7D05, 0x8D67, 0x7D06, 0xE2FC,
+	0x7D0A, 0xE343, 0x7D0B, 0x96E4, 0x7D0D, 0x945B, 0x7D10, 0x9552,
+	0x7D14, 0x8F83, 0x7D15, 0xE342, 0x7D17, 0x8ED1, 0x7D18, 0x8D68,
+	0x7D19, 0x8E86, 0x7D1A, 0x8B89, 0x7D1B, 0x95B4, 0x7D1C, 0xE341,
+	0x7D20, 0x9166, 0x7D21, 0x9661, 0x7D22, 0x8DF5, 0x7D2B, 0x8E87,
+	0x7D2C, 0x92DB, 0x7D2E, 0xE346, 0x7D2F, 0x97DD, 0x7D30, 0x8DD7,
+	0x7D32, 0xE347, 0x7D33, 0x9061, 0x7D35, 0xE349, 0x7D39, 0x8FD0,
+	0x7D3A, 0x8DAE, 0x7D3F, 0xE348, 0x7D42, 0x8F49, 0x7D43, 0x8CBC,
+	0x7D44, 0x9167, 0x7D45, 0xE344, 0x7D46, 0xE34A, 0x7D48, 0xFB8A,
+	0x7D4B, 0xE345, 0x7D4C, 0x8C6F, 0x7D4E, 0xE34D, 0x7D4F, 0xE351,
+	0x7D50, 0x8C8B, 0x7D56, 0xE34C, 0x7D5B, 0xE355, 0x7D5C, 0xFB8B,
+	0x7D5E, 0x8D69, 0x7D61, 0x978D, 0x7D62, 0x88BA, 0x7D63, 0xE352,
+	0x7D66, 0x8B8B, 0x7D68, 0xE34F, 0x7D6E, 0xE350, 0x7D71, 0x939D,
+	0x7D72, 0xE34E, 0x7D73, 0xE34B, 0x7D75, 0x8A47, 0x7D76, 0x90E2,
+	0x7D79, 0x8CA6, 0x7D7D, 0xE357, 0x7D89, 0xE354, 0x7D8F, 0xE356,
+	0x7D93, 0xE353, 0x7D99, 0x8C70, 0x7D9A, 0x91B1, 0x7D9B, 0xE358,
+	0x7D9C, 0x918E, 0x7D9F, 0xE365, 0x7DA0, 0xFB8D, 0x7DA2, 0xE361,
+	0x7DA3, 0xE35B, 0x7DAB, 0xE35F, 0x7DAC, 0x8EF8, 0x7DAD, 0x88DB,
+	0x7DAE, 0xE35A, 0x7DAF, 0xE362, 0x7DB0, 0xE366, 0x7DB1, 0x8D6A,
+	0x7DB2, 0x96D4, 0x7DB4, 0x92D4, 0x7DB5, 0xE35C, 0x7DB7, 0xFB8C,
+	0x7DB8, 0xE364, 0x7DBA, 0xE359, 0x7DBB, 0x925D, 0x7DBD, 0xE35E,
+	0x7DBE, 0x88BB, 0x7DBF, 0x96C8, 0x7DC7, 0xE35D, 0x7DCA, 0x8BD9,
+	0x7DCB, 0x94EA, 0x7DCF, 0x918D, 0x7DD1, 0x97CE, 0x7DD2, 0x8F8F,
+	0x7DD5, 0xE38E, 0x7DD6, 0xFB8E, 0x7DD8, 0xE367, 0x7DDA, 0x90FC,
+	0x7DDC, 0xE363, 0x7DDD, 0xE368, 0x7DDE, 0xE36A, 0x7DE0, 0x92F7,
+	0x7DE1, 0xE36D, 0x7DE4, 0xE369, 0x7DE8, 0x95D2, 0x7DE9, 0x8AC9,
+	0x7DEC, 0x96C9, 0x7DEF, 0x88DC, 0x7DF2, 0xE36C, 0x7DF4, 0x97FB,
+	0x7DFB, 0xE36B, 0x7E01, 0x898F, 0x7E04, 0x93EA, 0x7E05, 0xE36E,
+	0x7E09, 0xE375, 0x7E0A, 0xE36F, 0x7E0B, 0xE376, 0x7E12, 0xE372,
+	0x7E1B, 0x949B, 0x7E1E, 0x8EC8, 0x7E1F, 0xE374, 0x7E21, 0xE371,
+	0x7E22, 0xE377, 0x7E23, 0xE370, 0x7E26, 0x8F63, 0x7E2B, 0x9644,
+	0x7E2E, 0x8F6B, 0x7E31, 0xE373, 0x7E32, 0xE380, 0x7E35, 0xE37B,
+	0x7E37, 0xE37E, 0x7E39, 0xE37C, 0x7E3A, 0xE381, 0x7E3B, 0xE37A,
+	0x7E3D, 0xE360, 0x7E3E, 0x90D1, 0x7E41, 0x94C9, 0x7E43, 0xE37D,
+	0x7E46, 0xE378, 0x7E4A, 0x9140, 0x7E4B, 0x8C71, 0x7E4D, 0x8F4A,
+	0x7E52, 0xFB8F, 0x7E54, 0x9044, 0x7E55, 0x9155, 0x7E56, 0xE384,
+	0x7E59, 0xE386, 0x7E5A, 0xE387, 0x7E5D, 0xE383, 0x7E5E, 0xE385,
+	0x7E66, 0xE379, 0x7E67, 0xE382, 0x7E69, 0xE38A, 0x7E6A, 0xE389,
+	0x7E6D, 0x969A, 0x7E70, 0x8C4A, 0x7E79, 0xE388, 0x7E7B, 0xE38C,
+	0x7E7C, 0xE38B, 0x7E7D, 0xE38F, 0x7E7F, 0xE391, 0x7E82, 0x8E5B,
+	0x7E83, 0xE38D, 0x7E88, 0xE392, 0x7E89, 0xE393, 0x7E8A, 0xFA5C,
+	0x7E8C, 0xE394, 0x7E8E, 0xE39A, 0x7E8F, 0x935A, 0x7E90, 0xE396,
+	0x7E92, 0xE395, 0x7E93, 0xE397, 0x7E94, 0xE398, 0x7E96, 0xE399,
+	0x7E9B, 0xE39B, 0x7E9C, 0xE39C, 0x7F36, 0x8ACA, 0x7F38, 0xE39D,
+	0x7F3A, 0xE39E, 0x7F45, 0xE39F, 0x7F47, 0xFB90, 0x7F4C, 0xE3A0,
+	0x7F4D, 0xE3A1, 0x7F4E, 0xE3A2, 0x7F50, 0xE3A3, 0x7F51, 0xE3A4,
+	0x7F54, 0xE3A6, 0x7F55, 0xE3A5, 0x7F58, 0xE3A7, 0x7F5F, 0xE3A8,
+	0x7F60, 0xE3A9, 0x7F67, 0xE3AC, 0x7F68, 0xE3AA, 0x7F69, 0xE3AB,
+	0x7F6A, 0x8DDF, 0x7F6B, 0x8C72, 0x7F6E, 0x9275, 0x7F70, 0x94B1,
+	0x7F72, 0x8F90, 0x7F75, 0x946C, 0x7F77, 0x94EB, 0x7F78, 0xE3AD,
+	0x7F79, 0x9CEB, 0x7F82, 0xE3AE, 0x7F83, 0xE3B0, 0x7F85, 0x9785,
+	0x7F86, 0xE3AF, 0x7F87, 0xE3B2, 0x7F88, 0xE3B1, 0x7F8A, 0x9772,
+	0x7F8C, 0xE3B3, 0x7F8E, 0x94FC, 0x7F94, 0xE3B4, 0x7F9A, 0xE3B7,
+	0x7F9D, 0xE3B6, 0x7F9E, 0xE3B5, 0x7FA1, 0xFB91, 0x7FA3, 0xE3B8,
+	0x7FA4, 0x8C51, 0x7FA8, 0x9141, 0x7FA9, 0x8B60, 0x7FAE, 0xE3BC,
+	0x7FAF, 0xE3B9, 0x7FB2, 0xE3BA, 0x7FB6, 0xE3BD, 0x7FB8, 0xE3BE,
+	0x7FB9, 0xE3BB, 0x7FBD, 0x8948, 0x7FC1, 0x89A5, 0x7FC5, 0xE3C0,
+	0x7FC6, 0xE3C1, 0x7FCA, 0xE3C2, 0x7FCC, 0x9782, 0x7FD2, 0x8F4B,
+	0x7FD4, 0xE3C4, 0x7FD5, 0xE3C3, 0x7FE0, 0x9089, 0x7FE1, 0xE3C5,
+	0x7FE6, 0xE3C6, 0x7FE9, 0xE3C7, 0x7FEB, 0x8AE3, 0x7FF0, 0x8ACB,
+	0x7FF3, 0xE3C8, 0x7FF9, 0xE3C9, 0x7FFB, 0x967C, 0x7FFC, 0x9783,
+	0x8000, 0x9773, 0x8001, 0x9856, 0x8003, 0x8D6C, 0x8004, 0xE3CC,
+	0x8005, 0x8ED2, 0x8006, 0xE3CB, 0x800B, 0xE3CD, 0x800C, 0x8EA7,
+	0x8010, 0x91CF, 0x8012, 0xE3CE, 0x8015, 0x8D6B, 0x8017, 0x96D5,
+	0x8018, 0xE3CF, 0x8019, 0xE3D0, 0x801C, 0xE3D1, 0x8021, 0xE3D2,
+	0x8028, 0xE3D3, 0x8033, 0x8EA8, 0x8036, 0x96EB, 0x803B, 0xE3D5,
+	0x803D, 0x925E, 0x803F, 0xE3D4, 0x8046, 0xE3D7, 0x804A, 0xE3D6,
+	0x8052, 0xE3D8, 0x8056, 0x90B9, 0x8058, 0xE3D9, 0x805A, 0xE3DA,
+	0x805E, 0x95B7, 0x805F, 0xE3DB, 0x8061, 0x918F, 0x8062, 0xE3DC,
+	0x8068, 0xE3DD, 0x806F, 0x97FC, 0x8070, 0xE3E0, 0x8072, 0xE3DF,
+	0x8073, 0xE3DE, 0x8074, 0x92AE, 0x8076, 0xE3E1, 0x8077, 0x9045,
+	0x8079, 0xE3E2, 0x807D, 0xE3E3, 0x807E, 0x9857, 0x807F, 0xE3E4,
+	0x8084, 0xE3E5, 0x8085, 0xE3E7, 0x8086, 0xE3E6, 0x8087, 0x94A3,
+	0x8089, 0x93F7, 0x808B, 0x985D, 0x808C, 0x94A7, 0x8093, 0xE3E9,
+	0x8096, 0x8FD1, 0x8098, 0x9549, 0x809A, 0xE3EA, 0x809B, 0xE3E8,
+	0x809D, 0x8ACC, 0x80A1, 0x8CD2, 0x80A2, 0x8E88, 0x80A5, 0x94EC,
+	0x80A9, 0x8CA8, 0x80AA, 0x9662, 0x80AC, 0xE3ED, 0x80AD, 0xE3EB,
+	0x80AF, 0x8D6D, 0x80B1, 0x8D6E, 0x80B2, 0x88E7, 0x80B4, 0x8DE6,
+	0x80BA, 0x9478, 0x80C3, 0x88DD, 0x80C4, 0xE3F2, 0x80C6, 0x925F,
+	0x80CC, 0x9477, 0x80CE, 0x91D9, 0x80D6, 0xE3F4, 0x80D9, 0xE3F0,
+	0x80DA, 0xE3F3, 0x80DB, 0xE3EE, 0x80DD, 0xE3F1, 0x80DE, 0x9645,
+	0x80E1, 0x8CD3, 0x80E4, 0x88FB, 0x80E5, 0xE3EF, 0x80EF, 0xE3F6,
+	0x80F1, 0xE3F7, 0x80F4, 0x93B7, 0x80F8, 0x8BB9, 0x80FC, 0xE445,
+	0x80FD, 0x945C, 0x8102, 0x8E89, 0x8105, 0x8BBA, 0x8106, 0x90C6,
+	0x8107, 0x9865, 0x8108, 0x96AC, 0x8109, 0xE3F5, 0x810A, 0x90D2,
+	0x811A, 0x8B72, 0x811B, 0xE3F8, 0x8123, 0xE3FA, 0x8129, 0xE3F9,
+	0x812F, 0xE3FB, 0x8131, 0x9245, 0x8133, 0x945D, 0x8139, 0x92AF,
+	0x813E, 0xE442, 0x8146, 0xE441, 0x814B, 0xE3FC, 0x814E, 0x9074,
+	0x8150, 0x9585, 0x8151, 0xE444, 0x8153, 0xE443, 0x8154, 0x8D6F,
+	0x8155, 0x9872, 0x815F, 0xE454, 0x8165, 0xE448, 0x8166, 0xE449,
+	0x816B, 0x8EEE, 0x816E, 0xE447, 0x8170, 0x8D98, 0x8171, 0xE446,
+	0x8174, 0xE44A, 0x8178, 0x92B0, 0x8179, 0x95A0, 0x817A, 0x9142,
+	0x817F, 0x91DA, 0x8180, 0xE44E, 0x8182, 0xE44F, 0x8183, 0xE44B,
+	0x8188, 0xE44C, 0x818A, 0xE44D, 0x818F, 0x8D70, 0x8193, 0xE455,
+	0x8195, 0xE451, 0x819A, 0x9586, 0x819C, 0x968C, 0x819D, 0x9547,
+	0x81A0, 0xE450, 0x81A3, 0xE453, 0x81A4, 0xE452, 0x81A8, 0x9663,
+	0x81A9, 0xE456, 0x81B0, 0xE457, 0x81B3, 0x9156, 0x81B5, 0xE458,
+	0x81B8, 0xE45A, 0x81BA, 0xE45E, 0x81BD, 0xE45B, 0x81BE, 0xE459,
+	0x81BF, 0x945E, 0x81C0, 0xE45C, 0x81C2, 0xE45D, 0x81C6, 0x89B0,
+	0x81C8, 0xE464, 0x81C9, 0xE45F, 0x81CD, 0xE460, 0x81D1, 0xE461,
+	0x81D3, 0x919F, 0x81D8, 0xE463, 0x81D9, 0xE462, 0x81DA, 0xE465,
+	0x81DF, 0xE466, 0x81E0, 0xE467, 0x81E3, 0x9062, 0x81E5, 0x89E7,
+	0x81E7, 0xE468, 0x81E8, 0x97D5, 0x81EA, 0x8EA9, 0x81ED, 0x8F4C,
+	0x81F3, 0x8E8A, 0x81F4, 0x9276, 0x81FA, 0xE469, 0x81FB, 0xE46A,
+	0x81FC, 0x8950, 0x81FE, 0xE46B, 0x8201, 0xE46C, 0x8202, 0xE46D,
+	0x8205, 0xE46E, 0x8207, 0xE46F, 0x8208, 0x8BBB, 0x8209, 0x9DA8,
+	0x820A, 0xE470, 0x820C, 0x90E3, 0x820D, 0xE471, 0x820E, 0x8EC9,
+	0x8210, 0xE472, 0x8212, 0x98AE, 0x8216, 0xE473, 0x8217, 0x95DC,
+	0x8218, 0x8ADA, 0x821B, 0x9143, 0x821C, 0x8F77, 0x821E, 0x9591,
+	0x821F, 0x8F4D, 0x8229, 0xE474, 0x822A, 0x8D71, 0x822B, 0xE475,
+	0x822C, 0x94CA, 0x822E, 0xE484, 0x8233, 0xE477, 0x8235, 0x91C7,
+	0x8236, 0x9495, 0x8237, 0x8CBD, 0x8238, 0xE476, 0x8239, 0x9144,
+	0x8240, 0xE478, 0x8247, 0x92F8, 0x8258, 0xE47A, 0x8259, 0xE479,
+	0x825A, 0xE47C, 0x825D, 0xE47B, 0x825F, 0xE47D, 0x8262, 0xE480,
+	0x8264, 0xE47E, 0x8266, 0x8ACD, 0x8268, 0xE481, 0x826A, 0xE482,
+	0x826B, 0xE483, 0x826E, 0x8DAF, 0x826F, 0x97C7, 0x8271, 0xE485,
+	0x8272, 0x9046, 0x8276, 0x8990, 0x8277, 0xE486, 0x8278, 0xE487,
+	0x827E, 0xE488, 0x828B, 0x88F0, 0x828D, 0xE489, 0x8292, 0xE48A,
+	0x8299, 0x9587, 0x829D, 0x8EC5, 0x829F, 0xE48C, 0x82A5, 0x8A48,
+	0x82A6, 0x88B0, 0x82AB, 0xE48B, 0x82AC, 0xE48E, 0x82AD, 0x946D,
+	0x82AF, 0x9063, 0x82B1, 0x89D4, 0x82B3, 0x9646, 0x82B8, 0x8C7C,
+	0x82B9, 0x8BDA, 0x82BB, 0xE48D, 0x82BD, 0x89E8, 0x82C5, 0x8AA1,
+	0x82D1, 0x8991, 0x82D2, 0xE492, 0x82D3, 0x97E8, 0x82D4, 0x91DB,
+	0x82D7, 0x9563, 0x82D9, 0xE49E, 0x82DB, 0x89D5, 0x82DC, 0xE49C,
+	0x82DE, 0xE49A, 0x82DF, 0xE491, 0x82E1, 0xE48F, 0x82E3, 0xE490,
+	0x82E5, 0x8EE1, 0x82E6, 0x8BEA, 0x82E7, 0x9297, 0x82EB, 0x93CF,
+	0x82F1, 0x8970, 0x82F3, 0xE494, 0x82F4, 0xE493, 0x82F9, 0xE499,
+	0x82FA, 0xE495, 0x82FB, 0xE498, 0x8301, 0xFB93, 0x8302, 0x96CE,
+	0x8303, 0xE497, 0x8304, 0x89D6, 0x8305, 0x8A9D, 0x8306, 0xE49B,
+	0x8309, 0xE49D, 0x830E, 0x8C73, 0x8316, 0xE4A1, 0x8317, 0xE4AA,
+	0x8318, 0xE4AB, 0x831C, 0x88A9, 0x8323, 0xE4B2, 0x8328, 0x88EF,
+	0x832B, 0xE4A9, 0x832F, 0xE4A8, 0x8331, 0xE4A3, 0x8332, 0xE4A2,
+	0x8334, 0xE4A0, 0x8335, 0xE49F, 0x8336, 0x9283, 0x8338, 0x91F9,
+	0x8339, 0xE4A5, 0x8340, 0xE4A4, 0x8345, 0xE4A7, 0x8349, 0x9190,
+	0x834A, 0x8C74, 0x834F, 0x8960, 0x8350, 0xE4A6, 0x8352, 0x8D72,
+	0x8358, 0x9191, 0x8362, 0xFB94, 0x8373, 0xE4B8, 0x8375, 0xE4B9,
+	0x8377, 0x89D7, 0x837B, 0x89AC, 0x837C, 0xE4B6, 0x837F, 0xFB95,
+	0x8385, 0xE4AC, 0x8387, 0xE4B4, 0x8389, 0xE4BB, 0x838A, 0xE4B5,
+	0x838E, 0xE4B3, 0x8393, 0xE496, 0x8396, 0xE4B1, 0x839A, 0xE4AD,
+	0x839E, 0x8ACE, 0x839F, 0xE4AF, 0x83A0, 0xE4BA, 0x83A2, 0xE4B0,
+	0x83A8, 0xE4BC, 0x83AA, 0xE4AE, 0x83AB, 0x949C, 0x83B1, 0x9789,
+	0x83B5, 0xE4B7, 0x83BD, 0xE4CD, 0x83C1, 0xE4C5, 0x83C5, 0x909B,
+	0x83C7, 0xFB96, 0x83CA, 0x8B65, 0x83CC, 0x8BDB, 0x83CE, 0xE4C0,
+	0x83D3, 0x89D9, 0x83D6, 0x8FD2, 0x83D8, 0xE4C3, 0x83DC, 0x8DD8,
+	0x83DF, 0x9370, 0x83E0, 0xE4C8, 0x83E9, 0x95EC, 0x83EB, 0xE4BF,
+	0x83EF, 0x89D8, 0x83F0, 0x8CD4, 0x83F1, 0x9548, 0x83F2, 0xE4C9,
+	0x83F4, 0xE4BD, 0x83F6, 0xFB97, 0x83F7, 0xE4C6, 0x83FB, 0xE4D0,
+	0x83FD, 0xE4C1, 0x8403, 0xE4C2, 0x8404, 0x93B8, 0x8407, 0xE4C7,
+	0x840B, 0xE4C4, 0x840C, 0x9647, 0x840D, 0xE4CA, 0x840E, 0x88DE,
+	0x8413, 0xE4BE, 0x8420, 0xE4CC, 0x8422, 0xE4CB, 0x8429, 0x948B,
+	0x842A, 0xE4D2, 0x842C, 0xE4DD, 0x8431, 0x8A9E, 0x8435, 0xE4E0,
+	0x8438, 0xE4CE, 0x843C, 0xE4D3, 0x843D, 0x978E, 0x8446, 0xE4DC,
+	0x8448, 0xFB98, 0x8449, 0x9774, 0x844E, 0x97A8, 0x8457, 0x9298,
+	0x845B, 0x8A8B, 0x8461, 0x9592, 0x8462, 0xE4E2, 0x8463, 0x939F,
+	0x8466, 0x88AF, 0x8469, 0xE4DB, 0x846B, 0xE4D7, 0x846C, 0x9192,
+	0x846D, 0xE4D1, 0x846E, 0xE4D9, 0x846F, 0xE4DE, 0x8471, 0x944B,
+	0x8475, 0x88A8, 0x8477, 0xE4D6, 0x8479, 0xE4DF, 0x847A, 0x9598,
+	0x8482, 0xE4DA, 0x8484, 0xE4D5, 0x848B, 0x8FD3, 0x8490, 0x8F4E,
+	0x8494, 0x8EAA, 0x8499, 0x96D6, 0x849C, 0x9566, 0x849F, 0xE4E5,
+	0x84A1, 0xE4EE, 0x84AD, 0xE4D8, 0x84B2, 0x8A97, 0x84B4, 0xFB99,
+	0x84B8, 0x8FF6, 0x84B9, 0xE4E3, 0x84BB, 0xE4E8, 0x84BC, 0x9193,
+	0x84BF, 0xE4E4, 0x84C1, 0xE4EB, 0x84C4, 0x927E, 0x84C6, 0xE4EC,
+	0x84C9, 0x9775, 0x84CA, 0xE4E1, 0x84CB, 0x8A57, 0x84CD, 0xE4E7,
+	0x84D0, 0xE4EA, 0x84D1, 0x96AA, 0x84D6, 0xE4ED, 0x84D9, 0xE4E6,
+	0x84DA, 0xE4E9, 0x84DC, 0xFA60, 0x84EC, 0x9648, 0x84EE, 0x9840,
+	0x84F4, 0xE4F1, 0x84FC, 0xE4F8, 0x84FF, 0xE4F0, 0x8500, 0x8EC1,
+	0x8506, 0xE4CF, 0x8511, 0x95CC, 0x8513, 0x96A0, 0x8514, 0xE4F7,
+	0x8515, 0xE4F6, 0x8517, 0xE4F2, 0x8518, 0xE4F3, 0x851A, 0x8955,
+	0x851F, 0xE4F5, 0x8521, 0xE4EF, 0x8526, 0x92D3, 0x852C, 0xE4F4,
+	0x852D, 0x88FC, 0x8535, 0x91A0, 0x853D, 0x95C1, 0x8540, 0xE4F9,
+	0x8541, 0xE540, 0x8543, 0x94D7, 0x8548, 0xE4FC, 0x8549, 0x8FD4,
+	0x854A, 0x8EC7, 0x854B, 0xE542, 0x854E, 0x8BBC, 0x8553, 0xFB9A,
+	0x8555, 0xE543, 0x8557, 0x9599, 0x8558, 0xE4FB, 0x8559, 0xFB9B,
+	0x855A, 0xE4D4, 0x8563, 0xE4FA, 0x8568, 0x986E, 0x8569, 0x93A0,
+	0x856A, 0x9593, 0x856B, 0xFB9C, 0x856D, 0xE54A, 0x8577, 0xE550,
+	0x857E, 0xE551, 0x8580, 0xE544, 0x8584, 0x9496, 0x8587, 0xE54E,
+	0x8588, 0xE546, 0x858A, 0xE548, 0x8590, 0xE552, 0x8591, 0xE547,
+	0x8594, 0xE54B, 0x8597, 0x8992, 0x8599, 0x93E3, 0x859B, 0xE54C,
+	0x859C, 0xE54F, 0x85A4, 0xE545, 0x85A6, 0x9145, 0x85A8, 0xE549,
+	0x85A9, 0x8E46, 0x85AA, 0x9064, 0x85AB, 0x8C4F, 0x85AC, 0x96F2,
+	0x85AE, 0x96F7, 0x85AF, 0x8F92, 0x85B0, 0xFB9E, 0x85B9, 0xE556,
+	0x85BA, 0xE554, 0x85C1, 0x986D, 0x85C9, 0xE553, 0x85CD, 0x9795,
+	0x85CF, 0xE555, 0x85D0, 0xE557, 0x85D5, 0xE558, 0x85DC, 0xE55B,
+	0x85DD, 0xE559, 0x85E4, 0x93A1, 0x85E5, 0xE55A, 0x85E9, 0x94CB,
+	0x85EA, 0xE54D, 0x85F7, 0x8F93, 0x85F9, 0xE55C, 0x85FA, 0xE561,
+	0x85FB, 0x9194, 0x85FE, 0xE560, 0x8602, 0xE541, 0x8606, 0xE562,
+	0x8607, 0x9168, 0x860A, 0xE55D, 0x860B, 0xE55F, 0x8613, 0xE55E,
+	0x8616, 0x9F50, 0x8617, 0x9F41, 0x861A, 0xE564, 0x8622, 0xE563,
+	0x862D, 0x9796, 0x862F, 0xE1BA, 0x8630, 0xE565, 0x863F, 0xE566,
+	0x864D, 0xE567, 0x864E, 0x8CD5, 0x8650, 0x8B73, 0x8654, 0xE569,
+	0x8655, 0x997C, 0x865A, 0x8B95, 0x865C, 0x97B8, 0x865E, 0x8BF1,
+	0x865F, 0xE56A, 0x8667, 0xE56B, 0x866B, 0x928E, 0x8671, 0xE56C,
+	0x8679, 0x93F8, 0x867B, 0x88B8, 0x868A, 0x89E1, 0x868B, 0xE571,
+	0x868C, 0xE572, 0x8693, 0xE56D, 0x8695, 0x8E5C, 0x86A3, 0xE56E,
+	0x86A4, 0x9461, 0x86A9, 0xE56F, 0x86AA, 0xE570, 0x86AB, 0xE57A,
+	0x86AF, 0xE574, 0x86B0, 0xE577, 0x86B6, 0xE573, 0x86C4, 0xE575,
+	0x86C6, 0xE576, 0x86C7, 0x8ED6, 0x86C9, 0xE578, 0x86CB, 0x9260,
+	0x86CD, 0x8C75, 0x86CE, 0x8A61, 0x86D4, 0xE57B, 0x86D9, 0x8A5E,
+	0x86DB, 0xE581, 0x86DE, 0xE57C, 0x86DF, 0xE580, 0x86E4, 0x94B8,
+	0x86E9, 0xE57D, 0x86EC, 0xE57E, 0x86ED, 0x9567, 0x86EE, 0x94D8,
+	0x86EF, 0xE582, 0x86F8, 0x91FB, 0x86F9, 0xE58C, 0x86FB, 0xE588,
+	0x86FE, 0x89E9, 0x8700, 0xE586, 0x8702, 0x9649, 0x8703, 0xE587,
+	0x8706, 0xE584, 0x8708, 0xE585, 0x8709, 0xE58A, 0x870A, 0xE58D,
+	0x870D, 0xE58B, 0x8711, 0xE589, 0x8712, 0xE583, 0x8718, 0x9277,
+	0x871A, 0xE594, 0x871C, 0x96A8, 0x8725, 0xE592, 0x8729, 0xE593,
+	0x8734, 0xE58E, 0x8737, 0xE590, 0x873B, 0xE591, 0x873F, 0xE58F,
+	0x8749, 0x90E4, 0x874B, 0x9858, 0x874C, 0xE598, 0x874E, 0xE599,
+	0x8753, 0xE59F, 0x8755, 0x9049, 0x8757, 0xE59B, 0x8759, 0xE59E,
+	0x875F, 0xE596, 0x8760, 0xE595, 0x8763, 0xE5A0, 0x8766, 0x89DA,
+	0x8768, 0xE59C, 0x876A, 0xE5A1, 0x876E, 0xE59D, 0x8774, 0xE59A,
+	0x8776, 0x92B1, 0x8778, 0xE597, 0x877F, 0x9488, 0x8782, 0xE5A5,
+	0x878D, 0x975A, 0x879F, 0xE5A4, 0x87A2, 0xE5A3, 0x87AB, 0xE5AC,
+	0x87AF, 0xE5A6, 0x87B3, 0xE5AE, 0x87BA, 0x9786, 0x87BB, 0xE5B1,
+	0x87BD, 0xE5A8, 0x87C0, 0xE5A9, 0x87C4, 0xE5AD, 0x87C6, 0xE5B0,
+	0x87C7, 0xE5AF, 0x87CB, 0xE5A7, 0x87D0, 0xE5AA, 0x87D2, 0xE5BB,
+	0x87E0, 0xE5B4, 0x87EF, 0xE5B2, 0x87F2, 0xE5B3, 0x87F6, 0xE5B8,
+	0x87F7, 0xE5B9, 0x87F9, 0x8A49, 0x87FB, 0x8B61, 0x87FE, 0xE5B7,
+	0x8805, 0xE5A2, 0x8807, 0xFBA1, 0x880D, 0xE5B6, 0x880E, 0xE5BA,
+	0x880F, 0xE5B5, 0x8811, 0xE5BC, 0x8815, 0xE5BE, 0x8816, 0xE5BD,
+	0x8821, 0xE5C0, 0x8822, 0xE5BF, 0x8823, 0xE579, 0x8827, 0xE5C4,
+	0x8831, 0xE5C1, 0x8836, 0xE5C2, 0x8839, 0xE5C3, 0x883B, 0xE5C5,
+	0x8840, 0x8C8C, 0x8842, 0xE5C7, 0x8844, 0xE5C6, 0x8846, 0x8F4F,
+	0x884C, 0x8D73, 0x884D, 0x9FA5, 0x8852, 0xE5C8, 0x8853, 0x8F70,
+	0x8857, 0x8A58, 0x8859, 0xE5C9, 0x885B, 0x8971, 0x885D, 0x8FD5,
+	0x885E, 0xE5CA, 0x8861, 0x8D74, 0x8862, 0xE5CB, 0x8863, 0x88DF,
+	0x8868, 0x955C, 0x886B, 0xE5CC, 0x8870, 0x908A, 0x8872, 0xE5D3,
+	0x8875, 0xE5D0, 0x8877, 0x928F, 0x887D, 0xE5D1, 0x887E, 0xE5CE,
+	0x887F, 0x8BDC, 0x8881, 0xE5CD, 0x8882, 0xE5D4, 0x8888, 0x8C55,
+	0x888B, 0x91DC, 0x888D, 0xE5DA, 0x8892, 0xE5D6, 0x8896, 0x91B3,
+	0x8897, 0xE5D5, 0x8899, 0xE5D8, 0x889E, 0xE5CF, 0x88A2, 0xE5D9,
+	0x88A4, 0xE5DB, 0x88AB, 0x94ED, 0x88AE, 0xE5D7, 0x88B0, 0xE5DC,
+	0x88B1, 0xE5DE, 0x88B4, 0x8CD1, 0x88B5, 0xE5D2, 0x88B7, 0x88BF,
+	0x88BF, 0xE5DD, 0x88C1, 0x8DD9, 0x88C2, 0x97F4, 0x88C3, 0xE5DF,
+	0x88C4, 0xE5E0, 0x88C5, 0x9195, 0x88CF, 0x97A0, 0x88D4, 0xE5E1,
+	0x88D5, 0x9754, 0x88D8, 0xE5E2, 0x88D9, 0xE5E3, 0x88DC, 0x95E2,
+	0x88DD, 0xE5E4, 0x88DF, 0x8DBE, 0x88E1, 0x97A1, 0x88E8, 0xE5E9,
+	0x88F2, 0xE5EA, 0x88F3, 0x8FD6, 0x88F4, 0xE5E8, 0x88F5, 0xFBA2,
+	0x88F8, 0x9787, 0x88F9, 0xE5E5, 0x88FC, 0xE5E7, 0x88FD, 0x90BB,
+	0x88FE, 0x909E, 0x8902, 0xE5E6, 0x8904, 0xE5EB, 0x8907, 0x95A1,
+	0x890A, 0xE5ED, 0x890C, 0xE5EC, 0x8910, 0x8A8C, 0x8912, 0x964A,
+	0x8913, 0xE5EE, 0x891C, 0xFA5D, 0x891D, 0xE5FA, 0x891E, 0xE5F0,
+	0x8925, 0xE5F1, 0x892A, 0xE5F2, 0x892B, 0xE5F3, 0x8936, 0xE5F7,
+	0x8938, 0xE5F8, 0x893B, 0xE5F6, 0x8941, 0xE5F4, 0x8943, 0xE5EF,
+	0x8944, 0xE5F5, 0x894C, 0xE5F9, 0x894D, 0xE8B5, 0x8956, 0x89A6,
+	0x895E, 0xE5FC, 0x895F, 0x8BDD, 0x8960, 0xE5FB, 0x8964, 0xE641,
+	0x8966, 0xE640, 0x896A, 0xE643, 0x896D, 0xE642, 0x896F, 0xE644,
+	0x8972, 0x8F50, 0x8974, 0xE645, 0x8977, 0xE646, 0x897E, 0xE647,
+	0x897F, 0x90BC, 0x8981, 0x9776, 0x8983, 0xE648, 0x8986, 0x95A2,
+	0x8987, 0x9465, 0x8988, 0xE649, 0x898A, 0xE64A, 0x898B, 0x8CA9,
+	0x898F, 0x8B4B, 0x8993, 0xE64B, 0x8996, 0x8E8B, 0x8997, 0x9460,
+	0x8998, 0xE64C, 0x899A, 0x8A6F, 0x89A1, 0xE64D, 0x89A6, 0xE64F,
+	0x89A7, 0x9797, 0x89A9, 0xE64E, 0x89AA, 0x9065, 0x89AC, 0xE650,
+	0x89AF, 0xE651, 0x89B2, 0xE652, 0x89B3, 0x8ACF, 0x89BA, 0xE653,
+	0x89BD, 0xE654, 0x89BF, 0xE655, 0x89C0, 0xE656, 0x89D2, 0x8A70,
+	0x89DA, 0xE657, 0x89DC, 0xE658, 0x89DD, 0xE659, 0x89E3, 0x89F0,
+	0x89E6, 0x9047, 0x89E7, 0xE65A, 0x89F4, 0xE65B, 0x89F8, 0xE65C,
+	0x8A00, 0x8CBE, 0x8A02, 0x92F9, 0x8A03, 0xE65D, 0x8A08, 0x8C76,
+	0x8A0A, 0x9075, 0x8A0C, 0xE660, 0x8A0E, 0x93A2, 0x8A10, 0xE65F,
+	0x8A12, 0xFBA3, 0x8A13, 0x8C50, 0x8A16, 0xE65E, 0x8A17, 0x91F5,
+	0x8A18, 0x8B4C, 0x8A1B, 0xE661, 0x8A1D, 0xE662, 0x8A1F, 0x8FD7,
+	0x8A23, 0x8C8D, 0x8A25, 0xE663, 0x8A2A, 0x964B, 0x8A2D, 0x90DD,
+	0x8A31, 0x8B96, 0x8A33, 0x96F3, 0x8A34, 0x9169, 0x8A36, 0xE664,
+	0x8A37, 0xFBA4, 0x8A3A, 0x9066, 0x8A3B, 0x9290, 0x8A3C, 0x8FD8,
+	0x8A41, 0xE665, 0x8A46, 0xE668, 0x8A48, 0xE669, 0x8A50, 0x8DBC,
+	0x8A51, 0x91C0, 0x8A52, 0xE667, 0x8A54, 0x8FD9, 0x8A55, 0x955D,
+	0x8A5B, 0xE666, 0x8A5E, 0x8E8C, 0x8A60, 0x8972, 0x8A62, 0xE66D,
+	0x8A63, 0x8C77, 0x8A66, 0x8E8E, 0x8A69, 0x8E8D, 0x8A6B, 0x986C,
+	0x8A6C, 0xE66C, 0x8A6D, 0xE66B, 0x8A6E, 0x9146, 0x8A70, 0x8B6C,
+	0x8A71, 0x9862, 0x8A72, 0x8A59, 0x8A73, 0x8FDA, 0x8A79, 0xFBA5,
+	0x8A7C, 0xE66A, 0x8A82, 0xE66F, 0x8A84, 0xE670, 0x8A85, 0xE66E,
+	0x8A87, 0x8CD6, 0x8A89, 0x975F, 0x8A8C, 0x8E8F, 0x8A8D, 0x9446,
+	0x8A91, 0xE673, 0x8A93, 0x90BE, 0x8A95, 0x9261, 0x8A98, 0x9755,
+	0x8A9A, 0xE676, 0x8A9E, 0x8CEA, 0x8AA0, 0x90BD, 0x8AA1, 0xE672,
+	0x8AA3, 0xE677, 0x8AA4, 0x8CEB, 0x8AA5, 0xE674, 0x8AA6, 0xE675,
+	0x8AA7, 0xFBA6, 0x8AA8, 0xE671, 0x8AAC, 0x90E0, 0x8AAD, 0x93C7,
+	0x8AB0, 0x924E, 0x8AB2, 0x89DB, 0x8AB9, 0x94EE, 0x8ABC, 0x8B62,
+	0x8ABE, 0xFBA7, 0x8ABF, 0x92B2, 0x8AC2, 0xE67A, 0x8AC4, 0xE678,
+	0x8AC7, 0x926B, 0x8ACB, 0x90BF, 0x8ACC, 0x8AD0, 0x8ACD, 0xE679,
+	0x8ACF, 0x907A, 0x8AD2, 0x97C8, 0x8AD6, 0x985F, 0x8ADA, 0xE67B,
+	0x8ADB, 0xE687, 0x8ADC, 0x92B3, 0x8ADE, 0xE686, 0x8ADF, 0xFBA8,
+	0x8AE0, 0xE683, 0x8AE1, 0xE68B, 0x8AE2, 0xE684, 0x8AE4, 0xE680,
+	0x8AE6, 0x92FA, 0x8AE7, 0xE67E, 0x8AEB, 0xE67C, 0x8AED, 0x9740,
+	0x8AEE, 0x8E90, 0x8AF1, 0xE681, 0x8AF3, 0xE67D, 0x8AF6, 0xFBAA,
+	0x8AF7, 0xE685, 0x8AF8, 0x8F94, 0x8AFA, 0x8CBF, 0x8AFE, 0x91F8,
+	0x8B00, 0x9664, 0x8B01, 0x8979, 0x8B02, 0x88E0, 0x8B04, 0x93A3,
+	0x8B07, 0xE689, 0x8B0C, 0xE688, 0x8B0E, 0x93E4, 0x8B10, 0xE68D,
+	0x8B14, 0xE682, 0x8B16, 0xE68C, 0x8B17, 0xE68E, 0x8B19, 0x8CAA,
+	0x8B1A, 0xE68A, 0x8B1B, 0x8D75, 0x8B1D, 0x8ED3, 0x8B20, 0xE68F,
+	0x8B21, 0x9777, 0x8B26, 0xE692, 0x8B28, 0xE695, 0x8B2B, 0xE693,
+	0x8B2C, 0x9554, 0x8B33, 0xE690, 0x8B39, 0x8BDE, 0x8B3E, 0xE694,
+	0x8B41, 0xE696, 0x8B49, 0xE69A, 0x8B4C, 0xE697, 0x8B4E, 0xE699,
+	0x8B4F, 0xE698, 0x8B53, 0xFBAB, 0x8B56, 0xE69B, 0x8B58, 0x8EAF,
+	0x8B5A, 0xE69D, 0x8B5B, 0xE69C, 0x8B5C, 0x9588, 0x8B5F, 0xE69F,
+	0x8B66, 0x8C78, 0x8B6B, 0xE69E, 0x8B6C, 0xE6A0, 0x8B6F, 0xE6A1,
+	0x8B70, 0x8B63, 0x8B71, 0xE3BF, 0x8B72, 0x8FF7, 0x8B74, 0xE6A2,
+	0x8B77, 0x8CEC, 0x8B7D, 0xE6A3, 0x8B7F, 0xFBAC, 0x8B80, 0xE6A4,
+	0x8B83, 0x8E5D, 0x8B8A, 0x9DCC, 0x8B8C, 0xE6A5, 0x8B8E, 0xE6A6,
+	0x8B90, 0x8F51, 0x8B92, 0xE6A7, 0x8B93, 0xE6A8, 0x8B96, 0xE6A9,
+	0x8B99, 0xE6AA, 0x8B9A, 0xE6AB, 0x8C37, 0x924A, 0x8C3A, 0xE6AC,
+	0x8C3F, 0xE6AE, 0x8C41, 0xE6AD, 0x8C46, 0x93A4, 0x8C48, 0xE6AF,
+	0x8C4A, 0x964C, 0x8C4C, 0xE6B0, 0x8C4E, 0xE6B1, 0x8C50, 0xE6B2,
+	0x8C55, 0xE6B3, 0x8C5A, 0x93D8, 0x8C61, 0x8FDB, 0x8C62, 0xE6B4,
+	0x8C6A, 0x8D8B, 0x8C6B, 0x98AC, 0x8C6C, 0xE6B5, 0x8C78, 0xE6B6,
+	0x8C79, 0x955E, 0x8C7A, 0xE6B7, 0x8C7C, 0xE6BF, 0x8C82, 0xE6B8,
+	0x8C85, 0xE6BA, 0x8C89, 0xE6B9, 0x8C8A, 0xE6BB, 0x8C8C, 0x9665,
+	0x8C8D, 0xE6BC, 0x8C8E, 0xE6BD, 0x8C94, 0xE6BE, 0x8C98, 0xE6C0,
+	0x8C9D, 0x8A4C, 0x8C9E, 0x92E5, 0x8CA0, 0x9589, 0x8CA1, 0x8DE0,
+	0x8CA2, 0x8D76, 0x8CA7, 0x956E, 0x8CA8, 0x89DD, 0x8CA9, 0x94CC,
+	0x8CAA, 0xE6C3, 0x8CAB, 0x8AD1, 0x8CAC, 0x90D3, 0x8CAD, 0xE6C2,
+	0x8CAE, 0xE6C7, 0x8CAF, 0x9299, 0x8CB0, 0x96E1, 0x8CB2, 0xE6C5,
+	0x8CB3, 0xE6C6, 0x8CB4, 0x8B4D, 0x8CB6, 0xE6C8, 0x8CB7, 0x9483,
+	0x8CB8, 0x91DD, 0x8CBB, 0x94EF, 0x8CBC, 0x935C, 0x8CBD, 0xE6C4,
+	0x8CBF, 0x9666, 0x8CC0, 0x89EA, 0x8CC1, 0xE6CA, 0x8CC2, 0x9847,
+	0x8CC3, 0x92C0, 0x8CC4, 0x9864, 0x8CC7, 0x8E91, 0x8CC8, 0xE6C9,
+	0x8CCA, 0x91AF, 0x8CCD, 0xE6DA, 0x8CCE, 0x9147, 0x8CD1, 0x93F6,
+	0x8CD3, 0x956F, 0x8CDA, 0xE6CD, 0x8CDB, 0x8E5E, 0x8CDC, 0x8E92,
+	0x8CDE, 0x8FDC, 0x8CE0, 0x9485, 0x8CE2, 0x8CAB, 0x8CE3, 0xE6CC,
+	0x8CE4, 0xE6CB, 0x8CE6, 0x958A, 0x8CEA, 0x8EBF, 0x8CED, 0x9371,
+	0x8CF0, 0xFBAD, 0x8CF4, 0xFBAE, 0x8CFA, 0xE6CF, 0x8CFB, 0xE6D0,
+	0x8CFC, 0x8D77, 0x8CFD, 0xE6CE, 0x8D04, 0xE6D1, 0x8D05, 0xE6D2,
+	0x8D07, 0xE6D4, 0x8D08, 0x91A1, 0x8D0A, 0xE6D3, 0x8D0B, 0x8AE4,
+	0x8D0D, 0xE6D6, 0x8D0F, 0xE6D5, 0x8D10, 0xE6D7, 0x8D12, 0xFBAF,
+	0x8D13, 0xE6D9, 0x8D14, 0xE6DB, 0x8D16, 0xE6DC, 0x8D64, 0x90D4,
+	0x8D66, 0x8ECD, 0x8D67, 0xE6DD, 0x8D6B, 0x8A71, 0x8D6D, 0xE6DE,
+	0x8D70, 0x9196, 0x8D71, 0xE6DF, 0x8D73, 0xE6E0, 0x8D74, 0x958B,
+	0x8D76, 0xFBB0, 0x8D77, 0x8B4E, 0x8D81, 0xE6E1, 0x8D85, 0x92B4,
+	0x8D8A, 0x897A, 0x8D99, 0xE6E2, 0x8DA3, 0x8EEF, 0x8DA8, 0x9096,
+	0x8DB3, 0x91AB, 0x8DBA, 0xE6E5, 0x8DBE, 0xE6E4, 0x8DC2, 0xE6E3,
+	0x8DCB, 0xE6EB, 0x8DCC, 0xE6E9, 0x8DCF, 0xE6E6, 0x8DD6, 0xE6E8,
+	0x8DDA, 0xE6E7, 0x8DDB, 0xE6EA, 0x8DDD, 0x8B97, 0x8DDF, 0xE6EE,
+	0x8DE1, 0x90D5, 0x8DE3, 0xE6EF, 0x8DE8, 0x8CD7, 0x8DEA, 0xE6EC,
+	0x8DEB, 0xE6ED, 0x8DEF, 0x9848, 0x8DF3, 0x92B5, 0x8DF5, 0x9148,
+	0x8DFC, 0xE6F0, 0x8DFF, 0xE6F3, 0x8E08, 0xE6F1, 0x8E09, 0xE6F2,
+	0x8E0A, 0x9778, 0x8E0F, 0x93A5, 0x8E10, 0xE6F6, 0x8E1D, 0xE6F4,
+	0x8E1E, 0xE6F5, 0x8E1F, 0xE6F7, 0x8E2A, 0xE748, 0x8E30, 0xE6FA,
+	0x8E34, 0xE6FB, 0x8E35, 0xE6F9, 0x8E42, 0xE6F8, 0x8E44, 0x92FB,
+	0x8E47, 0xE740, 0x8E48, 0xE744, 0x8E49, 0xE741, 0x8E4A, 0xE6FC,
+	0x8E4C, 0xE742, 0x8E50, 0xE743, 0x8E55, 0xE74A, 0x8E59, 0xE745,
+	0x8E5F, 0x90D6, 0x8E60, 0xE747, 0x8E63, 0xE749, 0x8E64, 0xE746,
+	0x8E72, 0xE74C, 0x8E74, 0x8F52, 0x8E76, 0xE74B, 0x8E7C, 0xE74D,
+	0x8E81, 0xE74E, 0x8E84, 0xE751, 0x8E85, 0xE750, 0x8E87, 0xE74F,
+	0x8E8A, 0xE753, 0x8E8B, 0xE752, 0x8E8D, 0x96F4, 0x8E91, 0xE755,
+	0x8E93, 0xE754, 0x8E94, 0xE756, 0x8E99, 0xE757, 0x8EA1, 0xE759,
+	0x8EAA, 0xE758, 0x8EAB, 0x9067, 0x8EAC, 0xE75A, 0x8EAF, 0x8BEB,
+	0x8EB0, 0xE75B, 0x8EB1, 0xE75D, 0x8EBE, 0xE75E, 0x8EC5, 0xE75F,
+	0x8EC6, 0xE75C, 0x8EC8, 0xE760, 0x8ECA, 0x8ED4, 0x8ECB, 0xE761,
+	0x8ECC, 0x8B4F, 0x8ECD, 0x8C52, 0x8ECF, 0xFBB2, 0x8ED2, 0x8CAC,
+	0x8EDB, 0xE762, 0x8EDF, 0x93EE, 0x8EE2, 0x935D, 0x8EE3, 0xE763,
+	0x8EEB, 0xE766, 0x8EF8, 0x8EB2, 0x8EFB, 0xE765, 0x8EFC, 0xE764,
+	0x8EFD, 0x8C79, 0x8EFE, 0xE767, 0x8F03, 0x8A72, 0x8F05, 0xE769,
+	0x8F09, 0x8DDA, 0x8F0A, 0xE768, 0x8F0C, 0xE771, 0x8F12, 0xE76B,
+	0x8F13, 0xE76D, 0x8F14, 0x95E3, 0x8F15, 0xE76A, 0x8F19, 0xE76C,
+	0x8F1B, 0xE770, 0x8F1C, 0xE76E, 0x8F1D, 0x8B50, 0x8F1F, 0xE76F,
+	0x8F26, 0xE772, 0x8F29, 0x9479, 0x8F2A, 0x97D6, 0x8F2F, 0x8F53,
+	0x8F33, 0xE773, 0x8F38, 0x9741, 0x8F39, 0xE775, 0x8F3B, 0xE774,
+	0x8F3E, 0xE778, 0x8F3F, 0x9760, 0x8F42, 0xE777, 0x8F44, 0x8A8D,
+	0x8F45, 0xE776, 0x8F46, 0xE77B, 0x8F49, 0xE77A, 0x8F4C, 0xE779,
+	0x8F4D, 0x9351, 0x8F4E, 0xE77C, 0x8F57, 0xE77D, 0x8F5C, 0xE77E,
+	0x8F5F, 0x8D8C, 0x8F61, 0x8C44, 0x8F62, 0xE780, 0x8F63, 0xE781,
+	0x8F64, 0xE782, 0x8F9B, 0x9068, 0x8F9C, 0xE783, 0x8F9E, 0x8EAB,
+	0x8F9F, 0xE784, 0x8FA3, 0xE785, 0x8FA7, 0x999F, 0x8FA8, 0x999E,
+	0x8FAD, 0xE786, 0x8FAE, 0xE390, 0x8FAF, 0xE787, 0x8FB0, 0x9243,
+	0x8FB1, 0x904A, 0x8FB2, 0x945F, 0x8FB7, 0xE788, 0x8FBA, 0x95D3,
+	0x8FBB, 0x92D2, 0x8FBC, 0x8D9E, 0x8FBF, 0x9248, 0x8FC2, 0x8949,
+	0x8FC4, 0x9698, 0x8FC5, 0x9076, 0x8FCE, 0x8C7D, 0x8FD1, 0x8BDF,
+	0x8FD4, 0x95D4, 0x8FDA, 0xE789, 0x8FE2, 0xE78B, 0x8FE5, 0xE78A,
+	0x8FE6, 0x89DE, 0x8FE9, 0x93F4, 0x8FEA, 0xE78C, 0x8FEB, 0x9497,
+	0x8FED, 0x9352, 0x8FEF, 0xE78D, 0x8FF0, 0x8F71, 0x8FF4, 0xE78F,
+	0x8FF7, 0x96C0, 0x8FF8, 0xE79E, 0x8FF9, 0xE791, 0x8FFA, 0xE792,
+	0x8FFD, 0x92C7, 0x9000, 0x91DE, 0x9001, 0x9197, 0x9003, 0x93A6,
+	0x9005, 0xE790, 0x9006, 0x8B74, 0x900B, 0xE799, 0x900D, 0xE796,
+	0x900E, 0xE7A3, 0x900F, 0x93A7, 0x9010, 0x9280, 0x9011, 0xE793,
+	0x9013, 0x92FC, 0x9014, 0x9372, 0x9015, 0xE794, 0x9016, 0xE798,
+	0x9017, 0x9080, 0x9019, 0x9487, 0x901A, 0x92CA, 0x901D, 0x90C0,
+	0x901E, 0xE797, 0x901F, 0x91AC, 0x9020, 0x91A2, 0x9021, 0xE795,
+	0x9022, 0x88A7, 0x9023, 0x9841, 0x9027, 0xE79A, 0x902E, 0x91DF,
+	0x9031, 0x8F54, 0x9032, 0x9069, 0x9035, 0xE79C, 0x9036, 0xE79B,
+	0x9038, 0x88ED, 0x9039, 0xE79D, 0x903C, 0x954E, 0x903E, 0xE7A5,
+	0x9041, 0x93D9, 0x9042, 0x908B, 0x9045, 0x9278, 0x9047, 0x8BF6,
+	0x9049, 0xE7A4, 0x904A, 0x9756, 0x904B, 0x895E, 0x904D, 0x95D5,
+	0x904E, 0x89DF, 0x904F, 0xE79F, 0x9050, 0xE7A0, 0x9051, 0xE7A1,
+	0x9052, 0xE7A2, 0x9053, 0x93B9, 0x9054, 0x9242, 0x9055, 0x88E1,
+	0x9056, 0xE7A6, 0x9058, 0xE7A7, 0x9059, 0xEAA1, 0x905C, 0x91BB,
+	0x905E, 0xE7A8, 0x9060, 0x8993, 0x9061, 0x916B, 0x9063, 0x8CAD,
+	0x9065, 0x9779, 0x9067, 0xFBB5, 0x9068, 0xE7A9, 0x9069, 0x934B,
+	0x906D, 0x9198, 0x906E, 0x8ED5, 0x906F, 0xE7AA, 0x9072, 0xE7AD,
+	0x9075, 0x8F85, 0x9076, 0xE7AB, 0x9077, 0x914A, 0x9078, 0x9149,
+	0x907A, 0x88E2, 0x907C, 0x97C9, 0x907D, 0xE7AF, 0x907F, 0x94F0,
+	0x9080, 0xE7B1, 0x9081, 0xE7B0, 0x9082, 0xE7AE, 0x9083, 0xE284,
+	0x9084, 0x8AD2, 0x9087, 0xE78E, 0x9089, 0xE7B3, 0x908A, 0xE7B2,
+	0x908F, 0xE7B4, 0x9091, 0x9757, 0x90A3, 0x93DF, 0x90A6, 0x964D,
+	0x90A8, 0xE7B5, 0x90AA, 0x8ED7, 0x90AF, 0xE7B6, 0x90B1, 0xE7B7,
+	0x90B5, 0xE7B8, 0x90B8, 0x9340, 0x90C1, 0x88E8, 0x90CA, 0x8D78,
+	0x90CE, 0x9859, 0x90DB, 0xE7BC, 0x90DE, 0xFBB6, 0x90E1, 0x8C53,
+	0x90E2, 0xE7B9, 0x90E4, 0xE7BA, 0x90E8, 0x9594, 0x90ED, 0x8A73,
+	0x90F5, 0x9758, 0x90F7, 0x8BBD, 0x90FD, 0x9373, 0x9102, 0xE7BD,
+	0x9112, 0xE7BE, 0x9115, 0xFBB8, 0x9119, 0xE7BF, 0x9127, 0xFBB9,
+	0x912D, 0x9341, 0x9130, 0xE7C1, 0x9132, 0xE7C0, 0x9149, 0x93D1,
+	0x914A, 0xE7C2, 0x914B, 0x8F55, 0x914C, 0x8EDE, 0x914D, 0x947A,
+	0x914E, 0x9291, 0x9152, 0x8EF0, 0x9154, 0x908C, 0x9156, 0xE7C3,
+	0x9158, 0xE7C4, 0x9162, 0x907C, 0x9163, 0xE7C5, 0x9165, 0xE7C6,
+	0x9169, 0xE7C7, 0x916A, 0x978F, 0x916C, 0x8F56, 0x9172, 0xE7C9,
+	0x9173, 0xE7C8, 0x9175, 0x8D79, 0x9177, 0x8D93, 0x9178, 0x8E5F,
+	0x9182, 0xE7CC, 0x9187, 0x8F86, 0x9189, 0xE7CB, 0x918B, 0xE7CA,
+	0x918D, 0x91E7, 0x9190, 0x8CED, 0x9192, 0x90C1, 0x9197, 0x94AE,
+	0x919C, 0x8F58, 0x91A2, 0xE7CD, 0x91A4, 0x8FDD, 0x91AA, 0xE7D0,
+	0x91AB, 0xE7CE, 0x91AF, 0xE7CF, 0x91B4, 0xE7D2, 0x91B5, 0xE7D1,
+	0x91B8, 0x8FF8, 0x91BA, 0xE7D3, 0x91C0, 0xE7D4, 0x91C1, 0xE7D5,
+	0x91C6, 0x94CE, 0x91C7, 0x8DD1, 0x91C8, 0x8EDF, 0x91C9, 0xE7D6,
+	0x91CB, 0xE7D7, 0x91CC, 0x97A2, 0x91CD, 0x8F64, 0x91CE, 0x96EC,
+	0x91CF, 0x97CA, 0x91D0, 0xE7D8, 0x91D1, 0x8BE0, 0x91D6, 0xE7D9,
+	0x91D7, 0xFBBB, 0x91D8, 0x9342, 0x91DA, 0xFBBA, 0x91DB, 0xE7DC,
+	0x91DC, 0x8A98, 0x91DD, 0x906A, 0x91DE, 0xFBBC, 0x91DF, 0xE7DA,
+	0x91E1, 0xE7DB, 0x91E3, 0x92DE, 0x91E4, 0xFBBF, 0x91E5, 0xFBC0,
+	0x91E6, 0x9674, 0x91E7, 0x8BFA, 0x91ED, 0xFBBD, 0x91EE, 0xFBBE,
+	0x91F5, 0xE7DE, 0x91F6, 0xE7DF, 0x91FC, 0xE7DD, 0x91FF, 0xE7E1,
+	0x9206, 0xFBC1, 0x920A, 0xFBC3, 0x920D, 0x93DD, 0x920E, 0x8A62,
+	0x9210, 0xFBC2, 0x9211, 0xE7E5, 0x9214, 0xE7E2, 0x9215, 0xE7E4,
+	0x921E, 0xE7E0, 0x9229, 0xE86E, 0x922C, 0xE7E3, 0x9234, 0x97E9,
+	0x9237, 0x8CD8, 0x9239, 0xFBCA, 0x923A, 0xFBC4, 0x923C, 0xFBC6,
+	0x923F, 0xE7ED, 0x9240, 0xFBC5, 0x9244, 0x9353, 0x9245, 0xE7E8,
+	0x9248, 0xE7EB, 0x9249, 0xE7E9, 0x924B, 0xE7EE, 0x924E, 0xFBC7,
+	0x9250, 0xE7EF, 0x9251, 0xFBC9, 0x9257, 0xE7E7, 0x9259, 0xFBC8,
+	0x925A, 0xE7F4, 0x925B, 0x8994, 0x925E, 0xE7E6, 0x9262, 0x94AB,
+	0x9264, 0xE7EA, 0x9266, 0x8FDE, 0x9267, 0xFBCB, 0x9271, 0x8D7A,
+	0x9277, 0xFBCD, 0x9278, 0xFBCE, 0x927E, 0x9667, 0x9280, 0x8BE2,
+	0x9283, 0x8F65, 0x9285, 0x93BA, 0x9288, 0xFA5F, 0x9291, 0x914C,
+	0x9293, 0xE7F2, 0x9295, 0xE7EC, 0x9296, 0xE7F1, 0x9298, 0x96C1,
+	0x929A, 0x92B6, 0x929B, 0xE7F3, 0x929C, 0xE7F0, 0x92A7, 0xFBCC,
+	0x92AD, 0x914B, 0x92B7, 0xE7F7, 0x92B9, 0xE7F6, 0x92CF, 0xE7F5,
+	0x92D0, 0xFBD2, 0x92D2, 0x964E, 0x92D3, 0xFBD6, 0x92D5, 0xFBD4,
+	0x92D7, 0xFBD0, 0x92D9, 0xFBD1, 0x92E0, 0xFBD5, 0x92E4, 0x8F9B,
+	0x92E7, 0xFBCF, 0x92E9, 0xE7F8, 0x92EA, 0x95DD, 0x92ED, 0x8973,
+	0x92F2, 0x9565, 0x92F3, 0x9292, 0x92F8, 0x8B98, 0x92F9, 0xFA65,
+	0x92FA, 0xE7FA, 0x92FB, 0xFBD9, 0x92FC, 0x8D7C, 0x92FF, 0xFBDC,
+	0x9302, 0xFBDE, 0x9306, 0x8E4B, 0x930F, 0xE7F9, 0x9310, 0x908D,
+	0x9318, 0x908E, 0x9319, 0xE840, 0x931A, 0xE842, 0x931D, 0xFBDD,
+	0x931E, 0xFBDB, 0x9320, 0x8FF9, 0x9321, 0xFBD8, 0x9322, 0xE841,
+	0x9323, 0xE843, 0x9325, 0xFBD7, 0x9326, 0x8BD1, 0x9328, 0x9564,
+	0x932B, 0x8EE0, 0x932C, 0x9842, 0x932E, 0xE7FC, 0x932F, 0x8DF6,
+	0x9332, 0x985E, 0x9335, 0xE845, 0x933A, 0xE844, 0x933B, 0xE846,
+	0x9344, 0xE7FB, 0x9348, 0xFA5E, 0x934B, 0x93E7, 0x934D, 0x9374,
+	0x9354, 0x92D5, 0x9356, 0xE84B, 0x9357, 0xFBE0, 0x935B, 0x9262,
+	0x935C, 0xE847, 0x9360, 0xE848, 0x936C, 0x8C4C, 0x936E, 0xE84A,
+	0x9370, 0xFBDF, 0x9375, 0x8CAE, 0x937C, 0xE849, 0x937E, 0x8FDF,
+	0x938C, 0x8A99, 0x9394, 0xE84F, 0x9396, 0x8DBD, 0x9397, 0x9199,
+	0x939A, 0x92C8, 0x93A4, 0xFBE1, 0x93A7, 0x8A5A, 0x93AC, 0xE84D,
+	0x93AD, 0xE84E, 0x93AE, 0x92C1, 0x93B0, 0xE84C, 0x93B9, 0xE850,
+	0x93C3, 0xE856, 0x93C6, 0xFBE2, 0x93C8, 0xE859, 0x93D0, 0xE858,
+	0x93D1, 0x934C, 0x93D6, 0xE851, 0x93D7, 0xE852, 0x93D8, 0xE855,
+	0x93DD, 0xE857, 0x93DE, 0xFBE3, 0x93E1, 0x8BBE, 0x93E4, 0xE85A,
+	0x93E5, 0xE854, 0x93E8, 0xE853, 0x93F8, 0xFBE4, 0x9403, 0xE85E,
+	0x9407, 0xE85F, 0x9410, 0xE860, 0x9413, 0xE85D, 0x9414, 0xE85C,
+	0x9418, 0x8FE0, 0x9419, 0x93A8, 0x941A, 0xE85B, 0x9421, 0xE864,
+	0x942B, 0xE862, 0x9431, 0xFBE5, 0x9435, 0xE863, 0x9436, 0xE861,
+	0x9438, 0x91F6, 0x943A, 0xE865, 0x9441, 0xE866, 0x9444, 0xE868,
+	0x9445, 0xFBE6, 0x9448, 0xFBE7, 0x9451, 0x8AD3, 0x9452, 0xE867,
+	0x9453, 0x96F8, 0x945A, 0xE873, 0x945B, 0xE869, 0x945E, 0xE86C,
+	0x9460, 0xE86A, 0x9462, 0xE86B, 0x946A, 0xE86D, 0x9470, 0xE86F,
+	0x9475, 0xE870, 0x9477, 0xE871, 0x947C, 0xE874, 0x947D, 0xE872,
+	0x947E, 0xE875, 0x947F, 0xE877, 0x9481, 0xE876, 0x9577, 0x92B7,
+	0x9580, 0x96E5, 0x9582, 0xE878, 0x9583, 0x914D, 0x9587, 0xE879,
+	0x9589, 0x95C2, 0x958A, 0xE87A, 0x958B, 0x8A4A, 0x958F, 0x895B,
+	0x9591, 0x8AD5, 0x9592, 0xFBE8, 0x9593, 0x8AD4, 0x9594, 0xE87B,
+	0x9596, 0xE87C, 0x9598, 0xE87D, 0x9599, 0xE87E, 0x95A0, 0xE880,
+	0x95A2, 0x8AD6, 0x95A3, 0x8A74, 0x95A4, 0x8D7D, 0x95A5, 0x94B4,
+	0x95A7, 0xE882, 0x95A8, 0xE881, 0x95AD, 0xE883, 0x95B2, 0x897B,
+	0x95B9, 0xE886, 0x95BB, 0xE885, 0x95BC, 0xE884, 0x95BE, 0xE887,
+	0x95C3, 0xE88A, 0x95C7, 0x88C5, 0x95CA, 0xE888, 0x95CC, 0xE88C,
+	0x95CD, 0xE88B, 0x95D4, 0xE88E, 0x95D5, 0xE88D, 0x95D6, 0xE88F,
+	0x95D8, 0x93AC, 0x95DC, 0xE890, 0x95E1, 0xE891, 0x95E2, 0xE893,
+	0x95E5, 0xE892, 0x961C, 0x958C, 0x9621, 0xE894, 0x9628, 0xE895,
+	0x962A, 0x8DE3, 0x962E, 0xE896, 0x962F, 0xE897, 0x9632, 0x9668,
+	0x963B, 0x916A, 0x963F, 0x88A2, 0x9640, 0x91C9, 0x9642, 0xE898,
+	0x9644, 0x958D, 0x964B, 0xE89B, 0x964C, 0xE899, 0x964D, 0x8D7E,
+	0x964F, 0xE89A, 0x9650, 0x8CC0, 0x965B, 0x95C3, 0x965C, 0xE89D,
+	0x965D, 0xE89F, 0x965E, 0xE89E, 0x965F, 0xE8A0, 0x9662, 0x8940,
+	0x9663, 0x9077, 0x9664, 0x8F9C, 0x9665, 0x8AD7, 0x9666, 0xE8A1,
+	0x966A, 0x9486, 0x966C, 0xE8A3, 0x9670, 0x8941, 0x9672, 0xE8A2,
+	0x9673, 0x92C2, 0x9675, 0x97CB, 0x9676, 0x93A9, 0x9677, 0xE89C,
+	0x9678, 0x97A4, 0x967A, 0x8CAF, 0x967D, 0x977A, 0x9685, 0x8BF7,
+	0x9686, 0x97B2, 0x9688, 0x8C47, 0x968A, 0x91E0, 0x968B, 0xE440,
+	0x968D, 0xE8A4, 0x968E, 0x8A4B, 0x968F, 0x908F, 0x9694, 0x8A75,
+	0x9695, 0xE8A6, 0x9697, 0xE8A7, 0x9698, 0xE8A5, 0x9699, 0x8C84,
+	0x969B, 0x8DDB, 0x969C, 0x8FE1, 0x969D, 0xFBEB, 0x96A0, 0x8942,
+	0x96A3, 0x97D7, 0x96A7, 0xE8A9, 0x96A8, 0xE7AC, 0x96AA, 0xE8A8,
+	0x96AF, 0xFBEC, 0x96B0, 0xE8AC, 0x96B1, 0xE8AA, 0x96B2, 0xE8AB,
+	0x96B4, 0xE8AD, 0x96B6, 0xE8AE, 0x96B7, 0x97EA, 0x96B8, 0xE8AF,
+	0x96B9, 0xE8B0, 0x96BB, 0x90C7, 0x96BC, 0x94B9, 0x96C0, 0x909D,
+	0x96C1, 0x8AE5, 0x96C4, 0x9759, 0x96C5, 0x89EB, 0x96C6, 0x8F57,
+	0x96C7, 0x8CD9, 0x96C9, 0xE8B3, 0x96CB, 0xE8B2, 0x96CC, 0x8E93,
+	0x96CD, 0xE8B4, 0x96CE, 0xE8B1, 0x96D1, 0x8E47, 0x96D5, 0xE8B8,
+	0x96D6, 0xE5AB, 0x96D9, 0x99D4, 0x96DB, 0x9097, 0x96DC, 0xE8B6,
+	0x96E2, 0x97A3, 0x96E3, 0x93EF, 0x96E8, 0x894A, 0x96EA, 0x90E1,
+	0x96EB, 0x8EB4, 0x96F0, 0x95B5, 0x96F2, 0x895F, 0x96F6, 0x97EB,
+	0x96F7, 0x978B, 0x96F9, 0xE8B9, 0x96FB, 0x9364, 0x9700, 0x8EF9,
+	0x9704, 0xE8BA, 0x9706, 0xE8BB, 0x9707, 0x906B, 0x9708, 0xE8BC,
+	0x970A, 0x97EC, 0x970D, 0xE8B7, 0x970E, 0xE8BE, 0x970F, 0xE8C0,
+	0x9711, 0xE8BF, 0x9713, 0xE8BD, 0x9716, 0xE8C1, 0x9719, 0xE8C2,
+	0x971C, 0x919A, 0x971E, 0x89E0, 0x9724, 0xE8C3, 0x9727, 0x96B6,
+	0x972A, 0xE8C4, 0x9730, 0xE8C5, 0x9732, 0x9849, 0x9733, 0xFBED,
+	0x9738, 0x9E50, 0x9739, 0xE8C6, 0x973B, 0xFBEE, 0x973D, 0xE8C7,
+	0x973E, 0xE8C8, 0x9742, 0xE8CC, 0x9743, 0xFBEF, 0x9744, 0xE8C9,
+	0x9746, 0xE8CA, 0x9748, 0xE8CB, 0x9749, 0xE8CD, 0x974D, 0xFBF0,
+	0x974F, 0xFBF1, 0x9751, 0xFBF2, 0x9752, 0x90C2, 0x9755, 0xFBF3,
+	0x9756, 0x96F5, 0x9759, 0x90C3, 0x975C, 0xE8CE, 0x975E, 0x94F1,
+	0x9760, 0xE8CF, 0x9761, 0xEA72, 0x9762, 0x96CA, 0x9764, 0xE8D0,
+	0x9766, 0xE8D1, 0x9768, 0xE8D2, 0x9769, 0x8A76, 0x976B, 0xE8D4,
+	0x976D, 0x9078, 0x9771, 0xE8D5, 0x9774, 0x8C43, 0x9779, 0xE8D6,
+	0x977A, 0xE8DA, 0x977C, 0xE8D8, 0x9781, 0xE8D9, 0x9784, 0x8A93,
+	0x9785, 0xE8D7, 0x9786, 0xE8DB, 0x978B, 0xE8DC, 0x978D, 0x88C6,
+	0x978F, 0xE8DD, 0x9790, 0xE8DE, 0x9798, 0x8FE2, 0x979C, 0xE8DF,
+	0x97A0, 0x8B66, 0x97A3, 0xE8E2, 0x97A6, 0xE8E1, 0x97A8, 0xE8E0,
+	0x97AB, 0xE691, 0x97AD, 0x95DA, 0x97B3, 0xE8E3, 0x97B4, 0xE8E4,
+	0x97C3, 0xE8E5, 0x97C6, 0xE8E6, 0x97C8, 0xE8E7, 0x97CB, 0xE8E8,
+	0x97D3, 0x8AD8, 0x97DC, 0xE8E9, 0x97ED, 0xE8EA, 0x97EE, 0x9442,
+	0x97F2, 0xE8EC, 0x97F3, 0x89B9, 0x97F5, 0xE8EF, 0x97F6, 0xE8EE,
+	0x97FB, 0x8943, 0x97FF, 0x8BBF, 0x9801, 0x95C5, 0x9802, 0x92B8,
+	0x9803, 0x8DA0, 0x9805, 0x8D80, 0x9806, 0x8F87, 0x9808, 0x907B,
+	0x980C, 0xE8F1, 0x980F, 0xE8F0, 0x9810, 0x9761, 0x9811, 0x8AE6,
+	0x9812, 0x94D0, 0x9813, 0x93DA, 0x9817, 0x909C, 0x9818, 0x97CC,
+	0x981A, 0x8C7A, 0x9821, 0xE8F4, 0x9824, 0xE8F3, 0x982C, 0x966A,
+	0x982D, 0x93AA, 0x9834, 0x896F, 0x9837, 0xE8F5, 0x9838, 0xE8F2,
+	0x983B, 0x9570, 0x983C, 0x978A, 0x983D, 0xE8F6, 0x9846, 0xE8F7,
+	0x984B, 0xE8F9, 0x984C, 0x91E8, 0x984D, 0x8A7A, 0x984E, 0x8A7B,
+	0x984F, 0xE8F8, 0x9854, 0x8AE7, 0x9855, 0x8CB0, 0x9857, 0xFBF4,
+	0x9858, 0x8AE8, 0x985B, 0x935E, 0x985E, 0x97DE, 0x9865, 0xFBF5,
+	0x9867, 0x8CDA, 0x986B, 0xE8FA, 0x986F, 0xE8FB, 0x9870, 0xE8FC,
+	0x9871, 0xE940, 0x9873, 0xE942, 0x9874, 0xE941, 0x98A8, 0x9597,
+	0x98AA, 0xE943, 0x98AF, 0xE944, 0x98B1, 0xE945, 0x98B6, 0xE946,
+	0x98C3, 0xE948, 0x98C4, 0xE947, 0x98C6, 0xE949, 0x98DB, 0x94F2,
+	0x98DC, 0xE3CA, 0x98DF, 0x9048, 0x98E2, 0x8B51, 0x98E9, 0xE94A,
+	0x98EB, 0xE94B, 0x98ED, 0x99AA, 0x98EE, 0x9F5A, 0x98EF, 0x94D1,
+	0x98F2, 0x88F9, 0x98F4, 0x88B9, 0x98FC, 0x8E94, 0x98FD, 0x964F,
+	0x98FE, 0x8FFC, 0x9903, 0xE94C, 0x9905, 0x96DD, 0x9909, 0xE94D,
+	0x990A, 0x977B, 0x990C, 0x8961, 0x9910, 0x8E60, 0x9912, 0xE94E,
+	0x9913, 0x89EC, 0x9914, 0xE94F, 0x9918, 0xE950, 0x991D, 0xE952,
+	0x991E, 0xE953, 0x9920, 0xE955, 0x9921, 0xE951, 0x9924, 0xE954,
+	0x9927, 0xFBF8, 0x9928, 0x8AD9, 0x992C, 0xE956, 0x992E, 0xE957,
+	0x993D, 0xE958, 0x993E, 0xE959, 0x9942, 0xE95A, 0x9945, 0xE95C,
+	0x9949, 0xE95B, 0x994B, 0xE95E, 0x994C, 0xE961, 0x9950, 0xE95D,
+	0x9951, 0xE95F, 0x9952, 0xE960, 0x9955, 0xE962, 0x9957, 0x8BC0,
+	0x9996, 0x8EF1, 0x9997, 0xE963, 0x9998, 0xE964, 0x9999, 0x8D81,
+	0x999E, 0xFBFA, 0x99A5, 0xE965, 0x99A8, 0x8A5D, 0x99AC, 0x946E,
+	0x99AD, 0xE966, 0x99AE, 0xE967, 0x99B3, 0x9279, 0x99B4, 0x93E9,
+	0x99BC, 0xE968, 0x99C1, 0x949D, 0x99C4, 0x91CA, 0x99C5, 0x8977,
+	0x99C6, 0x8BEC, 0x99C8, 0x8BED, 0x99D0, 0x9293, 0x99D1, 0xE96D,
+	0x99D2, 0x8BEE, 0x99D5, 0x89ED, 0x99D8, 0xE96C, 0x99DB, 0xE96A,
+	0x99DD, 0xE96B, 0x99DF, 0xE969, 0x99E2, 0xE977, 0x99ED, 0xE96E,
+	0x99EE, 0xE96F, 0x99F1, 0xE970, 0x99F2, 0xE971, 0x99F8, 0xE973,
+	0x99FB, 0xE972, 0x99FF, 0x8F78, 0x9A01, 0xE974, 0x9A05, 0xE976,
+	0x9A0E, 0x8B52, 0x9A0F, 0xE975, 0x9A12, 0x919B, 0x9A13, 0x8CB1,
+	0x9A19, 0xE978, 0x9A28, 0x91CB, 0x9A2B, 0xE979, 0x9A30, 0x93AB,
+	0x9A37, 0xE97A, 0x9A3E, 0xE980, 0x9A40, 0xE97D, 0x9A42, 0xE97C,
+	0x9A43, 0xE97E, 0x9A45, 0xE97B, 0x9A4D, 0xE982, 0x9A4E, 0xFBFB,
+	0x9A55, 0xE981, 0x9A57, 0xE984, 0x9A5A, 0x8BC1, 0x9A5B, 0xE983,
+	0x9A5F, 0xE985, 0x9A62, 0xE986, 0x9A64, 0xE988, 0x9A65, 0xE987,
+	0x9A69, 0xE989, 0x9A6A, 0xE98B, 0x9A6B, 0xE98A, 0x9AA8, 0x8D9C,
+	0x9AAD, 0xE98C, 0x9AB0, 0xE98D, 0x9AB8, 0x8A5B, 0x9ABC, 0xE98E,
+	0x9AC0, 0xE98F, 0x9AC4, 0x9091, 0x9ACF, 0xE990, 0x9AD1, 0xE991,
+	0x9AD3, 0xE992, 0x9AD4, 0xE993, 0x9AD8, 0x8D82, 0x9AD9, 0xFBFC,
+	0x9ADC, 0xFC40, 0x9ADE, 0xE994, 0x9ADF, 0xE995, 0x9AE2, 0xE996,
+	0x9AE3, 0xE997, 0x9AE6, 0xE998, 0x9AEA, 0x94AF, 0x9AEB, 0xE99A,
+	0x9AED, 0x9545, 0x9AEE, 0xE99B, 0x9AEF, 0xE999, 0x9AF1, 0xE99D,
+	0x9AF4, 0xE99C, 0x9AF7, 0xE99E, 0x9AFB, 0xE99F, 0x9B06, 0xE9A0,
+	0x9B18, 0xE9A1, 0x9B1A, 0xE9A2, 0x9B1F, 0xE9A3, 0x9B22, 0xE9A4,
+	0x9B23, 0xE9A5, 0x9B25, 0xE9A6, 0x9B27, 0xE9A7, 0x9B28, 0xE9A8,
+	0x9B29, 0xE9A9, 0x9B2A, 0xE9AA, 0x9B2E, 0xE9AB, 0x9B2F, 0xE9AC,
+	0x9B31, 0x9F54, 0x9B32, 0xE9AD, 0x9B3B, 0xE2F6, 0x9B3C, 0x8B53,
+	0x9B41, 0x8A40, 0x9B42, 0x8DB0, 0x9B43, 0xE9AF, 0x9B44, 0xE9AE,
+	0x9B45, 0x96A3, 0x9B4D, 0xE9B1, 0x9B4E, 0xE9B2, 0x9B4F, 0xE9B0,
+	0x9B51, 0xE9B3, 0x9B54, 0x9682, 0x9B58, 0xE9B4, 0x9B5A, 0x8B9B,
+	0x9B6F, 0x9844, 0x9B72, 0xFC42, 0x9B74, 0xE9B5, 0x9B75, 0xFC41,
+	0x9B83, 0xE9B7, 0x9B8E, 0x88BC, 0x9B8F, 0xFC43, 0x9B91, 0xE9B8,
+	0x9B92, 0x95A9, 0x9B93, 0xE9B6, 0x9B96, 0xE9B9, 0x9B97, 0xE9BA,
+	0x9B9F, 0xE9BB, 0x9BA0, 0xE9BC, 0x9BA8, 0xE9BD, 0x9BAA, 0x968E,
+	0x9BAB, 0x8E4C, 0x9BAD, 0x8DF8, 0x9BAE, 0x914E, 0x9BB1, 0xFC44,
+	0x9BB4, 0xE9BE, 0x9BB9, 0xE9C1, 0x9BBB, 0xFC45, 0x9BC0, 0xE9BF,
+	0x9BC6, 0xE9C2, 0x9BC9, 0x8CEF, 0x9BCA, 0xE9C0, 0x9BCF, 0xE9C3,
+	0x9BD1, 0xE9C4, 0x9BD2, 0xE9C5, 0x9BD4, 0xE9C9, 0x9BD6, 0x8E49,
+	0x9BDB, 0x91E2, 0x9BE1, 0xE9CA, 0x9BE2, 0xE9C7, 0x9BE3, 0xE9C6,
+	0x9BE4, 0xE9C8, 0x9BE8, 0x8C7E, 0x9BF0, 0xE9CE, 0x9BF1, 0xE9CD,
+	0x9BF2, 0xE9CC, 0x9BF5, 0x88B1, 0x9C00, 0xFC46, 0x9C04, 0xE9D8,
+	0x9C06, 0xE9D4, 0x9C08, 0xE9D5, 0x9C09, 0xE9D1, 0x9C0A, 0xE9D7,
+	0x9C0C, 0xE9D3, 0x9C0D, 0x8A82, 0x9C10, 0x986B, 0x9C12, 0xE9D6,
+	0x9C13, 0xE9D2, 0x9C14, 0xE9D0, 0x9C15, 0xE9CF, 0x9C1B, 0xE9DA,
+	0x9C21, 0xE9DD, 0x9C24, 0xE9DC, 0x9C25, 0xE9DB, 0x9C2D, 0x9568,
+	0x9C2E, 0xE9D9, 0x9C2F, 0x88F1, 0x9C30, 0xE9DE, 0x9C32, 0xE9E0,
+	0x9C39, 0x8A8F, 0x9C3A, 0xE9CB, 0x9C3B, 0x8956, 0x9C3E, 0xE9E2,
+	0x9C46, 0xE9E1, 0x9C47, 0xE9DF, 0x9C48, 0x924C, 0x9C52, 0x9690,
+	0x9C57, 0x97D8, 0x9C5A, 0xE9E3, 0x9C60, 0xE9E4, 0x9C67, 0xE9E5,
+	0x9C76, 0xE9E6, 0x9C78, 0xE9E7, 0x9CE5, 0x92B9, 0x9CE7, 0xE9E8,
+	0x9CE9, 0x94B5, 0x9CEB, 0xE9ED, 0x9CEC, 0xE9E9, 0x9CF0, 0xE9EA,
+	0x9CF3, 0x9650, 0x9CF4, 0x96C2, 0x9CF6, 0x93CE, 0x9D03, 0xE9EE,
+	0x9D06, 0xE9EF, 0x9D07, 0x93BC, 0x9D08, 0xE9EC, 0x9D09, 0xE9EB,
+	0x9D0E, 0x89A8, 0x9D12, 0xE9F7, 0x9D15, 0xE9F6, 0x9D1B, 0x8995,
+	0x9D1F, 0xE9F4, 0x9D23, 0xE9F3, 0x9D26, 0xE9F1, 0x9D28, 0x8A9B,
+	0x9D2A, 0xE9F0, 0x9D2B, 0x8EB0, 0x9D2C, 0x89A7, 0x9D3B, 0x8D83,
+	0x9D3E, 0xE9FA, 0x9D3F, 0xE9F9, 0x9D41, 0xE9F8, 0x9D44, 0xE9F5,
+	0x9D46, 0xE9FB, 0x9D48, 0xE9FC, 0x9D50, 0xEA44, 0x9D51, 0xEA43,
+	0x9D59, 0xEA45, 0x9D5C, 0x894C, 0x9D5D, 0xEA40, 0x9D5E, 0xEA41,
+	0x9D60, 0x8D94, 0x9D61, 0x96B7, 0x9D64, 0xEA42, 0x9D6B, 0xFC48,
+	0x9D6C, 0x9651, 0x9D6F, 0xEA4A, 0x9D70, 0xFC47, 0x9D72, 0xEA46,
+	0x9D7A, 0xEA4B, 0x9D87, 0xEA48, 0x9D89, 0xEA47, 0x9D8F, 0x8C7B,
+	0x9D9A, 0xEA4C, 0x9DA4, 0xEA4D, 0x9DA9, 0xEA4E, 0x9DAB, 0xEA49,
+	0x9DAF, 0xE9F2, 0x9DB2, 0xEA4F, 0x9DB4, 0x92DF, 0x9DB8, 0xEA53,
+	0x9DBA, 0xEA54, 0x9DBB, 0xEA52, 0x9DC1, 0xEA51, 0x9DC2, 0xEA57,
+	0x9DC4, 0xEA50, 0x9DC6, 0xEA55, 0x9DCF, 0xEA56, 0x9DD3, 0xEA59,
+	0x9DD9, 0xEA58, 0x9DE6, 0xEA5B, 0x9DED, 0xEA5C, 0x9DEF, 0xEA5D,
+	0x9DF2, 0x9868, 0x9DF8, 0xEA5A, 0x9DF9, 0x91E9, 0x9DFA, 0x8DEB,
+	0x9DFD, 0xEA5E, 0x9E19, 0xFC4A, 0x9E1A, 0xEA5F, 0x9E1B, 0xEA60,
+	0x9E1E, 0xEA61, 0x9E75, 0xEA62, 0x9E78, 0x8CB2, 0x9E79, 0xEA63,
+	0x9E7D, 0xEA64, 0x9E7F, 0x8EAD, 0x9E81, 0xEA65, 0x9E88, 0xEA66,
+	0x9E8B, 0xEA67, 0x9E8C, 0xEA68, 0x9E91, 0xEA6B, 0x9E92, 0xEA69,
+	0x9E93, 0x985B, 0x9E95, 0xEA6A, 0x9E97, 0x97ED, 0x9E9D, 0xEA6C,
+	0x9E9F, 0x97D9, 0x9EA5, 0xEA6D, 0x9EA6, 0x949E, 0x9EA9, 0xEA6E,
+	0x9EAA, 0xEA70, 0x9EAD, 0xEA71, 0x9EB8, 0xEA6F, 0x9EB9, 0x8D8D,
+	0x9EBA, 0x96CB, 0x9EBB, 0x9683, 0x9EBC, 0x9BF5, 0x9EBE, 0x9F80,
+	0x9EBF, 0x969B, 0x9EC4, 0x89A9, 0x9ECC, 0xEA73, 0x9ECD, 0x8B6F,
+	0x9ECE, 0xEA74, 0x9ECF, 0xEA75, 0x9ED0, 0xEA76, 0x9ED1, 0xFC4B,
+	0x9ED2, 0x8D95, 0x9ED4, 0xEA77, 0x9ED8, 0xE0D2, 0x9ED9, 0x96D9,
+	0x9EDB, 0x91E1, 0x9EDC, 0xEA78, 0x9EDD, 0xEA7A, 0x9EDE, 0xEA79,
+	0x9EE0, 0xEA7B, 0x9EE5, 0xEA7C, 0x9EE8, 0xEA7D, 0x9EEF, 0xEA7E,
+	0x9EF4, 0xEA80, 0x9EF6, 0xEA81, 0x9EF7, 0xEA82, 0x9EF9, 0xEA83,
+	0x9EFB, 0xEA84, 0x9EFC, 0xEA85, 0x9EFD, 0xEA86, 0x9F07, 0xEA87,
+	0x9F08, 0xEA88, 0x9F0E, 0x9343, 0x9F13, 0x8CDB, 0x9F15, 0xEA8A,
+	0x9F20, 0x916C, 0x9F21, 0xEA8B, 0x9F2C, 0xEA8C, 0x9F3B, 0x9540,
+	0x9F3E, 0xEA8D, 0x9F4A, 0xEA8E, 0x9F4B, 0xE256, 0x9F4E, 0xE6D8,
+	0x9F4F, 0xE8EB, 0x9F52, 0xEA8F, 0x9F54, 0xEA90, 0x9F5F, 0xEA92,
+	0x9F60, 0xEA93, 0x9F61, 0xEA94, 0x9F62, 0x97EE, 0x9F63, 0xEA91,
+	0x9F66, 0xEA95, 0x9F67, 0xEA96, 0x9F6A, 0xEA98, 0x9F6C, 0xEA97,
+	0x9F72, 0xEA9A, 0x9F76, 0xEA9B, 0x9F77, 0xEA99, 0x9F8D, 0x97B4,
+	0x9F95, 0xEA9C, 0x9F9C, 0xEA9D, 0x9F9D, 0xE273, 0x9FA0, 0xEA9E,
+	0xF929, 0xFAE0, 0xF9DC, 0xFBE9, 0xFA0E, 0xFA90, 0xFA0F, 0xFA9B,
+	0xFA10, 0xFA9C, 0xFA11, 0xFAB1, 0xFA12, 0xFAD8, 0xFA13, 0xFAE8,
+	0xFA14, 0xFAEA, 0xFA15, 0xFB58, 0xFA16, 0xFB5E, 0xFA17, 0xFB75,
+	0xFA18, 0xFB7D, 0xFA19, 0xFB7E, 0xFA1A, 0xFB80, 0xFA1B, 0xFB82,
+	0xFA1C, 0xFB86, 0xFA1D, 0xFB89, 0xFA1E, 0xFB92, 0xFA1F, 0xFB9D,
+	0xFA20, 0xFB9F, 0xFA21, 0xFBA0, 0xFA22, 0xFBA9, 0xFA23, 0xFBB1,
+	0xFA24, 0xFBB3, 0xFA25, 0xFBB4, 0xFA26, 0xFBB7, 0xFA27, 0xFBD3,
+	0xFA28, 0xFBDA, 0xFA29, 0xFBEA, 0xFA2A, 0xFBF6, 0xFA2B, 0xFBF7,
+	0xFA2C, 0xFBF9, 0xFA2D, 0xFC49, 0xFF01, 0x8149, 0xFF02, 0xFA57,
+	0xFF03, 0x8194, 0xFF04, 0x8190, 0xFF05, 0x8193, 0xFF06, 0x8195,
+	0xFF07, 0xFA56, 0xFF08, 0x8169, 0xFF09, 0x816A, 0xFF0A, 0x8196,
+	0xFF0B, 0x817B, 0xFF0C, 0x8143, 0xFF0D, 0x817C, 0xFF0E, 0x8144,
+	0xFF0F, 0x815E, 0xFF10, 0x824F, 0xFF11, 0x8250, 0xFF12, 0x8251,
+	0xFF13, 0x8252, 0xFF14, 0x8253, 0xFF15, 0x8254, 0xFF16, 0x8255,
+	0xFF17, 0x8256, 0xFF18, 0x8257, 0xFF19, 0x8258, 0xFF1A, 0x8146,
+	0xFF1B, 0x8147, 0xFF1C, 0x8183, 0xFF1D, 0x8181, 0xFF1E, 0x8184,
+	0xFF1F, 0x8148, 0xFF20, 0x8197, 0xFF21, 0x8260, 0xFF22, 0x8261,
+	0xFF23, 0x8262, 0xFF24, 0x8263, 0xFF25, 0x8264, 0xFF26, 0x8265,
+	0xFF27, 0x8266, 0xFF28, 0x8267, 0xFF29, 0x8268, 0xFF2A, 0x8269,
+	0xFF2B, 0x826A, 0xFF2C, 0x826B, 0xFF2D, 0x826C, 0xFF2E, 0x826D,
+	0xFF2F, 0x826E, 0xFF30, 0x826F, 0xFF31, 0x8270, 0xFF32, 0x8271,
+	0xFF33, 0x8272, 0xFF34, 0x8273, 0xFF35, 0x8274, 0xFF36, 0x8275,
+	0xFF37, 0x8276, 0xFF38, 0x8277, 0xFF39, 0x8278, 0xFF3A, 0x8279,
+	0xFF3B, 0x816D, 0xFF3C, 0x815F, 0xFF3D, 0x816E, 0xFF3E, 0x814F,
+	0xFF3F, 0x8151, 0xFF40, 0x814D, 0xFF41, 0x8281, 0xFF42, 0x8282,
+	0xFF43, 0x8283, 0xFF44, 0x8284, 0xFF45, 0x8285, 0xFF46, 0x8286,
+	0xFF47, 0x8287, 0xFF48, 0x8288, 0xFF49, 0x8289, 0xFF4A, 0x828A,
+	0xFF4B, 0x828B, 0xFF4C, 0x828C, 0xFF4D, 0x828D, 0xFF4E, 0x828E,
+	0xFF4F, 0x828F, 0xFF50, 0x8290, 0xFF51, 0x8291, 0xFF52, 0x8292,
+	0xFF53, 0x8293, 0xFF54, 0x8294, 0xFF55, 0x8295, 0xFF56, 0x8296,
+	0xFF57, 0x8297, 0xFF58, 0x8298, 0xFF59, 0x8299, 0xFF5A, 0x829A,
+	0xFF5B, 0x816F, 0xFF5C, 0x8162, 0xFF5D, 0x8170, 0xFF5E, 0x8160,
+	0xFF61, 0x00A1, 0xFF62, 0x00A2, 0xFF63, 0x00A3, 0xFF64, 0x00A4,
+	0xFF65, 0x00A5, 0xFF66, 0x00A6, 0xFF67, 0x00A7, 0xFF68, 0x00A8,
+	0xFF69, 0x00A9, 0xFF6A, 0x00AA, 0xFF6B, 0x00AB, 0xFF6C, 0x00AC,
+	0xFF6D, 0x00AD, 0xFF6E, 0x00AE, 0xFF6F, 0x00AF, 0xFF70, 0x00B0,
+	0xFF71, 0x00B1, 0xFF72, 0x00B2, 0xFF73, 0x00B3, 0xFF74, 0x00B4,
+	0xFF75, 0x00B5, 0xFF76, 0x00B6, 0xFF77, 0x00B7, 0xFF78, 0x00B8,
+	0xFF79, 0x00B9, 0xFF7A, 0x00BA, 0xFF7B, 0x00BB, 0xFF7C, 0x00BC,
+	0xFF7D, 0x00BD, 0xFF7E, 0x00BE, 0xFF7F, 0x00BF, 0xFF80, 0x00C0,
+	0xFF81, 0x00C1, 0xFF82, 0x00C2, 0xFF83, 0x00C3, 0xFF84, 0x00C4,
+	0xFF85, 0x00C5, 0xFF86, 0x00C6, 0xFF87, 0x00C7, 0xFF88, 0x00C8,
+	0xFF89, 0x00C9, 0xFF8A, 0x00CA, 0xFF8B, 0x00CB, 0xFF8C, 0x00CC,
+	0xFF8D, 0x00CD, 0xFF8E, 0x00CE, 0xFF8F, 0x00CF, 0xFF90, 0x00D0,
+	0xFF91, 0x00D1, 0xFF92, 0x00D2, 0xFF93, 0x00D3, 0xFF94, 0x00D4,
+	0xFF95, 0x00D5, 0xFF96, 0x00D6, 0xFF97, 0x00D7, 0xFF98, 0x00D8,
+	0xFF99, 0x00D9, 0xFF9A, 0x00DA, 0xFF9B, 0x00DB, 0xFF9C, 0x00DC,
+	0xFF9D, 0x00DD, 0xFF9E, 0x00DE, 0xFF9F, 0x00DF, 0xFFE0, 0x8191,
+	0xFFE1, 0x8192, 0xFFE2, 0x81CA, 0xFFE3, 0x8150, 0xFFE4, 0xFA55,
+	0xFFE5, 0x818F, 0, 0
+};
+
+#if !_TINY_TABLE
+static
+const WCHAR sjis2uni[] = {
+/*	SJIS - Unicode, SJIS - Unicode, SJIS - Unicode, SJIS - Unicode, */
+	0x00A1, 0xFF61, 0x00A2, 0xFF62, 0x00A3, 0xFF63, 0x00A4, 0xFF64,
+	0x00A5, 0xFF65, 0x00A6, 0xFF66, 0x00A7, 0xFF67, 0x00A8, 0xFF68,
+	0x00A9, 0xFF69, 0x00AA, 0xFF6A, 0x00AB, 0xFF6B, 0x00AC, 0xFF6C,
+	0x00AD, 0xFF6D, 0x00AE, 0xFF6E, 0x00AF, 0xFF6F, 0x00B0, 0xFF70,
+	0x00B1, 0xFF71, 0x00B2, 0xFF72, 0x00B3, 0xFF73, 0x00B4, 0xFF74,
+	0x00B5, 0xFF75, 0x00B6, 0xFF76, 0x00B7, 0xFF77, 0x00B8, 0xFF78,
+	0x00B9, 0xFF79, 0x00BA, 0xFF7A, 0x00BB, 0xFF7B, 0x00BC, 0xFF7C,
+	0x00BD, 0xFF7D, 0x00BE, 0xFF7E, 0x00BF, 0xFF7F, 0x00C0, 0xFF80,
+	0x00C1, 0xFF81, 0x00C2, 0xFF82, 0x00C3, 0xFF83, 0x00C4, 0xFF84,
+	0x00C5, 0xFF85, 0x00C6, 0xFF86, 0x00C7, 0xFF87, 0x00C8, 0xFF88,
+	0x00C9, 0xFF89, 0x00CA, 0xFF8A, 0x00CB, 0xFF8B, 0x00CC, 0xFF8C,
+	0x00CD, 0xFF8D, 0x00CE, 0xFF8E, 0x00CF, 0xFF8F, 0x00D0, 0xFF90,
+	0x00D1, 0xFF91, 0x00D2, 0xFF92, 0x00D3, 0xFF93, 0x00D4, 0xFF94,
+	0x00D5, 0xFF95, 0x00D6, 0xFF96, 0x00D7, 0xFF97, 0x00D8, 0xFF98,
+	0x00D9, 0xFF99, 0x00DA, 0xFF9A, 0x00DB, 0xFF9B, 0x00DC, 0xFF9C,
+	0x00DD, 0xFF9D, 0x00DE, 0xFF9E, 0x00DF, 0xFF9F, 0x8140, 0x3000,
+	0x8141, 0x3001, 0x8142, 0x3002, 0x8143, 0xFF0C, 0x8144, 0xFF0E,
+	0x8145, 0x30FB, 0x8146, 0xFF1A, 0x8147, 0xFF1B, 0x8148, 0xFF1F,
+	0x8149, 0xFF01, 0x814A, 0x309B, 0x814B, 0x309C, 0x814C, 0x00B4,
+	0x814D, 0xFF40, 0x814E, 0x00A8, 0x814F, 0xFF3E, 0x8150, 0xFFE3,
+	0x8151, 0xFF3F, 0x8152, 0x30FD, 0x8153, 0x30FE, 0x8154, 0x309D,
+	0x8155, 0x309E, 0x8156, 0x3003, 0x8157, 0x4EDD, 0x8158, 0x3005,
+	0x8159, 0x3006, 0x815A, 0x3007, 0x815B, 0x30FC, 0x815C, 0x2015,
+	0x815D, 0x2010, 0x815E, 0xFF0F, 0x815F, 0xFF3C, 0x8160, 0xFF5E,
+	0x8161, 0x2225, 0x8162, 0xFF5C, 0x8163, 0x2026, 0x8164, 0x2025,
+	0x8165, 0x2018, 0x8166, 0x2019, 0x8167, 0x201C, 0x8168, 0x201D,
+	0x8169, 0xFF08, 0x816A, 0xFF09, 0x816B, 0x3014, 0x816C, 0x3015,
+	0x816D, 0xFF3B, 0x816E, 0xFF3D, 0x816F, 0xFF5B, 0x8170, 0xFF5D,
+	0x8171, 0x3008, 0x8172, 0x3009, 0x8173, 0x300A, 0x8174, 0x300B,
+	0x8175, 0x300C, 0x8176, 0x300D, 0x8177, 0x300E, 0x8178, 0x300F,
+	0x8179, 0x3010, 0x817A, 0x3011, 0x817B, 0xFF0B, 0x817C, 0xFF0D,
+	0x817D, 0x00B1, 0x817E, 0x00D7, 0x8180, 0x00F7, 0x8181, 0xFF1D,
+	0x8182, 0x2260, 0x8183, 0xFF1C, 0x8184, 0xFF1E, 0x8185, 0x2266,
+	0x8186, 0x2267, 0x8187, 0x221E, 0x8188, 0x2234, 0x8189, 0x2642,
+	0x818A, 0x2640, 0x818B, 0x00B0, 0x818C, 0x2032, 0x818D, 0x2033,
+	0x818E, 0x2103, 0x818F, 0xFFE5, 0x8190, 0xFF04, 0x8191, 0xFFE0,
+	0x8192, 0xFFE1, 0x8193, 0xFF05, 0x8194, 0xFF03, 0x8195, 0xFF06,
+	0x8196, 0xFF0A, 0x8197, 0xFF20, 0x8198, 0x00A7, 0x8199, 0x2606,
+	0x819A, 0x2605, 0x819B, 0x25CB, 0x819C, 0x25CF, 0x819D, 0x25CE,
+	0x819E, 0x25C7, 0x819F, 0x25C6, 0x81A0, 0x25A1, 0x81A1, 0x25A0,
+	0x81A2, 0x25B3, 0x81A3, 0x25B2, 0x81A4, 0x25BD, 0x81A5, 0x25BC,
+	0x81A6, 0x203B, 0x81A7, 0x3012, 0x81A8, 0x2192, 0x81A9, 0x2190,
+	0x81AA, 0x2191, 0x81AB, 0x2193, 0x81AC, 0x3013, 0x81B8, 0x2208,
+	0x81B9, 0x220B, 0x81BA, 0x2286, 0x81BB, 0x2287, 0x81BC, 0x2282,
+	0x81BD, 0x2283, 0x81BE, 0x222A, 0x81BF, 0x2229, 0x81C8, 0x2227,
+	0x81C9, 0x2228, 0x81CA, 0xFFE2, 0x81CB, 0x21D2, 0x81CC, 0x21D4,
+	0x81CD, 0x2200, 0x81CE, 0x2203, 0x81DA, 0x2220, 0x81DB, 0x22A5,
+	0x81DC, 0x2312, 0x81DD, 0x2202, 0x81DE, 0x2207, 0x81DF, 0x2261,
+	0x81E0, 0x2252, 0x81E1, 0x226A, 0x81E2, 0x226B, 0x81E3, 0x221A,
+	0x81E4, 0x223D, 0x81E5, 0x221D, 0x81E6, 0x2235, 0x81E7, 0x222B,
+	0x81E8, 0x222C, 0x81F0, 0x212B, 0x81F1, 0x2030, 0x81F2, 0x266F,
+	0x81F3, 0x266D, 0x81F4, 0x266A, 0x81F5, 0x2020, 0x81F6, 0x2021,
+	0x81F7, 0x00B6, 0x81FC, 0x25EF, 0x824F, 0xFF10, 0x8250, 0xFF11,
+	0x8251, 0xFF12, 0x8252, 0xFF13, 0x8253, 0xFF14, 0x8254, 0xFF15,
+	0x8255, 0xFF16, 0x8256, 0xFF17, 0x8257, 0xFF18, 0x8258, 0xFF19,
+	0x8260, 0xFF21, 0x8261, 0xFF22, 0x8262, 0xFF23, 0x8263, 0xFF24,
+	0x8264, 0xFF25, 0x8265, 0xFF26, 0x8266, 0xFF27, 0x8267, 0xFF28,
+	0x8268, 0xFF29, 0x8269, 0xFF2A, 0x826A, 0xFF2B, 0x826B, 0xFF2C,
+	0x826C, 0xFF2D, 0x826D, 0xFF2E, 0x826E, 0xFF2F, 0x826F, 0xFF30,
+	0x8270, 0xFF31, 0x8271, 0xFF32, 0x8272, 0xFF33, 0x8273, 0xFF34,
+	0x8274, 0xFF35, 0x8275, 0xFF36, 0x8276, 0xFF37, 0x8277, 0xFF38,
+	0x8278, 0xFF39, 0x8279, 0xFF3A, 0x8281, 0xFF41, 0x8282, 0xFF42,
+	0x8283, 0xFF43, 0x8284, 0xFF44, 0x8285, 0xFF45, 0x8286, 0xFF46,
+	0x8287, 0xFF47, 0x8288, 0xFF48, 0x8289, 0xFF49, 0x828A, 0xFF4A,
+	0x828B, 0xFF4B, 0x828C, 0xFF4C, 0x828D, 0xFF4D, 0x828E, 0xFF4E,
+	0x828F, 0xFF4F, 0x8290, 0xFF50, 0x8291, 0xFF51, 0x8292, 0xFF52,
+	0x8293, 0xFF53, 0x8294, 0xFF54, 0x8295, 0xFF55, 0x8296, 0xFF56,
+	0x8297, 0xFF57, 0x8298, 0xFF58, 0x8299, 0xFF59, 0x829A, 0xFF5A,
+	0x829F, 0x3041, 0x82A0, 0x3042, 0x82A1, 0x3043, 0x82A2, 0x3044,
+	0x82A3, 0x3045, 0x82A4, 0x3046, 0x82A5, 0x3047, 0x82A6, 0x3048,
+	0x82A7, 0x3049, 0x82A8, 0x304A, 0x82A9, 0x304B, 0x82AA, 0x304C,
+	0x82AB, 0x304D, 0x82AC, 0x304E, 0x82AD, 0x304F, 0x82AE, 0x3050,
+	0x82AF, 0x3051, 0x82B0, 0x3052, 0x82B1, 0x3053, 0x82B2, 0x3054,
+	0x82B3, 0x3055, 0x82B4, 0x3056, 0x82B5, 0x3057, 0x82B6, 0x3058,
+	0x82B7, 0x3059, 0x82B8, 0x305A, 0x82B9, 0x305B, 0x82BA, 0x305C,
+	0x82BB, 0x305D, 0x82BC, 0x305E, 0x82BD, 0x305F, 0x82BE, 0x3060,
+	0x82BF, 0x3061, 0x82C0, 0x3062, 0x82C1, 0x3063, 0x82C2, 0x3064,
+	0x82C3, 0x3065, 0x82C4, 0x3066, 0x82C5, 0x3067, 0x82C6, 0x3068,
+	0x82C7, 0x3069, 0x82C8, 0x306A, 0x82C9, 0x306B, 0x82CA, 0x306C,
+	0x82CB, 0x306D, 0x82CC, 0x306E, 0x82CD, 0x306F, 0x82CE, 0x3070,
+	0x82CF, 0x3071, 0x82D0, 0x3072, 0x82D1, 0x3073, 0x82D2, 0x3074,
+	0x82D3, 0x3075, 0x82D4, 0x3076, 0x82D5, 0x3077, 0x82D6, 0x3078,
+	0x82D7, 0x3079, 0x82D8, 0x307A, 0x82D9, 0x307B, 0x82DA, 0x307C,
+	0x82DB, 0x307D, 0x82DC, 0x307E, 0x82DD, 0x307F, 0x82DE, 0x3080,
+	0x82DF, 0x3081, 0x82E0, 0x3082, 0x82E1, 0x3083, 0x82E2, 0x3084,
+	0x82E3, 0x3085, 0x82E4, 0x3086, 0x82E5, 0x3087, 0x82E6, 0x3088,
+	0x82E7, 0x3089, 0x82E8, 0x308A, 0x82E9, 0x308B, 0x82EA, 0x308C,
+	0x82EB, 0x308D, 0x82EC, 0x308E, 0x82ED, 0x308F, 0x82EE, 0x3090,
+	0x82EF, 0x3091, 0x82F0, 0x3092, 0x82F1, 0x3093, 0x8340, 0x30A1,
+	0x8341, 0x30A2, 0x8342, 0x30A3, 0x8343, 0x30A4, 0x8344, 0x30A5,
+	0x8345, 0x30A6, 0x8346, 0x30A7, 0x8347, 0x30A8, 0x8348, 0x30A9,
+	0x8349, 0x30AA, 0x834A, 0x30AB, 0x834B, 0x30AC, 0x834C, 0x30AD,
+	0x834D, 0x30AE, 0x834E, 0x30AF, 0x834F, 0x30B0, 0x8350, 0x30B1,
+	0x8351, 0x30B2, 0x8352, 0x30B3, 0x8353, 0x30B4, 0x8354, 0x30B5,
+	0x8355, 0x30B6, 0x8356, 0x30B7, 0x8357, 0x30B8, 0x8358, 0x30B9,
+	0x8359, 0x30BA, 0x835A, 0x30BB, 0x835B, 0x30BC, 0x835C, 0x30BD,
+	0x835D, 0x30BE, 0x835E, 0x30BF, 0x835F, 0x30C0, 0x8360, 0x30C1,
+	0x8361, 0x30C2, 0x8362, 0x30C3, 0x8363, 0x30C4, 0x8364, 0x30C5,
+	0x8365, 0x30C6, 0x8366, 0x30C7, 0x8367, 0x30C8, 0x8368, 0x30C9,
+	0x8369, 0x30CA, 0x836A, 0x30CB, 0x836B, 0x30CC, 0x836C, 0x30CD,
+	0x836D, 0x30CE, 0x836E, 0x30CF, 0x836F, 0x30D0, 0x8370, 0x30D1,
+	0x8371, 0x30D2, 0x8372, 0x30D3, 0x8373, 0x30D4, 0x8374, 0x30D5,
+	0x8375, 0x30D6, 0x8376, 0x30D7, 0x8377, 0x30D8, 0x8378, 0x30D9,
+	0x8379, 0x30DA, 0x837A, 0x30DB, 0x837B, 0x30DC, 0x837C, 0x30DD,
+	0x837D, 0x30DE, 0x837E, 0x30DF, 0x8380, 0x30E0, 0x8381, 0x30E1,
+	0x8382, 0x30E2, 0x8383, 0x30E3, 0x8384, 0x30E4, 0x8385, 0x30E5,
+	0x8386, 0x30E6, 0x8387, 0x30E7, 0x8388, 0x30E8, 0x8389, 0x30E9,
+	0x838A, 0x30EA, 0x838B, 0x30EB, 0x838C, 0x30EC, 0x838D, 0x30ED,
+	0x838E, 0x30EE, 0x838F, 0x30EF, 0x8390, 0x30F0, 0x8391, 0x30F1,
+	0x8392, 0x30F2, 0x8393, 0x30F3, 0x8394, 0x30F4, 0x8395, 0x30F5,
+	0x8396, 0x30F6, 0x839F, 0x0391, 0x83A0, 0x0392, 0x83A1, 0x0393,
+	0x83A2, 0x0394, 0x83A3, 0x0395, 0x83A4, 0x0396, 0x83A5, 0x0397,
+	0x83A6, 0x0398, 0x83A7, 0x0399, 0x83A8, 0x039A, 0x83A9, 0x039B,
+	0x83AA, 0x039C, 0x83AB, 0x039D, 0x83AC, 0x039E, 0x83AD, 0x039F,
+	0x83AE, 0x03A0, 0x83AF, 0x03A1, 0x83B0, 0x03A3, 0x83B1, 0x03A4,
+	0x83B2, 0x03A5, 0x83B3, 0x03A6, 0x83B4, 0x03A7, 0x83B5, 0x03A8,
+	0x83B6, 0x03A9, 0x83BF, 0x03B1, 0x83C0, 0x03B2, 0x83C1, 0x03B3,
+	0x83C2, 0x03B4, 0x83C3, 0x03B5, 0x83C4, 0x03B6, 0x83C5, 0x03B7,
+	0x83C6, 0x03B8, 0x83C7, 0x03B9, 0x83C8, 0x03BA, 0x83C9, 0x03BB,
+	0x83CA, 0x03BC, 0x83CB, 0x03BD, 0x83CC, 0x03BE, 0x83CD, 0x03BF,
+	0x83CE, 0x03C0, 0x83CF, 0x03C1, 0x83D0, 0x03C3, 0x83D1, 0x03C4,
+	0x83D2, 0x03C5, 0x83D3, 0x03C6, 0x83D4, 0x03C7, 0x83D5, 0x03C8,
+	0x83D6, 0x03C9, 0x8440, 0x0410, 0x8441, 0x0411, 0x8442, 0x0412,
+	0x8443, 0x0413, 0x8444, 0x0414, 0x8445, 0x0415, 0x8446, 0x0401,
+	0x8447, 0x0416, 0x8448, 0x0417, 0x8449, 0x0418, 0x844A, 0x0419,
+	0x844B, 0x041A, 0x844C, 0x041B, 0x844D, 0x041C, 0x844E, 0x041D,
+	0x844F, 0x041E, 0x8450, 0x041F, 0x8451, 0x0420, 0x8452, 0x0421,
+	0x8453, 0x0422, 0x8454, 0x0423, 0x8455, 0x0424, 0x8456, 0x0425,
+	0x8457, 0x0426, 0x8458, 0x0427, 0x8459, 0x0428, 0x845A, 0x0429,
+	0x845B, 0x042A, 0x845C, 0x042B, 0x845D, 0x042C, 0x845E, 0x042D,
+	0x845F, 0x042E, 0x8460, 0x042F, 0x8470, 0x0430, 0x8471, 0x0431,
+	0x8472, 0x0432, 0x8473, 0x0433, 0x8474, 0x0434, 0x8475, 0x0435,
+	0x8476, 0x0451, 0x8477, 0x0436, 0x8478, 0x0437, 0x8479, 0x0438,
+	0x847A, 0x0439, 0x847B, 0x043A, 0x847C, 0x043B, 0x847D, 0x043C,
+	0x847E, 0x043D, 0x8480, 0x043E, 0x8481, 0x043F, 0x8482, 0x0440,
+	0x8483, 0x0441, 0x8484, 0x0442, 0x8485, 0x0443, 0x8486, 0x0444,
+	0x8487, 0x0445, 0x8488, 0x0446, 0x8489, 0x0447, 0x848A, 0x0448,
+	0x848B, 0x0449, 0x848C, 0x044A, 0x848D, 0x044B, 0x848E, 0x044C,
+	0x848F, 0x044D, 0x8490, 0x044E, 0x8491, 0x044F, 0x849F, 0x2500,
+	0x84A0, 0x2502, 0x84A1, 0x250C, 0x84A2, 0x2510, 0x84A3, 0x2518,
+	0x84A4, 0x2514, 0x84A5, 0x251C, 0x84A6, 0x252C, 0x84A7, 0x2524,
+	0x84A8, 0x2534, 0x84A9, 0x253C, 0x84AA, 0x2501, 0x84AB, 0x2503,
+	0x84AC, 0x250F, 0x84AD, 0x2513, 0x84AE, 0x251B, 0x84AF, 0x2517,
+	0x84B0, 0x2523, 0x84B1, 0x2533, 0x84B2, 0x252B, 0x84B3, 0x253B,
+	0x84B4, 0x254B, 0x84B5, 0x2520, 0x84B6, 0x252F, 0x84B7, 0x2528,
+	0x84B8, 0x2537, 0x84B9, 0x253F, 0x84BA, 0x251D, 0x84BB, 0x2530,
+	0x84BC, 0x2525, 0x84BD, 0x2538, 0x84BE, 0x2542, 0x8740, 0x2460,
+	0x8741, 0x2461, 0x8742, 0x2462, 0x8743, 0x2463, 0x8744, 0x2464,
+	0x8745, 0x2465, 0x8746, 0x2466, 0x8747, 0x2467, 0x8748, 0x2468,
+	0x8749, 0x2469, 0x874A, 0x246A, 0x874B, 0x246B, 0x874C, 0x246C,
+	0x874D, 0x246D, 0x874E, 0x246E, 0x874F, 0x246F, 0x8750, 0x2470,
+	0x8751, 0x2471, 0x8752, 0x2472, 0x8753, 0x2473, 0x8754, 0x2160,
+	0x8755, 0x2161, 0x8756, 0x2162, 0x8757, 0x2163, 0x8758, 0x2164,
+	0x8759, 0x2165, 0x875A, 0x2166, 0x875B, 0x2167, 0x875C, 0x2168,
+	0x875D, 0x2169, 0x875F, 0x3349, 0x8760, 0x3314, 0x8761, 0x3322,
+	0x8762, 0x334D, 0x8763, 0x3318, 0x8764, 0x3327, 0x8765, 0x3303,
+	0x8766, 0x3336, 0x8767, 0x3351, 0x8768, 0x3357, 0x8769, 0x330D,
+	0x876A, 0x3326, 0x876B, 0x3323, 0x876C, 0x332B, 0x876D, 0x334A,
+	0x876E, 0x333B, 0x876F, 0x339C, 0x8770, 0x339D, 0x8771, 0x339E,
+	0x8772, 0x338E, 0x8773, 0x338F, 0x8774, 0x33C4, 0x8775, 0x33A1,
+	0x877E, 0x337B, 0x8780, 0x301D, 0x8781, 0x301F, 0x8782, 0x2116,
+	0x8783, 0x33CD, 0x8784, 0x2121, 0x8785, 0x32A4, 0x8786, 0x32A5,
+	0x8787, 0x32A6, 0x8788, 0x32A7, 0x8789, 0x32A8, 0x878A, 0x3231,
+	0x878B, 0x3232, 0x878C, 0x3239, 0x878D, 0x337E, 0x878E, 0x337D,
+	0x878F, 0x337C, 0x8793, 0x222E, 0x8794, 0x2211, 0x8798, 0x221F,
+	0x8799, 0x22BF, 0x889F, 0x4E9C, 0x88A0, 0x5516, 0x88A1, 0x5A03,
+	0x88A2, 0x963F, 0x88A3, 0x54C0, 0x88A4, 0x611B, 0x88A5, 0x6328,
+	0x88A6, 0x59F6, 0x88A7, 0x9022, 0x88A8, 0x8475, 0x88A9, 0x831C,
+	0x88AA, 0x7A50, 0x88AB, 0x60AA, 0x88AC, 0x63E1, 0x88AD, 0x6E25,
+	0x88AE, 0x65ED, 0x88AF, 0x8466, 0x88B0, 0x82A6, 0x88B1, 0x9BF5,
+	0x88B2, 0x6893, 0x88B3, 0x5727, 0x88B4, 0x65A1, 0x88B5, 0x6271,
+	0x88B6, 0x5B9B, 0x88B7, 0x59D0, 0x88B8, 0x867B, 0x88B9, 0x98F4,
+	0x88BA, 0x7D62, 0x88BB, 0x7DBE, 0x88BC, 0x9B8E, 0x88BD, 0x6216,
+	0x88BE, 0x7C9F, 0x88BF, 0x88B7, 0x88C0, 0x5B89, 0x88C1, 0x5EB5,
+	0x88C2, 0x6309, 0x88C3, 0x6697, 0x88C4, 0x6848, 0x88C5, 0x95C7,
+	0x88C6, 0x978D, 0x88C7, 0x674F, 0x88C8, 0x4EE5, 0x88C9, 0x4F0A,
+	0x88CA, 0x4F4D, 0x88CB, 0x4F9D, 0x88CC, 0x5049, 0x88CD, 0x56F2,
+	0x88CE, 0x5937, 0x88CF, 0x59D4, 0x88D0, 0x5A01, 0x88D1, 0x5C09,
+	0x88D2, 0x60DF, 0x88D3, 0x610F, 0x88D4, 0x6170, 0x88D5, 0x6613,
+	0x88D6, 0x6905, 0x88D7, 0x70BA, 0x88D8, 0x754F, 0x88D9, 0x7570,
+	0x88DA, 0x79FB, 0x88DB, 0x7DAD, 0x88DC, 0x7DEF, 0x88DD, 0x80C3,
+	0x88DE, 0x840E, 0x88DF, 0x8863, 0x88E0, 0x8B02, 0x88E1, 0x9055,
+	0x88E2, 0x907A, 0x88E3, 0x533B, 0x88E4, 0x4E95, 0x88E5, 0x4EA5,
+	0x88E6, 0x57DF, 0x88E7, 0x80B2, 0x88E8, 0x90C1, 0x88E9, 0x78EF,
+	0x88EA, 0x4E00, 0x88EB, 0x58F1, 0x88EC, 0x6EA2, 0x88ED, 0x9038,
+	0x88EE, 0x7A32, 0x88EF, 0x8328, 0x88F0, 0x828B, 0x88F1, 0x9C2F,
+	0x88F2, 0x5141, 0x88F3, 0x5370, 0x88F4, 0x54BD, 0x88F5, 0x54E1,
+	0x88F6, 0x56E0, 0x88F7, 0x59FB, 0x88F8, 0x5F15, 0x88F9, 0x98F2,
+	0x88FA, 0x6DEB, 0x88FB, 0x80E4, 0x88FC, 0x852D, 0x8940, 0x9662,
+	0x8941, 0x9670, 0x8942, 0x96A0, 0x8943, 0x97FB, 0x8944, 0x540B,
+	0x8945, 0x53F3, 0x8946, 0x5B87, 0x8947, 0x70CF, 0x8948, 0x7FBD,
+	0x8949, 0x8FC2, 0x894A, 0x96E8, 0x894B, 0x536F, 0x894C, 0x9D5C,
+	0x894D, 0x7ABA, 0x894E, 0x4E11, 0x894F, 0x7893, 0x8950, 0x81FC,
+	0x8951, 0x6E26, 0x8952, 0x5618, 0x8953, 0x5504, 0x8954, 0x6B1D,
+	0x8955, 0x851A, 0x8956, 0x9C3B, 0x8957, 0x59E5, 0x8958, 0x53A9,
+	0x8959, 0x6D66, 0x895A, 0x74DC, 0x895B, 0x958F, 0x895C, 0x5642,
+	0x895D, 0x4E91, 0x895E, 0x904B, 0x895F, 0x96F2, 0x8960, 0x834F,
+	0x8961, 0x990C, 0x8962, 0x53E1, 0x8963, 0x55B6, 0x8964, 0x5B30,
+	0x8965, 0x5F71, 0x8966, 0x6620, 0x8967, 0x66F3, 0x8968, 0x6804,
+	0x8969, 0x6C38, 0x896A, 0x6CF3, 0x896B, 0x6D29, 0x896C, 0x745B,
+	0x896D, 0x76C8, 0x896E, 0x7A4E, 0x896F, 0x9834, 0x8970, 0x82F1,
+	0x8971, 0x885B, 0x8972, 0x8A60, 0x8973, 0x92ED, 0x8974, 0x6DB2,
+	0x8975, 0x75AB, 0x8976, 0x76CA, 0x8977, 0x99C5, 0x8978, 0x60A6,
+	0x8979, 0x8B01, 0x897A, 0x8D8A, 0x897B, 0x95B2, 0x897C, 0x698E,
+	0x897D, 0x53AD, 0x897E, 0x5186, 0x8980, 0x5712, 0x8981, 0x5830,
+	0x8982, 0x5944, 0x8983, 0x5BB4, 0x8984, 0x5EF6, 0x8985, 0x6028,
+	0x8986, 0x63A9, 0x8987, 0x63F4, 0x8988, 0x6CBF, 0x8989, 0x6F14,
+	0x898A, 0x708E, 0x898B, 0x7114, 0x898C, 0x7159, 0x898D, 0x71D5,
+	0x898E, 0x733F, 0x898F, 0x7E01, 0x8990, 0x8276, 0x8991, 0x82D1,
+	0x8992, 0x8597, 0x8993, 0x9060, 0x8994, 0x925B, 0x8995, 0x9D1B,
+	0x8996, 0x5869, 0x8997, 0x65BC, 0x8998, 0x6C5A, 0x8999, 0x7525,
+	0x899A, 0x51F9, 0x899B, 0x592E, 0x899C, 0x5965, 0x899D, 0x5F80,
+	0x899E, 0x5FDC, 0x899F, 0x62BC, 0x89A0, 0x65FA, 0x89A1, 0x6A2A,
+	0x89A2, 0x6B27, 0x89A3, 0x6BB4, 0x89A4, 0x738B, 0x89A5, 0x7FC1,
+	0x89A6, 0x8956, 0x89A7, 0x9D2C, 0x89A8, 0x9D0E, 0x89A9, 0x9EC4,
+	0x89AA, 0x5CA1, 0x89AB, 0x6C96, 0x89AC, 0x837B, 0x89AD, 0x5104,
+	0x89AE, 0x5C4B, 0x89AF, 0x61B6, 0x89B0, 0x81C6, 0x89B1, 0x6876,
+	0x89B2, 0x7261, 0x89B3, 0x4E59, 0x89B4, 0x4FFA, 0x89B5, 0x5378,
+	0x89B6, 0x6069, 0x89B7, 0x6E29, 0x89B8, 0x7A4F, 0x89B9, 0x97F3,
+	0x89BA, 0x4E0B, 0x89BB, 0x5316, 0x89BC, 0x4EEE, 0x89BD, 0x4F55,
+	0x89BE, 0x4F3D, 0x89BF, 0x4FA1, 0x89C0, 0x4F73, 0x89C1, 0x52A0,
+	0x89C2, 0x53EF, 0x89C3, 0x5609, 0x89C4, 0x590F, 0x89C5, 0x5AC1,
+	0x89C6, 0x5BB6, 0x89C7, 0x5BE1, 0x89C8, 0x79D1, 0x89C9, 0x6687,
+	0x89CA, 0x679C, 0x89CB, 0x67B6, 0x89CC, 0x6B4C, 0x89CD, 0x6CB3,
+	0x89CE, 0x706B, 0x89CF, 0x73C2, 0x89D0, 0x798D, 0x89D1, 0x79BE,
+	0x89D2, 0x7A3C, 0x89D3, 0x7B87, 0x89D4, 0x82B1, 0x89D5, 0x82DB,
+	0x89D6, 0x8304, 0x89D7, 0x8377, 0x89D8, 0x83EF, 0x89D9, 0x83D3,
+	0x89DA, 0x8766, 0x89DB, 0x8AB2, 0x89DC, 0x5629, 0x89DD, 0x8CA8,
+	0x89DE, 0x8FE6, 0x89DF, 0x904E, 0x89E0, 0x971E, 0x89E1, 0x868A,
+	0x89E2, 0x4FC4, 0x89E3, 0x5CE8, 0x89E4, 0x6211, 0x89E5, 0x7259,
+	0x89E6, 0x753B, 0x89E7, 0x81E5, 0x89E8, 0x82BD, 0x89E9, 0x86FE,
+	0x89EA, 0x8CC0, 0x89EB, 0x96C5, 0x89EC, 0x9913, 0x89ED, 0x99D5,
+	0x89EE, 0x4ECB, 0x89EF, 0x4F1A, 0x89F0, 0x89E3, 0x89F1, 0x56DE,
+	0x89F2, 0x584A, 0x89F3, 0x58CA, 0x89F4, 0x5EFB, 0x89F5, 0x5FEB,
+	0x89F6, 0x602A, 0x89F7, 0x6094, 0x89F8, 0x6062, 0x89F9, 0x61D0,
+	0x89FA, 0x6212, 0x89FB, 0x62D0, 0x89FC, 0x6539, 0x8A40, 0x9B41,
+	0x8A41, 0x6666, 0x8A42, 0x68B0, 0x8A43, 0x6D77, 0x8A44, 0x7070,
+	0x8A45, 0x754C, 0x8A46, 0x7686, 0x8A47, 0x7D75, 0x8A48, 0x82A5,
+	0x8A49, 0x87F9, 0x8A4A, 0x958B, 0x8A4B, 0x968E, 0x8A4C, 0x8C9D,
+	0x8A4D, 0x51F1, 0x8A4E, 0x52BE, 0x8A4F, 0x5916, 0x8A50, 0x54B3,
+	0x8A51, 0x5BB3, 0x8A52, 0x5D16, 0x8A53, 0x6168, 0x8A54, 0x6982,
+	0x8A55, 0x6DAF, 0x8A56, 0x788D, 0x8A57, 0x84CB, 0x8A58, 0x8857,
+	0x8A59, 0x8A72, 0x8A5A, 0x93A7, 0x8A5B, 0x9AB8, 0x8A5C, 0x6D6C,
+	0x8A5D, 0x99A8, 0x8A5E, 0x86D9, 0x8A5F, 0x57A3, 0x8A60, 0x67FF,
+	0x8A61, 0x86CE, 0x8A62, 0x920E, 0x8A63, 0x5283, 0x8A64, 0x5687,
+	0x8A65, 0x5404, 0x8A66, 0x5ED3, 0x8A67, 0x62E1, 0x8A68, 0x64B9,
+	0x8A69, 0x683C, 0x8A6A, 0x6838, 0x8A6B, 0x6BBB, 0x8A6C, 0x7372,
+	0x8A6D, 0x78BA, 0x8A6E, 0x7A6B, 0x8A6F, 0x899A, 0x8A70, 0x89D2,
+	0x8A71, 0x8D6B, 0x8A72, 0x8F03, 0x8A73, 0x90ED, 0x8A74, 0x95A3,
+	0x8A75, 0x9694, 0x8A76, 0x9769, 0x8A77, 0x5B66, 0x8A78, 0x5CB3,
+	0x8A79, 0x697D, 0x8A7A, 0x984D, 0x8A7B, 0x984E, 0x8A7C, 0x639B,
+	0x8A7D, 0x7B20, 0x8A7E, 0x6A2B, 0x8A80, 0x6A7F, 0x8A81, 0x68B6,
+	0x8A82, 0x9C0D, 0x8A83, 0x6F5F, 0x8A84, 0x5272, 0x8A85, 0x559D,
+	0x8A86, 0x6070, 0x8A87, 0x62EC, 0x8A88, 0x6D3B, 0x8A89, 0x6E07,
+	0x8A8A, 0x6ED1, 0x8A8B, 0x845B, 0x8A8C, 0x8910, 0x8A8D, 0x8F44,
+	0x8A8E, 0x4E14, 0x8A8F, 0x9C39, 0x8A90, 0x53F6, 0x8A91, 0x691B,
+	0x8A92, 0x6A3A, 0x8A93, 0x9784, 0x8A94, 0x682A, 0x8A95, 0x515C,
+	0x8A96, 0x7AC3, 0x8A97, 0x84B2, 0x8A98, 0x91DC, 0x8A99, 0x938C,
+	0x8A9A, 0x565B, 0x8A9B, 0x9D28, 0x8A9C, 0x6822, 0x8A9D, 0x8305,
+	0x8A9E, 0x8431, 0x8A9F, 0x7CA5, 0x8AA0, 0x5208, 0x8AA1, 0x82C5,
+	0x8AA2, 0x74E6, 0x8AA3, 0x4E7E, 0x8AA4, 0x4F83, 0x8AA5, 0x51A0,
+	0x8AA6, 0x5BD2, 0x8AA7, 0x520A, 0x8AA8, 0x52D8, 0x8AA9, 0x52E7,
+	0x8AAA, 0x5DFB, 0x8AAB, 0x559A, 0x8AAC, 0x582A, 0x8AAD, 0x59E6,
+	0x8AAE, 0x5B8C, 0x8AAF, 0x5B98, 0x8AB0, 0x5BDB, 0x8AB1, 0x5E72,
+	0x8AB2, 0x5E79, 0x8AB3, 0x60A3, 0x8AB4, 0x611F, 0x8AB5, 0x6163,
+	0x8AB6, 0x61BE, 0x8AB7, 0x63DB, 0x8AB8, 0x6562, 0x8AB9, 0x67D1,
+	0x8ABA, 0x6853, 0x8ABB, 0x68FA, 0x8ABC, 0x6B3E, 0x8ABD, 0x6B53,
+	0x8ABE, 0x6C57, 0x8ABF, 0x6F22, 0x8AC0, 0x6F97, 0x8AC1, 0x6F45,
+	0x8AC2, 0x74B0, 0x8AC3, 0x7518, 0x8AC4, 0x76E3, 0x8AC5, 0x770B,
+	0x8AC6, 0x7AFF, 0x8AC7, 0x7BA1, 0x8AC8, 0x7C21, 0x8AC9, 0x7DE9,
+	0x8ACA, 0x7F36, 0x8ACB, 0x7FF0, 0x8ACC, 0x809D, 0x8ACD, 0x8266,
+	0x8ACE, 0x839E, 0x8ACF, 0x89B3, 0x8AD0, 0x8ACC, 0x8AD1, 0x8CAB,
+	0x8AD2, 0x9084, 0x8AD3, 0x9451, 0x8AD4, 0x9593, 0x8AD5, 0x9591,
+	0x8AD6, 0x95A2, 0x8AD7, 0x9665, 0x8AD8, 0x97D3, 0x8AD9, 0x9928,
+	0x8ADA, 0x8218, 0x8ADB, 0x4E38, 0x8ADC, 0x542B, 0x8ADD, 0x5CB8,
+	0x8ADE, 0x5DCC, 0x8ADF, 0x73A9, 0x8AE0, 0x764C, 0x8AE1, 0x773C,
+	0x8AE2, 0x5CA9, 0x8AE3, 0x7FEB, 0x8AE4, 0x8D0B, 0x8AE5, 0x96C1,
+	0x8AE6, 0x9811, 0x8AE7, 0x9854, 0x8AE8, 0x9858, 0x8AE9, 0x4F01,
+	0x8AEA, 0x4F0E, 0x8AEB, 0x5371, 0x8AEC, 0x559C, 0x8AED, 0x5668,
+	0x8AEE, 0x57FA, 0x8AEF, 0x5947, 0x8AF0, 0x5B09, 0x8AF1, 0x5BC4,
+	0x8AF2, 0x5C90, 0x8AF3, 0x5E0C, 0x8AF4, 0x5E7E, 0x8AF5, 0x5FCC,
+	0x8AF6, 0x63EE, 0x8AF7, 0x673A, 0x8AF8, 0x65D7, 0x8AF9, 0x65E2,
+	0x8AFA, 0x671F, 0x8AFB, 0x68CB, 0x8AFC, 0x68C4, 0x8B40, 0x6A5F,
+	0x8B41, 0x5E30, 0x8B42, 0x6BC5, 0x8B43, 0x6C17, 0x8B44, 0x6C7D,
+	0x8B45, 0x757F, 0x8B46, 0x7948, 0x8B47, 0x5B63, 0x8B48, 0x7A00,
+	0x8B49, 0x7D00, 0x8B4A, 0x5FBD, 0x8B4B, 0x898F, 0x8B4C, 0x8A18,
+	0x8B4D, 0x8CB4, 0x8B4E, 0x8D77, 0x8B4F, 0x8ECC, 0x8B50, 0x8F1D,
+	0x8B51, 0x98E2, 0x8B52, 0x9A0E, 0x8B53, 0x9B3C, 0x8B54, 0x4E80,
+	0x8B55, 0x507D, 0x8B56, 0x5100, 0x8B57, 0x5993, 0x8B58, 0x5B9C,
+	0x8B59, 0x622F, 0x8B5A, 0x6280, 0x8B5B, 0x64EC, 0x8B5C, 0x6B3A,
+	0x8B5D, 0x72A0, 0x8B5E, 0x7591, 0x8B5F, 0x7947, 0x8B60, 0x7FA9,
+	0x8B61, 0x87FB, 0x8B62, 0x8ABC, 0x8B63, 0x8B70, 0x8B64, 0x63AC,
+	0x8B65, 0x83CA, 0x8B66, 0x97A0, 0x8B67, 0x5409, 0x8B68, 0x5403,
+	0x8B69, 0x55AB, 0x8B6A, 0x6854, 0x8B6B, 0x6A58, 0x8B6C, 0x8A70,
+	0x8B6D, 0x7827, 0x8B6E, 0x6775, 0x8B6F, 0x9ECD, 0x8B70, 0x5374,
+	0x8B71, 0x5BA2, 0x8B72, 0x811A, 0x8B73, 0x8650, 0x8B74, 0x9006,
+	0x8B75, 0x4E18, 0x8B76, 0x4E45, 0x8B77, 0x4EC7, 0x8B78, 0x4F11,
+	0x8B79, 0x53CA, 0x8B7A, 0x5438, 0x8B7B, 0x5BAE, 0x8B7C, 0x5F13,
+	0x8B7D, 0x6025, 0x8B7E, 0x6551, 0x8B80, 0x673D, 0x8B81, 0x6C42,
+	0x8B82, 0x6C72, 0x8B83, 0x6CE3, 0x8B84, 0x7078, 0x8B85, 0x7403,
+	0x8B86, 0x7A76, 0x8B87, 0x7AAE, 0x8B88, 0x7B08, 0x8B89, 0x7D1A,
+	0x8B8A, 0x7CFE, 0x8B8B, 0x7D66, 0x8B8C, 0x65E7, 0x8B8D, 0x725B,
+	0x8B8E, 0x53BB, 0x8B8F, 0x5C45, 0x8B90, 0x5DE8, 0x8B91, 0x62D2,
+	0x8B92, 0x62E0, 0x8B93, 0x6319, 0x8B94, 0x6E20, 0x8B95, 0x865A,
+	0x8B96, 0x8A31, 0x8B97, 0x8DDD, 0x8B98, 0x92F8, 0x8B99, 0x6F01,
+	0x8B9A, 0x79A6, 0x8B9B, 0x9B5A, 0x8B9C, 0x4EA8, 0x8B9D, 0x4EAB,
+	0x8B9E, 0x4EAC, 0x8B9F, 0x4F9B, 0x8BA0, 0x4FA0, 0x8BA1, 0x50D1,
+	0x8BA2, 0x5147, 0x8BA3, 0x7AF6, 0x8BA4, 0x5171, 0x8BA5, 0x51F6,
+	0x8BA6, 0x5354, 0x8BA7, 0x5321, 0x8BA8, 0x537F, 0x8BA9, 0x53EB,
+	0x8BAA, 0x55AC, 0x8BAB, 0x5883, 0x8BAC, 0x5CE1, 0x8BAD, 0x5F37,
+	0x8BAE, 0x5F4A, 0x8BAF, 0x602F, 0x8BB0, 0x6050, 0x8BB1, 0x606D,
+	0x8BB2, 0x631F, 0x8BB3, 0x6559, 0x8BB4, 0x6A4B, 0x8BB5, 0x6CC1,
+	0x8BB6, 0x72C2, 0x8BB7, 0x72ED, 0x8BB8, 0x77EF, 0x8BB9, 0x80F8,
+	0x8BBA, 0x8105, 0x8BBB, 0x8208, 0x8BBC, 0x854E, 0x8BBD, 0x90F7,
+	0x8BBE, 0x93E1, 0x8BBF, 0x97FF, 0x8BC0, 0x9957, 0x8BC1, 0x9A5A,
+	0x8BC2, 0x4EF0, 0x8BC3, 0x51DD, 0x8BC4, 0x5C2D, 0x8BC5, 0x6681,
+	0x8BC6, 0x696D, 0x8BC7, 0x5C40, 0x8BC8, 0x66F2, 0x8BC9, 0x6975,
+	0x8BCA, 0x7389, 0x8BCB, 0x6850, 0x8BCC, 0x7C81, 0x8BCD, 0x50C5,
+	0x8BCE, 0x52E4, 0x8BCF, 0x5747, 0x8BD0, 0x5DFE, 0x8BD1, 0x9326,
+	0x8BD2, 0x65A4, 0x8BD3, 0x6B23, 0x8BD4, 0x6B3D, 0x8BD5, 0x7434,
+	0x8BD6, 0x7981, 0x8BD7, 0x79BD, 0x8BD8, 0x7B4B, 0x8BD9, 0x7DCA,
+	0x8BDA, 0x82B9, 0x8BDB, 0x83CC, 0x8BDC, 0x887F, 0x8BDD, 0x895F,
+	0x8BDE, 0x8B39, 0x8BDF, 0x8FD1, 0x8BE0, 0x91D1, 0x8BE1, 0x541F,
+	0x8BE2, 0x9280, 0x8BE3, 0x4E5D, 0x8BE4, 0x5036, 0x8BE5, 0x53E5,
+	0x8BE6, 0x533A, 0x8BE7, 0x72D7, 0x8BE8, 0x7396, 0x8BE9, 0x77E9,
+	0x8BEA, 0x82E6, 0x8BEB, 0x8EAF, 0x8BEC, 0x99C6, 0x8BED, 0x99C8,
+	0x8BEE, 0x99D2, 0x8BEF, 0x5177, 0x8BF0, 0x611A, 0x8BF1, 0x865E,
+	0x8BF2, 0x55B0, 0x8BF3, 0x7A7A, 0x8BF4, 0x5076, 0x8BF5, 0x5BD3,
+	0x8BF6, 0x9047, 0x8BF7, 0x9685, 0x8BF8, 0x4E32, 0x8BF9, 0x6ADB,
+	0x8BFA, 0x91E7, 0x8BFB, 0x5C51, 0x8BFC, 0x5C48, 0x8C40, 0x6398,
+	0x8C41, 0x7A9F, 0x8C42, 0x6C93, 0x8C43, 0x9774, 0x8C44, 0x8F61,
+	0x8C45, 0x7AAA, 0x8C46, 0x718A, 0x8C47, 0x9688, 0x8C48, 0x7C82,
+	0x8C49, 0x6817, 0x8C4A, 0x7E70, 0x8C4B, 0x6851, 0x8C4C, 0x936C,
+	0x8C4D, 0x52F2, 0x8C4E, 0x541B, 0x8C4F, 0x85AB, 0x8C50, 0x8A13,
+	0x8C51, 0x7FA4, 0x8C52, 0x8ECD, 0x8C53, 0x90E1, 0x8C54, 0x5366,
+	0x8C55, 0x8888, 0x8C56, 0x7941, 0x8C57, 0x4FC2, 0x8C58, 0x50BE,
+	0x8C59, 0x5211, 0x8C5A, 0x5144, 0x8C5B, 0x5553, 0x8C5C, 0x572D,
+	0x8C5D, 0x73EA, 0x8C5E, 0x578B, 0x8C5F, 0x5951, 0x8C60, 0x5F62,
+	0x8C61, 0x5F84, 0x8C62, 0x6075, 0x8C63, 0x6176, 0x8C64, 0x6167,
+	0x8C65, 0x61A9, 0x8C66, 0x63B2, 0x8C67, 0x643A, 0x8C68, 0x656C,
+	0x8C69, 0x666F, 0x8C6A, 0x6842, 0x8C6B, 0x6E13, 0x8C6C, 0x7566,
+	0x8C6D, 0x7A3D, 0x8C6E, 0x7CFB, 0x8C6F, 0x7D4C, 0x8C70, 0x7D99,
+	0x8C71, 0x7E4B, 0x8C72, 0x7F6B, 0x8C73, 0x830E, 0x8C74, 0x834A,
+	0x8C75, 0x86CD, 0x8C76, 0x8A08, 0x8C77, 0x8A63, 0x8C78, 0x8B66,
+	0x8C79, 0x8EFD, 0x8C7A, 0x981A, 0x8C7B, 0x9D8F, 0x8C7C, 0x82B8,
+	0x8C7D, 0x8FCE, 0x8C7E, 0x9BE8, 0x8C80, 0x5287, 0x8C81, 0x621F,
+	0x8C82, 0x6483, 0x8C83, 0x6FC0, 0x8C84, 0x9699, 0x8C85, 0x6841,
+	0x8C86, 0x5091, 0x8C87, 0x6B20, 0x8C88, 0x6C7A, 0x8C89, 0x6F54,
+	0x8C8A, 0x7A74, 0x8C8B, 0x7D50, 0x8C8C, 0x8840, 0x8C8D, 0x8A23,
+	0x8C8E, 0x6708, 0x8C8F, 0x4EF6, 0x8C90, 0x5039, 0x8C91, 0x5026,
+	0x8C92, 0x5065, 0x8C93, 0x517C, 0x8C94, 0x5238, 0x8C95, 0x5263,
+	0x8C96, 0x55A7, 0x8C97, 0x570F, 0x8C98, 0x5805, 0x8C99, 0x5ACC,
+	0x8C9A, 0x5EFA, 0x8C9B, 0x61B2, 0x8C9C, 0x61F8, 0x8C9D, 0x62F3,
+	0x8C9E, 0x6372, 0x8C9F, 0x691C, 0x8CA0, 0x6A29, 0x8CA1, 0x727D,
+	0x8CA2, 0x72AC, 0x8CA3, 0x732E, 0x8CA4, 0x7814, 0x8CA5, 0x786F,
+	0x8CA6, 0x7D79, 0x8CA7, 0x770C, 0x8CA8, 0x80A9, 0x8CA9, 0x898B,
+	0x8CAA, 0x8B19, 0x8CAB, 0x8CE2, 0x8CAC, 0x8ED2, 0x8CAD, 0x9063,
+	0x8CAE, 0x9375, 0x8CAF, 0x967A, 0x8CB0, 0x9855, 0x8CB1, 0x9A13,
+	0x8CB2, 0x9E78, 0x8CB3, 0x5143, 0x8CB4, 0x539F, 0x8CB5, 0x53B3,
+	0x8CB6, 0x5E7B, 0x8CB7, 0x5F26, 0x8CB8, 0x6E1B, 0x8CB9, 0x6E90,
+	0x8CBA, 0x7384, 0x8CBB, 0x73FE, 0x8CBC, 0x7D43, 0x8CBD, 0x8237,
+	0x8CBE, 0x8A00, 0x8CBF, 0x8AFA, 0x8CC0, 0x9650, 0x8CC1, 0x4E4E,
+	0x8CC2, 0x500B, 0x8CC3, 0x53E4, 0x8CC4, 0x547C, 0x8CC5, 0x56FA,
+	0x8CC6, 0x59D1, 0x8CC7, 0x5B64, 0x8CC8, 0x5DF1, 0x8CC9, 0x5EAB,
+	0x8CCA, 0x5F27, 0x8CCB, 0x6238, 0x8CCC, 0x6545, 0x8CCD, 0x67AF,
+	0x8CCE, 0x6E56, 0x8CCF, 0x72D0, 0x8CD0, 0x7CCA, 0x8CD1, 0x88B4,
+	0x8CD2, 0x80A1, 0x8CD3, 0x80E1, 0x8CD4, 0x83F0, 0x8CD5, 0x864E,
+	0x8CD6, 0x8A87, 0x8CD7, 0x8DE8, 0x8CD8, 0x9237, 0x8CD9, 0x96C7,
+	0x8CDA, 0x9867, 0x8CDB, 0x9F13, 0x8CDC, 0x4E94, 0x8CDD, 0x4E92,
+	0x8CDE, 0x4F0D, 0x8CDF, 0x5348, 0x8CE0, 0x5449, 0x8CE1, 0x543E,
+	0x8CE2, 0x5A2F, 0x8CE3, 0x5F8C, 0x8CE4, 0x5FA1, 0x8CE5, 0x609F,
+	0x8CE6, 0x68A7, 0x8CE7, 0x6A8E, 0x8CE8, 0x745A, 0x8CE9, 0x7881,
+	0x8CEA, 0x8A9E, 0x8CEB, 0x8AA4, 0x8CEC, 0x8B77, 0x8CED, 0x9190,
+	0x8CEE, 0x4E5E, 0x8CEF, 0x9BC9, 0x8CF0, 0x4EA4, 0x8CF1, 0x4F7C,
+	0x8CF2, 0x4FAF, 0x8CF3, 0x5019, 0x8CF4, 0x5016, 0x8CF5, 0x5149,
+	0x8CF6, 0x516C, 0x8CF7, 0x529F, 0x8CF8, 0x52B9, 0x8CF9, 0x52FE,
+	0x8CFA, 0x539A, 0x8CFB, 0x53E3, 0x8CFC, 0x5411, 0x8D40, 0x540E,
+	0x8D41, 0x5589, 0x8D42, 0x5751, 0x8D43, 0x57A2, 0x8D44, 0x597D,
+	0x8D45, 0x5B54, 0x8D46, 0x5B5D, 0x8D47, 0x5B8F, 0x8D48, 0x5DE5,
+	0x8D49, 0x5DE7, 0x8D4A, 0x5DF7, 0x8D4B, 0x5E78, 0x8D4C, 0x5E83,
+	0x8D4D, 0x5E9A, 0x8D4E, 0x5EB7, 0x8D4F, 0x5F18, 0x8D50, 0x6052,
+	0x8D51, 0x614C, 0x8D52, 0x6297, 0x8D53, 0x62D8, 0x8D54, 0x63A7,
+	0x8D55, 0x653B, 0x8D56, 0x6602, 0x8D57, 0x6643, 0x8D58, 0x66F4,
+	0x8D59, 0x676D, 0x8D5A, 0x6821, 0x8D5B, 0x6897, 0x8D5C, 0x69CB,
+	0x8D5D, 0x6C5F, 0x8D5E, 0x6D2A, 0x8D5F, 0x6D69, 0x8D60, 0x6E2F,
+	0x8D61, 0x6E9D, 0x8D62, 0x7532, 0x8D63, 0x7687, 0x8D64, 0x786C,
+	0x8D65, 0x7A3F, 0x8D66, 0x7CE0, 0x8D67, 0x7D05, 0x8D68, 0x7D18,
+	0x8D69, 0x7D5E, 0x8D6A, 0x7DB1, 0x8D6B, 0x8015, 0x8D6C, 0x8003,
+	0x8D6D, 0x80AF, 0x8D6E, 0x80B1, 0x8D6F, 0x8154, 0x8D70, 0x818F,
+	0x8D71, 0x822A, 0x8D72, 0x8352, 0x8D73, 0x884C, 0x8D74, 0x8861,
+	0x8D75, 0x8B1B, 0x8D76, 0x8CA2, 0x8D77, 0x8CFC, 0x8D78, 0x90CA,
+	0x8D79, 0x9175, 0x8D7A, 0x9271, 0x8D7B, 0x783F, 0x8D7C, 0x92FC,
+	0x8D7D, 0x95A4, 0x8D7E, 0x964D, 0x8D80, 0x9805, 0x8D81, 0x9999,
+	0x8D82, 0x9AD8, 0x8D83, 0x9D3B, 0x8D84, 0x525B, 0x8D85, 0x52AB,
+	0x8D86, 0x53F7, 0x8D87, 0x5408, 0x8D88, 0x58D5, 0x8D89, 0x62F7,
+	0x8D8A, 0x6FE0, 0x8D8B, 0x8C6A, 0x8D8C, 0x8F5F, 0x8D8D, 0x9EB9,
+	0x8D8E, 0x514B, 0x8D8F, 0x523B, 0x8D90, 0x544A, 0x8D91, 0x56FD,
+	0x8D92, 0x7A40, 0x8D93, 0x9177, 0x8D94, 0x9D60, 0x8D95, 0x9ED2,
+	0x8D96, 0x7344, 0x8D97, 0x6F09, 0x8D98, 0x8170, 0x8D99, 0x7511,
+	0x8D9A, 0x5FFD, 0x8D9B, 0x60DA, 0x8D9C, 0x9AA8, 0x8D9D, 0x72DB,
+	0x8D9E, 0x8FBC, 0x8D9F, 0x6B64, 0x8DA0, 0x9803, 0x8DA1, 0x4ECA,
+	0x8DA2, 0x56F0, 0x8DA3, 0x5764, 0x8DA4, 0x58BE, 0x8DA5, 0x5A5A,
+	0x8DA6, 0x6068, 0x8DA7, 0x61C7, 0x8DA8, 0x660F, 0x8DA9, 0x6606,
+	0x8DAA, 0x6839, 0x8DAB, 0x68B1, 0x8DAC, 0x6DF7, 0x8DAD, 0x75D5,
+	0x8DAE, 0x7D3A, 0x8DAF, 0x826E, 0x8DB0, 0x9B42, 0x8DB1, 0x4E9B,
+	0x8DB2, 0x4F50, 0x8DB3, 0x53C9, 0x8DB4, 0x5506, 0x8DB5, 0x5D6F,
+	0x8DB6, 0x5DE6, 0x8DB7, 0x5DEE, 0x8DB8, 0x67FB, 0x8DB9, 0x6C99,
+	0x8DBA, 0x7473, 0x8DBB, 0x7802, 0x8DBC, 0x8A50, 0x8DBD, 0x9396,
+	0x8DBE, 0x88DF, 0x8DBF, 0x5750, 0x8DC0, 0x5EA7, 0x8DC1, 0x632B,
+	0x8DC2, 0x50B5, 0x8DC3, 0x50AC, 0x8DC4, 0x518D, 0x8DC5, 0x6700,
+	0x8DC6, 0x54C9, 0x8DC7, 0x585E, 0x8DC8, 0x59BB, 0x8DC9, 0x5BB0,
+	0x8DCA, 0x5F69, 0x8DCB, 0x624D, 0x8DCC, 0x63A1, 0x8DCD, 0x683D,
+	0x8DCE, 0x6B73, 0x8DCF, 0x6E08, 0x8DD0, 0x707D, 0x8DD1, 0x91C7,
+	0x8DD2, 0x7280, 0x8DD3, 0x7815, 0x8DD4, 0x7826, 0x8DD5, 0x796D,
+	0x8DD6, 0x658E, 0x8DD7, 0x7D30, 0x8DD8, 0x83DC, 0x8DD9, 0x88C1,
+	0x8DDA, 0x8F09, 0x8DDB, 0x969B, 0x8DDC, 0x5264, 0x8DDD, 0x5728,
+	0x8DDE, 0x6750, 0x8DDF, 0x7F6A, 0x8DE0, 0x8CA1, 0x8DE1, 0x51B4,
+	0x8DE2, 0x5742, 0x8DE3, 0x962A, 0x8DE4, 0x583A, 0x8DE5, 0x698A,
+	0x8DE6, 0x80B4, 0x8DE7, 0x54B2, 0x8DE8, 0x5D0E, 0x8DE9, 0x57FC,
+	0x8DEA, 0x7895, 0x8DEB, 0x9DFA, 0x8DEC, 0x4F5C, 0x8DED, 0x524A,
+	0x8DEE, 0x548B, 0x8DEF, 0x643E, 0x8DF0, 0x6628, 0x8DF1, 0x6714,
+	0x8DF2, 0x67F5, 0x8DF3, 0x7A84, 0x8DF4, 0x7B56, 0x8DF5, 0x7D22,
+	0x8DF6, 0x932F, 0x8DF7, 0x685C, 0x8DF8, 0x9BAD, 0x8DF9, 0x7B39,
+	0x8DFA, 0x5319, 0x8DFB, 0x518A, 0x8DFC, 0x5237, 0x8E40, 0x5BDF,
+	0x8E41, 0x62F6, 0x8E42, 0x64AE, 0x8E43, 0x64E6, 0x8E44, 0x672D,
+	0x8E45, 0x6BBA, 0x8E46, 0x85A9, 0x8E47, 0x96D1, 0x8E48, 0x7690,
+	0x8E49, 0x9BD6, 0x8E4A, 0x634C, 0x8E4B, 0x9306, 0x8E4C, 0x9BAB,
+	0x8E4D, 0x76BF, 0x8E4E, 0x6652, 0x8E4F, 0x4E09, 0x8E50, 0x5098,
+	0x8E51, 0x53C2, 0x8E52, 0x5C71, 0x8E53, 0x60E8, 0x8E54, 0x6492,
+	0x8E55, 0x6563, 0x8E56, 0x685F, 0x8E57, 0x71E6, 0x8E58, 0x73CA,
+	0x8E59, 0x7523, 0x8E5A, 0x7B97, 0x8E5B, 0x7E82, 0x8E5C, 0x8695,
+	0x8E5D, 0x8B83, 0x8E5E, 0x8CDB, 0x8E5F, 0x9178, 0x8E60, 0x9910,
+	0x8E61, 0x65AC, 0x8E62, 0x66AB, 0x8E63, 0x6B8B, 0x8E64, 0x4ED5,
+	0x8E65, 0x4ED4, 0x8E66, 0x4F3A, 0x8E67, 0x4F7F, 0x8E68, 0x523A,
+	0x8E69, 0x53F8, 0x8E6A, 0x53F2, 0x8E6B, 0x55E3, 0x8E6C, 0x56DB,
+	0x8E6D, 0x58EB, 0x8E6E, 0x59CB, 0x8E6F, 0x59C9, 0x8E70, 0x59FF,
+	0x8E71, 0x5B50, 0x8E72, 0x5C4D, 0x8E73, 0x5E02, 0x8E74, 0x5E2B,
+	0x8E75, 0x5FD7, 0x8E76, 0x601D, 0x8E77, 0x6307, 0x8E78, 0x652F,
+	0x8E79, 0x5B5C, 0x8E7A, 0x65AF, 0x8E7B, 0x65BD, 0x8E7C, 0x65E8,
+	0x8E7D, 0x679D, 0x8E7E, 0x6B62, 0x8E80, 0x6B7B, 0x8E81, 0x6C0F,
+	0x8E82, 0x7345, 0x8E83, 0x7949, 0x8E84, 0x79C1, 0x8E85, 0x7CF8,
+	0x8E86, 0x7D19, 0x8E87, 0x7D2B, 0x8E88, 0x80A2, 0x8E89, 0x8102,
+	0x8E8A, 0x81F3, 0x8E8B, 0x8996, 0x8E8C, 0x8A5E, 0x8E8D, 0x8A69,
+	0x8E8E, 0x8A66, 0x8E8F, 0x8A8C, 0x8E90, 0x8AEE, 0x8E91, 0x8CC7,
+	0x8E92, 0x8CDC, 0x8E93, 0x96CC, 0x8E94, 0x98FC, 0x8E95, 0x6B6F,
+	0x8E96, 0x4E8B, 0x8E97, 0x4F3C, 0x8E98, 0x4F8D, 0x8E99, 0x5150,
+	0x8E9A, 0x5B57, 0x8E9B, 0x5BFA, 0x8E9C, 0x6148, 0x8E9D, 0x6301,
+	0x8E9E, 0x6642, 0x8E9F, 0x6B21, 0x8EA0, 0x6ECB, 0x8EA1, 0x6CBB,
+	0x8EA2, 0x723E, 0x8EA3, 0x74BD, 0x8EA4, 0x75D4, 0x8EA5, 0x78C1,
+	0x8EA6, 0x793A, 0x8EA7, 0x800C, 0x8EA8, 0x8033, 0x8EA9, 0x81EA,
+	0x8EAA, 0x8494, 0x8EAB, 0x8F9E, 0x8EAC, 0x6C50, 0x8EAD, 0x9E7F,
+	0x8EAE, 0x5F0F, 0x8EAF, 0x8B58, 0x8EB0, 0x9D2B, 0x8EB1, 0x7AFA,
+	0x8EB2, 0x8EF8, 0x8EB3, 0x5B8D, 0x8EB4, 0x96EB, 0x8EB5, 0x4E03,
+	0x8EB6, 0x53F1, 0x8EB7, 0x57F7, 0x8EB8, 0x5931, 0x8EB9, 0x5AC9,
+	0x8EBA, 0x5BA4, 0x8EBB, 0x6089, 0x8EBC, 0x6E7F, 0x8EBD, 0x6F06,
+	0x8EBE, 0x75BE, 0x8EBF, 0x8CEA, 0x8EC0, 0x5B9F, 0x8EC1, 0x8500,
+	0x8EC2, 0x7BE0, 0x8EC3, 0x5072, 0x8EC4, 0x67F4, 0x8EC5, 0x829D,
+	0x8EC6, 0x5C61, 0x8EC7, 0x854A, 0x8EC8, 0x7E1E, 0x8EC9, 0x820E,
+	0x8ECA, 0x5199, 0x8ECB, 0x5C04, 0x8ECC, 0x6368, 0x8ECD, 0x8D66,
+	0x8ECE, 0x659C, 0x8ECF, 0x716E, 0x8ED0, 0x793E, 0x8ED1, 0x7D17,
+	0x8ED2, 0x8005, 0x8ED3, 0x8B1D, 0x8ED4, 0x8ECA, 0x8ED5, 0x906E,
+	0x8ED6, 0x86C7, 0x8ED7, 0x90AA, 0x8ED8, 0x501F, 0x8ED9, 0x52FA,
+	0x8EDA, 0x5C3A, 0x8EDB, 0x6753, 0x8EDC, 0x707C, 0x8EDD, 0x7235,
+	0x8EDE, 0x914C, 0x8EDF, 0x91C8, 0x8EE0, 0x932B, 0x8EE1, 0x82E5,
+	0x8EE2, 0x5BC2, 0x8EE3, 0x5F31, 0x8EE4, 0x60F9, 0x8EE5, 0x4E3B,
+	0x8EE6, 0x53D6, 0x8EE7, 0x5B88, 0x8EE8, 0x624B, 0x8EE9, 0x6731,
+	0x8EEA, 0x6B8A, 0x8EEB, 0x72E9, 0x8EEC, 0x73E0, 0x8EED, 0x7A2E,
+	0x8EEE, 0x816B, 0x8EEF, 0x8DA3, 0x8EF0, 0x9152, 0x8EF1, 0x9996,
+	0x8EF2, 0x5112, 0x8EF3, 0x53D7, 0x8EF4, 0x546A, 0x8EF5, 0x5BFF,
+	0x8EF6, 0x6388, 0x8EF7, 0x6A39, 0x8EF8, 0x7DAC, 0x8EF9, 0x9700,
+	0x8EFA, 0x56DA, 0x8EFB, 0x53CE, 0x8EFC, 0x5468, 0x8F40, 0x5B97,
+	0x8F41, 0x5C31, 0x8F42, 0x5DDE, 0x8F43, 0x4FEE, 0x8F44, 0x6101,
+	0x8F45, 0x62FE, 0x8F46, 0x6D32, 0x8F47, 0x79C0, 0x8F48, 0x79CB,
+	0x8F49, 0x7D42, 0x8F4A, 0x7E4D, 0x8F4B, 0x7FD2, 0x8F4C, 0x81ED,
+	0x8F4D, 0x821F, 0x8F4E, 0x8490, 0x8F4F, 0x8846, 0x8F50, 0x8972,
+	0x8F51, 0x8B90, 0x8F52, 0x8E74, 0x8F53, 0x8F2F, 0x8F54, 0x9031,
+	0x8F55, 0x914B, 0x8F56, 0x916C, 0x8F57, 0x96C6, 0x8F58, 0x919C,
+	0x8F59, 0x4EC0, 0x8F5A, 0x4F4F, 0x8F5B, 0x5145, 0x8F5C, 0x5341,
+	0x8F5D, 0x5F93, 0x8F5E, 0x620E, 0x8F5F, 0x67D4, 0x8F60, 0x6C41,
+	0x8F61, 0x6E0B, 0x8F62, 0x7363, 0x8F63, 0x7E26, 0x8F64, 0x91CD,
+	0x8F65, 0x9283, 0x8F66, 0x53D4, 0x8F67, 0x5919, 0x8F68, 0x5BBF,
+	0x8F69, 0x6DD1, 0x8F6A, 0x795D, 0x8F6B, 0x7E2E, 0x8F6C, 0x7C9B,
+	0x8F6D, 0x587E, 0x8F6E, 0x719F, 0x8F6F, 0x51FA, 0x8F70, 0x8853,
+	0x8F71, 0x8FF0, 0x8F72, 0x4FCA, 0x8F73, 0x5CFB, 0x8F74, 0x6625,
+	0x8F75, 0x77AC, 0x8F76, 0x7AE3, 0x8F77, 0x821C, 0x8F78, 0x99FF,
+	0x8F79, 0x51C6, 0x8F7A, 0x5FAA, 0x8F7B, 0x65EC, 0x8F7C, 0x696F,
+	0x8F7D, 0x6B89, 0x8F7E, 0x6DF3, 0x8F80, 0x6E96, 0x8F81, 0x6F64,
+	0x8F82, 0x76FE, 0x8F83, 0x7D14, 0x8F84, 0x5DE1, 0x8F85, 0x9075,
+	0x8F86, 0x9187, 0x8F87, 0x9806, 0x8F88, 0x51E6, 0x8F89, 0x521D,
+	0x8F8A, 0x6240, 0x8F8B, 0x6691, 0x8F8C, 0x66D9, 0x8F8D, 0x6E1A,
+	0x8F8E, 0x5EB6, 0x8F8F, 0x7DD2, 0x8F90, 0x7F72, 0x8F91, 0x66F8,
+	0x8F92, 0x85AF, 0x8F93, 0x85F7, 0x8F94, 0x8AF8, 0x8F95, 0x52A9,
+	0x8F96, 0x53D9, 0x8F97, 0x5973, 0x8F98, 0x5E8F, 0x8F99, 0x5F90,
+	0x8F9A, 0x6055, 0x8F9B, 0x92E4, 0x8F9C, 0x9664, 0x8F9D, 0x50B7,
+	0x8F9E, 0x511F, 0x8F9F, 0x52DD, 0x8FA0, 0x5320, 0x8FA1, 0x5347,
+	0x8FA2, 0x53EC, 0x8FA3, 0x54E8, 0x8FA4, 0x5546, 0x8FA5, 0x5531,
+	0x8FA6, 0x5617, 0x8FA7, 0x5968, 0x8FA8, 0x59BE, 0x8FA9, 0x5A3C,
+	0x8FAA, 0x5BB5, 0x8FAB, 0x5C06, 0x8FAC, 0x5C0F, 0x8FAD, 0x5C11,
+	0x8FAE, 0x5C1A, 0x8FAF, 0x5E84, 0x8FB0, 0x5E8A, 0x8FB1, 0x5EE0,
+	0x8FB2, 0x5F70, 0x8FB3, 0x627F, 0x8FB4, 0x6284, 0x8FB5, 0x62DB,
+	0x8FB6, 0x638C, 0x8FB7, 0x6377, 0x8FB8, 0x6607, 0x8FB9, 0x660C,
+	0x8FBA, 0x662D, 0x8FBB, 0x6676, 0x8FBC, 0x677E, 0x8FBD, 0x68A2,
+	0x8FBE, 0x6A1F, 0x8FBF, 0x6A35, 0x8FC0, 0x6CBC, 0x8FC1, 0x6D88,
+	0x8FC2, 0x6E09, 0x8FC3, 0x6E58, 0x8FC4, 0x713C, 0x8FC5, 0x7126,
+	0x8FC6, 0x7167, 0x8FC7, 0x75C7, 0x8FC8, 0x7701, 0x8FC9, 0x785D,
+	0x8FCA, 0x7901, 0x8FCB, 0x7965, 0x8FCC, 0x79F0, 0x8FCD, 0x7AE0,
+	0x8FCE, 0x7B11, 0x8FCF, 0x7CA7, 0x8FD0, 0x7D39, 0x8FD1, 0x8096,
+	0x8FD2, 0x83D6, 0x8FD3, 0x848B, 0x8FD4, 0x8549, 0x8FD5, 0x885D,
+	0x8FD6, 0x88F3, 0x8FD7, 0x8A1F, 0x8FD8, 0x8A3C, 0x8FD9, 0x8A54,
+	0x8FDA, 0x8A73, 0x8FDB, 0x8C61, 0x8FDC, 0x8CDE, 0x8FDD, 0x91A4,
+	0x8FDE, 0x9266, 0x8FDF, 0x937E, 0x8FE0, 0x9418, 0x8FE1, 0x969C,
+	0x8FE2, 0x9798, 0x8FE3, 0x4E0A, 0x8FE4, 0x4E08, 0x8FE5, 0x4E1E,
+	0x8FE6, 0x4E57, 0x8FE7, 0x5197, 0x8FE8, 0x5270, 0x8FE9, 0x57CE,
+	0x8FEA, 0x5834, 0x8FEB, 0x58CC, 0x8FEC, 0x5B22, 0x8FED, 0x5E38,
+	0x8FEE, 0x60C5, 0x8FEF, 0x64FE, 0x8FF0, 0x6761, 0x8FF1, 0x6756,
+	0x8FF2, 0x6D44, 0x8FF3, 0x72B6, 0x8FF4, 0x7573, 0x8FF5, 0x7A63,
+	0x8FF6, 0x84B8, 0x8FF7, 0x8B72, 0x8FF8, 0x91B8, 0x8FF9, 0x9320,
+	0x8FFA, 0x5631, 0x8FFB, 0x57F4, 0x8FFC, 0x98FE, 0x9040, 0x62ED,
+	0x9041, 0x690D, 0x9042, 0x6B96, 0x9043, 0x71ED, 0x9044, 0x7E54,
+	0x9045, 0x8077, 0x9046, 0x8272, 0x9047, 0x89E6, 0x9048, 0x98DF,
+	0x9049, 0x8755, 0x904A, 0x8FB1, 0x904B, 0x5C3B, 0x904C, 0x4F38,
+	0x904D, 0x4FE1, 0x904E, 0x4FB5, 0x904F, 0x5507, 0x9050, 0x5A20,
+	0x9051, 0x5BDD, 0x9052, 0x5BE9, 0x9053, 0x5FC3, 0x9054, 0x614E,
+	0x9055, 0x632F, 0x9056, 0x65B0, 0x9057, 0x664B, 0x9058, 0x68EE,
+	0x9059, 0x699B, 0x905A, 0x6D78, 0x905B, 0x6DF1, 0x905C, 0x7533,
+	0x905D, 0x75B9, 0x905E, 0x771F, 0x905F, 0x795E, 0x9060, 0x79E6,
+	0x9061, 0x7D33, 0x9062, 0x81E3, 0x9063, 0x82AF, 0x9064, 0x85AA,
+	0x9065, 0x89AA, 0x9066, 0x8A3A, 0x9067, 0x8EAB, 0x9068, 0x8F9B,
+	0x9069, 0x9032, 0x906A, 0x91DD, 0x906B, 0x9707, 0x906C, 0x4EBA,
+	0x906D, 0x4EC1, 0x906E, 0x5203, 0x906F, 0x5875, 0x9070, 0x58EC,
+	0x9071, 0x5C0B, 0x9072, 0x751A, 0x9073, 0x5C3D, 0x9074, 0x814E,
+	0x9075, 0x8A0A, 0x9076, 0x8FC5, 0x9077, 0x9663, 0x9078, 0x976D,
+	0x9079, 0x7B25, 0x907A, 0x8ACF, 0x907B, 0x9808, 0x907C, 0x9162,
+	0x907D, 0x56F3, 0x907E, 0x53A8, 0x9080, 0x9017, 0x9081, 0x5439,
+	0x9082, 0x5782, 0x9083, 0x5E25, 0x9084, 0x63A8, 0x9085, 0x6C34,
+	0x9086, 0x708A, 0x9087, 0x7761, 0x9088, 0x7C8B, 0x9089, 0x7FE0,
+	0x908A, 0x8870, 0x908B, 0x9042, 0x908C, 0x9154, 0x908D, 0x9310,
+	0x908E, 0x9318, 0x908F, 0x968F, 0x9090, 0x745E, 0x9091, 0x9AC4,
+	0x9092, 0x5D07, 0x9093, 0x5D69, 0x9094, 0x6570, 0x9095, 0x67A2,
+	0x9096, 0x8DA8, 0x9097, 0x96DB, 0x9098, 0x636E, 0x9099, 0x6749,
+	0x909A, 0x6919, 0x909B, 0x83C5, 0x909C, 0x9817, 0x909D, 0x96C0,
+	0x909E, 0x88FE, 0x909F, 0x6F84, 0x90A0, 0x647A, 0x90A1, 0x5BF8,
+	0x90A2, 0x4E16, 0x90A3, 0x702C, 0x90A4, 0x755D, 0x90A5, 0x662F,
+	0x90A6, 0x51C4, 0x90A7, 0x5236, 0x90A8, 0x52E2, 0x90A9, 0x59D3,
+	0x90AA, 0x5F81, 0x90AB, 0x6027, 0x90AC, 0x6210, 0x90AD, 0x653F,
+	0x90AE, 0x6574, 0x90AF, 0x661F, 0x90B0, 0x6674, 0x90B1, 0x68F2,
+	0x90B2, 0x6816, 0x90B3, 0x6B63, 0x90B4, 0x6E05, 0x90B5, 0x7272,
+	0x90B6, 0x751F, 0x90B7, 0x76DB, 0x90B8, 0x7CBE, 0x90B9, 0x8056,
+	0x90BA, 0x58F0, 0x90BB, 0x88FD, 0x90BC, 0x897F, 0x90BD, 0x8AA0,
+	0x90BE, 0x8A93, 0x90BF, 0x8ACB, 0x90C0, 0x901D, 0x90C1, 0x9192,
+	0x90C2, 0x9752, 0x90C3, 0x9759, 0x90C4, 0x6589, 0x90C5, 0x7A0E,
+	0x90C6, 0x8106, 0x90C7, 0x96BB, 0x90C8, 0x5E2D, 0x90C9, 0x60DC,
+	0x90CA, 0x621A, 0x90CB, 0x65A5, 0x90CC, 0x6614, 0x90CD, 0x6790,
+	0x90CE, 0x77F3, 0x90CF, 0x7A4D, 0x90D0, 0x7C4D, 0x90D1, 0x7E3E,
+	0x90D2, 0x810A, 0x90D3, 0x8CAC, 0x90D4, 0x8D64, 0x90D5, 0x8DE1,
+	0x90D6, 0x8E5F, 0x90D7, 0x78A9, 0x90D8, 0x5207, 0x90D9, 0x62D9,
+	0x90DA, 0x63A5, 0x90DB, 0x6442, 0x90DC, 0x6298, 0x90DD, 0x8A2D,
+	0x90DE, 0x7A83, 0x90DF, 0x7BC0, 0x90E0, 0x8AAC, 0x90E1, 0x96EA,
+	0x90E2, 0x7D76, 0x90E3, 0x820C, 0x90E4, 0x8749, 0x90E5, 0x4ED9,
+	0x90E6, 0x5148, 0x90E7, 0x5343, 0x90E8, 0x5360, 0x90E9, 0x5BA3,
+	0x90EA, 0x5C02, 0x90EB, 0x5C16, 0x90EC, 0x5DDD, 0x90ED, 0x6226,
+	0x90EE, 0x6247, 0x90EF, 0x64B0, 0x90F0, 0x6813, 0x90F1, 0x6834,
+	0x90F2, 0x6CC9, 0x90F3, 0x6D45, 0x90F4, 0x6D17, 0x90F5, 0x67D3,
+	0x90F6, 0x6F5C, 0x90F7, 0x714E, 0x90F8, 0x717D, 0x90F9, 0x65CB,
+	0x90FA, 0x7A7F, 0x90FB, 0x7BAD, 0x90FC, 0x7DDA, 0x9140, 0x7E4A,
+	0x9141, 0x7FA8, 0x9142, 0x817A, 0x9143, 0x821B, 0x9144, 0x8239,
+	0x9145, 0x85A6, 0x9146, 0x8A6E, 0x9147, 0x8CCE, 0x9148, 0x8DF5,
+	0x9149, 0x9078, 0x914A, 0x9077, 0x914B, 0x92AD, 0x914C, 0x9291,
+	0x914D, 0x9583, 0x914E, 0x9BAE, 0x914F, 0x524D, 0x9150, 0x5584,
+	0x9151, 0x6F38, 0x9152, 0x7136, 0x9153, 0x5168, 0x9154, 0x7985,
+	0x9155, 0x7E55, 0x9156, 0x81B3, 0x9157, 0x7CCE, 0x9158, 0x564C,
+	0x9159, 0x5851, 0x915A, 0x5CA8, 0x915B, 0x63AA, 0x915C, 0x66FE,
+	0x915D, 0x66FD, 0x915E, 0x695A, 0x915F, 0x72D9, 0x9160, 0x758F,
+	0x9161, 0x758E, 0x9162, 0x790E, 0x9163, 0x7956, 0x9164, 0x79DF,
+	0x9165, 0x7C97, 0x9166, 0x7D20, 0x9167, 0x7D44, 0x9168, 0x8607,
+	0x9169, 0x8A34, 0x916A, 0x963B, 0x916B, 0x9061, 0x916C, 0x9F20,
+	0x916D, 0x50E7, 0x916E, 0x5275, 0x916F, 0x53CC, 0x9170, 0x53E2,
+	0x9171, 0x5009, 0x9172, 0x55AA, 0x9173, 0x58EE, 0x9174, 0x594F,
+	0x9175, 0x723D, 0x9176, 0x5B8B, 0x9177, 0x5C64, 0x9178, 0x531D,
+	0x9179, 0x60E3, 0x917A, 0x60F3, 0x917B, 0x635C, 0x917C, 0x6383,
+	0x917D, 0x633F, 0x917E, 0x63BB, 0x9180, 0x64CD, 0x9181, 0x65E9,
+	0x9182, 0x66F9, 0x9183, 0x5DE3, 0x9184, 0x69CD, 0x9185, 0x69FD,
+	0x9186, 0x6F15, 0x9187, 0x71E5, 0x9188, 0x4E89, 0x9189, 0x75E9,
+	0x918A, 0x76F8, 0x918B, 0x7A93, 0x918C, 0x7CDF, 0x918D, 0x7DCF,
+	0x918E, 0x7D9C, 0x918F, 0x8061, 0x9190, 0x8349, 0x9191, 0x8358,
+	0x9192, 0x846C, 0x9193, 0x84BC, 0x9194, 0x85FB, 0x9195, 0x88C5,
+	0x9196, 0x8D70, 0x9197, 0x9001, 0x9198, 0x906D, 0x9199, 0x9397,
+	0x919A, 0x971C, 0x919B, 0x9A12, 0x919C, 0x50CF, 0x919D, 0x5897,
+	0x919E, 0x618E, 0x919F, 0x81D3, 0x91A0, 0x8535, 0x91A1, 0x8D08,
+	0x91A2, 0x9020, 0x91A3, 0x4FC3, 0x91A4, 0x5074, 0x91A5, 0x5247,
+	0x91A6, 0x5373, 0x91A7, 0x606F, 0x91A8, 0x6349, 0x91A9, 0x675F,
+	0x91AA, 0x6E2C, 0x91AB, 0x8DB3, 0x91AC, 0x901F, 0x91AD, 0x4FD7,
+	0x91AE, 0x5C5E, 0x91AF, 0x8CCA, 0x91B0, 0x65CF, 0x91B1, 0x7D9A,
+	0x91B2, 0x5352, 0x91B3, 0x8896, 0x91B4, 0x5176, 0x91B5, 0x63C3,
+	0x91B6, 0x5B58, 0x91B7, 0x5B6B, 0x91B8, 0x5C0A, 0x91B9, 0x640D,
+	0x91BA, 0x6751, 0x91BB, 0x905C, 0x91BC, 0x4ED6, 0x91BD, 0x591A,
+	0x91BE, 0x592A, 0x91BF, 0x6C70, 0x91C0, 0x8A51, 0x91C1, 0x553E,
+	0x91C2, 0x5815, 0x91C3, 0x59A5, 0x91C4, 0x60F0, 0x91C5, 0x6253,
+	0x91C6, 0x67C1, 0x91C7, 0x8235, 0x91C8, 0x6955, 0x91C9, 0x9640,
+	0x91CA, 0x99C4, 0x91CB, 0x9A28, 0x91CC, 0x4F53, 0x91CD, 0x5806,
+	0x91CE, 0x5BFE, 0x91CF, 0x8010, 0x91D0, 0x5CB1, 0x91D1, 0x5E2F,
+	0x91D2, 0x5F85, 0x91D3, 0x6020, 0x91D4, 0x614B, 0x91D5, 0x6234,
+	0x91D6, 0x66FF, 0x91D7, 0x6CF0, 0x91D8, 0x6EDE, 0x91D9, 0x80CE,
+	0x91DA, 0x817F, 0x91DB, 0x82D4, 0x91DC, 0x888B, 0x91DD, 0x8CB8,
+	0x91DE, 0x9000, 0x91DF, 0x902E, 0x91E0, 0x968A, 0x91E1, 0x9EDB,
+	0x91E2, 0x9BDB, 0x91E3, 0x4EE3, 0x91E4, 0x53F0, 0x91E5, 0x5927,
+	0x91E6, 0x7B2C, 0x91E7, 0x918D, 0x91E8, 0x984C, 0x91E9, 0x9DF9,
+	0x91EA, 0x6EDD, 0x91EB, 0x7027, 0x91EC, 0x5353, 0x91ED, 0x5544,
+	0x91EE, 0x5B85, 0x91EF, 0x6258, 0x91F0, 0x629E, 0x91F1, 0x62D3,
+	0x91F2, 0x6CA2, 0x91F3, 0x6FEF, 0x91F4, 0x7422, 0x91F5, 0x8A17,
+	0x91F6, 0x9438, 0x91F7, 0x6FC1, 0x91F8, 0x8AFE, 0x91F9, 0x8338,
+	0x91FA, 0x51E7, 0x91FB, 0x86F8, 0x91FC, 0x53EA, 0x9240, 0x53E9,
+	0x9241, 0x4F46, 0x9242, 0x9054, 0x9243, 0x8FB0, 0x9244, 0x596A,
+	0x9245, 0x8131, 0x9246, 0x5DFD, 0x9247, 0x7AEA, 0x9248, 0x8FBF,
+	0x9249, 0x68DA, 0x924A, 0x8C37, 0x924B, 0x72F8, 0x924C, 0x9C48,
+	0x924D, 0x6A3D, 0x924E, 0x8AB0, 0x924F, 0x4E39, 0x9250, 0x5358,
+	0x9251, 0x5606, 0x9252, 0x5766, 0x9253, 0x62C5, 0x9254, 0x63A2,
+	0x9255, 0x65E6, 0x9256, 0x6B4E, 0x9257, 0x6DE1, 0x9258, 0x6E5B,
+	0x9259, 0x70AD, 0x925A, 0x77ED, 0x925B, 0x7AEF, 0x925C, 0x7BAA,
+	0x925D, 0x7DBB, 0x925E, 0x803D, 0x925F, 0x80C6, 0x9260, 0x86CB,
+	0x9261, 0x8A95, 0x9262, 0x935B, 0x9263, 0x56E3, 0x9264, 0x58C7,
+	0x9265, 0x5F3E, 0x9266, 0x65AD, 0x9267, 0x6696, 0x9268, 0x6A80,
+	0x9269, 0x6BB5, 0x926A, 0x7537, 0x926B, 0x8AC7, 0x926C, 0x5024,
+	0x926D, 0x77E5, 0x926E, 0x5730, 0x926F, 0x5F1B, 0x9270, 0x6065,
+	0x9271, 0x667A, 0x9272, 0x6C60, 0x9273, 0x75F4, 0x9274, 0x7A1A,
+	0x9275, 0x7F6E, 0x9276, 0x81F4, 0x9277, 0x8718, 0x9278, 0x9045,
+	0x9279, 0x99B3, 0x927A, 0x7BC9, 0x927B, 0x755C, 0x927C, 0x7AF9,
+	0x927D, 0x7B51, 0x927E, 0x84C4, 0x9280, 0x9010, 0x9281, 0x79E9,
+	0x9282, 0x7A92, 0x9283, 0x8336, 0x9284, 0x5AE1, 0x9285, 0x7740,
+	0x9286, 0x4E2D, 0x9287, 0x4EF2, 0x9288, 0x5B99, 0x9289, 0x5FE0,
+	0x928A, 0x62BD, 0x928B, 0x663C, 0x928C, 0x67F1, 0x928D, 0x6CE8,
+	0x928E, 0x866B, 0x928F, 0x8877, 0x9290, 0x8A3B, 0x9291, 0x914E,
+	0x9292, 0x92F3, 0x9293, 0x99D0, 0x9294, 0x6A17, 0x9295, 0x7026,
+	0x9296, 0x732A, 0x9297, 0x82E7, 0x9298, 0x8457, 0x9299, 0x8CAF,
+	0x929A, 0x4E01, 0x929B, 0x5146, 0x929C, 0x51CB, 0x929D, 0x558B,
+	0x929E, 0x5BF5, 0x929F, 0x5E16, 0x92A0, 0x5E33, 0x92A1, 0x5E81,
+	0x92A2, 0x5F14, 0x92A3, 0x5F35, 0x92A4, 0x5F6B, 0x92A5, 0x5FB4,
+	0x92A6, 0x61F2, 0x92A7, 0x6311, 0x92A8, 0x66A2, 0x92A9, 0x671D,
+	0x92AA, 0x6F6E, 0x92AB, 0x7252, 0x92AC, 0x753A, 0x92AD, 0x773A,
+	0x92AE, 0x8074, 0x92AF, 0x8139, 0x92B0, 0x8178, 0x92B1, 0x8776,
+	0x92B2, 0x8ABF, 0x92B3, 0x8ADC, 0x92B4, 0x8D85, 0x92B5, 0x8DF3,
+	0x92B6, 0x929A, 0x92B7, 0x9577, 0x92B8, 0x9802, 0x92B9, 0x9CE5,
+	0x92BA, 0x52C5, 0x92BB, 0x6357, 0x92BC, 0x76F4, 0x92BD, 0x6715,
+	0x92BE, 0x6C88, 0x92BF, 0x73CD, 0x92C0, 0x8CC3, 0x92C1, 0x93AE,
+	0x92C2, 0x9673, 0x92C3, 0x6D25, 0x92C4, 0x589C, 0x92C5, 0x690E,
+	0x92C6, 0x69CC, 0x92C7, 0x8FFD, 0x92C8, 0x939A, 0x92C9, 0x75DB,
+	0x92CA, 0x901A, 0x92CB, 0x585A, 0x92CC, 0x6802, 0x92CD, 0x63B4,
+	0x92CE, 0x69FB, 0x92CF, 0x4F43, 0x92D0, 0x6F2C, 0x92D1, 0x67D8,
+	0x92D2, 0x8FBB, 0x92D3, 0x8526, 0x92D4, 0x7DB4, 0x92D5, 0x9354,
+	0x92D6, 0x693F, 0x92D7, 0x6F70, 0x92D8, 0x576A, 0x92D9, 0x58F7,
+	0x92DA, 0x5B2C, 0x92DB, 0x7D2C, 0x92DC, 0x722A, 0x92DD, 0x540A,
+	0x92DE, 0x91E3, 0x92DF, 0x9DB4, 0x92E0, 0x4EAD, 0x92E1, 0x4F4E,
+	0x92E2, 0x505C, 0x92E3, 0x5075, 0x92E4, 0x5243, 0x92E5, 0x8C9E,
+	0x92E6, 0x5448, 0x92E7, 0x5824, 0x92E8, 0x5B9A, 0x92E9, 0x5E1D,
+	0x92EA, 0x5E95, 0x92EB, 0x5EAD, 0x92EC, 0x5EF7, 0x92ED, 0x5F1F,
+	0x92EE, 0x608C, 0x92EF, 0x62B5, 0x92F0, 0x633A, 0x92F1, 0x63D0,
+	0x92F2, 0x68AF, 0x92F3, 0x6C40, 0x92F4, 0x7887, 0x92F5, 0x798E,
+	0x92F6, 0x7A0B, 0x92F7, 0x7DE0, 0x92F8, 0x8247, 0x92F9, 0x8A02,
+	0x92FA, 0x8AE6, 0x92FB, 0x8E44, 0x92FC, 0x9013, 0x9340, 0x90B8,
+	0x9341, 0x912D, 0x9342, 0x91D8, 0x9343, 0x9F0E, 0x9344, 0x6CE5,
+	0x9345, 0x6458, 0x9346, 0x64E2, 0x9347, 0x6575, 0x9348, 0x6EF4,
+	0x9349, 0x7684, 0x934A, 0x7B1B, 0x934B, 0x9069, 0x934C, 0x93D1,
+	0x934D, 0x6EBA, 0x934E, 0x54F2, 0x934F, 0x5FB9, 0x9350, 0x64A4,
+	0x9351, 0x8F4D, 0x9352, 0x8FED, 0x9353, 0x9244, 0x9354, 0x5178,
+	0x9355, 0x586B, 0x9356, 0x5929, 0x9357, 0x5C55, 0x9358, 0x5E97,
+	0x9359, 0x6DFB, 0x935A, 0x7E8F, 0x935B, 0x751C, 0x935C, 0x8CBC,
+	0x935D, 0x8EE2, 0x935E, 0x985B, 0x935F, 0x70B9, 0x9360, 0x4F1D,
+	0x9361, 0x6BBF, 0x9362, 0x6FB1, 0x9363, 0x7530, 0x9364, 0x96FB,
+	0x9365, 0x514E, 0x9366, 0x5410, 0x9367, 0x5835, 0x9368, 0x5857,
+	0x9369, 0x59AC, 0x936A, 0x5C60, 0x936B, 0x5F92, 0x936C, 0x6597,
+	0x936D, 0x675C, 0x936E, 0x6E21, 0x936F, 0x767B, 0x9370, 0x83DF,
+	0x9371, 0x8CED, 0x9372, 0x9014, 0x9373, 0x90FD, 0x9374, 0x934D,
+	0x9375, 0x7825, 0x9376, 0x783A, 0x9377, 0x52AA, 0x9378, 0x5EA6,
+	0x9379, 0x571F, 0x937A, 0x5974, 0x937B, 0x6012, 0x937C, 0x5012,
+	0x937D, 0x515A, 0x937E, 0x51AC, 0x9380, 0x51CD, 0x9381, 0x5200,
+	0x9382, 0x5510, 0x9383, 0x5854, 0x9384, 0x5858, 0x9385, 0x5957,
+	0x9386, 0x5B95, 0x9387, 0x5CF6, 0x9388, 0x5D8B, 0x9389, 0x60BC,
+	0x938A, 0x6295, 0x938B, 0x642D, 0x938C, 0x6771, 0x938D, 0x6843,
+	0x938E, 0x68BC, 0x938F, 0x68DF, 0x9390, 0x76D7, 0x9391, 0x6DD8,
+	0x9392, 0x6E6F, 0x9393, 0x6D9B, 0x9394, 0x706F, 0x9395, 0x71C8,
+	0x9396, 0x5F53, 0x9397, 0x75D8, 0x9398, 0x7977, 0x9399, 0x7B49,
+	0x939A, 0x7B54, 0x939B, 0x7B52, 0x939C, 0x7CD6, 0x939D, 0x7D71,
+	0x939E, 0x5230, 0x939F, 0x8463, 0x93A0, 0x8569, 0x93A1, 0x85E4,
+	0x93A2, 0x8A0E, 0x93A3, 0x8B04, 0x93A4, 0x8C46, 0x93A5, 0x8E0F,
+	0x93A6, 0x9003, 0x93A7, 0x900F, 0x93A8, 0x9419, 0x93A9, 0x9676,
+	0x93AA, 0x982D, 0x93AB, 0x9A30, 0x93AC, 0x95D8, 0x93AD, 0x50CD,
+	0x93AE, 0x52D5, 0x93AF, 0x540C, 0x93B0, 0x5802, 0x93B1, 0x5C0E,
+	0x93B2, 0x61A7, 0x93B3, 0x649E, 0x93B4, 0x6D1E, 0x93B5, 0x77B3,
+	0x93B6, 0x7AE5, 0x93B7, 0x80F4, 0x93B8, 0x8404, 0x93B9, 0x9053,
+	0x93BA, 0x9285, 0x93BB, 0x5CE0, 0x93BC, 0x9D07, 0x93BD, 0x533F,
+	0x93BE, 0x5F97, 0x93BF, 0x5FB3, 0x93C0, 0x6D9C, 0x93C1, 0x7279,
+	0x93C2, 0x7763, 0x93C3, 0x79BF, 0x93C4, 0x7BE4, 0x93C5, 0x6BD2,
+	0x93C6, 0x72EC, 0x93C7, 0x8AAD, 0x93C8, 0x6803, 0x93C9, 0x6A61,
+	0x93CA, 0x51F8, 0x93CB, 0x7A81, 0x93CC, 0x6934, 0x93CD, 0x5C4A,
+	0x93CE, 0x9CF6, 0x93CF, 0x82EB, 0x93D0, 0x5BC5, 0x93D1, 0x9149,
+	0x93D2, 0x701E, 0x93D3, 0x5678, 0x93D4, 0x5C6F, 0x93D5, 0x60C7,
+	0x93D6, 0x6566, 0x93D7, 0x6C8C, 0x93D8, 0x8C5A, 0x93D9, 0x9041,
+	0x93DA, 0x9813, 0x93DB, 0x5451, 0x93DC, 0x66C7, 0x93DD, 0x920D,
+	0x93DE, 0x5948, 0x93DF, 0x90A3, 0x93E0, 0x5185, 0x93E1, 0x4E4D,
+	0x93E2, 0x51EA, 0x93E3, 0x8599, 0x93E4, 0x8B0E, 0x93E5, 0x7058,
+	0x93E6, 0x637A, 0x93E7, 0x934B, 0x93E8, 0x6962, 0x93E9, 0x99B4,
+	0x93EA, 0x7E04, 0x93EB, 0x7577, 0x93EC, 0x5357, 0x93ED, 0x6960,
+	0x93EE, 0x8EDF, 0x93EF, 0x96E3, 0x93F0, 0x6C5D, 0x93F1, 0x4E8C,
+	0x93F2, 0x5C3C, 0x93F3, 0x5F10, 0x93F4, 0x8FE9, 0x93F5, 0x5302,
+	0x93F6, 0x8CD1, 0x93F7, 0x8089, 0x93F8, 0x8679, 0x93F9, 0x5EFF,
+	0x93FA, 0x65E5, 0x93FB, 0x4E73, 0x93FC, 0x5165, 0x9440, 0x5982,
+	0x9441, 0x5C3F, 0x9442, 0x97EE, 0x9443, 0x4EFB, 0x9444, 0x598A,
+	0x9445, 0x5FCD, 0x9446, 0x8A8D, 0x9447, 0x6FE1, 0x9448, 0x79B0,
+	0x9449, 0x7962, 0x944A, 0x5BE7, 0x944B, 0x8471, 0x944C, 0x732B,
+	0x944D, 0x71B1, 0x944E, 0x5E74, 0x944F, 0x5FF5, 0x9450, 0x637B,
+	0x9451, 0x649A, 0x9452, 0x71C3, 0x9453, 0x7C98, 0x9454, 0x4E43,
+	0x9455, 0x5EFC, 0x9456, 0x4E4B, 0x9457, 0x57DC, 0x9458, 0x56A2,
+	0x9459, 0x60A9, 0x945A, 0x6FC3, 0x945B, 0x7D0D, 0x945C, 0x80FD,
+	0x945D, 0x8133, 0x945E, 0x81BF, 0x945F, 0x8FB2, 0x9460, 0x8997,
+	0x9461, 0x86A4, 0x9462, 0x5DF4, 0x9463, 0x628A, 0x9464, 0x64AD,
+	0x9465, 0x8987, 0x9466, 0x6777, 0x9467, 0x6CE2, 0x9468, 0x6D3E,
+	0x9469, 0x7436, 0x946A, 0x7834, 0x946B, 0x5A46, 0x946C, 0x7F75,
+	0x946D, 0x82AD, 0x946E, 0x99AC, 0x946F, 0x4FF3, 0x9470, 0x5EC3,
+	0x9471, 0x62DD, 0x9472, 0x6392, 0x9473, 0x6557, 0x9474, 0x676F,
+	0x9475, 0x76C3, 0x9476, 0x724C, 0x9477, 0x80CC, 0x9478, 0x80BA,
+	0x9479, 0x8F29, 0x947A, 0x914D, 0x947B, 0x500D, 0x947C, 0x57F9,
+	0x947D, 0x5A92, 0x947E, 0x6885, 0x9480, 0x6973, 0x9481, 0x7164,
+	0x9482, 0x72FD, 0x9483, 0x8CB7, 0x9484, 0x58F2, 0x9485, 0x8CE0,
+	0x9486, 0x966A, 0x9487, 0x9019, 0x9488, 0x877F, 0x9489, 0x79E4,
+	0x948A, 0x77E7, 0x948B, 0x8429, 0x948C, 0x4F2F, 0x948D, 0x5265,
+	0x948E, 0x535A, 0x948F, 0x62CD, 0x9490, 0x67CF, 0x9491, 0x6CCA,
+	0x9492, 0x767D, 0x9493, 0x7B94, 0x9494, 0x7C95, 0x9495, 0x8236,
+	0x9496, 0x8584, 0x9497, 0x8FEB, 0x9498, 0x66DD, 0x9499, 0x6F20,
+	0x949A, 0x7206, 0x949B, 0x7E1B, 0x949C, 0x83AB, 0x949D, 0x99C1,
+	0x949E, 0x9EA6, 0x949F, 0x51FD, 0x94A0, 0x7BB1, 0x94A1, 0x7872,
+	0x94A2, 0x7BB8, 0x94A3, 0x8087, 0x94A4, 0x7B48, 0x94A5, 0x6AE8,
+	0x94A6, 0x5E61, 0x94A7, 0x808C, 0x94A8, 0x7551, 0x94A9, 0x7560,
+	0x94AA, 0x516B, 0x94AB, 0x9262, 0x94AC, 0x6E8C, 0x94AD, 0x767A,
+	0x94AE, 0x9197, 0x94AF, 0x9AEA, 0x94B0, 0x4F10, 0x94B1, 0x7F70,
+	0x94B2, 0x629C, 0x94B3, 0x7B4F, 0x94B4, 0x95A5, 0x94B5, 0x9CE9,
+	0x94B6, 0x567A, 0x94B7, 0x5859, 0x94B8, 0x86E4, 0x94B9, 0x96BC,
+	0x94BA, 0x4F34, 0x94BB, 0x5224, 0x94BC, 0x534A, 0x94BD, 0x53CD,
+	0x94BE, 0x53DB, 0x94BF, 0x5E06, 0x94C0, 0x642C, 0x94C1, 0x6591,
+	0x94C2, 0x677F, 0x94C3, 0x6C3E, 0x94C4, 0x6C4E, 0x94C5, 0x7248,
+	0x94C6, 0x72AF, 0x94C7, 0x73ED, 0x94C8, 0x7554, 0x94C9, 0x7E41,
+	0x94CA, 0x822C, 0x94CB, 0x85E9, 0x94CC, 0x8CA9, 0x94CD, 0x7BC4,
+	0x94CE, 0x91C6, 0x94CF, 0x7169, 0x94D0, 0x9812, 0x94D1, 0x98EF,
+	0x94D2, 0x633D, 0x94D3, 0x6669, 0x94D4, 0x756A, 0x94D5, 0x76E4,
+	0x94D6, 0x78D0, 0x94D7, 0x8543, 0x94D8, 0x86EE, 0x94D9, 0x532A,
+	0x94DA, 0x5351, 0x94DB, 0x5426, 0x94DC, 0x5983, 0x94DD, 0x5E87,
+	0x94DE, 0x5F7C, 0x94DF, 0x60B2, 0x94E0, 0x6249, 0x94E1, 0x6279,
+	0x94E2, 0x62AB, 0x94E3, 0x6590, 0x94E4, 0x6BD4, 0x94E5, 0x6CCC,
+	0x94E6, 0x75B2, 0x94E7, 0x76AE, 0x94E8, 0x7891, 0x94E9, 0x79D8,
+	0x94EA, 0x7DCB, 0x94EB, 0x7F77, 0x94EC, 0x80A5, 0x94ED, 0x88AB,
+	0x94EE, 0x8AB9, 0x94EF, 0x8CBB, 0x94F0, 0x907F, 0x94F1, 0x975E,
+	0x94F2, 0x98DB, 0x94F3, 0x6A0B, 0x94F4, 0x7C38, 0x94F5, 0x5099,
+	0x94F6, 0x5C3E, 0x94F7, 0x5FAE, 0x94F8, 0x6787, 0x94F9, 0x6BD8,
+	0x94FA, 0x7435, 0x94FB, 0x7709, 0x94FC, 0x7F8E, 0x9540, 0x9F3B,
+	0x9541, 0x67CA, 0x9542, 0x7A17, 0x9543, 0x5339, 0x9544, 0x758B,
+	0x9545, 0x9AED, 0x9546, 0x5F66, 0x9547, 0x819D, 0x9548, 0x83F1,
+	0x9549, 0x8098, 0x954A, 0x5F3C, 0x954B, 0x5FC5, 0x954C, 0x7562,
+	0x954D, 0x7B46, 0x954E, 0x903C, 0x954F, 0x6867, 0x9550, 0x59EB,
+	0x9551, 0x5A9B, 0x9552, 0x7D10, 0x9553, 0x767E, 0x9554, 0x8B2C,
+	0x9555, 0x4FF5, 0x9556, 0x5F6A, 0x9557, 0x6A19, 0x9558, 0x6C37,
+	0x9559, 0x6F02, 0x955A, 0x74E2, 0x955B, 0x7968, 0x955C, 0x8868,
+	0x955D, 0x8A55, 0x955E, 0x8C79, 0x955F, 0x5EDF, 0x9560, 0x63CF,
+	0x9561, 0x75C5, 0x9562, 0x79D2, 0x9563, 0x82D7, 0x9564, 0x9328,
+	0x9565, 0x92F2, 0x9566, 0x849C, 0x9567, 0x86ED, 0x9568, 0x9C2D,
+	0x9569, 0x54C1, 0x956A, 0x5F6C, 0x956B, 0x658C, 0x956C, 0x6D5C,
+	0x956D, 0x7015, 0x956E, 0x8CA7, 0x956F, 0x8CD3, 0x9570, 0x983B,
+	0x9571, 0x654F, 0x9572, 0x74F6, 0x9573, 0x4E0D, 0x9574, 0x4ED8,
+	0x9575, 0x57E0, 0x9576, 0x592B, 0x9577, 0x5A66, 0x9578, 0x5BCC,
+	0x9579, 0x51A8, 0x957A, 0x5E03, 0x957B, 0x5E9C, 0x957C, 0x6016,
+	0x957D, 0x6276, 0x957E, 0x6577, 0x9580, 0x65A7, 0x9581, 0x666E,
+	0x9582, 0x6D6E, 0x9583, 0x7236, 0x9584, 0x7B26, 0x9585, 0x8150,
+	0x9586, 0x819A, 0x9587, 0x8299, 0x9588, 0x8B5C, 0x9589, 0x8CA0,
+	0x958A, 0x8CE6, 0x958B, 0x8D74, 0x958C, 0x961C, 0x958D, 0x9644,
+	0x958E, 0x4FAE, 0x958F, 0x64AB, 0x9590, 0x6B66, 0x9591, 0x821E,
+	0x9592, 0x8461, 0x9593, 0x856A, 0x9594, 0x90E8, 0x9595, 0x5C01,
+	0x9596, 0x6953, 0x9597, 0x98A8, 0x9598, 0x847A, 0x9599, 0x8557,
+	0x959A, 0x4F0F, 0x959B, 0x526F, 0x959C, 0x5FA9, 0x959D, 0x5E45,
+	0x959E, 0x670D, 0x959F, 0x798F, 0x95A0, 0x8179, 0x95A1, 0x8907,
+	0x95A2, 0x8986, 0x95A3, 0x6DF5, 0x95A4, 0x5F17, 0x95A5, 0x6255,
+	0x95A6, 0x6CB8, 0x95A7, 0x4ECF, 0x95A8, 0x7269, 0x95A9, 0x9B92,
+	0x95AA, 0x5206, 0x95AB, 0x543B, 0x95AC, 0x5674, 0x95AD, 0x58B3,
+	0x95AE, 0x61A4, 0x95AF, 0x626E, 0x95B0, 0x711A, 0x95B1, 0x596E,
+	0x95B2, 0x7C89, 0x95B3, 0x7CDE, 0x95B4, 0x7D1B, 0x95B5, 0x96F0,
+	0x95B6, 0x6587, 0x95B7, 0x805E, 0x95B8, 0x4E19, 0x95B9, 0x4F75,
+	0x95BA, 0x5175, 0x95BB, 0x5840, 0x95BC, 0x5E63, 0x95BD, 0x5E73,
+	0x95BE, 0x5F0A, 0x95BF, 0x67C4, 0x95C0, 0x4E26, 0x95C1, 0x853D,
+	0x95C2, 0x9589, 0x95C3, 0x965B, 0x95C4, 0x7C73, 0x95C5, 0x9801,
+	0x95C6, 0x50FB, 0x95C7, 0x58C1, 0x95C8, 0x7656, 0x95C9, 0x78A7,
+	0x95CA, 0x5225, 0x95CB, 0x77A5, 0x95CC, 0x8511, 0x95CD, 0x7B86,
+	0x95CE, 0x504F, 0x95CF, 0x5909, 0x95D0, 0x7247, 0x95D1, 0x7BC7,
+	0x95D2, 0x7DE8, 0x95D3, 0x8FBA, 0x95D4, 0x8FD4, 0x95D5, 0x904D,
+	0x95D6, 0x4FBF, 0x95D7, 0x52C9, 0x95D8, 0x5A29, 0x95D9, 0x5F01,
+	0x95DA, 0x97AD, 0x95DB, 0x4FDD, 0x95DC, 0x8217, 0x95DD, 0x92EA,
+	0x95DE, 0x5703, 0x95DF, 0x6355, 0x95E0, 0x6B69, 0x95E1, 0x752B,
+	0x95E2, 0x88DC, 0x95E3, 0x8F14, 0x95E4, 0x7A42, 0x95E5, 0x52DF,
+	0x95E6, 0x5893, 0x95E7, 0x6155, 0x95E8, 0x620A, 0x95E9, 0x66AE,
+	0x95EA, 0x6BCD, 0x95EB, 0x7C3F, 0x95EC, 0x83E9, 0x95ED, 0x5023,
+	0x95EE, 0x4FF8, 0x95EF, 0x5305, 0x95F0, 0x5446, 0x95F1, 0x5831,
+	0x95F2, 0x5949, 0x95F3, 0x5B9D, 0x95F4, 0x5CF0, 0x95F5, 0x5CEF,
+	0x95F6, 0x5D29, 0x95F7, 0x5E96, 0x95F8, 0x62B1, 0x95F9, 0x6367,
+	0x95FA, 0x653E, 0x95FB, 0x65B9, 0x95FC, 0x670B, 0x9640, 0x6CD5,
+	0x9641, 0x6CE1, 0x9642, 0x70F9, 0x9643, 0x7832, 0x9644, 0x7E2B,
+	0x9645, 0x80DE, 0x9646, 0x82B3, 0x9647, 0x840C, 0x9648, 0x84EC,
+	0x9649, 0x8702, 0x964A, 0x8912, 0x964B, 0x8A2A, 0x964C, 0x8C4A,
+	0x964D, 0x90A6, 0x964E, 0x92D2, 0x964F, 0x98FD, 0x9650, 0x9CF3,
+	0x9651, 0x9D6C, 0x9652, 0x4E4F, 0x9653, 0x4EA1, 0x9654, 0x508D,
+	0x9655, 0x5256, 0x9656, 0x574A, 0x9657, 0x59A8, 0x9658, 0x5E3D,
+	0x9659, 0x5FD8, 0x965A, 0x5FD9, 0x965B, 0x623F, 0x965C, 0x66B4,
+	0x965D, 0x671B, 0x965E, 0x67D0, 0x965F, 0x68D2, 0x9660, 0x5192,
+	0x9661, 0x7D21, 0x9662, 0x80AA, 0x9663, 0x81A8, 0x9664, 0x8B00,
+	0x9665, 0x8C8C, 0x9666, 0x8CBF, 0x9667, 0x927E, 0x9668, 0x9632,
+	0x9669, 0x5420, 0x966A, 0x982C, 0x966B, 0x5317, 0x966C, 0x50D5,
+	0x966D, 0x535C, 0x966E, 0x58A8, 0x966F, 0x64B2, 0x9670, 0x6734,
+	0x9671, 0x7267, 0x9672, 0x7766, 0x9673, 0x7A46, 0x9674, 0x91E6,
+	0x9675, 0x52C3, 0x9676, 0x6CA1, 0x9677, 0x6B86, 0x9678, 0x5800,
+	0x9679, 0x5E4C, 0x967A, 0x5954, 0x967B, 0x672C, 0x967C, 0x7FFB,
+	0x967D, 0x51E1, 0x967E, 0x76C6, 0x9680, 0x6469, 0x9681, 0x78E8,
+	0x9682, 0x9B54, 0x9683, 0x9EBB, 0x9684, 0x57CB, 0x9685, 0x59B9,
+	0x9686, 0x6627, 0x9687, 0x679A, 0x9688, 0x6BCE, 0x9689, 0x54E9,
+	0x968A, 0x69D9, 0x968B, 0x5E55, 0x968C, 0x819C, 0x968D, 0x6795,
+	0x968E, 0x9BAA, 0x968F, 0x67FE, 0x9690, 0x9C52, 0x9691, 0x685D,
+	0x9692, 0x4EA6, 0x9693, 0x4FE3, 0x9694, 0x53C8, 0x9695, 0x62B9,
+	0x9696, 0x672B, 0x9697, 0x6CAB, 0x9698, 0x8FC4, 0x9699, 0x4FAD,
+	0x969A, 0x7E6D, 0x969B, 0x9EBF, 0x969C, 0x4E07, 0x969D, 0x6162,
+	0x969E, 0x6E80, 0x969F, 0x6F2B, 0x96A0, 0x8513, 0x96A1, 0x5473,
+	0x96A2, 0x672A, 0x96A3, 0x9B45, 0x96A4, 0x5DF3, 0x96A5, 0x7B95,
+	0x96A6, 0x5CAC, 0x96A7, 0x5BC6, 0x96A8, 0x871C, 0x96A9, 0x6E4A,
+	0x96AA, 0x84D1, 0x96AB, 0x7A14, 0x96AC, 0x8108, 0x96AD, 0x5999,
+	0x96AE, 0x7C8D, 0x96AF, 0x6C11, 0x96B0, 0x7720, 0x96B1, 0x52D9,
+	0x96B2, 0x5922, 0x96B3, 0x7121, 0x96B4, 0x725F, 0x96B5, 0x77DB,
+	0x96B6, 0x9727, 0x96B7, 0x9D61, 0x96B8, 0x690B, 0x96B9, 0x5A7F,
+	0x96BA, 0x5A18, 0x96BB, 0x51A5, 0x96BC, 0x540D, 0x96BD, 0x547D,
+	0x96BE, 0x660E, 0x96BF, 0x76DF, 0x96C0, 0x8FF7, 0x96C1, 0x9298,
+	0x96C2, 0x9CF4, 0x96C3, 0x59EA, 0x96C4, 0x725D, 0x96C5, 0x6EC5,
+	0x96C6, 0x514D, 0x96C7, 0x68C9, 0x96C8, 0x7DBF, 0x96C9, 0x7DEC,
+	0x96CA, 0x9762, 0x96CB, 0x9EBA, 0x96CC, 0x6478, 0x96CD, 0x6A21,
+	0x96CE, 0x8302, 0x96CF, 0x5984, 0x96D0, 0x5B5F, 0x96D1, 0x6BDB,
+	0x96D2, 0x731B, 0x96D3, 0x76F2, 0x96D4, 0x7DB2, 0x96D5, 0x8017,
+	0x96D6, 0x8499, 0x96D7, 0x5132, 0x96D8, 0x6728, 0x96D9, 0x9ED9,
+	0x96DA, 0x76EE, 0x96DB, 0x6762, 0x96DC, 0x52FF, 0x96DD, 0x9905,
+	0x96DE, 0x5C24, 0x96DF, 0x623B, 0x96E0, 0x7C7E, 0x96E1, 0x8CB0,
+	0x96E2, 0x554F, 0x96E3, 0x60B6, 0x96E4, 0x7D0B, 0x96E5, 0x9580,
+	0x96E6, 0x5301, 0x96E7, 0x4E5F, 0x96E8, 0x51B6, 0x96E9, 0x591C,
+	0x96EA, 0x723A, 0x96EB, 0x8036, 0x96EC, 0x91CE, 0x96ED, 0x5F25,
+	0x96EE, 0x77E2, 0x96EF, 0x5384, 0x96F0, 0x5F79, 0x96F1, 0x7D04,
+	0x96F2, 0x85AC, 0x96F3, 0x8A33, 0x96F4, 0x8E8D, 0x96F5, 0x9756,
+	0x96F6, 0x67F3, 0x96F7, 0x85AE, 0x96F8, 0x9453, 0x96F9, 0x6109,
+	0x96FA, 0x6108, 0x96FB, 0x6CB9, 0x96FC, 0x7652, 0x9740, 0x8AED,
+	0x9741, 0x8F38, 0x9742, 0x552F, 0x9743, 0x4F51, 0x9744, 0x512A,
+	0x9745, 0x52C7, 0x9746, 0x53CB, 0x9747, 0x5BA5, 0x9748, 0x5E7D,
+	0x9749, 0x60A0, 0x974A, 0x6182, 0x974B, 0x63D6, 0x974C, 0x6709,
+	0x974D, 0x67DA, 0x974E, 0x6E67, 0x974F, 0x6D8C, 0x9750, 0x7336,
+	0x9751, 0x7337, 0x9752, 0x7531, 0x9753, 0x7950, 0x9754, 0x88D5,
+	0x9755, 0x8A98, 0x9756, 0x904A, 0x9757, 0x9091, 0x9758, 0x90F5,
+	0x9759, 0x96C4, 0x975A, 0x878D, 0x975B, 0x5915, 0x975C, 0x4E88,
+	0x975D, 0x4F59, 0x975E, 0x4E0E, 0x975F, 0x8A89, 0x9760, 0x8F3F,
+	0x9761, 0x9810, 0x9762, 0x50AD, 0x9763, 0x5E7C, 0x9764, 0x5996,
+	0x9765, 0x5BB9, 0x9766, 0x5EB8, 0x9767, 0x63DA, 0x9768, 0x63FA,
+	0x9769, 0x64C1, 0x976A, 0x66DC, 0x976B, 0x694A, 0x976C, 0x69D8,
+	0x976D, 0x6D0B, 0x976E, 0x6EB6, 0x976F, 0x7194, 0x9770, 0x7528,
+	0x9771, 0x7AAF, 0x9772, 0x7F8A, 0x9773, 0x8000, 0x9774, 0x8449,
+	0x9775, 0x84C9, 0x9776, 0x8981, 0x9777, 0x8B21, 0x9778, 0x8E0A,
+	0x9779, 0x9065, 0x977A, 0x967D, 0x977B, 0x990A, 0x977C, 0x617E,
+	0x977D, 0x6291, 0x977E, 0x6B32, 0x9780, 0x6C83, 0x9781, 0x6D74,
+	0x9782, 0x7FCC, 0x9783, 0x7FFC, 0x9784, 0x6DC0, 0x9785, 0x7F85,
+	0x9786, 0x87BA, 0x9787, 0x88F8, 0x9788, 0x6765, 0x9789, 0x83B1,
+	0x978A, 0x983C, 0x978B, 0x96F7, 0x978C, 0x6D1B, 0x978D, 0x7D61,
+	0x978E, 0x843D, 0x978F, 0x916A, 0x9790, 0x4E71, 0x9791, 0x5375,
+	0x9792, 0x5D50, 0x9793, 0x6B04, 0x9794, 0x6FEB, 0x9795, 0x85CD,
+	0x9796, 0x862D, 0x9797, 0x89A7, 0x9798, 0x5229, 0x9799, 0x540F,
+	0x979A, 0x5C65, 0x979B, 0x674E, 0x979C, 0x68A8, 0x979D, 0x7406,
+	0x979E, 0x7483, 0x979F, 0x75E2, 0x97A0, 0x88CF, 0x97A1, 0x88E1,
+	0x97A2, 0x91CC, 0x97A3, 0x96E2, 0x97A4, 0x9678, 0x97A5, 0x5F8B,
+	0x97A6, 0x7387, 0x97A7, 0x7ACB, 0x97A8, 0x844E, 0x97A9, 0x63A0,
+	0x97AA, 0x7565, 0x97AB, 0x5289, 0x97AC, 0x6D41, 0x97AD, 0x6E9C,
+	0x97AE, 0x7409, 0x97AF, 0x7559, 0x97B0, 0x786B, 0x97B1, 0x7C92,
+	0x97B2, 0x9686, 0x97B3, 0x7ADC, 0x97B4, 0x9F8D, 0x97B5, 0x4FB6,
+	0x97B6, 0x616E, 0x97B7, 0x65C5, 0x97B8, 0x865C, 0x97B9, 0x4E86,
+	0x97BA, 0x4EAE, 0x97BB, 0x50DA, 0x97BC, 0x4E21, 0x97BD, 0x51CC,
+	0x97BE, 0x5BEE, 0x97BF, 0x6599, 0x97C0, 0x6881, 0x97C1, 0x6DBC,
+	0x97C2, 0x731F, 0x97C3, 0x7642, 0x97C4, 0x77AD, 0x97C5, 0x7A1C,
+	0x97C6, 0x7CE7, 0x97C7, 0x826F, 0x97C8, 0x8AD2, 0x97C9, 0x907C,
+	0x97CA, 0x91CF, 0x97CB, 0x9675, 0x97CC, 0x9818, 0x97CD, 0x529B,
+	0x97CE, 0x7DD1, 0x97CF, 0x502B, 0x97D0, 0x5398, 0x97D1, 0x6797,
+	0x97D2, 0x6DCB, 0x97D3, 0x71D0, 0x97D4, 0x7433, 0x97D5, 0x81E8,
+	0x97D6, 0x8F2A, 0x97D7, 0x96A3, 0x97D8, 0x9C57, 0x97D9, 0x9E9F,
+	0x97DA, 0x7460, 0x97DB, 0x5841, 0x97DC, 0x6D99, 0x97DD, 0x7D2F,
+	0x97DE, 0x985E, 0x97DF, 0x4EE4, 0x97E0, 0x4F36, 0x97E1, 0x4F8B,
+	0x97E2, 0x51B7, 0x97E3, 0x52B1, 0x97E4, 0x5DBA, 0x97E5, 0x601C,
+	0x97E6, 0x73B2, 0x97E7, 0x793C, 0x97E8, 0x82D3, 0x97E9, 0x9234,
+	0x97EA, 0x96B7, 0x97EB, 0x96F6, 0x97EC, 0x970A, 0x97ED, 0x9E97,
+	0x97EE, 0x9F62, 0x97EF, 0x66A6, 0x97F0, 0x6B74, 0x97F1, 0x5217,
+	0x97F2, 0x52A3, 0x97F3, 0x70C8, 0x97F4, 0x88C2, 0x97F5, 0x5EC9,
+	0x97F6, 0x604B, 0x97F7, 0x6190, 0x97F8, 0x6F23, 0x97F9, 0x7149,
+	0x97FA, 0x7C3E, 0x97FB, 0x7DF4, 0x97FC, 0x806F, 0x9840, 0x84EE,
+	0x9841, 0x9023, 0x9842, 0x932C, 0x9843, 0x5442, 0x9844, 0x9B6F,
+	0x9845, 0x6AD3, 0x9846, 0x7089, 0x9847, 0x8CC2, 0x9848, 0x8DEF,
+	0x9849, 0x9732, 0x984A, 0x52B4, 0x984B, 0x5A41, 0x984C, 0x5ECA,
+	0x984D, 0x5F04, 0x984E, 0x6717, 0x984F, 0x697C, 0x9850, 0x6994,
+	0x9851, 0x6D6A, 0x9852, 0x6F0F, 0x9853, 0x7262, 0x9854, 0x72FC,
+	0x9855, 0x7BED, 0x9856, 0x8001, 0x9857, 0x807E, 0x9858, 0x874B,
+	0x9859, 0x90CE, 0x985A, 0x516D, 0x985B, 0x9E93, 0x985C, 0x7984,
+	0x985D, 0x808B, 0x985E, 0x9332, 0x985F, 0x8AD6, 0x9860, 0x502D,
+	0x9861, 0x548C, 0x9862, 0x8A71, 0x9863, 0x6B6A, 0x9864, 0x8CC4,
+	0x9865, 0x8107, 0x9866, 0x60D1, 0x9867, 0x67A0, 0x9868, 0x9DF2,
+	0x9869, 0x4E99, 0x986A, 0x4E98, 0x986B, 0x9C10, 0x986C, 0x8A6B,
+	0x986D, 0x85C1, 0x986E, 0x8568, 0x986F, 0x6900, 0x9870, 0x6E7E,
+	0x9871, 0x7897, 0x9872, 0x8155, 0x989F, 0x5F0C, 0x98A0, 0x4E10,
+	0x98A1, 0x4E15, 0x98A2, 0x4E2A, 0x98A3, 0x4E31, 0x98A4, 0x4E36,
+	0x98A5, 0x4E3C, 0x98A6, 0x4E3F, 0x98A7, 0x4E42, 0x98A8, 0x4E56,
+	0x98A9, 0x4E58, 0x98AA, 0x4E82, 0x98AB, 0x4E85, 0x98AC, 0x8C6B,
+	0x98AD, 0x4E8A, 0x98AE, 0x8212, 0x98AF, 0x5F0D, 0x98B0, 0x4E8E,
+	0x98B1, 0x4E9E, 0x98B2, 0x4E9F, 0x98B3, 0x4EA0, 0x98B4, 0x4EA2,
+	0x98B5, 0x4EB0, 0x98B6, 0x4EB3, 0x98B7, 0x4EB6, 0x98B8, 0x4ECE,
+	0x98B9, 0x4ECD, 0x98BA, 0x4EC4, 0x98BB, 0x4EC6, 0x98BC, 0x4EC2,
+	0x98BD, 0x4ED7, 0x98BE, 0x4EDE, 0x98BF, 0x4EED, 0x98C0, 0x4EDF,
+	0x98C1, 0x4EF7, 0x98C2, 0x4F09, 0x98C3, 0x4F5A, 0x98C4, 0x4F30,
+	0x98C5, 0x4F5B, 0x98C6, 0x4F5D, 0x98C7, 0x4F57, 0x98C8, 0x4F47,
+	0x98C9, 0x4F76, 0x98CA, 0x4F88, 0x98CB, 0x4F8F, 0x98CC, 0x4F98,
+	0x98CD, 0x4F7B, 0x98CE, 0x4F69, 0x98CF, 0x4F70, 0x98D0, 0x4F91,
+	0x98D1, 0x4F6F, 0x98D2, 0x4F86, 0x98D3, 0x4F96, 0x98D4, 0x5118,
+	0x98D5, 0x4FD4, 0x98D6, 0x4FDF, 0x98D7, 0x4FCE, 0x98D8, 0x4FD8,
+	0x98D9, 0x4FDB, 0x98DA, 0x4FD1, 0x98DB, 0x4FDA, 0x98DC, 0x4FD0,
+	0x98DD, 0x4FE4, 0x98DE, 0x4FE5, 0x98DF, 0x501A, 0x98E0, 0x5028,
+	0x98E1, 0x5014, 0x98E2, 0x502A, 0x98E3, 0x5025, 0x98E4, 0x5005,
+	0x98E5, 0x4F1C, 0x98E6, 0x4FF6, 0x98E7, 0x5021, 0x98E8, 0x5029,
+	0x98E9, 0x502C, 0x98EA, 0x4FFE, 0x98EB, 0x4FEF, 0x98EC, 0x5011,
+	0x98ED, 0x5006, 0x98EE, 0x5043, 0x98EF, 0x5047, 0x98F0, 0x6703,
+	0x98F1, 0x5055, 0x98F2, 0x5050, 0x98F3, 0x5048, 0x98F4, 0x505A,
+	0x98F5, 0x5056, 0x98F6, 0x506C, 0x98F7, 0x5078, 0x98F8, 0x5080,
+	0x98F9, 0x509A, 0x98FA, 0x5085, 0x98FB, 0x50B4, 0x98FC, 0x50B2,
+	0x9940, 0x50C9, 0x9941, 0x50CA, 0x9942, 0x50B3, 0x9943, 0x50C2,
+	0x9944, 0x50D6, 0x9945, 0x50DE, 0x9946, 0x50E5, 0x9947, 0x50ED,
+	0x9948, 0x50E3, 0x9949, 0x50EE, 0x994A, 0x50F9, 0x994B, 0x50F5,
+	0x994C, 0x5109, 0x994D, 0x5101, 0x994E, 0x5102, 0x994F, 0x5116,
+	0x9950, 0x5115, 0x9951, 0x5114, 0x9952, 0x511A, 0x9953, 0x5121,
+	0x9954, 0x513A, 0x9955, 0x5137, 0x9956, 0x513C, 0x9957, 0x513B,
+	0x9958, 0x513F, 0x9959, 0x5140, 0x995A, 0x5152, 0x995B, 0x514C,
+	0x995C, 0x5154, 0x995D, 0x5162, 0x995E, 0x7AF8, 0x995F, 0x5169,
+	0x9960, 0x516A, 0x9961, 0x516E, 0x9962, 0x5180, 0x9963, 0x5182,
+	0x9964, 0x56D8, 0x9965, 0x518C, 0x9966, 0x5189, 0x9967, 0x518F,
+	0x9968, 0x5191, 0x9969, 0x5193, 0x996A, 0x5195, 0x996B, 0x5196,
+	0x996C, 0x51A4, 0x996D, 0x51A6, 0x996E, 0x51A2, 0x996F, 0x51A9,
+	0x9970, 0x51AA, 0x9971, 0x51AB, 0x9972, 0x51B3, 0x9973, 0x51B1,
+	0x9974, 0x51B2, 0x9975, 0x51B0, 0x9976, 0x51B5, 0x9977, 0x51BD,
+	0x9978, 0x51C5, 0x9979, 0x51C9, 0x997A, 0x51DB, 0x997B, 0x51E0,
+	0x997C, 0x8655, 0x997D, 0x51E9, 0x997E, 0x51ED, 0x9980, 0x51F0,
+	0x9981, 0x51F5, 0x9982, 0x51FE, 0x9983, 0x5204, 0x9984, 0x520B,
+	0x9985, 0x5214, 0x9986, 0x520E, 0x9987, 0x5227, 0x9988, 0x522A,
+	0x9989, 0x522E, 0x998A, 0x5233, 0x998B, 0x5239, 0x998C, 0x524F,
+	0x998D, 0x5244, 0x998E, 0x524B, 0x998F, 0x524C, 0x9990, 0x525E,
+	0x9991, 0x5254, 0x9992, 0x526A, 0x9993, 0x5274, 0x9994, 0x5269,
+	0x9995, 0x5273, 0x9996, 0x527F, 0x9997, 0x527D, 0x9998, 0x528D,
+	0x9999, 0x5294, 0x999A, 0x5292, 0x999B, 0x5271, 0x999C, 0x5288,
+	0x999D, 0x5291, 0x999E, 0x8FA8, 0x999F, 0x8FA7, 0x99A0, 0x52AC,
+	0x99A1, 0x52AD, 0x99A2, 0x52BC, 0x99A3, 0x52B5, 0x99A4, 0x52C1,
+	0x99A5, 0x52CD, 0x99A6, 0x52D7, 0x99A7, 0x52DE, 0x99A8, 0x52E3,
+	0x99A9, 0x52E6, 0x99AA, 0x98ED, 0x99AB, 0x52E0, 0x99AC, 0x52F3,
+	0x99AD, 0x52F5, 0x99AE, 0x52F8, 0x99AF, 0x52F9, 0x99B0, 0x5306,
+	0x99B1, 0x5308, 0x99B2, 0x7538, 0x99B3, 0x530D, 0x99B4, 0x5310,
+	0x99B5, 0x530F, 0x99B6, 0x5315, 0x99B7, 0x531A, 0x99B8, 0x5323,
+	0x99B9, 0x532F, 0x99BA, 0x5331, 0x99BB, 0x5333, 0x99BC, 0x5338,
+	0x99BD, 0x5340, 0x99BE, 0x5346, 0x99BF, 0x5345, 0x99C0, 0x4E17,
+	0x99C1, 0x5349, 0x99C2, 0x534D, 0x99C3, 0x51D6, 0x99C4, 0x535E,
+	0x99C5, 0x5369, 0x99C6, 0x536E, 0x99C7, 0x5918, 0x99C8, 0x537B,
+	0x99C9, 0x5377, 0x99CA, 0x5382, 0x99CB, 0x5396, 0x99CC, 0x53A0,
+	0x99CD, 0x53A6, 0x99CE, 0x53A5, 0x99CF, 0x53AE, 0x99D0, 0x53B0,
+	0x99D1, 0x53B6, 0x99D2, 0x53C3, 0x99D3, 0x7C12, 0x99D4, 0x96D9,
+	0x99D5, 0x53DF, 0x99D6, 0x66FC, 0x99D7, 0x71EE, 0x99D8, 0x53EE,
+	0x99D9, 0x53E8, 0x99DA, 0x53ED, 0x99DB, 0x53FA, 0x99DC, 0x5401,
+	0x99DD, 0x543D, 0x99DE, 0x5440, 0x99DF, 0x542C, 0x99E0, 0x542D,
+	0x99E1, 0x543C, 0x99E2, 0x542E, 0x99E3, 0x5436, 0x99E4, 0x5429,
+	0x99E5, 0x541D, 0x99E6, 0x544E, 0x99E7, 0x548F, 0x99E8, 0x5475,
+	0x99E9, 0x548E, 0x99EA, 0x545F, 0x99EB, 0x5471, 0x99EC, 0x5477,
+	0x99ED, 0x5470, 0x99EE, 0x5492, 0x99EF, 0x547B, 0x99F0, 0x5480,
+	0x99F1, 0x5476, 0x99F2, 0x5484, 0x99F3, 0x5490, 0x99F4, 0x5486,
+	0x99F5, 0x54C7, 0x99F6, 0x54A2, 0x99F7, 0x54B8, 0x99F8, 0x54A5,
+	0x99F9, 0x54AC, 0x99FA, 0x54C4, 0x99FB, 0x54C8, 0x99FC, 0x54A8,
+	0x9A40, 0x54AB, 0x9A41, 0x54C2, 0x9A42, 0x54A4, 0x9A43, 0x54BE,
+	0x9A44, 0x54BC, 0x9A45, 0x54D8, 0x9A46, 0x54E5, 0x9A47, 0x54E6,
+	0x9A48, 0x550F, 0x9A49, 0x5514, 0x9A4A, 0x54FD, 0x9A4B, 0x54EE,
+	0x9A4C, 0x54ED, 0x9A4D, 0x54FA, 0x9A4E, 0x54E2, 0x9A4F, 0x5539,
+	0x9A50, 0x5540, 0x9A51, 0x5563, 0x9A52, 0x554C, 0x9A53, 0x552E,
+	0x9A54, 0x555C, 0x9A55, 0x5545, 0x9A56, 0x5556, 0x9A57, 0x5557,
+	0x9A58, 0x5538, 0x9A59, 0x5533, 0x9A5A, 0x555D, 0x9A5B, 0x5599,
+	0x9A5C, 0x5580, 0x9A5D, 0x54AF, 0x9A5E, 0x558A, 0x9A5F, 0x559F,
+	0x9A60, 0x557B, 0x9A61, 0x557E, 0x9A62, 0x5598, 0x9A63, 0x559E,
+	0x9A64, 0x55AE, 0x9A65, 0x557C, 0x9A66, 0x5583, 0x9A67, 0x55A9,
+	0x9A68, 0x5587, 0x9A69, 0x55A8, 0x9A6A, 0x55DA, 0x9A6B, 0x55C5,
+	0x9A6C, 0x55DF, 0x9A6D, 0x55C4, 0x9A6E, 0x55DC, 0x9A6F, 0x55E4,
+	0x9A70, 0x55D4, 0x9A71, 0x5614, 0x9A72, 0x55F7, 0x9A73, 0x5616,
+	0x9A74, 0x55FE, 0x9A75, 0x55FD, 0x9A76, 0x561B, 0x9A77, 0x55F9,
+	0x9A78, 0x564E, 0x9A79, 0x5650, 0x9A7A, 0x71DF, 0x9A7B, 0x5634,
+	0x9A7C, 0x5636, 0x9A7D, 0x5632, 0x9A7E, 0x5638, 0x9A80, 0x566B,
+	0x9A81, 0x5664, 0x9A82, 0x562F, 0x9A83, 0x566C, 0x9A84, 0x566A,
+	0x9A85, 0x5686, 0x9A86, 0x5680, 0x9A87, 0x568A, 0x9A88, 0x56A0,
+	0x9A89, 0x5694, 0x9A8A, 0x568F, 0x9A8B, 0x56A5, 0x9A8C, 0x56AE,
+	0x9A8D, 0x56B6, 0x9A8E, 0x56B4, 0x9A8F, 0x56C2, 0x9A90, 0x56BC,
+	0x9A91, 0x56C1, 0x9A92, 0x56C3, 0x9A93, 0x56C0, 0x9A94, 0x56C8,
+	0x9A95, 0x56CE, 0x9A96, 0x56D1, 0x9A97, 0x56D3, 0x9A98, 0x56D7,
+	0x9A99, 0x56EE, 0x9A9A, 0x56F9, 0x9A9B, 0x5700, 0x9A9C, 0x56FF,
+	0x9A9D, 0x5704, 0x9A9E, 0x5709, 0x9A9F, 0x5708, 0x9AA0, 0x570B,
+	0x9AA1, 0x570D, 0x9AA2, 0x5713, 0x9AA3, 0x5718, 0x9AA4, 0x5716,
+	0x9AA5, 0x55C7, 0x9AA6, 0x571C, 0x9AA7, 0x5726, 0x9AA8, 0x5737,
+	0x9AA9, 0x5738, 0x9AAA, 0x574E, 0x9AAB, 0x573B, 0x9AAC, 0x5740,
+	0x9AAD, 0x574F, 0x9AAE, 0x5769, 0x9AAF, 0x57C0, 0x9AB0, 0x5788,
+	0x9AB1, 0x5761, 0x9AB2, 0x577F, 0x9AB3, 0x5789, 0x9AB4, 0x5793,
+	0x9AB5, 0x57A0, 0x9AB6, 0x57B3, 0x9AB7, 0x57A4, 0x9AB8, 0x57AA,
+	0x9AB9, 0x57B0, 0x9ABA, 0x57C3, 0x9ABB, 0x57C6, 0x9ABC, 0x57D4,
+	0x9ABD, 0x57D2, 0x9ABE, 0x57D3, 0x9ABF, 0x580A, 0x9AC0, 0x57D6,
+	0x9AC1, 0x57E3, 0x9AC2, 0x580B, 0x9AC3, 0x5819, 0x9AC4, 0x581D,
+	0x9AC5, 0x5872, 0x9AC6, 0x5821, 0x9AC7, 0x5862, 0x9AC8, 0x584B,
+	0x9AC9, 0x5870, 0x9ACA, 0x6BC0, 0x9ACB, 0x5852, 0x9ACC, 0x583D,
+	0x9ACD, 0x5879, 0x9ACE, 0x5885, 0x9ACF, 0x58B9, 0x9AD0, 0x589F,
+	0x9AD1, 0x58AB, 0x9AD2, 0x58BA, 0x9AD3, 0x58DE, 0x9AD4, 0x58BB,
+	0x9AD5, 0x58B8, 0x9AD6, 0x58AE, 0x9AD7, 0x58C5, 0x9AD8, 0x58D3,
+	0x9AD9, 0x58D1, 0x9ADA, 0x58D7, 0x9ADB, 0x58D9, 0x9ADC, 0x58D8,
+	0x9ADD, 0x58E5, 0x9ADE, 0x58DC, 0x9ADF, 0x58E4, 0x9AE0, 0x58DF,
+	0x9AE1, 0x58EF, 0x9AE2, 0x58FA, 0x9AE3, 0x58F9, 0x9AE4, 0x58FB,
+	0x9AE5, 0x58FC, 0x9AE6, 0x58FD, 0x9AE7, 0x5902, 0x9AE8, 0x590A,
+	0x9AE9, 0x5910, 0x9AEA, 0x591B, 0x9AEB, 0x68A6, 0x9AEC, 0x5925,
+	0x9AED, 0x592C, 0x9AEE, 0x592D, 0x9AEF, 0x5932, 0x9AF0, 0x5938,
+	0x9AF1, 0x593E, 0x9AF2, 0x7AD2, 0x9AF3, 0x5955, 0x9AF4, 0x5950,
+	0x9AF5, 0x594E, 0x9AF6, 0x595A, 0x9AF7, 0x5958, 0x9AF8, 0x5962,
+	0x9AF9, 0x5960, 0x9AFA, 0x5967, 0x9AFB, 0x596C, 0x9AFC, 0x5969,
+	0x9B40, 0x5978, 0x9B41, 0x5981, 0x9B42, 0x599D, 0x9B43, 0x4F5E,
+	0x9B44, 0x4FAB, 0x9B45, 0x59A3, 0x9B46, 0x59B2, 0x9B47, 0x59C6,
+	0x9B48, 0x59E8, 0x9B49, 0x59DC, 0x9B4A, 0x598D, 0x9B4B, 0x59D9,
+	0x9B4C, 0x59DA, 0x9B4D, 0x5A25, 0x9B4E, 0x5A1F, 0x9B4F, 0x5A11,
+	0x9B50, 0x5A1C, 0x9B51, 0x5A09, 0x9B52, 0x5A1A, 0x9B53, 0x5A40,
+	0x9B54, 0x5A6C, 0x9B55, 0x5A49, 0x9B56, 0x5A35, 0x9B57, 0x5A36,
+	0x9B58, 0x5A62, 0x9B59, 0x5A6A, 0x9B5A, 0x5A9A, 0x9B5B, 0x5ABC,
+	0x9B5C, 0x5ABE, 0x9B5D, 0x5ACB, 0x9B5E, 0x5AC2, 0x9B5F, 0x5ABD,
+	0x9B60, 0x5AE3, 0x9B61, 0x5AD7, 0x9B62, 0x5AE6, 0x9B63, 0x5AE9,
+	0x9B64, 0x5AD6, 0x9B65, 0x5AFA, 0x9B66, 0x5AFB, 0x9B67, 0x5B0C,
+	0x9B68, 0x5B0B, 0x9B69, 0x5B16, 0x9B6A, 0x5B32, 0x9B6B, 0x5AD0,
+	0x9B6C, 0x5B2A, 0x9B6D, 0x5B36, 0x9B6E, 0x5B3E, 0x9B6F, 0x5B43,
+	0x9B70, 0x5B45, 0x9B71, 0x5B40, 0x9B72, 0x5B51, 0x9B73, 0x5B55,
+	0x9B74, 0x5B5A, 0x9B75, 0x5B5B, 0x9B76, 0x5B65, 0x9B77, 0x5B69,
+	0x9B78, 0x5B70, 0x9B79, 0x5B73, 0x9B7A, 0x5B75, 0x9B7B, 0x5B78,
+	0x9B7C, 0x6588, 0x9B7D, 0x5B7A, 0x9B7E, 0x5B80, 0x9B80, 0x5B83,
+	0x9B81, 0x5BA6, 0x9B82, 0x5BB8, 0x9B83, 0x5BC3, 0x9B84, 0x5BC7,
+	0x9B85, 0x5BC9, 0x9B86, 0x5BD4, 0x9B87, 0x5BD0, 0x9B88, 0x5BE4,
+	0x9B89, 0x5BE6, 0x9B8A, 0x5BE2, 0x9B8B, 0x5BDE, 0x9B8C, 0x5BE5,
+	0x9B8D, 0x5BEB, 0x9B8E, 0x5BF0, 0x9B8F, 0x5BF6, 0x9B90, 0x5BF3,
+	0x9B91, 0x5C05, 0x9B92, 0x5C07, 0x9B93, 0x5C08, 0x9B94, 0x5C0D,
+	0x9B95, 0x5C13, 0x9B96, 0x5C20, 0x9B97, 0x5C22, 0x9B98, 0x5C28,
+	0x9B99, 0x5C38, 0x9B9A, 0x5C39, 0x9B9B, 0x5C41, 0x9B9C, 0x5C46,
+	0x9B9D, 0x5C4E, 0x9B9E, 0x5C53, 0x9B9F, 0x5C50, 0x9BA0, 0x5C4F,
+	0x9BA1, 0x5B71, 0x9BA2, 0x5C6C, 0x9BA3, 0x5C6E, 0x9BA4, 0x4E62,
+	0x9BA5, 0x5C76, 0x9BA6, 0x5C79, 0x9BA7, 0x5C8C, 0x9BA8, 0x5C91,
+	0x9BA9, 0x5C94, 0x9BAA, 0x599B, 0x9BAB, 0x5CAB, 0x9BAC, 0x5CBB,
+	0x9BAD, 0x5CB6, 0x9BAE, 0x5CBC, 0x9BAF, 0x5CB7, 0x9BB0, 0x5CC5,
+	0x9BB1, 0x5CBE, 0x9BB2, 0x5CC7, 0x9BB3, 0x5CD9, 0x9BB4, 0x5CE9,
+	0x9BB5, 0x5CFD, 0x9BB6, 0x5CFA, 0x9BB7, 0x5CED, 0x9BB8, 0x5D8C,
+	0x9BB9, 0x5CEA, 0x9BBA, 0x5D0B, 0x9BBB, 0x5D15, 0x9BBC, 0x5D17,
+	0x9BBD, 0x5D5C, 0x9BBE, 0x5D1F, 0x9BBF, 0x5D1B, 0x9BC0, 0x5D11,
+	0x9BC1, 0x5D14, 0x9BC2, 0x5D22, 0x9BC3, 0x5D1A, 0x9BC4, 0x5D19,
+	0x9BC5, 0x5D18, 0x9BC6, 0x5D4C, 0x9BC7, 0x5D52, 0x9BC8, 0x5D4E,
+	0x9BC9, 0x5D4B, 0x9BCA, 0x5D6C, 0x9BCB, 0x5D73, 0x9BCC, 0x5D76,
+	0x9BCD, 0x5D87, 0x9BCE, 0x5D84, 0x9BCF, 0x5D82, 0x9BD0, 0x5DA2,
+	0x9BD1, 0x5D9D, 0x9BD2, 0x5DAC, 0x9BD3, 0x5DAE, 0x9BD4, 0x5DBD,
+	0x9BD5, 0x5D90, 0x9BD6, 0x5DB7, 0x9BD7, 0x5DBC, 0x9BD8, 0x5DC9,
+	0x9BD9, 0x5DCD, 0x9BDA, 0x5DD3, 0x9BDB, 0x5DD2, 0x9BDC, 0x5DD6,
+	0x9BDD, 0x5DDB, 0x9BDE, 0x5DEB, 0x9BDF, 0x5DF2, 0x9BE0, 0x5DF5,
+	0x9BE1, 0x5E0B, 0x9BE2, 0x5E1A, 0x9BE3, 0x5E19, 0x9BE4, 0x5E11,
+	0x9BE5, 0x5E1B, 0x9BE6, 0x5E36, 0x9BE7, 0x5E37, 0x9BE8, 0x5E44,
+	0x9BE9, 0x5E43, 0x9BEA, 0x5E40, 0x9BEB, 0x5E4E, 0x9BEC, 0x5E57,
+	0x9BED, 0x5E54, 0x9BEE, 0x5E5F, 0x9BEF, 0x5E62, 0x9BF0, 0x5E64,
+	0x9BF1, 0x5E47, 0x9BF2, 0x5E75, 0x9BF3, 0x5E76, 0x9BF4, 0x5E7A,
+	0x9BF5, 0x9EBC, 0x9BF6, 0x5E7F, 0x9BF7, 0x5EA0, 0x9BF8, 0x5EC1,
+	0x9BF9, 0x5EC2, 0x9BFA, 0x5EC8, 0x9BFB, 0x5ED0, 0x9BFC, 0x5ECF,
+	0x9C40, 0x5ED6, 0x9C41, 0x5EE3, 0x9C42, 0x5EDD, 0x9C43, 0x5EDA,
+	0x9C44, 0x5EDB, 0x9C45, 0x5EE2, 0x9C46, 0x5EE1, 0x9C47, 0x5EE8,
+	0x9C48, 0x5EE9, 0x9C49, 0x5EEC, 0x9C4A, 0x5EF1, 0x9C4B, 0x5EF3,
+	0x9C4C, 0x5EF0, 0x9C4D, 0x5EF4, 0x9C4E, 0x5EF8, 0x9C4F, 0x5EFE,
+	0x9C50, 0x5F03, 0x9C51, 0x5F09, 0x9C52, 0x5F5D, 0x9C53, 0x5F5C,
+	0x9C54, 0x5F0B, 0x9C55, 0x5F11, 0x9C56, 0x5F16, 0x9C57, 0x5F29,
+	0x9C58, 0x5F2D, 0x9C59, 0x5F38, 0x9C5A, 0x5F41, 0x9C5B, 0x5F48,
+	0x9C5C, 0x5F4C, 0x9C5D, 0x5F4E, 0x9C5E, 0x5F2F, 0x9C5F, 0x5F51,
+	0x9C60, 0x5F56, 0x9C61, 0x5F57, 0x9C62, 0x5F59, 0x9C63, 0x5F61,
+	0x9C64, 0x5F6D, 0x9C65, 0x5F73, 0x9C66, 0x5F77, 0x9C67, 0x5F83,
+	0x9C68, 0x5F82, 0x9C69, 0x5F7F, 0x9C6A, 0x5F8A, 0x9C6B, 0x5F88,
+	0x9C6C, 0x5F91, 0x9C6D, 0x5F87, 0x9C6E, 0x5F9E, 0x9C6F, 0x5F99,
+	0x9C70, 0x5F98, 0x9C71, 0x5FA0, 0x9C72, 0x5FA8, 0x9C73, 0x5FAD,
+	0x9C74, 0x5FBC, 0x9C75, 0x5FD6, 0x9C76, 0x5FFB, 0x9C77, 0x5FE4,
+	0x9C78, 0x5FF8, 0x9C79, 0x5FF1, 0x9C7A, 0x5FDD, 0x9C7B, 0x60B3,
+	0x9C7C, 0x5FFF, 0x9C7D, 0x6021, 0x9C7E, 0x6060, 0x9C80, 0x6019,
+	0x9C81, 0x6010, 0x9C82, 0x6029, 0x9C83, 0x600E, 0x9C84, 0x6031,
+	0x9C85, 0x601B, 0x9C86, 0x6015, 0x9C87, 0x602B, 0x9C88, 0x6026,
+	0x9C89, 0x600F, 0x9C8A, 0x603A, 0x9C8B, 0x605A, 0x9C8C, 0x6041,
+	0x9C8D, 0x606A, 0x9C8E, 0x6077, 0x9C8F, 0x605F, 0x9C90, 0x604A,
+	0x9C91, 0x6046, 0x9C92, 0x604D, 0x9C93, 0x6063, 0x9C94, 0x6043,
+	0x9C95, 0x6064, 0x9C96, 0x6042, 0x9C97, 0x606C, 0x9C98, 0x606B,
+	0x9C99, 0x6059, 0x9C9A, 0x6081, 0x9C9B, 0x608D, 0x9C9C, 0x60E7,
+	0x9C9D, 0x6083, 0x9C9E, 0x609A, 0x9C9F, 0x6084, 0x9CA0, 0x609B,
+	0x9CA1, 0x6096, 0x9CA2, 0x6097, 0x9CA3, 0x6092, 0x9CA4, 0x60A7,
+	0x9CA5, 0x608B, 0x9CA6, 0x60E1, 0x9CA7, 0x60B8, 0x9CA8, 0x60E0,
+	0x9CA9, 0x60D3, 0x9CAA, 0x60B4, 0x9CAB, 0x5FF0, 0x9CAC, 0x60BD,
+	0x9CAD, 0x60C6, 0x9CAE, 0x60B5, 0x9CAF, 0x60D8, 0x9CB0, 0x614D,
+	0x9CB1, 0x6115, 0x9CB2, 0x6106, 0x9CB3, 0x60F6, 0x9CB4, 0x60F7,
+	0x9CB5, 0x6100, 0x9CB6, 0x60F4, 0x9CB7, 0x60FA, 0x9CB8, 0x6103,
+	0x9CB9, 0x6121, 0x9CBA, 0x60FB, 0x9CBB, 0x60F1, 0x9CBC, 0x610D,
+	0x9CBD, 0x610E, 0x9CBE, 0x6147, 0x9CBF, 0x613E, 0x9CC0, 0x6128,
+	0x9CC1, 0x6127, 0x9CC2, 0x614A, 0x9CC3, 0x613F, 0x9CC4, 0x613C,
+	0x9CC5, 0x612C, 0x9CC6, 0x6134, 0x9CC7, 0x613D, 0x9CC8, 0x6142,
+	0x9CC9, 0x6144, 0x9CCA, 0x6173, 0x9CCB, 0x6177, 0x9CCC, 0x6158,
+	0x9CCD, 0x6159, 0x9CCE, 0x615A, 0x9CCF, 0x616B, 0x9CD0, 0x6174,
+	0x9CD1, 0x616F, 0x9CD2, 0x6165, 0x9CD3, 0x6171, 0x9CD4, 0x615F,
+	0x9CD5, 0x615D, 0x9CD6, 0x6153, 0x9CD7, 0x6175, 0x9CD8, 0x6199,
+	0x9CD9, 0x6196, 0x9CDA, 0x6187, 0x9CDB, 0x61AC, 0x9CDC, 0x6194,
+	0x9CDD, 0x619A, 0x9CDE, 0x618A, 0x9CDF, 0x6191, 0x9CE0, 0x61AB,
+	0x9CE1, 0x61AE, 0x9CE2, 0x61CC, 0x9CE3, 0x61CA, 0x9CE4, 0x61C9,
+	0x9CE5, 0x61F7, 0x9CE6, 0x61C8, 0x9CE7, 0x61C3, 0x9CE8, 0x61C6,
+	0x9CE9, 0x61BA, 0x9CEA, 0x61CB, 0x9CEB, 0x7F79, 0x9CEC, 0x61CD,
+	0x9CED, 0x61E6, 0x9CEE, 0x61E3, 0x9CEF, 0x61F6, 0x9CF0, 0x61FA,
+	0x9CF1, 0x61F4, 0x9CF2, 0x61FF, 0x9CF3, 0x61FD, 0x9CF4, 0x61FC,
+	0x9CF5, 0x61FE, 0x9CF6, 0x6200, 0x9CF7, 0x6208, 0x9CF8, 0x6209,
+	0x9CF9, 0x620D, 0x9CFA, 0x620C, 0x9CFB, 0x6214, 0x9CFC, 0x621B,
+	0x9D40, 0x621E, 0x9D41, 0x6221, 0x9D42, 0x622A, 0x9D43, 0x622E,
+	0x9D44, 0x6230, 0x9D45, 0x6232, 0x9D46, 0x6233, 0x9D47, 0x6241,
+	0x9D48, 0x624E, 0x9D49, 0x625E, 0x9D4A, 0x6263, 0x9D4B, 0x625B,
+	0x9D4C, 0x6260, 0x9D4D, 0x6268, 0x9D4E, 0x627C, 0x9D4F, 0x6282,
+	0x9D50, 0x6289, 0x9D51, 0x627E, 0x9D52, 0x6292, 0x9D53, 0x6293,
+	0x9D54, 0x6296, 0x9D55, 0x62D4, 0x9D56, 0x6283, 0x9D57, 0x6294,
+	0x9D58, 0x62D7, 0x9D59, 0x62D1, 0x9D5A, 0x62BB, 0x9D5B, 0x62CF,
+	0x9D5C, 0x62FF, 0x9D5D, 0x62C6, 0x9D5E, 0x64D4, 0x9D5F, 0x62C8,
+	0x9D60, 0x62DC, 0x9D61, 0x62CC, 0x9D62, 0x62CA, 0x9D63, 0x62C2,
+	0x9D64, 0x62C7, 0x9D65, 0x629B, 0x9D66, 0x62C9, 0x9D67, 0x630C,
+	0x9D68, 0x62EE, 0x9D69, 0x62F1, 0x9D6A, 0x6327, 0x9D6B, 0x6302,
+	0x9D6C, 0x6308, 0x9D6D, 0x62EF, 0x9D6E, 0x62F5, 0x9D6F, 0x6350,
+	0x9D70, 0x633E, 0x9D71, 0x634D, 0x9D72, 0x641C, 0x9D73, 0x634F,
+	0x9D74, 0x6396, 0x9D75, 0x638E, 0x9D76, 0x6380, 0x9D77, 0x63AB,
+	0x9D78, 0x6376, 0x9D79, 0x63A3, 0x9D7A, 0x638F, 0x9D7B, 0x6389,
+	0x9D7C, 0x639F, 0x9D7D, 0x63B5, 0x9D7E, 0x636B, 0x9D80, 0x6369,
+	0x9D81, 0x63BE, 0x9D82, 0x63E9, 0x9D83, 0x63C0, 0x9D84, 0x63C6,
+	0x9D85, 0x63E3, 0x9D86, 0x63C9, 0x9D87, 0x63D2, 0x9D88, 0x63F6,
+	0x9D89, 0x63C4, 0x9D8A, 0x6416, 0x9D8B, 0x6434, 0x9D8C, 0x6406,
+	0x9D8D, 0x6413, 0x9D8E, 0x6426, 0x9D8F, 0x6436, 0x9D90, 0x651D,
+	0x9D91, 0x6417, 0x9D92, 0x6428, 0x9D93, 0x640F, 0x9D94, 0x6467,
+	0x9D95, 0x646F, 0x9D96, 0x6476, 0x9D97, 0x644E, 0x9D98, 0x652A,
+	0x9D99, 0x6495, 0x9D9A, 0x6493, 0x9D9B, 0x64A5, 0x9D9C, 0x64A9,
+	0x9D9D, 0x6488, 0x9D9E, 0x64BC, 0x9D9F, 0x64DA, 0x9DA0, 0x64D2,
+	0x9DA1, 0x64C5, 0x9DA2, 0x64C7, 0x9DA3, 0x64BB, 0x9DA4, 0x64D8,
+	0x9DA5, 0x64C2, 0x9DA6, 0x64F1, 0x9DA7, 0x64E7, 0x9DA8, 0x8209,
+	0x9DA9, 0x64E0, 0x9DAA, 0x64E1, 0x9DAB, 0x62AC, 0x9DAC, 0x64E3,
+	0x9DAD, 0x64EF, 0x9DAE, 0x652C, 0x9DAF, 0x64F6, 0x9DB0, 0x64F4,
+	0x9DB1, 0x64F2, 0x9DB2, 0x64FA, 0x9DB3, 0x6500, 0x9DB4, 0x64FD,
+	0x9DB5, 0x6518, 0x9DB6, 0x651C, 0x9DB7, 0x6505, 0x9DB8, 0x6524,
+	0x9DB9, 0x6523, 0x9DBA, 0x652B, 0x9DBB, 0x6534, 0x9DBC, 0x6535,
+	0x9DBD, 0x6537, 0x9DBE, 0x6536, 0x9DBF, 0x6538, 0x9DC0, 0x754B,
+	0x9DC1, 0x6548, 0x9DC2, 0x6556, 0x9DC3, 0x6555, 0x9DC4, 0x654D,
+	0x9DC5, 0x6558, 0x9DC6, 0x655E, 0x9DC7, 0x655D, 0x9DC8, 0x6572,
+	0x9DC9, 0x6578, 0x9DCA, 0x6582, 0x9DCB, 0x6583, 0x9DCC, 0x8B8A,
+	0x9DCD, 0x659B, 0x9DCE, 0x659F, 0x9DCF, 0x65AB, 0x9DD0, 0x65B7,
+	0x9DD1, 0x65C3, 0x9DD2, 0x65C6, 0x9DD3, 0x65C1, 0x9DD4, 0x65C4,
+	0x9DD5, 0x65CC, 0x9DD6, 0x65D2, 0x9DD7, 0x65DB, 0x9DD8, 0x65D9,
+	0x9DD9, 0x65E0, 0x9DDA, 0x65E1, 0x9DDB, 0x65F1, 0x9DDC, 0x6772,
+	0x9DDD, 0x660A, 0x9DDE, 0x6603, 0x9DDF, 0x65FB, 0x9DE0, 0x6773,
+	0x9DE1, 0x6635, 0x9DE2, 0x6636, 0x9DE3, 0x6634, 0x9DE4, 0x661C,
+	0x9DE5, 0x664F, 0x9DE6, 0x6644, 0x9DE7, 0x6649, 0x9DE8, 0x6641,
+	0x9DE9, 0x665E, 0x9DEA, 0x665D, 0x9DEB, 0x6664, 0x9DEC, 0x6667,
+	0x9DED, 0x6668, 0x9DEE, 0x665F, 0x9DEF, 0x6662, 0x9DF0, 0x6670,
+	0x9DF1, 0x6683, 0x9DF2, 0x6688, 0x9DF3, 0x668E, 0x9DF4, 0x6689,
+	0x9DF5, 0x6684, 0x9DF6, 0x6698, 0x9DF7, 0x669D, 0x9DF8, 0x66C1,
+	0x9DF9, 0x66B9, 0x9DFA, 0x66C9, 0x9DFB, 0x66BE, 0x9DFC, 0x66BC,
+	0x9E40, 0x66C4, 0x9E41, 0x66B8, 0x9E42, 0x66D6, 0x9E43, 0x66DA,
+	0x9E44, 0x66E0, 0x9E45, 0x663F, 0x9E46, 0x66E6, 0x9E47, 0x66E9,
+	0x9E48, 0x66F0, 0x9E49, 0x66F5, 0x9E4A, 0x66F7, 0x9E4B, 0x670F,
+	0x9E4C, 0x6716, 0x9E4D, 0x671E, 0x9E4E, 0x6726, 0x9E4F, 0x6727,
+	0x9E50, 0x9738, 0x9E51, 0x672E, 0x9E52, 0x673F, 0x9E53, 0x6736,
+	0x9E54, 0x6741, 0x9E55, 0x6738, 0x9E56, 0x6737, 0x9E57, 0x6746,
+	0x9E58, 0x675E, 0x9E59, 0x6760, 0x9E5A, 0x6759, 0x9E5B, 0x6763,
+	0x9E5C, 0x6764, 0x9E5D, 0x6789, 0x9E5E, 0x6770, 0x9E5F, 0x67A9,
+	0x9E60, 0x677C, 0x9E61, 0x676A, 0x9E62, 0x678C, 0x9E63, 0x678B,
+	0x9E64, 0x67A6, 0x9E65, 0x67A1, 0x9E66, 0x6785, 0x9E67, 0x67B7,
+	0x9E68, 0x67EF, 0x9E69, 0x67B4, 0x9E6A, 0x67EC, 0x9E6B, 0x67B3,
+	0x9E6C, 0x67E9, 0x9E6D, 0x67B8, 0x9E6E, 0x67E4, 0x9E6F, 0x67DE,
+	0x9E70, 0x67DD, 0x9E71, 0x67E2, 0x9E72, 0x67EE, 0x9E73, 0x67B9,
+	0x9E74, 0x67CE, 0x9E75, 0x67C6, 0x9E76, 0x67E7, 0x9E77, 0x6A9C,
+	0x9E78, 0x681E, 0x9E79, 0x6846, 0x9E7A, 0x6829, 0x9E7B, 0x6840,
+	0x9E7C, 0x684D, 0x9E7D, 0x6832, 0x9E7E, 0x684E, 0x9E80, 0x68B3,
+	0x9E81, 0x682B, 0x9E82, 0x6859, 0x9E83, 0x6863, 0x9E84, 0x6877,
+	0x9E85, 0x687F, 0x9E86, 0x689F, 0x9E87, 0x688F, 0x9E88, 0x68AD,
+	0x9E89, 0x6894, 0x9E8A, 0x689D, 0x9E8B, 0x689B, 0x9E8C, 0x6883,
+	0x9E8D, 0x6AAE, 0x9E8E, 0x68B9, 0x9E8F, 0x6874, 0x9E90, 0x68B5,
+	0x9E91, 0x68A0, 0x9E92, 0x68BA, 0x9E93, 0x690F, 0x9E94, 0x688D,
+	0x9E95, 0x687E, 0x9E96, 0x6901, 0x9E97, 0x68CA, 0x9E98, 0x6908,
+	0x9E99, 0x68D8, 0x9E9A, 0x6922, 0x9E9B, 0x6926, 0x9E9C, 0x68E1,
+	0x9E9D, 0x690C, 0x9E9E, 0x68CD, 0x9E9F, 0x68D4, 0x9EA0, 0x68E7,
+	0x9EA1, 0x68D5, 0x9EA2, 0x6936, 0x9EA3, 0x6912, 0x9EA4, 0x6904,
+	0x9EA5, 0x68D7, 0x9EA6, 0x68E3, 0x9EA7, 0x6925, 0x9EA8, 0x68F9,
+	0x9EA9, 0x68E0, 0x9EAA, 0x68EF, 0x9EAB, 0x6928, 0x9EAC, 0x692A,
+	0x9EAD, 0x691A, 0x9EAE, 0x6923, 0x9EAF, 0x6921, 0x9EB0, 0x68C6,
+	0x9EB1, 0x6979, 0x9EB2, 0x6977, 0x9EB3, 0x695C, 0x9EB4, 0x6978,
+	0x9EB5, 0x696B, 0x9EB6, 0x6954, 0x9EB7, 0x697E, 0x9EB8, 0x696E,
+	0x9EB9, 0x6939, 0x9EBA, 0x6974, 0x9EBB, 0x693D, 0x9EBC, 0x6959,
+	0x9EBD, 0x6930, 0x9EBE, 0x6961, 0x9EBF, 0x695E, 0x9EC0, 0x695D,
+	0x9EC1, 0x6981, 0x9EC2, 0x696A, 0x9EC3, 0x69B2, 0x9EC4, 0x69AE,
+	0x9EC5, 0x69D0, 0x9EC6, 0x69BF, 0x9EC7, 0x69C1, 0x9EC8, 0x69D3,
+	0x9EC9, 0x69BE, 0x9ECA, 0x69CE, 0x9ECB, 0x5BE8, 0x9ECC, 0x69CA,
+	0x9ECD, 0x69DD, 0x9ECE, 0x69BB, 0x9ECF, 0x69C3, 0x9ED0, 0x69A7,
+	0x9ED1, 0x6A2E, 0x9ED2, 0x6991, 0x9ED3, 0x69A0, 0x9ED4, 0x699C,
+	0x9ED5, 0x6995, 0x9ED6, 0x69B4, 0x9ED7, 0x69DE, 0x9ED8, 0x69E8,
+	0x9ED9, 0x6A02, 0x9EDA, 0x6A1B, 0x9EDB, 0x69FF, 0x9EDC, 0x6B0A,
+	0x9EDD, 0x69F9, 0x9EDE, 0x69F2, 0x9EDF, 0x69E7, 0x9EE0, 0x6A05,
+	0x9EE1, 0x69B1, 0x9EE2, 0x6A1E, 0x9EE3, 0x69ED, 0x9EE4, 0x6A14,
+	0x9EE5, 0x69EB, 0x9EE6, 0x6A0A, 0x9EE7, 0x6A12, 0x9EE8, 0x6AC1,
+	0x9EE9, 0x6A23, 0x9EEA, 0x6A13, 0x9EEB, 0x6A44, 0x9EEC, 0x6A0C,
+	0x9EED, 0x6A72, 0x9EEE, 0x6A36, 0x9EEF, 0x6A78, 0x9EF0, 0x6A47,
+	0x9EF1, 0x6A62, 0x9EF2, 0x6A59, 0x9EF3, 0x6A66, 0x9EF4, 0x6A48,
+	0x9EF5, 0x6A38, 0x9EF6, 0x6A22, 0x9EF7, 0x6A90, 0x9EF8, 0x6A8D,
+	0x9EF9, 0x6AA0, 0x9EFA, 0x6A84, 0x9EFB, 0x6AA2, 0x9EFC, 0x6AA3,
+	0x9F40, 0x6A97, 0x9F41, 0x8617, 0x9F42, 0x6ABB, 0x9F43, 0x6AC3,
+	0x9F44, 0x6AC2, 0x9F45, 0x6AB8, 0x9F46, 0x6AB3, 0x9F47, 0x6AAC,
+	0x9F48, 0x6ADE, 0x9F49, 0x6AD1, 0x9F4A, 0x6ADF, 0x9F4B, 0x6AAA,
+	0x9F4C, 0x6ADA, 0x9F4D, 0x6AEA, 0x9F4E, 0x6AFB, 0x9F4F, 0x6B05,
+	0x9F50, 0x8616, 0x9F51, 0x6AFA, 0x9F52, 0x6B12, 0x9F53, 0x6B16,
+	0x9F54, 0x9B31, 0x9F55, 0x6B1F, 0x9F56, 0x6B38, 0x9F57, 0x6B37,
+	0x9F58, 0x76DC, 0x9F59, 0x6B39, 0x9F5A, 0x98EE, 0x9F5B, 0x6B47,
+	0x9F5C, 0x6B43, 0x9F5D, 0x6B49, 0x9F5E, 0x6B50, 0x9F5F, 0x6B59,
+	0x9F60, 0x6B54, 0x9F61, 0x6B5B, 0x9F62, 0x6B5F, 0x9F63, 0x6B61,
+	0x9F64, 0x6B78, 0x9F65, 0x6B79, 0x9F66, 0x6B7F, 0x9F67, 0x6B80,
+	0x9F68, 0x6B84, 0x9F69, 0x6B83, 0x9F6A, 0x6B8D, 0x9F6B, 0x6B98,
+	0x9F6C, 0x6B95, 0x9F6D, 0x6B9E, 0x9F6E, 0x6BA4, 0x9F6F, 0x6BAA,
+	0x9F70, 0x6BAB, 0x9F71, 0x6BAF, 0x9F72, 0x6BB2, 0x9F73, 0x6BB1,
+	0x9F74, 0x6BB3, 0x9F75, 0x6BB7, 0x9F76, 0x6BBC, 0x9F77, 0x6BC6,
+	0x9F78, 0x6BCB, 0x9F79, 0x6BD3, 0x9F7A, 0x6BDF, 0x9F7B, 0x6BEC,
+	0x9F7C, 0x6BEB, 0x9F7D, 0x6BF3, 0x9F7E, 0x6BEF, 0x9F80, 0x9EBE,
+	0x9F81, 0x6C08, 0x9F82, 0x6C13, 0x9F83, 0x6C14, 0x9F84, 0x6C1B,
+	0x9F85, 0x6C24, 0x9F86, 0x6C23, 0x9F87, 0x6C5E, 0x9F88, 0x6C55,
+	0x9F89, 0x6C62, 0x9F8A, 0x6C6A, 0x9F8B, 0x6C82, 0x9F8C, 0x6C8D,
+	0x9F8D, 0x6C9A, 0x9F8E, 0x6C81, 0x9F8F, 0x6C9B, 0x9F90, 0x6C7E,
+	0x9F91, 0x6C68, 0x9F92, 0x6C73, 0x9F93, 0x6C92, 0x9F94, 0x6C90,
+	0x9F95, 0x6CC4, 0x9F96, 0x6CF1, 0x9F97, 0x6CD3, 0x9F98, 0x6CBD,
+	0x9F99, 0x6CD7, 0x9F9A, 0x6CC5, 0x9F9B, 0x6CDD, 0x9F9C, 0x6CAE,
+	0x9F9D, 0x6CB1, 0x9F9E, 0x6CBE, 0x9F9F, 0x6CBA, 0x9FA0, 0x6CDB,
+	0x9FA1, 0x6CEF, 0x9FA2, 0x6CD9, 0x9FA3, 0x6CEA, 0x9FA4, 0x6D1F,
+	0x9FA5, 0x884D, 0x9FA6, 0x6D36, 0x9FA7, 0x6D2B, 0x9FA8, 0x6D3D,
+	0x9FA9, 0x6D38, 0x9FAA, 0x6D19, 0x9FAB, 0x6D35, 0x9FAC, 0x6D33,
+	0x9FAD, 0x6D12, 0x9FAE, 0x6D0C, 0x9FAF, 0x6D63, 0x9FB0, 0x6D93,
+	0x9FB1, 0x6D64, 0x9FB2, 0x6D5A, 0x9FB3, 0x6D79, 0x9FB4, 0x6D59,
+	0x9FB5, 0x6D8E, 0x9FB6, 0x6D95, 0x9FB7, 0x6FE4, 0x9FB8, 0x6D85,
+	0x9FB9, 0x6DF9, 0x9FBA, 0x6E15, 0x9FBB, 0x6E0A, 0x9FBC, 0x6DB5,
+	0x9FBD, 0x6DC7, 0x9FBE, 0x6DE6, 0x9FBF, 0x6DB8, 0x9FC0, 0x6DC6,
+	0x9FC1, 0x6DEC, 0x9FC2, 0x6DDE, 0x9FC3, 0x6DCC, 0x9FC4, 0x6DE8,
+	0x9FC5, 0x6DD2, 0x9FC6, 0x6DC5, 0x9FC7, 0x6DFA, 0x9FC8, 0x6DD9,
+	0x9FC9, 0x6DE4, 0x9FCA, 0x6DD5, 0x9FCB, 0x6DEA, 0x9FCC, 0x6DEE,
+	0x9FCD, 0x6E2D, 0x9FCE, 0x6E6E, 0x9FCF, 0x6E2E, 0x9FD0, 0x6E19,
+	0x9FD1, 0x6E72, 0x9FD2, 0x6E5F, 0x9FD3, 0x6E3E, 0x9FD4, 0x6E23,
+	0x9FD5, 0x6E6B, 0x9FD6, 0x6E2B, 0x9FD7, 0x6E76, 0x9FD8, 0x6E4D,
+	0x9FD9, 0x6E1F, 0x9FDA, 0x6E43, 0x9FDB, 0x6E3A, 0x9FDC, 0x6E4E,
+	0x9FDD, 0x6E24, 0x9FDE, 0x6EFF, 0x9FDF, 0x6E1D, 0x9FE0, 0x6E38,
+	0x9FE1, 0x6E82, 0x9FE2, 0x6EAA, 0x9FE3, 0x6E98, 0x9FE4, 0x6EC9,
+	0x9FE5, 0x6EB7, 0x9FE6, 0x6ED3, 0x9FE7, 0x6EBD, 0x9FE8, 0x6EAF,
+	0x9FE9, 0x6EC4, 0x9FEA, 0x6EB2, 0x9FEB, 0x6ED4, 0x9FEC, 0x6ED5,
+	0x9FED, 0x6E8F, 0x9FEE, 0x6EA5, 0x9FEF, 0x6EC2, 0x9FF0, 0x6E9F,
+	0x9FF1, 0x6F41, 0x9FF2, 0x6F11, 0x9FF3, 0x704C, 0x9FF4, 0x6EEC,
+	0x9FF5, 0x6EF8, 0x9FF6, 0x6EFE, 0x9FF7, 0x6F3F, 0x9FF8, 0x6EF2,
+	0x9FF9, 0x6F31, 0x9FFA, 0x6EEF, 0x9FFB, 0x6F32, 0x9FFC, 0x6ECC,
+	0xE040, 0x6F3E, 0xE041, 0x6F13, 0xE042, 0x6EF7, 0xE043, 0x6F86,
+	0xE044, 0x6F7A, 0xE045, 0x6F78, 0xE046, 0x6F81, 0xE047, 0x6F80,
+	0xE048, 0x6F6F, 0xE049, 0x6F5B, 0xE04A, 0x6FF3, 0xE04B, 0x6F6D,
+	0xE04C, 0x6F82, 0xE04D, 0x6F7C, 0xE04E, 0x6F58, 0xE04F, 0x6F8E,
+	0xE050, 0x6F91, 0xE051, 0x6FC2, 0xE052, 0x6F66, 0xE053, 0x6FB3,
+	0xE054, 0x6FA3, 0xE055, 0x6FA1, 0xE056, 0x6FA4, 0xE057, 0x6FB9,
+	0xE058, 0x6FC6, 0xE059, 0x6FAA, 0xE05A, 0x6FDF, 0xE05B, 0x6FD5,
+	0xE05C, 0x6FEC, 0xE05D, 0x6FD4, 0xE05E, 0x6FD8, 0xE05F, 0x6FF1,
+	0xE060, 0x6FEE, 0xE061, 0x6FDB, 0xE062, 0x7009, 0xE063, 0x700B,
+	0xE064, 0x6FFA, 0xE065, 0x7011, 0xE066, 0x7001, 0xE067, 0x700F,
+	0xE068, 0x6FFE, 0xE069, 0x701B, 0xE06A, 0x701A, 0xE06B, 0x6F74,
+	0xE06C, 0x701D, 0xE06D, 0x7018, 0xE06E, 0x701F, 0xE06F, 0x7030,
+	0xE070, 0x703E, 0xE071, 0x7032, 0xE072, 0x7051, 0xE073, 0x7063,
+	0xE074, 0x7099, 0xE075, 0x7092, 0xE076, 0x70AF, 0xE077, 0x70F1,
+	0xE078, 0x70AC, 0xE079, 0x70B8, 0xE07A, 0x70B3, 0xE07B, 0x70AE,
+	0xE07C, 0x70DF, 0xE07D, 0x70CB, 0xE07E, 0x70DD, 0xE080, 0x70D9,
+	0xE081, 0x7109, 0xE082, 0x70FD, 0xE083, 0x711C, 0xE084, 0x7119,
+	0xE085, 0x7165, 0xE086, 0x7155, 0xE087, 0x7188, 0xE088, 0x7166,
+	0xE089, 0x7162, 0xE08A, 0x714C, 0xE08B, 0x7156, 0xE08C, 0x716C,
+	0xE08D, 0x718F, 0xE08E, 0x71FB, 0xE08F, 0x7184, 0xE090, 0x7195,
+	0xE091, 0x71A8, 0xE092, 0x71AC, 0xE093, 0x71D7, 0xE094, 0x71B9,
+	0xE095, 0x71BE, 0xE096, 0x71D2, 0xE097, 0x71C9, 0xE098, 0x71D4,
+	0xE099, 0x71CE, 0xE09A, 0x71E0, 0xE09B, 0x71EC, 0xE09C, 0x71E7,
+	0xE09D, 0x71F5, 0xE09E, 0x71FC, 0xE09F, 0x71F9, 0xE0A0, 0x71FF,
+	0xE0A1, 0x720D, 0xE0A2, 0x7210, 0xE0A3, 0x721B, 0xE0A4, 0x7228,
+	0xE0A5, 0x722D, 0xE0A6, 0x722C, 0xE0A7, 0x7230, 0xE0A8, 0x7232,
+	0xE0A9, 0x723B, 0xE0AA, 0x723C, 0xE0AB, 0x723F, 0xE0AC, 0x7240,
+	0xE0AD, 0x7246, 0xE0AE, 0x724B, 0xE0AF, 0x7258, 0xE0B0, 0x7274,
+	0xE0B1, 0x727E, 0xE0B2, 0x7282, 0xE0B3, 0x7281, 0xE0B4, 0x7287,
+	0xE0B5, 0x7292, 0xE0B6, 0x7296, 0xE0B7, 0x72A2, 0xE0B8, 0x72A7,
+	0xE0B9, 0x72B9, 0xE0BA, 0x72B2, 0xE0BB, 0x72C3, 0xE0BC, 0x72C6,
+	0xE0BD, 0x72C4, 0xE0BE, 0x72CE, 0xE0BF, 0x72D2, 0xE0C0, 0x72E2,
+	0xE0C1, 0x72E0, 0xE0C2, 0x72E1, 0xE0C3, 0x72F9, 0xE0C4, 0x72F7,
+	0xE0C5, 0x500F, 0xE0C6, 0x7317, 0xE0C7, 0x730A, 0xE0C8, 0x731C,
+	0xE0C9, 0x7316, 0xE0CA, 0x731D, 0xE0CB, 0x7334, 0xE0CC, 0x732F,
+	0xE0CD, 0x7329, 0xE0CE, 0x7325, 0xE0CF, 0x733E, 0xE0D0, 0x734E,
+	0xE0D1, 0x734F, 0xE0D2, 0x9ED8, 0xE0D3, 0x7357, 0xE0D4, 0x736A,
+	0xE0D5, 0x7368, 0xE0D6, 0x7370, 0xE0D7, 0x7378, 0xE0D8, 0x7375,
+	0xE0D9, 0x737B, 0xE0DA, 0x737A, 0xE0DB, 0x73C8, 0xE0DC, 0x73B3,
+	0xE0DD, 0x73CE, 0xE0DE, 0x73BB, 0xE0DF, 0x73C0, 0xE0E0, 0x73E5,
+	0xE0E1, 0x73EE, 0xE0E2, 0x73DE, 0xE0E3, 0x74A2, 0xE0E4, 0x7405,
+	0xE0E5, 0x746F, 0xE0E6, 0x7425, 0xE0E7, 0x73F8, 0xE0E8, 0x7432,
+	0xE0E9, 0x743A, 0xE0EA, 0x7455, 0xE0EB, 0x743F, 0xE0EC, 0x745F,
+	0xE0ED, 0x7459, 0xE0EE, 0x7441, 0xE0EF, 0x745C, 0xE0F0, 0x7469,
+	0xE0F1, 0x7470, 0xE0F2, 0x7463, 0xE0F3, 0x746A, 0xE0F4, 0x7476,
+	0xE0F5, 0x747E, 0xE0F6, 0x748B, 0xE0F7, 0x749E, 0xE0F8, 0x74A7,
+	0xE0F9, 0x74CA, 0xE0FA, 0x74CF, 0xE0FB, 0x74D4, 0xE0FC, 0x73F1,
+	0xE140, 0x74E0, 0xE141, 0x74E3, 0xE142, 0x74E7, 0xE143, 0x74E9,
+	0xE144, 0x74EE, 0xE145, 0x74F2, 0xE146, 0x74F0, 0xE147, 0x74F1,
+	0xE148, 0x74F8, 0xE149, 0x74F7, 0xE14A, 0x7504, 0xE14B, 0x7503,
+	0xE14C, 0x7505, 0xE14D, 0x750C, 0xE14E, 0x750E, 0xE14F, 0x750D,
+	0xE150, 0x7515, 0xE151, 0x7513, 0xE152, 0x751E, 0xE153, 0x7526,
+	0xE154, 0x752C, 0xE155, 0x753C, 0xE156, 0x7544, 0xE157, 0x754D,
+	0xE158, 0x754A, 0xE159, 0x7549, 0xE15A, 0x755B, 0xE15B, 0x7546,
+	0xE15C, 0x755A, 0xE15D, 0x7569, 0xE15E, 0x7564, 0xE15F, 0x7567,
+	0xE160, 0x756B, 0xE161, 0x756D, 0xE162, 0x7578, 0xE163, 0x7576,
+	0xE164, 0x7586, 0xE165, 0x7587, 0xE166, 0x7574, 0xE167, 0x758A,
+	0xE168, 0x7589, 0xE169, 0x7582, 0xE16A, 0x7594, 0xE16B, 0x759A,
+	0xE16C, 0x759D, 0xE16D, 0x75A5, 0xE16E, 0x75A3, 0xE16F, 0x75C2,
+	0xE170, 0x75B3, 0xE171, 0x75C3, 0xE172, 0x75B5, 0xE173, 0x75BD,
+	0xE174, 0x75B8, 0xE175, 0x75BC, 0xE176, 0x75B1, 0xE177, 0x75CD,
+	0xE178, 0x75CA, 0xE179, 0x75D2, 0xE17A, 0x75D9, 0xE17B, 0x75E3,
+	0xE17C, 0x75DE, 0xE17D, 0x75FE, 0xE17E, 0x75FF, 0xE180, 0x75FC,
+	0xE181, 0x7601, 0xE182, 0x75F0, 0xE183, 0x75FA, 0xE184, 0x75F2,
+	0xE185, 0x75F3, 0xE186, 0x760B, 0xE187, 0x760D, 0xE188, 0x7609,
+	0xE189, 0x761F, 0xE18A, 0x7627, 0xE18B, 0x7620, 0xE18C, 0x7621,
+	0xE18D, 0x7622, 0xE18E, 0x7624, 0xE18F, 0x7634, 0xE190, 0x7630,
+	0xE191, 0x763B, 0xE192, 0x7647, 0xE193, 0x7648, 0xE194, 0x7646,
+	0xE195, 0x765C, 0xE196, 0x7658, 0xE197, 0x7661, 0xE198, 0x7662,
+	0xE199, 0x7668, 0xE19A, 0x7669, 0xE19B, 0x766A, 0xE19C, 0x7667,
+	0xE19D, 0x766C, 0xE19E, 0x7670, 0xE19F, 0x7672, 0xE1A0, 0x7676,
+	0xE1A1, 0x7678, 0xE1A2, 0x767C, 0xE1A3, 0x7680, 0xE1A4, 0x7683,
+	0xE1A5, 0x7688, 0xE1A6, 0x768B, 0xE1A7, 0x768E, 0xE1A8, 0x7696,
+	0xE1A9, 0x7693, 0xE1AA, 0x7699, 0xE1AB, 0x769A, 0xE1AC, 0x76B0,
+	0xE1AD, 0x76B4, 0xE1AE, 0x76B8, 0xE1AF, 0x76B9, 0xE1B0, 0x76BA,
+	0xE1B1, 0x76C2, 0xE1B2, 0x76CD, 0xE1B3, 0x76D6, 0xE1B4, 0x76D2,
+	0xE1B5, 0x76DE, 0xE1B6, 0x76E1, 0xE1B7, 0x76E5, 0xE1B8, 0x76E7,
+	0xE1B9, 0x76EA, 0xE1BA, 0x862F, 0xE1BB, 0x76FB, 0xE1BC, 0x7708,
+	0xE1BD, 0x7707, 0xE1BE, 0x7704, 0xE1BF, 0x7729, 0xE1C0, 0x7724,
+	0xE1C1, 0x771E, 0xE1C2, 0x7725, 0xE1C3, 0x7726, 0xE1C4, 0x771B,
+	0xE1C5, 0x7737, 0xE1C6, 0x7738, 0xE1C7, 0x7747, 0xE1C8, 0x775A,
+	0xE1C9, 0x7768, 0xE1CA, 0x776B, 0xE1CB, 0x775B, 0xE1CC, 0x7765,
+	0xE1CD, 0x777F, 0xE1CE, 0x777E, 0xE1CF, 0x7779, 0xE1D0, 0x778E,
+	0xE1D1, 0x778B, 0xE1D2, 0x7791, 0xE1D3, 0x77A0, 0xE1D4, 0x779E,
+	0xE1D5, 0x77B0, 0xE1D6, 0x77B6, 0xE1D7, 0x77B9, 0xE1D8, 0x77BF,
+	0xE1D9, 0x77BC, 0xE1DA, 0x77BD, 0xE1DB, 0x77BB, 0xE1DC, 0x77C7,
+	0xE1DD, 0x77CD, 0xE1DE, 0x77D7, 0xE1DF, 0x77DA, 0xE1E0, 0x77DC,
+	0xE1E1, 0x77E3, 0xE1E2, 0x77EE, 0xE1E3, 0x77FC, 0xE1E4, 0x780C,
+	0xE1E5, 0x7812, 0xE1E6, 0x7926, 0xE1E7, 0x7820, 0xE1E8, 0x792A,
+	0xE1E9, 0x7845, 0xE1EA, 0x788E, 0xE1EB, 0x7874, 0xE1EC, 0x7886,
+	0xE1ED, 0x787C, 0xE1EE, 0x789A, 0xE1EF, 0x788C, 0xE1F0, 0x78A3,
+	0xE1F1, 0x78B5, 0xE1F2, 0x78AA, 0xE1F3, 0x78AF, 0xE1F4, 0x78D1,
+	0xE1F5, 0x78C6, 0xE1F6, 0x78CB, 0xE1F7, 0x78D4, 0xE1F8, 0x78BE,
+	0xE1F9, 0x78BC, 0xE1FA, 0x78C5, 0xE1FB, 0x78CA, 0xE1FC, 0x78EC,
+	0xE240, 0x78E7, 0xE241, 0x78DA, 0xE242, 0x78FD, 0xE243, 0x78F4,
+	0xE244, 0x7907, 0xE245, 0x7912, 0xE246, 0x7911, 0xE247, 0x7919,
+	0xE248, 0x792C, 0xE249, 0x792B, 0xE24A, 0x7940, 0xE24B, 0x7960,
+	0xE24C, 0x7957, 0xE24D, 0x795F, 0xE24E, 0x795A, 0xE24F, 0x7955,
+	0xE250, 0x7953, 0xE251, 0x797A, 0xE252, 0x797F, 0xE253, 0x798A,
+	0xE254, 0x799D, 0xE255, 0x79A7, 0xE256, 0x9F4B, 0xE257, 0x79AA,
+	0xE258, 0x79AE, 0xE259, 0x79B3, 0xE25A, 0x79B9, 0xE25B, 0x79BA,
+	0xE25C, 0x79C9, 0xE25D, 0x79D5, 0xE25E, 0x79E7, 0xE25F, 0x79EC,
+	0xE260, 0x79E1, 0xE261, 0x79E3, 0xE262, 0x7A08, 0xE263, 0x7A0D,
+	0xE264, 0x7A18, 0xE265, 0x7A19, 0xE266, 0x7A20, 0xE267, 0x7A1F,
+	0xE268, 0x7980, 0xE269, 0x7A31, 0xE26A, 0x7A3B, 0xE26B, 0x7A3E,
+	0xE26C, 0x7A37, 0xE26D, 0x7A43, 0xE26E, 0x7A57, 0xE26F, 0x7A49,
+	0xE270, 0x7A61, 0xE271, 0x7A62, 0xE272, 0x7A69, 0xE273, 0x9F9D,
+	0xE274, 0x7A70, 0xE275, 0x7A79, 0xE276, 0x7A7D, 0xE277, 0x7A88,
+	0xE278, 0x7A97, 0xE279, 0x7A95, 0xE27A, 0x7A98, 0xE27B, 0x7A96,
+	0xE27C, 0x7AA9, 0xE27D, 0x7AC8, 0xE27E, 0x7AB0, 0xE280, 0x7AB6,
+	0xE281, 0x7AC5, 0xE282, 0x7AC4, 0xE283, 0x7ABF, 0xE284, 0x9083,
+	0xE285, 0x7AC7, 0xE286, 0x7ACA, 0xE287, 0x7ACD, 0xE288, 0x7ACF,
+	0xE289, 0x7AD5, 0xE28A, 0x7AD3, 0xE28B, 0x7AD9, 0xE28C, 0x7ADA,
+	0xE28D, 0x7ADD, 0xE28E, 0x7AE1, 0xE28F, 0x7AE2, 0xE290, 0x7AE6,
+	0xE291, 0x7AED, 0xE292, 0x7AF0, 0xE293, 0x7B02, 0xE294, 0x7B0F,
+	0xE295, 0x7B0A, 0xE296, 0x7B06, 0xE297, 0x7B33, 0xE298, 0x7B18,
+	0xE299, 0x7B19, 0xE29A, 0x7B1E, 0xE29B, 0x7B35, 0xE29C, 0x7B28,
+	0xE29D, 0x7B36, 0xE29E, 0x7B50, 0xE29F, 0x7B7A, 0xE2A0, 0x7B04,
+	0xE2A1, 0x7B4D, 0xE2A2, 0x7B0B, 0xE2A3, 0x7B4C, 0xE2A4, 0x7B45,
+	0xE2A5, 0x7B75, 0xE2A6, 0x7B65, 0xE2A7, 0x7B74, 0xE2A8, 0x7B67,
+	0xE2A9, 0x7B70, 0xE2AA, 0x7B71, 0xE2AB, 0x7B6C, 0xE2AC, 0x7B6E,
+	0xE2AD, 0x7B9D, 0xE2AE, 0x7B98, 0xE2AF, 0x7B9F, 0xE2B0, 0x7B8D,
+	0xE2B1, 0x7B9C, 0xE2B2, 0x7B9A, 0xE2B3, 0x7B8B, 0xE2B4, 0x7B92,
+	0xE2B5, 0x7B8F, 0xE2B6, 0x7B5D, 0xE2B7, 0x7B99, 0xE2B8, 0x7BCB,
+	0xE2B9, 0x7BC1, 0xE2BA, 0x7BCC, 0xE2BB, 0x7BCF, 0xE2BC, 0x7BB4,
+	0xE2BD, 0x7BC6, 0xE2BE, 0x7BDD, 0xE2BF, 0x7BE9, 0xE2C0, 0x7C11,
+	0xE2C1, 0x7C14, 0xE2C2, 0x7BE6, 0xE2C3, 0x7BE5, 0xE2C4, 0x7C60,
+	0xE2C5, 0x7C00, 0xE2C6, 0x7C07, 0xE2C7, 0x7C13, 0xE2C8, 0x7BF3,
+	0xE2C9, 0x7BF7, 0xE2CA, 0x7C17, 0xE2CB, 0x7C0D, 0xE2CC, 0x7BF6,
+	0xE2CD, 0x7C23, 0xE2CE, 0x7C27, 0xE2CF, 0x7C2A, 0xE2D0, 0x7C1F,
+	0xE2D1, 0x7C37, 0xE2D2, 0x7C2B, 0xE2D3, 0x7C3D, 0xE2D4, 0x7C4C,
+	0xE2D5, 0x7C43, 0xE2D6, 0x7C54, 0xE2D7, 0x7C4F, 0xE2D8, 0x7C40,
+	0xE2D9, 0x7C50, 0xE2DA, 0x7C58, 0xE2DB, 0x7C5F, 0xE2DC, 0x7C64,
+	0xE2DD, 0x7C56, 0xE2DE, 0x7C65, 0xE2DF, 0x7C6C, 0xE2E0, 0x7C75,
+	0xE2E1, 0x7C83, 0xE2E2, 0x7C90, 0xE2E3, 0x7CA4, 0xE2E4, 0x7CAD,
+	0xE2E5, 0x7CA2, 0xE2E6, 0x7CAB, 0xE2E7, 0x7CA1, 0xE2E8, 0x7CA8,
+	0xE2E9, 0x7CB3, 0xE2EA, 0x7CB2, 0xE2EB, 0x7CB1, 0xE2EC, 0x7CAE,
+	0xE2ED, 0x7CB9, 0xE2EE, 0x7CBD, 0xE2EF, 0x7CC0, 0xE2F0, 0x7CC5,
+	0xE2F1, 0x7CC2, 0xE2F2, 0x7CD8, 0xE2F3, 0x7CD2, 0xE2F4, 0x7CDC,
+	0xE2F5, 0x7CE2, 0xE2F6, 0x9B3B, 0xE2F7, 0x7CEF, 0xE2F8, 0x7CF2,
+	0xE2F9, 0x7CF4, 0xE2FA, 0x7CF6, 0xE2FB, 0x7CFA, 0xE2FC, 0x7D06,
+	0xE340, 0x7D02, 0xE341, 0x7D1C, 0xE342, 0x7D15, 0xE343, 0x7D0A,
+	0xE344, 0x7D45, 0xE345, 0x7D4B, 0xE346, 0x7D2E, 0xE347, 0x7D32,
+	0xE348, 0x7D3F, 0xE349, 0x7D35, 0xE34A, 0x7D46, 0xE34B, 0x7D73,
+	0xE34C, 0x7D56, 0xE34D, 0x7D4E, 0xE34E, 0x7D72, 0xE34F, 0x7D68,
+	0xE350, 0x7D6E, 0xE351, 0x7D4F, 0xE352, 0x7D63, 0xE353, 0x7D93,
+	0xE354, 0x7D89, 0xE355, 0x7D5B, 0xE356, 0x7D8F, 0xE357, 0x7D7D,
+	0xE358, 0x7D9B, 0xE359, 0x7DBA, 0xE35A, 0x7DAE, 0xE35B, 0x7DA3,
+	0xE35C, 0x7DB5, 0xE35D, 0x7DC7, 0xE35E, 0x7DBD, 0xE35F, 0x7DAB,
+	0xE360, 0x7E3D, 0xE361, 0x7DA2, 0xE362, 0x7DAF, 0xE363, 0x7DDC,
+	0xE364, 0x7DB8, 0xE365, 0x7D9F, 0xE366, 0x7DB0, 0xE367, 0x7DD8,
+	0xE368, 0x7DDD, 0xE369, 0x7DE4, 0xE36A, 0x7DDE, 0xE36B, 0x7DFB,
+	0xE36C, 0x7DF2, 0xE36D, 0x7DE1, 0xE36E, 0x7E05, 0xE36F, 0x7E0A,
+	0xE370, 0x7E23, 0xE371, 0x7E21, 0xE372, 0x7E12, 0xE373, 0x7E31,
+	0xE374, 0x7E1F, 0xE375, 0x7E09, 0xE376, 0x7E0B, 0xE377, 0x7E22,
+	0xE378, 0x7E46, 0xE379, 0x7E66, 0xE37A, 0x7E3B, 0xE37B, 0x7E35,
+	0xE37C, 0x7E39, 0xE37D, 0x7E43, 0xE37E, 0x7E37, 0xE380, 0x7E32,
+	0xE381, 0x7E3A, 0xE382, 0x7E67, 0xE383, 0x7E5D, 0xE384, 0x7E56,
+	0xE385, 0x7E5E, 0xE386, 0x7E59, 0xE387, 0x7E5A, 0xE388, 0x7E79,
+	0xE389, 0x7E6A, 0xE38A, 0x7E69, 0xE38B, 0x7E7C, 0xE38C, 0x7E7B,
+	0xE38D, 0x7E83, 0xE38E, 0x7DD5, 0xE38F, 0x7E7D, 0xE390, 0x8FAE,
+	0xE391, 0x7E7F, 0xE392, 0x7E88, 0xE393, 0x7E89, 0xE394, 0x7E8C,
+	0xE395, 0x7E92, 0xE396, 0x7E90, 0xE397, 0x7E93, 0xE398, 0x7E94,
+	0xE399, 0x7E96, 0xE39A, 0x7E8E, 0xE39B, 0x7E9B, 0xE39C, 0x7E9C,
+	0xE39D, 0x7F38, 0xE39E, 0x7F3A, 0xE39F, 0x7F45, 0xE3A0, 0x7F4C,
+	0xE3A1, 0x7F4D, 0xE3A2, 0x7F4E, 0xE3A3, 0x7F50, 0xE3A4, 0x7F51,
+	0xE3A5, 0x7F55, 0xE3A6, 0x7F54, 0xE3A7, 0x7F58, 0xE3A8, 0x7F5F,
+	0xE3A9, 0x7F60, 0xE3AA, 0x7F68, 0xE3AB, 0x7F69, 0xE3AC, 0x7F67,
+	0xE3AD, 0x7F78, 0xE3AE, 0x7F82, 0xE3AF, 0x7F86, 0xE3B0, 0x7F83,
+	0xE3B1, 0x7F88, 0xE3B2, 0x7F87, 0xE3B3, 0x7F8C, 0xE3B4, 0x7F94,
+	0xE3B5, 0x7F9E, 0xE3B6, 0x7F9D, 0xE3B7, 0x7F9A, 0xE3B8, 0x7FA3,
+	0xE3B9, 0x7FAF, 0xE3BA, 0x7FB2, 0xE3BB, 0x7FB9, 0xE3BC, 0x7FAE,
+	0xE3BD, 0x7FB6, 0xE3BE, 0x7FB8, 0xE3BF, 0x8B71, 0xE3C0, 0x7FC5,
+	0xE3C1, 0x7FC6, 0xE3C2, 0x7FCA, 0xE3C3, 0x7FD5, 0xE3C4, 0x7FD4,
+	0xE3C5, 0x7FE1, 0xE3C6, 0x7FE6, 0xE3C7, 0x7FE9, 0xE3C8, 0x7FF3,
+	0xE3C9, 0x7FF9, 0xE3CA, 0x98DC, 0xE3CB, 0x8006, 0xE3CC, 0x8004,
+	0xE3CD, 0x800B, 0xE3CE, 0x8012, 0xE3CF, 0x8018, 0xE3D0, 0x8019,
+	0xE3D1, 0x801C, 0xE3D2, 0x8021, 0xE3D3, 0x8028, 0xE3D4, 0x803F,
+	0xE3D5, 0x803B, 0xE3D6, 0x804A, 0xE3D7, 0x8046, 0xE3D8, 0x8052,
+	0xE3D9, 0x8058, 0xE3DA, 0x805A, 0xE3DB, 0x805F, 0xE3DC, 0x8062,
+	0xE3DD, 0x8068, 0xE3DE, 0x8073, 0xE3DF, 0x8072, 0xE3E0, 0x8070,
+	0xE3E1, 0x8076, 0xE3E2, 0x8079, 0xE3E3, 0x807D, 0xE3E4, 0x807F,
+	0xE3E5, 0x8084, 0xE3E6, 0x8086, 0xE3E7, 0x8085, 0xE3E8, 0x809B,
+	0xE3E9, 0x8093, 0xE3EA, 0x809A, 0xE3EB, 0x80AD, 0xE3EC, 0x5190,
+	0xE3ED, 0x80AC, 0xE3EE, 0x80DB, 0xE3EF, 0x80E5, 0xE3F0, 0x80D9,
+	0xE3F1, 0x80DD, 0xE3F2, 0x80C4, 0xE3F3, 0x80DA, 0xE3F4, 0x80D6,
+	0xE3F5, 0x8109, 0xE3F6, 0x80EF, 0xE3F7, 0x80F1, 0xE3F8, 0x811B,
+	0xE3F9, 0x8129, 0xE3FA, 0x8123, 0xE3FB, 0x812F, 0xE3FC, 0x814B,
+	0xE440, 0x968B, 0xE441, 0x8146, 0xE442, 0x813E, 0xE443, 0x8153,
+	0xE444, 0x8151, 0xE445, 0x80FC, 0xE446, 0x8171, 0xE447, 0x816E,
+	0xE448, 0x8165, 0xE449, 0x8166, 0xE44A, 0x8174, 0xE44B, 0x8183,
+	0xE44C, 0x8188, 0xE44D, 0x818A, 0xE44E, 0x8180, 0xE44F, 0x8182,
+	0xE450, 0x81A0, 0xE451, 0x8195, 0xE452, 0x81A4, 0xE453, 0x81A3,
+	0xE454, 0x815F, 0xE455, 0x8193, 0xE456, 0x81A9, 0xE457, 0x81B0,
+	0xE458, 0x81B5, 0xE459, 0x81BE, 0xE45A, 0x81B8, 0xE45B, 0x81BD,
+	0xE45C, 0x81C0, 0xE45D, 0x81C2, 0xE45E, 0x81BA, 0xE45F, 0x81C9,
+	0xE460, 0x81CD, 0xE461, 0x81D1, 0xE462, 0x81D9, 0xE463, 0x81D8,
+	0xE464, 0x81C8, 0xE465, 0x81DA, 0xE466, 0x81DF, 0xE467, 0x81E0,
+	0xE468, 0x81E7, 0xE469, 0x81FA, 0xE46A, 0x81FB, 0xE46B, 0x81FE,
+	0xE46C, 0x8201, 0xE46D, 0x8202, 0xE46E, 0x8205, 0xE46F, 0x8207,
+	0xE470, 0x820A, 0xE471, 0x820D, 0xE472, 0x8210, 0xE473, 0x8216,
+	0xE474, 0x8229, 0xE475, 0x822B, 0xE476, 0x8238, 0xE477, 0x8233,
+	0xE478, 0x8240, 0xE479, 0x8259, 0xE47A, 0x8258, 0xE47B, 0x825D,
+	0xE47C, 0x825A, 0xE47D, 0x825F, 0xE47E, 0x8264, 0xE480, 0x8262,
+	0xE481, 0x8268, 0xE482, 0x826A, 0xE483, 0x826B, 0xE484, 0x822E,
+	0xE485, 0x8271, 0xE486, 0x8277, 0xE487, 0x8278, 0xE488, 0x827E,
+	0xE489, 0x828D, 0xE48A, 0x8292, 0xE48B, 0x82AB, 0xE48C, 0x829F,
+	0xE48D, 0x82BB, 0xE48E, 0x82AC, 0xE48F, 0x82E1, 0xE490, 0x82E3,
+	0xE491, 0x82DF, 0xE492, 0x82D2, 0xE493, 0x82F4, 0xE494, 0x82F3,
+	0xE495, 0x82FA, 0xE496, 0x8393, 0xE497, 0x8303, 0xE498, 0x82FB,
+	0xE499, 0x82F9, 0xE49A, 0x82DE, 0xE49B, 0x8306, 0xE49C, 0x82DC,
+	0xE49D, 0x8309, 0xE49E, 0x82D9, 0xE49F, 0x8335, 0xE4A0, 0x8334,
+	0xE4A1, 0x8316, 0xE4A2, 0x8332, 0xE4A3, 0x8331, 0xE4A4, 0x8340,
+	0xE4A5, 0x8339, 0xE4A6, 0x8350, 0xE4A7, 0x8345, 0xE4A8, 0x832F,
+	0xE4A9, 0x832B, 0xE4AA, 0x8317, 0xE4AB, 0x8318, 0xE4AC, 0x8385,
+	0xE4AD, 0x839A, 0xE4AE, 0x83AA, 0xE4AF, 0x839F, 0xE4B0, 0x83A2,
+	0xE4B1, 0x8396, 0xE4B2, 0x8323, 0xE4B3, 0x838E, 0xE4B4, 0x8387,
+	0xE4B5, 0x838A, 0xE4B6, 0x837C, 0xE4B7, 0x83B5, 0xE4B8, 0x8373,
+	0xE4B9, 0x8375, 0xE4BA, 0x83A0, 0xE4BB, 0x8389, 0xE4BC, 0x83A8,
+	0xE4BD, 0x83F4, 0xE4BE, 0x8413, 0xE4BF, 0x83EB, 0xE4C0, 0x83CE,
+	0xE4C1, 0x83FD, 0xE4C2, 0x8403, 0xE4C3, 0x83D8, 0xE4C4, 0x840B,
+	0xE4C5, 0x83C1, 0xE4C6, 0x83F7, 0xE4C7, 0x8407, 0xE4C8, 0x83E0,
+	0xE4C9, 0x83F2, 0xE4CA, 0x840D, 0xE4CB, 0x8422, 0xE4CC, 0x8420,
+	0xE4CD, 0x83BD, 0xE4CE, 0x8438, 0xE4CF, 0x8506, 0xE4D0, 0x83FB,
+	0xE4D1, 0x846D, 0xE4D2, 0x842A, 0xE4D3, 0x843C, 0xE4D4, 0x855A,
+	0xE4D5, 0x8484, 0xE4D6, 0x8477, 0xE4D7, 0x846B, 0xE4D8, 0x84AD,
+	0xE4D9, 0x846E, 0xE4DA, 0x8482, 0xE4DB, 0x8469, 0xE4DC, 0x8446,
+	0xE4DD, 0x842C, 0xE4DE, 0x846F, 0xE4DF, 0x8479, 0xE4E0, 0x8435,
+	0xE4E1, 0x84CA, 0xE4E2, 0x8462, 0xE4E3, 0x84B9, 0xE4E4, 0x84BF,
+	0xE4E5, 0x849F, 0xE4E6, 0x84D9, 0xE4E7, 0x84CD, 0xE4E8, 0x84BB,
+	0xE4E9, 0x84DA, 0xE4EA, 0x84D0, 0xE4EB, 0x84C1, 0xE4EC, 0x84C6,
+	0xE4ED, 0x84D6, 0xE4EE, 0x84A1, 0xE4EF, 0x8521, 0xE4F0, 0x84FF,
+	0xE4F1, 0x84F4, 0xE4F2, 0x8517, 0xE4F3, 0x8518, 0xE4F4, 0x852C,
+	0xE4F5, 0x851F, 0xE4F6, 0x8515, 0xE4F7, 0x8514, 0xE4F8, 0x84FC,
+	0xE4F9, 0x8540, 0xE4FA, 0x8563, 0xE4FB, 0x8558, 0xE4FC, 0x8548,
+	0xE540, 0x8541, 0xE541, 0x8602, 0xE542, 0x854B, 0xE543, 0x8555,
+	0xE544, 0x8580, 0xE545, 0x85A4, 0xE546, 0x8588, 0xE547, 0x8591,
+	0xE548, 0x858A, 0xE549, 0x85A8, 0xE54A, 0x856D, 0xE54B, 0x8594,
+	0xE54C, 0x859B, 0xE54D, 0x85EA, 0xE54E, 0x8587, 0xE54F, 0x859C,
+	0xE550, 0x8577, 0xE551, 0x857E, 0xE552, 0x8590, 0xE553, 0x85C9,
+	0xE554, 0x85BA, 0xE555, 0x85CF, 0xE556, 0x85B9, 0xE557, 0x85D0,
+	0xE558, 0x85D5, 0xE559, 0x85DD, 0xE55A, 0x85E5, 0xE55B, 0x85DC,
+	0xE55C, 0x85F9, 0xE55D, 0x860A, 0xE55E, 0x8613, 0xE55F, 0x860B,
+	0xE560, 0x85FE, 0xE561, 0x85FA, 0xE562, 0x8606, 0xE563, 0x8622,
+	0xE564, 0x861A, 0xE565, 0x8630, 0xE566, 0x863F, 0xE567, 0x864D,
+	0xE568, 0x4E55, 0xE569, 0x8654, 0xE56A, 0x865F, 0xE56B, 0x8667,
+	0xE56C, 0x8671, 0xE56D, 0x8693, 0xE56E, 0x86A3, 0xE56F, 0x86A9,
+	0xE570, 0x86AA, 0xE571, 0x868B, 0xE572, 0x868C, 0xE573, 0x86B6,
+	0xE574, 0x86AF, 0xE575, 0x86C4, 0xE576, 0x86C6, 0xE577, 0x86B0,
+	0xE578, 0x86C9, 0xE579, 0x8823, 0xE57A, 0x86AB, 0xE57B, 0x86D4,
+	0xE57C, 0x86DE, 0xE57D, 0x86E9, 0xE57E, 0x86EC, 0xE580, 0x86DF,
+	0xE581, 0x86DB, 0xE582, 0x86EF, 0xE583, 0x8712, 0xE584, 0x8706,
+	0xE585, 0x8708, 0xE586, 0x8700, 0xE587, 0x8703, 0xE588, 0x86FB,
+	0xE589, 0x8711, 0xE58A, 0x8709, 0xE58B, 0x870D, 0xE58C, 0x86F9,
+	0xE58D, 0x870A, 0xE58E, 0x8734, 0xE58F, 0x873F, 0xE590, 0x8737,
+	0xE591, 0x873B, 0xE592, 0x8725, 0xE593, 0x8729, 0xE594, 0x871A,
+	0xE595, 0x8760, 0xE596, 0x875F, 0xE597, 0x8778, 0xE598, 0x874C,
+	0xE599, 0x874E, 0xE59A, 0x8774, 0xE59B, 0x8757, 0xE59C, 0x8768,
+	0xE59D, 0x876E, 0xE59E, 0x8759, 0xE59F, 0x8753, 0xE5A0, 0x8763,
+	0xE5A1, 0x876A, 0xE5A2, 0x8805, 0xE5A3, 0x87A2, 0xE5A4, 0x879F,
+	0xE5A5, 0x8782, 0xE5A6, 0x87AF, 0xE5A7, 0x87CB, 0xE5A8, 0x87BD,
+	0xE5A9, 0x87C0, 0xE5AA, 0x87D0, 0xE5AB, 0x96D6, 0xE5AC, 0x87AB,
+	0xE5AD, 0x87C4, 0xE5AE, 0x87B3, 0xE5AF, 0x87C7, 0xE5B0, 0x87C6,
+	0xE5B1, 0x87BB, 0xE5B2, 0x87EF, 0xE5B3, 0x87F2, 0xE5B4, 0x87E0,
+	0xE5B5, 0x880F, 0xE5B6, 0x880D, 0xE5B7, 0x87FE, 0xE5B8, 0x87F6,
+	0xE5B9, 0x87F7, 0xE5BA, 0x880E, 0xE5BB, 0x87D2, 0xE5BC, 0x8811,
+	0xE5BD, 0x8816, 0xE5BE, 0x8815, 0xE5BF, 0x8822, 0xE5C0, 0x8821,
+	0xE5C1, 0x8831, 0xE5C2, 0x8836, 0xE5C3, 0x8839, 0xE5C4, 0x8827,
+	0xE5C5, 0x883B, 0xE5C6, 0x8844, 0xE5C7, 0x8842, 0xE5C8, 0x8852,
+	0xE5C9, 0x8859, 0xE5CA, 0x885E, 0xE5CB, 0x8862, 0xE5CC, 0x886B,
+	0xE5CD, 0x8881, 0xE5CE, 0x887E, 0xE5CF, 0x889E, 0xE5D0, 0x8875,
+	0xE5D1, 0x887D, 0xE5D2, 0x88B5, 0xE5D3, 0x8872, 0xE5D4, 0x8882,
+	0xE5D5, 0x8897, 0xE5D6, 0x8892, 0xE5D7, 0x88AE, 0xE5D8, 0x8899,
+	0xE5D9, 0x88A2, 0xE5DA, 0x888D, 0xE5DB, 0x88A4, 0xE5DC, 0x88B0,
+	0xE5DD, 0x88BF, 0xE5DE, 0x88B1, 0xE5DF, 0x88C3, 0xE5E0, 0x88C4,
+	0xE5E1, 0x88D4, 0xE5E2, 0x88D8, 0xE5E3, 0x88D9, 0xE5E4, 0x88DD,
+	0xE5E5, 0x88F9, 0xE5E6, 0x8902, 0xE5E7, 0x88FC, 0xE5E8, 0x88F4,
+	0xE5E9, 0x88E8, 0xE5EA, 0x88F2, 0xE5EB, 0x8904, 0xE5EC, 0x890C,
+	0xE5ED, 0x890A, 0xE5EE, 0x8913, 0xE5EF, 0x8943, 0xE5F0, 0x891E,
+	0xE5F1, 0x8925, 0xE5F2, 0x892A, 0xE5F3, 0x892B, 0xE5F4, 0x8941,
+	0xE5F5, 0x8944, 0xE5F6, 0x893B, 0xE5F7, 0x8936, 0xE5F8, 0x8938,
+	0xE5F9, 0x894C, 0xE5FA, 0x891D, 0xE5FB, 0x8960, 0xE5FC, 0x895E,
+	0xE640, 0x8966, 0xE641, 0x8964, 0xE642, 0x896D, 0xE643, 0x896A,
+	0xE644, 0x896F, 0xE645, 0x8974, 0xE646, 0x8977, 0xE647, 0x897E,
+	0xE648, 0x8983, 0xE649, 0x8988, 0xE64A, 0x898A, 0xE64B, 0x8993,
+	0xE64C, 0x8998, 0xE64D, 0x89A1, 0xE64E, 0x89A9, 0xE64F, 0x89A6,
+	0xE650, 0x89AC, 0xE651, 0x89AF, 0xE652, 0x89B2, 0xE653, 0x89BA,
+	0xE654, 0x89BD, 0xE655, 0x89BF, 0xE656, 0x89C0, 0xE657, 0x89DA,
+	0xE658, 0x89DC, 0xE659, 0x89DD, 0xE65A, 0x89E7, 0xE65B, 0x89F4,
+	0xE65C, 0x89F8, 0xE65D, 0x8A03, 0xE65E, 0x8A16, 0xE65F, 0x8A10,
+	0xE660, 0x8A0C, 0xE661, 0x8A1B, 0xE662, 0x8A1D, 0xE663, 0x8A25,
+	0xE664, 0x8A36, 0xE665, 0x8A41, 0xE666, 0x8A5B, 0xE667, 0x8A52,
+	0xE668, 0x8A46, 0xE669, 0x8A48, 0xE66A, 0x8A7C, 0xE66B, 0x8A6D,
+	0xE66C, 0x8A6C, 0xE66D, 0x8A62, 0xE66E, 0x8A85, 0xE66F, 0x8A82,
+	0xE670, 0x8A84, 0xE671, 0x8AA8, 0xE672, 0x8AA1, 0xE673, 0x8A91,
+	0xE674, 0x8AA5, 0xE675, 0x8AA6, 0xE676, 0x8A9A, 0xE677, 0x8AA3,
+	0xE678, 0x8AC4, 0xE679, 0x8ACD, 0xE67A, 0x8AC2, 0xE67B, 0x8ADA,
+	0xE67C, 0x8AEB, 0xE67D, 0x8AF3, 0xE67E, 0x8AE7, 0xE680, 0x8AE4,
+	0xE681, 0x8AF1, 0xE682, 0x8B14, 0xE683, 0x8AE0, 0xE684, 0x8AE2,
+	0xE685, 0x8AF7, 0xE686, 0x8ADE, 0xE687, 0x8ADB, 0xE688, 0x8B0C,
+	0xE689, 0x8B07, 0xE68A, 0x8B1A, 0xE68B, 0x8AE1, 0xE68C, 0x8B16,
+	0xE68D, 0x8B10, 0xE68E, 0x8B17, 0xE68F, 0x8B20, 0xE690, 0x8B33,
+	0xE691, 0x97AB, 0xE692, 0x8B26, 0xE693, 0x8B2B, 0xE694, 0x8B3E,
+	0xE695, 0x8B28, 0xE696, 0x8B41, 0xE697, 0x8B4C, 0xE698, 0x8B4F,
+	0xE699, 0x8B4E, 0xE69A, 0x8B49, 0xE69B, 0x8B56, 0xE69C, 0x8B5B,
+	0xE69D, 0x8B5A, 0xE69E, 0x8B6B, 0xE69F, 0x8B5F, 0xE6A0, 0x8B6C,
+	0xE6A1, 0x8B6F, 0xE6A2, 0x8B74, 0xE6A3, 0x8B7D, 0xE6A4, 0x8B80,
+	0xE6A5, 0x8B8C, 0xE6A6, 0x8B8E, 0xE6A7, 0x8B92, 0xE6A8, 0x8B93,
+	0xE6A9, 0x8B96, 0xE6AA, 0x8B99, 0xE6AB, 0x8B9A, 0xE6AC, 0x8C3A,
+	0xE6AD, 0x8C41, 0xE6AE, 0x8C3F, 0xE6AF, 0x8C48, 0xE6B0, 0x8C4C,
+	0xE6B1, 0x8C4E, 0xE6B2, 0x8C50, 0xE6B3, 0x8C55, 0xE6B4, 0x8C62,
+	0xE6B5, 0x8C6C, 0xE6B6, 0x8C78, 0xE6B7, 0x8C7A, 0xE6B8, 0x8C82,
+	0xE6B9, 0x8C89, 0xE6BA, 0x8C85, 0xE6BB, 0x8C8A, 0xE6BC, 0x8C8D,
+	0xE6BD, 0x8C8E, 0xE6BE, 0x8C94, 0xE6BF, 0x8C7C, 0xE6C0, 0x8C98,
+	0xE6C1, 0x621D, 0xE6C2, 0x8CAD, 0xE6C3, 0x8CAA, 0xE6C4, 0x8CBD,
+	0xE6C5, 0x8CB2, 0xE6C6, 0x8CB3, 0xE6C7, 0x8CAE, 0xE6C8, 0x8CB6,
+	0xE6C9, 0x8CC8, 0xE6CA, 0x8CC1, 0xE6CB, 0x8CE4, 0xE6CC, 0x8CE3,
+	0xE6CD, 0x8CDA, 0xE6CE, 0x8CFD, 0xE6CF, 0x8CFA, 0xE6D0, 0x8CFB,
+	0xE6D1, 0x8D04, 0xE6D2, 0x8D05, 0xE6D3, 0x8D0A, 0xE6D4, 0x8D07,
+	0xE6D5, 0x8D0F, 0xE6D6, 0x8D0D, 0xE6D7, 0x8D10, 0xE6D8, 0x9F4E,
+	0xE6D9, 0x8D13, 0xE6DA, 0x8CCD, 0xE6DB, 0x8D14, 0xE6DC, 0x8D16,
+	0xE6DD, 0x8D67, 0xE6DE, 0x8D6D, 0xE6DF, 0x8D71, 0xE6E0, 0x8D73,
+	0xE6E1, 0x8D81, 0xE6E2, 0x8D99, 0xE6E3, 0x8DC2, 0xE6E4, 0x8DBE,
+	0xE6E5, 0x8DBA, 0xE6E6, 0x8DCF, 0xE6E7, 0x8DDA, 0xE6E8, 0x8DD6,
+	0xE6E9, 0x8DCC, 0xE6EA, 0x8DDB, 0xE6EB, 0x8DCB, 0xE6EC, 0x8DEA,
+	0xE6ED, 0x8DEB, 0xE6EE, 0x8DDF, 0xE6EF, 0x8DE3, 0xE6F0, 0x8DFC,
+	0xE6F1, 0x8E08, 0xE6F2, 0x8E09, 0xE6F3, 0x8DFF, 0xE6F4, 0x8E1D,
+	0xE6F5, 0x8E1E, 0xE6F6, 0x8E10, 0xE6F7, 0x8E1F, 0xE6F8, 0x8E42,
+	0xE6F9, 0x8E35, 0xE6FA, 0x8E30, 0xE6FB, 0x8E34, 0xE6FC, 0x8E4A,
+	0xE740, 0x8E47, 0xE741, 0x8E49, 0xE742, 0x8E4C, 0xE743, 0x8E50,
+	0xE744, 0x8E48, 0xE745, 0x8E59, 0xE746, 0x8E64, 0xE747, 0x8E60,
+	0xE748, 0x8E2A, 0xE749, 0x8E63, 0xE74A, 0x8E55, 0xE74B, 0x8E76,
+	0xE74C, 0x8E72, 0xE74D, 0x8E7C, 0xE74E, 0x8E81, 0xE74F, 0x8E87,
+	0xE750, 0x8E85, 0xE751, 0x8E84, 0xE752, 0x8E8B, 0xE753, 0x8E8A,
+	0xE754, 0x8E93, 0xE755, 0x8E91, 0xE756, 0x8E94, 0xE757, 0x8E99,
+	0xE758, 0x8EAA, 0xE759, 0x8EA1, 0xE75A, 0x8EAC, 0xE75B, 0x8EB0,
+	0xE75C, 0x8EC6, 0xE75D, 0x8EB1, 0xE75E, 0x8EBE, 0xE75F, 0x8EC5,
+	0xE760, 0x8EC8, 0xE761, 0x8ECB, 0xE762, 0x8EDB, 0xE763, 0x8EE3,
+	0xE764, 0x8EFC, 0xE765, 0x8EFB, 0xE766, 0x8EEB, 0xE767, 0x8EFE,
+	0xE768, 0x8F0A, 0xE769, 0x8F05, 0xE76A, 0x8F15, 0xE76B, 0x8F12,
+	0xE76C, 0x8F19, 0xE76D, 0x8F13, 0xE76E, 0x8F1C, 0xE76F, 0x8F1F,
+	0xE770, 0x8F1B, 0xE771, 0x8F0C, 0xE772, 0x8F26, 0xE773, 0x8F33,
+	0xE774, 0x8F3B, 0xE775, 0x8F39, 0xE776, 0x8F45, 0xE777, 0x8F42,
+	0xE778, 0x8F3E, 0xE779, 0x8F4C, 0xE77A, 0x8F49, 0xE77B, 0x8F46,
+	0xE77C, 0x8F4E, 0xE77D, 0x8F57, 0xE77E, 0x8F5C, 0xE780, 0x8F62,
+	0xE781, 0x8F63, 0xE782, 0x8F64, 0xE783, 0x8F9C, 0xE784, 0x8F9F,
+	0xE785, 0x8FA3, 0xE786, 0x8FAD, 0xE787, 0x8FAF, 0xE788, 0x8FB7,
+	0xE789, 0x8FDA, 0xE78A, 0x8FE5, 0xE78B, 0x8FE2, 0xE78C, 0x8FEA,
+	0xE78D, 0x8FEF, 0xE78E, 0x9087, 0xE78F, 0x8FF4, 0xE790, 0x9005,
+	0xE791, 0x8FF9, 0xE792, 0x8FFA, 0xE793, 0x9011, 0xE794, 0x9015,
+	0xE795, 0x9021, 0xE796, 0x900D, 0xE797, 0x901E, 0xE798, 0x9016,
+	0xE799, 0x900B, 0xE79A, 0x9027, 0xE79B, 0x9036, 0xE79C, 0x9035,
+	0xE79D, 0x9039, 0xE79E, 0x8FF8, 0xE79F, 0x904F, 0xE7A0, 0x9050,
+	0xE7A1, 0x9051, 0xE7A2, 0x9052, 0xE7A3, 0x900E, 0xE7A4, 0x9049,
+	0xE7A5, 0x903E, 0xE7A6, 0x9056, 0xE7A7, 0x9058, 0xE7A8, 0x905E,
+	0xE7A9, 0x9068, 0xE7AA, 0x906F, 0xE7AB, 0x9076, 0xE7AC, 0x96A8,
+	0xE7AD, 0x9072, 0xE7AE, 0x9082, 0xE7AF, 0x907D, 0xE7B0, 0x9081,
+	0xE7B1, 0x9080, 0xE7B2, 0x908A, 0xE7B3, 0x9089, 0xE7B4, 0x908F,
+	0xE7B5, 0x90A8, 0xE7B6, 0x90AF, 0xE7B7, 0x90B1, 0xE7B8, 0x90B5,
+	0xE7B9, 0x90E2, 0xE7BA, 0x90E4, 0xE7BB, 0x6248, 0xE7BC, 0x90DB,
+	0xE7BD, 0x9102, 0xE7BE, 0x9112, 0xE7BF, 0x9119, 0xE7C0, 0x9132,
+	0xE7C1, 0x9130, 0xE7C2, 0x914A, 0xE7C3, 0x9156, 0xE7C4, 0x9158,
+	0xE7C5, 0x9163, 0xE7C6, 0x9165, 0xE7C7, 0x9169, 0xE7C8, 0x9173,
+	0xE7C9, 0x9172, 0xE7CA, 0x918B, 0xE7CB, 0x9189, 0xE7CC, 0x9182,
+	0xE7CD, 0x91A2, 0xE7CE, 0x91AB, 0xE7CF, 0x91AF, 0xE7D0, 0x91AA,
+	0xE7D1, 0x91B5, 0xE7D2, 0x91B4, 0xE7D3, 0x91BA, 0xE7D4, 0x91C0,
+	0xE7D5, 0x91C1, 0xE7D6, 0x91C9, 0xE7D7, 0x91CB, 0xE7D8, 0x91D0,
+	0xE7D9, 0x91D6, 0xE7DA, 0x91DF, 0xE7DB, 0x91E1, 0xE7DC, 0x91DB,
+	0xE7DD, 0x91FC, 0xE7DE, 0x91F5, 0xE7DF, 0x91F6, 0xE7E0, 0x921E,
+	0xE7E1, 0x91FF, 0xE7E2, 0x9214, 0xE7E3, 0x922C, 0xE7E4, 0x9215,
+	0xE7E5, 0x9211, 0xE7E6, 0x925E, 0xE7E7, 0x9257, 0xE7E8, 0x9245,
+	0xE7E9, 0x9249, 0xE7EA, 0x9264, 0xE7EB, 0x9248, 0xE7EC, 0x9295,
+	0xE7ED, 0x923F, 0xE7EE, 0x924B, 0xE7EF, 0x9250, 0xE7F0, 0x929C,
+	0xE7F1, 0x9296, 0xE7F2, 0x9293, 0xE7F3, 0x929B, 0xE7F4, 0x925A,
+	0xE7F5, 0x92CF, 0xE7F6, 0x92B9, 0xE7F7, 0x92B7, 0xE7F8, 0x92E9,
+	0xE7F9, 0x930F, 0xE7FA, 0x92FA, 0xE7FB, 0x9344, 0xE7FC, 0x932E,
+	0xE840, 0x9319, 0xE841, 0x9322, 0xE842, 0x931A, 0xE843, 0x9323,
+	0xE844, 0x933A, 0xE845, 0x9335, 0xE846, 0x933B, 0xE847, 0x935C,
+	0xE848, 0x9360, 0xE849, 0x937C, 0xE84A, 0x936E, 0xE84B, 0x9356,
+	0xE84C, 0x93B0, 0xE84D, 0x93AC, 0xE84E, 0x93AD, 0xE84F, 0x9394,
+	0xE850, 0x93B9, 0xE851, 0x93D6, 0xE852, 0x93D7, 0xE853, 0x93E8,
+	0xE854, 0x93E5, 0xE855, 0x93D8, 0xE856, 0x93C3, 0xE857, 0x93DD,
+	0xE858, 0x93D0, 0xE859, 0x93C8, 0xE85A, 0x93E4, 0xE85B, 0x941A,
+	0xE85C, 0x9414, 0xE85D, 0x9413, 0xE85E, 0x9403, 0xE85F, 0x9407,
+	0xE860, 0x9410, 0xE861, 0x9436, 0xE862, 0x942B, 0xE863, 0x9435,
+	0xE864, 0x9421, 0xE865, 0x943A, 0xE866, 0x9441, 0xE867, 0x9452,
+	0xE868, 0x9444, 0xE869, 0x945B, 0xE86A, 0x9460, 0xE86B, 0x9462,
+	0xE86C, 0x945E, 0xE86D, 0x946A, 0xE86E, 0x9229, 0xE86F, 0x9470,
+	0xE870, 0x9475, 0xE871, 0x9477, 0xE872, 0x947D, 0xE873, 0x945A,
+	0xE874, 0x947C, 0xE875, 0x947E, 0xE876, 0x9481, 0xE877, 0x947F,
+	0xE878, 0x9582, 0xE879, 0x9587, 0xE87A, 0x958A, 0xE87B, 0x9594,
+	0xE87C, 0x9596, 0xE87D, 0x9598, 0xE87E, 0x9599, 0xE880, 0x95A0,
+	0xE881, 0x95A8, 0xE882, 0x95A7, 0xE883, 0x95AD, 0xE884, 0x95BC,
+	0xE885, 0x95BB, 0xE886, 0x95B9, 0xE887, 0x95BE, 0xE888, 0x95CA,
+	0xE889, 0x6FF6, 0xE88A, 0x95C3, 0xE88B, 0x95CD, 0xE88C, 0x95CC,
+	0xE88D, 0x95D5, 0xE88E, 0x95D4, 0xE88F, 0x95D6, 0xE890, 0x95DC,
+	0xE891, 0x95E1, 0xE892, 0x95E5, 0xE893, 0x95E2, 0xE894, 0x9621,
+	0xE895, 0x9628, 0xE896, 0x962E, 0xE897, 0x962F, 0xE898, 0x9642,
+	0xE899, 0x964C, 0xE89A, 0x964F, 0xE89B, 0x964B, 0xE89C, 0x9677,
+	0xE89D, 0x965C, 0xE89E, 0x965E, 0xE89F, 0x965D, 0xE8A0, 0x965F,
+	0xE8A1, 0x9666, 0xE8A2, 0x9672, 0xE8A3, 0x966C, 0xE8A4, 0x968D,
+	0xE8A5, 0x9698, 0xE8A6, 0x9695, 0xE8A7, 0x9697, 0xE8A8, 0x96AA,
+	0xE8A9, 0x96A7, 0xE8AA, 0x96B1, 0xE8AB, 0x96B2, 0xE8AC, 0x96B0,
+	0xE8AD, 0x96B4, 0xE8AE, 0x96B6, 0xE8AF, 0x96B8, 0xE8B0, 0x96B9,
+	0xE8B1, 0x96CE, 0xE8B2, 0x96CB, 0xE8B3, 0x96C9, 0xE8B4, 0x96CD,
+	0xE8B5, 0x894D, 0xE8B6, 0x96DC, 0xE8B7, 0x970D, 0xE8B8, 0x96D5,
+	0xE8B9, 0x96F9, 0xE8BA, 0x9704, 0xE8BB, 0x9706, 0xE8BC, 0x9708,
+	0xE8BD, 0x9713, 0xE8BE, 0x970E, 0xE8BF, 0x9711, 0xE8C0, 0x970F,
+	0xE8C1, 0x9716, 0xE8C2, 0x9719, 0xE8C3, 0x9724, 0xE8C4, 0x972A,
+	0xE8C5, 0x9730, 0xE8C6, 0x9739, 0xE8C7, 0x973D, 0xE8C8, 0x973E,
+	0xE8C9, 0x9744, 0xE8CA, 0x9746, 0xE8CB, 0x9748, 0xE8CC, 0x9742,
+	0xE8CD, 0x9749, 0xE8CE, 0x975C, 0xE8CF, 0x9760, 0xE8D0, 0x9764,
+	0xE8D1, 0x9766, 0xE8D2, 0x9768, 0xE8D3, 0x52D2, 0xE8D4, 0x976B,
+	0xE8D5, 0x9771, 0xE8D6, 0x9779, 0xE8D7, 0x9785, 0xE8D8, 0x977C,
+	0xE8D9, 0x9781, 0xE8DA, 0x977A, 0xE8DB, 0x9786, 0xE8DC, 0x978B,
+	0xE8DD, 0x978F, 0xE8DE, 0x9790, 0xE8DF, 0x979C, 0xE8E0, 0x97A8,
+	0xE8E1, 0x97A6, 0xE8E2, 0x97A3, 0xE8E3, 0x97B3, 0xE8E4, 0x97B4,
+	0xE8E5, 0x97C3, 0xE8E6, 0x97C6, 0xE8E7, 0x97C8, 0xE8E8, 0x97CB,
+	0xE8E9, 0x97DC, 0xE8EA, 0x97ED, 0xE8EB, 0x9F4F, 0xE8EC, 0x97F2,
+	0xE8ED, 0x7ADF, 0xE8EE, 0x97F6, 0xE8EF, 0x97F5, 0xE8F0, 0x980F,
+	0xE8F1, 0x980C, 0xE8F2, 0x9838, 0xE8F3, 0x9824, 0xE8F4, 0x9821,
+	0xE8F5, 0x9837, 0xE8F6, 0x983D, 0xE8F7, 0x9846, 0xE8F8, 0x984F,
+	0xE8F9, 0x984B, 0xE8FA, 0x986B, 0xE8FB, 0x986F, 0xE8FC, 0x9870,
+	0xE940, 0x9871, 0xE941, 0x9874, 0xE942, 0x9873, 0xE943, 0x98AA,
+	0xE944, 0x98AF, 0xE945, 0x98B1, 0xE946, 0x98B6, 0xE947, 0x98C4,
+	0xE948, 0x98C3, 0xE949, 0x98C6, 0xE94A, 0x98E9, 0xE94B, 0x98EB,
+	0xE94C, 0x9903, 0xE94D, 0x9909, 0xE94E, 0x9912, 0xE94F, 0x9914,
+	0xE950, 0x9918, 0xE951, 0x9921, 0xE952, 0x991D, 0xE953, 0x991E,
+	0xE954, 0x9924, 0xE955, 0x9920, 0xE956, 0x992C, 0xE957, 0x992E,
+	0xE958, 0x993D, 0xE959, 0x993E, 0xE95A, 0x9942, 0xE95B, 0x9949,
+	0xE95C, 0x9945, 0xE95D, 0x9950, 0xE95E, 0x994B, 0xE95F, 0x9951,
+	0xE960, 0x9952, 0xE961, 0x994C, 0xE962, 0x9955, 0xE963, 0x9997,
+	0xE964, 0x9998, 0xE965, 0x99A5, 0xE966, 0x99AD, 0xE967, 0x99AE,
+	0xE968, 0x99BC, 0xE969, 0x99DF, 0xE96A, 0x99DB, 0xE96B, 0x99DD,
+	0xE96C, 0x99D8, 0xE96D, 0x99D1, 0xE96E, 0x99ED, 0xE96F, 0x99EE,
+	0xE970, 0x99F1, 0xE971, 0x99F2, 0xE972, 0x99FB, 0xE973, 0x99F8,
+	0xE974, 0x9A01, 0xE975, 0x9A0F, 0xE976, 0x9A05, 0xE977, 0x99E2,
+	0xE978, 0x9A19, 0xE979, 0x9A2B, 0xE97A, 0x9A37, 0xE97B, 0x9A45,
+	0xE97C, 0x9A42, 0xE97D, 0x9A40, 0xE97E, 0x9A43, 0xE980, 0x9A3E,
+	0xE981, 0x9A55, 0xE982, 0x9A4D, 0xE983, 0x9A5B, 0xE984, 0x9A57,
+	0xE985, 0x9A5F, 0xE986, 0x9A62, 0xE987, 0x9A65, 0xE988, 0x9A64,
+	0xE989, 0x9A69, 0xE98A, 0x9A6B, 0xE98B, 0x9A6A, 0xE98C, 0x9AAD,
+	0xE98D, 0x9AB0, 0xE98E, 0x9ABC, 0xE98F, 0x9AC0, 0xE990, 0x9ACF,
+	0xE991, 0x9AD1, 0xE992, 0x9AD3, 0xE993, 0x9AD4, 0xE994, 0x9ADE,
+	0xE995, 0x9ADF, 0xE996, 0x9AE2, 0xE997, 0x9AE3, 0xE998, 0x9AE6,
+	0xE999, 0x9AEF, 0xE99A, 0x9AEB, 0xE99B, 0x9AEE, 0xE99C, 0x9AF4,
+	0xE99D, 0x9AF1, 0xE99E, 0x9AF7, 0xE99F, 0x9AFB, 0xE9A0, 0x9B06,
+	0xE9A1, 0x9B18, 0xE9A2, 0x9B1A, 0xE9A3, 0x9B1F, 0xE9A4, 0x9B22,
+	0xE9A5, 0x9B23, 0xE9A6, 0x9B25, 0xE9A7, 0x9B27, 0xE9A8, 0x9B28,
+	0xE9A9, 0x9B29, 0xE9AA, 0x9B2A, 0xE9AB, 0x9B2E, 0xE9AC, 0x9B2F,
+	0xE9AD, 0x9B32, 0xE9AE, 0x9B44, 0xE9AF, 0x9B43, 0xE9B0, 0x9B4F,
+	0xE9B1, 0x9B4D, 0xE9B2, 0x9B4E, 0xE9B3, 0x9B51, 0xE9B4, 0x9B58,
+	0xE9B5, 0x9B74, 0xE9B6, 0x9B93, 0xE9B7, 0x9B83, 0xE9B8, 0x9B91,
+	0xE9B9, 0x9B96, 0xE9BA, 0x9B97, 0xE9BB, 0x9B9F, 0xE9BC, 0x9BA0,
+	0xE9BD, 0x9BA8, 0xE9BE, 0x9BB4, 0xE9BF, 0x9BC0, 0xE9C0, 0x9BCA,
+	0xE9C1, 0x9BB9, 0xE9C2, 0x9BC6, 0xE9C3, 0x9BCF, 0xE9C4, 0x9BD1,
+	0xE9C5, 0x9BD2, 0xE9C6, 0x9BE3, 0xE9C7, 0x9BE2, 0xE9C8, 0x9BE4,
+	0xE9C9, 0x9BD4, 0xE9CA, 0x9BE1, 0xE9CB, 0x9C3A, 0xE9CC, 0x9BF2,
+	0xE9CD, 0x9BF1, 0xE9CE, 0x9BF0, 0xE9CF, 0x9C15, 0xE9D0, 0x9C14,
+	0xE9D1, 0x9C09, 0xE9D2, 0x9C13, 0xE9D3, 0x9C0C, 0xE9D4, 0x9C06,
+	0xE9D5, 0x9C08, 0xE9D6, 0x9C12, 0xE9D7, 0x9C0A, 0xE9D8, 0x9C04,
+	0xE9D9, 0x9C2E, 0xE9DA, 0x9C1B, 0xE9DB, 0x9C25, 0xE9DC, 0x9C24,
+	0xE9DD, 0x9C21, 0xE9DE, 0x9C30, 0xE9DF, 0x9C47, 0xE9E0, 0x9C32,
+	0xE9E1, 0x9C46, 0xE9E2, 0x9C3E, 0xE9E3, 0x9C5A, 0xE9E4, 0x9C60,
+	0xE9E5, 0x9C67, 0xE9E6, 0x9C76, 0xE9E7, 0x9C78, 0xE9E8, 0x9CE7,
+	0xE9E9, 0x9CEC, 0xE9EA, 0x9CF0, 0xE9EB, 0x9D09, 0xE9EC, 0x9D08,
+	0xE9ED, 0x9CEB, 0xE9EE, 0x9D03, 0xE9EF, 0x9D06, 0xE9F0, 0x9D2A,
+	0xE9F1, 0x9D26, 0xE9F2, 0x9DAF, 0xE9F3, 0x9D23, 0xE9F4, 0x9D1F,
+	0xE9F5, 0x9D44, 0xE9F6, 0x9D15, 0xE9F7, 0x9D12, 0xE9F8, 0x9D41,
+	0xE9F9, 0x9D3F, 0xE9FA, 0x9D3E, 0xE9FB, 0x9D46, 0xE9FC, 0x9D48,
+	0xEA40, 0x9D5D, 0xEA41, 0x9D5E, 0xEA42, 0x9D64, 0xEA43, 0x9D51,
+	0xEA44, 0x9D50, 0xEA45, 0x9D59, 0xEA46, 0x9D72, 0xEA47, 0x9D89,
+	0xEA48, 0x9D87, 0xEA49, 0x9DAB, 0xEA4A, 0x9D6F, 0xEA4B, 0x9D7A,
+	0xEA4C, 0x9D9A, 0xEA4D, 0x9DA4, 0xEA4E, 0x9DA9, 0xEA4F, 0x9DB2,
+	0xEA50, 0x9DC4, 0xEA51, 0x9DC1, 0xEA52, 0x9DBB, 0xEA53, 0x9DB8,
+	0xEA54, 0x9DBA, 0xEA55, 0x9DC6, 0xEA56, 0x9DCF, 0xEA57, 0x9DC2,
+	0xEA58, 0x9DD9, 0xEA59, 0x9DD3, 0xEA5A, 0x9DF8, 0xEA5B, 0x9DE6,
+	0xEA5C, 0x9DED, 0xEA5D, 0x9DEF, 0xEA5E, 0x9DFD, 0xEA5F, 0x9E1A,
+	0xEA60, 0x9E1B, 0xEA61, 0x9E1E, 0xEA62, 0x9E75, 0xEA63, 0x9E79,
+	0xEA64, 0x9E7D, 0xEA65, 0x9E81, 0xEA66, 0x9E88, 0xEA67, 0x9E8B,
+	0xEA68, 0x9E8C, 0xEA69, 0x9E92, 0xEA6A, 0x9E95, 0xEA6B, 0x9E91,
+	0xEA6C, 0x9E9D, 0xEA6D, 0x9EA5, 0xEA6E, 0x9EA9, 0xEA6F, 0x9EB8,
+	0xEA70, 0x9EAA, 0xEA71, 0x9EAD, 0xEA72, 0x9761, 0xEA73, 0x9ECC,
+	0xEA74, 0x9ECE, 0xEA75, 0x9ECF, 0xEA76, 0x9ED0, 0xEA77, 0x9ED4,
+	0xEA78, 0x9EDC, 0xEA79, 0x9EDE, 0xEA7A, 0x9EDD, 0xEA7B, 0x9EE0,
+	0xEA7C, 0x9EE5, 0xEA7D, 0x9EE8, 0xEA7E, 0x9EEF, 0xEA80, 0x9EF4,
+	0xEA81, 0x9EF6, 0xEA82, 0x9EF7, 0xEA83, 0x9EF9, 0xEA84, 0x9EFB,
+	0xEA85, 0x9EFC, 0xEA86, 0x9EFD, 0xEA87, 0x9F07, 0xEA88, 0x9F08,
+	0xEA89, 0x76B7, 0xEA8A, 0x9F15, 0xEA8B, 0x9F21, 0xEA8C, 0x9F2C,
+	0xEA8D, 0x9F3E, 0xEA8E, 0x9F4A, 0xEA8F, 0x9F52, 0xEA90, 0x9F54,
+	0xEA91, 0x9F63, 0xEA92, 0x9F5F, 0xEA93, 0x9F60, 0xEA94, 0x9F61,
+	0xEA95, 0x9F66, 0xEA96, 0x9F67, 0xEA97, 0x9F6C, 0xEA98, 0x9F6A,
+	0xEA99, 0x9F77, 0xEA9A, 0x9F72, 0xEA9B, 0x9F76, 0xEA9C, 0x9F95,
+	0xEA9D, 0x9F9C, 0xEA9E, 0x9FA0, 0xEA9F, 0x582F, 0xEAA0, 0x69C7,
+	0xEAA1, 0x9059, 0xEAA2, 0x7464, 0xEAA3, 0x51DC, 0xEAA4, 0x7199,
+	0xFA40, 0x2170, 0xFA41, 0x2171, 0xFA42, 0x2172, 0xFA43, 0x2173,
+	0xFA44, 0x2174, 0xFA45, 0x2175, 0xFA46, 0x2176, 0xFA47, 0x2177,
+	0xFA48, 0x2178, 0xFA49, 0x2179, 0xFA55, 0xFFE4, 0xFA56, 0xFF07,
+	0xFA57, 0xFF02, 0xFA5C, 0x7E8A, 0xFA5D, 0x891C, 0xFA5E, 0x9348,
+	0xFA5F, 0x9288, 0xFA60, 0x84DC, 0xFA61, 0x4FC9, 0xFA62, 0x70BB,
+	0xFA63, 0x6631, 0xFA64, 0x68C8, 0xFA65, 0x92F9, 0xFA66, 0x66FB,
+	0xFA67, 0x5F45, 0xFA68, 0x4E28, 0xFA69, 0x4EE1, 0xFA6A, 0x4EFC,
+	0xFA6B, 0x4F00, 0xFA6C, 0x4F03, 0xFA6D, 0x4F39, 0xFA6E, 0x4F56,
+	0xFA6F, 0x4F92, 0xFA70, 0x4F8A, 0xFA71, 0x4F9A, 0xFA72, 0x4F94,
+	0xFA73, 0x4FCD, 0xFA74, 0x5040, 0xFA75, 0x5022, 0xFA76, 0x4FFF,
+	0xFA77, 0x501E, 0xFA78, 0x5046, 0xFA79, 0x5070, 0xFA7A, 0x5042,
+	0xFA7B, 0x5094, 0xFA7C, 0x50F4, 0xFA7D, 0x50D8, 0xFA7E, 0x514A,
+	0xFA80, 0x5164, 0xFA81, 0x519D, 0xFA82, 0x51BE, 0xFA83, 0x51EC,
+	0xFA84, 0x5215, 0xFA85, 0x529C, 0xFA86, 0x52A6, 0xFA87, 0x52C0,
+	0xFA88, 0x52DB, 0xFA89, 0x5300, 0xFA8A, 0x5307, 0xFA8B, 0x5324,
+	0xFA8C, 0x5372, 0xFA8D, 0x5393, 0xFA8E, 0x53B2, 0xFA8F, 0x53DD,
+	0xFA90, 0xFA0E, 0xFA91, 0x549C, 0xFA92, 0x548A, 0xFA93, 0x54A9,
+	0xFA94, 0x54FF, 0xFA95, 0x5586, 0xFA96, 0x5759, 0xFA97, 0x5765,
+	0xFA98, 0x57AC, 0xFA99, 0x57C8, 0xFA9A, 0x57C7, 0xFA9B, 0xFA0F,
+	0xFA9C, 0xFA10, 0xFA9D, 0x589E, 0xFA9E, 0x58B2, 0xFA9F, 0x590B,
+	0xFAA0, 0x5953, 0xFAA1, 0x595B, 0xFAA2, 0x595D, 0xFAA3, 0x5963,
+	0xFAA4, 0x59A4, 0xFAA5, 0x59BA, 0xFAA6, 0x5B56, 0xFAA7, 0x5BC0,
+	0xFAA8, 0x752F, 0xFAA9, 0x5BD8, 0xFAAA, 0x5BEC, 0xFAAB, 0x5C1E,
+	0xFAAC, 0x5CA6, 0xFAAD, 0x5CBA, 0xFAAE, 0x5CF5, 0xFAAF, 0x5D27,
+	0xFAB0, 0x5D53, 0xFAB1, 0xFA11, 0xFAB2, 0x5D42, 0xFAB3, 0x5D6D,
+	0xFAB4, 0x5DB8, 0xFAB5, 0x5DB9, 0xFAB6, 0x5DD0, 0xFAB7, 0x5F21,
+	0xFAB8, 0x5F34, 0xFAB9, 0x5F67, 0xFABA, 0x5FB7, 0xFABB, 0x5FDE,
+	0xFABC, 0x605D, 0xFABD, 0x6085, 0xFABE, 0x608A, 0xFABF, 0x60DE,
+	0xFAC0, 0x60D5, 0xFAC1, 0x6120, 0xFAC2, 0x60F2, 0xFAC3, 0x6111,
+	0xFAC4, 0x6137, 0xFAC5, 0x6130, 0xFAC6, 0x6198, 0xFAC7, 0x6213,
+	0xFAC8, 0x62A6, 0xFAC9, 0x63F5, 0xFACA, 0x6460, 0xFACB, 0x649D,
+	0xFACC, 0x64CE, 0xFACD, 0x654E, 0xFACE, 0x6600, 0xFACF, 0x6615,
+	0xFAD0, 0x663B, 0xFAD1, 0x6609, 0xFAD2, 0x662E, 0xFAD3, 0x661E,
+	0xFAD4, 0x6624, 0xFAD5, 0x6665, 0xFAD6, 0x6657, 0xFAD7, 0x6659,
+	0xFAD8, 0xFA12, 0xFAD9, 0x6673, 0xFADA, 0x6699, 0xFADB, 0x66A0,
+	0xFADC, 0x66B2, 0xFADD, 0x66BF, 0xFADE, 0x66FA, 0xFADF, 0x670E,
+	0xFAE0, 0xF929, 0xFAE1, 0x6766, 0xFAE2, 0x67BB, 0xFAE3, 0x6852,
+	0xFAE4, 0x67C0, 0xFAE5, 0x6801, 0xFAE6, 0x6844, 0xFAE7, 0x68CF,
+	0xFAE8, 0xFA13, 0xFAE9, 0x6968, 0xFAEA, 0xFA14, 0xFAEB, 0x6998,
+	0xFAEC, 0x69E2, 0xFAED, 0x6A30, 0xFAEE, 0x6A6B, 0xFAEF, 0x6A46,
+	0xFAF0, 0x6A73, 0xFAF1, 0x6A7E, 0xFAF2, 0x6AE2, 0xFAF3, 0x6AE4,
+	0xFAF4, 0x6BD6, 0xFAF5, 0x6C3F, 0xFAF6, 0x6C5C, 0xFAF7, 0x6C86,
+	0xFAF8, 0x6C6F, 0xFAF9, 0x6CDA, 0xFAFA, 0x6D04, 0xFAFB, 0x6D87,
+	0xFAFC, 0x6D6F, 0xFB40, 0x6D96, 0xFB41, 0x6DAC, 0xFB42, 0x6DCF,
+	0xFB43, 0x6DF8, 0xFB44, 0x6DF2, 0xFB45, 0x6DFC, 0xFB46, 0x6E39,
+	0xFB47, 0x6E5C, 0xFB48, 0x6E27, 0xFB49, 0x6E3C, 0xFB4A, 0x6EBF,
+	0xFB4B, 0x6F88, 0xFB4C, 0x6FB5, 0xFB4D, 0x6FF5, 0xFB4E, 0x7005,
+	0xFB4F, 0x7007, 0xFB50, 0x7028, 0xFB51, 0x7085, 0xFB52, 0x70AB,
+	0xFB53, 0x710F, 0xFB54, 0x7104, 0xFB55, 0x715C, 0xFB56, 0x7146,
+	0xFB57, 0x7147, 0xFB58, 0xFA15, 0xFB59, 0x71C1, 0xFB5A, 0x71FE,
+	0xFB5B, 0x72B1, 0xFB5C, 0x72BE, 0xFB5D, 0x7324, 0xFB5E, 0xFA16,
+	0xFB5F, 0x7377, 0xFB60, 0x73BD, 0xFB61, 0x73C9, 0xFB62, 0x73D6,
+	0xFB63, 0x73E3, 0xFB64, 0x73D2, 0xFB65, 0x7407, 0xFB66, 0x73F5,
+	0xFB67, 0x7426, 0xFB68, 0x742A, 0xFB69, 0x7429, 0xFB6A, 0x742E,
+	0xFB6B, 0x7462, 0xFB6C, 0x7489, 0xFB6D, 0x749F, 0xFB6E, 0x7501,
+	0xFB6F, 0x756F, 0xFB70, 0x7682, 0xFB71, 0x769C, 0xFB72, 0x769E,
+	0xFB73, 0x769B, 0xFB74, 0x76A6, 0xFB75, 0xFA17, 0xFB76, 0x7746,
+	0xFB77, 0x52AF, 0xFB78, 0x7821, 0xFB79, 0x784E, 0xFB7A, 0x7864,
+	0xFB7B, 0x787A, 0xFB7C, 0x7930, 0xFB7D, 0xFA18, 0xFB7E, 0xFA19,
+	0xFB80, 0xFA1A, 0xFB81, 0x7994, 0xFB82, 0xFA1B, 0xFB83, 0x799B,
+	0xFB84, 0x7AD1, 0xFB85, 0x7AE7, 0xFB86, 0xFA1C, 0xFB87, 0x7AEB,
+	0xFB88, 0x7B9E, 0xFB89, 0xFA1D, 0xFB8A, 0x7D48, 0xFB8B, 0x7D5C,
+	0xFB8C, 0x7DB7, 0xFB8D, 0x7DA0, 0xFB8E, 0x7DD6, 0xFB8F, 0x7E52,
+	0xFB90, 0x7F47, 0xFB91, 0x7FA1, 0xFB92, 0xFA1E, 0xFB93, 0x8301,
+	0xFB94, 0x8362, 0xFB95, 0x837F, 0xFB96, 0x83C7, 0xFB97, 0x83F6,
+	0xFB98, 0x8448, 0xFB99, 0x84B4, 0xFB9A, 0x8553, 0xFB9B, 0x8559,
+	0xFB9C, 0x856B, 0xFB9D, 0xFA1F, 0xFB9E, 0x85B0, 0xFB9F, 0xFA20,
+	0xFBA0, 0xFA21, 0xFBA1, 0x8807, 0xFBA2, 0x88F5, 0xFBA3, 0x8A12,
+	0xFBA4, 0x8A37, 0xFBA5, 0x8A79, 0xFBA6, 0x8AA7, 0xFBA7, 0x8ABE,
+	0xFBA8, 0x8ADF, 0xFBA9, 0xFA22, 0xFBAA, 0x8AF6, 0xFBAB, 0x8B53,
+	0xFBAC, 0x8B7F, 0xFBAD, 0x8CF0, 0xFBAE, 0x8CF4, 0xFBAF, 0x8D12,
+	0xFBB0, 0x8D76, 0xFBB1, 0xFA23, 0xFBB2, 0x8ECF, 0xFBB3, 0xFA24,
+	0xFBB4, 0xFA25, 0xFBB5, 0x9067, 0xFBB6, 0x90DE, 0xFBB7, 0xFA26,
+	0xFBB8, 0x9115, 0xFBB9, 0x9127, 0xFBBA, 0x91DA, 0xFBBB, 0x91D7,
+	0xFBBC, 0x91DE, 0xFBBD, 0x91ED, 0xFBBE, 0x91EE, 0xFBBF, 0x91E4,
+	0xFBC0, 0x91E5, 0xFBC1, 0x9206, 0xFBC2, 0x9210, 0xFBC3, 0x920A,
+	0xFBC4, 0x923A, 0xFBC5, 0x9240, 0xFBC6, 0x923C, 0xFBC7, 0x924E,
+	0xFBC8, 0x9259, 0xFBC9, 0x9251, 0xFBCA, 0x9239, 0xFBCB, 0x9267,
+	0xFBCC, 0x92A7, 0xFBCD, 0x9277, 0xFBCE, 0x9278, 0xFBCF, 0x92E7,
+	0xFBD0, 0x92D7, 0xFBD1, 0x92D9, 0xFBD2, 0x92D0, 0xFBD3, 0xFA27,
+	0xFBD4, 0x92D5, 0xFBD5, 0x92E0, 0xFBD6, 0x92D3, 0xFBD7, 0x9325,
+	0xFBD8, 0x9321, 0xFBD9, 0x92FB, 0xFBDA, 0xFA28, 0xFBDB, 0x931E,
+	0xFBDC, 0x92FF, 0xFBDD, 0x931D, 0xFBDE, 0x9302, 0xFBDF, 0x9370,
+	0xFBE0, 0x9357, 0xFBE1, 0x93A4, 0xFBE2, 0x93C6, 0xFBE3, 0x93DE,
+	0xFBE4, 0x93F8, 0xFBE5, 0x9431, 0xFBE6, 0x9445, 0xFBE7, 0x9448,
+	0xFBE8, 0x9592, 0xFBE9, 0xF9DC, 0xFBEA, 0xFA29, 0xFBEB, 0x969D,
+	0xFBEC, 0x96AF, 0xFBED, 0x9733, 0xFBEE, 0x973B, 0xFBEF, 0x9743,
+	0xFBF0, 0x974D, 0xFBF1, 0x974F, 0xFBF2, 0x9751, 0xFBF3, 0x9755,
+	0xFBF4, 0x9857, 0xFBF5, 0x9865, 0xFBF6, 0xFA2A, 0xFBF7, 0xFA2B,
+	0xFBF8, 0x9927, 0xFBF9, 0xFA2C, 0xFBFA, 0x999E, 0xFBFB, 0x9A4E,
+	0xFBFC, 0x9AD9, 0xFC40, 0x9ADC, 0xFC41, 0x9B75, 0xFC42, 0x9B72,
+	0xFC43, 0x9B8F, 0xFC44, 0x9BB1, 0xFC45, 0x9BBB, 0xFC46, 0x9C00,
+	0xFC47, 0x9D70, 0xFC48, 0x9D6B, 0xFC49, 0xFA2D, 0xFC4A, 0x9E19,
+	0xFC4B, 0x9ED1, 0, 0
+};
+#endif
+
+
+
+WCHAR ff_convert (	/* Converted code, 0 means conversion error */
+	WCHAR	chr,	/* Character code to be converted */
+	UINT	dir		/* 0: Unicode to OEM code, 1: OEM code to Unicode */
+)
+{
+	const WCHAR *p;
+	WCHAR c;
+	int i, n, li, hi;
+
+
+	if (chr <= 0x80) {	/* ASCII */
+		c = chr;
+	} else {
+#if !_TINY_TABLE
+		if (dir) {		/* OEM code to unicode */
+			p = sjis2uni;
+			hi = sizeof sjis2uni / 4 - 1;
+		} else {		/* Unicode to OEM code */
+			p = uni2sjis;
+			hi = sizeof uni2sjis / 4 - 1;
+		}
+		li = 0;
+		for (n = 16; n; n--) {
+			i = li + (hi - li) / 2;
+			if (chr == p[i * 2]) break;
+			if (chr > p[i * 2])
+				li = i;
+			else
+				hi = i;
+		}
+		c = n ? p[i * 2 + 1] : 0;
+#else
+		if (dir) {		/* OEM code to unicode (Incremental search)*/
+			p = &uni2sjis[1];
+			do {
+				c = *p;
+				p += 2;
+			} while (c && c != chr);
+			p -= 3;
+			c = *p;
+		} else {		/* Unicode to OEM code */
+			li = 0; hi = sizeof uni2sjis / 4 - 1;
+			for (n = 16; n; n--) {
+				i = li + (hi - li) / 2;
+				if (chr == uni2sjis[i * 2]) break;
+				if (chr > uni2sjis[i * 2])
+					li = i;
+				else
+					hi = i;
+			}
+			c = n ? uni2sjis[i * 2 + 1] : 0;
+		}
+#endif
+	}
+
+	return c;
+}
+
+
+
+WCHAR ff_wtoupper (
+	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 {			/* Extended characters */
+		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: UsbWattMeter/trunk/fatfs/option/cc936.c
===================================================================
--- UsbWattMeter/trunk/fatfs/option/cc936.c	(revision 164)
+++ UsbWattMeter/trunk/fatfs/option/cc936.c	(revision 164)
@@ -0,0 +1,11004 @@
+/*------------------------------------------------------------------------*/
+/* Unicode - OEM code bidirectional converter  (C)ChaN, 2015              */
+/* CP936 (Simplified Chinese GBK)                                         */
+/*------------------------------------------------------------------------*/
+
+#include "../ff.h"
+
+
+#if !_USE_LFN || _CODE_PAGE != 936
+#error This file is not needed in current configuration. Remove from the project.
+#endif
+
+static
+const WCHAR uni2oem[] = {
+/*  Unicode - OEM,  Unicode - OEM,  Unicode - OEM,  Unicode - OEM */
+	0x00A4, 0xA1E8, 0x00A7, 0xA1EC, 0x00A8, 0xA1A7, 0x00B0, 0xA1E3,
+	0x00B1, 0xA1C0, 0x00B7, 0xA1A4, 0x00D7, 0xA1C1, 0x00E0, 0xA8A4,
+	0x00E1, 0xA8A2, 0x00E8, 0xA8A8, 0x00E9, 0xA8A6, 0x00EA, 0xA8BA,
+	0x00EC, 0xA8AC, 0x00ED, 0xA8AA, 0x00F2, 0xA8B0, 0x00F3, 0xA8AE,
+	0x00F7, 0xA1C2, 0x00F9, 0xA8B4, 0x00FA, 0xA8B2, 0x00FC, 0xA8B9,
+	0x0101, 0xA8A1, 0x0113, 0xA8A5, 0x011B, 0xA8A7, 0x012B, 0xA8A9,
+	0x0144, 0xA8BD, 0x0148, 0xA8BE, 0x014D, 0xA8AD, 0x016B, 0xA8B1,
+	0x01CE, 0xA8A3, 0x01D0, 0xA8AB, 0x01D2, 0xA8AF, 0x01D4, 0xA8B3,
+	0x01D6, 0xA8B5, 0x01D8, 0xA8B6, 0x01DA, 0xA8B7, 0x01DC, 0xA8B8,
+	0x0251, 0xA8BB, 0x0261, 0xA8C0, 0x02C7, 0xA1A6, 0x02C9, 0xA1A5,
+	0x02CA, 0xA840, 0x02CB, 0xA841, 0x02D9, 0xA842, 0x0391, 0xA6A1,
+	0x0392, 0xA6A2, 0x0393, 0xA6A3, 0x0394, 0xA6A4, 0x0395, 0xA6A5,
+	0x0396, 0xA6A6, 0x0397, 0xA6A7, 0x0398, 0xA6A8, 0x0399, 0xA6A9,
+	0x039A, 0xA6AA, 0x039B, 0xA6AB, 0x039C, 0xA6AC, 0x039D, 0xA6AD,
+	0x039E, 0xA6AE, 0x039F, 0xA6AF, 0x03A0, 0xA6B0, 0x03A1, 0xA6B1,
+	0x03A3, 0xA6B2, 0x03A4, 0xA6B3, 0x03A5, 0xA6B4, 0x03A6, 0xA6B5,
+	0x03A7, 0xA6B6, 0x03A8, 0xA6B7, 0x03A9, 0xA6B8, 0x03B1, 0xA6C1,
+	0x03B2, 0xA6C2, 0x03B3, 0xA6C3, 0x03B4, 0xA6C4, 0x03B5, 0xA6C5,
+	0x03B6, 0xA6C6, 0x03B7, 0xA6C7, 0x03B8, 0xA6C8, 0x03B9, 0xA6C9,
+	0x03BA, 0xA6CA, 0x03BB, 0xA6CB, 0x03BC, 0xA6CC, 0x03BD, 0xA6CD,
+	0x03BE, 0xA6CE, 0x03BF, 0xA6CF, 0x03C0, 0xA6D0, 0x03C1, 0xA6D1,
+	0x03C3, 0xA6D2, 0x03C4, 0xA6D3, 0x03C5, 0xA6D4, 0x03C6, 0xA6D5,
+	0x03C7, 0xA6D6, 0x03C8, 0xA6D7, 0x03C9, 0xA6D8, 0x0401, 0xA7A7,
+	0x0410, 0xA7A1, 0x0411, 0xA7A2, 0x0412, 0xA7A3, 0x0413, 0xA7A4,
+	0x0414, 0xA7A5, 0x0415, 0xA7A6, 0x0416, 0xA7A8, 0x0417, 0xA7A9,
+	0x0418, 0xA7AA, 0x0419, 0xA7AB, 0x041A, 0xA7AC, 0x041B, 0xA7AD,
+	0x041C, 0xA7AE, 0x041D, 0xA7AF, 0x041E, 0xA7B0, 0x041F, 0xA7B1,
+	0x0420, 0xA7B2, 0x0421, 0xA7B3, 0x0422, 0xA7B4, 0x0423, 0xA7B5,
+	0x0424, 0xA7B6, 0x0425, 0xA7B7, 0x0426, 0xA7B8, 0x0427, 0xA7B9,
+	0x0428, 0xA7BA, 0x0429, 0xA7BB, 0x042A, 0xA7BC, 0x042B, 0xA7BD,
+	0x042C, 0xA7BE, 0x042D, 0xA7BF, 0x042E, 0xA7C0, 0x042F, 0xA7C1,
+	0x0430, 0xA7D1, 0x0431, 0xA7D2, 0x0432, 0xA7D3, 0x0433, 0xA7D4,
+	0x0434, 0xA7D5, 0x0435, 0xA7D6, 0x0436, 0xA7D8, 0x0437, 0xA7D9,
+	0x0438, 0xA7DA, 0x0439, 0xA7DB, 0x043A, 0xA7DC, 0x043B, 0xA7DD,
+	0x043C, 0xA7DE, 0x043D, 0xA7DF, 0x043E, 0xA7E0, 0x043F, 0xA7E1,
+	0x0440, 0xA7E2, 0x0441, 0xA7E3, 0x0442, 0xA7E4, 0x0443, 0xA7E5,
+	0x0444, 0xA7E6, 0x0445, 0xA7E7, 0x0446, 0xA7E8, 0x0447, 0xA7E9,
+	0x0448, 0xA7EA, 0x0449, 0xA7EB, 0x044A, 0xA7EC, 0x044B, 0xA7ED,
+	0x044C, 0xA7EE, 0x044D, 0xA7EF, 0x044E, 0xA7F0, 0x044F, 0xA7F1,
+	0x0451, 0xA7D7, 0x2010, 0xA95C, 0x2013, 0xA843, 0x2014, 0xA1AA,
+	0x2015, 0xA844, 0x2016, 0xA1AC, 0x2018, 0xA1AE, 0x2019, 0xA1AF,
+	0x201C, 0xA1B0, 0x201D, 0xA1B1, 0x2025, 0xA845, 0x2026, 0xA1AD,
+	0x2030, 0xA1EB, 0x2032, 0xA1E4, 0x2033, 0xA1E5, 0x2035, 0xA846,
+	0x203B, 0xA1F9, 0x20AC, 0x0080, 0x2103, 0xA1E6, 0x2105, 0xA847,
+	0x2109, 0xA848, 0x2116, 0xA1ED, 0x2121, 0xA959, 0x2160, 0xA2F1,
+	0x2161, 0xA2F2, 0x2162, 0xA2F3, 0x2163, 0xA2F4, 0x2164, 0xA2F5,
+	0x2165, 0xA2F6, 0x2166, 0xA2F7, 0x2167, 0xA2F8, 0x2168, 0xA2F9,
+	0x2169, 0xA2FA, 0x216A, 0xA2FB, 0x216B, 0xA2FC, 0x2170, 0xA2A1,
+	0x2171, 0xA2A2, 0x2172, 0xA2A3, 0x2173, 0xA2A4, 0x2174, 0xA2A5,
+	0x2175, 0xA2A6, 0x2176, 0xA2A7, 0x2177, 0xA2A8, 0x2178, 0xA2A9,
+	0x2179, 0xA2AA, 0x2190, 0xA1FB, 0x2191, 0xA1FC, 0x2192, 0xA1FA,
+	0x2193, 0xA1FD, 0x2196, 0xA849, 0x2197, 0xA84A, 0x2198, 0xA84B,
+	0x2199, 0xA84C, 0x2208, 0xA1CA, 0x220F, 0xA1C7, 0x2211, 0xA1C6,
+	0x2215, 0xA84D, 0x221A, 0xA1CC, 0x221D, 0xA1D8, 0x221E, 0xA1DE,
+	0x221F, 0xA84E, 0x2220, 0xA1CF, 0x2223, 0xA84F, 0x2225, 0xA1CE,
+	0x2227, 0xA1C4, 0x2228, 0xA1C5, 0x2229, 0xA1C9, 0x222A, 0xA1C8,
+	0x222B, 0xA1D2, 0x222E, 0xA1D3, 0x2234, 0xA1E0, 0x2235, 0xA1DF,
+	0x2236, 0xA1C3, 0x2237, 0xA1CB, 0x223D, 0xA1D7, 0x2248, 0xA1D6,
+	0x224C, 0xA1D5, 0x2252, 0xA850, 0x2260, 0xA1D9, 0x2261, 0xA1D4,
+	0x2264, 0xA1DC, 0x2265, 0xA1DD, 0x2266, 0xA851, 0x2267, 0xA852,
+	0x226E, 0xA1DA, 0x226F, 0xA1DB, 0x2295, 0xA892, 0x2299, 0xA1D1,
+	0x22A5, 0xA1CD, 0x22BF, 0xA853, 0x2312, 0xA1D0, 0x2460, 0xA2D9,
+	0x2461, 0xA2DA, 0x2462, 0xA2DB, 0x2463, 0xA2DC, 0x2464, 0xA2DD,
+	0x2465, 0xA2DE, 0x2466, 0xA2DF, 0x2467, 0xA2E0, 0x2468, 0xA2E1,
+	0x2469, 0xA2E2, 0x2474, 0xA2C5, 0x2475, 0xA2C6, 0x2476, 0xA2C7,
+	0x2477, 0xA2C8, 0x2478, 0xA2C9, 0x2479, 0xA2CA, 0x247A, 0xA2CB,
+	0x247B, 0xA2CC, 0x247C, 0xA2CD, 0x247D, 0xA2CE, 0x247E, 0xA2CF,
+	0x247F, 0xA2D0, 0x2480, 0xA2D1, 0x2481, 0xA2D2, 0x2482, 0xA2D3,
+	0x2483, 0xA2D4, 0x2484, 0xA2D5, 0x2485, 0xA2D6, 0x2486, 0xA2D7,
+	0x2487, 0xA2D8, 0x2488, 0xA2B1, 0x2489, 0xA2B2, 0x248A, 0xA2B3,
+	0x248B, 0xA2B4, 0x248C, 0xA2B5, 0x248D, 0xA2B6, 0x248E, 0xA2B7,
+	0x248F, 0xA2B8, 0x2490, 0xA2B9, 0x2491, 0xA2BA, 0x2492, 0xA2BB,
+	0x2493, 0xA2BC, 0x2494, 0xA2BD, 0x2495, 0xA2BE, 0x2496, 0xA2BF,
+	0x2497, 0xA2C0, 0x2498, 0xA2C1, 0x2499, 0xA2C2, 0x249A, 0xA2C3,
+	0x249B, 0xA2C4, 0x2500, 0xA9A4, 0x2501, 0xA9A5, 0x2502, 0xA9A6,
+	0x2503, 0xA9A7, 0x2504, 0xA9A8, 0x2505, 0xA9A9, 0x2506, 0xA9AA,
+	0x2507, 0xA9AB, 0x2508, 0xA9AC, 0x2509, 0xA9AD, 0x250A, 0xA9AE,
+	0x250B, 0xA9AF, 0x250C, 0xA9B0, 0x250D, 0xA9B1, 0x250E, 0xA9B2,
+	0x250F, 0xA9B3, 0x2510, 0xA9B4, 0x2511, 0xA9B5, 0x2512, 0xA9B6,
+	0x2513, 0xA9B7, 0x2514, 0xA9B8, 0x2515, 0xA9B9, 0x2516, 0xA9BA,
+	0x2517, 0xA9BB, 0x2518, 0xA9BC, 0x2519, 0xA9BD, 0x251A, 0xA9BE,
+	0x251B, 0xA9BF, 0x251C, 0xA9C0, 0x251D, 0xA9C1, 0x251E, 0xA9C2,
+	0x251F, 0xA9C3, 0x2520, 0xA9C4, 0x2521, 0xA9C5, 0x2522, 0xA9C6,
+	0x2523, 0xA9C7, 0x2524, 0xA9C8, 0x2525, 0xA9C9, 0x2526, 0xA9CA,
+	0x2527, 0xA9CB, 0x2528, 0xA9CC, 0x2529, 0xA9CD, 0x252A, 0xA9CE,
+	0x252B, 0xA9CF, 0x252C, 0xA9D0, 0x252D, 0xA9D1, 0x252E, 0xA9D2,
+	0x252F, 0xA9D3, 0x2530, 0xA9D4, 0x2531, 0xA9D5, 0x2532, 0xA9D6,
+	0x2533, 0xA9D7, 0x2534, 0xA9D8, 0x2535, 0xA9D9, 0x2536, 0xA9DA,
+	0x2537, 0xA9DB, 0x2538, 0xA9DC, 0x2539, 0xA9DD, 0x253A, 0xA9DE,
+	0x253B, 0xA9DF, 0x253C, 0xA9E0, 0x253D, 0xA9E1, 0x253E, 0xA9E2,
+	0x253F, 0xA9E3, 0x2540, 0xA9E4, 0x2541, 0xA9E5, 0x2542, 0xA9E6,
+	0x2543, 0xA9E7, 0x2544, 0xA9E8, 0x2545, 0xA9E9, 0x2546, 0xA9EA,
+	0x2547, 0xA9EB, 0x2548, 0xA9EC, 0x2549, 0xA9ED, 0x254A, 0xA9EE,
+	0x254B, 0xA9EF, 0x2550, 0xA854, 0x2551, 0xA855, 0x2552, 0xA856,
+	0x2553, 0xA857, 0x2554, 0xA858, 0x2555, 0xA859, 0x2556, 0xA85A,
+	0x2557, 0xA85B, 0x2558, 0xA85C, 0x2559, 0xA85D, 0x255A, 0xA85E,
+	0x255B, 0xA85F, 0x255C, 0xA860, 0x255D, 0xA861, 0x255E, 0xA862,
+	0x255F, 0xA863, 0x2560, 0xA864, 0x2561, 0xA865, 0x2562, 0xA866,
+	0x2563, 0xA867, 0x2564, 0xA868, 0x2565, 0xA869, 0x2566, 0xA86A,
+	0x2567, 0xA86B, 0x2568, 0xA86C, 0x2569, 0xA86D, 0x256A, 0xA86E,
+	0x256B, 0xA86F, 0x256C, 0xA870, 0x256D, 0xA871, 0x256E, 0xA872,
+	0x256F, 0xA873, 0x2570, 0xA874, 0x2571, 0xA875, 0x2572, 0xA876,
+	0x2573, 0xA877, 0x2581, 0xA878, 0x2582, 0xA879, 0x2583, 0xA87A,
+	0x2584, 0xA87B, 0x2585, 0xA87C, 0x2586, 0xA87D, 0x2587, 0xA87E,
+	0x2588, 0xA880, 0x2589, 0xA881, 0x258A, 0xA882, 0x258B, 0xA883,
+	0x258C, 0xA884, 0x258D, 0xA885, 0x258E, 0xA886, 0x258F, 0xA887,
+	0x2593, 0xA888, 0x2594, 0xA889, 0x2595, 0xA88A, 0x25A0, 0xA1F6,
+	0x25A1, 0xA1F5, 0x25B2, 0xA1F8, 0x25B3, 0xA1F7, 0x25BC, 0xA88B,
+	0x25BD, 0xA88C, 0x25C6, 0xA1F4, 0x25C7, 0xA1F3, 0x25CB, 0xA1F0,
+	0x25CE, 0xA1F2, 0x25CF, 0xA1F1, 0x25E2, 0xA88D, 0x25E3, 0xA88E,
+	0x25E4, 0xA88F, 0x25E5, 0xA890, 0x2605, 0xA1EF, 0x2606, 0xA1EE,
+	0x2609, 0xA891, 0x2640, 0xA1E2, 0x2642, 0xA1E1, 0x3000, 0xA1A1,
+	0x3001, 0xA1A2, 0x3002, 0xA1A3, 0x3003, 0xA1A8, 0x3005, 0xA1A9,
+	0x3006, 0xA965, 0x3007, 0xA996, 0x3008, 0xA1B4, 0x3009, 0xA1B5,
+	0x300A, 0xA1B6, 0x300B, 0xA1B7, 0x300C, 0xA1B8, 0x300D, 0xA1B9,
+	0x300E, 0xA1BA, 0x300F, 0xA1BB, 0x3010, 0xA1BE, 0x3011, 0xA1BF,
+	0x3012, 0xA893, 0x3013, 0xA1FE, 0x3014, 0xA1B2, 0x3015, 0xA1B3,
+	0x3016, 0xA1BC, 0x3017, 0xA1BD, 0x301D, 0xA894, 0x301E, 0xA895,
+	0x3021, 0xA940, 0x3022, 0xA941, 0x3023, 0xA942, 0x3024, 0xA943,
+	0x3025, 0xA944, 0x3026, 0xA945, 0x3027, 0xA946, 0x3028, 0xA947,
+	0x3029, 0xA948, 0x3041, 0xA4A1, 0x3042, 0xA4A2, 0x3043, 0xA4A3,
+	0x3044, 0xA4A4, 0x3045, 0xA4A5, 0x3046, 0xA4A6, 0x3047, 0xA4A7,
+	0x3048, 0xA4A8, 0x3049, 0xA4A9, 0x304A, 0xA4AA, 0x304B, 0xA4AB,
+	0x304C, 0xA4AC, 0x304D, 0xA4AD, 0x304E, 0xA4AE, 0x304F, 0xA4AF,
+	0x3050, 0xA4B0, 0x3051, 0xA4B1, 0x3052, 0xA4B2, 0x3053, 0xA4B3,
+	0x3054, 0xA4B4, 0x3055, 0xA4B5, 0x3056, 0xA4B6, 0x3057, 0xA4B7,
+	0x3058, 0xA4B8, 0x3059, 0xA4B9, 0x305A, 0xA4BA, 0x305B, 0xA4BB,
+	0x305C, 0xA4BC, 0x305D, 0xA4BD, 0x305E, 0xA4BE, 0x305F, 0xA4BF,
+	0x3060, 0xA4C0, 0x3061, 0xA4C1, 0x3062, 0xA4C2, 0x3063, 0xA4C3,
+	0x3064, 0xA4C4, 0x3065, 0xA4C5, 0x3066, 0xA4C6, 0x3067, 0xA4C7,
+	0x3068, 0xA4C8, 0x3069, 0xA4C9, 0x306A, 0xA4CA, 0x306B, 0xA4CB,
+	0x306C, 0xA4CC, 0x306D, 0xA4CD, 0x306E, 0xA4CE, 0x306F, 0xA4CF,
+	0x3070, 0xA4D0, 0x3071, 0xA4D1, 0x3072, 0xA4D2, 0x3073, 0xA4D3,
+	0x3074, 0xA4D4, 0x3075, 0xA4D5, 0x3076, 0xA4D6, 0x3077, 0xA4D7,
+	0x3078, 0xA4D8, 0x3079, 0xA4D9, 0x307A, 0xA4DA, 0x307B, 0xA4DB,
+	0x307C, 0xA4DC, 0x307D, 0xA4DD, 0x307E, 0xA4DE, 0x307F, 0xA4DF,
+	0x3080, 0xA4E0, 0x3081, 0xA4E1, 0x3082, 0xA4E2, 0x3083, 0xA4E3,
+	0x3084, 0xA4E4, 0x3085, 0xA4E5, 0x3086, 0xA4E6, 0x3087, 0xA4E7,
+	0x3088, 0xA4E8, 0x3089, 0xA4E9, 0x308A, 0xA4EA, 0x308B, 0xA4EB,
+	0x308C, 0xA4EC, 0x308D, 0xA4ED, 0x308E, 0xA4EE, 0x308F, 0xA4EF,
+	0x3090, 0xA4F0, 0x3091, 0xA4F1, 0x3092, 0xA4F2, 0x3093, 0xA4F3,
+	0x309B, 0xA961, 0x309C, 0xA962, 0x309D, 0xA966, 0x309E, 0xA967,
+	0x30A1, 0xA5A1, 0x30A2, 0xA5A2, 0x30A3, 0xA5A3, 0x30A4, 0xA5A4,
+	0x30A5, 0xA5A5, 0x30A6, 0xA5A6, 0x30A7, 0xA5A7, 0x30A8, 0xA5A8,
+	0x30A9, 0xA5A9, 0x30AA, 0xA5AA, 0x30AB, 0xA5AB, 0x30AC, 0xA5AC,
+	0x30AD, 0xA5AD, 0x30AE, 0xA5AE, 0x30AF, 0xA5AF, 0x30B0, 0xA5B0,
+	0x30B1, 0xA5B1, 0x30B2, 0xA5B2, 0x30B3, 0xA5B3, 0x30B4, 0xA5B4,
+	0x30B5, 0xA5B5, 0x30B6, 0xA5B6, 0x30B7, 0xA5B7, 0x30B8, 0xA5B8,
+	0x30B9, 0xA5B9, 0x30BA, 0xA5BA, 0x30BB, 0xA5BB, 0x30BC, 0xA5BC,
+	0x30BD, 0xA5BD, 0x30BE, 0xA5BE, 0x30BF, 0xA5BF, 0x30C0, 0xA5C0,
+	0x30C1, 0xA5C1, 0x30C2, 0xA5C2, 0x30C3, 0xA5C3, 0x30C4, 0xA5C4,
+	0x30C5, 0xA5C5, 0x30C6, 0xA5C6, 0x30C7, 0xA5C7, 0x30C8, 0xA5C8,
+	0x30C9, 0xA5C9, 0x30CA, 0xA5CA, 0x30CB, 0xA5CB, 0x30CC, 0xA5CC,
+	0x30CD, 0xA5CD, 0x30CE, 0xA5CE, 0x30CF, 0xA5CF, 0x30D0, 0xA5D0,
+	0x30D1, 0xA5D1, 0x30D2, 0xA5D2, 0x30D3, 0xA5D3, 0x30D4, 0xA5D4,
+	0x30D5, 0xA5D5, 0x30D6, 0xA5D6, 0x30D7, 0xA5D7, 0x30D8, 0xA5D8,
+	0x30D9, 0xA5D9, 0x30DA, 0xA5DA, 0x30DB, 0xA5DB, 0x30DC, 0xA5DC,
+	0x30DD, 0xA5DD, 0x30DE, 0xA5DE, 0x30DF, 0xA5DF, 0x30E0, 0xA5E0,
+	0x30E1, 0xA5E1, 0x30E2, 0xA5E2, 0x30E3, 0xA5E3, 0x30E4, 0xA5E4,
+	0x30E5, 0xA5E5, 0x30E6, 0xA5E6, 0x30E7, 0xA5E7, 0x30E8, 0xA5E8,
+	0x30E9, 0xA5E9, 0x30EA, 0xA5EA, 0x30EB, 0xA5EB, 0x30EC, 0xA5EC,
+	0x30ED, 0xA5ED, 0x30EE, 0xA5EE, 0x30EF, 0xA5EF, 0x30F0, 0xA5F0,
+	0x30F1, 0xA5F1, 0x30F2, 0xA5F2, 0x30F3, 0xA5F3, 0x30F4, 0xA5F4,
+	0x30F5, 0xA5F5, 0x30F6, 0xA5F6, 0x30FC, 0xA960, 0x30FD, 0xA963,
+	0x30FE, 0xA964, 0x3105, 0xA8C5, 0x3106, 0xA8C6, 0x3107, 0xA8C7,
+	0x3108, 0xA8C8, 0x3109, 0xA8C9, 0x310A, 0xA8CA, 0x310B, 0xA8CB,
+	0x310C, 0xA8CC, 0x310D, 0xA8CD, 0x310E, 0xA8CE, 0x310F, 0xA8CF,
+	0x3110, 0xA8D0, 0x3111, 0xA8D1, 0x3112, 0xA8D2, 0x3113, 0xA8D3,
+	0x3114, 0xA8D4, 0x3115, 0xA8D5, 0x3116, 0xA8D6, 0x3117, 0xA8D7,
+	0x3118, 0xA8D8, 0x3119, 0xA8D9, 0x311A, 0xA8DA, 0x311B, 0xA8DB,
+	0x311C, 0xA8DC, 0x311D, 0xA8DD, 0x311E, 0xA8DE, 0x311F, 0xA8DF,
+	0x3120, 0xA8E0, 0x3121, 0xA8E1, 0x3122, 0xA8E2, 0x3123, 0xA8E3,
+	0x3124, 0xA8E4, 0x3125, 0xA8E5, 0x3126, 0xA8E6, 0x3127, 0xA8E7,
+	0x3128, 0xA8E8, 0x3129, 0xA8E9, 0x3220, 0xA2E5, 0x3221, 0xA2E6,
+	0x3222, 0xA2E7, 0x3223, 0xA2E8, 0x3224, 0xA2E9, 0x3225, 0xA2EA,
+	0x3226, 0xA2EB, 0x3227, 0xA2EC, 0x3228, 0xA2ED, 0x3229, 0xA2EE,
+	0x3231, 0xA95A, 0x32A3, 0xA949, 0x338E, 0xA94A, 0x338F, 0xA94B,
+	0x339C, 0xA94C, 0x339D, 0xA94D, 0x339E, 0xA94E, 0x33A1, 0xA94F,
+	0x33C4, 0xA950, 0x33CE, 0xA951, 0x33D1, 0xA952, 0x33D2, 0xA953,
+	0x33D5, 0xA954, 0x4E00, 0xD2BB, 0x4E01, 0xB6A1, 0x4E02, 0x8140,
+	0x4E03, 0xC6DF, 0x4E04, 0x8141, 0x4E05, 0x8142, 0x4E06, 0x8143,
+	0x4E07, 0xCDF2, 0x4E08, 0xD5C9, 0x4E09, 0xC8FD, 0x4E0A, 0xC9CF,
+	0x4E0B, 0xCFC2, 0x4E0C, 0xD8A2, 0x4E0D, 0xB2BB, 0x4E0E, 0xD3EB,
+	0x4E0F, 0x8144, 0x4E10, 0xD8A4, 0x4E11, 0xB3F3, 0x4E12, 0x8145,
+	0x4E13, 0xD7A8, 0x4E14, 0xC7D2, 0x4E15, 0xD8A7, 0x4E16, 0xCAC0,
+	0x4E17, 0x8146, 0x4E18, 0xC7F0, 0x4E19, 0xB1FB, 0x4E1A, 0xD2B5,
+	0x4E1B, 0xB4D4, 0x4E1C, 0xB6AB, 0x4E1D, 0xCBBF, 0x4E1E, 0xD8A9,
+	0x4E1F, 0x8147, 0x4E20, 0x8148, 0x4E21, 0x8149, 0x4E22, 0xB6AA,
+	0x4E23, 0x814A, 0x4E24, 0xC1BD, 0x4E25, 0xD1CF, 0x4E26, 0x814B,
+	0x4E27, 0xC9A5, 0x4E28, 0xD8AD, 0x4E29, 0x814C, 0x4E2A, 0xB8F6,
+	0x4E2B, 0xD1BE, 0x4E2C, 0xE3DC, 0x4E2D, 0xD6D0, 0x4E2E, 0x814D,
+	0x4E2F, 0x814E, 0x4E30, 0xB7E1, 0x4E31, 0x814F, 0x4E32, 0xB4AE,
+	0x4E33, 0x8150, 0x4E34, 0xC1D9, 0x4E35, 0x8151, 0x4E36, 0xD8BC,
+	0x4E37, 0x8152, 0x4E38, 0xCDE8, 0x4E39, 0xB5A4, 0x4E3A, 0xCEAA,
+	0x4E3B, 0xD6F7, 0x4E3C, 0x8153, 0x4E3D, 0xC0F6, 0x4E3E, 0xBED9,
+	0x4E3F, 0xD8AF, 0x4E40, 0x8154, 0x4E41, 0x8155, 0x4E42, 0x8156,
+	0x4E43, 0xC4CB, 0x4E44, 0x8157, 0x4E45, 0xBEC3, 0x4E46, 0x8158,
+	0x4E47, 0xD8B1, 0x4E48, 0xC3B4, 0x4E49, 0xD2E5, 0x4E4A, 0x8159,
+	0x4E4B, 0xD6AE, 0x4E4C, 0xCEDA, 0x4E4D, 0xD5A7, 0x4E4E, 0xBAF5,
+	0x4E4F, 0xB7A6, 0x4E50, 0xC0D6, 0x4E51, 0x815A, 0x4E52, 0xC6B9,
+	0x4E53, 0xC5D2, 0x4E54, 0xC7C7, 0x4E55, 0x815B, 0x4E56, 0xB9D4,
+	0x4E57, 0x815C, 0x4E58, 0xB3CB, 0x4E59, 0xD2D2, 0x4E5A, 0x815D,
+	0x4E5B, 0x815E, 0x4E5C, 0xD8BF, 0x4E5D, 0xBEC5, 0x4E5E, 0xC6F2,
+	0x4E5F, 0xD2B2, 0x4E60, 0xCFB0, 0x4E61, 0xCFE7, 0x4E62, 0x815F,
+	0x4E63, 0x8160, 0x4E64, 0x8161, 0x4E65, 0x8162, 0x4E66, 0xCAE9,
+	0x4E67, 0x8163, 0x4E68, 0x8164, 0x4E69, 0xD8C0, 0x4E6A, 0x8165,
+	0x4E6B, 0x8166, 0x4E6C, 0x8167, 0x4E6D, 0x8168, 0x4E6E, 0x8169,
+	0x4E6F, 0x816A, 0x4E70, 0xC2F2, 0x4E71, 0xC2D2, 0x4E72, 0x816B,
+	0x4E73, 0xC8E9, 0x4E74, 0x816C, 0x4E75, 0x816D, 0x4E76, 0x816E,
+	0x4E77, 0x816F, 0x4E78, 0x8170, 0x4E79, 0x8171, 0x4E7A, 0x8172,
+	0x4E7B, 0x8173, 0x4E7C, 0x8174, 0x4E7D, 0x8175, 0x4E7E, 0xC7AC,
+	0x4E7F, 0x8176, 0x4E80, 0x8177, 0x4E81, 0x8178, 0x4E82, 0x8179,
+	0x4E83, 0x817A, 0x4E84, 0x817B, 0x4E85, 0x817C, 0x4E86, 0xC1CB,
+	0x4E87, 0x817D, 0x4E88, 0xD3E8, 0x4E89, 0xD5F9, 0x4E8A, 0x817E,
+	0x4E8B, 0xCAC2, 0x4E8C, 0xB6FE, 0x4E8D, 0xD8A1, 0x4E8E, 0xD3DA,
+	0x4E8F, 0xBFF7, 0x4E90, 0x8180, 0x4E91, 0xD4C6, 0x4E92, 0xBBA5,
+	0x4E93, 0xD8C1, 0x4E94, 0xCEE5, 0x4E95, 0xBEAE, 0x4E96, 0x8181,
+	0x4E97, 0x8182, 0x4E98, 0xD8A8, 0x4E99, 0x8183, 0x4E9A, 0xD1C7,
+	0x4E9B, 0xD0A9, 0x4E9C, 0x8184, 0x4E9D, 0x8185, 0x4E9E, 0x8186,
+	0x4E9F, 0xD8BD, 0x4EA0, 0xD9EF, 0x4EA1, 0xCDF6, 0x4EA2, 0xBFBA,
+	0x4EA3, 0x8187, 0x4EA4, 0xBDBB, 0x4EA5, 0xBAA5, 0x4EA6, 0xD2E0,
+	0x4EA7, 0xB2FA, 0x4EA8, 0xBAE0, 0x4EA9, 0xC4B6, 0x4EAA, 0x8188,
+	0x4EAB, 0xCFED, 0x4EAC, 0xBEA9, 0x4EAD, 0xCDA4, 0x4EAE, 0xC1C1,
+	0x4EAF, 0x8189, 0x4EB0, 0x818A, 0x4EB1, 0x818B, 0x4EB2, 0xC7D7,
+	0x4EB3, 0xD9F1, 0x4EB4, 0x818C, 0x4EB5, 0xD9F4, 0x4EB6, 0x818D,
+	0x4EB7, 0x818E, 0x4EB8, 0x818F, 0x4EB9, 0x8190, 0x4EBA, 0xC8CB,
+	0x4EBB, 0xD8E9, 0x4EBC, 0x8191, 0x4EBD, 0x8192, 0x4EBE, 0x8193,
+	0x4EBF, 0xD2DA, 0x4EC0, 0xCAB2, 0x4EC1, 0xC8CA, 0x4EC2, 0xD8EC,
+	0x4EC3, 0xD8EA, 0x4EC4, 0xD8C6, 0x4EC5, 0xBDF6, 0x4EC6, 0xC6CD,
+	0x4EC7, 0xB3F0, 0x4EC8, 0x8194, 0x4EC9, 0xD8EB, 0x4ECA, 0xBDF1,
+	0x4ECB, 0xBDE9, 0x4ECC, 0x8195, 0x4ECD, 0xC8D4, 0x4ECE, 0xB4D3,
+	0x4ECF, 0x8196, 0x4ED0, 0x8197, 0x4ED1, 0xC2D8, 0x4ED2, 0x8198,
+	0x4ED3, 0xB2D6, 0x4ED4, 0xD7D0, 0x4ED5, 0xCACB, 0x4ED6, 0xCBFB,
+	0x4ED7, 0xD5CC, 0x4ED8, 0xB8B6, 0x4ED9, 0xCFC9, 0x4EDA, 0x8199,
+	0x4EDB, 0x819A, 0x4EDC, 0x819B, 0x4EDD, 0xD9DA, 0x4EDE, 0xD8F0,
+	0x4EDF, 0xC7AA, 0x4EE0, 0x819C, 0x4EE1, 0xD8EE, 0x4EE2, 0x819D,
+	0x4EE3, 0xB4FA, 0x4EE4, 0xC1EE, 0x4EE5, 0xD2D4, 0x4EE6, 0x819E,
+	0x4EE7, 0x819F, 0x4EE8, 0xD8ED, 0x4EE9, 0x81A0, 0x4EEA, 0xD2C7,
+	0x4EEB, 0xD8EF, 0x4EEC, 0xC3C7, 0x4EED, 0x81A1, 0x4EEE, 0x81A2,
+	0x4EEF, 0x81A3, 0x4EF0, 0xD1F6, 0x4EF1, 0x81A4, 0x4EF2, 0xD6D9,
+	0x4EF3, 0xD8F2, 0x4EF4, 0x81A5, 0x4EF5, 0xD8F5, 0x4EF6, 0xBCFE,
+	0x4EF7, 0xBCDB, 0x4EF8, 0x81A6, 0x4EF9, 0x81A7, 0x4EFA, 0x81A8,
+	0x4EFB, 0xC8CE, 0x4EFC, 0x81A9, 0x4EFD, 0xB7DD, 0x4EFE, 0x81AA,
+	0x4EFF, 0xB7C2, 0x4F00, 0x81AB, 0x4F01, 0xC6F3, 0x4F02, 0x81AC,
+	0x4F03, 0x81AD, 0x4F04, 0x81AE, 0x4F05, 0x81AF, 0x4F06, 0x81B0,
+	0x4F07, 0x81B1, 0x4F08, 0x81B2, 0x4F09, 0xD8F8, 0x4F0A, 0xD2C1,
+	0x4F0B, 0x81B3, 0x4F0C, 0x81B4, 0x4F0D, 0xCEE9, 0x4F0E, 0xBCBF,
+	0x4F0F, 0xB7FC, 0x4F10, 0xB7A5, 0x4F11, 0xD0DD, 0x4F12, 0x81B5,
+	0x4F13, 0x81B6, 0x4F14, 0x81B7, 0x4F15, 0x81B8, 0x4F16, 0x81B9,
+	0x4F17, 0xD6DA, 0x4F18, 0xD3C5, 0x4F19, 0xBBEF, 0x4F1A, 0xBBE1,
+	0x4F1B, 0xD8F1, 0x4F1C, 0x81BA, 0x4F1D, 0x81BB, 0x4F1E, 0xC9A1,
+	0x4F1F, 0xCEB0, 0x4F20, 0xB4AB, 0x4F21, 0x81BC, 0x4F22, 0xD8F3,
+	0x4F23, 0x81BD, 0x4F24, 0xC9CB, 0x4F25, 0xD8F6, 0x4F26, 0xC2D7,
+	0x4F27, 0xD8F7, 0x4F28, 0x81BE, 0x4F29, 0x81BF, 0x4F2A, 0xCEB1,
+	0x4F2B, 0xD8F9, 0x4F2C, 0x81C0, 0x4F2D, 0x81C1, 0x4F2E, 0x81C2,
+	0x4F2F, 0xB2AE, 0x4F30, 0xB9C0, 0x4F31, 0x81C3, 0x4F32, 0xD9A3,
+	0x4F33, 0x81C4, 0x4F34, 0xB0E9, 0x4F35, 0x81C5, 0x4F36, 0xC1E6,
+	0x4F37, 0x81C6, 0x4F38, 0xC9EC, 0x4F39, 0x81C7, 0x4F3A, 0xCBC5,
+	0x4F3B, 0x81C8, 0x4F3C, 0xCBC6, 0x4F3D, 0xD9A4, 0x4F3E, 0x81C9,
+	0x4F3F, 0x81CA, 0x4F40, 0x81CB, 0x4F41, 0x81CC, 0x4F42, 0x81CD,
+	0x4F43, 0xB5E8, 0x4F44, 0x81CE, 0x4F45, 0x81CF, 0x4F46, 0xB5AB,
+	0x4F47, 0x81D0, 0x4F48, 0x81D1, 0x4F49, 0x81D2, 0x4F4A, 0x81D3,
+	0x4F4B, 0x81D4, 0x4F4C, 0x81D5, 0x4F4D, 0xCEBB, 0x4F4E, 0xB5CD,
+	0x4F4F, 0xD7A1, 0x4F50, 0xD7F4, 0x4F51, 0xD3D3, 0x4F52, 0x81D6,
+	0x4F53, 0xCCE5, 0x4F54, 0x81D7, 0x4F55, 0xBACE, 0x4F56, 0x81D8,
+	0x4F57, 0xD9A2, 0x4F58, 0xD9DC, 0x4F59, 0xD3E0, 0x4F5A, 0xD8FD,
+	0x4F5B, 0xB7F0, 0x4F5C, 0xD7F7, 0x4F5D, 0xD8FE, 0x4F5E, 0xD8FA,
+	0x4F5F, 0xD9A1, 0x4F60, 0xC4E3, 0x4F61, 0x81D9, 0x4F62, 0x81DA,
+	0x4F63, 0xD3B6, 0x4F64, 0xD8F4, 0x4F65, 0xD9DD, 0x4F66, 0x81DB,
+	0x4F67, 0xD8FB, 0x4F68, 0x81DC, 0x4F69, 0xC5E5, 0x4F6A, 0x81DD,
+	0x4F6B, 0x81DE, 0x4F6C, 0xC0D0, 0x4F6D, 0x81DF, 0x4F6E, 0x81E0,
+	0x4F6F, 0xD1F0, 0x4F70, 0xB0DB, 0x4F71, 0x81E1, 0x4F72, 0x81E2,
+	0x4F73, 0xBCD1, 0x4F74, 0xD9A6, 0x4F75, 0x81E3, 0x4F76, 0xD9A5,
+	0x4F77, 0x81E4, 0x4F78, 0x81E5, 0x4F79, 0x81E6, 0x4F7A, 0x81E7,
+	0x4F7B, 0xD9AC, 0x4F7C, 0xD9AE, 0x4F7D, 0x81E8, 0x4F7E, 0xD9AB,
+	0x4F7F, 0xCAB9, 0x4F80, 0x81E9, 0x4F81, 0x81EA, 0x4F82, 0x81EB,
+	0x4F83, 0xD9A9, 0x4F84, 0xD6B6, 0x4F85, 0x81EC, 0x4F86, 0x81ED,
+	0x4F87, 0x81EE, 0x4F88, 0xB3DE, 0x4F89, 0xD9A8, 0x4F8A, 0x81EF,
+	0x4F8B, 0xC0FD, 0x4F8C, 0x81F0, 0x4F8D, 0xCACC, 0x4F8E, 0x81F1,
+	0x4F8F, 0xD9AA, 0x4F90, 0x81F2, 0x4F91, 0xD9A7, 0x4F92, 0x81F3,
+	0x4F93, 0x81F4, 0x4F94, 0xD9B0, 0x4F95, 0x81F5, 0x4F96, 0x81F6,
+	0x4F97, 0xB6B1, 0x4F98, 0x81F7, 0x4F99, 0x81F8, 0x4F9A, 0x81F9,
+	0x4F9B, 0xB9A9, 0x4F9C, 0x81FA, 0x4F9D, 0xD2C0, 0x4F9E, 0x81FB,
+	0x4F9F, 0x81FC, 0x4FA0, 0xCFC0, 0x4FA1, 0x81FD, 0x4FA2, 0x81FE,
+	0x4FA3, 0xC2C2, 0x4FA4, 0x8240, 0x4FA5, 0xBDC4, 0x4FA6, 0xD5EC,
+	0x4FA7, 0xB2E0, 0x4FA8, 0xC7C8, 0x4FA9, 0xBFEB, 0x4FAA, 0xD9AD,
+	0x4FAB, 0x8241, 0x4FAC, 0xD9AF, 0x4FAD, 0x8242, 0x4FAE, 0xCEEA,
+	0x4FAF, 0xBAEE, 0x4FB0, 0x8243, 0x4FB1, 0x8244, 0x4FB2, 0x8245,
+	0x4FB3, 0x8246, 0x4FB4, 0x8247, 0x4FB5, 0xC7D6, 0x4FB6, 0x8248,
+	0x4FB7, 0x8249, 0x4FB8, 0x824A, 0x4FB9, 0x824B, 0x4FBA, 0x824C,
+	0x4FBB, 0x824D, 0x4FBC, 0x824E, 0x4FBD, 0x824F, 0x4FBE, 0x8250,
+	0x4FBF, 0xB1E3, 0x4FC0, 0x8251, 0x4FC1, 0x8252, 0x4FC2, 0x8253,
+	0x4FC3, 0xB4D9, 0x4FC4, 0xB6ED, 0x4FC5, 0xD9B4, 0x4FC6, 0x8254,
+	0x4FC7, 0x8255, 0x4FC8, 0x8256, 0x4FC9, 0x8257, 0x4FCA, 0xBFA1,
+	0x4FCB, 0x8258, 0x4FCC, 0x8259, 0x4FCD, 0x825A, 0x4FCE, 0xD9DE,
+	0x4FCF, 0xC7CE, 0x4FD0, 0xC0FE, 0x4FD1, 0xD9B8, 0x4FD2, 0x825B,
+	0x4FD3, 0x825C, 0x4FD4, 0x825D, 0x4FD5, 0x825E, 0x4FD6, 0x825F,
+	0x4FD7, 0xCBD7, 0x4FD8, 0xB7FD, 0x4FD9, 0x8260, 0x4FDA, 0xD9B5,
+	0x4FDB, 0x8261, 0x4FDC, 0xD9B7, 0x4FDD, 0xB1A3, 0x4FDE, 0xD3E1,
+	0x4FDF, 0xD9B9, 0x4FE0, 0x8262, 0x4FE1, 0xD0C5, 0x4FE2, 0x8263,
+	0x4FE3, 0xD9B6, 0x4FE4, 0x8264, 0x4FE5, 0x8265, 0x4FE6, 0xD9B1,
+	0x4FE7, 0x8266, 0x4FE8, 0xD9B2, 0x4FE9, 0xC1A9, 0x4FEA, 0xD9B3,
+	0x4FEB, 0x8267, 0x4FEC, 0x8268, 0x4FED, 0xBCF3, 0x4FEE, 0xD0DE,
+	0x4FEF, 0xB8A9, 0x4FF0, 0x8269, 0x4FF1, 0xBEE3, 0x4FF2, 0x826A,
+	0x4FF3, 0xD9BD, 0x4FF4, 0x826B, 0x4FF5, 0x826C, 0x4FF6, 0x826D,
+	0x4FF7, 0x826E, 0x4FF8, 0xD9BA, 0x4FF9, 0x826F, 0x4FFA, 0xB0B3,
+	0x4FFB, 0x8270, 0x4FFC, 0x8271, 0x4FFD, 0x8272, 0x4FFE, 0xD9C2,
+	0x4FFF, 0x8273, 0x5000, 0x8274, 0x5001, 0x8275, 0x5002, 0x8276,
+	0x5003, 0x8277, 0x5004, 0x8278, 0x5005, 0x8279, 0x5006, 0x827A,
+	0x5007, 0x827B, 0x5008, 0x827C, 0x5009, 0x827D, 0x500A, 0x827E,
+	0x500B, 0x8280, 0x500C, 0xD9C4, 0x500D, 0xB1B6, 0x500E, 0x8281,
+	0x500F, 0xD9BF, 0x5010, 0x8282, 0x5011, 0x8283, 0x5012, 0xB5B9,
+	0x5013, 0x8284, 0x5014, 0xBEF3, 0x5015, 0x8285, 0x5016, 0x8286,
+	0x5017, 0x8287, 0x5018, 0xCCC8, 0x5019, 0xBAF2, 0x501A, 0xD2D0,
+	0x501B, 0x8288, 0x501C, 0xD9C3, 0x501D, 0x8289, 0x501E, 0x828A,
+	0x501F, 0xBDE8, 0x5020, 0x828B, 0x5021, 0xB3AB, 0x5022, 0x828C,
+	0x5023, 0x828D, 0x5024, 0x828E, 0x5025, 0xD9C5, 0x5026, 0xBEEB,
+	0x5027, 0x828F, 0x5028, 0xD9C6, 0x5029, 0xD9BB, 0x502A, 0xC4DF,
+	0x502B, 0x8290, 0x502C, 0xD9BE, 0x502D, 0xD9C1, 0x502E, 0xD9C0,
+	0x502F, 0x8291, 0x5030, 0x8292, 0x5031, 0x8293, 0x5032, 0x8294,
+	0x5033, 0x8295, 0x5034, 0x8296, 0x5035, 0x8297, 0x5036, 0x8298,
+	0x5037, 0x8299, 0x5038, 0x829A, 0x5039, 0x829B, 0x503A, 0xD5AE,
+	0x503B, 0x829C, 0x503C, 0xD6B5, 0x503D, 0x829D, 0x503E, 0xC7E3,
+	0x503F, 0x829E, 0x5040, 0x829F, 0x5041, 0x82A0, 0x5042, 0x82A1,
+	0x5043, 0xD9C8, 0x5044, 0x82A2, 0x5045, 0x82A3, 0x5046, 0x82A4,
+	0x5047, 0xBCD9, 0x5048, 0xD9CA, 0x5049, 0x82A5, 0x504A, 0x82A6,
+	0x504B, 0x82A7, 0x504C, 0xD9BC, 0x504D, 0x82A8, 0x504E, 0xD9CB,
+	0x504F, 0xC6AB, 0x5050, 0x82A9, 0x5051, 0x82AA, 0x5052, 0x82AB,
+	0x5053, 0x82AC, 0x5054, 0x82AD, 0x5055, 0xD9C9, 0x5056, 0x82AE,
+	0x5057, 0x82AF, 0x5058, 0x82B0, 0x5059, 0x82B1, 0x505A, 0xD7F6,
+	0x505B, 0x82B2, 0x505C, 0xCDA3, 0x505D, 0x82B3, 0x505E, 0x82B4,
+	0x505F, 0x82B5, 0x5060, 0x82B6, 0x5061, 0x82B7, 0x5062, 0x82B8,
+	0x5063, 0x82B9, 0x5064, 0x82BA, 0x5065, 0xBDA1, 0x5066, 0x82BB,
+	0x5067, 0x82BC, 0x5068, 0x82BD, 0x5069, 0x82BE, 0x506A, 0x82BF,
+	0x506B, 0x82C0, 0x506C, 0xD9CC, 0x506D, 0x82C1, 0x506E, 0x82C2,
+	0x506F, 0x82C3, 0x5070, 0x82C4, 0x5071, 0x82C5, 0x5072, 0x82C6,
+	0x5073, 0x82C7, 0x5074, 0x82C8, 0x5075, 0x82C9, 0x5076, 0xC5BC,
+	0x5077, 0xCDB5, 0x5078, 0x82CA, 0x5079, 0x82CB, 0x507A, 0x82CC,
+	0x507B, 0xD9CD, 0x507C, 0x82CD, 0x507D, 0x82CE, 0x507E, 0xD9C7,
+	0x507F, 0xB3A5, 0x5080, 0xBFFE, 0x5081, 0x82CF, 0x5082, 0x82D0,
+	0x5083, 0x82D1, 0x5084, 0x82D2, 0x5085, 0xB8B5, 0x5086, 0x82D3,
+	0x5087, 0x82D4, 0x5088, 0xC0FC, 0x5089, 0x82D5, 0x508A, 0x82D6,
+	0x508B, 0x82D7, 0x508C, 0x82D8, 0x508D, 0xB0F8, 0x508E, 0x82D9,
+	0x508F, 0x82DA, 0x5090, 0x82DB, 0x5091, 0x82DC, 0x5092, 0x82DD,
+	0x5093, 0x82DE, 0x5094, 0x82DF, 0x5095, 0x82E0, 0x5096, 0x82E1,
+	0x5097, 0x82E2, 0x5098, 0x82E3, 0x5099, 0x82E4, 0x509A, 0x82E5,
+	0x509B, 0x82E6, 0x509C, 0x82E7, 0x509D, 0x82E8, 0x509E, 0x82E9,
+	0x509F, 0x82EA, 0x50A0, 0x82EB, 0x50A1, 0x82EC, 0x50A2, 0x82ED,
+	0x50A3, 0xB4F6, 0x50A4, 0x82EE, 0x50A5, 0xD9CE, 0x50A6, 0x82EF,
+	0x50A7, 0xD9CF, 0x50A8, 0xB4A2, 0x50A9, 0xD9D0, 0x50AA, 0x82F0,
+	0x50AB, 0x82F1, 0x50AC, 0xB4DF, 0x50AD, 0x82F2, 0x50AE, 0x82F3,
+	0x50AF, 0x82F4, 0x50B0, 0x82F5, 0x50B1, 0x82F6, 0x50B2, 0xB0C1,
+	0x50B3, 0x82F7, 0x50B4, 0x82F8, 0x50B5, 0x82F9, 0x50B6, 0x82FA,
+	0x50B7, 0x82FB, 0x50B8, 0x82FC, 0x50B9, 0x82FD, 0x50BA, 0xD9D1,
+	0x50BB, 0xC9B5, 0x50BC, 0x82FE, 0x50BD, 0x8340, 0x50BE, 0x8341,
+	0x50BF, 0x8342, 0x50C0, 0x8343, 0x50C1, 0x8344, 0x50C2, 0x8345,
+	0x50C3, 0x8346, 0x50C4, 0x8347, 0x50C5, 0x8348, 0x50C6, 0x8349,
+	0x50C7, 0x834A, 0x50C8, 0x834B, 0x50C9, 0x834C, 0x50CA, 0x834D,
+	0x50CB, 0x834E, 0x50CC, 0x834F, 0x50CD, 0x8350, 0x50CE, 0x8351,
+	0x50CF, 0xCFF1, 0x50D0, 0x8352, 0x50D1, 0x8353, 0x50D2, 0x8354,
+	0x50D3, 0x8355, 0x50D4, 0x8356, 0x50D5, 0x8357, 0x50D6, 0xD9D2,
+	0x50D7, 0x8358, 0x50D8, 0x8359, 0x50D9, 0x835A, 0x50DA, 0xC1C5,
+	0x50DB, 0x835B, 0x50DC, 0x835C, 0x50DD, 0x835D, 0x50DE, 0x835E,
+	0x50DF, 0x835F, 0x50E0, 0x8360, 0x50E1, 0x8361, 0x50E2, 0x8362,
+	0x50E3, 0x8363, 0x50E4, 0x8364, 0x50E5, 0x8365, 0x50E6, 0xD9D6,
+	0x50E7, 0xC9AE, 0x50E8, 0x8366, 0x50E9, 0x8367, 0x50EA, 0x8368,
+	0x50EB, 0x8369, 0x50EC, 0xD9D5, 0x50ED, 0xD9D4, 0x50EE, 0xD9D7,
+	0x50EF, 0x836A, 0x50F0, 0x836B, 0x50F1, 0x836C, 0x50F2, 0x836D,
+	0x50F3, 0xCBDB, 0x50F4, 0x836E, 0x50F5, 0xBDA9, 0x50F6, 0x836F,
+	0x50F7, 0x8370, 0x50F8, 0x8371, 0x50F9, 0x8372, 0x50FA, 0x8373,
+	0x50FB, 0xC6A7, 0x50FC, 0x8374, 0x50FD, 0x8375, 0x50FE, 0x8376,
+	0x50FF, 0x8377, 0x5100, 0x8378, 0x5101, 0x8379, 0x5102, 0x837A,
+	0x5103, 0x837B, 0x5104, 0x837C, 0x5105, 0x837D, 0x5106, 0xD9D3,
+	0x5107, 0xD9D8, 0x5108, 0x837E, 0x5109, 0x8380, 0x510A, 0x8381,
+	0x510B, 0xD9D9, 0x510C, 0x8382, 0x510D, 0x8383, 0x510E, 0x8384,
+	0x510F, 0x8385, 0x5110, 0x8386, 0x5111, 0x8387, 0x5112, 0xC8E5,
+	0x5113, 0x8388, 0x5114, 0x8389, 0x5115, 0x838A, 0x5116, 0x838B,
+	0x5117, 0x838C, 0x5118, 0x838D, 0x5119, 0x838E, 0x511A, 0x838F,
+	0x511B, 0x8390, 0x511C, 0x8391, 0x511D, 0x8392, 0x511E, 0x8393,
+	0x511F, 0x8394, 0x5120, 0x8395, 0x5121, 0xC0DC, 0x5122, 0x8396,
+	0x5123, 0x8397, 0x5124, 0x8398, 0x5125, 0x8399, 0x5126, 0x839A,
+	0x5127, 0x839B, 0x5128, 0x839C, 0x5129, 0x839D, 0x512A, 0x839E,
+	0x512B, 0x839F, 0x512C, 0x83A0, 0x512D, 0x83A1, 0x512E, 0x83A2,
+	0x512F, 0x83A3, 0x5130, 0x83A4, 0x5131, 0x83A5, 0x5132, 0x83A6,
+	0x5133, 0x83A7, 0x5134, 0x83A8, 0x5135, 0x83A9, 0x5136, 0x83AA,
+	0x5137, 0x83AB, 0x5138, 0x83AC, 0x5139, 0x83AD, 0x513A, 0x83AE,
+	0x513B, 0x83AF, 0x513C, 0x83B0, 0x513D, 0x83B1, 0x513E, 0x83B2,
+	0x513F, 0xB6F9, 0x5140, 0xD8A3, 0x5141, 0xD4CA, 0x5142, 0x83B3,
+	0x5143, 0xD4AA, 0x5144, 0xD0D6, 0x5145, 0xB3E4, 0x5146, 0xD5D7,
+	0x5147, 0x83B4, 0x5148, 0xCFC8, 0x5149, 0xB9E2, 0x514A, 0x83B5,
+	0x514B, 0xBFCB, 0x514C, 0x83B6, 0x514D, 0xC3E2, 0x514E, 0x83B7,
+	0x514F, 0x83B8, 0x5150, 0x83B9, 0x5151, 0xB6D2, 0x5152, 0x83BA,
+	0x5153, 0x83BB, 0x5154, 0xCDC3, 0x5155, 0xD9EE, 0x5156, 0xD9F0,
+	0x5157, 0x83BC, 0x5158, 0x83BD, 0x5159, 0x83BE, 0x515A, 0xB5B3,
+	0x515B, 0x83BF, 0x515C, 0xB6B5, 0x515D, 0x83C0, 0x515E, 0x83C1,
+	0x515F, 0x83C2, 0x5160, 0x83C3, 0x5161, 0x83C4, 0x5162, 0xBEA4,
+	0x5163, 0x83C5, 0x5164, 0x83C6, 0x5165, 0xC8EB, 0x5166, 0x83C7,
+	0x5167, 0x83C8, 0x5168, 0xC8AB, 0x5169, 0x83C9, 0x516A, 0x83CA,
+	0x516B, 0xB0CB, 0x516C, 0xB9AB, 0x516D, 0xC1F9, 0x516E, 0xD9E2,
+	0x516F, 0x83CB, 0x5170, 0xC0BC, 0x5171, 0xB9B2, 0x5172, 0x83CC,
+	0x5173, 0xB9D8, 0x5174, 0xD0CB, 0x5175, 0xB1F8, 0x5176, 0xC6E4,
+	0x5177, 0xBEDF, 0x5178, 0xB5E4, 0x5179, 0xD7C8, 0x517A, 0x83CD,
+	0x517B, 0xD1F8, 0x517C, 0xBCE6, 0x517D, 0xCADE, 0x517E, 0x83CE,
+	0x517F, 0x83CF, 0x5180, 0xBCBD, 0x5181, 0xD9E6, 0x5182, 0xD8E7,
+	0x5183, 0x83D0, 0x5184, 0x83D1, 0x5185, 0xC4DA, 0x5186, 0x83D2,
+	0x5187, 0x83D3, 0x5188, 0xB8D4, 0x5189, 0xC8BD, 0x518A, 0x83D4,
+	0x518B, 0x83D5, 0x518C, 0xB2E1, 0x518D, 0xD4D9, 0x518E, 0x83D6,
+	0x518F, 0x83D7, 0x5190, 0x83D8, 0x5191, 0x83D9, 0x5192, 0xC3B0,
+	0x5193, 0x83DA, 0x5194, 0x83DB, 0x5195, 0xC3E1, 0x5196, 0xDAA2,
+	0x5197, 0xC8DF, 0x5198, 0x83DC, 0x5199, 0xD0B4, 0x519A, 0x83DD,
+	0x519B, 0xBEFC, 0x519C, 0xC5A9, 0x519D, 0x83DE, 0x519E, 0x83DF,
+	0x519F, 0x83E0, 0x51A0, 0xB9DA, 0x51A1, 0x83E1, 0x51A2, 0xDAA3,
+	0x51A3, 0x83E2, 0x51A4, 0xD4A9, 0x51A5, 0xDAA4, 0x51A6, 0x83E3,
+	0x51A7, 0x83E4, 0x51A8, 0x83E5, 0x51A9, 0x83E6, 0x51AA, 0x83E7,
+	0x51AB, 0xD9FB, 0x51AC, 0xB6AC, 0x51AD, 0x83E8, 0x51AE, 0x83E9,
+	0x51AF, 0xB7EB, 0x51B0, 0xB1F9, 0x51B1, 0xD9FC, 0x51B2, 0xB3E5,
+	0x51B3, 0xBEF6, 0x51B4, 0x83EA, 0x51B5, 0xBFF6, 0x51B6, 0xD2B1,
+	0x51B7, 0xC0E4, 0x51B8, 0x83EB, 0x51B9, 0x83EC, 0x51BA, 0x83ED,
+	0x51BB, 0xB6B3, 0x51BC, 0xD9FE, 0x51BD, 0xD9FD, 0x51BE, 0x83EE,
+	0x51BF, 0x83EF, 0x51C0, 0xBEBB, 0x51C1, 0x83F0, 0x51C2, 0x83F1,
+	0x51C3, 0x83F2, 0x51C4, 0xC6E0, 0x51C5, 0x83F3, 0x51C6, 0xD7BC,
+	0x51C7, 0xDAA1, 0x51C8, 0x83F4, 0x51C9, 0xC1B9, 0x51CA, 0x83F5,
+	0x51CB, 0xB5F2, 0x51CC, 0xC1E8, 0x51CD, 0x83F6, 0x51CE, 0x83F7,
+	0x51CF, 0xBCF5, 0x51D0, 0x83F8, 0x51D1, 0xB4D5, 0x51D2, 0x83F9,
+	0x51D3, 0x83FA, 0x51D4, 0x83FB, 0x51D5, 0x83FC, 0x51D6, 0x83FD,
+	0x51D7, 0x83FE, 0x51D8, 0x8440, 0x51D9, 0x8441, 0x51DA, 0x8442,
+	0x51DB, 0xC1DD, 0x51DC, 0x8443, 0x51DD, 0xC4FD, 0x51DE, 0x8444,
+	0x51DF, 0x8445, 0x51E0, 0xBCB8, 0x51E1, 0xB7B2, 0x51E2, 0x8446,
+	0x51E3, 0x8447, 0x51E4, 0xB7EF, 0x51E5, 0x8448, 0x51E6, 0x8449,
+	0x51E7, 0x844A, 0x51E8, 0x844B, 0x51E9, 0x844C, 0x51EA, 0x844D,
+	0x51EB, 0xD9EC, 0x51EC, 0x844E, 0x51ED, 0xC6BE, 0x51EE, 0x844F,
+	0x51EF, 0xBFAD, 0x51F0, 0xBBCB, 0x51F1, 0x8450, 0x51F2, 0x8451,
+	0x51F3, 0xB5CA, 0x51F4, 0x8452, 0x51F5, 0xDBC9, 0x51F6, 0xD0D7,
+	0x51F7, 0x8453, 0x51F8, 0xCDB9, 0x51F9, 0xB0BC, 0x51FA, 0xB3F6,
+	0x51FB, 0xBBF7, 0x51FC, 0xDBCA, 0x51FD, 0xBAAF, 0x51FE, 0x8454,
+	0x51FF, 0xD4E4, 0x5200, 0xB5B6, 0x5201, 0xB5F3, 0x5202, 0xD8D6,
+	0x5203, 0xC8D0, 0x5204, 0x8455, 0x5205, 0x8456, 0x5206, 0xB7D6,
+	0x5207, 0xC7D0, 0x5208, 0xD8D7, 0x5209, 0x8457, 0x520A, 0xBFAF,
+	0x520B, 0x8458, 0x520C, 0x8459, 0x520D, 0xDBBB, 0x520E, 0xD8D8,
+	0x520F, 0x845A, 0x5210, 0x845B, 0x5211, 0xD0CC, 0x5212, 0xBBAE,
+	0x5213, 0x845C, 0x5214, 0x845D, 0x5215, 0x845E, 0x5216, 0xEBBE,
+	0x5217, 0xC1D0, 0x5218, 0xC1F5, 0x5219, 0xD4F2, 0x521A, 0xB8D5,
+	0x521B, 0xB4B4, 0x521C, 0x845F, 0x521D, 0xB3F5, 0x521E, 0x8460,
+	0x521F, 0x8461, 0x5220, 0xC9BE, 0x5221, 0x8462, 0x5222, 0x8463,
+	0x5223, 0x8464, 0x5224, 0xC5D0, 0x5225, 0x8465, 0x5226, 0x8466,
+	0x5227, 0x8467, 0x5228, 0xC5D9, 0x5229, 0xC0FB, 0x522A, 0x8468,
+	0x522B, 0xB1F0, 0x522C, 0x8469, 0x522D, 0xD8D9, 0x522E, 0xB9CE,
+	0x522F, 0x846A, 0x5230, 0xB5BD, 0x5231, 0x846B, 0x5232, 0x846C,
+	0x5233, 0xD8DA, 0x5234, 0x846D, 0x5235, 0x846E, 0x5236, 0xD6C6,
+	0x5237, 0xCBA2, 0x5238, 0xC8AF, 0x5239, 0xC9B2, 0x523A, 0xB4CC,
+	0x523B, 0xBFCC, 0x523C, 0x846F, 0x523D, 0xB9F4, 0x523E, 0x8470,
+	0x523F, 0xD8DB, 0x5240, 0xD8DC, 0x5241, 0xB6E7, 0x5242, 0xBCC1,
+	0x5243, 0xCCEA, 0x5244, 0x8471, 0x5245, 0x8472, 0x5246, 0x8473,
+	0x5247, 0x8474, 0x5248, 0x8475, 0x5249, 0x8476, 0x524A, 0xCFF7,
+	0x524B, 0x8477, 0x524C, 0xD8DD, 0x524D, 0xC7B0, 0x524E, 0x8478,
+	0x524F, 0x8479, 0x5250, 0xB9D0, 0x5251, 0xBDA3, 0x5252, 0x847A,
+	0x5253, 0x847B, 0x5254, 0xCCDE, 0x5255, 0x847C, 0x5256, 0xC6CA,
+	0x5257, 0x847D, 0x5258, 0x847E, 0x5259, 0x8480, 0x525A, 0x8481,
+	0x525B, 0x8482, 0x525C, 0xD8E0, 0x525D, 0x8483, 0x525E, 0xD8DE,
+	0x525F, 0x8484, 0x5260, 0x8485, 0x5261, 0xD8DF, 0x5262, 0x8486,
+	0x5263, 0x8487, 0x5264, 0x8488, 0x5265, 0xB0FE, 0x5266, 0x8489,
+	0x5267, 0xBEE7, 0x5268, 0x848A, 0x5269, 0xCAA3, 0x526A, 0xBCF4,
+	0x526B, 0x848B, 0x526C, 0x848C, 0x526D, 0x848D, 0x526E, 0x848E,
+	0x526F, 0xB8B1, 0x5270, 0x848F, 0x5271, 0x8490, 0x5272, 0xB8EE,
+	0x5273, 0x8491, 0x5274, 0x8492, 0x5275, 0x8493, 0x5276, 0x8494,
+	0x5277, 0x8495, 0x5278, 0x8496, 0x5279, 0x8497, 0x527A, 0x8498,
+	0x527B, 0x8499, 0x527C, 0x849A, 0x527D, 0xD8E2, 0x527E, 0x849B,
+	0x527F, 0xBDCB, 0x5280, 0x849C, 0x5281, 0xD8E4, 0x5282, 0xD8E3,
+	0x5283, 0x849D, 0x5284, 0x849E, 0x5285, 0x849F, 0x5286, 0x84A0,
+	0x5287, 0x84A1, 0x5288, 0xC5FC, 0x5289, 0x84A2, 0x528A, 0x84A3,
+	0x528B, 0x84A4, 0x528C, 0x84A5, 0x528D, 0x84A6, 0x528E, 0x84A7,
+	0x528F, 0x84A8, 0x5290, 0xD8E5, 0x5291, 0x84A9, 0x5292, 0x84AA,
+	0x5293, 0xD8E6, 0x5294, 0x84AB, 0x5295, 0x84AC, 0x5296, 0x84AD,
+	0x5297, 0x84AE, 0x5298, 0x84AF, 0x5299, 0x84B0, 0x529A, 0x84B1,
+	0x529B, 0xC1A6, 0x529C, 0x84B2, 0x529D, 0xC8B0, 0x529E, 0xB0EC,
+	0x529F, 0xB9A6, 0x52A0, 0xBCD3, 0x52A1, 0xCEF1, 0x52A2, 0xDBBD,
+	0x52A3, 0xC1D3, 0x52A4, 0x84B3, 0x52A5, 0x84B4, 0x52A6, 0x84B5,
+	0x52A7, 0x84B6, 0x52A8, 0xB6AF, 0x52A9, 0xD6FA, 0x52AA, 0xC5AC,
+	0x52AB, 0xBDD9, 0x52AC, 0xDBBE, 0x52AD, 0xDBBF, 0x52AE, 0x84B7,
+	0x52AF, 0x84B8, 0x52B0, 0x84B9, 0x52B1, 0xC0F8, 0x52B2, 0xBEA2,
+	0x52B3, 0xC0CD, 0x52B4, 0x84BA, 0x52B5, 0x84BB, 0x52B6, 0x84BC,
+	0x52B7, 0x84BD, 0x52B8, 0x84BE, 0x52B9, 0x84BF, 0x52BA, 0x84C0,
+	0x52BB, 0x84C1, 0x52BC, 0x84C2, 0x52BD, 0x84C3, 0x52BE, 0xDBC0,
+	0x52BF, 0xCAC6, 0x52C0, 0x84C4, 0x52C1, 0x84C5, 0x52C2, 0x84C6,
+	0x52C3, 0xB2AA, 0x52C4, 0x84C7, 0x52C5, 0x84C8, 0x52C6, 0x84C9,
+	0x52C7, 0xD3C2, 0x52C8, 0x84CA, 0x52C9, 0xC3E3, 0x52CA, 0x84CB,
+	0x52CB, 0xD1AB, 0x52CC, 0x84CC, 0x52CD, 0x84CD, 0x52CE, 0x84CE,
+	0x52CF, 0x84CF, 0x52D0, 0xDBC2, 0x52D1, 0x84D0, 0x52D2, 0xC0D5,
+	0x52D3, 0x84D1, 0x52D4, 0x84D2, 0x52D5, 0x84D3, 0x52D6, 0xDBC3,
+	0x52D7, 0x84D4, 0x52D8, 0xBFB1, 0x52D9, 0x84D5, 0x52DA, 0x84D6,
+	0x52DB, 0x84D7, 0x52DC, 0x84D8, 0x52DD, 0x84D9, 0x52DE, 0x84DA,
+	0x52DF, 0xC4BC, 0x52E0, 0x84DB, 0x52E1, 0x84DC, 0x52E2, 0x84DD,
+	0x52E3, 0x84DE, 0x52E4, 0xC7DA, 0x52E5, 0x84DF, 0x52E6, 0x84E0,
+	0x52E7, 0x84E1, 0x52E8, 0x84E2, 0x52E9, 0x84E3, 0x52EA, 0x84E4,
+	0x52EB, 0x84E5, 0x52EC, 0x84E6, 0x52ED, 0x84E7, 0x52EE, 0x84E8,
+	0x52EF, 0x84E9, 0x52F0, 0xDBC4, 0x52F1, 0x84EA, 0x52F2, 0x84EB,
+	0x52F3, 0x84EC, 0x52F4, 0x84ED, 0x52F5, 0x84EE, 0x52F6, 0x84EF,
+	0x52F7, 0x84F0, 0x52F8, 0x84F1, 0x52F9, 0xD9E8, 0x52FA, 0xC9D7,
+	0x52FB, 0x84F2, 0x52FC, 0x84F3, 0x52FD, 0x84F4, 0x52FE, 0xB9B4,
+	0x52FF, 0xCEF0, 0x5300, 0xD4C8, 0x5301, 0x84F5, 0x5302, 0x84F6,
+	0x5303, 0x84F7, 0x5304, 0x84F8, 0x5305, 0xB0FC, 0x5306, 0xB4D2,
+	0x5307, 0x84F9, 0x5308, 0xD0D9, 0x5309, 0x84FA, 0x530A, 0x84FB,
+	0x530B, 0x84FC, 0x530C, 0x84FD, 0x530D, 0xD9E9, 0x530E, 0x84FE,
+	0x530F, 0xDECB, 0x5310, 0xD9EB, 0x5311, 0x8540, 0x5312, 0x8541,
+	0x5313, 0x8542, 0x5314, 0x8543, 0x5315, 0xD8B0, 0x5316, 0xBBAF,
+	0x5317, 0xB1B1, 0x5318, 0x8544, 0x5319, 0xB3D7, 0x531A, 0xD8CE,
+	0x531B, 0x8545, 0x531C, 0x8546, 0x531D, 0xD4D1, 0x531E, 0x8547,
+	0x531F, 0x8548, 0x5320, 0xBDB3, 0x5321, 0xBFEF, 0x5322, 0x8549,
+	0x5323, 0xCFBB, 0x5324, 0x854A, 0x5325, 0x854B, 0x5326, 0xD8D0,
+	0x5327, 0x854C, 0x5328, 0x854D, 0x5329, 0x854E, 0x532A, 0xB7CB,
+	0x532B, 0x854F, 0x532C, 0x8550, 0x532D, 0x8551, 0x532E, 0xD8D1,
+	0x532F, 0x8552, 0x5330, 0x8553, 0x5331, 0x8554, 0x5332, 0x8555,
+	0x5333, 0x8556, 0x5334, 0x8557, 0x5335, 0x8558, 0x5336, 0x8559,
+	0x5337, 0x855A, 0x5338, 0x855B, 0x5339, 0xC6A5, 0x533A, 0xC7F8,
+	0x533B, 0xD2BD, 0x533C, 0x855C, 0x533D, 0x855D, 0x533E, 0xD8D2,
+	0x533F, 0xC4E4, 0x5340, 0x855E, 0x5341, 0xCAAE, 0x5342, 0x855F,
+	0x5343, 0xC7A7, 0x5344, 0x8560, 0x5345, 0xD8A6, 0x5346, 0x8561,
+	0x5347, 0xC9FD, 0x5348, 0xCEE7, 0x5349, 0xBBDC, 0x534A, 0xB0EB,
+	0x534B, 0x8562, 0x534C, 0x8563, 0x534D, 0x8564, 0x534E, 0xBBAA,
+	0x534F, 0xD0AD, 0x5350, 0x8565, 0x5351, 0xB1B0, 0x5352, 0xD7E4,
+	0x5353, 0xD7BF, 0x5354, 0x8566, 0x5355, 0xB5A5, 0x5356, 0xC2F4,
+	0x5357, 0xC4CF, 0x5358, 0x8567, 0x5359, 0x8568, 0x535A, 0xB2A9,
+	0x535B, 0x8569, 0x535C, 0xB2B7, 0x535D, 0x856A, 0x535E, 0xB1E5,
+	0x535F, 0xDFB2, 0x5360, 0xD5BC, 0x5361, 0xBFA8, 0x5362, 0xC2AC,
+	0x5363, 0xD8D5, 0x5364, 0xC2B1, 0x5365, 0x856B, 0x5366, 0xD8D4,
+	0x5367, 0xCED4, 0x5368, 0x856C, 0x5369, 0xDAE0, 0x536A, 0x856D,
+	0x536B, 0xCEC0, 0x536C, 0x856E, 0x536D, 0x856F, 0x536E, 0xD8B4,
+	0x536F, 0xC3AE, 0x5370, 0xD3A1, 0x5371, 0xCEA3, 0x5372, 0x8570,
+	0x5373, 0xBCB4, 0x5374, 0xC8B4, 0x5375, 0xC2D1, 0x5376, 0x8571,
+	0x5377, 0xBEED, 0x5378, 0xD0B6, 0x5379, 0x8572, 0x537A, 0xDAE1,
+	0x537B, 0x8573, 0x537C, 0x8574, 0x537D, 0x8575, 0x537E, 0x8576,
+	0x537F, 0xC7E4, 0x5380, 0x8577, 0x5381, 0x8578, 0x5382, 0xB3A7,
+	0x5383, 0x8579, 0x5384, 0xB6F2, 0x5385, 0xCCFC, 0x5386, 0xC0FA,
+	0x5387, 0x857A, 0x5388, 0x857B, 0x5389, 0xC0F7, 0x538A, 0x857C,
+	0x538B, 0xD1B9, 0x538C, 0xD1E1, 0x538D, 0xD8C7, 0x538E, 0x857D,
+	0x538F, 0x857E, 0x5390, 0x8580, 0x5391, 0x8581, 0x5392, 0x8582,
+	0x5393, 0x8583, 0x5394, 0x8584, 0x5395, 0xB2DE, 0x5396, 0x8585,
+	0x5397, 0x8586, 0x5398, 0xC0E5, 0x5399, 0x8587, 0x539A, 0xBAF1,
+	0x539B, 0x8588, 0x539C, 0x8589, 0x539D, 0xD8C8, 0x539E, 0x858A,
+	0x539F, 0xD4AD, 0x53A0, 0x858B, 0x53A1, 0x858C, 0x53A2, 0xCFE1,
+	0x53A3, 0xD8C9, 0x53A4, 0x858D, 0x53A5, 0xD8CA, 0x53A6, 0xCFC3,
+	0x53A7, 0x858E, 0x53A8, 0xB3F8, 0x53A9, 0xBEC7, 0x53AA, 0x858F,
+	0x53AB, 0x8590, 0x53AC, 0x8591, 0x53AD, 0x8592, 0x53AE, 0xD8CB,
+	0x53AF, 0x8593, 0x53B0, 0x8594, 0x53B1, 0x8595, 0x53B2, 0x8596,
+	0x53B3, 0x8597, 0x53B4, 0x8598, 0x53B5, 0x8599, 0x53B6, 0xDBCC,
+	0x53B7, 0x859A, 0x53B8, 0x859B, 0x53B9, 0x859C, 0x53BA, 0x859D,
+	0x53BB, 0xC8A5, 0x53BC, 0x859E, 0x53BD, 0x859F, 0x53BE, 0x85A0,
+	0x53BF, 0xCFD8, 0x53C0, 0x85A1, 0x53C1, 0xC8FE, 0x53C2, 0xB2CE,
+	0x53C3, 0x85A2, 0x53C4, 0x85A3, 0x53C5, 0x85A4, 0x53C6, 0x85A5,
+	0x53C7, 0x85A6, 0x53C8, 0xD3D6, 0x53C9, 0xB2E6, 0x53CA, 0xBCB0,
+	0x53CB, 0xD3D1, 0x53CC, 0xCBAB, 0x53CD, 0xB7B4, 0x53CE, 0x85A7,
+	0x53CF, 0x85A8, 0x53D0, 0x85A9, 0x53D1, 0xB7A2, 0x53D2, 0x85AA,
+	0x53D3, 0x85AB, 0x53D4, 0xCAE5, 0x53D5, 0x85AC, 0x53D6, 0xC8A1,
+	0x53D7, 0xCADC, 0x53D8, 0xB1E4, 0x53D9, 0xD0F0, 0x53DA, 0x85AD,
+	0x53DB, 0xC5D1, 0x53DC, 0x85AE, 0x53DD, 0x85AF, 0x53DE, 0x85B0,
+	0x53DF, 0xDBC5, 0x53E0, 0xB5FE, 0x53E1, 0x85B1, 0x53E2, 0x85B2,
+	0x53E3, 0xBFDA, 0x53E4, 0xB9C5, 0x53E5, 0xBEE4, 0x53E6, 0xC1ED,
+	0x53E7, 0x85B3, 0x53E8, 0xDFB6, 0x53E9, 0xDFB5, 0x53EA, 0xD6BB,
+	0x53EB, 0xBDD0, 0x53EC, 0xD5D9, 0x53ED, 0xB0C8, 0x53EE, 0xB6A3,
+	0x53EF, 0xBFC9, 0x53F0, 0xCCA8, 0x53F1, 0xDFB3, 0x53F2, 0xCAB7,
+	0x53F3, 0xD3D2, 0x53F4, 0x85B4, 0x53F5, 0xD8CF, 0x53F6, 0xD2B6,
+	0x53F7, 0xBAC5, 0x53F8, 0xCBBE, 0x53F9, 0xCCBE, 0x53FA, 0x85B5,
+	0x53FB, 0xDFB7, 0x53FC, 0xB5F0, 0x53FD, 0xDFB4, 0x53FE, 0x85B6,
+	0x53FF, 0x85B7, 0x5400, 0x85B8, 0x5401, 0xD3F5, 0x5402, 0x85B9,
+	0x5403, 0xB3D4, 0x5404, 0xB8F7, 0x5405, 0x85BA, 0x5406, 0xDFBA,
+	0x5407, 0x85BB, 0x5408, 0xBACF, 0x5409, 0xBCAA, 0x540A, 0xB5F5,
+	0x540B, 0x85BC, 0x540C, 0xCDAC, 0x540D, 0xC3FB, 0x540E, 0xBAF3,
+	0x540F, 0xC0F4, 0x5410, 0xCDC2, 0x5411, 0xCFF2, 0x5412, 0xDFB8,
+	0x5413, 0xCFC5, 0x5414, 0x85BD, 0x5415, 0xC2C0, 0x5416, 0xDFB9,
+	0x5417, 0xC2F0, 0x5418, 0x85BE, 0x5419, 0x85BF, 0x541A, 0x85C0,
+	0x541B, 0xBEFD, 0x541C, 0x85C1, 0x541D, 0xC1DF, 0x541E, 0xCDCC,
+	0x541F, 0xD2F7, 0x5420, 0xB7CD, 0x5421, 0xDFC1, 0x5422, 0x85C2,
+	0x5423, 0xDFC4, 0x5424, 0x85C3, 0x5425, 0x85C4, 0x5426, 0xB7F1,
+	0x5427, 0xB0C9, 0x5428, 0xB6D6, 0x5429, 0xB7D4, 0x542A, 0x85C5,
+	0x542B, 0xBAAC, 0x542C, 0xCCFD, 0x542D, 0xBFD4, 0x542E, 0xCBB1,
+	0x542F, 0xC6F4, 0x5430, 0x85C6, 0x5431, 0xD6A8, 0x5432, 0xDFC5,
+	0x5433, 0x85C7, 0x5434, 0xCEE2, 0x5435, 0xB3B3, 0x5436, 0x85C8,
+	0x5437, 0x85C9, 0x5438, 0xCEFC, 0x5439, 0xB4B5, 0x543A, 0x85CA,
+	0x543B, 0xCEC7, 0x543C, 0xBAF0, 0x543D, 0x85CB, 0x543E, 0xCEE1,
+	0x543F, 0x85CC, 0x5440, 0xD1BD, 0x5441, 0x85CD, 0x5442, 0x85CE,
+	0x5443, 0xDFC0, 0x5444, 0x85CF, 0x5445, 0x85D0, 0x5446, 0xB4F4,
+	0x5447, 0x85D1, 0x5448, 0xB3CA, 0x5449, 0x85D2, 0x544A, 0xB8E6,
+	0x544B, 0xDFBB, 0x544C, 0x85D3, 0x544D, 0x85D4, 0x544E, 0x85D5,
+	0x544F, 0x85D6, 0x5450, 0xC4C5, 0x5451, 0x85D7, 0x5452, 0xDFBC,
+	0x5453, 0xDFBD, 0x5454, 0xDFBE, 0x5455, 0xC5BB, 0x5456, 0xDFBF,
+	0x5457, 0xDFC2, 0x5458, 0xD4B1, 0x5459, 0xDFC3, 0x545A, 0x85D8,
+	0x545B, 0xC7BA, 0x545C, 0xCED8, 0x545D, 0x85D9, 0x545E, 0x85DA,
+	0x545F, 0x85DB, 0x5460, 0x85DC, 0x5461, 0x85DD, 0x5462, 0xC4D8,
+	0x5463, 0x85DE, 0x5464, 0xDFCA, 0x5465, 0x85DF, 0x5466, 0xDFCF,
+	0x5467, 0x85E0, 0x5468, 0xD6DC, 0x5469, 0x85E1, 0x546A, 0x85E2,
+	0x546B, 0x85E3, 0x546C, 0x85E4, 0x546D, 0x85E5, 0x546E, 0x85E6,
+	0x546F, 0x85E7, 0x5470, 0x85E8, 0x5471, 0xDFC9, 0x5472, 0xDFDA,
+	0x5473, 0xCEB6, 0x5474, 0x85E9, 0x5475, 0xBAC7, 0x5476, 0xDFCE,
+	0x5477, 0xDFC8, 0x5478, 0xC5DE, 0x5479, 0x85EA, 0x547A, 0x85EB,
+	0x547B, 0xC9EB, 0x547C, 0xBAF4, 0x547D, 0xC3FC, 0x547E, 0x85EC,
+	0x547F, 0x85ED, 0x5480, 0xBED7, 0x5481, 0x85EE, 0x5482, 0xDFC6,
+	0x5483, 0x85EF, 0x5484, 0xDFCD, 0x5485, 0x85F0, 0x5486, 0xC5D8,
+	0x5487, 0x85F1, 0x5488, 0x85F2, 0x5489, 0x85F3, 0x548A, 0x85F4,
+	0x548B, 0xD5A6, 0x548C, 0xBACD, 0x548D, 0x85F5, 0x548E, 0xBECC,
+	0x548F, 0xD3BD, 0x5490, 0xB8C0, 0x5491, 0x85F6, 0x5492, 0xD6E4,
+	0x5493, 0x85F7, 0x5494, 0xDFC7, 0x5495, 0xB9BE, 0x5496, 0xBFA7,
+	0x5497, 0x85F8, 0x5498, 0x85F9, 0x5499, 0xC1FC, 0x549A, 0xDFCB,
+	0x549B, 0xDFCC, 0x549C, 0x85FA, 0x549D, 0xDFD0, 0x549E, 0x85FB,
+	0x549F, 0x85FC, 0x54A0, 0x85FD, 0x54A1, 0x85FE, 0x54A2, 0x8640,
+	0x54A3, 0xDFDB, 0x54A4, 0xDFE5, 0x54A5, 0x8641, 0x54A6, 0xDFD7,
+	0x54A7, 0xDFD6, 0x54A8, 0xD7C9, 0x54A9, 0xDFE3, 0x54AA, 0xDFE4,
+	0x54AB, 0xE5EB, 0x54AC, 0xD2A7, 0x54AD, 0xDFD2, 0x54AE, 0x8642,
+	0x54AF, 0xBFA9, 0x54B0, 0x8643, 0x54B1, 0xD4DB, 0x54B2, 0x8644,
+	0x54B3, 0xBFC8, 0x54B4, 0xDFD4, 0x54B5, 0x8645, 0x54B6, 0x8646,
+	0x54B7, 0x8647, 0x54B8, 0xCFCC, 0x54B9, 0x8648, 0x54BA, 0x8649,
+	0x54BB, 0xDFDD, 0x54BC, 0x864A, 0x54BD, 0xD1CA, 0x54BE, 0x864B,
+	0x54BF, 0xDFDE, 0x54C0, 0xB0A7, 0x54C1, 0xC6B7, 0x54C2, 0xDFD3,
+	0x54C3, 0x864C, 0x54C4, 0xBAE5, 0x54C5, 0x864D, 0x54C6, 0xB6DF,
+	0x54C7, 0xCDDB, 0x54C8, 0xB9FE, 0x54C9, 0xD4D5, 0x54CA, 0x864E,
+	0x54CB, 0x864F, 0x54CC, 0xDFDF, 0x54CD, 0xCFEC, 0x54CE, 0xB0A5,
+	0x54CF, 0xDFE7, 0x54D0, 0xDFD1, 0x54D1, 0xD1C6, 0x54D2, 0xDFD5,
+	0x54D3, 0xDFD8, 0x54D4, 0xDFD9, 0x54D5, 0xDFDC, 0x54D6, 0x8650,
+	0x54D7, 0xBBA9, 0x54D8, 0x8651, 0x54D9, 0xDFE0, 0x54DA, 0xDFE1,
+	0x54DB, 0x8652, 0x54DC, 0xDFE2, 0x54DD, 0xDFE6, 0x54DE, 0xDFE8,
+	0x54DF, 0xD3B4, 0x54E0, 0x8653, 0x54E1, 0x8654, 0x54E2, 0x8655,
+	0x54E3, 0x8656, 0x54E4, 0x8657, 0x54E5, 0xB8E7, 0x54E6, 0xC5B6,
+	0x54E7, 0xDFEA, 0x54E8, 0xC9DA, 0x54E9, 0xC1A8, 0x54EA, 0xC4C4,
+	0x54EB, 0x8658, 0x54EC, 0x8659, 0x54ED, 0xBFDE, 0x54EE, 0xCFF8,
+	0x54EF, 0x865A, 0x54F0, 0x865B, 0x54F1, 0x865C, 0x54F2, 0xD5DC,
+	0x54F3, 0xDFEE, 0x54F4, 0x865D, 0x54F5, 0x865E, 0x54F6, 0x865F,
+	0x54F7, 0x8660, 0x54F8, 0x8661, 0x54F9, 0x8662, 0x54FA, 0xB2B8,
+	0x54FB, 0x8663, 0x54FC, 0xBADF, 0x54FD, 0xDFEC, 0x54FE, 0x8664,
+	0x54FF, 0xDBC1, 0x5500, 0x8665, 0x5501, 0xD1E4, 0x5502, 0x8666,
+	0x5503, 0x8667, 0x5504, 0x8668, 0x5505, 0x8669, 0x5506, 0xCBF4,
+	0x5507, 0xB4BD, 0x5508, 0x866A, 0x5509, 0xB0A6, 0x550A, 0x866B,
+	0x550B, 0x866C, 0x550C, 0x866D, 0x550D, 0x866E, 0x550E, 0x866F,
+	0x550F, 0xDFF1, 0x5510, 0xCCC6, 0x5511, 0xDFF2, 0x5512, 0x8670,
+	0x5513, 0x8671, 0x5514, 0xDFED, 0x5515, 0x8672, 0x5516, 0x8673,
+	0x5517, 0x8674, 0x5518, 0x8675, 0x5519, 0x8676, 0x551A, 0x8677,
+	0x551B, 0xDFE9, 0x551C, 0x8678, 0x551D, 0x8679, 0x551E, 0x867A,
+	0x551F, 0x867B, 0x5520, 0xDFEB, 0x5521, 0x867C, 0x5522, 0xDFEF,
+	0x5523, 0xDFF0, 0x5524, 0xBBBD, 0x5525, 0x867D, 0x5526, 0x867E,
+	0x5527, 0xDFF3, 0x5528, 0x8680, 0x5529, 0x8681, 0x552A, 0xDFF4,
+	0x552B, 0x8682, 0x552C, 0xBBA3, 0x552D, 0x8683, 0x552E, 0xCADB,
+	0x552F, 0xCEA8, 0x5530, 0xE0A7, 0x5531, 0xB3AA, 0x5532, 0x8684,
+	0x5533, 0xE0A6, 0x5534, 0x8685, 0x5535, 0x8686, 0x5536, 0x8687,
+	0x5537, 0xE0A1, 0x5538, 0x8688, 0x5539, 0x8689, 0x553A, 0x868A,
+	0x553B, 0x868B, 0x553C, 0xDFFE, 0x553D, 0x868C, 0x553E, 0xCDD9,
+	0x553F, 0xDFFC, 0x5540, 0x868D, 0x5541, 0xDFFA, 0x5542, 0x868E,
+	0x5543, 0xBFD0, 0x5544, 0xD7C4, 0x5545, 0x868F, 0x5546, 0xC9CC,
+	0x5547, 0x8690, 0x5548, 0x8691, 0x5549, 0xDFF8, 0x554A, 0xB0A1,
+	0x554B, 0x8692, 0x554C, 0x8693, 0x554D, 0x8694, 0x554E, 0x8695,
+	0x554F, 0x8696, 0x5550, 0xDFFD, 0x5551, 0x8697, 0x5552, 0x8698,
+	0x5553, 0x8699, 0x5554, 0x869A, 0x5555, 0xDFFB, 0x5556, 0xE0A2,
+	0x5557, 0x869B, 0x5558, 0x869C, 0x5559, 0x869D, 0x555A, 0x869E,
+	0x555B, 0x869F, 0x555C, 0xE0A8, 0x555D, 0x86A0, 0x555E, 0x86A1,
+	0x555F, 0x86A2, 0x5560, 0x86A3, 0x5561, 0xB7C8, 0x5562, 0x86A4,
+	0x5563, 0x86A5, 0x5564, 0xC6A1, 0x5565, 0xC9B6, 0x5566, 0xC0B2,
+	0x5567, 0xDFF5, 0x5568, 0x86A6, 0x5569, 0x86A7, 0x556A, 0xC5BE,
+	0x556B, 0x86A8, 0x556C, 0xD8C4, 0x556D, 0xDFF9, 0x556E, 0xC4F6,
+	0x556F, 0x86A9, 0x5570, 0x86AA, 0x5571, 0x86AB, 0x5572, 0x86AC,
+	0x5573, 0x86AD, 0x5574, 0x86AE, 0x5575, 0xE0A3, 0x5576, 0xE0A4,
+	0x5577, 0xE0A5, 0x5578, 0xD0A5, 0x5579, 0x86AF, 0x557A, 0x86B0,
+	0x557B, 0xE0B4, 0x557C, 0xCCE4, 0x557D, 0x86B1, 0x557E, 0xE0B1,
+	0x557F, 0x86B2, 0x5580, 0xBFA6, 0x5581, 0xE0AF, 0x5582, 0xCEB9,
+	0x5583, 0xE0AB, 0x5584, 0xC9C6, 0x5585, 0x86B3, 0x5586, 0x86B4,
+	0x5587, 0xC0AE, 0x5588, 0xE0AE, 0x5589, 0xBAED, 0x558A, 0xBAB0,
+	0x558B, 0xE0A9, 0x558C, 0x86B5, 0x558D, 0x86B6, 0x558E, 0x86B7,
+	0x558F, 0xDFF6, 0x5590, 0x86B8, 0x5591, 0xE0B3, 0x5592, 0x86B9,
+	0x5593, 0x86BA, 0x5594, 0xE0B8, 0x5595, 0x86BB, 0x5596, 0x86BC,
+	0x5597, 0x86BD, 0x5598, 0xB4AD, 0x5599, 0xE0B9, 0x559A, 0x86BE,
+	0x559B, 0x86BF, 0x559C, 0xCFB2, 0x559D, 0xBAC8, 0x559E, 0x86C0,
+	0x559F, 0xE0B0, 0x55A0, 0x86C1, 0x55A1, 0x86C2, 0x55A2, 0x86C3,
+	0x55A3, 0x86C4, 0x55A4, 0x86C5, 0x55A5, 0x86C6, 0x55A6, 0x86C7,
+	0x55A7, 0xD0FA, 0x55A8, 0x86C8, 0x55A9, 0x86C9, 0x55AA, 0x86CA,
+	0x55AB, 0x86CB, 0x55AC, 0x86CC, 0x55AD, 0x86CD, 0x55AE, 0x86CE,
+	0x55AF, 0x86CF, 0x55B0, 0x86D0, 0x55B1, 0xE0AC, 0x55B2, 0x86D1,
+	0x55B3, 0xD4FB, 0x55B4, 0x86D2, 0x55B5, 0xDFF7, 0x55B6, 0x86D3,
+	0x55B7, 0xC5E7, 0x55B8, 0x86D4, 0x55B9, 0xE0AD, 0x55BA, 0x86D5,
+	0x55BB, 0xD3F7, 0x55BC, 0x86D6, 0x55BD, 0xE0B6, 0x55BE, 0xE0B7,
+	0x55BF, 0x86D7, 0x55C0, 0x86D8, 0x55C1, 0x86D9, 0x55C2, 0x86DA,
+	0x55C3, 0x86DB, 0x55C4, 0xE0C4, 0x55C5, 0xD0E1, 0x55C6, 0x86DC,
+	0x55C7, 0x86DD, 0x55C8, 0x86DE, 0x55C9, 0xE0BC, 0x55CA, 0x86DF,
+	0x55CB, 0x86E0, 0x55CC, 0xE0C9, 0x55CD, 0xE0CA, 0x55CE, 0x86E1,
+	0x55CF, 0x86E2, 0x55D0, 0x86E3, 0x55D1, 0xE0BE, 0x55D2, 0xE0AA,
+	0x55D3, 0xC9A4, 0x55D4, 0xE0C1, 0x55D5, 0x86E4, 0x55D6, 0xE0B2,
+	0x55D7, 0x86E5, 0x55D8, 0x86E6, 0x55D9, 0x86E7, 0x55DA, 0x86E8,
+	0x55DB, 0x86E9, 0x55DC, 0xCAC8, 0x55DD, 0xE0C3, 0x55DE, 0x86EA,
+	0x55DF, 0xE0B5, 0x55E0, 0x86EB, 0x55E1, 0xCECB, 0x55E2, 0x86EC,
+	0x55E3, 0xCBC3, 0x55E4, 0xE0CD, 0x55E5, 0xE0C6, 0x55E6, 0xE0C2,
+	0x55E7, 0x86ED, 0x55E8, 0xE0CB, 0x55E9, 0x86EE, 0x55EA, 0xE0BA,
+	0x55EB, 0xE0BF, 0x55EC, 0xE0C0, 0x55ED, 0x86EF, 0x55EE, 0x86F0,
+	0x55EF, 0xE0C5, 0x55F0, 0x86F1, 0x55F1, 0x86F2, 0x55F2, 0xE0C7,
+	0x55F3, 0xE0C8, 0x55F4, 0x86F3, 0x55F5, 0xE0CC, 0x55F6, 0x86F4,
+	0x55F7, 0xE0BB, 0x55F8, 0x86F5, 0x55F9, 0x86F6, 0x55FA, 0x86F7,
+	0x55FB, 0x86F8, 0x55FC, 0x86F9, 0x55FD, 0xCBD4, 0x55FE, 0xE0D5,
+	0x55FF, 0x86FA, 0x5600, 0xE0D6, 0x5601, 0xE0D2, 0x5602, 0x86FB,
+	0x5603, 0x86FC, 0x5604, 0x86FD, 0x5605, 0x86FE, 0x5606, 0x8740,
+	0x5607, 0x8741, 0x5608, 0xE0D0, 0x5609, 0xBCCE, 0x560A, 0x8742,
+	0x560B, 0x8743, 0x560C, 0xE0D1, 0x560D, 0x8744, 0x560E, 0xB8C2,
+	0x560F, 0xD8C5, 0x5610, 0x8745, 0x5611, 0x8746, 0x5612, 0x8747,
+	0x5613, 0x8748, 0x5614, 0x8749, 0x5615, 0x874A, 0x5616, 0x874B,
+	0x5617, 0x874C, 0x5618, 0xD0EA, 0x5619, 0x874D, 0x561A, 0x874E,
+	0x561B, 0xC2EF, 0x561C, 0x874F, 0x561D, 0x8750, 0x561E, 0xE0CF,
+	0x561F, 0xE0BD, 0x5620, 0x8751, 0x5621, 0x8752, 0x5622, 0x8753,
+	0x5623, 0xE0D4, 0x5624, 0xE0D3, 0x5625, 0x8754, 0x5626, 0x8755,
+	0x5627, 0xE0D7, 0x5628, 0x8756, 0x5629, 0x8757, 0x562A, 0x8758,
+	0x562B, 0x8759, 0x562C, 0xE0DC, 0x562D, 0xE0D8, 0x562E, 0x875A,
+	0x562F, 0x875B, 0x5630, 0x875C, 0x5631, 0xD6F6, 0x5632, 0xB3B0,
+	0x5633, 0x875D, 0x5634, 0xD7EC, 0x5635, 0x875E, 0x5636, 0xCBBB,
+	0x5637, 0x875F, 0x5638, 0x8760, 0x5639, 0xE0DA, 0x563A, 0x8761,
+	0x563B, 0xCEFB, 0x563C, 0x8762, 0x563D, 0x8763, 0x563E, 0x8764,
+	0x563F, 0xBAD9, 0x5640, 0x8765, 0x5641, 0x8766, 0x5642, 0x8767,
+	0x5643, 0x8768, 0x5644, 0x8769, 0x5645, 0x876A, 0x5646, 0x876B,
+	0x5647, 0x876C, 0x5648, 0x876D, 0x5649, 0x876E, 0x564A, 0x876F,
+	0x564B, 0x8770, 0x564C, 0xE0E1, 0x564D, 0xE0DD, 0x564E, 0xD2AD,
+	0x564F, 0x8771, 0x5650, 0x8772, 0x5651, 0x8773, 0x5652, 0x8774,
+	0x5653, 0x8775, 0x5654, 0xE0E2, 0x5655, 0x8776, 0x5656, 0x8777,
+	0x5657, 0xE0DB, 0x5658, 0xE0D9, 0x5659, 0xE0DF, 0x565A, 0x8778,
+	0x565B, 0x8779, 0x565C, 0xE0E0, 0x565D, 0x877A, 0x565E, 0x877B,
+	0x565F, 0x877C, 0x5660, 0x877D, 0x5661, 0x877E, 0x5662, 0xE0DE,
+	0x5663, 0x8780, 0x5664, 0xE0E4, 0x5665, 0x8781, 0x5666, 0x8782,
+	0x5667, 0x8783, 0x5668, 0xC6F7, 0x5669, 0xD8AC, 0x566A, 0xD4EB,
+	0x566B, 0xE0E6, 0x566C, 0xCAC9, 0x566D, 0x8784, 0x566E, 0x8785,
+	0x566F, 0x8786, 0x5670, 0x8787, 0x5671, 0xE0E5, 0x5672, 0x8788,
+	0x5673, 0x8789, 0x5674, 0x878A, 0x5675, 0x878B, 0x5676, 0xB8C1,
+	0x5677, 0x878C, 0x5678, 0x878D, 0x5679, 0x878E, 0x567A, 0x878F,
+	0x567B, 0xE0E7, 0x567C, 0xE0E8, 0x567D, 0x8790, 0x567E, 0x8791,
+	0x567F, 0x8792, 0x5680, 0x8793, 0x5681, 0x8794, 0x5682, 0x8795,
+	0x5683, 0x8796, 0x5684, 0x8797, 0x5685, 0xE0E9, 0x5686, 0xE0E3,
+	0x5687, 0x8798, 0x5688, 0x8799, 0x5689, 0x879A, 0x568A, 0x879B,
+	0x568B, 0x879C, 0x568C, 0x879D, 0x568D, 0x879E, 0x568E, 0xBABF,
+	0x568F, 0xCCE7, 0x5690, 0x879F, 0x5691, 0x87A0, 0x5692, 0x87A1,
+	0x5693, 0xE0EA, 0x5694, 0x87A2, 0x5695, 0x87A3, 0x5696, 0x87A4,
+	0x5697, 0x87A5, 0x5698, 0x87A6, 0x5699, 0x87A7, 0x569A, 0x87A8,
+	0x569B, 0x87A9, 0x569C, 0x87AA, 0x569D, 0x87AB, 0x569E, 0x87AC,
+	0x569F, 0x87AD, 0x56A0, 0x87AE, 0x56A1, 0x87AF, 0x56A2, 0x87B0,
+	0x56A3, 0xCFF9, 0x56A4, 0x87B1, 0x56A5, 0x87B2, 0x56A6, 0x87B3,
+	0x56A7, 0x87B4, 0x56A8, 0x87B5, 0x56A9, 0x87B6, 0x56AA, 0x87B7,
+	0x56AB, 0x87B8, 0x56AC, 0x87B9, 0x56AD, 0x87BA, 0x56AE, 0x87BB,
+	0x56AF, 0xE0EB, 0x56B0, 0x87BC, 0x56B1, 0x87BD, 0x56B2, 0x87BE,
+	0x56B3, 0x87BF, 0x56B4, 0x87C0, 0x56B5, 0x87C1, 0x56B6, 0x87C2,
+	0x56B7, 0xC8C2, 0x56B8, 0x87C3, 0x56B9, 0x87C4, 0x56BA, 0x87C5,
+	0x56BB, 0x87C6, 0x56BC, 0xBDC0, 0x56BD, 0x87C7, 0x56BE, 0x87C8,
+	0x56BF, 0x87C9, 0x56C0, 0x87CA, 0x56C1, 0x87CB, 0x56C2, 0x87CC,
+	0x56C3, 0x87CD, 0x56C4, 0x87CE, 0x56C5, 0x87CF, 0x56C6, 0x87D0,
+	0x56C7, 0x87D1, 0x56C8, 0x87D2, 0x56C9, 0x87D3, 0x56CA, 0xC4D2,
+	0x56CB, 0x87D4, 0x56CC, 0x87D5, 0x56CD, 0x87D6, 0x56CE, 0x87D7,
+	0x56CF, 0x87D8, 0x56D0, 0x87D9, 0x56D1, 0x87DA, 0x56D2, 0x87DB,
+	0x56D3, 0x87DC, 0x56D4, 0xE0EC, 0x56D5, 0x87DD, 0x56D6, 0x87DE,
+	0x56D7, 0xE0ED, 0x56D8, 0x87DF, 0x56D9, 0x87E0, 0x56DA, 0xC7F4,
+	0x56DB, 0xCBC4, 0x56DC, 0x87E1, 0x56DD, 0xE0EE, 0x56DE, 0xBBD8,
+	0x56DF, 0xD8B6, 0x56E0, 0xD2F2, 0x56E1, 0xE0EF, 0x56E2, 0xCDC5,
+	0x56E3, 0x87E2, 0x56E4, 0xB6DA, 0x56E5, 0x87E3, 0x56E6, 0x87E4,
+	0x56E7, 0x87E5, 0x56E8, 0x87E6, 0x56E9, 0x87E7, 0x56EA, 0x87E8,
+	0x56EB, 0xE0F1, 0x56EC, 0x87E9, 0x56ED, 0xD4B0, 0x56EE, 0x87EA,
+	0x56EF, 0x87EB, 0x56F0, 0xC0A7, 0x56F1, 0xB4D1, 0x56F2, 0x87EC,
+	0x56F3, 0x87ED, 0x56F4, 0xCEA7, 0x56F5, 0xE0F0, 0x56F6, 0x87EE,
+	0x56F7, 0x87EF, 0x56F8, 0x87F0, 0x56F9, 0xE0F2, 0x56FA, 0xB9CC,
+	0x56FB, 0x87F1, 0x56FC, 0x87F2, 0x56FD, 0xB9FA, 0x56FE, 0xCDBC,
+	0x56FF, 0xE0F3, 0x5700, 0x87F3, 0x5701, 0x87F4, 0x5702, 0x87F5,
+	0x5703, 0xC6D4, 0x5704, 0xE0F4, 0x5705, 0x87F6, 0x5706, 0xD4B2,
+	0x5707, 0x87F7, 0x5708, 0xC8A6, 0x5709, 0xE0F6, 0x570A, 0xE0F5,
+	0x570B, 0x87F8, 0x570C, 0x87F9, 0x570D, 0x87FA, 0x570E, 0x87FB,
+	0x570F, 0x87FC, 0x5710, 0x87FD, 0x5711, 0x87FE, 0x5712, 0x8840,
+	0x5713, 0x8841, 0x5714, 0x8842, 0x5715, 0x8843, 0x5716, 0x8844,
+	0x5717, 0x8845, 0x5718, 0x8846, 0x5719, 0x8847, 0x571A, 0x8848,
+	0x571B, 0x8849, 0x571C, 0xE0F7, 0x571D, 0x884A, 0x571E, 0x884B,
+	0x571F, 0xCDC1, 0x5720, 0x884C, 0x5721, 0x884D, 0x5722, 0x884E,
+	0x5723, 0xCAA5, 0x5724, 0x884F, 0x5725, 0x8850, 0x5726, 0x8851,
+	0x5727, 0x8852, 0x5728, 0xD4DA, 0x5729, 0xDBD7, 0x572A, 0xDBD9,
+	0x572B, 0x8853, 0x572C, 0xDBD8, 0x572D, 0xB9E7, 0x572E, 0xDBDC,
+	0x572F, 0xDBDD, 0x5730, 0xB5D8, 0x5731, 0x8854, 0x5732, 0x8855,
+	0x5733, 0xDBDA, 0x5734, 0x8856, 0x5735, 0x8857, 0x5736, 0x8858,
+	0x5737, 0x8859, 0x5738, 0x885A, 0x5739, 0xDBDB, 0x573A, 0xB3A1,
+	0x573B, 0xDBDF, 0x573C, 0x885B, 0x573D, 0x885C, 0x573E, 0xBBF8,
+	0x573F, 0x885D, 0x5740, 0xD6B7, 0x5741, 0x885E, 0x5742, 0xDBE0,
+	0x5743, 0x885F, 0x5744, 0x8860, 0x5745, 0x8861, 0x5746, 0x8862,
+	0x5747, 0xBEF9, 0x5748, 0x8863, 0x5749, 0x8864, 0x574A, 0xB7BB,
+	0x574B, 0x8865, 0x574C, 0xDBD0, 0x574D, 0xCCAE, 0x574E, 0xBFB2,
+	0x574F, 0xBBB5, 0x5750, 0xD7F8, 0x5751, 0xBFD3, 0x5752, 0x8866,
+	0x5753, 0x8867, 0x5754, 0x8868, 0x5755, 0x8869, 0x5756, 0x886A,
+	0x5757, 0xBFE9, 0x5758, 0x886B, 0x5759, 0x886C, 0x575A, 0xBCE1,
+	0x575B, 0xCCB3, 0x575C, 0xDBDE, 0x575D, 0xB0D3, 0x575E, 0xCEEB,
+	0x575F, 0xB7D8, 0x5760, 0xD7B9, 0x5761, 0xC6C2, 0x5762, 0x886D,
+	0x5763, 0x886E, 0x5764, 0xC0A4, 0x5765, 0x886F, 0x5766, 0xCCB9,
+	0x5767, 0x8870, 0x5768, 0xDBE7, 0x5769, 0xDBE1, 0x576A, 0xC6BA,
+	0x576B, 0xDBE3, 0x576C, 0x8871, 0x576D, 0xDBE8, 0x576E, 0x8872,
+	0x576F, 0xC5F7, 0x5770, 0x8873, 0x5771, 0x8874, 0x5772, 0x8875,
+	0x5773, 0xDBEA, 0x5774, 0x8876, 0x5775, 0x8877, 0x5776, 0xDBE9,
+	0x5777, 0xBFC0, 0x5778, 0x8878, 0x5779, 0x8879, 0x577A, 0x887A,
+	0x577B, 0xDBE6, 0x577C, 0xDBE5, 0x577D, 0x887B, 0x577E, 0x887C,
+	0x577F, 0x887D, 0x5780, 0x887E, 0x5781, 0x8880, 0x5782, 0xB4B9,
+	0x5783, 0xC0AC, 0x5784, 0xC2A2, 0x5785, 0xDBE2, 0x5786, 0xDBE4,
+	0x5787, 0x8881, 0x5788, 0x8882, 0x5789, 0x8883, 0x578A, 0x8884,
+	0x578B, 0xD0CD, 0x578C, 0xDBED, 0x578D, 0x8885, 0x578E, 0x8886,
+	0x578F, 0x8887, 0x5790, 0x8888, 0x5791, 0x8889, 0x5792, 0xC0DD,
+	0x5793, 0xDBF2, 0x5794, 0x888A, 0x5795, 0x888B, 0x5796, 0x888C,
+	0x5797, 0x888D, 0x5798, 0x888E, 0x5799, 0x888F, 0x579A, 0x8890,
+	0x579B, 0xB6E2, 0x579C, 0x8891, 0x579D, 0x8892, 0x579E, 0x8893,
+	0x579F, 0x8894, 0x57A0, 0xDBF3, 0x57A1, 0xDBD2, 0x57A2, 0xB9B8,
+	0x57A3, 0xD4AB, 0x57A4, 0xDBEC, 0x57A5, 0x8895, 0x57A6, 0xBFD1,
+	0x57A7, 0xDBF0, 0x57A8, 0x8896, 0x57A9, 0xDBD1, 0x57AA, 0x8897,
+	0x57AB, 0xB5E6, 0x57AC, 0x8898, 0x57AD, 0xDBEB, 0x57AE, 0xBFE5,
+	0x57AF, 0x8899, 0x57B0, 0x889A, 0x57B1, 0x889B, 0x57B2, 0xDBEE,
+	0x57B3, 0x889C, 0x57B4, 0xDBF1, 0x57B5, 0x889D, 0x57B6, 0x889E,
+	0x57B7, 0x889F, 0x57B8, 0xDBF9, 0x57B9, 0x88A0, 0x57BA, 0x88A1,
+	0x57BB, 0x88A2, 0x57BC, 0x88A3, 0x57BD, 0x88A4, 0x57BE, 0x88A5,
+	0x57BF, 0x88A6, 0x57C0, 0x88A7, 0x57C1, 0x88A8, 0x57C2, 0xB9A1,
+	0x57C3, 0xB0A3, 0x57C4, 0x88A9, 0x57C5, 0x88AA, 0x57C6, 0x88AB,
+	0x57C7, 0x88AC, 0x57C8, 0x88AD, 0x57C9, 0x88AE, 0x57CA, 0x88AF,
+	0x57CB, 0xC2F1, 0x57CC, 0x88B0, 0x57CD, 0x88B1, 0x57CE, 0xB3C7,
+	0x57CF, 0xDBEF, 0x57D0, 0x88B2, 0x57D1, 0x88B3, 0x57D2, 0xDBF8,
+	0x57D3, 0x88B4, 0x57D4, 0xC6D2, 0x57D5, 0xDBF4, 0x57D6, 0x88B5,
+	0x57D7, 0x88B6, 0x57D8, 0xDBF5, 0x57D9, 0xDBF7, 0x57DA, 0xDBF6,
+	0x57DB, 0x88B7, 0x57DC, 0x88B8, 0x57DD, 0xDBFE, 0x57DE, 0x88B9,
+	0x57DF, 0xD3F2, 0x57E0, 0xB2BA, 0x57E1, 0x88BA, 0x57E2, 0x88BB,
+	0x57E3, 0x88BC, 0x57E4, 0xDBFD, 0x57E5, 0x88BD, 0x57E6, 0x88BE,
+	0x57E7, 0x88BF, 0x57E8, 0x88C0, 0x57E9, 0x88C1, 0x57EA, 0x88C2,
+	0x57EB, 0x88C3, 0x57EC, 0x88C4, 0x57ED, 0xDCA4, 0x57EE, 0x88C5,
+	0x57EF, 0xDBFB, 0x57F0, 0x88C6, 0x57F1, 0x88C7, 0x57F2, 0x88C8,
+	0x57F3, 0x88C9, 0x57F4, 0xDBFA, 0x57F5, 0x88CA, 0x57F6, 0x88CB,
+	0x57F7, 0x88CC, 0x57F8, 0xDBFC, 0x57F9, 0xC5E0, 0x57FA, 0xBBF9,
+	0x57FB, 0x88CD, 0x57FC, 0x88CE, 0x57FD, 0xDCA3, 0x57FE, 0x88CF,
+	0x57FF, 0x88D0, 0x5800, 0xDCA5, 0x5801, 0x88D1, 0x5802, 0xCCC3,
+	0x5803, 0x88D2, 0x5804, 0x88D3, 0x5805, 0x88D4, 0x5806, 0xB6D1,
+	0x5807, 0xDDC0, 0x5808, 0x88D5, 0x5809, 0x88D6, 0x580A, 0x88D7,
+	0x580B, 0xDCA1, 0x580C, 0x88D8, 0x580D, 0xDCA2, 0x580E, 0x88D9,
+	0x580F, 0x88DA, 0x5810, 0x88DB, 0x5811, 0xC7B5, 0x5812, 0x88DC,
+	0x5813, 0x88DD, 0x5814, 0x88DE, 0x5815, 0xB6E9, 0x5816, 0x88DF,
+	0x5817, 0x88E0, 0x5818, 0x88E1, 0x5819, 0xDCA7, 0x581A, 0x88E2,
+	0x581B, 0x88E3, 0x581C, 0x88E4, 0x581D, 0x88E5, 0x581E, 0xDCA6,
+	0x581F, 0x88E6, 0x5820, 0xDCA9, 0x5821, 0xB1A4, 0x5822, 0x88E7,
+	0x5823, 0x88E8, 0x5824, 0xB5CC, 0x5825, 0x88E9, 0x5826, 0x88EA,
+	0x5827, 0x88EB, 0x5828, 0x88EC, 0x5829, 0x88ED, 0x582A, 0xBFB0,
+	0x582B, 0x88EE, 0x582C, 0x88EF, 0x582D, 0x88F0, 0x582E, 0x88F1,
+	0x582F, 0x88F2, 0x5830, 0xD1DF, 0x5831, 0x88F3, 0x5832, 0x88F4,
+	0x5833, 0x88F5, 0x5834, 0x88F6, 0x5835, 0xB6C2, 0x5836, 0x88F7,
+	0x5837, 0x88F8, 0x5838, 0x88F9, 0x5839, 0x88FA, 0x583A, 0x88FB,
+	0x583B, 0x88FC, 0x583C, 0x88FD, 0x583D, 0x88FE, 0x583E, 0x8940,
+	0x583F, 0x8941, 0x5840, 0x8942, 0x5841, 0x8943, 0x5842, 0x8944,
+	0x5843, 0x8945, 0x5844, 0xDCA8, 0x5845, 0x8946, 0x5846, 0x8947,
+	0x5847, 0x8948, 0x5848, 0x8949, 0x5849, 0x894A, 0x584A, 0x894B,
+	0x584B, 0x894C, 0x584C, 0xCBFA, 0x584D, 0xEBF3, 0x584E, 0x894D,
+	0x584F, 0x894E, 0x5850, 0x894F, 0x5851, 0xCBDC, 0x5852, 0x8950,
+	0x5853, 0x8951, 0x5854, 0xCBFE, 0x5855, 0x8952, 0x5856, 0x8953,
+	0x5857, 0x8954, 0x5858, 0xCCC1, 0x5859, 0x8955, 0x585A, 0x8956,
+	0x585B, 0x8957, 0x585C, 0x8958, 0x585D, 0x8959, 0x585E, 0xC8FB,
+	0x585F, 0x895A, 0x5860, 0x895B, 0x5861, 0x895C, 0x5862, 0x895D,
+	0x5863, 0x895E, 0x5864, 0x895F, 0x5865, 0xDCAA, 0x5866, 0x8960,
+	0x5867, 0x8961, 0x5868, 0x8962, 0x5869, 0x8963, 0x586A, 0x8964,
+	0x586B, 0xCCEE, 0x586C, 0xDCAB, 0x586D, 0x8965, 0x586E, 0x8966,
+	0x586F, 0x8967, 0x5870, 0x8968, 0x5871, 0x8969, 0x5872, 0x896A,
+	0x5873, 0x896B, 0x5874, 0x896C, 0x5875, 0x896D, 0x5876, 0x896E,
+	0x5877, 0x896F, 0x5878, 0x8970, 0x5879, 0x8971, 0x587A, 0x8972,
+	0x587B, 0x8973, 0x587C, 0x8974, 0x587D, 0x8975, 0x587E, 0xDBD3,
+	0x587F, 0x8976, 0x5880, 0xDCAF, 0x5881, 0xDCAC, 0x5882, 0x8977,
+	0x5883, 0xBEB3, 0x5884, 0x8978, 0x5885, 0xCAFB, 0x5886, 0x8979,
+	0x5887, 0x897A, 0x5888, 0x897B, 0x5889, 0xDCAD, 0x588A, 0x897C,
+	0x588B, 0x897D, 0x588C, 0x897E, 0x588D, 0x8980, 0x588E, 0x8981,
+	0x588F, 0x8982, 0x5890, 0x8983, 0x5891, 0x8984, 0x5892, 0xC9CA,
+	0x5893, 0xC4B9, 0x5894, 0x8985, 0x5895, 0x8986, 0x5896, 0x8987,
+	0x5897, 0x8988, 0x5898, 0x8989, 0x5899, 0xC7BD, 0x589A, 0xDCAE,
+	0x589B, 0x898A, 0x589C, 0x898B, 0x589D, 0x898C, 0x589E, 0xD4F6,
+	0x589F, 0xD0E6, 0x58A0, 0x898D, 0x58A1, 0x898E, 0x58A2, 0x898F,
+	0x58A3, 0x8990, 0x58A4, 0x8991, 0x58A5, 0x8992, 0x58A6, 0x8993,
+	0x58A7, 0x8994, 0x58A8, 0xC4AB, 0x58A9, 0xB6D5, 0x58AA, 0x8995,
+	0x58AB, 0x8996, 0x58AC, 0x8997, 0x58AD, 0x8998, 0x58AE, 0x8999,
+	0x58AF, 0x899A, 0x58B0, 0x899B, 0x58B1, 0x899C, 0x58B2, 0x899D,
+	0x58B3, 0x899E, 0x58B4, 0x899F, 0x58B5, 0x89A0, 0x58B6, 0x89A1,
+	0x58B7, 0x89A2, 0x58B8, 0x89A3, 0x58B9, 0x89A4, 0x58BA, 0x89A5,
+	0x58BB, 0x89A6, 0x58BC, 0xDBD4, 0x58BD, 0x89A7, 0x58BE, 0x89A8,
+	0x58BF, 0x89A9, 0x58C0, 0x89AA, 0x58C1, 0xB1DA, 0x58C2, 0x89AB,
+	0x58C3, 0x89AC, 0x58C4, 0x89AD, 0x58C5, 0xDBD5, 0x58C6, 0x89AE,
+	0x58C7, 0x89AF, 0x58C8, 0x89B0, 0x58C9, 0x89B1, 0x58CA, 0x89B2,
+	0x58CB, 0x89B3, 0x58CC, 0x89B4, 0x58CD, 0x89B5, 0x58CE, 0x89B6,
+	0x58CF, 0x89B7, 0x58D0, 0x89B8, 0x58D1, 0xDBD6, 0x58D2, 0x89B9,
+	0x58D3, 0x89BA, 0x58D4, 0x89BB, 0x58D5, 0xBABE, 0x58D6, 0x89BC,
+	0x58D7, 0x89BD, 0x58D8, 0x89BE, 0x58D9, 0x89BF, 0x58DA, 0x89C0,
+	0x58DB, 0x89C1, 0x58DC, 0x89C2, 0x58DD, 0x89C3, 0x58DE, 0x89C4,
+	0x58DF, 0x89C5, 0x58E0, 0x89C6, 0x58E1, 0x89C7, 0x58E2, 0x89C8,
+	0x58E3, 0x89C9, 0x58E4, 0xC8C0, 0x58E5, 0x89CA, 0x58E6, 0x89CB,
+	0x58E7, 0x89CC, 0x58E8, 0x89CD, 0x58E9, 0x89CE, 0x58EA, 0x89CF,
+	0x58EB, 0xCABF, 0x58EC, 0xC8C9, 0x58ED, 0x89D0, 0x58EE, 0xD7B3,
+	0x58EF, 0x89D1, 0x58F0, 0xC9F9, 0x58F1, 0x89D2, 0x58F2, 0x89D3,
+	0x58F3, 0xBFC7, 0x58F4, 0x89D4, 0x58F5, 0x89D5, 0x58F6, 0xBAF8,
+	0x58F7, 0x89D6, 0x58F8, 0x89D7, 0x58F9, 0xD2BC, 0x58FA, 0x89D8,
+	0x58FB, 0x89D9, 0x58FC, 0x89DA, 0x58FD, 0x89DB, 0x58FE, 0x89DC,
+	0x58FF, 0x89DD, 0x5900, 0x89DE, 0x5901, 0x89DF, 0x5902, 0xE2BA,
+	0x5903, 0x89E0, 0x5904, 0xB4A6, 0x5905, 0x89E1, 0x5906, 0x89E2,
+	0x5907, 0xB1B8, 0x5908, 0x89E3, 0x5909, 0x89E4, 0x590A, 0x89E5,
+	0x590B, 0x89E6, 0x590C, 0x89E7, 0x590D, 0xB8B4, 0x590E, 0x89E8,
+	0x590F, 0xCFC4, 0x5910, 0x89E9, 0x5911, 0x89EA, 0x5912, 0x89EB,
+	0x5913, 0x89EC, 0x5914, 0xD9E7, 0x5915, 0xCFA6, 0x5916, 0xCDE2,
+	0x5917, 0x89ED, 0x5918, 0x89EE, 0x5919, 0xD9ED, 0x591A, 0xB6E0,
+	0x591B, 0x89EF, 0x591C, 0xD2B9, 0x591D, 0x89F0, 0x591E, 0x89F1,
+	0x591F, 0xB9BB, 0x5920, 0x89F2, 0x5921, 0x89F3, 0x5922, 0x89F4,
+	0x5923, 0x89F5, 0x5924, 0xE2B9, 0x5925, 0xE2B7, 0x5926, 0x89F6,
+	0x5927, 0xB4F3, 0x5928, 0x89F7, 0x5929, 0xCCEC, 0x592A, 0xCCAB,
+	0x592B, 0xB7F2, 0x592C, 0x89F8, 0x592D, 0xD8B2, 0x592E, 0xD1EB,
+	0x592F, 0xBABB, 0x5930, 0x89F9, 0x5931, 0xCAA7, 0x5932, 0x89FA,
+	0x5933, 0x89FB, 0x5934, 0xCDB7, 0x5935, 0x89FC, 0x5936, 0x89FD,
+	0x5937, 0xD2C4, 0x5938, 0xBFE4, 0x5939, 0xBCD0, 0x593A, 0xB6E1,
+	0x593B, 0x89FE, 0x593C, 0xDEC5, 0x593D, 0x8A40, 0x593E, 0x8A41,
+	0x593F, 0x8A42, 0x5940, 0x8A43, 0x5941, 0xDEC6, 0x5942, 0xDBBC,
+	0x5943, 0x8A44, 0x5944, 0xD1D9, 0x5945, 0x8A45, 0x5946, 0x8A46,
+	0x5947, 0xC6E6, 0x5948, 0xC4CE, 0x5949, 0xB7EE, 0x594A, 0x8A47,
+	0x594B, 0xB7DC, 0x594C, 0x8A48, 0x594D, 0x8A49, 0x594E, 0xBFFC,
+	0x594F, 0xD7E0, 0x5950, 0x8A4A, 0x5951, 0xC6F5, 0x5952, 0x8A4B,
+	0x5953, 0x8A4C, 0x5954, 0xB1BC, 0x5955, 0xDEC8, 0x5956, 0xBDB1,
+	0x5957, 0xCCD7, 0x5958, 0xDECA, 0x5959, 0x8A4D, 0x595A, 0xDEC9,
+	0x595B, 0x8A4E, 0x595C, 0x8A4F, 0x595D, 0x8A50, 0x595E, 0x8A51,
+	0x595F, 0x8A52, 0x5960, 0xB5EC, 0x5961, 0x8A53, 0x5962, 0xC9DD,
+	0x5963, 0x8A54, 0x5964, 0x8A55, 0x5965, 0xB0C2, 0x5966, 0x8A56,
+	0x5967, 0x8A57, 0x5968, 0x8A58, 0x5969, 0x8A59, 0x596A, 0x8A5A,
+	0x596B, 0x8A5B, 0x596C, 0x8A5C, 0x596D, 0x8A5D, 0x596E, 0x8A5E,
+	0x596F, 0x8A5F, 0x5970, 0x8A60, 0x5971, 0x8A61, 0x5972, 0x8A62,
+	0x5973, 0xC5AE, 0x5974, 0xC5AB, 0x5975, 0x8A63, 0x5976, 0xC4CC,
+	0x5977, 0x8A64, 0x5978, 0xBCE9, 0x5979, 0xCBFD, 0x597A, 0x8A65,
+	0x597B, 0x8A66, 0x597C, 0x8A67, 0x597D, 0xBAC3, 0x597E, 0x8A68,
+	0x597F, 0x8A69, 0x5980, 0x8A6A, 0x5981, 0xE5F9, 0x5982, 0xC8E7,
+	0x5983, 0xE5FA, 0x5984, 0xCDFD, 0x5985, 0x8A6B, 0x5986, 0xD7B1,
+	0x5987, 0xB8BE, 0x5988, 0xC2E8, 0x5989, 0x8A6C, 0x598A, 0xC8D1,
+	0x598B, 0x8A6D, 0x598C, 0x8A6E, 0x598D, 0xE5FB, 0x598E, 0x8A6F,
+	0x598F, 0x8A70, 0x5990, 0x8A71, 0x5991, 0x8A72, 0x5992, 0xB6CA,
+	0x5993, 0xBCCB, 0x5994, 0x8A73, 0x5995, 0x8A74, 0x5996, 0xD1FD,
+	0x5997, 0xE6A1, 0x5998, 0x8A75, 0x5999, 0xC3EE, 0x599A, 0x8A76,
+	0x599B, 0x8A77, 0x599C, 0x8A78, 0x599D, 0x8A79, 0x599E, 0xE6A4,
+	0x599F, 0x8A7A, 0x59A0, 0x8A7B, 0x59A1, 0x8A7C, 0x59A2, 0x8A7D,
+	0x59A3, 0xE5FE, 0x59A4, 0xE6A5, 0x59A5, 0xCDD7, 0x59A6, 0x8A7E,
+	0x59A7, 0x8A80, 0x59A8, 0xB7C1, 0x59A9, 0xE5FC, 0x59AA, 0xE5FD,
+	0x59AB, 0xE6A3, 0x59AC, 0x8A81, 0x59AD, 0x8A82, 0x59AE, 0xC4DD,
+	0x59AF, 0xE6A8, 0x59B0, 0x8A83, 0x59B1, 0x8A84, 0x59B2, 0xE6A7,
+	0x59B3, 0x8A85, 0x59B4, 0x8A86, 0x59B5, 0x8A87, 0x59B6, 0x8A88,
+	0x59B7, 0x8A89, 0x59B8, 0x8A8A, 0x59B9, 0xC3C3, 0x59BA, 0x8A8B,
+	0x59BB, 0xC6DE, 0x59BC, 0x8A8C, 0x59BD, 0x8A8D, 0x59BE, 0xE6AA,
+	0x59BF, 0x8A8E, 0x59C0, 0x8A8F, 0x59C1, 0x8A90, 0x59C2, 0x8A91,
+	0x59C3, 0x8A92, 0x59C4, 0x8A93, 0x59C5, 0x8A94, 0x59C6, 0xC4B7,
+	0x59C7, 0x8A95, 0x59C8, 0x8A96, 0x59C9, 0x8A97, 0x59CA, 0xE6A2,
+	0x59CB, 0xCABC, 0x59CC, 0x8A98, 0x59CD, 0x8A99, 0x59CE, 0x8A9A,
+	0x59CF, 0x8A9B, 0x59D0, 0xBDE3, 0x59D1, 0xB9C3, 0x59D2, 0xE6A6,
+	0x59D3, 0xD0D5, 0x59D4, 0xCEAF, 0x59D5, 0x8A9C, 0x59D6, 0x8A9D,
+	0x59D7, 0xE6A9, 0x59D8, 0xE6B0, 0x59D9, 0x8A9E, 0x59DA, 0xD2A6,
+	0x59DB, 0x8A9F, 0x59DC, 0xBDAA, 0x59DD, 0xE6AD, 0x59DE, 0x8AA0,
+	0x59DF, 0x8AA1, 0x59E0, 0x8AA2, 0x59E1, 0x8AA3, 0x59E2, 0x8AA4,
+	0x59E3, 0xE6AF, 0x59E4, 0x8AA5, 0x59E5, 0xC0D1, 0x59E6, 0x8AA6,
+	0x59E7, 0x8AA7, 0x59E8, 0xD2CC, 0x59E9, 0x8AA8, 0x59EA, 0x8AA9,
+	0x59EB, 0x8AAA, 0x59EC, 0xBCA7, 0x59ED, 0x8AAB, 0x59EE, 0x8AAC,
+	0x59EF, 0x8AAD, 0x59F0, 0x8AAE, 0x59F1, 0x8AAF, 0x59F2, 0x8AB0,
+	0x59F3, 0x8AB1, 0x59F4, 0x8AB2, 0x59F5, 0x8AB3, 0x59F6, 0x8AB4,
+	0x59F7, 0x8AB5, 0x59F8, 0x8AB6, 0x59F9, 0xE6B1, 0x59FA, 0x8AB7,
+	0x59FB, 0xD2F6, 0x59FC, 0x8AB8, 0x59FD, 0x8AB9, 0x59FE, 0x8ABA,
+	0x59FF, 0xD7CB, 0x5A00, 0x8ABB, 0x5A01, 0xCDFE, 0x5A02, 0x8ABC,
+	0x5A03, 0xCDDE, 0x5A04, 0xC2A6, 0x5A05, 0xE6AB, 0x5A06, 0xE6AC,
+	0x5A07, 0xBDBF, 0x5A08, 0xE6AE, 0x5A09, 0xE6B3, 0x5A0A, 0x8ABD,
+	0x5A0B, 0x8ABE, 0x5A0C, 0xE6B2, 0x5A0D, 0x8ABF, 0x5A0E, 0x8AC0,
+	0x5A0F, 0x8AC1, 0x5A10, 0x8AC2, 0x5A11, 0xE6B6, 0x5A12, 0x8AC3,
+	0x5A13, 0xE6B8, 0x5A14, 0x8AC4, 0x5A15, 0x8AC5, 0x5A16, 0x8AC6,
+	0x5A17, 0x8AC7, 0x5A18, 0xC4EF, 0x5A19, 0x8AC8, 0x5A1A, 0x8AC9,
+	0x5A1B, 0x8ACA, 0x5A1C, 0xC4C8, 0x5A1D, 0x8ACB, 0x5A1E, 0x8ACC,
+	0x5A1F, 0xBEEA, 0x5A20, 0xC9EF, 0x5A21, 0x8ACD, 0x5A22, 0x8ACE,
+	0x5A23, 0xE6B7, 0x5A24, 0x8ACF, 0x5A25, 0xB6F0, 0x5A26, 0x8AD0,
+	0x5A27, 0x8AD1, 0x5A28, 0x8AD2, 0x5A29, 0xC3E4, 0x5A2A, 0x8AD3,
+	0x5A2B, 0x8AD4, 0x5A2C, 0x8AD5, 0x5A2D, 0x8AD6, 0x5A2E, 0x8AD7,
+	0x5A2F, 0x8AD8, 0x5A30, 0x8AD9, 0x5A31, 0xD3E9, 0x5A32, 0xE6B4,
+	0x5A33, 0x8ADA, 0x5A34, 0xE6B5, 0x5A35, 0x8ADB, 0x5A36, 0xC8A2,
+	0x5A37, 0x8ADC, 0x5A38, 0x8ADD, 0x5A39, 0x8ADE, 0x5A3A, 0x8ADF,
+	0x5A3B, 0x8AE0, 0x5A3C, 0xE6BD, 0x5A3D, 0x8AE1, 0x5A3E, 0x8AE2,
+	0x5A3F, 0x8AE3, 0x5A40, 0xE6B9, 0x5A41, 0x8AE4, 0x5A42, 0x8AE5,
+	0x5A43, 0x8AE6, 0x5A44, 0x8AE7, 0x5A45, 0x8AE8, 0x5A46, 0xC6C5,
+	0x5A47, 0x8AE9, 0x5A48, 0x8AEA, 0x5A49, 0xCDF1, 0x5A4A, 0xE6BB,
+	0x5A4B, 0x8AEB, 0x5A4C, 0x8AEC, 0x5A4D, 0x8AED, 0x5A4E, 0x8AEE,
+	0x5A4F, 0x8AEF, 0x5A50, 0x8AF0, 0x5A51, 0x8AF1, 0x5A52, 0x8AF2,
+	0x5A53, 0x8AF3, 0x5A54, 0x8AF4, 0x5A55, 0xE6BC, 0x5A56, 0x8AF5,
+	0x5A57, 0x8AF6, 0x5A58, 0x8AF7, 0x5A59, 0x8AF8, 0x5A5A, 0xBBE9,
+	0x5A5B, 0x8AF9, 0x5A5C, 0x8AFA, 0x5A5D, 0x8AFB, 0x5A5E, 0x8AFC,
+	0x5A5F, 0x8AFD, 0x5A60, 0x8AFE, 0x5A61, 0x8B40, 0x5A62, 0xE6BE,
+	0x5A63, 0x8B41, 0x5A64, 0x8B42, 0x5A65, 0x8B43, 0x5A66, 0x8B44,
+	0x5A67, 0xE6BA, 0x5A68, 0x8B45, 0x5A69, 0x8B46, 0x5A6A, 0xC0B7,
+	0x5A6B, 0x8B47, 0x5A6C, 0x8B48, 0x5A6D, 0x8B49, 0x5A6E, 0x8B4A,
+	0x5A6F, 0x8B4B, 0x5A70, 0x8B4C, 0x5A71, 0x8B4D, 0x5A72, 0x8B4E,
+	0x5A73, 0x8B4F, 0x5A74, 0xD3A4, 0x5A75, 0xE6BF, 0x5A76, 0xC9F4,
+	0x5A77, 0xE6C3, 0x5A78, 0x8B50, 0x5A79, 0x8B51, 0x5A7A, 0xE6C4,
+	0x5A7B, 0x8B52, 0x5A7C, 0x8B53, 0x5A7D, 0x8B54, 0x5A7E, 0x8B55,
+	0x5A7F, 0xD0F6, 0x5A80, 0x8B56, 0x5A81, 0x8B57, 0x5A82, 0x8B58,
+	0x5A83, 0x8B59, 0x5A84, 0x8B5A, 0x5A85, 0x8B5B, 0x5A86, 0x8B5C,
+	0x5A87, 0x8B5D, 0x5A88, 0x8B5E, 0x5A89, 0x8B5F, 0x5A8A, 0x8B60,
+	0x5A8B, 0x8B61, 0x5A8C, 0x8B62, 0x5A8D, 0x8B63, 0x5A8E, 0x8B64,
+	0x5A8F, 0x8B65, 0x5A90, 0x8B66, 0x5A91, 0x8B67, 0x5A92, 0xC3BD,
+	0x5A93, 0x8B68, 0x5A94, 0x8B69, 0x5A95, 0x8B6A, 0x5A96, 0x8B6B,
+	0x5A97, 0x8B6C, 0x5A98, 0x8B6D, 0x5A99, 0x8B6E, 0x5A9A, 0xC3C4,
+	0x5A9B, 0xE6C2, 0x5A9C, 0x8B6F, 0x5A9D, 0x8B70, 0x5A9E, 0x8B71,
+	0x5A9F, 0x8B72, 0x5AA0, 0x8B73, 0x5AA1, 0x8B74, 0x5AA2, 0x8B75,
+	0x5AA3, 0x8B76, 0x5AA4, 0x8B77, 0x5AA5, 0x8B78, 0x5AA6, 0x8B79,
+	0x5AA7, 0x8B7A, 0x5AA8, 0x8B7B, 0x5AA9, 0x8B7C, 0x5AAA, 0xE6C1,
+	0x5AAB, 0x8B7D, 0x5AAC, 0x8B7E, 0x5AAD, 0x8B80, 0x5AAE, 0x8B81,
+	0x5AAF, 0x8B82, 0x5AB0, 0x8B83, 0x5AB1, 0x8B84, 0x5AB2, 0xE6C7,
+	0x5AB3, 0xCFB1, 0x5AB4, 0x8B85, 0x5AB5, 0xEBF4, 0x5AB6, 0x8B86,
+	0x5AB7, 0x8B87, 0x5AB8, 0xE6CA, 0x5AB9, 0x8B88, 0x5ABA, 0x8B89,
+	0x5ABB, 0x8B8A, 0x5ABC, 0x8B8B, 0x5ABD, 0x8B8C, 0x5ABE, 0xE6C5,
+	0x5ABF, 0x8B8D, 0x5AC0, 0x8B8E, 0x5AC1, 0xBCDE, 0x5AC2, 0xC9A9,
+	0x5AC3, 0x8B8F, 0x5AC4, 0x8B90, 0x5AC5, 0x8B91, 0x5AC6, 0x8B92,
+	0x5AC7, 0x8B93, 0x5AC8, 0x8B94, 0x5AC9, 0xBCB5, 0x5ACA, 0x8B95,
+	0x5ACB, 0x8B96, 0x5ACC, 0xCFD3, 0x5ACD, 0x8B97, 0x5ACE, 0x8B98,
+	0x5ACF, 0x8B99, 0x5AD0, 0x8B9A, 0x5AD1, 0x8B9B, 0x5AD2, 0xE6C8,
+	0x5AD3, 0x8B9C, 0x5AD4, 0xE6C9, 0x5AD5, 0x8B9D, 0x5AD6, 0xE6CE,
+	0x5AD7, 0x8B9E, 0x5AD8, 0xE6D0, 0x5AD9, 0x8B9F, 0x5ADA, 0x8BA0,
+	0x5ADB, 0x8BA1, 0x5ADC, 0xE6D1, 0x5ADD, 0x8BA2, 0x5ADE, 0x8BA3,
+	0x5ADF, 0x8BA4, 0x5AE0, 0xE6CB, 0x5AE1, 0xB5D5, 0x5AE2, 0x8BA5,
+	0x5AE3, 0xE6CC, 0x5AE4, 0x8BA6, 0x5AE5, 0x8BA7, 0x5AE6, 0xE6CF,
+	0x5AE7, 0x8BA8, 0x5AE8, 0x8BA9, 0x5AE9, 0xC4DB, 0x5AEA, 0x8BAA,
+	0x5AEB, 0xE6C6, 0x5AEC, 0x8BAB, 0x5AED, 0x8BAC, 0x5AEE, 0x8BAD,
+	0x5AEF, 0x8BAE, 0x5AF0, 0x8BAF, 0x5AF1, 0xE6CD, 0x5AF2, 0x8BB0,
+	0x5AF3, 0x8BB1, 0x5AF4, 0x8BB2, 0x5AF5, 0x8BB3, 0x5AF6, 0x8BB4,
+	0x5AF7, 0x8BB5, 0x5AF8, 0x8BB6, 0x5AF9, 0x8BB7, 0x5AFA, 0x8BB8,
+	0x5AFB, 0x8BB9, 0x5AFC, 0x8BBA, 0x5AFD, 0x8BBB, 0x5AFE, 0x8BBC,
+	0x5AFF, 0x8BBD, 0x5B00, 0x8BBE, 0x5B01, 0x8BBF, 0x5B02, 0x8BC0,
+	0x5B03, 0x8BC1, 0x5B04, 0x8BC2, 0x5B05, 0x8BC3, 0x5B06, 0x8BC4,
+	0x5B07, 0x8BC5, 0x5B08, 0x8BC6, 0x5B09, 0xE6D2, 0x5B0A, 0x8BC7,
+	0x5B0B, 0x8BC8, 0x5B0C, 0x8BC9, 0x5B0D, 0x8BCA, 0x5B0E, 0x8BCB,
+	0x5B0F, 0x8BCC, 0x5B10, 0x8BCD, 0x5B11, 0x8BCE, 0x5B12, 0x8BCF,
+	0x5B13, 0x8BD0, 0x5B14, 0x8BD1, 0x5B15, 0x8BD2, 0x5B16, 0xE6D4,
+	0x5B17, 0xE6D3, 0x5B18, 0x8BD3, 0x5B19, 0x8BD4, 0x5B1A, 0x8BD5,
+	0x5B1B, 0x8BD6, 0x5B1C, 0x8BD7, 0x5B1D, 0x8BD8, 0x5B1E, 0x8BD9,
+	0x5B1F, 0x8BDA, 0x5B20, 0x8BDB, 0x5B21, 0x8BDC, 0x5B22, 0x8BDD,
+	0x5B23, 0x8BDE, 0x5B24, 0x8BDF, 0x5B25, 0x8BE0, 0x5B26, 0x8BE1,
+	0x5B27, 0x8BE2, 0x5B28, 0x8BE3, 0x5B29, 0x8BE4, 0x5B2A, 0x8BE5,
+	0x5B2B, 0x8BE6, 0x5B2C, 0x8BE7, 0x5B2D, 0x8BE8, 0x5B2E, 0x8BE9,
+	0x5B2F, 0x8BEA, 0x5B30, 0x8BEB, 0x5B31, 0x8BEC, 0x5B32, 0xE6D5,
+	0x5B33, 0x8BED, 0x5B34, 0xD9F8, 0x5B35, 0x8BEE, 0x5B36, 0x8BEF,
+	0x5B37, 0xE6D6, 0x5B38, 0x8BF0, 0x5B39, 0x8BF1, 0x5B3A, 0x8BF2,
+	0x5B3B, 0x8BF3, 0x5B3C, 0x8BF4, 0x5B3D, 0x8BF5, 0x5B3E, 0x8BF6,
+	0x5B3F, 0x8BF7, 0x5B40, 0xE6D7, 0x5B41, 0x8BF8, 0x5B42, 0x8BF9,
+	0x5B43, 0x8BFA, 0x5B44, 0x8BFB, 0x5B45, 0x8BFC, 0x5B46, 0x8BFD,
+	0x5B47, 0x8BFE, 0x5B48, 0x8C40, 0x5B49, 0x8C41, 0x5B4A, 0x8C42,
+	0x5B4B, 0x8C43, 0x5B4C, 0x8C44, 0x5B4D, 0x8C45, 0x5B4E, 0x8C46,
+	0x5B4F, 0x8C47, 0x5B50, 0xD7D3, 0x5B51, 0xE6DD, 0x5B52, 0x8C48,
+	0x5B53, 0xE6DE, 0x5B54, 0xBFD7, 0x5B55, 0xD4D0, 0x5B56, 0x8C49,
+	0x5B57, 0xD7D6, 0x5B58, 0xB4E6, 0x5B59, 0xCBEF, 0x5B5A, 0xE6DA,
+	0x5B5B, 0xD8C3, 0x5B5C, 0xD7CE, 0x5B5D, 0xD0A2, 0x5B5E, 0x8C4A,
+	0x5B5F, 0xC3CF, 0x5B60, 0x8C4B, 0x5B61, 0x8C4C, 0x5B62, 0xE6DF,
+	0x5B63, 0xBCBE, 0x5B64, 0xB9C2, 0x5B65, 0xE6DB, 0x5B66, 0xD1A7,
+	0x5B67, 0x8C4D, 0x5B68, 0x8C4E, 0x5B69, 0xBAA2, 0x5B6A, 0xC2CF,
+	0x5B6B, 0x8C4F, 0x5B6C, 0xD8AB, 0x5B6D, 0x8C50, 0x5B6E, 0x8C51,
+	0x5B6F, 0x8C52, 0x5B70, 0xCAEB, 0x5B71, 0xE5EE, 0x5B72, 0x8C53,
+	0x5B73, 0xE6DC, 0x5B74, 0x8C54, 0x5B75, 0xB7F5, 0x5B76, 0x8C55,
+	0x5B77, 0x8C56, 0x5B78, 0x8C57, 0x5B79, 0x8C58, 0x5B7A, 0xC8E6,
+	0x5B7B, 0x8C59, 0x5B7C, 0x8C5A, 0x5B7D, 0xC4F5, 0x5B7E, 0x8C5B,
+	0x5B7F, 0x8C5C, 0x5B80, 0xE5B2, 0x5B81, 0xC4FE, 0x5B82, 0x8C5D,
+	0x5B83, 0xCBFC, 0x5B84, 0xE5B3, 0x5B85, 0xD5AC, 0x5B86, 0x8C5E,
+	0x5B87, 0xD3EE, 0x5B88, 0xCAD8, 0x5B89, 0xB0B2, 0x5B8A, 0x8C5F,
+	0x5B8B, 0xCBCE, 0x5B8C, 0xCDEA, 0x5B8D, 0x8C60, 0x5B8E, 0x8C61,
+	0x5B8F, 0xBAEA, 0x5B90, 0x8C62, 0x5B91, 0x8C63, 0x5B92, 0x8C64,
+	0x5B93, 0xE5B5, 0x5B94, 0x8C65, 0x5B95, 0xE5B4, 0x5B96, 0x8C66,
+	0x5B97, 0xD7DA, 0x5B98, 0xB9D9, 0x5B99, 0xD6E6, 0x5B9A, 0xB6A8,
+	0x5B9B, 0xCDF0, 0x5B9C, 0xD2CB, 0x5B9D, 0xB1A6, 0x5B9E, 0xCAB5,
+	0x5B9F, 0x8C67, 0x5BA0, 0xB3E8, 0x5BA1, 0xC9F3, 0x5BA2, 0xBFCD,
+	0x5BA3, 0xD0FB, 0x5BA4, 0xCAD2, 0x5BA5, 0xE5B6, 0x5BA6, 0xBBC2,
+	0x5BA7, 0x8C68, 0x5BA8, 0x8C69, 0x5BA9, 0x8C6A, 0x5BAA, 0xCFDC,
+	0x5BAB, 0xB9AC, 0x5BAC, 0x8C6B, 0x5BAD, 0x8C6C, 0x5BAE, 0x8C6D,
+	0x5BAF, 0x8C6E, 0x5BB0, 0xD4D7, 0x5BB1, 0x8C6F, 0x5BB2, 0x8C70,
+	0x5BB3, 0xBAA6, 0x5BB4, 0xD1E7, 0x5BB5, 0xCFFC, 0x5BB6, 0xBCD2,
+	0x5BB7, 0x8C71, 0x5BB8, 0xE5B7, 0x5BB9, 0xC8DD, 0x5BBA, 0x8C72,
+	0x5BBB, 0x8C73, 0x5BBC, 0x8C74, 0x5BBD, 0xBFED, 0x5BBE, 0xB1F6,
+	0x5BBF, 0xCBDE, 0x5BC0, 0x8C75, 0x5BC1, 0x8C76, 0x5BC2, 0xBCC5,
+	0x5BC3, 0x8C77, 0x5BC4, 0xBCC4, 0x5BC5, 0xD2FA, 0x5BC6, 0xC3DC,
+	0x5BC7, 0xBFDC, 0x5BC8, 0x8C78, 0x5BC9, 0x8C79, 0x5BCA, 0x8C7A,
+	0x5BCB, 0x8C7B, 0x5BCC, 0xB8BB, 0x5BCD, 0x8C7C, 0x5BCE, 0x8C7D,
+	0x5BCF, 0x8C7E, 0x5BD0, 0xC3C2, 0x5BD1, 0x8C80, 0x5BD2, 0xBAAE,
+	0x5BD3, 0xD4A2, 0x5BD4, 0x8C81, 0x5BD5, 0x8C82, 0x5BD6, 0x8C83,
+	0x5BD7, 0x8C84, 0x5BD8, 0x8C85, 0x5BD9, 0x8C86, 0x5BDA, 0x8C87,
+	0x5BDB, 0x8C88, 0x5BDC, 0x8C89, 0x5BDD, 0xC7DE, 0x5BDE, 0xC4AF,
+	0x5BDF, 0xB2EC, 0x5BE0, 0x8C8A, 0x5BE1, 0xB9D1, 0x5BE2, 0x8C8B,
+	0x5BE3, 0x8C8C, 0x5BE4, 0xE5BB, 0x5BE5, 0xC1C8, 0x5BE6, 0x8C8D,
+	0x5BE7, 0x8C8E, 0x5BE8, 0xD5AF, 0x5BE9, 0x8C8F, 0x5BEA, 0x8C90,
+	0x5BEB, 0x8C91, 0x5BEC, 0x8C92, 0x5BED, 0x8C93, 0x5BEE, 0xE5BC,
+	0x5BEF, 0x8C94, 0x5BF0, 0xE5BE, 0x5BF1, 0x8C95, 0x5BF2, 0x8C96,
+	0x5BF3, 0x8C97, 0x5BF4, 0x8C98, 0x5BF5, 0x8C99, 0x5BF6, 0x8C9A,
+	0x5BF7, 0x8C9B, 0x5BF8, 0xB4E7, 0x5BF9, 0xB6D4, 0x5BFA, 0xCBC2,
+	0x5BFB, 0xD1B0, 0x5BFC, 0xB5BC, 0x5BFD, 0x8C9C, 0x5BFE, 0x8C9D,
+	0x5BFF, 0xCAD9, 0x5C00, 0x8C9E, 0x5C01, 0xB7E2, 0x5C02, 0x8C9F,
+	0x5C03, 0x8CA0, 0x5C04, 0xC9E4, 0x5C05, 0x8CA1, 0x5C06, 0xBDAB,
+	0x5C07, 0x8CA2, 0x5C08, 0x8CA3, 0x5C09, 0xCEBE, 0x5C0A, 0xD7F0,
+	0x5C0B, 0x8CA4, 0x5C0C, 0x8CA5, 0x5C0D, 0x8CA6, 0x5C0E, 0x8CA7,
+	0x5C0F, 0xD0A1, 0x5C10, 0x8CA8, 0x5C11, 0xC9D9, 0x5C12, 0x8CA9,
+	0x5C13, 0x8CAA, 0x5C14, 0xB6FB, 0x5C15, 0xE6D8, 0x5C16, 0xBCE2,
+	0x5C17, 0x8CAB, 0x5C18, 0xB3BE, 0x5C19, 0x8CAC, 0x5C1A, 0xC9D0,
+	0x5C1B, 0x8CAD, 0x5C1C, 0xE6D9, 0x5C1D, 0xB3A2, 0x5C1E, 0x8CAE,
+	0x5C1F, 0x8CAF, 0x5C20, 0x8CB0, 0x5C21, 0x8CB1, 0x5C22, 0xDECC,
+	0x5C23, 0x8CB2, 0x5C24, 0xD3C8, 0x5C25, 0xDECD, 0x5C26, 0x8CB3,
+	0x5C27, 0xD2A2, 0x5C28, 0x8CB4, 0x5C29, 0x8CB5, 0x5C2A, 0x8CB6,
+	0x5C2B, 0x8CB7, 0x5C2C, 0xDECE, 0x5C2D, 0x8CB8, 0x5C2E, 0x8CB9,
+	0x5C2F, 0x8CBA, 0x5C30, 0x8CBB, 0x5C31, 0xBECD, 0x5C32, 0x8CBC,
+	0x5C33, 0x8CBD, 0x5C34, 0xDECF, 0x5C35, 0x8CBE, 0x5C36, 0x8CBF,
+	0x5C37, 0x8CC0, 0x5C38, 0xCAAC, 0x5C39, 0xD2FC, 0x5C3A, 0xB3DF,
+	0x5C3B, 0xE5EA, 0x5C3C, 0xC4E1, 0x5C3D, 0xBEA1, 0x5C3E, 0xCEB2,
+	0x5C3F, 0xC4F2, 0x5C40, 0xBED6, 0x5C41, 0xC6A8, 0x5C42, 0xB2E3,
+	0x5C43, 0x8CC1, 0x5C44, 0x8CC2, 0x5C45, 0xBED3, 0x5C46, 0x8CC3,
+	0x5C47, 0x8CC4, 0x5C48, 0xC7FC, 0x5C49, 0xCCEB, 0x5C4A, 0xBDEC,
+	0x5C4B, 0xCEDD, 0x5C4C, 0x8CC5, 0x5C4D, 0x8CC6, 0x5C4E, 0xCABA,
+	0x5C4F, 0xC6C1, 0x5C50, 0xE5EC, 0x5C51, 0xD0BC, 0x5C52, 0x8CC7,
+	0x5C53, 0x8CC8, 0x5C54, 0x8CC9, 0x5C55, 0xD5B9, 0x5C56, 0x8CCA,
+	0x5C57, 0x8CCB, 0x5C58, 0x8CCC, 0x5C59, 0xE5ED, 0x5C5A, 0x8CCD,
+	0x5C5B, 0x8CCE, 0x5C5C, 0x8CCF, 0x5C5D, 0x8CD0, 0x5C5E, 0xCAF4,
+	0x5C5F, 0x8CD1, 0x5C60, 0xCDC0, 0x5C61, 0xC2C5, 0x5C62, 0x8CD2,
+	0x5C63, 0xE5EF, 0x5C64, 0x8CD3, 0x5C65, 0xC2C4, 0x5C66, 0xE5F0,
+	0x5C67, 0x8CD4, 0x5C68, 0x8CD5, 0x5C69, 0x8CD6, 0x5C6A, 0x8CD7,
+	0x5C6B, 0x8CD8, 0x5C6C, 0x8CD9, 0x5C6D, 0x8CDA, 0x5C6E, 0xE5F8,
+	0x5C6F, 0xCDCD, 0x5C70, 0x8CDB, 0x5C71, 0xC9BD, 0x5C72, 0x8CDC,
+	0x5C73, 0x8CDD, 0x5C74, 0x8CDE, 0x5C75, 0x8CDF, 0x5C76, 0x8CE0,
+	0x5C77, 0x8CE1, 0x5C78, 0x8CE2, 0x5C79, 0xD2D9, 0x5C7A, 0xE1A8,
+	0x5C7B, 0x8CE3, 0x5C7C, 0x8CE4, 0x5C7D, 0x8CE5, 0x5C7E, 0x8CE6,
+	0x5C7F, 0xD3EC, 0x5C80, 0x8CE7, 0x5C81, 0xCBEA, 0x5C82, 0xC6F1,
+	0x5C83, 0x8CE8, 0x5C84, 0x8CE9, 0x5C85, 0x8CEA, 0x5C86, 0x8CEB,
+	0x5C87, 0x8CEC, 0x5C88, 0xE1AC, 0x5C89, 0x8CED, 0x5C8A, 0x8CEE,
+	0x5C8B, 0x8CEF, 0x5C8C, 0xE1A7, 0x5C8D, 0xE1A9, 0x5C8E, 0x8CF0,
+	0x5C8F, 0x8CF1, 0x5C90, 0xE1AA, 0x5C91, 0xE1AF, 0x5C92, 0x8CF2,
+	0x5C93, 0x8CF3, 0x5C94, 0xB2ED, 0x5C95, 0x8CF4, 0x5C96, 0xE1AB,
+	0x5C97, 0xB8DA, 0x5C98, 0xE1AD, 0x5C99, 0xE1AE, 0x5C9A, 0xE1B0,
+	0x5C9B, 0xB5BA, 0x5C9C, 0xE1B1, 0x5C9D, 0x8CF5, 0x5C9E, 0x8CF6,
+	0x5C9F, 0x8CF7, 0x5CA0, 0x8CF8, 0x5CA1, 0x8CF9, 0x5CA2, 0xE1B3,
+	0x5CA3, 0xE1B8, 0x5CA4, 0x8CFA, 0x5CA5, 0x8CFB, 0x5CA6, 0x8CFC,
+	0x5CA7, 0x8CFD, 0x5CA8, 0x8CFE, 0x5CA9, 0xD1D2, 0x5CAA, 0x8D40,
+	0x5CAB, 0xE1B6, 0x5CAC, 0xE1B5, 0x5CAD, 0xC1EB, 0x5CAE, 0x8D41,
+	0x5CAF, 0x8D42, 0x5CB0, 0x8D43, 0x5CB1, 0xE1B7, 0x5CB2, 0x8D44,
+	0x5CB3, 0xD4C0, 0x5CB4, 0x8D45, 0x5CB5, 0xE1B2, 0x5CB6, 0x8D46,
+	0x5CB7, 0xE1BA, 0x5CB8, 0xB0B6, 0x5CB9, 0x8D47, 0x5CBA, 0x8D48,
+	0x5CBB, 0x8D49, 0x5CBC, 0x8D4A, 0x5CBD, 0xE1B4, 0x5CBE, 0x8D4B,
+	0x5CBF, 0xBFF9, 0x5CC0, 0x8D4C, 0x5CC1, 0xE1B9, 0x5CC2, 0x8D4D,
+	0x5CC3, 0x8D4E, 0x5CC4, 0xE1BB, 0x5CC5, 0x8D4F, 0x5CC6, 0x8D50,
+	0x5CC7, 0x8D51, 0x5CC8, 0x8D52, 0x5CC9, 0x8D53, 0x5CCA, 0x8D54,
+	0x5CCB, 0xE1BE, 0x5CCC, 0x8D55, 0x5CCD, 0x8D56, 0x5CCE, 0x8D57,
+	0x5CCF, 0x8D58, 0x5CD0, 0x8D59, 0x5CD1, 0x8D5A, 0x5CD2, 0xE1BC,
+	0x5CD3, 0x8D5B, 0x5CD4, 0x8D5C, 0x5CD5, 0x8D5D, 0x5CD6, 0x8D5E,
+	0x5CD7, 0x8D5F, 0x5CD8, 0x8D60, 0x5CD9, 0xD6C5, 0x5CDA, 0x8D61,
+	0x5CDB, 0x8D62, 0x5CDC, 0x8D63, 0x5CDD, 0x8D64, 0x5CDE, 0x8D65,
+	0x5CDF, 0x8D66, 0x5CE0, 0x8D67, 0x5CE1, 0xCFBF, 0x5CE2, 0x8D68,
+	0x5CE3, 0x8D69, 0x5CE4, 0xE1BD, 0x5CE5, 0xE1BF, 0x5CE6, 0xC2CD,
+	0x5CE7, 0x8D6A, 0x5CE8, 0xB6EB, 0x5CE9, 0x8D6B, 0x5CEA, 0xD3F8,
+	0x5CEB, 0x8D6C, 0x5CEC, 0x8D6D, 0x5CED, 0xC7CD, 0x5CEE, 0x8D6E,
+	0x5CEF, 0x8D6F, 0x5CF0, 0xB7E5, 0x5CF1, 0x8D70, 0x5CF2, 0x8D71,
+	0x5CF3, 0x8D72, 0x5CF4, 0x8D73, 0x5CF5, 0x8D74, 0x5CF6, 0x8D75,
+	0x5CF7, 0x8D76, 0x5CF8, 0x8D77, 0x5CF9, 0x8D78, 0x5CFA, 0x8D79,
+	0x5CFB, 0xBEFE, 0x5CFC, 0x8D7A, 0x5CFD, 0x8D7B, 0x5CFE, 0x8D7C,
+	0x5CFF, 0x8D7D, 0x5D00, 0x8D7E, 0x5D01, 0x8D80, 0x5D02, 0xE1C0,
+	0x5D03, 0xE1C1, 0x5D04, 0x8D81, 0x5D05, 0x8D82, 0x5D06, 0xE1C7,
+	0x5D07, 0xB3E7, 0x5D08, 0x8D83, 0x5D09, 0x8D84, 0x5D0A, 0x8D85,
+	0x5D0B, 0x8D86, 0x5D0C, 0x8D87, 0x5D0D, 0x8D88, 0x5D0E, 0xC6E9,
+	0x5D0F, 0x8D89, 0x5D10, 0x8D8A, 0x5D11, 0x8D8B, 0x5D12, 0x8D8C,
+	0x5D13, 0x8D8D, 0x5D14, 0xB4DE, 0x5D15, 0x8D8E, 0x5D16, 0xD1C2,
+	0x5D17, 0x8D8F, 0x5D18, 0x8D90, 0x5D19, 0x8D91, 0x5D1A, 0x8D92,
+	0x5D1B, 0xE1C8, 0x5D1C, 0x8D93, 0x5D1D, 0x8D94, 0x5D1E, 0xE1C6,
+	0x5D1F, 0x8D95, 0x5D20, 0x8D96, 0x5D21, 0x8D97, 0x5D22, 0x8D98,
+	0x5D23, 0x8D99, 0x5D24, 0xE1C5, 0x5D25, 0x8D9A, 0x5D26, 0xE1C3,
+	0x5D27, 0xE1C2, 0x5D28, 0x8D9B, 0x5D29, 0xB1C0, 0x5D2A, 0x8D9C,
+	0x5D2B, 0x8D9D, 0x5D2C, 0x8D9E, 0x5D2D, 0xD5B8, 0x5D2E, 0xE1C4,
+	0x5D2F, 0x8D9F, 0x5D30, 0x8DA0, 0x5D31, 0x8DA1, 0x5D32, 0x8DA2,
+	0x5D33, 0x8DA3, 0x5D34, 0xE1CB, 0x5D35, 0x8DA4, 0x5D36, 0x8DA5,
+	0x5D37, 0x8DA6, 0x5D38, 0x8DA7, 0x5D39, 0x8DA8, 0x5D3A, 0x8DA9,
+	0x5D3B, 0x8DAA, 0x5D3C, 0x8DAB, 0x5D3D, 0xE1CC, 0x5D3E, 0xE1CA,
+	0x5D3F, 0x8DAC, 0x5D40, 0x8DAD, 0x5D41, 0x8DAE, 0x5D42, 0x8DAF,
+	0x5D43, 0x8DB0, 0x5D44, 0x8DB1, 0x5D45, 0x8DB2, 0x5D46, 0x8DB3,
+	0x5D47, 0xEFFA, 0x5D48, 0x8DB4, 0x5D49, 0x8DB5, 0x5D4A, 0xE1D3,
+	0x5D4B, 0xE1D2, 0x5D4C, 0xC7B6, 0x5D4D, 0x8DB6, 0x5D4E, 0x8DB7,
+	0x5D4F, 0x8DB8, 0x5D50, 0x8DB9, 0x5D51, 0x8DBA, 0x5D52, 0x8DBB,
+	0x5D53, 0x8DBC, 0x5D54, 0x8DBD, 0x5D55, 0x8DBE, 0x5D56, 0x8DBF,
+	0x5D57, 0x8DC0, 0x5D58, 0xE1C9, 0x5D59, 0x8DC1, 0x5D5A, 0x8DC2,
+	0x5D5B, 0xE1CE, 0x5D5C, 0x8DC3, 0x5D5D, 0xE1D0, 0x5D5E, 0x8DC4,
+	0x5D5F, 0x8DC5, 0x5D60, 0x8DC6, 0x5D61, 0x8DC7, 0x5D62, 0x8DC8,
+	0x5D63, 0x8DC9, 0x5D64, 0x8DCA, 0x5D65, 0x8DCB, 0x5D66, 0x8DCC,
+	0x5D67, 0x8DCD, 0x5D68, 0x8DCE, 0x5D69, 0xE1D4, 0x5D6A, 0x8DCF,
+	0x5D6B, 0xE1D1, 0x5D6C, 0xE1CD, 0x5D6D, 0x8DD0, 0x5D6E, 0x8DD1,
+	0x5D6F, 0xE1CF, 0x5D70, 0x8DD2, 0x5D71, 0x8DD3, 0x5D72, 0x8DD4,
+	0x5D73, 0x8DD5, 0x5D74, 0xE1D5, 0x5D75, 0x8DD6, 0x5D76, 0x8DD7,
+	0x5D77, 0x8DD8, 0x5D78, 0x8DD9, 0x5D79, 0x8DDA, 0x5D7A, 0x8DDB,
+	0x5D7B, 0x8DDC, 0x5D7C, 0x8DDD, 0x5D7D, 0x8DDE, 0x5D7E, 0x8DDF,
+	0x5D7F, 0x8DE0, 0x5D80, 0x8DE1, 0x5D81, 0x8DE2, 0x5D82, 0xE1D6,
+	0x5D83, 0x8DE3, 0x5D84, 0x8DE4, 0x5D85, 0x8DE5, 0x5D86, 0x8DE6,
+	0x5D87, 0x8DE7, 0x5D88, 0x8DE8, 0x5D89, 0x8DE9, 0x5D8A, 0x8DEA,
+	0x5D8B, 0x8DEB, 0x5D8C, 0x8DEC, 0x5D8D, 0x8DED, 0x5D8E, 0x8DEE,
+	0x5D8F, 0x8DEF, 0x5D90, 0x8DF0, 0x5D91, 0x8DF1, 0x5D92, 0x8DF2,
+	0x5D93, 0x8DF3, 0x5D94, 0x8DF4, 0x5D95, 0x8DF5, 0x5D96, 0x8DF6,
+	0x5D97, 0x8DF7, 0x5D98, 0x8DF8, 0x5D99, 0xE1D7, 0x5D9A, 0x8DF9,
+	0x5D9B, 0x8DFA, 0x5D9C, 0x8DFB, 0x5D9D, 0xE1D8, 0x5D9E, 0x8DFC,
+	0x5D9F, 0x8DFD, 0x5DA0, 0x8DFE, 0x5DA1, 0x8E40, 0x5DA2, 0x8E41,
+	0x5DA3, 0x8E42, 0x5DA4, 0x8E43, 0x5DA5, 0x8E44, 0x5DA6, 0x8E45,
+	0x5DA7, 0x8E46, 0x5DA8, 0x8E47, 0x5DA9, 0x8E48, 0x5DAA, 0x8E49,
+	0x5DAB, 0x8E4A, 0x5DAC, 0x8E4B, 0x5DAD, 0x8E4C, 0x5DAE, 0x8E4D,
+	0x5DAF, 0x8E4E, 0x5DB0, 0x8E4F, 0x5DB1, 0x8E50, 0x5DB2, 0x8E51,
+	0x5DB3, 0x8E52, 0x5DB4, 0x8E53, 0x5DB5, 0x8E54, 0x5DB6, 0x8E55,
+	0x5DB7, 0xE1DA, 0x5DB8, 0x8E56, 0x5DB9, 0x8E57, 0x5DBA, 0x8E58,
+	0x5DBB, 0x8E59, 0x5DBC, 0x8E5A, 0x5DBD, 0x8E5B, 0x5DBE, 0x8E5C,
+	0x5DBF, 0x8E5D, 0x5DC0, 0x8E5E, 0x5DC1, 0x8E5F, 0x5DC2, 0x8E60,
+	0x5DC3, 0x8E61, 0x5DC4, 0x8E62, 0x5DC5, 0xE1DB, 0x5DC6, 0x8E63,
+	0x5DC7, 0x8E64, 0x5DC8, 0x8E65, 0x5DC9, 0x8E66, 0x5DCA, 0x8E67,
+	0x5DCB, 0x8E68, 0x5DCC, 0x8E69, 0x5DCD, 0xCEA1, 0x5DCE, 0x8E6A,
+	0x5DCF, 0x8E6B, 0x5DD0, 0x8E6C, 0x5DD1, 0x8E6D, 0x5DD2, 0x8E6E,
+	0x5DD3, 0x8E6F, 0x5DD4, 0x8E70, 0x5DD5, 0x8E71, 0x5DD6, 0x8E72,
+	0x5DD7, 0x8E73, 0x5DD8, 0x8E74, 0x5DD9, 0x8E75, 0x5DDA, 0x8E76,
+	0x5DDB, 0xE7DD, 0x5DDC, 0x8E77, 0x5DDD, 0xB4A8, 0x5DDE, 0xD6DD,
+	0x5DDF, 0x8E78, 0x5DE0, 0x8E79, 0x5DE1, 0xD1B2, 0x5DE2, 0xB3B2,
+	0x5DE3, 0x8E7A, 0x5DE4, 0x8E7B, 0x5DE5, 0xB9A4, 0x5DE6, 0xD7F3,
+	0x5DE7, 0xC7C9, 0x5DE8, 0xBEDE, 0x5DE9, 0xB9AE, 0x5DEA, 0x8E7C,
+	0x5DEB, 0xCED7, 0x5DEC, 0x8E7D, 0x5DED, 0x8E7E, 0x5DEE, 0xB2EE,
+	0x5DEF, 0xDBCF, 0x5DF0, 0x8E80, 0x5DF1, 0xBCBA, 0x5DF2, 0xD2D1,
+	0x5DF3, 0xCBC8, 0x5DF4, 0xB0CD, 0x5DF5, 0x8E81, 0x5DF6, 0x8E82,
+	0x5DF7, 0xCFEF, 0x5DF8, 0x8E83, 0x5DF9, 0x8E84, 0x5DFA, 0x8E85,
+	0x5DFB, 0x8E86, 0x5DFC, 0x8E87, 0x5DFD, 0xD9E3, 0x5DFE, 0xBDED,
+	0x5DFF, 0x8E88, 0x5E00, 0x8E89, 0x5E01, 0xB1D2, 0x5E02, 0xCAD0,
+	0x5E03, 0xB2BC, 0x5E04, 0x8E8A, 0x5E05, 0xCBA7, 0x5E06, 0xB7AB,
+	0x5E07, 0x8E8B, 0x5E08, 0xCAA6, 0x5E09, 0x8E8C, 0x5E0A, 0x8E8D,
+	0x5E0B, 0x8E8E, 0x5E0C, 0xCFA3, 0x5E0D, 0x8E8F, 0x5E0E, 0x8E90,
+	0x5E0F, 0xE0F8, 0x5E10, 0xD5CA, 0x5E11, 0xE0FB, 0x5E12, 0x8E91,
+	0x5E13, 0x8E92, 0x5E14, 0xE0FA, 0x5E15, 0xC5C1, 0x5E16, 0xCCFB,
+	0x5E17, 0x8E93, 0x5E18, 0xC1B1, 0x5E19, 0xE0F9, 0x5E1A, 0xD6E3,
+	0x5E1B, 0xB2AF, 0x5E1C, 0xD6C4, 0x5E1D, 0xB5DB, 0x5E1E, 0x8E94,
+	0x5E1F, 0x8E95, 0x5E20, 0x8E96, 0x5E21, 0x8E97, 0x5E22, 0x8E98,
+	0x5E23, 0x8E99, 0x5E24, 0x8E9A, 0x5E25, 0x8E9B, 0x5E26, 0xB4F8,
+	0x5E27, 0xD6A1, 0x5E28, 0x8E9C, 0x5E29, 0x8E9D, 0x5E2A, 0x8E9E,
+	0x5E2B, 0x8E9F, 0x5E2C, 0x8EA0, 0x5E2D, 0xCFAF, 0x5E2E, 0xB0EF,
+	0x5E2F, 0x8EA1, 0x5E30, 0x8EA2, 0x5E31, 0xE0FC, 0x5E32, 0x8EA3,
+	0x5E33, 0x8EA4, 0x5E34, 0x8EA5, 0x5E35, 0x8EA6, 0x5E36, 0x8EA7,
+	0x5E37, 0xE1A1, 0x5E38, 0xB3A3, 0x5E39, 0x8EA8, 0x5E3A, 0x8EA9,
+	0x5E3B, 0xE0FD, 0x5E3C, 0xE0FE, 0x5E3D, 0xC3B1, 0x5E3E, 0x8EAA,
+	0x5E3F, 0x8EAB, 0x5E40, 0x8EAC, 0x5E41, 0x8EAD, 0x5E42, 0xC3DD,
+	0x5E43, 0x8EAE, 0x5E44, 0xE1A2, 0x5E45, 0xB7F9, 0x5E46, 0x8EAF,
+	0x5E47, 0x8EB0, 0x5E48, 0x8EB1, 0x5E49, 0x8EB2, 0x5E4A, 0x8EB3,
+	0x5E4B, 0x8EB4, 0x5E4C, 0xBBCF, 0x5E4D, 0x8EB5, 0x5E4E, 0x8EB6,
+	0x5E4F, 0x8EB7, 0x5E50, 0x8EB8, 0x5E51, 0x8EB9, 0x5E52, 0x8EBA,
+	0x5E53, 0x8EBB, 0x5E54, 0xE1A3, 0x5E55, 0xC4BB, 0x5E56, 0x8EBC,
+	0x5E57, 0x8EBD, 0x5E58, 0x8EBE, 0x5E59, 0x8EBF, 0x5E5A, 0x8EC0,
+	0x5E5B, 0xE1A4, 0x5E5C, 0x8EC1, 0x5E5D, 0x8EC2, 0x5E5E, 0xE1A5,
+	0x5E5F, 0x8EC3, 0x5E60, 0x8EC4, 0x5E61, 0xE1A6, 0x5E62, 0xB4B1,
+	0x5E63, 0x8EC5, 0x5E64, 0x8EC6, 0x5E65, 0x8EC7, 0x5E66, 0x8EC8,
+	0x5E67, 0x8EC9, 0x5E68, 0x8ECA, 0x5E69, 0x8ECB, 0x5E6A, 0x8ECC,
+	0x5E6B, 0x8ECD, 0x5E6C, 0x8ECE, 0x5E6D, 0x8ECF, 0x5E6E, 0x8ED0,
+	0x5E6F, 0x8ED1, 0x5E70, 0x8ED2, 0x5E71, 0x8ED3, 0x5E72, 0xB8C9,
+	0x5E73, 0xC6BD, 0x5E74, 0xC4EA, 0x5E75, 0x8ED4, 0x5E76, 0xB2A2,
+	0x5E77, 0x8ED5, 0x5E78, 0xD0D2, 0x5E79, 0x8ED6, 0x5E7A, 0xE7DB,
+	0x5E7B, 0xBBC3, 0x5E7C, 0xD3D7, 0x5E7D, 0xD3C4, 0x5E7E, 0x8ED7,
+	0x5E7F, 0xB9E3, 0x5E80, 0xE2CF, 0x5E81, 0x8ED8, 0x5E82, 0x8ED9,
+	0x5E83, 0x8EDA, 0x5E84, 0xD7AF, 0x5E85, 0x8EDB, 0x5E86, 0xC7EC,
+	0x5E87, 0xB1D3, 0x5E88, 0x8EDC, 0x5E89, 0x8EDD, 0x5E8A, 0xB4B2,
+	0x5E8B, 0xE2D1, 0x5E8C, 0x8EDE, 0x5E8D, 0x8EDF, 0x5E8E, 0x8EE0,
+	0x5E8F, 0xD0F2, 0x5E90, 0xC2AE, 0x5E91, 0xE2D0, 0x5E92, 0x8EE1,
+	0x5E93, 0xBFE2, 0x5E94, 0xD3A6, 0x5E95, 0xB5D7, 0x5E96, 0xE2D2,
+	0x5E97, 0xB5EA, 0x5E98, 0x8EE2, 0x5E99, 0xC3ED, 0x5E9A, 0xB8FD,
+	0x5E9B, 0x8EE3, 0x5E9C, 0xB8AE, 0x5E9D, 0x8EE4, 0x5E9E, 0xC5D3,
+	0x5E9F, 0xB7CF, 0x5EA0, 0xE2D4, 0x5EA1, 0x8EE5, 0x5EA2, 0x8EE6,
+	0x5EA3, 0x8EE7, 0x5EA4, 0x8EE8, 0x5EA5, 0xE2D3, 0x5EA6, 0xB6C8,
+	0x5EA7, 0xD7F9, 0x5EA8, 0x8EE9, 0x5EA9, 0x8EEA, 0x5EAA, 0x8EEB,
+	0x5EAB, 0x8EEC, 0x5EAC, 0x8EED, 0x5EAD, 0xCDA5, 0x5EAE, 0x8EEE,
+	0x5EAF, 0x8EEF, 0x5EB0, 0x8EF0, 0x5EB1, 0x8EF1, 0x5EB2, 0x8EF2,
+	0x5EB3, 0xE2D8, 0x5EB4, 0x8EF3, 0x5EB5, 0xE2D6, 0x5EB6, 0xCAFC,
+	0x5EB7, 0xBFB5, 0x5EB8, 0xD3B9, 0x5EB9, 0xE2D5, 0x5EBA, 0x8EF4,
+	0x5EBB, 0x8EF5, 0x5EBC, 0x8EF6, 0x5EBD, 0x8EF7, 0x5EBE, 0xE2D7,
+	0x5EBF, 0x8EF8, 0x5EC0, 0x8EF9, 0x5EC1, 0x8EFA, 0x5EC2, 0x8EFB,
+	0x5EC3, 0x8EFC, 0x5EC4, 0x8EFD, 0x5EC5, 0x8EFE, 0x5EC6, 0x8F40,
+	0x5EC7, 0x8F41, 0x5EC8, 0x8F42, 0x5EC9, 0xC1AE, 0x5ECA, 0xC0C8,
+	0x5ECB, 0x8F43, 0x5ECC, 0x8F44, 0x5ECD, 0x8F45, 0x5ECE, 0x8F46,
+	0x5ECF, 0x8F47, 0x5ED0, 0x8F48, 0x5ED1, 0xE2DB, 0x5ED2, 0xE2DA,
+	0x5ED3, 0xC0AA, 0x5ED4, 0x8F49, 0x5ED5, 0x8F4A, 0x5ED6, 0xC1CE,
+	0x5ED7, 0x8F4B, 0x5ED8, 0x8F4C, 0x5ED9, 0x8F4D, 0x5EDA, 0x8F4E,
+	0x5EDB, 0xE2DC, 0x5EDC, 0x8F4F, 0x5EDD, 0x8F50, 0x5EDE, 0x8F51,
+	0x5EDF, 0x8F52, 0x5EE0, 0x8F53, 0x5EE1, 0x8F54, 0x5EE2, 0x8F55,
+	0x5EE3, 0x8F56, 0x5EE4, 0x8F57, 0x5EE5, 0x8F58, 0x5EE6, 0x8F59,
+	0x5EE7, 0x8F5A, 0x5EE8, 0xE2DD, 0x5EE9, 0x8F5B, 0x5EEA, 0xE2DE,
+	0x5EEB, 0x8F5C, 0x5EEC, 0x8F5D, 0x5EED, 0x8F5E, 0x5EEE, 0x8F5F,
+	0x5EEF, 0x8F60, 0x5EF0, 0x8F61, 0x5EF1, 0x8F62, 0x5EF2, 0x8F63,
+	0x5EF3, 0x8F64, 0x5EF4, 0xDBC8, 0x5EF5, 0x8F65, 0x5EF6, 0xD1D3,
+	0x5EF7, 0xCDA2, 0x5EF8, 0x8F66, 0x5EF9, 0x8F67, 0x5EFA, 0xBDA8,
+	0x5EFB, 0x8F68, 0x5EFC, 0x8F69, 0x5EFD, 0x8F6A, 0x5EFE, 0xDEC3,
+	0x5EFF, 0xD8A5, 0x5F00, 0xBFAA, 0x5F01, 0xDBCD, 0x5F02, 0xD2EC,
+	0x5F03, 0xC6FA, 0x5F04, 0xC5AA, 0x5F05, 0x8F6B, 0x5F06, 0x8F6C,
+	0x5F07, 0x8F6D, 0x5F08, 0xDEC4, 0x5F09, 0x8F6E, 0x5F0A, 0xB1D7,
+	0x5F0B, 0xDFAE, 0x5F0C, 0x8F6F, 0x5F0D, 0x8F70, 0x5F0E, 0x8F71,
+	0x5F0F, 0xCABD, 0x5F10, 0x8F72, 0x5F11, 0xDFB1, 0x5F12, 0x8F73,
+	0x5F13, 0xB9AD, 0x5F14, 0x8F74, 0x5F15, 0xD2FD, 0x5F16, 0x8F75,
+	0x5F17, 0xB8A5, 0x5F18, 0xBAEB, 0x5F19, 0x8F76, 0x5F1A, 0x8F77,
+	0x5F1B, 0xB3DA, 0x5F1C, 0x8F78, 0x5F1D, 0x8F79, 0x5F1E, 0x8F7A,
+	0x5F1F, 0xB5DC, 0x5F20, 0xD5C5, 0x5F21, 0x8F7B, 0x5F22, 0x8F7C,
+	0x5F23, 0x8F7D, 0x5F24, 0x8F7E, 0x5F25, 0xC3D6, 0x5F26, 0xCFD2,
+	0x5F27, 0xBBA1, 0x5F28, 0x8F80, 0x5F29, 0xE5F3, 0x5F2A, 0xE5F2,
+	0x5F2B, 0x8F81, 0x5F2C, 0x8F82, 0x5F2D, 0xE5F4, 0x5F2E, 0x8F83,
+	0x5F2F, 0xCDE4, 0x5F30, 0x8F84, 0x5F31, 0xC8F5, 0x5F32, 0x8F85,
+	0x5F33, 0x8F86, 0x5F34, 0x8F87, 0x5F35, 0x8F88, 0x5F36, 0x8F89,
+	0x5F37, 0x8F8A, 0x5F38, 0x8F8B, 0x5F39, 0xB5AF, 0x5F3A, 0xC7BF,
+	0x5F3B, 0x8F8C, 0x5F3C, 0xE5F6, 0x5F3D, 0x8F8D, 0x5F3E, 0x8F8E,
+	0x5F3F, 0x8F8F, 0x5F40, 0xECB0, 0x5F41, 0x8F90, 0x5F42, 0x8F91,
+	0x5F43, 0x8F92, 0x5F44, 0x8F93, 0x5F45, 0x8F94, 0x5F46, 0x8F95,
+	0x5F47, 0x8F96, 0x5F48, 0x8F97, 0x5F49, 0x8F98, 0x5F4A, 0x8F99,
+	0x5F4B, 0x8F9A, 0x5F4C, 0x8F9B, 0x5F4D, 0x8F9C, 0x5F4E, 0x8F9D,
+	0x5F4F, 0x8F9E, 0x5F50, 0xE5E6, 0x5F51, 0x8F9F, 0x5F52, 0xB9E9,
+	0x5F53, 0xB5B1, 0x5F54, 0x8FA0, 0x5F55, 0xC2BC, 0x5F56, 0xE5E8,
+	0x5F57, 0xE5E7, 0x5F58, 0xE5E9, 0x5F59, 0x8FA1, 0x5F5A, 0x8FA2,
+	0x5F5B, 0x8FA3, 0x5F5C, 0x8FA4, 0x5F5D, 0xD2CD, 0x5F5E, 0x8FA5,
+	0x5F5F, 0x8FA6, 0x5F60, 0x8FA7, 0x5F61, 0xE1EA, 0x5F62, 0xD0CE,
+	0x5F63, 0x8FA8, 0x5F64, 0xCDAE, 0x5F65, 0x8FA9, 0x5F66, 0xD1E5,
+	0x5F67, 0x8FAA, 0x5F68, 0x8FAB, 0x5F69, 0xB2CA, 0x5F6A, 0xB1EB,
+	0x5F6B, 0x8FAC, 0x5F6C, 0xB1F2, 0x5F6D, 0xC5ED, 0x5F6E, 0x8FAD,
+	0x5F6F, 0x8FAE, 0x5F70, 0xD5C3, 0x5F71, 0xD3B0, 0x5F72, 0x8FAF,
+	0x5F73, 0xE1DC, 0x5F74, 0x8FB0, 0x5F75, 0x8FB1, 0x5F76, 0x8FB2,
+	0x5F77, 0xE1DD, 0x5F78, 0x8FB3, 0x5F79, 0xD2DB, 0x5F7A, 0x8FB4,
+	0x5F7B, 0xB3B9, 0x5F7C, 0xB1CB, 0x5F7D, 0x8FB5, 0x5F7E, 0x8FB6,
+	0x5F7F, 0x8FB7, 0x5F80, 0xCDF9, 0x5F81, 0xD5F7, 0x5F82, 0xE1DE,
+	0x5F83, 0x8FB8, 0x5F84, 0xBEB6, 0x5F85, 0xB4FD, 0x5F86, 0x8FB9,
+	0x5F87, 0xE1DF, 0x5F88, 0xBADC, 0x5F89, 0xE1E0, 0x5F8A, 0xBBB2,
+	0x5F8B, 0xC2C9, 0x5F8C, 0xE1E1, 0x5F8D, 0x8FBA, 0x5F8E, 0x8FBB,
+	0x5F8F, 0x8FBC, 0x5F90, 0xD0EC, 0x5F91, 0x8FBD, 0x5F92, 0xCDBD,
+	0x5F93, 0x8FBE, 0x5F94, 0x8FBF, 0x5F95, 0xE1E2, 0x5F96, 0x8FC0,
+	0x5F97, 0xB5C3, 0x5F98, 0xC5C7, 0x5F99, 0xE1E3, 0x5F9A, 0x8FC1,
+	0x5F9B, 0x8FC2, 0x5F9C, 0xE1E4, 0x5F9D, 0x8FC3, 0x5F9E, 0x8FC4,
+	0x5F9F, 0x8FC5, 0x5FA0, 0x8FC6, 0x5FA1, 0xD3F9, 0x5FA2, 0x8FC7,
+	0x5FA3, 0x8FC8, 0x5FA4, 0x8FC9, 0x5FA5, 0x8FCA, 0x5FA6, 0x8FCB,
+	0x5FA7, 0x8FCC, 0x5FA8, 0xE1E5, 0x5FA9, 0x8FCD, 0x5FAA, 0xD1AD,
+	0x5FAB, 0x8FCE, 0x5FAC, 0x8FCF, 0x5FAD, 0xE1E6, 0x5FAE, 0xCEA2,
+	0x5FAF, 0x8FD0, 0x5FB0, 0x8FD1, 0x5FB1, 0x8FD2, 0x5FB2, 0x8FD3,
+	0x5FB3, 0x8FD4, 0x5FB4, 0x8FD5, 0x5FB5, 0xE1E7, 0x5FB6, 0x8FD6,
+	0x5FB7, 0xB5C2, 0x5FB8, 0x8FD7, 0x5FB9, 0x8FD8, 0x5FBA, 0x8FD9,
+	0x5FBB, 0x8FDA, 0x5FBC, 0xE1E8, 0x5FBD, 0xBBD5, 0x5FBE, 0x8FDB,
+	0x5FBF, 0x8FDC, 0x5FC0, 0x8FDD, 0x5FC1, 0x8FDE, 0x5FC2, 0x8FDF,
+	0x5FC3, 0xD0C4, 0x5FC4, 0xE2E0, 0x5FC5, 0xB1D8, 0x5FC6, 0xD2E4,
+	0x5FC7, 0x8FE0, 0x5FC8, 0x8FE1, 0x5FC9, 0xE2E1, 0x5FCA, 0x8FE2,
+	0x5FCB, 0x8FE3, 0x5FCC, 0xBCC9, 0x5FCD, 0xC8CC, 0x5FCE, 0x8FE4,
+	0x5FCF, 0xE2E3, 0x5FD0, 0xECFE, 0x5FD1, 0xECFD, 0x5FD2, 0xDFAF,
+	0x5FD3, 0x8FE5, 0x5FD4, 0x8FE6, 0x5FD5, 0x8FE7, 0x5FD6, 0xE2E2,
+	0x5FD7, 0xD6BE, 0x5FD8, 0xCDFC, 0x5FD9, 0xC3A6, 0x5FDA, 0x8FE8,
+	0x5FDB, 0x8FE9, 0x5FDC, 0x8FEA, 0x5FDD, 0xE3C3, 0x5FDE, 0x8FEB,
+	0x5FDF, 0x8FEC, 0x5FE0, 0xD6D2, 0x5FE1, 0xE2E7, 0x5FE2, 0x8FED,
+	0x5FE3, 0x8FEE, 0x5FE4, 0xE2E8, 0x5FE5, 0x8FEF, 0x5FE6, 0x8FF0,
+	0x5FE7, 0xD3C7, 0x5FE8, 0x8FF1, 0x5FE9, 0x8FF2, 0x5FEA, 0xE2EC,
+	0x5FEB, 0xBFEC, 0x5FEC, 0x8FF3, 0x5FED, 0xE2ED, 0x5FEE, 0xE2E5,
+	0x5FEF, 0x8FF4, 0x5FF0, 0x8FF5, 0x5FF1, 0xB3C0, 0x5FF2, 0x8FF6,
+	0x5FF3, 0x8FF7, 0x5FF4, 0x8FF8, 0x5FF5, 0xC4EE, 0x5FF6, 0x8FF9,
+	0x5FF7, 0x8FFA, 0x5FF8, 0xE2EE, 0x5FF9, 0x8FFB, 0x5FFA, 0x8FFC,
+	0x5FFB, 0xD0C3, 0x5FFC, 0x8FFD, 0x5FFD, 0xBAF6, 0x5FFE, 0xE2E9,
+	0x5FFF, 0xB7DE, 0x6000, 0xBBB3, 0x6001, 0xCCAC, 0x6002, 0xCBCB,
+	0x6003, 0xE2E4, 0x6004, 0xE2E6, 0x6005, 0xE2EA, 0x6006, 0xE2EB,
+	0x6007, 0x8FFE, 0x6008, 0x9040, 0x6009, 0x9041, 0x600A, 0xE2F7,
+	0x600B, 0x9042, 0x600C, 0x9043, 0x600D, 0xE2F4, 0x600E, 0xD4F5,
+	0x600F, 0xE2F3, 0x6010, 0x9044, 0x6011, 0x9045, 0x6012, 0xC5AD,
+	0x6013, 0x9046, 0x6014, 0xD5FA, 0x6015, 0xC5C2, 0x6016, 0xB2C0,
+	0x6017, 0x9047, 0x6018, 0x9048, 0x6019, 0xE2EF, 0x601A, 0x9049,
+	0x601B, 0xE2F2, 0x601C, 0xC1AF, 0x601D, 0xCBBC, 0x601E, 0x904A,
+	0x601F, 0x904B, 0x6020, 0xB5A1, 0x6021, 0xE2F9, 0x6022, 0x904C,
+	0x6023, 0x904D, 0x6024, 0x904E, 0x6025, 0xBCB1, 0x6026, 0xE2F1,
+	0x6027, 0xD0D4, 0x6028, 0xD4B9, 0x6029, 0xE2F5, 0x602A, 0xB9D6,
+	0x602B, 0xE2F6, 0x602C, 0x904F, 0x602D, 0x9050, 0x602E, 0x9051,
+	0x602F, 0xC7D3, 0x6030, 0x9052, 0x6031, 0x9053, 0x6032, 0x9054,
+	0x6033, 0x9055, 0x6034, 0x9056, 0x6035, 0xE2F0, 0x6036, 0x9057,
+	0x6037, 0x9058, 0x6038, 0x9059, 0x6039, 0x905A, 0x603A, 0x905B,
+	0x603B, 0xD7DC, 0x603C, 0xEDA1, 0x603D, 0x905C, 0x603E, 0x905D,
+	0x603F, 0xE2F8, 0x6040, 0x905E, 0x6041, 0xEDA5, 0x6042, 0xE2FE,
+	0x6043, 0xCAD1, 0x6044, 0x905F, 0x6045, 0x9060, 0x6046, 0x9061,
+	0x6047, 0x9062, 0x6048, 0x9063, 0x6049, 0x9064, 0x604A, 0x9065,
+	0x604B, 0xC1B5, 0x604C, 0x9066, 0x604D, 0xBBD0, 0x604E, 0x9067,
+	0x604F, 0x9068, 0x6050, 0xBFD6, 0x6051, 0x9069, 0x6052, 0xBAE3,
+	0x6053, 0x906A, 0x6054, 0x906B, 0x6055, 0xCBA1, 0x6056, 0x906C,
+	0x6057, 0x906D, 0x6058, 0x906E, 0x6059, 0xEDA6, 0x605A, 0xEDA3,
+	0x605B, 0x906F, 0x605C, 0x9070, 0x605D, 0xEDA2, 0x605E, 0x9071,
+	0x605F, 0x9072, 0x6060, 0x9073, 0x6061, 0x9074, 0x6062, 0xBBD6,
+	0x6063, 0xEDA7, 0x6064, 0xD0F4, 0x6065, 0x9075, 0x6066, 0x9076,
+	0x6067, 0xEDA4, 0x6068, 0xBADE, 0x6069, 0xB6F7, 0x606A, 0xE3A1,
+	0x606B, 0xB6B2, 0x606C, 0xCCF1, 0x606D, 0xB9A7, 0x606E, 0x9077,
+	0x606F, 0xCFA2, 0x6070, 0xC7A1, 0x6071, 0x9078, 0x6072, 0x9079,
+	0x6073, 0xBFD2, 0x6074, 0x907A, 0x6075, 0x907B, 0x6076, 0xB6F1,
+	0x6077, 0x907C, 0x6078, 0xE2FA, 0x6079, 0xE2FB, 0x607A, 0xE2FD,
+	0x607B, 0xE2FC, 0x607C, 0xC4D5, 0x607D, 0xE3A2, 0x607E, 0x907D,
+	0x607F, 0xD3C1, 0x6080, 0x907E, 0x6081, 0x9080, 0x6082, 0x9081,
+	0x6083, 0xE3A7, 0x6084, 0xC7C4, 0x6085, 0x9082, 0x6086, 0x9083,
+	0x6087, 0x9084, 0x6088, 0x9085, 0x6089, 0xCFA4, 0x608A, 0x9086,
+	0x608B, 0x9087, 0x608C, 0xE3A9, 0x608D, 0xBAB7, 0x608E, 0x9088,
+	0x608F, 0x9089, 0x6090, 0x908A, 0x6091, 0x908B, 0x6092, 0xE3A8,
+	0x6093, 0x908C, 0x6094, 0xBBDA, 0x6095, 0x908D, 0x6096, 0xE3A3,
+	0x6097, 0x908E, 0x6098, 0x908F, 0x6099, 0x9090, 0x609A, 0xE3A4,
+	0x609B, 0xE3AA, 0x609C, 0x9091, 0x609D, 0xE3A6, 0x609E, 0x9092,
+	0x609F, 0xCEF2, 0x60A0, 0xD3C6, 0x60A1, 0x9093, 0x60A2, 0x9094,
+	0x60A3, 0xBBBC, 0x60A4, 0x9095, 0x60A5, 0x9096, 0x60A6, 0xD4C3,
+	0x60A7, 0x9097, 0x60A8, 0xC4FA, 0x60A9, 0x9098, 0x60AA, 0x9099,
+	0x60AB, 0xEDA8, 0x60AC, 0xD0FC, 0x60AD, 0xE3A5, 0x60AE, 0x909A,
+	0x60AF, 0xC3F5, 0x60B0, 0x909B, 0x60B1, 0xE3AD, 0x60B2, 0xB1AF,
+	0x60B3, 0x909C, 0x60B4, 0xE3B2, 0x60B5, 0x909D, 0x60B6, 0x909E,
+	0x60B7, 0x909F, 0x60B8, 0xBCC2, 0x60B9, 0x90A0, 0x60BA, 0x90A1,
+	0x60BB, 0xE3AC, 0x60BC, 0xB5BF, 0x60BD, 0x90A2, 0x60BE, 0x90A3,
+	0x60BF, 0x90A4, 0x60C0, 0x90A5, 0x60C1, 0x90A6, 0x60C2, 0x90A7,
+	0x60C3, 0x90A8, 0x60C4, 0x90A9, 0x60C5, 0xC7E9, 0x60C6, 0xE3B0,
+	0x60C7, 0x90AA, 0x60C8, 0x90AB, 0x60C9, 0x90AC, 0x60CA, 0xBEAA,
+	0x60CB, 0xCDEF, 0x60CC, 0x90AD, 0x60CD, 0x90AE, 0x60CE, 0x90AF,
+	0x60CF, 0x90B0, 0x60D0, 0x90B1, 0x60D1, 0xBBF3, 0x60D2, 0x90B2,
+	0x60D3, 0x90B3, 0x60D4, 0x90B4, 0x60D5, 0xCCE8, 0x60D6, 0x90B5,
+	0x60D7, 0x90B6, 0x60D8, 0xE3AF, 0x60D9, 0x90B7, 0x60DA, 0xE3B1,
+	0x60DB, 0x90B8, 0x60DC, 0xCFA7, 0x60DD, 0xE3AE, 0x60DE, 0x90B9,
+	0x60DF, 0xCEA9, 0x60E0, 0xBBDD, 0x60E1, 0x90BA, 0x60E2, 0x90BB,
+	0x60E3, 0x90BC, 0x60E4, 0x90BD, 0x60E5, 0x90BE, 0x60E6, 0xB5EB,
+	0x60E7, 0xBEE5, 0x60E8, 0xB2D2, 0x60E9, 0xB3CD, 0x60EA, 0x90BF,
+	0x60EB, 0xB1B9, 0x60EC, 0xE3AB, 0x60ED, 0xB2D1, 0x60EE, 0xB5AC,
+	0x60EF, 0xB9DF, 0x60F0, 0xB6E8, 0x60F1, 0x90C0, 0x60F2, 0x90C1,
+	0x60F3, 0xCFEB, 0x60F4, 0xE3B7, 0x60F5, 0x90C2, 0x60F6, 0xBBCC,
+	0x60F7, 0x90C3, 0x60F8, 0x90C4, 0x60F9, 0xC8C7, 0x60FA, 0xD0CA,
+	0x60FB, 0x90C5, 0x60FC, 0x90C6, 0x60FD, 0x90C7, 0x60FE, 0x90C8,
+	0x60FF, 0x90C9, 0x6100, 0xE3B8, 0x6101, 0xB3EE, 0x6102, 0x90CA,
+	0x6103, 0x90CB, 0x6104, 0x90CC, 0x6105, 0x90CD, 0x6106, 0xEDA9,
+	0x6107, 0x90CE, 0x6108, 0xD3FA, 0x6109, 0xD3E4, 0x610A, 0x90CF,
+	0x610B, 0x90D0, 0x610C, 0x90D1, 0x610D, 0xEDAA, 0x610E, 0xE3B9,
+	0x610F, 0xD2E2, 0x6110, 0x90D2, 0x6111, 0x90D3, 0x6112, 0x90D4,
+	0x6113, 0x90D5, 0x6114, 0x90D6, 0x6115, 0xE3B5, 0x6116, 0x90D7,
+	0x6117, 0x90D8, 0x6118, 0x90D9, 0x6119, 0x90DA, 0x611A, 0xD3DE,
+	0x611B, 0x90DB, 0x611C, 0x90DC, 0x611D, 0x90DD, 0x611E, 0x90DE,
+	0x611F, 0xB8D0, 0x6120, 0xE3B3, 0x6121, 0x90DF, 0x6122, 0x90E0,
+	0x6123, 0xE3B6, 0x6124, 0xB7DF, 0x6125, 0x90E1, 0x6126, 0xE3B4,
+	0x6127, 0xC0A2, 0x6128, 0x90E2, 0x6129, 0x90E3, 0x612A, 0x90E4,
+	0x612B, 0xE3BA, 0x612C, 0x90E5, 0x612D, 0x90E6, 0x612E, 0x90E7,
+	0x612F, 0x90E8, 0x6130, 0x90E9, 0x6131, 0x90EA, 0x6132, 0x90EB,
+	0x6133, 0x90EC, 0x6134, 0x90ED, 0x6135, 0x90EE, 0x6136, 0x90EF,
+	0x6137, 0x90F0, 0x6138, 0x90F1, 0x6139, 0x90F2, 0x613A, 0x90F3,
+	0x613B, 0x90F4, 0x613C, 0x90F5, 0x613D, 0x90F6, 0x613E, 0x90F7,
+	0x613F, 0xD4B8, 0x6140, 0x90F8, 0x6141, 0x90F9, 0x6142, 0x90FA,
+	0x6143, 0x90FB, 0x6144, 0x90FC, 0x6145, 0x90FD, 0x6146, 0x90FE,
+	0x6147, 0x9140, 0x6148, 0xB4C8, 0x6149, 0x9141, 0x614A, 0xE3BB,
+	0x614B, 0x9142, 0x614C, 0xBBC5, 0x614D, 0x9143, 0x614E, 0xC9F7,
+	0x614F, 0x9144, 0x6150, 0x9145, 0x6151, 0xC9E5, 0x6152, 0x9146,
+	0x6153, 0x9147, 0x6154, 0x9148, 0x6155, 0xC4BD, 0x6156, 0x9149,
+	0x6157, 0x914A, 0x6158, 0x914B, 0x6159, 0x914C, 0x615A, 0x914D,
+	0x615B, 0x914E, 0x615C, 0x914F, 0x615D, 0xEDAB, 0x615E, 0x9150,
+	0x615F, 0x9151, 0x6160, 0x9152, 0x6161, 0x9153, 0x6162, 0xC2FD,
+	0x6163, 0x9154, 0x6164, 0x9155, 0x6165, 0x9156, 0x6166, 0x9157,
+	0x6167, 0xBBDB, 0x6168, 0xBFAE, 0x6169, 0x9158, 0x616A, 0x9159,
+	0x616B, 0x915A, 0x616C, 0x915B, 0x616D, 0x915C, 0x616E, 0x915D,
+	0x616F, 0x915E, 0x6170, 0xCEBF, 0x6171, 0x915F, 0x6172, 0x9160,
+	0x6173, 0x9161, 0x6174, 0x9162, 0x6175, 0xE3BC, 0x6176, 0x9163,
+	0x6177, 0xBFB6, 0x6178, 0x9164, 0x6179, 0x9165, 0x617A, 0x9166,
+	0x617B, 0x9167, 0x617C, 0x9168, 0x617D, 0x9169, 0x617E, 0x916A,
+	0x617F, 0x916B, 0x6180, 0x916C, 0x6181, 0x916D, 0x6182, 0x916E,
+	0x6183, 0x916F, 0x6184, 0x9170, 0x6185, 0x9171, 0x6186, 0x9172,
+	0x6187, 0x9173, 0x6188, 0x9174, 0x6189, 0x9175, 0x618A, 0x9176,
+	0x618B, 0xB1EF, 0x618C, 0x9177, 0x618D, 0x9178, 0x618E, 0xD4F7,
+	0x618F, 0x9179, 0x6190, 0x917A, 0x6191, 0x917B, 0x6192, 0x917C,
+	0x6193, 0x917D, 0x6194, 0xE3BE, 0x6195, 0x917E, 0x6196, 0x9180,
+	0x6197, 0x9181, 0x6198, 0x9182, 0x6199, 0x9183, 0x619A, 0x9184,
+	0x619B, 0x9185, 0x619C, 0x9186, 0x619D, 0xEDAD, 0x619E, 0x9187,
+	0x619F, 0x9188, 0x61A0, 0x9189, 0x61A1, 0x918A, 0x61A2, 0x918B,
+	0x61A3, 0x918C, 0x61A4, 0x918D, 0x61A5, 0x918E, 0x61A6, 0x918F,
+	0x61A7, 0xE3BF, 0x61A8, 0xBAA9, 0x61A9, 0xEDAC, 0x61AA, 0x9190,
+	0x61AB, 0x9191, 0x61AC, 0xE3BD, 0x61AD, 0x9192, 0x61AE, 0x9193,
+	0x61AF, 0x9194, 0x61B0, 0x9195, 0x61B1, 0x9196, 0x61B2, 0x9197,
+	0x61B3, 0x9198, 0x61B4, 0x9199, 0x61B5, 0x919A, 0x61B6, 0x919B,
+	0x61B7, 0xE3C0, 0x61B8, 0x919C, 0x61B9, 0x919D, 0x61BA, 0x919E,
+	0x61BB, 0x919F, 0x61BC, 0x91A0, 0x61BD, 0x91A1, 0x61BE, 0xBAB6,
+	0x61BF, 0x91A2, 0x61C0, 0x91A3, 0x61C1, 0x91A4, 0x61C2, 0xB6AE,
+	0x61C3, 0x91A5, 0x61C4, 0x91A6, 0x61C5, 0x91A7, 0x61C6, 0x91A8,
+	0x61C7, 0x91A9, 0x61C8, 0xD0B8, 0x61C9, 0x91AA, 0x61CA, 0xB0C3,
+	0x61CB, 0xEDAE, 0x61CC, 0x91AB, 0x61CD, 0x91AC, 0x61CE, 0x91AD,
+	0x61CF, 0x91AE, 0x61D0, 0x91AF, 0x61D1, 0xEDAF, 0x61D2, 0xC0C1,
+	0x61D3, 0x91B0, 0x61D4, 0xE3C1, 0x61D5, 0x91B1, 0x61D6, 0x91B2,
+	0x61D7, 0x91B3, 0x61D8, 0x91B4, 0x61D9, 0x91B5, 0x61DA, 0x91B6,
+	0x61DB, 0x91B7, 0x61DC, 0x91B8, 0x61DD, 0x91B9, 0x61DE, 0x91BA,
+	0x61DF, 0x91BB, 0x61E0, 0x91BC, 0x61E1, 0x91BD, 0x61E2, 0x91BE,
+	0x61E3, 0x91BF, 0x61E4, 0x91C0, 0x61E5, 0x91C1, 0x61E6, 0xC5B3,
+	0x61E7, 0x91C2, 0x61E8, 0x91C3, 0x61E9, 0x91C4, 0x61EA, 0x91C5,
+	0x61EB, 0x91C6, 0x61EC, 0x91C7, 0x61ED, 0x91C8, 0x61EE, 0x91C9,
+	0x61EF, 0x91CA, 0x61F0, 0x91CB, 0x61F1, 0x91CC, 0x61F2, 0x91CD,
+	0x61F3, 0x91CE, 0x61F4, 0x91CF, 0x61F5, 0xE3C2, 0x61F6, 0x91D0,
+	0x61F7, 0x91D1, 0x61F8, 0x91D2, 0x61F9, 0x91D3, 0x61FA, 0x91D4,
+	0x61FB, 0x91D5, 0x61FC, 0x91D6, 0x61FD, 0x91D7, 0x61FE, 0x91D8,
+	0x61FF, 0xDCB2, 0x6200, 0x91D9, 0x6201, 0x91DA, 0x6202, 0x91DB,
+	0x6203, 0x91DC, 0x6204, 0x91DD, 0x6205, 0x91DE, 0x6206, 0xEDB0,
+	0x6207, 0x91DF, 0x6208, 0xB8EA, 0x6209, 0x91E0, 0x620A, 0xCEEC,
+	0x620B, 0xEAA7, 0x620C, 0xD0E7, 0x620D, 0xCAF9, 0x620E, 0xC8D6,
+	0x620F, 0xCFB7, 0x6210, 0xB3C9, 0x6211, 0xCED2, 0x6212, 0xBDE4,
+	0x6213, 0x91E1, 0x6214, 0x91E2, 0x6215, 0xE3DE, 0x6216, 0xBBF2,
+	0x6217, 0xEAA8, 0x6218, 0xD5BD, 0x6219, 0x91E3, 0x621A, 0xC6DD,
+	0x621B, 0xEAA9, 0x621C, 0x91E4, 0x621D, 0x91E5, 0x621E, 0x91E6,
+	0x621F, 0xEAAA, 0x6220, 0x91E7, 0x6221, 0xEAAC, 0x6222, 0xEAAB,
+	0x6223, 0x91E8, 0x6224, 0xEAAE, 0x6225, 0xEAAD, 0x6226, 0x91E9,
+	0x6227, 0x91EA, 0x6228, 0x91EB, 0x6229, 0x91EC, 0x622A, 0xBDD8,
+	0x622B, 0x91ED, 0x622C, 0xEAAF, 0x622D, 0x91EE, 0x622E, 0xC2BE,
+	0x622F, 0x91EF, 0x6230, 0x91F0, 0x6231, 0x91F1, 0x6232, 0x91F2,
+	0x6233, 0xB4C1, 0x6234, 0xB4F7, 0x6235, 0x91F3, 0x6236, 0x91F4,
+	0x6237, 0xBBA7, 0x6238, 0x91F5, 0x6239, 0x91F6, 0x623A, 0x91F7,
+	0x623B, 0x91F8, 0x623C, 0x91F9, 0x623D, 0xECE6, 0x623E, 0xECE5,
+	0x623F, 0xB7BF, 0x6240, 0xCBF9, 0x6241, 0xB1E2, 0x6242, 0x91FA,
+	0x6243, 0xECE7, 0x6244, 0x91FB, 0x6245, 0x91FC, 0x6246, 0x91FD,
+	0x6247, 0xC9C8, 0x6248, 0xECE8, 0x6249, 0xECE9, 0x624A, 0x91FE,
+	0x624B, 0xCAD6, 0x624C, 0xDED0, 0x624D, 0xB2C5, 0x624E, 0xD4FA,
+	0x624F, 0x9240, 0x6250, 0x9241, 0x6251, 0xC6CB, 0x6252, 0xB0C7,
+	0x6253, 0xB4F2, 0x6254, 0xC8D3, 0x6255, 0x9242, 0x6256, 0x9243,
+	0x6257, 0x9244, 0x6258, 0xCDD0, 0x6259, 0x9245, 0x625A, 0x9246,
+	0x625B, 0xBFB8, 0x625C, 0x9247, 0x625D, 0x9248, 0x625E, 0x9249,
+	0x625F, 0x924A, 0x6260, 0x924B, 0x6261, 0x924C, 0x6262, 0x924D,
+	0x6263, 0xBFDB, 0x6264, 0x924E, 0x6265, 0x924F, 0x6266, 0xC7A4,
+	0x6267, 0xD6B4, 0x6268, 0x9250, 0x6269, 0xC0A9, 0x626A, 0xDED1,
+	0x626B, 0xC9A8, 0x626C, 0xD1EF, 0x626D, 0xC5A4, 0x626E, 0xB0E7,
+	0x626F, 0xB3B6, 0x6270, 0xC8C5, 0x6271, 0x9251, 0x6272, 0x9252,
+	0x6273, 0xB0E2, 0x6274, 0x9253, 0x6275, 0x9254, 0x6276, 0xB7F6,
+	0x6277, 0x9255, 0x6278, 0x9256, 0x6279, 0xC5FA, 0x627A, 0x9257,
+	0x627B, 0x9258, 0x627C, 0xB6F3, 0x627D, 0x9259, 0x627E, 0xD5D2,
+	0x627F, 0xB3D0, 0x6280, 0xBCBC, 0x6281, 0x925A, 0x6282, 0x925B,
+	0x6283, 0x925C, 0x6284, 0xB3AD, 0x6285, 0x925D, 0x6286, 0x925E,
+	0x6287, 0x925F, 0x6288, 0x9260, 0x6289, 0xBEF1, 0x628A, 0xB0D1,
+	0x628B, 0x9261, 0x628C, 0x9262, 0x628D, 0x9263, 0x628E, 0x9264,
+	0x628F, 0x9265, 0x6290, 0x9266, 0x6291, 0xD2D6, 0x6292, 0xCAE3,
+	0x6293, 0xD7A5, 0x6294, 0x9267, 0x6295, 0xCDB6, 0x6296, 0xB6B6,
+	0x6297, 0xBFB9, 0x6298, 0xD5DB, 0x6299, 0x9268, 0x629A, 0xB8A7,
+	0x629B, 0xC5D7, 0x629C, 0x9269, 0x629D, 0x926A, 0x629E, 0x926B,
+	0x629F, 0xDED2, 0x62A0, 0xBFD9, 0x62A1, 0xC2D5, 0x62A2, 0xC7C0,
+	0x62A3, 0x926C, 0x62A4, 0xBBA4, 0x62A5, 0xB1A8, 0x62A6, 0x926D,
+	0x62A7, 0x926E, 0x62A8, 0xC5EA, 0x62A9, 0x926F, 0x62AA, 0x9270,
+	0x62AB, 0xC5FB, 0x62AC, 0xCCA7, 0x62AD, 0x9271, 0x62AE, 0x9272,
+	0x62AF, 0x9273, 0x62B0, 0x9274, 0x62B1, 0xB1A7, 0x62B2, 0x9275,
+	0x62B3, 0x9276, 0x62B4, 0x9277, 0x62B5, 0xB5D6, 0x62B6, 0x9278,
+	0x62B7, 0x9279, 0x62B8, 0x927A, 0x62B9, 0xC4A8, 0x62BA, 0x927B,
+	0x62BB, 0xDED3, 0x62BC, 0xD1BA, 0x62BD, 0xB3E9, 0x62BE, 0x927C,
+	0x62BF, 0xC3F2, 0x62C0, 0x927D, 0x62C1, 0x927E, 0x62C2, 0xB7F7,
+	0x62C3, 0x9280, 0x62C4, 0xD6F4, 0x62C5, 0xB5A3, 0x62C6, 0xB2F0,
+	0x62C7, 0xC4B4, 0x62C8, 0xC4E9, 0x62C9, 0xC0AD, 0x62CA, 0xDED4,
+	0x62CB, 0x9281, 0x62CC, 0xB0E8, 0x62CD, 0xC5C4, 0x62CE, 0xC1E0,
+	0x62CF, 0x9282, 0x62D0, 0xB9D5, 0x62D1, 0x9283, 0x62D2, 0xBEDC,
+	0x62D3, 0xCDD8, 0x62D4, 0xB0CE, 0x62D5, 0x9284, 0x62D6, 0xCDCF,
+	0x62D7, 0xDED6, 0x62D8, 0xBED0, 0x62D9, 0xD7BE, 0x62DA, 0xDED5,
+	0x62DB, 0xD5D0, 0x62DC, 0xB0DD, 0x62DD, 0x9285, 0x62DE, 0x9286,
+	0x62DF, 0xC4E2, 0x62E0, 0x9287, 0x62E1, 0x9288, 0x62E2, 0xC2A3,
+	0x62E3, 0xBCF0, 0x62E4, 0x9289, 0x62E5, 0xD3B5, 0x62E6, 0xC0B9,
+	0x62E7, 0xC5A1, 0x62E8, 0xB2A6, 0x62E9, 0xD4F1, 0x62EA, 0x928A,
+	0x62EB, 0x928B, 0x62EC, 0xC0A8, 0x62ED, 0xCAC3, 0x62EE, 0xDED7,
+	0x62EF, 0xD5FC, 0x62F0, 0x928C, 0x62F1, 0xB9B0, 0x62F2, 0x928D,
+	0x62F3, 0xC8AD, 0x62F4, 0xCBA9, 0x62F5, 0x928E, 0x62F6, 0xDED9,
+	0x62F7, 0xBFBD, 0x62F8, 0x928F, 0x62F9, 0x9290, 0x62FA, 0x9291,
+	0x62FB, 0x9292, 0x62FC, 0xC6B4, 0x62FD, 0xD7A7, 0x62FE, 0xCAB0,
+	0x62FF, 0xC4C3, 0x6300, 0x9293, 0x6301, 0xB3D6, 0x6302, 0xB9D2,
+	0x6303, 0x9294, 0x6304, 0x9295, 0x6305, 0x9296, 0x6306, 0x9297,
+	0x6307, 0xD6B8, 0x6308, 0xEAFC, 0x6309, 0xB0B4, 0x630A, 0x9298,
+	0x630B, 0x9299, 0x630C, 0x929A, 0x630D, 0x929B, 0x630E, 0xBFE6,
+	0x630F, 0x929C, 0x6310, 0x929D, 0x6311, 0xCCF4, 0x6312, 0x929E,
+	0x6313, 0x929F, 0x6314, 0x92A0, 0x6315, 0x92A1, 0x6316, 0xCDDA,
+	0x6317, 0x92A2, 0x6318, 0x92A3, 0x6319, 0x92A4, 0x631A, 0xD6BF,
+	0x631B, 0xC2CE, 0x631C, 0x92A5, 0x631D, 0xCECE, 0x631E, 0xCCA2,
+	0x631F, 0xD0AE, 0x6320, 0xC4D3, 0x6321, 0xB5B2, 0x6322, 0xDED8,
+	0x6323, 0xD5F5, 0x6324, 0xBCB7, 0x6325, 0xBBD3, 0x6326, 0x92A6,
+	0x6327, 0x92A7, 0x6328, 0xB0A4, 0x6329, 0x92A8, 0x632A, 0xC5B2,
+	0x632B, 0xB4EC, 0x632C, 0x92A9, 0x632D, 0x92AA, 0x632E, 0x92AB,
+	0x632F, 0xD5F1, 0x6330, 0x92AC, 0x6331, 0x92AD, 0x6332, 0xEAFD,
+	0x6333, 0x92AE, 0x6334, 0x92AF, 0x6335, 0x92B0, 0x6336, 0x92B1,
+	0x6337, 0x92B2, 0x6338, 0x92B3, 0x6339, 0xDEDA, 0x633A, 0xCDA6,
+	0x633B, 0x92B4, 0x633C, 0x92B5, 0x633D, 0xCDEC, 0x633E, 0x92B6,
+	0x633F, 0x92B7, 0x6340, 0x92B8, 0x6341, 0x92B9, 0x6342, 0xCEE6,
+	0x6343, 0xDEDC, 0x6344, 0x92BA, 0x6345, 0xCDB1, 0x6346, 0xC0A6,
+	0x6347, 0x92BB, 0x6348, 0x92BC, 0x6349, 0xD7BD, 0x634A, 0x92BD,
+	0x634B, 0xDEDB, 0x634C, 0xB0C6, 0x634D, 0xBAB4, 0x634E, 0xC9D3,
+	0x634F, 0xC4F3, 0x6350, 0xBEE8, 0x6351, 0x92BE, 0x6352, 0x92BF,
+	0x6353, 0x92C0, 0x6354, 0x92C1, 0x6355, 0xB2B6, 0x6356, 0x92C2,
+	0x6357, 0x92C3, 0x6358, 0x92C4, 0x6359, 0x92C5, 0x635A, 0x92C6,
+	0x635B, 0x92C7, 0x635C, 0x92C8, 0x635D, 0x92C9, 0x635E, 0xC0CC,
+	0x635F, 0xCBF0, 0x6360, 0x92CA, 0x6361, 0xBCF1, 0x6362, 0xBBBB,
+	0x6363, 0xB5B7, 0x6364, 0x92CB, 0x6365, 0x92CC, 0x6366, 0x92CD,
+	0x6367, 0xC5F5, 0x6368, 0x92CE, 0x6369, 0xDEE6, 0x636A, 0x92CF,
+	0x636B, 0x92D0, 0x636C, 0x92D1, 0x636D, 0xDEE3, 0x636E, 0xBEDD,
+	0x636F, 0x92D2, 0x6370, 0x92D3, 0x6371, 0xDEDF, 0x6372, 0x92D4,
+	0x6373, 0x92D5, 0x6374, 0x92D6, 0x6375, 0x92D7, 0x6376, 0xB4B7,
+	0x6377, 0xBDDD, 0x6378, 0x92D8, 0x6379, 0x92D9, 0x637A, 0xDEE0,
+	0x637B, 0xC4ED, 0x637C, 0x92DA, 0x637D, 0x92DB, 0x637E, 0x92DC,
+	0x637F, 0x92DD, 0x6380, 0xCFC6, 0x6381, 0x92DE, 0x6382, 0xB5E0,
+	0x6383, 0x92DF, 0x6384, 0x92E0, 0x6385, 0x92E1, 0x6386, 0x92E2,
+	0x6387, 0xB6DE, 0x6388, 0xCADA, 0x6389, 0xB5F4, 0x638A, 0xDEE5,
+	0x638B, 0x92E3, 0x638C, 0xD5C6, 0x638D, 0x92E4, 0x638E, 0xDEE1,
+	0x638F, 0xCCCD, 0x6390, 0xC6FE, 0x6391, 0x92E5, 0x6392, 0xC5C5,
+	0x6393, 0x92E6, 0x6394, 0x92E7, 0x6395, 0x92E8, 0x6396, 0xD2B4,
+	0x6397, 0x92E9, 0x6398, 0xBEF2, 0x6399, 0x92EA, 0x639A, 0x92EB,
+	0x639B, 0x92EC, 0x639C, 0x92ED, 0x639D, 0x92EE, 0x639E, 0x92EF,
+	0x639F, 0x92F0, 0x63A0, 0xC2D3, 0x63A1, 0x92F1, 0x63A2, 0xCCBD,
+	0x63A3, 0xB3B8, 0x63A4, 0x92F2, 0x63A5, 0xBDD3, 0x63A6, 0x92F3,
+	0x63A7, 0xBFD8, 0x63A8, 0xCDC6, 0x63A9, 0xD1DA, 0x63AA, 0xB4EB,
+	0x63AB, 0x92F4, 0x63AC, 0xDEE4, 0x63AD, 0xDEDD, 0x63AE, 0xDEE7,
+	0x63AF, 0x92F5, 0x63B0, 0xEAFE, 0x63B1, 0x92F6, 0x63B2, 0x92F7,
+	0x63B3, 0xC2B0, 0x63B4, 0xDEE2, 0x63B5, 0x92F8, 0x63B6, 0x92F9,
+	0x63B7, 0xD6C0, 0x63B8, 0xB5A7, 0x63B9, 0x92FA, 0x63BA, 0xB2F4,
+	0x63BB, 0x92FB, 0x63BC, 0xDEE8, 0x63BD, 0x92FC, 0x63BE, 0xDEF2,
+	0x63BF, 0x92FD, 0x63C0, 0x92FE, 0x63C1, 0x9340, 0x63C2, 0x9341,
+	0x63C3, 0x9342, 0x63C4, 0xDEED, 0x63C5, 0x9343, 0x63C6, 0xDEF1,
+	0x63C7, 0x9344, 0x63C8, 0x9345, 0x63C9, 0xC8E0, 0x63CA, 0x9346,
+	0x63CB, 0x9347, 0x63CC, 0x9348, 0x63CD, 0xD7E1, 0x63CE, 0xDEEF,
+	0x63CF, 0xC3E8, 0x63D0, 0xCCE1, 0x63D1, 0x9349, 0x63D2, 0xB2E5,
+	0x63D3, 0x934A, 0x63D4, 0x934B, 0x63D5, 0x934C, 0x63D6, 0xD2BE,
+	0x63D7, 0x934D, 0x63D8, 0x934E, 0x63D9, 0x934F, 0x63DA, 0x9350,
+	0x63DB, 0x9351, 0x63DC, 0x9352, 0x63DD, 0x9353, 0x63DE, 0xDEEE,
+	0x63DF, 0x9354, 0x63E0, 0xDEEB, 0x63E1, 0xCED5, 0x63E2, 0x9355,
+	0x63E3, 0xB4A7, 0x63E4, 0x9356, 0x63E5, 0x9357, 0x63E6, 0x9358,
+	0x63E7, 0x9359, 0x63E8, 0x935A, 0x63E9, 0xBFAB, 0x63EA, 0xBEBE,
+	0x63EB, 0x935B, 0x63EC, 0x935C, 0x63ED, 0xBDD2, 0x63EE, 0x935D,
+	0x63EF, 0x935E, 0x63F0, 0x935F, 0x63F1, 0x9360, 0x63F2, 0xDEE9,
+	0x63F3, 0x9361, 0x63F4, 0xD4AE, 0x63F5, 0x9362, 0x63F6, 0xDEDE,
+	0x63F7, 0x9363, 0x63F8, 0xDEEA, 0x63F9, 0x9364, 0x63FA, 0x9365,
+	0x63FB, 0x9366, 0x63FC, 0x9367, 0x63FD, 0xC0BF, 0x63FE, 0x9368,
+	0x63FF, 0xDEEC, 0x6400, 0xB2F3, 0x6401, 0xB8E9, 0x6402, 0xC2A7,
+	0x6403, 0x9369, 0x6404, 0x936A, 0x6405, 0xBDC1, 0x6406, 0x936B,
+	0x6407, 0x936C, 0x6408, 0x936D, 0x6409, 0x936E, 0x640A, 0x936F,
+	0x640B, 0xDEF5, 0x640C, 0xDEF8, 0x640D, 0x9370, 0x640E, 0x9371,
+	0x640F, 0xB2AB, 0x6410, 0xB4A4, 0x6411, 0x9372, 0x6412, 0x9373,
+	0x6413, 0xB4EA, 0x6414, 0xC9A6, 0x6415, 0x9374, 0x6416, 0x9375,
+	0x6417, 0x9376, 0x6418, 0x9377, 0x6419, 0x9378, 0x641A, 0x9379,
+	0x641B, 0xDEF6, 0x641C, 0xCBD1, 0x641D, 0x937A, 0x641E, 0xB8E3,
+	0x641F, 0x937B, 0x6420, 0xDEF7, 0x6421, 0xDEFA, 0x6422, 0x937C,
+	0x6423, 0x937D, 0x6424, 0x937E, 0x6425, 0x9380, 0x6426, 0xDEF9,
+	0x6427, 0x9381, 0x6428, 0x9382, 0x6429, 0x9383, 0x642A, 0xCCC2,
+	0x642B, 0x9384, 0x642C, 0xB0E1, 0x642D, 0xB4EE, 0x642E, 0x9385,
+	0x642F, 0x9386, 0x6430, 0x9387, 0x6431, 0x9388, 0x6432, 0x9389,
+	0x6433, 0x938A, 0x6434, 0xE5BA, 0x6435, 0x938B, 0x6436, 0x938C,
+	0x6437, 0x938D, 0x6438, 0x938E, 0x6439, 0x938F, 0x643A, 0xD0AF,
+	0x643B, 0x9390, 0x643C, 0x9391, 0x643D, 0xB2EB, 0x643E, 0x9392,
+	0x643F, 0xEBA1, 0x6440, 0x9393, 0x6441, 0xDEF4, 0x6442, 0x9394,
+	0x6443, 0x9395, 0x6444, 0xC9E3, 0x6445, 0xDEF3, 0x6446, 0xB0DA,
+	0x6447, 0xD2A1, 0x6448, 0xB1F7, 0x6449, 0x9396, 0x644A, 0xCCAF,
+	0x644B, 0x9397, 0x644C, 0x9398, 0x644D, 0x9399, 0x644E, 0x939A,
+	0x644F, 0x939B, 0x6450, 0x939C, 0x6451, 0x939D, 0x6452, 0xDEF0,
+	0x6453, 0x939E, 0x6454, 0xCBA4, 0x6455, 0x939F, 0x6456, 0x93A0,
+	0x6457, 0x93A1, 0x6458, 0xD5AA, 0x6459, 0x93A2, 0x645A, 0x93A3,
+	0x645B, 0x93A4, 0x645C, 0x93A5, 0x645D, 0x93A6, 0x645E, 0xDEFB,
+	0x645F, 0x93A7, 0x6460, 0x93A8, 0x6461, 0x93A9, 0x6462, 0x93AA,
+	0x6463, 0x93AB, 0x6464, 0x93AC, 0x6465, 0x93AD, 0x6466, 0x93AE,
+	0x6467, 0xB4DD, 0x6468, 0x93AF, 0x6469, 0xC4A6, 0x646A, 0x93B0,
+	0x646B, 0x93B1, 0x646C, 0x93B2, 0x646D, 0xDEFD, 0x646E, 0x93B3,
+	0x646F, 0x93B4, 0x6470, 0x93B5, 0x6471, 0x93B6, 0x6472, 0x93B7,
+	0x6473, 0x93B8, 0x6474, 0x93B9, 0x6475, 0x93BA, 0x6476, 0x93BB,
+	0x6477, 0x93BC, 0x6478, 0xC3FE, 0x6479, 0xC4A1, 0x647A, 0xDFA1,
+	0x647B, 0x93BD, 0x647C, 0x93BE, 0x647D, 0x93BF, 0x647E, 0x93C0,
+	0x647F, 0x93C1, 0x6480, 0x93C2, 0x6481, 0x93C3, 0x6482, 0xC1CC,
+	0x6483, 0x93C4, 0x6484, 0xDEFC, 0x6485, 0xBEEF, 0x6486, 0x93C5,
+	0x6487, 0xC6B2, 0x6488, 0x93C6, 0x6489, 0x93C7, 0x648A, 0x93C8,
+	0x648B, 0x93C9, 0x648C, 0x93CA, 0x648D, 0x93CB, 0x648E, 0x93CC,
+	0x648F, 0x93CD, 0x6490, 0x93CE, 0x6491, 0xB3C5, 0x6492, 0xC8F6,
+	0x6493, 0x93CF, 0x6494, 0x93D0, 0x6495, 0xCBBA, 0x6496, 0xDEFE,
+	0x6497, 0x93D1, 0x6498, 0x93D2, 0x6499, 0xDFA4, 0x649A, 0x93D3,
+	0x649B, 0x93D4, 0x649C, 0x93D5, 0x649D, 0x93D6, 0x649E, 0xD7B2,
+	0x649F, 0x93D7, 0x64A0, 0x93D8, 0x64A1, 0x93D9, 0x64A2, 0x93DA,
+	0x64A3, 0x93DB, 0x64A4, 0xB3B7, 0x64A5, 0x93DC, 0x64A6, 0x93DD,
+	0x64A7, 0x93DE, 0x64A8, 0x93DF, 0x64A9, 0xC1C3, 0x64AA, 0x93E0,
+	0x64AB, 0x93E1, 0x64AC, 0xC7CB, 0x64AD, 0xB2A5, 0x64AE, 0xB4E9,
+	0x64AF, 0x93E2, 0x64B0, 0xD7AB, 0x64B1, 0x93E3, 0x64B2, 0x93E4,
+	0x64B3, 0x93E5, 0x64B4, 0x93E6, 0x64B5, 0xC4EC, 0x64B6, 0x93E7,
+	0x64B7, 0xDFA2, 0x64B8, 0xDFA3, 0x64B9, 0x93E8, 0x64BA, 0xDFA5,
+	0x64BB, 0x93E9, 0x64BC, 0xBAB3, 0x64BD, 0x93EA, 0x64BE, 0x93EB,
+	0x64BF, 0x93EC, 0x64C0, 0xDFA6, 0x64C1, 0x93ED, 0x64C2, 0xC0DE,
+	0x64C3, 0x93EE, 0x64C4, 0x93EF, 0x64C5, 0xC9C3, 0x64C6, 0x93F0,
+	0x64C7, 0x93F1, 0x64C8, 0x93F2, 0x64C9, 0x93F3, 0x64CA, 0x93F4,
+	0x64CB, 0x93F5, 0x64CC, 0x93F6, 0x64CD, 0xB2D9, 0x64CE, 0xC7E6,
+	0x64CF, 0x93F7, 0x64D0, 0xDFA7, 0x64D1, 0x93F8, 0x64D2, 0xC7DC,
+	0x64D3, 0x93F9, 0x64D4, 0x93FA, 0x64D5, 0x93FB, 0x64D6, 0x93FC,
+	0x64D7, 0xDFA8, 0x64D8, 0xEBA2, 0x64D9, 0x93FD, 0x64DA, 0x93FE,
+	0x64DB, 0x9440, 0x64DC, 0x9441, 0x64DD, 0x9442, 0x64DE, 0xCBD3,
+	0x64DF, 0x9443, 0x64E0, 0x9444, 0x64E1, 0x9445, 0x64E2, 0xDFAA,
+	0x64E3, 0x9446, 0x64E4, 0xDFA9, 0x64E5, 0x9447, 0x64E6, 0xB2C1,
+	0x64E7, 0x9448, 0x64E8, 0x9449, 0x64E9, 0x944A, 0x64EA, 0x944B,
+	0x64EB, 0x944C, 0x64EC, 0x944D, 0x64ED, 0x944E, 0x64EE, 0x944F,
+	0x64EF, 0x9450, 0x64F0, 0x9451, 0x64F1, 0x9452, 0x64F2, 0x9453,
+	0x64F3, 0x9454, 0x64F4, 0x9455, 0x64F5, 0x9456, 0x64F6, 0x9457,
+	0x64F7, 0x9458, 0x64F8, 0x9459, 0x64F9, 0x945A, 0x64FA, 0x945B,
+	0x64FB, 0x945C, 0x64FC, 0x945D, 0x64FD, 0x945E, 0x64FE, 0x945F,
+	0x64FF, 0x9460, 0x6500, 0xC5CA, 0x6501, 0x9461, 0x6502, 0x9462,
+	0x6503, 0x9463, 0x6504, 0x9464, 0x6505, 0x9465, 0x6506, 0x9466,
+	0x6507, 0x9467, 0x6508, 0x9468, 0x6509, 0xDFAB, 0x650A, 0x9469,
+	0x650B, 0x946A, 0x650C, 0x946B, 0x650D, 0x946C, 0x650E, 0x946D,
+	0x650F, 0x946E, 0x6510, 0x946F, 0x6511, 0x9470, 0x6512, 0xD4DC,
+	0x6513, 0x9471, 0x6514, 0x9472, 0x6515, 0x9473, 0x6516, 0x9474,
+	0x6517, 0x9475, 0x6518, 0xC8C1, 0x6519, 0x9476, 0x651A, 0x9477,
+	0x651B, 0x9478, 0x651C, 0x9479, 0x651D, 0x947A, 0x651E, 0x947B,
+	0x651F, 0x947C, 0x6520, 0x947D, 0x6521, 0x947E, 0x6522, 0x9480,
+	0x6523, 0x9481, 0x6524, 0x9482, 0x6525, 0xDFAC, 0x6526, 0x9483,
+	0x6527, 0x9484, 0x6528, 0x9485, 0x6529, 0x9486, 0x652A, 0x9487,
+	0x652B, 0xBEF0, 0x652C, 0x9488, 0x652D, 0x9489, 0x652E, 0xDFAD,
+	0x652F, 0xD6A7, 0x6530, 0x948A, 0x6531, 0x948B, 0x6532, 0x948C,
+	0x6533, 0x948D, 0x6534, 0xEAB7, 0x6535, 0xEBB6, 0x6536, 0xCAD5,
+	0x6537, 0x948E, 0x6538, 0xD8FC, 0x6539, 0xB8C4, 0x653A, 0x948F,
+	0x653B, 0xB9A5, 0x653C, 0x9490, 0x653D, 0x9491, 0x653E, 0xB7C5,
+	0x653F, 0xD5FE, 0x6540, 0x9492, 0x6541, 0x9493, 0x6542, 0x9494,
+	0x6543, 0x9495, 0x6544, 0x9496, 0x6545, 0xB9CA, 0x6546, 0x9497,
+	0x6547, 0x9498, 0x6548, 0xD0A7, 0x6549, 0xF4CD, 0x654A, 0x9499,
+	0x654B, 0x949A, 0x654C, 0xB5D0, 0x654D, 0x949B, 0x654E, 0x949C,
+	0x654F, 0xC3F4, 0x6550, 0x949D, 0x6551, 0xBEC8, 0x6552, 0x949E,
+	0x6553, 0x949F, 0x6554, 0x94A0, 0x6555, 0xEBB7, 0x6556, 0xB0BD,
+	0x6557, 0x94A1, 0x6558, 0x94A2, 0x6559, 0xBDCC, 0x655A, 0x94A3,
+	0x655B, 0xC1B2, 0x655C, 0x94A4, 0x655D, 0xB1D6, 0x655E, 0xB3A8,
+	0x655F, 0x94A5, 0x6560, 0x94A6, 0x6561, 0x94A7, 0x6562, 0xB8D2,
+	0x6563, 0xC9A2, 0x6564, 0x94A8, 0x6565, 0x94A9, 0x6566, 0xB6D8,
+	0x6567, 0x94AA, 0x6568, 0x94AB, 0x6569, 0x94AC, 0x656A, 0x94AD,
+	0x656B, 0xEBB8, 0x656C, 0xBEB4, 0x656D, 0x94AE, 0x656E, 0x94AF,
+	0x656F, 0x94B0, 0x6570, 0xCAFD, 0x6571, 0x94B1, 0x6572, 0xC7C3,
+	0x6573, 0x94B2, 0x6574, 0xD5FB, 0x6575, 0x94B3, 0x6576, 0x94B4,
+	0x6577, 0xB7F3, 0x6578, 0x94B5, 0x6579, 0x94B6, 0x657A, 0x94B7,
+	0x657B, 0x94B8, 0x657C, 0x94B9, 0x657D, 0x94BA, 0x657E, 0x94BB,
+	0x657F, 0x94BC, 0x6580, 0x94BD, 0x6581, 0x94BE, 0x6582, 0x94BF,
+	0x6583, 0x94C0, 0x6584, 0x94C1, 0x6585, 0x94C2, 0x6586, 0x94C3,
+	0x6587, 0xCEC4, 0x6588, 0x94C4, 0x6589, 0x94C5, 0x658A, 0x94C6,
+	0x658B, 0xD5AB, 0x658C, 0xB1F3, 0x658D, 0x94C7, 0x658E, 0x94C8,
+	0x658F, 0x94C9, 0x6590, 0xECB3, 0x6591, 0xB0DF, 0x6592, 0x94CA,
+	0x6593, 0xECB5, 0x6594, 0x94CB, 0x6595, 0x94CC, 0x6596, 0x94CD,
+	0x6597, 0xB6B7, 0x6598, 0x94CE, 0x6599, 0xC1CF, 0x659A, 0x94CF,
+	0x659B, 0xF5FA, 0x659C, 0xD0B1, 0x659D, 0x94D0, 0x659E, 0x94D1,
+	0x659F, 0xD5E5, 0x65A0, 0x94D2, 0x65A1, 0xCED3, 0x65A2, 0x94D3,
+	0x65A3, 0x94D4, 0x65A4, 0xBDEF, 0x65A5, 0xB3E2, 0x65A6, 0x94D5,
+	0x65A7, 0xB8AB, 0x65A8, 0x94D6, 0x65A9, 0xD5B6, 0x65AA, 0x94D7,
+	0x65AB, 0xEDBD, 0x65AC, 0x94D8, 0x65AD, 0xB6CF, 0x65AE, 0x94D9,
+	0x65AF, 0xCBB9, 0x65B0, 0xD0C2, 0x65B1, 0x94DA, 0x65B2, 0x94DB,
+	0x65B3, 0x94DC, 0x65B4, 0x94DD, 0x65B5, 0x94DE, 0x65B6, 0x94DF,
+	0x65B7, 0x94E0, 0x65B8, 0x94E1, 0x65B9, 0xB7BD, 0x65BA, 0x94E2,
+	0x65BB, 0x94E3, 0x65BC, 0xECB6, 0x65BD, 0xCAA9, 0x65BE, 0x94E4,
+	0x65BF, 0x94E5, 0x65C0, 0x94E6, 0x65C1, 0xC5D4, 0x65C2, 0x94E7,
+	0x65C3, 0xECB9, 0x65C4, 0xECB8, 0x65C5, 0xC2C3, 0x65C6, 0xECB7,
+	0x65C7, 0x94E8, 0x65C8, 0x94E9, 0x65C9, 0x94EA, 0x65CA, 0x94EB,
+	0x65CB, 0xD0FD, 0x65CC, 0xECBA, 0x65CD, 0x94EC, 0x65CE, 0xECBB,
+	0x65CF, 0xD7E5, 0x65D0, 0x94ED, 0x65D1, 0x94EE, 0x65D2, 0xECBC,
+	0x65D3, 0x94EF, 0x65D4, 0x94F0, 0x65D5, 0x94F1, 0x65D6, 0xECBD,
+	0x65D7, 0xC6EC, 0x65D8, 0x94F2, 0x65D9, 0x94F3, 0x65DA, 0x94F4,
+	0x65DB, 0x94F5, 0x65DC, 0x94F6, 0x65DD, 0x94F7, 0x65DE, 0x94F8,
+	0x65DF, 0x94F9, 0x65E0, 0xCEDE, 0x65E1, 0x94FA, 0x65E2, 0xBCC8,
+	0x65E3, 0x94FB, 0x65E4, 0x94FC, 0x65E5, 0xC8D5, 0x65E6, 0xB5A9,
+	0x65E7, 0xBEC9, 0x65E8, 0xD6BC, 0x65E9, 0xD4E7, 0x65EA, 0x94FD,
+	0x65EB, 0x94FE, 0x65EC, 0xD1AE, 0x65ED, 0xD0F1, 0x65EE, 0xEAB8,
+	0x65EF, 0xEAB9, 0x65F0, 0xEABA, 0x65F1, 0xBAB5, 0x65F2, 0x9540,
+	0x65F3, 0x9541, 0x65F4, 0x9542, 0x65F5, 0x9543, 0x65F6, 0xCAB1,
+	0x65F7, 0xBFF5, 0x65F8, 0x9544, 0x65F9, 0x9545, 0x65FA, 0xCDFA,
+	0x65FB, 0x9546, 0x65FC, 0x9547, 0x65FD, 0x9548, 0x65FE, 0x9549,
+	0x65FF, 0x954A, 0x6600, 0xEAC0, 0x6601, 0x954B, 0x6602, 0xB0BA,
+	0x6603, 0xEABE, 0x6604, 0x954C, 0x6605, 0x954D, 0x6606, 0xC0A5,
+	0x6607, 0x954E, 0x6608, 0x954F, 0x6609, 0x9550, 0x660A, 0xEABB,
+	0x660B, 0x9551, 0x660C, 0xB2FD, 0x660D, 0x9552, 0x660E, 0xC3F7,
+	0x660F, 0xBBE8, 0x6610, 0x9553, 0x6611, 0x9554, 0x6612, 0x9555,
+	0x6613, 0xD2D7, 0x6614, 0xCEF4, 0x6615, 0xEABF, 0x6616, 0x9556,
+	0x6617, 0x9557, 0x6618, 0x9558, 0x6619, 0xEABC, 0x661A, 0x9559,
+	0x661B, 0x955A, 0x661C, 0x955B, 0x661D, 0xEAC3, 0x661E, 0x955C,
+	0x661F, 0xD0C7, 0x6620, 0xD3B3, 0x6621, 0x955D, 0x6622, 0x955E,
+	0x6623, 0x955F, 0x6624, 0x9560, 0x6625, 0xB4BA, 0x6626, 0x9561,
+	0x6627, 0xC3C1, 0x6628, 0xD7F2, 0x6629, 0x9562, 0x662A, 0x9563,
+	0x662B, 0x9564, 0x662C, 0x9565, 0x662D, 0xD5D1, 0x662E, 0x9566,
+	0x662F, 0xCAC7, 0x6630, 0x9567, 0x6631, 0xEAC5, 0x6632, 0x9568,
+	0x6633, 0x9569, 0x6634, 0xEAC4, 0x6635, 0xEAC7, 0x6636, 0xEAC6,
+	0x6637, 0x956A, 0x6638, 0x956B, 0x6639, 0x956C, 0x663A, 0x956D,
+	0x663B, 0x956E, 0x663C, 0xD6E7, 0x663D, 0x956F, 0x663E, 0xCFD4,
+	0x663F, 0x9570, 0x6640, 0x9571, 0x6641, 0xEACB, 0x6642, 0x9572,
+	0x6643, 0xBBCE, 0x6644, 0x9573, 0x6645, 0x9574, 0x6646, 0x9575,
+	0x6647, 0x9576, 0x6648, 0x9577, 0x6649, 0x9578, 0x664A, 0x9579,
+	0x664B, 0xBDFA, 0x664C, 0xC9CE, 0x664D, 0x957A, 0x664E, 0x957B,
+	0x664F, 0xEACC, 0x6650, 0x957C, 0x6651, 0x957D, 0x6652, 0xC9B9,
+	0x6653, 0xCFFE, 0x6654, 0xEACA, 0x6655, 0xD4CE, 0x6656, 0xEACD,
+	0x6657, 0xEACF, 0x6658, 0x957E, 0x6659, 0x9580, 0x665A, 0xCDED,
+	0x665B, 0x9581, 0x665C, 0x9582, 0x665D, 0x9583, 0x665E, 0x9584,
+	0x665F, 0xEAC9, 0x6660, 0x9585, 0x6661, 0xEACE, 0x6662, 0x9586,
+	0x6663, 0x9587, 0x6664, 0xCEEE, 0x6665, 0x9588, 0x6666, 0xBBDE,
+	0x6667, 0x9589, 0x6668, 0xB3BF, 0x6669, 0x958A, 0x666A, 0x958B,
+	0x666B, 0x958C, 0x666C, 0x958D, 0x666D, 0x958E, 0x666E, 0xC6D5,
+	0x666F, 0xBEB0, 0x6670, 0xCEFA, 0x6671, 0x958F, 0x6672, 0x9590,
+	0x6673, 0x9591, 0x6674, 0xC7E7, 0x6675, 0x9592, 0x6676, 0xBEA7,
+	0x6677, 0xEAD0, 0x6678, 0x9593, 0x6679, 0x9594, 0x667A, 0xD6C7,
+	0x667B, 0x9595, 0x667C, 0x9596, 0x667D, 0x9597, 0x667E, 0xC1C0,
+	0x667F, 0x9598, 0x6680, 0x9599, 0x6681, 0x959A, 0x6682, 0xD4DD,
+	0x6683, 0x959B, 0x6684, 0xEAD1, 0x6685, 0x959C, 0x6686, 0x959D,
+	0x6687, 0xCFBE, 0x6688, 0x959E, 0x6689, 0x959F, 0x668A, 0x95A0,
+	0x668B, 0x95A1, 0x668C, 0xEAD2, 0x668D, 0x95A2, 0x668E, 0x95A3,
+	0x668F, 0x95A4, 0x6690, 0x95A5, 0x6691, 0xCAEE, 0x6692, 0x95A6,
+	0x6693, 0x95A7, 0x6694, 0x95A8, 0x6695, 0x95A9, 0x6696, 0xC5AF,
+	0x6697, 0xB0B5, 0x6698, 0x95AA, 0x6699, 0x95AB, 0x669A, 0x95AC,
+	0x669B, 0x95AD, 0x669C, 0x95AE, 0x669D, 0xEAD4, 0x669E, 0x95AF,
+	0x669F, 0x95B0, 0x66A0, 0x95B1, 0x66A1, 0x95B2, 0x66A2, 0x95B3,
+	0x66A3, 0x95B4, 0x66A4, 0x95B5, 0x66A5, 0x95B6, 0x66A6, 0x95B7,
+	0x66A7, 0xEAD3, 0x66A8, 0xF4DF, 0x66A9, 0x95B8, 0x66AA, 0x95B9,
+	0x66AB, 0x95BA, 0x66AC, 0x95BB, 0x66AD, 0x95BC, 0x66AE, 0xC4BA,
+	0x66AF, 0x95BD, 0x66B0, 0x95BE, 0x66B1, 0x95BF, 0x66B2, 0x95C0,
+	0x66B3, 0x95C1, 0x66B4, 0xB1A9, 0x66B5, 0x95C2, 0x66B6, 0x95C3,
+	0x66B7, 0x95C4, 0x66B8, 0x95C5, 0x66B9, 0xE5DF, 0x66BA, 0x95C6,
+	0x66BB, 0x95C7, 0x66BC, 0x95C8, 0x66BD, 0x95C9, 0x66BE, 0xEAD5,
+	0x66BF, 0x95CA, 0x66C0, 0x95CB, 0x66C1, 0x95CC, 0x66C2, 0x95CD,
+	0x66C3, 0x95CE, 0x66C4, 0x95CF, 0x66C5, 0x95D0, 0x66C6, 0x95D1,
+	0x66C7, 0x95D2, 0x66C8, 0x95D3, 0x66C9, 0x95D4, 0x66CA, 0x95D5,
+	0x66CB, 0x95D6, 0x66CC, 0x95D7, 0x66CD, 0x95D8, 0x66CE, 0x95D9,
+	0x66CF, 0x95DA, 0x66D0, 0x95DB, 0x66D1, 0x95DC, 0x66D2, 0x95DD,
+	0x66D3, 0x95DE, 0x66D4, 0x95DF, 0x66D5, 0x95E0, 0x66D6, 0x95E1,
+	0x66D7, 0x95E2, 0x66D8, 0x95E3, 0x66D9, 0xCAEF, 0x66DA, 0x95E4,
+	0x66DB, 0xEAD6, 0x66DC, 0xEAD7, 0x66DD, 0xC6D8, 0x66DE, 0x95E5,
+	0x66DF, 0x95E6, 0x66E0, 0x95E7, 0x66E1, 0x95E8, 0x66E2, 0x95E9,
+	0x66E3, 0x95EA, 0x66E4, 0x95EB, 0x66E5, 0x95EC, 0x66E6, 0xEAD8,
+	0x66E7, 0x95ED, 0x66E8, 0x95EE, 0x66E9, 0xEAD9, 0x66EA, 0x95EF,
+	0x66EB, 0x95F0, 0x66EC, 0x95F1, 0x66ED, 0x95F2, 0x66EE, 0x95F3,
+	0x66EF, 0x95F4, 0x66F0, 0xD4BB, 0x66F1, 0x95F5, 0x66F2, 0xC7FA,
+	0x66F3, 0xD2B7, 0x66F4, 0xB8FC, 0x66F5, 0x95F6, 0x66F6, 0x95F7,
+	0x66F7, 0xEAC2, 0x66F8, 0x95F8, 0x66F9, 0xB2DC, 0x66FA, 0x95F9,
+	0x66FB, 0x95FA, 0x66FC, 0xC2FC, 0x66FD, 0x95FB, 0x66FE, 0xD4F8,
+	0x66FF, 0xCCE6, 0x6700, 0xD7EE, 0x6701, 0x95FC, 0x6702, 0x95FD,
+	0x6703, 0x95FE, 0x6704, 0x9640, 0x6705, 0x9641, 0x6706, 0x9642,
+	0x6707, 0x9643, 0x6708, 0xD4C2, 0x6709, 0xD3D0, 0x670A, 0xEBC3,
+	0x670B, 0xC5F3, 0x670C, 0x9644, 0x670D, 0xB7FE, 0x670E, 0x9645,
+	0x670F, 0x9646, 0x6710, 0xEBD4, 0x6711, 0x9647, 0x6712, 0x9648,
+	0x6713, 0x9649, 0x6714, 0xCBB7, 0x6715, 0xEBDE, 0x6716, 0x964A,
+	0x6717, 0xC0CA, 0x6718, 0x964B, 0x6719, 0x964C, 0x671A, 0x964D,
+	0x671B, 0xCDFB, 0x671C, 0x964E, 0x671D, 0xB3AF, 0x671E, 0x964F,
+	0x671F, 0xC6DA, 0x6720, 0x9650, 0x6721, 0x9651, 0x6722, 0x9652,
+	0x6723, 0x9653, 0x6724, 0x9654, 0x6725, 0x9655, 0x6726, 0xEBFC,
+	0x6727, 0x9656, 0x6728, 0xC4BE, 0x6729, 0x9657, 0x672A, 0xCEB4,
+	0x672B, 0xC4A9, 0x672C, 0xB1BE, 0x672D, 0xD4FD, 0x672E, 0x9658,
+	0x672F, 0xCAF5, 0x6730, 0x9659, 0x6731, 0xD6EC, 0x6732, 0x965A,
+	0x6733, 0x965B, 0x6734, 0xC6D3, 0x6735, 0xB6E4, 0x6736, 0x965C,
+	0x6737, 0x965D, 0x6738, 0x965E, 0x6739, 0x965F, 0x673A, 0xBBFA,
+	0x673B, 0x9660, 0x673C, 0x9661, 0x673D, 0xD0E0, 0x673E, 0x9662,
+	0x673F, 0x9663, 0x6740, 0xC9B1, 0x6741, 0x9664, 0x6742, 0xD4D3,
+	0x6743, 0xC8A8, 0x6744, 0x9665, 0x6745, 0x9666, 0x6746, 0xB8CB,
+	0x6747, 0x9667, 0x6748, 0xE8BE, 0x6749, 0xC9BC, 0x674A, 0x9668,
+	0x674B, 0x9669, 0x674C, 0xE8BB, 0x674D, 0x966A, 0x674E, 0xC0EE,
+	0x674F, 0xD0D3, 0x6750, 0xB2C4, 0x6751, 0xB4E5, 0x6752, 0x966B,
+	0x6753, 0xE8BC, 0x6754, 0x966C, 0x6755, 0x966D, 0x6756, 0xD5C8,
+	0x6757, 0x966E, 0x6758, 0x966F, 0x6759, 0x9670, 0x675A, 0x9671,
+	0x675B, 0x9672, 0x675C, 0xB6C5, 0x675D, 0x9673, 0x675E, 0xE8BD,
+	0x675F, 0xCAF8, 0x6760, 0xB8DC, 0x6761, 0xCCF5, 0x6762, 0x9674,
+	0x6763, 0x9675, 0x6764, 0x9676, 0x6765, 0xC0B4, 0x6766, 0x9677,
+	0x6767, 0x9678, 0x6768, 0xD1EE, 0x6769, 0xE8BF, 0x676A, 0xE8C2,
+	0x676B, 0x9679, 0x676C, 0x967A, 0x676D, 0xBABC, 0x676E, 0x967B,
+	0x676F, 0xB1AD, 0x6770, 0xBDDC, 0x6771, 0x967C, 0x6772, 0xEABD,
+	0x6773, 0xE8C3, 0x6774, 0x967D, 0x6775, 0xE8C6, 0x6776, 0x967E,
+	0x6777, 0xE8CB, 0x6778, 0x9680, 0x6779, 0x9681, 0x677A, 0x9682,
+	0x677B, 0x9683, 0x677C, 0xE8CC, 0x677D, 0x9684, 0x677E, 0xCBC9,
+	0x677F, 0xB0E5, 0x6780, 0x9685, 0x6781, 0xBCAB, 0x6782, 0x9686,
+	0x6783, 0x9687, 0x6784, 0xB9B9, 0x6785, 0x9688, 0x6786, 0x9689,
+	0x6787, 0xE8C1, 0x6788, 0x968A, 0x6789, 0xCDF7, 0x678A, 0x968B,
+	0x678B, 0xE8CA, 0x678C, 0x968C, 0x678D, 0x968D, 0x678E, 0x968E,
+	0x678F, 0x968F, 0x6790, 0xCEF6, 0x6791, 0x9690, 0x6792, 0x9691,
+	0x6793, 0x9692, 0x6794, 0x9693, 0x6795, 0xD5ED, 0x6796, 0x9694,
+	0x6797, 0xC1D6, 0x6798, 0xE8C4, 0x6799, 0x9695, 0x679A, 0xC3B6,
+	0x679B, 0x9696, 0x679C, 0xB9FB, 0x679D, 0xD6A6, 0x679E, 0xE8C8,
+	0x679F, 0x9697, 0x67A0, 0x9698, 0x67A1, 0x9699, 0x67A2, 0xCAE0,
+	0x67A3, 0xD4E6, 0x67A4, 0x969A, 0x67A5, 0xE8C0, 0x67A6, 0x969B,
+	0x67A7, 0xE8C5, 0x67A8, 0xE8C7, 0x67A9, 0x969C, 0x67AA, 0xC7B9,
+	0x67AB, 0xB7E3, 0x67AC, 0x969D, 0x67AD, 0xE8C9, 0x67AE, 0x969E,
+	0x67AF, 0xBFDD, 0x67B0, 0xE8D2, 0x67B1, 0x969F, 0x67B2, 0x96A0,
+	0x67B3, 0xE8D7, 0x67B4, 0x96A1, 0x67B5, 0xE8D5, 0x67B6, 0xBCDC,
+	0x67B7, 0xBCCF, 0x67B8, 0xE8DB, 0x67B9, 0x96A2, 0x67BA, 0x96A3,
+	0x67BB, 0x96A4, 0x67BC, 0x96A5, 0x67BD, 0x96A6, 0x67BE, 0x96A7,
+	0x67BF, 0x96A8, 0x67C0, 0x96A9, 0x67C1, 0xE8DE, 0x67C2, 0x96AA,
+	0x67C3, 0xE8DA, 0x67C4, 0xB1FA, 0x67C5, 0x96AB, 0x67C6, 0x96AC,
+	0x67C7, 0x96AD, 0x67C8, 0x96AE, 0x67C9, 0x96AF, 0x67CA, 0x96B0,
+	0x67CB, 0x96B1, 0x67CC, 0x96B2, 0x67CD, 0x96B3, 0x67CE, 0x96B4,
+	0x67CF, 0xB0D8, 0x67D0, 0xC4B3, 0x67D1, 0xB8CC, 0x67D2, 0xC6E2,
+	0x67D3, 0xC8BE, 0x67D4, 0xC8E1, 0x67D5, 0x96B5, 0x67D6, 0x96B6,
+	0x67D7, 0x96B7, 0x67D8, 0xE8CF, 0x67D9, 0xE8D4, 0x67DA, 0xE8D6,
+	0x67DB, 0x96B8, 0x67DC, 0xB9F1, 0x67DD, 0xE8D8, 0x67DE, 0xD7F5,
+	0x67DF, 0x96B9, 0x67E0, 0xC4FB, 0x67E1, 0x96BA, 0x67E2, 0xE8DC,
+	0x67E3, 0x96BB, 0x67E4, 0x96BC, 0x67E5, 0xB2E9, 0x67E6, 0x96BD,
+	0x67E7, 0x96BE, 0x67E8, 0x96BF, 0x67E9, 0xE8D1, 0x67EA, 0x96C0,
+	0x67EB, 0x96C1, 0x67EC, 0xBCED, 0x67ED, 0x96C2, 0x67EE, 0x96C3,
+	0x67EF, 0xBFC2, 0x67F0, 0xE8CD, 0x67F1, 0xD6F9, 0x67F2, 0x96C4,
+	0x67F3, 0xC1F8, 0x67F4, 0xB2F1, 0x67F5, 0x96C5, 0x67F6, 0x96C6,
+	0x67F7, 0x96C7, 0x67F8, 0x96C8, 0x67F9, 0x96C9, 0x67FA, 0x96CA,
+	0x67FB, 0x96CB, 0x67FC, 0x96CC, 0x67FD, 0xE8DF, 0x67FE, 0x96CD,
+	0x67FF, 0xCAC1, 0x6800, 0xE8D9, 0x6801, 0x96CE, 0x6802, 0x96CF,
+	0x6803, 0x96D0, 0x6804, 0x96D1, 0x6805, 0xD5A4, 0x6806, 0x96D2,
+	0x6807, 0xB1EA, 0x6808, 0xD5BB, 0x6809, 0xE8CE, 0x680A, 0xE8D0,
+	0x680B, 0xB6B0, 0x680C, 0xE8D3, 0x680D, 0x96D3, 0x680E, 0xE8DD,
+	0x680F, 0xC0B8, 0x6810, 0x96D4, 0x6811, 0xCAF7, 0x6812, 0x96D5,
+	0x6813, 0xCBA8, 0x6814, 0x96D6, 0x6815, 0x96D7, 0x6816, 0xC6DC,
+	0x6817, 0xC0F5, 0x6818, 0x96D8, 0x6819, 0x96D9, 0x681A, 0x96DA,
+	0x681B, 0x96DB, 0x681C, 0x96DC, 0x681D, 0xE8E9, 0x681E, 0x96DD,
+	0x681F, 0x96DE, 0x6820, 0x96DF, 0x6821, 0xD0A3, 0x6822, 0x96E0,
+	0x6823, 0x96E1, 0x6824, 0x96E2, 0x6825, 0x96E3, 0x6826, 0x96E4,
+	0x6827, 0x96E5, 0x6828, 0x96E6, 0x6829, 0xE8F2, 0x682A, 0xD6EA,
+	0x682B, 0x96E7, 0x682C, 0x96E8, 0x682D, 0x96E9, 0x682E, 0x96EA,
+	0x682F, 0x96EB, 0x6830, 0x96EC, 0x6831, 0x96ED, 0x6832, 0xE8E0,
+	0x6833, 0xE8E1, 0x6834, 0x96EE, 0x6835, 0x96EF, 0x6836, 0x96F0,
+	0x6837, 0xD1F9, 0x6838, 0xBACB, 0x6839, 0xB8F9, 0x683A, 0x96F1,
+	0x683B, 0x96F2, 0x683C, 0xB8F1, 0x683D, 0xD4D4, 0x683E, 0xE8EF,
+	0x683F, 0x96F3, 0x6840, 0xE8EE, 0x6841, 0xE8EC, 0x6842, 0xB9F0,
+	0x6843, 0xCCD2, 0x6844, 0xE8E6, 0x6845, 0xCEA6, 0x6846, 0xBFF2,
+	0x6847, 0x96F4, 0x6848, 0xB0B8, 0x6849, 0xE8F1, 0x684A, 0xE8F0,
+	0x684B, 0x96F5, 0x684C, 0xD7C0, 0x684D, 0x96F6, 0x684E, 0xE8E4,
+	0x684F, 0x96F7, 0x6850, 0xCDA9, 0x6851, 0xC9A3, 0x6852, 0x96F8,
+	0x6853, 0xBBB8, 0x6854, 0xBDDB, 0x6855, 0xE8EA, 0x6856, 0x96F9,
+	0x6857, 0x96FA, 0x6858, 0x96FB, 0x6859, 0x96FC, 0x685A, 0x96FD,
+	0x685B, 0x96FE, 0x685C, 0x9740, 0x685D, 0x9741, 0x685E, 0x9742,
+	0x685F, 0x9743, 0x6860, 0xE8E2, 0x6861, 0xE8E3, 0x6862, 0xE8E5,
+	0x6863, 0xB5B5, 0x6864, 0xE8E7, 0x6865, 0xC7C5, 0x6866, 0xE8EB,
+	0x6867, 0xE8ED, 0x6868, 0xBDB0, 0x6869, 0xD7AE, 0x686A, 0x9744,
+	0x686B, 0xE8F8, 0x686C, 0x9745, 0x686D, 0x9746, 0x686E, 0x9747,
+	0x686F, 0x9748, 0x6870, 0x9749, 0x6871, 0x974A, 0x6872, 0x974B,
+	0x6873, 0x974C, 0x6874, 0xE8F5, 0x6875, 0x974D, 0x6876, 0xCDB0,
+	0x6877, 0xE8F6, 0x6878, 0x974E, 0x6879, 0x974F, 0x687A, 0x9750,
+	0x687B, 0x9751, 0x687C, 0x9752, 0x687D, 0x9753, 0x687E, 0x9754,
+	0x687F, 0x9755, 0x6880, 0x9756, 0x6881, 0xC1BA, 0x6882, 0x9757,
+	0x6883, 0xE8E8, 0x6884, 0x9758, 0x6885, 0xC3B7, 0x6886, 0xB0F0,
+	0x6887, 0x9759, 0x6888, 0x975A, 0x6889, 0x975B, 0x688A, 0x975C,
+	0x688B, 0x975D, 0x688C, 0x975E, 0x688D, 0x975F, 0x688E, 0x9760,
+	0x688F, 0xE8F4, 0x6890, 0x9761, 0x6891, 0x9762, 0x6892, 0x9763,
+	0x6893, 0xE8F7, 0x6894, 0x9764, 0x6895, 0x9765, 0x6896, 0x9766,
+	0x6897, 0xB9A3, 0x6898, 0x9767, 0x6899, 0x9768, 0x689A, 0x9769,
+	0x689B, 0x976A, 0x689C, 0x976B, 0x689D, 0x976C, 0x689E, 0x976D,
+	0x689F, 0x976E, 0x68A0, 0x976F, 0x68A1, 0x9770, 0x68A2, 0xC9D2,
+	0x68A3, 0x9771, 0x68A4, 0x9772, 0x68A5, 0x9773, 0x68A6, 0xC3CE,
+	0x68A7, 0xCEE0, 0x68A8, 0xC0E6, 0x68A9, 0x9774, 0x68AA, 0x9775,
+	0x68AB, 0x9776, 0x68AC, 0x9777, 0x68AD, 0xCBF3, 0x68AE, 0x9778,
+	0x68AF, 0xCCDD, 0x68B0, 0xD0B5, 0x68B1, 0x9779, 0x68B2, 0x977A,
+	0x68B3, 0xCAE1, 0x68B4, 0x977B, 0x68B5, 0xE8F3, 0x68B6, 0x977C,
+	0x68B7, 0x977D, 0x68B8, 0x977E, 0x68B9, 0x9780, 0x68BA, 0x9781,
+	0x68BB, 0x9782, 0x68BC, 0x9783, 0x68BD, 0x9784, 0x68BE, 0x9785,
+	0x68BF, 0x9786, 0x68C0, 0xBCEC, 0x68C1, 0x9787, 0x68C2, 0xE8F9,
+	0x68C3, 0x9788, 0x68C4, 0x9789, 0x68C5, 0x978A, 0x68C6, 0x978B,
+	0x68C7, 0x978C, 0x68C8, 0x978D, 0x68C9, 0xC3DE, 0x68CA, 0x978E,
+	0x68CB, 0xC6E5, 0x68CC, 0x978F, 0x68CD, 0xB9F7, 0x68CE, 0x9790,
+	0x68CF, 0x9791, 0x68D0, 0x9792, 0x68D1, 0x9793, 0x68D2, 0xB0F4,
+	0x68D3, 0x9794, 0x68D4, 0x9795, 0x68D5, 0xD7D8, 0x68D6, 0x9796,
+	0x68D7, 0x9797, 0x68D8, 0xBCAC, 0x68D9, 0x9798, 0x68DA, 0xC5EF,
+	0x68DB, 0x9799, 0x68DC, 0x979A, 0x68DD, 0x979B, 0x68DE, 0x979C,
+	0x68DF, 0x979D, 0x68E0, 0xCCC4, 0x68E1, 0x979E, 0x68E2, 0x979F,
+	0x68E3, 0xE9A6, 0x68E4, 0x97A0, 0x68E5, 0x97A1, 0x68E6, 0x97A2,
+	0x68E7, 0x97A3, 0x68E8, 0x97A4, 0x68E9, 0x97A5, 0x68EA, 0x97A6,
+	0x68EB, 0x97A7, 0x68EC, 0x97A8, 0x68ED, 0x97A9, 0x68EE, 0xC9AD,
+	0x68EF, 0x97AA, 0x68F0, 0xE9A2, 0x68F1, 0xC0E2, 0x68F2, 0x97AB,
+	0x68F3, 0x97AC, 0x68F4, 0x97AD, 0x68F5, 0xBFC3, 0x68F6, 0x97AE,
+	0x68F7, 0x97AF, 0x68F8, 0x97B0, 0x68F9, 0xE8FE, 0x68FA, 0xB9D7,
+	0x68FB, 0x97B1, 0x68FC, 0xE8FB, 0x68FD, 0x97B2, 0x68FE, 0x97B3,
+	0x68FF, 0x97B4, 0x6900, 0x97B5, 0x6901, 0xE9A4, 0x6902, 0x97B6,
+	0x6903, 0x97B7, 0x6904, 0x97B8, 0x6905, 0xD2CE, 0x6906, 0x97B9,
+	0x6907, 0x97BA, 0x6908, 0x97BB, 0x6909, 0x97BC, 0x690A, 0x97BD,
+	0x690B, 0xE9A3, 0x690C, 0x97BE, 0x690D, 0xD6B2, 0x690E, 0xD7B5,
+	0x690F, 0x97BF, 0x6910, 0xE9A7, 0x6911, 0x97C0, 0x6912, 0xBDB7,
+	0x6913, 0x97C1, 0x6914, 0x97C2, 0x6915, 0x97C3, 0x6916, 0x97C4,
+	0x6917, 0x97C5, 0x6918, 0x97C6, 0x6919, 0x97C7, 0x691A, 0x97C8,
+	0x691B, 0x97C9, 0x691C, 0x97CA, 0x691D, 0x97CB, 0x691E, 0x97CC,
+	0x691F, 0xE8FC, 0x6920, 0xE8FD, 0x6921, 0x97CD, 0x6922, 0x97CE,
+	0x6923, 0x97CF, 0x6924, 0xE9A1, 0x6925, 0x97D0, 0x6926, 0x97D1,
+	0x6927, 0x97D2, 0x6928, 0x97D3, 0x6929, 0x97D4, 0x692A, 0x97D5,
+	0x692B, 0x97D6, 0x692C, 0x97D7, 0x692D, 0xCDD6, 0x692E, 0x97D8,
+	0x692F, 0x97D9, 0x6930, 0xD2AC, 0x6931, 0x97DA, 0x6932, 0x97DB,
+	0x6933, 0x97DC, 0x6934, 0xE9B2, 0x6935, 0x97DD, 0x6936, 0x97DE,
+	0x6937, 0x97DF, 0x6938, 0x97E0, 0x6939, 0xE9A9, 0x693A, 0x97E1,
+	0x693B, 0x97E2, 0x693C, 0x97E3, 0x693D, 0xB4AA, 0x693E, 0x97E4,
+	0x693F, 0xB4BB, 0x6940, 0x97E5, 0x6941, 0x97E6, 0x6942, 0xE9AB,
+	0x6943, 0x97E7, 0x6944, 0x97E8, 0x6945, 0x97E9, 0x6946, 0x97EA,
+	0x6947, 0x97EB, 0x6948, 0x97EC, 0x6949, 0x97ED, 0x694A, 0x97EE,
+	0x694B, 0x97EF, 0x694C, 0x97F0, 0x694D, 0x97F1, 0x694E, 0x97F2,
+	0x694F, 0x97F3, 0x6950, 0x97F4, 0x6951, 0x97F5, 0x6952, 0x97F6,
+	0x6953, 0x97F7, 0x6954, 0xD0A8, 0x6955, 0x97F8, 0x6956, 0x97F9,
+	0x6957, 0xE9A5, 0x6958, 0x97FA, 0x6959, 0x97FB, 0x695A, 0xB3FE,
+	0x695B, 0x97FC, 0x695C, 0x97FD, 0x695D, 0xE9AC, 0x695E, 0xC0E3,
+	0x695F, 0x97FE, 0x6960, 0xE9AA, 0x6961, 0x9840, 0x6962, 0x9841,
+	0x6963, 0xE9B9, 0x6964, 0x9842, 0x6965, 0x9843, 0x6966, 0xE9B8,
+	0x6967, 0x9844, 0x6968, 0x9845, 0x6969, 0x9846, 0x696A, 0x9847,
+	0x696B, 0xE9AE, 0x696C, 0x9848, 0x696D, 0x9849, 0x696E, 0xE8FA,
+	0x696F, 0x984A, 0x6970, 0x984B, 0x6971, 0xE9A8, 0x6972, 0x984C,
+	0x6973, 0x984D, 0x6974, 0x984E, 0x6975, 0x984F, 0x6976, 0x9850,
+	0x6977, 0xBFAC, 0x6978, 0xE9B1, 0x6979, 0xE9BA, 0x697A, 0x9851,
+	0x697B, 0x9852, 0x697C, 0xC2A5, 0x697D, 0x9853, 0x697E, 0x9854,
+	0x697F, 0x9855, 0x6980, 0xE9AF, 0x6981, 0x9856, 0x6982, 0xB8C5,
+	0x6983, 0x9857, 0x6984, 0xE9AD, 0x6985, 0x9858, 0x6986, 0xD3DC,
+	0x6987, 0xE9B4, 0x6988, 0xE9B5, 0x6989, 0xE9B7, 0x698A, 0x9859,
+	0x698B, 0x985A, 0x698C, 0x985B, 0x698D, 0xE9C7, 0x698E, 0x985C,
+	0x698F, 0x985D, 0x6990, 0x985E, 0x6991, 0x985F, 0x6992, 0x9860,
+	0x6993, 0x9861, 0x6994, 0xC0C6, 0x6995, 0xE9C5, 0x6996, 0x9862,
+	0x6997, 0x9863, 0x6998, 0xE9B0, 0x6999, 0x9864, 0x699A, 0x9865,
+	0x699B, 0xE9BB, 0x699C, 0xB0F1, 0x699D, 0x9866, 0x699E, 0x9867,
+	0x699F, 0x9868, 0x69A0, 0x9869, 0x69A1, 0x986A, 0x69A2, 0x986B,
+	0x69A3, 0x986C, 0x69A4, 0x986D, 0x69A5, 0x986E, 0x69A6, 0x986F,
+	0x69A7, 0xE9BC, 0x69A8, 0xD5A5, 0x69A9, 0x9870, 0x69AA, 0x9871,
+	0x69AB, 0xE9BE, 0x69AC, 0x9872, 0x69AD, 0xE9BF, 0x69AE, 0x9873,
+	0x69AF, 0x9874, 0x69B0, 0x9875, 0x69B1, 0xE9C1, 0x69B2, 0x9876,
+	0x69B3, 0x9877, 0x69B4, 0xC1F1, 0x69B5, 0x9878, 0x69B6, 0x9879,
+	0x69B7, 0xC8B6, 0x69B8, 0x987A, 0x69B9, 0x987B, 0x69BA, 0x987C,
+	0x69BB, 0xE9BD, 0x69BC, 0x987D, 0x69BD, 0x987E, 0x69BE, 0x9880,
+	0x69BF, 0x9881, 0x69C0, 0x9882, 0x69C1, 0xE9C2, 0x69C2, 0x9883,
+	0x69C3, 0x9884, 0x69C4, 0x9885, 0x69C5, 0x9886, 0x69C6, 0x9887,
+	0x69C7, 0x9888, 0x69C8, 0x9889, 0x69C9, 0x988A, 0x69CA, 0xE9C3,
+	0x69CB, 0x988B, 0x69CC, 0xE9B3, 0x69CD, 0x988C, 0x69CE, 0xE9B6,
+	0x69CF, 0x988D, 0x69D0, 0xBBB1, 0x69D1, 0x988E, 0x69D2, 0x988F,
+	0x69D3, 0x9890, 0x69D4, 0xE9C0, 0x69D5, 0x9891, 0x69D6, 0x9892,
+	0x69D7, 0x9893, 0x69D8, 0x9894, 0x69D9, 0x9895, 0x69DA, 0x9896,
+	0x69DB, 0xBCF7, 0x69DC, 0x9897, 0x69DD, 0x9898, 0x69DE, 0x9899,
+	0x69DF, 0xE9C4, 0x69E0, 0xE9C6, 0x69E1, 0x989A, 0x69E2, 0x989B,
+	0x69E3, 0x989C, 0x69E4, 0x989D, 0x69E5, 0x989E, 0x69E6, 0x989F,
+	0x69E7, 0x98A0, 0x69E8, 0x98A1, 0x69E9, 0x98A2, 0x69EA, 0x98A3,
+	0x69EB, 0x98A4, 0x69EC, 0x98A5, 0x69ED, 0xE9CA, 0x69EE, 0x98A6,
+	0x69EF, 0x98A7, 0x69F0, 0x98A8, 0x69F1, 0x98A9, 0x69F2, 0xE9CE,
+	0x69F3, 0x98AA, 0x69F4, 0x98AB, 0x69F5, 0x98AC, 0x69F6, 0x98AD,
+	0x69F7, 0x98AE, 0x69F8, 0x98AF, 0x69F9, 0x98B0, 0x69FA, 0x98B1,
+	0x69FB, 0x98B2, 0x69FC, 0x98B3, 0x69FD, 0xB2DB, 0x69FE, 0x98B4,
+	0x69FF, 0xE9C8, 0x6A00, 0x98B5, 0x6A01, 0x98B6, 0x6A02, 0x98B7,
+	0x6A03, 0x98B8, 0x6A04, 0x98B9, 0x6A05, 0x98BA, 0x6A06, 0x98BB,
+	0x6A07, 0x98BC, 0x6A08, 0x98BD, 0x6A09, 0x98BE, 0x6A0A, 0xB7AE,
+	0x6A0B, 0x98BF, 0x6A0C, 0x98C0, 0x6A0D, 0x98C1, 0x6A0E, 0x98C2,
+	0x6A0F, 0x98C3, 0x6A10, 0x98C4, 0x6A11, 0x98C5, 0x6A12, 0x98C6,
+	0x6A13, 0x98C7, 0x6A14, 0x98C8, 0x6A15, 0x98C9, 0x6A16, 0x98CA,
+	0x6A17, 0xE9CB, 0x6A18, 0xE9CC, 0x6A19, 0x98CB, 0x6A1A, 0x98CC,
+	0x6A1B, 0x98CD, 0x6A1C, 0x98CE, 0x6A1D, 0x98CF, 0x6A1E, 0x98D0,
+	0x6A1F, 0xD5C1, 0x6A20, 0x98D1, 0x6A21, 0xC4A3, 0x6A22, 0x98D2,
+	0x6A23, 0x98D3, 0x6A24, 0x98D4, 0x6A25, 0x98D5, 0x6A26, 0x98D6,
+	0x6A27, 0x98D7, 0x6A28, 0xE9D8, 0x6A29, 0x98D8, 0x6A2A, 0xBAE1,
+	0x6A2B, 0x98D9, 0x6A2C, 0x98DA, 0x6A2D, 0x98DB, 0x6A2E, 0x98DC,
+	0x6A2F, 0xE9C9, 0x6A30, 0x98DD, 0x6A31, 0xD3A3, 0x6A32, 0x98DE,
+	0x6A33, 0x98DF, 0x6A34, 0x98E0, 0x6A35, 0xE9D4, 0x6A36, 0x98E1,
+	0x6A37, 0x98E2, 0x6A38, 0x98E3, 0x6A39, 0x98E4, 0x6A3A, 0x98E5,
+	0x6A3B, 0x98E6, 0x6A3C, 0x98E7, 0x6A3D, 0xE9D7, 0x6A3E, 0xE9D0,
+	0x6A3F, 0x98E8, 0x6A40, 0x98E9, 0x6A41, 0x98EA, 0x6A42, 0x98EB,
+	0x6A43, 0x98EC, 0x6A44, 0xE9CF, 0x6A45, 0x98ED, 0x6A46, 0x98EE,
+	0x6A47, 0xC7C1, 0x6A48, 0x98EF, 0x6A49, 0x98F0, 0x6A4A, 0x98F1,
+	0x6A4B, 0x98F2, 0x6A4C, 0x98F3, 0x6A4D, 0x98F4, 0x6A4E, 0x98F5,
+	0x6A4F, 0x98F6, 0x6A50, 0xE9D2, 0x6A51, 0x98F7, 0x6A52, 0x98F8,
+	0x6A53, 0x98F9, 0x6A54, 0x98FA, 0x6A55, 0x98FB, 0x6A56, 0x98FC,
+	0x6A57, 0x98FD, 0x6A58, 0xE9D9, 0x6A59, 0xB3C8, 0x6A5A, 0x98FE,
+	0x6A5B, 0xE9D3, 0x6A5C, 0x9940, 0x6A5D, 0x9941, 0x6A5E, 0x9942,
+	0x6A5F, 0x9943, 0x6A60, 0x9944, 0x6A61, 0xCFF0, 0x6A62, 0x9945,
+	0x6A63, 0x9946, 0x6A64, 0x9947, 0x6A65, 0xE9CD, 0x6A66, 0x9948,
+	0x6A67, 0x9949, 0x6A68, 0x994A, 0x6A69, 0x994B, 0x6A6A, 0x994C,
+	0x6A6B, 0x994D, 0x6A6C, 0x994E, 0x6A6D, 0x994F, 0x6A6E, 0x9950,
+	0x6A6F, 0x9951, 0x6A70, 0x9952, 0x6A71, 0xB3F7, 0x6A72, 0x9953,
+	0x6A73, 0x9954, 0x6A74, 0x9955, 0x6A75, 0x9956, 0x6A76, 0x9957,
+	0x6A77, 0x9958, 0x6A78, 0x9959, 0x6A79, 0xE9D6, 0x6A7A, 0x995A,
+	0x6A7B, 0x995B, 0x6A7C, 0xE9DA, 0x6A7D, 0x995C, 0x6A7E, 0x995D,
+	0x6A7F, 0x995E, 0x6A80, 0xCCB4, 0x6A81, 0x995F, 0x6A82, 0x9960,
+	0x6A83, 0x9961, 0x6A84, 0xCFAD, 0x6A85, 0x9962, 0x6A86, 0x9963,
+	0x6A87, 0x9964, 0x6A88, 0x9965, 0x6A89, 0x9966, 0x6A8A, 0x9967,
+	0x6A8B, 0x9968, 0x6A8C, 0x9969, 0x6A8D, 0x996A, 0x6A8E, 0xE9D5,
+	0x6A8F, 0x996B, 0x6A90, 0xE9DC, 0x6A91, 0xE9DB, 0x6A92, 0x996C,
+	0x6A93, 0x996D, 0x6A94, 0x996E, 0x6A95, 0x996F, 0x6A96, 0x9970,
+	0x6A97, 0xE9DE, 0x6A98, 0x9971, 0x6A99, 0x9972, 0x6A9A, 0x9973,
+	0x6A9B, 0x9974, 0x6A9C, 0x9975, 0x6A9D, 0x9976, 0x6A9E, 0x9977,
+	0x6A9F, 0x9978, 0x6AA0, 0xE9D1, 0x6AA1, 0x9979, 0x6AA2, 0x997A,
+	0x6AA3, 0x997B, 0x6AA4, 0x997C, 0x6AA5, 0x997D, 0x6AA6, 0x997E,
+	0x6AA7, 0x9980, 0x6AA8, 0x9981, 0x6AA9, 0xE9DD, 0x6AAA, 0x9982,
+	0x6AAB, 0xE9DF, 0x6AAC, 0xC3CA, 0x6AAD, 0x9983, 0x6AAE, 0x9984,
+	0x6AAF, 0x9985, 0x6AB0, 0x9986, 0x6AB1, 0x9987, 0x6AB2, 0x9988,
+	0x6AB3, 0x9989, 0x6AB4, 0x998A, 0x6AB5, 0x998B, 0x6AB6, 0x998C,
+	0x6AB7, 0x998D, 0x6AB8, 0x998E, 0x6AB9, 0x998F, 0x6ABA, 0x9990,
+	0x6ABB, 0x9991, 0x6ABC, 0x9992, 0x6ABD, 0x9993, 0x6ABE, 0x9994,
+	0x6ABF, 0x9995, 0x6AC0, 0x9996, 0x6AC1, 0x9997, 0x6AC2, 0x9998,
+	0x6AC3, 0x9999, 0x6AC4, 0x999A, 0x6AC5, 0x999B, 0x6AC6, 0x999C,
+	0x6AC7, 0x999D, 0x6AC8, 0x999E, 0x6AC9, 0x999F, 0x6ACA, 0x99A0,
+	0x6ACB, 0x99A1, 0x6ACC, 0x99A2, 0x6ACD, 0x99A3, 0x6ACE, 0x99A4,
+	0x6ACF, 0x99A5, 0x6AD0, 0x99A6, 0x6AD1, 0x99A7, 0x6AD2, 0x99A8,
+	0x6AD3, 0x99A9, 0x6AD4, 0x99AA, 0x6AD5, 0x99AB, 0x6AD6, 0x99AC,
+	0x6AD7, 0x99AD, 0x6AD8, 0x99AE, 0x6AD9, 0x99AF, 0x6ADA, 0x99B0,
+	0x6ADB, 0x99B1, 0x6ADC, 0x99B2, 0x6ADD, 0x99B3, 0x6ADE, 0x99B4,
+	0x6ADF, 0x99B5, 0x6AE0, 0x99B6, 0x6AE1, 0x99B7, 0x6AE2, 0x99B8,
+	0x6AE3, 0x99B9, 0x6AE4, 0x99BA, 0x6AE5, 0x99BB, 0x6AE6, 0x99BC,
+	0x6AE7, 0x99BD, 0x6AE8, 0x99BE, 0x6AE9, 0x99BF, 0x6AEA, 0x99C0,
+	0x6AEB, 0x99C1, 0x6AEC, 0x99C2, 0x6AED, 0x99C3, 0x6AEE, 0x99C4,
+	0x6AEF, 0x99C5, 0x6AF0, 0x99C6, 0x6AF1, 0x99C7, 0x6AF2, 0x99C8,
+	0x6AF3, 0x99C9, 0x6AF4, 0x99CA, 0x6AF5, 0x99CB, 0x6AF6, 0x99CC,
+	0x6AF7, 0x99CD, 0x6AF8, 0x99CE, 0x6AF9, 0x99CF, 0x6AFA, 0x99D0,
+	0x6AFB, 0x99D1, 0x6AFC, 0x99D2, 0x6AFD, 0x99D3, 0x6AFE, 0x99D4,
+	0x6AFF, 0x99D5, 0x6B00, 0x99D6, 0x6B01, 0x99D7, 0x6B02, 0x99D8,
+	0x6B03, 0x99D9, 0x6B04, 0x99DA, 0x6B05, 0x99DB, 0x6B06, 0x99DC,
+	0x6B07, 0x99DD, 0x6B08, 0x99DE, 0x6B09, 0x99DF, 0x6B0A, 0x99E0,
+	0x6B0B, 0x99E1, 0x6B0C, 0x99E2, 0x6B0D, 0x99E3, 0x6B0E, 0x99E4,
+	0x6B0F, 0x99E5, 0x6B10, 0x99E6, 0x6B11, 0x99E7, 0x6B12, 0x99E8,
+	0x6B13, 0x99E9, 0x6B14, 0x99EA, 0x6B15, 0x99EB, 0x6B16, 0x99EC,
+	0x6B17, 0x99ED, 0x6B18, 0x99EE, 0x6B19, 0x99EF, 0x6B1A, 0x99F0,
+	0x6B1B, 0x99F1, 0x6B1C, 0x99F2, 0x6B1D, 0x99F3, 0x6B1E, 0x99F4,
+	0x6B1F, 0x99F5, 0x6B20, 0xC7B7, 0x6B21, 0xB4CE, 0x6B22, 0xBBB6,
+	0x6B23, 0xD0C0, 0x6B24, 0xECA3, 0x6B25, 0x99F6, 0x6B26, 0x99F7,
+	0x6B27, 0xC5B7, 0x6B28, 0x99F8, 0x6B29, 0x99F9, 0x6B2A, 0x99FA,
+	0x6B2B, 0x99FB, 0x6B2C, 0x99FC, 0x6B2D, 0x99FD, 0x6B2E, 0x99FE,
+	0x6B2F, 0x9A40, 0x6B30, 0x9A41, 0x6B31, 0x9A42, 0x6B32, 0xD3FB,
+	0x6B33, 0x9A43, 0x6B34, 0x9A44, 0x6B35, 0x9A45, 0x6B36, 0x9A46,
+	0x6B37, 0xECA4, 0x6B38, 0x9A47, 0x6B39, 0xECA5, 0x6B3A, 0xC6DB,
+	0x6B3B, 0x9A48, 0x6B3C, 0x9A49, 0x6B3D, 0x9A4A, 0x6B3E, 0xBFEE,
+	0x6B3F, 0x9A4B, 0x6B40, 0x9A4C, 0x6B41, 0x9A4D, 0x6B42, 0x9A4E,
+	0x6B43, 0xECA6, 0x6B44, 0x9A4F, 0x6B45, 0x9A50, 0x6B46, 0xECA7,
+	0x6B47, 0xD0AA, 0x6B48, 0x9A51, 0x6B49, 0xC7B8, 0x6B4A, 0x9A52,
+	0x6B4B, 0x9A53, 0x6B4C, 0xB8E8, 0x6B4D, 0x9A54, 0x6B4E, 0x9A55,
+	0x6B4F, 0x9A56, 0x6B50, 0x9A57, 0x6B51, 0x9A58, 0x6B52, 0x9A59,
+	0x6B53, 0x9A5A, 0x6B54, 0x9A5B, 0x6B55, 0x9A5C, 0x6B56, 0x9A5D,
+	0x6B57, 0x9A5E, 0x6B58, 0x9A5F, 0x6B59, 0xECA8, 0x6B5A, 0x9A60,
+	0x6B5B, 0x9A61, 0x6B5C, 0x9A62, 0x6B5D, 0x9A63, 0x6B5E, 0x9A64,
+	0x6B5F, 0x9A65, 0x6B60, 0x9A66, 0x6B61, 0x9A67, 0x6B62, 0xD6B9,
+	0x6B63, 0xD5FD, 0x6B64, 0xB4CB, 0x6B65, 0xB2BD, 0x6B66, 0xCEE4,
+	0x6B67, 0xC6E7, 0x6B68, 0x9A68, 0x6B69, 0x9A69, 0x6B6A, 0xCDE1,
+	0x6B6B, 0x9A6A, 0x6B6C, 0x9A6B, 0x6B6D, 0x9A6C, 0x6B6E, 0x9A6D,
+	0x6B6F, 0x9A6E, 0x6B70, 0x9A6F, 0x6B71, 0x9A70, 0x6B72, 0x9A71,
+	0x6B73, 0x9A72, 0x6B74, 0x9A73, 0x6B75, 0x9A74, 0x6B76, 0x9A75,
+	0x6B77, 0x9A76, 0x6B78, 0x9A77, 0x6B79, 0xB4F5, 0x6B7A, 0x9A78,
+	0x6B7B, 0xCBC0, 0x6B7C, 0xBCDF, 0x6B7D, 0x9A79, 0x6B7E, 0x9A7A,
+	0x6B7F, 0x9A7B, 0x6B80, 0x9A7C, 0x6B81, 0xE9E2, 0x6B82, 0xE9E3,
+	0x6B83, 0xD1EA, 0x6B84, 0xE9E5, 0x6B85, 0x9A7D, 0x6B86, 0xB4F9,
+	0x6B87, 0xE9E4, 0x6B88, 0x9A7E, 0x6B89, 0xD1B3, 0x6B8A, 0xCAE2,
+	0x6B8B, 0xB2D0, 0x6B8C, 0x9A80, 0x6B8D, 0xE9E8, 0x6B8E, 0x9A81,
+	0x6B8F, 0x9A82, 0x6B90, 0x9A83, 0x6B91, 0x9A84, 0x6B92, 0xE9E6,
+	0x6B93, 0xE9E7, 0x6B94, 0x9A85, 0x6B95, 0x9A86, 0x6B96, 0xD6B3,
+	0x6B97, 0x9A87, 0x6B98, 0x9A88, 0x6B99, 0x9A89, 0x6B9A, 0xE9E9,
+	0x6B9B, 0xE9EA, 0x6B9C, 0x9A8A, 0x6B9D, 0x9A8B, 0x6B9E, 0x9A8C,
+	0x6B9F, 0x9A8D, 0x6BA0, 0x9A8E, 0x6BA1, 0xE9EB, 0x6BA2, 0x9A8F,
+	0x6BA3, 0x9A90, 0x6BA4, 0x9A91, 0x6BA5, 0x9A92, 0x6BA6, 0x9A93,
+	0x6BA7, 0x9A94, 0x6BA8, 0x9A95, 0x6BA9, 0x9A96, 0x6BAA, 0xE9EC,
+	0x6BAB, 0x9A97, 0x6BAC, 0x9A98, 0x6BAD, 0x9A99, 0x6BAE, 0x9A9A,
+	0x6BAF, 0x9A9B, 0x6BB0, 0x9A9C, 0x6BB1, 0x9A9D, 0x6BB2, 0x9A9E,
+	0x6BB3, 0xECAF, 0x6BB4, 0xC5B9, 0x6BB5, 0xB6CE, 0x6BB6, 0x9A9F,
+	0x6BB7, 0xD2F3, 0x6BB8, 0x9AA0, 0x6BB9, 0x9AA1, 0x6BBA, 0x9AA2,
+	0x6BBB, 0x9AA3, 0x6BBC, 0x9AA4, 0x6BBD, 0x9AA5, 0x6BBE, 0x9AA6,
+	0x6BBF, 0xB5EE, 0x6BC0, 0x9AA7, 0x6BC1, 0xBBD9, 0x6BC2, 0xECB1,
+	0x6BC3, 0x9AA8, 0x6BC4, 0x9AA9, 0x6BC5, 0xD2E3, 0x6BC6, 0x9AAA,
+	0x6BC7, 0x9AAB, 0x6BC8, 0x9AAC, 0x6BC9, 0x9AAD, 0x6BCA, 0x9AAE,
+	0x6BCB, 0xCEE3, 0x6BCC, 0x9AAF, 0x6BCD, 0xC4B8, 0x6BCE, 0x9AB0,
+	0x6BCF, 0xC3BF, 0x6BD0, 0x9AB1, 0x6BD1, 0x9AB2, 0x6BD2, 0xB6BE,
+	0x6BD3, 0xD8B9, 0x6BD4, 0xB1C8, 0x6BD5, 0xB1CF, 0x6BD6, 0xB1D1,
+	0x6BD7, 0xC5FE, 0x6BD8, 0x9AB3, 0x6BD9, 0xB1D0, 0x6BDA, 0x9AB4,
+	0x6BDB, 0xC3AB, 0x6BDC, 0x9AB5, 0x6BDD, 0x9AB6, 0x6BDE, 0x9AB7,
+	0x6BDF, 0x9AB8, 0x6BE0, 0x9AB9, 0x6BE1, 0xD5B1, 0x6BE2, 0x9ABA,
+	0x6BE3, 0x9ABB, 0x6BE4, 0x9ABC, 0x6BE5, 0x9ABD, 0x6BE6, 0x9ABE,
+	0x6BE7, 0x9ABF, 0x6BE8, 0x9AC0, 0x6BE9, 0x9AC1, 0x6BEA, 0xEBA4,
+	0x6BEB, 0xBAC1, 0x6BEC, 0x9AC2, 0x6BED, 0x9AC3, 0x6BEE, 0x9AC4,
+	0x6BEF, 0xCCBA, 0x6BF0, 0x9AC5, 0x6BF1, 0x9AC6, 0x6BF2, 0x9AC7,
+	0x6BF3, 0xEBA5, 0x6BF4, 0x9AC8, 0x6BF5, 0xEBA7, 0x6BF6, 0x9AC9,
+	0x6BF7, 0x9ACA, 0x6BF8, 0x9ACB, 0x6BF9, 0xEBA8, 0x6BFA, 0x9ACC,
+	0x6BFB, 0x9ACD, 0x6BFC, 0x9ACE, 0x6BFD, 0xEBA6, 0x6BFE, 0x9ACF,
+	0x6BFF, 0x9AD0, 0x6C00, 0x9AD1, 0x6C01, 0x9AD2, 0x6C02, 0x9AD3,
+	0x6C03, 0x9AD4, 0x6C04, 0x9AD5, 0x6C05, 0xEBA9, 0x6C06, 0xEBAB,
+	0x6C07, 0xEBAA, 0x6C08, 0x9AD6, 0x6C09, 0x9AD7, 0x6C0A, 0x9AD8,
+	0x6C0B, 0x9AD9, 0x6C0C, 0x9ADA, 0x6C0D, 0xEBAC, 0x6C0E, 0x9ADB,
+	0x6C0F, 0xCACF, 0x6C10, 0xD8B5, 0x6C11, 0xC3F1, 0x6C12, 0x9ADC,
+	0x6C13, 0xC3A5, 0x6C14, 0xC6F8, 0x6C15, 0xEBAD, 0x6C16, 0xC4CA,
+	0x6C17, 0x9ADD, 0x6C18, 0xEBAE, 0x6C19, 0xEBAF, 0x6C1A, 0xEBB0,
+	0x6C1B, 0xB7D5, 0x6C1C, 0x9ADE, 0x6C1D, 0x9ADF, 0x6C1E, 0x9AE0,
+	0x6C1F, 0xB7FA, 0x6C20, 0x9AE1, 0x6C21, 0xEBB1, 0x6C22, 0xC7E2,
+	0x6C23, 0x9AE2, 0x6C24, 0xEBB3, 0x6C25, 0x9AE3, 0x6C26, 0xBAA4,
+	0x6C27, 0xD1F5, 0x6C28, 0xB0B1, 0x6C29, 0xEBB2, 0x6C2A, 0xEBB4,
+	0x6C2B, 0x9AE4, 0x6C2C, 0x9AE5, 0x6C2D, 0x9AE6, 0x6C2E, 0xB5AA,
+	0x6C2F, 0xC2C8, 0x6C30, 0xC7E8, 0x6C31, 0x9AE7, 0x6C32, 0xEBB5,
+	0x6C33, 0x9AE8, 0x6C34, 0xCBAE, 0x6C35, 0xE3DF, 0x6C36, 0x9AE9,
+	0x6C37, 0x9AEA, 0x6C38, 0xD3C0, 0x6C39, 0x9AEB, 0x6C3A, 0x9AEC,
+	0x6C3B, 0x9AED, 0x6C3C, 0x9AEE, 0x6C3D, 0xD9DB, 0x6C3E, 0x9AEF,
+	0x6C3F, 0x9AF0, 0x6C40, 0xCDA1, 0x6C41, 0xD6AD, 0x6C42, 0xC7F3,
+	0x6C43, 0x9AF1, 0x6C44, 0x9AF2, 0x6C45, 0x9AF3, 0x6C46, 0xD9E0,
+	0x6C47, 0xBBE3, 0x6C48, 0x9AF4, 0x6C49, 0xBABA, 0x6C4A, 0xE3E2,
+	0x6C4B, 0x9AF5, 0x6C4C, 0x9AF6, 0x6C4D, 0x9AF7, 0x6C4E, 0x9AF8,
+	0x6C4F, 0x9AF9, 0x6C50, 0xCFAB, 0x6C51, 0x9AFA, 0x6C52, 0x9AFB,
+	0x6C53, 0x9AFC, 0x6C54, 0xE3E0, 0x6C55, 0xC9C7, 0x6C56, 0x9AFD,
+	0x6C57, 0xBAB9, 0x6C58, 0x9AFE, 0x6C59, 0x9B40, 0x6C5A, 0x9B41,
+	0x6C5B, 0xD1B4, 0x6C5C, 0xE3E1, 0x6C5D, 0xC8EA, 0x6C5E, 0xB9AF,
+	0x6C5F, 0xBDAD, 0x6C60, 0xB3D8, 0x6C61, 0xCEDB, 0x6C62, 0x9B42,
+	0x6C63, 0x9B43, 0x6C64, 0xCCC0, 0x6C65, 0x9B44, 0x6C66, 0x9B45,
+	0x6C67, 0x9B46, 0x6C68, 0xE3E8, 0x6C69, 0xE3E9, 0x6C6A, 0xCDF4,
+	0x6C6B, 0x9B47, 0x6C6C, 0x9B48, 0x6C6D, 0x9B49, 0x6C6E, 0x9B4A,
+	0x6C6F, 0x9B4B, 0x6C70, 0xCCAD, 0x6C71, 0x9B4C, 0x6C72, 0xBCB3,
+	0x6C73, 0x9B4D, 0x6C74, 0xE3EA, 0x6C75, 0x9B4E, 0x6C76, 0xE3EB,
+	0x6C77, 0x9B4F, 0x6C78, 0x9B50, 0x6C79, 0xD0DA, 0x6C7A, 0x9B51,
+	0x6C7B, 0x9B52, 0x6C7C, 0x9B53, 0x6C7D, 0xC6FB, 0x6C7E, 0xB7DA,
+	0x6C7F, 0x9B54, 0x6C80, 0x9B55, 0x6C81, 0xC7DF, 0x6C82, 0xD2CA,
+	0x6C83, 0xCED6, 0x6C84, 0x9B56, 0x6C85, 0xE3E4, 0x6C86, 0xE3EC,
+	0x6C87, 0x9B57, 0x6C88, 0xC9F2, 0x6C89, 0xB3C1, 0x6C8A, 0x9B58,
+	0x6C8B, 0x9B59, 0x6C8C, 0xE3E7, 0x6C8D, 0x9B5A, 0x6C8E, 0x9B5B,
+	0x6C8F, 0xC6E3, 0x6C90, 0xE3E5, 0x6C91, 0x9B5C, 0x6C92, 0x9B5D,
+	0x6C93, 0xEDB3, 0x6C94, 0xE3E6, 0x6C95, 0x9B5E, 0x6C96, 0x9B5F,
+	0x6C97, 0x9B60, 0x6C98, 0x9B61, 0x6C99, 0xC9B3, 0x6C9A, 0x9B62,
+	0x6C9B, 0xC5E6, 0x6C9C, 0x9B63, 0x6C9D, 0x9B64, 0x6C9E, 0x9B65,
+	0x6C9F, 0xB9B5, 0x6CA0, 0x9B66, 0x6CA1, 0xC3BB, 0x6CA2, 0x9B67,
+	0x6CA3, 0xE3E3, 0x6CA4, 0xC5BD, 0x6CA5, 0xC1A4, 0x6CA6, 0xC2D9,
+	0x6CA7, 0xB2D7, 0x6CA8, 0x9B68, 0x6CA9, 0xE3ED, 0x6CAA, 0xBBA6,
+	0x6CAB, 0xC4AD, 0x6CAC, 0x9B69, 0x6CAD, 0xE3F0, 0x6CAE, 0xBEDA,
+	0x6CAF, 0x9B6A, 0x6CB0, 0x9B6B, 0x6CB1, 0xE3FB, 0x6CB2, 0xE3F5,
+	0x6CB3, 0xBAD3, 0x6CB4, 0x9B6C, 0x6CB5, 0x9B6D, 0x6CB6, 0x9B6E,
+	0x6CB7, 0x9B6F, 0x6CB8, 0xB7D0, 0x6CB9, 0xD3CD, 0x6CBA, 0x9B70,
+	0x6CBB, 0xD6CE, 0x6CBC, 0xD5D3, 0x6CBD, 0xB9C1, 0x6CBE, 0xD5B4,
+	0x6CBF, 0xD1D8, 0x6CC0, 0x9B71, 0x6CC1, 0x9B72, 0x6CC2, 0x9B73,
+	0x6CC3, 0x9B74, 0x6CC4, 0xD0B9, 0x6CC5, 0xC7F6, 0x6CC6, 0x9B75,
+	0x6CC7, 0x9B76, 0x6CC8, 0x9B77, 0x6CC9, 0xC8AA, 0x6CCA, 0xB2B4,
+	0x6CCB, 0x9B78, 0x6CCC, 0xC3DA, 0x6CCD, 0x9B79, 0x6CCE, 0x9B7A,
+	0x6CCF, 0x9B7B, 0x6CD0, 0xE3EE, 0x6CD1, 0x9B7C, 0x6CD2, 0x9B7D,
+	0x6CD3, 0xE3FC, 0x6CD4, 0xE3EF, 0x6CD5, 0xB7A8, 0x6CD6, 0xE3F7,
+	0x6CD7, 0xE3F4, 0x6CD8, 0x9B7E, 0x6CD9, 0x9B80, 0x6CDA, 0x9B81,
+	0x6CDB, 0xB7BA, 0x6CDC, 0x9B82, 0x6CDD, 0x9B83, 0x6CDE, 0xC5A2,
+	0x6CDF, 0x9B84, 0x6CE0, 0xE3F6, 0x6CE1, 0xC5DD, 0x6CE2, 0xB2A8,
+	0x6CE3, 0xC6FC, 0x6CE4, 0x9B85, 0x6CE5, 0xC4E0, 0x6CE6, 0x9B86,
+	0x6CE7, 0x9B87, 0x6CE8, 0xD7A2, 0x6CE9, 0x9B88, 0x6CEA, 0xC0E1,
+	0x6CEB, 0xE3F9, 0x6CEC, 0x9B89, 0x6CED, 0x9B8A, 0x6CEE, 0xE3FA,
+	0x6CEF, 0xE3FD, 0x6CF0, 0xCCA9, 0x6CF1, 0xE3F3, 0x6CF2, 0x9B8B,
+	0x6CF3, 0xD3BE, 0x6CF4, 0x9B8C, 0x6CF5, 0xB1C3, 0x6CF6, 0xEDB4,
+	0x6CF7, 0xE3F1, 0x6CF8, 0xE3F2, 0x6CF9, 0x9B8D, 0x6CFA, 0xE3F8,
+	0x6CFB, 0xD0BA, 0x6CFC, 0xC6C3, 0x6CFD, 0xD4F3, 0x6CFE, 0xE3FE,
+	0x6CFF, 0x9B8E, 0x6D00, 0x9B8F, 0x6D01, 0xBDE0, 0x6D02, 0x9B90,
+	0x6D03, 0x9B91, 0x6D04, 0xE4A7, 0x6D05, 0x9B92, 0x6D06, 0x9B93,
+	0x6D07, 0xE4A6, 0x6D08, 0x9B94, 0x6D09, 0x9B95, 0x6D0A, 0x9B96,
+	0x6D0B, 0xD1F3, 0x6D0C, 0xE4A3, 0x6D0D, 0x9B97, 0x6D0E, 0xE4A9,
+	0x6D0F, 0x9B98, 0x6D10, 0x9B99, 0x6D11, 0x9B9A, 0x6D12, 0xC8F7,
+	0x6D13, 0x9B9B, 0x6D14, 0x9B9C, 0x6D15, 0x9B9D, 0x6D16, 0x9B9E,
+	0x6D17, 0xCFB4, 0x6D18, 0x9B9F, 0x6D19, 0xE4A8, 0x6D1A, 0xE4AE,
+	0x6D1B, 0xC2E5, 0x6D1C, 0x9BA0, 0x6D1D, 0x9BA1, 0x6D1E, 0xB6B4,
+	0x6D1F, 0x9BA2, 0x6D20, 0x9BA3, 0x6D21, 0x9BA4, 0x6D22, 0x9BA5,
+	0x6D23, 0x9BA6, 0x6D24, 0x9BA7, 0x6D25, 0xBDF2, 0x6D26, 0x9BA8,
+	0x6D27, 0xE4A2, 0x6D28, 0x9BA9, 0x6D29, 0x9BAA, 0x6D2A, 0xBAE9,
+	0x6D2B, 0xE4AA, 0x6D2C, 0x9BAB, 0x6D2D, 0x9BAC, 0x6D2E, 0xE4AC,
+	0x6D2F, 0x9BAD, 0x6D30, 0x9BAE, 0x6D31, 0xB6FD, 0x6D32, 0xD6DE,
+	0x6D33, 0xE4B2, 0x6D34, 0x9BAF, 0x6D35, 0xE4AD, 0x6D36, 0x9BB0,
+	0x6D37, 0x9BB1, 0x6D38, 0x9BB2, 0x6D39, 0xE4A1, 0x6D3A, 0x9BB3,
+	0x6D3B, 0xBBEE, 0x6D3C, 0xCDDD, 0x6D3D, 0xC7A2, 0x6D3E, 0xC5C9,
+	0x6D3F, 0x9BB4, 0x6D40, 0x9BB5, 0x6D41, 0xC1F7, 0x6D42, 0x9BB6,
+	0x6D43, 0xE4A4, 0x6D44, 0x9BB7, 0x6D45, 0xC7B3, 0x6D46, 0xBDAC,
+	0x6D47, 0xBDBD, 0x6D48, 0xE4A5, 0x6D49, 0x9BB8, 0x6D4A, 0xD7C7,
+	0x6D4B, 0xB2E2, 0x6D4C, 0x9BB9, 0x6D4D, 0xE4AB, 0x6D4E, 0xBCC3,
+	0x6D4F, 0xE4AF, 0x6D50, 0x9BBA, 0x6D51, 0xBBEB, 0x6D52, 0xE4B0,
+	0x6D53, 0xC5A8, 0x6D54, 0xE4B1, 0x6D55, 0x9BBB, 0x6D56, 0x9BBC,
+	0x6D57, 0x9BBD, 0x6D58, 0x9BBE, 0x6D59, 0xD5E3, 0x6D5A, 0xBFA3,
+	0x6D5B, 0x9BBF, 0x6D5C, 0xE4BA, 0x6D5D, 0x9BC0, 0x6D5E, 0xE4B7,
+	0x6D5F, 0x9BC1, 0x6D60, 0xE4BB, 0x6D61, 0x9BC2, 0x6D62, 0x9BC3,
+	0x6D63, 0xE4BD, 0x6D64, 0x9BC4, 0x6D65, 0x9BC5, 0x6D66, 0xC6D6,
+	0x6D67, 0x9BC6, 0x6D68, 0x9BC7, 0x6D69, 0xBAC6, 0x6D6A, 0xC0CB,
+	0x6D6B, 0x9BC8, 0x6D6C, 0x9BC9, 0x6D6D, 0x9BCA, 0x6D6E, 0xB8A1,
+	0x6D6F, 0xE4B4, 0x6D70, 0x9BCB, 0x6D71, 0x9BCC, 0x6D72, 0x9BCD,
+	0x6D73, 0x9BCE, 0x6D74, 0xD4A1, 0x6D75, 0x9BCF, 0x6D76, 0x9BD0,
+	0x6D77, 0xBAA3, 0x6D78, 0xBDFE, 0x6D79, 0x9BD1, 0x6D7A, 0x9BD2,
+	0x6D7B, 0x9BD3, 0x6D7C, 0xE4BC, 0x6D7D, 0x9BD4, 0x6D7E, 0x9BD5,
+	0x6D7F, 0x9BD6, 0x6D80, 0x9BD7, 0x6D81, 0x9BD8, 0x6D82, 0xCDBF,
+	0x6D83, 0x9BD9, 0x6D84, 0x9BDA, 0x6D85, 0xC4F9, 0x6D86, 0x9BDB,
+	0x6D87, 0x9BDC, 0x6D88, 0xCFFB, 0x6D89, 0xC9E6, 0x6D8A, 0x9BDD,
+	0x6D8B, 0x9BDE, 0x6D8C, 0xD3BF, 0x6D8D, 0x9BDF, 0x6D8E, 0xCFD1,
+	0x6D8F, 0x9BE0, 0x6D90, 0x9BE1, 0x6D91, 0xE4B3, 0x6D92, 0x9BE2,
+	0x6D93, 0xE4B8, 0x6D94, 0xE4B9, 0x6D95, 0xCCE9, 0x6D96, 0x9BE3,
+	0x6D97, 0x9BE4, 0x6D98, 0x9BE5, 0x6D99, 0x9BE6, 0x6D9A, 0x9BE7,
+	0x6D9B, 0xCCCE, 0x6D9C, 0x9BE8, 0x6D9D, 0xC0D4, 0x6D9E, 0xE4B5,
+	0x6D9F, 0xC1B0, 0x6DA0, 0xE4B6, 0x6DA1, 0xCED0, 0x6DA2, 0x9BE9,
+	0x6DA3, 0xBBC1, 0x6DA4, 0xB5D3, 0x6DA5, 0x9BEA, 0x6DA6, 0xC8F3,
+	0x6DA7, 0xBDA7, 0x6DA8, 0xD5C7, 0x6DA9, 0xC9AC, 0x6DAA, 0xB8A2,
+	0x6DAB, 0xE4CA, 0x6DAC, 0x9BEB, 0x6DAD, 0x9BEC, 0x6DAE, 0xE4CC,
+	0x6DAF, 0xD1C4, 0x6DB0, 0x9BED, 0x6DB1, 0x9BEE, 0x6DB2, 0xD2BA,
+	0x6DB3, 0x9BEF, 0x6DB4, 0x9BF0, 0x6DB5, 0xBAAD, 0x6DB6, 0x9BF1,
+	0x6DB7, 0x9BF2, 0x6DB8, 0xBAD4, 0x6DB9, 0x9BF3, 0x6DBA, 0x9BF4,
+	0x6DBB, 0x9BF5, 0x6DBC, 0x9BF6, 0x6DBD, 0x9BF7, 0x6DBE, 0x9BF8,
+	0x6DBF, 0xE4C3, 0x6DC0, 0xB5ED, 0x6DC1, 0x9BF9, 0x6DC2, 0x9BFA,
+	0x6DC3, 0x9BFB, 0x6DC4, 0xD7CD, 0x6DC5, 0xE4C0, 0x6DC6, 0xCFFD,
+	0x6DC7, 0xE4BF, 0x6DC8, 0x9BFC, 0x6DC9, 0x9BFD, 0x6DCA, 0x9BFE,
+	0x6DCB, 0xC1DC, 0x6DCC, 0xCCCA, 0x6DCD, 0x9C40, 0x6DCE, 0x9C41,
+	0x6DCF, 0x9C42, 0x6DD0, 0x9C43, 0x6DD1, 0xCAE7, 0x6DD2, 0x9C44,
+	0x6DD3, 0x9C45, 0x6DD4, 0x9C46, 0x6DD5, 0x9C47, 0x6DD6, 0xC4D7,
+	0x6DD7, 0x9C48, 0x6DD8, 0xCCD4, 0x6DD9, 0xE4C8, 0x6DDA, 0x9C49,
+	0x6DDB, 0x9C4A, 0x6DDC, 0x9C4B, 0x6DDD, 0xE4C7, 0x6DDE, 0xE4C1,
+	0x6DDF, 0x9C4C, 0x6DE0, 0xE4C4, 0x6DE1, 0xB5AD, 0x6DE2, 0x9C4D,
+	0x6DE3, 0x9C4E, 0x6DE4, 0xD3D9, 0x6DE5, 0x9C4F, 0x6DE6, 0xE4C6,
+	0x6DE7, 0x9C50, 0x6DE8, 0x9C51, 0x6DE9, 0x9C52, 0x6DEA, 0x9C53,
+	0x6DEB, 0xD2F9, 0x6DEC, 0xB4E3, 0x6DED, 0x9C54, 0x6DEE, 0xBBB4,
+	0x6DEF, 0x9C55, 0x6DF0, 0x9C56, 0x6DF1, 0xC9EE, 0x6DF2, 0x9C57,
+	0x6DF3, 0xB4BE, 0x6DF4, 0x9C58, 0x6DF5, 0x9C59, 0x6DF6, 0x9C5A,
+	0x6DF7, 0xBBEC, 0x6DF8, 0x9C5B, 0x6DF9, 0xD1CD, 0x6DFA, 0x9C5C,
+	0x6DFB, 0xCCED, 0x6DFC, 0xEDB5, 0x6DFD, 0x9C5D, 0x6DFE, 0x9C5E,
+	0x6DFF, 0x9C5F, 0x6E00, 0x9C60, 0x6E01, 0x9C61, 0x6E02, 0x9C62,
+	0x6E03, 0x9C63, 0x6E04, 0x9C64, 0x6E05, 0xC7E5, 0x6E06, 0x9C65,
+	0x6E07, 0x9C66, 0x6E08, 0x9C67, 0x6E09, 0x9C68, 0x6E0A, 0xD4A8,
+	0x6E0B, 0x9C69, 0x6E0C, 0xE4CB, 0x6E0D, 0xD7D5, 0x6E0E, 0xE4C2,
+	0x6E0F, 0x9C6A, 0x6E10, 0xBDA5, 0x6E11, 0xE4C5, 0x6E12, 0x9C6B,
+	0x6E13, 0x9C6C, 0x6E14, 0xD3E6, 0x6E15, 0x9C6D, 0x6E16, 0xE4C9,
+	0x6E17, 0xC9F8, 0x6E18, 0x9C6E, 0x6E19, 0x9C6F, 0x6E1A, 0xE4BE,
+	0x6E1B, 0x9C70, 0x6E1C, 0x9C71, 0x6E1D, 0xD3E5, 0x6E1E, 0x9C72,
+	0x6E1F, 0x9C73, 0x6E20, 0xC7FE, 0x6E21, 0xB6C9, 0x6E22, 0x9C74,
+	0x6E23, 0xD4FC, 0x6E24, 0xB2B3, 0x6E25, 0xE4D7, 0x6E26, 0x9C75,
+	0x6E27, 0x9C76, 0x6E28, 0x9C77, 0x6E29, 0xCEC2, 0x6E2A, 0x9C78,
+	0x6E2B, 0xE4CD, 0x6E2C, 0x9C79, 0x6E2D, 0xCEBC, 0x6E2E, 0x9C7A,
+	0x6E2F, 0xB8DB, 0x6E30, 0x9C7B, 0x6E31, 0x9C7C, 0x6E32, 0xE4D6,
+	0x6E33, 0x9C7D, 0x6E34, 0xBFCA, 0x6E35, 0x9C7E, 0x6E36, 0x9C80,
+	0x6E37, 0x9C81, 0x6E38, 0xD3CE, 0x6E39, 0x9C82, 0x6E3A, 0xC3EC,
+	0x6E3B, 0x9C83, 0x6E3C, 0x9C84, 0x6E3D, 0x9C85, 0x6E3E, 0x9C86,
+	0x6E3F, 0x9C87, 0x6E40, 0x9C88, 0x6E41, 0x9C89, 0x6E42, 0x9C8A,
+	0x6E43, 0xC5C8, 0x6E44, 0xE4D8, 0x6E45, 0x9C8B, 0x6E46, 0x9C8C,
+	0x6E47, 0x9C8D, 0x6E48, 0x9C8E, 0x6E49, 0x9C8F, 0x6E4A, 0x9C90,
+	0x6E4B, 0x9C91, 0x6E4C, 0x9C92, 0x6E4D, 0xCDC4, 0x6E4E, 0xE4CF,
+	0x6E4F, 0x9C93, 0x6E50, 0x9C94, 0x6E51, 0x9C95, 0x6E52, 0x9C96,
+	0x6E53, 0xE4D4, 0x6E54, 0xE4D5, 0x6E55, 0x9C97, 0x6E56, 0xBAFE,
+	0x6E57, 0x9C98, 0x6E58, 0xCFE6, 0x6E59, 0x9C99, 0x6E5A, 0x9C9A,
+	0x6E5B, 0xD5BF, 0x6E5C, 0x9C9B, 0x6E5D, 0x9C9C, 0x6E5E, 0x9C9D,
+	0x6E5F, 0xE4D2, 0x6E60, 0x9C9E, 0x6E61, 0x9C9F, 0x6E62, 0x9CA0,
+	0x6E63, 0x9CA1, 0x6E64, 0x9CA2, 0x6E65, 0x9CA3, 0x6E66, 0x9CA4,
+	0x6E67, 0x9CA5, 0x6E68, 0x9CA6, 0x6E69, 0x9CA7, 0x6E6A, 0x9CA8,
+	0x6E6B, 0xE4D0, 0x6E6C, 0x9CA9, 0x6E6D, 0x9CAA, 0x6E6E, 0xE4CE,
+	0x6E6F, 0x9CAB, 0x6E70, 0x9CAC, 0x6E71, 0x9CAD, 0x6E72, 0x9CAE,
+	0x6E73, 0x9CAF, 0x6E74, 0x9CB0, 0x6E75, 0x9CB1, 0x6E76, 0x9CB2,
+	0x6E77, 0x9CB3, 0x6E78, 0x9CB4, 0x6E79, 0x9CB5, 0x6E7A, 0x9CB6,
+	0x6E7B, 0x9CB7, 0x6E7C, 0x9CB8, 0x6E7D, 0x9CB9, 0x6E7E, 0xCDE5,
+	0x6E7F, 0xCAAA, 0x6E80, 0x9CBA, 0x6E81, 0x9CBB, 0x6E82, 0x9CBC,
+	0x6E83, 0xC0A3, 0x6E84, 0x9CBD, 0x6E85, 0xBDA6, 0x6E86, 0xE4D3,
+	0x6E87, 0x9CBE, 0x6E88, 0x9CBF, 0x6E89, 0xB8C8, 0x6E8A, 0x9CC0,
+	0x6E8B, 0x9CC1, 0x6E8C, 0x9CC2, 0x6E8D, 0x9CC3, 0x6E8E, 0x9CC4,
+	0x6E8F, 0xE4E7, 0x6E90, 0xD4B4, 0x6E91, 0x9CC5, 0x6E92, 0x9CC6,
+	0x6E93, 0x9CC7, 0x6E94, 0x9CC8, 0x6E95, 0x9CC9, 0x6E96, 0x9CCA,
+	0x6E97, 0x9CCB, 0x6E98, 0xE4DB, 0x6E99, 0x9CCC, 0x6E9A, 0x9CCD,
+	0x6E9B, 0x9CCE, 0x6E9C, 0xC1EF, 0x6E9D, 0x9CCF, 0x6E9E, 0x9CD0,
+	0x6E9F, 0xE4E9, 0x6EA0, 0x9CD1, 0x6EA1, 0x9CD2, 0x6EA2, 0xD2E7,
+	0x6EA3, 0x9CD3, 0x6EA4, 0x9CD4, 0x6EA5, 0xE4DF, 0x6EA6, 0x9CD5,
+	0x6EA7, 0xE4E0, 0x6EA8, 0x9CD6, 0x6EA9, 0x9CD7, 0x6EAA, 0xCFAA,
+	0x6EAB, 0x9CD8, 0x6EAC, 0x9CD9, 0x6EAD, 0x9CDA, 0x6EAE, 0x9CDB,
+	0x6EAF, 0xCBDD, 0x6EB0, 0x9CDC, 0x6EB1, 0xE4DA, 0x6EB2, 0xE4D1,
+	0x6EB3, 0x9CDD, 0x6EB4, 0xE4E5, 0x6EB5, 0x9CDE, 0x6EB6, 0xC8DC,
+	0x6EB7, 0xE4E3, 0x6EB8, 0x9CDF, 0x6EB9, 0x9CE0, 0x6EBA, 0xC4E7,
+	0x6EBB, 0xE4E2, 0x6EBC, 0x9CE1, 0x6EBD, 0xE4E1, 0x6EBE, 0x9CE2,
+	0x6EBF, 0x9CE3, 0x6EC0, 0x9CE4, 0x6EC1, 0xB3FC, 0x6EC2, 0xE4E8,
+	0x6EC3, 0x9CE5, 0x6EC4, 0x9CE6, 0x6EC5, 0x9CE7, 0x6EC6, 0x9CE8,
+	0x6EC7, 0xB5E1, 0x6EC8, 0x9CE9, 0x6EC9, 0x9CEA, 0x6ECA, 0x9CEB,
+	0x6ECB, 0xD7CC, 0x6ECC, 0x9CEC, 0x6ECD, 0x9CED, 0x6ECE, 0x9CEE,
+	0x6ECF, 0xE4E6, 0x6ED0, 0x9CEF, 0x6ED1, 0xBBAC, 0x6ED2, 0x9CF0,
+	0x6ED3, 0xD7D2, 0x6ED4, 0xCCCF, 0x6ED5, 0xEBF8, 0x6ED6, 0x9CF1,
+	0x6ED7, 0xE4E4, 0x6ED8, 0x9CF2, 0x6ED9, 0x9CF3, 0x6EDA, 0xB9F6,
+	0x6EDB, 0x9CF4, 0x6EDC, 0x9CF5, 0x6EDD, 0x9CF6, 0x6EDE, 0xD6CD,
+	0x6EDF, 0xE4D9, 0x6EE0, 0xE4DC, 0x6EE1, 0xC2FA, 0x6EE2, 0xE4DE,
+	0x6EE3, 0x9CF7, 0x6EE4, 0xC2CB, 0x6EE5, 0xC0C4, 0x6EE6, 0xC2D0,
+	0x6EE7, 0x9CF8, 0x6EE8, 0xB1F5, 0x6EE9, 0xCCB2, 0x6EEA, 0x9CF9,
+	0x6EEB, 0x9CFA, 0x6EEC, 0x9CFB, 0x6EED, 0x9CFC, 0x6EEE, 0x9CFD,
+	0x6EEF, 0x9CFE, 0x6EF0, 0x9D40, 0x6EF1, 0x9D41, 0x6EF2, 0x9D42,
+	0x6EF3, 0x9D43, 0x6EF4, 0xB5CE, 0x6EF5, 0x9D44, 0x6EF6, 0x9D45,
+	0x6EF7, 0x9D46, 0x6EF8, 0x9D47, 0x6EF9, 0xE4EF, 0x6EFA, 0x9D48,
+	0x6EFB, 0x9D49, 0x6EFC, 0x9D4A, 0x6EFD, 0x9D4B, 0x6EFE, 0x9D4C,
+	0x6EFF, 0x9D4D, 0x6F00, 0x9D4E, 0x6F01, 0x9D4F, 0x6F02, 0xC6AF,
+	0x6F03, 0x9D50, 0x6F04, 0x9D51, 0x6F05, 0x9D52, 0x6F06, 0xC6E1,
+	0x6F07, 0x9D53, 0x6F08, 0x9D54, 0x6F09, 0xE4F5, 0x6F0A, 0x9D55,
+	0x6F0B, 0x9D56, 0x6F0C, 0x9D57, 0x6F0D, 0x9D58, 0x6F0E, 0x9D59,
+	0x6F0F, 0xC2A9, 0x6F10, 0x9D5A, 0x6F11, 0x9D5B, 0x6F12, 0x9D5C,
+	0x6F13, 0xC0EC, 0x6F14, 0xD1DD, 0x6F15, 0xE4EE, 0x6F16, 0x9D5D,
+	0x6F17, 0x9D5E, 0x6F18, 0x9D5F, 0x6F19, 0x9D60, 0x6F1A, 0x9D61,
+	0x6F1B, 0x9D62, 0x6F1C, 0x9D63, 0x6F1D, 0x9D64, 0x6F1E, 0x9D65,
+	0x6F1F, 0x9D66, 0x6F20, 0xC4AE, 0x6F21, 0x9D67, 0x6F22, 0x9D68,
+	0x6F23, 0x9D69, 0x6F24, 0xE4ED, 0x6F25, 0x9D6A, 0x6F26, 0x9D6B,
+	0x6F27, 0x9D6C, 0x6F28, 0x9D6D, 0x6F29, 0xE4F6, 0x6F2A, 0xE4F4,
+	0x6F2B, 0xC2FE, 0x6F2C, 0x9D6E, 0x6F2D, 0xE4DD, 0x6F2E, 0x9D6F,
+	0x6F2F, 0xE4F0, 0x6F30, 0x9D70, 0x6F31, 0xCAFE, 0x6F32, 0x9D71,
+	0x6F33, 0xD5C4, 0x6F34, 0x9D72, 0x6F35, 0x9D73, 0x6F36, 0xE4F1,
+	0x6F37, 0x9D74, 0x6F38, 0x9D75, 0x6F39, 0x9D76, 0x6F3A, 0x9D77,
+	0x6F3B, 0x9D78, 0x6F3C, 0x9D79, 0x6F3D, 0x9D7A, 0x6F3E, 0xD1FA,
+	0x6F3F, 0x9D7B, 0x6F40, 0x9D7C, 0x6F41, 0x9D7D, 0x6F42, 0x9D7E,
+	0x6F43, 0x9D80, 0x6F44, 0x9D81, 0x6F45, 0x9D82, 0x6F46, 0xE4EB,
+	0x6F47, 0xE4EC, 0x6F48, 0x9D83, 0x6F49, 0x9D84, 0x6F4A, 0x9D85,
+	0x6F4B, 0xE4F2, 0x6F4C, 0x9D86, 0x6F4D, 0xCEAB, 0x6F4E, 0x9D87,
+	0x6F4F, 0x9D88, 0x6F50, 0x9D89, 0x6F51, 0x9D8A, 0x6F52, 0x9D8B,
+	0x6F53, 0x9D8C, 0x6F54, 0x9D8D, 0x6F55, 0x9D8E, 0x6F56, 0x9D8F,
+	0x6F57, 0x9D90, 0x6F58, 0xC5CB, 0x6F59, 0x9D91, 0x6F5A, 0x9D92,
+	0x6F5B, 0x9D93, 0x6F5C, 0xC7B1, 0x6F5D, 0x9D94, 0x6F5E, 0xC2BA,
+	0x6F5F, 0x9D95, 0x6F60, 0x9D96, 0x6F61, 0x9D97, 0x6F62, 0xE4EA,
+	0x6F63, 0x9D98, 0x6F64, 0x9D99, 0x6F65, 0x9D9A, 0x6F66, 0xC1CA,
+	0x6F67, 0x9D9B, 0x6F68, 0x9D9C, 0x6F69, 0x9D9D, 0x6F6A, 0x9D9E,
+	0x6F6B, 0x9D9F, 0x6F6C, 0x9DA0, 0x6F6D, 0xCCB6, 0x6F6E, 0xB3B1,
+	0x6F6F, 0x9DA1, 0x6F70, 0x9DA2, 0x6F71, 0x9DA3, 0x6F72, 0xE4FB,
+	0x6F73, 0x9DA4, 0x6F74, 0xE4F3, 0x6F75, 0x9DA5, 0x6F76, 0x9DA6,
+	0x6F77, 0x9DA7, 0x6F78, 0xE4FA, 0x6F79, 0x9DA8, 0x6F7A, 0xE4FD,
+	0x6F7B, 0x9DA9, 0x6F7C, 0xE4FC, 0x6F7D, 0x9DAA, 0x6F7E, 0x9DAB,
+	0x6F7F, 0x9DAC, 0x6F80, 0x9DAD, 0x6F81, 0x9DAE, 0x6F82, 0x9DAF,
+	0x6F83, 0x9DB0, 0x6F84, 0xB3CE, 0x6F85, 0x9DB1, 0x6F86, 0x9DB2,
+	0x6F87, 0x9DB3, 0x6F88, 0xB3BA, 0x6F89, 0xE4F7, 0x6F8A, 0x9DB4,
+	0x6F8B, 0x9DB5, 0x6F8C, 0xE4F9, 0x6F8D, 0xE4F8, 0x6F8E, 0xC5EC,
+	0x6F8F, 0x9DB6, 0x6F90, 0x9DB7, 0x6F91, 0x9DB8, 0x6F92, 0x9DB9,
+	0x6F93, 0x9DBA, 0x6F94, 0x9DBB, 0x6F95, 0x9DBC, 0x6F96, 0x9DBD,
+	0x6F97, 0x9DBE, 0x6F98, 0x9DBF, 0x6F99, 0x9DC0, 0x6F9A, 0x9DC1,
+	0x6F9B, 0x9DC2, 0x6F9C, 0xC0BD, 0x6F9D, 0x9DC3, 0x6F9E, 0x9DC4,
+	0x6F9F, 0x9DC5, 0x6FA0, 0x9DC6, 0x6FA1, 0xD4E8, 0x6FA2, 0x9DC7,
+	0x6FA3, 0x9DC8, 0x6FA4, 0x9DC9, 0x6FA5, 0x9DCA, 0x6FA6, 0x9DCB,
+	0x6FA7, 0xE5A2, 0x6FA8, 0x9DCC, 0x6FA9, 0x9DCD, 0x6FAA, 0x9DCE,
+	0x6FAB, 0x9DCF, 0x6FAC, 0x9DD0, 0x6FAD, 0x9DD1, 0x6FAE, 0x9DD2,
+	0x6FAF, 0x9DD3, 0x6FB0, 0x9DD4, 0x6FB1, 0x9DD5, 0x6FB2, 0x9DD6,
+	0x6FB3, 0xB0C4, 0x6FB4, 0x9DD7, 0x6FB5, 0x9DD8, 0x6FB6, 0xE5A4,
+	0x6FB7, 0x9DD9, 0x6FB8, 0x9DDA, 0x6FB9, 0xE5A3, 0x6FBA, 0x9DDB,
+	0x6FBB, 0x9DDC, 0x6FBC, 0x9DDD, 0x6FBD, 0x9DDE, 0x6FBE, 0x9DDF,
+	0x6FBF, 0x9DE0, 0x6FC0, 0xBCA4, 0x6FC1, 0x9DE1, 0x6FC2, 0xE5A5,
+	0x6FC3, 0x9DE2, 0x6FC4, 0x9DE3, 0x6FC5, 0x9DE4, 0x6FC6, 0x9DE5,
+	0x6FC7, 0x9DE6, 0x6FC8, 0x9DE7, 0x6FC9, 0xE5A1, 0x6FCA, 0x9DE8,
+	0x6FCB, 0x9DE9, 0x6FCC, 0x9DEA, 0x6FCD, 0x9DEB, 0x6FCE, 0x9DEC,
+	0x6FCF, 0x9DED, 0x6FD0, 0x9DEE, 0x6FD1, 0xE4FE, 0x6FD2, 0xB1F4,
+	0x6FD3, 0x9DEF, 0x6FD4, 0x9DF0, 0x6FD5, 0x9DF1, 0x6FD6, 0x9DF2,
+	0x6FD7, 0x9DF3, 0x6FD8, 0x9DF4, 0x6FD9, 0x9DF5, 0x6FDA, 0x9DF6,
+	0x6FDB, 0x9DF7, 0x6FDC, 0x9DF8, 0x6FDD, 0x9DF9, 0x6FDE, 0xE5A8,
+	0x6FDF, 0x9DFA, 0x6FE0, 0xE5A9, 0x6FE1, 0xE5A6, 0x6FE2, 0x9DFB,
+	0x6FE3, 0x9DFC, 0x6FE4, 0x9DFD, 0x6FE5, 0x9DFE, 0x6FE6, 0x9E40,
+	0x6FE7, 0x9E41, 0x6FE8, 0x9E42, 0x6FE9, 0x9E43, 0x6FEA, 0x9E44,
+	0x6FEB, 0x9E45, 0x6FEC, 0x9E46, 0x6FED, 0x9E47, 0x6FEE, 0xE5A7,
+	0x6FEF, 0xE5AA, 0x6FF0, 0x9E48, 0x6FF1, 0x9E49, 0x6FF2, 0x9E4A,
+	0x6FF3, 0x9E4B, 0x6FF4, 0x9E4C, 0x6FF5, 0x9E4D, 0x6FF6, 0x9E4E,
+	0x6FF7, 0x9E4F, 0x6FF8, 0x9E50, 0x6FF9, 0x9E51, 0x6FFA, 0x9E52,
+	0x6FFB, 0x9E53, 0x6FFC, 0x9E54, 0x6FFD, 0x9E55, 0x6FFE, 0x9E56,
+	0x6FFF, 0x9E57, 0x7000, 0x9E58, 0x7001, 0x9E59, 0x7002, 0x9E5A,
+	0x7003, 0x9E5B, 0x7004, 0x9E5C, 0x7005, 0x9E5D, 0x7006, 0x9E5E,
+	0x7007, 0x9E5F, 0x7008, 0x9E60, 0x7009, 0x9E61, 0x700A, 0x9E62,
+	0x700B, 0x9E63, 0x700C, 0x9E64, 0x700D, 0x9E65, 0x700E, 0x9E66,
+	0x700F, 0x9E67, 0x7010, 0x9E68, 0x7011, 0xC6D9, 0x7012, 0x9E69,
+	0x7013, 0x9E6A, 0x7014, 0x9E6B, 0x7015, 0x9E6C, 0x7016, 0x9E6D,
+	0x7017, 0x9E6E, 0x7018, 0x9E6F, 0x7019, 0x9E70, 0x701A, 0xE5AB,
+	0x701B, 0xE5AD, 0x701C, 0x9E71, 0x701D, 0x9E72, 0x701E, 0x9E73,
+	0x701F, 0x9E74, 0x7020, 0x9E75, 0x7021, 0x9E76, 0x7022, 0x9E77,
+	0x7023, 0xE5AC, 0x7024, 0x9E78, 0x7025, 0x9E79, 0x7026, 0x9E7A,
+	0x7027, 0x9E7B, 0x7028, 0x9E7C, 0x7029, 0x9E7D, 0x702A, 0x9E7E,
+	0x702B, 0x9E80, 0x702C, 0x9E81, 0x702D, 0x9E82, 0x702E, 0x9E83,
+	0x702F, 0x9E84, 0x7030, 0x9E85, 0x7031, 0x9E86, 0x7032, 0x9E87,
+	0x7033, 0x9E88, 0x7034, 0x9E89, 0x7035, 0xE5AF, 0x7036, 0x9E8A,
+	0x7037, 0x9E8B, 0x7038, 0x9E8C, 0x7039, 0xE5AE, 0x703A, 0x9E8D,
+	0x703B, 0x9E8E, 0x703C, 0x9E8F, 0x703D, 0x9E90, 0x703E, 0x9E91,
+	0x703F, 0x9E92, 0x7040, 0x9E93, 0x7041, 0x9E94, 0x7042, 0x9E95,
+	0x7043, 0x9E96, 0x7044, 0x9E97, 0x7045, 0x9E98, 0x7046, 0x9E99,
+	0x7047, 0x9E9A, 0x7048, 0x9E9B, 0x7049, 0x9E9C, 0x704A, 0x9E9D,
+	0x704B, 0x9E9E, 0x704C, 0xB9E0, 0x704D, 0x9E9F, 0x704E, 0x9EA0,
+	0x704F, 0xE5B0, 0x7050, 0x9EA1, 0x7051, 0x9EA2, 0x7052, 0x9EA3,
+	0x7053, 0x9EA4, 0x7054, 0x9EA5, 0x7055, 0x9EA6, 0x7056, 0x9EA7,
+	0x7057, 0x9EA8, 0x7058, 0x9EA9, 0x7059, 0x9EAA, 0x705A, 0x9EAB,
+	0x705B, 0x9EAC, 0x705C, 0x9EAD, 0x705D, 0x9EAE, 0x705E, 0xE5B1,
+	0x705F, 0x9EAF, 0x7060, 0x9EB0, 0x7061, 0x9EB1, 0x7062, 0x9EB2,
+	0x7063, 0x9EB3, 0x7064, 0x9EB4, 0x7065, 0x9EB5, 0x7066, 0x9EB6,
+	0x7067, 0x9EB7, 0x7068, 0x9EB8, 0x7069, 0x9EB9, 0x706A, 0x9EBA,
+	0x706B, 0xBBF0, 0x706C, 0xECE1, 0x706D, 0xC3F0, 0x706E, 0x9EBB,
+	0x706F, 0xB5C6, 0x7070, 0xBBD2, 0x7071, 0x9EBC, 0x7072, 0x9EBD,
+	0x7073, 0x9EBE, 0x7074, 0x9EBF, 0x7075, 0xC1E9, 0x7076, 0xD4EE,
+	0x7077, 0x9EC0, 0x7078, 0xBEC4, 0x7079, 0x9EC1, 0x707A, 0x9EC2,
+	0x707B, 0x9EC3, 0x707C, 0xD7C6, 0x707D, 0x9EC4, 0x707E, 0xD4D6,
+	0x707F, 0xB2D3, 0x7080, 0xECBE, 0x7081, 0x9EC5, 0x7082, 0x9EC6,
+	0x7083, 0x9EC7, 0x7084, 0x9EC8, 0x7085, 0xEAC1, 0x7086, 0x9EC9,
+	0x7087, 0x9ECA, 0x7088, 0x9ECB, 0x7089, 0xC2AF, 0x708A, 0xB4B6,
+	0x708B, 0x9ECC, 0x708C, 0x9ECD, 0x708D, 0x9ECE, 0x708E, 0xD1D7,
+	0x708F, 0x9ECF, 0x7090, 0x9ED0, 0x7091, 0x9ED1, 0x7092, 0xB3B4,
+	0x7093, 0x9ED2, 0x7094, 0xC8B2, 0x7095, 0xBFBB, 0x7096, 0xECC0,
+	0x7097, 0x9ED3, 0x7098, 0x9ED4, 0x7099, 0xD6CB, 0x709A, 0x9ED5,
+	0x709B, 0x9ED6, 0x709C, 0xECBF, 0x709D, 0xECC1, 0x709E, 0x9ED7,
+	0x709F, 0x9ED8, 0x70A0, 0x9ED9, 0x70A1, 0x9EDA, 0x70A2, 0x9EDB,
+	0x70A3, 0x9EDC, 0x70A4, 0x9EDD, 0x70A5, 0x9EDE, 0x70A6, 0x9EDF,
+	0x70A7, 0x9EE0, 0x70A8, 0x9EE1, 0x70A9, 0x9EE2, 0x70AA, 0x9EE3,
+	0x70AB, 0xECC5, 0x70AC, 0xBEE6, 0x70AD, 0xCCBF, 0x70AE, 0xC5DA,
+	0x70AF, 0xBEBC, 0x70B0, 0x9EE4, 0x70B1, 0xECC6, 0x70B2, 0x9EE5,
+	0x70B3, 0xB1FE, 0x70B4, 0x9EE6, 0x70B5, 0x9EE7, 0x70B6, 0x9EE8,
+	0x70B7, 0xECC4, 0x70B8, 0xD5A8, 0x70B9, 0xB5E3, 0x70BA, 0x9EE9,
+	0x70BB, 0xECC2, 0x70BC, 0xC1B6, 0x70BD, 0xB3E3, 0x70BE, 0x9EEA,
+	0x70BF, 0x9EEB, 0x70C0, 0xECC3, 0x70C1, 0xCBB8, 0x70C2, 0xC0C3,
+	0x70C3, 0xCCFE, 0x70C4, 0x9EEC, 0x70C5, 0x9EED, 0x70C6, 0x9EEE,
+	0x70C7, 0x9EEF, 0x70C8, 0xC1D2, 0x70C9, 0x9EF0, 0x70CA, 0xECC8,
+	0x70CB, 0x9EF1, 0x70CC, 0x9EF2, 0x70CD, 0x9EF3, 0x70CE, 0x9EF4,
+	0x70CF, 0x9EF5, 0x70D0, 0x9EF6, 0x70D1, 0x9EF7, 0x70D2, 0x9EF8,
+	0x70D3, 0x9EF9, 0x70D4, 0x9EFA, 0x70D5, 0x9EFB, 0x70D6, 0x9EFC,
+	0x70D7, 0x9EFD, 0x70D8, 0xBAE6, 0x70D9, 0xC0D3, 0x70DA, 0x9EFE,
+	0x70DB, 0xD6F2, 0x70DC, 0x9F40, 0x70DD, 0x9F41, 0x70DE, 0x9F42,
+	0x70DF, 0xD1CC, 0x70E0, 0x9F43, 0x70E1, 0x9F44, 0x70E2, 0x9F45,
+	0x70E3, 0x9F46, 0x70E4, 0xBFBE, 0x70E5, 0x9F47, 0x70E6, 0xB7B3,
+	0x70E7, 0xC9D5, 0x70E8, 0xECC7, 0x70E9, 0xBBE2, 0x70EA, 0x9F48,
+	0x70EB, 0xCCCC, 0x70EC, 0xBDFD, 0x70ED, 0xC8C8, 0x70EE, 0x9F49,
+	0x70EF, 0xCFA9, 0x70F0, 0x9F4A, 0x70F1, 0x9F4B, 0x70F2, 0x9F4C,
+	0x70F3, 0x9F4D, 0x70F4, 0x9F4E, 0x70F5, 0x9F4F, 0x70F6, 0x9F50,
+	0x70F7, 0xCDE9, 0x70F8, 0x9F51, 0x70F9, 0xC5EB, 0x70FA, 0x9F52,
+	0x70FB, 0x9F53, 0x70FC, 0x9F54, 0x70FD, 0xB7E9, 0x70FE, 0x9F55,
+	0x70FF, 0x9F56, 0x7100, 0x9F57, 0x7101, 0x9F58, 0x7102, 0x9F59,
+	0x7103, 0x9F5A, 0x7104, 0x9F5B, 0x7105, 0x9F5C, 0x7106, 0x9F5D,
+	0x7107, 0x9F5E, 0x7108, 0x9F5F, 0x7109, 0xD1C9, 0x710A, 0xBAB8,
+	0x710B, 0x9F60, 0x710C, 0x9F61, 0x710D, 0x9F62, 0x710E, 0x9F63,
+	0x710F, 0x9F64, 0x7110, 0xECC9, 0x7111, 0x9F65, 0x7112, 0x9F66,
+	0x7113, 0xECCA, 0x7114, 0x9F67, 0x7115, 0xBBC0, 0x7116, 0xECCB,
+	0x7117, 0x9F68, 0x7118, 0xECE2, 0x7119, 0xB1BA, 0x711A, 0xB7D9,
+	0x711B, 0x9F69, 0x711C, 0x9F6A, 0x711D, 0x9F6B, 0x711E, 0x9F6C,
+	0x711F, 0x9F6D, 0x7120, 0x9F6E, 0x7121, 0x9F6F, 0x7122, 0x9F70,
+	0x7123, 0x9F71, 0x7124, 0x9F72, 0x7125, 0x9F73, 0x7126, 0xBDB9,
+	0x7127, 0x9F74, 0x7128, 0x9F75, 0x7129, 0x9F76, 0x712A, 0x9F77,
+	0x712B, 0x9F78, 0x712C, 0x9F79, 0x712D, 0x9F7A, 0x712E, 0x9F7B,
+	0x712F, 0xECCC, 0x7130, 0xD1E6, 0x7131, 0xECCD, 0x7132, 0x9F7C,
+	0x7133, 0x9F7D, 0x7134, 0x9F7E, 0x7135, 0x9F80, 0x7136, 0xC8BB,
+	0x7137, 0x9F81, 0x7138, 0x9F82, 0x7139, 0x9F83, 0x713A, 0x9F84,
+	0x713B, 0x9F85, 0x713C, 0x9F86, 0x713D, 0x9F87, 0x713E, 0x9F88,
+	0x713F, 0x9F89, 0x7140, 0x9F8A, 0x7141, 0x9F8B, 0x7142, 0x9F8C,
+	0x7143, 0x9F8D, 0x7144, 0x9F8E, 0x7145, 0xECD1, 0x7146, 0x9F8F,
+	0x7147, 0x9F90, 0x7148, 0x9F91, 0x7149, 0x9F92, 0x714A, 0xECD3,
+	0x714B, 0x9F93, 0x714C, 0xBBCD, 0x714D, 0x9F94, 0x714E, 0xBCE5,
+	0x714F, 0x9F95, 0x7150, 0x9F96, 0x7151, 0x9F97, 0x7152, 0x9F98,
+	0x7153, 0x9F99, 0x7154, 0x9F9A, 0x7155, 0x9F9B, 0x7156, 0x9F9C,
+	0x7157, 0x9F9D, 0x7158, 0x9F9E, 0x7159, 0x9F9F, 0x715A, 0x9FA0,
+	0x715B, 0x9FA1, 0x715C, 0xECCF, 0x715D, 0x9FA2, 0x715E, 0xC9B7,
+	0x715F, 0x9FA3, 0x7160, 0x9FA4, 0x7161, 0x9FA5, 0x7162, 0x9FA6,
+	0x7163, 0x9FA7, 0x7164, 0xC3BA, 0x7165, 0x9FA8, 0x7166, 0xECE3,
+	0x7167, 0xD5D5, 0x7168, 0xECD0, 0x7169, 0x9FA9, 0x716A, 0x9FAA,
+	0x716B, 0x9FAB, 0x716C, 0x9FAC, 0x716D, 0x9FAD, 0x716E, 0xD6F3,
+	0x716F, 0x9FAE, 0x7170, 0x9FAF, 0x7171, 0x9FB0, 0x7172, 0xECD2,
+	0x7173, 0xECCE, 0x7174, 0x9FB1, 0x7175, 0x9FB2, 0x7176, 0x9FB3,
+	0x7177, 0x9FB4, 0x7178, 0xECD4, 0x7179, 0x9FB5, 0x717A, 0xECD5,
+	0x717B, 0x9FB6, 0x717C, 0x9FB7, 0x717D, 0xC9BF, 0x717E, 0x9FB8,
+	0x717F, 0x9FB9, 0x7180, 0x9FBA, 0x7181, 0x9FBB, 0x7182, 0x9FBC,
+	0x7183, 0x9FBD, 0x7184, 0xCFA8, 0x7185, 0x9FBE, 0x7186, 0x9FBF,
+	0x7187, 0x9FC0, 0x7188, 0x9FC1, 0x7189, 0x9FC2, 0x718A, 0xD0DC,
+	0x718B, 0x9FC3, 0x718C, 0x9FC4, 0x718D, 0x9FC5, 0x718E, 0x9FC6,
+	0x718F, 0xD1AC, 0x7190, 0x9FC7, 0x7191, 0x9FC8, 0x7192, 0x9FC9,
+	0x7193, 0x9FCA, 0x7194, 0xC8DB, 0x7195, 0x9FCB, 0x7196, 0x9FCC,
+	0x7197, 0x9FCD, 0x7198, 0xECD6, 0x7199, 0xCEF5, 0x719A, 0x9FCE,
+	0x719B, 0x9FCF, 0x719C, 0x9FD0, 0x719D, 0x9FD1, 0x719E, 0x9FD2,
+	0x719F, 0xCAEC, 0x71A0, 0xECDA, 0x71A1, 0x9FD3, 0x71A2, 0x9FD4,
+	0x71A3, 0x9FD5, 0x71A4, 0x9FD6, 0x71A5, 0x9FD7, 0x71A6, 0x9FD8,
+	0x71A7, 0x9FD9, 0x71A8, 0xECD9, 0x71A9, 0x9FDA, 0x71AA, 0x9FDB,
+	0x71AB, 0x9FDC, 0x71AC, 0xB0BE, 0x71AD, 0x9FDD, 0x71AE, 0x9FDE,
+	0x71AF, 0x9FDF, 0x71B0, 0x9FE0, 0x71B1, 0x9FE1, 0x71B2, 0x9FE2,
+	0x71B3, 0xECD7, 0x71B4, 0x9FE3, 0x71B5, 0xECD8, 0x71B6, 0x9FE4,
+	0x71B7, 0x9FE5, 0x71B8, 0x9FE6, 0x71B9, 0xECE4, 0x71BA, 0x9FE7,
+	0x71BB, 0x9FE8, 0x71BC, 0x9FE9, 0x71BD, 0x9FEA, 0x71BE, 0x9FEB,
+	0x71BF, 0x9FEC, 0x71C0, 0x9FED, 0x71C1, 0x9FEE, 0x71C2, 0x9FEF,
+	0x71C3, 0xC8BC, 0x71C4, 0x9FF0, 0x71C5, 0x9FF1, 0x71C6, 0x9FF2,
+	0x71C7, 0x9FF3, 0x71C8, 0x9FF4, 0x71C9, 0x9FF5, 0x71CA, 0x9FF6,
+	0x71CB, 0x9FF7, 0x71CC, 0x9FF8, 0x71CD, 0x9FF9, 0x71CE, 0xC1C7,
+	0x71CF, 0x9FFA, 0x71D0, 0x9FFB, 0x71D1, 0x9FFC, 0x71D2, 0x9FFD,
+	0x71D3, 0x9FFE, 0x71D4, 0xECDC, 0x71D5, 0xD1E0, 0x71D6, 0xA040,
+	0x71D7, 0xA041, 0x71D8, 0xA042, 0x71D9, 0xA043, 0x71DA, 0xA044,
+	0x71DB, 0xA045, 0x71DC, 0xA046, 0x71DD, 0xA047, 0x71DE, 0xA048,
+	0x71DF, 0xA049, 0x71E0, 0xECDB, 0x71E1, 0xA04A, 0x71E2, 0xA04B,
+	0x71E3, 0xA04C, 0x71E4, 0xA04D, 0x71E5, 0xD4EF, 0x71E6, 0xA04E,
+	0x71E7, 0xECDD, 0x71E8, 0xA04F, 0x71E9, 0xA050, 0x71EA, 0xA051,
+	0x71EB, 0xA052, 0x71EC, 0xA053, 0x71ED, 0xA054, 0x71EE, 0xDBC6,
+	0x71EF, 0xA055, 0x71F0, 0xA056, 0x71F1, 0xA057, 0x71F2, 0xA058,
+	0x71F3, 0xA059, 0x71F4, 0xA05A, 0x71F5, 0xA05B, 0x71F6, 0xA05C,
+	0x71F7, 0xA05D, 0x71F8, 0xA05E, 0x71F9, 0xECDE, 0x71FA, 0xA05F,
+	0x71FB, 0xA060, 0x71FC, 0xA061, 0x71FD, 0xA062, 0x71FE, 0xA063,
+	0x71FF, 0xA064, 0x7200, 0xA065, 0x7201, 0xA066, 0x7202, 0xA067,
+	0x7203, 0xA068, 0x7204, 0xA069, 0x7205, 0xA06A, 0x7206, 0xB1AC,
+	0x7207, 0xA06B, 0x7208, 0xA06C, 0x7209, 0xA06D, 0x720A, 0xA06E,
+	0x720B, 0xA06F, 0x720C, 0xA070, 0x720D, 0xA071, 0x720E, 0xA072,
+	0x720F, 0xA073, 0x7210, 0xA074, 0x7211, 0xA075, 0x7212, 0xA076,
+	0x7213, 0xA077, 0x7214, 0xA078, 0x7215, 0xA079, 0x7216, 0xA07A,
+	0x7217, 0xA07B, 0x7218, 0xA07C, 0x7219, 0xA07D, 0x721A, 0xA07E,
+	0x721B, 0xA080, 0x721C, 0xA081, 0x721D, 0xECDF, 0x721E, 0xA082,
+	0x721F, 0xA083, 0x7220, 0xA084, 0x7221, 0xA085, 0x7222, 0xA086,
+	0x7223, 0xA087, 0x7224, 0xA088, 0x7225, 0xA089, 0x7226, 0xA08A,
+	0x7227, 0xA08B, 0x7228, 0xECE0, 0x7229, 0xA08C, 0x722A, 0xD7A6,
+	0x722B, 0xA08D, 0x722C, 0xC5C0, 0x722D, 0xA08E, 0x722E, 0xA08F,
+	0x722F, 0xA090, 0x7230, 0xEBBC, 0x7231, 0xB0AE, 0x7232, 0xA091,
+	0x7233, 0xA092, 0x7234, 0xA093, 0x7235, 0xBEF4, 0x7236, 0xB8B8,
+	0x7237, 0xD2AF, 0x7238, 0xB0D6, 0x7239, 0xB5F9, 0x723A, 0xA094,
+	0x723B, 0xD8B3, 0x723C, 0xA095, 0x723D, 0xCBAC, 0x723E, 0xA096,
+	0x723F, 0xE3DD, 0x7240, 0xA097, 0x7241, 0xA098, 0x7242, 0xA099,
+	0x7243, 0xA09A, 0x7244, 0xA09B, 0x7245, 0xA09C, 0x7246, 0xA09D,
+	0x7247, 0xC6AC, 0x7248, 0xB0E6, 0x7249, 0xA09E, 0x724A, 0xA09F,
+	0x724B, 0xA0A0, 0x724C, 0xC5C6, 0x724D, 0xEBB9, 0x724E, 0xA0A1,
+	0x724F, 0xA0A2, 0x7250, 0xA0A3, 0x7251, 0xA0A4, 0x7252, 0xEBBA,
+	0x7253, 0xA0A5, 0x7254, 0xA0A6, 0x7255, 0xA0A7, 0x7256, 0xEBBB,
+	0x7257, 0xA0A8, 0x7258, 0xA0A9, 0x7259, 0xD1C0, 0x725A, 0xA0AA,
+	0x725B, 0xC5A3, 0x725C, 0xA0AB, 0x725D, 0xEAF2, 0x725E, 0xA0AC,
+	0x725F, 0xC4B2, 0x7260, 0xA0AD, 0x7261, 0xC4B5, 0x7262, 0xC0CE,
+	0x7263, 0xA0AE, 0x7264, 0xA0AF, 0x7265, 0xA0B0, 0x7266, 0xEAF3,
+	0x7267, 0xC4C1, 0x7268, 0xA0B1, 0x7269, 0xCEEF, 0x726A, 0xA0B2,
+	0x726B, 0xA0B3, 0x726C, 0xA0B4, 0x726D, 0xA0B5, 0x726E, 0xEAF0,
+	0x726F, 0xEAF4, 0x7270, 0xA0B6, 0x7271, 0xA0B7, 0x7272, 0xC9FC,
+	0x7273, 0xA0B8, 0x7274, 0xA0B9, 0x7275, 0xC7A3, 0x7276, 0xA0BA,
+	0x7277, 0xA0BB, 0x7278, 0xA0BC, 0x7279, 0xCCD8, 0x727A, 0xCEFE,
+	0x727B, 0xA0BD, 0x727C, 0xA0BE, 0x727D, 0xA0BF, 0x727E, 0xEAF5,
+	0x727F, 0xEAF6, 0x7280, 0xCFAC, 0x7281, 0xC0E7, 0x7282, 0xA0C0,
+	0x7283, 0xA0C1, 0x7284, 0xEAF7, 0x7285, 0xA0C2, 0x7286, 0xA0C3,
+	0x7287, 0xA0C4, 0x7288, 0xA0C5, 0x7289, 0xA0C6, 0x728A, 0xB6BF,
+	0x728B, 0xEAF8, 0x728C, 0xA0C7, 0x728D, 0xEAF9, 0x728E, 0xA0C8,
+	0x728F, 0xEAFA, 0x7290, 0xA0C9, 0x7291, 0xA0CA, 0x7292, 0xEAFB,
+	0x7293, 0xA0CB, 0x7294, 0xA0CC, 0x7295, 0xA0CD, 0x7296, 0xA0CE,
+	0x7297, 0xA0CF, 0x7298, 0xA0D0, 0x7299, 0xA0D1, 0x729A, 0xA0D2,
+	0x729B, 0xA0D3, 0x729C, 0xA0D4, 0x729D, 0xA0D5, 0x729E, 0xA0D6,
+	0x729F, 0xEAF1, 0x72A0, 0xA0D7, 0x72A1, 0xA0D8, 0x72A2, 0xA0D9,
+	0x72A3, 0xA0DA, 0x72A4, 0xA0DB, 0x72A5, 0xA0DC, 0x72A6, 0xA0DD,
+	0x72A7, 0xA0DE, 0x72A8, 0xA0DF, 0x72A9, 0xA0E0, 0x72AA, 0xA0E1,
+	0x72AB, 0xA0E2, 0x72AC, 0xC8AE, 0x72AD, 0xE1EB, 0x72AE, 0xA0E3,
+	0x72AF, 0xB7B8, 0x72B0, 0xE1EC, 0x72B1, 0xA0E4, 0x72B2, 0xA0E5,
+	0x72B3, 0xA0E6, 0x72B4, 0xE1ED, 0x72B5, 0xA0E7, 0x72B6, 0xD7B4,
+	0x72B7, 0xE1EE, 0x72B8, 0xE1EF, 0x72B9, 0xD3CC, 0x72BA, 0xA0E8,
+	0x72BB, 0xA0E9, 0x72BC, 0xA0EA, 0x72BD, 0xA0EB, 0x72BE, 0xA0EC,
+	0x72BF, 0xA0ED, 0x72C0, 0xA0EE, 0x72C1, 0xE1F1, 0x72C2, 0xBFF1,
+	0x72C3, 0xE1F0, 0x72C4, 0xB5D2, 0x72C5, 0xA0EF, 0x72C6, 0xA0F0,
+	0x72C7, 0xA0F1, 0x72C8, 0xB1B7, 0x72C9, 0xA0F2, 0x72CA, 0xA0F3,
+	0x72CB, 0xA0F4, 0x72CC, 0xA0F5, 0x72CD, 0xE1F3, 0x72CE, 0xE1F2,
+	0x72CF, 0xA0F6, 0x72D0, 0xBAFC, 0x72D1, 0xA0F7, 0x72D2, 0xE1F4,
+	0x72D3, 0xA0F8, 0x72D4, 0xA0F9, 0x72D5, 0xA0FA, 0x72D6, 0xA0FB,
+	0x72D7, 0xB9B7, 0x72D8, 0xA0FC, 0x72D9, 0xBED1, 0x72DA, 0xA0FD,
+	0x72DB, 0xA0FE, 0x72DC, 0xAA40, 0x72DD, 0xAA41, 0x72DE, 0xC4FC,
+	0x72DF, 0xAA42, 0x72E0, 0xBADD, 0x72E1, 0xBDC6, 0x72E2, 0xAA43,
+	0x72E3, 0xAA44, 0x72E4, 0xAA45, 0x72E5, 0xAA46, 0x72E6, 0xAA47,
+	0x72E7, 0xAA48, 0x72E8, 0xE1F5, 0x72E9, 0xE1F7, 0x72EA, 0xAA49,
+	0x72EB, 0xAA4A, 0x72EC, 0xB6C0, 0x72ED, 0xCFC1, 0x72EE, 0xCAA8,
+	0x72EF, 0xE1F6, 0x72F0, 0xD5F8, 0x72F1, 0xD3FC, 0x72F2, 0xE1F8,
+	0x72F3, 0xE1FC, 0x72F4, 0xE1F9, 0x72F5, 0xAA4B, 0x72F6, 0xAA4C,
+	0x72F7, 0xE1FA, 0x72F8, 0xC0EA, 0x72F9, 0xAA4D, 0x72FA, 0xE1FE,
+	0x72FB, 0xE2A1, 0x72FC, 0xC0C7, 0x72FD, 0xAA4E, 0x72FE, 0xAA4F,
+	0x72FF, 0xAA50, 0x7300, 0xAA51, 0x7301, 0xE1FB, 0x7302, 0xAA52,
+	0x7303, 0xE1FD, 0x7304, 0xAA53, 0x7305, 0xAA54, 0x7306, 0xAA55,
+	0x7307, 0xAA56, 0x7308, 0xAA57, 0x7309, 0xAA58, 0x730A, 0xE2A5,
+	0x730B, 0xAA59, 0x730C, 0xAA5A, 0x730D, 0xAA5B, 0x730E, 0xC1D4,
+	0x730F, 0xAA5C, 0x7310, 0xAA5D, 0x7311, 0xAA5E, 0x7312, 0xAA5F,
+	0x7313, 0xE2A3, 0x7314, 0xAA60, 0x7315, 0xE2A8, 0x7316, 0xB2FE,
+	0x7317, 0xE2A2, 0x7318, 0xAA61, 0x7319, 0xAA62, 0x731A, 0xAA63,
+	0x731B, 0xC3CD, 0x731C, 0xB2C2, 0x731D, 0xE2A7, 0x731E, 0xE2A6,
+	0x731F, 0xAA64, 0x7320, 0xAA65, 0x7321, 0xE2A4, 0x7322, 0xE2A9,
+	0x7323, 0xAA66, 0x7324, 0xAA67, 0x7325, 0xE2AB, 0x7326, 0xAA68,
+	0x7327, 0xAA69, 0x7328, 0xAA6A, 0x7329, 0xD0C9, 0x732A, 0xD6ED,
+	0x732B, 0xC3A8, 0x732C, 0xE2AC, 0x732D, 0xAA6B, 0x732E, 0xCFD7,
+	0x732F, 0xAA6C, 0x7330, 0xAA6D, 0x7331, 0xE2AE, 0x7332, 0xAA6E,
+	0x7333, 0xAA6F, 0x7334, 0xBAEF, 0x7335, 0xAA70, 0x7336, 0xAA71,
+	0x7337, 0xE9E0, 0x7338, 0xE2AD, 0x7339, 0xE2AA, 0x733A, 0xAA72,
+	0x733B, 0xAA73, 0x733C, 0xAA74, 0x733D, 0xAA75, 0x733E, 0xBBAB,
+	0x733F, 0xD4B3, 0x7340, 0xAA76, 0x7341, 0xAA77, 0x7342, 0xAA78,
+	0x7343, 0xAA79, 0x7344, 0xAA7A, 0x7345, 0xAA7B, 0x7346, 0xAA7C,
+	0x7347, 0xAA7D, 0x7348, 0xAA7E, 0x7349, 0xAA80, 0x734A, 0xAA81,
+	0x734B, 0xAA82, 0x734C, 0xAA83, 0x734D, 0xE2B0, 0x734E, 0xAA84,
+	0x734F, 0xAA85, 0x7350, 0xE2AF, 0x7351, 0xAA86, 0x7352, 0xE9E1,
+	0x7353, 0xAA87, 0x7354, 0xAA88, 0x7355, 0xAA89, 0x7356, 0xAA8A,
+	0x7357, 0xE2B1, 0x7358, 0xAA8B, 0x7359, 0xAA8C, 0x735A, 0xAA8D,
+	0x735B, 0xAA8E, 0x735C, 0xAA8F, 0x735D, 0xAA90, 0x735E, 0xAA91,
+	0x735F, 0xAA92, 0x7360, 0xE2B2, 0x7361, 0xAA93, 0x7362, 0xAA94,
+	0x7363, 0xAA95, 0x7364, 0xAA96, 0x7365, 0xAA97, 0x7366, 0xAA98,
+	0x7367, 0xAA99, 0x7368, 0xAA9A, 0x7369, 0xAA9B, 0x736A, 0xAA9C,
+	0x736B, 0xAA9D, 0x736C, 0xE2B3, 0x736D, 0xCCA1, 0x736E, 0xAA9E,
+	0x736F, 0xE2B4, 0x7370, 0xAA9F, 0x7371, 0xAAA0, 0x7372, 0xAB40,
+	0x7373, 0xAB41, 0x7374, 0xAB42, 0x7375, 0xAB43, 0x7376, 0xAB44,
+	0x7377, 0xAB45, 0x7378, 0xAB46, 0x7379, 0xAB47, 0x737A, 0xAB48,
+	0x737B, 0xAB49, 0x737C, 0xAB4A, 0x737D, 0xAB4B, 0x737E, 0xE2B5,
+	0x737F, 0xAB4C, 0x7380, 0xAB4D, 0x7381, 0xAB4E, 0x7382, 0xAB4F,
+	0x7383, 0xAB50, 0x7384, 0xD0FE, 0x7385, 0xAB51, 0x7386, 0xAB52,
+	0x7387, 0xC2CA, 0x7388, 0xAB53, 0x7389, 0xD3F1, 0x738A, 0xAB54,
+	0x738B, 0xCDF5, 0x738C, 0xAB55, 0x738D, 0xAB56, 0x738E, 0xE7E0,
+	0x738F, 0xAB57, 0x7390, 0xAB58, 0x7391, 0xE7E1, 0x7392, 0xAB59,
+	0x7393, 0xAB5A, 0x7394, 0xAB5B, 0x7395, 0xAB5C, 0x7396, 0xBEC1,
+	0x7397, 0xAB5D, 0x7398, 0xAB5E, 0x7399, 0xAB5F, 0x739A, 0xAB60,
+	0x739B, 0xC2EA, 0x739C, 0xAB61, 0x739D, 0xAB62, 0x739E, 0xAB63,
+	0x739F, 0xE7E4, 0x73A0, 0xAB64, 0x73A1, 0xAB65, 0x73A2, 0xE7E3,
+	0x73A3, 0xAB66, 0x73A4, 0xAB67, 0x73A5, 0xAB68, 0x73A6, 0xAB69,
+	0x73A7, 0xAB6A, 0x73A8, 0xAB6B, 0x73A9, 0xCDE6, 0x73AA, 0xAB6C,
+	0x73AB, 0xC3B5, 0x73AC, 0xAB6D, 0x73AD, 0xAB6E, 0x73AE, 0xE7E2,
+	0x73AF, 0xBBB7, 0x73B0, 0xCFD6, 0x73B1, 0xAB6F, 0x73B2, 0xC1E1,
+	0x73B3, 0xE7E9, 0x73B4, 0xAB70, 0x73B5, 0xAB71, 0x73B6, 0xAB72,
+	0x73B7, 0xE7E8, 0x73B8, 0xAB73, 0x73B9, 0xAB74, 0x73BA, 0xE7F4,
+	0x73BB, 0xB2A3, 0x73BC, 0xAB75, 0x73BD, 0xAB76, 0x73BE, 0xAB77,
+	0x73BF, 0xAB78, 0x73C0, 0xE7EA, 0x73C1, 0xAB79, 0x73C2, 0xE7E6,
+	0x73C3, 0xAB7A, 0x73C4, 0xAB7B, 0x73C5, 0xAB7C, 0x73C6, 0xAB7D,
+	0x73C7, 0xAB7E, 0x73C8, 0xE7EC, 0x73C9, 0xE7EB, 0x73CA, 0xC9BA,
+	0x73CB, 0xAB80, 0x73CC, 0xAB81, 0x73CD, 0xD5E4, 0x73CE, 0xAB82,
+	0x73CF, 0xE7E5, 0x73D0, 0xB7A9, 0x73D1, 0xE7E7, 0x73D2, 0xAB83,
+	0x73D3, 0xAB84, 0x73D4, 0xAB85, 0x73D5, 0xAB86, 0x73D6, 0xAB87,
+	0x73D7, 0xAB88, 0x73D8, 0xAB89, 0x73D9, 0xE7EE, 0x73DA, 0xAB8A,
+	0x73DB, 0xAB8B, 0x73DC, 0xAB8C, 0x73DD, 0xAB8D, 0x73DE, 0xE7F3,
+	0x73DF, 0xAB8E, 0x73E0, 0xD6E9, 0x73E1, 0xAB8F, 0x73E2, 0xAB90,
+	0x73E3, 0xAB91, 0x73E4, 0xAB92, 0x73E5, 0xE7ED, 0x73E6, 0xAB93,
+	0x73E7, 0xE7F2, 0x73E8, 0xAB94, 0x73E9, 0xE7F1, 0x73EA, 0xAB95,
+	0x73EB, 0xAB96, 0x73EC, 0xAB97, 0x73ED, 0xB0E0, 0x73EE, 0xAB98,
+	0x73EF, 0xAB99, 0x73F0, 0xAB9A, 0x73F1, 0xAB9B, 0x73F2, 0xE7F5,
+	0x73F3, 0xAB9C, 0x73F4, 0xAB9D, 0x73F5, 0xAB9E, 0x73F6, 0xAB9F,
+	0x73F7, 0xABA0, 0x73F8, 0xAC40, 0x73F9, 0xAC41, 0x73FA, 0xAC42,
+	0x73FB, 0xAC43, 0x73FC, 0xAC44, 0x73FD, 0xAC45, 0x73FE, 0xAC46,
+	0x73FF, 0xAC47, 0x7400, 0xAC48, 0x7401, 0xAC49, 0x7402, 0xAC4A,
+	0x7403, 0xC7F2, 0x7404, 0xAC4B, 0x7405, 0xC0C5, 0x7406, 0xC0ED,
+	0x7407, 0xAC4C, 0x7408, 0xAC4D, 0x7409, 0xC1F0, 0x740A, 0xE7F0,
+	0x740B, 0xAC4E, 0x740C, 0xAC4F, 0x740D, 0xAC50, 0x740E, 0xAC51,
+	0x740F, 0xE7F6, 0x7410, 0xCBF6, 0x7411, 0xAC52, 0x7412, 0xAC53,
+	0x7413, 0xAC54, 0x7414, 0xAC55, 0x7415, 0xAC56, 0x7416, 0xAC57,
+	0x7417, 0xAC58, 0x7418, 0xAC59, 0x7419, 0xAC5A, 0x741A, 0xE8A2,
+	0x741B, 0xE8A1, 0x741C, 0xAC5B, 0x741D, 0xAC5C, 0x741E, 0xAC5D,
+	0x741F, 0xAC5E, 0x7420, 0xAC5F, 0x7421, 0xAC60, 0x7422, 0xD7C1,
+	0x7423, 0xAC61, 0x7424, 0xAC62, 0x7425, 0xE7FA, 0x7426, 0xE7F9,
+	0x7427, 0xAC63, 0x7428, 0xE7FB, 0x7429, 0xAC64, 0x742A, 0xE7F7,
+	0x742B, 0xAC65, 0x742C, 0xE7FE, 0x742D, 0xAC66, 0x742E, 0xE7FD,
+	0x742F, 0xAC67, 0x7430, 0xE7FC, 0x7431, 0xAC68, 0x7432, 0xAC69,
+	0x7433, 0xC1D5, 0x7434, 0xC7D9, 0x7435, 0xC5FD, 0x7436, 0xC5C3,
+	0x7437, 0xAC6A, 0x7438, 0xAC6B, 0x7439, 0xAC6C, 0x743A, 0xAC6D,
+	0x743B, 0xAC6E, 0x743C, 0xC7ED, 0x743D, 0xAC6F, 0x743E, 0xAC70,
+	0x743F, 0xAC71, 0x7440, 0xAC72, 0x7441, 0xE8A3, 0x7442, 0xAC73,
+	0x7443, 0xAC74, 0x7444, 0xAC75, 0x7445, 0xAC76, 0x7446, 0xAC77,
+	0x7447, 0xAC78, 0x7448, 0xAC79, 0x7449, 0xAC7A, 0x744A, 0xAC7B,
+	0x744B, 0xAC7C, 0x744C, 0xAC7D, 0x744D, 0xAC7E, 0x744E, 0xAC80,
+	0x744F, 0xAC81, 0x7450, 0xAC82, 0x7451, 0xAC83, 0x7452, 0xAC84,
+	0x7453, 0xAC85, 0x7454, 0xAC86, 0x7455, 0xE8A6, 0x7456, 0xAC87,
+	0x7457, 0xE8A5, 0x7458, 0xAC88, 0x7459, 0xE8A7, 0x745A, 0xBAF7,
+	0x745B, 0xE7F8, 0x745C, 0xE8A4, 0x745D, 0xAC89, 0x745E, 0xC8F0,
+	0x745F, 0xC9AA, 0x7460, 0xAC8A, 0x7461, 0xAC8B, 0x7462, 0xAC8C,
+	0x7463, 0xAC8D, 0x7464, 0xAC8E, 0x7465, 0xAC8F, 0x7466, 0xAC90,
+	0x7467, 0xAC91, 0x7468, 0xAC92, 0x7469, 0xAC93, 0x746A, 0xAC94,
+	0x746B, 0xAC95, 0x746C, 0xAC96, 0x746D, 0xE8A9, 0x746E, 0xAC97,
+	0x746F, 0xAC98, 0x7470, 0xB9E5, 0x7471, 0xAC99, 0x7472, 0xAC9A,
+	0x7473, 0xAC9B, 0x7474, 0xAC9C, 0x7475, 0xAC9D, 0x7476, 0xD1FE,
+	0x7477, 0xE8A8, 0x7478, 0xAC9E, 0x7479, 0xAC9F, 0x747A, 0xACA0,
+	0x747B, 0xAD40, 0x747C, 0xAD41, 0x747D, 0xAD42, 0x747E, 0xE8AA,
+	0x747F, 0xAD43, 0x7480, 0xE8AD, 0x7481, 0xE8AE, 0x7482, 0xAD44,
+	0x7483, 0xC1A7, 0x7484, 0xAD45, 0x7485, 0xAD46, 0x7486, 0xAD47,
+	0x7487, 0xE8AF, 0x7488, 0xAD48, 0x7489, 0xAD49, 0x748A, 0xAD4A,
+	0x748B, 0xE8B0, 0x748C, 0xAD4B, 0x748D, 0xAD4C, 0x748E, 0xE8AC,
+	0x748F, 0xAD4D, 0x7490, 0xE8B4, 0x7491, 0xAD4E, 0x7492, 0xAD4F,
+	0x7493, 0xAD50, 0x7494, 0xAD51, 0x7495, 0xAD52, 0x7496, 0xAD53,
+	0x7497, 0xAD54, 0x7498, 0xAD55, 0x7499, 0xAD56, 0x749A, 0xAD57,
+	0x749B, 0xAD58, 0x749C, 0xE8AB, 0x749D, 0xAD59, 0x749E, 0xE8B1,
+	0x749F, 0xAD5A, 0x74A0, 0xAD5B, 0x74A1, 0xAD5C, 0x74A2, 0xAD5D,
+	0x74A3, 0xAD5E, 0x74A4, 0xAD5F, 0x74A5, 0xAD60, 0x74A6, 0xAD61,
+	0x74A7, 0xE8B5, 0x74A8, 0xE8B2, 0x74A9, 0xE8B3, 0x74AA, 0xAD62,
+	0x74AB, 0xAD63, 0x74AC, 0xAD64, 0x74AD, 0xAD65, 0x74AE, 0xAD66,
+	0x74AF, 0xAD67, 0x74B0, 0xAD68, 0x74B1, 0xAD69, 0x74B2, 0xAD6A,
+	0x74B3, 0xAD6B, 0x74B4, 0xAD6C, 0x74B5, 0xAD6D, 0x74B6, 0xAD6E,
+	0x74B7, 0xAD6F, 0x74B8, 0xAD70, 0x74B9, 0xAD71, 0x74BA, 0xE8B7,
+	0x74BB, 0xAD72, 0x74BC, 0xAD73, 0x74BD, 0xAD74, 0x74BE, 0xAD75,
+	0x74BF, 0xAD76, 0x74C0, 0xAD77, 0x74C1, 0xAD78, 0x74C2, 0xAD79,
+	0x74C3, 0xAD7A, 0x74C4, 0xAD7B, 0x74C5, 0xAD7C, 0x74C6, 0xAD7D,
+	0x74C7, 0xAD7E, 0x74C8, 0xAD80, 0x74C9, 0xAD81, 0x74CA, 0xAD82,
+	0x74CB, 0xAD83, 0x74CC, 0xAD84, 0x74CD, 0xAD85, 0x74CE, 0xAD86,
+	0x74CF, 0xAD87, 0x74D0, 0xAD88, 0x74D1, 0xAD89, 0x74D2, 0xE8B6,
+	0x74D3, 0xAD8A, 0x74D4, 0xAD8B, 0x74D5, 0xAD8C, 0x74D6, 0xAD8D,
+	0x74D7, 0xAD8E, 0x74D8, 0xAD8F, 0x74D9, 0xAD90, 0x74DA, 0xAD91,
+	0x74DB, 0xAD92, 0x74DC, 0xB9CF, 0x74DD, 0xAD93, 0x74DE, 0xF0AC,
+	0x74DF, 0xAD94, 0x74E0, 0xF0AD, 0x74E1, 0xAD95, 0x74E2, 0xC6B0,
+	0x74E3, 0xB0EA, 0x74E4, 0xC8BF, 0x74E5, 0xAD96, 0x74E6, 0xCDDF,
+	0x74E7, 0xAD97, 0x74E8, 0xAD98, 0x74E9, 0xAD99, 0x74EA, 0xAD9A,
+	0x74EB, 0xAD9B, 0x74EC, 0xAD9C, 0x74ED, 0xAD9D, 0x74EE, 0xCECD,
+	0x74EF, 0xEAB1, 0x74F0, 0xAD9E, 0x74F1, 0xAD9F, 0x74F2, 0xADA0,
+	0x74F3, 0xAE40, 0x74F4, 0xEAB2, 0x74F5, 0xAE41, 0x74F6, 0xC6BF,
+	0x74F7, 0xB4C9, 0x74F8, 0xAE42, 0x74F9, 0xAE43, 0x74FA, 0xAE44,
+	0x74FB, 0xAE45, 0x74FC, 0xAE46, 0x74FD, 0xAE47, 0x74FE, 0xAE48,
+	0x74FF, 0xEAB3, 0x7500, 0xAE49, 0x7501, 0xAE4A, 0x7502, 0xAE4B,
+	0x7503, 0xAE4C, 0x7504, 0xD5E7, 0x7505, 0xAE4D, 0x7506, 0xAE4E,
+	0x7507, 0xAE4F, 0x7508, 0xAE50, 0x7509, 0xAE51, 0x750A, 0xAE52,
+	0x750B, 0xAE53, 0x750C, 0xAE54, 0x750D, 0xDDF9, 0x750E, 0xAE55,
+	0x750F, 0xEAB4, 0x7510, 0xAE56, 0x7511, 0xEAB5, 0x7512, 0xAE57,
+	0x7513, 0xEAB6, 0x7514, 0xAE58, 0x7515, 0xAE59, 0x7516, 0xAE5A,
+	0x7517, 0xAE5B, 0x7518, 0xB8CA, 0x7519, 0xDFB0, 0x751A, 0xC9F5,
+	0x751B, 0xAE5C, 0x751C, 0xCCF0, 0x751D, 0xAE5D, 0x751E, 0xAE5E,
+	0x751F, 0xC9FA, 0x7520, 0xAE5F, 0x7521, 0xAE60, 0x7522, 0xAE61,
+	0x7523, 0xAE62, 0x7524, 0xAE63, 0x7525, 0xC9FB, 0x7526, 0xAE64,
+	0x7527, 0xAE65, 0x7528, 0xD3C3, 0x7529, 0xCBA6, 0x752A, 0xAE66,
+	0x752B, 0xB8A6, 0x752C, 0xF0AE, 0x752D, 0xB1C2, 0x752E, 0xAE67,
+	0x752F, 0xE5B8, 0x7530, 0xCCEF, 0x7531, 0xD3C9, 0x7532, 0xBCD7,
+	0x7533, 0xC9EA, 0x7534, 0xAE68, 0x7535, 0xB5E7, 0x7536, 0xAE69,
+	0x7537, 0xC4D0, 0x7538, 0xB5E9, 0x7539, 0xAE6A, 0x753A, 0xEEAE,
+	0x753B, 0xBBAD, 0x753C, 0xAE6B, 0x753D, 0xAE6C, 0x753E, 0xE7DE,
+	0x753F, 0xAE6D, 0x7540, 0xEEAF, 0x7541, 0xAE6E, 0x7542, 0xAE6F,
+	0x7543, 0xAE70, 0x7544, 0xAE71, 0x7545, 0xB3A9, 0x7546, 0xAE72,
+	0x7547, 0xAE73, 0x7548, 0xEEB2, 0x7549, 0xAE74, 0x754A, 0xAE75,
+	0x754B, 0xEEB1, 0x754C, 0xBDE7, 0x754D, 0xAE76, 0x754E, 0xEEB0,
+	0x754F, 0xCEB7, 0x7550, 0xAE77, 0x7551, 0xAE78, 0x7552, 0xAE79,
+	0x7553, 0xAE7A, 0x7554, 0xC5CF, 0x7555, 0xAE7B, 0x7556, 0xAE7C,
+	0x7557, 0xAE7D, 0x7558, 0xAE7E, 0x7559, 0xC1F4, 0x755A, 0xDBCE,
+	0x755B, 0xEEB3, 0x755C, 0xD0F3, 0x755D, 0xAE80, 0x755E, 0xAE81,
+	0x755F, 0xAE82, 0x7560, 0xAE83, 0x7561, 0xAE84, 0x7562, 0xAE85,
+	0x7563, 0xAE86, 0x7564, 0xAE87, 0x7565, 0xC2D4, 0x7566, 0xC6E8,
+	0x7567, 0xAE88, 0x7568, 0xAE89, 0x7569, 0xAE8A, 0x756A, 0xB7AC,
+	0x756B, 0xAE8B, 0x756C, 0xAE8C, 0x756D, 0xAE8D, 0x756E, 0xAE8E,
+	0x756F, 0xAE8F, 0x7570, 0xAE90, 0x7571, 0xAE91, 0x7572, 0xEEB4,
+	0x7573, 0xAE92, 0x7574, 0xB3EB, 0x7575, 0xAE93, 0x7576, 0xAE94,
+	0x7577, 0xAE95, 0x7578, 0xBBFB, 0x7579, 0xEEB5, 0x757A, 0xAE96,
+	0x757B, 0xAE97, 0x757C, 0xAE98, 0x757D, 0xAE99, 0x757E, 0xAE9A,
+	0x757F, 0xE7DC, 0x7580, 0xAE9B, 0x7581, 0xAE9C, 0x7582, 0xAE9D,
+	0x7583, 0xEEB6, 0x7584, 0xAE9E, 0x7585, 0xAE9F, 0x7586, 0xBDAE,
+	0x7587, 0xAEA0, 0x7588, 0xAF40, 0x7589, 0xAF41, 0x758A, 0xAF42,
+	0x758B, 0xF1E2, 0x758C, 0xAF43, 0x758D, 0xAF44, 0x758E, 0xAF45,
+	0x758F, 0xCAE8, 0x7590, 0xAF46, 0x7591, 0xD2C9, 0x7592, 0xF0DA,
+	0x7593, 0xAF47, 0x7594, 0xF0DB, 0x7595, 0xAF48, 0x7596, 0xF0DC,
+	0x7597, 0xC1C6, 0x7598, 0xAF49, 0x7599, 0xB8ED, 0x759A, 0xBECE,
+	0x759B, 0xAF4A, 0x759C, 0xAF4B, 0x759D, 0xF0DE, 0x759E, 0xAF4C,
+	0x759F, 0xC5B1, 0x75A0, 0xF0DD, 0x75A1, 0xD1F1, 0x75A2, 0xAF4D,
+	0x75A3, 0xF0E0, 0x75A4, 0xB0CC, 0x75A5, 0xBDEA, 0x75A6, 0xAF4E,
+	0x75A7, 0xAF4F, 0x75A8, 0xAF50, 0x75A9, 0xAF51, 0x75AA, 0xAF52,
+	0x75AB, 0xD2DF, 0x75AC, 0xF0DF, 0x75AD, 0xAF53, 0x75AE, 0xB4AF,
+	0x75AF, 0xB7E8, 0x75B0, 0xF0E6, 0x75B1, 0xF0E5, 0x75B2, 0xC6A3,
+	0x75B3, 0xF0E1, 0x75B4, 0xF0E2, 0x75B5, 0xB4C3, 0x75B6, 0xAF54,
+	0x75B7, 0xAF55, 0x75B8, 0xF0E3, 0x75B9, 0xD5EE, 0x75BA, 0xAF56,
+	0x75BB, 0xAF57, 0x75BC, 0xCCDB, 0x75BD, 0xBED2, 0x75BE, 0xBCB2,
+	0x75BF, 0xAF58, 0x75C0, 0xAF59, 0x75C1, 0xAF5A, 0x75C2, 0xF0E8,
+	0x75C3, 0xF0E7, 0x75C4, 0xF0E4, 0x75C5, 0xB2A1, 0x75C6, 0xAF5B,
+	0x75C7, 0xD6A2, 0x75C8, 0xD3B8, 0x75C9, 0xBEB7, 0x75CA, 0xC8AC,
+	0x75CB, 0xAF5C, 0x75CC, 0xAF5D, 0x75CD, 0xF0EA, 0x75CE, 0xAF5E,
+	0x75CF, 0xAF5F, 0x75D0, 0xAF60, 0x75D1, 0xAF61, 0x75D2, 0xD1F7,
+	0x75D3, 0xAF62, 0x75D4, 0xD6CC, 0x75D5, 0xBADB, 0x75D6, 0xF0E9,
+	0x75D7, 0xAF63, 0x75D8, 0xB6BB, 0x75D9, 0xAF64, 0x75DA, 0xAF65,
+	0x75DB, 0xCDB4, 0x75DC, 0xAF66, 0x75DD, 0xAF67, 0x75DE, 0xC6A6,
+	0x75DF, 0xAF68, 0x75E0, 0xAF69, 0x75E1, 0xAF6A, 0x75E2, 0xC1A1,
+	0x75E3, 0xF0EB, 0x75E4, 0xF0EE, 0x75E5, 0xAF6B, 0x75E6, 0xF0ED,
+	0x75E7, 0xF0F0, 0x75E8, 0xF0EC, 0x75E9, 0xAF6C, 0x75EA, 0xBBBE,
+	0x75EB, 0xF0EF, 0x75EC, 0xAF6D, 0x75ED, 0xAF6E, 0x75EE, 0xAF6F,
+	0x75EF, 0xAF70, 0x75F0, 0xCCB5, 0x75F1, 0xF0F2, 0x75F2, 0xAF71,
+	0x75F3, 0xAF72, 0x75F4, 0xB3D5, 0x75F5, 0xAF73, 0x75F6, 0xAF74,
+	0x75F7, 0xAF75, 0x75F8, 0xAF76, 0x75F9, 0xB1D4, 0x75FA, 0xAF77,
+	0x75FB, 0xAF78, 0x75FC, 0xF0F3, 0x75FD, 0xAF79, 0x75FE, 0xAF7A,
+	0x75FF, 0xF0F4, 0x7600, 0xF0F6, 0x7601, 0xB4E1, 0x7602, 0xAF7B,
+	0x7603, 0xF0F1, 0x7604, 0xAF7C, 0x7605, 0xF0F7, 0x7606, 0xAF7D,
+	0x7607, 0xAF7E, 0x7608, 0xAF80, 0x7609, 0xAF81, 0x760A, 0xF0FA,
+	0x760B, 0xAF82, 0x760C, 0xF0F8, 0x760D, 0xAF83, 0x760E, 0xAF84,
+	0x760F, 0xAF85, 0x7610, 0xF0F5, 0x7611, 0xAF86, 0x7612, 0xAF87,
+	0x7613, 0xAF88, 0x7614, 0xAF89, 0x7615, 0xF0FD, 0x7616, 0xAF8A,
+	0x7617, 0xF0F9, 0x7618, 0xF0FC, 0x7619, 0xF0FE, 0x761A, 0xAF8B,
+	0x761B, 0xF1A1, 0x761C, 0xAF8C, 0x761D, 0xAF8D, 0x761E, 0xAF8E,
+	0x761F, 0xCEC1, 0x7620, 0xF1A4, 0x7621, 0xAF8F, 0x7622, 0xF1A3,
+	0x7623, 0xAF90, 0x7624, 0xC1F6, 0x7625, 0xF0FB, 0x7626, 0xCADD,
+	0x7627, 0xAF91, 0x7628, 0xAF92, 0x7629, 0xB4F1, 0x762A, 0xB1F1,
+	0x762B, 0xCCB1, 0x762C, 0xAF93, 0x762D, 0xF1A6, 0x762E, 0xAF94,
+	0x762F, 0xAF95, 0x7630, 0xF1A7, 0x7631, 0xAF96, 0x7632, 0xAF97,
+	0x7633, 0xF1AC, 0x7634, 0xD5CE, 0x7635, 0xF1A9, 0x7636, 0xAF98,
+	0x7637, 0xAF99, 0x7638, 0xC8B3, 0x7639, 0xAF9A, 0x763A, 0xAF9B,
+	0x763B, 0xAF9C, 0x763C, 0xF1A2, 0x763D, 0xAF9D, 0x763E, 0xF1AB,
+	0x763F, 0xF1A8, 0x7640, 0xF1A5, 0x7641, 0xAF9E, 0x7642, 0xAF9F,
+	0x7643, 0xF1AA, 0x7644, 0xAFA0, 0x7645, 0xB040, 0x7646, 0xB041,
+	0x7647, 0xB042, 0x7648, 0xB043, 0x7649, 0xB044, 0x764A, 0xB045,
+	0x764B, 0xB046, 0x764C, 0xB0A9, 0x764D, 0xF1AD, 0x764E, 0xB047,
+	0x764F, 0xB048, 0x7650, 0xB049, 0x7651, 0xB04A, 0x7652, 0xB04B,
+	0x7653, 0xB04C, 0x7654, 0xF1AF, 0x7655, 0xB04D, 0x7656, 0xF1B1,
+	0x7657, 0xB04E, 0x7658, 0xB04F, 0x7659, 0xB050, 0x765A, 0xB051,
+	0x765B, 0xB052, 0x765C, 0xF1B0, 0x765D, 0xB053, 0x765E, 0xF1AE,
+	0x765F, 0xB054, 0x7660, 0xB055, 0x7661, 0xB056, 0x7662, 0xB057,
+	0x7663, 0xD1A2, 0x7664, 0xB058, 0x7665, 0xB059, 0x7666, 0xB05A,
+	0x7667, 0xB05B, 0x7668, 0xB05C, 0x7669, 0xB05D, 0x766A, 0xB05E,
+	0x766B, 0xF1B2, 0x766C, 0xB05F, 0x766D, 0xB060, 0x766E, 0xB061,
+	0x766F, 0xF1B3, 0x7670, 0xB062, 0x7671, 0xB063, 0x7672, 0xB064,
+	0x7673, 0xB065, 0x7674, 0xB066, 0x7675, 0xB067, 0x7676, 0xB068,
+	0x7677, 0xB069, 0x7678, 0xB9EF, 0x7679, 0xB06A, 0x767A, 0xB06B,
+	0x767B, 0xB5C7, 0x767C, 0xB06C, 0x767D, 0xB0D7, 0x767E, 0xB0D9,
+	0x767F, 0xB06D, 0x7680, 0xB06E, 0x7681, 0xB06F, 0x7682, 0xD4ED,
+	0x7683, 0xB070, 0x7684, 0xB5C4, 0x7685, 0xB071, 0x7686, 0xBDD4,
+	0x7687, 0xBBCA, 0x7688, 0xF0A7, 0x7689, 0xB072, 0x768A, 0xB073,
+	0x768B, 0xB8DE, 0x768C, 0xB074, 0x768D, 0xB075, 0x768E, 0xF0A8,
+	0x768F, 0xB076, 0x7690, 0xB077, 0x7691, 0xB0A8, 0x7692, 0xB078,
+	0x7693, 0xF0A9, 0x7694, 0xB079, 0x7695, 0xB07A, 0x7696, 0xCDEE,
+	0x7697, 0xB07B, 0x7698, 0xB07C, 0x7699, 0xF0AA, 0x769A, 0xB07D,
+	0x769B, 0xB07E, 0x769C, 0xB080, 0x769D, 0xB081, 0x769E, 0xB082,
+	0x769F, 0xB083, 0x76A0, 0xB084, 0x76A1, 0xB085, 0x76A2, 0xB086,
+	0x76A3, 0xB087, 0x76A4, 0xF0AB, 0x76A5, 0xB088, 0x76A6, 0xB089,
+	0x76A7, 0xB08A, 0x76A8, 0xB08B, 0x76A9, 0xB08C, 0x76AA, 0xB08D,
+	0x76AB, 0xB08E, 0x76AC, 0xB08F, 0x76AD, 0xB090, 0x76AE, 0xC6A4,
+	0x76AF, 0xB091, 0x76B0, 0xB092, 0x76B1, 0xD6E5, 0x76B2, 0xF1E4,
+	0x76B3, 0xB093, 0x76B4, 0xF1E5, 0x76B5, 0xB094, 0x76B6, 0xB095,
+	0x76B7, 0xB096, 0x76B8, 0xB097, 0x76B9, 0xB098, 0x76BA, 0xB099,
+	0x76BB, 0xB09A, 0x76BC, 0xB09B, 0x76BD, 0xB09C, 0x76BE, 0xB09D,
+	0x76BF, 0xC3F3, 0x76C0, 0xB09E, 0x76C1, 0xB09F, 0x76C2, 0xD3DB,
+	0x76C3, 0xB0A0, 0x76C4, 0xB140, 0x76C5, 0xD6D1, 0x76C6, 0xC5E8,
+	0x76C7, 0xB141, 0x76C8, 0xD3AF, 0x76C9, 0xB142, 0x76CA, 0xD2E6,
+	0x76CB, 0xB143, 0x76CC, 0xB144, 0x76CD, 0xEEC1, 0x76CE, 0xB0BB,
+	0x76CF, 0xD5B5, 0x76D0, 0xD1CE, 0x76D1, 0xBCE0, 0x76D2, 0xBAD0,
+	0x76D3, 0xB145, 0x76D4, 0xBFF8, 0x76D5, 0xB146, 0x76D6, 0xB8C7,
+	0x76D7, 0xB5C1, 0x76D8, 0xC5CC, 0x76D9, 0xB147, 0x76DA, 0xB148,
+	0x76DB, 0xCAA2, 0x76DC, 0xB149, 0x76DD, 0xB14A, 0x76DE, 0xB14B,
+	0x76DF, 0xC3CB, 0x76E0, 0xB14C, 0x76E1, 0xB14D, 0x76E2, 0xB14E,
+	0x76E3, 0xB14F, 0x76E4, 0xB150, 0x76E5, 0xEEC2, 0x76E6, 0xB151,
+	0x76E7, 0xB152, 0x76E8, 0xB153, 0x76E9, 0xB154, 0x76EA, 0xB155,
+	0x76EB, 0xB156, 0x76EC, 0xB157, 0x76ED, 0xB158, 0x76EE, 0xC4BF,
+	0x76EF, 0xB6A2, 0x76F0, 0xB159, 0x76F1, 0xEDEC, 0x76F2, 0xC3A4,
+	0x76F3, 0xB15A, 0x76F4, 0xD6B1, 0x76F5, 0xB15B, 0x76F6, 0xB15C,
+	0x76F7, 0xB15D, 0x76F8, 0xCFE0, 0x76F9, 0xEDEF, 0x76FA, 0xB15E,
+	0x76FB, 0xB15F, 0x76FC, 0xC5CE, 0x76FD, 0xB160, 0x76FE, 0xB6DC,
+	0x76FF, 0xB161, 0x7700, 0xB162, 0x7701, 0xCAA1, 0x7702, 0xB163,
+	0x7703, 0xB164, 0x7704, 0xEDED, 0x7705, 0xB165, 0x7706, 0xB166,
+	0x7707, 0xEDF0, 0x7708, 0xEDF1, 0x7709, 0xC3BC, 0x770A, 0xB167,
+	0x770B, 0xBFB4, 0x770C, 0xB168, 0x770D, 0xEDEE, 0x770E, 0xB169,
+	0x770F, 0xB16A, 0x7710, 0xB16B, 0x7711, 0xB16C, 0x7712, 0xB16D,
+	0x7713, 0xB16E, 0x7714, 0xB16F, 0x7715, 0xB170, 0x7716, 0xB171,
+	0x7717, 0xB172, 0x7718, 0xB173, 0x7719, 0xEDF4, 0x771A, 0xEDF2,
+	0x771B, 0xB174, 0x771C, 0xB175, 0x771D, 0xB176, 0x771E, 0xB177,
+	0x771F, 0xD5E6, 0x7720, 0xC3DF, 0x7721, 0xB178, 0x7722, 0xEDF3,
+	0x7723, 0xB179, 0x7724, 0xB17A, 0x7725, 0xB17B, 0x7726, 0xEDF6,
+	0x7727, 0xB17C, 0x7728, 0xD5A3, 0x7729, 0xD1A3, 0x772A, 0xB17D,
+	0x772B, 0xB17E, 0x772C, 0xB180, 0x772D, 0xEDF5, 0x772E, 0xB181,
+	0x772F, 0xC3D0, 0x7730, 0xB182, 0x7731, 0xB183, 0x7732, 0xB184,
+	0x7733, 0xB185, 0x7734, 0xB186, 0x7735, 0xEDF7, 0x7736, 0xBFF4,
+	0x7737, 0xBEEC, 0x7738, 0xEDF8, 0x7739, 0xB187, 0x773A, 0xCCF7,
+	0x773B, 0xB188, 0x773C, 0xD1DB, 0x773D, 0xB189, 0x773E, 0xB18A,
+	0x773F, 0xB18B, 0x7740, 0xD7C5, 0x7741, 0xD5F6, 0x7742, 0xB18C,
+	0x7743, 0xEDFC, 0x7744, 0xB18D, 0x7745, 0xB18E, 0x7746, 0xB18F,
+	0x7747, 0xEDFB, 0x7748, 0xB190, 0x7749, 0xB191, 0x774A, 0xB192,
+	0x774B, 0xB193, 0x774C, 0xB194, 0x774D, 0xB195, 0x774E, 0xB196,
+	0x774F, 0xB197, 0x7750, 0xEDF9, 0x7751, 0xEDFA, 0x7752, 0xB198,
+	0x7753, 0xB199, 0x7754, 0xB19A, 0x7755, 0xB19B, 0x7756, 0xB19C,
+	0x7757, 0xB19D, 0x7758, 0xB19E, 0x7759, 0xB19F, 0x775A, 0xEDFD,
+	0x775B, 0xBEA6, 0x775C, 0xB1A0, 0x775D, 0xB240, 0x775E, 0xB241,
+	0x775F, 0xB242, 0x7760, 0xB243, 0x7761, 0xCBAF, 0x7762, 0xEEA1,
+	0x7763, 0xB6BD, 0x7764, 0xB244, 0x7765, 0xEEA2, 0x7766, 0xC4C0,
+	0x7767, 0xB245, 0x7768, 0xEDFE, 0x7769, 0xB246, 0x776A, 0xB247,
+	0x776B, 0xBDDE, 0x776C, 0xB2C7, 0x776D, 0xB248, 0x776E, 0xB249,
+	0x776F, 0xB24A, 0x7770, 0xB24B, 0x7771, 0xB24C, 0x7772, 0xB24D,
+	0x7773, 0xB24E, 0x7774, 0xB24F, 0x7775, 0xB250, 0x7776, 0xB251,
+	0x7777, 0xB252, 0x7778, 0xB253, 0x7779, 0xB6C3, 0x777A, 0xB254,
+	0x777B, 0xB255, 0x777C, 0xB256, 0x777D, 0xEEA5, 0x777E, 0xD8BA,
+	0x777F, 0xEEA3, 0x7780, 0xEEA6, 0x7781, 0xB257, 0x7782, 0xB258,
+	0x7783, 0xB259, 0x7784, 0xC3E9, 0x7785, 0xB3F2, 0x7786, 0xB25A,
+	0x7787, 0xB25B, 0x7788, 0xB25C, 0x7789, 0xB25D, 0x778A, 0xB25E,
+	0x778B, 0xB25F, 0x778C, 0xEEA7, 0x778D, 0xEEA4, 0x778E, 0xCFB9,
+	0x778F, 0xB260, 0x7790, 0xB261, 0x7791, 0xEEA8, 0x7792, 0xC2F7,
+	0x7793, 0xB262, 0x7794, 0xB263, 0x7795, 0xB264, 0x7796, 0xB265,
+	0x7797, 0xB266, 0x7798, 0xB267, 0x7799, 0xB268, 0x779A, 0xB269,
+	0x779B, 0xB26A, 0x779C, 0xB26B, 0x779D, 0xB26C, 0x779E, 0xB26D,
+	0x779F, 0xEEA9, 0x77A0, 0xEEAA, 0x77A1, 0xB26E, 0x77A2, 0xDEAB,
+	0x77A3, 0xB26F, 0x77A4, 0xB270, 0x77A5, 0xC6B3, 0x77A6, 0xB271,
+	0x77A7, 0xC7C6, 0x77A8, 0xB272, 0x77A9, 0xD6F5, 0x77AA, 0xB5C9,
+	0x77AB, 0xB273, 0x77AC, 0xCBB2, 0x77AD, 0xB274, 0x77AE, 0xB275,
+	0x77AF, 0xB276, 0x77B0, 0xEEAB, 0x77B1, 0xB277, 0x77B2, 0xB278,
+	0x77B3, 0xCDAB, 0x77B4, 0xB279, 0x77B5, 0xEEAC, 0x77B6, 0xB27A,
+	0x77B7, 0xB27B, 0x77B8, 0xB27C, 0x77B9, 0xB27D, 0x77BA, 0xB27E,
+	0x77BB, 0xD5B0, 0x77BC, 0xB280, 0x77BD, 0xEEAD, 0x77BE, 0xB281,
+	0x77BF, 0xF6C4, 0x77C0, 0xB282, 0x77C1, 0xB283, 0x77C2, 0xB284,
+	0x77C3, 0xB285, 0x77C4, 0xB286, 0x77C5, 0xB287, 0x77C6, 0xB288,
+	0x77C7, 0xB289, 0x77C8, 0xB28A, 0x77C9, 0xB28B, 0x77CA, 0xB28C,
+	0x77CB, 0xB28D, 0x77CC, 0xB28E, 0x77CD, 0xDBC7, 0x77CE, 0xB28F,
+	0x77CF, 0xB290, 0x77D0, 0xB291, 0x77D1, 0xB292, 0x77D2, 0xB293,
+	0x77D3, 0xB294, 0x77D4, 0xB295, 0x77D5, 0xB296, 0x77D6, 0xB297,
+	0x77D7, 0xB4A3, 0x77D8, 0xB298, 0x77D9, 0xB299, 0x77DA, 0xB29A,
+	0x77DB, 0xC3AC, 0x77DC, 0xF1E6, 0x77DD, 0xB29B, 0x77DE, 0xB29C,
+	0x77DF, 0xB29D, 0x77E0, 0xB29E, 0x77E1, 0xB29F, 0x77E2, 0xCAB8,
+	0x77E3, 0xD2D3, 0x77E4, 0xB2A0, 0x77E5, 0xD6AA, 0x77E6, 0xB340,
+	0x77E7, 0xEFF2, 0x77E8, 0xB341, 0x77E9, 0xBED8, 0x77EA, 0xB342,
+	0x77EB, 0xBDC3, 0x77EC, 0xEFF3, 0x77ED, 0xB6CC, 0x77EE, 0xB0AB,
+	0x77EF, 0xB343, 0x77F0, 0xB344, 0x77F1, 0xB345, 0x77F2, 0xB346,
+	0x77F3, 0xCAAF, 0x77F4, 0xB347, 0x77F5, 0xB348, 0x77F6, 0xEDB6,
+	0x77F7, 0xB349, 0x77F8, 0xEDB7, 0x77F9, 0xB34A, 0x77FA, 0xB34B,
+	0x77FB, 0xB34C, 0x77FC, 0xB34D, 0x77FD, 0xCEF9, 0x77FE, 0xB7AF,
+	0x77FF, 0xBFF3, 0x7800, 0xEDB8, 0x7801, 0xC2EB, 0x7802, 0xC9B0,
+	0x7803, 0xB34E, 0x7804, 0xB34F, 0x7805, 0xB350, 0x7806, 0xB351,
+	0x7807, 0xB352, 0x7808, 0xB353, 0x7809, 0xEDB9, 0x780A, 0xB354,
+	0x780B, 0xB355, 0x780C, 0xC6F6, 0x780D, 0xBFB3, 0x780E, 0xB356,
+	0x780F, 0xB357, 0x7810, 0xB358, 0x7811, 0xEDBC, 0x7812, 0xC5F8,
+	0x7813, 0xB359, 0x7814, 0xD1D0, 0x7815, 0xB35A, 0x7816, 0xD7A9,
+	0x7817, 0xEDBA, 0x7818, 0xEDBB, 0x7819, 0xB35B, 0x781A, 0xD1E2,
+	0x781B, 0xB35C, 0x781C, 0xEDBF, 0x781D, 0xEDC0, 0x781E, 0xB35D,
+	0x781F, 0xEDC4, 0x7820, 0xB35E, 0x7821, 0xB35F, 0x7822, 0xB360,
+	0x7823, 0xEDC8, 0x7824, 0xB361, 0x7825, 0xEDC6, 0x7826, 0xEDCE,
+	0x7827, 0xD5E8, 0x7828, 0xB362, 0x7829, 0xEDC9, 0x782A, 0xB363,
+	0x782B, 0xB364, 0x782C, 0xEDC7, 0x782D, 0xEDBE, 0x782E, 0xB365,
+	0x782F, 0xB366, 0x7830, 0xC5E9, 0x7831, 0xB367, 0x7832, 0xB368,
+	0x7833, 0xB369, 0x7834, 0xC6C6, 0x7835, 0xB36A, 0x7836, 0xB36B,
+	0x7837, 0xC9E9, 0x7838, 0xD4D2, 0x7839, 0xEDC1, 0x783A, 0xEDC2,
+	0x783B, 0xEDC3, 0x783C, 0xEDC5, 0x783D, 0xB36C, 0x783E, 0xC0F9,
+	0x783F, 0xB36D, 0x7840, 0xB4A1, 0x7841, 0xB36E, 0x7842, 0xB36F,
+	0x7843, 0xB370, 0x7844, 0xB371, 0x7845, 0xB9E8, 0x7846, 0xB372,
+	0x7847, 0xEDD0, 0x7848, 0xB373, 0x7849, 0xB374, 0x784A, 0xB375,
+	0x784B, 0xB376, 0x784C, 0xEDD1, 0x784D, 0xB377, 0x784E, 0xEDCA,
+	0x784F, 0xB378, 0x7850, 0xEDCF, 0x7851, 0xB379, 0x7852, 0xCEF8,
+	0x7853, 0xB37A, 0x7854, 0xB37B, 0x7855, 0xCBB6, 0x7856, 0xEDCC,
+	0x7857, 0xEDCD, 0x7858, 0xB37C, 0x7859, 0xB37D, 0x785A, 0xB37E,
+	0x785B, 0xB380, 0x785C, 0xB381, 0x785D, 0xCFF5, 0x785E, 0xB382,
+	0x785F, 0xB383, 0x7860, 0xB384, 0x7861, 0xB385, 0x7862, 0xB386,
+	0x7863, 0xB387, 0x7864, 0xB388, 0x7865, 0xB389, 0x7866, 0xB38A,
+	0x7867, 0xB38B, 0x7868, 0xB38C, 0x7869, 0xB38D, 0x786A, 0xEDD2,
+	0x786B, 0xC1F2, 0x786C, 0xD3B2, 0x786D, 0xEDCB, 0x786E, 0xC8B7,
+	0x786F, 0xB38E, 0x7870, 0xB38F, 0x7871, 0xB390, 0x7872, 0xB391,
+	0x7873, 0xB392, 0x7874, 0xB393, 0x7875, 0xB394, 0x7876, 0xB395,
+	0x7877, 0xBCEF, 0x7878, 0xB396, 0x7879, 0xB397, 0x787A, 0xB398,
+	0x787B, 0xB399, 0x787C, 0xC5F0, 0x787D, 0xB39A, 0x787E, 0xB39B,
+	0x787F, 0xB39C, 0x7880, 0xB39D, 0x7881, 0xB39E, 0x7882, 0xB39F,
+	0x7883, 0xB3A0, 0x7884, 0xB440, 0x7885, 0xB441, 0x7886, 0xB442,
+	0x7887, 0xEDD6, 0x7888, 0xB443, 0x7889, 0xB5EF, 0x788A, 0xB444,
+	0x788B, 0xB445, 0x788C, 0xC2B5, 0x788D, 0xB0AD, 0x788E, 0xCBE9,
+	0x788F, 0xB446, 0x7890, 0xB447, 0x7891, 0xB1AE, 0x7892, 0xB448,
+	0x7893, 0xEDD4, 0x7894, 0xB449, 0x7895, 0xB44A, 0x7896, 0xB44B,
+	0x7897, 0xCDEB, 0x7898, 0xB5E2, 0x7899, 0xB44C, 0x789A, 0xEDD5,
+	0x789B, 0xEDD3, 0x789C, 0xEDD7, 0x789D, 0xB44D, 0x789E, 0xB44E,
+	0x789F, 0xB5FA, 0x78A0, 0xB44F, 0x78A1, 0xEDD8, 0x78A2, 0xB450,
+	0x78A3, 0xEDD9, 0x78A4, 0xB451, 0x78A5, 0xEDDC, 0x78A6, 0xB452,
+	0x78A7, 0xB1CC, 0x78A8, 0xB453, 0x78A9, 0xB454, 0x78AA, 0xB455,
+	0x78AB, 0xB456, 0x78AC, 0xB457, 0x78AD, 0xB458, 0x78AE, 0xB459,
+	0x78AF, 0xB45A, 0x78B0, 0xC5F6, 0x78B1, 0xBCEE, 0x78B2, 0xEDDA,
+	0x78B3, 0xCCBC, 0x78B4, 0xB2EA, 0x78B5, 0xB45B, 0x78B6, 0xB45C,
+	0x78B7, 0xB45D, 0x78B8, 0xB45E, 0x78B9, 0xEDDB, 0x78BA, 0xB45F,
+	0x78BB, 0xB460, 0x78BC, 0xB461, 0x78BD, 0xB462, 0x78BE, 0xC4EB,
+	0x78BF, 0xB463, 0x78C0, 0xB464, 0x78C1, 0xB4C5, 0x78C2, 0xB465,
+	0x78C3, 0xB466, 0x78C4, 0xB467, 0x78C5, 0xB0F5, 0x78C6, 0xB468,
+	0x78C7, 0xB469, 0x78C8, 0xB46A, 0x78C9, 0xEDDF, 0x78CA, 0xC0DA,
+	0x78CB, 0xB4E8, 0x78CC, 0xB46B, 0x78CD, 0xB46C, 0x78CE, 0xB46D,
+	0x78CF, 0xB46E, 0x78D0, 0xC5CD, 0x78D1, 0xB46F, 0x78D2, 0xB470,
+	0x78D3, 0xB471, 0x78D4, 0xEDDD, 0x78D5, 0xBFC4, 0x78D6, 0xB472,
+	0x78D7, 0xB473, 0x78D8, 0xB474, 0x78D9, 0xEDDE, 0x78DA, 0xB475,
+	0x78DB, 0xB476, 0x78DC, 0xB477, 0x78DD, 0xB478, 0x78DE, 0xB479,
+	0x78DF, 0xB47A, 0x78E0, 0xB47B, 0x78E1, 0xB47C, 0x78E2, 0xB47D,
+	0x78E3, 0xB47E, 0x78E4, 0xB480, 0x78E5, 0xB481, 0x78E6, 0xB482,
+	0x78E7, 0xB483, 0x78E8, 0xC4A5, 0x78E9, 0xB484, 0x78EA, 0xB485,
+	0x78EB, 0xB486, 0x78EC, 0xEDE0, 0x78ED, 0xB487, 0x78EE, 0xB488,
+	0x78EF, 0xB489, 0x78F0, 0xB48A, 0x78F1, 0xB48B, 0x78F2, 0xEDE1,
+	0x78F3, 0xB48C, 0x78F4, 0xEDE3, 0x78F5, 0xB48D, 0x78F6, 0xB48E,
+	0x78F7, 0xC1D7, 0x78F8, 0xB48F, 0x78F9, 0xB490, 0x78FA, 0xBBC7,
+	0x78FB, 0xB491, 0x78FC, 0xB492, 0x78FD, 0xB493, 0x78FE, 0xB494,
+	0x78FF, 0xB495, 0x7900, 0xB496, 0x7901, 0xBDB8, 0x7902, 0xB497,
+	0x7903, 0xB498, 0x7904, 0xB499, 0x7905, 0xEDE2, 0x7906, 0xB49A,
+	0x7907, 0xB49B, 0x7908, 0xB49C, 0x7909, 0xB49D, 0x790A, 0xB49E,
+	0x790B, 0xB49F, 0x790C, 0xB4A0, 0x790D, 0xB540, 0x790E, 0xB541,
+	0x790F, 0xB542, 0x7910, 0xB543, 0x7911, 0xB544, 0x7912, 0xB545,
+	0x7913, 0xEDE4, 0x7914, 0xB546, 0x7915, 0xB547, 0x7916, 0xB548,
+	0x7917, 0xB549, 0x7918, 0xB54A, 0x7919, 0xB54B, 0x791A, 0xB54C,
+	0x791B, 0xB54D, 0x791C, 0xB54E, 0x791D, 0xB54F, 0x791E, 0xEDE6,
+	0x791F, 0xB550, 0x7920, 0xB551, 0x7921, 0xB552, 0x7922, 0xB553,
+	0x7923, 0xB554, 0x7924, 0xEDE5, 0x7925, 0xB555, 0x7926, 0xB556,
+	0x7927, 0xB557, 0x7928, 0xB558, 0x7929, 0xB559, 0x792A, 0xB55A,
+	0x792B, 0xB55B, 0x792C, 0xB55C, 0x792D, 0xB55D, 0x792E, 0xB55E,
+	0x792F, 0xB55F, 0x7930, 0xB560, 0x7931, 0xB561, 0x7932, 0xB562,
+	0x7933, 0xB563, 0x7934, 0xEDE7, 0x7935, 0xB564, 0x7936, 0xB565,
+	0x7937, 0xB566, 0x7938, 0xB567, 0x7939, 0xB568, 0x793A, 0xCABE,
+	0x793B, 0xECEA, 0x793C, 0xC0F1, 0x793D, 0xB569, 0x793E, 0xC9E7,
+	0x793F, 0xB56A, 0x7940, 0xECEB, 0x7941, 0xC6EE, 0x7942, 0xB56B,
+	0x7943, 0xB56C, 0x7944, 0xB56D, 0x7945, 0xB56E, 0x7946, 0xECEC,
+	0x7947, 0xB56F, 0x7948, 0xC6ED, 0x7949, 0xECED, 0x794A, 0xB570,
+	0x794B, 0xB571, 0x794C, 0xB572, 0x794D, 0xB573, 0x794E, 0xB574,
+	0x794F, 0xB575, 0x7950, 0xB576, 0x7951, 0xB577, 0x7952, 0xB578,
+	0x7953, 0xECF0, 0x7954, 0xB579, 0x7955, 0xB57A, 0x7956, 0xD7E6,
+	0x7957, 0xECF3, 0x7958, 0xB57B, 0x7959, 0xB57C, 0x795A, 0xECF1,
+	0x795B, 0xECEE, 0x795C, 0xECEF, 0x795D, 0xD7A3, 0x795E, 0xC9F1,
+	0x795F, 0xCBEE, 0x7960, 0xECF4, 0x7961, 0xB57D, 0x7962, 0xECF2,
+	0x7963, 0xB57E, 0x7964, 0xB580, 0x7965, 0xCFE9, 0x7966, 0xB581,
+	0x7967, 0xECF6, 0x7968, 0xC6B1, 0x7969, 0xB582, 0x796A, 0xB583,
+	0x796B, 0xB584, 0x796C, 0xB585, 0x796D, 0xBCC0, 0x796E, 0xB586,
+	0x796F, 0xECF5, 0x7970, 0xB587, 0x7971, 0xB588, 0x7972, 0xB589,
+	0x7973, 0xB58A, 0x7974, 0xB58B, 0x7975, 0xB58C, 0x7976, 0xB58D,
+	0x7977, 0xB5BB, 0x7978, 0xBBF6, 0x7979, 0xB58E, 0x797A, 0xECF7,
+	0x797B, 0xB58F, 0x797C, 0xB590, 0x797D, 0xB591, 0x797E, 0xB592,
+	0x797F, 0xB593, 0x7980, 0xD9F7, 0x7981, 0xBDFB, 0x7982, 0xB594,
+	0x7983, 0xB595, 0x7984, 0xC2BB, 0x7985, 0xECF8, 0x7986, 0xB596,
+	0x7987, 0xB597, 0x7988, 0xB598, 0x7989, 0xB599, 0x798A, 0xECF9,
+	0x798B, 0xB59A, 0x798C, 0xB59B, 0x798D, 0xB59C, 0x798E, 0xB59D,
+	0x798F, 0xB8A3, 0x7990, 0xB59E, 0x7991, 0xB59F, 0x7992, 0xB5A0,
+	0x7993, 0xB640, 0x7994, 0xB641, 0x7995, 0xB642, 0x7996, 0xB643,
+	0x7997, 0xB644, 0x7998, 0xB645, 0x7999, 0xB646, 0x799A, 0xECFA,
+	0x799B, 0xB647, 0x799C, 0xB648, 0x799D, 0xB649, 0x799E, 0xB64A,
+	0x799F, 0xB64B, 0x79A0, 0xB64C, 0x79A1, 0xB64D, 0x79A2, 0xB64E,
+	0x79A3, 0xB64F, 0x79A4, 0xB650, 0x79A5, 0xB651, 0x79A6, 0xB652,
+	0x79A7, 0xECFB, 0x79A8, 0xB653, 0x79A9, 0xB654, 0x79AA, 0xB655,
+	0x79AB, 0xB656, 0x79AC, 0xB657, 0x79AD, 0xB658, 0x79AE, 0xB659,
+	0x79AF, 0xB65A, 0x79B0, 0xB65B, 0x79B1, 0xB65C, 0x79B2, 0xB65D,
+	0x79B3, 0xECFC, 0x79B4, 0xB65E, 0x79B5, 0xB65F, 0x79B6, 0xB660,
+	0x79B7, 0xB661, 0x79B8, 0xB662, 0x79B9, 0xD3ED, 0x79BA, 0xD8AE,
+	0x79BB, 0xC0EB, 0x79BC, 0xB663, 0x79BD, 0xC7DD, 0x79BE, 0xBACC,
+	0x79BF, 0xB664, 0x79C0, 0xD0E3, 0x79C1, 0xCBBD, 0x79C2, 0xB665,
+	0x79C3, 0xCDBA, 0x79C4, 0xB666, 0x79C5, 0xB667, 0x79C6, 0xB8D1,
+	0x79C7, 0xB668, 0x79C8, 0xB669, 0x79C9, 0xB1FC, 0x79CA, 0xB66A,
+	0x79CB, 0xC7EF, 0x79CC, 0xB66B, 0x79CD, 0xD6D6, 0x79CE, 0xB66C,
+	0x79CF, 0xB66D, 0x79D0, 0xB66E, 0x79D1, 0xBFC6, 0x79D2, 0xC3EB,
+	0x79D3, 0xB66F, 0x79D4, 0xB670, 0x79D5, 0xEFF5, 0x79D6, 0xB671,
+	0x79D7, 0xB672, 0x79D8, 0xC3D8, 0x79D9, 0xB673, 0x79DA, 0xB674,
+	0x79DB, 0xB675, 0x79DC, 0xB676, 0x79DD, 0xB677, 0x79DE, 0xB678,
+	0x79DF, 0xD7E2, 0x79E0, 0xB679, 0x79E1, 0xB67A, 0x79E2, 0xB67B,
+	0x79E3, 0xEFF7, 0x79E4, 0xB3D3, 0x79E5, 0xB67C, 0x79E6, 0xC7D8,
+	0x79E7, 0xD1ED, 0x79E8, 0xB67D, 0x79E9, 0xD6C8, 0x79EA, 0xB67E,
+	0x79EB, 0xEFF8, 0x79EC, 0xB680, 0x79ED, 0xEFF6, 0x79EE, 0xB681,
+	0x79EF, 0xBBFD, 0x79F0, 0xB3C6, 0x79F1, 0xB682, 0x79F2, 0xB683,
+	0x79F3, 0xB684, 0x79F4, 0xB685, 0x79F5, 0xB686, 0x79F6, 0xB687,
+	0x79F7, 0xB688, 0x79F8, 0xBDD5, 0x79F9, 0xB689, 0x79FA, 0xB68A,
+	0x79FB, 0xD2C6, 0x79FC, 0xB68B, 0x79FD, 0xBBE0, 0x79FE, 0xB68C,
+	0x79FF, 0xB68D, 0x7A00, 0xCFA1, 0x7A01, 0xB68E, 0x7A02, 0xEFFC,
+	0x7A03, 0xEFFB, 0x7A04, 0xB68F, 0x7A05, 0xB690, 0x7A06, 0xEFF9,
+	0x7A07, 0xB691, 0x7A08, 0xB692, 0x7A09, 0xB693, 0x7A0A, 0xB694,
+	0x7A0B, 0xB3CC, 0x7A0C, 0xB695, 0x7A0D, 0xC9D4, 0x7A0E, 0xCBB0,
+	0x7A0F, 0xB696, 0x7A10, 0xB697, 0x7A11, 0xB698, 0x7A12, 0xB699,
+	0x7A13, 0xB69A, 0x7A14, 0xEFFE, 0x7A15, 0xB69B, 0x7A16, 0xB69C,
+	0x7A17, 0xB0DE, 0x7A18, 0xB69D, 0x7A19, 0xB69E, 0x7A1A, 0xD6C9,
+	0x7A1B, 0xB69F, 0x7A1C, 0xB6A0, 0x7A1D, 0xB740, 0x7A1E, 0xEFFD,
+	0x7A1F, 0xB741, 0x7A20, 0xB3ED, 0x7A21, 0xB742, 0x7A22, 0xB743,
+	0x7A23, 0xF6D5, 0x7A24, 0xB744, 0x7A25, 0xB745, 0x7A26, 0xB746,
+	0x7A27, 0xB747, 0x7A28, 0xB748, 0x7A29, 0xB749, 0x7A2A, 0xB74A,
+	0x7A2B, 0xB74B, 0x7A2C, 0xB74C, 0x7A2D, 0xB74D, 0x7A2E, 0xB74E,
+	0x7A2F, 0xB74F, 0x7A30, 0xB750, 0x7A31, 0xB751, 0x7A32, 0xB752,
+	0x7A33, 0xCEC8, 0x7A34, 0xB753, 0x7A35, 0xB754, 0x7A36, 0xB755,
+	0x7A37, 0xF0A2, 0x7A38, 0xB756, 0x7A39, 0xF0A1, 0x7A3A, 0xB757,
+	0x7A3B, 0xB5BE, 0x7A3C, 0xBCDA, 0x7A3D, 0xBBFC, 0x7A3E, 0xB758,
+	0x7A3F, 0xB8E5, 0x7A40, 0xB759, 0x7A41, 0xB75A, 0x7A42, 0xB75B,
+	0x7A43, 0xB75C, 0x7A44, 0xB75D, 0x7A45, 0xB75E, 0x7A46, 0xC4C2,
+	0x7A47, 0xB75F, 0x7A48, 0xB760, 0x7A49, 0xB761, 0x7A4A, 0xB762,
+	0x7A4B, 0xB763, 0x7A4C, 0xB764, 0x7A4D, 0xB765, 0x7A4E, 0xB766,
+	0x7A4F, 0xB767, 0x7A50, 0xB768, 0x7A51, 0xF0A3, 0x7A52, 0xB769,
+	0x7A53, 0xB76A, 0x7A54, 0xB76B, 0x7A55, 0xB76C, 0x7A56, 0xB76D,
+	0x7A57, 0xCBEB, 0x7A58, 0xB76E, 0x7A59, 0xB76F, 0x7A5A, 0xB770,
+	0x7A5B, 0xB771, 0x7A5C, 0xB772, 0x7A5D, 0xB773, 0x7A5E, 0xB774,
+	0x7A5F, 0xB775, 0x7A60, 0xB776, 0x7A61, 0xB777, 0x7A62, 0xB778,
+	0x7A63, 0xB779, 0x7A64, 0xB77A, 0x7A65, 0xB77B, 0x7A66, 0xB77C,
+	0x7A67, 0xB77D, 0x7A68, 0xB77E, 0x7A69, 0xB780, 0x7A6A, 0xB781,
+	0x7A6B, 0xB782, 0x7A6C, 0xB783, 0x7A6D, 0xB784, 0x7A6E, 0xB785,
+	0x7A6F, 0xB786, 0x7A70, 0xF0A6, 0x7A71, 0xB787, 0x7A72, 0xB788,
+	0x7A73, 0xB789, 0x7A74, 0xD1A8, 0x7A75, 0xB78A, 0x7A76, 0xBEBF,
+	0x7A77, 0xC7EE, 0x7A78, 0xF1B6, 0x7A79, 0xF1B7, 0x7A7A, 0xBFD5,
+	0x7A7B, 0xB78B, 0x7A7C, 0xB78C, 0x7A7D, 0xB78D, 0x7A7E, 0xB78E,
+	0x7A7F, 0xB4A9, 0x7A80, 0xF1B8, 0x7A81, 0xCDBB, 0x7A82, 0xB78F,
+	0x7A83, 0xC7D4, 0x7A84, 0xD5AD, 0x7A85, 0xB790, 0x7A86, 0xF1B9,
+	0x7A87, 0xB791, 0x7A88, 0xF1BA, 0x7A89, 0xB792, 0x7A8A, 0xB793,
+	0x7A8B, 0xB794, 0x7A8C, 0xB795, 0x7A8D, 0xC7CF, 0x7A8E, 0xB796,
+	0x7A8F, 0xB797, 0x7A90, 0xB798, 0x7A91, 0xD2A4, 0x7A92, 0xD6CF,
+	0x7A93, 0xB799, 0x7A94, 0xB79A, 0x7A95, 0xF1BB, 0x7A96, 0xBDD1,
+	0x7A97, 0xB4B0, 0x7A98, 0xBEBD, 0x7A99, 0xB79B, 0x7A9A, 0xB79C,
+	0x7A9B, 0xB79D, 0x7A9C, 0xB4DC, 0x7A9D, 0xCED1, 0x7A9E, 0xB79E,
+	0x7A9F, 0xBFDF, 0x7AA0, 0xF1BD, 0x7AA1, 0xB79F, 0x7AA2, 0xB7A0,
+	0x7AA3, 0xB840, 0x7AA4, 0xB841, 0x7AA5, 0xBFFA, 0x7AA6, 0xF1BC,
+	0x7AA7, 0xB842, 0x7AA8, 0xF1BF, 0x7AA9, 0xB843, 0x7AAA, 0xB844,
+	0x7AAB, 0xB845, 0x7AAC, 0xF1BE, 0x7AAD, 0xF1C0, 0x7AAE, 0xB846,
+	0x7AAF, 0xB847, 0x7AB0, 0xB848, 0x7AB1, 0xB849, 0x7AB2, 0xB84A,
+	0x7AB3, 0xF1C1, 0x7AB4, 0xB84B, 0x7AB5, 0xB84C, 0x7AB6, 0xB84D,
+	0x7AB7, 0xB84E, 0x7AB8, 0xB84F, 0x7AB9, 0xB850, 0x7ABA, 0xB851,
+	0x7ABB, 0xB852, 0x7ABC, 0xB853, 0x7ABD, 0xB854, 0x7ABE, 0xB855,
+	0x7ABF, 0xC1FE, 0x7AC0, 0xB856, 0x7AC1, 0xB857, 0x7AC2, 0xB858,
+	0x7AC3, 0xB859, 0x7AC4, 0xB85A, 0x7AC5, 0xB85B, 0x7AC6, 0xB85C,
+	0x7AC7, 0xB85D, 0x7AC8, 0xB85E, 0x7AC9, 0xB85F, 0x7ACA, 0xB860,
+	0x7ACB, 0xC1A2, 0x7ACC, 0xB861, 0x7ACD, 0xB862, 0x7ACE, 0xB863,
+	0x7ACF, 0xB864, 0x7AD0, 0xB865, 0x7AD1, 0xB866, 0x7AD2, 0xB867,
+	0x7AD3, 0xB868, 0x7AD4, 0xB869, 0x7AD5, 0xB86A, 0x7AD6, 0xCAFA,
+	0x7AD7, 0xB86B, 0x7AD8, 0xB86C, 0x7AD9, 0xD5BE, 0x7ADA, 0xB86D,
+	0x7ADB, 0xB86E, 0x7ADC, 0xB86F, 0x7ADD, 0xB870, 0x7ADE, 0xBEBA,
+	0x7ADF, 0xBEB9, 0x7AE0, 0xD5C2, 0x7AE1, 0xB871, 0x7AE2, 0xB872,
+	0x7AE3, 0xBFA2, 0x7AE4, 0xB873, 0x7AE5, 0xCDAF, 0x7AE6, 0xF1B5,
+	0x7AE7, 0xB874, 0x7AE8, 0xB875, 0x7AE9, 0xB876, 0x7AEA, 0xB877,
+	0x7AEB, 0xB878, 0x7AEC, 0xB879, 0x7AED, 0xBDDF, 0x7AEE, 0xB87A,
+	0x7AEF, 0xB6CB, 0x7AF0, 0xB87B, 0x7AF1, 0xB87C, 0x7AF2, 0xB87D,
+	0x7AF3, 0xB87E, 0x7AF4, 0xB880, 0x7AF5, 0xB881, 0x7AF6, 0xB882,
+	0x7AF7, 0xB883, 0x7AF8, 0xB884, 0x7AF9, 0xD6F1, 0x7AFA, 0xF3C3,
+	0x7AFB, 0xB885, 0x7AFC, 0xB886, 0x7AFD, 0xF3C4, 0x7AFE, 0xB887,
+	0x7AFF, 0xB8CD, 0x7B00, 0xB888, 0x7B01, 0xB889, 0x7B02, 0xB88A,
+	0x7B03, 0xF3C6, 0x7B04, 0xF3C7, 0x7B05, 0xB88B, 0x7B06, 0xB0CA,
+	0x7B07, 0xB88C, 0x7B08, 0xF3C5, 0x7B09, 0xB88D, 0x7B0A, 0xF3C9,
+	0x7B0B, 0xCBF1, 0x7B0C, 0xB88E, 0x7B0D, 0xB88F, 0x7B0E, 0xB890,
+	0x7B0F, 0xF3CB, 0x7B10, 0xB891, 0x7B11, 0xD0A6, 0x7B12, 0xB892,
+	0x7B13, 0xB893, 0x7B14, 0xB1CA, 0x7B15, 0xF3C8, 0x7B16, 0xB894,
+	0x7B17, 0xB895, 0x7B18, 0xB896, 0x7B19, 0xF3CF, 0x7B1A, 0xB897,
+	0x7B1B, 0xB5D1, 0x7B1C, 0xB898, 0x7B1D, 0xB899, 0x7B1E, 0xF3D7,
+	0x7B1F, 0xB89A, 0x7B20, 0xF3D2, 0x7B21, 0xB89B, 0x7B22, 0xB89C,
+	0x7B23, 0xB89D, 0x7B24, 0xF3D4, 0x7B25, 0xF3D3, 0x7B26, 0xB7FB,
+	0x7B27, 0xB89E, 0x7B28, 0xB1BF, 0x7B29, 0xB89F, 0x7B2A, 0xF3CE,
+	0x7B2B, 0xF3CA, 0x7B2C, 0xB5DA, 0x7B2D, 0xB8A0, 0x7B2E, 0xF3D0,
+	0x7B2F, 0xB940, 0x7B30, 0xB941, 0x7B31, 0xF3D1, 0x7B32, 0xB942,
+	0x7B33, 0xF3D5, 0x7B34, 0xB943, 0x7B35, 0xB944, 0x7B36, 0xB945,
+	0x7B37, 0xB946, 0x7B38, 0xF3CD, 0x7B39, 0xB947, 0x7B3A, 0xBCE3,
+	0x7B3B, 0xB948, 0x7B3C, 0xC1FD, 0x7B3D, 0xB949, 0x7B3E, 0xF3D6,
+	0x7B3F, 0xB94A, 0x7B40, 0xB94B, 0x7B41, 0xB94C, 0x7B42, 0xB94D,
+	0x7B43, 0xB94E, 0x7B44, 0xB94F, 0x7B45, 0xF3DA, 0x7B46, 0xB950,
+	0x7B47, 0xF3CC, 0x7B48, 0xB951, 0x7B49, 0xB5C8, 0x7B4A, 0xB952,
+	0x7B4B, 0xBDEE, 0x7B4C, 0xF3DC, 0x7B4D, 0xB953, 0x7B4E, 0xB954,
+	0x7B4F, 0xB7A4, 0x7B50, 0xBFF0, 0x7B51, 0xD6FE, 0x7B52, 0xCDB2,
+	0x7B53, 0xB955, 0x7B54, 0xB4F0, 0x7B55, 0xB956, 0x7B56, 0xB2DF,
+	0x7B57, 0xB957, 0x7B58, 0xF3D8, 0x7B59, 0xB958, 0x7B5A, 0xF3D9,
+	0x7B5B, 0xC9B8, 0x7B5C, 0xB959, 0x7B5D, 0xF3DD, 0x7B5E, 0xB95A,
+	0x7B5F, 0xB95B, 0x7B60, 0xF3DE, 0x7B61, 0xB95C, 0x7B62, 0xF3E1,
+	0x7B63, 0xB95D, 0x7B64, 0xB95E, 0x7B65, 0xB95F, 0x7B66, 0xB960,
+	0x7B67, 0xB961, 0x7B68, 0xB962, 0x7B69, 0xB963, 0x7B6A, 0xB964,
+	0x7B6B, 0xB965, 0x7B6C, 0xB966, 0x7B6D, 0xB967, 0x7B6E, 0xF3DF,
+	0x7B6F, 0xB968, 0x7B70, 0xB969, 0x7B71, 0xF3E3, 0x7B72, 0xF3E2,
+	0x7B73, 0xB96A, 0x7B74, 0xB96B, 0x7B75, 0xF3DB, 0x7B76, 0xB96C,
+	0x7B77, 0xBFEA, 0x7B78, 0xB96D, 0x7B79, 0xB3EF, 0x7B7A, 0xB96E,
+	0x7B7B, 0xF3E0, 0x7B7C, 0xB96F, 0x7B7D, 0xB970, 0x7B7E, 0xC7A9,
+	0x7B7F, 0xB971, 0x7B80, 0xBCF2, 0x7B81, 0xB972, 0x7B82, 0xB973,
+	0x7B83, 0xB974, 0x7B84, 0xB975, 0x7B85, 0xF3EB, 0x7B86, 0xB976,
+	0x7B87, 0xB977, 0x7B88, 0xB978, 0x7B89, 0xB979, 0x7B8A, 0xB97A,
+	0x7B8B, 0xB97B, 0x7B8C, 0xB97C, 0x7B8D, 0xB9BF, 0x7B8E, 0xB97D,
+	0x7B8F, 0xB97E, 0x7B90, 0xF3E4, 0x7B91, 0xB980, 0x7B92, 0xB981,
+	0x7B93, 0xB982, 0x7B94, 0xB2AD, 0x7B95, 0xBBFE, 0x7B96, 0xB983,
+	0x7B97, 0xCBE3, 0x7B98, 0xB984, 0x7B99, 0xB985, 0x7B9A, 0xB986,
+	0x7B9B, 0xB987, 0x7B9C, 0xF3ED, 0x7B9D, 0xF3E9, 0x7B9E, 0xB988,
+	0x7B9F, 0xB989, 0x7BA0, 0xB98A, 0x7BA1, 0xB9DC, 0x7BA2, 0xF3EE,
+	0x7BA3, 0xB98B, 0x7BA4, 0xB98C, 0x7BA5, 0xB98D, 0x7BA6, 0xF3E5,
+	0x7BA7, 0xF3E6, 0x7BA8, 0xF3EA, 0x7BA9, 0xC2E1, 0x7BAA, 0xF3EC,
+	0x7BAB, 0xF3EF, 0x7BAC, 0xF3E8, 0x7BAD, 0xBCFD, 0x7BAE, 0xB98E,
+	0x7BAF, 0xB98F, 0x7BB0, 0xB990, 0x7BB1, 0xCFE4, 0x7BB2, 0xB991,
+	0x7BB3, 0xB992, 0x7BB4, 0xF3F0, 0x7BB5, 0xB993, 0x7BB6, 0xB994,
+	0x7BB7, 0xB995, 0x7BB8, 0xF3E7, 0x7BB9, 0xB996, 0x7BBA, 0xB997,
+	0x7BBB, 0xB998, 0x7BBC, 0xB999, 0x7BBD, 0xB99A, 0x7BBE, 0xB99B,
+	0x7BBF, 0xB99C, 0x7BC0, 0xB99D, 0x7BC1, 0xF3F2, 0x7BC2, 0xB99E,
+	0x7BC3, 0xB99F, 0x7BC4, 0xB9A0, 0x7BC5, 0xBA40, 0x7BC6, 0xD7AD,
+	0x7BC7, 0xC6AA, 0x7BC8, 0xBA41, 0x7BC9, 0xBA42, 0x7BCA, 0xBA43,
+	0x7BCB, 0xBA44, 0x7BCC, 0xF3F3, 0x7BCD, 0xBA45, 0x7BCE, 0xBA46,
+	0x7BCF, 0xBA47, 0x7BD0, 0xBA48, 0x7BD1, 0xF3F1, 0x7BD2, 0xBA49,
+	0x7BD3, 0xC2A8, 0x7BD4, 0xBA4A, 0x7BD5, 0xBA4B, 0x7BD6, 0xBA4C,
+	0x7BD7, 0xBA4D, 0x7BD8, 0xBA4E, 0x7BD9, 0xB8DD, 0x7BDA, 0xF3F5,
+	0x7BDB, 0xBA4F, 0x7BDC, 0xBA50, 0x7BDD, 0xF3F4, 0x7BDE, 0xBA51,
+	0x7BDF, 0xBA52, 0x7BE0, 0xBA53, 0x7BE1, 0xB4DB, 0x7BE2, 0xBA54,
+	0x7BE3, 0xBA55, 0x7BE4, 0xBA56, 0x7BE5, 0xF3F6, 0x7BE6, 0xF3F7,
+	0x7BE7, 0xBA57, 0x7BE8, 0xBA58, 0x7BE9, 0xBA59, 0x7BEA, 0xF3F8,
+	0x7BEB, 0xBA5A, 0x7BEC, 0xBA5B, 0x7BED, 0xBA5C, 0x7BEE, 0xC0BA,
+	0x7BEF, 0xBA5D, 0x7BF0, 0xBA5E, 0x7BF1, 0xC0E9, 0x7BF2, 0xBA5F,
+	0x7BF3, 0xBA60, 0x7BF4, 0xBA61, 0x7BF5, 0xBA62, 0x7BF6, 0xBA63,
+	0x7BF7, 0xC5F1, 0x7BF8, 0xBA64, 0x7BF9, 0xBA65, 0x7BFA, 0xBA66,
+	0x7BFB, 0xBA67, 0x7BFC, 0xF3FB, 0x7BFD, 0xBA68, 0x7BFE, 0xF3FA,
+	0x7BFF, 0xBA69, 0x7C00, 0xBA6A, 0x7C01, 0xBA6B, 0x7C02, 0xBA6C,
+	0x7C03, 0xBA6D, 0x7C04, 0xBA6E, 0x7C05, 0xBA6F, 0x7C06, 0xBA70,
+	0x7C07, 0xB4D8, 0x7C08, 0xBA71, 0x7C09, 0xBA72, 0x7C0A, 0xBA73,
+	0x7C0B, 0xF3FE, 0x7C0C, 0xF3F9, 0x7C0D, 0xBA74, 0x7C0E, 0xBA75,
+	0x7C0F, 0xF3FC, 0x7C10, 0xBA76, 0x7C11, 0xBA77, 0x7C12, 0xBA78,
+	0x7C13, 0xBA79, 0x7C14, 0xBA7A, 0x7C15, 0xBA7B, 0x7C16, 0xF3FD,
+	0x7C17, 0xBA7C, 0x7C18, 0xBA7D, 0x7C19, 0xBA7E, 0x7C1A, 0xBA80,
+	0x7C1B, 0xBA81, 0x7C1C, 0xBA82, 0x7C1D, 0xBA83, 0x7C1E, 0xBA84,
+	0x7C1F, 0xF4A1, 0x7C20, 0xBA85, 0x7C21, 0xBA86, 0x7C22, 0xBA87,
+	0x7C23, 0xBA88, 0x7C24, 0xBA89, 0x7C25, 0xBA8A, 0x7C26, 0xF4A3,
+	0x7C27, 0xBBC9, 0x7C28, 0xBA8B, 0x7C29, 0xBA8C, 0x7C2A, 0xF4A2,
+	0x7C2B, 0xBA8D, 0x7C2C, 0xBA8E, 0x7C2D, 0xBA8F, 0x7C2E, 0xBA90,
+	0x7C2F, 0xBA91, 0x7C30, 0xBA92, 0x7C31, 0xBA93, 0x7C32, 0xBA94,
+	0x7C33, 0xBA95, 0x7C34, 0xBA96, 0x7C35, 0xBA97, 0x7C36, 0xBA98,
+	0x7C37, 0xBA99, 0x7C38, 0xF4A4, 0x7C39, 0xBA9A, 0x7C3A, 0xBA9B,
+	0x7C3B, 0xBA9C, 0x7C3C, 0xBA9D, 0x7C3D, 0xBA9E, 0x7C3E, 0xBA9F,
+	0x7C3F, 0xB2BE, 0x7C40, 0xF4A6, 0x7C41, 0xF4A5, 0x7C42, 0xBAA0,
+	0x7C43, 0xBB40, 0x7C44, 0xBB41, 0x7C45, 0xBB42, 0x7C46, 0xBB43,
+	0x7C47, 0xBB44, 0x7C48, 0xBB45, 0x7C49, 0xBB46, 0x7C4A, 0xBB47,
+	0x7C4B, 0xBB48, 0x7C4C, 0xBB49, 0x7C4D, 0xBCAE, 0x7C4E, 0xBB4A,
+	0x7C4F, 0xBB4B, 0x7C50, 0xBB4C, 0x7C51, 0xBB4D, 0x7C52, 0xBB4E,
+	0x7C53, 0xBB4F, 0x7C54, 0xBB50, 0x7C55, 0xBB51, 0x7C56, 0xBB52,
+	0x7C57, 0xBB53, 0x7C58, 0xBB54, 0x7C59, 0xBB55, 0x7C5A, 0xBB56,
+	0x7C5B, 0xBB57, 0x7C5C, 0xBB58, 0x7C5D, 0xBB59, 0x7C5E, 0xBB5A,
+	0x7C5F, 0xBB5B, 0x7C60, 0xBB5C, 0x7C61, 0xBB5D, 0x7C62, 0xBB5E,
+	0x7C63, 0xBB5F, 0x7C64, 0xBB60, 0x7C65, 0xBB61, 0x7C66, 0xBB62,
+	0x7C67, 0xBB63, 0x7C68, 0xBB64, 0x7C69, 0xBB65, 0x7C6A, 0xBB66,
+	0x7C6B, 0xBB67, 0x7C6C, 0xBB68, 0x7C6D, 0xBB69, 0x7C6E, 0xBB6A,
+	0x7C6F, 0xBB6B, 0x7C70, 0xBB6C, 0x7C71, 0xBB6D, 0x7C72, 0xBB6E,
+	0x7C73, 0xC3D7, 0x7C74, 0xD9E1, 0x7C75, 0xBB6F, 0x7C76, 0xBB70,
+	0x7C77, 0xBB71, 0x7C78, 0xBB72, 0x7C79, 0xBB73, 0x7C7A, 0xBB74,
+	0x7C7B, 0xC0E0, 0x7C7C, 0xF4CC, 0x7C7D, 0xD7D1, 0x7C7E, 0xBB75,
+	0x7C7F, 0xBB76, 0x7C80, 0xBB77, 0x7C81, 0xBB78, 0x7C82, 0xBB79,
+	0x7C83, 0xBB7A, 0x7C84, 0xBB7B, 0x7C85, 0xBB7C, 0x7C86, 0xBB7D,
+	0x7C87, 0xBB7E, 0x7C88, 0xBB80, 0x7C89, 0xB7DB, 0x7C8A, 0xBB81,
+	0x7C8B, 0xBB82, 0x7C8C, 0xBB83, 0x7C8D, 0xBB84, 0x7C8E, 0xBB85,
+	0x7C8F, 0xBB86, 0x7C90, 0xBB87, 0x7C91, 0xF4CE, 0x7C92, 0xC1A3,
+	0x7C93, 0xBB88, 0x7C94, 0xBB89, 0x7C95, 0xC6C9, 0x7C96, 0xBB8A,
+	0x7C97, 0xB4D6, 0x7C98, 0xD5B3, 0x7C99, 0xBB8B, 0x7C9A, 0xBB8C,
+	0x7C9B, 0xBB8D, 0x7C9C, 0xF4D0, 0x7C9D, 0xF4CF, 0x7C9E, 0xF4D1,
+	0x7C9F, 0xCBDA, 0x7CA0, 0xBB8E, 0x7CA1, 0xBB8F, 0x7CA2, 0xF4D2,
+	0x7CA3, 0xBB90, 0x7CA4, 0xD4C1, 0x7CA5, 0xD6E0, 0x7CA6, 0xBB91,
+	0x7CA7, 0xBB92, 0x7CA8, 0xBB93, 0x7CA9, 0xBB94, 0x7CAA, 0xB7E0,
+	0x7CAB, 0xBB95, 0x7CAC, 0xBB96, 0x7CAD, 0xBB97, 0x7CAE, 0xC1B8,
+	0x7CAF, 0xBB98, 0x7CB0, 0xBB99, 0x7CB1, 0xC1BB, 0x7CB2, 0xF4D3,
+	0x7CB3, 0xBEAC, 0x7CB4, 0xBB9A, 0x7CB5, 0xBB9B, 0x7CB6, 0xBB9C,
+	0x7CB7, 0xBB9D, 0x7CB8, 0xBB9E, 0x7CB9, 0xB4E2, 0x7CBA, 0xBB9F,
+	0x7CBB, 0xBBA0, 0x7CBC, 0xF4D4, 0x7CBD, 0xF4D5, 0x7CBE, 0xBEAB,
+	0x7CBF, 0xBC40, 0x7CC0, 0xBC41, 0x7CC1, 0xF4D6, 0x7CC2, 0xBC42,
+	0x7CC3, 0xBC43, 0x7CC4, 0xBC44, 0x7CC5, 0xF4DB, 0x7CC6, 0xBC45,
+	0x7CC7, 0xF4D7, 0x7CC8, 0xF4DA, 0x7CC9, 0xBC46, 0x7CCA, 0xBAFD,
+	0x7CCB, 0xBC47, 0x7CCC, 0xF4D8, 0x7CCD, 0xF4D9, 0x7CCE, 0xBC48,
+	0x7CCF, 0xBC49, 0x7CD0, 0xBC4A, 0x7CD1, 0xBC4B, 0x7CD2, 0xBC4C,
+	0x7CD3, 0xBC4D, 0x7CD4, 0xBC4E, 0x7CD5, 0xB8E2, 0x7CD6, 0xCCC7,
+	0x7CD7, 0xF4DC, 0x7CD8, 0xBC4F, 0x7CD9, 0xB2DA, 0x7CDA, 0xBC50,
+	0x7CDB, 0xBC51, 0x7CDC, 0xC3D3, 0x7CDD, 0xBC52, 0x7CDE, 0xBC53,
+	0x7CDF, 0xD4E3, 0x7CE0, 0xBFB7, 0x7CE1, 0xBC54, 0x7CE2, 0xBC55,
+	0x7CE3, 0xBC56, 0x7CE4, 0xBC57, 0x7CE5, 0xBC58, 0x7CE6, 0xBC59,
+	0x7CE7, 0xBC5A, 0x7CE8, 0xF4DD, 0x7CE9, 0xBC5B, 0x7CEA, 0xBC5C,
+	0x7CEB, 0xBC5D, 0x7CEC, 0xBC5E, 0x7CED, 0xBC5F, 0x7CEE, 0xBC60,
+	0x7CEF, 0xC5B4, 0x7CF0, 0xBC61, 0x7CF1, 0xBC62, 0x7CF2, 0xBC63,
+	0x7CF3, 0xBC64, 0x7CF4, 0xBC65, 0x7CF5, 0xBC66, 0x7CF6, 0xBC67,
+	0x7CF7, 0xBC68, 0x7CF8, 0xF4E9, 0x7CF9, 0xBC69, 0x7CFA, 0xBC6A,
+	0x7CFB, 0xCFB5, 0x7CFC, 0xBC6B, 0x7CFD, 0xBC6C, 0x7CFE, 0xBC6D,
+	0x7CFF, 0xBC6E, 0x7D00, 0xBC6F, 0x7D01, 0xBC70, 0x7D02, 0xBC71,
+	0x7D03, 0xBC72, 0x7D04, 0xBC73, 0x7D05, 0xBC74, 0x7D06, 0xBC75,
+	0x7D07, 0xBC76, 0x7D08, 0xBC77, 0x7D09, 0xBC78, 0x7D0A, 0xCEC9,
+	0x7D0B, 0xBC79, 0x7D0C, 0xBC7A, 0x7D0D, 0xBC7B, 0x7D0E, 0xBC7C,
+	0x7D0F, 0xBC7D, 0x7D10, 0xBC7E, 0x7D11, 0xBC80, 0x7D12, 0xBC81,
+	0x7D13, 0xBC82, 0x7D14, 0xBC83, 0x7D15, 0xBC84, 0x7D16, 0xBC85,
+	0x7D17, 0xBC86, 0x7D18, 0xBC87, 0x7D19, 0xBC88, 0x7D1A, 0xBC89,
+	0x7D1B, 0xBC8A, 0x7D1C, 0xBC8B, 0x7D1D, 0xBC8C, 0x7D1E, 0xBC8D,
+	0x7D1F, 0xBC8E, 0x7D20, 0xCBD8, 0x7D21, 0xBC8F, 0x7D22, 0xCBF7,
+	0x7D23, 0xBC90, 0x7D24, 0xBC91, 0x7D25, 0xBC92, 0x7D26, 0xBC93,
+	0x7D27, 0xBDF4, 0x7D28, 0xBC94, 0x7D29, 0xBC95, 0x7D2A, 0xBC96,
+	0x7D2B, 0xD7CF, 0x7D2C, 0xBC97, 0x7D2D, 0xBC98, 0x7D2E, 0xBC99,
+	0x7D2F, 0xC0DB, 0x7D30, 0xBC9A, 0x7D31, 0xBC9B, 0x7D32, 0xBC9C,
+	0x7D33, 0xBC9D, 0x7D34, 0xBC9E, 0x7D35, 0xBC9F, 0x7D36, 0xBCA0,
+	0x7D37, 0xBD40, 0x7D38, 0xBD41, 0x7D39, 0xBD42, 0x7D3A, 0xBD43,
+	0x7D3B, 0xBD44, 0x7D3C, 0xBD45, 0x7D3D, 0xBD46, 0x7D3E, 0xBD47,
+	0x7D3F, 0xBD48, 0x7D40, 0xBD49, 0x7D41, 0xBD4A, 0x7D42, 0xBD4B,
+	0x7D43, 0xBD4C, 0x7D44, 0xBD4D, 0x7D45, 0xBD4E, 0x7D46, 0xBD4F,
+	0x7D47, 0xBD50, 0x7D48, 0xBD51, 0x7D49, 0xBD52, 0x7D4A, 0xBD53,
+	0x7D4B, 0xBD54, 0x7D4C, 0xBD55, 0x7D4D, 0xBD56, 0x7D4E, 0xBD57,
+	0x7D4F, 0xBD58, 0x7D50, 0xBD59, 0x7D51, 0xBD5A, 0x7D52, 0xBD5B,
+	0x7D53, 0xBD5C, 0x7D54, 0xBD5D, 0x7D55, 0xBD5E, 0x7D56, 0xBD5F,
+	0x7D57, 0xBD60, 0x7D58, 0xBD61, 0x7D59, 0xBD62, 0x7D5A, 0xBD63,
+	0x7D5B, 0xBD64, 0x7D5C, 0xBD65, 0x7D5D, 0xBD66, 0x7D5E, 0xBD67,
+	0x7D5F, 0xBD68, 0x7D60, 0xBD69, 0x7D61, 0xBD6A, 0x7D62, 0xBD6B,
+	0x7D63, 0xBD6C, 0x7D64, 0xBD6D, 0x7D65, 0xBD6E, 0x7D66, 0xBD6F,
+	0x7D67, 0xBD70, 0x7D68, 0xBD71, 0x7D69, 0xBD72, 0x7D6A, 0xBD73,
+	0x7D6B, 0xBD74, 0x7D6C, 0xBD75, 0x7D6D, 0xBD76, 0x7D6E, 0xD0F5,
+	0x7D6F, 0xBD77, 0x7D70, 0xBD78, 0x7D71, 0xBD79, 0x7D72, 0xBD7A,
+	0x7D73, 0xBD7B, 0x7D74, 0xBD7C, 0x7D75, 0xBD7D, 0x7D76, 0xBD7E,
+	0x7D77, 0xF4EA, 0x7D78, 0xBD80, 0x7D79, 0xBD81, 0x7D7A, 0xBD82,
+	0x7D7B, 0xBD83, 0x7D7C, 0xBD84, 0x7D7D, 0xBD85, 0x7D7E, 0xBD86,
+	0x7D7F, 0xBD87, 0x7D80, 0xBD88, 0x7D81, 0xBD89, 0x7D82, 0xBD8A,
+	0x7D83, 0xBD8B, 0x7D84, 0xBD8C, 0x7D85, 0xBD8D, 0x7D86, 0xBD8E,
+	0x7D87, 0xBD8F, 0x7D88, 0xBD90, 0x7D89, 0xBD91, 0x7D8A, 0xBD92,
+	0x7D8B, 0xBD93, 0x7D8C, 0xBD94, 0x7D8D, 0xBD95, 0x7D8E, 0xBD96,
+	0x7D8F, 0xBD97, 0x7D90, 0xBD98, 0x7D91, 0xBD99, 0x7D92, 0xBD9A,
+	0x7D93, 0xBD9B, 0x7D94, 0xBD9C, 0x7D95, 0xBD9D, 0x7D96, 0xBD9E,
+	0x7D97, 0xBD9F, 0x7D98, 0xBDA0, 0x7D99, 0xBE40, 0x7D9A, 0xBE41,
+	0x7D9B, 0xBE42, 0x7D9C, 0xBE43, 0x7D9D, 0xBE44, 0x7D9E, 0xBE45,
+	0x7D9F, 0xBE46, 0x7DA0, 0xBE47, 0x7DA1, 0xBE48, 0x7DA2, 0xBE49,
+	0x7DA3, 0xBE4A, 0x7DA4, 0xBE4B, 0x7DA5, 0xBE4C, 0x7DA6, 0xF4EB,
+	0x7DA7, 0xBE4D, 0x7DA8, 0xBE4E, 0x7DA9, 0xBE4F, 0x7DAA, 0xBE50,
+	0x7DAB, 0xBE51, 0x7DAC, 0xBE52, 0x7DAD, 0xBE53, 0x7DAE, 0xF4EC,
+	0x7DAF, 0xBE54, 0x7DB0, 0xBE55, 0x7DB1, 0xBE56, 0x7DB2, 0xBE57,
+	0x7DB3, 0xBE58, 0x7DB4, 0xBE59, 0x7DB5, 0xBE5A, 0x7DB6, 0xBE5B,
+	0x7DB7, 0xBE5C, 0x7DB8, 0xBE5D, 0x7DB9, 0xBE5E, 0x7DBA, 0xBE5F,
+	0x7DBB, 0xBE60, 0x7DBC, 0xBE61, 0x7DBD, 0xBE62, 0x7DBE, 0xBE63,
+	0x7DBF, 0xBE64, 0x7DC0, 0xBE65, 0x7DC1, 0xBE66, 0x7DC2, 0xBE67,
+	0x7DC3, 0xBE68, 0x7DC4, 0xBE69, 0x7DC5, 0xBE6A, 0x7DC6, 0xBE6B,
+	0x7DC7, 0xBE6C, 0x7DC8, 0xBE6D, 0x7DC9, 0xBE6E, 0x7DCA, 0xBE6F,
+	0x7DCB, 0xBE70, 0x7DCC, 0xBE71, 0x7DCD, 0xBE72, 0x7DCE, 0xBE73,
+	0x7DCF, 0xBE74, 0x7DD0, 0xBE75, 0x7DD1, 0xBE76, 0x7DD2, 0xBE77,
+	0x7DD3, 0xBE78, 0x7DD4, 0xBE79, 0x7DD5, 0xBE7A, 0x7DD6, 0xBE7B,
+	0x7DD7, 0xBE7C, 0x7DD8, 0xBE7D, 0x7DD9, 0xBE7E, 0x7DDA, 0xBE80,
+	0x7DDB, 0xBE81, 0x7DDC, 0xBE82, 0x7DDD, 0xBE83, 0x7DDE, 0xBE84,
+	0x7DDF, 0xBE85, 0x7DE0, 0xBE86, 0x7DE1, 0xBE87, 0x7DE2, 0xBE88,
+	0x7DE3, 0xBE89, 0x7DE4, 0xBE8A, 0x7DE5, 0xBE8B, 0x7DE6, 0xBE8C,
+	0x7DE7, 0xBE8D, 0x7DE8, 0xBE8E, 0x7DE9, 0xBE8F, 0x7DEA, 0xBE90,
+	0x7DEB, 0xBE91, 0x7DEC, 0xBE92, 0x7DED, 0xBE93, 0x7DEE, 0xBE94,
+	0x7DEF, 0xBE95, 0x7DF0, 0xBE96, 0x7DF1, 0xBE97, 0x7DF2, 0xBE98,
+	0x7DF3, 0xBE99, 0x7DF4, 0xBE9A, 0x7DF5, 0xBE9B, 0x7DF6, 0xBE9C,
+	0x7DF7, 0xBE9D, 0x7DF8, 0xBE9E, 0x7DF9, 0xBE9F, 0x7DFA, 0xBEA0,
+	0x7DFB, 0xBF40, 0x7DFC, 0xBF41, 0x7DFD, 0xBF42, 0x7DFE, 0xBF43,
+	0x7DFF, 0xBF44, 0x7E00, 0xBF45, 0x7E01, 0xBF46, 0x7E02, 0xBF47,
+	0x7E03, 0xBF48, 0x7E04, 0xBF49, 0x7E05, 0xBF4A, 0x7E06, 0xBF4B,
+	0x7E07, 0xBF4C, 0x7E08, 0xBF4D, 0x7E09, 0xBF4E, 0x7E0A, 0xBF4F,
+	0x7E0B, 0xBF50, 0x7E0C, 0xBF51, 0x7E0D, 0xBF52, 0x7E0E, 0xBF53,
+	0x7E0F, 0xBF54, 0x7E10, 0xBF55, 0x7E11, 0xBF56, 0x7E12, 0xBF57,
+	0x7E13, 0xBF58, 0x7E14, 0xBF59, 0x7E15, 0xBF5A, 0x7E16, 0xBF5B,
+	0x7E17, 0xBF5C, 0x7E18, 0xBF5D, 0x7E19, 0xBF5E, 0x7E1A, 0xBF5F,
+	0x7E1B, 0xBF60, 0x7E1C, 0xBF61, 0x7E1D, 0xBF62, 0x7E1E, 0xBF63,
+	0x7E1F, 0xBF64, 0x7E20, 0xBF65, 0x7E21, 0xBF66, 0x7E22, 0xBF67,
+	0x7E23, 0xBF68, 0x7E24, 0xBF69, 0x7E25, 0xBF6A, 0x7E26, 0xBF6B,
+	0x7E27, 0xBF6C, 0x7E28, 0xBF6D, 0x7E29, 0xBF6E, 0x7E2A, 0xBF6F,
+	0x7E2B, 0xBF70, 0x7E2C, 0xBF71, 0x7E2D, 0xBF72, 0x7E2E, 0xBF73,
+	0x7E2F, 0xBF74, 0x7E30, 0xBF75, 0x7E31, 0xBF76, 0x7E32, 0xBF77,
+	0x7E33, 0xBF78, 0x7E34, 0xBF79, 0x7E35, 0xBF7A, 0x7E36, 0xBF7B,
+	0x7E37, 0xBF7C, 0x7E38, 0xBF7D, 0x7E39, 0xBF7E, 0x7E3A, 0xBF80,
+	0x7E3B, 0xF7E3, 0x7E3C, 0xBF81, 0x7E3D, 0xBF82, 0x7E3E, 0xBF83,
+	0x7E3F, 0xBF84, 0x7E40, 0xBF85, 0x7E41, 0xB7B1, 0x7E42, 0xBF86,
+	0x7E43, 0xBF87, 0x7E44, 0xBF88, 0x7E45, 0xBF89, 0x7E46, 0xBF8A,
+	0x7E47, 0xF4ED, 0x7E48, 0xBF8B, 0x7E49, 0xBF8C, 0x7E4A, 0xBF8D,
+	0x7E4B, 0xBF8E, 0x7E4C, 0xBF8F, 0x7E4D, 0xBF90, 0x7E4E, 0xBF91,
+	0x7E4F, 0xBF92, 0x7E50, 0xBF93, 0x7E51, 0xBF94, 0x7E52, 0xBF95,
+	0x7E53, 0xBF96, 0x7E54, 0xBF97, 0x7E55, 0xBF98, 0x7E56, 0xBF99,
+	0x7E57, 0xBF9A, 0x7E58, 0xBF9B, 0x7E59, 0xBF9C, 0x7E5A, 0xBF9D,
+	0x7E5B, 0xBF9E, 0x7E5C, 0xBF9F, 0x7E5D, 0xBFA0, 0x7E5E, 0xC040,
+	0x7E5F, 0xC041, 0x7E60, 0xC042, 0x7E61, 0xC043, 0x7E62, 0xC044,
+	0x7E63, 0xC045, 0x7E64, 0xC046, 0x7E65, 0xC047, 0x7E66, 0xC048,
+	0x7E67, 0xC049, 0x7E68, 0xC04A, 0x7E69, 0xC04B, 0x7E6A, 0xC04C,
+	0x7E6B, 0xC04D, 0x7E6C, 0xC04E, 0x7E6D, 0xC04F, 0x7E6E, 0xC050,
+	0x7E6F, 0xC051, 0x7E70, 0xC052, 0x7E71, 0xC053, 0x7E72, 0xC054,
+	0x7E73, 0xC055, 0x7E74, 0xC056, 0x7E75, 0xC057, 0x7E76, 0xC058,
+	0x7E77, 0xC059, 0x7E78, 0xC05A, 0x7E79, 0xC05B, 0x7E7A, 0xC05C,
+	0x7E7B, 0xC05D, 0x7E7C, 0xC05E, 0x7E7D, 0xC05F, 0x7E7E, 0xC060,
+	0x7E7F, 0xC061, 0x7E80, 0xC062, 0x7E81, 0xC063, 0x7E82, 0xD7EB,
+	0x7E83, 0xC064, 0x7E84, 0xC065, 0x7E85, 0xC066, 0x7E86, 0xC067,
+	0x7E87, 0xC068, 0x7E88, 0xC069, 0x7E89, 0xC06A, 0x7E8A, 0xC06B,
+	0x7E8B, 0xC06C, 0x7E8C, 0xC06D, 0x7E8D, 0xC06E, 0x7E8E, 0xC06F,
+	0x7E8F, 0xC070, 0x7E90, 0xC071, 0x7E91, 0xC072, 0x7E92, 0xC073,
+	0x7E93, 0xC074, 0x7E94, 0xC075, 0x7E95, 0xC076, 0x7E96, 0xC077,
+	0x7E97, 0xC078, 0x7E98, 0xC079, 0x7E99, 0xC07A, 0x7E9A, 0xC07B,
+	0x7E9B, 0xF4EE, 0x7E9C, 0xC07C, 0x7E9D, 0xC07D, 0x7E9E, 0xC07E,
+	0x7E9F, 0xE6F9, 0x7EA0, 0xBEC0, 0x7EA1, 0xE6FA, 0x7EA2, 0xBAEC,
+	0x7EA3, 0xE6FB, 0x7EA4, 0xCFCB, 0x7EA5, 0xE6FC, 0x7EA6, 0xD4BC,
+	0x7EA7, 0xBCB6, 0x7EA8, 0xE6FD, 0x7EA9, 0xE6FE, 0x7EAA, 0xBCCD,
+	0x7EAB, 0xC8D2, 0x7EAC, 0xCEB3, 0x7EAD, 0xE7A1, 0x7EAE, 0xC080,
+	0x7EAF, 0xB4BF, 0x7EB0, 0xE7A2, 0x7EB1, 0xC9B4, 0x7EB2, 0xB8D9,
+	0x7EB3, 0xC4C9, 0x7EB4, 0xC081, 0x7EB5, 0xD7DD, 0x7EB6, 0xC2DA,
+	0x7EB7, 0xB7D7, 0x7EB8, 0xD6BD, 0x7EB9, 0xCEC6, 0x7EBA, 0xB7C4,
+	0x7EBB, 0xC082, 0x7EBC, 0xC083, 0x7EBD, 0xC5A6, 0x7EBE, 0xE7A3,
+	0x7EBF, 0xCFDF, 0x7EC0, 0xE7A4, 0x7EC1, 0xE7A5, 0x7EC2, 0xE7A6,
+	0x7EC3, 0xC1B7, 0x7EC4, 0xD7E9, 0x7EC5, 0xC9F0, 0x7EC6, 0xCFB8,
+	0x7EC7, 0xD6AF, 0x7EC8, 0xD6D5, 0x7EC9, 0xE7A7, 0x7ECA, 0xB0ED,
+	0x7ECB, 0xE7A8, 0x7ECC, 0xE7A9, 0x7ECD, 0xC9DC, 0x7ECE, 0xD2EF,
+	0x7ECF, 0xBEAD, 0x7ED0, 0xE7AA, 0x7ED1, 0xB0F3, 0x7ED2, 0xC8DE,
+	0x7ED3, 0xBDE1, 0x7ED4, 0xE7AB, 0x7ED5, 0xC8C6, 0x7ED6, 0xC084,
+	0x7ED7, 0xE7AC, 0x7ED8, 0xBBE6, 0x7ED9, 0xB8F8, 0x7EDA, 0xD1A4,
+	0x7EDB, 0xE7AD, 0x7EDC, 0xC2E7, 0x7EDD, 0xBEF8, 0x7EDE, 0xBDCA,
+	0x7EDF, 0xCDB3, 0x7EE0, 0xE7AE, 0x7EE1, 0xE7AF, 0x7EE2, 0xBEEE,
+	0x7EE3, 0xD0E5, 0x7EE4, 0xC085, 0x7EE5, 0xCBE7, 0x7EE6, 0xCCD0,
+	0x7EE7, 0xBCCC, 0x7EE8, 0xE7B0, 0x7EE9, 0xBCA8, 0x7EEA, 0xD0F7,
+	0x7EEB, 0xE7B1, 0x7EEC, 0xC086, 0x7EED, 0xD0F8, 0x7EEE, 0xE7B2,
+	0x7EEF, 0xE7B3, 0x7EF0, 0xB4C2, 0x7EF1, 0xE7B4, 0x7EF2, 0xE7B5,
+	0x7EF3, 0xC9FE, 0x7EF4, 0xCEAC, 0x7EF5, 0xC3E0, 0x7EF6, 0xE7B7,
+	0x7EF7, 0xB1C1, 0x7EF8, 0xB3F1, 0x7EF9, 0xC087, 0x7EFA, 0xE7B8,
+	0x7EFB, 0xE7B9, 0x7EFC, 0xD7DB, 0x7EFD, 0xD5C0, 0x7EFE, 0xE7BA,
+	0x7EFF, 0xC2CC, 0x7F00, 0xD7BA, 0x7F01, 0xE7BB, 0x7F02, 0xE7BC,
+	0x7F03, 0xE7BD, 0x7F04, 0xBCEA, 0x7F05, 0xC3E5, 0x7F06, 0xC0C2,
+	0x7F07, 0xE7BE, 0x7F08, 0xE7BF, 0x7F09, 0xBCA9, 0x7F0A, 0xC088,
+	0x7F0B, 0xE7C0, 0x7F0C, 0xE7C1, 0x7F0D, 0xE7B6, 0x7F0E, 0xB6D0,
+	0x7F0F, 0xE7C2, 0x7F10, 0xC089, 0x7F11, 0xE7C3, 0x7F12, 0xE7C4,
+	0x7F13, 0xBBBA, 0x7F14, 0xB5DE, 0x7F15, 0xC2C6, 0x7F16, 0xB1E0,
+	0x7F17, 0xE7C5, 0x7F18, 0xD4B5, 0x7F19, 0xE7C6, 0x7F1A, 0xB8BF,
+	0x7F1B, 0xE7C8, 0x7F1C, 0xE7C7, 0x7F1D, 0xB7EC, 0x7F1E, 0xC08A,
+	0x7F1F, 0xE7C9, 0x7F20, 0xB2F8, 0x7F21, 0xE7CA, 0x7F22, 0xE7CB,
+	0x7F23, 0xE7CC, 0x7F24, 0xE7CD, 0x7F25, 0xE7CE, 0x7F26, 0xE7CF,
+	0x7F27, 0xE7D0, 0x7F28, 0xD3A7, 0x7F29, 0xCBF5, 0x7F2A, 0xE7D1,
+	0x7F2B, 0xE7D2, 0x7F2C, 0xE7D3, 0x7F2D, 0xE7D4, 0x7F2E, 0xC9C9,
+	0x7F2F, 0xE7D5, 0x7F30, 0xE7D6, 0x7F31, 0xE7D7, 0x7F32, 0xE7D8,
+	0x7F33, 0xE7D9, 0x7F34, 0xBDC9, 0x7F35, 0xE7DA, 0x7F36, 0xF3BE,
+	0x7F37, 0xC08B, 0x7F38, 0xB8D7, 0x7F39, 0xC08C, 0x7F3A, 0xC8B1,
+	0x7F3B, 0xC08D, 0x7F3C, 0xC08E, 0x7F3D, 0xC08F, 0x7F3E, 0xC090,
+	0x7F3F, 0xC091, 0x7F40, 0xC092, 0x7F41, 0xC093, 0x7F42, 0xF3BF,
+	0x7F43, 0xC094, 0x7F44, 0xF3C0, 0x7F45, 0xF3C1, 0x7F46, 0xC095,
+	0x7F47, 0xC096, 0x7F48, 0xC097, 0x7F49, 0xC098, 0x7F4A, 0xC099,
+	0x7F4B, 0xC09A, 0x7F4C, 0xC09B, 0x7F4D, 0xC09C, 0x7F4E, 0xC09D,
+	0x7F4F, 0xC09E, 0x7F50, 0xB9DE, 0x7F51, 0xCDF8, 0x7F52, 0xC09F,
+	0x7F53, 0xC0A0, 0x7F54, 0xD8E8, 0x7F55, 0xBAB1, 0x7F56, 0xC140,
+	0x7F57, 0xC2DE, 0x7F58, 0xEEB7, 0x7F59, 0xC141, 0x7F5A, 0xB7A3,
+	0x7F5B, 0xC142, 0x7F5C, 0xC143, 0x7F5D, 0xC144, 0x7F5E, 0xC145,
+	0x7F5F, 0xEEB9, 0x7F60, 0xC146, 0x7F61, 0xEEB8, 0x7F62, 0xB0D5,
+	0x7F63, 0xC147, 0x7F64, 0xC148, 0x7F65, 0xC149, 0x7F66, 0xC14A,
+	0x7F67, 0xC14B, 0x7F68, 0xEEBB, 0x7F69, 0xD5D6, 0x7F6A, 0xD7EF,
+	0x7F6B, 0xC14C, 0x7F6C, 0xC14D, 0x7F6D, 0xC14E, 0x7F6E, 0xD6C3,
+	0x7F6F, 0xC14F, 0x7F70, 0xC150, 0x7F71, 0xEEBD, 0x7F72, 0xCAF0,
+	0x7F73, 0xC151, 0x7F74, 0xEEBC, 0x7F75, 0xC152, 0x7F76, 0xC153,
+	0x7F77, 0xC154, 0x7F78, 0xC155, 0x7F79, 0xEEBE, 0x7F7A, 0xC156,
+	0x7F7B, 0xC157, 0x7F7C, 0xC158, 0x7F7D, 0xC159, 0x7F7E, 0xEEC0,
+	0x7F7F, 0xC15A, 0x7F80, 0xC15B, 0x7F81, 0xEEBF, 0x7F82, 0xC15C,
+	0x7F83, 0xC15D, 0x7F84, 0xC15E, 0x7F85, 0xC15F, 0x7F86, 0xC160,
+	0x7F87, 0xC161, 0x7F88, 0xC162, 0x7F89, 0xC163, 0x7F8A, 0xD1F2,
+	0x7F8B, 0xC164, 0x7F8C, 0xC7BC, 0x7F8D, 0xC165, 0x7F8E, 0xC3C0,
+	0x7F8F, 0xC166, 0x7F90, 0xC167, 0x7F91, 0xC168, 0x7F92, 0xC169,
+	0x7F93, 0xC16A, 0x7F94, 0xB8E1, 0x7F95, 0xC16B, 0x7F96, 0xC16C,
+	0x7F97, 0xC16D, 0x7F98, 0xC16E, 0x7F99, 0xC16F, 0x7F9A, 0xC1E7,
+	0x7F9B, 0xC170, 0x7F9C, 0xC171, 0x7F9D, 0xF4C6, 0x7F9E, 0xD0DF,
+	0x7F9F, 0xF4C7, 0x7FA0, 0xC172, 0x7FA1, 0xCFDB, 0x7FA2, 0xC173,
+	0x7FA3, 0xC174, 0x7FA4, 0xC8BA, 0x7FA5, 0xC175, 0x7FA6, 0xC176,
+	0x7FA7, 0xF4C8, 0x7FA8, 0xC177, 0x7FA9, 0xC178, 0x7FAA, 0xC179,
+	0x7FAB, 0xC17A, 0x7FAC, 0xC17B, 0x7FAD, 0xC17C, 0x7FAE, 0xC17D,
+	0x7FAF, 0xF4C9, 0x7FB0, 0xF4CA, 0x7FB1, 0xC17E, 0x7FB2, 0xF4CB,
+	0x7FB3, 0xC180, 0x7FB4, 0xC181, 0x7FB5, 0xC182, 0x7FB6, 0xC183,
+	0x7FB7, 0xC184, 0x7FB8, 0xD9FA, 0x7FB9, 0xB8FE, 0x7FBA, 0xC185,
+	0x7FBB, 0xC186, 0x7FBC, 0xE5F1, 0x7FBD, 0xD3F0, 0x7FBE, 0xC187,
+	0x7FBF, 0xF4E0, 0x7FC0, 0xC188, 0x7FC1, 0xCECC, 0x7FC2, 0xC189,
+	0x7FC3, 0xC18A, 0x7FC4, 0xC18B, 0x7FC5, 0xB3E1, 0x7FC6, 0xC18C,
+	0x7FC7, 0xC18D, 0x7FC8, 0xC18E, 0x7FC9, 0xC18F, 0x7FCA, 0xF1B4,
+	0x7FCB, 0xC190, 0x7FCC, 0xD2EE, 0x7FCD, 0xC191, 0x7FCE, 0xF4E1,
+	0x7FCF, 0xC192, 0x7FD0, 0xC193, 0x7FD1, 0xC194, 0x7FD2, 0xC195,
+	0x7FD3, 0xC196, 0x7FD4, 0xCFE8, 0x7FD5, 0xF4E2, 0x7FD6, 0xC197,
+	0x7FD7, 0xC198, 0x7FD8, 0xC7CC, 0x7FD9, 0xC199, 0x7FDA, 0xC19A,
+	0x7FDB, 0xC19B, 0x7FDC, 0xC19C, 0x7FDD, 0xC19D, 0x7FDE, 0xC19E,
+	0x7FDF, 0xB5D4, 0x7FE0, 0xB4E4, 0x7FE1, 0xF4E4, 0x7FE2, 0xC19F,
+	0x7FE3, 0xC1A0, 0x7FE4, 0xC240, 0x7FE5, 0xF4E3, 0x7FE6, 0xF4E5,
+	0x7FE7, 0xC241, 0x7FE8, 0xC242, 0x7FE9, 0xF4E6, 0x7FEA, 0xC243,
+	0x7FEB, 0xC244, 0x7FEC, 0xC245, 0x7FED, 0xC246, 0x7FEE, 0xF4E7,
+	0x7FEF, 0xC247, 0x7FF0, 0xBAB2, 0x7FF1, 0xB0BF, 0x7FF2, 0xC248,
+	0x7FF3, 0xF4E8, 0x7FF4, 0xC249, 0x7FF5, 0xC24A, 0x7FF6, 0xC24B,
+	0x7FF7, 0xC24C, 0x7FF8, 0xC24D, 0x7FF9, 0xC24E, 0x7FFA, 0xC24F,
+	0x7FFB, 0xB7AD, 0x7FFC, 0xD2ED, 0x7FFD, 0xC250, 0x7FFE, 0xC251,
+	0x7FFF, 0xC252, 0x8000, 0xD2AB, 0x8001, 0xC0CF, 0x8002, 0xC253,
+	0x8003, 0xBFBC, 0x8004, 0xEBA3, 0x8005, 0xD5DF, 0x8006, 0xEAC8,
+	0x8007, 0xC254, 0x8008, 0xC255, 0x8009, 0xC256, 0x800A, 0xC257,
+	0x800B, 0xF1F3, 0x800C, 0xB6F8, 0x800D, 0xCBA3, 0x800E, 0xC258,
+	0x800F, 0xC259, 0x8010, 0xC4CD, 0x8011, 0xC25A, 0x8012, 0xF1E7,
+	0x8013, 0xC25B, 0x8014, 0xF1E8, 0x8015, 0xB8FB, 0x8016, 0xF1E9,
+	0x8017, 0xBAC4, 0x8018, 0xD4C5, 0x8019, 0xB0D2, 0x801A, 0xC25C,
+	0x801B, 0xC25D, 0x801C, 0xF1EA, 0x801D, 0xC25E, 0x801E, 0xC25F,
+	0x801F, 0xC260, 0x8020, 0xF1EB, 0x8021, 0xC261, 0x8022, 0xF1EC,
+	0x8023, 0xC262, 0x8024, 0xC263, 0x8025, 0xF1ED, 0x8026, 0xF1EE,
+	0x8027, 0xF1EF, 0x8028, 0xF1F1, 0x8029, 0xF1F0, 0x802A, 0xC5D5,
+	0x802B, 0xC264, 0x802C, 0xC265, 0x802D, 0xC266, 0x802E, 0xC267,
+	0x802F, 0xC268, 0x8030, 0xC269, 0x8031, 0xF1F2, 0x8032, 0xC26A,
+	0x8033, 0xB6FA, 0x8034, 0xC26B, 0x8035, 0xF1F4, 0x8036, 0xD2AE,
+	0x8037, 0xDEC7, 0x8038, 0xCBCA, 0x8039, 0xC26C, 0x803A, 0xC26D,
+	0x803B, 0xB3DC, 0x803C, 0xC26E, 0x803D, 0xB5A2, 0x803E, 0xC26F,
+	0x803F, 0xB9A2, 0x8040, 0xC270, 0x8041, 0xC271, 0x8042, 0xC4F4,
+	0x8043, 0xF1F5, 0x8044, 0xC272, 0x8045, 0xC273, 0x8046, 0xF1F6,
+	0x8047, 0xC274, 0x8048, 0xC275, 0x8049, 0xC276, 0x804A, 0xC1C4,
+	0x804B, 0xC1FB, 0x804C, 0xD6B0, 0x804D, 0xF1F7, 0x804E, 0xC277,
+	0x804F, 0xC278, 0x8050, 0xC279, 0x8051, 0xC27A, 0x8052, 0xF1F8,
+	0x8053, 0xC27B, 0x8054, 0xC1AA, 0x8055, 0xC27C, 0x8056, 0xC27D,
+	0x8057, 0xC27E, 0x8058, 0xC6B8, 0x8059, 0xC280, 0x805A, 0xBEDB,
+	0x805B, 0xC281, 0x805C, 0xC282, 0x805D, 0xC283, 0x805E, 0xC284,
+	0x805F, 0xC285, 0x8060, 0xC286, 0x8061, 0xC287, 0x8062, 0xC288,
+	0x8063, 0xC289, 0x8064, 0xC28A, 0x8065, 0xC28B, 0x8066, 0xC28C,
+	0x8067, 0xC28D, 0x8068, 0xC28E, 0x8069, 0xF1F9, 0x806A, 0xB4CF,
+	0x806B, 0xC28F, 0x806C, 0xC290, 0x806D, 0xC291, 0x806E, 0xC292,
+	0x806F, 0xC293, 0x8070, 0xC294, 0x8071, 0xF1FA, 0x8072, 0xC295,
+	0x8073, 0xC296, 0x8074, 0xC297, 0x8075, 0xC298, 0x8076, 0xC299,
+	0x8077, 0xC29A, 0x8078, 0xC29B, 0x8079, 0xC29C, 0x807A, 0xC29D,
+	0x807B, 0xC29E, 0x807C, 0xC29F, 0x807D, 0xC2A0, 0x807E, 0xC340,
+	0x807F, 0xEDB2, 0x8080, 0xEDB1, 0x8081, 0xC341, 0x8082, 0xC342,
+	0x8083, 0xCBE0, 0x8084, 0xD2DE, 0x8085, 0xC343, 0x8086, 0xCBC1,
+	0x8087, 0xD5D8, 0x8088, 0xC344, 0x8089, 0xC8E2, 0x808A, 0xC345,
+	0x808B, 0xC0DF, 0x808C, 0xBCA1, 0x808D, 0xC346, 0x808E, 0xC347,
+	0x808F, 0xC348, 0x8090, 0xC349, 0x8091, 0xC34A, 0x8092, 0xC34B,
+	0x8093, 0xEBC1, 0x8094, 0xC34C, 0x8095, 0xC34D, 0x8096, 0xD0A4,
+	0x8097, 0xC34E, 0x8098, 0xD6E2, 0x8099, 0xC34F, 0x809A, 0xB6C7,
+	0x809B, 0xB8D8, 0x809C, 0xEBC0, 0x809D, 0xB8CE, 0x809E, 0xC350,
+	0x809F, 0xEBBF, 0x80A0, 0xB3A6, 0x80A1, 0xB9C9, 0x80A2, 0xD6AB,
+	0x80A3, 0xC351, 0x80A4, 0xB7F4, 0x80A5, 0xB7CA, 0x80A6, 0xC352,
+	0x80A7, 0xC353, 0x80A8, 0xC354, 0x80A9, 0xBCE7, 0x80AA, 0xB7BE,
+	0x80AB, 0xEBC6, 0x80AC, 0xC355, 0x80AD, 0xEBC7, 0x80AE, 0xB0B9,
+	0x80AF, 0xBFCF, 0x80B0, 0xC356, 0x80B1, 0xEBC5, 0x80B2, 0xD3FD,
+	0x80B3, 0xC357, 0x80B4, 0xEBC8, 0x80B5, 0xC358, 0x80B6, 0xC359,
+	0x80B7, 0xEBC9, 0x80B8, 0xC35A, 0x80B9, 0xC35B, 0x80BA, 0xB7CE,
+	0x80BB, 0xC35C, 0x80BC, 0xEBC2, 0x80BD, 0xEBC4, 0x80BE, 0xC9F6,
+	0x80BF, 0xD6D7, 0x80C0, 0xD5CD, 0x80C1, 0xD0B2, 0x80C2, 0xEBCF,
+	0x80C3, 0xCEB8, 0x80C4, 0xEBD0, 0x80C5, 0xC35D, 0x80C6, 0xB5A8,
+	0x80C7, 0xC35E, 0x80C8, 0xC35F, 0x80C9, 0xC360, 0x80CA, 0xC361,
+	0x80CB, 0xC362, 0x80CC, 0xB1B3, 0x80CD, 0xEBD2, 0x80CE, 0xCCA5,
+	0x80CF, 0xC363, 0x80D0, 0xC364, 0x80D1, 0xC365, 0x80D2, 0xC366,
+	0x80D3, 0xC367, 0x80D4, 0xC368, 0x80D5, 0xC369, 0x80D6, 0xC5D6,
+	0x80D7, 0xEBD3, 0x80D8, 0xC36A, 0x80D9, 0xEBD1, 0x80DA, 0xC5DF,
+	0x80DB, 0xEBCE, 0x80DC, 0xCAA4, 0x80DD, 0xEBD5, 0x80DE, 0xB0FB,
+	0x80DF, 0xC36B, 0x80E0, 0xC36C, 0x80E1, 0xBAFA, 0x80E2, 0xC36D,
+	0x80E3, 0xC36E, 0x80E4, 0xD8B7, 0x80E5, 0xF1E3, 0x80E6, 0xC36F,
+	0x80E7, 0xEBCA, 0x80E8, 0xEBCB, 0x80E9, 0xEBCC, 0x80EA, 0xEBCD,
+	0x80EB, 0xEBD6, 0x80EC, 0xE6C0, 0x80ED, 0xEBD9, 0x80EE, 0xC370,
+	0x80EF, 0xBFE8, 0x80F0, 0xD2C8, 0x80F1, 0xEBD7, 0x80F2, 0xEBDC,
+	0x80F3, 0xB8EC, 0x80F4, 0xEBD8, 0x80F5, 0xC371, 0x80F6, 0xBDBA,
+	0x80F7, 0xC372, 0x80F8, 0xD0D8, 0x80F9, 0xC373, 0x80FA, 0xB0B7,
+	0x80FB, 0xC374, 0x80FC, 0xEBDD, 0x80FD, 0xC4DC, 0x80FE, 0xC375,
+	0x80FF, 0xC376, 0x8100, 0xC377, 0x8101, 0xC378, 0x8102, 0xD6AC,
+	0x8103, 0xC379, 0x8104, 0xC37A, 0x8105, 0xC37B, 0x8106, 0xB4E0,
+	0x8107, 0xC37C, 0x8108, 0xC37D, 0x8109, 0xC2F6, 0x810A, 0xBCB9,
+	0x810B, 0xC37E, 0x810C, 0xC380, 0x810D, 0xEBDA, 0x810E, 0xEBDB,
+	0x810F, 0xD4E0, 0x8110, 0xC6EA, 0x8111, 0xC4D4, 0x8112, 0xEBDF,
+	0x8113, 0xC5A7, 0x8114, 0xD9F5, 0x8115, 0xC381, 0x8116, 0xB2B1,
+	0x8117, 0xC382, 0x8118, 0xEBE4, 0x8119, 0xC383, 0x811A, 0xBDC5,
+	0x811B, 0xC384, 0x811C, 0xC385, 0x811D, 0xC386, 0x811E, 0xEBE2,
+	0x811F, 0xC387, 0x8120, 0xC388, 0x8121, 0xC389, 0x8122, 0xC38A,
+	0x8123, 0xC38B, 0x8124, 0xC38C, 0x8125, 0xC38D, 0x8126, 0xC38E,
+	0x8127, 0xC38F, 0x8128, 0xC390, 0x8129, 0xC391, 0x812A, 0xC392,
+	0x812B, 0xC393, 0x812C, 0xEBE3, 0x812D, 0xC394, 0x812E, 0xC395,
+	0x812F, 0xB8AC, 0x8130, 0xC396, 0x8131, 0xCDD1, 0x8132, 0xEBE5,
+	0x8133, 0xC397, 0x8134, 0xC398, 0x8135, 0xC399, 0x8136, 0xEBE1,
+	0x8137, 0xC39A, 0x8138, 0xC1B3, 0x8139, 0xC39B, 0x813A, 0xC39C,
+	0x813B, 0xC39D, 0x813C, 0xC39E, 0x813D, 0xC39F, 0x813E, 0xC6A2,
+	0x813F, 0xC3A0, 0x8140, 0xC440, 0x8141, 0xC441, 0x8142, 0xC442,
+	0x8143, 0xC443, 0x8144, 0xC444, 0x8145, 0xC445, 0x8146, 0xCCF3,
+	0x8147, 0xC446, 0x8148, 0xEBE6, 0x8149, 0xC447, 0x814A, 0xC0B0,
+	0x814B, 0xD2B8, 0x814C, 0xEBE7, 0x814D, 0xC448, 0x814E, 0xC449,
+	0x814F, 0xC44A, 0x8150, 0xB8AF, 0x8151, 0xB8AD, 0x8152, 0xC44B,
+	0x8153, 0xEBE8, 0x8154, 0xC7BB, 0x8155, 0xCDF3, 0x8156, 0xC44C,
+	0x8157, 0xC44D, 0x8158, 0xC44E, 0x8159, 0xEBEA, 0x815A, 0xEBEB,
+	0x815B, 0xC44F, 0x815C, 0xC450, 0x815D, 0xC451, 0x815E, 0xC452,
+	0x815F, 0xC453, 0x8160, 0xEBED, 0x8161, 0xC454, 0x8162, 0xC455,
+	0x8163, 0xC456, 0x8164, 0xC457, 0x8165, 0xD0C8, 0x8166, 0xC458,
+	0x8167, 0xEBF2, 0x8168, 0xC459, 0x8169, 0xEBEE, 0x816A, 0xC45A,
+	0x816B, 0xC45B, 0x816C, 0xC45C, 0x816D, 0xEBF1, 0x816E, 0xC8F9,
+	0x816F, 0xC45D, 0x8170, 0xD1FC, 0x8171, 0xEBEC, 0x8172, 0xC45E,
+	0x8173, 0xC45F, 0x8174, 0xEBE9, 0x8175, 0xC460, 0x8176, 0xC461,
+	0x8177, 0xC462, 0x8178, 0xC463, 0x8179, 0xB8B9, 0x817A, 0xCFD9,
+	0x817B, 0xC4E5, 0x817C, 0xEBEF, 0x817D, 0xEBF0, 0x817E, 0xCCDA,
+	0x817F, 0xCDC8, 0x8180, 0xB0F2, 0x8181, 0xC464, 0x8182, 0xEBF6,
+	0x8183, 0xC465, 0x8184, 0xC466, 0x8185, 0xC467, 0x8186, 0xC468,
+	0x8187, 0xC469, 0x8188, 0xEBF5, 0x8189, 0xC46A, 0x818A, 0xB2B2,
+	0x818B, 0xC46B, 0x818C, 0xC46C, 0x818D, 0xC46D, 0x818E, 0xC46E,
+	0x818F, 0xB8E0, 0x8190, 0xC46F, 0x8191, 0xEBF7, 0x8192, 0xC470,
+	0x8193, 0xC471, 0x8194, 0xC472, 0x8195, 0xC473, 0x8196, 0xC474,
+	0x8197, 0xC475, 0x8198, 0xB1EC, 0x8199, 0xC476, 0x819A, 0xC477,
+	0x819B, 0xCCC5, 0x819C, 0xC4A4, 0x819D, 0xCFA5, 0x819E, 0xC478,
+	0x819F, 0xC479, 0x81A0, 0xC47A, 0x81A1, 0xC47B, 0x81A2, 0xC47C,
+	0x81A3, 0xEBF9, 0x81A4, 0xC47D, 0x81A5, 0xC47E, 0x81A6, 0xECA2,
+	0x81A7, 0xC480, 0x81A8, 0xC5F2, 0x81A9, 0xC481, 0x81AA, 0xEBFA,
+	0x81AB, 0xC482, 0x81AC, 0xC483, 0x81AD, 0xC484, 0x81AE, 0xC485,
+	0x81AF, 0xC486, 0x81B0, 0xC487, 0x81B1, 0xC488, 0x81B2, 0xC489,
+	0x81B3, 0xC9C5, 0x81B4, 0xC48A, 0x81B5, 0xC48B, 0x81B6, 0xC48C,
+	0x81B7, 0xC48D, 0x81B8, 0xC48E, 0x81B9, 0xC48F, 0x81BA, 0xE2DF,
+	0x81BB, 0xEBFE, 0x81BC, 0xC490, 0x81BD, 0xC491, 0x81BE, 0xC492,
+	0x81BF, 0xC493, 0x81C0, 0xCDCE, 0x81C1, 0xECA1, 0x81C2, 0xB1DB,
+	0x81C3, 0xD3B7, 0x81C4, 0xC494, 0x81C5, 0xC495, 0x81C6, 0xD2DC,
+	0x81C7, 0xC496, 0x81C8, 0xC497, 0x81C9, 0xC498, 0x81CA, 0xEBFD,
+	0x81CB, 0xC499, 0x81CC, 0xEBFB, 0x81CD, 0xC49A, 0x81CE, 0xC49B,
+	0x81CF, 0xC49C, 0x81D0, 0xC49D, 0x81D1, 0xC49E, 0x81D2, 0xC49F,
+	0x81D3, 0xC4A0, 0x81D4, 0xC540, 0x81D5, 0xC541, 0x81D6, 0xC542,
+	0x81D7, 0xC543, 0x81D8, 0xC544, 0x81D9, 0xC545, 0x81DA, 0xC546,
+	0x81DB, 0xC547, 0x81DC, 0xC548, 0x81DD, 0xC549, 0x81DE, 0xC54A,
+	0x81DF, 0xC54B, 0x81E0, 0xC54C, 0x81E1, 0xC54D, 0x81E2, 0xC54E,
+	0x81E3, 0xB3BC, 0x81E4, 0xC54F, 0x81E5, 0xC550, 0x81E6, 0xC551,
+	0x81E7, 0xEAB0, 0x81E8, 0xC552, 0x81E9, 0xC553, 0x81EA, 0xD7D4,
+	0x81EB, 0xC554, 0x81EC, 0xF4AB, 0x81ED, 0xB3F4, 0x81EE, 0xC555,
+	0x81EF, 0xC556, 0x81F0, 0xC557, 0x81F1, 0xC558, 0x81F2, 0xC559,
+	0x81F3, 0xD6C1, 0x81F4, 0xD6C2, 0x81F5, 0xC55A, 0x81F6, 0xC55B,
+	0x81F7, 0xC55C, 0x81F8, 0xC55D, 0x81F9, 0xC55E, 0x81FA, 0xC55F,
+	0x81FB, 0xD5E9, 0x81FC, 0xBECA, 0x81FD, 0xC560, 0x81FE, 0xF4A7,
+	0x81FF, 0xC561, 0x8200, 0xD2A8, 0x8201, 0xF4A8, 0x8202, 0xF4A9,
+	0x8203, 0xC562, 0x8204, 0xF4AA, 0x8205, 0xBECB, 0x8206, 0xD3DF,
+	0x8207, 0xC563, 0x8208, 0xC564, 0x8209, 0xC565, 0x820A, 0xC566,
+	0x820B, 0xC567, 0x820C, 0xC9E0, 0x820D, 0xC9E1, 0x820E, 0xC568,
+	0x820F, 0xC569, 0x8210, 0xF3C2, 0x8211, 0xC56A, 0x8212, 0xCAE6,
+	0x8213, 0xC56B, 0x8214, 0xCCF2, 0x8215, 0xC56C, 0x8216, 0xC56D,
+	0x8217, 0xC56E, 0x8218, 0xC56F, 0x8219, 0xC570, 0x821A, 0xC571,
+	0x821B, 0xE2B6, 0x821C, 0xCBB4, 0x821D, 0xC572, 0x821E, 0xCEE8,
+	0x821F, 0xD6DB, 0x8220, 0xC573, 0x8221, 0xF4AD, 0x8222, 0xF4AE,
+	0x8223, 0xF4AF, 0x8224, 0xC574, 0x8225, 0xC575, 0x8226, 0xC576,
+	0x8227, 0xC577, 0x8228, 0xF4B2, 0x8229, 0xC578, 0x822A, 0xBABD,
+	0x822B, 0xF4B3, 0x822C, 0xB0E3, 0x822D, 0xF4B0, 0x822E, 0xC579,
+	0x822F, 0xF4B1, 0x8230, 0xBDA2, 0x8231, 0xB2D5, 0x8232, 0xC57A,
+	0x8233, 0xF4B6, 0x8234, 0xF4B7, 0x8235, 0xB6E6, 0x8236, 0xB2B0,
+	0x8237, 0xCFCF, 0x8238, 0xF4B4, 0x8239, 0xB4AC, 0x823A, 0xC57B,
+	0x823B, 0xF4B5, 0x823C, 0xC57C, 0x823D, 0xC57D, 0x823E, 0xF4B8,
+	0x823F, 0xC57E, 0x8240, 0xC580, 0x8241, 0xC581, 0x8242, 0xC582,
+	0x8243, 0xC583, 0x8244, 0xF4B9, 0x8245, 0xC584, 0x8246, 0xC585,
+	0x8247, 0xCDA7, 0x8248, 0xC586, 0x8249, 0xF4BA, 0x824A, 0xC587,
+	0x824B, 0xF4BB, 0x824C, 0xC588, 0x824D, 0xC589, 0x824E, 0xC58A,
+	0x824F, 0xF4BC, 0x8250, 0xC58B, 0x8251, 0xC58C, 0x8252, 0xC58D,
+	0x8253, 0xC58E, 0x8254, 0xC58F, 0x8255, 0xC590, 0x8256, 0xC591,
+	0x8257, 0xC592, 0x8258, 0xCBD2, 0x8259, 0xC593, 0x825A, 0xF4BD,
+	0x825B, 0xC594, 0x825C, 0xC595, 0x825D, 0xC596, 0x825E, 0xC597,
+	0x825F, 0xF4BE, 0x8260, 0xC598, 0x8261, 0xC599, 0x8262, 0xC59A,
+	0x8263, 0xC59B, 0x8264, 0xC59C, 0x8265, 0xC59D, 0x8266, 0xC59E,
+	0x8267, 0xC59F, 0x8268, 0xF4BF, 0x8269, 0xC5A0, 0x826A, 0xC640,
+	0x826B, 0xC641, 0x826C, 0xC642, 0x826D, 0xC643, 0x826E, 0xF4DE,
+	0x826F, 0xC1BC, 0x8270, 0xBCE8, 0x8271, 0xC644, 0x8272, 0xC9AB,
+	0x8273, 0xD1DE, 0x8274, 0xE5F5, 0x8275, 0xC645, 0x8276, 0xC646,
+	0x8277, 0xC647, 0x8278, 0xC648, 0x8279, 0xDCB3, 0x827A, 0xD2D5,
+	0x827B, 0xC649, 0x827C, 0xC64A, 0x827D, 0xDCB4, 0x827E, 0xB0AC,
+	0x827F, 0xDCB5, 0x8280, 0xC64B, 0x8281, 0xC64C, 0x8282, 0xBDDA,
+	0x8283, 0xC64D, 0x8284, 0xDCB9, 0x8285, 0xC64E, 0x8286, 0xC64F,
+	0x8287, 0xC650, 0x8288, 0xD8C2, 0x8289, 0xC651, 0x828A, 0xDCB7,
+	0x828B, 0xD3F3, 0x828C, 0xC652, 0x828D, 0xC9D6, 0x828E, 0xDCBA,
+	0x828F, 0xDCB6, 0x8290, 0xC653, 0x8291, 0xDCBB, 0x8292, 0xC3A2,
+	0x8293, 0xC654, 0x8294, 0xC655, 0x8295, 0xC656, 0x8296, 0xC657,
+	0x8297, 0xDCBC, 0x8298, 0xDCC5, 0x8299, 0xDCBD, 0x829A, 0xC658,
+	0x829B, 0xC659, 0x829C, 0xCEDF, 0x829D, 0xD6A5, 0x829E, 0xC65A,
+	0x829F, 0xDCCF, 0x82A0, 0xC65B, 0x82A1, 0xDCCD, 0x82A2, 0xC65C,
+	0x82A3, 0xC65D, 0x82A4, 0xDCD2, 0x82A5, 0xBDE6, 0x82A6, 0xC2AB,
+	0x82A7, 0xC65E, 0x82A8, 0xDCB8, 0x82A9, 0xDCCB, 0x82AA, 0xDCCE,
+	0x82AB, 0xDCBE, 0x82AC, 0xB7D2, 0x82AD, 0xB0C5, 0x82AE, 0xDCC7,
+	0x82AF, 0xD0BE, 0x82B0, 0xDCC1, 0x82B1, 0xBBA8, 0x82B2, 0xC65F,
+	0x82B3, 0xB7BC, 0x82B4, 0xDCCC, 0x82B5, 0xC660, 0x82B6, 0xC661,
+	0x82B7, 0xDCC6, 0x82B8, 0xDCBF, 0x82B9, 0xC7DB, 0x82BA, 0xC662,
+	0x82BB, 0xC663, 0x82BC, 0xC664, 0x82BD, 0xD1BF, 0x82BE, 0xDCC0,
+	0x82BF, 0xC665, 0x82C0, 0xC666, 0x82C1, 0xDCCA, 0x82C2, 0xC667,
+	0x82C3, 0xC668, 0x82C4, 0xDCD0, 0x82C5, 0xC669, 0x82C6, 0xC66A,
+	0x82C7, 0xCEAD, 0x82C8, 0xDCC2, 0x82C9, 0xC66B, 0x82CA, 0xDCC3,
+	0x82CB, 0xDCC8, 0x82CC, 0xDCC9, 0x82CD, 0xB2D4, 0x82CE, 0xDCD1,
+	0x82CF, 0xCBD5, 0x82D0, 0xC66C, 0x82D1, 0xD4B7, 0x82D2, 0xDCDB,
+	0x82D3, 0xDCDF, 0x82D4, 0xCCA6, 0x82D5, 0xDCE6, 0x82D6, 0xC66D,
+	0x82D7, 0xC3E7, 0x82D8, 0xDCDC, 0x82D9, 0xC66E, 0x82DA, 0xC66F,
+	0x82DB, 0xBFC1, 0x82DC, 0xDCD9, 0x82DD, 0xC670, 0x82DE, 0xB0FA,
+	0x82DF, 0xB9B6, 0x82E0, 0xDCE5, 0x82E1, 0xDCD3, 0x82E2, 0xC671,
+	0x82E3, 0xDCC4, 0x82E4, 0xDCD6, 0x82E5, 0xC8F4, 0x82E6, 0xBFE0,
+	0x82E7, 0xC672, 0x82E8, 0xC673, 0x82E9, 0xC674, 0x82EA, 0xC675,
+	0x82EB, 0xC9BB, 0x82EC, 0xC676, 0x82ED, 0xC677, 0x82EE, 0xC678,
+	0x82EF, 0xB1BD, 0x82F0, 0xC679, 0x82F1, 0xD3A2, 0x82F2, 0xC67A,
+	0x82F3, 0xC67B, 0x82F4, 0xDCDA, 0x82F5, 0xC67C, 0x82F6, 0xC67D,
+	0x82F7, 0xDCD5, 0x82F8, 0xC67E, 0x82F9, 0xC6BB, 0x82FA, 0xC680,
+	0x82FB, 0xDCDE, 0x82FC, 0xC681, 0x82FD, 0xC682, 0x82FE, 0xC683,
+	0x82FF, 0xC684, 0x8300, 0xC685, 0x8301, 0xD7C2, 0x8302, 0xC3AF,
+	0x8303, 0xB7B6, 0x8304, 0xC7D1, 0x8305, 0xC3A9, 0x8306, 0xDCE2,
+	0x8307, 0xDCD8, 0x8308, 0xDCEB, 0x8309, 0xDCD4, 0x830A, 0xC686,
+	0x830B, 0xC687, 0x830C, 0xDCDD, 0x830D, 0xC688, 0x830E, 0xBEA5,
+	0x830F, 0xDCD7, 0x8310, 0xC689, 0x8311, 0xDCE0, 0x8312, 0xC68A,
+	0x8313, 0xC68B, 0x8314, 0xDCE3, 0x8315, 0xDCE4, 0x8316, 0xC68C,
+	0x8317, 0xDCF8, 0x8318, 0xC68D, 0x8319, 0xC68E, 0x831A, 0xDCE1,
+	0x831B, 0xDDA2, 0x831C, 0xDCE7, 0x831D, 0xC68F, 0x831E, 0xC690,
+	0x831F, 0xC691, 0x8320, 0xC692, 0x8321, 0xC693, 0x8322, 0xC694,
+	0x8323, 0xC695, 0x8324, 0xC696, 0x8325, 0xC697, 0x8326, 0xC698,
+	0x8327, 0xBCEB, 0x8328, 0xB4C4, 0x8329, 0xC699, 0x832A, 0xC69A,
+	0x832B, 0xC3A3, 0x832C, 0xB2E7, 0x832D, 0xDCFA, 0x832E, 0xC69B,
+	0x832F, 0xDCF2, 0x8330, 0xC69C, 0x8331, 0xDCEF, 0x8332, 0xC69D,
+	0x8333, 0xDCFC, 0x8334, 0xDCEE, 0x8335, 0xD2F0, 0x8336, 0xB2E8,
+	0x8337, 0xC69E, 0x8338, 0xC8D7, 0x8339, 0xC8E3, 0x833A, 0xDCFB,
+	0x833B, 0xC69F, 0x833C, 0xDCED, 0x833D, 0xC6A0, 0x833E, 0xC740,
+	0x833F, 0xC741, 0x8340, 0xDCF7, 0x8341, 0xC742, 0x8342, 0xC743,
+	0x8343, 0xDCF5, 0x8344, 0xC744, 0x8345, 0xC745, 0x8346, 0xBEA3,
+	0x8347, 0xDCF4, 0x8348, 0xC746, 0x8349, 0xB2DD, 0x834A, 0xC747,
+	0x834B, 0xC748, 0x834C, 0xC749, 0x834D, 0xC74A, 0x834E, 0xC74B,
+	0x834F, 0xDCF3, 0x8350, 0xBCF6, 0x8351, 0xDCE8, 0x8352, 0xBBC4,
+	0x8353, 0xC74C, 0x8354, 0xC0F3, 0x8355, 0xC74D, 0x8356, 0xC74E,
+	0x8357, 0xC74F, 0x8358, 0xC750, 0x8359, 0xC751, 0x835A, 0xBCD4,
+	0x835B, 0xDCE9, 0x835C, 0xDCEA, 0x835D, 0xC752, 0x835E, 0xDCF1,
+	0x835F, 0xDCF6, 0x8360, 0xDCF9, 0x8361, 0xB5B4, 0x8362, 0xC753,
+	0x8363, 0xC8D9, 0x8364, 0xBBE7, 0x8365, 0xDCFE, 0x8366, 0xDCFD,
+	0x8367, 0xD3AB, 0x8368, 0xDDA1, 0x8369, 0xDDA3, 0x836A, 0xDDA5,
+	0x836B, 0xD2F1, 0x836C, 0xDDA4, 0x836D, 0xDDA6, 0x836E, 0xDDA7,
+	0x836F, 0xD2A9, 0x8370, 0xC754, 0x8371, 0xC755, 0x8372, 0xC756,
+	0x8373, 0xC757, 0x8374, 0xC758, 0x8375, 0xC759, 0x8376, 0xC75A,
+	0x8377, 0xBAC9, 0x8378, 0xDDA9, 0x8379, 0xC75B, 0x837A, 0xC75C,
+	0x837B, 0xDDB6, 0x837C, 0xDDB1, 0x837D, 0xDDB4, 0x837E, 0xC75D,
+	0x837F, 0xC75E, 0x8380, 0xC75F, 0x8381, 0xC760, 0x8382, 0xC761,
+	0x8383, 0xC762, 0x8384, 0xC763, 0x8385, 0xDDB0, 0x8386, 0xC6CE,
+	0x8387, 0xC764, 0x8388, 0xC765, 0x8389, 0xC0F2, 0x838A, 0xC766,
+	0x838B, 0xC767, 0x838C, 0xC768, 0x838D, 0xC769, 0x838E, 0xC9AF,
+	0x838F, 0xC76A, 0x8390, 0xC76B, 0x8391, 0xC76C, 0x8392, 0xDCEC,
+	0x8393, 0xDDAE, 0x8394, 0xC76D, 0x8395, 0xC76E, 0x8396, 0xC76F,
+	0x8397, 0xC770, 0x8398, 0xDDB7, 0x8399, 0xC771, 0x839A, 0xC772,
+	0x839B, 0xDCF0, 0x839C, 0xDDAF, 0x839D, 0xC773, 0x839E, 0xDDB8,
+	0x839F, 0xC774, 0x83A0, 0xDDAC, 0x83A1, 0xC775, 0x83A2, 0xC776,
+	0x83A3, 0xC777, 0x83A4, 0xC778, 0x83A5, 0xC779, 0x83A6, 0xC77A,
+	0x83A7, 0xC77B, 0x83A8, 0xDDB9, 0x83A9, 0xDDB3, 0x83AA, 0xDDAD,
+	0x83AB, 0xC4AA, 0x83AC, 0xC77C, 0x83AD, 0xC77D, 0x83AE, 0xC77E,
+	0x83AF, 0xC780, 0x83B0, 0xDDA8, 0x83B1, 0xC0B3, 0x83B2, 0xC1AB,
+	0x83B3, 0xDDAA, 0x83B4, 0xDDAB, 0x83B5, 0xC781, 0x83B6, 0xDDB2,
+	0x83B7, 0xBBF1, 0x83B8, 0xDDB5, 0x83B9, 0xD3A8, 0x83BA, 0xDDBA,
+	0x83BB, 0xC782, 0x83BC, 0xDDBB, 0x83BD, 0xC3A7, 0x83BE, 0xC783,
+	0x83BF, 0xC784, 0x83C0, 0xDDD2, 0x83C1, 0xDDBC, 0x83C2, 0xC785,
+	0x83C3, 0xC786, 0x83C4, 0xC787, 0x83C5, 0xDDD1, 0x83C6, 0xC788,
+	0x83C7, 0xB9BD, 0x83C8, 0xC789, 0x83C9, 0xC78A, 0x83CA, 0xBED5,
+	0x83CB, 0xC78B, 0x83CC, 0xBEFA, 0x83CD, 0xC78C, 0x83CE, 0xC78D,
+	0x83CF, 0xBACA, 0x83D0, 0xC78E, 0x83D1, 0xC78F, 0x83D2, 0xC790,
+	0x83D3, 0xC791, 0x83D4, 0xDDCA, 0x83D5, 0xC792, 0x83D6, 0xDDC5,
+	0x83D7, 0xC793, 0x83D8, 0xDDBF, 0x83D9, 0xC794, 0x83DA, 0xC795,
+	0x83DB, 0xC796, 0x83DC, 0xB2CB, 0x83DD, 0xDDC3, 0x83DE, 0xC797,
+	0x83DF, 0xDDCB, 0x83E0, 0xB2A4, 0x83E1, 0xDDD5, 0x83E2, 0xC798,
+	0x83E3, 0xC799, 0x83E4, 0xC79A, 0x83E5, 0xDDBE, 0x83E6, 0xC79B,
+	0x83E7, 0xC79C, 0x83E8, 0xC79D, 0x83E9, 0xC6D0, 0x83EA, 0xDDD0,
+	0x83EB, 0xC79E, 0x83EC, 0xC79F, 0x83ED, 0xC7A0, 0x83EE, 0xC840,
+	0x83EF, 0xC841, 0x83F0, 0xDDD4, 0x83F1, 0xC1E2, 0x83F2, 0xB7C6,
+	0x83F3, 0xC842, 0x83F4, 0xC843, 0x83F5, 0xC844, 0x83F6, 0xC845,
+	0x83F7, 0xC846, 0x83F8, 0xDDCE, 0x83F9, 0xDDCF, 0x83FA, 0xC847,
+	0x83FB, 0xC848, 0x83FC, 0xC849, 0x83FD, 0xDDC4, 0x83FE, 0xC84A,
+	0x83FF, 0xC84B, 0x8400, 0xC84C, 0x8401, 0xDDBD, 0x8402, 0xC84D,
+	0x8403, 0xDDCD, 0x8404, 0xCCD1, 0x8405, 0xC84E, 0x8406, 0xDDC9,
+	0x8407, 0xC84F, 0x8408, 0xC850, 0x8409, 0xC851, 0x840A, 0xC852,
+	0x840B, 0xDDC2, 0x840C, 0xC3C8, 0x840D, 0xC6BC, 0x840E, 0xCEAE,
+	0x840F, 0xDDCC, 0x8410, 0xC853, 0x8411, 0xDDC8, 0x8412, 0xC854,
+	0x8413, 0xC855, 0x8414, 0xC856, 0x8415, 0xC857, 0x8416, 0xC858,
+	0x8417, 0xC859, 0x8418, 0xDDC1, 0x8419, 0xC85A, 0x841A, 0xC85B,
+	0x841B, 0xC85C, 0x841C, 0xDDC6, 0x841D, 0xC2DC, 0x841E, 0xC85D,
+	0x841F, 0xC85E, 0x8420, 0xC85F, 0x8421, 0xC860, 0x8422, 0xC861,
+	0x8423, 0xC862, 0x8424, 0xD3A9, 0x8425, 0xD3AA, 0x8426, 0xDDD3,
+	0x8427, 0xCFF4, 0x8428, 0xC8F8, 0x8429, 0xC863, 0x842A, 0xC864,
+	0x842B, 0xC865, 0x842C, 0xC866, 0x842D, 0xC867, 0x842E, 0xC868,
+	0x842F, 0xC869, 0x8430, 0xC86A, 0x8431, 0xDDE6, 0x8432, 0xC86B,
+	0x8433, 0xC86C, 0x8434, 0xC86D, 0x8435, 0xC86E, 0x8436, 0xC86F,
+	0x8437, 0xC870, 0x8438, 0xDDC7, 0x8439, 0xC871, 0x843A, 0xC872,
+	0x843B, 0xC873, 0x843C, 0xDDE0, 0x843D, 0xC2E4, 0x843E, 0xC874,
+	0x843F, 0xC875, 0x8440, 0xC876, 0x8441, 0xC877, 0x8442, 0xC878,
+	0x8443, 0xC879, 0x8444, 0xC87A, 0x8445, 0xC87B, 0x8446, 0xDDE1,
+	0x8447, 0xC87C, 0x8448, 0xC87D, 0x8449, 0xC87E, 0x844A, 0xC880,
+	0x844B, 0xC881, 0x844C, 0xC882, 0x844D, 0xC883, 0x844E, 0xC884,
+	0x844F, 0xC885, 0x8450, 0xC886, 0x8451, 0xDDD7, 0x8452, 0xC887,
+	0x8453, 0xC888, 0x8454, 0xC889, 0x8455, 0xC88A, 0x8456, 0xC88B,
+	0x8457, 0xD6F8, 0x8458, 0xC88C, 0x8459, 0xDDD9, 0x845A, 0xDDD8,
+	0x845B, 0xB8F0, 0x845C, 0xDDD6, 0x845D, 0xC88D, 0x845E, 0xC88E,
+	0x845F, 0xC88F, 0x8460, 0xC890, 0x8461, 0xC6CF, 0x8462, 0xC891,
+	0x8463, 0xB6AD, 0x8464, 0xC892, 0x8465, 0xC893, 0x8466, 0xC894,
+	0x8467, 0xC895, 0x8468, 0xC896, 0x8469, 0xDDE2, 0x846A, 0xC897,
+	0x846B, 0xBAF9, 0x846C, 0xD4E1, 0x846D, 0xDDE7, 0x846E, 0xC898,
+	0x846F, 0xC899, 0x8470, 0xC89A, 0x8471, 0xB4D0, 0x8472, 0xC89B,
+	0x8473, 0xDDDA, 0x8474, 0xC89C, 0x8475, 0xBFFB, 0x8476, 0xDDE3,
+	0x8477, 0xC89D, 0x8478, 0xDDDF, 0x8479, 0xC89E, 0x847A, 0xDDDD,
+	0x847B, 0xC89F, 0x847C, 0xC8A0, 0x847D, 0xC940, 0x847E, 0xC941,
+	0x847F, 0xC942, 0x8480, 0xC943, 0x8481, 0xC944, 0x8482, 0xB5D9,
+	0x8483, 0xC945, 0x8484, 0xC946, 0x8485, 0xC947, 0x8486, 0xC948,
+	0x8487, 0xDDDB, 0x8488, 0xDDDC, 0x8489, 0xDDDE, 0x848A, 0xC949,
+	0x848B, 0xBDAF, 0x848C, 0xDDE4, 0x848D, 0xC94A, 0x848E, 0xDDE5,
+	0x848F, 0xC94B, 0x8490, 0xC94C, 0x8491, 0xC94D, 0x8492, 0xC94E,
+	0x8493, 0xC94F, 0x8494, 0xC950, 0x8495, 0xC951, 0x8496, 0xC952,
+	0x8497, 0xDDF5, 0x8498, 0xC953, 0x8499, 0xC3C9, 0x849A, 0xC954,
+	0x849B, 0xC955, 0x849C, 0xCBE2, 0x849D, 0xC956, 0x849E, 0xC957,
+	0x849F, 0xC958, 0x84A0, 0xC959, 0x84A1, 0xDDF2, 0x84A2, 0xC95A,
+	0x84A3, 0xC95B, 0x84A4, 0xC95C, 0x84A5, 0xC95D, 0x84A6, 0xC95E,
+	0x84A7, 0xC95F, 0x84A8, 0xC960, 0x84A9, 0xC961, 0x84AA, 0xC962,
+	0x84AB, 0xC963, 0x84AC, 0xC964, 0x84AD, 0xC965, 0x84AE, 0xC966,
+	0x84AF, 0xD8E1, 0x84B0, 0xC967, 0x84B1, 0xC968, 0x84B2, 0xC6D1,
+	0x84B3, 0xC969, 0x84B4, 0xDDF4, 0x84B5, 0xC96A, 0x84B6, 0xC96B,
+	0x84B7, 0xC96C, 0x84B8, 0xD5F4, 0x84B9, 0xDDF3, 0x84BA, 0xDDF0,
+	0x84BB, 0xC96D, 0x84BC, 0xC96E, 0x84BD, 0xDDEC, 0x84BE, 0xC96F,
+	0x84BF, 0xDDEF, 0x84C0, 0xC970, 0x84C1, 0xDDE8, 0x84C2, 0xC971,
+	0x84C3, 0xC972, 0x84C4, 0xD0EE, 0x84C5, 0xC973, 0x84C6, 0xC974,
+	0x84C7, 0xC975, 0x84C8, 0xC976, 0x84C9, 0xC8D8, 0x84CA, 0xDDEE,
+	0x84CB, 0xC977, 0x84CC, 0xC978, 0x84CD, 0xDDE9, 0x84CE, 0xC979,
+	0x84CF, 0xC97A, 0x84D0, 0xDDEA, 0x84D1, 0xCBF2, 0x84D2, 0xC97B,
+	0x84D3, 0xDDED, 0x84D4, 0xC97C, 0x84D5, 0xC97D, 0x84D6, 0xB1CD,
+	0x84D7, 0xC97E, 0x84D8, 0xC980, 0x84D9, 0xC981, 0x84DA, 0xC982,
+	0x84DB, 0xC983, 0x84DC, 0xC984, 0x84DD, 0xC0B6, 0x84DE, 0xC985,
+	0x84DF, 0xBCBB, 0x84E0, 0xDDF1, 0x84E1, 0xC986, 0x84E2, 0xC987,
+	0x84E3, 0xDDF7, 0x84E4, 0xC988, 0x84E5, 0xDDF6, 0x84E6, 0xDDEB,
+	0x84E7, 0xC989, 0x84E8, 0xC98A, 0x84E9, 0xC98B, 0x84EA, 0xC98C,
+	0x84EB, 0xC98D, 0x84EC, 0xC5EE, 0x84ED, 0xC98E, 0x84EE, 0xC98F,
+	0x84EF, 0xC990, 0x84F0, 0xDDFB, 0x84F1, 0xC991, 0x84F2, 0xC992,
+	0x84F3, 0xC993, 0x84F4, 0xC994, 0x84F5, 0xC995, 0x84F6, 0xC996,
+	0x84F7, 0xC997, 0x84F8, 0xC998, 0x84F9, 0xC999, 0x84FA, 0xC99A,
+	0x84FB, 0xC99B, 0x84FC, 0xDEA4, 0x84FD, 0xC99C, 0x84FE, 0xC99D,
+	0x84FF, 0xDEA3, 0x8500, 0xC99E, 0x8501, 0xC99F, 0x8502, 0xC9A0,
+	0x8503, 0xCA40, 0x8504, 0xCA41, 0x8505, 0xCA42, 0x8506, 0xCA43,
+	0x8507, 0xCA44, 0x8508, 0xCA45, 0x8509, 0xCA46, 0x850A, 0xCA47,
+	0x850B, 0xCA48, 0x850C, 0xDDF8, 0x850D, 0xCA49, 0x850E, 0xCA4A,
+	0x850F, 0xCA4B, 0x8510, 0xCA4C, 0x8511, 0xC3EF, 0x8512, 0xCA4D,
+	0x8513, 0xC2FB, 0x8514, 0xCA4E, 0x8515, 0xCA4F, 0x8516, 0xCA50,
+	0x8517, 0xD5E1, 0x8518, 0xCA51, 0x8519, 0xCA52, 0x851A, 0xCEB5,
+	0x851B, 0xCA53, 0x851C, 0xCA54, 0x851D, 0xCA55, 0x851E, 0xCA56,
+	0x851F, 0xDDFD, 0x8520, 0xCA57, 0x8521, 0xB2CC, 0x8522, 0xCA58,
+	0x8523, 0xCA59, 0x8524, 0xCA5A, 0x8525, 0xCA5B, 0x8526, 0xCA5C,
+	0x8527, 0xCA5D, 0x8528, 0xCA5E, 0x8529, 0xCA5F, 0x852A, 0xCA60,
+	0x852B, 0xC4E8, 0x852C, 0xCADF, 0x852D, 0xCA61, 0x852E, 0xCA62,
+	0x852F, 0xCA63, 0x8530, 0xCA64, 0x8531, 0xCA65, 0x8532, 0xCA66,
+	0x8533, 0xCA67, 0x8534, 0xCA68, 0x8535, 0xCA69, 0x8536, 0xCA6A,
+	0x8537, 0xC7BE, 0x8538, 0xDDFA, 0x8539, 0xDDFC, 0x853A, 0xDDFE,
+	0x853B, 0xDEA2, 0x853C, 0xB0AA, 0x853D, 0xB1CE, 0x853E, 0xCA6B,
+	0x853F, 0xCA6C, 0x8540, 0xCA6D, 0x8541, 0xCA6E, 0x8542, 0xCA6F,
+	0x8543, 0xDEAC, 0x8544, 0xCA70, 0x8545, 0xCA71, 0x8546, 0xCA72,
+	0x8547, 0xCA73, 0x8548, 0xDEA6, 0x8549, 0xBDB6, 0x854A, 0xC8EF,
+	0x854B, 0xCA74, 0x854C, 0xCA75, 0x854D, 0xCA76, 0x854E, 0xCA77,
+	0x854F, 0xCA78, 0x8550, 0xCA79, 0x8551, 0xCA7A, 0x8552, 0xCA7B,
+	0x8553, 0xCA7C, 0x8554, 0xCA7D, 0x8555, 0xCA7E, 0x8556, 0xDEA1,
+	0x8557, 0xCA80, 0x8558, 0xCA81, 0x8559, 0xDEA5, 0x855A, 0xCA82,
+	0x855B, 0xCA83, 0x855C, 0xCA84, 0x855D, 0xCA85, 0x855E, 0xDEA9,
+	0x855F, 0xCA86, 0x8560, 0xCA87, 0x8561, 0xCA88, 0x8562, 0xCA89,
+	0x8563, 0xCA8A, 0x8564, 0xDEA8, 0x8565, 0xCA8B, 0x8566, 0xCA8C,
+	0x8567, 0xCA8D, 0x8568, 0xDEA7, 0x8569, 0xCA8E, 0x856A, 0xCA8F,
+	0x856B, 0xCA90, 0x856C, 0xCA91, 0x856D, 0xCA92, 0x856E, 0xCA93,
+	0x856F, 0xCA94, 0x8570, 0xCA95, 0x8571, 0xCA96, 0x8572, 0xDEAD,
+	0x8573, 0xCA97, 0x8574, 0xD4CC, 0x8575, 0xCA98, 0x8576, 0xCA99,
+	0x8577, 0xCA9A, 0x8578, 0xCA9B, 0x8579, 0xDEB3, 0x857A, 0xDEAA,
+	0x857B, 0xDEAE, 0x857C, 0xCA9C, 0x857D, 0xCA9D, 0x857E, 0xC0D9,
+	0x857F, 0xCA9E, 0x8580, 0xCA9F, 0x8581, 0xCAA0, 0x8582, 0xCB40,
+	0x8583, 0xCB41, 0x8584, 0xB1A1, 0x8585, 0xDEB6, 0x8586, 0xCB42,
+	0x8587, 0xDEB1, 0x8588, 0xCB43, 0x8589, 0xCB44, 0x858A, 0xCB45,
+	0x858B, 0xCB46, 0x858C, 0xCB47, 0x858D, 0xCB48, 0x858E, 0xCB49,
+	0x858F, 0xDEB2, 0x8590, 0xCB4A, 0x8591, 0xCB4B, 0x8592, 0xCB4C,
+	0x8593, 0xCB4D, 0x8594, 0xCB4E, 0x8595, 0xCB4F, 0x8596, 0xCB50,
+	0x8597, 0xCB51, 0x8598, 0xCB52, 0x8599, 0xCB53, 0x859A, 0xCB54,
+	0x859B, 0xD1A6, 0x859C, 0xDEB5, 0x859D, 0xCB55, 0x859E, 0xCB56,
+	0x859F, 0xCB57, 0x85A0, 0xCB58, 0x85A1, 0xCB59, 0x85A2, 0xCB5A,
+	0x85A3, 0xCB5B, 0x85A4, 0xDEAF, 0x85A5, 0xCB5C, 0x85A6, 0xCB5D,
+	0x85A7, 0xCB5E, 0x85A8, 0xDEB0, 0x85A9, 0xCB5F, 0x85AA, 0xD0BD,
+	0x85AB, 0xCB60, 0x85AC, 0xCB61, 0x85AD, 0xCB62, 0x85AE, 0xDEB4,
+	0x85AF, 0xCAED, 0x85B0, 0xDEB9, 0x85B1, 0xCB63, 0x85B2, 0xCB64,
+	0x85B3, 0xCB65, 0x85B4, 0xCB66, 0x85B5, 0xCB67, 0x85B6, 0xCB68,
+	0x85B7, 0xDEB8, 0x85B8, 0xCB69, 0x85B9, 0xDEB7, 0x85BA, 0xCB6A,
+	0x85BB, 0xCB6B, 0x85BC, 0xCB6C, 0x85BD, 0xCB6D, 0x85BE, 0xCB6E,
+	0x85BF, 0xCB6F, 0x85C0, 0xCB70, 0x85C1, 0xDEBB, 0x85C2, 0xCB71,
+	0x85C3, 0xCB72, 0x85C4, 0xCB73, 0x85C5, 0xCB74, 0x85C6, 0xCB75,
+	0x85C7, 0xCB76, 0x85C8, 0xCB77, 0x85C9, 0xBDE5, 0x85CA, 0xCB78,
+	0x85CB, 0xCB79, 0x85CC, 0xCB7A, 0x85CD, 0xCB7B, 0x85CE, 0xCB7C,
+	0x85CF, 0xB2D8, 0x85D0, 0xC3EA, 0x85D1, 0xCB7D, 0x85D2, 0xCB7E,
+	0x85D3, 0xDEBA, 0x85D4, 0xCB80, 0x85D5, 0xC5BA, 0x85D6, 0xCB81,
+	0x85D7, 0xCB82, 0x85D8, 0xCB83, 0x85D9, 0xCB84, 0x85DA, 0xCB85,
+	0x85DB, 0xCB86, 0x85DC, 0xDEBC, 0x85DD, 0xCB87, 0x85DE, 0xCB88,
+	0x85DF, 0xCB89, 0x85E0, 0xCB8A, 0x85E1, 0xCB8B, 0x85E2, 0xCB8C,
+	0x85E3, 0xCB8D, 0x85E4, 0xCCD9, 0x85E5, 0xCB8E, 0x85E6, 0xCB8F,
+	0x85E7, 0xCB90, 0x85E8, 0xCB91, 0x85E9, 0xB7AA, 0x85EA, 0xCB92,
+	0x85EB, 0xCB93, 0x85EC, 0xCB94, 0x85ED, 0xCB95, 0x85EE, 0xCB96,
+	0x85EF, 0xCB97, 0x85F0, 0xCB98, 0x85F1, 0xCB99, 0x85F2, 0xCB9A,
+	0x85F3, 0xCB9B, 0x85F4, 0xCB9C, 0x85F5, 0xCB9D, 0x85F6, 0xCB9E,
+	0x85F7, 0xCB9F, 0x85F8, 0xCBA0, 0x85F9, 0xCC40, 0x85FA, 0xCC41,
+	0x85FB, 0xD4E5, 0x85FC, 0xCC42, 0x85FD, 0xCC43, 0x85FE, 0xCC44,
+	0x85FF, 0xDEBD, 0x8600, 0xCC45, 0x8601, 0xCC46, 0x8602, 0xCC47,
+	0x8603, 0xCC48, 0x8604, 0xCC49, 0x8605, 0xDEBF, 0x8606, 0xCC4A,
+	0x8607, 0xCC4B, 0x8608, 0xCC4C, 0x8609, 0xCC4D, 0x860A, 0xCC4E,
+	0x860B, 0xCC4F, 0x860C, 0xCC50, 0x860D, 0xCC51, 0x860E, 0xCC52,
+	0x860F, 0xCC53, 0x8610, 0xCC54, 0x8611, 0xC4A2, 0x8612, 0xCC55,
+	0x8613, 0xCC56, 0x8614, 0xCC57, 0x8615, 0xCC58, 0x8616, 0xDEC1,
+	0x8617, 0xCC59, 0x8618, 0xCC5A, 0x8619, 0xCC5B, 0x861A, 0xCC5C,
+	0x861B, 0xCC5D, 0x861C, 0xCC5E, 0x861D, 0xCC5F, 0x861E, 0xCC60,
+	0x861F, 0xCC61, 0x8620, 0xCC62, 0x8621, 0xCC63, 0x8622, 0xCC64,
+	0x8623, 0xCC65, 0x8624, 0xCC66, 0x8625, 0xCC67, 0x8626, 0xCC68,
+	0x8627, 0xDEBE, 0x8628, 0xCC69, 0x8629, 0xDEC0, 0x862A, 0xCC6A,
+	0x862B, 0xCC6B, 0x862C, 0xCC6C, 0x862D, 0xCC6D, 0x862E, 0xCC6E,
+	0x862F, 0xCC6F, 0x8630, 0xCC70, 0x8631, 0xCC71, 0x8632, 0xCC72,
+	0x8633, 0xCC73, 0x8634, 0xCC74, 0x8635, 0xCC75, 0x8636, 0xCC76,
+	0x8637, 0xCC77, 0x8638, 0xD5BA, 0x8639, 0xCC78, 0x863A, 0xCC79,
+	0x863B, 0xCC7A, 0x863C, 0xDEC2, 0x863D, 0xCC7B, 0x863E, 0xCC7C,
+	0x863F, 0xCC7D, 0x8640, 0xCC7E, 0x8641, 0xCC80, 0x8642, 0xCC81,
+	0x8643, 0xCC82, 0x8644, 0xCC83, 0x8645, 0xCC84, 0x8646, 0xCC85,
+	0x8647, 0xCC86, 0x8648, 0xCC87, 0x8649, 0xCC88, 0x864A, 0xCC89,
+	0x864B, 0xCC8A, 0x864C, 0xCC8B, 0x864D, 0xF2AE, 0x864E, 0xBBA2,
+	0x864F, 0xC2B2, 0x8650, 0xC5B0, 0x8651, 0xC2C7, 0x8652, 0xCC8C,
+	0x8653, 0xCC8D, 0x8654, 0xF2AF, 0x8655, 0xCC8E, 0x8656, 0xCC8F,
+	0x8657, 0xCC90, 0x8658, 0xCC91, 0x8659, 0xCC92, 0x865A, 0xD0E9,
+	0x865B, 0xCC93, 0x865C, 0xCC94, 0x865D, 0xCC95, 0x865E, 0xD3DD,
+	0x865F, 0xCC96, 0x8660, 0xCC97, 0x8661, 0xCC98, 0x8662, 0xEBBD,
+	0x8663, 0xCC99, 0x8664, 0xCC9A, 0x8665, 0xCC9B, 0x8666, 0xCC9C,
+	0x8667, 0xCC9D, 0x8668, 0xCC9E, 0x8669, 0xCC9F, 0x866A, 0xCCA0,
+	0x866B, 0xB3E6, 0x866C, 0xF2B0, 0x866D, 0xCD40, 0x866E, 0xF2B1,
+	0x866F, 0xCD41, 0x8670, 0xCD42, 0x8671, 0xCAAD, 0x8672, 0xCD43,
+	0x8673, 0xCD44, 0x8674, 0xCD45, 0x8675, 0xCD46, 0x8676, 0xCD47,
+	0x8677, 0xCD48, 0x8678, 0xCD49, 0x8679, 0xBAE7, 0x867A, 0xF2B3,
+	0x867B, 0xF2B5, 0x867C, 0xF2B4, 0x867D, 0xCBE4, 0x867E, 0xCFBA,
+	0x867F, 0xF2B2, 0x8680, 0xCAB4, 0x8681, 0xD2CF, 0x8682, 0xC2EC,
+	0x8683, 0xCD4A, 0x8684, 0xCD4B, 0x8685, 0xCD4C, 0x8686, 0xCD4D,
+	0x8687, 0xCD4E, 0x8688, 0xCD4F, 0x8689, 0xCD50, 0x868A, 0xCEC3,
+	0x868B, 0xF2B8, 0x868C, 0xB0F6, 0x868D, 0xF2B7, 0x868E, 0xCD51,
+	0x868F, 0xCD52, 0x8690, 0xCD53, 0x8691, 0xCD54, 0x8692, 0xCD55,
+	0x8693, 0xF2BE, 0x8694, 0xCD56, 0x8695, 0xB2CF, 0x8696, 0xCD57,
+	0x8697, 0xCD58, 0x8698, 0xCD59, 0x8699, 0xCD5A, 0x869A, 0xCD5B,
+	0x869B, 0xCD5C, 0x869C, 0xD1C1, 0x869D, 0xF2BA, 0x869E, 0xCD5D,
+	0x869F, 0xCD5E, 0x86A0, 0xCD5F, 0x86A1, 0xCD60, 0x86A2, 0xCD61,
+	0x86A3, 0xF2BC, 0x86A4, 0xD4E9, 0x86A5, 0xCD62, 0x86A6, 0xCD63,
+	0x86A7, 0xF2BB, 0x86A8, 0xF2B6, 0x86A9, 0xF2BF, 0x86AA, 0xF2BD,
+	0x86AB, 0xCD64, 0x86AC, 0xF2B9, 0x86AD, 0xCD65, 0x86AE, 0xCD66,
+	0x86AF, 0xF2C7, 0x86B0, 0xF2C4, 0x86B1, 0xF2C6, 0x86B2, 0xCD67,
+	0x86B3, 0xCD68, 0x86B4, 0xF2CA, 0x86B5, 0xF2C2, 0x86B6, 0xF2C0,
+	0x86B7, 0xCD69, 0x86B8, 0xCD6A, 0x86B9, 0xCD6B, 0x86BA, 0xF2C5,
+	0x86BB, 0xCD6C, 0x86BC, 0xCD6D, 0x86BD, 0xCD6E, 0x86BE, 0xCD6F,
+	0x86BF, 0xCD70, 0x86C0, 0xD6FB, 0x86C1, 0xCD71, 0x86C2, 0xCD72,
+	0x86C3, 0xCD73, 0x86C4, 0xF2C1, 0x86C5, 0xCD74, 0x86C6, 0xC7F9,
+	0x86C7, 0xC9DF, 0x86C8, 0xCD75, 0x86C9, 0xF2C8, 0x86CA, 0xB9C6,
+	0x86CB, 0xB5B0, 0x86CC, 0xCD76, 0x86CD, 0xCD77, 0x86CE, 0xF2C3,
+	0x86CF, 0xF2C9, 0x86D0, 0xF2D0, 0x86D1, 0xF2D6, 0x86D2, 0xCD78,
+	0x86D3, 0xCD79, 0x86D4, 0xBBD7, 0x86D5, 0xCD7A, 0x86D6, 0xCD7B,
+	0x86D7, 0xCD7C, 0x86D8, 0xF2D5, 0x86D9, 0xCDDC, 0x86DA, 0xCD7D,
+	0x86DB, 0xD6EB, 0x86DC, 0xCD7E, 0x86DD, 0xCD80, 0x86DE, 0xF2D2,
+	0x86DF, 0xF2D4, 0x86E0, 0xCD81, 0x86E1, 0xCD82, 0x86E2, 0xCD83,
+	0x86E3, 0xCD84, 0x86E4, 0xB8F2, 0x86E5, 0xCD85, 0x86E6, 0xCD86,
+	0x86E7, 0xCD87, 0x86E8, 0xCD88, 0x86E9, 0xF2CB, 0x86EA, 0xCD89,
+	0x86EB, 0xCD8A, 0x86EC, 0xCD8B, 0x86ED, 0xF2CE, 0x86EE, 0xC2F9,
+	0x86EF, 0xCD8C, 0x86F0, 0xD5DD, 0x86F1, 0xF2CC, 0x86F2, 0xF2CD,
+	0x86F3, 0xF2CF, 0x86F4, 0xF2D3, 0x86F5, 0xCD8D, 0x86F6, 0xCD8E,
+	0x86F7, 0xCD8F, 0x86F8, 0xF2D9, 0x86F9, 0xD3BC, 0x86FA, 0xCD90,
+	0x86FB, 0xCD91, 0x86FC, 0xCD92, 0x86FD, 0xCD93, 0x86FE, 0xB6EA,
+	0x86FF, 0xCD94, 0x8700, 0xCAF1, 0x8701, 0xCD95, 0x8702, 0xB7E4,
+	0x8703, 0xF2D7, 0x8704, 0xCD96, 0x8705, 0xCD97, 0x8706, 0xCD98,
+	0x8707, 0xF2D8, 0x8708, 0xF2DA, 0x8709, 0xF2DD, 0x870A, 0xF2DB,
+	0x870B, 0xCD99, 0x870C, 0xCD9A, 0x870D, 0xF2DC, 0x870E, 0xCD9B,
+	0x870F, 0xCD9C, 0x8710, 0xCD9D, 0x8711, 0xCD9E, 0x8712, 0xD1D1,
+	0x8713, 0xF2D1, 0x8714, 0xCD9F, 0x8715, 0xCDC9, 0x8716, 0xCDA0,
+	0x8717, 0xCECF, 0x8718, 0xD6A9, 0x8719, 0xCE40, 0x871A, 0xF2E3,
+	0x871B, 0xCE41, 0x871C, 0xC3DB, 0x871D, 0xCE42, 0x871E, 0xF2E0,
+	0x871F, 0xCE43, 0x8720, 0xCE44, 0x8721, 0xC0AF, 0x8722, 0xF2EC,
+	0x8723, 0xF2DE, 0x8724, 0xCE45, 0x8725, 0xF2E1, 0x8726, 0xCE46,
+	0x8727, 0xCE47, 0x8728, 0xCE48, 0x8729, 0xF2E8, 0x872A, 0xCE49,
+	0x872B, 0xCE4A, 0x872C, 0xCE4B, 0x872D, 0xCE4C, 0x872E, 0xF2E2,
+	0x872F, 0xCE4D, 0x8730, 0xCE4E, 0x8731, 0xF2E7, 0x8732, 0xCE4F,
+	0x8733, 0xCE50, 0x8734, 0xF2E6, 0x8735, 0xCE51, 0x8736, 0xCE52,
+	0x8737, 0xF2E9, 0x8738, 0xCE53, 0x8739, 0xCE54, 0x873A, 0xCE55,
+	0x873B, 0xF2DF, 0x873C, 0xCE56, 0x873D, 0xCE57, 0x873E, 0xF2E4,
+	0x873F, 0xF2EA, 0x8740, 0xCE58, 0x8741, 0xCE59, 0x8742, 0xCE5A,
+	0x8743, 0xCE5B, 0x8744, 0xCE5C, 0x8745, 0xCE5D, 0x8746, 0xCE5E,
+	0x8747, 0xD3AC, 0x8748, 0xF2E5, 0x8749, 0xB2F5, 0x874A, 0xCE5F,
+	0x874B, 0xCE60, 0x874C, 0xF2F2, 0x874D, 0xCE61, 0x874E, 0xD0AB,
+	0x874F, 0xCE62, 0x8750, 0xCE63, 0x8751, 0xCE64, 0x8752, 0xCE65,
+	0x8753, 0xF2F5, 0x8754, 0xCE66, 0x8755, 0xCE67, 0x8756, 0xCE68,
+	0x8757, 0xBBC8, 0x8758, 0xCE69, 0x8759, 0xF2F9, 0x875A, 0xCE6A,
+	0x875B, 0xCE6B, 0x875C, 0xCE6C, 0x875D, 0xCE6D, 0x875E, 0xCE6E,
+	0x875F, 0xCE6F, 0x8760, 0xF2F0, 0x8761, 0xCE70, 0x8762, 0xCE71,
+	0x8763, 0xF2F6, 0x8764, 0xF2F8, 0x8765, 0xF2FA, 0x8766, 0xCE72,
+	0x8767, 0xCE73, 0x8768, 0xCE74, 0x8769, 0xCE75, 0x876A, 0xCE76,
+	0x876B, 0xCE77, 0x876C, 0xCE78, 0x876D, 0xCE79, 0x876E, 0xF2F3,
+	0x876F, 0xCE7A, 0x8770, 0xF2F1, 0x8771, 0xCE7B, 0x8772, 0xCE7C,
+	0x8773, 0xCE7D, 0x8774, 0xBAFB, 0x8775, 0xCE7E, 0x8776, 0xB5FB,
+	0x8777, 0xCE80, 0x8778, 0xCE81, 0x8779, 0xCE82, 0x877A, 0xCE83,
+	0x877B, 0xF2EF, 0x877C, 0xF2F7, 0x877D, 0xF2ED, 0x877E, 0xF2EE,
+	0x877F, 0xCE84, 0x8780, 0xCE85, 0x8781, 0xCE86, 0x8782, 0xF2EB,
+	0x8783, 0xF3A6, 0x8784, 0xCE87, 0x8785, 0xF3A3, 0x8786, 0xCE88,
+	0x8787, 0xCE89, 0x8788, 0xF3A2, 0x8789, 0xCE8A, 0x878A, 0xCE8B,
+	0x878B, 0xF2F4, 0x878C, 0xCE8C, 0x878D, 0xC8DA, 0x878E, 0xCE8D,
+	0x878F, 0xCE8E, 0x8790, 0xCE8F, 0x8791, 0xCE90, 0x8792, 0xCE91,
+	0x8793, 0xF2FB, 0x8794, 0xCE92, 0x8795, 0xCE93, 0x8796, 0xCE94,
+	0x8797, 0xF3A5, 0x8798, 0xCE95, 0x8799, 0xCE96, 0x879A, 0xCE97,
+	0x879B, 0xCE98, 0x879C, 0xCE99, 0x879D, 0xCE9A, 0x879E, 0xCE9B,
+	0x879F, 0xC3F8, 0x87A0, 0xCE9C, 0x87A1, 0xCE9D, 0x87A2, 0xCE9E,
+	0x87A3, 0xCE9F, 0x87A4, 0xCEA0, 0x87A5, 0xCF40, 0x87A6, 0xCF41,
+	0x87A7, 0xCF42, 0x87A8, 0xF2FD, 0x87A9, 0xCF43, 0x87AA, 0xCF44,
+	0x87AB, 0xF3A7, 0x87AC, 0xF3A9, 0x87AD, 0xF3A4, 0x87AE, 0xCF45,
+	0x87AF, 0xF2FC, 0x87B0, 0xCF46, 0x87B1, 0xCF47, 0x87B2, 0xCF48,
+	0x87B3, 0xF3AB, 0x87B4, 0xCF49, 0x87B5, 0xF3AA, 0x87B6, 0xCF4A,
+	0x87B7, 0xCF4B, 0x87B8, 0xCF4C, 0x87B9, 0xCF4D, 0x87BA, 0xC2DD,
+	0x87BB, 0xCF4E, 0x87BC, 0xCF4F, 0x87BD, 0xF3AE, 0x87BE, 0xCF50,
+	0x87BF, 0xCF51, 0x87C0, 0xF3B0, 0x87C1, 0xCF52, 0x87C2, 0xCF53,
+	0x87C3, 0xCF54, 0x87C4, 0xCF55, 0x87C5, 0xCF56, 0x87C6, 0xF3A1,
+	0x87C7, 0xCF57, 0x87C8, 0xCF58, 0x87C9, 0xCF59, 0x87CA, 0xF3B1,
+	0x87CB, 0xF3AC, 0x87CC, 0xCF5A, 0x87CD, 0xCF5B, 0x87CE, 0xCF5C,
+	0x87CF, 0xCF5D, 0x87D0, 0xCF5E, 0x87D1, 0xF3AF, 0x87D2, 0xF2FE,
+	0x87D3, 0xF3AD, 0x87D4, 0xCF5F, 0x87D5, 0xCF60, 0x87D6, 0xCF61,
+	0x87D7, 0xCF62, 0x87D8, 0xCF63, 0x87D9, 0xCF64, 0x87DA, 0xCF65,
+	0x87DB, 0xF3B2, 0x87DC, 0xCF66, 0x87DD, 0xCF67, 0x87DE, 0xCF68,
+	0x87DF, 0xCF69, 0x87E0, 0xF3B4, 0x87E1, 0xCF6A, 0x87E2, 0xCF6B,
+	0x87E3, 0xCF6C, 0x87E4, 0xCF6D, 0x87E5, 0xF3A8, 0x87E6, 0xCF6E,
+	0x87E7, 0xCF6F, 0x87E8, 0xCF70, 0x87E9, 0xCF71, 0x87EA, 0xF3B3,
+	0x87EB, 0xCF72, 0x87EC, 0xCF73, 0x87ED, 0xCF74, 0x87EE, 0xF3B5,
+	0x87EF, 0xCF75, 0x87F0, 0xCF76, 0x87F1, 0xCF77, 0x87F2, 0xCF78,
+	0x87F3, 0xCF79, 0x87F4, 0xCF7A, 0x87F5, 0xCF7B, 0x87F6, 0xCF7C,
+	0x87F7, 0xCF7D, 0x87F8, 0xCF7E, 0x87F9, 0xD0B7, 0x87FA, 0xCF80,
+	0x87FB, 0xCF81, 0x87FC, 0xCF82, 0x87FD, 0xCF83, 0x87FE, 0xF3B8,
+	0x87FF, 0xCF84, 0x8800, 0xCF85, 0x8801, 0xCF86, 0x8802, 0xCF87,
+	0x8803, 0xD9F9, 0x8804, 0xCF88, 0x8805, 0xCF89, 0x8806, 0xCF8A,
+	0x8807, 0xCF8B, 0x8808, 0xCF8C, 0x8809, 0xCF8D, 0x880A, 0xF3B9,
+	0x880B, 0xCF8E, 0x880C, 0xCF8F, 0x880D, 0xCF90, 0x880E, 0xCF91,
+	0x880F, 0xCF92, 0x8810, 0xCF93, 0x8811, 0xCF94, 0x8812, 0xCF95,
+	0x8813, 0xF3B7, 0x8814, 0xCF96, 0x8815, 0xC8E4, 0x8816, 0xF3B6,
+	0x8817, 0xCF97, 0x8818, 0xCF98, 0x8819, 0xCF99, 0x881A, 0xCF9A,
+	0x881B, 0xF3BA, 0x881C, 0xCF9B, 0x881D, 0xCF9C, 0x881E, 0xCF9D,
+	0x881F, 0xCF9E, 0x8820, 0xCF9F, 0x8821, 0xF3BB, 0x8822, 0xB4C0,
+	0x8823, 0xCFA0, 0x8824, 0xD040, 0x8825, 0xD041, 0x8826, 0xD042,
+	0x8827, 0xD043, 0x8828, 0xD044, 0x8829, 0xD045, 0x882A, 0xD046,
+	0x882B, 0xD047, 0x882C, 0xD048, 0x882D, 0xD049, 0x882E, 0xD04A,
+	0x882F, 0xD04B, 0x8830, 0xD04C, 0x8831, 0xD04D, 0x8832, 0xEEC3,
+	0x8833, 0xD04E, 0x8834, 0xD04F, 0x8835, 0xD050, 0x8836, 0xD051,
+	0x8837, 0xD052, 0x8838, 0xD053, 0x8839, 0xF3BC, 0x883A, 0xD054,
+	0x883B, 0xD055, 0x883C, 0xF3BD, 0x883D, 0xD056, 0x883E, 0xD057,
+	0x883F, 0xD058, 0x8840, 0xD1AA, 0x8841, 0xD059, 0x8842, 0xD05A,
+	0x8843, 0xD05B, 0x8844, 0xF4AC, 0x8845, 0xD0C6, 0x8846, 0xD05C,
+	0x8847, 0xD05D, 0x8848, 0xD05E, 0x8849, 0xD05F, 0x884A, 0xD060,
+	0x884B, 0xD061, 0x884C, 0xD0D0, 0x884D, 0xD1DC, 0x884E, 0xD062,
+	0x884F, 0xD063, 0x8850, 0xD064, 0x8851, 0xD065, 0x8852, 0xD066,
+	0x8853, 0xD067, 0x8854, 0xCFCE, 0x8855, 0xD068, 0x8856, 0xD069,
+	0x8857, 0xBDD6, 0x8858, 0xD06A, 0x8859, 0xD1C3, 0x885A, 0xD06B,
+	0x885B, 0xD06C, 0x885C, 0xD06D, 0x885D, 0xD06E, 0x885E, 0xD06F,
+	0x885F, 0xD070, 0x8860, 0xD071, 0x8861, 0xBAE2, 0x8862, 0xE1E9,
+	0x8863, 0xD2C2, 0x8864, 0xF1C2, 0x8865, 0xB2B9, 0x8866, 0xD072,
+	0x8867, 0xD073, 0x8868, 0xB1ED, 0x8869, 0xF1C3, 0x886A, 0xD074,
+	0x886B, 0xC9C0, 0x886C, 0xB3C4, 0x886D, 0xD075, 0x886E, 0xD9F2,
+	0x886F, 0xD076, 0x8870, 0xCBA5, 0x8871, 0xD077, 0x8872, 0xF1C4,
+	0x8873, 0xD078, 0x8874, 0xD079, 0x8875, 0xD07A, 0x8876, 0xD07B,
+	0x8877, 0xD6D4, 0x8878, 0xD07C, 0x8879, 0xD07D, 0x887A, 0xD07E,
+	0x887B, 0xD080, 0x887C, 0xD081, 0x887D, 0xF1C5, 0x887E, 0xF4C0,
+	0x887F, 0xF1C6, 0x8880, 0xD082, 0x8881, 0xD4AC, 0x8882, 0xF1C7,
+	0x8883, 0xD083, 0x8884, 0xB0C0, 0x8885, 0xF4C1, 0x8886, 0xD084,
+	0x8887, 0xD085, 0x8888, 0xF4C2, 0x8889, 0xD086, 0x888A, 0xD087,
+	0x888B, 0xB4FC, 0x888C, 0xD088, 0x888D, 0xC5DB, 0x888E, 0xD089,
+	0x888F, 0xD08A, 0x8890, 0xD08B, 0x8891, 0xD08C, 0x8892, 0xCCBB,
+	0x8893, 0xD08D, 0x8894, 0xD08E, 0x8895, 0xD08F, 0x8896, 0xD0E4,
+	0x8897, 0xD090, 0x8898, 0xD091, 0x8899, 0xD092, 0x889A, 0xD093,
+	0x889B, 0xD094, 0x889C, 0xCDE0, 0x889D, 0xD095, 0x889E, 0xD096,
+	0x889F, 0xD097, 0x88A0, 0xD098, 0x88A1, 0xD099, 0x88A2, 0xF1C8,
+	0x88A3, 0xD09A, 0x88A4, 0xD9F3, 0x88A5, 0xD09B, 0x88A6, 0xD09C,
+	0x88A7, 0xD09D, 0x88A8, 0xD09E, 0x88A9, 0xD09F, 0x88AA, 0xD0A0,
+	0x88AB, 0xB1BB, 0x88AC, 0xD140, 0x88AD, 0xCFAE, 0x88AE, 0xD141,
+	0x88AF, 0xD142, 0x88B0, 0xD143, 0x88B1, 0xB8A4, 0x88B2, 0xD144,
+	0x88B3, 0xD145, 0x88B4, 0xD146, 0x88B5, 0xD147, 0x88B6, 0xD148,
+	0x88B7, 0xF1CA, 0x88B8, 0xD149, 0x88B9, 0xD14A, 0x88BA, 0xD14B,
+	0x88BB, 0xD14C, 0x88BC, 0xF1CB, 0x88BD, 0xD14D, 0x88BE, 0xD14E,
+	0x88BF, 0xD14F, 0x88C0, 0xD150, 0x88C1, 0xB2C3, 0x88C2, 0xC1D1,
+	0x88C3, 0xD151, 0x88C4, 0xD152, 0x88C5, 0xD7B0, 0x88C6, 0xF1C9,
+	0x88C7, 0xD153, 0x88C8, 0xD154, 0x88C9, 0xF1CC, 0x88CA, 0xD155,
+	0x88CB, 0xD156, 0x88CC, 0xD157, 0x88CD, 0xD158, 0x88CE, 0xF1CE,
+	0x88CF, 0xD159, 0x88D0, 0xD15A, 0x88D1, 0xD15B, 0x88D2, 0xD9F6,
+	0x88D3, 0xD15C, 0x88D4, 0xD2E1, 0x88D5, 0xD4A3, 0x88D6, 0xD15D,
+	0x88D7, 0xD15E, 0x88D8, 0xF4C3, 0x88D9, 0xC8B9, 0x88DA, 0xD15F,
+	0x88DB, 0xD160, 0x88DC, 0xD161, 0x88DD, 0xD162, 0x88DE, 0xD163,
+	0x88DF, 0xF4C4, 0x88E0, 0xD164, 0x88E1, 0xD165, 0x88E2, 0xF1CD,
+	0x88E3, 0xF1CF, 0x88E4, 0xBFE3, 0x88E5, 0xF1D0, 0x88E6, 0xD166,
+	0x88E7, 0xD167, 0x88E8, 0xF1D4, 0x88E9, 0xD168, 0x88EA, 0xD169,
+	0x88EB, 0xD16A, 0x88EC, 0xD16B, 0x88ED, 0xD16C, 0x88EE, 0xD16D,
+	0x88EF, 0xD16E, 0x88F0, 0xF1D6, 0x88F1, 0xF1D1, 0x88F2, 0xD16F,
+	0x88F3, 0xC9D1, 0x88F4, 0xC5E1, 0x88F5, 0xD170, 0x88F6, 0xD171,
+	0x88F7, 0xD172, 0x88F8, 0xC2E3, 0x88F9, 0xB9FC, 0x88FA, 0xD173,
+	0x88FB, 0xD174, 0x88FC, 0xF1D3, 0x88FD, 0xD175, 0x88FE, 0xF1D5,
+	0x88FF, 0xD176, 0x8900, 0xD177, 0x8901, 0xD178, 0x8902, 0xB9D3,
+	0x8903, 0xD179, 0x8904, 0xD17A, 0x8905, 0xD17B, 0x8906, 0xD17C,
+	0x8907, 0xD17D, 0x8908, 0xD17E, 0x8909, 0xD180, 0x890A, 0xF1DB,
+	0x890B, 0xD181, 0x890C, 0xD182, 0x890D, 0xD183, 0x890E, 0xD184,
+	0x890F, 0xD185, 0x8910, 0xBAD6, 0x8911, 0xD186, 0x8912, 0xB0FD,
+	0x8913, 0xF1D9, 0x8914, 0xD187, 0x8915, 0xD188, 0x8916, 0xD189,
+	0x8917, 0xD18A, 0x8918, 0xD18B, 0x8919, 0xF1D8, 0x891A, 0xF1D2,
+	0x891B, 0xF1DA, 0x891C, 0xD18C, 0x891D, 0xD18D, 0x891E, 0xD18E,
+	0x891F, 0xD18F, 0x8920, 0xD190, 0x8921, 0xF1D7, 0x8922, 0xD191,
+	0x8923, 0xD192, 0x8924, 0xD193, 0x8925, 0xC8EC, 0x8926, 0xD194,
+	0x8927, 0xD195, 0x8928, 0xD196, 0x8929, 0xD197, 0x892A, 0xCDCA,
+	0x892B, 0xF1DD, 0x892C, 0xD198, 0x892D, 0xD199, 0x892E, 0xD19A,
+	0x892F, 0xD19B, 0x8930, 0xE5BD, 0x8931, 0xD19C, 0x8932, 0xD19D,
+	0x8933, 0xD19E, 0x8934, 0xF1DC, 0x8935, 0xD19F, 0x8936, 0xF1DE,
+	0x8937, 0xD1A0, 0x8938, 0xD240, 0x8939, 0xD241, 0x893A, 0xD242,
+	0x893B, 0xD243, 0x893C, 0xD244, 0x893D, 0xD245, 0x893E, 0xD246,
+	0x893F, 0xD247, 0x8940, 0xD248, 0x8941, 0xF1DF, 0x8942, 0xD249,
+	0x8943, 0xD24A, 0x8944, 0xCFE5, 0x8945, 0xD24B, 0x8946, 0xD24C,
+	0x8947, 0xD24D, 0x8948, 0xD24E, 0x8949, 0xD24F, 0x894A, 0xD250,
+	0x894B, 0xD251, 0x894C, 0xD252, 0x894D, 0xD253, 0x894E, 0xD254,
+	0x894F, 0xD255, 0x8950, 0xD256, 0x8951, 0xD257, 0x8952, 0xD258,
+	0x8953, 0xD259, 0x8954, 0xD25A, 0x8955, 0xD25B, 0x8956, 0xD25C,
+	0x8957, 0xD25D, 0x8958, 0xD25E, 0x8959, 0xD25F, 0x895A, 0xD260,
+	0x895B, 0xD261, 0x895C, 0xD262, 0x895D, 0xD263, 0x895E, 0xF4C5,
+	0x895F, 0xBDF3, 0x8960, 0xD264, 0x8961, 0xD265, 0x8962, 0xD266,
+	0x8963, 0xD267, 0x8964, 0xD268, 0x8965, 0xD269, 0x8966, 0xF1E0,
+	0x8967, 0xD26A, 0x8968, 0xD26B, 0x8969, 0xD26C, 0x896A, 0xD26D,
+	0x896B, 0xD26E, 0x896C, 0xD26F, 0x896D, 0xD270, 0x896E, 0xD271,
+	0x896F, 0xD272, 0x8970, 0xD273, 0x8971, 0xD274, 0x8972, 0xD275,
+	0x8973, 0xD276, 0x8974, 0xD277, 0x8975, 0xD278, 0x8976, 0xD279,
+	0x8977, 0xD27A, 0x8978, 0xD27B, 0x8979, 0xD27C, 0x897A, 0xD27D,
+	0x897B, 0xF1E1, 0x897C, 0xD27E, 0x897D, 0xD280, 0x897E, 0xD281,
+	0x897F, 0xCEF7, 0x8980, 0xD282, 0x8981, 0xD2AA, 0x8982, 0xD283,
+	0x8983, 0xF1FB, 0x8984, 0xD284, 0x8985, 0xD285, 0x8986, 0xB8B2,
+	0x8987, 0xD286, 0x8988, 0xD287, 0x8989, 0xD288, 0x898A, 0xD289,
+	0x898B, 0xD28A, 0x898C, 0xD28B, 0x898D, 0xD28C, 0x898E, 0xD28D,
+	0x898F, 0xD28E, 0x8990, 0xD28F, 0x8991, 0xD290, 0x8992, 0xD291,
+	0x8993, 0xD292, 0x8994, 0xD293, 0x8995, 0xD294, 0x8996, 0xD295,
+	0x8997, 0xD296, 0x8998, 0xD297, 0x8999, 0xD298, 0x899A, 0xD299,
+	0x899B, 0xD29A, 0x899C, 0xD29B, 0x899D, 0xD29C, 0x899E, 0xD29D,
+	0x899F, 0xD29E, 0x89A0, 0xD29F, 0x89A1, 0xD2A0, 0x89A2, 0xD340,
+	0x89A3, 0xD341, 0x89A4, 0xD342, 0x89A5, 0xD343, 0x89A6, 0xD344,
+	0x89A7, 0xD345, 0x89A8, 0xD346, 0x89A9, 0xD347, 0x89AA, 0xD348,
+	0x89AB, 0xD349, 0x89AC, 0xD34A, 0x89AD, 0xD34B, 0x89AE, 0xD34C,
+	0x89AF, 0xD34D, 0x89B0, 0xD34E, 0x89B1, 0xD34F, 0x89B2, 0xD350,
+	0x89B3, 0xD351, 0x89B4, 0xD352, 0x89B5, 0xD353, 0x89B6, 0xD354,
+	0x89B7, 0xD355, 0x89B8, 0xD356, 0x89B9, 0xD357, 0x89BA, 0xD358,
+	0x89BB, 0xD359, 0x89BC, 0xD35A, 0x89BD, 0xD35B, 0x89BE, 0xD35C,
+	0x89BF, 0xD35D, 0x89C0, 0xD35E, 0x89C1, 0xBCFB, 0x89C2, 0xB9DB,
+	0x89C3, 0xD35F, 0x89C4, 0xB9E6, 0x89C5, 0xC3D9, 0x89C6, 0xCAD3,
+	0x89C7, 0xEAE8, 0x89C8, 0xC0C0, 0x89C9, 0xBEF5, 0x89CA, 0xEAE9,
+	0x89CB, 0xEAEA, 0x89CC, 0xEAEB, 0x89CD, 0xD360, 0x89CE, 0xEAEC,
+	0x89CF, 0xEAED, 0x89D0, 0xEAEE, 0x89D1, 0xEAEF, 0x89D2, 0xBDC7,
+	0x89D3, 0xD361, 0x89D4, 0xD362, 0x89D5, 0xD363, 0x89D6, 0xF5FB,
+	0x89D7, 0xD364, 0x89D8, 0xD365, 0x89D9, 0xD366, 0x89DA, 0xF5FD,
+	0x89DB, 0xD367, 0x89DC, 0xF5FE, 0x89DD, 0xD368, 0x89DE, 0xF5FC,
+	0x89DF, 0xD369, 0x89E0, 0xD36A, 0x89E1, 0xD36B, 0x89E2, 0xD36C,
+	0x89E3, 0xBDE2, 0x89E4, 0xD36D, 0x89E5, 0xF6A1, 0x89E6, 0xB4A5,
+	0x89E7, 0xD36E, 0x89E8, 0xD36F, 0x89E9, 0xD370, 0x89EA, 0xD371,
+	0x89EB, 0xF6A2, 0x89EC, 0xD372, 0x89ED, 0xD373, 0x89EE, 0xD374,
+	0x89EF, 0xF6A3, 0x89F0, 0xD375, 0x89F1, 0xD376, 0x89F2, 0xD377,
+	0x89F3, 0xECB2, 0x89F4, 0xD378, 0x89F5, 0xD379, 0x89F6, 0xD37A,
+	0x89F7, 0xD37B, 0x89F8, 0xD37C, 0x89F9, 0xD37D, 0x89FA, 0xD37E,
+	0x89FB, 0xD380, 0x89FC, 0xD381, 0x89FD, 0xD382, 0x89FE, 0xD383,
+	0x89FF, 0xD384, 0x8A00, 0xD1D4, 0x8A01, 0xD385, 0x8A02, 0xD386,
+	0x8A03, 0xD387, 0x8A04, 0xD388, 0x8A05, 0xD389, 0x8A06, 0xD38A,
+	0x8A07, 0xD9EA, 0x8A08, 0xD38B, 0x8A09, 0xD38C, 0x8A0A, 0xD38D,
+	0x8A0B, 0xD38E, 0x8A0C, 0xD38F, 0x8A0D, 0xD390, 0x8A0E, 0xD391,
+	0x8A0F, 0xD392, 0x8A10, 0xD393, 0x8A11, 0xD394, 0x8A12, 0xD395,
+	0x8A13, 0xD396, 0x8A14, 0xD397, 0x8A15, 0xD398, 0x8A16, 0xD399,
+	0x8A17, 0xD39A, 0x8A18, 0xD39B, 0x8A19, 0xD39C, 0x8A1A, 0xD39D,
+	0x8A1B, 0xD39E, 0x8A1C, 0xD39F, 0x8A1D, 0xD3A0, 0x8A1E, 0xD440,
+	0x8A1F, 0xD441, 0x8A20, 0xD442, 0x8A21, 0xD443, 0x8A22, 0xD444,
+	0x8A23, 0xD445, 0x8A24, 0xD446, 0x8A25, 0xD447, 0x8A26, 0xD448,
+	0x8A27, 0xD449, 0x8A28, 0xD44A, 0x8A29, 0xD44B, 0x8A2A, 0xD44C,
+	0x8A2B, 0xD44D, 0x8A2C, 0xD44E, 0x8A2D, 0xD44F, 0x8A2E, 0xD450,
+	0x8A2F, 0xD451, 0x8A30, 0xD452, 0x8A31, 0xD453, 0x8A32, 0xD454,
+	0x8A33, 0xD455, 0x8A34, 0xD456, 0x8A35, 0xD457, 0x8A36, 0xD458,
+	0x8A37, 0xD459, 0x8A38, 0xD45A, 0x8A39, 0xD45B, 0x8A3A, 0xD45C,
+	0x8A3B, 0xD45D, 0x8A3C, 0xD45E, 0x8A3D, 0xD45F, 0x8A3E, 0xF6A4,
+	0x8A3F, 0xD460, 0x8A40, 0xD461, 0x8A41, 0xD462, 0x8A42, 0xD463,
+	0x8A43, 0xD464, 0x8A44, 0xD465, 0x8A45, 0xD466, 0x8A46, 0xD467,
+	0x8A47, 0xD468, 0x8A48, 0xEEBA, 0x8A49, 0xD469, 0x8A4A, 0xD46A,
+	0x8A4B, 0xD46B, 0x8A4C, 0xD46C, 0x8A4D, 0xD46D, 0x8A4E, 0xD46E,
+	0x8A4F, 0xD46F, 0x8A50, 0xD470, 0x8A51, 0xD471, 0x8A52, 0xD472,
+	0x8A53, 0xD473, 0x8A54, 0xD474, 0x8A55, 0xD475, 0x8A56, 0xD476,
+	0x8A57, 0xD477, 0x8A58, 0xD478, 0x8A59, 0xD479, 0x8A5A, 0xD47A,
+	0x8A5B, 0xD47B, 0x8A5C, 0xD47C, 0x8A5D, 0xD47D, 0x8A5E, 0xD47E,
+	0x8A5F, 0xD480, 0x8A60, 0xD481, 0x8A61, 0xD482, 0x8A62, 0xD483,
+	0x8A63, 0xD484, 0x8A64, 0xD485, 0x8A65, 0xD486, 0x8A66, 0xD487,
+	0x8A67, 0xD488, 0x8A68, 0xD489, 0x8A69, 0xD48A, 0x8A6A, 0xD48B,
+	0x8A6B, 0xD48C, 0x8A6C, 0xD48D, 0x8A6D, 0xD48E, 0x8A6E, 0xD48F,
+	0x8A6F, 0xD490, 0x8A70, 0xD491, 0x8A71, 0xD492, 0x8A72, 0xD493,
+	0x8A73, 0xD494, 0x8A74, 0xD495, 0x8A75, 0xD496, 0x8A76, 0xD497,
+	0x8A77, 0xD498, 0x8A78, 0xD499, 0x8A79, 0xD5B2, 0x8A7A, 0xD49A,
+	0x8A7B, 0xD49B, 0x8A7C, 0xD49C, 0x8A7D, 0xD49D, 0x8A7E, 0xD49E,
+	0x8A7F, 0xD49F, 0x8A80, 0xD4A0, 0x8A81, 0xD540, 0x8A82, 0xD541,
+	0x8A83, 0xD542, 0x8A84, 0xD543, 0x8A85, 0xD544, 0x8A86, 0xD545,
+	0x8A87, 0xD546, 0x8A88, 0xD547, 0x8A89, 0xD3FE, 0x8A8A, 0xCCDC,
+	0x8A8B, 0xD548, 0x8A8C, 0xD549, 0x8A8D, 0xD54A, 0x8A8E, 0xD54B,
+	0x8A8F, 0xD54C, 0x8A90, 0xD54D, 0x8A91, 0xD54E, 0x8A92, 0xD54F,
+	0x8A93, 0xCAC4, 0x8A94, 0xD550, 0x8A95, 0xD551, 0x8A96, 0xD552,
+	0x8A97, 0xD553, 0x8A98, 0xD554, 0x8A99, 0xD555, 0x8A9A, 0xD556,
+	0x8A9B, 0xD557, 0x8A9C, 0xD558, 0x8A9D, 0xD559, 0x8A9E, 0xD55A,
+	0x8A9F, 0xD55B, 0x8AA0, 0xD55C, 0x8AA1, 0xD55D, 0x8AA2, 0xD55E,
+	0x8AA3, 0xD55F, 0x8AA4, 0xD560, 0x8AA5, 0xD561, 0x8AA6, 0xD562,
+	0x8AA7, 0xD563, 0x8AA8, 0xD564, 0x8AA9, 0xD565, 0x8AAA, 0xD566,
+	0x8AAB, 0xD567, 0x8AAC, 0xD568, 0x8AAD, 0xD569, 0x8AAE, 0xD56A,
+	0x8AAF, 0xD56B, 0x8AB0, 0xD56C, 0x8AB1, 0xD56D, 0x8AB2, 0xD56E,
+	0x8AB3, 0xD56F, 0x8AB4, 0xD570, 0x8AB5, 0xD571, 0x8AB6, 0xD572,
+	0x8AB7, 0xD573, 0x8AB8, 0xD574, 0x8AB9, 0xD575, 0x8ABA, 0xD576,
+	0x8ABB, 0xD577, 0x8ABC, 0xD578, 0x8ABD, 0xD579, 0x8ABE, 0xD57A,
+	0x8ABF, 0xD57B, 0x8AC0, 0xD57C, 0x8AC1, 0xD57D, 0x8AC2, 0xD57E,
+	0x8AC3, 0xD580, 0x8AC4, 0xD581, 0x8AC5, 0xD582, 0x8AC6, 0xD583,
+	0x8AC7, 0xD584, 0x8AC8, 0xD585, 0x8AC9, 0xD586, 0x8ACA, 0xD587,
+	0x8ACB, 0xD588, 0x8ACC, 0xD589, 0x8ACD, 0xD58A, 0x8ACE, 0xD58B,
+	0x8ACF, 0xD58C, 0x8AD0, 0xD58D, 0x8AD1, 0xD58E, 0x8AD2, 0xD58F,
+	0x8AD3, 0xD590, 0x8AD4, 0xD591, 0x8AD5, 0xD592, 0x8AD6, 0xD593,
+	0x8AD7, 0xD594, 0x8AD8, 0xD595, 0x8AD9, 0xD596, 0x8ADA, 0xD597,
+	0x8ADB, 0xD598, 0x8ADC, 0xD599, 0x8ADD, 0xD59A, 0x8ADE, 0xD59B,
+	0x8ADF, 0xD59C, 0x8AE0, 0xD59D, 0x8AE1, 0xD59E, 0x8AE2, 0xD59F,
+	0x8AE3, 0xD5A0, 0x8AE4, 0xD640, 0x8AE5, 0xD641, 0x8AE6, 0xD642,
+	0x8AE7, 0xD643, 0x8AE8, 0xD644, 0x8AE9, 0xD645, 0x8AEA, 0xD646,
+	0x8AEB, 0xD647, 0x8AEC, 0xD648, 0x8AED, 0xD649, 0x8AEE, 0xD64A,
+	0x8AEF, 0xD64B, 0x8AF0, 0xD64C, 0x8AF1, 0xD64D, 0x8AF2, 0xD64E,
+	0x8AF3, 0xD64F, 0x8AF4, 0xD650, 0x8AF5, 0xD651, 0x8AF6, 0xD652,
+	0x8AF7, 0xD653, 0x8AF8, 0xD654, 0x8AF9, 0xD655, 0x8AFA, 0xD656,
+	0x8AFB, 0xD657, 0x8AFC, 0xD658, 0x8AFD, 0xD659, 0x8AFE, 0xD65A,
+	0x8AFF, 0xD65B, 0x8B00, 0xD65C, 0x8B01, 0xD65D, 0x8B02, 0xD65E,
+	0x8B03, 0xD65F, 0x8B04, 0xD660, 0x8B05, 0xD661, 0x8B06, 0xD662,
+	0x8B07, 0xE5C0, 0x8B08, 0xD663, 0x8B09, 0xD664, 0x8B0A, 0xD665,
+	0x8B0B, 0xD666, 0x8B0C, 0xD667, 0x8B0D, 0xD668, 0x8B0E, 0xD669,
+	0x8B0F, 0xD66A, 0x8B10, 0xD66B, 0x8B11, 0xD66C, 0x8B12, 0xD66D,
+	0x8B13, 0xD66E, 0x8B14, 0xD66F, 0x8B15, 0xD670, 0x8B16, 0xD671,
+	0x8B17, 0xD672, 0x8B18, 0xD673, 0x8B19, 0xD674, 0x8B1A, 0xD675,
+	0x8B1B, 0xD676, 0x8B1C, 0xD677, 0x8B1D, 0xD678, 0x8B1E, 0xD679,
+	0x8B1F, 0xD67A, 0x8B20, 0xD67B, 0x8B21, 0xD67C, 0x8B22, 0xD67D,
+	0x8B23, 0xD67E, 0x8B24, 0xD680, 0x8B25, 0xD681, 0x8B26, 0xF6A5,
+	0x8B27, 0xD682, 0x8B28, 0xD683, 0x8B29, 0xD684, 0x8B2A, 0xD685,
+	0x8B2B, 0xD686, 0x8B2C, 0xD687, 0x8B2D, 0xD688, 0x8B2E, 0xD689,
+	0x8B2F, 0xD68A, 0x8B30, 0xD68B, 0x8B31, 0xD68C, 0x8B32, 0xD68D,
+	0x8B33, 0xD68E, 0x8B34, 0xD68F, 0x8B35, 0xD690, 0x8B36, 0xD691,
+	0x8B37, 0xD692, 0x8B38, 0xD693, 0x8B39, 0xD694, 0x8B3A, 0xD695,
+	0x8B3B, 0xD696, 0x8B3C, 0xD697, 0x8B3D, 0xD698, 0x8B3E, 0xD699,
+	0x8B3F, 0xD69A, 0x8B40, 0xD69B, 0x8B41, 0xD69C, 0x8B42, 0xD69D,
+	0x8B43, 0xD69E, 0x8B44, 0xD69F, 0x8B45, 0xD6A0, 0x8B46, 0xD740,
+	0x8B47, 0xD741, 0x8B48, 0xD742, 0x8B49, 0xD743, 0x8B4A, 0xD744,
+	0x8B4B, 0xD745, 0x8B4C, 0xD746, 0x8B4D, 0xD747, 0x8B4E, 0xD748,
+	0x8B4F, 0xD749, 0x8B50, 0xD74A, 0x8B51, 0xD74B, 0x8B52, 0xD74C,
+	0x8B53, 0xD74D, 0x8B54, 0xD74E, 0x8B55, 0xD74F, 0x8B56, 0xD750,
+	0x8B57, 0xD751, 0x8B58, 0xD752, 0x8B59, 0xD753, 0x8B5A, 0xD754,
+	0x8B5B, 0xD755, 0x8B5C, 0xD756, 0x8B5D, 0xD757, 0x8B5E, 0xD758,
+	0x8B5F, 0xD759, 0x8B60, 0xD75A, 0x8B61, 0xD75B, 0x8B62, 0xD75C,
+	0x8B63, 0xD75D, 0x8B64, 0xD75E, 0x8B65, 0xD75F, 0x8B66, 0xBEAF,
+	0x8B67, 0xD760, 0x8B68, 0xD761, 0x8B69, 0xD762, 0x8B6A, 0xD763,
+	0x8B6B, 0xD764, 0x8B6C, 0xC6A9, 0x8B6D, 0xD765, 0x8B6E, 0xD766,
+	0x8B6F, 0xD767, 0x8B70, 0xD768, 0x8B71, 0xD769, 0x8B72, 0xD76A,
+	0x8B73, 0xD76B, 0x8B74, 0xD76C, 0x8B75, 0xD76D, 0x8B76, 0xD76E,
+	0x8B77, 0xD76F, 0x8B78, 0xD770, 0x8B79, 0xD771, 0x8B7A, 0xD772,
+	0x8B7B, 0xD773, 0x8B7C, 0xD774, 0x8B7D, 0xD775, 0x8B7E, 0xD776,
+	0x8B7F, 0xD777, 0x8B80, 0xD778, 0x8B81, 0xD779, 0x8B82, 0xD77A,
+	0x8B83, 0xD77B, 0x8B84, 0xD77C, 0x8B85, 0xD77D, 0x8B86, 0xD77E,
+	0x8B87, 0xD780, 0x8B88, 0xD781, 0x8B89, 0xD782, 0x8B8A, 0xD783,
+	0x8B8B, 0xD784, 0x8B8C, 0xD785, 0x8B8D, 0xD786, 0x8B8E, 0xD787,
+	0x8B8F, 0xD788, 0x8B90, 0xD789, 0x8B91, 0xD78A, 0x8B92, 0xD78B,
+	0x8B93, 0xD78C, 0x8B94, 0xD78D, 0x8B95, 0xD78E, 0x8B96, 0xD78F,
+	0x8B97, 0xD790, 0x8B98, 0xD791, 0x8B99, 0xD792, 0x8B9A, 0xD793,
+	0x8B9B, 0xD794, 0x8B9C, 0xD795, 0x8B9D, 0xD796, 0x8B9E, 0xD797,
+	0x8B9F, 0xD798, 0x8BA0, 0xDAA5, 0x8BA1, 0xBCC6, 0x8BA2, 0xB6A9,
+	0x8BA3, 0xB8BC, 0x8BA4, 0xC8CF, 0x8BA5, 0xBCA5, 0x8BA6, 0xDAA6,
+	0x8BA7, 0xDAA7, 0x8BA8, 0xCCD6, 0x8BA9, 0xC8C3, 0x8BAA, 0xDAA8,
+	0x8BAB, 0xC6FD, 0x8BAC, 0xD799, 0x8BAD, 0xD1B5, 0x8BAE, 0xD2E9,
+	0x8BAF, 0xD1B6, 0x8BB0, 0xBCC7, 0x8BB1, 0xD79A, 0x8BB2, 0xBDB2,
+	0x8BB3, 0xBBE4, 0x8BB4, 0xDAA9, 0x8BB5, 0xDAAA, 0x8BB6, 0xD1C8,
+	0x8BB7, 0xDAAB, 0x8BB8, 0xD0ED, 0x8BB9, 0xB6EF, 0x8BBA, 0xC2DB,
+	0x8BBB, 0xD79B, 0x8BBC, 0xCBCF, 0x8BBD, 0xB7ED, 0x8BBE, 0xC9E8,
+	0x8BBF, 0xB7C3, 0x8BC0, 0xBEF7, 0x8BC1, 0xD6A4, 0x8BC2, 0xDAAC,
+	0x8BC3, 0xDAAD, 0x8BC4, 0xC6C0, 0x8BC5, 0xD7E7, 0x8BC6, 0xCAB6,
+	0x8BC7, 0xD79C, 0x8BC8, 0xD5A9, 0x8BC9, 0xCBDF, 0x8BCA, 0xD5EF,
+	0x8BCB, 0xDAAE, 0x8BCC, 0xD6DF, 0x8BCD, 0xB4CA, 0x8BCE, 0xDAB0,
+	0x8BCF, 0xDAAF, 0x8BD0, 0xD79D, 0x8BD1, 0xD2EB, 0x8BD2, 0xDAB1,
+	0x8BD3, 0xDAB2, 0x8BD4, 0xDAB3, 0x8BD5, 0xCAD4, 0x8BD6, 0xDAB4,
+	0x8BD7, 0xCAAB, 0x8BD8, 0xDAB5, 0x8BD9, 0xDAB6, 0x8BDA, 0xB3CF,
+	0x8BDB, 0xD6EF, 0x8BDC, 0xDAB7, 0x8BDD, 0xBBB0, 0x8BDE, 0xB5AE,
+	0x8BDF, 0xDAB8, 0x8BE0, 0xDAB9, 0x8BE1, 0xB9EE, 0x8BE2, 0xD1AF,
+	0x8BE3, 0xD2E8, 0x8BE4, 0xDABA, 0x8BE5, 0xB8C3, 0x8BE6, 0xCFEA,
+	0x8BE7, 0xB2EF, 0x8BE8, 0xDABB, 0x8BE9, 0xDABC, 0x8BEA, 0xD79E,
+	0x8BEB, 0xBDEB, 0x8BEC, 0xCEDC, 0x8BED, 0xD3EF, 0x8BEE, 0xDABD,
+	0x8BEF, 0xCEF3, 0x8BF0, 0xDABE, 0x8BF1, 0xD3D5, 0x8BF2, 0xBBE5,
+	0x8BF3, 0xDABF, 0x8BF4, 0xCBB5, 0x8BF5, 0xCBD0, 0x8BF6, 0xDAC0,
+	0x8BF7, 0xC7EB, 0x8BF8, 0xD6EE, 0x8BF9, 0xDAC1, 0x8BFA, 0xC5B5,
+	0x8BFB, 0xB6C1, 0x8BFC, 0xDAC2, 0x8BFD, 0xB7CC, 0x8BFE, 0xBFCE,
+	0x8BFF, 0xDAC3, 0x8C00, 0xDAC4, 0x8C01, 0xCBAD, 0x8C02, 0xDAC5,
+	0x8C03, 0xB5F7, 0x8C04, 0xDAC6, 0x8C05, 0xC1C2, 0x8C06, 0xD7BB,
+	0x8C07, 0xDAC7, 0x8C08, 0xCCB8, 0x8C09, 0xD79F, 0x8C0A, 0xD2EA,
+	0x8C0B, 0xC4B1, 0x8C0C, 0xDAC8, 0x8C0D, 0xB5FD, 0x8C0E, 0xBBD1,
+	0x8C0F, 0xDAC9, 0x8C10, 0xD0B3, 0x8C11, 0xDACA, 0x8C12, 0xDACB,
+	0x8C13, 0xCEBD, 0x8C14, 0xDACC, 0x8C15, 0xDACD, 0x8C16, 0xDACE,
+	0x8C17, 0xB2F7, 0x8C18, 0xDAD1, 0x8C19, 0xDACF, 0x8C1A, 0xD1E8,
+	0x8C1B, 0xDAD0, 0x8C1C, 0xC3D5, 0x8C1D, 0xDAD2, 0x8C1E, 0xD7A0,
+	0x8C1F, 0xDAD3, 0x8C20, 0xDAD4, 0x8C21, 0xDAD5, 0x8C22, 0xD0BB,
+	0x8C23, 0xD2A5, 0x8C24, 0xB0F9, 0x8C25, 0xDAD6, 0x8C26, 0xC7AB,
+	0x8C27, 0xDAD7, 0x8C28, 0xBDF7, 0x8C29, 0xC3A1, 0x8C2A, 0xDAD8,
+	0x8C2B, 0xDAD9, 0x8C2C, 0xC3FD, 0x8C2D, 0xCCB7, 0x8C2E, 0xDADA,
+	0x8C2F, 0xDADB, 0x8C30, 0xC0BE, 0x8C31, 0xC6D7, 0x8C32, 0xDADC,
+	0x8C33, 0xDADD, 0x8C34, 0xC7B4, 0x8C35, 0xDADE, 0x8C36, 0xDADF,
+	0x8C37, 0xB9C8, 0x8C38, 0xD840, 0x8C39, 0xD841, 0x8C3A, 0xD842,
+	0x8C3B, 0xD843, 0x8C3C, 0xD844, 0x8C3D, 0xD845, 0x8C3E, 0xD846,
+	0x8C3F, 0xD847, 0x8C40, 0xD848, 0x8C41, 0xBBED, 0x8C42, 0xD849,
+	0x8C43, 0xD84A, 0x8C44, 0xD84B, 0x8C45, 0xD84C, 0x8C46, 0xB6B9,
+	0x8C47, 0xF4F8, 0x8C48, 0xD84D, 0x8C49, 0xF4F9, 0x8C4A, 0xD84E,
+	0x8C4B, 0xD84F, 0x8C4C, 0xCDE3, 0x8C4D, 0xD850, 0x8C4E, 0xD851,
+	0x8C4F, 0xD852, 0x8C50, 0xD853, 0x8C51, 0xD854, 0x8C52, 0xD855,
+	0x8C53, 0xD856, 0x8C54, 0xD857, 0x8C55, 0xF5B9, 0x8C56, 0xD858,
+	0x8C57, 0xD859, 0x8C58, 0xD85A, 0x8C59, 0xD85B, 0x8C5A, 0xEBE0,
+	0x8C5B, 0xD85C, 0x8C5C, 0xD85D, 0x8C5D, 0xD85E, 0x8C5E, 0xD85F,
+	0x8C5F, 0xD860, 0x8C60, 0xD861, 0x8C61, 0xCFF3, 0x8C62, 0xBBBF,
+	0x8C63, 0xD862, 0x8C64, 0xD863, 0x8C65, 0xD864, 0x8C66, 0xD865,
+	0x8C67, 0xD866, 0x8C68, 0xD867, 0x8C69, 0xD868, 0x8C6A, 0xBAC0,
+	0x8C6B, 0xD4A5, 0x8C6C, 0xD869, 0x8C6D, 0xD86A, 0x8C6E, 0xD86B,
+	0x8C6F, 0xD86C, 0x8C70, 0xD86D, 0x8C71, 0xD86E, 0x8C72, 0xD86F,
+	0x8C73, 0xE1D9, 0x8C74, 0xD870, 0x8C75, 0xD871, 0x8C76, 0xD872,
+	0x8C77, 0xD873, 0x8C78, 0xF5F4, 0x8C79, 0xB1AA, 0x8C7A, 0xB2F2,
+	0x8C7B, 0xD874, 0x8C7C, 0xD875, 0x8C7D, 0xD876, 0x8C7E, 0xD877,
+	0x8C7F, 0xD878, 0x8C80, 0xD879, 0x8C81, 0xD87A, 0x8C82, 0xF5F5,
+	0x8C83, 0xD87B, 0x8C84, 0xD87C, 0x8C85, 0xF5F7, 0x8C86, 0xD87D,
+	0x8C87, 0xD87E, 0x8C88, 0xD880, 0x8C89, 0xBAD1, 0x8C8A, 0xF5F6,
+	0x8C8B, 0xD881, 0x8C8C, 0xC3B2, 0x8C8D, 0xD882, 0x8C8E, 0xD883,
+	0x8C8F, 0xD884, 0x8C90, 0xD885, 0x8C91, 0xD886, 0x8C92, 0xD887,
+	0x8C93, 0xD888, 0x8C94, 0xF5F9, 0x8C95, 0xD889, 0x8C96, 0xD88A,
+	0x8C97, 0xD88B, 0x8C98, 0xF5F8, 0x8C99, 0xD88C, 0x8C9A, 0xD88D,
+	0x8C9B, 0xD88E, 0x8C9C, 0xD88F, 0x8C9D, 0xD890, 0x8C9E, 0xD891,
+	0x8C9F, 0xD892, 0x8CA0, 0xD893, 0x8CA1, 0xD894, 0x8CA2, 0xD895,
+	0x8CA3, 0xD896, 0x8CA4, 0xD897, 0x8CA5, 0xD898, 0x8CA6, 0xD899,
+	0x8CA7, 0xD89A, 0x8CA8, 0xD89B, 0x8CA9, 0xD89C, 0x8CAA, 0xD89D,
+	0x8CAB, 0xD89E, 0x8CAC, 0xD89F, 0x8CAD, 0xD8A0, 0x8CAE, 0xD940,
+	0x8CAF, 0xD941, 0x8CB0, 0xD942, 0x8CB1, 0xD943, 0x8CB2, 0xD944,
+	0x8CB3, 0xD945, 0x8CB4, 0xD946, 0x8CB5, 0xD947, 0x8CB6, 0xD948,
+	0x8CB7, 0xD949, 0x8CB8, 0xD94A, 0x8CB9, 0xD94B, 0x8CBA, 0xD94C,
+	0x8CBB, 0xD94D, 0x8CBC, 0xD94E, 0x8CBD, 0xD94F, 0x8CBE, 0xD950,
+	0x8CBF, 0xD951, 0x8CC0, 0xD952, 0x8CC1, 0xD953, 0x8CC2, 0xD954,
+	0x8CC3, 0xD955, 0x8CC4, 0xD956, 0x8CC5, 0xD957, 0x8CC6, 0xD958,
+	0x8CC7, 0xD959, 0x8CC8, 0xD95A, 0x8CC9, 0xD95B, 0x8CCA, 0xD95C,
+	0x8CCB, 0xD95D, 0x8CCC, 0xD95E, 0x8CCD, 0xD95F, 0x8CCE, 0xD960,
+	0x8CCF, 0xD961, 0x8CD0, 0xD962, 0x8CD1, 0xD963, 0x8CD2, 0xD964,
+	0x8CD3, 0xD965, 0x8CD4, 0xD966, 0x8CD5, 0xD967, 0x8CD6, 0xD968,
+	0x8CD7, 0xD969, 0x8CD8, 0xD96A, 0x8CD9, 0xD96B, 0x8CDA, 0xD96C,
+	0x8CDB, 0xD96D, 0x8CDC, 0xD96E, 0x8CDD, 0xD96F, 0x8CDE, 0xD970,
+	0x8CDF, 0xD971, 0x8CE0, 0xD972, 0x8CE1, 0xD973, 0x8CE2, 0xD974,
+	0x8CE3, 0xD975, 0x8CE4, 0xD976, 0x8CE5, 0xD977, 0x8CE6, 0xD978,
+	0x8CE7, 0xD979, 0x8CE8, 0xD97A, 0x8CE9, 0xD97B, 0x8CEA, 0xD97C,
+	0x8CEB, 0xD97D, 0x8CEC, 0xD97E, 0x8CED, 0xD980, 0x8CEE, 0xD981,
+	0x8CEF, 0xD982, 0x8CF0, 0xD983, 0x8CF1, 0xD984, 0x8CF2, 0xD985,
+	0x8CF3, 0xD986, 0x8CF4, 0xD987, 0x8CF5, 0xD988, 0x8CF6, 0xD989,
+	0x8CF7, 0xD98A, 0x8CF8, 0xD98B, 0x8CF9, 0xD98C, 0x8CFA, 0xD98D,
+	0x8CFB, 0xD98E, 0x8CFC, 0xD98F, 0x8CFD, 0xD990, 0x8CFE, 0xD991,
+	0x8CFF, 0xD992, 0x8D00, 0xD993, 0x8D01, 0xD994, 0x8D02, 0xD995,
+	0x8D03, 0xD996, 0x8D04, 0xD997, 0x8D05, 0xD998, 0x8D06, 0xD999,
+	0x8D07, 0xD99A, 0x8D08, 0xD99B, 0x8D09, 0xD99C, 0x8D0A, 0xD99D,
+	0x8D0B, 0xD99E, 0x8D0C, 0xD99F, 0x8D0D, 0xD9A0, 0x8D0E, 0xDA40,
+	0x8D0F, 0xDA41, 0x8D10, 0xDA42, 0x8D11, 0xDA43, 0x8D12, 0xDA44,
+	0x8D13, 0xDA45, 0x8D14, 0xDA46, 0x8D15, 0xDA47, 0x8D16, 0xDA48,
+	0x8D17, 0xDA49, 0x8D18, 0xDA4A, 0x8D19, 0xDA4B, 0x8D1A, 0xDA4C,
+	0x8D1B, 0xDA4D, 0x8D1C, 0xDA4E, 0x8D1D, 0xB1B4, 0x8D1E, 0xD5EA,
+	0x8D1F, 0xB8BA, 0x8D20, 0xDA4F, 0x8D21, 0xB9B1, 0x8D22, 0xB2C6,
+	0x8D23, 0xD4F0, 0x8D24, 0xCFCD, 0x8D25, 0xB0DC, 0x8D26, 0xD5CB,
+	0x8D27, 0xBBF5, 0x8D28, 0xD6CA, 0x8D29, 0xB7B7, 0x8D2A, 0xCCB0,
+	0x8D2B, 0xC6B6, 0x8D2C, 0xB1E1, 0x8D2D, 0xB9BA, 0x8D2E, 0xD6FC,
+	0x8D2F, 0xB9E1, 0x8D30, 0xB7A1, 0x8D31, 0xBCFA, 0x8D32, 0xEADA,
+	0x8D33, 0xEADB, 0x8D34, 0xCCF9, 0x8D35, 0xB9F3, 0x8D36, 0xEADC,
+	0x8D37, 0xB4FB, 0x8D38, 0xC3B3, 0x8D39, 0xB7D1, 0x8D3A, 0xBAD8,
+	0x8D3B, 0xEADD, 0x8D3C, 0xD4F4, 0x8D3D, 0xEADE, 0x8D3E, 0xBCD6,
+	0x8D3F, 0xBBDF, 0x8D40, 0xEADF, 0x8D41, 0xC1DE, 0x8D42, 0xC2B8,
+	0x8D43, 0xD4DF, 0x8D44, 0xD7CA, 0x8D45, 0xEAE0, 0x8D46, 0xEAE1,
+	0x8D47, 0xEAE4, 0x8D48, 0xEAE2, 0x8D49, 0xEAE3, 0x8D4A, 0xC9DE,
+	0x8D4B, 0xB8B3, 0x8D4C, 0xB6C4, 0x8D4D, 0xEAE5, 0x8D4E, 0xCAEA,
+	0x8D4F, 0xC9CD, 0x8D50, 0xB4CD, 0x8D51, 0xDA50, 0x8D52, 0xDA51,
+	0x8D53, 0xE2D9, 0x8D54, 0xC5E2, 0x8D55, 0xEAE6, 0x8D56, 0xC0B5,
+	0x8D57, 0xDA52, 0x8D58, 0xD7B8, 0x8D59, 0xEAE7, 0x8D5A, 0xD7AC,
+	0x8D5B, 0xC8FC, 0x8D5C, 0xD8D3, 0x8D5D, 0xD8CD, 0x8D5E, 0xD4DE,
+	0x8D5F, 0xDA53, 0x8D60, 0xD4F9, 0x8D61, 0xC9C4, 0x8D62, 0xD3AE,
+	0x8D63, 0xB8D3, 0x8D64, 0xB3E0, 0x8D65, 0xDA54, 0x8D66, 0xC9E2,
+	0x8D67, 0xF4F6, 0x8D68, 0xDA55, 0x8D69, 0xDA56, 0x8D6A, 0xDA57,
+	0x8D6B, 0xBAD5, 0x8D6C, 0xDA58, 0x8D6D, 0xF4F7, 0x8D6E, 0xDA59,
+	0x8D6F, 0xDA5A, 0x8D70, 0xD7DF, 0x8D71, 0xDA5B, 0x8D72, 0xDA5C,
+	0x8D73, 0xF4F1, 0x8D74, 0xB8B0, 0x8D75, 0xD5D4, 0x8D76, 0xB8CF,
+	0x8D77, 0xC6F0, 0x8D78, 0xDA5D, 0x8D79, 0xDA5E, 0x8D7A, 0xDA5F,
+	0x8D7B, 0xDA60, 0x8D7C, 0xDA61, 0x8D7D, 0xDA62, 0x8D7E, 0xDA63,
+	0x8D7F, 0xDA64, 0x8D80, 0xDA65, 0x8D81, 0xB3C3, 0x8D82, 0xDA66,
+	0x8D83, 0xDA67, 0x8D84, 0xF4F2, 0x8D85, 0xB3AC, 0x8D86, 0xDA68,
+	0x8D87, 0xDA69, 0x8D88, 0xDA6A, 0x8D89, 0xDA6B, 0x8D8A, 0xD4BD,
+	0x8D8B, 0xC7F7, 0x8D8C, 0xDA6C, 0x8D8D, 0xDA6D, 0x8D8E, 0xDA6E,
+	0x8D8F, 0xDA6F, 0x8D90, 0xDA70, 0x8D91, 0xF4F4, 0x8D92, 0xDA71,
+	0x8D93, 0xDA72, 0x8D94, 0xF4F3, 0x8D95, 0xDA73, 0x8D96, 0xDA74,
+	0x8D97, 0xDA75, 0x8D98, 0xDA76, 0x8D99, 0xDA77, 0x8D9A, 0xDA78,
+	0x8D9B, 0xDA79, 0x8D9C, 0xDA7A, 0x8D9D, 0xDA7B, 0x8D9E, 0xDA7C,
+	0x8D9F, 0xCCCB, 0x8DA0, 0xDA7D, 0x8DA1, 0xDA7E, 0x8DA2, 0xDA80,
+	0x8DA3, 0xC8A4, 0x8DA4, 0xDA81, 0x8DA5, 0xDA82, 0x8DA6, 0xDA83,
+	0x8DA7, 0xDA84, 0x8DA8, 0xDA85, 0x8DA9, 0xDA86, 0x8DAA, 0xDA87,
+	0x8DAB, 0xDA88, 0x8DAC, 0xDA89, 0x8DAD, 0xDA8A, 0x8DAE, 0xDA8B,
+	0x8DAF, 0xDA8C, 0x8DB0, 0xDA8D, 0x8DB1, 0xF4F5, 0x8DB2, 0xDA8E,
+	0x8DB3, 0xD7E3, 0x8DB4, 0xC5BF, 0x8DB5, 0xF5C0, 0x8DB6, 0xDA8F,
+	0x8DB7, 0xDA90, 0x8DB8, 0xF5BB, 0x8DB9, 0xDA91, 0x8DBA, 0xF5C3,
+	0x8DBB, 0xDA92, 0x8DBC, 0xF5C2, 0x8DBD, 0xDA93, 0x8DBE, 0xD6BA,
+	0x8DBF, 0xF5C1, 0x8DC0, 0xDA94, 0x8DC1, 0xDA95, 0x8DC2, 0xDA96,
+	0x8DC3, 0xD4BE, 0x8DC4, 0xF5C4, 0x8DC5, 0xDA97, 0x8DC6, 0xF5CC,
+	0x8DC7, 0xDA98, 0x8DC8, 0xDA99, 0x8DC9, 0xDA9A, 0x8DCA, 0xDA9B,
+	0x8DCB, 0xB0CF, 0x8DCC, 0xB5F8, 0x8DCD, 0xDA9C, 0x8DCE, 0xF5C9,
+	0x8DCF, 0xF5CA, 0x8DD0, 0xDA9D, 0x8DD1, 0xC5DC, 0x8DD2, 0xDA9E,
+	0x8DD3, 0xDA9F, 0x8DD4, 0xDAA0, 0x8DD5, 0xDB40, 0x8DD6, 0xF5C5,
+	0x8DD7, 0xF5C6, 0x8DD8, 0xDB41, 0x8DD9, 0xDB42, 0x8DDA, 0xF5C7,
+	0x8DDB, 0xF5CB, 0x8DDC, 0xDB43, 0x8DDD, 0xBEE0, 0x8DDE, 0xF5C8,
+	0x8DDF, 0xB8FA, 0x8DE0, 0xDB44, 0x8DE1, 0xDB45, 0x8DE2, 0xDB46,
+	0x8DE3, 0xF5D0, 0x8DE4, 0xF5D3, 0x8DE5, 0xDB47, 0x8DE6, 0xDB48,
+	0x8DE7, 0xDB49, 0x8DE8, 0xBFE7, 0x8DE9, 0xDB4A, 0x8DEA, 0xB9F2,
+	0x8DEB, 0xF5BC, 0x8DEC, 0xF5CD, 0x8DED, 0xDB4B, 0x8DEE, 0xDB4C,
+	0x8DEF, 0xC2B7, 0x8DF0, 0xDB4D, 0x8DF1, 0xDB4E, 0x8DF2, 0xDB4F,
+	0x8DF3, 0xCCF8, 0x8DF4, 0xDB50, 0x8DF5, 0xBCF9, 0x8DF6, 0xDB51,
+	0x8DF7, 0xF5CE, 0x8DF8, 0xF5CF, 0x8DF9, 0xF5D1, 0x8DFA, 0xB6E5,
+	0x8DFB, 0xF5D2, 0x8DFC, 0xDB52, 0x8DFD, 0xF5D5, 0x8DFE, 0xDB53,
+	0x8DFF, 0xDB54, 0x8E00, 0xDB55, 0x8E01, 0xDB56, 0x8E02, 0xDB57,
+	0x8E03, 0xDB58, 0x8E04, 0xDB59, 0x8E05, 0xF5BD, 0x8E06, 0xDB5A,
+	0x8E07, 0xDB5B, 0x8E08, 0xDB5C, 0x8E09, 0xF5D4, 0x8E0A, 0xD3BB,
+	0x8E0B, 0xDB5D, 0x8E0C, 0xB3EC, 0x8E0D, 0xDB5E, 0x8E0E, 0xDB5F,
+	0x8E0F, 0xCCA4, 0x8E10, 0xDB60, 0x8E11, 0xDB61, 0x8E12, 0xDB62,
+	0x8E13, 0xDB63, 0x8E14, 0xF5D6, 0x8E15, 0xDB64, 0x8E16, 0xDB65,
+	0x8E17, 0xDB66, 0x8E18, 0xDB67, 0x8E19, 0xDB68, 0x8E1A, 0xDB69,
+	0x8E1B, 0xDB6A, 0x8E1C, 0xDB6B, 0x8E1D, 0xF5D7, 0x8E1E, 0xBEE1,
+	0x8E1F, 0xF5D8, 0x8E20, 0xDB6C, 0x8E21, 0xDB6D, 0x8E22, 0xCCDF,
+	0x8E23, 0xF5DB, 0x8E24, 0xDB6E, 0x8E25, 0xDB6F, 0x8E26, 0xDB70,
+	0x8E27, 0xDB71, 0x8E28, 0xDB72, 0x8E29, 0xB2C8, 0x8E2A, 0xD7D9,
+	0x8E2B, 0xDB73, 0x8E2C, 0xF5D9, 0x8E2D, 0xDB74, 0x8E2E, 0xF5DA,
+	0x8E2F, 0xF5DC, 0x8E30, 0xDB75, 0x8E31, 0xF5E2, 0x8E32, 0xDB76,
+	0x8E33, 0xDB77, 0x8E34, 0xDB78, 0x8E35, 0xF5E0, 0x8E36, 0xDB79,
+	0x8E37, 0xDB7A, 0x8E38, 0xDB7B, 0x8E39, 0xF5DF, 0x8E3A, 0xF5DD,
+	0x8E3B, 0xDB7C, 0x8E3C, 0xDB7D, 0x8E3D, 0xF5E1, 0x8E3E, 0xDB7E,
+	0x8E3F, 0xDB80, 0x8E40, 0xF5DE, 0x8E41, 0xF5E4, 0x8E42, 0xF5E5,
+	0x8E43, 0xDB81, 0x8E44, 0xCCE3, 0x8E45, 0xDB82, 0x8E46, 0xDB83,
+	0x8E47, 0xE5BF, 0x8E48, 0xB5B8, 0x8E49, 0xF5E3, 0x8E4A, 0xF5E8,
+	0x8E4B, 0xCCA3, 0x8E4C, 0xDB84, 0x8E4D, 0xDB85, 0x8E4E, 0xDB86,
+	0x8E4F, 0xDB87, 0x8E50, 0xDB88, 0x8E51, 0xF5E6, 0x8E52, 0xF5E7,
+	0x8E53, 0xDB89, 0x8E54, 0xDB8A, 0x8E55, 0xDB8B, 0x8E56, 0xDB8C,
+	0x8E57, 0xDB8D, 0x8E58, 0xDB8E, 0x8E59, 0xF5BE, 0x8E5A, 0xDB8F,
+	0x8E5B, 0xDB90, 0x8E5C, 0xDB91, 0x8E5D, 0xDB92, 0x8E5E, 0xDB93,
+	0x8E5F, 0xDB94, 0x8E60, 0xDB95, 0x8E61, 0xDB96, 0x8E62, 0xDB97,
+	0x8E63, 0xDB98, 0x8E64, 0xDB99, 0x8E65, 0xDB9A, 0x8E66, 0xB1C4,
+	0x8E67, 0xDB9B, 0x8E68, 0xDB9C, 0x8E69, 0xF5BF, 0x8E6A, 0xDB9D,
+	0x8E6B, 0xDB9E, 0x8E6C, 0xB5C5, 0x8E6D, 0xB2E4, 0x8E6E, 0xDB9F,
+	0x8E6F, 0xF5EC, 0x8E70, 0xF5E9, 0x8E71, 0xDBA0, 0x8E72, 0xB6D7,
+	0x8E73, 0xDC40, 0x8E74, 0xF5ED, 0x8E75, 0xDC41, 0x8E76, 0xF5EA,
+	0x8E77, 0xDC42, 0x8E78, 0xDC43, 0x8E79, 0xDC44, 0x8E7A, 0xDC45,
+	0x8E7B, 0xDC46, 0x8E7C, 0xF5EB, 0x8E7D, 0xDC47, 0x8E7E, 0xDC48,
+	0x8E7F, 0xB4DA, 0x8E80, 0xDC49, 0x8E81, 0xD4EA, 0x8E82, 0xDC4A,
+	0x8E83, 0xDC4B, 0x8E84, 0xDC4C, 0x8E85, 0xF5EE, 0x8E86, 0xDC4D,
+	0x8E87, 0xB3F9, 0x8E88, 0xDC4E, 0x8E89, 0xDC4F, 0x8E8A, 0xDC50,
+	0x8E8B, 0xDC51, 0x8E8C, 0xDC52, 0x8E8D, 0xDC53, 0x8E8E, 0xDC54,
+	0x8E8F, 0xF5EF, 0x8E90, 0xF5F1, 0x8E91, 0xDC55, 0x8E92, 0xDC56,
+	0x8E93, 0xDC57, 0x8E94, 0xF5F0, 0x8E95, 0xDC58, 0x8E96, 0xDC59,
+	0x8E97, 0xDC5A, 0x8E98, 0xDC5B, 0x8E99, 0xDC5C, 0x8E9A, 0xDC5D,
+	0x8E9B, 0xDC5E, 0x8E9C, 0xF5F2, 0x8E9D, 0xDC5F, 0x8E9E, 0xF5F3,
+	0x8E9F, 0xDC60, 0x8EA0, 0xDC61, 0x8EA1, 0xDC62, 0x8EA2, 0xDC63,
+	0x8EA3, 0xDC64, 0x8EA4, 0xDC65, 0x8EA5, 0xDC66, 0x8EA6, 0xDC67,
+	0x8EA7, 0xDC68, 0x8EA8, 0xDC69, 0x8EA9, 0xDC6A, 0x8EAA, 0xDC6B,
+	0x8EAB, 0xC9ED, 0x8EAC, 0xB9AA, 0x8EAD, 0xDC6C, 0x8EAE, 0xDC6D,
+	0x8EAF, 0xC7FB, 0x8EB0, 0xDC6E, 0x8EB1, 0xDC6F, 0x8EB2, 0xB6E3,
+	0x8EB3, 0xDC70, 0x8EB4, 0xDC71, 0x8EB5, 0xDC72, 0x8EB6, 0xDC73,
+	0x8EB7, 0xDC74, 0x8EB8, 0xDC75, 0x8EB9, 0xDC76, 0x8EBA, 0xCCC9,
+	0x8EBB, 0xDC77, 0x8EBC, 0xDC78, 0x8EBD, 0xDC79, 0x8EBE, 0xDC7A,
+	0x8EBF, 0xDC7B, 0x8EC0, 0xDC7C, 0x8EC1, 0xDC7D, 0x8EC2, 0xDC7E,
+	0x8EC3, 0xDC80, 0x8EC4, 0xDC81, 0x8EC5, 0xDC82, 0x8EC6, 0xDC83,
+	0x8EC7, 0xDC84, 0x8EC8, 0xDC85, 0x8EC9, 0xDC86, 0x8ECA, 0xDC87,
+	0x8ECB, 0xDC88, 0x8ECC, 0xDC89, 0x8ECD, 0xDC8A, 0x8ECE, 0xEAA6,
+	0x8ECF, 0xDC8B, 0x8ED0, 0xDC8C, 0x8ED1, 0xDC8D, 0x8ED2, 0xDC8E,
+	0x8ED3, 0xDC8F, 0x8ED4, 0xDC90, 0x8ED5, 0xDC91, 0x8ED6, 0xDC92,
+	0x8ED7, 0xDC93, 0x8ED8, 0xDC94, 0x8ED9, 0xDC95, 0x8EDA, 0xDC96,
+	0x8EDB, 0xDC97, 0x8EDC, 0xDC98, 0x8EDD, 0xDC99, 0x8EDE, 0xDC9A,
+	0x8EDF, 0xDC9B, 0x8EE0, 0xDC9C, 0x8EE1, 0xDC9D, 0x8EE2, 0xDC9E,
+	0x8EE3, 0xDC9F, 0x8EE4, 0xDCA0, 0x8EE5, 0xDD40, 0x8EE6, 0xDD41,
+	0x8EE7, 0xDD42, 0x8EE8, 0xDD43, 0x8EE9, 0xDD44, 0x8EEA, 0xDD45,
+	0x8EEB, 0xDD46, 0x8EEC, 0xDD47, 0x8EED, 0xDD48, 0x8EEE, 0xDD49,
+	0x8EEF, 0xDD4A, 0x8EF0, 0xDD4B, 0x8EF1, 0xDD4C, 0x8EF2, 0xDD4D,
+	0x8EF3, 0xDD4E, 0x8EF4, 0xDD4F, 0x8EF5, 0xDD50, 0x8EF6, 0xDD51,
+	0x8EF7, 0xDD52, 0x8EF8, 0xDD53, 0x8EF9, 0xDD54, 0x8EFA, 0xDD55,
+	0x8EFB, 0xDD56, 0x8EFC, 0xDD57, 0x8EFD, 0xDD58, 0x8EFE, 0xDD59,
+	0x8EFF, 0xDD5A, 0x8F00, 0xDD5B, 0x8F01, 0xDD5C, 0x8F02, 0xDD5D,
+	0x8F03, 0xDD5E, 0x8F04, 0xDD5F, 0x8F05, 0xDD60, 0x8F06, 0xDD61,
+	0x8F07, 0xDD62, 0x8F08, 0xDD63, 0x8F09, 0xDD64, 0x8F0A, 0xDD65,
+	0x8F0B, 0xDD66, 0x8F0C, 0xDD67, 0x8F0D, 0xDD68, 0x8F0E, 0xDD69,
+	0x8F0F, 0xDD6A, 0x8F10, 0xDD6B, 0x8F11, 0xDD6C, 0x8F12, 0xDD6D,
+	0x8F13, 0xDD6E, 0x8F14, 0xDD6F, 0x8F15, 0xDD70, 0x8F16, 0xDD71,
+	0x8F17, 0xDD72, 0x8F18, 0xDD73, 0x8F19, 0xDD74, 0x8F1A, 0xDD75,
+	0x8F1B, 0xDD76, 0x8F1C, 0xDD77, 0x8F1D, 0xDD78, 0x8F1E, 0xDD79,
+	0x8F1F, 0xDD7A, 0x8F20, 0xDD7B, 0x8F21, 0xDD7C, 0x8F22, 0xDD7D,
+	0x8F23, 0xDD7E, 0x8F24, 0xDD80, 0x8F25, 0xDD81, 0x8F26, 0xDD82,
+	0x8F27, 0xDD83, 0x8F28, 0xDD84, 0x8F29, 0xDD85, 0x8F2A, 0xDD86,
+	0x8F2B, 0xDD87, 0x8F2C, 0xDD88, 0x8F2D, 0xDD89, 0x8F2E, 0xDD8A,
+	0x8F2F, 0xDD8B, 0x8F30, 0xDD8C, 0x8F31, 0xDD8D, 0x8F32, 0xDD8E,
+	0x8F33, 0xDD8F, 0x8F34, 0xDD90, 0x8F35, 0xDD91, 0x8F36, 0xDD92,
+	0x8F37, 0xDD93, 0x8F38, 0xDD94, 0x8F39, 0xDD95, 0x8F3A, 0xDD96,
+	0x8F3B, 0xDD97, 0x8F3C, 0xDD98, 0x8F3D, 0xDD99, 0x8F3E, 0xDD9A,
+	0x8F3F, 0xDD9B, 0x8F40, 0xDD9C, 0x8F41, 0xDD9D, 0x8F42, 0xDD9E,
+	0x8F43, 0xDD9F, 0x8F44, 0xDDA0, 0x8F45, 0xDE40, 0x8F46, 0xDE41,
+	0x8F47, 0xDE42, 0x8F48, 0xDE43, 0x8F49, 0xDE44, 0x8F4A, 0xDE45,
+	0x8F4B, 0xDE46, 0x8F4C, 0xDE47, 0x8F4D, 0xDE48, 0x8F4E, 0xDE49,
+	0x8F4F, 0xDE4A, 0x8F50, 0xDE4B, 0x8F51, 0xDE4C, 0x8F52, 0xDE4D,
+	0x8F53, 0xDE4E, 0x8F54, 0xDE4F, 0x8F55, 0xDE50, 0x8F56, 0xDE51,
+	0x8F57, 0xDE52, 0x8F58, 0xDE53, 0x8F59, 0xDE54, 0x8F5A, 0xDE55,
+	0x8F5B, 0xDE56, 0x8F5C, 0xDE57, 0x8F5D, 0xDE58, 0x8F5E, 0xDE59,
+	0x8F5F, 0xDE5A, 0x8F60, 0xDE5B, 0x8F61, 0xDE5C, 0x8F62, 0xDE5D,
+	0x8F63, 0xDE5E, 0x8F64, 0xDE5F, 0x8F65, 0xDE60, 0x8F66, 0xB3B5,
+	0x8F67, 0xD4FE, 0x8F68, 0xB9EC, 0x8F69, 0xD0F9, 0x8F6A, 0xDE61,
+	0x8F6B, 0xE9ED, 0x8F6C, 0xD7AA, 0x8F6D, 0xE9EE, 0x8F6E, 0xC2D6,
+	0x8F6F, 0xC8ED, 0x8F70, 0xBAE4, 0x8F71, 0xE9EF, 0x8F72, 0xE9F0,
+	0x8F73, 0xE9F1, 0x8F74, 0xD6E1, 0x8F75, 0xE9F2, 0x8F76, 0xE9F3,
+	0x8F77, 0xE9F5, 0x8F78, 0xE9F4, 0x8F79, 0xE9F6, 0x8F7A, 0xE9F7,
+	0x8F7B, 0xC7E1, 0x8F7C, 0xE9F8, 0x8F7D, 0xD4D8, 0x8F7E, 0xE9F9,
+	0x8F7F, 0xBDCE, 0x8F80, 0xDE62, 0x8F81, 0xE9FA, 0x8F82, 0xE9FB,
+	0x8F83, 0xBDCF, 0x8F84, 0xE9FC, 0x8F85, 0xB8A8, 0x8F86, 0xC1BE,
+	0x8F87, 0xE9FD, 0x8F88, 0xB1B2, 0x8F89, 0xBBD4, 0x8F8A, 0xB9F5,
+	0x8F8B, 0xE9FE, 0x8F8C, 0xDE63, 0x8F8D, 0xEAA1, 0x8F8E, 0xEAA2,
+	0x8F8F, 0xEAA3, 0x8F90, 0xB7F8, 0x8F91, 0xBCAD, 0x8F92, 0xDE64,
+	0x8F93, 0xCAE4, 0x8F94, 0xE0CE, 0x8F95, 0xD4AF, 0x8F96, 0xCFBD,
+	0x8F97, 0xD5B7, 0x8F98, 0xEAA4, 0x8F99, 0xD5DE, 0x8F9A, 0xEAA5,
+	0x8F9B, 0xD0C1, 0x8F9C, 0xB9BC, 0x8F9D, 0xDE65, 0x8F9E, 0xB4C7,
+	0x8F9F, 0xB1D9, 0x8FA0, 0xDE66, 0x8FA1, 0xDE67, 0x8FA2, 0xDE68,
+	0x8FA3, 0xC0B1, 0x8FA4, 0xDE69, 0x8FA5, 0xDE6A, 0x8FA6, 0xDE6B,
+	0x8FA7, 0xDE6C, 0x8FA8, 0xB1E6, 0x8FA9, 0xB1E7, 0x8FAA, 0xDE6D,
+	0x8FAB, 0xB1E8, 0x8FAC, 0xDE6E, 0x8FAD, 0xDE6F, 0x8FAE, 0xDE70,
+	0x8FAF, 0xDE71, 0x8FB0, 0xB3BD, 0x8FB1, 0xC8E8, 0x8FB2, 0xDE72,
+	0x8FB3, 0xDE73, 0x8FB4, 0xDE74, 0x8FB5, 0xDE75, 0x8FB6, 0xE5C1,
+	0x8FB7, 0xDE76, 0x8FB8, 0xDE77, 0x8FB9, 0xB1DF, 0x8FBA, 0xDE78,
+	0x8FBB, 0xDE79, 0x8FBC, 0xDE7A, 0x8FBD, 0xC1C9, 0x8FBE, 0xB4EF,
+	0x8FBF, 0xDE7B, 0x8FC0, 0xDE7C, 0x8FC1, 0xC7A8, 0x8FC2, 0xD3D8,
+	0x8FC3, 0xDE7D, 0x8FC4, 0xC6F9, 0x8FC5, 0xD1B8, 0x8FC6, 0xDE7E,
+	0x8FC7, 0xB9FD, 0x8FC8, 0xC2F5, 0x8FC9, 0xDE80, 0x8FCA, 0xDE81,
+	0x8FCB, 0xDE82, 0x8FCC, 0xDE83, 0x8FCD, 0xDE84, 0x8FCE, 0xD3AD,
+	0x8FCF, 0xDE85, 0x8FD0, 0xD4CB, 0x8FD1, 0xBDFC, 0x8FD2, 0xDE86,
+	0x8FD3, 0xE5C2, 0x8FD4, 0xB7B5, 0x8FD5, 0xE5C3, 0x8FD6, 0xDE87,
+	0x8FD7, 0xDE88, 0x8FD8, 0xBBB9, 0x8FD9, 0xD5E2, 0x8FDA, 0xDE89,
+	0x8FDB, 0xBDF8, 0x8FDC, 0xD4B6, 0x8FDD, 0xCEA5, 0x8FDE, 0xC1AC,
+	0x8FDF, 0xB3D9, 0x8FE0, 0xDE8A, 0x8FE1, 0xDE8B, 0x8FE2, 0xCCF6,
+	0x8FE3, 0xDE8C, 0x8FE4, 0xE5C6, 0x8FE5, 0xE5C4, 0x8FE6, 0xE5C8,
+	0x8FE7, 0xDE8D, 0x8FE8, 0xE5CA, 0x8FE9, 0xE5C7, 0x8FEA, 0xB5CF,
+	0x8FEB, 0xC6C8, 0x8FEC, 0xDE8E, 0x8FED, 0xB5FC, 0x8FEE, 0xE5C5,
+	0x8FEF, 0xDE8F, 0x8FF0, 0xCAF6, 0x8FF1, 0xDE90, 0x8FF2, 0xDE91,
+	0x8FF3, 0xE5C9, 0x8FF4, 0xDE92, 0x8FF5, 0xDE93, 0x8FF6, 0xDE94,
+	0x8FF7, 0xC3D4, 0x8FF8, 0xB1C5, 0x8FF9, 0xBCA3, 0x8FFA, 0xDE95,
+	0x8FFB, 0xDE96, 0x8FFC, 0xDE97, 0x8FFD, 0xD7B7, 0x8FFE, 0xDE98,
+	0x8FFF, 0xDE99, 0x9000, 0xCDCB, 0x9001, 0xCBCD, 0x9002, 0xCACA,
+	0x9003, 0xCCD3, 0x9004, 0xE5CC, 0x9005, 0xE5CB, 0x9006, 0xC4E6,
+	0x9007, 0xDE9A, 0x9008, 0xDE9B, 0x9009, 0xD1A1, 0x900A, 0xD1B7,
+	0x900B, 0xE5CD, 0x900C, 0xDE9C, 0x900D, 0xE5D0, 0x900E, 0xDE9D,
+	0x900F, 0xCDB8, 0x9010, 0xD6F0, 0x9011, 0xE5CF, 0x9012, 0xB5DD,
+	0x9013, 0xDE9E, 0x9014, 0xCDBE, 0x9015, 0xDE9F, 0x9016, 0xE5D1,
+	0x9017, 0xB6BA, 0x9018, 0xDEA0, 0x9019, 0xDF40, 0x901A, 0xCDA8,
+	0x901B, 0xB9E4, 0x901C, 0xDF41, 0x901D, 0xCAC5, 0x901E, 0xB3D1,
+	0x901F, 0xCBD9, 0x9020, 0xD4EC, 0x9021, 0xE5D2, 0x9022, 0xB7EA,
+	0x9023, 0xDF42, 0x9024, 0xDF43, 0x9025, 0xDF44, 0x9026, 0xE5CE,
+	0x9027, 0xDF45, 0x9028, 0xDF46, 0x9029, 0xDF47, 0x902A, 0xDF48,
+	0x902B, 0xDF49, 0x902C, 0xDF4A, 0x902D, 0xE5D5, 0x902E, 0xB4FE,
+	0x902F, 0xE5D6, 0x9030, 0xDF4B, 0x9031, 0xDF4C, 0x9032, 0xDF4D,
+	0x9033, 0xDF4E, 0x9034, 0xDF4F, 0x9035, 0xE5D3, 0x9036, 0xE5D4,
+	0x9037, 0xDF50, 0x9038, 0xD2DD, 0x9039, 0xDF51, 0x903A, 0xDF52,
+	0x903B, 0xC2DF, 0x903C, 0xB1C6, 0x903D, 0xDF53, 0x903E, 0xD3E2,
+	0x903F, 0xDF54, 0x9040, 0xDF55, 0x9041, 0xB6DD, 0x9042, 0xCBEC,
+	0x9043, 0xDF56, 0x9044, 0xE5D7, 0x9045, 0xDF57, 0x9046, 0xDF58,
+	0x9047, 0xD3F6, 0x9048, 0xDF59, 0x9049, 0xDF5A, 0x904A, 0xDF5B,
+	0x904B, 0xDF5C, 0x904C, 0xDF5D, 0x904D, 0xB1E9, 0x904E, 0xDF5E,
+	0x904F, 0xB6F4, 0x9050, 0xE5DA, 0x9051, 0xE5D8, 0x9052, 0xE5D9,
+	0x9053, 0xB5C0, 0x9054, 0xDF5F, 0x9055, 0xDF60, 0x9056, 0xDF61,
+	0x9057, 0xD2C5, 0x9058, 0xE5DC, 0x9059, 0xDF62, 0x905A, 0xDF63,
+	0x905B, 0xE5DE, 0x905C, 0xDF64, 0x905D, 0xDF65, 0x905E, 0xDF66,
+	0x905F, 0xDF67, 0x9060, 0xDF68, 0x9061, 0xDF69, 0x9062, 0xE5DD,
+	0x9063, 0xC7B2, 0x9064, 0xDF6A, 0x9065, 0xD2A3, 0x9066, 0xDF6B,
+	0x9067, 0xDF6C, 0x9068, 0xE5DB, 0x9069, 0xDF6D, 0x906A, 0xDF6E,
+	0x906B, 0xDF6F, 0x906C, 0xDF70, 0x906D, 0xD4E2, 0x906E, 0xD5DA,
+	0x906F, 0xDF71, 0x9070, 0xDF72, 0x9071, 0xDF73, 0x9072, 0xDF74,
+	0x9073, 0xDF75, 0x9074, 0xE5E0, 0x9075, 0xD7F1, 0x9076, 0xDF76,
+	0x9077, 0xDF77, 0x9078, 0xDF78, 0x9079, 0xDF79, 0x907A, 0xDF7A,
+	0x907B, 0xDF7B, 0x907C, 0xDF7C, 0x907D, 0xE5E1, 0x907E, 0xDF7D,
+	0x907F, 0xB1DC, 0x9080, 0xD1FB, 0x9081, 0xDF7E, 0x9082, 0xE5E2,
+	0x9083, 0xE5E4, 0x9084, 0xDF80, 0x9085, 0xDF81, 0x9086, 0xDF82,
+	0x9087, 0xDF83, 0x9088, 0xE5E3, 0x9089, 0xDF84, 0x908A, 0xDF85,
+	0x908B, 0xE5E5, 0x908C, 0xDF86, 0x908D, 0xDF87, 0x908E, 0xDF88,
+	0x908F, 0xDF89, 0x9090, 0xDF8A, 0x9091, 0xD2D8, 0x9092, 0xDF8B,
+	0x9093, 0xB5CB, 0x9094, 0xDF8C, 0x9095, 0xE7DF, 0x9096, 0xDF8D,
+	0x9097, 0xDAF5, 0x9098, 0xDF8E, 0x9099, 0xDAF8, 0x909A, 0xDF8F,
+	0x909B, 0xDAF6, 0x909C, 0xDF90, 0x909D, 0xDAF7, 0x909E, 0xDF91,
+	0x909F, 0xDF92, 0x90A0, 0xDF93, 0x90A1, 0xDAFA, 0x90A2, 0xD0CF,
+	0x90A3, 0xC4C7, 0x90A4, 0xDF94, 0x90A5, 0xDF95, 0x90A6, 0xB0EE,
+	0x90A7, 0xDF96, 0x90A8, 0xDF97, 0x90A9, 0xDF98, 0x90AA, 0xD0B0,
+	0x90AB, 0xDF99, 0x90AC, 0xDAF9, 0x90AD, 0xDF9A, 0x90AE, 0xD3CA,
+	0x90AF, 0xBAAA, 0x90B0, 0xDBA2, 0x90B1, 0xC7F1, 0x90B2, 0xDF9B,
+	0x90B3, 0xDAFC, 0x90B4, 0xDAFB, 0x90B5, 0xC9DB, 0x90B6, 0xDAFD,
+	0x90B7, 0xDF9C, 0x90B8, 0xDBA1, 0x90B9, 0xD7DE, 0x90BA, 0xDAFE,
+	0x90BB, 0xC1DA, 0x90BC, 0xDF9D, 0x90BD, 0xDF9E, 0x90BE, 0xDBA5,
+	0x90BF, 0xDF9F, 0x90C0, 0xDFA0, 0x90C1, 0xD3F4, 0x90C2, 0xE040,
+	0x90C3, 0xE041, 0x90C4, 0xDBA7, 0x90C5, 0xDBA4, 0x90C6, 0xE042,
+	0x90C7, 0xDBA8, 0x90C8, 0xE043, 0x90C9, 0xE044, 0x90CA, 0xBDBC,
+	0x90CB, 0xE045, 0x90CC, 0xE046, 0x90CD, 0xE047, 0x90CE, 0xC0C9,
+	0x90CF, 0xDBA3, 0x90D0, 0xDBA6, 0x90D1, 0xD6A3, 0x90D2, 0xE048,
+	0x90D3, 0xDBA9, 0x90D4, 0xE049, 0x90D5, 0xE04A, 0x90D6, 0xE04B,
+	0x90D7, 0xDBAD, 0x90D8, 0xE04C, 0x90D9, 0xE04D, 0x90DA, 0xE04E,
+	0x90DB, 0xDBAE, 0x90DC, 0xDBAC, 0x90DD, 0xBAC2, 0x90DE, 0xE04F,
+	0x90DF, 0xE050, 0x90E0, 0xE051, 0x90E1, 0xBFA4, 0x90E2, 0xDBAB,
+	0x90E3, 0xE052, 0x90E4, 0xE053, 0x90E5, 0xE054, 0x90E6, 0xDBAA,
+	0x90E7, 0xD4C7, 0x90E8, 0xB2BF, 0x90E9, 0xE055, 0x90EA, 0xE056,
+	0x90EB, 0xDBAF, 0x90EC, 0xE057, 0x90ED, 0xB9F9, 0x90EE, 0xE058,
+	0x90EF, 0xDBB0, 0x90F0, 0xE059, 0x90F1, 0xE05A, 0x90F2, 0xE05B,
+	0x90F3, 0xE05C, 0x90F4, 0xB3BB, 0x90F5, 0xE05D, 0x90F6, 0xE05E,
+	0x90F7, 0xE05F, 0x90F8, 0xB5A6, 0x90F9, 0xE060, 0x90FA, 0xE061,
+	0x90FB, 0xE062, 0x90FC, 0xE063, 0x90FD, 0xB6BC, 0x90FE, 0xDBB1,
+	0x90FF, 0xE064, 0x9100, 0xE065, 0x9101, 0xE066, 0x9102, 0xB6F5,
+	0x9103, 0xE067, 0x9104, 0xDBB2, 0x9105, 0xE068, 0x9106, 0xE069,
+	0x9107, 0xE06A, 0x9108, 0xE06B, 0x9109, 0xE06C, 0x910A, 0xE06D,
+	0x910B, 0xE06E, 0x910C, 0xE06F, 0x910D, 0xE070, 0x910E, 0xE071,
+	0x910F, 0xE072, 0x9110, 0xE073, 0x9111, 0xE074, 0x9112, 0xE075,
+	0x9113, 0xE076, 0x9114, 0xE077, 0x9115, 0xE078, 0x9116, 0xE079,
+	0x9117, 0xE07A, 0x9118, 0xE07B, 0x9119, 0xB1C9, 0x911A, 0xE07C,
+	0x911B, 0xE07D, 0x911C, 0xE07E, 0x911D, 0xE080, 0x911E, 0xDBB4,
+	0x911F, 0xE081, 0x9120, 0xE082, 0x9121, 0xE083, 0x9122, 0xDBB3,
+	0x9123, 0xDBB5, 0x9124, 0xE084, 0x9125, 0xE085, 0x9126, 0xE086,
+	0x9127, 0xE087, 0x9128, 0xE088, 0x9129, 0xE089, 0x912A, 0xE08A,
+	0x912B, 0xE08B, 0x912C, 0xE08C, 0x912D, 0xE08D, 0x912E, 0xE08E,
+	0x912F, 0xDBB7, 0x9130, 0xE08F, 0x9131, 0xDBB6, 0x9132, 0xE090,
+	0x9133, 0xE091, 0x9134, 0xE092, 0x9135, 0xE093, 0x9136, 0xE094,
+	0x9137, 0xE095, 0x9138, 0xE096, 0x9139, 0xDBB8, 0x913A, 0xE097,
+	0x913B, 0xE098, 0x913C, 0xE099, 0x913D, 0xE09A, 0x913E, 0xE09B,
+	0x913F, 0xE09C, 0x9140, 0xE09D, 0x9141, 0xE09E, 0x9142, 0xE09F,
+	0x9143, 0xDBB9, 0x9144, 0xE0A0, 0x9145, 0xE140, 0x9146, 0xDBBA,
+	0x9147, 0xE141, 0x9148, 0xE142, 0x9149, 0xD3CF, 0x914A, 0xF4FA,
+	0x914B, 0xC7F5, 0x914C, 0xD7C3, 0x914D, 0xC5E4, 0x914E, 0xF4FC,
+	0x914F, 0xF4FD, 0x9150, 0xF4FB, 0x9151, 0xE143, 0x9152, 0xBEC6,
+	0x9153, 0xE144, 0x9154, 0xE145, 0x9155, 0xE146, 0x9156, 0xE147,
+	0x9157, 0xD0EF, 0x9158, 0xE148, 0x9159, 0xE149, 0x915A, 0xB7D3,
+	0x915B, 0xE14A, 0x915C, 0xE14B, 0x915D, 0xD4CD, 0x915E, 0xCCAA,
+	0x915F, 0xE14C, 0x9160, 0xE14D, 0x9161, 0xF5A2, 0x9162, 0xF5A1,
+	0x9163, 0xBAA8, 0x9164, 0xF4FE, 0x9165, 0xCBD6, 0x9166, 0xE14E,
+	0x9167, 0xE14F, 0x9168, 0xE150, 0x9169, 0xF5A4, 0x916A, 0xC0D2,
+	0x916B, 0xE151, 0x916C, 0xB3EA, 0x916D, 0xE152, 0x916E, 0xCDAA,
+	0x916F, 0xF5A5, 0x9170, 0xF5A3, 0x9171, 0xBDB4, 0x9172, 0xF5A8,
+	0x9173, 0xE153, 0x9174, 0xF5A9, 0x9175, 0xBDCD, 0x9176, 0xC3B8,
+	0x9177, 0xBFE1, 0x9178, 0xCBE1, 0x9179, 0xF5AA, 0x917A, 0xE154,
+	0x917B, 0xE155, 0x917C, 0xE156, 0x917D, 0xF5A6, 0x917E, 0xF5A7,
+	0x917F, 0xC4F0, 0x9180, 0xE157, 0x9181, 0xE158, 0x9182, 0xE159,
+	0x9183, 0xE15A, 0x9184, 0xE15B, 0x9185, 0xF5AC, 0x9186, 0xE15C,
+	0x9187, 0xB4BC, 0x9188, 0xE15D, 0x9189, 0xD7ED, 0x918A, 0xE15E,
+	0x918B, 0xB4D7, 0x918C, 0xF5AB, 0x918D, 0xF5AE, 0x918E, 0xE15F,
+	0x918F, 0xE160, 0x9190, 0xF5AD, 0x9191, 0xF5AF, 0x9192, 0xD0D1,
+	0x9193, 0xE161, 0x9194, 0xE162, 0x9195, 0xE163, 0x9196, 0xE164,
+	0x9197, 0xE165, 0x9198, 0xE166, 0x9199, 0xE167, 0x919A, 0xC3D1,
+	0x919B, 0xC8A9, 0x919C, 0xE168, 0x919D, 0xE169, 0x919E, 0xE16A,
+	0x919F, 0xE16B, 0x91A0, 0xE16C, 0x91A1, 0xE16D, 0x91A2, 0xF5B0,
+	0x91A3, 0xF5B1, 0x91A4, 0xE16E, 0x91A5, 0xE16F, 0x91A6, 0xE170,
+	0x91A7, 0xE171, 0x91A8, 0xE172, 0x91A9, 0xE173, 0x91AA, 0xF5B2,
+	0x91AB, 0xE174, 0x91AC, 0xE175, 0x91AD, 0xF5B3, 0x91AE, 0xF5B4,
+	0x91AF, 0xF5B5, 0x91B0, 0xE176, 0x91B1, 0xE177, 0x91B2, 0xE178,
+	0x91B3, 0xE179, 0x91B4, 0xF5B7, 0x91B5, 0xF5B6, 0x91B6, 0xE17A,
+	0x91B7, 0xE17B, 0x91B8, 0xE17C, 0x91B9, 0xE17D, 0x91BA, 0xF5B8,
+	0x91BB, 0xE17E, 0x91BC, 0xE180, 0x91BD, 0xE181, 0x91BE, 0xE182,
+	0x91BF, 0xE183, 0x91C0, 0xE184, 0x91C1, 0xE185, 0x91C2, 0xE186,
+	0x91C3, 0xE187, 0x91C4, 0xE188, 0x91C5, 0xE189, 0x91C6, 0xE18A,
+	0x91C7, 0xB2C9, 0x91C8, 0xE18B, 0x91C9, 0xD3D4, 0x91CA, 0xCACD,
+	0x91CB, 0xE18C, 0x91CC, 0xC0EF, 0x91CD, 0xD6D8, 0x91CE, 0xD2B0,
+	0x91CF, 0xC1BF, 0x91D0, 0xE18D, 0x91D1, 0xBDF0, 0x91D2, 0xE18E,
+	0x91D3, 0xE18F, 0x91D4, 0xE190, 0x91D5, 0xE191, 0x91D6, 0xE192,
+	0x91D7, 0xE193, 0x91D8, 0xE194, 0x91D9, 0xE195, 0x91DA, 0xE196,
+	0x91DB, 0xE197, 0x91DC, 0xB8AA, 0x91DD, 0xE198, 0x91DE, 0xE199,
+	0x91DF, 0xE19A, 0x91E0, 0xE19B, 0x91E1, 0xE19C, 0x91E2, 0xE19D,
+	0x91E3, 0xE19E, 0x91E4, 0xE19F, 0x91E5, 0xE1A0, 0x91E6, 0xE240,
+	0x91E7, 0xE241, 0x91E8, 0xE242, 0x91E9, 0xE243, 0x91EA, 0xE244,
+	0x91EB, 0xE245, 0x91EC, 0xE246, 0x91ED, 0xE247, 0x91EE, 0xE248,
+	0x91EF, 0xE249, 0x91F0, 0xE24A, 0x91F1, 0xE24B, 0x91F2, 0xE24C,
+	0x91F3, 0xE24D, 0x91F4, 0xE24E, 0x91F5, 0xE24F, 0x91F6, 0xE250,
+	0x91F7, 0xE251, 0x91F8, 0xE252, 0x91F9, 0xE253, 0x91FA, 0xE254,
+	0x91FB, 0xE255, 0x91FC, 0xE256, 0x91FD, 0xE257, 0x91FE, 0xE258,
+	0x91FF, 0xE259, 0x9200, 0xE25A, 0x9201, 0xE25B, 0x9202, 0xE25C,
+	0x9203, 0xE25D, 0x9204, 0xE25E, 0x9205, 0xE25F, 0x9206, 0xE260,
+	0x9207, 0xE261, 0x9208, 0xE262, 0x9209, 0xE263, 0x920A, 0xE264,
+	0x920B, 0xE265, 0x920C, 0xE266, 0x920D, 0xE267, 0x920E, 0xE268,
+	0x920F, 0xE269, 0x9210, 0xE26A, 0x9211, 0xE26B, 0x9212, 0xE26C,
+	0x9213, 0xE26D, 0x9214, 0xE26E, 0x9215, 0xE26F, 0x9216, 0xE270,
+	0x9217, 0xE271, 0x9218, 0xE272, 0x9219, 0xE273, 0x921A, 0xE274,
+	0x921B, 0xE275, 0x921C, 0xE276, 0x921D, 0xE277, 0x921E, 0xE278,
+	0x921F, 0xE279, 0x9220, 0xE27A, 0x9221, 0xE27B, 0x9222, 0xE27C,
+	0x9223, 0xE27D, 0x9224, 0xE27E, 0x9225, 0xE280, 0x9226, 0xE281,
+	0x9227, 0xE282, 0x9228, 0xE283, 0x9229, 0xE284, 0x922A, 0xE285,
+	0x922B, 0xE286, 0x922C, 0xE287, 0x922D, 0xE288, 0x922E, 0xE289,
+	0x922F, 0xE28A, 0x9230, 0xE28B, 0x9231, 0xE28C, 0x9232, 0xE28D,
+	0x9233, 0xE28E, 0x9234, 0xE28F, 0x9235, 0xE290, 0x9236, 0xE291,
+	0x9237, 0xE292, 0x9238, 0xE293, 0x9239, 0xE294, 0x923A, 0xE295,
+	0x923B, 0xE296, 0x923C, 0xE297, 0x923D, 0xE298, 0x923E, 0xE299,
+	0x923F, 0xE29A, 0x9240, 0xE29B, 0x9241, 0xE29C, 0x9242, 0xE29D,
+	0x9243, 0xE29E, 0x9244, 0xE29F, 0x9245, 0xE2A0, 0x9246, 0xE340,
+	0x9247, 0xE341, 0x9248, 0xE342, 0x9249, 0xE343, 0x924A, 0xE344,
+	0x924B, 0xE345, 0x924C, 0xE346, 0x924D, 0xE347, 0x924E, 0xE348,
+	0x924F, 0xE349, 0x9250, 0xE34A, 0x9251, 0xE34B, 0x9252, 0xE34C,
+	0x9253, 0xE34D, 0x9254, 0xE34E, 0x9255, 0xE34F, 0x9256, 0xE350,
+	0x9257, 0xE351, 0x9258, 0xE352, 0x9259, 0xE353, 0x925A, 0xE354,
+	0x925B, 0xE355, 0x925C, 0xE356, 0x925D, 0xE357, 0x925E, 0xE358,
+	0x925F, 0xE359, 0x9260, 0xE35A, 0x9261, 0xE35B, 0x9262, 0xE35C,
+	0x9263, 0xE35D, 0x9264, 0xE35E, 0x9265, 0xE35F, 0x9266, 0xE360,
+	0x9267, 0xE361, 0x9268, 0xE362, 0x9269, 0xE363, 0x926A, 0xE364,
+	0x926B, 0xE365, 0x926C, 0xE366, 0x926D, 0xE367, 0x926E, 0xE368,
+	0x926F, 0xE369, 0x9270, 0xE36A, 0x9271, 0xE36B, 0x9272, 0xE36C,
+	0x9273, 0xE36D, 0x9274, 0xBCF8, 0x9275, 0xE36E, 0x9276, 0xE36F,
+	0x9277, 0xE370, 0x9278, 0xE371, 0x9279, 0xE372, 0x927A, 0xE373,
+	0x927B, 0xE374, 0x927C, 0xE375, 0x927D, 0xE376, 0x927E, 0xE377,
+	0x927F, 0xE378, 0x9280, 0xE379, 0x9281, 0xE37A, 0x9282, 0xE37B,
+	0x9283, 0xE37C, 0x9284, 0xE37D, 0x9285, 0xE37E, 0x9286, 0xE380,
+	0x9287, 0xE381, 0x9288, 0xE382, 0x9289, 0xE383, 0x928A, 0xE384,
+	0x928B, 0xE385, 0x928C, 0xE386, 0x928D, 0xE387, 0x928E, 0xF6C6,
+	0x928F, 0xE388, 0x9290, 0xE389, 0x9291, 0xE38A, 0x9292, 0xE38B,
+	0x9293, 0xE38C, 0x9294, 0xE38D, 0x9295, 0xE38E, 0x9296, 0xE38F,
+	0x9297, 0xE390, 0x9298, 0xE391, 0x9299, 0xE392, 0x929A, 0xE393,
+	0x929B, 0xE394, 0x929C, 0xE395, 0x929D, 0xE396, 0x929E, 0xE397,
+	0x929F, 0xE398, 0x92A0, 0xE399, 0x92A1, 0xE39A, 0x92A2, 0xE39B,
+	0x92A3, 0xE39C, 0x92A4, 0xE39D, 0x92A5, 0xE39E, 0x92A6, 0xE39F,
+	0x92A7, 0xE3A0, 0x92A8, 0xE440, 0x92A9, 0xE441, 0x92AA, 0xE442,
+	0x92AB, 0xE443, 0x92AC, 0xE444, 0x92AD, 0xE445, 0x92AE, 0xF6C7,
+	0x92AF, 0xE446, 0x92B0, 0xE447, 0x92B1, 0xE448, 0x92B2, 0xE449,
+	0x92B3, 0xE44A, 0x92B4, 0xE44B, 0x92B5, 0xE44C, 0x92B6, 0xE44D,
+	0x92B7, 0xE44E, 0x92B8, 0xE44F, 0x92B9, 0xE450, 0x92BA, 0xE451,
+	0x92BB, 0xE452, 0x92BC, 0xE453, 0x92BD, 0xE454, 0x92BE, 0xE455,
+	0x92BF, 0xE456, 0x92C0, 0xE457, 0x92C1, 0xE458, 0x92C2, 0xE459,
+	0x92C3, 0xE45A, 0x92C4, 0xE45B, 0x92C5, 0xE45C, 0x92C6, 0xE45D,
+	0x92C7, 0xE45E, 0x92C8, 0xF6C8, 0x92C9, 0xE45F, 0x92CA, 0xE460,
+	0x92CB, 0xE461, 0x92CC, 0xE462, 0x92CD, 0xE463, 0x92CE, 0xE464,
+	0x92CF, 0xE465, 0x92D0, 0xE466, 0x92D1, 0xE467, 0x92D2, 0xE468,
+	0x92D3, 0xE469, 0x92D4, 0xE46A, 0x92D5, 0xE46B, 0x92D6, 0xE46C,
+	0x92D7, 0xE46D, 0x92D8, 0xE46E, 0x92D9, 0xE46F, 0x92DA, 0xE470,
+	0x92DB, 0xE471, 0x92DC, 0xE472, 0x92DD, 0xE473, 0x92DE, 0xE474,
+	0x92DF, 0xE475, 0x92E0, 0xE476, 0x92E1, 0xE477, 0x92E2, 0xE478,
+	0x92E3, 0xE479, 0x92E4, 0xE47A, 0x92E5, 0xE47B, 0x92E6, 0xE47C,
+	0x92E7, 0xE47D, 0x92E8, 0xE47E, 0x92E9, 0xE480, 0x92EA, 0xE481,
+	0x92EB, 0xE482, 0x92EC, 0xE483, 0x92ED, 0xE484, 0x92EE, 0xE485,
+	0x92EF, 0xE486, 0x92F0, 0xE487, 0x92F1, 0xE488, 0x92F2, 0xE489,
+	0x92F3, 0xE48A, 0x92F4, 0xE48B, 0x92F5, 0xE48C, 0x92F6, 0xE48D,
+	0x92F7, 0xE48E, 0x92F8, 0xE48F, 0x92F9, 0xE490, 0x92FA, 0xE491,
+	0x92FB, 0xE492, 0x92FC, 0xE493, 0x92FD, 0xE494, 0x92FE, 0xE495,
+	0x92FF, 0xE496, 0x9300, 0xE497, 0x9301, 0xE498, 0x9302, 0xE499,
+	0x9303, 0xE49A, 0x9304, 0xE49B, 0x9305, 0xE49C, 0x9306, 0xE49D,
+	0x9307, 0xE49E, 0x9308, 0xE49F, 0x9309, 0xE4A0, 0x930A, 0xE540,
+	0x930B, 0xE541, 0x930C, 0xE542, 0x930D, 0xE543, 0x930E, 0xE544,
+	0x930F, 0xE545, 0x9310, 0xE546, 0x9311, 0xE547, 0x9312, 0xE548,
+	0x9313, 0xE549, 0x9314, 0xE54A, 0x9315, 0xE54B, 0x9316, 0xE54C,
+	0x9317, 0xE54D, 0x9318, 0xE54E, 0x9319, 0xE54F, 0x931A, 0xE550,
+	0x931B, 0xE551, 0x931C, 0xE552, 0x931D, 0xE553, 0x931E, 0xE554,
+	0x931F, 0xE555, 0x9320, 0xE556, 0x9321, 0xE557, 0x9322, 0xE558,
+	0x9323, 0xE559, 0x9324, 0xE55A, 0x9325, 0xE55B, 0x9326, 0xE55C,
+	0x9327, 0xE55D, 0x9328, 0xE55E, 0x9329, 0xE55F, 0x932A, 0xE560,
+	0x932B, 0xE561, 0x932C, 0xE562, 0x932D, 0xE563, 0x932E, 0xE564,
+	0x932F, 0xE565, 0x9330, 0xE566, 0x9331, 0xE567, 0x9332, 0xE568,
+	0x9333, 0xE569, 0x9334, 0xE56A, 0x9335, 0xE56B, 0x9336, 0xE56C,
+	0x9337, 0xE56D, 0x9338, 0xE56E, 0x9339, 0xE56F, 0x933A, 0xE570,
+	0x933B, 0xE571, 0x933C, 0xE572, 0x933D, 0xE573, 0x933E, 0xF6C9,
+	0x933F, 0xE574, 0x9340, 0xE575, 0x9341, 0xE576, 0x9342, 0xE577,
+	0x9343, 0xE578, 0x9344, 0xE579, 0x9345, 0xE57A, 0x9346, 0xE57B,
+	0x9347, 0xE57C, 0x9348, 0xE57D, 0x9349, 0xE57E, 0x934A, 0xE580,
+	0x934B, 0xE581, 0x934C, 0xE582, 0x934D, 0xE583, 0x934E, 0xE584,
+	0x934F, 0xE585, 0x9350, 0xE586, 0x9351, 0xE587, 0x9352, 0xE588,
+	0x9353, 0xE589, 0x9354, 0xE58A, 0x9355, 0xE58B, 0x9356, 0xE58C,
+	0x9357, 0xE58D, 0x9358, 0xE58E, 0x9359, 0xE58F, 0x935A, 0xE590,
+	0x935B, 0xE591, 0x935C, 0xE592, 0x935D, 0xE593, 0x935E, 0xE594,
+	0x935F, 0xE595, 0x9360, 0xE596, 0x9361, 0xE597, 0x9362, 0xE598,
+	0x9363, 0xE599, 0x9364, 0xE59A, 0x9365, 0xE59B, 0x9366, 0xE59C,
+	0x9367, 0xE59D, 0x9368, 0xE59E, 0x9369, 0xE59F, 0x936A, 0xF6CA,
+	0x936B, 0xE5A0, 0x936C, 0xE640, 0x936D, 0xE641, 0x936E, 0xE642,
+	0x936F, 0xE643, 0x9370, 0xE644, 0x9371, 0xE645, 0x9372, 0xE646,
+	0x9373, 0xE647, 0x9374, 0xE648, 0x9375, 0xE649, 0x9376, 0xE64A,
+	0x9377, 0xE64B, 0x9378, 0xE64C, 0x9379, 0xE64D, 0x937A, 0xE64E,
+	0x937B, 0xE64F, 0x937C, 0xE650, 0x937D, 0xE651, 0x937E, 0xE652,
+	0x937F, 0xE653, 0x9380, 0xE654, 0x9381, 0xE655, 0x9382, 0xE656,
+	0x9383, 0xE657, 0x9384, 0xE658, 0x9385, 0xE659, 0x9386, 0xE65A,
+	0x9387, 0xE65B, 0x9388, 0xE65C, 0x9389, 0xE65D, 0x938A, 0xE65E,
+	0x938B, 0xE65F, 0x938C, 0xE660, 0x938D, 0xE661, 0x938E, 0xE662,
+	0x938F, 0xF6CC, 0x9390, 0xE663, 0x9391, 0xE664, 0x9392, 0xE665,
+	0x9393, 0xE666, 0x9394, 0xE667, 0x9395, 0xE668, 0x9396, 0xE669,
+	0x9397, 0xE66A, 0x9398, 0xE66B, 0x9399, 0xE66C, 0x939A, 0xE66D,
+	0x939B, 0xE66E, 0x939C, 0xE66F, 0x939D, 0xE670, 0x939E, 0xE671,
+	0x939F, 0xE672, 0x93A0, 0xE673, 0x93A1, 0xE674, 0x93A2, 0xE675,
+	0x93A3, 0xE676, 0x93A4, 0xE677, 0x93A5, 0xE678, 0x93A6, 0xE679,
+	0x93A7, 0xE67A, 0x93A8, 0xE67B, 0x93A9, 0xE67C, 0x93AA, 0xE67D,
+	0x93AB, 0xE67E, 0x93AC, 0xE680, 0x93AD, 0xE681, 0x93AE, 0xE682,
+	0x93AF, 0xE683, 0x93B0, 0xE684, 0x93B1, 0xE685, 0x93B2, 0xE686,
+	0x93B3, 0xE687, 0x93B4, 0xE688, 0x93B5, 0xE689, 0x93B6, 0xE68A,
+	0x93B7, 0xE68B, 0x93B8, 0xE68C, 0x93B9, 0xE68D, 0x93BA, 0xE68E,
+	0x93BB, 0xE68F, 0x93BC, 0xE690, 0x93BD, 0xE691, 0x93BE, 0xE692,
+	0x93BF, 0xE693, 0x93C0, 0xE694, 0x93C1, 0xE695, 0x93C2, 0xE696,
+	0x93C3, 0xE697, 0x93C4, 0xE698, 0x93C5, 0xE699, 0x93C6, 0xE69A,
+	0x93C7, 0xE69B, 0x93C8, 0xE69C, 0x93C9, 0xE69D, 0x93CA, 0xF6CB,
+	0x93CB, 0xE69E, 0x93CC, 0xE69F, 0x93CD, 0xE6A0, 0x93CE, 0xE740,
+	0x93CF, 0xE741, 0x93D0, 0xE742, 0x93D1, 0xE743, 0x93D2, 0xE744,
+	0x93D3, 0xE745, 0x93D4, 0xE746, 0x93D5, 0xE747, 0x93D6, 0xF7E9,
+	0x93D7, 0xE748, 0x93D8, 0xE749, 0x93D9, 0xE74A, 0x93DA, 0xE74B,
+	0x93DB, 0xE74C, 0x93DC, 0xE74D, 0x93DD, 0xE74E, 0x93DE, 0xE74F,
+	0x93DF, 0xE750, 0x93E0, 0xE751, 0x93E1, 0xE752, 0x93E2, 0xE753,
+	0x93E3, 0xE754, 0x93E4, 0xE755, 0x93E5, 0xE756, 0x93E6, 0xE757,
+	0x93E7, 0xE758, 0x93E8, 0xE759, 0x93E9, 0xE75A, 0x93EA, 0xE75B,
+	0x93EB, 0xE75C, 0x93EC, 0xE75D, 0x93ED, 0xE75E, 0x93EE, 0xE75F,
+	0x93EF, 0xE760, 0x93F0, 0xE761, 0x93F1, 0xE762, 0x93F2, 0xE763,
+	0x93F3, 0xE764, 0x93F4, 0xE765, 0x93F5, 0xE766, 0x93F6, 0xE767,
+	0x93F7, 0xE768, 0x93F8, 0xE769, 0x93F9, 0xE76A, 0x93FA, 0xE76B,
+	0x93FB, 0xE76C, 0x93FC, 0xE76D, 0x93FD, 0xE76E, 0x93FE, 0xE76F,
+	0x93FF, 0xE770, 0x9400, 0xE771, 0x9401, 0xE772, 0x9402, 0xE773,
+	0x9403, 0xE774, 0x9404, 0xE775, 0x9405, 0xE776, 0x9406, 0xE777,
+	0x9407, 0xE778, 0x9408, 0xE779, 0x9409, 0xE77A, 0x940A, 0xE77B,
+	0x940B, 0xE77C, 0x940C, 0xE77D, 0x940D, 0xE77E, 0x940E, 0xE780,
+	0x940F, 0xE781, 0x9410, 0xE782, 0x9411, 0xE783, 0x9412, 0xE784,
+	0x9413, 0xE785, 0x9414, 0xE786, 0x9415, 0xE787, 0x9416, 0xE788,
+	0x9417, 0xE789, 0x9418, 0xE78A, 0x9419, 0xE78B, 0x941A, 0xE78C,
+	0x941B, 0xE78D, 0x941C, 0xE78E, 0x941D, 0xE78F, 0x941E, 0xE790,
+	0x941F, 0xE791, 0x9420, 0xE792, 0x9421, 0xE793, 0x9422, 0xE794,
+	0x9423, 0xE795, 0x9424, 0xE796, 0x9425, 0xE797, 0x9426, 0xE798,
+	0x9427, 0xE799, 0x9428, 0xE79A, 0x9429, 0xE79B, 0x942A, 0xE79C,
+	0x942B, 0xE79D, 0x942C, 0xE79E, 0x942D, 0xE79F, 0x942E, 0xE7A0,
+	0x942F, 0xE840, 0x9430, 0xE841, 0x9431, 0xE842, 0x9432, 0xE843,
+	0x9433, 0xE844, 0x9434, 0xE845, 0x9435, 0xE846, 0x9436, 0xE847,
+	0x9437, 0xE848, 0x9438, 0xE849, 0x9439, 0xE84A, 0x943A, 0xE84B,
+	0x943B, 0xE84C, 0x943C, 0xE84D, 0x943D, 0xE84E, 0x943E, 0xF6CD,
+	0x943F, 0xE84F, 0x9440, 0xE850, 0x9441, 0xE851, 0x9442, 0xE852,
+	0x9443, 0xE853, 0x9444, 0xE854, 0x9445, 0xE855, 0x9446, 0xE856,
+	0x9447, 0xE857, 0x9448, 0xE858, 0x9449, 0xE859, 0x944A, 0xE85A,
+	0x944B, 0xE85B, 0x944C, 0xE85C, 0x944D, 0xE85D, 0x944E, 0xE85E,
+	0x944F, 0xE85F, 0x9450, 0xE860, 0x9451, 0xE861, 0x9452, 0xE862,
+	0x9453, 0xE863, 0x9454, 0xE864, 0x9455, 0xE865, 0x9456, 0xE866,
+	0x9457, 0xE867, 0x9458, 0xE868, 0x9459, 0xE869, 0x945A, 0xE86A,
+	0x945B, 0xE86B, 0x945C, 0xE86C, 0x945D, 0xE86D, 0x945E, 0xE86E,
+	0x945F, 0xE86F, 0x9460, 0xE870, 0x9461, 0xE871, 0x9462, 0xE872,
+	0x9463, 0xE873, 0x9464, 0xE874, 0x9465, 0xE875, 0x9466, 0xE876,
+	0x9467, 0xE877, 0x9468, 0xE878, 0x9469, 0xE879, 0x946A, 0xE87A,
+	0x946B, 0xF6CE, 0x946C, 0xE87B, 0x946D, 0xE87C, 0x946E, 0xE87D,
+	0x946F, 0xE87E, 0x9470, 0xE880, 0x9471, 0xE881, 0x9472, 0xE882,
+	0x9473, 0xE883, 0x9474, 0xE884, 0x9475, 0xE885, 0x9476, 0xE886,
+	0x9477, 0xE887, 0x9478, 0xE888, 0x9479, 0xE889, 0x947A, 0xE88A,
+	0x947B, 0xE88B, 0x947C, 0xE88C, 0x947D, 0xE88D, 0x947E, 0xE88E,
+	0x947F, 0xE88F, 0x9480, 0xE890, 0x9481, 0xE891, 0x9482, 0xE892,
+	0x9483, 0xE893, 0x9484, 0xE894, 0x9485, 0xEEC4, 0x9486, 0xEEC5,
+	0x9487, 0xEEC6, 0x9488, 0xD5EB, 0x9489, 0xB6A4, 0x948A, 0xEEC8,
+	0x948B, 0xEEC7, 0x948C, 0xEEC9, 0x948D, 0xEECA, 0x948E, 0xC7A5,
+	0x948F, 0xEECB, 0x9490, 0xEECC, 0x9491, 0xE895, 0x9492, 0xB7B0,
+	0x9493, 0xB5F6, 0x9494, 0xEECD, 0x9495, 0xEECF, 0x9496, 0xE896,
+	0x9497, 0xEECE, 0x9498, 0xE897, 0x9499, 0xB8C6, 0x949A, 0xEED0,
+	0x949B, 0xEED1, 0x949C, 0xEED2, 0x949D, 0xB6DB, 0x949E, 0xB3AE,
+	0x949F, 0xD6D3, 0x94A0, 0xC4C6, 0x94A1, 0xB1B5, 0x94A2, 0xB8D6,
+	0x94A3, 0xEED3, 0x94A4, 0xEED4, 0x94A5, 0xD4BF, 0x94A6, 0xC7D5,
+	0x94A7, 0xBEFB, 0x94A8, 0xCED9, 0x94A9, 0xB9B3, 0x94AA, 0xEED6,
+	0x94AB, 0xEED5, 0x94AC, 0xEED8, 0x94AD, 0xEED7, 0x94AE, 0xC5A5,
+	0x94AF, 0xEED9, 0x94B0, 0xEEDA, 0x94B1, 0xC7AE, 0x94B2, 0xEEDB,
+	0x94B3, 0xC7AF, 0x94B4, 0xEEDC, 0x94B5, 0xB2A7, 0x94B6, 0xEEDD,
+	0x94B7, 0xEEDE, 0x94B8, 0xEEDF, 0x94B9, 0xEEE0, 0x94BA, 0xEEE1,
+	0x94BB, 0xD7EA, 0x94BC, 0xEEE2, 0x94BD, 0xEEE3, 0x94BE, 0xBCD8,
+	0x94BF, 0xEEE4, 0x94C0, 0xD3CB, 0x94C1, 0xCCFA, 0x94C2, 0xB2AC,
+	0x94C3, 0xC1E5, 0x94C4, 0xEEE5, 0x94C5, 0xC7A6, 0x94C6, 0xC3AD,
+	0x94C7, 0xE898, 0x94C8, 0xEEE6, 0x94C9, 0xEEE7, 0x94CA, 0xEEE8,
+	0x94CB, 0xEEE9, 0x94CC, 0xEEEA, 0x94CD, 0xEEEB, 0x94CE, 0xEEEC,
+	0x94CF, 0xE899, 0x94D0, 0xEEED, 0x94D1, 0xEEEE, 0x94D2, 0xEEEF,
+	0x94D3, 0xE89A, 0x94D4, 0xE89B, 0x94D5, 0xEEF0, 0x94D6, 0xEEF1,
+	0x94D7, 0xEEF2, 0x94D8, 0xEEF4, 0x94D9, 0xEEF3, 0x94DA, 0xE89C,
+	0x94DB, 0xEEF5, 0x94DC, 0xCDAD, 0x94DD, 0xC2C1, 0x94DE, 0xEEF6,
+	0x94DF, 0xEEF7, 0x94E0, 0xEEF8, 0x94E1, 0xD5A1, 0x94E2, 0xEEF9,
+	0x94E3, 0xCFB3, 0x94E4, 0xEEFA, 0x94E5, 0xEEFB, 0x94E6, 0xE89D,
+	0x94E7, 0xEEFC, 0x94E8, 0xEEFD, 0x94E9, 0xEFA1, 0x94EA, 0xEEFE,
+	0x94EB, 0xEFA2, 0x94EC, 0xB8F5, 0x94ED, 0xC3FA, 0x94EE, 0xEFA3,
+	0x94EF, 0xEFA4, 0x94F0, 0xBDC2, 0x94F1, 0xD2BF, 0x94F2, 0xB2F9,
+	0x94F3, 0xEFA5, 0x94F4, 0xEFA6, 0x94F5, 0xEFA7, 0x94F6, 0xD2F8,
+	0x94F7, 0xEFA8, 0x94F8, 0xD6FD, 0x94F9, 0xEFA9, 0x94FA, 0xC6CC,
+	0x94FB, 0xE89E, 0x94FC, 0xEFAA, 0x94FD, 0xEFAB, 0x94FE, 0xC1B4,
+	0x94FF, 0xEFAC, 0x9500, 0xCFFA, 0x9501, 0xCBF8, 0x9502, 0xEFAE,
+	0x9503, 0xEFAD, 0x9504, 0xB3FA, 0x9505, 0xB9F8, 0x9506, 0xEFAF,
+	0x9507, 0xEFB0, 0x9508, 0xD0E2, 0x9509, 0xEFB1, 0x950A, 0xEFB2,
+	0x950B, 0xB7E6, 0x950C, 0xD0BF, 0x950D, 0xEFB3, 0x950E, 0xEFB4,
+	0x950F, 0xEFB5, 0x9510, 0xC8F1, 0x9511, 0xCCE0, 0x9512, 0xEFB6,
+	0x9513, 0xEFB7, 0x9514, 0xEFB8, 0x9515, 0xEFB9, 0x9516, 0xEFBA,
+	0x9517, 0xD5E0, 0x9518, 0xEFBB, 0x9519, 0xB4ED, 0x951A, 0xC3AA,
+	0x951B, 0xEFBC, 0x951C, 0xE89F, 0x951D, 0xEFBD, 0x951E, 0xEFBE,
+	0x951F, 0xEFBF, 0x9520, 0xE8A0, 0x9521, 0xCEFD, 0x9522, 0xEFC0,
+	0x9523, 0xC2E0, 0x9524, 0xB4B8, 0x9525, 0xD7B6, 0x9526, 0xBDF5,
+	0x9527, 0xE940, 0x9528, 0xCFC7, 0x9529, 0xEFC3, 0x952A, 0xEFC1,
+	0x952B, 0xEFC2, 0x952C, 0xEFC4, 0x952D, 0xB6A7, 0x952E, 0xBCFC,
+	0x952F, 0xBEE2, 0x9530, 0xC3CC, 0x9531, 0xEFC5, 0x9532, 0xEFC6,
+	0x9533, 0xE941, 0x9534, 0xEFC7, 0x9535, 0xEFCF, 0x9536, 0xEFC8,
+	0x9537, 0xEFC9, 0x9538, 0xEFCA, 0x9539, 0xC7C2, 0x953A, 0xEFF1,
+	0x953B, 0xB6CD, 0x953C, 0xEFCB, 0x953D, 0xE942, 0x953E, 0xEFCC,
+	0x953F, 0xEFCD, 0x9540, 0xB6C6, 0x9541, 0xC3BE, 0x9542, 0xEFCE,
+	0x9543, 0xE943, 0x9544, 0xEFD0, 0x9545, 0xEFD1, 0x9546, 0xEFD2,
+	0x9547, 0xD5F2, 0x9548, 0xE944, 0x9549, 0xEFD3, 0x954A, 0xC4F7,
+	0x954B, 0xE945, 0x954C, 0xEFD4, 0x954D, 0xC4F8, 0x954E, 0xEFD5,
+	0x954F, 0xEFD6, 0x9550, 0xB8E4, 0x9551, 0xB0F7, 0x9552, 0xEFD7,
+	0x9553, 0xEFD8, 0x9554, 0xEFD9, 0x9555, 0xE946, 0x9556, 0xEFDA,
+	0x9557, 0xEFDB, 0x9558, 0xEFDC, 0x9559, 0xEFDD, 0x955A, 0xE947,
+	0x955B, 0xEFDE, 0x955C, 0xBEB5, 0x955D, 0xEFE1, 0x955E, 0xEFDF,
+	0x955F, 0xEFE0, 0x9560, 0xE948, 0x9561, 0xEFE2, 0x9562, 0xEFE3,
+	0x9563, 0xC1CD, 0x9564, 0xEFE4, 0x9565, 0xEFE5, 0x9566, 0xEFE6,
+	0x9567, 0xEFE7, 0x9568, 0xEFE8, 0x9569, 0xEFE9, 0x956A, 0xEFEA,
+	0x956B, 0xEFEB, 0x956C, 0xEFEC, 0x956D, 0xC0D8, 0x956E, 0xE949,
+	0x956F, 0xEFED, 0x9570, 0xC1AD, 0x9571, 0xEFEE, 0x9572, 0xEFEF,
+	0x9573, 0xEFF0, 0x9574, 0xE94A, 0x9575, 0xE94B, 0x9576, 0xCFE2,
+	0x9577, 0xE94C, 0x9578, 0xE94D, 0x9579, 0xE94E, 0x957A, 0xE94F,
+	0x957B, 0xE950, 0x957C, 0xE951, 0x957D, 0xE952, 0x957E, 0xE953,
+	0x957F, 0xB3A4, 0x9580, 0xE954, 0x9581, 0xE955, 0x9582, 0xE956,
+	0x9583, 0xE957, 0x9584, 0xE958, 0x9585, 0xE959, 0x9586, 0xE95A,
+	0x9587, 0xE95B, 0x9588, 0xE95C, 0x9589, 0xE95D, 0x958A, 0xE95E,
+	0x958B, 0xE95F, 0x958C, 0xE960, 0x958D, 0xE961, 0x958E, 0xE962,
+	0x958F, 0xE963, 0x9590, 0xE964, 0x9591, 0xE965, 0x9592, 0xE966,
+	0x9593, 0xE967, 0x9594, 0xE968, 0x9595, 0xE969, 0x9596, 0xE96A,
+	0x9597, 0xE96B, 0x9598, 0xE96C, 0x9599, 0xE96D, 0x959A, 0xE96E,
+	0x959B, 0xE96F, 0x959C, 0xE970, 0x959D, 0xE971, 0x959E, 0xE972,
+	0x959F, 0xE973, 0x95A0, 0xE974, 0x95A1, 0xE975, 0x95A2, 0xE976,
+	0x95A3, 0xE977, 0x95A4, 0xE978, 0x95A5, 0xE979, 0x95A6, 0xE97A,
+	0x95A7, 0xE97B, 0x95A8, 0xE97C, 0x95A9, 0xE97D, 0x95AA, 0xE97E,
+	0x95AB, 0xE980, 0x95AC, 0xE981, 0x95AD, 0xE982, 0x95AE, 0xE983,
+	0x95AF, 0xE984, 0x95B0, 0xE985, 0x95B1, 0xE986, 0x95B2, 0xE987,
+	0x95B3, 0xE988, 0x95B4, 0xE989, 0x95B5, 0xE98A, 0x95B6, 0xE98B,
+	0x95B7, 0xE98C, 0x95B8, 0xE98D, 0x95B9, 0xE98E, 0x95BA, 0xE98F,
+	0x95BB, 0xE990, 0x95BC, 0xE991, 0x95BD, 0xE992, 0x95BE, 0xE993,
+	0x95BF, 0xE994, 0x95C0, 0xE995, 0x95C1, 0xE996, 0x95C2, 0xE997,
+	0x95C3, 0xE998, 0x95C4, 0xE999, 0x95C5, 0xE99A, 0x95C6, 0xE99B,
+	0x95C7, 0xE99C, 0x95C8, 0xE99D, 0x95C9, 0xE99E, 0x95CA, 0xE99F,
+	0x95CB, 0xE9A0, 0x95CC, 0xEA40, 0x95CD, 0xEA41, 0x95CE, 0xEA42,
+	0x95CF, 0xEA43, 0x95D0, 0xEA44, 0x95D1, 0xEA45, 0x95D2, 0xEA46,
+	0x95D3, 0xEA47, 0x95D4, 0xEA48, 0x95D5, 0xEA49, 0x95D6, 0xEA4A,
+	0x95D7, 0xEA4B, 0x95D8, 0xEA4C, 0x95D9, 0xEA4D, 0x95DA, 0xEA4E,
+	0x95DB, 0xEA4F, 0x95DC, 0xEA50, 0x95DD, 0xEA51, 0x95DE, 0xEA52,
+	0x95DF, 0xEA53, 0x95E0, 0xEA54, 0x95E1, 0xEA55, 0x95E2, 0xEA56,
+	0x95E3, 0xEA57, 0x95E4, 0xEA58, 0x95E5, 0xEA59, 0x95E6, 0xEA5A,
+	0x95E7, 0xEA5B, 0x95E8, 0xC3C5, 0x95E9, 0xE3C5, 0x95EA, 0xC9C1,
+	0x95EB, 0xE3C6, 0x95EC, 0xEA5C, 0x95ED, 0xB1D5, 0x95EE, 0xCECA,
+	0x95EF, 0xB4B3, 0x95F0, 0xC8F2, 0x95F1, 0xE3C7, 0x95F2, 0xCFD0,
+	0x95F3, 0xE3C8, 0x95F4, 0xBCE4, 0x95F5, 0xE3C9, 0x95F6, 0xE3CA,
+	0x95F7, 0xC3C6, 0x95F8, 0xD5A2, 0x95F9, 0xC4D6, 0x95FA, 0xB9EB,
+	0x95FB, 0xCEC5, 0x95FC, 0xE3CB, 0x95FD, 0xC3F6, 0x95FE, 0xE3CC,
+	0x95FF, 0xEA5D, 0x9600, 0xB7A7, 0x9601, 0xB8F3, 0x9602, 0xBAD2,
+	0x9603, 0xE3CD, 0x9604, 0xE3CE, 0x9605, 0xD4C4, 0x9606, 0xE3CF,
+	0x9607, 0xEA5E, 0x9608, 0xE3D0, 0x9609, 0xD1CB, 0x960A, 0xE3D1,
+	0x960B, 0xE3D2, 0x960C, 0xE3D3, 0x960D, 0xE3D4, 0x960E, 0xD1D6,
+	0x960F, 0xE3D5, 0x9610, 0xB2FB, 0x9611, 0xC0BB, 0x9612, 0xE3D6,
+	0x9613, 0xEA5F, 0x9614, 0xC0AB, 0x9615, 0xE3D7, 0x9616, 0xE3D8,
+	0x9617, 0xE3D9, 0x9618, 0xEA60, 0x9619, 0xE3DA, 0x961A, 0xE3DB,
+	0x961B, 0xEA61, 0x961C, 0xB8B7, 0x961D, 0xDAE2, 0x961E, 0xEA62,
+	0x961F, 0xB6D3, 0x9620, 0xEA63, 0x9621, 0xDAE4, 0x9622, 0xDAE3,
+	0x9623, 0xEA64, 0x9624, 0xEA65, 0x9625, 0xEA66, 0x9626, 0xEA67,
+	0x9627, 0xEA68, 0x9628, 0xEA69, 0x9629, 0xEA6A, 0x962A, 0xDAE6,
+	0x962B, 0xEA6B, 0x962C, 0xEA6C, 0x962D, 0xEA6D, 0x962E, 0xC8EE,
+	0x962F, 0xEA6E, 0x9630, 0xEA6F, 0x9631, 0xDAE5, 0x9632, 0xB7C0,
+	0x9633, 0xD1F4, 0x9634, 0xD2F5, 0x9635, 0xD5F3, 0x9636, 0xBDD7,
+	0x9637, 0xEA70, 0x9638, 0xEA71, 0x9639, 0xEA72, 0x963A, 0xEA73,
+	0x963B, 0xD7E8, 0x963C, 0xDAE8, 0x963D, 0xDAE7, 0x963E, 0xEA74,
+	0x963F, 0xB0A2, 0x9640, 0xCDD3, 0x9641, 0xEA75, 0x9642, 0xDAE9,
+	0x9643, 0xEA76, 0x9644, 0xB8BD, 0x9645, 0xBCCA, 0x9646, 0xC2BD,
+	0x9647, 0xC2A4, 0x9648, 0xB3C2, 0x9649, 0xDAEA, 0x964A, 0xEA77,
+	0x964B, 0xC2AA, 0x964C, 0xC4B0, 0x964D, 0xBDB5, 0x964E, 0xEA78,
+	0x964F, 0xEA79, 0x9650, 0xCFDE, 0x9651, 0xEA7A, 0x9652, 0xEA7B,
+	0x9653, 0xEA7C, 0x9654, 0xDAEB, 0x9655, 0xC9C2, 0x9656, 0xEA7D,
+	0x9657, 0xEA7E, 0x9658, 0xEA80, 0x9659, 0xEA81, 0x965A, 0xEA82,
+	0x965B, 0xB1DD, 0x965C, 0xEA83, 0x965D, 0xEA84, 0x965E, 0xEA85,
+	0x965F, 0xDAEC, 0x9660, 0xEA86, 0x9661, 0xB6B8, 0x9662, 0xD4BA,
+	0x9663, 0xEA87, 0x9664, 0xB3FD, 0x9665, 0xEA88, 0x9666, 0xEA89,
+	0x9667, 0xDAED, 0x9668, 0xD4C9, 0x9669, 0xCFD5, 0x966A, 0xC5E3,
+	0x966B, 0xEA8A, 0x966C, 0xDAEE, 0x966D, 0xEA8B, 0x966E, 0xEA8C,
+	0x966F, 0xEA8D, 0x9670, 0xEA8E, 0x9671, 0xEA8F, 0x9672, 0xDAEF,
+	0x9673, 0xEA90, 0x9674, 0xDAF0, 0x9675, 0xC1EA, 0x9676, 0xCCD5,
+	0x9677, 0xCFDD, 0x9678, 0xEA91, 0x9679, 0xEA92, 0x967A, 0xEA93,
+	0x967B, 0xEA94, 0x967C, 0xEA95, 0x967D, 0xEA96, 0x967E, 0xEA97,
+	0x967F, 0xEA98, 0x9680, 0xEA99, 0x9681, 0xEA9A, 0x9682, 0xEA9B,
+	0x9683, 0xEA9C, 0x9684, 0xEA9D, 0x9685, 0xD3E7, 0x9686, 0xC2A1,
+	0x9687, 0xEA9E, 0x9688, 0xDAF1, 0x9689, 0xEA9F, 0x968A, 0xEAA0,
+	0x968B, 0xCBE5, 0x968C, 0xEB40, 0x968D, 0xDAF2, 0x968E, 0xEB41,
+	0x968F, 0xCBE6, 0x9690, 0xD2FE, 0x9691, 0xEB42, 0x9692, 0xEB43,
+	0x9693, 0xEB44, 0x9694, 0xB8F4, 0x9695, 0xEB45, 0x9696, 0xEB46,
+	0x9697, 0xDAF3, 0x9698, 0xB0AF, 0x9699, 0xCFB6, 0x969A, 0xEB47,
+	0x969B, 0xEB48, 0x969C, 0xD5CF, 0x969D, 0xEB49, 0x969E, 0xEB4A,
+	0x969F, 0xEB4B, 0x96A0, 0xEB4C, 0x96A1, 0xEB4D, 0x96A2, 0xEB4E,
+	0x96A3, 0xEB4F, 0x96A4, 0xEB50, 0x96A5, 0xEB51, 0x96A6, 0xEB52,
+	0x96A7, 0xCBED, 0x96A8, 0xEB53, 0x96A9, 0xEB54, 0x96AA, 0xEB55,
+	0x96AB, 0xEB56, 0x96AC, 0xEB57, 0x96AD, 0xEB58, 0x96AE, 0xEB59,
+	0x96AF, 0xEB5A, 0x96B0, 0xDAF4, 0x96B1, 0xEB5B, 0x96B2, 0xEB5C,
+	0x96B3, 0xE3C4, 0x96B4, 0xEB5D, 0x96B5, 0xEB5E, 0x96B6, 0xC1A5,
+	0x96B7, 0xEB5F, 0x96B8, 0xEB60, 0x96B9, 0xF6BF, 0x96BA, 0xEB61,
+	0x96BB, 0xEB62, 0x96BC, 0xF6C0, 0x96BD, 0xF6C1, 0x96BE, 0xC4D1,
+	0x96BF, 0xEB63, 0x96C0, 0xC8B8, 0x96C1, 0xD1E3, 0x96C2, 0xEB64,
+	0x96C3, 0xEB65, 0x96C4, 0xD0DB, 0x96C5, 0xD1C5, 0x96C6, 0xBCAF,
+	0x96C7, 0xB9CD, 0x96C8, 0xEB66, 0x96C9, 0xEFF4, 0x96CA, 0xEB67,
+	0x96CB, 0xEB68, 0x96CC, 0xB4C6, 0x96CD, 0xD3BA, 0x96CE, 0xF6C2,
+	0x96CF, 0xB3FB, 0x96D0, 0xEB69, 0x96D1, 0xEB6A, 0x96D2, 0xF6C3,
+	0x96D3, 0xEB6B, 0x96D4, 0xEB6C, 0x96D5, 0xB5F1, 0x96D6, 0xEB6D,
+	0x96D7, 0xEB6E, 0x96D8, 0xEB6F, 0x96D9, 0xEB70, 0x96DA, 0xEB71,
+	0x96DB, 0xEB72, 0x96DC, 0xEB73, 0x96DD, 0xEB74, 0x96DE, 0xEB75,
+	0x96DF, 0xEB76, 0x96E0, 0xF6C5, 0x96E1, 0xEB77, 0x96E2, 0xEB78,
+	0x96E3, 0xEB79, 0x96E4, 0xEB7A, 0x96E5, 0xEB7B, 0x96E6, 0xEB7C,
+	0x96E7, 0xEB7D, 0x96E8, 0xD3EA, 0x96E9, 0xF6A7, 0x96EA, 0xD1A9,
+	0x96EB, 0xEB7E, 0x96EC, 0xEB80, 0x96ED, 0xEB81, 0x96EE, 0xEB82,
+	0x96EF, 0xF6A9, 0x96F0, 0xEB83, 0x96F1, 0xEB84, 0x96F2, 0xEB85,
+	0x96F3, 0xF6A8, 0x96F4, 0xEB86, 0x96F5, 0xEB87, 0x96F6, 0xC1E3,
+	0x96F7, 0xC0D7, 0x96F8, 0xEB88, 0x96F9, 0xB1A2, 0x96FA, 0xEB89,
+	0x96FB, 0xEB8A, 0x96FC, 0xEB8B, 0x96FD, 0xEB8C, 0x96FE, 0xCEED,
+	0x96FF, 0xEB8D, 0x9700, 0xD0E8, 0x9701, 0xF6AB, 0x9702, 0xEB8E,
+	0x9703, 0xEB8F, 0x9704, 0xCFF6, 0x9705, 0xEB90, 0x9706, 0xF6AA,
+	0x9707, 0xD5F0, 0x9708, 0xF6AC, 0x9709, 0xC3B9, 0x970A, 0xEB91,
+	0x970B, 0xEB92, 0x970C, 0xEB93, 0x970D, 0xBBF4, 0x970E, 0xF6AE,
+	0x970F, 0xF6AD, 0x9710, 0xEB94, 0x9711, 0xEB95, 0x9712, 0xEB96,
+	0x9713, 0xC4DE, 0x9714, 0xEB97, 0x9715, 0xEB98, 0x9716, 0xC1D8,
+	0x9717, 0xEB99, 0x9718, 0xEB9A, 0x9719, 0xEB9B, 0x971A, 0xEB9C,
+	0x971B, 0xEB9D, 0x971C, 0xCBAA, 0x971D, 0xEB9E, 0x971E, 0xCFBC,
+	0x971F, 0xEB9F, 0x9720, 0xEBA0, 0x9721, 0xEC40, 0x9722, 0xEC41,
+	0x9723, 0xEC42, 0x9724, 0xEC43, 0x9725, 0xEC44, 0x9726, 0xEC45,
+	0x9727, 0xEC46, 0x9728, 0xEC47, 0x9729, 0xEC48, 0x972A, 0xF6AF,
+	0x972B, 0xEC49, 0x972C, 0xEC4A, 0x972D, 0xF6B0, 0x972E, 0xEC4B,
+	0x972F, 0xEC4C, 0x9730, 0xF6B1, 0x9731, 0xEC4D, 0x9732, 0xC2B6,
+	0x9733, 0xEC4E, 0x9734, 0xEC4F, 0x9735, 0xEC50, 0x9736, 0xEC51,
+	0x9737, 0xEC52, 0x9738, 0xB0D4, 0x9739, 0xC5F9, 0x973A, 0xEC53,
+	0x973B, 0xEC54, 0x973C, 0xEC55, 0x973D, 0xEC56, 0x973E, 0xF6B2,
+	0x973F, 0xEC57, 0x9740, 0xEC58, 0x9741, 0xEC59, 0x9742, 0xEC5A,
+	0x9743, 0xEC5B, 0x9744, 0xEC5C, 0x9745, 0xEC5D, 0x9746, 0xEC5E,
+	0x9747, 0xEC5F, 0x9748, 0xEC60, 0x9749, 0xEC61, 0x974A, 0xEC62,
+	0x974B, 0xEC63, 0x974C, 0xEC64, 0x974D, 0xEC65, 0x974E, 0xEC66,
+	0x974F, 0xEC67, 0x9750, 0xEC68, 0x9751, 0xEC69, 0x9752, 0xC7E0,
+	0x9753, 0xF6A6, 0x9754, 0xEC6A, 0x9755, 0xEC6B, 0x9756, 0xBEB8,
+	0x9757, 0xEC6C, 0x9758, 0xEC6D, 0x9759, 0xBEB2, 0x975A, 0xEC6E,
+	0x975B, 0xB5E5, 0x975C, 0xEC6F, 0x975D, 0xEC70, 0x975E, 0xB7C7,
+	0x975F, 0xEC71, 0x9760, 0xBFBF, 0x9761, 0xC3D2, 0x9762, 0xC3E6,
+	0x9763, 0xEC72, 0x9764, 0xEC73, 0x9765, 0xD8CC, 0x9766, 0xEC74,
+	0x9767, 0xEC75, 0x9768, 0xEC76, 0x9769, 0xB8EF, 0x976A, 0xEC77,
+	0x976B, 0xEC78, 0x976C, 0xEC79, 0x976D, 0xEC7A, 0x976E, 0xEC7B,
+	0x976F, 0xEC7C, 0x9770, 0xEC7D, 0x9771, 0xEC7E, 0x9772, 0xEC80,
+	0x9773, 0xBDF9, 0x9774, 0xD1A5, 0x9775, 0xEC81, 0x9776, 0xB0D0,
+	0x9777, 0xEC82, 0x9778, 0xEC83, 0x9779, 0xEC84, 0x977A, 0xEC85,
+	0x977B, 0xEC86, 0x977C, 0xF7B0, 0x977D, 0xEC87, 0x977E, 0xEC88,
+	0x977F, 0xEC89, 0x9780, 0xEC8A, 0x9781, 0xEC8B, 0x9782, 0xEC8C,
+	0x9783, 0xEC8D, 0x9784, 0xEC8E, 0x9785, 0xF7B1, 0x9786, 0xEC8F,
+	0x9787, 0xEC90, 0x9788, 0xEC91, 0x9789, 0xEC92, 0x978A, 0xEC93,
+	0x978B, 0xD0AC, 0x978C, 0xEC94, 0x978D, 0xB0B0, 0x978E, 0xEC95,
+	0x978F, 0xEC96, 0x9790, 0xEC97, 0x9791, 0xF7B2, 0x9792, 0xF7B3,
+	0x9793, 0xEC98, 0x9794, 0xF7B4, 0x9795, 0xEC99, 0x9796, 0xEC9A,
+	0x9797, 0xEC9B, 0x9798, 0xC7CA, 0x9799, 0xEC9C, 0x979A, 0xEC9D,
+	0x979B, 0xEC9E, 0x979C, 0xEC9F, 0x979D, 0xECA0, 0x979E, 0xED40,
+	0x979F, 0xED41, 0x97A0, 0xBECF, 0x97A1, 0xED42, 0x97A2, 0xED43,
+	0x97A3, 0xF7B7, 0x97A4, 0xED44, 0x97A5, 0xED45, 0x97A6, 0xED46,
+	0x97A7, 0xED47, 0x97A8, 0xED48, 0x97A9, 0xED49, 0x97AA, 0xED4A,
+	0x97AB, 0xF7B6, 0x97AC, 0xED4B, 0x97AD, 0xB1DE, 0x97AE, 0xED4C,
+	0x97AF, 0xF7B5, 0x97B0, 0xED4D, 0x97B1, 0xED4E, 0x97B2, 0xF7B8,
+	0x97B3, 0xED4F, 0x97B4, 0xF7B9, 0x97B5, 0xED50, 0x97B6, 0xED51,
+	0x97B7, 0xED52, 0x97B8, 0xED53, 0x97B9, 0xED54, 0x97BA, 0xED55,
+	0x97BB, 0xED56, 0x97BC, 0xED57, 0x97BD, 0xED58, 0x97BE, 0xED59,
+	0x97BF, 0xED5A, 0x97C0, 0xED5B, 0x97C1, 0xED5C, 0x97C2, 0xED5D,
+	0x97C3, 0xED5E, 0x97C4, 0xED5F, 0x97C5, 0xED60, 0x97C6, 0xED61,
+	0x97C7, 0xED62, 0x97C8, 0xED63, 0x97C9, 0xED64, 0x97CA, 0xED65,
+	0x97CB, 0xED66, 0x97CC, 0xED67, 0x97CD, 0xED68, 0x97CE, 0xED69,
+	0x97CF, 0xED6A, 0x97D0, 0xED6B, 0x97D1, 0xED6C, 0x97D2, 0xED6D,
+	0x97D3, 0xED6E, 0x97D4, 0xED6F, 0x97D5, 0xED70, 0x97D6, 0xED71,
+	0x97D7, 0xED72, 0x97D8, 0xED73, 0x97D9, 0xED74, 0x97DA, 0xED75,
+	0x97DB, 0xED76, 0x97DC, 0xED77, 0x97DD, 0xED78, 0x97DE, 0xED79,
+	0x97DF, 0xED7A, 0x97E0, 0xED7B, 0x97E1, 0xED7C, 0x97E2, 0xED7D,
+	0x97E3, 0xED7E, 0x97E4, 0xED80, 0x97E5, 0xED81, 0x97E6, 0xCEA4,
+	0x97E7, 0xC8CD, 0x97E8, 0xED82, 0x97E9, 0xBAAB, 0x97EA, 0xE8B8,
+	0x97EB, 0xE8B9, 0x97EC, 0xE8BA, 0x97ED, 0xBEC2, 0x97EE, 0xED83,
+	0x97EF, 0xED84, 0x97F0, 0xED85, 0x97F1, 0xED86, 0x97F2, 0xED87,
+	0x97F3, 0xD2F4, 0x97F4, 0xED88, 0x97F5, 0xD4CF, 0x97F6, 0xC9D8,
+	0x97F7, 0xED89, 0x97F8, 0xED8A, 0x97F9, 0xED8B, 0x97FA, 0xED8C,
+	0x97FB, 0xED8D, 0x97FC, 0xED8E, 0x97FD, 0xED8F, 0x97FE, 0xED90,
+	0x97FF, 0xED91, 0x9800, 0xED92, 0x9801, 0xED93, 0x9802, 0xED94,
+	0x9803, 0xED95, 0x9804, 0xED96, 0x9805, 0xED97, 0x9806, 0xED98,
+	0x9807, 0xED99, 0x9808, 0xED9A, 0x9809, 0xED9B, 0x980A, 0xED9C,
+	0x980B, 0xED9D, 0x980C, 0xED9E, 0x980D, 0xED9F, 0x980E, 0xEDA0,
+	0x980F, 0xEE40, 0x9810, 0xEE41, 0x9811, 0xEE42, 0x9812, 0xEE43,
+	0x9813, 0xEE44, 0x9814, 0xEE45, 0x9815, 0xEE46, 0x9816, 0xEE47,
+	0x9817, 0xEE48, 0x9818, 0xEE49, 0x9819, 0xEE4A, 0x981A, 0xEE4B,
+	0x981B, 0xEE4C, 0x981C, 0xEE4D, 0x981D, 0xEE4E, 0x981E, 0xEE4F,
+	0x981F, 0xEE50, 0x9820, 0xEE51, 0x9821, 0xEE52, 0x9822, 0xEE53,
+	0x9823, 0xEE54, 0x9824, 0xEE55, 0x9825, 0xEE56, 0x9826, 0xEE57,
+	0x9827, 0xEE58, 0x9828, 0xEE59, 0x9829, 0xEE5A, 0x982A, 0xEE5B,
+	0x982B, 0xEE5C, 0x982C, 0xEE5D, 0x982D, 0xEE5E, 0x982E, 0xEE5F,
+	0x982F, 0xEE60, 0x9830, 0xEE61, 0x9831, 0xEE62, 0x9832, 0xEE63,
+	0x9833, 0xEE64, 0x9834, 0xEE65, 0x9835, 0xEE66, 0x9836, 0xEE67,
+	0x9837, 0xEE68, 0x9838, 0xEE69, 0x9839, 0xEE6A, 0x983A, 0xEE6B,
+	0x983B, 0xEE6C, 0x983C, 0xEE6D, 0x983D, 0xEE6E, 0x983E, 0xEE6F,
+	0x983F, 0xEE70, 0x9840, 0xEE71, 0x9841, 0xEE72, 0x9842, 0xEE73,
+	0x9843, 0xEE74, 0x9844, 0xEE75, 0x9845, 0xEE76, 0x9846, 0xEE77,
+	0x9847, 0xEE78, 0x9848, 0xEE79, 0x9849, 0xEE7A, 0x984A, 0xEE7B,
+	0x984B, 0xEE7C, 0x984C, 0xEE7D, 0x984D, 0xEE7E, 0x984E, 0xEE80,
+	0x984F, 0xEE81, 0x9850, 0xEE82, 0x9851, 0xEE83, 0x9852, 0xEE84,
+	0x9853, 0xEE85, 0x9854, 0xEE86, 0x9855, 0xEE87, 0x9856, 0xEE88,
+	0x9857, 0xEE89, 0x9858, 0xEE8A, 0x9859, 0xEE8B, 0x985A, 0xEE8C,
+	0x985B, 0xEE8D, 0x985C, 0xEE8E, 0x985D, 0xEE8F, 0x985E, 0xEE90,
+	0x985F, 0xEE91, 0x9860, 0xEE92, 0x9861, 0xEE93, 0x9862, 0xEE94,
+	0x9863, 0xEE95, 0x9864, 0xEE96, 0x9865, 0xEE97, 0x9866, 0xEE98,
+	0x9867, 0xEE99, 0x9868, 0xEE9A, 0x9869, 0xEE9B, 0x986A, 0xEE9C,
+	0x986B, 0xEE9D, 0x986C, 0xEE9E, 0x986D, 0xEE9F, 0x986E, 0xEEA0,
+	0x986F, 0xEF40, 0x9870, 0xEF41, 0x9871, 0xEF42, 0x9872, 0xEF43,
+	0x9873, 0xEF44, 0x9874, 0xEF45, 0x9875, 0xD2B3, 0x9876, 0xB6A5,
+	0x9877, 0xC7EA, 0x9878, 0xF1FC, 0x9879, 0xCFEE, 0x987A, 0xCBB3,
+	0x987B, 0xD0EB, 0x987C, 0xE7EF, 0x987D, 0xCDE7, 0x987E, 0xB9CB,
+	0x987F, 0xB6D9, 0x9880, 0xF1FD, 0x9881, 0xB0E4, 0x9882, 0xCBCC,
+	0x9883, 0xF1FE, 0x9884, 0xD4A4, 0x9885, 0xC2AD, 0x9886, 0xC1EC,
+	0x9887, 0xC6C4, 0x9888, 0xBEB1, 0x9889, 0xF2A1, 0x988A, 0xBCD5,
+	0x988B, 0xEF46, 0x988C, 0xF2A2, 0x988D, 0xF2A3, 0x988E, 0xEF47,
+	0x988F, 0xF2A4, 0x9890, 0xD2C3, 0x9891, 0xC6B5, 0x9892, 0xEF48,
+	0x9893, 0xCDC7, 0x9894, 0xF2A5, 0x9895, 0xEF49, 0x9896, 0xD3B1,
+	0x9897, 0xBFC5, 0x9898, 0xCCE2, 0x9899, 0xEF4A, 0x989A, 0xF2A6,
+	0x989B, 0xF2A7, 0x989C, 0xD1D5, 0x989D, 0xB6EE, 0x989E, 0xF2A8,
+	0x989F, 0xF2A9, 0x98A0, 0xB5DF, 0x98A1, 0xF2AA, 0x98A2, 0xF2AB,
+	0x98A3, 0xEF4B, 0x98A4, 0xB2FC, 0x98A5, 0xF2AC, 0x98A6, 0xF2AD,
+	0x98A7, 0xC8A7, 0x98A8, 0xEF4C, 0x98A9, 0xEF4D, 0x98AA, 0xEF4E,
+	0x98AB, 0xEF4F, 0x98AC, 0xEF50, 0x98AD, 0xEF51, 0x98AE, 0xEF52,
+	0x98AF, 0xEF53, 0x98B0, 0xEF54, 0x98B1, 0xEF55, 0x98B2, 0xEF56,
+	0x98B3, 0xEF57, 0x98B4, 0xEF58, 0x98B5, 0xEF59, 0x98B6, 0xEF5A,
+	0x98B7, 0xEF5B, 0x98B8, 0xEF5C, 0x98B9, 0xEF5D, 0x98BA, 0xEF5E,
+	0x98BB, 0xEF5F, 0x98BC, 0xEF60, 0x98BD, 0xEF61, 0x98BE, 0xEF62,
+	0x98BF, 0xEF63, 0x98C0, 0xEF64, 0x98C1, 0xEF65, 0x98C2, 0xEF66,
+	0x98C3, 0xEF67, 0x98C4, 0xEF68, 0x98C5, 0xEF69, 0x98C6, 0xEF6A,
+	0x98C7, 0xEF6B, 0x98C8, 0xEF6C, 0x98C9, 0xEF6D, 0x98CA, 0xEF6E,
+	0x98CB, 0xEF6F, 0x98CC, 0xEF70, 0x98CD, 0xEF71, 0x98CE, 0xB7E7,
+	0x98CF, 0xEF72, 0x98D0, 0xEF73, 0x98D1, 0xECA9, 0x98D2, 0xECAA,
+	0x98D3, 0xECAB, 0x98D4, 0xEF74, 0x98D5, 0xECAC, 0x98D6, 0xEF75,
+	0x98D7, 0xEF76, 0x98D8, 0xC6AE, 0x98D9, 0xECAD, 0x98DA, 0xECAE,
+	0x98DB, 0xEF77, 0x98DC, 0xEF78, 0x98DD, 0xEF79, 0x98DE, 0xB7C9,
+	0x98DF, 0xCAB3, 0x98E0, 0xEF7A, 0x98E1, 0xEF7B, 0x98E2, 0xEF7C,
+	0x98E3, 0xEF7D, 0x98E4, 0xEF7E, 0x98E5, 0xEF80, 0x98E6, 0xEF81,
+	0x98E7, 0xE2B8, 0x98E8, 0xF7CF, 0x98E9, 0xEF82, 0x98EA, 0xEF83,
+	0x98EB, 0xEF84, 0x98EC, 0xEF85, 0x98ED, 0xEF86, 0x98EE, 0xEF87,
+	0x98EF, 0xEF88, 0x98F0, 0xEF89, 0x98F1, 0xEF8A, 0x98F2, 0xEF8B,
+	0x98F3, 0xEF8C, 0x98F4, 0xEF8D, 0x98F5, 0xEF8E, 0x98F6, 0xEF8F,
+	0x98F7, 0xEF90, 0x98F8, 0xEF91, 0x98F9, 0xEF92, 0x98FA, 0xEF93,
+	0x98FB, 0xEF94, 0x98FC, 0xEF95, 0x98FD, 0xEF96, 0x98FE, 0xEF97,
+	0x98FF, 0xEF98, 0x9900, 0xEF99, 0x9901, 0xEF9A, 0x9902, 0xEF9B,
+	0x9903, 0xEF9C, 0x9904, 0xEF9D, 0x9905, 0xEF9E, 0x9906, 0xEF9F,
+	0x9907, 0xEFA0, 0x9908, 0xF040, 0x9909, 0xF041, 0x990A, 0xF042,
+	0x990B, 0xF043, 0x990C, 0xF044, 0x990D, 0xF7D0, 0x990E, 0xF045,
+	0x990F, 0xF046, 0x9910, 0xB2CD, 0x9911, 0xF047, 0x9912, 0xF048,
+	0x9913, 0xF049, 0x9914, 0xF04A, 0x9915, 0xF04B, 0x9916, 0xF04C,
+	0x9917, 0xF04D, 0x9918, 0xF04E, 0x9919, 0xF04F, 0x991A, 0xF050,
+	0x991B, 0xF051, 0x991C, 0xF052, 0x991D, 0xF053, 0x991E, 0xF054,
+	0x991F, 0xF055, 0x9920, 0xF056, 0x9921, 0xF057, 0x9922, 0xF058,
+	0x9923, 0xF059, 0x9924, 0xF05A, 0x9925, 0xF05B, 0x9926, 0xF05C,
+	0x9927, 0xF05D, 0x9928, 0xF05E, 0x9929, 0xF05F, 0x992A, 0xF060,
+	0x992B, 0xF061, 0x992C, 0xF062, 0x992D, 0xF063, 0x992E, 0xF7D1,
+	0x992F, 0xF064, 0x9930, 0xF065, 0x9931, 0xF066, 0x9932, 0xF067,
+	0x9933, 0xF068, 0x9934, 0xF069, 0x9935, 0xF06A, 0x9936, 0xF06B,
+	0x9937, 0xF06C, 0x9938, 0xF06D, 0x9939, 0xF06E, 0x993A, 0xF06F,
+	0x993B, 0xF070, 0x993C, 0xF071, 0x993D, 0xF072, 0x993E, 0xF073,
+	0x993F, 0xF074, 0x9940, 0xF075, 0x9941, 0xF076, 0x9942, 0xF077,
+	0x9943, 0xF078, 0x9944, 0xF079, 0x9945, 0xF07A, 0x9946, 0xF07B,
+	0x9947, 0xF07C, 0x9948, 0xF07D, 0x9949, 0xF07E, 0x994A, 0xF080,
+	0x994B, 0xF081, 0x994C, 0xF082, 0x994D, 0xF083, 0x994E, 0xF084,
+	0x994F, 0xF085, 0x9950, 0xF086, 0x9951, 0xF087, 0x9952, 0xF088,
+	0x9953, 0xF089, 0x9954, 0xF7D3, 0x9955, 0xF7D2, 0x9956, 0xF08A,
+	0x9957, 0xF08B, 0x9958, 0xF08C, 0x9959, 0xF08D, 0x995A, 0xF08E,
+	0x995B, 0xF08F, 0x995C, 0xF090, 0x995D, 0xF091, 0x995E, 0xF092,
+	0x995F, 0xF093, 0x9960, 0xF094, 0x9961, 0xF095, 0x9962, 0xF096,
+	0x9963, 0xE2BB, 0x9964, 0xF097, 0x9965, 0xBCA2, 0x9966, 0xF098,
+	0x9967, 0xE2BC, 0x9968, 0xE2BD, 0x9969, 0xE2BE, 0x996A, 0xE2BF,
+	0x996B, 0xE2C0, 0x996C, 0xE2C1, 0x996D, 0xB7B9, 0x996E, 0xD2FB,
+	0x996F, 0xBDA4, 0x9970, 0xCACE, 0x9971, 0xB1A5, 0x9972, 0xCBC7,
+	0x9973, 0xF099, 0x9974, 0xE2C2, 0x9975, 0xB6FC, 0x9976, 0xC8C4,
+	0x9977, 0xE2C3, 0x9978, 0xF09A, 0x9979, 0xF09B, 0x997A, 0xBDC8,
+	0x997B, 0xF09C, 0x997C, 0xB1FD, 0x997D, 0xE2C4, 0x997E, 0xF09D,
+	0x997F, 0xB6F6, 0x9980, 0xE2C5, 0x9981, 0xC4D9, 0x9982, 0xF09E,
+	0x9983, 0xF09F, 0x9984, 0xE2C6, 0x9985, 0xCFDA, 0x9986, 0xB9DD,
+	0x9987, 0xE2C7, 0x9988, 0xC0A1, 0x9989, 0xF0A0, 0x998A, 0xE2C8,
+	0x998B, 0xB2F6, 0x998C, 0xF140, 0x998D, 0xE2C9, 0x998E, 0xF141,
+	0x998F, 0xC1F3, 0x9990, 0xE2CA, 0x9991, 0xE2CB, 0x9992, 0xC2F8,
+	0x9993, 0xE2CC, 0x9994, 0xE2CD, 0x9995, 0xE2CE, 0x9996, 0xCAD7,
+	0x9997, 0xD8B8, 0x9998, 0xD9E5, 0x9999, 0xCFE3, 0x999A, 0xF142,
+	0x999B, 0xF143, 0x999C, 0xF144, 0x999D, 0xF145, 0x999E, 0xF146,
+	0x999F, 0xF147, 0x99A0, 0xF148, 0x99A1, 0xF149, 0x99A2, 0xF14A,
+	0x99A3, 0xF14B, 0x99A4, 0xF14C, 0x99A5, 0xF0A5, 0x99A6, 0xF14D,
+	0x99A7, 0xF14E, 0x99A8, 0xDCB0, 0x99A9, 0xF14F, 0x99AA, 0xF150,
+	0x99AB, 0xF151, 0x99AC, 0xF152, 0x99AD, 0xF153, 0x99AE, 0xF154,
+	0x99AF, 0xF155, 0x99B0, 0xF156, 0x99B1, 0xF157, 0x99B2, 0xF158,
+	0x99B3, 0xF159, 0x99B4, 0xF15A, 0x99B5, 0xF15B, 0x99B6, 0xF15C,
+	0x99B7, 0xF15D, 0x99B8, 0xF15E, 0x99B9, 0xF15F, 0x99BA, 0xF160,
+	0x99BB, 0xF161, 0x99BC, 0xF162, 0x99BD, 0xF163, 0x99BE, 0xF164,
+	0x99BF, 0xF165, 0x99C0, 0xF166, 0x99C1, 0xF167, 0x99C2, 0xF168,
+	0x99C3, 0xF169, 0x99C4, 0xF16A, 0x99C5, 0xF16B, 0x99C6, 0xF16C,
+	0x99C7, 0xF16D, 0x99C8, 0xF16E, 0x99C9, 0xF16F, 0x99CA, 0xF170,
+	0x99CB, 0xF171, 0x99CC, 0xF172, 0x99CD, 0xF173, 0x99CE, 0xF174,
+	0x99CF, 0xF175, 0x99D0, 0xF176, 0x99D1, 0xF177, 0x99D2, 0xF178,
+	0x99D3, 0xF179, 0x99D4, 0xF17A, 0x99D5, 0xF17B, 0x99D6, 0xF17C,
+	0x99D7, 0xF17D, 0x99D8, 0xF17E, 0x99D9, 0xF180, 0x99DA, 0xF181,
+	0x99DB, 0xF182, 0x99DC, 0xF183, 0x99DD, 0xF184, 0x99DE, 0xF185,
+	0x99DF, 0xF186, 0x99E0, 0xF187, 0x99E1, 0xF188, 0x99E2, 0xF189,
+	0x99E3, 0xF18A, 0x99E4, 0xF18B, 0x99E5, 0xF18C, 0x99E6, 0xF18D,
+	0x99E7, 0xF18E, 0x99E8, 0xF18F, 0x99E9, 0xF190, 0x99EA, 0xF191,
+	0x99EB, 0xF192, 0x99EC, 0xF193, 0x99ED, 0xF194, 0x99EE, 0xF195,
+	0x99EF, 0xF196, 0x99F0, 0xF197, 0x99F1, 0xF198, 0x99F2, 0xF199,
+	0x99F3, 0xF19A, 0x99F4, 0xF19B, 0x99F5, 0xF19C, 0x99F6, 0xF19D,
+	0x99F7, 0xF19E, 0x99F8, 0xF19F, 0x99F9, 0xF1A0, 0x99FA, 0xF240,
+	0x99FB, 0xF241, 0x99FC, 0xF242, 0x99FD, 0xF243, 0x99FE, 0xF244,
+	0x99FF, 0xF245, 0x9A00, 0xF246, 0x9A01, 0xF247, 0x9A02, 0xF248,
+	0x9A03, 0xF249, 0x9A04, 0xF24A, 0x9A05, 0xF24B, 0x9A06, 0xF24C,
+	0x9A07, 0xF24D, 0x9A08, 0xF24E, 0x9A09, 0xF24F, 0x9A0A, 0xF250,
+	0x9A0B, 0xF251, 0x9A0C, 0xF252, 0x9A0D, 0xF253, 0x9A0E, 0xF254,
+	0x9A0F, 0xF255, 0x9A10, 0xF256, 0x9A11, 0xF257, 0x9A12, 0xF258,
+	0x9A13, 0xF259, 0x9A14, 0xF25A, 0x9A15, 0xF25B, 0x9A16, 0xF25C,
+	0x9A17, 0xF25D, 0x9A18, 0xF25E, 0x9A19, 0xF25F, 0x9A1A, 0xF260,
+	0x9A1B, 0xF261, 0x9A1C, 0xF262, 0x9A1D, 0xF263, 0x9A1E, 0xF264,
+	0x9A1F, 0xF265, 0x9A20, 0xF266, 0x9A21, 0xF267, 0x9A22, 0xF268,
+	0x9A23, 0xF269, 0x9A24, 0xF26A, 0x9A25, 0xF26B, 0x9A26, 0xF26C,
+	0x9A27, 0xF26D, 0x9A28, 0xF26E, 0x9A29, 0xF26F, 0x9A2A, 0xF270,
+	0x9A2B, 0xF271, 0x9A2C, 0xF272, 0x9A2D, 0xF273, 0x9A2E, 0xF274,
+	0x9A2F, 0xF275, 0x9A30, 0xF276, 0x9A31, 0xF277, 0x9A32, 0xF278,
+	0x9A33, 0xF279, 0x9A34, 0xF27A, 0x9A35, 0xF27B, 0x9A36, 0xF27C,
+	0x9A37, 0xF27D, 0x9A38, 0xF27E, 0x9A39, 0xF280, 0x9A3A, 0xF281,
+	0x9A3B, 0xF282, 0x9A3C, 0xF283, 0x9A3D, 0xF284, 0x9A3E, 0xF285,
+	0x9A3F, 0xF286, 0x9A40, 0xF287, 0x9A41, 0xF288, 0x9A42, 0xF289,
+	0x9A43, 0xF28A, 0x9A44, 0xF28B, 0x9A45, 0xF28C, 0x9A46, 0xF28D,
+	0x9A47, 0xF28E, 0x9A48, 0xF28F, 0x9A49, 0xF290, 0x9A4A, 0xF291,
+	0x9A4B, 0xF292, 0x9A4C, 0xF293, 0x9A4D, 0xF294, 0x9A4E, 0xF295,
+	0x9A4F, 0xF296, 0x9A50, 0xF297, 0x9A51, 0xF298, 0x9A52, 0xF299,
+	0x9A53, 0xF29A, 0x9A54, 0xF29B, 0x9A55, 0xF29C, 0x9A56, 0xF29D,
+	0x9A57, 0xF29E, 0x9A58, 0xF29F, 0x9A59, 0xF2A0, 0x9A5A, 0xF340,
+	0x9A5B, 0xF341, 0x9A5C, 0xF342, 0x9A5D, 0xF343, 0x9A5E, 0xF344,
+	0x9A5F, 0xF345, 0x9A60, 0xF346, 0x9A61, 0xF347, 0x9A62, 0xF348,
+	0x9A63, 0xF349, 0x9A64, 0xF34A, 0x9A65, 0xF34B, 0x9A66, 0xF34C,
+	0x9A67, 0xF34D, 0x9A68, 0xF34E, 0x9A69, 0xF34F, 0x9A6A, 0xF350,
+	0x9A6B, 0xF351, 0x9A6C, 0xC2ED, 0x9A6D, 0xD4A6, 0x9A6E, 0xCDD4,
+	0x9A6F, 0xD1B1, 0x9A70, 0xB3DB, 0x9A71, 0xC7FD, 0x9A72, 0xF352,
+	0x9A73, 0xB2B5, 0x9A74, 0xC2BF, 0x9A75, 0xE6E0, 0x9A76, 0xCABB,
+	0x9A77, 0xE6E1, 0x9A78, 0xE6E2, 0x9A79, 0xBED4, 0x9A7A, 0xE6E3,
+	0x9A7B, 0xD7A4, 0x9A7C, 0xCDD5, 0x9A7D, 0xE6E5, 0x9A7E, 0xBCDD,
+	0x9A7F, 0xE6E4, 0x9A80, 0xE6E6, 0x9A81, 0xE6E7, 0x9A82, 0xC2EE,
+	0x9A83, 0xF353, 0x9A84, 0xBDBE, 0x9A85, 0xE6E8, 0x9A86, 0xC2E6,
+	0x9A87, 0xBAA7, 0x9A88, 0xE6E9, 0x9A89, 0xF354, 0x9A8A, 0xE6EA,
+	0x9A8B, 0xB3D2, 0x9A8C, 0xD1E9, 0x9A8D, 0xF355, 0x9A8E, 0xF356,
+	0x9A8F, 0xBFA5, 0x9A90, 0xE6EB, 0x9A91, 0xC6EF, 0x9A92, 0xE6EC,
+	0x9A93, 0xE6ED, 0x9A94, 0xF357, 0x9A95, 0xF358, 0x9A96, 0xE6EE,
+	0x9A97, 0xC6AD, 0x9A98, 0xE6EF, 0x9A99, 0xF359, 0x9A9A, 0xC9A7,
+	0x9A9B, 0xE6F0, 0x9A9C, 0xE6F1, 0x9A9D, 0xE6F2, 0x9A9E, 0xE5B9,
+	0x9A9F, 0xE6F3, 0x9AA0, 0xE6F4, 0x9AA1, 0xC2E2, 0x9AA2, 0xE6F5,
+	0x9AA3, 0xE6F6, 0x9AA4, 0xD6E8, 0x9AA5, 0xE6F7, 0x9AA6, 0xF35A,
+	0x9AA7, 0xE6F8, 0x9AA8, 0xB9C7, 0x9AA9, 0xF35B, 0x9AAA, 0xF35C,
+	0x9AAB, 0xF35D, 0x9AAC, 0xF35E, 0x9AAD, 0xF35F, 0x9AAE, 0xF360,
+	0x9AAF, 0xF361, 0x9AB0, 0xF7BB, 0x9AB1, 0xF7BA, 0x9AB2, 0xF362,
+	0x9AB3, 0xF363, 0x9AB4, 0xF364, 0x9AB5, 0xF365, 0x9AB6, 0xF7BE,
+	0x9AB7, 0xF7BC, 0x9AB8, 0xBAA1, 0x9AB9, 0xF366, 0x9ABA, 0xF7BF,
+	0x9ABB, 0xF367, 0x9ABC, 0xF7C0, 0x9ABD, 0xF368, 0x9ABE, 0xF369,
+	0x9ABF, 0xF36A, 0x9AC0, 0xF7C2, 0x9AC1, 0xF7C1, 0x9AC2, 0xF7C4,
+	0x9AC3, 0xF36B, 0x9AC4, 0xF36C, 0x9AC5, 0xF7C3, 0x9AC6, 0xF36D,
+	0x9AC7, 0xF36E, 0x9AC8, 0xF36F, 0x9AC9, 0xF370, 0x9ACA, 0xF371,
+	0x9ACB, 0xF7C5, 0x9ACC, 0xF7C6, 0x9ACD, 0xF372, 0x9ACE, 0xF373,
+	0x9ACF, 0xF374, 0x9AD0, 0xF375, 0x9AD1, 0xF7C7, 0x9AD2, 0xF376,
+	0x9AD3, 0xCBE8, 0x9AD4, 0xF377, 0x9AD5, 0xF378, 0x9AD6, 0xF379,
+	0x9AD7, 0xF37A, 0x9AD8, 0xB8DF, 0x9AD9, 0xF37B, 0x9ADA, 0xF37C,
+	0x9ADB, 0xF37D, 0x9ADC, 0xF37E, 0x9ADD, 0xF380, 0x9ADE, 0xF381,
+	0x9ADF, 0xF7D4, 0x9AE0, 0xF382, 0x9AE1, 0xF7D5, 0x9AE2, 0xF383,
+	0x9AE3, 0xF384, 0x9AE4, 0xF385, 0x9AE5, 0xF386, 0x9AE6, 0xF7D6,
+	0x9AE7, 0xF387, 0x9AE8, 0xF388, 0x9AE9, 0xF389, 0x9AEA, 0xF38A,
+	0x9AEB, 0xF7D8, 0x9AEC, 0xF38B, 0x9AED, 0xF7DA, 0x9AEE, 0xF38C,
+	0x9AEF, 0xF7D7, 0x9AF0, 0xF38D, 0x9AF1, 0xF38E, 0x9AF2, 0xF38F,
+	0x9AF3, 0xF390, 0x9AF4, 0xF391, 0x9AF5, 0xF392, 0x9AF6, 0xF393,
+	0x9AF7, 0xF394, 0x9AF8, 0xF395, 0x9AF9, 0xF7DB, 0x9AFA, 0xF396,
+	0x9AFB, 0xF7D9, 0x9AFC, 0xF397, 0x9AFD, 0xF398, 0x9AFE, 0xF399,
+	0x9AFF, 0xF39A, 0x9B00, 0xF39B, 0x9B01, 0xF39C, 0x9B02, 0xF39D,
+	0x9B03, 0xD7D7, 0x9B04, 0xF39E, 0x9B05, 0xF39F, 0x9B06, 0xF3A0,
+	0x9B07, 0xF440, 0x9B08, 0xF7DC, 0x9B09, 0xF441, 0x9B0A, 0xF442,
+	0x9B0B, 0xF443, 0x9B0C, 0xF444, 0x9B0D, 0xF445, 0x9B0E, 0xF446,
+	0x9B0F, 0xF7DD, 0x9B10, 0xF447, 0x9B11, 0xF448, 0x9B12, 0xF449,
+	0x9B13, 0xF7DE, 0x9B14, 0xF44A, 0x9B15, 0xF44B, 0x9B16, 0xF44C,
+	0x9B17, 0xF44D, 0x9B18, 0xF44E, 0x9B19, 0xF44F, 0x9B1A, 0xF450,
+	0x9B1B, 0xF451, 0x9B1C, 0xF452, 0x9B1D, 0xF453, 0x9B1E, 0xF454,
+	0x9B1F, 0xF7DF, 0x9B20, 0xF455, 0x9B21, 0xF456, 0x9B22, 0xF457,
+	0x9B23, 0xF7E0, 0x9B24, 0xF458, 0x9B25, 0xF459, 0x9B26, 0xF45A,
+	0x9B27, 0xF45B, 0x9B28, 0xF45C, 0x9B29, 0xF45D, 0x9B2A, 0xF45E,
+	0x9B2B, 0xF45F, 0x9B2C, 0xF460, 0x9B2D, 0xF461, 0x9B2E, 0xF462,
+	0x9B2F, 0xDBCB, 0x9B30, 0xF463, 0x9B31, 0xF464, 0x9B32, 0xD8AA,
+	0x9B33, 0xF465, 0x9B34, 0xF466, 0x9B35, 0xF467, 0x9B36, 0xF468,
+	0x9B37, 0xF469, 0x9B38, 0xF46A, 0x9B39, 0xF46B, 0x9B3A, 0xF46C,
+	0x9B3B, 0xE5F7, 0x9B3C, 0xB9ED, 0x9B3D, 0xF46D, 0x9B3E, 0xF46E,
+	0x9B3F, 0xF46F, 0x9B40, 0xF470, 0x9B41, 0xBFFD, 0x9B42, 0xBBEA,
+	0x9B43, 0xF7C9, 0x9B44, 0xC6C7, 0x9B45, 0xF7C8, 0x9B46, 0xF471,
+	0x9B47, 0xF7CA, 0x9B48, 0xF7CC, 0x9B49, 0xF7CB, 0x9B4A, 0xF472,
+	0x9B4B, 0xF473, 0x9B4C, 0xF474, 0x9B4D, 0xF7CD, 0x9B4E, 0xF475,
+	0x9B4F, 0xCEBA, 0x9B50, 0xF476, 0x9B51, 0xF7CE, 0x9B52, 0xF477,
+	0x9B53, 0xF478, 0x9B54, 0xC4A7, 0x9B55, 0xF479, 0x9B56, 0xF47A,
+	0x9B57, 0xF47B, 0x9B58, 0xF47C, 0x9B59, 0xF47D, 0x9B5A, 0xF47E,
+	0x9B5B, 0xF480, 0x9B5C, 0xF481, 0x9B5D, 0xF482, 0x9B5E, 0xF483,
+	0x9B5F, 0xF484, 0x9B60, 0xF485, 0x9B61, 0xF486, 0x9B62, 0xF487,
+	0x9B63, 0xF488, 0x9B64, 0xF489, 0x9B65, 0xF48A, 0x9B66, 0xF48B,
+	0x9B67, 0xF48C, 0x9B68, 0xF48D, 0x9B69, 0xF48E, 0x9B6A, 0xF48F,
+	0x9B6B, 0xF490, 0x9B6C, 0xF491, 0x9B6D, 0xF492, 0x9B6E, 0xF493,
+	0x9B6F, 0xF494, 0x9B70, 0xF495, 0x9B71, 0xF496, 0x9B72, 0xF497,
+	0x9B73, 0xF498, 0x9B74, 0xF499, 0x9B75, 0xF49A, 0x9B76, 0xF49B,
+	0x9B77, 0xF49C, 0x9B78, 0xF49D, 0x9B79, 0xF49E, 0x9B7A, 0xF49F,
+	0x9B7B, 0xF4A0, 0x9B7C, 0xF540, 0x9B7D, 0xF541, 0x9B7E, 0xF542,
+	0x9B7F, 0xF543, 0x9B80, 0xF544, 0x9B81, 0xF545, 0x9B82, 0xF546,
+	0x9B83, 0xF547, 0x9B84, 0xF548, 0x9B85, 0xF549, 0x9B86, 0xF54A,
+	0x9B87, 0xF54B, 0x9B88, 0xF54C, 0x9B89, 0xF54D, 0x9B8A, 0xF54E,
+	0x9B8B, 0xF54F, 0x9B8C, 0xF550, 0x9B8D, 0xF551, 0x9B8E, 0xF552,
+	0x9B8F, 0xF553, 0x9B90, 0xF554, 0x9B91, 0xF555, 0x9B92, 0xF556,
+	0x9B93, 0xF557, 0x9B94, 0xF558, 0x9B95, 0xF559, 0x9B96, 0xF55A,
+	0x9B97, 0xF55B, 0x9B98, 0xF55C, 0x9B99, 0xF55D, 0x9B9A, 0xF55E,
+	0x9B9B, 0xF55F, 0x9B9C, 0xF560, 0x9B9D, 0xF561, 0x9B9E, 0xF562,
+	0x9B9F, 0xF563, 0x9BA0, 0xF564, 0x9BA1, 0xF565, 0x9BA2, 0xF566,
+	0x9BA3, 0xF567, 0x9BA4, 0xF568, 0x9BA5, 0xF569, 0x9BA6, 0xF56A,
+	0x9BA7, 0xF56B, 0x9BA8, 0xF56C, 0x9BA9, 0xF56D, 0x9BAA, 0xF56E,
+	0x9BAB, 0xF56F, 0x9BAC, 0xF570, 0x9BAD, 0xF571, 0x9BAE, 0xF572,
+	0x9BAF, 0xF573, 0x9BB0, 0xF574, 0x9BB1, 0xF575, 0x9BB2, 0xF576,
+	0x9BB3, 0xF577, 0x9BB4, 0xF578, 0x9BB5, 0xF579, 0x9BB6, 0xF57A,
+	0x9BB7, 0xF57B, 0x9BB8, 0xF57C, 0x9BB9, 0xF57D, 0x9BBA, 0xF57E,
+	0x9BBB, 0xF580, 0x9BBC, 0xF581, 0x9BBD, 0xF582, 0x9BBE, 0xF583,
+	0x9BBF, 0xF584, 0x9BC0, 0xF585, 0x9BC1, 0xF586, 0x9BC2, 0xF587,
+	0x9BC3, 0xF588, 0x9BC4, 0xF589, 0x9BC5, 0xF58A, 0x9BC6, 0xF58B,
+	0x9BC7, 0xF58C, 0x9BC8, 0xF58D, 0x9BC9, 0xF58E, 0x9BCA, 0xF58F,
+	0x9BCB, 0xF590, 0x9BCC, 0xF591, 0x9BCD, 0xF592, 0x9BCE, 0xF593,
+	0x9BCF, 0xF594, 0x9BD0, 0xF595, 0x9BD1, 0xF596, 0x9BD2, 0xF597,
+	0x9BD3, 0xF598, 0x9BD4, 0xF599, 0x9BD5, 0xF59A, 0x9BD6, 0xF59B,
+	0x9BD7, 0xF59C, 0x9BD8, 0xF59D, 0x9BD9, 0xF59E, 0x9BDA, 0xF59F,
+	0x9BDB, 0xF5A0, 0x9BDC, 0xF640, 0x9BDD, 0xF641, 0x9BDE, 0xF642,
+	0x9BDF, 0xF643, 0x9BE0, 0xF644, 0x9BE1, 0xF645, 0x9BE2, 0xF646,
+	0x9BE3, 0xF647, 0x9BE4, 0xF648, 0x9BE5, 0xF649, 0x9BE6, 0xF64A,
+	0x9BE7, 0xF64B, 0x9BE8, 0xF64C, 0x9BE9, 0xF64D, 0x9BEA, 0xF64E,
+	0x9BEB, 0xF64F, 0x9BEC, 0xF650, 0x9BED, 0xF651, 0x9BEE, 0xF652,
+	0x9BEF, 0xF653, 0x9BF0, 0xF654, 0x9BF1, 0xF655, 0x9BF2, 0xF656,
+	0x9BF3, 0xF657, 0x9BF4, 0xF658, 0x9BF5, 0xF659, 0x9BF6, 0xF65A,
+	0x9BF7, 0xF65B, 0x9BF8, 0xF65C, 0x9BF9, 0xF65D, 0x9BFA, 0xF65E,
+	0x9BFB, 0xF65F, 0x9BFC, 0xF660, 0x9BFD, 0xF661, 0x9BFE, 0xF662,
+	0x9BFF, 0xF663, 0x9C00, 0xF664, 0x9C01, 0xF665, 0x9C02, 0xF666,
+	0x9C03, 0xF667, 0x9C04, 0xF668, 0x9C05, 0xF669, 0x9C06, 0xF66A,
+	0x9C07, 0xF66B, 0x9C08, 0xF66C, 0x9C09, 0xF66D, 0x9C0A, 0xF66E,
+	0x9C0B, 0xF66F, 0x9C0C, 0xF670, 0x9C0D, 0xF671, 0x9C0E, 0xF672,
+	0x9C0F, 0xF673, 0x9C10, 0xF674, 0x9C11, 0xF675, 0x9C12, 0xF676,
+	0x9C13, 0xF677, 0x9C14, 0xF678, 0x9C15, 0xF679, 0x9C16, 0xF67A,
+	0x9C17, 0xF67B, 0x9C18, 0xF67C, 0x9C19, 0xF67D, 0x9C1A, 0xF67E,
+	0x9C1B, 0xF680, 0x9C1C, 0xF681, 0x9C1D, 0xF682, 0x9C1E, 0xF683,
+	0x9C1F, 0xF684, 0x9C20, 0xF685, 0x9C21, 0xF686, 0x9C22, 0xF687,
+	0x9C23, 0xF688, 0x9C24, 0xF689, 0x9C25, 0xF68A, 0x9C26, 0xF68B,
+	0x9C27, 0xF68C, 0x9C28, 0xF68D, 0x9C29, 0xF68E, 0x9C2A, 0xF68F,
+	0x9C2B, 0xF690, 0x9C2C, 0xF691, 0x9C2D, 0xF692, 0x9C2E, 0xF693,
+	0x9C2F, 0xF694, 0x9C30, 0xF695, 0x9C31, 0xF696, 0x9C32, 0xF697,
+	0x9C33, 0xF698, 0x9C34, 0xF699, 0x9C35, 0xF69A, 0x9C36, 0xF69B,
+	0x9C37, 0xF69C, 0x9C38, 0xF69D, 0x9C39, 0xF69E, 0x9C3A, 0xF69F,
+	0x9C3B, 0xF6A0, 0x9C3C, 0xF740, 0x9C3D, 0xF741, 0x9C3E, 0xF742,
+	0x9C3F, 0xF743, 0x9C40, 0xF744, 0x9C41, 0xF745, 0x9C42, 0xF746,
+	0x9C43, 0xF747, 0x9C44, 0xF748, 0x9C45, 0xF749, 0x9C46, 0xF74A,
+	0x9C47, 0xF74B, 0x9C48, 0xF74C, 0x9C49, 0xF74D, 0x9C4A, 0xF74E,
+	0x9C4B, 0xF74F, 0x9C4C, 0xF750, 0x9C4D, 0xF751, 0x9C4E, 0xF752,
+	0x9C4F, 0xF753, 0x9C50, 0xF754, 0x9C51, 0xF755, 0x9C52, 0xF756,
+	0x9C53, 0xF757, 0x9C54, 0xF758, 0x9C55, 0xF759, 0x9C56, 0xF75A,
+	0x9C57, 0xF75B, 0x9C58, 0xF75C, 0x9C59, 0xF75D, 0x9C5A, 0xF75E,
+	0x9C5B, 0xF75F, 0x9C5C, 0xF760, 0x9C5D, 0xF761, 0x9C5E, 0xF762,
+	0x9C5F, 0xF763, 0x9C60, 0xF764, 0x9C61, 0xF765, 0x9C62, 0xF766,
+	0x9C63, 0xF767, 0x9C64, 0xF768, 0x9C65, 0xF769, 0x9C66, 0xF76A,
+	0x9C67, 0xF76B, 0x9C68, 0xF76C, 0x9C69, 0xF76D, 0x9C6A, 0xF76E,
+	0x9C6B, 0xF76F, 0x9C6C, 0xF770, 0x9C6D, 0xF771, 0x9C6E, 0xF772,
+	0x9C6F, 0xF773, 0x9C70, 0xF774, 0x9C71, 0xF775, 0x9C72, 0xF776,
+	0x9C73, 0xF777, 0x9C74, 0xF778, 0x9C75, 0xF779, 0x9C76, 0xF77A,
+	0x9C77, 0xF77B, 0x9C78, 0xF77C, 0x9C79, 0xF77D, 0x9C7A, 0xF77E,
+	0x9C7B, 0xF780, 0x9C7C, 0xD3E3, 0x9C7D, 0xF781, 0x9C7E, 0xF782,
+	0x9C7F, 0xF6CF, 0x9C80, 0xF783, 0x9C81, 0xC2B3, 0x9C82, 0xF6D0,
+	0x9C83, 0xF784, 0x9C84, 0xF785, 0x9C85, 0xF6D1, 0x9C86, 0xF6D2,
+	0x9C87, 0xF6D3, 0x9C88, 0xF6D4, 0x9C89, 0xF786, 0x9C8A, 0xF787,
+	0x9C8B, 0xF6D6, 0x9C8C, 0xF788, 0x9C8D, 0xB1AB, 0x9C8E, 0xF6D7,
+	0x9C8F, 0xF789, 0x9C90, 0xF6D8, 0x9C91, 0xF6D9, 0x9C92, 0xF6DA,
+	0x9C93, 0xF78A, 0x9C94, 0xF6DB, 0x9C95, 0xF6DC, 0x9C96, 0xF78B,
+	0x9C97, 0xF78C, 0x9C98, 0xF78D, 0x9C99, 0xF78E, 0x9C9A, 0xF6DD,
+	0x9C9B, 0xF6DE, 0x9C9C, 0xCFCA, 0x9C9D, 0xF78F, 0x9C9E, 0xF6DF,
+	0x9C9F, 0xF6E0, 0x9CA0, 0xF6E1, 0x9CA1, 0xF6E2, 0x9CA2, 0xF6E3,
+	0x9CA3, 0xF6E4, 0x9CA4, 0xC0F0, 0x9CA5, 0xF6E5, 0x9CA6, 0xF6E6,
+	0x9CA7, 0xF6E7, 0x9CA8, 0xF6E8, 0x9CA9, 0xF6E9, 0x9CAA, 0xF790,
+	0x9CAB, 0xF6EA, 0x9CAC, 0xF791, 0x9CAD, 0xF6EB, 0x9CAE, 0xF6EC,
+	0x9CAF, 0xF792, 0x9CB0, 0xF6ED, 0x9CB1, 0xF6EE, 0x9CB2, 0xF6EF,
+	0x9CB3, 0xF6F0, 0x9CB4, 0xF6F1, 0x9CB5, 0xF6F2, 0x9CB6, 0xF6F3,
+	0x9CB7, 0xF6F4, 0x9CB8, 0xBEA8, 0x9CB9, 0xF793, 0x9CBA, 0xF6F5,
+	0x9CBB, 0xF6F6, 0x9CBC, 0xF6F7, 0x9CBD, 0xF6F8, 0x9CBE, 0xF794,
+	0x9CBF, 0xF795, 0x9CC0, 0xF796, 0x9CC1, 0xF797, 0x9CC2, 0xF798,
+	0x9CC3, 0xC8FA, 0x9CC4, 0xF6F9, 0x9CC5, 0xF6FA, 0x9CC6, 0xF6FB,
+	0x9CC7, 0xF6FC, 0x9CC8, 0xF799, 0x9CC9, 0xF79A, 0x9CCA, 0xF6FD,
+	0x9CCB, 0xF6FE, 0x9CCC, 0xF7A1, 0x9CCD, 0xF7A2, 0x9CCE, 0xF7A3,
+	0x9CCF, 0xF7A4, 0x9CD0, 0xF7A5, 0x9CD1, 0xF79B, 0x9CD2, 0xF79C,
+	0x9CD3, 0xF7A6, 0x9CD4, 0xF7A7, 0x9CD5, 0xF7A8, 0x9CD6, 0xB1EE,
+	0x9CD7, 0xF7A9, 0x9CD8, 0xF7AA, 0x9CD9, 0xF7AB, 0x9CDA, 0xF79D,
+	0x9CDB, 0xF79E, 0x9CDC, 0xF7AC, 0x9CDD, 0xF7AD, 0x9CDE, 0xC1DB,
+	0x9CDF, 0xF7AE, 0x9CE0, 0xF79F, 0x9CE1, 0xF7A0, 0x9CE2, 0xF7AF,
+	0x9CE3, 0xF840, 0x9CE4, 0xF841, 0x9CE5, 0xF842, 0x9CE6, 0xF843,
+	0x9CE7, 0xF844, 0x9CE8, 0xF845, 0x9CE9, 0xF846, 0x9CEA, 0xF847,
+	0x9CEB, 0xF848, 0x9CEC, 0xF849, 0x9CED, 0xF84A, 0x9CEE, 0xF84B,
+	0x9CEF, 0xF84C, 0x9CF0, 0xF84D, 0x9CF1, 0xF84E, 0x9CF2, 0xF84F,
+	0x9CF3, 0xF850, 0x9CF4, 0xF851, 0x9CF5, 0xF852, 0x9CF6, 0xF853,
+	0x9CF7, 0xF854, 0x9CF8, 0xF855, 0x9CF9, 0xF856, 0x9CFA, 0xF857,
+	0x9CFB, 0xF858, 0x9CFC, 0xF859, 0x9CFD, 0xF85A, 0x9CFE, 0xF85B,
+	0x9CFF, 0xF85C, 0x9D00, 0xF85D, 0x9D01, 0xF85E, 0x9D02, 0xF85F,
+	0x9D03, 0xF860, 0x9D04, 0xF861, 0x9D05, 0xF862, 0x9D06, 0xF863,
+	0x9D07, 0xF864, 0x9D08, 0xF865, 0x9D09, 0xF866, 0x9D0A, 0xF867,
+	0x9D0B, 0xF868, 0x9D0C, 0xF869, 0x9D0D, 0xF86A, 0x9D0E, 0xF86B,
+	0x9D0F, 0xF86C, 0x9D10, 0xF86D, 0x9D11, 0xF86E, 0x9D12, 0xF86F,
+	0x9D13, 0xF870, 0x9D14, 0xF871, 0x9D15, 0xF872, 0x9D16, 0xF873,
+	0x9D17, 0xF874, 0x9D18, 0xF875, 0x9D19, 0xF876, 0x9D1A, 0xF877,
+	0x9D1B, 0xF878, 0x9D1C, 0xF879, 0x9D1D, 0xF87A, 0x9D1E, 0xF87B,
+	0x9D1F, 0xF87C, 0x9D20, 0xF87D, 0x9D21, 0xF87E, 0x9D22, 0xF880,
+	0x9D23, 0xF881, 0x9D24, 0xF882, 0x9D25, 0xF883, 0x9D26, 0xF884,
+	0x9D27, 0xF885, 0x9D28, 0xF886, 0x9D29, 0xF887, 0x9D2A, 0xF888,
+	0x9D2B, 0xF889, 0x9D2C, 0xF88A, 0x9D2D, 0xF88B, 0x9D2E, 0xF88C,
+	0x9D2F, 0xF88D, 0x9D30, 0xF88E, 0x9D31, 0xF88F, 0x9D32, 0xF890,
+	0x9D33, 0xF891, 0x9D34, 0xF892, 0x9D35, 0xF893, 0x9D36, 0xF894,
+	0x9D37, 0xF895, 0x9D38, 0xF896, 0x9D39, 0xF897, 0x9D3A, 0xF898,
+	0x9D3B, 0xF899, 0x9D3C, 0xF89A, 0x9D3D, 0xF89B, 0x9D3E, 0xF89C,
+	0x9D3F, 0xF89D, 0x9D40, 0xF89E, 0x9D41, 0xF89F, 0x9D42, 0xF8A0,
+	0x9D43, 0xF940, 0x9D44, 0xF941, 0x9D45, 0xF942, 0x9D46, 0xF943,
+	0x9D47, 0xF944, 0x9D48, 0xF945, 0x9D49, 0xF946, 0x9D4A, 0xF947,
+	0x9D4B, 0xF948, 0x9D4C, 0xF949, 0x9D4D, 0xF94A, 0x9D4E, 0xF94B,
+	0x9D4F, 0xF94C, 0x9D50, 0xF94D, 0x9D51, 0xF94E, 0x9D52, 0xF94F,
+	0x9D53, 0xF950, 0x9D54, 0xF951, 0x9D55, 0xF952, 0x9D56, 0xF953,
+	0x9D57, 0xF954, 0x9D58, 0xF955, 0x9D59, 0xF956, 0x9D5A, 0xF957,
+	0x9D5B, 0xF958, 0x9D5C, 0xF959, 0x9D5D, 0xF95A, 0x9D5E, 0xF95B,
+	0x9D5F, 0xF95C, 0x9D60, 0xF95D, 0x9D61, 0xF95E, 0x9D62, 0xF95F,
+	0x9D63, 0xF960, 0x9D64, 0xF961, 0x9D65, 0xF962, 0x9D66, 0xF963,
+	0x9D67, 0xF964, 0x9D68, 0xF965, 0x9D69, 0xF966, 0x9D6A, 0xF967,
+	0x9D6B, 0xF968, 0x9D6C, 0xF969, 0x9D6D, 0xF96A, 0x9D6E, 0xF96B,
+	0x9D6F, 0xF96C, 0x9D70, 0xF96D, 0x9D71, 0xF96E, 0x9D72, 0xF96F,
+	0x9D73, 0xF970, 0x9D74, 0xF971, 0x9D75, 0xF972, 0x9D76, 0xF973,
+	0x9D77, 0xF974, 0x9D78, 0xF975, 0x9D79, 0xF976, 0x9D7A, 0xF977,
+	0x9D7B, 0xF978, 0x9D7C, 0xF979, 0x9D7D, 0xF97A, 0x9D7E, 0xF97B,
+	0x9D7F, 0xF97C, 0x9D80, 0xF97D, 0x9D81, 0xF97E, 0x9D82, 0xF980,
+	0x9D83, 0xF981, 0x9D84, 0xF982, 0x9D85, 0xF983, 0x9D86, 0xF984,
+	0x9D87, 0xF985, 0x9D88, 0xF986, 0x9D89, 0xF987, 0x9D8A, 0xF988,
+	0x9D8B, 0xF989, 0x9D8C, 0xF98A, 0x9D8D, 0xF98B, 0x9D8E, 0xF98C,
+	0x9D8F, 0xF98D, 0x9D90, 0xF98E, 0x9D91, 0xF98F, 0x9D92, 0xF990,
+	0x9D93, 0xF991, 0x9D94, 0xF992, 0x9D95, 0xF993, 0x9D96, 0xF994,
+	0x9D97, 0xF995, 0x9D98, 0xF996, 0x9D99, 0xF997, 0x9D9A, 0xF998,
+	0x9D9B, 0xF999, 0x9D9C, 0xF99A, 0x9D9D, 0xF99B, 0x9D9E, 0xF99C,
+	0x9D9F, 0xF99D, 0x9DA0, 0xF99E, 0x9DA1, 0xF99F, 0x9DA2, 0xF9A0,
+	0x9DA3, 0xFA40, 0x9DA4, 0xFA41, 0x9DA5, 0xFA42, 0x9DA6, 0xFA43,
+	0x9DA7, 0xFA44, 0x9DA8, 0xFA45, 0x9DA9, 0xFA46, 0x9DAA, 0xFA47,
+	0x9DAB, 0xFA48, 0x9DAC, 0xFA49, 0x9DAD, 0xFA4A, 0x9DAE, 0xFA4B,
+	0x9DAF, 0xFA4C, 0x9DB0, 0xFA4D, 0x9DB1, 0xFA4E, 0x9DB2, 0xFA4F,
+	0x9DB3, 0xFA50, 0x9DB4, 0xFA51, 0x9DB5, 0xFA52, 0x9DB6, 0xFA53,
+	0x9DB7, 0xFA54, 0x9DB8, 0xFA55, 0x9DB9, 0xFA56, 0x9DBA, 0xFA57,
+	0x9DBB, 0xFA58, 0x9DBC, 0xFA59, 0x9DBD, 0xFA5A, 0x9DBE, 0xFA5B,
+	0x9DBF, 0xFA5C, 0x9DC0, 0xFA5D, 0x9DC1, 0xFA5E, 0x9DC2, 0xFA5F,
+	0x9DC3, 0xFA60, 0x9DC4, 0xFA61, 0x9DC5, 0xFA62, 0x9DC6, 0xFA63,
+	0x9DC7, 0xFA64, 0x9DC8, 0xFA65, 0x9DC9, 0xFA66, 0x9DCA, 0xFA67,
+	0x9DCB, 0xFA68, 0x9DCC, 0xFA69, 0x9DCD, 0xFA6A, 0x9DCE, 0xFA6B,
+	0x9DCF, 0xFA6C, 0x9DD0, 0xFA6D, 0x9DD1, 0xFA6E, 0x9DD2, 0xFA6F,
+	0x9DD3, 0xFA70, 0x9DD4, 0xFA71, 0x9DD5, 0xFA72, 0x9DD6, 0xFA73,
+	0x9DD7, 0xFA74, 0x9DD8, 0xFA75, 0x9DD9, 0xFA76, 0x9DDA, 0xFA77,
+	0x9DDB, 0xFA78, 0x9DDC, 0xFA79, 0x9DDD, 0xFA7A, 0x9DDE, 0xFA7B,
+	0x9DDF, 0xFA7C, 0x9DE0, 0xFA7D, 0x9DE1, 0xFA7E, 0x9DE2, 0xFA80,
+	0x9DE3, 0xFA81, 0x9DE4, 0xFA82, 0x9DE5, 0xFA83, 0x9DE6, 0xFA84,
+	0x9DE7, 0xFA85, 0x9DE8, 0xFA86, 0x9DE9, 0xFA87, 0x9DEA, 0xFA88,
+	0x9DEB, 0xFA89, 0x9DEC, 0xFA8A, 0x9DED, 0xFA8B, 0x9DEE, 0xFA8C,
+	0x9DEF, 0xFA8D, 0x9DF0, 0xFA8E, 0x9DF1, 0xFA8F, 0x9DF2, 0xFA90,
+	0x9DF3, 0xFA91, 0x9DF4, 0xFA92, 0x9DF5, 0xFA93, 0x9DF6, 0xFA94,
+	0x9DF7, 0xFA95, 0x9DF8, 0xFA96, 0x9DF9, 0xFA97, 0x9DFA, 0xFA98,
+	0x9DFB, 0xFA99, 0x9DFC, 0xFA9A, 0x9DFD, 0xFA9B, 0x9DFE, 0xFA9C,
+	0x9DFF, 0xFA9D, 0x9E00, 0xFA9E, 0x9E01, 0xFA9F, 0x9E02, 0xFAA0,
+	0x9E03, 0xFB40, 0x9E04, 0xFB41, 0x9E05, 0xFB42, 0x9E06, 0xFB43,
+	0x9E07, 0xFB44, 0x9E08, 0xFB45, 0x9E09, 0xFB46, 0x9E0A, 0xFB47,
+	0x9E0B, 0xFB48, 0x9E0C, 0xFB49, 0x9E0D, 0xFB4A, 0x9E0E, 0xFB4B,
+	0x9E0F, 0xFB4C, 0x9E10, 0xFB4D, 0x9E11, 0xFB4E, 0x9E12, 0xFB4F,
+	0x9E13, 0xFB50, 0x9E14, 0xFB51, 0x9E15, 0xFB52, 0x9E16, 0xFB53,
+	0x9E17, 0xFB54, 0x9E18, 0xFB55, 0x9E19, 0xFB56, 0x9E1A, 0xFB57,
+	0x9E1B, 0xFB58, 0x9E1C, 0xFB59, 0x9E1D, 0xFB5A, 0x9E1E, 0xFB5B,
+	0x9E1F, 0xC4F1, 0x9E20, 0xF0AF, 0x9E21, 0xBCA6, 0x9E22, 0xF0B0,
+	0x9E23, 0xC3F9, 0x9E24, 0xFB5C, 0x9E25, 0xC5B8, 0x9E26, 0xD1BB,
+	0x9E27, 0xFB5D, 0x9E28, 0xF0B1, 0x9E29, 0xF0B2, 0x9E2A, 0xF0B3,
+	0x9E2B, 0xF0B4, 0x9E2C, 0xF0B5, 0x9E2D, 0xD1BC, 0x9E2E, 0xFB5E,
+	0x9E2F, 0xD1EC, 0x9E30, 0xFB5F, 0x9E31, 0xF0B7, 0x9E32, 0xF0B6,
+	0x9E33, 0xD4A7, 0x9E34, 0xFB60, 0x9E35, 0xCDD2, 0x9E36, 0xF0B8,
+	0x9E37, 0xF0BA, 0x9E38, 0xF0B9, 0x9E39, 0xF0BB, 0x9E3A, 0xF0BC,
+	0x9E3B, 0xFB61, 0x9E3C, 0xFB62, 0x9E3D, 0xB8EB, 0x9E3E, 0xF0BD,
+	0x9E3F, 0xBAE8, 0x9E40, 0xFB63, 0x9E41, 0xF0BE, 0x9E42, 0xF0BF,
+	0x9E43, 0xBEE9, 0x9E44, 0xF0C0, 0x9E45, 0xB6EC, 0x9E46, 0xF0C1,
+	0x9E47, 0xF0C2, 0x9E48, 0xF0C3, 0x9E49, 0xF0C4, 0x9E4A, 0xC8B5,
+	0x9E4B, 0xF0C5, 0x9E4C, 0xF0C6, 0x9E4D, 0xFB64, 0x9E4E, 0xF0C7,
+	0x9E4F, 0xC5F4, 0x9E50, 0xFB65, 0x9E51, 0xF0C8, 0x9E52, 0xFB66,
+	0x9E53, 0xFB67, 0x9E54, 0xFB68, 0x9E55, 0xF0C9, 0x9E56, 0xFB69,
+	0x9E57, 0xF0CA, 0x9E58, 0xF7BD, 0x9E59, 0xFB6A, 0x9E5A, 0xF0CB,
+	0x9E5B, 0xF0CC, 0x9E5C, 0xF0CD, 0x9E5D, 0xFB6B, 0x9E5E, 0xF0CE,
+	0x9E5F, 0xFB6C, 0x9E60, 0xFB6D, 0x9E61, 0xFB6E, 0x9E62, 0xFB6F,
+	0x9E63, 0xF0CF, 0x9E64, 0xBAD7, 0x9E65, 0xFB70, 0x9E66, 0xF0D0,
+	0x9E67, 0xF0D1, 0x9E68, 0xF0D2, 0x9E69, 0xF0D3, 0x9E6A, 0xF0D4,
+	0x9E6B, 0xF0D5, 0x9E6C, 0xF0D6, 0x9E6D, 0xF0D8, 0x9E6E, 0xFB71,
+	0x9E6F, 0xFB72, 0x9E70, 0xD3A5, 0x9E71, 0xF0D7, 0x9E72, 0xFB73,
+	0x9E73, 0xF0D9, 0x9E74, 0xFB74, 0x9E75, 0xFB75, 0x9E76, 0xFB76,
+	0x9E77, 0xFB77, 0x9E78, 0xFB78, 0x9E79, 0xFB79, 0x9E7A, 0xFB7A,
+	0x9E7B, 0xFB7B, 0x9E7C, 0xFB7C, 0x9E7D, 0xFB7D, 0x9E7E, 0xF5BA,
+	0x9E7F, 0xC2B9, 0x9E80, 0xFB7E, 0x9E81, 0xFB80, 0x9E82, 0xF7E4,
+	0x9E83, 0xFB81, 0x9E84, 0xFB82, 0x9E85, 0xFB83, 0x9E86, 0xFB84,
+	0x9E87, 0xF7E5, 0x9E88, 0xF7E6, 0x9E89, 0xFB85, 0x9E8A, 0xFB86,
+	0x9E8B, 0xF7E7, 0x9E8C, 0xFB87, 0x9E8D, 0xFB88, 0x9E8E, 0xFB89,
+	0x9E8F, 0xFB8A, 0x9E90, 0xFB8B, 0x9E91, 0xFB8C, 0x9E92, 0xF7E8,
+	0x9E93, 0xC2B4, 0x9E94, 0xFB8D, 0x9E95, 0xFB8E, 0x9E96, 0xFB8F,
+	0x9E97, 0xFB90, 0x9E98, 0xFB91, 0x9E99, 0xFB92, 0x9E9A, 0xFB93,
+	0x9E9B, 0xFB94, 0x9E9C, 0xFB95, 0x9E9D, 0xF7EA, 0x9E9E, 0xFB96,
+	0x9E9F, 0xF7EB, 0x9EA0, 0xFB97, 0x9EA1, 0xFB98, 0x9EA2, 0xFB99,
+	0x9EA3, 0xFB9A, 0x9EA4, 0xFB9B, 0x9EA5, 0xFB9C, 0x9EA6, 0xC2F3,
+	0x9EA7, 0xFB9D, 0x9EA8, 0xFB9E, 0x9EA9, 0xFB9F, 0x9EAA, 0xFBA0,
+	0x9EAB, 0xFC40, 0x9EAC, 0xFC41, 0x9EAD, 0xFC42, 0x9EAE, 0xFC43,
+	0x9EAF, 0xFC44, 0x9EB0, 0xFC45, 0x9EB1, 0xFC46, 0x9EB2, 0xFC47,
+	0x9EB3, 0xFC48, 0x9EB4, 0xF4F0, 0x9EB5, 0xFC49, 0x9EB6, 0xFC4A,
+	0x9EB7, 0xFC4B, 0x9EB8, 0xF4EF, 0x9EB9, 0xFC4C, 0x9EBA, 0xFC4D,
+	0x9EBB, 0xC2E9, 0x9EBC, 0xFC4E, 0x9EBD, 0xF7E1, 0x9EBE, 0xF7E2,
+	0x9EBF, 0xFC4F, 0x9EC0, 0xFC50, 0x9EC1, 0xFC51, 0x9EC2, 0xFC52,
+	0x9EC3, 0xFC53, 0x9EC4, 0xBBC6, 0x9EC5, 0xFC54, 0x9EC6, 0xFC55,
+	0x9EC7, 0xFC56, 0x9EC8, 0xFC57, 0x9EC9, 0xD9E4, 0x9ECA, 0xFC58,
+	0x9ECB, 0xFC59, 0x9ECC, 0xFC5A, 0x9ECD, 0xCAF2, 0x9ECE, 0xC0E8,
+	0x9ECF, 0xF0A4, 0x9ED0, 0xFC5B, 0x9ED1, 0xBADA, 0x9ED2, 0xFC5C,
+	0x9ED3, 0xFC5D, 0x9ED4, 0xC7AD, 0x9ED5, 0xFC5E, 0x9ED6, 0xFC5F,
+	0x9ED7, 0xFC60, 0x9ED8, 0xC4AC, 0x9ED9, 0xFC61, 0x9EDA, 0xFC62,
+	0x9EDB, 0xF7EC, 0x9EDC, 0xF7ED, 0x9EDD, 0xF7EE, 0x9EDE, 0xFC63,
+	0x9EDF, 0xF7F0, 0x9EE0, 0xF7EF, 0x9EE1, 0xFC64, 0x9EE2, 0xF7F1,
+	0x9EE3, 0xFC65, 0x9EE4, 0xFC66, 0x9EE5, 0xF7F4, 0x9EE6, 0xFC67,
+	0x9EE7, 0xF7F3, 0x9EE8, 0xFC68, 0x9EE9, 0xF7F2, 0x9EEA, 0xF7F5,
+	0x9EEB, 0xFC69, 0x9EEC, 0xFC6A, 0x9EED, 0xFC6B, 0x9EEE, 0xFC6C,
+	0x9EEF, 0xF7F6, 0x9EF0, 0xFC6D, 0x9EF1, 0xFC6E, 0x9EF2, 0xFC6F,
+	0x9EF3, 0xFC70, 0x9EF4, 0xFC71, 0x9EF5, 0xFC72, 0x9EF6, 0xFC73,
+	0x9EF7, 0xFC74, 0x9EF8, 0xFC75, 0x9EF9, 0xEDE9, 0x9EFA, 0xFC76,
+	0x9EFB, 0xEDEA, 0x9EFC, 0xEDEB, 0x9EFD, 0xFC77, 0x9EFE, 0xF6BC,
+	0x9EFF, 0xFC78, 0x9F00, 0xFC79, 0x9F01, 0xFC7A, 0x9F02, 0xFC7B,
+	0x9F03, 0xFC7C, 0x9F04, 0xFC7D, 0x9F05, 0xFC7E, 0x9F06, 0xFC80,
+	0x9F07, 0xFC81, 0x9F08, 0xFC82, 0x9F09, 0xFC83, 0x9F0A, 0xFC84,
+	0x9F0B, 0xF6BD, 0x9F0C, 0xFC85, 0x9F0D, 0xF6BE, 0x9F0E, 0xB6A6,
+	0x9F0F, 0xFC86, 0x9F10, 0xD8BE, 0x9F11, 0xFC87, 0x9F12, 0xFC88,
+	0x9F13, 0xB9C4, 0x9F14, 0xFC89, 0x9F15, 0xFC8A, 0x9F16, 0xFC8B,
+	0x9F17, 0xD8BB, 0x9F18, 0xFC8C, 0x9F19, 0xDCB1, 0x9F1A, 0xFC8D,
+	0x9F1B, 0xFC8E, 0x9F1C, 0xFC8F, 0x9F1D, 0xFC90, 0x9F1E, 0xFC91,
+	0x9F1F, 0xFC92, 0x9F20, 0xCAF3, 0x9F21, 0xFC93, 0x9F22, 0xF7F7,
+	0x9F23, 0xFC94, 0x9F24, 0xFC95, 0x9F25, 0xFC96, 0x9F26, 0xFC97,
+	0x9F27, 0xFC98, 0x9F28, 0xFC99, 0x9F29, 0xFC9A, 0x9F2A, 0xFC9B,
+	0x9F2B, 0xFC9C, 0x9F2C, 0xF7F8, 0x9F2D, 0xFC9D, 0x9F2E, 0xFC9E,
+	0x9F2F, 0xF7F9, 0x9F30, 0xFC9F, 0x9F31, 0xFCA0, 0x9F32, 0xFD40,
+	0x9F33, 0xFD41, 0x9F34, 0xFD42, 0x9F35, 0xFD43, 0x9F36, 0xFD44,
+	0x9F37, 0xF7FB, 0x9F38, 0xFD45, 0x9F39, 0xF7FA, 0x9F3A, 0xFD46,
+	0x9F3B, 0xB1C7, 0x9F3C, 0xFD47, 0x9F3D, 0xF7FC, 0x9F3E, 0xF7FD,
+	0x9F3F, 0xFD48, 0x9F40, 0xFD49, 0x9F41, 0xFD4A, 0x9F42, 0xFD4B,
+	0x9F43, 0xFD4C, 0x9F44, 0xF7FE, 0x9F45, 0xFD4D, 0x9F46, 0xFD4E,
+	0x9F47, 0xFD4F, 0x9F48, 0xFD50, 0x9F49, 0xFD51, 0x9F4A, 0xFD52,
+	0x9F4B, 0xFD53, 0x9F4C, 0xFD54, 0x9F4D, 0xFD55, 0x9F4E, 0xFD56,
+	0x9F4F, 0xFD57, 0x9F50, 0xC6EB, 0x9F51, 0xECB4, 0x9F52, 0xFD58,
+	0x9F53, 0xFD59, 0x9F54, 0xFD5A, 0x9F55, 0xFD5B, 0x9F56, 0xFD5C,
+	0x9F57, 0xFD5D, 0x9F58, 0xFD5E, 0x9F59, 0xFD5F, 0x9F5A, 0xFD60,
+	0x9F5B, 0xFD61, 0x9F5C, 0xFD62, 0x9F5D, 0xFD63, 0x9F5E, 0xFD64,
+	0x9F5F, 0xFD65, 0x9F60, 0xFD66, 0x9F61, 0xFD67, 0x9F62, 0xFD68,
+	0x9F63, 0xFD69, 0x9F64, 0xFD6A, 0x9F65, 0xFD6B, 0x9F66, 0xFD6C,
+	0x9F67, 0xFD6D, 0x9F68, 0xFD6E, 0x9F69, 0xFD6F, 0x9F6A, 0xFD70,
+	0x9F6B, 0xFD71, 0x9F6C, 0xFD72, 0x9F6D, 0xFD73, 0x9F6E, 0xFD74,
+	0x9F6F, 0xFD75, 0x9F70, 0xFD76, 0x9F71, 0xFD77, 0x9F72, 0xFD78,
+	0x9F73, 0xFD79, 0x9F74, 0xFD7A, 0x9F75, 0xFD7B, 0x9F76, 0xFD7C,
+	0x9F77, 0xFD7D, 0x9F78, 0xFD7E, 0x9F79, 0xFD80, 0x9F7A, 0xFD81,
+	0x9F7B, 0xFD82, 0x9F7C, 0xFD83, 0x9F7D, 0xFD84, 0x9F7E, 0xFD85,
+	0x9F7F, 0xB3DD, 0x9F80, 0xF6B3, 0x9F81, 0xFD86, 0x9F82, 0xFD87,
+	0x9F83, 0xF6B4, 0x9F84, 0xC1E4, 0x9F85, 0xF6B5, 0x9F86, 0xF6B6,
+	0x9F87, 0xF6B7, 0x9F88, 0xF6B8, 0x9F89, 0xF6B9, 0x9F8A, 0xF6BA,
+	0x9F8B, 0xC8A3, 0x9F8C, 0xF6BB, 0x9F8D, 0xFD88, 0x9F8E, 0xFD89,
+	0x9F8F, 0xFD8A, 0x9F90, 0xFD8B, 0x9F91, 0xFD8C, 0x9F92, 0xFD8D,
+	0x9F93, 0xFD8E, 0x9F94, 0xFD8F, 0x9F95, 0xFD90, 0x9F96, 0xFD91,
+	0x9F97, 0xFD92, 0x9F98, 0xFD93, 0x9F99, 0xC1FA, 0x9F9A, 0xB9A8,
+	0x9F9B, 0xEDE8, 0x9F9C, 0xFD94, 0x9F9D, 0xFD95, 0x9F9E, 0xFD96,
+	0x9F9F, 0xB9EA, 0x9FA0, 0xD9DF, 0x9FA1, 0xFD97, 0x9FA2, 0xFD98,
+	0x9FA3, 0xFD99, 0x9FA4, 0xFD9A, 0x9FA5, 0xFD9B, 0xF92C, 0xFD9C,
+	0xF979, 0xFD9D, 0xF995, 0xFD9E, 0xF9E7, 0xFD9F, 0xF9F1, 0xFDA0,
+	0xFA0C, 0xFE40, 0xFA0D, 0xFE41, 0xFA0E, 0xFE42, 0xFA0F, 0xFE43,
+	0xFA11, 0xFE44, 0xFA13, 0xFE45, 0xFA14, 0xFE46, 0xFA18, 0xFE47,
+	0xFA1F, 0xFE48, 0xFA20, 0xFE49, 0xFA21, 0xFE4A, 0xFA23, 0xFE4B,
+	0xFA24, 0xFE4C, 0xFA27, 0xFE4D, 0xFA28, 0xFE4E, 0xFA29, 0xFE4F,
+	0xFE30, 0xA955, 0xFE31, 0xA6F2, 0xFE33, 0xA6F4, 0xFE34, 0xA6F5,
+	0xFE35, 0xA6E0, 0xFE36, 0xA6E1, 0xFE37, 0xA6F0, 0xFE38, 0xA6F1,
+	0xFE39, 0xA6E2, 0xFE3A, 0xA6E3, 0xFE3B, 0xA6EE, 0xFE3C, 0xA6EF,
+	0xFE3D, 0xA6E6, 0xFE3E, 0xA6E7, 0xFE3F, 0xA6E4, 0xFE40, 0xA6E5,
+	0xFE41, 0xA6E8, 0xFE42, 0xA6E9, 0xFE43, 0xA6EA, 0xFE44, 0xA6EB,
+	0xFE49, 0xA968, 0xFE4A, 0xA969, 0xFE4B, 0xA96A, 0xFE4C, 0xA96B,
+	0xFE4D, 0xA96C, 0xFE4E, 0xA96D, 0xFE4F, 0xA96E, 0xFE50, 0xA96F,
+	0xFE51, 0xA970, 0xFE52, 0xA971, 0xFE54, 0xA972, 0xFE55, 0xA973,
+	0xFE56, 0xA974, 0xFE57, 0xA975, 0xFE59, 0xA976, 0xFE5A, 0xA977,
+	0xFE5B, 0xA978, 0xFE5C, 0xA979, 0xFE5D, 0xA97A, 0xFE5E, 0xA97B,
+	0xFE5F, 0xA97C, 0xFE60, 0xA97D, 0xFE61, 0xA97E, 0xFE62, 0xA980,
+	0xFE63, 0xA981, 0xFE64, 0xA982, 0xFE65, 0xA983, 0xFE66, 0xA984,
+	0xFE68, 0xA985, 0xFE69, 0xA986, 0xFE6A, 0xA987, 0xFE6B, 0xA988,
+	0xFF01, 0xA3A1, 0xFF02, 0xA3A2, 0xFF03, 0xA3A3, 0xFF04, 0xA1E7,
+	0xFF05, 0xA3A5, 0xFF06, 0xA3A6, 0xFF07, 0xA3A7, 0xFF08, 0xA3A8,
+	0xFF09, 0xA3A9, 0xFF0A, 0xA3AA, 0xFF0B, 0xA3AB, 0xFF0C, 0xA3AC,
+	0xFF0D, 0xA3AD, 0xFF0E, 0xA3AE, 0xFF0F, 0xA3AF, 0xFF10, 0xA3B0,
+	0xFF11, 0xA3B1, 0xFF12, 0xA3B2, 0xFF13, 0xA3B3, 0xFF14, 0xA3B4,
+	0xFF15, 0xA3B5, 0xFF16, 0xA3B6, 0xFF17, 0xA3B7, 0xFF18, 0xA3B8,
+	0xFF19, 0xA3B9, 0xFF1A, 0xA3BA, 0xFF1B, 0xA3BB, 0xFF1C, 0xA3BC,
+	0xFF1D, 0xA3BD, 0xFF1E, 0xA3BE, 0xFF1F, 0xA3BF, 0xFF20, 0xA3C0,
+	0xFF21, 0xA3C1, 0xFF22, 0xA3C2, 0xFF23, 0xA3C3, 0xFF24, 0xA3C4,
+	0xFF25, 0xA3C5, 0xFF26, 0xA3C6, 0xFF27, 0xA3C7, 0xFF28, 0xA3C8,
+	0xFF29, 0xA3C9, 0xFF2A, 0xA3CA, 0xFF2B, 0xA3CB, 0xFF2C, 0xA3CC,
+	0xFF2D, 0xA3CD, 0xFF2E, 0xA3CE, 0xFF2F, 0xA3CF, 0xFF30, 0xA3D0,
+	0xFF31, 0xA3D1, 0xFF32, 0xA3D2, 0xFF33, 0xA3D3, 0xFF34, 0xA3D4,
+	0xFF35, 0xA3D5, 0xFF36, 0xA3D6, 0xFF37, 0xA3D7, 0xFF38, 0xA3D8,
+	0xFF39, 0xA3D9, 0xFF3A, 0xA3DA, 0xFF3B, 0xA3DB, 0xFF3C, 0xA3DC,
+	0xFF3D, 0xA3DD, 0xFF3E, 0xA3DE, 0xFF3F, 0xA3DF, 0xFF40, 0xA3E0,
+	0xFF41, 0xA3E1, 0xFF42, 0xA3E2, 0xFF43, 0xA3E3, 0xFF44, 0xA3E4,
+	0xFF45, 0xA3E5, 0xFF46, 0xA3E6, 0xFF47, 0xA3E7, 0xFF48, 0xA3E8,
+	0xFF49, 0xA3E9, 0xFF4A, 0xA3EA, 0xFF4B, 0xA3EB, 0xFF4C, 0xA3EC,
+	0xFF4D, 0xA3ED, 0xFF4E, 0xA3EE, 0xFF4F, 0xA3EF, 0xFF50, 0xA3F0,
+	0xFF51, 0xA3F1, 0xFF52, 0xA3F2, 0xFF53, 0xA3F3, 0xFF54, 0xA3F4,
+	0xFF55, 0xA3F5, 0xFF56, 0xA3F6, 0xFF57, 0xA3F7, 0xFF58, 0xA3F8,
+	0xFF59, 0xA3F9, 0xFF5A, 0xA3FA, 0xFF5B, 0xA3FB, 0xFF5C, 0xA3FC,
+	0xFF5D, 0xA3FD, 0xFF5E, 0xA1AB, 0xFFE0, 0xA1E9, 0xFFE1, 0xA1EA,
+	0xFFE2, 0xA956, 0xFFE3, 0xA3FE, 0xFFE4, 0xA957, 0xFFE5, 0xA3A4,
+	0, 0
+};
+
+static
+const WCHAR oem2uni[] = {
+/*	OEM - Unicode,  OEM - Unicode,  OEM - Unicode,  OEM - Unicode */
+	0x0080, 0x20AC, 0x8140, 0x4E02, 0x8141, 0x4E04, 0x8142, 0x4E05,
+	0x8143, 0x4E06, 0x8144, 0x4E0F, 0x8145, 0x4E12, 0x8146, 0x4E17,
+	0x8147, 0x4E1F, 0x8148, 0x4E20, 0x8149, 0x4E21, 0x814A, 0x4E23,
+	0x814B, 0x4E26, 0x814C, 0x4E29, 0x814D, 0x4E2E, 0x814E, 0x4E2F,
+	0x814F, 0x4E31, 0x8150, 0x4E33, 0x8151, 0x4E35, 0x8152, 0x4E37,
+	0x8153, 0x4E3C, 0x8154, 0x4E40, 0x8155, 0x4E41, 0x8156, 0x4E42,
+	0x8157, 0x4E44, 0x8158, 0x4E46, 0x8159, 0x4E4A, 0x815A, 0x4E51,
+	0x815B, 0x4E55, 0x815C, 0x4E57, 0x815D, 0x4E5A, 0x815E, 0x4E5B,
+	0x815F, 0x4E62, 0x8160, 0x4E63, 0x8161, 0x4E64, 0x8162, 0x4E65,
+	0x8163, 0x4E67, 0x8164, 0x4E68, 0x8165, 0x4E6A, 0x8166, 0x4E6B,
+	0x8167, 0x4E6C, 0x8168, 0x4E6D, 0x8169, 0x4E6E, 0x816A, 0x4E6F,
+	0x816B, 0x4E72, 0x816C, 0x4E74, 0x816D, 0x4E75, 0x816E, 0x4E76,
+	0x816F, 0x4E77, 0x8170, 0x4E78, 0x8171, 0x4E79, 0x8172, 0x4E7A,
+	0x8173, 0x4E7B, 0x8174, 0x4E7C, 0x8175, 0x4E7D, 0x8176, 0x4E7F,
+	0x8177, 0x4E80, 0x8178, 0x4E81, 0x8179, 0x4E82, 0x817A, 0x4E83,
+	0x817B, 0x4E84, 0x817C, 0x4E85, 0x817D, 0x4E87, 0x817E, 0x4E8A,
+	0x8180, 0x4E90, 0x8181, 0x4E96, 0x8182, 0x4E97, 0x8183, 0x4E99,
+	0x8184, 0x4E9C, 0x8185, 0x4E9D, 0x8186, 0x4E9E, 0x8187, 0x4EA3,
+	0x8188, 0x4EAA, 0x8189, 0x4EAF, 0x818A, 0x4EB0, 0x818B, 0x4EB1,
+	0x818C, 0x4EB4, 0x818D, 0x4EB6, 0x818E, 0x4EB7, 0x818F, 0x4EB8,
+	0x8190, 0x4EB9, 0x8191, 0x4EBC, 0x8192, 0x4EBD, 0x8193, 0x4EBE,
+	0x8194, 0x4EC8, 0x8195, 0x4ECC, 0x8196, 0x4ECF, 0x8197, 0x4ED0,
+	0x8198, 0x4ED2, 0x8199, 0x4EDA, 0x819A, 0x4EDB, 0x819B, 0x4EDC,
+	0x819C, 0x4EE0, 0x819D, 0x4EE2, 0x819E, 0x4EE6, 0x819F, 0x4EE7,
+	0x81A0, 0x4EE9, 0x81A1, 0x4EED, 0x81A2, 0x4EEE, 0x81A3, 0x4EEF,
+	0x81A4, 0x4EF1, 0x81A5, 0x4EF4, 0x81A6, 0x4EF8, 0x81A7, 0x4EF9,
+	0x81A8, 0x4EFA, 0x81A9, 0x4EFC, 0x81AA, 0x4EFE, 0x81AB, 0x4F00,
+	0x81AC, 0x4F02, 0x81AD, 0x4F03, 0x81AE, 0x4F04, 0x81AF, 0x4F05,
+	0x81B0, 0x4F06, 0x81B1, 0x4F07, 0x81B2, 0x4F08, 0x81B3, 0x4F0B,
+	0x81B4, 0x4F0C, 0x81B5, 0x4F12, 0x81B6, 0x4F13, 0x81B7, 0x4F14,
+	0x81B8, 0x4F15, 0x81B9, 0x4F16, 0x81BA, 0x4F1C, 0x81BB, 0x4F1D,
+	0x81BC, 0x4F21, 0x81BD, 0x4F23, 0x81BE, 0x4F28, 0x81BF, 0x4F29,
+	0x81C0, 0x4F2C, 0x81C1, 0x4F2D, 0x81C2, 0x4F2E, 0x81C3, 0x4F31,
+	0x81C4, 0x4F33, 0x81C5, 0x4F35, 0x81C6, 0x4F37, 0x81C7, 0x4F39,
+	0x81C8, 0x4F3B, 0x81C9, 0x4F3E, 0x81CA, 0x4F3F, 0x81CB, 0x4F40,
+	0x81CC, 0x4F41, 0x81CD, 0x4F42, 0x81CE, 0x4F44, 0x81CF, 0x4F45,
+	0x81D0, 0x4F47, 0x81D1, 0x4F48, 0x81D2, 0x4F49, 0x81D3, 0x4F4A,
+	0x81D4, 0x4F4B, 0x81D5, 0x4F4C, 0x81D6, 0x4F52, 0x81D7, 0x4F54,
+	0x81D8, 0x4F56, 0x81D9, 0x4F61, 0x81DA, 0x4F62, 0x81DB, 0x4F66,
+	0x81DC, 0x4F68, 0x81DD, 0x4F6A, 0x81DE, 0x4F6B, 0x81DF, 0x4F6D,
+	0x81E0, 0x4F6E, 0x81E1, 0x4F71, 0x81E2, 0x4F72, 0x81E3, 0x4F75,
+	0x81E4, 0x4F77, 0x81E5, 0x4F78, 0x81E6, 0x4F79, 0x81E7, 0x4F7A,
+	0x81E8, 0x4F7D, 0x81E9, 0x4F80, 0x81EA, 0x4F81, 0x81EB, 0x4F82,
+	0x81EC, 0x4F85, 0x81ED, 0x4F86, 0x81EE, 0x4F87, 0x81EF, 0x4F8A,
+	0x81F0, 0x4F8C, 0x81F1, 0x4F8E, 0x81F2, 0x4F90, 0x81F3, 0x4F92,
+	0x81F4, 0x4F93, 0x81F5, 0x4F95, 0x81F6, 0x4F96, 0x81F7, 0x4F98,
+	0x81F8, 0x4F99, 0x81F9, 0x4F9A, 0x81FA, 0x4F9C, 0x81FB, 0x4F9E,
+	0x81FC, 0x4F9F, 0x81FD, 0x4FA1, 0x81FE, 0x4FA2, 0x8240, 0x4FA4,
+	0x8241, 0x4FAB, 0x8242, 0x4FAD, 0x8243, 0x4FB0, 0x8244, 0x4FB1,
+	0x8245, 0x4FB2, 0x8246, 0x4FB3, 0x8247, 0x4FB4, 0x8248, 0x4FB6,
+	0x8249, 0x4FB7, 0x824A, 0x4FB8, 0x824B, 0x4FB9, 0x824C, 0x4FBA,
+	0x824D, 0x4FBB, 0x824E, 0x4FBC, 0x824F, 0x4FBD, 0x8250, 0x4FBE,
+	0x8251, 0x4FC0, 0x8252, 0x4FC1, 0x8253, 0x4FC2, 0x8254, 0x4FC6,
+	0x8255, 0x4FC7, 0x8256, 0x4FC8, 0x8257, 0x4FC9, 0x8258, 0x4FCB,
+	0x8259, 0x4FCC, 0x825A, 0x4FCD, 0x825B, 0x4FD2, 0x825C, 0x4FD3,
+	0x825D, 0x4FD4, 0x825E, 0x4FD5, 0x825F, 0x4FD6, 0x8260, 0x4FD9,
+	0x8261, 0x4FDB, 0x8262, 0x4FE0, 0x8263, 0x4FE2, 0x8264, 0x4FE4,
+	0x8265, 0x4FE5, 0x8266, 0x4FE7, 0x8267, 0x4FEB, 0x8268, 0x4FEC,
+	0x8269, 0x4FF0, 0x826A, 0x4FF2, 0x826B, 0x4FF4, 0x826C, 0x4FF5,
+	0x826D, 0x4FF6, 0x826E, 0x4FF7, 0x826F, 0x4FF9, 0x8270, 0x4FFB,
+	0x8271, 0x4FFC, 0x8272, 0x4FFD, 0x8273, 0x4FFF, 0x8274, 0x5000,
+	0x8275, 0x5001, 0x8276, 0x5002, 0x8277, 0x5003, 0x8278, 0x5004,
+	0x8279, 0x5005, 0x827A, 0x5006, 0x827B, 0x5007, 0x827C, 0x5008,
+	0x827D, 0x5009, 0x827E, 0x500A, 0x8280, 0x500B, 0x8281, 0x500E,
+	0x8282, 0x5010, 0x8283, 0x5011, 0x8284, 0x5013, 0x8285, 0x5015,
+	0x8286, 0x5016, 0x8287, 0x5017, 0x8288, 0x501B, 0x8289, 0x501D,
+	0x828A, 0x501E, 0x828B, 0x5020, 0x828C, 0x5022, 0x828D, 0x5023,
+	0x828E, 0x5024, 0x828F, 0x5027, 0x8290, 0x502B, 0x8291, 0x502F,
+	0x8292, 0x5030, 0x8293, 0x5031, 0x8294, 0x5032, 0x8295, 0x5033,
+	0x8296, 0x5034, 0x8297, 0x5035, 0x8298, 0x5036, 0x8299, 0x5037,
+	0x829A, 0x5038, 0x829B, 0x5039, 0x829C, 0x503B, 0x829D, 0x503D,
+	0x829E, 0x503F, 0x829F, 0x5040, 0x82A0, 0x5041, 0x82A1, 0x5042,
+	0x82A2, 0x5044, 0x82A3, 0x5045, 0x82A4, 0x5046, 0x82A5, 0x5049,
+	0x82A6, 0x504A, 0x82A7, 0x504B, 0x82A8, 0x504D, 0x82A9, 0x5050,
+	0x82AA, 0x5051, 0x82AB, 0x5052, 0x82AC, 0x5053, 0x82AD, 0x5054,
+	0x82AE, 0x5056, 0x82AF, 0x5057, 0x82B0, 0x5058, 0x82B1, 0x5059,
+	0x82B2, 0x505B, 0x82B3, 0x505D, 0x82B4, 0x505E, 0x82B5, 0x505F,
+	0x82B6, 0x5060, 0x82B7, 0x5061, 0x82B8, 0x5062, 0x82B9, 0x5063,
+	0x82BA, 0x5064, 0x82BB, 0x5066, 0x82BC, 0x5067, 0x82BD, 0x5068,
+	0x82BE, 0x5069, 0x82BF, 0x506A, 0x82C0, 0x506B, 0x82C1, 0x506D,
+	0x82C2, 0x506E, 0x82C3, 0x506F, 0x82C4, 0x5070, 0x82C5, 0x5071,
+	0x82C6, 0x5072, 0x82C7, 0x5073, 0x82C8, 0x5074, 0x82C9, 0x5075,
+	0x82CA, 0x5078, 0x82CB, 0x5079, 0x82CC, 0x507A, 0x82CD, 0x507C,
+	0x82CE, 0x507D, 0x82CF, 0x5081, 0x82D0, 0x5082, 0x82D1, 0x5083,
+	0x82D2, 0x5084, 0x82D3, 0x5086, 0x82D4, 0x5087, 0x82D5, 0x5089,
+	0x82D6, 0x508A, 0x82D7, 0x508B, 0x82D8, 0x508C, 0x82D9, 0x508E,
+	0x82DA, 0x508F, 0x82DB, 0x5090, 0x82DC, 0x5091, 0x82DD, 0x5092,
+	0x82DE, 0x5093, 0x82DF, 0x5094, 0x82E0, 0x5095, 0x82E1, 0x5096,
+	0x82E2, 0x5097, 0x82E3, 0x5098, 0x82E4, 0x5099, 0x82E5, 0x509A,
+	0x82E6, 0x509B, 0x82E7, 0x509C, 0x82E8, 0x509D, 0x82E9, 0x509E,
+	0x82EA, 0x509F, 0x82EB, 0x50A0, 0x82EC, 0x50A1, 0x82ED, 0x50A2,
+	0x82EE, 0x50A4, 0x82EF, 0x50A6, 0x82F0, 0x50AA, 0x82F1, 0x50AB,
+	0x82F2, 0x50AD, 0x82F3, 0x50AE, 0x82F4, 0x50AF, 0x82F5, 0x50B0,
+	0x82F6, 0x50B1, 0x82F7, 0x50B3, 0x82F8, 0x50B4, 0x82F9, 0x50B5,
+	0x82FA, 0x50B6, 0x82FB, 0x50B7, 0x82FC, 0x50B8, 0x82FD, 0x50B9,
+	0x82FE, 0x50BC, 0x8340, 0x50BD, 0x8341, 0x50BE, 0x8342, 0x50BF,
+	0x8343, 0x50C0, 0x8344, 0x50C1, 0x8345, 0x50C2, 0x8346, 0x50C3,
+	0x8347, 0x50C4, 0x8348, 0x50C5, 0x8349, 0x50C6, 0x834A, 0x50C7,
+	0x834B, 0x50C8, 0x834C, 0x50C9, 0x834D, 0x50CA, 0x834E, 0x50CB,
+	0x834F, 0x50CC, 0x8350, 0x50CD, 0x8351, 0x50CE, 0x8352, 0x50D0,
+	0x8353, 0x50D1, 0x8354, 0x50D2, 0x8355, 0x50D3, 0x8356, 0x50D4,
+	0x8357, 0x50D5, 0x8358, 0x50D7, 0x8359, 0x50D8, 0x835A, 0x50D9,
+	0x835B, 0x50DB, 0x835C, 0x50DC, 0x835D, 0x50DD, 0x835E, 0x50DE,
+	0x835F, 0x50DF, 0x8360, 0x50E0, 0x8361, 0x50E1, 0x8362, 0x50E2,
+	0x8363, 0x50E3, 0x8364, 0x50E4, 0x8365, 0x50E5, 0x8366, 0x50E8,
+	0x8367, 0x50E9, 0x8368, 0x50EA, 0x8369, 0x50EB, 0x836A, 0x50EF,
+	0x836B, 0x50F0, 0x836C, 0x50F1, 0x836D, 0x50F2, 0x836E, 0x50F4,
+	0x836F, 0x50F6, 0x8370, 0x50F7, 0x8371, 0x50F8, 0x8372, 0x50F9,
+	0x8373, 0x50FA, 0x8374, 0x50FC, 0x8375, 0x50FD, 0x8376, 0x50FE,
+	0x8377, 0x50FF, 0x8378, 0x5100, 0x8379, 0x5101, 0x837A, 0x5102,
+	0x837B, 0x5103, 0x837C, 0x5104, 0x837D, 0x5105, 0x837E, 0x5108,
+	0x8380, 0x5109, 0x8381, 0x510A, 0x8382, 0x510C, 0x8383, 0x510D,
+	0x8384, 0x510E, 0x8385, 0x510F, 0x8386, 0x5110, 0x8387, 0x5111,
+	0x8388, 0x5113, 0x8389, 0x5114, 0x838A, 0x5115, 0x838B, 0x5116,
+	0x838C, 0x5117, 0x838D, 0x5118, 0x838E, 0x5119, 0x838F, 0x511A,
+	0x8390, 0x511B, 0x8391, 0x511C, 0x8392, 0x511D, 0x8393, 0x511E,
+	0x8394, 0x511F, 0x8395, 0x5120, 0x8396, 0x5122, 0x8397, 0x5123,
+	0x8398, 0x5124, 0x8399, 0x5125, 0x839A, 0x5126, 0x839B, 0x5127,
+	0x839C, 0x5128, 0x839D, 0x5129, 0x839E, 0x512A, 0x839F, 0x512B,
+	0x83A0, 0x512C, 0x83A1, 0x512D, 0x83A2, 0x512E, 0x83A3, 0x512F,
+	0x83A4, 0x5130, 0x83A5, 0x5131, 0x83A6, 0x5132, 0x83A7, 0x5133,
+	0x83A8, 0x5134, 0x83A9, 0x5135, 0x83AA, 0x5136, 0x83AB, 0x5137,
+	0x83AC, 0x5138, 0x83AD, 0x5139, 0x83AE, 0x513A, 0x83AF, 0x513B,
+	0x83B0, 0x513C, 0x83B1, 0x513D, 0x83B2, 0x513E, 0x83B3, 0x5142,
+	0x83B4, 0x5147, 0x83B5, 0x514A, 0x83B6, 0x514C, 0x83B7, 0x514E,
+	0x83B8, 0x514F, 0x83B9, 0x5150, 0x83BA, 0x5152, 0x83BB, 0x5153,
+	0x83BC, 0x5157, 0x83BD, 0x5158, 0x83BE, 0x5159, 0x83BF, 0x515B,
+	0x83C0, 0x515D, 0x83C1, 0x515E, 0x83C2, 0x515F, 0x83C3, 0x5160,
+	0x83C4, 0x5161, 0x83C5, 0x5163, 0x83C6, 0x5164, 0x83C7, 0x5166,
+	0x83C8, 0x5167, 0x83C9, 0x5169, 0x83CA, 0x516A, 0x83CB, 0x516F,
+	0x83CC, 0x5172, 0x83CD, 0x517A, 0x83CE, 0x517E, 0x83CF, 0x517F,
+	0x83D0, 0x5183, 0x83D1, 0x5184, 0x83D2, 0x5186, 0x83D3, 0x5187,
+	0x83D4, 0x518A, 0x83D5, 0x518B, 0x83D6, 0x518E, 0x83D7, 0x518F,
+	0x83D8, 0x5190, 0x83D9, 0x5191, 0x83DA, 0x5193, 0x83DB, 0x5194,
+	0x83DC, 0x5198, 0x83DD, 0x519A, 0x83DE, 0x519D, 0x83DF, 0x519E,
+	0x83E0, 0x519F, 0x83E1, 0x51A1, 0x83E2, 0x51A3, 0x83E3, 0x51A6,
+	0x83E4, 0x51A7, 0x83E5, 0x51A8, 0x83E6, 0x51A9, 0x83E7, 0x51AA,
+	0x83E8, 0x51AD, 0x83E9, 0x51AE, 0x83EA, 0x51B4, 0x83EB, 0x51B8,
+	0x83EC, 0x51B9, 0x83ED, 0x51BA, 0x83EE, 0x51BE, 0x83EF, 0x51BF,
+	0x83F0, 0x51C1, 0x83F1, 0x51C2, 0x83F2, 0x51C3, 0x83F3, 0x51C5,
+	0x83F4, 0x51C8, 0x83F5, 0x51CA, 0x83F6, 0x51CD, 0x83F7, 0x51CE,
+	0x83F8, 0x51D0, 0x83F9, 0x51D2, 0x83FA, 0x51D3, 0x83FB, 0x51D4,
+	0x83FC, 0x51D5, 0x83FD, 0x51D6, 0x83FE, 0x51D7, 0x8440, 0x51D8,
+	0x8441, 0x51D9, 0x8442, 0x51DA, 0x8443, 0x51DC, 0x8444, 0x51DE,
+	0x8445, 0x51DF, 0x8446, 0x51E2, 0x8447, 0x51E3, 0x8448, 0x51E5,
+	0x8449, 0x51E6, 0x844A, 0x51E7, 0x844B, 0x51E8, 0x844C, 0x51E9,
+	0x844D, 0x51EA, 0x844E, 0x51EC, 0x844F, 0x51EE, 0x8450, 0x51F1,
+	0x8451, 0x51F2, 0x8452, 0x51F4, 0x8453, 0x51F7, 0x8454, 0x51FE,
+	0x8455, 0x5204, 0x8456, 0x5205, 0x8457, 0x5209, 0x8458, 0x520B,
+	0x8459, 0x520C, 0x845A, 0x520F, 0x845B, 0x5210, 0x845C, 0x5213,
+	0x845D, 0x5214, 0x845E, 0x5215, 0x845F, 0x521C, 0x8460, 0x521E,
+	0x8461, 0x521F, 0x8462, 0x5221, 0x8463, 0x5222, 0x8464, 0x5223,
+	0x8465, 0x5225, 0x8466, 0x5226, 0x8467, 0x5227, 0x8468, 0x522A,
+	0x8469, 0x522C, 0x846A, 0x522F, 0x846B, 0x5231, 0x846C, 0x5232,
+	0x846D, 0x5234, 0x846E, 0x5235, 0x846F, 0x523C, 0x8470, 0x523E,
+	0x8471, 0x5244, 0x8472, 0x5245, 0x8473, 0x5246, 0x8474, 0x5247,
+	0x8475, 0x5248, 0x8476, 0x5249, 0x8477, 0x524B, 0x8478, 0x524E,
+	0x8479, 0x524F, 0x847A, 0x5252, 0x847B, 0x5253, 0x847C, 0x5255,
+	0x847D, 0x5257, 0x847E, 0x5258, 0x8480, 0x5259, 0x8481, 0x525A,
+	0x8482, 0x525B, 0x8483, 0x525D, 0x8484, 0x525F, 0x8485, 0x5260,
+	0x8486, 0x5262, 0x8487, 0x5263, 0x8488, 0x5264, 0x8489, 0x5266,
+	0x848A, 0x5268, 0x848B, 0x526B, 0x848C, 0x526C, 0x848D, 0x526D,
+	0x848E, 0x526E, 0x848F, 0x5270, 0x8490, 0x5271, 0x8491, 0x5273,
+	0x8492, 0x5274, 0x8493, 0x5275, 0x8494, 0x5276, 0x8495, 0x5277,
+	0x8496, 0x5278, 0x8497, 0x5279, 0x8498, 0x527A, 0x8499, 0x527B,
+	0x849A, 0x527C, 0x849B, 0x527E, 0x849C, 0x5280, 0x849D, 0x5283,
+	0x849E, 0x5284, 0x849F, 0x5285, 0x84A0, 0x5286, 0x84A1, 0x5287,
+	0x84A2, 0x5289, 0x84A3, 0x528A, 0x84A4, 0x528B, 0x84A5, 0x528C,
+	0x84A6, 0x528D, 0x84A7, 0x528E, 0x84A8, 0x528F, 0x84A9, 0x5291,
+	0x84AA, 0x5292, 0x84AB, 0x5294, 0x84AC, 0x5295, 0x84AD, 0x5296,
+	0x84AE, 0x5297, 0x84AF, 0x5298, 0x84B0, 0x5299, 0x84B1, 0x529A,
+	0x84B2, 0x529C, 0x84B3, 0x52A4, 0x84B4, 0x52A5, 0x84B5, 0x52A6,
+	0x84B6, 0x52A7, 0x84B7, 0x52AE, 0x84B8, 0x52AF, 0x84B9, 0x52B0,
+	0x84BA, 0x52B4, 0x84BB, 0x52B5, 0x84BC, 0x52B6, 0x84BD, 0x52B7,
+	0x84BE, 0x52B8, 0x84BF, 0x52B9, 0x84C0, 0x52BA, 0x84C1, 0x52BB,
+	0x84C2, 0x52BC, 0x84C3, 0x52BD, 0x84C4, 0x52C0, 0x84C5, 0x52C1,
+	0x84C6, 0x52C2, 0x84C7, 0x52C4, 0x84C8, 0x52C5, 0x84C9, 0x52C6,
+	0x84CA, 0x52C8, 0x84CB, 0x52CA, 0x84CC, 0x52CC, 0x84CD, 0x52CD,
+	0x84CE, 0x52CE, 0x84CF, 0x52CF, 0x84D0, 0x52D1, 0x84D1, 0x52D3,
+	0x84D2, 0x52D4, 0x84D3, 0x52D5, 0x84D4, 0x52D7, 0x84D5, 0x52D9,
+	0x84D6, 0x52DA, 0x84D7, 0x52DB, 0x84D8, 0x52DC, 0x84D9, 0x52DD,
+	0x84DA, 0x52DE, 0x84DB, 0x52E0, 0x84DC, 0x52E1, 0x84DD, 0x52E2,
+	0x84DE, 0x52E3, 0x84DF, 0x52E5, 0x84E0, 0x52E6, 0x84E1, 0x52E7,
+	0x84E2, 0x52E8, 0x84E3, 0x52E9, 0x84E4, 0x52EA, 0x84E5, 0x52EB,
+	0x84E6, 0x52EC, 0x84E7, 0x52ED, 0x84E8, 0x52EE, 0x84E9, 0x52EF,
+	0x84EA, 0x52F1, 0x84EB, 0x52F2, 0x84EC, 0x52F3, 0x84ED, 0x52F4,
+	0x84EE, 0x52F5, 0x84EF, 0x52F6, 0x84F0, 0x52F7, 0x84F1, 0x52F8,
+	0x84F2, 0x52FB, 0x84F3, 0x52FC, 0x84F4, 0x52FD, 0x84F5, 0x5301,
+	0x84F6, 0x5302, 0x84F7, 0x5303, 0x84F8, 0x5304, 0x84F9, 0x5307,
+	0x84FA, 0x5309, 0x84FB, 0x530A, 0x84FC, 0x530B, 0x84FD, 0x530C,
+	0x84FE, 0x530E, 0x8540, 0x5311, 0x8541, 0x5312, 0x8542, 0x5313,
+	0x8543, 0x5314, 0x8544, 0x5318, 0x8545, 0x531B, 0x8546, 0x531C,
+	0x8547, 0x531E, 0x8548, 0x531F, 0x8549, 0x5322, 0x854A, 0x5324,
+	0x854B, 0x5325, 0x854C, 0x5327, 0x854D, 0x5328, 0x854E, 0x5329,
+	0x854F, 0x532B, 0x8550, 0x532C, 0x8551, 0x532D, 0x8552, 0x532F,
+	0x8553, 0x5330, 0x8554, 0x5331, 0x8555, 0x5332, 0x8556, 0x5333,
+	0x8557, 0x5334, 0x8558, 0x5335, 0x8559, 0x5336, 0x855A, 0x5337,
+	0x855B, 0x5338, 0x855C, 0x533C, 0x855D, 0x533D, 0x855E, 0x5340,
+	0x855F, 0x5342, 0x8560, 0x5344, 0x8561, 0x5346, 0x8562, 0x534B,
+	0x8563, 0x534C, 0x8564, 0x534D, 0x8565, 0x5350, 0x8566, 0x5354,
+	0x8567, 0x5358, 0x8568, 0x5359, 0x8569, 0x535B, 0x856A, 0x535D,
+	0x856B, 0x5365, 0x856C, 0x5368, 0x856D, 0x536A, 0x856E, 0x536C,
+	0x856F, 0x536D, 0x8570, 0x5372, 0x8571, 0x5376, 0x8572, 0x5379,
+	0x8573, 0x537B, 0x8574, 0x537C, 0x8575, 0x537D, 0x8576, 0x537E,
+	0x8577, 0x5380, 0x8578, 0x5381, 0x8579, 0x5383, 0x857A, 0x5387,
+	0x857B, 0x5388, 0x857C, 0x538A, 0x857D, 0x538E, 0x857E, 0x538F,
+	0x8580, 0x5390, 0x8581, 0x5391, 0x8582, 0x5392, 0x8583, 0x5393,
+	0x8584, 0x5394, 0x8585, 0x5396, 0x8586, 0x5397, 0x8587, 0x5399,
+	0x8588, 0x539B, 0x8589, 0x539C, 0x858A, 0x539E, 0x858B, 0x53A0,
+	0x858C, 0x53A1, 0x858D, 0x53A4, 0x858E, 0x53A7, 0x858F, 0x53AA,
+	0x8590, 0x53AB, 0x8591, 0x53AC, 0x8592, 0x53AD, 0x8593, 0x53AF,
+	0x8594, 0x53B0, 0x8595, 0x53B1, 0x8596, 0x53B2, 0x8597, 0x53B3,
+	0x8598, 0x53B4, 0x8599, 0x53B5, 0x859A, 0x53B7, 0x859B, 0x53B8,
+	0x859C, 0x53B9, 0x859D, 0x53BA, 0x859E, 0x53BC, 0x859F, 0x53BD,
+	0x85A0, 0x53BE, 0x85A1, 0x53C0, 0x85A2, 0x53C3, 0x85A3, 0x53C4,
+	0x85A4, 0x53C5, 0x85A5, 0x53C6, 0x85A6, 0x53C7, 0x85A7, 0x53CE,
+	0x85A8, 0x53CF, 0x85A9, 0x53D0, 0x85AA, 0x53D2, 0x85AB, 0x53D3,
+	0x85AC, 0x53D5, 0x85AD, 0x53DA, 0x85AE, 0x53DC, 0x85AF, 0x53DD,
+	0x85B0, 0x53DE, 0x85B1, 0x53E1, 0x85B2, 0x53E2, 0x85B3, 0x53E7,
+	0x85B4, 0x53F4, 0x85B5, 0x53FA, 0x85B6, 0x53FE, 0x85B7, 0x53FF,
+	0x85B8, 0x5400, 0x85B9, 0x5402, 0x85BA, 0x5405, 0x85BB, 0x5407,
+	0x85BC, 0x540B, 0x85BD, 0x5414, 0x85BE, 0x5418, 0x85BF, 0x5419,
+	0x85C0, 0x541A, 0x85C1, 0x541C, 0x85C2, 0x5422, 0x85C3, 0x5424,
+	0x85C4, 0x5425, 0x85C5, 0x542A, 0x85C6, 0x5430, 0x85C7, 0x5433,
+	0x85C8, 0x5436, 0x85C9, 0x5437, 0x85CA, 0x543A, 0x85CB, 0x543D,
+	0x85CC, 0x543F, 0x85CD, 0x5441, 0x85CE, 0x5442, 0x85CF, 0x5444,
+	0x85D0, 0x5445, 0x85D1, 0x5447, 0x85D2, 0x5449, 0x85D3, 0x544C,
+	0x85D4, 0x544D, 0x85D5, 0x544E, 0x85D6, 0x544F, 0x85D7, 0x5451,
+	0x85D8, 0x545A, 0x85D9, 0x545D, 0x85DA, 0x545E, 0x85DB, 0x545F,
+	0x85DC, 0x5460, 0x85DD, 0x5461, 0x85DE, 0x5463, 0x85DF, 0x5465,
+	0x85E0, 0x5467, 0x85E1, 0x5469, 0x85E2, 0x546A, 0x85E3, 0x546B,
+	0x85E4, 0x546C, 0x85E5, 0x546D, 0x85E6, 0x546E, 0x85E7, 0x546F,
+	0x85E8, 0x5470, 0x85E9, 0x5474, 0x85EA, 0x5479, 0x85EB, 0x547A,
+	0x85EC, 0x547E, 0x85ED, 0x547F, 0x85EE, 0x5481, 0x85EF, 0x5483,
+	0x85F0, 0x5485, 0x85F1, 0x5487, 0x85F2, 0x5488, 0x85F3, 0x5489,
+	0x85F4, 0x548A, 0x85F5, 0x548D, 0x85F6, 0x5491, 0x85F7, 0x5493,
+	0x85F8, 0x5497, 0x85F9, 0x5498, 0x85FA, 0x549C, 0x85FB, 0x549E,
+	0x85FC, 0x549F, 0x85FD, 0x54A0, 0x85FE, 0x54A1, 0x8640, 0x54A2,
+	0x8641, 0x54A5, 0x8642, 0x54AE, 0x8643, 0x54B0, 0x8644, 0x54B2,
+	0x8645, 0x54B5, 0x8646, 0x54B6, 0x8647, 0x54B7, 0x8648, 0x54B9,
+	0x8649, 0x54BA, 0x864A, 0x54BC, 0x864B, 0x54BE, 0x864C, 0x54C3,
+	0x864D, 0x54C5, 0x864E, 0x54CA, 0x864F, 0x54CB, 0x8650, 0x54D6,
+	0x8651, 0x54D8, 0x8652, 0x54DB, 0x8653, 0x54E0, 0x8654, 0x54E1,
+	0x8655, 0x54E2, 0x8656, 0x54E3, 0x8657, 0x54E4, 0x8658, 0x54EB,
+	0x8659, 0x54EC, 0x865A, 0x54EF, 0x865B, 0x54F0, 0x865C, 0x54F1,
+	0x865D, 0x54F4, 0x865E, 0x54F5, 0x865F, 0x54F6, 0x8660, 0x54F7,
+	0x8661, 0x54F8, 0x8662, 0x54F9, 0x8663, 0x54FB, 0x8664, 0x54FE,
+	0x8665, 0x5500, 0x8666, 0x5502, 0x8667, 0x5503, 0x8668, 0x5504,
+	0x8669, 0x5505, 0x866A, 0x5508, 0x866B, 0x550A, 0x866C, 0x550B,
+	0x866D, 0x550C, 0x866E, 0x550D, 0x866F, 0x550E, 0x8670, 0x5512,
+	0x8671, 0x5513, 0x8672, 0x5515, 0x8673, 0x5516, 0x8674, 0x5517,
+	0x8675, 0x5518, 0x8676, 0x5519, 0x8677, 0x551A, 0x8678, 0x551C,
+	0x8679, 0x551D, 0x867A, 0x551E, 0x867B, 0x551F, 0x867C, 0x5521,
+	0x867D, 0x5525, 0x867E, 0x5526, 0x8680, 0x5528, 0x8681, 0x5529,
+	0x8682, 0x552B, 0x8683, 0x552D, 0x8684, 0x5532, 0x8685, 0x5534,
+	0x8686, 0x5535, 0x8687, 0x5536, 0x8688, 0x5538, 0x8689, 0x5539,
+	0x868A, 0x553A, 0x868B, 0x553B, 0x868C, 0x553D, 0x868D, 0x5540,
+	0x868E, 0x5542, 0x868F, 0x5545, 0x8690, 0x5547, 0x8691, 0x5548,
+	0x8692, 0x554B, 0x8693, 0x554C, 0x8694, 0x554D, 0x8695, 0x554E,
+	0x8696, 0x554F, 0x8697, 0x5551, 0x8698, 0x5552, 0x8699, 0x5553,
+	0x869A, 0x5554, 0x869B, 0x5557, 0x869C, 0x5558, 0x869D, 0x5559,
+	0x869E, 0x555A, 0x869F, 0x555B, 0x86A0, 0x555D, 0x86A1, 0x555E,
+	0x86A2, 0x555F, 0x86A3, 0x5560, 0x86A4, 0x5562, 0x86A5, 0x5563,
+	0x86A6, 0x5568, 0x86A7, 0x5569, 0x86A8, 0x556B, 0x86A9, 0x556F,
+	0x86AA, 0x5570, 0x86AB, 0x5571, 0x86AC, 0x5572, 0x86AD, 0x5573,
+	0x86AE, 0x5574, 0x86AF, 0x5579, 0x86B0, 0x557A, 0x86B1, 0x557D,
+	0x86B2, 0x557F, 0x86B3, 0x5585, 0x86B4, 0x5586, 0x86B5, 0x558C,
+	0x86B6, 0x558D, 0x86B7, 0x558E, 0x86B8, 0x5590, 0x86B9, 0x5592,
+	0x86BA, 0x5593, 0x86BB, 0x5595, 0x86BC, 0x5596, 0x86BD, 0x5597,
+	0x86BE, 0x559A, 0x86BF, 0x559B, 0x86C0, 0x559E, 0x86C1, 0x55A0,
+	0x86C2, 0x55A1, 0x86C3, 0x55A2, 0x86C4, 0x55A3, 0x86C5, 0x55A4,
+	0x86C6, 0x55A5, 0x86C7, 0x55A6, 0x86C8, 0x55A8, 0x86C9, 0x55A9,
+	0x86CA, 0x55AA, 0x86CB, 0x55AB, 0x86CC, 0x55AC, 0x86CD, 0x55AD,
+	0x86CE, 0x55AE, 0x86CF, 0x55AF, 0x86D0, 0x55B0, 0x86D1, 0x55B2,
+	0x86D2, 0x55B4, 0x86D3, 0x55B6, 0x86D4, 0x55B8, 0x86D5, 0x55BA,
+	0x86D6, 0x55BC, 0x86D7, 0x55BF, 0x86D8, 0x55C0, 0x86D9, 0x55C1,
+	0x86DA, 0x55C2, 0x86DB, 0x55C3, 0x86DC, 0x55C6, 0x86DD, 0x55C7,
+	0x86DE, 0x55C8, 0x86DF, 0x55CA, 0x86E0, 0x55CB, 0x86E1, 0x55CE,
+	0x86E2, 0x55CF, 0x86E3, 0x55D0, 0x86E4, 0x55D5, 0x86E5, 0x55D7,
+	0x86E6, 0x55D8, 0x86E7, 0x55D9, 0x86E8, 0x55DA, 0x86E9, 0x55DB,
+	0x86EA, 0x55DE, 0x86EB, 0x55E0, 0x86EC, 0x55E2, 0x86ED, 0x55E7,
+	0x86EE, 0x55E9, 0x86EF, 0x55ED, 0x86F0, 0x55EE, 0x86F1, 0x55F0,
+	0x86F2, 0x55F1, 0x86F3, 0x55F4, 0x86F4, 0x55F6, 0x86F5, 0x55F8,
+	0x86F6, 0x55F9, 0x86F7, 0x55FA, 0x86F8, 0x55FB, 0x86F9, 0x55FC,
+	0x86FA, 0x55FF, 0x86FB, 0x5602, 0x86FC, 0x5603, 0x86FD, 0x5604,
+	0x86FE, 0x5605, 0x8740, 0x5606, 0x8741, 0x5607, 0x8742, 0x560A,
+	0x8743, 0x560B, 0x8744, 0x560D, 0x8745, 0x5610, 0x8746, 0x5611,
+	0x8747, 0x5612, 0x8748, 0x5613, 0x8749, 0x5614, 0x874A, 0x5615,
+	0x874B, 0x5616, 0x874C, 0x5617, 0x874D, 0x5619, 0x874E, 0x561A,
+	0x874F, 0x561C, 0x8750, 0x561D, 0x8751, 0x5620, 0x8752, 0x5621,
+	0x8753, 0x5622, 0x8754, 0x5625, 0x8755, 0x5626, 0x8756, 0x5628,
+	0x8757, 0x5629, 0x8758, 0x562A, 0x8759, 0x562B, 0x875A, 0x562E,
+	0x875B, 0x562F, 0x875C, 0x5630, 0x875D, 0x5633, 0x875E, 0x5635,
+	0x875F, 0x5637, 0x8760, 0x5638, 0x8761, 0x563A, 0x8762, 0x563C,
+	0x8763, 0x563D, 0x8764, 0x563E, 0x8765, 0x5640, 0x8766, 0x5641,
+	0x8767, 0x5642, 0x8768, 0x5643, 0x8769, 0x5644, 0x876A, 0x5645,
+	0x876B, 0x5646, 0x876C, 0x5647, 0x876D, 0x5648, 0x876E, 0x5649,
+	0x876F, 0x564A, 0x8770, 0x564B, 0x8771, 0x564F, 0x8772, 0x5650,
+	0x8773, 0x5651, 0x8774, 0x5652, 0x8775, 0x5653, 0x8776, 0x5655,
+	0x8777, 0x5656, 0x8778, 0x565A, 0x8779, 0x565B, 0x877A, 0x565D,
+	0x877B, 0x565E, 0x877C, 0x565F, 0x877D, 0x5660, 0x877E, 0x5661,
+	0x8780, 0x5663, 0x8781, 0x5665, 0x8782, 0x5666, 0x8783, 0x5667,
+	0x8784, 0x566D, 0x8785, 0x566E, 0x8786, 0x566F, 0x8787, 0x5670,
+	0x8788, 0x5672, 0x8789, 0x5673, 0x878A, 0x5674, 0x878B, 0x5675,
+	0x878C, 0x5677, 0x878D, 0x5678, 0x878E, 0x5679, 0x878F, 0x567A,
+	0x8790, 0x567D, 0x8791, 0x567E, 0x8792, 0x567F, 0x8793, 0x5680,
+	0x8794, 0x5681, 0x8795, 0x5682, 0x8796, 0x5683, 0x8797, 0x5684,
+	0x8798, 0x5687, 0x8799, 0x5688, 0x879A, 0x5689, 0x879B, 0x568A,
+	0x879C, 0x568B, 0x879D, 0x568C, 0x879E, 0x568D, 0x879F, 0x5690,
+	0x87A0, 0x5691, 0x87A1, 0x5692, 0x87A2, 0x5694, 0x87A3, 0x5695,
+	0x87A4, 0x5696, 0x87A5, 0x5697, 0x87A6, 0x5698, 0x87A7, 0x5699,
+	0x87A8, 0x569A, 0x87A9, 0x569B, 0x87AA, 0x569C, 0x87AB, 0x569D,
+	0x87AC, 0x569E, 0x87AD, 0x569F, 0x87AE, 0x56A0, 0x87AF, 0x56A1,
+	0x87B0, 0x56A2, 0x87B1, 0x56A4, 0x87B2, 0x56A5, 0x87B3, 0x56A6,
+	0x87B4, 0x56A7, 0x87B5, 0x56A8, 0x87B6, 0x56A9, 0x87B7, 0x56AA,
+	0x87B8, 0x56AB, 0x87B9, 0x56AC, 0x87BA, 0x56AD, 0x87BB, 0x56AE,
+	0x87BC, 0x56B0, 0x87BD, 0x56B1, 0x87BE, 0x56B2, 0x87BF, 0x56B3,
+	0x87C0, 0x56B4, 0x87C1, 0x56B5, 0x87C2, 0x56B6, 0x87C3, 0x56B8,
+	0x87C4, 0x56B9, 0x87C5, 0x56BA, 0x87C6, 0x56BB, 0x87C7, 0x56BD,
+	0x87C8, 0x56BE, 0x87C9, 0x56BF, 0x87CA, 0x56C0, 0x87CB, 0x56C1,
+	0x87CC, 0x56C2, 0x87CD, 0x56C3, 0x87CE, 0x56C4, 0x87CF, 0x56C5,
+	0x87D0, 0x56C6, 0x87D1, 0x56C7, 0x87D2, 0x56C8, 0x87D3, 0x56C9,
+	0x87D4, 0x56CB, 0x87D5, 0x56CC, 0x87D6, 0x56CD, 0x87D7, 0x56CE,
+	0x87D8, 0x56CF, 0x87D9, 0x56D0, 0x87DA, 0x56D1, 0x87DB, 0x56D2,
+	0x87DC, 0x56D3, 0x87DD, 0x56D5, 0x87DE, 0x56D6, 0x87DF, 0x56D8,
+	0x87E0, 0x56D9, 0x87E1, 0x56DC, 0x87E2, 0x56E3, 0x87E3, 0x56E5,
+	0x87E4, 0x56E6, 0x87E5, 0x56E7, 0x87E6, 0x56E8, 0x87E7, 0x56E9,
+	0x87E8, 0x56EA, 0x87E9, 0x56EC, 0x87EA, 0x56EE, 0x87EB, 0x56EF,
+	0x87EC, 0x56F2, 0x87ED, 0x56F3, 0x87EE, 0x56F6, 0x87EF, 0x56F7,
+	0x87F0, 0x56F8, 0x87F1, 0x56FB, 0x87F2, 0x56FC, 0x87F3, 0x5700,
+	0x87F4, 0x5701, 0x87F5, 0x5702, 0x87F6, 0x5705, 0x87F7, 0x5707,
+	0x87F8, 0x570B, 0x87F9, 0x570C, 0x87FA, 0x570D, 0x87FB, 0x570E,
+	0x87FC, 0x570F, 0x87FD, 0x5710, 0x87FE, 0x5711, 0x8840, 0x5712,
+	0x8841, 0x5713, 0x8842, 0x5714, 0x8843, 0x5715, 0x8844, 0x5716,
+	0x8845, 0x5717, 0x8846, 0x5718, 0x8847, 0x5719, 0x8848, 0x571A,
+	0x8849, 0x571B, 0x884A, 0x571D, 0x884B, 0x571E, 0x884C, 0x5720,
+	0x884D, 0x5721, 0x884E, 0x5722, 0x884F, 0x5724, 0x8850, 0x5725,
+	0x8851, 0x5726, 0x8852, 0x5727, 0x8853, 0x572B, 0x8854, 0x5731,
+	0x8855, 0x5732, 0x8856, 0x5734, 0x8857, 0x5735, 0x8858, 0x5736,
+	0x8859, 0x5737, 0x885A, 0x5738, 0x885B, 0x573C, 0x885C, 0x573D,
+	0x885D, 0x573F, 0x885E, 0x5741, 0x885F, 0x5743, 0x8860, 0x5744,
+	0x8861, 0x5745, 0x8862, 0x5746, 0x8863, 0x5748, 0x8864, 0x5749,
+	0x8865, 0x574B, 0x8866, 0x5752, 0x8867, 0x5753, 0x8868, 0x5754,
+	0x8869, 0x5755, 0x886A, 0x5756, 0x886B, 0x5758, 0x886C, 0x5759,
+	0x886D, 0x5762, 0x886E, 0x5763, 0x886F, 0x5765, 0x8870, 0x5767,
+	0x8871, 0x576C, 0x8872, 0x576E, 0x8873, 0x5770, 0x8874, 0x5771,
+	0x8875, 0x5772, 0x8876, 0x5774, 0x8877, 0x5775, 0x8878, 0x5778,
+	0x8879, 0x5779, 0x887A, 0x577A, 0x887B, 0x577D, 0x887C, 0x577E,
+	0x887D, 0x577F, 0x887E, 0x5780, 0x8880, 0x5781, 0x8881, 0x5787,
+	0x8882, 0x5788, 0x8883, 0x5789, 0x8884, 0x578A, 0x8885, 0x578D,
+	0x8886, 0x578E, 0x8887, 0x578F, 0x8888, 0x5790, 0x8889, 0x5791,
+	0x888A, 0x5794, 0x888B, 0x5795, 0x888C, 0x5796, 0x888D, 0x5797,
+	0x888E, 0x5798, 0x888F, 0x5799, 0x8890, 0x579A, 0x8891, 0x579C,
+	0x8892, 0x579D, 0x8893, 0x579E, 0x8894, 0x579F, 0x8895, 0x57A5,
+	0x8896, 0x57A8, 0x8897, 0x57AA, 0x8898, 0x57AC, 0x8899, 0x57AF,
+	0x889A, 0x57B0, 0x889B, 0x57B1, 0x889C, 0x57B3, 0x889D, 0x57B5,
+	0x889E, 0x57B6, 0x889F, 0x57B7, 0x88A0, 0x57B9, 0x88A1, 0x57BA,
+	0x88A2, 0x57BB, 0x88A3, 0x57BC, 0x88A4, 0x57BD, 0x88A5, 0x57BE,
+	0x88A6, 0x57BF, 0x88A7, 0x57C0, 0x88A8, 0x57C1, 0x88A9, 0x57C4,
+	0x88AA, 0x57C5, 0x88AB, 0x57C6, 0x88AC, 0x57C7, 0x88AD, 0x57C8,
+	0x88AE, 0x57C9, 0x88AF, 0x57CA, 0x88B0, 0x57CC, 0x88B1, 0x57CD,
+	0x88B2, 0x57D0, 0x88B3, 0x57D1, 0x88B4, 0x57D3, 0x88B5, 0x57D6,
+	0x88B6, 0x57D7, 0x88B7, 0x57DB, 0x88B8, 0x57DC, 0x88B9, 0x57DE,
+	0x88BA, 0x57E1, 0x88BB, 0x57E2, 0x88BC, 0x57E3, 0x88BD, 0x57E5,
+	0x88BE, 0x57E6, 0x88BF, 0x57E7, 0x88C0, 0x57E8, 0x88C1, 0x57E9,
+	0x88C2, 0x57EA, 0x88C3, 0x57EB, 0x88C4, 0x57EC, 0x88C5, 0x57EE,
+	0x88C6, 0x57F0, 0x88C7, 0x57F1, 0x88C8, 0x57F2, 0x88C9, 0x57F3,
+	0x88CA, 0x57F5, 0x88CB, 0x57F6, 0x88CC, 0x57F7, 0x88CD, 0x57FB,
+	0x88CE, 0x57FC, 0x88CF, 0x57FE, 0x88D0, 0x57FF, 0x88D1, 0x5801,
+	0x88D2, 0x5803, 0x88D3, 0x5804, 0x88D4, 0x5805, 0x88D5, 0x5808,
+	0x88D6, 0x5809, 0x88D7, 0x580A, 0x88D8, 0x580C, 0x88D9, 0x580E,
+	0x88DA, 0x580F, 0x88DB, 0x5810, 0x88DC, 0x5812, 0x88DD, 0x5813,
+	0x88DE, 0x5814, 0x88DF, 0x5816, 0x88E0, 0x5817, 0x88E1, 0x5818,
+	0x88E2, 0x581A, 0x88E3, 0x581B, 0x88E4, 0x581C, 0x88E5, 0x581D,
+	0x88E6, 0x581F, 0x88E7, 0x5822, 0x88E8, 0x5823, 0x88E9, 0x5825,
+	0x88EA, 0x5826, 0x88EB, 0x5827, 0x88EC, 0x5828, 0x88ED, 0x5829,
+	0x88EE, 0x582B, 0x88EF, 0x582C, 0x88F0, 0x582D, 0x88F1, 0x582E,
+	0x88F2, 0x582F, 0x88F3, 0x5831, 0x88F4, 0x5832, 0x88F5, 0x5833,
+	0x88F6, 0x5834, 0x88F7, 0x5836, 0x88F8, 0x5837, 0x88F9, 0x5838,
+	0x88FA, 0x5839, 0x88FB, 0x583A, 0x88FC, 0x583B, 0x88FD, 0x583C,
+	0x88FE, 0x583D, 0x8940, 0x583E, 0x8941, 0x583F, 0x8942, 0x5840,
+	0x8943, 0x5841, 0x8944, 0x5842, 0x8945, 0x5843, 0x8946, 0x5845,
+	0x8947, 0x5846, 0x8948, 0x5847, 0x8949, 0x5848, 0x894A, 0x5849,
+	0x894B, 0x584A, 0x894C, 0x584B, 0x894D, 0x584E, 0x894E, 0x584F,
+	0x894F, 0x5850, 0x8950, 0x5852, 0x8951, 0x5853, 0x8952, 0x5855,
+	0x8953, 0x5856, 0x8954, 0x5857, 0x8955, 0x5859, 0x8956, 0x585A,
+	0x8957, 0x585B, 0x8958, 0x585C, 0x8959, 0x585D, 0x895A, 0x585F,
+	0x895B, 0x5860, 0x895C, 0x5861, 0x895D, 0x5862, 0x895E, 0x5863,
+	0x895F, 0x5864, 0x8960, 0x5866, 0x8961, 0x5867, 0x8962, 0x5868,
+	0x8963, 0x5869, 0x8964, 0x586A, 0x8965, 0x586D, 0x8966, 0x586E,
+	0x8967, 0x586F, 0x8968, 0x5870, 0x8969, 0x5871, 0x896A, 0x5872,
+	0x896B, 0x5873, 0x896C, 0x5874, 0x896D, 0x5875, 0x896E, 0x5876,
+	0x896F, 0x5877, 0x8970, 0x5878, 0x8971, 0x5879, 0x8972, 0x587A,
+	0x8973, 0x587B, 0x8974, 0x587C, 0x8975, 0x587D, 0x8976, 0x587F,
+	0x8977, 0x5882, 0x8978, 0x5884, 0x8979, 0x5886, 0x897A, 0x5887,
+	0x897B, 0x5888, 0x897C, 0x588A, 0x897D, 0x588B, 0x897E, 0x588C,
+	0x8980, 0x588D, 0x8981, 0x588E, 0x8982, 0x588F, 0x8983, 0x5890,
+	0x8984, 0x5891, 0x8985, 0x5894, 0x8986, 0x5895, 0x8987, 0x5896,
+	0x8988, 0x5897, 0x8989, 0x5898, 0x898A, 0x589B, 0x898B, 0x589C,
+	0x898C, 0x589D, 0x898D, 0x58A0, 0x898E, 0x58A1, 0x898F, 0x58A2,
+	0x8990, 0x58A3, 0x8991, 0x58A4, 0x8992, 0x58A5, 0x8993, 0x58A6,
+	0x8994, 0x58A7, 0x8995, 0x58AA, 0x8996, 0x58AB, 0x8997, 0x58AC,
+	0x8998, 0x58AD, 0x8999, 0x58AE, 0x899A, 0x58AF, 0x899B, 0x58B0,
+	0x899C, 0x58B1, 0x899D, 0x58B2, 0x899E, 0x58B3, 0x899F, 0x58B4,
+	0x89A0, 0x58B5, 0x89A1, 0x58B6, 0x89A2, 0x58B7, 0x89A3, 0x58B8,
+	0x89A4, 0x58B9, 0x89A5, 0x58BA, 0x89A6, 0x58BB, 0x89A7, 0x58BD,
+	0x89A8, 0x58BE, 0x89A9, 0x58BF, 0x89AA, 0x58C0, 0x89AB, 0x58C2,
+	0x89AC, 0x58C3, 0x89AD, 0x58C4, 0x89AE, 0x58C6, 0x89AF, 0x58C7,
+	0x89B0, 0x58C8, 0x89B1, 0x58C9, 0x89B2, 0x58CA, 0x89B3, 0x58CB,
+	0x89B4, 0x58CC, 0x89B5, 0x58CD, 0x89B6, 0x58CE, 0x89B7, 0x58CF,
+	0x89B8, 0x58D0, 0x89B9, 0x58D2, 0x89BA, 0x58D3, 0x89BB, 0x58D4,
+	0x89BC, 0x58D6, 0x89BD, 0x58D7, 0x89BE, 0x58D8, 0x89BF, 0x58D9,
+	0x89C0, 0x58DA, 0x89C1, 0x58DB, 0x89C2, 0x58DC, 0x89C3, 0x58DD,
+	0x89C4, 0x58DE, 0x89C5, 0x58DF, 0x89C6, 0x58E0, 0x89C7, 0x58E1,
+	0x89C8, 0x58E2, 0x89C9, 0x58E3, 0x89CA, 0x58E5, 0x89CB, 0x58E6,
+	0x89CC, 0x58E7, 0x89CD, 0x58E8, 0x89CE, 0x58E9, 0x89CF, 0x58EA,
+	0x89D0, 0x58ED, 0x89D1, 0x58EF, 0x89D2, 0x58F1, 0x89D3, 0x58F2,
+	0x89D4, 0x58F4, 0x89D5, 0x58F5, 0x89D6, 0x58F7, 0x89D7, 0x58F8,
+	0x89D8, 0x58FA, 0x89D9, 0x58FB, 0x89DA, 0x58FC, 0x89DB, 0x58FD,
+	0x89DC, 0x58FE, 0x89DD, 0x58FF, 0x89DE, 0x5900, 0x89DF, 0x5901,
+	0x89E0, 0x5903, 0x89E1, 0x5905, 0x89E2, 0x5906, 0x89E3, 0x5908,
+	0x89E4, 0x5909, 0x89E5, 0x590A, 0x89E6, 0x590B, 0x89E7, 0x590C,
+	0x89E8, 0x590E, 0x89E9, 0x5910, 0x89EA, 0x5911, 0x89EB, 0x5912,
+	0x89EC, 0x5913, 0x89ED, 0x5917, 0x89EE, 0x5918, 0x89EF, 0x591B,
+	0x89F0, 0x591D, 0x89F1, 0x591E, 0x89F2, 0x5920, 0x89F3, 0x5921,
+	0x89F4, 0x5922, 0x89F5, 0x5923, 0x89F6, 0x5926, 0x89F7, 0x5928,
+	0x89F8, 0x592C, 0x89F9, 0x5930, 0x89FA, 0x5932, 0x89FB, 0x5933,
+	0x89FC, 0x5935, 0x89FD, 0x5936, 0x89FE, 0x593B, 0x8A40, 0x593D,
+	0x8A41, 0x593E, 0x8A42, 0x593F, 0x8A43, 0x5940, 0x8A44, 0x5943,
+	0x8A45, 0x5945, 0x8A46, 0x5946, 0x8A47, 0x594A, 0x8A48, 0x594C,
+	0x8A49, 0x594D, 0x8A4A, 0x5950, 0x8A4B, 0x5952, 0x8A4C, 0x5953,
+	0x8A4D, 0x5959, 0x8A4E, 0x595B, 0x8A4F, 0x595C, 0x8A50, 0x595D,
+	0x8A51, 0x595E, 0x8A52, 0x595F, 0x8A53, 0x5961, 0x8A54, 0x5963,
+	0x8A55, 0x5964, 0x8A56, 0x5966, 0x8A57, 0x5967, 0x8A58, 0x5968,
+	0x8A59, 0x5969, 0x8A5A, 0x596A, 0x8A5B, 0x596B, 0x8A5C, 0x596C,
+	0x8A5D, 0x596D, 0x8A5E, 0x596E, 0x8A5F, 0x596F, 0x8A60, 0x5970,
+	0x8A61, 0x5971, 0x8A62, 0x5972, 0x8A63, 0x5975, 0x8A64, 0x5977,
+	0x8A65, 0x597A, 0x8A66, 0x597B, 0x8A67, 0x597C, 0x8A68, 0x597E,
+	0x8A69, 0x597F, 0x8A6A, 0x5980, 0x8A6B, 0x5985, 0x8A6C, 0x5989,
+	0x8A6D, 0x598B, 0x8A6E, 0x598C, 0x8A6F, 0x598E, 0x8A70, 0x598F,
+	0x8A71, 0x5990, 0x8A72, 0x5991, 0x8A73, 0x5994, 0x8A74, 0x5995,
+	0x8A75, 0x5998, 0x8A76, 0x599A, 0x8A77, 0x599B, 0x8A78, 0x599C,
+	0x8A79, 0x599D, 0x8A7A, 0x599F, 0x8A7B, 0x59A0, 0x8A7C, 0x59A1,
+	0x8A7D, 0x59A2, 0x8A7E, 0x59A6, 0x8A80, 0x59A7, 0x8A81, 0x59AC,
+	0x8A82, 0x59AD, 0x8A83, 0x59B0, 0x8A84, 0x59B1, 0x8A85, 0x59B3,
+	0x8A86, 0x59B4, 0x8A87, 0x59B5, 0x8A88, 0x59B6, 0x8A89, 0x59B7,
+	0x8A8A, 0x59B8, 0x8A8B, 0x59BA, 0x8A8C, 0x59BC, 0x8A8D, 0x59BD,
+	0x8A8E, 0x59BF, 0x8A8F, 0x59C0, 0x8A90, 0x59C1, 0x8A91, 0x59C2,
+	0x8A92, 0x59C3, 0x8A93, 0x59C4, 0x8A94, 0x59C5, 0x8A95, 0x59C7,
+	0x8A96, 0x59C8, 0x8A97, 0x59C9, 0x8A98, 0x59CC, 0x8A99, 0x59CD,
+	0x8A9A, 0x59CE, 0x8A9B, 0x59CF, 0x8A9C, 0x59D5, 0x8A9D, 0x59D6,
+	0x8A9E, 0x59D9, 0x8A9F, 0x59DB, 0x8AA0, 0x59DE, 0x8AA1, 0x59DF,
+	0x8AA2, 0x59E0, 0x8AA3, 0x59E1, 0x8AA4, 0x59E2, 0x8AA5, 0x59E4,
+	0x8AA6, 0x59E6, 0x8AA7, 0x59E7, 0x8AA8, 0x59E9, 0x8AA9, 0x59EA,
+	0x8AAA, 0x59EB, 0x8AAB, 0x59ED, 0x8AAC, 0x59EE, 0x8AAD, 0x59EF,
+	0x8AAE, 0x59F0, 0x8AAF, 0x59F1, 0x8AB0, 0x59F2, 0x8AB1, 0x59F3,
+	0x8AB2, 0x59F4, 0x8AB3, 0x59F5, 0x8AB4, 0x59F6, 0x8AB5, 0x59F7,
+	0x8AB6, 0x59F8, 0x8AB7, 0x59FA, 0x8AB8, 0x59FC, 0x8AB9, 0x59FD,
+	0x8ABA, 0x59FE, 0x8ABB, 0x5A00, 0x8ABC, 0x5A02, 0x8ABD, 0x5A0A,
+	0x8ABE, 0x5A0B, 0x8ABF, 0x5A0D, 0x8AC0, 0x5A0E, 0x8AC1, 0x5A0F,
+	0x8AC2, 0x5A10, 0x8AC3, 0x5A12, 0x8AC4, 0x5A14, 0x8AC5, 0x5A15,
+	0x8AC6, 0x5A16, 0x8AC7, 0x5A17, 0x8AC8, 0x5A19, 0x8AC9, 0x5A1A,
+	0x8ACA, 0x5A1B, 0x8ACB, 0x5A1D, 0x8ACC, 0x5A1E, 0x8ACD, 0x5A21,
+	0x8ACE, 0x5A22, 0x8ACF, 0x5A24, 0x8AD0, 0x5A26, 0x8AD1, 0x5A27,
+	0x8AD2, 0x5A28, 0x8AD3, 0x5A2A, 0x8AD4, 0x5A2B, 0x8AD5, 0x5A2C,
+	0x8AD6, 0x5A2D, 0x8AD7, 0x5A2E, 0x8AD8, 0x5A2F, 0x8AD9, 0x5A30,
+	0x8ADA, 0x5A33, 0x8ADB, 0x5A35, 0x8ADC, 0x5A37, 0x8ADD, 0x5A38,
+	0x8ADE, 0x5A39, 0x8ADF, 0x5A3A, 0x8AE0, 0x5A3B, 0x8AE1, 0x5A3D,
+	0x8AE2, 0x5A3E, 0x8AE3, 0x5A3F, 0x8AE4, 0x5A41, 0x8AE5, 0x5A42,
+	0x8AE6, 0x5A43, 0x8AE7, 0x5A44, 0x8AE8, 0x5A45, 0x8AE9, 0x5A47,
+	0x8AEA, 0x5A48, 0x8AEB, 0x5A4B, 0x8AEC, 0x5A4C, 0x8AED, 0x5A4D,
+	0x8AEE, 0x5A4E, 0x8AEF, 0x5A4F, 0x8AF0, 0x5A50, 0x8AF1, 0x5A51,
+	0x8AF2, 0x5A52, 0x8AF3, 0x5A53, 0x8AF4, 0x5A54, 0x8AF5, 0x5A56,
+	0x8AF6, 0x5A57, 0x8AF7, 0x5A58, 0x8AF8, 0x5A59, 0x8AF9, 0x5A5B,
+	0x8AFA, 0x5A5C, 0x8AFB, 0x5A5D, 0x8AFC, 0x5A5E, 0x8AFD, 0x5A5F,
+	0x8AFE, 0x5A60, 0x8B40, 0x5A61, 0x8B41, 0x5A63, 0x8B42, 0x5A64,
+	0x8B43, 0x5A65, 0x8B44, 0x5A66, 0x8B45, 0x5A68, 0x8B46, 0x5A69,
+	0x8B47, 0x5A6B, 0x8B48, 0x5A6C, 0x8B49, 0x5A6D, 0x8B4A, 0x5A6E,
+	0x8B4B, 0x5A6F, 0x8B4C, 0x5A70, 0x8B4D, 0x5A71, 0x8B4E, 0x5A72,
+	0x8B4F, 0x5A73, 0x8B50, 0x5A78, 0x8B51, 0x5A79, 0x8B52, 0x5A7B,
+	0x8B53, 0x5A7C, 0x8B54, 0x5A7D, 0x8B55, 0x5A7E, 0x8B56, 0x5A80,
+	0x8B57, 0x5A81, 0x8B58, 0x5A82, 0x8B59, 0x5A83, 0x8B5A, 0x5A84,
+	0x8B5B, 0x5A85, 0x8B5C, 0x5A86, 0x8B5D, 0x5A87, 0x8B5E, 0x5A88,
+	0x8B5F, 0x5A89, 0x8B60, 0x5A8A, 0x8B61, 0x5A8B, 0x8B62, 0x5A8C,
+	0x8B63, 0x5A8D, 0x8B64, 0x5A8E, 0x8B65, 0x5A8F, 0x8B66, 0x5A90,
+	0x8B67, 0x5A91, 0x8B68, 0x5A93, 0x8B69, 0x5A94, 0x8B6A, 0x5A95,
+	0x8B6B, 0x5A96, 0x8B6C, 0x5A97, 0x8B6D, 0x5A98, 0x8B6E, 0x5A99,
+	0x8B6F, 0x5A9C, 0x8B70, 0x5A9D, 0x8B71, 0x5A9E, 0x8B72, 0x5A9F,
+	0x8B73, 0x5AA0, 0x8B74, 0x5AA1, 0x8B75, 0x5AA2, 0x8B76, 0x5AA3,
+	0x8B77, 0x5AA4, 0x8B78, 0x5AA5, 0x8B79, 0x5AA6, 0x8B7A, 0x5AA7,
+	0x8B7B, 0x5AA8, 0x8B7C, 0x5AA9, 0x8B7D, 0x5AAB, 0x8B7E, 0x5AAC,
+	0x8B80, 0x5AAD, 0x8B81, 0x5AAE, 0x8B82, 0x5AAF, 0x8B83, 0x5AB0,
+	0x8B84, 0x5AB1, 0x8B85, 0x5AB4, 0x8B86, 0x5AB6, 0x8B87, 0x5AB7,
+	0x8B88, 0x5AB9, 0x8B89, 0x5ABA, 0x8B8A, 0x5ABB, 0x8B8B, 0x5ABC,
+	0x8B8C, 0x5ABD, 0x8B8D, 0x5ABF, 0x8B8E, 0x5AC0, 0x8B8F, 0x5AC3,
+	0x8B90, 0x5AC4, 0x8B91, 0x5AC5, 0x8B92, 0x5AC6, 0x8B93, 0x5AC7,
+	0x8B94, 0x5AC8, 0x8B95, 0x5ACA, 0x8B96, 0x5ACB, 0x8B97, 0x5ACD,
+	0x8B98, 0x5ACE, 0x8B99, 0x5ACF, 0x8B9A, 0x5AD0, 0x8B9B, 0x5AD1,
+	0x8B9C, 0x5AD3, 0x8B9D, 0x5AD5, 0x8B9E, 0x5AD7, 0x8B9F, 0x5AD9,
+	0x8BA0, 0x5ADA, 0x8BA1, 0x5ADB, 0x8BA2, 0x5ADD, 0x8BA3, 0x5ADE,
+	0x8BA4, 0x5ADF, 0x8BA5, 0x5AE2, 0x8BA6, 0x5AE4, 0x8BA7, 0x5AE5,
+	0x8BA8, 0x5AE7, 0x8BA9, 0x5AE8, 0x8BAA, 0x5AEA, 0x8BAB, 0x5AEC,
+	0x8BAC, 0x5AED, 0x8BAD, 0x5AEE, 0x8BAE, 0x5AEF, 0x8BAF, 0x5AF0,
+	0x8BB0, 0x5AF2, 0x8BB1, 0x5AF3, 0x8BB2, 0x5AF4, 0x8BB3, 0x5AF5,
+	0x8BB4, 0x5AF6, 0x8BB5, 0x5AF7, 0x8BB6, 0x5AF8, 0x8BB7, 0x5AF9,
+	0x8BB8, 0x5AFA, 0x8BB9, 0x5AFB, 0x8BBA, 0x5AFC, 0x8BBB, 0x5AFD,
+	0x8BBC, 0x5AFE, 0x8BBD, 0x5AFF, 0x8BBE, 0x5B00, 0x8BBF, 0x5B01,
+	0x8BC0, 0x5B02, 0x8BC1, 0x5B03, 0x8BC2, 0x5B04, 0x8BC3, 0x5B05,
+	0x8BC4, 0x5B06, 0x8BC5, 0x5B07, 0x8BC6, 0x5B08, 0x8BC7, 0x5B0A,
+	0x8BC8, 0x5B0B, 0x8BC9, 0x5B0C, 0x8BCA, 0x5B0D, 0x8BCB, 0x5B0E,
+	0x8BCC, 0x5B0F, 0x8BCD, 0x5B10, 0x8BCE, 0x5B11, 0x8BCF, 0x5B12,
+	0x8BD0, 0x5B13, 0x8BD1, 0x5B14, 0x8BD2, 0x5B15, 0x8BD3, 0x5B18,
+	0x8BD4, 0x5B19, 0x8BD5, 0x5B1A, 0x8BD6, 0x5B1B, 0x8BD7, 0x5B1C,
+	0x8BD8, 0x5B1D, 0x8BD9, 0x5B1E, 0x8BDA, 0x5B1F, 0x8BDB, 0x5B20,
+	0x8BDC, 0x5B21, 0x8BDD, 0x5B22, 0x8BDE, 0x5B23, 0x8BDF, 0x5B24,
+	0x8BE0, 0x5B25, 0x8BE1, 0x5B26, 0x8BE2, 0x5B27, 0x8BE3, 0x5B28,
+	0x8BE4, 0x5B29, 0x8BE5, 0x5B2A, 0x8BE6, 0x5B2B, 0x8BE7, 0x5B2C,
+	0x8BE8, 0x5B2D, 0x8BE9, 0x5B2E, 0x8BEA, 0x5B2F, 0x8BEB, 0x5B30,
+	0x8BEC, 0x5B31, 0x8BED, 0x5B33, 0x8BEE, 0x5B35, 0x8BEF, 0x5B36,
+	0x8BF0, 0x5B38, 0x8BF1, 0x5B39, 0x8BF2, 0x5B3A, 0x8BF3, 0x5B3B,
+	0x8BF4, 0x5B3C, 0x8BF5, 0x5B3D, 0x8BF6, 0x5B3E, 0x8BF7, 0x5B3F,
+	0x8BF8, 0x5B41, 0x8BF9, 0x5B42, 0x8BFA, 0x5B43, 0x8BFB, 0x5B44,
+	0x8BFC, 0x5B45, 0x8BFD, 0x5B46, 0x8BFE, 0x5B47, 0x8C40, 0x5B48,
+	0x8C41, 0x5B49, 0x8C42, 0x5B4A, 0x8C43, 0x5B4B, 0x8C44, 0x5B4C,
+	0x8C45, 0x5B4D, 0x8C46, 0x5B4E, 0x8C47, 0x5B4F, 0x8C48, 0x5B52,
+	0x8C49, 0x5B56, 0x8C4A, 0x5B5E, 0x8C4B, 0x5B60, 0x8C4C, 0x5B61,
+	0x8C4D, 0x5B67, 0x8C4E, 0x5B68, 0x8C4F, 0x5B6B, 0x8C50, 0x5B6D,
+	0x8C51, 0x5B6E, 0x8C52, 0x5B6F, 0x8C53, 0x5B72, 0x8C54, 0x5B74,
+	0x8C55, 0x5B76, 0x8C56, 0x5B77, 0x8C57, 0x5B78, 0x8C58, 0x5B79,
+	0x8C59, 0x5B7B, 0x8C5A, 0x5B7C, 0x8C5B, 0x5B7E, 0x8C5C, 0x5B7F,
+	0x8C5D, 0x5B82, 0x8C5E, 0x5B86, 0x8C5F, 0x5B8A, 0x8C60, 0x5B8D,
+	0x8C61, 0x5B8E, 0x8C62, 0x5B90, 0x8C63, 0x5B91, 0x8C64, 0x5B92,
+	0x8C65, 0x5B94, 0x8C66, 0x5B96, 0x8C67, 0x5B9F, 0x8C68, 0x5BA7,
+	0x8C69, 0x5BA8, 0x8C6A, 0x5BA9, 0x8C6B, 0x5BAC, 0x8C6C, 0x5BAD,
+	0x8C6D, 0x5BAE, 0x8C6E, 0x5BAF, 0x8C6F, 0x5BB1, 0x8C70, 0x5BB2,
+	0x8C71, 0x5BB7, 0x8C72, 0x5BBA, 0x8C73, 0x5BBB, 0x8C74, 0x5BBC,
+	0x8C75, 0x5BC0, 0x8C76, 0x5BC1, 0x8C77, 0x5BC3, 0x8C78, 0x5BC8,
+	0x8C79, 0x5BC9, 0x8C7A, 0x5BCA, 0x8C7B, 0x5BCB, 0x8C7C, 0x5BCD,
+	0x8C7D, 0x5BCE, 0x8C7E, 0x5BCF, 0x8C80, 0x5BD1, 0x8C81, 0x5BD4,
+	0x8C82, 0x5BD5, 0x8C83, 0x5BD6, 0x8C84, 0x5BD7, 0x8C85, 0x5BD8,
+	0x8C86, 0x5BD9, 0x8C87, 0x5BDA, 0x8C88, 0x5BDB, 0x8C89, 0x5BDC,
+	0x8C8A, 0x5BE0, 0x8C8B, 0x5BE2, 0x8C8C, 0x5BE3, 0x8C8D, 0x5BE6,
+	0x8C8E, 0x5BE7, 0x8C8F, 0x5BE9, 0x8C90, 0x5BEA, 0x8C91, 0x5BEB,
+	0x8C92, 0x5BEC, 0x8C93, 0x5BED, 0x8C94, 0x5BEF, 0x8C95, 0x5BF1,
+	0x8C96, 0x5BF2, 0x8C97, 0x5BF3, 0x8C98, 0x5BF4, 0x8C99, 0x5BF5,
+	0x8C9A, 0x5BF6, 0x8C9B, 0x5BF7, 0x8C9C, 0x5BFD, 0x8C9D, 0x5BFE,
+	0x8C9E, 0x5C00, 0x8C9F, 0x5C02, 0x8CA0, 0x5C03, 0x8CA1, 0x5C05,
+	0x8CA2, 0x5C07, 0x8CA3, 0x5C08, 0x8CA4, 0x5C0B, 0x8CA5, 0x5C0C,
+	0x8CA6, 0x5C0D, 0x8CA7, 0x5C0E, 0x8CA8, 0x5C10, 0x8CA9, 0x5C12,
+	0x8CAA, 0x5C13, 0x8CAB, 0x5C17, 0x8CAC, 0x5C19, 0x8CAD, 0x5C1B,
+	0x8CAE, 0x5C1E, 0x8CAF, 0x5C1F, 0x8CB0, 0x5C20, 0x8CB1, 0x5C21,
+	0x8CB2, 0x5C23, 0x8CB3, 0x5C26, 0x8CB4, 0x5C28, 0x8CB5, 0x5C29,
+	0x8CB6, 0x5C2A, 0x8CB7, 0x5C2B, 0x8CB8, 0x5C2D, 0x8CB9, 0x5C2E,
+	0x8CBA, 0x5C2F, 0x8CBB, 0x5C30, 0x8CBC, 0x5C32, 0x8CBD, 0x5C33,
+	0x8CBE, 0x5C35, 0x8CBF, 0x5C36, 0x8CC0, 0x5C37, 0x8CC1, 0x5C43,
+	0x8CC2, 0x5C44, 0x8CC3, 0x5C46, 0x8CC4, 0x5C47, 0x8CC5, 0x5C4C,
+	0x8CC6, 0x5C4D, 0x8CC7, 0x5C52, 0x8CC8, 0x5C53, 0x8CC9, 0x5C54,
+	0x8CCA, 0x5C56, 0x8CCB, 0x5C57, 0x8CCC, 0x5C58, 0x8CCD, 0x5C5A,
+	0x8CCE, 0x5C5B, 0x8CCF, 0x5C5C, 0x8CD0, 0x5C5D, 0x8CD1, 0x5C5F,
+	0x8CD2, 0x5C62, 0x8CD3, 0x5C64, 0x8CD4, 0x5C67, 0x8CD5, 0x5C68,
+	0x8CD6, 0x5C69, 0x8CD7, 0x5C6A, 0x8CD8, 0x5C6B, 0x8CD9, 0x5C6C,
+	0x8CDA, 0x5C6D, 0x8CDB, 0x5C70, 0x8CDC, 0x5C72, 0x8CDD, 0x5C73,
+	0x8CDE, 0x5C74, 0x8CDF, 0x5C75, 0x8CE0, 0x5C76, 0x8CE1, 0x5C77,
+	0x8CE2, 0x5C78, 0x8CE3, 0x5C7B, 0x8CE4, 0x5C7C, 0x8CE5, 0x5C7D,
+	0x8CE6, 0x5C7E, 0x8CE7, 0x5C80, 0x8CE8, 0x5C83, 0x8CE9, 0x5C84,
+	0x8CEA, 0x5C85, 0x8CEB, 0x5C86, 0x8CEC, 0x5C87, 0x8CED, 0x5C89,
+	0x8CEE, 0x5C8A, 0x8CEF, 0x5C8B, 0x8CF0, 0x5C8E, 0x8CF1, 0x5C8F,
+	0x8CF2, 0x5C92, 0x8CF3, 0x5C93, 0x8CF4, 0x5C95, 0x8CF5, 0x5C9D,
+	0x8CF6, 0x5C9E, 0x8CF7, 0x5C9F, 0x8CF8, 0x5CA0, 0x8CF9, 0x5CA1,
+	0x8CFA, 0x5CA4, 0x8CFB, 0x5CA5, 0x8CFC, 0x5CA6, 0x8CFD, 0x5CA7,
+	0x8CFE, 0x5CA8, 0x8D40, 0x5CAA, 0x8D41, 0x5CAE, 0x8D42, 0x5CAF,
+	0x8D43, 0x5CB0, 0x8D44, 0x5CB2, 0x8D45, 0x5CB4, 0x8D46, 0x5CB6,
+	0x8D47, 0x5CB9, 0x8D48, 0x5CBA, 0x8D49, 0x5CBB, 0x8D4A, 0x5CBC,
+	0x8D4B, 0x5CBE, 0x8D4C, 0x5CC0, 0x8D4D, 0x5CC2, 0x8D4E, 0x5CC3,
+	0x8D4F, 0x5CC5, 0x8D50, 0x5CC6, 0x8D51, 0x5CC7, 0x8D52, 0x5CC8,
+	0x8D53, 0x5CC9, 0x8D54, 0x5CCA, 0x8D55, 0x5CCC, 0x8D56, 0x5CCD,
+	0x8D57, 0x5CCE, 0x8D58, 0x5CCF, 0x8D59, 0x5CD0, 0x8D5A, 0x5CD1,
+	0x8D5B, 0x5CD3, 0x8D5C, 0x5CD4, 0x8D5D, 0x5CD5, 0x8D5E, 0x5CD6,
+	0x8D5F, 0x5CD7, 0x8D60, 0x5CD8, 0x8D61, 0x5CDA, 0x8D62, 0x5CDB,
+	0x8D63, 0x5CDC, 0x8D64, 0x5CDD, 0x8D65, 0x5CDE, 0x8D66, 0x5CDF,
+	0x8D67, 0x5CE0, 0x8D68, 0x5CE2, 0x8D69, 0x5CE3, 0x8D6A, 0x5CE7,
+	0x8D6B, 0x5CE9, 0x8D6C, 0x5CEB, 0x8D6D, 0x5CEC, 0x8D6E, 0x5CEE,
+	0x8D6F, 0x5CEF, 0x8D70, 0x5CF1, 0x8D71, 0x5CF2, 0x8D72, 0x5CF3,
+	0x8D73, 0x5CF4, 0x8D74, 0x5CF5, 0x8D75, 0x5CF6, 0x8D76, 0x5CF7,
+	0x8D77, 0x5CF8, 0x8D78, 0x5CF9, 0x8D79, 0x5CFA, 0x8D7A, 0x5CFC,
+	0x8D7B, 0x5CFD, 0x8D7C, 0x5CFE, 0x8D7D, 0x5CFF, 0x8D7E, 0x5D00,
+	0x8D80, 0x5D01, 0x8D81, 0x5D04, 0x8D82, 0x5D05, 0x8D83, 0x5D08,
+	0x8D84, 0x5D09, 0x8D85, 0x5D0A, 0x8D86, 0x5D0B, 0x8D87, 0x5D0C,
+	0x8D88, 0x5D0D, 0x8D89, 0x5D0F, 0x8D8A, 0x5D10, 0x8D8B, 0x5D11,
+	0x8D8C, 0x5D12, 0x8D8D, 0x5D13, 0x8D8E, 0x5D15, 0x8D8F, 0x5D17,
+	0x8D90, 0x5D18, 0x8D91, 0x5D19, 0x8D92, 0x5D1A, 0x8D93, 0x5D1C,
+	0x8D94, 0x5D1D, 0x8D95, 0x5D1F, 0x8D96, 0x5D20, 0x8D97, 0x5D21,
+	0x8D98, 0x5D22, 0x8D99, 0x5D23, 0x8D9A, 0x5D25, 0x8D9B, 0x5D28,
+	0x8D9C, 0x5D2A, 0x8D9D, 0x5D2B, 0x8D9E, 0x5D2C, 0x8D9F, 0x5D2F,
+	0x8DA0, 0x5D30, 0x8DA1, 0x5D31, 0x8DA2, 0x5D32, 0x8DA3, 0x5D33,
+	0x8DA4, 0x5D35, 0x8DA5, 0x5D36, 0x8DA6, 0x5D37, 0x8DA7, 0x5D38,
+	0x8DA8, 0x5D39, 0x8DA9, 0x5D3A, 0x8DAA, 0x5D3B, 0x8DAB, 0x5D3C,
+	0x8DAC, 0x5D3F, 0x8DAD, 0x5D40, 0x8DAE, 0x5D41, 0x8DAF, 0x5D42,
+	0x8DB0, 0x5D43, 0x8DB1, 0x5D44, 0x8DB2, 0x5D45, 0x8DB3, 0x5D46,
+	0x8DB4, 0x5D48, 0x8DB5, 0x5D49, 0x8DB6, 0x5D4D, 0x8DB7, 0x5D4E,
+	0x8DB8, 0x5D4F, 0x8DB9, 0x5D50, 0x8DBA, 0x5D51, 0x8DBB, 0x5D52,
+	0x8DBC, 0x5D53, 0x8DBD, 0x5D54, 0x8DBE, 0x5D55, 0x8DBF, 0x5D56,
+	0x8DC0, 0x5D57, 0x8DC1, 0x5D59, 0x8DC2, 0x5D5A, 0x8DC3, 0x5D5C,
+	0x8DC4, 0x5D5E, 0x8DC5, 0x5D5F, 0x8DC6, 0x5D60, 0x8DC7, 0x5D61,
+	0x8DC8, 0x5D62, 0x8DC9, 0x5D63, 0x8DCA, 0x5D64, 0x8DCB, 0x5D65,
+	0x8DCC, 0x5D66, 0x8DCD, 0x5D67, 0x8DCE, 0x5D68, 0x8DCF, 0x5D6A,
+	0x8DD0, 0x5D6D, 0x8DD1, 0x5D6E, 0x8DD2, 0x5D70, 0x8DD3, 0x5D71,
+	0x8DD4, 0x5D72, 0x8DD5, 0x5D73, 0x8DD6, 0x5D75, 0x8DD7, 0x5D76,
+	0x8DD8, 0x5D77, 0x8DD9, 0x5D78, 0x8DDA, 0x5D79, 0x8DDB, 0x5D7A,
+	0x8DDC, 0x5D7B, 0x8DDD, 0x5D7C, 0x8DDE, 0x5D7D, 0x8DDF, 0x5D7E,
+	0x8DE0, 0x5D7F, 0x8DE1, 0x5D80, 0x8DE2, 0x5D81, 0x8DE3, 0x5D83,
+	0x8DE4, 0x5D84, 0x8DE5, 0x5D85, 0x8DE6, 0x5D86, 0x8DE7, 0x5D87,
+	0x8DE8, 0x5D88, 0x8DE9, 0x5D89, 0x8DEA, 0x5D8A, 0x8DEB, 0x5D8B,
+	0x8DEC, 0x5D8C, 0x8DED, 0x5D8D, 0x8DEE, 0x5D8E, 0x8DEF, 0x5D8F,
+	0x8DF0, 0x5D90, 0x8DF1, 0x5D91, 0x8DF2, 0x5D92, 0x8DF3, 0x5D93,
+	0x8DF4, 0x5D94, 0x8DF5, 0x5D95, 0x8DF6, 0x5D96, 0x8DF7, 0x5D97,
+	0x8DF8, 0x5D98, 0x8DF9, 0x5D9A, 0x8DFA, 0x5D9B, 0x8DFB, 0x5D9C,
+	0x8DFC, 0x5D9E, 0x8DFD, 0x5D9F, 0x8DFE, 0x5DA0, 0x8E40, 0x5DA1,
+	0x8E41, 0x5DA2, 0x8E42, 0x5DA3, 0x8E43, 0x5DA4, 0x8E44, 0x5DA5,
+	0x8E45, 0x5DA6, 0x8E46, 0x5DA7, 0x8E47, 0x5DA8, 0x8E48, 0x5DA9,
+	0x8E49, 0x5DAA, 0x8E4A, 0x5DAB, 0x8E4B, 0x5DAC, 0x8E4C, 0x5DAD,
+	0x8E4D, 0x5DAE, 0x8E4E, 0x5DAF, 0x8E4F, 0x5DB0, 0x8E50, 0x5DB1,
+	0x8E51, 0x5DB2, 0x8E52, 0x5DB3, 0x8E53, 0x5DB4, 0x8E54, 0x5DB5,
+	0x8E55, 0x5DB6, 0x8E56, 0x5DB8, 0x8E57, 0x5DB9, 0x8E58, 0x5DBA,
+	0x8E59, 0x5DBB, 0x8E5A, 0x5DBC, 0x8E5B, 0x5DBD, 0x8E5C, 0x5DBE,
+	0x8E5D, 0x5DBF, 0x8E5E, 0x5DC0, 0x8E5F, 0x5DC1, 0x8E60, 0x5DC2,
+	0x8E61, 0x5DC3, 0x8E62, 0x5DC4, 0x8E63, 0x5DC6, 0x8E64, 0x5DC7,
+	0x8E65, 0x5DC8, 0x8E66, 0x5DC9, 0x8E67, 0x5DCA, 0x8E68, 0x5DCB,
+	0x8E69, 0x5DCC, 0x8E6A, 0x5DCE, 0x8E6B, 0x5DCF, 0x8E6C, 0x5DD0,
+	0x8E6D, 0x5DD1, 0x8E6E, 0x5DD2, 0x8E6F, 0x5DD3, 0x8E70, 0x5DD4,
+	0x8E71, 0x5DD5, 0x8E72, 0x5DD6, 0x8E73, 0x5DD7, 0x8E74, 0x5DD8,
+	0x8E75, 0x5DD9, 0x8E76, 0x5DDA, 0x8E77, 0x5DDC, 0x8E78, 0x5DDF,
+	0x8E79, 0x5DE0, 0x8E7A, 0x5DE3, 0x8E7B, 0x5DE4, 0x8E7C, 0x5DEA,
+	0x8E7D, 0x5DEC, 0x8E7E, 0x5DED, 0x8E80, 0x5DF0, 0x8E81, 0x5DF5,
+	0x8E82, 0x5DF6, 0x8E83, 0x5DF8, 0x8E84, 0x5DF9, 0x8E85, 0x5DFA,
+	0x8E86, 0x5DFB, 0x8E87, 0x5DFC, 0x8E88, 0x5DFF, 0x8E89, 0x5E00,
+	0x8E8A, 0x5E04, 0x8E8B, 0x5E07, 0x8E8C, 0x5E09, 0x8E8D, 0x5E0A,
+	0x8E8E, 0x5E0B, 0x8E8F, 0x5E0D, 0x8E90, 0x5E0E, 0x8E91, 0x5E12,
+	0x8E92, 0x5E13, 0x8E93, 0x5E17, 0x8E94, 0x5E1E, 0x8E95, 0x5E1F,
+	0x8E96, 0x5E20, 0x8E97, 0x5E21, 0x8E98, 0x5E22, 0x8E99, 0x5E23,
+	0x8E9A, 0x5E24, 0x8E9B, 0x5E25, 0x8E9C, 0x5E28, 0x8E9D, 0x5E29,
+	0x8E9E, 0x5E2A, 0x8E9F, 0x5E2B, 0x8EA0, 0x5E2C, 0x8EA1, 0x5E2F,
+	0x8EA2, 0x5E30, 0x8EA3, 0x5E32, 0x8EA4, 0x5E33, 0x8EA5, 0x5E34,
+	0x8EA6, 0x5E35, 0x8EA7, 0x5E36, 0x8EA8, 0x5E39, 0x8EA9, 0x5E3A,
+	0x8EAA, 0x5E3E, 0x8EAB, 0x5E3F, 0x8EAC, 0x5E40, 0x8EAD, 0x5E41,
+	0x8EAE, 0x5E43, 0x8EAF, 0x5E46, 0x8EB0, 0x5E47, 0x8EB1, 0x5E48,
+	0x8EB2, 0x5E49, 0x8EB3, 0x5E4A, 0x8EB4, 0x5E4B, 0x8EB5, 0x5E4D,
+	0x8EB6, 0x5E4E, 0x8EB7, 0x5E4F, 0x8EB8, 0x5E50, 0x8EB9, 0x5E51,
+	0x8EBA, 0x5E52, 0x8EBB, 0x5E53, 0x8EBC, 0x5E56, 0x8EBD, 0x5E57,
+	0x8EBE, 0x5E58, 0x8EBF, 0x5E59, 0x8EC0, 0x5E5A, 0x8EC1, 0x5E5C,
+	0x8EC2, 0x5E5D, 0x8EC3, 0x5E5F, 0x8EC4, 0x5E60, 0x8EC5, 0x5E63,
+	0x8EC6, 0x5E64, 0x8EC7, 0x5E65, 0x8EC8, 0x5E66, 0x8EC9, 0x5E67,
+	0x8ECA, 0x5E68, 0x8ECB, 0x5E69, 0x8ECC, 0x5E6A, 0x8ECD, 0x5E6B,
+	0x8ECE, 0x5E6C, 0x8ECF, 0x5E6D, 0x8ED0, 0x5E6E, 0x8ED1, 0x5E6F,
+	0x8ED2, 0x5E70, 0x8ED3, 0x5E71, 0x8ED4, 0x5E75, 0x8ED5, 0x5E77,
+	0x8ED6, 0x5E79, 0x8ED7, 0x5E7E, 0x8ED8, 0x5E81, 0x8ED9, 0x5E82,
+	0x8EDA, 0x5E83, 0x8EDB, 0x5E85, 0x8EDC, 0x5E88, 0x8EDD, 0x5E89,
+	0x8EDE, 0x5E8C, 0x8EDF, 0x5E8D, 0x8EE0, 0x5E8E, 0x8EE1, 0x5E92,
+	0x8EE2, 0x5E98, 0x8EE3, 0x5E9B, 0x8EE4, 0x5E9D, 0x8EE5, 0x5EA1,
+	0x8EE6, 0x5EA2, 0x8EE7, 0x5EA3, 0x8EE8, 0x5EA4, 0x8EE9, 0x5EA8,
+	0x8EEA, 0x5EA9, 0x8EEB, 0x5EAA, 0x8EEC, 0x5EAB, 0x8EED, 0x5EAC,
+	0x8EEE, 0x5EAE, 0x8EEF, 0x5EAF, 0x8EF0, 0x5EB0, 0x8EF1, 0x5EB1,
+	0x8EF2, 0x5EB2, 0x8EF3, 0x5EB4, 0x8EF4, 0x5EBA, 0x8EF5, 0x5EBB,
+	0x8EF6, 0x5EBC, 0x8EF7, 0x5EBD, 0x8EF8, 0x5EBF, 0x8EF9, 0x5EC0,
+	0x8EFA, 0x5EC1, 0x8EFB, 0x5EC2, 0x8EFC, 0x5EC3, 0x8EFD, 0x5EC4,
+	0x8EFE, 0x5EC5, 0x8F40, 0x5EC6, 0x8F41, 0x5EC7, 0x8F42, 0x5EC8,
+	0x8F43, 0x5ECB, 0x8F44, 0x5ECC, 0x8F45, 0x5ECD, 0x8F46, 0x5ECE,
+	0x8F47, 0x5ECF, 0x8F48, 0x5ED0, 0x8F49, 0x5ED4, 0x8F4A, 0x5ED5,
+	0x8F4B, 0x5ED7, 0x8F4C, 0x5ED8, 0x8F4D, 0x5ED9, 0x8F4E, 0x5EDA,
+	0x8F4F, 0x5EDC, 0x8F50, 0x5EDD, 0x8F51, 0x5EDE, 0x8F52, 0x5EDF,
+	0x8F53, 0x5EE0, 0x8F54, 0x5EE1, 0x8F55, 0x5EE2, 0x8F56, 0x5EE3,
+	0x8F57, 0x5EE4, 0x8F58, 0x5EE5, 0x8F59, 0x5EE6, 0x8F5A, 0x5EE7,
+	0x8F5B, 0x5EE9, 0x8F5C, 0x5EEB, 0x8F5D, 0x5EEC, 0x8F5E, 0x5EED,
+	0x8F5F, 0x5EEE, 0x8F60, 0x5EEF, 0x8F61, 0x5EF0, 0x8F62, 0x5EF1,
+	0x8F63, 0x5EF2, 0x8F64, 0x5EF3, 0x8F65, 0x5EF5, 0x8F66, 0x5EF8,
+	0x8F67, 0x5EF9, 0x8F68, 0x5EFB, 0x8F69, 0x5EFC, 0x8F6A, 0x5EFD,
+	0x8F6B, 0x5F05, 0x8F6C, 0x5F06, 0x8F6D, 0x5F07, 0x8F6E, 0x5F09,
+	0x8F6F, 0x5F0C, 0x8F70, 0x5F0D, 0x8F71, 0x5F0E, 0x8F72, 0x5F10,
+	0x8F73, 0x5F12, 0x8F74, 0x5F14, 0x8F75, 0x5F16, 0x8F76, 0x5F19,
+	0x8F77, 0x5F1A, 0x8F78, 0x5F1C, 0x8F79, 0x5F1D, 0x8F7A, 0x5F1E,
+	0x8F7B, 0x5F21, 0x8F7C, 0x5F22, 0x8F7D, 0x5F23, 0x8F7E, 0x5F24,
+	0x8F80, 0x5F28, 0x8F81, 0x5F2B, 0x8F82, 0x5F2C, 0x8F83, 0x5F2E,
+	0x8F84, 0x5F30, 0x8F85, 0x5F32, 0x8F86, 0x5F33, 0x8F87, 0x5F34,
+	0x8F88, 0x5F35, 0x8F89, 0x5F36, 0x8F8A, 0x5F37, 0x8F8B, 0x5F38,
+	0x8F8C, 0x5F3B, 0x8F8D, 0x5F3D, 0x8F8E, 0x5F3E, 0x8F8F, 0x5F3F,
+	0x8F90, 0x5F41, 0x8F91, 0x5F42, 0x8F92, 0x5F43, 0x8F93, 0x5F44,
+	0x8F94, 0x5F45, 0x8F95, 0x5F46, 0x8F96, 0x5F47, 0x8F97, 0x5F48,
+	0x8F98, 0x5F49, 0x8F99, 0x5F4A, 0x8F9A, 0x5F4B, 0x8F9B, 0x5F4C,
+	0x8F9C, 0x5F4D, 0x8F9D, 0x5F4E, 0x8F9E, 0x5F4F, 0x8F9F, 0x5F51,
+	0x8FA0, 0x5F54, 0x8FA1, 0x5F59, 0x8FA2, 0x5F5A, 0x8FA3, 0x5F5B,
+	0x8FA4, 0x5F5C, 0x8FA5, 0x5F5E, 0x8FA6, 0x5F5F, 0x8FA7, 0x5F60,
+	0x8FA8, 0x5F63, 0x8FA9, 0x5F65, 0x8FAA, 0x5F67, 0x8FAB, 0x5F68,
+	0x8FAC, 0x5F6B, 0x8FAD, 0x5F6E, 0x8FAE, 0x5F6F, 0x8FAF, 0x5F72,
+	0x8FB0, 0x5F74, 0x8FB1, 0x5F75, 0x8FB2, 0x5F76, 0x8FB3, 0x5F78,
+	0x8FB4, 0x5F7A, 0x8FB5, 0x5F7D, 0x8FB6, 0x5F7E, 0x8FB7, 0x5F7F,
+	0x8FB8, 0x5F83, 0x8FB9, 0x5F86, 0x8FBA, 0x5F8D, 0x8FBB, 0x5F8E,
+	0x8FBC, 0x5F8F, 0x8FBD, 0x5F91, 0x8FBE, 0x5F93, 0x8FBF, 0x5F94,
+	0x8FC0, 0x5F96, 0x8FC1, 0x5F9A, 0x8FC2, 0x5F9B, 0x8FC3, 0x5F9D,
+	0x8FC4, 0x5F9E, 0x8FC5, 0x5F9F, 0x8FC6, 0x5FA0, 0x8FC7, 0x5FA2,
+	0x8FC8, 0x5FA3, 0x8FC9, 0x5FA4, 0x8FCA, 0x5FA5, 0x8FCB, 0x5FA6,
+	0x8FCC, 0x5FA7, 0x8FCD, 0x5FA9, 0x8FCE, 0x5FAB, 0x8FCF, 0x5FAC,
+	0x8FD0, 0x5FAF, 0x8FD1, 0x5FB0, 0x8FD2, 0x5FB1, 0x8FD3, 0x5FB2,
+	0x8FD4, 0x5FB3, 0x8FD5, 0x5FB4, 0x8FD6, 0x5FB6, 0x8FD7, 0x5FB8,
+	0x8FD8, 0x5FB9, 0x8FD9, 0x5FBA, 0x8FDA, 0x5FBB, 0x8FDB, 0x5FBE,
+	0x8FDC, 0x5FBF, 0x8FDD, 0x5FC0, 0x8FDE, 0x5FC1, 0x8FDF, 0x5FC2,
+	0x8FE0, 0x5FC7, 0x8FE1, 0x5FC8, 0x8FE2, 0x5FCA, 0x8FE3, 0x5FCB,
+	0x8FE4, 0x5FCE, 0x8FE5, 0x5FD3, 0x8FE6, 0x5FD4, 0x8FE7, 0x5FD5,
+	0x8FE8, 0x5FDA, 0x8FE9, 0x5FDB, 0x8FEA, 0x5FDC, 0x8FEB, 0x5FDE,
+	0x8FEC, 0x5FDF, 0x8FED, 0x5FE2, 0x8FEE, 0x5FE3, 0x8FEF, 0x5FE5,
+	0x8FF0, 0x5FE6, 0x8FF1, 0x5FE8, 0x8FF2, 0x5FE9, 0x8FF3, 0x5FEC,
+	0x8FF4, 0x5FEF, 0x8FF5, 0x5FF0, 0x8FF6, 0x5FF2, 0x8FF7, 0x5FF3,
+	0x8FF8, 0x5FF4, 0x8FF9, 0x5FF6, 0x8FFA, 0x5FF7, 0x8FFB, 0x5FF9,
+	0x8FFC, 0x5FFA, 0x8FFD, 0x5FFC, 0x8FFE, 0x6007, 0x9040, 0x6008,
+	0x9041, 0x6009, 0x9042, 0x600B, 0x9043, 0x600C, 0x9044, 0x6010,
+	0x9045, 0x6011, 0x9046, 0x6013, 0x9047, 0x6017, 0x9048, 0x6018,
+	0x9049, 0x601A, 0x904A, 0x601E, 0x904B, 0x601F, 0x904C, 0x6022,
+	0x904D, 0x6023, 0x904E, 0x6024, 0x904F, 0x602C, 0x9050, 0x602D,
+	0x9051, 0x602E, 0x9052, 0x6030, 0x9053, 0x6031, 0x9054, 0x6032,
+	0x9055, 0x6033, 0x9056, 0x6034, 0x9057, 0x6036, 0x9058, 0x6037,
+	0x9059, 0x6038, 0x905A, 0x6039, 0x905B, 0x603A, 0x905C, 0x603D,
+	0x905D, 0x603E, 0x905E, 0x6040, 0x905F, 0x6044, 0x9060, 0x6045,
+	0x9061, 0x6046, 0x9062, 0x6047, 0x9063, 0x6048, 0x9064, 0x6049,
+	0x9065, 0x604A, 0x9066, 0x604C, 0x9067, 0x604E, 0x9068, 0x604F,
+	0x9069, 0x6051, 0x906A, 0x6053, 0x906B, 0x6054, 0x906C, 0x6056,
+	0x906D, 0x6057, 0x906E, 0x6058, 0x906F, 0x605B, 0x9070, 0x605C,
+	0x9071, 0x605E, 0x9072, 0x605F, 0x9073, 0x6060, 0x9074, 0x6061,
+	0x9075, 0x6065, 0x9076, 0x6066, 0x9077, 0x606E, 0x9078, 0x6071,
+	0x9079, 0x6072, 0x907A, 0x6074, 0x907B, 0x6075, 0x907C, 0x6077,
+	0x907D, 0x607E, 0x907E, 0x6080, 0x9080, 0x6081, 0x9081, 0x6082,
+	0x9082, 0x6085, 0x9083, 0x6086, 0x9084, 0x6087, 0x9085, 0x6088,
+	0x9086, 0x608A, 0x9087, 0x608B, 0x9088, 0x608E, 0x9089, 0x608F,
+	0x908A, 0x6090, 0x908B, 0x6091, 0x908C, 0x6093, 0x908D, 0x6095,
+	0x908E, 0x6097, 0x908F, 0x6098, 0x9090, 0x6099, 0x9091, 0x609C,
+	0x9092, 0x609E, 0x9093, 0x60A1, 0x9094, 0x60A2, 0x9095, 0x60A4,
+	0x9096, 0x60A5, 0x9097, 0x60A7, 0x9098, 0x60A9, 0x9099, 0x60AA,
+	0x909A, 0x60AE, 0x909B, 0x60B0, 0x909C, 0x60B3, 0x909D, 0x60B5,
+	0x909E, 0x60B6, 0x909F, 0x60B7, 0x90A0, 0x60B9, 0x90A1, 0x60BA,
+	0x90A2, 0x60BD, 0x90A3, 0x60BE, 0x90A4, 0x60BF, 0x90A5, 0x60C0,
+	0x90A6, 0x60C1, 0x90A7, 0x60C2, 0x90A8, 0x60C3, 0x90A9, 0x60C4,
+	0x90AA, 0x60C7, 0x90AB, 0x60C8, 0x90AC, 0x60C9, 0x90AD, 0x60CC,
+	0x90AE, 0x60CD, 0x90AF, 0x60CE, 0x90B0, 0x60CF, 0x90B1, 0x60D0,
+	0x90B2, 0x60D2, 0x90B3, 0x60D3, 0x90B4, 0x60D4, 0x90B5, 0x60D6,
+	0x90B6, 0x60D7, 0x90B7, 0x60D9, 0x90B8, 0x60DB, 0x90B9, 0x60DE,
+	0x90BA, 0x60E1, 0x90BB, 0x60E2, 0x90BC, 0x60E3, 0x90BD, 0x60E4,
+	0x90BE, 0x60E5, 0x90BF, 0x60EA, 0x90C0, 0x60F1, 0x90C1, 0x60F2,
+	0x90C2, 0x60F5, 0x90C3, 0x60F7, 0x90C4, 0x60F8, 0x90C5, 0x60FB,
+	0x90C6, 0x60FC, 0x90C7, 0x60FD, 0x90C8, 0x60FE, 0x90C9, 0x60FF,
+	0x90CA, 0x6102, 0x90CB, 0x6103, 0x90CC, 0x6104, 0x90CD, 0x6105,
+	0x90CE, 0x6107, 0x90CF, 0x610A, 0x90D0, 0x610B, 0x90D1, 0x610C,
+	0x90D2, 0x6110, 0x90D3, 0x6111, 0x90D4, 0x6112, 0x90D5, 0x6113,
+	0x90D6, 0x6114, 0x90D7, 0x6116, 0x90D8, 0x6117, 0x90D9, 0x6118,
+	0x90DA, 0x6119, 0x90DB, 0x611B, 0x90DC, 0x611C, 0x90DD, 0x611D,
+	0x90DE, 0x611E, 0x90DF, 0x6121, 0x90E0, 0x6122, 0x90E1, 0x6125,
+	0x90E2, 0x6128, 0x90E3, 0x6129, 0x90E4, 0x612A, 0x90E5, 0x612C,
+	0x90E6, 0x612D, 0x90E7, 0x612E, 0x90E8, 0x612F, 0x90E9, 0x6130,
+	0x90EA, 0x6131, 0x90EB, 0x6132, 0x90EC, 0x6133, 0x90ED, 0x6134,
+	0x90EE, 0x6135, 0x90EF, 0x6136, 0x90F0, 0x6137, 0x90F1, 0x6138,
+	0x90F2, 0x6139, 0x90F3, 0x613A, 0x90F4, 0x613B, 0x90F5, 0x613C,
+	0x90F6, 0x613D, 0x90F7, 0x613E, 0x90F8, 0x6140, 0x90F9, 0x6141,
+	0x90FA, 0x6142, 0x90FB, 0x6143, 0x90FC, 0x6144, 0x90FD, 0x6145,
+	0x90FE, 0x6146, 0x9140, 0x6147, 0x9141, 0x6149, 0x9142, 0x614B,
+	0x9143, 0x614D, 0x9144, 0x614F, 0x9145, 0x6150, 0x9146, 0x6152,
+	0x9147, 0x6153, 0x9148, 0x6154, 0x9149, 0x6156, 0x914A, 0x6157,
+	0x914B, 0x6158, 0x914C, 0x6159, 0x914D, 0x615A, 0x914E, 0x615B,
+	0x914F, 0x615C, 0x9150, 0x615E, 0x9151, 0x615F, 0x9152, 0x6160,
+	0x9153, 0x6161, 0x9154, 0x6163, 0x9155, 0x6164, 0x9156, 0x6165,
+	0x9157, 0x6166, 0x9158, 0x6169, 0x9159, 0x616A, 0x915A, 0x616B,
+	0x915B, 0x616C, 0x915C, 0x616D, 0x915D, 0x616E, 0x915E, 0x616F,
+	0x915F, 0x6171, 0x9160, 0x6172, 0x9161, 0x6173, 0x9162, 0x6174,
+	0x9163, 0x6176, 0x9164, 0x6178, 0x9165, 0x6179, 0x9166, 0x617A,
+	0x9167, 0x617B, 0x9168, 0x617C, 0x9169, 0x617D, 0x916A, 0x617E,
+	0x916B, 0x617F, 0x916C, 0x6180, 0x916D, 0x6181, 0x916E, 0x6182,
+	0x916F, 0x6183, 0x9170, 0x6184, 0x9171, 0x6185, 0x9172, 0x6186,
+	0x9173, 0x6187, 0x9174, 0x6188, 0x9175, 0x6189, 0x9176, 0x618A,
+	0x9177, 0x618C, 0x9178, 0x618D, 0x9179, 0x618F, 0x917A, 0x6190,
+	0x917B, 0x6191, 0x917C, 0x6192, 0x917D, 0x6193, 0x917E, 0x6195,
+	0x9180, 0x6196, 0x9181, 0x6197, 0x9182, 0x6198, 0x9183, 0x6199,
+	0x9184, 0x619A, 0x9185, 0x619B, 0x9186, 0x619C, 0x9187, 0x619E,
+	0x9188, 0x619F, 0x9189, 0x61A0, 0x918A, 0x61A1, 0x918B, 0x61A2,
+	0x918C, 0x61A3, 0x918D, 0x61A4, 0x918E, 0x61A5, 0x918F, 0x61A6,
+	0x9190, 0x61AA, 0x9191, 0x61AB, 0x9192, 0x61AD, 0x9193, 0x61AE,
+	0x9194, 0x61AF, 0x9195, 0x61B0, 0x9196, 0x61B1, 0x9197, 0x61B2,
+	0x9198, 0x61B3, 0x9199, 0x61B4, 0x919A, 0x61B5, 0x919B, 0x61B6,
+	0x919C, 0x61B8, 0x919D, 0x61B9, 0x919E, 0x61BA, 0x919F, 0x61BB,
+	0x91A0, 0x61BC, 0x91A1, 0x61BD, 0x91A2, 0x61BF, 0x91A3, 0x61C0,
+	0x91A4, 0x61C1, 0x91A5, 0x61C3, 0x91A6, 0x61C4, 0x91A7, 0x61C5,
+	0x91A8, 0x61C6, 0x91A9, 0x61C7, 0x91AA, 0x61C9, 0x91AB, 0x61CC,
+	0x91AC, 0x61CD, 0x91AD, 0x61CE, 0x91AE, 0x61CF, 0x91AF, 0x61D0,
+	0x91B0, 0x61D3, 0x91B1, 0x61D5, 0x91B2, 0x61D6, 0x91B3, 0x61D7,
+	0x91B4, 0x61D8, 0x91B5, 0x61D9, 0x91B6, 0x61DA, 0x91B7, 0x61DB,
+	0x91B8, 0x61DC, 0x91B9, 0x61DD, 0x91BA, 0x61DE, 0x91BB, 0x61DF,
+	0x91BC, 0x61E0, 0x91BD, 0x61E1, 0x91BE, 0x61E2, 0x91BF, 0x61E3,
+	0x91C0, 0x61E4, 0x91C1, 0x61E5, 0x91C2, 0x61E7, 0x91C3, 0x61E8,
+	0x91C4, 0x61E9, 0x91C5, 0x61EA, 0x91C6, 0x61EB, 0x91C7, 0x61EC,
+	0x91C8, 0x61ED, 0x91C9, 0x61EE, 0x91CA, 0x61EF, 0x91CB, 0x61F0,
+	0x91CC, 0x61F1, 0x91CD, 0x61F2, 0x91CE, 0x61F3, 0x91CF, 0x61F4,
+	0x91D0, 0x61F6, 0x91D1, 0x61F7, 0x91D2, 0x61F8, 0x91D3, 0x61F9,
+	0x91D4, 0x61FA, 0x91D5, 0x61FB, 0x91D6, 0x61FC, 0x91D7, 0x61FD,
+	0x91D8, 0x61FE, 0x91D9, 0x6200, 0x91DA, 0x6201, 0x91DB, 0x6202,
+	0x91DC, 0x6203, 0x91DD, 0x6204, 0x91DE, 0x6205, 0x91DF, 0x6207,
+	0x91E0, 0x6209, 0x91E1, 0x6213, 0x91E2, 0x6214, 0x91E3, 0x6219,
+	0x91E4, 0x621C, 0x91E5, 0x621D, 0x91E6, 0x621E, 0x91E7, 0x6220,
+	0x91E8, 0x6223, 0x91E9, 0x6226, 0x91EA, 0x6227, 0x91EB, 0x6228,
+	0x91EC, 0x6229, 0x91ED, 0x622B, 0x91EE, 0x622D, 0x91EF, 0x622F,
+	0x91F0, 0x6230, 0x91F1, 0x6231, 0x91F2, 0x6232, 0x91F3, 0x6235,
+	0x91F4, 0x6236, 0x91F5, 0x6238, 0x91F6, 0x6239, 0x91F7, 0x623A,
+	0x91F8, 0x623B, 0x91F9, 0x623C, 0x91FA, 0x6242, 0x91FB, 0x6244,
+	0x91FC, 0x6245, 0x91FD, 0x6246, 0x91FE, 0x624A, 0x9240, 0x624F,
+	0x9241, 0x6250, 0x9242, 0x6255, 0x9243, 0x6256, 0x9244, 0x6257,
+	0x9245, 0x6259, 0x9246, 0x625A, 0x9247, 0x625C, 0x9248, 0x625D,
+	0x9249, 0x625E, 0x924A, 0x625F, 0x924B, 0x6260, 0x924C, 0x6261,
+	0x924D, 0x6262, 0x924E, 0x6264, 0x924F, 0x6265, 0x9250, 0x6268,
+	0x9251, 0x6271, 0x9252, 0x6272, 0x9253, 0x6274, 0x9254, 0x6275,
+	0x9255, 0x6277, 0x9256, 0x6278, 0x9257, 0x627A, 0x9258, 0x627B,
+	0x9259, 0x627D, 0x925A, 0x6281, 0x925B, 0x6282, 0x925C, 0x6283,
+	0x925D, 0x6285, 0x925E, 0x6286, 0x925F, 0x6287, 0x9260, 0x6288,
+	0x9261, 0x628B, 0x9262, 0x628C, 0x9263, 0x628D, 0x9264, 0x628E,
+	0x9265, 0x628F, 0x9266, 0x6290, 0x9267, 0x6294, 0x9268, 0x6299,
+	0x9269, 0x629C, 0x926A, 0x629D, 0x926B, 0x629E, 0x926C, 0x62A3,
+	0x926D, 0x62A6, 0x926E, 0x62A7, 0x926F, 0x62A9, 0x9270, 0x62AA,
+	0x9271, 0x62AD, 0x9272, 0x62AE, 0x9273, 0x62AF, 0x9274, 0x62B0,
+	0x9275, 0x62B2, 0x9276, 0x62B3, 0x9277, 0x62B4, 0x9278, 0x62B6,
+	0x9279, 0x62B7, 0x927A, 0x62B8, 0x927B, 0x62BA, 0x927C, 0x62BE,
+	0x927D, 0x62C0, 0x927E, 0x62C1, 0x9280, 0x62C3, 0x9281, 0x62CB,
+	0x9282, 0x62CF, 0x9283, 0x62D1, 0x9284, 0x62D5, 0x9285, 0x62DD,
+	0x9286, 0x62DE, 0x9287, 0x62E0, 0x9288, 0x62E1, 0x9289, 0x62E4,
+	0x928A, 0x62EA, 0x928B, 0x62EB, 0x928C, 0x62F0, 0x928D, 0x62F2,
+	0x928E, 0x62F5, 0x928F, 0x62F8, 0x9290, 0x62F9, 0x9291, 0x62FA,
+	0x9292, 0x62FB, 0x9293, 0x6300, 0x9294, 0x6303, 0x9295, 0x6304,
+	0x9296, 0x6305, 0x9297, 0x6306, 0x9298, 0x630A, 0x9299, 0x630B,
+	0x929A, 0x630C, 0x929B, 0x630D, 0x929C, 0x630F, 0x929D, 0x6310,
+	0x929E, 0x6312, 0x929F, 0x6313, 0x92A0, 0x6314, 0x92A1, 0x6315,
+	0x92A2, 0x6317, 0x92A3, 0x6318, 0x92A4, 0x6319, 0x92A5, 0x631C,
+	0x92A6, 0x6326, 0x92A7, 0x6327, 0x92A8, 0x6329, 0x92A9, 0x632C,
+	0x92AA, 0x632D, 0x92AB, 0x632E, 0x92AC, 0x6330, 0x92AD, 0x6331,
+	0x92AE, 0x6333, 0x92AF, 0x6334, 0x92B0, 0x6335, 0x92B1, 0x6336,
+	0x92B2, 0x6337, 0x92B3, 0x6338, 0x92B4, 0x633B, 0x92B5, 0x633C,
+	0x92B6, 0x633E, 0x92B7, 0x633F, 0x92B8, 0x6340, 0x92B9, 0x6341,
+	0x92BA, 0x6344, 0x92BB, 0x6347, 0x92BC, 0x6348, 0x92BD, 0x634A,
+	0x92BE, 0x6351, 0x92BF, 0x6352, 0x92C0, 0x6353, 0x92C1, 0x6354,
+	0x92C2, 0x6356, 0x92C3, 0x6357, 0x92C4, 0x6358, 0x92C5, 0x6359,
+	0x92C6, 0x635A, 0x92C7, 0x635B, 0x92C8, 0x635C, 0x92C9, 0x635D,
+	0x92CA, 0x6360, 0x92CB, 0x6364, 0x92CC, 0x6365, 0x92CD, 0x6366,
+	0x92CE, 0x6368, 0x92CF, 0x636A, 0x92D0, 0x636B, 0x92D1, 0x636C,
+	0x92D2, 0x636F, 0x92D3, 0x6370, 0x92D4, 0x6372, 0x92D5, 0x6373,
+	0x92D6, 0x6374, 0x92D7, 0x6375, 0x92D8, 0x6378, 0x92D9, 0x6379,
+	0x92DA, 0x637C, 0x92DB, 0x637D, 0x92DC, 0x637E, 0x92DD, 0x637F,
+	0x92DE, 0x6381, 0x92DF, 0x6383, 0x92E0, 0x6384, 0x92E1, 0x6385,
+	0x92E2, 0x6386, 0x92E3, 0x638B, 0x92E4, 0x638D, 0x92E5, 0x6391,
+	0x92E6, 0x6393, 0x92E7, 0x6394, 0x92E8, 0x6395, 0x92E9, 0x6397,
+	0x92EA, 0x6399, 0x92EB, 0x639A, 0x92EC, 0x639B, 0x92ED, 0x639C,
+	0x92EE, 0x639D, 0x92EF, 0x639E, 0x92F0, 0x639F, 0x92F1, 0x63A1,
+	0x92F2, 0x63A4, 0x92F3, 0x63A6, 0x92F4, 0x63AB, 0x92F5, 0x63AF,
+	0x92F6, 0x63B1, 0x92F7, 0x63B2, 0x92F8, 0x63B5, 0x92F9, 0x63B6,
+	0x92FA, 0x63B9, 0x92FB, 0x63BB, 0x92FC, 0x63BD, 0x92FD, 0x63BF,
+	0x92FE, 0x63C0, 0x9340, 0x63C1, 0x9341, 0x63C2, 0x9342, 0x63C3,
+	0x9343, 0x63C5, 0x9344, 0x63C7, 0x9345, 0x63C8, 0x9346, 0x63CA,
+	0x9347, 0x63CB, 0x9348, 0x63CC, 0x9349, 0x63D1, 0x934A, 0x63D3,
+	0x934B, 0x63D4, 0x934C, 0x63D5, 0x934D, 0x63D7, 0x934E, 0x63D8,
+	0x934F, 0x63D9, 0x9350, 0x63DA, 0x9351, 0x63DB, 0x9352, 0x63DC,
+	0x9353, 0x63DD, 0x9354, 0x63DF, 0x9355, 0x63E2, 0x9356, 0x63E4,
+	0x9357, 0x63E5, 0x9358, 0x63E6, 0x9359, 0x63E7, 0x935A, 0x63E8,
+	0x935B, 0x63EB, 0x935C, 0x63EC, 0x935D, 0x63EE, 0x935E, 0x63EF,
+	0x935F, 0x63F0, 0x9360, 0x63F1, 0x9361, 0x63F3, 0x9362, 0x63F5,
+	0x9363, 0x63F7, 0x9364, 0x63F9, 0x9365, 0x63FA, 0x9366, 0x63FB,
+	0x9367, 0x63FC, 0x9368, 0x63FE, 0x9369, 0x6403, 0x936A, 0x6404,
+	0x936B, 0x6406, 0x936C, 0x6407, 0x936D, 0x6408, 0x936E, 0x6409,
+	0x936F, 0x640A, 0x9370, 0x640D, 0x9371, 0x640E, 0x9372, 0x6411,
+	0x9373, 0x6412, 0x9374, 0x6415, 0x9375, 0x6416, 0x9376, 0x6417,
+	0x9377, 0x6418, 0x9378, 0x6419, 0x9379, 0x641A, 0x937A, 0x641D,
+	0x937B, 0x641F, 0x937C, 0x6422, 0x937D, 0x6423, 0x937E, 0x6424,
+	0x9380, 0x6425, 0x9381, 0x6427, 0x9382, 0x6428, 0x9383, 0x6429,
+	0x9384, 0x642B, 0x9385, 0x642E, 0x9386, 0x642F, 0x9387, 0x6430,
+	0x9388, 0x6431, 0x9389, 0x6432, 0x938A, 0x6433, 0x938B, 0x6435,
+	0x938C, 0x6436, 0x938D, 0x6437, 0x938E, 0x6438, 0x938F, 0x6439,
+	0x9390, 0x643B, 0x9391, 0x643C, 0x9392, 0x643E, 0x9393, 0x6440,
+	0x9394, 0x6442, 0x9395, 0x6443, 0x9396, 0x6449, 0x9397, 0x644B,
+	0x9398, 0x644C, 0x9399, 0x644D, 0x939A, 0x644E, 0x939B, 0x644F,
+	0x939C, 0x6450, 0x939D, 0x6451, 0x939E, 0x6453, 0x939F, 0x6455,
+	0x93A0, 0x6456, 0x93A1, 0x6457, 0x93A2, 0x6459, 0x93A3, 0x645A,
+	0x93A4, 0x645B, 0x93A5, 0x645C, 0x93A6, 0x645D, 0x93A7, 0x645F,
+	0x93A8, 0x6460, 0x93A9, 0x6461, 0x93AA, 0x6462, 0x93AB, 0x6463,
+	0x93AC, 0x6464, 0x93AD, 0x6465, 0x93AE, 0x6466, 0x93AF, 0x6468,
+	0x93B0, 0x646A, 0x93B1, 0x646B, 0x93B2, 0x646C, 0x93B3, 0x646E,
+	0x93B4, 0x646F, 0x93B5, 0x6470, 0x93B6, 0x6471, 0x93B7, 0x6472,
+	0x93B8, 0x6473, 0x93B9, 0x6474, 0x93BA, 0x6475, 0x93BB, 0x6476,
+	0x93BC, 0x6477, 0x93BD, 0x647B, 0x93BE, 0x647C, 0x93BF, 0x647D,
+	0x93C0, 0x647E, 0x93C1, 0x647F, 0x93C2, 0x6480, 0x93C3, 0x6481,
+	0x93C4, 0x6483, 0x93C5, 0x6486, 0x93C6, 0x6488, 0x93C7, 0x6489,
+	0x93C8, 0x648A, 0x93C9, 0x648B, 0x93CA, 0x648C, 0x93CB, 0x648D,
+	0x93CC, 0x648E, 0x93CD, 0x648F, 0x93CE, 0x6490, 0x93CF, 0x6493,
+	0x93D0, 0x6494, 0x93D1, 0x6497, 0x93D2, 0x6498, 0x93D3, 0x649A,
+	0x93D4, 0x649B, 0x93D5, 0x649C, 0x93D6, 0x649D, 0x93D7, 0x649F,
+	0x93D8, 0x64A0, 0x93D9, 0x64A1, 0x93DA, 0x64A2, 0x93DB, 0x64A3,
+	0x93DC, 0x64A5, 0x93DD, 0x64A6, 0x93DE, 0x64A7, 0x93DF, 0x64A8,
+	0x93E0, 0x64AA, 0x93E1, 0x64AB, 0x93E2, 0x64AF, 0x93E3, 0x64B1,
+	0x93E4, 0x64B2, 0x93E5, 0x64B3, 0x93E6, 0x64B4, 0x93E7, 0x64B6,
+	0x93E8, 0x64B9, 0x93E9, 0x64BB, 0x93EA, 0x64BD, 0x93EB, 0x64BE,
+	0x93EC, 0x64BF, 0x93ED, 0x64C1, 0x93EE, 0x64C3, 0x93EF, 0x64C4,
+	0x93F0, 0x64C6, 0x93F1, 0x64C7, 0x93F2, 0x64C8, 0x93F3, 0x64C9,
+	0x93F4, 0x64CA, 0x93F5, 0x64CB, 0x93F6, 0x64CC, 0x93F7, 0x64CF,
+	0x93F8, 0x64D1, 0x93F9, 0x64D3, 0x93FA, 0x64D4, 0x93FB, 0x64D5,
+	0x93FC, 0x64D6, 0x93FD, 0x64D9, 0x93FE, 0x64DA, 0x9440, 0x64DB,
+	0x9441, 0x64DC, 0x9442, 0x64DD, 0x9443, 0x64DF, 0x9444, 0x64E0,
+	0x9445, 0x64E1, 0x9446, 0x64E3, 0x9447, 0x64E5, 0x9448, 0x64E7,
+	0x9449, 0x64E8, 0x944A, 0x64E9, 0x944B, 0x64EA, 0x944C, 0x64EB,
+	0x944D, 0x64EC, 0x944E, 0x64ED, 0x944F, 0x64EE, 0x9450, 0x64EF,
+	0x9451, 0x64F0, 0x9452, 0x64F1, 0x9453, 0x64F2, 0x9454, 0x64F3,
+	0x9455, 0x64F4, 0x9456, 0x64F5, 0x9457, 0x64F6, 0x9458, 0x64F7,
+	0x9459, 0x64F8, 0x945A, 0x64F9, 0x945B, 0x64FA, 0x945C, 0x64FB,
+	0x945D, 0x64FC, 0x945E, 0x64FD, 0x945F, 0x64FE, 0x9460, 0x64FF,
+	0x9461, 0x6501, 0x9462, 0x6502, 0x9463, 0x6503, 0x9464, 0x6504,
+	0x9465, 0x6505, 0x9466, 0x6506, 0x9467, 0x6507, 0x9468, 0x6508,
+	0x9469, 0x650A, 0x946A, 0x650B, 0x946B, 0x650C, 0x946C, 0x650D,
+	0x946D, 0x650E, 0x946E, 0x650F, 0x946F, 0x6510, 0x9470, 0x6511,
+	0x9471, 0x6513, 0x9472, 0x6514, 0x9473, 0x6515, 0x9474, 0x6516,
+	0x9475, 0x6517, 0x9476, 0x6519, 0x9477, 0x651A, 0x9478, 0x651B,
+	0x9479, 0x651C, 0x947A, 0x651D, 0x947B, 0x651E, 0x947C, 0x651F,
+	0x947D, 0x6520, 0x947E, 0x6521, 0x9480, 0x6522, 0x9481, 0x6523,
+	0x9482, 0x6524, 0x9483, 0x6526, 0x9484, 0x6527, 0x9485, 0x6528,
+	0x9486, 0x6529, 0x9487, 0x652A, 0x9488, 0x652C, 0x9489, 0x652D,
+	0x948A, 0x6530, 0x948B, 0x6531, 0x948C, 0x6532, 0x948D, 0x6533,
+	0x948E, 0x6537, 0x948F, 0x653A, 0x9490, 0x653C, 0x9491, 0x653D,
+	0x9492, 0x6540, 0x9493, 0x6541, 0x9494, 0x6542, 0x9495, 0x6543,
+	0x9496, 0x6544, 0x9497, 0x6546, 0x9498, 0x6547, 0x9499, 0x654A,
+	0x949A, 0x654B, 0x949B, 0x654D, 0x949C, 0x654E, 0x949D, 0x6550,
+	0x949E, 0x6552, 0x949F, 0x6553, 0x94A0, 0x6554, 0x94A1, 0x6557,
+	0x94A2, 0x6558, 0x94A3, 0x655A, 0x94A4, 0x655C, 0x94A5, 0x655F,
+	0x94A6, 0x6560, 0x94A7, 0x6561, 0x94A8, 0x6564, 0x94A9, 0x6565,
+	0x94AA, 0x6567, 0x94AB, 0x6568, 0x94AC, 0x6569, 0x94AD, 0x656A,
+	0x94AE, 0x656D, 0x94AF, 0x656E, 0x94B0, 0x656F, 0x94B1, 0x6571,
+	0x94B2, 0x6573, 0x94B3, 0x6575, 0x94B4, 0x6576, 0x94B5, 0x6578,
+	0x94B6, 0x6579, 0x94B7, 0x657A, 0x94B8, 0x657B, 0x94B9, 0x657C,
+	0x94BA, 0x657D, 0x94BB, 0x657E, 0x94BC, 0x657F, 0x94BD, 0x6580,
+	0x94BE, 0x6581, 0x94BF, 0x6582, 0x94C0, 0x6583, 0x94C1, 0x6584,
+	0x94C2, 0x6585, 0x94C3, 0x6586, 0x94C4, 0x6588, 0x94C5, 0x6589,
+	0x94C6, 0x658A, 0x94C7, 0x658D, 0x94C8, 0x658E, 0x94C9, 0x658F,
+	0x94CA, 0x6592, 0x94CB, 0x6594, 0x94CC, 0x6595, 0x94CD, 0x6596,
+	0x94CE, 0x6598, 0x94CF, 0x659A, 0x94D0, 0x659D, 0x94D1, 0x659E,
+	0x94D2, 0x65A0, 0x94D3, 0x65A2, 0x94D4, 0x65A3, 0x94D5, 0x65A6,
+	0x94D6, 0x65A8, 0x94D7, 0x65AA, 0x94D8, 0x65AC, 0x94D9, 0x65AE,
+	0x94DA, 0x65B1, 0x94DB, 0x65B2, 0x94DC, 0x65B3, 0x94DD, 0x65B4,
+	0x94DE, 0x65B5, 0x94DF, 0x65B6, 0x94E0, 0x65B7, 0x94E1, 0x65B8,
+	0x94E2, 0x65BA, 0x94E3, 0x65BB, 0x94E4, 0x65BE, 0x94E5, 0x65BF,
+	0x94E6, 0x65C0, 0x94E7, 0x65C2, 0x94E8, 0x65C7, 0x94E9, 0x65C8,
+	0x94EA, 0x65C9, 0x94EB, 0x65CA, 0x94EC, 0x65CD, 0x94ED, 0x65D0,
+	0x94EE, 0x65D1, 0x94EF, 0x65D3, 0x94F0, 0x65D4, 0x94F1, 0x65D5,
+	0x94F2, 0x65D8, 0x94F3, 0x65D9, 0x94F4, 0x65DA, 0x94F5, 0x65DB,
+	0x94F6, 0x65DC, 0x94F7, 0x65DD, 0x94F8, 0x65DE, 0x94F9, 0x65DF,
+	0x94FA, 0x65E1, 0x94FB, 0x65E3, 0x94FC, 0x65E4, 0x94FD, 0x65EA,
+	0x94FE, 0x65EB, 0x9540, 0x65F2, 0x9541, 0x65F3, 0x9542, 0x65F4,
+	0x9543, 0x65F5, 0x9544, 0x65F8, 0x9545, 0x65F9, 0x9546, 0x65FB,
+	0x9547, 0x65FC, 0x9548, 0x65FD, 0x9549, 0x65FE, 0x954A, 0x65FF,
+	0x954B, 0x6601, 0x954C, 0x6604, 0x954D, 0x6605, 0x954E, 0x6607,
+	0x954F, 0x6608, 0x9550, 0x6609, 0x9551, 0x660B, 0x9552, 0x660D,
+	0x9553, 0x6610, 0x9554, 0x6611, 0x9555, 0x6612, 0x9556, 0x6616,
+	0x9557, 0x6617, 0x9558, 0x6618, 0x9559, 0x661A, 0x955A, 0x661B,
+	0x955B, 0x661C, 0x955C, 0x661E, 0x955D, 0x6621, 0x955E, 0x6622,
+	0x955F, 0x6623, 0x9560, 0x6624, 0x9561, 0x6626, 0x9562, 0x6629,
+	0x9563, 0x662A, 0x9564, 0x662B, 0x9565, 0x662C, 0x9566, 0x662E,
+	0x9567, 0x6630, 0x9568, 0x6632, 0x9569, 0x6633, 0x956A, 0x6637,
+	0x956B, 0x6638, 0x956C, 0x6639, 0x956D, 0x663A, 0x956E, 0x663B,
+	0x956F, 0x663D, 0x9570, 0x663F, 0x9571, 0x6640, 0x9572, 0x6642,
+	0x9573, 0x6644, 0x9574, 0x6645, 0x9575, 0x6646, 0x9576, 0x6647,
+	0x9577, 0x6648, 0x9578, 0x6649, 0x9579, 0x664A, 0x957A, 0x664D,
+	0x957B, 0x664E, 0x957C, 0x6650, 0x957D, 0x6651, 0x957E, 0x6658,
+	0x9580, 0x6659, 0x9581, 0x665B, 0x9582, 0x665C, 0x9583, 0x665D,
+	0x9584, 0x665E, 0x9585, 0x6660, 0x9586, 0x6662, 0x9587, 0x6663,
+	0x9588, 0x6665, 0x9589, 0x6667, 0x958A, 0x6669, 0x958B, 0x666A,
+	0x958C, 0x666B, 0x958D, 0x666C, 0x958E, 0x666D, 0x958F, 0x6671,
+	0x9590, 0x6672, 0x9591, 0x6673, 0x9592, 0x6675, 0x9593, 0x6678,
+	0x9594, 0x6679, 0x9595, 0x667B, 0x9596, 0x667C, 0x9597, 0x667D,
+	0x9598, 0x667F, 0x9599, 0x6680, 0x959A, 0x6681, 0x959B, 0x6683,
+	0x959C, 0x6685, 0x959D, 0x6686, 0x959E, 0x6688, 0x959F, 0x6689,
+	0x95A0, 0x668A, 0x95A1, 0x668B, 0x95A2, 0x668D, 0x95A3, 0x668E,
+	0x95A4, 0x668F, 0x95A5, 0x6690, 0x95A6, 0x6692, 0x95A7, 0x6693,
+	0x95A8, 0x6694, 0x95A9, 0x6695, 0x95AA, 0x6698, 0x95AB, 0x6699,
+	0x95AC, 0x669A, 0x95AD, 0x669B, 0x95AE, 0x669C, 0x95AF, 0x669E,
+	0x95B0, 0x669F, 0x95B1, 0x66A0, 0x95B2, 0x66A1, 0x95B3, 0x66A2,
+	0x95B4, 0x66A3, 0x95B5, 0x66A4, 0x95B6, 0x66A5, 0x95B7, 0x66A6,
+	0x95B8, 0x66A9, 0x95B9, 0x66AA, 0x95BA, 0x66AB, 0x95BB, 0x66AC,
+	0x95BC, 0x66AD, 0x95BD, 0x66AF, 0x95BE, 0x66B0, 0x95BF, 0x66B1,
+	0x95C0, 0x66B2, 0x95C1, 0x66B3, 0x95C2, 0x66B5, 0x95C3, 0x66B6,
+	0x95C4, 0x66B7, 0x95C5, 0x66B8, 0x95C6, 0x66BA, 0x95C7, 0x66BB,
+	0x95C8, 0x66BC, 0x95C9, 0x66BD, 0x95CA, 0x66BF, 0x95CB, 0x66C0,
+	0x95CC, 0x66C1, 0x95CD, 0x66C2, 0x95CE, 0x66C3, 0x95CF, 0x66C4,
+	0x95D0, 0x66C5, 0x95D1, 0x66C6, 0x95D2, 0x66C7, 0x95D3, 0x66C8,
+	0x95D4, 0x66C9, 0x95D5, 0x66CA, 0x95D6, 0x66CB, 0x95D7, 0x66CC,
+	0x95D8, 0x66CD, 0x95D9, 0x66CE, 0x95DA, 0x66CF, 0x95DB, 0x66D0,
+	0x95DC, 0x66D1, 0x95DD, 0x66D2, 0x95DE, 0x66D3, 0x95DF, 0x66D4,
+	0x95E0, 0x66D5, 0x95E1, 0x66D6, 0x95E2, 0x66D7, 0x95E3, 0x66D8,
+	0x95E4, 0x66DA, 0x95E5, 0x66DE, 0x95E6, 0x66DF, 0x95E7, 0x66E0,
+	0x95E8, 0x66E1, 0x95E9, 0x66E2, 0x95EA, 0x66E3, 0x95EB, 0x66E4,
+	0x95EC, 0x66E5, 0x95ED, 0x66E7, 0x95EE, 0x66E8, 0x95EF, 0x66EA,
+	0x95F0, 0x66EB, 0x95F1, 0x66EC, 0x95F2, 0x66ED, 0x95F3, 0x66EE,
+	0x95F4, 0x66EF, 0x95F5, 0x66F1, 0x95F6, 0x66F5, 0x95F7, 0x66F6,
+	0x95F8, 0x66F8, 0x95F9, 0x66FA, 0x95FA, 0x66FB, 0x95FB, 0x66FD,
+	0x95FC, 0x6701, 0x95FD, 0x6702, 0x95FE, 0x6703, 0x9640, 0x6704,
+	0x9641, 0x6705, 0x9642, 0x6706, 0x9643, 0x6707, 0x9644, 0x670C,
+	0x9645, 0x670E, 0x9646, 0x670F, 0x9647, 0x6711, 0x9648, 0x6712,
+	0x9649, 0x6713, 0x964A, 0x6716, 0x964B, 0x6718, 0x964C, 0x6719,
+	0x964D, 0x671A, 0x964E, 0x671C, 0x964F, 0x671E, 0x9650, 0x6720,
+	0x9651, 0x6721, 0x9652, 0x6722, 0x9653, 0x6723, 0x9654, 0x6724,
+	0x9655, 0x6725, 0x9656, 0x6727, 0x9657, 0x6729, 0x9658, 0x672E,
+	0x9659, 0x6730, 0x965A, 0x6732, 0x965B, 0x6733, 0x965C, 0x6736,
+	0x965D, 0x6737, 0x965E, 0x6738, 0x965F, 0x6739, 0x9660, 0x673B,
+	0x9661, 0x673C, 0x9662, 0x673E, 0x9663, 0x673F, 0x9664, 0x6741,
+	0x9665, 0x6744, 0x9666, 0x6745, 0x9667, 0x6747, 0x9668, 0x674A,
+	0x9669, 0x674B, 0x966A, 0x674D, 0x966B, 0x6752, 0x966C, 0x6754,
+	0x966D, 0x6755, 0x966E, 0x6757, 0x966F, 0x6758, 0x9670, 0x6759,
+	0x9671, 0x675A, 0x9672, 0x675B, 0x9673, 0x675D, 0x9674, 0x6762,
+	0x9675, 0x6763, 0x9676, 0x6764, 0x9677, 0x6766, 0x9678, 0x6767,
+	0x9679, 0x676B, 0x967A, 0x676C, 0x967B, 0x676E, 0x967C, 0x6771,
+	0x967D, 0x6774, 0x967E, 0x6776, 0x9680, 0x6778, 0x9681, 0x6779,
+	0x9682, 0x677A, 0x9683, 0x677B, 0x9684, 0x677D, 0x9685, 0x6780,
+	0x9686, 0x6782, 0x9687, 0x6783, 0x9688, 0x6785, 0x9689, 0x6786,
+	0x968A, 0x6788, 0x968B, 0x678A, 0x968C, 0x678C, 0x968D, 0x678D,
+	0x968E, 0x678E, 0x968F, 0x678F, 0x9690, 0x6791, 0x9691, 0x6792,
+	0x9692, 0x6793, 0x9693, 0x6794, 0x9694, 0x6796, 0x9695, 0x6799,
+	0x9696, 0x679B, 0x9697, 0x679F, 0x9698, 0x67A0, 0x9699, 0x67A1,
+	0x969A, 0x67A4, 0x969B, 0x67A6, 0x969C, 0x67A9, 0x969D, 0x67AC,
+	0x969E, 0x67AE, 0x969F, 0x67B1, 0x96A0, 0x67B2, 0x96A1, 0x67B4,
+	0x96A2, 0x67B9, 0x96A3, 0x67BA, 0x96A4, 0x67BB, 0x96A5, 0x67BC,
+	0x96A6, 0x67BD, 0x96A7, 0x67BE, 0x96A8, 0x67BF, 0x96A9, 0x67C0,
+	0x96AA, 0x67C2, 0x96AB, 0x67C5, 0x96AC, 0x67C6, 0x96AD, 0x67C7,
+	0x96AE, 0x67C8, 0x96AF, 0x67C9, 0x96B0, 0x67CA, 0x96B1, 0x67CB,
+	0x96B2, 0x67CC, 0x96B3, 0x67CD, 0x96B4, 0x67CE, 0x96B5, 0x67D5,
+	0x96B6, 0x67D6, 0x96B7, 0x67D7, 0x96B8, 0x67DB, 0x96B9, 0x67DF,
+	0x96BA, 0x67E1, 0x96BB, 0x67E3, 0x96BC, 0x67E4, 0x96BD, 0x67E6,
+	0x96BE, 0x67E7, 0x96BF, 0x67E8, 0x96C0, 0x67EA, 0x96C1, 0x67EB,
+	0x96C2, 0x67ED, 0x96C3, 0x67EE, 0x96C4, 0x67F2, 0x96C5, 0x67F5,
+	0x96C6, 0x67F6, 0x96C7, 0x67F7, 0x96C8, 0x67F8, 0x96C9, 0x67F9,
+	0x96CA, 0x67FA, 0x96CB, 0x67FB, 0x96CC, 0x67FC, 0x96CD, 0x67FE,
+	0x96CE, 0x6801, 0x96CF, 0x6802, 0x96D0, 0x6803, 0x96D1, 0x6804,
+	0x96D2, 0x6806, 0x96D3, 0x680D, 0x96D4, 0x6810, 0x96D5, 0x6812,
+	0x96D6, 0x6814, 0x96D7, 0x6815, 0x96D8, 0x6818, 0x96D9, 0x6819,
+	0x96DA, 0x681A, 0x96DB, 0x681B, 0x96DC, 0x681C, 0x96DD, 0x681E,
+	0x96DE, 0x681F, 0x96DF, 0x6820, 0x96E0, 0x6822, 0x96E1, 0x6823,
+	0x96E2, 0x6824, 0x96E3, 0x6825, 0x96E4, 0x6826, 0x96E5, 0x6827,
+	0x96E6, 0x6828, 0x96E7, 0x682B, 0x96E8, 0x682C, 0x96E9, 0x682D,
+	0x96EA, 0x682E, 0x96EB, 0x682F, 0x96EC, 0x6830, 0x96ED, 0x6831,
+	0x96EE, 0x6834, 0x96EF, 0x6835, 0x96F0, 0x6836, 0x96F1, 0x683A,
+	0x96F2, 0x683B, 0x96F3, 0x683F, 0x96F4, 0x6847, 0x96F5, 0x684B,
+	0x96F6, 0x684D, 0x96F7, 0x684F, 0x96F8, 0x6852, 0x96F9, 0x6856,
+	0x96FA, 0x6857, 0x96FB, 0x6858, 0x96FC, 0x6859, 0x96FD, 0x685A,
+	0x96FE, 0x685B, 0x9740, 0x685C, 0x9741, 0x685D, 0x9742, 0x685E,
+	0x9743, 0x685F, 0x9744, 0x686A, 0x9745, 0x686C, 0x9746, 0x686D,
+	0x9747, 0x686E, 0x9748, 0x686F, 0x9749, 0x6870, 0x974A, 0x6871,
+	0x974B, 0x6872, 0x974C, 0x6873, 0x974D, 0x6875, 0x974E, 0x6878,
+	0x974F, 0x6879, 0x9750, 0x687A, 0x9751, 0x687B, 0x9752, 0x687C,
+	0x9753, 0x687D, 0x9754, 0x687E, 0x9755, 0x687F, 0x9756, 0x6880,
+	0x9757, 0x6882, 0x9758, 0x6884, 0x9759, 0x6887, 0x975A, 0x6888,
+	0x975B, 0x6889, 0x975C, 0x688A, 0x975D, 0x688B, 0x975E, 0x688C,
+	0x975F, 0x688D, 0x9760, 0x688E, 0x9761, 0x6890, 0x9762, 0x6891,
+	0x9763, 0x6892, 0x9764, 0x6894, 0x9765, 0x6895, 0x9766, 0x6896,
+	0x9767, 0x6898, 0x9768, 0x6899, 0x9769, 0x689A, 0x976A, 0x689B,
+	0x976B, 0x689C, 0x976C, 0x689D, 0x976D, 0x689E, 0x976E, 0x689F,
+	0x976F, 0x68A0, 0x9770, 0x68A1, 0x9771, 0x68A3, 0x9772, 0x68A4,
+	0x9773, 0x68A5, 0x9774, 0x68A9, 0x9775, 0x68AA, 0x9776, 0x68AB,
+	0x9777, 0x68AC, 0x9778, 0x68AE, 0x9779, 0x68B1, 0x977A, 0x68B2,
+	0x977B, 0x68B4, 0x977C, 0x68B6, 0x977D, 0x68B7, 0x977E, 0x68B8,
+	0x9780, 0x68B9, 0x9781, 0x68BA, 0x9782, 0x68BB, 0x9783, 0x68BC,
+	0x9784, 0x68BD, 0x9785, 0x68BE, 0x9786, 0x68BF, 0x9787, 0x68C1,
+	0x9788, 0x68C3, 0x9789, 0x68C4, 0x978A, 0x68C5, 0x978B, 0x68C6,
+	0x978C, 0x68C7, 0x978D, 0x68C8, 0x978E, 0x68CA, 0x978F, 0x68CC,
+	0x9790, 0x68CE, 0x9791, 0x68CF, 0x9792, 0x68D0, 0x9793, 0x68D1,
+	0x9794, 0x68D3, 0x9795, 0x68D4, 0x9796, 0x68D6, 0x9797, 0x68D7,
+	0x9798, 0x68D9, 0x9799, 0x68DB, 0x979A, 0x68DC, 0x979B, 0x68DD,
+	0x979C, 0x68DE, 0x979D, 0x68DF, 0x979E, 0x68E1, 0x979F, 0x68E2,
+	0x97A0, 0x68E4, 0x97A1, 0x68E5, 0x97A2, 0x68E6, 0x97A3, 0x68E7,
+	0x97A4, 0x68E8, 0x97A5, 0x68E9, 0x97A6, 0x68EA, 0x97A7, 0x68EB,
+	0x97A8, 0x68EC, 0x97A9, 0x68ED, 0x97AA, 0x68EF, 0x97AB, 0x68F2,
+	0x97AC, 0x68F3, 0x97AD, 0x68F4, 0x97AE, 0x68F6, 0x97AF, 0x68F7,
+	0x97B0, 0x68F8, 0x97B1, 0x68FB, 0x97B2, 0x68FD, 0x97B3, 0x68FE,
+	0x97B4, 0x68FF, 0x97B5, 0x6900, 0x97B6, 0x6902, 0x97B7, 0x6903,
+	0x97B8, 0x6904, 0x97B9, 0x6906, 0x97BA, 0x6907, 0x97BB, 0x6908,
+	0x97BC, 0x6909, 0x97BD, 0x690A, 0x97BE, 0x690C, 0x97BF, 0x690F,
+	0x97C0, 0x6911, 0x97C1, 0x6913, 0x97C2, 0x6914, 0x97C3, 0x6915,
+	0x97C4, 0x6916, 0x97C5, 0x6917, 0x97C6, 0x6918, 0x97C7, 0x6919,
+	0x97C8, 0x691A, 0x97C9, 0x691B, 0x97CA, 0x691C, 0x97CB, 0x691D,
+	0x97CC, 0x691E, 0x97CD, 0x6921, 0x97CE, 0x6922, 0x97CF, 0x6923,
+	0x97D0, 0x6925, 0x97D1, 0x6926, 0x97D2, 0x6927, 0x97D3, 0x6928,
+	0x97D4, 0x6929, 0x97D5, 0x692A, 0x97D6, 0x692B, 0x97D7, 0x692C,
+	0x97D8, 0x692E, 0x97D9, 0x692F, 0x97DA, 0x6931, 0x97DB, 0x6932,
+	0x97DC, 0x6933, 0x97DD, 0x6935, 0x97DE, 0x6936, 0x97DF, 0x6937,
+	0x97E0, 0x6938, 0x97E1, 0x693A, 0x97E2, 0x693B, 0x97E3, 0x693C,
+	0x97E4, 0x693E, 0x97E5, 0x6940, 0x97E6, 0x6941, 0x97E7, 0x6943,
+	0x97E8, 0x6944, 0x97E9, 0x6945, 0x97EA, 0x6946, 0x97EB, 0x6947,
+	0x97EC, 0x6948, 0x97ED, 0x6949, 0x97EE, 0x694A, 0x97EF, 0x694B,
+	0x97F0, 0x694C, 0x97F1, 0x694D, 0x97F2, 0x694E, 0x97F3, 0x694F,
+	0x97F4, 0x6950, 0x97F5, 0x6951, 0x97F6, 0x6952, 0x97F7, 0x6953,
+	0x97F8, 0x6955, 0x97F9, 0x6956, 0x97FA, 0x6958, 0x97FB, 0x6959,
+	0x97FC, 0x695B, 0x97FD, 0x695C, 0x97FE, 0x695F, 0x9840, 0x6961,
+	0x9841, 0x6962, 0x9842, 0x6964, 0x9843, 0x6965, 0x9844, 0x6967,
+	0x9845, 0x6968, 0x9846, 0x6969, 0x9847, 0x696A, 0x9848, 0x696C,
+	0x9849, 0x696D, 0x984A, 0x696F, 0x984B, 0x6970, 0x984C, 0x6972,
+	0x984D, 0x6973, 0x984E, 0x6974, 0x984F, 0x6975, 0x9850, 0x6976,
+	0x9851, 0x697A, 0x9852, 0x697B, 0x9853, 0x697D, 0x9854, 0x697E,
+	0x9855, 0x697F, 0x9856, 0x6981, 0x9857, 0x6983, 0x9858, 0x6985,
+	0x9859, 0x698A, 0x985A, 0x698B, 0x985B, 0x698C, 0x985C, 0x698E,
+	0x985D, 0x698F, 0x985E, 0x6990, 0x985F, 0x6991, 0x9860, 0x6992,
+	0x9861, 0x6993, 0x9862, 0x6996, 0x9863, 0x6997, 0x9864, 0x6999,
+	0x9865, 0x699A, 0x9866, 0x699D, 0x9867, 0x699E, 0x9868, 0x699F,
+	0x9869, 0x69A0, 0x986A, 0x69A1, 0x986B, 0x69A2, 0x986C, 0x69A3,
+	0x986D, 0x69A4, 0x986E, 0x69A5, 0x986F, 0x69A6, 0x9870, 0x69A9,
+	0x9871, 0x69AA, 0x9872, 0x69AC, 0x9873, 0x69AE, 0x9874, 0x69AF,
+	0x9875, 0x69B0, 0x9876, 0x69B2, 0x9877, 0x69B3, 0x9878, 0x69B5,
+	0x9879, 0x69B6, 0x987A, 0x69B8, 0x987B, 0x69B9, 0x987C, 0x69BA,
+	0x987D, 0x69BC, 0x987E, 0x69BD, 0x9880, 0x69BE, 0x9881, 0x69BF,
+	0x9882, 0x69C0, 0x9883, 0x69C2, 0x9884, 0x69C3, 0x9885, 0x69C4,
+	0x9886, 0x69C5, 0x9887, 0x69C6, 0x9888, 0x69C7, 0x9889, 0x69C8,
+	0x988A, 0x69C9, 0x988B, 0x69CB, 0x988C, 0x69CD, 0x988D, 0x69CF,
+	0x988E, 0x69D1, 0x988F, 0x69D2, 0x9890, 0x69D3, 0x9891, 0x69D5,
+	0x9892, 0x69D6, 0x9893, 0x69D7, 0x9894, 0x69D8, 0x9895, 0x69D9,
+	0x9896, 0x69DA, 0x9897, 0x69DC, 0x9898, 0x69DD, 0x9899, 0x69DE,
+	0x989A, 0x69E1, 0x989B, 0x69E2, 0x989C, 0x69E3, 0x989D, 0x69E4,
+	0x989E, 0x69E5, 0x989F, 0x69E6, 0x98A0, 0x69E7, 0x98A1, 0x69E8,
+	0x98A2, 0x69E9, 0x98A3, 0x69EA, 0x98A4, 0x69EB, 0x98A5, 0x69EC,
+	0x98A6, 0x69EE, 0x98A7, 0x69EF, 0x98A8, 0x69F0, 0x98A9, 0x69F1,
+	0x98AA, 0x69F3, 0x98AB, 0x69F4, 0x98AC, 0x69F5, 0x98AD, 0x69F6,
+	0x98AE, 0x69F7, 0x98AF, 0x69F8, 0x98B0, 0x69F9, 0x98B1, 0x69FA,
+	0x98B2, 0x69FB, 0x98B3, 0x69FC, 0x98B4, 0x69FE, 0x98B5, 0x6A00,
+	0x98B6, 0x6A01, 0x98B7, 0x6A02, 0x98B8, 0x6A03, 0x98B9, 0x6A04,
+	0x98BA, 0x6A05, 0x98BB, 0x6A06, 0x98BC, 0x6A07, 0x98BD, 0x6A08,
+	0x98BE, 0x6A09, 0x98BF, 0x6A0B, 0x98C0, 0x6A0C, 0x98C1, 0x6A0D,
+	0x98C2, 0x6A0E, 0x98C3, 0x6A0F, 0x98C4, 0x6A10, 0x98C5, 0x6A11,
+	0x98C6, 0x6A12, 0x98C7, 0x6A13, 0x98C8, 0x6A14, 0x98C9, 0x6A15,
+	0x98CA, 0x6A16, 0x98CB, 0x6A19, 0x98CC, 0x6A1A, 0x98CD, 0x6A1B,
+	0x98CE, 0x6A1C, 0x98CF, 0x6A1D, 0x98D0, 0x6A1E, 0x98D1, 0x6A20,
+	0x98D2, 0x6A22, 0x98D3, 0x6A23, 0x98D4, 0x6A24, 0x98D5, 0x6A25,
+	0x98D6, 0x6A26, 0x98D7, 0x6A27, 0x98D8, 0x6A29, 0x98D9, 0x6A2B,
+	0x98DA, 0x6A2C, 0x98DB, 0x6A2D, 0x98DC, 0x6A2E, 0x98DD, 0x6A30,
+	0x98DE, 0x6A32, 0x98DF, 0x6A33, 0x98E0, 0x6A34, 0x98E1, 0x6A36,
+	0x98E2, 0x6A37, 0x98E3, 0x6A38, 0x98E4, 0x6A39, 0x98E5, 0x6A3A,
+	0x98E6, 0x6A3B, 0x98E7, 0x6A3C, 0x98E8, 0x6A3F, 0x98E9, 0x6A40,
+	0x98EA, 0x6A41, 0x98EB, 0x6A42, 0x98EC, 0x6A43, 0x98ED, 0x6A45,
+	0x98EE, 0x6A46, 0x98EF, 0x6A48, 0x98F0, 0x6A49, 0x98F1, 0x6A4A,
+	0x98F2, 0x6A4B, 0x98F3, 0x6A4C, 0x98F4, 0x6A4D, 0x98F5, 0x6A4E,
+	0x98F6, 0x6A4F, 0x98F7, 0x6A51, 0x98F8, 0x6A52, 0x98F9, 0x6A53,
+	0x98FA, 0x6A54, 0x98FB, 0x6A55, 0x98FC, 0x6A56, 0x98FD, 0x6A57,
+	0x98FE, 0x6A5A, 0x9940, 0x6A5C, 0x9941, 0x6A5D, 0x9942, 0x6A5E,
+	0x9943, 0x6A5F, 0x9944, 0x6A60, 0x9945, 0x6A62, 0x9946, 0x6A63,
+	0x9947, 0x6A64, 0x9948, 0x6A66, 0x9949, 0x6A67, 0x994A, 0x6A68,
+	0x994B, 0x6A69, 0x994C, 0x6A6A, 0x994D, 0x6A6B, 0x994E, 0x6A6C,
+	0x994F, 0x6A6D, 0x9950, 0x6A6E, 0x9951, 0x6A6F, 0x9952, 0x6A70,
+	0x9953, 0x6A72, 0x9954, 0x6A73, 0x9955, 0x6A74, 0x9956, 0x6A75,
+	0x9957, 0x6A76, 0x9958, 0x6A77, 0x9959, 0x6A78, 0x995A, 0x6A7A,
+	0x995B, 0x6A7B, 0x995C, 0x6A7D, 0x995D, 0x6A7E, 0x995E, 0x6A7F,
+	0x995F, 0x6A81, 0x9960, 0x6A82, 0x9961, 0x6A83, 0x9962, 0x6A85,
+	0x9963, 0x6A86, 0x9964, 0x6A87, 0x9965, 0x6A88, 0x9966, 0x6A89,
+	0x9967, 0x6A8A, 0x9968, 0x6A8B, 0x9969, 0x6A8C, 0x996A, 0x6A8D,
+	0x996B, 0x6A8F, 0x996C, 0x6A92, 0x996D, 0x6A93, 0x996E, 0x6A94,
+	0x996F, 0x6A95, 0x9970, 0x6A96, 0x9971, 0x6A98, 0x9972, 0x6A99,
+	0x9973, 0x6A9A, 0x9974, 0x6A9B, 0x9975, 0x6A9C, 0x9976, 0x6A9D,
+	0x9977, 0x6A9E, 0x9978, 0x6A9F, 0x9979, 0x6AA1, 0x997A, 0x6AA2,
+	0x997B, 0x6AA3, 0x997C, 0x6AA4, 0x997D, 0x6AA5, 0x997E, 0x6AA6,
+	0x9980, 0x6AA7, 0x9981, 0x6AA8, 0x9982, 0x6AAA, 0x9983, 0x6AAD,
+	0x9984, 0x6AAE, 0x9985, 0x6AAF, 0x9986, 0x6AB0, 0x9987, 0x6AB1,
+	0x9988, 0x6AB2, 0x9989, 0x6AB3, 0x998A, 0x6AB4, 0x998B, 0x6AB5,
+	0x998C, 0x6AB6, 0x998D, 0x6AB7, 0x998E, 0x6AB8, 0x998F, 0x6AB9,
+	0x9990, 0x6ABA, 0x9991, 0x6ABB, 0x9992, 0x6ABC, 0x9993, 0x6ABD,
+	0x9994, 0x6ABE, 0x9995, 0x6ABF, 0x9996, 0x6AC0, 0x9997, 0x6AC1,
+	0x9998, 0x6AC2, 0x9999, 0x6AC3, 0x999A, 0x6AC4, 0x999B, 0x6AC5,
+	0x999C, 0x6AC6, 0x999D, 0x6AC7, 0x999E, 0x6AC8, 0x999F, 0x6AC9,
+	0x99A0, 0x6ACA, 0x99A1, 0x6ACB, 0x99A2, 0x6ACC, 0x99A3, 0x6ACD,
+	0x99A4, 0x6ACE, 0x99A5, 0x6ACF, 0x99A6, 0x6AD0, 0x99A7, 0x6AD1,
+	0x99A8, 0x6AD2, 0x99A9, 0x6AD3, 0x99AA, 0x6AD4, 0x99AB, 0x6AD5,
+	0x99AC, 0x6AD6, 0x99AD, 0x6AD7, 0x99AE, 0x6AD8, 0x99AF, 0x6AD9,
+	0x99B0, 0x6ADA, 0x99B1, 0x6ADB, 0x99B2, 0x6ADC, 0x99B3, 0x6ADD,
+	0x99B4, 0x6ADE, 0x99B5, 0x6ADF, 0x99B6, 0x6AE0, 0x99B7, 0x6AE1,
+	0x99B8, 0x6AE2, 0x99B9, 0x6AE3, 0x99BA, 0x6AE4, 0x99BB, 0x6AE5,
+	0x99BC, 0x6AE6, 0x99BD, 0x6AE7, 0x99BE, 0x6AE8, 0x99BF, 0x6AE9,
+	0x99C0, 0x6AEA, 0x99C1, 0x6AEB, 0x99C2, 0x6AEC, 0x99C3, 0x6AED,
+	0x99C4, 0x6AEE, 0x99C5, 0x6AEF, 0x99C6, 0x6AF0, 0x99C7, 0x6AF1,
+	0x99C8, 0x6AF2, 0x99C9, 0x6AF3, 0x99CA, 0x6AF4, 0x99CB, 0x6AF5,
+	0x99CC, 0x6AF6, 0x99CD, 0x6AF7, 0x99CE, 0x6AF8, 0x99CF, 0x6AF9,
+	0x99D0, 0x6AFA, 0x99D1, 0x6AFB, 0x99D2, 0x6AFC, 0x99D3, 0x6AFD,
+	0x99D4, 0x6AFE, 0x99D5, 0x6AFF, 0x99D6, 0x6B00, 0x99D7, 0x6B01,
+	0x99D8, 0x6B02, 0x99D9, 0x6B03, 0x99DA, 0x6B04, 0x99DB, 0x6B05,
+	0x99DC, 0x6B06, 0x99DD, 0x6B07, 0x99DE, 0x6B08, 0x99DF, 0x6B09,
+	0x99E0, 0x6B0A, 0x99E1, 0x6B0B, 0x99E2, 0x6B0C, 0x99E3, 0x6B0D,
+	0x99E4, 0x6B0E, 0x99E5, 0x6B0F, 0x99E6, 0x6B10, 0x99E7, 0x6B11,
+	0x99E8, 0x6B12, 0x99E9, 0x6B13, 0x99EA, 0x6B14, 0x99EB, 0x6B15,
+	0x99EC, 0x6B16, 0x99ED, 0x6B17, 0x99EE, 0x6B18, 0x99EF, 0x6B19,
+	0x99F0, 0x6B1A, 0x99F1, 0x6B1B, 0x99F2, 0x6B1C, 0x99F3, 0x6B1D,
+	0x99F4, 0x6B1E, 0x99F5, 0x6B1F, 0x99F6, 0x6B25, 0x99F7, 0x6B26,
+	0x99F8, 0x6B28, 0x99F9, 0x6B29, 0x99FA, 0x6B2A, 0x99FB, 0x6B2B,
+	0x99FC, 0x6B2C, 0x99FD, 0x6B2D, 0x99FE, 0x6B2E, 0x9A40, 0x6B2F,
+	0x9A41, 0x6B30, 0x9A42, 0x6B31, 0x9A43, 0x6B33, 0x9A44, 0x6B34,
+	0x9A45, 0x6B35, 0x9A46, 0x6B36, 0x9A47, 0x6B38, 0x9A48, 0x6B3B,
+	0x9A49, 0x6B3C, 0x9A4A, 0x6B3D, 0x9A4B, 0x6B3F, 0x9A4C, 0x6B40,
+	0x9A4D, 0x6B41, 0x9A4E, 0x6B42, 0x9A4F, 0x6B44, 0x9A50, 0x6B45,
+	0x9A51, 0x6B48, 0x9A52, 0x6B4A, 0x9A53, 0x6B4B, 0x9A54, 0x6B4D,
+	0x9A55, 0x6B4E, 0x9A56, 0x6B4F, 0x9A57, 0x6B50, 0x9A58, 0x6B51,
+	0x9A59, 0x6B52, 0x9A5A, 0x6B53, 0x9A5B, 0x6B54, 0x9A5C, 0x6B55,
+	0x9A5D, 0x6B56, 0x9A5E, 0x6B57, 0x9A5F, 0x6B58, 0x9A60, 0x6B5A,
+	0x9A61, 0x6B5B, 0x9A62, 0x6B5C, 0x9A63, 0x6B5D, 0x9A64, 0x6B5E,
+	0x9A65, 0x6B5F, 0x9A66, 0x6B60, 0x9A67, 0x6B61, 0x9A68, 0x6B68,
+	0x9A69, 0x6B69, 0x9A6A, 0x6B6B, 0x9A6B, 0x6B6C, 0x9A6C, 0x6B6D,
+	0x9A6D, 0x6B6E, 0x9A6E, 0x6B6F, 0x9A6F, 0x6B70, 0x9A70, 0x6B71,
+	0x9A71, 0x6B72, 0x9A72, 0x6B73, 0x9A73, 0x6B74, 0x9A74, 0x6B75,
+	0x9A75, 0x6B76, 0x9A76, 0x6B77, 0x9A77, 0x6B78, 0x9A78, 0x6B7A,
+	0x9A79, 0x6B7D, 0x9A7A, 0x6B7E, 0x9A7B, 0x6B7F, 0x9A7C, 0x6B80,
+	0x9A7D, 0x6B85, 0x9A7E, 0x6B88, 0x9A80, 0x6B8C, 0x9A81, 0x6B8E,
+	0x9A82, 0x6B8F, 0x9A83, 0x6B90, 0x9A84, 0x6B91, 0x9A85, 0x6B94,
+	0x9A86, 0x6B95, 0x9A87, 0x6B97, 0x9A88, 0x6B98, 0x9A89, 0x6B99,
+	0x9A8A, 0x6B9C, 0x9A8B, 0x6B9D, 0x9A8C, 0x6B9E, 0x9A8D, 0x6B9F,
+	0x9A8E, 0x6BA0, 0x9A8F, 0x6BA2, 0x9A90, 0x6BA3, 0x9A91, 0x6BA4,
+	0x9A92, 0x6BA5, 0x9A93, 0x6BA6, 0x9A94, 0x6BA7, 0x9A95, 0x6BA8,
+	0x9A96, 0x6BA9, 0x9A97, 0x6BAB, 0x9A98, 0x6BAC, 0x9A99, 0x6BAD,
+	0x9A9A, 0x6BAE, 0x9A9B, 0x6BAF, 0x9A9C, 0x6BB0, 0x9A9D, 0x6BB1,
+	0x9A9E, 0x6BB2, 0x9A9F, 0x6BB6, 0x9AA0, 0x6BB8, 0x9AA1, 0x6BB9,
+	0x9AA2, 0x6BBA, 0x9AA3, 0x6BBB, 0x9AA4, 0x6BBC, 0x9AA5, 0x6BBD,
+	0x9AA6, 0x6BBE, 0x9AA7, 0x6BC0, 0x9AA8, 0x6BC3, 0x9AA9, 0x6BC4,
+	0x9AAA, 0x6BC6, 0x9AAB, 0x6BC7, 0x9AAC, 0x6BC8, 0x9AAD, 0x6BC9,
+	0x9AAE, 0x6BCA, 0x9AAF, 0x6BCC, 0x9AB0, 0x6BCE, 0x9AB1, 0x6BD0,
+	0x9AB2, 0x6BD1, 0x9AB3, 0x6BD8, 0x9AB4, 0x6BDA, 0x9AB5, 0x6BDC,
+	0x9AB6, 0x6BDD, 0x9AB7, 0x6BDE, 0x9AB8, 0x6BDF, 0x9AB9, 0x6BE0,
+	0x9ABA, 0x6BE2, 0x9ABB, 0x6BE3, 0x9ABC, 0x6BE4, 0x9ABD, 0x6BE5,
+	0x9ABE, 0x6BE6, 0x9ABF, 0x6BE7, 0x9AC0, 0x6BE8, 0x9AC1, 0x6BE9,
+	0x9AC2, 0x6BEC, 0x9AC3, 0x6BED, 0x9AC4, 0x6BEE, 0x9AC5, 0x6BF0,
+	0x9AC6, 0x6BF1, 0x9AC7, 0x6BF2, 0x9AC8, 0x6BF4, 0x9AC9, 0x6BF6,
+	0x9ACA, 0x6BF7, 0x9ACB, 0x6BF8, 0x9ACC, 0x6BFA, 0x9ACD, 0x6BFB,
+	0x9ACE, 0x6BFC, 0x9ACF, 0x6BFE, 0x9AD0, 0x6BFF, 0x9AD1, 0x6C00,
+	0x9AD2, 0x6C01, 0x9AD3, 0x6C02, 0x9AD4, 0x6C03, 0x9AD5, 0x6C04,
+	0x9AD6, 0x6C08, 0x9AD7, 0x6C09, 0x9AD8, 0x6C0A, 0x9AD9, 0x6C0B,
+	0x9ADA, 0x6C0C, 0x9ADB, 0x6C0E, 0x9ADC, 0x6C12, 0x9ADD, 0x6C17,
+	0x9ADE, 0x6C1C, 0x9ADF, 0x6C1D, 0x9AE0, 0x6C1E, 0x9AE1, 0x6C20,
+	0x9AE2, 0x6C23, 0x9AE3, 0x6C25, 0x9AE4, 0x6C2B, 0x9AE5, 0x6C2C,
+	0x9AE6, 0x6C2D, 0x9AE7, 0x6C31, 0x9AE8, 0x6C33, 0x9AE9, 0x6C36,
+	0x9AEA, 0x6C37, 0x9AEB, 0x6C39, 0x9AEC, 0x6C3A, 0x9AED, 0x6C3B,
+	0x9AEE, 0x6C3C, 0x9AEF, 0x6C3E, 0x9AF0, 0x6C3F, 0x9AF1, 0x6C43,
+	0x9AF2, 0x6C44, 0x9AF3, 0x6C45, 0x9AF4, 0x6C48, 0x9AF5, 0x6C4B,
+	0x9AF6, 0x6C4C, 0x9AF7, 0x6C4D, 0x9AF8, 0x6C4E, 0x9AF9, 0x6C4F,
+	0x9AFA, 0x6C51, 0x9AFB, 0x6C52, 0x9AFC, 0x6C53, 0x9AFD, 0x6C56,
+	0x9AFE, 0x6C58, 0x9B40, 0x6C59, 0x9B41, 0x6C5A, 0x9B42, 0x6C62,
+	0x9B43, 0x6C63, 0x9B44, 0x6C65, 0x9B45, 0x6C66, 0x9B46, 0x6C67,
+	0x9B47, 0x6C6B, 0x9B48, 0x6C6C, 0x9B49, 0x6C6D, 0x9B4A, 0x6C6E,
+	0x9B4B, 0x6C6F, 0x9B4C, 0x6C71, 0x9B4D, 0x6C73, 0x9B4E, 0x6C75,
+	0x9B4F, 0x6C77, 0x9B50, 0x6C78, 0x9B51, 0x6C7A, 0x9B52, 0x6C7B,
+	0x9B53, 0x6C7C, 0x9B54, 0x6C7F, 0x9B55, 0x6C80, 0x9B56, 0x6C84,
+	0x9B57, 0x6C87, 0x9B58, 0x6C8A, 0x9B59, 0x6C8B, 0x9B5A, 0x6C8D,
+	0x9B5B, 0x6C8E, 0x9B5C, 0x6C91, 0x9B5D, 0x6C92, 0x9B5E, 0x6C95,
+	0x9B5F, 0x6C96, 0x9B60, 0x6C97, 0x9B61, 0x6C98, 0x9B62, 0x6C9A,
+	0x9B63, 0x6C9C, 0x9B64, 0x6C9D, 0x9B65, 0x6C9E, 0x9B66, 0x6CA0,
+	0x9B67, 0x6CA2, 0x9B68, 0x6CA8, 0x9B69, 0x6CAC, 0x9B6A, 0x6CAF,
+	0x9B6B, 0x6CB0, 0x9B6C, 0x6CB4, 0x9B6D, 0x6CB5, 0x9B6E, 0x6CB6,
+	0x9B6F, 0x6CB7, 0x9B70, 0x6CBA, 0x9B71, 0x6CC0, 0x9B72, 0x6CC1,
+	0x9B73, 0x6CC2, 0x9B74, 0x6CC3, 0x9B75, 0x6CC6, 0x9B76, 0x6CC7,
+	0x9B77, 0x6CC8, 0x9B78, 0x6CCB, 0x9B79, 0x6CCD, 0x9B7A, 0x6CCE,
+	0x9B7B, 0x6CCF, 0x9B7C, 0x6CD1, 0x9B7D, 0x6CD2, 0x9B7E, 0x6CD8,
+	0x9B80, 0x6CD9, 0x9B81, 0x6CDA, 0x9B82, 0x6CDC, 0x9B83, 0x6CDD,
+	0x9B84, 0x6CDF, 0x9B85, 0x6CE4, 0x9B86, 0x6CE6, 0x9B87, 0x6CE7,
+	0x9B88, 0x6CE9, 0x9B89, 0x6CEC, 0x9B8A, 0x6CED, 0x9B8B, 0x6CF2,
+	0x9B8C, 0x6CF4, 0x9B8D, 0x6CF9, 0x9B8E, 0x6CFF, 0x9B8F, 0x6D00,
+	0x9B90, 0x6D02, 0x9B91, 0x6D03, 0x9B92, 0x6D05, 0x9B93, 0x6D06,
+	0x9B94, 0x6D08, 0x9B95, 0x6D09, 0x9B96, 0x6D0A, 0x9B97, 0x6D0D,
+	0x9B98, 0x6D0F, 0x9B99, 0x6D10, 0x9B9A, 0x6D11, 0x9B9B, 0x6D13,
+	0x9B9C, 0x6D14, 0x9B9D, 0x6D15, 0x9B9E, 0x6D16, 0x9B9F, 0x6D18,
+	0x9BA0, 0x6D1C, 0x9BA1, 0x6D1D, 0x9BA2, 0x6D1F, 0x9BA3, 0x6D20,
+	0x9BA4, 0x6D21, 0x9BA5, 0x6D22, 0x9BA6, 0x6D23, 0x9BA7, 0x6D24,
+	0x9BA8, 0x6D26, 0x9BA9, 0x6D28, 0x9BAA, 0x6D29, 0x9BAB, 0x6D2C,
+	0x9BAC, 0x6D2D, 0x9BAD, 0x6D2F, 0x9BAE, 0x6D30, 0x9BAF, 0x6D34,
+	0x9BB0, 0x6D36, 0x9BB1, 0x6D37, 0x9BB2, 0x6D38, 0x9BB3, 0x6D3A,
+	0x9BB4, 0x6D3F, 0x9BB5, 0x6D40, 0x9BB6, 0x6D42, 0x9BB7, 0x6D44,
+	0x9BB8, 0x6D49, 0x9BB9, 0x6D4C, 0x9BBA, 0x6D50, 0x9BBB, 0x6D55,
+	0x9BBC, 0x6D56, 0x9BBD, 0x6D57, 0x9BBE, 0x6D58, 0x9BBF, 0x6D5B,
+	0x9BC0, 0x6D5D, 0x9BC1, 0x6D5F, 0x9BC2, 0x6D61, 0x9BC3, 0x6D62,
+	0x9BC4, 0x6D64, 0x9BC5, 0x6D65, 0x9BC6, 0x6D67, 0x9BC7, 0x6D68,
+	0x9BC8, 0x6D6B, 0x9BC9, 0x6D6C, 0x9BCA, 0x6D6D, 0x9BCB, 0x6D70,
+	0x9BCC, 0x6D71, 0x9BCD, 0x6D72, 0x9BCE, 0x6D73, 0x9BCF, 0x6D75,
+	0x9BD0, 0x6D76, 0x9BD1, 0x6D79, 0x9BD2, 0x6D7A, 0x9BD3, 0x6D7B,
+	0x9BD4, 0x6D7D, 0x9BD5, 0x6D7E, 0x9BD6, 0x6D7F, 0x9BD7, 0x6D80,
+	0x9BD8, 0x6D81, 0x9BD9, 0x6D83, 0x9BDA, 0x6D84, 0x9BDB, 0x6D86,
+	0x9BDC, 0x6D87, 0x9BDD, 0x6D8A, 0x9BDE, 0x6D8B, 0x9BDF, 0x6D8D,
+	0x9BE0, 0x6D8F, 0x9BE1, 0x6D90, 0x9BE2, 0x6D92, 0x9BE3, 0x6D96,
+	0x9BE4, 0x6D97, 0x9BE5, 0x6D98, 0x9BE6, 0x6D99, 0x9BE7, 0x6D9A,
+	0x9BE8, 0x6D9C, 0x9BE9, 0x6DA2, 0x9BEA, 0x6DA5, 0x9BEB, 0x6DAC,
+	0x9BEC, 0x6DAD, 0x9BED, 0x6DB0, 0x9BEE, 0x6DB1, 0x9BEF, 0x6DB3,
+	0x9BF0, 0x6DB4, 0x9BF1, 0x6DB6, 0x9BF2, 0x6DB7, 0x9BF3, 0x6DB9,
+	0x9BF4, 0x6DBA, 0x9BF5, 0x6DBB, 0x9BF6, 0x6DBC, 0x9BF7, 0x6DBD,
+	0x9BF8, 0x6DBE, 0x9BF9, 0x6DC1, 0x9BFA, 0x6DC2, 0x9BFB, 0x6DC3,
+	0x9BFC, 0x6DC8, 0x9BFD, 0x6DC9, 0x9BFE, 0x6DCA, 0x9C40, 0x6DCD,
+	0x9C41, 0x6DCE, 0x9C42, 0x6DCF, 0x9C43, 0x6DD0, 0x9C44, 0x6DD2,
+	0x9C45, 0x6DD3, 0x9C46, 0x6DD4, 0x9C47, 0x6DD5, 0x9C48, 0x6DD7,
+	0x9C49, 0x6DDA, 0x9C4A, 0x6DDB, 0x9C4B, 0x6DDC, 0x9C4C, 0x6DDF,
+	0x9C4D, 0x6DE2, 0x9C4E, 0x6DE3, 0x9C4F, 0x6DE5, 0x9C50, 0x6DE7,
+	0x9C51, 0x6DE8, 0x9C52, 0x6DE9, 0x9C53, 0x6DEA, 0x9C54, 0x6DED,
+	0x9C55, 0x6DEF, 0x9C56, 0x6DF0, 0x9C57, 0x6DF2, 0x9C58, 0x6DF4,
+	0x9C59, 0x6DF5, 0x9C5A, 0x6DF6, 0x9C5B, 0x6DF8, 0x9C5C, 0x6DFA,
+	0x9C5D, 0x6DFD, 0x9C5E, 0x6DFE, 0x9C5F, 0x6DFF, 0x9C60, 0x6E00,
+	0x9C61, 0x6E01, 0x9C62, 0x6E02, 0x9C63, 0x6E03, 0x9C64, 0x6E04,
+	0x9C65, 0x6E06, 0x9C66, 0x6E07, 0x9C67, 0x6E08, 0x9C68, 0x6E09,
+	0x9C69, 0x6E0B, 0x9C6A, 0x6E0F, 0x9C6B, 0x6E12, 0x9C6C, 0x6E13,
+	0x9C6D, 0x6E15, 0x9C6E, 0x6E18, 0x9C6F, 0x6E19, 0x9C70, 0x6E1B,
+	0x9C71, 0x6E1C, 0x9C72, 0x6E1E, 0x9C73, 0x6E1F, 0x9C74, 0x6E22,
+	0x9C75, 0x6E26, 0x9C76, 0x6E27, 0x9C77, 0x6E28, 0x9C78, 0x6E2A,
+	0x9C79, 0x6E2C, 0x9C7A, 0x6E2E, 0x9C7B, 0x6E30, 0x9C7C, 0x6E31,
+	0x9C7D, 0x6E33, 0x9C7E, 0x6E35, 0x9C80, 0x6E36, 0x9C81, 0x6E37,
+	0x9C82, 0x6E39, 0x9C83, 0x6E3B, 0x9C84, 0x6E3C, 0x9C85, 0x6E3D,
+	0x9C86, 0x6E3E, 0x9C87, 0x6E3F, 0x9C88, 0x6E40, 0x9C89, 0x6E41,
+	0x9C8A, 0x6E42, 0x9C8B, 0x6E45, 0x9C8C, 0x6E46, 0x9C8D, 0x6E47,
+	0x9C8E, 0x6E48, 0x9C8F, 0x6E49, 0x9C90, 0x6E4A, 0x9C91, 0x6E4B,
+	0x9C92, 0x6E4C, 0x9C93, 0x6E4F, 0x9C94, 0x6E50, 0x9C95, 0x6E51,
+	0x9C96, 0x6E52, 0x9C97, 0x6E55, 0x9C98, 0x6E57, 0x9C99, 0x6E59,
+	0x9C9A, 0x6E5A, 0x9C9B, 0x6E5C, 0x9C9C, 0x6E5D, 0x9C9D, 0x6E5E,
+	0x9C9E, 0x6E60, 0x9C9F, 0x6E61, 0x9CA0, 0x6E62, 0x9CA1, 0x6E63,
+	0x9CA2, 0x6E64, 0x9CA3, 0x6E65, 0x9CA4, 0x6E66, 0x9CA5, 0x6E67,
+	0x9CA6, 0x6E68, 0x9CA7, 0x6E69, 0x9CA8, 0x6E6A, 0x9CA9, 0x6E6C,
+	0x9CAA, 0x6E6D, 0x9CAB, 0x6E6F, 0x9CAC, 0x6E70, 0x9CAD, 0x6E71,
+	0x9CAE, 0x6E72, 0x9CAF, 0x6E73, 0x9CB0, 0x6E74, 0x9CB1, 0x6E75,
+	0x9CB2, 0x6E76, 0x9CB3, 0x6E77, 0x9CB4, 0x6E78, 0x9CB5, 0x6E79,
+	0x9CB6, 0x6E7A, 0x9CB7, 0x6E7B, 0x9CB8, 0x6E7C, 0x9CB9, 0x6E7D,
+	0x9CBA, 0x6E80, 0x9CBB, 0x6E81, 0x9CBC, 0x6E82, 0x9CBD, 0x6E84,
+	0x9CBE, 0x6E87, 0x9CBF, 0x6E88, 0x9CC0, 0x6E8A, 0x9CC1, 0x6E8B,
+	0x9CC2, 0x6E8C, 0x9CC3, 0x6E8D, 0x9CC4, 0x6E8E, 0x9CC5, 0x6E91,
+	0x9CC6, 0x6E92, 0x9CC7, 0x6E93, 0x9CC8, 0x6E94, 0x9CC9, 0x6E95,
+	0x9CCA, 0x6E96, 0x9CCB, 0x6E97, 0x9CCC, 0x6E99, 0x9CCD, 0x6E9A,
+	0x9CCE, 0x6E9B, 0x9CCF, 0x6E9D, 0x9CD0, 0x6E9E, 0x9CD1, 0x6EA0,
+	0x9CD2, 0x6EA1, 0x9CD3, 0x6EA3, 0x9CD4, 0x6EA4, 0x9CD5, 0x6EA6,
+	0x9CD6, 0x6EA8, 0x9CD7, 0x6EA9, 0x9CD8, 0x6EAB, 0x9CD9, 0x6EAC,
+	0x9CDA, 0x6EAD, 0x9CDB, 0x6EAE, 0x9CDC, 0x6EB0, 0x9CDD, 0x6EB3,
+	0x9CDE, 0x6EB5, 0x9CDF, 0x6EB8, 0x9CE0, 0x6EB9, 0x9CE1, 0x6EBC,
+	0x9CE2, 0x6EBE, 0x9CE3, 0x6EBF, 0x9CE4, 0x6EC0, 0x9CE5, 0x6EC3,
+	0x9CE6, 0x6EC4, 0x9CE7, 0x6EC5, 0x9CE8, 0x6EC6, 0x9CE9, 0x6EC8,
+	0x9CEA, 0x6EC9, 0x9CEB, 0x6ECA, 0x9CEC, 0x6ECC, 0x9CED, 0x6ECD,
+	0x9CEE, 0x6ECE, 0x9CEF, 0x6ED0, 0x9CF0, 0x6ED2, 0x9CF1, 0x6ED6,
+	0x9CF2, 0x6ED8, 0x9CF3, 0x6ED9, 0x9CF4, 0x6EDB, 0x9CF5, 0x6EDC,
+	0x9CF6, 0x6EDD, 0x9CF7, 0x6EE3, 0x9CF8, 0x6EE7, 0x9CF9, 0x6EEA,
+	0x9CFA, 0x6EEB, 0x9CFB, 0x6EEC, 0x9CFC, 0x6EED, 0x9CFD, 0x6EEE,
+	0x9CFE, 0x6EEF, 0x9D40, 0x6EF0, 0x9D41, 0x6EF1, 0x9D42, 0x6EF2,
+	0x9D43, 0x6EF3, 0x9D44, 0x6EF5, 0x9D45, 0x6EF6, 0x9D46, 0x6EF7,
+	0x9D47, 0x6EF8, 0x9D48, 0x6EFA, 0x9D49, 0x6EFB, 0x9D4A, 0x6EFC,
+	0x9D4B, 0x6EFD, 0x9D4C, 0x6EFE, 0x9D4D, 0x6EFF, 0x9D4E, 0x6F00,
+	0x9D4F, 0x6F01, 0x9D50, 0x6F03, 0x9D51, 0x6F04, 0x9D52, 0x6F05,
+	0x9D53, 0x6F07, 0x9D54, 0x6F08, 0x9D55, 0x6F0A, 0x9D56, 0x6F0B,
+	0x9D57, 0x6F0C, 0x9D58, 0x6F0D, 0x9D59, 0x6F0E, 0x9D5A, 0x6F10,
+	0x9D5B, 0x6F11, 0x9D5C, 0x6F12, 0x9D5D, 0x6F16, 0x9D5E, 0x6F17,
+	0x9D5F, 0x6F18, 0x9D60, 0x6F19, 0x9D61, 0x6F1A, 0x9D62, 0x6F1B,
+	0x9D63, 0x6F1C, 0x9D64, 0x6F1D, 0x9D65, 0x6F1E, 0x9D66, 0x6F1F,
+	0x9D67, 0x6F21, 0x9D68, 0x6F22, 0x9D69, 0x6F23, 0x9D6A, 0x6F25,
+	0x9D6B, 0x6F26, 0x9D6C, 0x6F27, 0x9D6D, 0x6F28, 0x9D6E, 0x6F2C,
+	0x9D6F, 0x6F2E, 0x9D70, 0x6F30, 0x9D71, 0x6F32, 0x9D72, 0x6F34,
+	0x9D73, 0x6F35, 0x9D74, 0x6F37, 0x9D75, 0x6F38, 0x9D76, 0x6F39,
+	0x9D77, 0x6F3A, 0x9D78, 0x6F3B, 0x9D79, 0x6F3C, 0x9D7A, 0x6F3D,
+	0x9D7B, 0x6F3F, 0x9D7C, 0x6F40, 0x9D7D, 0x6F41, 0x9D7E, 0x6F42,
+	0x9D80, 0x6F43, 0x9D81, 0x6F44, 0x9D82, 0x6F45, 0x9D83, 0x6F48,
+	0x9D84, 0x6F49, 0x9D85, 0x6F4A, 0x9D86, 0x6F4C, 0x9D87, 0x6F4E,
+	0x9D88, 0x6F4F, 0x9D89, 0x6F50, 0x9D8A, 0x6F51, 0x9D8B, 0x6F52,
+	0x9D8C, 0x6F53, 0x9D8D, 0x6F54, 0x9D8E, 0x6F55, 0x9D8F, 0x6F56,
+	0x9D90, 0x6F57, 0x9D91, 0x6F59, 0x9D92, 0x6F5A, 0x9D93, 0x6F5B,
+	0x9D94, 0x6F5D, 0x9D95, 0x6F5F, 0x9D96, 0x6F60, 0x9D97, 0x6F61,
+	0x9D98, 0x6F63, 0x9D99, 0x6F64, 0x9D9A, 0x6F65, 0x9D9B, 0x6F67,
+	0x9D9C, 0x6F68, 0x9D9D, 0x6F69, 0x9D9E, 0x6F6A, 0x9D9F, 0x6F6B,
+	0x9DA0, 0x6F6C, 0x9DA1, 0x6F6F, 0x9DA2, 0x6F70, 0x9DA3, 0x6F71,
+	0x9DA4, 0x6F73, 0x9DA5, 0x6F75, 0x9DA6, 0x6F76, 0x9DA7, 0x6F77,
+	0x9DA8, 0x6F79, 0x9DA9, 0x6F7B, 0x9DAA, 0x6F7D, 0x9DAB, 0x6F7E,
+	0x9DAC, 0x6F7F, 0x9DAD, 0x6F80, 0x9DAE, 0x6F81, 0x9DAF, 0x6F82,
+	0x9DB0, 0x6F83, 0x9DB1, 0x6F85, 0x9DB2, 0x6F86, 0x9DB3, 0x6F87,
+	0x9DB4, 0x6F8A, 0x9DB5, 0x6F8B, 0x9DB6, 0x6F8F, 0x9DB7, 0x6F90,
+	0x9DB8, 0x6F91, 0x9DB9, 0x6F92, 0x9DBA, 0x6F93, 0x9DBB, 0x6F94,
+	0x9DBC, 0x6F95, 0x9DBD, 0x6F96, 0x9DBE, 0x6F97, 0x9DBF, 0x6F98,
+	0x9DC0, 0x6F99, 0x9DC1, 0x6F9A, 0x9DC2, 0x6F9B, 0x9DC3, 0x6F9D,
+	0x9DC4, 0x6F9E, 0x9DC5, 0x6F9F, 0x9DC6, 0x6FA0, 0x9DC7, 0x6FA2,
+	0x9DC8, 0x6FA3, 0x9DC9, 0x6FA4, 0x9DCA, 0x6FA5, 0x9DCB, 0x6FA6,
+	0x9DCC, 0x6FA8, 0x9DCD, 0x6FA9, 0x9DCE, 0x6FAA, 0x9DCF, 0x6FAB,
+	0x9DD0, 0x6FAC, 0x9DD1, 0x6FAD, 0x9DD2, 0x6FAE, 0x9DD3, 0x6FAF,
+	0x9DD4, 0x6FB0, 0x9DD5, 0x6FB1, 0x9DD6, 0x6FB2, 0x9DD7, 0x6FB4,
+	0x9DD8, 0x6FB5, 0x9DD9, 0x6FB7, 0x9DDA, 0x6FB8, 0x9DDB, 0x6FBA,
+	0x9DDC, 0x6FBB, 0x9DDD, 0x6FBC, 0x9DDE, 0x6FBD, 0x9DDF, 0x6FBE,
+	0x9DE0, 0x6FBF, 0x9DE1, 0x6FC1, 0x9DE2, 0x6FC3, 0x9DE3, 0x6FC4,
+	0x9DE4, 0x6FC5, 0x9DE5, 0x6FC6, 0x9DE6, 0x6FC7, 0x9DE7, 0x6FC8,
+	0x9DE8, 0x6FCA, 0x9DE9, 0x6FCB, 0x9DEA, 0x6FCC, 0x9DEB, 0x6FCD,
+	0x9DEC, 0x6FCE, 0x9DED, 0x6FCF, 0x9DEE, 0x6FD0, 0x9DEF, 0x6FD3,
+	0x9DF0, 0x6FD4, 0x9DF1, 0x6FD5, 0x9DF2, 0x6FD6, 0x9DF3, 0x6FD7,
+	0x9DF4, 0x6FD8, 0x9DF5, 0x6FD9, 0x9DF6, 0x6FDA, 0x9DF7, 0x6FDB,
+	0x9DF8, 0x6FDC, 0x9DF9, 0x6FDD, 0x9DFA, 0x6FDF, 0x9DFB, 0x6FE2,
+	0x9DFC, 0x6FE3, 0x9DFD, 0x6FE4, 0x9DFE, 0x6FE5, 0x9E40, 0x6FE6,
+	0x9E41, 0x6FE7, 0x9E42, 0x6FE8, 0x9E43, 0x6FE9, 0x9E44, 0x6FEA,
+	0x9E45, 0x6FEB, 0x9E46, 0x6FEC, 0x9E47, 0x6FED, 0x9E48, 0x6FF0,
+	0x9E49, 0x6FF1, 0x9E4A, 0x6FF2, 0x9E4B, 0x6FF3, 0x9E4C, 0x6FF4,
+	0x9E4D, 0x6FF5, 0x9E4E, 0x6FF6, 0x9E4F, 0x6FF7, 0x9E50, 0x6FF8,
+	0x9E51, 0x6FF9, 0x9E52, 0x6FFA, 0x9E53, 0x6FFB, 0x9E54, 0x6FFC,
+	0x9E55, 0x6FFD, 0x9E56, 0x6FFE, 0x9E57, 0x6FFF, 0x9E58, 0x7000,
+	0x9E59, 0x7001, 0x9E5A, 0x7002, 0x9E5B, 0x7003, 0x9E5C, 0x7004,
+	0x9E5D, 0x7005, 0x9E5E, 0x7006, 0x9E5F, 0x7007, 0x9E60, 0x7008,
+	0x9E61, 0x7009, 0x9E62, 0x700A, 0x9E63, 0x700B, 0x9E64, 0x700C,
+	0x9E65, 0x700D, 0x9E66, 0x700E, 0x9E67, 0x700F, 0x9E68, 0x7010,
+	0x9E69, 0x7012, 0x9E6A, 0x7013, 0x9E6B, 0x7014, 0x9E6C, 0x7015,
+	0x9E6D, 0x7016, 0x9E6E, 0x7017, 0x9E6F, 0x7018, 0x9E70, 0x7019,
+	0x9E71, 0x701C, 0x9E72, 0x701D, 0x9E73, 0x701E, 0x9E74, 0x701F,
+	0x9E75, 0x7020, 0x9E76, 0x7021, 0x9E77, 0x7022, 0x9E78, 0x7024,
+	0x9E79, 0x7025, 0x9E7A, 0x7026, 0x9E7B, 0x7027, 0x9E7C, 0x7028,
+	0x9E7D, 0x7029, 0x9E7E, 0x702A, 0x9E80, 0x702B, 0x9E81, 0x702C,
+	0x9E82, 0x702D, 0x9E83, 0x702E, 0x9E84, 0x702F, 0x9E85, 0x7030,
+	0x9E86, 0x7031, 0x9E87, 0x7032, 0x9E88, 0x7033, 0x9E89, 0x7034,
+	0x9E8A, 0x7036, 0x9E8B, 0x7037, 0x9E8C, 0x7038, 0x9E8D, 0x703A,
+	0x9E8E, 0x703B, 0x9E8F, 0x703C, 0x9E90, 0x703D, 0x9E91, 0x703E,
+	0x9E92, 0x703F, 0x9E93, 0x7040, 0x9E94, 0x7041, 0x9E95, 0x7042,
+	0x9E96, 0x7043, 0x9E97, 0x7044, 0x9E98, 0x7045, 0x9E99, 0x7046,
+	0x9E9A, 0x7047, 0x9E9B, 0x7048, 0x9E9C, 0x7049, 0x9E9D, 0x704A,
+	0x9E9E, 0x704B, 0x9E9F, 0x704D, 0x9EA0, 0x704E, 0x9EA1, 0x7050,
+	0x9EA2, 0x7051, 0x9EA3, 0x7052, 0x9EA4, 0x7053, 0x9EA5, 0x7054,
+	0x9EA6, 0x7055, 0x9EA7, 0x7056, 0x9EA8, 0x7057, 0x9EA9, 0x7058,
+	0x9EAA, 0x7059, 0x9EAB, 0x705A, 0x9EAC, 0x705B, 0x9EAD, 0x705C,
+	0x9EAE, 0x705D, 0x9EAF, 0x705F, 0x9EB0, 0x7060, 0x9EB1, 0x7061,
+	0x9EB2, 0x7062, 0x9EB3, 0x7063, 0x9EB4, 0x7064, 0x9EB5, 0x7065,
+	0x9EB6, 0x7066, 0x9EB7, 0x7067, 0x9EB8, 0x7068, 0x9EB9, 0x7069,
+	0x9EBA, 0x706A, 0x9EBB, 0x706E, 0x9EBC, 0x7071, 0x9EBD, 0x7072,
+	0x9EBE, 0x7073, 0x9EBF, 0x7074, 0x9EC0, 0x7077, 0x9EC1, 0x7079,
+	0x9EC2, 0x707A, 0x9EC3, 0x707B, 0x9EC4, 0x707D, 0x9EC5, 0x7081,
+	0x9EC6, 0x7082, 0x9EC7, 0x7083, 0x9EC8, 0x7084, 0x9EC9, 0x7086,
+	0x9ECA, 0x7087, 0x9ECB, 0x7088, 0x9ECC, 0x708B, 0x9ECD, 0x708C,
+	0x9ECE, 0x708D, 0x9ECF, 0x708F, 0x9ED0, 0x7090, 0x9ED1, 0x7091,
+	0x9ED2, 0x7093, 0x9ED3, 0x7097, 0x9ED4, 0x7098, 0x9ED5, 0x709A,
+	0x9ED6, 0x709B, 0x9ED7, 0x709E, 0x9ED8, 0x709F, 0x9ED9, 0x70A0,
+	0x9EDA, 0x70A1, 0x9EDB, 0x70A2, 0x9EDC, 0x70A3, 0x9EDD, 0x70A4,
+	0x9EDE, 0x70A5, 0x9EDF, 0x70A6, 0x9EE0, 0x70A7, 0x9EE1, 0x70A8,
+	0x9EE2, 0x70A9, 0x9EE3, 0x70AA, 0x9EE4, 0x70B0, 0x9EE5, 0x70B2,
+	0x9EE6, 0x70B4, 0x9EE7, 0x70B5, 0x9EE8, 0x70B6, 0x9EE9, 0x70BA,
+	0x9EEA, 0x70BE, 0x9EEB, 0x70BF, 0x9EEC, 0x70C4, 0x9EED, 0x70C5,
+	0x9EEE, 0x70C6, 0x9EEF, 0x70C7, 0x9EF0, 0x70C9, 0x9EF1, 0x70CB,
+	0x9EF2, 0x70CC, 0x9EF3, 0x70CD, 0x9EF4, 0x70CE, 0x9EF5, 0x70CF,
+	0x9EF6, 0x70D0, 0x9EF7, 0x70D1, 0x9EF8, 0x70D2, 0x9EF9, 0x70D3,
+	0x9EFA, 0x70D4, 0x9EFB, 0x70D5, 0x9EFC, 0x70D6, 0x9EFD, 0x70D7,
+	0x9EFE, 0x70DA, 0x9F40, 0x70DC, 0x9F41, 0x70DD, 0x9F42, 0x70DE,
+	0x9F43, 0x70E0, 0x9F44, 0x70E1, 0x9F45, 0x70E2, 0x9F46, 0x70E3,
+	0x9F47, 0x70E5, 0x9F48, 0x70EA, 0x9F49, 0x70EE, 0x9F4A, 0x70F0,
+	0x9F4B, 0x70F1, 0x9F4C, 0x70F2, 0x9F4D, 0x70F3, 0x9F4E, 0x70F4,
+	0x9F4F, 0x70F5, 0x9F50, 0x70F6, 0x9F51, 0x70F8, 0x9F52, 0x70FA,
+	0x9F53, 0x70FB, 0x9F54, 0x70FC, 0x9F55, 0x70FE, 0x9F56, 0x70FF,
+	0x9F57, 0x7100, 0x9F58, 0x7101, 0x9F59, 0x7102, 0x9F5A, 0x7103,
+	0x9F5B, 0x7104, 0x9F5C, 0x7105, 0x9F5D, 0x7106, 0x9F5E, 0x7107,
+	0x9F5F, 0x7108, 0x9F60, 0x710B, 0x9F61, 0x710C, 0x9F62, 0x710D,
+	0x9F63, 0x710E, 0x9F64, 0x710F, 0x9F65, 0x7111, 0x9F66, 0x7112,
+	0x9F67, 0x7114, 0x9F68, 0x7117, 0x9F69, 0x711B, 0x9F6A, 0x711C,
+	0x9F6B, 0x711D, 0x9F6C, 0x711E, 0x9F6D, 0x711F, 0x9F6E, 0x7120,
+	0x9F6F, 0x7121, 0x9F70, 0x7122, 0x9F71, 0x7123, 0x9F72, 0x7124,
+	0x9F73, 0x7125, 0x9F74, 0x7127, 0x9F75, 0x7128, 0x9F76, 0x7129,
+	0x9F77, 0x712A, 0x9F78, 0x712B, 0x9F79, 0x712C, 0x9F7A, 0x712D,
+	0x9F7B, 0x712E, 0x9F7C, 0x7132, 0x9F7D, 0x7133, 0x9F7E, 0x7134,
+	0x9F80, 0x7135, 0x9F81, 0x7137, 0x9F82, 0x7138, 0x9F83, 0x7139,
+	0x9F84, 0x713A, 0x9F85, 0x713B, 0x9F86, 0x713C, 0x9F87, 0x713D,
+	0x9F88, 0x713E, 0x9F89, 0x713F, 0x9F8A, 0x7140, 0x9F8B, 0x7141,
+	0x9F8C, 0x7142, 0x9F8D, 0x7143, 0x9F8E, 0x7144, 0x9F8F, 0x7146,
+	0x9F90, 0x7147, 0x9F91, 0x7148, 0x9F92, 0x7149, 0x9F93, 0x714B,
+	0x9F94, 0x714D, 0x9F95, 0x714F, 0x9F96, 0x7150, 0x9F97, 0x7151,
+	0x9F98, 0x7152, 0x9F99, 0x7153, 0x9F9A, 0x7154, 0x9F9B, 0x7155,
+	0x9F9C, 0x7156, 0x9F9D, 0x7157, 0x9F9E, 0x7158, 0x9F9F, 0x7159,
+	0x9FA0, 0x715A, 0x9FA1, 0x715B, 0x9FA2, 0x715D, 0x9FA3, 0x715F,
+	0x9FA4, 0x7160, 0x9FA5, 0x7161, 0x9FA6, 0x7162, 0x9FA7, 0x7163,
+	0x9FA8, 0x7165, 0x9FA9, 0x7169, 0x9FAA, 0x716A, 0x9FAB, 0x716B,
+	0x9FAC, 0x716C, 0x9FAD, 0x716D, 0x9FAE, 0x716F, 0x9FAF, 0x7170,
+	0x9FB0, 0x7171, 0x9FB1, 0x7174, 0x9FB2, 0x7175, 0x9FB3, 0x7176,
+	0x9FB4, 0x7177, 0x9FB5, 0x7179, 0x9FB6, 0x717B, 0x9FB7, 0x717C,
+	0x9FB8, 0x717E, 0x9FB9, 0x717F, 0x9FBA, 0x7180, 0x9FBB, 0x7181,
+	0x9FBC, 0x7182, 0x9FBD, 0x7183, 0x9FBE, 0x7185, 0x9FBF, 0x7186,
+	0x9FC0, 0x7187, 0x9FC1, 0x7188, 0x9FC2, 0x7189, 0x9FC3, 0x718B,
+	0x9FC4, 0x718C, 0x9FC5, 0x718D, 0x9FC6, 0x718E, 0x9FC7, 0x7190,
+	0x9FC8, 0x7191, 0x9FC9, 0x7192, 0x9FCA, 0x7193, 0x9FCB, 0x7195,
+	0x9FCC, 0x7196, 0x9FCD, 0x7197, 0x9FCE, 0x719A, 0x9FCF, 0x719B,
+	0x9FD0, 0x719C, 0x9FD1, 0x719D, 0x9FD2, 0x719E, 0x9FD3, 0x71A1,
+	0x9FD4, 0x71A2, 0x9FD5, 0x71A3, 0x9FD6, 0x71A4, 0x9FD7, 0x71A5,
+	0x9FD8, 0x71A6, 0x9FD9, 0x71A7, 0x9FDA, 0x71A9, 0x9FDB, 0x71AA,
+	0x9FDC, 0x71AB, 0x9FDD, 0x71AD, 0x9FDE, 0x71AE, 0x9FDF, 0x71AF,
+	0x9FE0, 0x71B0, 0x9FE1, 0x71B1, 0x9FE2, 0x71B2, 0x9FE3, 0x71B4,
+	0x9FE4, 0x71B6, 0x9FE5, 0x71B7, 0x9FE6, 0x71B8, 0x9FE7, 0x71BA,
+	0x9FE8, 0x71BB, 0x9FE9, 0x71BC, 0x9FEA, 0x71BD, 0x9FEB, 0x71BE,
+	0x9FEC, 0x71BF, 0x9FED, 0x71C0, 0x9FEE, 0x71C1, 0x9FEF, 0x71C2,
+	0x9FF0, 0x71C4, 0x9FF1, 0x71C5, 0x9FF2, 0x71C6, 0x9FF3, 0x71C7,
+	0x9FF4, 0x71C8, 0x9FF5, 0x71C9, 0x9FF6, 0x71CA, 0x9FF7, 0x71CB,
+	0x9FF8, 0x71CC, 0x9FF9, 0x71CD, 0x9FFA, 0x71CF, 0x9FFB, 0x71D0,
+	0x9FFC, 0x71D1, 0x9FFD, 0x71D2, 0x9FFE, 0x71D3, 0xA040, 0x71D6,
+	0xA041, 0x71D7, 0xA042, 0x71D8, 0xA043, 0x71D9, 0xA044, 0x71DA,
+	0xA045, 0x71DB, 0xA046, 0x71DC, 0xA047, 0x71DD, 0xA048, 0x71DE,
+	0xA049, 0x71DF, 0xA04A, 0x71E1, 0xA04B, 0x71E2, 0xA04C, 0x71E3,
+	0xA04D, 0x71E4, 0xA04E, 0x71E6, 0xA04F, 0x71E8, 0xA050, 0x71E9,
+	0xA051, 0x71EA, 0xA052, 0x71EB, 0xA053, 0x71EC, 0xA054, 0x71ED,
+	0xA055, 0x71EF, 0xA056, 0x71F0, 0xA057, 0x71F1, 0xA058, 0x71F2,
+	0xA059, 0x71F3, 0xA05A, 0x71F4, 0xA05B, 0x71F5, 0xA05C, 0x71F6,
+	0xA05D, 0x71F7, 0xA05E, 0x71F8, 0xA05F, 0x71FA, 0xA060, 0x71FB,
+	0xA061, 0x71FC, 0xA062, 0x71FD, 0xA063, 0x71FE, 0xA064, 0x71FF,
+	0xA065, 0x7200, 0xA066, 0x7201, 0xA067, 0x7202, 0xA068, 0x7203,
+	0xA069, 0x7204, 0xA06A, 0x7205, 0xA06B, 0x7207, 0xA06C, 0x7208,
+	0xA06D, 0x7209, 0xA06E, 0x720A, 0xA06F, 0x720B, 0xA070, 0x720C,
+	0xA071, 0x720D, 0xA072, 0x720E, 0xA073, 0x720F, 0xA074, 0x7210,
+	0xA075, 0x7211, 0xA076, 0x7212, 0xA077, 0x7213, 0xA078, 0x7214,
+	0xA079, 0x7215, 0xA07A, 0x7216, 0xA07B, 0x7217, 0xA07C, 0x7218,
+	0xA07D, 0x7219, 0xA07E, 0x721A, 0xA080, 0x721B, 0xA081, 0x721C,
+	0xA082, 0x721E, 0xA083, 0x721F, 0xA084, 0x7220, 0xA085, 0x7221,
+	0xA086, 0x7222, 0xA087, 0x7223, 0xA088, 0x7224, 0xA089, 0x7225,
+	0xA08A, 0x7226, 0xA08B, 0x7227, 0xA08C, 0x7229, 0xA08D, 0x722B,
+	0xA08E, 0x722D, 0xA08F, 0x722E, 0xA090, 0x722F, 0xA091, 0x7232,
+	0xA092, 0x7233, 0xA093, 0x7234, 0xA094, 0x723A, 0xA095, 0x723C,
+	0xA096, 0x723E, 0xA097, 0x7240, 0xA098, 0x7241, 0xA099, 0x7242,
+	0xA09A, 0x7243, 0xA09B, 0x7244, 0xA09C, 0x7245, 0xA09D, 0x7246,
+	0xA09E, 0x7249, 0xA09F, 0x724A, 0xA0A0, 0x724B, 0xA0A1, 0x724E,
+	0xA0A2, 0x724F, 0xA0A3, 0x7250, 0xA0A4, 0x7251, 0xA0A5, 0x7253,
+	0xA0A6, 0x7254, 0xA0A7, 0x7255, 0xA0A8, 0x7257, 0xA0A9, 0x7258,
+	0xA0AA, 0x725A, 0xA0AB, 0x725C, 0xA0AC, 0x725E, 0xA0AD, 0x7260,
+	0xA0AE, 0x7263, 0xA0AF, 0x7264, 0xA0B0, 0x7265, 0xA0B1, 0x7268,
+	0xA0B2, 0x726A, 0xA0B3, 0x726B, 0xA0B4, 0x726C, 0xA0B5, 0x726D,
+	0xA0B6, 0x7270, 0xA0B7, 0x7271, 0xA0B8, 0x7273, 0xA0B9, 0x7274,
+	0xA0BA, 0x7276, 0xA0BB, 0x7277, 0xA0BC, 0x7278, 0xA0BD, 0x727B,
+	0xA0BE, 0x727C, 0xA0BF, 0x727D, 0xA0C0, 0x7282, 0xA0C1, 0x7283,
+	0xA0C2, 0x7285, 0xA0C3, 0x7286, 0xA0C4, 0x7287, 0xA0C5, 0x7288,
+	0xA0C6, 0x7289, 0xA0C7, 0x728C, 0xA0C8, 0x728E, 0xA0C9, 0x7290,
+	0xA0CA, 0x7291, 0xA0CB, 0x7293, 0xA0CC, 0x7294, 0xA0CD, 0x7295,
+	0xA0CE, 0x7296, 0xA0CF, 0x7297, 0xA0D0, 0x7298, 0xA0D1, 0x7299,
+	0xA0D2, 0x729A, 0xA0D3, 0x729B, 0xA0D4, 0x729C, 0xA0D5, 0x729D,
+	0xA0D6, 0x729E, 0xA0D7, 0x72A0, 0xA0D8, 0x72A1, 0xA0D9, 0x72A2,
+	0xA0DA, 0x72A3, 0xA0DB, 0x72A4, 0xA0DC, 0x72A5, 0xA0DD, 0x72A6,
+	0xA0DE, 0x72A7, 0xA0DF, 0x72A8, 0xA0E0, 0x72A9, 0xA0E1, 0x72AA,
+	0xA0E2, 0x72AB, 0xA0E3, 0x72AE, 0xA0E4, 0x72B1, 0xA0E5, 0x72B2,
+	0xA0E6, 0x72B3, 0xA0E7, 0x72B5, 0xA0E8, 0x72BA, 0xA0E9, 0x72BB,
+	0xA0EA, 0x72BC, 0xA0EB, 0x72BD, 0xA0EC, 0x72BE, 0xA0ED, 0x72BF,
+	0xA0EE, 0x72C0, 0xA0EF, 0x72C5, 0xA0F0, 0x72C6, 0xA0F1, 0x72C7,
+	0xA0F2, 0x72C9, 0xA0F3, 0x72CA, 0xA0F4, 0x72CB, 0xA0F5, 0x72CC,
+	0xA0F6, 0x72CF, 0xA0F7, 0x72D1, 0xA0F8, 0x72D3, 0xA0F9, 0x72D4,
+	0xA0FA, 0x72D5, 0xA0FB, 0x72D6, 0xA0FC, 0x72D8, 0xA0FD, 0x72DA,
+	0xA0FE, 0x72DB, 0xA1A1, 0x3000, 0xA1A2, 0x3001, 0xA1A3, 0x3002,
+	0xA1A4, 0x00B7, 0xA1A5, 0x02C9, 0xA1A6, 0x02C7, 0xA1A7, 0x00A8,
+	0xA1A8, 0x3003, 0xA1A9, 0x3005, 0xA1AA, 0x2014, 0xA1AB, 0xFF5E,
+	0xA1AC, 0x2016, 0xA1AD, 0x2026, 0xA1AE, 0x2018, 0xA1AF, 0x2019,
+	0xA1B0, 0x201C, 0xA1B1, 0x201D, 0xA1B2, 0x3014, 0xA1B3, 0x3015,
+	0xA1B4, 0x3008, 0xA1B5, 0x3009, 0xA1B6, 0x300A, 0xA1B7, 0x300B,
+	0xA1B8, 0x300C, 0xA1B9, 0x300D, 0xA1BA, 0x300E, 0xA1BB, 0x300F,
+	0xA1BC, 0x3016, 0xA1BD, 0x3017, 0xA1BE, 0x3010, 0xA1BF, 0x3011,
+	0xA1C0, 0x00B1, 0xA1C1, 0x00D7, 0xA1C2, 0x00F7, 0xA1C3, 0x2236,
+	0xA1C4, 0x2227, 0xA1C5, 0x2228, 0xA1C6, 0x2211, 0xA1C7, 0x220F,
+	0xA1C8, 0x222A, 0xA1C9, 0x2229, 0xA1CA, 0x2208, 0xA1CB, 0x2237,
+	0xA1CC, 0x221A, 0xA1CD, 0x22A5, 0xA1CE, 0x2225, 0xA1CF, 0x2220,
+	0xA1D0, 0x2312, 0xA1D1, 0x2299, 0xA1D2, 0x222B, 0xA1D3, 0x222E,
+	0xA1D4, 0x2261, 0xA1D5, 0x224C, 0xA1D6, 0x2248, 0xA1D7, 0x223D,
+	0xA1D8, 0x221D, 0xA1D9, 0x2260, 0xA1DA, 0x226E, 0xA1DB, 0x226F,
+	0xA1DC, 0x2264, 0xA1DD, 0x2265, 0xA1DE, 0x221E, 0xA1DF, 0x2235,
+	0xA1E0, 0x2234, 0xA1E1, 0x2642, 0xA1E2, 0x2640, 0xA1E3, 0x00B0,
+	0xA1E4, 0x2032, 0xA1E5, 0x2033, 0xA1E6, 0x2103, 0xA1E7, 0xFF04,
+	0xA1E8, 0x00A4, 0xA1E9, 0xFFE0, 0xA1EA, 0xFFE1, 0xA1EB, 0x2030,
+	0xA1EC, 0x00A7, 0xA1ED, 0x2116, 0xA1EE, 0x2606, 0xA1EF, 0x2605,
+	0xA1F0, 0x25CB, 0xA1F1, 0x25CF, 0xA1F2, 0x25CE, 0xA1F3, 0x25C7,
+	0xA1F4, 0x25C6, 0xA1F5, 0x25A1, 0xA1F6, 0x25A0, 0xA1F7, 0x25B3,
+	0xA1F8, 0x25B2, 0xA1F9, 0x203B, 0xA1FA, 0x2192, 0xA1FB, 0x2190,
+	0xA1FC, 0x2191, 0xA1FD, 0x2193, 0xA1FE, 0x3013, 0xA2A1, 0x2170,
+	0xA2A2, 0x2171, 0xA2A3, 0x2172, 0xA2A4, 0x2173, 0xA2A5, 0x2174,
+	0xA2A6, 0x2175, 0xA2A7, 0x2176, 0xA2A8, 0x2177, 0xA2A9, 0x2178,
+	0xA2AA, 0x2179, 0xA2B1, 0x2488, 0xA2B2, 0x2489, 0xA2B3, 0x248A,
+	0xA2B4, 0x248B, 0xA2B5, 0x248C, 0xA2B6, 0x248D, 0xA2B7, 0x248E,
+	0xA2B8, 0x248F, 0xA2B9, 0x2490, 0xA2BA, 0x2491, 0xA2BB, 0x2492,
+	0xA2BC, 0x2493, 0xA2BD, 0x2494, 0xA2BE, 0x2495, 0xA2BF, 0x2496,
+	0xA2C0, 0x2497, 0xA2C1, 0x2498, 0xA2C2, 0x2499, 0xA2C3, 0x249A,
+	0xA2C4, 0x249B, 0xA2C5, 0x2474, 0xA2C6, 0x2475, 0xA2C7, 0x2476,
+	0xA2C8, 0x2477, 0xA2C9, 0x2478, 0xA2CA, 0x2479, 0xA2CB, 0x247A,
+	0xA2CC, 0x247B, 0xA2CD, 0x247C, 0xA2CE, 0x247D, 0xA2CF, 0x247E,
+	0xA2D0, 0x247F, 0xA2D1, 0x2480, 0xA2D2, 0x2481, 0xA2D3, 0x2482,
+	0xA2D4, 0x2483, 0xA2D5, 0x2484, 0xA2D6, 0x2485, 0xA2D7, 0x2486,
+	0xA2D8, 0x2487, 0xA2D9, 0x2460, 0xA2DA, 0x2461, 0xA2DB, 0x2462,
+	0xA2DC, 0x2463, 0xA2DD, 0x2464, 0xA2DE, 0x2465, 0xA2DF, 0x2466,
+	0xA2E0, 0x2467, 0xA2E1, 0x2468, 0xA2E2, 0x2469, 0xA2E5, 0x3220,
+	0xA2E6, 0x3221, 0xA2E7, 0x3222, 0xA2E8, 0x3223, 0xA2E9, 0x3224,
+	0xA2EA, 0x3225, 0xA2EB, 0x3226, 0xA2EC, 0x3227, 0xA2ED, 0x3228,
+	0xA2EE, 0x3229, 0xA2F1, 0x2160, 0xA2F2, 0x2161, 0xA2F3, 0x2162,
+	0xA2F4, 0x2163, 0xA2F5, 0x2164, 0xA2F6, 0x2165, 0xA2F7, 0x2166,
+	0xA2F8, 0x2167, 0xA2F9, 0x2168, 0xA2FA, 0x2169, 0xA2FB, 0x216A,
+	0xA2FC, 0x216B, 0xA3A1, 0xFF01, 0xA3A2, 0xFF02, 0xA3A3, 0xFF03,
+	0xA3A4, 0xFFE5, 0xA3A5, 0xFF05, 0xA3A6, 0xFF06, 0xA3A7, 0xFF07,
+	0xA3A8, 0xFF08, 0xA3A9, 0xFF09, 0xA3AA, 0xFF0A, 0xA3AB, 0xFF0B,
+	0xA3AC, 0xFF0C, 0xA3AD, 0xFF0D, 0xA3AE, 0xFF0E, 0xA3AF, 0xFF0F,
+	0xA3B0, 0xFF10, 0xA3B1, 0xFF11, 0xA3B2, 0xFF12, 0xA3B3, 0xFF13,
+	0xA3B4, 0xFF14, 0xA3B5, 0xFF15, 0xA3B6, 0xFF16, 0xA3B7, 0xFF17,
+	0xA3B8, 0xFF18, 0xA3B9, 0xFF19, 0xA3BA, 0xFF1A, 0xA3BB, 0xFF1B,
+	0xA3BC, 0xFF1C, 0xA3BD, 0xFF1D, 0xA3BE, 0xFF1E, 0xA3BF, 0xFF1F,
+	0xA3C0, 0xFF20, 0xA3C1, 0xFF21, 0xA3C2, 0xFF22, 0xA3C3, 0xFF23,
+	0xA3C4, 0xFF24, 0xA3C5, 0xFF25, 0xA3C6, 0xFF26, 0xA3C7, 0xFF27,
+	0xA3C8, 0xFF28, 0xA3C9, 0xFF29, 0xA3CA, 0xFF2A, 0xA3CB, 0xFF2B,
+	0xA3CC, 0xFF2C, 0xA3CD, 0xFF2D, 0xA3CE, 0xFF2E, 0xA3CF, 0xFF2F,
+	0xA3D0, 0xFF30, 0xA3D1, 0xFF31, 0xA3D2, 0xFF32, 0xA3D3, 0xFF33,
+	0xA3D4, 0xFF34, 0xA3D5, 0xFF35, 0xA3D6, 0xFF36, 0xA3D7, 0xFF37,
+	0xA3D8, 0xFF38, 0xA3D9, 0xFF39, 0xA3DA, 0xFF3A, 0xA3DB, 0xFF3B,
+	0xA3DC, 0xFF3C, 0xA3DD, 0xFF3D, 0xA3DE, 0xFF3E, 0xA3DF, 0xFF3F,
+	0xA3E0, 0xFF40, 0xA3E1, 0xFF41, 0xA3E2, 0xFF42, 0xA3E3, 0xFF43,
+	0xA3E4, 0xFF44, 0xA3E5, 0xFF45, 0xA3E6, 0xFF46, 0xA3E7, 0xFF47,
+	0xA3E8, 0xFF48, 0xA3E9, 0xFF49, 0xA3EA, 0xFF4A, 0xA3EB, 0xFF4B,
+	0xA3EC, 0xFF4C, 0xA3ED, 0xFF4D, 0xA3EE, 0xFF4E, 0xA3EF, 0xFF4F,
+	0xA3F0, 0xFF50, 0xA3F1, 0xFF51, 0xA3F2, 0xFF52, 0xA3F3, 0xFF53,
+	0xA3F4, 0xFF54, 0xA3F5, 0xFF55, 0xA3F6, 0xFF56, 0xA3F7, 0xFF57,
+	0xA3F8, 0xFF58, 0xA3F9, 0xFF59, 0xA3FA, 0xFF5A, 0xA3FB, 0xFF5B,
+	0xA3FC, 0xFF5C, 0xA3FD, 0xFF5D, 0xA3FE, 0xFFE3, 0xA4A1, 0x3041,
+	0xA4A2, 0x3042, 0xA4A3, 0x3043, 0xA4A4, 0x3044, 0xA4A5, 0x3045,
+	0xA4A6, 0x3046, 0xA4A7, 0x3047, 0xA4A8, 0x3048, 0xA4A9, 0x3049,
+	0xA4AA, 0x304A, 0xA4AB, 0x304B, 0xA4AC, 0x304C, 0xA4AD, 0x304D,
+	0xA4AE, 0x304E, 0xA4AF, 0x304F, 0xA4B0, 0x3050, 0xA4B1, 0x3051,
+	0xA4B2, 0x3052, 0xA4B3, 0x3053, 0xA4B4, 0x3054, 0xA4B5, 0x3055,
+	0xA4B6, 0x3056, 0xA4B7, 0x3057, 0xA4B8, 0x3058, 0xA4B9, 0x3059,
+	0xA4BA, 0x305A, 0xA4BB, 0x305B, 0xA4BC, 0x305C, 0xA4BD, 0x305D,
+	0xA4BE, 0x305E, 0xA4BF, 0x305F, 0xA4C0, 0x3060, 0xA4C1, 0x3061,
+	0xA4C2, 0x3062, 0xA4C3, 0x3063, 0xA4C4, 0x3064, 0xA4C5, 0x3065,
+	0xA4C6, 0x3066, 0xA4C7, 0x3067, 0xA4C8, 0x3068, 0xA4C9, 0x3069,
+	0xA4CA, 0x306A, 0xA4CB, 0x306B, 0xA4CC, 0x306C, 0xA4CD, 0x306D,
+	0xA4CE, 0x306E, 0xA4CF, 0x306F, 0xA4D0, 0x3070, 0xA4D1, 0x3071,
+	0xA4D2, 0x3072, 0xA4D3, 0x3073, 0xA4D4, 0x3074, 0xA4D5, 0x3075,
+	0xA4D6, 0x3076, 0xA4D7, 0x3077, 0xA4D8, 0x3078, 0xA4D9, 0x3079,
+	0xA4DA, 0x307A, 0xA4DB, 0x307B, 0xA4DC, 0x307C, 0xA4DD, 0x307D,
+	0xA4DE, 0x307E, 0xA4DF, 0x307F, 0xA4E0, 0x3080, 0xA4E1, 0x3081,
+	0xA4E2, 0x3082, 0xA4E3, 0x3083, 0xA4E4, 0x3084, 0xA4E5, 0x3085,
+	0xA4E6, 0x3086, 0xA4E7, 0x3087, 0xA4E8, 0x3088, 0xA4E9, 0x3089,
+	0xA4EA, 0x308A, 0xA4EB, 0x308B, 0xA4EC, 0x308C, 0xA4ED, 0x308D,
+	0xA4EE, 0x308E, 0xA4EF, 0x308F, 0xA4F0, 0x3090, 0xA4F1, 0x3091,
+	0xA4F2, 0x3092, 0xA4F3, 0x3093, 0xA5A1, 0x30A1, 0xA5A2, 0x30A2,
+	0xA5A3, 0x30A3, 0xA5A4, 0x30A4, 0xA5A5, 0x30A5, 0xA5A6, 0x30A6,
+	0xA5A7, 0x30A7, 0xA5A8, 0x30A8, 0xA5A9, 0x30A9, 0xA5AA, 0x30AA,
+	0xA5AB, 0x30AB, 0xA5AC, 0x30AC, 0xA5AD, 0x30AD, 0xA5AE, 0x30AE,
+	0xA5AF, 0x30AF, 0xA5B0, 0x30B0, 0xA5B1, 0x30B1, 0xA5B2, 0x30B2,
+	0xA5B3, 0x30B3, 0xA5B4, 0x30B4, 0xA5B5, 0x30B5, 0xA5B6, 0x30B6,
+	0xA5B7, 0x30B7, 0xA5B8, 0x30B8, 0xA5B9, 0x30B9, 0xA5BA, 0x30BA,
+	0xA5BB, 0x30BB, 0xA5BC, 0x30BC, 0xA5BD, 0x30BD, 0xA5BE, 0x30BE,
+	0xA5BF, 0x30BF, 0xA5C0, 0x30C0, 0xA5C1, 0x30C1, 0xA5C2, 0x30C2,
+	0xA5C3, 0x30C3, 0xA5C4, 0x30C4, 0xA5C5, 0x30C5, 0xA5C6, 0x30C6,
+	0xA5C7, 0x30C7, 0xA5C8, 0x30C8, 0xA5C9, 0x30C9, 0xA5CA, 0x30CA,
+	0xA5CB, 0x30CB, 0xA5CC, 0x30CC, 0xA5CD, 0x30CD, 0xA5CE, 0x30CE,
+	0xA5CF, 0x30CF, 0xA5D0, 0x30D0, 0xA5D1, 0x30D1, 0xA5D2, 0x30D2,
+	0xA5D3, 0x30D3, 0xA5D4, 0x30D4, 0xA5D5, 0x30D5, 0xA5D6, 0x30D6,
+	0xA5D7, 0x30D7, 0xA5D8, 0x30D8, 0xA5D9, 0x30D9, 0xA5DA, 0x30DA,
+	0xA5DB, 0x30DB, 0xA5DC, 0x30DC, 0xA5DD, 0x30DD, 0xA5DE, 0x30DE,
+	0xA5DF, 0x30DF, 0xA5E0, 0x30E0, 0xA5E1, 0x30E1, 0xA5E2, 0x30E2,
+	0xA5E3, 0x30E3, 0xA5E4, 0x30E4, 0xA5E5, 0x30E5, 0xA5E6, 0x30E6,
+	0xA5E7, 0x30E7, 0xA5E8, 0x30E8, 0xA5E9, 0x30E9, 0xA5EA, 0x30EA,
+	0xA5EB, 0x30EB, 0xA5EC, 0x30EC, 0xA5ED, 0x30ED, 0xA5EE, 0x30EE,
+	0xA5EF, 0x30EF, 0xA5F0, 0x30F0, 0xA5F1, 0x30F1, 0xA5F2, 0x30F2,
+	0xA5F3, 0x30F3, 0xA5F4, 0x30F4, 0xA5F5, 0x30F5, 0xA5F6, 0x30F6,
+	0xA6A1, 0x0391, 0xA6A2, 0x0392, 0xA6A3, 0x0393, 0xA6A4, 0x0394,
+	0xA6A5, 0x0395, 0xA6A6, 0x0396, 0xA6A7, 0x0397, 0xA6A8, 0x0398,
+	0xA6A9, 0x0399, 0xA6AA, 0x039A, 0xA6AB, 0x039B, 0xA6AC, 0x039C,
+	0xA6AD, 0x039D, 0xA6AE, 0x039E, 0xA6AF, 0x039F, 0xA6B0, 0x03A0,
+	0xA6B1, 0x03A1, 0xA6B2, 0x03A3, 0xA6B3, 0x03A4, 0xA6B4, 0x03A5,
+	0xA6B5, 0x03A6, 0xA6B6, 0x03A7, 0xA6B7, 0x03A8, 0xA6B8, 0x03A9,
+	0xA6C1, 0x03B1, 0xA6C2, 0x03B2, 0xA6C3, 0x03B3, 0xA6C4, 0x03B4,
+	0xA6C5, 0x03B5, 0xA6C6, 0x03B6, 0xA6C7, 0x03B7, 0xA6C8, 0x03B8,
+	0xA6C9, 0x03B9, 0xA6CA, 0x03BA, 0xA6CB, 0x03BB, 0xA6CC, 0x03BC,
+	0xA6CD, 0x03BD, 0xA6CE, 0x03BE, 0xA6CF, 0x03BF, 0xA6D0, 0x03C0,
+	0xA6D1, 0x03C1, 0xA6D2, 0x03C3, 0xA6D3, 0x03C4, 0xA6D4, 0x03C5,
+	0xA6D5, 0x03C6, 0xA6D6, 0x03C7, 0xA6D7, 0x03C8, 0xA6D8, 0x03C9,
+	0xA6E0, 0xFE35, 0xA6E1, 0xFE36, 0xA6E2, 0xFE39, 0xA6E3, 0xFE3A,
+	0xA6E4, 0xFE3F, 0xA6E5, 0xFE40, 0xA6E6, 0xFE3D, 0xA6E7, 0xFE3E,
+	0xA6E8, 0xFE41, 0xA6E9, 0xFE42, 0xA6EA, 0xFE43, 0xA6EB, 0xFE44,
+	0xA6EE, 0xFE3B, 0xA6EF, 0xFE3C, 0xA6F0, 0xFE37, 0xA6F1, 0xFE38,
+	0xA6F2, 0xFE31, 0xA6F4, 0xFE33, 0xA6F5, 0xFE34, 0xA7A1, 0x0410,
+	0xA7A2, 0x0411, 0xA7A3, 0x0412, 0xA7A4, 0x0413, 0xA7A5, 0x0414,
+	0xA7A6, 0x0415, 0xA7A7, 0x0401, 0xA7A8, 0x0416, 0xA7A9, 0x0417,
+	0xA7AA, 0x0418, 0xA7AB, 0x0419, 0xA7AC, 0x041A, 0xA7AD, 0x041B,
+	0xA7AE, 0x041C, 0xA7AF, 0x041D, 0xA7B0, 0x041E, 0xA7B1, 0x041F,
+	0xA7B2, 0x0420, 0xA7B3, 0x0421, 0xA7B4, 0x0422, 0xA7B5, 0x0423,
+	0xA7B6, 0x0424, 0xA7B7, 0x0425, 0xA7B8, 0x0426, 0xA7B9, 0x0427,
+	0xA7BA, 0x0428, 0xA7BB, 0x0429, 0xA7BC, 0x042A, 0xA7BD, 0x042B,
+	0xA7BE, 0x042C, 0xA7BF, 0x042D, 0xA7C0, 0x042E, 0xA7C1, 0x042F,
+	0xA7D1, 0x0430, 0xA7D2, 0x0431, 0xA7D3, 0x0432, 0xA7D4, 0x0433,
+	0xA7D5, 0x0434, 0xA7D6, 0x0435, 0xA7D7, 0x0451, 0xA7D8, 0x0436,
+	0xA7D9, 0x0437, 0xA7DA, 0x0438, 0xA7DB, 0x0439, 0xA7DC, 0x043A,
+	0xA7DD, 0x043B, 0xA7DE, 0x043C, 0xA7DF, 0x043D, 0xA7E0, 0x043E,
+	0xA7E1, 0x043F, 0xA7E2, 0x0440, 0xA7E3, 0x0441, 0xA7E4, 0x0442,
+	0xA7E5, 0x0443, 0xA7E6, 0x0444, 0xA7E7, 0x0445, 0xA7E8, 0x0446,
+	0xA7E9, 0x0447, 0xA7EA, 0x0448, 0xA7EB, 0x0449, 0xA7EC, 0x044A,
+	0xA7ED, 0x044B, 0xA7EE, 0x044C, 0xA7EF, 0x044D, 0xA7F0, 0x044E,
+	0xA7F1, 0x044F, 0xA840, 0x02CA, 0xA841, 0x02CB, 0xA842, 0x02D9,
+	0xA843, 0x2013, 0xA844, 0x2015, 0xA845, 0x2025, 0xA846, 0x2035,
+	0xA847, 0x2105, 0xA848, 0x2109, 0xA849, 0x2196, 0xA84A, 0x2197,
+	0xA84B, 0x2198, 0xA84C, 0x2199, 0xA84D, 0x2215, 0xA84E, 0x221F,
+	0xA84F, 0x2223, 0xA850, 0x2252, 0xA851, 0x2266, 0xA852, 0x2267,
+	0xA853, 0x22BF, 0xA854, 0x2550, 0xA855, 0x2551, 0xA856, 0x2552,
+	0xA857, 0x2553, 0xA858, 0x2554, 0xA859, 0x2555, 0xA85A, 0x2556,
+	0xA85B, 0x2557, 0xA85C, 0x2558, 0xA85D, 0x2559, 0xA85E, 0x255A,
+	0xA85F, 0x255B, 0xA860, 0x255C, 0xA861, 0x255D, 0xA862, 0x255E,
+	0xA863, 0x255F, 0xA864, 0x2560, 0xA865, 0x2561, 0xA866, 0x2562,
+	0xA867, 0x2563, 0xA868, 0x2564, 0xA869, 0x2565, 0xA86A, 0x2566,
+	0xA86B, 0x2567, 0xA86C, 0x2568, 0xA86D, 0x2569, 0xA86E, 0x256A,
+	0xA86F, 0x256B, 0xA870, 0x256C, 0xA871, 0x256D, 0xA872, 0x256E,
+	0xA873, 0x256F, 0xA874, 0x2570, 0xA875, 0x2571, 0xA876, 0x2572,
+	0xA877, 0x2573, 0xA878, 0x2581, 0xA879, 0x2582, 0xA87A, 0x2583,
+	0xA87B, 0x2584, 0xA87C, 0x2585, 0xA87D, 0x2586, 0xA87E, 0x2587,
+	0xA880, 0x2588, 0xA881, 0x2589, 0xA882, 0x258A, 0xA883, 0x258B,
+	0xA884, 0x258C, 0xA885, 0x258D, 0xA886, 0x258E, 0xA887, 0x258F,
+	0xA888, 0x2593, 0xA889, 0x2594, 0xA88A, 0x2595, 0xA88B, 0x25BC,
+	0xA88C, 0x25BD, 0xA88D, 0x25E2, 0xA88E, 0x25E3, 0xA88F, 0x25E4,
+	0xA890, 0x25E5, 0xA891, 0x2609, 0xA892, 0x2295, 0xA893, 0x3012,
+	0xA894, 0x301D, 0xA895, 0x301E, 0xA8A1, 0x0101, 0xA8A2, 0x00E1,
+	0xA8A3, 0x01CE, 0xA8A4, 0x00E0, 0xA8A5, 0x0113, 0xA8A6, 0x00E9,
+	0xA8A7, 0x011B, 0xA8A8, 0x00E8, 0xA8A9, 0x012B, 0xA8AA, 0x00ED,
+	0xA8AB, 0x01D0, 0xA8AC, 0x00EC, 0xA8AD, 0x014D, 0xA8AE, 0x00F3,
+	0xA8AF, 0x01D2, 0xA8B0, 0x00F2, 0xA8B1, 0x016B, 0xA8B2, 0x00FA,
+	0xA8B3, 0x01D4, 0xA8B4, 0x00F9, 0xA8B5, 0x01D6, 0xA8B6, 0x01D8,
+	0xA8B7, 0x01DA, 0xA8B8, 0x01DC, 0xA8B9, 0x00FC, 0xA8BA, 0x00EA,
+	0xA8BB, 0x0251, 0xA8BD, 0x0144, 0xA8BE, 0x0148, 0xA8C0, 0x0261,
+	0xA8C5, 0x3105, 0xA8C6, 0x3106, 0xA8C7, 0x3107, 0xA8C8, 0x3108,
+	0xA8C9, 0x3109, 0xA8CA, 0x310A, 0xA8CB, 0x310B, 0xA8CC, 0x310C,
+	0xA8CD, 0x310D, 0xA8CE, 0x310E, 0xA8CF, 0x310F, 0xA8D0, 0x3110,
+	0xA8D1, 0x3111, 0xA8D2, 0x3112, 0xA8D3, 0x3113, 0xA8D4, 0x3114,
+	0xA8D5, 0x3115, 0xA8D6, 0x3116, 0xA8D7, 0x3117, 0xA8D8, 0x3118,
+	0xA8D9, 0x3119, 0xA8DA, 0x311A, 0xA8DB, 0x311B, 0xA8DC, 0x311C,
+	0xA8DD, 0x311D, 0xA8DE, 0x311E, 0xA8DF, 0x311F, 0xA8E0, 0x3120,
+	0xA8E1, 0x3121, 0xA8E2, 0x3122, 0xA8E3, 0x3123, 0xA8E4, 0x3124,
+	0xA8E5, 0x3125, 0xA8E6, 0x3126, 0xA8E7, 0x3127, 0xA8E8, 0x3128,
+	0xA8E9, 0x3129, 0xA940, 0x3021, 0xA941, 0x3022, 0xA942, 0x3023,
+	0xA943, 0x3024, 0xA944, 0x3025, 0xA945, 0x3026, 0xA946, 0x3027,
+	0xA947, 0x3028, 0xA948, 0x3029, 0xA949, 0x32A3, 0xA94A, 0x338E,
+	0xA94B, 0x338F, 0xA94C, 0x339C, 0xA94D, 0x339D, 0xA94E, 0x339E,
+	0xA94F, 0x33A1, 0xA950, 0x33C4, 0xA951, 0x33CE, 0xA952, 0x33D1,
+	0xA953, 0x33D2, 0xA954, 0x33D5, 0xA955, 0xFE30, 0xA956, 0xFFE2,
+	0xA957, 0xFFE4, 0xA959, 0x2121, 0xA95A, 0x3231, 0xA95C, 0x2010,
+	0xA960, 0x30FC, 0xA961, 0x309B, 0xA962, 0x309C, 0xA963, 0x30FD,
+	0xA964, 0x30FE, 0xA965, 0x3006, 0xA966, 0x309D, 0xA967, 0x309E,
+	0xA968, 0xFE49, 0xA969, 0xFE4A, 0xA96A, 0xFE4B, 0xA96B, 0xFE4C,
+	0xA96C, 0xFE4D, 0xA96D, 0xFE4E, 0xA96E, 0xFE4F, 0xA96F, 0xFE50,
+	0xA970, 0xFE51, 0xA971, 0xFE52, 0xA972, 0xFE54, 0xA973, 0xFE55,
+	0xA974, 0xFE56, 0xA975, 0xFE57, 0xA976, 0xFE59, 0xA977, 0xFE5A,
+	0xA978, 0xFE5B, 0xA979, 0xFE5C, 0xA97A, 0xFE5D, 0xA97B, 0xFE5E,
+	0xA97C, 0xFE5F, 0xA97D, 0xFE60, 0xA97E, 0xFE61, 0xA980, 0xFE62,
+	0xA981, 0xFE63, 0xA982, 0xFE64, 0xA983, 0xFE65, 0xA984, 0xFE66,
+	0xA985, 0xFE68, 0xA986, 0xFE69, 0xA987, 0xFE6A, 0xA988, 0xFE6B,
+	0xA996, 0x3007, 0xA9A4, 0x2500, 0xA9A5, 0x2501, 0xA9A6, 0x2502,
+	0xA9A7, 0x2503, 0xA9A8, 0x2504, 0xA9A9, 0x2505, 0xA9AA, 0x2506,
+	0xA9AB, 0x2507, 0xA9AC, 0x2508, 0xA9AD, 0x2509, 0xA9AE, 0x250A,
+	0xA9AF, 0x250B, 0xA9B0, 0x250C, 0xA9B1, 0x250D, 0xA9B2, 0x250E,
+	0xA9B3, 0x250F, 0xA9B4, 0x2510, 0xA9B5, 0x2511, 0xA9B6, 0x2512,
+	0xA9B7, 0x2513, 0xA9B8, 0x2514, 0xA9B9, 0x2515, 0xA9BA, 0x2516,
+	0xA9BB, 0x2517, 0xA9BC, 0x2518, 0xA9BD, 0x2519, 0xA9BE, 0x251A,
+	0xA9BF, 0x251B, 0xA9C0, 0x251C, 0xA9C1, 0x251D, 0xA9C2, 0x251E,
+	0xA9C3, 0x251F, 0xA9C4, 0x2520, 0xA9C5, 0x2521, 0xA9C6, 0x2522,
+	0xA9C7, 0x2523, 0xA9C8, 0x2524, 0xA9C9, 0x2525, 0xA9CA, 0x2526,
+	0xA9CB, 0x2527, 0xA9CC, 0x2528, 0xA9CD, 0x2529, 0xA9CE, 0x252A,
+	0xA9CF, 0x252B, 0xA9D0, 0x252C, 0xA9D1, 0x252D, 0xA9D2, 0x252E,
+	0xA9D3, 0x252F, 0xA9D4, 0x2530, 0xA9D5, 0x2531, 0xA9D6, 0x2532,
+	0xA9D7, 0x2533, 0xA9D8, 0x2534, 0xA9D9, 0x2535, 0xA9DA, 0x2536,
+	0xA9DB, 0x2537, 0xA9DC, 0x2538, 0xA9DD, 0x2539, 0xA9DE, 0x253A,
+	0xA9DF, 0x253B, 0xA9E0, 0x253C, 0xA9E1, 0x253D, 0xA9E2, 0x253E,
+	0xA9E3, 0x253F, 0xA9E4, 0x2540, 0xA9E5, 0x2541, 0xA9E6, 0x2542,
+	0xA9E7, 0x2543, 0xA9E8, 0x2544, 0xA9E9, 0x2545, 0xA9EA, 0x2546,
+	0xA9EB, 0x2547, 0xA9EC, 0x2548, 0xA9ED, 0x2549, 0xA9EE, 0x254A,
+	0xA9EF, 0x254B, 0xAA40, 0x72DC, 0xAA41, 0x72DD, 0xAA42, 0x72DF,
+	0xAA43, 0x72E2, 0xAA44, 0x72E3, 0xAA45, 0x72E4, 0xAA46, 0x72E5,
+	0xAA47, 0x72E6, 0xAA48, 0x72E7, 0xAA49, 0x72EA, 0xAA4A, 0x72EB,
+	0xAA4B, 0x72F5, 0xAA4C, 0x72F6, 0xAA4D, 0x72F9, 0xAA4E, 0x72FD,
+	0xAA4F, 0x72FE, 0xAA50, 0x72FF, 0xAA51, 0x7300, 0xAA52, 0x7302,
+	0xAA53, 0x7304, 0xAA54, 0x7305, 0xAA55, 0x7306, 0xAA56, 0x7307,
+	0xAA57, 0x7308, 0xAA58, 0x7309, 0xAA59, 0x730B, 0xAA5A, 0x730C,
+	0xAA5B, 0x730D, 0xAA5C, 0x730F, 0xAA5D, 0x7310, 0xAA5E, 0x7311,
+	0xAA5F, 0x7312, 0xAA60, 0x7314, 0xAA61, 0x7318, 0xAA62, 0x7319,
+	0xAA63, 0x731A, 0xAA64, 0x731F, 0xAA65, 0x7320, 0xAA66, 0x7323,
+	0xAA67, 0x7324, 0xAA68, 0x7326, 0xAA69, 0x7327, 0xAA6A, 0x7328,
+	0xAA6B, 0x732D, 0xAA6C, 0x732F, 0xAA6D, 0x7330, 0xAA6E, 0x7332,
+	0xAA6F, 0x7333, 0xAA70, 0x7335, 0xAA71, 0x7336, 0xAA72, 0x733A,
+	0xAA73, 0x733B, 0xAA74, 0x733C, 0xAA75, 0x733D, 0xAA76, 0x7340,
+	0xAA77, 0x7341, 0xAA78, 0x7342, 0xAA79, 0x7343, 0xAA7A, 0x7344,
+	0xAA7B, 0x7345, 0xAA7C, 0x7346, 0xAA7D, 0x7347, 0xAA7E, 0x7348,
+	0xAA80, 0x7349, 0xAA81, 0x734A, 0xAA82, 0x734B, 0xAA83, 0x734C,
+	0xAA84, 0x734E, 0xAA85, 0x734F, 0xAA86, 0x7351, 0xAA87, 0x7353,
+	0xAA88, 0x7354, 0xAA89, 0x7355, 0xAA8A, 0x7356, 0xAA8B, 0x7358,
+	0xAA8C, 0x7359, 0xAA8D, 0x735A, 0xAA8E, 0x735B, 0xAA8F, 0x735C,
+	0xAA90, 0x735D, 0xAA91, 0x735E, 0xAA92, 0x735F, 0xAA93, 0x7361,
+	0xAA94, 0x7362, 0xAA95, 0x7363, 0xAA96, 0x7364, 0xAA97, 0x7365,
+	0xAA98, 0x7366, 0xAA99, 0x7367, 0xAA9A, 0x7368, 0xAA9B, 0x7369,
+	0xAA9C, 0x736A, 0xAA9D, 0x736B, 0xAA9E, 0x736E, 0xAA9F, 0x7370,
+	0xAAA0, 0x7371, 0xAB40, 0x7372, 0xAB41, 0x7373, 0xAB42, 0x7374,
+	0xAB43, 0x7375, 0xAB44, 0x7376, 0xAB45, 0x7377, 0xAB46, 0x7378,
+	0xAB47, 0x7379, 0xAB48, 0x737A, 0xAB49, 0x737B, 0xAB4A, 0x737C,
+	0xAB4B, 0x737D, 0xAB4C, 0x737F, 0xAB4D, 0x7380, 0xAB4E, 0x7381,
+	0xAB4F, 0x7382, 0xAB50, 0x7383, 0xAB51, 0x7385, 0xAB52, 0x7386,
+	0xAB53, 0x7388, 0xAB54, 0x738A, 0xAB55, 0x738C, 0xAB56, 0x738D,
+	0xAB57, 0x738F, 0xAB58, 0x7390, 0xAB59, 0x7392, 0xAB5A, 0x7393,
+	0xAB5B, 0x7394, 0xAB5C, 0x7395, 0xAB5D, 0x7397, 0xAB5E, 0x7398,
+	0xAB5F, 0x7399, 0xAB60, 0x739A, 0xAB61, 0x739C, 0xAB62, 0x739D,
+	0xAB63, 0x739E, 0xAB64, 0x73A0, 0xAB65, 0x73A1, 0xAB66, 0x73A3,
+	0xAB67, 0x73A4, 0xAB68, 0x73A5, 0xAB69, 0x73A6, 0xAB6A, 0x73A7,
+	0xAB6B, 0x73A8, 0xAB6C, 0x73AA, 0xAB6D, 0x73AC, 0xAB6E, 0x73AD,
+	0xAB6F, 0x73B1, 0xAB70, 0x73B4, 0xAB71, 0x73B5, 0xAB72, 0x73B6,
+	0xAB73, 0x73B8, 0xAB74, 0x73B9, 0xAB75, 0x73BC, 0xAB76, 0x73BD,
+	0xAB77, 0x73BE, 0xAB78, 0x73BF, 0xAB79, 0x73C1, 0xAB7A, 0x73C3,
+	0xAB7B, 0x73C4, 0xAB7C, 0x73C5, 0xAB7D, 0x73C6, 0xAB7E, 0x73C7,
+	0xAB80, 0x73CB, 0xAB81, 0x73CC, 0xAB82, 0x73CE, 0xAB83, 0x73D2,
+	0xAB84, 0x73D3, 0xAB85, 0x73D4, 0xAB86, 0x73D5, 0xAB87, 0x73D6,
+	0xAB88, 0x73D7, 0xAB89, 0x73D8, 0xAB8A, 0x73DA, 0xAB8B, 0x73DB,
+	0xAB8C, 0x73DC, 0xAB8D, 0x73DD, 0xAB8E, 0x73DF, 0xAB8F, 0x73E1,
+	0xAB90, 0x73E2, 0xAB91, 0x73E3, 0xAB92, 0x73E4, 0xAB93, 0x73E6,
+	0xAB94, 0x73E8, 0xAB95, 0x73EA, 0xAB96, 0x73EB, 0xAB97, 0x73EC,
+	0xAB98, 0x73EE, 0xAB99, 0x73EF, 0xAB9A, 0x73F0, 0xAB9B, 0x73F1,
+	0xAB9C, 0x73F3, 0xAB9D, 0x73F4, 0xAB9E, 0x73F5, 0xAB9F, 0x73F6,
+	0xABA0, 0x73F7, 0xAC40, 0x73F8, 0xAC41, 0x73F9, 0xAC42, 0x73FA,
+	0xAC43, 0x73FB, 0xAC44, 0x73FC, 0xAC45, 0x73FD, 0xAC46, 0x73FE,
+	0xAC47, 0x73FF, 0xAC48, 0x7400, 0xAC49, 0x7401, 0xAC4A, 0x7402,
+	0xAC4B, 0x7404, 0xAC4C, 0x7407, 0xAC4D, 0x7408, 0xAC4E, 0x740B,
+	0xAC4F, 0x740C, 0xAC50, 0x740D, 0xAC51, 0x740E, 0xAC52, 0x7411,
+	0xAC53, 0x7412, 0xAC54, 0x7413, 0xAC55, 0x7414, 0xAC56, 0x7415,
+	0xAC57, 0x7416, 0xAC58, 0x7417, 0xAC59, 0x7418, 0xAC5A, 0x7419,
+	0xAC5B, 0x741C, 0xAC5C, 0x741D, 0xAC5D, 0x741E, 0xAC5E, 0x741F,
+	0xAC5F, 0x7420, 0xAC60, 0x7421, 0xAC61, 0x7423, 0xAC62, 0x7424,
+	0xAC63, 0x7427, 0xAC64, 0x7429, 0xAC65, 0x742B, 0xAC66, 0x742D,
+	0xAC67, 0x742F, 0xAC68, 0x7431, 0xAC69, 0x7432, 0xAC6A, 0x7437,
+	0xAC6B, 0x7438, 0xAC6C, 0x7439, 0xAC6D, 0x743A, 0xAC6E, 0x743B,
+	0xAC6F, 0x743D, 0xAC70, 0x743E, 0xAC71, 0x743F, 0xAC72, 0x7440,
+	0xAC73, 0x7442, 0xAC74, 0x7443, 0xAC75, 0x7444, 0xAC76, 0x7445,
+	0xAC77, 0x7446, 0xAC78, 0x7447, 0xAC79, 0x7448, 0xAC7A, 0x7449,
+	0xAC7B, 0x744A, 0xAC7C, 0x744B, 0xAC7D, 0x744C, 0xAC7E, 0x744D,
+	0xAC80, 0x744E, 0xAC81, 0x744F, 0xAC82, 0x7450, 0xAC83, 0x7451,
+	0xAC84, 0x7452, 0xAC85, 0x7453, 0xAC86, 0x7454, 0xAC87, 0x7456,
+	0xAC88, 0x7458, 0xAC89, 0x745D, 0xAC8A, 0x7460, 0xAC8B, 0x7461,
+	0xAC8C, 0x7462, 0xAC8D, 0x7463, 0xAC8E, 0x7464, 0xAC8F, 0x7465,
+	0xAC90, 0x7466, 0xAC91, 0x7467, 0xAC92, 0x7468, 0xAC93, 0x7469,
+	0xAC94, 0x746A, 0xAC95, 0x746B, 0xAC96, 0x746C, 0xAC97, 0x746E,
+	0xAC98, 0x746F, 0xAC99, 0x7471, 0xAC9A, 0x7472, 0xAC9B, 0x7473,
+	0xAC9C, 0x7474, 0xAC9D, 0x7475, 0xAC9E, 0x7478, 0xAC9F, 0x7479,
+	0xACA0, 0x747A, 0xAD40, 0x747B, 0xAD41, 0x747C, 0xAD42, 0x747D,
+	0xAD43, 0x747F, 0xAD44, 0x7482, 0xAD45, 0x7484, 0xAD46, 0x7485,
+	0xAD47, 0x7486, 0xAD48, 0x7488, 0xAD49, 0x7489, 0xAD4A, 0x748A,
+	0xAD4B, 0x748C, 0xAD4C, 0x748D, 0xAD4D, 0x748F, 0xAD4E, 0x7491,
+	0xAD4F, 0x7492, 0xAD50, 0x7493, 0xAD51, 0x7494, 0xAD52, 0x7495,
+	0xAD53, 0x7496, 0xAD54, 0x7497, 0xAD55, 0x7498, 0xAD56, 0x7499,
+	0xAD57, 0x749A, 0xAD58, 0x749B, 0xAD59, 0x749D, 0xAD5A, 0x749F,
+	0xAD5B, 0x74A0, 0xAD5C, 0x74A1, 0xAD5D, 0x74A2, 0xAD5E, 0x74A3,
+	0xAD5F, 0x74A4, 0xAD60, 0x74A5, 0xAD61, 0x74A6, 0xAD62, 0x74AA,
+	0xAD63, 0x74AB, 0xAD64, 0x74AC, 0xAD65, 0x74AD, 0xAD66, 0x74AE,
+	0xAD67, 0x74AF, 0xAD68, 0x74B0, 0xAD69, 0x74B1, 0xAD6A, 0x74B2,
+	0xAD6B, 0x74B3, 0xAD6C, 0x74B4, 0xAD6D, 0x74B5, 0xAD6E, 0x74B6,
+	0xAD6F, 0x74B7, 0xAD70, 0x74B8, 0xAD71, 0x74B9, 0xAD72, 0x74BB,
+	0xAD73, 0x74BC, 0xAD74, 0x74BD, 0xAD75, 0x74BE, 0xAD76, 0x74BF,
+	0xAD77, 0x74C0, 0xAD78, 0x74C1, 0xAD79, 0x74C2, 0xAD7A, 0x74C3,
+	0xAD7B, 0x74C4, 0xAD7C, 0x74C5, 0xAD7D, 0x74C6, 0xAD7E, 0x74C7,
+	0xAD80, 0x74C8, 0xAD81, 0x74C9, 0xAD82, 0x74CA, 0xAD83, 0x74CB,
+	0xAD84, 0x74CC, 0xAD85, 0x74CD, 0xAD86, 0x74CE, 0xAD87, 0x74CF,
+	0xAD88, 0x74D0, 0xAD89, 0x74D1, 0xAD8A, 0x74D3, 0xAD8B, 0x74D4,
+	0xAD8C, 0x74D5, 0xAD8D, 0x74D6, 0xAD8E, 0x74D7, 0xAD8F, 0x74D8,
+	0xAD90, 0x74D9, 0xAD91, 0x74DA, 0xAD92, 0x74DB, 0xAD93, 0x74DD,
+	0xAD94, 0x74DF, 0xAD95, 0x74E1, 0xAD96, 0x74E5, 0xAD97, 0x74E7,
+	0xAD98, 0x74E8, 0xAD99, 0x74E9, 0xAD9A, 0x74EA, 0xAD9B, 0x74EB,
+	0xAD9C, 0x74EC, 0xAD9D, 0x74ED, 0xAD9E, 0x74F0, 0xAD9F, 0x74F1,
+	0xADA0, 0x74F2, 0xAE40, 0x74F3, 0xAE41, 0x74F5, 0xAE42, 0x74F8,
+	0xAE43, 0x74F9, 0xAE44, 0x74FA, 0xAE45, 0x74FB, 0xAE46, 0x74FC,
+	0xAE47, 0x74FD, 0xAE48, 0x74FE, 0xAE49, 0x7500, 0xAE4A, 0x7501,
+	0xAE4B, 0x7502, 0xAE4C, 0x7503, 0xAE4D, 0x7505, 0xAE4E, 0x7506,
+	0xAE4F, 0x7507, 0xAE50, 0x7508, 0xAE51, 0x7509, 0xAE52, 0x750A,
+	0xAE53, 0x750B, 0xAE54, 0x750C, 0xAE55, 0x750E, 0xAE56, 0x7510,
+	0xAE57, 0x7512, 0xAE58, 0x7514, 0xAE59, 0x7515, 0xAE5A, 0x7516,
+	0xAE5B, 0x7517, 0xAE5C, 0x751B, 0xAE5D, 0x751D, 0xAE5E, 0x751E,
+	0xAE5F, 0x7520, 0xAE60, 0x7521, 0xAE61, 0x7522, 0xAE62, 0x7523,
+	0xAE63, 0x7524, 0xAE64, 0x7526, 0xAE65, 0x7527, 0xAE66, 0x752A,
+	0xAE67, 0x752E, 0xAE68, 0x7534, 0xAE69, 0x7536, 0xAE6A, 0x7539,
+	0xAE6B, 0x753C, 0xAE6C, 0x753D, 0xAE6D, 0x753F, 0xAE6E, 0x7541,
+	0xAE6F, 0x7542, 0xAE70, 0x7543, 0xAE71, 0x7544, 0xAE72, 0x7546,
+	0xAE73, 0x7547, 0xAE74, 0x7549, 0xAE75, 0x754A, 0xAE76, 0x754D,
+	0xAE77, 0x7550, 0xAE78, 0x7551, 0xAE79, 0x7552, 0xAE7A, 0x7553,
+	0xAE7B, 0x7555, 0xAE7C, 0x7556, 0xAE7D, 0x7557, 0xAE7E, 0x7558,
+	0xAE80, 0x755D, 0xAE81, 0x755E, 0xAE82, 0x755F, 0xAE83, 0x7560,
+	0xAE84, 0x7561, 0xAE85, 0x7562, 0xAE86, 0x7563, 0xAE87, 0x7564,
+	0xAE88, 0x7567, 0xAE89, 0x7568, 0xAE8A, 0x7569, 0xAE8B, 0x756B,
+	0xAE8C, 0x756C, 0xAE8D, 0x756D, 0xAE8E, 0x756E, 0xAE8F, 0x756F,
+	0xAE90, 0x7570, 0xAE91, 0x7571, 0xAE92, 0x7573, 0xAE93, 0x7575,
+	0xAE94, 0x7576, 0xAE95, 0x7577, 0xAE96, 0x757A, 0xAE97, 0x757B,
+	0xAE98, 0x757C, 0xAE99, 0x757D, 0xAE9A, 0x757E, 0xAE9B, 0x7580,
+	0xAE9C, 0x7581, 0xAE9D, 0x7582, 0xAE9E, 0x7584, 0xAE9F, 0x7585,
+	0xAEA0, 0x7587, 0xAF40, 0x7588, 0xAF41, 0x7589, 0xAF42, 0x758A,
+	0xAF43, 0x758C, 0xAF44, 0x758D, 0xAF45, 0x758E, 0xAF46, 0x7590,
+	0xAF47, 0x7593, 0xAF48, 0x7595, 0xAF49, 0x7598, 0xAF4A, 0x759B,
+	0xAF4B, 0x759C, 0xAF4C, 0x759E, 0xAF4D, 0x75A2, 0xAF4E, 0x75A6,
+	0xAF4F, 0x75A7, 0xAF50, 0x75A8, 0xAF51, 0x75A9, 0xAF52, 0x75AA,
+	0xAF53, 0x75AD, 0xAF54, 0x75B6, 0xAF55, 0x75B7, 0xAF56, 0x75BA,
+	0xAF57, 0x75BB, 0xAF58, 0x75BF, 0xAF59, 0x75C0, 0xAF5A, 0x75C1,
+	0xAF5B, 0x75C6, 0xAF5C, 0x75CB, 0xAF5D, 0x75CC, 0xAF5E, 0x75CE,
+	0xAF5F, 0x75CF, 0xAF60, 0x75D0, 0xAF61, 0x75D1, 0xAF62, 0x75D3,
+	0xAF63, 0x75D7, 0xAF64, 0x75D9, 0xAF65, 0x75DA, 0xAF66, 0x75DC,
+	0xAF67, 0x75DD, 0xAF68, 0x75DF, 0xAF69, 0x75E0, 0xAF6A, 0x75E1,
+	0xAF6B, 0x75E5, 0xAF6C, 0x75E9, 0xAF6D, 0x75EC, 0xAF6E, 0x75ED,
+	0xAF6F, 0x75EE, 0xAF70, 0x75EF, 0xAF71, 0x75F2, 0xAF72, 0x75F3,
+	0xAF73, 0x75F5, 0xAF74, 0x75F6, 0xAF75, 0x75F7, 0xAF76, 0x75F8,
+	0xAF77, 0x75FA, 0xAF78, 0x75FB, 0xAF79, 0x75FD, 0xAF7A, 0x75FE,
+	0xAF7B, 0x7602, 0xAF7C, 0x7604, 0xAF7D, 0x7606, 0xAF7E, 0x7607,
+	0xAF80, 0x7608, 0xAF81, 0x7609, 0xAF82, 0x760B, 0xAF83, 0x760D,
+	0xAF84, 0x760E, 0xAF85, 0x760F, 0xAF86, 0x7611, 0xAF87, 0x7612,
+	0xAF88, 0x7613, 0xAF89, 0x7614, 0xAF8A, 0x7616, 0xAF8B, 0x761A,
+	0xAF8C, 0x761C, 0xAF8D, 0x761D, 0xAF8E, 0x761E, 0xAF8F, 0x7621,
+	0xAF90, 0x7623, 0xAF91, 0x7627, 0xAF92, 0x7628, 0xAF93, 0x762C,
+	0xAF94, 0x762E, 0xAF95, 0x762F, 0xAF96, 0x7631, 0xAF97, 0x7632,
+	0xAF98, 0x7636, 0xAF99, 0x7637, 0xAF9A, 0x7639, 0xAF9B, 0x763A,
+	0xAF9C, 0x763B, 0xAF9D, 0x763D, 0xAF9E, 0x7641, 0xAF9F, 0x7642,
+	0xAFA0, 0x7644, 0xB040, 0x7645, 0xB041, 0x7646, 0xB042, 0x7647,
+	0xB043, 0x7648, 0xB044, 0x7649, 0xB045, 0x764A, 0xB046, 0x764B,
+	0xB047, 0x764E, 0xB048, 0x764F, 0xB049, 0x7650, 0xB04A, 0x7651,
+	0xB04B, 0x7652, 0xB04C, 0x7653, 0xB04D, 0x7655, 0xB04E, 0x7657,
+	0xB04F, 0x7658, 0xB050, 0x7659, 0xB051, 0x765A, 0xB052, 0x765B,
+	0xB053, 0x765D, 0xB054, 0x765F, 0xB055, 0x7660, 0xB056, 0x7661,
+	0xB057, 0x7662, 0xB058, 0x7664, 0xB059, 0x7665, 0xB05A, 0x7666,
+	0xB05B, 0x7667, 0xB05C, 0x7668, 0xB05D, 0x7669, 0xB05E, 0x766A,
+	0xB05F, 0x766C, 0xB060, 0x766D, 0xB061, 0x766E, 0xB062, 0x7670,
+	0xB063, 0x7671, 0xB064, 0x7672, 0xB065, 0x7673, 0xB066, 0x7674,
+	0xB067, 0x7675, 0xB068, 0x7676, 0xB069, 0x7677, 0xB06A, 0x7679,
+	0xB06B, 0x767A, 0xB06C, 0x767C, 0xB06D, 0x767F, 0xB06E, 0x7680,
+	0xB06F, 0x7681, 0xB070, 0x7683, 0xB071, 0x7685, 0xB072, 0x7689,
+	0xB073, 0x768A, 0xB074, 0x768C, 0xB075, 0x768D, 0xB076, 0x768F,
+	0xB077, 0x7690, 0xB078, 0x7692, 0xB079, 0x7694, 0xB07A, 0x7695,
+	0xB07B, 0x7697, 0xB07C, 0x7698, 0xB07D, 0x769A, 0xB07E, 0x769B,
+	0xB080, 0x769C, 0xB081, 0x769D, 0xB082, 0x769E, 0xB083, 0x769F,
+	0xB084, 0x76A0, 0xB085, 0x76A1, 0xB086, 0x76A2, 0xB087, 0x76A3,
+	0xB088, 0x76A5, 0xB089, 0x76A6, 0xB08A, 0x76A7, 0xB08B, 0x76A8,
+	0xB08C, 0x76A9, 0xB08D, 0x76AA, 0xB08E, 0x76AB, 0xB08F, 0x76AC,
+	0xB090, 0x76AD, 0xB091, 0x76AF, 0xB092, 0x76B0, 0xB093, 0x76B3,
+	0xB094, 0x76B5, 0xB095, 0x76B6, 0xB096, 0x76B7, 0xB097, 0x76B8,
+	0xB098, 0x76B9, 0xB099, 0x76BA, 0xB09A, 0x76BB, 0xB09B, 0x76BC,
+	0xB09C, 0x76BD, 0xB09D, 0x76BE, 0xB09E, 0x76C0, 0xB09F, 0x76C1,
+	0xB0A0, 0x76C3, 0xB0A1, 0x554A, 0xB0A2, 0x963F, 0xB0A3, 0x57C3,
+	0xB0A4, 0x6328, 0xB0A5, 0x54CE, 0xB0A6, 0x5509, 0xB0A7, 0x54C0,
+	0xB0A8, 0x7691, 0xB0A9, 0x764C, 0xB0AA, 0x853C, 0xB0AB, 0x77EE,
+	0xB0AC, 0x827E, 0xB0AD, 0x788D, 0xB0AE, 0x7231, 0xB0AF, 0x9698,
+	0xB0B0, 0x978D, 0xB0B1, 0x6C28, 0xB0B2, 0x5B89, 0xB0B3, 0x4FFA,
+	0xB0B4, 0x6309, 0xB0B5, 0x6697, 0xB0B6, 0x5CB8, 0xB0B7, 0x80FA,
+	0xB0B8, 0x6848, 0xB0B9, 0x80AE, 0xB0BA, 0x6602, 0xB0BB, 0x76CE,
+	0xB0BC, 0x51F9, 0xB0BD, 0x6556, 0xB0BE, 0x71AC, 0xB0BF, 0x7FF1,
+	0xB0C0, 0x8884, 0xB0C1, 0x50B2, 0xB0C2, 0x5965, 0xB0C3, 0x61CA,
+	0xB0C4, 0x6FB3, 0xB0C5, 0x82AD, 0xB0C6, 0x634C, 0xB0C7, 0x6252,
+	0xB0C8, 0x53ED, 0xB0C9, 0x5427, 0xB0CA, 0x7B06, 0xB0CB, 0x516B,
+	0xB0CC, 0x75A4, 0xB0CD, 0x5DF4, 0xB0CE, 0x62D4, 0xB0CF, 0x8DCB,
+	0xB0D0, 0x9776, 0xB0D1, 0x628A, 0xB0D2, 0x8019, 0xB0D3, 0x575D,
+	0xB0D4, 0x9738, 0xB0D5, 0x7F62, 0xB0D6, 0x7238, 0xB0D7, 0x767D,
+	0xB0D8, 0x67CF, 0xB0D9, 0x767E, 0xB0DA, 0x6446, 0xB0DB, 0x4F70,
+	0xB0DC, 0x8D25, 0xB0DD, 0x62DC, 0xB0DE, 0x7A17, 0xB0DF, 0x6591,
+	0xB0E0, 0x73ED, 0xB0E1, 0x642C, 0xB0E2, 0x6273, 0xB0E3, 0x822C,
+	0xB0E4, 0x9881, 0xB0E5, 0x677F, 0xB0E6, 0x7248, 0xB0E7, 0x626E,
+	0xB0E8, 0x62CC, 0xB0E9, 0x4F34, 0xB0EA, 0x74E3, 0xB0EB, 0x534A,
+	0xB0EC, 0x529E, 0xB0ED, 0x7ECA, 0xB0EE, 0x90A6, 0xB0EF, 0x5E2E,
+	0xB0F0, 0x6886, 0xB0F1, 0x699C, 0xB0F2, 0x8180, 0xB0F3, 0x7ED1,
+	0xB0F4, 0x68D2, 0xB0F5, 0x78C5, 0xB0F6, 0x868C, 0xB0F7, 0x9551,
+	0xB0F8, 0x508D, 0xB0F9, 0x8C24, 0xB0FA, 0x82DE, 0xB0FB, 0x80DE,
+	0xB0FC, 0x5305, 0xB0FD, 0x8912, 0xB0FE, 0x5265, 0xB140, 0x76C4,
+	0xB141, 0x76C7, 0xB142, 0x76C9, 0xB143, 0x76CB, 0xB144, 0x76CC,
+	0xB145, 0x76D3, 0xB146, 0x76D5, 0xB147, 0x76D9, 0xB148, 0x76DA,
+	0xB149, 0x76DC, 0xB14A, 0x76DD, 0xB14B, 0x76DE, 0xB14C, 0x76E0,
+	0xB14D, 0x76E1, 0xB14E, 0x76E2, 0xB14F, 0x76E3, 0xB150, 0x76E4,
+	0xB151, 0x76E6, 0xB152, 0x76E7, 0xB153, 0x76E8, 0xB154, 0x76E9,
+	0xB155, 0x76EA, 0xB156, 0x76EB, 0xB157, 0x76EC, 0xB158, 0x76ED,
+	0xB159, 0x76F0, 0xB15A, 0x76F3, 0xB15B, 0x76F5, 0xB15C, 0x76F6,
+	0xB15D, 0x76F7, 0xB15E, 0x76FA, 0xB15F, 0x76FB, 0xB160, 0x76FD,
+	0xB161, 0x76FF, 0xB162, 0x7700, 0xB163, 0x7702, 0xB164, 0x7703,
+	0xB165, 0x7705, 0xB166, 0x7706, 0xB167, 0x770A, 0xB168, 0x770C,
+	0xB169, 0x770E, 0xB16A, 0x770F, 0xB16B, 0x7710, 0xB16C, 0x7711,
+	0xB16D, 0x7712, 0xB16E, 0x7713, 0xB16F, 0x7714, 0xB170, 0x7715,
+	0xB171, 0x7716, 0xB172, 0x7717, 0xB173, 0x7718, 0xB174, 0x771B,
+	0xB175, 0x771C, 0xB176, 0x771D, 0xB177, 0x771E, 0xB178, 0x7721,
+	0xB179, 0x7723, 0xB17A, 0x7724, 0xB17B, 0x7725, 0xB17C, 0x7727,
+	0xB17D, 0x772A, 0xB17E, 0x772B, 0xB180, 0x772C, 0xB181, 0x772E,
+	0xB182, 0x7730, 0xB183, 0x7731, 0xB184, 0x7732, 0xB185, 0x7733,
+	0xB186, 0x7734, 0xB187, 0x7739, 0xB188, 0x773B, 0xB189, 0x773D,
+	0xB18A, 0x773E, 0xB18B, 0x773F, 0xB18C, 0x7742, 0xB18D, 0x7744,
+	0xB18E, 0x7745, 0xB18F, 0x7746, 0xB190, 0x7748, 0xB191, 0x7749,
+	0xB192, 0x774A, 0xB193, 0x774B, 0xB194, 0x774C, 0xB195, 0x774D,
+	0xB196, 0x774E, 0xB197, 0x774F, 0xB198, 0x7752, 0xB199, 0x7753,
+	0xB19A, 0x7754, 0xB19B, 0x7755, 0xB19C, 0x7756, 0xB19D, 0x7757,
+	0xB19E, 0x7758, 0xB19F, 0x7759, 0xB1A0, 0x775C, 0xB1A1, 0x8584,
+	0xB1A2, 0x96F9, 0xB1A3, 0x4FDD, 0xB1A4, 0x5821, 0xB1A5, 0x9971,
+	0xB1A6, 0x5B9D, 0xB1A7, 0x62B1, 0xB1A8, 0x62A5, 0xB1A9, 0x66B4,
+	0xB1AA, 0x8C79, 0xB1AB, 0x9C8D, 0xB1AC, 0x7206, 0xB1AD, 0x676F,
+	0xB1AE, 0x7891, 0xB1AF, 0x60B2, 0xB1B0, 0x5351, 0xB1B1, 0x5317,
+	0xB1B2, 0x8F88, 0xB1B3, 0x80CC, 0xB1B4, 0x8D1D, 0xB1B5, 0x94A1,
+	0xB1B6, 0x500D, 0xB1B7, 0x72C8, 0xB1B8, 0x5907, 0xB1B9, 0x60EB,
+	0xB1BA, 0x7119, 0xB1BB, 0x88AB, 0xB1BC, 0x5954, 0xB1BD, 0x82EF,
+	0xB1BE, 0x672C, 0xB1BF, 0x7B28, 0xB1C0, 0x5D29, 0xB1C1, 0x7EF7,
+	0xB1C2, 0x752D, 0xB1C3, 0x6CF5, 0xB1C4, 0x8E66, 0xB1C5, 0x8FF8,
+	0xB1C6, 0x903C, 0xB1C7, 0x9F3B, 0xB1C8, 0x6BD4, 0xB1C9, 0x9119,
+	0xB1CA, 0x7B14, 0xB1CB, 0x5F7C, 0xB1CC, 0x78A7, 0xB1CD, 0x84D6,
+	0xB1CE, 0x853D, 0xB1CF, 0x6BD5, 0xB1D0, 0x6BD9, 0xB1D1, 0x6BD6,
+	0xB1D2, 0x5E01, 0xB1D3, 0x5E87, 0xB1D4, 0x75F9, 0xB1D5, 0x95ED,
+	0xB1D6, 0x655D, 0xB1D7, 0x5F0A, 0xB1D8, 0x5FC5, 0xB1D9, 0x8F9F,
+	0xB1DA, 0x58C1, 0xB1DB, 0x81C2, 0xB1DC, 0x907F, 0xB1DD, 0x965B,
+	0xB1DE, 0x97AD, 0xB1DF, 0x8FB9, 0xB1E0, 0x7F16, 0xB1E1, 0x8D2C,
+	0xB1E2, 0x6241, 0xB1E3, 0x4FBF, 0xB1E4, 0x53D8, 0xB1E5, 0x535E,
+	0xB1E6, 0x8FA8, 0xB1E7, 0x8FA9, 0xB1E8, 0x8FAB, 0xB1E9, 0x904D,
+	0xB1EA, 0x6807, 0xB1EB, 0x5F6A, 0xB1EC, 0x8198, 0xB1ED, 0x8868,
+	0xB1EE, 0x9CD6, 0xB1EF, 0x618B, 0xB1F0, 0x522B, 0xB1F1, 0x762A,
+	0xB1F2, 0x5F6C, 0xB1F3, 0x658C, 0xB1F4, 0x6FD2, 0xB1F5, 0x6EE8,
+	0xB1F6, 0x5BBE, 0xB1F7, 0x6448, 0xB1F8, 0x5175, 0xB1F9, 0x51B0,
+	0xB1FA, 0x67C4, 0xB1FB, 0x4E19, 0xB1FC, 0x79C9, 0xB1FD, 0x997C,
+	0xB1FE, 0x70B3, 0xB240, 0x775D, 0xB241, 0x775E, 0xB242, 0x775F,
+	0xB243, 0x7760, 0xB244, 0x7764, 0xB245, 0x7767, 0xB246, 0x7769,
+	0xB247, 0x776A, 0xB248, 0x776D, 0xB249, 0x776E, 0xB24A, 0x776F,
+	0xB24B, 0x7770, 0xB24C, 0x7771, 0xB24D, 0x7772, 0xB24E, 0x7773,
+	0xB24F, 0x7774, 0xB250, 0x7775, 0xB251, 0x7776, 0xB252, 0x7777,
+	0xB253, 0x7778, 0xB254, 0x777A, 0xB255, 0x777B, 0xB256, 0x777C,
+	0xB257, 0x7781, 0xB258, 0x7782, 0xB259, 0x7783, 0xB25A, 0x7786,
+	0xB25B, 0x7787, 0xB25C, 0x7788, 0xB25D, 0x7789, 0xB25E, 0x778A,
+	0xB25F, 0x778B, 0xB260, 0x778F, 0xB261, 0x7790, 0xB262, 0x7793,
+	0xB263, 0x7794, 0xB264, 0x7795, 0xB265, 0x7796, 0xB266, 0x7797,
+	0xB267, 0x7798, 0xB268, 0x7799, 0xB269, 0x779A, 0xB26A, 0x779B,
+	0xB26B, 0x779C, 0xB26C, 0x779D, 0xB26D, 0x779E, 0xB26E, 0x77A1,
+	0xB26F, 0x77A3, 0xB270, 0x77A4, 0xB271, 0x77A6, 0xB272, 0x77A8,
+	0xB273, 0x77AB, 0xB274, 0x77AD, 0xB275, 0x77AE, 0xB276, 0x77AF,
+	0xB277, 0x77B1, 0xB278, 0x77B2, 0xB279, 0x77B4, 0xB27A, 0x77B6,
+	0xB27B, 0x77B7, 0xB27C, 0x77B8, 0xB27D, 0x77B9, 0xB27E, 0x77BA,
+	0xB280, 0x77BC, 0xB281, 0x77BE, 0xB282, 0x77C0, 0xB283, 0x77C1,
+	0xB284, 0x77C2, 0xB285, 0x77C3, 0xB286, 0x77C4, 0xB287, 0x77C5,
+	0xB288, 0x77C6, 0xB289, 0x77C7, 0xB28A, 0x77C8, 0xB28B, 0x77C9,
+	0xB28C, 0x77CA, 0xB28D, 0x77CB, 0xB28E, 0x77CC, 0xB28F, 0x77CE,
+	0xB290, 0x77CF, 0xB291, 0x77D0, 0xB292, 0x77D1, 0xB293, 0x77D2,
+	0xB294, 0x77D3, 0xB295, 0x77D4, 0xB296, 0x77D5, 0xB297, 0x77D6,
+	0xB298, 0x77D8, 0xB299, 0x77D9, 0xB29A, 0x77DA, 0xB29B, 0x77DD,
+	0xB29C, 0x77DE, 0xB29D, 0x77DF, 0xB29E, 0x77E0, 0xB29F, 0x77E1,
+	0xB2A0, 0x77E4, 0xB2A1, 0x75C5, 0xB2A2, 0x5E76, 0xB2A3, 0x73BB,
+	0xB2A4, 0x83E0, 0xB2A5, 0x64AD, 0xB2A6, 0x62E8, 0xB2A7, 0x94B5,
+	0xB2A8, 0x6CE2, 0xB2A9, 0x535A, 0xB2AA, 0x52C3, 0xB2AB, 0x640F,
+	0xB2AC, 0x94C2, 0xB2AD, 0x7B94, 0xB2AE, 0x4F2F, 0xB2AF, 0x5E1B,
+	0xB2B0, 0x8236, 0xB2B1, 0x8116, 0xB2B2, 0x818A, 0xB2B3, 0x6E24,
+	0xB2B4, 0x6CCA, 0xB2B5, 0x9A73, 0xB2B6, 0x6355, 0xB2B7, 0x535C,
+	0xB2B8, 0x54FA, 0xB2B9, 0x8865, 0xB2BA, 0x57E0, 0xB2BB, 0x4E0D,
+	0xB2BC, 0x5E03, 0xB2BD, 0x6B65, 0xB2BE, 0x7C3F, 0xB2BF, 0x90E8,
+	0xB2C0, 0x6016, 0xB2C1, 0x64E6, 0xB2C2, 0x731C, 0xB2C3, 0x88C1,
+	0xB2C4, 0x6750, 0xB2C5, 0x624D, 0xB2C6, 0x8D22, 0xB2C7, 0x776C,
+	0xB2C8, 0x8E29, 0xB2C9, 0x91C7, 0xB2CA, 0x5F69, 0xB2CB, 0x83DC,
+	0xB2CC, 0x8521, 0xB2CD, 0x9910, 0xB2CE, 0x53C2, 0xB2CF, 0x8695,
+	0xB2D0, 0x6B8B, 0xB2D1, 0x60ED, 0xB2D2, 0x60E8, 0xB2D3, 0x707F,
+	0xB2D4, 0x82CD, 0xB2D5, 0x8231, 0xB2D6, 0x4ED3, 0xB2D7, 0x6CA7,
+	0xB2D8, 0x85CF, 0xB2D9, 0x64CD, 0xB2DA, 0x7CD9, 0xB2DB, 0x69FD,
+	0xB2DC, 0x66F9, 0xB2DD, 0x8349, 0xB2DE, 0x5395, 0xB2DF, 0x7B56,
+	0xB2E0, 0x4FA7, 0xB2E1, 0x518C, 0xB2E2, 0x6D4B, 0xB2E3, 0x5C42,
+	0xB2E4, 0x8E6D, 0xB2E5, 0x63D2, 0xB2E6, 0x53C9, 0xB2E7, 0x832C,
+	0xB2E8, 0x8336, 0xB2E9, 0x67E5, 0xB2EA, 0x78B4, 0xB2EB, 0x643D,
+	0xB2EC, 0x5BDF, 0xB2ED, 0x5C94, 0xB2EE, 0x5DEE, 0xB2EF, 0x8BE7,
+	0xB2F0, 0x62C6, 0xB2F1, 0x67F4, 0xB2F2, 0x8C7A, 0xB2F3, 0x6400,
+	0xB2F4, 0x63BA, 0xB2F5, 0x8749, 0xB2F6, 0x998B, 0xB2F7, 0x8C17,
+	0xB2F8, 0x7F20, 0xB2F9, 0x94F2, 0xB2FA, 0x4EA7, 0xB2FB, 0x9610,
+	0xB2FC, 0x98A4, 0xB2FD, 0x660C, 0xB2FE, 0x7316, 0xB340, 0x77E6,
+	0xB341, 0x77E8, 0xB342, 0x77EA, 0xB343, 0x77EF, 0xB344, 0x77F0,
+	0xB345, 0x77F1, 0xB346, 0x77F2, 0xB347, 0x77F4, 0xB348, 0x77F5,
+	0xB349, 0x77F7, 0xB34A, 0x77F9, 0xB34B, 0x77FA, 0xB34C, 0x77FB,
+	0xB34D, 0x77FC, 0xB34E, 0x7803, 0xB34F, 0x7804, 0xB350, 0x7805,
+	0xB351, 0x7806, 0xB352, 0x7807, 0xB353, 0x7808, 0xB354, 0x780A,
+	0xB355, 0x780B, 0xB356, 0x780E, 0xB357, 0x780F, 0xB358, 0x7810,
+	0xB359, 0x7813, 0xB35A, 0x7815, 0xB35B, 0x7819, 0xB35C, 0x781B,
+	0xB35D, 0x781E, 0xB35E, 0x7820, 0xB35F, 0x7821, 0xB360, 0x7822,
+	0xB361, 0x7824, 0xB362, 0x7828, 0xB363, 0x782A, 0xB364, 0x782B,
+	0xB365, 0x782E, 0xB366, 0x782F, 0xB367, 0x7831, 0xB368, 0x7832,
+	0xB369, 0x7833, 0xB36A, 0x7835, 0xB36B, 0x7836, 0xB36C, 0x783D,
+	0xB36D, 0x783F, 0xB36E, 0x7841, 0xB36F, 0x7842, 0xB370, 0x7843,
+	0xB371, 0x7844, 0xB372, 0x7846, 0xB373, 0x7848, 0xB374, 0x7849,
+	0xB375, 0x784A, 0xB376, 0x784B, 0xB377, 0x784D, 0xB378, 0x784F,
+	0xB379, 0x7851, 0xB37A, 0x7853, 0xB37B, 0x7854, 0xB37C, 0x7858,
+	0xB37D, 0x7859, 0xB37E, 0x785A, 0xB380, 0x785B, 0xB381, 0x785C,
+	0xB382, 0x785E, 0xB383, 0x785F, 0xB384, 0x7860, 0xB385, 0x7861,
+	0xB386, 0x7862, 0xB387, 0x7863, 0xB388, 0x7864, 0xB389, 0x7865,
+	0xB38A, 0x7866, 0xB38B, 0x7867, 0xB38C, 0x7868, 0xB38D, 0x7869,
+	0xB38E, 0x786F, 0xB38F, 0x7870, 0xB390, 0x7871, 0xB391, 0x7872,
+	0xB392, 0x7873, 0xB393, 0x7874, 0xB394, 0x7875, 0xB395, 0x7876,
+	0xB396, 0x7878, 0xB397, 0x7879, 0xB398, 0x787A, 0xB399, 0x787B,
+	0xB39A, 0x787D, 0xB39B, 0x787E, 0xB39C, 0x787F, 0xB39D, 0x7880,
+	0xB39E, 0x7881, 0xB39F, 0x7882, 0xB3A0, 0x7883, 0xB3A1, 0x573A,
+	0xB3A2, 0x5C1D, 0xB3A3, 0x5E38, 0xB3A4, 0x957F, 0xB3A5, 0x507F,
+	0xB3A6, 0x80A0, 0xB3A7, 0x5382, 0xB3A8, 0x655E, 0xB3A9, 0x7545,
+	0xB3AA, 0x5531, 0xB3AB, 0x5021, 0xB3AC, 0x8D85, 0xB3AD, 0x6284,
+	0xB3AE, 0x949E, 0xB3AF, 0x671D, 0xB3B0, 0x5632, 0xB3B1, 0x6F6E,
+	0xB3B2, 0x5DE2, 0xB3B3, 0x5435, 0xB3B4, 0x7092, 0xB3B5, 0x8F66,
+	0xB3B6, 0x626F, 0xB3B7, 0x64A4, 0xB3B8, 0x63A3, 0xB3B9, 0x5F7B,
+	0xB3BA, 0x6F88, 0xB3BB, 0x90F4, 0xB3BC, 0x81E3, 0xB3BD, 0x8FB0,
+	0xB3BE, 0x5C18, 0xB3BF, 0x6668, 0xB3C0, 0x5FF1, 0xB3C1, 0x6C89,
+	0xB3C2, 0x9648, 0xB3C3, 0x8D81, 0xB3C4, 0x886C, 0xB3C5, 0x6491,
+	0xB3C6, 0x79F0, 0xB3C7, 0x57CE, 0xB3C8, 0x6A59, 0xB3C9, 0x6210,
+	0xB3CA, 0x5448, 0xB3CB, 0x4E58, 0xB3CC, 0x7A0B, 0xB3CD, 0x60E9,
+	0xB3CE, 0x6F84, 0xB3CF, 0x8BDA, 0xB3D0, 0x627F, 0xB3D1, 0x901E,
+	0xB3D2, 0x9A8B, 0xB3D3, 0x79E4, 0xB3D4, 0x5403, 0xB3D5, 0x75F4,
+	0xB3D6, 0x6301, 0xB3D7, 0x5319, 0xB3D8, 0x6C60, 0xB3D9, 0x8FDF,
+	0xB3DA, 0x5F1B, 0xB3DB, 0x9A70, 0xB3DC, 0x803B, 0xB3DD, 0x9F7F,
+	0xB3DE, 0x4F88, 0xB3DF, 0x5C3A, 0xB3E0, 0x8D64, 0xB3E1, 0x7FC5,
+	0xB3E2, 0x65A5, 0xB3E3, 0x70BD, 0xB3E4, 0x5145, 0xB3E5, 0x51B2,
+	0xB3E6, 0x866B, 0xB3E7, 0x5D07, 0xB3E8, 0x5BA0, 0xB3E9, 0x62BD,
+	0xB3EA, 0x916C, 0xB3EB, 0x7574, 0xB3EC, 0x8E0C, 0xB3ED, 0x7A20,
+	0xB3EE, 0x6101, 0xB3EF, 0x7B79, 0xB3F0, 0x4EC7, 0xB3F1, 0x7EF8,
+	0xB3F2, 0x7785, 0xB3F3, 0x4E11, 0xB3F4, 0x81ED, 0xB3F5, 0x521D,
+	0xB3F6, 0x51FA, 0xB3F7, 0x6A71, 0xB3F8, 0x53A8, 0xB3F9, 0x8E87,
+	0xB3FA, 0x9504, 0xB3FB, 0x96CF, 0xB3FC, 0x6EC1, 0xB3FD, 0x9664,
+	0xB3FE, 0x695A, 0xB440, 0x7884, 0xB441, 0x7885, 0xB442, 0x7886,
+	0xB443, 0x7888, 0xB444, 0x788A, 0xB445, 0x788B, 0xB446, 0x788F,
+	0xB447, 0x7890, 0xB448, 0x7892, 0xB449, 0x7894, 0xB44A, 0x7895,
+	0xB44B, 0x7896, 0xB44C, 0x7899, 0xB44D, 0x789D, 0xB44E, 0x789E,
+	0xB44F, 0x78A0, 0xB450, 0x78A2, 0xB451, 0x78A4, 0xB452, 0x78A6,
+	0xB453, 0x78A8, 0xB454, 0x78A9, 0xB455, 0x78AA, 0xB456, 0x78AB,
+	0xB457, 0x78AC, 0xB458, 0x78AD, 0xB459, 0x78AE, 0xB45A, 0x78AF,
+	0xB45B, 0x78B5, 0xB45C, 0x78B6, 0xB45D, 0x78B7, 0xB45E, 0x78B8,
+	0xB45F, 0x78BA, 0xB460, 0x78BB, 0xB461, 0x78BC, 0xB462, 0x78BD,
+	0xB463, 0x78BF, 0xB464, 0x78C0, 0xB465, 0x78C2, 0xB466, 0x78C3,
+	0xB467, 0x78C4, 0xB468, 0x78C6, 0xB469, 0x78C7, 0xB46A, 0x78C8,
+	0xB46B, 0x78CC, 0xB46C, 0x78CD, 0xB46D, 0x78CE, 0xB46E, 0x78CF,
+	0xB46F, 0x78D1, 0xB470, 0x78D2, 0xB471, 0x78D3, 0xB472, 0x78D6,
+	0xB473, 0x78D7, 0xB474, 0x78D8, 0xB475, 0x78DA, 0xB476, 0x78DB,
+	0xB477, 0x78DC, 0xB478, 0x78DD, 0xB479, 0x78DE, 0xB47A, 0x78DF,
+	0xB47B, 0x78E0, 0xB47C, 0x78E1, 0xB47D, 0x78E2, 0xB47E, 0x78E3,
+	0xB480, 0x78E4, 0xB481, 0x78E5, 0xB482, 0x78E6, 0xB483, 0x78E7,
+	0xB484, 0x78E9, 0xB485, 0x78EA, 0xB486, 0x78EB, 0xB487, 0x78ED,
+	0xB488, 0x78EE, 0xB489, 0x78EF, 0xB48A, 0x78F0, 0xB48B, 0x78F1,
+	0xB48C, 0x78F3, 0xB48D, 0x78F5, 0xB48E, 0x78F6, 0xB48F, 0x78F8,
+	0xB490, 0x78F9, 0xB491, 0x78FB, 0xB492, 0x78FC, 0xB493, 0x78FD,
+	0xB494, 0x78FE, 0xB495, 0x78FF, 0xB496, 0x7900, 0xB497, 0x7902,
+	0xB498, 0x7903, 0xB499, 0x7904, 0xB49A, 0x7906, 0xB49B, 0x7907,
+	0xB49C, 0x7908, 0xB49D, 0x7909, 0xB49E, 0x790A, 0xB49F, 0x790B,
+	0xB4A0, 0x790C, 0xB4A1, 0x7840, 0xB4A2, 0x50A8, 0xB4A3, 0x77D7,
+	0xB4A4, 0x6410, 0xB4A5, 0x89E6, 0xB4A6, 0x5904, 0xB4A7, 0x63E3,
+	0xB4A8, 0x5DDD, 0xB4A9, 0x7A7F, 0xB4AA, 0x693D, 0xB4AB, 0x4F20,
+	0xB4AC, 0x8239, 0xB4AD, 0x5598, 0xB4AE, 0x4E32, 0xB4AF, 0x75AE,
+	0xB4B0, 0x7A97, 0xB4B1, 0x5E62, 0xB4B2, 0x5E8A, 0xB4B3, 0x95EF,
+	0xB4B4, 0x521B, 0xB4B5, 0x5439, 0xB4B6, 0x708A, 0xB4B7, 0x6376,
+	0xB4B8, 0x9524, 0xB4B9, 0x5782, 0xB4BA, 0x6625, 0xB4BB, 0x693F,
+	0xB4BC, 0x9187, 0xB4BD, 0x5507, 0xB4BE, 0x6DF3, 0xB4BF, 0x7EAF,
+	0xB4C0, 0x8822, 0xB4C1, 0x6233, 0xB4C2, 0x7EF0, 0xB4C3, 0x75B5,
+	0xB4C4, 0x8328, 0xB4C5, 0x78C1, 0xB4C6, 0x96CC, 0xB4C7, 0x8F9E,
+	0xB4C8, 0x6148, 0xB4C9, 0x74F7, 0xB4CA, 0x8BCD, 0xB4CB, 0x6B64,
+	0xB4CC, 0x523A, 0xB4CD, 0x8D50, 0xB4CE, 0x6B21, 0xB4CF, 0x806A,
+	0xB4D0, 0x8471, 0xB4D1, 0x56F1, 0xB4D2, 0x5306, 0xB4D3, 0x4ECE,
+	0xB4D4, 0x4E1B, 0xB4D5, 0x51D1, 0xB4D6, 0x7C97, 0xB4D7, 0x918B,
+	0xB4D8, 0x7C07, 0xB4D9, 0x4FC3, 0xB4DA, 0x8E7F, 0xB4DB, 0x7BE1,
+	0xB4DC, 0x7A9C, 0xB4DD, 0x6467, 0xB4DE, 0x5D14, 0xB4DF, 0x50AC,
+	0xB4E0, 0x8106, 0xB4E1, 0x7601, 0xB4E2, 0x7CB9, 0xB4E3, 0x6DEC,
+	0xB4E4, 0x7FE0, 0xB4E5, 0x6751, 0xB4E6, 0x5B58, 0xB4E7, 0x5BF8,
+	0xB4E8, 0x78CB, 0xB4E9, 0x64AE, 0xB4EA, 0x6413, 0xB4EB, 0x63AA,
+	0xB4EC, 0x632B, 0xB4ED, 0x9519, 0xB4EE, 0x642D, 0xB4EF, 0x8FBE,
+	0xB4F0, 0x7B54, 0xB4F1, 0x7629, 0xB4F2, 0x6253, 0xB4F3, 0x5927,
+	0xB4F4, 0x5446, 0xB4F5, 0x6B79, 0xB4F6, 0x50A3, 0xB4F7, 0x6234,
+	0xB4F8, 0x5E26, 0xB4F9, 0x6B86, 0xB4FA, 0x4EE3, 0xB4FB, 0x8D37,
+	0xB4FC, 0x888B, 0xB4FD, 0x5F85, 0xB4FE, 0x902E, 0xB540, 0x790D,
+	0xB541, 0x790E, 0xB542, 0x790F, 0xB543, 0x7910, 0xB544, 0x7911,
+	0xB545, 0x7912, 0xB546, 0x7914, 0xB547, 0x7915, 0xB548, 0x7916,
+	0xB549, 0x7917, 0xB54A, 0x7918, 0xB54B, 0x7919, 0xB54C, 0x791A,
+	0xB54D, 0x791B, 0xB54E, 0x791C, 0xB54F, 0x791D, 0xB550, 0x791F,
+	0xB551, 0x7920, 0xB552, 0x7921, 0xB553, 0x7922, 0xB554, 0x7923,
+	0xB555, 0x7925, 0xB556, 0x7926, 0xB557, 0x7927, 0xB558, 0x7928,
+	0xB559, 0x7929, 0xB55A, 0x792A, 0xB55B, 0x792B, 0xB55C, 0x792C,
+	0xB55D, 0x792D, 0xB55E, 0x792E, 0xB55F, 0x792F, 0xB560, 0x7930,
+	0xB561, 0x7931, 0xB562, 0x7932, 0xB563, 0x7933, 0xB564, 0x7935,
+	0xB565, 0x7936, 0xB566, 0x7937, 0xB567, 0x7938, 0xB568, 0x7939,
+	0xB569, 0x793D, 0xB56A, 0x793F, 0xB56B, 0x7942, 0xB56C, 0x7943,
+	0xB56D, 0x7944, 0xB56E, 0x7945, 0xB56F, 0x7947, 0xB570, 0x794A,
+	0xB571, 0x794B, 0xB572, 0x794C, 0xB573, 0x794D, 0xB574, 0x794E,
+	0xB575, 0x794F, 0xB576, 0x7950, 0xB577, 0x7951, 0xB578, 0x7952,
+	0xB579, 0x7954, 0xB57A, 0x7955, 0xB57B, 0x7958, 0xB57C, 0x7959,
+	0xB57D, 0x7961, 0xB57E, 0x7963, 0xB580, 0x7964, 0xB581, 0x7966,
+	0xB582, 0x7969, 0xB583, 0x796A, 0xB584, 0x796B, 0xB585, 0x796C,
+	0xB586, 0x796E, 0xB587, 0x7970, 0xB588, 0x7971, 0xB589, 0x7972,
+	0xB58A, 0x7973, 0xB58B, 0x7974, 0xB58C, 0x7975, 0xB58D, 0x7976,
+	0xB58E, 0x7979, 0xB58F, 0x797B, 0xB590, 0x797C, 0xB591, 0x797D,
+	0xB592, 0x797E, 0xB593, 0x797F, 0xB594, 0x7982, 0xB595, 0x7983,
+	0xB596, 0x7986, 0xB597, 0x7987, 0xB598, 0x7988, 0xB599, 0x7989,
+	0xB59A, 0x798B, 0xB59B, 0x798C, 0xB59C, 0x798D, 0xB59D, 0x798E,
+	0xB59E, 0x7990, 0xB59F, 0x7991, 0xB5A0, 0x7992, 0xB5A1, 0x6020,
+	0xB5A2, 0x803D, 0xB5A3, 0x62C5, 0xB5A4, 0x4E39, 0xB5A5, 0x5355,
+	0xB5A6, 0x90F8, 0xB5A7, 0x63B8, 0xB5A8, 0x80C6, 0xB5A9, 0x65E6,
+	0xB5AA, 0x6C2E, 0xB5AB, 0x4F46, 0xB5AC, 0x60EE, 0xB5AD, 0x6DE1,
+	0xB5AE, 0x8BDE, 0xB5AF, 0x5F39, 0xB5B0, 0x86CB, 0xB5B1, 0x5F53,
+	0xB5B2, 0x6321, 0xB5B3, 0x515A, 0xB5B4, 0x8361, 0xB5B5, 0x6863,
+	0xB5B6, 0x5200, 0xB5B7, 0x6363, 0xB5B8, 0x8E48, 0xB5B9, 0x5012,
+	0xB5BA, 0x5C9B, 0xB5BB, 0x7977, 0xB5BC, 0x5BFC, 0xB5BD, 0x5230,
+	0xB5BE, 0x7A3B, 0xB5BF, 0x60BC, 0xB5C0, 0x9053, 0xB5C1, 0x76D7,
+	0xB5C2, 0x5FB7, 0xB5C3, 0x5F97, 0xB5C4, 0x7684, 0xB5C5, 0x8E6C,
+	0xB5C6, 0x706F, 0xB5C7, 0x767B, 0xB5C8, 0x7B49, 0xB5C9, 0x77AA,
+	0xB5CA, 0x51F3, 0xB5CB, 0x9093, 0xB5CC, 0x5824, 0xB5CD, 0x4F4E,
+	0xB5CE, 0x6EF4, 0xB5CF, 0x8FEA, 0xB5D0, 0x654C, 0xB5D1, 0x7B1B,
+	0xB5D2, 0x72C4, 0xB5D3, 0x6DA4, 0xB5D4, 0x7FDF, 0xB5D5, 0x5AE1,
+	0xB5D6, 0x62B5, 0xB5D7, 0x5E95, 0xB5D8, 0x5730, 0xB5D9, 0x8482,
+	0xB5DA, 0x7B2C, 0xB5DB, 0x5E1D, 0xB5DC, 0x5F1F, 0xB5DD, 0x9012,
+	0xB5DE, 0x7F14, 0xB5DF, 0x98A0, 0xB5E0, 0x6382, 0xB5E1, 0x6EC7,
+	0xB5E2, 0x7898, 0xB5E3, 0x70B9, 0xB5E4, 0x5178, 0xB5E5, 0x975B,
+	0xB5E6, 0x57AB, 0xB5E7, 0x7535, 0xB5E8, 0x4F43, 0xB5E9, 0x7538,
+	0xB5EA, 0x5E97, 0xB5EB, 0x60E6, 0xB5EC, 0x5960, 0xB5ED, 0x6DC0,
+	0xB5EE, 0x6BBF, 0xB5EF, 0x7889, 0xB5F0, 0x53FC, 0xB5F1, 0x96D5,
+	0xB5F2, 0x51CB, 0xB5F3, 0x5201, 0xB5F4, 0x6389, 0xB5F5, 0x540A,
+	0xB5F6, 0x9493, 0xB5F7, 0x8C03, 0xB5F8, 0x8DCC, 0xB5F9, 0x7239,
+	0xB5FA, 0x789F, 0xB5FB, 0x8776, 0xB5FC, 0x8FED, 0xB5FD, 0x8C0D,
+	0xB5FE, 0x53E0, 0xB640, 0x7993, 0xB641, 0x7994, 0xB642, 0x7995,
+	0xB643, 0x7996, 0xB644, 0x7997, 0xB645, 0x7998, 0xB646, 0x7999,
+	0xB647, 0x799B, 0xB648, 0x799C, 0xB649, 0x799D, 0xB64A, 0x799E,
+	0xB64B, 0x799F, 0xB64C, 0x79A0, 0xB64D, 0x79A1, 0xB64E, 0x79A2,
+	0xB64F, 0x79A3, 0xB650, 0x79A4, 0xB651, 0x79A5, 0xB652, 0x79A6,
+	0xB653, 0x79A8, 0xB654, 0x79A9, 0xB655, 0x79AA, 0xB656, 0x79AB,
+	0xB657, 0x79AC, 0xB658, 0x79AD, 0xB659, 0x79AE, 0xB65A, 0x79AF,
+	0xB65B, 0x79B0, 0xB65C, 0x79B1, 0xB65D, 0x79B2, 0xB65E, 0x79B4,
+	0xB65F, 0x79B5, 0xB660, 0x79B6, 0xB661, 0x79B7, 0xB662, 0x79B8,
+	0xB663, 0x79BC, 0xB664, 0x79BF, 0xB665, 0x79C2, 0xB666, 0x79C4,
+	0xB667, 0x79C5, 0xB668, 0x79C7, 0xB669, 0x79C8, 0xB66A, 0x79CA,
+	0xB66B, 0x79CC, 0xB66C, 0x79CE, 0xB66D, 0x79CF, 0xB66E, 0x79D0,
+	0xB66F, 0x79D3, 0xB670, 0x79D4, 0xB671, 0x79D6, 0xB672, 0x79D7,
+	0xB673, 0x79D9, 0xB674, 0x79DA, 0xB675, 0x79DB, 0xB676, 0x79DC,
+	0xB677, 0x79DD, 0xB678, 0x79DE, 0xB679, 0x79E0, 0xB67A, 0x79E1,
+	0xB67B, 0x79E2, 0xB67C, 0x79E5, 0xB67D, 0x79E8, 0xB67E, 0x79EA,
+	0xB680, 0x79EC, 0xB681, 0x79EE, 0xB682, 0x79F1, 0xB683, 0x79F2,
+	0xB684, 0x79F3, 0xB685, 0x79F4, 0xB686, 0x79F5, 0xB687, 0x79F6,
+	0xB688, 0x79F7, 0xB689, 0x79F9, 0xB68A, 0x79FA, 0xB68B, 0x79FC,
+	0xB68C, 0x79FE, 0xB68D, 0x79FF, 0xB68E, 0x7A01, 0xB68F, 0x7A04,
+	0xB690, 0x7A05, 0xB691, 0x7A07, 0xB692, 0x7A08, 0xB693, 0x7A09,
+	0xB694, 0x7A0A, 0xB695, 0x7A0C, 0xB696, 0x7A0F, 0xB697, 0x7A10,
+	0xB698, 0x7A11, 0xB699, 0x7A12, 0xB69A, 0x7A13, 0xB69B, 0x7A15,
+	0xB69C, 0x7A16, 0xB69D, 0x7A18, 0xB69E, 0x7A19, 0xB69F, 0x7A1B,
+	0xB6A0, 0x7A1C, 0xB6A1, 0x4E01, 0xB6A2, 0x76EF, 0xB6A3, 0x53EE,
+	0xB6A4, 0x9489, 0xB6A5, 0x9876, 0xB6A6, 0x9F0E, 0xB6A7, 0x952D,
+	0xB6A8, 0x5B9A, 0xB6A9, 0x8BA2, 0xB6AA, 0x4E22, 0xB6AB, 0x4E1C,
+	0xB6AC, 0x51AC, 0xB6AD, 0x8463, 0xB6AE, 0x61C2, 0xB6AF, 0x52A8,
+	0xB6B0, 0x680B, 0xB6B1, 0x4F97, 0xB6B2, 0x606B, 0xB6B3, 0x51BB,
+	0xB6B4, 0x6D1E, 0xB6B5, 0x515C, 0xB6B6, 0x6296, 0xB6B7, 0x6597,
+	0xB6B8, 0x9661, 0xB6B9, 0x8C46, 0xB6BA, 0x9017, 0xB6BB, 0x75D8,
+	0xB6BC, 0x90FD, 0xB6BD, 0x7763, 0xB6BE, 0x6BD2, 0xB6BF, 0x728A,
+	0xB6C0, 0x72EC, 0xB6C1, 0x8BFB, 0xB6C2, 0x5835, 0xB6C3, 0x7779,
+	0xB6C4, 0x8D4C, 0xB6C5, 0x675C, 0xB6C6, 0x9540, 0xB6C7, 0x809A,
+	0xB6C8, 0x5EA6, 0xB6C9, 0x6E21, 0xB6CA, 0x5992, 0xB6CB, 0x7AEF,
+	0xB6CC, 0x77ED, 0xB6CD, 0x953B, 0xB6CE, 0x6BB5, 0xB6CF, 0x65AD,
+	0xB6D0, 0x7F0E, 0xB6D1, 0x5806, 0xB6D2, 0x5151, 0xB6D3, 0x961F,
+	0xB6D4, 0x5BF9, 0xB6D5, 0x58A9, 0xB6D6, 0x5428, 0xB6D7, 0x8E72,
+	0xB6D8, 0x6566, 0xB6D9, 0x987F, 0xB6DA, 0x56E4, 0xB6DB, 0x949D,
+	0xB6DC, 0x76FE, 0xB6DD, 0x9041, 0xB6DE, 0x6387, 0xB6DF, 0x54C6,
+	0xB6E0, 0x591A, 0xB6E1, 0x593A, 0xB6E2, 0x579B, 0xB6E3, 0x8EB2,
+	0xB6E4, 0x6735, 0xB6E5, 0x8DFA, 0xB6E6, 0x8235, 0xB6E7, 0x5241,
+	0xB6E8, 0x60F0, 0xB6E9, 0x5815, 0xB6EA, 0x86FE, 0xB6EB, 0x5CE8,
+	0xB6EC, 0x9E45, 0xB6ED, 0x4FC4, 0xB6EE, 0x989D, 0xB6EF, 0x8BB9,
+	0xB6F0, 0x5A25, 0xB6F1, 0x6076, 0xB6F2, 0x5384, 0xB6F3, 0x627C,
+	0xB6F4, 0x904F, 0xB6F5, 0x9102, 0xB6F6, 0x997F, 0xB6F7, 0x6069,
+	0xB6F8, 0x800C, 0xB6F9, 0x513F, 0xB6FA, 0x8033, 0xB6FB, 0x5C14,
+	0xB6FC, 0x9975, 0xB6FD, 0x6D31, 0xB6FE, 0x4E8C, 0xB740, 0x7A1D,
+	0xB741, 0x7A1F, 0xB742, 0x7A21, 0xB743, 0x7A22, 0xB744, 0x7A24,
+	0xB745, 0x7A25, 0xB746, 0x7A26, 0xB747, 0x7A27, 0xB748, 0x7A28,
+	0xB749, 0x7A29, 0xB74A, 0x7A2A, 0xB74B, 0x7A2B, 0xB74C, 0x7A2C,
+	0xB74D, 0x7A2D, 0xB74E, 0x7A2E, 0xB74F, 0x7A2F, 0xB750, 0x7A30,
+	0xB751, 0x7A31, 0xB752, 0x7A32, 0xB753, 0x7A34, 0xB754, 0x7A35,
+	0xB755, 0x7A36, 0xB756, 0x7A38, 0xB757, 0x7A3A, 0xB758, 0x7A3E,
+	0xB759, 0x7A40, 0xB75A, 0x7A41, 0xB75B, 0x7A42, 0xB75C, 0x7A43,
+	0xB75D, 0x7A44, 0xB75E, 0x7A45, 0xB75F, 0x7A47, 0xB760, 0x7A48,
+	0xB761, 0x7A49, 0xB762, 0x7A4A, 0xB763, 0x7A4B, 0xB764, 0x7A4C,
+	0xB765, 0x7A4D, 0xB766, 0x7A4E, 0xB767, 0x7A4F, 0xB768, 0x7A50,
+	0xB769, 0x7A52, 0xB76A, 0x7A53, 0xB76B, 0x7A54, 0xB76C, 0x7A55,
+	0xB76D, 0x7A56, 0xB76E, 0x7A58, 0xB76F, 0x7A59, 0xB770, 0x7A5A,
+	0xB771, 0x7A5B, 0xB772, 0x7A5C, 0xB773, 0x7A5D, 0xB774, 0x7A5E,
+	0xB775, 0x7A5F, 0xB776, 0x7A60, 0xB777, 0x7A61, 0xB778, 0x7A62,
+	0xB779, 0x7A63, 0xB77A, 0x7A64, 0xB77B, 0x7A65, 0xB77C, 0x7A66,
+	0xB77D, 0x7A67, 0xB77E, 0x7A68, 0xB780, 0x7A69, 0xB781, 0x7A6A,
+	0xB782, 0x7A6B, 0xB783, 0x7A6C, 0xB784, 0x7A6D, 0xB785, 0x7A6E,
+	0xB786, 0x7A6F, 0xB787, 0x7A71, 0xB788, 0x7A72, 0xB789, 0x7A73,
+	0xB78A, 0x7A75, 0xB78B, 0x7A7B, 0xB78C, 0x7A7C, 0xB78D, 0x7A7D,
+	0xB78E, 0x7A7E, 0xB78F, 0x7A82, 0xB790, 0x7A85, 0xB791, 0x7A87,
+	0xB792, 0x7A89, 0xB793, 0x7A8A, 0xB794, 0x7A8B, 0xB795, 0x7A8C,
+	0xB796, 0x7A8E, 0xB797, 0x7A8F, 0xB798, 0x7A90, 0xB799, 0x7A93,
+	0xB79A, 0x7A94, 0xB79B, 0x7A99, 0xB79C, 0x7A9A, 0xB79D, 0x7A9B,
+	0xB79E, 0x7A9E, 0xB79F, 0x7AA1, 0xB7A0, 0x7AA2, 0xB7A1, 0x8D30,
+	0xB7A2, 0x53D1, 0xB7A3, 0x7F5A, 0xB7A4, 0x7B4F, 0xB7A5, 0x4F10,
+	0xB7A6, 0x4E4F, 0xB7A7, 0x9600, 0xB7A8, 0x6CD5, 0xB7A9, 0x73D0,
+	0xB7AA, 0x85E9, 0xB7AB, 0x5E06, 0xB7AC, 0x756A, 0xB7AD, 0x7FFB,
+	0xB7AE, 0x6A0A, 0xB7AF, 0x77FE, 0xB7B0, 0x9492, 0xB7B1, 0x7E41,
+	0xB7B2, 0x51E1, 0xB7B3, 0x70E6, 0xB7B4, 0x53CD, 0xB7B5, 0x8FD4,
+	0xB7B6, 0x8303, 0xB7B7, 0x8D29, 0xB7B8, 0x72AF, 0xB7B9, 0x996D,
+	0xB7BA, 0x6CDB, 0xB7BB, 0x574A, 0xB7BC, 0x82B3, 0xB7BD, 0x65B9,
+	0xB7BE, 0x80AA, 0xB7BF, 0x623F, 0xB7C0, 0x9632, 0xB7C1, 0x59A8,
+	0xB7C2, 0x4EFF, 0xB7C3, 0x8BBF, 0xB7C4, 0x7EBA, 0xB7C5, 0x653E,
+	0xB7C6, 0x83F2, 0xB7C7, 0x975E, 0xB7C8, 0x5561, 0xB7C9, 0x98DE,
+	0xB7CA, 0x80A5, 0xB7CB, 0x532A, 0xB7CC, 0x8BFD, 0xB7CD, 0x5420,
+	0xB7CE, 0x80BA, 0xB7CF, 0x5E9F, 0xB7D0, 0x6CB8, 0xB7D1, 0x8D39,
+	0xB7D2, 0x82AC, 0xB7D3, 0x915A, 0xB7D4, 0x5429, 0xB7D5, 0x6C1B,
+	0xB7D6, 0x5206, 0xB7D7, 0x7EB7, 0xB7D8, 0x575F, 0xB7D9, 0x711A,
+	0xB7DA, 0x6C7E, 0xB7DB, 0x7C89, 0xB7DC, 0x594B, 0xB7DD, 0x4EFD,
+	0xB7DE, 0x5FFF, 0xB7DF, 0x6124, 0xB7E0, 0x7CAA, 0xB7E1, 0x4E30,
+	0xB7E2, 0x5C01, 0xB7E3, 0x67AB, 0xB7E4, 0x8702, 0xB7E5, 0x5CF0,
+	0xB7E6, 0x950B, 0xB7E7, 0x98CE, 0xB7E8, 0x75AF, 0xB7E9, 0x70FD,
+	0xB7EA, 0x9022, 0xB7EB, 0x51AF, 0xB7EC, 0x7F1D, 0xB7ED, 0x8BBD,
+	0xB7EE, 0x5949, 0xB7EF, 0x51E4, 0xB7F0, 0x4F5B, 0xB7F1, 0x5426,
+	0xB7F2, 0x592B, 0xB7F3, 0x6577, 0xB7F4, 0x80A4, 0xB7F5, 0x5B75,
+	0xB7F6, 0x6276, 0xB7F7, 0x62C2, 0xB7F8, 0x8F90, 0xB7F9, 0x5E45,
+	0xB7FA, 0x6C1F, 0xB7FB, 0x7B26, 0xB7FC, 0x4F0F, 0xB7FD, 0x4FD8,
+	0xB7FE, 0x670D, 0xB840, 0x7AA3, 0xB841, 0x7AA4, 0xB842, 0x7AA7,
+	0xB843, 0x7AA9, 0xB844, 0x7AAA, 0xB845, 0x7AAB, 0xB846, 0x7AAE,
+	0xB847, 0x7AAF, 0xB848, 0x7AB0, 0xB849, 0x7AB1, 0xB84A, 0x7AB2,
+	0xB84B, 0x7AB4, 0xB84C, 0x7AB5, 0xB84D, 0x7AB6, 0xB84E, 0x7AB7,
+	0xB84F, 0x7AB8, 0xB850, 0x7AB9, 0xB851, 0x7ABA, 0xB852, 0x7ABB,
+	0xB853, 0x7ABC, 0xB854, 0x7ABD, 0xB855, 0x7ABE, 0xB856, 0x7AC0,
+	0xB857, 0x7AC1, 0xB858, 0x7AC2, 0xB859, 0x7AC3, 0xB85A, 0x7AC4,
+	0xB85B, 0x7AC5, 0xB85C, 0x7AC6, 0xB85D, 0x7AC7, 0xB85E, 0x7AC8,
+	0xB85F, 0x7AC9, 0xB860, 0x7ACA, 0xB861, 0x7ACC, 0xB862, 0x7ACD,
+	0xB863, 0x7ACE, 0xB864, 0x7ACF, 0xB865, 0x7AD0, 0xB866, 0x7AD1,
+	0xB867, 0x7AD2, 0xB868, 0x7AD3, 0xB869, 0x7AD4, 0xB86A, 0x7AD5,
+	0xB86B, 0x7AD7, 0xB86C, 0x7AD8, 0xB86D, 0x7ADA, 0xB86E, 0x7ADB,
+	0xB86F, 0x7ADC, 0xB870, 0x7ADD, 0xB871, 0x7AE1, 0xB872, 0x7AE2,
+	0xB873, 0x7AE4, 0xB874, 0x7AE7, 0xB875, 0x7AE8, 0xB876, 0x7AE9,
+	0xB877, 0x7AEA, 0xB878, 0x7AEB, 0xB879, 0x7AEC, 0xB87A, 0x7AEE,
+	0xB87B, 0x7AF0, 0xB87C, 0x7AF1, 0xB87D, 0x7AF2, 0xB87E, 0x7AF3,
+	0xB880, 0x7AF4, 0xB881, 0x7AF5, 0xB882, 0x7AF6, 0xB883, 0x7AF7,
+	0xB884, 0x7AF8, 0xB885, 0x7AFB, 0xB886, 0x7AFC, 0xB887, 0x7AFE,
+	0xB888, 0x7B00, 0xB889, 0x7B01, 0xB88A, 0x7B02, 0xB88B, 0x7B05,
+	0xB88C, 0x7B07, 0xB88D, 0x7B09, 0xB88E, 0x7B0C, 0xB88F, 0x7B0D,
+	0xB890, 0x7B0E, 0xB891, 0x7B10, 0xB892, 0x7B12, 0xB893, 0x7B13,
+	0xB894, 0x7B16, 0xB895, 0x7B17, 0xB896, 0x7B18, 0xB897, 0x7B1A,
+	0xB898, 0x7B1C, 0xB899, 0x7B1D, 0xB89A, 0x7B1F, 0xB89B, 0x7B21,
+	0xB89C, 0x7B22, 0xB89D, 0x7B23, 0xB89E, 0x7B27, 0xB89F, 0x7B29,
+	0xB8A0, 0x7B2D, 0xB8A1, 0x6D6E, 0xB8A2, 0x6DAA, 0xB8A3, 0x798F,
+	0xB8A4, 0x88B1, 0xB8A5, 0x5F17, 0xB8A6, 0x752B, 0xB8A7, 0x629A,
+	0xB8A8, 0x8F85, 0xB8A9, 0x4FEF, 0xB8AA, 0x91DC, 0xB8AB, 0x65A7,
+	0xB8AC, 0x812F, 0xB8AD, 0x8151, 0xB8AE, 0x5E9C, 0xB8AF, 0x8150,
+	0xB8B0, 0x8D74, 0xB8B1, 0x526F, 0xB8B2, 0x8986, 0xB8B3, 0x8D4B,
+	0xB8B4, 0x590D, 0xB8B5, 0x5085, 0xB8B6, 0x4ED8, 0xB8B7, 0x961C,
+	0xB8B8, 0x7236, 0xB8B9, 0x8179, 0xB8BA, 0x8D1F, 0xB8BB, 0x5BCC,
+	0xB8BC, 0x8BA3, 0xB8BD, 0x9644, 0xB8BE, 0x5987, 0xB8BF, 0x7F1A,
+	0xB8C0, 0x5490, 0xB8C1, 0x5676, 0xB8C2, 0x560E, 0xB8C3, 0x8BE5,
+	0xB8C4, 0x6539, 0xB8C5, 0x6982, 0xB8C6, 0x9499, 0xB8C7, 0x76D6,
+	0xB8C8, 0x6E89, 0xB8C9, 0x5E72, 0xB8CA, 0x7518, 0xB8CB, 0x6746,
+	0xB8CC, 0x67D1, 0xB8CD, 0x7AFF, 0xB8CE, 0x809D, 0xB8CF, 0x8D76,
+	0xB8D0, 0x611F, 0xB8D1, 0x79C6, 0xB8D2, 0x6562, 0xB8D3, 0x8D63,
+	0xB8D4, 0x5188, 0xB8D5, 0x521A, 0xB8D6, 0x94A2, 0xB8D7, 0x7F38,
+	0xB8D8, 0x809B, 0xB8D9, 0x7EB2, 0xB8DA, 0x5C97, 0xB8DB, 0x6E2F,
+	0xB8DC, 0x6760, 0xB8DD, 0x7BD9, 0xB8DE, 0x768B, 0xB8DF, 0x9AD8,
+	0xB8E0, 0x818F, 0xB8E1, 0x7F94, 0xB8E2, 0x7CD5, 0xB8E3, 0x641E,
+	0xB8E4, 0x9550, 0xB8E5, 0x7A3F, 0xB8E6, 0x544A, 0xB8E7, 0x54E5,
+	0xB8E8, 0x6B4C, 0xB8E9, 0x6401, 0xB8EA, 0x6208, 0xB8EB, 0x9E3D,
+	0xB8EC, 0x80F3, 0xB8ED, 0x7599, 0xB8EE, 0x5272, 0xB8EF, 0x9769,
+	0xB8F0, 0x845B, 0xB8F1, 0x683C, 0xB8F2, 0x86E4, 0xB8F3, 0x9601,
+	0xB8F4, 0x9694, 0xB8F5, 0x94EC, 0xB8F6, 0x4E2A, 0xB8F7, 0x5404,
+	0xB8F8, 0x7ED9, 0xB8F9, 0x6839, 0xB8FA, 0x8DDF, 0xB8FB, 0x8015,
+	0xB8FC, 0x66F4, 0xB8FD, 0x5E9A, 0xB8FE, 0x7FB9, 0xB940, 0x7B2F,
+	0xB941, 0x7B30, 0xB942, 0x7B32, 0xB943, 0x7B34, 0xB944, 0x7B35,
+	0xB945, 0x7B36, 0xB946, 0x7B37, 0xB947, 0x7B39, 0xB948, 0x7B3B,
+	0xB949, 0x7B3D, 0xB94A, 0x7B3F, 0xB94B, 0x7B40, 0xB94C, 0x7B41,
+	0xB94D, 0x7B42, 0xB94E, 0x7B43, 0xB94F, 0x7B44, 0xB950, 0x7B46,
+	0xB951, 0x7B48, 0xB952, 0x7B4A, 0xB953, 0x7B4D, 0xB954, 0x7B4E,
+	0xB955, 0x7B53, 0xB956, 0x7B55, 0xB957, 0x7B57, 0xB958, 0x7B59,
+	0xB959, 0x7B5C, 0xB95A, 0x7B5E, 0xB95B, 0x7B5F, 0xB95C, 0x7B61,
+	0xB95D, 0x7B63, 0xB95E, 0x7B64, 0xB95F, 0x7B65, 0xB960, 0x7B66,
+	0xB961, 0x7B67, 0xB962, 0x7B68, 0xB963, 0x7B69, 0xB964, 0x7B6A,
+	0xB965, 0x7B6B, 0xB966, 0x7B6C, 0xB967, 0x7B6D, 0xB968, 0x7B6F,
+	0xB969, 0x7B70, 0xB96A, 0x7B73, 0xB96B, 0x7B74, 0xB96C, 0x7B76,
+	0xB96D, 0x7B78, 0xB96E, 0x7B7A, 0xB96F, 0x7B7C, 0xB970, 0x7B7D,
+	0xB971, 0x7B7F, 0xB972, 0x7B81, 0xB973, 0x7B82, 0xB974, 0x7B83,
+	0xB975, 0x7B84, 0xB976, 0x7B86, 0xB977, 0x7B87, 0xB978, 0x7B88,
+	0xB979, 0x7B89, 0xB97A, 0x7B8A, 0xB97B, 0x7B8B, 0xB97C, 0x7B8C,
+	0xB97D, 0x7B8E, 0xB97E, 0x7B8F, 0xB980, 0x7B91, 0xB981, 0x7B92,
+	0xB982, 0x7B93, 0xB983, 0x7B96, 0xB984, 0x7B98, 0xB985, 0x7B99,
+	0xB986, 0x7B9A, 0xB987, 0x7B9B, 0xB988, 0x7B9E, 0xB989, 0x7B9F,
+	0xB98A, 0x7BA0, 0xB98B, 0x7BA3, 0xB98C, 0x7BA4, 0xB98D, 0x7BA5,
+	0xB98E, 0x7BAE, 0xB98F, 0x7BAF, 0xB990, 0x7BB0, 0xB991, 0x7BB2,
+	0xB992, 0x7BB3, 0xB993, 0x7BB5, 0xB994, 0x7BB6, 0xB995, 0x7BB7,
+	0xB996, 0x7BB9, 0xB997, 0x7BBA, 0xB998, 0x7BBB, 0xB999, 0x7BBC,
+	0xB99A, 0x7BBD, 0xB99B, 0x7BBE, 0xB99C, 0x7BBF, 0xB99D, 0x7BC0,
+	0xB99E, 0x7BC2, 0xB99F, 0x7BC3, 0xB9A0, 0x7BC4, 0xB9A1, 0x57C2,
+	0xB9A2, 0x803F, 0xB9A3, 0x6897, 0xB9A4, 0x5DE5, 0xB9A5, 0x653B,
+	0xB9A6, 0x529F, 0xB9A7, 0x606D, 0xB9A8, 0x9F9A, 0xB9A9, 0x4F9B,
+	0xB9AA, 0x8EAC, 0xB9AB, 0x516C, 0xB9AC, 0x5BAB, 0xB9AD, 0x5F13,
+	0xB9AE, 0x5DE9, 0xB9AF, 0x6C5E, 0xB9B0, 0x62F1, 0xB9B1, 0x8D21,
+	0xB9B2, 0x5171, 0xB9B3, 0x94A9, 0xB9B4, 0x52FE, 0xB9B5, 0x6C9F,
+	0xB9B6, 0x82DF, 0xB9B7, 0x72D7, 0xB9B8, 0x57A2, 0xB9B9, 0x6784,
+	0xB9BA, 0x8D2D, 0xB9BB, 0x591F, 0xB9BC, 0x8F9C, 0xB9BD, 0x83C7,
+	0xB9BE, 0x5495, 0xB9BF, 0x7B8D, 0xB9C0, 0x4F30, 0xB9C1, 0x6CBD,
+	0xB9C2, 0x5B64, 0xB9C3, 0x59D1, 0xB9C4, 0x9F13, 0xB9C5, 0x53E4,
+	0xB9C6, 0x86CA, 0xB9C7, 0x9AA8, 0xB9C8, 0x8C37, 0xB9C9, 0x80A1,
+	0xB9CA, 0x6545, 0xB9CB, 0x987E, 0xB9CC, 0x56FA, 0xB9CD, 0x96C7,
+	0xB9CE, 0x522E, 0xB9CF, 0x74DC, 0xB9D0, 0x5250, 0xB9D1, 0x5BE1,
+	0xB9D2, 0x6302, 0xB9D3, 0x8902, 0xB9D4, 0x4E56, 0xB9D5, 0x62D0,
+	0xB9D6, 0x602A, 0xB9D7, 0x68FA, 0xB9D8, 0x5173, 0xB9D9, 0x5B98,
+	0xB9DA, 0x51A0, 0xB9DB, 0x89C2, 0xB9DC, 0x7BA1, 0xB9DD, 0x9986,
+	0xB9DE, 0x7F50, 0xB9DF, 0x60EF, 0xB9E0, 0x704C, 0xB9E1, 0x8D2F,
+	0xB9E2, 0x5149, 0xB9E3, 0x5E7F, 0xB9E4, 0x901B, 0xB9E5, 0x7470,
+	0xB9E6, 0x89C4, 0xB9E7, 0x572D, 0xB9E8, 0x7845, 0xB9E9, 0x5F52,
+	0xB9EA, 0x9F9F, 0xB9EB, 0x95FA, 0xB9EC, 0x8F68, 0xB9ED, 0x9B3C,
+	0xB9EE, 0x8BE1, 0xB9EF, 0x7678, 0xB9F0, 0x6842, 0xB9F1, 0x67DC,
+	0xB9F2, 0x8DEA, 0xB9F3, 0x8D35, 0xB9F4, 0x523D, 0xB9F5, 0x8F8A,
+	0xB9F6, 0x6EDA, 0xB9F7, 0x68CD, 0xB9F8, 0x9505, 0xB9F9, 0x90ED,
+	0xB9FA, 0x56FD, 0xB9FB, 0x679C, 0xB9FC, 0x88F9, 0xB9FD, 0x8FC7,
+	0xB9FE, 0x54C8, 0xBA40, 0x7BC5, 0xBA41, 0x7BC8, 0xBA42, 0x7BC9,
+	0xBA43, 0x7BCA, 0xBA44, 0x7BCB, 0xBA45, 0x7BCD, 0xBA46, 0x7BCE,
+	0xBA47, 0x7BCF, 0xBA48, 0x7BD0, 0xBA49, 0x7BD2, 0xBA4A, 0x7BD4,
+	0xBA4B, 0x7BD5, 0xBA4C, 0x7BD6, 0xBA4D, 0x7BD7, 0xBA4E, 0x7BD8,
+	0xBA4F, 0x7BDB, 0xBA50, 0x7BDC, 0xBA51, 0x7BDE, 0xBA52, 0x7BDF,
+	0xBA53, 0x7BE0, 0xBA54, 0x7BE2, 0xBA55, 0x7BE3, 0xBA56, 0x7BE4,
+	0xBA57, 0x7BE7, 0xBA58, 0x7BE8, 0xBA59, 0x7BE9, 0xBA5A, 0x7BEB,
+	0xBA5B, 0x7BEC, 0xBA5C, 0x7BED, 0xBA5D, 0x7BEF, 0xBA5E, 0x7BF0,
+	0xBA5F, 0x7BF2, 0xBA60, 0x7BF3, 0xBA61, 0x7BF4, 0xBA62, 0x7BF5,
+	0xBA63, 0x7BF6, 0xBA64, 0x7BF8, 0xBA65, 0x7BF9, 0xBA66, 0x7BFA,
+	0xBA67, 0x7BFB, 0xBA68, 0x7BFD, 0xBA69, 0x7BFF, 0xBA6A, 0x7C00,
+	0xBA6B, 0x7C01, 0xBA6C, 0x7C02, 0xBA6D, 0x7C03, 0xBA6E, 0x7C04,
+	0xBA6F, 0x7C05, 0xBA70, 0x7C06, 0xBA71, 0x7C08, 0xBA72, 0x7C09,
+	0xBA73, 0x7C0A, 0xBA74, 0x7C0D, 0xBA75, 0x7C0E, 0xBA76, 0x7C10,
+	0xBA77, 0x7C11, 0xBA78, 0x7C12, 0xBA79, 0x7C13, 0xBA7A, 0x7C14,
+	0xBA7B, 0x7C15, 0xBA7C, 0x7C17, 0xBA7D, 0x7C18, 0xBA7E, 0x7C19,
+	0xBA80, 0x7C1A, 0xBA81, 0x7C1B, 0xBA82, 0x7C1C, 0xBA83, 0x7C1D,
+	0xBA84, 0x7C1E, 0xBA85, 0x7C20, 0xBA86, 0x7C21, 0xBA87, 0x7C22,
+	0xBA88, 0x7C23, 0xBA89, 0x7C24, 0xBA8A, 0x7C25, 0xBA8B, 0x7C28,
+	0xBA8C, 0x7C29, 0xBA8D, 0x7C2B, 0xBA8E, 0x7C2C, 0xBA8F, 0x7C2D,
+	0xBA90, 0x7C2E, 0xBA91, 0x7C2F, 0xBA92, 0x7C30, 0xBA93, 0x7C31,
+	0xBA94, 0x7C32, 0xBA95, 0x7C33, 0xBA96, 0x7C34, 0xBA97, 0x7C35,
+	0xBA98, 0x7C36, 0xBA99, 0x7C37, 0xBA9A, 0x7C39, 0xBA9B, 0x7C3A,
+	0xBA9C, 0x7C3B, 0xBA9D, 0x7C3C, 0xBA9E, 0x7C3D, 0xBA9F, 0x7C3E,
+	0xBAA0, 0x7C42, 0xBAA1, 0x9AB8, 0xBAA2, 0x5B69, 0xBAA3, 0x6D77,
+	0xBAA4, 0x6C26, 0xBAA5, 0x4EA5, 0xBAA6, 0x5BB3, 0xBAA7, 0x9A87,
+	0xBAA8, 0x9163, 0xBAA9, 0x61A8, 0xBAAA, 0x90AF, 0xBAAB, 0x97E9,
+	0xBAAC, 0x542B, 0xBAAD, 0x6DB5, 0xBAAE, 0x5BD2, 0xBAAF, 0x51FD,
+	0xBAB0, 0x558A, 0xBAB1, 0x7F55, 0xBAB2, 0x7FF0, 0xBAB3, 0x64BC,
+	0xBAB4, 0x634D, 0xBAB5, 0x65F1, 0xBAB6, 0x61BE, 0xBAB7, 0x608D,
+	0xBAB8, 0x710A, 0xBAB9, 0x6C57, 0xBABA, 0x6C49, 0xBABB, 0x592F,
+	0xBABC, 0x676D, 0xBABD, 0x822A, 0xBABE, 0x58D5, 0xBABF, 0x568E,
+	0xBAC0, 0x8C6A, 0xBAC1, 0x6BEB, 0xBAC2, 0x90DD, 0xBAC3, 0x597D,
+	0xBAC4, 0x8017, 0xBAC5, 0x53F7, 0xBAC6, 0x6D69, 0xBAC7, 0x5475,
+	0xBAC8, 0x559D, 0xBAC9, 0x8377, 0xBACA, 0x83CF, 0xBACB, 0x6838,
+	0xBACC, 0x79BE, 0xBACD, 0x548C, 0xBACE, 0x4F55, 0xBACF, 0x5408,
+	0xBAD0, 0x76D2, 0xBAD1, 0x8C89, 0xBAD2, 0x9602, 0xBAD3, 0x6CB3,
+	0xBAD4, 0x6DB8, 0xBAD5, 0x8D6B, 0xBAD6, 0x8910, 0xBAD7, 0x9E64,
+	0xBAD8, 0x8D3A, 0xBAD9, 0x563F, 0xBADA, 0x9ED1, 0xBADB, 0x75D5,
+	0xBADC, 0x5F88, 0xBADD, 0x72E0, 0xBADE, 0x6068, 0xBADF, 0x54FC,
+	0xBAE0, 0x4EA8, 0xBAE1, 0x6A2A, 0xBAE2, 0x8861, 0xBAE3, 0x6052,
+	0xBAE4, 0x8F70, 0xBAE5, 0x54C4, 0xBAE6, 0x70D8, 0xBAE7, 0x8679,
+	0xBAE8, 0x9E3F, 0xBAE9, 0x6D2A, 0xBAEA, 0x5B8F, 0xBAEB, 0x5F18,
+	0xBAEC, 0x7EA2, 0xBAED, 0x5589, 0xBAEE, 0x4FAF, 0xBAEF, 0x7334,
+	0xBAF0, 0x543C, 0xBAF1, 0x539A, 0xBAF2, 0x5019, 0xBAF3, 0x540E,
+	0xBAF4, 0x547C, 0xBAF5, 0x4E4E, 0xBAF6, 0x5FFD, 0xBAF7, 0x745A,
+	0xBAF8, 0x58F6, 0xBAF9, 0x846B, 0xBAFA, 0x80E1, 0xBAFB, 0x8774,
+	0xBAFC, 0x72D0, 0xBAFD, 0x7CCA, 0xBAFE, 0x6E56, 0xBB40, 0x7C43,
+	0xBB41, 0x7C44, 0xBB42, 0x7C45, 0xBB43, 0x7C46, 0xBB44, 0x7C47,
+	0xBB45, 0x7C48, 0xBB46, 0x7C49, 0xBB47, 0x7C4A, 0xBB48, 0x7C4B,
+	0xBB49, 0x7C4C, 0xBB4A, 0x7C4E, 0xBB4B, 0x7C4F, 0xBB4C, 0x7C50,
+	0xBB4D, 0x7C51, 0xBB4E, 0x7C52, 0xBB4F, 0x7C53, 0xBB50, 0x7C54,
+	0xBB51, 0x7C55, 0xBB52, 0x7C56, 0xBB53, 0x7C57, 0xBB54, 0x7C58,
+	0xBB55, 0x7C59, 0xBB56, 0x7C5A, 0xBB57, 0x7C5B, 0xBB58, 0x7C5C,
+	0xBB59, 0x7C5D, 0xBB5A, 0x7C5E, 0xBB5B, 0x7C5F, 0xBB5C, 0x7C60,
+	0xBB5D, 0x7C61, 0xBB5E, 0x7C62, 0xBB5F, 0x7C63, 0xBB60, 0x7C64,
+	0xBB61, 0x7C65, 0xBB62, 0x7C66, 0xBB63, 0x7C67, 0xBB64, 0x7C68,
+	0xBB65, 0x7C69, 0xBB66, 0x7C6A, 0xBB67, 0x7C6B, 0xBB68, 0x7C6C,
+	0xBB69, 0x7C6D, 0xBB6A, 0x7C6E, 0xBB6B, 0x7C6F, 0xBB6C, 0x7C70,
+	0xBB6D, 0x7C71, 0xBB6E, 0x7C72, 0xBB6F, 0x7C75, 0xBB70, 0x7C76,
+	0xBB71, 0x7C77, 0xBB72, 0x7C78, 0xBB73, 0x7C79, 0xBB74, 0x7C7A,
+	0xBB75, 0x7C7E, 0xBB76, 0x7C7F, 0xBB77, 0x7C80, 0xBB78, 0x7C81,
+	0xBB79, 0x7C82, 0xBB7A, 0x7C83, 0xBB7B, 0x7C84, 0xBB7C, 0x7C85,
+	0xBB7D, 0x7C86, 0xBB7E, 0x7C87, 0xBB80, 0x7C88, 0xBB81, 0x7C8A,
+	0xBB82, 0x7C8B, 0xBB83, 0x7C8C, 0xBB84, 0x7C8D, 0xBB85, 0x7C8E,
+	0xBB86, 0x7C8F, 0xBB87, 0x7C90, 0xBB88, 0x7C93, 0xBB89, 0x7C94,
+	0xBB8A, 0x7C96, 0xBB8B, 0x7C99, 0xBB8C, 0x7C9A, 0xBB8D, 0x7C9B,
+	0xBB8E, 0x7CA0, 0xBB8F, 0x7CA1, 0xBB90, 0x7CA3, 0xBB91, 0x7CA6,
+	0xBB92, 0x7CA7, 0xBB93, 0x7CA8, 0xBB94, 0x7CA9, 0xBB95, 0x7CAB,
+	0xBB96, 0x7CAC, 0xBB97, 0x7CAD, 0xBB98, 0x7CAF, 0xBB99, 0x7CB0,
+	0xBB9A, 0x7CB4, 0xBB9B, 0x7CB5, 0xBB9C, 0x7CB6, 0xBB9D, 0x7CB7,
+	0xBB9E, 0x7CB8, 0xBB9F, 0x7CBA, 0xBBA0, 0x7CBB, 0xBBA1, 0x5F27,
+	0xBBA2, 0x864E, 0xBBA3, 0x552C, 0xBBA4, 0x62A4, 0xBBA5, 0x4E92,
+	0xBBA6, 0x6CAA, 0xBBA7, 0x6237, 0xBBA8, 0x82B1, 0xBBA9, 0x54D7,
+	0xBBAA, 0x534E, 0xBBAB, 0x733E, 0xBBAC, 0x6ED1, 0xBBAD, 0x753B,
+	0xBBAE, 0x5212, 0xBBAF, 0x5316, 0xBBB0, 0x8BDD, 0xBBB1, 0x69D0,
+	0xBBB2, 0x5F8A, 0xBBB3, 0x6000, 0xBBB4, 0x6DEE, 0xBBB5, 0x574F,
+	0xBBB6, 0x6B22, 0xBBB7, 0x73AF, 0xBBB8, 0x6853, 0xBBB9, 0x8FD8,
+	0xBBBA, 0x7F13, 0xBBBB, 0x6362, 0xBBBC, 0x60A3, 0xBBBD, 0x5524,
+	0xBBBE, 0x75EA, 0xBBBF, 0x8C62, 0xBBC0, 0x7115, 0xBBC1, 0x6DA3,
+	0xBBC2, 0x5BA6, 0xBBC3, 0x5E7B, 0xBBC4, 0x8352, 0xBBC5, 0x614C,
+	0xBBC6, 0x9EC4, 0xBBC7, 0x78FA, 0xBBC8, 0x8757, 0xBBC9, 0x7C27,
+	0xBBCA, 0x7687, 0xBBCB, 0x51F0, 0xBBCC, 0x60F6, 0xBBCD, 0x714C,
+	0xBBCE, 0x6643, 0xBBCF, 0x5E4C, 0xBBD0, 0x604D, 0xBBD1, 0x8C0E,
+	0xBBD2, 0x7070, 0xBBD3, 0x6325, 0xBBD4, 0x8F89, 0xBBD5, 0x5FBD,
+	0xBBD6, 0x6062, 0xBBD7, 0x86D4, 0xBBD8, 0x56DE, 0xBBD9, 0x6BC1,
+	0xBBDA, 0x6094, 0xBBDB, 0x6167, 0xBBDC, 0x5349, 0xBBDD, 0x60E0,
+	0xBBDE, 0x6666, 0xBBDF, 0x8D3F, 0xBBE0, 0x79FD, 0xBBE1, 0x4F1A,
+	0xBBE2, 0x70E9, 0xBBE3, 0x6C47, 0xBBE4, 0x8BB3, 0xBBE5, 0x8BF2,
+	0xBBE6, 0x7ED8, 0xBBE7, 0x8364, 0xBBE8, 0x660F, 0xBBE9, 0x5A5A,
+	0xBBEA, 0x9B42, 0xBBEB, 0x6D51, 0xBBEC, 0x6DF7, 0xBBED, 0x8C41,
+	0xBBEE, 0x6D3B, 0xBBEF, 0x4F19, 0xBBF0, 0x706B, 0xBBF1, 0x83B7,
+	0xBBF2, 0x6216, 0xBBF3, 0x60D1, 0xBBF4, 0x970D, 0xBBF5, 0x8D27,
+	0xBBF6, 0x7978, 0xBBF7, 0x51FB, 0xBBF8, 0x573E, 0xBBF9, 0x57FA,
+	0xBBFA, 0x673A, 0xBBFB, 0x7578, 0xBBFC, 0x7A3D, 0xBBFD, 0x79EF,
+	0xBBFE, 0x7B95, 0xBC40, 0x7CBF, 0xBC41, 0x7CC0, 0xBC42, 0x7CC2,
+	0xBC43, 0x7CC3, 0xBC44, 0x7CC4, 0xBC45, 0x7CC6, 0xBC46, 0x7CC9,
+	0xBC47, 0x7CCB, 0xBC48, 0x7CCE, 0xBC49, 0x7CCF, 0xBC4A, 0x7CD0,
+	0xBC4B, 0x7CD1, 0xBC4C, 0x7CD2, 0xBC4D, 0x7CD3, 0xBC4E, 0x7CD4,
+	0xBC4F, 0x7CD8, 0xBC50, 0x7CDA, 0xBC51, 0x7CDB, 0xBC52, 0x7CDD,
+	0xBC53, 0x7CDE, 0xBC54, 0x7CE1, 0xBC55, 0x7CE2, 0xBC56, 0x7CE3,
+	0xBC57, 0x7CE4, 0xBC58, 0x7CE5, 0xBC59, 0x7CE6, 0xBC5A, 0x7CE7,
+	0xBC5B, 0x7CE9, 0xBC5C, 0x7CEA, 0xBC5D, 0x7CEB, 0xBC5E, 0x7CEC,
+	0xBC5F, 0x7CED, 0xBC60, 0x7CEE, 0xBC61, 0x7CF0, 0xBC62, 0x7CF1,
+	0xBC63, 0x7CF2, 0xBC64, 0x7CF3, 0xBC65, 0x7CF4, 0xBC66, 0x7CF5,
+	0xBC67, 0x7CF6, 0xBC68, 0x7CF7, 0xBC69, 0x7CF9, 0xBC6A, 0x7CFA,
+	0xBC6B, 0x7CFC, 0xBC6C, 0x7CFD, 0xBC6D, 0x7CFE, 0xBC6E, 0x7CFF,
+	0xBC6F, 0x7D00, 0xBC70, 0x7D01, 0xBC71, 0x7D02, 0xBC72, 0x7D03,
+	0xBC73, 0x7D04, 0xBC74, 0x7D05, 0xBC75, 0x7D06, 0xBC76, 0x7D07,
+	0xBC77, 0x7D08, 0xBC78, 0x7D09, 0xBC79, 0x7D0B, 0xBC7A, 0x7D0C,
+	0xBC7B, 0x7D0D, 0xBC7C, 0x7D0E, 0xBC7D, 0x7D0F, 0xBC7E, 0x7D10,
+	0xBC80, 0x7D11, 0xBC81, 0x7D12, 0xBC82, 0x7D13, 0xBC83, 0x7D14,
+	0xBC84, 0x7D15, 0xBC85, 0x7D16, 0xBC86, 0x7D17, 0xBC87, 0x7D18,
+	0xBC88, 0x7D19, 0xBC89, 0x7D1A, 0xBC8A, 0x7D1B, 0xBC8B, 0x7D1C,
+	0xBC8C, 0x7D1D, 0xBC8D, 0x7D1E, 0xBC8E, 0x7D1F, 0xBC8F, 0x7D21,
+	0xBC90, 0x7D23, 0xBC91, 0x7D24, 0xBC92, 0x7D25, 0xBC93, 0x7D26,
+	0xBC94, 0x7D28, 0xBC95, 0x7D29, 0xBC96, 0x7D2A, 0xBC97, 0x7D2C,
+	0xBC98, 0x7D2D, 0xBC99, 0x7D2E, 0xBC9A, 0x7D30, 0xBC9B, 0x7D31,
+	0xBC9C, 0x7D32, 0xBC9D, 0x7D33, 0xBC9E, 0x7D34, 0xBC9F, 0x7D35,
+	0xBCA0, 0x7D36, 0xBCA1, 0x808C, 0xBCA2, 0x9965, 0xBCA3, 0x8FF9,
+	0xBCA4, 0x6FC0, 0xBCA5, 0x8BA5, 0xBCA6, 0x9E21, 0xBCA7, 0x59EC,
+	0xBCA8, 0x7EE9, 0xBCA9, 0x7F09, 0xBCAA, 0x5409, 0xBCAB, 0x6781,
+	0xBCAC, 0x68D8, 0xBCAD, 0x8F91, 0xBCAE, 0x7C4D, 0xBCAF, 0x96C6,
+	0xBCB0, 0x53CA, 0xBCB1, 0x6025, 0xBCB2, 0x75BE, 0xBCB3, 0x6C72,
+	0xBCB4, 0x5373, 0xBCB5, 0x5AC9, 0xBCB6, 0x7EA7, 0xBCB7, 0x6324,
+	0xBCB8, 0x51E0, 0xBCB9, 0x810A, 0xBCBA, 0x5DF1, 0xBCBB, 0x84DF,
+	0xBCBC, 0x6280, 0xBCBD, 0x5180, 0xBCBE, 0x5B63, 0xBCBF, 0x4F0E,
+	0xBCC0, 0x796D, 0xBCC1, 0x5242, 0xBCC2, 0x60B8, 0xBCC3, 0x6D4E,
+	0xBCC4, 0x5BC4, 0xBCC5, 0x5BC2, 0xBCC6, 0x8BA1, 0xBCC7, 0x8BB0,
+	0xBCC8, 0x65E2, 0xBCC9, 0x5FCC, 0xBCCA, 0x9645, 0xBCCB, 0x5993,
+	0xBCCC, 0x7EE7, 0xBCCD, 0x7EAA, 0xBCCE, 0x5609, 0xBCCF, 0x67B7,
+	0xBCD0, 0x5939, 0xBCD1, 0x4F73, 0xBCD2, 0x5BB6, 0xBCD3, 0x52A0,
+	0xBCD4, 0x835A, 0xBCD5, 0x988A, 0xBCD6, 0x8D3E, 0xBCD7, 0x7532,
+	0xBCD8, 0x94BE, 0xBCD9, 0x5047, 0xBCDA, 0x7A3C, 0xBCDB, 0x4EF7,
+	0xBCDC, 0x67B6, 0xBCDD, 0x9A7E, 0xBCDE, 0x5AC1, 0xBCDF, 0x6B7C,
+	0xBCE0, 0x76D1, 0xBCE1, 0x575A, 0xBCE2, 0x5C16, 0xBCE3, 0x7B3A,
+	0xBCE4, 0x95F4, 0xBCE5, 0x714E, 0xBCE6, 0x517C, 0xBCE7, 0x80A9,
+	0xBCE8, 0x8270, 0xBCE9, 0x5978, 0xBCEA, 0x7F04, 0xBCEB, 0x8327,
+	0xBCEC, 0x68C0, 0xBCED, 0x67EC, 0xBCEE, 0x78B1, 0xBCEF, 0x7877,
+	0xBCF0, 0x62E3, 0xBCF1, 0x6361, 0xBCF2, 0x7B80, 0xBCF3, 0x4FED,
+	0xBCF4, 0x526A, 0xBCF5, 0x51CF, 0xBCF6, 0x8350, 0xBCF7, 0x69DB,
+	0xBCF8, 0x9274, 0xBCF9, 0x8DF5, 0xBCFA, 0x8D31, 0xBCFB, 0x89C1,
+	0xBCFC, 0x952E, 0xBCFD, 0x7BAD, 0xBCFE, 0x4EF6, 0xBD40, 0x7D37,
+	0xBD41, 0x7D38, 0xBD42, 0x7D39, 0xBD43, 0x7D3A, 0xBD44, 0x7D3B,
+	0xBD45, 0x7D3C, 0xBD46, 0x7D3D, 0xBD47, 0x7D3E, 0xBD48, 0x7D3F,
+	0xBD49, 0x7D40, 0xBD4A, 0x7D41, 0xBD4B, 0x7D42, 0xBD4C, 0x7D43,
+	0xBD4D, 0x7D44, 0xBD4E, 0x7D45, 0xBD4F, 0x7D46, 0xBD50, 0x7D47,
+	0xBD51, 0x7D48, 0xBD52, 0x7D49, 0xBD53, 0x7D4A, 0xBD54, 0x7D4B,
+	0xBD55, 0x7D4C, 0xBD56, 0x7D4D, 0xBD57, 0x7D4E, 0xBD58, 0x7D4F,
+	0xBD59, 0x7D50, 0xBD5A, 0x7D51, 0xBD5B, 0x7D52, 0xBD5C, 0x7D53,
+	0xBD5D, 0x7D54, 0xBD5E, 0x7D55, 0xBD5F, 0x7D56, 0xBD60, 0x7D57,
+	0xBD61, 0x7D58, 0xBD62, 0x7D59, 0xBD63, 0x7D5A, 0xBD64, 0x7D5B,
+	0xBD65, 0x7D5C, 0xBD66, 0x7D5D, 0xBD67, 0x7D5E, 0xBD68, 0x7D5F,
+	0xBD69, 0x7D60, 0xBD6A, 0x7D61, 0xBD6B, 0x7D62, 0xBD6C, 0x7D63,
+	0xBD6D, 0x7D64, 0xBD6E, 0x7D65, 0xBD6F, 0x7D66, 0xBD70, 0x7D67,
+	0xBD71, 0x7D68, 0xBD72, 0x7D69, 0xBD73, 0x7D6A, 0xBD74, 0x7D6B,
+	0xBD75, 0x7D6C, 0xBD76, 0x7D6D, 0xBD77, 0x7D6F, 0xBD78, 0x7D70,
+	0xBD79, 0x7D71, 0xBD7A, 0x7D72, 0xBD7B, 0x7D73, 0xBD7C, 0x7D74,
+	0xBD7D, 0x7D75, 0xBD7E, 0x7D76, 0xBD80, 0x7D78, 0xBD81, 0x7D79,
+	0xBD82, 0x7D7A, 0xBD83, 0x7D7B, 0xBD84, 0x7D7C, 0xBD85, 0x7D7D,
+	0xBD86, 0x7D7E, 0xBD87, 0x7D7F, 0xBD88, 0x7D80, 0xBD89, 0x7D81,
+	0xBD8A, 0x7D82, 0xBD8B, 0x7D83, 0xBD8C, 0x7D84, 0xBD8D, 0x7D85,
+	0xBD8E, 0x7D86, 0xBD8F, 0x7D87, 0xBD90, 0x7D88, 0xBD91, 0x7D89,
+	0xBD92, 0x7D8A, 0xBD93, 0x7D8B, 0xBD94, 0x7D8C, 0xBD95, 0x7D8D,
+	0xBD96, 0x7D8E, 0xBD97, 0x7D8F, 0xBD98, 0x7D90, 0xBD99, 0x7D91,
+	0xBD9A, 0x7D92, 0xBD9B, 0x7D93, 0xBD9C, 0x7D94, 0xBD9D, 0x7D95,
+	0xBD9E, 0x7D96, 0xBD9F, 0x7D97, 0xBDA0, 0x7D98, 0xBDA1, 0x5065,
+	0xBDA2, 0x8230, 0xBDA3, 0x5251, 0xBDA4, 0x996F, 0xBDA5, 0x6E10,
+	0xBDA6, 0x6E85, 0xBDA7, 0x6DA7, 0xBDA8, 0x5EFA, 0xBDA9, 0x50F5,
+	0xBDAA, 0x59DC, 0xBDAB, 0x5C06, 0xBDAC, 0x6D46, 0xBDAD, 0x6C5F,
+	0xBDAE, 0x7586, 0xBDAF, 0x848B, 0xBDB0, 0x6868, 0xBDB1, 0x5956,
+	0xBDB2, 0x8BB2, 0xBDB3, 0x5320, 0xBDB4, 0x9171, 0xBDB5, 0x964D,
+	0xBDB6, 0x8549, 0xBDB7, 0x6912, 0xBDB8, 0x7901, 0xBDB9, 0x7126,
+	0xBDBA, 0x80F6, 0xBDBB, 0x4EA4, 0xBDBC, 0x90CA, 0xBDBD, 0x6D47,
+	0xBDBE, 0x9A84, 0xBDBF, 0x5A07, 0xBDC0, 0x56BC, 0xBDC1, 0x6405,
+	0xBDC2, 0x94F0, 0xBDC3, 0x77EB, 0xBDC4, 0x4FA5, 0xBDC5, 0x811A,
+	0xBDC6, 0x72E1, 0xBDC7, 0x89D2, 0xBDC8, 0x997A, 0xBDC9, 0x7F34,
+	0xBDCA, 0x7EDE, 0xBDCB, 0x527F, 0xBDCC, 0x6559, 0xBDCD, 0x9175,
+	0xBDCE, 0x8F7F, 0xBDCF, 0x8F83, 0xBDD0, 0x53EB, 0xBDD1, 0x7A96,
+	0xBDD2, 0x63ED, 0xBDD3, 0x63A5, 0xBDD4, 0x7686, 0xBDD5, 0x79F8,
+	0xBDD6, 0x8857, 0xBDD7, 0x9636, 0xBDD8, 0x622A, 0xBDD9, 0x52AB,
+	0xBDDA, 0x8282, 0xBDDB, 0x6854, 0xBDDC, 0x6770, 0xBDDD, 0x6377,
+	0xBDDE, 0x776B, 0xBDDF, 0x7AED, 0xBDE0, 0x6D01, 0xBDE1, 0x7ED3,
+	0xBDE2, 0x89E3, 0xBDE3, 0x59D0, 0xBDE4, 0x6212, 0xBDE5, 0x85C9,
+	0xBDE6, 0x82A5, 0xBDE7, 0x754C, 0xBDE8, 0x501F, 0xBDE9, 0x4ECB,
+	0xBDEA, 0x75A5, 0xBDEB, 0x8BEB, 0xBDEC, 0x5C4A, 0xBDED, 0x5DFE,
+	0xBDEE, 0x7B4B, 0xBDEF, 0x65A4, 0xBDF0, 0x91D1, 0xBDF1, 0x4ECA,
+	0xBDF2, 0x6D25, 0xBDF3, 0x895F, 0xBDF4, 0x7D27, 0xBDF5, 0x9526,
+	0xBDF6, 0x4EC5, 0xBDF7, 0x8C28, 0xBDF8, 0x8FDB, 0xBDF9, 0x9773,
+	0xBDFA, 0x664B, 0xBDFB, 0x7981, 0xBDFC, 0x8FD1, 0xBDFD, 0x70EC,
+	0xBDFE, 0x6D78, 0xBE40, 0x7D99, 0xBE41, 0x7D9A, 0xBE42, 0x7D9B,
+	0xBE43, 0x7D9C, 0xBE44, 0x7D9D, 0xBE45, 0x7D9E, 0xBE46, 0x7D9F,
+	0xBE47, 0x7DA0, 0xBE48, 0x7DA1, 0xBE49, 0x7DA2, 0xBE4A, 0x7DA3,
+	0xBE4B, 0x7DA4, 0xBE4C, 0x7DA5, 0xBE4D, 0x7DA7, 0xBE4E, 0x7DA8,
+	0xBE4F, 0x7DA9, 0xBE50, 0x7DAA, 0xBE51, 0x7DAB, 0xBE52, 0x7DAC,
+	0xBE53, 0x7DAD, 0xBE54, 0x7DAF, 0xBE55, 0x7DB0, 0xBE56, 0x7DB1,
+	0xBE57, 0x7DB2, 0xBE58, 0x7DB3, 0xBE59, 0x7DB4, 0xBE5A, 0x7DB5,
+	0xBE5B, 0x7DB6, 0xBE5C, 0x7DB7, 0xBE5D, 0x7DB8, 0xBE5E, 0x7DB9,
+	0xBE5F, 0x7DBA, 0xBE60, 0x7DBB, 0xBE61, 0x7DBC, 0xBE62, 0x7DBD,
+	0xBE63, 0x7DBE, 0xBE64, 0x7DBF, 0xBE65, 0x7DC0, 0xBE66, 0x7DC1,
+	0xBE67, 0x7DC2, 0xBE68, 0x7DC3, 0xBE69, 0x7DC4, 0xBE6A, 0x7DC5,
+	0xBE6B, 0x7DC6, 0xBE6C, 0x7DC7, 0xBE6D, 0x7DC8, 0xBE6E, 0x7DC9,
+	0xBE6F, 0x7DCA, 0xBE70, 0x7DCB, 0xBE71, 0x7DCC, 0xBE72, 0x7DCD,
+	0xBE73, 0x7DCE, 0xBE74, 0x7DCF, 0xBE75, 0x7DD0, 0xBE76, 0x7DD1,
+	0xBE77, 0x7DD2, 0xBE78, 0x7DD3, 0xBE79, 0x7DD4, 0xBE7A, 0x7DD5,
+	0xBE7B, 0x7DD6, 0xBE7C, 0x7DD7, 0xBE7D, 0x7DD8, 0xBE7E, 0x7DD9,
+	0xBE80, 0x7DDA, 0xBE81, 0x7DDB, 0xBE82, 0x7DDC, 0xBE83, 0x7DDD,
+	0xBE84, 0x7DDE, 0xBE85, 0x7DDF, 0xBE86, 0x7DE0, 0xBE87, 0x7DE1,
+	0xBE88, 0x7DE2, 0xBE89, 0x7DE3, 0xBE8A, 0x7DE4, 0xBE8B, 0x7DE5,
+	0xBE8C, 0x7DE6, 0xBE8D, 0x7DE7, 0xBE8E, 0x7DE8, 0xBE8F, 0x7DE9,
+	0xBE90, 0x7DEA, 0xBE91, 0x7DEB, 0xBE92, 0x7DEC, 0xBE93, 0x7DED,
+	0xBE94, 0x7DEE, 0xBE95, 0x7DEF, 0xBE96, 0x7DF0, 0xBE97, 0x7DF1,
+	0xBE98, 0x7DF2, 0xBE99, 0x7DF3, 0xBE9A, 0x7DF4, 0xBE9B, 0x7DF5,
+	0xBE9C, 0x7DF6, 0xBE9D, 0x7DF7, 0xBE9E, 0x7DF8, 0xBE9F, 0x7DF9,
+	0xBEA0, 0x7DFA, 0xBEA1, 0x5C3D, 0xBEA2, 0x52B2, 0xBEA3, 0x8346,
+	0xBEA4, 0x5162, 0xBEA5, 0x830E, 0xBEA6, 0x775B, 0xBEA7, 0x6676,
+	0xBEA8, 0x9CB8, 0xBEA9, 0x4EAC, 0xBEAA, 0x60CA, 0xBEAB, 0x7CBE,
+	0xBEAC, 0x7CB3, 0xBEAD, 0x7ECF, 0xBEAE, 0x4E95, 0xBEAF, 0x8B66,
+	0xBEB0, 0x666F, 0xBEB1, 0x9888, 0xBEB2, 0x9759, 0xBEB3, 0x5883,
+	0xBEB4, 0x656C, 0xBEB5, 0x955C, 0xBEB6, 0x5F84, 0xBEB7, 0x75C9,
+	0xBEB8, 0x9756, 0xBEB9, 0x7ADF, 0xBEBA, 0x7ADE, 0xBEBB, 0x51C0,
+	0xBEBC, 0x70AF, 0xBEBD, 0x7A98, 0xBEBE, 0x63EA, 0xBEBF, 0x7A76,
+	0xBEC0, 0x7EA0, 0xBEC1, 0x7396, 0xBEC2, 0x97ED, 0xBEC3, 0x4E45,
+	0xBEC4, 0x7078, 0xBEC5, 0x4E5D, 0xBEC6, 0x9152, 0xBEC7, 0x53A9,
+	0xBEC8, 0x6551, 0xBEC9, 0x65E7, 0xBECA, 0x81FC, 0xBECB, 0x8205,
+	0xBECC, 0x548E, 0xBECD, 0x5C31, 0xBECE, 0x759A, 0xBECF, 0x97A0,
+	0xBED0, 0x62D8, 0xBED1, 0x72D9, 0xBED2, 0x75BD, 0xBED3, 0x5C45,
+	0xBED4, 0x9A79, 0xBED5, 0x83CA, 0xBED6, 0x5C40, 0xBED7, 0x5480,
+	0xBED8, 0x77E9, 0xBED9, 0x4E3E, 0xBEDA, 0x6CAE, 0xBEDB, 0x805A,
+	0xBEDC, 0x62D2, 0xBEDD, 0x636E, 0xBEDE, 0x5DE8, 0xBEDF, 0x5177,
+	0xBEE0, 0x8DDD, 0xBEE1, 0x8E1E, 0xBEE2, 0x952F, 0xBEE3, 0x4FF1,
+	0xBEE4, 0x53E5, 0xBEE5, 0x60E7, 0xBEE6, 0x70AC, 0xBEE7, 0x5267,
+	0xBEE8, 0x6350, 0xBEE9, 0x9E43, 0xBEEA, 0x5A1F, 0xBEEB, 0x5026,
+	0xBEEC, 0x7737, 0xBEED, 0x5377, 0xBEEE, 0x7EE2, 0xBEEF, 0x6485,
+	0xBEF0, 0x652B, 0xBEF1, 0x6289, 0xBEF2, 0x6398, 0xBEF3, 0x5014,
+	0xBEF4, 0x7235, 0xBEF5, 0x89C9, 0xBEF6, 0x51B3, 0xBEF7, 0x8BC0,
+	0xBEF8, 0x7EDD, 0xBEF9, 0x5747, 0xBEFA, 0x83CC, 0xBEFB, 0x94A7,
+	0xBEFC, 0x519B, 0xBEFD, 0x541B, 0xBEFE, 0x5CFB, 0xBF40, 0x7DFB,
+	0xBF41, 0x7DFC, 0xBF42, 0x7DFD, 0xBF43, 0x7DFE, 0xBF44, 0x7DFF,
+	0xBF45, 0x7E00, 0xBF46, 0x7E01, 0xBF47, 0x7E02, 0xBF48, 0x7E03,
+	0xBF49, 0x7E04, 0xBF4A, 0x7E05, 0xBF4B, 0x7E06, 0xBF4C, 0x7E07,
+	0xBF4D, 0x7E08, 0xBF4E, 0x7E09, 0xBF4F, 0x7E0A, 0xBF50, 0x7E0B,
+	0xBF51, 0x7E0C, 0xBF52, 0x7E0D, 0xBF53, 0x7E0E, 0xBF54, 0x7E0F,
+	0xBF55, 0x7E10, 0xBF56, 0x7E11, 0xBF57, 0x7E12, 0xBF58, 0x7E13,
+	0xBF59, 0x7E14, 0xBF5A, 0x7E15, 0xBF5B, 0x7E16, 0xBF5C, 0x7E17,
+	0xBF5D, 0x7E18, 0xBF5E, 0x7E19, 0xBF5F, 0x7E1A, 0xBF60, 0x7E1B,
+	0xBF61, 0x7E1C, 0xBF62, 0x7E1D, 0xBF63, 0x7E1E, 0xBF64, 0x7E1F,
+	0xBF65, 0x7E20, 0xBF66, 0x7E21, 0xBF67, 0x7E22, 0xBF68, 0x7E23,
+	0xBF69, 0x7E24, 0xBF6A, 0x7E25, 0xBF6B, 0x7E26, 0xBF6C, 0x7E27,
+	0xBF6D, 0x7E28, 0xBF6E, 0x7E29, 0xBF6F, 0x7E2A, 0xBF70, 0x7E2B,
+	0xBF71, 0x7E2C, 0xBF72, 0x7E2D, 0xBF73, 0x7E2E, 0xBF74, 0x7E2F,
+	0xBF75, 0x7E30, 0xBF76, 0x7E31, 0xBF77, 0x7E32, 0xBF78, 0x7E33,
+	0xBF79, 0x7E34, 0xBF7A, 0x7E35, 0xBF7B, 0x7E36, 0xBF7C, 0x7E37,
+	0xBF7D, 0x7E38, 0xBF7E, 0x7E39, 0xBF80, 0x7E3A, 0xBF81, 0x7E3C,
+	0xBF82, 0x7E3D, 0xBF83, 0x7E3E, 0xBF84, 0x7E3F, 0xBF85, 0x7E40,
+	0xBF86, 0x7E42, 0xBF87, 0x7E43, 0xBF88, 0x7E44, 0xBF89, 0x7E45,
+	0xBF8A, 0x7E46, 0xBF8B, 0x7E48, 0xBF8C, 0x7E49, 0xBF8D, 0x7E4A,
+	0xBF8E, 0x7E4B, 0xBF8F, 0x7E4C, 0xBF90, 0x7E4D, 0xBF91, 0x7E4E,
+	0xBF92, 0x7E4F, 0xBF93, 0x7E50, 0xBF94, 0x7E51, 0xBF95, 0x7E52,
+	0xBF96, 0x7E53, 0xBF97, 0x7E54, 0xBF98, 0x7E55, 0xBF99, 0x7E56,
+	0xBF9A, 0x7E57, 0xBF9B, 0x7E58, 0xBF9C, 0x7E59, 0xBF9D, 0x7E5A,
+	0xBF9E, 0x7E5B, 0xBF9F, 0x7E5C, 0xBFA0, 0x7E5D, 0xBFA1, 0x4FCA,
+	0xBFA2, 0x7AE3, 0xBFA3, 0x6D5A, 0xBFA4, 0x90E1, 0xBFA5, 0x9A8F,
+	0xBFA6, 0x5580, 0xBFA7, 0x5496, 0xBFA8, 0x5361, 0xBFA9, 0x54AF,
+	0xBFAA, 0x5F00, 0xBFAB, 0x63E9, 0xBFAC, 0x6977, 0xBFAD, 0x51EF,
+	0xBFAE, 0x6168, 0xBFAF, 0x520A, 0xBFB0, 0x582A, 0xBFB1, 0x52D8,
+	0xBFB2, 0x574E, 0xBFB3, 0x780D, 0xBFB4, 0x770B, 0xBFB5, 0x5EB7,
+	0xBFB6, 0x6177, 0xBFB7, 0x7CE0, 0xBFB8, 0x625B, 0xBFB9, 0x6297,
+	0xBFBA, 0x4EA2, 0xBFBB, 0x7095, 0xBFBC, 0x8003, 0xBFBD, 0x62F7,
+	0xBFBE, 0x70E4, 0xBFBF, 0x9760, 0xBFC0, 0x5777, 0xBFC1, 0x82DB,
+	0xBFC2, 0x67EF, 0xBFC3, 0x68F5, 0xBFC4, 0x78D5, 0xBFC5, 0x9897,
+	0xBFC6, 0x79D1, 0xBFC7, 0x58F3, 0xBFC8, 0x54B3, 0xBFC9, 0x53EF,
+	0xBFCA, 0x6E34, 0xBFCB, 0x514B, 0xBFCC, 0x523B, 0xBFCD, 0x5BA2,
+	0xBFCE, 0x8BFE, 0xBFCF, 0x80AF, 0xBFD0, 0x5543, 0xBFD1, 0x57A6,
+	0xBFD2, 0x6073, 0xBFD3, 0x5751, 0xBFD4, 0x542D, 0xBFD5, 0x7A7A,
+	0xBFD6, 0x6050, 0xBFD7, 0x5B54, 0xBFD8, 0x63A7, 0xBFD9, 0x62A0,
+	0xBFDA, 0x53E3, 0xBFDB, 0x6263, 0xBFDC, 0x5BC7, 0xBFDD, 0x67AF,
+	0xBFDE, 0x54ED, 0xBFDF, 0x7A9F, 0xBFE0, 0x82E6, 0xBFE1, 0x9177,
+	0xBFE2, 0x5E93, 0xBFE3, 0x88E4, 0xBFE4, 0x5938, 0xBFE5, 0x57AE,
+	0xBFE6, 0x630E, 0xBFE7, 0x8DE8, 0xBFE8, 0x80EF, 0xBFE9, 0x5757,
+	0xBFEA, 0x7B77, 0xBFEB, 0x4FA9, 0xBFEC, 0x5FEB, 0xBFED, 0x5BBD,
+	0xBFEE, 0x6B3E, 0xBFEF, 0x5321, 0xBFF0, 0x7B50, 0xBFF1, 0x72C2,
+	0xBFF2, 0x6846, 0xBFF3, 0x77FF, 0xBFF4, 0x7736, 0xBFF5, 0x65F7,
+	0xBFF6, 0x51B5, 0xBFF7, 0x4E8F, 0xBFF8, 0x76D4, 0xBFF9, 0x5CBF,
+	0xBFFA, 0x7AA5, 0xBFFB, 0x8475, 0xBFFC, 0x594E, 0xBFFD, 0x9B41,
+	0xBFFE, 0x5080, 0xC040, 0x7E5E, 0xC041, 0x7E5F, 0xC042, 0x7E60,
+	0xC043, 0x7E61, 0xC044, 0x7E62, 0xC045, 0x7E63, 0xC046, 0x7E64,
+	0xC047, 0x7E65, 0xC048, 0x7E66, 0xC049, 0x7E67, 0xC04A, 0x7E68,
+	0xC04B, 0x7E69, 0xC04C, 0x7E6A, 0xC04D, 0x7E6B, 0xC04E, 0x7E6C,
+	0xC04F, 0x7E6D, 0xC050, 0x7E6E, 0xC051, 0x7E6F, 0xC052, 0x7E70,
+	0xC053, 0x7E71, 0xC054, 0x7E72, 0xC055, 0x7E73, 0xC056, 0x7E74,
+	0xC057, 0x7E75, 0xC058, 0x7E76, 0xC059, 0x7E77, 0xC05A, 0x7E78,
+	0xC05B, 0x7E79, 0xC05C, 0x7E7A, 0xC05D, 0x7E7B, 0xC05E, 0x7E7C,
+	0xC05F, 0x7E7D, 0xC060, 0x7E7E, 0xC061, 0x7E7F, 0xC062, 0x7E80,
+	0xC063, 0x7E81, 0xC064, 0x7E83, 0xC065, 0x7E84, 0xC066, 0x7E85,
+	0xC067, 0x7E86, 0xC068, 0x7E87, 0xC069, 0x7E88, 0xC06A, 0x7E89,
+	0xC06B, 0x7E8A, 0xC06C, 0x7E8B, 0xC06D, 0x7E8C, 0xC06E, 0x7E8D,
+	0xC06F, 0x7E8E, 0xC070, 0x7E8F, 0xC071, 0x7E90, 0xC072, 0x7E91,
+	0xC073, 0x7E92, 0xC074, 0x7E93, 0xC075, 0x7E94, 0xC076, 0x7E95,
+	0xC077, 0x7E96, 0xC078, 0x7E97, 0xC079, 0x7E98, 0xC07A, 0x7E99,
+	0xC07B, 0x7E9A, 0xC07C, 0x7E9C, 0xC07D, 0x7E9D, 0xC07E, 0x7E9E,
+	0xC080, 0x7EAE, 0xC081, 0x7EB4, 0xC082, 0x7EBB, 0xC083, 0x7EBC,
+	0xC084, 0x7ED6, 0xC085, 0x7EE4, 0xC086, 0x7EEC, 0xC087, 0x7EF9,
+	0xC088, 0x7F0A, 0xC089, 0x7F10, 0xC08A, 0x7F1E, 0xC08B, 0x7F37,
+	0xC08C, 0x7F39, 0xC08D, 0x7F3B, 0xC08E, 0x7F3C, 0xC08F, 0x7F3D,
+	0xC090, 0x7F3E, 0xC091, 0x7F3F, 0xC092, 0x7F40, 0xC093, 0x7F41,
+	0xC094, 0x7F43, 0xC095, 0x7F46, 0xC096, 0x7F47, 0xC097, 0x7F48,
+	0xC098, 0x7F49, 0xC099, 0x7F4A, 0xC09A, 0x7F4B, 0xC09B, 0x7F4C,
+	0xC09C, 0x7F4D, 0xC09D, 0x7F4E, 0xC09E, 0x7F4F, 0xC09F, 0x7F52,
+	0xC0A0, 0x7F53, 0xC0A1, 0x9988, 0xC0A2, 0x6127, 0xC0A3, 0x6E83,
+	0xC0A4, 0x5764, 0xC0A5, 0x6606, 0xC0A6, 0x6346, 0xC0A7, 0x56F0,
+	0xC0A8, 0x62EC, 0xC0A9, 0x6269, 0xC0AA, 0x5ED3, 0xC0AB, 0x9614,
+	0xC0AC, 0x5783, 0xC0AD, 0x62C9, 0xC0AE, 0x5587, 0xC0AF, 0x8721,
+	0xC0B0, 0x814A, 0xC0B1, 0x8FA3, 0xC0B2, 0x5566, 0xC0B3, 0x83B1,
+	0xC0B4, 0x6765, 0xC0B5, 0x8D56, 0xC0B6, 0x84DD, 0xC0B7, 0x5A6A,
+	0xC0B8, 0x680F, 0xC0B9, 0x62E6, 0xC0BA, 0x7BEE, 0xC0BB, 0x9611,
+	0xC0BC, 0x5170, 0xC0BD, 0x6F9C, 0xC0BE, 0x8C30, 0xC0BF, 0x63FD,
+	0xC0C0, 0x89C8, 0xC0C1, 0x61D2, 0xC0C2, 0x7F06, 0xC0C3, 0x70C2,
+	0xC0C4, 0x6EE5, 0xC0C5, 0x7405, 0xC0C6, 0x6994, 0xC0C7, 0x72FC,
+	0xC0C8, 0x5ECA, 0xC0C9, 0x90CE, 0xC0CA, 0x6717, 0xC0CB, 0x6D6A,
+	0xC0CC, 0x635E, 0xC0CD, 0x52B3, 0xC0CE, 0x7262, 0xC0CF, 0x8001,
+	0xC0D0, 0x4F6C, 0xC0D1, 0x59E5, 0xC0D2, 0x916A, 0xC0D3, 0x70D9,
+	0xC0D4, 0x6D9D, 0xC0D5, 0x52D2, 0xC0D6, 0x4E50, 0xC0D7, 0x96F7,
+	0xC0D8, 0x956D, 0xC0D9, 0x857E, 0xC0DA, 0x78CA, 0xC0DB, 0x7D2F,
+	0xC0DC, 0x5121, 0xC0DD, 0x5792, 0xC0DE, 0x64C2, 0xC0DF, 0x808B,
+	0xC0E0, 0x7C7B, 0xC0E1, 0x6CEA, 0xC0E2, 0x68F1, 0xC0E3, 0x695E,
+	0xC0E4, 0x51B7, 0xC0E5, 0x5398, 0xC0E6, 0x68A8, 0xC0E7, 0x7281,
+	0xC0E8, 0x9ECE, 0xC0E9, 0x7BF1, 0xC0EA, 0x72F8, 0xC0EB, 0x79BB,
+	0xC0EC, 0x6F13, 0xC0ED, 0x7406, 0xC0EE, 0x674E, 0xC0EF, 0x91CC,
+	0xC0F0, 0x9CA4, 0xC0F1, 0x793C, 0xC0F2, 0x8389, 0xC0F3, 0x8354,
+	0xC0F4, 0x540F, 0xC0F5, 0x6817, 0xC0F6, 0x4E3D, 0xC0F7, 0x5389,
+	0xC0F8, 0x52B1, 0xC0F9, 0x783E, 0xC0FA, 0x5386, 0xC0FB, 0x5229,
+	0xC0FC, 0x5088, 0xC0FD, 0x4F8B, 0xC0FE, 0x4FD0, 0xC140, 0x7F56,
+	0xC141, 0x7F59, 0xC142, 0x7F5B, 0xC143, 0x7F5C, 0xC144, 0x7F5D,
+	0xC145, 0x7F5E, 0xC146, 0x7F60, 0xC147, 0x7F63, 0xC148, 0x7F64,
+	0xC149, 0x7F65, 0xC14A, 0x7F66, 0xC14B, 0x7F67, 0xC14C, 0x7F6B,
+	0xC14D, 0x7F6C, 0xC14E, 0x7F6D, 0xC14F, 0x7F6F, 0xC150, 0x7F70,
+	0xC151, 0x7F73, 0xC152, 0x7F75, 0xC153, 0x7F76, 0xC154, 0x7F77,
+	0xC155, 0x7F78, 0xC156, 0x7F7A, 0xC157, 0x7F7B, 0xC158, 0x7F7C,
+	0xC159, 0x7F7D, 0xC15A, 0x7F7F, 0xC15B, 0x7F80, 0xC15C, 0x7F82,
+	0xC15D, 0x7F83, 0xC15E, 0x7F84, 0xC15F, 0x7F85, 0xC160, 0x7F86,
+	0xC161, 0x7F87, 0xC162, 0x7F88, 0xC163, 0x7F89, 0xC164, 0x7F8B,
+	0xC165, 0x7F8D, 0xC166, 0x7F8F, 0xC167, 0x7F90, 0xC168, 0x7F91,
+	0xC169, 0x7F92, 0xC16A, 0x7F93, 0xC16B, 0x7F95, 0xC16C, 0x7F96,
+	0xC16D, 0x7F97, 0xC16E, 0x7F98, 0xC16F, 0x7F99, 0xC170, 0x7F9B,
+	0xC171, 0x7F9C, 0xC172, 0x7FA0, 0xC173, 0x7FA2, 0xC174, 0x7FA3,
+	0xC175, 0x7FA5, 0xC176, 0x7FA6, 0xC177, 0x7FA8, 0xC178, 0x7FA9,
+	0xC179, 0x7FAA, 0xC17A, 0x7FAB, 0xC17B, 0x7FAC, 0xC17C, 0x7FAD,
+	0xC17D, 0x7FAE, 0xC17E, 0x7FB1, 0xC180, 0x7FB3, 0xC181, 0x7FB4,
+	0xC182, 0x7FB5, 0xC183, 0x7FB6, 0xC184, 0x7FB7, 0xC185, 0x7FBA,
+	0xC186, 0x7FBB, 0xC187, 0x7FBE, 0xC188, 0x7FC0, 0xC189, 0x7FC2,
+	0xC18A, 0x7FC3, 0xC18B, 0x7FC4, 0xC18C, 0x7FC6, 0xC18D, 0x7FC7,
+	0xC18E, 0x7FC8, 0xC18F, 0x7FC9, 0xC190, 0x7FCB, 0xC191, 0x7FCD,
+	0xC192, 0x7FCF, 0xC193, 0x7FD0, 0xC194, 0x7FD1, 0xC195, 0x7FD2,
+	0xC196, 0x7FD3, 0xC197, 0x7FD6, 0xC198, 0x7FD7, 0xC199, 0x7FD9,
+	0xC19A, 0x7FDA, 0xC19B, 0x7FDB, 0xC19C, 0x7FDC, 0xC19D, 0x7FDD,
+	0xC19E, 0x7FDE, 0xC19F, 0x7FE2, 0xC1A0, 0x7FE3, 0xC1A1, 0x75E2,
+	0xC1A2, 0x7ACB, 0xC1A3, 0x7C92, 0xC1A4, 0x6CA5, 0xC1A5, 0x96B6,
+	0xC1A6, 0x529B, 0xC1A7, 0x7483, 0xC1A8, 0x54E9, 0xC1A9, 0x4FE9,
+	0xC1AA, 0x8054, 0xC1AB, 0x83B2, 0xC1AC, 0x8FDE, 0xC1AD, 0x9570,
+	0xC1AE, 0x5EC9, 0xC1AF, 0x601C, 0xC1B0, 0x6D9F, 0xC1B1, 0x5E18,
+	0xC1B2, 0x655B, 0xC1B3, 0x8138, 0xC1B4, 0x94FE, 0xC1B5, 0x604B,
+	0xC1B6, 0x70BC, 0xC1B7, 0x7EC3, 0xC1B8, 0x7CAE, 0xC1B9, 0x51C9,
+	0xC1BA, 0x6881, 0xC1BB, 0x7CB1, 0xC1BC, 0x826F, 0xC1BD, 0x4E24,
+	0xC1BE, 0x8F86, 0xC1BF, 0x91CF, 0xC1C0, 0x667E, 0xC1C1, 0x4EAE,
+	0xC1C2, 0x8C05, 0xC1C3, 0x64A9, 0xC1C4, 0x804A, 0xC1C5, 0x50DA,
+	0xC1C6, 0x7597, 0xC1C7, 0x71CE, 0xC1C8, 0x5BE5, 0xC1C9, 0x8FBD,
+	0xC1CA, 0x6F66, 0xC1CB, 0x4E86, 0xC1CC, 0x6482, 0xC1CD, 0x9563,
+	0xC1CE, 0x5ED6, 0xC1CF, 0x6599, 0xC1D0, 0x5217, 0xC1D1, 0x88C2,
+	0xC1D2, 0x70C8, 0xC1D3, 0x52A3, 0xC1D4, 0x730E, 0xC1D5, 0x7433,
+	0xC1D6, 0x6797, 0xC1D7, 0x78F7, 0xC1D8, 0x9716, 0xC1D9, 0x4E34,
+	0xC1DA, 0x90BB, 0xC1DB, 0x9CDE, 0xC1DC, 0x6DCB, 0xC1DD, 0x51DB,
+	0xC1DE, 0x8D41, 0xC1DF, 0x541D, 0xC1E0, 0x62CE, 0xC1E1, 0x73B2,
+	0xC1E2, 0x83F1, 0xC1E3, 0x96F6, 0xC1E4, 0x9F84, 0xC1E5, 0x94C3,
+	0xC1E6, 0x4F36, 0xC1E7, 0x7F9A, 0xC1E8, 0x51CC, 0xC1E9, 0x7075,
+	0xC1EA, 0x9675, 0xC1EB, 0x5CAD, 0xC1EC, 0x9886, 0xC1ED, 0x53E6,
+	0xC1EE, 0x4EE4, 0xC1EF, 0x6E9C, 0xC1F0, 0x7409, 0xC1F1, 0x69B4,
+	0xC1F2, 0x786B, 0xC1F3, 0x998F, 0xC1F4, 0x7559, 0xC1F5, 0x5218,
+	0xC1F6, 0x7624, 0xC1F7, 0x6D41, 0xC1F8, 0x67F3, 0xC1F9, 0x516D,
+	0xC1FA, 0x9F99, 0xC1FB, 0x804B, 0xC1FC, 0x5499, 0xC1FD, 0x7B3C,
+	0xC1FE, 0x7ABF, 0xC240, 0x7FE4, 0xC241, 0x7FE7, 0xC242, 0x7FE8,
+	0xC243, 0x7FEA, 0xC244, 0x7FEB, 0xC245, 0x7FEC, 0xC246, 0x7FED,
+	0xC247, 0x7FEF, 0xC248, 0x7FF2, 0xC249, 0x7FF4, 0xC24A, 0x7FF5,
+	0xC24B, 0x7FF6, 0xC24C, 0x7FF7, 0xC24D, 0x7FF8, 0xC24E, 0x7FF9,
+	0xC24F, 0x7FFA, 0xC250, 0x7FFD, 0xC251, 0x7FFE, 0xC252, 0x7FFF,
+	0xC253, 0x8002, 0xC254, 0x8007, 0xC255, 0x8008, 0xC256, 0x8009,
+	0xC257, 0x800A, 0xC258, 0x800E, 0xC259, 0x800F, 0xC25A, 0x8011,
+	0xC25B, 0x8013, 0xC25C, 0x801A, 0xC25D, 0x801B, 0xC25E, 0x801D,
+	0xC25F, 0x801E, 0xC260, 0x801F, 0xC261, 0x8021, 0xC262, 0x8023,
+	0xC263, 0x8024, 0xC264, 0x802B, 0xC265, 0x802C, 0xC266, 0x802D,
+	0xC267, 0x802E, 0xC268, 0x802F, 0xC269, 0x8030, 0xC26A, 0x8032,
+	0xC26B, 0x8034, 0xC26C, 0x8039, 0xC26D, 0x803A, 0xC26E, 0x803C,
+	0xC26F, 0x803E, 0xC270, 0x8040, 0xC271, 0x8041, 0xC272, 0x8044,
+	0xC273, 0x8045, 0xC274, 0x8047, 0xC275, 0x8048, 0xC276, 0x8049,
+	0xC277, 0x804E, 0xC278, 0x804F, 0xC279, 0x8050, 0xC27A, 0x8051,
+	0xC27B, 0x8053, 0xC27C, 0x8055, 0xC27D, 0x8056, 0xC27E, 0x8057,
+	0xC280, 0x8059, 0xC281, 0x805B, 0xC282, 0x805C, 0xC283, 0x805D,
+	0xC284, 0x805E, 0xC285, 0x805F, 0xC286, 0x8060, 0xC287, 0x8061,
+	0xC288, 0x8062, 0xC289, 0x8063, 0xC28A, 0x8064, 0xC28B, 0x8065,
+	0xC28C, 0x8066, 0xC28D, 0x8067, 0xC28E, 0x8068, 0xC28F, 0x806B,
+	0xC290, 0x806C, 0xC291, 0x806D, 0xC292, 0x806E, 0xC293, 0x806F,
+	0xC294, 0x8070, 0xC295, 0x8072, 0xC296, 0x8073, 0xC297, 0x8074,
+	0xC298, 0x8075, 0xC299, 0x8076, 0xC29A, 0x8077, 0xC29B, 0x8078,
+	0xC29C, 0x8079, 0xC29D, 0x807A, 0xC29E, 0x807B, 0xC29F, 0x807C,
+	0xC2A0, 0x807D, 0xC2A1, 0x9686, 0xC2A2, 0x5784, 0xC2A3, 0x62E2,
+	0xC2A4, 0x9647, 0xC2A5, 0x697C, 0xC2A6, 0x5A04, 0xC2A7, 0x6402,
+	0xC2A8, 0x7BD3, 0xC2A9, 0x6F0F, 0xC2AA, 0x964B, 0xC2AB, 0x82A6,
+	0xC2AC, 0x5362, 0xC2AD, 0x9885, 0xC2AE, 0x5E90, 0xC2AF, 0x7089,
+	0xC2B0, 0x63B3, 0xC2B1, 0x5364, 0xC2B2, 0x864F, 0xC2B3, 0x9C81,
+	0xC2B4, 0x9E93, 0xC2B5, 0x788C, 0xC2B6, 0x9732, 0xC2B7, 0x8DEF,
+	0xC2B8, 0x8D42, 0xC2B9, 0x9E7F, 0xC2BA, 0x6F5E, 0xC2BB, 0x7984,
+	0xC2BC, 0x5F55, 0xC2BD, 0x9646, 0xC2BE, 0x622E, 0xC2BF, 0x9A74,
+	0xC2C0, 0x5415, 0xC2C1, 0x94DD, 0xC2C2, 0x4FA3, 0xC2C3, 0x65C5,
+	0xC2C4, 0x5C65, 0xC2C5, 0x5C61, 0xC2C6, 0x7F15, 0xC2C7, 0x8651,
+	0xC2C8, 0x6C2F, 0xC2C9, 0x5F8B, 0xC2CA, 0x7387, 0xC2CB, 0x6EE4,
+	0xC2CC, 0x7EFF, 0xC2CD, 0x5CE6, 0xC2CE, 0x631B, 0xC2CF, 0x5B6A,
+	0xC2D0, 0x6EE6, 0xC2D1, 0x5375, 0xC2D2, 0x4E71, 0xC2D3, 0x63A0,
+	0xC2D4, 0x7565, 0xC2D5, 0x62A1, 0xC2D6, 0x8F6E, 0xC2D7, 0x4F26,
+	0xC2D8, 0x4ED1, 0xC2D9, 0x6CA6, 0xC2DA, 0x7EB6, 0xC2DB, 0x8BBA,
+	0xC2DC, 0x841D, 0xC2DD, 0x87BA, 0xC2DE, 0x7F57, 0xC2DF, 0x903B,
+	0xC2E0, 0x9523, 0xC2E1, 0x7BA9, 0xC2E2, 0x9AA1, 0xC2E3, 0x88F8,
+	0xC2E4, 0x843D, 0xC2E5, 0x6D1B, 0xC2E6, 0x9A86, 0xC2E7, 0x7EDC,
+	0xC2E8, 0x5988, 0xC2E9, 0x9EBB, 0xC2EA, 0x739B, 0xC2EB, 0x7801,
+	0xC2EC, 0x8682, 0xC2ED, 0x9A6C, 0xC2EE, 0x9A82, 0xC2EF, 0x561B,
+	0xC2F0, 0x5417, 0xC2F1, 0x57CB, 0xC2F2, 0x4E70, 0xC2F3, 0x9EA6,
+	0xC2F4, 0x5356, 0xC2F5, 0x8FC8, 0xC2F6, 0x8109, 0xC2F7, 0x7792,
+	0xC2F8, 0x9992, 0xC2F9, 0x86EE, 0xC2FA, 0x6EE1, 0xC2FB, 0x8513,
+	0xC2FC, 0x66FC, 0xC2FD, 0x6162, 0xC2FE, 0x6F2B, 0xC340, 0x807E,
+	0xC341, 0x8081, 0xC342, 0x8082, 0xC343, 0x8085, 0xC344, 0x8088,
+	0xC345, 0x808A, 0xC346, 0x808D, 0xC347, 0x808E, 0xC348, 0x808F,
+	0xC349, 0x8090, 0xC34A, 0x8091, 0xC34B, 0x8092, 0xC34C, 0x8094,
+	0xC34D, 0x8095, 0xC34E, 0x8097, 0xC34F, 0x8099, 0xC350, 0x809E,
+	0xC351, 0x80A3, 0xC352, 0x80A6, 0xC353, 0x80A7, 0xC354, 0x80A8,
+	0xC355, 0x80AC, 0xC356, 0x80B0, 0xC357, 0x80B3, 0xC358, 0x80B5,
+	0xC359, 0x80B6, 0xC35A, 0x80B8, 0xC35B, 0x80B9, 0xC35C, 0x80BB,
+	0xC35D, 0x80C5, 0xC35E, 0x80C7, 0xC35F, 0x80C8, 0xC360, 0x80C9,
+	0xC361, 0x80CA, 0xC362, 0x80CB, 0xC363, 0x80CF, 0xC364, 0x80D0,
+	0xC365, 0x80D1, 0xC366, 0x80D2, 0xC367, 0x80D3, 0xC368, 0x80D4,
+	0xC369, 0x80D5, 0xC36A, 0x80D8, 0xC36B, 0x80DF, 0xC36C, 0x80E0,
+	0xC36D, 0x80E2, 0xC36E, 0x80E3, 0xC36F, 0x80E6, 0xC370, 0x80EE,
+	0xC371, 0x80F5, 0xC372, 0x80F7, 0xC373, 0x80F9, 0xC374, 0x80FB,
+	0xC375, 0x80FE, 0xC376, 0x80FF, 0xC377, 0x8100, 0xC378, 0x8101,
+	0xC379, 0x8103, 0xC37A, 0x8104, 0xC37B, 0x8105, 0xC37C, 0x8107,
+	0xC37D, 0x8108, 0xC37E, 0x810B, 0xC380, 0x810C, 0xC381, 0x8115,
+	0xC382, 0x8117, 0xC383, 0x8119, 0xC384, 0x811B, 0xC385, 0x811C,
+	0xC386, 0x811D, 0xC387, 0x811F, 0xC388, 0x8120, 0xC389, 0x8121,
+	0xC38A, 0x8122, 0xC38B, 0x8123, 0xC38C, 0x8124, 0xC38D, 0x8125,
+	0xC38E, 0x8126, 0xC38F, 0x8127, 0xC390, 0x8128, 0xC391, 0x8129,
+	0xC392, 0x812A, 0xC393, 0x812B, 0xC394, 0x812D, 0xC395, 0x812E,
+	0xC396, 0x8130, 0xC397, 0x8133, 0xC398, 0x8134, 0xC399, 0x8135,
+	0xC39A, 0x8137, 0xC39B, 0x8139, 0xC39C, 0x813A, 0xC39D, 0x813B,
+	0xC39E, 0x813C, 0xC39F, 0x813D, 0xC3A0, 0x813F, 0xC3A1, 0x8C29,
+	0xC3A2, 0x8292, 0xC3A3, 0x832B, 0xC3A4, 0x76F2, 0xC3A5, 0x6C13,
+	0xC3A6, 0x5FD9, 0xC3A7, 0x83BD, 0xC3A8, 0x732B, 0xC3A9, 0x8305,
+	0xC3AA, 0x951A, 0xC3AB, 0x6BDB, 0xC3AC, 0x77DB, 0xC3AD, 0x94C6,
+	0xC3AE, 0x536F, 0xC3AF, 0x8302, 0xC3B0, 0x5192, 0xC3B1, 0x5E3D,
+	0xC3B2, 0x8C8C, 0xC3B3, 0x8D38, 0xC3B4, 0x4E48, 0xC3B5, 0x73AB,
+	0xC3B6, 0x679A, 0xC3B7, 0x6885, 0xC3B8, 0x9176, 0xC3B9, 0x9709,
+	0xC3BA, 0x7164, 0xC3BB, 0x6CA1, 0xC3BC, 0x7709, 0xC3BD, 0x5A92,
+	0xC3BE, 0x9541, 0xC3BF, 0x6BCF, 0xC3C0, 0x7F8E, 0xC3C1, 0x6627,
+	0xC3C2, 0x5BD0, 0xC3C3, 0x59B9, 0xC3C4, 0x5A9A, 0xC3C5, 0x95E8,
+	0xC3C6, 0x95F7, 0xC3C7, 0x4EEC, 0xC3C8, 0x840C, 0xC3C9, 0x8499,
+	0xC3CA, 0x6AAC, 0xC3CB, 0x76DF, 0xC3CC, 0x9530, 0xC3CD, 0x731B,
+	0xC3CE, 0x68A6, 0xC3CF, 0x5B5F, 0xC3D0, 0x772F, 0xC3D1, 0x919A,
+	0xC3D2, 0x9761, 0xC3D3, 0x7CDC, 0xC3D4, 0x8FF7, 0xC3D5, 0x8C1C,
+	0xC3D6, 0x5F25, 0xC3D7, 0x7C73, 0xC3D8, 0x79D8, 0xC3D9, 0x89C5,
+	0xC3DA, 0x6CCC, 0xC3DB, 0x871C, 0xC3DC, 0x5BC6, 0xC3DD, 0x5E42,
+	0xC3DE, 0x68C9, 0xC3DF, 0x7720, 0xC3E0, 0x7EF5, 0xC3E1, 0x5195,
+	0xC3E2, 0x514D, 0xC3E3, 0x52C9, 0xC3E4, 0x5A29, 0xC3E5, 0x7F05,
+	0xC3E6, 0x9762, 0xC3E7, 0x82D7, 0xC3E8, 0x63CF, 0xC3E9, 0x7784,
+	0xC3EA, 0x85D0, 0xC3EB, 0x79D2, 0xC3EC, 0x6E3A, 0xC3ED, 0x5E99,
+	0xC3EE, 0x5999, 0xC3EF, 0x8511, 0xC3F0, 0x706D, 0xC3F1, 0x6C11,
+	0xC3F2, 0x62BF, 0xC3F3, 0x76BF, 0xC3F4, 0x654F, 0xC3F5, 0x60AF,
+	0xC3F6, 0x95FD, 0xC3F7, 0x660E, 0xC3F8, 0x879F, 0xC3F9, 0x9E23,
+	0xC3FA, 0x94ED, 0xC3FB, 0x540D, 0xC3FC, 0x547D, 0xC3FD, 0x8C2C,
+	0xC3FE, 0x6478, 0xC440, 0x8140, 0xC441, 0x8141, 0xC442, 0x8142,
+	0xC443, 0x8143, 0xC444, 0x8144, 0xC445, 0x8145, 0xC446, 0x8147,
+	0xC447, 0x8149, 0xC448, 0x814D, 0xC449, 0x814E, 0xC44A, 0x814F,
+	0xC44B, 0x8152, 0xC44C, 0x8156, 0xC44D, 0x8157, 0xC44E, 0x8158,
+	0xC44F, 0x815B, 0xC450, 0x815C, 0xC451, 0x815D, 0xC452, 0x815E,
+	0xC453, 0x815F, 0xC454, 0x8161, 0xC455, 0x8162, 0xC456, 0x8163,
+	0xC457, 0x8164, 0xC458, 0x8166, 0xC459, 0x8168, 0xC45A, 0x816A,
+	0xC45B, 0x816B, 0xC45C, 0x816C, 0xC45D, 0x816F, 0xC45E, 0x8172,
+	0xC45F, 0x8173, 0xC460, 0x8175, 0xC461, 0x8176, 0xC462, 0x8177,
+	0xC463, 0x8178, 0xC464, 0x8181, 0xC465, 0x8183, 0xC466, 0x8184,
+	0xC467, 0x8185, 0xC468, 0x8186, 0xC469, 0x8187, 0xC46A, 0x8189,
+	0xC46B, 0x818B, 0xC46C, 0x818C, 0xC46D, 0x818D, 0xC46E, 0x818E,
+	0xC46F, 0x8190, 0xC470, 0x8192, 0xC471, 0x8193, 0xC472, 0x8194,
+	0xC473, 0x8195, 0xC474, 0x8196, 0xC475, 0x8197, 0xC476, 0x8199,
+	0xC477, 0x819A, 0xC478, 0x819E, 0xC479, 0x819F, 0xC47A, 0x81A0,
+	0xC47B, 0x81A1, 0xC47C, 0x81A2, 0xC47D, 0x81A4, 0xC47E, 0x81A5,
+	0xC480, 0x81A7, 0xC481, 0x81A9, 0xC482, 0x81AB, 0xC483, 0x81AC,
+	0xC484, 0x81AD, 0xC485, 0x81AE, 0xC486, 0x81AF, 0xC487, 0x81B0,
+	0xC488, 0x81B1, 0xC489, 0x81B2, 0xC48A, 0x81B4, 0xC48B, 0x81B5,
+	0xC48C, 0x81B6, 0xC48D, 0x81B7, 0xC48E, 0x81B8, 0xC48F, 0x81B9,
+	0xC490, 0x81BC, 0xC491, 0x81BD, 0xC492, 0x81BE, 0xC493, 0x81BF,
+	0xC494, 0x81C4, 0xC495, 0x81C5, 0xC496, 0x81C7, 0xC497, 0x81C8,
+	0xC498, 0x81C9, 0xC499, 0x81CB, 0xC49A, 0x81CD, 0xC49B, 0x81CE,
+	0xC49C, 0x81CF, 0xC49D, 0x81D0, 0xC49E, 0x81D1, 0xC49F, 0x81D2,
+	0xC4A0, 0x81D3, 0xC4A1, 0x6479, 0xC4A2, 0x8611, 0xC4A3, 0x6A21,
+	0xC4A4, 0x819C, 0xC4A5, 0x78E8, 0xC4A6, 0x6469, 0xC4A7, 0x9B54,
+	0xC4A8, 0x62B9, 0xC4A9, 0x672B, 0xC4AA, 0x83AB, 0xC4AB, 0x58A8,
+	0xC4AC, 0x9ED8, 0xC4AD, 0x6CAB, 0xC4AE, 0x6F20, 0xC4AF, 0x5BDE,
+	0xC4B0, 0x964C, 0xC4B1, 0x8C0B, 0xC4B2, 0x725F, 0xC4B3, 0x67D0,
+	0xC4B4, 0x62C7, 0xC4B5, 0x7261, 0xC4B6, 0x4EA9, 0xC4B7, 0x59C6,
+	0xC4B8, 0x6BCD, 0xC4B9, 0x5893, 0xC4BA, 0x66AE, 0xC4BB, 0x5E55,
+	0xC4BC, 0x52DF, 0xC4BD, 0x6155, 0xC4BE, 0x6728, 0xC4BF, 0x76EE,
+	0xC4C0, 0x7766, 0xC4C1, 0x7267, 0xC4C2, 0x7A46, 0xC4C3, 0x62FF,
+	0xC4C4, 0x54EA, 0xC4C5, 0x5450, 0xC4C6, 0x94A0, 0xC4C7, 0x90A3,
+	0xC4C8, 0x5A1C, 0xC4C9, 0x7EB3, 0xC4CA, 0x6C16, 0xC4CB, 0x4E43,
+	0xC4CC, 0x5976, 0xC4CD, 0x8010, 0xC4CE, 0x5948, 0xC4CF, 0x5357,
+	0xC4D0, 0x7537, 0xC4D1, 0x96BE, 0xC4D2, 0x56CA, 0xC4D3, 0x6320,
+	0xC4D4, 0x8111, 0xC4D5, 0x607C, 0xC4D6, 0x95F9, 0xC4D7, 0x6DD6,
+	0xC4D8, 0x5462, 0xC4D9, 0x9981, 0xC4DA, 0x5185, 0xC4DB, 0x5AE9,
+	0xC4DC, 0x80FD, 0xC4DD, 0x59AE, 0xC4DE, 0x9713, 0xC4DF, 0x502A,
+	0xC4E0, 0x6CE5, 0xC4E1, 0x5C3C, 0xC4E2, 0x62DF, 0xC4E3, 0x4F60,
+	0xC4E4, 0x533F, 0xC4E5, 0x817B, 0xC4E6, 0x9006, 0xC4E7, 0x6EBA,
+	0xC4E8, 0x852B, 0xC4E9, 0x62C8, 0xC4EA, 0x5E74, 0xC4EB, 0x78BE,
+	0xC4EC, 0x64B5, 0xC4ED, 0x637B, 0xC4EE, 0x5FF5, 0xC4EF, 0x5A18,
+	0xC4F0, 0x917F, 0xC4F1, 0x9E1F, 0xC4F2, 0x5C3F, 0xC4F3, 0x634F,
+	0xC4F4, 0x8042, 0xC4F5, 0x5B7D, 0xC4F6, 0x556E, 0xC4F7, 0x954A,
+	0xC4F8, 0x954D, 0xC4F9, 0x6D85, 0xC4FA, 0x60A8, 0xC4FB, 0x67E0,
+	0xC4FC, 0x72DE, 0xC4FD, 0x51DD, 0xC4FE, 0x5B81, 0xC540, 0x81D4,
+	0xC541, 0x81D5, 0xC542, 0x81D6, 0xC543, 0x81D7, 0xC544, 0x81D8,
+	0xC545, 0x81D9, 0xC546, 0x81DA, 0xC547, 0x81DB, 0xC548, 0x81DC,
+	0xC549, 0x81DD, 0xC54A, 0x81DE, 0xC54B, 0x81DF, 0xC54C, 0x81E0,
+	0xC54D, 0x81E1, 0xC54E, 0x81E2, 0xC54F, 0x81E4, 0xC550, 0x81E5,
+	0xC551, 0x81E6, 0xC552, 0x81E8, 0xC553, 0x81E9, 0xC554, 0x81EB,
+	0xC555, 0x81EE, 0xC556, 0x81EF, 0xC557, 0x81F0, 0xC558, 0x81F1,
+	0xC559, 0x81F2, 0xC55A, 0x81F5, 0xC55B, 0x81F6, 0xC55C, 0x81F7,
+	0xC55D, 0x81F8, 0xC55E, 0x81F9, 0xC55F, 0x81FA, 0xC560, 0x81FD,
+	0xC561, 0x81FF, 0xC562, 0x8203, 0xC563, 0x8207, 0xC564, 0x8208,
+	0xC565, 0x8209, 0xC566, 0x820A, 0xC567, 0x820B, 0xC568, 0x820E,
+	0xC569, 0x820F, 0xC56A, 0x8211, 0xC56B, 0x8213, 0xC56C, 0x8215,
+	0xC56D, 0x8216, 0xC56E, 0x8217, 0xC56F, 0x8218, 0xC570, 0x8219,
+	0xC571, 0x821A, 0xC572, 0x821D, 0xC573, 0x8220, 0xC574, 0x8224,
+	0xC575, 0x8225, 0xC576, 0x8226, 0xC577, 0x8227, 0xC578, 0x8229,
+	0xC579, 0x822E, 0xC57A, 0x8232, 0xC57B, 0x823A, 0xC57C, 0x823C,
+	0xC57D, 0x823D, 0xC57E, 0x823F, 0xC580, 0x8240, 0xC581, 0x8241,
+	0xC582, 0x8242, 0xC583, 0x8243, 0xC584, 0x8245, 0xC585, 0x8246,
+	0xC586, 0x8248, 0xC587, 0x824A, 0xC588, 0x824C, 0xC589, 0x824D,
+	0xC58A, 0x824E, 0xC58B, 0x8250, 0xC58C, 0x8251, 0xC58D, 0x8252,
+	0xC58E, 0x8253, 0xC58F, 0x8254, 0xC590, 0x8255, 0xC591, 0x8256,
+	0xC592, 0x8257, 0xC593, 0x8259, 0xC594, 0x825B, 0xC595, 0x825C,
+	0xC596, 0x825D, 0xC597, 0x825E, 0xC598, 0x8260, 0xC599, 0x8261,
+	0xC59A, 0x8262, 0xC59B, 0x8263, 0xC59C, 0x8264, 0xC59D, 0x8265,
+	0xC59E, 0x8266, 0xC59F, 0x8267, 0xC5A0, 0x8269, 0xC5A1, 0x62E7,
+	0xC5A2, 0x6CDE, 0xC5A3, 0x725B, 0xC5A4, 0x626D, 0xC5A5, 0x94AE,
+	0xC5A6, 0x7EBD, 0xC5A7, 0x8113, 0xC5A8, 0x6D53, 0xC5A9, 0x519C,
+	0xC5AA, 0x5F04, 0xC5AB, 0x5974, 0xC5AC, 0x52AA, 0xC5AD, 0x6012,
+	0xC5AE, 0x5973, 0xC5AF, 0x6696, 0xC5B0, 0x8650, 0xC5B1, 0x759F,
+	0xC5B2, 0x632A, 0xC5B3, 0x61E6, 0xC5B4, 0x7CEF, 0xC5B5, 0x8BFA,
+	0xC5B6, 0x54E6, 0xC5B7, 0x6B27, 0xC5B8, 0x9E25, 0xC5B9, 0x6BB4,
+	0xC5BA, 0x85D5, 0xC5BB, 0x5455, 0xC5BC, 0x5076, 0xC5BD, 0x6CA4,
+	0xC5BE, 0x556A, 0xC5BF, 0x8DB4, 0xC5C0, 0x722C, 0xC5C1, 0x5E15,
+	0xC5C2, 0x6015, 0xC5C3, 0x7436, 0xC5C4, 0x62CD, 0xC5C5, 0x6392,
+	0xC5C6, 0x724C, 0xC5C7, 0x5F98, 0xC5C8, 0x6E43, 0xC5C9, 0x6D3E,
+	0xC5CA, 0x6500, 0xC5CB, 0x6F58, 0xC5CC, 0x76D8, 0xC5CD, 0x78D0,
+	0xC5CE, 0x76FC, 0xC5CF, 0x7554, 0xC5D0, 0x5224, 0xC5D1, 0x53DB,
+	0xC5D2, 0x4E53, 0xC5D3, 0x5E9E, 0xC5D4, 0x65C1, 0xC5D5, 0x802A,
+	0xC5D6, 0x80D6, 0xC5D7, 0x629B, 0xC5D8, 0x5486, 0xC5D9, 0x5228,
+	0xC5DA, 0x70AE, 0xC5DB, 0x888D, 0xC5DC, 0x8DD1, 0xC5DD, 0x6CE1,
+	0xC5DE, 0x5478, 0xC5DF, 0x80DA, 0xC5E0, 0x57F9, 0xC5E1, 0x88F4,
+	0xC5E2, 0x8D54, 0xC5E3, 0x966A, 0xC5E4, 0x914D, 0xC5E5, 0x4F69,
+	0xC5E6, 0x6C9B, 0xC5E7, 0x55B7, 0xC5E8, 0x76C6, 0xC5E9, 0x7830,
+	0xC5EA, 0x62A8, 0xC5EB, 0x70F9, 0xC5EC, 0x6F8E, 0xC5ED, 0x5F6D,
+	0xC5EE, 0x84EC, 0xC5EF, 0x68DA, 0xC5F0, 0x787C, 0xC5F1, 0x7BF7,
+	0xC5F2, 0x81A8, 0xC5F3, 0x670B, 0xC5F4, 0x9E4F, 0xC5F5, 0x6367,
+	0xC5F6, 0x78B0, 0xC5F7, 0x576F, 0xC5F8, 0x7812, 0xC5F9, 0x9739,
+	0xC5FA, 0x6279, 0xC5FB, 0x62AB, 0xC5FC, 0x5288, 0xC5FD, 0x7435,
+	0xC5FE, 0x6BD7, 0xC640, 0x826A, 0xC641, 0x826B, 0xC642, 0x826C,
+	0xC643, 0x826D, 0xC644, 0x8271, 0xC645, 0x8275, 0xC646, 0x8276,
+	0xC647, 0x8277, 0xC648, 0x8278, 0xC649, 0x827B, 0xC64A, 0x827C,
+	0xC64B, 0x8280, 0xC64C, 0x8281, 0xC64D, 0x8283, 0xC64E, 0x8285,
+	0xC64F, 0x8286, 0xC650, 0x8287, 0xC651, 0x8289, 0xC652, 0x828C,
+	0xC653, 0x8290, 0xC654, 0x8293, 0xC655, 0x8294, 0xC656, 0x8295,
+	0xC657, 0x8296, 0xC658, 0x829A, 0xC659, 0x829B, 0xC65A, 0x829E,
+	0xC65B, 0x82A0, 0xC65C, 0x82A2, 0xC65D, 0x82A3, 0xC65E, 0x82A7,
+	0xC65F, 0x82B2, 0xC660, 0x82B5, 0xC661, 0x82B6, 0xC662, 0x82BA,
+	0xC663, 0x82BB, 0xC664, 0x82BC, 0xC665, 0x82BF, 0xC666, 0x82C0,
+	0xC667, 0x82C2, 0xC668, 0x82C3, 0xC669, 0x82C5, 0xC66A, 0x82C6,
+	0xC66B, 0x82C9, 0xC66C, 0x82D0, 0xC66D, 0x82D6, 0xC66E, 0x82D9,
+	0xC66F, 0x82DA, 0xC670, 0x82DD, 0xC671, 0x82E2, 0xC672, 0x82E7,
+	0xC673, 0x82E8, 0xC674, 0x82E9, 0xC675, 0x82EA, 0xC676, 0x82EC,
+	0xC677, 0x82ED, 0xC678, 0x82EE, 0xC679, 0x82F0, 0xC67A, 0x82F2,
+	0xC67B, 0x82F3, 0xC67C, 0x82F5, 0xC67D, 0x82F6, 0xC67E, 0x82F8,
+	0xC680, 0x82FA, 0xC681, 0x82FC, 0xC682, 0x82FD, 0xC683, 0x82FE,
+	0xC684, 0x82FF, 0xC685, 0x8300, 0xC686, 0x830A, 0xC687, 0x830B,
+	0xC688, 0x830D, 0xC689, 0x8310, 0xC68A, 0x8312, 0xC68B, 0x8313,
+	0xC68C, 0x8316, 0xC68D, 0x8318, 0xC68E, 0x8319, 0xC68F, 0x831D,
+	0xC690, 0x831E, 0xC691, 0x831F, 0xC692, 0x8320, 0xC693, 0x8321,
+	0xC694, 0x8322, 0xC695, 0x8323, 0xC696, 0x8324, 0xC697, 0x8325,
+	0xC698, 0x8326, 0xC699, 0x8329, 0xC69A, 0x832A, 0xC69B, 0x832E,
+	0xC69C, 0x8330, 0xC69D, 0x8332, 0xC69E, 0x8337, 0xC69F, 0x833B,
+	0xC6A0, 0x833D, 0xC6A1, 0x5564, 0xC6A2, 0x813E, 0xC6A3, 0x75B2,
+	0xC6A4, 0x76AE, 0xC6A5, 0x5339, 0xC6A6, 0x75DE, 0xC6A7, 0x50FB,
+	0xC6A8, 0x5C41, 0xC6A9, 0x8B6C, 0xC6AA, 0x7BC7, 0xC6AB, 0x504F,
+	0xC6AC, 0x7247, 0xC6AD, 0x9A97, 0xC6AE, 0x98D8, 0xC6AF, 0x6F02,
+	0xC6B0, 0x74E2, 0xC6B1, 0x7968, 0xC6B2, 0x6487, 0xC6B3, 0x77A5,
+	0xC6B4, 0x62FC, 0xC6B5, 0x9891, 0xC6B6, 0x8D2B, 0xC6B7, 0x54C1,
+	0xC6B8, 0x8058, 0xC6B9, 0x4E52, 0xC6BA, 0x576A, 0xC6BB, 0x82F9,
+	0xC6BC, 0x840D, 0xC6BD, 0x5E73, 0xC6BE, 0x51ED, 0xC6BF, 0x74F6,
+	0xC6C0, 0x8BC4, 0xC6C1, 0x5C4F, 0xC6C2, 0x5761, 0xC6C3, 0x6CFC,
+	0xC6C4, 0x9887, 0xC6C5, 0x5A46, 0xC6C6, 0x7834, 0xC6C7, 0x9B44,
+	0xC6C8, 0x8FEB, 0xC6C9, 0x7C95, 0xC6CA, 0x5256, 0xC6CB, 0x6251,
+	0xC6CC, 0x94FA, 0xC6CD, 0x4EC6, 0xC6CE, 0x8386, 0xC6CF, 0x8461,
+	0xC6D0, 0x83E9, 0xC6D1, 0x84B2, 0xC6D2, 0x57D4, 0xC6D3, 0x6734,
+	0xC6D4, 0x5703, 0xC6D5, 0x666E, 0xC6D6, 0x6D66, 0xC6D7, 0x8C31,
+	0xC6D8, 0x66DD, 0xC6D9, 0x7011, 0xC6DA, 0x671F, 0xC6DB, 0x6B3A,
+	0xC6DC, 0x6816, 0xC6DD, 0x621A, 0xC6DE, 0x59BB, 0xC6DF, 0x4E03,
+	0xC6E0, 0x51C4, 0xC6E1, 0x6F06, 0xC6E2, 0x67D2, 0xC6E3, 0x6C8F,
+	0xC6E4, 0x5176, 0xC6E5, 0x68CB, 0xC6E6, 0x5947, 0xC6E7, 0x6B67,
+	0xC6E8, 0x7566, 0xC6E9, 0x5D0E, 0xC6EA, 0x8110, 0xC6EB, 0x9F50,
+	0xC6EC, 0x65D7, 0xC6ED, 0x7948, 0xC6EE, 0x7941, 0xC6EF, 0x9A91,
+	0xC6F0, 0x8D77, 0xC6F1, 0x5C82, 0xC6F2, 0x4E5E, 0xC6F3, 0x4F01,
+	0xC6F4, 0x542F, 0xC6F5, 0x5951, 0xC6F6, 0x780C, 0xC6F7, 0x5668,
+	0xC6F8, 0x6C14, 0xC6F9, 0x8FC4, 0xC6FA, 0x5F03, 0xC6FB, 0x6C7D,
+	0xC6FC, 0x6CE3, 0xC6FD, 0x8BAB, 0xC6FE, 0x6390, 0xC740, 0x833E,
+	0xC741, 0x833F, 0xC742, 0x8341, 0xC743, 0x8342, 0xC744, 0x8344,
+	0xC745, 0x8345, 0xC746, 0x8348, 0xC747, 0x834A, 0xC748, 0x834B,
+	0xC749, 0x834C, 0xC74A, 0x834D, 0xC74B, 0x834E, 0xC74C, 0x8353,
+	0xC74D, 0x8355, 0xC74E, 0x8356, 0xC74F, 0x8357, 0xC750, 0x8358,
+	0xC751, 0x8359, 0xC752, 0x835D, 0xC753, 0x8362, 0xC754, 0x8370,
+	0xC755, 0x8371, 0xC756, 0x8372, 0xC757, 0x8373, 0xC758, 0x8374,
+	0xC759, 0x8375, 0xC75A, 0x8376, 0xC75B, 0x8379, 0xC75C, 0x837A,
+	0xC75D, 0x837E, 0xC75E, 0x837F, 0xC75F, 0x8380, 0xC760, 0x8381,
+	0xC761, 0x8382, 0xC762, 0x8383, 0xC763, 0x8384, 0xC764, 0x8387,
+	0xC765, 0x8388, 0xC766, 0x838A, 0xC767, 0x838B, 0xC768, 0x838C,
+	0xC769, 0x838D, 0xC76A, 0x838F, 0xC76B, 0x8390, 0xC76C, 0x8391,
+	0xC76D, 0x8394, 0xC76E, 0x8395, 0xC76F, 0x8396, 0xC770, 0x8397,
+	0xC771, 0x8399, 0xC772, 0x839A, 0xC773, 0x839D, 0xC774, 0x839F,
+	0xC775, 0x83A1, 0xC776, 0x83A2, 0xC777, 0x83A3, 0xC778, 0x83A4,
+	0xC779, 0x83A5, 0xC77A, 0x83A6, 0xC77B, 0x83A7, 0xC77C, 0x83AC,
+	0xC77D, 0x83AD, 0xC77E, 0x83AE, 0xC780, 0x83AF, 0xC781, 0x83B5,
+	0xC782, 0x83BB, 0xC783, 0x83BE, 0xC784, 0x83BF, 0xC785, 0x83C2,
+	0xC786, 0x83C3, 0xC787, 0x83C4, 0xC788, 0x83C6, 0xC789, 0x83C8,
+	0xC78A, 0x83C9, 0xC78B, 0x83CB, 0xC78C, 0x83CD, 0xC78D, 0x83CE,
+	0xC78E, 0x83D0, 0xC78F, 0x83D1, 0xC790, 0x83D2, 0xC791, 0x83D3,
+	0xC792, 0x83D5, 0xC793, 0x83D7, 0xC794, 0x83D9, 0xC795, 0x83DA,
+	0xC796, 0x83DB, 0xC797, 0x83DE, 0xC798, 0x83E2, 0xC799, 0x83E3,
+	0xC79A, 0x83E4, 0xC79B, 0x83E6, 0xC79C, 0x83E7, 0xC79D, 0x83E8,
+	0xC79E, 0x83EB, 0xC79F, 0x83EC, 0xC7A0, 0x83ED, 0xC7A1, 0x6070,
+	0xC7A2, 0x6D3D, 0xC7A3, 0x7275, 0xC7A4, 0x6266, 0xC7A5, 0x948E,
+	0xC7A6, 0x94C5, 0xC7A7, 0x5343, 0xC7A8, 0x8FC1, 0xC7A9, 0x7B7E,
+	0xC7AA, 0x4EDF, 0xC7AB, 0x8C26, 0xC7AC, 0x4E7E, 0xC7AD, 0x9ED4,
+	0xC7AE, 0x94B1, 0xC7AF, 0x94B3, 0xC7B0, 0x524D, 0xC7B1, 0x6F5C,
+	0xC7B2, 0x9063, 0xC7B3, 0x6D45, 0xC7B4, 0x8C34, 0xC7B5, 0x5811,
+	0xC7B6, 0x5D4C, 0xC7B7, 0x6B20, 0xC7B8, 0x6B49, 0xC7B9, 0x67AA,
+	0xC7BA, 0x545B, 0xC7BB, 0x8154, 0xC7BC, 0x7F8C, 0xC7BD, 0x5899,
+	0xC7BE, 0x8537, 0xC7BF, 0x5F3A, 0xC7C0, 0x62A2, 0xC7C1, 0x6A47,
+	0xC7C2, 0x9539, 0xC7C3, 0x6572, 0xC7C4, 0x6084, 0xC7C5, 0x6865,
+	0xC7C6, 0x77A7, 0xC7C7, 0x4E54, 0xC7C8, 0x4FA8, 0xC7C9, 0x5DE7,
+	0xC7CA, 0x9798, 0xC7CB, 0x64AC, 0xC7CC, 0x7FD8, 0xC7CD, 0x5CED,
+	0xC7CE, 0x4FCF, 0xC7CF, 0x7A8D, 0xC7D0, 0x5207, 0xC7D1, 0x8304,
+	0xC7D2, 0x4E14, 0xC7D3, 0x602F, 0xC7D4, 0x7A83, 0xC7D5, 0x94A6,
+	0xC7D6, 0x4FB5, 0xC7D7, 0x4EB2, 0xC7D8, 0x79E6, 0xC7D9, 0x7434,
+	0xC7DA, 0x52E4, 0xC7DB, 0x82B9, 0xC7DC, 0x64D2, 0xC7DD, 0x79BD,
+	0xC7DE, 0x5BDD, 0xC7DF, 0x6C81, 0xC7E0, 0x9752, 0xC7E1, 0x8F7B,
+	0xC7E2, 0x6C22, 0xC7E3, 0x503E, 0xC7E4, 0x537F, 0xC7E5, 0x6E05,
+	0xC7E6, 0x64CE, 0xC7E7, 0x6674, 0xC7E8, 0x6C30, 0xC7E9, 0x60C5,
+	0xC7EA, 0x9877, 0xC7EB, 0x8BF7, 0xC7EC, 0x5E86, 0xC7ED, 0x743C,
+	0xC7EE, 0x7A77, 0xC7EF, 0x79CB, 0xC7F0, 0x4E18, 0xC7F1, 0x90B1,
+	0xC7F2, 0x7403, 0xC7F3, 0x6C42, 0xC7F4, 0x56DA, 0xC7F5, 0x914B,
+	0xC7F6, 0x6CC5, 0xC7F7, 0x8D8B, 0xC7F8, 0x533A, 0xC7F9, 0x86C6,
+	0xC7FA, 0x66F2, 0xC7FB, 0x8EAF, 0xC7FC, 0x5C48, 0xC7FD, 0x9A71,
+	0xC7FE, 0x6E20, 0xC840, 0x83EE, 0xC841, 0x83EF, 0xC842, 0x83F3,
+	0xC843, 0x83F4, 0xC844, 0x83F5, 0xC845, 0x83F6, 0xC846, 0x83F7,
+	0xC847, 0x83FA, 0xC848, 0x83FB, 0xC849, 0x83FC, 0xC84A, 0x83FE,
+	0xC84B, 0x83FF, 0xC84C, 0x8400, 0xC84D, 0x8402, 0xC84E, 0x8405,
+	0xC84F, 0x8407, 0xC850, 0x8408, 0xC851, 0x8409, 0xC852, 0x840A,
+	0xC853, 0x8410, 0xC854, 0x8412, 0xC855, 0x8413, 0xC856, 0x8414,
+	0xC857, 0x8415, 0xC858, 0x8416, 0xC859, 0x8417, 0xC85A, 0x8419,
+	0xC85B, 0x841A, 0xC85C, 0x841B, 0xC85D, 0x841E, 0xC85E, 0x841F,
+	0xC85F, 0x8420, 0xC860, 0x8421, 0xC861, 0x8422, 0xC862, 0x8423,
+	0xC863, 0x8429, 0xC864, 0x842A, 0xC865, 0x842B, 0xC866, 0x842C,
+	0xC867, 0x842D, 0xC868, 0x842E, 0xC869, 0x842F, 0xC86A, 0x8430,
+	0xC86B, 0x8432, 0xC86C, 0x8433, 0xC86D, 0x8434, 0xC86E, 0x8435,
+	0xC86F, 0x8436, 0xC870, 0x8437, 0xC871, 0x8439, 0xC872, 0x843A,
+	0xC873, 0x843B, 0xC874, 0x843E, 0xC875, 0x843F, 0xC876, 0x8440,
+	0xC877, 0x8441, 0xC878, 0x8442, 0xC879, 0x8443, 0xC87A, 0x8444,
+	0xC87B, 0x8445, 0xC87C, 0x8447, 0xC87D, 0x8448, 0xC87E, 0x8449,
+	0xC880, 0x844A, 0xC881, 0x844B, 0xC882, 0x844C, 0xC883, 0x844D,
+	0xC884, 0x844E, 0xC885, 0x844F, 0xC886, 0x8450, 0xC887, 0x8452,
+	0xC888, 0x8453, 0xC889, 0x8454, 0xC88A, 0x8455, 0xC88B, 0x8456,
+	0xC88C, 0x8458, 0xC88D, 0x845D, 0xC88E, 0x845E, 0xC88F, 0x845F,
+	0xC890, 0x8460, 0xC891, 0x8462, 0xC892, 0x8464, 0xC893, 0x8465,
+	0xC894, 0x8466, 0xC895, 0x8467, 0xC896, 0x8468, 0xC897, 0x846A,
+	0xC898, 0x846E, 0xC899, 0x846F, 0xC89A, 0x8470, 0xC89B, 0x8472,
+	0xC89C, 0x8474, 0xC89D, 0x8477, 0xC89E, 0x8479, 0xC89F, 0x847B,
+	0xC8A0, 0x847C, 0xC8A1, 0x53D6, 0xC8A2, 0x5A36, 0xC8A3, 0x9F8B,
+	0xC8A4, 0x8DA3, 0xC8A5, 0x53BB, 0xC8A6, 0x5708, 0xC8A7, 0x98A7,
+	0xC8A8, 0x6743, 0xC8A9, 0x919B, 0xC8AA, 0x6CC9, 0xC8AB, 0x5168,
+	0xC8AC, 0x75CA, 0xC8AD, 0x62F3, 0xC8AE, 0x72AC, 0xC8AF, 0x5238,
+	0xC8B0, 0x529D, 0xC8B1, 0x7F3A, 0xC8B2, 0x7094, 0xC8B3, 0x7638,
+	0xC8B4, 0x5374, 0xC8B5, 0x9E4A, 0xC8B6, 0x69B7, 0xC8B7, 0x786E,
+	0xC8B8, 0x96C0, 0xC8B9, 0x88D9, 0xC8BA, 0x7FA4, 0xC8BB, 0x7136,
+	0xC8BC, 0x71C3, 0xC8BD, 0x5189, 0xC8BE, 0x67D3, 0xC8BF, 0x74E4,
+	0xC8C0, 0x58E4, 0xC8C1, 0x6518, 0xC8C2, 0x56B7, 0xC8C3, 0x8BA9,
+	0xC8C4, 0x9976, 0xC8C5, 0x6270, 0xC8C6, 0x7ED5, 0xC8C7, 0x60F9,
+	0xC8C8, 0x70ED, 0xC8C9, 0x58EC, 0xC8CA, 0x4EC1, 0xC8CB, 0x4EBA,
+	0xC8CC, 0x5FCD, 0xC8CD, 0x97E7, 0xC8CE, 0x4EFB, 0xC8CF, 0x8BA4,
+	0xC8D0, 0x5203, 0xC8D1, 0x598A, 0xC8D2, 0x7EAB, 0xC8D3, 0x6254,
+	0xC8D4, 0x4ECD, 0xC8D5, 0x65E5, 0xC8D6, 0x620E, 0xC8D7, 0x8338,
+	0xC8D8, 0x84C9, 0xC8D9, 0x8363, 0xC8DA, 0x878D, 0xC8DB, 0x7194,
+	0xC8DC, 0x6EB6, 0xC8DD, 0x5BB9, 0xC8DE, 0x7ED2, 0xC8DF, 0x5197,
+	0xC8E0, 0x63C9, 0xC8E1, 0x67D4, 0xC8E2, 0x8089, 0xC8E3, 0x8339,
+	0xC8E4, 0x8815, 0xC8E5, 0x5112, 0xC8E6, 0x5B7A, 0xC8E7, 0x5982,
+	0xC8E8, 0x8FB1, 0xC8E9, 0x4E73, 0xC8EA, 0x6C5D, 0xC8EB, 0x5165,
+	0xC8EC, 0x8925, 0xC8ED, 0x8F6F, 0xC8EE, 0x962E, 0xC8EF, 0x854A,
+	0xC8F0, 0x745E, 0xC8F1, 0x9510, 0xC8F2, 0x95F0, 0xC8F3, 0x6DA6,
+	0xC8F4, 0x82E5, 0xC8F5, 0x5F31, 0xC8F6, 0x6492, 0xC8F7, 0x6D12,
+	0xC8F8, 0x8428, 0xC8F9, 0x816E, 0xC8FA, 0x9CC3, 0xC8FB, 0x585E,
+	0xC8FC, 0x8D5B, 0xC8FD, 0x4E09, 0xC8FE, 0x53C1, 0xC940, 0x847D,
+	0xC941, 0x847E, 0xC942, 0x847F, 0xC943, 0x8480, 0xC944, 0x8481,
+	0xC945, 0x8483, 0xC946, 0x8484, 0xC947, 0x8485, 0xC948, 0x8486,
+	0xC949, 0x848A, 0xC94A, 0x848D, 0xC94B, 0x848F, 0xC94C, 0x8490,
+	0xC94D, 0x8491, 0xC94E, 0x8492, 0xC94F, 0x8493, 0xC950, 0x8494,
+	0xC951, 0x8495, 0xC952, 0x8496, 0xC953, 0x8498, 0xC954, 0x849A,
+	0xC955, 0x849B, 0xC956, 0x849D, 0xC957, 0x849E, 0xC958, 0x849F,
+	0xC959, 0x84A0, 0xC95A, 0x84A2, 0xC95B, 0x84A3, 0xC95C, 0x84A4,
+	0xC95D, 0x84A5, 0xC95E, 0x84A6, 0xC95F, 0x84A7, 0xC960, 0x84A8,
+	0xC961, 0x84A9, 0xC962, 0x84AA, 0xC963, 0x84AB, 0xC964, 0x84AC,
+	0xC965, 0x84AD, 0xC966, 0x84AE, 0xC967, 0x84B0, 0xC968, 0x84B1,
+	0xC969, 0x84B3, 0xC96A, 0x84B5, 0xC96B, 0x84B6, 0xC96C, 0x84B7,
+	0xC96D, 0x84BB, 0xC96E, 0x84BC, 0xC96F, 0x84BE, 0xC970, 0x84C0,
+	0xC971, 0x84C2, 0xC972, 0x84C3, 0xC973, 0x84C5, 0xC974, 0x84C6,
+	0xC975, 0x84C7, 0xC976, 0x84C8, 0xC977, 0x84CB, 0xC978, 0x84CC,
+	0xC979, 0x84CE, 0xC97A, 0x84CF, 0xC97B, 0x84D2, 0xC97C, 0x84D4,
+	0xC97D, 0x84D5, 0xC97E, 0x84D7, 0xC980, 0x84D8, 0xC981, 0x84D9,
+	0xC982, 0x84DA, 0xC983, 0x84DB, 0xC984, 0x84DC, 0xC985, 0x84DE,
+	0xC986, 0x84E1, 0xC987, 0x84E2, 0xC988, 0x84E4, 0xC989, 0x84E7,
+	0xC98A, 0x84E8, 0xC98B, 0x84E9, 0xC98C, 0x84EA, 0xC98D, 0x84EB,
+	0xC98E, 0x84ED, 0xC98F, 0x84EE, 0xC990, 0x84EF, 0xC991, 0x84F1,
+	0xC992, 0x84F2, 0xC993, 0x84F3, 0xC994, 0x84F4, 0xC995, 0x84F5,
+	0xC996, 0x84F6, 0xC997, 0x84F7, 0xC998, 0x84F8, 0xC999, 0x84F9,
+	0xC99A, 0x84FA, 0xC99B, 0x84FB, 0xC99C, 0x84FD, 0xC99D, 0x84FE,
+	0xC99E, 0x8500, 0xC99F, 0x8501, 0xC9A0, 0x8502, 0xC9A1, 0x4F1E,
+	0xC9A2, 0x6563, 0xC9A3, 0x6851, 0xC9A4, 0x55D3, 0xC9A5, 0x4E27,
+	0xC9A6, 0x6414, 0xC9A7, 0x9A9A, 0xC9A8, 0x626B, 0xC9A9, 0x5AC2,
+	0xC9AA, 0x745F, 0xC9AB, 0x8272, 0xC9AC, 0x6DA9, 0xC9AD, 0x68EE,
+	0xC9AE, 0x50E7, 0xC9AF, 0x838E, 0xC9B0, 0x7802, 0xC9B1, 0x6740,
+	0xC9B2, 0x5239, 0xC9B3, 0x6C99, 0xC9B4, 0x7EB1, 0xC9B5, 0x50BB,
+	0xC9B6, 0x5565, 0xC9B7, 0x715E, 0xC9B8, 0x7B5B, 0xC9B9, 0x6652,
+	0xC9BA, 0x73CA, 0xC9BB, 0x82EB, 0xC9BC, 0x6749, 0xC9BD, 0x5C71,
+	0xC9BE, 0x5220, 0xC9BF, 0x717D, 0xC9C0, 0x886B, 0xC9C1, 0x95EA,
+	0xC9C2, 0x9655, 0xC9C3, 0x64C5, 0xC9C4, 0x8D61, 0xC9C5, 0x81B3,
+	0xC9C6, 0x5584, 0xC9C7, 0x6C55, 0xC9C8, 0x6247, 0xC9C9, 0x7F2E,
+	0xC9CA, 0x5892, 0xC9CB, 0x4F24, 0xC9CC, 0x5546, 0xC9CD, 0x8D4F,
+	0xC9CE, 0x664C, 0xC9CF, 0x4E0A, 0xC9D0, 0x5C1A, 0xC9D1, 0x88F3,
+	0xC9D2, 0x68A2, 0xC9D3, 0x634E, 0xC9D4, 0x7A0D, 0xC9D5, 0x70E7,
+	0xC9D6, 0x828D, 0xC9D7, 0x52FA, 0xC9D8, 0x97F6, 0xC9D9, 0x5C11,
+	0xC9DA, 0x54E8, 0xC9DB, 0x90B5, 0xC9DC, 0x7ECD, 0xC9DD, 0x5962,
+	0xC9DE, 0x8D4A, 0xC9DF, 0x86C7, 0xC9E0, 0x820C, 0xC9E1, 0x820D,
+	0xC9E2, 0x8D66, 0xC9E3, 0x6444, 0xC9E4, 0x5C04, 0xC9E5, 0x6151,
+	0xC9E6, 0x6D89, 0xC9E7, 0x793E, 0xC9E8, 0x8BBE, 0xC9E9, 0x7837,
+	0xC9EA, 0x7533, 0xC9EB, 0x547B, 0xC9EC, 0x4F38, 0xC9ED, 0x8EAB,
+	0xC9EE, 0x6DF1, 0xC9EF, 0x5A20, 0xC9F0, 0x7EC5, 0xC9F1, 0x795E,
+	0xC9F2, 0x6C88, 0xC9F3, 0x5BA1, 0xC9F4, 0x5A76, 0xC9F5, 0x751A,
+	0xC9F6, 0x80BE, 0xC9F7, 0x614E, 0xC9F8, 0x6E17, 0xC9F9, 0x58F0,
+	0xC9FA, 0x751F, 0xC9FB, 0x7525, 0xC9FC, 0x7272, 0xC9FD, 0x5347,
+	0xC9FE, 0x7EF3, 0xCA40, 0x8503, 0xCA41, 0x8504, 0xCA42, 0x8505,
+	0xCA43, 0x8506, 0xCA44, 0x8507, 0xCA45, 0x8508, 0xCA46, 0x8509,
+	0xCA47, 0x850A, 0xCA48, 0x850B, 0xCA49, 0x850D, 0xCA4A, 0x850E,
+	0xCA4B, 0x850F, 0xCA4C, 0x8510, 0xCA4D, 0x8512, 0xCA4E, 0x8514,
+	0xCA4F, 0x8515, 0xCA50, 0x8516, 0xCA51, 0x8518, 0xCA52, 0x8519,
+	0xCA53, 0x851B, 0xCA54, 0x851C, 0xCA55, 0x851D, 0xCA56, 0x851E,
+	0xCA57, 0x8520, 0xCA58, 0x8522, 0xCA59, 0x8523, 0xCA5A, 0x8524,
+	0xCA5B, 0x8525, 0xCA5C, 0x8526, 0xCA5D, 0x8527, 0xCA5E, 0x8528,
+	0xCA5F, 0x8529, 0xCA60, 0x852A, 0xCA61, 0x852D, 0xCA62, 0x852E,
+	0xCA63, 0x852F, 0xCA64, 0x8530, 0xCA65, 0x8531, 0xCA66, 0x8532,
+	0xCA67, 0x8533, 0xCA68, 0x8534, 0xCA69, 0x8535, 0xCA6A, 0x8536,
+	0xCA6B, 0x853E, 0xCA6C, 0x853F, 0xCA6D, 0x8540, 0xCA6E, 0x8541,
+	0xCA6F, 0x8542, 0xCA70, 0x8544, 0xCA71, 0x8545, 0xCA72, 0x8546,
+	0xCA73, 0x8547, 0xCA74, 0x854B, 0xCA75, 0x854C, 0xCA76, 0x854D,
+	0xCA77, 0x854E, 0xCA78, 0x854F, 0xCA79, 0x8550, 0xCA7A, 0x8551,
+	0xCA7B, 0x8552, 0xCA7C, 0x8553, 0xCA7D, 0x8554, 0xCA7E, 0x8555,
+	0xCA80, 0x8557, 0xCA81, 0x8558, 0xCA82, 0x855A, 0xCA83, 0x855B,
+	0xCA84, 0x855C, 0xCA85, 0x855D, 0xCA86, 0x855F, 0xCA87, 0x8560,
+	0xCA88, 0x8561, 0xCA89, 0x8562, 0xCA8A, 0x8563, 0xCA8B, 0x8565,
+	0xCA8C, 0x8566, 0xCA8D, 0x8567, 0xCA8E, 0x8569, 0xCA8F, 0x856A,
+	0xCA90, 0x856B, 0xCA91, 0x856C, 0xCA92, 0x856D, 0xCA93, 0x856E,
+	0xCA94, 0x856F, 0xCA95, 0x8570, 0xCA96, 0x8571, 0xCA97, 0x8573,
+	0xCA98, 0x8575, 0xCA99, 0x8576, 0xCA9A, 0x8577, 0xCA9B, 0x8578,
+	0xCA9C, 0x857C, 0xCA9D, 0x857D, 0xCA9E, 0x857F, 0xCA9F, 0x8580,
+	0xCAA0, 0x8581, 0xCAA1, 0x7701, 0xCAA2, 0x76DB, 0xCAA3, 0x5269,
+	0xCAA4, 0x80DC, 0xCAA5, 0x5723, 0xCAA6, 0x5E08, 0xCAA7, 0x5931,
+	0xCAA8, 0x72EE, 0xCAA9, 0x65BD, 0xCAAA, 0x6E7F, 0xCAAB, 0x8BD7,
+	0xCAAC, 0x5C38, 0xCAAD, 0x8671, 0xCAAE, 0x5341, 0xCAAF, 0x77F3,
+	0xCAB0, 0x62FE, 0xCAB1, 0x65F6, 0xCAB2, 0x4EC0, 0xCAB3, 0x98DF,
+	0xCAB4, 0x8680, 0xCAB5, 0x5B9E, 0xCAB6, 0x8BC6, 0xCAB7, 0x53F2,
+	0xCAB8, 0x77E2, 0xCAB9, 0x4F7F, 0xCABA, 0x5C4E, 0xCABB, 0x9A76,
+	0xCABC, 0x59CB, 0xCABD, 0x5F0F, 0xCABE, 0x793A, 0xCABF, 0x58EB,
+	0xCAC0, 0x4E16, 0xCAC1, 0x67FF, 0xCAC2, 0x4E8B, 0xCAC3, 0x62ED,
+	0xCAC4, 0x8A93, 0xCAC5, 0x901D, 0xCAC6, 0x52BF, 0xCAC7, 0x662F,
+	0xCAC8, 0x55DC, 0xCAC9, 0x566C, 0xCACA, 0x9002, 0xCACB, 0x4ED5,
+	0xCACC, 0x4F8D, 0xCACD, 0x91CA, 0xCACE, 0x9970, 0xCACF, 0x6C0F,
+	0xCAD0, 0x5E02, 0xCAD1, 0x6043, 0xCAD2, 0x5BA4, 0xCAD3, 0x89C6,
+	0xCAD4, 0x8BD5, 0xCAD5, 0x6536, 0xCAD6, 0x624B, 0xCAD7, 0x9996,
+	0xCAD8, 0x5B88, 0xCAD9, 0x5BFF, 0xCADA, 0x6388, 0xCADB, 0x552E,
+	0xCADC, 0x53D7, 0xCADD, 0x7626, 0xCADE, 0x517D, 0xCADF, 0x852C,
+	0xCAE0, 0x67A2, 0xCAE1, 0x68B3, 0xCAE2, 0x6B8A, 0xCAE3, 0x6292,
+	0xCAE4, 0x8F93, 0xCAE5, 0x53D4, 0xCAE6, 0x8212, 0xCAE7, 0x6DD1,
+	0xCAE8, 0x758F, 0xCAE9, 0x4E66, 0xCAEA, 0x8D4E, 0xCAEB, 0x5B70,
+	0xCAEC, 0x719F, 0xCAED, 0x85AF, 0xCAEE, 0x6691, 0xCAEF, 0x66D9,
+	0xCAF0, 0x7F72, 0xCAF1, 0x8700, 0xCAF2, 0x9ECD, 0xCAF3, 0x9F20,
+	0xCAF4, 0x5C5E, 0xCAF5, 0x672F, 0xCAF6, 0x8FF0, 0xCAF7, 0x6811,
+	0xCAF8, 0x675F, 0xCAF9, 0x620D, 0xCAFA, 0x7AD6, 0xCAFB, 0x5885,
+	0xCAFC, 0x5EB6, 0xCAFD, 0x6570, 0xCAFE, 0x6F31, 0xCB40, 0x8582,
+	0xCB41, 0x8583, 0xCB42, 0x8586, 0xCB43, 0x8588, 0xCB44, 0x8589,
+	0xCB45, 0x858A, 0xCB46, 0x858B, 0xCB47, 0x858C, 0xCB48, 0x858D,
+	0xCB49, 0x858E, 0xCB4A, 0x8590, 0xCB4B, 0x8591, 0xCB4C, 0x8592,
+	0xCB4D, 0x8593, 0xCB4E, 0x8594, 0xCB4F, 0x8595, 0xCB50, 0x8596,
+	0xCB51, 0x8597, 0xCB52, 0x8598, 0xCB53, 0x8599, 0xCB54, 0x859A,
+	0xCB55, 0x859D, 0xCB56, 0x859E, 0xCB57, 0x859F, 0xCB58, 0x85A0,
+	0xCB59, 0x85A1, 0xCB5A, 0x85A2, 0xCB5B, 0x85A3, 0xCB5C, 0x85A5,
+	0xCB5D, 0x85A6, 0xCB5E, 0x85A7, 0xCB5F, 0x85A9, 0xCB60, 0x85AB,
+	0xCB61, 0x85AC, 0xCB62, 0x85AD, 0xCB63, 0x85B1, 0xCB64, 0x85B2,
+	0xCB65, 0x85B3, 0xCB66, 0x85B4, 0xCB67, 0x85B5, 0xCB68, 0x85B6,
+	0xCB69, 0x85B8, 0xCB6A, 0x85BA, 0xCB6B, 0x85BB, 0xCB6C, 0x85BC,
+	0xCB6D, 0x85BD, 0xCB6E, 0x85BE, 0xCB6F, 0x85BF, 0xCB70, 0x85C0,
+	0xCB71, 0x85C2, 0xCB72, 0x85C3, 0xCB73, 0x85C4, 0xCB74, 0x85C5,
+	0xCB75, 0x85C6, 0xCB76, 0x85C7, 0xCB77, 0x85C8, 0xCB78, 0x85CA,
+	0xCB79, 0x85CB, 0xCB7A, 0x85CC, 0xCB7B, 0x85CD, 0xCB7C, 0x85CE,
+	0xCB7D, 0x85D1, 0xCB7E, 0x85D2, 0xCB80, 0x85D4, 0xCB81, 0x85D6,
+	0xCB82, 0x85D7, 0xCB83, 0x85D8, 0xCB84, 0x85D9, 0xCB85, 0x85DA,
+	0xCB86, 0x85DB, 0xCB87, 0x85DD, 0xCB88, 0x85DE, 0xCB89, 0x85DF,
+	0xCB8A, 0x85E0, 0xCB8B, 0x85E1, 0xCB8C, 0x85E2, 0xCB8D, 0x85E3,
+	0xCB8E, 0x85E5, 0xCB8F, 0x85E6, 0xCB90, 0x85E7, 0xCB91, 0x85E8,
+	0xCB92, 0x85EA, 0xCB93, 0x85EB, 0xCB94, 0x85EC, 0xCB95, 0x85ED,
+	0xCB96, 0x85EE, 0xCB97, 0x85EF, 0xCB98, 0x85F0, 0xCB99, 0x85F1,
+	0xCB9A, 0x85F2, 0xCB9B, 0x85F3, 0xCB9C, 0x85F4, 0xCB9D, 0x85F5,
+	0xCB9E, 0x85F6, 0xCB9F, 0x85F7, 0xCBA0, 0x85F8, 0xCBA1, 0x6055,
+	0xCBA2, 0x5237, 0xCBA3, 0x800D, 0xCBA4, 0x6454, 0xCBA5, 0x8870,
+	0xCBA6, 0x7529, 0xCBA7, 0x5E05, 0xCBA8, 0x6813, 0xCBA9, 0x62F4,
+	0xCBAA, 0x971C, 0xCBAB, 0x53CC, 0xCBAC, 0x723D, 0xCBAD, 0x8C01,
+	0xCBAE, 0x6C34, 0xCBAF, 0x7761, 0xCBB0, 0x7A0E, 0xCBB1, 0x542E,
+	0xCBB2, 0x77AC, 0xCBB3, 0x987A, 0xCBB4, 0x821C, 0xCBB5, 0x8BF4,
+	0xCBB6, 0x7855, 0xCBB7, 0x6714, 0xCBB8, 0x70C1, 0xCBB9, 0x65AF,
+	0xCBBA, 0x6495, 0xCBBB, 0x5636, 0xCBBC, 0x601D, 0xCBBD, 0x79C1,
+	0xCBBE, 0x53F8, 0xCBBF, 0x4E1D, 0xCBC0, 0x6B7B, 0xCBC1, 0x8086,
+	0xCBC2, 0x5BFA, 0xCBC3, 0x55E3, 0xCBC4, 0x56DB, 0xCBC5, 0x4F3A,
+	0xCBC6, 0x4F3C, 0xCBC7, 0x9972, 0xCBC8, 0x5DF3, 0xCBC9, 0x677E,
+	0xCBCA, 0x8038, 0xCBCB, 0x6002, 0xCBCC, 0x9882, 0xCBCD, 0x9001,
+	0xCBCE, 0x5B8B, 0xCBCF, 0x8BBC, 0xCBD0, 0x8BF5, 0xCBD1, 0x641C,
+	0xCBD2, 0x8258, 0xCBD3, 0x64DE, 0xCBD4, 0x55FD, 0xCBD5, 0x82CF,
+	0xCBD6, 0x9165, 0xCBD7, 0x4FD7, 0xCBD8, 0x7D20, 0xCBD9, 0x901F,
+	0xCBDA, 0x7C9F, 0xCBDB, 0x50F3, 0xCBDC, 0x5851, 0xCBDD, 0x6EAF,
+	0xCBDE, 0x5BBF, 0xCBDF, 0x8BC9, 0xCBE0, 0x8083, 0xCBE1, 0x9178,
+	0xCBE2, 0x849C, 0xCBE3, 0x7B97, 0xCBE4, 0x867D, 0xCBE5, 0x968B,
+	0xCBE6, 0x968F, 0xCBE7, 0x7EE5, 0xCBE8, 0x9AD3, 0xCBE9, 0x788E,
+	0xCBEA, 0x5C81, 0xCBEB, 0x7A57, 0xCBEC, 0x9042, 0xCBED, 0x96A7,
+	0xCBEE, 0x795F, 0xCBEF, 0x5B59, 0xCBF0, 0x635F, 0xCBF1, 0x7B0B,
+	0xCBF2, 0x84D1, 0xCBF3, 0x68AD, 0xCBF4, 0x5506, 0xCBF5, 0x7F29,
+	0xCBF6, 0x7410, 0xCBF7, 0x7D22, 0xCBF8, 0x9501, 0xCBF9, 0x6240,
+	0xCBFA, 0x584C, 0xCBFB, 0x4ED6, 0xCBFC, 0x5B83, 0xCBFD, 0x5979,
+	0xCBFE, 0x5854, 0xCC40, 0x85F9, 0xCC41, 0x85FA, 0xCC42, 0x85FC,
+	0xCC43, 0x85FD, 0xCC44, 0x85FE, 0xCC45, 0x8600, 0xCC46, 0x8601,
+	0xCC47, 0x8602, 0xCC48, 0x8603, 0xCC49, 0x8604, 0xCC4A, 0x8606,
+	0xCC4B, 0x8607, 0xCC4C, 0x8608, 0xCC4D, 0x8609, 0xCC4E, 0x860A,
+	0xCC4F, 0x860B, 0xCC50, 0x860C, 0xCC51, 0x860D, 0xCC52, 0x860E,
+	0xCC53, 0x860F, 0xCC54, 0x8610, 0xCC55, 0x8612, 0xCC56, 0x8613,
+	0xCC57, 0x8614, 0xCC58, 0x8615, 0xCC59, 0x8617, 0xCC5A, 0x8618,
+	0xCC5B, 0x8619, 0xCC5C, 0x861A, 0xCC5D, 0x861B, 0xCC5E, 0x861C,
+	0xCC5F, 0x861D, 0xCC60, 0x861E, 0xCC61, 0x861F, 0xCC62, 0x8620,
+	0xCC63, 0x8621, 0xCC64, 0x8622, 0xCC65, 0x8623, 0xCC66, 0x8624,
+	0xCC67, 0x8625, 0xCC68, 0x8626, 0xCC69, 0x8628, 0xCC6A, 0x862A,
+	0xCC6B, 0x862B, 0xCC6C, 0x862C, 0xCC6D, 0x862D, 0xCC6E, 0x862E,
+	0xCC6F, 0x862F, 0xCC70, 0x8630, 0xCC71, 0x8631, 0xCC72, 0x8632,
+	0xCC73, 0x8633, 0xCC74, 0x8634, 0xCC75, 0x8635, 0xCC76, 0x8636,
+	0xCC77, 0x8637, 0xCC78, 0x8639, 0xCC79, 0x863A, 0xCC7A, 0x863B,
+	0xCC7B, 0x863D, 0xCC7C, 0x863E, 0xCC7D, 0x863F, 0xCC7E, 0x8640,
+	0xCC80, 0x8641, 0xCC81, 0x8642, 0xCC82, 0x8643, 0xCC83, 0x8644,
+	0xCC84, 0x8645, 0xCC85, 0x8646, 0xCC86, 0x8647, 0xCC87, 0x8648,
+	0xCC88, 0x8649, 0xCC89, 0x864A, 0xCC8A, 0x864B, 0xCC8B, 0x864C,
+	0xCC8C, 0x8652, 0xCC8D, 0x8653, 0xCC8E, 0x8655, 0xCC8F, 0x8656,
+	0xCC90, 0x8657, 0xCC91, 0x8658, 0xCC92, 0x8659, 0xCC93, 0x865B,
+	0xCC94, 0x865C, 0xCC95, 0x865D, 0xCC96, 0x865F, 0xCC97, 0x8660,
+	0xCC98, 0x8661, 0xCC99, 0x8663, 0xCC9A, 0x8664, 0xCC9B, 0x8665,
+	0xCC9C, 0x8666, 0xCC9D, 0x8667, 0xCC9E, 0x8668, 0xCC9F, 0x8669,
+	0xCCA0, 0x866A, 0xCCA1, 0x736D, 0xCCA2, 0x631E, 0xCCA3, 0x8E4B,
+	0xCCA4, 0x8E0F, 0xCCA5, 0x80CE, 0xCCA6, 0x82D4, 0xCCA7, 0x62AC,
+	0xCCA8, 0x53F0, 0xCCA9, 0x6CF0, 0xCCAA, 0x915E, 0xCCAB, 0x592A,
+	0xCCAC, 0x6001, 0xCCAD, 0x6C70, 0xCCAE, 0x574D, 0xCCAF, 0x644A,
+	0xCCB0, 0x8D2A, 0xCCB1, 0x762B, 0xCCB2, 0x6EE9, 0xCCB3, 0x575B,
+	0xCCB4, 0x6A80, 0xCCB5, 0x75F0, 0xCCB6, 0x6F6D, 0xCCB7, 0x8C2D,
+	0xCCB8, 0x8C08, 0xCCB9, 0x5766, 0xCCBA, 0x6BEF, 0xCCBB, 0x8892,
+	0xCCBC, 0x78B3, 0xCCBD, 0x63A2, 0xCCBE, 0x53F9, 0xCCBF, 0x70AD,
+	0xCCC0, 0x6C64, 0xCCC1, 0x5858, 0xCCC2, 0x642A, 0xCCC3, 0x5802,
+	0xCCC4, 0x68E0, 0xCCC5, 0x819B, 0xCCC6, 0x5510, 0xCCC7, 0x7CD6,
+	0xCCC8, 0x5018, 0xCCC9, 0x8EBA, 0xCCCA, 0x6DCC, 0xCCCB, 0x8D9F,
+	0xCCCC, 0x70EB, 0xCCCD, 0x638F, 0xCCCE, 0x6D9B, 0xCCCF, 0x6ED4,
+	0xCCD0, 0x7EE6, 0xCCD1, 0x8404, 0xCCD2, 0x6843, 0xCCD3, 0x9003,
+	0xCCD4, 0x6DD8, 0xCCD5, 0x9676, 0xCCD6, 0x8BA8, 0xCCD7, 0x5957,
+	0xCCD8, 0x7279, 0xCCD9, 0x85E4, 0xCCDA, 0x817E, 0xCCDB, 0x75BC,
+	0xCCDC, 0x8A8A, 0xCCDD, 0x68AF, 0xCCDE, 0x5254, 0xCCDF, 0x8E22,
+	0xCCE0, 0x9511, 0xCCE1, 0x63D0, 0xCCE2, 0x9898, 0xCCE3, 0x8E44,
+	0xCCE4, 0x557C, 0xCCE5, 0x4F53, 0xCCE6, 0x66FF, 0xCCE7, 0x568F,
+	0xCCE8, 0x60D5, 0xCCE9, 0x6D95, 0xCCEA, 0x5243, 0xCCEB, 0x5C49,
+	0xCCEC, 0x5929, 0xCCED, 0x6DFB, 0xCCEE, 0x586B, 0xCCEF, 0x7530,
+	0xCCF0, 0x751C, 0xCCF1, 0x606C, 0xCCF2, 0x8214, 0xCCF3, 0x8146,
+	0xCCF4, 0x6311, 0xCCF5, 0x6761, 0xCCF6, 0x8FE2, 0xCCF7, 0x773A,
+	0xCCF8, 0x8DF3, 0xCCF9, 0x8D34, 0xCCFA, 0x94C1, 0xCCFB, 0x5E16,
+	0xCCFC, 0x5385, 0xCCFD, 0x542C, 0xCCFE, 0x70C3, 0xCD40, 0x866D,
+	0xCD41, 0x866F, 0xCD42, 0x8670, 0xCD43, 0x8672, 0xCD44, 0x8673,
+	0xCD45, 0x8674, 0xCD46, 0x8675, 0xCD47, 0x8676, 0xCD48, 0x8677,
+	0xCD49, 0x8678, 0xCD4A, 0x8683, 0xCD4B, 0x8684, 0xCD4C, 0x8685,
+	0xCD4D, 0x8686, 0xCD4E, 0x8687, 0xCD4F, 0x8688, 0xCD50, 0x8689,
+	0xCD51, 0x868E, 0xCD52, 0x868F, 0xCD53, 0x8690, 0xCD54, 0x8691,
+	0xCD55, 0x8692, 0xCD56, 0x8694, 0xCD57, 0x8696, 0xCD58, 0x8697,
+	0xCD59, 0x8698, 0xCD5A, 0x8699, 0xCD5B, 0x869A, 0xCD5C, 0x869B,
+	0xCD5D, 0x869E, 0xCD5E, 0x869F, 0xCD5F, 0x86A0, 0xCD60, 0x86A1,
+	0xCD61, 0x86A2, 0xCD62, 0x86A5, 0xCD63, 0x86A6, 0xCD64, 0x86AB,
+	0xCD65, 0x86AD, 0xCD66, 0x86AE, 0xCD67, 0x86B2, 0xCD68, 0x86B3,
+	0xCD69, 0x86B7, 0xCD6A, 0x86B8, 0xCD6B, 0x86B9, 0xCD6C, 0x86BB,
+	0xCD6D, 0x86BC, 0xCD6E, 0x86BD, 0xCD6F, 0x86BE, 0xCD70, 0x86BF,
+	0xCD71, 0x86C1, 0xCD72, 0x86C2, 0xCD73, 0x86C3, 0xCD74, 0x86C5,
+	0xCD75, 0x86C8, 0xCD76, 0x86CC, 0xCD77, 0x86CD, 0xCD78, 0x86D2,
+	0xCD79, 0x86D3, 0xCD7A, 0x86D5, 0xCD7B, 0x86D6, 0xCD7C, 0x86D7,
+	0xCD7D, 0x86DA, 0xCD7E, 0x86DC, 0xCD80, 0x86DD, 0xCD81, 0x86E0,
+	0xCD82, 0x86E1, 0xCD83, 0x86E2, 0xCD84, 0x86E3, 0xCD85, 0x86E5,
+	0xCD86, 0x86E6, 0xCD87, 0x86E7, 0xCD88, 0x86E8, 0xCD89, 0x86EA,
+	0xCD8A, 0x86EB, 0xCD8B, 0x86EC, 0xCD8C, 0x86EF, 0xCD8D, 0x86F5,
+	0xCD8E, 0x86F6, 0xCD8F, 0x86F7, 0xCD90, 0x86FA, 0xCD91, 0x86FB,
+	0xCD92, 0x86FC, 0xCD93, 0x86FD, 0xCD94, 0x86FF, 0xCD95, 0x8701,
+	0xCD96, 0x8704, 0xCD97, 0x8705, 0xCD98, 0x8706, 0xCD99, 0x870B,
+	0xCD9A, 0x870C, 0xCD9B, 0x870E, 0xCD9C, 0x870F, 0xCD9D, 0x8710,
+	0xCD9E, 0x8711, 0xCD9F, 0x8714, 0xCDA0, 0x8716, 0xCDA1, 0x6C40,
+	0xCDA2, 0x5EF7, 0xCDA3, 0x505C, 0xCDA4, 0x4EAD, 0xCDA5, 0x5EAD,
+	0xCDA6, 0x633A, 0xCDA7, 0x8247, 0xCDA8, 0x901A, 0xCDA9, 0x6850,
+	0xCDAA, 0x916E, 0xCDAB, 0x77B3, 0xCDAC, 0x540C, 0xCDAD, 0x94DC,
+	0xCDAE, 0x5F64, 0xCDAF, 0x7AE5, 0xCDB0, 0x6876, 0xCDB1, 0x6345,
+	0xCDB2, 0x7B52, 0xCDB3, 0x7EDF, 0xCDB4, 0x75DB, 0xCDB5, 0x5077,
+	0xCDB6, 0x6295, 0xCDB7, 0x5934, 0xCDB8, 0x900F, 0xCDB9, 0x51F8,
+	0xCDBA, 0x79C3, 0xCDBB, 0x7A81, 0xCDBC, 0x56FE, 0xCDBD, 0x5F92,
+	0xCDBE, 0x9014, 0xCDBF, 0x6D82, 0xCDC0, 0x5C60, 0xCDC1, 0x571F,
+	0xCDC2, 0x5410, 0xCDC3, 0x5154, 0xCDC4, 0x6E4D, 0xCDC5, 0x56E2,
+	0xCDC6, 0x63A8, 0xCDC7, 0x9893, 0xCDC8, 0x817F, 0xCDC9, 0x8715,
+	0xCDCA, 0x892A, 0xCDCB, 0x9000, 0xCDCC, 0x541E, 0xCDCD, 0x5C6F,
+	0xCDCE, 0x81C0, 0xCDCF, 0x62D6, 0xCDD0, 0x6258, 0xCDD1, 0x8131,
+	0xCDD2, 0x9E35, 0xCDD3, 0x9640, 0xCDD4, 0x9A6E, 0xCDD5, 0x9A7C,
+	0xCDD6, 0x692D, 0xCDD7, 0x59A5, 0xCDD8, 0x62D3, 0xCDD9, 0x553E,
+	0xCDDA, 0x6316, 0xCDDB, 0x54C7, 0xCDDC, 0x86D9, 0xCDDD, 0x6D3C,
+	0xCDDE, 0x5A03, 0xCDDF, 0x74E6, 0xCDE0, 0x889C, 0xCDE1, 0x6B6A,
+	0xCDE2, 0x5916, 0xCDE3, 0x8C4C, 0xCDE4, 0x5F2F, 0xCDE5, 0x6E7E,
+	0xCDE6, 0x73A9, 0xCDE7, 0x987D, 0xCDE8, 0x4E38, 0xCDE9, 0x70F7,
+	0xCDEA, 0x5B8C, 0xCDEB, 0x7897, 0xCDEC, 0x633D, 0xCDED, 0x665A,
+	0xCDEE, 0x7696, 0xCDEF, 0x60CB, 0xCDF0, 0x5B9B, 0xCDF1, 0x5A49,
+	0xCDF2, 0x4E07, 0xCDF3, 0x8155, 0xCDF4, 0x6C6A, 0xCDF5, 0x738B,
+	0xCDF6, 0x4EA1, 0xCDF7, 0x6789, 0xCDF8, 0x7F51, 0xCDF9, 0x5F80,
+	0xCDFA, 0x65FA, 0xCDFB, 0x671B, 0xCDFC, 0x5FD8, 0xCDFD, 0x5984,
+	0xCDFE, 0x5A01, 0xCE40, 0x8719, 0xCE41, 0x871B, 0xCE42, 0x871D,
+	0xCE43, 0x871F, 0xCE44, 0x8720, 0xCE45, 0x8724, 0xCE46, 0x8726,
+	0xCE47, 0x8727, 0xCE48, 0x8728, 0xCE49, 0x872A, 0xCE4A, 0x872B,
+	0xCE4B, 0x872C, 0xCE4C, 0x872D, 0xCE4D, 0x872F, 0xCE4E, 0x8730,
+	0xCE4F, 0x8732, 0xCE50, 0x8733, 0xCE51, 0x8735, 0xCE52, 0x8736,
+	0xCE53, 0x8738, 0xCE54, 0x8739, 0xCE55, 0x873A, 0xCE56, 0x873C,
+	0xCE57, 0x873D, 0xCE58, 0x8740, 0xCE59, 0x8741, 0xCE5A, 0x8742,
+	0xCE5B, 0x8743, 0xCE5C, 0x8744, 0xCE5D, 0x8745, 0xCE5E, 0x8746,
+	0xCE5F, 0x874A, 0xCE60, 0x874B, 0xCE61, 0x874D, 0xCE62, 0x874F,
+	0xCE63, 0x8750, 0xCE64, 0x8751, 0xCE65, 0x8752, 0xCE66, 0x8754,
+	0xCE67, 0x8755, 0xCE68, 0x8756, 0xCE69, 0x8758, 0xCE6A, 0x875A,
+	0xCE6B, 0x875B, 0xCE6C, 0x875C, 0xCE6D, 0x875D, 0xCE6E, 0x875E,
+	0xCE6F, 0x875F, 0xCE70, 0x8761, 0xCE71, 0x8762, 0xCE72, 0x8766,
+	0xCE73, 0x8767, 0xCE74, 0x8768, 0xCE75, 0x8769, 0xCE76, 0x876A,
+	0xCE77, 0x876B, 0xCE78, 0x876C, 0xCE79, 0x876D, 0xCE7A, 0x876F,
+	0xCE7B, 0x8771, 0xCE7C, 0x8772, 0xCE7D, 0x8773, 0xCE7E, 0x8775,
+	0xCE80, 0x8777, 0xCE81, 0x8778, 0xCE82, 0x8779, 0xCE83, 0x877A,
+	0xCE84, 0x877F, 0xCE85, 0x8780, 0xCE86, 0x8781, 0xCE87, 0x8784,
+	0xCE88, 0x8786, 0xCE89, 0x8787, 0xCE8A, 0x8789, 0xCE8B, 0x878A,
+	0xCE8C, 0x878C, 0xCE8D, 0x878E, 0xCE8E, 0x878F, 0xCE8F, 0x8790,
+	0xCE90, 0x8791, 0xCE91, 0x8792, 0xCE92, 0x8794, 0xCE93, 0x8795,
+	0xCE94, 0x8796, 0xCE95, 0x8798, 0xCE96, 0x8799, 0xCE97, 0x879A,
+	0xCE98, 0x879B, 0xCE99, 0x879C, 0xCE9A, 0x879D, 0xCE9B, 0x879E,
+	0xCE9C, 0x87A0, 0xCE9D, 0x87A1, 0xCE9E, 0x87A2, 0xCE9F, 0x87A3,
+	0xCEA0, 0x87A4, 0xCEA1, 0x5DCD, 0xCEA2, 0x5FAE, 0xCEA3, 0x5371,
+	0xCEA4, 0x97E6, 0xCEA5, 0x8FDD, 0xCEA6, 0x6845, 0xCEA7, 0x56F4,
+	0xCEA8, 0x552F, 0xCEA9, 0x60DF, 0xCEAA, 0x4E3A, 0xCEAB, 0x6F4D,
+	0xCEAC, 0x7EF4, 0xCEAD, 0x82C7, 0xCEAE, 0x840E, 0xCEAF, 0x59D4,
+	0xCEB0, 0x4F1F, 0xCEB1, 0x4F2A, 0xCEB2, 0x5C3E, 0xCEB3, 0x7EAC,
+	0xCEB4, 0x672A, 0xCEB5, 0x851A, 0xCEB6, 0x5473, 0xCEB7, 0x754F,
+	0xCEB8, 0x80C3, 0xCEB9, 0x5582, 0xCEBA, 0x9B4F, 0xCEBB, 0x4F4D,
+	0xCEBC, 0x6E2D, 0xCEBD, 0x8C13, 0xCEBE, 0x5C09, 0xCEBF, 0x6170,
+	0xCEC0, 0x536B, 0xCEC1, 0x761F, 0xCEC2, 0x6E29, 0xCEC3, 0x868A,
+	0xCEC4, 0x6587, 0xCEC5, 0x95FB, 0xCEC6, 0x7EB9, 0xCEC7, 0x543B,
+	0xCEC8, 0x7A33, 0xCEC9, 0x7D0A, 0xCECA, 0x95EE, 0xCECB, 0x55E1,
+	0xCECC, 0x7FC1, 0xCECD, 0x74EE, 0xCECE, 0x631D, 0xCECF, 0x8717,
+	0xCED0, 0x6DA1, 0xCED1, 0x7A9D, 0xCED2, 0x6211, 0xCED3, 0x65A1,
+	0xCED4, 0x5367, 0xCED5, 0x63E1, 0xCED6, 0x6C83, 0xCED7, 0x5DEB,
+	0xCED8, 0x545C, 0xCED9, 0x94A8, 0xCEDA, 0x4E4C, 0xCEDB, 0x6C61,
+	0xCEDC, 0x8BEC, 0xCEDD, 0x5C4B, 0xCEDE, 0x65E0, 0xCEDF, 0x829C,
+	0xCEE0, 0x68A7, 0xCEE1, 0x543E, 0xCEE2, 0x5434, 0xCEE3, 0x6BCB,
+	0xCEE4, 0x6B66, 0xCEE5, 0x4E94, 0xCEE6, 0x6342, 0xCEE7, 0x5348,
+	0xCEE8, 0x821E, 0xCEE9, 0x4F0D, 0xCEEA, 0x4FAE, 0xCEEB, 0x575E,
+	0xCEEC, 0x620A, 0xCEED, 0x96FE, 0xCEEE, 0x6664, 0xCEEF, 0x7269,
+	0xCEF0, 0x52FF, 0xCEF1, 0x52A1, 0xCEF2, 0x609F, 0xCEF3, 0x8BEF,
+	0xCEF4, 0x6614, 0xCEF5, 0x7199, 0xCEF6, 0x6790, 0xCEF7, 0x897F,
+	0xCEF8, 0x7852, 0xCEF9, 0x77FD, 0xCEFA, 0x6670, 0xCEFB, 0x563B,
+	0xCEFC, 0x5438, 0xCEFD, 0x9521, 0xCEFE, 0x727A, 0xCF40, 0x87A5,
+	0xCF41, 0x87A6, 0xCF42, 0x87A7, 0xCF43, 0x87A9, 0xCF44, 0x87AA,
+	0xCF45, 0x87AE, 0xCF46, 0x87B0, 0xCF47, 0x87B1, 0xCF48, 0x87B2,
+	0xCF49, 0x87B4, 0xCF4A, 0x87B6, 0xCF4B, 0x87B7, 0xCF4C, 0x87B8,
+	0xCF4D, 0x87B9, 0xCF4E, 0x87BB, 0xCF4F, 0x87BC, 0xCF50, 0x87BE,
+	0xCF51, 0x87BF, 0xCF52, 0x87C1, 0xCF53, 0x87C2, 0xCF54, 0x87C3,
+	0xCF55, 0x87C4, 0xCF56, 0x87C5, 0xCF57, 0x87C7, 0xCF58, 0x87C8,
+	0xCF59, 0x87C9, 0xCF5A, 0x87CC, 0xCF5B, 0x87CD, 0xCF5C, 0x87CE,
+	0xCF5D, 0x87CF, 0xCF5E, 0x87D0, 0xCF5F, 0x87D4, 0xCF60, 0x87D5,
+	0xCF61, 0x87D6, 0xCF62, 0x87D7, 0xCF63, 0x87D8, 0xCF64, 0x87D9,
+	0xCF65, 0x87DA, 0xCF66, 0x87DC, 0xCF67, 0x87DD, 0xCF68, 0x87DE,
+	0xCF69, 0x87DF, 0xCF6A, 0x87E1, 0xCF6B, 0x87E2, 0xCF6C, 0x87E3,
+	0xCF6D, 0x87E4, 0xCF6E, 0x87E6, 0xCF6F, 0x87E7, 0xCF70, 0x87E8,
+	0xCF71, 0x87E9, 0xCF72, 0x87EB, 0xCF73, 0x87EC, 0xCF74, 0x87ED,
+	0xCF75, 0x87EF, 0xCF76, 0x87F0, 0xCF77, 0x87F1, 0xCF78, 0x87F2,
+	0xCF79, 0x87F3, 0xCF7A, 0x87F4, 0xCF7B, 0x87F5, 0xCF7C, 0x87F6,
+	0xCF7D, 0x87F7, 0xCF7E, 0x87F8, 0xCF80, 0x87FA, 0xCF81, 0x87FB,
+	0xCF82, 0x87FC, 0xCF83, 0x87FD, 0xCF84, 0x87FF, 0xCF85, 0x8800,
+	0xCF86, 0x8801, 0xCF87, 0x8802, 0xCF88, 0x8804, 0xCF89, 0x8805,
+	0xCF8A, 0x8806, 0xCF8B, 0x8807, 0xCF8C, 0x8808, 0xCF8D, 0x8809,
+	0xCF8E, 0x880B, 0xCF8F, 0x880C, 0xCF90, 0x880D, 0xCF91, 0x880E,
+	0xCF92, 0x880F, 0xCF93, 0x8810, 0xCF94, 0x8811, 0xCF95, 0x8812,
+	0xCF96, 0x8814, 0xCF97, 0x8817, 0xCF98, 0x8818, 0xCF99, 0x8819,
+	0xCF9A, 0x881A, 0xCF9B, 0x881C, 0xCF9C, 0x881D, 0xCF9D, 0x881E,
+	0xCF9E, 0x881F, 0xCF9F, 0x8820, 0xCFA0, 0x8823, 0xCFA1, 0x7A00,
+	0xCFA2, 0x606F, 0xCFA3, 0x5E0C, 0xCFA4, 0x6089, 0xCFA5, 0x819D,
+	0xCFA6, 0x5915, 0xCFA7, 0x60DC, 0xCFA8, 0x7184, 0xCFA9, 0x70EF,
+	0xCFAA, 0x6EAA, 0xCFAB, 0x6C50, 0xCFAC, 0x7280, 0xCFAD, 0x6A84,
+	0xCFAE, 0x88AD, 0xCFAF, 0x5E2D, 0xCFB0, 0x4E60, 0xCFB1, 0x5AB3,
+	0xCFB2, 0x559C, 0xCFB3, 0x94E3, 0xCFB4, 0x6D17, 0xCFB5, 0x7CFB,
+	0xCFB6, 0x9699, 0xCFB7, 0x620F, 0xCFB8, 0x7EC6, 0xCFB9, 0x778E,
+	0xCFBA, 0x867E, 0xCFBB, 0x5323, 0xCFBC, 0x971E, 0xCFBD, 0x8F96,
+	0xCFBE, 0x6687, 0xCFBF, 0x5CE1, 0xCFC0, 0x4FA0, 0xCFC1, 0x72ED,
+	0xCFC2, 0x4E0B, 0xCFC3, 0x53A6, 0xCFC4, 0x590F, 0xCFC5, 0x5413,
+	0xCFC6, 0x6380, 0xCFC7, 0x9528, 0xCFC8, 0x5148, 0xCFC9, 0x4ED9,
+	0xCFCA, 0x9C9C, 0xCFCB, 0x7EA4, 0xCFCC, 0x54B8, 0xCFCD, 0x8D24,
+	0xCFCE, 0x8854, 0xCFCF, 0x8237, 0xCFD0, 0x95F2, 0xCFD1, 0x6D8E,
+	0xCFD2, 0x5F26, 0xCFD3, 0x5ACC, 0xCFD4, 0x663E, 0xCFD5, 0x9669,
+	0xCFD6, 0x73B0, 0xCFD7, 0x732E, 0xCFD8, 0x53BF, 0xCFD9, 0x817A,
+	0xCFDA, 0x9985, 0xCFDB, 0x7FA1, 0xCFDC, 0x5BAA, 0xCFDD, 0x9677,
+	0xCFDE, 0x9650, 0xCFDF, 0x7EBF, 0xCFE0, 0x76F8, 0xCFE1, 0x53A2,
+	0xCFE2, 0x9576, 0xCFE3, 0x9999, 0xCFE4, 0x7BB1, 0xCFE5, 0x8944,
+	0xCFE6, 0x6E58, 0xCFE7, 0x4E61, 0xCFE8, 0x7FD4, 0xCFE9, 0x7965,
+	0xCFEA, 0x8BE6, 0xCFEB, 0x60F3, 0xCFEC, 0x54CD, 0xCFED, 0x4EAB,
+	0xCFEE, 0x9879, 0xCFEF, 0x5DF7, 0xCFF0, 0x6A61, 0xCFF1, 0x50CF,
+	0xCFF2, 0x5411, 0xCFF3, 0x8C61, 0xCFF4, 0x8427, 0xCFF5, 0x785D,
+	0xCFF6, 0x9704, 0xCFF7, 0x524A, 0xCFF8, 0x54EE, 0xCFF9, 0x56A3,
+	0xCFFA, 0x9500, 0xCFFB, 0x6D88, 0xCFFC, 0x5BB5, 0xCFFD, 0x6DC6,
+	0xCFFE, 0x6653, 0xD040, 0x8824, 0xD041, 0x8825, 0xD042, 0x8826,
+	0xD043, 0x8827, 0xD044, 0x8828, 0xD045, 0x8829, 0xD046, 0x882A,
+	0xD047, 0x882B, 0xD048, 0x882C, 0xD049, 0x882D, 0xD04A, 0x882E,
+	0xD04B, 0x882F, 0xD04C, 0x8830, 0xD04D, 0x8831, 0xD04E, 0x8833,
+	0xD04F, 0x8834, 0xD050, 0x8835, 0xD051, 0x8836, 0xD052, 0x8837,
+	0xD053, 0x8838, 0xD054, 0x883A, 0xD055, 0x883B, 0xD056, 0x883D,
+	0xD057, 0x883E, 0xD058, 0x883F, 0xD059, 0x8841, 0xD05A, 0x8842,
+	0xD05B, 0x8843, 0xD05C, 0x8846, 0xD05D, 0x8847, 0xD05E, 0x8848,
+	0xD05F, 0x8849, 0xD060, 0x884A, 0xD061, 0x884B, 0xD062, 0x884E,
+	0xD063, 0x884F, 0xD064, 0x8850, 0xD065, 0x8851, 0xD066, 0x8852,
+	0xD067, 0x8853, 0xD068, 0x8855, 0xD069, 0x8856, 0xD06A, 0x8858,
+	0xD06B, 0x885A, 0xD06C, 0x885B, 0xD06D, 0x885C, 0xD06E, 0x885D,
+	0xD06F, 0x885E, 0xD070, 0x885F, 0xD071, 0x8860, 0xD072, 0x8866,
+	0xD073, 0x8867, 0xD074, 0x886A, 0xD075, 0x886D, 0xD076, 0x886F,
+	0xD077, 0x8871, 0xD078, 0x8873, 0xD079, 0x8874, 0xD07A, 0x8875,
+	0xD07B, 0x8876, 0xD07C, 0x8878, 0xD07D, 0x8879, 0xD07E, 0x887A,
+	0xD080, 0x887B, 0xD081, 0x887C, 0xD082, 0x8880, 0xD083, 0x8883,
+	0xD084, 0x8886, 0xD085, 0x8887, 0xD086, 0x8889, 0xD087, 0x888A,
+	0xD088, 0x888C, 0xD089, 0x888E, 0xD08A, 0x888F, 0xD08B, 0x8890,
+	0xD08C, 0x8891, 0xD08D, 0x8893, 0xD08E, 0x8894, 0xD08F, 0x8895,
+	0xD090, 0x8897, 0xD091, 0x8898, 0xD092, 0x8899, 0xD093, 0x889A,
+	0xD094, 0x889B, 0xD095, 0x889D, 0xD096, 0x889E, 0xD097, 0x889F,
+	0xD098, 0x88A0, 0xD099, 0x88A1, 0xD09A, 0x88A3, 0xD09B, 0x88A5,
+	0xD09C, 0x88A6, 0xD09D, 0x88A7, 0xD09E, 0x88A8, 0xD09F, 0x88A9,
+	0xD0A0, 0x88AA, 0xD0A1, 0x5C0F, 0xD0A2, 0x5B5D, 0xD0A3, 0x6821,
+	0xD0A4, 0x8096, 0xD0A5, 0x5578, 0xD0A6, 0x7B11, 0xD0A7, 0x6548,
+	0xD0A8, 0x6954, 0xD0A9, 0x4E9B, 0xD0AA, 0x6B47, 0xD0AB, 0x874E,
+	0xD0AC, 0x978B, 0xD0AD, 0x534F, 0xD0AE, 0x631F, 0xD0AF, 0x643A,
+	0xD0B0, 0x90AA, 0xD0B1, 0x659C, 0xD0B2, 0x80C1, 0xD0B3, 0x8C10,
+	0xD0B4, 0x5199, 0xD0B5, 0x68B0, 0xD0B6, 0x5378, 0xD0B7, 0x87F9,
+	0xD0B8, 0x61C8, 0xD0B9, 0x6CC4, 0xD0BA, 0x6CFB, 0xD0BB, 0x8C22,
+	0xD0BC, 0x5C51, 0xD0BD, 0x85AA, 0xD0BE, 0x82AF, 0xD0BF, 0x950C,
+	0xD0C0, 0x6B23, 0xD0C1, 0x8F9B, 0xD0C2, 0x65B0, 0xD0C3, 0x5FFB,
+	0xD0C4, 0x5FC3, 0xD0C5, 0x4FE1, 0xD0C6, 0x8845, 0xD0C7, 0x661F,
+	0xD0C8, 0x8165, 0xD0C9, 0x7329, 0xD0CA, 0x60FA, 0xD0CB, 0x5174,
+	0xD0CC, 0x5211, 0xD0CD, 0x578B, 0xD0CE, 0x5F62, 0xD0CF, 0x90A2,
+	0xD0D0, 0x884C, 0xD0D1, 0x9192, 0xD0D2, 0x5E78, 0xD0D3, 0x674F,
+	0xD0D4, 0x6027, 0xD0D5, 0x59D3, 0xD0D6, 0x5144, 0xD0D7, 0x51F6,
+	0xD0D8, 0x80F8, 0xD0D9, 0x5308, 0xD0DA, 0x6C79, 0xD0DB, 0x96C4,
+	0xD0DC, 0x718A, 0xD0DD, 0x4F11, 0xD0DE, 0x4FEE, 0xD0DF, 0x7F9E,
+	0xD0E0, 0x673D, 0xD0E1, 0x55C5, 0xD0E2, 0x9508, 0xD0E3, 0x79C0,
+	0xD0E4, 0x8896, 0xD0E5, 0x7EE3, 0xD0E6, 0x589F, 0xD0E7, 0x620C,
+	0xD0E8, 0x9700, 0xD0E9, 0x865A, 0xD0EA, 0x5618, 0xD0EB, 0x987B,
+	0xD0EC, 0x5F90, 0xD0ED, 0x8BB8, 0xD0EE, 0x84C4, 0xD0EF, 0x9157,
+	0xD0F0, 0x53D9, 0xD0F1, 0x65ED, 0xD0F2, 0x5E8F, 0xD0F3, 0x755C,
+	0xD0F4, 0x6064, 0xD0F5, 0x7D6E, 0xD0F6, 0x5A7F, 0xD0F7, 0x7EEA,
+	0xD0F8, 0x7EED, 0xD0F9, 0x8F69, 0xD0FA, 0x55A7, 0xD0FB, 0x5BA3,
+	0xD0FC, 0x60AC, 0xD0FD, 0x65CB, 0xD0FE, 0x7384, 0xD140, 0x88AC,
+	0xD141, 0x88AE, 0xD142, 0x88AF, 0xD143, 0x88B0, 0xD144, 0x88B2,
+	0xD145, 0x88B3, 0xD146, 0x88B4, 0xD147, 0x88B5, 0xD148, 0x88B6,
+	0xD149, 0x88B8, 0xD14A, 0x88B9, 0xD14B, 0x88BA, 0xD14C, 0x88BB,
+	0xD14D, 0x88BD, 0xD14E, 0x88BE, 0xD14F, 0x88BF, 0xD150, 0x88C0,
+	0xD151, 0x88C3, 0xD152, 0x88C4, 0xD153, 0x88C7, 0xD154, 0x88C8,
+	0xD155, 0x88CA, 0xD156, 0x88CB, 0xD157, 0x88CC, 0xD158, 0x88CD,
+	0xD159, 0x88CF, 0xD15A, 0x88D0, 0xD15B, 0x88D1, 0xD15C, 0x88D3,
+	0xD15D, 0x88D6, 0xD15E, 0x88D7, 0xD15F, 0x88DA, 0xD160, 0x88DB,
+	0xD161, 0x88DC, 0xD162, 0x88DD, 0xD163, 0x88DE, 0xD164, 0x88E0,
+	0xD165, 0x88E1, 0xD166, 0x88E6, 0xD167, 0x88E7, 0xD168, 0x88E9,
+	0xD169, 0x88EA, 0xD16A, 0x88EB, 0xD16B, 0x88EC, 0xD16C, 0x88ED,
+	0xD16D, 0x88EE, 0xD16E, 0x88EF, 0xD16F, 0x88F2, 0xD170, 0x88F5,
+	0xD171, 0x88F6, 0xD172, 0x88F7, 0xD173, 0x88FA, 0xD174, 0x88FB,
+	0xD175, 0x88FD, 0xD176, 0x88FF, 0xD177, 0x8900, 0xD178, 0x8901,
+	0xD179, 0x8903, 0xD17A, 0x8904, 0xD17B, 0x8905, 0xD17C, 0x8906,
+	0xD17D, 0x8907, 0xD17E, 0x8908, 0xD180, 0x8909, 0xD181, 0x890B,
+	0xD182, 0x890C, 0xD183, 0x890D, 0xD184, 0x890E, 0xD185, 0x890F,
+	0xD186, 0x8911, 0xD187, 0x8914, 0xD188, 0x8915, 0xD189, 0x8916,
+	0xD18A, 0x8917, 0xD18B, 0x8918, 0xD18C, 0x891C, 0xD18D, 0x891D,
+	0xD18E, 0x891E, 0xD18F, 0x891F, 0xD190, 0x8920, 0xD191, 0x8922,
+	0xD192, 0x8923, 0xD193, 0x8924, 0xD194, 0x8926, 0xD195, 0x8927,
+	0xD196, 0x8928, 0xD197, 0x8929, 0xD198, 0x892C, 0xD199, 0x892D,
+	0xD19A, 0x892E, 0xD19B, 0x892F, 0xD19C, 0x8931, 0xD19D, 0x8932,
+	0xD19E, 0x8933, 0xD19F, 0x8935, 0xD1A0, 0x8937, 0xD1A1, 0x9009,
+	0xD1A2, 0x7663, 0xD1A3, 0x7729, 0xD1A4, 0x7EDA, 0xD1A5, 0x9774,
+	0xD1A6, 0x859B, 0xD1A7, 0x5B66, 0xD1A8, 0x7A74, 0xD1A9, 0x96EA,
+	0xD1AA, 0x8840, 0xD1AB, 0x52CB, 0xD1AC, 0x718F, 0xD1AD, 0x5FAA,
+	0xD1AE, 0x65EC, 0xD1AF, 0x8BE2, 0xD1B0, 0x5BFB, 0xD1B1, 0x9A6F,
+	0xD1B2, 0x5DE1, 0xD1B3, 0x6B89, 0xD1B4, 0x6C5B, 0xD1B5, 0x8BAD,
+	0xD1B6, 0x8BAF, 0xD1B7, 0x900A, 0xD1B8, 0x8FC5, 0xD1B9, 0x538B,
+	0xD1BA, 0x62BC, 0xD1BB, 0x9E26, 0xD1BC, 0x9E2D, 0xD1BD, 0x5440,
+	0xD1BE, 0x4E2B, 0xD1BF, 0x82BD, 0xD1C0, 0x7259, 0xD1C1, 0x869C,
+	0xD1C2, 0x5D16, 0xD1C3, 0x8859, 0xD1C4, 0x6DAF, 0xD1C5, 0x96C5,
+	0xD1C6, 0x54D1, 0xD1C7, 0x4E9A, 0xD1C8, 0x8BB6, 0xD1C9, 0x7109,
+	0xD1CA, 0x54BD, 0xD1CB, 0x9609, 0xD1CC, 0x70DF, 0xD1CD, 0x6DF9,
+	0xD1CE, 0x76D0, 0xD1CF, 0x4E25, 0xD1D0, 0x7814, 0xD1D1, 0x8712,
+	0xD1D2, 0x5CA9, 0xD1D3, 0x5EF6, 0xD1D4, 0x8A00, 0xD1D5, 0x989C,
+	0xD1D6, 0x960E, 0xD1D7, 0x708E, 0xD1D8, 0x6CBF, 0xD1D9, 0x5944,
+	0xD1DA, 0x63A9, 0xD1DB, 0x773C, 0xD1DC, 0x884D, 0xD1DD, 0x6F14,
+	0xD1DE, 0x8273, 0xD1DF, 0x5830, 0xD1E0, 0x71D5, 0xD1E1, 0x538C,
+	0xD1E2, 0x781A, 0xD1E3, 0x96C1, 0xD1E4, 0x5501, 0xD1E5, 0x5F66,
+	0xD1E6, 0x7130, 0xD1E7, 0x5BB4, 0xD1E8, 0x8C1A, 0xD1E9, 0x9A8C,
+	0xD1EA, 0x6B83, 0xD1EB, 0x592E, 0xD1EC, 0x9E2F, 0xD1ED, 0x79E7,
+	0xD1EE, 0x6768, 0xD1EF, 0x626C, 0xD1F0, 0x4F6F, 0xD1F1, 0x75A1,
+	0xD1F2, 0x7F8A, 0xD1F3, 0x6D0B, 0xD1F4, 0x9633, 0xD1F5, 0x6C27,
+	0xD1F6, 0x4EF0, 0xD1F7, 0x75D2, 0xD1F8, 0x517B, 0xD1F9, 0x6837,
+	0xD1FA, 0x6F3E, 0xD1FB, 0x9080, 0xD1FC, 0x8170, 0xD1FD, 0x5996,
+	0xD1FE, 0x7476, 0xD240, 0x8938, 0xD241, 0x8939, 0xD242, 0x893A,
+	0xD243, 0x893B, 0xD244, 0x893C, 0xD245, 0x893D, 0xD246, 0x893E,
+	0xD247, 0x893F, 0xD248, 0x8940, 0xD249, 0x8942, 0xD24A, 0x8943,
+	0xD24B, 0x8945, 0xD24C, 0x8946, 0xD24D, 0x8947, 0xD24E, 0x8948,
+	0xD24F, 0x8949, 0xD250, 0x894A, 0xD251, 0x894B, 0xD252, 0x894C,
+	0xD253, 0x894D, 0xD254, 0x894E, 0xD255, 0x894F, 0xD256, 0x8950,
+	0xD257, 0x8951, 0xD258, 0x8952, 0xD259, 0x8953, 0xD25A, 0x8954,
+	0xD25B, 0x8955, 0xD25C, 0x8956, 0xD25D, 0x8957, 0xD25E, 0x8958,
+	0xD25F, 0x8959, 0xD260, 0x895A, 0xD261, 0x895B, 0xD262, 0x895C,
+	0xD263, 0x895D, 0xD264, 0x8960, 0xD265, 0x8961, 0xD266, 0x8962,
+	0xD267, 0x8963, 0xD268, 0x8964, 0xD269, 0x8965, 0xD26A, 0x8967,
+	0xD26B, 0x8968, 0xD26C, 0x8969, 0xD26D, 0x896A, 0xD26E, 0x896B,
+	0xD26F, 0x896C, 0xD270, 0x896D, 0xD271, 0x896E, 0xD272, 0x896F,
+	0xD273, 0x8970, 0xD274, 0x8971, 0xD275, 0x8972, 0xD276, 0x8973,
+	0xD277, 0x8974, 0xD278, 0x8975, 0xD279, 0x8976, 0xD27A, 0x8977,
+	0xD27B, 0x8978, 0xD27C, 0x8979, 0xD27D, 0x897A, 0xD27E, 0x897C,
+	0xD280, 0x897D, 0xD281, 0x897E, 0xD282, 0x8980, 0xD283, 0x8982,
+	0xD284, 0x8984, 0xD285, 0x8985, 0xD286, 0x8987, 0xD287, 0x8988,
+	0xD288, 0x8989, 0xD289, 0x898A, 0xD28A, 0x898B, 0xD28B, 0x898C,
+	0xD28C, 0x898D, 0xD28D, 0x898E, 0xD28E, 0x898F, 0xD28F, 0x8990,
+	0xD290, 0x8991, 0xD291, 0x8992, 0xD292, 0x8993, 0xD293, 0x8994,
+	0xD294, 0x8995, 0xD295, 0x8996, 0xD296, 0x8997, 0xD297, 0x8998,
+	0xD298, 0x8999, 0xD299, 0x899A, 0xD29A, 0x899B, 0xD29B, 0x899C,
+	0xD29C, 0x899D, 0xD29D, 0x899E, 0xD29E, 0x899F, 0xD29F, 0x89A0,
+	0xD2A0, 0x89A1, 0xD2A1, 0x6447, 0xD2A2, 0x5C27, 0xD2A3, 0x9065,
+	0xD2A4, 0x7A91, 0xD2A5, 0x8C23, 0xD2A6, 0x59DA, 0xD2A7, 0x54AC,
+	0xD2A8, 0x8200, 0xD2A9, 0x836F, 0xD2AA, 0x8981, 0xD2AB, 0x8000,
+	0xD2AC, 0x6930, 0xD2AD, 0x564E, 0xD2AE, 0x8036, 0xD2AF, 0x7237,
+	0xD2B0, 0x91CE, 0xD2B1, 0x51B6, 0xD2B2, 0x4E5F, 0xD2B3, 0x9875,
+	0xD2B4, 0x6396, 0xD2B5, 0x4E1A, 0xD2B6, 0x53F6, 0xD2B7, 0x66F3,
+	0xD2B8, 0x814B, 0xD2B9, 0x591C, 0xD2BA, 0x6DB2, 0xD2BB, 0x4E00,
+	0xD2BC, 0x58F9, 0xD2BD, 0x533B, 0xD2BE, 0x63D6, 0xD2BF, 0x94F1,
+	0xD2C0, 0x4F9D, 0xD2C1, 0x4F0A, 0xD2C2, 0x8863, 0xD2C3, 0x9890,
+	0xD2C4, 0x5937, 0xD2C5, 0x9057, 0xD2C6, 0x79FB, 0xD2C7, 0x4EEA,
+	0xD2C8, 0x80F0, 0xD2C9, 0x7591, 0xD2CA, 0x6C82, 0xD2CB, 0x5B9C,
+	0xD2CC, 0x59E8, 0xD2CD, 0x5F5D, 0xD2CE, 0x6905, 0xD2CF, 0x8681,
+	0xD2D0, 0x501A, 0xD2D1, 0x5DF2, 0xD2D2, 0x4E59, 0xD2D3, 0x77E3,
+	0xD2D4, 0x4EE5, 0xD2D5, 0x827A, 0xD2D6, 0x6291, 0xD2D7, 0x6613,
+	0xD2D8, 0x9091, 0xD2D9, 0x5C79, 0xD2DA, 0x4EBF, 0xD2DB, 0x5F79,
+	0xD2DC, 0x81C6, 0xD2DD, 0x9038, 0xD2DE, 0x8084, 0xD2DF, 0x75AB,
+	0xD2E0, 0x4EA6, 0xD2E1, 0x88D4, 0xD2E2, 0x610F, 0xD2E3, 0x6BC5,
+	0xD2E4, 0x5FC6, 0xD2E5, 0x4E49, 0xD2E6, 0x76CA, 0xD2E7, 0x6EA2,
+	0xD2E8, 0x8BE3, 0xD2E9, 0x8BAE, 0xD2EA, 0x8C0A, 0xD2EB, 0x8BD1,
+	0xD2EC, 0x5F02, 0xD2ED, 0x7FFC, 0xD2EE, 0x7FCC, 0xD2EF, 0x7ECE,
+	0xD2F0, 0x8335, 0xD2F1, 0x836B, 0xD2F2, 0x56E0, 0xD2F3, 0x6BB7,
+	0xD2F4, 0x97F3, 0xD2F5, 0x9634, 0xD2F6, 0x59FB, 0xD2F7, 0x541F,
+	0xD2F8, 0x94F6, 0xD2F9, 0x6DEB, 0xD2FA, 0x5BC5, 0xD2FB, 0x996E,
+	0xD2FC, 0x5C39, 0xD2FD, 0x5F15, 0xD2FE, 0x9690, 0xD340, 0x89A2,
+	0xD341, 0x89A3, 0xD342, 0x89A4, 0xD343, 0x89A5, 0xD344, 0x89A6,
+	0xD345, 0x89A7, 0xD346, 0x89A8, 0xD347, 0x89A9, 0xD348, 0x89AA,
+	0xD349, 0x89AB, 0xD34A, 0x89AC, 0xD34B, 0x89AD, 0xD34C, 0x89AE,
+	0xD34D, 0x89AF, 0xD34E, 0x89B0, 0xD34F, 0x89B1, 0xD350, 0x89B2,
+	0xD351, 0x89B3, 0xD352, 0x89B4, 0xD353, 0x89B5, 0xD354, 0x89B6,
+	0xD355, 0x89B7, 0xD356, 0x89B8, 0xD357, 0x89B9, 0xD358, 0x89BA,
+	0xD359, 0x89BB, 0xD35A, 0x89BC, 0xD35B, 0x89BD, 0xD35C, 0x89BE,
+	0xD35D, 0x89BF, 0xD35E, 0x89C0, 0xD35F, 0x89C3, 0xD360, 0x89CD,
+	0xD361, 0x89D3, 0xD362, 0x89D4, 0xD363, 0x89D5, 0xD364, 0x89D7,
+	0xD365, 0x89D8, 0xD366, 0x89D9, 0xD367, 0x89DB, 0xD368, 0x89DD,
+	0xD369, 0x89DF, 0xD36A, 0x89E0, 0xD36B, 0x89E1, 0xD36C, 0x89E2,
+	0xD36D, 0x89E4, 0xD36E, 0x89E7, 0xD36F, 0x89E8, 0xD370, 0x89E9,
+	0xD371, 0x89EA, 0xD372, 0x89EC, 0xD373, 0x89ED, 0xD374, 0x89EE,
+	0xD375, 0x89F0, 0xD376, 0x89F1, 0xD377, 0x89F2, 0xD378, 0x89F4,
+	0xD379, 0x89F5, 0xD37A, 0x89F6, 0xD37B, 0x89F7, 0xD37C, 0x89F8,
+	0xD37D, 0x89F9, 0xD37E, 0x89FA, 0xD380, 0x89FB, 0xD381, 0x89FC,
+	0xD382, 0x89FD, 0xD383, 0x89FE, 0xD384, 0x89FF, 0xD385, 0x8A01,
+	0xD386, 0x8A02, 0xD387, 0x8A03, 0xD388, 0x8A04, 0xD389, 0x8A05,
+	0xD38A, 0x8A06, 0xD38B, 0x8A08, 0xD38C, 0x8A09, 0xD38D, 0x8A0A,
+	0xD38E, 0x8A0B, 0xD38F, 0x8A0C, 0xD390, 0x8A0D, 0xD391, 0x8A0E,
+	0xD392, 0x8A0F, 0xD393, 0x8A10, 0xD394, 0x8A11, 0xD395, 0x8A12,
+	0xD396, 0x8A13, 0xD397, 0x8A14, 0xD398, 0x8A15, 0xD399, 0x8A16,
+	0xD39A, 0x8A17, 0xD39B, 0x8A18, 0xD39C, 0x8A19, 0xD39D, 0x8A1A,
+	0xD39E, 0x8A1B, 0xD39F, 0x8A1C, 0xD3A0, 0x8A1D, 0xD3A1, 0x5370,
+	0xD3A2, 0x82F1, 0xD3A3, 0x6A31, 0xD3A4, 0x5A74, 0xD3A5, 0x9E70,
+	0xD3A6, 0x5E94, 0xD3A7, 0x7F28, 0xD3A8, 0x83B9, 0xD3A9, 0x8424,
+	0xD3AA, 0x8425, 0xD3AB, 0x8367, 0xD3AC, 0x8747, 0xD3AD, 0x8FCE,
+	0xD3AE, 0x8D62, 0xD3AF, 0x76C8, 0xD3B0, 0x5F71, 0xD3B1, 0x9896,
+	0xD3B2, 0x786C, 0xD3B3, 0x6620, 0xD3B4, 0x54DF, 0xD3B5, 0x62E5,
+	0xD3B6, 0x4F63, 0xD3B7, 0x81C3, 0xD3B8, 0x75C8, 0xD3B9, 0x5EB8,
+	0xD3BA, 0x96CD, 0xD3BB, 0x8E0A, 0xD3BC, 0x86F9, 0xD3BD, 0x548F,
+	0xD3BE, 0x6CF3, 0xD3BF, 0x6D8C, 0xD3C0, 0x6C38, 0xD3C1, 0x607F,
+	0xD3C2, 0x52C7, 0xD3C3, 0x7528, 0xD3C4, 0x5E7D, 0xD3C5, 0x4F18,
+	0xD3C6, 0x60A0, 0xD3C7, 0x5FE7, 0xD3C8, 0x5C24, 0xD3C9, 0x7531,
+	0xD3CA, 0x90AE, 0xD3CB, 0x94C0, 0xD3CC, 0x72B9, 0xD3CD, 0x6CB9,
+	0xD3CE, 0x6E38, 0xD3CF, 0x9149, 0xD3D0, 0x6709, 0xD3D1, 0x53CB,
+	0xD3D2, 0x53F3, 0xD3D3, 0x4F51, 0xD3D4, 0x91C9, 0xD3D5, 0x8BF1,
+	0xD3D6, 0x53C8, 0xD3D7, 0x5E7C, 0xD3D8, 0x8FC2, 0xD3D9, 0x6DE4,
+	0xD3DA, 0x4E8E, 0xD3DB, 0x76C2, 0xD3DC, 0x6986, 0xD3DD, 0x865E,
+	0xD3DE, 0x611A, 0xD3DF, 0x8206, 0xD3E0, 0x4F59, 0xD3E1, 0x4FDE,
+	0xD3E2, 0x903E, 0xD3E3, 0x9C7C, 0xD3E4, 0x6109, 0xD3E5, 0x6E1D,
+	0xD3E6, 0x6E14, 0xD3E7, 0x9685, 0xD3E8, 0x4E88, 0xD3E9, 0x5A31,
+	0xD3EA, 0x96E8, 0xD3EB, 0x4E0E, 0xD3EC, 0x5C7F, 0xD3ED, 0x79B9,
+	0xD3EE, 0x5B87, 0xD3EF, 0x8BED, 0xD3F0, 0x7FBD, 0xD3F1, 0x7389,
+	0xD3F2, 0x57DF, 0xD3F3, 0x828B, 0xD3F4, 0x90C1, 0xD3F5, 0x5401,
+	0xD3F6, 0x9047, 0xD3F7, 0x55BB, 0xD3F8, 0x5CEA, 0xD3F9, 0x5FA1,
+	0xD3FA, 0x6108, 0xD3FB, 0x6B32, 0xD3FC, 0x72F1, 0xD3FD, 0x80B2,
+	0xD3FE, 0x8A89, 0xD440, 0x8A1E, 0xD441, 0x8A1F, 0xD442, 0x8A20,
+	0xD443, 0x8A21, 0xD444, 0x8A22, 0xD445, 0x8A23, 0xD446, 0x8A24,
+	0xD447, 0x8A25, 0xD448, 0x8A26, 0xD449, 0x8A27, 0xD44A, 0x8A28,
+	0xD44B, 0x8A29, 0xD44C, 0x8A2A, 0xD44D, 0x8A2B, 0xD44E, 0x8A2C,
+	0xD44F, 0x8A2D, 0xD450, 0x8A2E, 0xD451, 0x8A2F, 0xD452, 0x8A30,
+	0xD453, 0x8A31, 0xD454, 0x8A32, 0xD455, 0x8A33, 0xD456, 0x8A34,
+	0xD457, 0x8A35, 0xD458, 0x8A36, 0xD459, 0x8A37, 0xD45A, 0x8A38,
+	0xD45B, 0x8A39, 0xD45C, 0x8A3A, 0xD45D, 0x8A3B, 0xD45E, 0x8A3C,
+	0xD45F, 0x8A3D, 0xD460, 0x8A3F, 0xD461, 0x8A40, 0xD462, 0x8A41,
+	0xD463, 0x8A42, 0xD464, 0x8A43, 0xD465, 0x8A44, 0xD466, 0x8A45,
+	0xD467, 0x8A46, 0xD468, 0x8A47, 0xD469, 0x8A49, 0xD46A, 0x8A4A,
+	0xD46B, 0x8A4B, 0xD46C, 0x8A4C, 0xD46D, 0x8A4D, 0xD46E, 0x8A4E,
+	0xD46F, 0x8A4F, 0xD470, 0x8A50, 0xD471, 0x8A51, 0xD472, 0x8A52,
+	0xD473, 0x8A53, 0xD474, 0x8A54, 0xD475, 0x8A55, 0xD476, 0x8A56,
+	0xD477, 0x8A57, 0xD478, 0x8A58, 0xD479, 0x8A59, 0xD47A, 0x8A5A,
+	0xD47B, 0x8A5B, 0xD47C, 0x8A5C, 0xD47D, 0x8A5D, 0xD47E, 0x8A5E,
+	0xD480, 0x8A5F, 0xD481, 0x8A60, 0xD482, 0x8A61, 0xD483, 0x8A62,
+	0xD484, 0x8A63, 0xD485, 0x8A64, 0xD486, 0x8A65, 0xD487, 0x8A66,
+	0xD488, 0x8A67, 0xD489, 0x8A68, 0xD48A, 0x8A69, 0xD48B, 0x8A6A,
+	0xD48C, 0x8A6B, 0xD48D, 0x8A6C, 0xD48E, 0x8A6D, 0xD48F, 0x8A6E,
+	0xD490, 0x8A6F, 0xD491, 0x8A70, 0xD492, 0x8A71, 0xD493, 0x8A72,
+	0xD494, 0x8A73, 0xD495, 0x8A74, 0xD496, 0x8A75, 0xD497, 0x8A76,
+	0xD498, 0x8A77, 0xD499, 0x8A78, 0xD49A, 0x8A7A, 0xD49B, 0x8A7B,
+	0xD49C, 0x8A7C, 0xD49D, 0x8A7D, 0xD49E, 0x8A7E, 0xD49F, 0x8A7F,
+	0xD4A0, 0x8A80, 0xD4A1, 0x6D74, 0xD4A2, 0x5BD3, 0xD4A3, 0x88D5,
+	0xD4A4, 0x9884, 0xD4A5, 0x8C6B, 0xD4A6, 0x9A6D, 0xD4A7, 0x9E33,
+	0xD4A8, 0x6E0A, 0xD4A9, 0x51A4, 0xD4AA, 0x5143, 0xD4AB, 0x57A3,
+	0xD4AC, 0x8881, 0xD4AD, 0x539F, 0xD4AE, 0x63F4, 0xD4AF, 0x8F95,
+	0xD4B0, 0x56ED, 0xD4B1, 0x5458, 0xD4B2, 0x5706, 0xD4B3, 0x733F,
+	0xD4B4, 0x6E90, 0xD4B5, 0x7F18, 0xD4B6, 0x8FDC, 0xD4B7, 0x82D1,
+	0xD4B8, 0x613F, 0xD4B9, 0x6028, 0xD4BA, 0x9662, 0xD4BB, 0x66F0,
+	0xD4BC, 0x7EA6, 0xD4BD, 0x8D8A, 0xD4BE, 0x8DC3, 0xD4BF, 0x94A5,
+	0xD4C0, 0x5CB3, 0xD4C1, 0x7CA4, 0xD4C2, 0x6708, 0xD4C3, 0x60A6,
+	0xD4C4, 0x9605, 0xD4C5, 0x8018, 0xD4C6, 0x4E91, 0xD4C7, 0x90E7,
+	0xD4C8, 0x5300, 0xD4C9, 0x9668, 0xD4CA, 0x5141, 0xD4CB, 0x8FD0,
+	0xD4CC, 0x8574, 0xD4CD, 0x915D, 0xD4CE, 0x6655, 0xD4CF, 0x97F5,
+	0xD4D0, 0x5B55, 0xD4D1, 0x531D, 0xD4D2, 0x7838, 0xD4D3, 0x6742,
+	0xD4D4, 0x683D, 0xD4D5, 0x54C9, 0xD4D6, 0x707E, 0xD4D7, 0x5BB0,
+	0xD4D8, 0x8F7D, 0xD4D9, 0x518D, 0xD4DA, 0x5728, 0xD4DB, 0x54B1,
+	0xD4DC, 0x6512, 0xD4DD, 0x6682, 0xD4DE, 0x8D5E, 0xD4DF, 0x8D43,
+	0xD4E0, 0x810F, 0xD4E1, 0x846C, 0xD4E2, 0x906D, 0xD4E3, 0x7CDF,
+	0xD4E4, 0x51FF, 0xD4E5, 0x85FB, 0xD4E6, 0x67A3, 0xD4E7, 0x65E9,
+	0xD4E8, 0x6FA1, 0xD4E9, 0x86A4, 0xD4EA, 0x8E81, 0xD4EB, 0x566A,
+	0xD4EC, 0x9020, 0xD4ED, 0x7682, 0xD4EE, 0x7076, 0xD4EF, 0x71E5,
+	0xD4F0, 0x8D23, 0xD4F1, 0x62E9, 0xD4F2, 0x5219, 0xD4F3, 0x6CFD,
+	0xD4F4, 0x8D3C, 0xD4F5, 0x600E, 0xD4F6, 0x589E, 0xD4F7, 0x618E,
+	0xD4F8, 0x66FE, 0xD4F9, 0x8D60, 0xD4FA, 0x624E, 0xD4FB, 0x55B3,
+	0xD4FC, 0x6E23, 0xD4FD, 0x672D, 0xD4FE, 0x8F67, 0xD540, 0x8A81,
+	0xD541, 0x8A82, 0xD542, 0x8A83, 0xD543, 0x8A84, 0xD544, 0x8A85,
+	0xD545, 0x8A86, 0xD546, 0x8A87, 0xD547, 0x8A88, 0xD548, 0x8A8B,
+	0xD549, 0x8A8C, 0xD54A, 0x8A8D, 0xD54B, 0x8A8E, 0xD54C, 0x8A8F,
+	0xD54D, 0x8A90, 0xD54E, 0x8A91, 0xD54F, 0x8A92, 0xD550, 0x8A94,
+	0xD551, 0x8A95, 0xD552, 0x8A96, 0xD553, 0x8A97, 0xD554, 0x8A98,
+	0xD555, 0x8A99, 0xD556, 0x8A9A, 0xD557, 0x8A9B, 0xD558, 0x8A9C,
+	0xD559, 0x8A9D, 0xD55A, 0x8A9E, 0xD55B, 0x8A9F, 0xD55C, 0x8AA0,
+	0xD55D, 0x8AA1, 0xD55E, 0x8AA2, 0xD55F, 0x8AA3, 0xD560, 0x8AA4,
+	0xD561, 0x8AA5, 0xD562, 0x8AA6, 0xD563, 0x8AA7, 0xD564, 0x8AA8,
+	0xD565, 0x8AA9, 0xD566, 0x8AAA, 0xD567, 0x8AAB, 0xD568, 0x8AAC,
+	0xD569, 0x8AAD, 0xD56A, 0x8AAE, 0xD56B, 0x8AAF, 0xD56C, 0x8AB0,
+	0xD56D, 0x8AB1, 0xD56E, 0x8AB2, 0xD56F, 0x8AB3, 0xD570, 0x8AB4,
+	0xD571, 0x8AB5, 0xD572, 0x8AB6, 0xD573, 0x8AB7, 0xD574, 0x8AB8,
+	0xD575, 0x8AB9, 0xD576, 0x8ABA, 0xD577, 0x8ABB, 0xD578, 0x8ABC,
+	0xD579, 0x8ABD, 0xD57A, 0x8ABE, 0xD57B, 0x8ABF, 0xD57C, 0x8AC0,
+	0xD57D, 0x8AC1, 0xD57E, 0x8AC2, 0xD580, 0x8AC3, 0xD581, 0x8AC4,
+	0xD582, 0x8AC5, 0xD583, 0x8AC6, 0xD584, 0x8AC7, 0xD585, 0x8AC8,
+	0xD586, 0x8AC9, 0xD587, 0x8ACA, 0xD588, 0x8ACB, 0xD589, 0x8ACC,
+	0xD58A, 0x8ACD, 0xD58B, 0x8ACE, 0xD58C, 0x8ACF, 0xD58D, 0x8AD0,
+	0xD58E, 0x8AD1, 0xD58F, 0x8AD2, 0xD590, 0x8AD3, 0xD591, 0x8AD4,
+	0xD592, 0x8AD5, 0xD593, 0x8AD6, 0xD594, 0x8AD7, 0xD595, 0x8AD8,
+	0xD596, 0x8AD9, 0xD597, 0x8ADA, 0xD598, 0x8ADB, 0xD599, 0x8ADC,
+	0xD59A, 0x8ADD, 0xD59B, 0x8ADE, 0xD59C, 0x8ADF, 0xD59D, 0x8AE0,
+	0xD59E, 0x8AE1, 0xD59F, 0x8AE2, 0xD5A0, 0x8AE3, 0xD5A1, 0x94E1,
+	0xD5A2, 0x95F8, 0xD5A3, 0x7728, 0xD5A4, 0x6805, 0xD5A5, 0x69A8,
+	0xD5A6, 0x548B, 0xD5A7, 0x4E4D, 0xD5A8, 0x70B8, 0xD5A9, 0x8BC8,
+	0xD5AA, 0x6458, 0xD5AB, 0x658B, 0xD5AC, 0x5B85, 0xD5AD, 0x7A84,
+	0xD5AE, 0x503A, 0xD5AF, 0x5BE8, 0xD5B0, 0x77BB, 0xD5B1, 0x6BE1,
+	0xD5B2, 0x8A79, 0xD5B3, 0x7C98, 0xD5B4, 0x6CBE, 0xD5B5, 0x76CF,
+	0xD5B6, 0x65A9, 0xD5B7, 0x8F97, 0xD5B8, 0x5D2D, 0xD5B9, 0x5C55,
+	0xD5BA, 0x8638, 0xD5BB, 0x6808, 0xD5BC, 0x5360, 0xD5BD, 0x6218,
+	0xD5BE, 0x7AD9, 0xD5BF, 0x6E5B, 0xD5C0, 0x7EFD, 0xD5C1, 0x6A1F,
+	0xD5C2, 0x7AE0, 0xD5C3, 0x5F70, 0xD5C4, 0x6F33, 0xD5C5, 0x5F20,
+	0xD5C6, 0x638C, 0xD5C7, 0x6DA8, 0xD5C8, 0x6756, 0xD5C9, 0x4E08,
+	0xD5CA, 0x5E10, 0xD5CB, 0x8D26, 0xD5CC, 0x4ED7, 0xD5CD, 0x80C0,
+	0xD5CE, 0x7634, 0xD5CF, 0x969C, 0xD5D0, 0x62DB, 0xD5D1, 0x662D,
+	0xD5D2, 0x627E, 0xD5D3, 0x6CBC, 0xD5D4, 0x8D75, 0xD5D5, 0x7167,
+	0xD5D6, 0x7F69, 0xD5D7, 0x5146, 0xD5D8, 0x8087, 0xD5D9, 0x53EC,
+	0xD5DA, 0x906E, 0xD5DB, 0x6298, 0xD5DC, 0x54F2, 0xD5DD, 0x86F0,
+	0xD5DE, 0x8F99, 0xD5DF, 0x8005, 0xD5E0, 0x9517, 0xD5E1, 0x8517,
+	0xD5E2, 0x8FD9, 0xD5E3, 0x6D59, 0xD5E4, 0x73CD, 0xD5E5, 0x659F,
+	0xD5E6, 0x771F, 0xD5E7, 0x7504, 0xD5E8, 0x7827, 0xD5E9, 0x81FB,
+	0xD5EA, 0x8D1E, 0xD5EB, 0x9488, 0xD5EC, 0x4FA6, 0xD5ED, 0x6795,
+	0xD5EE, 0x75B9, 0xD5EF, 0x8BCA, 0xD5F0, 0x9707, 0xD5F1, 0x632F,
+	0xD5F2, 0x9547, 0xD5F3, 0x9635, 0xD5F4, 0x84B8, 0xD5F5, 0x6323,
+	0xD5F6, 0x7741, 0xD5F7, 0x5F81, 0xD5F8, 0x72F0, 0xD5F9, 0x4E89,
+	0xD5FA, 0x6014, 0xD5FB, 0x6574, 0xD5FC, 0x62EF, 0xD5FD, 0x6B63,
+	0xD5FE, 0x653F, 0xD640, 0x8AE4, 0xD641, 0x8AE5, 0xD642, 0x8AE6,
+	0xD643, 0x8AE7, 0xD644, 0x8AE8, 0xD645, 0x8AE9, 0xD646, 0x8AEA,
+	0xD647, 0x8AEB, 0xD648, 0x8AEC, 0xD649, 0x8AED, 0xD64A, 0x8AEE,
+	0xD64B, 0x8AEF, 0xD64C, 0x8AF0, 0xD64D, 0x8AF1, 0xD64E, 0x8AF2,
+	0xD64F, 0x8AF3, 0xD650, 0x8AF4, 0xD651, 0x8AF5, 0xD652, 0x8AF6,
+	0xD653, 0x8AF7, 0xD654, 0x8AF8, 0xD655, 0x8AF9, 0xD656, 0x8AFA,
+	0xD657, 0x8AFB, 0xD658, 0x8AFC, 0xD659, 0x8AFD, 0xD65A, 0x8AFE,
+	0xD65B, 0x8AFF, 0xD65C, 0x8B00, 0xD65D, 0x8B01, 0xD65E, 0x8B02,
+	0xD65F, 0x8B03, 0xD660, 0x8B04, 0xD661, 0x8B05, 0xD662, 0x8B06,
+	0xD663, 0x8B08, 0xD664, 0x8B09, 0xD665, 0x8B0A, 0xD666, 0x8B0B,
+	0xD667, 0x8B0C, 0xD668, 0x8B0D, 0xD669, 0x8B0E, 0xD66A, 0x8B0F,
+	0xD66B, 0x8B10, 0xD66C, 0x8B11, 0xD66D, 0x8B12, 0xD66E, 0x8B13,
+	0xD66F, 0x8B14, 0xD670, 0x8B15, 0xD671, 0x8B16, 0xD672, 0x8B17,
+	0xD673, 0x8B18, 0xD674, 0x8B19, 0xD675, 0x8B1A, 0xD676, 0x8B1B,
+	0xD677, 0x8B1C, 0xD678, 0x8B1D, 0xD679, 0x8B1E, 0xD67A, 0x8B1F,
+	0xD67B, 0x8B20, 0xD67C, 0x8B21, 0xD67D, 0x8B22, 0xD67E, 0x8B23,
+	0xD680, 0x8B24, 0xD681, 0x8B25, 0xD682, 0x8B27, 0xD683, 0x8B28,
+	0xD684, 0x8B29, 0xD685, 0x8B2A, 0xD686, 0x8B2B, 0xD687, 0x8B2C,
+	0xD688, 0x8B2D, 0xD689, 0x8B2E, 0xD68A, 0x8B2F, 0xD68B, 0x8B30,
+	0xD68C, 0x8B31, 0xD68D, 0x8B32, 0xD68E, 0x8B33, 0xD68F, 0x8B34,
+	0xD690, 0x8B35, 0xD691, 0x8B36, 0xD692, 0x8B37, 0xD693, 0x8B38,
+	0xD694, 0x8B39, 0xD695, 0x8B3A, 0xD696, 0x8B3B, 0xD697, 0x8B3C,
+	0xD698, 0x8B3D, 0xD699, 0x8B3E, 0xD69A, 0x8B3F, 0xD69B, 0x8B40,
+	0xD69C, 0x8B41, 0xD69D, 0x8B42, 0xD69E, 0x8B43, 0xD69F, 0x8B44,
+	0xD6A0, 0x8B45, 0xD6A1, 0x5E27, 0xD6A2, 0x75C7, 0xD6A3, 0x90D1,
+	0xD6A4, 0x8BC1, 0xD6A5, 0x829D, 0xD6A6, 0x679D, 0xD6A7, 0x652F,
+	0xD6A8, 0x5431, 0xD6A9, 0x8718, 0xD6AA, 0x77E5, 0xD6AB, 0x80A2,
+	0xD6AC, 0x8102, 0xD6AD, 0x6C41, 0xD6AE, 0x4E4B, 0xD6AF, 0x7EC7,
+	0xD6B0, 0x804C, 0xD6B1, 0x76F4, 0xD6B2, 0x690D, 0xD6B3, 0x6B96,
+	0xD6B4, 0x6267, 0xD6B5, 0x503C, 0xD6B6, 0x4F84, 0xD6B7, 0x5740,
+	0xD6B8, 0x6307, 0xD6B9, 0x6B62, 0xD6BA, 0x8DBE, 0xD6BB, 0x53EA,
+	0xD6BC, 0x65E8, 0xD6BD, 0x7EB8, 0xD6BE, 0x5FD7, 0xD6BF, 0x631A,
+	0xD6C0, 0x63B7, 0xD6C1, 0x81F3, 0xD6C2, 0x81F4, 0xD6C3, 0x7F6E,
+	0xD6C4, 0x5E1C, 0xD6C5, 0x5CD9, 0xD6C6, 0x5236, 0xD6C7, 0x667A,
+	0xD6C8, 0x79E9, 0xD6C9, 0x7A1A, 0xD6CA, 0x8D28, 0xD6CB, 0x7099,
+	0xD6CC, 0x75D4, 0xD6CD, 0x6EDE, 0xD6CE, 0x6CBB, 0xD6CF, 0x7A92,
+	0xD6D0, 0x4E2D, 0xD6D1, 0x76C5, 0xD6D2, 0x5FE0, 0xD6D3, 0x949F,
+	0xD6D4, 0x8877, 0xD6D5, 0x7EC8, 0xD6D6, 0x79CD, 0xD6D7, 0x80BF,
+	0xD6D8, 0x91CD, 0xD6D9, 0x4EF2, 0xD6DA, 0x4F17, 0xD6DB, 0x821F,
+	0xD6DC, 0x5468, 0xD6DD, 0x5DDE, 0xD6DE, 0x6D32, 0xD6DF, 0x8BCC,
+	0xD6E0, 0x7CA5, 0xD6E1, 0x8F74, 0xD6E2, 0x8098, 0xD6E3, 0x5E1A,
+	0xD6E4, 0x5492, 0xD6E5, 0x76B1, 0xD6E6, 0x5B99, 0xD6E7, 0x663C,
+	0xD6E8, 0x9AA4, 0xD6E9, 0x73E0, 0xD6EA, 0x682A, 0xD6EB, 0x86DB,
+	0xD6EC, 0x6731, 0xD6ED, 0x732A, 0xD6EE, 0x8BF8, 0xD6EF, 0x8BDB,
+	0xD6F0, 0x9010, 0xD6F1, 0x7AF9, 0xD6F2, 0x70DB, 0xD6F3, 0x716E,
+	0xD6F4, 0x62C4, 0xD6F5, 0x77A9, 0xD6F6, 0x5631, 0xD6F7, 0x4E3B,
+	0xD6F8, 0x8457, 0xD6F9, 0x67F1, 0xD6FA, 0x52A9, 0xD6FB, 0x86C0,
+	0xD6FC, 0x8D2E, 0xD6FD, 0x94F8, 0xD6FE, 0x7B51, 0xD740, 0x8B46,
+	0xD741, 0x8B47, 0xD742, 0x8B48, 0xD743, 0x8B49, 0xD744, 0x8B4A,
+	0xD745, 0x8B4B, 0xD746, 0x8B4C, 0xD747, 0x8B4D, 0xD748, 0x8B4E,
+	0xD749, 0x8B4F, 0xD74A, 0x8B50, 0xD74B, 0x8B51, 0xD74C, 0x8B52,
+	0xD74D, 0x8B53, 0xD74E, 0x8B54, 0xD74F, 0x8B55, 0xD750, 0x8B56,
+	0xD751, 0x8B57, 0xD752, 0x8B58, 0xD753, 0x8B59, 0xD754, 0x8B5A,
+	0xD755, 0x8B5B, 0xD756, 0x8B5C, 0xD757, 0x8B5D, 0xD758, 0x8B5E,
+	0xD759, 0x8B5F, 0xD75A, 0x8B60, 0xD75B, 0x8B61, 0xD75C, 0x8B62,
+	0xD75D, 0x8B63, 0xD75E, 0x8B64, 0xD75F, 0x8B65, 0xD760, 0x8B67,
+	0xD761, 0x8B68, 0xD762, 0x8B69, 0xD763, 0x8B6A, 0xD764, 0x8B6B,
+	0xD765, 0x8B6D, 0xD766, 0x8B6E, 0xD767, 0x8B6F, 0xD768, 0x8B70,
+	0xD769, 0x8B71, 0xD76A, 0x8B72, 0xD76B, 0x8B73, 0xD76C, 0x8B74,
+	0xD76D, 0x8B75, 0xD76E, 0x8B76, 0xD76F, 0x8B77, 0xD770, 0x8B78,
+	0xD771, 0x8B79, 0xD772, 0x8B7A, 0xD773, 0x8B7B, 0xD774, 0x8B7C,
+	0xD775, 0x8B7D, 0xD776, 0x8B7E, 0xD777, 0x8B7F, 0xD778, 0x8B80,
+	0xD779, 0x8B81, 0xD77A, 0x8B82, 0xD77B, 0x8B83, 0xD77C, 0x8B84,
+	0xD77D, 0x8B85, 0xD77E, 0x8B86, 0xD780, 0x8B87, 0xD781, 0x8B88,
+	0xD782, 0x8B89, 0xD783, 0x8B8A, 0xD784, 0x8B8B, 0xD785, 0x8B8C,
+	0xD786, 0x8B8D, 0xD787, 0x8B8E, 0xD788, 0x8B8F, 0xD789, 0x8B90,
+	0xD78A, 0x8B91, 0xD78B, 0x8B92, 0xD78C, 0x8B93, 0xD78D, 0x8B94,
+	0xD78E, 0x8B95, 0xD78F, 0x8B96, 0xD790, 0x8B97, 0xD791, 0x8B98,
+	0xD792, 0x8B99, 0xD793, 0x8B9A, 0xD794, 0x8B9B, 0xD795, 0x8B9C,
+	0xD796, 0x8B9D, 0xD797, 0x8B9E, 0xD798, 0x8B9F, 0xD799, 0x8BAC,
+	0xD79A, 0x8BB1, 0xD79B, 0x8BBB, 0xD79C, 0x8BC7, 0xD79D, 0x8BD0,
+	0xD79E, 0x8BEA, 0xD79F, 0x8C09, 0xD7A0, 0x8C1E, 0xD7A1, 0x4F4F,
+	0xD7A2, 0x6CE8, 0xD7A3, 0x795D, 0xD7A4, 0x9A7B, 0xD7A5, 0x6293,
+	0xD7A6, 0x722A, 0xD7A7, 0x62FD, 0xD7A8, 0x4E13, 0xD7A9, 0x7816,
+	0xD7AA, 0x8F6C, 0xD7AB, 0x64B0, 0xD7AC, 0x8D5A, 0xD7AD, 0x7BC6,
+	0xD7AE, 0x6869, 0xD7AF, 0x5E84, 0xD7B0, 0x88C5, 0xD7B1, 0x5986,
+	0xD7B2, 0x649E, 0xD7B3, 0x58EE, 0xD7B4, 0x72B6, 0xD7B5, 0x690E,
+	0xD7B6, 0x9525, 0xD7B7, 0x8FFD, 0xD7B8, 0x8D58, 0xD7B9, 0x5760,
+	0xD7BA, 0x7F00, 0xD7BB, 0x8C06, 0xD7BC, 0x51C6, 0xD7BD, 0x6349,
+	0xD7BE, 0x62D9, 0xD7BF, 0x5353, 0xD7C0, 0x684C, 0xD7C1, 0x7422,
+	0xD7C2, 0x8301, 0xD7C3, 0x914C, 0xD7C4, 0x5544, 0xD7C5, 0x7740,
+	0xD7C6, 0x707C, 0xD7C7, 0x6D4A, 0xD7C8, 0x5179, 0xD7C9, 0x54A8,
+	0xD7CA, 0x8D44, 0xD7CB, 0x59FF, 0xD7CC, 0x6ECB, 0xD7CD, 0x6DC4,
+	0xD7CE, 0x5B5C, 0xD7CF, 0x7D2B, 0xD7D0, 0x4ED4, 0xD7D1, 0x7C7D,
+	0xD7D2, 0x6ED3, 0xD7D3, 0x5B50, 0xD7D4, 0x81EA, 0xD7D5, 0x6E0D,
+	0xD7D6, 0x5B57, 0xD7D7, 0x9B03, 0xD7D8, 0x68D5, 0xD7D9, 0x8E2A,
+	0xD7DA, 0x5B97, 0xD7DB, 0x7EFC, 0xD7DC, 0x603B, 0xD7DD, 0x7EB5,
+	0xD7DE, 0x90B9, 0xD7DF, 0x8D70, 0xD7E0, 0x594F, 0xD7E1, 0x63CD,
+	0xD7E2, 0x79DF, 0xD7E3, 0x8DB3, 0xD7E4, 0x5352, 0xD7E5, 0x65CF,
+	0xD7E6, 0x7956, 0xD7E7, 0x8BC5, 0xD7E8, 0x963B, 0xD7E9, 0x7EC4,
+	0xD7EA, 0x94BB, 0xD7EB, 0x7E82, 0xD7EC, 0x5634, 0xD7ED, 0x9189,
+	0xD7EE, 0x6700, 0xD7EF, 0x7F6A, 0xD7F0, 0x5C0A, 0xD7F1, 0x9075,
+	0xD7F2, 0x6628, 0xD7F3, 0x5DE6, 0xD7F4, 0x4F50, 0xD7F5, 0x67DE,
+	0xD7F6, 0x505A, 0xD7F7, 0x4F5C, 0xD7F8, 0x5750, 0xD7F9, 0x5EA7,
+	0xD840, 0x8C38, 0xD841, 0x8C39, 0xD842, 0x8C3A, 0xD843, 0x8C3B,
+	0xD844, 0x8C3C, 0xD845, 0x8C3D, 0xD846, 0x8C3E, 0xD847, 0x8C3F,
+	0xD848, 0x8C40, 0xD849, 0x8C42, 0xD84A, 0x8C43, 0xD84B, 0x8C44,
+	0xD84C, 0x8C45, 0xD84D, 0x8C48, 0xD84E, 0x8C4A, 0xD84F, 0x8C4B,
+	0xD850, 0x8C4D, 0xD851, 0x8C4E, 0xD852, 0x8C4F, 0xD853, 0x8C50,
+	0xD854, 0x8C51, 0xD855, 0x8C52, 0xD856, 0x8C53, 0xD857, 0x8C54,
+	0xD858, 0x8C56, 0xD859, 0x8C57, 0xD85A, 0x8C58, 0xD85B, 0x8C59,
+	0xD85C, 0x8C5B, 0xD85D, 0x8C5C, 0xD85E, 0x8C5D, 0xD85F, 0x8C5E,
+	0xD860, 0x8C5F, 0xD861, 0x8C60, 0xD862, 0x8C63, 0xD863, 0x8C64,
+	0xD864, 0x8C65, 0xD865, 0x8C66, 0xD866, 0x8C67, 0xD867, 0x8C68,
+	0xD868, 0x8C69, 0xD869, 0x8C6C, 0xD86A, 0x8C6D, 0xD86B, 0x8C6E,
+	0xD86C, 0x8C6F, 0xD86D, 0x8C70, 0xD86E, 0x8C71, 0xD86F, 0x8C72,
+	0xD870, 0x8C74, 0xD871, 0x8C75, 0xD872, 0x8C76, 0xD873, 0x8C77,
+	0xD874, 0x8C7B, 0xD875, 0x8C7C, 0xD876, 0x8C7D, 0xD877, 0x8C7E,
+	0xD878, 0x8C7F, 0xD879, 0x8C80, 0xD87A, 0x8C81, 0xD87B, 0x8C83,
+	0xD87C, 0x8C84, 0xD87D, 0x8C86, 0xD87E, 0x8C87, 0xD880, 0x8C88,
+	0xD881, 0x8C8B, 0xD882, 0x8C8D, 0xD883, 0x8C8E, 0xD884, 0x8C8F,
+	0xD885, 0x8C90, 0xD886, 0x8C91, 0xD887, 0x8C92, 0xD888, 0x8C93,
+	0xD889, 0x8C95, 0xD88A, 0x8C96, 0xD88B, 0x8C97, 0xD88C, 0x8C99,
+	0xD88D, 0x8C9A, 0xD88E, 0x8C9B, 0xD88F, 0x8C9C, 0xD890, 0x8C9D,
+	0xD891, 0x8C9E, 0xD892, 0x8C9F, 0xD893, 0x8CA0, 0xD894, 0x8CA1,
+	0xD895, 0x8CA2, 0xD896, 0x8CA3, 0xD897, 0x8CA4, 0xD898, 0x8CA5,
+	0xD899, 0x8CA6, 0xD89A, 0x8CA7, 0xD89B, 0x8CA8, 0xD89C, 0x8CA9,
+	0xD89D, 0x8CAA, 0xD89E, 0x8CAB, 0xD89F, 0x8CAC, 0xD8A0, 0x8CAD,
+	0xD8A1, 0x4E8D, 0xD8A2, 0x4E0C, 0xD8A3, 0x5140, 0xD8A4, 0x4E10,
+	0xD8A5, 0x5EFF, 0xD8A6, 0x5345, 0xD8A7, 0x4E15, 0xD8A8, 0x4E98,
+	0xD8A9, 0x4E1E, 0xD8AA, 0x9B32, 0xD8AB, 0x5B6C, 0xD8AC, 0x5669,
+	0xD8AD, 0x4E28, 0xD8AE, 0x79BA, 0xD8AF, 0x4E3F, 0xD8B0, 0x5315,
+	0xD8B1, 0x4E47, 0xD8B2, 0x592D, 0xD8B3, 0x723B, 0xD8B4, 0x536E,
+	0xD8B5, 0x6C10, 0xD8B6, 0x56DF, 0xD8B7, 0x80E4, 0xD8B8, 0x9997,
+	0xD8B9, 0x6BD3, 0xD8BA, 0x777E, 0xD8BB, 0x9F17, 0xD8BC, 0x4E36,
+	0xD8BD, 0x4E9F, 0xD8BE, 0x9F10, 0xD8BF, 0x4E5C, 0xD8C0, 0x4E69,
+	0xD8C1, 0x4E93, 0xD8C2, 0x8288, 0xD8C3, 0x5B5B, 0xD8C4, 0x556C,
+	0xD8C5, 0x560F, 0xD8C6, 0x4EC4, 0xD8C7, 0x538D, 0xD8C8, 0x539D,
+	0xD8C9, 0x53A3, 0xD8CA, 0x53A5, 0xD8CB, 0x53AE, 0xD8CC, 0x9765,
+	0xD8CD, 0x8D5D, 0xD8CE, 0x531A, 0xD8CF, 0x53F5, 0xD8D0, 0x5326,
+	0xD8D1, 0x532E, 0xD8D2, 0x533E, 0xD8D3, 0x8D5C, 0xD8D4, 0x5366,
+	0xD8D5, 0x5363, 0xD8D6, 0x5202, 0xD8D7, 0x5208, 0xD8D8, 0x520E,
+	0xD8D9, 0x522D, 0xD8DA, 0x5233, 0xD8DB, 0x523F, 0xD8DC, 0x5240,
+	0xD8DD, 0x524C, 0xD8DE, 0x525E, 0xD8DF, 0x5261, 0xD8E0, 0x525C,
+	0xD8E1, 0x84AF, 0xD8E2, 0x527D, 0xD8E3, 0x5282, 0xD8E4, 0x5281,
+	0xD8E5, 0x5290, 0xD8E6, 0x5293, 0xD8E7, 0x5182, 0xD8E8, 0x7F54,
+	0xD8E9, 0x4EBB, 0xD8EA, 0x4EC3, 0xD8EB, 0x4EC9, 0xD8EC, 0x4EC2,
+	0xD8ED, 0x4EE8, 0xD8EE, 0x4EE1, 0xD8EF, 0x4EEB, 0xD8F0, 0x4EDE,
+	0xD8F1, 0x4F1B, 0xD8F2, 0x4EF3, 0xD8F3, 0x4F22, 0xD8F4, 0x4F64,
+	0xD8F5, 0x4EF5, 0xD8F6, 0x4F25, 0xD8F7, 0x4F27, 0xD8F8, 0x4F09,
+	0xD8F9, 0x4F2B, 0xD8FA, 0x4F5E, 0xD8FB, 0x4F67, 0xD8FC, 0x6538,
+	0xD8FD, 0x4F5A, 0xD8FE, 0x4F5D, 0xD940, 0x8CAE, 0xD941, 0x8CAF,
+	0xD942, 0x8CB0, 0xD943, 0x8CB1, 0xD944, 0x8CB2, 0xD945, 0x8CB3,
+	0xD946, 0x8CB4, 0xD947, 0x8CB5, 0xD948, 0x8CB6, 0xD949, 0x8CB7,
+	0xD94A, 0x8CB8, 0xD94B, 0x8CB9, 0xD94C, 0x8CBA, 0xD94D, 0x8CBB,
+	0xD94E, 0x8CBC, 0xD94F, 0x8CBD, 0xD950, 0x8CBE, 0xD951, 0x8CBF,
+	0xD952, 0x8CC0, 0xD953, 0x8CC1, 0xD954, 0x8CC2, 0xD955, 0x8CC3,
+	0xD956, 0x8CC4, 0xD957, 0x8CC5, 0xD958, 0x8CC6, 0xD959, 0x8CC7,
+	0xD95A, 0x8CC8, 0xD95B, 0x8CC9, 0xD95C, 0x8CCA, 0xD95D, 0x8CCB,
+	0xD95E, 0x8CCC, 0xD95F, 0x8CCD, 0xD960, 0x8CCE, 0xD961, 0x8CCF,
+	0xD962, 0x8CD0, 0xD963, 0x8CD1, 0xD964, 0x8CD2, 0xD965, 0x8CD3,
+	0xD966, 0x8CD4, 0xD967, 0x8CD5, 0xD968, 0x8CD6, 0xD969, 0x8CD7,
+	0xD96A, 0x8CD8, 0xD96B, 0x8CD9, 0xD96C, 0x8CDA, 0xD96D, 0x8CDB,
+	0xD96E, 0x8CDC, 0xD96F, 0x8CDD, 0xD970, 0x8CDE, 0xD971, 0x8CDF,
+	0xD972, 0x8CE0, 0xD973, 0x8CE1, 0xD974, 0x8CE2, 0xD975, 0x8CE3,
+	0xD976, 0x8CE4, 0xD977, 0x8CE5, 0xD978, 0x8CE6, 0xD979, 0x8CE7,
+	0xD97A, 0x8CE8, 0xD97B, 0x8CE9, 0xD97C, 0x8CEA, 0xD97D, 0x8CEB,
+	0xD97E, 0x8CEC, 0xD980, 0x8CED, 0xD981, 0x8CEE, 0xD982, 0x8CEF,
+	0xD983, 0x8CF0, 0xD984, 0x8CF1, 0xD985, 0x8CF2, 0xD986, 0x8CF3,
+	0xD987, 0x8CF4, 0xD988, 0x8CF5, 0xD989, 0x8CF6, 0xD98A, 0x8CF7,
+	0xD98B, 0x8CF8, 0xD98C, 0x8CF9, 0xD98D, 0x8CFA, 0xD98E, 0x8CFB,
+	0xD98F, 0x8CFC, 0xD990, 0x8CFD, 0xD991, 0x8CFE, 0xD992, 0x8CFF,
+	0xD993, 0x8D00, 0xD994, 0x8D01, 0xD995, 0x8D02, 0xD996, 0x8D03,
+	0xD997, 0x8D04, 0xD998, 0x8D05, 0xD999, 0x8D06, 0xD99A, 0x8D07,
+	0xD99B, 0x8D08, 0xD99C, 0x8D09, 0xD99D, 0x8D0A, 0xD99E, 0x8D0B,
+	0xD99F, 0x8D0C, 0xD9A0, 0x8D0D, 0xD9A1, 0x4F5F, 0xD9A2, 0x4F57,
+	0xD9A3, 0x4F32, 0xD9A4, 0x4F3D, 0xD9A5, 0x4F76, 0xD9A6, 0x4F74,
+	0xD9A7, 0x4F91, 0xD9A8, 0x4F89, 0xD9A9, 0x4F83, 0xD9AA, 0x4F8F,
+	0xD9AB, 0x4F7E, 0xD9AC, 0x4F7B, 0xD9AD, 0x4FAA, 0xD9AE, 0x4F7C,
+	0xD9AF, 0x4FAC, 0xD9B0, 0x4F94, 0xD9B1, 0x4FE6, 0xD9B2, 0x4FE8,
+	0xD9B3, 0x4FEA, 0xD9B4, 0x4FC5, 0xD9B5, 0x4FDA, 0xD9B6, 0x4FE3,
+	0xD9B7, 0x4FDC, 0xD9B8, 0x4FD1, 0xD9B9, 0x4FDF, 0xD9BA, 0x4FF8,
+	0xD9BB, 0x5029, 0xD9BC, 0x504C, 0xD9BD, 0x4FF3, 0xD9BE, 0x502C,
+	0xD9BF, 0x500F, 0xD9C0, 0x502E, 0xD9C1, 0x502D, 0xD9C2, 0x4FFE,
+	0xD9C3, 0x501C, 0xD9C4, 0x500C, 0xD9C5, 0x5025, 0xD9C6, 0x5028,
+	0xD9C7, 0x507E, 0xD9C8, 0x5043, 0xD9C9, 0x5055, 0xD9CA, 0x5048,
+	0xD9CB, 0x504E, 0xD9CC, 0x506C, 0xD9CD, 0x507B, 0xD9CE, 0x50A5,
+	0xD9CF, 0x50A7, 0xD9D0, 0x50A9, 0xD9D1, 0x50BA, 0xD9D2, 0x50D6,
+	0xD9D3, 0x5106, 0xD9D4, 0x50ED, 0xD9D5, 0x50EC, 0xD9D6, 0x50E6,
+	0xD9D7, 0x50EE, 0xD9D8, 0x5107, 0xD9D9, 0x510B, 0xD9DA, 0x4EDD,
+	0xD9DB, 0x6C3D, 0xD9DC, 0x4F58, 0xD9DD, 0x4F65, 0xD9DE, 0x4FCE,
+	0xD9DF, 0x9FA0, 0xD9E0, 0x6C46, 0xD9E1, 0x7C74, 0xD9E2, 0x516E,
+	0xD9E3, 0x5DFD, 0xD9E4, 0x9EC9, 0xD9E5, 0x9998, 0xD9E6, 0x5181,
+	0xD9E7, 0x5914, 0xD9E8, 0x52F9, 0xD9E9, 0x530D, 0xD9EA, 0x8A07,
+	0xD9EB, 0x5310, 0xD9EC, 0x51EB, 0xD9ED, 0x5919, 0xD9EE, 0x5155,
+	0xD9EF, 0x4EA0, 0xD9F0, 0x5156, 0xD9F1, 0x4EB3, 0xD9F2, 0x886E,
+	0xD9F3, 0x88A4, 0xD9F4, 0x4EB5, 0xD9F5, 0x8114, 0xD9F6, 0x88D2,
+	0xD9F7, 0x7980, 0xD9F8, 0x5B34, 0xD9F9, 0x8803, 0xD9FA, 0x7FB8,
+	0xD9FB, 0x51AB, 0xD9FC, 0x51B1, 0xD9FD, 0x51BD, 0xD9FE, 0x51BC,
+	0xDA40, 0x8D0E, 0xDA41, 0x8D0F, 0xDA42, 0x8D10, 0xDA43, 0x8D11,
+	0xDA44, 0x8D12, 0xDA45, 0x8D13, 0xDA46, 0x8D14, 0xDA47, 0x8D15,
+	0xDA48, 0x8D16, 0xDA49, 0x8D17, 0xDA4A, 0x8D18, 0xDA4B, 0x8D19,
+	0xDA4C, 0x8D1A, 0xDA4D, 0x8D1B, 0xDA4E, 0x8D1C, 0xDA4F, 0x8D20,
+	0xDA50, 0x8D51, 0xDA51, 0x8D52, 0xDA52, 0x8D57, 0xDA53, 0x8D5F,
+	0xDA54, 0x8D65, 0xDA55, 0x8D68, 0xDA56, 0x8D69, 0xDA57, 0x8D6A,
+	0xDA58, 0x8D6C, 0xDA59, 0x8D6E, 0xDA5A, 0x8D6F, 0xDA5B, 0x8D71,
+	0xDA5C, 0x8D72, 0xDA5D, 0x8D78, 0xDA5E, 0x8D79, 0xDA5F, 0x8D7A,
+	0xDA60, 0x8D7B, 0xDA61, 0x8D7C, 0xDA62, 0x8D7D, 0xDA63, 0x8D7E,
+	0xDA64, 0x8D7F, 0xDA65, 0x8D80, 0xDA66, 0x8D82, 0xDA67, 0x8D83,
+	0xDA68, 0x8D86, 0xDA69, 0x8D87, 0xDA6A, 0x8D88, 0xDA6B, 0x8D89,
+	0xDA6C, 0x8D8C, 0xDA6D, 0x8D8D, 0xDA6E, 0x8D8E, 0xDA6F, 0x8D8F,
+	0xDA70, 0x8D90, 0xDA71, 0x8D92, 0xDA72, 0x8D93, 0xDA73, 0x8D95,
+	0xDA74, 0x8D96, 0xDA75, 0x8D97, 0xDA76, 0x8D98, 0xDA77, 0x8D99,
+	0xDA78, 0x8D9A, 0xDA79, 0x8D9B, 0xDA7A, 0x8D9C, 0xDA7B, 0x8D9D,
+	0xDA7C, 0x8D9E, 0xDA7D, 0x8DA0, 0xDA7E, 0x8DA1, 0xDA80, 0x8DA2,
+	0xDA81, 0x8DA4, 0xDA82, 0x8DA5, 0xDA83, 0x8DA6, 0xDA84, 0x8DA7,
+	0xDA85, 0x8DA8, 0xDA86, 0x8DA9, 0xDA87, 0x8DAA, 0xDA88, 0x8DAB,
+	0xDA89, 0x8DAC, 0xDA8A, 0x8DAD, 0xDA8B, 0x8DAE, 0xDA8C, 0x8DAF,
+	0xDA8D, 0x8DB0, 0xDA8E, 0x8DB2, 0xDA8F, 0x8DB6, 0xDA90, 0x8DB7,
+	0xDA91, 0x8DB9, 0xDA92, 0x8DBB, 0xDA93, 0x8DBD, 0xDA94, 0x8DC0,
+	0xDA95, 0x8DC1, 0xDA96, 0x8DC2, 0xDA97, 0x8DC5, 0xDA98, 0x8DC7,
+	0xDA99, 0x8DC8, 0xDA9A, 0x8DC9, 0xDA9B, 0x8DCA, 0xDA9C, 0x8DCD,
+	0xDA9D, 0x8DD0, 0xDA9E, 0x8DD2, 0xDA9F, 0x8DD3, 0xDAA0, 0x8DD4,
+	0xDAA1, 0x51C7, 0xDAA2, 0x5196, 0xDAA3, 0x51A2, 0xDAA4, 0x51A5,
+	0xDAA5, 0x8BA0, 0xDAA6, 0x8BA6, 0xDAA7, 0x8BA7, 0xDAA8, 0x8BAA,
+	0xDAA9, 0x8BB4, 0xDAAA, 0x8BB5, 0xDAAB, 0x8BB7, 0xDAAC, 0x8BC2,
+	0xDAAD, 0x8BC3, 0xDAAE, 0x8BCB, 0xDAAF, 0x8BCF, 0xDAB0, 0x8BCE,
+	0xDAB1, 0x8BD2, 0xDAB2, 0x8BD3, 0xDAB3, 0x8BD4, 0xDAB4, 0x8BD6,
+	0xDAB5, 0x8BD8, 0xDAB6, 0x8BD9, 0xDAB7, 0x8BDC, 0xDAB8, 0x8BDF,
+	0xDAB9, 0x8BE0, 0xDABA, 0x8BE4, 0xDABB, 0x8BE8, 0xDABC, 0x8BE9,
+	0xDABD, 0x8BEE, 0xDABE, 0x8BF0, 0xDABF, 0x8BF3, 0xDAC0, 0x8BF6,
+	0xDAC1, 0x8BF9, 0xDAC2, 0x8BFC, 0xDAC3, 0x8BFF, 0xDAC4, 0x8C00,
+	0xDAC5, 0x8C02, 0xDAC6, 0x8C04, 0xDAC7, 0x8C07, 0xDAC8, 0x8C0C,
+	0xDAC9, 0x8C0F, 0xDACA, 0x8C11, 0xDACB, 0x8C12, 0xDACC, 0x8C14,
+	0xDACD, 0x8C15, 0xDACE, 0x8C16, 0xDACF, 0x8C19, 0xDAD0, 0x8C1B,
+	0xDAD1, 0x8C18, 0xDAD2, 0x8C1D, 0xDAD3, 0x8C1F, 0xDAD4, 0x8C20,
+	0xDAD5, 0x8C21, 0xDAD6, 0x8C25, 0xDAD7, 0x8C27, 0xDAD8, 0x8C2A,
+	0xDAD9, 0x8C2B, 0xDADA, 0x8C2E, 0xDADB, 0x8C2F, 0xDADC, 0x8C32,
+	0xDADD, 0x8C33, 0xDADE, 0x8C35, 0xDADF, 0x8C36, 0xDAE0, 0x5369,
+	0xDAE1, 0x537A, 0xDAE2, 0x961D, 0xDAE3, 0x9622, 0xDAE4, 0x9621,
+	0xDAE5, 0x9631, 0xDAE6, 0x962A, 0xDAE7, 0x963D, 0xDAE8, 0x963C,
+	0xDAE9, 0x9642, 0xDAEA, 0x9649, 0xDAEB, 0x9654, 0xDAEC, 0x965F,
+	0xDAED, 0x9667, 0xDAEE, 0x966C, 0xDAEF, 0x9672, 0xDAF0, 0x9674,
+	0xDAF1, 0x9688, 0xDAF2, 0x968D, 0xDAF3, 0x9697, 0xDAF4, 0x96B0,
+	0xDAF5, 0x9097, 0xDAF6, 0x909B, 0xDAF7, 0x909D, 0xDAF8, 0x9099,
+	0xDAF9, 0x90AC, 0xDAFA, 0x90A1, 0xDAFB, 0x90B4, 0xDAFC, 0x90B3,
+	0xDAFD, 0x90B6, 0xDAFE, 0x90BA, 0xDB40, 0x8DD5, 0xDB41, 0x8DD8,
+	0xDB42, 0x8DD9, 0xDB43, 0x8DDC, 0xDB44, 0x8DE0, 0xDB45, 0x8DE1,
+	0xDB46, 0x8DE2, 0xDB47, 0x8DE5, 0xDB48, 0x8DE6, 0xDB49, 0x8DE7,
+	0xDB4A, 0x8DE9, 0xDB4B, 0x8DED, 0xDB4C, 0x8DEE, 0xDB4D, 0x8DF0,
+	0xDB4E, 0x8DF1, 0xDB4F, 0x8DF2, 0xDB50, 0x8DF4, 0xDB51, 0x8DF6,
+	0xDB52, 0x8DFC, 0xDB53, 0x8DFE, 0xDB54, 0x8DFF, 0xDB55, 0x8E00,
+	0xDB56, 0x8E01, 0xDB57, 0x8E02, 0xDB58, 0x8E03, 0xDB59, 0x8E04,
+	0xDB5A, 0x8E06, 0xDB5B, 0x8E07, 0xDB5C, 0x8E08, 0xDB5D, 0x8E0B,
+	0xDB5E, 0x8E0D, 0xDB5F, 0x8E0E, 0xDB60, 0x8E10, 0xDB61, 0x8E11,
+	0xDB62, 0x8E12, 0xDB63, 0x8E13, 0xDB64, 0x8E15, 0xDB65, 0x8E16,
+	0xDB66, 0x8E17, 0xDB67, 0x8E18, 0xDB68, 0x8E19, 0xDB69, 0x8E1A,
+	0xDB6A, 0x8E1B, 0xDB6B, 0x8E1C, 0xDB6C, 0x8E20, 0xDB6D, 0x8E21,
+	0xDB6E, 0x8E24, 0xDB6F, 0x8E25, 0xDB70, 0x8E26, 0xDB71, 0x8E27,
+	0xDB72, 0x8E28, 0xDB73, 0x8E2B, 0xDB74, 0x8E2D, 0xDB75, 0x8E30,
+	0xDB76, 0x8E32, 0xDB77, 0x8E33, 0xDB78, 0x8E34, 0xDB79, 0x8E36,
+	0xDB7A, 0x8E37, 0xDB7B, 0x8E38, 0xDB7C, 0x8E3B, 0xDB7D, 0x8E3C,
+	0xDB7E, 0x8E3E, 0xDB80, 0x8E3F, 0xDB81, 0x8E43, 0xDB82, 0x8E45,
+	0xDB83, 0x8E46, 0xDB84, 0x8E4C, 0xDB85, 0x8E4D, 0xDB86, 0x8E4E,
+	0xDB87, 0x8E4F, 0xDB88, 0x8E50, 0xDB89, 0x8E53, 0xDB8A, 0x8E54,
+	0xDB8B, 0x8E55, 0xDB8C, 0x8E56, 0xDB8D, 0x8E57, 0xDB8E, 0x8E58,
+	0xDB8F, 0x8E5A, 0xDB90, 0x8E5B, 0xDB91, 0x8E5C, 0xDB92, 0x8E5D,
+	0xDB93, 0x8E5E, 0xDB94, 0x8E5F, 0xDB95, 0x8E60, 0xDB96, 0x8E61,
+	0xDB97, 0x8E62, 0xDB98, 0x8E63, 0xDB99, 0x8E64, 0xDB9A, 0x8E65,
+	0xDB9B, 0x8E67, 0xDB9C, 0x8E68, 0xDB9D, 0x8E6A, 0xDB9E, 0x8E6B,
+	0xDB9F, 0x8E6E, 0xDBA0, 0x8E71, 0xDBA1, 0x90B8, 0xDBA2, 0x90B0,
+	0xDBA3, 0x90CF, 0xDBA4, 0x90C5, 0xDBA5, 0x90BE, 0xDBA6, 0x90D0,
+	0xDBA7, 0x90C4, 0xDBA8, 0x90C7, 0xDBA9, 0x90D3, 0xDBAA, 0x90E6,
+	0xDBAB, 0x90E2, 0xDBAC, 0x90DC, 0xDBAD, 0x90D7, 0xDBAE, 0x90DB,
+	0xDBAF, 0x90EB, 0xDBB0, 0x90EF, 0xDBB1, 0x90FE, 0xDBB2, 0x9104,
+	0xDBB3, 0x9122, 0xDBB4, 0x911E, 0xDBB5, 0x9123, 0xDBB6, 0x9131,
+	0xDBB7, 0x912F, 0xDBB8, 0x9139, 0xDBB9, 0x9143, 0xDBBA, 0x9146,
+	0xDBBB, 0x520D, 0xDBBC, 0x5942, 0xDBBD, 0x52A2, 0xDBBE, 0x52AC,
+	0xDBBF, 0x52AD, 0xDBC0, 0x52BE, 0xDBC1, 0x54FF, 0xDBC2, 0x52D0,
+	0xDBC3, 0x52D6, 0xDBC4, 0x52F0, 0xDBC5, 0x53DF, 0xDBC6, 0x71EE,
+	0xDBC7, 0x77CD, 0xDBC8, 0x5EF4, 0xDBC9, 0x51F5, 0xDBCA, 0x51FC,
+	0xDBCB, 0x9B2F, 0xDBCC, 0x53B6, 0xDBCD, 0x5F01, 0xDBCE, 0x755A,
+	0xDBCF, 0x5DEF, 0xDBD0, 0x574C, 0xDBD1, 0x57A9, 0xDBD2, 0x57A1,
+	0xDBD3, 0x587E, 0xDBD4, 0x58BC, 0xDBD5, 0x58C5, 0xDBD6, 0x58D1,
+	0xDBD7, 0x5729, 0xDBD8, 0x572C, 0xDBD9, 0x572A, 0xDBDA, 0x5733,
+	0xDBDB, 0x5739, 0xDBDC, 0x572E, 0xDBDD, 0x572F, 0xDBDE, 0x575C,
+	0xDBDF, 0x573B, 0xDBE0, 0x5742, 0xDBE1, 0x5769, 0xDBE2, 0x5785,
+	0xDBE3, 0x576B, 0xDBE4, 0x5786, 0xDBE5, 0x577C, 0xDBE6, 0x577B,
+	0xDBE7, 0x5768, 0xDBE8, 0x576D, 0xDBE9, 0x5776, 0xDBEA, 0x5773,
+	0xDBEB, 0x57AD, 0xDBEC, 0x57A4, 0xDBED, 0x578C, 0xDBEE, 0x57B2,
+	0xDBEF, 0x57CF, 0xDBF0, 0x57A7, 0xDBF1, 0x57B4, 0xDBF2, 0x5793,
+	0xDBF3, 0x57A0, 0xDBF4, 0x57D5, 0xDBF5, 0x57D8, 0xDBF6, 0x57DA,
+	0xDBF7, 0x57D9, 0xDBF8, 0x57D2, 0xDBF9, 0x57B8, 0xDBFA, 0x57F4,
+	0xDBFB, 0x57EF, 0xDBFC, 0x57F8, 0xDBFD, 0x57E4, 0xDBFE, 0x57DD,
+	0xDC40, 0x8E73, 0xDC41, 0x8E75, 0xDC42, 0x8E77, 0xDC43, 0x8E78,
+	0xDC44, 0x8E79, 0xDC45, 0x8E7A, 0xDC46, 0x8E7B, 0xDC47, 0x8E7D,
+	0xDC48, 0x8E7E, 0xDC49, 0x8E80, 0xDC4A, 0x8E82, 0xDC4B, 0x8E83,
+	0xDC4C, 0x8E84, 0xDC4D, 0x8E86, 0xDC4E, 0x8E88, 0xDC4F, 0x8E89,
+	0xDC50, 0x8E8A, 0xDC51, 0x8E8B, 0xDC52, 0x8E8C, 0xDC53, 0x8E8D,
+	0xDC54, 0x8E8E, 0xDC55, 0x8E91, 0xDC56, 0x8E92, 0xDC57, 0x8E93,
+	0xDC58, 0x8E95, 0xDC59, 0x8E96, 0xDC5A, 0x8E97, 0xDC5B, 0x8E98,
+	0xDC5C, 0x8E99, 0xDC5D, 0x8E9A, 0xDC5E, 0x8E9B, 0xDC5F, 0x8E9D,
+	0xDC60, 0x8E9F, 0xDC61, 0x8EA0, 0xDC62, 0x8EA1, 0xDC63, 0x8EA2,
+	0xDC64, 0x8EA3, 0xDC65, 0x8EA4, 0xDC66, 0x8EA5, 0xDC67, 0x8EA6,
+	0xDC68, 0x8EA7, 0xDC69, 0x8EA8, 0xDC6A, 0x8EA9, 0xDC6B, 0x8EAA,
+	0xDC6C, 0x8EAD, 0xDC6D, 0x8EAE, 0xDC6E, 0x8EB0, 0xDC6F, 0x8EB1,
+	0xDC70, 0x8EB3, 0xDC71, 0x8EB4, 0xDC72, 0x8EB5, 0xDC73, 0x8EB6,
+	0xDC74, 0x8EB7, 0xDC75, 0x8EB8, 0xDC76, 0x8EB9, 0xDC77, 0x8EBB,
+	0xDC78, 0x8EBC, 0xDC79, 0x8EBD, 0xDC7A, 0x8EBE, 0xDC7B, 0x8EBF,
+	0xDC7C, 0x8EC0, 0xDC7D, 0x8EC1, 0xDC7E, 0x8EC2, 0xDC80, 0x8EC3,
+	0xDC81, 0x8EC4, 0xDC82, 0x8EC5, 0xDC83, 0x8EC6, 0xDC84, 0x8EC7,
+	0xDC85, 0x8EC8, 0xDC86, 0x8EC9, 0xDC87, 0x8ECA, 0xDC88, 0x8ECB,
+	0xDC89, 0x8ECC, 0xDC8A, 0x8ECD, 0xDC8B, 0x8ECF, 0xDC8C, 0x8ED0,
+	0xDC8D, 0x8ED1, 0xDC8E, 0x8ED2, 0xDC8F, 0x8ED3, 0xDC90, 0x8ED4,
+	0xDC91, 0x8ED5, 0xDC92, 0x8ED6, 0xDC93, 0x8ED7, 0xDC94, 0x8ED8,
+	0xDC95, 0x8ED9, 0xDC96, 0x8EDA, 0xDC97, 0x8EDB, 0xDC98, 0x8EDC,
+	0xDC99, 0x8EDD, 0xDC9A, 0x8EDE, 0xDC9B, 0x8EDF, 0xDC9C, 0x8EE0,
+	0xDC9D, 0x8EE1, 0xDC9E, 0x8EE2, 0xDC9F, 0x8EE3, 0xDCA0, 0x8EE4,
+	0xDCA1, 0x580B, 0xDCA2, 0x580D, 0xDCA3, 0x57FD, 0xDCA4, 0x57ED,
+	0xDCA5, 0x5800, 0xDCA6, 0x581E, 0xDCA7, 0x5819, 0xDCA8, 0x5844,
+	0xDCA9, 0x5820, 0xDCAA, 0x5865, 0xDCAB, 0x586C, 0xDCAC, 0x5881,
+	0xDCAD, 0x5889, 0xDCAE, 0x589A, 0xDCAF, 0x5880, 0xDCB0, 0x99A8,
+	0xDCB1, 0x9F19, 0xDCB2, 0x61FF, 0xDCB3, 0x8279, 0xDCB4, 0x827D,
+	0xDCB5, 0x827F, 0xDCB6, 0x828F, 0xDCB7, 0x828A, 0xDCB8, 0x82A8,
+	0xDCB9, 0x8284, 0xDCBA, 0x828E, 0xDCBB, 0x8291, 0xDCBC, 0x8297,
+	0xDCBD, 0x8299, 0xDCBE, 0x82AB, 0xDCBF, 0x82B8, 0xDCC0, 0x82BE,
+	0xDCC1, 0x82B0, 0xDCC2, 0x82C8, 0xDCC3, 0x82CA, 0xDCC4, 0x82E3,
+	0xDCC5, 0x8298, 0xDCC6, 0x82B7, 0xDCC7, 0x82AE, 0xDCC8, 0x82CB,
+	0xDCC9, 0x82CC, 0xDCCA, 0x82C1, 0xDCCB, 0x82A9, 0xDCCC, 0x82B4,
+	0xDCCD, 0x82A1, 0xDCCE, 0x82AA, 0xDCCF, 0x829F, 0xDCD0, 0x82C4,
+	0xDCD1, 0x82CE, 0xDCD2, 0x82A4, 0xDCD3, 0x82E1, 0xDCD4, 0x8309,
+	0xDCD5, 0x82F7, 0xDCD6, 0x82E4, 0xDCD7, 0x830F, 0xDCD8, 0x8307,
+	0xDCD9, 0x82DC, 0xDCDA, 0x82F4, 0xDCDB, 0x82D2, 0xDCDC, 0x82D8,
+	0xDCDD, 0x830C, 0xDCDE, 0x82FB, 0xDCDF, 0x82D3, 0xDCE0, 0x8311,
+	0xDCE1, 0x831A, 0xDCE2, 0x8306, 0xDCE3, 0x8314, 0xDCE4, 0x8315,
+	0xDCE5, 0x82E0, 0xDCE6, 0x82D5, 0xDCE7, 0x831C, 0xDCE8, 0x8351,
+	0xDCE9, 0x835B, 0xDCEA, 0x835C, 0xDCEB, 0x8308, 0xDCEC, 0x8392,
+	0xDCED, 0x833C, 0xDCEE, 0x8334, 0xDCEF, 0x8331, 0xDCF0, 0x839B,
+	0xDCF1, 0x835E, 0xDCF2, 0x832F, 0xDCF3, 0x834F, 0xDCF4, 0x8347,
+	0xDCF5, 0x8343, 0xDCF6, 0x835F, 0xDCF7, 0x8340, 0xDCF8, 0x8317,
+	0xDCF9, 0x8360, 0xDCFA, 0x832D, 0xDCFB, 0x833A, 0xDCFC, 0x8333,
+	0xDCFD, 0x8366, 0xDCFE, 0x8365, 0xDD40, 0x8EE5, 0xDD41, 0x8EE6,
+	0xDD42, 0x8EE7, 0xDD43, 0x8EE8, 0xDD44, 0x8EE9, 0xDD45, 0x8EEA,
+	0xDD46, 0x8EEB, 0xDD47, 0x8EEC, 0xDD48, 0x8EED, 0xDD49, 0x8EEE,
+	0xDD4A, 0x8EEF, 0xDD4B, 0x8EF0, 0xDD4C, 0x8EF1, 0xDD4D, 0x8EF2,
+	0xDD4E, 0x8EF3, 0xDD4F, 0x8EF4, 0xDD50, 0x8EF5, 0xDD51, 0x8EF6,
+	0xDD52, 0x8EF7, 0xDD53, 0x8EF8, 0xDD54, 0x8EF9, 0xDD55, 0x8EFA,
+	0xDD56, 0x8EFB, 0xDD57, 0x8EFC, 0xDD58, 0x8EFD, 0xDD59, 0x8EFE,
+	0xDD5A, 0x8EFF, 0xDD5B, 0x8F00, 0xDD5C, 0x8F01, 0xDD5D, 0x8F02,
+	0xDD5E, 0x8F03, 0xDD5F, 0x8F04, 0xDD60, 0x8F05, 0xDD61, 0x8F06,
+	0xDD62, 0x8F07, 0xDD63, 0x8F08, 0xDD64, 0x8F09, 0xDD65, 0x8F0A,
+	0xDD66, 0x8F0B, 0xDD67, 0x8F0C, 0xDD68, 0x8F0D, 0xDD69, 0x8F0E,
+	0xDD6A, 0x8F0F, 0xDD6B, 0x8F10, 0xDD6C, 0x8F11, 0xDD6D, 0x8F12,
+	0xDD6E, 0x8F13, 0xDD6F, 0x8F14, 0xDD70, 0x8F15, 0xDD71, 0x8F16,
+	0xDD72, 0x8F17, 0xDD73, 0x8F18, 0xDD74, 0x8F19, 0xDD75, 0x8F1A,
+	0xDD76, 0x8F1B, 0xDD77, 0x8F1C, 0xDD78, 0x8F1D, 0xDD79, 0x8F1E,
+	0xDD7A, 0x8F1F, 0xDD7B, 0x8F20, 0xDD7C, 0x8F21, 0xDD7D, 0x8F22,
+	0xDD7E, 0x8F23, 0xDD80, 0x8F24, 0xDD81, 0x8F25, 0xDD82, 0x8F26,
+	0xDD83, 0x8F27, 0xDD84, 0x8F28, 0xDD85, 0x8F29, 0xDD86, 0x8F2A,
+	0xDD87, 0x8F2B, 0xDD88, 0x8F2C, 0xDD89, 0x8F2D, 0xDD8A, 0x8F2E,
+	0xDD8B, 0x8F2F, 0xDD8C, 0x8F30, 0xDD8D, 0x8F31, 0xDD8E, 0x8F32,
+	0xDD8F, 0x8F33, 0xDD90, 0x8F34, 0xDD91, 0x8F35, 0xDD92, 0x8F36,
+	0xDD93, 0x8F37, 0xDD94, 0x8F38, 0xDD95, 0x8F39, 0xDD96, 0x8F3A,
+	0xDD97, 0x8F3B, 0xDD98, 0x8F3C, 0xDD99, 0x8F3D, 0xDD9A, 0x8F3E,
+	0xDD9B, 0x8F3F, 0xDD9C, 0x8F40, 0xDD9D, 0x8F41, 0xDD9E, 0x8F42,
+	0xDD9F, 0x8F43, 0xDDA0, 0x8F44, 0xDDA1, 0x8368, 0xDDA2, 0x831B,
+	0xDDA3, 0x8369, 0xDDA4, 0x836C, 0xDDA5, 0x836A, 0xDDA6, 0x836D,
+	0xDDA7, 0x836E, 0xDDA8, 0x83B0, 0xDDA9, 0x8378, 0xDDAA, 0x83B3,
+	0xDDAB, 0x83B4, 0xDDAC, 0x83A0, 0xDDAD, 0x83AA, 0xDDAE, 0x8393,
+	0xDDAF, 0x839C, 0xDDB0, 0x8385, 0xDDB1, 0x837C, 0xDDB2, 0x83B6,
+	0xDDB3, 0x83A9, 0xDDB4, 0x837D, 0xDDB5, 0x83B8, 0xDDB6, 0x837B,
+	0xDDB7, 0x8398, 0xDDB8, 0x839E, 0xDDB9, 0x83A8, 0xDDBA, 0x83BA,
+	0xDDBB, 0x83BC, 0xDDBC, 0x83C1, 0xDDBD, 0x8401, 0xDDBE, 0x83E5,
+	0xDDBF, 0x83D8, 0xDDC0, 0x5807, 0xDDC1, 0x8418, 0xDDC2, 0x840B,
+	0xDDC3, 0x83DD, 0xDDC4, 0x83FD, 0xDDC5, 0x83D6, 0xDDC6, 0x841C,
+	0xDDC7, 0x8438, 0xDDC8, 0x8411, 0xDDC9, 0x8406, 0xDDCA, 0x83D4,
+	0xDDCB, 0x83DF, 0xDDCC, 0x840F, 0xDDCD, 0x8403, 0xDDCE, 0x83F8,
+	0xDDCF, 0x83F9, 0xDDD0, 0x83EA, 0xDDD1, 0x83C5, 0xDDD2, 0x83C0,
+	0xDDD3, 0x8426, 0xDDD4, 0x83F0, 0xDDD5, 0x83E1, 0xDDD6, 0x845C,
+	0xDDD7, 0x8451, 0xDDD8, 0x845A, 0xDDD9, 0x8459, 0xDDDA, 0x8473,
+	0xDDDB, 0x8487, 0xDDDC, 0x8488, 0xDDDD, 0x847A, 0xDDDE, 0x8489,
+	0xDDDF, 0x8478, 0xDDE0, 0x843C, 0xDDE1, 0x8446, 0xDDE2, 0x8469,
+	0xDDE3, 0x8476, 0xDDE4, 0x848C, 0xDDE5, 0x848E, 0xDDE6, 0x8431,
+	0xDDE7, 0x846D, 0xDDE8, 0x84C1, 0xDDE9, 0x84CD, 0xDDEA, 0x84D0,
+	0xDDEB, 0x84E6, 0xDDEC, 0x84BD, 0xDDED, 0x84D3, 0xDDEE, 0x84CA,
+	0xDDEF, 0x84BF, 0xDDF0, 0x84BA, 0xDDF1, 0x84E0, 0xDDF2, 0x84A1,
+	0xDDF3, 0x84B9, 0xDDF4, 0x84B4, 0xDDF5, 0x8497, 0xDDF6, 0x84E5,
+	0xDDF7, 0x84E3, 0xDDF8, 0x850C, 0xDDF9, 0x750D, 0xDDFA, 0x8538,
+	0xDDFB, 0x84F0, 0xDDFC, 0x8539, 0xDDFD, 0x851F, 0xDDFE, 0x853A,
+	0xDE40, 0x8F45, 0xDE41, 0x8F46, 0xDE42, 0x8F47, 0xDE43, 0x8F48,
+	0xDE44, 0x8F49, 0xDE45, 0x8F4A, 0xDE46, 0x8F4B, 0xDE47, 0x8F4C,
+	0xDE48, 0x8F4D, 0xDE49, 0x8F4E, 0xDE4A, 0x8F4F, 0xDE4B, 0x8F50,
+	0xDE4C, 0x8F51, 0xDE4D, 0x8F52, 0xDE4E, 0x8F53, 0xDE4F, 0x8F54,
+	0xDE50, 0x8F55, 0xDE51, 0x8F56, 0xDE52, 0x8F57, 0xDE53, 0x8F58,
+	0xDE54, 0x8F59, 0xDE55, 0x8F5A, 0xDE56, 0x8F5B, 0xDE57, 0x8F5C,
+	0xDE58, 0x8F5D, 0xDE59, 0x8F5E, 0xDE5A, 0x8F5F, 0xDE5B, 0x8F60,
+	0xDE5C, 0x8F61, 0xDE5D, 0x8F62, 0xDE5E, 0x8F63, 0xDE5F, 0x8F64,
+	0xDE60, 0x8F65, 0xDE61, 0x8F6A, 0xDE62, 0x8F80, 0xDE63, 0x8F8C,
+	0xDE64, 0x8F92, 0xDE65, 0x8F9D, 0xDE66, 0x8FA0, 0xDE67, 0x8FA1,
+	0xDE68, 0x8FA2, 0xDE69, 0x8FA4, 0xDE6A, 0x8FA5, 0xDE6B, 0x8FA6,
+	0xDE6C, 0x8FA7, 0xDE6D, 0x8FAA, 0xDE6E, 0x8FAC, 0xDE6F, 0x8FAD,
+	0xDE70, 0x8FAE, 0xDE71, 0x8FAF, 0xDE72, 0x8FB2, 0xDE73, 0x8FB3,
+	0xDE74, 0x8FB4, 0xDE75, 0x8FB5, 0xDE76, 0x8FB7, 0xDE77, 0x8FB8,
+	0xDE78, 0x8FBA, 0xDE79, 0x8FBB, 0xDE7A, 0x8FBC, 0xDE7B, 0x8FBF,
+	0xDE7C, 0x8FC0, 0xDE7D, 0x8FC3, 0xDE7E, 0x8FC6, 0xDE80, 0x8FC9,
+	0xDE81, 0x8FCA, 0xDE82, 0x8FCB, 0xDE83, 0x8FCC, 0xDE84, 0x8FCD,
+	0xDE85, 0x8FCF, 0xDE86, 0x8FD2, 0xDE87, 0x8FD6, 0xDE88, 0x8FD7,
+	0xDE89, 0x8FDA, 0xDE8A, 0x8FE0, 0xDE8B, 0x8FE1, 0xDE8C, 0x8FE3,
+	0xDE8D, 0x8FE7, 0xDE8E, 0x8FEC, 0xDE8F, 0x8FEF, 0xDE90, 0x8FF1,
+	0xDE91, 0x8FF2, 0xDE92, 0x8FF4, 0xDE93, 0x8FF5, 0xDE94, 0x8FF6,
+	0xDE95, 0x8FFA, 0xDE96, 0x8FFB, 0xDE97, 0x8FFC, 0xDE98, 0x8FFE,
+	0xDE99, 0x8FFF, 0xDE9A, 0x9007, 0xDE9B, 0x9008, 0xDE9C, 0x900C,
+	0xDE9D, 0x900E, 0xDE9E, 0x9013, 0xDE9F, 0x9015, 0xDEA0, 0x9018,
+	0xDEA1, 0x8556, 0xDEA2, 0x853B, 0xDEA3, 0x84FF, 0xDEA4, 0x84FC,
+	0xDEA5, 0x8559, 0xDEA6, 0x8548, 0xDEA7, 0x8568, 0xDEA8, 0x8564,
+	0xDEA9, 0x855E, 0xDEAA, 0x857A, 0xDEAB, 0x77A2, 0xDEAC, 0x8543,
+	0xDEAD, 0x8572, 0xDEAE, 0x857B, 0xDEAF, 0x85A4, 0xDEB0, 0x85A8,
+	0xDEB1, 0x8587, 0xDEB2, 0x858F, 0xDEB3, 0x8579, 0xDEB4, 0x85AE,
+	0xDEB5, 0x859C, 0xDEB6, 0x8585, 0xDEB7, 0x85B9, 0xDEB8, 0x85B7,
+	0xDEB9, 0x85B0, 0xDEBA, 0x85D3, 0xDEBB, 0x85C1, 0xDEBC, 0x85DC,
+	0xDEBD, 0x85FF, 0xDEBE, 0x8627, 0xDEBF, 0x8605, 0xDEC0, 0x8629,
+	0xDEC1, 0x8616, 0xDEC2, 0x863C, 0xDEC3, 0x5EFE, 0xDEC4, 0x5F08,
+	0xDEC5, 0x593C, 0xDEC6, 0x5941, 0xDEC7, 0x8037, 0xDEC8, 0x5955,
+	0xDEC9, 0x595A, 0xDECA, 0x5958, 0xDECB, 0x530F, 0xDECC, 0x5C22,
+	0xDECD, 0x5C25, 0xDECE, 0x5C2C, 0xDECF, 0x5C34, 0xDED0, 0x624C,
+	0xDED1, 0x626A, 0xDED2, 0x629F, 0xDED3, 0x62BB, 0xDED4, 0x62CA,
+	0xDED5, 0x62DA, 0xDED6, 0x62D7, 0xDED7, 0x62EE, 0xDED8, 0x6322,
+	0xDED9, 0x62F6, 0xDEDA, 0x6339, 0xDEDB, 0x634B, 0xDEDC, 0x6343,
+	0xDEDD, 0x63AD, 0xDEDE, 0x63F6, 0xDEDF, 0x6371, 0xDEE0, 0x637A,
+	0xDEE1, 0x638E, 0xDEE2, 0x63B4, 0xDEE3, 0x636D, 0xDEE4, 0x63AC,
+	0xDEE5, 0x638A, 0xDEE6, 0x6369, 0xDEE7, 0x63AE, 0xDEE8, 0x63BC,
+	0xDEE9, 0x63F2, 0xDEEA, 0x63F8, 0xDEEB, 0x63E0, 0xDEEC, 0x63FF,
+	0xDEED, 0x63C4, 0xDEEE, 0x63DE, 0xDEEF, 0x63CE, 0xDEF0, 0x6452,
+	0xDEF1, 0x63C6, 0xDEF2, 0x63BE, 0xDEF3, 0x6445, 0xDEF4, 0x6441,
+	0xDEF5, 0x640B, 0xDEF6, 0x641B, 0xDEF7, 0x6420, 0xDEF8, 0x640C,
+	0xDEF9, 0x6426, 0xDEFA, 0x6421, 0xDEFB, 0x645E, 0xDEFC, 0x6484,
+	0xDEFD, 0x646D, 0xDEFE, 0x6496, 0xDF40, 0x9019, 0xDF41, 0x901C,
+	0xDF42, 0x9023, 0xDF43, 0x9024, 0xDF44, 0x9025, 0xDF45, 0x9027,
+	0xDF46, 0x9028, 0xDF47, 0x9029, 0xDF48, 0x902A, 0xDF49, 0x902B,
+	0xDF4A, 0x902C, 0xDF4B, 0x9030, 0xDF4C, 0x9031, 0xDF4D, 0x9032,
+	0xDF4E, 0x9033, 0xDF4F, 0x9034, 0xDF50, 0x9037, 0xDF51, 0x9039,
+	0xDF52, 0x903A, 0xDF53, 0x903D, 0xDF54, 0x903F, 0xDF55, 0x9040,
+	0xDF56, 0x9043, 0xDF57, 0x9045, 0xDF58, 0x9046, 0xDF59, 0x9048,
+	0xDF5A, 0x9049, 0xDF5B, 0x904A, 0xDF5C, 0x904B, 0xDF5D, 0x904C,
+	0xDF5E, 0x904E, 0xDF5F, 0x9054, 0xDF60, 0x9055, 0xDF61, 0x9056,
+	0xDF62, 0x9059, 0xDF63, 0x905A, 0xDF64, 0x905C, 0xDF65, 0x905D,
+	0xDF66, 0x905E, 0xDF67, 0x905F, 0xDF68, 0x9060, 0xDF69, 0x9061,
+	0xDF6A, 0x9064, 0xDF6B, 0x9066, 0xDF6C, 0x9067, 0xDF6D, 0x9069,
+	0xDF6E, 0x906A, 0xDF6F, 0x906B, 0xDF70, 0x906C, 0xDF71, 0x906F,
+	0xDF72, 0x9070, 0xDF73, 0x9071, 0xDF74, 0x9072, 0xDF75, 0x9073,
+	0xDF76, 0x9076, 0xDF77, 0x9077, 0xDF78, 0x9078, 0xDF79, 0x9079,
+	0xDF7A, 0x907A, 0xDF7B, 0x907B, 0xDF7C, 0x907C, 0xDF7D, 0x907E,
+	0xDF7E, 0x9081, 0xDF80, 0x9084, 0xDF81, 0x9085, 0xDF82, 0x9086,
+	0xDF83, 0x9087, 0xDF84, 0x9089, 0xDF85, 0x908A, 0xDF86, 0x908C,
+	0xDF87, 0x908D, 0xDF88, 0x908E, 0xDF89, 0x908F, 0xDF8A, 0x9090,
+	0xDF8B, 0x9092, 0xDF8C, 0x9094, 0xDF8D, 0x9096, 0xDF8E, 0x9098,
+	0xDF8F, 0x909A, 0xDF90, 0x909C, 0xDF91, 0x909E, 0xDF92, 0x909F,
+	0xDF93, 0x90A0, 0xDF94, 0x90A4, 0xDF95, 0x90A5, 0xDF96, 0x90A7,
+	0xDF97, 0x90A8, 0xDF98, 0x90A9, 0xDF99, 0x90AB, 0xDF9A, 0x90AD,
+	0xDF9B, 0x90B2, 0xDF9C, 0x90B7, 0xDF9D, 0x90BC, 0xDF9E, 0x90BD,
+	0xDF9F, 0x90BF, 0xDFA0, 0x90C0, 0xDFA1, 0x647A, 0xDFA2, 0x64B7,
+	0xDFA3, 0x64B8, 0xDFA4, 0x6499, 0xDFA5, 0x64BA, 0xDFA6, 0x64C0,
+	0xDFA7, 0x64D0, 0xDFA8, 0x64D7, 0xDFA9, 0x64E4, 0xDFAA, 0x64E2,
+	0xDFAB, 0x6509, 0xDFAC, 0x6525, 0xDFAD, 0x652E, 0xDFAE, 0x5F0B,
+	0xDFAF, 0x5FD2, 0xDFB0, 0x7519, 0xDFB1, 0x5F11, 0xDFB2, 0x535F,
+	0xDFB3, 0x53F1, 0xDFB4, 0x53FD, 0xDFB5, 0x53E9, 0xDFB6, 0x53E8,
+	0xDFB7, 0x53FB, 0xDFB8, 0x5412, 0xDFB9, 0x5416, 0xDFBA, 0x5406,
+	0xDFBB, 0x544B, 0xDFBC, 0x5452, 0xDFBD, 0x5453, 0xDFBE, 0x5454,
+	0xDFBF, 0x5456, 0xDFC0, 0x5443, 0xDFC1, 0x5421, 0xDFC2, 0x5457,
+	0xDFC3, 0x5459, 0xDFC4, 0x5423, 0xDFC5, 0x5432, 0xDFC6, 0x5482,
+	0xDFC7, 0x5494, 0xDFC8, 0x5477, 0xDFC9, 0x5471, 0xDFCA, 0x5464,
+	0xDFCB, 0x549A, 0xDFCC, 0x549B, 0xDFCD, 0x5484, 0xDFCE, 0x5476,
+	0xDFCF, 0x5466, 0xDFD0, 0x549D, 0xDFD1, 0x54D0, 0xDFD2, 0x54AD,
+	0xDFD3, 0x54C2, 0xDFD4, 0x54B4, 0xDFD5, 0x54D2, 0xDFD6, 0x54A7,
+	0xDFD7, 0x54A6, 0xDFD8, 0x54D3, 0xDFD9, 0x54D4, 0xDFDA, 0x5472,
+	0xDFDB, 0x54A3, 0xDFDC, 0x54D5, 0xDFDD, 0x54BB, 0xDFDE, 0x54BF,
+	0xDFDF, 0x54CC, 0xDFE0, 0x54D9, 0xDFE1, 0x54DA, 0xDFE2, 0x54DC,
+	0xDFE3, 0x54A9, 0xDFE4, 0x54AA, 0xDFE5, 0x54A4, 0xDFE6, 0x54DD,
+	0xDFE7, 0x54CF, 0xDFE8, 0x54DE, 0xDFE9, 0x551B, 0xDFEA, 0x54E7,
+	0xDFEB, 0x5520, 0xDFEC, 0x54FD, 0xDFED, 0x5514, 0xDFEE, 0x54F3,
+	0xDFEF, 0x5522, 0xDFF0, 0x5523, 0xDFF1, 0x550F, 0xDFF2, 0x5511,
+	0xDFF3, 0x5527, 0xDFF4, 0x552A, 0xDFF5, 0x5567, 0xDFF6, 0x558F,
+	0xDFF7, 0x55B5, 0xDFF8, 0x5549, 0xDFF9, 0x556D, 0xDFFA, 0x5541,
+	0xDFFB, 0x5555, 0xDFFC, 0x553F, 0xDFFD, 0x5550, 0xDFFE, 0x553C,
+	0xE040, 0x90C2, 0xE041, 0x90C3, 0xE042, 0x90C6, 0xE043, 0x90C8,
+	0xE044, 0x90C9, 0xE045, 0x90CB, 0xE046, 0x90CC, 0xE047, 0x90CD,
+	0xE048, 0x90D2, 0xE049, 0x90D4, 0xE04A, 0x90D5, 0xE04B, 0x90D6,
+	0xE04C, 0x90D8, 0xE04D, 0x90D9, 0xE04E, 0x90DA, 0xE04F, 0x90DE,
+	0xE050, 0x90DF, 0xE051, 0x90E0, 0xE052, 0x90E3, 0xE053, 0x90E4,
+	0xE054, 0x90E5, 0xE055, 0x90E9, 0xE056, 0x90EA, 0xE057, 0x90EC,
+	0xE058, 0x90EE, 0xE059, 0x90F0, 0xE05A, 0x90F1, 0xE05B, 0x90F2,
+	0xE05C, 0x90F3, 0xE05D, 0x90F5, 0xE05E, 0x90F6, 0xE05F, 0x90F7,
+	0xE060, 0x90F9, 0xE061, 0x90FA, 0xE062, 0x90FB, 0xE063, 0x90FC,
+	0xE064, 0x90FF, 0xE065, 0x9100, 0xE066, 0x9101, 0xE067, 0x9103,
+	0xE068, 0x9105, 0xE069, 0x9106, 0xE06A, 0x9107, 0xE06B, 0x9108,
+	0xE06C, 0x9109, 0xE06D, 0x910A, 0xE06E, 0x910B, 0xE06F, 0x910C,
+	0xE070, 0x910D, 0xE071, 0x910E, 0xE072, 0x910F, 0xE073, 0x9110,
+	0xE074, 0x9111, 0xE075, 0x9112, 0xE076, 0x9113, 0xE077, 0x9114,
+	0xE078, 0x9115, 0xE079, 0x9116, 0xE07A, 0x9117, 0xE07B, 0x9118,
+	0xE07C, 0x911A, 0xE07D, 0x911B, 0xE07E, 0x911C, 0xE080, 0x911D,
+	0xE081, 0x911F, 0xE082, 0x9120, 0xE083, 0x9121, 0xE084, 0x9124,
+	0xE085, 0x9125, 0xE086, 0x9126, 0xE087, 0x9127, 0xE088, 0x9128,
+	0xE089, 0x9129, 0xE08A, 0x912A, 0xE08B, 0x912B, 0xE08C, 0x912C,
+	0xE08D, 0x912D, 0xE08E, 0x912E, 0xE08F, 0x9130, 0xE090, 0x9132,
+	0xE091, 0x9133, 0xE092, 0x9134, 0xE093, 0x9135, 0xE094, 0x9136,
+	0xE095, 0x9137, 0xE096, 0x9138, 0xE097, 0x913A, 0xE098, 0x913B,
+	0xE099, 0x913C, 0xE09A, 0x913D, 0xE09B, 0x913E, 0xE09C, 0x913F,
+	0xE09D, 0x9140, 0xE09E, 0x9141, 0xE09F, 0x9142, 0xE0A0, 0x9144,
+	0xE0A1, 0x5537, 0xE0A2, 0x5556, 0xE0A3, 0x5575, 0xE0A4, 0x5576,
+	0xE0A5, 0x5577, 0xE0A6, 0x5533, 0xE0A7, 0x5530, 0xE0A8, 0x555C,
+	0xE0A9, 0x558B, 0xE0AA, 0x55D2, 0xE0AB, 0x5583, 0xE0AC, 0x55B1,
+	0xE0AD, 0x55B9, 0xE0AE, 0x5588, 0xE0AF, 0x5581, 0xE0B0, 0x559F,
+	0xE0B1, 0x557E, 0xE0B2, 0x55D6, 0xE0B3, 0x5591, 0xE0B4, 0x557B,
+	0xE0B5, 0x55DF, 0xE0B6, 0x55BD, 0xE0B7, 0x55BE, 0xE0B8, 0x5594,
+	0xE0B9, 0x5599, 0xE0BA, 0x55EA, 0xE0BB, 0x55F7, 0xE0BC, 0x55C9,
+	0xE0BD, 0x561F, 0xE0BE, 0x55D1, 0xE0BF, 0x55EB, 0xE0C0, 0x55EC,
+	0xE0C1, 0x55D4, 0xE0C2, 0x55E6, 0xE0C3, 0x55DD, 0xE0C4, 0x55C4,
+	0xE0C5, 0x55EF, 0xE0C6, 0x55E5, 0xE0C7, 0x55F2, 0xE0C8, 0x55F3,
+	0xE0C9, 0x55CC, 0xE0CA, 0x55CD, 0xE0CB, 0x55E8, 0xE0CC, 0x55F5,
+	0xE0CD, 0x55E4, 0xE0CE, 0x8F94, 0xE0CF, 0x561E, 0xE0D0, 0x5608,
+	0xE0D1, 0x560C, 0xE0D2, 0x5601, 0xE0D3, 0x5624, 0xE0D4, 0x5623,
+	0xE0D5, 0x55FE, 0xE0D6, 0x5600, 0xE0D7, 0x5627, 0xE0D8, 0x562D,
+	0xE0D9, 0x5658, 0xE0DA, 0x5639, 0xE0DB, 0x5657, 0xE0DC, 0x562C,
+	0xE0DD, 0x564D, 0xE0DE, 0x5662, 0xE0DF, 0x5659, 0xE0E0, 0x565C,
+	0xE0E1, 0x564C, 0xE0E2, 0x5654, 0xE0E3, 0x5686, 0xE0E4, 0x5664,
+	0xE0E5, 0x5671, 0xE0E6, 0x566B, 0xE0E7, 0x567B, 0xE0E8, 0x567C,
+	0xE0E9, 0x5685, 0xE0EA, 0x5693, 0xE0EB, 0x56AF, 0xE0EC, 0x56D4,
+	0xE0ED, 0x56D7, 0xE0EE, 0x56DD, 0xE0EF, 0x56E1, 0xE0F0, 0x56F5,
+	0xE0F1, 0x56EB, 0xE0F2, 0x56F9, 0xE0F3, 0x56FF, 0xE0F4, 0x5704,
+	0xE0F5, 0x570A, 0xE0F6, 0x5709, 0xE0F7, 0x571C, 0xE0F8, 0x5E0F,
+	0xE0F9, 0x5E19, 0xE0FA, 0x5E14, 0xE0FB, 0x5E11, 0xE0FC, 0x5E31,
+	0xE0FD, 0x5E3B, 0xE0FE, 0x5E3C, 0xE140, 0x9145, 0xE141, 0x9147,
+	0xE142, 0x9148, 0xE143, 0x9151, 0xE144, 0x9153, 0xE145, 0x9154,
+	0xE146, 0x9155, 0xE147, 0x9156, 0xE148, 0x9158, 0xE149, 0x9159,
+	0xE14A, 0x915B, 0xE14B, 0x915C, 0xE14C, 0x915F, 0xE14D, 0x9160,
+	0xE14E, 0x9166, 0xE14F, 0x9167, 0xE150, 0x9168, 0xE151, 0x916B,
+	0xE152, 0x916D, 0xE153, 0x9173, 0xE154, 0x917A, 0xE155, 0x917B,
+	0xE156, 0x917C, 0xE157, 0x9180, 0xE158, 0x9181, 0xE159, 0x9182,
+	0xE15A, 0x9183, 0xE15B, 0x9184, 0xE15C, 0x9186, 0xE15D, 0x9188,
+	0xE15E, 0x918A, 0xE15F, 0x918E, 0xE160, 0x918F, 0xE161, 0x9193,
+	0xE162, 0x9194, 0xE163, 0x9195, 0xE164, 0x9196, 0xE165, 0x9197,
+	0xE166, 0x9198, 0xE167, 0x9199, 0xE168, 0x919C, 0xE169, 0x919D,
+	0xE16A, 0x919E, 0xE16B, 0x919F, 0xE16C, 0x91A0, 0xE16D, 0x91A1,
+	0xE16E, 0x91A4, 0xE16F, 0x91A5, 0xE170, 0x91A6, 0xE171, 0x91A7,
+	0xE172, 0x91A8, 0xE173, 0x91A9, 0xE174, 0x91AB, 0xE175, 0x91AC,
+	0xE176, 0x91B0, 0xE177, 0x91B1, 0xE178, 0x91B2, 0xE179, 0x91B3,
+	0xE17A, 0x91B6, 0xE17B, 0x91B7, 0xE17C, 0x91B8, 0xE17D, 0x91B9,
+	0xE17E, 0x91BB, 0xE180, 0x91BC, 0xE181, 0x91BD, 0xE182, 0x91BE,
+	0xE183, 0x91BF, 0xE184, 0x91C0, 0xE185, 0x91C1, 0xE186, 0x91C2,
+	0xE187, 0x91C3, 0xE188, 0x91C4, 0xE189, 0x91C5, 0xE18A, 0x91C6,
+	0xE18B, 0x91C8, 0xE18C, 0x91CB, 0xE18D, 0x91D0, 0xE18E, 0x91D2,
+	0xE18F, 0x91D3, 0xE190, 0x91D4, 0xE191, 0x91D5, 0xE192, 0x91D6,
+	0xE193, 0x91D7, 0xE194, 0x91D8, 0xE195, 0x91D9, 0xE196, 0x91DA,
+	0xE197, 0x91DB, 0xE198, 0x91DD, 0xE199, 0x91DE, 0xE19A, 0x91DF,
+	0xE19B, 0x91E0, 0xE19C, 0x91E1, 0xE19D, 0x91E2, 0xE19E, 0x91E3,
+	0xE19F, 0x91E4, 0xE1A0, 0x91E5, 0xE1A1, 0x5E37, 0xE1A2, 0x5E44,
+	0xE1A3, 0x5E54, 0xE1A4, 0x5E5B, 0xE1A5, 0x5E5E, 0xE1A6, 0x5E61,
+	0xE1A7, 0x5C8C, 0xE1A8, 0x5C7A, 0xE1A9, 0x5C8D, 0xE1AA, 0x5C90,
+	0xE1AB, 0x5C96, 0xE1AC, 0x5C88, 0xE1AD, 0x5C98, 0xE1AE, 0x5C99,
+	0xE1AF, 0x5C91, 0xE1B0, 0x5C9A, 0xE1B1, 0x5C9C, 0xE1B2, 0x5CB5,
+	0xE1B3, 0x5CA2, 0xE1B4, 0x5CBD, 0xE1B5, 0x5CAC, 0xE1B6, 0x5CAB,
+	0xE1B7, 0x5CB1, 0xE1B8, 0x5CA3, 0xE1B9, 0x5CC1, 0xE1BA, 0x5CB7,
+	0xE1BB, 0x5CC4, 0xE1BC, 0x5CD2, 0xE1BD, 0x5CE4, 0xE1BE, 0x5CCB,
+	0xE1BF, 0x5CE5, 0xE1C0, 0x5D02, 0xE1C1, 0x5D03, 0xE1C2, 0x5D27,
+	0xE1C3, 0x5D26, 0xE1C4, 0x5D2E, 0xE1C5, 0x5D24, 0xE1C6, 0x5D1E,
+	0xE1C7, 0x5D06, 0xE1C8, 0x5D1B, 0xE1C9, 0x5D58, 0xE1CA, 0x5D3E,
+	0xE1CB, 0x5D34, 0xE1CC, 0x5D3D, 0xE1CD, 0x5D6C, 0xE1CE, 0x5D5B,
+	0xE1CF, 0x5D6F, 0xE1D0, 0x5D5D, 0xE1D1, 0x5D6B, 0xE1D2, 0x5D4B,
+	0xE1D3, 0x5D4A, 0xE1D4, 0x5D69, 0xE1D5, 0x5D74, 0xE1D6, 0x5D82,
+	0xE1D7, 0x5D99, 0xE1D8, 0x5D9D, 0xE1D9, 0x8C73, 0xE1DA, 0x5DB7,
+	0xE1DB, 0x5DC5, 0xE1DC, 0x5F73, 0xE1DD, 0x5F77, 0xE1DE, 0x5F82,
+	0xE1DF, 0x5F87, 0xE1E0, 0x5F89, 0xE1E1, 0x5F8C, 0xE1E2, 0x5F95,
+	0xE1E3, 0x5F99, 0xE1E4, 0x5F9C, 0xE1E5, 0x5FA8, 0xE1E6, 0x5FAD,
+	0xE1E7, 0x5FB5, 0xE1E8, 0x5FBC, 0xE1E9, 0x8862, 0xE1EA, 0x5F61,
+	0xE1EB, 0x72AD, 0xE1EC, 0x72B0, 0xE1ED, 0x72B4, 0xE1EE, 0x72B7,
+	0xE1EF, 0x72B8, 0xE1F0, 0x72C3, 0xE1F1, 0x72C1, 0xE1F2, 0x72CE,
+	0xE1F3, 0x72CD, 0xE1F4, 0x72D2, 0xE1F5, 0x72E8, 0xE1F6, 0x72EF,
+	0xE1F7, 0x72E9, 0xE1F8, 0x72F2, 0xE1F9, 0x72F4, 0xE1FA, 0x72F7,
+	0xE1FB, 0x7301, 0xE1FC, 0x72F3, 0xE1FD, 0x7303, 0xE1FE, 0x72FA,
+	0xE240, 0x91E6, 0xE241, 0x91E7, 0xE242, 0x91E8, 0xE243, 0x91E9,
+	0xE244, 0x91EA, 0xE245, 0x91EB, 0xE246, 0x91EC, 0xE247, 0x91ED,
+	0xE248, 0x91EE, 0xE249, 0x91EF, 0xE24A, 0x91F0, 0xE24B, 0x91F1,
+	0xE24C, 0x91F2, 0xE24D, 0x91F3, 0xE24E, 0x91F4, 0xE24F, 0x91F5,
+	0xE250, 0x91F6, 0xE251, 0x91F7, 0xE252, 0x91F8, 0xE253, 0x91F9,
+	0xE254, 0x91FA, 0xE255, 0x91FB, 0xE256, 0x91FC, 0xE257, 0x91FD,
+	0xE258, 0x91FE, 0xE259, 0x91FF, 0xE25A, 0x9200, 0xE25B, 0x9201,
+	0xE25C, 0x9202, 0xE25D, 0x9203, 0xE25E, 0x9204, 0xE25F, 0x9205,
+	0xE260, 0x9206, 0xE261, 0x9207, 0xE262, 0x9208, 0xE263, 0x9209,
+	0xE264, 0x920A, 0xE265, 0x920B, 0xE266, 0x920C, 0xE267, 0x920D,
+	0xE268, 0x920E, 0xE269, 0x920F, 0xE26A, 0x9210, 0xE26B, 0x9211,
+	0xE26C, 0x9212, 0xE26D, 0x9213, 0xE26E, 0x9214, 0xE26F, 0x9215,
+	0xE270, 0x9216, 0xE271, 0x9217, 0xE272, 0x9218, 0xE273, 0x9219,
+	0xE274, 0x921A, 0xE275, 0x921B, 0xE276, 0x921C, 0xE277, 0x921D,
+	0xE278, 0x921E, 0xE279, 0x921F, 0xE27A, 0x9220, 0xE27B, 0x9221,
+	0xE27C, 0x9222, 0xE27D, 0x9223, 0xE27E, 0x9224, 0xE280, 0x9225,
+	0xE281, 0x9226, 0xE282, 0x9227, 0xE283, 0x9228, 0xE284, 0x9229,
+	0xE285, 0x922A, 0xE286, 0x922B, 0xE287, 0x922C, 0xE288, 0x922D,
+	0xE289, 0x922E, 0xE28A, 0x922F, 0xE28B, 0x9230, 0xE28C, 0x9231,
+	0xE28D, 0x9232, 0xE28E, 0x9233, 0xE28F, 0x9234, 0xE290, 0x9235,
+	0xE291, 0x9236, 0xE292, 0x9237, 0xE293, 0x9238, 0xE294, 0x9239,
+	0xE295, 0x923A, 0xE296, 0x923B, 0xE297, 0x923C, 0xE298, 0x923D,
+	0xE299, 0x923E, 0xE29A, 0x923F, 0xE29B, 0x9240, 0xE29C, 0x9241,
+	0xE29D, 0x9242, 0xE29E, 0x9243, 0xE29F, 0x9244, 0xE2A0, 0x9245,
+	0xE2A1, 0x72FB, 0xE2A2, 0x7317, 0xE2A3, 0x7313, 0xE2A4, 0x7321,
+	0xE2A5, 0x730A, 0xE2A6, 0x731E, 0xE2A7, 0x731D, 0xE2A8, 0x7315,
+	0xE2A9, 0x7322, 0xE2AA, 0x7339, 0xE2AB, 0x7325, 0xE2AC, 0x732C,
+	0xE2AD, 0x7338, 0xE2AE, 0x7331, 0xE2AF, 0x7350, 0xE2B0, 0x734D,
+	0xE2B1, 0x7357, 0xE2B2, 0x7360, 0xE2B3, 0x736C, 0xE2B4, 0x736F,
+	0xE2B5, 0x737E, 0xE2B6, 0x821B, 0xE2B7, 0x5925, 0xE2B8, 0x98E7,
+	0xE2B9, 0x5924, 0xE2BA, 0x5902, 0xE2BB, 0x9963, 0xE2BC, 0x9967,
+	0xE2BD, 0x9968, 0xE2BE, 0x9969, 0xE2BF, 0x996A, 0xE2C0, 0x996B,
+	0xE2C1, 0x996C, 0xE2C2, 0x9974, 0xE2C3, 0x9977, 0xE2C4, 0x997D,
+	0xE2C5, 0x9980, 0xE2C6, 0x9984, 0xE2C7, 0x9987, 0xE2C8, 0x998A,
+	0xE2C9, 0x998D, 0xE2CA, 0x9990, 0xE2CB, 0x9991, 0xE2CC, 0x9993,
+	0xE2CD, 0x9994, 0xE2CE, 0x9995, 0xE2CF, 0x5E80, 0xE2D0, 0x5E91,
+	0xE2D1, 0x5E8B, 0xE2D2, 0x5E96, 0xE2D3, 0x5EA5, 0xE2D4, 0x5EA0,
+	0xE2D5, 0x5EB9, 0xE2D6, 0x5EB5, 0xE2D7, 0x5EBE, 0xE2D8, 0x5EB3,
+	0xE2D9, 0x8D53, 0xE2DA, 0x5ED2, 0xE2DB, 0x5ED1, 0xE2DC, 0x5EDB,
+	0xE2DD, 0x5EE8, 0xE2DE, 0x5EEA, 0xE2DF, 0x81BA, 0xE2E0, 0x5FC4,
+	0xE2E1, 0x5FC9, 0xE2E2, 0x5FD6, 0xE2E3, 0x5FCF, 0xE2E4, 0x6003,
+	0xE2E5, 0x5FEE, 0xE2E6, 0x6004, 0xE2E7, 0x5FE1, 0xE2E8, 0x5FE4,
+	0xE2E9, 0x5FFE, 0xE2EA, 0x6005, 0xE2EB, 0x6006, 0xE2EC, 0x5FEA,
+	0xE2ED, 0x5FED, 0xE2EE, 0x5FF8, 0xE2EF, 0x6019, 0xE2F0, 0x6035,
+	0xE2F1, 0x6026, 0xE2F2, 0x601B, 0xE2F3, 0x600F, 0xE2F4, 0x600D,
+	0xE2F5, 0x6029, 0xE2F6, 0x602B, 0xE2F7, 0x600A, 0xE2F8, 0x603F,
+	0xE2F9, 0x6021, 0xE2FA, 0x6078, 0xE2FB, 0x6079, 0xE2FC, 0x607B,
+	0xE2FD, 0x607A, 0xE2FE, 0x6042, 0xE340, 0x9246, 0xE341, 0x9247,
+	0xE342, 0x9248, 0xE343, 0x9249, 0xE344, 0x924A, 0xE345, 0x924B,
+	0xE346, 0x924C, 0xE347, 0x924D, 0xE348, 0x924E, 0xE349, 0x924F,
+	0xE34A, 0x9250, 0xE34B, 0x9251, 0xE34C, 0x9252, 0xE34D, 0x9253,
+	0xE34E, 0x9254, 0xE34F, 0x9255, 0xE350, 0x9256, 0xE351, 0x9257,
+	0xE352, 0x9258, 0xE353, 0x9259, 0xE354, 0x925A, 0xE355, 0x925B,
+	0xE356, 0x925C, 0xE357, 0x925D, 0xE358, 0x925E, 0xE359, 0x925F,
+	0xE35A, 0x9260, 0xE35B, 0x9261, 0xE35C, 0x9262, 0xE35D, 0x9263,
+	0xE35E, 0x9264, 0xE35F, 0x9265, 0xE360, 0x9266, 0xE361, 0x9267,
+	0xE362, 0x9268, 0xE363, 0x9269, 0xE364, 0x926A, 0xE365, 0x926B,
+	0xE366, 0x926C, 0xE367, 0x926D, 0xE368, 0x926E, 0xE369, 0x926F,
+	0xE36A, 0x9270, 0xE36B, 0x9271, 0xE36C, 0x9272, 0xE36D, 0x9273,
+	0xE36E, 0x9275, 0xE36F, 0x9276, 0xE370, 0x9277, 0xE371, 0x9278,
+	0xE372, 0x9279, 0xE373, 0x927A, 0xE374, 0x927B, 0xE375, 0x927C,
+	0xE376, 0x927D, 0xE377, 0x927E, 0xE378, 0x927F, 0xE379, 0x9280,
+	0xE37A, 0x9281, 0xE37B, 0x9282, 0xE37C, 0x9283, 0xE37D, 0x9284,
+	0xE37E, 0x9285, 0xE380, 0x9286, 0xE381, 0x9287, 0xE382, 0x9288,
+	0xE383, 0x9289, 0xE384, 0x928A, 0xE385, 0x928B, 0xE386, 0x928C,
+	0xE387, 0x928D, 0xE388, 0x928F, 0xE389, 0x9290, 0xE38A, 0x9291,
+	0xE38B, 0x9292, 0xE38C, 0x9293, 0xE38D, 0x9294, 0xE38E, 0x9295,
+	0xE38F, 0x9296, 0xE390, 0x9297, 0xE391, 0x9298, 0xE392, 0x9299,
+	0xE393, 0x929A, 0xE394, 0x929B, 0xE395, 0x929C, 0xE396, 0x929D,
+	0xE397, 0x929E, 0xE398, 0x929F, 0xE399, 0x92A0, 0xE39A, 0x92A1,
+	0xE39B, 0x92A2, 0xE39C, 0x92A3, 0xE39D, 0x92A4, 0xE39E, 0x92A5,
+	0xE39F, 0x92A6, 0xE3A0, 0x92A7, 0xE3A1, 0x606A, 0xE3A2, 0x607D,
+	0xE3A3, 0x6096, 0xE3A4, 0x609A, 0xE3A5, 0x60AD, 0xE3A6, 0x609D,
+	0xE3A7, 0x6083, 0xE3A8, 0x6092, 0xE3A9, 0x608C, 0xE3AA, 0x609B,
+	0xE3AB, 0x60EC, 0xE3AC, 0x60BB, 0xE3AD, 0x60B1, 0xE3AE, 0x60DD,
+	0xE3AF, 0x60D8, 0xE3B0, 0x60C6, 0xE3B1, 0x60DA, 0xE3B2, 0x60B4,
+	0xE3B3, 0x6120, 0xE3B4, 0x6126, 0xE3B5, 0x6115, 0xE3B6, 0x6123,
+	0xE3B7, 0x60F4, 0xE3B8, 0x6100, 0xE3B9, 0x610E, 0xE3BA, 0x612B,
+	0xE3BB, 0x614A, 0xE3BC, 0x6175, 0xE3BD, 0x61AC, 0xE3BE, 0x6194,
+	0xE3BF, 0x61A7, 0xE3C0, 0x61B7, 0xE3C1, 0x61D4, 0xE3C2, 0x61F5,
+	0xE3C3, 0x5FDD, 0xE3C4, 0x96B3, 0xE3C5, 0x95E9, 0xE3C6, 0x95EB,
+	0xE3C7, 0x95F1, 0xE3C8, 0x95F3, 0xE3C9, 0x95F5, 0xE3CA, 0x95F6,
+	0xE3CB, 0x95FC, 0xE3CC, 0x95FE, 0xE3CD, 0x9603, 0xE3CE, 0x9604,
+	0xE3CF, 0x9606, 0xE3D0, 0x9608, 0xE3D1, 0x960A, 0xE3D2, 0x960B,
+	0xE3D3, 0x960C, 0xE3D4, 0x960D, 0xE3D5, 0x960F, 0xE3D6, 0x9612,
+	0xE3D7, 0x9615, 0xE3D8, 0x9616, 0xE3D9, 0x9617, 0xE3DA, 0x9619,
+	0xE3DB, 0x961A, 0xE3DC, 0x4E2C, 0xE3DD, 0x723F, 0xE3DE, 0x6215,
+	0xE3DF, 0x6C35, 0xE3E0, 0x6C54, 0xE3E1, 0x6C5C, 0xE3E2, 0x6C4A,
+	0xE3E3, 0x6CA3, 0xE3E4, 0x6C85, 0xE3E5, 0x6C90, 0xE3E6, 0x6C94,
+	0xE3E7, 0x6C8C, 0xE3E8, 0x6C68, 0xE3E9, 0x6C69, 0xE3EA, 0x6C74,
+	0xE3EB, 0x6C76, 0xE3EC, 0x6C86, 0xE3ED, 0x6CA9, 0xE3EE, 0x6CD0,
+	0xE3EF, 0x6CD4, 0xE3F0, 0x6CAD, 0xE3F1, 0x6CF7, 0xE3F2, 0x6CF8,
+	0xE3F3, 0x6CF1, 0xE3F4, 0x6CD7, 0xE3F5, 0x6CB2, 0xE3F6, 0x6CE0,
+	0xE3F7, 0x6CD6, 0xE3F8, 0x6CFA, 0xE3F9, 0x6CEB, 0xE3FA, 0x6CEE,
+	0xE3FB, 0x6CB1, 0xE3FC, 0x6CD3, 0xE3FD, 0x6CEF, 0xE3FE, 0x6CFE,
+	0xE440, 0x92A8, 0xE441, 0x92A9, 0xE442, 0x92AA, 0xE443, 0x92AB,
+	0xE444, 0x92AC, 0xE445, 0x92AD, 0xE446, 0x92AF, 0xE447, 0x92B0,
+	0xE448, 0x92B1, 0xE449, 0x92B2, 0xE44A, 0x92B3, 0xE44B, 0x92B4,
+	0xE44C, 0x92B5, 0xE44D, 0x92B6, 0xE44E, 0x92B7, 0xE44F, 0x92B8,
+	0xE450, 0x92B9, 0xE451, 0x92BA, 0xE452, 0x92BB, 0xE453, 0x92BC,
+	0xE454, 0x92BD, 0xE455, 0x92BE, 0xE456, 0x92BF, 0xE457, 0x92C0,
+	0xE458, 0x92C1, 0xE459, 0x92C2, 0xE45A, 0x92C3, 0xE45B, 0x92C4,
+	0xE45C, 0x92C5, 0xE45D, 0x92C6, 0xE45E, 0x92C7, 0xE45F, 0x92C9,
+	0xE460, 0x92CA, 0xE461, 0x92CB, 0xE462, 0x92CC, 0xE463, 0x92CD,
+	0xE464, 0x92CE, 0xE465, 0x92CF, 0xE466, 0x92D0, 0xE467, 0x92D1,
+	0xE468, 0x92D2, 0xE469, 0x92D3, 0xE46A, 0x92D4, 0xE46B, 0x92D5,
+	0xE46C, 0x92D6, 0xE46D, 0x92D7, 0xE46E, 0x92D8, 0xE46F, 0x92D9,
+	0xE470, 0x92DA, 0xE471, 0x92DB, 0xE472, 0x92DC, 0xE473, 0x92DD,
+	0xE474, 0x92DE, 0xE475, 0x92DF, 0xE476, 0x92E0, 0xE477, 0x92E1,
+	0xE478, 0x92E2, 0xE479, 0x92E3, 0xE47A, 0x92E4, 0xE47B, 0x92E5,
+	0xE47C, 0x92E6, 0xE47D, 0x92E7, 0xE47E, 0x92E8, 0xE480, 0x92E9,
+	0xE481, 0x92EA, 0xE482, 0x92EB, 0xE483, 0x92EC, 0xE484, 0x92ED,
+	0xE485, 0x92EE, 0xE486, 0x92EF, 0xE487, 0x92F0, 0xE488, 0x92F1,
+	0xE489, 0x92F2, 0xE48A, 0x92F3, 0xE48B, 0x92F4, 0xE48C, 0x92F5,
+	0xE48D, 0x92F6, 0xE48E, 0x92F7, 0xE48F, 0x92F8, 0xE490, 0x92F9,
+	0xE491, 0x92FA, 0xE492, 0x92FB, 0xE493, 0x92FC, 0xE494, 0x92FD,
+	0xE495, 0x92FE, 0xE496, 0x92FF, 0xE497, 0x9300, 0xE498, 0x9301,
+	0xE499, 0x9302, 0xE49A, 0x9303, 0xE49B, 0x9304, 0xE49C, 0x9305,
+	0xE49D, 0x9306, 0xE49E, 0x9307, 0xE49F, 0x9308, 0xE4A0, 0x9309,
+	0xE4A1, 0x6D39, 0xE4A2, 0x6D27, 0xE4A3, 0x6D0C, 0xE4A4, 0x6D43,
+	0xE4A5, 0x6D48, 0xE4A6, 0x6D07, 0xE4A7, 0x6D04, 0xE4A8, 0x6D19,
+	0xE4A9, 0x6D0E, 0xE4AA, 0x6D2B, 0xE4AB, 0x6D4D, 0xE4AC, 0x6D2E,
+	0xE4AD, 0x6D35, 0xE4AE, 0x6D1A, 0xE4AF, 0x6D4F, 0xE4B0, 0x6D52,
+	0xE4B1, 0x6D54, 0xE4B2, 0x6D33, 0xE4B3, 0x6D91, 0xE4B4, 0x6D6F,
+	0xE4B5, 0x6D9E, 0xE4B6, 0x6DA0, 0xE4B7, 0x6D5E, 0xE4B8, 0x6D93,
+	0xE4B9, 0x6D94, 0xE4BA, 0x6D5C, 0xE4BB, 0x6D60, 0xE4BC, 0x6D7C,
+	0xE4BD, 0x6D63, 0xE4BE, 0x6E1A, 0xE4BF, 0x6DC7, 0xE4C0, 0x6DC5,
+	0xE4C1, 0x6DDE, 0xE4C2, 0x6E0E, 0xE4C3, 0x6DBF, 0xE4C4, 0x6DE0,
+	0xE4C5, 0x6E11, 0xE4C6, 0x6DE6, 0xE4C7, 0x6DDD, 0xE4C8, 0x6DD9,
+	0xE4C9, 0x6E16, 0xE4CA, 0x6DAB, 0xE4CB, 0x6E0C, 0xE4CC, 0x6DAE,
+	0xE4CD, 0x6E2B, 0xE4CE, 0x6E6E, 0xE4CF, 0x6E4E, 0xE4D0, 0x6E6B,
+	0xE4D1, 0x6EB2, 0xE4D2, 0x6E5F, 0xE4D3, 0x6E86, 0xE4D4, 0x6E53,
+	0xE4D5, 0x6E54, 0xE4D6, 0x6E32, 0xE4D7, 0x6E25, 0xE4D8, 0x6E44,
+	0xE4D9, 0x6EDF, 0xE4DA, 0x6EB1, 0xE4DB, 0x6E98, 0xE4DC, 0x6EE0,
+	0xE4DD, 0x6F2D, 0xE4DE, 0x6EE2, 0xE4DF, 0x6EA5, 0xE4E0, 0x6EA7,
+	0xE4E1, 0x6EBD, 0xE4E2, 0x6EBB, 0xE4E3, 0x6EB7, 0xE4E4, 0x6ED7,
+	0xE4E5, 0x6EB4, 0xE4E6, 0x6ECF, 0xE4E7, 0x6E8F, 0xE4E8, 0x6EC2,
+	0xE4E9, 0x6E9F, 0xE4EA, 0x6F62, 0xE4EB, 0x6F46, 0xE4EC, 0x6F47,
+	0xE4ED, 0x6F24, 0xE4EE, 0x6F15, 0xE4EF, 0x6EF9, 0xE4F0, 0x6F2F,
+	0xE4F1, 0x6F36, 0xE4F2, 0x6F4B, 0xE4F3, 0x6F74, 0xE4F4, 0x6F2A,
+	0xE4F5, 0x6F09, 0xE4F6, 0x6F29, 0xE4F7, 0x6F89, 0xE4F8, 0x6F8D,
+	0xE4F9, 0x6F8C, 0xE4FA, 0x6F78, 0xE4FB, 0x6F72, 0xE4FC, 0x6F7C,
+	0xE4FD, 0x6F7A, 0xE4FE, 0x6FD1, 0xE540, 0x930A, 0xE541, 0x930B,
+	0xE542, 0x930C, 0xE543, 0x930D, 0xE544, 0x930E, 0xE545, 0x930F,
+	0xE546, 0x9310, 0xE547, 0x9311, 0xE548, 0x9312, 0xE549, 0x9313,
+	0xE54A, 0x9314, 0xE54B, 0x9315, 0xE54C, 0x9316, 0xE54D, 0x9317,
+	0xE54E, 0x9318, 0xE54F, 0x9319, 0xE550, 0x931A, 0xE551, 0x931B,
+	0xE552, 0x931C, 0xE553, 0x931D, 0xE554, 0x931E, 0xE555, 0x931F,
+	0xE556, 0x9320, 0xE557, 0x9321, 0xE558, 0x9322, 0xE559, 0x9323,
+	0xE55A, 0x9324, 0xE55B, 0x9325, 0xE55C, 0x9326, 0xE55D, 0x9327,
+	0xE55E, 0x9328, 0xE55F, 0x9329, 0xE560, 0x932A, 0xE561, 0x932B,
+	0xE562, 0x932C, 0xE563, 0x932D, 0xE564, 0x932E, 0xE565, 0x932F,
+	0xE566, 0x9330, 0xE567, 0x9331, 0xE568, 0x9332, 0xE569, 0x9333,
+	0xE56A, 0x9334, 0xE56B, 0x9335, 0xE56C, 0x9336, 0xE56D, 0x9337,
+	0xE56E, 0x9338, 0xE56F, 0x9339, 0xE570, 0x933A, 0xE571, 0x933B,
+	0xE572, 0x933C, 0xE573, 0x933D, 0xE574, 0x933F, 0xE575, 0x9340,
+	0xE576, 0x9341, 0xE577, 0x9342, 0xE578, 0x9343, 0xE579, 0x9344,
+	0xE57A, 0x9345, 0xE57B, 0x9346, 0xE57C, 0x9347, 0xE57D, 0x9348,
+	0xE57E, 0x9349, 0xE580, 0x934A, 0xE581, 0x934B, 0xE582, 0x934C,
+	0xE583, 0x934D, 0xE584, 0x934E, 0xE585, 0x934F, 0xE586, 0x9350,
+	0xE587, 0x9351, 0xE588, 0x9352, 0xE589, 0x9353, 0xE58A, 0x9354,
+	0xE58B, 0x9355, 0xE58C, 0x9356, 0xE58D, 0x9357, 0xE58E, 0x9358,
+	0xE58F, 0x9359, 0xE590, 0x935A, 0xE591, 0x935B, 0xE592, 0x935C,
+	0xE593, 0x935D, 0xE594, 0x935E, 0xE595, 0x935F, 0xE596, 0x9360,
+	0xE597, 0x9361, 0xE598, 0x9362, 0xE599, 0x9363, 0xE59A, 0x9364,
+	0xE59B, 0x9365, 0xE59C, 0x9366, 0xE59D, 0x9367, 0xE59E, 0x9368,
+	0xE59F, 0x9369, 0xE5A0, 0x936B, 0xE5A1, 0x6FC9, 0xE5A2, 0x6FA7,
+	0xE5A3, 0x6FB9, 0xE5A4, 0x6FB6, 0xE5A5, 0x6FC2, 0xE5A6, 0x6FE1,
+	0xE5A7, 0x6FEE, 0xE5A8, 0x6FDE, 0xE5A9, 0x6FE0, 0xE5AA, 0x6FEF,
+	0xE5AB, 0x701A, 0xE5AC, 0x7023, 0xE5AD, 0x701B, 0xE5AE, 0x7039,
+	0xE5AF, 0x7035, 0xE5B0, 0x704F, 0xE5B1, 0x705E, 0xE5B2, 0x5B80,
+	0xE5B3, 0x5B84, 0xE5B4, 0x5B95, 0xE5B5, 0x5B93, 0xE5B6, 0x5BA5,
+	0xE5B7, 0x5BB8, 0xE5B8, 0x752F, 0xE5B9, 0x9A9E, 0xE5BA, 0x6434,
+	0xE5BB, 0x5BE4, 0xE5BC, 0x5BEE, 0xE5BD, 0x8930, 0xE5BE, 0x5BF0,
+	0xE5BF, 0x8E47, 0xE5C0, 0x8B07, 0xE5C1, 0x8FB6, 0xE5C2, 0x8FD3,
+	0xE5C3, 0x8FD5, 0xE5C4, 0x8FE5, 0xE5C5, 0x8FEE, 0xE5C6, 0x8FE4,
+	0xE5C7, 0x8FE9, 0xE5C8, 0x8FE6, 0xE5C9, 0x8FF3, 0xE5CA, 0x8FE8,
+	0xE5CB, 0x9005, 0xE5CC, 0x9004, 0xE5CD, 0x900B, 0xE5CE, 0x9026,
+	0xE5CF, 0x9011, 0xE5D0, 0x900D, 0xE5D1, 0x9016, 0xE5D2, 0x9021,
+	0xE5D3, 0x9035, 0xE5D4, 0x9036, 0xE5D5, 0x902D, 0xE5D6, 0x902F,
+	0xE5D7, 0x9044, 0xE5D8, 0x9051, 0xE5D9, 0x9052, 0xE5DA, 0x9050,
+	0xE5DB, 0x9068, 0xE5DC, 0x9058, 0xE5DD, 0x9062, 0xE5DE, 0x905B,
+	0xE5DF, 0x66B9, 0xE5E0, 0x9074, 0xE5E1, 0x907D, 0xE5E2, 0x9082,
+	0xE5E3, 0x9088, 0xE5E4, 0x9083, 0xE5E5, 0x908B, 0xE5E6, 0x5F50,
+	0xE5E7, 0x5F57, 0xE5E8, 0x5F56, 0xE5E9, 0x5F58, 0xE5EA, 0x5C3B,
+	0xE5EB, 0x54AB, 0xE5EC, 0x5C50, 0xE5ED, 0x5C59, 0xE5EE, 0x5B71,
+	0xE5EF, 0x5C63, 0xE5F0, 0x5C66, 0xE5F1, 0x7FBC, 0xE5F2, 0x5F2A,
+	0xE5F3, 0x5F29, 0xE5F4, 0x5F2D, 0xE5F5, 0x8274, 0xE5F6, 0x5F3C,
+	0xE5F7, 0x9B3B, 0xE5F8, 0x5C6E, 0xE5F9, 0x5981, 0xE5FA, 0x5983,
+	0xE5FB, 0x598D, 0xE5FC, 0x59A9, 0xE5FD, 0x59AA, 0xE5FE, 0x59A3,
+	0xE640, 0x936C, 0xE641, 0x936D, 0xE642, 0x936E, 0xE643, 0x936F,
+	0xE644, 0x9370, 0xE645, 0x9371, 0xE646, 0x9372, 0xE647, 0x9373,
+	0xE648, 0x9374, 0xE649, 0x9375, 0xE64A, 0x9376, 0xE64B, 0x9377,
+	0xE64C, 0x9378, 0xE64D, 0x9379, 0xE64E, 0x937A, 0xE64F, 0x937B,
+	0xE650, 0x937C, 0xE651, 0x937D, 0xE652, 0x937E, 0xE653, 0x937F,
+	0xE654, 0x9380, 0xE655, 0x9381, 0xE656, 0x9382, 0xE657, 0x9383,
+	0xE658, 0x9384, 0xE659, 0x9385, 0xE65A, 0x9386, 0xE65B, 0x9387,
+	0xE65C, 0x9388, 0xE65D, 0x9389, 0xE65E, 0x938A, 0xE65F, 0x938B,
+	0xE660, 0x938C, 0xE661, 0x938D, 0xE662, 0x938E, 0xE663, 0x9390,
+	0xE664, 0x9391, 0xE665, 0x9392, 0xE666, 0x9393, 0xE667, 0x9394,
+	0xE668, 0x9395, 0xE669, 0x9396, 0xE66A, 0x9397, 0xE66B, 0x9398,
+	0xE66C, 0x9399, 0xE66D, 0x939A, 0xE66E, 0x939B, 0xE66F, 0x939C,
+	0xE670, 0x939D, 0xE671, 0x939E, 0xE672, 0x939F, 0xE673, 0x93A0,
+	0xE674, 0x93A1, 0xE675, 0x93A2, 0xE676, 0x93A3, 0xE677, 0x93A4,
+	0xE678, 0x93A5, 0xE679, 0x93A6, 0xE67A, 0x93A7, 0xE67B, 0x93A8,
+	0xE67C, 0x93A9, 0xE67D, 0x93AA, 0xE67E, 0x93AB, 0xE680, 0x93AC,
+	0xE681, 0x93AD, 0xE682, 0x93AE, 0xE683, 0x93AF, 0xE684, 0x93B0,
+	0xE685, 0x93B1, 0xE686, 0x93B2, 0xE687, 0x93B3, 0xE688, 0x93B4,
+	0xE689, 0x93B5, 0xE68A, 0x93B6, 0xE68B, 0x93B7, 0xE68C, 0x93B8,
+	0xE68D, 0x93B9, 0xE68E, 0x93BA, 0xE68F, 0x93BB, 0xE690, 0x93BC,
+	0xE691, 0x93BD, 0xE692, 0x93BE, 0xE693, 0x93BF, 0xE694, 0x93C0,
+	0xE695, 0x93C1, 0xE696, 0x93C2, 0xE697, 0x93C3, 0xE698, 0x93C4,
+	0xE699, 0x93C5, 0xE69A, 0x93C6, 0xE69B, 0x93C7, 0xE69C, 0x93C8,
+	0xE69D, 0x93C9, 0xE69E, 0x93CB, 0xE69F, 0x93CC, 0xE6A0, 0x93CD,
+	0xE6A1, 0x5997, 0xE6A2, 0x59CA, 0xE6A3, 0x59AB, 0xE6A4, 0x599E,
+	0xE6A5, 0x59A4, 0xE6A6, 0x59D2, 0xE6A7, 0x59B2, 0xE6A8, 0x59AF,
+	0xE6A9, 0x59D7, 0xE6AA, 0x59BE, 0xE6AB, 0x5A05, 0xE6AC, 0x5A06,
+	0xE6AD, 0x59DD, 0xE6AE, 0x5A08, 0xE6AF, 0x59E3, 0xE6B0, 0x59D8,
+	0xE6B1, 0x59F9, 0xE6B2, 0x5A0C, 0xE6B3, 0x5A09, 0xE6B4, 0x5A32,
+	0xE6B5, 0x5A34, 0xE6B6, 0x5A11, 0xE6B7, 0x5A23, 0xE6B8, 0x5A13,
+	0xE6B9, 0x5A40, 0xE6BA, 0x5A67, 0xE6BB, 0x5A4A, 0xE6BC, 0x5A55,
+	0xE6BD, 0x5A3C, 0xE6BE, 0x5A62, 0xE6BF, 0x5A75, 0xE6C0, 0x80EC,
+	0xE6C1, 0x5AAA, 0xE6C2, 0x5A9B, 0xE6C3, 0x5A77, 0xE6C4, 0x5A7A,
+	0xE6C5, 0x5ABE, 0xE6C6, 0x5AEB, 0xE6C7, 0x5AB2, 0xE6C8, 0x5AD2,
+	0xE6C9, 0x5AD4, 0xE6CA, 0x5AB8, 0xE6CB, 0x5AE0, 0xE6CC, 0x5AE3,
+	0xE6CD, 0x5AF1, 0xE6CE, 0x5AD6, 0xE6CF, 0x5AE6, 0xE6D0, 0x5AD8,
+	0xE6D1, 0x5ADC, 0xE6D2, 0x5B09, 0xE6D3, 0x5B17, 0xE6D4, 0x5B16,
+	0xE6D5, 0x5B32, 0xE6D6, 0x5B37, 0xE6D7, 0x5B40, 0xE6D8, 0x5C15,
+	0xE6D9, 0x5C1C, 0xE6DA, 0x5B5A, 0xE6DB, 0x5B65, 0xE6DC, 0x5B73,
+	0xE6DD, 0x5B51, 0xE6DE, 0x5B53, 0xE6DF, 0x5B62, 0xE6E0, 0x9A75,
+	0xE6E1, 0x9A77, 0xE6E2, 0x9A78, 0xE6E3, 0x9A7A, 0xE6E4, 0x9A7F,
+	0xE6E5, 0x9A7D, 0xE6E6, 0x9A80, 0xE6E7, 0x9A81, 0xE6E8, 0x9A85,
+	0xE6E9, 0x9A88, 0xE6EA, 0x9A8A, 0xE6EB, 0x9A90, 0xE6EC, 0x9A92,
+	0xE6ED, 0x9A93, 0xE6EE, 0x9A96, 0xE6EF, 0x9A98, 0xE6F0, 0x9A9B,
+	0xE6F1, 0x9A9C, 0xE6F2, 0x9A9D, 0xE6F3, 0x9A9F, 0xE6F4, 0x9AA0,
+	0xE6F5, 0x9AA2, 0xE6F6, 0x9AA3, 0xE6F7, 0x9AA5, 0xE6F8, 0x9AA7,
+	0xE6F9, 0x7E9F, 0xE6FA, 0x7EA1, 0xE6FB, 0x7EA3, 0xE6FC, 0x7EA5,
+	0xE6FD, 0x7EA8, 0xE6FE, 0x7EA9, 0xE740, 0x93CE, 0xE741, 0x93CF,
+	0xE742, 0x93D0, 0xE743, 0x93D1, 0xE744, 0x93D2, 0xE745, 0x93D3,
+	0xE746, 0x93D4, 0xE747, 0x93D5, 0xE748, 0x93D7, 0xE749, 0x93D8,
+	0xE74A, 0x93D9, 0xE74B, 0x93DA, 0xE74C, 0x93DB, 0xE74D, 0x93DC,
+	0xE74E, 0x93DD, 0xE74F, 0x93DE, 0xE750, 0x93DF, 0xE751, 0x93E0,
+	0xE752, 0x93E1, 0xE753, 0x93E2, 0xE754, 0x93E3, 0xE755, 0x93E4,
+	0xE756, 0x93E5, 0xE757, 0x93E6, 0xE758, 0x93E7, 0xE759, 0x93E8,
+	0xE75A, 0x93E9, 0xE75B, 0x93EA, 0xE75C, 0x93EB, 0xE75D, 0x93EC,
+	0xE75E, 0x93ED, 0xE75F, 0x93EE, 0xE760, 0x93EF, 0xE761, 0x93F0,
+	0xE762, 0x93F1, 0xE763, 0x93F2, 0xE764, 0x93F3, 0xE765, 0x93F4,
+	0xE766, 0x93F5, 0xE767, 0x93F6, 0xE768, 0x93F7, 0xE769, 0x93F8,
+	0xE76A, 0x93F9, 0xE76B, 0x93FA, 0xE76C, 0x93FB, 0xE76D, 0x93FC,
+	0xE76E, 0x93FD, 0xE76F, 0x93FE, 0xE770, 0x93FF, 0xE771, 0x9400,
+	0xE772, 0x9401, 0xE773, 0x9402, 0xE774, 0x9403, 0xE775, 0x9404,
+	0xE776, 0x9405, 0xE777, 0x9406, 0xE778, 0x9407, 0xE779, 0x9408,
+	0xE77A, 0x9409, 0xE77B, 0x940A, 0xE77C, 0x940B, 0xE77D, 0x940C,
+	0xE77E, 0x940D, 0xE780, 0x940E, 0xE781, 0x940F, 0xE782, 0x9410,
+	0xE783, 0x9411, 0xE784, 0x9412, 0xE785, 0x9413, 0xE786, 0x9414,
+	0xE787, 0x9415, 0xE788, 0x9416, 0xE789, 0x9417, 0xE78A, 0x9418,
+	0xE78B, 0x9419, 0xE78C, 0x941A, 0xE78D, 0x941B, 0xE78E, 0x941C,
+	0xE78F, 0x941D, 0xE790, 0x941E, 0xE791, 0x941F, 0xE792, 0x9420,
+	0xE793, 0x9421, 0xE794, 0x9422, 0xE795, 0x9423, 0xE796, 0x9424,
+	0xE797, 0x9425, 0xE798, 0x9426, 0xE799, 0x9427, 0xE79A, 0x9428,
+	0xE79B, 0x9429, 0xE79C, 0x942A, 0xE79D, 0x942B, 0xE79E, 0x942C,
+	0xE79F, 0x942D, 0xE7A0, 0x942E, 0xE7A1, 0x7EAD, 0xE7A2, 0x7EB0,
+	0xE7A3, 0x7EBE, 0xE7A4, 0x7EC0, 0xE7A5, 0x7EC1, 0xE7A6, 0x7EC2,
+	0xE7A7, 0x7EC9, 0xE7A8, 0x7ECB, 0xE7A9, 0x7ECC, 0xE7AA, 0x7ED0,
+	0xE7AB, 0x7ED4, 0xE7AC, 0x7ED7, 0xE7AD, 0x7EDB, 0xE7AE, 0x7EE0,
+	0xE7AF, 0x7EE1, 0xE7B0, 0x7EE8, 0xE7B1, 0x7EEB, 0xE7B2, 0x7EEE,
+	0xE7B3, 0x7EEF, 0xE7B4, 0x7EF1, 0xE7B5, 0x7EF2, 0xE7B6, 0x7F0D,
+	0xE7B7, 0x7EF6, 0xE7B8, 0x7EFA, 0xE7B9, 0x7EFB, 0xE7BA, 0x7EFE,
+	0xE7BB, 0x7F01, 0xE7BC, 0x7F02, 0xE7BD, 0x7F03, 0xE7BE, 0x7F07,
+	0xE7BF, 0x7F08, 0xE7C0, 0x7F0B, 0xE7C1, 0x7F0C, 0xE7C2, 0x7F0F,
+	0xE7C3, 0x7F11, 0xE7C4, 0x7F12, 0xE7C5, 0x7F17, 0xE7C6, 0x7F19,
+	0xE7C7, 0x7F1C, 0xE7C8, 0x7F1B, 0xE7C9, 0x7F1F, 0xE7CA, 0x7F21,
+	0xE7CB, 0x7F22, 0xE7CC, 0x7F23, 0xE7CD, 0x7F24, 0xE7CE, 0x7F25,
+	0xE7CF, 0x7F26, 0xE7D0, 0x7F27, 0xE7D1, 0x7F2A, 0xE7D2, 0x7F2B,
+	0xE7D3, 0x7F2C, 0xE7D4, 0x7F2D, 0xE7D5, 0x7F2F, 0xE7D6, 0x7F30,
+	0xE7D7, 0x7F31, 0xE7D8, 0x7F32, 0xE7D9, 0x7F33, 0xE7DA, 0x7F35,
+	0xE7DB, 0x5E7A, 0xE7DC, 0x757F, 0xE7DD, 0x5DDB, 0xE7DE, 0x753E,
+	0xE7DF, 0x9095, 0xE7E0, 0x738E, 0xE7E1, 0x7391, 0xE7E2, 0x73AE,
+	0xE7E3, 0x73A2, 0xE7E4, 0x739F, 0xE7E5, 0x73CF, 0xE7E6, 0x73C2,
+	0xE7E7, 0x73D1, 0xE7E8, 0x73B7, 0xE7E9, 0x73B3, 0xE7EA, 0x73C0,
+	0xE7EB, 0x73C9, 0xE7EC, 0x73C8, 0xE7ED, 0x73E5, 0xE7EE, 0x73D9,
+	0xE7EF, 0x987C, 0xE7F0, 0x740A, 0xE7F1, 0x73E9, 0xE7F2, 0x73E7,
+	0xE7F3, 0x73DE, 0xE7F4, 0x73BA, 0xE7F5, 0x73F2, 0xE7F6, 0x740F,
+	0xE7F7, 0x742A, 0xE7F8, 0x745B, 0xE7F9, 0x7426, 0xE7FA, 0x7425,
+	0xE7FB, 0x7428, 0xE7FC, 0x7430, 0xE7FD, 0x742E, 0xE7FE, 0x742C,
+	0xE840, 0x942F, 0xE841, 0x9430, 0xE842, 0x9431, 0xE843, 0x9432,
+	0xE844, 0x9433, 0xE845, 0x9434, 0xE846, 0x9435, 0xE847, 0x9436,
+	0xE848, 0x9437, 0xE849, 0x9438, 0xE84A, 0x9439, 0xE84B, 0x943A,
+	0xE84C, 0x943B, 0xE84D, 0x943C, 0xE84E, 0x943D, 0xE84F, 0x943F,
+	0xE850, 0x9440, 0xE851, 0x9441, 0xE852, 0x9442, 0xE853, 0x9443,
+	0xE854, 0x9444, 0xE855, 0x9445, 0xE856, 0x9446, 0xE857, 0x9447,
+	0xE858, 0x9448, 0xE859, 0x9449, 0xE85A, 0x944A, 0xE85B, 0x944B,
+	0xE85C, 0x944C, 0xE85D, 0x944D, 0xE85E, 0x944E, 0xE85F, 0x944F,
+	0xE860, 0x9450, 0xE861, 0x9451, 0xE862, 0x9452, 0xE863, 0x9453,
+	0xE864, 0x9454, 0xE865, 0x9455, 0xE866, 0x9456, 0xE867, 0x9457,
+	0xE868, 0x9458, 0xE869, 0x9459, 0xE86A, 0x945A, 0xE86B, 0x945B,
+	0xE86C, 0x945C, 0xE86D, 0x945D, 0xE86E, 0x945E, 0xE86F, 0x945F,
+	0xE870, 0x9460, 0xE871, 0x9461, 0xE872, 0x9462, 0xE873, 0x9463,
+	0xE874, 0x9464, 0xE875, 0x9465, 0xE876, 0x9466, 0xE877, 0x9467,
+	0xE878, 0x9468, 0xE879, 0x9469, 0xE87A, 0x946A, 0xE87B, 0x946C,
+	0xE87C, 0x946D, 0xE87D, 0x946E, 0xE87E, 0x946F, 0xE880, 0x9470,
+	0xE881, 0x9471, 0xE882, 0x9472, 0xE883, 0x9473, 0xE884, 0x9474,
+	0xE885, 0x9475, 0xE886, 0x9476, 0xE887, 0x9477, 0xE888, 0x9478,
+	0xE889, 0x9479, 0xE88A, 0x947A, 0xE88B, 0x947B, 0xE88C, 0x947C,
+	0xE88D, 0x947D, 0xE88E, 0x947E, 0xE88F, 0x947F, 0xE890, 0x9480,
+	0xE891, 0x9481, 0xE892, 0x9482, 0xE893, 0x9483, 0xE894, 0x9484,
+	0xE895, 0x9491, 0xE896, 0x9496, 0xE897, 0x9498, 0xE898, 0x94C7,
+	0xE899, 0x94CF, 0xE89A, 0x94D3, 0xE89B, 0x94D4, 0xE89C, 0x94DA,
+	0xE89D, 0x94E6, 0xE89E, 0x94FB, 0xE89F, 0x951C, 0xE8A0, 0x9520,
+	0xE8A1, 0x741B, 0xE8A2, 0x741A, 0xE8A3, 0x7441, 0xE8A4, 0x745C,
+	0xE8A5, 0x7457, 0xE8A6, 0x7455, 0xE8A7, 0x7459, 0xE8A8, 0x7477,
+	0xE8A9, 0x746D, 0xE8AA, 0x747E, 0xE8AB, 0x749C, 0xE8AC, 0x748E,
+	0xE8AD, 0x7480, 0xE8AE, 0x7481, 0xE8AF, 0x7487, 0xE8B0, 0x748B,
+	0xE8B1, 0x749E, 0xE8B2, 0x74A8, 0xE8B3, 0x74A9, 0xE8B4, 0x7490,
+	0xE8B5, 0x74A7, 0xE8B6, 0x74D2, 0xE8B7, 0x74BA, 0xE8B8, 0x97EA,
+	0xE8B9, 0x97EB, 0xE8BA, 0x97EC, 0xE8BB, 0x674C, 0xE8BC, 0x6753,
+	0xE8BD, 0x675E, 0xE8BE, 0x6748, 0xE8BF, 0x6769, 0xE8C0, 0x67A5,
+	0xE8C1, 0x6787, 0xE8C2, 0x676A, 0xE8C3, 0x6773, 0xE8C4, 0x6798,
+	0xE8C5, 0x67A7, 0xE8C6, 0x6775, 0xE8C7, 0x67A8, 0xE8C8, 0x679E,
+	0xE8C9, 0x67AD, 0xE8CA, 0x678B, 0xE8CB, 0x6777, 0xE8CC, 0x677C,
+	0xE8CD, 0x67F0, 0xE8CE, 0x6809, 0xE8CF, 0x67D8, 0xE8D0, 0x680A,
+	0xE8D1, 0x67E9, 0xE8D2, 0x67B0, 0xE8D3, 0x680C, 0xE8D4, 0x67D9,
+	0xE8D5, 0x67B5, 0xE8D6, 0x67DA, 0xE8D7, 0x67B3, 0xE8D8, 0x67DD,
+	0xE8D9, 0x6800, 0xE8DA, 0x67C3, 0xE8DB, 0x67B8, 0xE8DC, 0x67E2,
+	0xE8DD, 0x680E, 0xE8DE, 0x67C1, 0xE8DF, 0x67FD, 0xE8E0, 0x6832,
+	0xE8E1, 0x6833, 0xE8E2, 0x6860, 0xE8E3, 0x6861, 0xE8E4, 0x684E,
+	0xE8E5, 0x6862, 0xE8E6, 0x6844, 0xE8E7, 0x6864, 0xE8E8, 0x6883,
+	0xE8E9, 0x681D, 0xE8EA, 0x6855, 0xE8EB, 0x6866, 0xE8EC, 0x6841,
+	0xE8ED, 0x6867, 0xE8EE, 0x6840, 0xE8EF, 0x683E, 0xE8F0, 0x684A,
+	0xE8F1, 0x6849, 0xE8F2, 0x6829, 0xE8F3, 0x68B5, 0xE8F4, 0x688F,
+	0xE8F5, 0x6874, 0xE8F6, 0x6877, 0xE8F7, 0x6893, 0xE8F8, 0x686B,
+	0xE8F9, 0x68C2, 0xE8FA, 0x696E, 0xE8FB, 0x68FC, 0xE8FC, 0x691F,
+	0xE8FD, 0x6920, 0xE8FE, 0x68F9, 0xE940, 0x9527, 0xE941, 0x9533,
+	0xE942, 0x953D, 0xE943, 0x9543, 0xE944, 0x9548, 0xE945, 0x954B,
+	0xE946, 0x9555, 0xE947, 0x955A, 0xE948, 0x9560, 0xE949, 0x956E,
+	0xE94A, 0x9574, 0xE94B, 0x9575, 0xE94C, 0x9577, 0xE94D, 0x9578,
+	0xE94E, 0x9579, 0xE94F, 0x957A, 0xE950, 0x957B, 0xE951, 0x957C,
+	0xE952, 0x957D, 0xE953, 0x957E, 0xE954, 0x9580, 0xE955, 0x9581,
+	0xE956, 0x9582, 0xE957, 0x9583, 0xE958, 0x9584, 0xE959, 0x9585,
+	0xE95A, 0x9586, 0xE95B, 0x9587, 0xE95C, 0x9588, 0xE95D, 0x9589,
+	0xE95E, 0x958A, 0xE95F, 0x958B, 0xE960, 0x958C, 0xE961, 0x958D,
+	0xE962, 0x958E, 0xE963, 0x958F, 0xE964, 0x9590, 0xE965, 0x9591,
+	0xE966, 0x9592, 0xE967, 0x9593, 0xE968, 0x9594, 0xE969, 0x9595,
+	0xE96A, 0x9596, 0xE96B, 0x9597, 0xE96C, 0x9598, 0xE96D, 0x9599,
+	0xE96E, 0x959A, 0xE96F, 0x959B, 0xE970, 0x959C, 0xE971, 0x959D,
+	0xE972, 0x959E, 0xE973, 0x959F, 0xE974, 0x95A0, 0xE975, 0x95A1,
+	0xE976, 0x95A2, 0xE977, 0x95A3, 0xE978, 0x95A4, 0xE979, 0x95A5,
+	0xE97A, 0x95A6, 0xE97B, 0x95A7, 0xE97C, 0x95A8, 0xE97D, 0x95A9,
+	0xE97E, 0x95AA, 0xE980, 0x95AB, 0xE981, 0x95AC, 0xE982, 0x95AD,
+	0xE983, 0x95AE, 0xE984, 0x95AF, 0xE985, 0x95B0, 0xE986, 0x95B1,
+	0xE987, 0x95B2, 0xE988, 0x95B3, 0xE989, 0x95B4, 0xE98A, 0x95B5,
+	0xE98B, 0x95B6, 0xE98C, 0x95B7, 0xE98D, 0x95B8, 0xE98E, 0x95B9,
+	0xE98F, 0x95BA, 0xE990, 0x95BB, 0xE991, 0x95BC, 0xE992, 0x95BD,
+	0xE993, 0x95BE, 0xE994, 0x95BF, 0xE995, 0x95C0, 0xE996, 0x95C1,
+	0xE997, 0x95C2, 0xE998, 0x95C3, 0xE999, 0x95C4, 0xE99A, 0x95C5,
+	0xE99B, 0x95C6, 0xE99C, 0x95C7, 0xE99D, 0x95C8, 0xE99E, 0x95C9,
+	0xE99F, 0x95CA, 0xE9A0, 0x95CB, 0xE9A1, 0x6924, 0xE9A2, 0x68F0,
+	0xE9A3, 0x690B, 0xE9A4, 0x6901, 0xE9A5, 0x6957, 0xE9A6, 0x68E3,
+	0xE9A7, 0x6910, 0xE9A8, 0x6971, 0xE9A9, 0x6939, 0xE9AA, 0x6960,
+	0xE9AB, 0x6942, 0xE9AC, 0x695D, 0xE9AD, 0x6984, 0xE9AE, 0x696B,
+	0xE9AF, 0x6980, 0xE9B0, 0x6998, 0xE9B1, 0x6978, 0xE9B2, 0x6934,
+	0xE9B3, 0x69CC, 0xE9B4, 0x6987, 0xE9B5, 0x6988, 0xE9B6, 0x69CE,
+	0xE9B7, 0x6989, 0xE9B8, 0x6966, 0xE9B9, 0x6963, 0xE9BA, 0x6979,
+	0xE9BB, 0x699B, 0xE9BC, 0x69A7, 0xE9BD, 0x69BB, 0xE9BE, 0x69AB,
+	0xE9BF, 0x69AD, 0xE9C0, 0x69D4, 0xE9C1, 0x69B1, 0xE9C2, 0x69C1,
+	0xE9C3, 0x69CA, 0xE9C4, 0x69DF, 0xE9C5, 0x6995, 0xE9C6, 0x69E0,
+	0xE9C7, 0x698D, 0xE9C8, 0x69FF, 0xE9C9, 0x6A2F, 0xE9CA, 0x69ED,
+	0xE9CB, 0x6A17, 0xE9CC, 0x6A18, 0xE9CD, 0x6A65, 0xE9CE, 0x69F2,
+	0xE9CF, 0x6A44, 0xE9D0, 0x6A3E, 0xE9D1, 0x6AA0, 0xE9D2, 0x6A50,
+	0xE9D3, 0x6A5B, 0xE9D4, 0x6A35, 0xE9D5, 0x6A8E, 0xE9D6, 0x6A79,
+	0xE9D7, 0x6A3D, 0xE9D8, 0x6A28, 0xE9D9, 0x6A58, 0xE9DA, 0x6A7C,
+	0xE9DB, 0x6A91, 0xE9DC, 0x6A90, 0xE9DD, 0x6AA9, 0xE9DE, 0x6A97,
+	0xE9DF, 0x6AAB, 0xE9E0, 0x7337, 0xE9E1, 0x7352, 0xE9E2, 0x6B81,
+	0xE9E3, 0x6B82, 0xE9E4, 0x6B87, 0xE9E5, 0x6B84, 0xE9E6, 0x6B92,
+	0xE9E7, 0x6B93, 0xE9E8, 0x6B8D, 0xE9E9, 0x6B9A, 0xE9EA, 0x6B9B,
+	0xE9EB, 0x6BA1, 0xE9EC, 0x6BAA, 0xE9ED, 0x8F6B, 0xE9EE, 0x8F6D,
+	0xE9EF, 0x8F71, 0xE9F0, 0x8F72, 0xE9F1, 0x8F73, 0xE9F2, 0x8F75,
+	0xE9F3, 0x8F76, 0xE9F4, 0x8F78, 0xE9F5, 0x8F77, 0xE9F6, 0x8F79,
+	0xE9F7, 0x8F7A, 0xE9F8, 0x8F7C, 0xE9F9, 0x8F7E, 0xE9FA, 0x8F81,
+	0xE9FB, 0x8F82, 0xE9FC, 0x8F84, 0xE9FD, 0x8F87, 0xE9FE, 0x8F8B,
+	0xEA40, 0x95CC, 0xEA41, 0x95CD, 0xEA42, 0x95CE, 0xEA43, 0x95CF,
+	0xEA44, 0x95D0, 0xEA45, 0x95D1, 0xEA46, 0x95D2, 0xEA47, 0x95D3,
+	0xEA48, 0x95D4, 0xEA49, 0x95D5, 0xEA4A, 0x95D6, 0xEA4B, 0x95D7,
+	0xEA4C, 0x95D8, 0xEA4D, 0x95D9, 0xEA4E, 0x95DA, 0xEA4F, 0x95DB,
+	0xEA50, 0x95DC, 0xEA51, 0x95DD, 0xEA52, 0x95DE, 0xEA53, 0x95DF,
+	0xEA54, 0x95E0, 0xEA55, 0x95E1, 0xEA56, 0x95E2, 0xEA57, 0x95E3,
+	0xEA58, 0x95E4, 0xEA59, 0x95E5, 0xEA5A, 0x95E6, 0xEA5B, 0x95E7,
+	0xEA5C, 0x95EC, 0xEA5D, 0x95FF, 0xEA5E, 0x9607, 0xEA5F, 0x9613,
+	0xEA60, 0x9618, 0xEA61, 0x961B, 0xEA62, 0x961E, 0xEA63, 0x9620,
+	0xEA64, 0x9623, 0xEA65, 0x9624, 0xEA66, 0x9625, 0xEA67, 0x9626,
+	0xEA68, 0x9627, 0xEA69, 0x9628, 0xEA6A, 0x9629, 0xEA6B, 0x962B,
+	0xEA6C, 0x962C, 0xEA6D, 0x962D, 0xEA6E, 0x962F, 0xEA6F, 0x9630,
+	0xEA70, 0x9637, 0xEA71, 0x9638, 0xEA72, 0x9639, 0xEA73, 0x963A,
+	0xEA74, 0x963E, 0xEA75, 0x9641, 0xEA76, 0x9643, 0xEA77, 0x964A,
+	0xEA78, 0x964E, 0xEA79, 0x964F, 0xEA7A, 0x9651, 0xEA7B, 0x9652,
+	0xEA7C, 0x9653, 0xEA7D, 0x9656, 0xEA7E, 0x9657, 0xEA80, 0x9658,
+	0xEA81, 0x9659, 0xEA82, 0x965A, 0xEA83, 0x965C, 0xEA84, 0x965D,
+	0xEA85, 0x965E, 0xEA86, 0x9660, 0xEA87, 0x9663, 0xEA88, 0x9665,
+	0xEA89, 0x9666, 0xEA8A, 0x966B, 0xEA8B, 0x966D, 0xEA8C, 0x966E,
+	0xEA8D, 0x966F, 0xEA8E, 0x9670, 0xEA8F, 0x9671, 0xEA90, 0x9673,
+	0xEA91, 0x9678, 0xEA92, 0x9679, 0xEA93, 0x967A, 0xEA94, 0x967B,
+	0xEA95, 0x967C, 0xEA96, 0x967D, 0xEA97, 0x967E, 0xEA98, 0x967F,
+	0xEA99, 0x9680, 0xEA9A, 0x9681, 0xEA9B, 0x9682, 0xEA9C, 0x9683,
+	0xEA9D, 0x9684, 0xEA9E, 0x9687, 0xEA9F, 0x9689, 0xEAA0, 0x968A,
+	0xEAA1, 0x8F8D, 0xEAA2, 0x8F8E, 0xEAA3, 0x8F8F, 0xEAA4, 0x8F98,
+	0xEAA5, 0x8F9A, 0xEAA6, 0x8ECE, 0xEAA7, 0x620B, 0xEAA8, 0x6217,
+	0xEAA9, 0x621B, 0xEAAA, 0x621F, 0xEAAB, 0x6222, 0xEAAC, 0x6221,
+	0xEAAD, 0x6225, 0xEAAE, 0x6224, 0xEAAF, 0x622C, 0xEAB0, 0x81E7,
+	0xEAB1, 0x74EF, 0xEAB2, 0x74F4, 0xEAB3, 0x74FF, 0xEAB4, 0x750F,
+	0xEAB5, 0x7511, 0xEAB6, 0x7513, 0xEAB7, 0x6534, 0xEAB8, 0x65EE,
+	0xEAB9, 0x65EF, 0xEABA, 0x65F0, 0xEABB, 0x660A, 0xEABC, 0x6619,
+	0xEABD, 0x6772, 0xEABE, 0x6603, 0xEABF, 0x6615, 0xEAC0, 0x6600,
+	0xEAC1, 0x7085, 0xEAC2, 0x66F7, 0xEAC3, 0x661D, 0xEAC4, 0x6634,
+	0xEAC5, 0x6631, 0xEAC6, 0x6636, 0xEAC7, 0x6635, 0xEAC8, 0x8006,
+	0xEAC9, 0x665F, 0xEACA, 0x6654, 0xEACB, 0x6641, 0xEACC, 0x664F,
+	0xEACD, 0x6656, 0xEACE, 0x6661, 0xEACF, 0x6657, 0xEAD0, 0x6677,
+	0xEAD1, 0x6684, 0xEAD2, 0x668C, 0xEAD3, 0x66A7, 0xEAD4, 0x669D,
+	0xEAD5, 0x66BE, 0xEAD6, 0x66DB, 0xEAD7, 0x66DC, 0xEAD8, 0x66E6,
+	0xEAD9, 0x66E9, 0xEADA, 0x8D32, 0xEADB, 0x8D33, 0xEADC, 0x8D36,
+	0xEADD, 0x8D3B, 0xEADE, 0x8D3D, 0xEADF, 0x8D40, 0xEAE0, 0x8D45,
+	0xEAE1, 0x8D46, 0xEAE2, 0x8D48, 0xEAE3, 0x8D49, 0xEAE4, 0x8D47,
+	0xEAE5, 0x8D4D, 0xEAE6, 0x8D55, 0xEAE7, 0x8D59, 0xEAE8, 0x89C7,
+	0xEAE9, 0x89CA, 0xEAEA, 0x89CB, 0xEAEB, 0x89CC, 0xEAEC, 0x89CE,
+	0xEAED, 0x89CF, 0xEAEE, 0x89D0, 0xEAEF, 0x89D1, 0xEAF0, 0x726E,
+	0xEAF1, 0x729F, 0xEAF2, 0x725D, 0xEAF3, 0x7266, 0xEAF4, 0x726F,
+	0xEAF5, 0x727E, 0xEAF6, 0x727F, 0xEAF7, 0x7284, 0xEAF8, 0x728B,
+	0xEAF9, 0x728D, 0xEAFA, 0x728F, 0xEAFB, 0x7292, 0xEAFC, 0x6308,
+	0xEAFD, 0x6332, 0xEAFE, 0x63B0, 0xEB40, 0x968C, 0xEB41, 0x968E,
+	0xEB42, 0x9691, 0xEB43, 0x9692, 0xEB44, 0x9693, 0xEB45, 0x9695,
+	0xEB46, 0x9696, 0xEB47, 0x969A, 0xEB48, 0x969B, 0xEB49, 0x969D,
+	0xEB4A, 0x969E, 0xEB4B, 0x969F, 0xEB4C, 0x96A0, 0xEB4D, 0x96A1,
+	0xEB4E, 0x96A2, 0xEB4F, 0x96A3, 0xEB50, 0x96A4, 0xEB51, 0x96A5,
+	0xEB52, 0x96A6, 0xEB53, 0x96A8, 0xEB54, 0x96A9, 0xEB55, 0x96AA,
+	0xEB56, 0x96AB, 0xEB57, 0x96AC, 0xEB58, 0x96AD, 0xEB59, 0x96AE,
+	0xEB5A, 0x96AF, 0xEB5B, 0x96B1, 0xEB5C, 0x96B2, 0xEB5D, 0x96B4,
+	0xEB5E, 0x96B5, 0xEB5F, 0x96B7, 0xEB60, 0x96B8, 0xEB61, 0x96BA,
+	0xEB62, 0x96BB, 0xEB63, 0x96BF, 0xEB64, 0x96C2, 0xEB65, 0x96C3,
+	0xEB66, 0x96C8, 0xEB67, 0x96CA, 0xEB68, 0x96CB, 0xEB69, 0x96D0,
+	0xEB6A, 0x96D1, 0xEB6B, 0x96D3, 0xEB6C, 0x96D4, 0xEB6D, 0x96D6,
+	0xEB6E, 0x96D7, 0xEB6F, 0x96D8, 0xEB70, 0x96D9, 0xEB71, 0x96DA,
+	0xEB72, 0x96DB, 0xEB73, 0x96DC, 0xEB74, 0x96DD, 0xEB75, 0x96DE,
+	0xEB76, 0x96DF, 0xEB77, 0x96E1, 0xEB78, 0x96E2, 0xEB79, 0x96E3,
+	0xEB7A, 0x96E4, 0xEB7B, 0x96E5, 0xEB7C, 0x96E6, 0xEB7D, 0x96E7,
+	0xEB7E, 0x96EB, 0xEB80, 0x96EC, 0xEB81, 0x96ED, 0xEB82, 0x96EE,
+	0xEB83, 0x96F0, 0xEB84, 0x96F1, 0xEB85, 0x96F2, 0xEB86, 0x96F4,
+	0xEB87, 0x96F5, 0xEB88, 0x96F8, 0xEB89, 0x96FA, 0xEB8A, 0x96FB,
+	0xEB8B, 0x96FC, 0xEB8C, 0x96FD, 0xEB8D, 0x96FF, 0xEB8E, 0x9702,
+	0xEB8F, 0x9703, 0xEB90, 0x9705, 0xEB91, 0x970A, 0xEB92, 0x970B,
+	0xEB93, 0x970C, 0xEB94, 0x9710, 0xEB95, 0x9711, 0xEB96, 0x9712,
+	0xEB97, 0x9714, 0xEB98, 0x9715, 0xEB99, 0x9717, 0xEB9A, 0x9718,
+	0xEB9B, 0x9719, 0xEB9C, 0x971A, 0xEB9D, 0x971B, 0xEB9E, 0x971D,
+	0xEB9F, 0x971F, 0xEBA0, 0x9720, 0xEBA1, 0x643F, 0xEBA2, 0x64D8,
+	0xEBA3, 0x8004, 0xEBA4, 0x6BEA, 0xEBA5, 0x6BF3, 0xEBA6, 0x6BFD,
+	0xEBA7, 0x6BF5, 0xEBA8, 0x6BF9, 0xEBA9, 0x6C05, 0xEBAA, 0x6C07,
+	0xEBAB, 0x6C06, 0xEBAC, 0x6C0D, 0xEBAD, 0x6C15, 0xEBAE, 0x6C18,
+	0xEBAF, 0x6C19, 0xEBB0, 0x6C1A, 0xEBB1, 0x6C21, 0xEBB2, 0x6C29,
+	0xEBB3, 0x6C24, 0xEBB4, 0x6C2A, 0xEBB5, 0x6C32, 0xEBB6, 0x6535,
+	0xEBB7, 0x6555, 0xEBB8, 0x656B, 0xEBB9, 0x724D, 0xEBBA, 0x7252,
+	0xEBBB, 0x7256, 0xEBBC, 0x7230, 0xEBBD, 0x8662, 0xEBBE, 0x5216,
+	0xEBBF, 0x809F, 0xEBC0, 0x809C, 0xEBC1, 0x8093, 0xEBC2, 0x80BC,
+	0xEBC3, 0x670A, 0xEBC4, 0x80BD, 0xEBC5, 0x80B1, 0xEBC6, 0x80AB,
+	0xEBC7, 0x80AD, 0xEBC8, 0x80B4, 0xEBC9, 0x80B7, 0xEBCA, 0x80E7,
+	0xEBCB, 0x80E8, 0xEBCC, 0x80E9, 0xEBCD, 0x80EA, 0xEBCE, 0x80DB,
+	0xEBCF, 0x80C2, 0xEBD0, 0x80C4, 0xEBD1, 0x80D9, 0xEBD2, 0x80CD,
+	0xEBD3, 0x80D7, 0xEBD4, 0x6710, 0xEBD5, 0x80DD, 0xEBD6, 0x80EB,
+	0xEBD7, 0x80F1, 0xEBD8, 0x80F4, 0xEBD9, 0x80ED, 0xEBDA, 0x810D,
+	0xEBDB, 0x810E, 0xEBDC, 0x80F2, 0xEBDD, 0x80FC, 0xEBDE, 0x6715,
+	0xEBDF, 0x8112, 0xEBE0, 0x8C5A, 0xEBE1, 0x8136, 0xEBE2, 0x811E,
+	0xEBE3, 0x812C, 0xEBE4, 0x8118, 0xEBE5, 0x8132, 0xEBE6, 0x8148,
+	0xEBE7, 0x814C, 0xEBE8, 0x8153, 0xEBE9, 0x8174, 0xEBEA, 0x8159,
+	0xEBEB, 0x815A, 0xEBEC, 0x8171, 0xEBED, 0x8160, 0xEBEE, 0x8169,
+	0xEBEF, 0x817C, 0xEBF0, 0x817D, 0xEBF1, 0x816D, 0xEBF2, 0x8167,
+	0xEBF3, 0x584D, 0xEBF4, 0x5AB5, 0xEBF5, 0x8188, 0xEBF6, 0x8182,
+	0xEBF7, 0x8191, 0xEBF8, 0x6ED5, 0xEBF9, 0x81A3, 0xEBFA, 0x81AA,
+	0xEBFB, 0x81CC, 0xEBFC, 0x6726, 0xEBFD, 0x81CA, 0xEBFE, 0x81BB,
+	0xEC40, 0x9721, 0xEC41, 0x9722, 0xEC42, 0x9723, 0xEC43, 0x9724,
+	0xEC44, 0x9725, 0xEC45, 0x9726, 0xEC46, 0x9727, 0xEC47, 0x9728,
+	0xEC48, 0x9729, 0xEC49, 0x972B, 0xEC4A, 0x972C, 0xEC4B, 0x972E,
+	0xEC4C, 0x972F, 0xEC4D, 0x9731, 0xEC4E, 0x9733, 0xEC4F, 0x9734,
+	0xEC50, 0x9735, 0xEC51, 0x9736, 0xEC52, 0x9737, 0xEC53, 0x973A,
+	0xEC54, 0x973B, 0xEC55, 0x973C, 0xEC56, 0x973D, 0xEC57, 0x973F,
+	0xEC58, 0x9740, 0xEC59, 0x9741, 0xEC5A, 0x9742, 0xEC5B, 0x9743,
+	0xEC5C, 0x9744, 0xEC5D, 0x9745, 0xEC5E, 0x9746, 0xEC5F, 0x9747,
+	0xEC60, 0x9748, 0xEC61, 0x9749, 0xEC62, 0x974A, 0xEC63, 0x974B,
+	0xEC64, 0x974C, 0xEC65, 0x974D, 0xEC66, 0x974E, 0xEC67, 0x974F,
+	0xEC68, 0x9750, 0xEC69, 0x9751, 0xEC6A, 0x9754, 0xEC6B, 0x9755,
+	0xEC6C, 0x9757, 0xEC6D, 0x9758, 0xEC6E, 0x975A, 0xEC6F, 0x975C,
+	0xEC70, 0x975D, 0xEC71, 0x975F, 0xEC72, 0x9763, 0xEC73, 0x9764,
+	0xEC74, 0x9766, 0xEC75, 0x9767, 0xEC76, 0x9768, 0xEC77, 0x976A,
+	0xEC78, 0x976B, 0xEC79, 0x976C, 0xEC7A, 0x976D, 0xEC7B, 0x976E,
+	0xEC7C, 0x976F, 0xEC7D, 0x9770, 0xEC7E, 0x9771, 0xEC80, 0x9772,
+	0xEC81, 0x9775, 0xEC82, 0x9777, 0xEC83, 0x9778, 0xEC84, 0x9779,
+	0xEC85, 0x977A, 0xEC86, 0x977B, 0xEC87, 0x977D, 0xEC88, 0x977E,
+	0xEC89, 0x977F, 0xEC8A, 0x9780, 0xEC8B, 0x9781, 0xEC8C, 0x9782,
+	0xEC8D, 0x9783, 0xEC8E, 0x9784, 0xEC8F, 0x9786, 0xEC90, 0x9787,
+	0xEC91, 0x9788, 0xEC92, 0x9789, 0xEC93, 0x978A, 0xEC94, 0x978C,
+	0xEC95, 0x978E, 0xEC96, 0x978F, 0xEC97, 0x9790, 0xEC98, 0x9793,
+	0xEC99, 0x9795, 0xEC9A, 0x9796, 0xEC9B, 0x9797, 0xEC9C, 0x9799,
+	0xEC9D, 0x979A, 0xEC9E, 0x979B, 0xEC9F, 0x979C, 0xECA0, 0x979D,
+	0xECA1, 0x81C1, 0xECA2, 0x81A6, 0xECA3, 0x6B24, 0xECA4, 0x6B37,
+	0xECA5, 0x6B39, 0xECA6, 0x6B43, 0xECA7, 0x6B46, 0xECA8, 0x6B59,
+	0xECA9, 0x98D1, 0xECAA, 0x98D2, 0xECAB, 0x98D3, 0xECAC, 0x98D5,
+	0xECAD, 0x98D9, 0xECAE, 0x98DA, 0xECAF, 0x6BB3, 0xECB0, 0x5F40,
+	0xECB1, 0x6BC2, 0xECB2, 0x89F3, 0xECB3, 0x6590, 0xECB4, 0x9F51,
+	0xECB5, 0x6593, 0xECB6, 0x65BC, 0xECB7, 0x65C6, 0xECB8, 0x65C4,
+	0xECB9, 0x65C3, 0xECBA, 0x65CC, 0xECBB, 0x65CE, 0xECBC, 0x65D2,
+	0xECBD, 0x65D6, 0xECBE, 0x7080, 0xECBF, 0x709C, 0xECC0, 0x7096,
+	0xECC1, 0x709D, 0xECC2, 0x70BB, 0xECC3, 0x70C0, 0xECC4, 0x70B7,
+	0xECC5, 0x70AB, 0xECC6, 0x70B1, 0xECC7, 0x70E8, 0xECC8, 0x70CA,
+	0xECC9, 0x7110, 0xECCA, 0x7113, 0xECCB, 0x7116, 0xECCC, 0x712F,
+	0xECCD, 0x7131, 0xECCE, 0x7173, 0xECCF, 0x715C, 0xECD0, 0x7168,
+	0xECD1, 0x7145, 0xECD2, 0x7172, 0xECD3, 0x714A, 0xECD4, 0x7178,
+	0xECD5, 0x717A, 0xECD6, 0x7198, 0xECD7, 0x71B3, 0xECD8, 0x71B5,
+	0xECD9, 0x71A8, 0xECDA, 0x71A0, 0xECDB, 0x71E0, 0xECDC, 0x71D4,
+	0xECDD, 0x71E7, 0xECDE, 0x71F9, 0xECDF, 0x721D, 0xECE0, 0x7228,
+	0xECE1, 0x706C, 0xECE2, 0x7118, 0xECE3, 0x7166, 0xECE4, 0x71B9,
+	0xECE5, 0x623E, 0xECE6, 0x623D, 0xECE7, 0x6243, 0xECE8, 0x6248,
+	0xECE9, 0x6249, 0xECEA, 0x793B, 0xECEB, 0x7940, 0xECEC, 0x7946,
+	0xECED, 0x7949, 0xECEE, 0x795B, 0xECEF, 0x795C, 0xECF0, 0x7953,
+	0xECF1, 0x795A, 0xECF2, 0x7962, 0xECF3, 0x7957, 0xECF4, 0x7960,
+	0xECF5, 0x796F, 0xECF6, 0x7967, 0xECF7, 0x797A, 0xECF8, 0x7985,
+	0xECF9, 0x798A, 0xECFA, 0x799A, 0xECFB, 0x79A7, 0xECFC, 0x79B3,
+	0xECFD, 0x5FD1, 0xECFE, 0x5FD0, 0xED40, 0x979E, 0xED41, 0x979F,
+	0xED42, 0x97A1, 0xED43, 0x97A2, 0xED44, 0x97A4, 0xED45, 0x97A5,
+	0xED46, 0x97A6, 0xED47, 0x97A7, 0xED48, 0x97A8, 0xED49, 0x97A9,
+	0xED4A, 0x97AA, 0xED4B, 0x97AC, 0xED4C, 0x97AE, 0xED4D, 0x97B0,
+	0xED4E, 0x97B1, 0xED4F, 0x97B3, 0xED50, 0x97B5, 0xED51, 0x97B6,
+	0xED52, 0x97B7, 0xED53, 0x97B8, 0xED54, 0x97B9, 0xED55, 0x97BA,
+	0xED56, 0x97BB, 0xED57, 0x97BC, 0xED58, 0x97BD, 0xED59, 0x97BE,
+	0xED5A, 0x97BF, 0xED5B, 0x97C0, 0xED5C, 0x97C1, 0xED5D, 0x97C2,
+	0xED5E, 0x97C3, 0xED5F, 0x97C4, 0xED60, 0x97C5, 0xED61, 0x97C6,
+	0xED62, 0x97C7, 0xED63, 0x97C8, 0xED64, 0x97C9, 0xED65, 0x97CA,
+	0xED66, 0x97CB, 0xED67, 0x97CC, 0xED68, 0x97CD, 0xED69, 0x97CE,
+	0xED6A, 0x97CF, 0xED6B, 0x97D0, 0xED6C, 0x97D1, 0xED6D, 0x97D2,
+	0xED6E, 0x97D3, 0xED6F, 0x97D4, 0xED70, 0x97D5, 0xED71, 0x97D6,
+	0xED72, 0x97D7, 0xED73, 0x97D8, 0xED74, 0x97D9, 0xED75, 0x97DA,
+	0xED76, 0x97DB, 0xED77, 0x97DC, 0xED78, 0x97DD, 0xED79, 0x97DE,
+	0xED7A, 0x97DF, 0xED7B, 0x97E0, 0xED7C, 0x97E1, 0xED7D, 0x97E2,
+	0xED7E, 0x97E3, 0xED80, 0x97E4, 0xED81, 0x97E5, 0xED82, 0x97E8,
+	0xED83, 0x97EE, 0xED84, 0x97EF, 0xED85, 0x97F0, 0xED86, 0x97F1,
+	0xED87, 0x97F2, 0xED88, 0x97F4, 0xED89, 0x97F7, 0xED8A, 0x97F8,
+	0xED8B, 0x97F9, 0xED8C, 0x97FA, 0xED8D, 0x97FB, 0xED8E, 0x97FC,
+	0xED8F, 0x97FD, 0xED90, 0x97FE, 0xED91, 0x97FF, 0xED92, 0x9800,
+	0xED93, 0x9801, 0xED94, 0x9802, 0xED95, 0x9803, 0xED96, 0x9804,
+	0xED97, 0x9805, 0xED98, 0x9806, 0xED99, 0x9807, 0xED9A, 0x9808,
+	0xED9B, 0x9809, 0xED9C, 0x980A, 0xED9D, 0x980B, 0xED9E, 0x980C,
+	0xED9F, 0x980D, 0xEDA0, 0x980E, 0xEDA1, 0x603C, 0xEDA2, 0x605D,
+	0xEDA3, 0x605A, 0xEDA4, 0x6067, 0xEDA5, 0x6041, 0xEDA6, 0x6059,
+	0xEDA7, 0x6063, 0xEDA8, 0x60AB, 0xEDA9, 0x6106, 0xEDAA, 0x610D,
+	0xEDAB, 0x615D, 0xEDAC, 0x61A9, 0xEDAD, 0x619D, 0xEDAE, 0x61CB,
+	0xEDAF, 0x61D1, 0xEDB0, 0x6206, 0xEDB1, 0x8080, 0xEDB2, 0x807F,
+	0xEDB3, 0x6C93, 0xEDB4, 0x6CF6, 0xEDB5, 0x6DFC, 0xEDB6, 0x77F6,
+	0xEDB7, 0x77F8, 0xEDB8, 0x7800, 0xEDB9, 0x7809, 0xEDBA, 0x7817,
+	0xEDBB, 0x7818, 0xEDBC, 0x7811, 0xEDBD, 0x65AB, 0xEDBE, 0x782D,
+	0xEDBF, 0x781C, 0xEDC0, 0x781D, 0xEDC1, 0x7839, 0xEDC2, 0x783A,
+	0xEDC3, 0x783B, 0xEDC4, 0x781F, 0xEDC5, 0x783C, 0xEDC6, 0x7825,
+	0xEDC7, 0x782C, 0xEDC8, 0x7823, 0xEDC9, 0x7829, 0xEDCA, 0x784E,
+	0xEDCB, 0x786D, 0xEDCC, 0x7856, 0xEDCD, 0x7857, 0xEDCE, 0x7826,
+	0xEDCF, 0x7850, 0xEDD0, 0x7847, 0xEDD1, 0x784C, 0xEDD2, 0x786A,
+	0xEDD3, 0x789B, 0xEDD4, 0x7893, 0xEDD5, 0x789A, 0xEDD6, 0x7887,
+	0xEDD7, 0x789C, 0xEDD8, 0x78A1, 0xEDD9, 0x78A3, 0xEDDA, 0x78B2,
+	0xEDDB, 0x78B9, 0xEDDC, 0x78A5, 0xEDDD, 0x78D4, 0xEDDE, 0x78D9,
+	0xEDDF, 0x78C9, 0xEDE0, 0x78EC, 0xEDE1, 0x78F2, 0xEDE2, 0x7905,
+	0xEDE3, 0x78F4, 0xEDE4, 0x7913, 0xEDE5, 0x7924, 0xEDE6, 0x791E,
+	0xEDE7, 0x7934, 0xEDE8, 0x9F9B, 0xEDE9, 0x9EF9, 0xEDEA, 0x9EFB,
+	0xEDEB, 0x9EFC, 0xEDEC, 0x76F1, 0xEDED, 0x7704, 0xEDEE, 0x770D,
+	0xEDEF, 0x76F9, 0xEDF0, 0x7707, 0xEDF1, 0x7708, 0xEDF2, 0x771A,
+	0xEDF3, 0x7722, 0xEDF4, 0x7719, 0xEDF5, 0x772D, 0xEDF6, 0x7726,
+	0xEDF7, 0x7735, 0xEDF8, 0x7738, 0xEDF9, 0x7750, 0xEDFA, 0x7751,
+	0xEDFB, 0x7747, 0xEDFC, 0x7743, 0xEDFD, 0x775A, 0xEDFE, 0x7768,
+	0xEE40, 0x980F, 0xEE41, 0x9810, 0xEE42, 0x9811, 0xEE43, 0x9812,
+	0xEE44, 0x9813, 0xEE45, 0x9814, 0xEE46, 0x9815, 0xEE47, 0x9816,
+	0xEE48, 0x9817, 0xEE49, 0x9818, 0xEE4A, 0x9819, 0xEE4B, 0x981A,
+	0xEE4C, 0x981B, 0xEE4D, 0x981C, 0xEE4E, 0x981D, 0xEE4F, 0x981E,
+	0xEE50, 0x981F, 0xEE51, 0x9820, 0xEE52, 0x9821, 0xEE53, 0x9822,
+	0xEE54, 0x9823, 0xEE55, 0x9824, 0xEE56, 0x9825, 0xEE57, 0x9826,
+	0xEE58, 0x9827, 0xEE59, 0x9828, 0xEE5A, 0x9829, 0xEE5B, 0x982A,
+	0xEE5C, 0x982B, 0xEE5D, 0x982C, 0xEE5E, 0x982D, 0xEE5F, 0x982E,
+	0xEE60, 0x982F, 0xEE61, 0x9830, 0xEE62, 0x9831, 0xEE63, 0x9832,
+	0xEE64, 0x9833, 0xEE65, 0x9834, 0xEE66, 0x9835, 0xEE67, 0x9836,
+	0xEE68, 0x9837, 0xEE69, 0x9838, 0xEE6A, 0x9839, 0xEE6B, 0x983A,
+	0xEE6C, 0x983B, 0xEE6D, 0x983C, 0xEE6E, 0x983D, 0xEE6F, 0x983E,
+	0xEE70, 0x983F, 0xEE71, 0x9840, 0xEE72, 0x9841, 0xEE73, 0x9842,
+	0xEE74, 0x9843, 0xEE75, 0x9844, 0xEE76, 0x9845, 0xEE77, 0x9846,
+	0xEE78, 0x9847, 0xEE79, 0x9848, 0xEE7A, 0x9849, 0xEE7B, 0x984A,
+	0xEE7C, 0x984B, 0xEE7D, 0x984C, 0xEE7E, 0x984D, 0xEE80, 0x984E,
+	0xEE81, 0x984F, 0xEE82, 0x9850, 0xEE83, 0x9851, 0xEE84, 0x9852,
+	0xEE85, 0x9853, 0xEE86, 0x9854, 0xEE87, 0x9855, 0xEE88, 0x9856,
+	0xEE89, 0x9857, 0xEE8A, 0x9858, 0xEE8B, 0x9859, 0xEE8C, 0x985A,
+	0xEE8D, 0x985B, 0xEE8E, 0x985C, 0xEE8F, 0x985D, 0xEE90, 0x985E,
+	0xEE91, 0x985F, 0xEE92, 0x9860, 0xEE93, 0x9861, 0xEE94, 0x9862,
+	0xEE95, 0x9863, 0xEE96, 0x9864, 0xEE97, 0x9865, 0xEE98, 0x9866,
+	0xEE99, 0x9867, 0xEE9A, 0x9868, 0xEE9B, 0x9869, 0xEE9C, 0x986A,
+	0xEE9D, 0x986B, 0xEE9E, 0x986C, 0xEE9F, 0x986D, 0xEEA0, 0x986E,
+	0xEEA1, 0x7762, 0xEEA2, 0x7765, 0xEEA3, 0x777F, 0xEEA4, 0x778D,
+	0xEEA5, 0x777D, 0xEEA6, 0x7780, 0xEEA7, 0x778C, 0xEEA8, 0x7791,
+	0xEEA9, 0x779F, 0xEEAA, 0x77A0, 0xEEAB, 0x77B0, 0xEEAC, 0x77B5,
+	0xEEAD, 0x77BD, 0xEEAE, 0x753A, 0xEEAF, 0x7540, 0xEEB0, 0x754E,
+	0xEEB1, 0x754B, 0xEEB2, 0x7548, 0xEEB3, 0x755B, 0xEEB4, 0x7572,
+	0xEEB5, 0x7579, 0xEEB6, 0x7583, 0xEEB7, 0x7F58, 0xEEB8, 0x7F61,
+	0xEEB9, 0x7F5F, 0xEEBA, 0x8A48, 0xEEBB, 0x7F68, 0xEEBC, 0x7F74,
+	0xEEBD, 0x7F71, 0xEEBE, 0x7F79, 0xEEBF, 0x7F81, 0xEEC0, 0x7F7E,
+	0xEEC1, 0x76CD, 0xEEC2, 0x76E5, 0xEEC3, 0x8832, 0xEEC4, 0x9485,
+	0xEEC5, 0x9486, 0xEEC6, 0x9487, 0xEEC7, 0x948B, 0xEEC8, 0x948A,
+	0xEEC9, 0x948C, 0xEECA, 0x948D, 0xEECB, 0x948F, 0xEECC, 0x9490,
+	0xEECD, 0x9494, 0xEECE, 0x9497, 0xEECF, 0x9495, 0xEED0, 0x949A,
+	0xEED1, 0x949B, 0xEED2, 0x949C, 0xEED3, 0x94A3, 0xEED4, 0x94A4,
+	0xEED5, 0x94AB, 0xEED6, 0x94AA, 0xEED7, 0x94AD, 0xEED8, 0x94AC,
+	0xEED9, 0x94AF, 0xEEDA, 0x94B0, 0xEEDB, 0x94B2, 0xEEDC, 0x94B4,
+	0xEEDD, 0x94B6, 0xEEDE, 0x94B7, 0xEEDF, 0x94B8, 0xEEE0, 0x94B9,
+	0xEEE1, 0x94BA, 0xEEE2, 0x94BC, 0xEEE3, 0x94BD, 0xEEE4, 0x94BF,
+	0xEEE5, 0x94C4, 0xEEE6, 0x94C8, 0xEEE7, 0x94C9, 0xEEE8, 0x94CA,
+	0xEEE9, 0x94CB, 0xEEEA, 0x94CC, 0xEEEB, 0x94CD, 0xEEEC, 0x94CE,
+	0xEEED, 0x94D0, 0xEEEE, 0x94D1, 0xEEEF, 0x94D2, 0xEEF0, 0x94D5,
+	0xEEF1, 0x94D6, 0xEEF2, 0x94D7, 0xEEF3, 0x94D9, 0xEEF4, 0x94D8,
+	0xEEF5, 0x94DB, 0xEEF6, 0x94DE, 0xEEF7, 0x94DF, 0xEEF8, 0x94E0,
+	0xEEF9, 0x94E2, 0xEEFA, 0x94E4, 0xEEFB, 0x94E5, 0xEEFC, 0x94E7,
+	0xEEFD, 0x94E8, 0xEEFE, 0x94EA, 0xEF40, 0x986F, 0xEF41, 0x9870,
+	0xEF42, 0x9871, 0xEF43, 0x9872, 0xEF44, 0x9873, 0xEF45, 0x9874,
+	0xEF46, 0x988B, 0xEF47, 0x988E, 0xEF48, 0x9892, 0xEF49, 0x9895,
+	0xEF4A, 0x9899, 0xEF4B, 0x98A3, 0xEF4C, 0x98A8, 0xEF4D, 0x98A9,
+	0xEF4E, 0x98AA, 0xEF4F, 0x98AB, 0xEF50, 0x98AC, 0xEF51, 0x98AD,
+	0xEF52, 0x98AE, 0xEF53, 0x98AF, 0xEF54, 0x98B0, 0xEF55, 0x98B1,
+	0xEF56, 0x98B2, 0xEF57, 0x98B3, 0xEF58, 0x98B4, 0xEF59, 0x98B5,
+	0xEF5A, 0x98B6, 0xEF5B, 0x98B7, 0xEF5C, 0x98B8, 0xEF5D, 0x98B9,
+	0xEF5E, 0x98BA, 0xEF5F, 0x98BB, 0xEF60, 0x98BC, 0xEF61, 0x98BD,
+	0xEF62, 0x98BE, 0xEF63, 0x98BF, 0xEF64, 0x98C0, 0xEF65, 0x98C1,
+	0xEF66, 0x98C2, 0xEF67, 0x98C3, 0xEF68, 0x98C4, 0xEF69, 0x98C5,
+	0xEF6A, 0x98C6, 0xEF6B, 0x98C7, 0xEF6C, 0x98C8, 0xEF6D, 0x98C9,
+	0xEF6E, 0x98CA, 0xEF6F, 0x98CB, 0xEF70, 0x98CC, 0xEF71, 0x98CD,
+	0xEF72, 0x98CF, 0xEF73, 0x98D0, 0xEF74, 0x98D4, 0xEF75, 0x98D6,
+	0xEF76, 0x98D7, 0xEF77, 0x98DB, 0xEF78, 0x98DC, 0xEF79, 0x98DD,
+	0xEF7A, 0x98E0, 0xEF7B, 0x98E1, 0xEF7C, 0x98E2, 0xEF7D, 0x98E3,
+	0xEF7E, 0x98E4, 0xEF80, 0x98E5, 0xEF81, 0x98E6, 0xEF82, 0x98E9,
+	0xEF83, 0x98EA, 0xEF84, 0x98EB, 0xEF85, 0x98EC, 0xEF86, 0x98ED,
+	0xEF87, 0x98EE, 0xEF88, 0x98EF, 0xEF89, 0x98F0, 0xEF8A, 0x98F1,
+	0xEF8B, 0x98F2, 0xEF8C, 0x98F3, 0xEF8D, 0x98F4, 0xEF8E, 0x98F5,
+	0xEF8F, 0x98F6, 0xEF90, 0x98F7, 0xEF91, 0x98F8, 0xEF92, 0x98F9,
+	0xEF93, 0x98FA, 0xEF94, 0x98FB, 0xEF95, 0x98FC, 0xEF96, 0x98FD,
+	0xEF97, 0x98FE, 0xEF98, 0x98FF, 0xEF99, 0x9900, 0xEF9A, 0x9901,
+	0xEF9B, 0x9902, 0xEF9C, 0x9903, 0xEF9D, 0x9904, 0xEF9E, 0x9905,
+	0xEF9F, 0x9906, 0xEFA0, 0x9907, 0xEFA1, 0x94E9, 0xEFA2, 0x94EB,
+	0xEFA3, 0x94EE, 0xEFA4, 0x94EF, 0xEFA5, 0x94F3, 0xEFA6, 0x94F4,
+	0xEFA7, 0x94F5, 0xEFA8, 0x94F7, 0xEFA9, 0x94F9, 0xEFAA, 0x94FC,
+	0xEFAB, 0x94FD, 0xEFAC, 0x94FF, 0xEFAD, 0x9503, 0xEFAE, 0x9502,
+	0xEFAF, 0x9506, 0xEFB0, 0x9507, 0xEFB1, 0x9509, 0xEFB2, 0x950A,
+	0xEFB3, 0x950D, 0xEFB4, 0x950E, 0xEFB5, 0x950F, 0xEFB6, 0x9512,
+	0xEFB7, 0x9513, 0xEFB8, 0x9514, 0xEFB9, 0x9515, 0xEFBA, 0x9516,
+	0xEFBB, 0x9518, 0xEFBC, 0x951B, 0xEFBD, 0x951D, 0xEFBE, 0x951E,
+	0xEFBF, 0x951F, 0xEFC0, 0x9522, 0xEFC1, 0x952A, 0xEFC2, 0x952B,
+	0xEFC3, 0x9529, 0xEFC4, 0x952C, 0xEFC5, 0x9531, 0xEFC6, 0x9532,
+	0xEFC7, 0x9534, 0xEFC8, 0x9536, 0xEFC9, 0x9537, 0xEFCA, 0x9538,
+	0xEFCB, 0x953C, 0xEFCC, 0x953E, 0xEFCD, 0x953F, 0xEFCE, 0x9542,
+	0xEFCF, 0x9535, 0xEFD0, 0x9544, 0xEFD1, 0x9545, 0xEFD2, 0x9546,
+	0xEFD3, 0x9549, 0xEFD4, 0x954C, 0xEFD5, 0x954E, 0xEFD6, 0x954F,
+	0xEFD7, 0x9552, 0xEFD8, 0x9553, 0xEFD9, 0x9554, 0xEFDA, 0x9556,
+	0xEFDB, 0x9557, 0xEFDC, 0x9558, 0xEFDD, 0x9559, 0xEFDE, 0x955B,
+	0xEFDF, 0x955E, 0xEFE0, 0x955F, 0xEFE1, 0x955D, 0xEFE2, 0x9561,
+	0xEFE3, 0x9562, 0xEFE4, 0x9564, 0xEFE5, 0x9565, 0xEFE6, 0x9566,
+	0xEFE7, 0x9567, 0xEFE8, 0x9568, 0xEFE9, 0x9569, 0xEFEA, 0x956A,
+	0xEFEB, 0x956B, 0xEFEC, 0x956C, 0xEFED, 0x956F, 0xEFEE, 0x9571,
+	0xEFEF, 0x9572, 0xEFF0, 0x9573, 0xEFF1, 0x953A, 0xEFF2, 0x77E7,
+	0xEFF3, 0x77EC, 0xEFF4, 0x96C9, 0xEFF5, 0x79D5, 0xEFF6, 0x79ED,
+	0xEFF7, 0x79E3, 0xEFF8, 0x79EB, 0xEFF9, 0x7A06, 0xEFFA, 0x5D47,
+	0xEFFB, 0x7A03, 0xEFFC, 0x7A02, 0xEFFD, 0x7A1E, 0xEFFE, 0x7A14,
+	0xF040, 0x9908, 0xF041, 0x9909, 0xF042, 0x990A, 0xF043, 0x990B,
+	0xF044, 0x990C, 0xF045, 0x990E, 0xF046, 0x990F, 0xF047, 0x9911,
+	0xF048, 0x9912, 0xF049, 0x9913, 0xF04A, 0x9914, 0xF04B, 0x9915,
+	0xF04C, 0x9916, 0xF04D, 0x9917, 0xF04E, 0x9918, 0xF04F, 0x9919,
+	0xF050, 0x991A, 0xF051, 0x991B, 0xF052, 0x991C, 0xF053, 0x991D,
+	0xF054, 0x991E, 0xF055, 0x991F, 0xF056, 0x9920, 0xF057, 0x9921,
+	0xF058, 0x9922, 0xF059, 0x9923, 0xF05A, 0x9924, 0xF05B, 0x9925,
+	0xF05C, 0x9926, 0xF05D, 0x9927, 0xF05E, 0x9928, 0xF05F, 0x9929,
+	0xF060, 0x992A, 0xF061, 0x992B, 0xF062, 0x992C, 0xF063, 0x992D,
+	0xF064, 0x992F, 0xF065, 0x9930, 0xF066, 0x9931, 0xF067, 0x9932,
+	0xF068, 0x9933, 0xF069, 0x9934, 0xF06A, 0x9935, 0xF06B, 0x9936,
+	0xF06C, 0x9937, 0xF06D, 0x9938, 0xF06E, 0x9939, 0xF06F, 0x993A,
+	0xF070, 0x993B, 0xF071, 0x993C, 0xF072, 0x993D, 0xF073, 0x993E,
+	0xF074, 0x993F, 0xF075, 0x9940, 0xF076, 0x9941, 0xF077, 0x9942,
+	0xF078, 0x9943, 0xF079, 0x9944, 0xF07A, 0x9945, 0xF07B, 0x9946,
+	0xF07C, 0x9947, 0xF07D, 0x9948, 0xF07E, 0x9949, 0xF080, 0x994A,
+	0xF081, 0x994B, 0xF082, 0x994C, 0xF083, 0x994D, 0xF084, 0x994E,
+	0xF085, 0x994F, 0xF086, 0x9950, 0xF087, 0x9951, 0xF088, 0x9952,
+	0xF089, 0x9953, 0xF08A, 0x9956, 0xF08B, 0x9957, 0xF08C, 0x9958,
+	0xF08D, 0x9959, 0xF08E, 0x995A, 0xF08F, 0x995B, 0xF090, 0x995C,
+	0xF091, 0x995D, 0xF092, 0x995E, 0xF093, 0x995F, 0xF094, 0x9960,
+	0xF095, 0x9961, 0xF096, 0x9962, 0xF097, 0x9964, 0xF098, 0x9966,
+	0xF099, 0x9973, 0xF09A, 0x9978, 0xF09B, 0x9979, 0xF09C, 0x997B,
+	0xF09D, 0x997E, 0xF09E, 0x9982, 0xF09F, 0x9983, 0xF0A0, 0x9989,
+	0xF0A1, 0x7A39, 0xF0A2, 0x7A37, 0xF0A3, 0x7A51, 0xF0A4, 0x9ECF,
+	0xF0A5, 0x99A5, 0xF0A6, 0x7A70, 0xF0A7, 0x7688, 0xF0A8, 0x768E,
+	0xF0A9, 0x7693, 0xF0AA, 0x7699, 0xF0AB, 0x76A4, 0xF0AC, 0x74DE,
+	0xF0AD, 0x74E0, 0xF0AE, 0x752C, 0xF0AF, 0x9E20, 0xF0B0, 0x9E22,
+	0xF0B1, 0x9E28, 0xF0B2, 0x9E29, 0xF0B3, 0x9E2A, 0xF0B4, 0x9E2B,
+	0xF0B5, 0x9E2C, 0xF0B6, 0x9E32, 0xF0B7, 0x9E31, 0xF0B8, 0x9E36,
+	0xF0B9, 0x9E38, 0xF0BA, 0x9E37, 0xF0BB, 0x9E39, 0xF0BC, 0x9E3A,
+	0xF0BD, 0x9E3E, 0xF0BE, 0x9E41, 0xF0BF, 0x9E42, 0xF0C0, 0x9E44,
+	0xF0C1, 0x9E46, 0xF0C2, 0x9E47, 0xF0C3, 0x9E48, 0xF0C4, 0x9E49,
+	0xF0C5, 0x9E4B, 0xF0C6, 0x9E4C, 0xF0C7, 0x9E4E, 0xF0C8, 0x9E51,
+	0xF0C9, 0x9E55, 0xF0CA, 0x9E57, 0xF0CB, 0x9E5A, 0xF0CC, 0x9E5B,
+	0xF0CD, 0x9E5C, 0xF0CE, 0x9E5E, 0xF0CF, 0x9E63, 0xF0D0, 0x9E66,
+	0xF0D1, 0x9E67, 0xF0D2, 0x9E68, 0xF0D3, 0x9E69, 0xF0D4, 0x9E6A,
+	0xF0D5, 0x9E6B, 0xF0D6, 0x9E6C, 0xF0D7, 0x9E71, 0xF0D8, 0x9E6D,
+	0xF0D9, 0x9E73, 0xF0DA, 0x7592, 0xF0DB, 0x7594, 0xF0DC, 0x7596,
+	0xF0DD, 0x75A0, 0xF0DE, 0x759D, 0xF0DF, 0x75AC, 0xF0E0, 0x75A3,
+	0xF0E1, 0x75B3, 0xF0E2, 0x75B4, 0xF0E3, 0x75B8, 0xF0E4, 0x75C4,
+	0xF0E5, 0x75B1, 0xF0E6, 0x75B0, 0xF0E7, 0x75C3, 0xF0E8, 0x75C2,
+	0xF0E9, 0x75D6, 0xF0EA, 0x75CD, 0xF0EB, 0x75E3, 0xF0EC, 0x75E8,
+	0xF0ED, 0x75E6, 0xF0EE, 0x75E4, 0xF0EF, 0x75EB, 0xF0F0, 0x75E7,
+	0xF0F1, 0x7603, 0xF0F2, 0x75F1, 0xF0F3, 0x75FC, 0xF0F4, 0x75FF,
+	0xF0F5, 0x7610, 0xF0F6, 0x7600, 0xF0F7, 0x7605, 0xF0F8, 0x760C,
+	0xF0F9, 0x7617, 0xF0FA, 0x760A, 0xF0FB, 0x7625, 0xF0FC, 0x7618,
+	0xF0FD, 0x7615, 0xF0FE, 0x7619, 0xF140, 0x998C, 0xF141, 0x998E,
+	0xF142, 0x999A, 0xF143, 0x999B, 0xF144, 0x999C, 0xF145, 0x999D,
+	0xF146, 0x999E, 0xF147, 0x999F, 0xF148, 0x99A0, 0xF149, 0x99A1,
+	0xF14A, 0x99A2, 0xF14B, 0x99A3, 0xF14C, 0x99A4, 0xF14D, 0x99A6,
+	0xF14E, 0x99A7, 0xF14F, 0x99A9, 0xF150, 0x99AA, 0xF151, 0x99AB,
+	0xF152, 0x99AC, 0xF153, 0x99AD, 0xF154, 0x99AE, 0xF155, 0x99AF,
+	0xF156, 0x99B0, 0xF157, 0x99B1, 0xF158, 0x99B2, 0xF159, 0x99B3,
+	0xF15A, 0x99B4, 0xF15B, 0x99B5, 0xF15C, 0x99B6, 0xF15D, 0x99B7,
+	0xF15E, 0x99B8, 0xF15F, 0x99B9, 0xF160, 0x99BA, 0xF161, 0x99BB,
+	0xF162, 0x99BC, 0xF163, 0x99BD, 0xF164, 0x99BE, 0xF165, 0x99BF,
+	0xF166, 0x99C0, 0xF167, 0x99C1, 0xF168, 0x99C2, 0xF169, 0x99C3,
+	0xF16A, 0x99C4, 0xF16B, 0x99C5, 0xF16C, 0x99C6, 0xF16D, 0x99C7,
+	0xF16E, 0x99C8, 0xF16F, 0x99C9, 0xF170, 0x99CA, 0xF171, 0x99CB,
+	0xF172, 0x99CC, 0xF173, 0x99CD, 0xF174, 0x99CE, 0xF175, 0x99CF,
+	0xF176, 0x99D0, 0xF177, 0x99D1, 0xF178, 0x99D2, 0xF179, 0x99D3,
+	0xF17A, 0x99D4, 0xF17B, 0x99D5, 0xF17C, 0x99D6, 0xF17D, 0x99D7,
+	0xF17E, 0x99D8, 0xF180, 0x99D9, 0xF181, 0x99DA, 0xF182, 0x99DB,
+	0xF183, 0x99DC, 0xF184, 0x99DD, 0xF185, 0x99DE, 0xF186, 0x99DF,
+	0xF187, 0x99E0, 0xF188, 0x99E1, 0xF189, 0x99E2, 0xF18A, 0x99E3,
+	0xF18B, 0x99E4, 0xF18C, 0x99E5, 0xF18D, 0x99E6, 0xF18E, 0x99E7,
+	0xF18F, 0x99E8, 0xF190, 0x99E9, 0xF191, 0x99EA, 0xF192, 0x99EB,
+	0xF193, 0x99EC, 0xF194, 0x99ED, 0xF195, 0x99EE, 0xF196, 0x99EF,
+	0xF197, 0x99F0, 0xF198, 0x99F1, 0xF199, 0x99F2, 0xF19A, 0x99F3,
+	0xF19B, 0x99F4, 0xF19C, 0x99F5, 0xF19D, 0x99F6, 0xF19E, 0x99F7,
+	0xF19F, 0x99F8, 0xF1A0, 0x99F9, 0xF1A1, 0x761B, 0xF1A2, 0x763C,
+	0xF1A3, 0x7622, 0xF1A4, 0x7620, 0xF1A5, 0x7640, 0xF1A6, 0x762D,
+	0xF1A7, 0x7630, 0xF1A8, 0x763F, 0xF1A9, 0x7635, 0xF1AA, 0x7643,
+	0xF1AB, 0x763E, 0xF1AC, 0x7633, 0xF1AD, 0x764D, 0xF1AE, 0x765E,
+	0xF1AF, 0x7654, 0xF1B0, 0x765C, 0xF1B1, 0x7656, 0xF1B2, 0x766B,
+	0xF1B3, 0x766F, 0xF1B4, 0x7FCA, 0xF1B5, 0x7AE6, 0xF1B6, 0x7A78,
+	0xF1B7, 0x7A79, 0xF1B8, 0x7A80, 0xF1B9, 0x7A86, 0xF1BA, 0x7A88,
+	0xF1BB, 0x7A95, 0xF1BC, 0x7AA6, 0xF1BD, 0x7AA0, 0xF1BE, 0x7AAC,
+	0xF1BF, 0x7AA8, 0xF1C0, 0x7AAD, 0xF1C1, 0x7AB3, 0xF1C2, 0x8864,
+	0xF1C3, 0x8869, 0xF1C4, 0x8872, 0xF1C5, 0x887D, 0xF1C6, 0x887F,
+	0xF1C7, 0x8882, 0xF1C8, 0x88A2, 0xF1C9, 0x88C6, 0xF1CA, 0x88B7,
+	0xF1CB, 0x88BC, 0xF1CC, 0x88C9, 0xF1CD, 0x88E2, 0xF1CE, 0x88CE,
+	0xF1CF, 0x88E3, 0xF1D0, 0x88E5, 0xF1D1, 0x88F1, 0xF1D2, 0x891A,
+	0xF1D3, 0x88FC, 0xF1D4, 0x88E8, 0xF1D5, 0x88FE, 0xF1D6, 0x88F0,
+	0xF1D7, 0x8921, 0xF1D8, 0x8919, 0xF1D9, 0x8913, 0xF1DA, 0x891B,
+	0xF1DB, 0x890A, 0xF1DC, 0x8934, 0xF1DD, 0x892B, 0xF1DE, 0x8936,
+	0xF1DF, 0x8941, 0xF1E0, 0x8966, 0xF1E1, 0x897B, 0xF1E2, 0x758B,
+	0xF1E3, 0x80E5, 0xF1E4, 0x76B2, 0xF1E5, 0x76B4, 0xF1E6, 0x77DC,
+	0xF1E7, 0x8012, 0xF1E8, 0x8014, 0xF1E9, 0x8016, 0xF1EA, 0x801C,
+	0xF1EB, 0x8020, 0xF1EC, 0x8022, 0xF1ED, 0x8025, 0xF1EE, 0x8026,
+	0xF1EF, 0x8027, 0xF1F0, 0x8029, 0xF1F1, 0x8028, 0xF1F2, 0x8031,
+	0xF1F3, 0x800B, 0xF1F4, 0x8035, 0xF1F5, 0x8043, 0xF1F6, 0x8046,
+	0xF1F7, 0x804D, 0xF1F8, 0x8052, 0xF1F9, 0x8069, 0xF1FA, 0x8071,
+	0xF1FB, 0x8983, 0xF1FC, 0x9878, 0xF1FD, 0x9880, 0xF1FE, 0x9883,
+	0xF240, 0x99FA, 0xF241, 0x99FB, 0xF242, 0x99FC, 0xF243, 0x99FD,
+	0xF244, 0x99FE, 0xF245, 0x99FF, 0xF246, 0x9A00, 0xF247, 0x9A01,
+	0xF248, 0x9A02, 0xF249, 0x9A03, 0xF24A, 0x9A04, 0xF24B, 0x9A05,
+	0xF24C, 0x9A06, 0xF24D, 0x9A07, 0xF24E, 0x9A08, 0xF24F, 0x9A09,
+	0xF250, 0x9A0A, 0xF251, 0x9A0B, 0xF252, 0x9A0C, 0xF253, 0x9A0D,
+	0xF254, 0x9A0E, 0xF255, 0x9A0F, 0xF256, 0x9A10, 0xF257, 0x9A11,
+	0xF258, 0x9A12, 0xF259, 0x9A13, 0xF25A, 0x9A14, 0xF25B, 0x9A15,
+	0xF25C, 0x9A16, 0xF25D, 0x9A17, 0xF25E, 0x9A18, 0xF25F, 0x9A19,
+	0xF260, 0x9A1A, 0xF261, 0x9A1B, 0xF262, 0x9A1C, 0xF263, 0x9A1D,
+	0xF264, 0x9A1E, 0xF265, 0x9A1F, 0xF266, 0x9A20, 0xF267, 0x9A21,
+	0xF268, 0x9A22, 0xF269, 0x9A23, 0xF26A, 0x9A24, 0xF26B, 0x9A25,
+	0xF26C, 0x9A26, 0xF26D, 0x9A27, 0xF26E, 0x9A28, 0xF26F, 0x9A29,
+	0xF270, 0x9A2A, 0xF271, 0x9A2B, 0xF272, 0x9A2C, 0xF273, 0x9A2D,
+	0xF274, 0x9A2E, 0xF275, 0x9A2F, 0xF276, 0x9A30, 0xF277, 0x9A31,
+	0xF278, 0x9A32, 0xF279, 0x9A33, 0xF27A, 0x9A34, 0xF27B, 0x9A35,
+	0xF27C, 0x9A36, 0xF27D, 0x9A37, 0xF27E, 0x9A38, 0xF280, 0x9A39,
+	0xF281, 0x9A3A, 0xF282, 0x9A3B, 0xF283, 0x9A3C, 0xF284, 0x9A3D,
+	0xF285, 0x9A3E, 0xF286, 0x9A3F, 0xF287, 0x9A40, 0xF288, 0x9A41,
+	0xF289, 0x9A42, 0xF28A, 0x9A43, 0xF28B, 0x9A44, 0xF28C, 0x9A45,
+	0xF28D, 0x9A46, 0xF28E, 0x9A47, 0xF28F, 0x9A48, 0xF290, 0x9A49,
+	0xF291, 0x9A4A, 0xF292, 0x9A4B, 0xF293, 0x9A4C, 0xF294, 0x9A4D,
+	0xF295, 0x9A4E, 0xF296, 0x9A4F, 0xF297, 0x9A50, 0xF298, 0x9A51,
+	0xF299, 0x9A52, 0xF29A, 0x9A53, 0xF29B, 0x9A54, 0xF29C, 0x9A55,
+	0xF29D, 0x9A56, 0xF29E, 0x9A57, 0xF29F, 0x9A58, 0xF2A0, 0x9A59,
+	0xF2A1, 0x9889, 0xF2A2, 0x988C, 0xF2A3, 0x988D, 0xF2A4, 0x988F,
+	0xF2A5, 0x9894, 0xF2A6, 0x989A, 0xF2A7, 0x989B, 0xF2A8, 0x989E,
+	0xF2A9, 0x989F, 0xF2AA, 0x98A1, 0xF2AB, 0x98A2, 0xF2AC, 0x98A5,
+	0xF2AD, 0x98A6, 0xF2AE, 0x864D, 0xF2AF, 0x8654, 0xF2B0, 0x866C,
+	0xF2B1, 0x866E, 0xF2B2, 0x867F, 0xF2B3, 0x867A, 0xF2B4, 0x867C,
+	0xF2B5, 0x867B, 0xF2B6, 0x86A8, 0xF2B7, 0x868D, 0xF2B8, 0x868B,
+	0xF2B9, 0x86AC, 0xF2BA, 0x869D, 0xF2BB, 0x86A7, 0xF2BC, 0x86A3,
+	0xF2BD, 0x86AA, 0xF2BE, 0x8693, 0xF2BF, 0x86A9, 0xF2C0, 0x86B6,
+	0xF2C1, 0x86C4, 0xF2C2, 0x86B5, 0xF2C3, 0x86CE, 0xF2C4, 0x86B0,
+	0xF2C5, 0x86BA, 0xF2C6, 0x86B1, 0xF2C7, 0x86AF, 0xF2C8, 0x86C9,
+	0xF2C9, 0x86CF, 0xF2CA, 0x86B4, 0xF2CB, 0x86E9, 0xF2CC, 0x86F1,
+	0xF2CD, 0x86F2, 0xF2CE, 0x86ED, 0xF2CF, 0x86F3, 0xF2D0, 0x86D0,
+	0xF2D1, 0x8713, 0xF2D2, 0x86DE, 0xF2D3, 0x86F4, 0xF2D4, 0x86DF,
+	0xF2D5, 0x86D8, 0xF2D6, 0x86D1, 0xF2D7, 0x8703, 0xF2D8, 0x8707,
+	0xF2D9, 0x86F8, 0xF2DA, 0x8708, 0xF2DB, 0x870A, 0xF2DC, 0x870D,
+	0xF2DD, 0x8709, 0xF2DE, 0x8723, 0xF2DF, 0x873B, 0xF2E0, 0x871E,
+	0xF2E1, 0x8725, 0xF2E2, 0x872E, 0xF2E3, 0x871A, 0xF2E4, 0x873E,
+	0xF2E5, 0x8748, 0xF2E6, 0x8734, 0xF2E7, 0x8731, 0xF2E8, 0x8729,
+	0xF2E9, 0x8737, 0xF2EA, 0x873F, 0xF2EB, 0x8782, 0xF2EC, 0x8722,
+	0xF2ED, 0x877D, 0xF2EE, 0x877E, 0xF2EF, 0x877B, 0xF2F0, 0x8760,
+	0xF2F1, 0x8770, 0xF2F2, 0x874C, 0xF2F3, 0x876E, 0xF2F4, 0x878B,
+	0xF2F5, 0x8753, 0xF2F6, 0x8763, 0xF2F7, 0x877C, 0xF2F8, 0x8764,
+	0xF2F9, 0x8759, 0xF2FA, 0x8765, 0xF2FB, 0x8793, 0xF2FC, 0x87AF,
+	0xF2FD, 0x87A8, 0xF2FE, 0x87D2, 0xF340, 0x9A5A, 0xF341, 0x9A5B,
+	0xF342, 0x9A5C, 0xF343, 0x9A5D, 0xF344, 0x9A5E, 0xF345, 0x9A5F,
+	0xF346, 0x9A60, 0xF347, 0x9A61, 0xF348, 0x9A62, 0xF349, 0x9A63,
+	0xF34A, 0x9A64, 0xF34B, 0x9A65, 0xF34C, 0x9A66, 0xF34D, 0x9A67,
+	0xF34E, 0x9A68, 0xF34F, 0x9A69, 0xF350, 0x9A6A, 0xF351, 0x9A6B,
+	0xF352, 0x9A72, 0xF353, 0x9A83, 0xF354, 0x9A89, 0xF355, 0x9A8D,
+	0xF356, 0x9A8E, 0xF357, 0x9A94, 0xF358, 0x9A95, 0xF359, 0x9A99,
+	0xF35A, 0x9AA6, 0xF35B, 0x9AA9, 0xF35C, 0x9AAA, 0xF35D, 0x9AAB,
+	0xF35E, 0x9AAC, 0xF35F, 0x9AAD, 0xF360, 0x9AAE, 0xF361, 0x9AAF,
+	0xF362, 0x9AB2, 0xF363, 0x9AB3, 0xF364, 0x9AB4, 0xF365, 0x9AB5,
+	0xF366, 0x9AB9, 0xF367, 0x9ABB, 0xF368, 0x9ABD, 0xF369, 0x9ABE,
+	0xF36A, 0x9ABF, 0xF36B, 0x9AC3, 0xF36C, 0x9AC4, 0xF36D, 0x9AC6,
+	0xF36E, 0x9AC7, 0xF36F, 0x9AC8, 0xF370, 0x9AC9, 0xF371, 0x9ACA,
+	0xF372, 0x9ACD, 0xF373, 0x9ACE, 0xF374, 0x9ACF, 0xF375, 0x9AD0,
+	0xF376, 0x9AD2, 0xF377, 0x9AD4, 0xF378, 0x9AD5, 0xF379, 0x9AD6,
+	0xF37A, 0x9AD7, 0xF37B, 0x9AD9, 0xF37C, 0x9ADA, 0xF37D, 0x9ADB,
+	0xF37E, 0x9ADC, 0xF380, 0x9ADD, 0xF381, 0x9ADE, 0xF382, 0x9AE0,
+	0xF383, 0x9AE2, 0xF384, 0x9AE3, 0xF385, 0x9AE4, 0xF386, 0x9AE5,
+	0xF387, 0x9AE7, 0xF388, 0x9AE8, 0xF389, 0x9AE9, 0xF38A, 0x9AEA,
+	0xF38B, 0x9AEC, 0xF38C, 0x9AEE, 0xF38D, 0x9AF0, 0xF38E, 0x9AF1,
+	0xF38F, 0x9AF2, 0xF390, 0x9AF3, 0xF391, 0x9AF4, 0xF392, 0x9AF5,
+	0xF393, 0x9AF6, 0xF394, 0x9AF7, 0xF395, 0x9AF8, 0xF396, 0x9AFA,
+	0xF397, 0x9AFC, 0xF398, 0x9AFD, 0xF399, 0x9AFE, 0xF39A, 0x9AFF,
+	0xF39B, 0x9B00, 0xF39C, 0x9B01, 0xF39D, 0x9B02, 0xF39E, 0x9B04,
+	0xF39F, 0x9B05, 0xF3A0, 0x9B06, 0xF3A1, 0x87C6, 0xF3A2, 0x8788,
+	0xF3A3, 0x8785, 0xF3A4, 0x87AD, 0xF3A5, 0x8797, 0xF3A6, 0x8783,
+	0xF3A7, 0x87AB, 0xF3A8, 0x87E5, 0xF3A9, 0x87AC, 0xF3AA, 0x87B5,
+	0xF3AB, 0x87B3, 0xF3AC, 0x87CB, 0xF3AD, 0x87D3, 0xF3AE, 0x87BD,
+	0xF3AF, 0x87D1, 0xF3B0, 0x87C0, 0xF3B1, 0x87CA, 0xF3B2, 0x87DB,
+	0xF3B3, 0x87EA, 0xF3B4, 0x87E0, 0xF3B5, 0x87EE, 0xF3B6, 0x8816,
+	0xF3B7, 0x8813, 0xF3B8, 0x87FE, 0xF3B9, 0x880A, 0xF3BA, 0x881B,
+	0xF3BB, 0x8821, 0xF3BC, 0x8839, 0xF3BD, 0x883C, 0xF3BE, 0x7F36,
+	0xF3BF, 0x7F42, 0xF3C0, 0x7F44, 0xF3C1, 0x7F45, 0xF3C2, 0x8210,
+	0xF3C3, 0x7AFA, 0xF3C4, 0x7AFD, 0xF3C5, 0x7B08, 0xF3C6, 0x7B03,
+	0xF3C7, 0x7B04, 0xF3C8, 0x7B15, 0xF3C9, 0x7B0A, 0xF3CA, 0x7B2B,
+	0xF3CB, 0x7B0F, 0xF3CC, 0x7B47, 0xF3CD, 0x7B38, 0xF3CE, 0x7B2A,
+	0xF3CF, 0x7B19, 0xF3D0, 0x7B2E, 0xF3D1, 0x7B31, 0xF3D2, 0x7B20,
+	0xF3D3, 0x7B25, 0xF3D4, 0x7B24, 0xF3D5, 0x7B33, 0xF3D6, 0x7B3E,
+	0xF3D7, 0x7B1E, 0xF3D8, 0x7B58, 0xF3D9, 0x7B5A, 0xF3DA, 0x7B45,
+	0xF3DB, 0x7B75, 0xF3DC, 0x7B4C, 0xF3DD, 0x7B5D, 0xF3DE, 0x7B60,
+	0xF3DF, 0x7B6E, 0xF3E0, 0x7B7B, 0xF3E1, 0x7B62, 0xF3E2, 0x7B72,
+	0xF3E3, 0x7B71, 0xF3E4, 0x7B90, 0xF3E5, 0x7BA6, 0xF3E6, 0x7BA7,
+	0xF3E7, 0x7BB8, 0xF3E8, 0x7BAC, 0xF3E9, 0x7B9D, 0xF3EA, 0x7BA8,
+	0xF3EB, 0x7B85, 0xF3EC, 0x7BAA, 0xF3ED, 0x7B9C, 0xF3EE, 0x7BA2,
+	0xF3EF, 0x7BAB, 0xF3F0, 0x7BB4, 0xF3F1, 0x7BD1, 0xF3F2, 0x7BC1,
+	0xF3F3, 0x7BCC, 0xF3F4, 0x7BDD, 0xF3F5, 0x7BDA, 0xF3F6, 0x7BE5,
+	0xF3F7, 0x7BE6, 0xF3F8, 0x7BEA, 0xF3F9, 0x7C0C, 0xF3FA, 0x7BFE,
+	0xF3FB, 0x7BFC, 0xF3FC, 0x7C0F, 0xF3FD, 0x7C16, 0xF3FE, 0x7C0B,
+	0xF440, 0x9B07, 0xF441, 0x9B09, 0xF442, 0x9B0A, 0xF443, 0x9B0B,
+	0xF444, 0x9B0C, 0xF445, 0x9B0D, 0xF446, 0x9B0E, 0xF447, 0x9B10,
+	0xF448, 0x9B11, 0xF449, 0x9B12, 0xF44A, 0x9B14, 0xF44B, 0x9B15,
+	0xF44C, 0x9B16, 0xF44D, 0x9B17, 0xF44E, 0x9B18, 0xF44F, 0x9B19,
+	0xF450, 0x9B1A, 0xF451, 0x9B1B, 0xF452, 0x9B1C, 0xF453, 0x9B1D,
+	0xF454, 0x9B1E, 0xF455, 0x9B20, 0xF456, 0x9B21, 0xF457, 0x9B22,
+	0xF458, 0x9B24, 0xF459, 0x9B25, 0xF45A, 0x9B26, 0xF45B, 0x9B27,
+	0xF45C, 0x9B28, 0xF45D, 0x9B29, 0xF45E, 0x9B2A, 0xF45F, 0x9B2B,
+	0xF460, 0x9B2C, 0xF461, 0x9B2D, 0xF462, 0x9B2E, 0xF463, 0x9B30,
+	0xF464, 0x9B31, 0xF465, 0x9B33, 0xF466, 0x9B34, 0xF467, 0x9B35,
+	0xF468, 0x9B36, 0xF469, 0x9B37, 0xF46A, 0x9B38, 0xF46B, 0x9B39,
+	0xF46C, 0x9B3A, 0xF46D, 0x9B3D, 0xF46E, 0x9B3E, 0xF46F, 0x9B3F,
+	0xF470, 0x9B40, 0xF471, 0x9B46, 0xF472, 0x9B4A, 0xF473, 0x9B4B,
+	0xF474, 0x9B4C, 0xF475, 0x9B4E, 0xF476, 0x9B50, 0xF477, 0x9B52,
+	0xF478, 0x9B53, 0xF479, 0x9B55, 0xF47A, 0x9B56, 0xF47B, 0x9B57,
+	0xF47C, 0x9B58, 0xF47D, 0x9B59, 0xF47E, 0x9B5A, 0xF480, 0x9B5B,
+	0xF481, 0x9B5C, 0xF482, 0x9B5D, 0xF483, 0x9B5E, 0xF484, 0x9B5F,
+	0xF485, 0x9B60, 0xF486, 0x9B61, 0xF487, 0x9B62, 0xF488, 0x9B63,
+	0xF489, 0x9B64, 0xF48A, 0x9B65, 0xF48B, 0x9B66, 0xF48C, 0x9B67,
+	0xF48D, 0x9B68, 0xF48E, 0x9B69, 0xF48F, 0x9B6A, 0xF490, 0x9B6B,
+	0xF491, 0x9B6C, 0xF492, 0x9B6D, 0xF493, 0x9B6E, 0xF494, 0x9B6F,
+	0xF495, 0x9B70, 0xF496, 0x9B71, 0xF497, 0x9B72, 0xF498, 0x9B73,
+	0xF499, 0x9B74, 0xF49A, 0x9B75, 0xF49B, 0x9B76, 0xF49C, 0x9B77,
+	0xF49D, 0x9B78, 0xF49E, 0x9B79, 0xF49F, 0x9B7A, 0xF4A0, 0x9B7B,
+	0xF4A1, 0x7C1F, 0xF4A2, 0x7C2A, 0xF4A3, 0x7C26, 0xF4A4, 0x7C38,
+	0xF4A5, 0x7C41, 0xF4A6, 0x7C40, 0xF4A7, 0x81FE, 0xF4A8, 0x8201,
+	0xF4A9, 0x8202, 0xF4AA, 0x8204, 0xF4AB, 0x81EC, 0xF4AC, 0x8844,
+	0xF4AD, 0x8221, 0xF4AE, 0x8222, 0xF4AF, 0x8223, 0xF4B0, 0x822D,
+	0xF4B1, 0x822F, 0xF4B2, 0x8228, 0xF4B3, 0x822B, 0xF4B4, 0x8238,
+	0xF4B5, 0x823B, 0xF4B6, 0x8233, 0xF4B7, 0x8234, 0xF4B8, 0x823E,
+	0xF4B9, 0x8244, 0xF4BA, 0x8249, 0xF4BB, 0x824B, 0xF4BC, 0x824F,
+	0xF4BD, 0x825A, 0xF4BE, 0x825F, 0xF4BF, 0x8268, 0xF4C0, 0x887E,
+	0xF4C1, 0x8885, 0xF4C2, 0x8888, 0xF4C3, 0x88D8, 0xF4C4, 0x88DF,
+	0xF4C5, 0x895E, 0xF4C6, 0x7F9D, 0xF4C7, 0x7F9F, 0xF4C8, 0x7FA7,
+	0xF4C9, 0x7FAF, 0xF4CA, 0x7FB0, 0xF4CB, 0x7FB2, 0xF4CC, 0x7C7C,
+	0xF4CD, 0x6549, 0xF4CE, 0x7C91, 0xF4CF, 0x7C9D, 0xF4D0, 0x7C9C,
+	0xF4D1, 0x7C9E, 0xF4D2, 0x7CA2, 0xF4D3, 0x7CB2, 0xF4D4, 0x7CBC,
+	0xF4D5, 0x7CBD, 0xF4D6, 0x7CC1, 0xF4D7, 0x7CC7, 0xF4D8, 0x7CCC,
+	0xF4D9, 0x7CCD, 0xF4DA, 0x7CC8, 0xF4DB, 0x7CC5, 0xF4DC, 0x7CD7,
+	0xF4DD, 0x7CE8, 0xF4DE, 0x826E, 0xF4DF, 0x66A8, 0xF4E0, 0x7FBF,
+	0xF4E1, 0x7FCE, 0xF4E2, 0x7FD5, 0xF4E3, 0x7FE5, 0xF4E4, 0x7FE1,
+	0xF4E5, 0x7FE6, 0xF4E6, 0x7FE9, 0xF4E7, 0x7FEE, 0xF4E8, 0x7FF3,
+	0xF4E9, 0x7CF8, 0xF4EA, 0x7D77, 0xF4EB, 0x7DA6, 0xF4EC, 0x7DAE,
+	0xF4ED, 0x7E47, 0xF4EE, 0x7E9B, 0xF4EF, 0x9EB8, 0xF4F0, 0x9EB4,
+	0xF4F1, 0x8D73, 0xF4F2, 0x8D84, 0xF4F3, 0x8D94, 0xF4F4, 0x8D91,
+	0xF4F5, 0x8DB1, 0xF4F6, 0x8D67, 0xF4F7, 0x8D6D, 0xF4F8, 0x8C47,
+	0xF4F9, 0x8C49, 0xF4FA, 0x914A, 0xF4FB, 0x9150, 0xF4FC, 0x914E,
+	0xF4FD, 0x914F, 0xF4FE, 0x9164, 0xF540, 0x9B7C, 0xF541, 0x9B7D,
+	0xF542, 0x9B7E, 0xF543, 0x9B7F, 0xF544, 0x9B80, 0xF545, 0x9B81,
+	0xF546, 0x9B82, 0xF547, 0x9B83, 0xF548, 0x9B84, 0xF549, 0x9B85,
+	0xF54A, 0x9B86, 0xF54B, 0x9B87, 0xF54C, 0x9B88, 0xF54D, 0x9B89,
+	0xF54E, 0x9B8A, 0xF54F, 0x9B8B, 0xF550, 0x9B8C, 0xF551, 0x9B8D,
+	0xF552, 0x9B8E, 0xF553, 0x9B8F, 0xF554, 0x9B90, 0xF555, 0x9B91,
+	0xF556, 0x9B92, 0xF557, 0x9B93, 0xF558, 0x9B94, 0xF559, 0x9B95,
+	0xF55A, 0x9B96, 0xF55B, 0x9B97, 0xF55C, 0x9B98, 0xF55D, 0x9B99,
+	0xF55E, 0x9B9A, 0xF55F, 0x9B9B, 0xF560, 0x9B9C, 0xF561, 0x9B9D,
+	0xF562, 0x9B9E, 0xF563, 0x9B9F, 0xF564, 0x9BA0, 0xF565, 0x9BA1,
+	0xF566, 0x9BA2, 0xF567, 0x9BA3, 0xF568, 0x9BA4, 0xF569, 0x9BA5,
+	0xF56A, 0x9BA6, 0xF56B, 0x9BA7, 0xF56C, 0x9BA8, 0xF56D, 0x9BA9,
+	0xF56E, 0x9BAA, 0xF56F, 0x9BAB, 0xF570, 0x9BAC, 0xF571, 0x9BAD,
+	0xF572, 0x9BAE, 0xF573, 0x9BAF, 0xF574, 0x9BB0, 0xF575, 0x9BB1,
+	0xF576, 0x9BB2, 0xF577, 0x9BB3, 0xF578, 0x9BB4, 0xF579, 0x9BB5,
+	0xF57A, 0x9BB6, 0xF57B, 0x9BB7, 0xF57C, 0x9BB8, 0xF57D, 0x9BB9,
+	0xF57E, 0x9BBA, 0xF580, 0x9BBB, 0xF581, 0x9BBC, 0xF582, 0x9BBD,
+	0xF583, 0x9BBE, 0xF584, 0x9BBF, 0xF585, 0x9BC0, 0xF586, 0x9BC1,
+	0xF587, 0x9BC2, 0xF588, 0x9BC3, 0xF589, 0x9BC4, 0xF58A, 0x9BC5,
+	0xF58B, 0x9BC6, 0xF58C, 0x9BC7, 0xF58D, 0x9BC8, 0xF58E, 0x9BC9,
+	0xF58F, 0x9BCA, 0xF590, 0x9BCB, 0xF591, 0x9BCC, 0xF592, 0x9BCD,
+	0xF593, 0x9BCE, 0xF594, 0x9BCF, 0xF595, 0x9BD0, 0xF596, 0x9BD1,
+	0xF597, 0x9BD2, 0xF598, 0x9BD3, 0xF599, 0x9BD4, 0xF59A, 0x9BD5,
+	0xF59B, 0x9BD6, 0xF59C, 0x9BD7, 0xF59D, 0x9BD8, 0xF59E, 0x9BD9,
+	0xF59F, 0x9BDA, 0xF5A0, 0x9BDB, 0xF5A1, 0x9162, 0xF5A2, 0x9161,
+	0xF5A3, 0x9170, 0xF5A4, 0x9169, 0xF5A5, 0x916F, 0xF5A6, 0x917D,
+	0xF5A7, 0x917E, 0xF5A8, 0x9172, 0xF5A9, 0x9174, 0xF5AA, 0x9179,
+	0xF5AB, 0x918C, 0xF5AC, 0x9185, 0xF5AD, 0x9190, 0xF5AE, 0x918D,
+	0xF5AF, 0x9191, 0xF5B0, 0x91A2, 0xF5B1, 0x91A3, 0xF5B2, 0x91AA,
+	0xF5B3, 0x91AD, 0xF5B4, 0x91AE, 0xF5B5, 0x91AF, 0xF5B6, 0x91B5,
+	0xF5B7, 0x91B4, 0xF5B8, 0x91BA, 0xF5B9, 0x8C55, 0xF5BA, 0x9E7E,
+	0xF5BB, 0x8DB8, 0xF5BC, 0x8DEB, 0xF5BD, 0x8E05, 0xF5BE, 0x8E59,
+	0xF5BF, 0x8E69, 0xF5C0, 0x8DB5, 0xF5C1, 0x8DBF, 0xF5C2, 0x8DBC,
+	0xF5C3, 0x8DBA, 0xF5C4, 0x8DC4, 0xF5C5, 0x8DD6, 0xF5C6, 0x8DD7,
+	0xF5C7, 0x8DDA, 0xF5C8, 0x8DDE, 0xF5C9, 0x8DCE, 0xF5CA, 0x8DCF,
+	0xF5CB, 0x8DDB, 0xF5CC, 0x8DC6, 0xF5CD, 0x8DEC, 0xF5CE, 0x8DF7,
+	0xF5CF, 0x8DF8, 0xF5D0, 0x8DE3, 0xF5D1, 0x8DF9, 0xF5D2, 0x8DFB,
+	0xF5D3, 0x8DE4, 0xF5D4, 0x8E09, 0xF5D5, 0x8DFD, 0xF5D6, 0x8E14,
+	0xF5D7, 0x8E1D, 0xF5D8, 0x8E1F, 0xF5D9, 0x8E2C, 0xF5DA, 0x8E2E,
+	0xF5DB, 0x8E23, 0xF5DC, 0x8E2F, 0xF5DD, 0x8E3A, 0xF5DE, 0x8E40,
+	0xF5DF, 0x8E39, 0xF5E0, 0x8E35, 0xF5E1, 0x8E3D, 0xF5E2, 0x8E31,
+	0xF5E3, 0x8E49, 0xF5E4, 0x8E41, 0xF5E5, 0x8E42, 0xF5E6, 0x8E51,
+	0xF5E7, 0x8E52, 0xF5E8, 0x8E4A, 0xF5E9, 0x8E70, 0xF5EA, 0x8E76,
+	0xF5EB, 0x8E7C, 0xF5EC, 0x8E6F, 0xF5ED, 0x8E74, 0xF5EE, 0x8E85,
+	0xF5EF, 0x8E8F, 0xF5F0, 0x8E94, 0xF5F1, 0x8E90, 0xF5F2, 0x8E9C,
+	0xF5F3, 0x8E9E, 0xF5F4, 0x8C78, 0xF5F5, 0x8C82, 0xF5F6, 0x8C8A,
+	0xF5F7, 0x8C85, 0xF5F8, 0x8C98, 0xF5F9, 0x8C94, 0xF5FA, 0x659B,
+	0xF5FB, 0x89D6, 0xF5FC, 0x89DE, 0xF5FD, 0x89DA, 0xF5FE, 0x89DC,
+	0xF640, 0x9BDC, 0xF641, 0x9BDD, 0xF642, 0x9BDE, 0xF643, 0x9BDF,
+	0xF644, 0x9BE0, 0xF645, 0x9BE1, 0xF646, 0x9BE2, 0xF647, 0x9BE3,
+	0xF648, 0x9BE4, 0xF649, 0x9BE5, 0xF64A, 0x9BE6, 0xF64B, 0x9BE7,
+	0xF64C, 0x9BE8, 0xF64D, 0x9BE9, 0xF64E, 0x9BEA, 0xF64F, 0x9BEB,
+	0xF650, 0x9BEC, 0xF651, 0x9BED, 0xF652, 0x9BEE, 0xF653, 0x9BEF,
+	0xF654, 0x9BF0, 0xF655, 0x9BF1, 0xF656, 0x9BF2, 0xF657, 0x9BF3,
+	0xF658, 0x9BF4, 0xF659, 0x9BF5, 0xF65A, 0x9BF6, 0xF65B, 0x9BF7,
+	0xF65C, 0x9BF8, 0xF65D, 0x9BF9, 0xF65E, 0x9BFA, 0xF65F, 0x9BFB,
+	0xF660, 0x9BFC, 0xF661, 0x9BFD, 0xF662, 0x9BFE, 0xF663, 0x9BFF,
+	0xF664, 0x9C00, 0xF665, 0x9C01, 0xF666, 0x9C02, 0xF667, 0x9C03,
+	0xF668, 0x9C04, 0xF669, 0x9C05, 0xF66A, 0x9C06, 0xF66B, 0x9C07,
+	0xF66C, 0x9C08, 0xF66D, 0x9C09, 0xF66E, 0x9C0A, 0xF66F, 0x9C0B,
+	0xF670, 0x9C0C, 0xF671, 0x9C0D, 0xF672, 0x9C0E, 0xF673, 0x9C0F,
+	0xF674, 0x9C10, 0xF675, 0x9C11, 0xF676, 0x9C12, 0xF677, 0x9C13,
+	0xF678, 0x9C14, 0xF679, 0x9C15, 0xF67A, 0x9C16, 0xF67B, 0x9C17,
+	0xF67C, 0x9C18, 0xF67D, 0x9C19, 0xF67E, 0x9C1A, 0xF680, 0x9C1B,
+	0xF681, 0x9C1C, 0xF682, 0x9C1D, 0xF683, 0x9C1E, 0xF684, 0x9C1F,
+	0xF685, 0x9C20, 0xF686, 0x9C21, 0xF687, 0x9C22, 0xF688, 0x9C23,
+	0xF689, 0x9C24, 0xF68A, 0x9C25, 0xF68B, 0x9C26, 0xF68C, 0x9C27,
+	0xF68D, 0x9C28, 0xF68E, 0x9C29, 0xF68F, 0x9C2A, 0xF690, 0x9C2B,
+	0xF691, 0x9C2C, 0xF692, 0x9C2D, 0xF693, 0x9C2E, 0xF694, 0x9C2F,
+	0xF695, 0x9C30, 0xF696, 0x9C31, 0xF697, 0x9C32, 0xF698, 0x9C33,
+	0xF699, 0x9C34, 0xF69A, 0x9C35, 0xF69B, 0x9C36, 0xF69C, 0x9C37,
+	0xF69D, 0x9C38, 0xF69E, 0x9C39, 0xF69F, 0x9C3A, 0xF6A0, 0x9C3B,
+	0xF6A1, 0x89E5, 0xF6A2, 0x89EB, 0xF6A3, 0x89EF, 0xF6A4, 0x8A3E,
+	0xF6A5, 0x8B26, 0xF6A6, 0x9753, 0xF6A7, 0x96E9, 0xF6A8, 0x96F3,
+	0xF6A9, 0x96EF, 0xF6AA, 0x9706, 0xF6AB, 0x9701, 0xF6AC, 0x9708,
+	0xF6AD, 0x970F, 0xF6AE, 0x970E, 0xF6AF, 0x972A, 0xF6B0, 0x972D,
+	0xF6B1, 0x9730, 0xF6B2, 0x973E, 0xF6B3, 0x9F80, 0xF6B4, 0x9F83,
+	0xF6B5, 0x9F85, 0xF6B6, 0x9F86, 0xF6B7, 0x9F87, 0xF6B8, 0x9F88,
+	0xF6B9, 0x9F89, 0xF6BA, 0x9F8A, 0xF6BB, 0x9F8C, 0xF6BC, 0x9EFE,
+	0xF6BD, 0x9F0B, 0xF6BE, 0x9F0D, 0xF6BF, 0x96B9, 0xF6C0, 0x96BC,
+	0xF6C1, 0x96BD, 0xF6C2, 0x96CE, 0xF6C3, 0x96D2, 0xF6C4, 0x77BF,
+	0xF6C5, 0x96E0, 0xF6C6, 0x928E, 0xF6C7, 0x92AE, 0xF6C8, 0x92C8,
+	0xF6C9, 0x933E, 0xF6CA, 0x936A, 0xF6CB, 0x93CA, 0xF6CC, 0x938F,
+	0xF6CD, 0x943E, 0xF6CE, 0x946B, 0xF6CF, 0x9C7F, 0xF6D0, 0x9C82,
+	0xF6D1, 0x9C85, 0xF6D2, 0x9C86, 0xF6D3, 0x9C87, 0xF6D4, 0x9C88,
+	0xF6D5, 0x7A23, 0xF6D6, 0x9C8B, 0xF6D7, 0x9C8E, 0xF6D8, 0x9C90,
+	0xF6D9, 0x9C91, 0xF6DA, 0x9C92, 0xF6DB, 0x9C94, 0xF6DC, 0x9C95,
+	0xF6DD, 0x9C9A, 0xF6DE, 0x9C9B, 0xF6DF, 0x9C9E, 0xF6E0, 0x9C9F,
+	0xF6E1, 0x9CA0, 0xF6E2, 0x9CA1, 0xF6E3, 0x9CA2, 0xF6E4, 0x9CA3,
+	0xF6E5, 0x9CA5, 0xF6E6, 0x9CA6, 0xF6E7, 0x9CA7, 0xF6E8, 0x9CA8,
+	0xF6E9, 0x9CA9, 0xF6EA, 0x9CAB, 0xF6EB, 0x9CAD, 0xF6EC, 0x9CAE,
+	0xF6ED, 0x9CB0, 0xF6EE, 0x9CB1, 0xF6EF, 0x9CB2, 0xF6F0, 0x9CB3,
+	0xF6F1, 0x9CB4, 0xF6F2, 0x9CB5, 0xF6F3, 0x9CB6, 0xF6F4, 0x9CB7,
+	0xF6F5, 0x9CBA, 0xF6F6, 0x9CBB, 0xF6F7, 0x9CBC, 0xF6F8, 0x9CBD,
+	0xF6F9, 0x9CC4, 0xF6FA, 0x9CC5, 0xF6FB, 0x9CC6, 0xF6FC, 0x9CC7,
+	0xF6FD, 0x9CCA, 0xF6FE, 0x9CCB, 0xF740, 0x9C3C, 0xF741, 0x9C3D,
+	0xF742, 0x9C3E, 0xF743, 0x9C3F, 0xF744, 0x9C40, 0xF745, 0x9C41,
+	0xF746, 0x9C42, 0xF747, 0x9C43, 0xF748, 0x9C44, 0xF749, 0x9C45,
+	0xF74A, 0x9C46, 0xF74B, 0x9C47, 0xF74C, 0x9C48, 0xF74D, 0x9C49,
+	0xF74E, 0x9C4A, 0xF74F, 0x9C4B, 0xF750, 0x9C4C, 0xF751, 0x9C4D,
+	0xF752, 0x9C4E, 0xF753, 0x9C4F, 0xF754, 0x9C50, 0xF755, 0x9C51,
+	0xF756, 0x9C52, 0xF757, 0x9C53, 0xF758, 0x9C54, 0xF759, 0x9C55,
+	0xF75A, 0x9C56, 0xF75B, 0x9C57, 0xF75C, 0x9C58, 0xF75D, 0x9C59,
+	0xF75E, 0x9C5A, 0xF75F, 0x9C5B, 0xF760, 0x9C5C, 0xF761, 0x9C5D,
+	0xF762, 0x9C5E, 0xF763, 0x9C5F, 0xF764, 0x9C60, 0xF765, 0x9C61,
+	0xF766, 0x9C62, 0xF767, 0x9C63, 0xF768, 0x9C64, 0xF769, 0x9C65,
+	0xF76A, 0x9C66, 0xF76B, 0x9C67, 0xF76C, 0x9C68, 0xF76D, 0x9C69,
+	0xF76E, 0x9C6A, 0xF76F, 0x9C6B, 0xF770, 0x9C6C, 0xF771, 0x9C6D,
+	0xF772, 0x9C6E, 0xF773, 0x9C6F, 0xF774, 0x9C70, 0xF775, 0x9C71,
+	0xF776, 0x9C72, 0xF777, 0x9C73, 0xF778, 0x9C74, 0xF779, 0x9C75,
+	0xF77A, 0x9C76, 0xF77B, 0x9C77, 0xF77C, 0x9C78, 0xF77D, 0x9C79,
+	0xF77E, 0x9C7A, 0xF780, 0x9C7B, 0xF781, 0x9C7D, 0xF782, 0x9C7E,
+	0xF783, 0x9C80, 0xF784, 0x9C83, 0xF785, 0x9C84, 0xF786, 0x9C89,
+	0xF787, 0x9C8A, 0xF788, 0x9C8C, 0xF789, 0x9C8F, 0xF78A, 0x9C93,
+	0xF78B, 0x9C96, 0xF78C, 0x9C97, 0xF78D, 0x9C98, 0xF78E, 0x9C99,
+	0xF78F, 0x9C9D, 0xF790, 0x9CAA, 0xF791, 0x9CAC, 0xF792, 0x9CAF,
+	0xF793, 0x9CB9, 0xF794, 0x9CBE, 0xF795, 0x9CBF, 0xF796, 0x9CC0,
+	0xF797, 0x9CC1, 0xF798, 0x9CC2, 0xF799, 0x9CC8, 0xF79A, 0x9CC9,
+	0xF79B, 0x9CD1, 0xF79C, 0x9CD2, 0xF79D, 0x9CDA, 0xF79E, 0x9CDB,
+	0xF79F, 0x9CE0, 0xF7A0, 0x9CE1, 0xF7A1, 0x9CCC, 0xF7A2, 0x9CCD,
+	0xF7A3, 0x9CCE, 0xF7A4, 0x9CCF, 0xF7A5, 0x9CD0, 0xF7A6, 0x9CD3,
+	0xF7A7, 0x9CD4, 0xF7A8, 0x9CD5, 0xF7A9, 0x9CD7, 0xF7AA, 0x9CD8,
+	0xF7AB, 0x9CD9, 0xF7AC, 0x9CDC, 0xF7AD, 0x9CDD, 0xF7AE, 0x9CDF,
+	0xF7AF, 0x9CE2, 0xF7B0, 0x977C, 0xF7B1, 0x9785, 0xF7B2, 0x9791,
+	0xF7B3, 0x9792, 0xF7B4, 0x9794, 0xF7B5, 0x97AF, 0xF7B6, 0x97AB,
+	0xF7B7, 0x97A3, 0xF7B8, 0x97B2, 0xF7B9, 0x97B4, 0xF7BA, 0x9AB1,
+	0xF7BB, 0x9AB0, 0xF7BC, 0x9AB7, 0xF7BD, 0x9E58, 0xF7BE, 0x9AB6,
+	0xF7BF, 0x9ABA, 0xF7C0, 0x9ABC, 0xF7C1, 0x9AC1, 0xF7C2, 0x9AC0,
+	0xF7C3, 0x9AC5, 0xF7C4, 0x9AC2, 0xF7C5, 0x9ACB, 0xF7C6, 0x9ACC,
+	0xF7C7, 0x9AD1, 0xF7C8, 0x9B45, 0xF7C9, 0x9B43, 0xF7CA, 0x9B47,
+	0xF7CB, 0x9B49, 0xF7CC, 0x9B48, 0xF7CD, 0x9B4D, 0xF7CE, 0x9B51,
+	0xF7CF, 0x98E8, 0xF7D0, 0x990D, 0xF7D1, 0x992E, 0xF7D2, 0x9955,
+	0xF7D3, 0x9954, 0xF7D4, 0x9ADF, 0xF7D5, 0x9AE1, 0xF7D6, 0x9AE6,
+	0xF7D7, 0x9AEF, 0xF7D8, 0x9AEB, 0xF7D9, 0x9AFB, 0xF7DA, 0x9AED,
+	0xF7DB, 0x9AF9, 0xF7DC, 0x9B08, 0xF7DD, 0x9B0F, 0xF7DE, 0x9B13,
+	0xF7DF, 0x9B1F, 0xF7E0, 0x9B23, 0xF7E1, 0x9EBD, 0xF7E2, 0x9EBE,
+	0xF7E3, 0x7E3B, 0xF7E4, 0x9E82, 0xF7E5, 0x9E87, 0xF7E6, 0x9E88,
+	0xF7E7, 0x9E8B, 0xF7E8, 0x9E92, 0xF7E9, 0x93D6, 0xF7EA, 0x9E9D,
+	0xF7EB, 0x9E9F, 0xF7EC, 0x9EDB, 0xF7ED, 0x9EDC, 0xF7EE, 0x9EDD,
+	0xF7EF, 0x9EE0, 0xF7F0, 0x9EDF, 0xF7F1, 0x9EE2, 0xF7F2, 0x9EE9,
+	0xF7F3, 0x9EE7, 0xF7F4, 0x9EE5, 0xF7F5, 0x9EEA, 0xF7F6, 0x9EEF,
+	0xF7F7, 0x9F22, 0xF7F8, 0x9F2C, 0xF7F9, 0x9F2F, 0xF7FA, 0x9F39,
+	0xF7FB, 0x9F37, 0xF7FC, 0x9F3D, 0xF7FD, 0x9F3E, 0xF7FE, 0x9F44,
+	0xF840, 0x9CE3, 0xF841, 0x9CE4, 0xF842, 0x9CE5, 0xF843, 0x9CE6,
+	0xF844, 0x9CE7, 0xF845, 0x9CE8, 0xF846, 0x9CE9, 0xF847, 0x9CEA,
+	0xF848, 0x9CEB, 0xF849, 0x9CEC, 0xF84A, 0x9CED, 0xF84B, 0x9CEE,
+	0xF84C, 0x9CEF, 0xF84D, 0x9CF0, 0xF84E, 0x9CF1, 0xF84F, 0x9CF2,
+	0xF850, 0x9CF3, 0xF851, 0x9CF4, 0xF852, 0x9CF5, 0xF853, 0x9CF6,
+	0xF854, 0x9CF7, 0xF855, 0x9CF8, 0xF856, 0x9CF9, 0xF857, 0x9CFA,
+	0xF858, 0x9CFB, 0xF859, 0x9CFC, 0xF85A, 0x9CFD, 0xF85B, 0x9CFE,
+	0xF85C, 0x9CFF, 0xF85D, 0x9D00, 0xF85E, 0x9D01, 0xF85F, 0x9D02,
+	0xF860, 0x9D03, 0xF861, 0x9D04, 0xF862, 0x9D05, 0xF863, 0x9D06,
+	0xF864, 0x9D07, 0xF865, 0x9D08, 0xF866, 0x9D09, 0xF867, 0x9D0A,
+	0xF868, 0x9D0B, 0xF869, 0x9D0C, 0xF86A, 0x9D0D, 0xF86B, 0x9D0E,
+	0xF86C, 0x9D0F, 0xF86D, 0x9D10, 0xF86E, 0x9D11, 0xF86F, 0x9D12,
+	0xF870, 0x9D13, 0xF871, 0x9D14, 0xF872, 0x9D15, 0xF873, 0x9D16,
+	0xF874, 0x9D17, 0xF875, 0x9D18, 0xF876, 0x9D19, 0xF877, 0x9D1A,
+	0xF878, 0x9D1B, 0xF879, 0x9D1C, 0xF87A, 0x9D1D, 0xF87B, 0x9D1E,
+	0xF87C, 0x9D1F, 0xF87D, 0x9D20, 0xF87E, 0x9D21, 0xF880, 0x9D22,
+	0xF881, 0x9D23, 0xF882, 0x9D24, 0xF883, 0x9D25, 0xF884, 0x9D26,
+	0xF885, 0x9D27, 0xF886, 0x9D28, 0xF887, 0x9D29, 0xF888, 0x9D2A,
+	0xF889, 0x9D2B, 0xF88A, 0x9D2C, 0xF88B, 0x9D2D, 0xF88C, 0x9D2E,
+	0xF88D, 0x9D2F, 0xF88E, 0x9D30, 0xF88F, 0x9D31, 0xF890, 0x9D32,
+	0xF891, 0x9D33, 0xF892, 0x9D34, 0xF893, 0x9D35, 0xF894, 0x9D36,
+	0xF895, 0x9D37, 0xF896, 0x9D38, 0xF897, 0x9D39, 0xF898, 0x9D3A,
+	0xF899, 0x9D3B, 0xF89A, 0x9D3C, 0xF89B, 0x9D3D, 0xF89C, 0x9D3E,
+	0xF89D, 0x9D3F, 0xF89E, 0x9D40, 0xF89F, 0x9D41, 0xF8A0, 0x9D42,
+	0xF940, 0x9D43, 0xF941, 0x9D44, 0xF942, 0x9D45, 0xF943, 0x9D46,
+	0xF944, 0x9D47, 0xF945, 0x9D48, 0xF946, 0x9D49, 0xF947, 0x9D4A,
+	0xF948, 0x9D4B, 0xF949, 0x9D4C, 0xF94A, 0x9D4D, 0xF94B, 0x9D4E,
+	0xF94C, 0x9D4F, 0xF94D, 0x9D50, 0xF94E, 0x9D51, 0xF94F, 0x9D52,
+	0xF950, 0x9D53, 0xF951, 0x9D54, 0xF952, 0x9D55, 0xF953, 0x9D56,
+	0xF954, 0x9D57, 0xF955, 0x9D58, 0xF956, 0x9D59, 0xF957, 0x9D5A,
+	0xF958, 0x9D5B, 0xF959, 0x9D5C, 0xF95A, 0x9D5D, 0xF95B, 0x9D5E,
+	0xF95C, 0x9D5F, 0xF95D, 0x9D60, 0xF95E, 0x9D61, 0xF95F, 0x9D62,
+	0xF960, 0x9D63, 0xF961, 0x9D64, 0xF962, 0x9D65, 0xF963, 0x9D66,
+	0xF964, 0x9D67, 0xF965, 0x9D68, 0xF966, 0x9D69, 0xF967, 0x9D6A,
+	0xF968, 0x9D6B, 0xF969, 0x9D6C, 0xF96A, 0x9D6D, 0xF96B, 0x9D6E,
+	0xF96C, 0x9D6F, 0xF96D, 0x9D70, 0xF96E, 0x9D71, 0xF96F, 0x9D72,
+	0xF970, 0x9D73, 0xF971, 0x9D74, 0xF972, 0x9D75, 0xF973, 0x9D76,
+	0xF974, 0x9D77, 0xF975, 0x9D78, 0xF976, 0x9D79, 0xF977, 0x9D7A,
+	0xF978, 0x9D7B, 0xF979, 0x9D7C, 0xF97A, 0x9D7D, 0xF97B, 0x9D7E,
+	0xF97C, 0x9D7F, 0xF97D, 0x9D80, 0xF97E, 0x9D81, 0xF980, 0x9D82,
+	0xF981, 0x9D83, 0xF982, 0x9D84, 0xF983, 0x9D85, 0xF984, 0x9D86,
+	0xF985, 0x9D87, 0xF986, 0x9D88, 0xF987, 0x9D89, 0xF988, 0x9D8A,
+	0xF989, 0x9D8B, 0xF98A, 0x9D8C, 0xF98B, 0x9D8D, 0xF98C, 0x9D8E,
+	0xF98D, 0x9D8F, 0xF98E, 0x9D90, 0xF98F, 0x9D91, 0xF990, 0x9D92,
+	0xF991, 0x9D93, 0xF992, 0x9D94, 0xF993, 0x9D95, 0xF994, 0x9D96,
+	0xF995, 0x9D97, 0xF996, 0x9D98, 0xF997, 0x9D99, 0xF998, 0x9D9A,
+	0xF999, 0x9D9B, 0xF99A, 0x9D9C, 0xF99B, 0x9D9D, 0xF99C, 0x9D9E,
+	0xF99D, 0x9D9F, 0xF99E, 0x9DA0, 0xF99F, 0x9DA1, 0xF9A0, 0x9DA2,
+	0xFA40, 0x9DA3, 0xFA41, 0x9DA4, 0xFA42, 0x9DA5, 0xFA43, 0x9DA6,
+	0xFA44, 0x9DA7, 0xFA45, 0x9DA8, 0xFA46, 0x9DA9, 0xFA47, 0x9DAA,
+	0xFA48, 0x9DAB, 0xFA49, 0x9DAC, 0xFA4A, 0x9DAD, 0xFA4B, 0x9DAE,
+	0xFA4C, 0x9DAF, 0xFA4D, 0x9DB0, 0xFA4E, 0x9DB1, 0xFA4F, 0x9DB2,
+	0xFA50, 0x9DB3, 0xFA51, 0x9DB4, 0xFA52, 0x9DB5, 0xFA53, 0x9DB6,
+	0xFA54, 0x9DB7, 0xFA55, 0x9DB8, 0xFA56, 0x9DB9, 0xFA57, 0x9DBA,
+	0xFA58, 0x9DBB, 0xFA59, 0x9DBC, 0xFA5A, 0x9DBD, 0xFA5B, 0x9DBE,
+	0xFA5C, 0x9DBF, 0xFA5D, 0x9DC0, 0xFA5E, 0x9DC1, 0xFA5F, 0x9DC2,
+	0xFA60, 0x9DC3, 0xFA61, 0x9DC4, 0xFA62, 0x9DC5, 0xFA63, 0x9DC6,
+	0xFA64, 0x9DC7, 0xFA65, 0x9DC8, 0xFA66, 0x9DC9, 0xFA67, 0x9DCA,
+	0xFA68, 0x9DCB, 0xFA69, 0x9DCC, 0xFA6A, 0x9DCD, 0xFA6B, 0x9DCE,
+	0xFA6C, 0x9DCF, 0xFA6D, 0x9DD0, 0xFA6E, 0x9DD1, 0xFA6F, 0x9DD2,
+	0xFA70, 0x9DD3, 0xFA71, 0x9DD4, 0xFA72, 0x9DD5, 0xFA73, 0x9DD6,
+	0xFA74, 0x9DD7, 0xFA75, 0x9DD8, 0xFA76, 0x9DD9, 0xFA77, 0x9DDA,
+	0xFA78, 0x9DDB, 0xFA79, 0x9DDC, 0xFA7A, 0x9DDD, 0xFA7B, 0x9DDE,
+	0xFA7C, 0x9DDF, 0xFA7D, 0x9DE0, 0xFA7E, 0x9DE1, 0xFA80, 0x9DE2,
+	0xFA81, 0x9DE3, 0xFA82, 0x9DE4, 0xFA83, 0x9DE5, 0xFA84, 0x9DE6,
+	0xFA85, 0x9DE7, 0xFA86, 0x9DE8, 0xFA87, 0x9DE9, 0xFA88, 0x9DEA,
+	0xFA89, 0x9DEB, 0xFA8A, 0x9DEC, 0xFA8B, 0x9DED, 0xFA8C, 0x9DEE,
+	0xFA8D, 0x9DEF, 0xFA8E, 0x9DF0, 0xFA8F, 0x9DF1, 0xFA90, 0x9DF2,
+	0xFA91, 0x9DF3, 0xFA92, 0x9DF4, 0xFA93, 0x9DF5, 0xFA94, 0x9DF6,
+	0xFA95, 0x9DF7, 0xFA96, 0x9DF8, 0xFA97, 0x9DF9, 0xFA98, 0x9DFA,
+	0xFA99, 0x9DFB, 0xFA9A, 0x9DFC, 0xFA9B, 0x9DFD, 0xFA9C, 0x9DFE,
+	0xFA9D, 0x9DFF, 0xFA9E, 0x9E00, 0xFA9F, 0x9E01, 0xFAA0, 0x9E02,
+	0xFB40, 0x9E03, 0xFB41, 0x9E04, 0xFB42, 0x9E05, 0xFB43, 0x9E06,
+	0xFB44, 0x9E07, 0xFB45, 0x9E08, 0xFB46, 0x9E09, 0xFB47, 0x9E0A,
+	0xFB48, 0x9E0B, 0xFB49, 0x9E0C, 0xFB4A, 0x9E0D, 0xFB4B, 0x9E0E,
+	0xFB4C, 0x9E0F, 0xFB4D, 0x9E10, 0xFB4E, 0x9E11, 0xFB4F, 0x9E12,
+	0xFB50, 0x9E13, 0xFB51, 0x9E14, 0xFB52, 0x9E15, 0xFB53, 0x9E16,
+	0xFB54, 0x9E17, 0xFB55, 0x9E18, 0xFB56, 0x9E19, 0xFB57, 0x9E1A,
+	0xFB58, 0x9E1B, 0xFB59, 0x9E1C, 0xFB5A, 0x9E1D, 0xFB5B, 0x9E1E,
+	0xFB5C, 0x9E24, 0xFB5D, 0x9E27, 0xFB5E, 0x9E2E, 0xFB5F, 0x9E30,
+	0xFB60, 0x9E34, 0xFB61, 0x9E3B, 0xFB62, 0x9E3C, 0xFB63, 0x9E40,
+	0xFB64, 0x9E4D, 0xFB65, 0x9E50, 0xFB66, 0x9E52, 0xFB67, 0x9E53,
+	0xFB68, 0x9E54, 0xFB69, 0x9E56, 0xFB6A, 0x9E59, 0xFB6B, 0x9E5D,
+	0xFB6C, 0x9E5F, 0xFB6D, 0x9E60, 0xFB6E, 0x9E61, 0xFB6F, 0x9E62,
+	0xFB70, 0x9E65, 0xFB71, 0x9E6E, 0xFB72, 0x9E6F, 0xFB73, 0x9E72,
+	0xFB74, 0x9E74, 0xFB75, 0x9E75, 0xFB76, 0x9E76, 0xFB77, 0x9E77,
+	0xFB78, 0x9E78, 0xFB79, 0x9E79, 0xFB7A, 0x9E7A, 0xFB7B, 0x9E7B,
+	0xFB7C, 0x9E7C, 0xFB7D, 0x9E7D, 0xFB7E, 0x9E80, 0xFB80, 0x9E81,
+	0xFB81, 0x9E83, 0xFB82, 0x9E84, 0xFB83, 0x9E85, 0xFB84, 0x9E86,
+	0xFB85, 0x9E89, 0xFB86, 0x9E8A, 0xFB87, 0x9E8C, 0xFB88, 0x9E8D,
+	0xFB89, 0x9E8E, 0xFB8A, 0x9E8F, 0xFB8B, 0x9E90, 0xFB8C, 0x9E91,
+	0xFB8D, 0x9E94, 0xFB8E, 0x9E95, 0xFB8F, 0x9E96, 0xFB90, 0x9E97,
+	0xFB91, 0x9E98, 0xFB92, 0x9E99, 0xFB93, 0x9E9A, 0xFB94, 0x9E9B,
+	0xFB95, 0x9E9C, 0xFB96, 0x9E9E, 0xFB97, 0x9EA0, 0xFB98, 0x9EA1,
+	0xFB99, 0x9EA2, 0xFB9A, 0x9EA3, 0xFB9B, 0x9EA4, 0xFB9C, 0x9EA5,
+	0xFB9D, 0x9EA7, 0xFB9E, 0x9EA8, 0xFB9F, 0x9EA9, 0xFBA0, 0x9EAA,
+	0xFC40, 0x9EAB, 0xFC41, 0x9EAC, 0xFC42, 0x9EAD, 0xFC43, 0x9EAE,
+	0xFC44, 0x9EAF, 0xFC45, 0x9EB0, 0xFC46, 0x9EB1, 0xFC47, 0x9EB2,
+	0xFC48, 0x9EB3, 0xFC49, 0x9EB5, 0xFC4A, 0x9EB6, 0xFC4B, 0x9EB7,
+	0xFC4C, 0x9EB9, 0xFC4D, 0x9EBA, 0xFC4E, 0x9EBC, 0xFC4F, 0x9EBF,
+	0xFC50, 0x9EC0, 0xFC51, 0x9EC1, 0xFC52, 0x9EC2, 0xFC53, 0x9EC3,
+	0xFC54, 0x9EC5, 0xFC55, 0x9EC6, 0xFC56, 0x9EC7, 0xFC57, 0x9EC8,
+	0xFC58, 0x9ECA, 0xFC59, 0x9ECB, 0xFC5A, 0x9ECC, 0xFC5B, 0x9ED0,
+	0xFC5C, 0x9ED2, 0xFC5D, 0x9ED3, 0xFC5E, 0x9ED5, 0xFC5F, 0x9ED6,
+	0xFC60, 0x9ED7, 0xFC61, 0x9ED9, 0xFC62, 0x9EDA, 0xFC63, 0x9EDE,
+	0xFC64, 0x9EE1, 0xFC65, 0x9EE3, 0xFC66, 0x9EE4, 0xFC67, 0x9EE6,
+	0xFC68, 0x9EE8, 0xFC69, 0x9EEB, 0xFC6A, 0x9EEC, 0xFC6B, 0x9EED,
+	0xFC6C, 0x9EEE, 0xFC6D, 0x9EF0, 0xFC6E, 0x9EF1, 0xFC6F, 0x9EF2,
+	0xFC70, 0x9EF3, 0xFC71, 0x9EF4, 0xFC72, 0x9EF5, 0xFC73, 0x9EF6,
+	0xFC74, 0x9EF7, 0xFC75, 0x9EF8, 0xFC76, 0x9EFA, 0xFC77, 0x9EFD,
+	0xFC78, 0x9EFF, 0xFC79, 0x9F00, 0xFC7A, 0x9F01, 0xFC7B, 0x9F02,
+	0xFC7C, 0x9F03, 0xFC7D, 0x9F04, 0xFC7E, 0x9F05, 0xFC80, 0x9F06,
+	0xFC81, 0x9F07, 0xFC82, 0x9F08, 0xFC83, 0x9F09, 0xFC84, 0x9F0A,
+	0xFC85, 0x9F0C, 0xFC86, 0x9F0F, 0xFC87, 0x9F11, 0xFC88, 0x9F12,
+	0xFC89, 0x9F14, 0xFC8A, 0x9F15, 0xFC8B, 0x9F16, 0xFC8C, 0x9F18,
+	0xFC8D, 0x9F1A, 0xFC8E, 0x9F1B, 0xFC8F, 0x9F1C, 0xFC90, 0x9F1D,
+	0xFC91, 0x9F1E, 0xFC92, 0x9F1F, 0xFC93, 0x9F21, 0xFC94, 0x9F23,
+	0xFC95, 0x9F24, 0xFC96, 0x9F25, 0xFC97, 0x9F26, 0xFC98, 0x9F27,
+	0xFC99, 0x9F28, 0xFC9A, 0x9F29, 0xFC9B, 0x9F2A, 0xFC9C, 0x9F2B,
+	0xFC9D, 0x9F2D, 0xFC9E, 0x9F2E, 0xFC9F, 0x9F30, 0xFCA0, 0x9F31,
+	0xFD40, 0x9F32, 0xFD41, 0x9F33, 0xFD42, 0x9F34, 0xFD43, 0x9F35,
+	0xFD44, 0x9F36, 0xFD45, 0x9F38, 0xFD46, 0x9F3A, 0xFD47, 0x9F3C,
+	0xFD48, 0x9F3F, 0xFD49, 0x9F40, 0xFD4A, 0x9F41, 0xFD4B, 0x9F42,
+	0xFD4C, 0x9F43, 0xFD4D, 0x9F45, 0xFD4E, 0x9F46, 0xFD4F, 0x9F47,
+	0xFD50, 0x9F48, 0xFD51, 0x9F49, 0xFD52, 0x9F4A, 0xFD53, 0x9F4B,
+	0xFD54, 0x9F4C, 0xFD55, 0x9F4D, 0xFD56, 0x9F4E, 0xFD57, 0x9F4F,
+	0xFD58, 0x9F52, 0xFD59, 0x9F53, 0xFD5A, 0x9F54, 0xFD5B, 0x9F55,
+	0xFD5C, 0x9F56, 0xFD5D, 0x9F57, 0xFD5E, 0x9F58, 0xFD5F, 0x9F59,
+	0xFD60, 0x9F5A, 0xFD61, 0x9F5B, 0xFD62, 0x9F5C, 0xFD63, 0x9F5D,
+	0xFD64, 0x9F5E, 0xFD65, 0x9F5F, 0xFD66, 0x9F60, 0xFD67, 0x9F61,
+	0xFD68, 0x9F62, 0xFD69, 0x9F63, 0xFD6A, 0x9F64, 0xFD6B, 0x9F65,
+	0xFD6C, 0x9F66, 0xFD6D, 0x9F67, 0xFD6E, 0x9F68, 0xFD6F, 0x9F69,
+	0xFD70, 0x9F6A, 0xFD71, 0x9F6B, 0xFD72, 0x9F6C, 0xFD73, 0x9F6D,
+	0xFD74, 0x9F6E, 0xFD75, 0x9F6F, 0xFD76, 0x9F70, 0xFD77, 0x9F71,
+	0xFD78, 0x9F72, 0xFD79, 0x9F73, 0xFD7A, 0x9F74, 0xFD7B, 0x9F75,
+	0xFD7C, 0x9F76, 0xFD7D, 0x9F77, 0xFD7E, 0x9F78, 0xFD80, 0x9F79,
+	0xFD81, 0x9F7A, 0xFD82, 0x9F7B, 0xFD83, 0x9F7C, 0xFD84, 0x9F7D,
+	0xFD85, 0x9F7E, 0xFD86, 0x9F81, 0xFD87, 0x9F82, 0xFD88, 0x9F8D,
+	0xFD89, 0x9F8E, 0xFD8A, 0x9F8F, 0xFD8B, 0x9F90, 0xFD8C, 0x9F91,
+	0xFD8D, 0x9F92, 0xFD8E, 0x9F93, 0xFD8F, 0x9F94, 0xFD90, 0x9F95,
+	0xFD91, 0x9F96, 0xFD92, 0x9F97, 0xFD93, 0x9F98, 0xFD94, 0x9F9C,
+	0xFD95, 0x9F9D, 0xFD96, 0x9F9E, 0xFD97, 0x9FA1, 0xFD98, 0x9FA2,
+	0xFD99, 0x9FA3, 0xFD9A, 0x9FA4, 0xFD9B, 0x9FA5, 0xFD9C, 0xF92C,
+	0xFD9D, 0xF979, 0xFD9E, 0xF995, 0xFD9F, 0xF9E7, 0xFDA0, 0xF9F1,
+	0xFE40, 0xFA0C, 0xFE41, 0xFA0D, 0xFE42, 0xFA0E, 0xFE43, 0xFA0F,
+	0xFE44, 0xFA11, 0xFE45, 0xFA13, 0xFE46, 0xFA14, 0xFE47, 0xFA18,
+	0xFE48, 0xFA1F, 0xFE49, 0xFA20, 0xFE4A, 0xFA21, 0xFE4B, 0xFA23,
+	0xFE4C, 0xFA24, 0xFE4D, 0xFA27, 0xFE4E, 0xFA28, 0xFE4F, 0xFA29,
+	0, 0
+};
+
+
+
+WCHAR ff_convert (	/* Converted code, 0 means conversion error */
+	WCHAR	chr,	/* Character code to be converted */
+	UINT	dir		/* 0: Unicode to OEM code, 1: OEM code to Unicode */
+)
+{
+	const WCHAR *p;
+	WCHAR c;
+	int i, n, li, hi;
+
+
+	if (chr < 0x80) {	/* ASCII */
+		c = chr;
+	} else {
+		if (dir) {		/* OEM code to unicode */
+			p = oem2uni;
+			hi = sizeof oem2uni / 4 - 1;
+		} else {		/* Unicode to OEM code */
+			p = uni2oem;
+			hi = sizeof uni2oem / 4 - 1;
+		}
+		li = 0;
+		for (n = 16; n; n--) {
+			i = li + (hi - li) / 2;
+			if (chr == p[i * 2]) break;
+			if (chr > p[i * 2])
+				li = i;
+			else
+				hi = i;
+		}
+		c = n ? p[i * 2 + 1] : 0;
+	}
+
+	return c;
+}
+
+
+
+WCHAR ff_wtoupper (
+	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 {			/* Extended characters */
+		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: UsbWattMeter/trunk/fatfs/option/cc949.c
===================================================================
--- UsbWattMeter/trunk/fatfs/option/cc949.c	(revision 164)
+++ UsbWattMeter/trunk/fatfs/option/cc949.c	(revision 164)
@@ -0,0 +1,8634 @@
+/*------------------------------------------------------------------------*/
+/* Unicode - OEM code bidirectional converter  (C)ChaN, 2015              */
+/* CP949 (Korean EUC-KR)                                                  */
+/*------------------------------------------------------------------------*/
+
+#include "../ff.h"
+
+
+#if !_USE_LFN || _CODE_PAGE != 949
+#error This file is not needed in current configuration. Remove from the project.
+#endif
+
+
+static
+const WCHAR uni2oem[] = {
+/*  Unicode - OEM,  Unicode - OEM,  Unicode - OEM,  Unicode - OEM */
+	0x00A1, 0xA2AE, 0x00A4, 0xA2B4, 0x00A7, 0xA1D7, 0x00A8, 0xA1A7,
+	0x00AA, 0xA8A3, 0x00AD, 0xA1A9, 0x00AE, 0xA2E7, 0x00B0, 0xA1C6,
+	0x00B1, 0xA1BE, 0x00B2, 0xA9F7, 0x00B3, 0xA9F8, 0x00B4, 0xA2A5,
+	0x00B6, 0xA2D2, 0x00B7, 0xA1A4, 0x00B8, 0xA2AC, 0x00B9, 0xA9F6,
+	0x00BA, 0xA8AC, 0x00BC, 0xA8F9, 0x00BD, 0xA8F6, 0x00BE, 0xA8FA,
+	0x00BF, 0xA2AF, 0x00C6, 0xA8A1, 0x00D0, 0xA8A2, 0x00D7, 0xA1BF,
+	0x00D8, 0xA8AA, 0x00DE, 0xA8AD, 0x00DF, 0xA9AC, 0x00E6, 0xA9A1,
+	0x00F0, 0xA9A3, 0x00F7, 0xA1C0, 0x00F8, 0xA9AA, 0x00FE, 0xA9AD,
+	0x0111, 0xA9A2, 0x0126, 0xA8A4, 0x0127, 0xA9A4, 0x0131, 0xA9A5,
+	0x0132, 0xA8A6, 0x0133, 0xA9A6, 0x0138, 0xA9A7, 0x013F, 0xA8A8,
+	0x0140, 0xA9A8, 0x0141, 0xA8A9, 0x0142, 0xA9A9, 0x0149, 0xA9B0,
+	0x014A, 0xA8AF, 0x014B, 0xA9AF, 0x0152, 0xA8AB, 0x0153, 0xA9AB,
+	0x0166, 0xA8AE, 0x0167, 0xA9AE, 0x02C7, 0xA2A7, 0x02D0, 0xA2B0,
+	0x02D8, 0xA2A8, 0x02D9, 0xA2AB, 0x02DA, 0xA2AA, 0x02DB, 0xA2AD,
+	0x02DD, 0xA2A9, 0x0391, 0xA5C1, 0x0392, 0xA5C2, 0x0393, 0xA5C3,
+	0x0394, 0xA5C4, 0x0395, 0xA5C5, 0x0396, 0xA5C6, 0x0397, 0xA5C7,
+	0x0398, 0xA5C8, 0x0399, 0xA5C9, 0x039A, 0xA5CA, 0x039B, 0xA5CB,
+	0x039C, 0xA5CC, 0x039D, 0xA5CD, 0x039E, 0xA5CE, 0x039F, 0xA5CF,
+	0x03A0, 0xA5D0, 0x03A1, 0xA5D1, 0x03A3, 0xA5D2, 0x03A4, 0xA5D3,
+	0x03A5, 0xA5D4, 0x03A6, 0xA5D5, 0x03A7, 0xA5D6, 0x03A8, 0xA5D7,
+	0x03A9, 0xA5D8, 0x03B1, 0xA5E1, 0x03B2, 0xA5E2, 0x03B3, 0xA5E3,
+	0x03B4, 0xA5E4, 0x03B5, 0xA5E5, 0x03B6, 0xA5E6, 0x03B7, 0xA5E7,
+	0x03B8, 0xA5E8, 0x03B9, 0xA5E9, 0x03BA, 0xA5EA, 0x03BB, 0xA5EB,
+	0x03BC, 0xA5EC, 0x03BD, 0xA5ED, 0x03BE, 0xA5EE, 0x03BF, 0xA5EF,
+	0x03C0, 0xA5F0, 0x03C1, 0xA5F1, 0x03C3, 0xA5F2, 0x03C4, 0xA5F3,
+	0x03C5, 0xA5F4, 0x03C6, 0xA5F5, 0x03C7, 0xA5F6, 0x03C8, 0xA5F7,
+	0x03C9, 0xA5F8, 0x0401, 0xACA7, 0x0410, 0xACA1, 0x0411, 0xACA2,
+	0x0412, 0xACA3, 0x0413, 0xACA4, 0x0414, 0xACA5, 0x0415, 0xACA6,
+	0x0416, 0xACA8, 0x0417, 0xACA9, 0x0418, 0xACAA, 0x0419, 0xACAB,
+	0x041A, 0xACAC, 0x041B, 0xACAD, 0x041C, 0xACAE, 0x041D, 0xACAF,
+	0x041E, 0xACB0, 0x041F, 0xACB1, 0x0420, 0xACB2, 0x0421, 0xACB3,
+	0x0422, 0xACB4, 0x0423, 0xACB5, 0x0424, 0xACB6, 0x0425, 0xACB7,
+	0x0426, 0xACB8, 0x0427, 0xACB9, 0x0428, 0xACBA, 0x0429, 0xACBB,
+	0x042A, 0xACBC, 0x042B, 0xACBD, 0x042C, 0xACBE, 0x042D, 0xACBF,
+	0x042E, 0xACC0, 0x042F, 0xACC1, 0x0430, 0xACD1, 0x0431, 0xACD2,
+	0x0432, 0xACD3, 0x0433, 0xACD4, 0x0434, 0xACD5, 0x0435, 0xACD6,
+	0x0436, 0xACD8, 0x0437, 0xACD9, 0x0438, 0xACDA, 0x0439, 0xACDB,
+	0x043A, 0xACDC, 0x043B, 0xACDD, 0x043C, 0xACDE, 0x043D, 0xACDF,
+	0x043E, 0xACE0, 0x043F, 0xACE1, 0x0440, 0xACE2, 0x0441, 0xACE3,
+	0x0442, 0xACE4, 0x0443, 0xACE5, 0x0444, 0xACE6, 0x0445, 0xACE7,
+	0x0446, 0xACE8, 0x0447, 0xACE9, 0x0448, 0xACEA, 0x0449, 0xACEB,
+	0x044A, 0xACEC, 0x044B, 0xACED, 0x044C, 0xACEE, 0x044D, 0xACEF,
+	0x044E, 0xACF0, 0x044F, 0xACF1, 0x0451, 0xACD7, 0x2015, 0xA1AA,
+	0x2018, 0xA1AE, 0x2019, 0xA1AF, 0x201C, 0xA1B0, 0x201D, 0xA1B1,
+	0x2020, 0xA2D3, 0x2021, 0xA2D4, 0x2025, 0xA1A5, 0x2026, 0xA1A6,
+	0x2030, 0xA2B6, 0x2032, 0xA1C7, 0x2033, 0xA1C8, 0x203B, 0xA1D8,
+	0x2074, 0xA9F9, 0x207F, 0xA9FA, 0x2081, 0xA9FB, 0x2082, 0xA9FC,
+	0x2083, 0xA9FD, 0x2084, 0xA9FE, 0x20AC, 0xA2E6, 0x2103, 0xA1C9,
+	0x2109, 0xA2B5, 0x2113, 0xA7A4, 0x2116, 0xA2E0, 0x2121, 0xA2E5,
+	0x2122, 0xA2E2, 0x2126, 0xA7D9, 0x212B, 0xA1CA, 0x2153, 0xA8F7,
+	0x2154, 0xA8F8, 0x215B, 0xA8FB, 0x215C, 0xA8FC, 0x215D, 0xA8FD,
+	0x215E, 0xA8FE, 0x2160, 0xA5B0, 0x2161, 0xA5B1, 0x2162, 0xA5B2,
+	0x2163, 0xA5B3, 0x2164, 0xA5B4, 0x2165, 0xA5B5, 0x2166, 0xA5B6,
+	0x2167, 0xA5B7, 0x2168, 0xA5B8, 0x2169, 0xA5B9, 0x2170, 0xA5A1,
+	0x2171, 0xA5A2, 0x2172, 0xA5A3, 0x2173, 0xA5A4, 0x2174, 0xA5A5,
+	0x2175, 0xA5A6, 0x2176, 0xA5A7, 0x2177, 0xA5A8, 0x2178, 0xA5A9,
+	0x2179, 0xA5AA, 0x2190, 0xA1E7, 0x2191, 0xA1E8, 0x2192, 0xA1E6,
+	0x2193, 0xA1E9, 0x2194, 0xA1EA, 0x2195, 0xA2D5, 0x2196, 0xA2D8,
+	0x2197, 0xA2D6, 0x2198, 0xA2D9, 0x2199, 0xA2D7, 0x21D2, 0xA2A1,
+	0x21D4, 0xA2A2, 0x2200, 0xA2A3, 0x2202, 0xA1D3, 0x2203, 0xA2A4,
+	0x2207, 0xA1D4, 0x2208, 0xA1F4, 0x220B, 0xA1F5, 0x220F, 0xA2B3,
+	0x2211, 0xA2B2, 0x221A, 0xA1EE, 0x221D, 0xA1F0, 0x221E, 0xA1C4,
+	0x2220, 0xA1D0, 0x2225, 0xA1AB, 0x2227, 0xA1FC, 0x2228, 0xA1FD,
+	0x2229, 0xA1FB, 0x222A, 0xA1FA, 0x222B, 0xA1F2, 0x222C, 0xA1F3,
+	0x222E, 0xA2B1, 0x2234, 0xA1C5, 0x2235, 0xA1F1, 0x223C, 0xA1AD,
+	0x223D, 0xA1EF, 0x2252, 0xA1D6, 0x2260, 0xA1C1, 0x2261, 0xA1D5,
+	0x2264, 0xA1C2, 0x2265, 0xA1C3, 0x226A, 0xA1EC, 0x226B, 0xA1ED,
+	0x2282, 0xA1F8, 0x2283, 0xA1F9, 0x2286, 0xA1F6, 0x2287, 0xA1F7,
+	0x2299, 0xA2C1, 0x22A5, 0xA1D1, 0x2312, 0xA1D2, 0x2460, 0xA8E7,
+	0x2461, 0xA8E8, 0x2462, 0xA8E9, 0x2463, 0xA8EA, 0x2464, 0xA8EB,
+	0x2465, 0xA8EC, 0x2466, 0xA8ED, 0x2467, 0xA8EE, 0x2468, 0xA8EF,
+	0x2469, 0xA8F0, 0x246A, 0xA8F1, 0x246B, 0xA8F2, 0x246C, 0xA8F3,
+	0x246D, 0xA8F4, 0x246E, 0xA8F5, 0x2474, 0xA9E7, 0x2475, 0xA9E8,
+	0x2476, 0xA9E9, 0x2477, 0xA9EA, 0x2478, 0xA9EB, 0x2479, 0xA9EC,
+	0x247A, 0xA9ED, 0x247B, 0xA9EE, 0x247C, 0xA9EF, 0x247D, 0xA9F0,
+	0x247E, 0xA9F1, 0x247F, 0xA9F2, 0x2480, 0xA9F3, 0x2481, 0xA9F4,
+	0x2482, 0xA9F5, 0x249C, 0xA9CD, 0x249D, 0xA9CE, 0x249E, 0xA9CF,
+	0x249F, 0xA9D0, 0x24A0, 0xA9D1, 0x24A1, 0xA9D2, 0x24A2, 0xA9D3,
+	0x24A3, 0xA9D4, 0x24A4, 0xA9D5, 0x24A5, 0xA9D6, 0x24A6, 0xA9D7,
+	0x24A7, 0xA9D8, 0x24A8, 0xA9D9, 0x24A9, 0xA9DA, 0x24AA, 0xA9DB,
+	0x24AB, 0xA9DC, 0x24AC, 0xA9DD, 0x24AD, 0xA9DE, 0x24AE, 0xA9DF,
+	0x24AF, 0xA9E0, 0x24B0, 0xA9E1, 0x24B1, 0xA9E2, 0x24B2, 0xA9E3,
+	0x24B3, 0xA9E4, 0x24B4, 0xA9E5, 0x24B5, 0xA9E6, 0x24D0, 0xA8CD,
+	0x24D1, 0xA8CE, 0x24D2, 0xA8CF, 0x24D3, 0xA8D0, 0x24D4, 0xA8D1,
+	0x24D5, 0xA8D2, 0x24D6, 0xA8D3, 0x24D7, 0xA8D4, 0x24D8, 0xA8D5,
+	0x24D9, 0xA8D6, 0x24DA, 0xA8D7, 0x24DB, 0xA8D8, 0x24DC, 0xA8D9,
+	0x24DD, 0xA8DA, 0x24DE, 0xA8DB, 0x24DF, 0xA8DC, 0x24E0, 0xA8DD,
+	0x24E1, 0xA8DE, 0x24E2, 0xA8DF, 0x24E3, 0xA8E0, 0x24E4, 0xA8E1,
+	0x24E5, 0xA8E2, 0x24E6, 0xA8E3, 0x24E7, 0xA8E4, 0x24E8, 0xA8E5,
+	0x24E9, 0xA8E6, 0x2500, 0xA6A1, 0x2501, 0xA6AC, 0x2502, 0xA6A2,
+	0x2503, 0xA6AD, 0x250C, 0xA6A3, 0x250D, 0xA6C8, 0x250E, 0xA6C7,
+	0x250F, 0xA6AE, 0x2510, 0xA6A4, 0x2511, 0xA6C2, 0x2512, 0xA6C1,
+	0x2513, 0xA6AF, 0x2514, 0xA6A6, 0x2515, 0xA6C6, 0x2516, 0xA6C5,
+	0x2517, 0xA6B1, 0x2518, 0xA6A5, 0x2519, 0xA6C4, 0x251A, 0xA6C3,
+	0x251B, 0xA6B0, 0x251C, 0xA6A7, 0x251D, 0xA6BC, 0x251E, 0xA6C9,
+	0x251F, 0xA6CA, 0x2520, 0xA6B7, 0x2521, 0xA6CB, 0x2522, 0xA6CC,
+	0x2523, 0xA6B2, 0x2524, 0xA6A9, 0x2525, 0xA6BE, 0x2526, 0xA6CD,
+	0x2527, 0xA6CE, 0x2528, 0xA6B9, 0x2529, 0xA6CF, 0x252A, 0xA6D0,
+	0x252B, 0xA6B4, 0x252C, 0xA6A8, 0x252D, 0xA6D1, 0x252E, 0xA6D2,
+	0x252F, 0xA6B8, 0x2530, 0xA6BD, 0x2531, 0xA6D3, 0x2532, 0xA6D4,
+	0x2533, 0xA6B3, 0x2534, 0xA6AA, 0x2535, 0xA6D5, 0x2536, 0xA6D6,
+	0x2537, 0xA6BA, 0x2538, 0xA6BF, 0x2539, 0xA6D7, 0x253A, 0xA6D8,
+	0x253B, 0xA6B5, 0x253C, 0xA6AB, 0x253D, 0xA6D9, 0x253E, 0xA6DA,
+	0x253F, 0xA6BB, 0x2540, 0xA6DB, 0x2541, 0xA6DC, 0x2542, 0xA6C0,
+	0x2543, 0xA6DD, 0x2544, 0xA6DE, 0x2545, 0xA6DF, 0x2546, 0xA6E0,
+	0x2547, 0xA6E1, 0x2548, 0xA6E2, 0x2549, 0xA6E3, 0x254A, 0xA6E4,
+	0x254B, 0xA6B6, 0x2592, 0xA2C6, 0x25A0, 0xA1E1, 0x25A1, 0xA1E0,
+	0x25A3, 0xA2C3, 0x25A4, 0xA2C7, 0x25A5, 0xA2C8, 0x25A6, 0xA2CB,
+	0x25A7, 0xA2CA, 0x25A8, 0xA2C9, 0x25A9, 0xA2CC, 0x25B2, 0xA1E3,
+	0x25B3, 0xA1E2, 0x25B6, 0xA2BA, 0x25B7, 0xA2B9, 0x25BC, 0xA1E5,
+	0x25BD, 0xA1E4, 0x25C0, 0xA2B8, 0x25C1, 0xA2B7, 0x25C6, 0xA1DF,
+	0x25C7, 0xA1DE, 0x25C8, 0xA2C2, 0x25CB, 0xA1DB, 0x25CE, 0xA1DD,
+	0x25CF, 0xA1DC, 0x25D0, 0xA2C4, 0x25D1, 0xA2C5, 0x2605, 0xA1DA,
+	0x2606, 0xA1D9, 0x260E, 0xA2CF, 0x260F, 0xA2CE, 0x261C, 0xA2D0,
+	0x261E, 0xA2D1, 0x2640, 0xA1CF, 0x2642, 0xA1CE, 0x2660, 0xA2BC,
+	0x2661, 0xA2BD, 0x2663, 0xA2C0, 0x2664, 0xA2BB, 0x2665, 0xA2BE,
+	0x2667, 0xA2BF, 0x2668, 0xA2CD, 0x2669, 0xA2DB, 0x266A, 0xA2DC,
+	0x266C, 0xA2DD, 0x266D, 0xA2DA, 0x3000, 0xA1A1, 0x3001, 0xA1A2,
+	0x3002, 0xA1A3, 0x3003, 0xA1A8, 0x3008, 0xA1B4, 0x3009, 0xA1B5,
+	0x300A, 0xA1B6, 0x300B, 0xA1B7, 0x300C, 0xA1B8, 0x300D, 0xA1B9,
+	0x300E, 0xA1BA, 0x300F, 0xA1BB, 0x3010, 0xA1BC, 0x3011, 0xA1BD,
+	0x3013, 0xA1EB, 0x3014, 0xA1B2, 0x3015, 0xA1B3, 0x3041, 0xAAA1,
+	0x3042, 0xAAA2, 0x3043, 0xAAA3, 0x3044, 0xAAA4, 0x3045, 0xAAA5,
+	0x3046, 0xAAA6, 0x3047, 0xAAA7, 0x3048, 0xAAA8, 0x3049, 0xAAA9,
+	0x304A, 0xAAAA, 0x304B, 0xAAAB, 0x304C, 0xAAAC, 0x304D, 0xAAAD,
+	0x304E, 0xAAAE, 0x304F, 0xAAAF, 0x3050, 0xAAB0, 0x3051, 0xAAB1,
+	0x3052, 0xAAB2, 0x3053, 0xAAB3, 0x3054, 0xAAB4, 0x3055, 0xAAB5,
+	0x3056, 0xAAB6, 0x3057, 0xAAB7, 0x3058, 0xAAB8, 0x3059, 0xAAB9,
+	0x305A, 0xAABA, 0x305B, 0xAABB, 0x305C, 0xAABC, 0x305D, 0xAABD,
+	0x305E, 0xAABE, 0x305F, 0xAABF, 0x3060, 0xAAC0, 0x3061, 0xAAC1,
+	0x3062, 0xAAC2, 0x3063, 0xAAC3, 0x3064, 0xAAC4, 0x3065, 0xAAC5,
+	0x3066, 0xAAC6, 0x3067, 0xAAC7, 0x3068, 0xAAC8, 0x3069, 0xAAC9,
+	0x306A, 0xAACA, 0x306B, 0xAACB, 0x306C, 0xAACC, 0x306D, 0xAACD,
+	0x306E, 0xAACE, 0x306F, 0xAACF, 0x3070, 0xAAD0, 0x3071, 0xAAD1,
+	0x3072, 0xAAD2, 0x3073, 0xAAD3, 0x3074, 0xAAD4, 0x3075, 0xAAD5,
+	0x3076, 0xAAD6, 0x3077, 0xAAD7, 0x3078, 0xAAD8, 0x3079, 0xAAD9,
+	0x307A, 0xAADA, 0x307B, 0xAADB, 0x307C, 0xAADC, 0x307D, 0xAADD,
+	0x307E, 0xAADE, 0x307F, 0xAADF, 0x3080, 0xAAE0, 0x3081, 0xAAE1,
+	0x3082, 0xAAE2, 0x3083, 0xAAE3, 0x3084, 0xAAE4, 0x3085, 0xAAE5,
+	0x3086, 0xAAE6, 0x3087, 0xAAE7, 0x3088, 0xAAE8, 0x3089, 0xAAE9,
+	0x308A, 0xAAEA, 0x308B, 0xAAEB, 0x308C, 0xAAEC, 0x308D, 0xAAED,
+	0x308E, 0xAAEE, 0x308F, 0xAAEF, 0x3090, 0xAAF0, 0x3091, 0xAAF1,
+	0x3092, 0xAAF2, 0x3093, 0xAAF3, 0x30A1, 0xABA1, 0x30A2, 0xABA2,
+	0x30A3, 0xABA3, 0x30A4, 0xABA4, 0x30A5, 0xABA5, 0x30A6, 0xABA6,
+	0x30A7, 0xABA7, 0x30A8, 0xABA8, 0x30A9, 0xABA9, 0x30AA, 0xABAA,
+	0x30AB, 0xABAB, 0x30AC, 0xABAC, 0x30AD, 0xABAD, 0x30AE, 0xABAE,
+	0x30AF, 0xABAF, 0x30B0, 0xABB0, 0x30B1, 0xABB1, 0x30B2, 0xABB2,
+	0x30B3, 0xABB3, 0x30B4, 0xABB4, 0x30B5, 0xABB5, 0x30B6, 0xABB6,
+	0x30B7, 0xABB7, 0x30B8, 0xABB8, 0x30B9, 0xABB9, 0x30BA, 0xABBA,
+	0x30BB, 0xABBB, 0x30BC, 0xABBC, 0x30BD, 0xABBD, 0x30BE, 0xABBE,
+	0x30BF, 0xABBF, 0x30C0, 0xABC0, 0x30C1, 0xABC1, 0x30C2, 0xABC2,
+	0x30C3, 0xABC3, 0x30C4, 0xABC4, 0x30C5, 0xABC5, 0x30C6, 0xABC6,
+	0x30C7, 0xABC7, 0x30C8, 0xABC8, 0x30C9, 0xABC9, 0x30CA, 0xABCA,
+	0x30CB, 0xABCB, 0x30CC, 0xABCC, 0x30CD, 0xABCD, 0x30CE, 0xABCE,
+	0x30CF, 0xABCF, 0x30D0, 0xABD0, 0x30D1, 0xABD1, 0x30D2, 0xABD2,
+	0x30D3, 0xABD3, 0x30D4, 0xABD4, 0x30D5, 0xABD5, 0x30D6, 0xABD6,
+	0x30D7, 0xABD7, 0x30D8, 0xABD8, 0x30D9, 0xABD9, 0x30DA, 0xABDA,
+	0x30DB, 0xABDB, 0x30DC, 0xABDC, 0x30DD, 0xABDD, 0x30DE, 0xABDE,
+	0x30DF, 0xABDF, 0x30E0, 0xABE0, 0x30E1, 0xABE1, 0x30E2, 0xABE2,
+	0x30E3, 0xABE3, 0x30E4, 0xABE4, 0x30E5, 0xABE5, 0x30E6, 0xABE6,
+	0x30E7, 0xABE7, 0x30E8, 0xABE8, 0x30E9, 0xABE9, 0x30EA, 0xABEA,
+	0x30EB, 0xABEB, 0x30EC, 0xABEC, 0x30ED, 0xABED, 0x30EE, 0xABEE,
+	0x30EF, 0xABEF, 0x30F0, 0xABF0, 0x30F1, 0xABF1, 0x30F2, 0xABF2,
+	0x30F3, 0xABF3, 0x30F4, 0xABF4, 0x30F5, 0xABF5, 0x30F6, 0xABF6,
+	0x3131, 0xA4A1, 0x3132, 0xA4A2, 0x3133, 0xA4A3, 0x3134, 0xA4A4,
+	0x3135, 0xA4A5, 0x3136, 0xA4A6, 0x3137, 0xA4A7, 0x3138, 0xA4A8,
+	0x3139, 0xA4A9, 0x313A, 0xA4AA, 0x313B, 0xA4AB, 0x313C, 0xA4AC,
+	0x313D, 0xA4AD, 0x313E, 0xA4AE, 0x313F, 0xA4AF, 0x3140, 0xA4B0,
+	0x3141, 0xA4B1, 0x3142, 0xA4B2, 0x3143, 0xA4B3, 0x3144, 0xA4B4,
+	0x3145, 0xA4B5, 0x3146, 0xA4B6, 0x3147, 0xA4B7, 0x3148, 0xA4B8,
+	0x3149, 0xA4B9, 0x314A, 0xA4BA, 0x314B, 0xA4BB, 0x314C, 0xA4BC,
+	0x314D, 0xA4BD, 0x314E, 0xA4BE, 0x314F, 0xA4BF, 0x3150, 0xA4C0,
+	0x3151, 0xA4C1, 0x3152, 0xA4C2, 0x3153, 0xA4C3, 0x3154, 0xA4C4,
+	0x3155, 0xA4C5, 0x3156, 0xA4C6, 0x3157, 0xA4C7, 0x3158, 0xA4C8,
+	0x3159, 0xA4C9, 0x315A, 0xA4CA, 0x315B, 0xA4CB, 0x315C, 0xA4CC,
+	0x315D, 0xA4CD, 0x315E, 0xA4CE, 0x315F, 0xA4CF, 0x3160, 0xA4D0,
+	0x3161, 0xA4D1, 0x3162, 0xA4D2, 0x3163, 0xA4D3, 0x3164, 0xA4D4,
+	0x3165, 0xA4D5, 0x3166, 0xA4D6, 0x3167, 0xA4D7, 0x3168, 0xA4D8,
+	0x3169, 0xA4D9, 0x316A, 0xA4DA, 0x316B, 0xA4DB, 0x316C, 0xA4DC,
+	0x316D, 0xA4DD, 0x316E, 0xA4DE, 0x316F, 0xA4DF, 0x3170, 0xA4E0,
+	0x3171, 0xA4E1, 0x3172, 0xA4E2, 0x3173, 0xA4E3, 0x3174, 0xA4E4,
+	0x3175, 0xA4E5, 0x3176, 0xA4E6, 0x3177, 0xA4E7, 0x3178, 0xA4E8,
+	0x3179, 0xA4E9, 0x317A, 0xA4EA, 0x317B, 0xA4EB, 0x317C, 0xA4EC,
+	0x317D, 0xA4ED, 0x317E, 0xA4EE, 0x317F, 0xA4EF, 0x3180, 0xA4F0,
+	0x3181, 0xA4F1, 0x3182, 0xA4F2, 0x3183, 0xA4F3, 0x3184, 0xA4F4,
+	0x3185, 0xA4F5, 0x3186, 0xA4F6, 0x3187, 0xA4F7, 0x3188, 0xA4F8,
+	0x3189, 0xA4F9, 0x318A, 0xA4FA, 0x318B, 0xA4FB, 0x318C, 0xA4FC,
+	0x318D, 0xA4FD, 0x318E, 0xA4FE, 0x3200, 0xA9B1, 0x3201, 0xA9B2,
+	0x3202, 0xA9B3, 0x3203, 0xA9B4, 0x3204, 0xA9B5, 0x3205, 0xA9B6,
+	0x3206, 0xA9B7, 0x3207, 0xA9B8, 0x3208, 0xA9B9, 0x3209, 0xA9BA,
+	0x320A, 0xA9BB, 0x320B, 0xA9BC, 0x320C, 0xA9BD, 0x320D, 0xA9BE,
+	0x320E, 0xA9BF, 0x320F, 0xA9C0, 0x3210, 0xA9C1, 0x3211, 0xA9C2,
+	0x3212, 0xA9C3, 0x3213, 0xA9C4, 0x3214, 0xA9C5, 0x3215, 0xA9C6,
+	0x3216, 0xA9C7, 0x3217, 0xA9C8, 0x3218, 0xA9C9, 0x3219, 0xA9CA,
+	0x321A, 0xA9CB, 0x321B, 0xA9CC, 0x321C, 0xA2DF, 0x3260, 0xA8B1,
+	0x3261, 0xA8B2, 0x3262, 0xA8B3, 0x3263, 0xA8B4, 0x3264, 0xA8B5,
+	0x3265, 0xA8B6, 0x3266, 0xA8B7, 0x3267, 0xA8B8, 0x3268, 0xA8B9,
+	0x3269, 0xA8BA, 0x326A, 0xA8BB, 0x326B, 0xA8BC, 0x326C, 0xA8BD,
+	0x326D, 0xA8BE, 0x326E, 0xA8BF, 0x326F, 0xA8C0, 0x3270, 0xA8C1,
+	0x3271, 0xA8C2, 0x3272, 0xA8C3, 0x3273, 0xA8C4, 0x3274, 0xA8C5,
+	0x3275, 0xA8C6, 0x3276, 0xA8C7, 0x3277, 0xA8C8, 0x3278, 0xA8C9,
+	0x3279, 0xA8CA, 0x327A, 0xA8CB, 0x327B, 0xA8CC, 0x327F, 0xA2DE,
+	0x3380, 0xA7C9, 0x3381, 0xA7CA, 0x3382, 0xA7CB, 0x3383, 0xA7CC,
+	0x3384, 0xA7CD, 0x3388, 0xA7BA, 0x3389, 0xA7BB, 0x338A, 0xA7DC,
+	0x338B, 0xA7DD, 0x338C, 0xA7DE, 0x338D, 0xA7B6, 0x338E, 0xA7B7,
+	0x338F, 0xA7B8, 0x3390, 0xA7D4, 0x3391, 0xA7D5, 0x3392, 0xA7D6,
+	0x3393, 0xA7D7, 0x3394, 0xA7D8, 0x3395, 0xA7A1, 0x3396, 0xA7A2,
+	0x3397, 0xA7A3, 0x3398, 0xA7A5, 0x3399, 0xA7AB, 0x339A, 0xA7AC,
+	0x339B, 0xA7AD, 0x339C, 0xA7AE, 0x339D, 0xA7AF, 0x339E, 0xA7B0,
+	0x339F, 0xA7B1, 0x33A0, 0xA7B2, 0x33A1, 0xA7B3, 0x33A2, 0xA7B4,
+	0x33A3, 0xA7A7, 0x33A4, 0xA7A8, 0x33A5, 0xA7A9, 0x33A6, 0xA7AA,
+	0x33A7, 0xA7BD, 0x33A8, 0xA7BE, 0x33A9, 0xA7E5, 0x33AA, 0xA7E6,
+	0x33AB, 0xA7E7, 0x33AC, 0xA7E8, 0x33AD, 0xA7E1, 0x33AE, 0xA7E2,
+	0x33AF, 0xA7E3, 0x33B0, 0xA7BF, 0x33B1, 0xA7C0, 0x33B2, 0xA7C1,
+	0x33B3, 0xA7C2, 0x33B4, 0xA7C3, 0x33B5, 0xA7C4, 0x33B6, 0xA7C5,
+	0x33B7, 0xA7C6, 0x33B8, 0xA7C7, 0x33B9, 0xA7C8, 0x33BA, 0xA7CE,
+	0x33BB, 0xA7CF, 0x33BC, 0xA7D0, 0x33BD, 0xA7D1, 0x33BE, 0xA7D2,
+	0x33BF, 0xA7D3, 0x33C0, 0xA7DA, 0x33C1, 0xA7DB, 0x33C2, 0xA2E3,
+	0x33C3, 0xA7EC, 0x33C4, 0xA7A6, 0x33C5, 0xA7E0, 0x33C6, 0xA7EF,
+	0x33C7, 0xA2E1, 0x33C8, 0xA7BC, 0x33C9, 0xA7ED, 0x33CA, 0xA7B5,
+	0x33CF, 0xA7B9, 0x33D0, 0xA7EA, 0x33D3, 0xA7EB, 0x33D6, 0xA7DF,
+	0x33D8, 0xA2E4, 0x33DB, 0xA7E4, 0x33DC, 0xA7EE, 0x33DD, 0xA7E9,
+	0x4E00, 0xECE9, 0x4E01, 0xEFCB, 0x4E03, 0xF6D2, 0x4E07, 0xD8B2,
+	0x4E08, 0xEDDB, 0x4E09, 0xDFB2, 0x4E0A, 0xDFBE, 0x4E0B, 0xF9BB,
+	0x4E0D, 0xDCF4, 0x4E11, 0xF5E4, 0x4E14, 0xF3A6, 0x4E15, 0xDDE0,
+	0x4E16, 0xE1A6, 0x4E18, 0xCEF8, 0x4E19, 0xDCB0, 0x4E1E, 0xE3AA,
+	0x4E2D, 0xF1E9, 0x4E32, 0xCDFA, 0x4E38, 0xFCAF, 0x4E39, 0xD3A1,
+	0x4E3B, 0xF1AB, 0x4E42, 0xE7D1, 0x4E43, 0xD2AC, 0x4E45, 0xCEF9,
+	0x4E4B, 0xF1FD, 0x4E4D, 0xDEBF, 0x4E4E, 0xFBBA, 0x4E4F, 0xF9B9,
+	0x4E56, 0xCED2, 0x4E58, 0xE3AB, 0x4E59, 0xEBE0, 0x4E5D, 0xCEFA,
+	0x4E5E, 0xCBF7, 0x4E5F, 0xE5A5, 0x4E6B, 0xCAE1, 0x4E6D, 0xD4CC,
+	0x4E73, 0xEAE1, 0x4E76, 0xDCE3, 0x4E77, 0xDFAD, 0x4E7E, 0xCBEB,
+	0x4E82, 0xD5AF, 0x4E86, 0xD6F5, 0x4E88, 0xE5F8, 0x4E8B, 0xDEC0,
+	0x4E8C, 0xECA3, 0x4E8E, 0xE9CD, 0x4E90, 0xEAA7, 0x4E91, 0xE9F6,
+	0x4E92, 0xFBBB, 0x4E94, 0xE7E9, 0x4E95, 0xEFCC, 0x4E98, 0xD0E6,
+	0x4E9B, 0xDEC1, 0x4E9E, 0xE4AC, 0x4EA1, 0xD8CC, 0x4EA2, 0xF9F1,
+	0x4EA4, 0xCEDF, 0x4EA5, 0xFAA4, 0x4EA6, 0xE6B2, 0x4EA8, 0xFAFB,
+	0x4EAB, 0xFABD, 0x4EAC, 0xCCC8, 0x4EAD, 0xEFCD, 0x4EAE, 0xD5D5,
+	0x4EB6, 0xD3A2, 0x4EBA, 0xECD1, 0x4EC0, 0xE4A7, 0x4EC1, 0xECD2,
+	0x4EC4, 0xF6B1, 0x4EC7, 0xCEFB, 0x4ECA, 0xD0D1, 0x4ECB, 0xCBBF,
+	0x4ECD, 0xEDA4, 0x4ED4, 0xEDA8, 0x4ED5, 0xDEC2, 0x4ED6, 0xF6E2,
+	0x4ED7, 0xEDDC, 0x4ED8, 0xDCF5, 0x4ED9, 0xE0B9, 0x4EDD, 0xD4CE,
+	0x4EDF, 0xF4B5, 0x4EE3, 0xD3DB, 0x4EE4, 0xD6B5, 0x4EE5, 0xECA4,
+	0x4EF0, 0xE4E6, 0x4EF2, 0xF1EA, 0x4EF6, 0xCBEC, 0x4EF7, 0xCBC0,
+	0x4EFB, 0xECF2, 0x4F01, 0xD0EA, 0x4F09, 0xF9F2, 0x4F0A, 0xECA5,
+	0x4F0B, 0xD0DF, 0x4F0D, 0xE7EA, 0x4F0E, 0xD0EB, 0x4F0F, 0xDCD1,
+	0x4F10, 0xDBE9, 0x4F11, 0xFDCC, 0x4F2F, 0xDBD7, 0x4F34, 0xDAE1,
+	0x4F36, 0xD6B6, 0x4F38, 0xE3DF, 0x4F3A, 0xDEC3, 0x4F3C, 0xDEC4,
+	0x4F3D, 0xCAA1, 0x4F43, 0xEEEC, 0x4F46, 0xD3A3, 0x4F47, 0xEEB7,
+	0x4F48, 0xF8CF, 0x4F4D, 0xEAC8, 0x4F4E, 0xEEB8, 0x4F4F, 0xF1AC,
+	0x4F50, 0xF1A5, 0x4F51, 0xE9CE, 0x4F55, 0xF9BC, 0x4F59, 0xE5F9,
+	0x4F5A, 0xECEA, 0x4F5B, 0xDDD6, 0x4F5C, 0xEDC2, 0x4F69, 0xF8A5,
+	0x4F6F, 0xE5BA, 0x4F70, 0xDBD8, 0x4F73, 0xCAA2, 0x4F76, 0xD1CD,
+	0x4F7A, 0xEEED, 0x4F7E, 0xECEB, 0x4F7F, 0xDEC5, 0x4F81, 0xE3E0,
+	0x4F83, 0xCAC9, 0x4F84, 0xF2E9, 0x4F86, 0xD5CE, 0x4F88, 0xF6B6,
+	0x4F8A, 0xCEC2, 0x4F8B, 0xD6C7, 0x4F8D, 0xE3B4, 0x4F8F, 0xF1AD,
+	0x4F91, 0xEAE2, 0x4F96, 0xD7C2, 0x4F98, 0xF3A7, 0x4F9B, 0xCDEA,
+	0x4F9D, 0xEBEE, 0x4FAE, 0xD9B2, 0x4FAF, 0xFDA5, 0x4FB5, 0xF6D5,
+	0x4FB6, 0xD5E2, 0x4FBF, 0xF8B5, 0x4FC2, 0xCCF5, 0x4FC3, 0xF5B5,
+	0x4FC4, 0xE4AD, 0x4FC9, 0xE7EB, 0x4FCA, 0xF1D5, 0x4FCE, 0xF0BB,
+	0x4FD1, 0xE9B5, 0x4FD3, 0xCCC9, 0x4FD4, 0xFAD5, 0x4FD7, 0xE1D4,
+	0x4FDA, 0xD7D6, 0x4FDD, 0xDCC1, 0x4FDF, 0xDEC6, 0x4FE0, 0xFAEF,
+	0x4FE1, 0xE3E1, 0x4FEE, 0xE1F3, 0x4FEF, 0xDCF6, 0x4FF1, 0xCEFC,
+	0x4FF3, 0xDBC4, 0x4FF5, 0xF8F1, 0x4FF8, 0xDCE4, 0x4FFA, 0xE5EF,
+	0x5002, 0xDCB1, 0x5006, 0xD5D6, 0x5009, 0xF3DA, 0x500B, 0xCBC1,
+	0x500D, 0xDBC3, 0x5011, 0xD9FA, 0x5012, 0xD3EE, 0x5016, 0xFAB8,
+	0x5019, 0xFDA6, 0x501A, 0xEBEF, 0x501C, 0xF4A6, 0x501E, 0xCCCA,
+	0x501F, 0xF3A8, 0x5021, 0xF3DB, 0x5023, 0xDBA7, 0x5024, 0xF6B7,
+	0x5026, 0xCFE6, 0x5027, 0xF0F2, 0x5028, 0xCBDA, 0x502A, 0xE7D2,
+	0x502B, 0xD7C3, 0x502C, 0xF6F0, 0x502D, 0xE8DE, 0x503B, 0xE5A6,
+	0x5043, 0xE5E7, 0x5047, 0xCAA3, 0x5048, 0xCCA7, 0x5049, 0xEAC9,
+	0x504F, 0xF8B6, 0x5055, 0xFAA5, 0x505A, 0xF1AE, 0x505C, 0xEFCE,
+	0x5065, 0xCBED, 0x5074, 0xF6B0, 0x5075, 0xEFCF, 0x5076, 0xE9CF,
+	0x5078, 0xF7DE, 0x5080, 0xCED3, 0x5085, 0xDCF7, 0x508D, 0xDBA8,
+	0x5091, 0xCBF8, 0x5098, 0xDFA1, 0x5099, 0xDDE1, 0x50AC, 0xF5CA,
+	0x50AD, 0xE9B6, 0x50B2, 0xE7EC, 0x50B3, 0xEEEE, 0x50B5, 0xF3F0,
+	0x50B7, 0xDFBF, 0x50BE, 0xCCCB, 0x50C5, 0xD0C1, 0x50C9, 0xF4D2,
+	0x50CA, 0xE0BA, 0x50CF, 0xDFC0, 0x50D1, 0xCEE0, 0x50D5, 0xDCD2,
+	0x50D6, 0xFDEA, 0x50DA, 0xD6F6, 0x50DE, 0xEACA, 0x50E5, 0xE8E9,
+	0x50E7, 0xE3AC, 0x50ED, 0xF3D0, 0x50F9, 0xCAA4, 0x50FB, 0xDBF8,
+	0x50FF, 0xDEC7, 0x5100, 0xEBF0, 0x5101, 0xF1D6, 0x5104, 0xE5E2,
+	0x5106, 0xCCCC, 0x5109, 0xCBFB, 0x5112, 0xEAE3, 0x511F, 0xDFC1,
+	0x5121, 0xD6ED, 0x512A, 0xE9D0, 0x5132, 0xEEB9, 0x5137, 0xD5E3,
+	0x513A, 0xD1D3, 0x513C, 0xE5F0, 0x5140, 0xE8B4, 0x5141, 0xEBC3,
+	0x5143, 0xEAAA, 0x5144, 0xFAFC, 0x5145, 0xF5F6, 0x5146, 0xF0BC,
+	0x5147, 0xFDD4, 0x5148, 0xE0BB, 0x5149, 0xCEC3, 0x514B, 0xD0BA,
+	0x514C, 0xF7BA, 0x514D, 0xD8F3, 0x514E, 0xF7CD, 0x5152, 0xE4AE,
+	0x515C, 0xD4DF, 0x5162, 0xD0E7, 0x5165, 0xECFD, 0x5167, 0xD2AE,
+	0x5168, 0xEEEF, 0x5169, 0xD5D7, 0x516A, 0xEAE4, 0x516B, 0xF8A2,
+	0x516C, 0xCDEB, 0x516D, 0xD7BF, 0x516E, 0xFBB1, 0x5171, 0xCDEC,
+	0x5175, 0xDCB2, 0x5176, 0xD0EC, 0x5177, 0xCEFD, 0x5178, 0xEEF0,
+	0x517C, 0xCCC2, 0x5180, 0xD0ED, 0x5186, 0xE5F7, 0x518A, 0xF3FC,
+	0x518D, 0xEEA2, 0x5192, 0xD9B3, 0x5195, 0xD8F4, 0x5197, 0xE9B7,
+	0x51A0, 0xCEAE, 0x51A5, 0xD9A2, 0x51AA, 0xD8F1, 0x51AC, 0xD4CF,
+	0x51B6, 0xE5A7, 0x51B7, 0xD5D2, 0x51BD, 0xD6A9, 0x51C4, 0xF4A2,
+	0x51C6, 0xF1D7, 0x51C9, 0xD5D8, 0x51CB, 0xF0BD, 0x51CC, 0xD7D0,
+	0x51CD, 0xD4D0, 0x51DC, 0xD7CF, 0x51DD, 0xEBEA, 0x51DE, 0xFDEB,
+	0x51E1, 0xDBED, 0x51F0, 0xFCC5, 0x51F1, 0xCBC2, 0x51F6, 0xFDD5,
+	0x51F8, 0xF4C8, 0x51F9, 0xE8EA, 0x51FA, 0xF5F3, 0x51FD, 0xF9DE,
+	0x5200, 0xD3EF, 0x5203, 0xECD3, 0x5206, 0xDDC2, 0x5207, 0xEFB7,
+	0x5208, 0xE7D4, 0x520A, 0xCACA, 0x520E, 0xD9FB, 0x5211, 0xFAFD,
+	0x5217, 0xD6AA, 0x521D, 0xF4F8, 0x5224, 0xF7F7, 0x5225, 0xDCAC,
+	0x5229, 0xD7D7, 0x522A, 0xDFA2, 0x522E, 0xCEBE, 0x5230, 0xD3F0,
+	0x5236, 0xF0A4, 0x5237, 0xE1EC, 0x5238, 0xCFE7, 0x5239, 0xF3CB,
+	0x523A, 0xEDA9, 0x523B, 0xCABE, 0x5243, 0xF4EF, 0x5247, 0xF6CE,
+	0x524A, 0xDEFB, 0x524B, 0xD0BB, 0x524C, 0xD5B7, 0x524D, 0xEEF1,
+	0x5254, 0xF4A8, 0x5256, 0xDCF8, 0x525B, 0xCBA7, 0x525D, 0xDACE,
+	0x5261, 0xE0E6, 0x5269, 0xEDA5, 0x526A, 0xEEF2, 0x526F, 0xDCF9,
+	0x5272, 0xF9DC, 0x5275, 0xF3DC, 0x527D, 0xF8F2, 0x527F, 0xF4F9,
+	0x5283, 0xFCF1, 0x5287, 0xD0BC, 0x5288, 0xDBF9, 0x5289, 0xD7B1,
+	0x528D, 0xCBFC, 0x5291, 0xF0A5, 0x5292, 0xCBFD, 0x529B, 0xD5F4,
+	0x529F, 0xCDED, 0x52A0, 0xCAA5, 0x52A3, 0xD6AB, 0x52A4, 0xD0C2,
+	0x52A9, 0xF0BE, 0x52AA, 0xD2BD, 0x52AB, 0xCCA4, 0x52BE, 0xFAB6,
+	0x52C1, 0xCCCD, 0x52C3, 0xDAFA, 0x52C5, 0xF6CF, 0x52C7, 0xE9B8,
+	0x52C9, 0xD8F5, 0x52CD, 0xCCCE, 0x52D2, 0xD7CD, 0x52D5, 0xD4D1,
+	0x52D6, 0xE9ED, 0x52D8, 0xCAEB, 0x52D9, 0xD9E2, 0x52DB, 0xFDB2,
+	0x52DD, 0xE3AD, 0x52DE, 0xD6CC, 0x52DF, 0xD9B4, 0x52E2, 0xE1A7,
+	0x52E3, 0xEED3, 0x52E4, 0xD0C3, 0x52F3, 0xFDB3, 0x52F5, 0xD5E4,
+	0x52F8, 0xCFE8, 0x52FA, 0xEDC3, 0x52FB, 0xD0B2, 0x52FE, 0xCEFE,
+	0x52FF, 0xDAA8, 0x5305, 0xF8D0, 0x5308, 0xFDD6, 0x530D, 0xF8D1,
+	0x530F, 0xF8D2, 0x5310, 0xDCD3, 0x5315, 0xDDE2, 0x5316, 0xFBF9,
+	0x5317, 0xDDC1, 0x5319, 0xE3B5, 0x5320, 0xEDDD, 0x5321, 0xCEC4,
+	0x5323, 0xCBA1, 0x532A, 0xDDE3, 0x532F, 0xFCDD, 0x5339, 0xF9AF,
+	0x533F, 0xD2FB, 0x5340, 0xCFA1, 0x5341, 0xE4A8, 0x5343, 0xF4B6,
+	0x5344, 0xECFE, 0x5347, 0xE3AE, 0x5348, 0xE7ED, 0x5349, 0xFDC1,
+	0x534A, 0xDAE2, 0x534D, 0xD8B3, 0x5351, 0xDDE4, 0x5352, 0xF0EF,
+	0x5353, 0xF6F1, 0x5354, 0xFAF0, 0x5357, 0xD1F5, 0x535A, 0xDACF,
+	0x535C, 0xDCD4, 0x535E, 0xDCA6, 0x5360, 0xEFBF, 0x5366, 0xCECF,
+	0x5368, 0xE0D9, 0x536F, 0xD9D6, 0x5370, 0xECD4, 0x5371, 0xEACB,
+	0x5374, 0xCABF, 0x5375, 0xD5B0, 0x5377, 0xCFE9, 0x537D, 0xF1ED,
+	0x537F, 0xCCCF, 0x5384, 0xE4F8, 0x5393, 0xE4ED, 0x5398, 0xD7D8,
+	0x539A, 0xFDA7, 0x539F, 0xEAAB, 0x53A0, 0xF6B2, 0x53A5, 0xCFF0,
+	0x53A6, 0xF9BD, 0x53AD, 0xE6F4, 0x53BB, 0xCBDB, 0x53C3, 0xF3D1,
+	0x53C8, 0xE9D1, 0x53C9, 0xF3A9, 0x53CA, 0xD0E0, 0x53CB, 0xE9D2,
+	0x53CD, 0xDAE3, 0x53D4, 0xE2D2, 0x53D6, 0xF6A2, 0x53D7, 0xE1F4,
+	0x53DB, 0xDAE4, 0x53E1, 0xE7D5, 0x53E2, 0xF5BF, 0x53E3, 0xCFA2,
+	0x53E4, 0xCDAF, 0x53E5, 0xCFA3, 0x53E9, 0xCDB0, 0x53EA, 0xF1FE,
+	0x53EB, 0xD0A3, 0x53EC, 0xE1AF, 0x53ED, 0xF8A3, 0x53EF, 0xCAA6,
+	0x53F0, 0xF7BB, 0x53F1, 0xF2EA, 0x53F2, 0xDEC8, 0x53F3, 0xE9D3,
+	0x53F8, 0xDEC9, 0x5403, 0xFDDE, 0x5404, 0xCAC0, 0x5408, 0xF9EA,
+	0x5409, 0xD1CE, 0x540A, 0xEED4, 0x540C, 0xD4D2, 0x540D, 0xD9A3,
+	0x540E, 0xFDA8, 0x540F, 0xD7D9, 0x5410, 0xF7CE, 0x5411, 0xFABE,
+	0x541B, 0xCFD6, 0x541D, 0xD7F0, 0x541F, 0xEBE1, 0x5420, 0xF8C5,
+	0x5426, 0xDCFA, 0x5429, 0xDDC3, 0x542B, 0xF9DF, 0x5433, 0xE7EF,
+	0x5438, 0xFDE5, 0x5439, 0xF6A3, 0x543B, 0xD9FC, 0x543C, 0xFDA9,
+	0x543E, 0xE7EE, 0x5442, 0xD5E5, 0x5448, 0xEFD0, 0x544A, 0xCDB1,
+	0x5451, 0xF7A2, 0x5468, 0xF1B2, 0x546A, 0xF1B1, 0x5471, 0xCDB2,
+	0x5473, 0xDAAB, 0x5475, 0xCAA7, 0x547B, 0xE3E2, 0x547C, 0xFBBC,
+	0x547D, 0xD9A4, 0x5480, 0xEEBA, 0x5486, 0xF8D3, 0x548C, 0xFBFA,
+	0x548E, 0xCFA4, 0x5490, 0xDCFB, 0x54A4, 0xF6E3, 0x54A8, 0xEDAA,
+	0x54AB, 0xF2A1, 0x54AC, 0xCEE1, 0x54B3, 0xFAA6, 0x54B8, 0xF9E0,
+	0x54BD, 0xECD6, 0x54C0, 0xE4EE, 0x54C1, 0xF9A1, 0x54C4, 0xFBEF,
+	0x54C8, 0xF9EB, 0x54C9, 0xEEA3, 0x54E1, 0xEAAC, 0x54E5, 0xCAA8,
+	0x54E8, 0xF4FA, 0x54ED, 0xCDD6, 0x54EE, 0xFCF6, 0x54F2, 0xF4C9,
+	0x54FA, 0xF8D4, 0x5504, 0xF8A6, 0x5506, 0xDECA, 0x5507, 0xF2C6,
+	0x550E, 0xD7DA, 0x5510, 0xD3D0, 0x551C, 0xD8C5, 0x552F, 0xEAE6,
+	0x5531, 0xF3DD, 0x5535, 0xE4DA, 0x553E, 0xF6E4, 0x5544, 0xF6F2,
+	0x5546, 0xDFC2, 0x554F, 0xD9FD, 0x5553, 0xCCF6, 0x5556, 0xD3BA,
+	0x555E, 0xE4AF, 0x5563, 0xF9E1, 0x557C, 0xF0A6, 0x5580, 0xCBD3,
+	0x5584, 0xE0BC, 0x5586, 0xF4CA, 0x5587, 0xD4FA, 0x5589, 0xFDAA,
+	0x558A, 0xF9E2, 0x5598, 0xF4B7, 0x5599, 0xFDC2, 0x559A, 0xFCB0,
+	0x559C, 0xFDEC, 0x559D, 0xCAE2, 0x55A7, 0xFDBD, 0x55A9, 0xEAE7,
+	0x55AA, 0xDFC3, 0x55AB, 0xD1D2, 0x55AC, 0xCEE2, 0x55AE, 0xD3A4,
+	0x55C5, 0xFDAB, 0x55C7, 0xDFE0, 0x55D4, 0xF2C7, 0x55DA, 0xE7F0,
+	0x55DC, 0xD0EE, 0x55DF, 0xF3AA, 0x55E3, 0xDECB, 0x55E4, 0xF6B8,
+	0x55FD, 0xE1F5, 0x55FE, 0xF1B3, 0x5606, 0xF7A3, 0x5609, 0xCAA9,
+	0x5614, 0xCFA5, 0x5617, 0xDFC4, 0x562F, 0xE1B0, 0x5632, 0xF0BF,
+	0x5634, 0xF6A4, 0x5636, 0xE3B6, 0x5653, 0xFAC6, 0x5668, 0xD0EF,
+	0x566B, 0xFDED, 0x5674, 0xDDC4, 0x5686, 0xFCF7, 0x56A5, 0xE6BF,
+	0x56AC, 0xDEAD, 0x56AE, 0xFABF, 0x56B4, 0xE5F1, 0x56BC, 0xEDC4,
+	0x56CA, 0xD2A5, 0x56CD, 0xFDEE, 0x56D1, 0xF5B6, 0x56DA, 0xE1F6,
+	0x56DB, 0xDECC, 0x56DE, 0xFCDE, 0x56E0, 0xECD7, 0x56F0, 0xCDDD,
+	0x56F9, 0xD6B7, 0x56FA, 0xCDB3, 0x5703, 0xF8D5, 0x5704, 0xE5D8,
+	0x5708, 0xCFEA, 0x570B, 0xCFD0, 0x570D, 0xEACC, 0x5712, 0xEAAE,
+	0x5713, 0xEAAD, 0x5716, 0xD3F1, 0x5718, 0xD3A5, 0x571F, 0xF7CF,
+	0x5728, 0xEEA4, 0x572D, 0xD0A4, 0x5730, 0xF2A2, 0x573B, 0xD0F0,
+	0x5740, 0xF2A3, 0x5742, 0xF7F8, 0x5747, 0xD0B3, 0x574A, 0xDBA9,
+	0x574D, 0xD3BB, 0x574E, 0xCAEC, 0x5750, 0xF1A6, 0x5751, 0xCBD5,
+	0x5761, 0xF7E7, 0x5764, 0xCDDE, 0x5766, 0xF7A4, 0x576A, 0xF8C0,
+	0x576E, 0xD3DD, 0x5770, 0xCCD0, 0x5775, 0xCFA6, 0x577C, 0xF6F3,
+	0x5782, 0xE1F7, 0x5788, 0xD3DC, 0x578B, 0xFAFE, 0x5793, 0xFAA7,
+	0x57A0, 0xEBD9, 0x57A2, 0xCFA7, 0x57A3, 0xEAAF, 0x57C3, 0xE4EF,
+	0x57C7, 0xE9B9, 0x57C8, 0xF1D8, 0x57CB, 0xD8D8, 0x57CE, 0xE0F2,
+	0x57DF, 0xE6B4, 0x57E0, 0xDCFC, 0x57F0, 0xF3F1, 0x57F4, 0xE3D0,
+	0x57F7, 0xF2FB, 0x57F9, 0xDBC6, 0x57FA, 0xD0F1, 0x57FC, 0xD0F2,
+	0x5800, 0xCFDC, 0x5802, 0xD3D1, 0x5805, 0xCCB1, 0x5806, 0xF7D8,
+	0x5808, 0xCBA8, 0x5809, 0xEBBC, 0x580A, 0xE4BE, 0x581E, 0xF4DC,
+	0x5821, 0xDCC2, 0x5824, 0xF0A7, 0x5827, 0xE6C0, 0x582A, 0xCAED,
+	0x582F, 0xE8EB, 0x5830, 0xE5E8, 0x5831, 0xDCC3, 0x5834, 0xEDDE,
+	0x5835, 0xD3F2, 0x583A, 0xCCF7, 0x584A, 0xCED4, 0x584B, 0xE7AB,
+	0x584F, 0xCBC3, 0x5851, 0xE1B1, 0x5854, 0xF7B2, 0x5857, 0xD3F3,
+	0x5858, 0xD3D2, 0x585A, 0xF5C0, 0x585E, 0xDFDD, 0x5861, 0xEEF3,
+	0x5862, 0xE7F1, 0x5864, 0xFDB4, 0x5875, 0xF2C8, 0x5879, 0xF3D2,
+	0x587C, 0xEEF4, 0x587E, 0xE2D3, 0x5883, 0xCCD1, 0x5885, 0xDFEA,
+	0x5889, 0xE9BA, 0x5893, 0xD9D7, 0x589C, 0xF5CD, 0x589E, 0xF1F2,
+	0x589F, 0xFAC7, 0x58A8, 0xD9F8, 0x58A9, 0xD4C2, 0x58AE, 0xF6E5,
+	0x58B3, 0xDDC5, 0x58BA, 0xE7F2, 0x58BB, 0xEDDF, 0x58BE, 0xCACB,
+	0x58C1, 0xDBFA, 0x58C5, 0xE8B5, 0x58C7, 0xD3A6, 0x58CE, 0xFDB5,
+	0x58D1, 0xF9C9, 0x58D3, 0xE4E2, 0x58D5, 0xFBBD, 0x58D8, 0xD7A4,
+	0x58D9, 0xCEC5, 0x58DE, 0xCED5, 0x58DF, 0xD6E6, 0x58E4, 0xE5BD,
+	0x58EB, 0xDECD, 0x58EC, 0xECF3, 0x58EF, 0xEDE0, 0x58F9, 0xECEC,
+	0x58FA, 0xFBBE, 0x58FB, 0xDFEB, 0x58FD, 0xE1F8, 0x590F, 0xF9BE,
+	0x5914, 0xD0F3, 0x5915, 0xE0AA, 0x5916, 0xE8E2, 0x5919, 0xE2D4,
+	0x591A, 0xD2FD, 0x591C, 0xE5A8, 0x5922, 0xD9D3, 0x5927, 0xD3DE,
+	0x5929, 0xF4B8, 0x592A, 0xF7BC, 0x592B, 0xDCFD, 0x592D, 0xE8EC,
+	0x592E, 0xE4E7, 0x5931, 0xE3F7, 0x5937, 0xECA8, 0x593E, 0xFAF1,
+	0x5944, 0xE5F2, 0x5947, 0xD0F4, 0x5948, 0xD2AF, 0x5949, 0xDCE5,
+	0x594E, 0xD0A5, 0x594F, 0xF1B4, 0x5950, 0xFCB1, 0x5951, 0xCCF8,
+	0x5954, 0xDDC6, 0x5955, 0xFAD1, 0x5957, 0xF7DF, 0x595A, 0xFAA8,
+	0x5960, 0xEEF5, 0x5962, 0xDECE, 0x5967, 0xE7F3, 0x596A, 0xF7AC,
+	0x596B, 0xEBC4, 0x596C, 0xEDE1, 0x596D, 0xE0AB, 0x596E, 0xDDC7,
+	0x5973, 0xD2B3, 0x5974, 0xD2BF, 0x5978, 0xCACC, 0x597D, 0xFBBF,
+	0x5982, 0xE5FD, 0x5983, 0xDDE5, 0x5984, 0xD8CD, 0x598A, 0xECF4,
+	0x5993, 0xD0F5, 0x5996, 0xE8ED, 0x5997, 0xD0D2, 0x5999, 0xD9D8,
+	0x59A5, 0xF6E6, 0x59A8, 0xDBAA, 0x59AC, 0xF7E0, 0x59B9, 0xD8D9,
+	0x59BB, 0xF4A3, 0x59BE, 0xF4DD, 0x59C3, 0xEFD1, 0x59C6, 0xD9B5,
+	0x59C9, 0xEDAB, 0x59CB, 0xE3B7, 0x59D0, 0xEEBB, 0x59D1, 0xCDB4,
+	0x59D3, 0xE0F3, 0x59D4, 0xEACD, 0x59D9, 0xECF5, 0x59DA, 0xE8EE,
+	0x59DC, 0xCBA9, 0x59DD, 0xF1AF, 0x59E6, 0xCACD, 0x59E8, 0xECA9,
+	0x59EA, 0xF2EB, 0x59EC, 0xFDEF, 0x59EE, 0xF9F3, 0x59F8, 0xE6C1,
+	0x59FB, 0xECD8, 0x59FF, 0xEDAC, 0x5A01, 0xEACE, 0x5A03, 0xE8DF,
+	0x5A11, 0xDECF, 0x5A18, 0xD2A6, 0x5A1B, 0xE7F4, 0x5A1C, 0xD1D6,
+	0x5A1F, 0xE6C2, 0x5A20, 0xE3E3, 0x5A25, 0xE4B0, 0x5A29, 0xD8B4,
+	0x5A36, 0xF6A5, 0x5A3C, 0xF3DE, 0x5A41, 0xD7A5, 0x5A46, 0xF7E8,
+	0x5A49, 0xE8C6, 0x5A5A, 0xFBE6, 0x5A62, 0xDDE6, 0x5A66, 0xDCFE,
+	0x5A92, 0xD8DA, 0x5A9A, 0xDAAC, 0x5A9B, 0xEAB0, 0x5AA4, 0xE3B8,
+	0x5AC1, 0xCAAA, 0x5AC2, 0xE1F9, 0x5AC4, 0xEAB1, 0x5AC9, 0xF2EC,
+	0x5ACC, 0xFAEE, 0x5AE1, 0xEED5, 0x5AE6, 0xF9F4, 0x5AE9, 0xD2EC,
+	0x5B05, 0xFBFB, 0x5B09, 0xFDF0, 0x5B0B, 0xE0BD, 0x5B0C, 0xCEE3,
+	0x5B16, 0xF8C6, 0x5B2A, 0xDEAE, 0x5B40, 0xDFC5, 0x5B43, 0xE5BE,
+	0x5B50, 0xEDAD, 0x5B51, 0xFAEA, 0x5B54, 0xCDEE, 0x5B55, 0xEDA6,
+	0x5B57, 0xEDAE, 0x5B58, 0xF0ED, 0x5B5A, 0xDDA1, 0x5B5C, 0xEDAF,
+	0x5B5D, 0xFCF8, 0x5B5F, 0xD8EB, 0x5B63, 0xCCF9, 0x5B64, 0xCDB5,
+	0x5B69, 0xFAA9, 0x5B6B, 0xE1DD, 0x5B70, 0xE2D5, 0x5B71, 0xEDCF,
+	0x5B75, 0xDDA2, 0x5B78, 0xF9CA, 0x5B7A, 0xEAE8, 0x5B7C, 0xE5ED,
+	0x5B85, 0xD3EB, 0x5B87, 0xE9D4, 0x5B88, 0xE1FA, 0x5B89, 0xE4CC,
+	0x5B8B, 0xE1E4, 0x5B8C, 0xE8C7, 0x5B8F, 0xCEDB, 0x5B93, 0xDCD5,
+	0x5B95, 0xF7B5, 0x5B96, 0xFCF3, 0x5B97, 0xF0F3, 0x5B98, 0xCEAF,
+	0x5B99, 0xF1B5, 0x5B9A, 0xEFD2, 0x5B9B, 0xE8C8, 0x5B9C, 0xEBF1,
+	0x5BA2, 0xCBD4, 0x5BA3, 0xE0BE, 0x5BA4, 0xE3F8, 0x5BA5, 0xEAE9,
+	0x5BA6, 0xFCB2, 0x5BAC, 0xE0F4, 0x5BAE, 0xCFE0, 0x5BB0, 0xEEA5,
+	0x5BB3, 0xFAAA, 0x5BB4, 0xE6C3, 0x5BB5, 0xE1B2, 0x5BB6, 0xCAAB,
+	0x5BB8, 0xE3E4, 0x5BB9, 0xE9BB, 0x5BBF, 0xE2D6, 0x5BC0, 0xF3F2,
+	0x5BC2, 0xEED6, 0x5BC3, 0xEAB2, 0x5BC4, 0xD0F6, 0x5BC5, 0xECD9,
+	0x5BC6, 0xDACB, 0x5BC7, 0xCFA8, 0x5BCC, 0xDDA3, 0x5BD0, 0xD8DB,
+	0x5BD2, 0xF9CE, 0x5BD3, 0xE9D5, 0x5BD4, 0xE3D1, 0x5BD7, 0xD2BC,
+	0x5BDE, 0xD8AC, 0x5BDF, 0xF3CC, 0x5BE1, 0xCDFB, 0x5BE2, 0xF6D6,
+	0x5BE4, 0xE7F5, 0x5BE5, 0xE8EF, 0x5BE6, 0xE3F9, 0x5BE7, 0xD2BB,
+	0x5BE8, 0xF3F3, 0x5BE9, 0xE3FB, 0x5BEB, 0xDED0, 0x5BEC, 0xCEB0,
+	0x5BEE, 0xD6F7, 0x5BEF, 0xF1D9, 0x5BF5, 0xF5C1, 0x5BF6, 0xDCC4,
+	0x5BF8, 0xF5BB, 0x5BFA, 0xDED1, 0x5C01, 0xDCE6, 0x5C04, 0xDED2,
+	0x5C07, 0xEDE2, 0x5C08, 0xEEF6, 0x5C09, 0xEACF, 0x5C0A, 0xF0EE,
+	0x5C0B, 0xE3FC, 0x5C0D, 0xD3DF, 0x5C0E, 0xD3F4, 0x5C0F, 0xE1B3,
+	0x5C11, 0xE1B4, 0x5C16, 0xF4D3, 0x5C19, 0xDFC6, 0x5C24, 0xE9D6,
+	0x5C28, 0xDBAB, 0x5C31, 0xF6A6, 0x5C38, 0xE3B9, 0x5C39, 0xEBC5,
+	0x5C3A, 0xF4A9, 0x5C3B, 0xCDB6, 0x5C3C, 0xD2F9, 0x5C3E, 0xDAAD,
+	0x5C3F, 0xD2E3, 0x5C40, 0xCFD1, 0x5C45, 0xCBDC, 0x5C46, 0xCCFA,
+	0x5C48, 0xCFDD, 0x5C4B, 0xE8A9, 0x5C4D, 0xE3BB, 0x5C4E, 0xE3BA,
+	0x5C51, 0xE0DA, 0x5C55, 0xEEF7, 0x5C5B, 0xDCB3, 0x5C60, 0xD3F5,
+	0x5C62, 0xD7A6, 0x5C64, 0xF6B5, 0x5C65, 0xD7DB, 0x5C6C, 0xE1D5,
+	0x5C6F, 0xD4EA, 0x5C71, 0xDFA3, 0x5C79, 0xFDDF, 0x5C90, 0xD0F7,
+	0x5C91, 0xEDD4, 0x5CA1, 0xCBAA, 0x5CA9, 0xE4DB, 0x5CAB, 0xE1FB,
+	0x5CAC, 0xCBA2, 0x5CB1, 0xD3E0, 0x5CB3, 0xE4BF, 0x5CB5, 0xFBC0,
+	0x5CB7, 0xDABE, 0x5CB8, 0xE4CD, 0x5CBA, 0xD6B9, 0x5CBE, 0xEFC0,
+	0x5CC0, 0xE1FC, 0x5CD9, 0xF6B9, 0x5CE0, 0xDFC7, 0x5CE8, 0xE4B1,
+	0x5CEF, 0xDCE7, 0x5CF0, 0xDCE8, 0x5CF4, 0xFAD6, 0x5CF6, 0xD3F6,
+	0x5CFB, 0xF1DA, 0x5CFD, 0xFAF2, 0x5D07, 0xE2FD, 0x5D0D, 0xD5CF,
+	0x5D0E, 0xD0F8, 0x5D11, 0xCDDF, 0x5D14, 0xF5CB, 0x5D16, 0xE4F0,
+	0x5D17, 0xCBAB, 0x5D19, 0xD7C4, 0x5D27, 0xE2FE, 0x5D29, 0xDDDA,
+	0x5D4B, 0xDAAE, 0x5D4C, 0xCAEE, 0x5D50, 0xD5B9, 0x5D69, 0xE3A1,
+	0x5D6C, 0xE8E3, 0x5D6F, 0xF3AB, 0x5D87, 0xCFA9, 0x5D8B, 0xD3F7,
+	0x5D9D, 0xD4F1, 0x5DA0, 0xCEE4, 0x5DA2, 0xE8F2, 0x5DAA, 0xE5F5,
+	0x5DB8, 0xE7AE, 0x5DBA, 0xD6BA, 0x5DBC, 0xDFEC, 0x5DBD, 0xE4C0,
+	0x5DCD, 0xE8E4, 0x5DD2, 0xD8B5, 0x5DD6, 0xE4DC, 0x5DDD, 0xF4B9,
+	0x5DDE, 0xF1B6, 0x5DE1, 0xE2DE, 0x5DE2, 0xE1B5, 0x5DE5, 0xCDEF,
+	0x5DE6, 0xF1A7, 0x5DE7, 0xCEE5, 0x5DE8, 0xCBDD, 0x5DEB, 0xD9E3,
+	0x5DEE, 0xF3AC, 0x5DF1, 0xD0F9, 0x5DF2, 0xECAB, 0x5DF3, 0xDED3,
+	0x5DF4, 0xF7E9, 0x5DF7, 0xF9F5, 0x5DFD, 0xE1DE, 0x5DFE, 0xCBEE,
+	0x5E02, 0xE3BC, 0x5E03, 0xF8D6, 0x5E06, 0xDBEE, 0x5E0C, 0xFDF1,
+	0x5E11, 0xF7B6, 0x5E16, 0xF4DE, 0x5E19, 0xF2ED, 0x5E1B, 0xDBD9,
+	0x5E1D, 0xF0A8, 0x5E25, 0xE1FD, 0x5E2B, 0xDED4, 0x5E2D, 0xE0AC,
+	0x5E33, 0xEDE3, 0x5E36, 0xD3E1, 0x5E38, 0xDFC8, 0x5E3D, 0xD9B6,
+	0x5E3F, 0xFDAC, 0x5E40, 0xEFD3, 0x5E44, 0xE4C1, 0x5E45, 0xF8EB,
+	0x5E47, 0xDBAC, 0x5E4C, 0xFCC6, 0x5E55, 0xD8AD, 0x5E5F, 0xF6BA,
+	0x5E61, 0xDBDF, 0x5E62, 0xD3D3, 0x5E63, 0xF8C7, 0x5E72, 0xCACE,
+	0x5E73, 0xF8C1, 0x5E74, 0xD2B4, 0x5E77, 0xDCB4, 0x5E78, 0xFAB9,
+	0x5E79, 0xCACF, 0x5E7B, 0xFCB3, 0x5E7C, 0xEAEA, 0x5E7D, 0xEAEB,
+	0x5E7E, 0xD0FA, 0x5E84, 0xEDE4, 0x5E87, 0xDDE7, 0x5E8A, 0xDFC9,
+	0x5E8F, 0xDFED, 0x5E95, 0xEEBC, 0x5E97, 0xEFC1, 0x5E9A, 0xCCD2,
+	0x5E9C, 0xDDA4, 0x5EA0, 0xDFCA, 0x5EA6, 0xD3F8, 0x5EA7, 0xF1A8,
+	0x5EAB, 0xCDB7, 0x5EAD, 0xEFD4, 0x5EB5, 0xE4DD, 0x5EB6, 0xDFEE,
+	0x5EB7, 0xCBAC, 0x5EB8, 0xE9BC, 0x5EBE, 0xEAEC, 0x5EC2, 0xDFCB,
+	0x5EC8, 0xF9BF, 0x5EC9, 0xD6AF, 0x5ECA, 0xD5C6, 0x5ED0, 0xCFAA,
+	0x5ED3, 0xCEA9, 0x5ED6, 0xD6F8, 0x5EDA, 0xF1B7, 0x5EDB, 0xEEF8,
+	0x5EDF, 0xD9D9, 0x5EE0, 0xF3DF, 0x5EE2, 0xF8C8, 0x5EE3, 0xCEC6,
+	0x5EEC, 0xD5E6, 0x5EF3, 0xF4E6, 0x5EF6, 0xE6C5, 0x5EF7, 0xEFD5,
+	0x5EFA, 0xCBEF, 0x5EFB, 0xFCDF, 0x5F01, 0xDCA7, 0x5F04, 0xD6E7,
+	0x5F0A, 0xF8C9, 0x5F0F, 0xE3D2, 0x5F11, 0xE3BD, 0x5F13, 0xCFE1,
+	0x5F14, 0xF0C0, 0x5F15, 0xECDA, 0x5F17, 0xDDD7, 0x5F18, 0xFBF0,
+	0x5F1B, 0xECAC, 0x5F1F, 0xF0A9, 0x5F26, 0xFAD7, 0x5F27, 0xFBC1,
+	0x5F29, 0xD2C0, 0x5F31, 0xE5B0, 0x5F35, 0xEDE5, 0x5F3A, 0xCBAD,
+	0x5F3C, 0xF9B0, 0x5F48, 0xF7A5, 0x5F4A, 0xCBAE, 0x5F4C, 0xDAAF,
+	0x5F4E, 0xD8B6, 0x5F56, 0xD3A7, 0x5F57, 0xFBB2, 0x5F59, 0xFDC4,
+	0x5F5B, 0xECAD, 0x5F62, 0xFBA1, 0x5F66, 0xE5E9, 0x5F67, 0xE9EE,
+	0x5F69, 0xF3F4, 0x5F6A, 0xF8F3, 0x5F6B, 0xF0C1, 0x5F6C, 0xDEAF,
+	0x5F6D, 0xF8B0, 0x5F70, 0xF3E0, 0x5F71, 0xE7AF, 0x5F77, 0xDBAD,
+	0x5F79, 0xE6B5, 0x5F7C, 0xF9A8, 0x5F7F, 0xDDD8, 0x5F80, 0xE8D9,
+	0x5F81, 0xEFD6, 0x5F85, 0xD3E2, 0x5F87, 0xE2DF, 0x5F8A, 0xFCE0,
+	0x5F8B, 0xD7C8, 0x5F8C, 0xFDAD, 0x5F90, 0xDFEF, 0x5F91, 0xCCD3,
+	0x5F92, 0xD3F9, 0x5F97, 0xD4F0, 0x5F98, 0xDBC7, 0x5F99, 0xDED5,
+	0x5F9E, 0xF0F4, 0x5FA0, 0xD5D0, 0x5FA1, 0xE5D9, 0x5FA8, 0xFCC7,
+	0x5FA9, 0xDCD6, 0x5FAA, 0xE2E0, 0x5FAE, 0xDAB0, 0x5FB5, 0xF3A3,
+	0x5FB7, 0xD3EC, 0x5FB9, 0xF4CB, 0x5FBD, 0xFDC5, 0x5FC3, 0xE3FD,
+	0x5FC5, 0xF9B1, 0x5FCC, 0xD0FB, 0x5FCD, 0xECDB, 0x5FD6, 0xF5BC,
+	0x5FD7, 0xF2A4, 0x5FD8, 0xD8CE, 0x5FD9, 0xD8CF, 0x5FE0, 0xF5F7,
+	0x5FEB, 0xF6E1, 0x5FF5, 0xD2B7, 0x5FFD, 0xFBEC, 0x5FFF, 0xDDC8,
+	0x600F, 0xE4E8, 0x6012, 0xD2C1, 0x6016, 0xF8D7, 0x601C, 0xD6BB,
+	0x601D, 0xDED6, 0x6020, 0xF7BD, 0x6021, 0xECAE, 0x6025, 0xD0E1,
+	0x6027, 0xE0F5, 0x6028, 0xEAB3, 0x602A, 0xCED6, 0x602F, 0xCCA5,
+	0x6041, 0xECF6, 0x6042, 0xE2E1, 0x6043, 0xE3BE, 0x604D, 0xFCC8,
+	0x6050, 0xCDF0, 0x6052, 0xF9F6, 0x6055, 0xDFF0, 0x6059, 0xE5BF,
+	0x605D, 0xCEBF, 0x6062, 0xFCE1, 0x6063, 0xEDB0, 0x6064, 0xFDD1,
+	0x6065, 0xF6BB, 0x6068, 0xF9CF, 0x6069, 0xEBDA, 0x606A, 0xCAC1,
+	0x606C, 0xD2B8, 0x606D, 0xCDF1, 0x606F, 0xE3D3, 0x6070, 0xFDE6,
+	0x6085, 0xE6ED, 0x6089, 0xE3FA, 0x608C, 0xF0AA, 0x608D, 0xF9D0,
+	0x6094, 0xFCE2, 0x6096, 0xF8A7, 0x609A, 0xE1E5, 0x609B, 0xEEF9,
+	0x609F, 0xE7F6, 0x60A0, 0xEAED, 0x60A3, 0xFCB4, 0x60A4, 0xF5C2,
+	0x60A7, 0xD7DC, 0x60B0, 0xF0F5, 0x60B2, 0xDDE8, 0x60B3, 0xD3ED,
+	0x60B4, 0xF5FC, 0x60B6, 0xDABF, 0x60B8, 0xCCFB, 0x60BC, 0xD3FA,
+	0x60BD, 0xF4A4, 0x60C5, 0xEFD7, 0x60C7, 0xD4C3, 0x60D1, 0xFBE3,
+	0x60DA, 0xFBED, 0x60DC, 0xE0AD, 0x60DF, 0xEAEE, 0x60E0, 0xFBB3,
+	0x60E1, 0xE4C2, 0x60F0, 0xF6E7, 0x60F1, 0xD2DD, 0x60F3, 0xDFCC,
+	0x60F6, 0xFCC9, 0x60F9, 0xE5A9, 0x60FA, 0xE0F6, 0x60FB, 0xF6B3,
+	0x6101, 0xE1FE, 0x6106, 0xCBF0, 0x6108, 0xEAEF, 0x6109, 0xEAF0,
+	0x610D, 0xDAC0, 0x610E, 0xF8B4, 0x610F, 0xEBF2, 0x6115, 0xE4C3,
+	0x611A, 0xE9D7, 0x611B, 0xE4F1, 0x611F, 0xCAEF, 0x6127, 0xCED7,
+	0x6130, 0xFCCA, 0x6134, 0xF3E1, 0x6137, 0xCBC4, 0x613C, 0xE3E5,
+	0x613E, 0xCBC5, 0x613F, 0xEAB4, 0x6142, 0xE9BD, 0x6144, 0xD7C9,
+	0x6147, 0xEBDB, 0x6148, 0xEDB1, 0x614A, 0xCCC3, 0x614B, 0xF7BE,
+	0x614C, 0xFCCB, 0x6153, 0xF8F4, 0x6155, 0xD9B7, 0x6158, 0xF3D3,
+	0x6159, 0xF3D4, 0x615D, 0xF7E4, 0x615F, 0xF7D1, 0x6162, 0xD8B7,
+	0x6163, 0xCEB1, 0x6164, 0xCAC2, 0x6167, 0xFBB4, 0x6168, 0xCBC6,
+	0x616B, 0xF0F6, 0x616E, 0xD5E7, 0x6170, 0xEAD0, 0x6176, 0xCCD4,
+	0x6177, 0xCBAF, 0x617D, 0xF4AA, 0x617E, 0xE9AF, 0x6181, 0xF5C3,
+	0x6182, 0xE9D8, 0x618A, 0xDDE9, 0x618E, 0xF1F3, 0x6190, 0xD5FB,
+	0x6191, 0xDEBB, 0x6194, 0xF4FB, 0x6198, 0xFDF3, 0x6199, 0xFDF2,
+	0x619A, 0xF7A6, 0x61A4, 0xDDC9, 0x61A7, 0xD4D3, 0x61A9, 0xCCA8,
+	0x61AB, 0xDAC1, 0x61AC, 0xCCD5, 0x61AE, 0xD9E4, 0x61B2, 0xFACA,
+	0x61B6, 0xE5E3, 0x61BA, 0xD3BC, 0x61BE, 0xCAF0, 0x61C3, 0xD0C4,
+	0x61C7, 0xCAD0, 0x61C8, 0xFAAB, 0x61C9, 0xEBEB, 0x61CA, 0xE7F8,
+	0x61CB, 0xD9E5, 0x61E6, 0xD1D7, 0x61F2, 0xF3A4, 0x61F6, 0xD4FB,
+	0x61F7, 0xFCE3, 0x61F8, 0xFAD8, 0x61FA, 0xF3D5, 0x61FC, 0xCFAB,
+	0x61FF, 0xEBF3, 0x6200, 0xD5FC, 0x6207, 0xD3D4, 0x6208, 0xCDFC,
+	0x620A, 0xD9E6, 0x620C, 0xE2F9, 0x620D, 0xE2A1, 0x620E, 0xEBD4,
+	0x6210, 0xE0F7, 0x6211, 0xE4B2, 0x6212, 0xCCFC, 0x6216, 0xFBE4,
+	0x621A, 0xF4AB, 0x621F, 0xD0BD, 0x6221, 0xCAF1, 0x622A, 0xEFB8,
+	0x622E, 0xD7C0, 0x6230, 0xEEFA, 0x6231, 0xFDF4, 0x6234, 0xD3E3,
+	0x6236, 0xFBC2, 0x623E, 0xD5E8, 0x623F, 0xDBAE, 0x6240, 0xE1B6,
+	0x6241, 0xF8B7, 0x6247, 0xE0BF, 0x6248, 0xFBC3, 0x6249, 0xDDEA,
+	0x624B, 0xE2A2, 0x624D, 0xEEA6, 0x6253, 0xF6E8, 0x6258, 0xF6F5,
+	0x626E, 0xDDCA, 0x6271, 0xD0E2, 0x6276, 0xDDA6, 0x6279, 0xDDEB,
+	0x627C, 0xE4F9, 0x627F, 0xE3AF, 0x6280, 0xD0FC, 0x6284, 0xF4FC,
+	0x6289, 0xCCBC, 0x628A, 0xF7EA, 0x6291, 0xE5E4, 0x6292, 0xDFF1,
+	0x6295, 0xF7E1, 0x6297, 0xF9F7, 0x6298, 0xEFB9, 0x629B, 0xF8D8,
+	0x62AB, 0xF9A9, 0x62B1, 0xF8D9, 0x62B5, 0xEEBD, 0x62B9, 0xD8C6,
+	0x62BC, 0xE4E3, 0x62BD, 0xF5CE, 0x62C2, 0xDDD9, 0x62C7, 0xD9E7,
+	0x62C8, 0xD2B9, 0x62C9, 0xD5C3, 0x62CC, 0xDAE5, 0x62CD, 0xDAD0,
+	0x62CF, 0xD1D9, 0x62D0, 0xCED8, 0x62D2, 0xCBDE, 0x62D3, 0xF4AC,
+	0x62D4, 0xDAFB, 0x62D6, 0xF6E9, 0x62D7, 0xE8F3, 0x62D8, 0xCFAC,
+	0x62D9, 0xF0F0, 0x62DB, 0xF4FD, 0x62DC, 0xDBC8, 0x62EC, 0xCEC0,
+	0x62ED, 0xE3D4, 0x62EE, 0xD1CF, 0x62EF, 0xF1F5, 0x62F1, 0xCDF2,
+	0x62F3, 0xCFEB, 0x62F7, 0xCDB8, 0x62FE, 0xE3A6, 0x62FF, 0xD1DA,
+	0x6301, 0xF2A5, 0x6307, 0xF2A6, 0x6309, 0xE4CE, 0x6311, 0xD3FB,
+	0x632B, 0xF1A9, 0x632F, 0xF2C9, 0x633A, 0xEFD8, 0x633B, 0xE6C9,
+	0x633D, 0xD8B8, 0x633E, 0xFAF3, 0x6349, 0xF3B5, 0x634C, 0xF8A4,
+	0x634F, 0xD1F3, 0x6350, 0xE6C8, 0x6355, 0xF8DA, 0x6367, 0xDCE9,
+	0x6368, 0xDED7, 0x636E, 0xCBDF, 0x6372, 0xCFEC, 0x6377, 0xF4DF,
+	0x637A, 0xD1F4, 0x637B, 0xD2BA, 0x637F, 0xDFF2, 0x6383, 0xE1B7,
+	0x6388, 0xE2A3, 0x6389, 0xD3FC, 0x638C, 0xEDE6, 0x6392, 0xDBC9,
+	0x6396, 0xE4FA, 0x6398, 0xCFDE, 0x639B, 0xCED0, 0x63A0, 0xD5D3,
+	0x63A1, 0xF3F5, 0x63A2, 0xF7AE, 0x63A5, 0xEFC8, 0x63A7, 0xCDF3,
+	0x63A8, 0xF5CF, 0x63A9, 0xE5F3, 0x63AA, 0xF0C2, 0x63C0, 0xCAD1,
+	0x63C4, 0xEAF1, 0x63C6, 0xD0A6, 0x63CF, 0xD9DA, 0x63D0, 0xF0AB,
+	0x63D6, 0xEBE7, 0x63DA, 0xE5C0, 0x63DB, 0xFCB5, 0x63E1, 0xE4C4,
+	0x63ED, 0xCCA9, 0x63EE, 0xFDC6, 0x63F4, 0xEAB5, 0x63F6, 0xE5AA,
+	0x63F7, 0xDFBA, 0x640D, 0xE1DF, 0x640F, 0xDAD1, 0x6414, 0xE1B8,
+	0x6416, 0xE8F4, 0x6417, 0xD3FD, 0x641C, 0xE2A4, 0x6422, 0xF2CA,
+	0x642C, 0xDAE6, 0x642D, 0xF7B3, 0x643A, 0xFDCD, 0x643E, 0xF3B6,
+	0x6458, 0xEED7, 0x6460, 0xF5C4, 0x6469, 0xD8A4, 0x646F, 0xF2A7,
+	0x6478, 0xD9B8, 0x6479, 0xD9B9, 0x647A, 0xEFC9, 0x6488, 0xD6CE,
+	0x6491, 0xF7CB, 0x6492, 0xDFAE, 0x6493, 0xE8F5, 0x649A, 0xD2B5,
+	0x649E, 0xD3D5, 0x64A4, 0xF4CC, 0x64A5, 0xDAFC, 0x64AB, 0xD9E8,
+	0x64AD, 0xF7EB, 0x64AE, 0xF5C9, 0x64B0, 0xF3BC, 0x64B2, 0xDAD2,
+	0x64BB, 0xD3B5, 0x64C1, 0xE8B6, 0x64C4, 0xD6CF, 0x64C5, 0xF4BA,
+	0x64C7, 0xF7C9, 0x64CA, 0xCCAA, 0x64CD, 0xF0C3, 0x64CE, 0xCCD6,
+	0x64D2, 0xD0D3, 0x64D4, 0xD3BD, 0x64D8, 0xDBFB, 0x64DA, 0xCBE0,
+	0x64E1, 0xD3E4, 0x64E2, 0xF6F7, 0x64E5, 0xD5BA, 0x64E6, 0xF3CD,
+	0x64E7, 0xCBE1, 0x64EC, 0xEBF4, 0x64F2, 0xF4AD, 0x64F4, 0xFCAA,
+	0x64FA, 0xF7EC, 0x64FE, 0xE8F6, 0x6500, 0xDAE7, 0x6504, 0xF7CC,
+	0x6518, 0xE5C1, 0x651D, 0xE0EE, 0x6523, 0xD5FD, 0x652A, 0xCEE6,
+	0x652B, 0xFCAB, 0x652C, 0xD5BB, 0x652F, 0xF2A8, 0x6536, 0xE2A5,
+	0x6537, 0xCDB9, 0x6538, 0xEAF2, 0x6539, 0xCBC7, 0x653B, 0xCDF4,
+	0x653E, 0xDBAF, 0x653F, 0xEFD9, 0x6545, 0xCDBA, 0x6548, 0xFCF9,
+	0x654D, 0xDFF3, 0x654E, 0xCEE7, 0x654F, 0xDAC2, 0x6551, 0xCFAD,
+	0x6556, 0xE7F9, 0x6557, 0xF8A8, 0x655E, 0xF3E2, 0x6562, 0xCAF2,
+	0x6563, 0xDFA4, 0x6566, 0xD4C4, 0x656C, 0xCCD7, 0x656D, 0xE5C2,
+	0x6572, 0xCDBB, 0x6574, 0xEFDA, 0x6575, 0xEED8, 0x6577, 0xDDA7,
+	0x6578, 0xE2A6, 0x657E, 0xE0C0, 0x6582, 0xD6B0, 0x6583, 0xF8CA,
+	0x6585, 0xFCFA, 0x6587, 0xD9FE, 0x658C, 0xDEB0, 0x6590, 0xDDEC,
+	0x6591, 0xDAE8, 0x6597, 0xD4E0, 0x6599, 0xD6F9, 0x659B, 0xCDD7,
+	0x659C, 0xDED8, 0x659F, 0xF2F8, 0x65A1, 0xE4D6, 0x65A4, 0xD0C5,
+	0x65A5, 0xF4AE, 0x65A7, 0xDDA8, 0x65AB, 0xEDC5, 0x65AC, 0xF3D6,
+	0x65AF, 0xDED9, 0x65B0, 0xE3E6, 0x65B7, 0xD3A8, 0x65B9, 0xDBB0,
+	0x65BC, 0xE5DA, 0x65BD, 0xE3BF, 0x65C1, 0xDBB1, 0x65C5, 0xD5E9,
+	0x65CB, 0xE0C1, 0x65CC, 0xEFDB, 0x65CF, 0xF0E9, 0x65D2, 0xD7B2,
+	0x65D7, 0xD0FD, 0x65E0, 0xD9E9, 0x65E3, 0xD0FE, 0x65E5, 0xECED,
+	0x65E6, 0xD3A9, 0x65E8, 0xF2A9, 0x65E9, 0xF0C4, 0x65EC, 0xE2E2,
+	0x65ED, 0xE9EF, 0x65F1, 0xF9D1, 0x65F4, 0xE9D9, 0x65FA, 0xE8DA,
+	0x65FB, 0xDAC3, 0x65FC, 0xDAC4, 0x65FD, 0xD4C5, 0x65FF, 0xE7FA,
+	0x6606, 0xCDE0, 0x6607, 0xE3B0, 0x6609, 0xDBB2, 0x660A, 0xFBC4,
+	0x660C, 0xF3E3, 0x660E, 0xD9A5, 0x660F, 0xFBE7, 0x6610, 0xDDCB,
+	0x6611, 0xD0D4, 0x6613, 0xE6B6, 0x6614, 0xE0AE, 0x6615, 0xFDDA,
+	0x661E, 0xDCB5, 0x661F, 0xE0F8, 0x6620, 0xE7B1, 0x6625, 0xF5F0,
+	0x6627, 0xD8DC, 0x6628, 0xEDC6, 0x662D, 0xE1B9, 0x662F, 0xE3C0,
+	0x6630, 0xF9C0, 0x6631, 0xE9F0, 0x6634, 0xD9DB, 0x6636, 0xF3E4,
+	0x663A, 0xDCB6, 0x663B, 0xE4E9, 0x6641, 0xF0C5, 0x6642, 0xE3C1,
+	0x6643, 0xFCCC, 0x6644, 0xFCCD, 0x6649, 0xF2CB, 0x664B, 0xF2CC,
+	0x664F, 0xE4CF, 0x6659, 0xF1DB, 0x665B, 0xFAD9, 0x665D, 0xF1B8,
+	0x665E, 0xFDF5, 0x665F, 0xE0F9, 0x6664, 0xE7FB, 0x6665, 0xFCB7,
+	0x6666, 0xFCE4, 0x6667, 0xFBC5, 0x6668, 0xE3E7, 0x6669, 0xD8B9,
+	0x666B, 0xF6F8, 0x666E, 0xDCC5, 0x666F, 0xCCD8, 0x6673, 0xE0AF,
+	0x6674, 0xF4E7, 0x6676, 0xEFDC, 0x6677, 0xCFFC, 0x6678, 0xEFDD,
+	0x667A, 0xF2AA, 0x6684, 0xFDBE, 0x6687, 0xCAAC, 0x6688, 0xFDBB,
+	0x6689, 0xFDC7, 0x668E, 0xE7B2, 0x6690, 0xEAD1, 0x6691, 0xDFF4,
+	0x6696, 0xD1EC, 0x6697, 0xE4DE, 0x6698, 0xE5C3, 0x669D, 0xD9A6,
+	0x66A0, 0xCDBC, 0x66A2, 0xF3E5, 0x66AB, 0xEDD5, 0x66AE, 0xD9BA,
+	0x66B2, 0xEDE7, 0x66B3, 0xFBB5, 0x66B4, 0xF8EC, 0x66B9, 0xE0E7,
+	0x66BB, 0xCCD9, 0x66BE, 0xD4C6, 0x66C4, 0xE7A5, 0x66C6, 0xD5F5,
+	0x66C7, 0xD3BE, 0x66C9, 0xFCFB, 0x66D6, 0xE4F2, 0x66D9, 0xDFF5,
+	0x66DC, 0xE8F8, 0x66DD, 0xF8ED, 0x66E0, 0xCEC7, 0x66E6, 0xFDF6,
+	0x66F0, 0xE8D8, 0x66F2, 0xCDD8, 0x66F3, 0xE7D6, 0x66F4, 0xCCDA,
+	0x66F7, 0xCAE3, 0x66F8, 0xDFF6, 0x66F9, 0xF0C7, 0x66FA, 0xF0C6,
+	0x66FC, 0xD8BA, 0x66FE, 0xF1F4, 0x66FF, 0xF4F0, 0x6700, 0xF5CC,
+	0x6703, 0xFCE5, 0x6708, 0xEAC5, 0x6709, 0xEAF3, 0x670B, 0xDDDB,
+	0x670D, 0xDCD7, 0x6714, 0xDEFD, 0x6715, 0xF2F9, 0x6717, 0xD5C7,
+	0x671B, 0xD8D0, 0x671D, 0xF0C8, 0x671E, 0xD1A1, 0x671F, 0xD1A2,
+	0x6726, 0xD9D4, 0x6727, 0xD6E8, 0x6728, 0xD9CA, 0x672A, 0xDAB1,
+	0x672B, 0xD8C7, 0x672C, 0xDCE2, 0x672D, 0xF3CE, 0x672E, 0xF5F4,
+	0x6731, 0xF1B9, 0x6734, 0xDAD3, 0x6736, 0xF6EA, 0x673A, 0xCFF5,
+	0x673D, 0xFDAE, 0x6746, 0xCAD2, 0x6749, 0xDFB4, 0x674E, 0xD7DD,
+	0x674F, 0xFABA, 0x6750, 0xEEA7, 0x6751, 0xF5BD, 0x6753, 0xF8F5,
+	0x6756, 0xEDE8, 0x675C, 0xD4E1, 0x675E, 0xD1A3, 0x675F, 0xE1D6,
+	0x676D, 0xF9F8, 0x676F, 0xDBCA, 0x6770, 0xCBF9, 0x6771, 0xD4D4,
+	0x6773, 0xD9DC, 0x6775, 0xEEBE, 0x6777, 0xF7ED, 0x677B, 0xD2EE,
+	0x677E, 0xE1E6, 0x677F, 0xF7F9, 0x6787, 0xDDED, 0x6789, 0xE8DB,
+	0x678B, 0xDBB3, 0x678F, 0xD1F7, 0x6790, 0xE0B0, 0x6793, 0xD4E2,
+	0x6795, 0xF6D7, 0x6797, 0xD7F9, 0x679A, 0xD8DD, 0x679C, 0xCDFD,
+	0x679D, 0xF2AB, 0x67AF, 0xCDBD, 0x67B0, 0xF8C2, 0x67B3, 0xF2AC,
+	0x67B6, 0xCAAD, 0x67B7, 0xCAAE, 0x67B8, 0xCFAE, 0x67BE, 0xE3C2,
+	0x67C4, 0xDCB7, 0x67CF, 0xDBDA, 0x67D0, 0xD9BB, 0x67D1, 0xCAF3,
+	0x67D2, 0xF6D3, 0x67D3, 0xE6F8, 0x67D4, 0xEAF5, 0x67DA, 0xEAF6,
+	0x67DD, 0xF6F9, 0x67E9, 0xCFAF, 0x67EC, 0xCAD3, 0x67EF, 0xCAAF,
+	0x67F0, 0xD2B0, 0x67F1, 0xF1BA, 0x67F3, 0xD7B3, 0x67F4, 0xE3C3,
+	0x67F5, 0xF3FD, 0x67F6, 0xDEDA, 0x67FB, 0xDEDB, 0x67FE, 0xEFDE,
+	0x6812, 0xE2E3, 0x6813, 0xEEFB, 0x6816, 0xDFF7, 0x6817, 0xD7CA,
+	0x6821, 0xCEE8, 0x6822, 0xDBDB, 0x682A, 0xF1BB, 0x682F, 0xE9F1,
+	0x6838, 0xFAB7, 0x6839, 0xD0C6, 0x683C, 0xCCAB, 0x683D, 0xEEA8,
+	0x6840, 0xCBFA, 0x6841, 0xF9F9, 0x6842, 0xCCFD, 0x6843, 0xD3FE,
+	0x6848, 0xE4D0, 0x684E, 0xF2EE, 0x6850, 0xD4D5, 0x6851, 0xDFCD,
+	0x6853, 0xFCB8, 0x6854, 0xD1D0, 0x686D, 0xF2CD, 0x6876, 0xF7D2,
+	0x687F, 0xCAD4, 0x6881, 0xD5D9, 0x6885, 0xD8DE, 0x688F, 0xCDD9,
+	0x6893, 0xEEA9, 0x6894, 0xF6BC, 0x6897, 0xCCDB, 0x689D, 0xF0C9,
+	0x689F, 0xFCFC, 0x68A1, 0xE8C9, 0x68A2, 0xF4FE, 0x68A7, 0xE7FC,
+	0x68A8, 0xD7DE, 0x68AD, 0xDEDC, 0x68AF, 0xF0AC, 0x68B0, 0xCCFE,
+	0x68B1, 0xCDE1, 0x68B3, 0xE1BA, 0x68B5, 0xDBEF, 0x68B6, 0xDAB2,
+	0x68C4, 0xD1A5, 0x68C5, 0xDCB8, 0x68C9, 0xD8F6, 0x68CB, 0xD1A4,
+	0x68CD, 0xCDE2, 0x68D2, 0xDCEA, 0x68D5, 0xF0F7, 0x68D7, 0xF0CA,
+	0x68D8, 0xD0BE, 0x68DA, 0xDDDC, 0x68DF, 0xD4D6, 0x68E0, 0xD3D6,
+	0x68E7, 0xEDD0, 0x68E8, 0xCDA1, 0x68EE, 0xDFB5, 0x68F2, 0xDFF8,
+	0x68F9, 0xD4A1, 0x68FA, 0xCEB2, 0x6900, 0xE8CA, 0x6905, 0xEBF5,
+	0x690D, 0xE3D5, 0x690E, 0xF5D0, 0x6912, 0xF5A1, 0x6927, 0xD9A7,
+	0x6930, 0xE5AB, 0x693D, 0xE6CB, 0x693F, 0xF5F1, 0x694A, 0xE5C5,
+	0x6953, 0xF9A3, 0x6954, 0xE0DB, 0x6955, 0xF6EB, 0x6957, 0xCBF1,
+	0x6959, 0xD9EA, 0x695A, 0xF5A2, 0x695E, 0xD7D1, 0x6960, 0xD1F8,
+	0x6961, 0xEAF8, 0x6962, 0xEAF9, 0x6963, 0xDAB3, 0x6968, 0xEFDF,
+	0x696B, 0xF1EF, 0x696D, 0xE5F6, 0x696E, 0xEEBF, 0x696F, 0xE2E4,
+	0x6975, 0xD0BF, 0x6977, 0xFAAC, 0x6978, 0xF5D1, 0x6979, 0xE7B3,
+	0x6995, 0xE9BE, 0x699B, 0xF2CE, 0x699C, 0xDBB4, 0x69A5, 0xFCCE,
+	0x69A7, 0xDDEE, 0x69AE, 0xE7B4, 0x69B4, 0xD7B4, 0x69BB, 0xF7B4,
+	0x69C1, 0xCDBE, 0x69C3, 0xDAE9, 0x69CB, 0xCFB0, 0x69CC, 0xF7D9,
+	0x69CD, 0xF3E6, 0x69D0, 0xCED9, 0x69E8, 0xCEAA, 0x69EA, 0xCBC8,
+	0x69FB, 0xD0A7, 0x69FD, 0xF0CB, 0x69FF, 0xD0C7, 0x6A02, 0xE4C5,
+	0x6A0A, 0xDBE0, 0x6A11, 0xD5DA, 0x6A13, 0xD7A7, 0x6A17, 0xEEC0,
+	0x6A19, 0xF8F6, 0x6A1E, 0xF5D2, 0x6A1F, 0xEDE9, 0x6A21, 0xD9BC,
+	0x6A23, 0xE5C6, 0x6A35, 0xF5A3, 0x6A38, 0xDAD4, 0x6A39, 0xE2A7,
+	0x6A3A, 0xFBFC, 0x6A3D, 0xF1DC, 0x6A44, 0xCAF4, 0x6A48, 0xE8FA,
+	0x6A4B, 0xCEE9, 0x6A52, 0xE9F8, 0x6A53, 0xE2E5, 0x6A58, 0xD0B9,
+	0x6A59, 0xD4F2, 0x6A5F, 0xD1A6, 0x6A61, 0xDFCE, 0x6A6B, 0xFCF4,
+	0x6A80, 0xD3AA, 0x6A84, 0xCCAC, 0x6A89, 0xEFE0, 0x6A8D, 0xE5E5,
+	0x6A8E, 0xD0D5, 0x6A97, 0xDBFC, 0x6A9C, 0xFCE6, 0x6AA2, 0xCBFE,
+	0x6AA3, 0xEDEA, 0x6AB3, 0xDEB1, 0x6ABB, 0xF9E3, 0x6AC2, 0xD4A2,
+	0x6AC3, 0xCFF6, 0x6AD3, 0xD6D0, 0x6ADA, 0xD5EA, 0x6ADB, 0xF1EE,
+	0x6AF6, 0xFACB, 0x6AFB, 0xE5A1, 0x6B04, 0xD5B1, 0x6B0A, 0xCFED,
+	0x6B0C, 0xEDEB, 0x6B12, 0xD5B2, 0x6B16, 0xD5BC, 0x6B20, 0xFDE2,
+	0x6B21, 0xF3AD, 0x6B23, 0xFDDB, 0x6B32, 0xE9B0, 0x6B3A, 0xD1A7,
+	0x6B3D, 0xFDE3, 0x6B3E, 0xCEB3, 0x6B46, 0xFDE4, 0x6B47, 0xFACE,
+	0x6B4C, 0xCAB0, 0x6B4E, 0xF7A7, 0x6B50, 0xCFB1, 0x6B5F, 0xE6A2,
+	0x6B61, 0xFCB6, 0x6B62, 0xF2AD, 0x6B63, 0xEFE1, 0x6B64, 0xF3AE,
+	0x6B65, 0xDCC6, 0x6B66, 0xD9EB, 0x6B6A, 0xE8E0, 0x6B72, 0xE1A8,
+	0x6B77, 0xD5F6, 0x6B78, 0xCFFD, 0x6B7B, 0xDEDD, 0x6B7F, 0xD9D1,
+	0x6B83, 0xE4EA, 0x6B84, 0xF2CF, 0x6B86, 0xF7BF, 0x6B89, 0xE2E6,
+	0x6B8A, 0xE2A8, 0x6B96, 0xE3D6, 0x6B98, 0xEDD1, 0x6B9E, 0xE9F9,
+	0x6BAE, 0xD6B1, 0x6BAF, 0xDEB2, 0x6BB2, 0xE0E8, 0x6BB5, 0xD3AB,
+	0x6BB7, 0xEBDC, 0x6BBA, 0xDFAF, 0x6BBC, 0xCAC3, 0x6BBF, 0xEEFC,
+	0x6BC1, 0xFDC3, 0x6BC5, 0xEBF6, 0x6BC6, 0xCFB2, 0x6BCB, 0xD9EC,
+	0x6BCD, 0xD9BD, 0x6BCF, 0xD8DF, 0x6BD2, 0xD4B8, 0x6BD3, 0xEBBE,
+	0x6BD4, 0xDDEF, 0x6BD6, 0xDDF0, 0x6BD7, 0xDDF1, 0x6BD8, 0xDDF2,
+	0x6BDB, 0xD9BE, 0x6BEB, 0xFBC6, 0x6BEC, 0xCFB3, 0x6C08, 0xEEFD,
+	0x6C0F, 0xE4AB, 0x6C11, 0xDAC5, 0x6C13, 0xD8EC, 0x6C23, 0xD1A8,
+	0x6C34, 0xE2A9, 0x6C37, 0xDEBC, 0x6C38, 0xE7B5, 0x6C3E, 0xDBF0,
+	0x6C40, 0xEFE2, 0x6C41, 0xF1F0, 0x6C42, 0xCFB4, 0x6C4E, 0xDBF1,
+	0x6C50, 0xE0B1, 0x6C55, 0xDFA5, 0x6C57, 0xF9D2, 0x6C5A, 0xE7FD,
+	0x6C5D, 0xE6A3, 0x6C5E, 0xFBF1, 0x6C5F, 0xCBB0, 0x6C60, 0xF2AE,
+	0x6C68, 0xCDE7, 0x6C6A, 0xE8DC, 0x6C6D, 0xE7D7, 0x6C70, 0xF7C0,
+	0x6C72, 0xD0E3, 0x6C76, 0xDAA1, 0x6C7A, 0xCCBD, 0x6C7D, 0xD1A9,
+	0x6C7E, 0xDDCC, 0x6C81, 0xE3FE, 0x6C82, 0xD1AA, 0x6C83, 0xE8AA,
+	0x6C85, 0xEAB6, 0x6C86, 0xF9FA, 0x6C87, 0xE6CC, 0x6C88, 0xF6D8,
+	0x6C8C, 0xD4C7, 0x6C90, 0xD9CB, 0x6C92, 0xD9D2, 0x6C93, 0xD3CB,
+	0x6C94, 0xD8F7, 0x6C95, 0xDAA9, 0x6C96, 0xF5F8, 0x6C99, 0xDEDE,
+	0x6C9A, 0xF2AF, 0x6C9B, 0xF8A9, 0x6CAB, 0xD8C8, 0x6CAE, 0xEEC1,
+	0x6CB3, 0xF9C1, 0x6CB8, 0xDDF3, 0x6CB9, 0xEAFA, 0x6CBB, 0xF6BD,
+	0x6CBC, 0xE1BB, 0x6CBD, 0xCDBF, 0x6CBE, 0xF4D4, 0x6CBF, 0xE6CD,
+	0x6CC1, 0xFCCF, 0x6CC2, 0xFBA2, 0x6CC4, 0xE0DC, 0x6CC9, 0xF4BB,
+	0x6CCA, 0xDAD5, 0x6CCC, 0xF9B2, 0x6CD3, 0xFBF2, 0x6CD5, 0xDBF6,
+	0x6CD7, 0xDEDF, 0x6CDB, 0xDBF2, 0x6CE1, 0xF8DC, 0x6CE2, 0xF7EE,
+	0x6CE3, 0xEBE8, 0x6CE5, 0xD2FA, 0x6CE8, 0xF1BC, 0x6CEB, 0xFADA,
+	0x6CEE, 0xDAEA, 0x6CEF, 0xDAC6, 0x6CF0, 0xF7C1, 0x6CF3, 0xE7B6,
+	0x6D0B, 0xE5C7, 0x6D0C, 0xD6AC, 0x6D11, 0xDCC7, 0x6D17, 0xE1A9,
+	0x6D19, 0xE2AA, 0x6D1B, 0xD5A6, 0x6D1E, 0xD4D7, 0x6D25, 0xF2D0,
+	0x6D27, 0xEAFB, 0x6D29, 0xE0DD, 0x6D2A, 0xFBF3, 0x6D32, 0xF1BD,
+	0x6D35, 0xE2E7, 0x6D36, 0xFDD7, 0x6D38, 0xCEC8, 0x6D39, 0xEAB7,
+	0x6D3B, 0xFCC0, 0x6D3D, 0xFDE7, 0x6D3E, 0xF7EF, 0x6D41, 0xD7B5,
+	0x6D59, 0xEFBA, 0x6D5A, 0xF1DD, 0x6D5C, 0xDEB3, 0x6D63, 0xE8CB,
+	0x6D66, 0xF8DD, 0x6D69, 0xFBC7, 0x6D6A, 0xD5C8, 0x6D6C, 0xD7DF,
+	0x6D6E, 0xDDA9, 0x6D74, 0xE9B1, 0x6D77, 0xFAAD, 0x6D78, 0xF6D9,
+	0x6D79, 0xFAF4, 0x6D7F, 0xF8AA, 0x6D85, 0xE6EE, 0x6D87, 0xCCDC,
+	0x6D88, 0xE1BC, 0x6D89, 0xE0EF, 0x6D8C, 0xE9BF, 0x6D8D, 0xFCFD,
+	0x6D8E, 0xE6CE, 0x6D91, 0xE1D7, 0x6D93, 0xE6CF, 0x6D95, 0xF4F1,
+	0x6DAF, 0xE4F3, 0x6DB2, 0xE4FB, 0x6DB5, 0xF9E4, 0x6DC0, 0xEFE3,
+	0x6DC3, 0xCFEE, 0x6DC4, 0xF6BE, 0x6DC5, 0xE0B2, 0x6DC6, 0xFCFE,
+	0x6DC7, 0xD1AB, 0x6DCB, 0xD7FA, 0x6DCF, 0xFBC8, 0x6DD1, 0xE2D7,
+	0x6DD8, 0xD4A3, 0x6DD9, 0xF0F8, 0x6DDA, 0xD7A8, 0x6DDE, 0xE1E7,
+	0x6DE1, 0xD3BF, 0x6DE8, 0xEFE4, 0x6DEA, 0xD7C5, 0x6DEB, 0xEBE2,
+	0x6DEE, 0xFCE7, 0x6DF1, 0xE4A2, 0x6DF3, 0xE2E8, 0x6DF5, 0xE6D0,
+	0x6DF7, 0xFBE8, 0x6DF8, 0xF4E8, 0x6DF9, 0xE5F4, 0x6DFA, 0xF4BC,
+	0x6DFB, 0xF4D5, 0x6E17, 0xDFB6, 0x6E19, 0xFCB9, 0x6E1A, 0xEEC2,
+	0x6E1B, 0xCAF5, 0x6E1F, 0xEFE5, 0x6E20, 0xCBE2, 0x6E21, 0xD4A4,
+	0x6E23, 0xDEE0, 0x6E24, 0xDAFD, 0x6E25, 0xE4C6, 0x6E26, 0xE8BE,
+	0x6E2B, 0xE0DE, 0x6E2C, 0xF6B4, 0x6E2D, 0xEAD2, 0x6E2F, 0xF9FB,
+	0x6E32, 0xE0C2, 0x6E34, 0xCAE4, 0x6E36, 0xE7B7, 0x6E38, 0xEAFD,
+	0x6E3A, 0xD9DD, 0x6E3C, 0xDAB4, 0x6E3D, 0xEEAA, 0x6E3E, 0xFBE9,
+	0x6E43, 0xDBCB, 0x6E44, 0xDAB5, 0x6E4A, 0xF1BE, 0x6E4D, 0xD3AC,
+	0x6E56, 0xFBC9, 0x6E58, 0xDFCF, 0x6E5B, 0xD3C0, 0x6E5C, 0xE3D7,
+	0x6E5E, 0xEFE6, 0x6E5F, 0xFCD0, 0x6E67, 0xE9C0, 0x6E6B, 0xF5D3,
+	0x6E6E, 0xECDC, 0x6E6F, 0xF7B7, 0x6E72, 0xEAB8, 0x6E73, 0xD1F9,
+	0x6E7A, 0xDCC8, 0x6E90, 0xEAB9, 0x6E96, 0xF1DE, 0x6E9C, 0xD7B6,
+	0x6E9D, 0xCFB5, 0x6E9F, 0xD9A8, 0x6EA2, 0xECEE, 0x6EA5, 0xDDAA,
+	0x6EAA, 0xCDA2, 0x6EAB, 0xE8AE, 0x6EAF, 0xE1BD, 0x6EB1, 0xF2D1,
+	0x6EB6, 0xE9C1, 0x6EBA, 0xD2FC, 0x6EC2, 0xDBB5, 0x6EC4, 0xF3E7,
+	0x6EC5, 0xD8FE, 0x6EC9, 0xFCD1, 0x6ECB, 0xEDB2, 0x6ECC, 0xF4AF,
+	0x6ECE, 0xFBA3, 0x6ED1, 0xFCC1, 0x6ED3, 0xEEAB, 0x6ED4, 0xD4A5,
+	0x6EEF, 0xF4F2, 0x6EF4, 0xEED9, 0x6EF8, 0xFBCA, 0x6EFE, 0xCDE3,
+	0x6EFF, 0xD8BB, 0x6F01, 0xE5DB, 0x6F02, 0xF8F7, 0x6F06, 0xF6D4,
+	0x6F0F, 0xD7A9, 0x6F11, 0xCBC9, 0x6F14, 0xE6D1, 0x6F15, 0xF0CC,
+	0x6F20, 0xD8AE, 0x6F22, 0xF9D3, 0x6F23, 0xD5FE, 0x6F2B, 0xD8BC,
+	0x6F2C, 0xF2B0, 0x6F31, 0xE2AB, 0x6F32, 0xF3E8, 0x6F38, 0xEFC2,
+	0x6F3F, 0xEDEC, 0x6F41, 0xE7B8, 0x6F51, 0xDAFE, 0x6F54, 0xCCBE,
+	0x6F57, 0xF2FC, 0x6F58, 0xDAEB, 0x6F5A, 0xE2D8, 0x6F5B, 0xEDD6,
+	0x6F5E, 0xD6D1, 0x6F5F, 0xE0B3, 0x6F62, 0xFCD2, 0x6F64, 0xEBC8,
+	0x6F6D, 0xD3C1, 0x6F6E, 0xF0CD, 0x6F70, 0xCFF7, 0x6F7A, 0xEDD2,
+	0x6F7C, 0xD4D8, 0x6F7D, 0xDCC9, 0x6F7E, 0xD7F1, 0x6F81, 0xDFBB,
+	0x6F84, 0xF3A5, 0x6F88, 0xF4CD, 0x6F8D, 0xF1BF, 0x6F8E, 0xF8B1,
+	0x6F90, 0xE9FA, 0x6F94, 0xFBCB, 0x6F97, 0xCAD5, 0x6FA3, 0xF9D4,
+	0x6FA4, 0xF7CA, 0x6FA7, 0xD6C8, 0x6FAE, 0xFCE8, 0x6FAF, 0xF3BD,
+	0x6FB1, 0xEEFE, 0x6FB3, 0xE7FE, 0x6FB9, 0xD3C2, 0x6FBE, 0xD3B6,
+	0x6FC0, 0xCCAD, 0x6FC1, 0xF6FA, 0x6FC2, 0xD6B2, 0x6FC3, 0xD2D8,
+	0x6FCA, 0xE7D8, 0x6FD5, 0xE3A5, 0x6FDA, 0xE7B9, 0x6FDF, 0xF0AD,
+	0x6FE0, 0xFBCC, 0x6FE1, 0xEBA1, 0x6FE4, 0xD4A6, 0x6FE9, 0xFBCD,
+	0x6FEB, 0xD5BD, 0x6FEC, 0xF1DF, 0x6FEF, 0xF6FB, 0x6FF1, 0xDEB4,
+	0x6FFE, 0xD5EB, 0x7001, 0xE5C8, 0x7005, 0xFBA4, 0x7006, 0xD4B9,
+	0x7009, 0xDEE1, 0x700B, 0xE4A3, 0x700F, 0xD7B7, 0x7011, 0xF8EE,
+	0x7015, 0xDEB5, 0x7018, 0xD6D2, 0x701A, 0xF9D5, 0x701B, 0xE7BA,
+	0x701C, 0xEBD5, 0x701D, 0xD5F7, 0x701E, 0xEFE7, 0x701F, 0xE1BE,
+	0x7023, 0xFAAE, 0x7027, 0xD6E9, 0x7028, 0xD6EE, 0x702F, 0xE7BB,
+	0x7037, 0xECCB, 0x703E, 0xD5B3, 0x704C, 0xCEB4, 0x7050, 0xFBA5,
+	0x7051, 0xE1EE, 0x7058, 0xF7A8, 0x705D, 0xFBCE, 0x7063, 0xD8BD,
+	0x706B, 0xFBFD, 0x7070, 0xFCE9, 0x7078, 0xCFB6, 0x707C, 0xEDC7,
+	0x707D, 0xEEAC, 0x7085, 0xCCDD, 0x708A, 0xF6A7, 0x708E, 0xE6FA,
+	0x7092, 0xF5A4, 0x7098, 0xFDDC, 0x7099, 0xEDB3, 0x709A, 0xCEC9,
+	0x70A1, 0xEFE8, 0x70A4, 0xE1BF, 0x70AB, 0xFADB, 0x70AC, 0xCBE3,
+	0x70AD, 0xF7A9, 0x70AF, 0xFBA6, 0x70B3, 0xDCB9, 0x70B7, 0xF1C0,
+	0x70B8, 0xEDC8, 0x70B9, 0xEFC3, 0x70C8, 0xD6AD, 0x70CB, 0xFDCE,
+	0x70CF, 0xE8A1, 0x70D8, 0xFBF4, 0x70D9, 0xD5A7, 0x70DD, 0xF1F6,
+	0x70DF, 0xE6D3, 0x70F1, 0xCCDE, 0x70F9, 0xF8B2, 0x70FD, 0xDCEB,
+	0x7104, 0xFDB6, 0x7109, 0xE5EA, 0x710C, 0xF1E0, 0x7119, 0xDBCC,
+	0x711A, 0xDDCD, 0x711E, 0xD4C8, 0x7121, 0xD9ED, 0x7126, 0xF5A5,
+	0x7130, 0xE6FB, 0x7136, 0xE6D4, 0x7147, 0xFDC8, 0x7149, 0xD6A1,
+	0x714A, 0xFDBF, 0x714C, 0xFCD3, 0x714E, 0xEFA1, 0x7150, 0xE7BC,
+	0x7156, 0xD1EE, 0x7159, 0xE6D5, 0x715C, 0xE9F2, 0x715E, 0xDFB0,
+	0x7164, 0xD8E0, 0x7165, 0xFCBA, 0x7166, 0xFDAF, 0x7167, 0xF0CE,
+	0x7169, 0xDBE1, 0x716C, 0xE5C9, 0x716E, 0xEDB4, 0x717D, 0xE0C3,
+	0x7184, 0xE3D8, 0x7189, 0xE9FB, 0x718A, 0xEAA8, 0x718F, 0xFDB7,
+	0x7192, 0xFBA7, 0x7194, 0xE9C2, 0x7199, 0xFDF7, 0x719F, 0xE2D9,
+	0x71A2, 0xDCEC, 0x71AC, 0xE8A2, 0x71B1, 0xE6F0, 0x71B9, 0xFDF8,
+	0x71BA, 0xFDF9, 0x71BE, 0xF6BF, 0x71C1, 0xE7A7, 0x71C3, 0xE6D7,
+	0x71C8, 0xD4F3, 0x71C9, 0xD4C9, 0x71CE, 0xD6FA, 0x71D0, 0xD7F2,
+	0x71D2, 0xE1C0, 0x71D4, 0xDBE2, 0x71D5, 0xE6D8, 0x71DF, 0xE7BD,
+	0x71E5, 0xF0CF, 0x71E6, 0xF3BE, 0x71E7, 0xE2AC, 0x71ED, 0xF5B7,
+	0x71EE, 0xE0F0, 0x71FB, 0xFDB8, 0x71FC, 0xE3E8, 0x71FE, 0xD4A7,
+	0x71FF, 0xE8FC, 0x7200, 0xFAD2, 0x7206, 0xF8EF, 0x7210, 0xD6D3,
+	0x721B, 0xD5B4, 0x722A, 0xF0D0, 0x722C, 0xF7F0, 0x722D, 0xEEB3,
+	0x7230, 0xEABA, 0x7232, 0xEAD3, 0x7235, 0xEDC9, 0x7236, 0xDDAB,
+	0x723A, 0xE5AC, 0x723B, 0xFDA1, 0x723D, 0xDFD0, 0x723E, 0xECB3,
+	0x7240, 0xDFD1, 0x7246, 0xEDED, 0x7247, 0xF8B8, 0x7248, 0xF7FA,
+	0x724C, 0xF8AB, 0x7252, 0xF4E0, 0x7258, 0xD4BA, 0x7259, 0xE4B3,
+	0x725B, 0xE9DA, 0x725D, 0xDEB6, 0x725F, 0xD9BF, 0x7261, 0xD9C0,
+	0x7262, 0xD6EF, 0x7267, 0xD9CC, 0x7269, 0xDAAA, 0x7272, 0xDFE5,
+	0x7279, 0xF7E5, 0x727D, 0xCCB2, 0x7280, 0xDFF9, 0x7281, 0xD7E0,
+	0x72A2, 0xD4BB, 0x72A7, 0xFDFA, 0x72AC, 0xCCB3, 0x72AF, 0xDBF3,
+	0x72C0, 0xDFD2, 0x72C2, 0xCECA, 0x72C4, 0xEEDA, 0x72CE, 0xE4E4,
+	0x72D0, 0xFBCF, 0x72D7, 0xCFB7, 0x72D9, 0xEEC3, 0x72E1, 0xCEEA,
+	0x72E9, 0xE2AD, 0x72F8, 0xD7E1, 0x72F9, 0xFAF5, 0x72FC, 0xD5C9,
+	0x72FD, 0xF8AC, 0x730A, 0xE7D9, 0x7316, 0xF3E9, 0x731B, 0xD8ED,
+	0x731C, 0xE3C4, 0x731D, 0xF0F1, 0x7325, 0xE8E5, 0x7329, 0xE0FA,
+	0x732A, 0xEEC4, 0x732B, 0xD9DE, 0x7336, 0xEBA2, 0x7337, 0xEBA3,
+	0x733E, 0xFCC2, 0x733F, 0xEABB, 0x7344, 0xE8AB, 0x7345, 0xDEE2,
+	0x7350, 0xEDEF, 0x7352, 0xE8A3, 0x7357, 0xCFF1, 0x7368, 0xD4BC,
+	0x736A, 0xFCEA, 0x7370, 0xE7BE, 0x7372, 0xFCF2, 0x7375, 0xD6B4,
+	0x7378, 0xE2AE, 0x737A, 0xD3B7, 0x737B, 0xFACC, 0x7384, 0xFADC,
+	0x7386, 0xEDB5, 0x7387, 0xE1E3, 0x7389, 0xE8AC, 0x738B, 0xE8DD,
+	0x738E, 0xEFE9, 0x7394, 0xF4BD, 0x7396, 0xCFB8, 0x7397, 0xE9DB,
+	0x7398, 0xD1AC, 0x739F, 0xDAC7, 0x73A7, 0xEBC9, 0x73A9, 0xE8CC,
+	0x73AD, 0xDEB7, 0x73B2, 0xD6BC, 0x73B3, 0xD3E5, 0x73B9, 0xFADD,
+	0x73C0, 0xDAD6, 0x73C2, 0xCAB1, 0x73C9, 0xDAC8, 0x73CA, 0xDFA6,
+	0x73CC, 0xF9B3, 0x73CD, 0xF2D2, 0x73CF, 0xCAC4, 0x73D6, 0xCECB,
+	0x73D9, 0xCDF5, 0x73DD, 0xFDB0, 0x73DE, 0xD5A8, 0x73E0, 0xF1C1,
+	0x73E3, 0xE2E9, 0x73E4, 0xDCCA, 0x73E5, 0xECB4, 0x73E6, 0xFAC0,
+	0x73E9, 0xFBA8, 0x73EA, 0xD0A8, 0x73ED, 0xDAEC, 0x73F7, 0xD9EE,
+	0x73F9, 0xE0FB, 0x73FD, 0xEFEA, 0x73FE, 0xFADE, 0x7401, 0xE0C4,
+	0x7403, 0xCFB9, 0x7405, 0xD5CA, 0x7406, 0xD7E2, 0x7407, 0xE2AF,
+	0x7409, 0xD7B8, 0x7413, 0xE8CD, 0x741B, 0xF6DA, 0x7420, 0xEFA2,
+	0x7421, 0xE2DA, 0x7422, 0xF6FC, 0x7425, 0xFBD0, 0x7426, 0xD1AD,
+	0x7428, 0xCDE4, 0x742A, 0xD1AE, 0x742B, 0xDCED, 0x742C, 0xE8CE,
+	0x742E, 0xF0F9, 0x742F, 0xCEB5, 0x7430, 0xE6FC, 0x7433, 0xD7FB,
+	0x7434, 0xD0D6, 0x7435, 0xDDF5, 0x7436, 0xF7F1, 0x7438, 0xF6FD,
+	0x743A, 0xDBF7, 0x743F, 0xFBEA, 0x7440, 0xE9DC, 0x7441, 0xD9C1,
+	0x7443, 0xF5F2, 0x7444, 0xE0C5, 0x744B, 0xEAD4, 0x7455, 0xF9C2,
+	0x7457, 0xEABC, 0x7459, 0xD2C5, 0x745A, 0xFBD1, 0x745B, 0xE7C0,
+	0x745C, 0xEBA5, 0x745E, 0xDFFA, 0x745F, 0xE3A2, 0x7460, 0xD7B9,
+	0x7462, 0xE9C3, 0x7464, 0xE8FD, 0x7465, 0xE8AF, 0x7468, 0xF2D3,
+	0x7469, 0xFBA9, 0x746A, 0xD8A5, 0x746F, 0xD5CB, 0x747E, 0xD0C8,
+	0x7482, 0xD1AF, 0x7483, 0xD7E3, 0x7487, 0xE0C6, 0x7489, 0xD6A2,
+	0x748B, 0xEDF0, 0x7498, 0xD7F3, 0x749C, 0xFCD4, 0x749E, 0xDAD7,
+	0x749F, 0xCCDF, 0x74A1, 0xF2D4, 0x74A3, 0xD1B0, 0x74A5, 0xCCE0,
+	0x74A7, 0xDBFD, 0x74A8, 0xF3BF, 0x74AA, 0xF0D1, 0x74B0, 0xFCBB,
+	0x74B2, 0xE2B0, 0x74B5, 0xE6A5, 0x74B9, 0xE2DB, 0x74BD, 0xDFDE,
+	0x74BF, 0xE0C7, 0x74C6, 0xF2EF, 0x74CA, 0xCCE1, 0x74CF, 0xD6EA,
+	0x74D4, 0xE7C2, 0x74D8, 0xCEB6, 0x74DA, 0xF3C0, 0x74DC, 0xCDFE,
+	0x74E0, 0xFBD2, 0x74E2, 0xF8F8, 0x74E3, 0xF7FB, 0x74E6, 0xE8BF,
+	0x74EE, 0xE8B7, 0x74F7, 0xEDB6, 0x7501, 0xDCBA, 0x7504, 0xCCB4,
+	0x7511, 0xF1F7, 0x7515, 0xE8B8, 0x7518, 0xCAF6, 0x751A, 0xE4A4,
+	0x751B, 0xF4D6, 0x751F, 0xDFE6, 0x7523, 0xDFA7, 0x7525, 0xDFE7,
+	0x7526, 0xE1C1, 0x7528, 0xE9C4, 0x752B, 0xDCCB, 0x752C, 0xE9C5,
+	0x7530, 0xEFA3, 0x7531, 0xEBA6, 0x7532, 0xCBA3, 0x7533, 0xE3E9,
+	0x7537, 0xD1FB, 0x7538, 0xEFA4, 0x753A, 0xEFEB, 0x7547, 0xD0B4,
+	0x754C, 0xCDA3, 0x754F, 0xE8E6, 0x7551, 0xEFA5, 0x7553, 0xD3CC,
+	0x7554, 0xDAED, 0x7559, 0xD7BA, 0x755B, 0xF2D5, 0x755C, 0xF5E5,
+	0x755D, 0xD9EF, 0x7562, 0xF9B4, 0x7565, 0xD5D4, 0x7566, 0xFDCF,
+	0x756A, 0xDBE3, 0x756F, 0xF1E1, 0x7570, 0xECB6, 0x7575, 0xFBFE,
+	0x7576, 0xD3D7, 0x7578, 0xD1B1, 0x757A, 0xCBB1, 0x757F, 0xD1B2,
+	0x7586, 0xCBB2, 0x7587, 0xF1C2, 0x758A, 0xF4E1, 0x758B, 0xF9B5,
+	0x758E, 0xE1C3, 0x758F, 0xE1C2, 0x7591, 0xEBF7, 0x759D, 0xDFA8,
+	0x75A5, 0xCBCA, 0x75AB, 0xE6B9, 0x75B1, 0xF8DE, 0x75B2, 0xF9AA,
+	0x75B3, 0xCAF7, 0x75B5, 0xEDB7, 0x75B8, 0xD3B8, 0x75B9, 0xF2D6,
+	0x75BC, 0xD4D9, 0x75BD, 0xEEC5, 0x75BE, 0xF2F0, 0x75C2, 0xCAB2,
+	0x75C5, 0xDCBB, 0x75C7, 0xF1F8, 0x75CD, 0xECB7, 0x75D2, 0xE5CA,
+	0x75D4, 0xF6C0, 0x75D5, 0xFDDD, 0x75D8, 0xD4E3, 0x75D9, 0xCCE2,
+	0x75DB, 0xF7D4, 0x75E2, 0xD7E5, 0x75F0, 0xD3C3, 0x75F2, 0xD8A6,
+	0x75F4, 0xF6C1, 0x75FA, 0xDDF6, 0x75FC, 0xCDC0, 0x7600, 0xE5DC,
+	0x760D, 0xE5CB, 0x7619, 0xE1C4, 0x761F, 0xE8B0, 0x7620, 0xF4B0,
+	0x7621, 0xF3EA, 0x7622, 0xDAEE, 0x7624, 0xD7BB, 0x7626, 0xE2B1,
+	0x763B, 0xD7AA, 0x7642, 0xD6FB, 0x764C, 0xE4DF, 0x764E, 0xCAD6,
+	0x7652, 0xEBA8, 0x7656, 0xDBFE, 0x7661, 0xF6C2, 0x7664, 0xEFBB,
+	0x7669, 0xD4FD, 0x766C, 0xE0C8, 0x7670, 0xE8B9, 0x7672, 0xEFA6,
+	0x7678, 0xCDA4, 0x767B, 0xD4F4, 0x767C, 0xDBA1, 0x767D, 0xDBDC,
+	0x767E, 0xDBDD, 0x7684, 0xEEDC, 0x7686, 0xCBCB, 0x7687, 0xFCD5,
+	0x768E, 0xCEEB, 0x7690, 0xCDC1, 0x7693, 0xFBD3, 0x76AE, 0xF9AB,
+	0x76BA, 0xF5D4, 0x76BF, 0xD9A9, 0x76C2, 0xE9DD, 0x76C3, 0xDBCD,
+	0x76C6, 0xDDCE, 0x76C8, 0xE7C3, 0x76CA, 0xECCC, 0x76D2, 0xF9EC,
+	0x76D6, 0xCBCC, 0x76DB, 0xE0FC, 0x76DC, 0xD4A8, 0x76DE, 0xEDD3,
+	0x76DF, 0xD8EF, 0x76E1, 0xF2D7, 0x76E3, 0xCAF8, 0x76E4, 0xDAEF,
+	0x76E7, 0xD6D4, 0x76EE, 0xD9CD, 0x76F2, 0xD8EE, 0x76F4, 0xF2C1,
+	0x76F8, 0xDFD3, 0x76FC, 0xDAF0, 0x76FE, 0xE2EA, 0x7701, 0xE0FD,
+	0x7704, 0xD8F8, 0x7708, 0xF7AF, 0x7709, 0xDAB6, 0x770B, 0xCAD7,
+	0x771E, 0xF2D8, 0x7720, 0xD8F9, 0x7729, 0xFADF, 0x7737, 0xCFEF,
+	0x7738, 0xD9C2, 0x773A, 0xF0D2, 0x773C, 0xE4D1, 0x7740, 0xF3B7,
+	0x774D, 0xFAE0, 0x775B, 0xEFEC, 0x7761, 0xE2B2, 0x7763, 0xD4BD,
+	0x7766, 0xD9CE, 0x776B, 0xF4E2, 0x7779, 0xD4A9, 0x777E, 0xCDC2,
+	0x777F, 0xE7DA, 0x778B, 0xF2D9, 0x7791, 0xD9AA, 0x779E, 0xD8BE,
+	0x77A5, 0xDCAD, 0x77AC, 0xE2EB, 0x77AD, 0xD6FC, 0x77B0, 0xCAF9,
+	0x77B3, 0xD4DA, 0x77BB, 0xF4D7, 0x77BC, 0xCCA1, 0x77BF, 0xCFBA,
+	0x77D7, 0xF5B8, 0x77DB, 0xD9C3, 0x77DC, 0xD0E8, 0x77E2, 0xE3C5,
+	0x77E3, 0xEBF8, 0x77E5, 0xF2B1, 0x77E9, 0xCFBB, 0x77ED, 0xD3AD,
+	0x77EE, 0xE8E1, 0x77EF, 0xCEEC, 0x77F3, 0xE0B4, 0x7802, 0xDEE3,
+	0x7812, 0xDDF7, 0x7825, 0xF2B2, 0x7826, 0xF3F6, 0x7827, 0xF6DB,
+	0x782C, 0xD7FE, 0x7832, 0xF8DF, 0x7834, 0xF7F2, 0x7845, 0xD0A9,
+	0x784F, 0xE6DA, 0x785D, 0xF5A6, 0x786B, 0xD7BC, 0x786C, 0xCCE3,
+	0x786F, 0xE6DB, 0x787C, 0xDDDD, 0x7881, 0xD1B3, 0x7887, 0xEFED,
+	0x788C, 0xD6DE, 0x788D, 0xE4F4, 0x788E, 0xE1EF, 0x7891, 0xDDF8,
+	0x7897, 0xE8CF, 0x78A3, 0xCAE5, 0x78A7, 0xDCA1, 0x78A9, 0xE0B5,
+	0x78BA, 0xFCAC, 0x78BB, 0xFCAD, 0x78BC, 0xD8A7, 0x78C1, 0xEDB8,
+	0x78C5, 0xDBB6, 0x78CA, 0xD6F0, 0x78CB, 0xF3AF, 0x78CE, 0xCDA5,
+	0x78D0, 0xDAF1, 0x78E8, 0xD8A8, 0x78EC, 0xCCE4, 0x78EF, 0xD1B4,
+	0x78F5, 0xCAD8, 0x78FB, 0xDAF2, 0x7901, 0xF5A7, 0x790E, 0xF5A8,
+	0x7916, 0xE6A6, 0x792A, 0xD5EC, 0x792B, 0xD5F8, 0x792C, 0xDAF3,
+	0x793A, 0xE3C6, 0x793E, 0xDEE4, 0x7940, 0xDEE5, 0x7941, 0xD1B5,
+	0x7947, 0xD1B6, 0x7948, 0xD1B7, 0x7949, 0xF2B3, 0x7950, 0xE9DE,
+	0x7956, 0xF0D3, 0x7957, 0xF2B4, 0x795A, 0xF0D4, 0x795B, 0xCBE4,
+	0x795C, 0xFBD4, 0x795D, 0xF5E6, 0x795E, 0xE3EA, 0x7960, 0xDEE6,
+	0x7965, 0xDFD4, 0x7968, 0xF8F9, 0x796D, 0xF0AE, 0x797A, 0xD1B8,
+	0x797F, 0xD6DF, 0x7981, 0xD0D7, 0x798D, 0xFCA1, 0x798E, 0xEFEE,
+	0x798F, 0xDCD8, 0x7991, 0xE9DF, 0x79A6, 0xE5DD, 0x79A7, 0xFDFB,
+	0x79AA, 0xE0C9, 0x79AE, 0xD6C9, 0x79B1, 0xD4AA, 0x79B3, 0xE5CC,
+	0x79B9, 0xE9E0, 0x79BD, 0xD0D8, 0x79BE, 0xFCA2, 0x79BF, 0xD4BE,
+	0x79C0, 0xE2B3, 0x79C1, 0xDEE7, 0x79C9, 0xDCBC, 0x79CA, 0xD2B6,
+	0x79CB, 0xF5D5, 0x79D1, 0xCEA1, 0x79D2, 0xF5A9, 0x79D5, 0xDDF9,
+	0x79D8, 0xDDFA, 0x79DF, 0xF0D5, 0x79E4, 0xF6DF, 0x79E6, 0xF2DA,
+	0x79E7, 0xE4EB, 0x79E9, 0xF2F1, 0x79FB, 0xECB9, 0x7A00, 0xFDFC,
+	0x7A05, 0xE1AA, 0x7A08, 0xCAD9, 0x7A0B, 0xEFEF, 0x7A0D, 0xF5AA,
+	0x7A14, 0xECF9, 0x7A17, 0xF8AD, 0x7A19, 0xF2C2, 0x7A1A, 0xF6C3,
+	0x7A1C, 0xD7D2, 0x7A1F, 0xF9A2, 0x7A20, 0xF0D6, 0x7A2E, 0xF0FA,
+	0x7A31, 0xF6E0, 0x7A36, 0xE9F3, 0x7A37, 0xF2C3, 0x7A3B, 0xD4AB,
+	0x7A3C, 0xCAB3, 0x7A3D, 0xCDA6, 0x7A3F, 0xCDC3, 0x7A40, 0xCDDA,
+	0x7A46, 0xD9CF, 0x7A49, 0xF6C4, 0x7A4D, 0xEEDD, 0x7A4E, 0xE7C4,
+	0x7A57, 0xE2B4, 0x7A61, 0xDFE2, 0x7A62, 0xE7DB, 0x7A69, 0xE8B1,
+	0x7A6B, 0xFCAE, 0x7A70, 0xE5CD, 0x7A74, 0xFAEB, 0x7A76, 0xCFBC,
+	0x7A79, 0xCFE2, 0x7A7A, 0xCDF6, 0x7A7D, 0xEFF0, 0x7A7F, 0xF4BE,
+	0x7A81, 0xD4CD, 0x7A84, 0xF3B8, 0x7A88, 0xE9A1, 0x7A92, 0xF2F2,
+	0x7A93, 0xF3EB, 0x7A95, 0xF0D7, 0x7A98, 0xCFD7, 0x7A9F, 0xCFDF,
+	0x7AA9, 0xE8C0, 0x7AAA, 0xE8C1, 0x7AAE, 0xCFE3, 0x7AAF, 0xE9A2,
+	0x7ABA, 0xD0AA, 0x7AC4, 0xF3C1, 0x7AC5, 0xD0AB, 0x7AC7, 0xD4E4,
+	0x7ACA, 0xEFBC, 0x7ACB, 0xD8A1, 0x7AD7, 0xD9DF, 0x7AD9, 0xF3D7,
+	0x7ADD, 0xDCBD, 0x7ADF, 0xCCE5, 0x7AE0, 0xEDF1, 0x7AE3, 0xF1E2,
+	0x7AE5, 0xD4DB, 0x7AEA, 0xE2B5, 0x7AED, 0xCAE6, 0x7AEF, 0xD3AE,
+	0x7AF6, 0xCCE6, 0x7AF9, 0xF1D3, 0x7AFA, 0xF5E7, 0x7AFF, 0xCADA,
+	0x7B0F, 0xFBEE, 0x7B11, 0xE1C5, 0x7B19, 0xDFE9, 0x7B1B, 0xEEDE,
+	0x7B1E, 0xF7C2, 0x7B20, 0xD8A2, 0x7B26, 0xDDAC, 0x7B2C, 0xF0AF,
+	0x7B2D, 0xD6BD, 0x7B39, 0xE1AB, 0x7B46, 0xF9B6, 0x7B49, 0xD4F5,
+	0x7B4B, 0xD0C9, 0x7B4C, 0xEFA7, 0x7B4D, 0xE2EC, 0x7B4F, 0xDBEA,
+	0x7B50, 0xCECC, 0x7B51, 0xF5E8, 0x7B52, 0xF7D5, 0x7B54, 0xD3CD,
+	0x7B56, 0xF3FE, 0x7B60, 0xD0B5, 0x7B6C, 0xE0FE, 0x7B6E, 0xDFFB,
+	0x7B75, 0xE6DD, 0x7B7D, 0xE8A4, 0x7B87, 0xCBCD, 0x7B8B, 0xEFA8,
+	0x7B8F, 0xEEB4, 0x7B94, 0xDAD8, 0x7B95, 0xD1B9, 0x7B97, 0xDFA9,
+	0x7B9A, 0xF3B0, 0x7B9D, 0xCCC4, 0x7BA1, 0xCEB7, 0x7BAD, 0xEFA9,
+	0x7BB1, 0xDFD5, 0x7BB4, 0xEDD7, 0x7BB8, 0xEEC6, 0x7BC0, 0xEFBD,
+	0x7BC1, 0xFCD6, 0x7BC4, 0xDBF4, 0x7BC6, 0xEFAA, 0x7BC7, 0xF8B9,
+	0x7BC9, 0xF5E9, 0x7BD2, 0xE3D9, 0x7BE0, 0xE1C6, 0x7BE4, 0xD4BF,
+	0x7BE9, 0xDEE8, 0x7C07, 0xF0EA, 0x7C12, 0xF3C2, 0x7C1E, 0xD3AF,
+	0x7C21, 0xCADB, 0x7C27, 0xFCD7, 0x7C2A, 0xEDD8, 0x7C2B, 0xE1C7,
+	0x7C3D, 0xF4D8, 0x7C3E, 0xD6B3, 0x7C3F, 0xDDAD, 0x7C43, 0xD5BE,
+	0x7C4C, 0xF1C3, 0x7C4D, 0xEEDF, 0x7C60, 0xD6EB, 0x7C64, 0xF4D9,
+	0x7C6C, 0xD7E6, 0x7C73, 0xDAB7, 0x7C83, 0xDDFB, 0x7C89, 0xDDCF,
+	0x7C92, 0xD8A3, 0x7C95, 0xDAD9, 0x7C97, 0xF0D8, 0x7C98, 0xEFC4,
+	0x7C9F, 0xE1D8, 0x7CA5, 0xF1D4, 0x7CA7, 0xEDF2, 0x7CAE, 0xD5DB,
+	0x7CB1, 0xD5DC, 0x7CB2, 0xF3C4, 0x7CB3, 0xCBD7, 0x7CB9, 0xE2B6,
+	0x7CBE, 0xEFF1, 0x7CCA, 0xFBD5, 0x7CD6, 0xD3D8, 0x7CDE, 0xDDD0,
+	0x7CDF, 0xF0D9, 0x7CE0, 0xCBB3, 0x7CE7, 0xD5DD, 0x7CFB, 0xCDA7,
+	0x7CFE, 0xD0AC, 0x7D00, 0xD1BA, 0x7D02, 0xF1C4, 0x7D04, 0xE5B3,
+	0x7D05, 0xFBF5, 0x7D06, 0xE9E1, 0x7D07, 0xFDE0, 0x7D08, 0xFCBC,
+	0x7D0A, 0xDAA2, 0x7D0B, 0xDAA3, 0x7D0D, 0xD2A1, 0x7D10, 0xD2EF,
+	0x7D14, 0xE2ED, 0x7D17, 0xDEE9, 0x7D18, 0xCEDC, 0x7D19, 0xF2B5,
+	0x7D1A, 0xD0E4, 0x7D1B, 0xDDD1, 0x7D20, 0xE1C8, 0x7D21, 0xDBB7,
+	0x7D22, 0xDFE3, 0x7D2B, 0xEDB9, 0x7D2C, 0xF1C5, 0x7D2E, 0xF3CF,
+	0x7D2F, 0xD7AB, 0x7D30, 0xE1AC, 0x7D33, 0xE3EB, 0x7D35, 0xEEC7,
+	0x7D39, 0xE1C9, 0x7D3A, 0xCAFA, 0x7D42, 0xF0FB, 0x7D43, 0xFAE1,
+	0x7D44, 0xF0DA, 0x7D45, 0xCCE7, 0x7D46, 0xDAF4, 0x7D50, 0xCCBF,
+	0x7D5E, 0xCEED, 0x7D61, 0xD5A9, 0x7D62, 0xFAE2, 0x7D66, 0xD0E5,
+	0x7D68, 0xEBD6, 0x7D6A, 0xECDF, 0x7D6E, 0xDFFC, 0x7D71, 0xF7D6,
+	0x7D72, 0xDEEA, 0x7D73, 0xCBB4, 0x7D76, 0xEFBE, 0x7D79, 0xCCB5,
+	0x7D7F, 0xCFBD, 0x7D8E, 0xEFF2, 0x7D8F, 0xE2B7, 0x7D93, 0xCCE8,
+	0x7D9C, 0xF0FC, 0x7DA0, 0xD6E0, 0x7DA2, 0xF1C6, 0x7DAC, 0xE2B8,
+	0x7DAD, 0xEBAB, 0x7DB1, 0xCBB5, 0x7DB2, 0xD8D1, 0x7DB4, 0xF4CE,
+	0x7DB5, 0xF3F7, 0x7DB8, 0xD7C6, 0x7DBA, 0xD1BB, 0x7DBB, 0xF7AA,
+	0x7DBD, 0xEDCA, 0x7DBE, 0xD7D3, 0x7DBF, 0xD8FA, 0x7DC7, 0xF6C5,
+	0x7DCA, 0xD1CC, 0x7DCB, 0xDDFC, 0x7DD6, 0xDFFD, 0x7DD8, 0xF9E5,
+	0x7DDA, 0xE0CA, 0x7DDD, 0xF2FD, 0x7DDE, 0xD3B0, 0x7DE0, 0xF4F3,
+	0x7DE1, 0xDAC9, 0x7DE3, 0xE6DE, 0x7DE8, 0xF8BA, 0x7DE9, 0xE8D0,
+	0x7DEC, 0xD8FB, 0x7DEF, 0xEAD5, 0x7DF4, 0xD6A3, 0x7DFB, 0xF6C6,
+	0x7E09, 0xF2DB, 0x7E0A, 0xE4FC, 0x7E15, 0xE8B2, 0x7E1B, 0xDADA,
+	0x7E1D, 0xF2DC, 0x7E1E, 0xFBD6, 0x7E1F, 0xE9B2, 0x7E21, 0xEEAD,
+	0x7E23, 0xFAE3, 0x7E2B, 0xDCEE, 0x7E2E, 0xF5EA, 0x7E2F, 0xE6E0,
+	0x7E31, 0xF0FD, 0x7E37, 0xD7AC, 0x7E3D, 0xF5C5, 0x7E3E, 0xEEE0,
+	0x7E41, 0xDBE5, 0x7E43, 0xDDDE, 0x7E46, 0xD9F0, 0x7E47, 0xE9A3,
+	0x7E52, 0xF1F9, 0x7E54, 0xF2C4, 0x7E55, 0xE0CB, 0x7E5E, 0xE9A4,
+	0x7E61, 0xE2B9, 0x7E69, 0xE3B1, 0x7E6A, 0xFCEB, 0x7E6B, 0xCDA8,
+	0x7E6D, 0xCCB6, 0x7E70, 0xF0DB, 0x7E79, 0xE6BA, 0x7E7C, 0xCDA9,
+	0x7E82, 0xF3C3, 0x7E8C, 0xE1D9, 0x7E8F, 0xEFAB, 0x7E93, 0xE7C5,
+	0x7E96, 0xE0E9, 0x7E98, 0xF3C5, 0x7E9B, 0xD4C0, 0x7E9C, 0xD5BF,
+	0x7F36, 0xDDAE, 0x7F38, 0xF9FC, 0x7F3A, 0xCCC0, 0x7F4C, 0xE5A2,
+	0x7F50, 0xCEB8, 0x7F54, 0xD8D2, 0x7F55, 0xF9D6, 0x7F6A, 0xF1AA,
+	0x7F6B, 0xCED1, 0x7F6E, 0xF6C7, 0x7F70, 0xDBEB, 0x7F72, 0xDFFE,
+	0x7F75, 0xD8E1, 0x7F77, 0xF7F3, 0x7F79, 0xD7E7, 0x7F85, 0xD4FE,
+	0x7F88, 0xD1BC, 0x7F8A, 0xE5CF, 0x7F8C, 0xCBB6, 0x7F8E, 0xDAB8,
+	0x7F94, 0xCDC4, 0x7F9A, 0xD6BE, 0x7F9E, 0xE2BA, 0x7FA4, 0xCFD8,
+	0x7FA8, 0xE0CC, 0x7FA9, 0xEBF9, 0x7FB2, 0xFDFD, 0x7FB8, 0xD7E8,
+	0x7FB9, 0xCBD8, 0x7FBD, 0xE9E2, 0x7FC1, 0xE8BA, 0x7FC5, 0xE3C7,
+	0x7FCA, 0xECCD, 0x7FCC, 0xECCE, 0x7FCE, 0xD6BF, 0x7FD2, 0xE3A7,
+	0x7FD4, 0xDFD6, 0x7FD5, 0xFDE8, 0x7FDF, 0xEEE1, 0x7FE0, 0xF6A8,
+	0x7FE1, 0xDDFD, 0x7FE9, 0xF8BB, 0x7FEB, 0xE8D1, 0x7FF0, 0xF9D7,
+	0x7FF9, 0xCEEE, 0x7FFC, 0xECCF, 0x8000, 0xE9A5, 0x8001, 0xD6D5,
+	0x8003, 0xCDC5, 0x8005, 0xEDBA, 0x8006, 0xD1BD, 0x8009, 0xCFBE,
+	0x800C, 0xECBB, 0x8010, 0xD2B1, 0x8015, 0xCCE9, 0x8017, 0xD9C4,
+	0x8018, 0xE9FC, 0x802D, 0xD1BE, 0x8033, 0xECBC, 0x8036, 0xE5AD,
+	0x803D, 0xF7B0, 0x803F, 0xCCEA, 0x8043, 0xD3C4, 0x8046, 0xD6C0,
+	0x804A, 0xD6FD, 0x8056, 0xE1A1, 0x8058, 0xDEBD, 0x805A, 0xF6A9,
+	0x805E, 0xDAA4, 0x806F, 0xD6A4, 0x8070, 0xF5C6, 0x8072, 0xE1A2,
+	0x8073, 0xE9C6, 0x8077, 0xF2C5, 0x807D, 0xF4E9, 0x807E, 0xD6EC,
+	0x807F, 0xEBD3, 0x8084, 0xECBD, 0x8085, 0xE2DC, 0x8086, 0xDEEB,
+	0x8087, 0xF0DC, 0x8089, 0xEBBF, 0x808B, 0xD7CE, 0x808C, 0xD1BF,
+	0x8096, 0xF5AB, 0x809B, 0xF9FD, 0x809D, 0xCADC, 0x80A1, 0xCDC6,
+	0x80A2, 0xF2B6, 0x80A5, 0xDDFE, 0x80A9, 0xCCB7, 0x80AA, 0xDBB8,
+	0x80AF, 0xD0E9, 0x80B1, 0xCEDD, 0x80B2, 0xEBC0, 0x80B4, 0xFDA2,
+	0x80BA, 0xF8CB, 0x80C3, 0xEAD6, 0x80C4, 0xF1B0, 0x80CC, 0xDBCE,
+	0x80CE, 0xF7C3, 0x80DA, 0xDBCF, 0x80DB, 0xCBA4, 0x80DE, 0xF8E0,
+	0x80E1, 0xFBD7, 0x80E4, 0xEBCA, 0x80E5, 0xE0A1, 0x80F1, 0xCECD,
+	0x80F4, 0xD4DC, 0x80F8, 0xFDD8, 0x80FD, 0xD2F6, 0x8102, 0xF2B7,
+	0x8105, 0xFAF6, 0x8106, 0xF6AA, 0x8107, 0xFAF7, 0x8108, 0xD8E6,
+	0x810A, 0xF4B1, 0x8118, 0xE8D2, 0x811A, 0xCAC5, 0x811B, 0xCCEB,
+	0x8123, 0xE2EE, 0x8129, 0xE2BB, 0x812B, 0xF7AD, 0x812F, 0xF8E1,
+	0x8139, 0xF3EC, 0x813E, 0xDEA1, 0x814B, 0xE4FD, 0x814E, 0xE3EC,
+	0x8150, 0xDDAF, 0x8151, 0xDDB0, 0x8154, 0xCBB7, 0x8155, 0xE8D3,
+	0x8165, 0xE1A3, 0x8166, 0xD2E0, 0x816B, 0xF0FE, 0x8170, 0xE9A6,
+	0x8171, 0xCBF2, 0x8178, 0xEDF3, 0x8179, 0xDCD9, 0x817A, 0xE0CD,
+	0x817F, 0xF7DA, 0x8180, 0xDBB9, 0x8188, 0xCCAE, 0x818A, 0xDADB,
+	0x818F, 0xCDC7, 0x819A, 0xDDB1, 0x819C, 0xD8AF, 0x819D, 0xE3A3,
+	0x81A0, 0xCEEF, 0x81A3, 0xF2F3, 0x81A8, 0xF8B3, 0x81B3, 0xE0CE,
+	0x81B5, 0xF5FD, 0x81BA, 0xEBEC, 0x81BD, 0xD3C5, 0x81BE, 0xFCEC,
+	0x81BF, 0xD2DB, 0x81C0, 0xD4EB, 0x81C2, 0xDEA2, 0x81C6, 0xE5E6,
+	0x81CD, 0xF0B0, 0x81D8, 0xD5C4, 0x81DF, 0xEDF4, 0x81E3, 0xE3ED,
+	0x81E5, 0xE8C2, 0x81E7, 0xEDF5, 0x81E8, 0xD7FC, 0x81EA, 0xEDBB,
+	0x81ED, 0xF6AB, 0x81F3, 0xF2B8, 0x81F4, 0xF6C8, 0x81FA, 0xD3E6,
+	0x81FB, 0xF2DD, 0x81FC, 0xCFBF, 0x81FE, 0xEBAC, 0x8205, 0xCFC0,
+	0x8207, 0xE6A8, 0x8208, 0xFDE9, 0x820A, 0xCFC1, 0x820C, 0xE0DF,
+	0x820D, 0xDEEC, 0x8212, 0xE0A2, 0x821B, 0xF4BF, 0x821C, 0xE2EF,
+	0x821E, 0xD9F1, 0x821F, 0xF1C7, 0x8221, 0xCBB8, 0x822A, 0xF9FE,
+	0x822B, 0xDBBA, 0x822C, 0xDAF5, 0x8235, 0xF6EC, 0x8236, 0xDADC,
+	0x8237, 0xFAE4, 0x8239, 0xE0CF, 0x8240, 0xDDB2, 0x8245, 0xE6A9,
+	0x8247, 0xEFF3, 0x8259, 0xF3ED, 0x8264, 0xEBFA, 0x8266, 0xF9E6,
+	0x826E, 0xCADD, 0x826F, 0xD5DE, 0x8271, 0xCADE, 0x8272, 0xDFE4,
+	0x8276, 0xE6FD, 0x8278, 0xF5AC, 0x827E, 0xE4F5, 0x828B, 0xE9E3,
+	0x828D, 0xEDCB, 0x828E, 0xCFE4, 0x8292, 0xD8D3, 0x8299, 0xDDB3,
+	0x829A, 0xD4EC, 0x829D, 0xF2B9, 0x829F, 0xDFB7, 0x82A5, 0xCBCE,
+	0x82A6, 0xFBD8, 0x82A9, 0xD0D9, 0x82AC, 0xDDD2, 0x82AD, 0xF7F4,
+	0x82AE, 0xE7DC, 0x82AF, 0xE4A5, 0x82B1, 0xFCA3, 0x82B3, 0xDBBB,
+	0x82B7, 0xF2BA, 0x82B8, 0xE9FD, 0x82B9, 0xD0CA, 0x82BB, 0xF5D6,
+	0x82BC, 0xD9C5, 0x82BD, 0xE4B4, 0x82BF, 0xEDA7, 0x82D1, 0xEABD,
+	0x82D2, 0xE6FE, 0x82D4, 0xF7C4, 0x82D5, 0xF5AD, 0x82D7, 0xD9E0,
+	0x82DB, 0xCAB4, 0x82DE, 0xF8E2, 0x82DF, 0xCFC2, 0x82E1, 0xECBE,
+	0x82E5, 0xE5B4, 0x82E6, 0xCDC8, 0x82E7, 0xEEC8, 0x82F1, 0xE7C8,
+	0x82FD, 0xCDC9, 0x82FE, 0xF9B7, 0x8301, 0xF1E8, 0x8302, 0xD9F2,
+	0x8303, 0xDBF5, 0x8304, 0xCAB5, 0x8305, 0xD9C6, 0x8309, 0xD8C9,
+	0x8317, 0xD9AB, 0x8328, 0xEDBC, 0x832B, 0xD8D4, 0x832F, 0xDCDA,
+	0x8331, 0xE2BC, 0x8334, 0xFCED, 0x8335, 0xECE0, 0x8336, 0xD2FE,
+	0x8338, 0xE9C7, 0x8339, 0xE6AA, 0x8340, 0xE2F0, 0x8347, 0xFABB,
+	0x8349, 0xF5AE, 0x834A, 0xFBAA, 0x834F, 0xECFB, 0x8351, 0xECBF,
+	0x8352, 0xFCD8, 0x8373, 0xD4E5, 0x8377, 0xF9C3, 0x837B, 0xEEE2,
+	0x8389, 0xD7E9, 0x838A, 0xEDF6, 0x838E, 0xDEED, 0x8396, 0xCCEC,
+	0x8398, 0xE3EE, 0x839E, 0xE8D4, 0x83A2, 0xFAF8, 0x83A9, 0xDDB4,
+	0x83AA, 0xE4B5, 0x83AB, 0xD8B0, 0x83BD, 0xD8D5, 0x83C1, 0xF4EA,
+	0x83C5, 0xCEB9, 0x83C9, 0xD6E1, 0x83CA, 0xCFD2, 0x83CC, 0xD0B6,
+	0x83D3, 0xCEA2, 0x83D6, 0xF3EE, 0x83DC, 0xF3F8, 0x83E9, 0xDCCC,
+	0x83EB, 0xD0CB, 0x83EF, 0xFCA4, 0x83F0, 0xCDCA, 0x83F1, 0xD7D4,
+	0x83F2, 0xDEA3, 0x83F4, 0xE4E0, 0x83F9, 0xEEC9, 0x83FD, 0xE2DD,
+	0x8403, 0xF5FE, 0x8404, 0xD4AC, 0x840A, 0xD5D1, 0x840C, 0xD8F0,
+	0x840D, 0xF8C3, 0x840E, 0xEAD7, 0x8429, 0xF5D7, 0x842C, 0xD8BF,
+	0x8431, 0xFDC0, 0x8438, 0xEBAD, 0x843D, 0xD5AA, 0x8449, 0xE7A8,
+	0x8457, 0xEECA, 0x845B, 0xCAE7, 0x8461, 0xF8E3, 0x8463, 0xD4DD,
+	0x8466, 0xEAD8, 0x846B, 0xFBD9, 0x846C, 0xEDF7, 0x846F, 0xE5B5,
+	0x8475, 0xD0AD, 0x847A, 0xF1F1, 0x8490, 0xE2BD, 0x8494, 0xE3C8,
+	0x8499, 0xD9D5, 0x849C, 0xDFAA, 0x84A1, 0xDBBC, 0x84B2, 0xF8E4,
+	0x84B8, 0xF1FA, 0x84BB, 0xE5B6, 0x84BC, 0xF3EF, 0x84BF, 0xFBDA,
+	0x84C0, 0xE1E0, 0x84C2, 0xD9AC, 0x84C4, 0xF5EB, 0x84C6, 0xE0B6,
+	0x84C9, 0xE9C8, 0x84CB, 0xCBCF, 0x84CD, 0xE3C9, 0x84D1, 0xDEEE,
+	0x84DA, 0xE2BE, 0x84EC, 0xDCEF, 0x84EE, 0xD6A5, 0x84F4, 0xE2F1,
+	0x84FC, 0xD6FE, 0x8511, 0xD9A1, 0x8513, 0xD8C0, 0x8514, 0xDCDB,
+	0x8517, 0xEDBD, 0x8518, 0xDFB8, 0x851A, 0xEAA5, 0x851E, 0xD7AD,
+	0x8521, 0xF3F9, 0x8523, 0xEDF8, 0x8525, 0xF5C7, 0x852C, 0xE1CA,
+	0x852D, 0xEBE3, 0x852F, 0xF2DE, 0x853D, 0xF8CC, 0x853F, 0xEAD9,
+	0x8541, 0xD3C6, 0x8543, 0xDBE6, 0x8549, 0xF5AF, 0x854E, 0xCEF0,
+	0x8553, 0xE9FE, 0x8559, 0xFBB6, 0x8563, 0xE2F2, 0x8568, 0xCFF2,
+	0x8569, 0xF7B9, 0x856A, 0xD9F3, 0x856D, 0xE1CB, 0x8584, 0xDADD,
+	0x8587, 0xDAB9, 0x858F, 0xEBFB, 0x8591, 0xCBB9, 0x8594, 0xEDF9,
+	0x859B, 0xE0E0, 0x85A6, 0xF4C0, 0x85A8, 0xFDBC, 0x85A9, 0xDFB1,
+	0x85AA, 0xE3EF, 0x85AF, 0xE0A3, 0x85B0, 0xFDB9, 0x85BA, 0xF0B1,
+	0x85C1, 0xCDCB, 0x85C9, 0xEDBE, 0x85CD, 0xD5C0, 0x85CE, 0xE3F0,
+	0x85CF, 0xEDFA, 0x85D5, 0xE9E4, 0x85DC, 0xD5ED, 0x85DD, 0xE7DD,
+	0x85E4, 0xD4F6, 0x85E5, 0xE5B7, 0x85E9, 0xDBE7, 0x85EA, 0xE2BF,
+	0x85F7, 0xEECB, 0x85FA, 0xD7F4, 0x85FB, 0xF0DD, 0x85FF, 0xCEAB,
+	0x8602, 0xE7DE, 0x8606, 0xD6D6, 0x8607, 0xE1CC, 0x860A, 0xE8B3,
+	0x8616, 0xE5EE, 0x8617, 0xDCA2, 0x861A, 0xE0D0, 0x862D, 0xD5B5,
+	0x863F, 0xD5A1, 0x864E, 0xFBDB, 0x8650, 0xF9CB, 0x8654, 0xCBF3,
+	0x8655, 0xF4A5, 0x865B, 0xFAC8, 0x865C, 0xD6D7, 0x865E, 0xE9E5,
+	0x865F, 0xFBDC, 0x8667, 0xFDD0, 0x8679, 0xFBF6, 0x868A, 0xDAA5,
+	0x868C, 0xDBBD, 0x8693, 0xECE2, 0x86A3, 0xCDF7, 0x86A4, 0xF0DE,
+	0x86A9, 0xF6C9, 0x86C7, 0xDEEF, 0x86CB, 0xD3B1, 0x86D4, 0xFCEE,
+	0x86D9, 0xE8C3, 0x86DB, 0xF1C8, 0x86DF, 0xCEF1, 0x86E4, 0xF9ED,
+	0x86ED, 0xF2F4, 0x86FE, 0xE4B6, 0x8700, 0xF5B9, 0x8702, 0xDCF0,
+	0x8703, 0xE3F1, 0x8708, 0xE8A5, 0x8718, 0xF2BB, 0x871A, 0xDEA4,
+	0x871C, 0xDACC, 0x874E, 0xCAE9, 0x8755, 0xE3DA, 0x8757, 0xFCD9,
+	0x875F, 0xEADA, 0x8766, 0xF9C4, 0x8768, 0xE3A4, 0x8774, 0xFBDD,
+	0x8776, 0xEFCA, 0x8778, 0xE8C4, 0x8782, 0xD5CC, 0x878D, 0xEBD7,
+	0x879F, 0xD9AD, 0x87A2, 0xFBAB, 0x87B3, 0xD3D9, 0x87BA, 0xD5A2,
+	0x87C4, 0xF6DE, 0x87E0, 0xDAF6, 0x87EC, 0xE0D1, 0x87EF, 0xE9A8,
+	0x87F2, 0xF5F9, 0x87F9, 0xFAAF, 0x87FB, 0xEBFC, 0x87FE, 0xE0EA,
+	0x8805, 0xE3B2, 0x881F, 0xD5C5, 0x8822, 0xF1E3, 0x8823, 0xD5EE,
+	0x8831, 0xCDCC, 0x8836, 0xEDD9, 0x883B, 0xD8C1, 0x8840, 0xFAEC,
+	0x8846, 0xF1EB, 0x884C, 0xFABC, 0x884D, 0xE6E2, 0x8852, 0xFAE5,
+	0x8853, 0xE2FA, 0x8857, 0xCAB6, 0x8859, 0xE4B7, 0x885B, 0xEADB,
+	0x885D, 0xF5FA, 0x8861, 0xFBAC, 0x8862, 0xCFC3, 0x8863, 0xEBFD,
+	0x8868, 0xF8FA, 0x886B, 0xDFB9, 0x8870, 0xE1F1, 0x8872, 0xD2A4,
+	0x8877, 0xF5FB, 0x887E, 0xD0DA, 0x887F, 0xD0DB, 0x8881, 0xEABE,
+	0x8882, 0xD9B1, 0x8888, 0xCAB7, 0x888B, 0xD3E7, 0x888D, 0xF8E5,
+	0x8892, 0xD3B2, 0x8896, 0xE2C0, 0x8897, 0xF2DF, 0x889E, 0xCDE5,
+	0x88AB, 0xF9AC, 0x88B4, 0xCDCD, 0x88C1, 0xEEAE, 0x88C2, 0xD6AE,
+	0x88CF, 0xD7EA, 0x88D4, 0xE7E0, 0x88D5, 0xEBAE, 0x88D9, 0xCFD9,
+	0x88DC, 0xDCCD, 0x88DD, 0xEDFB, 0x88DF, 0xDEF0, 0x88E1, 0xD7EB,
+	0x88E8, 0xDEA5, 0x88F3, 0xDFD7, 0x88F4, 0xDBD0, 0x88F5, 0xDBD1,
+	0x88F8, 0xD5A3, 0x88FD, 0xF0B2, 0x8907, 0xDCDC, 0x8910, 0xCAE8,
+	0x8912, 0xF8E6, 0x8913, 0xDCCE, 0x8918, 0xEADC, 0x8919, 0xDBD2,
+	0x8925, 0xE9B3, 0x892A, 0xF7DB, 0x8936, 0xE3A8, 0x8938, 0xD7AE,
+	0x893B, 0xE0E1, 0x8941, 0xCBBA, 0x8944, 0xE5D1, 0x895F, 0xD0DC,
+	0x8964, 0xD5C1, 0x896A, 0xD8CA, 0x8972, 0xE3A9, 0x897F, 0xE0A4,
+	0x8981, 0xE9A9, 0x8983, 0xD3C7, 0x8986, 0xDCDD, 0x8987, 0xF8AE,
+	0x898B, 0xCCB8, 0x898F, 0xD0AE, 0x8993, 0xD8F2, 0x8996, 0xE3CA,
+	0x89A1, 0xCCAF, 0x89A9, 0xD4AD, 0x89AA, 0xF6D1, 0x89B2, 0xD0CC,
+	0x89BA, 0xCAC6, 0x89BD, 0xD5C2, 0x89C0, 0xCEBA, 0x89D2, 0xCAC7,
+	0x89E3, 0xFAB0, 0x89F4, 0xDFD8, 0x89F8, 0xF5BA, 0x8A00, 0xE5EB,
+	0x8A02, 0xEFF4, 0x8A03, 0xDDB5, 0x8A08, 0xCDAA, 0x8A0A, 0xE3F2,
+	0x8A0C, 0xFBF7, 0x8A0E, 0xF7D0, 0x8A13, 0xFDBA, 0x8A16, 0xFDE1,
+	0x8A17, 0xF6FE, 0x8A18, 0xD1C0, 0x8A1B, 0xE8C5, 0x8A1D, 0xE4B8,
+	0x8A1F, 0xE1E8, 0x8A23, 0xCCC1, 0x8A25, 0xD2ED, 0x8A2A, 0xDBBE,
+	0x8A2D, 0xE0E2, 0x8A31, 0xFAC9, 0x8A34, 0xE1CD, 0x8A36, 0xCAB8,
+	0x8A3A, 0xF2E0, 0x8A3B, 0xF1C9, 0x8A50, 0xDEF1, 0x8A54, 0xF0DF,
+	0x8A55, 0xF8C4, 0x8A5B, 0xEECC, 0x8A5E, 0xDEF2, 0x8A60, 0xE7C9,
+	0x8A62, 0xE2F3, 0x8A63, 0xE7E1, 0x8A66, 0xE3CB, 0x8A69, 0xE3CC,
+	0x8A6D, 0xCFF8, 0x8A6E, 0xEFAC, 0x8A70, 0xFDFE, 0x8A71, 0xFCA5,
+	0x8A72, 0xFAB1, 0x8A73, 0xDFD9, 0x8A75, 0xE0D2, 0x8A79, 0xF4DA,
+	0x8A85, 0xF1CA, 0x8A87, 0xCEA3, 0x8A8C, 0xF2BC, 0x8A8D, 0xECE3,
+	0x8A93, 0xE0A5, 0x8A95, 0xF7AB, 0x8A98, 0xEBAF, 0x8A9E, 0xE5DE,
+	0x8AA0, 0xE1A4, 0x8AA1, 0xCDAB, 0x8AA3, 0xD9F4, 0x8AA4, 0xE8A6,
+	0x8AA5, 0xCDCE, 0x8AA6, 0xE1E9, 0x8AA8, 0xFCEF, 0x8AAA, 0xE0E3,
+	0x8AB0, 0xE2C1, 0x8AB2, 0xCEA4, 0x8AB9, 0xDEA6, 0x8ABC, 0xEBFE,
+	0x8ABE, 0xEBDD, 0x8ABF, 0xF0E0, 0x8AC2, 0xF4DB, 0x8AC4, 0xE2F4,
+	0x8AC7, 0xD3C8, 0x8ACB, 0xF4EB, 0x8ACD, 0xEEB5, 0x8ACF, 0xF5D8,
+	0x8AD2, 0xD5DF, 0x8AD6, 0xD6E5, 0x8ADB, 0xEBB0, 0x8ADC, 0xF4E3,
+	0x8AE1, 0xE3CD, 0x8AE6, 0xF4F4, 0x8AE7, 0xFAB2, 0x8AEA, 0xEFF5,
+	0x8AEB, 0xCADF, 0x8AED, 0xEBB1, 0x8AEE, 0xEDBF, 0x8AF1, 0xFDC9,
+	0x8AF6, 0xE4A6, 0x8AF7, 0xF9A4, 0x8AF8, 0xF0B3, 0x8AFA, 0xE5EC,
+	0x8AFE, 0xD1E7, 0x8B00, 0xD9C7, 0x8B01, 0xE4D7, 0x8B02, 0xEADD,
+	0x8B04, 0xD4F7, 0x8B0E, 0xDABA, 0x8B10, 0xDACD, 0x8B14, 0xF9CC,
+	0x8B16, 0xE1DA, 0x8B17, 0xDBBF, 0x8B19, 0xCCC5, 0x8B1A, 0xECD0,
+	0x8B1B, 0xCBBB, 0x8B1D, 0xDEF3, 0x8B20, 0xE9AA, 0x8B28, 0xD9C8,
+	0x8B2B, 0xEEE3, 0x8B2C, 0xD7BD, 0x8B33, 0xCFC4, 0x8B39, 0xD0CD,
+	0x8B41, 0xFCA6, 0x8B49, 0xF1FB, 0x8B4E, 0xFDD2, 0x8B4F, 0xD1C1,
+	0x8B58, 0xE3DB, 0x8B5A, 0xD3C9, 0x8B5C, 0xDCCF, 0x8B66, 0xCCED,
+	0x8B6C, 0xDEA7, 0x8B6F, 0xE6BB, 0x8B70, 0xECA1, 0x8B74, 0xCCB9,
+	0x8B77, 0xFBDE, 0x8B7D, 0xE7E2, 0x8B80, 0xD4C1, 0x8B8A, 0xDCA8,
+	0x8B90, 0xE2C2, 0x8B92, 0xF3D8, 0x8B93, 0xE5D3, 0x8B96, 0xF3D9,
+	0x8B9A, 0xF3C6, 0x8C37, 0xCDDB, 0x8C3F, 0xCDAC, 0x8C41, 0xFCC3,
+	0x8C46, 0xD4E7, 0x8C48, 0xD1C2, 0x8C4A, 0xF9A5, 0x8C4C, 0xE8D5,
+	0x8C55, 0xE3CE, 0x8C5A, 0xD4CA, 0x8C61, 0xDFDA, 0x8C6A, 0xFBDF,
+	0x8C6B, 0xE7E3, 0x8C79, 0xF8FB, 0x8C7A, 0xE3CF, 0x8C82, 0xF5B0,
+	0x8C8A, 0xD8E7, 0x8C8C, 0xD9C9, 0x8C9D, 0xF8AF, 0x8C9E, 0xEFF6,
+	0x8CA0, 0xDDB6, 0x8CA1, 0xEEAF, 0x8CA2, 0xCDF8, 0x8CA7, 0xDEB8,
+	0x8CA8, 0xFCA7, 0x8CA9, 0xF7FC, 0x8CAA, 0xF7B1, 0x8CAB, 0xCEBB,
+	0x8CAC, 0xF4A1, 0x8CAF, 0xEECD, 0x8CB0, 0xE1AE, 0x8CB3, 0xECC3,
+	0x8CB4, 0xCFFE, 0x8CB6, 0xF8BF, 0x8CB7, 0xD8E2, 0x8CB8, 0xD3E8,
+	0x8CBB, 0xDEA8, 0x8CBC, 0xF4E4, 0x8CBD, 0xECC2, 0x8CBF, 0xD9F5,
+	0x8CC0, 0xF9C5, 0x8CC1, 0xDDD3, 0x8CC2, 0xD6F1, 0x8CC3, 0xECFC,
+	0x8CC4, 0xFCF0, 0x8CC7, 0xEDC0, 0x8CC8, 0xCAB9, 0x8CCA, 0xEEE4,
+	0x8CD1, 0xF2E1, 0x8CD3, 0xDEB9, 0x8CDA, 0xD6F2, 0x8CDC, 0xDEF4,
+	0x8CDE, 0xDFDB, 0x8CE0, 0xDBD3, 0x8CE2, 0xFAE7, 0x8CE3, 0xD8E3,
+	0x8CE4, 0xF4C1, 0x8CE6, 0xDDB7, 0x8CEA, 0xF2F5, 0x8CED, 0xD4AE,
+	0x8CF4, 0xD6F3, 0x8CFB, 0xDDB8, 0x8CFC, 0xCFC5, 0x8CFD, 0xDFDF,
+	0x8D04, 0xF2BE, 0x8D05, 0xF6A1, 0x8D07, 0xEBCB, 0x8D08, 0xF1FC,
+	0x8D0A, 0xF3C7, 0x8D0D, 0xE0EB, 0x8D13, 0xEDFC, 0x8D16, 0xE1DB,
+	0x8D64, 0xEEE5, 0x8D66, 0xDEF5, 0x8D6B, 0xFAD3, 0x8D70, 0xF1CB,
+	0x8D73, 0xD0AF, 0x8D74, 0xDDB9, 0x8D77, 0xD1C3, 0x8D85, 0xF5B1,
+	0x8D8A, 0xEAC6, 0x8D99, 0xF0E1, 0x8DA3, 0xF6AC, 0x8DA8, 0xF5D9,
+	0x8DB3, 0xF0EB, 0x8DBA, 0xDDBA, 0x8DBE, 0xF2BF, 0x8DC6, 0xF7C5,
+	0x8DCB, 0xDBA2, 0x8DCC, 0xF2F6, 0x8DCF, 0xCABA, 0x8DDB, 0xF7F5,
+	0x8DDD, 0xCBE5, 0x8DE1, 0xEEE6, 0x8DE3, 0xE0D3, 0x8DE8, 0xCEA5,
+	0x8DEF, 0xD6D8, 0x8DF3, 0xD4AF, 0x8E0A, 0xE9C9, 0x8E0F, 0xD3CE,
+	0x8E10, 0xF4C2, 0x8E1E, 0xCBE6, 0x8E2A, 0xF1A1, 0x8E30, 0xEBB2,
+	0x8E35, 0xF1A2, 0x8E42, 0xEBB3, 0x8E44, 0xF0B4, 0x8E47, 0xCBF4,
+	0x8E48, 0xD4B0, 0x8E49, 0xF3B2, 0x8E4A, 0xFBB7, 0x8E59, 0xF5EC,
+	0x8E5F, 0xEEE7, 0x8E60, 0xF4B2, 0x8E74, 0xF5ED, 0x8E76, 0xCFF3,
+	0x8E81, 0xF0E2, 0x8E87, 0xEECE, 0x8E8A, 0xF1CC, 0x8E8D, 0xE5B8,
+	0x8EAA, 0xD7F5, 0x8EAB, 0xE3F3, 0x8EAC, 0xCFE5, 0x8EC0, 0xCFC6,
+	0x8ECA, 0xF3B3, 0x8ECB, 0xE4D8, 0x8ECC, 0xCFF9, 0x8ECD, 0xCFDA,
+	0x8ED2, 0xFACD, 0x8EDF, 0xE6E3, 0x8EEB, 0xF2E2, 0x8EF8, 0xF5EE,
+	0x8EFB, 0xCABB, 0x8EFE, 0xE3DC, 0x8F03, 0xCEF2, 0x8F05, 0xD6D9,
+	0x8F09, 0xEEB0, 0x8F12, 0xF4E5, 0x8F13, 0xD8C2, 0x8F14, 0xDCD0,
+	0x8F15, 0xCCEE, 0x8F1B, 0xD5E0, 0x8F1C, 0xF6CA, 0x8F1D, 0xFDCA,
+	0x8F1E, 0xD8D6, 0x8F1F, 0xF4CF, 0x8F26, 0xD6A6, 0x8F27, 0xDCBE,
+	0x8F29, 0xDBD4, 0x8F2A, 0xD7C7, 0x8F2F, 0xF2FE, 0x8F33, 0xF1CD,
+	0x8F38, 0xE2C3, 0x8F39, 0xDCDE, 0x8F3B, 0xDCDF, 0x8F3E, 0xEFAD,
+	0x8F3F, 0xE6AB, 0x8F44, 0xF9DD, 0x8F45, 0xEABF, 0x8F49, 0xEFAE,
+	0x8F4D, 0xF4D0, 0x8F4E, 0xCEF3, 0x8F5D, 0xE6AC, 0x8F5F, 0xCEDE,
+	0x8F62, 0xD5F9, 0x8F9B, 0xE3F4, 0x8F9C, 0xCDD0, 0x8FA3, 0xD5B8,
+	0x8FA6, 0xF7FD, 0x8FA8, 0xDCA9, 0x8FAD, 0xDEF6, 0x8FAF, 0xDCAA,
+	0x8FB0, 0xF2E3, 0x8FB1, 0xE9B4, 0x8FB2, 0xD2DC, 0x8FC2, 0xE9E6,
+	0x8FC5, 0xE3F6, 0x8FCE, 0xE7CA, 0x8FD1, 0xD0CE, 0x8FD4, 0xDAF7,
+	0x8FE6, 0xCABC, 0x8FEA, 0xEEE8, 0x8FEB, 0xDADE, 0x8FED, 0xF2F7,
+	0x8FF0, 0xE2FB, 0x8FF2, 0xCCA6, 0x8FF7, 0xDABB, 0x8FF9, 0xEEE9,
+	0x8FFD, 0xF5DA, 0x9000, 0xF7DC, 0x9001, 0xE1EA, 0x9002, 0xCEC1,
+	0x9003, 0xD4B1, 0x9005, 0xFDB1, 0x9006, 0xE6BD, 0x9008, 0xFBAD,
+	0x900B, 0xF8E7, 0x900D, 0xE1CE, 0x900F, 0xF7E2, 0x9010, 0xF5EF,
+	0x9011, 0xCFC7, 0x9014, 0xD4B2, 0x9015, 0xCCEF, 0x9017, 0xD4E8,
+	0x9019, 0xEECF, 0x901A, 0xF7D7, 0x901D, 0xE0A6, 0x901E, 0xD6C1,
+	0x901F, 0xE1DC, 0x9020, 0xF0E3, 0x9021, 0xF1E4, 0x9022, 0xDCF1,
+	0x9023, 0xD6A7, 0x902E, 0xF4F5, 0x9031, 0xF1CE, 0x9032, 0xF2E4,
+	0x9035, 0xD0B0, 0x9038, 0xECEF, 0x903C, 0xF9BA, 0x903E, 0xEBB5,
+	0x9041, 0xD4ED, 0x9042, 0xE2C4, 0x9047, 0xE9E7, 0x904A, 0xEBB4,
+	0x904B, 0xEAA1, 0x904D, 0xF8BC, 0x904E, 0xCEA6, 0x9050, 0xF9C6,
+	0x9051, 0xFCDA, 0x9053, 0xD4B3, 0x9054, 0xD3B9, 0x9055, 0xEADE,
+	0x9059, 0xE9AB, 0x905C, 0xE1E1, 0x905D, 0xD3CF, 0x905E, 0xF4F6,
+	0x9060, 0xEAC0, 0x9061, 0xE1CF, 0x9063, 0xCCBA, 0x9069, 0xEEEA,
+	0x906D, 0xF0E4, 0x906E, 0xF3B4, 0x906F, 0xD4EE, 0x9072, 0xF2C0,
+	0x9075, 0xF1E5, 0x9077, 0xF4C3, 0x9078, 0xE0D4, 0x907A, 0xEBB6,
+	0x907C, 0xD7A1, 0x907D, 0xCBE8, 0x907F, 0xF9AD, 0x9080, 0xE9AD,
+	0x9081, 0xD8E4, 0x9082, 0xFAB3, 0x9083, 0xE2C5, 0x9084, 0xFCBD,
+	0x9087, 0xECC4, 0x9088, 0xD8B1, 0x908A, 0xDCAB, 0x908F, 0xD5A4,
+	0x9091, 0xEBE9, 0x9095, 0xE8BB, 0x9099, 0xD8D7, 0x90A2, 0xFBAE,
+	0x90A3, 0xD1E1, 0x90A6, 0xDBC0, 0x90A8, 0xF5BE, 0x90AA, 0xDEF7,
+	0x90AF, 0xCAFB, 0x90B0, 0xF7C6, 0x90B1, 0xCFC8, 0x90B5, 0xE1D0,
+	0x90B8, 0xEED0, 0x90C1, 0xE9F4, 0x90CA, 0xCEF4, 0x90DE, 0xD5CD,
+	0x90E1, 0xCFDB, 0x90E8, 0xDDBB, 0x90ED, 0xCEAC, 0x90F5, 0xE9E8,
+	0x90FD, 0xD4B4, 0x9102, 0xE4C7, 0x9112, 0xF5DB, 0x9115, 0xFAC1,
+	0x9119, 0xDEA9, 0x9127, 0xD4F8, 0x912D, 0xEFF7, 0x9132, 0xD3B3,
+	0x9149, 0xEBB7, 0x914A, 0xEFF8, 0x914B, 0xF5DC, 0x914C, 0xEDCC,
+	0x914D, 0xDBD5, 0x914E, 0xF1CF, 0x9152, 0xF1D0, 0x9162, 0xF5B2,
+	0x9169, 0xD9AE, 0x916A, 0xD5AC, 0x916C, 0xE2C6, 0x9175, 0xFDA3,
+	0x9177, 0xFBE5, 0x9178, 0xDFAB, 0x9187, 0xE2F5, 0x9189, 0xF6AD,
+	0x918B, 0xF5B3, 0x918D, 0xF0B5, 0x9192, 0xE1A5, 0x919C, 0xF5DD,
+	0x91AB, 0xECA2, 0x91AC, 0xEDFD, 0x91AE, 0xF5B4, 0x91AF, 0xFBB8,
+	0x91B1, 0xDBA3, 0x91B4, 0xD6CA, 0x91B5, 0xCBD9, 0x91C0, 0xE5D4,
+	0x91C7, 0xF3FA, 0x91C9, 0xEBB8, 0x91CB, 0xE0B7, 0x91CC, 0xD7EC,
+	0x91CD, 0xF1EC, 0x91CE, 0xE5AF, 0x91CF, 0xD5E1, 0x91D0, 0xD7ED,
+	0x91D1, 0xD1D1, 0x91D7, 0xE1F2, 0x91D8, 0xEFF9, 0x91DC, 0xDDBC,
+	0x91DD, 0xF6DC, 0x91E3, 0xF0E5, 0x91E7, 0xF4C4, 0x91EA, 0xE9E9,
+	0x91F5, 0xF3FB, 0x920D, 0xD4EF, 0x9210, 0xCCA2, 0x9211, 0xF7FE,
+	0x9212, 0xDFBC, 0x9217, 0xEBCD, 0x921E, 0xD0B7, 0x9234, 0xD6C2,
+	0x923A, 0xE8AD, 0x923F, 0xEFAF, 0x9240, 0xCBA5, 0x9245, 0xCBE9,
+	0x9249, 0xFAE8, 0x9257, 0xCCC6, 0x925B, 0xE6E7, 0x925E, 0xEAC7,
+	0x9262, 0xDBA4, 0x9264, 0xCFC9, 0x9265, 0xE2FC, 0x9266, 0xEFFA,
+	0x9280, 0xEBDE, 0x9283, 0xF5C8, 0x9285, 0xD4DE, 0x9291, 0xE0D5,
+	0x9293, 0xEFB0, 0x9296, 0xE2C7, 0x9298, 0xD9AF, 0x929C, 0xF9E7,
+	0x92B3, 0xE7E5, 0x92B6, 0xCFCA, 0x92B7, 0xE1D1, 0x92B9, 0xE2C8,
+	0x92CC, 0xEFFB, 0x92CF, 0xFAF9, 0x92D2, 0xDCF2, 0x92E4, 0xE0A7,
+	0x92EA, 0xF8E8, 0x92F8, 0xCBEA, 0x92FC, 0xCBBC, 0x9304, 0xD6E2,
+	0x9310, 0xF5DE, 0x9318, 0xF5DF, 0x931A, 0xEEB6, 0x931E, 0xE2F6,
+	0x931F, 0xD3CA, 0x9320, 0xEFFC, 0x9321, 0xD1C4, 0x9322, 0xEFB1,
+	0x9324, 0xD1C5, 0x9326, 0xD0DE, 0x9328, 0xD9E1, 0x932B, 0xE0B8,
+	0x932E, 0xCDD1, 0x932F, 0xF3B9, 0x9348, 0xE7CC, 0x934A, 0xD6A8,
+	0x934B, 0xCEA7, 0x934D, 0xD4B5, 0x9354, 0xE4C8, 0x935B, 0xD3B4,
+	0x936E, 0xEBB9, 0x9375, 0xCBF5, 0x937C, 0xF6DD, 0x937E, 0xF1A3,
+	0x938C, 0xCCC7, 0x9394, 0xE9CA, 0x9396, 0xE1F0, 0x939A, 0xF5E0,
+	0x93A3, 0xFBAF, 0x93A7, 0xCBD1, 0x93AC, 0xFBE0, 0x93AD, 0xF2E5,
+	0x93B0, 0xECF0, 0x93C3, 0xF0EC, 0x93D1, 0xEEEB, 0x93DE, 0xE9CB,
+	0x93E1, 0xCCF0, 0x93E4, 0xD7AF, 0x93F6, 0xF3A1, 0x9404, 0xFCF5,
+	0x9418, 0xF1A4, 0x9425, 0xE0D6, 0x942B, 0xEFB2, 0x9435, 0xF4D1,
+	0x9438, 0xF7A1, 0x9444, 0xF1D1, 0x9451, 0xCAFC, 0x9452, 0xCAFD,
+	0x945B, 0xCECE, 0x947D, 0xF3C8, 0x947F, 0xF3BA, 0x9577, 0xEDFE,
+	0x9580, 0xDAA6, 0x9583, 0xE0EC, 0x9589, 0xF8CD, 0x958B, 0xCBD2,
+	0x958F, 0xEBCE, 0x9591, 0xF9D8, 0x9592, 0xF9D9, 0x9593, 0xCAE0,
+	0x9594, 0xDACA, 0x9598, 0xCBA6, 0x95A3, 0xCAC8, 0x95A4, 0xF9EE,
+	0x95A5, 0xDBEC, 0x95A8, 0xD0B1, 0x95AD, 0xD5EF, 0x95B1, 0xE6F3,
+	0x95BB, 0xE7A2, 0x95BC, 0xE4D9, 0x95C7, 0xE4E1, 0x95CA, 0xFCC4,
+	0x95D4, 0xF9EF, 0x95D5, 0xCFF4, 0x95D6, 0xF7E6, 0x95DC, 0xCEBC,
+	0x95E1, 0xF4C5, 0x95E2, 0xDCA3, 0x961C, 0xDDBD, 0x9621, 0xF4C6,
+	0x962A, 0xF8A1, 0x962E, 0xE8D6, 0x9632, 0xDBC1, 0x963B, 0xF0E6,
+	0x963F, 0xE4B9, 0x9640, 0xF6ED, 0x9642, 0xF9AE, 0x9644, 0xDDBE,
+	0x964B, 0xD7B0, 0x964C, 0xD8E8, 0x964D, 0xCBBD, 0x9650, 0xF9DA,
+	0x965B, 0xF8CE, 0x965C, 0xF9F0, 0x965D, 0xE0ED, 0x965E, 0xE3B3,
+	0x965F, 0xF4B3, 0x9662, 0xEAC2, 0x9663, 0xF2E6, 0x9664, 0xF0B6,
+	0x966A, 0xDBD6, 0x9670, 0xEBE4, 0x9673, 0xF2E7, 0x9675, 0xD7D5,
+	0x9676, 0xD4B6, 0x9677, 0xF9E8, 0x9678, 0xD7C1, 0x967D, 0xE5D5,
+	0x9685, 0xE9EA, 0x9686, 0xD7CC, 0x968A, 0xD3E9, 0x968B, 0xE2C9,
+	0x968D, 0xFCDB, 0x968E, 0xCDAD, 0x9694, 0xCCB0, 0x9695, 0xEAA2,
+	0x9698, 0xE4F6, 0x9699, 0xD0C0, 0x969B, 0xF0B7, 0x969C, 0xEEA1,
+	0x96A3, 0xD7F6, 0x96A7, 0xE2CA, 0x96A8, 0xE2CB, 0x96AA, 0xFACF,
+	0x96B1, 0xEBDF, 0x96B7, 0xD6CB, 0x96BB, 0xF4B4, 0x96C0, 0xEDCD,
+	0x96C1, 0xE4D2, 0x96C4, 0xEAA9, 0x96C5, 0xE4BA, 0x96C6, 0xF3A2,
+	0x96C7, 0xCDD2, 0x96C9, 0xF6CB, 0x96CB, 0xF1E6, 0x96CC, 0xEDC1,
+	0x96CD, 0xE8BC, 0x96CE, 0xEED1, 0x96D5, 0xF0E7, 0x96D6, 0xE2CC,
+	0x96D9, 0xE4AA, 0x96DB, 0xF5E1, 0x96DC, 0xEDDA, 0x96E2, 0xD7EE,
+	0x96E3, 0xD1F1, 0x96E8, 0xE9EB, 0x96E9, 0xE9EC, 0x96EA, 0xE0E4,
+	0x96EF, 0xDAA7, 0x96F0, 0xDDD4, 0x96F2, 0xEAA3, 0x96F6, 0xD6C3,
+	0x96F7, 0xD6F4, 0x96F9, 0xDADF, 0x96FB, 0xEFB3, 0x9700, 0xE2CD,
+	0x9706, 0xEFFD, 0x9707, 0xF2E8, 0x9711, 0xEFC5, 0x9713, 0xE7E7,
+	0x9716, 0xD7FD, 0x9719, 0xE7CE, 0x971C, 0xDFDC, 0x971E, 0xF9C7,
+	0x9727, 0xD9F6, 0x9730, 0xDFAC, 0x9732, 0xD6DA, 0x9739, 0xDCA4,
+	0x973D, 0xF0B8, 0x9742, 0xD5FA, 0x9744, 0xE4F7, 0x9748, 0xD6C4,
+	0x9751, 0xF4EC, 0x9756, 0xEFFE, 0x975C, 0xF0A1, 0x975E, 0xDEAA,
+	0x9761, 0xDABC, 0x9762, 0xD8FC, 0x9769, 0xFAD4, 0x976D, 0xECE5,
+	0x9774, 0xFCA8, 0x9777, 0xECE6, 0x977A, 0xD8CB, 0x978B, 0xFBB9,
+	0x978D, 0xE4D3, 0x978F, 0xCDF9, 0x97A0, 0xCFD3, 0x97A8, 0xCAEA,
+	0x97AB, 0xCFD4, 0x97AD, 0xF8BD, 0x97C6, 0xF4C7, 0x97CB, 0xEADF,
+	0x97D3, 0xF9DB, 0x97DC, 0xD4B7, 0x97F3, 0xEBE5, 0x97F6, 0xE1D2,
+	0x97FB, 0xEAA4, 0x97FF, 0xFAC2, 0x9800, 0xFBE1, 0x9801, 0xFAED,
+	0x9802, 0xF0A2, 0x9803, 0xCCF1, 0x9805, 0xFAA3, 0x9806, 0xE2F7,
+	0x9808, 0xE2CE, 0x980A, 0xE9F5, 0x980C, 0xE1EB, 0x9810, 0xE7E8,
+	0x9811, 0xE8D7, 0x9812, 0xDAF8, 0x9813, 0xD4CB, 0x9817, 0xF7F6,
+	0x9818, 0xD6C5, 0x982D, 0xD4E9, 0x9830, 0xFAFA, 0x9838, 0xCCF2,
+	0x9839, 0xF7DD, 0x983B, 0xDEBA, 0x9846, 0xCEA8, 0x984C, 0xF0B9,
+	0x984D, 0xE4FE, 0x984E, 0xE4C9, 0x9854, 0xE4D4, 0x9858, 0xEAC3,
+	0x985A, 0xEFB4, 0x985E, 0xD7BE, 0x9865, 0xFBE2, 0x9867, 0xCDD3,
+	0x986B, 0xEFB5, 0x986F, 0xFAE9, 0x98A8, 0xF9A6, 0x98AF, 0xDFBD,
+	0x98B1, 0xF7C7, 0x98C4, 0xF8FD, 0x98C7, 0xF8FC, 0x98DB, 0xDEAB,
+	0x98DC, 0xDBE8, 0x98DF, 0xE3DD, 0x98E1, 0xE1E2, 0x98E2, 0xD1C6,
+	0x98ED, 0xF6D0, 0x98EE, 0xEBE6, 0x98EF, 0xDAF9, 0x98F4, 0xECC7,
+	0x98FC, 0xDEF8, 0x98FD, 0xF8E9, 0x98FE, 0xE3DE, 0x9903, 0xCEF5,
+	0x9909, 0xFAC3, 0x990A, 0xE5D7, 0x990C, 0xECC8, 0x9910, 0xF3C9,
+	0x9913, 0xE4BB, 0x9918, 0xE6AE, 0x991E, 0xEFB6, 0x9920, 0xDCBF,
+	0x9928, 0xCEBD, 0x9945, 0xD8C3, 0x9949, 0xD0CF, 0x994B, 0xCFFA,
+	0x994C, 0xF3CA, 0x994D, 0xE0D7, 0x9951, 0xD1C7, 0x9952, 0xE9AE,
+	0x9954, 0xE8BD, 0x9957, 0xFAC4, 0x9996, 0xE2CF, 0x9999, 0xFAC5,
+	0x999D, 0xF9B8, 0x99A5, 0xDCE0, 0x99A8, 0xFBB0, 0x99AC, 0xD8A9,
+	0x99AD, 0xE5DF, 0x99AE, 0xF9A7, 0x99B1, 0xF6EE, 0x99B3, 0xF6CC,
+	0x99B4, 0xE2F8, 0x99B9, 0xECF1, 0x99C1, 0xDAE0, 0x99D0, 0xF1D2,
+	0x99D1, 0xD2CC, 0x99D2, 0xCFCB, 0x99D5, 0xCABD, 0x99D9, 0xDDBF,
+	0x99DD, 0xF6EF, 0x99DF, 0xDEF9, 0x99ED, 0xFAB4, 0x99F1, 0xD5AD,
+	0x99FF, 0xF1E7, 0x9A01, 0xDEBE, 0x9A08, 0xDCC0, 0x9A0E, 0xD1C8,
+	0x9A0F, 0xD1C9, 0x9A19, 0xF8BE, 0x9A2B, 0xCBF6, 0x9A30, 0xD4F9,
+	0x9A36, 0xF5E2, 0x9A37, 0xE1D3, 0x9A40, 0xD8E9, 0x9A43, 0xF8FE,
+	0x9A45, 0xCFCC, 0x9A4D, 0xFDA4, 0x9A55, 0xCEF6, 0x9A57, 0xFAD0,
+	0x9A5A, 0xCCF3, 0x9A5B, 0xE6BE, 0x9A5F, 0xF6AE, 0x9A62, 0xD5F0,
+	0x9A65, 0xD1CA, 0x9A69, 0xFCBE, 0x9A6A, 0xD5F1, 0x9AA8, 0xCDE9,
+	0x9AB8, 0xFAB5, 0x9AD3, 0xE2D0, 0x9AD4, 0xF4F7, 0x9AD8, 0xCDD4,
+	0x9AE5, 0xE7A3, 0x9AEE, 0xDBA5, 0x9B1A, 0xE2D1, 0x9B27, 0xD7A2,
+	0x9B2A, 0xF7E3, 0x9B31, 0xEAA6, 0x9B3C, 0xD0A1, 0x9B41, 0xCEDA,
+	0x9B42, 0xFBEB, 0x9B43, 0xDBA6, 0x9B44, 0xDBDE, 0x9B45, 0xD8E5,
+	0x9B4F, 0xEAE0, 0x9B54, 0xD8AA, 0x9B5A, 0xE5E0, 0x9B6F, 0xD6DB,
+	0x9B8E, 0xEFC6, 0x9B91, 0xF8EA, 0x9B9F, 0xE4D5, 0x9BAB, 0xCEF7,
+	0x9BAE, 0xE0D8, 0x9BC9, 0xD7EF, 0x9BD6, 0xF4ED, 0x9BE4, 0xCDE6,
+	0x9BE8, 0xCCF4, 0x9C0D, 0xF5E3, 0x9C10, 0xE4CA, 0x9C12, 0xDCE1,
+	0x9C15, 0xF9C8, 0x9C25, 0xFCBF, 0x9C32, 0xE8A7, 0x9C3B, 0xD8C4,
+	0x9C47, 0xCBBE, 0x9C49, 0xDCAE, 0x9C57, 0xD7F7, 0x9CE5, 0xF0E8,
+	0x9CE7, 0xDDC0, 0x9CE9, 0xCFCD, 0x9CF3, 0xDCF3, 0x9CF4, 0xD9B0,
+	0x9CF6, 0xE6E9, 0x9D09, 0xE4BC, 0x9D1B, 0xEAC4, 0x9D26, 0xE4EC,
+	0x9D28, 0xE4E5, 0x9D3B, 0xFBF8, 0x9D51, 0xCCBB, 0x9D5D, 0xE4BD,
+	0x9D60, 0xCDDC, 0x9D61, 0xD9F7, 0x9D6C, 0xDDDF, 0x9D72, 0xEDCE,
+	0x9DA9, 0xD9D0, 0x9DAF, 0xE5A3, 0x9DB4, 0xF9CD, 0x9DC4, 0xCDAE,
+	0x9DD7, 0xCFCE, 0x9DF2, 0xF6AF, 0x9DF8, 0xFDD3, 0x9DF9, 0xEBED,
+	0x9DFA, 0xD6DC, 0x9E1A, 0xE5A4, 0x9E1E, 0xD5B6, 0x9E75, 0xD6DD,
+	0x9E79, 0xF9E9, 0x9E7D, 0xE7A4, 0x9E7F, 0xD6E3, 0x9E92, 0xD1CB,
+	0x9E93, 0xD6E4, 0x9E97, 0xD5F2, 0x9E9D, 0xDEFA, 0x9E9F, 0xD7F8,
+	0x9EA5, 0xD8EA, 0x9EB4, 0xCFD5, 0x9EB5, 0xD8FD, 0x9EBB, 0xD8AB,
+	0x9EBE, 0xFDCB, 0x9EC3, 0xFCDC, 0x9ECD, 0xE0A8, 0x9ECE, 0xD5F3,
+	0x9ED1, 0xFDD9, 0x9ED4, 0xCCA3, 0x9ED8, 0xD9F9, 0x9EDB, 0xD3EA,
+	0x9EDC, 0xF5F5, 0x9EDE, 0xEFC7, 0x9EE8, 0xD3DA, 0x9EF4, 0xDABD,
+	0x9F07, 0xE8A8, 0x9F08, 0xDCAF, 0x9F0E, 0xF0A3, 0x9F13, 0xCDD5,
+	0x9F20, 0xE0A9, 0x9F3B, 0xDEAC, 0x9F4A, 0xF0BA, 0x9F4B, 0xEEB1,
+	0x9F4E, 0xEEB2, 0x9F52, 0xF6CD, 0x9F5F, 0xEED2, 0x9F61, 0xD6C6,
+	0x9F67, 0xE0E5, 0x9F6A, 0xF3BB, 0x9F6C, 0xE5E1, 0x9F77, 0xE4CB,
+	0x9F8D, 0xD7A3, 0x9F90, 0xDBC2, 0x9F95, 0xCAFE, 0x9F9C, 0xCFCF,
+	0xAC00, 0xB0A1, 0xAC01, 0xB0A2, 0xAC02, 0x8141, 0xAC03, 0x8142,
+	0xAC04, 0xB0A3, 0xAC05, 0x8143, 0xAC06, 0x8144, 0xAC07, 0xB0A4,
+	0xAC08, 0xB0A5, 0xAC09, 0xB0A6, 0xAC0A, 0xB0A7, 0xAC0B, 0x8145,
+	0xAC0C, 0x8146, 0xAC0D, 0x8147, 0xAC0E, 0x8148, 0xAC0F, 0x8149,
+	0xAC10, 0xB0A8, 0xAC11, 0xB0A9, 0xAC12, 0xB0AA, 0xAC13, 0xB0AB,
+	0xAC14, 0xB0AC, 0xAC15, 0xB0AD, 0xAC16, 0xB0AE, 0xAC17, 0xB0AF,
+	0xAC18, 0x814A, 0xAC19, 0xB0B0, 0xAC1A, 0xB0B1, 0xAC1B, 0xB0B2,
+	0xAC1C, 0xB0B3, 0xAC1D, 0xB0B4, 0xAC1E, 0x814B, 0xAC1F, 0x814C,
+	0xAC20, 0xB0B5, 0xAC21, 0x814D, 0xAC22, 0x814E, 0xAC23, 0x814F,
+	0xAC24, 0xB0B6, 0xAC25, 0x8150, 0xAC26, 0x8151, 0xAC27, 0x8152,
+	0xAC28, 0x8153, 0xAC29, 0x8154, 0xAC2A, 0x8155, 0xAC2B, 0x8156,
+	0xAC2C, 0xB0B7, 0xAC2D, 0xB0B8, 0xAC2E, 0x8157, 0xAC2F, 0xB0B9,
+	0xAC30, 0xB0BA, 0xAC31, 0xB0BB, 0xAC32, 0x8158, 0xAC33, 0x8159,
+	0xAC34, 0x815A, 0xAC35, 0x8161, 0xAC36, 0x8162, 0xAC37, 0x8163,
+	0xAC38, 0xB0BC, 0xAC39, 0xB0BD, 0xAC3A, 0x8164, 0xAC3B, 0x8165,
+	0xAC3C, 0xB0BE, 0xAC3D, 0x8166, 0xAC3E, 0x8167, 0xAC3F, 0x8168,
+	0xAC40, 0xB0BF, 0xAC41, 0x8169, 0xAC42, 0x816A, 0xAC43, 0x816B,
+	0xAC44, 0x816C, 0xAC45, 0x816D, 0xAC46, 0x816E, 0xAC47, 0x816F,
+	0xAC48, 0x8170, 0xAC49, 0x8171, 0xAC4A, 0x8172, 0xAC4B, 0xB0C0,
+	0xAC4C, 0x8173, 0xAC4D, 0xB0C1, 0xAC4E, 0x8174, 0xAC4F, 0x8175,
+	0xAC50, 0x8176, 0xAC51, 0x8177, 0xAC52, 0x8178, 0xAC53, 0x8179,
+	0xAC54, 0xB0C2, 0xAC55, 0x817A, 0xAC56, 0x8181, 0xAC57, 0x8182,
+	0xAC58, 0xB0C3, 0xAC59, 0x8183, 0xAC5A, 0x8184, 0xAC5B, 0x8185,
+	0xAC5C, 0xB0C4, 0xAC5D, 0x8186, 0xAC5E, 0x8187, 0xAC5F, 0x8188,
+	0xAC60, 0x8189, 0xAC61, 0x818A, 0xAC62, 0x818B, 0xAC63, 0x818C,
+	0xAC64, 0x818D, 0xAC65, 0x818E, 0xAC66, 0x818F, 0xAC67, 0x8190,
+	0xAC68, 0x8191, 0xAC69, 0x8192, 0xAC6A, 0x8193, 0xAC6B, 0x8194,
+	0xAC6C, 0x8195, 0xAC6D, 0x8196, 0xAC6E, 0x8197, 0xAC6F, 0x8198,
+	0xAC70, 0xB0C5, 0xAC71, 0xB0C6, 0xAC72, 0x8199, 0xAC73, 0x819A,
+	0xAC74, 0xB0C7, 0xAC75, 0x819B, 0xAC76, 0x819C, 0xAC77, 0xB0C8,
+	0xAC78, 0xB0C9, 0xAC79, 0x819D, 0xAC7A, 0xB0CA, 0xAC7B, 0x819E,
+	0xAC7C, 0x819F, 0xAC7D, 0x81A0, 0xAC7E, 0x81A1, 0xAC7F, 0x81A2,
+	0xAC80, 0xB0CB, 0xAC81, 0xB0CC, 0xAC82, 0x81A3, 0xAC83, 0xB0CD,
+	0xAC84, 0xB0CE, 0xAC85, 0xB0CF, 0xAC86, 0xB0D0, 0xAC87, 0x81A4,
+	0xAC88, 0x81A5, 0xAC89, 0xB0D1, 0xAC8A, 0xB0D2, 0xAC8B, 0xB0D3,
+	0xAC8C, 0xB0D4, 0xAC8D, 0x81A6, 0xAC8E, 0x81A7, 0xAC8F, 0x81A8,
+	0xAC90, 0xB0D5, 0xAC91, 0x81A9, 0xAC92, 0x81AA, 0xAC93, 0x81AB,
+	0xAC94, 0xB0D6, 0xAC95, 0x81AC, 0xAC96, 0x81AD, 0xAC97, 0x81AE,
+	0xAC98, 0x81AF, 0xAC99, 0x81B0, 0xAC9A, 0x81B1, 0xAC9B, 0x81B2,
+	0xAC9C, 0xB0D7, 0xAC9D, 0xB0D8, 0xAC9E, 0x81B3, 0xAC9F, 0xB0D9,
+	0xACA0, 0xB0DA, 0xACA1, 0xB0DB, 0xACA2, 0x81B4, 0xACA3, 0x81B5,
+	0xACA4, 0x81B6, 0xACA5, 0x81B7, 0xACA6, 0x81B8, 0xACA7, 0x81B9,
+	0xACA8, 0xB0DC, 0xACA9, 0xB0DD, 0xACAA, 0xB0DE, 0xACAB, 0x81BA,
+	0xACAC, 0xB0DF, 0xACAD, 0x81BB, 0xACAE, 0x81BC, 0xACAF, 0xB0E0,
+	0xACB0, 0xB0E1, 0xACB1, 0x81BD, 0xACB2, 0x81BE, 0xACB3, 0x81BF,
+	0xACB4, 0x81C0, 0xACB5, 0x81C1, 0xACB6, 0x81C2, 0xACB7, 0x81C3,
+	0xACB8, 0xB0E2, 0xACB9, 0xB0E3, 0xACBA, 0x81C4, 0xACBB, 0xB0E4,
+	0xACBC, 0xB0E5, 0xACBD, 0xB0E6, 0xACBE, 0x81C5, 0xACBF, 0x81C6,
+	0xACC0, 0x81C7, 0xACC1, 0xB0E7, 0xACC2, 0x81C8, 0xACC3, 0x81C9,
+	0xACC4, 0xB0E8, 0xACC5, 0x81CA, 0xACC6, 0x81CB, 0xACC7, 0x81CC,
+	0xACC8, 0xB0E9, 0xACC9, 0x81CD, 0xACCA, 0x81CE, 0xACCB, 0x81CF,
+	0xACCC, 0xB0EA, 0xACCD, 0x81D0, 0xACCE, 0x81D1, 0xACCF, 0x81D2,
+	0xACD0, 0x81D3, 0xACD1, 0x81D4, 0xACD2, 0x81D5, 0xACD3, 0x81D6,
+	0xACD4, 0x81D7, 0xACD5, 0xB0EB, 0xACD6, 0x81D8, 0xACD7, 0xB0EC,
+	0xACD8, 0x81D9, 0xACD9, 0x81DA, 0xACDA, 0x81DB, 0xACDB, 0x81DC,
+	0xACDC, 0x81DD, 0xACDD, 0x81DE, 0xACDE, 0x81DF, 0xACDF, 0x81E0,
+	0xACE0, 0xB0ED, 0xACE1, 0xB0EE, 0xACE2, 0x81E1, 0xACE3, 0x81E2,
+	0xACE4, 0xB0EF, 0xACE5, 0x81E3, 0xACE6, 0x81E4, 0xACE7, 0xB0F0,
+	0xACE8, 0xB0F1, 0xACE9, 0x81E5, 0xACEA, 0xB0F2, 0xACEB, 0x81E6,
+	0xACEC, 0xB0F3, 0xACED, 0x81E7, 0xACEE, 0x81E8, 0xACEF, 0xB0F4,
+	0xACF0, 0xB0F5, 0xACF1, 0xB0F6, 0xACF2, 0x81E9, 0xACF3, 0xB0F7,
+	0xACF4, 0x81EA, 0xACF5, 0xB0F8, 0xACF6, 0xB0F9, 0xACF7, 0x81EB,
+	0xACF8, 0x81EC, 0xACF9, 0x81ED, 0xACFA, 0x81EE, 0xACFB, 0x81EF,
+	0xACFC, 0xB0FA, 0xACFD, 0xB0FB, 0xACFE, 0x81F0, 0xACFF, 0x81F1,
+	0xAD00, 0xB0FC, 0xAD01, 0x81F2, 0xAD02, 0x81F3, 0xAD03, 0x81F4,
+	0xAD04, 0xB0FD, 0xAD05, 0x81F5, 0xAD06, 0xB0FE, 0xAD07, 0x81F6,
+	0xAD08, 0x81F7, 0xAD09, 0x81F8, 0xAD0A, 0x81F9, 0xAD0B, 0x81FA,
+	0xAD0C, 0xB1A1, 0xAD0D, 0xB1A2, 0xAD0E, 0x81FB, 0xAD0F, 0xB1A3,
+	0xAD10, 0x81FC, 0xAD11, 0xB1A4, 0xAD12, 0x81FD, 0xAD13, 0x81FE,
+	0xAD14, 0x8241, 0xAD15, 0x8242, 0xAD16, 0x8243, 0xAD17, 0x8244,
+	0xAD18, 0xB1A5, 0xAD19, 0x8245, 0xAD1A, 0x8246, 0xAD1B, 0x8247,
+	0xAD1C, 0xB1A6, 0xAD1D, 0x8248, 0xAD1E, 0x8249, 0xAD1F, 0x824A,
+	0xAD20, 0xB1A7, 0xAD21, 0x824B, 0xAD22, 0x824C, 0xAD23, 0x824D,
+	0xAD24, 0x824E, 0xAD25, 0x824F, 0xAD26, 0x8250, 0xAD27, 0x8251,
+	0xAD28, 0x8252, 0xAD29, 0xB1A8, 0xAD2A, 0x8253, 0xAD2B, 0x8254,
+	0xAD2C, 0xB1A9, 0xAD2D, 0xB1AA, 0xAD2E, 0x8255, 0xAD2F, 0x8256,
+	0xAD30, 0x8257, 0xAD31, 0x8258, 0xAD32, 0x8259, 0xAD33, 0x825A,
+	0xAD34, 0xB1AB, 0xAD35, 0xB1AC, 0xAD36, 0x8261, 0xAD37, 0x8262,
+	0xAD38, 0xB1AD, 0xAD39, 0x8263, 0xAD3A, 0x8264, 0xAD3B, 0x8265,
+	0xAD3C, 0xB1AE, 0xAD3D, 0x8266, 0xAD3E, 0x8267, 0xAD3F, 0x8268,
+	0xAD40, 0x8269, 0xAD41, 0x826A, 0xAD42, 0x826B, 0xAD43, 0x826C,
+	0xAD44, 0xB1AF, 0xAD45, 0xB1B0, 0xAD46, 0x826D, 0xAD47, 0xB1B1,
+	0xAD48, 0x826E, 0xAD49, 0xB1B2, 0xAD4A, 0x826F, 0xAD4B, 0x8270,
+	0xAD4C, 0x8271, 0xAD4D, 0x8272, 0xAD4E, 0x8273, 0xAD4F, 0x8274,
+	0xAD50, 0xB1B3, 0xAD51, 0x8275, 0xAD52, 0x8276, 0xAD53, 0x8277,
+	0xAD54, 0xB1B4, 0xAD55, 0x8278, 0xAD56, 0x8279, 0xAD57, 0x827A,
+	0xAD58, 0xB1B5, 0xAD59, 0x8281, 0xAD5A, 0x8282, 0xAD5B, 0x8283,
+	0xAD5C, 0x8284, 0xAD5D, 0x8285, 0xAD5E, 0x8286, 0xAD5F, 0x8287,
+	0xAD60, 0x8288, 0xAD61, 0xB1B6, 0xAD62, 0x8289, 0xAD63, 0xB1B7,
+	0xAD64, 0x828A, 0xAD65, 0x828B, 0xAD66, 0x828C, 0xAD67, 0x828D,
+	0xAD68, 0x828E, 0xAD69, 0x828F, 0xAD6A, 0x8290, 0xAD6B, 0x8291,
+	0xAD6C, 0xB1B8, 0xAD6D, 0xB1B9, 0xAD6E, 0x8292, 0xAD6F, 0x8293,
+	0xAD70, 0xB1BA, 0xAD71, 0x8294, 0xAD72, 0x8295, 0xAD73, 0xB1BB,
+	0xAD74, 0xB1BC, 0xAD75, 0xB1BD, 0xAD76, 0xB1BE, 0xAD77, 0x8296,
+	0xAD78, 0x8297, 0xAD79, 0x8298, 0xAD7A, 0x8299, 0xAD7B, 0xB1BF,
+	0xAD7C, 0xB1C0, 0xAD7D, 0xB1C1, 0xAD7E, 0x829A, 0xAD7F, 0xB1C2,
+	0xAD80, 0x829B, 0xAD81, 0xB1C3, 0xAD82, 0xB1C4, 0xAD83, 0x829C,
+	0xAD84, 0x829D, 0xAD85, 0x829E, 0xAD86, 0x829F, 0xAD87, 0x82A0,
+	0xAD88, 0xB1C5, 0xAD89, 0xB1C6, 0xAD8A, 0x82A1, 0xAD8B, 0x82A2,
+	0xAD8C, 0xB1C7, 0xAD8D, 0x82A3, 0xAD8E, 0x82A4, 0xAD8F, 0x82A5,
+	0xAD90, 0xB1C8, 0xAD91, 0x82A6, 0xAD92, 0x82A7, 0xAD93, 0x82A8,
+	0xAD94, 0x82A9, 0xAD95, 0x82AA, 0xAD96, 0x82AB, 0xAD97, 0x82AC,
+	0xAD98, 0x82AD, 0xAD99, 0x82AE, 0xAD9A, 0x82AF, 0xAD9B, 0x82B0,
+	0xAD9C, 0xB1C9, 0xAD9D, 0xB1CA, 0xAD9E, 0x82B1, 0xAD9F, 0x82B2,
+	0xADA0, 0x82B3, 0xADA1, 0x82B4, 0xADA2, 0x82B5, 0xADA3, 0x82B6,
+	0xADA4, 0xB1CB, 0xADA5, 0x82B7, 0xADA6, 0x82B8, 0xADA7, 0x82B9,
+	0xADA8, 0x82BA, 0xADA9, 0x82BB, 0xADAA, 0x82BC, 0xADAB, 0x82BD,
+	0xADAC, 0x82BE, 0xADAD, 0x82BF, 0xADAE, 0x82C0, 0xADAF, 0x82C1,
+	0xADB0, 0x82C2, 0xADB1, 0x82C3, 0xADB2, 0x82C4, 0xADB3, 0x82C5,
+	0xADB4, 0x82C6, 0xADB5, 0x82C7, 0xADB6, 0x82C8, 0xADB7, 0xB1CC,
+	0xADB8, 0x82C9, 0xADB9, 0x82CA, 0xADBA, 0x82CB, 0xADBB, 0x82CC,
+	0xADBC, 0x82CD, 0xADBD, 0x82CE, 0xADBE, 0x82CF, 0xADBF, 0x82D0,
+	0xADC0, 0xB1CD, 0xADC1, 0xB1CE, 0xADC2, 0x82D1, 0xADC3, 0x82D2,
+	0xADC4, 0xB1CF, 0xADC5, 0x82D3, 0xADC6, 0x82D4, 0xADC7, 0x82D5,
+	0xADC8, 0xB1D0, 0xADC9, 0x82D6, 0xADCA, 0x82D7, 0xADCB, 0x82D8,
+	0xADCC, 0x82D9, 0xADCD, 0x82DA, 0xADCE, 0x82DB, 0xADCF, 0x82DC,
+	0xADD0, 0xB1D1, 0xADD1, 0xB1D2, 0xADD2, 0x82DD, 0xADD3, 0xB1D3,
+	0xADD4, 0x82DE, 0xADD5, 0x82DF, 0xADD6, 0x82E0, 0xADD7, 0x82E1,
+	0xADD8, 0x82E2, 0xADD9, 0x82E3, 0xADDA, 0x82E4, 0xADDB, 0x82E5,
+	0xADDC, 0xB1D4, 0xADDD, 0x82E6, 0xADDE, 0x82E7, 0xADDF, 0x82E8,
+	0xADE0, 0xB1D5, 0xADE1, 0x82E9, 0xADE2, 0x82EA, 0xADE3, 0x82EB,
+	0xADE4, 0xB1D6, 0xADE5, 0x82EC, 0xADE6, 0x82ED, 0xADE7, 0x82EE,
+	0xADE8, 0x82EF, 0xADE9, 0x82F0, 0xADEA, 0x82F1, 0xADEB, 0x82F2,
+	0xADEC, 0x82F3, 0xADED, 0x82F4, 0xADEE, 0x82F5, 0xADEF, 0x82F6,
+	0xADF0, 0x82F7, 0xADF1, 0x82F8, 0xADF2, 0x82F9, 0xADF3, 0x82FA,
+	0xADF4, 0x82FB, 0xADF5, 0x82FC, 0xADF6, 0x82FD, 0xADF7, 0x82FE,
+	0xADF8, 0xB1D7, 0xADF9, 0xB1D8, 0xADFA, 0x8341, 0xADFB, 0x8342,
+	0xADFC, 0xB1D9, 0xADFD, 0x8343, 0xADFE, 0x8344, 0xADFF, 0xB1DA,
+	0xAE00, 0xB1DB, 0xAE01, 0xB1DC, 0xAE02, 0x8345, 0xAE03, 0x8346,
+	0xAE04, 0x8347, 0xAE05, 0x8348, 0xAE06, 0x8349, 0xAE07, 0x834A,
+	0xAE08, 0xB1DD, 0xAE09, 0xB1DE, 0xAE0A, 0x834B, 0xAE0B, 0xB1DF,
+	0xAE0C, 0x834C, 0xAE0D, 0xB1E0, 0xAE0E, 0x834D, 0xAE0F, 0x834E,
+	0xAE10, 0x834F, 0xAE11, 0x8350, 0xAE12, 0x8351, 0xAE13, 0x8352,
+	0xAE14, 0xB1E1, 0xAE15, 0x8353, 0xAE16, 0x8354, 0xAE17, 0x8355,
+	0xAE18, 0x8356, 0xAE19, 0x8357, 0xAE1A, 0x8358, 0xAE1B, 0x8359,
+	0xAE1C, 0x835A, 0xAE1D, 0x8361, 0xAE1E, 0x8362, 0xAE1F, 0x8363,
+	0xAE20, 0x8364, 0xAE21, 0x8365, 0xAE22, 0x8366, 0xAE23, 0x8367,
+	0xAE24, 0x8368, 0xAE25, 0x8369, 0xAE26, 0x836A, 0xAE27, 0x836B,
+	0xAE28, 0x836C, 0xAE29, 0x836D, 0xAE2A, 0x836E, 0xAE2B, 0x836F,
+	0xAE2C, 0x8370, 0xAE2D, 0x8371, 0xAE2E, 0x8372, 0xAE2F, 0x8373,
+	0xAE30, 0xB1E2, 0xAE31, 0xB1E3, 0xAE32, 0x8374, 0xAE33, 0x8375,
+	0xAE34, 0xB1E4, 0xAE35, 0x8376, 0xAE36, 0x8377, 0xAE37, 0xB1E5,
+	0xAE38, 0xB1E6, 0xAE39, 0x8378, 0xAE3A, 0xB1E7, 0xAE3B, 0x8379,
+	0xAE3C, 0x837A, 0xAE3D, 0x8381, 0xAE3E, 0x8382, 0xAE3F, 0x8383,
+	0xAE40, 0xB1E8, 0xAE41, 0xB1E9, 0xAE42, 0x8384, 0xAE43, 0xB1EA,
+	0xAE44, 0x8385, 0xAE45, 0xB1EB, 0xAE46, 0xB1EC, 0xAE47, 0x8386,
+	0xAE48, 0x8387, 0xAE49, 0x8388, 0xAE4A, 0xB1ED, 0xAE4B, 0x8389,
+	0xAE4C, 0xB1EE, 0xAE4D, 0xB1EF, 0xAE4E, 0xB1F0, 0xAE4F, 0x838A,
+	0xAE50, 0xB1F1, 0xAE51, 0x838B, 0xAE52, 0x838C, 0xAE53, 0x838D,
+	0xAE54, 0xB1F2, 0xAE55, 0x838E, 0xAE56, 0xB1F3, 0xAE57, 0x838F,
+	0xAE58, 0x8390, 0xAE59, 0x8391, 0xAE5A, 0x8392, 0xAE5B, 0x8393,
+	0xAE5C, 0xB1F4, 0xAE5D, 0xB1F5, 0xAE5E, 0x8394, 0xAE5F, 0xB1F6,
+	0xAE60, 0xB1F7, 0xAE61, 0xB1F8, 0xAE62, 0x8395, 0xAE63, 0x8396,
+	0xAE64, 0x8397, 0xAE65, 0xB1F9, 0xAE66, 0x8398, 0xAE67, 0x8399,
+	0xAE68, 0xB1FA, 0xAE69, 0xB1FB, 0xAE6A, 0x839A, 0xAE6B, 0x839B,
+	0xAE6C, 0xB1FC, 0xAE6D, 0x839C, 0xAE6E, 0x839D, 0xAE6F, 0x839E,
+	0xAE70, 0xB1FD, 0xAE71, 0x839F, 0xAE72, 0x83A0, 0xAE73, 0x83A1,
+	0xAE74, 0x83A2, 0xAE75, 0x83A3, 0xAE76, 0x83A4, 0xAE77, 0x83A5,
+	0xAE78, 0xB1FE, 0xAE79, 0xB2A1, 0xAE7A, 0x83A6, 0xAE7B, 0xB2A2,
+	0xAE7C, 0xB2A3, 0xAE7D, 0xB2A4, 0xAE7E, 0x83A7, 0xAE7F, 0x83A8,
+	0xAE80, 0x83A9, 0xAE81, 0x83AA, 0xAE82, 0x83AB, 0xAE83, 0x83AC,
+	0xAE84, 0xB2A5, 0xAE85, 0xB2A6, 0xAE86, 0x83AD, 0xAE87, 0x83AE,
+	0xAE88, 0x83AF, 0xAE89, 0x83B0, 0xAE8A, 0x83B1, 0xAE8B, 0x83B2,
+	0xAE8C, 0xB2A7, 0xAE8D, 0x83B3, 0xAE8E, 0x83B4, 0xAE8F, 0x83B5,
+	0xAE90, 0x83B6, 0xAE91, 0x83B7, 0xAE92, 0x83B8, 0xAE93, 0x83B9,
+	0xAE94, 0x83BA, 0xAE95, 0x83BB, 0xAE96, 0x83BC, 0xAE97, 0x83BD,
+	0xAE98, 0x83BE, 0xAE99, 0x83BF, 0xAE9A, 0x83C0, 0xAE9B, 0x83C1,
+	0xAE9C, 0x83C2, 0xAE9D, 0x83C3, 0xAE9E, 0x83C4, 0xAE9F, 0x83C5,
+	0xAEA0, 0x83C6, 0xAEA1, 0x83C7, 0xAEA2, 0x83C8, 0xAEA3, 0x83C9,
+	0xAEA4, 0x83CA, 0xAEA5, 0x83CB, 0xAEA6, 0x83CC, 0xAEA7, 0x83CD,
+	0xAEA8, 0x83CE, 0xAEA9, 0x83CF, 0xAEAA, 0x83D0, 0xAEAB, 0x83D1,
+	0xAEAC, 0x83D2, 0xAEAD, 0x83D3, 0xAEAE, 0x83D4, 0xAEAF, 0x83D5,
+	0xAEB0, 0x83D6, 0xAEB1, 0x83D7, 0xAEB2, 0x83D8, 0xAEB3, 0x83D9,
+	0xAEB4, 0x83DA, 0xAEB5, 0x83DB, 0xAEB6, 0x83DC, 0xAEB7, 0x83DD,
+	0xAEB8, 0x83DE, 0xAEB9, 0x83DF, 0xAEBA, 0x83E0, 0xAEBB, 0x83E1,
+	0xAEBC, 0xB2A8, 0xAEBD, 0xB2A9, 0xAEBE, 0xB2AA, 0xAEBF, 0x83E2,
+	0xAEC0, 0xB2AB, 0xAEC1, 0x83E3, 0xAEC2, 0x83E4, 0xAEC3, 0x83E5,
+	0xAEC4, 0xB2AC, 0xAEC5, 0x83E6, 0xAEC6, 0x83E7, 0xAEC7, 0x83E8,
+	0xAEC8, 0x83E9, 0xAEC9, 0x83EA, 0xAECA, 0x83EB, 0xAECB, 0x83EC,
+	0xAECC, 0xB2AD, 0xAECD, 0xB2AE, 0xAECE, 0x83ED, 0xAECF, 0xB2AF,
+	0xAED0, 0xB2B0, 0xAED1, 0xB2B1, 0xAED2, 0x83EE, 0xAED3, 0x83EF,
+	0xAED4, 0x83F0, 0xAED5, 0x83F1, 0xAED6, 0x83F2, 0xAED7, 0x83F3,
+	0xAED8, 0xB2B2, 0xAED9, 0xB2B3, 0xAEDA, 0x83F4, 0xAEDB, 0x83F5,
+	0xAEDC, 0xB2B4, 0xAEDD, 0x83F6, 0xAEDE, 0x83F7, 0xAEDF, 0x83F8,
+	0xAEE0, 0x83F9, 0xAEE1, 0x83FA, 0xAEE2, 0x83FB, 0xAEE3, 0x83FC,
+	0xAEE4, 0x83FD, 0xAEE5, 0x83FE, 0xAEE6, 0x8441, 0xAEE7, 0x8442,
+	0xAEE8, 0xB2B5, 0xAEE9, 0x8443, 0xAEEA, 0x8444, 0xAEEB, 0xB2B6,
+	0xAEEC, 0x8445, 0xAEED, 0xB2B7, 0xAEEE, 0x8446, 0xAEEF, 0x8447,
+	0xAEF0, 0x8448, 0xAEF1, 0x8449, 0xAEF2, 0x844A, 0xAEF3, 0x844B,
+	0xAEF4, 0xB2B8, 0xAEF5, 0x844C, 0xAEF6, 0x844D, 0xAEF7, 0x844E,
+	0xAEF8, 0xB2B9, 0xAEF9, 0x844F, 0xAEFA, 0x8450, 0xAEFB, 0x8451,
+	0xAEFC, 0xB2BA, 0xAEFD, 0x8452, 0xAEFE, 0x8453, 0xAEFF, 0x8454,
+	0xAF00, 0x8455, 0xAF01, 0x8456, 0xAF02, 0x8457, 0xAF03, 0x8458,
+	0xAF04, 0x8459, 0xAF05, 0x845A, 0xAF06, 0x8461, 0xAF07, 0xB2BB,
+	0xAF08, 0xB2BC, 0xAF09, 0x8462, 0xAF0A, 0x8463, 0xAF0B, 0x8464,
+	0xAF0C, 0x8465, 0xAF0D, 0xB2BD, 0xAF0E, 0x8466, 0xAF0F, 0x8467,
+	0xAF10, 0xB2BE, 0xAF11, 0x8468, 0xAF12, 0x8469, 0xAF13, 0x846A,
+	0xAF14, 0x846B, 0xAF15, 0x846C, 0xAF16, 0x846D, 0xAF17, 0x846E,
+	0xAF18, 0x846F, 0xAF19, 0x8470, 0xAF1A, 0x8471, 0xAF1B, 0x8472,
+	0xAF1C, 0x8473, 0xAF1D, 0x8474, 0xAF1E, 0x8475, 0xAF1F, 0x8476,
+	0xAF20, 0x8477, 0xAF21, 0x8478, 0xAF22, 0x8479, 0xAF23, 0x847A,
+	0xAF24, 0x8481, 0xAF25, 0x8482, 0xAF26, 0x8483, 0xAF27, 0x8484,
+	0xAF28, 0x8485, 0xAF29, 0x8486, 0xAF2A, 0x8487, 0xAF2B, 0x8488,
+	0xAF2C, 0xB2BF, 0xAF2D, 0xB2C0, 0xAF2E, 0x8489, 0xAF2F, 0x848A,
+	0xAF30, 0xB2C1, 0xAF31, 0x848B, 0xAF32, 0xB2C2, 0xAF33, 0x848C,
+	0xAF34, 0xB2C3, 0xAF35, 0x848D, 0xAF36, 0x848E, 0xAF37, 0x848F,
+	0xAF38, 0x8490, 0xAF39, 0x8491, 0xAF3A, 0x8492, 0xAF3B, 0x8493,
+	0xAF3C, 0xB2C4, 0xAF3D, 0xB2C5, 0xAF3E, 0x8494, 0xAF3F, 0xB2C6,
+	0xAF40, 0x8495, 0xAF41, 0xB2C7, 0xAF42, 0xB2C8, 0xAF43, 0xB2C9,
+	0xAF44, 0x8496, 0xAF45, 0x8497, 0xAF46, 0x8498, 0xAF47, 0x8499,
+	0xAF48, 0xB2CA, 0xAF49, 0xB2CB, 0xAF4A, 0x849A, 0xAF4B, 0x849B,
+	0xAF4C, 0x849C, 0xAF4D, 0x849D, 0xAF4E, 0x849E, 0xAF4F, 0x849F,
+	0xAF50, 0xB2CC, 0xAF51, 0x84A0, 0xAF52, 0x84A1, 0xAF53, 0x84A2,
+	0xAF54, 0x84A3, 0xAF55, 0x84A4, 0xAF56, 0x84A5, 0xAF57, 0x84A6,
+	0xAF58, 0x84A7, 0xAF59, 0x84A8, 0xAF5A, 0x84A9, 0xAF5B, 0x84AA,
+	0xAF5C, 0xB2CD, 0xAF5D, 0xB2CE, 0xAF5E, 0x84AB, 0xAF5F, 0x84AC,
+	0xAF60, 0x84AD, 0xAF61, 0x84AE, 0xAF62, 0x84AF, 0xAF63, 0x84B0,
+	0xAF64, 0xB2CF, 0xAF65, 0xB2D0, 0xAF66, 0x84B1, 0xAF67, 0x84B2,
+	0xAF68, 0x84B3, 0xAF69, 0x84B4, 0xAF6A, 0x84B5, 0xAF6B, 0x84B6,
+	0xAF6C, 0x84B7, 0xAF6D, 0x84B8, 0xAF6E, 0x84B9, 0xAF6F, 0x84BA,
+	0xAF70, 0x84BB, 0xAF71, 0x84BC, 0xAF72, 0x84BD, 0xAF73, 0x84BE,
+	0xAF74, 0x84BF, 0xAF75, 0x84C0, 0xAF76, 0x84C1, 0xAF77, 0x84C2,
+	0xAF78, 0x84C3, 0xAF79, 0xB2D1, 0xAF7A, 0x84C4, 0xAF7B, 0x84C5,
+	0xAF7C, 0x84C6, 0xAF7D, 0x84C7, 0xAF7E, 0x84C8, 0xAF7F, 0x84C9,
+	0xAF80, 0xB2D2, 0xAF81, 0x84CA, 0xAF82, 0x84CB, 0xAF83, 0x84CC,
+	0xAF84, 0xB2D3, 0xAF85, 0x84CD, 0xAF86, 0x84CE, 0xAF87, 0x84CF,
+	0xAF88, 0xB2D4, 0xAF89, 0x84D0, 0xAF8A, 0x84D1, 0xAF8B, 0x84D2,
+	0xAF8C, 0x84D3, 0xAF8D, 0x84D4, 0xAF8E, 0x84D5, 0xAF8F, 0x84D6,
+	0xAF90, 0xB2D5, 0xAF91, 0xB2D6, 0xAF92, 0x84D7, 0xAF93, 0x84D8,
+	0xAF94, 0x84D9, 0xAF95, 0xB2D7, 0xAF96, 0x84DA, 0xAF97, 0x84DB,
+	0xAF98, 0x84DC, 0xAF99, 0x84DD, 0xAF9A, 0x84DE, 0xAF9B, 0x84DF,
+	0xAF9C, 0xB2D8, 0xAF9D, 0x84E0, 0xAF9E, 0x84E1, 0xAF9F, 0x84E2,
+	0xAFA0, 0x84E3, 0xAFA1, 0x84E4, 0xAFA2, 0x84E5, 0xAFA3, 0x84E6,
+	0xAFA4, 0x84E7, 0xAFA5, 0x84E8, 0xAFA6, 0x84E9, 0xAFA7, 0x84EA,
+	0xAFA8, 0x84EB, 0xAFA9, 0x84EC, 0xAFAA, 0x84ED, 0xAFAB, 0x84EE,
+	0xAFAC, 0x84EF, 0xAFAD, 0x84F0, 0xAFAE, 0x84F1, 0xAFAF, 0x84F2,
+	0xAFB0, 0x84F3, 0xAFB1, 0x84F4, 0xAFB2, 0x84F5, 0xAFB3, 0x84F6,
+	0xAFB4, 0x84F7, 0xAFB5, 0x84F8, 0xAFB6, 0x84F9, 0xAFB7, 0x84FA,
+	0xAFB8, 0xB2D9, 0xAFB9, 0xB2DA, 0xAFBA, 0x84FB, 0xAFBB, 0x84FC,
+	0xAFBC, 0xB2DB, 0xAFBD, 0x84FD, 0xAFBE, 0x84FE, 0xAFBF, 0x8541,
+	0xAFC0, 0xB2DC, 0xAFC1, 0x8542, 0xAFC2, 0x8543, 0xAFC3, 0x8544,
+	0xAFC4, 0x8545, 0xAFC5, 0x8546, 0xAFC6, 0x8547, 0xAFC7, 0xB2DD,
+	0xAFC8, 0xB2DE, 0xAFC9, 0xB2DF, 0xAFCA, 0x8548, 0xAFCB, 0xB2E0,
+	0xAFCC, 0x8549, 0xAFCD, 0xB2E1, 0xAFCE, 0xB2E2, 0xAFCF, 0x854A,
+	0xAFD0, 0x854B, 0xAFD1, 0x854C, 0xAFD2, 0x854D, 0xAFD3, 0x854E,
+	0xAFD4, 0xB2E3, 0xAFD5, 0x854F, 0xAFD6, 0x8550, 0xAFD7, 0x8551,
+	0xAFD8, 0x8552, 0xAFD9, 0x8553, 0xAFDA, 0x8554, 0xAFDB, 0x8555,
+	0xAFDC, 0xB2E4, 0xAFDD, 0x8556, 0xAFDE, 0x8557, 0xAFDF, 0x8558,
+	0xAFE0, 0x8559, 0xAFE1, 0x855A, 0xAFE2, 0x8561, 0xAFE3, 0x8562,
+	0xAFE4, 0x8563, 0xAFE5, 0x8564, 0xAFE6, 0x8565, 0xAFE7, 0x8566,
+	0xAFE8, 0xB2E5, 0xAFE9, 0xB2E6, 0xAFEA, 0x8567, 0xAFEB, 0x8568,
+	0xAFEC, 0x8569, 0xAFED, 0x856A, 0xAFEE, 0x856B, 0xAFEF, 0x856C,
+	0xAFF0, 0xB2E7, 0xAFF1, 0xB2E8, 0xAFF2, 0x856D, 0xAFF3, 0x856E,
+	0xAFF4, 0xB2E9, 0xAFF5, 0x856F, 0xAFF6, 0x8570, 0xAFF7, 0x8571,
+	0xAFF8, 0xB2EA, 0xAFF9, 0x8572, 0xAFFA, 0x8573, 0xAFFB, 0x8574,
+	0xAFFC, 0x8575, 0xAFFD, 0x8576, 0xAFFE, 0x8577, 0xAFFF, 0x8578,
+	0xB000, 0xB2EB, 0xB001, 0xB2EC, 0xB002, 0x8579, 0xB003, 0x857A,
+	0xB004, 0xB2ED, 0xB005, 0x8581, 0xB006, 0x8582, 0xB007, 0x8583,
+	0xB008, 0x8584, 0xB009, 0x8585, 0xB00A, 0x8586, 0xB00B, 0x8587,
+	0xB00C, 0xB2EE, 0xB00D, 0x8588, 0xB00E, 0x8589, 0xB00F, 0x858A,
+	0xB010, 0xB2EF, 0xB011, 0x858B, 0xB012, 0x858C, 0xB013, 0x858D,
+	0xB014, 0xB2F0, 0xB015, 0x858E, 0xB016, 0x858F, 0xB017, 0x8590,
+	0xB018, 0x8591, 0xB019, 0x8592, 0xB01A, 0x8593, 0xB01B, 0x8594,
+	0xB01C, 0xB2F1, 0xB01D, 0xB2F2, 0xB01E, 0x8595, 0xB01F, 0x8596,
+	0xB020, 0x8597, 0xB021, 0x8598, 0xB022, 0x8599, 0xB023, 0x859A,
+	0xB024, 0x859B, 0xB025, 0x859C, 0xB026, 0x859D, 0xB027, 0x859E,
+	0xB028, 0xB2F3, 0xB029, 0x859F, 0xB02A, 0x85A0, 0xB02B, 0x85A1,
+	0xB02C, 0x85A2, 0xB02D, 0x85A3, 0xB02E, 0x85A4, 0xB02F, 0x85A5,
+	0xB030, 0x85A6, 0xB031, 0x85A7, 0xB032, 0x85A8, 0xB033, 0x85A9,
+	0xB034, 0x85AA, 0xB035, 0x85AB, 0xB036, 0x85AC, 0xB037, 0x85AD,
+	0xB038, 0x85AE, 0xB039, 0x85AF, 0xB03A, 0x85B0, 0xB03B, 0x85B1,
+	0xB03C, 0x85B2, 0xB03D, 0x85B3, 0xB03E, 0x85B4, 0xB03F, 0x85B5,
+	0xB040, 0x85B6, 0xB041, 0x85B7, 0xB042, 0x85B8, 0xB043, 0x85B9,
+	0xB044, 0xB2F4, 0xB045, 0xB2F5, 0xB046, 0x85BA, 0xB047, 0x85BB,
+	0xB048, 0xB2F6, 0xB049, 0x85BC, 0xB04A, 0xB2F7, 0xB04B, 0x85BD,
+	0xB04C, 0xB2F8, 0xB04D, 0x85BE, 0xB04E, 0xB2F9, 0xB04F, 0x85BF,
+	0xB050, 0x85C0, 0xB051, 0x85C1, 0xB052, 0x85C2, 0xB053, 0xB2FA,
+	0xB054, 0xB2FB, 0xB055, 0xB2FC, 0xB056, 0x85C3, 0xB057, 0xB2FD,
+	0xB058, 0x85C4, 0xB059, 0xB2FE, 0xB05A, 0x85C5, 0xB05B, 0x85C6,
+	0xB05C, 0x85C7, 0xB05D, 0xB3A1, 0xB05E, 0x85C8, 0xB05F, 0x85C9,
+	0xB060, 0x85CA, 0xB061, 0x85CB, 0xB062, 0x85CC, 0xB063, 0x85CD,
+	0xB064, 0x85CE, 0xB065, 0x85CF, 0xB066, 0x85D0, 0xB067, 0x85D1,
+	0xB068, 0x85D2, 0xB069, 0x85D3, 0xB06A, 0x85D4, 0xB06B, 0x85D5,
+	0xB06C, 0x85D6, 0xB06D, 0x85D7, 0xB06E, 0x85D8, 0xB06F, 0x85D9,
+	0xB070, 0x85DA, 0xB071, 0x85DB, 0xB072, 0x85DC, 0xB073, 0x85DD,
+	0xB074, 0x85DE, 0xB075, 0x85DF, 0xB076, 0x85E0, 0xB077, 0x85E1,
+	0xB078, 0x85E2, 0xB079, 0x85E3, 0xB07A, 0x85E4, 0xB07B, 0x85E5,
+	0xB07C, 0xB3A2, 0xB07D, 0xB3A3, 0xB07E, 0x85E6, 0xB07F, 0x85E7,
+	0xB080, 0xB3A4, 0xB081, 0x85E8, 0xB082, 0x85E9, 0xB083, 0x85EA,
+	0xB084, 0xB3A5, 0xB085, 0x85EB, 0xB086, 0x85EC, 0xB087, 0x85ED,
+	0xB088, 0x85EE, 0xB089, 0x85EF, 0xB08A, 0x85F0, 0xB08B, 0x85F1,
+	0xB08C, 0xB3A6, 0xB08D, 0xB3A7, 0xB08E, 0x85F2, 0xB08F, 0xB3A8,
+	0xB090, 0x85F3, 0xB091, 0xB3A9, 0xB092, 0x85F4, 0xB093, 0x85F5,
+	0xB094, 0x85F6, 0xB095, 0x85F7, 0xB096, 0x85F8, 0xB097, 0x85F9,
+	0xB098, 0xB3AA, 0xB099, 0xB3AB, 0xB09A, 0xB3AC, 0xB09B, 0x85FA,
+	0xB09C, 0xB3AD, 0xB09D, 0x85FB, 0xB09E, 0x85FC, 0xB09F, 0xB3AE,
+	0xB0A0, 0xB3AF, 0xB0A1, 0xB3B0, 0xB0A2, 0xB3B1, 0xB0A3, 0x85FD,
+	0xB0A4, 0x85FE, 0xB0A5, 0x8641, 0xB0A6, 0x8642, 0xB0A7, 0x8643,
+	0xB0A8, 0xB3B2, 0xB0A9, 0xB3B3, 0xB0AA, 0x8644, 0xB0AB, 0xB3B4,
+	0xB0AC, 0xB3B5, 0xB0AD, 0xB3B6, 0xB0AE, 0xB3B7, 0xB0AF, 0xB3B8,
+	0xB0B0, 0x8645, 0xB0B1, 0xB3B9, 0xB0B2, 0x8646, 0xB0B3, 0xB3BA,
+	0xB0B4, 0xB3BB, 0xB0B5, 0xB3BC, 0xB0B6, 0x8647, 0xB0B7, 0x8648,
+	0xB0B8, 0xB3BD, 0xB0B9, 0x8649, 0xB0BA, 0x864A, 0xB0BB, 0x864B,
+	0xB0BC, 0xB3BE, 0xB0BD, 0x864C, 0xB0BE, 0x864D, 0xB0BF, 0x864E,
+	0xB0C0, 0x864F, 0xB0C1, 0x8650, 0xB0C2, 0x8651, 0xB0C3, 0x8652,
+	0xB0C4, 0xB3BF, 0xB0C5, 0xB3C0, 0xB0C6, 0x8653, 0xB0C7, 0xB3C1,
+	0xB0C8, 0xB3C2, 0xB0C9, 0xB3C3, 0xB0CA, 0x8654, 0xB0CB, 0x8655,
+	0xB0CC, 0x8656, 0xB0CD, 0x8657, 0xB0CE, 0x8658, 0xB0CF, 0x8659,
+	0xB0D0, 0xB3C4, 0xB0D1, 0xB3C5, 0xB0D2, 0x865A, 0xB0D3, 0x8661,
+	0xB0D4, 0xB3C6, 0xB0D5, 0x8662, 0xB0D6, 0x8663, 0xB0D7, 0x8664,
+	0xB0D8, 0xB3C7, 0xB0D9, 0x8665, 0xB0DA, 0x8666, 0xB0DB, 0x8667,
+	0xB0DC, 0x8668, 0xB0DD, 0x8669, 0xB0DE, 0x866A, 0xB0DF, 0x866B,
+	0xB0E0, 0xB3C8, 0xB0E1, 0x866C, 0xB0E2, 0x866D, 0xB0E3, 0x866E,
+	0xB0E4, 0x866F, 0xB0E5, 0xB3C9, 0xB0E6, 0x8670, 0xB0E7, 0x8671,
+	0xB0E8, 0x8672, 0xB0E9, 0x8673, 0xB0EA, 0x8674, 0xB0EB, 0x8675,
+	0xB0EC, 0x8676, 0xB0ED, 0x8677, 0xB0EE, 0x8678, 0xB0EF, 0x8679,
+	0xB0F0, 0x867A, 0xB0F1, 0x8681, 0xB0F2, 0x8682, 0xB0F3, 0x8683,
+	0xB0F4, 0x8684, 0xB0F5, 0x8685, 0xB0F6, 0x8686, 0xB0F7, 0x8687,
+	0xB0F8, 0x8688, 0xB0F9, 0x8689, 0xB0FA, 0x868A, 0xB0FB, 0x868B,
+	0xB0FC, 0x868C, 0xB0FD, 0x868D, 0xB0FE, 0x868E, 0xB0FF, 0x868F,
+	0xB100, 0x8690, 0xB101, 0x8691, 0xB102, 0x8692, 0xB103, 0x8693,
+	0xB104, 0x8694, 0xB105, 0x8695, 0xB106, 0x8696, 0xB107, 0x8697,
+	0xB108, 0xB3CA, 0xB109, 0xB3CB, 0xB10A, 0x8698, 0xB10B, 0xB3CC,
+	0xB10C, 0xB3CD, 0xB10D, 0x8699, 0xB10E, 0x869A, 0xB10F, 0x869B,
+	0xB110, 0xB3CE, 0xB111, 0x869C, 0xB112, 0xB3CF, 0xB113, 0xB3D0,
+	0xB114, 0x869D, 0xB115, 0x869E, 0xB116, 0x869F, 0xB117, 0x86A0,
+	0xB118, 0xB3D1, 0xB119, 0xB3D2, 0xB11A, 0x86A1, 0xB11B, 0xB3D3,
+	0xB11C, 0xB3D4, 0xB11D, 0xB3D5, 0xB11E, 0x86A2, 0xB11F, 0x86A3,
+	0xB120, 0x86A4, 0xB121, 0x86A5, 0xB122, 0x86A6, 0xB123, 0xB3D6,
+	0xB124, 0xB3D7, 0xB125, 0xB3D8, 0xB126, 0x86A7, 0xB127, 0x86A8,
+	0xB128, 0xB3D9, 0xB129, 0x86A9, 0xB12A, 0x86AA, 0xB12B, 0x86AB,
+	0xB12C, 0xB3DA, 0xB12D, 0x86AC, 0xB12E, 0x86AD, 0xB12F, 0x86AE,
+	0xB130, 0x86AF, 0xB131, 0x86B0, 0xB132, 0x86B1, 0xB133, 0x86B2,
+	0xB134, 0xB3DB, 0xB135, 0xB3DC, 0xB136, 0x86B3, 0xB137, 0xB3DD,
+	0xB138, 0xB3DE, 0xB139, 0xB3DF, 0xB13A, 0x86B4, 0xB13B, 0x86B5,
+	0xB13C, 0x86B6, 0xB13D, 0x86B7, 0xB13E, 0x86B8, 0xB13F, 0x86B9,
+	0xB140, 0xB3E0, 0xB141, 0xB3E1, 0xB142, 0x86BA, 0xB143, 0x86BB,
+	0xB144, 0xB3E2, 0xB145, 0x86BC, 0xB146, 0x86BD, 0xB147, 0x86BE,
+	0xB148, 0xB3E3, 0xB149, 0x86BF, 0xB14A, 0x86C0, 0xB14B, 0x86C1,
+	0xB14C, 0x86C2, 0xB14D, 0x86C3, 0xB14E, 0x86C4, 0xB14F, 0x86C5,
+	0xB150, 0xB3E4, 0xB151, 0xB3E5, 0xB152, 0x86C6, 0xB153, 0x86C7,
+	0xB154, 0xB3E6, 0xB155, 0xB3E7, 0xB156, 0x86C8, 0xB157, 0x86C9,
+	0xB158, 0xB3E8, 0xB159, 0x86CA, 0xB15A, 0x86CB, 0xB15B, 0x86CC,
+	0xB15C, 0xB3E9, 0xB15D, 0x86CD, 0xB15E, 0x86CE, 0xB15F, 0x86CF,
+	0xB160, 0xB3EA, 0xB161, 0x86D0, 0xB162, 0x86D1, 0xB163, 0x86D2,
+	0xB164, 0x86D3, 0xB165, 0x86D4, 0xB166, 0x86D5, 0xB167, 0x86D6,
+	0xB168, 0x86D7, 0xB169, 0x86D8, 0xB16A, 0x86D9, 0xB16B, 0x86DA,
+	0xB16C, 0x86DB, 0xB16D, 0x86DC, 0xB16E, 0x86DD, 0xB16F, 0x86DE,
+	0xB170, 0x86DF, 0xB171, 0x86E0, 0xB172, 0x86E1, 0xB173, 0x86E2,
+	0xB174, 0x86E3, 0xB175, 0x86E4, 0xB176, 0x86E5, 0xB177, 0x86E6,
+	0xB178, 0xB3EB, 0xB179, 0xB3EC, 0xB17A, 0x86E7, 0xB17B, 0x86E8,
+	0xB17C, 0xB3ED, 0xB17D, 0x86E9, 0xB17E, 0x86EA, 0xB17F, 0x86EB,
+	0xB180, 0xB3EE, 0xB181, 0x86EC, 0xB182, 0xB3EF, 0xB183, 0x86ED,
+	0xB184, 0x86EE, 0xB185, 0x86EF, 0xB186, 0x86F0, 0xB187, 0x86F1,
+	0xB188, 0xB3F0, 0xB189, 0xB3F1, 0xB18A, 0x86F2, 0xB18B, 0xB3F2,
+	0xB18C, 0x86F3, 0xB18D, 0xB3F3, 0xB18E, 0x86F4, 0xB18F, 0x86F5,
+	0xB190, 0x86F6, 0xB191, 0x86F7, 0xB192, 0xB3F4, 0xB193, 0xB3F5,
+	0xB194, 0xB3F6, 0xB195, 0x86F8, 0xB196, 0x86F9, 0xB197, 0x86FA,
+	0xB198, 0xB3F7, 0xB199, 0x86FB, 0xB19A, 0x86FC, 0xB19B, 0x86FD,
+	0xB19C, 0xB3F8, 0xB19D, 0x86FE, 0xB19E, 0x8741, 0xB19F, 0x8742,
+	0xB1A0, 0x8743, 0xB1A1, 0x8744, 0xB1A2, 0x8745, 0xB1A3, 0x8746,
+	0xB1A4, 0x8747, 0xB1A5, 0x8748, 0xB1A6, 0x8749, 0xB1A7, 0x874A,
+	0xB1A8, 0xB3F9, 0xB1A9, 0x874B, 0xB1AA, 0x874C, 0xB1AB, 0x874D,
+	0xB1AC, 0x874E, 0xB1AD, 0x874F, 0xB1AE, 0x8750, 0xB1AF, 0x8751,
+	0xB1B0, 0x8752, 0xB1B1, 0x8753, 0xB1B2, 0x8754, 0xB1B3, 0x8755,
+	0xB1B4, 0x8756, 0xB1B5, 0x8757, 0xB1B6, 0x8758, 0xB1B7, 0x8759,
+	0xB1B8, 0x875A, 0xB1B9, 0x8761, 0xB1BA, 0x8762, 0xB1BB, 0x8763,
+	0xB1BC, 0x8764, 0xB1BD, 0x8765, 0xB1BE, 0x8766, 0xB1BF, 0x8767,
+	0xB1C0, 0x8768, 0xB1C1, 0x8769, 0xB1C2, 0x876A, 0xB1C3, 0x876B,
+	0xB1C4, 0x876C, 0xB1C5, 0x876D, 0xB1C6, 0x876E, 0xB1C7, 0x876F,
+	0xB1C8, 0x8770, 0xB1C9, 0x8771, 0xB1CA, 0x8772, 0xB1CB, 0x8773,
+	0xB1CC, 0xB3FA, 0xB1CD, 0x8774, 0xB1CE, 0x8775, 0xB1CF, 0x8776,
+	0xB1D0, 0xB3FB, 0xB1D1, 0x8777, 0xB1D2, 0x8778, 0xB1D3, 0x8779,
+	0xB1D4, 0xB3FC, 0xB1D5, 0x877A, 0xB1D6, 0x8781, 0xB1D7, 0x8782,
+	0xB1D8, 0x8783, 0xB1D9, 0x8784, 0xB1DA, 0x8785, 0xB1DB, 0x8786,
+	0xB1DC, 0xB3FD, 0xB1DD, 0xB3FE, 0xB1DE, 0x8787, 0xB1DF, 0xB4A1,
+	0xB1E0, 0x8788, 0xB1E1, 0x8789, 0xB1E2, 0x878A, 0xB1E3, 0x878B,
+	0xB1E4, 0x878C, 0xB1E5, 0x878D, 0xB1E6, 0x878E, 0xB1E7, 0x878F,
+	0xB1E8, 0xB4A2, 0xB1E9, 0xB4A3, 0xB1EA, 0x8790, 0xB1EB, 0x8791,
+	0xB1EC, 0xB4A4, 0xB1ED, 0x8792, 0xB1EE, 0x8793, 0xB1EF, 0x8794,
+	0xB1F0, 0xB4A5, 0xB1F1, 0x8795, 0xB1F2, 0x8796, 0xB1F3, 0x8797,
+	0xB1F4, 0x8798, 0xB1F5, 0x8799, 0xB1F6, 0x879A, 0xB1F7, 0x879B,
+	0xB1F8, 0x879C, 0xB1F9, 0xB4A6, 0xB1FA, 0x879D, 0xB1FB, 0xB4A7,
+	0xB1FC, 0x879E, 0xB1FD, 0xB4A8, 0xB1FE, 0x879F, 0xB1FF, 0x87A0,
+	0xB200, 0x87A1, 0xB201, 0x87A2, 0xB202, 0x87A3, 0xB203, 0x87A4,
+	0xB204, 0xB4A9, 0xB205, 0xB4AA, 0xB206, 0x87A5, 0xB207, 0x87A6,
+	0xB208, 0xB4AB, 0xB209, 0x87A7, 0xB20A, 0x87A8, 0xB20B, 0xB4AC,
+	0xB20C, 0xB4AD, 0xB20D, 0x87A9, 0xB20E, 0x87AA, 0xB20F, 0x87AB,
+	0xB210, 0x87AC, 0xB211, 0x87AD, 0xB212, 0x87AE, 0xB213, 0x87AF,
+	0xB214, 0xB4AE, 0xB215, 0xB4AF, 0xB216, 0x87B0, 0xB217, 0xB4B0,
+	0xB218, 0x87B1, 0xB219, 0xB4B1, 0xB21A, 0x87B2, 0xB21B, 0x87B3,
+	0xB21C, 0x87B4, 0xB21D, 0x87B5, 0xB21E, 0x87B6, 0xB21F, 0x87B7,
+	0xB220, 0xB4B2, 0xB221, 0x87B8, 0xB222, 0x87B9, 0xB223, 0x87BA,
+	0xB224, 0x87BB, 0xB225, 0x87BC, 0xB226, 0x87BD, 0xB227, 0x87BE,
+	0xB228, 0x87BF, 0xB229, 0x87C0, 0xB22A, 0x87C1, 0xB22B, 0x87C2,
+	0xB22C, 0x87C3, 0xB22D, 0x87C4, 0xB22E, 0x87C5, 0xB22F, 0x87C6,
+	0xB230, 0x87C7, 0xB231, 0x87C8, 0xB232, 0x87C9, 0xB233, 0x87CA,
+	0xB234, 0xB4B3, 0xB235, 0x87CB, 0xB236, 0x87CC, 0xB237, 0x87CD,
+	0xB238, 0x87CE, 0xB239, 0x87CF, 0xB23A, 0x87D0, 0xB23B, 0x87D1,
+	0xB23C, 0xB4B4, 0xB23D, 0x87D2, 0xB23E, 0x87D3, 0xB23F, 0x87D4,
+	0xB240, 0x87D5, 0xB241, 0x87D6, 0xB242, 0x87D7, 0xB243, 0x87D8,
+	0xB244, 0x87D9, 0xB245, 0x87DA, 0xB246, 0x87DB, 0xB247, 0x87DC,
+	0xB248, 0x87DD, 0xB249, 0x87DE, 0xB24A, 0x87DF, 0xB24B, 0x87E0,
+	0xB24C, 0x87E1, 0xB24D, 0x87E2, 0xB24E, 0x87E3, 0xB24F, 0x87E4,
+	0xB250, 0x87E5, 0xB251, 0x87E6, 0xB252, 0x87E7, 0xB253, 0x87E8,
+	0xB254, 0x87E9, 0xB255, 0x87EA, 0xB256, 0x87EB, 0xB257, 0x87EC,
+	0xB258, 0xB4B5, 0xB259, 0x87ED, 0xB25A, 0x87EE, 0xB25B, 0x87EF,
+	0xB25C, 0xB4B6, 0xB25D, 0x87F0, 0xB25E, 0x87F1, 0xB25F, 0x87F2,
+	0xB260, 0xB4B7, 0xB261, 0x87F3, 0xB262, 0x87F4, 0xB263, 0x87F5,
+	0xB264, 0x87F6, 0xB265, 0x87F7, 0xB266, 0x87F8, 0xB267, 0x87F9,
+	0xB268, 0xB4B8, 0xB269, 0xB4B9, 0xB26A, 0x87FA, 0xB26B, 0x87FB,
+	0xB26C, 0x87FC, 0xB26D, 0x87FD, 0xB26E, 0x87FE, 0xB26F, 0x8841,
+	0xB270, 0x8842, 0xB271, 0x8843, 0xB272, 0x8844, 0xB273, 0x8845,
+	0xB274, 0xB4BA, 0xB275, 0xB4BB, 0xB276, 0x8846, 0xB277, 0x8847,
+	0xB278, 0x8848, 0xB279, 0x8849, 0xB27A, 0x884A, 0xB27B, 0x884B,
+	0xB27C, 0xB4BC, 0xB27D, 0x884C, 0xB27E, 0x884D, 0xB27F, 0x884E,
+	0xB280, 0x884F, 0xB281, 0x8850, 0xB282, 0x8851, 0xB283, 0x8852,
+	0xB284, 0xB4BD, 0xB285, 0xB4BE, 0xB286, 0x8853, 0xB287, 0x8854,
+	0xB288, 0x8855, 0xB289, 0xB4BF, 0xB28A, 0x8856, 0xB28B, 0x8857,
+	0xB28C, 0x8858, 0xB28D, 0x8859, 0xB28E, 0x885A, 0xB28F, 0x8861,
+	0xB290, 0xB4C0, 0xB291, 0xB4C1, 0xB292, 0x8862, 0xB293, 0x8863,
+	0xB294, 0xB4C2, 0xB295, 0x8864, 0xB296, 0x8865, 0xB297, 0x8866,
+	0xB298, 0xB4C3, 0xB299, 0xB4C4, 0xB29A, 0xB4C5, 0xB29B, 0x8867,
+	0xB29C, 0x8868, 0xB29D, 0x8869, 0xB29E, 0x886A, 0xB29F, 0x886B,
+	0xB2A0, 0xB4C6, 0xB2A1, 0xB4C7, 0xB2A2, 0x886C, 0xB2A3, 0xB4C8,
+	0xB2A4, 0x886D, 0xB2A5, 0xB4C9, 0xB2A6, 0xB4CA, 0xB2A7, 0x886E,
+	0xB2A8, 0x886F, 0xB2A9, 0x8870, 0xB2AA, 0xB4CB, 0xB2AB, 0x8871,
+	0xB2AC, 0xB4CC, 0xB2AD, 0x8872, 0xB2AE, 0x8873, 0xB2AF, 0x8874,
+	0xB2B0, 0xB4CD, 0xB2B1, 0x8875, 0xB2B2, 0x8876, 0xB2B3, 0x8877,
+	0xB2B4, 0xB4CE, 0xB2B5, 0x8878, 0xB2B6, 0x8879, 0xB2B7, 0x887A,
+	0xB2B8, 0x8881, 0xB2B9, 0x8882, 0xB2BA, 0x8883, 0xB2BB, 0x8884,
+	0xB2BC, 0x8885, 0xB2BD, 0x8886, 0xB2BE, 0x8887, 0xB2BF, 0x8888,
+	0xB2C0, 0x8889, 0xB2C1, 0x888A, 0xB2C2, 0x888B, 0xB2C3, 0x888C,
+	0xB2C4, 0x888D, 0xB2C5, 0x888E, 0xB2C6, 0x888F, 0xB2C7, 0x8890,
+	0xB2C8, 0xB4CF, 0xB2C9, 0xB4D0, 0xB2CA, 0x8891, 0xB2CB, 0x8892,
+	0xB2CC, 0xB4D1, 0xB2CD, 0x8893, 0xB2CE, 0x8894, 0xB2CF, 0x8895,
+	0xB2D0, 0xB4D2, 0xB2D1, 0x8896, 0xB2D2, 0xB4D3, 0xB2D3, 0x8897,
+	0xB2D4, 0x8898, 0xB2D5, 0x8899, 0xB2D6, 0x889A, 0xB2D7, 0x889B,
+	0xB2D8, 0xB4D4, 0xB2D9, 0xB4D5, 0xB2DA, 0x889C, 0xB2DB, 0xB4D6,
+	0xB2DC, 0x889D, 0xB2DD, 0xB4D7, 0xB2DE, 0x889E, 0xB2DF, 0x889F,
+	0xB2E0, 0x88A0, 0xB2E1, 0x88A1, 0xB2E2, 0xB4D8, 0xB2E3, 0x88A2,
+	0xB2E4, 0xB4D9, 0xB2E5, 0xB4DA, 0xB2E6, 0xB4DB, 0xB2E7, 0x88A3,
+	0xB2E8, 0xB4DC, 0xB2E9, 0x88A4, 0xB2EA, 0x88A5, 0xB2EB, 0xB4DD,
+	0xB2EC, 0xB4DE, 0xB2ED, 0xB4DF, 0xB2EE, 0xB4E0, 0xB2EF, 0xB4E1,
+	0xB2F0, 0x88A6, 0xB2F1, 0x88A7, 0xB2F2, 0x88A8, 0xB2F3, 0xB4E2,
+	0xB2F4, 0xB4E3, 0xB2F5, 0xB4E4, 0xB2F6, 0x88A9, 0xB2F7, 0xB4E5,
+	0xB2F8, 0xB4E6, 0xB2F9, 0xB4E7, 0xB2FA, 0xB4E8, 0xB2FB, 0xB4E9,
+	0xB2FC, 0x88AA, 0xB2FD, 0x88AB, 0xB2FE, 0x88AC, 0xB2FF, 0xB4EA,
+	0xB300, 0xB4EB, 0xB301, 0xB4EC, 0xB302, 0x88AD, 0xB303, 0x88AE,
+	0xB304, 0xB4ED, 0xB305, 0x88AF, 0xB306, 0x88B0, 0xB307, 0x88B1,
+	0xB308, 0xB4EE, 0xB309, 0x88B2, 0xB30A, 0x88B3, 0xB30B, 0x88B4,
+	0xB30C, 0x88B5, 0xB30D, 0x88B6, 0xB30E, 0x88B7, 0xB30F, 0x88B8,
+	0xB310, 0xB4EF, 0xB311, 0xB4F0, 0xB312, 0x88B9, 0xB313, 0xB4F1,
+	0xB314, 0xB4F2, 0xB315, 0xB4F3, 0xB316, 0x88BA, 0xB317, 0x88BB,
+	0xB318, 0x88BC, 0xB319, 0x88BD, 0xB31A, 0x88BE, 0xB31B, 0x88BF,
+	0xB31C, 0xB4F4, 0xB31D, 0x88C0, 0xB31E, 0x88C1, 0xB31F, 0x88C2,
+	0xB320, 0x88C3, 0xB321, 0x88C4, 0xB322, 0x88C5, 0xB323, 0x88C6,
+	0xB324, 0x88C7, 0xB325, 0x88C8, 0xB326, 0x88C9, 0xB327, 0x88CA,
+	0xB328, 0x88CB, 0xB329, 0x88CC, 0xB32A, 0x88CD, 0xB32B, 0x88CE,
+	0xB32C, 0x88CF, 0xB32D, 0x88D0, 0xB32E, 0x88D1, 0xB32F, 0x88D2,
+	0xB330, 0x88D3, 0xB331, 0x88D4, 0xB332, 0x88D5, 0xB333, 0x88D6,
+	0xB334, 0x88D7, 0xB335, 0x88D8, 0xB336, 0x88D9, 0xB337, 0x88DA,
+	0xB338, 0x88DB, 0xB339, 0x88DC, 0xB33A, 0x88DD, 0xB33B, 0x88DE,
+	0xB33C, 0x88DF, 0xB33D, 0x88E0, 0xB33E, 0x88E1, 0xB33F, 0x88E2,
+	0xB340, 0x88E3, 0xB341, 0x88E4, 0xB342, 0x88E5, 0xB343, 0x88E6,
+	0xB344, 0x88E7, 0xB345, 0x88E8, 0xB346, 0x88E9, 0xB347, 0x88EA,
+	0xB348, 0x88EB, 0xB349, 0x88EC, 0xB34A, 0x88ED, 0xB34B, 0x88EE,
+	0xB34C, 0x88EF, 0xB34D, 0x88F0, 0xB34E, 0x88F1, 0xB34F, 0x88F2,
+	0xB350, 0x88F3, 0xB351, 0x88F4, 0xB352, 0x88F5, 0xB353, 0x88F6,
+	0xB354, 0xB4F5, 0xB355, 0xB4F6, 0xB356, 0xB4F7, 0xB357, 0x88F7,
+	0xB358, 0xB4F8, 0xB359, 0x88F8, 0xB35A, 0x88F9, 0xB35B, 0xB4F9,
+	0xB35C, 0xB4FA, 0xB35D, 0x88FA, 0xB35E, 0xB4FB, 0xB35F, 0xB4FC,
+	0xB360, 0x88FB, 0xB361, 0x88FC, 0xB362, 0x88FD, 0xB363, 0x88FE,
+	0xB364, 0xB4FD, 0xB365, 0xB4FE, 0xB366, 0x8941, 0xB367, 0xB5A1,
+	0xB368, 0x8942, 0xB369, 0xB5A2, 0xB36A, 0x8943, 0xB36B, 0xB5A3,
+	0xB36C, 0x8944, 0xB36D, 0x8945, 0xB36E, 0xB5A4, 0xB36F, 0x8946,
+	0xB370, 0xB5A5, 0xB371, 0xB5A6, 0xB372, 0x8947, 0xB373, 0x8948,
+	0xB374, 0xB5A7, 0xB375, 0x8949, 0xB376, 0x894A, 0xB377, 0x894B,
+	0xB378, 0xB5A8, 0xB379, 0x894C, 0xB37A, 0x894D, 0xB37B, 0x894E,
+	0xB37C, 0x894F, 0xB37D, 0x8950, 0xB37E, 0x8951, 0xB37F, 0x8952,
+	0xB380, 0xB5A9, 0xB381, 0xB5AA, 0xB382, 0x8953, 0xB383, 0xB5AB,
+	0xB384, 0xB5AC, 0xB385, 0xB5AD, 0xB386, 0x8954, 0xB387, 0x8955,
+	0xB388, 0x8956, 0xB389, 0x8957, 0xB38A, 0x8958, 0xB38B, 0x8959,
+	0xB38C, 0xB5AE, 0xB38D, 0x895A, 0xB38E, 0x8961, 0xB38F, 0x8962,
+	0xB390, 0xB5AF, 0xB391, 0x8963, 0xB392, 0x8964, 0xB393, 0x8965,
+	0xB394, 0xB5B0, 0xB395, 0x8966, 0xB396, 0x8967, 0xB397, 0x8968,
+	0xB398, 0x8969, 0xB399, 0x896A, 0xB39A, 0x896B, 0xB39B, 0x896C,
+	0xB39C, 0x896D, 0xB39D, 0x896E, 0xB39E, 0x896F, 0xB39F, 0x8970,
+	0xB3A0, 0xB5B1, 0xB3A1, 0xB5B2, 0xB3A2, 0x8971, 0xB3A3, 0x8972,
+	0xB3A4, 0x8973, 0xB3A5, 0x8974, 0xB3A6, 0x8975, 0xB3A7, 0x8976,
+	0xB3A8, 0xB5B3, 0xB3A9, 0x8977, 0xB3AA, 0x8978, 0xB3AB, 0x8979,
+	0xB3AC, 0xB5B4, 0xB3AD, 0x897A, 0xB3AE, 0x8981, 0xB3AF, 0x8982,
+	0xB3B0, 0x8983, 0xB3B1, 0x8984, 0xB3B2, 0x8985, 0xB3B3, 0x8986,
+	0xB3B4, 0x8987, 0xB3B5, 0x8988, 0xB3B6, 0x8989, 0xB3B7, 0x898A,
+	0xB3B8, 0x898B, 0xB3B9, 0x898C, 0xB3BA, 0x898D, 0xB3BB, 0x898E,
+	0xB3BC, 0x898F, 0xB3BD, 0x8990, 0xB3BE, 0x8991, 0xB3BF, 0x8992,
+	0xB3C0, 0x8993, 0xB3C1, 0x8994, 0xB3C2, 0x8995, 0xB3C3, 0x8996,
+	0xB3C4, 0xB5B5, 0xB3C5, 0xB5B6, 0xB3C6, 0x8997, 0xB3C7, 0x8998,
+	0xB3C8, 0xB5B7, 0xB3C9, 0x8999, 0xB3CA, 0x899A, 0xB3CB, 0xB5B8,
+	0xB3CC, 0xB5B9, 0xB3CD, 0x899B, 0xB3CE, 0xB5BA, 0xB3CF, 0x899C,
+	0xB3D0, 0xB5BB, 0xB3D1, 0x899D, 0xB3D2, 0x899E, 0xB3D3, 0x899F,
+	0xB3D4, 0xB5BC, 0xB3D5, 0xB5BD, 0xB3D6, 0x89A0, 0xB3D7, 0xB5BE,
+	0xB3D8, 0x89A1, 0xB3D9, 0xB5BF, 0xB3DA, 0x89A2, 0xB3DB, 0xB5C0,
+	0xB3DC, 0x89A3, 0xB3DD, 0xB5C1, 0xB3DE, 0x89A4, 0xB3DF, 0x89A5,
+	0xB3E0, 0xB5C2, 0xB3E1, 0x89A6, 0xB3E2, 0x89A7, 0xB3E3, 0x89A8,
+	0xB3E4, 0xB5C3, 0xB3E5, 0x89A9, 0xB3E6, 0x89AA, 0xB3E7, 0x89AB,
+	0xB3E8, 0xB5C4, 0xB3E9, 0x89AC, 0xB3EA, 0x89AD, 0xB3EB, 0x89AE,
+	0xB3EC, 0x89AF, 0xB3ED, 0x89B0, 0xB3EE, 0x89B1, 0xB3EF, 0x89B2,
+	0xB3F0, 0x89B3, 0xB3F1, 0x89B4, 0xB3F2, 0x89B5, 0xB3F3, 0x89B6,
+	0xB3F4, 0x89B7, 0xB3F5, 0x89B8, 0xB3F6, 0x89B9, 0xB3F7, 0x89BA,
+	0xB3F8, 0x89BB, 0xB3F9, 0x89BC, 0xB3FA, 0x89BD, 0xB3FB, 0x89BE,
+	0xB3FC, 0xB5C5, 0xB3FD, 0x89BF, 0xB3FE, 0x89C0, 0xB3FF, 0x89C1,
+	0xB400, 0x89C2, 0xB401, 0x89C3, 0xB402, 0x89C4, 0xB403, 0x89C5,
+	0xB404, 0x89C6, 0xB405, 0x89C7, 0xB406, 0x89C8, 0xB407, 0x89C9,
+	0xB408, 0x89CA, 0xB409, 0x89CB, 0xB40A, 0x89CC, 0xB40B, 0x89CD,
+	0xB40C, 0x89CE, 0xB40D, 0x89CF, 0xB40E, 0x89D0, 0xB40F, 0x89D1,
+	0xB410, 0xB5C6, 0xB411, 0x89D2, 0xB412, 0x89D3, 0xB413, 0x89D4,
+	0xB414, 0x89D5, 0xB415, 0x89D6, 0xB416, 0x89D7, 0xB417, 0x89D8,
+	0xB418, 0xB5C7, 0xB419, 0x89D9, 0xB41A, 0x89DA, 0xB41B, 0x89DB,
+	0xB41C, 0xB5C8, 0xB41D, 0x89DC, 0xB41E, 0x89DD, 0xB41F, 0x89DE,
+	0xB420, 0xB5C9, 0xB421, 0x89DF, 0xB422, 0x89E0, 0xB423, 0x89E1,
+	0xB424, 0x89E2, 0xB425, 0x89E3, 0xB426, 0x89E4, 0xB427, 0x89E5,
+	0xB428, 0xB5CA, 0xB429, 0xB5CB, 0xB42A, 0x89E6, 0xB42B, 0xB5CC,
+	0xB42C, 0x89E7, 0xB42D, 0x89E8, 0xB42E, 0x89E9, 0xB42F, 0x89EA,
+	0xB430, 0x89EB, 0xB431, 0x89EC, 0xB432, 0x89ED, 0xB433, 0x89EE,
+	0xB434, 0xB5CD, 0xB435, 0x89EF, 0xB436, 0x89F0, 0xB437, 0x89F1,
+	0xB438, 0x89F2, 0xB439, 0x89F3, 0xB43A, 0x89F4, 0xB43B, 0x89F5,
+	0xB43C, 0x89F6, 0xB43D, 0x89F7, 0xB43E, 0x89F8, 0xB43F, 0x89F9,
+	0xB440, 0x89FA, 0xB441, 0x89FB, 0xB442, 0x89FC, 0xB443, 0x89FD,
+	0xB444, 0x89FE, 0xB445, 0x8A41, 0xB446, 0x8A42, 0xB447, 0x8A43,
+	0xB448, 0x8A44, 0xB449, 0x8A45, 0xB44A, 0x8A46, 0xB44B, 0x8A47,
+	0xB44C, 0x8A48, 0xB44D, 0x8A49, 0xB44E, 0x8A4A, 0xB44F, 0x8A4B,
+	0xB450, 0xB5CE, 0xB451, 0xB5CF, 0xB452, 0x8A4C, 0xB453, 0x8A4D,
+	0xB454, 0xB5D0, 0xB455, 0x8A4E, 0xB456, 0x8A4F, 0xB457, 0x8A50,
+	0xB458, 0xB5D1, 0xB459, 0x8A51, 0xB45A, 0x8A52, 0xB45B, 0x8A53,
+	0xB45C, 0x8A54, 0xB45D, 0x8A55, 0xB45E, 0x8A56, 0xB45F, 0x8A57,
+	0xB460, 0xB5D2, 0xB461, 0xB5D3, 0xB462, 0x8A58, 0xB463, 0xB5D4,
+	0xB464, 0x8A59, 0xB465, 0xB5D5, 0xB466, 0x8A5A, 0xB467, 0x8A61,
+	0xB468, 0x8A62, 0xB469, 0x8A63, 0xB46A, 0x8A64, 0xB46B, 0x8A65,
+	0xB46C, 0xB5D6, 0xB46D, 0x8A66, 0xB46E, 0x8A67, 0xB46F, 0x8A68,
+	0xB470, 0x8A69, 0xB471, 0x8A6A, 0xB472, 0x8A6B, 0xB473, 0x8A6C,
+	0xB474, 0x8A6D, 0xB475, 0x8A6E, 0xB476, 0x8A6F, 0xB477, 0x8A70,
+	0xB478, 0x8A71, 0xB479, 0x8A72, 0xB47A, 0x8A73, 0xB47B, 0x8A74,
+	0xB47C, 0x8A75, 0xB47D, 0x8A76, 0xB47E, 0x8A77, 0xB47F, 0x8A78,
+	0xB480, 0xB5D7, 0xB481, 0x8A79, 0xB482, 0x8A7A, 0xB483, 0x8A81,
+	0xB484, 0x8A82, 0xB485, 0x8A83, 0xB486, 0x8A84, 0xB487, 0x8A85,
+	0xB488, 0xB5D8, 0xB489, 0x8A86, 0xB48A, 0x8A87, 0xB48B, 0x8A88,
+	0xB48C, 0x8A89, 0xB48D, 0x8A8A, 0xB48E, 0x8A8B, 0xB48F, 0x8A8C,
+	0xB490, 0x8A8D, 0xB491, 0x8A8E, 0xB492, 0x8A8F, 0xB493, 0x8A90,
+	0xB494, 0x8A91, 0xB495, 0x8A92, 0xB496, 0x8A93, 0xB497, 0x8A94,
+	0xB498, 0x8A95, 0xB499, 0x8A96, 0xB49A, 0x8A97, 0xB49B, 0x8A98,
+	0xB49C, 0x8A99, 0xB49D, 0xB5D9, 0xB49E, 0x8A9A, 0xB49F, 0x8A9B,
+	0xB4A0, 0x8A9C, 0xB4A1, 0x8A9D, 0xB4A2, 0x8A9E, 0xB4A3, 0x8A9F,
+	0xB4A4, 0xB5DA, 0xB4A5, 0x8AA0, 0xB4A6, 0x8AA1, 0xB4A7, 0x8AA2,
+	0xB4A8, 0xB5DB, 0xB4A9, 0x8AA3, 0xB4AA, 0x8AA4, 0xB4AB, 0x8AA5,
+	0xB4AC, 0xB5DC, 0xB4AD, 0x8AA6, 0xB4AE, 0x8AA7, 0xB4AF, 0x8AA8,
+	0xB4B0, 0x8AA9, 0xB4B1, 0x8AAA, 0xB4B2, 0x8AAB, 0xB4B3, 0x8AAC,
+	0xB4B4, 0x8AAD, 0xB4B5, 0xB5DD, 0xB4B6, 0x8AAE, 0xB4B7, 0xB5DE,
+	0xB4B8, 0x8AAF, 0xB4B9, 0xB5DF, 0xB4BA, 0x8AB0, 0xB4BB, 0x8AB1,
+	0xB4BC, 0x8AB2, 0xB4BD, 0x8AB3, 0xB4BE, 0x8AB4, 0xB4BF, 0x8AB5,
+	0xB4C0, 0xB5E0, 0xB4C1, 0x8AB6, 0xB4C2, 0x8AB7, 0xB4C3, 0x8AB8,
+	0xB4C4, 0xB5E1, 0xB4C5, 0x8AB9, 0xB4C6, 0x8ABA, 0xB4C7, 0x8ABB,
+	0xB4C8, 0xB5E2, 0xB4C9, 0x8ABC, 0xB4CA, 0x8ABD, 0xB4CB, 0x8ABE,
+	0xB4CC, 0x8ABF, 0xB4CD, 0x8AC0, 0xB4CE, 0x8AC1, 0xB4CF, 0x8AC2,
+	0xB4D0, 0xB5E3, 0xB4D1, 0x8AC3, 0xB4D2, 0x8AC4, 0xB4D3, 0x8AC5,
+	0xB4D4, 0x8AC6, 0xB4D5, 0xB5E4, 0xB4D6, 0x8AC7, 0xB4D7, 0x8AC8,
+	0xB4D8, 0x8AC9, 0xB4D9, 0x8ACA, 0xB4DA, 0x8ACB, 0xB4DB, 0x8ACC,
+	0xB4DC, 0xB5E5, 0xB4DD, 0xB5E6, 0xB4DE, 0x8ACD, 0xB4DF, 0x8ACE,
+	0xB4E0, 0xB5E7, 0xB4E1, 0x8ACF, 0xB4E2, 0x8AD0, 0xB4E3, 0xB5E8,
+	0xB4E4, 0xB5E9, 0xB4E5, 0x8AD1, 0xB4E6, 0xB5EA, 0xB4E7, 0x8AD2,
+	0xB4E8, 0x8AD3, 0xB4E9, 0x8AD4, 0xB4EA, 0x8AD5, 0xB4EB, 0x8AD6,
+	0xB4EC, 0xB5EB, 0xB4ED, 0xB5EC, 0xB4EE, 0x8AD7, 0xB4EF, 0xB5ED,
+	0xB4F0, 0x8AD8, 0xB4F1, 0xB5EE, 0xB4F2, 0x8AD9, 0xB4F3, 0x8ADA,
+	0xB4F4, 0x8ADB, 0xB4F5, 0x8ADC, 0xB4F6, 0x8ADD, 0xB4F7, 0x8ADE,
+	0xB4F8, 0xB5EF, 0xB4F9, 0x8ADF, 0xB4FA, 0x8AE0, 0xB4FB, 0x8AE1,
+	0xB4FC, 0x8AE2, 0xB4FD, 0x8AE3, 0xB4FE, 0x8AE4, 0xB4FF, 0x8AE5,
+	0xB500, 0x8AE6, 0xB501, 0x8AE7, 0xB502, 0x8AE8, 0xB503, 0x8AE9,
+	0xB504, 0x8AEA, 0xB505, 0x8AEB, 0xB506, 0x8AEC, 0xB507, 0x8AED,
+	0xB508, 0x8AEE, 0xB509, 0x8AEF, 0xB50A, 0x8AF0, 0xB50B, 0x8AF1,
+	0xB50C, 0x8AF2, 0xB50D, 0x8AF3, 0xB50E, 0x8AF4, 0xB50F, 0x8AF5,
+	0xB510, 0x8AF6, 0xB511, 0x8AF7, 0xB512, 0x8AF8, 0xB513, 0x8AF9,
+	0xB514, 0xB5F0, 0xB515, 0xB5F1, 0xB516, 0x8AFA, 0xB517, 0x8AFB,
+	0xB518, 0xB5F2, 0xB519, 0x8AFC, 0xB51A, 0x8AFD, 0xB51B, 0xB5F3,
+	0xB51C, 0xB5F4, 0xB51D, 0x8AFE, 0xB51E, 0x8B41, 0xB51F, 0x8B42,
+	0xB520, 0x8B43, 0xB521, 0x8B44, 0xB522, 0x8B45, 0xB523, 0x8B46,
+	0xB524, 0xB5F5, 0xB525, 0xB5F6, 0xB526, 0x8B47, 0xB527, 0xB5F7,
+	0xB528, 0xB5F8, 0xB529, 0xB5F9, 0xB52A, 0xB5FA, 0xB52B, 0x8B48,
+	0xB52C, 0x8B49, 0xB52D, 0x8B4A, 0xB52E, 0x8B4B, 0xB52F, 0x8B4C,
+	0xB530, 0xB5FB, 0xB531, 0xB5FC, 0xB532, 0x8B4D, 0xB533, 0x8B4E,
+	0xB534, 0xB5FD, 0xB535, 0x8B4F, 0xB536, 0x8B50, 0xB537, 0x8B51,
+	0xB538, 0xB5FE, 0xB539, 0x8B52, 0xB53A, 0x8B53, 0xB53B, 0x8B54,
+	0xB53C, 0x8B55, 0xB53D, 0x8B56, 0xB53E, 0x8B57, 0xB53F, 0x8B58,
+	0xB540, 0xB6A1, 0xB541, 0xB6A2, 0xB542, 0x8B59, 0xB543, 0xB6A3,
+	0xB544, 0xB6A4, 0xB545, 0xB6A5, 0xB546, 0x8B5A, 0xB547, 0x8B61,
+	0xB548, 0x8B62, 0xB549, 0x8B63, 0xB54A, 0x8B64, 0xB54B, 0xB6A6,
+	0xB54C, 0xB6A7, 0xB54D, 0xB6A8, 0xB54E, 0x8B65, 0xB54F, 0x8B66,
+	0xB550, 0xB6A9, 0xB551, 0x8B67, 0xB552, 0x8B68, 0xB553, 0x8B69,
+	0xB554, 0xB6AA, 0xB555, 0x8B6A, 0xB556, 0x8B6B, 0xB557, 0x8B6C,
+	0xB558, 0x8B6D, 0xB559, 0x8B6E, 0xB55A, 0x8B6F, 0xB55B, 0x8B70,
+	0xB55C, 0xB6AB, 0xB55D, 0xB6AC, 0xB55E, 0x8B71, 0xB55F, 0xB6AD,
+	0xB560, 0xB6AE, 0xB561, 0xB6AF, 0xB562, 0x8B72, 0xB563, 0x8B73,
+	0xB564, 0x8B74, 0xB565, 0x8B75, 0xB566, 0x8B76, 0xB567, 0x8B77,
+	0xB568, 0x8B78, 0xB569, 0x8B79, 0xB56A, 0x8B7A, 0xB56B, 0x8B81,
+	0xB56C, 0x8B82, 0xB56D, 0x8B83, 0xB56E, 0x8B84, 0xB56F, 0x8B85,
+	0xB570, 0x8B86, 0xB571, 0x8B87, 0xB572, 0x8B88, 0xB573, 0x8B89,
+	0xB574, 0x8B8A, 0xB575, 0x8B8B, 0xB576, 0x8B8C, 0xB577, 0x8B8D,
+	0xB578, 0x8B8E, 0xB579, 0x8B8F, 0xB57A, 0x8B90, 0xB57B, 0x8B91,
+	0xB57C, 0x8B92, 0xB57D, 0x8B93, 0xB57E, 0x8B94, 0xB57F, 0x8B95,
+	0xB580, 0x8B96, 0xB581, 0x8B97, 0xB582, 0x8B98, 0xB583, 0x8B99,
+	0xB584, 0x8B9A, 0xB585, 0x8B9B, 0xB586, 0x8B9C, 0xB587, 0x8B9D,
+	0xB588, 0x8B9E, 0xB589, 0x8B9F, 0xB58A, 0x8BA0, 0xB58B, 0x8BA1,
+	0xB58C, 0x8BA2, 0xB58D, 0x8BA3, 0xB58E, 0x8BA4, 0xB58F, 0x8BA5,
+	0xB590, 0x8BA6, 0xB591, 0x8BA7, 0xB592, 0x8BA8, 0xB593, 0x8BA9,
+	0xB594, 0x8BAA, 0xB595, 0x8BAB, 0xB596, 0x8BAC, 0xB597, 0x8BAD,
+	0xB598, 0x8BAE, 0xB599, 0x8BAF, 0xB59A, 0x8BB0, 0xB59B, 0x8BB1,
+	0xB59C, 0x8BB2, 0xB59D, 0x8BB3, 0xB59E, 0x8BB4, 0xB59F, 0x8BB5,
+	0xB5A0, 0xB6B0, 0xB5A1, 0xB6B1, 0xB5A2, 0x8BB6, 0xB5A3, 0x8BB7,
+	0xB5A4, 0xB6B2, 0xB5A5, 0x8BB8, 0xB5A6, 0x8BB9, 0xB5A7, 0x8BBA,
+	0xB5A8, 0xB6B3, 0xB5A9, 0x8BBB, 0xB5AA, 0xB6B4, 0xB5AB, 0xB6B5,
+	0xB5AC, 0x8BBC, 0xB5AD, 0x8BBD, 0xB5AE, 0x8BBE, 0xB5AF, 0x8BBF,
+	0xB5B0, 0xB6B6, 0xB5B1, 0xB6B7, 0xB5B2, 0x8BC0, 0xB5B3, 0xB6B8,
+	0xB5B4, 0xB6B9, 0xB5B5, 0xB6BA, 0xB5B6, 0x8BC1, 0xB5B7, 0x8BC2,
+	0xB5B8, 0x8BC3, 0xB5B9, 0x8BC4, 0xB5BA, 0x8BC5, 0xB5BB, 0xB6BB,
+	0xB5BC, 0xB6BC, 0xB5BD, 0xB6BD, 0xB5BE, 0x8BC6, 0xB5BF, 0x8BC7,
+	0xB5C0, 0xB6BE, 0xB5C1, 0x8BC8, 0xB5C2, 0x8BC9, 0xB5C3, 0x8BCA,
+	0xB5C4, 0xB6BF, 0xB5C5, 0x8BCB, 0xB5C6, 0x8BCC, 0xB5C7, 0x8BCD,
+	0xB5C8, 0x8BCE, 0xB5C9, 0x8BCF, 0xB5CA, 0x8BD0, 0xB5CB, 0x8BD1,
+	0xB5CC, 0xB6C0, 0xB5CD, 0xB6C1, 0xB5CE, 0x8BD2, 0xB5CF, 0xB6C2,
+	0xB5D0, 0xB6C3, 0xB5D1, 0xB6C4, 0xB5D2, 0x8BD3, 0xB5D3, 0x8BD4,
+	0xB5D4, 0x8BD5, 0xB5D5, 0x8BD6, 0xB5D6, 0x8BD7, 0xB5D7, 0x8BD8,
+	0xB5D8, 0xB6C5, 0xB5D9, 0x8BD9, 0xB5DA, 0x8BDA, 0xB5DB, 0x8BDB,
+	0xB5DC, 0x8BDC, 0xB5DD, 0x8BDD, 0xB5DE, 0x8BDE, 0xB5DF, 0x8BDF,
+	0xB5E0, 0x8BE0, 0xB5E1, 0x8BE1, 0xB5E2, 0x8BE2, 0xB5E3, 0x8BE3,
+	0xB5E4, 0x8BE4, 0xB5E5, 0x8BE5, 0xB5E6, 0x8BE6, 0xB5E7, 0x8BE7,
+	0xB5E8, 0x8BE8, 0xB5E9, 0x8BE9, 0xB5EA, 0x8BEA, 0xB5EB, 0x8BEB,
+	0xB5EC, 0xB6C6, 0xB5ED, 0x8BEC, 0xB5EE, 0x8BED, 0xB5EF, 0x8BEE,
+	0xB5F0, 0x8BEF, 0xB5F1, 0x8BF0, 0xB5F2, 0x8BF1, 0xB5F3, 0x8BF2,
+	0xB5F4, 0x8BF3, 0xB5F5, 0x8BF4, 0xB5F6, 0x8BF5, 0xB5F7, 0x8BF6,
+	0xB5F8, 0x8BF7, 0xB5F9, 0x8BF8, 0xB5FA, 0x8BF9, 0xB5FB, 0x8BFA,
+	0xB5FC, 0x8BFB, 0xB5FD, 0x8BFC, 0xB5FE, 0x8BFD, 0xB5FF, 0x8BFE,
+	0xB600, 0x8C41, 0xB601, 0x8C42, 0xB602, 0x8C43, 0xB603, 0x8C44,
+	0xB604, 0x8C45, 0xB605, 0x8C46, 0xB606, 0x8C47, 0xB607, 0x8C48,
+	0xB608, 0x8C49, 0xB609, 0x8C4A, 0xB60A, 0x8C4B, 0xB60B, 0x8C4C,
+	0xB60C, 0x8C4D, 0xB60D, 0x8C4E, 0xB60E, 0x8C4F, 0xB60F, 0x8C50,
+	0xB610, 0xB6C7, 0xB611, 0xB6C8, 0xB612, 0x8C51, 0xB613, 0x8C52,
+	0xB614, 0xB6C9, 0xB615, 0x8C53, 0xB616, 0x8C54, 0xB617, 0x8C55,
+	0xB618, 0xB6CA, 0xB619, 0x8C56, 0xB61A, 0x8C57, 0xB61B, 0x8C58,
+	0xB61C, 0x8C59, 0xB61D, 0x8C5A, 0xB61E, 0x8C61, 0xB61F, 0x8C62,
+	0xB620, 0x8C63, 0xB621, 0x8C64, 0xB622, 0x8C65, 0xB623, 0x8C66,
+	0xB624, 0x8C67, 0xB625, 0xB6CB, 0xB626, 0x8C68, 0xB627, 0x8C69,
+	0xB628, 0x8C6A, 0xB629, 0x8C6B, 0xB62A, 0x8C6C, 0xB62B, 0x8C6D,
+	0xB62C, 0xB6CC, 0xB62D, 0x8C6E, 0xB62E, 0x8C6F, 0xB62F, 0x8C70,
+	0xB630, 0x8C71, 0xB631, 0x8C72, 0xB632, 0x8C73, 0xB633, 0x8C74,
+	0xB634, 0xB6CD, 0xB635, 0x8C75, 0xB636, 0x8C76, 0xB637, 0x8C77,
+	0xB638, 0x8C78, 0xB639, 0x8C79, 0xB63A, 0x8C7A, 0xB63B, 0x8C81,
+	0xB63C, 0x8C82, 0xB63D, 0x8C83, 0xB63E, 0x8C84, 0xB63F, 0x8C85,
+	0xB640, 0x8C86, 0xB641, 0x8C87, 0xB642, 0x8C88, 0xB643, 0x8C89,
+	0xB644, 0x8C8A, 0xB645, 0x8C8B, 0xB646, 0x8C8C, 0xB647, 0x8C8D,
+	0xB648, 0xB6CE, 0xB649, 0x8C8E, 0xB64A, 0x8C8F, 0xB64B, 0x8C90,
+	0xB64C, 0x8C91, 0xB64D, 0x8C92, 0xB64E, 0x8C93, 0xB64F, 0x8C94,
+	0xB650, 0x8C95, 0xB651, 0x8C96, 0xB652, 0x8C97, 0xB653, 0x8C98,
+	0xB654, 0x8C99, 0xB655, 0x8C9A, 0xB656, 0x8C9B, 0xB657, 0x8C9C,
+	0xB658, 0x8C9D, 0xB659, 0x8C9E, 0xB65A, 0x8C9F, 0xB65B, 0x8CA0,
+	0xB65C, 0x8CA1, 0xB65D, 0x8CA2, 0xB65E, 0x8CA3, 0xB65F, 0x8CA4,
+	0xB660, 0x8CA5, 0xB661, 0x8CA6, 0xB662, 0x8CA7, 0xB663, 0x8CA8,
+	0xB664, 0xB6CF, 0xB665, 0x8CA9, 0xB666, 0x8CAA, 0xB667, 0x8CAB,
+	0xB668, 0xB6D0, 0xB669, 0x8CAC, 0xB66A, 0x8CAD, 0xB66B, 0x8CAE,
+	0xB66C, 0x8CAF, 0xB66D, 0x8CB0, 0xB66E, 0x8CB1, 0xB66F, 0x8CB2,
+	0xB670, 0x8CB3, 0xB671, 0x8CB4, 0xB672, 0x8CB5, 0xB673, 0x8CB6,
+	0xB674, 0x8CB7, 0xB675, 0x8CB8, 0xB676, 0x8CB9, 0xB677, 0x8CBA,
+	0xB678, 0x8CBB, 0xB679, 0x8CBC, 0xB67A, 0x8CBD, 0xB67B, 0x8CBE,
+	0xB67C, 0x8CBF, 0xB67D, 0x8CC0, 0xB67E, 0x8CC1, 0xB67F, 0x8CC2,
+	0xB680, 0x8CC3, 0xB681, 0x8CC4, 0xB682, 0x8CC5, 0xB683, 0x8CC6,
+	0xB684, 0x8CC7, 0xB685, 0x8CC8, 0xB686, 0x8CC9, 0xB687, 0x8CCA,
+	0xB688, 0x8CCB, 0xB689, 0x8CCC, 0xB68A, 0x8CCD, 0xB68B, 0x8CCE,
+	0xB68C, 0x8CCF, 0xB68D, 0x8CD0, 0xB68E, 0x8CD1, 0xB68F, 0x8CD2,
+	0xB690, 0x8CD3, 0xB691, 0x8CD4, 0xB692, 0x8CD5, 0xB693, 0x8CD6,
+	0xB694, 0x8CD7, 0xB695, 0x8CD8, 0xB696, 0x8CD9, 0xB697, 0x8CDA,
+	0xB698, 0x8CDB, 0xB699, 0x8CDC, 0xB69A, 0x8CDD, 0xB69B, 0x8CDE,
+	0xB69C, 0xB6D1, 0xB69D, 0xB6D2, 0xB69E, 0x8CDF, 0xB69F, 0x8CE0,
+	0xB6A0, 0xB6D3, 0xB6A1, 0x8CE1, 0xB6A2, 0x8CE2, 0xB6A3, 0x8CE3,
+	0xB6A4, 0xB6D4, 0xB6A5, 0x8CE4, 0xB6A6, 0x8CE5, 0xB6A7, 0x8CE6,
+	0xB6A8, 0x8CE7, 0xB6A9, 0x8CE8, 0xB6AA, 0x8CE9, 0xB6AB, 0xB6D5,
+	0xB6AC, 0xB6D6, 0xB6AD, 0x8CEA, 0xB6AE, 0x8CEB, 0xB6AF, 0x8CEC,
+	0xB6B0, 0x8CED, 0xB6B1, 0xB6D7, 0xB6B2, 0x8CEE, 0xB6B3, 0x8CEF,
+	0xB6B4, 0x8CF0, 0xB6B5, 0x8CF1, 0xB6B6, 0x8CF2, 0xB6B7, 0x8CF3,
+	0xB6B8, 0x8CF4, 0xB6B9, 0x8CF5, 0xB6BA, 0x8CF6, 0xB6BB, 0x8CF7,
+	0xB6BC, 0x8CF8, 0xB6BD, 0x8CF9, 0xB6BE, 0x8CFA, 0xB6BF, 0x8CFB,
+	0xB6C0, 0x8CFC, 0xB6C1, 0x8CFD, 0xB6C2, 0x8CFE, 0xB6C3, 0x8D41,
+	0xB6C4, 0x8D42, 0xB6C5, 0x8D43, 0xB6C6, 0x8D44, 0xB6C7, 0x8D45,
+	0xB6C8, 0x8D46, 0xB6C9, 0x8D47, 0xB6CA, 0x8D48, 0xB6CB, 0x8D49,
+	0xB6CC, 0x8D4A, 0xB6CD, 0x8D4B, 0xB6CE, 0x8D4C, 0xB6CF, 0x8D4D,
+	0xB6D0, 0x8D4E, 0xB6D1, 0x8D4F, 0xB6D2, 0x8D50, 0xB6D3, 0x8D51,
+	0xB6D4, 0xB6D8, 0xB6D5, 0x8D52, 0xB6D6, 0x8D53, 0xB6D7, 0x8D54,
+	0xB6D8, 0x8D55, 0xB6D9, 0x8D56, 0xB6DA, 0x8D57, 0xB6DB, 0x8D58,
+	0xB6DC, 0x8D59, 0xB6DD, 0x8D5A, 0xB6DE, 0x8D61, 0xB6DF, 0x8D62,
+	0xB6E0, 0x8D63, 0xB6E1, 0x8D64, 0xB6E2, 0x8D65, 0xB6E3, 0x8D66,
+	0xB6E4, 0x8D67, 0xB6E5, 0x8D68, 0xB6E6, 0x8D69, 0xB6E7, 0x8D6A,
+	0xB6E8, 0x8D6B, 0xB6E9, 0x8D6C, 0xB6EA, 0x8D6D, 0xB6EB, 0x8D6E,
+	0xB6EC, 0x8D6F, 0xB6ED, 0x8D70, 0xB6EE, 0x8D71, 0xB6EF, 0x8D72,
+	0xB6F0, 0xB6D9, 0xB6F1, 0x8D73, 0xB6F2, 0x8D74, 0xB6F3, 0x8D75,
+	0xB6F4, 0xB6DA, 0xB6F5, 0x8D76, 0xB6F6, 0x8D77, 0xB6F7, 0x8D78,
+	0xB6F8, 0xB6DB, 0xB6F9, 0x8D79, 0xB6FA, 0x8D7A, 0xB6FB, 0x8D81,
+	0xB6FC, 0x8D82, 0xB6FD, 0x8D83, 0xB6FE, 0x8D84, 0xB6FF, 0x8D85,
+	0xB700, 0xB6DC, 0xB701, 0xB6DD, 0xB702, 0x8D86, 0xB703, 0x8D87,
+	0xB704, 0x8D88, 0xB705, 0xB6DE, 0xB706, 0x8D89, 0xB707, 0x8D8A,
+	0xB708, 0x8D8B, 0xB709, 0x8D8C, 0xB70A, 0x8D8D, 0xB70B, 0x8D8E,
+	0xB70C, 0x8D8F, 0xB70D, 0x8D90, 0xB70E, 0x8D91, 0xB70F, 0x8D92,
+	0xB710, 0x8D93, 0xB711, 0x8D94, 0xB712, 0x8D95, 0xB713, 0x8D96,
+	0xB714, 0x8D97, 0xB715, 0x8D98, 0xB716, 0x8D99, 0xB717, 0x8D9A,
+	0xB718, 0x8D9B, 0xB719, 0x8D9C, 0xB71A, 0x8D9D, 0xB71B, 0x8D9E,
+	0xB71C, 0x8D9F, 0xB71D, 0x8DA0, 0xB71E, 0x8DA1, 0xB71F, 0x8DA2,
+	0xB720, 0x8DA3, 0xB721, 0x8DA4, 0xB722, 0x8DA5, 0xB723, 0x8DA6,
+	0xB724, 0x8DA7, 0xB725, 0x8DA8, 0xB726, 0x8DA9, 0xB727, 0x8DAA,
+	0xB728, 0xB6DF, 0xB729, 0xB6E0, 0xB72A, 0x8DAB, 0xB72B, 0x8DAC,
+	0xB72C, 0xB6E1, 0xB72D, 0x8DAD, 0xB72E, 0x8DAE, 0xB72F, 0xB6E2,
+	0xB730, 0xB6E3, 0xB731, 0x8DAF, 0xB732, 0x8DB0, 0xB733, 0x8DB1,
+	0xB734, 0x8DB2, 0xB735, 0x8DB3, 0xB736, 0x8DB4, 0xB737, 0x8DB5,
+	0xB738, 0xB6E4, 0xB739, 0xB6E5, 0xB73A, 0x8DB6, 0xB73B, 0xB6E6,
+	0xB73C, 0x8DB7, 0xB73D, 0x8DB8, 0xB73E, 0x8DB9, 0xB73F, 0x8DBA,
+	0xB740, 0x8DBB, 0xB741, 0x8DBC, 0xB742, 0x8DBD, 0xB743, 0x8DBE,
+	0xB744, 0xB6E7, 0xB745, 0x8DBF, 0xB746, 0x8DC0, 0xB747, 0x8DC1,
+	0xB748, 0xB6E8, 0xB749, 0x8DC2, 0xB74A, 0x8DC3, 0xB74B, 0x8DC4,
+	0xB74C, 0xB6E9, 0xB74D, 0x8DC5, 0xB74E, 0x8DC6, 0xB74F, 0x8DC7,
+	0xB750, 0x8DC8, 0xB751, 0x8DC9, 0xB752, 0x8DCA, 0xB753, 0x8DCB,
+	0xB754, 0xB6EA, 0xB755, 0xB6EB, 0xB756, 0x8DCC, 0xB757, 0x8DCD,
+	0xB758, 0x8DCE, 0xB759, 0x8DCF, 0xB75A, 0x8DD0, 0xB75B, 0x8DD1,
+	0xB75C, 0x8DD2, 0xB75D, 0x8DD3, 0xB75E, 0x8DD4, 0xB75F, 0x8DD5,
+	0xB760, 0xB6EC, 0xB761, 0x8DD6, 0xB762, 0x8DD7, 0xB763, 0x8DD8,
+	0xB764, 0xB6ED, 0xB765, 0x8DD9, 0xB766, 0x8DDA, 0xB767, 0x8DDB,
+	0xB768, 0xB6EE, 0xB769, 0x8DDC, 0xB76A, 0x8DDD, 0xB76B, 0x8DDE,
+	0xB76C, 0x8DDF, 0xB76D, 0x8DE0, 0xB76E, 0x8DE1, 0xB76F, 0x8DE2,
+	0xB770, 0xB6EF, 0xB771, 0xB6F0, 0xB772, 0x8DE3, 0xB773, 0xB6F1,
+	0xB774, 0x8DE4, 0xB775, 0xB6F2, 0xB776, 0x8DE5, 0xB777, 0x8DE6,
+	0xB778, 0x8DE7, 0xB779, 0x8DE8, 0xB77A, 0x8DE9, 0xB77B, 0x8DEA,
+	0xB77C, 0xB6F3, 0xB77D, 0xB6F4, 0xB77E, 0x8DEB, 0xB77F, 0x8DEC,
+	0xB780, 0xB6F5, 0xB781, 0x8DED, 0xB782, 0x8DEE, 0xB783, 0x8DEF,
+	0xB784, 0xB6F6, 0xB785, 0x8DF0, 0xB786, 0x8DF1, 0xB787, 0x8DF2,
+	0xB788, 0x8DF3, 0xB789, 0x8DF4, 0xB78A, 0x8DF5, 0xB78B, 0x8DF6,
+	0xB78C, 0xB6F7, 0xB78D, 0xB6F8, 0xB78E, 0x8DF7, 0xB78F, 0xB6F9,
+	0xB790, 0xB6FA, 0xB791, 0xB6FB, 0xB792, 0xB6FC, 0xB793, 0x8DF8,
+	0xB794, 0x8DF9, 0xB795, 0x8DFA, 0xB796, 0xB6FD, 0xB797, 0xB6FE,
+	0xB798, 0xB7A1, 0xB799, 0xB7A2, 0xB79A, 0x8DFB, 0xB79B, 0x8DFC,
+	0xB79C, 0xB7A3, 0xB79D, 0x8DFD, 0xB79E, 0x8DFE, 0xB79F, 0x8E41,
+	0xB7A0, 0xB7A4, 0xB7A1, 0x8E42, 0xB7A2, 0x8E43, 0xB7A3, 0x8E44,
+	0xB7A4, 0x8E45, 0xB7A5, 0x8E46, 0xB7A6, 0x8E47, 0xB7A7, 0x8E48,
+	0xB7A8, 0xB7A5, 0xB7A9, 0xB7A6, 0xB7AA, 0x8E49, 0xB7AB, 0xB7A7,
+	0xB7AC, 0xB7A8, 0xB7AD, 0xB7A9, 0xB7AE, 0x8E4A, 0xB7AF, 0x8E4B,
+	0xB7B0, 0x8E4C, 0xB7B1, 0x8E4D, 0xB7B2, 0x8E4E, 0xB7B3, 0x8E4F,
+	0xB7B4, 0xB7AA, 0xB7B5, 0xB7AB, 0xB7B6, 0x8E50, 0xB7B7, 0x8E51,
+	0xB7B8, 0xB7AC, 0xB7B9, 0x8E52, 0xB7BA, 0x8E53, 0xB7BB, 0x8E54,
+	0xB7BC, 0x8E55, 0xB7BD, 0x8E56, 0xB7BE, 0x8E57, 0xB7BF, 0x8E58,
+	0xB7C0, 0x8E59, 0xB7C1, 0x8E5A, 0xB7C2, 0x8E61, 0xB7C3, 0x8E62,
+	0xB7C4, 0x8E63, 0xB7C5, 0x8E64, 0xB7C6, 0x8E65, 0xB7C7, 0xB7AD,
+	0xB7C8, 0x8E66, 0xB7C9, 0xB7AE, 0xB7CA, 0x8E67, 0xB7CB, 0x8E68,
+	0xB7CC, 0x8E69, 0xB7CD, 0x8E6A, 0xB7CE, 0x8E6B, 0xB7CF, 0x8E6C,
+	0xB7D0, 0x8E6D, 0xB7D1, 0x8E6E, 0xB7D2, 0x8E6F, 0xB7D3, 0x8E70,
+	0xB7D4, 0x8E71, 0xB7D5, 0x8E72, 0xB7D6, 0x8E73, 0xB7D7, 0x8E74,
+	0xB7D8, 0x8E75, 0xB7D9, 0x8E76, 0xB7DA, 0x8E77, 0xB7DB, 0x8E78,
+	0xB7DC, 0x8E79, 0xB7DD, 0x8E7A, 0xB7DE, 0x8E81, 0xB7DF, 0x8E82,
+	0xB7E0, 0x8E83, 0xB7E1, 0x8E84, 0xB7E2, 0x8E85, 0xB7E3, 0x8E86,
+	0xB7E4, 0x8E87, 0xB7E5, 0x8E88, 0xB7E6, 0x8E89, 0xB7E7, 0x8E8A,
+	0xB7E8, 0x8E8B, 0xB7E9, 0x8E8C, 0xB7EA, 0x8E8D, 0xB7EB, 0x8E8E,
+	0xB7EC, 0xB7AF, 0xB7ED, 0xB7B0, 0xB7EE, 0x8E8F, 0xB7EF, 0x8E90,
+	0xB7F0, 0xB7B1, 0xB7F1, 0x8E91, 0xB7F2, 0x8E92, 0xB7F3, 0x8E93,
+	0xB7F4, 0xB7B2, 0xB7F5, 0x8E94, 0xB7F6, 0x8E95, 0xB7F7, 0x8E96,
+	0xB7F8, 0x8E97, 0xB7F9, 0x8E98, 0xB7FA, 0x8E99, 0xB7FB, 0x8E9A,
+	0xB7FC, 0xB7B3, 0xB7FD, 0xB7B4, 0xB7FE, 0x8E9B, 0xB7FF, 0xB7B5,
+	0xB800, 0xB7B6, 0xB801, 0xB7B7, 0xB802, 0x8E9C, 0xB803, 0x8E9D,
+	0xB804, 0x8E9E, 0xB805, 0x8E9F, 0xB806, 0x8EA0, 0xB807, 0xB7B8,
+	0xB808, 0xB7B9, 0xB809, 0xB7BA, 0xB80A, 0x8EA1, 0xB80B, 0x8EA2,
+	0xB80C, 0xB7BB, 0xB80D, 0x8EA3, 0xB80E, 0x8EA4, 0xB80F, 0x8EA5,
+	0xB810, 0xB7BC, 0xB811, 0x8EA6, 0xB812, 0x8EA7, 0xB813, 0x8EA8,
+	0xB814, 0x8EA9, 0xB815, 0x8EAA, 0xB816, 0x8EAB, 0xB817, 0x8EAC,
+	0xB818, 0xB7BD, 0xB819, 0xB7BE, 0xB81A, 0x8EAD, 0xB81B, 0xB7BF,
+	0xB81C, 0x8EAE, 0xB81D, 0xB7C0, 0xB81E, 0x8EAF, 0xB81F, 0x8EB0,
+	0xB820, 0x8EB1, 0xB821, 0x8EB2, 0xB822, 0x8EB3, 0xB823, 0x8EB4,
+	0xB824, 0xB7C1, 0xB825, 0xB7C2, 0xB826, 0x8EB5, 0xB827, 0x8EB6,
+	0xB828, 0xB7C3, 0xB829, 0x8EB7, 0xB82A, 0x8EB8, 0xB82B, 0x8EB9,
+	0xB82C, 0xB7C4, 0xB82D, 0x8EBA, 0xB82E, 0x8EBB, 0xB82F, 0x8EBC,
+	0xB830, 0x8EBD, 0xB831, 0x8EBE, 0xB832, 0x8EBF, 0xB833, 0x8EC0,
+	0xB834, 0xB7C5, 0xB835, 0xB7C6, 0xB836, 0x8EC1, 0xB837, 0xB7C7,
+	0xB838, 0xB7C8, 0xB839, 0xB7C9, 0xB83A, 0x8EC2, 0xB83B, 0x8EC3,
+	0xB83C, 0x8EC4, 0xB83D, 0x8EC5, 0xB83E, 0x8EC6, 0xB83F, 0x8EC7,
+	0xB840, 0xB7CA, 0xB841, 0x8EC8, 0xB842, 0x8EC9, 0xB843, 0x8ECA,
+	0xB844, 0xB7CB, 0xB845, 0x8ECB, 0xB846, 0x8ECC, 0xB847, 0x8ECD,
+	0xB848, 0x8ECE, 0xB849, 0x8ECF, 0xB84A, 0x8ED0, 0xB84B, 0x8ED1,
+	0xB84C, 0x8ED2, 0xB84D, 0x8ED3, 0xB84E, 0x8ED4, 0xB84F, 0x8ED5,
+	0xB850, 0x8ED6, 0xB851, 0xB7CC, 0xB852, 0x8ED7, 0xB853, 0xB7CD,
+	0xB854, 0x8ED8, 0xB855, 0x8ED9, 0xB856, 0x8EDA, 0xB857, 0x8EDB,
+	0xB858, 0x8EDC, 0xB859, 0x8EDD, 0xB85A, 0x8EDE, 0xB85B, 0x8EDF,
+	0xB85C, 0xB7CE, 0xB85D, 0xB7CF, 0xB85E, 0x8EE0, 0xB85F, 0x8EE1,
+	0xB860, 0xB7D0, 0xB861, 0x8EE2, 0xB862, 0x8EE3, 0xB863, 0x8EE4,
+	0xB864, 0xB7D1, 0xB865, 0x8EE5, 0xB866, 0x8EE6, 0xB867, 0x8EE7,
+	0xB868, 0x8EE8, 0xB869, 0x8EE9, 0xB86A, 0x8EEA, 0xB86B, 0x8EEB,
+	0xB86C, 0xB7D2, 0xB86D, 0xB7D3, 0xB86E, 0x8EEC, 0xB86F, 0xB7D4,
+	0xB870, 0x8EED, 0xB871, 0xB7D5, 0xB872, 0x8EEE, 0xB873, 0x8EEF,
+	0xB874, 0x8EF0, 0xB875, 0x8EF1, 0xB876, 0x8EF2, 0xB877, 0x8EF3,
+	0xB878, 0xB7D6, 0xB879, 0x8EF4, 0xB87A, 0x8EF5, 0xB87B, 0x8EF6,
+	0xB87C, 0xB7D7, 0xB87D, 0x8EF7, 0xB87E, 0x8EF8, 0xB87F, 0x8EF9,
+	0xB880, 0x8EFA, 0xB881, 0x8EFB, 0xB882, 0x8EFC, 0xB883, 0x8EFD,
+	0xB884, 0x8EFE, 0xB885, 0x8F41, 0xB886, 0x8F42, 0xB887, 0x8F43,
+	0xB888, 0x8F44, 0xB889, 0x8F45, 0xB88A, 0x8F46, 0xB88B, 0x8F47,
+	0xB88C, 0x8F48, 0xB88D, 0xB7D8, 0xB88E, 0x8F49, 0xB88F, 0x8F4A,
+	0xB890, 0x8F4B, 0xB891, 0x8F4C, 0xB892, 0x8F4D, 0xB893, 0x8F4E,
+	0xB894, 0x8F4F, 0xB895, 0x8F50, 0xB896, 0x8F51, 0xB897, 0x8F52,
+	0xB898, 0x8F53, 0xB899, 0x8F54, 0xB89A, 0x8F55, 0xB89B, 0x8F56,
+	0xB89C, 0x8F57, 0xB89D, 0x8F58, 0xB89E, 0x8F59, 0xB89F, 0x8F5A,
+	0xB8A0, 0x8F61, 0xB8A1, 0x8F62, 0xB8A2, 0x8F63, 0xB8A3, 0x8F64,
+	0xB8A4, 0x8F65, 0xB8A5, 0x8F66, 0xB8A6, 0x8F67, 0xB8A7, 0x8F68,
+	0xB8A8, 0xB7D9, 0xB8A9, 0x8F69, 0xB8AA, 0x8F6A, 0xB8AB, 0x8F6B,
+	0xB8AC, 0x8F6C, 0xB8AD, 0x8F6D, 0xB8AE, 0x8F6E, 0xB8AF, 0x8F6F,
+	0xB8B0, 0xB7DA, 0xB8B1, 0x8F70, 0xB8B2, 0x8F71, 0xB8B3, 0x8F72,
+	0xB8B4, 0xB7DB, 0xB8B5, 0x8F73, 0xB8B6, 0x8F74, 0xB8B7, 0x8F75,
+	0xB8B8, 0xB7DC, 0xB8B9, 0x8F76, 0xB8BA, 0x8F77, 0xB8BB, 0x8F78,
+	0xB8BC, 0x8F79, 0xB8BD, 0x8F7A, 0xB8BE, 0x8F81, 0xB8BF, 0x8F82,
+	0xB8C0, 0xB7DD, 0xB8C1, 0xB7DE, 0xB8C2, 0x8F83, 0xB8C3, 0xB7DF,
+	0xB8C4, 0x8F84, 0xB8C5, 0xB7E0, 0xB8C6, 0x8F85, 0xB8C7, 0x8F86,
+	0xB8C8, 0x8F87, 0xB8C9, 0x8F88, 0xB8CA, 0x8F89, 0xB8CB, 0x8F8A,
+	0xB8CC, 0xB7E1, 0xB8CD, 0x8F8B, 0xB8CE, 0x8F8C, 0xB8CF, 0x8F8D,
+	0xB8D0, 0xB7E2, 0xB8D1, 0x8F8E, 0xB8D2, 0x8F8F, 0xB8D3, 0x8F90,
+	0xB8D4, 0xB7E3, 0xB8D5, 0x8F91, 0xB8D6, 0x8F92, 0xB8D7, 0x8F93,
+	0xB8D8, 0x8F94, 0xB8D9, 0x8F95, 0xB8DA, 0x8F96, 0xB8DB, 0x8F97,
+	0xB8DC, 0x8F98, 0xB8DD, 0xB7E4, 0xB8DE, 0x8F99, 0xB8DF, 0xB7E5,
+	0xB8E0, 0x8F9A, 0xB8E1, 0xB7E6, 0xB8E2, 0x8F9B, 0xB8E3, 0x8F9C,
+	0xB8E4, 0x8F9D, 0xB8E5, 0x8F9E, 0xB8E6, 0x8F9F, 0xB8E7, 0x8FA0,
+	0xB8E8, 0xB7E7, 0xB8E9, 0xB7E8, 0xB8EA, 0x8FA1, 0xB8EB, 0x8FA2,
+	0xB8EC, 0xB7E9, 0xB8ED, 0x8FA3, 0xB8EE, 0x8FA4, 0xB8EF, 0x8FA5,
+	0xB8F0, 0xB7EA, 0xB8F1, 0x8FA6, 0xB8F2, 0x8FA7, 0xB8F3, 0x8FA8,
+	0xB8F4, 0x8FA9, 0xB8F5, 0x8FAA, 0xB8F6, 0x8FAB, 0xB8F7, 0x8FAC,
+	0xB8F8, 0xB7EB, 0xB8F9, 0xB7EC, 0xB8FA, 0x8FAD, 0xB8FB, 0xB7ED,
+	0xB8FC, 0x8FAE, 0xB8FD, 0xB7EE, 0xB8FE, 0x8FAF, 0xB8FF, 0x8FB0,
+	0xB900, 0x8FB1, 0xB901, 0x8FB2, 0xB902, 0x8FB3, 0xB903, 0x8FB4,
+	0xB904, 0xB7EF, 0xB905, 0x8FB5, 0xB906, 0x8FB6, 0xB907, 0x8FB7,
+	0xB908, 0x8FB8, 0xB909, 0x8FB9, 0xB90A, 0x8FBA, 0xB90B, 0x8FBB,
+	0xB90C, 0x8FBC, 0xB90D, 0x8FBD, 0xB90E, 0x8FBE, 0xB90F, 0x8FBF,
+	0xB910, 0x8FC0, 0xB911, 0x8FC1, 0xB912, 0x8FC2, 0xB913, 0x8FC3,
+	0xB914, 0x8FC4, 0xB915, 0x8FC5, 0xB916, 0x8FC6, 0xB917, 0x8FC7,
+	0xB918, 0xB7F0, 0xB919, 0x8FC8, 0xB91A, 0x8FC9, 0xB91B, 0x8FCA,
+	0xB91C, 0x8FCB, 0xB91D, 0x8FCC, 0xB91E, 0x8FCD, 0xB91F, 0x8FCE,
+	0xB920, 0xB7F1, 0xB921, 0x8FCF, 0xB922, 0x8FD0, 0xB923, 0x8FD1,
+	0xB924, 0x8FD2, 0xB925, 0x8FD3, 0xB926, 0x8FD4, 0xB927, 0x8FD5,
+	0xB928, 0x8FD6, 0xB929, 0x8FD7, 0xB92A, 0x8FD8, 0xB92B, 0x8FD9,
+	0xB92C, 0x8FDA, 0xB92D, 0x8FDB, 0xB92E, 0x8FDC, 0xB92F, 0x8FDD,
+	0xB930, 0x8FDE, 0xB931, 0x8FDF, 0xB932, 0x8FE0, 0xB933, 0x8FE1,
+	0xB934, 0x8FE2, 0xB935, 0x8FE3, 0xB936, 0x8FE4, 0xB937, 0x8FE5,
+	0xB938, 0x8FE6, 0xB939, 0x8FE7, 0xB93A, 0x8FE8, 0xB93B, 0x8FE9,
+	0xB93C, 0xB7F2, 0xB93D, 0xB7F3, 0xB93E, 0x8FEA, 0xB93F, 0x8FEB,
+	0xB940, 0xB7F4, 0xB941, 0x8FEC, 0xB942, 0x8FED, 0xB943, 0x8FEE,
+	0xB944, 0xB7F5, 0xB945, 0x8FEF, 0xB946, 0x8FF0, 0xB947, 0x8FF1,
+	0xB948, 0x8FF2, 0xB949, 0x8FF3, 0xB94A, 0x8FF4, 0xB94B, 0x8FF5,
+	0xB94C, 0xB7F6, 0xB94D, 0x8FF6, 0xB94E, 0x8FF7, 0xB94F, 0xB7F7,
+	0xB950, 0x8FF8, 0xB951, 0xB7F8, 0xB952, 0x8FF9, 0xB953, 0x8FFA,
+	0xB954, 0x8FFB, 0xB955, 0x8FFC, 0xB956, 0x8FFD, 0xB957, 0x8FFE,
+	0xB958, 0xB7F9, 0xB959, 0xB7FA, 0xB95A, 0x9041, 0xB95B, 0x9042,
+	0xB95C, 0xB7FB, 0xB95D, 0x9043, 0xB95E, 0x9044, 0xB95F, 0x9045,
+	0xB960, 0xB7FC, 0xB961, 0x9046, 0xB962, 0x9047, 0xB963, 0x9048,
+	0xB964, 0x9049, 0xB965, 0x904A, 0xB966, 0x904B, 0xB967, 0x904C,
+	0xB968, 0xB7FD, 0xB969, 0xB7FE, 0xB96A, 0x904D, 0xB96B, 0xB8A1,
+	0xB96C, 0x904E, 0xB96D, 0xB8A2, 0xB96E, 0x904F, 0xB96F, 0x9050,
+	0xB970, 0x9051, 0xB971, 0x9052, 0xB972, 0x9053, 0xB973, 0x9054,
+	0xB974, 0xB8A3, 0xB975, 0xB8A4, 0xB976, 0x9055, 0xB977, 0x9056,
+	0xB978, 0xB8A5, 0xB979, 0x9057, 0xB97A, 0x9058, 0xB97B, 0x9059,
+	0xB97C, 0xB8A6, 0xB97D, 0x905A, 0xB97E, 0x9061, 0xB97F, 0x9062,
+	0xB980, 0x9063, 0xB981, 0x9064, 0xB982, 0x9065, 0xB983, 0x9066,
+	0xB984, 0xB8A7, 0xB985, 0xB8A8, 0xB986, 0x9067, 0xB987, 0xB8A9,
+	0xB988, 0x9068, 0xB989, 0xB8AA, 0xB98A, 0xB8AB, 0xB98B, 0x9069,
+	0xB98C, 0x906A, 0xB98D, 0xB8AC, 0xB98E, 0xB8AD, 0xB98F, 0x906B,
+	0xB990, 0x906C, 0xB991, 0x906D, 0xB992, 0x906E, 0xB993, 0x906F,
+	0xB994, 0x9070, 0xB995, 0x9071, 0xB996, 0x9072, 0xB997, 0x9073,
+	0xB998, 0x9074, 0xB999, 0x9075, 0xB99A, 0x9076, 0xB99B, 0x9077,
+	0xB99C, 0x9078, 0xB99D, 0x9079, 0xB99E, 0x907A, 0xB99F, 0x9081,
+	0xB9A0, 0x9082, 0xB9A1, 0x9083, 0xB9A2, 0x9084, 0xB9A3, 0x9085,
+	0xB9A4, 0x9086, 0xB9A5, 0x9087, 0xB9A6, 0x9088, 0xB9A7, 0x9089,
+	0xB9A8, 0x908A, 0xB9A9, 0x908B, 0xB9AA, 0x908C, 0xB9AB, 0x908D,
+	0xB9AC, 0xB8AE, 0xB9AD, 0xB8AF, 0xB9AE, 0x908E, 0xB9AF, 0x908F,
+	0xB9B0, 0xB8B0, 0xB9B1, 0x9090, 0xB9B2, 0x9091, 0xB9B3, 0x9092,
+	0xB9B4, 0xB8B1, 0xB9B5, 0x9093, 0xB9B6, 0x9094, 0xB9B7, 0x9095,
+	0xB9B8, 0x9096, 0xB9B9, 0x9097, 0xB9BA, 0x9098, 0xB9BB, 0x9099,
+	0xB9BC, 0xB8B2, 0xB9BD, 0xB8B3, 0xB9BE, 0x909A, 0xB9BF, 0xB8B4,
+	0xB9C0, 0x909B, 0xB9C1, 0xB8B5, 0xB9C2, 0x909C, 0xB9C3, 0x909D,
+	0xB9C4, 0x909E, 0xB9C5, 0x909F, 0xB9C6, 0x90A0, 0xB9C7, 0x90A1,
+	0xB9C8, 0xB8B6, 0xB9C9, 0xB8B7, 0xB9CA, 0x90A2, 0xB9CB, 0x90A3,
+	0xB9CC, 0xB8B8, 0xB9CD, 0x90A4, 0xB9CE, 0xB8B9, 0xB9CF, 0xB8BA,
+	0xB9D0, 0xB8BB, 0xB9D1, 0xB8BC, 0xB9D2, 0xB8BD, 0xB9D3, 0x90A5,
+	0xB9D4, 0x90A6, 0xB9D5, 0x90A7, 0xB9D6, 0x90A8, 0xB9D7, 0x90A9,
+	0xB9D8, 0xB8BE, 0xB9D9, 0xB8BF, 0xB9DA, 0x90AA, 0xB9DB, 0xB8C0,
+	0xB9DC, 0x90AB, 0xB9DD, 0xB8C1, 0xB9DE, 0xB8C2, 0xB9DF, 0x90AC,
+	0xB9E0, 0x90AD, 0xB9E1, 0xB8C3, 0xB9E2, 0x90AE, 0xB9E3, 0xB8C4,
+	0xB9E4, 0xB8C5, 0xB9E5, 0xB8C6, 0xB9E6, 0x90AF, 0xB9E7, 0x90B0,
+	0xB9E8, 0xB8C7, 0xB9E9, 0x90B1, 0xB9EA, 0x90B2, 0xB9EB, 0x90B3,
+	0xB9EC, 0xB8C8, 0xB9ED, 0x90B4, 0xB9EE, 0x90B5, 0xB9EF, 0x90B6,
+	0xB9F0, 0x90B7, 0xB9F1, 0x90B8, 0xB9F2, 0x90B9, 0xB9F3, 0x90BA,
+	0xB9F4, 0xB8C9, 0xB9F5, 0xB8CA, 0xB9F6, 0x90BB, 0xB9F7, 0xB8CB,
+	0xB9F8, 0xB8CC, 0xB9F9, 0xB8CD, 0xB9FA, 0xB8CE, 0xB9FB, 0x90BC,
+	0xB9FC, 0x90BD, 0xB9FD, 0x90BE, 0xB9FE, 0x90BF, 0xB9FF, 0x90C0,
+	0xBA00, 0xB8CF, 0xBA01, 0xB8D0, 0xBA02, 0x90C1, 0xBA03, 0x90C2,
+	0xBA04, 0x90C3, 0xBA05, 0x90C4, 0xBA06, 0x90C5, 0xBA07, 0x90C6,
+	0xBA08, 0xB8D1, 0xBA09, 0x90C7, 0xBA0A, 0x90C8, 0xBA0B, 0x90C9,
+	0xBA0C, 0x90CA, 0xBA0D, 0x90CB, 0xBA0E, 0x90CC, 0xBA0F, 0x90CD,
+	0xBA10, 0x90CE, 0xBA11, 0x90CF, 0xBA12, 0x90D0, 0xBA13, 0x90D1,
+	0xBA14, 0x90D2, 0xBA15, 0xB8D2, 0xBA16, 0x90D3, 0xBA17, 0x90D4,
+	0xBA18, 0x90D5, 0xBA19, 0x90D6, 0xBA1A, 0x90D7, 0xBA1B, 0x90D8,
+	0xBA1C, 0x90D9, 0xBA1D, 0x90DA, 0xBA1E, 0x90DB, 0xBA1F, 0x90DC,
+	0xBA20, 0x90DD, 0xBA21, 0x90DE, 0xBA22, 0x90DF, 0xBA23, 0x90E0,
+	0xBA24, 0x90E1, 0xBA25, 0x90E2, 0xBA26, 0x90E3, 0xBA27, 0x90E4,
+	0xBA28, 0x90E5, 0xBA29, 0x90E6, 0xBA2A, 0x90E7, 0xBA2B, 0x90E8,
+	0xBA2C, 0x90E9, 0xBA2D, 0x90EA, 0xBA2E, 0x90EB, 0xBA2F, 0x90EC,
+	0xBA30, 0x90ED, 0xBA31, 0x90EE, 0xBA32, 0x90EF, 0xBA33, 0x90F0,
+	0xBA34, 0x90F1, 0xBA35, 0x90F2, 0xBA36, 0x90F3, 0xBA37, 0x90F4,
+	0xBA38, 0xB8D3, 0xBA39, 0xB8D4, 0xBA3A, 0x90F5, 0xBA3B, 0x90F6,
+	0xBA3C, 0xB8D5, 0xBA3D, 0x90F7, 0xBA3E, 0x90F8, 0xBA3F, 0x90F9,
+	0xBA40, 0xB8D6, 0xBA41, 0x90FA, 0xBA42, 0xB8D7, 0xBA43, 0x90FB,
+	0xBA44, 0x90FC, 0xBA45, 0x90FD, 0xBA46, 0x90FE, 0xBA47, 0x9141,
+	0xBA48, 0xB8D8, 0xBA49, 0xB8D9, 0xBA4A, 0x9142, 0xBA4B, 0xB8DA,
+	0xBA4C, 0x9143, 0xBA4D, 0xB8DB, 0xBA4E, 0xB8DC, 0xBA4F, 0x9144,
+	0xBA50, 0x9145, 0xBA51, 0x9146, 0xBA52, 0x9147, 0xBA53, 0xB8DD,
+	0xBA54, 0xB8DE, 0xBA55, 0xB8DF, 0xBA56, 0x9148, 0xBA57, 0x9149,
+	0xBA58, 0xB8E0, 0xBA59, 0x914A, 0xBA5A, 0x914B, 0xBA5B, 0x914C,
+	0xBA5C, 0xB8E1, 0xBA5D, 0x914D, 0xBA5E, 0x914E, 0xBA5F, 0x914F,
+	0xBA60, 0x9150, 0xBA61, 0x9151, 0xBA62, 0x9152, 0xBA63, 0x9153,
+	0xBA64, 0xB8E2, 0xBA65, 0xB8E3, 0xBA66, 0x9154, 0xBA67, 0xB8E4,
+	0xBA68, 0xB8E5, 0xBA69, 0xB8E6, 0xBA6A, 0x9155, 0xBA6B, 0x9156,
+	0xBA6C, 0x9157, 0xBA6D, 0x9158, 0xBA6E, 0x9159, 0xBA6F, 0x915A,
+	0xBA70, 0xB8E7, 0xBA71, 0xB8E8, 0xBA72, 0x9161, 0xBA73, 0x9162,
+	0xBA74, 0xB8E9, 0xBA75, 0x9163, 0xBA76, 0x9164, 0xBA77, 0x9165,
+	0xBA78, 0xB8EA, 0xBA79, 0x9166, 0xBA7A, 0x9167, 0xBA7B, 0x9168,
+	0xBA7C, 0x9169, 0xBA7D, 0x916A, 0xBA7E, 0x916B, 0xBA7F, 0x916C,
+	0xBA80, 0x916D, 0xBA81, 0x916E, 0xBA82, 0x916F, 0xBA83, 0xB8EB,
+	0xBA84, 0xB8EC, 0xBA85, 0xB8ED, 0xBA86, 0x9170, 0xBA87, 0xB8EE,
+	0xBA88, 0x9171, 0xBA89, 0x9172, 0xBA8A, 0x9173, 0xBA8B, 0x9174,
+	0xBA8C, 0xB8EF, 0xBA8D, 0x9175, 0xBA8E, 0x9176, 0xBA8F, 0x9177,
+	0xBA90, 0x9178, 0xBA91, 0x9179, 0xBA92, 0x917A, 0xBA93, 0x9181,
+	0xBA94, 0x9182, 0xBA95, 0x9183, 0xBA96, 0x9184, 0xBA97, 0x9185,
+	0xBA98, 0x9186, 0xBA99, 0x9187, 0xBA9A, 0x9188, 0xBA9B, 0x9189,
+	0xBA9C, 0x918A, 0xBA9D, 0x918B, 0xBA9E, 0x918C, 0xBA9F, 0x918D,
+	0xBAA0, 0x918E, 0xBAA1, 0x918F, 0xBAA2, 0x9190, 0xBAA3, 0x9191,
+	0xBAA4, 0x9192, 0xBAA5, 0x9193, 0xBAA6, 0x9194, 0xBAA7, 0x9195,
+	0xBAA8, 0xB8F0, 0xBAA9, 0xB8F1, 0xBAAA, 0x9196, 0xBAAB, 0xB8F2,
+	0xBAAC, 0xB8F3, 0xBAAD, 0x9197, 0xBAAE, 0x9198, 0xBAAF, 0x9199,
+	0xBAB0, 0xB8F4, 0xBAB1, 0x919A, 0xBAB2, 0xB8F5, 0xBAB3, 0x919B,
+	0xBAB4, 0x919C, 0xBAB5, 0x919D, 0xBAB6, 0x919E, 0xBAB7, 0x919F,
+	0xBAB8, 0xB8F6, 0xBAB9, 0xB8F7, 0xBABA, 0x91A0, 0xBABB, 0xB8F8,
+	0xBABC, 0x91A1, 0xBABD, 0xB8F9, 0xBABE, 0x91A2, 0xBABF, 0x91A3,
+	0xBAC0, 0x91A4, 0xBAC1, 0x91A5, 0xBAC2, 0x91A6, 0xBAC3, 0x91A7,
+	0xBAC4, 0xB8FA, 0xBAC5, 0x91A8, 0xBAC6, 0x91A9, 0xBAC7, 0x91AA,
+	0xBAC8, 0xB8FB, 0xBAC9, 0x91AB, 0xBACA, 0x91AC, 0xBACB, 0x91AD,
+	0xBACC, 0x91AE, 0xBACD, 0x91AF, 0xBACE, 0x91B0, 0xBACF, 0x91B1,
+	0xBAD0, 0x91B2, 0xBAD1, 0x91B3, 0xBAD2, 0x91B4, 0xBAD3, 0x91B5,
+	0xBAD4, 0x91B6, 0xBAD5, 0x91B7, 0xBAD6, 0x91B8, 0xBAD7, 0x91B9,
+	0xBAD8, 0xB8FC, 0xBAD9, 0xB8FD, 0xBADA, 0x91BA, 0xBADB, 0x91BB,
+	0xBADC, 0x91BC, 0xBADD, 0x91BD, 0xBADE, 0x91BE, 0xBADF, 0x91BF,
+	0xBAE0, 0x91C0, 0xBAE1, 0x91C1, 0xBAE2, 0x91C2, 0xBAE3, 0x91C3,
+	0xBAE4, 0x91C4, 0xBAE5, 0x91C5, 0xBAE6, 0x91C6, 0xBAE7, 0x91C7,
+	0xBAE8, 0x91C8, 0xBAE9, 0x91C9, 0xBAEA, 0x91CA, 0xBAEB, 0x91CB,
+	0xBAEC, 0x91CC, 0xBAED, 0x91CD, 0xBAEE, 0x91CE, 0xBAEF, 0x91CF,
+	0xBAF0, 0x91D0, 0xBAF1, 0x91D1, 0xBAF2, 0x91D2, 0xBAF3, 0x91D3,
+	0xBAF4, 0x91D4, 0xBAF5, 0x91D5, 0xBAF6, 0x91D6, 0xBAF7, 0x91D7,
+	0xBAF8, 0x91D8, 0xBAF9, 0x91D9, 0xBAFA, 0x91DA, 0xBAFB, 0x91DB,
+	0xBAFC, 0xB8FE, 0xBAFD, 0x91DC, 0xBAFE, 0x91DD, 0xBAFF, 0x91DE,
+	0xBB00, 0xB9A1, 0xBB01, 0x91DF, 0xBB02, 0x91E0, 0xBB03, 0x91E1,
+	0xBB04, 0xB9A2, 0xBB05, 0x91E2, 0xBB06, 0x91E3, 0xBB07, 0x91E4,
+	0xBB08, 0x91E5, 0xBB09, 0x91E6, 0xBB0A, 0x91E7, 0xBB0B, 0x91E8,
+	0xBB0C, 0x91E9, 0xBB0D, 0xB9A3, 0xBB0E, 0x91EA, 0xBB0F, 0xB9A4,
+	0xBB10, 0x91EB, 0xBB11, 0xB9A5, 0xBB12, 0x91EC, 0xBB13, 0x91ED,
+	0xBB14, 0x91EE, 0xBB15, 0x91EF, 0xBB16, 0x91F0, 0xBB17, 0x91F1,
+	0xBB18, 0xB9A6, 0xBB19, 0x91F2, 0xBB1A, 0x91F3, 0xBB1B, 0x91F4,
+	0xBB1C, 0xB9A7, 0xBB1D, 0x91F5, 0xBB1E, 0x91F6, 0xBB1F, 0x91F7,
+	0xBB20, 0xB9A8, 0xBB21, 0x91F8, 0xBB22, 0x91F9, 0xBB23, 0x91FA,
+	0xBB24, 0x91FB, 0xBB25, 0x91FC, 0xBB26, 0x91FD, 0xBB27, 0x91FE,
+	0xBB28, 0x9241, 0xBB29, 0xB9A9, 0xBB2A, 0x9242, 0xBB2B, 0xB9AA,
+	0xBB2C, 0x9243, 0xBB2D, 0x9244, 0xBB2E, 0x9245, 0xBB2F, 0x9246,
+	0xBB30, 0x9247, 0xBB31, 0x9248, 0xBB32, 0x9249, 0xBB33, 0x924A,
+	0xBB34, 0xB9AB, 0xBB35, 0xB9AC, 0xBB36, 0xB9AD, 0xBB37, 0x924B,
+	0xBB38, 0xB9AE, 0xBB39, 0x924C, 0xBB3A, 0x924D, 0xBB3B, 0xB9AF,
+	0xBB3C, 0xB9B0, 0xBB3D, 0xB9B1, 0xBB3E, 0xB9B2, 0xBB3F, 0x924E,
+	0xBB40, 0x924F, 0xBB41, 0x9250, 0xBB42, 0x9251, 0xBB43, 0x9252,
+	0xBB44, 0xB9B3, 0xBB45, 0xB9B4, 0xBB46, 0x9253, 0xBB47, 0xB9B5,
+	0xBB48, 0x9254, 0xBB49, 0xB9B6, 0xBB4A, 0x9255, 0xBB4B, 0x9256,
+	0xBB4C, 0x9257, 0xBB4D, 0xB9B7, 0xBB4E, 0x9258, 0xBB4F, 0xB9B8,
+	0xBB50, 0xB9B9, 0xBB51, 0x9259, 0xBB52, 0x925A, 0xBB53, 0x9261,
+	0xBB54, 0xB9BA, 0xBB55, 0x9262, 0xBB56, 0x9263, 0xBB57, 0x9264,
+	0xBB58, 0xB9BB, 0xBB59, 0x9265, 0xBB5A, 0x9266, 0xBB5B, 0x9267,
+	0xBB5C, 0x9268, 0xBB5D, 0x9269, 0xBB5E, 0x926A, 0xBB5F, 0x926B,
+	0xBB60, 0x926C, 0xBB61, 0xB9BC, 0xBB62, 0x926D, 0xBB63, 0xB9BD,
+	0xBB64, 0x926E, 0xBB65, 0x926F, 0xBB66, 0x9270, 0xBB67, 0x9271,
+	0xBB68, 0x9272, 0xBB69, 0x9273, 0xBB6A, 0x9274, 0xBB6B, 0x9275,
+	0xBB6C, 0xB9BE, 0xBB6D, 0x9276, 0xBB6E, 0x9277, 0xBB6F, 0x9278,
+	0xBB70, 0x9279, 0xBB71, 0x927A, 0xBB72, 0x9281, 0xBB73, 0x9282,
+	0xBB74, 0x9283, 0xBB75, 0x9284, 0xBB76, 0x9285, 0xBB77, 0x9286,
+	0xBB78, 0x9287, 0xBB79, 0x9288, 0xBB7A, 0x9289, 0xBB7B, 0x928A,
+	0xBB7C, 0x928B, 0xBB7D, 0x928C, 0xBB7E, 0x928D, 0xBB7F, 0x928E,
+	0xBB80, 0x928F, 0xBB81, 0x9290, 0xBB82, 0x9291, 0xBB83, 0x9292,
+	0xBB84, 0x9293, 0xBB85, 0x9294, 0xBB86, 0x9295, 0xBB87, 0x9296,
+	0xBB88, 0xB9BF, 0xBB89, 0x9297, 0xBB8A, 0x9298, 0xBB8B, 0x9299,
+	0xBB8C, 0xB9C0, 0xBB8D, 0x929A, 0xBB8E, 0x929B, 0xBB8F, 0x929C,
+	0xBB90, 0xB9C1, 0xBB91, 0x929D, 0xBB92, 0x929E, 0xBB93, 0x929F,
+	0xBB94, 0x92A0, 0xBB95, 0x92A1, 0xBB96, 0x92A2, 0xBB97, 0x92A3,
+	0xBB98, 0x92A4, 0xBB99, 0x92A5, 0xBB9A, 0x92A6, 0xBB9B, 0x92A7,
+	0xBB9C, 0x92A8, 0xBB9D, 0x92A9, 0xBB9E, 0x92AA, 0xBB9F, 0x92AB,
+	0xBBA0, 0x92AC, 0xBBA1, 0x92AD, 0xBBA2, 0x92AE, 0xBBA3, 0x92AF,
+	0xBBA4, 0xB9C2, 0xBBA5, 0x92B0, 0xBBA6, 0x92B1, 0xBBA7, 0x92B2,
+	0xBBA8, 0xB9C3, 0xBBA9, 0x92B3, 0xBBAA, 0x92B4, 0xBBAB, 0x92B5,
+	0xBBAC, 0xB9C4, 0xBBAD, 0x92B6, 0xBBAE, 0x92B7, 0xBBAF, 0x92B8,
+	0xBBB0, 0x92B9, 0xBBB1, 0x92BA, 0xBBB2, 0x92BB, 0xBBB3, 0x92BC,
+	0xBBB4, 0xB9C5, 0xBBB5, 0x92BD, 0xBBB6, 0x92BE, 0xBBB7, 0xB9C6,
+	0xBBB8, 0x92BF, 0xBBB9, 0x92C0, 0xBBBA, 0x92C1, 0xBBBB, 0x92C2,
+	0xBBBC, 0x92C3, 0xBBBD, 0x92C4, 0xBBBE, 0x92C5, 0xBBBF, 0x92C6,
+	0xBBC0, 0xB9C7, 0xBBC1, 0x92C7, 0xBBC2, 0x92C8, 0xBBC3, 0x92C9,
+	0xBBC4, 0xB9C8, 0xBBC5, 0x92CA, 0xBBC6, 0x92CB, 0xBBC7, 0x92CC,
+	0xBBC8, 0xB9C9, 0xBBC9, 0x92CD, 0xBBCA, 0x92CE, 0xBBCB, 0x92CF,
+	0xBBCC, 0x92D0, 0xBBCD, 0x92D1, 0xBBCE, 0x92D2, 0xBBCF, 0x92D3,
+	0xBBD0, 0xB9CA, 0xBBD1, 0x92D4, 0xBBD2, 0x92D5, 0xBBD3, 0xB9CB,
+	0xBBD4, 0x92D6, 0xBBD5, 0x92D7, 0xBBD6, 0x92D8, 0xBBD7, 0x92D9,
+	0xBBD8, 0x92DA, 0xBBD9, 0x92DB, 0xBBDA, 0x92DC, 0xBBDB, 0x92DD,
+	0xBBDC, 0x92DE, 0xBBDD, 0x92DF, 0xBBDE, 0x92E0, 0xBBDF, 0x92E1,
+	0xBBE0, 0x92E2, 0xBBE1, 0x92E3, 0xBBE2, 0x92E4, 0xBBE3, 0x92E5,
+	0xBBE4, 0x92E6, 0xBBE5, 0x92E7, 0xBBE6, 0x92E8, 0xBBE7, 0x92E9,
+	0xBBE8, 0x92EA, 0xBBE9, 0x92EB, 0xBBEA, 0x92EC, 0xBBEB, 0x92ED,
+	0xBBEC, 0x92EE, 0xBBED, 0x92EF, 0xBBEE, 0x92F0, 0xBBEF, 0x92F1,
+	0xBBF0, 0x92F2, 0xBBF1, 0x92F3, 0xBBF2, 0x92F4, 0xBBF3, 0x92F5,
+	0xBBF4, 0x92F6, 0xBBF5, 0x92F7, 0xBBF6, 0x92F8, 0xBBF7, 0x92F9,
+	0xBBF8, 0xB9CC, 0xBBF9, 0xB9CD, 0xBBFA, 0x92FA, 0xBBFB, 0x92FB,
+	0xBBFC, 0xB9CE, 0xBBFD, 0x92FC, 0xBBFE, 0x92FD, 0xBBFF, 0xB9CF,
+	0xBC00, 0xB9D0, 0xBC01, 0x92FE, 0xBC02, 0xB9D1, 0xBC03, 0x9341,
+	0xBC04, 0x9342, 0xBC05, 0x9343, 0xBC06, 0x9344, 0xBC07, 0x9345,
+	0xBC08, 0xB9D2, 0xBC09, 0xB9D3, 0xBC0A, 0x9346, 0xBC0B, 0xB9D4,
+	0xBC0C, 0xB9D5, 0xBC0D, 0xB9D6, 0xBC0E, 0x9347, 0xBC0F, 0xB9D7,
+	0xBC10, 0x9348, 0xBC11, 0xB9D8, 0xBC12, 0x9349, 0xBC13, 0x934A,
+	0xBC14, 0xB9D9, 0xBC15, 0xB9DA, 0xBC16, 0xB9DB, 0xBC17, 0xB9DC,
+	0xBC18, 0xB9DD, 0xBC19, 0x934B, 0xBC1A, 0x934C, 0xBC1B, 0xB9DE,
+	0xBC1C, 0xB9DF, 0xBC1D, 0xB9E0, 0xBC1E, 0xB9E1, 0xBC1F, 0xB9E2,
+	0xBC20, 0x934D, 0xBC21, 0x934E, 0xBC22, 0x934F, 0xBC23, 0x9350,
+	0xBC24, 0xB9E3, 0xBC25, 0xB9E4, 0xBC26, 0x9351, 0xBC27, 0xB9E5,
+	0xBC28, 0x9352, 0xBC29, 0xB9E6, 0xBC2A, 0x9353, 0xBC2B, 0x9354,
+	0xBC2C, 0x9355, 0xBC2D, 0xB9E7, 0xBC2E, 0x9356, 0xBC2F, 0x9357,
+	0xBC30, 0xB9E8, 0xBC31, 0xB9E9, 0xBC32, 0x9358, 0xBC33, 0x9359,
+	0xBC34, 0xB9EA, 0xBC35, 0x935A, 0xBC36, 0x9361, 0xBC37, 0x9362,
+	0xBC38, 0xB9EB, 0xBC39, 0x9363, 0xBC3A, 0x9364, 0xBC3B, 0x9365,
+	0xBC3C, 0x9366, 0xBC3D, 0x9367, 0xBC3E, 0x9368, 0xBC3F, 0x9369,
+	0xBC40, 0xB9EC, 0xBC41, 0xB9ED, 0xBC42, 0x936A, 0xBC43, 0xB9EE,
+	0xBC44, 0xB9EF, 0xBC45, 0xB9F0, 0xBC46, 0x936B, 0xBC47, 0x936C,
+	0xBC48, 0x936D, 0xBC49, 0xB9F1, 0xBC4A, 0x936E, 0xBC4B, 0x936F,
+	0xBC4C, 0xB9F2, 0xBC4D, 0xB9F3, 0xBC4E, 0x9370, 0xBC4F, 0x9371,
+	0xBC50, 0xB9F4, 0xBC51, 0x9372, 0xBC52, 0x9373, 0xBC53, 0x9374,
+	0xBC54, 0x9375, 0xBC55, 0x9376, 0xBC56, 0x9377, 0xBC57, 0x9378,
+	0xBC58, 0x9379, 0xBC59, 0x937A, 0xBC5A, 0x9381, 0xBC5B, 0x9382,
+	0xBC5C, 0x9383, 0xBC5D, 0xB9F5, 0xBC5E, 0x9384, 0xBC5F, 0x9385,
+	0xBC60, 0x9386, 0xBC61, 0x9387, 0xBC62, 0x9388, 0xBC63, 0x9389,
+	0xBC64, 0x938A, 0xBC65, 0x938B, 0xBC66, 0x938C, 0xBC67, 0x938D,
+	0xBC68, 0x938E, 0xBC69, 0x938F, 0xBC6A, 0x9390, 0xBC6B, 0x9391,
+	0xBC6C, 0x9392, 0xBC6D, 0x9393, 0xBC6E, 0x9394, 0xBC6F, 0x9395,
+	0xBC70, 0x9396, 0xBC71, 0x9397, 0xBC72, 0x9398, 0xBC73, 0x9399,
+	0xBC74, 0x939A, 0xBC75, 0x939B, 0xBC76, 0x939C, 0xBC77, 0x939D,
+	0xBC78, 0x939E, 0xBC79, 0x939F, 0xBC7A, 0x93A0, 0xBC7B, 0x93A1,
+	0xBC7C, 0x93A2, 0xBC7D, 0x93A3, 0xBC7E, 0x93A4, 0xBC7F, 0x93A5,
+	0xBC80, 0x93A6, 0xBC81, 0x93A7, 0xBC82, 0x93A8, 0xBC83, 0x93A9,
+	0xBC84, 0xB9F6, 0xBC85, 0xB9F7, 0xBC86, 0x93AA, 0xBC87, 0x93AB,
+	0xBC88, 0xB9F8, 0xBC89, 0x93AC, 0xBC8A, 0x93AD, 0xBC8B, 0xB9F9,
+	0xBC8C, 0xB9FA, 0xBC8D, 0x93AE, 0xBC8E, 0xB9FB, 0xBC8F, 0x93AF,
+	0xBC90, 0x93B0, 0xBC91, 0x93B1, 0xBC92, 0x93B2, 0xBC93, 0x93B3,
+	0xBC94, 0xB9FC, 0xBC95, 0xB9FD, 0xBC96, 0x93B4, 0xBC97, 0xB9FE,
+	0xBC98, 0x93B5, 0xBC99, 0xBAA1, 0xBC9A, 0xBAA2, 0xBC9B, 0x93B6,
+	0xBC9C, 0x93B7, 0xBC9D, 0x93B8, 0xBC9E, 0x93B9, 0xBC9F, 0x93BA,
+	0xBCA0, 0xBAA3, 0xBCA1, 0xBAA4, 0xBCA2, 0x93BB, 0xBCA3, 0x93BC,
+	0xBCA4, 0xBAA5, 0xBCA5, 0x93BD, 0xBCA6, 0x93BE, 0xBCA7, 0xBAA6,
+	0xBCA8, 0xBAA7, 0xBCA9, 0x93BF, 0xBCAA, 0x93C0, 0xBCAB, 0x93C1,
+	0xBCAC, 0x93C2, 0xBCAD, 0x93C3, 0xBCAE, 0x93C4, 0xBCAF, 0x93C5,
+	0xBCB0, 0xBAA8, 0xBCB1, 0xBAA9, 0xBCB2, 0x93C6, 0xBCB3, 0xBAAA,
+	0xBCB4, 0xBAAB, 0xBCB5, 0xBAAC, 0xBCB6, 0x93C7, 0xBCB7, 0x93C8,
+	0xBCB8, 0x93C9, 0xBCB9, 0x93CA, 0xBCBA, 0x93CB, 0xBCBB, 0x93CC,
+	0xBCBC, 0xBAAD, 0xBCBD, 0xBAAE, 0xBCBE, 0x93CD, 0xBCBF, 0x93CE,
+	0xBCC0, 0xBAAF, 0xBCC1, 0x93CF, 0xBCC2, 0x93D0, 0xBCC3, 0x93D1,
+	0xBCC4, 0xBAB0, 0xBCC5, 0x93D2, 0xBCC6, 0x93D3, 0xBCC7, 0x93D4,
+	0xBCC8, 0x93D5, 0xBCC9, 0x93D6, 0xBCCA, 0x93D7, 0xBCCB, 0x93D8,
+	0xBCCC, 0x93D9, 0xBCCD, 0xBAB1, 0xBCCE, 0x93DA, 0xBCCF, 0xBAB2,
+	0xBCD0, 0xBAB3, 0xBCD1, 0xBAB4, 0xBCD2, 0x93DB, 0xBCD3, 0x93DC,
+	0xBCD4, 0x93DD, 0xBCD5, 0xBAB5, 0xBCD6, 0x93DE, 0xBCD7, 0x93DF,
+	0xBCD8, 0xBAB6, 0xBCD9, 0x93E0, 0xBCDA, 0x93E1, 0xBCDB, 0x93E2,
+	0xBCDC, 0xBAB7, 0xBCDD, 0x93E3, 0xBCDE, 0x93E4, 0xBCDF, 0x93E5,
+	0xBCE0, 0x93E6, 0xBCE1, 0x93E7, 0xBCE2, 0x93E8, 0xBCE3, 0x93E9,
+	0xBCE4, 0x93EA, 0xBCE5, 0x93EB, 0xBCE6, 0x93EC, 0xBCE7, 0x93ED,
+	0xBCE8, 0x93EE, 0xBCE9, 0x93EF, 0xBCEA, 0x93F0, 0xBCEB, 0x93F1,
+	0xBCEC, 0x93F2, 0xBCED, 0x93F3, 0xBCEE, 0x93F4, 0xBCEF, 0x93F5,
+	0xBCF0, 0x93F6, 0xBCF1, 0x93F7, 0xBCF2, 0x93F8, 0xBCF3, 0x93F9,
+	0xBCF4, 0xBAB8, 0xBCF5, 0xBAB9, 0xBCF6, 0xBABA, 0xBCF7, 0x93FA,
+	0xBCF8, 0xBABB, 0xBCF9, 0x93FB, 0xBCFA, 0x93FC, 0xBCFB, 0x93FD,
+	0xBCFC, 0xBABC, 0xBCFD, 0x93FE, 0xBCFE, 0x9441, 0xBCFF, 0x9442,
+	0xBD00, 0x9443, 0xBD01, 0x9444, 0xBD02, 0x9445, 0xBD03, 0x9446,
+	0xBD04, 0xBABD, 0xBD05, 0xBABE, 0xBD06, 0x9447, 0xBD07, 0xBABF,
+	0xBD08, 0x9448, 0xBD09, 0xBAC0, 0xBD0A, 0x9449, 0xBD0B, 0x944A,
+	0xBD0C, 0x944B, 0xBD0D, 0x944C, 0xBD0E, 0x944D, 0xBD0F, 0x944E,
+	0xBD10, 0xBAC1, 0xBD11, 0x944F, 0xBD12, 0x9450, 0xBD13, 0x9451,
+	0xBD14, 0xBAC2, 0xBD15, 0x9452, 0xBD16, 0x9453, 0xBD17, 0x9454,
+	0xBD18, 0x9455, 0xBD19, 0x9456, 0xBD1A, 0x9457, 0xBD1B, 0x9458,
+	0xBD1C, 0x9459, 0xBD1D, 0x945A, 0xBD1E, 0x9461, 0xBD1F, 0x9462,
+	0xBD20, 0x9463, 0xBD21, 0x9464, 0xBD22, 0x9465, 0xBD23, 0x9466,
+	0xBD24, 0xBAC3, 0xBD25, 0x9467, 0xBD26, 0x9468, 0xBD27, 0x9469,
+	0xBD28, 0x946A, 0xBD29, 0x946B, 0xBD2A, 0x946C, 0xBD2B, 0x946D,
+	0xBD2C, 0xBAC4, 0xBD2D, 0x946E, 0xBD2E, 0x946F, 0xBD2F, 0x9470,
+	0xBD30, 0x9471, 0xBD31, 0x9472, 0xBD32, 0x9473, 0xBD33, 0x9474,
+	0xBD34, 0x9475, 0xBD35, 0x9476, 0xBD36, 0x9477, 0xBD37, 0x9478,
+	0xBD38, 0x9479, 0xBD39, 0x947A, 0xBD3A, 0x9481, 0xBD3B, 0x9482,
+	0xBD3C, 0x9483, 0xBD3D, 0x9484, 0xBD3E, 0x9485, 0xBD3F, 0x9486,
+	0xBD40, 0xBAC5, 0xBD41, 0x9487, 0xBD42, 0x9488, 0xBD43, 0x9489,
+	0xBD44, 0x948A, 0xBD45, 0x948B, 0xBD46, 0x948C, 0xBD47, 0x948D,
+	0xBD48, 0xBAC6, 0xBD49, 0xBAC7, 0xBD4A, 0x948E, 0xBD4B, 0x948F,
+	0xBD4C, 0xBAC8, 0xBD4D, 0x9490, 0xBD4E, 0x9491, 0xBD4F, 0x9492,
+	0xBD50, 0xBAC9, 0xBD51, 0x9493, 0xBD52, 0x9494, 0xBD53, 0x9495,
+	0xBD54, 0x9496, 0xBD55, 0x9497, 0xBD56, 0x9498, 0xBD57, 0x9499,
+	0xBD58, 0xBACA, 0xBD59, 0xBACB, 0xBD5A, 0x949A, 0xBD5B, 0x949B,
+	0xBD5C, 0x949C, 0xBD5D, 0x949D, 0xBD5E, 0x949E, 0xBD5F, 0x949F,
+	0xBD60, 0x94A0, 0xBD61, 0x94A1, 0xBD62, 0x94A2, 0xBD63, 0x94A3,
+	0xBD64, 0xBACC, 0xBD65, 0x94A4, 0xBD66, 0x94A5, 0xBD67, 0x94A6,
+	0xBD68, 0xBACD, 0xBD69, 0x94A7, 0xBD6A, 0x94A8, 0xBD6B, 0x94A9,
+	0xBD6C, 0x94AA, 0xBD6D, 0x94AB, 0xBD6E, 0x94AC, 0xBD6F, 0x94AD,
+	0xBD70, 0x94AE, 0xBD71, 0x94AF, 0xBD72, 0x94B0, 0xBD73, 0x94B1,
+	0xBD74, 0x94B2, 0xBD75, 0x94B3, 0xBD76, 0x94B4, 0xBD77, 0x94B5,
+	0xBD78, 0x94B6, 0xBD79, 0x94B7, 0xBD7A, 0x94B8, 0xBD7B, 0x94B9,
+	0xBD7C, 0x94BA, 0xBD7D, 0x94BB, 0xBD7E, 0x94BC, 0xBD7F, 0x94BD,
+	0xBD80, 0xBACE, 0xBD81, 0xBACF, 0xBD82, 0x94BE, 0xBD83, 0x94BF,
+	0xBD84, 0xBAD0, 0xBD85, 0x94C0, 0xBD86, 0x94C1, 0xBD87, 0xBAD1,
+	0xBD88, 0xBAD2, 0xBD89, 0xBAD3, 0xBD8A, 0xBAD4, 0xBD8B, 0x94C2,
+	0xBD8C, 0x94C3, 0xBD8D, 0x94C4, 0xBD8E, 0x94C5, 0xBD8F, 0x94C6,
+	0xBD90, 0xBAD5, 0xBD91, 0xBAD6, 0xBD92, 0x94C7, 0xBD93, 0xBAD7,
+	0xBD94, 0x94C8, 0xBD95, 0xBAD8, 0xBD96, 0x94C9, 0xBD97, 0x94CA,
+	0xBD98, 0x94CB, 0xBD99, 0xBAD9, 0xBD9A, 0xBADA, 0xBD9B, 0x94CC,
+	0xBD9C, 0xBADB, 0xBD9D, 0x94CD, 0xBD9E, 0x94CE, 0xBD9F, 0x94CF,
+	0xBDA0, 0x94D0, 0xBDA1, 0x94D1, 0xBDA2, 0x94D2, 0xBDA3, 0x94D3,
+	0xBDA4, 0xBADC, 0xBDA5, 0x94D4, 0xBDA6, 0x94D5, 0xBDA7, 0x94D6,
+	0xBDA8, 0x94D7, 0xBDA9, 0x94D8, 0xBDAA, 0x94D9, 0xBDAB, 0x94DA,
+	0xBDAC, 0x94DB, 0xBDAD, 0x94DC, 0xBDAE, 0x94DD, 0xBDAF, 0x94DE,
+	0xBDB0, 0xBADD, 0xBDB1, 0x94DF, 0xBDB2, 0x94E0, 0xBDB3, 0x94E1,
+	0xBDB4, 0x94E2, 0xBDB5, 0x94E3, 0xBDB6, 0x94E4, 0xBDB7, 0x94E5,
+	0xBDB8, 0xBADE, 0xBDB9, 0x94E6, 0xBDBA, 0x94E7, 0xBDBB, 0x94E8,
+	0xBDBC, 0x94E9, 0xBDBD, 0x94EA, 0xBDBE, 0x94EB, 0xBDBF, 0x94EC,
+	0xBDC0, 0x94ED, 0xBDC1, 0x94EE, 0xBDC2, 0x94EF, 0xBDC3, 0x94F0,
+	0xBDC4, 0x94F1, 0xBDC5, 0x94F2, 0xBDC6, 0x94F3, 0xBDC7, 0x94F4,
+	0xBDC8, 0x94F5, 0xBDC9, 0x94F6, 0xBDCA, 0x94F7, 0xBDCB, 0x94F8,
+	0xBDCC, 0x94F9, 0xBDCD, 0x94FA, 0xBDCE, 0x94FB, 0xBDCF, 0x94FC,
+	0xBDD0, 0x94FD, 0xBDD1, 0x94FE, 0xBDD2, 0x9541, 0xBDD3, 0x9542,
+	0xBDD4, 0xBADF, 0xBDD5, 0xBAE0, 0xBDD6, 0x9543, 0xBDD7, 0x9544,
+	0xBDD8, 0xBAE1, 0xBDD9, 0x9545, 0xBDDA, 0x9546, 0xBDDB, 0x9547,
+	0xBDDC, 0xBAE2, 0xBDDD, 0x9548, 0xBDDE, 0x9549, 0xBDDF, 0x954A,
+	0xBDE0, 0x954B, 0xBDE1, 0x954C, 0xBDE2, 0x954D, 0xBDE3, 0x954E,
+	0xBDE4, 0x954F, 0xBDE5, 0x9550, 0xBDE6, 0x9551, 0xBDE7, 0x9552,
+	0xBDE8, 0x9553, 0xBDE9, 0xBAE3, 0xBDEA, 0x9554, 0xBDEB, 0x9555,
+	0xBDEC, 0x9556, 0xBDED, 0x9557, 0xBDEE, 0x9558, 0xBDEF, 0x9559,
+	0xBDF0, 0xBAE4, 0xBDF1, 0x955A, 0xBDF2, 0x9561, 0xBDF3, 0x9562,
+	0xBDF4, 0xBAE5, 0xBDF5, 0x9563, 0xBDF6, 0x9564, 0xBDF7, 0x9565,
+	0xBDF8, 0xBAE6, 0xBDF9, 0x9566, 0xBDFA, 0x9567, 0xBDFB, 0x9568,
+	0xBDFC, 0x9569, 0xBDFD, 0x956A, 0xBDFE, 0x956B, 0xBDFF, 0x956C,
+	0xBE00, 0xBAE7, 0xBE01, 0x956D, 0xBE02, 0x956E, 0xBE03, 0xBAE8,
+	0xBE04, 0x956F, 0xBE05, 0xBAE9, 0xBE06, 0x9570, 0xBE07, 0x9571,
+	0xBE08, 0x9572, 0xBE09, 0x9573, 0xBE0A, 0x9574, 0xBE0B, 0x9575,
+	0xBE0C, 0xBAEA, 0xBE0D, 0xBAEB, 0xBE0E, 0x9576, 0xBE0F, 0x9577,
+	0xBE10, 0xBAEC, 0xBE11, 0x9578, 0xBE12, 0x9579, 0xBE13, 0x957A,
+	0xBE14, 0xBAED, 0xBE15, 0x9581, 0xBE16, 0x9582, 0xBE17, 0x9583,
+	0xBE18, 0x9584, 0xBE19, 0x9585, 0xBE1A, 0x9586, 0xBE1B, 0x9587,
+	0xBE1C, 0xBAEE, 0xBE1D, 0xBAEF, 0xBE1E, 0x9588, 0xBE1F, 0xBAF0,
+	0xBE20, 0x9589, 0xBE21, 0x958A, 0xBE22, 0x958B, 0xBE23, 0x958C,
+	0xBE24, 0x958D, 0xBE25, 0x958E, 0xBE26, 0x958F, 0xBE27, 0x9590,
+	0xBE28, 0x9591, 0xBE29, 0x9592, 0xBE2A, 0x9593, 0xBE2B, 0x9594,
+	0xBE2C, 0x9595, 0xBE2D, 0x9596, 0xBE2E, 0x9597, 0xBE2F, 0x9598,
+	0xBE30, 0x9599, 0xBE31, 0x959A, 0xBE32, 0x959B, 0xBE33, 0x959C,
+	0xBE34, 0x959D, 0xBE35, 0x959E, 0xBE36, 0x959F, 0xBE37, 0x95A0,
+	0xBE38, 0x95A1, 0xBE39, 0x95A2, 0xBE3A, 0x95A3, 0xBE3B, 0x95A4,
+	0xBE3C, 0x95A5, 0xBE3D, 0x95A6, 0xBE3E, 0x95A7, 0xBE3F, 0x95A8,
+	0xBE40, 0x95A9, 0xBE41, 0x95AA, 0xBE42, 0x95AB, 0xBE43, 0x95AC,
+	0xBE44, 0xBAF1, 0xBE45, 0xBAF2, 0xBE46, 0x95AD, 0xBE47, 0x95AE,
+	0xBE48, 0xBAF3, 0xBE49, 0x95AF, 0xBE4A, 0x95B0, 0xBE4B, 0x95B1,
+	0xBE4C, 0xBAF4, 0xBE4D, 0x95B2, 0xBE4E, 0xBAF5, 0xBE4F, 0x95B3,
+	0xBE50, 0x95B4, 0xBE51, 0x95B5, 0xBE52, 0x95B6, 0xBE53, 0x95B7,
+	0xBE54, 0xBAF6, 0xBE55, 0xBAF7, 0xBE56, 0x95B8, 0xBE57, 0xBAF8,
+	0xBE58, 0x95B9, 0xBE59, 0xBAF9, 0xBE5A, 0xBAFA, 0xBE5B, 0xBAFB,
+	0xBE5C, 0x95BA, 0xBE5D, 0x95BB, 0xBE5E, 0x95BC, 0xBE5F, 0x95BD,
+	0xBE60, 0xBAFC, 0xBE61, 0xBAFD, 0xBE62, 0x95BE, 0xBE63, 0x95BF,
+	0xBE64, 0xBAFE, 0xBE65, 0x95C0, 0xBE66, 0x95C1, 0xBE67, 0x95C2,
+	0xBE68, 0xBBA1, 0xBE69, 0x95C3, 0xBE6A, 0xBBA2, 0xBE6B, 0x95C4,
+	0xBE6C, 0x95C5, 0xBE6D, 0x95C6, 0xBE6E, 0x95C7, 0xBE6F, 0x95C8,
+	0xBE70, 0xBBA3, 0xBE71, 0xBBA4, 0xBE72, 0x95C9, 0xBE73, 0xBBA5,
+	0xBE74, 0xBBA6, 0xBE75, 0xBBA7, 0xBE76, 0x95CA, 0xBE77, 0x95CB,
+	0xBE78, 0x95CC, 0xBE79, 0x95CD, 0xBE7A, 0x95CE, 0xBE7B, 0xBBA8,
+	0xBE7C, 0xBBA9, 0xBE7D, 0xBBAA, 0xBE7E, 0x95CF, 0xBE7F, 0x95D0,
+	0xBE80, 0xBBAB, 0xBE81, 0x95D1, 0xBE82, 0x95D2, 0xBE83, 0x95D3,
+	0xBE84, 0xBBAC, 0xBE85, 0x95D4, 0xBE86, 0x95D5, 0xBE87, 0x95D6,
+	0xBE88, 0x95D7, 0xBE89, 0x95D8, 0xBE8A, 0x95D9, 0xBE8B, 0x95DA,
+	0xBE8C, 0xBBAD, 0xBE8D, 0xBBAE, 0xBE8E, 0x95DB, 0xBE8F, 0xBBAF,
+	0xBE90, 0xBBB0, 0xBE91, 0xBBB1, 0xBE92, 0x95DC, 0xBE93, 0x95DD,
+	0xBE94, 0x95DE, 0xBE95, 0x95DF, 0xBE96, 0x95E0, 0xBE97, 0x95E1,
+	0xBE98, 0xBBB2, 0xBE99, 0xBBB3, 0xBE9A, 0x95E2, 0xBE9B, 0x95E3,
+	0xBE9C, 0x95E4, 0xBE9D, 0x95E5, 0xBE9E, 0x95E6, 0xBE9F, 0x95E7,
+	0xBEA0, 0x95E8, 0xBEA1, 0x95E9, 0xBEA2, 0x95EA, 0xBEA3, 0x95EB,
+	0xBEA4, 0x95EC, 0xBEA5, 0x95ED, 0xBEA6, 0x95EE, 0xBEA7, 0x95EF,
+	0xBEA8, 0xBBB4, 0xBEA9, 0x95F0, 0xBEAA, 0x95F1, 0xBEAB, 0x95F2,
+	0xBEAC, 0x95F3, 0xBEAD, 0x95F4, 0xBEAE, 0x95F5, 0xBEAF, 0x95F6,
+	0xBEB0, 0x95F7, 0xBEB1, 0x95F8, 0xBEB2, 0x95F9, 0xBEB3, 0x95FA,
+	0xBEB4, 0x95FB, 0xBEB5, 0x95FC, 0xBEB6, 0x95FD, 0xBEB7, 0x95FE,
+	0xBEB8, 0x9641, 0xBEB9, 0x9642, 0xBEBA, 0x9643, 0xBEBB, 0x9644,
+	0xBEBC, 0x9645, 0xBEBD, 0x9646, 0xBEBE, 0x9647, 0xBEBF, 0x9648,
+	0xBEC0, 0x9649, 0xBEC1, 0x964A, 0xBEC2, 0x964B, 0xBEC3, 0x964C,
+	0xBEC4, 0x964D, 0xBEC5, 0x964E, 0xBEC6, 0x964F, 0xBEC7, 0x9650,
+	0xBEC8, 0x9651, 0xBEC9, 0x9652, 0xBECA, 0x9653, 0xBECB, 0x9654,
+	0xBECC, 0x9655, 0xBECD, 0x9656, 0xBECE, 0x9657, 0xBECF, 0x9658,
+	0xBED0, 0xBBB5, 0xBED1, 0xBBB6, 0xBED2, 0x9659, 0xBED3, 0x965A,
+	0xBED4, 0xBBB7, 0xBED5, 0x9661, 0xBED6, 0x9662, 0xBED7, 0xBBB8,
+	0xBED8, 0xBBB9, 0xBED9, 0x9663, 0xBEDA, 0x9664, 0xBEDB, 0x9665,
+	0xBEDC, 0x9666, 0xBEDD, 0x9667, 0xBEDE, 0x9668, 0xBEDF, 0x9669,
+	0xBEE0, 0xBBBA, 0xBEE1, 0x966A, 0xBEE2, 0x966B, 0xBEE3, 0xBBBB,
+	0xBEE4, 0xBBBC, 0xBEE5, 0xBBBD, 0xBEE6, 0x966C, 0xBEE7, 0x966D,
+	0xBEE8, 0x966E, 0xBEE9, 0x966F, 0xBEEA, 0x9670, 0xBEEB, 0x9671,
+	0xBEEC, 0xBBBE, 0xBEED, 0x9672, 0xBEEE, 0x9673, 0xBEEF, 0x9674,
+	0xBEF0, 0x9675, 0xBEF1, 0x9676, 0xBEF2, 0x9677, 0xBEF3, 0x9678,
+	0xBEF4, 0x9679, 0xBEF5, 0x967A, 0xBEF6, 0x9681, 0xBEF7, 0x9682,
+	0xBEF8, 0x9683, 0xBEF9, 0x9684, 0xBEFA, 0x9685, 0xBEFB, 0x9686,
+	0xBEFC, 0x9687, 0xBEFD, 0x9688, 0xBEFE, 0x9689, 0xBEFF, 0x968A,
+	0xBF00, 0x968B, 0xBF01, 0xBBBF, 0xBF02, 0x968C, 0xBF03, 0x968D,
+	0xBF04, 0x968E, 0xBF05, 0x968F, 0xBF06, 0x9690, 0xBF07, 0x9691,
+	0xBF08, 0xBBC0, 0xBF09, 0xBBC1, 0xBF0A, 0x9692, 0xBF0B, 0x9693,
+	0xBF0C, 0x9694, 0xBF0D, 0x9695, 0xBF0E, 0x9696, 0xBF0F, 0x9697,
+	0xBF10, 0x9698, 0xBF11, 0x9699, 0xBF12, 0x969A, 0xBF13, 0x969B,
+	0xBF14, 0x969C, 0xBF15, 0x969D, 0xBF16, 0x969E, 0xBF17, 0x969F,
+	0xBF18, 0xBBC2, 0xBF19, 0xBBC3, 0xBF1A, 0x96A0, 0xBF1B, 0xBBC4,
+	0xBF1C, 0xBBC5, 0xBF1D, 0xBBC6, 0xBF1E, 0x96A1, 0xBF1F, 0x96A2,
+	0xBF20, 0x96A3, 0xBF21, 0x96A4, 0xBF22, 0x96A5, 0xBF23, 0x96A6,
+	0xBF24, 0x96A7, 0xBF25, 0x96A8, 0xBF26, 0x96A9, 0xBF27, 0x96AA,
+	0xBF28, 0x96AB, 0xBF29, 0x96AC, 0xBF2A, 0x96AD, 0xBF2B, 0x96AE,
+	0xBF2C, 0x96AF, 0xBF2D, 0x96B0, 0xBF2E, 0x96B1, 0xBF2F, 0x96B2,
+	0xBF30, 0x96B3, 0xBF31, 0x96B4, 0xBF32, 0x96B5, 0xBF33, 0x96B6,
+	0xBF34, 0x96B7, 0xBF35, 0x96B8, 0xBF36, 0x96B9, 0xBF37, 0x96BA,
+	0xBF38, 0x96BB, 0xBF39, 0x96BC, 0xBF3A, 0x96BD, 0xBF3B, 0x96BE,
+	0xBF3C, 0x96BF, 0xBF3D, 0x96C0, 0xBF3E, 0x96C1, 0xBF3F, 0x96C2,
+	0xBF40, 0xBBC7, 0xBF41, 0xBBC8, 0xBF42, 0x96C3, 0xBF43, 0x96C4,
+	0xBF44, 0xBBC9, 0xBF45, 0x96C5, 0xBF46, 0x96C6, 0xBF47, 0x96C7,
+	0xBF48, 0xBBCA, 0xBF49, 0x96C8, 0xBF4A, 0x96C9, 0xBF4B, 0x96CA,
+	0xBF4C, 0x96CB, 0xBF4D, 0x96CC, 0xBF4E, 0x96CD, 0xBF4F, 0x96CE,
+	0xBF50, 0xBBCB, 0xBF51, 0xBBCC, 0xBF52, 0x96CF, 0xBF53, 0x96D0,
+	0xBF54, 0x96D1, 0xBF55, 0xBBCD, 0xBF56, 0x96D2, 0xBF57, 0x96D3,
+	0xBF58, 0x96D4, 0xBF59, 0x96D5, 0xBF5A, 0x96D6, 0xBF5B, 0x96D7,
+	0xBF5C, 0x96D8, 0xBF5D, 0x96D9, 0xBF5E, 0x96DA, 0xBF5F, 0x96DB,
+	0xBF60, 0x96DC, 0xBF61, 0x96DD, 0xBF62, 0x96DE, 0xBF63, 0x96DF,
+	0xBF64, 0x96E0, 0xBF65, 0x96E1, 0xBF66, 0x96E2, 0xBF67, 0x96E3,
+	0xBF68, 0x96E4, 0xBF69, 0x96E5, 0xBF6A, 0x96E6, 0xBF6B, 0x96E7,
+	0xBF6C, 0x96E8, 0xBF6D, 0x96E9, 0xBF6E, 0x96EA, 0xBF6F, 0x96EB,
+	0xBF70, 0x96EC, 0xBF71, 0x96ED, 0xBF72, 0x96EE, 0xBF73, 0x96EF,
+	0xBF74, 0x96F0, 0xBF75, 0x96F1, 0xBF76, 0x96F2, 0xBF77, 0x96F3,
+	0xBF78, 0x96F4, 0xBF79, 0x96F5, 0xBF7A, 0x96F6, 0xBF7B, 0x96F7,
+	0xBF7C, 0x96F8, 0xBF7D, 0x96F9, 0xBF7E, 0x96FA, 0xBF7F, 0x96FB,
+	0xBF80, 0x96FC, 0xBF81, 0x96FD, 0xBF82, 0x96FE, 0xBF83, 0x9741,
+	0xBF84, 0x9742, 0xBF85, 0x9743, 0xBF86, 0x9744, 0xBF87, 0x9745,
+	0xBF88, 0x9746, 0xBF89, 0x9747, 0xBF8A, 0x9748, 0xBF8B, 0x9749,
+	0xBF8C, 0x974A, 0xBF8D, 0x974B, 0xBF8E, 0x974C, 0xBF8F, 0x974D,
+	0xBF90, 0x974E, 0xBF91, 0x974F, 0xBF92, 0x9750, 0xBF93, 0x9751,
+	0xBF94, 0xBBCE, 0xBF95, 0x9752, 0xBF96, 0x9753, 0xBF97, 0x9754,
+	0xBF98, 0x9755, 0xBF99, 0x9756, 0xBF9A, 0x9757, 0xBF9B, 0x9758,
+	0xBF9C, 0x9759, 0xBF9D, 0x975A, 0xBF9E, 0x9761, 0xBF9F, 0x9762,
+	0xBFA0, 0x9763, 0xBFA1, 0x9764, 0xBFA2, 0x9765, 0xBFA3, 0x9766,
+	0xBFA4, 0x9767, 0xBFA5, 0x9768, 0xBFA6, 0x9769, 0xBFA7, 0x976A,
+	0xBFA8, 0x976B, 0xBFA9, 0x976C, 0xBFAA, 0x976D, 0xBFAB, 0x976E,
+	0xBFAC, 0x976F, 0xBFAD, 0x9770, 0xBFAE, 0x9771, 0xBFAF, 0x9772,
+	0xBFB0, 0xBBCF, 0xBFB1, 0x9773, 0xBFB2, 0x9774, 0xBFB3, 0x9775,
+	0xBFB4, 0x9776, 0xBFB5, 0x9777, 0xBFB6, 0x9778, 0xBFB7, 0x9779,
+	0xBFB8, 0x977A, 0xBFB9, 0x9781, 0xBFBA, 0x9782, 0xBFBB, 0x9783,
+	0xBFBC, 0x9784, 0xBFBD, 0x9785, 0xBFBE, 0x9786, 0xBFBF, 0x9787,
+	0xBFC0, 0x9788, 0xBFC1, 0x9789, 0xBFC2, 0x978A, 0xBFC3, 0x978B,
+	0xBFC4, 0x978C, 0xBFC5, 0xBBD0, 0xBFC6, 0x978D, 0xBFC7, 0x978E,
+	0xBFC8, 0x978F, 0xBFC9, 0x9790, 0xBFCA, 0x9791, 0xBFCB, 0x9792,
+	0xBFCC, 0xBBD1, 0xBFCD, 0xBBD2, 0xBFCE, 0x9793, 0xBFCF, 0x9794,
+	0xBFD0, 0xBBD3, 0xBFD1, 0x9795, 0xBFD2, 0x9796, 0xBFD3, 0x9797,
+	0xBFD4, 0xBBD4, 0xBFD5, 0x9798, 0xBFD6, 0x9799, 0xBFD7, 0x979A,
+	0xBFD8, 0x979B, 0xBFD9, 0x979C, 0xBFDA, 0x979D, 0xBFDB, 0x979E,
+	0xBFDC, 0xBBD5, 0xBFDD, 0x979F, 0xBFDE, 0x97A0, 0xBFDF, 0xBBD6,
+	0xBFE0, 0x97A1, 0xBFE1, 0xBBD7, 0xBFE2, 0x97A2, 0xBFE3, 0x97A3,
+	0xBFE4, 0x97A4, 0xBFE5, 0x97A5, 0xBFE6, 0x97A6, 0xBFE7, 0x97A7,
+	0xBFE8, 0x97A8, 0xBFE9, 0x97A9, 0xBFEA, 0x97AA, 0xBFEB, 0x97AB,
+	0xBFEC, 0x97AC, 0xBFED, 0x97AD, 0xBFEE, 0x97AE, 0xBFEF, 0x97AF,
+	0xBFF0, 0x97B0, 0xBFF1, 0x97B1, 0xBFF2, 0x97B2, 0xBFF3, 0x97B3,
+	0xBFF4, 0x97B4, 0xBFF5, 0x97B5, 0xBFF6, 0x97B6, 0xBFF7, 0x97B7,
+	0xBFF8, 0x97B8, 0xBFF9, 0x97B9, 0xBFFA, 0x97BA, 0xBFFB, 0x97BB,
+	0xBFFC, 0x97BC, 0xBFFD, 0x97BD, 0xBFFE, 0x97BE, 0xBFFF, 0x97BF,
+	0xC000, 0x97C0, 0xC001, 0x97C1, 0xC002, 0x97C2, 0xC003, 0x97C3,
+	0xC004, 0x97C4, 0xC005, 0x97C5, 0xC006, 0x97C6, 0xC007, 0x97C7,
+	0xC008, 0x97C8, 0xC009, 0x97C9, 0xC00A, 0x97CA, 0xC00B, 0x97CB,
+	0xC00C, 0x97CC, 0xC00D, 0x97CD, 0xC00E, 0x97CE, 0xC00F, 0x97CF,
+	0xC010, 0x97D0, 0xC011, 0x97D1, 0xC012, 0x97D2, 0xC013, 0x97D3,
+	0xC014, 0x97D4, 0xC015, 0x97D5, 0xC016, 0x97D6, 0xC017, 0x97D7,
+	0xC018, 0x97D8, 0xC019, 0x97D9, 0xC01A, 0x97DA, 0xC01B, 0x97DB,
+	0xC01C, 0x97DC, 0xC01D, 0x97DD, 0xC01E, 0x97DE, 0xC01F, 0x97DF,
+	0xC020, 0x97E0, 0xC021, 0x97E1, 0xC022, 0x97E2, 0xC023, 0x97E3,
+	0xC024, 0x97E4, 0xC025, 0x97E5, 0xC026, 0x97E6, 0xC027, 0x97E7,
+	0xC028, 0x97E8, 0xC029, 0x97E9, 0xC02A, 0x97EA, 0xC02B, 0x97EB,
+	0xC02C, 0x97EC, 0xC02D, 0x97ED, 0xC02E, 0x97EE, 0xC02F, 0x97EF,
+	0xC030, 0x97F0, 0xC031, 0x97F1, 0xC032, 0x97F2, 0xC033, 0x97F3,
+	0xC034, 0x97F4, 0xC035, 0x97F5, 0xC036, 0x97F6, 0xC037, 0x97F7,
+	0xC038, 0x97F8, 0xC039, 0x97F9, 0xC03A, 0x97FA, 0xC03B, 0x97FB,
+	0xC03C, 0xBBD8, 0xC03D, 0x97FC, 0xC03E, 0x97FD, 0xC03F, 0x97FE,
+	0xC040, 0x9841, 0xC041, 0x9842, 0xC042, 0x9843, 0xC043, 0x9844,
+	0xC044, 0x9845, 0xC045, 0x9846, 0xC046, 0x9847, 0xC047, 0x9848,
+	0xC048, 0x9849, 0xC049, 0x984A, 0xC04A, 0x984B, 0xC04B, 0x984C,
+	0xC04C, 0x984D, 0xC04D, 0x984E, 0xC04E, 0x984F, 0xC04F, 0x9850,
+	0xC050, 0x9851, 0xC051, 0xBBD9, 0xC052, 0x9852, 0xC053, 0x9853,
+	0xC054, 0x9854, 0xC055, 0x9855, 0xC056, 0x9856, 0xC057, 0x9857,
+	0xC058, 0xBBDA, 0xC059, 0x9858, 0xC05A, 0x9859, 0xC05B, 0x985A,
+	0xC05C, 0xBBDB, 0xC05D, 0x9861, 0xC05E, 0x9862, 0xC05F, 0x9863,
+	0xC060, 0xBBDC, 0xC061, 0x9864, 0xC062, 0x9865, 0xC063, 0x9866,
+	0xC064, 0x9867, 0xC065, 0x9868, 0xC066, 0x9869, 0xC067, 0x986A,
+	0xC068, 0xBBDD, 0xC069, 0xBBDE, 0xC06A, 0x986B, 0xC06B, 0x986C,
+	0xC06C, 0x986D, 0xC06D, 0x986E, 0xC06E, 0x986F, 0xC06F, 0x9870,
+	0xC070, 0x9871, 0xC071, 0x9872, 0xC072, 0x9873, 0xC073, 0x9874,
+	0xC074, 0x9875, 0xC075, 0x9876, 0xC076, 0x9877, 0xC077, 0x9878,
+	0xC078, 0x9879, 0xC079, 0x987A, 0xC07A, 0x9881, 0xC07B, 0x9882,
+	0xC07C, 0x9883, 0xC07D, 0x9884, 0xC07E, 0x9885, 0xC07F, 0x9886,
+	0xC080, 0x9887, 0xC081, 0x9888, 0xC082, 0x9889, 0xC083, 0x988A,
+	0xC084, 0x988B, 0xC085, 0x988C, 0xC086, 0x988D, 0xC087, 0x988E,
+	0xC088, 0x988F, 0xC089, 0x9890, 0xC08A, 0x9891, 0xC08B, 0x9892,
+	0xC08C, 0x9893, 0xC08D, 0x9894, 0xC08E, 0x9895, 0xC08F, 0x9896,
+	0xC090, 0xBBDF, 0xC091, 0xBBE0, 0xC092, 0x9897, 0xC093, 0x9898,
+	0xC094, 0xBBE1, 0xC095, 0x9899, 0xC096, 0x989A, 0xC097, 0x989B,
+	0xC098, 0xBBE2, 0xC099, 0x989C, 0xC09A, 0x989D, 0xC09B, 0x989E,
+	0xC09C, 0x989F, 0xC09D, 0x98A0, 0xC09E, 0x98A1, 0xC09F, 0x98A2,
+	0xC0A0, 0xBBE3, 0xC0A1, 0xBBE4, 0xC0A2, 0x98A3, 0xC0A3, 0xBBE5,
+	0xC0A4, 0x98A4, 0xC0A5, 0xBBE6, 0xC0A6, 0x98A5, 0xC0A7, 0x98A6,
+	0xC0A8, 0x98A7, 0xC0A9, 0x98A8, 0xC0AA, 0x98A9, 0xC0AB, 0x98AA,
+	0xC0AC, 0xBBE7, 0xC0AD, 0xBBE8, 0xC0AE, 0x98AB, 0xC0AF, 0xBBE9,
+	0xC0B0, 0xBBEA, 0xC0B1, 0x98AC, 0xC0B2, 0x98AD, 0xC0B3, 0xBBEB,
+	0xC0B4, 0xBBEC, 0xC0B5, 0xBBED, 0xC0B6, 0xBBEE, 0xC0B7, 0x98AE,
+	0xC0B8, 0x98AF, 0xC0B9, 0x98B0, 0xC0BA, 0x98B1, 0xC0BB, 0x98B2,
+	0xC0BC, 0xBBEF, 0xC0BD, 0xBBF0, 0xC0BE, 0x98B3, 0xC0BF, 0xBBF1,
+	0xC0C0, 0xBBF2, 0xC0C1, 0xBBF3, 0xC0C2, 0x98B4, 0xC0C3, 0x98B5,
+	0xC0C4, 0x98B6, 0xC0C5, 0xBBF4, 0xC0C6, 0x98B7, 0xC0C7, 0x98B8,
+	0xC0C8, 0xBBF5, 0xC0C9, 0xBBF6, 0xC0CA, 0x98B9, 0xC0CB, 0x98BA,
+	0xC0CC, 0xBBF7, 0xC0CD, 0x98BB, 0xC0CE, 0x98BC, 0xC0CF, 0x98BD,
+	0xC0D0, 0xBBF8, 0xC0D1, 0x98BE, 0xC0D2, 0x98BF, 0xC0D3, 0x98C0,
+	0xC0D4, 0x98C1, 0xC0D5, 0x98C2, 0xC0D6, 0x98C3, 0xC0D7, 0x98C4,
+	0xC0D8, 0xBBF9, 0xC0D9, 0xBBFA, 0xC0DA, 0x98C5, 0xC0DB, 0xBBFB,
+	0xC0DC, 0xBBFC, 0xC0DD, 0xBBFD, 0xC0DE, 0x98C6, 0xC0DF, 0x98C7,
+	0xC0E0, 0x98C8, 0xC0E1, 0x98C9, 0xC0E2, 0x98CA, 0xC0E3, 0x98CB,
+	0xC0E4, 0xBBFE, 0xC0E5, 0xBCA1, 0xC0E6, 0x98CC, 0xC0E7, 0x98CD,
+	0xC0E8, 0xBCA2, 0xC0E9, 0x98CE, 0xC0EA, 0x98CF, 0xC0EB, 0x98D0,
+	0xC0EC, 0xBCA3, 0xC0ED, 0x98D1, 0xC0EE, 0x98D2, 0xC0EF, 0x98D3,
+	0xC0F0, 0x98D4, 0xC0F1, 0x98D5, 0xC0F2, 0x98D6, 0xC0F3, 0x98D7,
+	0xC0F4, 0xBCA4, 0xC0F5, 0xBCA5, 0xC0F6, 0x98D8, 0xC0F7, 0xBCA6,
+	0xC0F8, 0x98D9, 0xC0F9, 0xBCA7, 0xC0FA, 0x98DA, 0xC0FB, 0x98DB,
+	0xC0FC, 0x98DC, 0xC0FD, 0x98DD, 0xC0FE, 0x98DE, 0xC0FF, 0x98DF,
+	0xC100, 0xBCA8, 0xC101, 0x98E0, 0xC102, 0x98E1, 0xC103, 0x98E2,
+	0xC104, 0xBCA9, 0xC105, 0x98E3, 0xC106, 0x98E4, 0xC107, 0x98E5,
+	0xC108, 0xBCAA, 0xC109, 0x98E6, 0xC10A, 0x98E7, 0xC10B, 0x98E8,
+	0xC10C, 0x98E9, 0xC10D, 0x98EA, 0xC10E, 0x98EB, 0xC10F, 0x98EC,
+	0xC110, 0xBCAB, 0xC111, 0x98ED, 0xC112, 0x98EE, 0xC113, 0x98EF,
+	0xC114, 0x98F0, 0xC115, 0xBCAC, 0xC116, 0x98F1, 0xC117, 0x98F2,
+	0xC118, 0x98F3, 0xC119, 0x98F4, 0xC11A, 0x98F5, 0xC11B, 0x98F6,
+	0xC11C, 0xBCAD, 0xC11D, 0xBCAE, 0xC11E, 0xBCAF, 0xC11F, 0xBCB0,
+	0xC120, 0xBCB1, 0xC121, 0x98F7, 0xC122, 0x98F8, 0xC123, 0xBCB2,
+	0xC124, 0xBCB3, 0xC125, 0x98F9, 0xC126, 0xBCB4, 0xC127, 0xBCB5,
+	0xC128, 0x98FA, 0xC129, 0x98FB, 0xC12A, 0x98FC, 0xC12B, 0x98FD,
+	0xC12C, 0xBCB6, 0xC12D, 0xBCB7, 0xC12E, 0x98FE, 0xC12F, 0xBCB8,
+	0xC130, 0xBCB9, 0xC131, 0xBCBA, 0xC132, 0x9941, 0xC133, 0x9942,
+	0xC134, 0x9943, 0xC135, 0x9944, 0xC136, 0xBCBB, 0xC137, 0x9945,
+	0xC138, 0xBCBC, 0xC139, 0xBCBD, 0xC13A, 0x9946, 0xC13B, 0x9947,
+	0xC13C, 0xBCBE, 0xC13D, 0x9948, 0xC13E, 0x9949, 0xC13F, 0x994A,
+	0xC140, 0xBCBF, 0xC141, 0x994B, 0xC142, 0x994C, 0xC143, 0x994D,
+	0xC144, 0x994E, 0xC145, 0x994F, 0xC146, 0x9950, 0xC147, 0x9951,
+	0xC148, 0xBCC0, 0xC149, 0xBCC1, 0xC14A, 0x9952, 0xC14B, 0xBCC2,
+	0xC14C, 0xBCC3, 0xC14D, 0xBCC4, 0xC14E, 0x9953, 0xC14F, 0x9954,
+	0xC150, 0x9955, 0xC151, 0x9956, 0xC152, 0x9957, 0xC153, 0x9958,
+	0xC154, 0xBCC5, 0xC155, 0xBCC6, 0xC156, 0x9959, 0xC157, 0x995A,
+	0xC158, 0xBCC7, 0xC159, 0x9961, 0xC15A, 0x9962, 0xC15B, 0x9963,
+	0xC15C, 0xBCC8, 0xC15D, 0x9964, 0xC15E, 0x9965, 0xC15F, 0x9966,
+	0xC160, 0x9967, 0xC161, 0x9968, 0xC162, 0x9969, 0xC163, 0x996A,
+	0xC164, 0xBCC9, 0xC165, 0xBCCA, 0xC166, 0x996B, 0xC167, 0xBCCB,
+	0xC168, 0xBCCC, 0xC169, 0xBCCD, 0xC16A, 0x996C, 0xC16B, 0x996D,
+	0xC16C, 0x996E, 0xC16D, 0x996F, 0xC16E, 0x9970, 0xC16F, 0x9971,
+	0xC170, 0xBCCE, 0xC171, 0x9972, 0xC172, 0x9973, 0xC173, 0x9974,
+	0xC174, 0xBCCF, 0xC175, 0x9975, 0xC176, 0x9976, 0xC177, 0x9977,
+	0xC178, 0xBCD0, 0xC179, 0x9978, 0xC17A, 0x9979, 0xC17B, 0x997A,
+	0xC17C, 0x9981, 0xC17D, 0x9982, 0xC17E, 0x9983, 0xC17F, 0x9984,
+	0xC180, 0x9985, 0xC181, 0x9986, 0xC182, 0x9987, 0xC183, 0x9988,
+	0xC184, 0x9989, 0xC185, 0xBCD1, 0xC186, 0x998A, 0xC187, 0x998B,
+	0xC188, 0x998C, 0xC189, 0x998D, 0xC18A, 0x998E, 0xC18B, 0x998F,
+	0xC18C, 0xBCD2, 0xC18D, 0xBCD3, 0xC18E, 0xBCD4, 0xC18F, 0x9990,
+	0xC190, 0xBCD5, 0xC191, 0x9991, 0xC192, 0x9992, 0xC193, 0x9993,
+	0xC194, 0xBCD6, 0xC195, 0x9994, 0xC196, 0xBCD7, 0xC197, 0x9995,
+	0xC198, 0x9996, 0xC199, 0x9997, 0xC19A, 0x9998, 0xC19B, 0x9999,
+	0xC19C, 0xBCD8, 0xC19D, 0xBCD9, 0xC19E, 0x999A, 0xC19F, 0xBCDA,
+	0xC1A0, 0x999B, 0xC1A1, 0xBCDB, 0xC1A2, 0x999C, 0xC1A3, 0x999D,
+	0xC1A4, 0x999E, 0xC1A5, 0xBCDC, 0xC1A6, 0x999F, 0xC1A7, 0x99A0,
+	0xC1A8, 0xBCDD, 0xC1A9, 0xBCDE, 0xC1AA, 0x99A1, 0xC1AB, 0x99A2,
+	0xC1AC, 0xBCDF, 0xC1AD, 0x99A3, 0xC1AE, 0x99A4, 0xC1AF, 0x99A5,
+	0xC1B0, 0xBCE0, 0xC1B1, 0x99A6, 0xC1B2, 0x99A7, 0xC1B3, 0x99A8,
+	0xC1B4, 0x99A9, 0xC1B5, 0x99AA, 0xC1B6, 0x99AB, 0xC1B7, 0x99AC,
+	0xC1B8, 0x99AD, 0xC1B9, 0x99AE, 0xC1BA, 0x99AF, 0xC1BB, 0x99B0,
+	0xC1BC, 0x99B1, 0xC1BD, 0xBCE1, 0xC1BE, 0x99B2, 0xC1BF, 0x99B3,
+	0xC1C0, 0x99B4, 0xC1C1, 0x99B5, 0xC1C2, 0x99B6, 0xC1C3, 0x99B7,
+	0xC1C4, 0xBCE2, 0xC1C5, 0x99B8, 0xC1C6, 0x99B9, 0xC1C7, 0x99BA,
+	0xC1C8, 0xBCE3, 0xC1C9, 0x99BB, 0xC1CA, 0x99BC, 0xC1CB, 0x99BD,
+	0xC1CC, 0xBCE4, 0xC1CD, 0x99BE, 0xC1CE, 0x99BF, 0xC1CF, 0x99C0,
+	0xC1D0, 0x99C1, 0xC1D1, 0x99C2, 0xC1D2, 0x99C3, 0xC1D3, 0x99C4,
+	0xC1D4, 0xBCE5, 0xC1D5, 0x99C5, 0xC1D6, 0x99C6, 0xC1D7, 0xBCE6,
+	0xC1D8, 0xBCE7, 0xC1D9, 0x99C7, 0xC1DA, 0x99C8, 0xC1DB, 0x99C9,
+	0xC1DC, 0x99CA, 0xC1DD, 0x99CB, 0xC1DE, 0x99CC, 0xC1DF, 0x99CD,
+	0xC1E0, 0xBCE8, 0xC1E1, 0x99CE, 0xC1E2, 0x99CF, 0xC1E3, 0x99D0,
+	0xC1E4, 0xBCE9, 0xC1E5, 0x99D1, 0xC1E6, 0x99D2, 0xC1E7, 0x99D3,
+	0xC1E8, 0xBCEA, 0xC1E9, 0x99D4, 0xC1EA, 0x99D5, 0xC1EB, 0x99D6,
+	0xC1EC, 0x99D7, 0xC1ED, 0x99D8, 0xC1EE, 0x99D9, 0xC1EF, 0x99DA,
+	0xC1F0, 0xBCEB, 0xC1F1, 0xBCEC, 0xC1F2, 0x99DB, 0xC1F3, 0xBCED,
+	0xC1F4, 0x99DC, 0xC1F5, 0x99DD, 0xC1F6, 0x99DE, 0xC1F7, 0x99DF,
+	0xC1F8, 0x99E0, 0xC1F9, 0x99E1, 0xC1FA, 0x99E2, 0xC1FB, 0x99E3,
+	0xC1FC, 0xBCEE, 0xC1FD, 0xBCEF, 0xC1FE, 0x99E4, 0xC1FF, 0x99E5,
+	0xC200, 0xBCF0, 0xC201, 0x99E6, 0xC202, 0x99E7, 0xC203, 0x99E8,
+	0xC204, 0xBCF1, 0xC205, 0x99E9, 0xC206, 0x99EA, 0xC207, 0x99EB,
+	0xC208, 0x99EC, 0xC209, 0x99ED, 0xC20A, 0x99EE, 0xC20B, 0x99EF,
+	0xC20C, 0xBCF2, 0xC20D, 0xBCF3, 0xC20E, 0x99F0, 0xC20F, 0xBCF4,
+	0xC210, 0x99F1, 0xC211, 0xBCF5, 0xC212, 0x99F2, 0xC213, 0x99F3,
+	0xC214, 0x99F4, 0xC215, 0x99F5, 0xC216, 0x99F6, 0xC217, 0x99F7,
+	0xC218, 0xBCF6, 0xC219, 0xBCF7, 0xC21A, 0x99F8, 0xC21B, 0x99F9,
+	0xC21C, 0xBCF8, 0xC21D, 0x99FA, 0xC21E, 0x99FB, 0xC21F, 0xBCF9,
+	0xC220, 0xBCFA, 0xC221, 0x99FC, 0xC222, 0x99FD, 0xC223, 0x99FE,
+	0xC224, 0x9A41, 0xC225, 0x9A42, 0xC226, 0x9A43, 0xC227, 0x9A44,
+	0xC228, 0xBCFB, 0xC229, 0xBCFC, 0xC22A, 0x9A45, 0xC22B, 0xBCFD,
+	0xC22C, 0x9A46, 0xC22D, 0xBCFE, 0xC22E, 0x9A47, 0xC22F, 0xBDA1,
+	0xC230, 0x9A48, 0xC231, 0xBDA2, 0xC232, 0xBDA3, 0xC233, 0x9A49,
+	0xC234, 0xBDA4, 0xC235, 0x9A4A, 0xC236, 0x9A4B, 0xC237, 0x9A4C,
+	0xC238, 0x9A4D, 0xC239, 0x9A4E, 0xC23A, 0x9A4F, 0xC23B, 0x9A50,
+	0xC23C, 0x9A51, 0xC23D, 0x9A52, 0xC23E, 0x9A53, 0xC23F, 0x9A54,
+	0xC240, 0x9A55, 0xC241, 0x9A56, 0xC242, 0x9A57, 0xC243, 0x9A58,
+	0xC244, 0x9A59, 0xC245, 0x9A5A, 0xC246, 0x9A61, 0xC247, 0x9A62,
+	0xC248, 0xBDA5, 0xC249, 0x9A63, 0xC24A, 0x9A64, 0xC24B, 0x9A65,
+	0xC24C, 0x9A66, 0xC24D, 0x9A67, 0xC24E, 0x9A68, 0xC24F, 0x9A69,
+	0xC250, 0xBDA6, 0xC251, 0xBDA7, 0xC252, 0x9A6A, 0xC253, 0x9A6B,
+	0xC254, 0xBDA8, 0xC255, 0x9A6C, 0xC256, 0x9A6D, 0xC257, 0x9A6E,
+	0xC258, 0xBDA9, 0xC259, 0x9A6F, 0xC25A, 0x9A70, 0xC25B, 0x9A71,
+	0xC25C, 0x9A72, 0xC25D, 0x9A73, 0xC25E, 0x9A74, 0xC25F, 0x9A75,
+	0xC260, 0xBDAA, 0xC261, 0x9A76, 0xC262, 0x9A77, 0xC263, 0x9A78,
+	0xC264, 0x9A79, 0xC265, 0xBDAB, 0xC266, 0x9A7A, 0xC267, 0x9A81,
+	0xC268, 0x9A82, 0xC269, 0x9A83, 0xC26A, 0x9A84, 0xC26B, 0x9A85,
+	0xC26C, 0xBDAC, 0xC26D, 0xBDAD, 0xC26E, 0x9A86, 0xC26F, 0x9A87,
+	0xC270, 0xBDAE, 0xC271, 0x9A88, 0xC272, 0x9A89, 0xC273, 0x9A8A,
+	0xC274, 0xBDAF, 0xC275, 0x9A8B, 0xC276, 0x9A8C, 0xC277, 0x9A8D,
+	0xC278, 0x9A8E, 0xC279, 0x9A8F, 0xC27A, 0x9A90, 0xC27B, 0x9A91,
+	0xC27C, 0xBDB0, 0xC27D, 0xBDB1, 0xC27E, 0x9A92, 0xC27F, 0xBDB2,
+	0xC280, 0x9A93, 0xC281, 0xBDB3, 0xC282, 0x9A94, 0xC283, 0x9A95,
+	0xC284, 0x9A96, 0xC285, 0x9A97, 0xC286, 0x9A98, 0xC287, 0x9A99,
+	0xC288, 0xBDB4, 0xC289, 0xBDB5, 0xC28A, 0x9A9A, 0xC28B, 0x9A9B,
+	0xC28C, 0x9A9C, 0xC28D, 0x9A9D, 0xC28E, 0x9A9E, 0xC28F, 0x9A9F,
+	0xC290, 0xBDB6, 0xC291, 0x9AA0, 0xC292, 0x9AA1, 0xC293, 0x9AA2,
+	0xC294, 0x9AA3, 0xC295, 0x9AA4, 0xC296, 0x9AA5, 0xC297, 0x9AA6,
+	0xC298, 0xBDB7, 0xC299, 0x9AA7, 0xC29A, 0x9AA8, 0xC29B, 0xBDB8,
+	0xC29C, 0x9AA9, 0xC29D, 0xBDB9, 0xC29E, 0x9AAA, 0xC29F, 0x9AAB,
+	0xC2A0, 0x9AAC, 0xC2A1, 0x9AAD, 0xC2A2, 0x9AAE, 0xC2A3, 0x9AAF,
+	0xC2A4, 0xBDBA, 0xC2A5, 0xBDBB, 0xC2A6, 0x9AB0, 0xC2A7, 0x9AB1,
+	0xC2A8, 0xBDBC, 0xC2A9, 0x9AB2, 0xC2AA, 0x9AB3, 0xC2AB, 0x9AB4,
+	0xC2AC, 0xBDBD, 0xC2AD, 0xBDBE, 0xC2AE, 0x9AB5, 0xC2AF, 0x9AB6,
+	0xC2B0, 0x9AB7, 0xC2B1, 0x9AB8, 0xC2B2, 0x9AB9, 0xC2B3, 0x9ABA,
+	0xC2B4, 0xBDBF, 0xC2B5, 0xBDC0, 0xC2B6, 0x9ABB, 0xC2B7, 0xBDC1,
+	0xC2B8, 0x9ABC, 0xC2B9, 0xBDC2, 0xC2BA, 0x9ABD, 0xC2BB, 0x9ABE,
+	0xC2BC, 0x9ABF, 0xC2BD, 0x9AC0, 0xC2BE, 0x9AC1, 0xC2BF, 0x9AC2,
+	0xC2C0, 0x9AC3, 0xC2C1, 0x9AC4, 0xC2C2, 0x9AC5, 0xC2C3, 0x9AC6,
+	0xC2C4, 0x9AC7, 0xC2C5, 0x9AC8, 0xC2C6, 0x9AC9, 0xC2C7, 0x9ACA,
+	0xC2C8, 0x9ACB, 0xC2C9, 0x9ACC, 0xC2CA, 0x9ACD, 0xC2CB, 0x9ACE,
+	0xC2CC, 0x9ACF, 0xC2CD, 0x9AD0, 0xC2CE, 0x9AD1, 0xC2CF, 0x9AD2,
+	0xC2D0, 0x9AD3, 0xC2D1, 0x9AD4, 0xC2D2, 0x9AD5, 0xC2D3, 0x9AD6,
+	0xC2D4, 0x9AD7, 0xC2D5, 0x9AD8, 0xC2D6, 0x9AD9, 0xC2D7, 0x9ADA,
+	0xC2D8, 0x9ADB, 0xC2D9, 0x9ADC, 0xC2DA, 0x9ADD, 0xC2DB, 0x9ADE,
+	0xC2DC, 0xBDC3, 0xC2DD, 0xBDC4, 0xC2DE, 0x9ADF, 0xC2DF, 0x9AE0,
+	0xC2E0, 0xBDC5, 0xC2E1, 0x9AE1, 0xC2E2, 0x9AE2, 0xC2E3, 0xBDC6,
+	0xC2E4, 0xBDC7, 0xC2E5, 0x9AE3, 0xC2E6, 0x9AE4, 0xC2E7, 0x9AE5,
+	0xC2E8, 0x9AE6, 0xC2E9, 0x9AE7, 0xC2EA, 0x9AE8, 0xC2EB, 0xBDC8,
+	0xC2EC, 0xBDC9, 0xC2ED, 0xBDCA, 0xC2EE, 0x9AE9, 0xC2EF, 0xBDCB,
+	0xC2F0, 0x9AEA, 0xC2F1, 0xBDCC, 0xC2F2, 0x9AEB, 0xC2F3, 0x9AEC,
+	0xC2F4, 0x9AED, 0xC2F5, 0x9AEE, 0xC2F6, 0xBDCD, 0xC2F7, 0x9AEF,
+	0xC2F8, 0xBDCE, 0xC2F9, 0xBDCF, 0xC2FA, 0x9AF0, 0xC2FB, 0xBDD0,
+	0xC2FC, 0xBDD1, 0xC2FD, 0x9AF1, 0xC2FE, 0x9AF2, 0xC2FF, 0x9AF3,
+	0xC300, 0xBDD2, 0xC301, 0x9AF4, 0xC302, 0x9AF5, 0xC303, 0x9AF6,
+	0xC304, 0x9AF7, 0xC305, 0x9AF8, 0xC306, 0x9AF9, 0xC307, 0x9AFA,
+	0xC308, 0xBDD3, 0xC309, 0xBDD4, 0xC30A, 0x9AFB, 0xC30B, 0x9AFC,
+	0xC30C, 0xBDD5, 0xC30D, 0xBDD6, 0xC30E, 0x9AFD, 0xC30F, 0x9AFE,
+	0xC310, 0x9B41, 0xC311, 0x9B42, 0xC312, 0x9B43, 0xC313, 0xBDD7,
+	0xC314, 0xBDD8, 0xC315, 0xBDD9, 0xC316, 0x9B44, 0xC317, 0x9B45,
+	0xC318, 0xBDDA, 0xC319, 0x9B46, 0xC31A, 0x9B47, 0xC31B, 0x9B48,
+	0xC31C, 0xBDDB, 0xC31D, 0x9B49, 0xC31E, 0x9B4A, 0xC31F, 0x9B4B,
+	0xC320, 0x9B4C, 0xC321, 0x9B4D, 0xC322, 0x9B4E, 0xC323, 0x9B4F,
+	0xC324, 0xBDDC, 0xC325, 0xBDDD, 0xC326, 0x9B50, 0xC327, 0x9B51,
+	0xC328, 0xBDDE, 0xC329, 0xBDDF, 0xC32A, 0x9B52, 0xC32B, 0x9B53,
+	0xC32C, 0x9B54, 0xC32D, 0x9B55, 0xC32E, 0x9B56, 0xC32F, 0x9B57,
+	0xC330, 0x9B58, 0xC331, 0x9B59, 0xC332, 0x9B5A, 0xC333, 0x9B61,
+	0xC334, 0x9B62, 0xC335, 0x9B63, 0xC336, 0x9B64, 0xC337, 0x9B65,
+	0xC338, 0x9B66, 0xC339, 0x9B67, 0xC33A, 0x9B68, 0xC33B, 0x9B69,
+	0xC33C, 0x9B6A, 0xC33D, 0x9B6B, 0xC33E, 0x9B6C, 0xC33F, 0x9B6D,
+	0xC340, 0x9B6E, 0xC341, 0x9B6F, 0xC342, 0x9B70, 0xC343, 0x9B71,
+	0xC344, 0x9B72, 0xC345, 0xBDE0, 0xC346, 0x9B73, 0xC347, 0x9B74,
+	0xC348, 0x9B75, 0xC349, 0x9B76, 0xC34A, 0x9B77, 0xC34B, 0x9B78,
+	0xC34C, 0x9B79, 0xC34D, 0x9B7A, 0xC34E, 0x9B81, 0xC34F, 0x9B82,
+	0xC350, 0x9B83, 0xC351, 0x9B84, 0xC352, 0x9B85, 0xC353, 0x9B86,
+	0xC354, 0x9B87, 0xC355, 0x9B88, 0xC356, 0x9B89, 0xC357, 0x9B8A,
+	0xC358, 0x9B8B, 0xC359, 0x9B8C, 0xC35A, 0x9B8D, 0xC35B, 0x9B8E,
+	0xC35C, 0x9B8F, 0xC35D, 0x9B90, 0xC35E, 0x9B91, 0xC35F, 0x9B92,
+	0xC360, 0x9B93, 0xC361, 0x9B94, 0xC362, 0x9B95, 0xC363, 0x9B96,
+	0xC364, 0x9B97, 0xC365, 0x9B98, 0xC366, 0x9B99, 0xC367, 0x9B9A,
+	0xC368, 0xBDE1, 0xC369, 0xBDE2, 0xC36A, 0x9B9B, 0xC36B, 0x9B9C,
+	0xC36C, 0xBDE3, 0xC36D, 0x9B9D, 0xC36E, 0x9B9E, 0xC36F, 0x9B9F,
+	0xC370, 0xBDE4, 0xC371, 0x9BA0, 0xC372, 0xBDE5, 0xC373, 0x9BA1,
+	0xC374, 0x9BA2, 0xC375, 0x9BA3, 0xC376, 0x9BA4, 0xC377, 0x9BA5,
+	0xC378, 0xBDE6, 0xC379, 0xBDE7, 0xC37A, 0x9BA6, 0xC37B, 0x9BA7,
+	0xC37C, 0xBDE8, 0xC37D, 0xBDE9, 0xC37E, 0x9BA8, 0xC37F, 0x9BA9,
+	0xC380, 0x9BAA, 0xC381, 0x9BAB, 0xC382, 0x9BAC, 0xC383, 0x9BAD,
+	0xC384, 0xBDEA, 0xC385, 0x9BAE, 0xC386, 0x9BAF, 0xC387, 0x9BB0,
+	0xC388, 0xBDEB, 0xC389, 0x9BB1, 0xC38A, 0x9BB2, 0xC38B, 0x9BB3,
+	0xC38C, 0xBDEC, 0xC38D, 0x9BB4, 0xC38E, 0x9BB5, 0xC38F, 0x9BB6,
+	0xC390, 0x9BB7, 0xC391, 0x9BB8, 0xC392, 0x9BB9, 0xC393, 0x9BBA,
+	0xC394, 0x9BBB, 0xC395, 0x9BBC, 0xC396, 0x9BBD, 0xC397, 0x9BBE,
+	0xC398, 0x9BBF, 0xC399, 0x9BC0, 0xC39A, 0x9BC1, 0xC39B, 0x9BC2,
+	0xC39C, 0x9BC3, 0xC39D, 0x9BC4, 0xC39E, 0x9BC5, 0xC39F, 0x9BC6,
+	0xC3A0, 0x9BC7, 0xC3A1, 0x9BC8, 0xC3A2, 0x9BC9, 0xC3A3, 0x9BCA,
+	0xC3A4, 0x9BCB, 0xC3A5, 0x9BCC, 0xC3A6, 0x9BCD, 0xC3A7, 0x9BCE,
+	0xC3A8, 0x9BCF, 0xC3A9, 0x9BD0, 0xC3AA, 0x9BD1, 0xC3AB, 0x9BD2,
+	0xC3AC, 0x9BD3, 0xC3AD, 0x9BD4, 0xC3AE, 0x9BD5, 0xC3AF, 0x9BD6,
+	0xC3B0, 0x9BD7, 0xC3B1, 0x9BD8, 0xC3B2, 0x9BD9, 0xC3B3, 0x9BDA,
+	0xC3B4, 0x9BDB, 0xC3B5, 0x9BDC, 0xC3B6, 0x9BDD, 0xC3B7, 0x9BDE,
+	0xC3B8, 0x9BDF, 0xC3B9, 0x9BE0, 0xC3BA, 0x9BE1, 0xC3BB, 0x9BE2,
+	0xC3BC, 0x9BE3, 0xC3BD, 0x9BE4, 0xC3BE, 0x9BE5, 0xC3BF, 0x9BE6,
+	0xC3C0, 0xBDED, 0xC3C1, 0x9BE7, 0xC3C2, 0x9BE8, 0xC3C3, 0x9BE9,
+	0xC3C4, 0x9BEA, 0xC3C5, 0x9BEB, 0xC3C6, 0x9BEC, 0xC3C7, 0x9BED,
+	0xC3C8, 0x9BEE, 0xC3C9, 0x9BEF, 0xC3CA, 0x9BF0, 0xC3CB, 0x9BF1,
+	0xC3CC, 0x9BF2, 0xC3CD, 0x9BF3, 0xC3CE, 0x9BF4, 0xC3CF, 0x9BF5,
+	0xC3D0, 0x9BF6, 0xC3D1, 0x9BF7, 0xC3D2, 0x9BF8, 0xC3D3, 0x9BF9,
+	0xC3D4, 0x9BFA, 0xC3D5, 0x9BFB, 0xC3D6, 0x9BFC, 0xC3D7, 0x9BFD,
+	0xC3D8, 0xBDEE, 0xC3D9, 0xBDEF, 0xC3DA, 0x9BFE, 0xC3DB, 0x9C41,
+	0xC3DC, 0xBDF0, 0xC3DD, 0x9C42, 0xC3DE, 0x9C43, 0xC3DF, 0xBDF1,
+	0xC3E0, 0xBDF2, 0xC3E1, 0x9C44, 0xC3E2, 0xBDF3, 0xC3E3, 0x9C45,
+	0xC3E4, 0x9C46, 0xC3E5, 0x9C47, 0xC3E6, 0x9C48, 0xC3E7, 0x9C49,
+	0xC3E8, 0xBDF4, 0xC3E9, 0xBDF5, 0xC3EA, 0x9C4A, 0xC3EB, 0x9C4B,
+	0xC3EC, 0x9C4C, 0xC3ED, 0xBDF6, 0xC3EE, 0x9C4D, 0xC3EF, 0x9C4E,
+	0xC3F0, 0x9C4F, 0xC3F1, 0x9C50, 0xC3F2, 0x9C51, 0xC3F3, 0x9C52,
+	0xC3F4, 0xBDF7, 0xC3F5, 0xBDF8, 0xC3F6, 0x9C53, 0xC3F7, 0x9C54,
+	0xC3F8, 0xBDF9, 0xC3F9, 0x9C55, 0xC3FA, 0x9C56, 0xC3FB, 0x9C57,
+	0xC3FC, 0x9C58, 0xC3FD, 0x9C59, 0xC3FE, 0x9C5A, 0xC3FF, 0x9C61,
+	0xC400, 0x9C62, 0xC401, 0x9C63, 0xC402, 0x9C64, 0xC403, 0x9C65,
+	0xC404, 0x9C66, 0xC405, 0x9C67, 0xC406, 0x9C68, 0xC407, 0x9C69,
+	0xC408, 0xBDFA, 0xC409, 0x9C6A, 0xC40A, 0x9C6B, 0xC40B, 0x9C6C,
+	0xC40C, 0x9C6D, 0xC40D, 0x9C6E, 0xC40E, 0x9C6F, 0xC40F, 0x9C70,
+	0xC410, 0xBDFB, 0xC411, 0x9C71, 0xC412, 0x9C72, 0xC413, 0x9C73,
+	0xC414, 0x9C74, 0xC415, 0x9C75, 0xC416, 0x9C76, 0xC417, 0x9C77,
+	0xC418, 0x9C78, 0xC419, 0x9C79, 0xC41A, 0x9C7A, 0xC41B, 0x9C81,
+	0xC41C, 0x9C82, 0xC41D, 0x9C83, 0xC41E, 0x9C84, 0xC41F, 0x9C85,
+	0xC420, 0x9C86, 0xC421, 0x9C87, 0xC422, 0x9C88, 0xC423, 0x9C89,
+	0xC424, 0xBDFC, 0xC425, 0x9C8A, 0xC426, 0x9C8B, 0xC427, 0x9C8C,
+	0xC428, 0x9C8D, 0xC429, 0x9C8E, 0xC42A, 0x9C8F, 0xC42B, 0x9C90,
+	0xC42C, 0xBDFD, 0xC42D, 0x9C91, 0xC42E, 0x9C92, 0xC42F, 0x9C93,
+	0xC430, 0xBDFE, 0xC431, 0x9C94, 0xC432, 0x9C95, 0xC433, 0x9C96,
+	0xC434, 0xBEA1, 0xC435, 0x9C97, 0xC436, 0x9C98, 0xC437, 0x9C99,
+	0xC438, 0x9C9A, 0xC439, 0x9C9B, 0xC43A, 0x9C9C, 0xC43B, 0x9C9D,
+	0xC43C, 0xBEA2, 0xC43D, 0xBEA3, 0xC43E, 0x9C9E, 0xC43F, 0x9C9F,
+	0xC440, 0x9CA0, 0xC441, 0x9CA1, 0xC442, 0x9CA2, 0xC443, 0x9CA3,
+	0xC444, 0x9CA4, 0xC445, 0x9CA5, 0xC446, 0x9CA6, 0xC447, 0x9CA7,
+	0xC448, 0xBEA4, 0xC449, 0x9CA8, 0xC44A, 0x9CA9, 0xC44B, 0x9CAA,
+	0xC44C, 0x9CAB, 0xC44D, 0x9CAC, 0xC44E, 0x9CAD, 0xC44F, 0x9CAE,
+	0xC450, 0x9CAF, 0xC451, 0x9CB0, 0xC452, 0x9CB1, 0xC453, 0x9CB2,
+	0xC454, 0x9CB3, 0xC455, 0x9CB4, 0xC456, 0x9CB5, 0xC457, 0x9CB6,
+	0xC458, 0x9CB7, 0xC459, 0x9CB8, 0xC45A, 0x9CB9, 0xC45B, 0x9CBA,
+	0xC45C, 0x9CBB, 0xC45D, 0x9CBC, 0xC45E, 0x9CBD, 0xC45F, 0x9CBE,
+	0xC460, 0x9CBF, 0xC461, 0x9CC0, 0xC462, 0x9CC1, 0xC463, 0x9CC2,
+	0xC464, 0xBEA5, 0xC465, 0xBEA6, 0xC466, 0x9CC3, 0xC467, 0x9CC4,
+	0xC468, 0xBEA7, 0xC469, 0x9CC5, 0xC46A, 0x9CC6, 0xC46B, 0x9CC7,
+	0xC46C, 0xBEA8, 0xC46D, 0x9CC8, 0xC46E, 0x9CC9, 0xC46F, 0x9CCA,
+	0xC470, 0x9CCB, 0xC471, 0x9CCC, 0xC472, 0x9CCD, 0xC473, 0x9CCE,
+	0xC474, 0xBEA9, 0xC475, 0xBEAA, 0xC476, 0x9CCF, 0xC477, 0x9CD0,
+	0xC478, 0x9CD1, 0xC479, 0xBEAB, 0xC47A, 0x9CD2, 0xC47B, 0x9CD3,
+	0xC47C, 0x9CD4, 0xC47D, 0x9CD5, 0xC47E, 0x9CD6, 0xC47F, 0x9CD7,
+	0xC480, 0xBEAC, 0xC481, 0x9CD8, 0xC482, 0x9CD9, 0xC483, 0x9CDA,
+	0xC484, 0x9CDB, 0xC485, 0x9CDC, 0xC486, 0x9CDD, 0xC487, 0x9CDE,
+	0xC488, 0x9CDF, 0xC489, 0x9CE0, 0xC48A, 0x9CE1, 0xC48B, 0x9CE2,
+	0xC48C, 0x9CE3, 0xC48D, 0x9CE4, 0xC48E, 0x9CE5, 0xC48F, 0x9CE6,
+	0xC490, 0x9CE7, 0xC491, 0x9CE8, 0xC492, 0x9CE9, 0xC493, 0x9CEA,
+	0xC494, 0xBEAD, 0xC495, 0x9CEB, 0xC496, 0x9CEC, 0xC497, 0x9CED,
+	0xC498, 0x9CEE, 0xC499, 0x9CEF, 0xC49A, 0x9CF0, 0xC49B, 0x9CF1,
+	0xC49C, 0xBEAE, 0xC49D, 0x9CF2, 0xC49E, 0x9CF3, 0xC49F, 0x9CF4,
+	0xC4A0, 0x9CF5, 0xC4A1, 0x9CF6, 0xC4A2, 0x9CF7, 0xC4A3, 0x9CF8,
+	0xC4A4, 0x9CF9, 0xC4A5, 0x9CFA, 0xC4A6, 0x9CFB, 0xC4A7, 0x9CFC,
+	0xC4A8, 0x9CFD, 0xC4A9, 0x9CFE, 0xC4AA, 0x9D41, 0xC4AB, 0x9D42,
+	0xC4AC, 0x9D43, 0xC4AD, 0x9D44, 0xC4AE, 0x9D45, 0xC4AF, 0x9D46,
+	0xC4B0, 0x9D47, 0xC4B1, 0x9D48, 0xC4B2, 0x9D49, 0xC4B3, 0x9D4A,
+	0xC4B4, 0x9D4B, 0xC4B5, 0x9D4C, 0xC4B6, 0x9D4D, 0xC4B7, 0x9D4E,
+	0xC4B8, 0xBEAF, 0xC4B9, 0x9D4F, 0xC4BA, 0x9D50, 0xC4BB, 0x9D51,
+	0xC4BC, 0xBEB0, 0xC4BD, 0x9D52, 0xC4BE, 0x9D53, 0xC4BF, 0x9D54,
+	0xC4C0, 0x9D55, 0xC4C1, 0x9D56, 0xC4C2, 0x9D57, 0xC4C3, 0x9D58,
+	0xC4C4, 0x9D59, 0xC4C5, 0x9D5A, 0xC4C6, 0x9D61, 0xC4C7, 0x9D62,
+	0xC4C8, 0x9D63, 0xC4C9, 0x9D64, 0xC4CA, 0x9D65, 0xC4CB, 0x9D66,
+	0xC4CC, 0x9D67, 0xC4CD, 0x9D68, 0xC4CE, 0x9D69, 0xC4CF, 0x9D6A,
+	0xC4D0, 0x9D6B, 0xC4D1, 0x9D6C, 0xC4D2, 0x9D6D, 0xC4D3, 0x9D6E,
+	0xC4D4, 0x9D6F, 0xC4D5, 0x9D70, 0xC4D6, 0x9D71, 0xC4D7, 0x9D72,
+	0xC4D8, 0x9D73, 0xC4D9, 0x9D74, 0xC4DA, 0x9D75, 0xC4DB, 0x9D76,
+	0xC4DC, 0x9D77, 0xC4DD, 0x9D78, 0xC4DE, 0x9D79, 0xC4DF, 0x9D7A,
+	0xC4E0, 0x9D81, 0xC4E1, 0x9D82, 0xC4E2, 0x9D83, 0xC4E3, 0x9D84,
+	0xC4E4, 0x9D85, 0xC4E5, 0x9D86, 0xC4E6, 0x9D87, 0xC4E7, 0x9D88,
+	0xC4E8, 0x9D89, 0xC4E9, 0xBEB1, 0xC4EA, 0x9D8A, 0xC4EB, 0x9D8B,
+	0xC4EC, 0x9D8C, 0xC4ED, 0x9D8D, 0xC4EE, 0x9D8E, 0xC4EF, 0x9D8F,
+	0xC4F0, 0xBEB2, 0xC4F1, 0xBEB3, 0xC4F2, 0x9D90, 0xC4F3, 0x9D91,
+	0xC4F4, 0xBEB4, 0xC4F5, 0x9D92, 0xC4F6, 0x9D93, 0xC4F7, 0x9D94,
+	0xC4F8, 0xBEB5, 0xC4F9, 0x9D95, 0xC4FA, 0xBEB6, 0xC4FB, 0x9D96,
+	0xC4FC, 0x9D97, 0xC4FD, 0x9D98, 0xC4FE, 0x9D99, 0xC4FF, 0xBEB7,
+	0xC500, 0xBEB8, 0xC501, 0xBEB9, 0xC502, 0x9D9A, 0xC503, 0x9D9B,
+	0xC504, 0x9D9C, 0xC505, 0x9D9D, 0xC506, 0x9D9E, 0xC507, 0x9D9F,
+	0xC508, 0x9DA0, 0xC509, 0x9DA1, 0xC50A, 0x9DA2, 0xC50B, 0x9DA3,
+	0xC50C, 0xBEBA, 0xC50D, 0x9DA4, 0xC50E, 0x9DA5, 0xC50F, 0x9DA6,
+	0xC510, 0xBEBB, 0xC511, 0x9DA7, 0xC512, 0x9DA8, 0xC513, 0x9DA9,
+	0xC514, 0xBEBC, 0xC515, 0x9DAA, 0xC516, 0x9DAB, 0xC517, 0x9DAC,
+	0xC518, 0x9DAD, 0xC519, 0x9DAE, 0xC51A, 0x9DAF, 0xC51B, 0x9DB0,
+	0xC51C, 0xBEBD, 0xC51D, 0x9DB1, 0xC51E, 0x9DB2, 0xC51F, 0x9DB3,
+	0xC520, 0x9DB4, 0xC521, 0x9DB5, 0xC522, 0x9DB6, 0xC523, 0x9DB7,
+	0xC524, 0x9DB8, 0xC525, 0x9DB9, 0xC526, 0x9DBA, 0xC527, 0x9DBB,
+	0xC528, 0xBEBE, 0xC529, 0xBEBF, 0xC52A, 0x9DBC, 0xC52B, 0x9DBD,
+	0xC52C, 0xBEC0, 0xC52D, 0x9DBE, 0xC52E, 0x9DBF, 0xC52F, 0x9DC0,
+	0xC530, 0xBEC1, 0xC531, 0x9DC1, 0xC532, 0x9DC2, 0xC533, 0x9DC3,
+	0xC534, 0x9DC4, 0xC535, 0x9DC5, 0xC536, 0x9DC6, 0xC537, 0x9DC7,
+	0xC538, 0xBEC2, 0xC539, 0xBEC3, 0xC53A, 0x9DC8, 0xC53B, 0xBEC4,
+	0xC53C, 0x9DC9, 0xC53D, 0xBEC5, 0xC53E, 0x9DCA, 0xC53F, 0x9DCB,
+	0xC540, 0x9DCC, 0xC541, 0x9DCD, 0xC542, 0x9DCE, 0xC543, 0x9DCF,
+	0xC544, 0xBEC6, 0xC545, 0xBEC7, 0xC546, 0x9DD0, 0xC547, 0x9DD1,
+	0xC548, 0xBEC8, 0xC549, 0xBEC9, 0xC54A, 0xBECA, 0xC54B, 0x9DD2,
+	0xC54C, 0xBECB, 0xC54D, 0xBECC, 0xC54E, 0xBECD, 0xC54F, 0x9DD3,
+	0xC550, 0x9DD4, 0xC551, 0x9DD5, 0xC552, 0x9DD6, 0xC553, 0xBECE,
+	0xC554, 0xBECF, 0xC555, 0xBED0, 0xC556, 0x9DD7, 0xC557, 0xBED1,
+	0xC558, 0xBED2, 0xC559, 0xBED3, 0xC55A, 0x9DD8, 0xC55B, 0x9DD9,
+	0xC55C, 0x9DDA, 0xC55D, 0xBED4, 0xC55E, 0xBED5, 0xC55F, 0x9DDB,
+	0xC560, 0xBED6, 0xC561, 0xBED7, 0xC562, 0x9DDC, 0xC563, 0x9DDD,
+	0xC564, 0xBED8, 0xC565, 0x9DDE, 0xC566, 0x9DDF, 0xC567, 0x9DE0,
+	0xC568, 0xBED9, 0xC569, 0x9DE1, 0xC56A, 0x9DE2, 0xC56B, 0x9DE3,
+	0xC56C, 0x9DE4, 0xC56D, 0x9DE5, 0xC56E, 0x9DE6, 0xC56F, 0x9DE7,
+	0xC570, 0xBEDA, 0xC571, 0xBEDB, 0xC572, 0x9DE8, 0xC573, 0xBEDC,
+	0xC574, 0xBEDD, 0xC575, 0xBEDE, 0xC576, 0x9DE9, 0xC577, 0x9DEA,
+	0xC578, 0x9DEB, 0xC579, 0x9DEC, 0xC57A, 0x9DED, 0xC57B, 0x9DEE,
+	0xC57C, 0xBEDF, 0xC57D, 0xBEE0, 0xC57E, 0x9DEF, 0xC57F, 0x9DF0,
+	0xC580, 0xBEE1, 0xC581, 0x9DF1, 0xC582, 0x9DF2, 0xC583, 0x9DF3,
+	0xC584, 0xBEE2, 0xC585, 0x9DF4, 0xC586, 0x9DF5, 0xC587, 0xBEE3,
+	0xC588, 0x9DF6, 0xC589, 0x9DF7, 0xC58A, 0x9DF8, 0xC58B, 0x9DF9,
+	0xC58C, 0xBEE4, 0xC58D, 0xBEE5, 0xC58E, 0x9DFA, 0xC58F, 0xBEE6,
+	0xC590, 0x9DFB, 0xC591, 0xBEE7, 0xC592, 0x9DFC, 0xC593, 0x9DFD,
+	0xC594, 0x9DFE, 0xC595, 0xBEE8, 0xC596, 0x9E41, 0xC597, 0xBEE9,
+	0xC598, 0xBEEA, 0xC599, 0x9E42, 0xC59A, 0x9E43, 0xC59B, 0x9E44,
+	0xC59C, 0xBEEB, 0xC59D, 0x9E45, 0xC59E, 0x9E46, 0xC59F, 0x9E47,
+	0xC5A0, 0xBEEC, 0xC5A1, 0x9E48, 0xC5A2, 0x9E49, 0xC5A3, 0x9E4A,
+	0xC5A4, 0x9E4B, 0xC5A5, 0x9E4C, 0xC5A6, 0x9E4D, 0xC5A7, 0x9E4E,
+	0xC5A8, 0x9E4F, 0xC5A9, 0xBEED, 0xC5AA, 0x9E50, 0xC5AB, 0x9E51,
+	0xC5AC, 0x9E52, 0xC5AD, 0x9E53, 0xC5AE, 0x9E54, 0xC5AF, 0x9E55,
+	0xC5B0, 0x9E56, 0xC5B1, 0x9E57, 0xC5B2, 0x9E58, 0xC5B3, 0x9E59,
+	0xC5B4, 0xBEEE, 0xC5B5, 0xBEEF, 0xC5B6, 0x9E5A, 0xC5B7, 0x9E61,
+	0xC5B8, 0xBEF0, 0xC5B9, 0xBEF1, 0xC5BA, 0x9E62, 0xC5BB, 0xBEF2,
+	0xC5BC, 0xBEF3, 0xC5BD, 0xBEF4, 0xC5BE, 0xBEF5, 0xC5BF, 0x9E63,
+	0xC5C0, 0x9E64, 0xC5C1, 0x9E65, 0xC5C2, 0x9E66, 0xC5C3, 0x9E67,
+	0xC5C4, 0xBEF6, 0xC5C5, 0xBEF7, 0xC5C6, 0xBEF8, 0xC5C7, 0xBEF9,
+	0xC5C8, 0xBEFA, 0xC5C9, 0xBEFB, 0xC5CA, 0xBEFC, 0xC5CB, 0x9E68,
+	0xC5CC, 0xBEFD, 0xC5CD, 0x9E69, 0xC5CE, 0xBEFE, 0xC5CF, 0x9E6A,
+	0xC5D0, 0xBFA1, 0xC5D1, 0xBFA2, 0xC5D2, 0x9E6B, 0xC5D3, 0x9E6C,
+	0xC5D4, 0xBFA3, 0xC5D5, 0x9E6D, 0xC5D6, 0x9E6E, 0xC5D7, 0x9E6F,
+	0xC5D8, 0xBFA4, 0xC5D9, 0x9E70, 0xC5DA, 0x9E71, 0xC5DB, 0x9E72,
+	0xC5DC, 0x9E73, 0xC5DD, 0x9E74, 0xC5DE, 0x9E75, 0xC5DF, 0x9E76,
+	0xC5E0, 0xBFA5, 0xC5E1, 0xBFA6, 0xC5E2, 0x9E77, 0xC5E3, 0xBFA7,
+	0xC5E4, 0x9E78, 0xC5E5, 0xBFA8, 0xC5E6, 0x9E79, 0xC5E7, 0x9E7A,
+	0xC5E8, 0x9E81, 0xC5E9, 0x9E82, 0xC5EA, 0x9E83, 0xC5EB, 0x9E84,
+	0xC5EC, 0xBFA9, 0xC5ED, 0xBFAA, 0xC5EE, 0xBFAB, 0xC5EF, 0x9E85,
+	0xC5F0, 0xBFAC, 0xC5F1, 0x9E86, 0xC5F2, 0x9E87, 0xC5F3, 0x9E88,
+	0xC5F4, 0xBFAD, 0xC5F5, 0x9E89, 0xC5F6, 0xBFAE, 0xC5F7, 0xBFAF,
+	0xC5F8, 0x9E8A, 0xC5F9, 0x9E8B, 0xC5FA, 0x9E8C, 0xC5FB, 0x9E8D,
+	0xC5FC, 0xBFB0, 0xC5FD, 0xBFB1, 0xC5FE, 0xBFB2, 0xC5FF, 0xBFB3,
+	0xC600, 0xBFB4, 0xC601, 0xBFB5, 0xC602, 0x9E8E, 0xC603, 0x9E8F,
+	0xC604, 0x9E90, 0xC605, 0xBFB6, 0xC606, 0xBFB7, 0xC607, 0xBFB8,
+	0xC608, 0xBFB9, 0xC609, 0x9E91, 0xC60A, 0x9E92, 0xC60B, 0x9E93,
+	0xC60C, 0xBFBA, 0xC60D, 0x9E94, 0xC60E, 0x9E95, 0xC60F, 0x9E96,
+	0xC610, 0xBFBB, 0xC611, 0x9E97, 0xC612, 0x9E98, 0xC613, 0x9E99,
+	0xC614, 0x9E9A, 0xC615, 0x9E9B, 0xC616, 0x9E9C, 0xC617, 0x9E9D,
+	0xC618, 0xBFBC, 0xC619, 0xBFBD, 0xC61A, 0x9E9E, 0xC61B, 0xBFBE,
+	0xC61C, 0xBFBF, 0xC61D, 0x9E9F, 0xC61E, 0x9EA0, 0xC61F, 0x9EA1,
+	0xC620, 0x9EA2, 0xC621, 0x9EA3, 0xC622, 0x9EA4, 0xC623, 0x9EA5,
+	0xC624, 0xBFC0, 0xC625, 0xBFC1, 0xC626, 0x9EA6, 0xC627, 0x9EA7,
+	0xC628, 0xBFC2, 0xC629, 0x9EA8, 0xC62A, 0x9EA9, 0xC62B, 0x9EAA,
+	0xC62C, 0xBFC3, 0xC62D, 0xBFC4, 0xC62E, 0xBFC5, 0xC62F, 0x9EAB,
+	0xC630, 0xBFC6, 0xC631, 0x9EAC, 0xC632, 0x9EAD, 0xC633, 0xBFC7,
+	0xC634, 0xBFC8, 0xC635, 0xBFC9, 0xC636, 0x9EAE, 0xC637, 0xBFCA,
+	0xC638, 0x9EAF, 0xC639, 0xBFCB, 0xC63A, 0x9EB0, 0xC63B, 0xBFCC,
+	0xC63C, 0x9EB1, 0xC63D, 0x9EB2, 0xC63E, 0x9EB3, 0xC63F, 0x9EB4,
+	0xC640, 0xBFCD, 0xC641, 0xBFCE, 0xC642, 0x9EB5, 0xC643, 0x9EB6,
+	0xC644, 0xBFCF, 0xC645, 0x9EB7, 0xC646, 0x9EB8, 0xC647, 0x9EB9,
+	0xC648, 0xBFD0, 0xC649, 0x9EBA, 0xC64A, 0x9EBB, 0xC64B, 0x9EBC,
+	0xC64C, 0x9EBD, 0xC64D, 0x9EBE, 0xC64E, 0x9EBF, 0xC64F, 0x9EC0,
+	0xC650, 0xBFD1, 0xC651, 0xBFD2, 0xC652, 0x9EC1, 0xC653, 0xBFD3,
+	0xC654, 0xBFD4, 0xC655, 0xBFD5, 0xC656, 0x9EC2, 0xC657, 0x9EC3,
+	0xC658, 0x9EC4, 0xC659, 0x9EC5, 0xC65A, 0x9EC6, 0xC65B, 0x9EC7,
+	0xC65C, 0xBFD6, 0xC65D, 0xBFD7, 0xC65E, 0x9EC8, 0xC65F, 0x9EC9,
+	0xC660, 0xBFD8, 0xC661, 0x9ECA, 0xC662, 0x9ECB, 0xC663, 0x9ECC,
+	0xC664, 0x9ECD, 0xC665, 0x9ECE, 0xC666, 0x9ECF, 0xC667, 0x9ED0,
+	0xC668, 0x9ED1, 0xC669, 0x9ED2, 0xC66A, 0x9ED3, 0xC66B, 0x9ED4,
+	0xC66C, 0xBFD9, 0xC66D, 0x9ED5, 0xC66E, 0x9ED6, 0xC66F, 0xBFDA,
+	0xC670, 0x9ED7, 0xC671, 0xBFDB, 0xC672, 0x9ED8, 0xC673, 0x9ED9,
+	0xC674, 0x9EDA, 0xC675, 0x9EDB, 0xC676, 0x9EDC, 0xC677, 0x9EDD,
+	0xC678, 0xBFDC, 0xC679, 0xBFDD, 0xC67A, 0x9EDE, 0xC67B, 0x9EDF,
+	0xC67C, 0xBFDE, 0xC67D, 0x9EE0, 0xC67E, 0x9EE1, 0xC67F, 0x9EE2,
+	0xC680, 0xBFDF, 0xC681, 0x9EE3, 0xC682, 0x9EE4, 0xC683, 0x9EE5,
+	0xC684, 0x9EE6, 0xC685, 0x9EE7, 0xC686, 0x9EE8, 0xC687, 0x9EE9,
+	0xC688, 0xBFE0, 0xC689, 0xBFE1, 0xC68A, 0x9EEA, 0xC68B, 0xBFE2,
+	0xC68C, 0x9EEB, 0xC68D, 0xBFE3, 0xC68E, 0x9EEC, 0xC68F, 0x9EED,
+	0xC690, 0x9EEE, 0xC691, 0x9EEF, 0xC692, 0x9EF0, 0xC693, 0x9EF1,
+	0xC694, 0xBFE4, 0xC695, 0xBFE5, 0xC696, 0x9EF2, 0xC697, 0x9EF3,
+	0xC698, 0xBFE6, 0xC699, 0x9EF4, 0xC69A, 0x9EF5, 0xC69B, 0x9EF6,
+	0xC69C, 0xBFE7, 0xC69D, 0x9EF7, 0xC69E, 0x9EF8, 0xC69F, 0x9EF9,
+	0xC6A0, 0x9EFA, 0xC6A1, 0x9EFB, 0xC6A2, 0x9EFC, 0xC6A3, 0x9EFD,
+	0xC6A4, 0xBFE8, 0xC6A5, 0xBFE9, 0xC6A6, 0x9EFE, 0xC6A7, 0xBFEA,
+	0xC6A8, 0x9F41, 0xC6A9, 0xBFEB, 0xC6AA, 0x9F42, 0xC6AB, 0x9F43,
+	0xC6AC, 0x9F44, 0xC6AD, 0x9F45, 0xC6AE, 0x9F46, 0xC6AF, 0x9F47,
+	0xC6B0, 0xBFEC, 0xC6B1, 0xBFED, 0xC6B2, 0x9F48, 0xC6B3, 0x9F49,
+	0xC6B4, 0xBFEE, 0xC6B5, 0x9F4A, 0xC6B6, 0x9F4B, 0xC6B7, 0x9F4C,
+	0xC6B8, 0xBFEF, 0xC6B9, 0xBFF0, 0xC6BA, 0xBFF1, 0xC6BB, 0x9F4D,
+	0xC6BC, 0x9F4E, 0xC6BD, 0x9F4F, 0xC6BE, 0x9F50, 0xC6BF, 0x9F51,
+	0xC6C0, 0xBFF2, 0xC6C1, 0xBFF3, 0xC6C2, 0x9F52, 0xC6C3, 0xBFF4,
+	0xC6C4, 0x9F53, 0xC6C5, 0xBFF5, 0xC6C6, 0x9F54, 0xC6C7, 0x9F55,
+	0xC6C8, 0x9F56, 0xC6C9, 0x9F57, 0xC6CA, 0x9F58, 0xC6CB, 0x9F59,
+	0xC6CC, 0xBFF6, 0xC6CD, 0xBFF7, 0xC6CE, 0x9F5A, 0xC6CF, 0x9F61,
+	0xC6D0, 0xBFF8, 0xC6D1, 0x9F62, 0xC6D2, 0x9F63, 0xC6D3, 0x9F64,
+	0xC6D4, 0xBFF9, 0xC6D5, 0x9F65, 0xC6D6, 0x9F66, 0xC6D7, 0x9F67,
+	0xC6D8, 0x9F68, 0xC6D9, 0x9F69, 0xC6DA, 0x9F6A, 0xC6DB, 0x9F6B,
+	0xC6DC, 0xBFFA, 0xC6DD, 0xBFFB, 0xC6DE, 0x9F6C, 0xC6DF, 0x9F6D,
+	0xC6E0, 0xBFFC, 0xC6E1, 0xBFFD, 0xC6E2, 0x9F6E, 0xC6E3, 0x9F6F,
+	0xC6E4, 0x9F70, 0xC6E5, 0x9F71, 0xC6E6, 0x9F72, 0xC6E7, 0x9F73,
+	0xC6E8, 0xBFFE, 0xC6E9, 0xC0A1, 0xC6EA, 0x9F74, 0xC6EB, 0x9F75,
+	0xC6EC, 0xC0A2, 0xC6ED, 0x9F76, 0xC6EE, 0x9F77, 0xC6EF, 0x9F78,
+	0xC6F0, 0xC0A3, 0xC6F1, 0x9F79, 0xC6F2, 0x9F7A, 0xC6F3, 0x9F81,
+	0xC6F4, 0x9F82, 0xC6F5, 0x9F83, 0xC6F6, 0x9F84, 0xC6F7, 0x9F85,
+	0xC6F8, 0xC0A4, 0xC6F9, 0xC0A5, 0xC6FA, 0x9F86, 0xC6FB, 0x9F87,
+	0xC6FC, 0x9F88, 0xC6FD, 0xC0A6, 0xC6FE, 0x9F89, 0xC6FF, 0x9F8A,
+	0xC700, 0x9F8B, 0xC701, 0x9F8C, 0xC702, 0x9F8D, 0xC703, 0x9F8E,
+	0xC704, 0xC0A7, 0xC705, 0xC0A8, 0xC706, 0x9F8F, 0xC707, 0x9F90,
+	0xC708, 0xC0A9, 0xC709, 0x9F91, 0xC70A, 0x9F92, 0xC70B, 0x9F93,
+	0xC70C, 0xC0AA, 0xC70D, 0x9F94, 0xC70E, 0x9F95, 0xC70F, 0x9F96,
+	0xC710, 0x9F97, 0xC711, 0x9F98, 0xC712, 0x9F99, 0xC713, 0x9F9A,
+	0xC714, 0xC0AB, 0xC715, 0xC0AC, 0xC716, 0x9F9B, 0xC717, 0xC0AD,
+	0xC718, 0x9F9C, 0xC719, 0xC0AE, 0xC71A, 0x9F9D, 0xC71B, 0x9F9E,
+	0xC71C, 0x9F9F, 0xC71D, 0x9FA0, 0xC71E, 0x9FA1, 0xC71F, 0x9FA2,
+	0xC720, 0xC0AF, 0xC721, 0xC0B0, 0xC722, 0x9FA3, 0xC723, 0x9FA4,
+	0xC724, 0xC0B1, 0xC725, 0x9FA5, 0xC726, 0x9FA6, 0xC727, 0x9FA7,
+	0xC728, 0xC0B2, 0xC729, 0x9FA8, 0xC72A, 0x9FA9, 0xC72B, 0x9FAA,
+	0xC72C, 0x9FAB, 0xC72D, 0x9FAC, 0xC72E, 0x9FAD, 0xC72F, 0x9FAE,
+	0xC730, 0xC0B3, 0xC731, 0xC0B4, 0xC732, 0x9FAF, 0xC733, 0xC0B5,
+	0xC734, 0x9FB0, 0xC735, 0xC0B6, 0xC736, 0x9FB1, 0xC737, 0xC0B7,
+	0xC738, 0x9FB2, 0xC739, 0x9FB3, 0xC73A, 0x9FB4, 0xC73B, 0x9FB5,
+	0xC73C, 0xC0B8, 0xC73D, 0xC0B9, 0xC73E, 0x9FB6, 0xC73F, 0x9FB7,
+	0xC740, 0xC0BA, 0xC741, 0x9FB8, 0xC742, 0x9FB9, 0xC743, 0x9FBA,
+	0xC744, 0xC0BB, 0xC745, 0x9FBB, 0xC746, 0x9FBC, 0xC747, 0x9FBD,
+	0xC748, 0x9FBE, 0xC749, 0x9FBF, 0xC74A, 0xC0BC, 0xC74B, 0x9FC0,
+	0xC74C, 0xC0BD, 0xC74D, 0xC0BE, 0xC74E, 0x9FC1, 0xC74F, 0xC0BF,
+	0xC750, 0x9FC2, 0xC751, 0xC0C0, 0xC752, 0xC0C1, 0xC753, 0xC0C2,
+	0xC754, 0xC0C3, 0xC755, 0xC0C4, 0xC756, 0xC0C5, 0xC757, 0xC0C6,
+	0xC758, 0xC0C7, 0xC759, 0x9FC3, 0xC75A, 0x9FC4, 0xC75B, 0x9FC5,
+	0xC75C, 0xC0C8, 0xC75D, 0x9FC6, 0xC75E, 0x9FC7, 0xC75F, 0x9FC8,
+	0xC760, 0xC0C9, 0xC761, 0x9FC9, 0xC762, 0x9FCA, 0xC763, 0x9FCB,
+	0xC764, 0x9FCC, 0xC765, 0x9FCD, 0xC766, 0x9FCE, 0xC767, 0x9FCF,
+	0xC768, 0xC0CA, 0xC769, 0x9FD0, 0xC76A, 0x9FD1, 0xC76B, 0xC0CB,
+	0xC76C, 0x9FD2, 0xC76D, 0x9FD3, 0xC76E, 0x9FD4, 0xC76F, 0x9FD5,
+	0xC770, 0x9FD6, 0xC771, 0x9FD7, 0xC772, 0x9FD8, 0xC773, 0x9FD9,
+	0xC774, 0xC0CC, 0xC775, 0xC0CD, 0xC776, 0x9FDA, 0xC777, 0x9FDB,
+	0xC778, 0xC0CE, 0xC779, 0x9FDC, 0xC77A, 0x9FDD, 0xC77B, 0x9FDE,
+	0xC77C, 0xC0CF, 0xC77D, 0xC0D0, 0xC77E, 0xC0D1, 0xC77F, 0x9FDF,
+	0xC780, 0x9FE0, 0xC781, 0x9FE1, 0xC782, 0x9FE2, 0xC783, 0xC0D2,
+	0xC784, 0xC0D3, 0xC785, 0xC0D4, 0xC786, 0x9FE3, 0xC787, 0xC0D5,
+	0xC788, 0xC0D6, 0xC789, 0xC0D7, 0xC78A, 0xC0D8, 0xC78B, 0x9FE4,
+	0xC78C, 0x9FE5, 0xC78D, 0x9FE6, 0xC78E, 0xC0D9, 0xC78F, 0x9FE7,
+	0xC790, 0xC0DA, 0xC791, 0xC0DB, 0xC792, 0x9FE8, 0xC793, 0x9FE9,
+	0xC794, 0xC0DC, 0xC795, 0x9FEA, 0xC796, 0xC0DD, 0xC797, 0xC0DE,
+	0xC798, 0xC0DF, 0xC799, 0x9FEB, 0xC79A, 0xC0E0, 0xC79B, 0x9FEC,
+	0xC79C, 0x9FED, 0xC79D, 0x9FEE, 0xC79E, 0x9FEF, 0xC79F, 0x9FF0,
+	0xC7A0, 0xC0E1, 0xC7A1, 0xC0E2, 0xC7A2, 0x9FF1, 0xC7A3, 0xC0E3,
+	0xC7A4, 0xC0E4, 0xC7A5, 0xC0E5, 0xC7A6, 0xC0E6, 0xC7A7, 0x9FF2,
+	0xC7A8, 0x9FF3, 0xC7A9, 0x9FF4, 0xC7AA, 0x9FF5, 0xC7AB, 0x9FF6,
+	0xC7AC, 0xC0E7, 0xC7AD, 0xC0E8, 0xC7AE, 0x9FF7, 0xC7AF, 0x9FF8,
+	0xC7B0, 0xC0E9, 0xC7B1, 0x9FF9, 0xC7B2, 0x9FFA, 0xC7B3, 0x9FFB,
+	0xC7B4, 0xC0EA, 0xC7B5, 0x9FFC, 0xC7B6, 0x9FFD, 0xC7B7, 0x9FFE,
+	0xC7B8, 0xA041, 0xC7B9, 0xA042, 0xC7BA, 0xA043, 0xC7BB, 0xA044,
+	0xC7BC, 0xC0EB, 0xC7BD, 0xC0EC, 0xC7BE, 0xA045, 0xC7BF, 0xC0ED,
+	0xC7C0, 0xC0EE, 0xC7C1, 0xC0EF, 0xC7C2, 0xA046, 0xC7C3, 0xA047,
+	0xC7C4, 0xA048, 0xC7C5, 0xA049, 0xC7C6, 0xA04A, 0xC7C7, 0xA04B,
+	0xC7C8, 0xC0F0, 0xC7C9, 0xC0F1, 0xC7CA, 0xA04C, 0xC7CB, 0xA04D,
+	0xC7CC, 0xC0F2, 0xC7CD, 0xA04E, 0xC7CE, 0xC0F3, 0xC7CF, 0xA04F,
+	0xC7D0, 0xC0F4, 0xC7D1, 0xA050, 0xC7D2, 0xA051, 0xC7D3, 0xA052,
+	0xC7D4, 0xA053, 0xC7D5, 0xA054, 0xC7D6, 0xA055, 0xC7D7, 0xA056,
+	0xC7D8, 0xC0F5, 0xC7D9, 0xA057, 0xC7DA, 0xA058, 0xC7DB, 0xA059,
+	0xC7DC, 0xA05A, 0xC7DD, 0xC0F6, 0xC7DE, 0xA061, 0xC7DF, 0xA062,
+	0xC7E0, 0xA063, 0xC7E1, 0xA064, 0xC7E2, 0xA065, 0xC7E3, 0xA066,
+	0xC7E4, 0xC0F7, 0xC7E5, 0xA067, 0xC7E6, 0xA068, 0xC7E7, 0xA069,
+	0xC7E8, 0xC0F8, 0xC7E9, 0xA06A, 0xC7EA, 0xA06B, 0xC7EB, 0xA06C,
+	0xC7EC, 0xC0F9, 0xC7ED, 0xA06D, 0xC7EE, 0xA06E, 0xC7EF, 0xA06F,
+	0xC7F0, 0xA070, 0xC7F1, 0xA071, 0xC7F2, 0xA072, 0xC7F3, 0xA073,
+	0xC7F4, 0xA074, 0xC7F5, 0xA075, 0xC7F6, 0xA076, 0xC7F7, 0xA077,
+	0xC7F8, 0xA078, 0xC7F9, 0xA079, 0xC7FA, 0xA07A, 0xC7FB, 0xA081,
+	0xC7FC, 0xA082, 0xC7FD, 0xA083, 0xC7FE, 0xA084, 0xC7FF, 0xA085,
+	0xC800, 0xC0FA, 0xC801, 0xC0FB, 0xC802, 0xA086, 0xC803, 0xA087,
+	0xC804, 0xC0FC, 0xC805, 0xA088, 0xC806, 0xA089, 0xC807, 0xA08A,
+	0xC808, 0xC0FD, 0xC809, 0xA08B, 0xC80A, 0xC0FE, 0xC80B, 0xA08C,
+	0xC80C, 0xA08D, 0xC80D, 0xA08E, 0xC80E, 0xA08F, 0xC80F, 0xA090,
+	0xC810, 0xC1A1, 0xC811, 0xC1A2, 0xC812, 0xA091, 0xC813, 0xC1A3,
+	0xC814, 0xA092, 0xC815, 0xC1A4, 0xC816, 0xC1A5, 0xC817, 0xA093,
+	0xC818, 0xA094, 0xC819, 0xA095, 0xC81A, 0xA096, 0xC81B, 0xA097,
+	0xC81C, 0xC1A6, 0xC81D, 0xC1A7, 0xC81E, 0xA098, 0xC81F, 0xA099,
+	0xC820, 0xC1A8, 0xC821, 0xA09A, 0xC822, 0xA09B, 0xC823, 0xA09C,
+	0xC824, 0xC1A9, 0xC825, 0xA09D, 0xC826, 0xA09E, 0xC827, 0xA09F,
+	0xC828, 0xA0A0, 0xC829, 0xA0A1, 0xC82A, 0xA0A2, 0xC82B, 0xA0A3,
+	0xC82C, 0xC1AA, 0xC82D, 0xC1AB, 0xC82E, 0xA0A4, 0xC82F, 0xC1AC,
+	0xC830, 0xA0A5, 0xC831, 0xC1AD, 0xC832, 0xA0A6, 0xC833, 0xA0A7,
+	0xC834, 0xA0A8, 0xC835, 0xA0A9, 0xC836, 0xA0AA, 0xC837, 0xA0AB,
+	0xC838, 0xC1AE, 0xC839, 0xA0AC, 0xC83A, 0xA0AD, 0xC83B, 0xA0AE,
+	0xC83C, 0xC1AF, 0xC83D, 0xA0AF, 0xC83E, 0xA0B0, 0xC83F, 0xA0B1,
+	0xC840, 0xC1B0, 0xC841, 0xA0B2, 0xC842, 0xA0B3, 0xC843, 0xA0B4,
+	0xC844, 0xA0B5, 0xC845, 0xA0B6, 0xC846, 0xA0B7, 0xC847, 0xA0B8,
+	0xC848, 0xC1B1, 0xC849, 0xC1B2, 0xC84A, 0xA0B9, 0xC84B, 0xA0BA,
+	0xC84C, 0xC1B3, 0xC84D, 0xC1B4, 0xC84E, 0xA0BB, 0xC84F, 0xA0BC,
+	0xC850, 0xA0BD, 0xC851, 0xA0BE, 0xC852, 0xA0BF, 0xC853, 0xA0C0,
+	0xC854, 0xC1B5, 0xC855, 0xA0C1, 0xC856, 0xA0C2, 0xC857, 0xA0C3,
+	0xC858, 0xA0C4, 0xC859, 0xA0C5, 0xC85A, 0xA0C6, 0xC85B, 0xA0C7,
+	0xC85C, 0xA0C8, 0xC85D, 0xA0C9, 0xC85E, 0xA0CA, 0xC85F, 0xA0CB,
+	0xC860, 0xA0CC, 0xC861, 0xA0CD, 0xC862, 0xA0CE, 0xC863, 0xA0CF,
+	0xC864, 0xA0D0, 0xC865, 0xA0D1, 0xC866, 0xA0D2, 0xC867, 0xA0D3,
+	0xC868, 0xA0D4, 0xC869, 0xA0D5, 0xC86A, 0xA0D6, 0xC86B, 0xA0D7,
+	0xC86C, 0xA0D8, 0xC86D, 0xA0D9, 0xC86E, 0xA0DA, 0xC86F, 0xA0DB,
+	0xC870, 0xC1B6, 0xC871, 0xC1B7, 0xC872, 0xA0DC, 0xC873, 0xA0DD,
+	0xC874, 0xC1B8, 0xC875, 0xA0DE, 0xC876, 0xA0DF, 0xC877, 0xA0E0,
+	0xC878, 0xC1B9, 0xC879, 0xA0E1, 0xC87A, 0xC1BA, 0xC87B, 0xA0E2,
+	0xC87C, 0xA0E3, 0xC87D, 0xA0E4, 0xC87E, 0xA0E5, 0xC87F, 0xA0E6,
+	0xC880, 0xC1BB, 0xC881, 0xC1BC, 0xC882, 0xA0E7, 0xC883, 0xC1BD,
+	0xC884, 0xA0E8, 0xC885, 0xC1BE, 0xC886, 0xC1BF, 0xC887, 0xC1C0,
+	0xC888, 0xA0E9, 0xC889, 0xA0EA, 0xC88A, 0xA0EB, 0xC88B, 0xC1C1,
+	0xC88C, 0xC1C2, 0xC88D, 0xC1C3, 0xC88E, 0xA0EC, 0xC88F, 0xA0ED,
+	0xC890, 0xA0EE, 0xC891, 0xA0EF, 0xC892, 0xA0F0, 0xC893, 0xA0F1,
+	0xC894, 0xC1C4, 0xC895, 0xA0F2, 0xC896, 0xA0F3, 0xC897, 0xA0F4,
+	0xC898, 0xA0F5, 0xC899, 0xA0F6, 0xC89A, 0xA0F7, 0xC89B, 0xA0F8,
+	0xC89C, 0xA0F9, 0xC89D, 0xC1C5, 0xC89E, 0xA0FA, 0xC89F, 0xC1C6,
+	0xC8A0, 0xA0FB, 0xC8A1, 0xC1C7, 0xC8A2, 0xA0FC, 0xC8A3, 0xA0FD,
+	0xC8A4, 0xA0FE, 0xC8A5, 0xA141, 0xC8A6, 0xA142, 0xC8A7, 0xA143,
+	0xC8A8, 0xC1C8, 0xC8A9, 0xA144, 0xC8AA, 0xA145, 0xC8AB, 0xA146,
+	0xC8AC, 0xA147, 0xC8AD, 0xA148, 0xC8AE, 0xA149, 0xC8AF, 0xA14A,
+	0xC8B0, 0xA14B, 0xC8B1, 0xA14C, 0xC8B2, 0xA14D, 0xC8B3, 0xA14E,
+	0xC8B4, 0xA14F, 0xC8B5, 0xA150, 0xC8B6, 0xA151, 0xC8B7, 0xA152,
+	0xC8B8, 0xA153, 0xC8B9, 0xA154, 0xC8BA, 0xA155, 0xC8BB, 0xA156,
+	0xC8BC, 0xC1C9, 0xC8BD, 0xC1CA, 0xC8BE, 0xA157, 0xC8BF, 0xA158,
+	0xC8C0, 0xA159, 0xC8C1, 0xA15A, 0xC8C2, 0xA161, 0xC8C3, 0xA162,
+	0xC8C4, 0xC1CB, 0xC8C5, 0xA163, 0xC8C6, 0xA164, 0xC8C7, 0xA165,
+	0xC8C8, 0xC1CC, 0xC8C9, 0xA166, 0xC8CA, 0xA167, 0xC8CB, 0xA168,
+	0xC8CC, 0xC1CD, 0xC8CD, 0xA169, 0xC8CE, 0xA16A, 0xC8CF, 0xA16B,
+	0xC8D0, 0xA16C, 0xC8D1, 0xA16D, 0xC8D2, 0xA16E, 0xC8D3, 0xA16F,
+	0xC8D4, 0xC1CE, 0xC8D5, 0xC1CF, 0xC8D6, 0xA170, 0xC8D7, 0xC1D0,
+	0xC8D8, 0xA171, 0xC8D9, 0xC1D1, 0xC8DA, 0xA172, 0xC8DB, 0xA173,
+	0xC8DC, 0xA174, 0xC8DD, 0xA175, 0xC8DE, 0xA176, 0xC8DF, 0xA177,
+	0xC8E0, 0xC1D2, 0xC8E1, 0xC1D3, 0xC8E2, 0xA178, 0xC8E3, 0xA179,
+	0xC8E4, 0xC1D4, 0xC8E5, 0xA17A, 0xC8E6, 0xA181, 0xC8E7, 0xA182,
+	0xC8E8, 0xA183, 0xC8E9, 0xA184, 0xC8EA, 0xA185, 0xC8EB, 0xA186,
+	0xC8EC, 0xA187, 0xC8ED, 0xA188, 0xC8EE, 0xA189, 0xC8EF, 0xA18A,
+	0xC8F0, 0xA18B, 0xC8F1, 0xA18C, 0xC8F2, 0xA18D, 0xC8F3, 0xA18E,
+	0xC8F4, 0xA18F, 0xC8F5, 0xC1D5, 0xC8F6, 0xA190, 0xC8F7, 0xA191,
+	0xC8F8, 0xA192, 0xC8F9, 0xA193, 0xC8FA, 0xA194, 0xC8FB, 0xA195,
+	0xC8FC, 0xC1D6, 0xC8FD, 0xC1D7, 0xC8FE, 0xA196, 0xC8FF, 0xA197,
+	0xC900, 0xC1D8, 0xC901, 0xA198, 0xC902, 0xA199, 0xC903, 0xA19A,
+	0xC904, 0xC1D9, 0xC905, 0xC1DA, 0xC906, 0xC1DB, 0xC907, 0xA19B,
+	0xC908, 0xA19C, 0xC909, 0xA19D, 0xC90A, 0xA19E, 0xC90B, 0xA19F,
+	0xC90C, 0xC1DC, 0xC90D, 0xC1DD, 0xC90E, 0xA1A0, 0xC90F, 0xC1DE,
+	0xC910, 0xA241, 0xC911, 0xC1DF, 0xC912, 0xA242, 0xC913, 0xA243,
+	0xC914, 0xA244, 0xC915, 0xA245, 0xC916, 0xA246, 0xC917, 0xA247,
+	0xC918, 0xC1E0, 0xC919, 0xA248, 0xC91A, 0xA249, 0xC91B, 0xA24A,
+	0xC91C, 0xA24B, 0xC91D, 0xA24C, 0xC91E, 0xA24D, 0xC91F, 0xA24E,
+	0xC920, 0xA24F, 0xC921, 0xA250, 0xC922, 0xA251, 0xC923, 0xA252,
+	0xC924, 0xA253, 0xC925, 0xA254, 0xC926, 0xA255, 0xC927, 0xA256,
+	0xC928, 0xA257, 0xC929, 0xA258, 0xC92A, 0xA259, 0xC92B, 0xA25A,
+	0xC92C, 0xC1E1, 0xC92D, 0xA261, 0xC92E, 0xA262, 0xC92F, 0xA263,
+	0xC930, 0xA264, 0xC931, 0xA265, 0xC932, 0xA266, 0xC933, 0xA267,
+	0xC934, 0xC1E2, 0xC935, 0xA268, 0xC936, 0xA269, 0xC937, 0xA26A,
+	0xC938, 0xA26B, 0xC939, 0xA26C, 0xC93A, 0xA26D, 0xC93B, 0xA26E,
+	0xC93C, 0xA26F, 0xC93D, 0xA270, 0xC93E, 0xA271, 0xC93F, 0xA272,
+	0xC940, 0xA273, 0xC941, 0xA274, 0xC942, 0xA275, 0xC943, 0xA276,
+	0xC944, 0xA277, 0xC945, 0xA278, 0xC946, 0xA279, 0xC947, 0xA27A,
+	0xC948, 0xA281, 0xC949, 0xA282, 0xC94A, 0xA283, 0xC94B, 0xA284,
+	0xC94C, 0xA285, 0xC94D, 0xA286, 0xC94E, 0xA287, 0xC94F, 0xA288,
+	0xC950, 0xC1E3, 0xC951, 0xC1E4, 0xC952, 0xA289, 0xC953, 0xA28A,
+	0xC954, 0xC1E5, 0xC955, 0xA28B, 0xC956, 0xA28C, 0xC957, 0xA28D,
+	0xC958, 0xC1E6, 0xC959, 0xA28E, 0xC95A, 0xA28F, 0xC95B, 0xA290,
+	0xC95C, 0xA291, 0xC95D, 0xA292, 0xC95E, 0xA293, 0xC95F, 0xA294,
+	0xC960, 0xC1E7, 0xC961, 0xC1E8, 0xC962, 0xA295, 0xC963, 0xC1E9,
+	0xC964, 0xA296, 0xC965, 0xA297, 0xC966, 0xA298, 0xC967, 0xA299,
+	0xC968, 0xA29A, 0xC969, 0xA29B, 0xC96A, 0xA29C, 0xC96B, 0xA29D,
+	0xC96C, 0xC1EA, 0xC96D, 0xA29E, 0xC96E, 0xA29F, 0xC96F, 0xA2A0,
+	0xC970, 0xC1EB, 0xC971, 0xA341, 0xC972, 0xA342, 0xC973, 0xA343,
+	0xC974, 0xC1EC, 0xC975, 0xA344, 0xC976, 0xA345, 0xC977, 0xA346,
+	0xC978, 0xA347, 0xC979, 0xA348, 0xC97A, 0xA349, 0xC97B, 0xA34A,
+	0xC97C, 0xC1ED, 0xC97D, 0xA34B, 0xC97E, 0xA34C, 0xC97F, 0xA34D,
+	0xC980, 0xA34E, 0xC981, 0xA34F, 0xC982, 0xA350, 0xC983, 0xA351,
+	0xC984, 0xA352, 0xC985, 0xA353, 0xC986, 0xA354, 0xC987, 0xA355,
+	0xC988, 0xC1EE, 0xC989, 0xC1EF, 0xC98A, 0xA356, 0xC98B, 0xA357,
+	0xC98C, 0xC1F0, 0xC98D, 0xA358, 0xC98E, 0xA359, 0xC98F, 0xA35A,
+	0xC990, 0xC1F1, 0xC991, 0xA361, 0xC992, 0xA362, 0xC993, 0xA363,
+	0xC994, 0xA364, 0xC995, 0xA365, 0xC996, 0xA366, 0xC997, 0xA367,
+	0xC998, 0xC1F2, 0xC999, 0xC1F3, 0xC99A, 0xA368, 0xC99B, 0xC1F4,
+	0xC99C, 0xA369, 0xC99D, 0xC1F5, 0xC99E, 0xA36A, 0xC99F, 0xA36B,
+	0xC9A0, 0xA36C, 0xC9A1, 0xA36D, 0xC9A2, 0xA36E, 0xC9A3, 0xA36F,
+	0xC9A4, 0xA370, 0xC9A5, 0xA371, 0xC9A6, 0xA372, 0xC9A7, 0xA373,
+	0xC9A8, 0xA374, 0xC9A9, 0xA375, 0xC9AA, 0xA376, 0xC9AB, 0xA377,
+	0xC9AC, 0xA378, 0xC9AD, 0xA379, 0xC9AE, 0xA37A, 0xC9AF, 0xA381,
+	0xC9B0, 0xA382, 0xC9B1, 0xA383, 0xC9B2, 0xA384, 0xC9B3, 0xA385,
+	0xC9B4, 0xA386, 0xC9B5, 0xA387, 0xC9B6, 0xA388, 0xC9B7, 0xA389,
+	0xC9B8, 0xA38A, 0xC9B9, 0xA38B, 0xC9BA, 0xA38C, 0xC9BB, 0xA38D,
+	0xC9BC, 0xA38E, 0xC9BD, 0xA38F, 0xC9BE, 0xA390, 0xC9BF, 0xA391,
+	0xC9C0, 0xC1F6, 0xC9C1, 0xC1F7, 0xC9C2, 0xA392, 0xC9C3, 0xA393,
+	0xC9C4, 0xC1F8, 0xC9C5, 0xA394, 0xC9C6, 0xA395, 0xC9C7, 0xC1F9,
+	0xC9C8, 0xC1FA, 0xC9C9, 0xA396, 0xC9CA, 0xC1FB, 0xC9CB, 0xA397,
+	0xC9CC, 0xA398, 0xC9CD, 0xA399, 0xC9CE, 0xA39A, 0xC9CF, 0xA39B,
+	0xC9D0, 0xC1FC, 0xC9D1, 0xC1FD, 0xC9D2, 0xA39C, 0xC9D3, 0xC1FE,
+	0xC9D4, 0xA39D, 0xC9D5, 0xC2A1, 0xC9D6, 0xC2A2, 0xC9D7, 0xA39E,
+	0xC9D8, 0xA39F, 0xC9D9, 0xC2A3, 0xC9DA, 0xC2A4, 0xC9DB, 0xA3A0,
+	0xC9DC, 0xC2A5, 0xC9DD, 0xC2A6, 0xC9DE, 0xA441, 0xC9DF, 0xA442,
+	0xC9E0, 0xC2A7, 0xC9E1, 0xA443, 0xC9E2, 0xC2A8, 0xC9E3, 0xA444,
+	0xC9E4, 0xC2A9, 0xC9E5, 0xA445, 0xC9E6, 0xA446, 0xC9E7, 0xC2AA,
+	0xC9E8, 0xA447, 0xC9E9, 0xA448, 0xC9EA, 0xA449, 0xC9EB, 0xA44A,
+	0xC9EC, 0xC2AB, 0xC9ED, 0xC2AC, 0xC9EE, 0xA44B, 0xC9EF, 0xC2AD,
+	0xC9F0, 0xC2AE, 0xC9F1, 0xC2AF, 0xC9F2, 0xA44C, 0xC9F3, 0xA44D,
+	0xC9F4, 0xA44E, 0xC9F5, 0xA44F, 0xC9F6, 0xA450, 0xC9F7, 0xA451,
+	0xC9F8, 0xC2B0, 0xC9F9, 0xC2B1, 0xC9FA, 0xA452, 0xC9FB, 0xA453,
+	0xC9FC, 0xC2B2, 0xC9FD, 0xA454, 0xC9FE, 0xA455, 0xC9FF, 0xA456,
+	0xCA00, 0xC2B3, 0xCA01, 0xA457, 0xCA02, 0xA458, 0xCA03, 0xA459,
+	0xCA04, 0xA45A, 0xCA05, 0xA461, 0xCA06, 0xA462, 0xCA07, 0xA463,
+	0xCA08, 0xC2B4, 0xCA09, 0xC2B5, 0xCA0A, 0xA464, 0xCA0B, 0xC2B6,
+	0xCA0C, 0xC2B7, 0xCA0D, 0xC2B8, 0xCA0E, 0xA465, 0xCA0F, 0xA466,
+	0xCA10, 0xA467, 0xCA11, 0xA468, 0xCA12, 0xA469, 0xCA13, 0xA46A,
+	0xCA14, 0xC2B9, 0xCA15, 0xA46B, 0xCA16, 0xA46C, 0xCA17, 0xA46D,
+	0xCA18, 0xC2BA, 0xCA19, 0xA46E, 0xCA1A, 0xA46F, 0xCA1B, 0xA470,
+	0xCA1C, 0xA471, 0xCA1D, 0xA472, 0xCA1E, 0xA473, 0xCA1F, 0xA474,
+	0xCA20, 0xA475, 0xCA21, 0xA476, 0xCA22, 0xA477, 0xCA23, 0xA478,
+	0xCA24, 0xA479, 0xCA25, 0xA47A, 0xCA26, 0xA481, 0xCA27, 0xA482,
+	0xCA28, 0xA483, 0xCA29, 0xC2BB, 0xCA2A, 0xA484, 0xCA2B, 0xA485,
+	0xCA2C, 0xA486, 0xCA2D, 0xA487, 0xCA2E, 0xA488, 0xCA2F, 0xA489,
+	0xCA30, 0xA48A, 0xCA31, 0xA48B, 0xCA32, 0xA48C, 0xCA33, 0xA48D,
+	0xCA34, 0xA48E, 0xCA35, 0xA48F, 0xCA36, 0xA490, 0xCA37, 0xA491,
+	0xCA38, 0xA492, 0xCA39, 0xA493, 0xCA3A, 0xA494, 0xCA3B, 0xA495,
+	0xCA3C, 0xA496, 0xCA3D, 0xA497, 0xCA3E, 0xA498, 0xCA3F, 0xA499,
+	0xCA40, 0xA49A, 0xCA41, 0xA49B, 0xCA42, 0xA49C, 0xCA43, 0xA49D,
+	0xCA44, 0xA49E, 0xCA45, 0xA49F, 0xCA46, 0xA4A0, 0xCA47, 0xA541,
+	0xCA48, 0xA542, 0xCA49, 0xA543, 0xCA4A, 0xA544, 0xCA4B, 0xA545,
+	0xCA4C, 0xC2BC, 0xCA4D, 0xC2BD, 0xCA4E, 0xA546, 0xCA4F, 0xA547,
+	0xCA50, 0xC2BE, 0xCA51, 0xA548, 0xCA52, 0xA549, 0xCA53, 0xA54A,
+	0xCA54, 0xC2BF, 0xCA55, 0xA54B, 0xCA56, 0xA54C, 0xCA57, 0xA54D,
+	0xCA58, 0xA54E, 0xCA59, 0xA54F, 0xCA5A, 0xA550, 0xCA5B, 0xA551,
+	0xCA5C, 0xC2C0, 0xCA5D, 0xC2C1, 0xCA5E, 0xA552, 0xCA5F, 0xC2C2,
+	0xCA60, 0xC2C3, 0xCA61, 0xC2C4, 0xCA62, 0xA553, 0xCA63, 0xA554,
+	0xCA64, 0xA555, 0xCA65, 0xA556, 0xCA66, 0xA557, 0xCA67, 0xA558,
+	0xCA68, 0xC2C5, 0xCA69, 0xA559, 0xCA6A, 0xA55A, 0xCA6B, 0xA561,
+	0xCA6C, 0xA562, 0xCA6D, 0xA563, 0xCA6E, 0xA564, 0xCA6F, 0xA565,
+	0xCA70, 0xA566, 0xCA71, 0xA567, 0xCA72, 0xA568, 0xCA73, 0xA569,
+	0xCA74, 0xA56A, 0xCA75, 0xA56B, 0xCA76, 0xA56C, 0xCA77, 0xA56D,
+	0xCA78, 0xA56E, 0xCA79, 0xA56F, 0xCA7A, 0xA570, 0xCA7B, 0xA571,
+	0xCA7C, 0xA572, 0xCA7D, 0xC2C6, 0xCA7E, 0xA573, 0xCA7F, 0xA574,
+	0xCA80, 0xA575, 0xCA81, 0xA576, 0xCA82, 0xA577, 0xCA83, 0xA578,
+	0xCA84, 0xC2C7, 0xCA85, 0xA579, 0xCA86, 0xA57A, 0xCA87, 0xA581,
+	0xCA88, 0xA582, 0xCA89, 0xA583, 0xCA8A, 0xA584, 0xCA8B, 0xA585,
+	0xCA8C, 0xA586, 0xCA8D, 0xA587, 0xCA8E, 0xA588, 0xCA8F, 0xA589,
+	0xCA90, 0xA58A, 0xCA91, 0xA58B, 0xCA92, 0xA58C, 0xCA93, 0xA58D,
+	0xCA94, 0xA58E, 0xCA95, 0xA58F, 0xCA96, 0xA590, 0xCA97, 0xA591,
+	0xCA98, 0xC2C8, 0xCA99, 0xA592, 0xCA9A, 0xA593, 0xCA9B, 0xA594,
+	0xCA9C, 0xA595, 0xCA9D, 0xA596, 0xCA9E, 0xA597, 0xCA9F, 0xA598,
+	0xCAA0, 0xA599, 0xCAA1, 0xA59A, 0xCAA2, 0xA59B, 0xCAA3, 0xA59C,
+	0xCAA4, 0xA59D, 0xCAA5, 0xA59E, 0xCAA6, 0xA59F, 0xCAA7, 0xA5A0,
+	0xCAA8, 0xA641, 0xCAA9, 0xA642, 0xCAAA, 0xA643, 0xCAAB, 0xA644,
+	0xCAAC, 0xA645, 0xCAAD, 0xA646, 0xCAAE, 0xA647, 0xCAAF, 0xA648,
+	0xCAB0, 0xA649, 0xCAB1, 0xA64A, 0xCAB2, 0xA64B, 0xCAB3, 0xA64C,
+	0xCAB4, 0xA64D, 0xCAB5, 0xA64E, 0xCAB6, 0xA64F, 0xCAB7, 0xA650,
+	0xCAB8, 0xA651, 0xCAB9, 0xA652, 0xCABA, 0xA653, 0xCABB, 0xA654,
+	0xCABC, 0xC2C9, 0xCABD, 0xC2CA, 0xCABE, 0xA655, 0xCABF, 0xA656,
+	0xCAC0, 0xC2CB, 0xCAC1, 0xA657, 0xCAC2, 0xA658, 0xCAC3, 0xA659,
+	0xCAC4, 0xC2CC, 0xCAC5, 0xA65A, 0xCAC6, 0xA661, 0xCAC7, 0xA662,
+	0xCAC8, 0xA663, 0xCAC9, 0xA664, 0xCACA, 0xA665, 0xCACB, 0xA666,
+	0xCACC, 0xC2CD, 0xCACD, 0xC2CE, 0xCACE, 0xA667, 0xCACF, 0xC2CF,
+	0xCAD0, 0xA668, 0xCAD1, 0xC2D0, 0xCAD2, 0xA669, 0xCAD3, 0xC2D1,
+	0xCAD4, 0xA66A, 0xCAD5, 0xA66B, 0xCAD6, 0xA66C, 0xCAD7, 0xA66D,
+	0xCAD8, 0xC2D2, 0xCAD9, 0xC2D3, 0xCADA, 0xA66E, 0xCADB, 0xA66F,
+	0xCADC, 0xA670, 0xCADD, 0xA671, 0xCADE, 0xA672, 0xCADF, 0xA673,
+	0xCAE0, 0xC2D4, 0xCAE1, 0xA674, 0xCAE2, 0xA675, 0xCAE3, 0xA676,
+	0xCAE4, 0xA677, 0xCAE5, 0xA678, 0xCAE6, 0xA679, 0xCAE7, 0xA67A,
+	0xCAE8, 0xA681, 0xCAE9, 0xA682, 0xCAEA, 0xA683, 0xCAEB, 0xA684,
+	0xCAEC, 0xC2D5, 0xCAED, 0xA685, 0xCAEE, 0xA686, 0xCAEF, 0xA687,
+	0xCAF0, 0xA688, 0xCAF1, 0xA689, 0xCAF2, 0xA68A, 0xCAF3, 0xA68B,
+	0xCAF4, 0xC2D6, 0xCAF5, 0xA68C, 0xCAF6, 0xA68D, 0xCAF7, 0xA68E,
+	0xCAF8, 0xA68F, 0xCAF9, 0xA690, 0xCAFA, 0xA691, 0xCAFB, 0xA692,
+	0xCAFC, 0xA693, 0xCAFD, 0xA694, 0xCAFE, 0xA695, 0xCAFF, 0xA696,
+	0xCB00, 0xA697, 0xCB01, 0xA698, 0xCB02, 0xA699, 0xCB03, 0xA69A,
+	0xCB04, 0xA69B, 0xCB05, 0xA69C, 0xCB06, 0xA69D, 0xCB07, 0xA69E,
+	0xCB08, 0xC2D7, 0xCB09, 0xA69F, 0xCB0A, 0xA6A0, 0xCB0B, 0xA741,
+	0xCB0C, 0xA742, 0xCB0D, 0xA743, 0xCB0E, 0xA744, 0xCB0F, 0xA745,
+	0xCB10, 0xC2D8, 0xCB11, 0xA746, 0xCB12, 0xA747, 0xCB13, 0xA748,
+	0xCB14, 0xC2D9, 0xCB15, 0xA749, 0xCB16, 0xA74A, 0xCB17, 0xA74B,
+	0xCB18, 0xC2DA, 0xCB19, 0xA74C, 0xCB1A, 0xA74D, 0xCB1B, 0xA74E,
+	0xCB1C, 0xA74F, 0xCB1D, 0xA750, 0xCB1E, 0xA751, 0xCB1F, 0xA752,
+	0xCB20, 0xC2DB, 0xCB21, 0xC2DC, 0xCB22, 0xA753, 0xCB23, 0xA754,
+	0xCB24, 0xA755, 0xCB25, 0xA756, 0xCB26, 0xA757, 0xCB27, 0xA758,
+	0xCB28, 0xA759, 0xCB29, 0xA75A, 0xCB2A, 0xA761, 0xCB2B, 0xA762,
+	0xCB2C, 0xA763, 0xCB2D, 0xA764, 0xCB2E, 0xA765, 0xCB2F, 0xA766,
+	0xCB30, 0xA767, 0xCB31, 0xA768, 0xCB32, 0xA769, 0xCB33, 0xA76A,
+	0xCB34, 0xA76B, 0xCB35, 0xA76C, 0xCB36, 0xA76D, 0xCB37, 0xA76E,
+	0xCB38, 0xA76F, 0xCB39, 0xA770, 0xCB3A, 0xA771, 0xCB3B, 0xA772,
+	0xCB3C, 0xA773, 0xCB3D, 0xA774, 0xCB3E, 0xA775, 0xCB3F, 0xA776,
+	0xCB40, 0xA777, 0xCB41, 0xC2DD, 0xCB42, 0xA778, 0xCB43, 0xA779,
+	0xCB44, 0xA77A, 0xCB45, 0xA781, 0xCB46, 0xA782, 0xCB47, 0xA783,
+	0xCB48, 0xC2DE, 0xCB49, 0xC2DF, 0xCB4A, 0xA784, 0xCB4B, 0xA785,
+	0xCB4C, 0xC2E0, 0xCB4D, 0xA786, 0xCB4E, 0xA787, 0xCB4F, 0xA788,
+	0xCB50, 0xC2E1, 0xCB51, 0xA789, 0xCB52, 0xA78A, 0xCB53, 0xA78B,
+	0xCB54, 0xA78C, 0xCB55, 0xA78D, 0xCB56, 0xA78E, 0xCB57, 0xA78F,
+	0xCB58, 0xC2E2, 0xCB59, 0xC2E3, 0xCB5A, 0xA790, 0xCB5B, 0xA791,
+	0xCB5C, 0xA792, 0xCB5D, 0xC2E4, 0xCB5E, 0xA793, 0xCB5F, 0xA794,
+	0xCB60, 0xA795, 0xCB61, 0xA796, 0xCB62, 0xA797, 0xCB63, 0xA798,
+	0xCB64, 0xC2E5, 0xCB65, 0xA799, 0xCB66, 0xA79A, 0xCB67, 0xA79B,
+	0xCB68, 0xA79C, 0xCB69, 0xA79D, 0xCB6A, 0xA79E, 0xCB6B, 0xA79F,
+	0xCB6C, 0xA7A0, 0xCB6D, 0xA841, 0xCB6E, 0xA842, 0xCB6F, 0xA843,
+	0xCB70, 0xA844, 0xCB71, 0xA845, 0xCB72, 0xA846, 0xCB73, 0xA847,
+	0xCB74, 0xA848, 0xCB75, 0xA849, 0xCB76, 0xA84A, 0xCB77, 0xA84B,
+	0xCB78, 0xC2E6, 0xCB79, 0xC2E7, 0xCB7A, 0xA84C, 0xCB7B, 0xA84D,
+	0xCB7C, 0xA84E, 0xCB7D, 0xA84F, 0xCB7E, 0xA850, 0xCB7F, 0xA851,
+	0xCB80, 0xA852, 0xCB81, 0xA853, 0xCB82, 0xA854, 0xCB83, 0xA855,
+	0xCB84, 0xA856, 0xCB85, 0xA857, 0xCB86, 0xA858, 0xCB87, 0xA859,
+	0xCB88, 0xA85A, 0xCB89, 0xA861, 0xCB8A, 0xA862, 0xCB8B, 0xA863,
+	0xCB8C, 0xA864, 0xCB8D, 0xA865, 0xCB8E, 0xA866, 0xCB8F, 0xA867,
+	0xCB90, 0xA868, 0xCB91, 0xA869, 0xCB92, 0xA86A, 0xCB93, 0xA86B,
+	0xCB94, 0xA86C, 0xCB95, 0xA86D, 0xCB96, 0xA86E, 0xCB97, 0xA86F,
+	0xCB98, 0xA870, 0xCB99, 0xA871, 0xCB9A, 0xA872, 0xCB9B, 0xA873,
+	0xCB9C, 0xC2E8, 0xCB9D, 0xA874, 0xCB9E, 0xA875, 0xCB9F, 0xA876,
+	0xCBA0, 0xA877, 0xCBA1, 0xA878, 0xCBA2, 0xA879, 0xCBA3, 0xA87A,
+	0xCBA4, 0xA881, 0xCBA5, 0xA882, 0xCBA6, 0xA883, 0xCBA7, 0xA884,
+	0xCBA8, 0xA885, 0xCBA9, 0xA886, 0xCBAA, 0xA887, 0xCBAB, 0xA888,
+	0xCBAC, 0xA889, 0xCBAD, 0xA88A, 0xCBAE, 0xA88B, 0xCBAF, 0xA88C,
+	0xCBB0, 0xA88D, 0xCBB1, 0xA88E, 0xCBB2, 0xA88F, 0xCBB3, 0xA890,
+	0xCBB4, 0xA891, 0xCBB5, 0xA892, 0xCBB6, 0xA893, 0xCBB7, 0xA894,
+	0xCBB8, 0xC2E9, 0xCBB9, 0xA895, 0xCBBA, 0xA896, 0xCBBB, 0xA897,
+	0xCBBC, 0xA898, 0xCBBD, 0xA899, 0xCBBE, 0xA89A, 0xCBBF, 0xA89B,
+	0xCBC0, 0xA89C, 0xCBC1, 0xA89D, 0xCBC2, 0xA89E, 0xCBC3, 0xA89F,
+	0xCBC4, 0xA8A0, 0xCBC5, 0xA941, 0xCBC6, 0xA942, 0xCBC7, 0xA943,
+	0xCBC8, 0xA944, 0xCBC9, 0xA945, 0xCBCA, 0xA946, 0xCBCB, 0xA947,
+	0xCBCC, 0xA948, 0xCBCD, 0xA949, 0xCBCE, 0xA94A, 0xCBCF, 0xA94B,
+	0xCBD0, 0xA94C, 0xCBD1, 0xA94D, 0xCBD2, 0xA94E, 0xCBD3, 0xA94F,
+	0xCBD4, 0xC2EA, 0xCBD5, 0xA950, 0xCBD6, 0xA951, 0xCBD7, 0xA952,
+	0xCBD8, 0xA953, 0xCBD9, 0xA954, 0xCBDA, 0xA955, 0xCBDB, 0xA956,
+	0xCBDC, 0xA957, 0xCBDD, 0xA958, 0xCBDE, 0xA959, 0xCBDF, 0xA95A,
+	0xCBE0, 0xA961, 0xCBE1, 0xA962, 0xCBE2, 0xA963, 0xCBE3, 0xA964,
+	0xCBE4, 0xC2EB, 0xCBE5, 0xA965, 0xCBE6, 0xA966, 0xCBE7, 0xC2EC,
+	0xCBE8, 0xA967, 0xCBE9, 0xC2ED, 0xCBEA, 0xA968, 0xCBEB, 0xA969,
+	0xCBEC, 0xA96A, 0xCBED, 0xA96B, 0xCBEE, 0xA96C, 0xCBEF, 0xA96D,
+	0xCBF0, 0xA96E, 0xCBF1, 0xA96F, 0xCBF2, 0xA970, 0xCBF3, 0xA971,
+	0xCBF4, 0xA972, 0xCBF5, 0xA973, 0xCBF6, 0xA974, 0xCBF7, 0xA975,
+	0xCBF8, 0xA976, 0xCBF9, 0xA977, 0xCBFA, 0xA978, 0xCBFB, 0xA979,
+	0xCBFC, 0xA97A, 0xCBFD, 0xA981, 0xCBFE, 0xA982, 0xCBFF, 0xA983,
+	0xCC00, 0xA984, 0xCC01, 0xA985, 0xCC02, 0xA986, 0xCC03, 0xA987,
+	0xCC04, 0xA988, 0xCC05, 0xA989, 0xCC06, 0xA98A, 0xCC07, 0xA98B,
+	0xCC08, 0xA98C, 0xCC09, 0xA98D, 0xCC0A, 0xA98E, 0xCC0B, 0xA98F,
+	0xCC0C, 0xC2EE, 0xCC0D, 0xC2EF, 0xCC0E, 0xA990, 0xCC0F, 0xA991,
+	0xCC10, 0xC2F0, 0xCC11, 0xA992, 0xCC12, 0xA993, 0xCC13, 0xA994,
+	0xCC14, 0xC2F1, 0xCC15, 0xA995, 0xCC16, 0xA996, 0xCC17, 0xA997,
+	0xCC18, 0xA998, 0xCC19, 0xA999, 0xCC1A, 0xA99A, 0xCC1B, 0xA99B,
+	0xCC1C, 0xC2F2, 0xCC1D, 0xC2F3, 0xCC1E, 0xA99C, 0xCC1F, 0xA99D,
+	0xCC20, 0xA99E, 0xCC21, 0xC2F4, 0xCC22, 0xC2F5, 0xCC23, 0xA99F,
+	0xCC24, 0xA9A0, 0xCC25, 0xAA41, 0xCC26, 0xAA42, 0xCC27, 0xC2F6,
+	0xCC28, 0xC2F7, 0xCC29, 0xC2F8, 0xCC2A, 0xAA43, 0xCC2B, 0xAA44,
+	0xCC2C, 0xC2F9, 0xCC2D, 0xAA45, 0xCC2E, 0xC2FA, 0xCC2F, 0xAA46,
+	0xCC30, 0xC2FB, 0xCC31, 0xAA47, 0xCC32, 0xAA48, 0xCC33, 0xAA49,
+	0xCC34, 0xAA4A, 0xCC35, 0xAA4B, 0xCC36, 0xAA4C, 0xCC37, 0xAA4D,
+	0xCC38, 0xC2FC, 0xCC39, 0xC2FD, 0xCC3A, 0xAA4E, 0xCC3B, 0xC2FE,
+	0xCC3C, 0xC3A1, 0xCC3D, 0xC3A2, 0xCC3E, 0xC3A3, 0xCC3F, 0xAA4F,
+	0xCC40, 0xAA50, 0xCC41, 0xAA51, 0xCC42, 0xAA52, 0xCC43, 0xAA53,
+	0xCC44, 0xC3A4, 0xCC45, 0xC3A5, 0xCC46, 0xAA54, 0xCC47, 0xAA55,
+	0xCC48, 0xC3A6, 0xCC49, 0xAA56, 0xCC4A, 0xAA57, 0xCC4B, 0xAA58,
+	0xCC4C, 0xC3A7, 0xCC4D, 0xAA59, 0xCC4E, 0xAA5A, 0xCC4F, 0xAA61,
+	0xCC50, 0xAA62, 0xCC51, 0xAA63, 0xCC52, 0xAA64, 0xCC53, 0xAA65,
+	0xCC54, 0xC3A8, 0xCC55, 0xC3A9, 0xCC56, 0xAA66, 0xCC57, 0xC3AA,
+	0xCC58, 0xC3AB, 0xCC59, 0xC3AC, 0xCC5A, 0xAA67, 0xCC5B, 0xAA68,
+	0xCC5C, 0xAA69, 0xCC5D, 0xAA6A, 0xCC5E, 0xAA6B, 0xCC5F, 0xAA6C,
+	0xCC60, 0xC3AD, 0xCC61, 0xAA6D, 0xCC62, 0xAA6E, 0xCC63, 0xAA6F,
+	0xCC64, 0xC3AE, 0xCC65, 0xAA70, 0xCC66, 0xC3AF, 0xCC67, 0xAA71,
+	0xCC68, 0xC3B0, 0xCC69, 0xAA72, 0xCC6A, 0xAA73, 0xCC6B, 0xAA74,
+	0xCC6C, 0xAA75, 0xCC6D, 0xAA76, 0xCC6E, 0xAA77, 0xCC6F, 0xAA78,
+	0xCC70, 0xC3B1, 0xCC71, 0xAA79, 0xCC72, 0xAA7A, 0xCC73, 0xAA81,
+	0xCC74, 0xAA82, 0xCC75, 0xC3B2, 0xCC76, 0xAA83, 0xCC77, 0xAA84,
+	0xCC78, 0xAA85, 0xCC79, 0xAA86, 0xCC7A, 0xAA87, 0xCC7B, 0xAA88,
+	0xCC7C, 0xAA89, 0xCC7D, 0xAA8A, 0xCC7E, 0xAA8B, 0xCC7F, 0xAA8C,
+	0xCC80, 0xAA8D, 0xCC81, 0xAA8E, 0xCC82, 0xAA8F, 0xCC83, 0xAA90,
+	0xCC84, 0xAA91, 0xCC85, 0xAA92, 0xCC86, 0xAA93, 0xCC87, 0xAA94,
+	0xCC88, 0xAA95, 0xCC89, 0xAA96, 0xCC8A, 0xAA97, 0xCC8B, 0xAA98,
+	0xCC8C, 0xAA99, 0xCC8D, 0xAA9A, 0xCC8E, 0xAA9B, 0xCC8F, 0xAA9C,
+	0xCC90, 0xAA9D, 0xCC91, 0xAA9E, 0xCC92, 0xAA9F, 0xCC93, 0xAAA0,
+	0xCC94, 0xAB41, 0xCC95, 0xAB42, 0xCC96, 0xAB43, 0xCC97, 0xAB44,
+	0xCC98, 0xC3B3, 0xCC99, 0xC3B4, 0xCC9A, 0xAB45, 0xCC9B, 0xAB46,
+	0xCC9C, 0xC3B5, 0xCC9D, 0xAB47, 0xCC9E, 0xAB48, 0xCC9F, 0xAB49,
+	0xCCA0, 0xC3B6, 0xCCA1, 0xAB4A, 0xCCA2, 0xAB4B, 0xCCA3, 0xAB4C,
+	0xCCA4, 0xAB4D, 0xCCA5, 0xAB4E, 0xCCA6, 0xAB4F, 0xCCA7, 0xAB50,
+	0xCCA8, 0xC3B7, 0xCCA9, 0xC3B8, 0xCCAA, 0xAB51, 0xCCAB, 0xC3B9,
+	0xCCAC, 0xC3BA, 0xCCAD, 0xC3BB, 0xCCAE, 0xAB52, 0xCCAF, 0xAB53,
+	0xCCB0, 0xAB54, 0xCCB1, 0xAB55, 0xCCB2, 0xAB56, 0xCCB3, 0xAB57,
+	0xCCB4, 0xC3BC, 0xCCB5, 0xC3BD, 0xCCB6, 0xAB58, 0xCCB7, 0xAB59,
+	0xCCB8, 0xC3BE, 0xCCB9, 0xAB5A, 0xCCBA, 0xAB61, 0xCCBB, 0xAB62,
+	0xCCBC, 0xC3BF, 0xCCBD, 0xAB63, 0xCCBE, 0xAB64, 0xCCBF, 0xAB65,
+	0xCCC0, 0xAB66, 0xCCC1, 0xAB67, 0xCCC2, 0xAB68, 0xCCC3, 0xAB69,
+	0xCCC4, 0xC3C0, 0xCCC5, 0xC3C1, 0xCCC6, 0xAB6A, 0xCCC7, 0xC3C2,
+	0xCCC8, 0xAB6B, 0xCCC9, 0xC3C3, 0xCCCA, 0xAB6C, 0xCCCB, 0xAB6D,
+	0xCCCC, 0xAB6E, 0xCCCD, 0xAB6F, 0xCCCE, 0xAB70, 0xCCCF, 0xAB71,
+	0xCCD0, 0xC3C4, 0xCCD1, 0xAB72, 0xCCD2, 0xAB73, 0xCCD3, 0xAB74,
+	0xCCD4, 0xC3C5, 0xCCD5, 0xAB75, 0xCCD6, 0xAB76, 0xCCD7, 0xAB77,
+	0xCCD8, 0xAB78, 0xCCD9, 0xAB79, 0xCCDA, 0xAB7A, 0xCCDB, 0xAB81,
+	0xCCDC, 0xAB82, 0xCCDD, 0xAB83, 0xCCDE, 0xAB84, 0xCCDF, 0xAB85,
+	0xCCE0, 0xAB86, 0xCCE1, 0xAB87, 0xCCE2, 0xAB88, 0xCCE3, 0xAB89,
+	0xCCE4, 0xC3C6, 0xCCE5, 0xAB8A, 0xCCE6, 0xAB8B, 0xCCE7, 0xAB8C,
+	0xCCE8, 0xAB8D, 0xCCE9, 0xAB8E, 0xCCEA, 0xAB8F, 0xCCEB, 0xAB90,
+	0xCCEC, 0xC3C7, 0xCCED, 0xAB91, 0xCCEE, 0xAB92, 0xCCEF, 0xAB93,
+	0xCCF0, 0xC3C8, 0xCCF1, 0xAB94, 0xCCF2, 0xAB95, 0xCCF3, 0xAB96,
+	0xCCF4, 0xAB97, 0xCCF5, 0xAB98, 0xCCF6, 0xAB99, 0xCCF7, 0xAB9A,
+	0xCCF8, 0xAB9B, 0xCCF9, 0xAB9C, 0xCCFA, 0xAB9D, 0xCCFB, 0xAB9E,
+	0xCCFC, 0xAB9F, 0xCCFD, 0xABA0, 0xCCFE, 0xAC41, 0xCCFF, 0xAC42,
+	0xCD00, 0xAC43, 0xCD01, 0xC3C9, 0xCD02, 0xAC44, 0xCD03, 0xAC45,
+	0xCD04, 0xAC46, 0xCD05, 0xAC47, 0xCD06, 0xAC48, 0xCD07, 0xAC49,
+	0xCD08, 0xC3CA, 0xCD09, 0xC3CB, 0xCD0A, 0xAC4A, 0xCD0B, 0xAC4B,
+	0xCD0C, 0xC3CC, 0xCD0D, 0xAC4C, 0xCD0E, 0xAC4D, 0xCD0F, 0xAC4E,
+	0xCD10, 0xC3CD, 0xCD11, 0xAC4F, 0xCD12, 0xAC50, 0xCD13, 0xAC51,
+	0xCD14, 0xAC52, 0xCD15, 0xAC53, 0xCD16, 0xAC54, 0xCD17, 0xAC55,
+	0xCD18, 0xC3CE, 0xCD19, 0xC3CF, 0xCD1A, 0xAC56, 0xCD1B, 0xC3D0,
+	0xCD1C, 0xAC57, 0xCD1D, 0xC3D1, 0xCD1E, 0xAC58, 0xCD1F, 0xAC59,
+	0xCD20, 0xAC5A, 0xCD21, 0xAC61, 0xCD22, 0xAC62, 0xCD23, 0xAC63,
+	0xCD24, 0xC3D2, 0xCD25, 0xAC64, 0xCD26, 0xAC65, 0xCD27, 0xAC66,
+	0xCD28, 0xC3D3, 0xCD29, 0xAC67, 0xCD2A, 0xAC68, 0xCD2B, 0xAC69,
+	0xCD2C, 0xC3D4, 0xCD2D, 0xAC6A, 0xCD2E, 0xAC6B, 0xCD2F, 0xAC6C,
+	0xCD30, 0xAC6D, 0xCD31, 0xAC6E, 0xCD32, 0xAC6F, 0xCD33, 0xAC70,
+	0xCD34, 0xAC71, 0xCD35, 0xAC72, 0xCD36, 0xAC73, 0xCD37, 0xAC74,
+	0xCD38, 0xAC75, 0xCD39, 0xC3D5, 0xCD3A, 0xAC76, 0xCD3B, 0xAC77,
+	0xCD3C, 0xAC78, 0xCD3D, 0xAC79, 0xCD3E, 0xAC7A, 0xCD3F, 0xAC81,
+	0xCD40, 0xAC82, 0xCD41, 0xAC83, 0xCD42, 0xAC84, 0xCD43, 0xAC85,
+	0xCD44, 0xAC86, 0xCD45, 0xAC87, 0xCD46, 0xAC88, 0xCD47, 0xAC89,
+	0xCD48, 0xAC8A, 0xCD49, 0xAC8B, 0xCD4A, 0xAC8C, 0xCD4B, 0xAC8D,
+	0xCD4C, 0xAC8E, 0xCD4D, 0xAC8F, 0xCD4E, 0xAC90, 0xCD4F, 0xAC91,
+	0xCD50, 0xAC92, 0xCD51, 0xAC93, 0xCD52, 0xAC94, 0xCD53, 0xAC95,
+	0xCD54, 0xAC96, 0xCD55, 0xAC97, 0xCD56, 0xAC98, 0xCD57, 0xAC99,
+	0xCD58, 0xAC9A, 0xCD59, 0xAC9B, 0xCD5A, 0xAC9C, 0xCD5B, 0xAC9D,
+	0xCD5C, 0xC3D6, 0xCD5D, 0xAC9E, 0xCD5E, 0xAC9F, 0xCD5F, 0xACA0,
+	0xCD60, 0xC3D7, 0xCD61, 0xAD41, 0xCD62, 0xAD42, 0xCD63, 0xAD43,
+	0xCD64, 0xC3D8, 0xCD65, 0xAD44, 0xCD66, 0xAD45, 0xCD67, 0xAD46,
+	0xCD68, 0xAD47, 0xCD69, 0xAD48, 0xCD6A, 0xAD49, 0xCD6B, 0xAD4A,
+	0xCD6C, 0xC3D9, 0xCD6D, 0xC3DA, 0xCD6E, 0xAD4B, 0xCD6F, 0xC3DB,
+	0xCD70, 0xAD4C, 0xCD71, 0xC3DC, 0xCD72, 0xAD4D, 0xCD73, 0xAD4E,
+	0xCD74, 0xAD4F, 0xCD75, 0xAD50, 0xCD76, 0xAD51, 0xCD77, 0xAD52,
+	0xCD78, 0xC3DD, 0xCD79, 0xAD53, 0xCD7A, 0xAD54, 0xCD7B, 0xAD55,
+	0xCD7C, 0xAD56, 0xCD7D, 0xAD57, 0xCD7E, 0xAD58, 0xCD7F, 0xAD59,
+	0xCD80, 0xAD5A, 0xCD81, 0xAD61, 0xCD82, 0xAD62, 0xCD83, 0xAD63,
+	0xCD84, 0xAD64, 0xCD85, 0xAD65, 0xCD86, 0xAD66, 0xCD87, 0xAD67,
+	0xCD88, 0xC3DE, 0xCD89, 0xAD68, 0xCD8A, 0xAD69, 0xCD8B, 0xAD6A,
+	0xCD8C, 0xAD6B, 0xCD8D, 0xAD6C, 0xCD8E, 0xAD6D, 0xCD8F, 0xAD6E,
+	0xCD90, 0xAD6F, 0xCD91, 0xAD70, 0xCD92, 0xAD71, 0xCD93, 0xAD72,
+	0xCD94, 0xC3DF, 0xCD95, 0xC3E0, 0xCD96, 0xAD73, 0xCD97, 0xAD74,
+	0xCD98, 0xC3E1, 0xCD99, 0xAD75, 0xCD9A, 0xAD76, 0xCD9B, 0xAD77,
+	0xCD9C, 0xC3E2, 0xCD9D, 0xAD78, 0xCD9E, 0xAD79, 0xCD9F, 0xAD7A,
+	0xCDA0, 0xAD81, 0xCDA1, 0xAD82, 0xCDA2, 0xAD83, 0xCDA3, 0xAD84,
+	0xCDA4, 0xC3E3, 0xCDA5, 0xC3E4, 0xCDA6, 0xAD85, 0xCDA7, 0xC3E5,
+	0xCDA8, 0xAD86, 0xCDA9, 0xC3E6, 0xCDAA, 0xAD87, 0xCDAB, 0xAD88,
+	0xCDAC, 0xAD89, 0xCDAD, 0xAD8A, 0xCDAE, 0xAD8B, 0xCDAF, 0xAD8C,
+	0xCDB0, 0xC3E7, 0xCDB1, 0xAD8D, 0xCDB2, 0xAD8E, 0xCDB3, 0xAD8F,
+	0xCDB4, 0xAD90, 0xCDB5, 0xAD91, 0xCDB6, 0xAD92, 0xCDB7, 0xAD93,
+	0xCDB8, 0xAD94, 0xCDB9, 0xAD95, 0xCDBA, 0xAD96, 0xCDBB, 0xAD97,
+	0xCDBC, 0xAD98, 0xCDBD, 0xAD99, 0xCDBE, 0xAD9A, 0xCDBF, 0xAD9B,
+	0xCDC0, 0xAD9C, 0xCDC1, 0xAD9D, 0xCDC2, 0xAD9E, 0xCDC3, 0xAD9F,
+	0xCDC4, 0xC3E8, 0xCDC5, 0xADA0, 0xCDC6, 0xAE41, 0xCDC7, 0xAE42,
+	0xCDC8, 0xAE43, 0xCDC9, 0xAE44, 0xCDCA, 0xAE45, 0xCDCB, 0xAE46,
+	0xCDCC, 0xC3E9, 0xCDCD, 0xAE47, 0xCDCE, 0xAE48, 0xCDCF, 0xAE49,
+	0xCDD0, 0xC3EA, 0xCDD1, 0xAE4A, 0xCDD2, 0xAE4B, 0xCDD3, 0xAE4C,
+	0xCDD4, 0xAE4D, 0xCDD5, 0xAE4E, 0xCDD6, 0xAE4F, 0xCDD7, 0xAE50,
+	0xCDD8, 0xAE51, 0xCDD9, 0xAE52, 0xCDDA, 0xAE53, 0xCDDB, 0xAE54,
+	0xCDDC, 0xAE55, 0xCDDD, 0xAE56, 0xCDDE, 0xAE57, 0xCDDF, 0xAE58,
+	0xCDE0, 0xAE59, 0xCDE1, 0xAE5A, 0xCDE2, 0xAE61, 0xCDE3, 0xAE62,
+	0xCDE4, 0xAE63, 0xCDE5, 0xAE64, 0xCDE6, 0xAE65, 0xCDE7, 0xAE66,
+	0xCDE8, 0xC3EB, 0xCDE9, 0xAE67, 0xCDEA, 0xAE68, 0xCDEB, 0xAE69,
+	0xCDEC, 0xC3EC, 0xCDED, 0xAE6A, 0xCDEE, 0xAE6B, 0xCDEF, 0xAE6C,
+	0xCDF0, 0xC3ED, 0xCDF1, 0xAE6D, 0xCDF2, 0xAE6E, 0xCDF3, 0xAE6F,
+	0xCDF4, 0xAE70, 0xCDF5, 0xAE71, 0xCDF6, 0xAE72, 0xCDF7, 0xAE73,
+	0xCDF8, 0xC3EE, 0xCDF9, 0xC3EF, 0xCDFA, 0xAE74, 0xCDFB, 0xC3F0,
+	0xCDFC, 0xAE75, 0xCDFD, 0xC3F1, 0xCDFE, 0xAE76, 0xCDFF, 0xAE77,
+	0xCE00, 0xAE78, 0xCE01, 0xAE79, 0xCE02, 0xAE7A, 0xCE03, 0xAE81,
+	0xCE04, 0xC3F2, 0xCE05, 0xAE82, 0xCE06, 0xAE83, 0xCE07, 0xAE84,
+	0xCE08, 0xC3F3, 0xCE09, 0xAE85, 0xCE0A, 0xAE86, 0xCE0B, 0xAE87,
+	0xCE0C, 0xC3F4, 0xCE0D, 0xAE88, 0xCE0E, 0xAE89, 0xCE0F, 0xAE8A,
+	0xCE10, 0xAE8B, 0xCE11, 0xAE8C, 0xCE12, 0xAE8D, 0xCE13, 0xAE8E,
+	0xCE14, 0xC3F5, 0xCE15, 0xAE8F, 0xCE16, 0xAE90, 0xCE17, 0xAE91,
+	0xCE18, 0xAE92, 0xCE19, 0xC3F6, 0xCE1A, 0xAE93, 0xCE1B, 0xAE94,
+	0xCE1C, 0xAE95, 0xCE1D, 0xAE96, 0xCE1E, 0xAE97, 0xCE1F, 0xAE98,
+	0xCE20, 0xC3F7, 0xCE21, 0xC3F8, 0xCE22, 0xAE99, 0xCE23, 0xAE9A,
+	0xCE24, 0xC3F9, 0xCE25, 0xAE9B, 0xCE26, 0xAE9C, 0xCE27, 0xAE9D,
+	0xCE28, 0xC3FA, 0xCE29, 0xAE9E, 0xCE2A, 0xAE9F, 0xCE2B, 0xAEA0,
+	0xCE2C, 0xAF41, 0xCE2D, 0xAF42, 0xCE2E, 0xAF43, 0xCE2F, 0xAF44,
+	0xCE30, 0xC3FB, 0xCE31, 0xC3FC, 0xCE32, 0xAF45, 0xCE33, 0xC3FD,
+	0xCE34, 0xAF46, 0xCE35, 0xC3FE, 0xCE36, 0xAF47, 0xCE37, 0xAF48,
+	0xCE38, 0xAF49, 0xCE39, 0xAF4A, 0xCE3A, 0xAF4B, 0xCE3B, 0xAF4C,
+	0xCE3C, 0xAF4D, 0xCE3D, 0xAF4E, 0xCE3E, 0xAF4F, 0xCE3F, 0xAF50,
+	0xCE40, 0xAF51, 0xCE41, 0xAF52, 0xCE42, 0xAF53, 0xCE43, 0xAF54,
+	0xCE44, 0xAF55, 0xCE45, 0xAF56, 0xCE46, 0xAF57, 0xCE47, 0xAF58,
+	0xCE48, 0xAF59, 0xCE49, 0xAF5A, 0xCE4A, 0xAF61, 0xCE4B, 0xAF62,
+	0xCE4C, 0xAF63, 0xCE4D, 0xAF64, 0xCE4E, 0xAF65, 0xCE4F, 0xAF66,
+	0xCE50, 0xAF67, 0xCE51, 0xAF68, 0xCE52, 0xAF69, 0xCE53, 0xAF6A,
+	0xCE54, 0xAF6B, 0xCE55, 0xAF6C, 0xCE56, 0xAF6D, 0xCE57, 0xAF6E,
+	0xCE58, 0xC4A1, 0xCE59, 0xC4A2, 0xCE5A, 0xAF6F, 0xCE5B, 0xAF70,
+	0xCE5C, 0xC4A3, 0xCE5D, 0xAF71, 0xCE5E, 0xAF72, 0xCE5F, 0xC4A4,
+	0xCE60, 0xC4A5, 0xCE61, 0xC4A6, 0xCE62, 0xAF73, 0xCE63, 0xAF74,
+	0xCE64, 0xAF75, 0xCE65, 0xAF76, 0xCE66, 0xAF77, 0xCE67, 0xAF78,
+	0xCE68, 0xC4A7, 0xCE69, 0xC4A8, 0xCE6A, 0xAF79, 0xCE6B, 0xC4A9,
+	0xCE6C, 0xAF7A, 0xCE6D, 0xC4AA, 0xCE6E, 0xAF81, 0xCE6F, 0xAF82,
+	0xCE70, 0xAF83, 0xCE71, 0xAF84, 0xCE72, 0xAF85, 0xCE73, 0xAF86,
+	0xCE74, 0xC4AB, 0xCE75, 0xC4AC, 0xCE76, 0xAF87, 0xCE77, 0xAF88,
+	0xCE78, 0xC4AD, 0xCE79, 0xAF89, 0xCE7A, 0xAF8A, 0xCE7B, 0xAF8B,
+	0xCE7C, 0xC4AE, 0xCE7D, 0xAF8C, 0xCE7E, 0xAF8D, 0xCE7F, 0xAF8E,
+	0xCE80, 0xAF8F, 0xCE81, 0xAF90, 0xCE82, 0xAF91, 0xCE83, 0xAF92,
+	0xCE84, 0xC4AF, 0xCE85, 0xC4B0, 0xCE86, 0xAF93, 0xCE87, 0xC4B1,
+	0xCE88, 0xAF94, 0xCE89, 0xC4B2, 0xCE8A, 0xAF95, 0xCE8B, 0xAF96,
+	0xCE8C, 0xAF97, 0xCE8D, 0xAF98, 0xCE8E, 0xAF99, 0xCE8F, 0xAF9A,
+	0xCE90, 0xC4B3, 0xCE91, 0xC4B4, 0xCE92, 0xAF9B, 0xCE93, 0xAF9C,
+	0xCE94, 0xC4B5, 0xCE95, 0xAF9D, 0xCE96, 0xAF9E, 0xCE97, 0xAF9F,
+	0xCE98, 0xC4B6, 0xCE99, 0xAFA0, 0xCE9A, 0xB041, 0xCE9B, 0xB042,
+	0xCE9C, 0xB043, 0xCE9D, 0xB044, 0xCE9E, 0xB045, 0xCE9F, 0xB046,
+	0xCEA0, 0xC4B7, 0xCEA1, 0xC4B8, 0xCEA2, 0xB047, 0xCEA3, 0xC4B9,
+	0xCEA4, 0xC4BA, 0xCEA5, 0xC4BB, 0xCEA6, 0xB048, 0xCEA7, 0xB049,
+	0xCEA8, 0xB04A, 0xCEA9, 0xB04B, 0xCEAA, 0xB04C, 0xCEAB, 0xB04D,
+	0xCEAC, 0xC4BC, 0xCEAD, 0xC4BD, 0xCEAE, 0xB04E, 0xCEAF, 0xB04F,
+	0xCEB0, 0xB050, 0xCEB1, 0xB051, 0xCEB2, 0xB052, 0xCEB3, 0xB053,
+	0xCEB4, 0xB054, 0xCEB5, 0xB055, 0xCEB6, 0xB056, 0xCEB7, 0xB057,
+	0xCEB8, 0xB058, 0xCEB9, 0xB059, 0xCEBA, 0xB05A, 0xCEBB, 0xB061,
+	0xCEBC, 0xB062, 0xCEBD, 0xB063, 0xCEBE, 0xB064, 0xCEBF, 0xB065,
+	0xCEC0, 0xB066, 0xCEC1, 0xC4BE, 0xCEC2, 0xB067, 0xCEC3, 0xB068,
+	0xCEC4, 0xB069, 0xCEC5, 0xB06A, 0xCEC6, 0xB06B, 0xCEC7, 0xB06C,
+	0xCEC8, 0xB06D, 0xCEC9, 0xB06E, 0xCECA, 0xB06F, 0xCECB, 0xB070,
+	0xCECC, 0xB071, 0xCECD, 0xB072, 0xCECE, 0xB073, 0xCECF, 0xB074,
+	0xCED0, 0xB075, 0xCED1, 0xB076, 0xCED2, 0xB077, 0xCED3, 0xB078,
+	0xCED4, 0xB079, 0xCED5, 0xB07A, 0xCED6, 0xB081, 0xCED7, 0xB082,
+	0xCED8, 0xB083, 0xCED9, 0xB084, 0xCEDA, 0xB085, 0xCEDB, 0xB086,
+	0xCEDC, 0xB087, 0xCEDD, 0xB088, 0xCEDE, 0xB089, 0xCEDF, 0xB08A,
+	0xCEE0, 0xB08B, 0xCEE1, 0xB08C, 0xCEE2, 0xB08D, 0xCEE3, 0xB08E,
+	0xCEE4, 0xC4BF, 0xCEE5, 0xC4C0, 0xCEE6, 0xB08F, 0xCEE7, 0xB090,
+	0xCEE8, 0xC4C1, 0xCEE9, 0xB091, 0xCEEA, 0xB092, 0xCEEB, 0xC4C2,
+	0xCEEC, 0xC4C3, 0xCEED, 0xB093, 0xCEEE, 0xB094, 0xCEEF, 0xB095,
+	0xCEF0, 0xB096, 0xCEF1, 0xB097, 0xCEF2, 0xB098, 0xCEF3, 0xB099,
+	0xCEF4, 0xC4C4, 0xCEF5, 0xC4C5, 0xCEF6, 0xB09A, 0xCEF7, 0xC4C6,
+	0xCEF8, 0xC4C7, 0xCEF9, 0xC4C8, 0xCEFA, 0xB09B, 0xCEFB, 0xB09C,
+	0xCEFC, 0xB09D, 0xCEFD, 0xB09E, 0xCEFE, 0xB09F, 0xCEFF, 0xB0A0,
+	0xCF00, 0xC4C9, 0xCF01, 0xC4CA, 0xCF02, 0xB141, 0xCF03, 0xB142,
+	0xCF04, 0xC4CB, 0xCF05, 0xB143, 0xCF06, 0xB144, 0xCF07, 0xB145,
+	0xCF08, 0xC4CC, 0xCF09, 0xB146, 0xCF0A, 0xB147, 0xCF0B, 0xB148,
+	0xCF0C, 0xB149, 0xCF0D, 0xB14A, 0xCF0E, 0xB14B, 0xCF0F, 0xB14C,
+	0xCF10, 0xC4CD, 0xCF11, 0xC4CE, 0xCF12, 0xB14D, 0xCF13, 0xC4CF,
+	0xCF14, 0xB14E, 0xCF15, 0xC4D0, 0xCF16, 0xB14F, 0xCF17, 0xB150,
+	0xCF18, 0xB151, 0xCF19, 0xB152, 0xCF1A, 0xB153, 0xCF1B, 0xB154,
+	0xCF1C, 0xC4D1, 0xCF1D, 0xB155, 0xCF1E, 0xB156, 0xCF1F, 0xB157,
+	0xCF20, 0xC4D2, 0xCF21, 0xB158, 0xCF22, 0xB159, 0xCF23, 0xB15A,
+	0xCF24, 0xC4D3, 0xCF25, 0xB161, 0xCF26, 0xB162, 0xCF27, 0xB163,
+	0xCF28, 0xB164, 0xCF29, 0xB165, 0xCF2A, 0xB166, 0xCF2B, 0xB167,
+	0xCF2C, 0xC4D4, 0xCF2D, 0xC4D5, 0xCF2E, 0xB168, 0xCF2F, 0xC4D6,
+	0xCF30, 0xC4D7, 0xCF31, 0xC4D8, 0xCF32, 0xB169, 0xCF33, 0xB16A,
+	0xCF34, 0xB16B, 0xCF35, 0xB16C, 0xCF36, 0xB16D, 0xCF37, 0xB16E,
+	0xCF38, 0xC4D9, 0xCF39, 0xB16F, 0xCF3A, 0xB170, 0xCF3B, 0xB171,
+	0xCF3C, 0xB172, 0xCF3D, 0xB173, 0xCF3E, 0xB174, 0xCF3F, 0xB175,
+	0xCF40, 0xB176, 0xCF41, 0xB177, 0xCF42, 0xB178, 0xCF43, 0xB179,
+	0xCF44, 0xB17A, 0xCF45, 0xB181, 0xCF46, 0xB182, 0xCF47, 0xB183,
+	0xCF48, 0xB184, 0xCF49, 0xB185, 0xCF4A, 0xB186, 0xCF4B, 0xB187,
+	0xCF4C, 0xB188, 0xCF4D, 0xB189, 0xCF4E, 0xB18A, 0xCF4F, 0xB18B,
+	0xCF50, 0xB18C, 0xCF51, 0xB18D, 0xCF52, 0xB18E, 0xCF53, 0xB18F,
+	0xCF54, 0xC4DA, 0xCF55, 0xC4DB, 0xCF56, 0xB190, 0xCF57, 0xB191,
+	0xCF58, 0xC4DC, 0xCF59, 0xB192, 0xCF5A, 0xB193, 0xCF5B, 0xB194,
+	0xCF5C, 0xC4DD, 0xCF5D, 0xB195, 0xCF5E, 0xB196, 0xCF5F, 0xB197,
+	0xCF60, 0xB198, 0xCF61, 0xB199, 0xCF62, 0xB19A, 0xCF63, 0xB19B,
+	0xCF64, 0xC4DE, 0xCF65, 0xC4DF, 0xCF66, 0xB19C, 0xCF67, 0xC4E0,
+	0xCF68, 0xB19D, 0xCF69, 0xC4E1, 0xCF6A, 0xB19E, 0xCF6B, 0xB19F,
+	0xCF6C, 0xB1A0, 0xCF6D, 0xB241, 0xCF6E, 0xB242, 0xCF6F, 0xB243,
+	0xCF70, 0xC4E2, 0xCF71, 0xC4E3, 0xCF72, 0xB244, 0xCF73, 0xB245,
+	0xCF74, 0xC4E4, 0xCF75, 0xB246, 0xCF76, 0xB247, 0xCF77, 0xB248,
+	0xCF78, 0xC4E5, 0xCF79, 0xB249, 0xCF7A, 0xB24A, 0xCF7B, 0xB24B,
+	0xCF7C, 0xB24C, 0xCF7D, 0xB24D, 0xCF7E, 0xB24E, 0xCF7F, 0xB24F,
+	0xCF80, 0xC4E6, 0xCF81, 0xB250, 0xCF82, 0xB251, 0xCF83, 0xB252,
+	0xCF84, 0xB253, 0xCF85, 0xC4E7, 0xCF86, 0xB254, 0xCF87, 0xB255,
+	0xCF88, 0xB256, 0xCF89, 0xB257, 0xCF8A, 0xB258, 0xCF8B, 0xB259,
+	0xCF8C, 0xC4E8, 0xCF8D, 0xB25A, 0xCF8E, 0xB261, 0xCF8F, 0xB262,
+	0xCF90, 0xB263, 0xCF91, 0xB264, 0xCF92, 0xB265, 0xCF93, 0xB266,
+	0xCF94, 0xB267, 0xCF95, 0xB268, 0xCF96, 0xB269, 0xCF97, 0xB26A,
+	0xCF98, 0xB26B, 0xCF99, 0xB26C, 0xCF9A, 0xB26D, 0xCF9B, 0xB26E,
+	0xCF9C, 0xB26F, 0xCF9D, 0xB270, 0xCF9E, 0xB271, 0xCF9F, 0xB272,
+	0xCFA0, 0xB273, 0xCFA1, 0xC4E9, 0xCFA2, 0xB274, 0xCFA3, 0xB275,
+	0xCFA4, 0xB276, 0xCFA5, 0xB277, 0xCFA6, 0xB278, 0xCFA7, 0xB279,
+	0xCFA8, 0xC4EA, 0xCFA9, 0xB27A, 0xCFAA, 0xB281, 0xCFAB, 0xB282,
+	0xCFAC, 0xB283, 0xCFAD, 0xB284, 0xCFAE, 0xB285, 0xCFAF, 0xB286,
+	0xCFB0, 0xC4EB, 0xCFB1, 0xB287, 0xCFB2, 0xB288, 0xCFB3, 0xB289,
+	0xCFB4, 0xB28A, 0xCFB5, 0xB28B, 0xCFB6, 0xB28C, 0xCFB7, 0xB28D,
+	0xCFB8, 0xB28E, 0xCFB9, 0xB28F, 0xCFBA, 0xB290, 0xCFBB, 0xB291,
+	0xCFBC, 0xB292, 0xCFBD, 0xB293, 0xCFBE, 0xB294, 0xCFBF, 0xB295,
+	0xCFC0, 0xB296, 0xCFC1, 0xB297, 0xCFC2, 0xB298, 0xCFC3, 0xB299,
+	0xCFC4, 0xC4EC, 0xCFC5, 0xB29A, 0xCFC6, 0xB29B, 0xCFC7, 0xB29C,
+	0xCFC8, 0xB29D, 0xCFC9, 0xB29E, 0xCFCA, 0xB29F, 0xCFCB, 0xB2A0,
+	0xCFCC, 0xB341, 0xCFCD, 0xB342, 0xCFCE, 0xB343, 0xCFCF, 0xB344,
+	0xCFD0, 0xB345, 0xCFD1, 0xB346, 0xCFD2, 0xB347, 0xCFD3, 0xB348,
+	0xCFD4, 0xB349, 0xCFD5, 0xB34A, 0xCFD6, 0xB34B, 0xCFD7, 0xB34C,
+	0xCFD8, 0xB34D, 0xCFD9, 0xB34E, 0xCFDA, 0xB34F, 0xCFDB, 0xB350,
+	0xCFDC, 0xB351, 0xCFDD, 0xB352, 0xCFDE, 0xB353, 0xCFDF, 0xB354,
+	0xCFE0, 0xC4ED, 0xCFE1, 0xC4EE, 0xCFE2, 0xB355, 0xCFE3, 0xB356,
+	0xCFE4, 0xC4EF, 0xCFE5, 0xB357, 0xCFE6, 0xB358, 0xCFE7, 0xB359,
+	0xCFE8, 0xC4F0, 0xCFE9, 0xB35A, 0xCFEA, 0xB361, 0xCFEB, 0xB362,
+	0xCFEC, 0xB363, 0xCFED, 0xB364, 0xCFEE, 0xB365, 0xCFEF, 0xB366,
+	0xCFF0, 0xC4F1, 0xCFF1, 0xC4F2, 0xCFF2, 0xB367, 0xCFF3, 0xC4F3,
+	0xCFF4, 0xB368, 0xCFF5, 0xC4F4, 0xCFF6, 0xB369, 0xCFF7, 0xB36A,
+	0xCFF8, 0xB36B, 0xCFF9, 0xB36C, 0xCFFA, 0xB36D, 0xCFFB, 0xB36E,
+	0xCFFC, 0xC4F5, 0xCFFD, 0xB36F, 0xCFFE, 0xB370, 0xCFFF, 0xB371,
+	0xD000, 0xC4F6, 0xD001, 0xB372, 0xD002, 0xB373, 0xD003, 0xB374,
+	0xD004, 0xC4F7, 0xD005, 0xB375, 0xD006, 0xB376, 0xD007, 0xB377,
+	0xD008, 0xB378, 0xD009, 0xB379, 0xD00A, 0xB37A, 0xD00B, 0xB381,
+	0xD00C, 0xB382, 0xD00D, 0xB383, 0xD00E, 0xB384, 0xD00F, 0xB385,
+	0xD010, 0xB386, 0xD011, 0xC4F8, 0xD012, 0xB387, 0xD013, 0xB388,
+	0xD014, 0xB389, 0xD015, 0xB38A, 0xD016, 0xB38B, 0xD017, 0xB38C,
+	0xD018, 0xC4F9, 0xD019, 0xB38D, 0xD01A, 0xB38E, 0xD01B, 0xB38F,
+	0xD01C, 0xB390, 0xD01D, 0xB391, 0xD01E, 0xB392, 0xD01F, 0xB393,
+	0xD020, 0xB394, 0xD021, 0xB395, 0xD022, 0xB396, 0xD023, 0xB397,
+	0xD024, 0xB398, 0xD025, 0xB399, 0xD026, 0xB39A, 0xD027, 0xB39B,
+	0xD028, 0xB39C, 0xD029, 0xB39D, 0xD02A, 0xB39E, 0xD02B, 0xB39F,
+	0xD02C, 0xB3A0, 0xD02D, 0xC4FA, 0xD02E, 0xB441, 0xD02F, 0xB442,
+	0xD030, 0xB443, 0xD031, 0xB444, 0xD032, 0xB445, 0xD033, 0xB446,
+	0xD034, 0xC4FB, 0xD035, 0xC4FC, 0xD036, 0xB447, 0xD037, 0xB448,
+	0xD038, 0xC4FD, 0xD039, 0xB449, 0xD03A, 0xB44A, 0xD03B, 0xB44B,
+	0xD03C, 0xC4FE, 0xD03D, 0xB44C, 0xD03E, 0xB44D, 0xD03F, 0xB44E,
+	0xD040, 0xB44F, 0xD041, 0xB450, 0xD042, 0xB451, 0xD043, 0xB452,
+	0xD044, 0xC5A1, 0xD045, 0xC5A2, 0xD046, 0xB453, 0xD047, 0xC5A3,
+	0xD048, 0xB454, 0xD049, 0xC5A4, 0xD04A, 0xB455, 0xD04B, 0xB456,
+	0xD04C, 0xB457, 0xD04D, 0xB458, 0xD04E, 0xB459, 0xD04F, 0xB45A,
+	0xD050, 0xC5A5, 0xD051, 0xB461, 0xD052, 0xB462, 0xD053, 0xB463,
+	0xD054, 0xC5A6, 0xD055, 0xB464, 0xD056, 0xB465, 0xD057, 0xB466,
+	0xD058, 0xC5A7, 0xD059, 0xB467, 0xD05A, 0xB468, 0xD05B, 0xB469,
+	0xD05C, 0xB46A, 0xD05D, 0xB46B, 0xD05E, 0xB46C, 0xD05F, 0xB46D,
+	0xD060, 0xC5A8, 0xD061, 0xB46E, 0xD062, 0xB46F, 0xD063, 0xB470,
+	0xD064, 0xB471, 0xD065, 0xB472, 0xD066, 0xB473, 0xD067, 0xB474,
+	0xD068, 0xB475, 0xD069, 0xB476, 0xD06A, 0xB477, 0xD06B, 0xB478,
+	0xD06C, 0xC5A9, 0xD06D, 0xC5AA, 0xD06E, 0xB479, 0xD06F, 0xB47A,
+	0xD070, 0xC5AB, 0xD071, 0xB481, 0xD072, 0xB482, 0xD073, 0xB483,
+	0xD074, 0xC5AC, 0xD075, 0xB484, 0xD076, 0xB485, 0xD077, 0xB486,
+	0xD078, 0xB487, 0xD079, 0xB488, 0xD07A, 0xB489, 0xD07B, 0xB48A,
+	0xD07C, 0xC5AD, 0xD07D, 0xC5AE, 0xD07E, 0xB48B, 0xD07F, 0xB48C,
+	0xD080, 0xB48D, 0xD081, 0xC5AF, 0xD082, 0xB48E, 0xD083, 0xB48F,
+	0xD084, 0xB490, 0xD085, 0xB491, 0xD086, 0xB492, 0xD087, 0xB493,
+	0xD088, 0xB494, 0xD089, 0xB495, 0xD08A, 0xB496, 0xD08B, 0xB497,
+	0xD08C, 0xB498, 0xD08D, 0xB499, 0xD08E, 0xB49A, 0xD08F, 0xB49B,
+	0xD090, 0xB49C, 0xD091, 0xB49D, 0xD092, 0xB49E, 0xD093, 0xB49F,
+	0xD094, 0xB4A0, 0xD095, 0xB541, 0xD096, 0xB542, 0xD097, 0xB543,
+	0xD098, 0xB544, 0xD099, 0xB545, 0xD09A, 0xB546, 0xD09B, 0xB547,
+	0xD09C, 0xB548, 0xD09D, 0xB549, 0xD09E, 0xB54A, 0xD09F, 0xB54B,
+	0xD0A0, 0xB54C, 0xD0A1, 0xB54D, 0xD0A2, 0xB54E, 0xD0A3, 0xB54F,
+	0xD0A4, 0xC5B0, 0xD0A5, 0xC5B1, 0xD0A6, 0xB550, 0xD0A7, 0xB551,
+	0xD0A8, 0xC5B2, 0xD0A9, 0xB552, 0xD0AA, 0xB553, 0xD0AB, 0xB554,
+	0xD0AC, 0xC5B3, 0xD0AD, 0xB555, 0xD0AE, 0xB556, 0xD0AF, 0xB557,
+	0xD0B0, 0xB558, 0xD0B1, 0xB559, 0xD0B2, 0xB55A, 0xD0B3, 0xB561,
+	0xD0B4, 0xC5B4, 0xD0B5, 0xC5B5, 0xD0B6, 0xB562, 0xD0B7, 0xC5B6,
+	0xD0B8, 0xB563, 0xD0B9, 0xC5B7, 0xD0BA, 0xB564, 0xD0BB, 0xB565,
+	0xD0BC, 0xB566, 0xD0BD, 0xB567, 0xD0BE, 0xB568, 0xD0BF, 0xB569,
+	0xD0C0, 0xC5B8, 0xD0C1, 0xC5B9, 0xD0C2, 0xB56A, 0xD0C3, 0xB56B,
+	0xD0C4, 0xC5BA, 0xD0C5, 0xB56C, 0xD0C6, 0xB56D, 0xD0C7, 0xB56E,
+	0xD0C8, 0xC5BB, 0xD0C9, 0xC5BC, 0xD0CA, 0xB56F, 0xD0CB, 0xB570,
+	0xD0CC, 0xB571, 0xD0CD, 0xB572, 0xD0CE, 0xB573, 0xD0CF, 0xB574,
+	0xD0D0, 0xC5BD, 0xD0D1, 0xC5BE, 0xD0D2, 0xB575, 0xD0D3, 0xC5BF,
+	0xD0D4, 0xC5C0, 0xD0D5, 0xC5C1, 0xD0D6, 0xB576, 0xD0D7, 0xB577,
+	0xD0D8, 0xB578, 0xD0D9, 0xB579, 0xD0DA, 0xB57A, 0xD0DB, 0xB581,
+	0xD0DC, 0xC5C2, 0xD0DD, 0xC5C3, 0xD0DE, 0xB582, 0xD0DF, 0xB583,
+	0xD0E0, 0xC5C4, 0xD0E1, 0xB584, 0xD0E2, 0xB585, 0xD0E3, 0xB586,
+	0xD0E4, 0xC5C5, 0xD0E5, 0xB587, 0xD0E6, 0xB588, 0xD0E7, 0xB589,
+	0xD0E8, 0xB58A, 0xD0E9, 0xB58B, 0xD0EA, 0xB58C, 0xD0EB, 0xB58D,
+	0xD0EC, 0xC5C6, 0xD0ED, 0xC5C7, 0xD0EE, 0xB58E, 0xD0EF, 0xC5C8,
+	0xD0F0, 0xC5C9, 0xD0F1, 0xC5CA, 0xD0F2, 0xB58F, 0xD0F3, 0xB590,
+	0xD0F4, 0xB591, 0xD0F5, 0xB592, 0xD0F6, 0xB593, 0xD0F7, 0xB594,
+	0xD0F8, 0xC5CB, 0xD0F9, 0xB595, 0xD0FA, 0xB596, 0xD0FB, 0xB597,
+	0xD0FC, 0xB598, 0xD0FD, 0xB599, 0xD0FE, 0xB59A, 0xD0FF, 0xB59B,
+	0xD100, 0xB59C, 0xD101, 0xB59D, 0xD102, 0xB59E, 0xD103, 0xB59F,
+	0xD104, 0xB5A0, 0xD105, 0xB641, 0xD106, 0xB642, 0xD107, 0xB643,
+	0xD108, 0xB644, 0xD109, 0xB645, 0xD10A, 0xB646, 0xD10B, 0xB647,
+	0xD10C, 0xB648, 0xD10D, 0xC5CC, 0xD10E, 0xB649, 0xD10F, 0xB64A,
+	0xD110, 0xB64B, 0xD111, 0xB64C, 0xD112, 0xB64D, 0xD113, 0xB64E,
+	0xD114, 0xB64F, 0xD115, 0xB650, 0xD116, 0xB651, 0xD117, 0xB652,
+	0xD118, 0xB653, 0xD119, 0xB654, 0xD11A, 0xB655, 0xD11B, 0xB656,
+	0xD11C, 0xB657, 0xD11D, 0xB658, 0xD11E, 0xB659, 0xD11F, 0xB65A,
+	0xD120, 0xB661, 0xD121, 0xB662, 0xD122, 0xB663, 0xD123, 0xB664,
+	0xD124, 0xB665, 0xD125, 0xB666, 0xD126, 0xB667, 0xD127, 0xB668,
+	0xD128, 0xB669, 0xD129, 0xB66A, 0xD12A, 0xB66B, 0xD12B, 0xB66C,
+	0xD12C, 0xB66D, 0xD12D, 0xB66E, 0xD12E, 0xB66F, 0xD12F, 0xB670,
+	0xD130, 0xC5CD, 0xD131, 0xC5CE, 0xD132, 0xB671, 0xD133, 0xB672,
+	0xD134, 0xC5CF, 0xD135, 0xB673, 0xD136, 0xB674, 0xD137, 0xB675,
+	0xD138, 0xC5D0, 0xD139, 0xB676, 0xD13A, 0xC5D1, 0xD13B, 0xB677,
+	0xD13C, 0xB678, 0xD13D, 0xB679, 0xD13E, 0xB67A, 0xD13F, 0xB681,
+	0xD140, 0xC5D2, 0xD141, 0xC5D3, 0xD142, 0xB682, 0xD143, 0xC5D4,
+	0xD144, 0xC5D5, 0xD145, 0xC5D6, 0xD146, 0xB683, 0xD147, 0xB684,
+	0xD148, 0xB685, 0xD149, 0xB686, 0xD14A, 0xB687, 0xD14B, 0xB688,
+	0xD14C, 0xC5D7, 0xD14D, 0xC5D8, 0xD14E, 0xB689, 0xD14F, 0xB68A,
+	0xD150, 0xC5D9, 0xD151, 0xB68B, 0xD152, 0xB68C, 0xD153, 0xB68D,
+	0xD154, 0xC5DA, 0xD155, 0xB68E, 0xD156, 0xB68F, 0xD157, 0xB690,
+	0xD158, 0xB691, 0xD159, 0xB692, 0xD15A, 0xB693, 0xD15B, 0xB694,
+	0xD15C, 0xC5DB, 0xD15D, 0xC5DC, 0xD15E, 0xB695, 0xD15F, 0xC5DD,
+	0xD160, 0xB696, 0xD161, 0xC5DE, 0xD162, 0xB697, 0xD163, 0xB698,
+	0xD164, 0xB699, 0xD165, 0xB69A, 0xD166, 0xB69B, 0xD167, 0xB69C,
+	0xD168, 0xC5DF, 0xD169, 0xB69D, 0xD16A, 0xB69E, 0xD16B, 0xB69F,
+	0xD16C, 0xC5E0, 0xD16D, 0xB6A0, 0xD16E, 0xB741, 0xD16F, 0xB742,
+	0xD170, 0xB743, 0xD171, 0xB744, 0xD172, 0xB745, 0xD173, 0xB746,
+	0xD174, 0xB747, 0xD175, 0xB748, 0xD176, 0xB749, 0xD177, 0xB74A,
+	0xD178, 0xB74B, 0xD179, 0xB74C, 0xD17A, 0xB74D, 0xD17B, 0xB74E,
+	0xD17C, 0xC5E1, 0xD17D, 0xB74F, 0xD17E, 0xB750, 0xD17F, 0xB751,
+	0xD180, 0xB752, 0xD181, 0xB753, 0xD182, 0xB754, 0xD183, 0xB755,
+	0xD184, 0xC5E2, 0xD185, 0xB756, 0xD186, 0xB757, 0xD187, 0xB758,
+	0xD188, 0xC5E3, 0xD189, 0xB759, 0xD18A, 0xB75A, 0xD18B, 0xB761,
+	0xD18C, 0xB762, 0xD18D, 0xB763, 0xD18E, 0xB764, 0xD18F, 0xB765,
+	0xD190, 0xB766, 0xD191, 0xB767, 0xD192, 0xB768, 0xD193, 0xB769,
+	0xD194, 0xB76A, 0xD195, 0xB76B, 0xD196, 0xB76C, 0xD197, 0xB76D,
+	0xD198, 0xB76E, 0xD199, 0xB76F, 0xD19A, 0xB770, 0xD19B, 0xB771,
+	0xD19C, 0xB772, 0xD19D, 0xB773, 0xD19E, 0xB774, 0xD19F, 0xB775,
+	0xD1A0, 0xC5E4, 0xD1A1, 0xC5E5, 0xD1A2, 0xB776, 0xD1A3, 0xB777,
+	0xD1A4, 0xC5E6, 0xD1A5, 0xB778, 0xD1A6, 0xB779, 0xD1A7, 0xB77A,
+	0xD1A8, 0xC5E7, 0xD1A9, 0xB781, 0xD1AA, 0xB782, 0xD1AB, 0xB783,
+	0xD1AC, 0xB784, 0xD1AD, 0xB785, 0xD1AE, 0xB786, 0xD1AF, 0xB787,
+	0xD1B0, 0xC5E8, 0xD1B1, 0xC5E9, 0xD1B2, 0xB788, 0xD1B3, 0xC5EA,
+	0xD1B4, 0xB789, 0xD1B5, 0xC5EB, 0xD1B6, 0xB78A, 0xD1B7, 0xB78B,
+	0xD1B8, 0xB78C, 0xD1B9, 0xB78D, 0xD1BA, 0xC5EC, 0xD1BB, 0xB78E,
+	0xD1BC, 0xC5ED, 0xD1BD, 0xB78F, 0xD1BE, 0xB790, 0xD1BF, 0xB791,
+	0xD1C0, 0xC5EE, 0xD1C1, 0xB792, 0xD1C2, 0xB793, 0xD1C3, 0xB794,
+	0xD1C4, 0xB795, 0xD1C5, 0xB796, 0xD1C6, 0xB797, 0xD1C7, 0xB798,
+	0xD1C8, 0xB799, 0xD1C9, 0xB79A, 0xD1CA, 0xB79B, 0xD1CB, 0xB79C,
+	0xD1CC, 0xB79D, 0xD1CD, 0xB79E, 0xD1CE, 0xB79F, 0xD1CF, 0xB7A0,
+	0xD1D0, 0xB841, 0xD1D1, 0xB842, 0xD1D2, 0xB843, 0xD1D3, 0xB844,
+	0xD1D4, 0xB845, 0xD1D5, 0xB846, 0xD1D6, 0xB847, 0xD1D7, 0xB848,
+	0xD1D8, 0xC5EF, 0xD1D9, 0xB849, 0xD1DA, 0xB84A, 0xD1DB, 0xB84B,
+	0xD1DC, 0xB84C, 0xD1DD, 0xB84D, 0xD1DE, 0xB84E, 0xD1DF, 0xB84F,
+	0xD1E0, 0xB850, 0xD1E1, 0xB851, 0xD1E2, 0xB852, 0xD1E3, 0xB853,
+	0xD1E4, 0xB854, 0xD1E5, 0xB855, 0xD1E6, 0xB856, 0xD1E7, 0xB857,
+	0xD1E8, 0xB858, 0xD1E9, 0xB859, 0xD1EA, 0xB85A, 0xD1EB, 0xB861,
+	0xD1EC, 0xB862, 0xD1ED, 0xB863, 0xD1EE, 0xB864, 0xD1EF, 0xB865,
+	0xD1F0, 0xB866, 0xD1F1, 0xB867, 0xD1F2, 0xB868, 0xD1F3, 0xB869,
+	0xD1F4, 0xC5F0, 0xD1F5, 0xB86A, 0xD1F6, 0xB86B, 0xD1F7, 0xB86C,
+	0xD1F8, 0xC5F1, 0xD1F9, 0xB86D, 0xD1FA, 0xB86E, 0xD1FB, 0xB86F,
+	0xD1FC, 0xB870, 0xD1FD, 0xB871, 0xD1FE, 0xB872, 0xD1FF, 0xB873,
+	0xD200, 0xB874, 0xD201, 0xB875, 0xD202, 0xB876, 0xD203, 0xB877,
+	0xD204, 0xB878, 0xD205, 0xB879, 0xD206, 0xB87A, 0xD207, 0xC5F2,
+	0xD208, 0xB881, 0xD209, 0xC5F3, 0xD20A, 0xB882, 0xD20B, 0xB883,
+	0xD20C, 0xB884, 0xD20D, 0xB885, 0xD20E, 0xB886, 0xD20F, 0xB887,
+	0xD210, 0xC5F4, 0xD211, 0xB888, 0xD212, 0xB889, 0xD213, 0xB88A,
+	0xD214, 0xB88B, 0xD215, 0xB88C, 0xD216, 0xB88D, 0xD217, 0xB88E,
+	0xD218, 0xB88F, 0xD219, 0xB890, 0xD21A, 0xB891, 0xD21B, 0xB892,
+	0xD21C, 0xB893, 0xD21D, 0xB894, 0xD21E, 0xB895, 0xD21F, 0xB896,
+	0xD220, 0xB897, 0xD221, 0xB898, 0xD222, 0xB899, 0xD223, 0xB89A,
+	0xD224, 0xB89B, 0xD225, 0xB89C, 0xD226, 0xB89D, 0xD227, 0xB89E,
+	0xD228, 0xB89F, 0xD229, 0xB8A0, 0xD22A, 0xB941, 0xD22B, 0xB942,
+	0xD22C, 0xC5F5, 0xD22D, 0xC5F6, 0xD22E, 0xB943, 0xD22F, 0xB944,
+	0xD230, 0xC5F7, 0xD231, 0xB945, 0xD232, 0xB946, 0xD233, 0xB947,
+	0xD234, 0xC5F8, 0xD235, 0xB948, 0xD236, 0xB949, 0xD237, 0xB94A,
+	0xD238, 0xB94B, 0xD239, 0xB94C, 0xD23A, 0xB94D, 0xD23B, 0xB94E,
+	0xD23C, 0xC5F9, 0xD23D, 0xC5FA, 0xD23E, 0xB94F, 0xD23F, 0xC5FB,
+	0xD240, 0xB950, 0xD241, 0xC5FC, 0xD242, 0xB951, 0xD243, 0xB952,
+	0xD244, 0xB953, 0xD245, 0xB954, 0xD246, 0xB955, 0xD247, 0xB956,
+	0xD248, 0xC5FD, 0xD249, 0xB957, 0xD24A, 0xB958, 0xD24B, 0xB959,
+	0xD24C, 0xB95A, 0xD24D, 0xB961, 0xD24E, 0xB962, 0xD24F, 0xB963,
+	0xD250, 0xB964, 0xD251, 0xB965, 0xD252, 0xB966, 0xD253, 0xB967,
+	0xD254, 0xB968, 0xD255, 0xB969, 0xD256, 0xB96A, 0xD257, 0xB96B,
+	0xD258, 0xB96C, 0xD259, 0xB96D, 0xD25A, 0xB96E, 0xD25B, 0xB96F,
+	0xD25C, 0xC5FE, 0xD25D, 0xB970, 0xD25E, 0xB971, 0xD25F, 0xB972,
+	0xD260, 0xB973, 0xD261, 0xB974, 0xD262, 0xB975, 0xD263, 0xB976,
+	0xD264, 0xC6A1, 0xD265, 0xB977, 0xD266, 0xB978, 0xD267, 0xB979,
+	0xD268, 0xB97A, 0xD269, 0xB981, 0xD26A, 0xB982, 0xD26B, 0xB983,
+	0xD26C, 0xB984, 0xD26D, 0xB985, 0xD26E, 0xB986, 0xD26F, 0xB987,
+	0xD270, 0xB988, 0xD271, 0xB989, 0xD272, 0xB98A, 0xD273, 0xB98B,
+	0xD274, 0xB98C, 0xD275, 0xB98D, 0xD276, 0xB98E, 0xD277, 0xB98F,
+	0xD278, 0xB990, 0xD279, 0xB991, 0xD27A, 0xB992, 0xD27B, 0xB993,
+	0xD27C, 0xB994, 0xD27D, 0xB995, 0xD27E, 0xB996, 0xD27F, 0xB997,
+	0xD280, 0xC6A2, 0xD281, 0xC6A3, 0xD282, 0xB998, 0xD283, 0xB999,
+	0xD284, 0xC6A4, 0xD285, 0xB99A, 0xD286, 0xB99B, 0xD287, 0xB99C,
+	0xD288, 0xC6A5, 0xD289, 0xB99D, 0xD28A, 0xB99E, 0xD28B, 0xB99F,
+	0xD28C, 0xB9A0, 0xD28D, 0xBA41, 0xD28E, 0xBA42, 0xD28F, 0xBA43,
+	0xD290, 0xC6A6, 0xD291, 0xC6A7, 0xD292, 0xBA44, 0xD293, 0xBA45,
+	0xD294, 0xBA46, 0xD295, 0xC6A8, 0xD296, 0xBA47, 0xD297, 0xBA48,
+	0xD298, 0xBA49, 0xD299, 0xBA4A, 0xD29A, 0xBA4B, 0xD29B, 0xBA4C,
+	0xD29C, 0xC6A9, 0xD29D, 0xBA4D, 0xD29E, 0xBA4E, 0xD29F, 0xBA4F,
+	0xD2A0, 0xC6AA, 0xD2A1, 0xBA50, 0xD2A2, 0xBA51, 0xD2A3, 0xBA52,
+	0xD2A4, 0xC6AB, 0xD2A5, 0xBA53, 0xD2A6, 0xBA54, 0xD2A7, 0xBA55,
+	0xD2A8, 0xBA56, 0xD2A9, 0xBA57, 0xD2AA, 0xBA58, 0xD2AB, 0xBA59,
+	0xD2AC, 0xC6AC, 0xD2AD, 0xBA5A, 0xD2AE, 0xBA61, 0xD2AF, 0xBA62,
+	0xD2B0, 0xBA63, 0xD2B1, 0xC6AD, 0xD2B2, 0xBA64, 0xD2B3, 0xBA65,
+	0xD2B4, 0xBA66, 0xD2B5, 0xBA67, 0xD2B6, 0xBA68, 0xD2B7, 0xBA69,
+	0xD2B8, 0xC6AE, 0xD2B9, 0xC6AF, 0xD2BA, 0xBA6A, 0xD2BB, 0xBA6B,
+	0xD2BC, 0xC6B0, 0xD2BD, 0xBA6C, 0xD2BE, 0xBA6D, 0xD2BF, 0xC6B1,
+	0xD2C0, 0xC6B2, 0xD2C1, 0xBA6E, 0xD2C2, 0xC6B3, 0xD2C3, 0xBA6F,
+	0xD2C4, 0xBA70, 0xD2C5, 0xBA71, 0xD2C6, 0xBA72, 0xD2C7, 0xBA73,
+	0xD2C8, 0xC6B4, 0xD2C9, 0xC6B5, 0xD2CA, 0xBA74, 0xD2CB, 0xC6B6,
+	0xD2CC, 0xBA75, 0xD2CD, 0xBA76, 0xD2CE, 0xBA77, 0xD2CF, 0xBA78,
+	0xD2D0, 0xBA79, 0xD2D1, 0xBA7A, 0xD2D2, 0xBA81, 0xD2D3, 0xBA82,
+	0xD2D4, 0xC6B7, 0xD2D5, 0xBA83, 0xD2D6, 0xBA84, 0xD2D7, 0xBA85,
+	0xD2D8, 0xC6B8, 0xD2D9, 0xBA86, 0xD2DA, 0xBA87, 0xD2DB, 0xBA88,
+	0xD2DC, 0xC6B9, 0xD2DD, 0xBA89, 0xD2DE, 0xBA8A, 0xD2DF, 0xBA8B,
+	0xD2E0, 0xBA8C, 0xD2E1, 0xBA8D, 0xD2E2, 0xBA8E, 0xD2E3, 0xBA8F,
+	0xD2E4, 0xC6BA, 0xD2E5, 0xC6BB, 0xD2E6, 0xBA90, 0xD2E7, 0xBA91,
+	0xD2E8, 0xBA92, 0xD2E9, 0xBA93, 0xD2EA, 0xBA94, 0xD2EB, 0xBA95,
+	0xD2EC, 0xBA96, 0xD2ED, 0xBA97, 0xD2EE, 0xBA98, 0xD2EF, 0xBA99,
+	0xD2F0, 0xC6BC, 0xD2F1, 0xC6BD, 0xD2F2, 0xBA9A, 0xD2F3, 0xBA9B,
+	0xD2F4, 0xC6BE, 0xD2F5, 0xBA9C, 0xD2F6, 0xBA9D, 0xD2F7, 0xBA9E,
+	0xD2F8, 0xC6BF, 0xD2F9, 0xBA9F, 0xD2FA, 0xBAA0, 0xD2FB, 0xBB41,
+	0xD2FC, 0xBB42, 0xD2FD, 0xBB43, 0xD2FE, 0xBB44, 0xD2FF, 0xBB45,
+	0xD300, 0xC6C0, 0xD301, 0xC6C1, 0xD302, 0xBB46, 0xD303, 0xC6C2,
+	0xD304, 0xBB47, 0xD305, 0xC6C3, 0xD306, 0xBB48, 0xD307, 0xBB49,
+	0xD308, 0xBB4A, 0xD309, 0xBB4B, 0xD30A, 0xBB4C, 0xD30B, 0xBB4D,
+	0xD30C, 0xC6C4, 0xD30D, 0xC6C5, 0xD30E, 0xC6C6, 0xD30F, 0xBB4E,
+	0xD310, 0xC6C7, 0xD311, 0xBB4F, 0xD312, 0xBB50, 0xD313, 0xBB51,
+	0xD314, 0xC6C8, 0xD315, 0xBB52, 0xD316, 0xC6C9, 0xD317, 0xBB53,
+	0xD318, 0xBB54, 0xD319, 0xBB55, 0xD31A, 0xBB56, 0xD31B, 0xBB57,
+	0xD31C, 0xC6CA, 0xD31D, 0xC6CB, 0xD31E, 0xBB58, 0xD31F, 0xC6CC,
+	0xD320, 0xC6CD, 0xD321, 0xC6CE, 0xD322, 0xBB59, 0xD323, 0xBB5A,
+	0xD324, 0xBB61, 0xD325, 0xC6CF, 0xD326, 0xBB62, 0xD327, 0xBB63,
+	0xD328, 0xC6D0, 0xD329, 0xC6D1, 0xD32A, 0xBB64, 0xD32B, 0xBB65,
+	0xD32C, 0xC6D2, 0xD32D, 0xBB66, 0xD32E, 0xBB67, 0xD32F, 0xBB68,
+	0xD330, 0xC6D3, 0xD331, 0xBB69, 0xD332, 0xBB6A, 0xD333, 0xBB6B,
+	0xD334, 0xBB6C, 0xD335, 0xBB6D, 0xD336, 0xBB6E, 0xD337, 0xBB6F,
+	0xD338, 0xC6D4, 0xD339, 0xC6D5, 0xD33A, 0xBB70, 0xD33B, 0xC6D6,
+	0xD33C, 0xC6D7, 0xD33D, 0xC6D8, 0xD33E, 0xBB71, 0xD33F, 0xBB72,
+	0xD340, 0xBB73, 0xD341, 0xBB74, 0xD342, 0xBB75, 0xD343, 0xBB76,
+	0xD344, 0xC6D9, 0xD345, 0xC6DA, 0xD346, 0xBB77, 0xD347, 0xBB78,
+	0xD348, 0xBB79, 0xD349, 0xBB7A, 0xD34A, 0xBB81, 0xD34B, 0xBB82,
+	0xD34C, 0xBB83, 0xD34D, 0xBB84, 0xD34E, 0xBB85, 0xD34F, 0xBB86,
+	0xD350, 0xBB87, 0xD351, 0xBB88, 0xD352, 0xBB89, 0xD353, 0xBB8A,
+	0xD354, 0xBB8B, 0xD355, 0xBB8C, 0xD356, 0xBB8D, 0xD357, 0xBB8E,
+	0xD358, 0xBB8F, 0xD359, 0xBB90, 0xD35A, 0xBB91, 0xD35B, 0xBB92,
+	0xD35C, 0xBB93, 0xD35D, 0xBB94, 0xD35E, 0xBB95, 0xD35F, 0xBB96,
+	0xD360, 0xBB97, 0xD361, 0xBB98, 0xD362, 0xBB99, 0xD363, 0xBB9A,
+	0xD364, 0xBB9B, 0xD365, 0xBB9C, 0xD366, 0xBB9D, 0xD367, 0xBB9E,
+	0xD368, 0xBB9F, 0xD369, 0xBBA0, 0xD36A, 0xBC41, 0xD36B, 0xBC42,
+	0xD36C, 0xBC43, 0xD36D, 0xBC44, 0xD36E, 0xBC45, 0xD36F, 0xBC46,
+	0xD370, 0xBC47, 0xD371, 0xBC48, 0xD372, 0xBC49, 0xD373, 0xBC4A,
+	0xD374, 0xBC4B, 0xD375, 0xBC4C, 0xD376, 0xBC4D, 0xD377, 0xBC4E,
+	0xD378, 0xBC4F, 0xD379, 0xBC50, 0xD37A, 0xBC51, 0xD37B, 0xBC52,
+	0xD37C, 0xC6DB, 0xD37D, 0xC6DC, 0xD37E, 0xBC53, 0xD37F, 0xBC54,
+	0xD380, 0xC6DD, 0xD381, 0xBC55, 0xD382, 0xBC56, 0xD383, 0xBC57,
+	0xD384, 0xC6DE, 0xD385, 0xBC58, 0xD386, 0xBC59, 0xD387, 0xBC5A,
+	0xD388, 0xBC61, 0xD389, 0xBC62, 0xD38A, 0xBC63, 0xD38B, 0xBC64,
+	0xD38C, 0xC6DF, 0xD38D, 0xC6E0, 0xD38E, 0xBC65, 0xD38F, 0xC6E1,
+	0xD390, 0xC6E2, 0xD391, 0xC6E3, 0xD392, 0xBC66, 0xD393, 0xBC67,
+	0xD394, 0xBC68, 0xD395, 0xBC69, 0xD396, 0xBC6A, 0xD397, 0xBC6B,
+	0xD398, 0xC6E4, 0xD399, 0xC6E5, 0xD39A, 0xBC6C, 0xD39B, 0xBC6D,
+	0xD39C, 0xC6E6, 0xD39D, 0xBC6E, 0xD39E, 0xBC6F, 0xD39F, 0xBC70,
+	0xD3A0, 0xC6E7, 0xD3A1, 0xBC71, 0xD3A2, 0xBC72, 0xD3A3, 0xBC73,
+	0xD3A4, 0xBC74, 0xD3A5, 0xBC75, 0xD3A6, 0xBC76, 0xD3A7, 0xBC77,
+	0xD3A8, 0xC6E8, 0xD3A9, 0xC6E9, 0xD3AA, 0xBC78, 0xD3AB, 0xC6EA,
+	0xD3AC, 0xBC79, 0xD3AD, 0xC6EB, 0xD3AE, 0xBC7A, 0xD3AF, 0xBC81,
+	0xD3B0, 0xBC82, 0xD3B1, 0xBC83, 0xD3B2, 0xBC84, 0xD3B3, 0xBC85,
+	0xD3B4, 0xC6EC, 0xD3B5, 0xBC86, 0xD3B6, 0xBC87, 0xD3B7, 0xBC88,
+	0xD3B8, 0xC6ED, 0xD3B9, 0xBC89, 0xD3BA, 0xBC8A, 0xD3BB, 0xBC8B,
+	0xD3BC, 0xC6EE, 0xD3BD, 0xBC8C, 0xD3BE, 0xBC8D, 0xD3BF, 0xBC8E,
+	0xD3C0, 0xBC8F, 0xD3C1, 0xBC90, 0xD3C2, 0xBC91, 0xD3C3, 0xBC92,
+	0xD3C4, 0xC6EF, 0xD3C5, 0xC6F0, 0xD3C6, 0xBC93, 0xD3C7, 0xBC94,
+	0xD3C8, 0xC6F1, 0xD3C9, 0xC6F2, 0xD3CA, 0xBC95, 0xD3CB, 0xBC96,
+	0xD3CC, 0xBC97, 0xD3CD, 0xBC98, 0xD3CE, 0xBC99, 0xD3CF, 0xBC9A,
+	0xD3D0, 0xC6F3, 0xD3D1, 0xBC9B, 0xD3D2, 0xBC9C, 0xD3D3, 0xBC9D,
+	0xD3D4, 0xBC9E, 0xD3D5, 0xBC9F, 0xD3D6, 0xBCA0, 0xD3D7, 0xBD41,
+	0xD3D8, 0xC6F4, 0xD3D9, 0xBD42, 0xD3DA, 0xBD43, 0xD3DB, 0xBD44,
+	0xD3DC, 0xBD45, 0xD3DD, 0xBD46, 0xD3DE, 0xBD47, 0xD3DF, 0xBD48,
+	0xD3E0, 0xBD49, 0xD3E1, 0xC6F5, 0xD3E2, 0xBD4A, 0xD3E3, 0xC6F6,
+	0xD3E4, 0xBD4B, 0xD3E5, 0xBD4C, 0xD3E6, 0xBD4D, 0xD3E7, 0xBD4E,
+	0xD3E8, 0xBD4F, 0xD3E9, 0xBD50, 0xD3EA, 0xBD51, 0xD3EB, 0xBD52,
+	0xD3EC, 0xC6F7, 0xD3ED, 0xC6F8, 0xD3EE, 0xBD53, 0xD3EF, 0xBD54,
+	0xD3F0, 0xC6F9, 0xD3F1, 0xBD55, 0xD3F2, 0xBD56, 0xD3F3, 0xBD57,
+	0xD3F4, 0xC6FA, 0xD3F5, 0xBD58, 0xD3F6, 0xBD59, 0xD3F7, 0xBD5A,
+	0xD3F8, 0xBD61, 0xD3F9, 0xBD62, 0xD3FA, 0xBD63, 0xD3FB, 0xBD64,
+	0xD3FC, 0xC6FB, 0xD3FD, 0xC6FC, 0xD3FE, 0xBD65, 0xD3FF, 0xC6FD,
+	0xD400, 0xBD66, 0xD401, 0xC6FE, 0xD402, 0xBD67, 0xD403, 0xBD68,
+	0xD404, 0xBD69, 0xD405, 0xBD6A, 0xD406, 0xBD6B, 0xD407, 0xBD6C,
+	0xD408, 0xC7A1, 0xD409, 0xBD6D, 0xD40A, 0xBD6E, 0xD40B, 0xBD6F,
+	0xD40C, 0xBD70, 0xD40D, 0xBD71, 0xD40E, 0xBD72, 0xD40F, 0xBD73,
+	0xD410, 0xBD74, 0xD411, 0xBD75, 0xD412, 0xBD76, 0xD413, 0xBD77,
+	0xD414, 0xBD78, 0xD415, 0xBD79, 0xD416, 0xBD7A, 0xD417, 0xBD81,
+	0xD418, 0xBD82, 0xD419, 0xBD83, 0xD41A, 0xBD84, 0xD41B, 0xBD85,
+	0xD41C, 0xBD86, 0xD41D, 0xC7A2, 0xD41E, 0xBD87, 0xD41F, 0xBD88,
+	0xD420, 0xBD89, 0xD421, 0xBD8A, 0xD422, 0xBD8B, 0xD423, 0xBD8C,
+	0xD424, 0xBD8D, 0xD425, 0xBD8E, 0xD426, 0xBD8F, 0xD427, 0xBD90,
+	0xD428, 0xBD91, 0xD429, 0xBD92, 0xD42A, 0xBD93, 0xD42B, 0xBD94,
+	0xD42C, 0xBD95, 0xD42D, 0xBD96, 0xD42E, 0xBD97, 0xD42F, 0xBD98,
+	0xD430, 0xBD99, 0xD431, 0xBD9A, 0xD432, 0xBD9B, 0xD433, 0xBD9C,
+	0xD434, 0xBD9D, 0xD435, 0xBD9E, 0xD436, 0xBD9F, 0xD437, 0xBDA0,
+	0xD438, 0xBE41, 0xD439, 0xBE42, 0xD43A, 0xBE43, 0xD43B, 0xBE44,
+	0xD43C, 0xBE45, 0xD43D, 0xBE46, 0xD43E, 0xBE47, 0xD43F, 0xBE48,
+	0xD440, 0xC7A3, 0xD441, 0xBE49, 0xD442, 0xBE4A, 0xD443, 0xBE4B,
+	0xD444, 0xC7A4, 0xD445, 0xBE4C, 0xD446, 0xBE4D, 0xD447, 0xBE4E,
+	0xD448, 0xBE4F, 0xD449, 0xBE50, 0xD44A, 0xBE51, 0xD44B, 0xBE52,
+	0xD44C, 0xBE53, 0xD44D, 0xBE54, 0xD44E, 0xBE55, 0xD44F, 0xBE56,
+	0xD450, 0xBE57, 0xD451, 0xBE58, 0xD452, 0xBE59, 0xD453, 0xBE5A,
+	0xD454, 0xBE61, 0xD455, 0xBE62, 0xD456, 0xBE63, 0xD457, 0xBE64,
+	0xD458, 0xBE65, 0xD459, 0xBE66, 0xD45A, 0xBE67, 0xD45B, 0xBE68,
+	0xD45C, 0xC7A5, 0xD45D, 0xBE69, 0xD45E, 0xBE6A, 0xD45F, 0xBE6B,
+	0xD460, 0xC7A6, 0xD461, 0xBE6C, 0xD462, 0xBE6D, 0xD463, 0xBE6E,
+	0xD464, 0xC7A7, 0xD465, 0xBE6F, 0xD466, 0xBE70, 0xD467, 0xBE71,
+	0xD468, 0xBE72, 0xD469, 0xBE73, 0xD46A, 0xBE74, 0xD46B, 0xBE75,
+	0xD46C, 0xBE76, 0xD46D, 0xC7A8, 0xD46E, 0xBE77, 0xD46F, 0xC7A9,
+	0xD470, 0xBE78, 0xD471, 0xBE79, 0xD472, 0xBE7A, 0xD473, 0xBE81,
+	0xD474, 0xBE82, 0xD475, 0xBE83, 0xD476, 0xBE84, 0xD477, 0xBE85,
+	0xD478, 0xC7AA, 0xD479, 0xC7AB, 0xD47A, 0xBE86, 0xD47B, 0xBE87,
+	0xD47C, 0xC7AC, 0xD47D, 0xBE88, 0xD47E, 0xBE89, 0xD47F, 0xC7AD,
+	0xD480, 0xC7AE, 0xD481, 0xBE8A, 0xD482, 0xC7AF, 0xD483, 0xBE8B,
+	0xD484, 0xBE8C, 0xD485, 0xBE8D, 0xD486, 0xBE8E, 0xD487, 0xBE8F,
+	0xD488, 0xC7B0, 0xD489, 0xC7B1, 0xD48A, 0xBE90, 0xD48B, 0xC7B2,
+	0xD48C, 0xBE91, 0xD48D, 0xC7B3, 0xD48E, 0xBE92, 0xD48F, 0xBE93,
+	0xD490, 0xBE94, 0xD491, 0xBE95, 0xD492, 0xBE96, 0xD493, 0xBE97,
+	0xD494, 0xC7B4, 0xD495, 0xBE98, 0xD496, 0xBE99, 0xD497, 0xBE9A,
+	0xD498, 0xBE9B, 0xD499, 0xBE9C, 0xD49A, 0xBE9D, 0xD49B, 0xBE9E,
+	0xD49C, 0xBE9F, 0xD49D, 0xBEA0, 0xD49E, 0xBF41, 0xD49F, 0xBF42,
+	0xD4A0, 0xBF43, 0xD4A1, 0xBF44, 0xD4A2, 0xBF45, 0xD4A3, 0xBF46,
+	0xD4A4, 0xBF47, 0xD4A5, 0xBF48, 0xD4A6, 0xBF49, 0xD4A7, 0xBF4A,
+	0xD4A8, 0xBF4B, 0xD4A9, 0xC7B5, 0xD4AA, 0xBF4C, 0xD4AB, 0xBF4D,
+	0xD4AC, 0xBF4E, 0xD4AD, 0xBF4F, 0xD4AE, 0xBF50, 0xD4AF, 0xBF51,
+	0xD4B0, 0xBF52, 0xD4B1, 0xBF53, 0xD4B2, 0xBF54, 0xD4B3, 0xBF55,
+	0xD4B4, 0xBF56, 0xD4B5, 0xBF57, 0xD4B6, 0xBF58, 0xD4B7, 0xBF59,
+	0xD4B8, 0xBF5A, 0xD4B9, 0xBF61, 0xD4BA, 0xBF62, 0xD4BB, 0xBF63,
+	0xD4BC, 0xBF64, 0xD4BD, 0xBF65, 0xD4BE, 0xBF66, 0xD4BF, 0xBF67,
+	0xD4C0, 0xBF68, 0xD4C1, 0xBF69, 0xD4C2, 0xBF6A, 0xD4C3, 0xBF6B,
+	0xD4C4, 0xBF6C, 0xD4C5, 0xBF6D, 0xD4C6, 0xBF6E, 0xD4C7, 0xBF6F,
+	0xD4C8, 0xBF70, 0xD4C9, 0xBF71, 0xD4CA, 0xBF72, 0xD4CB, 0xBF73,
+	0xD4CC, 0xC7B6, 0xD4CD, 0xBF74, 0xD4CE, 0xBF75, 0xD4CF, 0xBF76,
+	0xD4D0, 0xC7B7, 0xD4D1, 0xBF77, 0xD4D2, 0xBF78, 0xD4D3, 0xBF79,
+	0xD4D4, 0xC7B8, 0xD4D5, 0xBF7A, 0xD4D6, 0xBF81, 0xD4D7, 0xBF82,
+	0xD4D8, 0xBF83, 0xD4D9, 0xBF84, 0xD4DA, 0xBF85, 0xD4DB, 0xBF86,
+	0xD4DC, 0xC7B9, 0xD4DD, 0xBF87, 0xD4DE, 0xBF88, 0xD4DF, 0xC7BA,
+	0xD4E0, 0xBF89, 0xD4E1, 0xBF8A, 0xD4E2, 0xBF8B, 0xD4E3, 0xBF8C,
+	0xD4E4, 0xBF8D, 0xD4E5, 0xBF8E, 0xD4E6, 0xBF8F, 0xD4E7, 0xBF90,
+	0xD4E8, 0xC7BB, 0xD4E9, 0xBF91, 0xD4EA, 0xBF92, 0xD4EB, 0xBF93,
+	0xD4EC, 0xC7BC, 0xD4ED, 0xBF94, 0xD4EE, 0xBF95, 0xD4EF, 0xBF96,
+	0xD4F0, 0xC7BD, 0xD4F1, 0xBF97, 0xD4F2, 0xBF98, 0xD4F3, 0xBF99,
+	0xD4F4, 0xBF9A, 0xD4F5, 0xBF9B, 0xD4F6, 0xBF9C, 0xD4F7, 0xBF9D,
+	0xD4F8, 0xC7BE, 0xD4F9, 0xBF9E, 0xD4FA, 0xBF9F, 0xD4FB, 0xC7BF,
+	0xD4FC, 0xBFA0, 0xD4FD, 0xC7C0, 0xD4FE, 0xC041, 0xD4FF, 0xC042,
+	0xD500, 0xC043, 0xD501, 0xC044, 0xD502, 0xC045, 0xD503, 0xC046,
+	0xD504, 0xC7C1, 0xD505, 0xC047, 0xD506, 0xC048, 0xD507, 0xC049,
+	0xD508, 0xC7C2, 0xD509, 0xC04A, 0xD50A, 0xC04B, 0xD50B, 0xC04C,
+	0xD50C, 0xC7C3, 0xD50D, 0xC04D, 0xD50E, 0xC04E, 0xD50F, 0xC04F,
+	0xD510, 0xC050, 0xD511, 0xC051, 0xD512, 0xC052, 0xD513, 0xC053,
+	0xD514, 0xC7C4, 0xD515, 0xC7C5, 0xD516, 0xC054, 0xD517, 0xC7C6,
+	0xD518, 0xC055, 0xD519, 0xC056, 0xD51A, 0xC057, 0xD51B, 0xC058,
+	0xD51C, 0xC059, 0xD51D, 0xC05A, 0xD51E, 0xC061, 0xD51F, 0xC062,
+	0xD520, 0xC063, 0xD521, 0xC064, 0xD522, 0xC065, 0xD523, 0xC066,
+	0xD524, 0xC067, 0xD525, 0xC068, 0xD526, 0xC069, 0xD527, 0xC06A,
+	0xD528, 0xC06B, 0xD529, 0xC06C, 0xD52A, 0xC06D, 0xD52B, 0xC06E,
+	0xD52C, 0xC06F, 0xD52D, 0xC070, 0xD52E, 0xC071, 0xD52F, 0xC072,
+	0xD530, 0xC073, 0xD531, 0xC074, 0xD532, 0xC075, 0xD533, 0xC076,
+	0xD534, 0xC077, 0xD535, 0xC078, 0xD536, 0xC079, 0xD537, 0xC07A,
+	0xD538, 0xC081, 0xD539, 0xC082, 0xD53A, 0xC083, 0xD53B, 0xC084,
+	0xD53C, 0xC7C7, 0xD53D, 0xC7C8, 0xD53E, 0xC085, 0xD53F, 0xC086,
+	0xD540, 0xC7C9, 0xD541, 0xC087, 0xD542, 0xC088, 0xD543, 0xC089,
+	0xD544, 0xC7CA, 0xD545, 0xC08A, 0xD546, 0xC08B, 0xD547, 0xC08C,
+	0xD548, 0xC08D, 0xD549, 0xC08E, 0xD54A, 0xC08F, 0xD54B, 0xC090,
+	0xD54C, 0xC7CB, 0xD54D, 0xC7CC, 0xD54E, 0xC091, 0xD54F, 0xC7CD,
+	0xD550, 0xC092, 0xD551, 0xC7CE, 0xD552, 0xC093, 0xD553, 0xC094,
+	0xD554, 0xC095, 0xD555, 0xC096, 0xD556, 0xC097, 0xD557, 0xC098,
+	0xD558, 0xC7CF, 0xD559, 0xC7D0, 0xD55A, 0xC099, 0xD55B, 0xC09A,
+	0xD55C, 0xC7D1, 0xD55D, 0xC09B, 0xD55E, 0xC09C, 0xD55F, 0xC09D,
+	0xD560, 0xC7D2, 0xD561, 0xC09E, 0xD562, 0xC09F, 0xD563, 0xC0A0,
+	0xD564, 0xC141, 0xD565, 0xC7D3, 0xD566, 0xC142, 0xD567, 0xC143,
+	0xD568, 0xC7D4, 0xD569, 0xC7D5, 0xD56A, 0xC144, 0xD56B, 0xC7D6,
+	0xD56C, 0xC145, 0xD56D, 0xC7D7, 0xD56E, 0xC146, 0xD56F, 0xC147,
+	0xD570, 0xC148, 0xD571, 0xC149, 0xD572, 0xC14A, 0xD573, 0xC14B,
+	0xD574, 0xC7D8, 0xD575, 0xC7D9, 0xD576, 0xC14C, 0xD577, 0xC14D,
+	0xD578, 0xC7DA, 0xD579, 0xC14E, 0xD57A, 0xC14F, 0xD57B, 0xC150,
+	0xD57C, 0xC7DB, 0xD57D, 0xC151, 0xD57E, 0xC152, 0xD57F, 0xC153,
+	0xD580, 0xC154, 0xD581, 0xC155, 0xD582, 0xC156, 0xD583, 0xC157,
+	0xD584, 0xC7DC, 0xD585, 0xC7DD, 0xD586, 0xC158, 0xD587, 0xC7DE,
+	0xD588, 0xC7DF, 0xD589, 0xC7E0, 0xD58A, 0xC159, 0xD58B, 0xC15A,
+	0xD58C, 0xC161, 0xD58D, 0xC162, 0xD58E, 0xC163, 0xD58F, 0xC164,
+	0xD590, 0xC7E1, 0xD591, 0xC165, 0xD592, 0xC166, 0xD593, 0xC167,
+	0xD594, 0xC168, 0xD595, 0xC169, 0xD596, 0xC16A, 0xD597, 0xC16B,
+	0xD598, 0xC16C, 0xD599, 0xC16D, 0xD59A, 0xC16E, 0xD59B, 0xC16F,
+	0xD59C, 0xC170, 0xD59D, 0xC171, 0xD59E, 0xC172, 0xD59F, 0xC173,
+	0xD5A0, 0xC174, 0xD5A1, 0xC175, 0xD5A2, 0xC176, 0xD5A3, 0xC177,
+	0xD5A4, 0xC178, 0xD5A5, 0xC7E2, 0xD5A6, 0xC179, 0xD5A7, 0xC17A,
+	0xD5A8, 0xC181, 0xD5A9, 0xC182, 0xD5AA, 0xC183, 0xD5AB, 0xC184,
+	0xD5AC, 0xC185, 0xD5AD, 0xC186, 0xD5AE, 0xC187, 0xD5AF, 0xC188,
+	0xD5B0, 0xC189, 0xD5B1, 0xC18A, 0xD5B2, 0xC18B, 0xD5B3, 0xC18C,
+	0xD5B4, 0xC18D, 0xD5B5, 0xC18E, 0xD5B6, 0xC18F, 0xD5B7, 0xC190,
+	0xD5B8, 0xC191, 0xD5B9, 0xC192, 0xD5BA, 0xC193, 0xD5BB, 0xC194,
+	0xD5BC, 0xC195, 0xD5BD, 0xC196, 0xD5BE, 0xC197, 0xD5BF, 0xC198,
+	0xD5C0, 0xC199, 0xD5C1, 0xC19A, 0xD5C2, 0xC19B, 0xD5C3, 0xC19C,
+	0xD5C4, 0xC19D, 0xD5C5, 0xC19E, 0xD5C6, 0xC19F, 0xD5C7, 0xC1A0,
+	0xD5C8, 0xC7E3, 0xD5C9, 0xC7E4, 0xD5CA, 0xC241, 0xD5CB, 0xC242,
+	0xD5CC, 0xC7E5, 0xD5CD, 0xC243, 0xD5CE, 0xC244, 0xD5CF, 0xC245,
+	0xD5D0, 0xC7E6, 0xD5D1, 0xC246, 0xD5D2, 0xC7E7, 0xD5D3, 0xC247,
+	0xD5D4, 0xC248, 0xD5D5, 0xC249, 0xD5D6, 0xC24A, 0xD5D7, 0xC24B,
+	0xD5D8, 0xC7E8, 0xD5D9, 0xC7E9, 0xD5DA, 0xC24C, 0xD5DB, 0xC7EA,
+	0xD5DC, 0xC24D, 0xD5DD, 0xC7EB, 0xD5DE, 0xC24E, 0xD5DF, 0xC24F,
+	0xD5E0, 0xC250, 0xD5E1, 0xC251, 0xD5E2, 0xC252, 0xD5E3, 0xC253,
+	0xD5E4, 0xC7EC, 0xD5E5, 0xC7ED, 0xD5E6, 0xC254, 0xD5E7, 0xC255,
+	0xD5E8, 0xC7EE, 0xD5E9, 0xC256, 0xD5EA, 0xC257, 0xD5EB, 0xC258,
+	0xD5EC, 0xC7EF, 0xD5ED, 0xC259, 0xD5EE, 0xC25A, 0xD5EF, 0xC261,
+	0xD5F0, 0xC262, 0xD5F1, 0xC263, 0xD5F2, 0xC264, 0xD5F3, 0xC265,
+	0xD5F4, 0xC7F0, 0xD5F5, 0xC7F1, 0xD5F6, 0xC266, 0xD5F7, 0xC7F2,
+	0xD5F8, 0xC267, 0xD5F9, 0xC7F3, 0xD5FA, 0xC268, 0xD5FB, 0xC269,
+	0xD5FC, 0xC26A, 0xD5FD, 0xC26B, 0xD5FE, 0xC26C, 0xD5FF, 0xC26D,
+	0xD600, 0xC7F4, 0xD601, 0xC7F5, 0xD602, 0xC26E, 0xD603, 0xC26F,
+	0xD604, 0xC7F6, 0xD605, 0xC270, 0xD606, 0xC271, 0xD607, 0xC272,
+	0xD608, 0xC7F7, 0xD609, 0xC273, 0xD60A, 0xC274, 0xD60B, 0xC275,
+	0xD60C, 0xC276, 0xD60D, 0xC277, 0xD60E, 0xC278, 0xD60F, 0xC279,
+	0xD610, 0xC7F8, 0xD611, 0xC7F9, 0xD612, 0xC27A, 0xD613, 0xC7FA,
+	0xD614, 0xC7FB, 0xD615, 0xC7FC, 0xD616, 0xC281, 0xD617, 0xC282,
+	0xD618, 0xC283, 0xD619, 0xC284, 0xD61A, 0xC285, 0xD61B, 0xC286,
+	0xD61C, 0xC7FD, 0xD61D, 0xC287, 0xD61E, 0xC288, 0xD61F, 0xC289,
+	0xD620, 0xC7FE, 0xD621, 0xC28A, 0xD622, 0xC28B, 0xD623, 0xC28C,
+	0xD624, 0xC8A1, 0xD625, 0xC28D, 0xD626, 0xC28E, 0xD627, 0xC28F,
+	0xD628, 0xC290, 0xD629, 0xC291, 0xD62A, 0xC292, 0xD62B, 0xC293,
+	0xD62C, 0xC294, 0xD62D, 0xC8A2, 0xD62E, 0xC295, 0xD62F, 0xC296,
+	0xD630, 0xC297, 0xD631, 0xC298, 0xD632, 0xC299, 0xD633, 0xC29A,
+	0xD634, 0xC29B, 0xD635, 0xC29C, 0xD636, 0xC29D, 0xD637, 0xC29E,
+	0xD638, 0xC8A3, 0xD639, 0xC8A4, 0xD63A, 0xC29F, 0xD63B, 0xC2A0,
+	0xD63C, 0xC8A5, 0xD63D, 0xC341, 0xD63E, 0xC342, 0xD63F, 0xC343,
+	0xD640, 0xC8A6, 0xD641, 0xC344, 0xD642, 0xC345, 0xD643, 0xC346,
+	0xD644, 0xC347, 0xD645, 0xC8A7, 0xD646, 0xC348, 0xD647, 0xC349,
+	0xD648, 0xC8A8, 0xD649, 0xC8A9, 0xD64A, 0xC34A, 0xD64B, 0xC8AA,
+	0xD64C, 0xC34B, 0xD64D, 0xC8AB, 0xD64E, 0xC34C, 0xD64F, 0xC34D,
+	0xD650, 0xC34E, 0xD651, 0xC8AC, 0xD652, 0xC34F, 0xD653, 0xC350,
+	0xD654, 0xC8AD, 0xD655, 0xC8AE, 0xD656, 0xC351, 0xD657, 0xC352,
+	0xD658, 0xC8AF, 0xD659, 0xC353, 0xD65A, 0xC354, 0xD65B, 0xC355,
+	0xD65C, 0xC8B0, 0xD65D, 0xC356, 0xD65E, 0xC357, 0xD65F, 0xC358,
+	0xD660, 0xC359, 0xD661, 0xC35A, 0xD662, 0xC361, 0xD663, 0xC362,
+	0xD664, 0xC363, 0xD665, 0xC364, 0xD666, 0xC365, 0xD667, 0xC8B1,
+	0xD668, 0xC366, 0xD669, 0xC8B2, 0xD66A, 0xC367, 0xD66B, 0xC368,
+	0xD66C, 0xC369, 0xD66D, 0xC36A, 0xD66E, 0xC36B, 0xD66F, 0xC36C,
+	0xD670, 0xC8B3, 0xD671, 0xC8B4, 0xD672, 0xC36D, 0xD673, 0xC36E,
+	0xD674, 0xC8B5, 0xD675, 0xC36F, 0xD676, 0xC370, 0xD677, 0xC371,
+	0xD678, 0xC372, 0xD679, 0xC373, 0xD67A, 0xC374, 0xD67B, 0xC375,
+	0xD67C, 0xC376, 0xD67D, 0xC377, 0xD67E, 0xC378, 0xD67F, 0xC379,
+	0xD680, 0xC37A, 0xD681, 0xC381, 0xD682, 0xC382, 0xD683, 0xC8B6,
+	0xD684, 0xC383, 0xD685, 0xC8B7, 0xD686, 0xC384, 0xD687, 0xC385,
+	0xD688, 0xC386, 0xD689, 0xC387, 0xD68A, 0xC388, 0xD68B, 0xC389,
+	0xD68C, 0xC8B8, 0xD68D, 0xC8B9, 0xD68E, 0xC38A, 0xD68F, 0xC38B,
+	0xD690, 0xC8BA, 0xD691, 0xC38C, 0xD692, 0xC38D, 0xD693, 0xC38E,
+	0xD694, 0xC8BB, 0xD695, 0xC38F, 0xD696, 0xC390, 0xD697, 0xC391,
+	0xD698, 0xC392, 0xD699, 0xC393, 0xD69A, 0xC394, 0xD69B, 0xC395,
+	0xD69C, 0xC396, 0xD69D, 0xC8BC, 0xD69E, 0xC397, 0xD69F, 0xC8BD,
+	0xD6A0, 0xC398, 0xD6A1, 0xC8BE, 0xD6A2, 0xC399, 0xD6A3, 0xC39A,
+	0xD6A4, 0xC39B, 0xD6A5, 0xC39C, 0xD6A6, 0xC39D, 0xD6A7, 0xC39E,
+	0xD6A8, 0xC8BF, 0xD6A9, 0xC39F, 0xD6AA, 0xC3A0, 0xD6AB, 0xC441,
+	0xD6AC, 0xC8C0, 0xD6AD, 0xC442, 0xD6AE, 0xC443, 0xD6AF, 0xC444,
+	0xD6B0, 0xC8C1, 0xD6B1, 0xC445, 0xD6B2, 0xC446, 0xD6B3, 0xC447,
+	0xD6B4, 0xC448, 0xD6B5, 0xC449, 0xD6B6, 0xC44A, 0xD6B7, 0xC44B,
+	0xD6B8, 0xC44C, 0xD6B9, 0xC8C2, 0xD6BA, 0xC44D, 0xD6BB, 0xC8C3,
+	0xD6BC, 0xC44E, 0xD6BD, 0xC44F, 0xD6BE, 0xC450, 0xD6BF, 0xC451,
+	0xD6C0, 0xC452, 0xD6C1, 0xC453, 0xD6C2, 0xC454, 0xD6C3, 0xC455,
+	0xD6C4, 0xC8C4, 0xD6C5, 0xC8C5, 0xD6C6, 0xC456, 0xD6C7, 0xC457,
+	0xD6C8, 0xC8C6, 0xD6C9, 0xC458, 0xD6CA, 0xC459, 0xD6CB, 0xC45A,
+	0xD6CC, 0xC8C7, 0xD6CD, 0xC461, 0xD6CE, 0xC462, 0xD6CF, 0xC463,
+	0xD6D0, 0xC464, 0xD6D1, 0xC8C8, 0xD6D2, 0xC465, 0xD6D3, 0xC466,
+	0xD6D4, 0xC8C9, 0xD6D5, 0xC467, 0xD6D6, 0xC468, 0xD6D7, 0xC8CA,
+	0xD6D8, 0xC469, 0xD6D9, 0xC8CB, 0xD6DA, 0xC46A, 0xD6DB, 0xC46B,
+	0xD6DC, 0xC46C, 0xD6DD, 0xC46D, 0xD6DE, 0xC46E, 0xD6DF, 0xC46F,
+	0xD6E0, 0xC8CC, 0xD6E1, 0xC470, 0xD6E2, 0xC471, 0xD6E3, 0xC472,
+	0xD6E4, 0xC8CD, 0xD6E5, 0xC473, 0xD6E6, 0xC474, 0xD6E7, 0xC475,
+	0xD6E8, 0xC8CE, 0xD6E9, 0xC476, 0xD6EA, 0xC477, 0xD6EB, 0xC478,
+	0xD6EC, 0xC479, 0xD6ED, 0xC47A, 0xD6EE, 0xC481, 0xD6EF, 0xC482,
+	0xD6F0, 0xC8CF, 0xD6F1, 0xC483, 0xD6F2, 0xC484, 0xD6F3, 0xC485,
+	0xD6F4, 0xC486, 0xD6F5, 0xC8D0, 0xD6F6, 0xC487, 0xD6F7, 0xC488,
+	0xD6F8, 0xC489, 0xD6F9, 0xC48A, 0xD6FA, 0xC48B, 0xD6FB, 0xC48C,
+	0xD6FC, 0xC8D1, 0xD6FD, 0xC8D2, 0xD6FE, 0xC48D, 0xD6FF, 0xC48E,
+	0xD700, 0xC8D3, 0xD701, 0xC48F, 0xD702, 0xC490, 0xD703, 0xC491,
+	0xD704, 0xC8D4, 0xD705, 0xC492, 0xD706, 0xC493, 0xD707, 0xC494,
+	0xD708, 0xC495, 0xD709, 0xC496, 0xD70A, 0xC497, 0xD70B, 0xC498,
+	0xD70C, 0xC499, 0xD70D, 0xC49A, 0xD70E, 0xC49B, 0xD70F, 0xC49C,
+	0xD710, 0xC49D, 0xD711, 0xC8D5, 0xD712, 0xC49E, 0xD713, 0xC49F,
+	0xD714, 0xC4A0, 0xD715, 0xC541, 0xD716, 0xC542, 0xD717, 0xC543,
+	0xD718, 0xC8D6, 0xD719, 0xC8D7, 0xD71A, 0xC544, 0xD71B, 0xC545,
+	0xD71C, 0xC8D8, 0xD71D, 0xC546, 0xD71E, 0xC547, 0xD71F, 0xC548,
+	0xD720, 0xC8D9, 0xD721, 0xC549, 0xD722, 0xC54A, 0xD723, 0xC54B,
+	0xD724, 0xC54C, 0xD725, 0xC54D, 0xD726, 0xC54E, 0xD727, 0xC54F,
+	0xD728, 0xC8DA, 0xD729, 0xC8DB, 0xD72A, 0xC550, 0xD72B, 0xC8DC,
+	0xD72C, 0xC551, 0xD72D, 0xC8DD, 0xD72E, 0xC552, 0xD72F, 0xC553,
+	0xD730, 0xC554, 0xD731, 0xC555, 0xD732, 0xC556, 0xD733, 0xC557,
+	0xD734, 0xC8DE, 0xD735, 0xC8DF, 0xD736, 0xC558, 0xD737, 0xC559,
+	0xD738, 0xC8E0, 0xD739, 0xC55A, 0xD73A, 0xC561, 0xD73B, 0xC562,
+	0xD73C, 0xC8E1, 0xD73D, 0xC563, 0xD73E, 0xC564, 0xD73F, 0xC565,
+	0xD740, 0xC566, 0xD741, 0xC567, 0xD742, 0xC568, 0xD743, 0xC569,
+	0xD744, 0xC8E2, 0xD745, 0xC56A, 0xD746, 0xC56B, 0xD747, 0xC8E3,
+	0xD748, 0xC56C, 0xD749, 0xC8E4, 0xD74A, 0xC56D, 0xD74B, 0xC56E,
+	0xD74C, 0xC56F, 0xD74D, 0xC570, 0xD74E, 0xC571, 0xD74F, 0xC572,
+	0xD750, 0xC8E5, 0xD751, 0xC8E6, 0xD752, 0xC573, 0xD753, 0xC574,
+	0xD754, 0xC8E7, 0xD755, 0xC575, 0xD756, 0xC8E8, 0xD757, 0xC8E9,
+	0xD758, 0xC8EA, 0xD759, 0xC8EB, 0xD75A, 0xC576, 0xD75B, 0xC577,
+	0xD75C, 0xC578, 0xD75D, 0xC579, 0xD75E, 0xC57A, 0xD75F, 0xC581,
+	0xD760, 0xC8EC, 0xD761, 0xC8ED, 0xD762, 0xC582, 0xD763, 0xC8EE,
+	0xD764, 0xC583, 0xD765, 0xC8EF, 0xD766, 0xC584, 0xD767, 0xC585,
+	0xD768, 0xC586, 0xD769, 0xC8F0, 0xD76A, 0xC587, 0xD76B, 0xC588,
+	0xD76C, 0xC8F1, 0xD76D, 0xC589, 0xD76E, 0xC58A, 0xD76F, 0xC58B,
+	0xD770, 0xC8F2, 0xD771, 0xC58C, 0xD772, 0xC58D, 0xD773, 0xC58E,
+	0xD774, 0xC8F3, 0xD775, 0xC58F, 0xD776, 0xC590, 0xD777, 0xC591,
+	0xD778, 0xC592, 0xD779, 0xC593, 0xD77A, 0xC594, 0xD77B, 0xC595,
+	0xD77C, 0xC8F4, 0xD77D, 0xC8F5, 0xD77E, 0xC596, 0xD77F, 0xC597,
+	0xD780, 0xC598, 0xD781, 0xC8F6, 0xD782, 0xC599, 0xD783, 0xC59A,
+	0xD784, 0xC59B, 0xD785, 0xC59C, 0xD786, 0xC59D, 0xD787, 0xC59E,
+	0xD788, 0xC8F7, 0xD789, 0xC8F8, 0xD78A, 0xC59F, 0xD78B, 0xC5A0,
+	0xD78C, 0xC8F9, 0xD78D, 0xC641, 0xD78E, 0xC642, 0xD78F, 0xC643,
+	0xD790, 0xC8FA, 0xD791, 0xC644, 0xD792, 0xC645, 0xD793, 0xC646,
+	0xD794, 0xC647, 0xD795, 0xC648, 0xD796, 0xC649, 0xD797, 0xC64A,
+	0xD798, 0xC8FB, 0xD799, 0xC8FC, 0xD79A, 0xC64B, 0xD79B, 0xC8FD,
+	0xD79C, 0xC64C, 0xD79D, 0xC8FE, 0xD79E, 0xC64D, 0xD79F, 0xC64E,
+	0xD7A0, 0xC64F, 0xD7A1, 0xC650, 0xD7A2, 0xC651, 0xD7A3, 0xC652,
+	0xF900, 0xCBD0, 0xF901, 0xCBD6, 0xF902, 0xCBE7, 0xF903, 0xCDCF,
+	0xF904, 0xCDE8, 0xF905, 0xCEAD, 0xF906, 0xCFFB, 0xF907, 0xD0A2,
+	0xF908, 0xD0B8, 0xF909, 0xD0D0, 0xF90A, 0xD0DD, 0xF90B, 0xD1D4,
+	0xF90C, 0xD1D5, 0xF90D, 0xD1D8, 0xF90E, 0xD1DB, 0xF90F, 0xD1DC,
+	0xF910, 0xD1DD, 0xF911, 0xD1DE, 0xF912, 0xD1DF, 0xF913, 0xD1E0,
+	0xF914, 0xD1E2, 0xF915, 0xD1E3, 0xF916, 0xD1E4, 0xF917, 0xD1E5,
+	0xF918, 0xD1E6, 0xF919, 0xD1E8, 0xF91A, 0xD1E9, 0xF91B, 0xD1EA,
+	0xF91C, 0xD1EB, 0xF91D, 0xD1ED, 0xF91E, 0xD1EF, 0xF91F, 0xD1F0,
+	0xF920, 0xD1F2, 0xF921, 0xD1F6, 0xF922, 0xD1FA, 0xF923, 0xD1FC,
+	0xF924, 0xD1FD, 0xF925, 0xD1FE, 0xF926, 0xD2A2, 0xF927, 0xD2A3,
+	0xF928, 0xD2A7, 0xF929, 0xD2A8, 0xF92A, 0xD2A9, 0xF92B, 0xD2AA,
+	0xF92C, 0xD2AB, 0xF92D, 0xD2AD, 0xF92E, 0xD2B2, 0xF92F, 0xD2BE,
+	0xF930, 0xD2C2, 0xF931, 0xD2C3, 0xF932, 0xD2C4, 0xF933, 0xD2C6,
+	0xF934, 0xD2C7, 0xF935, 0xD2C8, 0xF936, 0xD2C9, 0xF937, 0xD2CA,
+	0xF938, 0xD2CB, 0xF939, 0xD2CD, 0xF93A, 0xD2CE, 0xF93B, 0xD2CF,
+	0xF93C, 0xD2D0, 0xF93D, 0xD2D1, 0xF93E, 0xD2D2, 0xF93F, 0xD2D3,
+	0xF940, 0xD2D4, 0xF941, 0xD2D5, 0xF942, 0xD2D6, 0xF943, 0xD2D7,
+	0xF944, 0xD2D9, 0xF945, 0xD2DA, 0xF946, 0xD2DE, 0xF947, 0xD2DF,
+	0xF948, 0xD2E1, 0xF949, 0xD2E2, 0xF94A, 0xD2E4, 0xF94B, 0xD2E5,
+	0xF94C, 0xD2E6, 0xF94D, 0xD2E7, 0xF94E, 0xD2E8, 0xF94F, 0xD2E9,
+	0xF950, 0xD2EA, 0xF951, 0xD2EB, 0xF952, 0xD2F0, 0xF953, 0xD2F1,
+	0xF954, 0xD2F2, 0xF955, 0xD2F3, 0xF956, 0xD2F4, 0xF957, 0xD2F5,
+	0xF958, 0xD2F7, 0xF959, 0xD2F8, 0xF95A, 0xD4E6, 0xF95B, 0xD4FC,
+	0xF95C, 0xD5A5, 0xF95D, 0xD5AB, 0xF95E, 0xD5AE, 0xF95F, 0xD6B8,
+	0xF960, 0xD6CD, 0xF961, 0xD7CB, 0xF962, 0xD7E4, 0xF963, 0xDBC5,
+	0xF964, 0xDBE4, 0xF965, 0xDCA5, 0xF966, 0xDDA5, 0xF967, 0xDDD5,
+	0xF968, 0xDDF4, 0xF969, 0xDEFC, 0xF96A, 0xDEFE, 0xF96B, 0xDFB3,
+	0xF96C, 0xDFE1, 0xF96D, 0xDFE8, 0xF96E, 0xE0F1, 0xF96F, 0xE1AD,
+	0xF970, 0xE1ED, 0xF971, 0xE3F5, 0xF972, 0xE4A1, 0xF973, 0xE4A9,
+	0xF974, 0xE5AE, 0xF975, 0xE5B1, 0xF976, 0xE5B2, 0xF977, 0xE5B9,
+	0xF978, 0xE5BB, 0xF979, 0xE5BC, 0xF97A, 0xE5C4, 0xF97B, 0xE5CE,
+	0xF97C, 0xE5D0, 0xF97D, 0xE5D2, 0xF97E, 0xE5D6, 0xF97F, 0xE5FA,
+	0xF980, 0xE5FB, 0xF981, 0xE5FC, 0xF982, 0xE5FE, 0xF983, 0xE6A1,
+	0xF984, 0xE6A4, 0xF985, 0xE6A7, 0xF986, 0xE6AD, 0xF987, 0xE6AF,
+	0xF988, 0xE6B0, 0xF989, 0xE6B1, 0xF98A, 0xE6B3, 0xF98B, 0xE6B7,
+	0xF98C, 0xE6B8, 0xF98D, 0xE6BC, 0xF98E, 0xE6C4, 0xF98F, 0xE6C6,
+	0xF990, 0xE6C7, 0xF991, 0xE6CA, 0xF992, 0xE6D2, 0xF993, 0xE6D6,
+	0xF994, 0xE6D9, 0xF995, 0xE6DC, 0xF996, 0xE6DF, 0xF997, 0xE6E1,
+	0xF998, 0xE6E4, 0xF999, 0xE6E5, 0xF99A, 0xE6E6, 0xF99B, 0xE6E8,
+	0xF99C, 0xE6EA, 0xF99D, 0xE6EB, 0xF99E, 0xE6EC, 0xF99F, 0xE6EF,
+	0xF9A0, 0xE6F1, 0xF9A1, 0xE6F2, 0xF9A2, 0xE6F5, 0xF9A3, 0xE6F6,
+	0xF9A4, 0xE6F7, 0xF9A5, 0xE6F9, 0xF9A6, 0xE7A1, 0xF9A7, 0xE7A6,
+	0xF9A8, 0xE7A9, 0xF9A9, 0xE7AA, 0xF9AA, 0xE7AC, 0xF9AB, 0xE7AD,
+	0xF9AC, 0xE7B0, 0xF9AD, 0xE7BF, 0xF9AE, 0xE7C1, 0xF9AF, 0xE7C6,
+	0xF9B0, 0xE7C7, 0xF9B1, 0xE7CB, 0xF9B2, 0xE7CD, 0xF9B3, 0xE7CF,
+	0xF9B4, 0xE7D0, 0xF9B5, 0xE7D3, 0xF9B6, 0xE7DF, 0xF9B7, 0xE7E4,
+	0xF9B8, 0xE7E6, 0xF9B9, 0xE7F7, 0xF9BA, 0xE8E7, 0xF9BB, 0xE8E8,
+	0xF9BC, 0xE8F0, 0xF9BD, 0xE8F1, 0xF9BE, 0xE8F7, 0xF9BF, 0xE8F9,
+	0xF9C0, 0xE8FB, 0xF9C1, 0xE8FE, 0xF9C2, 0xE9A7, 0xF9C3, 0xE9AC,
+	0xF9C4, 0xE9CC, 0xF9C5, 0xE9F7, 0xF9C6, 0xEAC1, 0xF9C7, 0xEAE5,
+	0xF9C8, 0xEAF4, 0xF9C9, 0xEAF7, 0xF9CA, 0xEAFC, 0xF9CB, 0xEAFE,
+	0xF9CC, 0xEBA4, 0xF9CD, 0xEBA7, 0xF9CE, 0xEBA9, 0xF9CF, 0xEBAA,
+	0xF9D0, 0xEBBA, 0xF9D1, 0xEBBB, 0xF9D2, 0xEBBD, 0xF9D3, 0xEBC1,
+	0xF9D4, 0xEBC2, 0xF9D5, 0xEBC6, 0xF9D6, 0xEBC7, 0xF9D7, 0xEBCC,
+	0xF9D8, 0xEBCF, 0xF9D9, 0xEBD0, 0xF9DA, 0xEBD1, 0xF9DB, 0xEBD2,
+	0xF9DC, 0xEBD8, 0xF9DD, 0xECA6, 0xF9DE, 0xECA7, 0xF9DF, 0xECAA,
+	0xF9E0, 0xECAF, 0xF9E1, 0xECB0, 0xF9E2, 0xECB1, 0xF9E3, 0xECB2,
+	0xF9E4, 0xECB5, 0xF9E5, 0xECB8, 0xF9E6, 0xECBA, 0xF9E7, 0xECC0,
+	0xF9E8, 0xECC1, 0xF9E9, 0xECC5, 0xF9EA, 0xECC6, 0xF9EB, 0xECC9,
+	0xF9EC, 0xECCA, 0xF9ED, 0xECD5, 0xF9EE, 0xECDD, 0xF9EF, 0xECDE,
+	0xF9F0, 0xECE1, 0xF9F1, 0xECE4, 0xF9F2, 0xECE7, 0xF9F3, 0xECE8,
+	0xF9F4, 0xECF7, 0xF9F5, 0xECF8, 0xF9F6, 0xECFA, 0xF9F7, 0xEDA1,
+	0xF9F8, 0xEDA2, 0xF9F9, 0xEDA3, 0xF9FA, 0xEDEE, 0xF9FB, 0xEEDB,
+	0xF9FC, 0xF2BD, 0xF9FD, 0xF2FA, 0xF9FE, 0xF3B1, 0xF9FF, 0xF4A7,
+	0xFA00, 0xF4EE, 0xFA01, 0xF6F4, 0xFA02, 0xF6F6, 0xFA03, 0xF7B8,
+	0xFA04, 0xF7C8, 0xFA05, 0xF7D3, 0xFA06, 0xF8DB, 0xFA07, 0xF8F0,
+	0xFA08, 0xFAA1, 0xFA09, 0xFAA2, 0xFA0A, 0xFAE6, 0xFA0B, 0xFCA9,
+	0xFF01, 0xA3A1, 0xFF02, 0xA3A2, 0xFF03, 0xA3A3, 0xFF04, 0xA3A4,
+	0xFF05, 0xA3A5, 0xFF06, 0xA3A6, 0xFF07, 0xA3A7, 0xFF08, 0xA3A8,
+	0xFF09, 0xA3A9, 0xFF0A, 0xA3AA, 0xFF0B, 0xA3AB, 0xFF0C, 0xA3AC,
+	0xFF0D, 0xA3AD, 0xFF0E, 0xA3AE, 0xFF0F, 0xA3AF, 0xFF10, 0xA3B0,
+	0xFF11, 0xA3B1, 0xFF12, 0xA3B2, 0xFF13, 0xA3B3, 0xFF14, 0xA3B4,
+	0xFF15, 0xA3B5, 0xFF16, 0xA3B6, 0xFF17, 0xA3B7, 0xFF18, 0xA3B8,
+	0xFF19, 0xA3B9, 0xFF1A, 0xA3BA, 0xFF1B, 0xA3BB, 0xFF1C, 0xA3BC,
+	0xFF1D, 0xA3BD, 0xFF1E, 0xA3BE, 0xFF1F, 0xA3BF, 0xFF20, 0xA3C0,
+	0xFF21, 0xA3C1, 0xFF22, 0xA3C2, 0xFF23, 0xA3C3, 0xFF24, 0xA3C4,
+	0xFF25, 0xA3C5, 0xFF26, 0xA3C6, 0xFF27, 0xA3C7, 0xFF28, 0xA3C8,
+	0xFF29, 0xA3C9, 0xFF2A, 0xA3CA, 0xFF2B, 0xA3CB, 0xFF2C, 0xA3CC,
+	0xFF2D, 0xA3CD, 0xFF2E, 0xA3CE, 0xFF2F, 0xA3CF, 0xFF30, 0xA3D0,
+	0xFF31, 0xA3D1, 0xFF32, 0xA3D2, 0xFF33, 0xA3D3, 0xFF34, 0xA3D4,
+	0xFF35, 0xA3D5, 0xFF36, 0xA3D6, 0xFF37, 0xA3D7, 0xFF38, 0xA3D8,
+	0xFF39, 0xA3D9, 0xFF3A, 0xA3DA, 0xFF3B, 0xA3DB, 0xFF3C, 0xA1AC,
+	0xFF3D, 0xA3DD, 0xFF3E, 0xA3DE, 0xFF3F, 0xA3DF, 0xFF40, 0xA3E0,
+	0xFF41, 0xA3E1, 0xFF42, 0xA3E2, 0xFF43, 0xA3E3, 0xFF44, 0xA3E4,
+	0xFF45, 0xA3E5, 0xFF46, 0xA3E6, 0xFF47, 0xA3E7, 0xFF48, 0xA3E8,
+	0xFF49, 0xA3E9, 0xFF4A, 0xA3EA, 0xFF4B, 0xA3EB, 0xFF4C, 0xA3EC,
+	0xFF4D, 0xA3ED, 0xFF4E, 0xA3EE, 0xFF4F, 0xA3EF, 0xFF50, 0xA3F0,
+	0xFF51, 0xA3F1, 0xFF52, 0xA3F2, 0xFF53, 0xA3F3, 0xFF54, 0xA3F4,
+	0xFF55, 0xA3F5, 0xFF56, 0xA3F6, 0xFF57, 0xA3F7, 0xFF58, 0xA3F8,
+	0xFF59, 0xA3F9, 0xFF5A, 0xA3FA, 0xFF5B, 0xA3FB, 0xFF5C, 0xA3FC,
+	0xFF5D, 0xA3FD, 0xFF5E, 0xA2A6, 0xFFE0, 0xA1CB, 0xFFE1, 0xA1CC,
+	0xFFE2, 0xA1FE, 0xFFE3, 0xA3FE, 0xFFE5, 0xA1CD, 0xFFE6, 0xA3DC,
+	0, 0
+};
+
+static
+const WCHAR oem2uni[] = {
+/*	OEM - Unicode,  OEM - Unicode,  OEM - Unicode,  OEM - Unicode */
+	0x8141, 0xAC02, 0x8142, 0xAC03, 0x8143, 0xAC05, 0x8144, 0xAC06,
+	0x8145, 0xAC0B, 0x8146, 0xAC0C, 0x8147, 0xAC0D, 0x8148, 0xAC0E,
+	0x8149, 0xAC0F, 0x814A, 0xAC18, 0x814B, 0xAC1E, 0x814C, 0xAC1F,
+	0x814D, 0xAC21, 0x814E, 0xAC22, 0x814F, 0xAC23, 0x8150, 0xAC25,
+	0x8151, 0xAC26, 0x8152, 0xAC27, 0x8153, 0xAC28, 0x8154, 0xAC29,
+	0x8155, 0xAC2A, 0x8156, 0xAC2B, 0x8157, 0xAC2E, 0x8158, 0xAC32,
+	0x8159, 0xAC33, 0x815A, 0xAC34, 0x8161, 0xAC35, 0x8162, 0xAC36,
+	0x8163, 0xAC37, 0x8164, 0xAC3A, 0x8165, 0xAC3B, 0x8166, 0xAC3D,
+	0x8167, 0xAC3E, 0x8168, 0xAC3F, 0x8169, 0xAC41, 0x816A, 0xAC42,
+	0x816B, 0xAC43, 0x816C, 0xAC44, 0x816D, 0xAC45, 0x816E, 0xAC46,
+	0x816F, 0xAC47, 0x8170, 0xAC48, 0x8171, 0xAC49, 0x8172, 0xAC4A,
+	0x8173, 0xAC4C, 0x8174, 0xAC4E, 0x8175, 0xAC4F, 0x8176, 0xAC50,
+	0x8177, 0xAC51, 0x8178, 0xAC52, 0x8179, 0xAC53, 0x817A, 0xAC55,
+	0x8181, 0xAC56, 0x8182, 0xAC57, 0x8183, 0xAC59, 0x8184, 0xAC5A,
+	0x8185, 0xAC5B, 0x8186, 0xAC5D, 0x8187, 0xAC5E, 0x8188, 0xAC5F,
+	0x8189, 0xAC60, 0x818A, 0xAC61, 0x818B, 0xAC62, 0x818C, 0xAC63,
+	0x818D, 0xAC64, 0x818E, 0xAC65, 0x818F, 0xAC66, 0x8190, 0xAC67,
+	0x8191, 0xAC68, 0x8192, 0xAC69, 0x8193, 0xAC6A, 0x8194, 0xAC6B,
+	0x8195, 0xAC6C, 0x8196, 0xAC6D, 0x8197, 0xAC6E, 0x8198, 0xAC6F,
+	0x8199, 0xAC72, 0x819A, 0xAC73, 0x819B, 0xAC75, 0x819C, 0xAC76,
+	0x819D, 0xAC79, 0x819E, 0xAC7B, 0x819F, 0xAC7C, 0x81A0, 0xAC7D,
+	0x81A1, 0xAC7E, 0x81A2, 0xAC7F, 0x81A3, 0xAC82, 0x81A4, 0xAC87,
+	0x81A5, 0xAC88, 0x81A6, 0xAC8D, 0x81A7, 0xAC8E, 0x81A8, 0xAC8F,
+	0x81A9, 0xAC91, 0x81AA, 0xAC92, 0x81AB, 0xAC93, 0x81AC, 0xAC95,
+	0x81AD, 0xAC96, 0x81AE, 0xAC97, 0x81AF, 0xAC98, 0x81B0, 0xAC99,
+	0x81B1, 0xAC9A, 0x81B2, 0xAC9B, 0x81B3, 0xAC9E, 0x81B4, 0xACA2,
+	0x81B5, 0xACA3, 0x81B6, 0xACA4, 0x81B7, 0xACA5, 0x81B8, 0xACA6,
+	0x81B9, 0xACA7, 0x81BA, 0xACAB, 0x81BB, 0xACAD, 0x81BC, 0xACAE,
+	0x81BD, 0xACB1, 0x81BE, 0xACB2, 0x81BF, 0xACB3, 0x81C0, 0xACB4,
+	0x81C1, 0xACB5, 0x81C2, 0xACB6, 0x81C3, 0xACB7, 0x81C4, 0xACBA,
+	0x81C5, 0xACBE, 0x81C6, 0xACBF, 0x81C7, 0xACC0, 0x81C8, 0xACC2,
+	0x81C9, 0xACC3, 0x81CA, 0xACC5, 0x81CB, 0xACC6, 0x81CC, 0xACC7,
+	0x81CD, 0xACC9, 0x81CE, 0xACCA, 0x81CF, 0xACCB, 0x81D0, 0xACCD,
+	0x81D1, 0xACCE, 0x81D2, 0xACCF, 0x81D3, 0xACD0, 0x81D4, 0xACD1,
+	0x81D5, 0xACD2, 0x81D6, 0xACD3, 0x81D7, 0xACD4, 0x81D8, 0xACD6,
+	0x81D9, 0xACD8, 0x81DA, 0xACD9, 0x81DB, 0xACDA, 0x81DC, 0xACDB,
+	0x81DD, 0xACDC, 0x81DE, 0xACDD, 0x81DF, 0xACDE, 0x81E0, 0xACDF,
+	0x81E1, 0xACE2, 0x81E2, 0xACE3, 0x81E3, 0xACE5, 0x81E4, 0xACE6,
+	0x81E5, 0xACE9, 0x81E6, 0xACEB, 0x81E7, 0xACED, 0x81E8, 0xACEE,
+	0x81E9, 0xACF2, 0x81EA, 0xACF4, 0x81EB, 0xACF7, 0x81EC, 0xACF8,
+	0x81ED, 0xACF9, 0x81EE, 0xACFA, 0x81EF, 0xACFB, 0x81F0, 0xACFE,
+	0x81F1, 0xACFF, 0x81F2, 0xAD01, 0x81F3, 0xAD02, 0x81F4, 0xAD03,
+	0x81F5, 0xAD05, 0x81F6, 0xAD07, 0x81F7, 0xAD08, 0x81F8, 0xAD09,
+	0x81F9, 0xAD0A, 0x81FA, 0xAD0B, 0x81FB, 0xAD0E, 0x81FC, 0xAD10,
+	0x81FD, 0xAD12, 0x81FE, 0xAD13, 0x8241, 0xAD14, 0x8242, 0xAD15,
+	0x8243, 0xAD16, 0x8244, 0xAD17, 0x8245, 0xAD19, 0x8246, 0xAD1A,
+	0x8247, 0xAD1B, 0x8248, 0xAD1D, 0x8249, 0xAD1E, 0x824A, 0xAD1F,
+	0x824B, 0xAD21, 0x824C, 0xAD22, 0x824D, 0xAD23, 0x824E, 0xAD24,
+	0x824F, 0xAD25, 0x8250, 0xAD26, 0x8251, 0xAD27, 0x8252, 0xAD28,
+	0x8253, 0xAD2A, 0x8254, 0xAD2B, 0x8255, 0xAD2E, 0x8256, 0xAD2F,
+	0x8257, 0xAD30, 0x8258, 0xAD31, 0x8259, 0xAD32, 0x825A, 0xAD33,
+	0x8261, 0xAD36, 0x8262, 0xAD37, 0x8263, 0xAD39, 0x8264, 0xAD3A,
+	0x8265, 0xAD3B, 0x8266, 0xAD3D, 0x8267, 0xAD3E, 0x8268, 0xAD3F,
+	0x8269, 0xAD40, 0x826A, 0xAD41, 0x826B, 0xAD42, 0x826C, 0xAD43,
+	0x826D, 0xAD46, 0x826E, 0xAD48, 0x826F, 0xAD4A, 0x8270, 0xAD4B,
+	0x8271, 0xAD4C, 0x8272, 0xAD4D, 0x8273, 0xAD4E, 0x8274, 0xAD4F,
+	0x8275, 0xAD51, 0x8276, 0xAD52, 0x8277, 0xAD53, 0x8278, 0xAD55,
+	0x8279, 0xAD56, 0x827A, 0xAD57, 0x8281, 0xAD59, 0x8282, 0xAD5A,
+	0x8283, 0xAD5B, 0x8284, 0xAD5C, 0x8285, 0xAD5D, 0x8286, 0xAD5E,
+	0x8287, 0xAD5F, 0x8288, 0xAD60, 0x8289, 0xAD62, 0x828A, 0xAD64,
+	0x828B, 0xAD65, 0x828C, 0xAD66, 0x828D, 0xAD67, 0x828E, 0xAD68,
+	0x828F, 0xAD69, 0x8290, 0xAD6A, 0x8291, 0xAD6B, 0x8292, 0xAD6E,
+	0x8293, 0xAD6F, 0x8294, 0xAD71, 0x8295, 0xAD72, 0x8296, 0xAD77,
+	0x8297, 0xAD78, 0x8298, 0xAD79, 0x8299, 0xAD7A, 0x829A, 0xAD7E,
+	0x829B, 0xAD80, 0x829C, 0xAD83, 0x829D, 0xAD84, 0x829E, 0xAD85,
+	0x829F, 0xAD86, 0x82A0, 0xAD87, 0x82A1, 0xAD8A, 0x82A2, 0xAD8B,
+	0x82A3, 0xAD8D, 0x82A4, 0xAD8E, 0x82A5, 0xAD8F, 0x82A6, 0xAD91,
+	0x82A7, 0xAD92, 0x82A8, 0xAD93, 0x82A9, 0xAD94, 0x82AA, 0xAD95,
+	0x82AB, 0xAD96, 0x82AC, 0xAD97, 0x82AD, 0xAD98, 0x82AE, 0xAD99,
+	0x82AF, 0xAD9A, 0x82B0, 0xAD9B, 0x82B1, 0xAD9E, 0x82B2, 0xAD9F,
+	0x82B3, 0xADA0, 0x82B4, 0xADA1, 0x82B5, 0xADA2, 0x82B6, 0xADA3,
+	0x82B7, 0xADA5, 0x82B8, 0xADA6, 0x82B9, 0xADA7, 0x82BA, 0xADA8,
+	0x82BB, 0xADA9, 0x82BC, 0xADAA, 0x82BD, 0xADAB, 0x82BE, 0xADAC,
+	0x82BF, 0xADAD, 0x82C0, 0xADAE, 0x82C1, 0xADAF, 0x82C2, 0xADB0,
+	0x82C3, 0xADB1, 0x82C4, 0xADB2, 0x82C5, 0xADB3, 0x82C6, 0xADB4,
+	0x82C7, 0xADB5, 0x82C8, 0xADB6, 0x82C9, 0xADB8, 0x82CA, 0xADB9,
+	0x82CB, 0xADBA, 0x82CC, 0xADBB, 0x82CD, 0xADBC, 0x82CE, 0xADBD,
+	0x82CF, 0xADBE, 0x82D0, 0xADBF, 0x82D1, 0xADC2, 0x82D2, 0xADC3,
+	0x82D3, 0xADC5, 0x82D4, 0xADC6, 0x82D5, 0xADC7, 0x82D6, 0xADC9,
+	0x82D7, 0xADCA, 0x82D8, 0xADCB, 0x82D9, 0xADCC, 0x82DA, 0xADCD,
+	0x82DB, 0xADCE, 0x82DC, 0xADCF, 0x82DD, 0xADD2, 0x82DE, 0xADD4,
+	0x82DF, 0xADD5, 0x82E0, 0xADD6, 0x82E1, 0xADD7, 0x82E2, 0xADD8,
+	0x82E3, 0xADD9, 0x82E4, 0xADDA, 0x82E5, 0xADDB, 0x82E6, 0xADDD,
+	0x82E7, 0xADDE, 0x82E8, 0xADDF, 0x82E9, 0xADE1, 0x82EA, 0xADE2,
+	0x82EB, 0xADE3, 0x82EC, 0xADE5, 0x82ED, 0xADE6, 0x82EE, 0xADE7,
+	0x82EF, 0xADE8, 0x82F0, 0xADE9, 0x82F1, 0xADEA, 0x82F2, 0xADEB,
+	0x82F3, 0xADEC, 0x82F4, 0xADED, 0x82F5, 0xADEE, 0x82F6, 0xADEF,
+	0x82F7, 0xADF0, 0x82F8, 0xADF1, 0x82F9, 0xADF2, 0x82FA, 0xADF3,
+	0x82FB, 0xADF4, 0x82FC, 0xADF5, 0x82FD, 0xADF6, 0x82FE, 0xADF7,
+	0x8341, 0xADFA, 0x8342, 0xADFB, 0x8343, 0xADFD, 0x8344, 0xADFE,
+	0x8345, 0xAE02, 0x8346, 0xAE03, 0x8347, 0xAE04, 0x8348, 0xAE05,
+	0x8349, 0xAE06, 0x834A, 0xAE07, 0x834B, 0xAE0A, 0x834C, 0xAE0C,
+	0x834D, 0xAE0E, 0x834E, 0xAE0F, 0x834F, 0xAE10, 0x8350, 0xAE11,
+	0x8351, 0xAE12, 0x8352, 0xAE13, 0x8353, 0xAE15, 0x8354, 0xAE16,
+	0x8355, 0xAE17, 0x8356, 0xAE18, 0x8357, 0xAE19, 0x8358, 0xAE1A,
+	0x8359, 0xAE1B, 0x835A, 0xAE1C, 0x8361, 0xAE1D, 0x8362, 0xAE1E,
+	0x8363, 0xAE1F, 0x8364, 0xAE20, 0x8365, 0xAE21, 0x8366, 0xAE22,
+	0x8367, 0xAE23, 0x8368, 0xAE24, 0x8369, 0xAE25, 0x836A, 0xAE26,
+	0x836B, 0xAE27, 0x836C, 0xAE28, 0x836D, 0xAE29, 0x836E, 0xAE2A,
+	0x836F, 0xAE2B, 0x8370, 0xAE2C, 0x8371, 0xAE2D, 0x8372, 0xAE2E,
+	0x8373, 0xAE2F, 0x8374, 0xAE32, 0x8375, 0xAE33, 0x8376, 0xAE35,
+	0x8377, 0xAE36, 0x8378, 0xAE39, 0x8379, 0xAE3B, 0x837A, 0xAE3C,
+	0x8381, 0xAE3D, 0x8382, 0xAE3E, 0x8383, 0xAE3F, 0x8384, 0xAE42,
+	0x8385, 0xAE44, 0x8386, 0xAE47, 0x8387, 0xAE48, 0x8388, 0xAE49,
+	0x8389, 0xAE4B, 0x838A, 0xAE4F, 0x838B, 0xAE51, 0x838C, 0xAE52,
+	0x838D, 0xAE53, 0x838E, 0xAE55, 0x838F, 0xAE57, 0x8390, 0xAE58,
+	0x8391, 0xAE59, 0x8392, 0xAE5A, 0x8393, 0xAE5B, 0x8394, 0xAE5E,
+	0x8395, 0xAE62, 0x8396, 0xAE63, 0x8397, 0xAE64, 0x8398, 0xAE66,
+	0x8399, 0xAE67, 0x839A, 0xAE6A, 0x839B, 0xAE6B, 0x839C, 0xAE6D,
+	0x839D, 0xAE6E, 0x839E, 0xAE6F, 0x839F, 0xAE71, 0x83A0, 0xAE72,
+	0x83A1, 0xAE73, 0x83A2, 0xAE74, 0x83A3, 0xAE75, 0x83A4, 0xAE76,
+	0x83A5, 0xAE77, 0x83A6, 0xAE7A, 0x83A7, 0xAE7E, 0x83A8, 0xAE7F,
+	0x83A9, 0xAE80, 0x83AA, 0xAE81, 0x83AB, 0xAE82, 0x83AC, 0xAE83,
+	0x83AD, 0xAE86, 0x83AE, 0xAE87, 0x83AF, 0xAE88, 0x83B0, 0xAE89,
+	0x83B1, 0xAE8A, 0x83B2, 0xAE8B, 0x83B3, 0xAE8D, 0x83B4, 0xAE8E,
+	0x83B5, 0xAE8F, 0x83B6, 0xAE90, 0x83B7, 0xAE91, 0x83B8, 0xAE92,
+	0x83B9, 0xAE93, 0x83BA, 0xAE94, 0x83BB, 0xAE95, 0x83BC, 0xAE96,
+	0x83BD, 0xAE97, 0x83BE, 0xAE98, 0x83BF, 0xAE99, 0x83C0, 0xAE9A,
+	0x83C1, 0xAE9B, 0x83C2, 0xAE9C, 0x83C3, 0xAE9D, 0x83C4, 0xAE9E,
+	0x83C5, 0xAE9F, 0x83C6, 0xAEA0, 0x83C7, 0xAEA1, 0x83C8, 0xAEA2,
+	0x83C9, 0xAEA3, 0x83CA, 0xAEA4, 0x83CB, 0xAEA5, 0x83CC, 0xAEA6,
+	0x83CD, 0xAEA7, 0x83CE, 0xAEA8, 0x83CF, 0xAEA9, 0x83D0, 0xAEAA,
+	0x83D1, 0xAEAB, 0x83D2, 0xAEAC, 0x83D3, 0xAEAD, 0x83D4, 0xAEAE,
+	0x83D5, 0xAEAF, 0x83D6, 0xAEB0, 0x83D7, 0xAEB1, 0x83D8, 0xAEB2,
+	0x83D9, 0xAEB3, 0x83DA, 0xAEB4, 0x83DB, 0xAEB5, 0x83DC, 0xAEB6,
+	0x83DD, 0xAEB7, 0x83DE, 0xAEB8, 0x83DF, 0xAEB9, 0x83E0, 0xAEBA,
+	0x83E1, 0xAEBB, 0x83E2, 0xAEBF, 0x83E3, 0xAEC1, 0x83E4, 0xAEC2,
+	0x83E5, 0xAEC3, 0x83E6, 0xAEC5, 0x83E7, 0xAEC6, 0x83E8, 0xAEC7,
+	0x83E9, 0xAEC8, 0x83EA, 0xAEC9, 0x83EB, 0xAECA, 0x83EC, 0xAECB,
+	0x83ED, 0xAECE, 0x83EE, 0xAED2, 0x83EF, 0xAED3, 0x83F0, 0xAED4,
+	0x83F1, 0xAED5, 0x83F2, 0xAED6, 0x83F3, 0xAED7, 0x83F4, 0xAEDA,
+	0x83F5, 0xAEDB, 0x83F6, 0xAEDD, 0x83F7, 0xAEDE, 0x83F8, 0xAEDF,
+	0x83F9, 0xAEE0, 0x83FA, 0xAEE1, 0x83FB, 0xAEE2, 0x83FC, 0xAEE3,
+	0x83FD, 0xAEE4, 0x83FE, 0xAEE5, 0x8441, 0xAEE6, 0x8442, 0xAEE7,
+	0x8443, 0xAEE9, 0x8444, 0xAEEA, 0x8445, 0xAEEC, 0x8446, 0xAEEE,
+	0x8447, 0xAEEF, 0x8448, 0xAEF0, 0x8449, 0xAEF1, 0x844A, 0xAEF2,
+	0x844B, 0xAEF3, 0x844C, 0xAEF5, 0x844D, 0xAEF6, 0x844E, 0xAEF7,
+	0x844F, 0xAEF9, 0x8450, 0xAEFA, 0x8451, 0xAEFB, 0x8452, 0xAEFD,
+	0x8453, 0xAEFE, 0x8454, 0xAEFF, 0x8455, 0xAF00, 0x8456, 0xAF01,
+	0x8457, 0xAF02, 0x8458, 0xAF03, 0x8459, 0xAF04, 0x845A, 0xAF05,
+	0x8461, 0xAF06, 0x8462, 0xAF09, 0x8463, 0xAF0A, 0x8464, 0xAF0B,
+	0x8465, 0xAF0C, 0x8466, 0xAF0E, 0x8467, 0xAF0F, 0x8468, 0xAF11,
+	0x8469, 0xAF12, 0x846A, 0xAF13, 0x846B, 0xAF14, 0x846C, 0xAF15,
+	0x846D, 0xAF16, 0x846E, 0xAF17, 0x846F, 0xAF18, 0x8470, 0xAF19,
+	0x8471, 0xAF1A, 0x8472, 0xAF1B, 0x8473, 0xAF1C, 0x8474, 0xAF1D,
+	0x8475, 0xAF1E, 0x8476, 0xAF1F, 0x8477, 0xAF20, 0x8478, 0xAF21,
+	0x8479, 0xAF22, 0x847A, 0xAF23, 0x8481, 0xAF24, 0x8482, 0xAF25,
+	0x8483, 0xAF26, 0x8484, 0xAF27, 0x8485, 0xAF28, 0x8486, 0xAF29,
+	0x8487, 0xAF2A, 0x8488, 0xAF2B, 0x8489, 0xAF2E, 0x848A, 0xAF2F,
+	0x848B, 0xAF31, 0x848C, 0xAF33, 0x848D, 0xAF35, 0x848E, 0xAF36,
+	0x848F, 0xAF37, 0x8490, 0xAF38, 0x8491, 0xAF39, 0x8492, 0xAF3A,
+	0x8493, 0xAF3B, 0x8494, 0xAF3E, 0x8495, 0xAF40, 0x8496, 0xAF44,
+	0x8497, 0xAF45, 0x8498, 0xAF46, 0x8499, 0xAF47, 0x849A, 0xAF4A,
+	0x849B, 0xAF4B, 0x849C, 0xAF4C, 0x849D, 0xAF4D, 0x849E, 0xAF4E,
+	0x849F, 0xAF4F, 0x84A0, 0xAF51, 0x84A1, 0xAF52, 0x84A2, 0xAF53,
+	0x84A3, 0xAF54, 0x84A4, 0xAF55, 0x84A5, 0xAF56, 0x84A6, 0xAF57,
+	0x84A7, 0xAF58, 0x84A8, 0xAF59, 0x84A9, 0xAF5A, 0x84AA, 0xAF5B,
+	0x84AB, 0xAF5E, 0x84AC, 0xAF5F, 0x84AD, 0xAF60, 0x84AE, 0xAF61,
+	0x84AF, 0xAF62, 0x84B0, 0xAF63, 0x84B1, 0xAF66, 0x84B2, 0xAF67,
+	0x84B3, 0xAF68, 0x84B4, 0xAF69, 0x84B5, 0xAF6A, 0x84B6, 0xAF6B,
+	0x84B7, 0xAF6C, 0x84B8, 0xAF6D, 0x84B9, 0xAF6E, 0x84BA, 0xAF6F,
+	0x84BB, 0xAF70, 0x84BC, 0xAF71, 0x84BD, 0xAF72, 0x84BE, 0xAF73,
+	0x84BF, 0xAF74, 0x84C0, 0xAF75, 0x84C1, 0xAF76, 0x84C2, 0xAF77,
+	0x84C3, 0xAF78, 0x84C4, 0xAF7A, 0x84C5, 0xAF7B, 0x84C6, 0xAF7C,
+	0x84C7, 0xAF7D, 0x84C8, 0xAF7E, 0x84C9, 0xAF7F, 0x84CA, 0xAF81,
+	0x84CB, 0xAF82, 0x84CC, 0xAF83, 0x84CD, 0xAF85, 0x84CE, 0xAF86,
+	0x84CF, 0xAF87, 0x84D0, 0xAF89, 0x84D1, 0xAF8A, 0x84D2, 0xAF8B,
+	0x84D3, 0xAF8C, 0x84D4, 0xAF8D, 0x84D5, 0xAF8E, 0x84D6, 0xAF8F,
+	0x84D7, 0xAF92, 0x84D8, 0xAF93, 0x84D9, 0xAF94, 0x84DA, 0xAF96,
+	0x84DB, 0xAF97, 0x84DC, 0xAF98, 0x84DD, 0xAF99, 0x84DE, 0xAF9A,
+	0x84DF, 0xAF9B, 0x84E0, 0xAF9D, 0x84E1, 0xAF9E, 0x84E2, 0xAF9F,
+	0x84E3, 0xAFA0, 0x84E4, 0xAFA1, 0x84E5, 0xAFA2, 0x84E6, 0xAFA3,
+	0x84E7, 0xAFA4, 0x84E8, 0xAFA5, 0x84E9, 0xAFA6, 0x84EA, 0xAFA7,
+	0x84EB, 0xAFA8, 0x84EC, 0xAFA9, 0x84ED, 0xAFAA, 0x84EE, 0xAFAB,
+	0x84EF, 0xAFAC, 0x84F0, 0xAFAD, 0x84F1, 0xAFAE, 0x84F2, 0xAFAF,
+	0x84F3, 0xAFB0, 0x84F4, 0xAFB1, 0x84F5, 0xAFB2, 0x84F6, 0xAFB3,
+	0x84F7, 0xAFB4, 0x84F8, 0xAFB5, 0x84F9, 0xAFB6, 0x84FA, 0xAFB7,
+	0x84FB, 0xAFBA, 0x84FC, 0xAFBB, 0x84FD, 0xAFBD, 0x84FE, 0xAFBE,
+	0x8541, 0xAFBF, 0x8542, 0xAFC1, 0x8543, 0xAFC2, 0x8544, 0xAFC3,
+	0x8545, 0xAFC4, 0x8546, 0xAFC5, 0x8547, 0xAFC6, 0x8548, 0xAFCA,
+	0x8549, 0xAFCC, 0x854A, 0xAFCF, 0x854B, 0xAFD0, 0x854C, 0xAFD1,
+	0x854D, 0xAFD2, 0x854E, 0xAFD3, 0x854F, 0xAFD5, 0x8550, 0xAFD6,
+	0x8551, 0xAFD7, 0x8552, 0xAFD8, 0x8553, 0xAFD9, 0x8554, 0xAFDA,
+	0x8555, 0xAFDB, 0x8556, 0xAFDD, 0x8557, 0xAFDE, 0x8558, 0xAFDF,
+	0x8559, 0xAFE0, 0x855A, 0xAFE1, 0x8561, 0xAFE2, 0x8562, 0xAFE3,
+	0x8563, 0xAFE4, 0x8564, 0xAFE5, 0x8565, 0xAFE6, 0x8566, 0xAFE7,
+	0x8567, 0xAFEA, 0x8568, 0xAFEB, 0x8569, 0xAFEC, 0x856A, 0xAFED,
+	0x856B, 0xAFEE, 0x856C, 0xAFEF, 0x856D, 0xAFF2, 0x856E, 0xAFF3,
+	0x856F, 0xAFF5, 0x8570, 0xAFF6, 0x8571, 0xAFF7, 0x8572, 0xAFF9,
+	0x8573, 0xAFFA, 0x8574, 0xAFFB, 0x8575, 0xAFFC, 0x8576, 0xAFFD,
+	0x8577, 0xAFFE, 0x8578, 0xAFFF, 0x8579, 0xB002, 0x857A, 0xB003,
+	0x8581, 0xB005, 0x8582, 0xB006, 0x8583, 0xB007, 0x8584, 0xB008,
+	0x8585, 0xB009, 0x8586, 0xB00A, 0x8587, 0xB00B, 0x8588, 0xB00D,
+	0x8589, 0xB00E, 0x858A, 0xB00F, 0x858B, 0xB011, 0x858C, 0xB012,
+	0x858D, 0xB013, 0x858E, 0xB015, 0x858F, 0xB016, 0x8590, 0xB017,
+	0x8591, 0xB018, 0x8592, 0xB019, 0x8593, 0xB01A, 0x8594, 0xB01B,
+	0x8595, 0xB01E, 0x8596, 0xB01F, 0x8597, 0xB020, 0x8598, 0xB021,
+	0x8599, 0xB022, 0x859A, 0xB023, 0x859B, 0xB024, 0x859C, 0xB025,
+	0x859D, 0xB026, 0x859E, 0xB027, 0x859F, 0xB029, 0x85A0, 0xB02A,
+	0x85A1, 0xB02B, 0x85A2, 0xB02C, 0x85A3, 0xB02D, 0x85A4, 0xB02E,
+	0x85A5, 0xB02F, 0x85A6, 0xB030, 0x85A7, 0xB031, 0x85A8, 0xB032,
+	0x85A9, 0xB033, 0x85AA, 0xB034, 0x85AB, 0xB035, 0x85AC, 0xB036,
+	0x85AD, 0xB037, 0x85AE, 0xB038, 0x85AF, 0xB039, 0x85B0, 0xB03A,
+	0x85B1, 0xB03B, 0x85B2, 0xB03C, 0x85B3, 0xB03D, 0x85B4, 0xB03E,
+	0x85B5, 0xB03F, 0x85B6, 0xB040, 0x85B7, 0xB041, 0x85B8, 0xB042,
+	0x85B9, 0xB043, 0x85BA, 0xB046, 0x85BB, 0xB047, 0x85BC, 0xB049,
+	0x85BD, 0xB04B, 0x85BE, 0xB04D, 0x85BF, 0xB04F, 0x85C0, 0xB050,
+	0x85C1, 0xB051, 0x85C2, 0xB052, 0x85C3, 0xB056, 0x85C4, 0xB058,
+	0x85C5, 0xB05A, 0x85C6, 0xB05B, 0x85C7, 0xB05C, 0x85C8, 0xB05E,
+	0x85C9, 0xB05F, 0x85CA, 0xB060, 0x85CB, 0xB061, 0x85CC, 0xB062,
+	0x85CD, 0xB063, 0x85CE, 0xB064, 0x85CF, 0xB065, 0x85D0, 0xB066,
+	0x85D1, 0xB067, 0x85D2, 0xB068, 0x85D3, 0xB069, 0x85D4, 0xB06A,
+	0x85D5, 0xB06B, 0x85D6, 0xB06C, 0x85D7, 0xB06D, 0x85D8, 0xB06E,
+	0x85D9, 0xB06F, 0x85DA, 0xB070, 0x85DB, 0xB071, 0x85DC, 0xB072,
+	0x85DD, 0xB073, 0x85DE, 0xB074, 0x85DF, 0xB075, 0x85E0, 0xB076,
+	0x85E1, 0xB077, 0x85E2, 0xB078, 0x85E3, 0xB079, 0x85E4, 0xB07A,
+	0x85E5, 0xB07B, 0x85E6, 0xB07E, 0x85E7, 0xB07F, 0x85E8, 0xB081,
+	0x85E9, 0xB082, 0x85EA, 0xB083, 0x85EB, 0xB085, 0x85EC, 0xB086,
+	0x85ED, 0xB087, 0x85EE, 0xB088, 0x85EF, 0xB089, 0x85F0, 0xB08A,
+	0x85F1, 0xB08B, 0x85F2, 0xB08E, 0x85F3, 0xB090, 0x85F4, 0xB092,
+	0x85F5, 0xB093, 0x85F6, 0xB094, 0x85F7, 0xB095, 0x85F8, 0xB096,
+	0x85F9, 0xB097, 0x85FA, 0xB09B, 0x85FB, 0xB09D, 0x85FC, 0xB09E,
+	0x85FD, 0xB0A3, 0x85FE, 0xB0A4, 0x8641, 0xB0A5, 0x8642, 0xB0A6,
+	0x8643, 0xB0A7, 0x8644, 0xB0AA, 0x8645, 0xB0B0, 0x8646, 0xB0B2,
+	0x8647, 0xB0B6, 0x8648, 0xB0B7, 0x8649, 0xB0B9, 0x864A, 0xB0BA,
+	0x864B, 0xB0BB, 0x864C, 0xB0BD, 0x864D, 0xB0BE, 0x864E, 0xB0BF,
+	0x864F, 0xB0C0, 0x8650, 0xB0C1, 0x8651, 0xB0C2, 0x8652, 0xB0C3,
+	0x8653, 0xB0C6, 0x8654, 0xB0CA, 0x8655, 0xB0CB, 0x8656, 0xB0CC,
+	0x8657, 0xB0CD, 0x8658, 0xB0CE, 0x8659, 0xB0CF, 0x865A, 0xB0D2,
+	0x8661, 0xB0D3, 0x8662, 0xB0D5, 0x8663, 0xB0D6, 0x8664, 0xB0D7,
+	0x8665, 0xB0D9, 0x8666, 0xB0DA, 0x8667, 0xB0DB, 0x8668, 0xB0DC,
+	0x8669, 0xB0DD, 0x866A, 0xB0DE, 0x866B, 0xB0DF, 0x866C, 0xB0E1,
+	0x866D, 0xB0E2, 0x866E, 0xB0E3, 0x866F, 0xB0E4, 0x8670, 0xB0E6,
+	0x8671, 0xB0E7, 0x8672, 0xB0E8, 0x8673, 0xB0E9, 0x8674, 0xB0EA,
+	0x8675, 0xB0EB, 0x8676, 0xB0EC, 0x8677, 0xB0ED, 0x8678, 0xB0EE,
+	0x8679, 0xB0EF, 0x867A, 0xB0F0, 0x8681, 0xB0F1, 0x8682, 0xB0F2,
+	0x8683, 0xB0F3, 0x8684, 0xB0F4, 0x8685, 0xB0F5, 0x8686, 0xB0F6,
+	0x8687, 0xB0F7, 0x8688, 0xB0F8, 0x8689, 0xB0F9, 0x868A, 0xB0FA,
+	0x868B, 0xB0FB, 0x868C, 0xB0FC, 0x868D, 0xB0FD, 0x868E, 0xB0FE,
+	0x868F, 0xB0FF, 0x8690, 0xB100, 0x8691, 0xB101, 0x8692, 0xB102,
+	0x8693, 0xB103, 0x8694, 0xB104, 0x8695, 0xB105, 0x8696, 0xB106,
+	0x8697, 0xB107, 0x8698, 0xB10A, 0x8699, 0xB10D, 0x869A, 0xB10E,
+	0x869B, 0xB10F, 0x869C, 0xB111, 0x869D, 0xB114, 0x869E, 0xB115,
+	0x869F, 0xB116, 0x86A0, 0xB117, 0x86A1, 0xB11A, 0x86A2, 0xB11E,
+	0x86A3, 0xB11F, 0x86A4, 0xB120, 0x86A5, 0xB121, 0x86A6, 0xB122,
+	0x86A7, 0xB126, 0x86A8, 0xB127, 0x86A9, 0xB129, 0x86AA, 0xB12A,
+	0x86AB, 0xB12B, 0x86AC, 0xB12D, 0x86AD, 0xB12E, 0x86AE, 0xB12F,
+	0x86AF, 0xB130, 0x86B0, 0xB131, 0x86B1, 0xB132, 0x86B2, 0xB133,
+	0x86B3, 0xB136, 0x86B4, 0xB13A, 0x86B5, 0xB13B, 0x86B6, 0xB13C,
+	0x86B7, 0xB13D, 0x86B8, 0xB13E, 0x86B9, 0xB13F, 0x86BA, 0xB142,
+	0x86BB, 0xB143, 0x86BC, 0xB145, 0x86BD, 0xB146, 0x86BE, 0xB147,
+	0x86BF, 0xB149, 0x86C0, 0xB14A, 0x86C1, 0xB14B, 0x86C2, 0xB14C,
+	0x86C3, 0xB14D, 0x86C4, 0xB14E, 0x86C5, 0xB14F, 0x86C6, 0xB152,
+	0x86C7, 0xB153, 0x86C8, 0xB156, 0x86C9, 0xB157, 0x86CA, 0xB159,
+	0x86CB, 0xB15A, 0x86CC, 0xB15B, 0x86CD, 0xB15D, 0x86CE, 0xB15E,
+	0x86CF, 0xB15F, 0x86D0, 0xB161, 0x86D1, 0xB162, 0x86D2, 0xB163,
+	0x86D3, 0xB164, 0x86D4, 0xB165, 0x86D5, 0xB166, 0x86D6, 0xB167,
+	0x86D7, 0xB168, 0x86D8, 0xB169, 0x86D9, 0xB16A, 0x86DA, 0xB16B,
+	0x86DB, 0xB16C, 0x86DC, 0xB16D, 0x86DD, 0xB16E, 0x86DE, 0xB16F,
+	0x86DF, 0xB170, 0x86E0, 0xB171, 0x86E1, 0xB172, 0x86E2, 0xB173,
+	0x86E3, 0xB174, 0x86E4, 0xB175, 0x86E5, 0xB176, 0x86E6, 0xB177,
+	0x86E7, 0xB17A, 0x86E8, 0xB17B, 0x86E9, 0xB17D, 0x86EA, 0xB17E,
+	0x86EB, 0xB17F, 0x86EC, 0xB181, 0x86ED, 0xB183, 0x86EE, 0xB184,
+	0x86EF, 0xB185, 0x86F0, 0xB186, 0x86F1, 0xB187, 0x86F2, 0xB18A,
+	0x86F3, 0xB18C, 0x86F4, 0xB18E, 0x86F5, 0xB18F, 0x86F6, 0xB190,
+	0x86F7, 0xB191, 0x86F8, 0xB195, 0x86F9, 0xB196, 0x86FA, 0xB197,
+	0x86FB, 0xB199, 0x86FC, 0xB19A, 0x86FD, 0xB19B, 0x86FE, 0xB19D,
+	0x8741, 0xB19E, 0x8742, 0xB19F, 0x8743, 0xB1A0, 0x8744, 0xB1A1,
+	0x8745, 0xB1A2, 0x8746, 0xB1A3, 0x8747, 0xB1A4, 0x8748, 0xB1A5,
+	0x8749, 0xB1A6, 0x874A, 0xB1A7, 0x874B, 0xB1A9, 0x874C, 0xB1AA,
+	0x874D, 0xB1AB, 0x874E, 0xB1AC, 0x874F, 0xB1AD, 0x8750, 0xB1AE,
+	0x8751, 0xB1AF, 0x8752, 0xB1B0, 0x8753, 0xB1B1, 0x8754, 0xB1B2,
+	0x8755, 0xB1B3, 0x8756, 0xB1B4, 0x8757, 0xB1B5, 0x8758, 0xB1B6,
+	0x8759, 0xB1B7, 0x875A, 0xB1B8, 0x8761, 0xB1B9, 0x8762, 0xB1BA,
+	0x8763, 0xB1BB, 0x8764, 0xB1BC, 0x8765, 0xB1BD, 0x8766, 0xB1BE,
+	0x8767, 0xB1BF, 0x8768, 0xB1C0, 0x8769, 0xB1C1, 0x876A, 0xB1C2,
+	0x876B, 0xB1C3, 0x876C, 0xB1C4, 0x876D, 0xB1C5, 0x876E, 0xB1C6,
+	0x876F, 0xB1C7, 0x8770, 0xB1C8, 0x8771, 0xB1C9, 0x8772, 0xB1CA,
+	0x8773, 0xB1CB, 0x8774, 0xB1CD, 0x8775, 0xB1CE, 0x8776, 0xB1CF,
+	0x8777, 0xB1D1, 0x8778, 0xB1D2, 0x8779, 0xB1D3, 0x877A, 0xB1D5,
+	0x8781, 0xB1D6, 0x8782, 0xB1D7, 0x8783, 0xB1D8, 0x8784, 0xB1D9,
+	0x8785, 0xB1DA, 0x8786, 0xB1DB, 0x8787, 0xB1DE, 0x8788, 0xB1E0,
+	0x8789, 0xB1E1, 0x878A, 0xB1E2, 0x878B, 0xB1E3, 0x878C, 0xB1E4,
+	0x878D, 0xB1E5, 0x878E, 0xB1E6, 0x878F, 0xB1E7, 0x8790, 0xB1EA,
+	0x8791, 0xB1EB, 0x8792, 0xB1ED, 0x8793, 0xB1EE, 0x8794, 0xB1EF,
+	0x8795, 0xB1F1, 0x8796, 0xB1F2, 0x8797, 0xB1F3, 0x8798, 0xB1F4,
+	0x8799, 0xB1F5, 0x879A, 0xB1F6, 0x879B, 0xB1F7, 0x879C, 0xB1F8,
+	0x879D, 0xB1FA, 0x879E, 0xB1FC, 0x879F, 0xB1FE, 0x87A0, 0xB1FF,
+	0x87A1, 0xB200, 0x87A2, 0xB201, 0x87A3, 0xB202, 0x87A4, 0xB203,
+	0x87A5, 0xB206, 0x87A6, 0xB207, 0x87A7, 0xB209, 0x87A8, 0xB20A,
+	0x87A9, 0xB20D, 0x87AA, 0xB20E, 0x87AB, 0xB20F, 0x87AC, 0xB210,
+	0x87AD, 0xB211, 0x87AE, 0xB212, 0x87AF, 0xB213, 0x87B0, 0xB216,
+	0x87B1, 0xB218, 0x87B2, 0xB21A, 0x87B3, 0xB21B, 0x87B4, 0xB21C,
+	0x87B5, 0xB21D, 0x87B6, 0xB21E, 0x87B7, 0xB21F, 0x87B8, 0xB221,
+	0x87B9, 0xB222, 0x87BA, 0xB223, 0x87BB, 0xB224, 0x87BC, 0xB225,
+	0x87BD, 0xB226, 0x87BE, 0xB227, 0x87BF, 0xB228, 0x87C0, 0xB229,
+	0x87C1, 0xB22A, 0x87C2, 0xB22B, 0x87C3, 0xB22C, 0x87C4, 0xB22D,
+	0x87C5, 0xB22E, 0x87C6, 0xB22F, 0x87C7, 0xB230, 0x87C8, 0xB231,
+	0x87C9, 0xB232, 0x87CA, 0xB233, 0x87CB, 0xB235, 0x87CC, 0xB236,
+	0x87CD, 0xB237, 0x87CE, 0xB238, 0x87CF, 0xB239, 0x87D0, 0xB23A,
+	0x87D1, 0xB23B, 0x87D2, 0xB23D, 0x87D3, 0xB23E, 0x87D4, 0xB23F,
+	0x87D5, 0xB240, 0x87D6, 0xB241, 0x87D7, 0xB242, 0x87D8, 0xB243,
+	0x87D9, 0xB244, 0x87DA, 0xB245, 0x87DB, 0xB246, 0x87DC, 0xB247,
+	0x87DD, 0xB248, 0x87DE, 0xB249, 0x87DF, 0xB24A, 0x87E0, 0xB24B,
+	0x87E1, 0xB24C, 0x87E2, 0xB24D, 0x87E3, 0xB24E, 0x87E4, 0xB24F,
+	0x87E5, 0xB250, 0x87E6, 0xB251, 0x87E7, 0xB252, 0x87E8, 0xB253,
+	0x87E9, 0xB254, 0x87EA, 0xB255, 0x87EB, 0xB256, 0x87EC, 0xB257,
+	0x87ED, 0xB259, 0x87EE, 0xB25A, 0x87EF, 0xB25B, 0x87F0, 0xB25D,
+	0x87F1, 0xB25E, 0x87F2, 0xB25F, 0x87F3, 0xB261, 0x87F4, 0xB262,
+	0x87F5, 0xB263, 0x87F6, 0xB264, 0x87F7, 0xB265, 0x87F8, 0xB266,
+	0x87F9, 0xB267, 0x87FA, 0xB26A, 0x87FB, 0xB26B, 0x87FC, 0xB26C,
+	0x87FD, 0xB26D, 0x87FE, 0xB26E, 0x8841, 0xB26F, 0x8842, 0xB270,
+	0x8843, 0xB271, 0x8844, 0xB272, 0x8845, 0xB273, 0x8846, 0xB276,
+	0x8847, 0xB277, 0x8848, 0xB278, 0x8849, 0xB279, 0x884A, 0xB27A,
+	0x884B, 0xB27B, 0x884C, 0xB27D, 0x884D, 0xB27E, 0x884E, 0xB27F,
+	0x884F, 0xB280, 0x8850, 0xB281, 0x8851, 0xB282, 0x8852, 0xB283,
+	0x8853, 0xB286, 0x8854, 0xB287, 0x8855, 0xB288, 0x8856, 0xB28A,
+	0x8857, 0xB28B, 0x8858, 0xB28C, 0x8859, 0xB28D, 0x885A, 0xB28E,
+	0x8861, 0xB28F, 0x8862, 0xB292, 0x8863, 0xB293, 0x8864, 0xB295,
+	0x8865, 0xB296, 0x8866, 0xB297, 0x8867, 0xB29B, 0x8868, 0xB29C,
+	0x8869, 0xB29D, 0x886A, 0xB29E, 0x886B, 0xB29F, 0x886C, 0xB2A2,
+	0x886D, 0xB2A4, 0x886E, 0xB2A7, 0x886F, 0xB2A8, 0x8870, 0xB2A9,
+	0x8871, 0xB2AB, 0x8872, 0xB2AD, 0x8873, 0xB2AE, 0x8874, 0xB2AF,
+	0x8875, 0xB2B1, 0x8876, 0xB2B2, 0x8877, 0xB2B3, 0x8878, 0xB2B5,
+	0x8879, 0xB2B6, 0x887A, 0xB2B7, 0x8881, 0xB2B8, 0x8882, 0xB2B9,
+	0x8883, 0xB2BA, 0x8884, 0xB2BB, 0x8885, 0xB2BC, 0x8886, 0xB2BD,
+	0x8887, 0xB2BE, 0x8888, 0xB2BF, 0x8889, 0xB2C0, 0x888A, 0xB2C1,
+	0x888B, 0xB2C2, 0x888C, 0xB2C3, 0x888D, 0xB2C4, 0x888E, 0xB2C5,
+	0x888F, 0xB2C6, 0x8890, 0xB2C7, 0x8891, 0xB2CA, 0x8892, 0xB2CB,
+	0x8893, 0xB2CD, 0x8894, 0xB2CE, 0x8895, 0xB2CF, 0x8896, 0xB2D1,
+	0x8897, 0xB2D3, 0x8898, 0xB2D4, 0x8899, 0xB2D5, 0x889A, 0xB2D6,
+	0x889B, 0xB2D7, 0x889C, 0xB2DA, 0x889D, 0xB2DC, 0x889E, 0xB2DE,
+	0x889F, 0xB2DF, 0x88A0, 0xB2E0, 0x88A1, 0xB2E1, 0x88A2, 0xB2E3,
+	0x88A3, 0xB2E7, 0x88A4, 0xB2E9, 0x88A5, 0xB2EA, 0x88A6, 0xB2F0,
+	0x88A7, 0xB2F1, 0x88A8, 0xB2F2, 0x88A9, 0xB2F6, 0x88AA, 0xB2FC,
+	0x88AB, 0xB2FD, 0x88AC, 0xB2FE, 0x88AD, 0xB302, 0x88AE, 0xB303,
+	0x88AF, 0xB305, 0x88B0, 0xB306, 0x88B1, 0xB307, 0x88B2, 0xB309,
+	0x88B3, 0xB30A, 0x88B4, 0xB30B, 0x88B5, 0xB30C, 0x88B6, 0xB30D,
+	0x88B7, 0xB30E, 0x88B8, 0xB30F, 0x88B9, 0xB312, 0x88BA, 0xB316,
+	0x88BB, 0xB317, 0x88BC, 0xB318, 0x88BD, 0xB319, 0x88BE, 0xB31A,
+	0x88BF, 0xB31B, 0x88C0, 0xB31D, 0x88C1, 0xB31E, 0x88C2, 0xB31F,
+	0x88C3, 0xB320, 0x88C4, 0xB321, 0x88C5, 0xB322, 0x88C6, 0xB323,
+	0x88C7, 0xB324, 0x88C8, 0xB325, 0x88C9, 0xB326, 0x88CA, 0xB327,
+	0x88CB, 0xB328, 0x88CC, 0xB329, 0x88CD, 0xB32A, 0x88CE, 0xB32B,
+	0x88CF, 0xB32C, 0x88D0, 0xB32D, 0x88D1, 0xB32E, 0x88D2, 0xB32F,
+	0x88D3, 0xB330, 0x88D4, 0xB331, 0x88D5, 0xB332, 0x88D6, 0xB333,
+	0x88D7, 0xB334, 0x88D8, 0xB335, 0x88D9, 0xB336, 0x88DA, 0xB337,
+	0x88DB, 0xB338, 0x88DC, 0xB339, 0x88DD, 0xB33A, 0x88DE, 0xB33B,
+	0x88DF, 0xB33C, 0x88E0, 0xB33D, 0x88E1, 0xB33E, 0x88E2, 0xB33F,
+	0x88E3, 0xB340, 0x88E4, 0xB341, 0x88E5, 0xB342, 0x88E6, 0xB343,
+	0x88E7, 0xB344, 0x88E8, 0xB345, 0x88E9, 0xB346, 0x88EA, 0xB347,
+	0x88EB, 0xB348, 0x88EC, 0xB349, 0x88ED, 0xB34A, 0x88EE, 0xB34B,
+	0x88EF, 0xB34C, 0x88F0, 0xB34D, 0x88F1, 0xB34E, 0x88F2, 0xB34F,
+	0x88F3, 0xB350, 0x88F4, 0xB351, 0x88F5, 0xB352, 0x88F6, 0xB353,
+	0x88F7, 0xB357, 0x88F8, 0xB359, 0x88F9, 0xB35A, 0x88FA, 0xB35D,
+	0x88FB, 0xB360, 0x88FC, 0xB361, 0x88FD, 0xB362, 0x88FE, 0xB363,
+	0x8941, 0xB366, 0x8942, 0xB368, 0x8943, 0xB36A, 0x8944, 0xB36C,
+	0x8945, 0xB36D, 0x8946, 0xB36F, 0x8947, 0xB372, 0x8948, 0xB373,
+	0x8949, 0xB375, 0x894A, 0xB376, 0x894B, 0xB377, 0x894C, 0xB379,
+	0x894D, 0xB37A, 0x894E, 0xB37B, 0x894F, 0xB37C, 0x8950, 0xB37D,
+	0x8951, 0xB37E, 0x8952, 0xB37F, 0x8953, 0xB382, 0x8954, 0xB386,
+	0x8955, 0xB387, 0x8956, 0xB388, 0x8957, 0xB389, 0x8958, 0xB38A,
+	0x8959, 0xB38B, 0x895A, 0xB38D, 0x8961, 0xB38E, 0x8962, 0xB38F,
+	0x8963, 0xB391, 0x8964, 0xB392, 0x8965, 0xB393, 0x8966, 0xB395,
+	0x8967, 0xB396, 0x8968, 0xB397, 0x8969, 0xB398, 0x896A, 0xB399,
+	0x896B, 0xB39A, 0x896C, 0xB39B, 0x896D, 0xB39C, 0x896E, 0xB39D,
+	0x896F, 0xB39E, 0x8970, 0xB39F, 0x8971, 0xB3A2, 0x8972, 0xB3A3,
+	0x8973, 0xB3A4, 0x8974, 0xB3A5, 0x8975, 0xB3A6, 0x8976, 0xB3A7,
+	0x8977, 0xB3A9, 0x8978, 0xB3AA, 0x8979, 0xB3AB, 0x897A, 0xB3AD,
+	0x8981, 0xB3AE, 0x8982, 0xB3AF, 0x8983, 0xB3B0, 0x8984, 0xB3B1,
+	0x8985, 0xB3B2, 0x8986, 0xB3B3, 0x8987, 0xB3B4, 0x8988, 0xB3B5,
+	0x8989, 0xB3B6, 0x898A, 0xB3B7, 0x898B, 0xB3B8, 0x898C, 0xB3B9,
+	0x898D, 0xB3BA, 0x898E, 0xB3BB, 0x898F, 0xB3BC, 0x8990, 0xB3BD,
+	0x8991, 0xB3BE, 0x8992, 0xB3BF, 0x8993, 0xB3C0, 0x8994, 0xB3C1,
+	0x8995, 0xB3C2, 0x8996, 0xB3C3, 0x8997, 0xB3C6, 0x8998, 0xB3C7,
+	0x8999, 0xB3C9, 0x899A, 0xB3CA, 0x899B, 0xB3CD, 0x899C, 0xB3CF,
+	0x899D, 0xB3D1, 0x899E, 0xB3D2, 0x899F, 0xB3D3, 0x89A0, 0xB3D6,
+	0x89A1, 0xB3D8, 0x89A2, 0xB3DA, 0x89A3, 0xB3DC, 0x89A4, 0xB3DE,
+	0x89A5, 0xB3DF, 0x89A6, 0xB3E1, 0x89A7, 0xB3E2, 0x89A8, 0xB3E3,
+	0x89A9, 0xB3E5, 0x89AA, 0xB3E6, 0x89AB, 0xB3E7, 0x89AC, 0xB3E9,
+	0x89AD, 0xB3EA, 0x89AE, 0xB3EB, 0x89AF, 0xB3EC, 0x89B0, 0xB3ED,
+	0x89B1, 0xB3EE, 0x89B2, 0xB3EF, 0x89B3, 0xB3F0, 0x89B4, 0xB3F1,
+	0x89B5, 0xB3F2, 0x89B6, 0xB3F3, 0x89B7, 0xB3F4, 0x89B8, 0xB3F5,
+	0x89B9, 0xB3F6, 0x89BA, 0xB3F7, 0x89BB, 0xB3F8, 0x89BC, 0xB3F9,
+	0x89BD, 0xB3FA, 0x89BE, 0xB3FB, 0x89BF, 0xB3FD, 0x89C0, 0xB3FE,
+	0x89C1, 0xB3FF, 0x89C2, 0xB400, 0x89C3, 0xB401, 0x89C4, 0xB402,
+	0x89C5, 0xB403, 0x89C6, 0xB404, 0x89C7, 0xB405, 0x89C8, 0xB406,
+	0x89C9, 0xB407, 0x89CA, 0xB408, 0x89CB, 0xB409, 0x89CC, 0xB40A,
+	0x89CD, 0xB40B, 0x89CE, 0xB40C, 0x89CF, 0xB40D, 0x89D0, 0xB40E,
+	0x89D1, 0xB40F, 0x89D2, 0xB411, 0x89D3, 0xB412, 0x89D4, 0xB413,
+	0x89D5, 0xB414, 0x89D6, 0xB415, 0x89D7, 0xB416, 0x89D8, 0xB417,
+	0x89D9, 0xB419, 0x89DA, 0xB41A, 0x89DB, 0xB41B, 0x89DC, 0xB41D,
+	0x89DD, 0xB41E, 0x89DE, 0xB41F, 0x89DF, 0xB421, 0x89E0, 0xB422,
+	0x89E1, 0xB423, 0x89E2, 0xB424, 0x89E3, 0xB425, 0x89E4, 0xB426,
+	0x89E5, 0xB427, 0x89E6, 0xB42A, 0x89E7, 0xB42C, 0x89E8, 0xB42D,
+	0x89E9, 0xB42E, 0x89EA, 0xB42F, 0x89EB, 0xB430, 0x89EC, 0xB431,
+	0x89ED, 0xB432, 0x89EE, 0xB433, 0x89EF, 0xB435, 0x89F0, 0xB436,
+	0x89F1, 0xB437, 0x89F2, 0xB438, 0x89F3, 0xB439, 0x89F4, 0xB43A,
+	0x89F5, 0xB43B, 0x89F6, 0xB43C, 0x89F7, 0xB43D, 0x89F8, 0xB43E,
+	0x89F9, 0xB43F, 0x89FA, 0xB440, 0x89FB, 0xB441, 0x89FC, 0xB442,
+	0x89FD, 0xB443, 0x89FE, 0xB444, 0x8A41, 0xB445, 0x8A42, 0xB446,
+	0x8A43, 0xB447, 0x8A44, 0xB448, 0x8A45, 0xB449, 0x8A46, 0xB44A,
+	0x8A47, 0xB44B, 0x8A48, 0xB44C, 0x8A49, 0xB44D, 0x8A4A, 0xB44E,
+	0x8A4B, 0xB44F, 0x8A4C, 0xB452, 0x8A4D, 0xB453, 0x8A4E, 0xB455,
+	0x8A4F, 0xB456, 0x8A50, 0xB457, 0x8A51, 0xB459, 0x8A52, 0xB45A,
+	0x8A53, 0xB45B, 0x8A54, 0xB45C, 0x8A55, 0xB45D, 0x8A56, 0xB45E,
+	0x8A57, 0xB45F, 0x8A58, 0xB462, 0x8A59, 0xB464, 0x8A5A, 0xB466,
+	0x8A61, 0xB467, 0x8A62, 0xB468, 0x8A63, 0xB469, 0x8A64, 0xB46A,
+	0x8A65, 0xB46B, 0x8A66, 0xB46D, 0x8A67, 0xB46E, 0x8A68, 0xB46F,
+	0x8A69, 0xB470, 0x8A6A, 0xB471, 0x8A6B, 0xB472, 0x8A6C, 0xB473,
+	0x8A6D, 0xB474, 0x8A6E, 0xB475, 0x8A6F, 0xB476, 0x8A70, 0xB477,
+	0x8A71, 0xB478, 0x8A72, 0xB479, 0x8A73, 0xB47A, 0x8A74, 0xB47B,
+	0x8A75, 0xB47C, 0x8A76, 0xB47D, 0x8A77, 0xB47E, 0x8A78, 0xB47F,
+	0x8A79, 0xB481, 0x8A7A, 0xB482, 0x8A81, 0xB483, 0x8A82, 0xB484,
+	0x8A83, 0xB485, 0x8A84, 0xB486, 0x8A85, 0xB487, 0x8A86, 0xB489,
+	0x8A87, 0xB48A, 0x8A88, 0xB48B, 0x8A89, 0xB48C, 0x8A8A, 0xB48D,
+	0x8A8B, 0xB48E, 0x8A8C, 0xB48F, 0x8A8D, 0xB490, 0x8A8E, 0xB491,
+	0x8A8F, 0xB492, 0x8A90, 0xB493, 0x8A91, 0xB494, 0x8A92, 0xB495,
+	0x8A93, 0xB496, 0x8A94, 0xB497, 0x8A95, 0xB498, 0x8A96, 0xB499,
+	0x8A97, 0xB49A, 0x8A98, 0xB49B, 0x8A99, 0xB49C, 0x8A9A, 0xB49E,
+	0x8A9B, 0xB49F, 0x8A9C, 0xB4A0, 0x8A9D, 0xB4A1, 0x8A9E, 0xB4A2,
+	0x8A9F, 0xB4A3, 0x8AA0, 0xB4A5, 0x8AA1, 0xB4A6, 0x8AA2, 0xB4A7,
+	0x8AA3, 0xB4A9, 0x8AA4, 0xB4AA, 0x8AA5, 0xB4AB, 0x8AA6, 0xB4AD,
+	0x8AA7, 0xB4AE, 0x8AA8, 0xB4AF, 0x8AA9, 0xB4B0, 0x8AAA, 0xB4B1,
+	0x8AAB, 0xB4B2, 0x8AAC, 0xB4B3, 0x8AAD, 0xB4B4, 0x8AAE, 0xB4B6,
+	0x8AAF, 0xB4B8, 0x8AB0, 0xB4BA, 0x8AB1, 0xB4BB, 0x8AB2, 0xB4BC,
+	0x8AB3, 0xB4BD, 0x8AB4, 0xB4BE, 0x8AB5, 0xB4BF, 0x8AB6, 0xB4C1,
+	0x8AB7, 0xB4C2, 0x8AB8, 0xB4C3, 0x8AB9, 0xB4C5, 0x8ABA, 0xB4C6,
+	0x8ABB, 0xB4C7, 0x8ABC, 0xB4C9, 0x8ABD, 0xB4CA, 0x8ABE, 0xB4CB,
+	0x8ABF, 0xB4CC, 0x8AC0, 0xB4CD, 0x8AC1, 0xB4CE, 0x8AC2, 0xB4CF,
+	0x8AC3, 0xB4D1, 0x8AC4, 0xB4D2, 0x8AC5, 0xB4D3, 0x8AC6, 0xB4D4,
+	0x8AC7, 0xB4D6, 0x8AC8, 0xB4D7, 0x8AC9, 0xB4D8, 0x8ACA, 0xB4D9,
+	0x8ACB, 0xB4DA, 0x8ACC, 0xB4DB, 0x8ACD, 0xB4DE, 0x8ACE, 0xB4DF,
+	0x8ACF, 0xB4E1, 0x8AD0, 0xB4E2, 0x8AD1, 0xB4E5, 0x8AD2, 0xB4E7,
+	0x8AD3, 0xB4E8, 0x8AD4, 0xB4E9, 0x8AD5, 0xB4EA, 0x8AD6, 0xB4EB,
+	0x8AD7, 0xB4EE, 0x8AD8, 0xB4F0, 0x8AD9, 0xB4F2, 0x8ADA, 0xB4F3,
+	0x8ADB, 0xB4F4, 0x8ADC, 0xB4F5, 0x8ADD, 0xB4F6, 0x8ADE, 0xB4F7,
+	0x8ADF, 0xB4F9, 0x8AE0, 0xB4FA, 0x8AE1, 0xB4FB, 0x8AE2, 0xB4FC,
+	0x8AE3, 0xB4FD, 0x8AE4, 0xB4FE, 0x8AE5, 0xB4FF, 0x8AE6, 0xB500,
+	0x8AE7, 0xB501, 0x8AE8, 0xB502, 0x8AE9, 0xB503, 0x8AEA, 0xB504,
+	0x8AEB, 0xB505, 0x8AEC, 0xB506, 0x8AED, 0xB507, 0x8AEE, 0xB508,
+	0x8AEF, 0xB509, 0x8AF0, 0xB50A, 0x8AF1, 0xB50B, 0x8AF2, 0xB50C,
+	0x8AF3, 0xB50D, 0x8AF4, 0xB50E, 0x8AF5, 0xB50F, 0x8AF6, 0xB510,
+	0x8AF7, 0xB511, 0x8AF8, 0xB512, 0x8AF9, 0xB513, 0x8AFA, 0xB516,
+	0x8AFB, 0xB517, 0x8AFC, 0xB519, 0x8AFD, 0xB51A, 0x8AFE, 0xB51D,
+	0x8B41, 0xB51E, 0x8B42, 0xB51F, 0x8B43, 0xB520, 0x8B44, 0xB521,
+	0x8B45, 0xB522, 0x8B46, 0xB523, 0x8B47, 0xB526, 0x8B48, 0xB52B,
+	0x8B49, 0xB52C, 0x8B4A, 0xB52D, 0x8B4B, 0xB52E, 0x8B4C, 0xB52F,
+	0x8B4D, 0xB532, 0x8B4E, 0xB533, 0x8B4F, 0xB535, 0x8B50, 0xB536,
+	0x8B51, 0xB537, 0x8B52, 0xB539, 0x8B53, 0xB53A, 0x8B54, 0xB53B,
+	0x8B55, 0xB53C, 0x8B56, 0xB53D, 0x8B57, 0xB53E, 0x8B58, 0xB53F,
+	0x8B59, 0xB542, 0x8B5A, 0xB546, 0x8B61, 0xB547, 0x8B62, 0xB548,
+	0x8B63, 0xB549, 0x8B64, 0xB54A, 0x8B65, 0xB54E, 0x8B66, 0xB54F,
+	0x8B67, 0xB551, 0x8B68, 0xB552, 0x8B69, 0xB553, 0x8B6A, 0xB555,
+	0x8B6B, 0xB556, 0x8B6C, 0xB557, 0x8B6D, 0xB558, 0x8B6E, 0xB559,
+	0x8B6F, 0xB55A, 0x8B70, 0xB55B, 0x8B71, 0xB55E, 0x8B72, 0xB562,
+	0x8B73, 0xB563, 0x8B74, 0xB564, 0x8B75, 0xB565, 0x8B76, 0xB566,
+	0x8B77, 0xB567, 0x8B78, 0xB568, 0x8B79, 0xB569, 0x8B7A, 0xB56A,
+	0x8B81, 0xB56B, 0x8B82, 0xB56C, 0x8B83, 0xB56D, 0x8B84, 0xB56E,
+	0x8B85, 0xB56F, 0x8B86, 0xB570, 0x8B87, 0xB571, 0x8B88, 0xB572,
+	0x8B89, 0xB573, 0x8B8A, 0xB574, 0x8B8B, 0xB575, 0x8B8C, 0xB576,
+	0x8B8D, 0xB577, 0x8B8E, 0xB578, 0x8B8F, 0xB579, 0x8B90, 0xB57A,
+	0x8B91, 0xB57B, 0x8B92, 0xB57C, 0x8B93, 0xB57D, 0x8B94, 0xB57E,
+	0x8B95, 0xB57F, 0x8B96, 0xB580, 0x8B97, 0xB581, 0x8B98, 0xB582,
+	0x8B99, 0xB583, 0x8B9A, 0xB584, 0x8B9B, 0xB585, 0x8B9C, 0xB586,
+	0x8B9D, 0xB587, 0x8B9E, 0xB588, 0x8B9F, 0xB589, 0x8BA0, 0xB58A,
+	0x8BA1, 0xB58B, 0x8BA2, 0xB58C, 0x8BA3, 0xB58D, 0x8BA4, 0xB58E,
+	0x8BA5, 0xB58F, 0x8BA6, 0xB590, 0x8BA7, 0xB591, 0x8BA8, 0xB592,
+	0x8BA9, 0xB593, 0x8BAA, 0xB594, 0x8BAB, 0xB595, 0x8BAC, 0xB596,
+	0x8BAD, 0xB597, 0x8BAE, 0xB598, 0x8BAF, 0xB599, 0x8BB0, 0xB59A,
+	0x8BB1, 0xB59B, 0x8BB2, 0xB59C, 0x8BB3, 0xB59D, 0x8BB4, 0xB59E,
+	0x8BB5, 0xB59F, 0x8BB6, 0xB5A2, 0x8BB7, 0xB5A3, 0x8BB8, 0xB5A5,
+	0x8BB9, 0xB5A6, 0x8BBA, 0xB5A7, 0x8BBB, 0xB5A9, 0x8BBC, 0xB5AC,
+	0x8BBD, 0xB5AD, 0x8BBE, 0xB5AE, 0x8BBF, 0xB5AF, 0x8BC0, 0xB5B2,
+	0x8BC1, 0xB5B6, 0x8BC2, 0xB5B7, 0x8BC3, 0xB5B8, 0x8BC4, 0xB5B9,
+	0x8BC5, 0xB5BA, 0x8BC6, 0xB5BE, 0x8BC7, 0xB5BF, 0x8BC8, 0xB5C1,
+	0x8BC9, 0xB5C2, 0x8BCA, 0xB5C3, 0x8BCB, 0xB5C5, 0x8BCC, 0xB5C6,
+	0x8BCD, 0xB5C7, 0x8BCE, 0xB5C8, 0x8BCF, 0xB5C9, 0x8BD0, 0xB5CA,
+	0x8BD1, 0xB5CB, 0x8BD2, 0xB5CE, 0x8BD3, 0xB5D2, 0x8BD4, 0xB5D3,
+	0x8BD5, 0xB5D4, 0x8BD6, 0xB5D5, 0x8BD7, 0xB5D6, 0x8BD8, 0xB5D7,
+	0x8BD9, 0xB5D9, 0x8BDA, 0xB5DA, 0x8BDB, 0xB5DB, 0x8BDC, 0xB5DC,
+	0x8BDD, 0xB5DD, 0x8BDE, 0xB5DE, 0x8BDF, 0xB5DF, 0x8BE0, 0xB5E0,
+	0x8BE1, 0xB5E1, 0x8BE2, 0xB5E2, 0x8BE3, 0xB5E3, 0x8BE4, 0xB5E4,
+	0x8BE5, 0xB5E5, 0x8BE6, 0xB5E6, 0x8BE7, 0xB5E7, 0x8BE8, 0xB5E8,
+	0x8BE9, 0xB5E9, 0x8BEA, 0xB5EA, 0x8BEB, 0xB5EB, 0x8BEC, 0xB5ED,
+	0x8BED, 0xB5EE, 0x8BEE, 0xB5EF, 0x8BEF, 0xB5F0, 0x8BF0, 0xB5F1,
+	0x8BF1, 0xB5F2, 0x8BF2, 0xB5F3, 0x8BF3, 0xB5F4, 0x8BF4, 0xB5F5,
+	0x8BF5, 0xB5F6, 0x8BF6, 0xB5F7, 0x8BF7, 0xB5F8, 0x8BF8, 0xB5F9,
+	0x8BF9, 0xB5FA, 0x8BFA, 0xB5FB, 0x8BFB, 0xB5FC, 0x8BFC, 0xB5FD,
+	0x8BFD, 0xB5FE, 0x8BFE, 0xB5FF, 0x8C41, 0xB600, 0x8C42, 0xB601,
+	0x8C43, 0xB602, 0x8C44, 0xB603, 0x8C45, 0xB604, 0x8C46, 0xB605,
+	0x8C47, 0xB606, 0x8C48, 0xB607, 0x8C49, 0xB608, 0x8C4A, 0xB609,
+	0x8C4B, 0xB60A, 0x8C4C, 0xB60B, 0x8C4D, 0xB60C, 0x8C4E, 0xB60D,
+	0x8C4F, 0xB60E, 0x8C50, 0xB60F, 0x8C51, 0xB612, 0x8C52, 0xB613,
+	0x8C53, 0xB615, 0x8C54, 0xB616, 0x8C55, 0xB617, 0x8C56, 0xB619,
+	0x8C57, 0xB61A, 0x8C58, 0xB61B, 0x8C59, 0xB61C, 0x8C5A, 0xB61D,
+	0x8C61, 0xB61E, 0x8C62, 0xB61F, 0x8C63, 0xB620, 0x8C64, 0xB621,
+	0x8C65, 0xB622, 0x8C66, 0xB623, 0x8C67, 0xB624, 0x8C68, 0xB626,
+	0x8C69, 0xB627, 0x8C6A, 0xB628, 0x8C6B, 0xB629, 0x8C6C, 0xB62A,
+	0x8C6D, 0xB62B, 0x8C6E, 0xB62D, 0x8C6F, 0xB62E, 0x8C70, 0xB62F,
+	0x8C71, 0xB630, 0x8C72, 0xB631, 0x8C73, 0xB632, 0x8C74, 0xB633,
+	0x8C75, 0xB635, 0x8C76, 0xB636, 0x8C77, 0xB637, 0x8C78, 0xB638,
+	0x8C79, 0xB639, 0x8C7A, 0xB63A, 0x8C81, 0xB63B, 0x8C82, 0xB63C,
+	0x8C83, 0xB63D, 0x8C84, 0xB63E, 0x8C85, 0xB63F, 0x8C86, 0xB640,
+	0x8C87, 0xB641, 0x8C88, 0xB642, 0x8C89, 0xB643, 0x8C8A, 0xB644,
+	0x8C8B, 0xB645, 0x8C8C, 0xB646, 0x8C8D, 0xB647, 0x8C8E, 0xB649,
+	0x8C8F, 0xB64A, 0x8C90, 0xB64B, 0x8C91, 0xB64C, 0x8C92, 0xB64D,
+	0x8C93, 0xB64E, 0x8C94, 0xB64F, 0x8C95, 0xB650, 0x8C96, 0xB651,
+	0x8C97, 0xB652, 0x8C98, 0xB653, 0x8C99, 0xB654, 0x8C9A, 0xB655,
+	0x8C9B, 0xB656, 0x8C9C, 0xB657, 0x8C9D, 0xB658, 0x8C9E, 0xB659,
+	0x8C9F, 0xB65A, 0x8CA0, 0xB65B, 0x8CA1, 0xB65C, 0x8CA2, 0xB65D,
+	0x8CA3, 0xB65E, 0x8CA4, 0xB65F, 0x8CA5, 0xB660, 0x8CA6, 0xB661,
+	0x8CA7, 0xB662, 0x8CA8, 0xB663, 0x8CA9, 0xB665, 0x8CAA, 0xB666,
+	0x8CAB, 0xB667, 0x8CAC, 0xB669, 0x8CAD, 0xB66A, 0x8CAE, 0xB66B,
+	0x8CAF, 0xB66C, 0x8CB0, 0xB66D, 0x8CB1, 0xB66E, 0x8CB2, 0xB66F,
+	0x8CB3, 0xB670, 0x8CB4, 0xB671, 0x8CB5, 0xB672, 0x8CB6, 0xB673,
+	0x8CB7, 0xB674, 0x8CB8, 0xB675, 0x8CB9, 0xB676, 0x8CBA, 0xB677,
+	0x8CBB, 0xB678, 0x8CBC, 0xB679, 0x8CBD, 0xB67A, 0x8CBE, 0xB67B,
+	0x8CBF, 0xB67C, 0x8CC0, 0xB67D, 0x8CC1, 0xB67E, 0x8CC2, 0xB67F,
+	0x8CC3, 0xB680, 0x8CC4, 0xB681, 0x8CC5, 0xB682, 0x8CC6, 0xB683,
+	0x8CC7, 0xB684, 0x8CC8, 0xB685, 0x8CC9, 0xB686, 0x8CCA, 0xB687,
+	0x8CCB, 0xB688, 0x8CCC, 0xB689, 0x8CCD, 0xB68A, 0x8CCE, 0xB68B,
+	0x8CCF, 0xB68C, 0x8CD0, 0xB68D, 0x8CD1, 0xB68E, 0x8CD2, 0xB68F,
+	0x8CD3, 0xB690, 0x8CD4, 0xB691, 0x8CD5, 0xB692, 0x8CD6, 0xB693,
+	0x8CD7, 0xB694, 0x8CD8, 0xB695, 0x8CD9, 0xB696, 0x8CDA, 0xB697,
+	0x8CDB, 0xB698, 0x8CDC, 0xB699, 0x8CDD, 0xB69A, 0x8CDE, 0xB69B,
+	0x8CDF, 0xB69E, 0x8CE0, 0xB69F, 0x8CE1, 0xB6A1, 0x8CE2, 0xB6A2,
+	0x8CE3, 0xB6A3, 0x8CE4, 0xB6A5, 0x8CE5, 0xB6A6, 0x8CE6, 0xB6A7,
+	0x8CE7, 0xB6A8, 0x8CE8, 0xB6A9, 0x8CE9, 0xB6AA, 0x8CEA, 0xB6AD,
+	0x8CEB, 0xB6AE, 0x8CEC, 0xB6AF, 0x8CED, 0xB6B0, 0x8CEE, 0xB6B2,
+	0x8CEF, 0xB6B3, 0x8CF0, 0xB6B4, 0x8CF1, 0xB6B5, 0x8CF2, 0xB6B6,
+	0x8CF3, 0xB6B7, 0x8CF4, 0xB6B8, 0x8CF5, 0xB6B9, 0x8CF6, 0xB6BA,
+	0x8CF7, 0xB6BB, 0x8CF8, 0xB6BC, 0x8CF9, 0xB6BD, 0x8CFA, 0xB6BE,
+	0x8CFB, 0xB6BF, 0x8CFC, 0xB6C0, 0x8CFD, 0xB6C1, 0x8CFE, 0xB6C2,
+	0x8D41, 0xB6C3, 0x8D42, 0xB6C4, 0x8D43, 0xB6C5, 0x8D44, 0xB6C6,
+	0x8D45, 0xB6C7, 0x8D46, 0xB6C8, 0x8D47, 0xB6C9, 0x8D48, 0xB6CA,
+	0x8D49, 0xB6CB, 0x8D4A, 0xB6CC, 0x8D4B, 0xB6CD, 0x8D4C, 0xB6CE,
+	0x8D4D, 0xB6CF, 0x8D4E, 0xB6D0, 0x8D4F, 0xB6D1, 0x8D50, 0xB6D2,
+	0x8D51, 0xB6D3, 0x8D52, 0xB6D5, 0x8D53, 0xB6D6, 0x8D54, 0xB6D7,
+	0x8D55, 0xB6D8, 0x8D56, 0xB6D9, 0x8D57, 0xB6DA, 0x8D58, 0xB6DB,
+	0x8D59, 0xB6DC, 0x8D5A, 0xB6DD, 0x8D61, 0xB6DE, 0x8D62, 0xB6DF,
+	0x8D63, 0xB6E0, 0x8D64, 0xB6E1, 0x8D65, 0xB6E2, 0x8D66, 0xB6E3,
+	0x8D67, 0xB6E4, 0x8D68, 0xB6E5, 0x8D69, 0xB6E6, 0x8D6A, 0xB6E7,
+	0x8D6B, 0xB6E8, 0x8D6C, 0xB6E9, 0x8D6D, 0xB6EA, 0x8D6E, 0xB6EB,
+	0x8D6F, 0xB6EC, 0x8D70, 0xB6ED, 0x8D71, 0xB6EE, 0x8D72, 0xB6EF,
+	0x8D73, 0xB6F1, 0x8D74, 0xB6F2, 0x8D75, 0xB6F3, 0x8D76, 0xB6F5,
+	0x8D77, 0xB6F6, 0x8D78, 0xB6F7, 0x8D79, 0xB6F9, 0x8D7A, 0xB6FA,
+	0x8D81, 0xB6FB, 0x8D82, 0xB6FC, 0x8D83, 0xB6FD, 0x8D84, 0xB6FE,
+	0x8D85, 0xB6FF, 0x8D86, 0xB702, 0x8D87, 0xB703, 0x8D88, 0xB704,
+	0x8D89, 0xB706, 0x8D8A, 0xB707, 0x8D8B, 0xB708, 0x8D8C, 0xB709,
+	0x8D8D, 0xB70A, 0x8D8E, 0xB70B, 0x8D8F, 0xB70C, 0x8D90, 0xB70D,
+	0x8D91, 0xB70E, 0x8D92, 0xB70F, 0x8D93, 0xB710, 0x8D94, 0xB711,
+	0x8D95, 0xB712, 0x8D96, 0xB713, 0x8D97, 0xB714, 0x8D98, 0xB715,
+	0x8D99, 0xB716, 0x8D9A, 0xB717, 0x8D9B, 0xB718, 0x8D9C, 0xB719,
+	0x8D9D, 0xB71A, 0x8D9E, 0xB71B, 0x8D9F, 0xB71C, 0x8DA0, 0xB71D,
+	0x8DA1, 0xB71E, 0x8DA2, 0xB71F, 0x8DA3, 0xB720, 0x8DA4, 0xB721,
+	0x8DA5, 0xB722, 0x8DA6, 0xB723, 0x8DA7, 0xB724, 0x8DA8, 0xB725,
+	0x8DA9, 0xB726, 0x8DAA, 0xB727, 0x8DAB, 0xB72A, 0x8DAC, 0xB72B,
+	0x8DAD, 0xB72D, 0x8DAE, 0xB72E, 0x8DAF, 0xB731, 0x8DB0, 0xB732,
+	0x8DB1, 0xB733, 0x8DB2, 0xB734, 0x8DB3, 0xB735, 0x8DB4, 0xB736,
+	0x8DB5, 0xB737, 0x8DB6, 0xB73A, 0x8DB7, 0xB73C, 0x8DB8, 0xB73D,
+	0x8DB9, 0xB73E, 0x8DBA, 0xB73F, 0x8DBB, 0xB740, 0x8DBC, 0xB741,
+	0x8DBD, 0xB742, 0x8DBE, 0xB743, 0x8DBF, 0xB745, 0x8DC0, 0xB746,
+	0x8DC1, 0xB747, 0x8DC2, 0xB749, 0x8DC3, 0xB74A, 0x8DC4, 0xB74B,
+	0x8DC5, 0xB74D, 0x8DC6, 0xB74E, 0x8DC7, 0xB74F, 0x8DC8, 0xB750,
+	0x8DC9, 0xB751, 0x8DCA, 0xB752, 0x8DCB, 0xB753, 0x8DCC, 0xB756,
+	0x8DCD, 0xB757, 0x8DCE, 0xB758, 0x8DCF, 0xB759, 0x8DD0, 0xB75A,
+	0x8DD1, 0xB75B, 0x8DD2, 0xB75C, 0x8DD3, 0xB75D, 0x8DD4, 0xB75E,
+	0x8DD5, 0xB75F, 0x8DD6, 0xB761, 0x8DD7, 0xB762, 0x8DD8, 0xB763,
+	0x8DD9, 0xB765, 0x8DDA, 0xB766, 0x8DDB, 0xB767, 0x8DDC, 0xB769,
+	0x8DDD, 0xB76A, 0x8DDE, 0xB76B, 0x8DDF, 0xB76C, 0x8DE0, 0xB76D,
+	0x8DE1, 0xB76E, 0x8DE2, 0xB76F, 0x8DE3, 0xB772, 0x8DE4, 0xB774,
+	0x8DE5, 0xB776, 0x8DE6, 0xB777, 0x8DE7, 0xB778, 0x8DE8, 0xB779,
+	0x8DE9, 0xB77A, 0x8DEA, 0xB77B, 0x8DEB, 0xB77E, 0x8DEC, 0xB77F,
+	0x8DED, 0xB781, 0x8DEE, 0xB782, 0x8DEF, 0xB783, 0x8DF0, 0xB785,
+	0x8DF1, 0xB786, 0x8DF2, 0xB787, 0x8DF3, 0xB788, 0x8DF4, 0xB789,
+	0x8DF5, 0xB78A, 0x8DF6, 0xB78B, 0x8DF7, 0xB78E, 0x8DF8, 0xB793,
+	0x8DF9, 0xB794, 0x8DFA, 0xB795, 0x8DFB, 0xB79A, 0x8DFC, 0xB79B,
+	0x8DFD, 0xB79D, 0x8DFE, 0xB79E, 0x8E41, 0xB79F, 0x8E42, 0xB7A1,
+	0x8E43, 0xB7A2, 0x8E44, 0xB7A3, 0x8E45, 0xB7A4, 0x8E46, 0xB7A5,
+	0x8E47, 0xB7A6, 0x8E48, 0xB7A7, 0x8E49, 0xB7AA, 0x8E4A, 0xB7AE,
+	0x8E4B, 0xB7AF, 0x8E4C, 0xB7B0, 0x8E4D, 0xB7B1, 0x8E4E, 0xB7B2,
+	0x8E4F, 0xB7B3, 0x8E50, 0xB7B6, 0x8E51, 0xB7B7, 0x8E52, 0xB7B9,
+	0x8E53, 0xB7BA, 0x8E54, 0xB7BB, 0x8E55, 0xB7BC, 0x8E56, 0xB7BD,
+	0x8E57, 0xB7BE, 0x8E58, 0xB7BF, 0x8E59, 0xB7C0, 0x8E5A, 0xB7C1,
+	0x8E61, 0xB7C2, 0x8E62, 0xB7C3, 0x8E63, 0xB7C4, 0x8E64, 0xB7C5,
+	0x8E65, 0xB7C6, 0x8E66, 0xB7C8, 0x8E67, 0xB7CA, 0x8E68, 0xB7CB,
+	0x8E69, 0xB7CC, 0x8E6A, 0xB7CD, 0x8E6B, 0xB7CE, 0x8E6C, 0xB7CF,
+	0x8E6D, 0xB7D0, 0x8E6E, 0xB7D1, 0x8E6F, 0xB7D2, 0x8E70, 0xB7D3,
+	0x8E71, 0xB7D4, 0x8E72, 0xB7D5, 0x8E73, 0xB7D6, 0x8E74, 0xB7D7,
+	0x8E75, 0xB7D8, 0x8E76, 0xB7D9, 0x8E77, 0xB7DA, 0x8E78, 0xB7DB,
+	0x8E79, 0xB7DC, 0x8E7A, 0xB7DD, 0x8E81, 0xB7DE, 0x8E82, 0xB7DF,
+	0x8E83, 0xB7E0, 0x8E84, 0xB7E1, 0x8E85, 0xB7E2, 0x8E86, 0xB7E3,
+	0x8E87, 0xB7E4, 0x8E88, 0xB7E5, 0x8E89, 0xB7E6, 0x8E8A, 0xB7E7,
+	0x8E8B, 0xB7E8, 0x8E8C, 0xB7E9, 0x8E8D, 0xB7EA, 0x8E8E, 0xB7EB,
+	0x8E8F, 0xB7EE, 0x8E90, 0xB7EF, 0x8E91, 0xB7F1, 0x8E92, 0xB7F2,
+	0x8E93, 0xB7F3, 0x8E94, 0xB7F5, 0x8E95, 0xB7F6, 0x8E96, 0xB7F7,
+	0x8E97, 0xB7F8, 0x8E98, 0xB7F9, 0x8E99, 0xB7FA, 0x8E9A, 0xB7FB,
+	0x8E9B, 0xB7FE, 0x8E9C, 0xB802, 0x8E9D, 0xB803, 0x8E9E, 0xB804,
+	0x8E9F, 0xB805, 0x8EA0, 0xB806, 0x8EA1, 0xB80A, 0x8EA2, 0xB80B,
+	0x8EA3, 0xB80D, 0x8EA4, 0xB80E, 0x8EA5, 0xB80F, 0x8EA6, 0xB811,
+	0x8EA7, 0xB812, 0x8EA8, 0xB813, 0x8EA9, 0xB814, 0x8EAA, 0xB815,
+	0x8EAB, 0xB816, 0x8EAC, 0xB817, 0x8EAD, 0xB81A, 0x8EAE, 0xB81C,
+	0x8EAF, 0xB81E, 0x8EB0, 0xB81F, 0x8EB1, 0xB820, 0x8EB2, 0xB821,
+	0x8EB3, 0xB822, 0x8EB4, 0xB823, 0x8EB5, 0xB826, 0x8EB6, 0xB827,
+	0x8EB7, 0xB829, 0x8EB8, 0xB82A, 0x8EB9, 0xB82B, 0x8EBA, 0xB82D,
+	0x8EBB, 0xB82E, 0x8EBC, 0xB82F, 0x8EBD, 0xB830, 0x8EBE, 0xB831,
+	0x8EBF, 0xB832, 0x8EC0, 0xB833, 0x8EC1, 0xB836, 0x8EC2, 0xB83A,
+	0x8EC3, 0xB83B, 0x8EC4, 0xB83C, 0x8EC5, 0xB83D, 0x8EC6, 0xB83E,
+	0x8EC7, 0xB83F, 0x8EC8, 0xB841, 0x8EC9, 0xB842, 0x8ECA, 0xB843,
+	0x8ECB, 0xB845, 0x8ECC, 0xB846, 0x8ECD, 0xB847, 0x8ECE, 0xB848,
+	0x8ECF, 0xB849, 0x8ED0, 0xB84A, 0x8ED1, 0xB84B, 0x8ED2, 0xB84C,
+	0x8ED3, 0xB84D, 0x8ED4, 0xB84E, 0x8ED5, 0xB84F, 0x8ED6, 0xB850,
+	0x8ED7, 0xB852, 0x8ED8, 0xB854, 0x8ED9, 0xB855, 0x8EDA, 0xB856,
+	0x8EDB, 0xB857, 0x8EDC, 0xB858, 0x8EDD, 0xB859, 0x8EDE, 0xB85A,
+	0x8EDF, 0xB85B, 0x8EE0, 0xB85E, 0x8EE1, 0xB85F, 0x8EE2, 0xB861,
+	0x8EE3, 0xB862, 0x8EE4, 0xB863, 0x8EE5, 0xB865, 0x8EE6, 0xB866,
+	0x8EE7, 0xB867, 0x8EE8, 0xB868, 0x8EE9, 0xB869, 0x8EEA, 0xB86A,
+	0x8EEB, 0xB86B, 0x8EEC, 0xB86E, 0x8EED, 0xB870, 0x8EEE, 0xB872,
+	0x8EEF, 0xB873, 0x8EF0, 0xB874, 0x8EF1, 0xB875, 0x8EF2, 0xB876,
+	0x8EF3, 0xB877, 0x8EF4, 0xB879, 0x8EF5, 0xB87A, 0x8EF6, 0xB87B,
+	0x8EF7, 0xB87D, 0x8EF8, 0xB87E, 0x8EF9, 0xB87F, 0x8EFA, 0xB880,
+	0x8EFB, 0xB881, 0x8EFC, 0xB882, 0x8EFD, 0xB883, 0x8EFE, 0xB884,
+	0x8F41, 0xB885, 0x8F42, 0xB886, 0x8F43, 0xB887, 0x8F44, 0xB888,
+	0x8F45, 0xB889, 0x8F46, 0xB88A, 0x8F47, 0xB88B, 0x8F48, 0xB88C,
+	0x8F49, 0xB88E, 0x8F4A, 0xB88F, 0x8F4B, 0xB890, 0x8F4C, 0xB891,
+	0x8F4D, 0xB892, 0x8F4E, 0xB893, 0x8F4F, 0xB894, 0x8F50, 0xB895,
+	0x8F51, 0xB896, 0x8F52, 0xB897, 0x8F53, 0xB898, 0x8F54, 0xB899,
+	0x8F55, 0xB89A, 0x8F56, 0xB89B, 0x8F57, 0xB89C, 0x8F58, 0xB89D,
+	0x8F59, 0xB89E, 0x8F5A, 0xB89F, 0x8F61, 0xB8A0, 0x8F62, 0xB8A1,
+	0x8F63, 0xB8A2, 0x8F64, 0xB8A3, 0x8F65, 0xB8A4, 0x8F66, 0xB8A5,
+	0x8F67, 0xB8A6, 0x8F68, 0xB8A7, 0x8F69, 0xB8A9, 0x8F6A, 0xB8AA,
+	0x8F6B, 0xB8AB, 0x8F6C, 0xB8AC, 0x8F6D, 0xB8AD, 0x8F6E, 0xB8AE,
+	0x8F6F, 0xB8AF, 0x8F70, 0xB8B1, 0x8F71, 0xB8B2, 0x8F72, 0xB8B3,
+	0x8F73, 0xB8B5, 0x8F74, 0xB8B6, 0x8F75, 0xB8B7, 0x8F76, 0xB8B9,
+	0x8F77, 0xB8BA, 0x8F78, 0xB8BB, 0x8F79, 0xB8BC, 0x8F7A, 0xB8BD,
+	0x8F81, 0xB8BE, 0x8F82, 0xB8BF, 0x8F83, 0xB8C2, 0x8F84, 0xB8C4,
+	0x8F85, 0xB8C6, 0x8F86, 0xB8C7, 0x8F87, 0xB8C8, 0x8F88, 0xB8C9,
+	0x8F89, 0xB8CA, 0x8F8A, 0xB8CB, 0x8F8B, 0xB8CD, 0x8F8C, 0xB8CE,
+	0x8F8D, 0xB8CF, 0x8F8E, 0xB8D1, 0x8F8F, 0xB8D2, 0x8F90, 0xB8D3,
+	0x8F91, 0xB8D5, 0x8F92, 0xB8D6, 0x8F93, 0xB8D7, 0x8F94, 0xB8D8,
+	0x8F95, 0xB8D9, 0x8F96, 0xB8DA, 0x8F97, 0xB8DB, 0x8F98, 0xB8DC,
+	0x8F99, 0xB8DE, 0x8F9A, 0xB8E0, 0x8F9B, 0xB8E2, 0x8F9C, 0xB8E3,
+	0x8F9D, 0xB8E4, 0x8F9E, 0xB8E5, 0x8F9F, 0xB8E6, 0x8FA0, 0xB8E7,
+	0x8FA1, 0xB8EA, 0x8FA2, 0xB8EB, 0x8FA3, 0xB8ED, 0x8FA4, 0xB8EE,
+	0x8FA5, 0xB8EF, 0x8FA6, 0xB8F1, 0x8FA7, 0xB8F2, 0x8FA8, 0xB8F3,
+	0x8FA9, 0xB8F4, 0x8FAA, 0xB8F5, 0x8FAB, 0xB8F6, 0x8FAC, 0xB8F7,
+	0x8FAD, 0xB8FA, 0x8FAE, 0xB8FC, 0x8FAF, 0xB8FE, 0x8FB0, 0xB8FF,
+	0x8FB1, 0xB900, 0x8FB2, 0xB901, 0x8FB3, 0xB902, 0x8FB4, 0xB903,
+	0x8FB5, 0xB905, 0x8FB6, 0xB906, 0x8FB7, 0xB907, 0x8FB8, 0xB908,
+	0x8FB9, 0xB909, 0x8FBA, 0xB90A, 0x8FBB, 0xB90B, 0x8FBC, 0xB90C,
+	0x8FBD, 0xB90D, 0x8FBE, 0xB90E, 0x8FBF, 0xB90F, 0x8FC0, 0xB910,
+	0x8FC1, 0xB911, 0x8FC2, 0xB912, 0x8FC3, 0xB913, 0x8FC4, 0xB914,
+	0x8FC5, 0xB915, 0x8FC6, 0xB916, 0x8FC7, 0xB917, 0x8FC8, 0xB919,
+	0x8FC9, 0xB91A, 0x8FCA, 0xB91B, 0x8FCB, 0xB91C, 0x8FCC, 0xB91D,
+	0x8FCD, 0xB91E, 0x8FCE, 0xB91F, 0x8FCF, 0xB921, 0x8FD0, 0xB922,
+	0x8FD1, 0xB923, 0x8FD2, 0xB924, 0x8FD3, 0xB925, 0x8FD4, 0xB926,
+	0x8FD5, 0xB927, 0x8FD6, 0xB928, 0x8FD7, 0xB929, 0x8FD8, 0xB92A,
+	0x8FD9, 0xB92B, 0x8FDA, 0xB92C, 0x8FDB, 0xB92D, 0x8FDC, 0xB92E,
+	0x8FDD, 0xB92F, 0x8FDE, 0xB930, 0x8FDF, 0xB931, 0x8FE0, 0xB932,
+	0x8FE1, 0xB933, 0x8FE2, 0xB934, 0x8FE3, 0xB935, 0x8FE4, 0xB936,
+	0x8FE5, 0xB937, 0x8FE6, 0xB938, 0x8FE7, 0xB939, 0x8FE8, 0xB93A,
+	0x8FE9, 0xB93B, 0x8FEA, 0xB93E, 0x8FEB, 0xB93F, 0x8FEC, 0xB941,
+	0x8FED, 0xB942, 0x8FEE, 0xB943, 0x8FEF, 0xB945, 0x8FF0, 0xB946,
+	0x8FF1, 0xB947, 0x8FF2, 0xB948, 0x8FF3, 0xB949, 0x8FF4, 0xB94A,
+	0x8FF5, 0xB94B, 0x8FF6, 0xB94D, 0x8FF7, 0xB94E, 0x8FF8, 0xB950,
+	0x8FF9, 0xB952, 0x8FFA, 0xB953, 0x8FFB, 0xB954, 0x8FFC, 0xB955,
+	0x8FFD, 0xB956, 0x8FFE, 0xB957, 0x9041, 0xB95A, 0x9042, 0xB95B,
+	0x9043, 0xB95D, 0x9044, 0xB95E, 0x9045, 0xB95F, 0x9046, 0xB961,
+	0x9047, 0xB962, 0x9048, 0xB963, 0x9049, 0xB964, 0x904A, 0xB965,
+	0x904B, 0xB966, 0x904C, 0xB967, 0x904D, 0xB96A, 0x904E, 0xB96C,
+	0x904F, 0xB96E, 0x9050, 0xB96F, 0x9051, 0xB970, 0x9052, 0xB971,
+	0x9053, 0xB972, 0x9054, 0xB973, 0x9055, 0xB976, 0x9056, 0xB977,
+	0x9057, 0xB979, 0x9058, 0xB97A, 0x9059, 0xB97B, 0x905A, 0xB97D,
+	0x9061, 0xB97E, 0x9062, 0xB97F, 0x9063, 0xB980, 0x9064, 0xB981,
+	0x9065, 0xB982, 0x9066, 0xB983, 0x9067, 0xB986, 0x9068, 0xB988,
+	0x9069, 0xB98B, 0x906A, 0xB98C, 0x906B, 0xB98F, 0x906C, 0xB990,
+	0x906D, 0xB991, 0x906E, 0xB992, 0x906F, 0xB993, 0x9070, 0xB994,
+	0x9071, 0xB995, 0x9072, 0xB996, 0x9073, 0xB997, 0x9074, 0xB998,
+	0x9075, 0xB999, 0x9076, 0xB99A, 0x9077, 0xB99B, 0x9078, 0xB99C,
+	0x9079, 0xB99D, 0x907A, 0xB99E, 0x9081, 0xB99F, 0x9082, 0xB9A0,
+	0x9083, 0xB9A1, 0x9084, 0xB9A2, 0x9085, 0xB9A3, 0x9086, 0xB9A4,
+	0x9087, 0xB9A5, 0x9088, 0xB9A6, 0x9089, 0xB9A7, 0x908A, 0xB9A8,
+	0x908B, 0xB9A9, 0x908C, 0xB9AA, 0x908D, 0xB9AB, 0x908E, 0xB9AE,
+	0x908F, 0xB9AF, 0x9090, 0xB9B1, 0x9091, 0xB9B2, 0x9092, 0xB9B3,
+	0x9093, 0xB9B5, 0x9094, 0xB9B6, 0x9095, 0xB9B7, 0x9096, 0xB9B8,
+	0x9097, 0xB9B9, 0x9098, 0xB9BA, 0x9099, 0xB9BB, 0x909A, 0xB9BE,
+	0x909B, 0xB9C0, 0x909C, 0xB9C2, 0x909D, 0xB9C3, 0x909E, 0xB9C4,
+	0x909F, 0xB9C5, 0x90A0, 0xB9C6, 0x90A1, 0xB9C7, 0x90A2, 0xB9CA,
+	0x90A3, 0xB9CB, 0x90A4, 0xB9CD, 0x90A5, 0xB9D3, 0x90A6, 0xB9D4,
+	0x90A7, 0xB9D5, 0x90A8, 0xB9D6, 0x90A9, 0xB9D7, 0x90AA, 0xB9DA,
+	0x90AB, 0xB9DC, 0x90AC, 0xB9DF, 0x90AD, 0xB9E0, 0x90AE, 0xB9E2,
+	0x90AF, 0xB9E6, 0x90B0, 0xB9E7, 0x90B1, 0xB9E9, 0x90B2, 0xB9EA,
+	0x90B3, 0xB9EB, 0x90B4, 0xB9ED, 0x90B5, 0xB9EE, 0x90B6, 0xB9EF,
+	0x90B7, 0xB9F0, 0x90B8, 0xB9F1, 0x90B9, 0xB9F2, 0x90BA, 0xB9F3,
+	0x90BB, 0xB9F6, 0x90BC, 0xB9FB, 0x90BD, 0xB9FC, 0x90BE, 0xB9FD,
+	0x90BF, 0xB9FE, 0x90C0, 0xB9FF, 0x90C1, 0xBA02, 0x90C2, 0xBA03,
+	0x90C3, 0xBA04, 0x90C4, 0xBA05, 0x90C5, 0xBA06, 0x90C6, 0xBA07,
+	0x90C7, 0xBA09, 0x90C8, 0xBA0A, 0x90C9, 0xBA0B, 0x90CA, 0xBA0C,
+	0x90CB, 0xBA0D, 0x90CC, 0xBA0E, 0x90CD, 0xBA0F, 0x90CE, 0xBA10,
+	0x90CF, 0xBA11, 0x90D0, 0xBA12, 0x90D1, 0xBA13, 0x90D2, 0xBA14,
+	0x90D3, 0xBA16, 0x90D4, 0xBA17, 0x90D5, 0xBA18, 0x90D6, 0xBA19,
+	0x90D7, 0xBA1A, 0x90D8, 0xBA1B, 0x90D9, 0xBA1C, 0x90DA, 0xBA1D,
+	0x90DB, 0xBA1E, 0x90DC, 0xBA1F, 0x90DD, 0xBA20, 0x90DE, 0xBA21,
+	0x90DF, 0xBA22, 0x90E0, 0xBA23, 0x90E1, 0xBA24, 0x90E2, 0xBA25,
+	0x90E3, 0xBA26, 0x90E4, 0xBA27, 0x90E5, 0xBA28, 0x90E6, 0xBA29,
+	0x90E7, 0xBA2A, 0x90E8, 0xBA2B, 0x90E9, 0xBA2C, 0x90EA, 0xBA2D,
+	0x90EB, 0xBA2E, 0x90EC, 0xBA2F, 0x90ED, 0xBA30, 0x90EE, 0xBA31,
+	0x90EF, 0xBA32, 0x90F0, 0xBA33, 0x90F1, 0xBA34, 0x90F2, 0xBA35,
+	0x90F3, 0xBA36, 0x90F4, 0xBA37, 0x90F5, 0xBA3A, 0x90F6, 0xBA3B,
+	0x90F7, 0xBA3D, 0x90F8, 0xBA3E, 0x90F9, 0xBA3F, 0x90FA, 0xBA41,
+	0x90FB, 0xBA43, 0x90FC, 0xBA44, 0x90FD, 0xBA45, 0x90FE, 0xBA46,
+	0x9141, 0xBA47, 0x9142, 0xBA4A, 0x9143, 0xBA4C, 0x9144, 0xBA4F,
+	0x9145, 0xBA50, 0x9146, 0xBA51, 0x9147, 0xBA52, 0x9148, 0xBA56,
+	0x9149, 0xBA57, 0x914A, 0xBA59, 0x914B, 0xBA5A, 0x914C, 0xBA5B,
+	0x914D, 0xBA5D, 0x914E, 0xBA5E, 0x914F, 0xBA5F, 0x9150, 0xBA60,
+	0x9151, 0xBA61, 0x9152, 0xBA62, 0x9153, 0xBA63, 0x9154, 0xBA66,
+	0x9155, 0xBA6A, 0x9156, 0xBA6B, 0x9157, 0xBA6C, 0x9158, 0xBA6D,
+	0x9159, 0xBA6E, 0x915A, 0xBA6F, 0x9161, 0xBA72, 0x9162, 0xBA73,
+	0x9163, 0xBA75, 0x9164, 0xBA76, 0x9165, 0xBA77, 0x9166, 0xBA79,
+	0x9167, 0xBA7A, 0x9168, 0xBA7B, 0x9169, 0xBA7C, 0x916A, 0xBA7D,
+	0x916B, 0xBA7E, 0x916C, 0xBA7F, 0x916D, 0xBA80, 0x916E, 0xBA81,
+	0x916F, 0xBA82, 0x9170, 0xBA86, 0x9171, 0xBA88, 0x9172, 0xBA89,
+	0x9173, 0xBA8A, 0x9174, 0xBA8B, 0x9175, 0xBA8D, 0x9176, 0xBA8E,
+	0x9177, 0xBA8F, 0x9178, 0xBA90, 0x9179, 0xBA91, 0x917A, 0xBA92,
+	0x9181, 0xBA93, 0x9182, 0xBA94, 0x9183, 0xBA95, 0x9184, 0xBA96,
+	0x9185, 0xBA97, 0x9186, 0xBA98, 0x9187, 0xBA99, 0x9188, 0xBA9A,
+	0x9189, 0xBA9B, 0x918A, 0xBA9C, 0x918B, 0xBA9D, 0x918C, 0xBA9E,
+	0x918D, 0xBA9F, 0x918E, 0xBAA0, 0x918F, 0xBAA1, 0x9190, 0xBAA2,
+	0x9191, 0xBAA3, 0x9192, 0xBAA4, 0x9193, 0xBAA5, 0x9194, 0xBAA6,
+	0x9195, 0xBAA7, 0x9196, 0xBAAA, 0x9197, 0xBAAD, 0x9198, 0xBAAE,
+	0x9199, 0xBAAF, 0x919A, 0xBAB1, 0x919B, 0xBAB3, 0x919C, 0xBAB4,
+	0x919D, 0xBAB5, 0x919E, 0xBAB6, 0x919F, 0xBAB7, 0x91A0, 0xBABA,
+	0x91A1, 0xBABC, 0x91A2, 0xBABE, 0x91A3, 0xBABF, 0x91A4, 0xBAC0,
+	0x91A5, 0xBAC1, 0x91A6, 0xBAC2, 0x91A7, 0xBAC3, 0x91A8, 0xBAC5,
+	0x91A9, 0xBAC6, 0x91AA, 0xBAC7, 0x91AB, 0xBAC9, 0x91AC, 0xBACA,
+	0x91AD, 0xBACB, 0x91AE, 0xBACC, 0x91AF, 0xBACD, 0x91B0, 0xBACE,
+	0x91B1, 0xBACF, 0x91B2, 0xBAD0, 0x91B3, 0xBAD1, 0x91B4, 0xBAD2,
+	0x91B5, 0xBAD3, 0x91B6, 0xBAD4, 0x91B7, 0xBAD5, 0x91B8, 0xBAD6,
+	0x91B9, 0xBAD7, 0x91BA, 0xBADA, 0x91BB, 0xBADB, 0x91BC, 0xBADC,
+	0x91BD, 0xBADD, 0x91BE, 0xBADE, 0x91BF, 0xBADF, 0x91C0, 0xBAE0,
+	0x91C1, 0xBAE1, 0x91C2, 0xBAE2, 0x91C3, 0xBAE3, 0x91C4, 0xBAE4,
+	0x91C5, 0xBAE5, 0x91C6, 0xBAE6, 0x91C7, 0xBAE7, 0x91C8, 0xBAE8,
+	0x91C9, 0xBAE9, 0x91CA, 0xBAEA, 0x91CB, 0xBAEB, 0x91CC, 0xBAEC,
+	0x91CD, 0xBAED, 0x91CE, 0xBAEE, 0x91CF, 0xBAEF, 0x91D0, 0xBAF0,
+	0x91D1, 0xBAF1, 0x91D2, 0xBAF2, 0x91D3, 0xBAF3, 0x91D4, 0xBAF4,
+	0x91D5, 0xBAF5, 0x91D6, 0xBAF6, 0x91D7, 0xBAF7, 0x91D8, 0xBAF8,
+	0x91D9, 0xBAF9, 0x91DA, 0xBAFA, 0x91DB, 0xBAFB, 0x91DC, 0xBAFD,
+	0x91DD, 0xBAFE, 0x91DE, 0xBAFF, 0x91DF, 0xBB01, 0x91E0, 0xBB02,
+	0x91E1, 0xBB03, 0x91E2, 0xBB05, 0x91E3, 0xBB06, 0x91E4, 0xBB07,
+	0x91E5, 0xBB08, 0x91E6, 0xBB09, 0x91E7, 0xBB0A, 0x91E8, 0xBB0B,
+	0x91E9, 0xBB0C, 0x91EA, 0xBB0E, 0x91EB, 0xBB10, 0x91EC, 0xBB12,
+	0x91ED, 0xBB13, 0x91EE, 0xBB14, 0x91EF, 0xBB15, 0x91F0, 0xBB16,
+	0x91F1, 0xBB17, 0x91F2, 0xBB19, 0x91F3, 0xBB1A, 0x91F4, 0xBB1B,
+	0x91F5, 0xBB1D, 0x91F6, 0xBB1E, 0x91F7, 0xBB1F, 0x91F8, 0xBB21,
+	0x91F9, 0xBB22, 0x91FA, 0xBB23, 0x91FB, 0xBB24, 0x91FC, 0xBB25,
+	0x91FD, 0xBB26, 0x91FE, 0xBB27, 0x9241, 0xBB28, 0x9242, 0xBB2A,
+	0x9243, 0xBB2C, 0x9244, 0xBB2D, 0x9245, 0xBB2E, 0x9246, 0xBB2F,
+	0x9247, 0xBB30, 0x9248, 0xBB31, 0x9249, 0xBB32, 0x924A, 0xBB33,
+	0x924B, 0xBB37, 0x924C, 0xBB39, 0x924D, 0xBB3A, 0x924E, 0xBB3F,
+	0x924F, 0xBB40, 0x9250, 0xBB41, 0x9251, 0xBB42, 0x9252, 0xBB43,
+	0x9253, 0xBB46, 0x9254, 0xBB48, 0x9255, 0xBB4A, 0x9256, 0xBB4B,
+	0x9257, 0xBB4C, 0x9258, 0xBB4E, 0x9259, 0xBB51, 0x925A, 0xBB52,
+	0x9261, 0xBB53, 0x9262, 0xBB55, 0x9263, 0xBB56, 0x9264, 0xBB57,
+	0x9265, 0xBB59, 0x9266, 0xBB5A, 0x9267, 0xBB5B, 0x9268, 0xBB5C,
+	0x9269, 0xBB5D, 0x926A, 0xBB5E, 0x926B, 0xBB5F, 0x926C, 0xBB60,
+	0x926D, 0xBB62, 0x926E, 0xBB64, 0x926F, 0xBB65, 0x9270, 0xBB66,
+	0x9271, 0xBB67, 0x9272, 0xBB68, 0x9273, 0xBB69, 0x9274, 0xBB6A,
+	0x9275, 0xBB6B, 0x9276, 0xBB6D, 0x9277, 0xBB6E, 0x9278, 0xBB6F,
+	0x9279, 0xBB70, 0x927A, 0xBB71, 0x9281, 0xBB72, 0x9282, 0xBB73,
+	0x9283, 0xBB74, 0x9284, 0xBB75, 0x9285, 0xBB76, 0x9286, 0xBB77,
+	0x9287, 0xBB78, 0x9288, 0xBB79, 0x9289, 0xBB7A, 0x928A, 0xBB7B,
+	0x928B, 0xBB7C, 0x928C, 0xBB7D, 0x928D, 0xBB7E, 0x928E, 0xBB7F,
+	0x928F, 0xBB80, 0x9290, 0xBB81, 0x9291, 0xBB82, 0x9292, 0xBB83,
+	0x9293, 0xBB84, 0x9294, 0xBB85, 0x9295, 0xBB86, 0x9296, 0xBB87,
+	0x9297, 0xBB89, 0x9298, 0xBB8A, 0x9299, 0xBB8B, 0x929A, 0xBB8D,
+	0x929B, 0xBB8E, 0x929C, 0xBB8F, 0x929D, 0xBB91, 0x929E, 0xBB92,
+	0x929F, 0xBB93, 0x92A0, 0xBB94, 0x92A1, 0xBB95, 0x92A2, 0xBB96,
+	0x92A3, 0xBB97, 0x92A4, 0xBB98, 0x92A5, 0xBB99, 0x92A6, 0xBB9A,
+	0x92A7, 0xBB9B, 0x92A8, 0xBB9C, 0x92A9, 0xBB9D, 0x92AA, 0xBB9E,
+	0x92AB, 0xBB9F, 0x92AC, 0xBBA0, 0x92AD, 0xBBA1, 0x92AE, 0xBBA2,
+	0x92AF, 0xBBA3, 0x92B0, 0xBBA5, 0x92B1, 0xBBA6, 0x92B2, 0xBBA7,
+	0x92B3, 0xBBA9, 0x92B4, 0xBBAA, 0x92B5, 0xBBAB, 0x92B6, 0xBBAD,
+	0x92B7, 0xBBAE, 0x92B8, 0xBBAF, 0x92B9, 0xBBB0, 0x92BA, 0xBBB1,
+	0x92BB, 0xBBB2, 0x92BC, 0xBBB3, 0x92BD, 0xBBB5, 0x92BE, 0xBBB6,
+	0x92BF, 0xBBB8, 0x92C0, 0xBBB9, 0x92C1, 0xBBBA, 0x92C2, 0xBBBB,
+	0x92C3, 0xBBBC, 0x92C4, 0xBBBD, 0x92C5, 0xBBBE, 0x92C6, 0xBBBF,
+	0x92C7, 0xBBC1, 0x92C8, 0xBBC2, 0x92C9, 0xBBC3, 0x92CA, 0xBBC5,
+	0x92CB, 0xBBC6, 0x92CC, 0xBBC7, 0x92CD, 0xBBC9, 0x92CE, 0xBBCA,
+	0x92CF, 0xBBCB, 0x92D0, 0xBBCC, 0x92D1, 0xBBCD, 0x92D2, 0xBBCE,
+	0x92D3, 0xBBCF, 0x92D4, 0xBBD1, 0x92D5, 0xBBD2, 0x92D6, 0xBBD4,
+	0x92D7, 0xBBD5, 0x92D8, 0xBBD6, 0x92D9, 0xBBD7, 0x92DA, 0xBBD8,
+	0x92DB, 0xBBD9, 0x92DC, 0xBBDA, 0x92DD, 0xBBDB, 0x92DE, 0xBBDC,
+	0x92DF, 0xBBDD, 0x92E0, 0xBBDE, 0x92E1, 0xBBDF, 0x92E2, 0xBBE0,
+	0x92E3, 0xBBE1, 0x92E4, 0xBBE2, 0x92E5, 0xBBE3, 0x92E6, 0xBBE4,
+	0x92E7, 0xBBE5, 0x92E8, 0xBBE6, 0x92E9, 0xBBE7, 0x92EA, 0xBBE8,
+	0x92EB, 0xBBE9, 0x92EC, 0xBBEA, 0x92ED, 0xBBEB, 0x92EE, 0xBBEC,
+	0x92EF, 0xBBED, 0x92F0, 0xBBEE, 0x92F1, 0xBBEF, 0x92F2, 0xBBF0,
+	0x92F3, 0xBBF1, 0x92F4, 0xBBF2, 0x92F5, 0xBBF3, 0x92F6, 0xBBF4,
+	0x92F7, 0xBBF5, 0x92F8, 0xBBF6, 0x92F9, 0xBBF7, 0x92FA, 0xBBFA,
+	0x92FB, 0xBBFB, 0x92FC, 0xBBFD, 0x92FD, 0xBBFE, 0x92FE, 0xBC01,
+	0x9341, 0xBC03, 0x9342, 0xBC04, 0x9343, 0xBC05, 0x9344, 0xBC06,
+	0x9345, 0xBC07, 0x9346, 0xBC0A, 0x9347, 0xBC0E, 0x9348, 0xBC10,
+	0x9349, 0xBC12, 0x934A, 0xBC13, 0x934B, 0xBC19, 0x934C, 0xBC1A,
+	0x934D, 0xBC20, 0x934E, 0xBC21, 0x934F, 0xBC22, 0x9350, 0xBC23,
+	0x9351, 0xBC26, 0x9352, 0xBC28, 0x9353, 0xBC2A, 0x9354, 0xBC2B,
+	0x9355, 0xBC2C, 0x9356, 0xBC2E, 0x9357, 0xBC2F, 0x9358, 0xBC32,
+	0x9359, 0xBC33, 0x935A, 0xBC35, 0x9361, 0xBC36, 0x9362, 0xBC37,
+	0x9363, 0xBC39, 0x9364, 0xBC3A, 0x9365, 0xBC3B, 0x9366, 0xBC3C,
+	0x9367, 0xBC3D, 0x9368, 0xBC3E, 0x9369, 0xBC3F, 0x936A, 0xBC42,
+	0x936B, 0xBC46, 0x936C, 0xBC47, 0x936D, 0xBC48, 0x936E, 0xBC4A,
+	0x936F, 0xBC4B, 0x9370, 0xBC4E, 0x9371, 0xBC4F, 0x9372, 0xBC51,
+	0x9373, 0xBC52, 0x9374, 0xBC53, 0x9375, 0xBC54, 0x9376, 0xBC55,
+	0x9377, 0xBC56, 0x9378, 0xBC57, 0x9379, 0xBC58, 0x937A, 0xBC59,
+	0x9381, 0xBC5A, 0x9382, 0xBC5B, 0x9383, 0xBC5C, 0x9384, 0xBC5E,
+	0x9385, 0xBC5F, 0x9386, 0xBC60, 0x9387, 0xBC61, 0x9388, 0xBC62,
+	0x9389, 0xBC63, 0x938A, 0xBC64, 0x938B, 0xBC65, 0x938C, 0xBC66,
+	0x938D, 0xBC67, 0x938E, 0xBC68, 0x938F, 0xBC69, 0x9390, 0xBC6A,
+	0x9391, 0xBC6B, 0x9392, 0xBC6C, 0x9393, 0xBC6D, 0x9394, 0xBC6E,
+	0x9395, 0xBC6F, 0x9396, 0xBC70, 0x9397, 0xBC71, 0x9398, 0xBC72,
+	0x9399, 0xBC73, 0x939A, 0xBC74, 0x939B, 0xBC75, 0x939C, 0xBC76,
+	0x939D, 0xBC77, 0x939E, 0xBC78, 0x939F, 0xBC79, 0x93A0, 0xBC7A,
+	0x93A1, 0xBC7B, 0x93A2, 0xBC7C, 0x93A3, 0xBC7D, 0x93A4, 0xBC7E,
+	0x93A5, 0xBC7F, 0x93A6, 0xBC80, 0x93A7, 0xBC81, 0x93A8, 0xBC82,
+	0x93A9, 0xBC83, 0x93AA, 0xBC86, 0x93AB, 0xBC87, 0x93AC, 0xBC89,
+	0x93AD, 0xBC8A, 0x93AE, 0xBC8D, 0x93AF, 0xBC8F, 0x93B0, 0xBC90,
+	0x93B1, 0xBC91, 0x93B2, 0xBC92, 0x93B3, 0xBC93, 0x93B4, 0xBC96,
+	0x93B5, 0xBC98, 0x93B6, 0xBC9B, 0x93B7, 0xBC9C, 0x93B8, 0xBC9D,
+	0x93B9, 0xBC9E, 0x93BA, 0xBC9F, 0x93BB, 0xBCA2, 0x93BC, 0xBCA3,
+	0x93BD, 0xBCA5, 0x93BE, 0xBCA6, 0x93BF, 0xBCA9, 0x93C0, 0xBCAA,
+	0x93C1, 0xBCAB, 0x93C2, 0xBCAC, 0x93C3, 0xBCAD, 0x93C4, 0xBCAE,
+	0x93C5, 0xBCAF, 0x93C6, 0xBCB2, 0x93C7, 0xBCB6, 0x93C8, 0xBCB7,
+	0x93C9, 0xBCB8, 0x93CA, 0xBCB9, 0x93CB, 0xBCBA, 0x93CC, 0xBCBB,
+	0x93CD, 0xBCBE, 0x93CE, 0xBCBF, 0x93CF, 0xBCC1, 0x93D0, 0xBCC2,
+	0x93D1, 0xBCC3, 0x93D2, 0xBCC5, 0x93D3, 0xBCC6, 0x93D4, 0xBCC7,
+	0x93D5, 0xBCC8, 0x93D6, 0xBCC9, 0x93D7, 0xBCCA, 0x93D8, 0xBCCB,
+	0x93D9, 0xBCCC, 0x93DA, 0xBCCE, 0x93DB, 0xBCD2, 0x93DC, 0xBCD3,
+	0x93DD, 0xBCD4, 0x93DE, 0xBCD6, 0x93DF, 0xBCD7, 0x93E0, 0xBCD9,
+	0x93E1, 0xBCDA, 0x93E2, 0xBCDB, 0x93E3, 0xBCDD, 0x93E4, 0xBCDE,
+	0x93E5, 0xBCDF, 0x93E6, 0xBCE0, 0x93E7, 0xBCE1, 0x93E8, 0xBCE2,
+	0x93E9, 0xBCE3, 0x93EA, 0xBCE4, 0x93EB, 0xBCE5, 0x93EC, 0xBCE6,
+	0x93ED, 0xBCE7, 0x93EE, 0xBCE8, 0x93EF, 0xBCE9, 0x93F0, 0xBCEA,
+	0x93F1, 0xBCEB, 0x93F2, 0xBCEC, 0x93F3, 0xBCED, 0x93F4, 0xBCEE,
+	0x93F5, 0xBCEF, 0x93F6, 0xBCF0, 0x93F7, 0xBCF1, 0x93F8, 0xBCF2,
+	0x93F9, 0xBCF3, 0x93FA, 0xBCF7, 0x93FB, 0xBCF9, 0x93FC, 0xBCFA,
+	0x93FD, 0xBCFB, 0x93FE, 0xBCFD, 0x9441, 0xBCFE, 0x9442, 0xBCFF,
+	0x9443, 0xBD00, 0x9444, 0xBD01, 0x9445, 0xBD02, 0x9446, 0xBD03,
+	0x9447, 0xBD06, 0x9448, 0xBD08, 0x9449, 0xBD0A, 0x944A, 0xBD0B,
+	0x944B, 0xBD0C, 0x944C, 0xBD0D, 0x944D, 0xBD0E, 0x944E, 0xBD0F,
+	0x944F, 0xBD11, 0x9450, 0xBD12, 0x9451, 0xBD13, 0x9452, 0xBD15,
+	0x9453, 0xBD16, 0x9454, 0xBD17, 0x9455, 0xBD18, 0x9456, 0xBD19,
+	0x9457, 0xBD1A, 0x9458, 0xBD1B, 0x9459, 0xBD1C, 0x945A, 0xBD1D,
+	0x9461, 0xBD1E, 0x9462, 0xBD1F, 0x9463, 0xBD20, 0x9464, 0xBD21,
+	0x9465, 0xBD22, 0x9466, 0xBD23, 0x9467, 0xBD25, 0x9468, 0xBD26,
+	0x9469, 0xBD27, 0x946A, 0xBD28, 0x946B, 0xBD29, 0x946C, 0xBD2A,
+	0x946D, 0xBD2B, 0x946E, 0xBD2D, 0x946F, 0xBD2E, 0x9470, 0xBD2F,
+	0x9471, 0xBD30, 0x9472, 0xBD31, 0x9473, 0xBD32, 0x9474, 0xBD33,
+	0x9475, 0xBD34, 0x9476, 0xBD35, 0x9477, 0xBD36, 0x9478, 0xBD37,
+	0x9479, 0xBD38, 0x947A, 0xBD39, 0x9481, 0xBD3A, 0x9482, 0xBD3B,
+	0x9483, 0xBD3C, 0x9484, 0xBD3D, 0x9485, 0xBD3E, 0x9486, 0xBD3F,
+	0x9487, 0xBD41, 0x9488, 0xBD42, 0x9489, 0xBD43, 0x948A, 0xBD44,
+	0x948B, 0xBD45, 0x948C, 0xBD46, 0x948D, 0xBD47, 0x948E, 0xBD4A,
+	0x948F, 0xBD4B, 0x9490, 0xBD4D, 0x9491, 0xBD4E, 0x9492, 0xBD4F,
+	0x9493, 0xBD51, 0x9494, 0xBD52, 0x9495, 0xBD53, 0x9496, 0xBD54,
+	0x9497, 0xBD55, 0x9498, 0xBD56, 0x9499, 0xBD57, 0x949A, 0xBD5A,
+	0x949B, 0xBD5B, 0x949C, 0xBD5C, 0x949D, 0xBD5D, 0x949E, 0xBD5E,
+	0x949F, 0xBD5F, 0x94A0, 0xBD60, 0x94A1, 0xBD61, 0x94A2, 0xBD62,
+	0x94A3, 0xBD63, 0x94A4, 0xBD65, 0x94A5, 0xBD66, 0x94A6, 0xBD67,
+	0x94A7, 0xBD69, 0x94A8, 0xBD6A, 0x94A9, 0xBD6B, 0x94AA, 0xBD6C,
+	0x94AB, 0xBD6D, 0x94AC, 0xBD6E, 0x94AD, 0xBD6F, 0x94AE, 0xBD70,
+	0x94AF, 0xBD71, 0x94B0, 0xBD72, 0x94B1, 0xBD73, 0x94B2, 0xBD74,
+	0x94B3, 0xBD75, 0x94B4, 0xBD76, 0x94B5, 0xBD77, 0x94B6, 0xBD78,
+	0x94B7, 0xBD79, 0x94B8, 0xBD7A, 0x94B9, 0xBD7B, 0x94BA, 0xBD7C,
+	0x94BB, 0xBD7D, 0x94BC, 0xBD7E, 0x94BD, 0xBD7F, 0x94BE, 0xBD82,
+	0x94BF, 0xBD83, 0x94C0, 0xBD85, 0x94C1, 0xBD86, 0x94C2, 0xBD8B,
+	0x94C3, 0xBD8C, 0x94C4, 0xBD8D, 0x94C5, 0xBD8E, 0x94C6, 0xBD8F,
+	0x94C7, 0xBD92, 0x94C8, 0xBD94, 0x94C9, 0xBD96, 0x94CA, 0xBD97,
+	0x94CB, 0xBD98, 0x94CC, 0xBD9B, 0x94CD, 0xBD9D, 0x94CE, 0xBD9E,
+	0x94CF, 0xBD9F, 0x94D0, 0xBDA0, 0x94D1, 0xBDA1, 0x94D2, 0xBDA2,
+	0x94D3, 0xBDA3, 0x94D4, 0xBDA5, 0x94D5, 0xBDA6, 0x94D6, 0xBDA7,
+	0x94D7, 0xBDA8, 0x94D8, 0xBDA9, 0x94D9, 0xBDAA, 0x94DA, 0xBDAB,
+	0x94DB, 0xBDAC, 0x94DC, 0xBDAD, 0x94DD, 0xBDAE, 0x94DE, 0xBDAF,
+	0x94DF, 0xBDB1, 0x94E0, 0xBDB2, 0x94E1, 0xBDB3, 0x94E2, 0xBDB4,
+	0x94E3, 0xBDB5, 0x94E4, 0xBDB6, 0x94E5, 0xBDB7, 0x94E6, 0xBDB9,
+	0x94E7, 0xBDBA, 0x94E8, 0xBDBB, 0x94E9, 0xBDBC, 0x94EA, 0xBDBD,
+	0x94EB, 0xBDBE, 0x94EC, 0xBDBF, 0x94ED, 0xBDC0, 0x94EE, 0xBDC1,
+	0x94EF, 0xBDC2, 0x94F0, 0xBDC3, 0x94F1, 0xBDC4, 0x94F2, 0xBDC5,
+	0x94F3, 0xBDC6, 0x94F4, 0xBDC7, 0x94F5, 0xBDC8, 0x94F6, 0xBDC9,
+	0x94F7, 0xBDCA, 0x94F8, 0xBDCB, 0x94F9, 0xBDCC, 0x94FA, 0xBDCD,
+	0x94FB, 0xBDCE, 0x94FC, 0xBDCF, 0x94FD, 0xBDD0, 0x94FE, 0xBDD1,
+	0x9541, 0xBDD2, 0x9542, 0xBDD3, 0x9543, 0xBDD6, 0x9544, 0xBDD7,
+	0x9545, 0xBDD9, 0x9546, 0xBDDA, 0x9547, 0xBDDB, 0x9548, 0xBDDD,
+	0x9549, 0xBDDE, 0x954A, 0xBDDF, 0x954B, 0xBDE0, 0x954C, 0xBDE1,
+	0x954D, 0xBDE2, 0x954E, 0xBDE3, 0x954F, 0xBDE4, 0x9550, 0xBDE5,
+	0x9551, 0xBDE6, 0x9552, 0xBDE7, 0x9553, 0xBDE8, 0x9554, 0xBDEA,
+	0x9555, 0xBDEB, 0x9556, 0xBDEC, 0x9557, 0xBDED, 0x9558, 0xBDEE,
+	0x9559, 0xBDEF, 0x955A, 0xBDF1, 0x9561, 0xBDF2, 0x9562, 0xBDF3,
+	0x9563, 0xBDF5, 0x9564, 0xBDF6, 0x9565, 0xBDF7, 0x9566, 0xBDF9,
+	0x9567, 0xBDFA, 0x9568, 0xBDFB, 0x9569, 0xBDFC, 0x956A, 0xBDFD,
+	0x956B, 0xBDFE, 0x956C, 0xBDFF, 0x956D, 0xBE01, 0x956E, 0xBE02,
+	0x956F, 0xBE04, 0x9570, 0xBE06, 0x9571, 0xBE07, 0x9572, 0xBE08,
+	0x9573, 0xBE09, 0x9574, 0xBE0A, 0x9575, 0xBE0B, 0x9576, 0xBE0E,
+	0x9577, 0xBE0F, 0x9578, 0xBE11, 0x9579, 0xBE12, 0x957A, 0xBE13,
+	0x9581, 0xBE15, 0x9582, 0xBE16, 0x9583, 0xBE17, 0x9584, 0xBE18,
+	0x9585, 0xBE19, 0x9586, 0xBE1A, 0x9587, 0xBE1B, 0x9588, 0xBE1E,
+	0x9589, 0xBE20, 0x958A, 0xBE21, 0x958B, 0xBE22, 0x958C, 0xBE23,
+	0x958D, 0xBE24, 0x958E, 0xBE25, 0x958F, 0xBE26, 0x9590, 0xBE27,
+	0x9591, 0xBE28, 0x9592, 0xBE29, 0x9593, 0xBE2A, 0x9594, 0xBE2B,
+	0x9595, 0xBE2C, 0x9596, 0xBE2D, 0x9597, 0xBE2E, 0x9598, 0xBE2F,
+	0x9599, 0xBE30, 0x959A, 0xBE31, 0x959B, 0xBE32, 0x959C, 0xBE33,
+	0x959D, 0xBE34, 0x959E, 0xBE35, 0x959F, 0xBE36, 0x95A0, 0xBE37,
+	0x95A1, 0xBE38, 0x95A2, 0xBE39, 0x95A3, 0xBE3A, 0x95A4, 0xBE3B,
+	0x95A5, 0xBE3C, 0x95A6, 0xBE3D, 0x95A7, 0xBE3E, 0x95A8, 0xBE3F,
+	0x95A9, 0xBE40, 0x95AA, 0xBE41, 0x95AB, 0xBE42, 0x95AC, 0xBE43,
+	0x95AD, 0xBE46, 0x95AE, 0xBE47, 0x95AF, 0xBE49, 0x95B0, 0xBE4A,
+	0x95B1, 0xBE4B, 0x95B2, 0xBE4D, 0x95B3, 0xBE4F, 0x95B4, 0xBE50,
+	0x95B5, 0xBE51, 0x95B6, 0xBE52, 0x95B7, 0xBE53, 0x95B8, 0xBE56,
+	0x95B9, 0xBE58, 0x95BA, 0xBE5C, 0x95BB, 0xBE5D, 0x95BC, 0xBE5E,
+	0x95BD, 0xBE5F, 0x95BE, 0xBE62, 0x95BF, 0xBE63, 0x95C0, 0xBE65,
+	0x95C1, 0xBE66, 0x95C2, 0xBE67, 0x95C3, 0xBE69, 0x95C4, 0xBE6B,
+	0x95C5, 0xBE6C, 0x95C6, 0xBE6D, 0x95C7, 0xBE6E, 0x95C8, 0xBE6F,
+	0x95C9, 0xBE72, 0x95CA, 0xBE76, 0x95CB, 0xBE77, 0x95CC, 0xBE78,
+	0x95CD, 0xBE79, 0x95CE, 0xBE7A, 0x95CF, 0xBE7E, 0x95D0, 0xBE7F,
+	0x95D1, 0xBE81, 0x95D2, 0xBE82, 0x95D3, 0xBE83, 0x95D4, 0xBE85,
+	0x95D5, 0xBE86, 0x95D6, 0xBE87, 0x95D7, 0xBE88, 0x95D8, 0xBE89,
+	0x95D9, 0xBE8A, 0x95DA, 0xBE8B, 0x95DB, 0xBE8E, 0x95DC, 0xBE92,
+	0x95DD, 0xBE93, 0x95DE, 0xBE94, 0x95DF, 0xBE95, 0x95E0, 0xBE96,
+	0x95E1, 0xBE97, 0x95E2, 0xBE9A, 0x95E3, 0xBE9B, 0x95E4, 0xBE9C,
+	0x95E5, 0xBE9D, 0x95E6, 0xBE9E, 0x95E7, 0xBE9F, 0x95E8, 0xBEA0,
+	0x95E9, 0xBEA1, 0x95EA, 0xBEA2, 0x95EB, 0xBEA3, 0x95EC, 0xBEA4,
+	0x95ED, 0xBEA5, 0x95EE, 0xBEA6, 0x95EF, 0xBEA7, 0x95F0, 0xBEA9,
+	0x95F1, 0xBEAA, 0x95F2, 0xBEAB, 0x95F3, 0xBEAC, 0x95F4, 0xBEAD,
+	0x95F5, 0xBEAE, 0x95F6, 0xBEAF, 0x95F7, 0xBEB0, 0x95F8, 0xBEB1,
+	0x95F9, 0xBEB2, 0x95FA, 0xBEB3, 0x95FB, 0xBEB4, 0x95FC, 0xBEB5,
+	0x95FD, 0xBEB6, 0x95FE, 0xBEB7, 0x9641, 0xBEB8, 0x9642, 0xBEB9,
+	0x9643, 0xBEBA, 0x9644, 0xBEBB, 0x9645, 0xBEBC, 0x9646, 0xBEBD,
+	0x9647, 0xBEBE, 0x9648, 0xBEBF, 0x9649, 0xBEC0, 0x964A, 0xBEC1,
+	0x964B, 0xBEC2, 0x964C, 0xBEC3, 0x964D, 0xBEC4, 0x964E, 0xBEC5,
+	0x964F, 0xBEC6, 0x9650, 0xBEC7, 0x9651, 0xBEC8, 0x9652, 0xBEC9,
+	0x9653, 0xBECA, 0x9654, 0xBECB, 0x9655, 0xBECC, 0x9656, 0xBECD,
+	0x9657, 0xBECE, 0x9658, 0xBECF, 0x9659, 0xBED2, 0x965A, 0xBED3,
+	0x9661, 0xBED5, 0x9662, 0xBED6, 0x9663, 0xBED9, 0x9664, 0xBEDA,
+	0x9665, 0xBEDB, 0x9666, 0xBEDC, 0x9667, 0xBEDD, 0x9668, 0xBEDE,
+	0x9669, 0xBEDF, 0x966A, 0xBEE1, 0x966B, 0xBEE2, 0x966C, 0xBEE6,
+	0x966D, 0xBEE7, 0x966E, 0xBEE8, 0x966F, 0xBEE9, 0x9670, 0xBEEA,
+	0x9671, 0xBEEB, 0x9672, 0xBEED, 0x9673, 0xBEEE, 0x9674, 0xBEEF,
+	0x9675, 0xBEF0, 0x9676, 0xBEF1, 0x9677, 0xBEF2, 0x9678, 0xBEF3,
+	0x9679, 0xBEF4, 0x967A, 0xBEF5, 0x9681, 0xBEF6, 0x9682, 0xBEF7,
+	0x9683, 0xBEF8, 0x9684, 0xBEF9, 0x9685, 0xBEFA, 0x9686, 0xBEFB,
+	0x9687, 0xBEFC, 0x9688, 0xBEFD, 0x9689, 0xBEFE, 0x968A, 0xBEFF,
+	0x968B, 0xBF00, 0x968C, 0xBF02, 0x968D, 0xBF03, 0x968E, 0xBF04,
+	0x968F, 0xBF05, 0x9690, 0xBF06, 0x9691, 0xBF07, 0x9692, 0xBF0A,
+	0x9693, 0xBF0B, 0x9694, 0xBF0C, 0x9695, 0xBF0D, 0x9696, 0xBF0E,
+	0x9697, 0xBF0F, 0x9698, 0xBF10, 0x9699, 0xBF11, 0x969A, 0xBF12,
+	0x969B, 0xBF13, 0x969C, 0xBF14, 0x969D, 0xBF15, 0x969E, 0xBF16,
+	0x969F, 0xBF17, 0x96A0, 0xBF1A, 0x96A1, 0xBF1E, 0x96A2, 0xBF1F,
+	0x96A3, 0xBF20, 0x96A4, 0xBF21, 0x96A5, 0xBF22, 0x96A6, 0xBF23,
+	0x96A7, 0xBF24, 0x96A8, 0xBF25, 0x96A9, 0xBF26, 0x96AA, 0xBF27,
+	0x96AB, 0xBF28, 0x96AC, 0xBF29, 0x96AD, 0xBF2A, 0x96AE, 0xBF2B,
+	0x96AF, 0xBF2C, 0x96B0, 0xBF2D, 0x96B1, 0xBF2E, 0x96B2, 0xBF2F,
+	0x96B3, 0xBF30, 0x96B4, 0xBF31, 0x96B5, 0xBF32, 0x96B6, 0xBF33,
+	0x96B7, 0xBF34, 0x96B8, 0xBF35, 0x96B9, 0xBF36, 0x96BA, 0xBF37,
+	0x96BB, 0xBF38, 0x96BC, 0xBF39, 0x96BD, 0xBF3A, 0x96BE, 0xBF3B,
+	0x96BF, 0xBF3C, 0x96C0, 0xBF3D, 0x96C1, 0xBF3E, 0x96C2, 0xBF3F,
+	0x96C3, 0xBF42, 0x96C4, 0xBF43, 0x96C5, 0xBF45, 0x96C6, 0xBF46,
+	0x96C7, 0xBF47, 0x96C8, 0xBF49, 0x96C9, 0xBF4A, 0x96CA, 0xBF4B,
+	0x96CB, 0xBF4C, 0x96CC, 0xBF4D, 0x96CD, 0xBF4E, 0x96CE, 0xBF4F,
+	0x96CF, 0xBF52, 0x96D0, 0xBF53, 0x96D1, 0xBF54, 0x96D2, 0xBF56,
+	0x96D3, 0xBF57, 0x96D4, 0xBF58, 0x96D5, 0xBF59, 0x96D6, 0xBF5A,
+	0x96D7, 0xBF5B, 0x96D8, 0xBF5C, 0x96D9, 0xBF5D, 0x96DA, 0xBF5E,
+	0x96DB, 0xBF5F, 0x96DC, 0xBF60, 0x96DD, 0xBF61, 0x96DE, 0xBF62,
+	0x96DF, 0xBF63, 0x96E0, 0xBF64, 0x96E1, 0xBF65, 0x96E2, 0xBF66,
+	0x96E3, 0xBF67, 0x96E4, 0xBF68, 0x96E5, 0xBF69, 0x96E6, 0xBF6A,
+	0x96E7, 0xBF6B, 0x96E8, 0xBF6C, 0x96E9, 0xBF6D, 0x96EA, 0xBF6E,
+	0x96EB, 0xBF6F, 0x96EC, 0xBF70, 0x96ED, 0xBF71, 0x96EE, 0xBF72,
+	0x96EF, 0xBF73, 0x96F0, 0xBF74, 0x96F1, 0xBF75, 0x96F2, 0xBF76,
+	0x96F3, 0xBF77, 0x96F4, 0xBF78, 0x96F5, 0xBF79, 0x96F6, 0xBF7A,
+	0x96F7, 0xBF7B, 0x96F8, 0xBF7C, 0x96F9, 0xBF7D, 0x96FA, 0xBF7E,
+	0x96FB, 0xBF7F, 0x96FC, 0xBF80, 0x96FD, 0xBF81, 0x96FE, 0xBF82,
+	0x9741, 0xBF83, 0x9742, 0xBF84, 0x9743, 0xBF85, 0x9744, 0xBF86,
+	0x9745, 0xBF87, 0x9746, 0xBF88, 0x9747, 0xBF89, 0x9748, 0xBF8A,
+	0x9749, 0xBF8B, 0x974A, 0xBF8C, 0x974B, 0xBF8D, 0x974C, 0xBF8E,
+	0x974D, 0xBF8F, 0x974E, 0xBF90, 0x974F, 0xBF91, 0x9750, 0xBF92,
+	0x9751, 0xBF93, 0x9752, 0xBF95, 0x9753, 0xBF96, 0x9754, 0xBF97,
+	0x9755, 0xBF98, 0x9756, 0xBF99, 0x9757, 0xBF9A, 0x9758, 0xBF9B,
+	0x9759, 0xBF9C, 0x975A, 0xBF9D, 0x9761, 0xBF9E, 0x9762, 0xBF9F,
+	0x9763, 0xBFA0, 0x9764, 0xBFA1, 0x9765, 0xBFA2, 0x9766, 0xBFA3,
+	0x9767, 0xBFA4, 0x9768, 0xBFA5, 0x9769, 0xBFA6, 0x976A, 0xBFA7,
+	0x976B, 0xBFA8, 0x976C, 0xBFA9, 0x976D, 0xBFAA, 0x976E, 0xBFAB,
+	0x976F, 0xBFAC, 0x9770, 0xBFAD, 0x9771, 0xBFAE, 0x9772, 0xBFAF,
+	0x9773, 0xBFB1, 0x9774, 0xBFB2, 0x9775, 0xBFB3, 0x9776, 0xBFB4,
+	0x9777, 0xBFB5, 0x9778, 0xBFB6, 0x9779, 0xBFB7, 0x977A, 0xBFB8,
+	0x9781, 0xBFB9, 0x9782, 0xBFBA, 0x9783, 0xBFBB, 0x9784, 0xBFBC,
+	0x9785, 0xBFBD, 0x9786, 0xBFBE, 0x9787, 0xBFBF, 0x9788, 0xBFC0,
+	0x9789, 0xBFC1, 0x978A, 0xBFC2, 0x978B, 0xBFC3, 0x978C, 0xBFC4,
+	0x978D, 0xBFC6, 0x978E, 0xBFC7, 0x978F, 0xBFC8, 0x9790, 0xBFC9,
+	0x9791, 0xBFCA, 0x9792, 0xBFCB, 0x9793, 0xBFCE, 0x9794, 0xBFCF,
+	0x9795, 0xBFD1, 0x9796, 0xBFD2, 0x9797, 0xBFD3, 0x9798, 0xBFD5,
+	0x9799, 0xBFD6, 0x979A, 0xBFD7, 0x979B, 0xBFD8, 0x979C, 0xBFD9,
+	0x979D, 0xBFDA, 0x979E, 0xBFDB, 0x979F, 0xBFDD, 0x97A0, 0xBFDE,
+	0x97A1, 0xBFE0, 0x97A2, 0xBFE2, 0x97A3, 0xBFE3, 0x97A4, 0xBFE4,
+	0x97A5, 0xBFE5, 0x97A6, 0xBFE6, 0x97A7, 0xBFE7, 0x97A8, 0xBFE8,
+	0x97A9, 0xBFE9, 0x97AA, 0xBFEA, 0x97AB, 0xBFEB, 0x97AC, 0xBFEC,
+	0x97AD, 0xBFED, 0x97AE, 0xBFEE, 0x97AF, 0xBFEF, 0x97B0, 0xBFF0,
+	0x97B1, 0xBFF1, 0x97B2, 0xBFF2, 0x97B3, 0xBFF3, 0x97B4, 0xBFF4,
+	0x97B5, 0xBFF5, 0x97B6, 0xBFF6, 0x97B7, 0xBFF7, 0x97B8, 0xBFF8,
+	0x97B9, 0xBFF9, 0x97BA, 0xBFFA, 0x97BB, 0xBFFB, 0x97BC, 0xBFFC,
+	0x97BD, 0xBFFD, 0x97BE, 0xBFFE, 0x97BF, 0xBFFF, 0x97C0, 0xC000,
+	0x97C1, 0xC001, 0x97C2, 0xC002, 0x97C3, 0xC003, 0x97C4, 0xC004,
+	0x97C5, 0xC005, 0x97C6, 0xC006, 0x97C7, 0xC007, 0x97C8, 0xC008,
+	0x97C9, 0xC009, 0x97CA, 0xC00A, 0x97CB, 0xC00B, 0x97CC, 0xC00C,
+	0x97CD, 0xC00D, 0x97CE, 0xC00E, 0x97CF, 0xC00F, 0x97D0, 0xC010,
+	0x97D1, 0xC011, 0x97D2, 0xC012, 0x97D3, 0xC013, 0x97D4, 0xC014,
+	0x97D5, 0xC015, 0x97D6, 0xC016, 0x97D7, 0xC017, 0x97D8, 0xC018,
+	0x97D9, 0xC019, 0x97DA, 0xC01A, 0x97DB, 0xC01B, 0x97DC, 0xC01C,
+	0x97DD, 0xC01D, 0x97DE, 0xC01E, 0x97DF, 0xC01F, 0x97E0, 0xC020,
+	0x97E1, 0xC021, 0x97E2, 0xC022, 0x97E3, 0xC023, 0x97E4, 0xC024,
+	0x97E5, 0xC025, 0x97E6, 0xC026, 0x97E7, 0xC027, 0x97E8, 0xC028,
+	0x97E9, 0xC029, 0x97EA, 0xC02A, 0x97EB, 0xC02B, 0x97EC, 0xC02C,
+	0x97ED, 0xC02D, 0x97EE, 0xC02E, 0x97EF, 0xC02F, 0x97F0, 0xC030,
+	0x97F1, 0xC031, 0x97F2, 0xC032, 0x97F3, 0xC033, 0x97F4, 0xC034,
+	0x97F5, 0xC035, 0x97F6, 0xC036, 0x97F7, 0xC037, 0x97F8, 0xC038,
+	0x97F9, 0xC039, 0x97FA, 0xC03A, 0x97FB, 0xC03B, 0x97FC, 0xC03D,
+	0x97FD, 0xC03E, 0x97FE, 0xC03F, 0x9841, 0xC040, 0x9842, 0xC041,
+	0x9843, 0xC042, 0x9844, 0xC043, 0x9845, 0xC044, 0x9846, 0xC045,
+	0x9847, 0xC046, 0x9848, 0xC047, 0x9849, 0xC048, 0x984A, 0xC049,
+	0x984B, 0xC04A, 0x984C, 0xC04B, 0x984D, 0xC04C, 0x984E, 0xC04D,
+	0x984F, 0xC04E, 0x9850, 0xC04F, 0x9851, 0xC050, 0x9852, 0xC052,
+	0x9853, 0xC053, 0x9854, 0xC054, 0x9855, 0xC055, 0x9856, 0xC056,
+	0x9857, 0xC057, 0x9858, 0xC059, 0x9859, 0xC05A, 0x985A, 0xC05B,
+	0x9861, 0xC05D, 0x9862, 0xC05E, 0x9863, 0xC05F, 0x9864, 0xC061,
+	0x9865, 0xC062, 0x9866, 0xC063, 0x9867, 0xC064, 0x9868, 0xC065,
+	0x9869, 0xC066, 0x986A, 0xC067, 0x986B, 0xC06A, 0x986C, 0xC06B,
+	0x986D, 0xC06C, 0x986E, 0xC06D, 0x986F, 0xC06E, 0x9870, 0xC06F,
+	0x9871, 0xC070, 0x9872, 0xC071, 0x9873, 0xC072, 0x9874, 0xC073,
+	0x9875, 0xC074, 0x9876, 0xC075, 0x9877, 0xC076, 0x9878, 0xC077,
+	0x9879, 0xC078, 0x987A, 0xC079, 0x9881, 0xC07A, 0x9882, 0xC07B,
+	0x9883, 0xC07C, 0x9884, 0xC07D, 0x9885, 0xC07E, 0x9886, 0xC07F,
+	0x9887, 0xC080, 0x9888, 0xC081, 0x9889, 0xC082, 0x988A, 0xC083,
+	0x988B, 0xC084, 0x988C, 0xC085, 0x988D, 0xC086, 0x988E, 0xC087,
+	0x988F, 0xC088, 0x9890, 0xC089, 0x9891, 0xC08A, 0x9892, 0xC08B,
+	0x9893, 0xC08C, 0x9894, 0xC08D, 0x9895, 0xC08E, 0x9896, 0xC08F,
+	0x9897, 0xC092, 0x9898, 0xC093, 0x9899, 0xC095, 0x989A, 0xC096,
+	0x989B, 0xC097, 0x989C, 0xC099, 0x989D, 0xC09A, 0x989E, 0xC09B,
+	0x989F, 0xC09C, 0x98A0, 0xC09D, 0x98A1, 0xC09E, 0x98A2, 0xC09F,
+	0x98A3, 0xC0A2, 0x98A4, 0xC0A4, 0x98A5, 0xC0A6, 0x98A6, 0xC0A7,
+	0x98A7, 0xC0A8, 0x98A8, 0xC0A9, 0x98A9, 0xC0AA, 0x98AA, 0xC0AB,
+	0x98AB, 0xC0AE, 0x98AC, 0xC0B1, 0x98AD, 0xC0B2, 0x98AE, 0xC0B7,
+	0x98AF, 0xC0B8, 0x98B0, 0xC0B9, 0x98B1, 0xC0BA, 0x98B2, 0xC0BB,
+	0x98B3, 0xC0BE, 0x98B4, 0xC0C2, 0x98B5, 0xC0C3, 0x98B6, 0xC0C4,
+	0x98B7, 0xC0C6, 0x98B8, 0xC0C7, 0x98B9, 0xC0CA, 0x98BA, 0xC0CB,
+	0x98BB, 0xC0CD, 0x98BC, 0xC0CE, 0x98BD, 0xC0CF, 0x98BE, 0xC0D1,
+	0x98BF, 0xC0D2, 0x98C0, 0xC0D3, 0x98C1, 0xC0D4, 0x98C2, 0xC0D5,
+	0x98C3, 0xC0D6, 0x98C4, 0xC0D7, 0x98C5, 0xC0DA, 0x98C6, 0xC0DE,
+	0x98C7, 0xC0DF, 0x98C8, 0xC0E0, 0x98C9, 0xC0E1, 0x98CA, 0xC0E2,
+	0x98CB, 0xC0E3, 0x98CC, 0xC0E6, 0x98CD, 0xC0E7, 0x98CE, 0xC0E9,
+	0x98CF, 0xC0EA, 0x98D0, 0xC0EB, 0x98D1, 0xC0ED, 0x98D2, 0xC0EE,
+	0x98D3, 0xC0EF, 0x98D4, 0xC0F0, 0x98D5, 0xC0F1, 0x98D6, 0xC0F2,
+	0x98D7, 0xC0F3, 0x98D8, 0xC0F6, 0x98D9, 0xC0F8, 0x98DA, 0xC0FA,
+	0x98DB, 0xC0FB, 0x98DC, 0xC0FC, 0x98DD, 0xC0FD, 0x98DE, 0xC0FE,
+	0x98DF, 0xC0FF, 0x98E0, 0xC101, 0x98E1, 0xC102, 0x98E2, 0xC103,
+	0x98E3, 0xC105, 0x98E4, 0xC106, 0x98E5, 0xC107, 0x98E6, 0xC109,
+	0x98E7, 0xC10A, 0x98E8, 0xC10B, 0x98E9, 0xC10C, 0x98EA, 0xC10D,
+	0x98EB, 0xC10E, 0x98EC, 0xC10F, 0x98ED, 0xC111, 0x98EE, 0xC112,
+	0x98EF, 0xC113, 0x98F0, 0xC114, 0x98F1, 0xC116, 0x98F2, 0xC117,
+	0x98F3, 0xC118, 0x98F4, 0xC119, 0x98F5, 0xC11A, 0x98F6, 0xC11B,
+	0x98F7, 0xC121, 0x98F8, 0xC122, 0x98F9, 0xC125, 0x98FA, 0xC128,
+	0x98FB, 0xC129, 0x98FC, 0xC12A, 0x98FD, 0xC12B, 0x98FE, 0xC12E,
+	0x9941, 0xC132, 0x9942, 0xC133, 0x9943, 0xC134, 0x9944, 0xC135,
+	0x9945, 0xC137, 0x9946, 0xC13A, 0x9947, 0xC13B, 0x9948, 0xC13D,
+	0x9949, 0xC13E, 0x994A, 0xC13F, 0x994B, 0xC141, 0x994C, 0xC142,
+	0x994D, 0xC143, 0x994E, 0xC144, 0x994F, 0xC145, 0x9950, 0xC146,
+	0x9951, 0xC147, 0x9952, 0xC14A, 0x9953, 0xC14E, 0x9954, 0xC14F,
+	0x9955, 0xC150, 0x9956, 0xC151, 0x9957, 0xC152, 0x9958, 0xC153,
+	0x9959, 0xC156, 0x995A, 0xC157, 0x9961, 0xC159, 0x9962, 0xC15A,
+	0x9963, 0xC15B, 0x9964, 0xC15D, 0x9965, 0xC15E, 0x9966, 0xC15F,
+	0x9967, 0xC160, 0x9968, 0xC161, 0x9969, 0xC162, 0x996A, 0xC163,
+	0x996B, 0xC166, 0x996C, 0xC16A, 0x996D, 0xC16B, 0x996E, 0xC16C,
+	0x996F, 0xC16D, 0x9970, 0xC16E, 0x9971, 0xC16F, 0x9972, 0xC171,
+	0x9973, 0xC172, 0x9974, 0xC173, 0x9975, 0xC175, 0x9976, 0xC176,
+	0x9977, 0xC177, 0x9978, 0xC179, 0x9979, 0xC17A, 0x997A, 0xC17B,
+	0x9981, 0xC17C, 0x9982, 0xC17D, 0x9983, 0xC17E, 0x9984, 0xC17F,
+	0x9985, 0xC180, 0x9986, 0xC181, 0x9987, 0xC182, 0x9988, 0xC183,
+	0x9989, 0xC184, 0x998A, 0xC186, 0x998B, 0xC187, 0x998C, 0xC188,
+	0x998D, 0xC189, 0x998E, 0xC18A, 0x998F, 0xC18B, 0x9990, 0xC18F,
+	0x9991, 0xC191, 0x9992, 0xC192, 0x9993, 0xC193, 0x9994, 0xC195,
+	0x9995, 0xC197, 0x9996, 0xC198, 0x9997, 0xC199, 0x9998, 0xC19A,
+	0x9999, 0xC19B, 0x999A, 0xC19E, 0x999B, 0xC1A0, 0x999C, 0xC1A2,
+	0x999D, 0xC1A3, 0x999E, 0xC1A4, 0x999F, 0xC1A6, 0x99A0, 0xC1A7,
+	0x99A1, 0xC1AA, 0x99A2, 0xC1AB, 0x99A3, 0xC1AD, 0x99A4, 0xC1AE,
+	0x99A5, 0xC1AF, 0x99A6, 0xC1B1, 0x99A7, 0xC1B2, 0x99A8, 0xC1B3,
+	0x99A9, 0xC1B4, 0x99AA, 0xC1B5, 0x99AB, 0xC1B6, 0x99AC, 0xC1B7,
+	0x99AD, 0xC1B8, 0x99AE, 0xC1B9, 0x99AF, 0xC1BA, 0x99B0, 0xC1BB,
+	0x99B1, 0xC1BC, 0x99B2, 0xC1BE, 0x99B3, 0xC1BF, 0x99B4, 0xC1C0,
+	0x99B5, 0xC1C1, 0x99B6, 0xC1C2, 0x99B7, 0xC1C3, 0x99B8, 0xC1C5,
+	0x99B9, 0xC1C6, 0x99BA, 0xC1C7, 0x99BB, 0xC1C9, 0x99BC, 0xC1CA,
+	0x99BD, 0xC1CB, 0x99BE, 0xC1CD, 0x99BF, 0xC1CE, 0x99C0, 0xC1CF,
+	0x99C1, 0xC1D0, 0x99C2, 0xC1D1, 0x99C3, 0xC1D2, 0x99C4, 0xC1D3,
+	0x99C5, 0xC1D5, 0x99C6, 0xC1D6, 0x99C7, 0xC1D9, 0x99C8, 0xC1DA,
+	0x99C9, 0xC1DB, 0x99CA, 0xC1DC, 0x99CB, 0xC1DD, 0x99CC, 0xC1DE,
+	0x99CD, 0xC1DF, 0x99CE, 0xC1E1, 0x99CF, 0xC1E2, 0x99D0, 0xC1E3,
+	0x99D1, 0xC1E5, 0x99D2, 0xC1E6, 0x99D3, 0xC1E7, 0x99D4, 0xC1E9,
+	0x99D5, 0xC1EA, 0x99D6, 0xC1EB, 0x99D7, 0xC1EC, 0x99D8, 0xC1ED,
+	0x99D9, 0xC1EE, 0x99DA, 0xC1EF, 0x99DB, 0xC1F2, 0x99DC, 0xC1F4,
+	0x99DD, 0xC1F5, 0x99DE, 0xC1F6, 0x99DF, 0xC1F7, 0x99E0, 0xC1F8,
+	0x99E1, 0xC1F9, 0x99E2, 0xC1FA, 0x99E3, 0xC1FB, 0x99E4, 0xC1FE,
+	0x99E5, 0xC1FF, 0x99E6, 0xC201, 0x99E7, 0xC202, 0x99E8, 0xC203,
+	0x99E9, 0xC205, 0x99EA, 0xC206, 0x99EB, 0xC207, 0x99EC, 0xC208,
+	0x99ED, 0xC209, 0x99EE, 0xC20A, 0x99EF, 0xC20B, 0x99F0, 0xC20E,
+	0x99F1, 0xC210, 0x99F2, 0xC212, 0x99F3, 0xC213, 0x99F4, 0xC214,
+	0x99F5, 0xC215, 0x99F6, 0xC216, 0x99F7, 0xC217, 0x99F8, 0xC21A,
+	0x99F9, 0xC21B, 0x99FA, 0xC21D, 0x99FB, 0xC21E, 0x99FC, 0xC221,
+	0x99FD, 0xC222, 0x99FE, 0xC223, 0x9A41, 0xC224, 0x9A42, 0xC225,
+	0x9A43, 0xC226, 0x9A44, 0xC227, 0x9A45, 0xC22A, 0x9A46, 0xC22C,
+	0x9A47, 0xC22E, 0x9A48, 0xC230, 0x9A49, 0xC233, 0x9A4A, 0xC235,
+	0x9A4B, 0xC236, 0x9A4C, 0xC237, 0x9A4D, 0xC238, 0x9A4E, 0xC239,
+	0x9A4F, 0xC23A, 0x9A50, 0xC23B, 0x9A51, 0xC23C, 0x9A52, 0xC23D,
+	0x9A53, 0xC23E, 0x9A54, 0xC23F, 0x9A55, 0xC240, 0x9A56, 0xC241,
+	0x9A57, 0xC242, 0x9A58, 0xC243, 0x9A59, 0xC244, 0x9A5A, 0xC245,
+	0x9A61, 0xC246, 0x9A62, 0xC247, 0x9A63, 0xC249, 0x9A64, 0xC24A,
+	0x9A65, 0xC24B, 0x9A66, 0xC24C, 0x9A67, 0xC24D, 0x9A68, 0xC24E,
+	0x9A69, 0xC24F, 0x9A6A, 0xC252, 0x9A6B, 0xC253, 0x9A6C, 0xC255,
+	0x9A6D, 0xC256, 0x9A6E, 0xC257, 0x9A6F, 0xC259, 0x9A70, 0xC25A,
+	0x9A71, 0xC25B, 0x9A72, 0xC25C, 0x9A73, 0xC25D, 0x9A74, 0xC25E,
+	0x9A75, 0xC25F, 0x9A76, 0xC261, 0x9A77, 0xC262, 0x9A78, 0xC263,
+	0x9A79, 0xC264, 0x9A7A, 0xC266, 0x9A81, 0xC267, 0x9A82, 0xC268,
+	0x9A83, 0xC269, 0x9A84, 0xC26A, 0x9A85, 0xC26B, 0x9A86, 0xC26E,
+	0x9A87, 0xC26F, 0x9A88, 0xC271, 0x9A89, 0xC272, 0x9A8A, 0xC273,
+	0x9A8B, 0xC275, 0x9A8C, 0xC276, 0x9A8D, 0xC277, 0x9A8E, 0xC278,
+	0x9A8F, 0xC279, 0x9A90, 0xC27A, 0x9A91, 0xC27B, 0x9A92, 0xC27E,
+	0x9A93, 0xC280, 0x9A94, 0xC282, 0x9A95, 0xC283, 0x9A96, 0xC284,
+	0x9A97, 0xC285, 0x9A98, 0xC286, 0x9A99, 0xC287, 0x9A9A, 0xC28A,
+	0x9A9B, 0xC28B, 0x9A9C, 0xC28C, 0x9A9D, 0xC28D, 0x9A9E, 0xC28E,
+	0x9A9F, 0xC28F, 0x9AA0, 0xC291, 0x9AA1, 0xC292, 0x9AA2, 0xC293,
+	0x9AA3, 0xC294, 0x9AA4, 0xC295, 0x9AA5, 0xC296, 0x9AA6, 0xC297,
+	0x9AA7, 0xC299, 0x9AA8, 0xC29A, 0x9AA9, 0xC29C, 0x9AAA, 0xC29E,
+	0x9AAB, 0xC29F, 0x9AAC, 0xC2A0, 0x9AAD, 0xC2A1, 0x9AAE, 0xC2A2,
+	0x9AAF, 0xC2A3, 0x9AB0, 0xC2A6, 0x9AB1, 0xC2A7, 0x9AB2, 0xC2A9,
+	0x9AB3, 0xC2AA, 0x9AB4, 0xC2AB, 0x9AB5, 0xC2AE, 0x9AB6, 0xC2AF,
+	0x9AB7, 0xC2B0, 0x9AB8, 0xC2B1, 0x9AB9, 0xC2B2, 0x9ABA, 0xC2B3,
+	0x9ABB, 0xC2B6, 0x9ABC, 0xC2B8, 0x9ABD, 0xC2BA, 0x9ABE, 0xC2BB,
+	0x9ABF, 0xC2BC, 0x9AC0, 0xC2BD, 0x9AC1, 0xC2BE, 0x9AC2, 0xC2BF,
+	0x9AC3, 0xC2C0, 0x9AC4, 0xC2C1, 0x9AC5, 0xC2C2, 0x9AC6, 0xC2C3,
+	0x9AC7, 0xC2C4, 0x9AC8, 0xC2C5, 0x9AC9, 0xC2C6, 0x9ACA, 0xC2C7,
+	0x9ACB, 0xC2C8, 0x9ACC, 0xC2C9, 0x9ACD, 0xC2CA, 0x9ACE, 0xC2CB,
+	0x9ACF, 0xC2CC, 0x9AD0, 0xC2CD, 0x9AD1, 0xC2CE, 0x9AD2, 0xC2CF,
+	0x9AD3, 0xC2D0, 0x9AD4, 0xC2D1, 0x9AD5, 0xC2D2, 0x9AD6, 0xC2D3,
+	0x9AD7, 0xC2D4, 0x9AD8, 0xC2D5, 0x9AD9, 0xC2D6, 0x9ADA, 0xC2D7,
+	0x9ADB, 0xC2D8, 0x9ADC, 0xC2D9, 0x9ADD, 0xC2DA, 0x9ADE, 0xC2DB,
+	0x9ADF, 0xC2DE, 0x9AE0, 0xC2DF, 0x9AE1, 0xC2E1, 0x9AE2, 0xC2E2,
+	0x9AE3, 0xC2E5, 0x9AE4, 0xC2E6, 0x9AE5, 0xC2E7, 0x9AE6, 0xC2E8,
+	0x9AE7, 0xC2E9, 0x9AE8, 0xC2EA, 0x9AE9, 0xC2EE, 0x9AEA, 0xC2F0,
+	0x9AEB, 0xC2F2, 0x9AEC, 0xC2F3, 0x9AED, 0xC2F4, 0x9AEE, 0xC2F5,
+	0x9AEF, 0xC2F7, 0x9AF0, 0xC2FA, 0x9AF1, 0xC2FD, 0x9AF2, 0xC2FE,
+	0x9AF3, 0xC2FF, 0x9AF4, 0xC301, 0x9AF5, 0xC302, 0x9AF6, 0xC303,
+	0x9AF7, 0xC304, 0x9AF8, 0xC305, 0x9AF9, 0xC306, 0x9AFA, 0xC307,
+	0x9AFB, 0xC30A, 0x9AFC, 0xC30B, 0x9AFD, 0xC30E, 0x9AFE, 0xC30F,
+	0x9B41, 0xC310, 0x9B42, 0xC311, 0x9B43, 0xC312, 0x9B44, 0xC316,
+	0x9B45, 0xC317, 0x9B46, 0xC319, 0x9B47, 0xC31A, 0x9B48, 0xC31B,
+	0x9B49, 0xC31D, 0x9B4A, 0xC31E, 0x9B4B, 0xC31F, 0x9B4C, 0xC320,
+	0x9B4D, 0xC321, 0x9B4E, 0xC322, 0x9B4F, 0xC323, 0x9B50, 0xC326,
+	0x9B51, 0xC327, 0x9B52, 0xC32A, 0x9B53, 0xC32B, 0x9B54, 0xC32C,
+	0x9B55, 0xC32D, 0x9B56, 0xC32E, 0x9B57, 0xC32F, 0x9B58, 0xC330,
+	0x9B59, 0xC331, 0x9B5A, 0xC332, 0x9B61, 0xC333, 0x9B62, 0xC334,
+	0x9B63, 0xC335, 0x9B64, 0xC336, 0x9B65, 0xC337, 0x9B66, 0xC338,
+	0x9B67, 0xC339, 0x9B68, 0xC33A, 0x9B69, 0xC33B, 0x9B6A, 0xC33C,
+	0x9B6B, 0xC33D, 0x9B6C, 0xC33E, 0x9B6D, 0xC33F, 0x9B6E, 0xC340,
+	0x9B6F, 0xC341, 0x9B70, 0xC342, 0x9B71, 0xC343, 0x9B72, 0xC344,
+	0x9B73, 0xC346, 0x9B74, 0xC347, 0x9B75, 0xC348, 0x9B76, 0xC349,
+	0x9B77, 0xC34A, 0x9B78, 0xC34B, 0x9B79, 0xC34C, 0x9B7A, 0xC34D,
+	0x9B81, 0xC34E, 0x9B82, 0xC34F, 0x9B83, 0xC350, 0x9B84, 0xC351,
+	0x9B85, 0xC352, 0x9B86, 0xC353, 0x9B87, 0xC354, 0x9B88, 0xC355,
+	0x9B89, 0xC356, 0x9B8A, 0xC357, 0x9B8B, 0xC358, 0x9B8C, 0xC359,
+	0x9B8D, 0xC35A, 0x9B8E, 0xC35B, 0x9B8F, 0xC35C, 0x9B90, 0xC35D,
+	0x9B91, 0xC35E, 0x9B92, 0xC35F, 0x9B93, 0xC360, 0x9B94, 0xC361,
+	0x9B95, 0xC362, 0x9B96, 0xC363, 0x9B97, 0xC364, 0x9B98, 0xC365,
+	0x9B99, 0xC366, 0x9B9A, 0xC367, 0x9B9B, 0xC36A, 0x9B9C, 0xC36B,
+	0x9B9D, 0xC36D, 0x9B9E, 0xC36E, 0x9B9F, 0xC36F, 0x9BA0, 0xC371,
+	0x9BA1, 0xC373, 0x9BA2, 0xC374, 0x9BA3, 0xC375, 0x9BA4, 0xC376,
+	0x9BA5, 0xC377, 0x9BA6, 0xC37A, 0x9BA7, 0xC37B, 0x9BA8, 0xC37E,
+	0x9BA9, 0xC37F, 0x9BAA, 0xC380, 0x9BAB, 0xC381, 0x9BAC, 0xC382,
+	0x9BAD, 0xC383, 0x9BAE, 0xC385, 0x9BAF, 0xC386, 0x9BB0, 0xC387,
+	0x9BB1, 0xC389, 0x9BB2, 0xC38A, 0x9BB3, 0xC38B, 0x9BB4, 0xC38D,
+	0x9BB5, 0xC38E, 0x9BB6, 0xC38F, 0x9BB7, 0xC390, 0x9BB8, 0xC391,
+	0x9BB9, 0xC392, 0x9BBA, 0xC393, 0x9BBB, 0xC394, 0x9BBC, 0xC395,
+	0x9BBD, 0xC396, 0x9BBE, 0xC397, 0x9BBF, 0xC398, 0x9BC0, 0xC399,
+	0x9BC1, 0xC39A, 0x9BC2, 0xC39B, 0x9BC3, 0xC39C, 0x9BC4, 0xC39D,
+	0x9BC5, 0xC39E, 0x9BC6, 0xC39F, 0x9BC7, 0xC3A0, 0x9BC8, 0xC3A1,
+	0x9BC9, 0xC3A2, 0x9BCA, 0xC3A3, 0x9BCB, 0xC3A4, 0x9BCC, 0xC3A5,
+	0x9BCD, 0xC3A6, 0x9BCE, 0xC3A7, 0x9BCF, 0xC3A8, 0x9BD0, 0xC3A9,
+	0x9BD1, 0xC3AA, 0x9BD2, 0xC3AB, 0x9BD3, 0xC3AC, 0x9BD4, 0xC3AD,
+	0x9BD5, 0xC3AE, 0x9BD6, 0xC3AF, 0x9BD7, 0xC3B0, 0x9BD8, 0xC3B1,
+	0x9BD9, 0xC3B2, 0x9BDA, 0xC3B3, 0x9BDB, 0xC3B4, 0x9BDC, 0xC3B5,
+	0x9BDD, 0xC3B6, 0x9BDE, 0xC3B7, 0x9BDF, 0xC3B8, 0x9BE0, 0xC3B9,
+	0x9BE1, 0xC3BA, 0x9BE2, 0xC3BB, 0x9BE3, 0xC3BC, 0x9BE4, 0xC3BD,
+	0x9BE5, 0xC3BE, 0x9BE6, 0xC3BF, 0x9BE7, 0xC3C1, 0x9BE8, 0xC3C2,
+	0x9BE9, 0xC3C3, 0x9BEA, 0xC3C4, 0x9BEB, 0xC3C5, 0x9BEC, 0xC3C6,
+	0x9BED, 0xC3C7, 0x9BEE, 0xC3C8, 0x9BEF, 0xC3C9, 0x9BF0, 0xC3CA,
+	0x9BF1, 0xC3CB, 0x9BF2, 0xC3CC, 0x9BF3, 0xC3CD, 0x9BF4, 0xC3CE,
+	0x9BF5, 0xC3CF, 0x9BF6, 0xC3D0, 0x9BF7, 0xC3D1, 0x9BF8, 0xC3D2,
+	0x9BF9, 0xC3D3, 0x9BFA, 0xC3D4, 0x9BFB, 0xC3D5, 0x9BFC, 0xC3D6,
+	0x9BFD, 0xC3D7, 0x9BFE, 0xC3DA, 0x9C41, 0xC3DB, 0x9C42, 0xC3DD,
+	0x9C43, 0xC3DE, 0x9C44, 0xC3E1, 0x9C45, 0xC3E3, 0x9C46, 0xC3E4,
+	0x9C47, 0xC3E5, 0x9C48, 0xC3E6, 0x9C49, 0xC3E7, 0x9C4A, 0xC3EA,
+	0x9C4B, 0xC3EB, 0x9C4C, 0xC3EC, 0x9C4D, 0xC3EE, 0x9C4E, 0xC3EF,
+	0x9C4F, 0xC3F0, 0x9C50, 0xC3F1, 0x9C51, 0xC3F2, 0x9C52, 0xC3F3,
+	0x9C53, 0xC3F6, 0x9C54, 0xC3F7, 0x9C55, 0xC3F9, 0x9C56, 0xC3FA,
+	0x9C57, 0xC3FB, 0x9C58, 0xC3FC, 0x9C59, 0xC3FD, 0x9C5A, 0xC3FE,
+	0x9C61, 0xC3FF, 0x9C62, 0xC400, 0x9C63, 0xC401, 0x9C64, 0xC402,
+	0x9C65, 0xC403, 0x9C66, 0xC404, 0x9C67, 0xC405, 0x9C68, 0xC406,
+	0x9C69, 0xC407, 0x9C6A, 0xC409, 0x9C6B, 0xC40A, 0x9C6C, 0xC40B,
+	0x9C6D, 0xC40C, 0x9C6E, 0xC40D, 0x9C6F, 0xC40E, 0x9C70, 0xC40F,
+	0x9C71, 0xC411, 0x9C72, 0xC412, 0x9C73, 0xC413, 0x9C74, 0xC414,
+	0x9C75, 0xC415, 0x9C76, 0xC416, 0x9C77, 0xC417, 0x9C78, 0xC418,
+	0x9C79, 0xC419, 0x9C7A, 0xC41A, 0x9C81, 0xC41B, 0x9C82, 0xC41C,
+	0x9C83, 0xC41D, 0x9C84, 0xC41E, 0x9C85, 0xC41F, 0x9C86, 0xC420,
+	0x9C87, 0xC421, 0x9C88, 0xC422, 0x9C89, 0xC423, 0x9C8A, 0xC425,
+	0x9C8B, 0xC426, 0x9C8C, 0xC427, 0x9C8D, 0xC428, 0x9C8E, 0xC429,
+	0x9C8F, 0xC42A, 0x9C90, 0xC42B, 0x9C91, 0xC42D, 0x9C92, 0xC42E,
+	0x9C93, 0xC42F, 0x9C94, 0xC431, 0x9C95, 0xC432, 0x9C96, 0xC433,
+	0x9C97, 0xC435, 0x9C98, 0xC436, 0x9C99, 0xC437, 0x9C9A, 0xC438,
+	0x9C9B, 0xC439, 0x9C9C, 0xC43A, 0x9C9D, 0xC43B, 0x9C9E, 0xC43E,
+	0x9C9F, 0xC43F, 0x9CA0, 0xC440, 0x9CA1, 0xC441, 0x9CA2, 0xC442,
+	0x9CA3, 0xC443, 0x9CA4, 0xC444, 0x9CA5, 0xC445, 0x9CA6, 0xC446,
+	0x9CA7, 0xC447, 0x9CA8, 0xC449, 0x9CA9, 0xC44A, 0x9CAA, 0xC44B,
+	0x9CAB, 0xC44C, 0x9CAC, 0xC44D, 0x9CAD, 0xC44E, 0x9CAE, 0xC44F,
+	0x9CAF, 0xC450, 0x9CB0, 0xC451, 0x9CB1, 0xC452, 0x9CB2, 0xC453,
+	0x9CB3, 0xC454, 0x9CB4, 0xC455, 0x9CB5, 0xC456, 0x9CB6, 0xC457,
+	0x9CB7, 0xC458, 0x9CB8, 0xC459, 0x9CB9, 0xC45A, 0x9CBA, 0xC45B,
+	0x9CBB, 0xC45C, 0x9CBC, 0xC45D, 0x9CBD, 0xC45E, 0x9CBE, 0xC45F,
+	0x9CBF, 0xC460, 0x9CC0, 0xC461, 0x9CC1, 0xC462, 0x9CC2, 0xC463,
+	0x9CC3, 0xC466, 0x9CC4, 0xC467, 0x9CC5, 0xC469, 0x9CC6, 0xC46A,
+	0x9CC7, 0xC46B, 0x9CC8, 0xC46D, 0x9CC9, 0xC46E, 0x9CCA, 0xC46F,
+	0x9CCB, 0xC470, 0x9CCC, 0xC471, 0x9CCD, 0xC472, 0x9CCE, 0xC473,
+	0x9CCF, 0xC476, 0x9CD0, 0xC477, 0x9CD1, 0xC478, 0x9CD2, 0xC47A,
+	0x9CD3, 0xC47B, 0x9CD4, 0xC47C, 0x9CD5, 0xC47D, 0x9CD6, 0xC47E,
+	0x9CD7, 0xC47F, 0x9CD8, 0xC481, 0x9CD9, 0xC482, 0x9CDA, 0xC483,
+	0x9CDB, 0xC484, 0x9CDC, 0xC485, 0x9CDD, 0xC486, 0x9CDE, 0xC487,
+	0x9CDF, 0xC488, 0x9CE0, 0xC489, 0x9CE1, 0xC48A, 0x9CE2, 0xC48B,
+	0x9CE3, 0xC48C, 0x9CE4, 0xC48D, 0x9CE5, 0xC48E, 0x9CE6, 0xC48F,
+	0x9CE7, 0xC490, 0x9CE8, 0xC491, 0x9CE9, 0xC492, 0x9CEA, 0xC493,
+	0x9CEB, 0xC495, 0x9CEC, 0xC496, 0x9CED, 0xC497, 0x9CEE, 0xC498,
+	0x9CEF, 0xC499, 0x9CF0, 0xC49A, 0x9CF1, 0xC49B, 0x9CF2, 0xC49D,
+	0x9CF3, 0xC49E, 0x9CF4, 0xC49F, 0x9CF5, 0xC4A0, 0x9CF6, 0xC4A1,
+	0x9CF7, 0xC4A2, 0x9CF8, 0xC4A3, 0x9CF9, 0xC4A4, 0x9CFA, 0xC4A5,
+	0x9CFB, 0xC4A6, 0x9CFC, 0xC4A7, 0x9CFD, 0xC4A8, 0x9CFE, 0xC4A9,
+	0x9D41, 0xC4AA, 0x9D42, 0xC4AB, 0x9D43, 0xC4AC, 0x9D44, 0xC4AD,
+	0x9D45, 0xC4AE, 0x9D46, 0xC4AF, 0x9D47, 0xC4B0, 0x9D48, 0xC4B1,
+	0x9D49, 0xC4B2, 0x9D4A, 0xC4B3, 0x9D4B, 0xC4B4, 0x9D4C, 0xC4B5,
+	0x9D4D, 0xC4B6, 0x9D4E, 0xC4B7, 0x9D4F, 0xC4B9, 0x9D50, 0xC4BA,
+	0x9D51, 0xC4BB, 0x9D52, 0xC4BD, 0x9D53, 0xC4BE, 0x9D54, 0xC4BF,
+	0x9D55, 0xC4C0, 0x9D56, 0xC4C1, 0x9D57, 0xC4C2, 0x9D58, 0xC4C3,
+	0x9D59, 0xC4C4, 0x9D5A, 0xC4C5, 0x9D61, 0xC4C6, 0x9D62, 0xC4C7,
+	0x9D63, 0xC4C8, 0x9D64, 0xC4C9, 0x9D65, 0xC4CA, 0x9D66, 0xC4CB,
+	0x9D67, 0xC4CC, 0x9D68, 0xC4CD, 0x9D69, 0xC4CE, 0x9D6A, 0xC4CF,
+	0x9D6B, 0xC4D0, 0x9D6C, 0xC4D1, 0x9D6D, 0xC4D2, 0x9D6E, 0xC4D3,
+	0x9D6F, 0xC4D4, 0x9D70, 0xC4D5, 0x9D71, 0xC4D6, 0x9D72, 0xC4D7,
+	0x9D73, 0xC4D8, 0x9D74, 0xC4D9, 0x9D75, 0xC4DA, 0x9D76, 0xC4DB,
+	0x9D77, 0xC4DC, 0x9D78, 0xC4DD, 0x9D79, 0xC4DE, 0x9D7A, 0xC4DF,
+	0x9D81, 0xC4E0, 0x9D82, 0xC4E1, 0x9D83, 0xC4E2, 0x9D84, 0xC4E3,
+	0x9D85, 0xC4E4, 0x9D86, 0xC4E5, 0x9D87, 0xC4E6, 0x9D88, 0xC4E7,
+	0x9D89, 0xC4E8, 0x9D8A, 0xC4EA, 0x9D8B, 0xC4EB, 0x9D8C, 0xC4EC,
+	0x9D8D, 0xC4ED, 0x9D8E, 0xC4EE, 0x9D8F, 0xC4EF, 0x9D90, 0xC4F2,
+	0x9D91, 0xC4F3, 0x9D92, 0xC4F5, 0x9D93, 0xC4F6, 0x9D94, 0xC4F7,
+	0x9D95, 0xC4F9, 0x9D96, 0xC4FB, 0x9D97, 0xC4FC, 0x9D98, 0xC4FD,
+	0x9D99, 0xC4FE, 0x9D9A, 0xC502, 0x9D9B, 0xC503, 0x9D9C, 0xC504,
+	0x9D9D, 0xC505, 0x9D9E, 0xC506, 0x9D9F, 0xC507, 0x9DA0, 0xC508,
+	0x9DA1, 0xC509, 0x9DA2, 0xC50A, 0x9DA3, 0xC50B, 0x9DA4, 0xC50D,
+	0x9DA5, 0xC50E, 0x9DA6, 0xC50F, 0x9DA7, 0xC511, 0x9DA8, 0xC512,
+	0x9DA9, 0xC513, 0x9DAA, 0xC515, 0x9DAB, 0xC516, 0x9DAC, 0xC517,
+	0x9DAD, 0xC518, 0x9DAE, 0xC519, 0x9DAF, 0xC51A, 0x9DB0, 0xC51B,
+	0x9DB1, 0xC51D, 0x9DB2, 0xC51E, 0x9DB3, 0xC51F, 0x9DB4, 0xC520,
+	0x9DB5, 0xC521, 0x9DB6, 0xC522, 0x9DB7, 0xC523, 0x9DB8, 0xC524,
+	0x9DB9, 0xC525, 0x9DBA, 0xC526, 0x9DBB, 0xC527, 0x9DBC, 0xC52A,
+	0x9DBD, 0xC52B, 0x9DBE, 0xC52D, 0x9DBF, 0xC52E, 0x9DC0, 0xC52F,
+	0x9DC1, 0xC531, 0x9DC2, 0xC532, 0x9DC3, 0xC533, 0x9DC4, 0xC534,
+	0x9DC5, 0xC535, 0x9DC6, 0xC536, 0x9DC7, 0xC537, 0x9DC8, 0xC53A,
+	0x9DC9, 0xC53C, 0x9DCA, 0xC53E, 0x9DCB, 0xC53F, 0x9DCC, 0xC540,
+	0x9DCD, 0xC541, 0x9DCE, 0xC542, 0x9DCF, 0xC543, 0x9DD0, 0xC546,
+	0x9DD1, 0xC547, 0x9DD2, 0xC54B, 0x9DD3, 0xC54F, 0x9DD4, 0xC550,
+	0x9DD5, 0xC551, 0x9DD6, 0xC552, 0x9DD7, 0xC556, 0x9DD8, 0xC55A,
+	0x9DD9, 0xC55B, 0x9DDA, 0xC55C, 0x9DDB, 0xC55F, 0x9DDC, 0xC562,
+	0x9DDD, 0xC563, 0x9DDE, 0xC565, 0x9DDF, 0xC566, 0x9DE0, 0xC567,
+	0x9DE1, 0xC569, 0x9DE2, 0xC56A, 0x9DE3, 0xC56B, 0x9DE4, 0xC56C,
+	0x9DE5, 0xC56D, 0x9DE6, 0xC56E, 0x9DE7, 0xC56F, 0x9DE8, 0xC572,
+	0x9DE9, 0xC576, 0x9DEA, 0xC577, 0x9DEB, 0xC578, 0x9DEC, 0xC579,
+	0x9DED, 0xC57A, 0x9DEE, 0xC57B, 0x9DEF, 0xC57E, 0x9DF0, 0xC57F,
+	0x9DF1, 0xC581, 0x9DF2, 0xC582, 0x9DF3, 0xC583, 0x9DF4, 0xC585,
+	0x9DF5, 0xC586, 0x9DF6, 0xC588, 0x9DF7, 0xC589, 0x9DF8, 0xC58A,
+	0x9DF9, 0xC58B, 0x9DFA, 0xC58E, 0x9DFB, 0xC590, 0x9DFC, 0xC592,
+	0x9DFD, 0xC593, 0x9DFE, 0xC594, 0x9E41, 0xC596, 0x9E42, 0xC599,
+	0x9E43, 0xC59A, 0x9E44, 0xC59B, 0x9E45, 0xC59D, 0x9E46, 0xC59E,
+	0x9E47, 0xC59F, 0x9E48, 0xC5A1, 0x9E49, 0xC5A2, 0x9E4A, 0xC5A3,
+	0x9E4B, 0xC5A4, 0x9E4C, 0xC5A5, 0x9E4D, 0xC5A6, 0x9E4E, 0xC5A7,
+	0x9E4F, 0xC5A8, 0x9E50, 0xC5AA, 0x9E51, 0xC5AB, 0x9E52, 0xC5AC,
+	0x9E53, 0xC5AD, 0x9E54, 0xC5AE, 0x9E55, 0xC5AF, 0x9E56, 0xC5B0,
+	0x9E57, 0xC5B1, 0x9E58, 0xC5B2, 0x9E59, 0xC5B3, 0x9E5A, 0xC5B6,
+	0x9E61, 0xC5B7, 0x9E62, 0xC5BA, 0x9E63, 0xC5BF, 0x9E64, 0xC5C0,
+	0x9E65, 0xC5C1, 0x9E66, 0xC5C2, 0x9E67, 0xC5C3, 0x9E68, 0xC5CB,
+	0x9E69, 0xC5CD, 0x9E6A, 0xC5CF, 0x9E6B, 0xC5D2, 0x9E6C, 0xC5D3,
+	0x9E6D, 0xC5D5, 0x9E6E, 0xC5D6, 0x9E6F, 0xC5D7, 0x9E70, 0xC5D9,
+	0x9E71, 0xC5DA, 0x9E72, 0xC5DB, 0x9E73, 0xC5DC, 0x9E74, 0xC5DD,
+	0x9E75, 0xC5DE, 0x9E76, 0xC5DF, 0x9E77, 0xC5E2, 0x9E78, 0xC5E4,
+	0x9E79, 0xC5E6, 0x9E7A, 0xC5E7, 0x9E81, 0xC5E8, 0x9E82, 0xC5E9,
+	0x9E83, 0xC5EA, 0x9E84, 0xC5EB, 0x9E85, 0xC5EF, 0x9E86, 0xC5F1,
+	0x9E87, 0xC5F2, 0x9E88, 0xC5F3, 0x9E89, 0xC5F5, 0x9E8A, 0xC5F8,
+	0x9E8B, 0xC5F9, 0x9E8C, 0xC5FA, 0x9E8D, 0xC5FB, 0x9E8E, 0xC602,
+	0x9E8F, 0xC603, 0x9E90, 0xC604, 0x9E91, 0xC609, 0x9E92, 0xC60A,
+	0x9E93, 0xC60B, 0x9E94, 0xC60D, 0x9E95, 0xC60E, 0x9E96, 0xC60F,
+	0x9E97, 0xC611, 0x9E98, 0xC612, 0x9E99, 0xC613, 0x9E9A, 0xC614,
+	0x9E9B, 0xC615, 0x9E9C, 0xC616, 0x9E9D, 0xC617, 0x9E9E, 0xC61A,
+	0x9E9F, 0xC61D, 0x9EA0, 0xC61E, 0x9EA1, 0xC61F, 0x9EA2, 0xC620,
+	0x9EA3, 0xC621, 0x9EA4, 0xC622, 0x9EA5, 0xC623, 0x9EA6, 0xC626,
+	0x9EA7, 0xC627, 0x9EA8, 0xC629, 0x9EA9, 0xC62A, 0x9EAA, 0xC62B,
+	0x9EAB, 0xC62F, 0x9EAC, 0xC631, 0x9EAD, 0xC632, 0x9EAE, 0xC636,
+	0x9EAF, 0xC638, 0x9EB0, 0xC63A, 0x9EB1, 0xC63C, 0x9EB2, 0xC63D,
+	0x9EB3, 0xC63E, 0x9EB4, 0xC63F, 0x9EB5, 0xC642, 0x9EB6, 0xC643,
+	0x9EB7, 0xC645, 0x9EB8, 0xC646, 0x9EB9, 0xC647, 0x9EBA, 0xC649,
+	0x9EBB, 0xC64A, 0x9EBC, 0xC64B, 0x9EBD, 0xC64C, 0x9EBE, 0xC64D,
+	0x9EBF, 0xC64E, 0x9EC0, 0xC64F, 0x9EC1, 0xC652, 0x9EC2, 0xC656,
+	0x9EC3, 0xC657, 0x9EC4, 0xC658, 0x9EC5, 0xC659, 0x9EC6, 0xC65A,
+	0x9EC7, 0xC65B, 0x9EC8, 0xC65E, 0x9EC9, 0xC65F, 0x9ECA, 0xC661,
+	0x9ECB, 0xC662, 0x9ECC, 0xC663, 0x9ECD, 0xC664, 0x9ECE, 0xC665,
+	0x9ECF, 0xC666, 0x9ED0, 0xC667, 0x9ED1, 0xC668, 0x9ED2, 0xC669,
+	0x9ED3, 0xC66A, 0x9ED4, 0xC66B, 0x9ED5, 0xC66D, 0x9ED6, 0xC66E,
+	0x9ED7, 0xC670, 0x9ED8, 0xC672, 0x9ED9, 0xC673, 0x9EDA, 0xC674,
+	0x9EDB, 0xC675, 0x9EDC, 0xC676, 0x9EDD, 0xC677, 0x9EDE, 0xC67A,
+	0x9EDF, 0xC67B, 0x9EE0, 0xC67D, 0x9EE1, 0xC67E, 0x9EE2, 0xC67F,
+	0x9EE3, 0xC681, 0x9EE4, 0xC682, 0x9EE5, 0xC683, 0x9EE6, 0xC684,
+	0x9EE7, 0xC685, 0x9EE8, 0xC686, 0x9EE9, 0xC687, 0x9EEA, 0xC68A,
+	0x9EEB, 0xC68C, 0x9EEC, 0xC68E, 0x9EED, 0xC68F, 0x9EEE, 0xC690,
+	0x9EEF, 0xC691, 0x9EF0, 0xC692, 0x9EF1, 0xC693, 0x9EF2, 0xC696,
+	0x9EF3, 0xC697, 0x9EF4, 0xC699, 0x9EF5, 0xC69A, 0x9EF6, 0xC69B,
+	0x9EF7, 0xC69D, 0x9EF8, 0xC69E, 0x9EF9, 0xC69F, 0x9EFA, 0xC6A0,
+	0x9EFB, 0xC6A1, 0x9EFC, 0xC6A2, 0x9EFD, 0xC6A3, 0x9EFE, 0xC6A6,
+	0x9F41, 0xC6A8, 0x9F42, 0xC6AA, 0x9F43, 0xC6AB, 0x9F44, 0xC6AC,
+	0x9F45, 0xC6AD, 0x9F46, 0xC6AE, 0x9F47, 0xC6AF, 0x9F48, 0xC6B2,
+	0x9F49, 0xC6B3, 0x9F4A, 0xC6B5, 0x9F4B, 0xC6B6, 0x9F4C, 0xC6B7,
+	0x9F4D, 0xC6BB, 0x9F4E, 0xC6BC, 0x9F4F, 0xC6BD, 0x9F50, 0xC6BE,
+	0x9F51, 0xC6BF, 0x9F52, 0xC6C2, 0x9F53, 0xC6C4, 0x9F54, 0xC6C6,
+	0x9F55, 0xC6C7, 0x9F56, 0xC6C8, 0x9F57, 0xC6C9, 0x9F58, 0xC6CA,
+	0x9F59, 0xC6CB, 0x9F5A, 0xC6CE, 0x9F61, 0xC6CF, 0x9F62, 0xC6D1,
+	0x9F63, 0xC6D2, 0x9F64, 0xC6D3, 0x9F65, 0xC6D5, 0x9F66, 0xC6D6,
+	0x9F67, 0xC6D7, 0x9F68, 0xC6D8, 0x9F69, 0xC6D9, 0x9F6A, 0xC6DA,
+	0x9F6B, 0xC6DB, 0x9F6C, 0xC6DE, 0x9F6D, 0xC6DF, 0x9F6E, 0xC6E2,
+	0x9F6F, 0xC6E3, 0x9F70, 0xC6E4, 0x9F71, 0xC6E5, 0x9F72, 0xC6E6,
+	0x9F73, 0xC6E7, 0x9F74, 0xC6EA, 0x9F75, 0xC6EB, 0x9F76, 0xC6ED,
+	0x9F77, 0xC6EE, 0x9F78, 0xC6EF, 0x9F79, 0xC6F1, 0x9F7A, 0xC6F2,
+	0x9F81, 0xC6F3, 0x9F82, 0xC6F4, 0x9F83, 0xC6F5, 0x9F84, 0xC6F6,
+	0x9F85, 0xC6F7, 0x9F86, 0xC6FA, 0x9F87, 0xC6FB, 0x9F88, 0xC6FC,
+	0x9F89, 0xC6FE, 0x9F8A, 0xC6FF, 0x9F8B, 0xC700, 0x9F8C, 0xC701,
+	0x9F8D, 0xC702, 0x9F8E, 0xC703, 0x9F8F, 0xC706, 0x9F90, 0xC707,
+	0x9F91, 0xC709, 0x9F92, 0xC70A, 0x9F93, 0xC70B, 0x9F94, 0xC70D,
+	0x9F95, 0xC70E, 0x9F96, 0xC70F, 0x9F97, 0xC710, 0x9F98, 0xC711,
+	0x9F99, 0xC712, 0x9F9A, 0xC713, 0x9F9B, 0xC716, 0x9F9C, 0xC718,
+	0x9F9D, 0xC71A, 0x9F9E, 0xC71B, 0x9F9F, 0xC71C, 0x9FA0, 0xC71D,
+	0x9FA1, 0xC71E, 0x9FA2, 0xC71F, 0x9FA3, 0xC722, 0x9FA4, 0xC723,
+	0x9FA5, 0xC725, 0x9FA6, 0xC726, 0x9FA7, 0xC727, 0x9FA8, 0xC729,
+	0x9FA9, 0xC72A, 0x9FAA, 0xC72B, 0x9FAB, 0xC72C, 0x9FAC, 0xC72D,
+	0x9FAD, 0xC72E, 0x9FAE, 0xC72F, 0x9FAF, 0xC732, 0x9FB0, 0xC734,
+	0x9FB1, 0xC736, 0x9FB2, 0xC738, 0x9FB3, 0xC739, 0x9FB4, 0xC73A,
+	0x9FB5, 0xC73B, 0x9FB6, 0xC73E, 0x9FB7, 0xC73F, 0x9FB8, 0xC741,
+	0x9FB9, 0xC742, 0x9FBA, 0xC743, 0x9FBB, 0xC745, 0x9FBC, 0xC746,
+	0x9FBD, 0xC747, 0x9FBE, 0xC748, 0x9FBF, 0xC749, 0x9FC0, 0xC74B,
+	0x9FC1, 0xC74E, 0x9FC2, 0xC750, 0x9FC3, 0xC759, 0x9FC4, 0xC75A,
+	0x9FC5, 0xC75B, 0x9FC6, 0xC75D, 0x9FC7, 0xC75E, 0x9FC8, 0xC75F,
+	0x9FC9, 0xC761, 0x9FCA, 0xC762, 0x9FCB, 0xC763, 0x9FCC, 0xC764,
+	0x9FCD, 0xC765, 0x9FCE, 0xC766, 0x9FCF, 0xC767, 0x9FD0, 0xC769,
+	0x9FD1, 0xC76A, 0x9FD2, 0xC76C, 0x9FD3, 0xC76D, 0x9FD4, 0xC76E,
+	0x9FD5, 0xC76F, 0x9FD6, 0xC770, 0x9FD7, 0xC771, 0x9FD8, 0xC772,
+	0x9FD9, 0xC773, 0x9FDA, 0xC776, 0x9FDB, 0xC777, 0x9FDC, 0xC779,
+	0x9FDD, 0xC77A, 0x9FDE, 0xC77B, 0x9FDF, 0xC77F, 0x9FE0, 0xC780,
+	0x9FE1, 0xC781, 0x9FE2, 0xC782, 0x9FE3, 0xC786, 0x9FE4, 0xC78B,
+	0x9FE5, 0xC78C, 0x9FE6, 0xC78D, 0x9FE7, 0xC78F, 0x9FE8, 0xC792,
+	0x9FE9, 0xC793, 0x9FEA, 0xC795, 0x9FEB, 0xC799, 0x9FEC, 0xC79B,
+	0x9FED, 0xC79C, 0x9FEE, 0xC79D, 0x9FEF, 0xC79E, 0x9FF0, 0xC79F,
+	0x9FF1, 0xC7A2, 0x9FF2, 0xC7A7, 0x9FF3, 0xC7A8, 0x9FF4, 0xC7A9,
+	0x9FF5, 0xC7AA, 0x9FF6, 0xC7AB, 0x9FF7, 0xC7AE, 0x9FF8, 0xC7AF,
+	0x9FF9, 0xC7B1, 0x9FFA, 0xC7B2, 0x9FFB, 0xC7B3, 0x9FFC, 0xC7B5,
+	0x9FFD, 0xC7B6, 0x9FFE, 0xC7B7, 0xA041, 0xC7B8, 0xA042, 0xC7B9,
+	0xA043, 0xC7BA, 0xA044, 0xC7BB, 0xA045, 0xC7BE, 0xA046, 0xC7C2,
+	0xA047, 0xC7C3, 0xA048, 0xC7C4, 0xA049, 0xC7C5, 0xA04A, 0xC7C6,
+	0xA04B, 0xC7C7, 0xA04C, 0xC7CA, 0xA04D, 0xC7CB, 0xA04E, 0xC7CD,
+	0xA04F, 0xC7CF, 0xA050, 0xC7D1, 0xA051, 0xC7D2, 0xA052, 0xC7D3,
+	0xA053, 0xC7D4, 0xA054, 0xC7D5, 0xA055, 0xC7D6, 0xA056, 0xC7D7,
+	0xA057, 0xC7D9, 0xA058, 0xC7DA, 0xA059, 0xC7DB, 0xA05A, 0xC7DC,
+	0xA061, 0xC7DE, 0xA062, 0xC7DF, 0xA063, 0xC7E0, 0xA064, 0xC7E1,
+	0xA065, 0xC7E2, 0xA066, 0xC7E3, 0xA067, 0xC7E5, 0xA068, 0xC7E6,
+	0xA069, 0xC7E7, 0xA06A, 0xC7E9, 0xA06B, 0xC7EA, 0xA06C, 0xC7EB,
+	0xA06D, 0xC7ED, 0xA06E, 0xC7EE, 0xA06F, 0xC7EF, 0xA070, 0xC7F0,
+	0xA071, 0xC7F1, 0xA072, 0xC7F2, 0xA073, 0xC7F3, 0xA074, 0xC7F4,
+	0xA075, 0xC7F5, 0xA076, 0xC7F6, 0xA077, 0xC7F7, 0xA078, 0xC7F8,
+	0xA079, 0xC7F9, 0xA07A, 0xC7FA, 0xA081, 0xC7FB, 0xA082, 0xC7FC,
+	0xA083, 0xC7FD, 0xA084, 0xC7FE, 0xA085, 0xC7FF, 0xA086, 0xC802,
+	0xA087, 0xC803, 0xA088, 0xC805, 0xA089, 0xC806, 0xA08A, 0xC807,
+	0xA08B, 0xC809, 0xA08C, 0xC80B, 0xA08D, 0xC80C, 0xA08E, 0xC80D,
+	0xA08F, 0xC80E, 0xA090, 0xC80F, 0xA091, 0xC812, 0xA092, 0xC814,
+	0xA093, 0xC817, 0xA094, 0xC818, 0xA095, 0xC819, 0xA096, 0xC81A,
+	0xA097, 0xC81B, 0xA098, 0xC81E, 0xA099, 0xC81F, 0xA09A, 0xC821,
+	0xA09B, 0xC822, 0xA09C, 0xC823, 0xA09D, 0xC825, 0xA09E, 0xC826,
+	0xA09F, 0xC827, 0xA0A0, 0xC828, 0xA0A1, 0xC829, 0xA0A2, 0xC82A,
+	0xA0A3, 0xC82B, 0xA0A4, 0xC82E, 0xA0A5, 0xC830, 0xA0A6, 0xC832,
+	0xA0A7, 0xC833, 0xA0A8, 0xC834, 0xA0A9, 0xC835, 0xA0AA, 0xC836,
+	0xA0AB, 0xC837, 0xA0AC, 0xC839, 0xA0AD, 0xC83A, 0xA0AE, 0xC83B,
+	0xA0AF, 0xC83D, 0xA0B0, 0xC83E, 0xA0B1, 0xC83F, 0xA0B2, 0xC841,
+	0xA0B3, 0xC842, 0xA0B4, 0xC843, 0xA0B5, 0xC844, 0xA0B6, 0xC845,
+	0xA0B7, 0xC846, 0xA0B8, 0xC847, 0xA0B9, 0xC84A, 0xA0BA, 0xC84B,
+	0xA0BB, 0xC84E, 0xA0BC, 0xC84F, 0xA0BD, 0xC850, 0xA0BE, 0xC851,
+	0xA0BF, 0xC852, 0xA0C0, 0xC853, 0xA0C1, 0xC855, 0xA0C2, 0xC856,
+	0xA0C3, 0xC857, 0xA0C4, 0xC858, 0xA0C5, 0xC859, 0xA0C6, 0xC85A,
+	0xA0C7, 0xC85B, 0xA0C8, 0xC85C, 0xA0C9, 0xC85D, 0xA0CA, 0xC85E,
+	0xA0CB, 0xC85F, 0xA0CC, 0xC860, 0xA0CD, 0xC861, 0xA0CE, 0xC862,
+	0xA0CF, 0xC863, 0xA0D0, 0xC864, 0xA0D1, 0xC865, 0xA0D2, 0xC866,
+	0xA0D3, 0xC867, 0xA0D4, 0xC868, 0xA0D5, 0xC869, 0xA0D6, 0xC86A,
+	0xA0D7, 0xC86B, 0xA0D8, 0xC86C, 0xA0D9, 0xC86D, 0xA0DA, 0xC86E,
+	0xA0DB, 0xC86F, 0xA0DC, 0xC872, 0xA0DD, 0xC873, 0xA0DE, 0xC875,
+	0xA0DF, 0xC876, 0xA0E0, 0xC877, 0xA0E1, 0xC879, 0xA0E2, 0xC87B,
+	0xA0E3, 0xC87C, 0xA0E4, 0xC87D, 0xA0E5, 0xC87E, 0xA0E6, 0xC87F,
+	0xA0E7, 0xC882, 0xA0E8, 0xC884, 0xA0E9, 0xC888, 0xA0EA, 0xC889,
+	0xA0EB, 0xC88A, 0xA0EC, 0xC88E, 0xA0ED, 0xC88F, 0xA0EE, 0xC890,
+	0xA0EF, 0xC891, 0xA0F0, 0xC892, 0xA0F1, 0xC893, 0xA0F2, 0xC895,
+	0xA0F3, 0xC896, 0xA0F4, 0xC897, 0xA0F5, 0xC898, 0xA0F6, 0xC899,
+	0xA0F7, 0xC89A, 0xA0F8, 0xC89B, 0xA0F9, 0xC89C, 0xA0FA, 0xC89E,
+	0xA0FB, 0xC8A0, 0xA0FC, 0xC8A2, 0xA0FD, 0xC8A3, 0xA0FE, 0xC8A4,
+	0xA141, 0xC8A5, 0xA142, 0xC8A6, 0xA143, 0xC8A7, 0xA144, 0xC8A9,
+	0xA145, 0xC8AA, 0xA146, 0xC8AB, 0xA147, 0xC8AC, 0xA148, 0xC8AD,
+	0xA149, 0xC8AE, 0xA14A, 0xC8AF, 0xA14B, 0xC8B0, 0xA14C, 0xC8B1,
+	0xA14D, 0xC8B2, 0xA14E, 0xC8B3, 0xA14F, 0xC8B4, 0xA150, 0xC8B5,
+	0xA151, 0xC8B6, 0xA152, 0xC8B7, 0xA153, 0xC8B8, 0xA154, 0xC8B9,
+	0xA155, 0xC8BA, 0xA156, 0xC8BB, 0xA157, 0xC8BE, 0xA158, 0xC8BF,
+	0xA159, 0xC8C0, 0xA15A, 0xC8C1, 0xA161, 0xC8C2, 0xA162, 0xC8C3,
+	0xA163, 0xC8C5, 0xA164, 0xC8C6, 0xA165, 0xC8C7, 0xA166, 0xC8C9,
+	0xA167, 0xC8CA, 0xA168, 0xC8CB, 0xA169, 0xC8CD, 0xA16A, 0xC8CE,
+	0xA16B, 0xC8CF, 0xA16C, 0xC8D0, 0xA16D, 0xC8D1, 0xA16E, 0xC8D2,
+	0xA16F, 0xC8D3, 0xA170, 0xC8D6, 0xA171, 0xC8D8, 0xA172, 0xC8DA,
+	0xA173, 0xC8DB, 0xA174, 0xC8DC, 0xA175, 0xC8DD, 0xA176, 0xC8DE,
+	0xA177, 0xC8DF, 0xA178, 0xC8E2, 0xA179, 0xC8E3, 0xA17A, 0xC8E5,
+	0xA181, 0xC8E6, 0xA182, 0xC8E7, 0xA183, 0xC8E8, 0xA184, 0xC8E9,
+	0xA185, 0xC8EA, 0xA186, 0xC8EB, 0xA187, 0xC8EC, 0xA188, 0xC8ED,
+	0xA189, 0xC8EE, 0xA18A, 0xC8EF, 0xA18B, 0xC8F0, 0xA18C, 0xC8F1,
+	0xA18D, 0xC8F2, 0xA18E, 0xC8F3, 0xA18F, 0xC8F4, 0xA190, 0xC8F6,
+	0xA191, 0xC8F7, 0xA192, 0xC8F8, 0xA193, 0xC8F9, 0xA194, 0xC8FA,
+	0xA195, 0xC8FB, 0xA196, 0xC8FE, 0xA197, 0xC8FF, 0xA198, 0xC901,
+	0xA199, 0xC902, 0xA19A, 0xC903, 0xA19B, 0xC907, 0xA19C, 0xC908,
+	0xA19D, 0xC909, 0xA19E, 0xC90A, 0xA19F, 0xC90B, 0xA1A0, 0xC90E,
+	0xA1A1, 0x3000, 0xA1A2, 0x3001, 0xA1A3, 0x3002, 0xA1A4, 0x00B7,
+	0xA1A5, 0x2025, 0xA1A6, 0x2026, 0xA1A7, 0x00A8, 0xA1A8, 0x3003,
+	0xA1A9, 0x00AD, 0xA1AA, 0x2015, 0xA1AB, 0x2225, 0xA1AC, 0xFF3C,
+	0xA1AD, 0x223C, 0xA1AE, 0x2018, 0xA1AF, 0x2019, 0xA1B0, 0x201C,
+	0xA1B1, 0x201D, 0xA1B2, 0x3014, 0xA1B3, 0x3015, 0xA1B4, 0x3008,
+	0xA1B5, 0x3009, 0xA1B6, 0x300A, 0xA1B7, 0x300B, 0xA1B8, 0x300C,
+	0xA1B9, 0x300D, 0xA1BA, 0x300E, 0xA1BB, 0x300F, 0xA1BC, 0x3010,
+	0xA1BD, 0x3011, 0xA1BE, 0x00B1, 0xA1BF, 0x00D7, 0xA1C0, 0x00F7,
+	0xA1C1, 0x2260, 0xA1C2, 0x2264, 0xA1C3, 0x2265, 0xA1C4, 0x221E,
+	0xA1C5, 0x2234, 0xA1C6, 0x00B0, 0xA1C7, 0x2032, 0xA1C8, 0x2033,
+	0xA1C9, 0x2103, 0xA1CA, 0x212B, 0xA1CB, 0xFFE0, 0xA1CC, 0xFFE1,
+	0xA1CD, 0xFFE5, 0xA1CE, 0x2642, 0xA1CF, 0x2640, 0xA1D0, 0x2220,
+	0xA1D1, 0x22A5, 0xA1D2, 0x2312, 0xA1D3, 0x2202, 0xA1D4, 0x2207,
+	0xA1D5, 0x2261, 0xA1D6, 0x2252, 0xA1D7, 0x00A7, 0xA1D8, 0x203B,
+	0xA1D9, 0x2606, 0xA1DA, 0x2605, 0xA1DB, 0x25CB, 0xA1DC, 0x25CF,
+	0xA1DD, 0x25CE, 0xA1DE, 0x25C7, 0xA1DF, 0x25C6, 0xA1E0, 0x25A1,
+	0xA1E1, 0x25A0, 0xA1E2, 0x25B3, 0xA1E3, 0x25B2, 0xA1E4, 0x25BD,
+	0xA1E5, 0x25BC, 0xA1E6, 0x2192, 0xA1E7, 0x2190, 0xA1E8, 0x2191,
+	0xA1E9, 0x2193, 0xA1EA, 0x2194, 0xA1EB, 0x3013, 0xA1EC, 0x226A,
+	0xA1ED, 0x226B, 0xA1EE, 0x221A, 0xA1EF, 0x223D, 0xA1F0, 0x221D,
+	0xA1F1, 0x2235, 0xA1F2, 0x222B, 0xA1F3, 0x222C, 0xA1F4, 0x2208,
+	0xA1F5, 0x220B, 0xA1F6, 0x2286, 0xA1F7, 0x2287, 0xA1F8, 0x2282,
+	0xA1F9, 0x2283, 0xA1FA, 0x222A, 0xA1FB, 0x2229, 0xA1FC, 0x2227,
+	0xA1FD, 0x2228, 0xA1FE, 0xFFE2, 0xA241, 0xC910, 0xA242, 0xC912,
+	0xA243, 0xC913, 0xA244, 0xC914, 0xA245, 0xC915, 0xA246, 0xC916,
+	0xA247, 0xC917, 0xA248, 0xC919, 0xA249, 0xC91A, 0xA24A, 0xC91B,
+	0xA24B, 0xC91C, 0xA24C, 0xC91D, 0xA24D, 0xC91E, 0xA24E, 0xC91F,
+	0xA24F, 0xC920, 0xA250, 0xC921, 0xA251, 0xC922, 0xA252, 0xC923,
+	0xA253, 0xC924, 0xA254, 0xC925, 0xA255, 0xC926, 0xA256, 0xC927,
+	0xA257, 0xC928, 0xA258, 0xC929, 0xA259, 0xC92A, 0xA25A, 0xC92B,
+	0xA261, 0xC92D, 0xA262, 0xC92E, 0xA263, 0xC92F, 0xA264, 0xC930,
+	0xA265, 0xC931, 0xA266, 0xC932, 0xA267, 0xC933, 0xA268, 0xC935,
+	0xA269, 0xC936, 0xA26A, 0xC937, 0xA26B, 0xC938, 0xA26C, 0xC939,
+	0xA26D, 0xC93A, 0xA26E, 0xC93B, 0xA26F, 0xC93C, 0xA270, 0xC93D,
+	0xA271, 0xC93E, 0xA272, 0xC93F, 0xA273, 0xC940, 0xA274, 0xC941,
+	0xA275, 0xC942, 0xA276, 0xC943, 0xA277, 0xC944, 0xA278, 0xC945,
+	0xA279, 0xC946, 0xA27A, 0xC947, 0xA281, 0xC948, 0xA282, 0xC949,
+	0xA283, 0xC94A, 0xA284, 0xC94B, 0xA285, 0xC94C, 0xA286, 0xC94D,
+	0xA287, 0xC94E, 0xA288, 0xC94F, 0xA289, 0xC952, 0xA28A, 0xC953,
+	0xA28B, 0xC955, 0xA28C, 0xC956, 0xA28D, 0xC957, 0xA28E, 0xC959,
+	0xA28F, 0xC95A, 0xA290, 0xC95B, 0xA291, 0xC95C, 0xA292, 0xC95D,
+	0xA293, 0xC95E, 0xA294, 0xC95F, 0xA295, 0xC962, 0xA296, 0xC964,
+	0xA297, 0xC965, 0xA298, 0xC966, 0xA299, 0xC967, 0xA29A, 0xC968,
+	0xA29B, 0xC969, 0xA29C, 0xC96A, 0xA29D, 0xC96B, 0xA29E, 0xC96D,
+	0xA29F, 0xC96E, 0xA2A0, 0xC96F, 0xA2A1, 0x21D2, 0xA2A2, 0x21D4,
+	0xA2A3, 0x2200, 0xA2A4, 0x2203, 0xA2A5, 0x00B4, 0xA2A6, 0xFF5E,
+	0xA2A7, 0x02C7, 0xA2A8, 0x02D8, 0xA2A9, 0x02DD, 0xA2AA, 0x02DA,
+	0xA2AB, 0x02D9, 0xA2AC, 0x00B8, 0xA2AD, 0x02DB, 0xA2AE, 0x00A1,
+	0xA2AF, 0x00BF, 0xA2B0, 0x02D0, 0xA2B1, 0x222E, 0xA2B2, 0x2211,
+	0xA2B3, 0x220F, 0xA2B4, 0x00A4, 0xA2B5, 0x2109, 0xA2B6, 0x2030,
+	0xA2B7, 0x25C1, 0xA2B8, 0x25C0, 0xA2B9, 0x25B7, 0xA2BA, 0x25B6,
+	0xA2BB, 0x2664, 0xA2BC, 0x2660, 0xA2BD, 0x2661, 0xA2BE, 0x2665,
+	0xA2BF, 0x2667, 0xA2C0, 0x2663, 0xA2C1, 0x2299, 0xA2C2, 0x25C8,
+	0xA2C3, 0x25A3, 0xA2C4, 0x25D0, 0xA2C5, 0x25D1, 0xA2C6, 0x2592,
+	0xA2C7, 0x25A4, 0xA2C8, 0x25A5, 0xA2C9, 0x25A8, 0xA2CA, 0x25A7,
+	0xA2CB, 0x25A6, 0xA2CC, 0x25A9, 0xA2CD, 0x2668, 0xA2CE, 0x260F,
+	0xA2CF, 0x260E, 0xA2D0, 0x261C, 0xA2D1, 0x261E, 0xA2D2, 0x00B6,
+	0xA2D3, 0x2020, 0xA2D4, 0x2021, 0xA2D5, 0x2195, 0xA2D6, 0x2197,
+	0xA2D7, 0x2199, 0xA2D8, 0x2196, 0xA2D9, 0x2198, 0xA2DA, 0x266D,
+	0xA2DB, 0x2669, 0xA2DC, 0x266A, 0xA2DD, 0x266C, 0xA2DE, 0x327F,
+	0xA2DF, 0x321C, 0xA2E0, 0x2116, 0xA2E1, 0x33C7, 0xA2E2, 0x2122,
+	0xA2E3, 0x33C2, 0xA2E4, 0x33D8, 0xA2E5, 0x2121, 0xA2E6, 0x20AC,
+	0xA2E7, 0x00AE, 0xA341, 0xC971, 0xA342, 0xC972, 0xA343, 0xC973,
+	0xA344, 0xC975, 0xA345, 0xC976, 0xA346, 0xC977, 0xA347, 0xC978,
+	0xA348, 0xC979, 0xA349, 0xC97A, 0xA34A, 0xC97B, 0xA34B, 0xC97D,
+	0xA34C, 0xC97E, 0xA34D, 0xC97F, 0xA34E, 0xC980, 0xA34F, 0xC981,
+	0xA350, 0xC982, 0xA351, 0xC983, 0xA352, 0xC984, 0xA353, 0xC985,
+	0xA354, 0xC986, 0xA355, 0xC987, 0xA356, 0xC98A, 0xA357, 0xC98B,
+	0xA358, 0xC98D, 0xA359, 0xC98E, 0xA35A, 0xC98F, 0xA361, 0xC991,
+	0xA362, 0xC992, 0xA363, 0xC993, 0xA364, 0xC994, 0xA365, 0xC995,
+	0xA366, 0xC996, 0xA367, 0xC997, 0xA368, 0xC99A, 0xA369, 0xC99C,
+	0xA36A, 0xC99E, 0xA36B, 0xC99F, 0xA36C, 0xC9A0, 0xA36D, 0xC9A1,
+	0xA36E, 0xC9A2, 0xA36F, 0xC9A3, 0xA370, 0xC9A4, 0xA371, 0xC9A5,
+	0xA372, 0xC9A6, 0xA373, 0xC9A7, 0xA374, 0xC9A8, 0xA375, 0xC9A9,
+	0xA376, 0xC9AA, 0xA377, 0xC9AB, 0xA378, 0xC9AC, 0xA379, 0xC9AD,
+	0xA37A, 0xC9AE, 0xA381, 0xC9AF, 0xA382, 0xC9B0, 0xA383, 0xC9B1,
+	0xA384, 0xC9B2, 0xA385, 0xC9B3, 0xA386, 0xC9B4, 0xA387, 0xC9B5,
+	0xA388, 0xC9B6, 0xA389, 0xC9B7, 0xA38A, 0xC9B8, 0xA38B, 0xC9B9,
+	0xA38C, 0xC9BA, 0xA38D, 0xC9BB, 0xA38E, 0xC9BC, 0xA38F, 0xC9BD,
+	0xA390, 0xC9BE, 0xA391, 0xC9BF, 0xA392, 0xC9C2, 0xA393, 0xC9C3,
+	0xA394, 0xC9C5, 0xA395, 0xC9C6, 0xA396, 0xC9C9, 0xA397, 0xC9CB,
+	0xA398, 0xC9CC, 0xA399, 0xC9CD, 0xA39A, 0xC9CE, 0xA39B, 0xC9CF,
+	0xA39C, 0xC9D2, 0xA39D, 0xC9D4, 0xA39E, 0xC9D7, 0xA39F, 0xC9D8,
+	0xA3A0, 0xC9DB, 0xA3A1, 0xFF01, 0xA3A2, 0xFF02, 0xA3A3, 0xFF03,
+	0xA3A4, 0xFF04, 0xA3A5, 0xFF05, 0xA3A6, 0xFF06, 0xA3A7, 0xFF07,
+	0xA3A8, 0xFF08, 0xA3A9, 0xFF09, 0xA3AA, 0xFF0A, 0xA3AB, 0xFF0B,
+	0xA3AC, 0xFF0C, 0xA3AD, 0xFF0D, 0xA3AE, 0xFF0E, 0xA3AF, 0xFF0F,
+	0xA3B0, 0xFF10, 0xA3B1, 0xFF11, 0xA3B2, 0xFF12, 0xA3B3, 0xFF13,
+	0xA3B4, 0xFF14, 0xA3B5, 0xFF15, 0xA3B6, 0xFF16, 0xA3B7, 0xFF17,
+	0xA3B8, 0xFF18, 0xA3B9, 0xFF19, 0xA3BA, 0xFF1A, 0xA3BB, 0xFF1B,
+	0xA3BC, 0xFF1C, 0xA3BD, 0xFF1D, 0xA3BE, 0xFF1E, 0xA3BF, 0xFF1F,
+	0xA3C0, 0xFF20, 0xA3C1, 0xFF21, 0xA3C2, 0xFF22, 0xA3C3, 0xFF23,
+	0xA3C4, 0xFF24, 0xA3C5, 0xFF25, 0xA3C6, 0xFF26, 0xA3C7, 0xFF27,
+	0xA3C8, 0xFF28, 0xA3C9, 0xFF29, 0xA3CA, 0xFF2A, 0xA3CB, 0xFF2B,
+	0xA3CC, 0xFF2C, 0xA3CD, 0xFF2D, 0xA3CE, 0xFF2E, 0xA3CF, 0xFF2F,
+	0xA3D0, 0xFF30, 0xA3D1, 0xFF31, 0xA3D2, 0xFF32, 0xA3D3, 0xFF33,
+	0xA3D4, 0xFF34, 0xA3D5, 0xFF35, 0xA3D6, 0xFF36, 0xA3D7, 0xFF37,
+	0xA3D8, 0xFF38, 0xA3D9, 0xFF39, 0xA3DA, 0xFF3A, 0xA3DB, 0xFF3B,
+	0xA3DC, 0xFFE6, 0xA3DD, 0xFF3D, 0xA3DE, 0xFF3E, 0xA3DF, 0xFF3F,
+	0xA3E0, 0xFF40, 0xA3E1, 0xFF41, 0xA3E2, 0xFF42, 0xA3E3, 0xFF43,
+	0xA3E4, 0xFF44, 0xA3E5, 0xFF45, 0xA3E6, 0xFF46, 0xA3E7, 0xFF47,
+	0xA3E8, 0xFF48, 0xA3E9, 0xFF49, 0xA3EA, 0xFF4A, 0xA3EB, 0xFF4B,
+	0xA3EC, 0xFF4C, 0xA3ED, 0xFF4D, 0xA3EE, 0xFF4E, 0xA3EF, 0xFF4F,
+	0xA3F0, 0xFF50, 0xA3F1, 0xFF51, 0xA3F2, 0xFF52, 0xA3F3, 0xFF53,
+	0xA3F4, 0xFF54, 0xA3F5, 0xFF55, 0xA3F6, 0xFF56, 0xA3F7, 0xFF57,
+	0xA3F8, 0xFF58, 0xA3F9, 0xFF59, 0xA3FA, 0xFF5A, 0xA3FB, 0xFF5B,
+	0xA3FC, 0xFF5C, 0xA3FD, 0xFF5D, 0xA3FE, 0xFFE3, 0xA441, 0xC9DE,
+	0xA442, 0xC9DF, 0xA443, 0xC9E1, 0xA444, 0xC9E3, 0xA445, 0xC9E5,
+	0xA446, 0xC9E6, 0xA447, 0xC9E8, 0xA448, 0xC9E9, 0xA449, 0xC9EA,
+	0xA44A, 0xC9EB, 0xA44B, 0xC9EE, 0xA44C, 0xC9F2, 0xA44D, 0xC9F3,
+	0xA44E, 0xC9F4, 0xA44F, 0xC9F5, 0xA450, 0xC9F6, 0xA451, 0xC9F7,
+	0xA452, 0xC9FA, 0xA453, 0xC9FB, 0xA454, 0xC9FD, 0xA455, 0xC9FE,
+	0xA456, 0xC9FF, 0xA457, 0xCA01, 0xA458, 0xCA02, 0xA459, 0xCA03,
+	0xA45A, 0xCA04, 0xA461, 0xCA05, 0xA462, 0xCA06, 0xA463, 0xCA07,
+	0xA464, 0xCA0A, 0xA465, 0xCA0E, 0xA466, 0xCA0F, 0xA467, 0xCA10,
+	0xA468, 0xCA11, 0xA469, 0xCA12, 0xA46A, 0xCA13, 0xA46B, 0xCA15,
+	0xA46C, 0xCA16, 0xA46D, 0xCA17, 0xA46E, 0xCA19, 0xA46F, 0xCA1A,
+	0xA470, 0xCA1B, 0xA471, 0xCA1C, 0xA472, 0xCA1D, 0xA473, 0xCA1E,
+	0xA474, 0xCA1F, 0xA475, 0xCA20, 0xA476, 0xCA21, 0xA477, 0xCA22,
+	0xA478, 0xCA23, 0xA479, 0xCA24, 0xA47A, 0xCA25, 0xA481, 0xCA26,
+	0xA482, 0xCA27, 0xA483, 0xCA28, 0xA484, 0xCA2A, 0xA485, 0xCA2B,
+	0xA486, 0xCA2C, 0xA487, 0xCA2D, 0xA488, 0xCA2E, 0xA489, 0xCA2F,
+	0xA48A, 0xCA30, 0xA48B, 0xCA31, 0xA48C, 0xCA32, 0xA48D, 0xCA33,
+	0xA48E, 0xCA34, 0xA48F, 0xCA35, 0xA490, 0xCA36, 0xA491, 0xCA37,
+	0xA492, 0xCA38, 0xA493, 0xCA39, 0xA494, 0xCA3A, 0xA495, 0xCA3B,
+	0xA496, 0xCA3C, 0xA497, 0xCA3D, 0xA498, 0xCA3E, 0xA499, 0xCA3F,
+	0xA49A, 0xCA40, 0xA49B, 0xCA41, 0xA49C, 0xCA42, 0xA49D, 0xCA43,
+	0xA49E, 0xCA44, 0xA49F, 0xCA45, 0xA4A0, 0xCA46, 0xA4A1, 0x3131,
+	0xA4A2, 0x3132, 0xA4A3, 0x3133, 0xA4A4, 0x3134, 0xA4A5, 0x3135,
+	0xA4A6, 0x3136, 0xA4A7, 0x3137, 0xA4A8, 0x3138, 0xA4A9, 0x3139,
+	0xA4AA, 0x313A, 0xA4AB, 0x313B, 0xA4AC, 0x313C, 0xA4AD, 0x313D,
+	0xA4AE, 0x313E, 0xA4AF, 0x313F, 0xA4B0, 0x3140, 0xA4B1, 0x3141,
+	0xA4B2, 0x3142, 0xA4B3, 0x3143, 0xA4B4, 0x3144, 0xA4B5, 0x3145,
+	0xA4B6, 0x3146, 0xA4B7, 0x3147, 0xA4B8, 0x3148, 0xA4B9, 0x3149,
+	0xA4BA, 0x314A, 0xA4BB, 0x314B, 0xA4BC, 0x314C, 0xA4BD, 0x314D,
+	0xA4BE, 0x314E, 0xA4BF, 0x314F, 0xA4C0, 0x3150, 0xA4C1, 0x3151,
+	0xA4C2, 0x3152, 0xA4C3, 0x3153, 0xA4C4, 0x3154, 0xA4C5, 0x3155,
+	0xA4C6, 0x3156, 0xA4C7, 0x3157, 0xA4C8, 0x3158, 0xA4C9, 0x3159,
+	0xA4CA, 0x315A, 0xA4CB, 0x315B, 0xA4CC, 0x315C, 0xA4CD, 0x315D,
+	0xA4CE, 0x315E, 0xA4CF, 0x315F, 0xA4D0, 0x3160, 0xA4D1, 0x3161,
+	0xA4D2, 0x3162, 0xA4D3, 0x3163, 0xA4D4, 0x3164, 0xA4D5, 0x3165,
+	0xA4D6, 0x3166, 0xA4D7, 0x3167, 0xA4D8, 0x3168, 0xA4D9, 0x3169,
+	0xA4DA, 0x316A, 0xA4DB, 0x316B, 0xA4DC, 0x316C, 0xA4DD, 0x316D,
+	0xA4DE, 0x316E, 0xA4DF, 0x316F, 0xA4E0, 0x3170, 0xA4E1, 0x3171,
+	0xA4E2, 0x3172, 0xA4E3, 0x3173, 0xA4E4, 0x3174, 0xA4E5, 0x3175,
+	0xA4E6, 0x3176, 0xA4E7, 0x3177, 0xA4E8, 0x3178, 0xA4E9, 0x3179,
+	0xA4EA, 0x317A, 0xA4EB, 0x317B, 0xA4EC, 0x317C, 0xA4ED, 0x317D,
+	0xA4EE, 0x317E, 0xA4EF, 0x317F, 0xA4F0, 0x3180, 0xA4F1, 0x3181,
+	0xA4F2, 0x3182, 0xA4F3, 0x3183, 0xA4F4, 0x3184, 0xA4F5, 0x3185,
+	0xA4F6, 0x3186, 0xA4F7, 0x3187, 0xA4F8, 0x3188, 0xA4F9, 0x3189,
+	0xA4FA, 0x318A, 0xA4FB, 0x318B, 0xA4FC, 0x318C, 0xA4FD, 0x318D,
+	0xA4FE, 0x318E, 0xA541, 0xCA47, 0xA542, 0xCA48, 0xA543, 0xCA49,
+	0xA544, 0xCA4A, 0xA545, 0xCA4B, 0xA546, 0xCA4E, 0xA547, 0xCA4F,
+	0xA548, 0xCA51, 0xA549, 0xCA52, 0xA54A, 0xCA53, 0xA54B, 0xCA55,
+	0xA54C, 0xCA56, 0xA54D, 0xCA57, 0xA54E, 0xCA58, 0xA54F, 0xCA59,
+	0xA550, 0xCA5A, 0xA551, 0xCA5B, 0xA552, 0xCA5E, 0xA553, 0xCA62,
+	0xA554, 0xCA63, 0xA555, 0xCA64, 0xA556, 0xCA65, 0xA557, 0xCA66,
+	0xA558, 0xCA67, 0xA559, 0xCA69, 0xA55A, 0xCA6A, 0xA561, 0xCA6B,
+	0xA562, 0xCA6C, 0xA563, 0xCA6D, 0xA564, 0xCA6E, 0xA565, 0xCA6F,
+	0xA566, 0xCA70, 0xA567, 0xCA71, 0xA568, 0xCA72, 0xA569, 0xCA73,
+	0xA56A, 0xCA74, 0xA56B, 0xCA75, 0xA56C, 0xCA76, 0xA56D, 0xCA77,
+	0xA56E, 0xCA78, 0xA56F, 0xCA79, 0xA570, 0xCA7A, 0xA571, 0xCA7B,
+	0xA572, 0xCA7C, 0xA573, 0xCA7E, 0xA574, 0xCA7F, 0xA575, 0xCA80,
+	0xA576, 0xCA81, 0xA577, 0xCA82, 0xA578, 0xCA83, 0xA579, 0xCA85,
+	0xA57A, 0xCA86, 0xA581, 0xCA87, 0xA582, 0xCA88, 0xA583, 0xCA89,
+	0xA584, 0xCA8A, 0xA585, 0xCA8B, 0xA586, 0xCA8C, 0xA587, 0xCA8D,
+	0xA588, 0xCA8E, 0xA589, 0xCA8F, 0xA58A, 0xCA90, 0xA58B, 0xCA91,
+	0xA58C, 0xCA92, 0xA58D, 0xCA93, 0xA58E, 0xCA94, 0xA58F, 0xCA95,
+	0xA590, 0xCA96, 0xA591, 0xCA97, 0xA592, 0xCA99, 0xA593, 0xCA9A,
+	0xA594, 0xCA9B, 0xA595, 0xCA9C, 0xA596, 0xCA9D, 0xA597, 0xCA9E,
+	0xA598, 0xCA9F, 0xA599, 0xCAA0, 0xA59A, 0xCAA1, 0xA59B, 0xCAA2,
+	0xA59C, 0xCAA3, 0xA59D, 0xCAA4, 0xA59E, 0xCAA5, 0xA59F, 0xCAA6,
+	0xA5A0, 0xCAA7, 0xA5A1, 0x2170, 0xA5A2, 0x2171, 0xA5A3, 0x2172,
+	0xA5A4, 0x2173, 0xA5A5, 0x2174, 0xA5A6, 0x2175, 0xA5A7, 0x2176,
+	0xA5A8, 0x2177, 0xA5A9, 0x2178, 0xA5AA, 0x2179, 0xA5B0, 0x2160,
+	0xA5B1, 0x2161, 0xA5B2, 0x2162, 0xA5B3, 0x2163, 0xA5B4, 0x2164,
+	0xA5B5, 0x2165, 0xA5B6, 0x2166, 0xA5B7, 0x2167, 0xA5B8, 0x2168,
+	0xA5B9, 0x2169, 0xA5C1, 0x0391, 0xA5C2, 0x0392, 0xA5C3, 0x0393,
+	0xA5C4, 0x0394, 0xA5C5, 0x0395, 0xA5C6, 0x0396, 0xA5C7, 0x0397,
+	0xA5C8, 0x0398, 0xA5C9, 0x0399, 0xA5CA, 0x039A, 0xA5CB, 0x039B,
+	0xA5CC, 0x039C, 0xA5CD, 0x039D, 0xA5CE, 0x039E, 0xA5CF, 0x039F,
+	0xA5D0, 0x03A0, 0xA5D1, 0x03A1, 0xA5D2, 0x03A3, 0xA5D3, 0x03A4,
+	0xA5D4, 0x03A5, 0xA5D5, 0x03A6, 0xA5D6, 0x03A7, 0xA5D7, 0x03A8,
+	0xA5D8, 0x03A9, 0xA5E1, 0x03B1, 0xA5E2, 0x03B2, 0xA5E3, 0x03B3,
+	0xA5E4, 0x03B4, 0xA5E5, 0x03B5, 0xA5E6, 0x03B6, 0xA5E7, 0x03B7,
+	0xA5E8, 0x03B8, 0xA5E9, 0x03B9, 0xA5EA, 0x03BA, 0xA5EB, 0x03BB,
+	0xA5EC, 0x03BC, 0xA5ED, 0x03BD, 0xA5EE, 0x03BE, 0xA5EF, 0x03BF,
+	0xA5F0, 0x03C0, 0xA5F1, 0x03C1, 0xA5F2, 0x03C3, 0xA5F3, 0x03C4,
+	0xA5F4, 0x03C5, 0xA5F5, 0x03C6, 0xA5F6, 0x03C7, 0xA5F7, 0x03C8,
+	0xA5F8, 0x03C9, 0xA641, 0xCAA8, 0xA642, 0xCAA9, 0xA643, 0xCAAA,
+	0xA644, 0xCAAB, 0xA645, 0xCAAC, 0xA646, 0xCAAD, 0xA647, 0xCAAE,
+	0xA648, 0xCAAF, 0xA649, 0xCAB0, 0xA64A, 0xCAB1, 0xA64B, 0xCAB2,
+	0xA64C, 0xCAB3, 0xA64D, 0xCAB4, 0xA64E, 0xCAB5, 0xA64F, 0xCAB6,
+	0xA650, 0xCAB7, 0xA651, 0xCAB8, 0xA652, 0xCAB9, 0xA653, 0xCABA,
+	0xA654, 0xCABB, 0xA655, 0xCABE, 0xA656, 0xCABF, 0xA657, 0xCAC1,
+	0xA658, 0xCAC2, 0xA659, 0xCAC3, 0xA65A, 0xCAC5, 0xA661, 0xCAC6,
+	0xA662, 0xCAC7, 0xA663, 0xCAC8, 0xA664, 0xCAC9, 0xA665, 0xCACA,
+	0xA666, 0xCACB, 0xA667, 0xCACE, 0xA668, 0xCAD0, 0xA669, 0xCAD2,
+	0xA66A, 0xCAD4, 0xA66B, 0xCAD5, 0xA66C, 0xCAD6, 0xA66D, 0xCAD7,
+	0xA66E, 0xCADA, 0xA66F, 0xCADB, 0xA670, 0xCADC, 0xA671, 0xCADD,
+	0xA672, 0xCADE, 0xA673, 0xCADF, 0xA674, 0xCAE1, 0xA675, 0xCAE2,
+	0xA676, 0xCAE3, 0xA677, 0xCAE4, 0xA678, 0xCAE5, 0xA679, 0xCAE6,
+	0xA67A, 0xCAE7, 0xA681, 0xCAE8, 0xA682, 0xCAE9, 0xA683, 0xCAEA,
+	0xA684, 0xCAEB, 0xA685, 0xCAED, 0xA686, 0xCAEE, 0xA687, 0xCAEF,
+	0xA688, 0xCAF0, 0xA689, 0xCAF1, 0xA68A, 0xCAF2, 0xA68B, 0xCAF3,
+	0xA68C, 0xCAF5, 0xA68D, 0xCAF6, 0xA68E, 0xCAF7, 0xA68F, 0xCAF8,
+	0xA690, 0xCAF9, 0xA691, 0xCAFA, 0xA692, 0xCAFB, 0xA693, 0xCAFC,
+	0xA694, 0xCAFD, 0xA695, 0xCAFE, 0xA696, 0xCAFF, 0xA697, 0xCB00,
+	0xA698, 0xCB01, 0xA699, 0xCB02, 0xA69A, 0xCB03, 0xA69B, 0xCB04,
+	0xA69C, 0xCB05, 0xA69D, 0xCB06, 0xA69E, 0xCB07, 0xA69F, 0xCB09,
+	0xA6A0, 0xCB0A, 0xA6A1, 0x2500, 0xA6A2, 0x2502, 0xA6A3, 0x250C,
+	0xA6A4, 0x2510, 0xA6A5, 0x2518, 0xA6A6, 0x2514, 0xA6A7, 0x251C,
+	0xA6A8, 0x252C, 0xA6A9, 0x2524, 0xA6AA, 0x2534, 0xA6AB, 0x253C,
+	0xA6AC, 0x2501, 0xA6AD, 0x2503, 0xA6AE, 0x250F, 0xA6AF, 0x2513,
+	0xA6B0, 0x251B, 0xA6B1, 0x2517, 0xA6B2, 0x2523, 0xA6B3, 0x2533,
+	0xA6B4, 0x252B, 0xA6B5, 0x253B, 0xA6B6, 0x254B, 0xA6B7, 0x2520,
+	0xA6B8, 0x252F, 0xA6B9, 0x2528, 0xA6BA, 0x2537, 0xA6BB, 0x253F,
+	0xA6BC, 0x251D, 0xA6BD, 0x2530, 0xA6BE, 0x2525, 0xA6BF, 0x2538,
+	0xA6C0, 0x2542, 0xA6C1, 0x2512, 0xA6C2, 0x2511, 0xA6C3, 0x251A,
+	0xA6C4, 0x2519, 0xA6C5, 0x2516, 0xA6C6, 0x2515, 0xA6C7, 0x250E,
+	0xA6C8, 0x250D, 0xA6C9, 0x251E, 0xA6CA, 0x251F, 0xA6CB, 0x2521,
+	0xA6CC, 0x2522, 0xA6CD, 0x2526, 0xA6CE, 0x2527, 0xA6CF, 0x2529,
+	0xA6D0, 0x252A, 0xA6D1, 0x252D, 0xA6D2, 0x252E, 0xA6D3, 0x2531,
+	0xA6D4, 0x2532, 0xA6D5, 0x2535, 0xA6D6, 0x2536, 0xA6D7, 0x2539,
+	0xA6D8, 0x253A, 0xA6D9, 0x253D, 0xA6DA, 0x253E, 0xA6DB, 0x2540,
+	0xA6DC, 0x2541, 0xA6DD, 0x2543, 0xA6DE, 0x2544, 0xA6DF, 0x2545,
+	0xA6E0, 0x2546, 0xA6E1, 0x2547, 0xA6E2, 0x2548, 0xA6E3, 0x2549,
+	0xA6E4, 0x254A, 0xA741, 0xCB0B, 0xA742, 0xCB0C, 0xA743, 0xCB0D,
+	0xA744, 0xCB0E, 0xA745, 0xCB0F, 0xA746, 0xCB11, 0xA747, 0xCB12,
+	0xA748, 0xCB13, 0xA749, 0xCB15, 0xA74A, 0xCB16, 0xA74B, 0xCB17,
+	0xA74C, 0xCB19, 0xA74D, 0xCB1A, 0xA74E, 0xCB1B, 0xA74F, 0xCB1C,
+	0xA750, 0xCB1D, 0xA751, 0xCB1E, 0xA752, 0xCB1F, 0xA753, 0xCB22,
+	0xA754, 0xCB23, 0xA755, 0xCB24, 0xA756, 0xCB25, 0xA757, 0xCB26,
+	0xA758, 0xCB27, 0xA759, 0xCB28, 0xA75A, 0xCB29, 0xA761, 0xCB2A,
+	0xA762, 0xCB2B, 0xA763, 0xCB2C, 0xA764, 0xCB2D, 0xA765, 0xCB2E,
+	0xA766, 0xCB2F, 0xA767, 0xCB30, 0xA768, 0xCB31, 0xA769, 0xCB32,
+	0xA76A, 0xCB33, 0xA76B, 0xCB34, 0xA76C, 0xCB35, 0xA76D, 0xCB36,
+	0xA76E, 0xCB37, 0xA76F, 0xCB38, 0xA770, 0xCB39, 0xA771, 0xCB3A,
+	0xA772, 0xCB3B, 0xA773, 0xCB3C, 0xA774, 0xCB3D, 0xA775, 0xCB3E,
+	0xA776, 0xCB3F, 0xA777, 0xCB40, 0xA778, 0xCB42, 0xA779, 0xCB43,
+	0xA77A, 0xCB44, 0xA781, 0xCB45, 0xA782, 0xCB46, 0xA783, 0xCB47,
+	0xA784, 0xCB4A, 0xA785, 0xCB4B, 0xA786, 0xCB4D, 0xA787, 0xCB4E,
+	0xA788, 0xCB4F, 0xA789, 0xCB51, 0xA78A, 0xCB52, 0xA78B, 0xCB53,
+	0xA78C, 0xCB54, 0xA78D, 0xCB55, 0xA78E, 0xCB56, 0xA78F, 0xCB57,
+	0xA790, 0xCB5A, 0xA791, 0xCB5B, 0xA792, 0xCB5C, 0xA793, 0xCB5E,
+	0xA794, 0xCB5F, 0xA795, 0xCB60, 0xA796, 0xCB61, 0xA797, 0xCB62,
+	0xA798, 0xCB63, 0xA799, 0xCB65, 0xA79A, 0xCB66, 0xA79B, 0xCB67,
+	0xA79C, 0xCB68, 0xA79D, 0xCB69, 0xA79E, 0xCB6A, 0xA79F, 0xCB6B,
+	0xA7A0, 0xCB6C, 0xA7A1, 0x3395, 0xA7A2, 0x3396, 0xA7A3, 0x3397,
+	0xA7A4, 0x2113, 0xA7A5, 0x3398, 0xA7A6, 0x33C4, 0xA7A7, 0x33A3,
+	0xA7A8, 0x33A4, 0xA7A9, 0x33A5, 0xA7AA, 0x33A6, 0xA7AB, 0x3399,
+	0xA7AC, 0x339A, 0xA7AD, 0x339B, 0xA7AE, 0x339C, 0xA7AF, 0x339D,
+	0xA7B0, 0x339E, 0xA7B1, 0x339F, 0xA7B2, 0x33A0, 0xA7B3, 0x33A1,
+	0xA7B4, 0x33A2, 0xA7B5, 0x33CA, 0xA7B6, 0x338D, 0xA7B7, 0x338E,
+	0xA7B8, 0x338F, 0xA7B9, 0x33CF, 0xA7BA, 0x3388, 0xA7BB, 0x3389,
+	0xA7BC, 0x33C8, 0xA7BD, 0x33A7, 0xA7BE, 0x33A8, 0xA7BF, 0x33B0,
+	0xA7C0, 0x33B1, 0xA7C1, 0x33B2, 0xA7C2, 0x33B3, 0xA7C3, 0x33B4,
+	0xA7C4, 0x33B5, 0xA7C5, 0x33B6, 0xA7C6, 0x33B7, 0xA7C7, 0x33B8,
+	0xA7C8, 0x33B9, 0xA7C9, 0x3380, 0xA7CA, 0x3381, 0xA7CB, 0x3382,
+	0xA7CC, 0x3383, 0xA7CD, 0x3384, 0xA7CE, 0x33BA, 0xA7CF, 0x33BB,
+	0xA7D0, 0x33BC, 0xA7D1, 0x33BD, 0xA7D2, 0x33BE, 0xA7D3, 0x33BF,
+	0xA7D4, 0x3390, 0xA7D5, 0x3391, 0xA7D6, 0x3392, 0xA7D7, 0x3393,
+	0xA7D8, 0x3394, 0xA7D9, 0x2126, 0xA7DA, 0x33C0, 0xA7DB, 0x33C1,
+	0xA7DC, 0x338A, 0xA7DD, 0x338B, 0xA7DE, 0x338C, 0xA7DF, 0x33D6,
+	0xA7E0, 0x33C5, 0xA7E1, 0x33AD, 0xA7E2, 0x33AE, 0xA7E3, 0x33AF,
+	0xA7E4, 0x33DB, 0xA7E5, 0x33A9, 0xA7E6, 0x33AA, 0xA7E7, 0x33AB,
+	0xA7E8, 0x33AC, 0xA7E9, 0x33DD, 0xA7EA, 0x33D0, 0xA7EB, 0x33D3,
+	0xA7EC, 0x33C3, 0xA7ED, 0x33C9, 0xA7EE, 0x33DC, 0xA7EF, 0x33C6,
+	0xA841, 0xCB6D, 0xA842, 0xCB6E, 0xA843, 0xCB6F, 0xA844, 0xCB70,
+	0xA845, 0xCB71, 0xA846, 0xCB72, 0xA847, 0xCB73, 0xA848, 0xCB74,
+	0xA849, 0xCB75, 0xA84A, 0xCB76, 0xA84B, 0xCB77, 0xA84C, 0xCB7A,
+	0xA84D, 0xCB7B, 0xA84E, 0xCB7C, 0xA84F, 0xCB7D, 0xA850, 0xCB7E,
+	0xA851, 0xCB7F, 0xA852, 0xCB80, 0xA853, 0xCB81, 0xA854, 0xCB82,
+	0xA855, 0xCB83, 0xA856, 0xCB84, 0xA857, 0xCB85, 0xA858, 0xCB86,
+	0xA859, 0xCB87, 0xA85A, 0xCB88, 0xA861, 0xCB89, 0xA862, 0xCB8A,
+	0xA863, 0xCB8B, 0xA864, 0xCB8C, 0xA865, 0xCB8D, 0xA866, 0xCB8E,
+	0xA867, 0xCB8F, 0xA868, 0xCB90, 0xA869, 0xCB91, 0xA86A, 0xCB92,
+	0xA86B, 0xCB93, 0xA86C, 0xCB94, 0xA86D, 0xCB95, 0xA86E, 0xCB96,
+	0xA86F, 0xCB97, 0xA870, 0xCB98, 0xA871, 0xCB99, 0xA872, 0xCB9A,
+	0xA873, 0xCB9B, 0xA874, 0xCB9D, 0xA875, 0xCB9E, 0xA876, 0xCB9F,
+	0xA877, 0xCBA0, 0xA878, 0xCBA1, 0xA879, 0xCBA2, 0xA87A, 0xCBA3,
+	0xA881, 0xCBA4, 0xA882, 0xCBA5, 0xA883, 0xCBA6, 0xA884, 0xCBA7,
+	0xA885, 0xCBA8, 0xA886, 0xCBA9, 0xA887, 0xCBAA, 0xA888, 0xCBAB,
+	0xA889, 0xCBAC, 0xA88A, 0xCBAD, 0xA88B, 0xCBAE, 0xA88C, 0xCBAF,
+	0xA88D, 0xCBB0, 0xA88E, 0xCBB1, 0xA88F, 0xCBB2, 0xA890, 0xCBB3,
+	0xA891, 0xCBB4, 0xA892, 0xCBB5, 0xA893, 0xCBB6, 0xA894, 0xCBB7,
+	0xA895, 0xCBB9, 0xA896, 0xCBBA, 0xA897, 0xCBBB, 0xA898, 0xCBBC,
+	0xA899, 0xCBBD, 0xA89A, 0xCBBE, 0xA89B, 0xCBBF, 0xA89C, 0xCBC0,
+	0xA89D, 0xCBC1, 0xA89E, 0xCBC2, 0xA89F, 0xCBC3, 0xA8A0, 0xCBC4,
+	0xA8A1, 0x00C6, 0xA8A2, 0x00D0, 0xA8A3, 0x00AA, 0xA8A4, 0x0126,
+	0xA8A6, 0x0132, 0xA8A8, 0x013F, 0xA8A9, 0x0141, 0xA8AA, 0x00D8,
+	0xA8AB, 0x0152, 0xA8AC, 0x00BA, 0xA8AD, 0x00DE, 0xA8AE, 0x0166,
+	0xA8AF, 0x014A, 0xA8B1, 0x3260, 0xA8B2, 0x3261, 0xA8B3, 0x3262,
+	0xA8B4, 0x3263, 0xA8B5, 0x3264, 0xA8B6, 0x3265, 0xA8B7, 0x3266,
+	0xA8B8, 0x3267, 0xA8B9, 0x3268, 0xA8BA, 0x3269, 0xA8BB, 0x326A,
+	0xA8BC, 0x326B, 0xA8BD, 0x326C, 0xA8BE, 0x326D, 0xA8BF, 0x326E,
+	0xA8C0, 0x326F, 0xA8C1, 0x3270, 0xA8C2, 0x3271, 0xA8C3, 0x3272,
+	0xA8C4, 0x3273, 0xA8C5, 0x3274, 0xA8C6, 0x3275, 0xA8C7, 0x3276,
+	0xA8C8, 0x3277, 0xA8C9, 0x3278, 0xA8CA, 0x3279, 0xA8CB, 0x327A,
+	0xA8CC, 0x327B, 0xA8CD, 0x24D0, 0xA8CE, 0x24D1, 0xA8CF, 0x24D2,
+	0xA8D0, 0x24D3, 0xA8D1, 0x24D4, 0xA8D2, 0x24D5, 0xA8D3, 0x24D6,
+	0xA8D4, 0x24D7, 0xA8D5, 0x24D8, 0xA8D6, 0x24D9, 0xA8D7, 0x24DA,
+	0xA8D8, 0x24DB, 0xA8D9, 0x24DC, 0xA8DA, 0x24DD, 0xA8DB, 0x24DE,
+	0xA8DC, 0x24DF, 0xA8DD, 0x24E0, 0xA8DE, 0x24E1, 0xA8DF, 0x24E2,
+	0xA8E0, 0x24E3, 0xA8E1, 0x24E4, 0xA8E2, 0x24E5, 0xA8E3, 0x24E6,
+	0xA8E4, 0x24E7, 0xA8E5, 0x24E8, 0xA8E6, 0x24E9, 0xA8E7, 0x2460,
+	0xA8E8, 0x2461, 0xA8E9, 0x2462, 0xA8EA, 0x2463, 0xA8EB, 0x2464,
+	0xA8EC, 0x2465, 0xA8ED, 0x2466, 0xA8EE, 0x2467, 0xA8EF, 0x2468,
+	0xA8F0, 0x2469, 0xA8F1, 0x246A, 0xA8F2, 0x246B, 0xA8F3, 0x246C,
+	0xA8F4, 0x246D, 0xA8F5, 0x246E, 0xA8F6, 0x00BD, 0xA8F7, 0x2153,
+	0xA8F8, 0x2154, 0xA8F9, 0x00BC, 0xA8FA, 0x00BE, 0xA8FB, 0x215B,
+	0xA8FC, 0x215C, 0xA8FD, 0x215D, 0xA8FE, 0x215E, 0xA941, 0xCBC5,
+	0xA942, 0xCBC6, 0xA943, 0xCBC7, 0xA944, 0xCBC8, 0xA945, 0xCBC9,
+	0xA946, 0xCBCA, 0xA947, 0xCBCB, 0xA948, 0xCBCC, 0xA949, 0xCBCD,
+	0xA94A, 0xCBCE, 0xA94B, 0xCBCF, 0xA94C, 0xCBD0, 0xA94D, 0xCBD1,
+	0xA94E, 0xCBD2, 0xA94F, 0xCBD3, 0xA950, 0xCBD5, 0xA951, 0xCBD6,
+	0xA952, 0xCBD7, 0xA953, 0xCBD8, 0xA954, 0xCBD9, 0xA955, 0xCBDA,
+	0xA956, 0xCBDB, 0xA957, 0xCBDC, 0xA958, 0xCBDD, 0xA959, 0xCBDE,
+	0xA95A, 0xCBDF, 0xA961, 0xCBE0, 0xA962, 0xCBE1, 0xA963, 0xCBE2,
+	0xA964, 0xCBE3, 0xA965, 0xCBE5, 0xA966, 0xCBE6, 0xA967, 0xCBE8,
+	0xA968, 0xCBEA, 0xA969, 0xCBEB, 0xA96A, 0xCBEC, 0xA96B, 0xCBED,
+	0xA96C, 0xCBEE, 0xA96D, 0xCBEF, 0xA96E, 0xCBF0, 0xA96F, 0xCBF1,
+	0xA970, 0xCBF2, 0xA971, 0xCBF3, 0xA972, 0xCBF4, 0xA973, 0xCBF5,
+	0xA974, 0xCBF6, 0xA975, 0xCBF7, 0xA976, 0xCBF8, 0xA977, 0xCBF9,
+	0xA978, 0xCBFA, 0xA979, 0xCBFB, 0xA97A, 0xCBFC, 0xA981, 0xCBFD,
+	0xA982, 0xCBFE, 0xA983, 0xCBFF, 0xA984, 0xCC00, 0xA985, 0xCC01,
+	0xA986, 0xCC02, 0xA987, 0xCC03, 0xA988, 0xCC04, 0xA989, 0xCC05,
+	0xA98A, 0xCC06, 0xA98B, 0xCC07, 0xA98C, 0xCC08, 0xA98D, 0xCC09,
+	0xA98E, 0xCC0A, 0xA98F, 0xCC0B, 0xA990, 0xCC0E, 0xA991, 0xCC0F,
+	0xA992, 0xCC11, 0xA993, 0xCC12, 0xA994, 0xCC13, 0xA995, 0xCC15,
+	0xA996, 0xCC16, 0xA997, 0xCC17, 0xA998, 0xCC18, 0xA999, 0xCC19,
+	0xA99A, 0xCC1A, 0xA99B, 0xCC1B, 0xA99C, 0xCC1E, 0xA99D, 0xCC1F,
+	0xA99E, 0xCC20, 0xA99F, 0xCC23, 0xA9A0, 0xCC24, 0xA9A1, 0x00E6,
+	0xA9A2, 0x0111, 0xA9A3, 0x00F0, 0xA9A4, 0x0127, 0xA9A5, 0x0131,
+	0xA9A6, 0x0133, 0xA9A7, 0x0138, 0xA9A8, 0x0140, 0xA9A9, 0x0142,
+	0xA9AA, 0x00F8, 0xA9AB, 0x0153, 0xA9AC, 0x00DF, 0xA9AD, 0x00FE,
+	0xA9AE, 0x0167, 0xA9AF, 0x014B, 0xA9B0, 0x0149, 0xA9B1, 0x3200,
+	0xA9B2, 0x3201, 0xA9B3, 0x3202, 0xA9B4, 0x3203, 0xA9B5, 0x3204,
+	0xA9B6, 0x3205, 0xA9B7, 0x3206, 0xA9B8, 0x3207, 0xA9B9, 0x3208,
+	0xA9BA, 0x3209, 0xA9BB, 0x320A, 0xA9BC, 0x320B, 0xA9BD, 0x320C,
+	0xA9BE, 0x320D, 0xA9BF, 0x320E, 0xA9C0, 0x320F, 0xA9C1, 0x3210,
+	0xA9C2, 0x3211, 0xA9C3, 0x3212, 0xA9C4, 0x3213, 0xA9C5, 0x3214,
+	0xA9C6, 0x3215, 0xA9C7, 0x3216, 0xA9C8, 0x3217, 0xA9C9, 0x3218,
+	0xA9CA, 0x3219, 0xA9CB, 0x321A, 0xA9CC, 0x321B, 0xA9CD, 0x249C,
+	0xA9CE, 0x249D, 0xA9CF, 0x249E, 0xA9D0, 0x249F, 0xA9D1, 0x24A0,
+	0xA9D2, 0x24A1, 0xA9D3, 0x24A2, 0xA9D4, 0x24A3, 0xA9D5, 0x24A4,
+	0xA9D6, 0x24A5, 0xA9D7, 0x24A6, 0xA9D8, 0x24A7, 0xA9D9, 0x24A8,
+	0xA9DA, 0x24A9, 0xA9DB, 0x24AA, 0xA9DC, 0x24AB, 0xA9DD, 0x24AC,
+	0xA9DE, 0x24AD, 0xA9DF, 0x24AE, 0xA9E0, 0x24AF, 0xA9E1, 0x24B0,
+	0xA9E2, 0x24B1, 0xA9E3, 0x24B2, 0xA9E4, 0x24B3, 0xA9E5, 0x24B4,
+	0xA9E6, 0x24B5, 0xA9E7, 0x2474, 0xA9E8, 0x2475, 0xA9E9, 0x2476,
+	0xA9EA, 0x2477, 0xA9EB, 0x2478, 0xA9EC, 0x2479, 0xA9ED, 0x247A,
+	0xA9EE, 0x247B, 0xA9EF, 0x247C, 0xA9F0, 0x247D, 0xA9F1, 0x247E,
+	0xA9F2, 0x247F, 0xA9F3, 0x2480, 0xA9F4, 0x2481, 0xA9F5, 0x2482,
+	0xA9F6, 0x00B9, 0xA9F7, 0x00B2, 0xA9F8, 0x00B3, 0xA9F9, 0x2074,
+	0xA9FA, 0x207F, 0xA9FB, 0x2081, 0xA9FC, 0x2082, 0xA9FD, 0x2083,
+	0xA9FE, 0x2084, 0xAA41, 0xCC25, 0xAA42, 0xCC26, 0xAA43, 0xCC2A,
+	0xAA44, 0xCC2B, 0xAA45, 0xCC2D, 0xAA46, 0xCC2F, 0xAA47, 0xCC31,
+	0xAA48, 0xCC32, 0xAA49, 0xCC33, 0xAA4A, 0xCC34, 0xAA4B, 0xCC35,
+	0xAA4C, 0xCC36, 0xAA4D, 0xCC37, 0xAA4E, 0xCC3A, 0xAA4F, 0xCC3F,
+	0xAA50, 0xCC40, 0xAA51, 0xCC41, 0xAA52, 0xCC42, 0xAA53, 0xCC43,
+	0xAA54, 0xCC46, 0xAA55, 0xCC47, 0xAA56, 0xCC49, 0xAA57, 0xCC4A,
+	0xAA58, 0xCC4B, 0xAA59, 0xCC4D, 0xAA5A, 0xCC4E, 0xAA61, 0xCC4F,
+	0xAA62, 0xCC50, 0xAA63, 0xCC51, 0xAA64, 0xCC52, 0xAA65, 0xCC53,
+	0xAA66, 0xCC56, 0xAA67, 0xCC5A, 0xAA68, 0xCC5B, 0xAA69, 0xCC5C,
+	0xAA6A, 0xCC5D, 0xAA6B, 0xCC5E, 0xAA6C, 0xCC5F, 0xAA6D, 0xCC61,
+	0xAA6E, 0xCC62, 0xAA6F, 0xCC63, 0xAA70, 0xCC65, 0xAA71, 0xCC67,
+	0xAA72, 0xCC69, 0xAA73, 0xCC6A, 0xAA74, 0xCC6B, 0xAA75, 0xCC6C,
+	0xAA76, 0xCC6D, 0xAA77, 0xCC6E, 0xAA78, 0xCC6F, 0xAA79, 0xCC71,
+	0xAA7A, 0xCC72, 0xAA81, 0xCC73, 0xAA82, 0xCC74, 0xAA83, 0xCC76,
+	0xAA84, 0xCC77, 0xAA85, 0xCC78, 0xAA86, 0xCC79, 0xAA87, 0xCC7A,
+	0xAA88, 0xCC7B, 0xAA89, 0xCC7C, 0xAA8A, 0xCC7D, 0xAA8B, 0xCC7E,
+	0xAA8C, 0xCC7F, 0xAA8D, 0xCC80, 0xAA8E, 0xCC81, 0xAA8F, 0xCC82,
+	0xAA90, 0xCC83, 0xAA91, 0xCC84, 0xAA92, 0xCC85, 0xAA93, 0xCC86,
+	0xAA94, 0xCC87, 0xAA95, 0xCC88, 0xAA96, 0xCC89, 0xAA97, 0xCC8A,
+	0xAA98, 0xCC8B, 0xAA99, 0xCC8C, 0xAA9A, 0xCC8D, 0xAA9B, 0xCC8E,
+	0xAA9C, 0xCC8F, 0xAA9D, 0xCC90, 0xAA9E, 0xCC91, 0xAA9F, 0xCC92,
+	0xAAA0, 0xCC93, 0xAAA1, 0x3041, 0xAAA2, 0x3042, 0xAAA3, 0x3043,
+	0xAAA4, 0x3044, 0xAAA5, 0x3045, 0xAAA6, 0x3046, 0xAAA7, 0x3047,
+	0xAAA8, 0x3048, 0xAAA9, 0x3049, 0xAAAA, 0x304A, 0xAAAB, 0x304B,
+	0xAAAC, 0x304C, 0xAAAD, 0x304D, 0xAAAE, 0x304E, 0xAAAF, 0x304F,
+	0xAAB0, 0x3050, 0xAAB1, 0x3051, 0xAAB2, 0x3052, 0xAAB3, 0x3053,
+	0xAAB4, 0x3054, 0xAAB5, 0x3055, 0xAAB6, 0x3056, 0xAAB7, 0x3057,
+	0xAAB8, 0x3058, 0xAAB9, 0x3059, 0xAABA, 0x305A, 0xAABB, 0x305B,
+	0xAABC, 0x305C, 0xAABD, 0x305D, 0xAABE, 0x305E, 0xAABF, 0x305F,
+	0xAAC0, 0x3060, 0xAAC1, 0x3061, 0xAAC2, 0x3062, 0xAAC3, 0x3063,
+	0xAAC4, 0x3064, 0xAAC5, 0x3065, 0xAAC6, 0x3066, 0xAAC7, 0x3067,
+	0xAAC8, 0x3068, 0xAAC9, 0x3069, 0xAACA, 0x306A, 0xAACB, 0x306B,
+	0xAACC, 0x306C, 0xAACD, 0x306D, 0xAACE, 0x306E, 0xAACF, 0x306F,
+	0xAAD0, 0x3070, 0xAAD1, 0x3071, 0xAAD2, 0x3072, 0xAAD3, 0x3073,
+	0xAAD4, 0x3074, 0xAAD5, 0x3075, 0xAAD6, 0x3076, 0xAAD7, 0x3077,
+	0xAAD8, 0x3078, 0xAAD9, 0x3079, 0xAADA, 0x307A, 0xAADB, 0x307B,
+	0xAADC, 0x307C, 0xAADD, 0x307D, 0xAADE, 0x307E, 0xAADF, 0x307F,
+	0xAAE0, 0x3080, 0xAAE1, 0x3081, 0xAAE2, 0x3082, 0xAAE3, 0x3083,
+	0xAAE4, 0x3084, 0xAAE5, 0x3085, 0xAAE6, 0x3086, 0xAAE7, 0x3087,
+	0xAAE8, 0x3088, 0xAAE9, 0x3089, 0xAAEA, 0x308A, 0xAAEB, 0x308B,
+	0xAAEC, 0x308C, 0xAAED, 0x308D, 0xAAEE, 0x308E, 0xAAEF, 0x308F,
+	0xAAF0, 0x3090, 0xAAF1, 0x3091, 0xAAF2, 0x3092, 0xAAF3, 0x3093,
+	0xAB41, 0xCC94, 0xAB42, 0xCC95, 0xAB43, 0xCC96, 0xAB44, 0xCC97,
+	0xAB45, 0xCC9A, 0xAB46, 0xCC9B, 0xAB47, 0xCC9D, 0xAB48, 0xCC9E,
+	0xAB49, 0xCC9F, 0xAB4A, 0xCCA1, 0xAB4B, 0xCCA2, 0xAB4C, 0xCCA3,
+	0xAB4D, 0xCCA4, 0xAB4E, 0xCCA5, 0xAB4F, 0xCCA6, 0xAB50, 0xCCA7,
+	0xAB51, 0xCCAA, 0xAB52, 0xCCAE, 0xAB53, 0xCCAF, 0xAB54, 0xCCB0,
+	0xAB55, 0xCCB1, 0xAB56, 0xCCB2, 0xAB57, 0xCCB3, 0xAB58, 0xCCB6,
+	0xAB59, 0xCCB7, 0xAB5A, 0xCCB9, 0xAB61, 0xCCBA, 0xAB62, 0xCCBB,
+	0xAB63, 0xCCBD, 0xAB64, 0xCCBE, 0xAB65, 0xCCBF, 0xAB66, 0xCCC0,
+	0xAB67, 0xCCC1, 0xAB68, 0xCCC2, 0xAB69, 0xCCC3, 0xAB6A, 0xCCC6,
+	0xAB6B, 0xCCC8, 0xAB6C, 0xCCCA, 0xAB6D, 0xCCCB, 0xAB6E, 0xCCCC,
+	0xAB6F, 0xCCCD, 0xAB70, 0xCCCE, 0xAB71, 0xCCCF, 0xAB72, 0xCCD1,
+	0xAB73, 0xCCD2, 0xAB74, 0xCCD3, 0xAB75, 0xCCD5, 0xAB76, 0xCCD6,
+	0xAB77, 0xCCD7, 0xAB78, 0xCCD8, 0xAB79, 0xCCD9, 0xAB7A, 0xCCDA,
+	0xAB81, 0xCCDB, 0xAB82, 0xCCDC, 0xAB83, 0xCCDD, 0xAB84, 0xCCDE,
+	0xAB85, 0xCCDF, 0xAB86, 0xCCE0, 0xAB87, 0xCCE1, 0xAB88, 0xCCE2,
+	0xAB89, 0xCCE3, 0xAB8A, 0xCCE5, 0xAB8B, 0xCCE6, 0xAB8C, 0xCCE7,
+	0xAB8D, 0xCCE8, 0xAB8E, 0xCCE9, 0xAB8F, 0xCCEA, 0xAB90, 0xCCEB,
+	0xAB91, 0xCCED, 0xAB92, 0xCCEE, 0xAB93, 0xCCEF, 0xAB94, 0xCCF1,
+	0xAB95, 0xCCF2, 0xAB96, 0xCCF3, 0xAB97, 0xCCF4, 0xAB98, 0xCCF5,
+	0xAB99, 0xCCF6, 0xAB9A, 0xCCF7, 0xAB9B, 0xCCF8, 0xAB9C, 0xCCF9,
+	0xAB9D, 0xCCFA, 0xAB9E, 0xCCFB, 0xAB9F, 0xCCFC, 0xABA0, 0xCCFD,
+	0xABA1, 0x30A1, 0xABA2, 0x30A2, 0xABA3, 0x30A3, 0xABA4, 0x30A4,
+	0xABA5, 0x30A5, 0xABA6, 0x30A6, 0xABA7, 0x30A7, 0xABA8, 0x30A8,
+	0xABA9, 0x30A9, 0xABAA, 0x30AA, 0xABAB, 0x30AB, 0xABAC, 0x30AC,
+	0xABAD, 0x30AD, 0xABAE, 0x30AE, 0xABAF, 0x30AF, 0xABB0, 0x30B0,
+	0xABB1, 0x30B1, 0xABB2, 0x30B2, 0xABB3, 0x30B3, 0xABB4, 0x30B4,
+	0xABB5, 0x30B5, 0xABB6, 0x30B6, 0xABB7, 0x30B7, 0xABB8, 0x30B8,
+	0xABB9, 0x30B9, 0xABBA, 0x30BA, 0xABBB, 0x30BB, 0xABBC, 0x30BC,
+	0xABBD, 0x30BD, 0xABBE, 0x30BE, 0xABBF, 0x30BF, 0xABC0, 0x30C0,
+	0xABC1, 0x30C1, 0xABC2, 0x30C2, 0xABC3, 0x30C3, 0xABC4, 0x30C4,
+	0xABC5, 0x30C5, 0xABC6, 0x30C6, 0xABC7, 0x30C7, 0xABC8, 0x30C8,
+	0xABC9, 0x30C9, 0xABCA, 0x30CA, 0xABCB, 0x30CB, 0xABCC, 0x30CC,
+	0xABCD, 0x30CD, 0xABCE, 0x30CE, 0xABCF, 0x30CF, 0xABD0, 0x30D0,
+	0xABD1, 0x30D1, 0xABD2, 0x30D2, 0xABD3, 0x30D3, 0xABD4, 0x30D4,
+	0xABD5, 0x30D5, 0xABD6, 0x30D6, 0xABD7, 0x30D7, 0xABD8, 0x30D8,
+	0xABD9, 0x30D9, 0xABDA, 0x30DA, 0xABDB, 0x30DB, 0xABDC, 0x30DC,
+	0xABDD, 0x30DD, 0xABDE, 0x30DE, 0xABDF, 0x30DF, 0xABE0, 0x30E0,
+	0xABE1, 0x30E1, 0xABE2, 0x30E2, 0xABE3, 0x30E3, 0xABE4, 0x30E4,
+	0xABE5, 0x30E5, 0xABE6, 0x30E6, 0xABE7, 0x30E7, 0xABE8, 0x30E8,
+	0xABE9, 0x30E9, 0xABEA, 0x30EA, 0xABEB, 0x30EB, 0xABEC, 0x30EC,
+	0xABED, 0x30ED, 0xABEE, 0x30EE, 0xABEF, 0x30EF, 0xABF0, 0x30F0,
+	0xABF1, 0x30F1, 0xABF2, 0x30F2, 0xABF3, 0x30F3, 0xABF4, 0x30F4,
+	0xABF5, 0x30F5, 0xABF6, 0x30F6, 0xAC41, 0xCCFE, 0xAC42, 0xCCFF,
+	0xAC43, 0xCD00, 0xAC44, 0xCD02, 0xAC45, 0xCD03, 0xAC46, 0xCD04,
+	0xAC47, 0xCD05, 0xAC48, 0xCD06, 0xAC49, 0xCD07, 0xAC4A, 0xCD0A,
+	0xAC4B, 0xCD0B, 0xAC4C, 0xCD0D, 0xAC4D, 0xCD0E, 0xAC4E, 0xCD0F,
+	0xAC4F, 0xCD11, 0xAC50, 0xCD12, 0xAC51, 0xCD13, 0xAC52, 0xCD14,
+	0xAC53, 0xCD15, 0xAC54, 0xCD16, 0xAC55, 0xCD17, 0xAC56, 0xCD1A,
+	0xAC57, 0xCD1C, 0xAC58, 0xCD1E, 0xAC59, 0xCD1F, 0xAC5A, 0xCD20,
+	0xAC61, 0xCD21, 0xAC62, 0xCD22, 0xAC63, 0xCD23, 0xAC64, 0xCD25,
+	0xAC65, 0xCD26, 0xAC66, 0xCD27, 0xAC67, 0xCD29, 0xAC68, 0xCD2A,
+	0xAC69, 0xCD2B, 0xAC6A, 0xCD2D, 0xAC6B, 0xCD2E, 0xAC6C, 0xCD2F,
+	0xAC6D, 0xCD30, 0xAC6E, 0xCD31, 0xAC6F, 0xCD32, 0xAC70, 0xCD33,
+	0xAC71, 0xCD34, 0xAC72, 0xCD35, 0xAC73, 0xCD36, 0xAC74, 0xCD37,
+	0xAC75, 0xCD38, 0xAC76, 0xCD3A, 0xAC77, 0xCD3B, 0xAC78, 0xCD3C,
+	0xAC79, 0xCD3D, 0xAC7A, 0xCD3E, 0xAC81, 0xCD3F, 0xAC82, 0xCD40,
+	0xAC83, 0xCD41, 0xAC84, 0xCD42, 0xAC85, 0xCD43, 0xAC86, 0xCD44,
+	0xAC87, 0xCD45, 0xAC88, 0xCD46, 0xAC89, 0xCD47, 0xAC8A, 0xCD48,
+	0xAC8B, 0xCD49, 0xAC8C, 0xCD4A, 0xAC8D, 0xCD4B, 0xAC8E, 0xCD4C,
+	0xAC8F, 0xCD4D, 0xAC90, 0xCD4E, 0xAC91, 0xCD4F, 0xAC92, 0xCD50,
+	0xAC93, 0xCD51, 0xAC94, 0xCD52, 0xAC95, 0xCD53, 0xAC96, 0xCD54,
+	0xAC97, 0xCD55, 0xAC98, 0xCD56, 0xAC99, 0xCD57, 0xAC9A, 0xCD58,
+	0xAC9B, 0xCD59, 0xAC9C, 0xCD5A, 0xAC9D, 0xCD5B, 0xAC9E, 0xCD5D,
+	0xAC9F, 0xCD5E, 0xACA0, 0xCD5F, 0xACA1, 0x0410, 0xACA2, 0x0411,
+	0xACA3, 0x0412, 0xACA4, 0x0413, 0xACA5, 0x0414, 0xACA6, 0x0415,
+	0xACA7, 0x0401, 0xACA8, 0x0416, 0xACA9, 0x0417, 0xACAA, 0x0418,
+	0xACAB, 0x0419, 0xACAC, 0x041A, 0xACAD, 0x041B, 0xACAE, 0x041C,
+	0xACAF, 0x041D, 0xACB0, 0x041E, 0xACB1, 0x041F, 0xACB2, 0x0420,
+	0xACB3, 0x0421, 0xACB4, 0x0422, 0xACB5, 0x0423, 0xACB6, 0x0424,
+	0xACB7, 0x0425, 0xACB8, 0x0426, 0xACB9, 0x0427, 0xACBA, 0x0428,
+	0xACBB, 0x0429, 0xACBC, 0x042A, 0xACBD, 0x042B, 0xACBE, 0x042C,
+	0xACBF, 0x042D, 0xACC0, 0x042E, 0xACC1, 0x042F, 0xACD1, 0x0430,
+	0xACD2, 0x0431, 0xACD3, 0x0432, 0xACD4, 0x0433, 0xACD5, 0x0434,
+	0xACD6, 0x0435, 0xACD7, 0x0451, 0xACD8, 0x0436, 0xACD9, 0x0437,
+	0xACDA, 0x0438, 0xACDB, 0x0439, 0xACDC, 0x043A, 0xACDD, 0x043B,
+	0xACDE, 0x043C, 0xACDF, 0x043D, 0xACE0, 0x043E, 0xACE1, 0x043F,
+	0xACE2, 0x0440, 0xACE3, 0x0441, 0xACE4, 0x0442, 0xACE5, 0x0443,
+	0xACE6, 0x0444, 0xACE7, 0x0445, 0xACE8, 0x0446, 0xACE9, 0x0447,
+	0xACEA, 0x0448, 0xACEB, 0x0449, 0xACEC, 0x044A, 0xACED, 0x044B,
+	0xACEE, 0x044C, 0xACEF, 0x044D, 0xACF0, 0x044E, 0xACF1, 0x044F,
+	0xAD41, 0xCD61, 0xAD42, 0xCD62, 0xAD43, 0xCD63, 0xAD44, 0xCD65,
+	0xAD45, 0xCD66, 0xAD46, 0xCD67, 0xAD47, 0xCD68, 0xAD48, 0xCD69,
+	0xAD49, 0xCD6A, 0xAD4A, 0xCD6B, 0xAD4B, 0xCD6E, 0xAD4C, 0xCD70,
+	0xAD4D, 0xCD72, 0xAD4E, 0xCD73, 0xAD4F, 0xCD74, 0xAD50, 0xCD75,
+	0xAD51, 0xCD76, 0xAD52, 0xCD77, 0xAD53, 0xCD79, 0xAD54, 0xCD7A,
+	0xAD55, 0xCD7B, 0xAD56, 0xCD7C, 0xAD57, 0xCD7D, 0xAD58, 0xCD7E,
+	0xAD59, 0xCD7F, 0xAD5A, 0xCD80, 0xAD61, 0xCD81, 0xAD62, 0xCD82,
+	0xAD63, 0xCD83, 0xAD64, 0xCD84, 0xAD65, 0xCD85, 0xAD66, 0xCD86,
+	0xAD67, 0xCD87, 0xAD68, 0xCD89, 0xAD69, 0xCD8A, 0xAD6A, 0xCD8B,
+	0xAD6B, 0xCD8C, 0xAD6C, 0xCD8D, 0xAD6D, 0xCD8E, 0xAD6E, 0xCD8F,
+	0xAD6F, 0xCD90, 0xAD70, 0xCD91, 0xAD71, 0xCD92, 0xAD72, 0xCD93,
+	0xAD73, 0xCD96, 0xAD74, 0xCD97, 0xAD75, 0xCD99, 0xAD76, 0xCD9A,
+	0xAD77, 0xCD9B, 0xAD78, 0xCD9D, 0xAD79, 0xCD9E, 0xAD7A, 0xCD9F,
+	0xAD81, 0xCDA0, 0xAD82, 0xCDA1, 0xAD83, 0xCDA2, 0xAD84, 0xCDA3,
+	0xAD85, 0xCDA6, 0xAD86, 0xCDA8, 0xAD87, 0xCDAA, 0xAD88, 0xCDAB,
+	0xAD89, 0xCDAC, 0xAD8A, 0xCDAD, 0xAD8B, 0xCDAE, 0xAD8C, 0xCDAF,
+	0xAD8D, 0xCDB1, 0xAD8E, 0xCDB2, 0xAD8F, 0xCDB3, 0xAD90, 0xCDB4,
+	0xAD91, 0xCDB5, 0xAD92, 0xCDB6, 0xAD93, 0xCDB7, 0xAD94, 0xCDB8,
+	0xAD95, 0xCDB9, 0xAD96, 0xCDBA, 0xAD97, 0xCDBB, 0xAD98, 0xCDBC,
+	0xAD99, 0xCDBD, 0xAD9A, 0xCDBE, 0xAD9B, 0xCDBF, 0xAD9C, 0xCDC0,
+	0xAD9D, 0xCDC1, 0xAD9E, 0xCDC2, 0xAD9F, 0xCDC3, 0xADA0, 0xCDC5,
+	0xAE41, 0xCDC6, 0xAE42, 0xCDC7, 0xAE43, 0xCDC8, 0xAE44, 0xCDC9,
+	0xAE45, 0xCDCA, 0xAE46, 0xCDCB, 0xAE47, 0xCDCD, 0xAE48, 0xCDCE,
+	0xAE49, 0xCDCF, 0xAE4A, 0xCDD1, 0xAE4B, 0xCDD2, 0xAE4C, 0xCDD3,
+	0xAE4D, 0xCDD4, 0xAE4E, 0xCDD5, 0xAE4F, 0xCDD6, 0xAE50, 0xCDD7,
+	0xAE51, 0xCDD8, 0xAE52, 0xCDD9, 0xAE53, 0xCDDA, 0xAE54, 0xCDDB,
+	0xAE55, 0xCDDC, 0xAE56, 0xCDDD, 0xAE57, 0xCDDE, 0xAE58, 0xCDDF,
+	0xAE59, 0xCDE0, 0xAE5A, 0xCDE1, 0xAE61, 0xCDE2, 0xAE62, 0xCDE3,
+	0xAE63, 0xCDE4, 0xAE64, 0xCDE5, 0xAE65, 0xCDE6, 0xAE66, 0xCDE7,
+	0xAE67, 0xCDE9, 0xAE68, 0xCDEA, 0xAE69, 0xCDEB, 0xAE6A, 0xCDED,
+	0xAE6B, 0xCDEE, 0xAE6C, 0xCDEF, 0xAE6D, 0xCDF1, 0xAE6E, 0xCDF2,
+	0xAE6F, 0xCDF3, 0xAE70, 0xCDF4, 0xAE71, 0xCDF5, 0xAE72, 0xCDF6,
+	0xAE73, 0xCDF7, 0xAE74, 0xCDFA, 0xAE75, 0xCDFC, 0xAE76, 0xCDFE,
+	0xAE77, 0xCDFF, 0xAE78, 0xCE00, 0xAE79, 0xCE01, 0xAE7A, 0xCE02,
+	0xAE81, 0xCE03, 0xAE82, 0xCE05, 0xAE83, 0xCE06, 0xAE84, 0xCE07,
+	0xAE85, 0xCE09, 0xAE86, 0xCE0A, 0xAE87, 0xCE0B, 0xAE88, 0xCE0D,
+	0xAE89, 0xCE0E, 0xAE8A, 0xCE0F, 0xAE8B, 0xCE10, 0xAE8C, 0xCE11,
+	0xAE8D, 0xCE12, 0xAE8E, 0xCE13, 0xAE8F, 0xCE15, 0xAE90, 0xCE16,
+	0xAE91, 0xCE17, 0xAE92, 0xCE18, 0xAE93, 0xCE1A, 0xAE94, 0xCE1B,
+	0xAE95, 0xCE1C, 0xAE96, 0xCE1D, 0xAE97, 0xCE1E, 0xAE98, 0xCE1F,
+	0xAE99, 0xCE22, 0xAE9A, 0xCE23, 0xAE9B, 0xCE25, 0xAE9C, 0xCE26,
+	0xAE9D, 0xCE27, 0xAE9E, 0xCE29, 0xAE9F, 0xCE2A, 0xAEA0, 0xCE2B,
+	0xAF41, 0xCE2C, 0xAF42, 0xCE2D, 0xAF43, 0xCE2E, 0xAF44, 0xCE2F,
+	0xAF45, 0xCE32, 0xAF46, 0xCE34, 0xAF47, 0xCE36, 0xAF48, 0xCE37,
+	0xAF49, 0xCE38, 0xAF4A, 0xCE39, 0xAF4B, 0xCE3A, 0xAF4C, 0xCE3B,
+	0xAF4D, 0xCE3C, 0xAF4E, 0xCE3D, 0xAF4F, 0xCE3E, 0xAF50, 0xCE3F,
+	0xAF51, 0xCE40, 0xAF52, 0xCE41, 0xAF53, 0xCE42, 0xAF54, 0xCE43,
+	0xAF55, 0xCE44, 0xAF56, 0xCE45, 0xAF57, 0xCE46, 0xAF58, 0xCE47,
+	0xAF59, 0xCE48, 0xAF5A, 0xCE49, 0xAF61, 0xCE4A, 0xAF62, 0xCE4B,
+	0xAF63, 0xCE4C, 0xAF64, 0xCE4D, 0xAF65, 0xCE4E, 0xAF66, 0xCE4F,
+	0xAF67, 0xCE50, 0xAF68, 0xCE51, 0xAF69, 0xCE52, 0xAF6A, 0xCE53,
+	0xAF6B, 0xCE54, 0xAF6C, 0xCE55, 0xAF6D, 0xCE56, 0xAF6E, 0xCE57,
+	0xAF6F, 0xCE5A, 0xAF70, 0xCE5B, 0xAF71, 0xCE5D, 0xAF72, 0xCE5E,
+	0xAF73, 0xCE62, 0xAF74, 0xCE63, 0xAF75, 0xCE64, 0xAF76, 0xCE65,
+	0xAF77, 0xCE66, 0xAF78, 0xCE67, 0xAF79, 0xCE6A, 0xAF7A, 0xCE6C,
+	0xAF81, 0xCE6E, 0xAF82, 0xCE6F, 0xAF83, 0xCE70, 0xAF84, 0xCE71,
+	0xAF85, 0xCE72, 0xAF86, 0xCE73, 0xAF87, 0xCE76, 0xAF88, 0xCE77,
+	0xAF89, 0xCE79, 0xAF8A, 0xCE7A, 0xAF8B, 0xCE7B, 0xAF8C, 0xCE7D,
+	0xAF8D, 0xCE7E, 0xAF8E, 0xCE7F, 0xAF8F, 0xCE80, 0xAF90, 0xCE81,
+	0xAF91, 0xCE82, 0xAF92, 0xCE83, 0xAF93, 0xCE86, 0xAF94, 0xCE88,
+	0xAF95, 0xCE8A, 0xAF96, 0xCE8B, 0xAF97, 0xCE8C, 0xAF98, 0xCE8D,
+	0xAF99, 0xCE8E, 0xAF9A, 0xCE8F, 0xAF9B, 0xCE92, 0xAF9C, 0xCE93,
+	0xAF9D, 0xCE95, 0xAF9E, 0xCE96, 0xAF9F, 0xCE97, 0xAFA0, 0xCE99,
+	0xB041, 0xCE9A, 0xB042, 0xCE9B, 0xB043, 0xCE9C, 0xB044, 0xCE9D,
+	0xB045, 0xCE9E, 0xB046, 0xCE9F, 0xB047, 0xCEA2, 0xB048, 0xCEA6,
+	0xB049, 0xCEA7, 0xB04A, 0xCEA8, 0xB04B, 0xCEA9, 0xB04C, 0xCEAA,
+	0xB04D, 0xCEAB, 0xB04E, 0xCEAE, 0xB04F, 0xCEAF, 0xB050, 0xCEB0,
+	0xB051, 0xCEB1, 0xB052, 0xCEB2, 0xB053, 0xCEB3, 0xB054, 0xCEB4,
+	0xB055, 0xCEB5, 0xB056, 0xCEB6, 0xB057, 0xCEB7, 0xB058, 0xCEB8,
+	0xB059, 0xCEB9, 0xB05A, 0xCEBA, 0xB061, 0xCEBB, 0xB062, 0xCEBC,
+	0xB063, 0xCEBD, 0xB064, 0xCEBE, 0xB065, 0xCEBF, 0xB066, 0xCEC0,
+	0xB067, 0xCEC2, 0xB068, 0xCEC3, 0xB069, 0xCEC4, 0xB06A, 0xCEC5,
+	0xB06B, 0xCEC6, 0xB06C, 0xCEC7, 0xB06D, 0xCEC8, 0xB06E, 0xCEC9,
+	0xB06F, 0xCECA, 0xB070, 0xCECB, 0xB071, 0xCECC, 0xB072, 0xCECD,
+	0xB073, 0xCECE, 0xB074, 0xCECF, 0xB075, 0xCED0, 0xB076, 0xCED1,
+	0xB077, 0xCED2, 0xB078, 0xCED3, 0xB079, 0xCED4, 0xB07A, 0xCED5,
+	0xB081, 0xCED6, 0xB082, 0xCED7, 0xB083, 0xCED8, 0xB084, 0xCED9,
+	0xB085, 0xCEDA, 0xB086, 0xCEDB, 0xB087, 0xCEDC, 0xB088, 0xCEDD,
+	0xB089, 0xCEDE, 0xB08A, 0xCEDF, 0xB08B, 0xCEE0, 0xB08C, 0xCEE1,
+	0xB08D, 0xCEE2, 0xB08E, 0xCEE3, 0xB08F, 0xCEE6, 0xB090, 0xCEE7,
+	0xB091, 0xCEE9, 0xB092, 0xCEEA, 0xB093, 0xCEED, 0xB094, 0xCEEE,
+	0xB095, 0xCEEF, 0xB096, 0xCEF0, 0xB097, 0xCEF1, 0xB098, 0xCEF2,
+	0xB099, 0xCEF3, 0xB09A, 0xCEF6, 0xB09B, 0xCEFA, 0xB09C, 0xCEFB,
+	0xB09D, 0xCEFC, 0xB09E, 0xCEFD, 0xB09F, 0xCEFE, 0xB0A0, 0xCEFF,
+	0xB0A1, 0xAC00, 0xB0A2, 0xAC01, 0xB0A3, 0xAC04, 0xB0A4, 0xAC07,
+	0xB0A5, 0xAC08, 0xB0A6, 0xAC09, 0xB0A7, 0xAC0A, 0xB0A8, 0xAC10,
+	0xB0A9, 0xAC11, 0xB0AA, 0xAC12, 0xB0AB, 0xAC13, 0xB0AC, 0xAC14,
+	0xB0AD, 0xAC15, 0xB0AE, 0xAC16, 0xB0AF, 0xAC17, 0xB0B0, 0xAC19,
+	0xB0B1, 0xAC1A, 0xB0B2, 0xAC1B, 0xB0B3, 0xAC1C, 0xB0B4, 0xAC1D,
+	0xB0B5, 0xAC20, 0xB0B6, 0xAC24, 0xB0B7, 0xAC2C, 0xB0B8, 0xAC2D,
+	0xB0B9, 0xAC2F, 0xB0BA, 0xAC30, 0xB0BB, 0xAC31, 0xB0BC, 0xAC38,
+	0xB0BD, 0xAC39, 0xB0BE, 0xAC3C, 0xB0BF, 0xAC40, 0xB0C0, 0xAC4B,
+	0xB0C1, 0xAC4D, 0xB0C2, 0xAC54, 0xB0C3, 0xAC58, 0xB0C4, 0xAC5C,
+	0xB0C5, 0xAC70, 0xB0C6, 0xAC71, 0xB0C7, 0xAC74, 0xB0C8, 0xAC77,
+	0xB0C9, 0xAC78, 0xB0CA, 0xAC7A, 0xB0CB, 0xAC80, 0xB0CC, 0xAC81,
+	0xB0CD, 0xAC83, 0xB0CE, 0xAC84, 0xB0CF, 0xAC85, 0xB0D0, 0xAC86,
+	0xB0D1, 0xAC89, 0xB0D2, 0xAC8A, 0xB0D3, 0xAC8B, 0xB0D4, 0xAC8C,
+	0xB0D5, 0xAC90, 0xB0D6, 0xAC94, 0xB0D7, 0xAC9C, 0xB0D8, 0xAC9D,
+	0xB0D9, 0xAC9F, 0xB0DA, 0xACA0, 0xB0DB, 0xACA1, 0xB0DC, 0xACA8,
+	0xB0DD, 0xACA9, 0xB0DE, 0xACAA, 0xB0DF, 0xACAC, 0xB0E0, 0xACAF,
+	0xB0E1, 0xACB0, 0xB0E2, 0xACB8, 0xB0E3, 0xACB9, 0xB0E4, 0xACBB,
+	0xB0E5, 0xACBC, 0xB0E6, 0xACBD, 0xB0E7, 0xACC1, 0xB0E8, 0xACC4,
+	0xB0E9, 0xACC8, 0xB0EA, 0xACCC, 0xB0EB, 0xACD5, 0xB0EC, 0xACD7,
+	0xB0ED, 0xACE0, 0xB0EE, 0xACE1, 0xB0EF, 0xACE4, 0xB0F0, 0xACE7,
+	0xB0F1, 0xACE8, 0xB0F2, 0xACEA, 0xB0F3, 0xACEC, 0xB0F4, 0xACEF,
+	0xB0F5, 0xACF0, 0xB0F6, 0xACF1, 0xB0F7, 0xACF3, 0xB0F8, 0xACF5,
+	0xB0F9, 0xACF6, 0xB0FA, 0xACFC, 0xB0FB, 0xACFD, 0xB0FC, 0xAD00,
+	0xB0FD, 0xAD04, 0xB0FE, 0xAD06, 0xB141, 0xCF02, 0xB142, 0xCF03,
+	0xB143, 0xCF05, 0xB144, 0xCF06, 0xB145, 0xCF07, 0xB146, 0xCF09,
+	0xB147, 0xCF0A, 0xB148, 0xCF0B, 0xB149, 0xCF0C, 0xB14A, 0xCF0D,
+	0xB14B, 0xCF0E, 0xB14C, 0xCF0F, 0xB14D, 0xCF12, 0xB14E, 0xCF14,
+	0xB14F, 0xCF16, 0xB150, 0xCF17, 0xB151, 0xCF18, 0xB152, 0xCF19,
+	0xB153, 0xCF1A, 0xB154, 0xCF1B, 0xB155, 0xCF1D, 0xB156, 0xCF1E,
+	0xB157, 0xCF1F, 0xB158, 0xCF21, 0xB159, 0xCF22, 0xB15A, 0xCF23,
+	0xB161, 0xCF25, 0xB162, 0xCF26, 0xB163, 0xCF27, 0xB164, 0xCF28,
+	0xB165, 0xCF29, 0xB166, 0xCF2A, 0xB167, 0xCF2B, 0xB168, 0xCF2E,
+	0xB169, 0xCF32, 0xB16A, 0xCF33, 0xB16B, 0xCF34, 0xB16C, 0xCF35,
+	0xB16D, 0xCF36, 0xB16E, 0xCF37, 0xB16F, 0xCF39, 0xB170, 0xCF3A,
+	0xB171, 0xCF3B, 0xB172, 0xCF3C, 0xB173, 0xCF3D, 0xB174, 0xCF3E,
+	0xB175, 0xCF3F, 0xB176, 0xCF40, 0xB177, 0xCF41, 0xB178, 0xCF42,
+	0xB179, 0xCF43, 0xB17A, 0xCF44, 0xB181, 0xCF45, 0xB182, 0xCF46,
+	0xB183, 0xCF47, 0xB184, 0xCF48, 0xB185, 0xCF49, 0xB186, 0xCF4A,
+	0xB187, 0xCF4B, 0xB188, 0xCF4C, 0xB189, 0xCF4D, 0xB18A, 0xCF4E,
+	0xB18B, 0xCF4F, 0xB18C, 0xCF50, 0xB18D, 0xCF51, 0xB18E, 0xCF52,
+	0xB18F, 0xCF53, 0xB190, 0xCF56, 0xB191, 0xCF57, 0xB192, 0xCF59,
+	0xB193, 0xCF5A, 0xB194, 0xCF5B, 0xB195, 0xCF5D, 0xB196, 0xCF5E,
+	0xB197, 0xCF5F, 0xB198, 0xCF60, 0xB199, 0xCF61, 0xB19A, 0xCF62,
+	0xB19B, 0xCF63, 0xB19C, 0xCF66, 0xB19D, 0xCF68, 0xB19E, 0xCF6A,
+	0xB19F, 0xCF6B, 0xB1A0, 0xCF6C, 0xB1A1, 0xAD0C, 0xB1A2, 0xAD0D,
+	0xB1A3, 0xAD0F, 0xB1A4, 0xAD11, 0xB1A5, 0xAD18, 0xB1A6, 0xAD1C,
+	0xB1A7, 0xAD20, 0xB1A8, 0xAD29, 0xB1A9, 0xAD2C, 0xB1AA, 0xAD2D,
+	0xB1AB, 0xAD34, 0xB1AC, 0xAD35, 0xB1AD, 0xAD38, 0xB1AE, 0xAD3C,
+	0xB1AF, 0xAD44, 0xB1B0, 0xAD45, 0xB1B1, 0xAD47, 0xB1B2, 0xAD49,
+	0xB1B3, 0xAD50, 0xB1B4, 0xAD54, 0xB1B5, 0xAD58, 0xB1B6, 0xAD61,
+	0xB1B7, 0xAD63, 0xB1B8, 0xAD6C, 0xB1B9, 0xAD6D, 0xB1BA, 0xAD70,
+	0xB1BB, 0xAD73, 0xB1BC, 0xAD74, 0xB1BD, 0xAD75, 0xB1BE, 0xAD76,
+	0xB1BF, 0xAD7B, 0xB1C0, 0xAD7C, 0xB1C1, 0xAD7D, 0xB1C2, 0xAD7F,
+	0xB1C3, 0xAD81, 0xB1C4, 0xAD82, 0xB1C5, 0xAD88, 0xB1C6, 0xAD89,
+	0xB1C7, 0xAD8C, 0xB1C8, 0xAD90, 0xB1C9, 0xAD9C, 0xB1CA, 0xAD9D,
+	0xB1CB, 0xADA4, 0xB1CC, 0xADB7, 0xB1CD, 0xADC0, 0xB1CE, 0xADC1,
+	0xB1CF, 0xADC4, 0xB1D0, 0xADC8, 0xB1D1, 0xADD0, 0xB1D2, 0xADD1,
+	0xB1D3, 0xADD3, 0xB1D4, 0xADDC, 0xB1D5, 0xADE0, 0xB1D6, 0xADE4,
+	0xB1D7, 0xADF8, 0xB1D8, 0xADF9, 0xB1D9, 0xADFC, 0xB1DA, 0xADFF,
+	0xB1DB, 0xAE00, 0xB1DC, 0xAE01, 0xB1DD, 0xAE08, 0xB1DE, 0xAE09,
+	0xB1DF, 0xAE0B, 0xB1E0, 0xAE0D, 0xB1E1, 0xAE14, 0xB1E2, 0xAE30,
+	0xB1E3, 0xAE31, 0xB1E4, 0xAE34, 0xB1E5, 0xAE37, 0xB1E6, 0xAE38,
+	0xB1E7, 0xAE3A, 0xB1E8, 0xAE40, 0xB1E9, 0xAE41, 0xB1EA, 0xAE43,
+	0xB1EB, 0xAE45, 0xB1EC, 0xAE46, 0xB1ED, 0xAE4A, 0xB1EE, 0xAE4C,
+	0xB1EF, 0xAE4D, 0xB1F0, 0xAE4E, 0xB1F1, 0xAE50, 0xB1F2, 0xAE54,
+	0xB1F3, 0xAE56, 0xB1F4, 0xAE5C, 0xB1F5, 0xAE5D, 0xB1F6, 0xAE5F,
+	0xB1F7, 0xAE60, 0xB1F8, 0xAE61, 0xB1F9, 0xAE65, 0xB1FA, 0xAE68,
+	0xB1FB, 0xAE69, 0xB1FC, 0xAE6C, 0xB1FD, 0xAE70, 0xB1FE, 0xAE78,
+	0xB241, 0xCF6D, 0xB242, 0xCF6E, 0xB243, 0xCF6F, 0xB244, 0xCF72,
+	0xB245, 0xCF73, 0xB246, 0xCF75, 0xB247, 0xCF76, 0xB248, 0xCF77,
+	0xB249, 0xCF79, 0xB24A, 0xCF7A, 0xB24B, 0xCF7B, 0xB24C, 0xCF7C,
+	0xB24D, 0xCF7D, 0xB24E, 0xCF7E, 0xB24F, 0xCF7F, 0xB250, 0xCF81,
+	0xB251, 0xCF82, 0xB252, 0xCF83, 0xB253, 0xCF84, 0xB254, 0xCF86,
+	0xB255, 0xCF87, 0xB256, 0xCF88, 0xB257, 0xCF89, 0xB258, 0xCF8A,
+	0xB259, 0xCF8B, 0xB25A, 0xCF8D, 0xB261, 0xCF8E, 0xB262, 0xCF8F,
+	0xB263, 0xCF90, 0xB264, 0xCF91, 0xB265, 0xCF92, 0xB266, 0xCF93,
+	0xB267, 0xCF94, 0xB268, 0xCF95, 0xB269, 0xCF96, 0xB26A, 0xCF97,
+	0xB26B, 0xCF98, 0xB26C, 0xCF99, 0xB26D, 0xCF9A, 0xB26E, 0xCF9B,
+	0xB26F, 0xCF9C, 0xB270, 0xCF9D, 0xB271, 0xCF9E, 0xB272, 0xCF9F,
+	0xB273, 0xCFA0, 0xB274, 0xCFA2, 0xB275, 0xCFA3, 0xB276, 0xCFA4,
+	0xB277, 0xCFA5, 0xB278, 0xCFA6, 0xB279, 0xCFA7, 0xB27A, 0xCFA9,
+	0xB281, 0xCFAA, 0xB282, 0xCFAB, 0xB283, 0xCFAC, 0xB284, 0xCFAD,
+	0xB285, 0xCFAE, 0xB286, 0xCFAF, 0xB287, 0xCFB1, 0xB288, 0xCFB2,
+	0xB289, 0xCFB3, 0xB28A, 0xCFB4, 0xB28B, 0xCFB5, 0xB28C, 0xCFB6,
+	0xB28D, 0xCFB7, 0xB28E, 0xCFB8, 0xB28F, 0xCFB9, 0xB290, 0xCFBA,
+	0xB291, 0xCFBB, 0xB292, 0xCFBC, 0xB293, 0xCFBD, 0xB294, 0xCFBE,
+	0xB295, 0xCFBF, 0xB296, 0xCFC0, 0xB297, 0xCFC1, 0xB298, 0xCFC2,
+	0xB299, 0xCFC3, 0xB29A, 0xCFC5, 0xB29B, 0xCFC6, 0xB29C, 0xCFC7,
+	0xB29D, 0xCFC8, 0xB29E, 0xCFC9, 0xB29F, 0xCFCA, 0xB2A0, 0xCFCB,
+	0xB2A1, 0xAE79, 0xB2A2, 0xAE7B, 0xB2A3, 0xAE7C, 0xB2A4, 0xAE7D,
+	0xB2A5, 0xAE84, 0xB2A6, 0xAE85, 0xB2A7, 0xAE8C, 0xB2A8, 0xAEBC,
+	0xB2A9, 0xAEBD, 0xB2AA, 0xAEBE, 0xB2AB, 0xAEC0, 0xB2AC, 0xAEC4,
+	0xB2AD, 0xAECC, 0xB2AE, 0xAECD, 0xB2AF, 0xAECF, 0xB2B0, 0xAED0,
+	0xB2B1, 0xAED1, 0xB2B2, 0xAED8, 0xB2B3, 0xAED9, 0xB2B4, 0xAEDC,
+	0xB2B5, 0xAEE8, 0xB2B6, 0xAEEB, 0xB2B7, 0xAEED, 0xB2B8, 0xAEF4,
+	0xB2B9, 0xAEF8, 0xB2BA, 0xAEFC, 0xB2BB, 0xAF07, 0xB2BC, 0xAF08,
+	0xB2BD, 0xAF0D, 0xB2BE, 0xAF10, 0xB2BF, 0xAF2C, 0xB2C0, 0xAF2D,
+	0xB2C1, 0xAF30, 0xB2C2, 0xAF32, 0xB2C3, 0xAF34, 0xB2C4, 0xAF3C,
+	0xB2C5, 0xAF3D, 0xB2C6, 0xAF3F, 0xB2C7, 0xAF41, 0xB2C8, 0xAF42,
+	0xB2C9, 0xAF43, 0xB2CA, 0xAF48, 0xB2CB, 0xAF49, 0xB2CC, 0xAF50,
+	0xB2CD, 0xAF5C, 0xB2CE, 0xAF5D, 0xB2CF, 0xAF64, 0xB2D0, 0xAF65,
+	0xB2D1, 0xAF79, 0xB2D2, 0xAF80, 0xB2D3, 0xAF84, 0xB2D4, 0xAF88,
+	0xB2D5, 0xAF90, 0xB2D6, 0xAF91, 0xB2D7, 0xAF95, 0xB2D8, 0xAF9C,
+	0xB2D9, 0xAFB8, 0xB2DA, 0xAFB9, 0xB2DB, 0xAFBC, 0xB2DC, 0xAFC0,
+	0xB2DD, 0xAFC7, 0xB2DE, 0xAFC8, 0xB2DF, 0xAFC9, 0xB2E0, 0xAFCB,
+	0xB2E1, 0xAFCD, 0xB2E2, 0xAFCE, 0xB2E3, 0xAFD4, 0xB2E4, 0xAFDC,
+	0xB2E5, 0xAFE8, 0xB2E6, 0xAFE9, 0xB2E7, 0xAFF0, 0xB2E8, 0xAFF1,
+	0xB2E9, 0xAFF4, 0xB2EA, 0xAFF8, 0xB2EB, 0xB000, 0xB2EC, 0xB001,
+	0xB2ED, 0xB004, 0xB2EE, 0xB00C, 0xB2EF, 0xB010, 0xB2F0, 0xB014,
+	0xB2F1, 0xB01C, 0xB2F2, 0xB01D, 0xB2F3, 0xB028, 0xB2F4, 0xB044,
+	0xB2F5, 0xB045, 0xB2F6, 0xB048, 0xB2F7, 0xB04A, 0xB2F8, 0xB04C,
+	0xB2F9, 0xB04E, 0xB2FA, 0xB053, 0xB2FB, 0xB054, 0xB2FC, 0xB055,
+	0xB2FD, 0xB057, 0xB2FE, 0xB059, 0xB341, 0xCFCC, 0xB342, 0xCFCD,
+	0xB343, 0xCFCE, 0xB344, 0xCFCF, 0xB345, 0xCFD0, 0xB346, 0xCFD1,
+	0xB347, 0xCFD2, 0xB348, 0xCFD3, 0xB349, 0xCFD4, 0xB34A, 0xCFD5,
+	0xB34B, 0xCFD6, 0xB34C, 0xCFD7, 0xB34D, 0xCFD8, 0xB34E, 0xCFD9,
+	0xB34F, 0xCFDA, 0xB350, 0xCFDB, 0xB351, 0xCFDC, 0xB352, 0xCFDD,
+	0xB353, 0xCFDE, 0xB354, 0xCFDF, 0xB355, 0xCFE2, 0xB356, 0xCFE3,
+	0xB357, 0xCFE5, 0xB358, 0xCFE6, 0xB359, 0xCFE7, 0xB35A, 0xCFE9,
+	0xB361, 0xCFEA, 0xB362, 0xCFEB, 0xB363, 0xCFEC, 0xB364, 0xCFED,
+	0xB365, 0xCFEE, 0xB366, 0xCFEF, 0xB367, 0xCFF2, 0xB368, 0xCFF4,
+	0xB369, 0xCFF6, 0xB36A, 0xCFF7, 0xB36B, 0xCFF8, 0xB36C, 0xCFF9,
+	0xB36D, 0xCFFA, 0xB36E, 0xCFFB, 0xB36F, 0xCFFD, 0xB370, 0xCFFE,
+	0xB371, 0xCFFF, 0xB372, 0xD001, 0xB373, 0xD002, 0xB374, 0xD003,
+	0xB375, 0xD005, 0xB376, 0xD006, 0xB377, 0xD007, 0xB378, 0xD008,
+	0xB379, 0xD009, 0xB37A, 0xD00A, 0xB381, 0xD00B, 0xB382, 0xD00C,
+	0xB383, 0xD00D, 0xB384, 0xD00E, 0xB385, 0xD00F, 0xB386, 0xD010,
+	0xB387, 0xD012, 0xB388, 0xD013, 0xB389, 0xD014, 0xB38A, 0xD015,
+	0xB38B, 0xD016, 0xB38C, 0xD017, 0xB38D, 0xD019, 0xB38E, 0xD01A,
+	0xB38F, 0xD01B, 0xB390, 0xD01C, 0xB391, 0xD01D, 0xB392, 0xD01E,
+	0xB393, 0xD01F, 0xB394, 0xD020, 0xB395, 0xD021, 0xB396, 0xD022,
+	0xB397, 0xD023, 0xB398, 0xD024, 0xB399, 0xD025, 0xB39A, 0xD026,
+	0xB39B, 0xD027, 0xB39C, 0xD028, 0xB39D, 0xD029, 0xB39E, 0xD02A,
+	0xB39F, 0xD02B, 0xB3A0, 0xD02C, 0xB3A1, 0xB05D, 0xB3A2, 0xB07C,
+	0xB3A3, 0xB07D, 0xB3A4, 0xB080, 0xB3A5, 0xB084, 0xB3A6, 0xB08C,
+	0xB3A7, 0xB08D, 0xB3A8, 0xB08F, 0xB3A9, 0xB091, 0xB3AA, 0xB098,
+	0xB3AB, 0xB099, 0xB3AC, 0xB09A, 0xB3AD, 0xB09C, 0xB3AE, 0xB09F,
+	0xB3AF, 0xB0A0, 0xB3B0, 0xB0A1, 0xB3B1, 0xB0A2, 0xB3B2, 0xB0A8,
+	0xB3B3, 0xB0A9, 0xB3B4, 0xB0AB, 0xB3B5, 0xB0AC, 0xB3B6, 0xB0AD,
+	0xB3B7, 0xB0AE, 0xB3B8, 0xB0AF, 0xB3B9, 0xB0B1, 0xB3BA, 0xB0B3,
+	0xB3BB, 0xB0B4, 0xB3BC, 0xB0B5, 0xB3BD, 0xB0B8, 0xB3BE, 0xB0BC,
+	0xB3BF, 0xB0C4, 0xB3C0, 0xB0C5, 0xB3C1, 0xB0C7, 0xB3C2, 0xB0C8,
+	0xB3C3, 0xB0C9, 0xB3C4, 0xB0D0, 0xB3C5, 0xB0D1, 0xB3C6, 0xB0D4,
+	0xB3C7, 0xB0D8, 0xB3C8, 0xB0E0, 0xB3C9, 0xB0E5, 0xB3CA, 0xB108,
+	0xB3CB, 0xB109, 0xB3CC, 0xB10B, 0xB3CD, 0xB10C, 0xB3CE, 0xB110,
+	0xB3CF, 0xB112, 0xB3D0, 0xB113, 0xB3D1, 0xB118, 0xB3D2, 0xB119,
+	0xB3D3, 0xB11B, 0xB3D4, 0xB11C, 0xB3D5, 0xB11D, 0xB3D6, 0xB123,
+	0xB3D7, 0xB124, 0xB3D8, 0xB125, 0xB3D9, 0xB128, 0xB3DA, 0xB12C,
+	0xB3DB, 0xB134, 0xB3DC, 0xB135, 0xB3DD, 0xB137, 0xB3DE, 0xB138,
+	0xB3DF, 0xB139, 0xB3E0, 0xB140, 0xB3E1, 0xB141, 0xB3E2, 0xB144,
+	0xB3E3, 0xB148, 0xB3E4, 0xB150, 0xB3E5, 0xB151, 0xB3E6, 0xB154,
+	0xB3E7, 0xB155, 0xB3E8, 0xB158, 0xB3E9, 0xB15C, 0xB3EA, 0xB160,
+	0xB3EB, 0xB178, 0xB3EC, 0xB179, 0xB3ED, 0xB17C, 0xB3EE, 0xB180,
+	0xB3EF, 0xB182, 0xB3F0, 0xB188, 0xB3F1, 0xB189, 0xB3F2, 0xB18B,
+	0xB3F3, 0xB18D, 0xB3F4, 0xB192, 0xB3F5, 0xB193, 0xB3F6, 0xB194,
+	0xB3F7, 0xB198, 0xB3F8, 0xB19C, 0xB3F9, 0xB1A8, 0xB3FA, 0xB1CC,
+	0xB3FB, 0xB1D0, 0xB3FC, 0xB1D4, 0xB3FD, 0xB1DC, 0xB3FE, 0xB1DD,
+	0xB441, 0xD02E, 0xB442, 0xD02F, 0xB443, 0xD030, 0xB444, 0xD031,
+	0xB445, 0xD032, 0xB446, 0xD033, 0xB447, 0xD036, 0xB448, 0xD037,
+	0xB449, 0xD039, 0xB44A, 0xD03A, 0xB44B, 0xD03B, 0xB44C, 0xD03D,
+	0xB44D, 0xD03E, 0xB44E, 0xD03F, 0xB44F, 0xD040, 0xB450, 0xD041,
+	0xB451, 0xD042, 0xB452, 0xD043, 0xB453, 0xD046, 0xB454, 0xD048,
+	0xB455, 0xD04A, 0xB456, 0xD04B, 0xB457, 0xD04C, 0xB458, 0xD04D,
+	0xB459, 0xD04E, 0xB45A, 0xD04F, 0xB461, 0xD051, 0xB462, 0xD052,
+	0xB463, 0xD053, 0xB464, 0xD055, 0xB465, 0xD056, 0xB466, 0xD057,
+	0xB467, 0xD059, 0xB468, 0xD05A, 0xB469, 0xD05B, 0xB46A, 0xD05C,
+	0xB46B, 0xD05D, 0xB46C, 0xD05E, 0xB46D, 0xD05F, 0xB46E, 0xD061,
+	0xB46F, 0xD062, 0xB470, 0xD063, 0xB471, 0xD064, 0xB472, 0xD065,
+	0xB473, 0xD066, 0xB474, 0xD067, 0xB475, 0xD068, 0xB476, 0xD069,
+	0xB477, 0xD06A, 0xB478, 0xD06B, 0xB479, 0xD06E, 0xB47A, 0xD06F,
+	0xB481, 0xD071, 0xB482, 0xD072, 0xB483, 0xD073, 0xB484, 0xD075,
+	0xB485, 0xD076, 0xB486, 0xD077, 0xB487, 0xD078, 0xB488, 0xD079,
+	0xB489, 0xD07A, 0xB48A, 0xD07B, 0xB48B, 0xD07E, 0xB48C, 0xD07F,
+	0xB48D, 0xD080, 0xB48E, 0xD082, 0xB48F, 0xD083, 0xB490, 0xD084,
+	0xB491, 0xD085, 0xB492, 0xD086, 0xB493, 0xD087, 0xB494, 0xD088,
+	0xB495, 0xD089, 0xB496, 0xD08A, 0xB497, 0xD08B, 0xB498, 0xD08C,
+	0xB499, 0xD08D, 0xB49A, 0xD08E, 0xB49B, 0xD08F, 0xB49C, 0xD090,
+	0xB49D, 0xD091, 0xB49E, 0xD092, 0xB49F, 0xD093, 0xB4A0, 0xD094,
+	0xB4A1, 0xB1DF, 0xB4A2, 0xB1E8, 0xB4A3, 0xB1E9, 0xB4A4, 0xB1EC,
+	0xB4A5, 0xB1F0, 0xB4A6, 0xB1F9, 0xB4A7, 0xB1FB, 0xB4A8, 0xB1FD,
+	0xB4A9, 0xB204, 0xB4AA, 0xB205, 0xB4AB, 0xB208, 0xB4AC, 0xB20B,
+	0xB4AD, 0xB20C, 0xB4AE, 0xB214, 0xB4AF, 0xB215, 0xB4B0, 0xB217,
+	0xB4B1, 0xB219, 0xB4B2, 0xB220, 0xB4B3, 0xB234, 0xB4B4, 0xB23C,
+	0xB4B5, 0xB258, 0xB4B6, 0xB25C, 0xB4B7, 0xB260, 0xB4B8, 0xB268,
+	0xB4B9, 0xB269, 0xB4BA, 0xB274, 0xB4BB, 0xB275, 0xB4BC, 0xB27C,
+	0xB4BD, 0xB284, 0xB4BE, 0xB285, 0xB4BF, 0xB289, 0xB4C0, 0xB290,
+	0xB4C1, 0xB291, 0xB4C2, 0xB294, 0xB4C3, 0xB298, 0xB4C4, 0xB299,
+	0xB4C5, 0xB29A, 0xB4C6, 0xB2A0, 0xB4C7, 0xB2A1, 0xB4C8, 0xB2A3,
+	0xB4C9, 0xB2A5, 0xB4CA, 0xB2A6, 0xB4CB, 0xB2AA, 0xB4CC, 0xB2AC,
+	0xB4CD, 0xB2B0, 0xB4CE, 0xB2B4, 0xB4CF, 0xB2C8, 0xB4D0, 0xB2C9,
+	0xB4D1, 0xB2CC, 0xB4D2, 0xB2D0, 0xB4D3, 0xB2D2, 0xB4D4, 0xB2D8,
+	0xB4D5, 0xB2D9, 0xB4D6, 0xB2DB, 0xB4D7, 0xB2DD, 0xB4D8, 0xB2E2,
+	0xB4D9, 0xB2E4, 0xB4DA, 0xB2E5, 0xB4DB, 0xB2E6, 0xB4DC, 0xB2E8,
+	0xB4DD, 0xB2EB, 0xB4DE, 0xB2EC, 0xB4DF, 0xB2ED, 0xB4E0, 0xB2EE,
+	0xB4E1, 0xB2EF, 0xB4E2, 0xB2F3, 0xB4E3, 0xB2F4, 0xB4E4, 0xB2F5,
+	0xB4E5, 0xB2F7, 0xB4E6, 0xB2F8, 0xB4E7, 0xB2F9, 0xB4E8, 0xB2FA,
+	0xB4E9, 0xB2FB, 0xB4EA, 0xB2FF, 0xB4EB, 0xB300, 0xB4EC, 0xB301,
+	0xB4ED, 0xB304, 0xB4EE, 0xB308, 0xB4EF, 0xB310, 0xB4F0, 0xB311,
+	0xB4F1, 0xB313, 0xB4F2, 0xB314, 0xB4F3, 0xB315, 0xB4F4, 0xB31C,
+	0xB4F5, 0xB354, 0xB4F6, 0xB355, 0xB4F7, 0xB356, 0xB4F8, 0xB358,
+	0xB4F9, 0xB35B, 0xB4FA, 0xB35C, 0xB4FB, 0xB35E, 0xB4FC, 0xB35F,
+	0xB4FD, 0xB364, 0xB4FE, 0xB365, 0xB541, 0xD095, 0xB542, 0xD096,
+	0xB543, 0xD097, 0xB544, 0xD098, 0xB545, 0xD099, 0xB546, 0xD09A,
+	0xB547, 0xD09B, 0xB548, 0xD09C, 0xB549, 0xD09D, 0xB54A, 0xD09E,
+	0xB54B, 0xD09F, 0xB54C, 0xD0A0, 0xB54D, 0xD0A1, 0xB54E, 0xD0A2,
+	0xB54F, 0xD0A3, 0xB550, 0xD0A6, 0xB551, 0xD0A7, 0xB552, 0xD0A9,
+	0xB553, 0xD0AA, 0xB554, 0xD0AB, 0xB555, 0xD0AD, 0xB556, 0xD0AE,
+	0xB557, 0xD0AF, 0xB558, 0xD0B0, 0xB559, 0xD0B1, 0xB55A, 0xD0B2,
+	0xB561, 0xD0B3, 0xB562, 0xD0B6, 0xB563, 0xD0B8, 0xB564, 0xD0BA,
+	0xB565, 0xD0BB, 0xB566, 0xD0BC, 0xB567, 0xD0BD, 0xB568, 0xD0BE,
+	0xB569, 0xD0BF, 0xB56A, 0xD0C2, 0xB56B, 0xD0C3, 0xB56C, 0xD0C5,
+	0xB56D, 0xD0C6, 0xB56E, 0xD0C7, 0xB56F, 0xD0CA, 0xB570, 0xD0CB,
+	0xB571, 0xD0CC, 0xB572, 0xD0CD, 0xB573, 0xD0CE, 0xB574, 0xD0CF,
+	0xB575, 0xD0D2, 0xB576, 0xD0D6, 0xB577, 0xD0D7, 0xB578, 0xD0D8,
+	0xB579, 0xD0D9, 0xB57A, 0xD0DA, 0xB581, 0xD0DB, 0xB582, 0xD0DE,
+	0xB583, 0xD0DF, 0xB584, 0xD0E1, 0xB585, 0xD0E2, 0xB586, 0xD0E3,
+	0xB587, 0xD0E5, 0xB588, 0xD0E6, 0xB589, 0xD0E7, 0xB58A, 0xD0E8,
+	0xB58B, 0xD0E9, 0xB58C, 0xD0EA, 0xB58D, 0xD0EB, 0xB58E, 0xD0EE,
+	0xB58F, 0xD0F2, 0xB590, 0xD0F3, 0xB591, 0xD0F4, 0xB592, 0xD0F5,
+	0xB593, 0xD0F6, 0xB594, 0xD0F7, 0xB595, 0xD0F9, 0xB596, 0xD0FA,
+	0xB597, 0xD0FB, 0xB598, 0xD0FC, 0xB599, 0xD0FD, 0xB59A, 0xD0FE,
+	0xB59B, 0xD0FF, 0xB59C, 0xD100, 0xB59D, 0xD101, 0xB59E, 0xD102,
+	0xB59F, 0xD103, 0xB5A0, 0xD104, 0xB5A1, 0xB367, 0xB5A2, 0xB369,
+	0xB5A3, 0xB36B, 0xB5A4, 0xB36E, 0xB5A5, 0xB370, 0xB5A6, 0xB371,
+	0xB5A7, 0xB374, 0xB5A8, 0xB378, 0xB5A9, 0xB380, 0xB5AA, 0xB381,
+	0xB5AB, 0xB383, 0xB5AC, 0xB384, 0xB5AD, 0xB385, 0xB5AE, 0xB38C,
+	0xB5AF, 0xB390, 0xB5B0, 0xB394, 0xB5B1, 0xB3A0, 0xB5B2, 0xB3A1,
+	0xB5B3, 0xB3A8, 0xB5B4, 0xB3AC, 0xB5B5, 0xB3C4, 0xB5B6, 0xB3C5,
+	0xB5B7, 0xB3C8, 0xB5B8, 0xB3CB, 0xB5B9, 0xB3CC, 0xB5BA, 0xB3CE,
+	0xB5BB, 0xB3D0, 0xB5BC, 0xB3D4, 0xB5BD, 0xB3D5, 0xB5BE, 0xB3D7,
+	0xB5BF, 0xB3D9, 0xB5C0, 0xB3DB, 0xB5C1, 0xB3DD, 0xB5C2, 0xB3E0,
+	0xB5C3, 0xB3E4, 0xB5C4, 0xB3E8, 0xB5C5, 0xB3FC, 0xB5C6, 0xB410,
+	0xB5C7, 0xB418, 0xB5C8, 0xB41C, 0xB5C9, 0xB420, 0xB5CA, 0xB428,
+	0xB5CB, 0xB429, 0xB5CC, 0xB42B, 0xB5CD, 0xB434, 0xB5CE, 0xB450,
+	0xB5CF, 0xB451, 0xB5D0, 0xB454, 0xB5D1, 0xB458, 0xB5D2, 0xB460,
+	0xB5D3, 0xB461, 0xB5D4, 0xB463, 0xB5D5, 0xB465, 0xB5D6, 0xB46C,
+	0xB5D7, 0xB480, 0xB5D8, 0xB488, 0xB5D9, 0xB49D, 0xB5DA, 0xB4A4,
+	0xB5DB, 0xB4A8, 0xB5DC, 0xB4AC, 0xB5DD, 0xB4B5, 0xB5DE, 0xB4B7,
+	0xB5DF, 0xB4B9, 0xB5E0, 0xB4C0, 0xB5E1, 0xB4C4, 0xB5E2, 0xB4C8,
+	0xB5E3, 0xB4D0, 0xB5E4, 0xB4D5, 0xB5E5, 0xB4DC, 0xB5E6, 0xB4DD,
+	0xB5E7, 0xB4E0, 0xB5E8, 0xB4E3, 0xB5E9, 0xB4E4, 0xB5EA, 0xB4E6,
+	0xB5EB, 0xB4EC, 0xB5EC, 0xB4ED, 0xB5ED, 0xB4EF, 0xB5EE, 0xB4F1,
+	0xB5EF, 0xB4F8, 0xB5F0, 0xB514, 0xB5F1, 0xB515, 0xB5F2, 0xB518,
+	0xB5F3, 0xB51B, 0xB5F4, 0xB51C, 0xB5F5, 0xB524, 0xB5F6, 0xB525,
+	0xB5F7, 0xB527, 0xB5F8, 0xB528, 0xB5F9, 0xB529, 0xB5FA, 0xB52A,
+	0xB5FB, 0xB530, 0xB5FC, 0xB531, 0xB5FD, 0xB534, 0xB5FE, 0xB538,
+	0xB641, 0xD105, 0xB642, 0xD106, 0xB643, 0xD107, 0xB644, 0xD108,
+	0xB645, 0xD109, 0xB646, 0xD10A, 0xB647, 0xD10B, 0xB648, 0xD10C,
+	0xB649, 0xD10E, 0xB64A, 0xD10F, 0xB64B, 0xD110, 0xB64C, 0xD111,
+	0xB64D, 0xD112, 0xB64E, 0xD113, 0xB64F, 0xD114, 0xB650, 0xD115,
+	0xB651, 0xD116, 0xB652, 0xD117, 0xB653, 0xD118, 0xB654, 0xD119,
+	0xB655, 0xD11A, 0xB656, 0xD11B, 0xB657, 0xD11C, 0xB658, 0xD11D,
+	0xB659, 0xD11E, 0xB65A, 0xD11F, 0xB661, 0xD120, 0xB662, 0xD121,
+	0xB663, 0xD122, 0xB664, 0xD123, 0xB665, 0xD124, 0xB666, 0xD125,
+	0xB667, 0xD126, 0xB668, 0xD127, 0xB669, 0xD128, 0xB66A, 0xD129,
+	0xB66B, 0xD12A, 0xB66C, 0xD12B, 0xB66D, 0xD12C, 0xB66E, 0xD12D,
+	0xB66F, 0xD12E, 0xB670, 0xD12F, 0xB671, 0xD132, 0xB672, 0xD133,
+	0xB673, 0xD135, 0xB674, 0xD136, 0xB675, 0xD137, 0xB676, 0xD139,
+	0xB677, 0xD13B, 0xB678, 0xD13C, 0xB679, 0xD13D, 0xB67A, 0xD13E,
+	0xB681, 0xD13F, 0xB682, 0xD142, 0xB683, 0xD146, 0xB684, 0xD147,
+	0xB685, 0xD148, 0xB686, 0xD149, 0xB687, 0xD14A, 0xB688, 0xD14B,
+	0xB689, 0xD14E, 0xB68A, 0xD14F, 0xB68B, 0xD151, 0xB68C, 0xD152,
+	0xB68D, 0xD153, 0xB68E, 0xD155, 0xB68F, 0xD156, 0xB690, 0xD157,
+	0xB691, 0xD158, 0xB692, 0xD159, 0xB693, 0xD15A, 0xB694, 0xD15B,
+	0xB695, 0xD15E, 0xB696, 0xD160, 0xB697, 0xD162, 0xB698, 0xD163,
+	0xB699, 0xD164, 0xB69A, 0xD165, 0xB69B, 0xD166, 0xB69C, 0xD167,
+	0xB69D, 0xD169, 0xB69E, 0xD16A, 0xB69F, 0xD16B, 0xB6A0, 0xD16D,
+	0xB6A1, 0xB540, 0xB6A2, 0xB541, 0xB6A3, 0xB543, 0xB6A4, 0xB544,
+	0xB6A5, 0xB545, 0xB6A6, 0xB54B, 0xB6A7, 0xB54C, 0xB6A8, 0xB54D,
+	0xB6A9, 0xB550, 0xB6AA, 0xB554, 0xB6AB, 0xB55C, 0xB6AC, 0xB55D,
+	0xB6AD, 0xB55F, 0xB6AE, 0xB560, 0xB6AF, 0xB561, 0xB6B0, 0xB5A0,
+	0xB6B1, 0xB5A1, 0xB6B2, 0xB5A4, 0xB6B3, 0xB5A8, 0xB6B4, 0xB5AA,
+	0xB6B5, 0xB5AB, 0xB6B6, 0xB5B0, 0xB6B7, 0xB5B1, 0xB6B8, 0xB5B3,
+	0xB6B9, 0xB5B4, 0xB6BA, 0xB5B5, 0xB6BB, 0xB5BB, 0xB6BC, 0xB5BC,
+	0xB6BD, 0xB5BD, 0xB6BE, 0xB5C0, 0xB6BF, 0xB5C4, 0xB6C0, 0xB5CC,
+	0xB6C1, 0xB5CD, 0xB6C2, 0xB5CF, 0xB6C3, 0xB5D0, 0xB6C4, 0xB5D1,
+	0xB6C5, 0xB5D8, 0xB6C6, 0xB5EC, 0xB6C7, 0xB610, 0xB6C8, 0xB611,
+	0xB6C9, 0xB614, 0xB6CA, 0xB618, 0xB6CB, 0xB625, 0xB6CC, 0xB62C,
+	0xB6CD, 0xB634, 0xB6CE, 0xB648, 0xB6CF, 0xB664, 0xB6D0, 0xB668,
+	0xB6D1, 0xB69C, 0xB6D2, 0xB69D, 0xB6D3, 0xB6A0, 0xB6D4, 0xB6A4,
+	0xB6D5, 0xB6AB, 0xB6D6, 0xB6AC, 0xB6D7, 0xB6B1, 0xB6D8, 0xB6D4,
+	0xB6D9, 0xB6F0, 0xB6DA, 0xB6F4, 0xB6DB, 0xB6F8, 0xB6DC, 0xB700,
+	0xB6DD, 0xB701, 0xB6DE, 0xB705, 0xB6DF, 0xB728, 0xB6E0, 0xB729,
+	0xB6E1, 0xB72C, 0xB6E2, 0xB72F, 0xB6E3, 0xB730, 0xB6E4, 0xB738,
+	0xB6E5, 0xB739, 0xB6E6, 0xB73B, 0xB6E7, 0xB744, 0xB6E8, 0xB748,
+	0xB6E9, 0xB74C, 0xB6EA, 0xB754, 0xB6EB, 0xB755, 0xB6EC, 0xB760,
+	0xB6ED, 0xB764, 0xB6EE, 0xB768, 0xB6EF, 0xB770, 0xB6F0, 0xB771,
+	0xB6F1, 0xB773, 0xB6F2, 0xB775, 0xB6F3, 0xB77C, 0xB6F4, 0xB77D,
+	0xB6F5, 0xB780, 0xB6F6, 0xB784, 0xB6F7, 0xB78C, 0xB6F8, 0xB78D,
+	0xB6F9, 0xB78F, 0xB6FA, 0xB790, 0xB6FB, 0xB791, 0xB6FC, 0xB792,
+	0xB6FD, 0xB796, 0xB6FE, 0xB797, 0xB741, 0xD16E, 0xB742, 0xD16F,
+	0xB743, 0xD170, 0xB744, 0xD171, 0xB745, 0xD172, 0xB746, 0xD173,
+	0xB747, 0xD174, 0xB748, 0xD175, 0xB749, 0xD176, 0xB74A, 0xD177,
+	0xB74B, 0xD178, 0xB74C, 0xD179, 0xB74D, 0xD17A, 0xB74E, 0xD17B,
+	0xB74F, 0xD17D, 0xB750, 0xD17E, 0xB751, 0xD17F, 0xB752, 0xD180,
+	0xB753, 0xD181, 0xB754, 0xD182, 0xB755, 0xD183, 0xB756, 0xD185,
+	0xB757, 0xD186, 0xB758, 0xD187, 0xB759, 0xD189, 0xB75A, 0xD18A,
+	0xB761, 0xD18B, 0xB762, 0xD18C, 0xB763, 0xD18D, 0xB764, 0xD18E,
+	0xB765, 0xD18F, 0xB766, 0xD190, 0xB767, 0xD191, 0xB768, 0xD192,
+	0xB769, 0xD193, 0xB76A, 0xD194, 0xB76B, 0xD195, 0xB76C, 0xD196,
+	0xB76D, 0xD197, 0xB76E, 0xD198, 0xB76F, 0xD199, 0xB770, 0xD19A,
+	0xB771, 0xD19B, 0xB772, 0xD19C, 0xB773, 0xD19D, 0xB774, 0xD19E,
+	0xB775, 0xD19F, 0xB776, 0xD1A2, 0xB777, 0xD1A3, 0xB778, 0xD1A5,
+	0xB779, 0xD1A6, 0xB77A, 0xD1A7, 0xB781, 0xD1A9, 0xB782, 0xD1AA,
+	0xB783, 0xD1AB, 0xB784, 0xD1AC, 0xB785, 0xD1AD, 0xB786, 0xD1AE,
+	0xB787, 0xD1AF, 0xB788, 0xD1B2, 0xB789, 0xD1B4, 0xB78A, 0xD1B6,
+	0xB78B, 0xD1B7, 0xB78C, 0xD1B8, 0xB78D, 0xD1B9, 0xB78E, 0xD1BB,
+	0xB78F, 0xD1BD, 0xB790, 0xD1BE, 0xB791, 0xD1BF, 0xB792, 0xD1C1,
+	0xB793, 0xD1C2, 0xB794, 0xD1C3, 0xB795, 0xD1C4, 0xB796, 0xD1C5,
+	0xB797, 0xD1C6, 0xB798, 0xD1C7, 0xB799, 0xD1C8, 0xB79A, 0xD1C9,
+	0xB79B, 0xD1CA, 0xB79C, 0xD1CB, 0xB79D, 0xD1CC, 0xB79E, 0xD1CD,
+	0xB79F, 0xD1CE, 0xB7A0, 0xD1CF, 0xB7A1, 0xB798, 0xB7A2, 0xB799,
+	0xB7A3, 0xB79C, 0xB7A4, 0xB7A0, 0xB7A5, 0xB7A8, 0xB7A6, 0xB7A9,
+	0xB7A7, 0xB7AB, 0xB7A8, 0xB7AC, 0xB7A9, 0xB7AD, 0xB7AA, 0xB7B4,
+	0xB7AB, 0xB7B5, 0xB7AC, 0xB7B8, 0xB7AD, 0xB7C7, 0xB7AE, 0xB7C9,
+	0xB7AF, 0xB7EC, 0xB7B0, 0xB7ED, 0xB7B1, 0xB7F0, 0xB7B2, 0xB7F4,
+	0xB7B3, 0xB7FC, 0xB7B4, 0xB7FD, 0xB7B5, 0xB7FF, 0xB7B6, 0xB800,
+	0xB7B7, 0xB801, 0xB7B8, 0xB807, 0xB7B9, 0xB808, 0xB7BA, 0xB809,
+	0xB7BB, 0xB80C, 0xB7BC, 0xB810, 0xB7BD, 0xB818, 0xB7BE, 0xB819,
+	0xB7BF, 0xB81B, 0xB7C0, 0xB81D, 0xB7C1, 0xB824, 0xB7C2, 0xB825,
+	0xB7C3, 0xB828, 0xB7C4, 0xB82C, 0xB7C5, 0xB834, 0xB7C6, 0xB835,
+	0xB7C7, 0xB837, 0xB7C8, 0xB838, 0xB7C9, 0xB839, 0xB7CA, 0xB840,
+	0xB7CB, 0xB844, 0xB7CC, 0xB851, 0xB7CD, 0xB853, 0xB7CE, 0xB85C,
+	0xB7CF, 0xB85D, 0xB7D0, 0xB860, 0xB7D1, 0xB864, 0xB7D2, 0xB86C,
+	0xB7D3, 0xB86D, 0xB7D4, 0xB86F, 0xB7D5, 0xB871, 0xB7D6, 0xB878,
+	0xB7D7, 0xB87C, 0xB7D8, 0xB88D, 0xB7D9, 0xB8A8, 0xB7DA, 0xB8B0,
+	0xB7DB, 0xB8B4, 0xB7DC, 0xB8B8, 0xB7DD, 0xB8C0, 0xB7DE, 0xB8C1,
+	0xB7DF, 0xB8C3, 0xB7E0, 0xB8C5, 0xB7E1, 0xB8CC, 0xB7E2, 0xB8D0,
+	0xB7E3, 0xB8D4, 0xB7E4, 0xB8DD, 0xB7E5, 0xB8DF, 0xB7E6, 0xB8E1,
+	0xB7E7, 0xB8E8, 0xB7E8, 0xB8E9, 0xB7E9, 0xB8EC, 0xB7EA, 0xB8F0,
+	0xB7EB, 0xB8F8, 0xB7EC, 0xB8F9, 0xB7ED, 0xB8FB, 0xB7EE, 0xB8FD,
+	0xB7EF, 0xB904, 0xB7F0, 0xB918, 0xB7F1, 0xB920, 0xB7F2, 0xB93C,
+	0xB7F3, 0xB93D, 0xB7F4, 0xB940, 0xB7F5, 0xB944, 0xB7F6, 0xB94C,
+	0xB7F7, 0xB94F, 0xB7F8, 0xB951, 0xB7F9, 0xB958, 0xB7FA, 0xB959,
+	0xB7FB, 0xB95C, 0xB7FC, 0xB960, 0xB7FD, 0xB968, 0xB7FE, 0xB969,
+	0xB841, 0xD1D0, 0xB842, 0xD1D1, 0xB843, 0xD1D2, 0xB844, 0xD1D3,
+	0xB845, 0xD1D4, 0xB846, 0xD1D5, 0xB847, 0xD1D6, 0xB848, 0xD1D7,
+	0xB849, 0xD1D9, 0xB84A, 0xD1DA, 0xB84B, 0xD1DB, 0xB84C, 0xD1DC,
+	0xB84D, 0xD1DD, 0xB84E, 0xD1DE, 0xB84F, 0xD1DF, 0xB850, 0xD1E0,
+	0xB851, 0xD1E1, 0xB852, 0xD1E2, 0xB853, 0xD1E3, 0xB854, 0xD1E4,
+	0xB855, 0xD1E5, 0xB856, 0xD1E6, 0xB857, 0xD1E7, 0xB858, 0xD1E8,
+	0xB859, 0xD1E9, 0xB85A, 0xD1EA, 0xB861, 0xD1EB, 0xB862, 0xD1EC,
+	0xB863, 0xD1ED, 0xB864, 0xD1EE, 0xB865, 0xD1EF, 0xB866, 0xD1F0,
+	0xB867, 0xD1F1, 0xB868, 0xD1F2, 0xB869, 0xD1F3, 0xB86A, 0xD1F5,
+	0xB86B, 0xD1F6, 0xB86C, 0xD1F7, 0xB86D, 0xD1F9, 0xB86E, 0xD1FA,
+	0xB86F, 0xD1FB, 0xB870, 0xD1FC, 0xB871, 0xD1FD, 0xB872, 0xD1FE,
+	0xB873, 0xD1FF, 0xB874, 0xD200, 0xB875, 0xD201, 0xB876, 0xD202,
+	0xB877, 0xD203, 0xB878, 0xD204, 0xB879, 0xD205, 0xB87A, 0xD206,
+	0xB881, 0xD208, 0xB882, 0xD20A, 0xB883, 0xD20B, 0xB884, 0xD20C,
+	0xB885, 0xD20D, 0xB886, 0xD20E, 0xB887, 0xD20F, 0xB888, 0xD211,
+	0xB889, 0xD212, 0xB88A, 0xD213, 0xB88B, 0xD214, 0xB88C, 0xD215,
+	0xB88D, 0xD216, 0xB88E, 0xD217, 0xB88F, 0xD218, 0xB890, 0xD219,
+	0xB891, 0xD21A, 0xB892, 0xD21B, 0xB893, 0xD21C, 0xB894, 0xD21D,
+	0xB895, 0xD21E, 0xB896, 0xD21F, 0xB897, 0xD220, 0xB898, 0xD221,
+	0xB899, 0xD222, 0xB89A, 0xD223, 0xB89B, 0xD224, 0xB89C, 0xD225,
+	0xB89D, 0xD226, 0xB89E, 0xD227, 0xB89F, 0xD228, 0xB8A0, 0xD229,
+	0xB8A1, 0xB96B, 0xB8A2, 0xB96D, 0xB8A3, 0xB974, 0xB8A4, 0xB975,
+	0xB8A5, 0xB978, 0xB8A6, 0xB97C, 0xB8A7, 0xB984, 0xB8A8, 0xB985,
+	0xB8A9, 0xB987, 0xB8AA, 0xB989, 0xB8AB, 0xB98A, 0xB8AC, 0xB98D,
+	0xB8AD, 0xB98E, 0xB8AE, 0xB9AC, 0xB8AF, 0xB9AD, 0xB8B0, 0xB9B0,
+	0xB8B1, 0xB9B4, 0xB8B2, 0xB9BC, 0xB8B3, 0xB9BD, 0xB8B4, 0xB9BF,
+	0xB8B5, 0xB9C1, 0xB8B6, 0xB9C8, 0xB8B7, 0xB9C9, 0xB8B8, 0xB9CC,
+	0xB8B9, 0xB9CE, 0xB8BA, 0xB9CF, 0xB8BB, 0xB9D0, 0xB8BC, 0xB9D1,
+	0xB8BD, 0xB9D2, 0xB8BE, 0xB9D8, 0xB8BF, 0xB9D9, 0xB8C0, 0xB9DB,
+	0xB8C1, 0xB9DD, 0xB8C2, 0xB9DE, 0xB8C3, 0xB9E1, 0xB8C4, 0xB9E3,
+	0xB8C5, 0xB9E4, 0xB8C6, 0xB9E5, 0xB8C7, 0xB9E8, 0xB8C8, 0xB9EC,
+	0xB8C9, 0xB9F4, 0xB8CA, 0xB9F5, 0xB8CB, 0xB9F7, 0xB8CC, 0xB9F8,
+	0xB8CD, 0xB9F9, 0xB8CE, 0xB9FA, 0xB8CF, 0xBA00, 0xB8D0, 0xBA01,
+	0xB8D1, 0xBA08, 0xB8D2, 0xBA15, 0xB8D3, 0xBA38, 0xB8D4, 0xBA39,
+	0xB8D5, 0xBA3C, 0xB8D6, 0xBA40, 0xB8D7, 0xBA42, 0xB8D8, 0xBA48,
+	0xB8D9, 0xBA49, 0xB8DA, 0xBA4B, 0xB8DB, 0xBA4D, 0xB8DC, 0xBA4E,
+	0xB8DD, 0xBA53, 0xB8DE, 0xBA54, 0xB8DF, 0xBA55, 0xB8E0, 0xBA58,
+	0xB8E1, 0xBA5C, 0xB8E2, 0xBA64, 0xB8E3, 0xBA65, 0xB8E4, 0xBA67,
+	0xB8E5, 0xBA68, 0xB8E6, 0xBA69, 0xB8E7, 0xBA70, 0xB8E8, 0xBA71,
+	0xB8E9, 0xBA74, 0xB8EA, 0xBA78, 0xB8EB, 0xBA83, 0xB8EC, 0xBA84,
+	0xB8ED, 0xBA85, 0xB8EE, 0xBA87, 0xB8EF, 0xBA8C, 0xB8F0, 0xBAA8,
+	0xB8F1, 0xBAA9, 0xB8F2, 0xBAAB, 0xB8F3, 0xBAAC, 0xB8F4, 0xBAB0,
+	0xB8F5, 0xBAB2, 0xB8F6, 0xBAB8, 0xB8F7, 0xBAB9, 0xB8F8, 0xBABB,
+	0xB8F9, 0xBABD, 0xB8FA, 0xBAC4, 0xB8FB, 0xBAC8, 0xB8FC, 0xBAD8,
+	0xB8FD, 0xBAD9, 0xB8FE, 0xBAFC, 0xB941, 0xD22A, 0xB942, 0xD22B,
+	0xB943, 0xD22E, 0xB944, 0xD22F, 0xB945, 0xD231, 0xB946, 0xD232,
+	0xB947, 0xD233, 0xB948, 0xD235, 0xB949, 0xD236, 0xB94A, 0xD237,
+	0xB94B, 0xD238, 0xB94C, 0xD239, 0xB94D, 0xD23A, 0xB94E, 0xD23B,
+	0xB94F, 0xD23E, 0xB950, 0xD240, 0xB951, 0xD242, 0xB952, 0xD243,
+	0xB953, 0xD244, 0xB954, 0xD245, 0xB955, 0xD246, 0xB956, 0xD247,
+	0xB957, 0xD249, 0xB958, 0xD24A, 0xB959, 0xD24B, 0xB95A, 0xD24C,
+	0xB961, 0xD24D, 0xB962, 0xD24E, 0xB963, 0xD24F, 0xB964, 0xD250,
+	0xB965, 0xD251, 0xB966, 0xD252, 0xB967, 0xD253, 0xB968, 0xD254,
+	0xB969, 0xD255, 0xB96A, 0xD256, 0xB96B, 0xD257, 0xB96C, 0xD258,
+	0xB96D, 0xD259, 0xB96E, 0xD25A, 0xB96F, 0xD25B, 0xB970, 0xD25D,
+	0xB971, 0xD25E, 0xB972, 0xD25F, 0xB973, 0xD260, 0xB974, 0xD261,
+	0xB975, 0xD262, 0xB976, 0xD263, 0xB977, 0xD265, 0xB978, 0xD266,
+	0xB979, 0xD267, 0xB97A, 0xD268, 0xB981, 0xD269, 0xB982, 0xD26A,
+	0xB983, 0xD26B, 0xB984, 0xD26C, 0xB985, 0xD26D, 0xB986, 0xD26E,
+	0xB987, 0xD26F, 0xB988, 0xD270, 0xB989, 0xD271, 0xB98A, 0xD272,
+	0xB98B, 0xD273, 0xB98C, 0xD274, 0xB98D, 0xD275, 0xB98E, 0xD276,
+	0xB98F, 0xD277, 0xB990, 0xD278, 0xB991, 0xD279, 0xB992, 0xD27A,
+	0xB993, 0xD27B, 0xB994, 0xD27C, 0xB995, 0xD27D, 0xB996, 0xD27E,
+	0xB997, 0xD27F, 0xB998, 0xD282, 0xB999, 0xD283, 0xB99A, 0xD285,
+	0xB99B, 0xD286, 0xB99C, 0xD287, 0xB99D, 0xD289, 0xB99E, 0xD28A,
+	0xB99F, 0xD28B, 0xB9A0, 0xD28C, 0xB9A1, 0xBB00, 0xB9A2, 0xBB04,
+	0xB9A3, 0xBB0D, 0xB9A4, 0xBB0F, 0xB9A5, 0xBB11, 0xB9A6, 0xBB18,
+	0xB9A7, 0xBB1C, 0xB9A8, 0xBB20, 0xB9A9, 0xBB29, 0xB9AA, 0xBB2B,
+	0xB9AB, 0xBB34, 0xB9AC, 0xBB35, 0xB9AD, 0xBB36, 0xB9AE, 0xBB38,
+	0xB9AF, 0xBB3B, 0xB9B0, 0xBB3C, 0xB9B1, 0xBB3D, 0xB9B2, 0xBB3E,
+	0xB9B3, 0xBB44, 0xB9B4, 0xBB45, 0xB9B5, 0xBB47, 0xB9B6, 0xBB49,
+	0xB9B7, 0xBB4D, 0xB9B8, 0xBB4F, 0xB9B9, 0xBB50, 0xB9BA, 0xBB54,
+	0xB9BB, 0xBB58, 0xB9BC, 0xBB61, 0xB9BD, 0xBB63, 0xB9BE, 0xBB6C,
+	0xB9BF, 0xBB88, 0xB9C0, 0xBB8C, 0xB9C1, 0xBB90, 0xB9C2, 0xBBA4,
+	0xB9C3, 0xBBA8, 0xB9C4, 0xBBAC, 0xB9C5, 0xBBB4, 0xB9C6, 0xBBB7,
+	0xB9C7, 0xBBC0, 0xB9C8, 0xBBC4, 0xB9C9, 0xBBC8, 0xB9CA, 0xBBD0,
+	0xB9CB, 0xBBD3, 0xB9CC, 0xBBF8, 0xB9CD, 0xBBF9, 0xB9CE, 0xBBFC,
+	0xB9CF, 0xBBFF, 0xB9D0, 0xBC00, 0xB9D1, 0xBC02, 0xB9D2, 0xBC08,
+	0xB9D3, 0xBC09, 0xB9D4, 0xBC0B, 0xB9D5, 0xBC0C, 0xB9D6, 0xBC0D,
+	0xB9D7, 0xBC0F, 0xB9D8, 0xBC11, 0xB9D9, 0xBC14, 0xB9DA, 0xBC15,
+	0xB9DB, 0xBC16, 0xB9DC, 0xBC17, 0xB9DD, 0xBC18, 0xB9DE, 0xBC1B,
+	0xB9DF, 0xBC1C, 0xB9E0, 0xBC1D, 0xB9E1, 0xBC1E, 0xB9E2, 0xBC1F,
+	0xB9E3, 0xBC24, 0xB9E4, 0xBC25, 0xB9E5, 0xBC27, 0xB9E6, 0xBC29,
+	0xB9E7, 0xBC2D, 0xB9E8, 0xBC30, 0xB9E9, 0xBC31, 0xB9EA, 0xBC34,
+	0xB9EB, 0xBC38, 0xB9EC, 0xBC40, 0xB9ED, 0xBC41, 0xB9EE, 0xBC43,
+	0xB9EF, 0xBC44, 0xB9F0, 0xBC45, 0xB9F1, 0xBC49, 0xB9F2, 0xBC4C,
+	0xB9F3, 0xBC4D, 0xB9F4, 0xBC50, 0xB9F5, 0xBC5D, 0xB9F6, 0xBC84,
+	0xB9F7, 0xBC85, 0xB9F8, 0xBC88, 0xB9F9, 0xBC8B, 0xB9FA, 0xBC8C,
+	0xB9FB, 0xBC8E, 0xB9FC, 0xBC94, 0xB9FD, 0xBC95, 0xB9FE, 0xBC97,
+	0xBA41, 0xD28D, 0xBA42, 0xD28E, 0xBA43, 0xD28F, 0xBA44, 0xD292,
+	0xBA45, 0xD293, 0xBA46, 0xD294, 0xBA47, 0xD296, 0xBA48, 0xD297,
+	0xBA49, 0xD298, 0xBA4A, 0xD299, 0xBA4B, 0xD29A, 0xBA4C, 0xD29B,
+	0xBA4D, 0xD29D, 0xBA4E, 0xD29E, 0xBA4F, 0xD29F, 0xBA50, 0xD2A1,
+	0xBA51, 0xD2A2, 0xBA52, 0xD2A3, 0xBA53, 0xD2A5, 0xBA54, 0xD2A6,
+	0xBA55, 0xD2A7, 0xBA56, 0xD2A8, 0xBA57, 0xD2A9, 0xBA58, 0xD2AA,
+	0xBA59, 0xD2AB, 0xBA5A, 0xD2AD, 0xBA61, 0xD2AE, 0xBA62, 0xD2AF,
+	0xBA63, 0xD2B0, 0xBA64, 0xD2B2, 0xBA65, 0xD2B3, 0xBA66, 0xD2B4,
+	0xBA67, 0xD2B5, 0xBA68, 0xD2B6, 0xBA69, 0xD2B7, 0xBA6A, 0xD2BA,
+	0xBA6B, 0xD2BB, 0xBA6C, 0xD2BD, 0xBA6D, 0xD2BE, 0xBA6E, 0xD2C1,
+	0xBA6F, 0xD2C3, 0xBA70, 0xD2C4, 0xBA71, 0xD2C5, 0xBA72, 0xD2C6,
+	0xBA73, 0xD2C7, 0xBA74, 0xD2CA, 0xBA75, 0xD2CC, 0xBA76, 0xD2CD,
+	0xBA77, 0xD2CE, 0xBA78, 0xD2CF, 0xBA79, 0xD2D0, 0xBA7A, 0xD2D1,
+	0xBA81, 0xD2D2, 0xBA82, 0xD2D3, 0xBA83, 0xD2D5, 0xBA84, 0xD2D6,
+	0xBA85, 0xD2D7, 0xBA86, 0xD2D9, 0xBA87, 0xD2DA, 0xBA88, 0xD2DB,
+	0xBA89, 0xD2DD, 0xBA8A, 0xD2DE, 0xBA8B, 0xD2DF, 0xBA8C, 0xD2E0,
+	0xBA8D, 0xD2E1, 0xBA8E, 0xD2E2, 0xBA8F, 0xD2E3, 0xBA90, 0xD2E6,
+	0xBA91, 0xD2E7, 0xBA92, 0xD2E8, 0xBA93, 0xD2E9, 0xBA94, 0xD2EA,
+	0xBA95, 0xD2EB, 0xBA96, 0xD2EC, 0xBA97, 0xD2ED, 0xBA98, 0xD2EE,
+	0xBA99, 0xD2EF, 0xBA9A, 0xD2F2, 0xBA9B, 0xD2F3, 0xBA9C, 0xD2F5,
+	0xBA9D, 0xD2F6, 0xBA9E, 0xD2F7, 0xBA9F, 0xD2F9, 0xBAA0, 0xD2FA,
+	0xBAA1, 0xBC99, 0xBAA2, 0xBC9A, 0xBAA3, 0xBCA0, 0xBAA4, 0xBCA1,
+	0xBAA5, 0xBCA4, 0xBAA6, 0xBCA7, 0xBAA7, 0xBCA8, 0xBAA8, 0xBCB0,
+	0xBAA9, 0xBCB1, 0xBAAA, 0xBCB3, 0xBAAB, 0xBCB4, 0xBAAC, 0xBCB5,
+	0xBAAD, 0xBCBC, 0xBAAE, 0xBCBD, 0xBAAF, 0xBCC0, 0xBAB0, 0xBCC4,
+	0xBAB1, 0xBCCD, 0xBAB2, 0xBCCF, 0xBAB3, 0xBCD0, 0xBAB4, 0xBCD1,
+	0xBAB5, 0xBCD5, 0xBAB6, 0xBCD8, 0xBAB7, 0xBCDC, 0xBAB8, 0xBCF4,
+	0xBAB9, 0xBCF5, 0xBABA, 0xBCF6, 0xBABB, 0xBCF8, 0xBABC, 0xBCFC,
+	0xBABD, 0xBD04, 0xBABE, 0xBD05, 0xBABF, 0xBD07, 0xBAC0, 0xBD09,
+	0xBAC1, 0xBD10, 0xBAC2, 0xBD14, 0xBAC3, 0xBD24, 0xBAC4, 0xBD2C,
+	0xBAC5, 0xBD40, 0xBAC6, 0xBD48, 0xBAC7, 0xBD49, 0xBAC8, 0xBD4C,
+	0xBAC9, 0xBD50, 0xBACA, 0xBD58, 0xBACB, 0xBD59, 0xBACC, 0xBD64,
+	0xBACD, 0xBD68, 0xBACE, 0xBD80, 0xBACF, 0xBD81, 0xBAD0, 0xBD84,
+	0xBAD1, 0xBD87, 0xBAD2, 0xBD88, 0xBAD3, 0xBD89, 0xBAD4, 0xBD8A,
+	0xBAD5, 0xBD90, 0xBAD6, 0xBD91, 0xBAD7, 0xBD93, 0xBAD8, 0xBD95,
+	0xBAD9, 0xBD99, 0xBADA, 0xBD9A, 0xBADB, 0xBD9C, 0xBADC, 0xBDA4,
+	0xBADD, 0xBDB0, 0xBADE, 0xBDB8, 0xBADF, 0xBDD4, 0xBAE0, 0xBDD5,
+	0xBAE1, 0xBDD8, 0xBAE2, 0xBDDC, 0xBAE3, 0xBDE9, 0xBAE4, 0xBDF0,
+	0xBAE5, 0xBDF4, 0xBAE6, 0xBDF8, 0xBAE7, 0xBE00, 0xBAE8, 0xBE03,
+	0xBAE9, 0xBE05, 0xBAEA, 0xBE0C, 0xBAEB, 0xBE0D, 0xBAEC, 0xBE10,
+	0xBAED, 0xBE14, 0xBAEE, 0xBE1C, 0xBAEF, 0xBE1D, 0xBAF0, 0xBE1F,
+	0xBAF1, 0xBE44, 0xBAF2, 0xBE45, 0xBAF3, 0xBE48, 0xBAF4, 0xBE4C,
+	0xBAF5, 0xBE4E, 0xBAF6, 0xBE54, 0xBAF7, 0xBE55, 0xBAF8, 0xBE57,
+	0xBAF9, 0xBE59, 0xBAFA, 0xBE5A, 0xBAFB, 0xBE5B, 0xBAFC, 0xBE60,
+	0xBAFD, 0xBE61, 0xBAFE, 0xBE64, 0xBB41, 0xD2FB, 0xBB42, 0xD2FC,
+	0xBB43, 0xD2FD, 0xBB44, 0xD2FE, 0xBB45, 0xD2FF, 0xBB46, 0xD302,
+	0xBB47, 0xD304, 0xBB48, 0xD306, 0xBB49, 0xD307, 0xBB4A, 0xD308,
+	0xBB4B, 0xD309, 0xBB4C, 0xD30A, 0xBB4D, 0xD30B, 0xBB4E, 0xD30F,
+	0xBB4F, 0xD311, 0xBB50, 0xD312, 0xBB51, 0xD313, 0xBB52, 0xD315,
+	0xBB53, 0xD317, 0xBB54, 0xD318, 0xBB55, 0xD319, 0xBB56, 0xD31A,
+	0xBB57, 0xD31B, 0xBB58, 0xD31E, 0xBB59, 0xD322, 0xBB5A, 0xD323,
+	0xBB61, 0xD324, 0xBB62, 0xD326, 0xBB63, 0xD327, 0xBB64, 0xD32A,
+	0xBB65, 0xD32B, 0xBB66, 0xD32D, 0xBB67, 0xD32E, 0xBB68, 0xD32F,
+	0xBB69, 0xD331, 0xBB6A, 0xD332, 0xBB6B, 0xD333, 0xBB6C, 0xD334,
+	0xBB6D, 0xD335, 0xBB6E, 0xD336, 0xBB6F, 0xD337, 0xBB70, 0xD33A,
+	0xBB71, 0xD33E, 0xBB72, 0xD33F, 0xBB73, 0xD340, 0xBB74, 0xD341,
+	0xBB75, 0xD342, 0xBB76, 0xD343, 0xBB77, 0xD346, 0xBB78, 0xD347,
+	0xBB79, 0xD348, 0xBB7A, 0xD349, 0xBB81, 0xD34A, 0xBB82, 0xD34B,
+	0xBB83, 0xD34C, 0xBB84, 0xD34D, 0xBB85, 0xD34E, 0xBB86, 0xD34F,
+	0xBB87, 0xD350, 0xBB88, 0xD351, 0xBB89, 0xD352, 0xBB8A, 0xD353,
+	0xBB8B, 0xD354, 0xBB8C, 0xD355, 0xBB8D, 0xD356, 0xBB8E, 0xD357,
+	0xBB8F, 0xD358, 0xBB90, 0xD359, 0xBB91, 0xD35A, 0xBB92, 0xD35B,
+	0xBB93, 0xD35C, 0xBB94, 0xD35D, 0xBB95, 0xD35E, 0xBB96, 0xD35F,
+	0xBB97, 0xD360, 0xBB98, 0xD361, 0xBB99, 0xD362, 0xBB9A, 0xD363,
+	0xBB9B, 0xD364, 0xBB9C, 0xD365, 0xBB9D, 0xD366, 0xBB9E, 0xD367,
+	0xBB9F, 0xD368, 0xBBA0, 0xD369, 0xBBA1, 0xBE68, 0xBBA2, 0xBE6A,
+	0xBBA3, 0xBE70, 0xBBA4, 0xBE71, 0xBBA5, 0xBE73, 0xBBA6, 0xBE74,
+	0xBBA7, 0xBE75, 0xBBA8, 0xBE7B, 0xBBA9, 0xBE7C, 0xBBAA, 0xBE7D,
+	0xBBAB, 0xBE80, 0xBBAC, 0xBE84, 0xBBAD, 0xBE8C, 0xBBAE, 0xBE8D,
+	0xBBAF, 0xBE8F, 0xBBB0, 0xBE90, 0xBBB1, 0xBE91, 0xBBB2, 0xBE98,
+	0xBBB3, 0xBE99, 0xBBB4, 0xBEA8, 0xBBB5, 0xBED0, 0xBBB6, 0xBED1,
+	0xBBB7, 0xBED4, 0xBBB8, 0xBED7, 0xBBB9, 0xBED8, 0xBBBA, 0xBEE0,
+	0xBBBB, 0xBEE3, 0xBBBC, 0xBEE4, 0xBBBD, 0xBEE5, 0xBBBE, 0xBEEC,
+	0xBBBF, 0xBF01, 0xBBC0, 0xBF08, 0xBBC1, 0xBF09, 0xBBC2, 0xBF18,
+	0xBBC3, 0xBF19, 0xBBC4, 0xBF1B, 0xBBC5, 0xBF1C, 0xBBC6, 0xBF1D,
+	0xBBC7, 0xBF40, 0xBBC8, 0xBF41, 0xBBC9, 0xBF44, 0xBBCA, 0xBF48,
+	0xBBCB, 0xBF50, 0xBBCC, 0xBF51, 0xBBCD, 0xBF55, 0xBBCE, 0xBF94,
+	0xBBCF, 0xBFB0, 0xBBD0, 0xBFC5, 0xBBD1, 0xBFCC, 0xBBD2, 0xBFCD,
+	0xBBD3, 0xBFD0, 0xBBD4, 0xBFD4, 0xBBD5, 0xBFDC, 0xBBD6, 0xBFDF,
+	0xBBD7, 0xBFE1, 0xBBD8, 0xC03C, 0xBBD9, 0xC051, 0xBBDA, 0xC058,
+	0xBBDB, 0xC05C, 0xBBDC, 0xC060, 0xBBDD, 0xC068, 0xBBDE, 0xC069,
+	0xBBDF, 0xC090, 0xBBE0, 0xC091, 0xBBE1, 0xC094, 0xBBE2, 0xC098,
+	0xBBE3, 0xC0A0, 0xBBE4, 0xC0A1, 0xBBE5, 0xC0A3, 0xBBE6, 0xC0A5,
+	0xBBE7, 0xC0AC, 0xBBE8, 0xC0AD, 0xBBE9, 0xC0AF, 0xBBEA, 0xC0B0,
+	0xBBEB, 0xC0B3, 0xBBEC, 0xC0B4, 0xBBED, 0xC0B5, 0xBBEE, 0xC0B6,
+	0xBBEF, 0xC0BC, 0xBBF0, 0xC0BD, 0xBBF1, 0xC0BF, 0xBBF2, 0xC0C0,
+	0xBBF3, 0xC0C1, 0xBBF4, 0xC0C5, 0xBBF5, 0xC0C8, 0xBBF6, 0xC0C9,
+	0xBBF7, 0xC0CC, 0xBBF8, 0xC0D0, 0xBBF9, 0xC0D8, 0xBBFA, 0xC0D9,
+	0xBBFB, 0xC0DB, 0xBBFC, 0xC0DC, 0xBBFD, 0xC0DD, 0xBBFE, 0xC0E4,
+	0xBC41, 0xD36A, 0xBC42, 0xD36B, 0xBC43, 0xD36C, 0xBC44, 0xD36D,
+	0xBC45, 0xD36E, 0xBC46, 0xD36F, 0xBC47, 0xD370, 0xBC48, 0xD371,
+	0xBC49, 0xD372, 0xBC4A, 0xD373, 0xBC4B, 0xD374, 0xBC4C, 0xD375,
+	0xBC4D, 0xD376, 0xBC4E, 0xD377, 0xBC4F, 0xD378, 0xBC50, 0xD379,
+	0xBC51, 0xD37A, 0xBC52, 0xD37B, 0xBC53, 0xD37E, 0xBC54, 0xD37F,
+	0xBC55, 0xD381, 0xBC56, 0xD382, 0xBC57, 0xD383, 0xBC58, 0xD385,
+	0xBC59, 0xD386, 0xBC5A, 0xD387, 0xBC61, 0xD388, 0xBC62, 0xD389,
+	0xBC63, 0xD38A, 0xBC64, 0xD38B, 0xBC65, 0xD38E, 0xBC66, 0xD392,
+	0xBC67, 0xD393, 0xBC68, 0xD394, 0xBC69, 0xD395, 0xBC6A, 0xD396,
+	0xBC6B, 0xD397, 0xBC6C, 0xD39A, 0xBC6D, 0xD39B, 0xBC6E, 0xD39D,
+	0xBC6F, 0xD39E, 0xBC70, 0xD39F, 0xBC71, 0xD3A1, 0xBC72, 0xD3A2,
+	0xBC73, 0xD3A3, 0xBC74, 0xD3A4, 0xBC75, 0xD3A5, 0xBC76, 0xD3A6,
+	0xBC77, 0xD3A7, 0xBC78, 0xD3AA, 0xBC79, 0xD3AC, 0xBC7A, 0xD3AE,
+	0xBC81, 0xD3AF, 0xBC82, 0xD3B0, 0xBC83, 0xD3B1, 0xBC84, 0xD3B2,
+	0xBC85, 0xD3B3, 0xBC86, 0xD3B5, 0xBC87, 0xD3B6, 0xBC88, 0xD3B7,
+	0xBC89, 0xD3B9, 0xBC8A, 0xD3BA, 0xBC8B, 0xD3BB, 0xBC8C, 0xD3BD,
+	0xBC8D, 0xD3BE, 0xBC8E, 0xD3BF, 0xBC8F, 0xD3C0, 0xBC90, 0xD3C1,
+	0xBC91, 0xD3C2, 0xBC92, 0xD3C3, 0xBC93, 0xD3C6, 0xBC94, 0xD3C7,
+	0xBC95, 0xD3CA, 0xBC96, 0xD3CB, 0xBC97, 0xD3CC, 0xBC98, 0xD3CD,
+	0xBC99, 0xD3CE, 0xBC9A, 0xD3CF, 0xBC9B, 0xD3D1, 0xBC9C, 0xD3D2,
+	0xBC9D, 0xD3D3, 0xBC9E, 0xD3D4, 0xBC9F, 0xD3D5, 0xBCA0, 0xD3D6,
+	0xBCA1, 0xC0E5, 0xBCA2, 0xC0E8, 0xBCA3, 0xC0EC, 0xBCA4, 0xC0F4,
+	0xBCA5, 0xC0F5, 0xBCA6, 0xC0F7, 0xBCA7, 0xC0F9, 0xBCA8, 0xC100,
+	0xBCA9, 0xC104, 0xBCAA, 0xC108, 0xBCAB, 0xC110, 0xBCAC, 0xC115,
+	0xBCAD, 0xC11C, 0xBCAE, 0xC11D, 0xBCAF, 0xC11E, 0xBCB0, 0xC11F,
+	0xBCB1, 0xC120, 0xBCB2, 0xC123, 0xBCB3, 0xC124, 0xBCB4, 0xC126,
+	0xBCB5, 0xC127, 0xBCB6, 0xC12C, 0xBCB7, 0xC12D, 0xBCB8, 0xC12F,
+	0xBCB9, 0xC130, 0xBCBA, 0xC131, 0xBCBB, 0xC136, 0xBCBC, 0xC138,
+	0xBCBD, 0xC139, 0xBCBE, 0xC13C, 0xBCBF, 0xC140, 0xBCC0, 0xC148,
+	0xBCC1, 0xC149, 0xBCC2, 0xC14B, 0xBCC3, 0xC14C, 0xBCC4, 0xC14D,
+	0xBCC5, 0xC154, 0xBCC6, 0xC155, 0xBCC7, 0xC158, 0xBCC8, 0xC15C,
+	0xBCC9, 0xC164, 0xBCCA, 0xC165, 0xBCCB, 0xC167, 0xBCCC, 0xC168,
+	0xBCCD, 0xC169, 0xBCCE, 0xC170, 0xBCCF, 0xC174, 0xBCD0, 0xC178,
+	0xBCD1, 0xC185, 0xBCD2, 0xC18C, 0xBCD3, 0xC18D, 0xBCD4, 0xC18E,
+	0xBCD5, 0xC190, 0xBCD6, 0xC194, 0xBCD7, 0xC196, 0xBCD8, 0xC19C,
+	0xBCD9, 0xC19D, 0xBCDA, 0xC19F, 0xBCDB, 0xC1A1, 0xBCDC, 0xC1A5,
+	0xBCDD, 0xC1A8, 0xBCDE, 0xC1A9, 0xBCDF, 0xC1AC, 0xBCE0, 0xC1B0,
+	0xBCE1, 0xC1BD, 0xBCE2, 0xC1C4, 0xBCE3, 0xC1C8, 0xBCE4, 0xC1CC,
+	0xBCE5, 0xC1D4, 0xBCE6, 0xC1D7, 0xBCE7, 0xC1D8, 0xBCE8, 0xC1E0,
+	0xBCE9, 0xC1E4, 0xBCEA, 0xC1E8, 0xBCEB, 0xC1F0, 0xBCEC, 0xC1F1,
+	0xBCED, 0xC1F3, 0xBCEE, 0xC1FC, 0xBCEF, 0xC1FD, 0xBCF0, 0xC200,
+	0xBCF1, 0xC204, 0xBCF2, 0xC20C, 0xBCF3, 0xC20D, 0xBCF4, 0xC20F,
+	0xBCF5, 0xC211, 0xBCF6, 0xC218, 0xBCF7, 0xC219, 0xBCF8, 0xC21C,
+	0xBCF9, 0xC21F, 0xBCFA, 0xC220, 0xBCFB, 0xC228, 0xBCFC, 0xC229,
+	0xBCFD, 0xC22B, 0xBCFE, 0xC22D, 0xBD41, 0xD3D7, 0xBD42, 0xD3D9,
+	0xBD43, 0xD3DA, 0xBD44, 0xD3DB, 0xBD45, 0xD3DC, 0xBD46, 0xD3DD,
+	0xBD47, 0xD3DE, 0xBD48, 0xD3DF, 0xBD49, 0xD3E0, 0xBD4A, 0xD3E2,
+	0xBD4B, 0xD3E4, 0xBD4C, 0xD3E5, 0xBD4D, 0xD3E6, 0xBD4E, 0xD3E7,
+	0xBD4F, 0xD3E8, 0xBD50, 0xD3E9, 0xBD51, 0xD3EA, 0xBD52, 0xD3EB,
+	0xBD53, 0xD3EE, 0xBD54, 0xD3EF, 0xBD55, 0xD3F1, 0xBD56, 0xD3F2,
+	0xBD57, 0xD3F3, 0xBD58, 0xD3F5, 0xBD59, 0xD3F6, 0xBD5A, 0xD3F7,
+	0xBD61, 0xD3F8, 0xBD62, 0xD3F9, 0xBD63, 0xD3FA, 0xBD64, 0xD3FB,
+	0xBD65, 0xD3FE, 0xBD66, 0xD400, 0xBD67, 0xD402, 0xBD68, 0xD403,
+	0xBD69, 0xD404, 0xBD6A, 0xD405, 0xBD6B, 0xD406, 0xBD6C, 0xD407,
+	0xBD6D, 0xD409, 0xBD6E, 0xD40A, 0xBD6F, 0xD40B, 0xBD70, 0xD40C,
+	0xBD71, 0xD40D, 0xBD72, 0xD40E, 0xBD73, 0xD40F, 0xBD74, 0xD410,
+	0xBD75, 0xD411, 0xBD76, 0xD412, 0xBD77, 0xD413, 0xBD78, 0xD414,
+	0xBD79, 0xD415, 0xBD7A, 0xD416, 0xBD81, 0xD417, 0xBD82, 0xD418,
+	0xBD83, 0xD419, 0xBD84, 0xD41A, 0xBD85, 0xD41B, 0xBD86, 0xD41C,
+	0xBD87, 0xD41E, 0xBD88, 0xD41F, 0xBD89, 0xD420, 0xBD8A, 0xD421,
+	0xBD8B, 0xD422, 0xBD8C, 0xD423, 0xBD8D, 0xD424, 0xBD8E, 0xD425,
+	0xBD8F, 0xD426, 0xBD90, 0xD427, 0xBD91, 0xD428, 0xBD92, 0xD429,
+	0xBD93, 0xD42A, 0xBD94, 0xD42B, 0xBD95, 0xD42C, 0xBD96, 0xD42D,
+	0xBD97, 0xD42E, 0xBD98, 0xD42F, 0xBD99, 0xD430, 0xBD9A, 0xD431,
+	0xBD9B, 0xD432, 0xBD9C, 0xD433, 0xBD9D, 0xD434, 0xBD9E, 0xD435,
+	0xBD9F, 0xD436, 0xBDA0, 0xD437, 0xBDA1, 0xC22F, 0xBDA2, 0xC231,
+	0xBDA3, 0xC232, 0xBDA4, 0xC234, 0xBDA5, 0xC248, 0xBDA6, 0xC250,
+	0xBDA7, 0xC251, 0xBDA8, 0xC254, 0xBDA9, 0xC258, 0xBDAA, 0xC260,
+	0xBDAB, 0xC265, 0xBDAC, 0xC26C, 0xBDAD, 0xC26D, 0xBDAE, 0xC270,
+	0xBDAF, 0xC274, 0xBDB0, 0xC27C, 0xBDB1, 0xC27D, 0xBDB2, 0xC27F,
+	0xBDB3, 0xC281, 0xBDB4, 0xC288, 0xBDB5, 0xC289, 0xBDB6, 0xC290,
+	0xBDB7, 0xC298, 0xBDB8, 0xC29B, 0xBDB9, 0xC29D, 0xBDBA, 0xC2A4,
+	0xBDBB, 0xC2A5, 0xBDBC, 0xC2A8, 0xBDBD, 0xC2AC, 0xBDBE, 0xC2AD,
+	0xBDBF, 0xC2B4, 0xBDC0, 0xC2B5, 0xBDC1, 0xC2B7, 0xBDC2, 0xC2B9,
+	0xBDC3, 0xC2DC, 0xBDC4, 0xC2DD, 0xBDC5, 0xC2E0, 0xBDC6, 0xC2E3,
+	0xBDC7, 0xC2E4, 0xBDC8, 0xC2EB, 0xBDC9, 0xC2EC, 0xBDCA, 0xC2ED,
+	0xBDCB, 0xC2EF, 0xBDCC, 0xC2F1, 0xBDCD, 0xC2F6, 0xBDCE, 0xC2F8,
+	0xBDCF, 0xC2F9, 0xBDD0, 0xC2FB, 0xBDD1, 0xC2FC, 0xBDD2, 0xC300,
+	0xBDD3, 0xC308, 0xBDD4, 0xC309, 0xBDD5, 0xC30C, 0xBDD6, 0xC30D,
+	0xBDD7, 0xC313, 0xBDD8, 0xC314, 0xBDD9, 0xC315, 0xBDDA, 0xC318,
+	0xBDDB, 0xC31C, 0xBDDC, 0xC324, 0xBDDD, 0xC325, 0xBDDE, 0xC328,
+	0xBDDF, 0xC329, 0xBDE0, 0xC345, 0xBDE1, 0xC368, 0xBDE2, 0xC369,
+	0xBDE3, 0xC36C, 0xBDE4, 0xC370, 0xBDE5, 0xC372, 0xBDE6, 0xC378,
+	0xBDE7, 0xC379, 0xBDE8, 0xC37C, 0xBDE9, 0xC37D, 0xBDEA, 0xC384,
+	0xBDEB, 0xC388, 0xBDEC, 0xC38C, 0xBDED, 0xC3C0, 0xBDEE, 0xC3D8,
+	0xBDEF, 0xC3D9, 0xBDF0, 0xC3DC, 0xBDF1, 0xC3DF, 0xBDF2, 0xC3E0,
+	0xBDF3, 0xC3E2, 0xBDF4, 0xC3E8, 0xBDF5, 0xC3E9, 0xBDF6, 0xC3ED,
+	0xBDF7, 0xC3F4, 0xBDF8, 0xC3F5, 0xBDF9, 0xC3F8, 0xBDFA, 0xC408,
+	0xBDFB, 0xC410, 0xBDFC, 0xC424, 0xBDFD, 0xC42C, 0xBDFE, 0xC430,
+	0xBE41, 0xD438, 0xBE42, 0xD439, 0xBE43, 0xD43A, 0xBE44, 0xD43B,
+	0xBE45, 0xD43C, 0xBE46, 0xD43D, 0xBE47, 0xD43E, 0xBE48, 0xD43F,
+	0xBE49, 0xD441, 0xBE4A, 0xD442, 0xBE4B, 0xD443, 0xBE4C, 0xD445,
+	0xBE4D, 0xD446, 0xBE4E, 0xD447, 0xBE4F, 0xD448, 0xBE50, 0xD449,
+	0xBE51, 0xD44A, 0xBE52, 0xD44B, 0xBE53, 0xD44C, 0xBE54, 0xD44D,
+	0xBE55, 0xD44E, 0xBE56, 0xD44F, 0xBE57, 0xD450, 0xBE58, 0xD451,
+	0xBE59, 0xD452, 0xBE5A, 0xD453, 0xBE61, 0xD454, 0xBE62, 0xD455,
+	0xBE63, 0xD456, 0xBE64, 0xD457, 0xBE65, 0xD458, 0xBE66, 0xD459,
+	0xBE67, 0xD45A, 0xBE68, 0xD45B, 0xBE69, 0xD45D, 0xBE6A, 0xD45E,
+	0xBE6B, 0xD45F, 0xBE6C, 0xD461, 0xBE6D, 0xD462, 0xBE6E, 0xD463,
+	0xBE6F, 0xD465, 0xBE70, 0xD466, 0xBE71, 0xD467, 0xBE72, 0xD468,
+	0xBE73, 0xD469, 0xBE74, 0xD46A, 0xBE75, 0xD46B, 0xBE76, 0xD46C,
+	0xBE77, 0xD46E, 0xBE78, 0xD470, 0xBE79, 0xD471, 0xBE7A, 0xD472,
+	0xBE81, 0xD473, 0xBE82, 0xD474, 0xBE83, 0xD475, 0xBE84, 0xD476,
+	0xBE85, 0xD477, 0xBE86, 0xD47A, 0xBE87, 0xD47B, 0xBE88, 0xD47D,
+	0xBE89, 0xD47E, 0xBE8A, 0xD481, 0xBE8B, 0xD483, 0xBE8C, 0xD484,
+	0xBE8D, 0xD485, 0xBE8E, 0xD486, 0xBE8F, 0xD487, 0xBE90, 0xD48A,
+	0xBE91, 0xD48C, 0xBE92, 0xD48E, 0xBE93, 0xD48F, 0xBE94, 0xD490,
+	0xBE95, 0xD491, 0xBE96, 0xD492, 0xBE97, 0xD493, 0xBE98, 0xD495,
+	0xBE99, 0xD496, 0xBE9A, 0xD497, 0xBE9B, 0xD498, 0xBE9C, 0xD499,
+	0xBE9D, 0xD49A, 0xBE9E, 0xD49B, 0xBE9F, 0xD49C, 0xBEA0, 0xD49D,
+	0xBEA1, 0xC434, 0xBEA2, 0xC43C, 0xBEA3, 0xC43D, 0xBEA4, 0xC448,
+	0xBEA5, 0xC464, 0xBEA6, 0xC465, 0xBEA7, 0xC468, 0xBEA8, 0xC46C,
+	0xBEA9, 0xC474, 0xBEAA, 0xC475, 0xBEAB, 0xC479, 0xBEAC, 0xC480,
+	0xBEAD, 0xC494, 0xBEAE, 0xC49C, 0xBEAF, 0xC4B8, 0xBEB0, 0xC4BC,
+	0xBEB1, 0xC4E9, 0xBEB2, 0xC4F0, 0xBEB3, 0xC4F1, 0xBEB4, 0xC4F4,
+	0xBEB5, 0xC4F8, 0xBEB6, 0xC4FA, 0xBEB7, 0xC4FF, 0xBEB8, 0xC500,
+	0xBEB9, 0xC501, 0xBEBA, 0xC50C, 0xBEBB, 0xC510, 0xBEBC, 0xC514,
+	0xBEBD, 0xC51C, 0xBEBE, 0xC528, 0xBEBF, 0xC529, 0xBEC0, 0xC52C,
+	0xBEC1, 0xC530, 0xBEC2, 0xC538, 0xBEC3, 0xC539, 0xBEC4, 0xC53B,
+	0xBEC5, 0xC53D, 0xBEC6, 0xC544, 0xBEC7, 0xC545, 0xBEC8, 0xC548,
+	0xBEC9, 0xC549, 0xBECA, 0xC54A, 0xBECB, 0xC54C, 0xBECC, 0xC54D,
+	0xBECD, 0xC54E, 0xBECE, 0xC553, 0xBECF, 0xC554, 0xBED0, 0xC555,
+	0xBED1, 0xC557, 0xBED2, 0xC558, 0xBED3, 0xC559, 0xBED4, 0xC55D,
+	0xBED5, 0xC55E, 0xBED6, 0xC560, 0xBED7, 0xC561, 0xBED8, 0xC564,
+	0xBED9, 0xC568, 0xBEDA, 0xC570, 0xBEDB, 0xC571, 0xBEDC, 0xC573,
+	0xBEDD, 0xC574, 0xBEDE, 0xC575, 0xBEDF, 0xC57C, 0xBEE0, 0xC57D,
+	0xBEE1, 0xC580, 0xBEE2, 0xC584, 0xBEE3, 0xC587, 0xBEE4, 0xC58C,
+	0xBEE5, 0xC58D, 0xBEE6, 0xC58F, 0xBEE7, 0xC591, 0xBEE8, 0xC595,
+	0xBEE9, 0xC597, 0xBEEA, 0xC598, 0xBEEB, 0xC59C, 0xBEEC, 0xC5A0,
+	0xBEED, 0xC5A9, 0xBEEE, 0xC5B4, 0xBEEF, 0xC5B5, 0xBEF0, 0xC5B8,
+	0xBEF1, 0xC5B9, 0xBEF2, 0xC5BB, 0xBEF3, 0xC5BC, 0xBEF4, 0xC5BD,
+	0xBEF5, 0xC5BE, 0xBEF6, 0xC5C4, 0xBEF7, 0xC5C5, 0xBEF8, 0xC5C6,
+	0xBEF9, 0xC5C7, 0xBEFA, 0xC5C8, 0xBEFB, 0xC5C9, 0xBEFC, 0xC5CA,
+	0xBEFD, 0xC5CC, 0xBEFE, 0xC5CE, 0xBF41, 0xD49E, 0xBF42, 0xD49F,
+	0xBF43, 0xD4A0, 0xBF44, 0xD4A1, 0xBF45, 0xD4A2, 0xBF46, 0xD4A3,
+	0xBF47, 0xD4A4, 0xBF48, 0xD4A5, 0xBF49, 0xD4A6, 0xBF4A, 0xD4A7,
+	0xBF4B, 0xD4A8, 0xBF4C, 0xD4AA, 0xBF4D, 0xD4AB, 0xBF4E, 0xD4AC,
+	0xBF4F, 0xD4AD, 0xBF50, 0xD4AE, 0xBF51, 0xD4AF, 0xBF52, 0xD4B0,
+	0xBF53, 0xD4B1, 0xBF54, 0xD4B2, 0xBF55, 0xD4B3, 0xBF56, 0xD4B4,
+	0xBF57, 0xD4B5, 0xBF58, 0xD4B6, 0xBF59, 0xD4B7, 0xBF5A, 0xD4B8,
+	0xBF61, 0xD4B9, 0xBF62, 0xD4BA, 0xBF63, 0xD4BB, 0xBF64, 0xD4BC,
+	0xBF65, 0xD4BD, 0xBF66, 0xD4BE, 0xBF67, 0xD4BF, 0xBF68, 0xD4C0,
+	0xBF69, 0xD4C1, 0xBF6A, 0xD4C2, 0xBF6B, 0xD4C3, 0xBF6C, 0xD4C4,
+	0xBF6D, 0xD4C5, 0xBF6E, 0xD4C6, 0xBF6F, 0xD4C7, 0xBF70, 0xD4C8,
+	0xBF71, 0xD4C9, 0xBF72, 0xD4CA, 0xBF73, 0xD4CB, 0xBF74, 0xD4CD,
+	0xBF75, 0xD4CE, 0xBF76, 0xD4CF, 0xBF77, 0xD4D1, 0xBF78, 0xD4D2,
+	0xBF79, 0xD4D3, 0xBF7A, 0xD4D5, 0xBF81, 0xD4D6, 0xBF82, 0xD4D7,
+	0xBF83, 0xD4D8, 0xBF84, 0xD4D9, 0xBF85, 0xD4DA, 0xBF86, 0xD4DB,
+	0xBF87, 0xD4DD, 0xBF88, 0xD4DE, 0xBF89, 0xD4E0, 0xBF8A, 0xD4E1,
+	0xBF8B, 0xD4E2, 0xBF8C, 0xD4E3, 0xBF8D, 0xD4E4, 0xBF8E, 0xD4E5,
+	0xBF8F, 0xD4E6, 0xBF90, 0xD4E7, 0xBF91, 0xD4E9, 0xBF92, 0xD4EA,
+	0xBF93, 0xD4EB, 0xBF94, 0xD4ED, 0xBF95, 0xD4EE, 0xBF96, 0xD4EF,
+	0xBF97, 0xD4F1, 0xBF98, 0xD4F2, 0xBF99, 0xD4F3, 0xBF9A, 0xD4F4,
+	0xBF9B, 0xD4F5, 0xBF9C, 0xD4F6, 0xBF9D, 0xD4F7, 0xBF9E, 0xD4F9,
+	0xBF9F, 0xD4FA, 0xBFA0, 0xD4FC, 0xBFA1, 0xC5D0, 0xBFA2, 0xC5D1,
+	0xBFA3, 0xC5D4, 0xBFA4, 0xC5D8, 0xBFA5, 0xC5E0, 0xBFA6, 0xC5E1,
+	0xBFA7, 0xC5E3, 0xBFA8, 0xC5E5, 0xBFA9, 0xC5EC, 0xBFAA, 0xC5ED,
+	0xBFAB, 0xC5EE, 0xBFAC, 0xC5F0, 0xBFAD, 0xC5F4, 0xBFAE, 0xC5F6,
+	0xBFAF, 0xC5F7, 0xBFB0, 0xC5FC, 0xBFB1, 0xC5FD, 0xBFB2, 0xC5FE,
+	0xBFB3, 0xC5FF, 0xBFB4, 0xC600, 0xBFB5, 0xC601, 0xBFB6, 0xC605,
+	0xBFB7, 0xC606, 0xBFB8, 0xC607, 0xBFB9, 0xC608, 0xBFBA, 0xC60C,
+	0xBFBB, 0xC610, 0xBFBC, 0xC618, 0xBFBD, 0xC619, 0xBFBE, 0xC61B,
+	0xBFBF, 0xC61C, 0xBFC0, 0xC624, 0xBFC1, 0xC625, 0xBFC2, 0xC628,
+	0xBFC3, 0xC62C, 0xBFC4, 0xC62D, 0xBFC5, 0xC62E, 0xBFC6, 0xC630,
+	0xBFC7, 0xC633, 0xBFC8, 0xC634, 0xBFC9, 0xC635, 0xBFCA, 0xC637,
+	0xBFCB, 0xC639, 0xBFCC, 0xC63B, 0xBFCD, 0xC640, 0xBFCE, 0xC641,
+	0xBFCF, 0xC644, 0xBFD0, 0xC648, 0xBFD1, 0xC650, 0xBFD2, 0xC651,
+	0xBFD3, 0xC653, 0xBFD4, 0xC654, 0xBFD5, 0xC655, 0xBFD6, 0xC65C,
+	0xBFD7, 0xC65D, 0xBFD8, 0xC660, 0xBFD9, 0xC66C, 0xBFDA, 0xC66F,
+	0xBFDB, 0xC671, 0xBFDC, 0xC678, 0xBFDD, 0xC679, 0xBFDE, 0xC67C,
+	0xBFDF, 0xC680, 0xBFE0, 0xC688, 0xBFE1, 0xC689, 0xBFE2, 0xC68B,
+	0xBFE3, 0xC68D, 0xBFE4, 0xC694, 0xBFE5, 0xC695, 0xBFE6, 0xC698,
+	0xBFE7, 0xC69C, 0xBFE8, 0xC6A4, 0xBFE9, 0xC6A5, 0xBFEA, 0xC6A7,
+	0xBFEB, 0xC6A9, 0xBFEC, 0xC6B0, 0xBFED, 0xC6B1, 0xBFEE, 0xC6B4,
+	0xBFEF, 0xC6B8, 0xBFF0, 0xC6B9, 0xBFF1, 0xC6BA, 0xBFF2, 0xC6C0,
+	0xBFF3, 0xC6C1, 0xBFF4, 0xC6C3, 0xBFF5, 0xC6C5, 0xBFF6, 0xC6CC,
+	0xBFF7, 0xC6CD, 0xBFF8, 0xC6D0, 0xBFF9, 0xC6D4, 0xBFFA, 0xC6DC,
+	0xBFFB, 0xC6DD, 0xBFFC, 0xC6E0, 0xBFFD, 0xC6E1, 0xBFFE, 0xC6E8,
+	0xC041, 0xD4FE, 0xC042, 0xD4FF, 0xC043, 0xD500, 0xC044, 0xD501,
+	0xC045, 0xD502, 0xC046, 0xD503, 0xC047, 0xD505, 0xC048, 0xD506,
+	0xC049, 0xD507, 0xC04A, 0xD509, 0xC04B, 0xD50A, 0xC04C, 0xD50B,
+	0xC04D, 0xD50D, 0xC04E, 0xD50E, 0xC04F, 0xD50F, 0xC050, 0xD510,
+	0xC051, 0xD511, 0xC052, 0xD512, 0xC053, 0xD513, 0xC054, 0xD516,
+	0xC055, 0xD518, 0xC056, 0xD519, 0xC057, 0xD51A, 0xC058, 0xD51B,
+	0xC059, 0xD51C, 0xC05A, 0xD51D, 0xC061, 0xD51E, 0xC062, 0xD51F,
+	0xC063, 0xD520, 0xC064, 0xD521, 0xC065, 0xD522, 0xC066, 0xD523,
+	0xC067, 0xD524, 0xC068, 0xD525, 0xC069, 0xD526, 0xC06A, 0xD527,
+	0xC06B, 0xD528, 0xC06C, 0xD529, 0xC06D, 0xD52A, 0xC06E, 0xD52B,
+	0xC06F, 0xD52C, 0xC070, 0xD52D, 0xC071, 0xD52E, 0xC072, 0xD52F,
+	0xC073, 0xD530, 0xC074, 0xD531, 0xC075, 0xD532, 0xC076, 0xD533,
+	0xC077, 0xD534, 0xC078, 0xD535, 0xC079, 0xD536, 0xC07A, 0xD537,
+	0xC081, 0xD538, 0xC082, 0xD539, 0xC083, 0xD53A, 0xC084, 0xD53B,
+	0xC085, 0xD53E, 0xC086, 0xD53F, 0xC087, 0xD541, 0xC088, 0xD542,
+	0xC089, 0xD543, 0xC08A, 0xD545, 0xC08B, 0xD546, 0xC08C, 0xD547,
+	0xC08D, 0xD548, 0xC08E, 0xD549, 0xC08F, 0xD54A, 0xC090, 0xD54B,
+	0xC091, 0xD54E, 0xC092, 0xD550, 0xC093, 0xD552, 0xC094, 0xD553,
+	0xC095, 0xD554, 0xC096, 0xD555, 0xC097, 0xD556, 0xC098, 0xD557,
+	0xC099, 0xD55A, 0xC09A, 0xD55B, 0xC09B, 0xD55D, 0xC09C, 0xD55E,
+	0xC09D, 0xD55F, 0xC09E, 0xD561, 0xC09F, 0xD562, 0xC0A0, 0xD563,
+	0xC0A1, 0xC6E9, 0xC0A2, 0xC6EC, 0xC0A3, 0xC6F0, 0xC0A4, 0xC6F8,
+	0xC0A5, 0xC6F9, 0xC0A6, 0xC6FD, 0xC0A7, 0xC704, 0xC0A8, 0xC705,
+	0xC0A9, 0xC708, 0xC0AA, 0xC70C, 0xC0AB, 0xC714, 0xC0AC, 0xC715,
+	0xC0AD, 0xC717, 0xC0AE, 0xC719, 0xC0AF, 0xC720, 0xC0B0, 0xC721,
+	0xC0B1, 0xC724, 0xC0B2, 0xC728, 0xC0B3, 0xC730, 0xC0B4, 0xC731,
+	0xC0B5, 0xC733, 0xC0B6, 0xC735, 0xC0B7, 0xC737, 0xC0B8, 0xC73C,
+	0xC0B9, 0xC73D, 0xC0BA, 0xC740, 0xC0BB, 0xC744, 0xC0BC, 0xC74A,
+	0xC0BD, 0xC74C, 0xC0BE, 0xC74D, 0xC0BF, 0xC74F, 0xC0C0, 0xC751,
+	0xC0C1, 0xC752, 0xC0C2, 0xC753, 0xC0C3, 0xC754, 0xC0C4, 0xC755,
+	0xC0C5, 0xC756, 0xC0C6, 0xC757, 0xC0C7, 0xC758, 0xC0C8, 0xC75C,
+	0xC0C9, 0xC760, 0xC0CA, 0xC768, 0xC0CB, 0xC76B, 0xC0CC, 0xC774,
+	0xC0CD, 0xC775, 0xC0CE, 0xC778, 0xC0CF, 0xC77C, 0xC0D0, 0xC77D,
+	0xC0D1, 0xC77E, 0xC0D2, 0xC783, 0xC0D3, 0xC784, 0xC0D4, 0xC785,
+	0xC0D5, 0xC787, 0xC0D6, 0xC788, 0xC0D7, 0xC789, 0xC0D8, 0xC78A,
+	0xC0D9, 0xC78E, 0xC0DA, 0xC790, 0xC0DB, 0xC791, 0xC0DC, 0xC794,
+	0xC0DD, 0xC796, 0xC0DE, 0xC797, 0xC0DF, 0xC798, 0xC0E0, 0xC79A,
+	0xC0E1, 0xC7A0, 0xC0E2, 0xC7A1, 0xC0E3, 0xC7A3, 0xC0E4, 0xC7A4,
+	0xC0E5, 0xC7A5, 0xC0E6, 0xC7A6, 0xC0E7, 0xC7AC, 0xC0E8, 0xC7AD,
+	0xC0E9, 0xC7B0, 0xC0EA, 0xC7B4, 0xC0EB, 0xC7BC, 0xC0EC, 0xC7BD,
+	0xC0ED, 0xC7BF, 0xC0EE, 0xC7C0, 0xC0EF, 0xC7C1, 0xC0F0, 0xC7C8,
+	0xC0F1, 0xC7C9, 0xC0F2, 0xC7CC, 0xC0F3, 0xC7CE, 0xC0F4, 0xC7D0,
+	0xC0F5, 0xC7D8, 0xC0F6, 0xC7DD, 0xC0F7, 0xC7E4, 0xC0F8, 0xC7E8,
+	0xC0F9, 0xC7EC, 0xC0FA, 0xC800, 0xC0FB, 0xC801, 0xC0FC, 0xC804,
+	0xC0FD, 0xC808, 0xC0FE, 0xC80A, 0xC141, 0xD564, 0xC142, 0xD566,
+	0xC143, 0xD567, 0xC144, 0xD56A, 0xC145, 0xD56C, 0xC146, 0xD56E,
+	0xC147, 0xD56F, 0xC148, 0xD570, 0xC149, 0xD571, 0xC14A, 0xD572,
+	0xC14B, 0xD573, 0xC14C, 0xD576, 0xC14D, 0xD577, 0xC14E, 0xD579,
+	0xC14F, 0xD57A, 0xC150, 0xD57B, 0xC151, 0xD57D, 0xC152, 0xD57E,
+	0xC153, 0xD57F, 0xC154, 0xD580, 0xC155, 0xD581, 0xC156, 0xD582,
+	0xC157, 0xD583, 0xC158, 0xD586, 0xC159, 0xD58A, 0xC15A, 0xD58B,
+	0xC161, 0xD58C, 0xC162, 0xD58D, 0xC163, 0xD58E, 0xC164, 0xD58F,
+	0xC165, 0xD591, 0xC166, 0xD592, 0xC167, 0xD593, 0xC168, 0xD594,
+	0xC169, 0xD595, 0xC16A, 0xD596, 0xC16B, 0xD597, 0xC16C, 0xD598,
+	0xC16D, 0xD599, 0xC16E, 0xD59A, 0xC16F, 0xD59B, 0xC170, 0xD59C,
+	0xC171, 0xD59D, 0xC172, 0xD59E, 0xC173, 0xD59F, 0xC174, 0xD5A0,
+	0xC175, 0xD5A1, 0xC176, 0xD5A2, 0xC177, 0xD5A3, 0xC178, 0xD5A4,
+	0xC179, 0xD5A6, 0xC17A, 0xD5A7, 0xC181, 0xD5A8, 0xC182, 0xD5A9,
+	0xC183, 0xD5AA, 0xC184, 0xD5AB, 0xC185, 0xD5AC, 0xC186, 0xD5AD,
+	0xC187, 0xD5AE, 0xC188, 0xD5AF, 0xC189, 0xD5B0, 0xC18A, 0xD5B1,
+	0xC18B, 0xD5B2, 0xC18C, 0xD5B3, 0xC18D, 0xD5B4, 0xC18E, 0xD5B5,
+	0xC18F, 0xD5B6, 0xC190, 0xD5B7, 0xC191, 0xD5B8, 0xC192, 0xD5B9,
+	0xC193, 0xD5BA, 0xC194, 0xD5BB, 0xC195, 0xD5BC, 0xC196, 0xD5BD,
+	0xC197, 0xD5BE, 0xC198, 0xD5BF, 0xC199, 0xD5C0, 0xC19A, 0xD5C1,
+	0xC19B, 0xD5C2, 0xC19C, 0xD5C3, 0xC19D, 0xD5C4, 0xC19E, 0xD5C5,
+	0xC19F, 0xD5C6, 0xC1A0, 0xD5C7, 0xC1A1, 0xC810, 0xC1A2, 0xC811,
+	0xC1A3, 0xC813, 0xC1A4, 0xC815, 0xC1A5, 0xC816, 0xC1A6, 0xC81C,
+	0xC1A7, 0xC81D, 0xC1A8, 0xC820, 0xC1A9, 0xC824, 0xC1AA, 0xC82C,
+	0xC1AB, 0xC82D, 0xC1AC, 0xC82F, 0xC1AD, 0xC831, 0xC1AE, 0xC838,
+	0xC1AF, 0xC83C, 0xC1B0, 0xC840, 0xC1B1, 0xC848, 0xC1B2, 0xC849,
+	0xC1B3, 0xC84C, 0xC1B4, 0xC84D, 0xC1B5, 0xC854, 0xC1B6, 0xC870,
+	0xC1B7, 0xC871, 0xC1B8, 0xC874, 0xC1B9, 0xC878, 0xC1BA, 0xC87A,
+	0xC1BB, 0xC880, 0xC1BC, 0xC881, 0xC1BD, 0xC883, 0xC1BE, 0xC885,
+	0xC1BF, 0xC886, 0xC1C0, 0xC887, 0xC1C1, 0xC88B, 0xC1C2, 0xC88C,
+	0xC1C3, 0xC88D, 0xC1C4, 0xC894, 0xC1C5, 0xC89D, 0xC1C6, 0xC89F,
+	0xC1C7, 0xC8A1, 0xC1C8, 0xC8A8, 0xC1C9, 0xC8BC, 0xC1CA, 0xC8BD,
+	0xC1CB, 0xC8C4, 0xC1CC, 0xC8C8, 0xC1CD, 0xC8CC, 0xC1CE, 0xC8D4,
+	0xC1CF, 0xC8D5, 0xC1D0, 0xC8D7, 0xC1D1, 0xC8D9, 0xC1D2, 0xC8E0,
+	0xC1D3, 0xC8E1, 0xC1D4, 0xC8E4, 0xC1D5, 0xC8F5, 0xC1D6, 0xC8FC,
+	0xC1D7, 0xC8FD, 0xC1D8, 0xC900, 0xC1D9, 0xC904, 0xC1DA, 0xC905,
+	0xC1DB, 0xC906, 0xC1DC, 0xC90C, 0xC1DD, 0xC90D, 0xC1DE, 0xC90F,
+	0xC1DF, 0xC911, 0xC1E0, 0xC918, 0xC1E1, 0xC92C, 0xC1E2, 0xC934,
+	0xC1E3, 0xC950, 0xC1E4, 0xC951, 0xC1E5, 0xC954, 0xC1E6, 0xC958,
+	0xC1E7, 0xC960, 0xC1E8, 0xC961, 0xC1E9, 0xC963, 0xC1EA, 0xC96C,
+	0xC1EB, 0xC970, 0xC1EC, 0xC974, 0xC1ED, 0xC97C, 0xC1EE, 0xC988,
+	0xC1EF, 0xC989, 0xC1F0, 0xC98C, 0xC1F1, 0xC990, 0xC1F2, 0xC998,
+	0xC1F3, 0xC999, 0xC1F4, 0xC99B, 0xC1F5, 0xC99D, 0xC1F6, 0xC9C0,
+	0xC1F7, 0xC9C1, 0xC1F8, 0xC9C4, 0xC1F9, 0xC9C7, 0xC1FA, 0xC9C8,
+	0xC1FB, 0xC9CA, 0xC1FC, 0xC9D0, 0xC1FD, 0xC9D1, 0xC1FE, 0xC9D3,
+	0xC241, 0xD5CA, 0xC242, 0xD5CB, 0xC243, 0xD5CD, 0xC244, 0xD5CE,
+	0xC245, 0xD5CF, 0xC246, 0xD5D1, 0xC247, 0xD5D3, 0xC248, 0xD5D4,
+	0xC249, 0xD5D5, 0xC24A, 0xD5D6, 0xC24B, 0xD5D7, 0xC24C, 0xD5DA,
+	0xC24D, 0xD5DC, 0xC24E, 0xD5DE, 0xC24F, 0xD5DF, 0xC250, 0xD5E0,
+	0xC251, 0xD5E1, 0xC252, 0xD5E2, 0xC253, 0xD5E3, 0xC254, 0xD5E6,
+	0xC255, 0xD5E7, 0xC256, 0xD5E9, 0xC257, 0xD5EA, 0xC258, 0xD5EB,
+	0xC259, 0xD5ED, 0xC25A, 0xD5EE, 0xC261, 0xD5EF, 0xC262, 0xD5F0,
+	0xC263, 0xD5F1, 0xC264, 0xD5F2, 0xC265, 0xD5F3, 0xC266, 0xD5F6,
+	0xC267, 0xD5F8, 0xC268, 0xD5FA, 0xC269, 0xD5FB, 0xC26A, 0xD5FC,
+	0xC26B, 0xD5FD, 0xC26C, 0xD5FE, 0xC26D, 0xD5FF, 0xC26E, 0xD602,
+	0xC26F, 0xD603, 0xC270, 0xD605, 0xC271, 0xD606, 0xC272, 0xD607,
+	0xC273, 0xD609, 0xC274, 0xD60A, 0xC275, 0xD60B, 0xC276, 0xD60C,
+	0xC277, 0xD60D, 0xC278, 0xD60E, 0xC279, 0xD60F, 0xC27A, 0xD612,
+	0xC281, 0xD616, 0xC282, 0xD617, 0xC283, 0xD618, 0xC284, 0xD619,
+	0xC285, 0xD61A, 0xC286, 0xD61B, 0xC287, 0xD61D, 0xC288, 0xD61E,
+	0xC289, 0xD61F, 0xC28A, 0xD621, 0xC28B, 0xD622, 0xC28C, 0xD623,
+	0xC28D, 0xD625, 0xC28E, 0xD626, 0xC28F, 0xD627, 0xC290, 0xD628,
+	0xC291, 0xD629, 0xC292, 0xD62A, 0xC293, 0xD62B, 0xC294, 0xD62C,
+	0xC295, 0xD62E, 0xC296, 0xD62F, 0xC297, 0xD630, 0xC298, 0xD631,
+	0xC299, 0xD632, 0xC29A, 0xD633, 0xC29B, 0xD634, 0xC29C, 0xD635,
+	0xC29D, 0xD636, 0xC29E, 0xD637, 0xC29F, 0xD63A, 0xC2A0, 0xD63B,
+	0xC2A1, 0xC9D5, 0xC2A2, 0xC9D6, 0xC2A3, 0xC9D9, 0xC2A4, 0xC9DA,
+	0xC2A5, 0xC9DC, 0xC2A6, 0xC9DD, 0xC2A7, 0xC9E0, 0xC2A8, 0xC9E2,
+	0xC2A9, 0xC9E4, 0xC2AA, 0xC9E7, 0xC2AB, 0xC9EC, 0xC2AC, 0xC9ED,
+	0xC2AD, 0xC9EF, 0xC2AE, 0xC9F0, 0xC2AF, 0xC9F1, 0xC2B0, 0xC9F8,
+	0xC2B1, 0xC9F9, 0xC2B2, 0xC9FC, 0xC2B3, 0xCA00, 0xC2B4, 0xCA08,
+	0xC2B5, 0xCA09, 0xC2B6, 0xCA0B, 0xC2B7, 0xCA0C, 0xC2B8, 0xCA0D,
+	0xC2B9, 0xCA14, 0xC2BA, 0xCA18, 0xC2BB, 0xCA29, 0xC2BC, 0xCA4C,
+	0xC2BD, 0xCA4D, 0xC2BE, 0xCA50, 0xC2BF, 0xCA54, 0xC2C0, 0xCA5C,
+	0xC2C1, 0xCA5D, 0xC2C2, 0xCA5F, 0xC2C3, 0xCA60, 0xC2C4, 0xCA61,
+	0xC2C5, 0xCA68, 0xC2C6, 0xCA7D, 0xC2C7, 0xCA84, 0xC2C8, 0xCA98,
+	0xC2C9, 0xCABC, 0xC2CA, 0xCABD, 0xC2CB, 0xCAC0, 0xC2CC, 0xCAC4,
+	0xC2CD, 0xCACC, 0xC2CE, 0xCACD, 0xC2CF, 0xCACF, 0xC2D0, 0xCAD1,
+	0xC2D1, 0xCAD3, 0xC2D2, 0xCAD8, 0xC2D3, 0xCAD9, 0xC2D4, 0xCAE0,
+	0xC2D5, 0xCAEC, 0xC2D6, 0xCAF4, 0xC2D7, 0xCB08, 0xC2D8, 0xCB10,
+	0xC2D9, 0xCB14, 0xC2DA, 0xCB18, 0xC2DB, 0xCB20, 0xC2DC, 0xCB21,
+	0xC2DD, 0xCB41, 0xC2DE, 0xCB48, 0xC2DF, 0xCB49, 0xC2E0, 0xCB4C,
+	0xC2E1, 0xCB50, 0xC2E2, 0xCB58, 0xC2E3, 0xCB59, 0xC2E4, 0xCB5D,
+	0xC2E5, 0xCB64, 0xC2E6, 0xCB78, 0xC2E7, 0xCB79, 0xC2E8, 0xCB9C,
+	0xC2E9, 0xCBB8, 0xC2EA, 0xCBD4, 0xC2EB, 0xCBE4, 0xC2EC, 0xCBE7,
+	0xC2ED, 0xCBE9, 0xC2EE, 0xCC0C, 0xC2EF, 0xCC0D, 0xC2F0, 0xCC10,
+	0xC2F1, 0xCC14, 0xC2F2, 0xCC1C, 0xC2F3, 0xCC1D, 0xC2F4, 0xCC21,
+	0xC2F5, 0xCC22, 0xC2F6, 0xCC27, 0xC2F7, 0xCC28, 0xC2F8, 0xCC29,
+	0xC2F9, 0xCC2C, 0xC2FA, 0xCC2E, 0xC2FB, 0xCC30, 0xC2FC, 0xCC38,
+	0xC2FD, 0xCC39, 0xC2FE, 0xCC3B, 0xC341, 0xD63D, 0xC342, 0xD63E,
+	0xC343, 0xD63F, 0xC344, 0xD641, 0xC345, 0xD642, 0xC346, 0xD643,
+	0xC347, 0xD644, 0xC348, 0xD646, 0xC349, 0xD647, 0xC34A, 0xD64A,
+	0xC34B, 0xD64C, 0xC34C, 0xD64E, 0xC34D, 0xD64F, 0xC34E, 0xD650,
+	0xC34F, 0xD652, 0xC350, 0xD653, 0xC351, 0xD656, 0xC352, 0xD657,
+	0xC353, 0xD659, 0xC354, 0xD65A, 0xC355, 0xD65B, 0xC356, 0xD65D,
+	0xC357, 0xD65E, 0xC358, 0xD65F, 0xC359, 0xD660, 0xC35A, 0xD661,
+	0xC361, 0xD662, 0xC362, 0xD663, 0xC363, 0xD664, 0xC364, 0xD665,
+	0xC365, 0xD666, 0xC366, 0xD668, 0xC367, 0xD66A, 0xC368, 0xD66B,
+	0xC369, 0xD66C, 0xC36A, 0xD66D, 0xC36B, 0xD66E, 0xC36C, 0xD66F,
+	0xC36D, 0xD672, 0xC36E, 0xD673, 0xC36F, 0xD675, 0xC370, 0xD676,
+	0xC371, 0xD677, 0xC372, 0xD678, 0xC373, 0xD679, 0xC374, 0xD67A,
+	0xC375, 0xD67B, 0xC376, 0xD67C, 0xC377, 0xD67D, 0xC378, 0xD67E,
+	0xC379, 0xD67F, 0xC37A, 0xD680, 0xC381, 0xD681, 0xC382, 0xD682,
+	0xC383, 0xD684, 0xC384, 0xD686, 0xC385, 0xD687, 0xC386, 0xD688,
+	0xC387, 0xD689, 0xC388, 0xD68A, 0xC389, 0xD68B, 0xC38A, 0xD68E,
+	0xC38B, 0xD68F, 0xC38C, 0xD691, 0xC38D, 0xD692, 0xC38E, 0xD693,
+	0xC38F, 0xD695, 0xC390, 0xD696, 0xC391, 0xD697, 0xC392, 0xD698,
+	0xC393, 0xD699, 0xC394, 0xD69A, 0xC395, 0xD69B, 0xC396, 0xD69C,
+	0xC397, 0xD69E, 0xC398, 0xD6A0, 0xC399, 0xD6A2, 0xC39A, 0xD6A3,
+	0xC39B, 0xD6A4, 0xC39C, 0xD6A5, 0xC39D, 0xD6A6, 0xC39E, 0xD6A7,
+	0xC39F, 0xD6A9, 0xC3A0, 0xD6AA, 0xC3A1, 0xCC3C, 0xC3A2, 0xCC3D,
+	0xC3A3, 0xCC3E, 0xC3A4, 0xCC44, 0xC3A5, 0xCC45, 0xC3A6, 0xCC48,
+	0xC3A7, 0xCC4C, 0xC3A8, 0xCC54, 0xC3A9, 0xCC55, 0xC3AA, 0xCC57,
+	0xC3AB, 0xCC58, 0xC3AC, 0xCC59, 0xC3AD, 0xCC60, 0xC3AE, 0xCC64,
+	0xC3AF, 0xCC66, 0xC3B0, 0xCC68, 0xC3B1, 0xCC70, 0xC3B2, 0xCC75,
+	0xC3B3, 0xCC98, 0xC3B4, 0xCC99, 0xC3B5, 0xCC9C, 0xC3B6, 0xCCA0,
+	0xC3B7, 0xCCA8, 0xC3B8, 0xCCA9, 0xC3B9, 0xCCAB, 0xC3BA, 0xCCAC,
+	0xC3BB, 0xCCAD, 0xC3BC, 0xCCB4, 0xC3BD, 0xCCB5, 0xC3BE, 0xCCB8,
+	0xC3BF, 0xCCBC, 0xC3C0, 0xCCC4, 0xC3C1, 0xCCC5, 0xC3C2, 0xCCC7,
+	0xC3C3, 0xCCC9, 0xC3C4, 0xCCD0, 0xC3C5, 0xCCD4, 0xC3C6, 0xCCE4,
+	0xC3C7, 0xCCEC, 0xC3C8, 0xCCF0, 0xC3C9, 0xCD01, 0xC3CA, 0xCD08,
+	0xC3CB, 0xCD09, 0xC3CC, 0xCD0C, 0xC3CD, 0xCD10, 0xC3CE, 0xCD18,
+	0xC3CF, 0xCD19, 0xC3D0, 0xCD1B, 0xC3D1, 0xCD1D, 0xC3D2, 0xCD24,
+	0xC3D3, 0xCD28, 0xC3D4, 0xCD2C, 0xC3D5, 0xCD39, 0xC3D6, 0xCD5C,
+	0xC3D7, 0xCD60, 0xC3D8, 0xCD64, 0xC3D9, 0xCD6C, 0xC3DA, 0xCD6D,
+	0xC3DB, 0xCD6F, 0xC3DC, 0xCD71, 0xC3DD, 0xCD78, 0xC3DE, 0xCD88,
+	0xC3DF, 0xCD94, 0xC3E0, 0xCD95, 0xC3E1, 0xCD98, 0xC3E2, 0xCD9C,
+	0xC3E3, 0xCDA4, 0xC3E4, 0xCDA5, 0xC3E5, 0xCDA7, 0xC3E6, 0xCDA9,
+	0xC3E7, 0xCDB0, 0xC3E8, 0xCDC4, 0xC3E9, 0xCDCC, 0xC3EA, 0xCDD0,
+	0xC3EB, 0xCDE8, 0xC3EC, 0xCDEC, 0xC3ED, 0xCDF0, 0xC3EE, 0xCDF8,
+	0xC3EF, 0xCDF9, 0xC3F0, 0xCDFB, 0xC3F1, 0xCDFD, 0xC3F2, 0xCE04,
+	0xC3F3, 0xCE08, 0xC3F4, 0xCE0C, 0xC3F5, 0xCE14, 0xC3F6, 0xCE19,
+	0xC3F7, 0xCE20, 0xC3F8, 0xCE21, 0xC3F9, 0xCE24, 0xC3FA, 0xCE28,
+	0xC3FB, 0xCE30, 0xC3FC, 0xCE31, 0xC3FD, 0xCE33, 0xC3FE, 0xCE35,
+	0xC441, 0xD6AB, 0xC442, 0xD6AD, 0xC443, 0xD6AE, 0xC444, 0xD6AF,
+	0xC445, 0xD6B1, 0xC446, 0xD6B2, 0xC447, 0xD6B3, 0xC448, 0xD6B4,
+	0xC449, 0xD6B5, 0xC44A, 0xD6B6, 0xC44B, 0xD6B7, 0xC44C, 0xD6B8,
+	0xC44D, 0xD6BA, 0xC44E, 0xD6BC, 0xC44F, 0xD6BD, 0xC450, 0xD6BE,
+	0xC451, 0xD6BF, 0xC452, 0xD6C0, 0xC453, 0xD6C1, 0xC454, 0xD6C2,
+	0xC455, 0xD6C3, 0xC456, 0xD6C6, 0xC457, 0xD6C7, 0xC458, 0xD6C9,
+	0xC459, 0xD6CA, 0xC45A, 0xD6CB, 0xC461, 0xD6CD, 0xC462, 0xD6CE,
+	0xC463, 0xD6CF, 0xC464, 0xD6D0, 0xC465, 0xD6D2, 0xC466, 0xD6D3,
+	0xC467, 0xD6D5, 0xC468, 0xD6D6, 0xC469, 0xD6D8, 0xC46A, 0xD6DA,
+	0xC46B, 0xD6DB, 0xC46C, 0xD6DC, 0xC46D, 0xD6DD, 0xC46E, 0xD6DE,
+	0xC46F, 0xD6DF, 0xC470, 0xD6E1, 0xC471, 0xD6E2, 0xC472, 0xD6E3,
+	0xC473, 0xD6E5, 0xC474, 0xD6E6, 0xC475, 0xD6E7, 0xC476, 0xD6E9,
+	0xC477, 0xD6EA, 0xC478, 0xD6EB, 0xC479, 0xD6EC, 0xC47A, 0xD6ED,
+	0xC481, 0xD6EE, 0xC482, 0xD6EF, 0xC483, 0xD6F1, 0xC484, 0xD6F2,
+	0xC485, 0xD6F3, 0xC486, 0xD6F4, 0xC487, 0xD6F6, 0xC488, 0xD6F7,
+	0xC489, 0xD6F8, 0xC48A, 0xD6F9, 0xC48B, 0xD6FA, 0xC48C, 0xD6FB,
+	0xC48D, 0xD6FE, 0xC48E, 0xD6FF, 0xC48F, 0xD701, 0xC490, 0xD702,
+	0xC491, 0xD703, 0xC492, 0xD705, 0xC493, 0xD706, 0xC494, 0xD707,
+	0xC495, 0xD708, 0xC496, 0xD709, 0xC497, 0xD70A, 0xC498, 0xD70B,
+	0xC499, 0xD70C, 0xC49A, 0xD70D, 0xC49B, 0xD70E, 0xC49C, 0xD70F,
+	0xC49D, 0xD710, 0xC49E, 0xD712, 0xC49F, 0xD713, 0xC4A0, 0xD714,
+	0xC4A1, 0xCE58, 0xC4A2, 0xCE59, 0xC4A3, 0xCE5C, 0xC4A4, 0xCE5F,
+	0xC4A5, 0xCE60, 0xC4A6, 0xCE61, 0xC4A7, 0xCE68, 0xC4A8, 0xCE69,
+	0xC4A9, 0xCE6B, 0xC4AA, 0xCE6D, 0xC4AB, 0xCE74, 0xC4AC, 0xCE75,
+	0xC4AD, 0xCE78, 0xC4AE, 0xCE7C, 0xC4AF, 0xCE84, 0xC4B0, 0xCE85,
+	0xC4B1, 0xCE87, 0xC4B2, 0xCE89, 0xC4B3, 0xCE90, 0xC4B4, 0xCE91,
+	0xC4B5, 0xCE94, 0xC4B6, 0xCE98, 0xC4B7, 0xCEA0, 0xC4B8, 0xCEA1,
+	0xC4B9, 0xCEA3, 0xC4BA, 0xCEA4, 0xC4BB, 0xCEA5, 0xC4BC, 0xCEAC,
+	0xC4BD, 0xCEAD, 0xC4BE, 0xCEC1, 0xC4BF, 0xCEE4, 0xC4C0, 0xCEE5,
+	0xC4C1, 0xCEE8, 0xC4C2, 0xCEEB, 0xC4C3, 0xCEEC, 0xC4C4, 0xCEF4,
+	0xC4C5, 0xCEF5, 0xC4C6, 0xCEF7, 0xC4C7, 0xCEF8, 0xC4C8, 0xCEF9,
+	0xC4C9, 0xCF00, 0xC4CA, 0xCF01, 0xC4CB, 0xCF04, 0xC4CC, 0xCF08,
+	0xC4CD, 0xCF10, 0xC4CE, 0xCF11, 0xC4CF, 0xCF13, 0xC4D0, 0xCF15,
+	0xC4D1, 0xCF1C, 0xC4D2, 0xCF20, 0xC4D3, 0xCF24, 0xC4D4, 0xCF2C,
+	0xC4D5, 0xCF2D, 0xC4D6, 0xCF2F, 0xC4D7, 0xCF30, 0xC4D8, 0xCF31,
+	0xC4D9, 0xCF38, 0xC4DA, 0xCF54, 0xC4DB, 0xCF55, 0xC4DC, 0xCF58,
+	0xC4DD, 0xCF5C, 0xC4DE, 0xCF64, 0xC4DF, 0xCF65, 0xC4E0, 0xCF67,
+	0xC4E1, 0xCF69, 0xC4E2, 0xCF70, 0xC4E3, 0xCF71, 0xC4E4, 0xCF74,
+	0xC4E5, 0xCF78, 0xC4E6, 0xCF80, 0xC4E7, 0xCF85, 0xC4E8, 0xCF8C,
+	0xC4E9, 0xCFA1, 0xC4EA, 0xCFA8, 0xC4EB, 0xCFB0, 0xC4EC, 0xCFC4,
+	0xC4ED, 0xCFE0, 0xC4EE, 0xCFE1, 0xC4EF, 0xCFE4, 0xC4F0, 0xCFE8,
+	0xC4F1, 0xCFF0, 0xC4F2, 0xCFF1, 0xC4F3, 0xCFF3, 0xC4F4, 0xCFF5,
+	0xC4F5, 0xCFFC, 0xC4F6, 0xD000, 0xC4F7, 0xD004, 0xC4F8, 0xD011,
+	0xC4F9, 0xD018, 0xC4FA, 0xD02D, 0xC4FB, 0xD034, 0xC4FC, 0xD035,
+	0xC4FD, 0xD038, 0xC4FE, 0xD03C, 0xC541, 0xD715, 0xC542, 0xD716,
+	0xC543, 0xD717, 0xC544, 0xD71A, 0xC545, 0xD71B, 0xC546, 0xD71D,
+	0xC547, 0xD71E, 0xC548, 0xD71F, 0xC549, 0xD721, 0xC54A, 0xD722,
+	0xC54B, 0xD723, 0xC54C, 0xD724, 0xC54D, 0xD725, 0xC54E, 0xD726,
+	0xC54F, 0xD727, 0xC550, 0xD72A, 0xC551, 0xD72C, 0xC552, 0xD72E,
+	0xC553, 0xD72F, 0xC554, 0xD730, 0xC555, 0xD731, 0xC556, 0xD732,
+	0xC557, 0xD733, 0xC558, 0xD736, 0xC559, 0xD737, 0xC55A, 0xD739,
+	0xC561, 0xD73A, 0xC562, 0xD73B, 0xC563, 0xD73D, 0xC564, 0xD73E,
+	0xC565, 0xD73F, 0xC566, 0xD740, 0xC567, 0xD741, 0xC568, 0xD742,
+	0xC569, 0xD743, 0xC56A, 0xD745, 0xC56B, 0xD746, 0xC56C, 0xD748,
+	0xC56D, 0xD74A, 0xC56E, 0xD74B, 0xC56F, 0xD74C, 0xC570, 0xD74D,
+	0xC571, 0xD74E, 0xC572, 0xD74F, 0xC573, 0xD752, 0xC574, 0xD753,
+	0xC575, 0xD755, 0xC576, 0xD75A, 0xC577, 0xD75B, 0xC578, 0xD75C,
+	0xC579, 0xD75D, 0xC57A, 0xD75E, 0xC581, 0xD75F, 0xC582, 0xD762,
+	0xC583, 0xD764, 0xC584, 0xD766, 0xC585, 0xD767, 0xC586, 0xD768,
+	0xC587, 0xD76A, 0xC588, 0xD76B, 0xC589, 0xD76D, 0xC58A, 0xD76E,
+	0xC58B, 0xD76F, 0xC58C, 0xD771, 0xC58D, 0xD772, 0xC58E, 0xD773,
+	0xC58F, 0xD775, 0xC590, 0xD776, 0xC591, 0xD777, 0xC592, 0xD778,
+	0xC593, 0xD779, 0xC594, 0xD77A, 0xC595, 0xD77B, 0xC596, 0xD77E,
+	0xC597, 0xD77F, 0xC598, 0xD780, 0xC599, 0xD782, 0xC59A, 0xD783,
+	0xC59B, 0xD784, 0xC59C, 0xD785, 0xC59D, 0xD786, 0xC59E, 0xD787,
+	0xC59F, 0xD78A, 0xC5A0, 0xD78B, 0xC5A1, 0xD044, 0xC5A2, 0xD045,
+	0xC5A3, 0xD047, 0xC5A4, 0xD049, 0xC5A5, 0xD050, 0xC5A6, 0xD054,
+	0xC5A7, 0xD058, 0xC5A8, 0xD060, 0xC5A9, 0xD06C, 0xC5AA, 0xD06D,
+	0xC5AB, 0xD070, 0xC5AC, 0xD074, 0xC5AD, 0xD07C, 0xC5AE, 0xD07D,
+	0xC5AF, 0xD081, 0xC5B0, 0xD0A4, 0xC5B1, 0xD0A5, 0xC5B2, 0xD0A8,
+	0xC5B3, 0xD0AC, 0xC5B4, 0xD0B4, 0xC5B5, 0xD0B5, 0xC5B6, 0xD0B7,
+	0xC5B7, 0xD0B9, 0xC5B8, 0xD0C0, 0xC5B9, 0xD0C1, 0xC5BA, 0xD0C4,
+	0xC5BB, 0xD0C8, 0xC5BC, 0xD0C9, 0xC5BD, 0xD0D0, 0xC5BE, 0xD0D1,
+	0xC5BF, 0xD0D3, 0xC5C0, 0xD0D4, 0xC5C1, 0xD0D5, 0xC5C2, 0xD0DC,
+	0xC5C3, 0xD0DD, 0xC5C4, 0xD0E0, 0xC5C5, 0xD0E4, 0xC5C6, 0xD0EC,
+	0xC5C7, 0xD0ED, 0xC5C8, 0xD0EF, 0xC5C9, 0xD0F0, 0xC5CA, 0xD0F1,
+	0xC5CB, 0xD0F8, 0xC5CC, 0xD10D, 0xC5CD, 0xD130, 0xC5CE, 0xD131,
+	0xC5CF, 0xD134, 0xC5D0, 0xD138, 0xC5D1, 0xD13A, 0xC5D2, 0xD140,
+	0xC5D3, 0xD141, 0xC5D4, 0xD143, 0xC5D5, 0xD144, 0xC5D6, 0xD145,
+	0xC5D7, 0xD14C, 0xC5D8, 0xD14D, 0xC5D9, 0xD150, 0xC5DA, 0xD154,
+	0xC5DB, 0xD15C, 0xC5DC, 0xD15D, 0xC5DD, 0xD15F, 0xC5DE, 0xD161,
+	0xC5DF, 0xD168, 0xC5E0, 0xD16C, 0xC5E1, 0xD17C, 0xC5E2, 0xD184,
+	0xC5E3, 0xD188, 0xC5E4, 0xD1A0, 0xC5E5, 0xD1A1, 0xC5E6, 0xD1A4,
+	0xC5E7, 0xD1A8, 0xC5E8, 0xD1B0, 0xC5E9, 0xD1B1, 0xC5EA, 0xD1B3,
+	0xC5EB, 0xD1B5, 0xC5EC, 0xD1BA, 0xC5ED, 0xD1BC, 0xC5EE, 0xD1C0,
+	0xC5EF, 0xD1D8, 0xC5F0, 0xD1F4, 0xC5F1, 0xD1F8, 0xC5F2, 0xD207,
+	0xC5F3, 0xD209, 0xC5F4, 0xD210, 0xC5F5, 0xD22C, 0xC5F6, 0xD22D,
+	0xC5F7, 0xD230, 0xC5F8, 0xD234, 0xC5F9, 0xD23C, 0xC5FA, 0xD23D,
+	0xC5FB, 0xD23F, 0xC5FC, 0xD241, 0xC5FD, 0xD248, 0xC5FE, 0xD25C,
+	0xC641, 0xD78D, 0xC642, 0xD78E, 0xC643, 0xD78F, 0xC644, 0xD791,
+	0xC645, 0xD792, 0xC646, 0xD793, 0xC647, 0xD794, 0xC648, 0xD795,
+	0xC649, 0xD796, 0xC64A, 0xD797, 0xC64B, 0xD79A, 0xC64C, 0xD79C,
+	0xC64D, 0xD79E, 0xC64E, 0xD79F, 0xC64F, 0xD7A0, 0xC650, 0xD7A1,
+	0xC651, 0xD7A2, 0xC652, 0xD7A3, 0xC6A1, 0xD264, 0xC6A2, 0xD280,
+	0xC6A3, 0xD281, 0xC6A4, 0xD284, 0xC6A5, 0xD288, 0xC6A6, 0xD290,
+	0xC6A7, 0xD291, 0xC6A8, 0xD295, 0xC6A9, 0xD29C, 0xC6AA, 0xD2A0,
+	0xC6AB, 0xD2A4, 0xC6AC, 0xD2AC, 0xC6AD, 0xD2B1, 0xC6AE, 0xD2B8,
+	0xC6AF, 0xD2B9, 0xC6B0, 0xD2BC, 0xC6B1, 0xD2BF, 0xC6B2, 0xD2C0,
+	0xC6B3, 0xD2C2, 0xC6B4, 0xD2C8, 0xC6B5, 0xD2C9, 0xC6B6, 0xD2CB,
+	0xC6B7, 0xD2D4, 0xC6B8, 0xD2D8, 0xC6B9, 0xD2DC, 0xC6BA, 0xD2E4,
+	0xC6BB, 0xD2E5, 0xC6BC, 0xD2F0, 0xC6BD, 0xD2F1, 0xC6BE, 0xD2F4,
+	0xC6BF, 0xD2F8, 0xC6C0, 0xD300, 0xC6C1, 0xD301, 0xC6C2, 0xD303,
+	0xC6C3, 0xD305, 0xC6C4, 0xD30C, 0xC6C5, 0xD30D, 0xC6C6, 0xD30E,
+	0xC6C7, 0xD310, 0xC6C8, 0xD314, 0xC6C9, 0xD316, 0xC6CA, 0xD31C,
+	0xC6CB, 0xD31D, 0xC6CC, 0xD31F, 0xC6CD, 0xD320, 0xC6CE, 0xD321,
+	0xC6CF, 0xD325, 0xC6D0, 0xD328, 0xC6D1, 0xD329, 0xC6D2, 0xD32C,
+	0xC6D3, 0xD330, 0xC6D4, 0xD338, 0xC6D5, 0xD339, 0xC6D6, 0xD33B,
+	0xC6D7, 0xD33C, 0xC6D8, 0xD33D, 0xC6D9, 0xD344, 0xC6DA, 0xD345,
+	0xC6DB, 0xD37C, 0xC6DC, 0xD37D, 0xC6DD, 0xD380, 0xC6DE, 0xD384,
+	0xC6DF, 0xD38C, 0xC6E0, 0xD38D, 0xC6E1, 0xD38F, 0xC6E2, 0xD390,
+	0xC6E3, 0xD391, 0xC6E4, 0xD398, 0xC6E5, 0xD399, 0xC6E6, 0xD39C,
+	0xC6E7, 0xD3A0, 0xC6E8, 0xD3A8, 0xC6E9, 0xD3A9, 0xC6EA, 0xD3AB,
+	0xC6EB, 0xD3AD, 0xC6EC, 0xD3B4, 0xC6ED, 0xD3B8, 0xC6EE, 0xD3BC,
+	0xC6EF, 0xD3C4, 0xC6F0, 0xD3C5, 0xC6F1, 0xD3C8, 0xC6F2, 0xD3C9,
+	0xC6F3, 0xD3D0, 0xC6F4, 0xD3D8, 0xC6F5, 0xD3E1, 0xC6F6, 0xD3E3,
+	0xC6F7, 0xD3EC, 0xC6F8, 0xD3ED, 0xC6F9, 0xD3F0, 0xC6FA, 0xD3F4,
+	0xC6FB, 0xD3FC, 0xC6FC, 0xD3FD, 0xC6FD, 0xD3FF, 0xC6FE, 0xD401,
+	0xC7A1, 0xD408, 0xC7A2, 0xD41D, 0xC7A3, 0xD440, 0xC7A4, 0xD444,
+	0xC7A5, 0xD45C, 0xC7A6, 0xD460, 0xC7A7, 0xD464, 0xC7A8, 0xD46D,
+	0xC7A9, 0xD46F, 0xC7AA, 0xD478, 0xC7AB, 0xD479, 0xC7AC, 0xD47C,
+	0xC7AD, 0xD47F, 0xC7AE, 0xD480, 0xC7AF, 0xD482, 0xC7B0, 0xD488,
+	0xC7B1, 0xD489, 0xC7B2, 0xD48B, 0xC7B3, 0xD48D, 0xC7B4, 0xD494,
+	0xC7B5, 0xD4A9, 0xC7B6, 0xD4CC, 0xC7B7, 0xD4D0, 0xC7B8, 0xD4D4,
+	0xC7B9, 0xD4DC, 0xC7BA, 0xD4DF, 0xC7BB, 0xD4E8, 0xC7BC, 0xD4EC,
+	0xC7BD, 0xD4F0, 0xC7BE, 0xD4F8, 0xC7BF, 0xD4FB, 0xC7C0, 0xD4FD,
+	0xC7C1, 0xD504, 0xC7C2, 0xD508, 0xC7C3, 0xD50C, 0xC7C4, 0xD514,
+	0xC7C5, 0xD515, 0xC7C6, 0xD517, 0xC7C7, 0xD53C, 0xC7C8, 0xD53D,
+	0xC7C9, 0xD540, 0xC7CA, 0xD544, 0xC7CB, 0xD54C, 0xC7CC, 0xD54D,
+	0xC7CD, 0xD54F, 0xC7CE, 0xD551, 0xC7CF, 0xD558, 0xC7D0, 0xD559,
+	0xC7D1, 0xD55C, 0xC7D2, 0xD560, 0xC7D3, 0xD565, 0xC7D4, 0xD568,
+	0xC7D5, 0xD569, 0xC7D6, 0xD56B, 0xC7D7, 0xD56D, 0xC7D8, 0xD574,
+	0xC7D9, 0xD575, 0xC7DA, 0xD578, 0xC7DB, 0xD57C, 0xC7DC, 0xD584,
+	0xC7DD, 0xD585, 0xC7DE, 0xD587, 0xC7DF, 0xD588, 0xC7E0, 0xD589,
+	0xC7E1, 0xD590, 0xC7E2, 0xD5A5, 0xC7E3, 0xD5C8, 0xC7E4, 0xD5C9,
+	0xC7E5, 0xD5CC, 0xC7E6, 0xD5D0, 0xC7E7, 0xD5D2, 0xC7E8, 0xD5D8,
+	0xC7E9, 0xD5D9, 0xC7EA, 0xD5DB, 0xC7EB, 0xD5DD, 0xC7EC, 0xD5E4,
+	0xC7ED, 0xD5E5, 0xC7EE, 0xD5E8, 0xC7EF, 0xD5EC, 0xC7F0, 0xD5F4,
+	0xC7F1, 0xD5F5, 0xC7F2, 0xD5F7, 0xC7F3, 0xD5F9, 0xC7F4, 0xD600,
+	0xC7F5, 0xD601, 0xC7F6, 0xD604, 0xC7F7, 0xD608, 0xC7F8, 0xD610,
+	0xC7F9, 0xD611, 0xC7FA, 0xD613, 0xC7FB, 0xD614, 0xC7FC, 0xD615,
+	0xC7FD, 0xD61C, 0xC7FE, 0xD620, 0xC8A1, 0xD624, 0xC8A2, 0xD62D,
+	0xC8A3, 0xD638, 0xC8A4, 0xD639, 0xC8A5, 0xD63C, 0xC8A6, 0xD640,
+	0xC8A7, 0xD645, 0xC8A8, 0xD648, 0xC8A9, 0xD649, 0xC8AA, 0xD64B,
+	0xC8AB, 0xD64D, 0xC8AC, 0xD651, 0xC8AD, 0xD654, 0xC8AE, 0xD655,
+	0xC8AF, 0xD658, 0xC8B0, 0xD65C, 0xC8B1, 0xD667, 0xC8B2, 0xD669,
+	0xC8B3, 0xD670, 0xC8B4, 0xD671, 0xC8B5, 0xD674, 0xC8B6, 0xD683,
+	0xC8B7, 0xD685, 0xC8B8, 0xD68C, 0xC8B9, 0xD68D, 0xC8BA, 0xD690,
+	0xC8BB, 0xD694, 0xC8BC, 0xD69D, 0xC8BD, 0xD69F, 0xC8BE, 0xD6A1,
+	0xC8BF, 0xD6A8, 0xC8C0, 0xD6AC, 0xC8C1, 0xD6B0, 0xC8C2, 0xD6B9,
+	0xC8C3, 0xD6BB, 0xC8C4, 0xD6C4, 0xC8C5, 0xD6C5, 0xC8C6, 0xD6C8,
+	0xC8C7, 0xD6CC, 0xC8C8, 0xD6D1, 0xC8C9, 0xD6D4, 0xC8CA, 0xD6D7,
+	0xC8CB, 0xD6D9, 0xC8CC, 0xD6E0, 0xC8CD, 0xD6E4, 0xC8CE, 0xD6E8,
+	0xC8CF, 0xD6F0, 0xC8D0, 0xD6F5, 0xC8D1, 0xD6FC, 0xC8D2, 0xD6FD,
+	0xC8D3, 0xD700, 0xC8D4, 0xD704, 0xC8D5, 0xD711, 0xC8D6, 0xD718,
+	0xC8D7, 0xD719, 0xC8D8, 0xD71C, 0xC8D9, 0xD720, 0xC8DA, 0xD728,
+	0xC8DB, 0xD729, 0xC8DC, 0xD72B, 0xC8DD, 0xD72D, 0xC8DE, 0xD734,
+	0xC8DF, 0xD735, 0xC8E0, 0xD738, 0xC8E1, 0xD73C, 0xC8E2, 0xD744,
+	0xC8E3, 0xD747, 0xC8E4, 0xD749, 0xC8E5, 0xD750, 0xC8E6, 0xD751,
+	0xC8E7, 0xD754, 0xC8E8, 0xD756, 0xC8E9, 0xD757, 0xC8EA, 0xD758,
+	0xC8EB, 0xD759, 0xC8EC, 0xD760, 0xC8ED, 0xD761, 0xC8EE, 0xD763,
+	0xC8EF, 0xD765, 0xC8F0, 0xD769, 0xC8F1, 0xD76C, 0xC8F2, 0xD770,
+	0xC8F3, 0xD774, 0xC8F4, 0xD77C, 0xC8F5, 0xD77D, 0xC8F6, 0xD781,
+	0xC8F7, 0xD788, 0xC8F8, 0xD789, 0xC8F9, 0xD78C, 0xC8FA, 0xD790,
+	0xC8FB, 0xD798, 0xC8FC, 0xD799, 0xC8FD, 0xD79B, 0xC8FE, 0xD79D,
+	0xCAA1, 0x4F3D, 0xCAA2, 0x4F73, 0xCAA3, 0x5047, 0xCAA4, 0x50F9,
+	0xCAA5, 0x52A0, 0xCAA6, 0x53EF, 0xCAA7, 0x5475, 0xCAA8, 0x54E5,
+	0xCAA9, 0x5609, 0xCAAA, 0x5AC1, 0xCAAB, 0x5BB6, 0xCAAC, 0x6687,
+	0xCAAD, 0x67B6, 0xCAAE, 0x67B7, 0xCAAF, 0x67EF, 0xCAB0, 0x6B4C,
+	0xCAB1, 0x73C2, 0xCAB2, 0x75C2, 0xCAB3, 0x7A3C, 0xCAB4, 0x82DB,
+	0xCAB5, 0x8304, 0xCAB6, 0x8857, 0xCAB7, 0x8888, 0xCAB8, 0x8A36,
+	0xCAB9, 0x8CC8, 0xCABA, 0x8DCF, 0xCABB, 0x8EFB, 0xCABC, 0x8FE6,
+	0xCABD, 0x99D5, 0xCABE, 0x523B, 0xCABF, 0x5374, 0xCAC0, 0x5404,
+	0xCAC1, 0x606A, 0xCAC2, 0x6164, 0xCAC3, 0x6BBC, 0xCAC4, 0x73CF,
+	0xCAC5, 0x811A, 0xCAC6, 0x89BA, 0xCAC7, 0x89D2, 0xCAC8, 0x95A3,
+	0xCAC9, 0x4F83, 0xCACA, 0x520A, 0xCACB, 0x58BE, 0xCACC, 0x5978,
+	0xCACD, 0x59E6, 0xCACE, 0x5E72, 0xCACF, 0x5E79, 0xCAD0, 0x61C7,
+	0xCAD1, 0x63C0, 0xCAD2, 0x6746, 0xCAD3, 0x67EC, 0xCAD4, 0x687F,
+	0xCAD5, 0x6F97, 0xCAD6, 0x764E, 0xCAD7, 0x770B, 0xCAD8, 0x78F5,
+	0xCAD9, 0x7A08, 0xCADA, 0x7AFF, 0xCADB, 0x7C21, 0xCADC, 0x809D,
+	0xCADD, 0x826E, 0xCADE, 0x8271, 0xCADF, 0x8AEB, 0xCAE0, 0x9593,
+	0xCAE1, 0x4E6B, 0xCAE2, 0x559D, 0xCAE3, 0x66F7, 0xCAE4, 0x6E34,
+	0xCAE5, 0x78A3, 0xCAE6, 0x7AED, 0xCAE7, 0x845B, 0xCAE8, 0x8910,
+	0xCAE9, 0x874E, 0xCAEA, 0x97A8, 0xCAEB, 0x52D8, 0xCAEC, 0x574E,
+	0xCAED, 0x582A, 0xCAEE, 0x5D4C, 0xCAEF, 0x611F, 0xCAF0, 0x61BE,
+	0xCAF1, 0x6221, 0xCAF2, 0x6562, 0xCAF3, 0x67D1, 0xCAF4, 0x6A44,
+	0xCAF5, 0x6E1B, 0xCAF6, 0x7518, 0xCAF7, 0x75B3, 0xCAF8, 0x76E3,
+	0xCAF9, 0x77B0, 0xCAFA, 0x7D3A, 0xCAFB, 0x90AF, 0xCAFC, 0x9451,
+	0xCAFD, 0x9452, 0xCAFE, 0x9F95, 0xCBA1, 0x5323, 0xCBA2, 0x5CAC,
+	0xCBA3, 0x7532, 0xCBA4, 0x80DB, 0xCBA5, 0x9240, 0xCBA6, 0x9598,
+	0xCBA7, 0x525B, 0xCBA8, 0x5808, 0xCBA9, 0x59DC, 0xCBAA, 0x5CA1,
+	0xCBAB, 0x5D17, 0xCBAC, 0x5EB7, 0xCBAD, 0x5F3A, 0xCBAE, 0x5F4A,
+	0xCBAF, 0x6177, 0xCBB0, 0x6C5F, 0xCBB1, 0x757A, 0xCBB2, 0x7586,
+	0xCBB3, 0x7CE0, 0xCBB4, 0x7D73, 0xCBB5, 0x7DB1, 0xCBB6, 0x7F8C,
+	0xCBB7, 0x8154, 0xCBB8, 0x8221, 0xCBB9, 0x8591, 0xCBBA, 0x8941,
+	0xCBBB, 0x8B1B, 0xCBBC, 0x92FC, 0xCBBD, 0x964D, 0xCBBE, 0x9C47,
+	0xCBBF, 0x4ECB, 0xCBC0, 0x4EF7, 0xCBC1, 0x500B, 0xCBC2, 0x51F1,
+	0xCBC3, 0x584F, 0xCBC4, 0x6137, 0xCBC5, 0x613E, 0xCBC6, 0x6168,
+	0xCBC7, 0x6539, 0xCBC8, 0x69EA, 0xCBC9, 0x6F11, 0xCBCA, 0x75A5,
+	0xCBCB, 0x7686, 0xCBCC, 0x76D6, 0xCBCD, 0x7B87, 0xCBCE, 0x82A5,
+	0xCBCF, 0x84CB, 0xCBD0, 0xF900, 0xCBD1, 0x93A7, 0xCBD2, 0x958B,
+	0xCBD3, 0x5580, 0xCBD4, 0x5BA2, 0xCBD5, 0x5751, 0xCBD6, 0xF901,
+	0xCBD7, 0x7CB3, 0xCBD8, 0x7FB9, 0xCBD9, 0x91B5, 0xCBDA, 0x5028,
+	0xCBDB, 0x53BB, 0xCBDC, 0x5C45, 0xCBDD, 0x5DE8, 0xCBDE, 0x62D2,
+	0xCBDF, 0x636E, 0xCBE0, 0x64DA, 0xCBE1, 0x64E7, 0xCBE2, 0x6E20,
+	0xCBE3, 0x70AC, 0xCBE4, 0x795B, 0xCBE5, 0x8DDD, 0xCBE6, 0x8E1E,
+	0xCBE7, 0xF902, 0xCBE8, 0x907D, 0xCBE9, 0x9245, 0xCBEA, 0x92F8,
+	0xCBEB, 0x4E7E, 0xCBEC, 0x4EF6, 0xCBED, 0x5065, 0xCBEE, 0x5DFE,
+	0xCBEF, 0x5EFA, 0xCBF0, 0x6106, 0xCBF1, 0x6957, 0xCBF2, 0x8171,
+	0xCBF3, 0x8654, 0xCBF4, 0x8E47, 0xCBF5, 0x9375, 0xCBF6, 0x9A2B,
+	0xCBF7, 0x4E5E, 0xCBF8, 0x5091, 0xCBF9, 0x6770, 0xCBFA, 0x6840,
+	0xCBFB, 0x5109, 0xCBFC, 0x528D, 0xCBFD, 0x5292, 0xCBFE, 0x6AA2,
+	0xCCA1, 0x77BC, 0xCCA2, 0x9210, 0xCCA3, 0x9ED4, 0xCCA4, 0x52AB,
+	0xCCA5, 0x602F, 0xCCA6, 0x8FF2, 0xCCA7, 0x5048, 0xCCA8, 0x61A9,
+	0xCCA9, 0x63ED, 0xCCAA, 0x64CA, 0xCCAB, 0x683C, 0xCCAC, 0x6A84,
+	0xCCAD, 0x6FC0, 0xCCAE, 0x8188, 0xCCAF, 0x89A1, 0xCCB0, 0x9694,
+	0xCCB1, 0x5805, 0xCCB2, 0x727D, 0xCCB3, 0x72AC, 0xCCB4, 0x7504,
+	0xCCB5, 0x7D79, 0xCCB6, 0x7E6D, 0xCCB7, 0x80A9, 0xCCB8, 0x898B,
+	0xCCB9, 0x8B74, 0xCCBA, 0x9063, 0xCCBB, 0x9D51, 0xCCBC, 0x6289,
+	0xCCBD, 0x6C7A, 0xCCBE, 0x6F54, 0xCCBF, 0x7D50, 0xCCC0, 0x7F3A,
+	0xCCC1, 0x8A23, 0xCCC2, 0x517C, 0xCCC3, 0x614A, 0xCCC4, 0x7B9D,
+	0xCCC5, 0x8B19, 0xCCC6, 0x9257, 0xCCC7, 0x938C, 0xCCC8, 0x4EAC,
+	0xCCC9, 0x4FD3, 0xCCCA, 0x501E, 0xCCCB, 0x50BE, 0xCCCC, 0x5106,
+	0xCCCD, 0x52C1, 0xCCCE, 0x52CD, 0xCCCF, 0x537F, 0xCCD0, 0x5770,
+	0xCCD1, 0x5883, 0xCCD2, 0x5E9A, 0xCCD3, 0x5F91, 0xCCD4, 0x6176,
+	0xCCD5, 0x61AC, 0xCCD6, 0x64CE, 0xCCD7, 0x656C, 0xCCD8, 0x666F,
+	0xCCD9, 0x66BB, 0xCCDA, 0x66F4, 0xCCDB, 0x6897, 0xCCDC, 0x6D87,
+	0xCCDD, 0x7085, 0xCCDE, 0x70F1, 0xCCDF, 0x749F, 0xCCE0, 0x74A5,
+	0xCCE1, 0x74CA, 0xCCE2, 0x75D9, 0xCCE3, 0x786C, 0xCCE4, 0x78EC,
+	0xCCE5, 0x7ADF, 0xCCE6, 0x7AF6, 0xCCE7, 0x7D45, 0xCCE8, 0x7D93,
+	0xCCE9, 0x8015, 0xCCEA, 0x803F, 0xCCEB, 0x811B, 0xCCEC, 0x8396,
+	0xCCED, 0x8B66, 0xCCEE, 0x8F15, 0xCCEF, 0x9015, 0xCCF0, 0x93E1,
+	0xCCF1, 0x9803, 0xCCF2, 0x9838, 0xCCF3, 0x9A5A, 0xCCF4, 0x9BE8,
+	0xCCF5, 0x4FC2, 0xCCF6, 0x5553, 0xCCF7, 0x583A, 0xCCF8, 0x5951,
+	0xCCF9, 0x5B63, 0xCCFA, 0x5C46, 0xCCFB, 0x60B8, 0xCCFC, 0x6212,
+	0xCCFD, 0x6842, 0xCCFE, 0x68B0, 0xCDA1, 0x68E8, 0xCDA2, 0x6EAA,
+	0xCDA3, 0x754C, 0xCDA4, 0x7678, 0xCDA5, 0x78CE, 0xCDA6, 0x7A3D,
+	0xCDA7, 0x7CFB, 0xCDA8, 0x7E6B, 0xCDA9, 0x7E7C, 0xCDAA, 0x8A08,
+	0xCDAB, 0x8AA1, 0xCDAC, 0x8C3F, 0xCDAD, 0x968E, 0xCDAE, 0x9DC4,
+	0xCDAF, 0x53E4, 0xCDB0, 0x53E9, 0xCDB1, 0x544A, 0xCDB2, 0x5471,
+	0xCDB3, 0x56FA, 0xCDB4, 0x59D1, 0xCDB5, 0x5B64, 0xCDB6, 0x5C3B,
+	0xCDB7, 0x5EAB, 0xCDB8, 0x62F7, 0xCDB9, 0x6537, 0xCDBA, 0x6545,
+	0xCDBB, 0x6572, 0xCDBC, 0x66A0, 0xCDBD, 0x67AF, 0xCDBE, 0x69C1,
+	0xCDBF, 0x6CBD, 0xCDC0, 0x75FC, 0xCDC1, 0x7690, 0xCDC2, 0x777E,
+	0xCDC3, 0x7A3F, 0xCDC4, 0x7F94, 0xCDC5, 0x8003, 0xCDC6, 0x80A1,
+	0xCDC7, 0x818F, 0xCDC8, 0x82E6, 0xCDC9, 0x82FD, 0xCDCA, 0x83F0,
+	0xCDCB, 0x85C1, 0xCDCC, 0x8831, 0xCDCD, 0x88B4, 0xCDCE, 0x8AA5,
+	0xCDCF, 0xF903, 0xCDD0, 0x8F9C, 0xCDD1, 0x932E, 0xCDD2, 0x96C7,
+	0xCDD3, 0x9867, 0xCDD4, 0x9AD8, 0xCDD5, 0x9F13, 0xCDD6, 0x54ED,
+	0xCDD7, 0x659B, 0xCDD8, 0x66F2, 0xCDD9, 0x688F, 0xCDDA, 0x7A40,
+	0xCDDB, 0x8C37, 0xCDDC, 0x9D60, 0xCDDD, 0x56F0, 0xCDDE, 0x5764,
+	0xCDDF, 0x5D11, 0xCDE0, 0x6606, 0xCDE1, 0x68B1, 0xCDE2, 0x68CD,
+	0xCDE3, 0x6EFE, 0xCDE4, 0x7428, 0xCDE5, 0x889E, 0xCDE6, 0x9BE4,
+	0xCDE7, 0x6C68, 0xCDE8, 0xF904, 0xCDE9, 0x9AA8, 0xCDEA, 0x4F9B,
+	0xCDEB, 0x516C, 0xCDEC, 0x5171, 0xCDED, 0x529F, 0xCDEE, 0x5B54,
+	0xCDEF, 0x5DE5, 0xCDF0, 0x6050, 0xCDF1, 0x606D, 0xCDF2, 0x62F1,
+	0xCDF3, 0x63A7, 0xCDF4, 0x653B, 0xCDF5, 0x73D9, 0xCDF6, 0x7A7A,
+	0xCDF7, 0x86A3, 0xCDF8, 0x8CA2, 0xCDF9, 0x978F, 0xCDFA, 0x4E32,
+	0xCDFB, 0x5BE1, 0xCDFC, 0x6208, 0xCDFD, 0x679C, 0xCDFE, 0x74DC,
+	0xCEA1, 0x79D1, 0xCEA2, 0x83D3, 0xCEA3, 0x8A87, 0xCEA4, 0x8AB2,
+	0xCEA5, 0x8DE8, 0xCEA6, 0x904E, 0xCEA7, 0x934B, 0xCEA8, 0x9846,
+	0xCEA9, 0x5ED3, 0xCEAA, 0x69E8, 0xCEAB, 0x85FF, 0xCEAC, 0x90ED,
+	0xCEAD, 0xF905, 0xCEAE, 0x51A0, 0xCEAF, 0x5B98, 0xCEB0, 0x5BEC,
+	0xCEB1, 0x6163, 0xCEB2, 0x68FA, 0xCEB3, 0x6B3E, 0xCEB4, 0x704C,
+	0xCEB5, 0x742F, 0xCEB6, 0x74D8, 0xCEB7, 0x7BA1, 0xCEB8, 0x7F50,
+	0xCEB9, 0x83C5, 0xCEBA, 0x89C0, 0xCEBB, 0x8CAB, 0xCEBC, 0x95DC,
+	0xCEBD, 0x9928, 0xCEBE, 0x522E, 0xCEBF, 0x605D, 0xCEC0, 0x62EC,
+	0xCEC1, 0x9002, 0xCEC2, 0x4F8A, 0xCEC3, 0x5149, 0xCEC4, 0x5321,
+	0xCEC5, 0x58D9, 0xCEC6, 0x5EE3, 0xCEC7, 0x66E0, 0xCEC8, 0x6D38,
+	0xCEC9, 0x709A, 0xCECA, 0x72C2, 0xCECB, 0x73D6, 0xCECC, 0x7B50,
+	0xCECD, 0x80F1, 0xCECE, 0x945B, 0xCECF, 0x5366, 0xCED0, 0x639B,
+	0xCED1, 0x7F6B, 0xCED2, 0x4E56, 0xCED3, 0x5080, 0xCED4, 0x584A,
+	0xCED5, 0x58DE, 0xCED6, 0x602A, 0xCED7, 0x6127, 0xCED8, 0x62D0,
+	0xCED9, 0x69D0, 0xCEDA, 0x9B41, 0xCEDB, 0x5B8F, 0xCEDC, 0x7D18,
+	0xCEDD, 0x80B1, 0xCEDE, 0x8F5F, 0xCEDF, 0x4EA4, 0xCEE0, 0x50D1,
+	0xCEE1, 0x54AC, 0xCEE2, 0x55AC, 0xCEE3, 0x5B0C, 0xCEE4, 0x5DA0,
+	0xCEE5, 0x5DE7, 0xCEE6, 0x652A, 0xCEE7, 0x654E, 0xCEE8, 0x6821,
+	0xCEE9, 0x6A4B, 0xCEEA, 0x72E1, 0xCEEB, 0x768E, 0xCEEC, 0x77EF,
+	0xCEED, 0x7D5E, 0xCEEE, 0x7FF9, 0xCEEF, 0x81A0, 0xCEF0, 0x854E,
+	0xCEF1, 0x86DF, 0xCEF2, 0x8F03, 0xCEF3, 0x8F4E, 0xCEF4, 0x90CA,
+	0xCEF5, 0x9903, 0xCEF6, 0x9A55, 0xCEF7, 0x9BAB, 0xCEF8, 0x4E18,
+	0xCEF9, 0x4E45, 0xCEFA, 0x4E5D, 0xCEFB, 0x4EC7, 0xCEFC, 0x4FF1,
+	0xCEFD, 0x5177, 0xCEFE, 0x52FE, 0xCFA1, 0x5340, 0xCFA2, 0x53E3,
+	0xCFA3, 0x53E5, 0xCFA4, 0x548E, 0xCFA5, 0x5614, 0xCFA6, 0x5775,
+	0xCFA7, 0x57A2, 0xCFA8, 0x5BC7, 0xCFA9, 0x5D87, 0xCFAA, 0x5ED0,
+	0xCFAB, 0x61FC, 0xCFAC, 0x62D8, 0xCFAD, 0x6551, 0xCFAE, 0x67B8,
+	0xCFAF, 0x67E9, 0xCFB0, 0x69CB, 0xCFB1, 0x6B50, 0xCFB2, 0x6BC6,
+	0xCFB3, 0x6BEC, 0xCFB4, 0x6C42, 0xCFB5, 0x6E9D, 0xCFB6, 0x7078,
+	0xCFB7, 0x72D7, 0xCFB8, 0x7396, 0xCFB9, 0x7403, 0xCFBA, 0x77BF,
+	0xCFBB, 0x77E9, 0xCFBC, 0x7A76, 0xCFBD, 0x7D7F, 0xCFBE, 0x8009,
+	0xCFBF, 0x81FC, 0xCFC0, 0x8205, 0xCFC1, 0x820A, 0xCFC2, 0x82DF,
+	0xCFC3, 0x8862, 0xCFC4, 0x8B33, 0xCFC5, 0x8CFC, 0xCFC6, 0x8EC0,
+	0xCFC7, 0x9011, 0xCFC8, 0x90B1, 0xCFC9, 0x9264, 0xCFCA, 0x92B6,
+	0xCFCB, 0x99D2, 0xCFCC, 0x9A45, 0xCFCD, 0x9CE9, 0xCFCE, 0x9DD7,
+	0xCFCF, 0x9F9C, 0xCFD0, 0x570B, 0xCFD1, 0x5C40, 0xCFD2, 0x83CA,
+	0xCFD3, 0x97A0, 0xCFD4, 0x97AB, 0xCFD5, 0x9EB4, 0xCFD6, 0x541B,
+	0xCFD7, 0x7A98, 0xCFD8, 0x7FA4, 0xCFD9, 0x88D9, 0xCFDA, 0x8ECD,
+	0xCFDB, 0x90E1, 0xCFDC, 0x5800, 0xCFDD, 0x5C48, 0xCFDE, 0x6398,
+	0xCFDF, 0x7A9F, 0xCFE0, 0x5BAE, 0xCFE1, 0x5F13, 0xCFE2, 0x7A79,
+	0xCFE3, 0x7AAE, 0xCFE4, 0x828E, 0xCFE5, 0x8EAC, 0xCFE6, 0x5026,
+	0xCFE7, 0x5238, 0xCFE8, 0x52F8, 0xCFE9, 0x5377, 0xCFEA, 0x5708,
+	0xCFEB, 0x62F3, 0xCFEC, 0x6372, 0xCFED, 0x6B0A, 0xCFEE, 0x6DC3,
+	0xCFEF, 0x7737, 0xCFF0, 0x53A5, 0xCFF1, 0x7357, 0xCFF2, 0x8568,
+	0xCFF3, 0x8E76, 0xCFF4, 0x95D5, 0xCFF5, 0x673A, 0xCFF6, 0x6AC3,
+	0xCFF7, 0x6F70, 0xCFF8, 0x8A6D, 0xCFF9, 0x8ECC, 0xCFFA, 0x994B,
+	0xCFFB, 0xF906, 0xCFFC, 0x6677, 0xCFFD, 0x6B78, 0xCFFE, 0x8CB4,
+	0xD0A1, 0x9B3C, 0xD0A2, 0xF907, 0xD0A3, 0x53EB, 0xD0A4, 0x572D,
+	0xD0A5, 0x594E, 0xD0A6, 0x63C6, 0xD0A7, 0x69FB, 0xD0A8, 0x73EA,
+	0xD0A9, 0x7845, 0xD0AA, 0x7ABA, 0xD0AB, 0x7AC5, 0xD0AC, 0x7CFE,
+	0xD0AD, 0x8475, 0xD0AE, 0x898F, 0xD0AF, 0x8D73, 0xD0B0, 0x9035,
+	0xD0B1, 0x95A8, 0xD0B2, 0x52FB, 0xD0B3, 0x5747, 0xD0B4, 0x7547,
+	0xD0B5, 0x7B60, 0xD0B6, 0x83CC, 0xD0B7, 0x921E, 0xD0B8, 0xF908,
+	0xD0B9, 0x6A58, 0xD0BA, 0x514B, 0xD0BB, 0x524B, 0xD0BC, 0x5287,
+	0xD0BD, 0x621F, 0xD0BE, 0x68D8, 0xD0BF, 0x6975, 0xD0C0, 0x9699,
+	0xD0C1, 0x50C5, 0xD0C2, 0x52A4, 0xD0C3, 0x52E4, 0xD0C4, 0x61C3,
+	0xD0C5, 0x65A4, 0xD0C6, 0x6839, 0xD0C7, 0x69FF, 0xD0C8, 0x747E,
+	0xD0C9, 0x7B4B, 0xD0CA, 0x82B9, 0xD0CB, 0x83EB, 0xD0CC, 0x89B2,
+	0xD0CD, 0x8B39, 0xD0CE, 0x8FD1, 0xD0CF, 0x9949, 0xD0D0, 0xF909,
+	0xD0D1, 0x4ECA, 0xD0D2, 0x5997, 0xD0D3, 0x64D2, 0xD0D4, 0x6611,
+	0xD0D5, 0x6A8E, 0xD0D6, 0x7434, 0xD0D7, 0x7981, 0xD0D8, 0x79BD,
+	0xD0D9, 0x82A9, 0xD0DA, 0x887E, 0xD0DB, 0x887F, 0xD0DC, 0x895F,
+	0xD0DD, 0xF90A, 0xD0DE, 0x9326, 0xD0DF, 0x4F0B, 0xD0E0, 0x53CA,
+	0xD0E1, 0x6025, 0xD0E2, 0x6271, 0xD0E3, 0x6C72, 0xD0E4, 0x7D1A,
+	0xD0E5, 0x7D66, 0xD0E6, 0x4E98, 0xD0E7, 0x5162, 0xD0E8, 0x77DC,
+	0xD0E9, 0x80AF, 0xD0EA, 0x4F01, 0xD0EB, 0x4F0E, 0xD0EC, 0x5176,
+	0xD0ED, 0x5180, 0xD0EE, 0x55DC, 0xD0EF, 0x5668, 0xD0F0, 0x573B,
+	0xD0F1, 0x57FA, 0xD0F2, 0x57FC, 0xD0F3, 0x5914, 0xD0F4, 0x5947,
+	0xD0F5, 0x5993, 0xD0F6, 0x5BC4, 0xD0F7, 0x5C90, 0xD0F8, 0x5D0E,
+	0xD0F9, 0x5DF1, 0xD0FA, 0x5E7E, 0xD0FB, 0x5FCC, 0xD0FC, 0x6280,
+	0xD0FD, 0x65D7, 0xD0FE, 0x65E3, 0xD1A1, 0x671E, 0xD1A2, 0x671F,
+	0xD1A3, 0x675E, 0xD1A4, 0x68CB, 0xD1A5, 0x68C4, 0xD1A6, 0x6A5F,
+	0xD1A7, 0x6B3A, 0xD1A8, 0x6C23, 0xD1A9, 0x6C7D, 0xD1AA, 0x6C82,
+	0xD1AB, 0x6DC7, 0xD1AC, 0x7398, 0xD1AD, 0x7426, 0xD1AE, 0x742A,
+	0xD1AF, 0x7482, 0xD1B0, 0x74A3, 0xD1B1, 0x7578, 0xD1B2, 0x757F,
+	0xD1B3, 0x7881, 0xD1B4, 0x78EF, 0xD1B5, 0x7941, 0xD1B6, 0x7947,
+	0xD1B7, 0x7948, 0xD1B8, 0x797A, 0xD1B9, 0x7B95, 0xD1BA, 0x7D00,
+	0xD1BB, 0x7DBA, 0xD1BC, 0x7F88, 0xD1BD, 0x8006, 0xD1BE, 0x802D,
+	0xD1BF, 0x808C, 0xD1C0, 0x8A18, 0xD1C1, 0x8B4F, 0xD1C2, 0x8C48,
+	0xD1C3, 0x8D77, 0xD1C4, 0x9321, 0xD1C5, 0x9324, 0xD1C6, 0x98E2,
+	0xD1C7, 0x9951, 0xD1C8, 0x9A0E, 0xD1C9, 0x9A0F, 0xD1CA, 0x9A65,
+	0xD1CB, 0x9E92, 0xD1CC, 0x7DCA, 0xD1CD, 0x4F76, 0xD1CE, 0x5409,
+	0xD1CF, 0x62EE, 0xD1D0, 0x6854, 0xD1D1, 0x91D1, 0xD1D2, 0x55AB,
+	0xD1D3, 0x513A, 0xD1D4, 0xF90B, 0xD1D5, 0xF90C, 0xD1D6, 0x5A1C,
+	0xD1D7, 0x61E6, 0xD1D8, 0xF90D, 0xD1D9, 0x62CF, 0xD1DA, 0x62FF,
+	0xD1DB, 0xF90E, 0xD1DC, 0xF90F, 0xD1DD, 0xF910, 0xD1DE, 0xF911,
+	0xD1DF, 0xF912, 0xD1E0, 0xF913, 0xD1E1, 0x90A3, 0xD1E2, 0xF914,
+	0xD1E3, 0xF915, 0xD1E4, 0xF916, 0xD1E5, 0xF917, 0xD1E6, 0xF918,
+	0xD1E7, 0x8AFE, 0xD1E8, 0xF919, 0xD1E9, 0xF91A, 0xD1EA, 0xF91B,
+	0xD1EB, 0xF91C, 0xD1EC, 0x6696, 0xD1ED, 0xF91D, 0xD1EE, 0x7156,
+	0xD1EF, 0xF91E, 0xD1F0, 0xF91F, 0xD1F1, 0x96E3, 0xD1F2, 0xF920,
+	0xD1F3, 0x634F, 0xD1F4, 0x637A, 0xD1F5, 0x5357, 0xD1F6, 0xF921,
+	0xD1F7, 0x678F, 0xD1F8, 0x6960, 0xD1F9, 0x6E73, 0xD1FA, 0xF922,
+	0xD1FB, 0x7537, 0xD1FC, 0xF923, 0xD1FD, 0xF924, 0xD1FE, 0xF925,
+	0xD2A1, 0x7D0D, 0xD2A2, 0xF926, 0xD2A3, 0xF927, 0xD2A4, 0x8872,
+	0xD2A5, 0x56CA, 0xD2A6, 0x5A18, 0xD2A7, 0xF928, 0xD2A8, 0xF929,
+	0xD2A9, 0xF92A, 0xD2AA, 0xF92B, 0xD2AB, 0xF92C, 0xD2AC, 0x4E43,
+	0xD2AD, 0xF92D, 0xD2AE, 0x5167, 0xD2AF, 0x5948, 0xD2B0, 0x67F0,
+	0xD2B1, 0x8010, 0xD2B2, 0xF92E, 0xD2B3, 0x5973, 0xD2B4, 0x5E74,
+	0xD2B5, 0x649A, 0xD2B6, 0x79CA, 0xD2B7, 0x5FF5, 0xD2B8, 0x606C,
+	0xD2B9, 0x62C8, 0xD2BA, 0x637B, 0xD2BB, 0x5BE7, 0xD2BC, 0x5BD7,
+	0xD2BD, 0x52AA, 0xD2BE, 0xF92F, 0xD2BF, 0x5974, 0xD2C0, 0x5F29,
+	0xD2C1, 0x6012, 0xD2C2, 0xF930, 0xD2C3, 0xF931, 0xD2C4, 0xF932,
+	0xD2C5, 0x7459, 0xD2C6, 0xF933, 0xD2C7, 0xF934, 0xD2C8, 0xF935,
+	0xD2C9, 0xF936, 0xD2CA, 0xF937, 0xD2CB, 0xF938, 0xD2CC, 0x99D1,
+	0xD2CD, 0xF939, 0xD2CE, 0xF93A, 0xD2CF, 0xF93B, 0xD2D0, 0xF93C,
+	0xD2D1, 0xF93D, 0xD2D2, 0xF93E, 0xD2D3, 0xF93F, 0xD2D4, 0xF940,
+	0xD2D5, 0xF941, 0xD2D6, 0xF942, 0xD2D7, 0xF943, 0xD2D8, 0x6FC3,
+	0xD2D9, 0xF944, 0xD2DA, 0xF945, 0xD2DB, 0x81BF, 0xD2DC, 0x8FB2,
+	0xD2DD, 0x60F1, 0xD2DE, 0xF946, 0xD2DF, 0xF947, 0xD2E0, 0x8166,
+	0xD2E1, 0xF948, 0xD2E2, 0xF949, 0xD2E3, 0x5C3F, 0xD2E4, 0xF94A,
+	0xD2E5, 0xF94B, 0xD2E6, 0xF94C, 0xD2E7, 0xF94D, 0xD2E8, 0xF94E,
+	0xD2E9, 0xF94F, 0xD2EA, 0xF950, 0xD2EB, 0xF951, 0xD2EC, 0x5AE9,
+	0xD2ED, 0x8A25, 0xD2EE, 0x677B, 0xD2EF, 0x7D10, 0xD2F0, 0xF952,
+	0xD2F1, 0xF953, 0xD2F2, 0xF954, 0xD2F3, 0xF955, 0xD2F4, 0xF956,
+	0xD2F5, 0xF957, 0xD2F6, 0x80FD, 0xD2F7, 0xF958, 0xD2F8, 0xF959,
+	0xD2F9, 0x5C3C, 0xD2FA, 0x6CE5, 0xD2FB, 0x533F, 0xD2FC, 0x6EBA,
+	0xD2FD, 0x591A, 0xD2FE, 0x8336, 0xD3A1, 0x4E39, 0xD3A2, 0x4EB6,
+	0xD3A3, 0x4F46, 0xD3A4, 0x55AE, 0xD3A5, 0x5718, 0xD3A6, 0x58C7,
+	0xD3A7, 0x5F56, 0xD3A8, 0x65B7, 0xD3A9, 0x65E6, 0xD3AA, 0x6A80,
+	0xD3AB, 0x6BB5, 0xD3AC, 0x6E4D, 0xD3AD, 0x77ED, 0xD3AE, 0x7AEF,
+	0xD3AF, 0x7C1E, 0xD3B0, 0x7DDE, 0xD3B1, 0x86CB, 0xD3B2, 0x8892,
+	0xD3B3, 0x9132, 0xD3B4, 0x935B, 0xD3B5, 0x64BB, 0xD3B6, 0x6FBE,
+	0xD3B7, 0x737A, 0xD3B8, 0x75B8, 0xD3B9, 0x9054, 0xD3BA, 0x5556,
+	0xD3BB, 0x574D, 0xD3BC, 0x61BA, 0xD3BD, 0x64D4, 0xD3BE, 0x66C7,
+	0xD3BF, 0x6DE1, 0xD3C0, 0x6E5B, 0xD3C1, 0x6F6D, 0xD3C2, 0x6FB9,
+	0xD3C3, 0x75F0, 0xD3C4, 0x8043, 0xD3C5, 0x81BD, 0xD3C6, 0x8541,
+	0xD3C7, 0x8983, 0xD3C8, 0x8AC7, 0xD3C9, 0x8B5A, 0xD3CA, 0x931F,
+	0xD3CB, 0x6C93, 0xD3CC, 0x7553, 0xD3CD, 0x7B54, 0xD3CE, 0x8E0F,
+	0xD3CF, 0x905D, 0xD3D0, 0x5510, 0xD3D1, 0x5802, 0xD3D2, 0x5858,
+	0xD3D3, 0x5E62, 0xD3D4, 0x6207, 0xD3D5, 0x649E, 0xD3D6, 0x68E0,
+	0xD3D7, 0x7576, 0xD3D8, 0x7CD6, 0xD3D9, 0x87B3, 0xD3DA, 0x9EE8,
+	0xD3DB, 0x4EE3, 0xD3DC, 0x5788, 0xD3DD, 0x576E, 0xD3DE, 0x5927,
+	0xD3DF, 0x5C0D, 0xD3E0, 0x5CB1, 0xD3E1, 0x5E36, 0xD3E2, 0x5F85,
+	0xD3E3, 0x6234, 0xD3E4, 0x64E1, 0xD3E5, 0x73B3, 0xD3E6, 0x81FA,
+	0xD3E7, 0x888B, 0xD3E8, 0x8CB8, 0xD3E9, 0x968A, 0xD3EA, 0x9EDB,
+	0xD3EB, 0x5B85, 0xD3EC, 0x5FB7, 0xD3ED, 0x60B3, 0xD3EE, 0x5012,
+	0xD3EF, 0x5200, 0xD3F0, 0x5230, 0xD3F1, 0x5716, 0xD3F2, 0x5835,
+	0xD3F3, 0x5857, 0xD3F4, 0x5C0E, 0xD3F5, 0x5C60, 0xD3F6, 0x5CF6,
+	0xD3F7, 0x5D8B, 0xD3F8, 0x5EA6, 0xD3F9, 0x5F92, 0xD3FA, 0x60BC,
+	0xD3FB, 0x6311, 0xD3FC, 0x6389, 0xD3FD, 0x6417, 0xD3FE, 0x6843,
+	0xD4A1, 0x68F9, 0xD4A2, 0x6AC2, 0xD4A3, 0x6DD8, 0xD4A4, 0x6E21,
+	0xD4A5, 0x6ED4, 0xD4A6, 0x6FE4, 0xD4A7, 0x71FE, 0xD4A8, 0x76DC,
+	0xD4A9, 0x7779, 0xD4AA, 0x79B1, 0xD4AB, 0x7A3B, 0xD4AC, 0x8404,
+	0xD4AD, 0x89A9, 0xD4AE, 0x8CED, 0xD4AF, 0x8DF3, 0xD4B0, 0x8E48,
+	0xD4B1, 0x9003, 0xD4B2, 0x9014, 0xD4B3, 0x9053, 0xD4B4, 0x90FD,
+	0xD4B5, 0x934D, 0xD4B6, 0x9676, 0xD4B7, 0x97DC, 0xD4B8, 0x6BD2,
+	0xD4B9, 0x7006, 0xD4BA, 0x7258, 0xD4BB, 0x72A2, 0xD4BC, 0x7368,
+	0xD4BD, 0x7763, 0xD4BE, 0x79BF, 0xD4BF, 0x7BE4, 0xD4C0, 0x7E9B,
+	0xD4C1, 0x8B80, 0xD4C2, 0x58A9, 0xD4C3, 0x60C7, 0xD4C4, 0x6566,
+	0xD4C5, 0x65FD, 0xD4C6, 0x66BE, 0xD4C7, 0x6C8C, 0xD4C8, 0x711E,
+	0xD4C9, 0x71C9, 0xD4CA, 0x8C5A, 0xD4CB, 0x9813, 0xD4CC, 0x4E6D,
+	0xD4CD, 0x7A81, 0xD4CE, 0x4EDD, 0xD4CF, 0x51AC, 0xD4D0, 0x51CD,
+	0xD4D1, 0x52D5, 0xD4D2, 0x540C, 0xD4D3, 0x61A7, 0xD4D4, 0x6771,
+	0xD4D5, 0x6850, 0xD4D6, 0x68DF, 0xD4D7, 0x6D1E, 0xD4D8, 0x6F7C,
+	0xD4D9, 0x75BC, 0xD4DA, 0x77B3, 0xD4DB, 0x7AE5, 0xD4DC, 0x80F4,
+	0xD4DD, 0x8463, 0xD4DE, 0x9285, 0xD4DF, 0x515C, 0xD4E0, 0x6597,
+	0xD4E1, 0x675C, 0xD4E2, 0x6793, 0xD4E3, 0x75D8, 0xD4E4, 0x7AC7,
+	0xD4E5, 0x8373, 0xD4E6, 0xF95A, 0xD4E7, 0x8C46, 0xD4E8, 0x9017,
+	0xD4E9, 0x982D, 0xD4EA, 0x5C6F, 0xD4EB, 0x81C0, 0xD4EC, 0x829A,
+	0xD4ED, 0x9041, 0xD4EE, 0x906F, 0xD4EF, 0x920D, 0xD4F0, 0x5F97,
+	0xD4F1, 0x5D9D, 0xD4F2, 0x6A59, 0xD4F3, 0x71C8, 0xD4F4, 0x767B,
+	0xD4F5, 0x7B49, 0xD4F6, 0x85E4, 0xD4F7, 0x8B04, 0xD4F8, 0x9127,
+	0xD4F9, 0x9A30, 0xD4FA, 0x5587, 0xD4FB, 0x61F6, 0xD4FC, 0xF95B,
+	0xD4FD, 0x7669, 0xD4FE, 0x7F85, 0xD5A1, 0x863F, 0xD5A2, 0x87BA,
+	0xD5A3, 0x88F8, 0xD5A4, 0x908F, 0xD5A5, 0xF95C, 0xD5A6, 0x6D1B,
+	0xD5A7, 0x70D9, 0xD5A8, 0x73DE, 0xD5A9, 0x7D61, 0xD5AA, 0x843D,
+	0xD5AB, 0xF95D, 0xD5AC, 0x916A, 0xD5AD, 0x99F1, 0xD5AE, 0xF95E,
+	0xD5AF, 0x4E82, 0xD5B0, 0x5375, 0xD5B1, 0x6B04, 0xD5B2, 0x6B12,
+	0xD5B3, 0x703E, 0xD5B4, 0x721B, 0xD5B5, 0x862D, 0xD5B6, 0x9E1E,
+	0xD5B7, 0x524C, 0xD5B8, 0x8FA3, 0xD5B9, 0x5D50, 0xD5BA, 0x64E5,
+	0xD5BB, 0x652C, 0xD5BC, 0x6B16, 0xD5BD, 0x6FEB, 0xD5BE, 0x7C43,
+	0xD5BF, 0x7E9C, 0xD5C0, 0x85CD, 0xD5C1, 0x8964, 0xD5C2, 0x89BD,
+	0xD5C3, 0x62C9, 0xD5C4, 0x81D8, 0xD5C5, 0x881F, 0xD5C6, 0x5ECA,
+	0xD5C7, 0x6717, 0xD5C8, 0x6D6A, 0xD5C9, 0x72FC, 0xD5CA, 0x7405,
+	0xD5CB, 0x746F, 0xD5CC, 0x8782, 0xD5CD, 0x90DE, 0xD5CE, 0x4F86,
+	0xD5CF, 0x5D0D, 0xD5D0, 0x5FA0, 0xD5D1, 0x840A, 0xD5D2, 0x51B7,
+	0xD5D3, 0x63A0, 0xD5D4, 0x7565, 0xD5D5, 0x4EAE, 0xD5D6, 0x5006,
+	0xD5D7, 0x5169, 0xD5D8, 0x51C9, 0xD5D9, 0x6881, 0xD5DA, 0x6A11,
+	0xD5DB, 0x7CAE, 0xD5DC, 0x7CB1, 0xD5DD, 0x7CE7, 0xD5DE, 0x826F,
+	0xD5DF, 0x8AD2, 0xD5E0, 0x8F1B, 0xD5E1, 0x91CF, 0xD5E2, 0x4FB6,
+	0xD5E3, 0x5137, 0xD5E4, 0x52F5, 0xD5E5, 0x5442, 0xD5E6, 0x5EEC,
+	0xD5E7, 0x616E, 0xD5E8, 0x623E, 0xD5E9, 0x65C5, 0xD5EA, 0x6ADA,
+	0xD5EB, 0x6FFE, 0xD5EC, 0x792A, 0xD5ED, 0x85DC, 0xD5EE, 0x8823,
+	0xD5EF, 0x95AD, 0xD5F0, 0x9A62, 0xD5F1, 0x9A6A, 0xD5F2, 0x9E97,
+	0xD5F3, 0x9ECE, 0xD5F4, 0x529B, 0xD5F5, 0x66C6, 0xD5F6, 0x6B77,
+	0xD5F7, 0x701D, 0xD5F8, 0x792B, 0xD5F9, 0x8F62, 0xD5FA, 0x9742,
+	0xD5FB, 0x6190, 0xD5FC, 0x6200, 0xD5FD, 0x6523, 0xD5FE, 0x6F23,
+	0xD6A1, 0x7149, 0xD6A2, 0x7489, 0xD6A3, 0x7DF4, 0xD6A4, 0x806F,
+	0xD6A5, 0x84EE, 0xD6A6, 0x8F26, 0xD6A7, 0x9023, 0xD6A8, 0x934A,
+	0xD6A9, 0x51BD, 0xD6AA, 0x5217, 0xD6AB, 0x52A3, 0xD6AC, 0x6D0C,
+	0xD6AD, 0x70C8, 0xD6AE, 0x88C2, 0xD6AF, 0x5EC9, 0xD6B0, 0x6582,
+	0xD6B1, 0x6BAE, 0xD6B2, 0x6FC2, 0xD6B3, 0x7C3E, 0xD6B4, 0x7375,
+	0xD6B5, 0x4EE4, 0xD6B6, 0x4F36, 0xD6B7, 0x56F9, 0xD6B8, 0xF95F,
+	0xD6B9, 0x5CBA, 0xD6BA, 0x5DBA, 0xD6BB, 0x601C, 0xD6BC, 0x73B2,
+	0xD6BD, 0x7B2D, 0xD6BE, 0x7F9A, 0xD6BF, 0x7FCE, 0xD6C0, 0x8046,
+	0xD6C1, 0x901E, 0xD6C2, 0x9234, 0xD6C3, 0x96F6, 0xD6C4, 0x9748,
+	0xD6C5, 0x9818, 0xD6C6, 0x9F61, 0xD6C7, 0x4F8B, 0xD6C8, 0x6FA7,
+	0xD6C9, 0x79AE, 0xD6CA, 0x91B4, 0xD6CB, 0x96B7, 0xD6CC, 0x52DE,
+	0xD6CD, 0xF960, 0xD6CE, 0x6488, 0xD6CF, 0x64C4, 0xD6D0, 0x6AD3,
+	0xD6D1, 0x6F5E, 0xD6D2, 0x7018, 0xD6D3, 0x7210, 0xD6D4, 0x76E7,
+	0xD6D5, 0x8001, 0xD6D6, 0x8606, 0xD6D7, 0x865C, 0xD6D8, 0x8DEF,
+	0xD6D9, 0x8F05, 0xD6DA, 0x9732, 0xD6DB, 0x9B6F, 0xD6DC, 0x9DFA,
+	0xD6DD, 0x9E75, 0xD6DE, 0x788C, 0xD6DF, 0x797F, 0xD6E0, 0x7DA0,
+	0xD6E1, 0x83C9, 0xD6E2, 0x9304, 0xD6E3, 0x9E7F, 0xD6E4, 0x9E93,
+	0xD6E5, 0x8AD6, 0xD6E6, 0x58DF, 0xD6E7, 0x5F04, 0xD6E8, 0x6727,
+	0xD6E9, 0x7027, 0xD6EA, 0x74CF, 0xD6EB, 0x7C60, 0xD6EC, 0x807E,
+	0xD6ED, 0x5121, 0xD6EE, 0x7028, 0xD6EF, 0x7262, 0xD6F0, 0x78CA,
+	0xD6F1, 0x8CC2, 0xD6F2, 0x8CDA, 0xD6F3, 0x8CF4, 0xD6F4, 0x96F7,
+	0xD6F5, 0x4E86, 0xD6F6, 0x50DA, 0xD6F7, 0x5BEE, 0xD6F8, 0x5ED6,
+	0xD6F9, 0x6599, 0xD6FA, 0x71CE, 0xD6FB, 0x7642, 0xD6FC, 0x77AD,
+	0xD6FD, 0x804A, 0xD6FE, 0x84FC, 0xD7A1, 0x907C, 0xD7A2, 0x9B27,
+	0xD7A3, 0x9F8D, 0xD7A4, 0x58D8, 0xD7A5, 0x5A41, 0xD7A6, 0x5C62,
+	0xD7A7, 0x6A13, 0xD7A8, 0x6DDA, 0xD7A9, 0x6F0F, 0xD7AA, 0x763B,
+	0xD7AB, 0x7D2F, 0xD7AC, 0x7E37, 0xD7AD, 0x851E, 0xD7AE, 0x8938,
+	0xD7AF, 0x93E4, 0xD7B0, 0x964B, 0xD7B1, 0x5289, 0xD7B2, 0x65D2,
+	0xD7B3, 0x67F3, 0xD7B4, 0x69B4, 0xD7B5, 0x6D41, 0xD7B6, 0x6E9C,
+	0xD7B7, 0x700F, 0xD7B8, 0x7409, 0xD7B9, 0x7460, 0xD7BA, 0x7559,
+	0xD7BB, 0x7624, 0xD7BC, 0x786B, 0xD7BD, 0x8B2C, 0xD7BE, 0x985E,
+	0xD7BF, 0x516D, 0xD7C0, 0x622E, 0xD7C1, 0x9678, 0xD7C2, 0x4F96,
+	0xD7C3, 0x502B, 0xD7C4, 0x5D19, 0xD7C5, 0x6DEA, 0xD7C6, 0x7DB8,
+	0xD7C7, 0x8F2A, 0xD7C8, 0x5F8B, 0xD7C9, 0x6144, 0xD7CA, 0x6817,
+	0xD7CB, 0xF961, 0xD7CC, 0x9686, 0xD7CD, 0x52D2, 0xD7CE, 0x808B,
+	0xD7CF, 0x51DC, 0xD7D0, 0x51CC, 0xD7D1, 0x695E, 0xD7D2, 0x7A1C,
+	0xD7D3, 0x7DBE, 0xD7D4, 0x83F1, 0xD7D5, 0x9675, 0xD7D6, 0x4FDA,
+	0xD7D7, 0x5229, 0xD7D8, 0x5398, 0xD7D9, 0x540F, 0xD7DA, 0x550E,
+	0xD7DB, 0x5C65, 0xD7DC, 0x60A7, 0xD7DD, 0x674E, 0xD7DE, 0x68A8,
+	0xD7DF, 0x6D6C, 0xD7E0, 0x7281, 0xD7E1, 0x72F8, 0xD7E2, 0x7406,
+	0xD7E3, 0x7483, 0xD7E4, 0xF962, 0xD7E5, 0x75E2, 0xD7E6, 0x7C6C,
+	0xD7E7, 0x7F79, 0xD7E8, 0x7FB8, 0xD7E9, 0x8389, 0xD7EA, 0x88CF,
+	0xD7EB, 0x88E1, 0xD7EC, 0x91CC, 0xD7ED, 0x91D0, 0xD7EE, 0x96E2,
+	0xD7EF, 0x9BC9, 0xD7F0, 0x541D, 0xD7F1, 0x6F7E, 0xD7F2, 0x71D0,
+	0xD7F3, 0x7498, 0xD7F4, 0x85FA, 0xD7F5, 0x8EAA, 0xD7F6, 0x96A3,
+	0xD7F7, 0x9C57, 0xD7F8, 0x9E9F, 0xD7F9, 0x6797, 0xD7FA, 0x6DCB,
+	0xD7FB, 0x7433, 0xD7FC, 0x81E8, 0xD7FD, 0x9716, 0xD7FE, 0x782C,
+	0xD8A1, 0x7ACB, 0xD8A2, 0x7B20, 0xD8A3, 0x7C92, 0xD8A4, 0x6469,
+	0xD8A5, 0x746A, 0xD8A6, 0x75F2, 0xD8A7, 0x78BC, 0xD8A8, 0x78E8,
+	0xD8A9, 0x99AC, 0xD8AA, 0x9B54, 0xD8AB, 0x9EBB, 0xD8AC, 0x5BDE,
+	0xD8AD, 0x5E55, 0xD8AE, 0x6F20, 0xD8AF, 0x819C, 0xD8B0, 0x83AB,
+	0xD8B1, 0x9088, 0xD8B2, 0x4E07, 0xD8B3, 0x534D, 0xD8B4, 0x5A29,
+	0xD8B5, 0x5DD2, 0xD8B6, 0x5F4E, 0xD8B7, 0x6162, 0xD8B8, 0x633D,
+	0xD8B9, 0x6669, 0xD8BA, 0x66FC, 0xD8BB, 0x6EFF, 0xD8BC, 0x6F2B,
+	0xD8BD, 0x7063, 0xD8BE, 0x779E, 0xD8BF, 0x842C, 0xD8C0, 0x8513,
+	0xD8C1, 0x883B, 0xD8C2, 0x8F13, 0xD8C3, 0x9945, 0xD8C4, 0x9C3B,
+	0xD8C5, 0x551C, 0xD8C6, 0x62B9, 0xD8C7, 0x672B, 0xD8C8, 0x6CAB,
+	0xD8C9, 0x8309, 0xD8CA, 0x896A, 0xD8CB, 0x977A, 0xD8CC, 0x4EA1,
+	0xD8CD, 0x5984, 0xD8CE, 0x5FD8, 0xD8CF, 0x5FD9, 0xD8D0, 0x671B,
+	0xD8D1, 0x7DB2, 0xD8D2, 0x7F54, 0xD8D3, 0x8292, 0xD8D4, 0x832B,
+	0xD8D5, 0x83BD, 0xD8D6, 0x8F1E, 0xD8D7, 0x9099, 0xD8D8, 0x57CB,
+	0xD8D9, 0x59B9, 0xD8DA, 0x5A92, 0xD8DB, 0x5BD0, 0xD8DC, 0x6627,
+	0xD8DD, 0x679A, 0xD8DE, 0x6885, 0xD8DF, 0x6BCF, 0xD8E0, 0x7164,
+	0xD8E1, 0x7F75, 0xD8E2, 0x8CB7, 0xD8E3, 0x8CE3, 0xD8E4, 0x9081,
+	0xD8E5, 0x9B45, 0xD8E6, 0x8108, 0xD8E7, 0x8C8A, 0xD8E8, 0x964C,
+	0xD8E9, 0x9A40, 0xD8EA, 0x9EA5, 0xD8EB, 0x5B5F, 0xD8EC, 0x6C13,
+	0xD8ED, 0x731B, 0xD8EE, 0x76F2, 0xD8EF, 0x76DF, 0xD8F0, 0x840C,
+	0xD8F1, 0x51AA, 0xD8F2, 0x8993, 0xD8F3, 0x514D, 0xD8F4, 0x5195,
+	0xD8F5, 0x52C9, 0xD8F6, 0x68C9, 0xD8F7, 0x6C94, 0xD8F8, 0x7704,
+	0xD8F9, 0x7720, 0xD8FA, 0x7DBF, 0xD8FB, 0x7DEC, 0xD8FC, 0x9762,
+	0xD8FD, 0x9EB5, 0xD8FE, 0x6EC5, 0xD9A1, 0x8511, 0xD9A2, 0x51A5,
+	0xD9A3, 0x540D, 0xD9A4, 0x547D, 0xD9A5, 0x660E, 0xD9A6, 0x669D,
+	0xD9A7, 0x6927, 0xD9A8, 0x6E9F, 0xD9A9, 0x76BF, 0xD9AA, 0x7791,
+	0xD9AB, 0x8317, 0xD9AC, 0x84C2, 0xD9AD, 0x879F, 0xD9AE, 0x9169,
+	0xD9AF, 0x9298, 0xD9B0, 0x9CF4, 0xD9B1, 0x8882, 0xD9B2, 0x4FAE,
+	0xD9B3, 0x5192, 0xD9B4, 0x52DF, 0xD9B5, 0x59C6, 0xD9B6, 0x5E3D,
+	0xD9B7, 0x6155, 0xD9B8, 0x6478, 0xD9B9, 0x6479, 0xD9BA, 0x66AE,
+	0xD9BB, 0x67D0, 0xD9BC, 0x6A21, 0xD9BD, 0x6BCD, 0xD9BE, 0x6BDB,
+	0xD9BF, 0x725F, 0xD9C0, 0x7261, 0xD9C1, 0x7441, 0xD9C2, 0x7738,
+	0xD9C3, 0x77DB, 0xD9C4, 0x8017, 0xD9C5, 0x82BC, 0xD9C6, 0x8305,
+	0xD9C7, 0x8B00, 0xD9C8, 0x8B28, 0xD9C9, 0x8C8C, 0xD9CA, 0x6728,
+	0xD9CB, 0x6C90, 0xD9CC, 0x7267, 0xD9CD, 0x76EE, 0xD9CE, 0x7766,
+	0xD9CF, 0x7A46, 0xD9D0, 0x9DA9, 0xD9D1, 0x6B7F, 0xD9D2, 0x6C92,
+	0xD9D3, 0x5922, 0xD9D4, 0x6726, 0xD9D5, 0x8499, 0xD9D6, 0x536F,
+	0xD9D7, 0x5893, 0xD9D8, 0x5999, 0xD9D9, 0x5EDF, 0xD9DA, 0x63CF,
+	0xD9DB, 0x6634, 0xD9DC, 0x6773, 0xD9DD, 0x6E3A, 0xD9DE, 0x732B,
+	0xD9DF, 0x7AD7, 0xD9E0, 0x82D7, 0xD9E1, 0x9328, 0xD9E2, 0x52D9,
+	0xD9E3, 0x5DEB, 0xD9E4, 0x61AE, 0xD9E5, 0x61CB, 0xD9E6, 0x620A,
+	0xD9E7, 0x62C7, 0xD9E8, 0x64AB, 0xD9E9, 0x65E0, 0xD9EA, 0x6959,
+	0xD9EB, 0x6B66, 0xD9EC, 0x6BCB, 0xD9ED, 0x7121, 0xD9EE, 0x73F7,
+	0xD9EF, 0x755D, 0xD9F0, 0x7E46, 0xD9F1, 0x821E, 0xD9F2, 0x8302,
+	0xD9F3, 0x856A, 0xD9F4, 0x8AA3, 0xD9F5, 0x8CBF, 0xD9F6, 0x9727,
+	0xD9F7, 0x9D61, 0xD9F8, 0x58A8, 0xD9F9, 0x9ED8, 0xD9FA, 0x5011,
+	0xD9FB, 0x520E, 0xD9FC, 0x543B, 0xD9FD, 0x554F, 0xD9FE, 0x6587,
+	0xDAA1, 0x6C76, 0xDAA2, 0x7D0A, 0xDAA3, 0x7D0B, 0xDAA4, 0x805E,
+	0xDAA5, 0x868A, 0xDAA6, 0x9580, 0xDAA7, 0x96EF, 0xDAA8, 0x52FF,
+	0xDAA9, 0x6C95, 0xDAAA, 0x7269, 0xDAAB, 0x5473, 0xDAAC, 0x5A9A,
+	0xDAAD, 0x5C3E, 0xDAAE, 0x5D4B, 0xDAAF, 0x5F4C, 0xDAB0, 0x5FAE,
+	0xDAB1, 0x672A, 0xDAB2, 0x68B6, 0xDAB3, 0x6963, 0xDAB4, 0x6E3C,
+	0xDAB5, 0x6E44, 0xDAB6, 0x7709, 0xDAB7, 0x7C73, 0xDAB8, 0x7F8E,
+	0xDAB9, 0x8587, 0xDABA, 0x8B0E, 0xDABB, 0x8FF7, 0xDABC, 0x9761,
+	0xDABD, 0x9EF4, 0xDABE, 0x5CB7, 0xDABF, 0x60B6, 0xDAC0, 0x610D,
+	0xDAC1, 0x61AB, 0xDAC2, 0x654F, 0xDAC3, 0x65FB, 0xDAC4, 0x65FC,
+	0xDAC5, 0x6C11, 0xDAC6, 0x6CEF, 0xDAC7, 0x739F, 0xDAC8, 0x73C9,
+	0xDAC9, 0x7DE1, 0xDACA, 0x9594, 0xDACB, 0x5BC6, 0xDACC, 0x871C,
+	0xDACD, 0x8B10, 0xDACE, 0x525D, 0xDACF, 0x535A, 0xDAD0, 0x62CD,
+	0xDAD1, 0x640F, 0xDAD2, 0x64B2, 0xDAD3, 0x6734, 0xDAD4, 0x6A38,
+	0xDAD5, 0x6CCA, 0xDAD6, 0x73C0, 0xDAD7, 0x749E, 0xDAD8, 0x7B94,
+	0xDAD9, 0x7C95, 0xDADA, 0x7E1B, 0xDADB, 0x818A, 0xDADC, 0x8236,
+	0xDADD, 0x8584, 0xDADE, 0x8FEB, 0xDADF, 0x96F9, 0xDAE0, 0x99C1,
+	0xDAE1, 0x4F34, 0xDAE2, 0x534A, 0xDAE3, 0x53CD, 0xDAE4, 0x53DB,
+	0xDAE5, 0x62CC, 0xDAE6, 0x642C, 0xDAE7, 0x6500, 0xDAE8, 0x6591,
+	0xDAE9, 0x69C3, 0xDAEA, 0x6CEE, 0xDAEB, 0x6F58, 0xDAEC, 0x73ED,
+	0xDAED, 0x7554, 0xDAEE, 0x7622, 0xDAEF, 0x76E4, 0xDAF0, 0x76FC,
+	0xDAF1, 0x78D0, 0xDAF2, 0x78FB, 0xDAF3, 0x792C, 0xDAF4, 0x7D46,
+	0xDAF5, 0x822C, 0xDAF6, 0x87E0, 0xDAF7, 0x8FD4, 0xDAF8, 0x9812,
+	0xDAF9, 0x98EF, 0xDAFA, 0x52C3, 0xDAFB, 0x62D4, 0xDAFC, 0x64A5,
+	0xDAFD, 0x6E24, 0xDAFE, 0x6F51, 0xDBA1, 0x767C, 0xDBA2, 0x8DCB,
+	0xDBA3, 0x91B1, 0xDBA4, 0x9262, 0xDBA5, 0x9AEE, 0xDBA6, 0x9B43,
+	0xDBA7, 0x5023, 0xDBA8, 0x508D, 0xDBA9, 0x574A, 0xDBAA, 0x59A8,
+	0xDBAB, 0x5C28, 0xDBAC, 0x5E47, 0xDBAD, 0x5F77, 0xDBAE, 0x623F,
+	0xDBAF, 0x653E, 0xDBB0, 0x65B9, 0xDBB1, 0x65C1, 0xDBB2, 0x6609,
+	0xDBB3, 0x678B, 0xDBB4, 0x699C, 0xDBB5, 0x6EC2, 0xDBB6, 0x78C5,
+	0xDBB7, 0x7D21, 0xDBB8, 0x80AA, 0xDBB9, 0x8180, 0xDBBA, 0x822B,
+	0xDBBB, 0x82B3, 0xDBBC, 0x84A1, 0xDBBD, 0x868C, 0xDBBE, 0x8A2A,
+	0xDBBF, 0x8B17, 0xDBC0, 0x90A6, 0xDBC1, 0x9632, 0xDBC2, 0x9F90,
+	0xDBC3, 0x500D, 0xDBC4, 0x4FF3, 0xDBC5, 0xF963, 0xDBC6, 0x57F9,
+	0xDBC7, 0x5F98, 0xDBC8, 0x62DC, 0xDBC9, 0x6392, 0xDBCA, 0x676F,
+	0xDBCB, 0x6E43, 0xDBCC, 0x7119, 0xDBCD, 0x76C3, 0xDBCE, 0x80CC,
+	0xDBCF, 0x80DA, 0xDBD0, 0x88F4, 0xDBD1, 0x88F5, 0xDBD2, 0x8919,
+	0xDBD3, 0x8CE0, 0xDBD4, 0x8F29, 0xDBD5, 0x914D, 0xDBD6, 0x966A,
+	0xDBD7, 0x4F2F, 0xDBD8, 0x4F70, 0xDBD9, 0x5E1B, 0xDBDA, 0x67CF,
+	0xDBDB, 0x6822, 0xDBDC, 0x767D, 0xDBDD, 0x767E, 0xDBDE, 0x9B44,
+	0xDBDF, 0x5E61, 0xDBE0, 0x6A0A, 0xDBE1, 0x7169, 0xDBE2, 0x71D4,
+	0xDBE3, 0x756A, 0xDBE4, 0xF964, 0xDBE5, 0x7E41, 0xDBE6, 0x8543,
+	0xDBE7, 0x85E9, 0xDBE8, 0x98DC, 0xDBE9, 0x4F10, 0xDBEA, 0x7B4F,
+	0xDBEB, 0x7F70, 0xDBEC, 0x95A5, 0xDBED, 0x51E1, 0xDBEE, 0x5E06,
+	0xDBEF, 0x68B5, 0xDBF0, 0x6C3E, 0xDBF1, 0x6C4E, 0xDBF2, 0x6CDB,
+	0xDBF3, 0x72AF, 0xDBF4, 0x7BC4, 0xDBF5, 0x8303, 0xDBF6, 0x6CD5,
+	0xDBF7, 0x743A, 0xDBF8, 0x50FB, 0xDBF9, 0x5288, 0xDBFA, 0x58C1,
+	0xDBFB, 0x64D8, 0xDBFC, 0x6A97, 0xDBFD, 0x74A7, 0xDBFE, 0x7656,
+	0xDCA1, 0x78A7, 0xDCA2, 0x8617, 0xDCA3, 0x95E2, 0xDCA4, 0x9739,
+	0xDCA5, 0xF965, 0xDCA6, 0x535E, 0xDCA7, 0x5F01, 0xDCA8, 0x8B8A,
+	0xDCA9, 0x8FA8, 0xDCAA, 0x8FAF, 0xDCAB, 0x908A, 0xDCAC, 0x5225,
+	0xDCAD, 0x77A5, 0xDCAE, 0x9C49, 0xDCAF, 0x9F08, 0xDCB0, 0x4E19,
+	0xDCB1, 0x5002, 0xDCB2, 0x5175, 0xDCB3, 0x5C5B, 0xDCB4, 0x5E77,
+	0xDCB5, 0x661E, 0xDCB6, 0x663A, 0xDCB7, 0x67C4, 0xDCB8, 0x68C5,
+	0xDCB9, 0x70B3, 0xDCBA, 0x7501, 0xDCBB, 0x75C5, 0xDCBC, 0x79C9,
+	0xDCBD, 0x7ADD, 0xDCBE, 0x8F27, 0xDCBF, 0x9920, 0xDCC0, 0x9A08,
+	0xDCC1, 0x4FDD, 0xDCC2, 0x5821, 0xDCC3, 0x5831, 0xDCC4, 0x5BF6,
+	0xDCC5, 0x666E, 0xDCC6, 0x6B65, 0xDCC7, 0x6D11, 0xDCC8, 0x6E7A,
+	0xDCC9, 0x6F7D, 0xDCCA, 0x73E4, 0xDCCB, 0x752B, 0xDCCC, 0x83E9,
+	0xDCCD, 0x88DC, 0xDCCE, 0x8913, 0xDCCF, 0x8B5C, 0xDCD0, 0x8F14,
+	0xDCD1, 0x4F0F, 0xDCD2, 0x50D5, 0xDCD3, 0x5310, 0xDCD4, 0x535C,
+	0xDCD5, 0x5B93, 0xDCD6, 0x5FA9, 0xDCD7, 0x670D, 0xDCD8, 0x798F,
+	0xDCD9, 0x8179, 0xDCDA, 0x832F, 0xDCDB, 0x8514, 0xDCDC, 0x8907,
+	0xDCDD, 0x8986, 0xDCDE, 0x8F39, 0xDCDF, 0x8F3B, 0xDCE0, 0x99A5,
+	0xDCE1, 0x9C12, 0xDCE2, 0x672C, 0xDCE3, 0x4E76, 0xDCE4, 0x4FF8,
+	0xDCE5, 0x5949, 0xDCE6, 0x5C01, 0xDCE7, 0x5CEF, 0xDCE8, 0x5CF0,
+	0xDCE9, 0x6367, 0xDCEA, 0x68D2, 0xDCEB, 0x70FD, 0xDCEC, 0x71A2,
+	0xDCED, 0x742B, 0xDCEE, 0x7E2B, 0xDCEF, 0x84EC, 0xDCF0, 0x8702,
+	0xDCF1, 0x9022, 0xDCF2, 0x92D2, 0xDCF3, 0x9CF3, 0xDCF4, 0x4E0D,
+	0xDCF5, 0x4ED8, 0xDCF6, 0x4FEF, 0xDCF7, 0x5085, 0xDCF8, 0x5256,
+	0xDCF9, 0x526F, 0xDCFA, 0x5426, 0xDCFB, 0x5490, 0xDCFC, 0x57E0,
+	0xDCFD, 0x592B, 0xDCFE, 0x5A66, 0xDDA1, 0x5B5A, 0xDDA2, 0x5B75,
+	0xDDA3, 0x5BCC, 0xDDA4, 0x5E9C, 0xDDA5, 0xF966, 0xDDA6, 0x6276,
+	0xDDA7, 0x6577, 0xDDA8, 0x65A7, 0xDDA9, 0x6D6E, 0xDDAA, 0x6EA5,
+	0xDDAB, 0x7236, 0xDDAC, 0x7B26, 0xDDAD, 0x7C3F, 0xDDAE, 0x7F36,
+	0xDDAF, 0x8150, 0xDDB0, 0x8151, 0xDDB1, 0x819A, 0xDDB2, 0x8240,
+	0xDDB3, 0x8299, 0xDDB4, 0x83A9, 0xDDB5, 0x8A03, 0xDDB6, 0x8CA0,
+	0xDDB7, 0x8CE6, 0xDDB8, 0x8CFB, 0xDDB9, 0x8D74, 0xDDBA, 0x8DBA,
+	0xDDBB, 0x90E8, 0xDDBC, 0x91DC, 0xDDBD, 0x961C, 0xDDBE, 0x9644,
+	0xDDBF, 0x99D9, 0xDDC0, 0x9CE7, 0xDDC1, 0x5317, 0xDDC2, 0x5206,
+	0xDDC3, 0x5429, 0xDDC4, 0x5674, 0xDDC5, 0x58B3, 0xDDC6, 0x5954,
+	0xDDC7, 0x596E, 0xDDC8, 0x5FFF, 0xDDC9, 0x61A4, 0xDDCA, 0x626E,
+	0xDDCB, 0x6610, 0xDDCC, 0x6C7E, 0xDDCD, 0x711A, 0xDDCE, 0x76C6,
+	0xDDCF, 0x7C89, 0xDDD0, 0x7CDE, 0xDDD1, 0x7D1B, 0xDDD2, 0x82AC,
+	0xDDD3, 0x8CC1, 0xDDD4, 0x96F0, 0xDDD5, 0xF967, 0xDDD6, 0x4F5B,
+	0xDDD7, 0x5F17, 0xDDD8, 0x5F7F, 0xDDD9, 0x62C2, 0xDDDA, 0x5D29,
+	0xDDDB, 0x670B, 0xDDDC, 0x68DA, 0xDDDD, 0x787C, 0xDDDE, 0x7E43,
+	0xDDDF, 0x9D6C, 0xDDE0, 0x4E15, 0xDDE1, 0x5099, 0xDDE2, 0x5315,
+	0xDDE3, 0x532A, 0xDDE4, 0x5351, 0xDDE5, 0x5983, 0xDDE6, 0x5A62,
+	0xDDE7, 0x5E87, 0xDDE8, 0x60B2, 0xDDE9, 0x618A, 0xDDEA, 0x6249,
+	0xDDEB, 0x6279, 0xDDEC, 0x6590, 0xDDED, 0x6787, 0xDDEE, 0x69A7,
+	0xDDEF, 0x6BD4, 0xDDF0, 0x6BD6, 0xDDF1, 0x6BD7, 0xDDF2, 0x6BD8,
+	0xDDF3, 0x6CB8, 0xDDF4, 0xF968, 0xDDF5, 0x7435, 0xDDF6, 0x75FA,
+	0xDDF7, 0x7812, 0xDDF8, 0x7891, 0xDDF9, 0x79D5, 0xDDFA, 0x79D8,
+	0xDDFB, 0x7C83, 0xDDFC, 0x7DCB, 0xDDFD, 0x7FE1, 0xDDFE, 0x80A5,
+	0xDEA1, 0x813E, 0xDEA2, 0x81C2, 0xDEA3, 0x83F2, 0xDEA4, 0x871A,
+	0xDEA5, 0x88E8, 0xDEA6, 0x8AB9, 0xDEA7, 0x8B6C, 0xDEA8, 0x8CBB,
+	0xDEA9, 0x9119, 0xDEAA, 0x975E, 0xDEAB, 0x98DB, 0xDEAC, 0x9F3B,
+	0xDEAD, 0x56AC, 0xDEAE, 0x5B2A, 0xDEAF, 0x5F6C, 0xDEB0, 0x658C,
+	0xDEB1, 0x6AB3, 0xDEB2, 0x6BAF, 0xDEB3, 0x6D5C, 0xDEB4, 0x6FF1,
+	0xDEB5, 0x7015, 0xDEB6, 0x725D, 0xDEB7, 0x73AD, 0xDEB8, 0x8CA7,
+	0xDEB9, 0x8CD3, 0xDEBA, 0x983B, 0xDEBB, 0x6191, 0xDEBC, 0x6C37,
+	0xDEBD, 0x8058, 0xDEBE, 0x9A01, 0xDEBF, 0x4E4D, 0xDEC0, 0x4E8B,
+	0xDEC1, 0x4E9B, 0xDEC2, 0x4ED5, 0xDEC3, 0x4F3A, 0xDEC4, 0x4F3C,
+	0xDEC5, 0x4F7F, 0xDEC6, 0x4FDF, 0xDEC7, 0x50FF, 0xDEC8, 0x53F2,
+	0xDEC9, 0x53F8, 0xDECA, 0x5506, 0xDECB, 0x55E3, 0xDECC, 0x56DB,
+	0xDECD, 0x58EB, 0xDECE, 0x5962, 0xDECF, 0x5A11, 0xDED0, 0x5BEB,
+	0xDED1, 0x5BFA, 0xDED2, 0x5C04, 0xDED3, 0x5DF3, 0xDED4, 0x5E2B,
+	0xDED5, 0x5F99, 0xDED6, 0x601D, 0xDED7, 0x6368, 0xDED8, 0x659C,
+	0xDED9, 0x65AF, 0xDEDA, 0x67F6, 0xDEDB, 0x67FB, 0xDEDC, 0x68AD,
+	0xDEDD, 0x6B7B, 0xDEDE, 0x6C99, 0xDEDF, 0x6CD7, 0xDEE0, 0x6E23,
+	0xDEE1, 0x7009, 0xDEE2, 0x7345, 0xDEE3, 0x7802, 0xDEE4, 0x793E,
+	0xDEE5, 0x7940, 0xDEE6, 0x7960, 0xDEE7, 0x79C1, 0xDEE8, 0x7BE9,
+	0xDEE9, 0x7D17, 0xDEEA, 0x7D72, 0xDEEB, 0x8086, 0xDEEC, 0x820D,
+	0xDEED, 0x838E, 0xDEEE, 0x84D1, 0xDEEF, 0x86C7, 0xDEF0, 0x88DF,
+	0xDEF1, 0x8A50, 0xDEF2, 0x8A5E, 0xDEF3, 0x8B1D, 0xDEF4, 0x8CDC,
+	0xDEF5, 0x8D66, 0xDEF6, 0x8FAD, 0xDEF7, 0x90AA, 0xDEF8, 0x98FC,
+	0xDEF9, 0x99DF, 0xDEFA, 0x9E9D, 0xDEFB, 0x524A, 0xDEFC, 0xF969,
+	0xDEFD, 0x6714, 0xDEFE, 0xF96A, 0xDFA1, 0x5098, 0xDFA2, 0x522A,
+	0xDFA3, 0x5C71, 0xDFA4, 0x6563, 0xDFA5, 0x6C55, 0xDFA6, 0x73CA,
+	0xDFA7, 0x7523, 0xDFA8, 0x759D, 0xDFA9, 0x7B97, 0xDFAA, 0x849C,
+	0xDFAB, 0x9178, 0xDFAC, 0x9730, 0xDFAD, 0x4E77, 0xDFAE, 0x6492,
+	0xDFAF, 0x6BBA, 0xDFB0, 0x715E, 0xDFB1, 0x85A9, 0xDFB2, 0x4E09,
+	0xDFB3, 0xF96B, 0xDFB4, 0x6749, 0xDFB5, 0x68EE, 0xDFB6, 0x6E17,
+	0xDFB7, 0x829F, 0xDFB8, 0x8518, 0xDFB9, 0x886B, 0xDFBA, 0x63F7,
+	0xDFBB, 0x6F81, 0xDFBC, 0x9212, 0xDFBD, 0x98AF, 0xDFBE, 0x4E0A,
+	0xDFBF, 0x50B7, 0xDFC0, 0x50CF, 0xDFC1, 0x511F, 0xDFC2, 0x5546,
+	0xDFC3, 0x55AA, 0xDFC4, 0x5617, 0xDFC5, 0x5B40, 0xDFC6, 0x5C19,
+	0xDFC7, 0x5CE0, 0xDFC8, 0x5E38, 0xDFC9, 0x5E8A, 0xDFCA, 0x5EA0,
+	0xDFCB, 0x5EC2, 0xDFCC, 0x60F3, 0xDFCD, 0x6851, 0xDFCE, 0x6A61,
+	0xDFCF, 0x6E58, 0xDFD0, 0x723D, 0xDFD1, 0x7240, 0xDFD2, 0x72C0,
+	0xDFD3, 0x76F8, 0xDFD4, 0x7965, 0xDFD5, 0x7BB1, 0xDFD6, 0x7FD4,
+	0xDFD7, 0x88F3, 0xDFD8, 0x89F4, 0xDFD9, 0x8A73, 0xDFDA, 0x8C61,
+	0xDFDB, 0x8CDE, 0xDFDC, 0x971C, 0xDFDD, 0x585E, 0xDFDE, 0x74BD,
+	0xDFDF, 0x8CFD, 0xDFE0, 0x55C7, 0xDFE1, 0xF96C, 0xDFE2, 0x7A61,
+	0xDFE3, 0x7D22, 0xDFE4, 0x8272, 0xDFE5, 0x7272, 0xDFE6, 0x751F,
+	0xDFE7, 0x7525, 0xDFE8, 0xF96D, 0xDFE9, 0x7B19, 0xDFEA, 0x5885,
+	0xDFEB, 0x58FB, 0xDFEC, 0x5DBC, 0xDFED, 0x5E8F, 0xDFEE, 0x5EB6,
+	0xDFEF, 0x5F90, 0xDFF0, 0x6055, 0xDFF1, 0x6292, 0xDFF2, 0x637F,
+	0xDFF3, 0x654D, 0xDFF4, 0x6691, 0xDFF5, 0x66D9, 0xDFF6, 0x66F8,
+	0xDFF7, 0x6816, 0xDFF8, 0x68F2, 0xDFF9, 0x7280, 0xDFFA, 0x745E,
+	0xDFFB, 0x7B6E, 0xDFFC, 0x7D6E, 0xDFFD, 0x7DD6, 0xDFFE, 0x7F72,
+	0xE0A1, 0x80E5, 0xE0A2, 0x8212, 0xE0A3, 0x85AF, 0xE0A4, 0x897F,
+	0xE0A5, 0x8A93, 0xE0A6, 0x901D, 0xE0A7, 0x92E4, 0xE0A8, 0x9ECD,
+	0xE0A9, 0x9F20, 0xE0AA, 0x5915, 0xE0AB, 0x596D, 0xE0AC, 0x5E2D,
+	0xE0AD, 0x60DC, 0xE0AE, 0x6614, 0xE0AF, 0x6673, 0xE0B0, 0x6790,
+	0xE0B1, 0x6C50, 0xE0B2, 0x6DC5, 0xE0B3, 0x6F5F, 0xE0B4, 0x77F3,
+	0xE0B5, 0x78A9, 0xE0B6, 0x84C6, 0xE0B7, 0x91CB, 0xE0B8, 0x932B,
+	0xE0B9, 0x4ED9, 0xE0BA, 0x50CA, 0xE0BB, 0x5148, 0xE0BC, 0x5584,
+	0xE0BD, 0x5B0B, 0xE0BE, 0x5BA3, 0xE0BF, 0x6247, 0xE0C0, 0x657E,
+	0xE0C1, 0x65CB, 0xE0C2, 0x6E32, 0xE0C3, 0x717D, 0xE0C4, 0x7401,
+	0xE0C5, 0x7444, 0xE0C6, 0x7487, 0xE0C7, 0x74BF, 0xE0C8, 0x766C,
+	0xE0C9, 0x79AA, 0xE0CA, 0x7DDA, 0xE0CB, 0x7E55, 0xE0CC, 0x7FA8,
+	0xE0CD, 0x817A, 0xE0CE, 0x81B3, 0xE0CF, 0x8239, 0xE0D0, 0x861A,
+	0xE0D1, 0x87EC, 0xE0D2, 0x8A75, 0xE0D3, 0x8DE3, 0xE0D4, 0x9078,
+	0xE0D5, 0x9291, 0xE0D6, 0x9425, 0xE0D7, 0x994D, 0xE0D8, 0x9BAE,
+	0xE0D9, 0x5368, 0xE0DA, 0x5C51, 0xE0DB, 0x6954, 0xE0DC, 0x6CC4,
+	0xE0DD, 0x6D29, 0xE0DE, 0x6E2B, 0xE0DF, 0x820C, 0xE0E0, 0x859B,
+	0xE0E1, 0x893B, 0xE0E2, 0x8A2D, 0xE0E3, 0x8AAA, 0xE0E4, 0x96EA,
+	0xE0E5, 0x9F67, 0xE0E6, 0x5261, 0xE0E7, 0x66B9, 0xE0E8, 0x6BB2,
+	0xE0E9, 0x7E96, 0xE0EA, 0x87FE, 0xE0EB, 0x8D0D, 0xE0EC, 0x9583,
+	0xE0ED, 0x965D, 0xE0EE, 0x651D, 0xE0EF, 0x6D89, 0xE0F0, 0x71EE,
+	0xE0F1, 0xF96E, 0xE0F2, 0x57CE, 0xE0F3, 0x59D3, 0xE0F4, 0x5BAC,
+	0xE0F5, 0x6027, 0xE0F6, 0x60FA, 0xE0F7, 0x6210, 0xE0F8, 0x661F,
+	0xE0F9, 0x665F, 0xE0FA, 0x7329, 0xE0FB, 0x73F9, 0xE0FC, 0x76DB,
+	0xE0FD, 0x7701, 0xE0FE, 0x7B6C, 0xE1A1, 0x8056, 0xE1A2, 0x8072,
+	0xE1A3, 0x8165, 0xE1A4, 0x8AA0, 0xE1A5, 0x9192, 0xE1A6, 0x4E16,
+	0xE1A7, 0x52E2, 0xE1A8, 0x6B72, 0xE1A9, 0x6D17, 0xE1AA, 0x7A05,
+	0xE1AB, 0x7B39, 0xE1AC, 0x7D30, 0xE1AD, 0xF96F, 0xE1AE, 0x8CB0,
+	0xE1AF, 0x53EC, 0xE1B0, 0x562F, 0xE1B1, 0x5851, 0xE1B2, 0x5BB5,
+	0xE1B3, 0x5C0F, 0xE1B4, 0x5C11, 0xE1B5, 0x5DE2, 0xE1B6, 0x6240,
+	0xE1B7, 0x6383, 0xE1B8, 0x6414, 0xE1B9, 0x662D, 0xE1BA, 0x68B3,
+	0xE1BB, 0x6CBC, 0xE1BC, 0x6D88, 0xE1BD, 0x6EAF, 0xE1BE, 0x701F,
+	0xE1BF, 0x70A4, 0xE1C0, 0x71D2, 0xE1C1, 0x7526, 0xE1C2, 0x758F,
+	0xE1C3, 0x758E, 0xE1C4, 0x7619, 0xE1C5, 0x7B11, 0xE1C6, 0x7BE0,
+	0xE1C7, 0x7C2B, 0xE1C8, 0x7D20, 0xE1C9, 0x7D39, 0xE1CA, 0x852C,
+	0xE1CB, 0x856D, 0xE1CC, 0x8607, 0xE1CD, 0x8A34, 0xE1CE, 0x900D,
+	0xE1CF, 0x9061, 0xE1D0, 0x90B5, 0xE1D1, 0x92B7, 0xE1D2, 0x97F6,
+	0xE1D3, 0x9A37, 0xE1D4, 0x4FD7, 0xE1D5, 0x5C6C, 0xE1D6, 0x675F,
+	0xE1D7, 0x6D91, 0xE1D8, 0x7C9F, 0xE1D9, 0x7E8C, 0xE1DA, 0x8B16,
+	0xE1DB, 0x8D16, 0xE1DC, 0x901F, 0xE1DD, 0x5B6B, 0xE1DE, 0x5DFD,
+	0xE1DF, 0x640D, 0xE1E0, 0x84C0, 0xE1E1, 0x905C, 0xE1E2, 0x98E1,
+	0xE1E3, 0x7387, 0xE1E4, 0x5B8B, 0xE1E5, 0x609A, 0xE1E6, 0x677E,
+	0xE1E7, 0x6DDE, 0xE1E8, 0x8A1F, 0xE1E9, 0x8AA6, 0xE1EA, 0x9001,
+	0xE1EB, 0x980C, 0xE1EC, 0x5237, 0xE1ED, 0xF970, 0xE1EE, 0x7051,
+	0xE1EF, 0x788E, 0xE1F0, 0x9396, 0xE1F1, 0x8870, 0xE1F2, 0x91D7,
+	0xE1F3, 0x4FEE, 0xE1F4, 0x53D7, 0xE1F5, 0x55FD, 0xE1F6, 0x56DA,
+	0xE1F7, 0x5782, 0xE1F8, 0x58FD, 0xE1F9, 0x5AC2, 0xE1FA, 0x5B88,
+	0xE1FB, 0x5CAB, 0xE1FC, 0x5CC0, 0xE1FD, 0x5E25, 0xE1FE, 0x6101,
+	0xE2A1, 0x620D, 0xE2A2, 0x624B, 0xE2A3, 0x6388, 0xE2A4, 0x641C,
+	0xE2A5, 0x6536, 0xE2A6, 0x6578, 0xE2A7, 0x6A39, 0xE2A8, 0x6B8A,
+	0xE2A9, 0x6C34, 0xE2AA, 0x6D19, 0xE2AB, 0x6F31, 0xE2AC, 0x71E7,
+	0xE2AD, 0x72E9, 0xE2AE, 0x7378, 0xE2AF, 0x7407, 0xE2B0, 0x74B2,
+	0xE2B1, 0x7626, 0xE2B2, 0x7761, 0xE2B3, 0x79C0, 0xE2B4, 0x7A57,
+	0xE2B5, 0x7AEA, 0xE2B6, 0x7CB9, 0xE2B7, 0x7D8F, 0xE2B8, 0x7DAC,
+	0xE2B9, 0x7E61, 0xE2BA, 0x7F9E, 0xE2BB, 0x8129, 0xE2BC, 0x8331,
+	0xE2BD, 0x8490, 0xE2BE, 0x84DA, 0xE2BF, 0x85EA, 0xE2C0, 0x8896,
+	0xE2C1, 0x8AB0, 0xE2C2, 0x8B90, 0xE2C3, 0x8F38, 0xE2C4, 0x9042,
+	0xE2C5, 0x9083, 0xE2C6, 0x916C, 0xE2C7, 0x9296, 0xE2C8, 0x92B9,
+	0xE2C9, 0x968B, 0xE2CA, 0x96A7, 0xE2CB, 0x96A8, 0xE2CC, 0x96D6,
+	0xE2CD, 0x9700, 0xE2CE, 0x9808, 0xE2CF, 0x9996, 0xE2D0, 0x9AD3,
+	0xE2D1, 0x9B1A, 0xE2D2, 0x53D4, 0xE2D3, 0x587E, 0xE2D4, 0x5919,
+	0xE2D5, 0x5B70, 0xE2D6, 0x5BBF, 0xE2D7, 0x6DD1, 0xE2D8, 0x6F5A,
+	0xE2D9, 0x719F, 0xE2DA, 0x7421, 0xE2DB, 0x74B9, 0xE2DC, 0x8085,
+	0xE2DD, 0x83FD, 0xE2DE, 0x5DE1, 0xE2DF, 0x5F87, 0xE2E0, 0x5FAA,
+	0xE2E1, 0x6042, 0xE2E2, 0x65EC, 0xE2E3, 0x6812, 0xE2E4, 0x696F,
+	0xE2E5, 0x6A53, 0xE2E6, 0x6B89, 0xE2E7, 0x6D35, 0xE2E8, 0x6DF3,
+	0xE2E9, 0x73E3, 0xE2EA, 0x76FE, 0xE2EB, 0x77AC, 0xE2EC, 0x7B4D,
+	0xE2ED, 0x7D14, 0xE2EE, 0x8123, 0xE2EF, 0x821C, 0xE2F0, 0x8340,
+	0xE2F1, 0x84F4, 0xE2F2, 0x8563, 0xE2F3, 0x8A62, 0xE2F4, 0x8AC4,
+	0xE2F5, 0x9187, 0xE2F6, 0x931E, 0xE2F7, 0x9806, 0xE2F8, 0x99B4,
+	0xE2F9, 0x620C, 0xE2FA, 0x8853, 0xE2FB, 0x8FF0, 0xE2FC, 0x9265,
+	0xE2FD, 0x5D07, 0xE2FE, 0x5D27, 0xE3A1, 0x5D69, 0xE3A2, 0x745F,
+	0xE3A3, 0x819D, 0xE3A4, 0x8768, 0xE3A5, 0x6FD5, 0xE3A6, 0x62FE,
+	0xE3A7, 0x7FD2, 0xE3A8, 0x8936, 0xE3A9, 0x8972, 0xE3AA, 0x4E1E,
+	0xE3AB, 0x4E58, 0xE3AC, 0x50E7, 0xE3AD, 0x52DD, 0xE3AE, 0x5347,
+	0xE3AF, 0x627F, 0xE3B0, 0x6607, 0xE3B1, 0x7E69, 0xE3B2, 0x8805,
+	0xE3B3, 0x965E, 0xE3B4, 0x4F8D, 0xE3B5, 0x5319, 0xE3B6, 0x5636,
+	0xE3B7, 0x59CB, 0xE3B8, 0x5AA4, 0xE3B9, 0x5C38, 0xE3BA, 0x5C4E,
+	0xE3BB, 0x5C4D, 0xE3BC, 0x5E02, 0xE3BD, 0x5F11, 0xE3BE, 0x6043,
+	0xE3BF, 0x65BD, 0xE3C0, 0x662F, 0xE3C1, 0x6642, 0xE3C2, 0x67BE,
+	0xE3C3, 0x67F4, 0xE3C4, 0x731C, 0xE3C5, 0x77E2, 0xE3C6, 0x793A,
+	0xE3C7, 0x7FC5, 0xE3C8, 0x8494, 0xE3C9, 0x84CD, 0xE3CA, 0x8996,
+	0xE3CB, 0x8A66, 0xE3CC, 0x8A69, 0xE3CD, 0x8AE1, 0xE3CE, 0x8C55,
+	0xE3CF, 0x8C7A, 0xE3D0, 0x57F4, 0xE3D1, 0x5BD4, 0xE3D2, 0x5F0F,
+	0xE3D3, 0x606F, 0xE3D4, 0x62ED, 0xE3D5, 0x690D, 0xE3D6, 0x6B96,
+	0xE3D7, 0x6E5C, 0xE3D8, 0x7184, 0xE3D9, 0x7BD2, 0xE3DA, 0x8755,
+	0xE3DB, 0x8B58, 0xE3DC, 0x8EFE, 0xE3DD, 0x98DF, 0xE3DE, 0x98FE,
+	0xE3DF, 0x4F38, 0xE3E0, 0x4F81, 0xE3E1, 0x4FE1, 0xE3E2, 0x547B,
+	0xE3E3, 0x5A20, 0xE3E4, 0x5BB8, 0xE3E5, 0x613C, 0xE3E6, 0x65B0,
+	0xE3E7, 0x6668, 0xE3E8, 0x71FC, 0xE3E9, 0x7533, 0xE3EA, 0x795E,
+	0xE3EB, 0x7D33, 0xE3EC, 0x814E, 0xE3ED, 0x81E3, 0xE3EE, 0x8398,
+	0xE3EF, 0x85AA, 0xE3F0, 0x85CE, 0xE3F1, 0x8703, 0xE3F2, 0x8A0A,
+	0xE3F3, 0x8EAB, 0xE3F4, 0x8F9B, 0xE3F5, 0xF971, 0xE3F6, 0x8FC5,
+	0xE3F7, 0x5931, 0xE3F8, 0x5BA4, 0xE3F9, 0x5BE6, 0xE3FA, 0x6089,
+	0xE3FB, 0x5BE9, 0xE3FC, 0x5C0B, 0xE3FD, 0x5FC3, 0xE3FE, 0x6C81,
+	0xE4A1, 0xF972, 0xE4A2, 0x6DF1, 0xE4A3, 0x700B, 0xE4A4, 0x751A,
+	0xE4A5, 0x82AF, 0xE4A6, 0x8AF6, 0xE4A7, 0x4EC0, 0xE4A8, 0x5341,
+	0xE4A9, 0xF973, 0xE4AA, 0x96D9, 0xE4AB, 0x6C0F, 0xE4AC, 0x4E9E,
+	0xE4AD, 0x4FC4, 0xE4AE, 0x5152, 0xE4AF, 0x555E, 0xE4B0, 0x5A25,
+	0xE4B1, 0x5CE8, 0xE4B2, 0x6211, 0xE4B3, 0x7259, 0xE4B4, 0x82BD,
+	0xE4B5, 0x83AA, 0xE4B6, 0x86FE, 0xE4B7, 0x8859, 0xE4B8, 0x8A1D,
+	0xE4B9, 0x963F, 0xE4BA, 0x96C5, 0xE4BB, 0x9913, 0xE4BC, 0x9D09,
+	0xE4BD, 0x9D5D, 0xE4BE, 0x580A, 0xE4BF, 0x5CB3, 0xE4C0, 0x5DBD,
+	0xE4C1, 0x5E44, 0xE4C2, 0x60E1, 0xE4C3, 0x6115, 0xE4C4, 0x63E1,
+	0xE4C5, 0x6A02, 0xE4C6, 0x6E25, 0xE4C7, 0x9102, 0xE4C8, 0x9354,
+	0xE4C9, 0x984E, 0xE4CA, 0x9C10, 0xE4CB, 0x9F77, 0xE4CC, 0x5B89,
+	0xE4CD, 0x5CB8, 0xE4CE, 0x6309, 0xE4CF, 0x664F, 0xE4D0, 0x6848,
+	0xE4D1, 0x773C, 0xE4D2, 0x96C1, 0xE4D3, 0x978D, 0xE4D4, 0x9854,
+	0xE4D5, 0x9B9F, 0xE4D6, 0x65A1, 0xE4D7, 0x8B01, 0xE4D8, 0x8ECB,
+	0xE4D9, 0x95BC, 0xE4DA, 0x5535, 0xE4DB, 0x5CA9, 0xE4DC, 0x5DD6,
+	0xE4DD, 0x5EB5, 0xE4DE, 0x6697, 0xE4DF, 0x764C, 0xE4E0, 0x83F4,
+	0xE4E1, 0x95C7, 0xE4E2, 0x58D3, 0xE4E3, 0x62BC, 0xE4E4, 0x72CE,
+	0xE4E5, 0x9D28, 0xE4E6, 0x4EF0, 0xE4E7, 0x592E, 0xE4E8, 0x600F,
+	0xE4E9, 0x663B, 0xE4EA, 0x6B83, 0xE4EB, 0x79E7, 0xE4EC, 0x9D26,
+	0xE4ED, 0x5393, 0xE4EE, 0x54C0, 0xE4EF, 0x57C3, 0xE4F0, 0x5D16,
+	0xE4F1, 0x611B, 0xE4F2, 0x66D6, 0xE4F3, 0x6DAF, 0xE4F4, 0x788D,
+	0xE4F5, 0x827E, 0xE4F6, 0x9698, 0xE4F7, 0x9744, 0xE4F8, 0x5384,
+	0xE4F9, 0x627C, 0xE4FA, 0x6396, 0xE4FB, 0x6DB2, 0xE4FC, 0x7E0A,
+	0xE4FD, 0x814B, 0xE4FE, 0x984D, 0xE5A1, 0x6AFB, 0xE5A2, 0x7F4C,
+	0xE5A3, 0x9DAF, 0xE5A4, 0x9E1A, 0xE5A5, 0x4E5F, 0xE5A6, 0x503B,
+	0xE5A7, 0x51B6, 0xE5A8, 0x591C, 0xE5A9, 0x60F9, 0xE5AA, 0x63F6,
+	0xE5AB, 0x6930, 0xE5AC, 0x723A, 0xE5AD, 0x8036, 0xE5AE, 0xF974,
+	0xE5AF, 0x91CE, 0xE5B0, 0x5F31, 0xE5B1, 0xF975, 0xE5B2, 0xF976,
+	0xE5B3, 0x7D04, 0xE5B4, 0x82E5, 0xE5B5, 0x846F, 0xE5B6, 0x84BB,
+	0xE5B7, 0x85E5, 0xE5B8, 0x8E8D, 0xE5B9, 0xF977, 0xE5BA, 0x4F6F,
+	0xE5BB, 0xF978, 0xE5BC, 0xF979, 0xE5BD, 0x58E4, 0xE5BE, 0x5B43,
+	0xE5BF, 0x6059, 0xE5C0, 0x63DA, 0xE5C1, 0x6518, 0xE5C2, 0x656D,
+	0xE5C3, 0x6698, 0xE5C4, 0xF97A, 0xE5C5, 0x694A, 0xE5C6, 0x6A23,
+	0xE5C7, 0x6D0B, 0xE5C8, 0x7001, 0xE5C9, 0x716C, 0xE5CA, 0x75D2,
+	0xE5CB, 0x760D, 0xE5CC, 0x79B3, 0xE5CD, 0x7A70, 0xE5CE, 0xF97B,
+	0xE5CF, 0x7F8A, 0xE5D0, 0xF97C, 0xE5D1, 0x8944, 0xE5D2, 0xF97D,
+	0xE5D3, 0x8B93, 0xE5D4, 0x91C0, 0xE5D5, 0x967D, 0xE5D6, 0xF97E,
+	0xE5D7, 0x990A, 0xE5D8, 0x5704, 0xE5D9, 0x5FA1, 0xE5DA, 0x65BC,
+	0xE5DB, 0x6F01, 0xE5DC, 0x7600, 0xE5DD, 0x79A6, 0xE5DE, 0x8A9E,
+	0xE5DF, 0x99AD, 0xE5E0, 0x9B5A, 0xE5E1, 0x9F6C, 0xE5E2, 0x5104,
+	0xE5E3, 0x61B6, 0xE5E4, 0x6291, 0xE5E5, 0x6A8D, 0xE5E6, 0x81C6,
+	0xE5E7, 0x5043, 0xE5E8, 0x5830, 0xE5E9, 0x5F66, 0xE5EA, 0x7109,
+	0xE5EB, 0x8A00, 0xE5EC, 0x8AFA, 0xE5ED, 0x5B7C, 0xE5EE, 0x8616,
+	0xE5EF, 0x4FFA, 0xE5F0, 0x513C, 0xE5F1, 0x56B4, 0xE5F2, 0x5944,
+	0xE5F3, 0x63A9, 0xE5F4, 0x6DF9, 0xE5F5, 0x5DAA, 0xE5F6, 0x696D,
+	0xE5F7, 0x5186, 0xE5F8, 0x4E88, 0xE5F9, 0x4F59, 0xE5FA, 0xF97F,
+	0xE5FB, 0xF980, 0xE5FC, 0xF981, 0xE5FD, 0x5982, 0xE5FE, 0xF982,
+	0xE6A1, 0xF983, 0xE6A2, 0x6B5F, 0xE6A3, 0x6C5D, 0xE6A4, 0xF984,
+	0xE6A5, 0x74B5, 0xE6A6, 0x7916, 0xE6A7, 0xF985, 0xE6A8, 0x8207,
+	0xE6A9, 0x8245, 0xE6AA, 0x8339, 0xE6AB, 0x8F3F, 0xE6AC, 0x8F5D,
+	0xE6AD, 0xF986, 0xE6AE, 0x9918, 0xE6AF, 0xF987, 0xE6B0, 0xF988,
+	0xE6B1, 0xF989, 0xE6B2, 0x4EA6, 0xE6B3, 0xF98A, 0xE6B4, 0x57DF,
+	0xE6B5, 0x5F79, 0xE6B6, 0x6613, 0xE6B7, 0xF98B, 0xE6B8, 0xF98C,
+	0xE6B9, 0x75AB, 0xE6BA, 0x7E79, 0xE6BB, 0x8B6F, 0xE6BC, 0xF98D,
+	0xE6BD, 0x9006, 0xE6BE, 0x9A5B, 0xE6BF, 0x56A5, 0xE6C0, 0x5827,
+	0xE6C1, 0x59F8, 0xE6C2, 0x5A1F, 0xE6C3, 0x5BB4, 0xE6C4, 0xF98E,
+	0xE6C5, 0x5EF6, 0xE6C6, 0xF98F, 0xE6C7, 0xF990, 0xE6C8, 0x6350,
+	0xE6C9, 0x633B, 0xE6CA, 0xF991, 0xE6CB, 0x693D, 0xE6CC, 0x6C87,
+	0xE6CD, 0x6CBF, 0xE6CE, 0x6D8E, 0xE6CF, 0x6D93, 0xE6D0, 0x6DF5,
+	0xE6D1, 0x6F14, 0xE6D2, 0xF992, 0xE6D3, 0x70DF, 0xE6D4, 0x7136,
+	0xE6D5, 0x7159, 0xE6D6, 0xF993, 0xE6D7, 0x71C3, 0xE6D8, 0x71D5,
+	0xE6D9, 0xF994, 0xE6DA, 0x784F, 0xE6DB, 0x786F, 0xE6DC, 0xF995,
+	0xE6DD, 0x7B75, 0xE6DE, 0x7DE3, 0xE6DF, 0xF996, 0xE6E0, 0x7E2F,
+	0xE6E1, 0xF997, 0xE6E2, 0x884D, 0xE6E3, 0x8EDF, 0xE6E4, 0xF998,
+	0xE6E5, 0xF999, 0xE6E6, 0xF99A, 0xE6E7, 0x925B, 0xE6E8, 0xF99B,
+	0xE6E9, 0x9CF6, 0xE6EA, 0xF99C, 0xE6EB, 0xF99D, 0xE6EC, 0xF99E,
+	0xE6ED, 0x6085, 0xE6EE, 0x6D85, 0xE6EF, 0xF99F, 0xE6F0, 0x71B1,
+	0xE6F1, 0xF9A0, 0xE6F2, 0xF9A1, 0xE6F3, 0x95B1, 0xE6F4, 0x53AD,
+	0xE6F5, 0xF9A2, 0xE6F6, 0xF9A3, 0xE6F7, 0xF9A4, 0xE6F8, 0x67D3,
+	0xE6F9, 0xF9A5, 0xE6FA, 0x708E, 0xE6FB, 0x7130, 0xE6FC, 0x7430,
+	0xE6FD, 0x8276, 0xE6FE, 0x82D2, 0xE7A1, 0xF9A6, 0xE7A2, 0x95BB,
+	0xE7A3, 0x9AE5, 0xE7A4, 0x9E7D, 0xE7A5, 0x66C4, 0xE7A6, 0xF9A7,
+	0xE7A7, 0x71C1, 0xE7A8, 0x8449, 0xE7A9, 0xF9A8, 0xE7AA, 0xF9A9,
+	0xE7AB, 0x584B, 0xE7AC, 0xF9AA, 0xE7AD, 0xF9AB, 0xE7AE, 0x5DB8,
+	0xE7AF, 0x5F71, 0xE7B0, 0xF9AC, 0xE7B1, 0x6620, 0xE7B2, 0x668E,
+	0xE7B3, 0x6979, 0xE7B4, 0x69AE, 0xE7B5, 0x6C38, 0xE7B6, 0x6CF3,
+	0xE7B7, 0x6E36, 0xE7B8, 0x6F41, 0xE7B9, 0x6FDA, 0xE7BA, 0x701B,
+	0xE7BB, 0x702F, 0xE7BC, 0x7150, 0xE7BD, 0x71DF, 0xE7BE, 0x7370,
+	0xE7BF, 0xF9AD, 0xE7C0, 0x745B, 0xE7C1, 0xF9AE, 0xE7C2, 0x74D4,
+	0xE7C3, 0x76C8, 0xE7C4, 0x7A4E, 0xE7C5, 0x7E93, 0xE7C6, 0xF9AF,
+	0xE7C7, 0xF9B0, 0xE7C8, 0x82F1, 0xE7C9, 0x8A60, 0xE7CA, 0x8FCE,
+	0xE7CB, 0xF9B1, 0xE7CC, 0x9348, 0xE7CD, 0xF9B2, 0xE7CE, 0x9719,
+	0xE7CF, 0xF9B3, 0xE7D0, 0xF9B4, 0xE7D1, 0x4E42, 0xE7D2, 0x502A,
+	0xE7D3, 0xF9B5, 0xE7D4, 0x5208, 0xE7D5, 0x53E1, 0xE7D6, 0x66F3,
+	0xE7D7, 0x6C6D, 0xE7D8, 0x6FCA, 0xE7D9, 0x730A, 0xE7DA, 0x777F,
+	0xE7DB, 0x7A62, 0xE7DC, 0x82AE, 0xE7DD, 0x85DD, 0xE7DE, 0x8602,
+	0xE7DF, 0xF9B6, 0xE7E0, 0x88D4, 0xE7E1, 0x8A63, 0xE7E2, 0x8B7D,
+	0xE7E3, 0x8C6B, 0xE7E4, 0xF9B7, 0xE7E5, 0x92B3, 0xE7E6, 0xF9B8,
+	0xE7E7, 0x9713, 0xE7E8, 0x9810, 0xE7E9, 0x4E94, 0xE7EA, 0x4F0D,
+	0xE7EB, 0x4FC9, 0xE7EC, 0x50B2, 0xE7ED, 0x5348, 0xE7EE, 0x543E,
+	0xE7EF, 0x5433, 0xE7F0, 0x55DA, 0xE7F1, 0x5862, 0xE7F2, 0x58BA,
+	0xE7F3, 0x5967, 0xE7F4, 0x5A1B, 0xE7F5, 0x5BE4, 0xE7F6, 0x609F,
+	0xE7F7, 0xF9B9, 0xE7F8, 0x61CA, 0xE7F9, 0x6556, 0xE7FA, 0x65FF,
+	0xE7FB, 0x6664, 0xE7FC, 0x68A7, 0xE7FD, 0x6C5A, 0xE7FE, 0x6FB3,
+	0xE8A1, 0x70CF, 0xE8A2, 0x71AC, 0xE8A3, 0x7352, 0xE8A4, 0x7B7D,
+	0xE8A5, 0x8708, 0xE8A6, 0x8AA4, 0xE8A7, 0x9C32, 0xE8A8, 0x9F07,
+	0xE8A9, 0x5C4B, 0xE8AA, 0x6C83, 0xE8AB, 0x7344, 0xE8AC, 0x7389,
+	0xE8AD, 0x923A, 0xE8AE, 0x6EAB, 0xE8AF, 0x7465, 0xE8B0, 0x761F,
+	0xE8B1, 0x7A69, 0xE8B2, 0x7E15, 0xE8B3, 0x860A, 0xE8B4, 0x5140,
+	0xE8B5, 0x58C5, 0xE8B6, 0x64C1, 0xE8B7, 0x74EE, 0xE8B8, 0x7515,
+	0xE8B9, 0x7670, 0xE8BA, 0x7FC1, 0xE8BB, 0x9095, 0xE8BC, 0x96CD,
+	0xE8BD, 0x9954, 0xE8BE, 0x6E26, 0xE8BF, 0x74E6, 0xE8C0, 0x7AA9,
+	0xE8C1, 0x7AAA, 0xE8C2, 0x81E5, 0xE8C3, 0x86D9, 0xE8C4, 0x8778,
+	0xE8C5, 0x8A1B, 0xE8C6, 0x5A49, 0xE8C7, 0x5B8C, 0xE8C8, 0x5B9B,
+	0xE8C9, 0x68A1, 0xE8CA, 0x6900, 0xE8CB, 0x6D63, 0xE8CC, 0x73A9,
+	0xE8CD, 0x7413, 0xE8CE, 0x742C, 0xE8CF, 0x7897, 0xE8D0, 0x7DE9,
+	0xE8D1, 0x7FEB, 0xE8D2, 0x8118, 0xE8D3, 0x8155, 0xE8D4, 0x839E,
+	0xE8D5, 0x8C4C, 0xE8D6, 0x962E, 0xE8D7, 0x9811, 0xE8D8, 0x66F0,
+	0xE8D9, 0x5F80, 0xE8DA, 0x65FA, 0xE8DB, 0x6789, 0xE8DC, 0x6C6A,
+	0xE8DD, 0x738B, 0xE8DE, 0x502D, 0xE8DF, 0x5A03, 0xE8E0, 0x6B6A,
+	0xE8E1, 0x77EE, 0xE8E2, 0x5916, 0xE8E3, 0x5D6C, 0xE8E4, 0x5DCD,
+	0xE8E5, 0x7325, 0xE8E6, 0x754F, 0xE8E7, 0xF9BA, 0xE8E8, 0xF9BB,
+	0xE8E9, 0x50E5, 0xE8EA, 0x51F9, 0xE8EB, 0x582F, 0xE8EC, 0x592D,
+	0xE8ED, 0x5996, 0xE8EE, 0x59DA, 0xE8EF, 0x5BE5, 0xE8F0, 0xF9BC,
+	0xE8F1, 0xF9BD, 0xE8F2, 0x5DA2, 0xE8F3, 0x62D7, 0xE8F4, 0x6416,
+	0xE8F5, 0x6493, 0xE8F6, 0x64FE, 0xE8F7, 0xF9BE, 0xE8F8, 0x66DC,
+	0xE8F9, 0xF9BF, 0xE8FA, 0x6A48, 0xE8FB, 0xF9C0, 0xE8FC, 0x71FF,
+	0xE8FD, 0x7464, 0xE8FE, 0xF9C1, 0xE9A1, 0x7A88, 0xE9A2, 0x7AAF,
+	0xE9A3, 0x7E47, 0xE9A4, 0x7E5E, 0xE9A5, 0x8000, 0xE9A6, 0x8170,
+	0xE9A7, 0xF9C2, 0xE9A8, 0x87EF, 0xE9A9, 0x8981, 0xE9AA, 0x8B20,
+	0xE9AB, 0x9059, 0xE9AC, 0xF9C3, 0xE9AD, 0x9080, 0xE9AE, 0x9952,
+	0xE9AF, 0x617E, 0xE9B0, 0x6B32, 0xE9B1, 0x6D74, 0xE9B2, 0x7E1F,
+	0xE9B3, 0x8925, 0xE9B4, 0x8FB1, 0xE9B5, 0x4FD1, 0xE9B6, 0x50AD,
+	0xE9B7, 0x5197, 0xE9B8, 0x52C7, 0xE9B9, 0x57C7, 0xE9BA, 0x5889,
+	0xE9BB, 0x5BB9, 0xE9BC, 0x5EB8, 0xE9BD, 0x6142, 0xE9BE, 0x6995,
+	0xE9BF, 0x6D8C, 0xE9C0, 0x6E67, 0xE9C1, 0x6EB6, 0xE9C2, 0x7194,
+	0xE9C3, 0x7462, 0xE9C4, 0x7528, 0xE9C5, 0x752C, 0xE9C6, 0x8073,
+	0xE9C7, 0x8338, 0xE9C8, 0x84C9, 0xE9C9, 0x8E0A, 0xE9CA, 0x9394,
+	0xE9CB, 0x93DE, 0xE9CC, 0xF9C4, 0xE9CD, 0x4E8E, 0xE9CE, 0x4F51,
+	0xE9CF, 0x5076, 0xE9D0, 0x512A, 0xE9D1, 0x53C8, 0xE9D2, 0x53CB,
+	0xE9D3, 0x53F3, 0xE9D4, 0x5B87, 0xE9D5, 0x5BD3, 0xE9D6, 0x5C24,
+	0xE9D7, 0x611A, 0xE9D8, 0x6182, 0xE9D9, 0x65F4, 0xE9DA, 0x725B,
+	0xE9DB, 0x7397, 0xE9DC, 0x7440, 0xE9DD, 0x76C2, 0xE9DE, 0x7950,
+	0xE9DF, 0x7991, 0xE9E0, 0x79B9, 0xE9E1, 0x7D06, 0xE9E2, 0x7FBD,
+	0xE9E3, 0x828B, 0xE9E4, 0x85D5, 0xE9E5, 0x865E, 0xE9E6, 0x8FC2,
+	0xE9E7, 0x9047, 0xE9E8, 0x90F5, 0xE9E9, 0x91EA, 0xE9EA, 0x9685,
+	0xE9EB, 0x96E8, 0xE9EC, 0x96E9, 0xE9ED, 0x52D6, 0xE9EE, 0x5F67,
+	0xE9EF, 0x65ED, 0xE9F0, 0x6631, 0xE9F1, 0x682F, 0xE9F2, 0x715C,
+	0xE9F3, 0x7A36, 0xE9F4, 0x90C1, 0xE9F5, 0x980A, 0xE9F6, 0x4E91,
+	0xE9F7, 0xF9C5, 0xE9F8, 0x6A52, 0xE9F9, 0x6B9E, 0xE9FA, 0x6F90,
+	0xE9FB, 0x7189, 0xE9FC, 0x8018, 0xE9FD, 0x82B8, 0xE9FE, 0x8553,
+	0xEAA1, 0x904B, 0xEAA2, 0x9695, 0xEAA3, 0x96F2, 0xEAA4, 0x97FB,
+	0xEAA5, 0x851A, 0xEAA6, 0x9B31, 0xEAA7, 0x4E90, 0xEAA8, 0x718A,
+	0xEAA9, 0x96C4, 0xEAAA, 0x5143, 0xEAAB, 0x539F, 0xEAAC, 0x54E1,
+	0xEAAD, 0x5713, 0xEAAE, 0x5712, 0xEAAF, 0x57A3, 0xEAB0, 0x5A9B,
+	0xEAB1, 0x5AC4, 0xEAB2, 0x5BC3, 0xEAB3, 0x6028, 0xEAB4, 0x613F,
+	0xEAB5, 0x63F4, 0xEAB6, 0x6C85, 0xEAB7, 0x6D39, 0xEAB8, 0x6E72,
+	0xEAB9, 0x6E90, 0xEABA, 0x7230, 0xEABB, 0x733F, 0xEABC, 0x7457,
+	0xEABD, 0x82D1, 0xEABE, 0x8881, 0xEABF, 0x8F45, 0xEAC0, 0x9060,
+	0xEAC1, 0xF9C6, 0xEAC2, 0x9662, 0xEAC3, 0x9858, 0xEAC4, 0x9D1B,
+	0xEAC5, 0x6708, 0xEAC6, 0x8D8A, 0xEAC7, 0x925E, 0xEAC8, 0x4F4D,
+	0xEAC9, 0x5049, 0xEACA, 0x50DE, 0xEACB, 0x5371, 0xEACC, 0x570D,
+	0xEACD, 0x59D4, 0xEACE, 0x5A01, 0xEACF, 0x5C09, 0xEAD0, 0x6170,
+	0xEAD1, 0x6690, 0xEAD2, 0x6E2D, 0xEAD3, 0x7232, 0xEAD4, 0x744B,
+	0xEAD5, 0x7DEF, 0xEAD6, 0x80C3, 0xEAD7, 0x840E, 0xEAD8, 0x8466,
+	0xEAD9, 0x853F, 0xEADA, 0x875F, 0xEADB, 0x885B, 0xEADC, 0x8918,
+	0xEADD, 0x8B02, 0xEADE, 0x9055, 0xEADF, 0x97CB, 0xEAE0, 0x9B4F,
+	0xEAE1, 0x4E73, 0xEAE2, 0x4F91, 0xEAE3, 0x5112, 0xEAE4, 0x516A,
+	0xEAE5, 0xF9C7, 0xEAE6, 0x552F, 0xEAE7, 0x55A9, 0xEAE8, 0x5B7A,
+	0xEAE9, 0x5BA5, 0xEAEA, 0x5E7C, 0xEAEB, 0x5E7D, 0xEAEC, 0x5EBE,
+	0xEAED, 0x60A0, 0xEAEE, 0x60DF, 0xEAEF, 0x6108, 0xEAF0, 0x6109,
+	0xEAF1, 0x63C4, 0xEAF2, 0x6538, 0xEAF3, 0x6709, 0xEAF4, 0xF9C8,
+	0xEAF5, 0x67D4, 0xEAF6, 0x67DA, 0xEAF7, 0xF9C9, 0xEAF8, 0x6961,
+	0xEAF9, 0x6962, 0xEAFA, 0x6CB9, 0xEAFB, 0x6D27, 0xEAFC, 0xF9CA,
+	0xEAFD, 0x6E38, 0xEAFE, 0xF9CB, 0xEBA1, 0x6FE1, 0xEBA2, 0x7336,
+	0xEBA3, 0x7337, 0xEBA4, 0xF9CC, 0xEBA5, 0x745C, 0xEBA6, 0x7531,
+	0xEBA7, 0xF9CD, 0xEBA8, 0x7652, 0xEBA9, 0xF9CE, 0xEBAA, 0xF9CF,
+	0xEBAB, 0x7DAD, 0xEBAC, 0x81FE, 0xEBAD, 0x8438, 0xEBAE, 0x88D5,
+	0xEBAF, 0x8A98, 0xEBB0, 0x8ADB, 0xEBB1, 0x8AED, 0xEBB2, 0x8E30,
+	0xEBB3, 0x8E42, 0xEBB4, 0x904A, 0xEBB5, 0x903E, 0xEBB6, 0x907A,
+	0xEBB7, 0x9149, 0xEBB8, 0x91C9, 0xEBB9, 0x936E, 0xEBBA, 0xF9D0,
+	0xEBBB, 0xF9D1, 0xEBBC, 0x5809, 0xEBBD, 0xF9D2, 0xEBBE, 0x6BD3,
+	0xEBBF, 0x8089, 0xEBC0, 0x80B2, 0xEBC1, 0xF9D3, 0xEBC2, 0xF9D4,
+	0xEBC3, 0x5141, 0xEBC4, 0x596B, 0xEBC5, 0x5C39, 0xEBC6, 0xF9D5,
+	0xEBC7, 0xF9D6, 0xEBC8, 0x6F64, 0xEBC9, 0x73A7, 0xEBCA, 0x80E4,
+	0xEBCB, 0x8D07, 0xEBCC, 0xF9D7, 0xEBCD, 0x9217, 0xEBCE, 0x958F,
+	0xEBCF, 0xF9D8, 0xEBD0, 0xF9D9, 0xEBD1, 0xF9DA, 0xEBD2, 0xF9DB,
+	0xEBD3, 0x807F, 0xEBD4, 0x620E, 0xEBD5, 0x701C, 0xEBD6, 0x7D68,
+	0xEBD7, 0x878D, 0xEBD8, 0xF9DC, 0xEBD9, 0x57A0, 0xEBDA, 0x6069,
+	0xEBDB, 0x6147, 0xEBDC, 0x6BB7, 0xEBDD, 0x8ABE, 0xEBDE, 0x9280,
+	0xEBDF, 0x96B1, 0xEBE0, 0x4E59, 0xEBE1, 0x541F, 0xEBE2, 0x6DEB,
+	0xEBE3, 0x852D, 0xEBE4, 0x9670, 0xEBE5, 0x97F3, 0xEBE6, 0x98EE,
+	0xEBE7, 0x63D6, 0xEBE8, 0x6CE3, 0xEBE9, 0x9091, 0xEBEA, 0x51DD,
+	0xEBEB, 0x61C9, 0xEBEC, 0x81BA, 0xEBED, 0x9DF9, 0xEBEE, 0x4F9D,
+	0xEBEF, 0x501A, 0xEBF0, 0x5100, 0xEBF1, 0x5B9C, 0xEBF2, 0x610F,
+	0xEBF3, 0x61FF, 0xEBF4, 0x64EC, 0xEBF5, 0x6905, 0xEBF6, 0x6BC5,
+	0xEBF7, 0x7591, 0xEBF8, 0x77E3, 0xEBF9, 0x7FA9, 0xEBFA, 0x8264,
+	0xEBFB, 0x858F, 0xEBFC, 0x87FB, 0xEBFD, 0x8863, 0xEBFE, 0x8ABC,
+	0xECA1, 0x8B70, 0xECA2, 0x91AB, 0xECA3, 0x4E8C, 0xECA4, 0x4EE5,
+	0xECA5, 0x4F0A, 0xECA6, 0xF9DD, 0xECA7, 0xF9DE, 0xECA8, 0x5937,
+	0xECA9, 0x59E8, 0xECAA, 0xF9DF, 0xECAB, 0x5DF2, 0xECAC, 0x5F1B,
+	0xECAD, 0x5F5B, 0xECAE, 0x6021, 0xECAF, 0xF9E0, 0xECB0, 0xF9E1,
+	0xECB1, 0xF9E2, 0xECB2, 0xF9E3, 0xECB3, 0x723E, 0xECB4, 0x73E5,
+	0xECB5, 0xF9E4, 0xECB6, 0x7570, 0xECB7, 0x75CD, 0xECB8, 0xF9E5,
+	0xECB9, 0x79FB, 0xECBA, 0xF9E6, 0xECBB, 0x800C, 0xECBC, 0x8033,
+	0xECBD, 0x8084, 0xECBE, 0x82E1, 0xECBF, 0x8351, 0xECC0, 0xF9E7,
+	0xECC1, 0xF9E8, 0xECC2, 0x8CBD, 0xECC3, 0x8CB3, 0xECC4, 0x9087,
+	0xECC5, 0xF9E9, 0xECC6, 0xF9EA, 0xECC7, 0x98F4, 0xECC8, 0x990C,
+	0xECC9, 0xF9EB, 0xECCA, 0xF9EC, 0xECCB, 0x7037, 0xECCC, 0x76CA,
+	0xECCD, 0x7FCA, 0xECCE, 0x7FCC, 0xECCF, 0x7FFC, 0xECD0, 0x8B1A,
+	0xECD1, 0x4EBA, 0xECD2, 0x4EC1, 0xECD3, 0x5203, 0xECD4, 0x5370,
+	0xECD5, 0xF9ED, 0xECD6, 0x54BD, 0xECD7, 0x56E0, 0xECD8, 0x59FB,
+	0xECD9, 0x5BC5, 0xECDA, 0x5F15, 0xECDB, 0x5FCD, 0xECDC, 0x6E6E,
+	0xECDD, 0xF9EE, 0xECDE, 0xF9EF, 0xECDF, 0x7D6A, 0xECE0, 0x8335,
+	0xECE1, 0xF9F0, 0xECE2, 0x8693, 0xECE3, 0x8A8D, 0xECE4, 0xF9F1,
+	0xECE5, 0x976D, 0xECE6, 0x9777, 0xECE7, 0xF9F2, 0xECE8, 0xF9F3,
+	0xECE9, 0x4E00, 0xECEA, 0x4F5A, 0xECEB, 0x4F7E, 0xECEC, 0x58F9,
+	0xECED, 0x65E5, 0xECEE, 0x6EA2, 0xECEF, 0x9038, 0xECF0, 0x93B0,
+	0xECF1, 0x99B9, 0xECF2, 0x4EFB, 0xECF3, 0x58EC, 0xECF4, 0x598A,
+	0xECF5, 0x59D9, 0xECF6, 0x6041, 0xECF7, 0xF9F4, 0xECF8, 0xF9F5,
+	0xECF9, 0x7A14, 0xECFA, 0xF9F6, 0xECFB, 0x834F, 0xECFC, 0x8CC3,
+	0xECFD, 0x5165, 0xECFE, 0x5344, 0xEDA1, 0xF9F7, 0xEDA2, 0xF9F8,
+	0xEDA3, 0xF9F9, 0xEDA4, 0x4ECD, 0xEDA5, 0x5269, 0xEDA6, 0x5B55,
+	0xEDA7, 0x82BF, 0xEDA8, 0x4ED4, 0xEDA9, 0x523A, 0xEDAA, 0x54A8,
+	0xEDAB, 0x59C9, 0xEDAC, 0x59FF, 0xEDAD, 0x5B50, 0xEDAE, 0x5B57,
+	0xEDAF, 0x5B5C, 0xEDB0, 0x6063, 0xEDB1, 0x6148, 0xEDB2, 0x6ECB,
+	0xEDB3, 0x7099, 0xEDB4, 0x716E, 0xEDB5, 0x7386, 0xEDB6, 0x74F7,
+	0xEDB7, 0x75B5, 0xEDB8, 0x78C1, 0xEDB9, 0x7D2B, 0xEDBA, 0x8005,
+	0xEDBB, 0x81EA, 0xEDBC, 0x8328, 0xEDBD, 0x8517, 0xEDBE, 0x85C9,
+	0xEDBF, 0x8AEE, 0xEDC0, 0x8CC7, 0xEDC1, 0x96CC, 0xEDC2, 0x4F5C,
+	0xEDC3, 0x52FA, 0xEDC4, 0x56BC, 0xEDC5, 0x65AB, 0xEDC6, 0x6628,
+	0xEDC7, 0x707C, 0xEDC8, 0x70B8, 0xEDC9, 0x7235, 0xEDCA, 0x7DBD,
+	0xEDCB, 0x828D, 0xEDCC, 0x914C, 0xEDCD, 0x96C0, 0xEDCE, 0x9D72,
+	0xEDCF, 0x5B71, 0xEDD0, 0x68E7, 0xEDD1, 0x6B98, 0xEDD2, 0x6F7A,
+	0xEDD3, 0x76DE, 0xEDD4, 0x5C91, 0xEDD5, 0x66AB, 0xEDD6, 0x6F5B,
+	0xEDD7, 0x7BB4, 0xEDD8, 0x7C2A, 0xEDD9, 0x8836, 0xEDDA, 0x96DC,
+	0xEDDB, 0x4E08, 0xEDDC, 0x4ED7, 0xEDDD, 0x5320, 0xEDDE, 0x5834,
+	0xEDDF, 0x58BB, 0xEDE0, 0x58EF, 0xEDE1, 0x596C, 0xEDE2, 0x5C07,
+	0xEDE3, 0x5E33, 0xEDE4, 0x5E84, 0xEDE5, 0x5F35, 0xEDE6, 0x638C,
+	0xEDE7, 0x66B2, 0xEDE8, 0x6756, 0xEDE9, 0x6A1F, 0xEDEA, 0x6AA3,
+	0xEDEB, 0x6B0C, 0xEDEC, 0x6F3F, 0xEDED, 0x7246, 0xEDEE, 0xF9FA,
+	0xEDEF, 0x7350, 0xEDF0, 0x748B, 0xEDF1, 0x7AE0, 0xEDF2, 0x7CA7,
+	0xEDF3, 0x8178, 0xEDF4, 0x81DF, 0xEDF5, 0x81E7, 0xEDF6, 0x838A,
+	0xEDF7, 0x846C, 0xEDF8, 0x8523, 0xEDF9, 0x8594, 0xEDFA, 0x85CF,
+	0xEDFB, 0x88DD, 0xEDFC, 0x8D13, 0xEDFD, 0x91AC, 0xEDFE, 0x9577,
+	0xEEA1, 0x969C, 0xEEA2, 0x518D, 0xEEA3, 0x54C9, 0xEEA4, 0x5728,
+	0xEEA5, 0x5BB0, 0xEEA6, 0x624D, 0xEEA7, 0x6750, 0xEEA8, 0x683D,
+	0xEEA9, 0x6893, 0xEEAA, 0x6E3D, 0xEEAB, 0x6ED3, 0xEEAC, 0x707D,
+	0xEEAD, 0x7E21, 0xEEAE, 0x88C1, 0xEEAF, 0x8CA1, 0xEEB0, 0x8F09,
+	0xEEB1, 0x9F4B, 0xEEB2, 0x9F4E, 0xEEB3, 0x722D, 0xEEB4, 0x7B8F,
+	0xEEB5, 0x8ACD, 0xEEB6, 0x931A, 0xEEB7, 0x4F47, 0xEEB8, 0x4F4E,
+	0xEEB9, 0x5132, 0xEEBA, 0x5480, 0xEEBB, 0x59D0, 0xEEBC, 0x5E95,
+	0xEEBD, 0x62B5, 0xEEBE, 0x6775, 0xEEBF, 0x696E, 0xEEC0, 0x6A17,
+	0xEEC1, 0x6CAE, 0xEEC2, 0x6E1A, 0xEEC3, 0x72D9, 0xEEC4, 0x732A,
+	0xEEC5, 0x75BD, 0xEEC6, 0x7BB8, 0xEEC7, 0x7D35, 0xEEC8, 0x82E7,
+	0xEEC9, 0x83F9, 0xEECA, 0x8457, 0xEECB, 0x85F7, 0xEECC, 0x8A5B,
+	0xEECD, 0x8CAF, 0xEECE, 0x8E87, 0xEECF, 0x9019, 0xEED0, 0x90B8,
+	0xEED1, 0x96CE, 0xEED2, 0x9F5F, 0xEED3, 0x52E3, 0xEED4, 0x540A,
+	0xEED5, 0x5AE1, 0xEED6, 0x5BC2, 0xEED7, 0x6458, 0xEED8, 0x6575,
+	0xEED9, 0x6EF4, 0xEEDA, 0x72C4, 0xEEDB, 0xF9FB, 0xEEDC, 0x7684,
+	0xEEDD, 0x7A4D, 0xEEDE, 0x7B1B, 0xEEDF, 0x7C4D, 0xEEE0, 0x7E3E,
+	0xEEE1, 0x7FDF, 0xEEE2, 0x837B, 0xEEE3, 0x8B2B, 0xEEE4, 0x8CCA,
+	0xEEE5, 0x8D64, 0xEEE6, 0x8DE1, 0xEEE7, 0x8E5F, 0xEEE8, 0x8FEA,
+	0xEEE9, 0x8FF9, 0xEEEA, 0x9069, 0xEEEB, 0x93D1, 0xEEEC, 0x4F43,
+	0xEEED, 0x4F7A, 0xEEEE, 0x50B3, 0xEEEF, 0x5168, 0xEEF0, 0x5178,
+	0xEEF1, 0x524D, 0xEEF2, 0x526A, 0xEEF3, 0x5861, 0xEEF4, 0x587C,
+	0xEEF5, 0x5960, 0xEEF6, 0x5C08, 0xEEF7, 0x5C55, 0xEEF8, 0x5EDB,
+	0xEEF9, 0x609B, 0xEEFA, 0x6230, 0xEEFB, 0x6813, 0xEEFC, 0x6BBF,
+	0xEEFD, 0x6C08, 0xEEFE, 0x6FB1, 0xEFA1, 0x714E, 0xEFA2, 0x7420,
+	0xEFA3, 0x7530, 0xEFA4, 0x7538, 0xEFA5, 0x7551, 0xEFA6, 0x7672,
+	0xEFA7, 0x7B4C, 0xEFA8, 0x7B8B, 0xEFA9, 0x7BAD, 0xEFAA, 0x7BC6,
+	0xEFAB, 0x7E8F, 0xEFAC, 0x8A6E, 0xEFAD, 0x8F3E, 0xEFAE, 0x8F49,
+	0xEFAF, 0x923F, 0xEFB0, 0x9293, 0xEFB1, 0x9322, 0xEFB2, 0x942B,
+	0xEFB3, 0x96FB, 0xEFB4, 0x985A, 0xEFB5, 0x986B, 0xEFB6, 0x991E,
+	0xEFB7, 0x5207, 0xEFB8, 0x622A, 0xEFB9, 0x6298, 0xEFBA, 0x6D59,
+	0xEFBB, 0x7664, 0xEFBC, 0x7ACA, 0xEFBD, 0x7BC0, 0xEFBE, 0x7D76,
+	0xEFBF, 0x5360, 0xEFC0, 0x5CBE, 0xEFC1, 0x5E97, 0xEFC2, 0x6F38,
+	0xEFC3, 0x70B9, 0xEFC4, 0x7C98, 0xEFC5, 0x9711, 0xEFC6, 0x9B8E,
+	0xEFC7, 0x9EDE, 0xEFC8, 0x63A5, 0xEFC9, 0x647A, 0xEFCA, 0x8776,
+	0xEFCB, 0x4E01, 0xEFCC, 0x4E95, 0xEFCD, 0x4EAD, 0xEFCE, 0x505C,
+	0xEFCF, 0x5075, 0xEFD0, 0x5448, 0xEFD1, 0x59C3, 0xEFD2, 0x5B9A,
+	0xEFD3, 0x5E40, 0xEFD4, 0x5EAD, 0xEFD5, 0x5EF7, 0xEFD6, 0x5F81,
+	0xEFD7, 0x60C5, 0xEFD8, 0x633A, 0xEFD9, 0x653F, 0xEFDA, 0x6574,
+	0xEFDB, 0x65CC, 0xEFDC, 0x6676, 0xEFDD, 0x6678, 0xEFDE, 0x67FE,
+	0xEFDF, 0x6968, 0xEFE0, 0x6A89, 0xEFE1, 0x6B63, 0xEFE2, 0x6C40,
+	0xEFE3, 0x6DC0, 0xEFE4, 0x6DE8, 0xEFE5, 0x6E1F, 0xEFE6, 0x6E5E,
+	0xEFE7, 0x701E, 0xEFE8, 0x70A1, 0xEFE9, 0x738E, 0xEFEA, 0x73FD,
+	0xEFEB, 0x753A, 0xEFEC, 0x775B, 0xEFED, 0x7887, 0xEFEE, 0x798E,
+	0xEFEF, 0x7A0B, 0xEFF0, 0x7A7D, 0xEFF1, 0x7CBE, 0xEFF2, 0x7D8E,
+	0xEFF3, 0x8247, 0xEFF4, 0x8A02, 0xEFF5, 0x8AEA, 0xEFF6, 0x8C9E,
+	0xEFF7, 0x912D, 0xEFF8, 0x914A, 0xEFF9, 0x91D8, 0xEFFA, 0x9266,
+	0xEFFB, 0x92CC, 0xEFFC, 0x9320, 0xEFFD, 0x9706, 0xEFFE, 0x9756,
+	0xF0A1, 0x975C, 0xF0A2, 0x9802, 0xF0A3, 0x9F0E, 0xF0A4, 0x5236,
+	0xF0A5, 0x5291, 0xF0A6, 0x557C, 0xF0A7, 0x5824, 0xF0A8, 0x5E1D,
+	0xF0A9, 0x5F1F, 0xF0AA, 0x608C, 0xF0AB, 0x63D0, 0xF0AC, 0x68AF,
+	0xF0AD, 0x6FDF, 0xF0AE, 0x796D, 0xF0AF, 0x7B2C, 0xF0B0, 0x81CD,
+	0xF0B1, 0x85BA, 0xF0B2, 0x88FD, 0xF0B3, 0x8AF8, 0xF0B4, 0x8E44,
+	0xF0B5, 0x918D, 0xF0B6, 0x9664, 0xF0B7, 0x969B, 0xF0B8, 0x973D,
+	0xF0B9, 0x984C, 0xF0BA, 0x9F4A, 0xF0BB, 0x4FCE, 0xF0BC, 0x5146,
+	0xF0BD, 0x51CB, 0xF0BE, 0x52A9, 0xF0BF, 0x5632, 0xF0C0, 0x5F14,
+	0xF0C1, 0x5F6B, 0xF0C2, 0x63AA, 0xF0C3, 0x64CD, 0xF0C4, 0x65E9,
+	0xF0C5, 0x6641, 0xF0C6, 0x66FA, 0xF0C7, 0x66F9, 0xF0C8, 0x671D,
+	0xF0C9, 0x689D, 0xF0CA, 0x68D7, 0xF0CB, 0x69FD, 0xF0CC, 0x6F15,
+	0xF0CD, 0x6F6E, 0xF0CE, 0x7167, 0xF0CF, 0x71E5, 0xF0D0, 0x722A,
+	0xF0D1, 0x74AA, 0xF0D2, 0x773A, 0xF0D3, 0x7956, 0xF0D4, 0x795A,
+	0xF0D5, 0x79DF, 0xF0D6, 0x7A20, 0xF0D7, 0x7A95, 0xF0D8, 0x7C97,
+	0xF0D9, 0x7CDF, 0xF0DA, 0x7D44, 0xF0DB, 0x7E70, 0xF0DC, 0x8087,
+	0xF0DD, 0x85FB, 0xF0DE, 0x86A4, 0xF0DF, 0x8A54, 0xF0E0, 0x8ABF,
+	0xF0E1, 0x8D99, 0xF0E2, 0x8E81, 0xF0E3, 0x9020, 0xF0E4, 0x906D,
+	0xF0E5, 0x91E3, 0xF0E6, 0x963B, 0xF0E7, 0x96D5, 0xF0E8, 0x9CE5,
+	0xF0E9, 0x65CF, 0xF0EA, 0x7C07, 0xF0EB, 0x8DB3, 0xF0EC, 0x93C3,
+	0xF0ED, 0x5B58, 0xF0EE, 0x5C0A, 0xF0EF, 0x5352, 0xF0F0, 0x62D9,
+	0xF0F1, 0x731D, 0xF0F2, 0x5027, 0xF0F3, 0x5B97, 0xF0F4, 0x5F9E,
+	0xF0F5, 0x60B0, 0xF0F6, 0x616B, 0xF0F7, 0x68D5, 0xF0F8, 0x6DD9,
+	0xF0F9, 0x742E, 0xF0FA, 0x7A2E, 0xF0FB, 0x7D42, 0xF0FC, 0x7D9C,
+	0xF0FD, 0x7E31, 0xF0FE, 0x816B, 0xF1A1, 0x8E2A, 0xF1A2, 0x8E35,
+	0xF1A3, 0x937E, 0xF1A4, 0x9418, 0xF1A5, 0x4F50, 0xF1A6, 0x5750,
+	0xF1A7, 0x5DE6, 0xF1A8, 0x5EA7, 0xF1A9, 0x632B, 0xF1AA, 0x7F6A,
+	0xF1AB, 0x4E3B, 0xF1AC, 0x4F4F, 0xF1AD, 0x4F8F, 0xF1AE, 0x505A,
+	0xF1AF, 0x59DD, 0xF1B0, 0x80C4, 0xF1B1, 0x546A, 0xF1B2, 0x5468,
+	0xF1B3, 0x55FE, 0xF1B4, 0x594F, 0xF1B5, 0x5B99, 0xF1B6, 0x5DDE,
+	0xF1B7, 0x5EDA, 0xF1B8, 0x665D, 0xF1B9, 0x6731, 0xF1BA, 0x67F1,
+	0xF1BB, 0x682A, 0xF1BC, 0x6CE8, 0xF1BD, 0x6D32, 0xF1BE, 0x6E4A,
+	0xF1BF, 0x6F8D, 0xF1C0, 0x70B7, 0xF1C1, 0x73E0, 0xF1C2, 0x7587,
+	0xF1C3, 0x7C4C, 0xF1C4, 0x7D02, 0xF1C5, 0x7D2C, 0xF1C6, 0x7DA2,
+	0xF1C7, 0x821F, 0xF1C8, 0x86DB, 0xF1C9, 0x8A3B, 0xF1CA, 0x8A85,
+	0xF1CB, 0x8D70, 0xF1CC, 0x8E8A, 0xF1CD, 0x8F33, 0xF1CE, 0x9031,
+	0xF1CF, 0x914E, 0xF1D0, 0x9152, 0xF1D1, 0x9444, 0xF1D2, 0x99D0,
+	0xF1D3, 0x7AF9, 0xF1D4, 0x7CA5, 0xF1D5, 0x4FCA, 0xF1D6, 0x5101,
+	0xF1D7, 0x51C6, 0xF1D8, 0x57C8, 0xF1D9, 0x5BEF, 0xF1DA, 0x5CFB,
+	0xF1DB, 0x6659, 0xF1DC, 0x6A3D, 0xF1DD, 0x6D5A, 0xF1DE, 0x6E96,
+	0xF1DF, 0x6FEC, 0xF1E0, 0x710C, 0xF1E1, 0x756F, 0xF1E2, 0x7AE3,
+	0xF1E3, 0x8822, 0xF1E4, 0x9021, 0xF1E5, 0x9075, 0xF1E6, 0x96CB,
+	0xF1E7, 0x99FF, 0xF1E8, 0x8301, 0xF1E9, 0x4E2D, 0xF1EA, 0x4EF2,
+	0xF1EB, 0x8846, 0xF1EC, 0x91CD, 0xF1ED, 0x537D, 0xF1EE, 0x6ADB,
+	0xF1EF, 0x696B, 0xF1F0, 0x6C41, 0xF1F1, 0x847A, 0xF1F2, 0x589E,
+	0xF1F3, 0x618E, 0xF1F4, 0x66FE, 0xF1F5, 0x62EF, 0xF1F6, 0x70DD,
+	0xF1F7, 0x7511, 0xF1F8, 0x75C7, 0xF1F9, 0x7E52, 0xF1FA, 0x84B8,
+	0xF1FB, 0x8B49, 0xF1FC, 0x8D08, 0xF1FD, 0x4E4B, 0xF1FE, 0x53EA,
+	0xF2A1, 0x54AB, 0xF2A2, 0x5730, 0xF2A3, 0x5740, 0xF2A4, 0x5FD7,
+	0xF2A5, 0x6301, 0xF2A6, 0x6307, 0xF2A7, 0x646F, 0xF2A8, 0x652F,
+	0xF2A9, 0x65E8, 0xF2AA, 0x667A, 0xF2AB, 0x679D, 0xF2AC, 0x67B3,
+	0xF2AD, 0x6B62, 0xF2AE, 0x6C60, 0xF2AF, 0x6C9A, 0xF2B0, 0x6F2C,
+	0xF2B1, 0x77E5, 0xF2B2, 0x7825, 0xF2B3, 0x7949, 0xF2B4, 0x7957,
+	0xF2B5, 0x7D19, 0xF2B6, 0x80A2, 0xF2B7, 0x8102, 0xF2B8, 0x81F3,
+	0xF2B9, 0x829D, 0xF2BA, 0x82B7, 0xF2BB, 0x8718, 0xF2BC, 0x8A8C,
+	0xF2BD, 0xF9FC, 0xF2BE, 0x8D04, 0xF2BF, 0x8DBE, 0xF2C0, 0x9072,
+	0xF2C1, 0x76F4, 0xF2C2, 0x7A19, 0xF2C3, 0x7A37, 0xF2C4, 0x7E54,
+	0xF2C5, 0x8077, 0xF2C6, 0x5507, 0xF2C7, 0x55D4, 0xF2C8, 0x5875,
+	0xF2C9, 0x632F, 0xF2CA, 0x6422, 0xF2CB, 0x6649, 0xF2CC, 0x664B,
+	0xF2CD, 0x686D, 0xF2CE, 0x699B, 0xF2CF, 0x6B84, 0xF2D0, 0x6D25,
+	0xF2D1, 0x6EB1, 0xF2D2, 0x73CD, 0xF2D3, 0x7468, 0xF2D4, 0x74A1,
+	0xF2D5, 0x755B, 0xF2D6, 0x75B9, 0xF2D7, 0x76E1, 0xF2D8, 0x771E,
+	0xF2D9, 0x778B, 0xF2DA, 0x79E6, 0xF2DB, 0x7E09, 0xF2DC, 0x7E1D,
+	0xF2DD, 0x81FB, 0xF2DE, 0x852F, 0xF2DF, 0x8897, 0xF2E0, 0x8A3A,
+	0xF2E1, 0x8CD1, 0xF2E2, 0x8EEB, 0xF2E3, 0x8FB0, 0xF2E4, 0x9032,
+	0xF2E5, 0x93AD, 0xF2E6, 0x9663, 0xF2E7, 0x9673, 0xF2E8, 0x9707,
+	0xF2E9, 0x4F84, 0xF2EA, 0x53F1, 0xF2EB, 0x59EA, 0xF2EC, 0x5AC9,
+	0xF2ED, 0x5E19, 0xF2EE, 0x684E, 0xF2EF, 0x74C6, 0xF2F0, 0x75BE,
+	0xF2F1, 0x79E9, 0xF2F2, 0x7A92, 0xF2F3, 0x81A3, 0xF2F4, 0x86ED,
+	0xF2F5, 0x8CEA, 0xF2F6, 0x8DCC, 0xF2F7, 0x8FED, 0xF2F8, 0x659F,
+	0xF2F9, 0x6715, 0xF2FA, 0xF9FD, 0xF2FB, 0x57F7, 0xF2FC, 0x6F57,
+	0xF2FD, 0x7DDD, 0xF2FE, 0x8F2F, 0xF3A1, 0x93F6, 0xF3A2, 0x96C6,
+	0xF3A3, 0x5FB5, 0xF3A4, 0x61F2, 0xF3A5, 0x6F84, 0xF3A6, 0x4E14,
+	0xF3A7, 0x4F98, 0xF3A8, 0x501F, 0xF3A9, 0x53C9, 0xF3AA, 0x55DF,
+	0xF3AB, 0x5D6F, 0xF3AC, 0x5DEE, 0xF3AD, 0x6B21, 0xF3AE, 0x6B64,
+	0xF3AF, 0x78CB, 0xF3B0, 0x7B9A, 0xF3B1, 0xF9FE, 0xF3B2, 0x8E49,
+	0xF3B3, 0x8ECA, 0xF3B4, 0x906E, 0xF3B5, 0x6349, 0xF3B6, 0x643E,
+	0xF3B7, 0x7740, 0xF3B8, 0x7A84, 0xF3B9, 0x932F, 0xF3BA, 0x947F,
+	0xF3BB, 0x9F6A, 0xF3BC, 0x64B0, 0xF3BD, 0x6FAF, 0xF3BE, 0x71E6,
+	0xF3BF, 0x74A8, 0xF3C0, 0x74DA, 0xF3C1, 0x7AC4, 0xF3C2, 0x7C12,
+	0xF3C3, 0x7E82, 0xF3C4, 0x7CB2, 0xF3C5, 0x7E98, 0xF3C6, 0x8B9A,
+	0xF3C7, 0x8D0A, 0xF3C8, 0x947D, 0xF3C9, 0x9910, 0xF3CA, 0x994C,
+	0xF3CB, 0x5239, 0xF3CC, 0x5BDF, 0xF3CD, 0x64E6, 0xF3CE, 0x672D,
+	0xF3CF, 0x7D2E, 0xF3D0, 0x50ED, 0xF3D1, 0x53C3, 0xF3D2, 0x5879,
+	0xF3D3, 0x6158, 0xF3D4, 0x6159, 0xF3D5, 0x61FA, 0xF3D6, 0x65AC,
+	0xF3D7, 0x7AD9, 0xF3D8, 0x8B92, 0xF3D9, 0x8B96, 0xF3DA, 0x5009,
+	0xF3DB, 0x5021, 0xF3DC, 0x5275, 0xF3DD, 0x5531, 0xF3DE, 0x5A3C,
+	0xF3DF, 0x5EE0, 0xF3E0, 0x5F70, 0xF3E1, 0x6134, 0xF3E2, 0x655E,
+	0xF3E3, 0x660C, 0xF3E4, 0x6636, 0xF3E5, 0x66A2, 0xF3E6, 0x69CD,
+	0xF3E7, 0x6EC4, 0xF3E8, 0x6F32, 0xF3E9, 0x7316, 0xF3EA, 0x7621,
+	0xF3EB, 0x7A93, 0xF3EC, 0x8139, 0xF3ED, 0x8259, 0xF3EE, 0x83D6,
+	0xF3EF, 0x84BC, 0xF3F0, 0x50B5, 0xF3F1, 0x57F0, 0xF3F2, 0x5BC0,
+	0xF3F3, 0x5BE8, 0xF3F4, 0x5F69, 0xF3F5, 0x63A1, 0xF3F6, 0x7826,
+	0xF3F7, 0x7DB5, 0xF3F8, 0x83DC, 0xF3F9, 0x8521, 0xF3FA, 0x91C7,
+	0xF3FB, 0x91F5, 0xF3FC, 0x518A, 0xF3FD, 0x67F5, 0xF3FE, 0x7B56,
+	0xF4A1, 0x8CAC, 0xF4A2, 0x51C4, 0xF4A3, 0x59BB, 0xF4A4, 0x60BD,
+	0xF4A5, 0x8655, 0xF4A6, 0x501C, 0xF4A7, 0xF9FF, 0xF4A8, 0x5254,
+	0xF4A9, 0x5C3A, 0xF4AA, 0x617D, 0xF4AB, 0x621A, 0xF4AC, 0x62D3,
+	0xF4AD, 0x64F2, 0xF4AE, 0x65A5, 0xF4AF, 0x6ECC, 0xF4B0, 0x7620,
+	0xF4B1, 0x810A, 0xF4B2, 0x8E60, 0xF4B3, 0x965F, 0xF4B4, 0x96BB,
+	0xF4B5, 0x4EDF, 0xF4B6, 0x5343, 0xF4B7, 0x5598, 0xF4B8, 0x5929,
+	0xF4B9, 0x5DDD, 0xF4BA, 0x64C5, 0xF4BB, 0x6CC9, 0xF4BC, 0x6DFA,
+	0xF4BD, 0x7394, 0xF4BE, 0x7A7F, 0xF4BF, 0x821B, 0xF4C0, 0x85A6,
+	0xF4C1, 0x8CE4, 0xF4C2, 0x8E10, 0xF4C3, 0x9077, 0xF4C4, 0x91E7,
+	0xF4C5, 0x95E1, 0xF4C6, 0x9621, 0xF4C7, 0x97C6, 0xF4C8, 0x51F8,
+	0xF4C9, 0x54F2, 0xF4CA, 0x5586, 0xF4CB, 0x5FB9, 0xF4CC, 0x64A4,
+	0xF4CD, 0x6F88, 0xF4CE, 0x7DB4, 0xF4CF, 0x8F1F, 0xF4D0, 0x8F4D,
+	0xF4D1, 0x9435, 0xF4D2, 0x50C9, 0xF4D3, 0x5C16, 0xF4D4, 0x6CBE,
+	0xF4D5, 0x6DFB, 0xF4D6, 0x751B, 0xF4D7, 0x77BB, 0xF4D8, 0x7C3D,
+	0xF4D9, 0x7C64, 0xF4DA, 0x8A79, 0xF4DB, 0x8AC2, 0xF4DC, 0x581E,
+	0xF4DD, 0x59BE, 0xF4DE, 0x5E16, 0xF4DF, 0x6377, 0xF4E0, 0x7252,
+	0xF4E1, 0x758A, 0xF4E2, 0x776B, 0xF4E3, 0x8ADC, 0xF4E4, 0x8CBC,
+	0xF4E5, 0x8F12, 0xF4E6, 0x5EF3, 0xF4E7, 0x6674, 0xF4E8, 0x6DF8,
+	0xF4E9, 0x807D, 0xF4EA, 0x83C1, 0xF4EB, 0x8ACB, 0xF4EC, 0x9751,
+	0xF4ED, 0x9BD6, 0xF4EE, 0xFA00, 0xF4EF, 0x5243, 0xF4F0, 0x66FF,
+	0xF4F1, 0x6D95, 0xF4F2, 0x6EEF, 0xF4F3, 0x7DE0, 0xF4F4, 0x8AE6,
+	0xF4F5, 0x902E, 0xF4F6, 0x905E, 0xF4F7, 0x9AD4, 0xF4F8, 0x521D,
+	0xF4F9, 0x527F, 0xF4FA, 0x54E8, 0xF4FB, 0x6194, 0xF4FC, 0x6284,
+	0xF4FD, 0x62DB, 0xF4FE, 0x68A2, 0xF5A1, 0x6912, 0xF5A2, 0x695A,
+	0xF5A3, 0x6A35, 0xF5A4, 0x7092, 0xF5A5, 0x7126, 0xF5A6, 0x785D,
+	0xF5A7, 0x7901, 0xF5A8, 0x790E, 0xF5A9, 0x79D2, 0xF5AA, 0x7A0D,
+	0xF5AB, 0x8096, 0xF5AC, 0x8278, 0xF5AD, 0x82D5, 0xF5AE, 0x8349,
+	0xF5AF, 0x8549, 0xF5B0, 0x8C82, 0xF5B1, 0x8D85, 0xF5B2, 0x9162,
+	0xF5B3, 0x918B, 0xF5B4, 0x91AE, 0xF5B5, 0x4FC3, 0xF5B6, 0x56D1,
+	0xF5B7, 0x71ED, 0xF5B8, 0x77D7, 0xF5B9, 0x8700, 0xF5BA, 0x89F8,
+	0xF5BB, 0x5BF8, 0xF5BC, 0x5FD6, 0xF5BD, 0x6751, 0xF5BE, 0x90A8,
+	0xF5BF, 0x53E2, 0xF5C0, 0x585A, 0xF5C1, 0x5BF5, 0xF5C2, 0x60A4,
+	0xF5C3, 0x6181, 0xF5C4, 0x6460, 0xF5C5, 0x7E3D, 0xF5C6, 0x8070,
+	0xF5C7, 0x8525, 0xF5C8, 0x9283, 0xF5C9, 0x64AE, 0xF5CA, 0x50AC,
+	0xF5CB, 0x5D14, 0xF5CC, 0x6700, 0xF5CD, 0x589C, 0xF5CE, 0x62BD,
+	0xF5CF, 0x63A8, 0xF5D0, 0x690E, 0xF5D1, 0x6978, 0xF5D2, 0x6A1E,
+	0xF5D3, 0x6E6B, 0xF5D4, 0x76BA, 0xF5D5, 0x79CB, 0xF5D6, 0x82BB,
+	0xF5D7, 0x8429, 0xF5D8, 0x8ACF, 0xF5D9, 0x8DA8, 0xF5DA, 0x8FFD,
+	0xF5DB, 0x9112, 0xF5DC, 0x914B, 0xF5DD, 0x919C, 0xF5DE, 0x9310,
+	0xF5DF, 0x9318, 0xF5E0, 0x939A, 0xF5E1, 0x96DB, 0xF5E2, 0x9A36,
+	0xF5E3, 0x9C0D, 0xF5E4, 0x4E11, 0xF5E5, 0x755C, 0xF5E6, 0x795D,
+	0xF5E7, 0x7AFA, 0xF5E8, 0x7B51, 0xF5E9, 0x7BC9, 0xF5EA, 0x7E2E,
+	0xF5EB, 0x84C4, 0xF5EC, 0x8E59, 0xF5ED, 0x8E74, 0xF5EE, 0x8EF8,
+	0xF5EF, 0x9010, 0xF5F0, 0x6625, 0xF5F1, 0x693F, 0xF5F2, 0x7443,
+	0xF5F3, 0x51FA, 0xF5F4, 0x672E, 0xF5F5, 0x9EDC, 0xF5F6, 0x5145,
+	0xF5F7, 0x5FE0, 0xF5F8, 0x6C96, 0xF5F9, 0x87F2, 0xF5FA, 0x885D,
+	0xF5FB, 0x8877, 0xF5FC, 0x60B4, 0xF5FD, 0x81B5, 0xF5FE, 0x8403,
+	0xF6A1, 0x8D05, 0xF6A2, 0x53D6, 0xF6A3, 0x5439, 0xF6A4, 0x5634,
+	0xF6A5, 0x5A36, 0xF6A6, 0x5C31, 0xF6A7, 0x708A, 0xF6A8, 0x7FE0,
+	0xF6A9, 0x805A, 0xF6AA, 0x8106, 0xF6AB, 0x81ED, 0xF6AC, 0x8DA3,
+	0xF6AD, 0x9189, 0xF6AE, 0x9A5F, 0xF6AF, 0x9DF2, 0xF6B0, 0x5074,
+	0xF6B1, 0x4EC4, 0xF6B2, 0x53A0, 0xF6B3, 0x60FB, 0xF6B4, 0x6E2C,
+	0xF6B5, 0x5C64, 0xF6B6, 0x4F88, 0xF6B7, 0x5024, 0xF6B8, 0x55E4,
+	0xF6B9, 0x5CD9, 0xF6BA, 0x5E5F, 0xF6BB, 0x6065, 0xF6BC, 0x6894,
+	0xF6BD, 0x6CBB, 0xF6BE, 0x6DC4, 0xF6BF, 0x71BE, 0xF6C0, 0x75D4,
+	0xF6C1, 0x75F4, 0xF6C2, 0x7661, 0xF6C3, 0x7A1A, 0xF6C4, 0x7A49,
+	0xF6C5, 0x7DC7, 0xF6C6, 0x7DFB, 0xF6C7, 0x7F6E, 0xF6C8, 0x81F4,
+	0xF6C9, 0x86A9, 0xF6CA, 0x8F1C, 0xF6CB, 0x96C9, 0xF6CC, 0x99B3,
+	0xF6CD, 0x9F52, 0xF6CE, 0x5247, 0xF6CF, 0x52C5, 0xF6D0, 0x98ED,
+	0xF6D1, 0x89AA, 0xF6D2, 0x4E03, 0xF6D3, 0x67D2, 0xF6D4, 0x6F06,
+	0xF6D5, 0x4FB5, 0xF6D6, 0x5BE2, 0xF6D7, 0x6795, 0xF6D8, 0x6C88,
+	0xF6D9, 0x6D78, 0xF6DA, 0x741B, 0xF6DB, 0x7827, 0xF6DC, 0x91DD,
+	0xF6DD, 0x937C, 0xF6DE, 0x87C4, 0xF6DF, 0x79E4, 0xF6E0, 0x7A31,
+	0xF6E1, 0x5FEB, 0xF6E2, 0x4ED6, 0xF6E3, 0x54A4, 0xF6E4, 0x553E,
+	0xF6E5, 0x58AE, 0xF6E6, 0x59A5, 0xF6E7, 0x60F0, 0xF6E8, 0x6253,
+	0xF6E9, 0x62D6, 0xF6EA, 0x6736, 0xF6EB, 0x6955, 0xF6EC, 0x8235,
+	0xF6ED, 0x9640, 0xF6EE, 0x99B1, 0xF6EF, 0x99DD, 0xF6F0, 0x502C,
+	0xF6F1, 0x5353, 0xF6F2, 0x5544, 0xF6F3, 0x577C, 0xF6F4, 0xFA01,
+	0xF6F5, 0x6258, 0xF6F6, 0xFA02, 0xF6F7, 0x64E2, 0xF6F8, 0x666B,
+	0xF6F9, 0x67DD, 0xF6FA, 0x6FC1, 0xF6FB, 0x6FEF, 0xF6FC, 0x7422,
+	0xF6FD, 0x7438, 0xF6FE, 0x8A17, 0xF7A1, 0x9438, 0xF7A2, 0x5451,
+	0xF7A3, 0x5606, 0xF7A4, 0x5766, 0xF7A5, 0x5F48, 0xF7A6, 0x619A,
+	0xF7A7, 0x6B4E, 0xF7A8, 0x7058, 0xF7A9, 0x70AD, 0xF7AA, 0x7DBB,
+	0xF7AB, 0x8A95, 0xF7AC, 0x596A, 0xF7AD, 0x812B, 0xF7AE, 0x63A2,
+	0xF7AF, 0x7708, 0xF7B0, 0x803D, 0xF7B1, 0x8CAA, 0xF7B2, 0x5854,
+	0xF7B3, 0x642D, 0xF7B4, 0x69BB, 0xF7B5, 0x5B95, 0xF7B6, 0x5E11,
+	0xF7B7, 0x6E6F, 0xF7B8, 0xFA03, 0xF7B9, 0x8569, 0xF7BA, 0x514C,
+	0xF7BB, 0x53F0, 0xF7BC, 0x592A, 0xF7BD, 0x6020, 0xF7BE, 0x614B,
+	0xF7BF, 0x6B86, 0xF7C0, 0x6C70, 0xF7C1, 0x6CF0, 0xF7C2, 0x7B1E,
+	0xF7C3, 0x80CE, 0xF7C4, 0x82D4, 0xF7C5, 0x8DC6, 0xF7C6, 0x90B0,
+	0xF7C7, 0x98B1, 0xF7C8, 0xFA04, 0xF7C9, 0x64C7, 0xF7CA, 0x6FA4,
+	0xF7CB, 0x6491, 0xF7CC, 0x6504, 0xF7CD, 0x514E, 0xF7CE, 0x5410,
+	0xF7CF, 0x571F, 0xF7D0, 0x8A0E, 0xF7D1, 0x615F, 0xF7D2, 0x6876,
+	0xF7D3, 0xFA05, 0xF7D4, 0x75DB, 0xF7D5, 0x7B52, 0xF7D6, 0x7D71,
+	0xF7D7, 0x901A, 0xF7D8, 0x5806, 0xF7D9, 0x69CC, 0xF7DA, 0x817F,
+	0xF7DB, 0x892A, 0xF7DC, 0x9000, 0xF7DD, 0x9839, 0xF7DE, 0x5078,
+	0xF7DF, 0x5957, 0xF7E0, 0x59AC, 0xF7E1, 0x6295, 0xF7E2, 0x900F,
+	0xF7E3, 0x9B2A, 0xF7E4, 0x615D, 0xF7E5, 0x7279, 0xF7E6, 0x95D6,
+	0xF7E7, 0x5761, 0xF7E8, 0x5A46, 0xF7E9, 0x5DF4, 0xF7EA, 0x628A,
+	0xF7EB, 0x64AD, 0xF7EC, 0x64FA, 0xF7ED, 0x6777, 0xF7EE, 0x6CE2,
+	0xF7EF, 0x6D3E, 0xF7F0, 0x722C, 0xF7F1, 0x7436, 0xF7F2, 0x7834,
+	0xF7F3, 0x7F77, 0xF7F4, 0x82AD, 0xF7F5, 0x8DDB, 0xF7F6, 0x9817,
+	0xF7F7, 0x5224, 0xF7F8, 0x5742, 0xF7F9, 0x677F, 0xF7FA, 0x7248,
+	0xF7FB, 0x74E3, 0xF7FC, 0x8CA9, 0xF7FD, 0x8FA6, 0xF7FE, 0x9211,
+	0xF8A1, 0x962A, 0xF8A2, 0x516B, 0xF8A3, 0x53ED, 0xF8A4, 0x634C,
+	0xF8A5, 0x4F69, 0xF8A6, 0x5504, 0xF8A7, 0x6096, 0xF8A8, 0x6557,
+	0xF8A9, 0x6C9B, 0xF8AA, 0x6D7F, 0xF8AB, 0x724C, 0xF8AC, 0x72FD,
+	0xF8AD, 0x7A17, 0xF8AE, 0x8987, 0xF8AF, 0x8C9D, 0xF8B0, 0x5F6D,
+	0xF8B1, 0x6F8E, 0xF8B2, 0x70F9, 0xF8B3, 0x81A8, 0xF8B4, 0x610E,
+	0xF8B5, 0x4FBF, 0xF8B6, 0x504F, 0xF8B7, 0x6241, 0xF8B8, 0x7247,
+	0xF8B9, 0x7BC7, 0xF8BA, 0x7DE8, 0xF8BB, 0x7FE9, 0xF8BC, 0x904D,
+	0xF8BD, 0x97AD, 0xF8BE, 0x9A19, 0xF8BF, 0x8CB6, 0xF8C0, 0x576A,
+	0xF8C1, 0x5E73, 0xF8C2, 0x67B0, 0xF8C3, 0x840D, 0xF8C4, 0x8A55,
+	0xF8C5, 0x5420, 0xF8C6, 0x5B16, 0xF8C7, 0x5E63, 0xF8C8, 0x5EE2,
+	0xF8C9, 0x5F0A, 0xF8CA, 0x6583, 0xF8CB, 0x80BA, 0xF8CC, 0x853D,
+	0xF8CD, 0x9589, 0xF8CE, 0x965B, 0xF8CF, 0x4F48, 0xF8D0, 0x5305,
+	0xF8D1, 0x530D, 0xF8D2, 0x530F, 0xF8D3, 0x5486, 0xF8D4, 0x54FA,
+	0xF8D5, 0x5703, 0xF8D6, 0x5E03, 0xF8D7, 0x6016, 0xF8D8, 0x629B,
+	0xF8D9, 0x62B1, 0xF8DA, 0x6355, 0xF8DB, 0xFA06, 0xF8DC, 0x6CE1,
+	0xF8DD, 0x6D66, 0xF8DE, 0x75B1, 0xF8DF, 0x7832, 0xF8E0, 0x80DE,
+	0xF8E1, 0x812F, 0xF8E2, 0x82DE, 0xF8E3, 0x8461, 0xF8E4, 0x84B2,
+	0xF8E5, 0x888D, 0xF8E6, 0x8912, 0xF8E7, 0x900B, 0xF8E8, 0x92EA,
+	0xF8E9, 0x98FD, 0xF8EA, 0x9B91, 0xF8EB, 0x5E45, 0xF8EC, 0x66B4,
+	0xF8ED, 0x66DD, 0xF8EE, 0x7011, 0xF8EF, 0x7206, 0xF8F0, 0xFA07,
+	0xF8F1, 0x4FF5, 0xF8F2, 0x527D, 0xF8F3, 0x5F6A, 0xF8F4, 0x6153,
+	0xF8F5, 0x6753, 0xF8F6, 0x6A19, 0xF8F7, 0x6F02, 0xF8F8, 0x74E2,
+	0xF8F9, 0x7968, 0xF8FA, 0x8868, 0xF8FB, 0x8C79, 0xF8FC, 0x98C7,
+	0xF8FD, 0x98C4, 0xF8FE, 0x9A43, 0xF9A1, 0x54C1, 0xF9A2, 0x7A1F,
+	0xF9A3, 0x6953, 0xF9A4, 0x8AF7, 0xF9A5, 0x8C4A, 0xF9A6, 0x98A8,
+	0xF9A7, 0x99AE, 0xF9A8, 0x5F7C, 0xF9A9, 0x62AB, 0xF9AA, 0x75B2,
+	0xF9AB, 0x76AE, 0xF9AC, 0x88AB, 0xF9AD, 0x907F, 0xF9AE, 0x9642,
+	0xF9AF, 0x5339, 0xF9B0, 0x5F3C, 0xF9B1, 0x5FC5, 0xF9B2, 0x6CCC,
+	0xF9B3, 0x73CC, 0xF9B4, 0x7562, 0xF9B5, 0x758B, 0xF9B6, 0x7B46,
+	0xF9B7, 0x82FE, 0xF9B8, 0x999D, 0xF9B9, 0x4E4F, 0xF9BA, 0x903C,
+	0xF9BB, 0x4E0B, 0xF9BC, 0x4F55, 0xF9BD, 0x53A6, 0xF9BE, 0x590F,
+	0xF9BF, 0x5EC8, 0xF9C0, 0x6630, 0xF9C1, 0x6CB3, 0xF9C2, 0x7455,
+	0xF9C3, 0x8377, 0xF9C4, 0x8766, 0xF9C5, 0x8CC0, 0xF9C6, 0x9050,
+	0xF9C7, 0x971E, 0xF9C8, 0x9C15, 0xF9C9, 0x58D1, 0xF9CA, 0x5B78,
+	0xF9CB, 0x8650, 0xF9CC, 0x8B14, 0xF9CD, 0x9DB4, 0xF9CE, 0x5BD2,
+	0xF9CF, 0x6068, 0xF9D0, 0x608D, 0xF9D1, 0x65F1, 0xF9D2, 0x6C57,
+	0xF9D3, 0x6F22, 0xF9D4, 0x6FA3, 0xF9D5, 0x701A, 0xF9D6, 0x7F55,
+	0xF9D7, 0x7FF0, 0xF9D8, 0x9591, 0xF9D9, 0x9592, 0xF9DA, 0x9650,
+	0xF9DB, 0x97D3, 0xF9DC, 0x5272, 0xF9DD, 0x8F44, 0xF9DE, 0x51FD,
+	0xF9DF, 0x542B, 0xF9E0, 0x54B8, 0xF9E1, 0x5563, 0xF9E2, 0x558A,
+	0xF9E3, 0x6ABB, 0xF9E4, 0x6DB5, 0xF9E5, 0x7DD8, 0xF9E6, 0x8266,
+	0xF9E7, 0x929C, 0xF9E8, 0x9677, 0xF9E9, 0x9E79, 0xF9EA, 0x5408,
+	0xF9EB, 0x54C8, 0xF9EC, 0x76D2, 0xF9ED, 0x86E4, 0xF9EE, 0x95A4,
+	0xF9EF, 0x95D4, 0xF9F0, 0x965C, 0xF9F1, 0x4EA2, 0xF9F2, 0x4F09,
+	0xF9F3, 0x59EE, 0xF9F4, 0x5AE6, 0xF9F5, 0x5DF7, 0xF9F6, 0x6052,
+	0xF9F7, 0x6297, 0xF9F8, 0x676D, 0xF9F9, 0x6841, 0xF9FA, 0x6C86,
+	0xF9FB, 0x6E2F, 0xF9FC, 0x7F38, 0xF9FD, 0x809B, 0xF9FE, 0x822A,
+	0xFAA1, 0xFA08, 0xFAA2, 0xFA09, 0xFAA3, 0x9805, 0xFAA4, 0x4EA5,
+	0xFAA5, 0x5055, 0xFAA6, 0x54B3, 0xFAA7, 0x5793, 0xFAA8, 0x595A,
+	0xFAA9, 0x5B69, 0xFAAA, 0x5BB3, 0xFAAB, 0x61C8, 0xFAAC, 0x6977,
+	0xFAAD, 0x6D77, 0xFAAE, 0x7023, 0xFAAF, 0x87F9, 0xFAB0, 0x89E3,
+	0xFAB1, 0x8A72, 0xFAB2, 0x8AE7, 0xFAB3, 0x9082, 0xFAB4, 0x99ED,
+	0xFAB5, 0x9AB8, 0xFAB6, 0x52BE, 0xFAB7, 0x6838, 0xFAB8, 0x5016,
+	0xFAB9, 0x5E78, 0xFABA, 0x674F, 0xFABB, 0x8347, 0xFABC, 0x884C,
+	0xFABD, 0x4EAB, 0xFABE, 0x5411, 0xFABF, 0x56AE, 0xFAC0, 0x73E6,
+	0xFAC1, 0x9115, 0xFAC2, 0x97FF, 0xFAC3, 0x9909, 0xFAC4, 0x9957,
+	0xFAC5, 0x9999, 0xFAC6, 0x5653, 0xFAC7, 0x589F, 0xFAC8, 0x865B,
+	0xFAC9, 0x8A31, 0xFACA, 0x61B2, 0xFACB, 0x6AF6, 0xFACC, 0x737B,
+	0xFACD, 0x8ED2, 0xFACE, 0x6B47, 0xFACF, 0x96AA, 0xFAD0, 0x9A57,
+	0xFAD1, 0x5955, 0xFAD2, 0x7200, 0xFAD3, 0x8D6B, 0xFAD4, 0x9769,
+	0xFAD5, 0x4FD4, 0xFAD6, 0x5CF4, 0xFAD7, 0x5F26, 0xFAD8, 0x61F8,
+	0xFAD9, 0x665B, 0xFADA, 0x6CEB, 0xFADB, 0x70AB, 0xFADC, 0x7384,
+	0xFADD, 0x73B9, 0xFADE, 0x73FE, 0xFADF, 0x7729, 0xFAE0, 0x774D,
+	0xFAE1, 0x7D43, 0xFAE2, 0x7D62, 0xFAE3, 0x7E23, 0xFAE4, 0x8237,
+	0xFAE5, 0x8852, 0xFAE6, 0xFA0A, 0xFAE7, 0x8CE2, 0xFAE8, 0x9249,
+	0xFAE9, 0x986F, 0xFAEA, 0x5B51, 0xFAEB, 0x7A74, 0xFAEC, 0x8840,
+	0xFAED, 0x9801, 0xFAEE, 0x5ACC, 0xFAEF, 0x4FE0, 0xFAF0, 0x5354,
+	0xFAF1, 0x593E, 0xFAF2, 0x5CFD, 0xFAF3, 0x633E, 0xFAF4, 0x6D79,
+	0xFAF5, 0x72F9, 0xFAF6, 0x8105, 0xFAF7, 0x8107, 0xFAF8, 0x83A2,
+	0xFAF9, 0x92CF, 0xFAFA, 0x9830, 0xFAFB, 0x4EA8, 0xFAFC, 0x5144,
+	0xFAFD, 0x5211, 0xFAFE, 0x578B, 0xFBA1, 0x5F62, 0xFBA2, 0x6CC2,
+	0xFBA3, 0x6ECE, 0xFBA4, 0x7005, 0xFBA5, 0x7050, 0xFBA6, 0x70AF,
+	0xFBA7, 0x7192, 0xFBA8, 0x73E9, 0xFBA9, 0x7469, 0xFBAA, 0x834A,
+	0xFBAB, 0x87A2, 0xFBAC, 0x8861, 0xFBAD, 0x9008, 0xFBAE, 0x90A2,
+	0xFBAF, 0x93A3, 0xFBB0, 0x99A8, 0xFBB1, 0x516E, 0xFBB2, 0x5F57,
+	0xFBB3, 0x60E0, 0xFBB4, 0x6167, 0xFBB5, 0x66B3, 0xFBB6, 0x8559,
+	0xFBB7, 0x8E4A, 0xFBB8, 0x91AF, 0xFBB9, 0x978B, 0xFBBA, 0x4E4E,
+	0xFBBB, 0x4E92, 0xFBBC, 0x547C, 0xFBBD, 0x58D5, 0xFBBE, 0x58FA,
+	0xFBBF, 0x597D, 0xFBC0, 0x5CB5, 0xFBC1, 0x5F27, 0xFBC2, 0x6236,
+	0xFBC3, 0x6248, 0xFBC4, 0x660A, 0xFBC5, 0x6667, 0xFBC6, 0x6BEB,
+	0xFBC7, 0x6D69, 0xFBC8, 0x6DCF, 0xFBC9, 0x6E56, 0xFBCA, 0x6EF8,
+	0xFBCB, 0x6F94, 0xFBCC, 0x6FE0, 0xFBCD, 0x6FE9, 0xFBCE, 0x705D,
+	0xFBCF, 0x72D0, 0xFBD0, 0x7425, 0xFBD1, 0x745A, 0xFBD2, 0x74E0,
+	0xFBD3, 0x7693, 0xFBD4, 0x795C, 0xFBD5, 0x7CCA, 0xFBD6, 0x7E1E,
+	0xFBD7, 0x80E1, 0xFBD8, 0x82A6, 0xFBD9, 0x846B, 0xFBDA, 0x84BF,
+	0xFBDB, 0x864E, 0xFBDC, 0x865F, 0xFBDD, 0x8774, 0xFBDE, 0x8B77,
+	0xFBDF, 0x8C6A, 0xFBE0, 0x93AC, 0xFBE1, 0x9800, 0xFBE2, 0x9865,
+	0xFBE3, 0x60D1, 0xFBE4, 0x6216, 0xFBE5, 0x9177, 0xFBE6, 0x5A5A,
+	0xFBE7, 0x660F, 0xFBE8, 0x6DF7, 0xFBE9, 0x6E3E, 0xFBEA, 0x743F,
+	0xFBEB, 0x9B42, 0xFBEC, 0x5FFD, 0xFBED, 0x60DA, 0xFBEE, 0x7B0F,
+	0xFBEF, 0x54C4, 0xFBF0, 0x5F18, 0xFBF1, 0x6C5E, 0xFBF2, 0x6CD3,
+	0xFBF3, 0x6D2A, 0xFBF4, 0x70D8, 0xFBF5, 0x7D05, 0xFBF6, 0x8679,
+	0xFBF7, 0x8A0C, 0xFBF8, 0x9D3B, 0xFBF9, 0x5316, 0xFBFA, 0x548C,
+	0xFBFB, 0x5B05, 0xFBFC, 0x6A3A, 0xFBFD, 0x706B, 0xFBFE, 0x7575,
+	0xFCA1, 0x798D, 0xFCA2, 0x79BE, 0xFCA3, 0x82B1, 0xFCA4, 0x83EF,
+	0xFCA5, 0x8A71, 0xFCA6, 0x8B41, 0xFCA7, 0x8CA8, 0xFCA8, 0x9774,
+	0xFCA9, 0xFA0B, 0xFCAA, 0x64F4, 0xFCAB, 0x652B, 0xFCAC, 0x78BA,
+	0xFCAD, 0x78BB, 0xFCAE, 0x7A6B, 0xFCAF, 0x4E38, 0xFCB0, 0x559A,
+	0xFCB1, 0x5950, 0xFCB2, 0x5BA6, 0xFCB3, 0x5E7B, 0xFCB4, 0x60A3,
+	0xFCB5, 0x63DB, 0xFCB6, 0x6B61, 0xFCB7, 0x6665, 0xFCB8, 0x6853,
+	0xFCB9, 0x6E19, 0xFCBA, 0x7165, 0xFCBB, 0x74B0, 0xFCBC, 0x7D08,
+	0xFCBD, 0x9084, 0xFCBE, 0x9A69, 0xFCBF, 0x9C25, 0xFCC0, 0x6D3B,
+	0xFCC1, 0x6ED1, 0xFCC2, 0x733E, 0xFCC3, 0x8C41, 0xFCC4, 0x95CA,
+	0xFCC5, 0x51F0, 0xFCC6, 0x5E4C, 0xFCC7, 0x5FA8, 0xFCC8, 0x604D,
+	0xFCC9, 0x60F6, 0xFCCA, 0x6130, 0xFCCB, 0x614C, 0xFCCC, 0x6643,
+	0xFCCD, 0x6644, 0xFCCE, 0x69A5, 0xFCCF, 0x6CC1, 0xFCD0, 0x6E5F,
+	0xFCD1, 0x6EC9, 0xFCD2, 0x6F62, 0xFCD3, 0x714C, 0xFCD4, 0x749C,
+	0xFCD5, 0x7687, 0xFCD6, 0x7BC1, 0xFCD7, 0x7C27, 0xFCD8, 0x8352,
+	0xFCD9, 0x8757, 0xFCDA, 0x9051, 0xFCDB, 0x968D, 0xFCDC, 0x9EC3,
+	0xFCDD, 0x532F, 0xFCDE, 0x56DE, 0xFCDF, 0x5EFB, 0xFCE0, 0x5F8A,
+	0xFCE1, 0x6062, 0xFCE2, 0x6094, 0xFCE3, 0x61F7, 0xFCE4, 0x6666,
+	0xFCE5, 0x6703, 0xFCE6, 0x6A9C, 0xFCE7, 0x6DEE, 0xFCE8, 0x6FAE,
+	0xFCE9, 0x7070, 0xFCEA, 0x736A, 0xFCEB, 0x7E6A, 0xFCEC, 0x81BE,
+	0xFCED, 0x8334, 0xFCEE, 0x86D4, 0xFCEF, 0x8AA8, 0xFCF0, 0x8CC4,
+	0xFCF1, 0x5283, 0xFCF2, 0x7372, 0xFCF3, 0x5B96, 0xFCF4, 0x6A6B,
+	0xFCF5, 0x9404, 0xFCF6, 0x54EE, 0xFCF7, 0x5686, 0xFCF8, 0x5B5D,
+	0xFCF9, 0x6548, 0xFCFA, 0x6585, 0xFCFB, 0x66C9, 0xFCFC, 0x689F,
+	0xFCFD, 0x6D8D, 0xFCFE, 0x6DC6, 0xFDA1, 0x723B, 0xFDA2, 0x80B4,
+	0xFDA3, 0x9175, 0xFDA4, 0x9A4D, 0xFDA5, 0x4FAF, 0xFDA6, 0x5019,
+	0xFDA7, 0x539A, 0xFDA8, 0x540E, 0xFDA9, 0x543C, 0xFDAA, 0x5589,
+	0xFDAB, 0x55C5, 0xFDAC, 0x5E3F, 0xFDAD, 0x5F8C, 0xFDAE, 0x673D,
+	0xFDAF, 0x7166, 0xFDB0, 0x73DD, 0xFDB1, 0x9005, 0xFDB2, 0x52DB,
+	0xFDB3, 0x52F3, 0xFDB4, 0x5864, 0xFDB5, 0x58CE, 0xFDB6, 0x7104,
+	0xFDB7, 0x718F, 0xFDB8, 0x71FB, 0xFDB9, 0x85B0, 0xFDBA, 0x8A13,
+	0xFDBB, 0x6688, 0xFDBC, 0x85A8, 0xFDBD, 0x55A7, 0xFDBE, 0x6684,
+	0xFDBF, 0x714A, 0xFDC0, 0x8431, 0xFDC1, 0x5349, 0xFDC2, 0x5599,
+	0xFDC3, 0x6BC1, 0xFDC4, 0x5F59, 0xFDC5, 0x5FBD, 0xFDC6, 0x63EE,
+	0xFDC7, 0x6689, 0xFDC8, 0x7147, 0xFDC9, 0x8AF1, 0xFDCA, 0x8F1D,
+	0xFDCB, 0x9EBE, 0xFDCC, 0x4F11, 0xFDCD, 0x643A, 0xFDCE, 0x70CB,
+	0xFDCF, 0x7566, 0xFDD0, 0x8667, 0xFDD1, 0x6064, 0xFDD2, 0x8B4E,
+	0xFDD3, 0x9DF8, 0xFDD4, 0x5147, 0xFDD5, 0x51F6, 0xFDD6, 0x5308,
+	0xFDD7, 0x6D36, 0xFDD8, 0x80F8, 0xFDD9, 0x9ED1, 0xFDDA, 0x6615,
+	0xFDDB, 0x6B23, 0xFDDC, 0x7098, 0xFDDD, 0x75D5, 0xFDDE, 0x5403,
+	0xFDDF, 0x5C79, 0xFDE0, 0x7D07, 0xFDE1, 0x8A16, 0xFDE2, 0x6B20,
+	0xFDE3, 0x6B3D, 0xFDE4, 0x6B46, 0xFDE5, 0x5438, 0xFDE6, 0x6070,
+	0xFDE7, 0x6D3D, 0xFDE8, 0x7FD5, 0xFDE9, 0x8208, 0xFDEA, 0x50D6,
+	0xFDEB, 0x51DE, 0xFDEC, 0x559C, 0xFDED, 0x566B, 0xFDEE, 0x56CD,
+	0xFDEF, 0x59EC, 0xFDF0, 0x5B09, 0xFDF1, 0x5E0C, 0xFDF2, 0x6199,
+	0xFDF3, 0x6198, 0xFDF4, 0x6231, 0xFDF5, 0x665E, 0xFDF6, 0x66E6,
+	0xFDF7, 0x7199, 0xFDF8, 0x71B9, 0xFDF9, 0x71BA, 0xFDFA, 0x72A7,
+	0xFDFB, 0x79A7, 0xFDFC, 0x7A00, 0xFDFD, 0x7FB2, 0xFDFE, 0x8A70,
+	0, 0
+};
+
+
+
+WCHAR ff_convert (	/* Converted code, 0 means conversion error */
+	WCHAR	chr,	/* Character code to be converted */
+	UINT	dir		/* 0: Unicode to OEM code, 1: OEM code to Unicode */
+)
+{
+	const WCHAR *p;
+	WCHAR c;
+	int i, n, li, hi;
+
+
+	if (chr < 0x80) {	/* ASCII */
+		c = chr;
+	} else {
+		if (dir) {		/* OEM code to unicode */
+			p = oem2uni;
+			hi = sizeof oem2uni / 4 - 1;
+		} else {		/* Unicode to OEM code */
+			p = uni2oem;
+			hi = sizeof uni2oem / 4 - 1;
+		}
+		li = 0;
+		for (n = 16; n; n--) {
+			i = li + (hi - li) / 2;
+			if (chr == p[i * 2]) break;
+			if (chr > p[i * 2])
+				li = i;
+			else
+				hi = i;
+		}
+		c = n ? p[i * 2 + 1] : 0;
+	}
+
+	return c;
+}
+
+
+
+
+WCHAR ff_wtoupper (
+	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 {			/* Extended characters */
+		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: UsbWattMeter/trunk/fatfs/option/cc950.c
===================================================================
--- UsbWattMeter/trunk/fatfs/option/cc950.c	(revision 164)
+++ UsbWattMeter/trunk/fatfs/option/cc950.c	(revision 164)
@@ -0,0 +1,6860 @@
+/*------------------------------------------------------------------------*/
+/* Unicode - OEM code bidirectional converter  (C)ChaN, 2015              */
+/* CP950 (Traditional Chinese Big5)                                       */
+/*------------------------------------------------------------------------*/
+
+#include "../ff.h"
+
+
+#if !_USE_LFN || _CODE_PAGE != 950
+#error This file is not needed in current configuration. Remove from the project.
+#endif
+
+
+static
+const WCHAR uni2oem[] = {
+/*  Unicode - OEM,  Unicode - OEM,  Unicode - OEM,  Unicode - OEM */
+	0x00A7, 0xA1B1, 0x00AF, 0xA1C2, 0x00B0, 0xA258, 0x00B1, 0xA1D3,
+	0x00B7, 0xA150, 0x00D7, 0xA1D1, 0x00F7, 0xA1D2, 0x02C7, 0xA3BE,
+	0x02C9, 0xA3BC, 0x02CA, 0xA3BD, 0x02CB, 0xA3BF, 0x02CD, 0xA1C5,
+	0x02D9, 0xA3BB, 0x0391, 0xA344, 0x0392, 0xA345, 0x0393, 0xA346,
+	0x0394, 0xA347, 0x0395, 0xA348, 0x0396, 0xA349, 0x0397, 0xA34A,
+	0x0398, 0xA34B, 0x0399, 0xA34C, 0x039A, 0xA34D, 0x039B, 0xA34E,
+	0x039C, 0xA34F, 0x039D, 0xA350, 0x039E, 0xA351, 0x039F, 0xA352,
+	0x03A0, 0xA353, 0x03A1, 0xA354, 0x03A3, 0xA355, 0x03A4, 0xA356,
+	0x03A5, 0xA357, 0x03A6, 0xA358, 0x03A7, 0xA359, 0x03A8, 0xA35A,
+	0x03A9, 0xA35B, 0x03B1, 0xA35C, 0x03B2, 0xA35D, 0x03B3, 0xA35E,
+	0x03B4, 0xA35F, 0x03B5, 0xA360, 0x03B6, 0xA361, 0x03B7, 0xA362,
+	0x03B8, 0xA363, 0x03B9, 0xA364, 0x03BA, 0xA365, 0x03BB, 0xA366,
+	0x03BC, 0xA367, 0x03BD, 0xA368, 0x03BE, 0xA369, 0x03BF, 0xA36A,
+	0x03C0, 0xA36B, 0x03C1, 0xA36C, 0x03C3, 0xA36D, 0x03C4, 0xA36E,
+	0x03C5, 0xA36F, 0x03C6, 0xA370, 0x03C7, 0xA371, 0x03C8, 0xA372,
+	0x03C9, 0xA373, 0x2013, 0xA156, 0x2014, 0xA158, 0x2018, 0xA1A5,
+	0x2019, 0xA1A6, 0x201C, 0xA1A7, 0x201D, 0xA1A8, 0x2025, 0xA14C,
+	0x2026, 0xA14B, 0x2027, 0xA145, 0x2032, 0xA1AC, 0x2035, 0xA1AB,
+	0x203B, 0xA1B0, 0x20AC, 0xA3E1, 0x2103, 0xA24A, 0x2105, 0xA1C1,
+	0x2109, 0xA24B, 0x2160, 0xA2B9, 0x2161, 0xA2BA, 0x2162, 0xA2BB,
+	0x2163, 0xA2BC, 0x2164, 0xA2BD, 0x2165, 0xA2BE, 0x2166, 0xA2BF,
+	0x2167, 0xA2C0, 0x2168, 0xA2C1, 0x2169, 0xA2C2, 0x2190, 0xA1F6,
+	0x2191, 0xA1F4, 0x2192, 0xA1F7, 0x2193, 0xA1F5, 0x2196, 0xA1F8,
+	0x2197, 0xA1F9, 0x2198, 0xA1FB, 0x2199, 0xA1FA, 0x2215, 0xA241,
+	0x221A, 0xA1D4, 0x221E, 0xA1DB, 0x221F, 0xA1E8, 0x2220, 0xA1E7,
+	0x2223, 0xA1FD, 0x2225, 0xA1FC, 0x2229, 0xA1E4, 0x222A, 0xA1E5,
+	0x222B, 0xA1EC, 0x222E, 0xA1ED, 0x2234, 0xA1EF, 0x2235, 0xA1EE,
+	0x2252, 0xA1DC, 0x2260, 0xA1DA, 0x2261, 0xA1DD, 0x2266, 0xA1D8,
+	0x2267, 0xA1D9, 0x2295, 0xA1F2, 0x2299, 0xA1F3, 0x22A5, 0xA1E6,
+	0x22BF, 0xA1E9, 0x2500, 0xA277, 0x2502, 0xA278, 0x250C, 0xA27A,
+	0x2510, 0xA27B, 0x2514, 0xA27C, 0x2518, 0xA27D, 0x251C, 0xA275,
+	0x2524, 0xA274, 0x252C, 0xA273, 0x2534, 0xA272, 0x253C, 0xA271,
+	0x2550, 0xA2A4, 0x2550, 0xF9F9, 0x2551, 0xF9F8, 0x2552, 0xF9E6,
+	0x2553, 0xF9EF, 0x2554, 0xF9DD, 0x2555, 0xF9E8, 0x2556, 0xF9F1,
+	0x2557, 0xF9DF, 0x2558, 0xF9EC, 0x2559, 0xF9F5, 0x255A, 0xF9E3,
+	0x255B, 0xF9EE, 0x255C, 0xF9F7, 0x255D, 0xF9E5, 0x255E, 0xA2A5,
+	0x255E, 0xF9E9, 0x255F, 0xF9F2, 0x2560, 0xF9E0, 0x2561, 0xA2A7,
+	0x2561, 0xF9EB, 0x2562, 0xF9F4, 0x2563, 0xF9E2, 0x2564, 0xF9E7,
+	0x2565, 0xF9F0, 0x2566, 0xF9DE, 0x2567, 0xF9ED, 0x2568, 0xF9F6,
+	0x2569, 0xF9E4, 0x256A, 0xA2A6, 0x256A, 0xF9EA, 0x256B, 0xF9F3,
+	0x256C, 0xF9E1, 0x256D, 0xA27E, 0x256D, 0xF9FA, 0x256E, 0xA2A1,
+	0x256E, 0xF9FB, 0x256F, 0xA2A3, 0x256F, 0xF9FD, 0x2570, 0xA2A2,
+	0x2570, 0xF9FC, 0x2571, 0xA2AC, 0x2572, 0xA2AD, 0x2573, 0xA2AE,
+	0x2574, 0xA15A, 0x2581, 0xA262, 0x2582, 0xA263, 0x2583, 0xA264,
+	0x2584, 0xA265, 0x2585, 0xA266, 0x2586, 0xA267, 0x2587, 0xA268,
+	0x2588, 0xA269, 0x2589, 0xA270, 0x258A, 0xA26F, 0x258B, 0xA26E,
+	0x258C, 0xA26D, 0x258D, 0xA26C, 0x258E, 0xA26B, 0x258F, 0xA26A,
+	0x2593, 0xF9FE, 0x2594, 0xA276, 0x2595, 0xA279, 0x25A0, 0xA1BD,
+	0x25A1, 0xA1BC, 0x25B2, 0xA1B6, 0x25B3, 0xA1B5, 0x25BC, 0xA1BF,
+	0x25BD, 0xA1BE, 0x25C6, 0xA1BB, 0x25C7, 0xA1BA, 0x25CB, 0xA1B3,
+	0x25CE, 0xA1B7, 0x25CF, 0xA1B4, 0x25E2, 0xA2A8, 0x25E3, 0xA2A9,
+	0x25E4, 0xA2AB, 0x25E5, 0xA2AA, 0x2605, 0xA1B9, 0x2606, 0xA1B8,
+	0x2640, 0xA1F0, 0x2642, 0xA1F1, 0x3000, 0xA140, 0x3001, 0xA142,
+	0x3002, 0xA143, 0x3003, 0xA1B2, 0x3008, 0xA171, 0x3009, 0xA172,
+	0x300A, 0xA16D, 0x300B, 0xA16E, 0x300C, 0xA175, 0x300D, 0xA176,
+	0x300E, 0xA179, 0x300F, 0xA17A, 0x3010, 0xA169, 0x3011, 0xA16A,
+	0x3012, 0xA245, 0x3014, 0xA165, 0x3015, 0xA166, 0x301D, 0xA1A9,
+	0x301E, 0xA1AA, 0x3021, 0xA2C3, 0x3022, 0xA2C4, 0x3023, 0xA2C5,
+	0x3024, 0xA2C6, 0x3025, 0xA2C7, 0x3026, 0xA2C8, 0x3027, 0xA2C9,
+	0x3028, 0xA2CA, 0x3029, 0xA2CB, 0x3105, 0xA374, 0x3106, 0xA375,
+	0x3107, 0xA376, 0x3108, 0xA377, 0x3109, 0xA378, 0x310A, 0xA379,
+	0x310B, 0xA37A, 0x310C, 0xA37B, 0x310D, 0xA37C, 0x310E, 0xA37D,
+	0x310F, 0xA37E, 0x3110, 0xA3A1, 0x3111, 0xA3A2, 0x3112, 0xA3A3,
+	0x3113, 0xA3A4, 0x3114, 0xA3A5, 0x3115, 0xA3A6, 0x3116, 0xA3A7,
+	0x3117, 0xA3A8, 0x3118, 0xA3A9, 0x3119, 0xA3AA, 0x311A, 0xA3AB,
+	0x311B, 0xA3AC, 0x311C, 0xA3AD, 0x311D, 0xA3AE, 0x311E, 0xA3AF,
+	0x311F, 0xA3B0, 0x3120, 0xA3B1, 0x3121, 0xA3B2, 0x3122, 0xA3B3,
+	0x3123, 0xA3B4, 0x3124, 0xA3B5, 0x3125, 0xA3B6, 0x3126, 0xA3B7,
+	0x3127, 0xA3B8, 0x3128, 0xA3B9, 0x3129, 0xA3BA, 0x32A3, 0xA1C0,
+	0x338E, 0xA255, 0x338F, 0xA256, 0x339C, 0xA250, 0x339D, 0xA251,
+	0x339E, 0xA252, 0x33A1, 0xA254, 0x33C4, 0xA257, 0x33CE, 0xA253,
+	0x33D1, 0xA1EB, 0x33D2, 0xA1EA, 0x33D5, 0xA24F, 0x4E00, 0xA440,
+	0x4E01, 0xA442, 0x4E03, 0xA443, 0x4E07, 0xC945, 0x4E08, 0xA456,
+	0x4E09, 0xA454, 0x4E0A, 0xA457, 0x4E0B, 0xA455, 0x4E0C, 0xC946,
+	0x4E0D, 0xA4A3, 0x4E0E, 0xC94F, 0x4E0F, 0xC94D, 0x4E10, 0xA4A2,
+	0x4E11, 0xA4A1, 0x4E14, 0xA542, 0x4E15, 0xA541, 0x4E16, 0xA540,
+	0x4E18, 0xA543, 0x4E19, 0xA4FE, 0x4E1E, 0xA5E0, 0x4E1F, 0xA5E1,
+	0x4E26, 0xA8C3, 0x4E2B, 0xA458, 0x4E2D, 0xA4A4, 0x4E2E, 0xC950,
+	0x4E30, 0xA4A5, 0x4E31, 0xC963, 0x4E32, 0xA6EA, 0x4E33, 0xCBB1,
+	0x4E38, 0xA459, 0x4E39, 0xA4A6, 0x4E3B, 0xA544, 0x4E3C, 0xC964,
+	0x4E42, 0xC940, 0x4E43, 0xA444, 0x4E45, 0xA45B, 0x4E47, 0xC947,
+	0x4E48, 0xA45C, 0x4E4B, 0xA4A7, 0x4E4D, 0xA545, 0x4E4E, 0xA547,
+	0x4E4F, 0xA546, 0x4E52, 0xA5E2, 0x4E53, 0xA5E3, 0x4E56, 0xA8C4,
+	0x4E58, 0xADBC, 0x4E59, 0xA441, 0x4E5C, 0xC941, 0x4E5D, 0xA445,
+	0x4E5E, 0xA45E, 0x4E5F, 0xA45D, 0x4E69, 0xA5E4, 0x4E73, 0xA8C5,
+	0x4E7E, 0xB0AE, 0x4E7F, 0xD44B, 0x4E82, 0xB6C3, 0x4E83, 0xDCB1,
+	0x4E84, 0xDCB2, 0x4E86, 0xA446, 0x4E88, 0xA4A9, 0x4E8B, 0xA8C6,
+	0x4E8C, 0xA447, 0x4E8D, 0xC948, 0x4E8E, 0xA45F, 0x4E91, 0xA4AA,
+	0x4E92, 0xA4AC, 0x4E93, 0xC951, 0x4E94, 0xA4AD, 0x4E95, 0xA4AB,
+	0x4E99, 0xA5E5, 0x4E9B, 0xA8C7, 0x4E9E, 0xA8C8, 0x4E9F, 0xAB45,
+	0x4EA1, 0xA460, 0x4EA2, 0xA4AE, 0x4EA4, 0xA5E6, 0x4EA5, 0xA5E8,
+	0x4EA6, 0xA5E7, 0x4EA8, 0xA6EB, 0x4EAB, 0xA8C9, 0x4EAC, 0xA8CA,
+	0x4EAD, 0xAB46, 0x4EAE, 0xAB47, 0x4EB3, 0xADBD, 0x4EB6, 0xDCB3,
+	0x4EB9, 0xF6D6, 0x4EBA, 0xA448, 0x4EC0, 0xA4B0, 0x4EC1, 0xA4AF,
+	0x4EC2, 0xC952, 0x4EC3, 0xA4B1, 0x4EC4, 0xA4B7, 0x4EC6, 0xA4B2,
+	0x4EC7, 0xA4B3, 0x4EC8, 0xC954, 0x4EC9, 0xC953, 0x4ECA, 0xA4B5,
+	0x4ECB, 0xA4B6, 0x4ECD, 0xA4B4, 0x4ED4, 0xA54A, 0x4ED5, 0xA54B,
+	0x4ED6, 0xA54C, 0x4ED7, 0xA54D, 0x4ED8, 0xA549, 0x4ED9, 0xA550,
+	0x4EDA, 0xC96A, 0x4EDC, 0xC966, 0x4EDD, 0xC969, 0x4EDE, 0xA551,
+	0x4EDF, 0xA561, 0x4EE1, 0xC968, 0x4EE3, 0xA54E, 0x4EE4, 0xA54F,
+	0x4EE5, 0xA548, 0x4EE8, 0xC965, 0x4EE9, 0xC967, 0x4EF0, 0xA5F5,
+	0x4EF1, 0xC9B0, 0x4EF2, 0xA5F2, 0x4EF3, 0xA5F6, 0x4EF4, 0xC9BA,
+	0x4EF5, 0xC9AE, 0x4EF6, 0xA5F3, 0x4EF7, 0xC9B2, 0x4EFB, 0xA5F4,
+	0x4EFD, 0xA5F7, 0x4EFF, 0xA5E9, 0x4F00, 0xC9B1, 0x4F01, 0xA5F8,
+	0x4F02, 0xC9B5, 0x4F04, 0xC9B9, 0x4F05, 0xC9B6, 0x4F08, 0xC9B3,
+	0x4F09, 0xA5EA, 0x4F0A, 0xA5EC, 0x4F0B, 0xA5F9, 0x4F0D, 0xA5EE,
+	0x4F0E, 0xC9AB, 0x4F0F, 0xA5F1, 0x4F10, 0xA5EF, 0x4F11, 0xA5F0,
+	0x4F12, 0xC9BB, 0x4F13, 0xC9B8, 0x4F14, 0xC9AF, 0x4F15, 0xA5ED,
+	0x4F18, 0xC9AC, 0x4F19, 0xA5EB, 0x4F1D, 0xC9B4, 0x4F22, 0xC9B7,
+	0x4F2C, 0xC9AD, 0x4F2D, 0xCA66, 0x4F2F, 0xA742, 0x4F30, 0xA6F4,
+	0x4F33, 0xCA67, 0x4F34, 0xA6F1, 0x4F36, 0xA744, 0x4F38, 0xA6F9,
+	0x4F3A, 0xA6F8, 0x4F3B, 0xCA5B, 0x4F3C, 0xA6FC, 0x4F3D, 0xA6F7,
+	0x4F3E, 0xCA60, 0x4F3F, 0xCA68, 0x4F41, 0xCA64, 0x4F43, 0xA6FA,
+	0x4F46, 0xA6FD, 0x4F47, 0xA6EE, 0x4F48, 0xA747, 0x4F49, 0xCA5D,
+	0x4F4C, 0xCBBD, 0x4F4D, 0xA6EC, 0x4F4E, 0xA743, 0x4F4F, 0xA6ED,
+	0x4F50, 0xA6F5, 0x4F51, 0xA6F6, 0x4F52, 0xCA62, 0x4F53, 0xCA5E,
+	0x4F54, 0xA6FB, 0x4F55, 0xA6F3, 0x4F56, 0xCA5A, 0x4F57, 0xA6EF,
+	0x4F58, 0xCA65, 0x4F59, 0xA745, 0x4F5A, 0xA748, 0x4F5B, 0xA6F2,
+	0x4F5C, 0xA740, 0x4F5D, 0xA746, 0x4F5E, 0xA6F0, 0x4F5F, 0xCA63,
+	0x4F60, 0xA741, 0x4F61, 0xCA69, 0x4F62, 0xCA5C, 0x4F63, 0xA6FE,
+	0x4F64, 0xCA5F, 0x4F67, 0xCA61, 0x4F69, 0xA8D8, 0x4F6A, 0xCBBF,
+	0x4F6B, 0xCBCB, 0x4F6C, 0xA8D0, 0x4F6E, 0xCBCC, 0x4F6F, 0xA8CB,
+	0x4F70, 0xA8D5, 0x4F73, 0xA8CE, 0x4F74, 0xCBB9, 0x4F75, 0xA8D6,
+	0x4F76, 0xCBB8, 0x4F77, 0xCBBC, 0x4F78, 0xCBC3, 0x4F79, 0xCBC1,
+	0x4F7A, 0xA8DE, 0x4F7B, 0xA8D9, 0x4F7C, 0xCBB3, 0x4F7D, 0xCBB5,
+	0x4F7E, 0xA8DB, 0x4F7F, 0xA8CF, 0x4F80, 0xCBB6, 0x4F81, 0xCBC2,
+	0x4F82, 0xCBC9, 0x4F83, 0xA8D4, 0x4F84, 0xCBBB, 0x4F85, 0xCBB4,
+	0x4F86, 0xA8D3, 0x4F87, 0xCBB7, 0x4F88, 0xA8D7, 0x4F89, 0xCBBA,
+	0x4F8B, 0xA8D2, 0x4F8D, 0xA8CD, 0x4F8F, 0xA8DC, 0x4F90, 0xCBC4,
+	0x4F91, 0xA8DD, 0x4F92, 0xCBC8, 0x4F94, 0xCBC6, 0x4F95, 0xCBCA,
+	0x4F96, 0xA8DA, 0x4F97, 0xCBBE, 0x4F98, 0xCBB2, 0x4F9A, 0xCBC0,
+	0x4F9B, 0xA8D1, 0x4F9C, 0xCBC5, 0x4F9D, 0xA8CC, 0x4F9E, 0xCBC7,
+	0x4FAE, 0xAB56, 0x4FAF, 0xAB4A, 0x4FB2, 0xCDE0, 0x4FB3, 0xCDE8,
+	0x4FB5, 0xAB49, 0x4FB6, 0xAB51, 0x4FB7, 0xAB5D, 0x4FB9, 0xCDEE,
+	0x4FBA, 0xCDEC, 0x4FBB, 0xCDE7, 0x4FBF, 0xAB4B, 0x4FC0, 0xCDED,
+	0x4FC1, 0xCDE3, 0x4FC2, 0xAB59, 0x4FC3, 0xAB50, 0x4FC4, 0xAB58,
+	0x4FC5, 0xCDDE, 0x4FC7, 0xCDEA, 0x4FC9, 0xCDE1, 0x4FCA, 0xAB54,
+	0x4FCB, 0xCDE2, 0x4FCD, 0xCDDD, 0x4FCE, 0xAB5B, 0x4FCF, 0xAB4E,
+	0x4FD0, 0xAB57, 0x4FD1, 0xAB4D, 0x4FD3, 0xCDDF, 0x4FD4, 0xCDE4,
+	0x4FD6, 0xCDEB, 0x4FD7, 0xAB55, 0x4FD8, 0xAB52, 0x4FD9, 0xCDE6,
+	0x4FDA, 0xAB5A, 0x4FDB, 0xCDE9, 0x4FDC, 0xCDE5, 0x4FDD, 0xAB4F,
+	0x4FDE, 0xAB5C, 0x4FDF, 0xAB53, 0x4FE0, 0xAB4C, 0x4FE1, 0xAB48,
+	0x4FEC, 0xCDEF, 0x4FEE, 0xADD7, 0x4FEF, 0xADC1, 0x4FF1, 0xADD1,
+	0x4FF3, 0xADD6, 0x4FF4, 0xD0D0, 0x4FF5, 0xD0CF, 0x4FF6, 0xD0D4,
+	0x4FF7, 0xD0D5, 0x4FF8, 0xADC4, 0x4FFA, 0xADCD, 0x4FFE, 0xADDA,
+	0x5000, 0xADCE, 0x5005, 0xD0C9, 0x5006, 0xADC7, 0x5007, 0xD0CA,
+	0x5009, 0xADDC, 0x500B, 0xADD3, 0x500C, 0xADBE, 0x500D, 0xADBF,
+	0x500E, 0xD0DD, 0x500F, 0xB0BF, 0x5011, 0xADCC, 0x5012, 0xADCB,
+	0x5013, 0xD0CB, 0x5014, 0xADCF, 0x5015, 0xD45B, 0x5016, 0xADC6,
+	0x5017, 0xD0D6, 0x5018, 0xADD5, 0x5019, 0xADD4, 0x501A, 0xADCA,
+	0x501B, 0xD0CE, 0x501C, 0xD0D7, 0x501E, 0xD0C8, 0x501F, 0xADC9,
+	0x5020, 0xD0D8, 0x5021, 0xADD2, 0x5022, 0xD0CC, 0x5023, 0xADC0,
+	0x5025, 0xADC3, 0x5026, 0xADC2, 0x5027, 0xD0D9, 0x5028, 0xADD0,
+	0x5029, 0xADC5, 0x502A, 0xADD9, 0x502B, 0xADDB, 0x502C, 0xD0D3,
+	0x502D, 0xADD8, 0x502F, 0xD0DB, 0x5030, 0xD0CD, 0x5031, 0xD0DC,
+	0x5033, 0xD0D1, 0x5035, 0xD0DA, 0x5037, 0xD0D2, 0x503C, 0xADC8,
+	0x5040, 0xD463, 0x5041, 0xD457, 0x5043, 0xB0B3, 0x5045, 0xD45C,
+	0x5046, 0xD462, 0x5047, 0xB0B2, 0x5048, 0xD455, 0x5049, 0xB0B6,
+	0x504A, 0xD459, 0x504B, 0xD452, 0x504C, 0xB0B4, 0x504D, 0xD456,
+	0x504E, 0xB0B9, 0x504F, 0xB0BE, 0x5051, 0xD467, 0x5053, 0xD451,
+	0x5055, 0xB0BA, 0x5057, 0xD466, 0x505A, 0xB0B5, 0x505B, 0xD458,
+	0x505C, 0xB0B1, 0x505D, 0xD453, 0x505E, 0xD44F, 0x505F, 0xD45D,
+	0x5060, 0xD450, 0x5061, 0xD44E, 0x5062, 0xD45A, 0x5063, 0xD460,
+	0x5064, 0xD461, 0x5065, 0xB0B7, 0x5068, 0xD85B, 0x5069, 0xD45E,
+	0x506A, 0xD44D, 0x506B, 0xD45F, 0x506D, 0xB0C1, 0x506E, 0xD464,
+	0x506F, 0xB0C0, 0x5070, 0xD44C, 0x5072, 0xD454, 0x5073, 0xD465,
+	0x5074, 0xB0BC, 0x5075, 0xB0BB, 0x5076, 0xB0B8, 0x5077, 0xB0BD,
+	0x507A, 0xB0AF, 0x507D, 0xB0B0, 0x5080, 0xB3C8, 0x5082, 0xD85E,
+	0x5083, 0xD857, 0x5085, 0xB3C5, 0x5087, 0xD85F, 0x508B, 0xD855,
+	0x508C, 0xD858, 0x508D, 0xB3C4, 0x508E, 0xD859, 0x5091, 0xB3C7,
+	0x5092, 0xD85D, 0x5094, 0xD853, 0x5095, 0xD852, 0x5096, 0xB3C9,
+	0x5098, 0xB3CA, 0x5099, 0xB3C6, 0x509A, 0xB3CB, 0x509B, 0xD851,
+	0x509C, 0xD85C, 0x509D, 0xD85A, 0x509E, 0xD854, 0x50A2, 0xB3C3,
+	0x50A3, 0xD856, 0x50AC, 0xB6CA, 0x50AD, 0xB6C4, 0x50AE, 0xDCB7,
+	0x50AF, 0xB6CD, 0x50B0, 0xDCBD, 0x50B1, 0xDCC0, 0x50B2, 0xB6C6,
+	0x50B3, 0xB6C7, 0x50B4, 0xDCBA, 0x50B5, 0xB6C5, 0x50B6, 0xDCC3,
+	0x50B7, 0xB6CB, 0x50B8, 0xDCC4, 0x50BA, 0xDCBF, 0x50BB, 0xB6CC,
+	0x50BD, 0xDCB4, 0x50BE, 0xB6C9, 0x50BF, 0xDCB5, 0x50C1, 0xDCBE,
+	0x50C2, 0xDCBC, 0x50C4, 0xDCB8, 0x50C5, 0xB6C8, 0x50C6, 0xDCB6,
+	0x50C7, 0xB6CE, 0x50C8, 0xDCBB, 0x50C9, 0xDCC2, 0x50CA, 0xDCB9,
+	0x50CB, 0xDCC1, 0x50CE, 0xB9B6, 0x50CF, 0xB9B3, 0x50D1, 0xB9B4,
+	0x50D3, 0xE0F9, 0x50D4, 0xE0F1, 0x50D5, 0xB9B2, 0x50D6, 0xB9AF,
+	0x50D7, 0xE0F2, 0x50DA, 0xB9B1, 0x50DB, 0xE0F5, 0x50DD, 0xE0F7,
+	0x50E0, 0xE0FE, 0x50E3, 0xE0FD, 0x50E4, 0xE0F8, 0x50E5, 0xB9AE,
+	0x50E6, 0xE0F0, 0x50E7, 0xB9AC, 0x50E8, 0xE0F3, 0x50E9, 0xB9B7,
+	0x50EA, 0xE0F6, 0x50EC, 0xE0FA, 0x50ED, 0xB9B0, 0x50EE, 0xB9AD,
+	0x50EF, 0xE0FC, 0x50F0, 0xE0FB, 0x50F1, 0xB9B5, 0x50F3, 0xE0F4,
+	0x50F5, 0xBBF8, 0x50F6, 0xE4EC, 0x50F8, 0xE4E9, 0x50F9, 0xBBF9,
+	0x50FB, 0xBBF7, 0x50FD, 0xE4F0, 0x50FE, 0xE4ED, 0x50FF, 0xE4E6,
+	0x5100, 0xBBF6, 0x5102, 0xBBFA, 0x5103, 0xE4E7, 0x5104, 0xBBF5,
+	0x5105, 0xBBFD, 0x5106, 0xE4EA, 0x5107, 0xE4EB, 0x5108, 0xBBFB,
+	0x5109, 0xBBFC, 0x510A, 0xE4F1, 0x510B, 0xE4EE, 0x510C, 0xE4EF,
+	0x5110, 0xBEAA, 0x5111, 0xE8F8, 0x5112, 0xBEA7, 0x5113, 0xE8F5,
+	0x5114, 0xBEA9, 0x5115, 0xBEAB, 0x5117, 0xE8F6, 0x5118, 0xBEA8,
+	0x511A, 0xE8F7, 0x511C, 0xE8F4, 0x511F, 0xC076, 0x5120, 0xECBD,
+	0x5121, 0xC077, 0x5122, 0xECBB, 0x5124, 0xECBC, 0x5125, 0xECBA,
+	0x5126, 0xECB9, 0x5129, 0xECBE, 0x512A, 0xC075, 0x512D, 0xEFB8,
+	0x512E, 0xEFB9, 0x5130, 0xE4E8, 0x5131, 0xEFB7, 0x5132, 0xC078,
+	0x5133, 0xC35F, 0x5134, 0xF1EB, 0x5135, 0xF1EC, 0x5137, 0xC4D7,
+	0x5138, 0xC4D8, 0x5139, 0xF5C1, 0x513A, 0xF5C0, 0x513B, 0xC56C,
+	0x513C, 0xC56B, 0x513D, 0xF7D0, 0x513F, 0xA449, 0x5140, 0xA461,
+	0x5141, 0xA4B9, 0x5143, 0xA4B8, 0x5144, 0xA553, 0x5145, 0xA552,
+	0x5146, 0xA5FC, 0x5147, 0xA5FB, 0x5148, 0xA5FD, 0x5149, 0xA5FA,
+	0x514B, 0xA74A, 0x514C, 0xA749, 0x514D, 0xA74B, 0x5152, 0xA8E0,
+	0x5154, 0xA8DF, 0x5155, 0xA8E1, 0x5157, 0xAB5E, 0x5159, 0xA259,
+	0x515A, 0xD0DE, 0x515B, 0xA25A, 0x515C, 0xB0C2, 0x515D, 0xA25C,
+	0x515E, 0xA25B, 0x515F, 0xD860, 0x5161, 0xA25D, 0x5162, 0xB9B8,
+	0x5163, 0xA25E, 0x5165, 0xA44A, 0x5167, 0xA4BA, 0x5168, 0xA5FE,
+	0x5169, 0xA8E2, 0x516B, 0xA44B, 0x516C, 0xA4BD, 0x516D, 0xA4BB,
+	0x516E, 0xA4BC, 0x5171, 0xA640, 0x5175, 0xA74C, 0x5176, 0xA8E4,
+	0x5177, 0xA8E3, 0x5178, 0xA8E5, 0x517C, 0xADDD, 0x5180, 0xBEAC,
+	0x5187, 0xC94E, 0x5189, 0xA554, 0x518A, 0xA555, 0x518D, 0xA641,
+	0x518F, 0xCA6A, 0x5191, 0xAB60, 0x5192, 0xAB5F, 0x5193, 0xD0E0,
+	0x5194, 0xD0DF, 0x5195, 0xB0C3, 0x5197, 0xA4BE, 0x5198, 0xC955,
+	0x519E, 0xCBCD, 0x51A0, 0xAB61, 0x51A2, 0xADE0, 0x51A4, 0xADDE,
+	0x51A5, 0xADDF, 0x51AA, 0xBEAD, 0x51AC, 0xA556, 0x51B0, 0xA642,
+	0x51B1, 0xC9BC, 0x51B6, 0xA74D, 0x51B7, 0xA74E, 0x51B9, 0xCA6B,
+	0x51BC, 0xCBCE, 0x51BD, 0xA8E6, 0x51BE, 0xCBCF, 0x51C4, 0xD0E2,
+	0x51C5, 0xD0E3, 0x51C6, 0xADE3, 0x51C8, 0xD0E4, 0x51CA, 0xD0E1,
+	0x51CB, 0xADE4, 0x51CC, 0xADE2, 0x51CD, 0xADE1, 0x51CE, 0xD0E5,
+	0x51D0, 0xD468, 0x51D4, 0xD861, 0x51D7, 0xDCC5, 0x51D8, 0xE140,
+	0x51DC, 0xBBFE, 0x51DD, 0xBEAE, 0x51DE, 0xE8F9, 0x51E0, 0xA44C,
+	0x51E1, 0xA45A, 0x51F0, 0xB0C4, 0x51F1, 0xB3CD, 0x51F3, 0xB9B9,
+	0x51F5, 0xC942, 0x51F6, 0xA4BF, 0x51F8, 0xA559, 0x51F9, 0xA557,
+	0x51FA, 0xA558, 0x51FD, 0xA8E7, 0x5200, 0xA44D, 0x5201, 0xA44E,
+	0x5203, 0xA462, 0x5206, 0xA4C0, 0x5207, 0xA4C1, 0x5208, 0xA4C2,
+	0x5209, 0xC9BE, 0x520A, 0xA55A, 0x520C, 0xC96B, 0x520E, 0xA646,
+	0x5210, 0xC9BF, 0x5211, 0xA644, 0x5212, 0xA645, 0x5213, 0xC9BD,
+	0x5216, 0xA647, 0x5217, 0xA643, 0x521C, 0xCA6C, 0x521D, 0xAAEC,
+	0x521E, 0xCA6D, 0x5221, 0xCA6E, 0x5224, 0xA750, 0x5225, 0xA74F,
+	0x5228, 0xA753, 0x5229, 0xA751, 0x522A, 0xA752, 0x522E, 0xA8ED,
+	0x5230, 0xA8EC, 0x5231, 0xCBD4, 0x5232, 0xCBD1, 0x5233, 0xCBD2,
+	0x5235, 0xCBD0, 0x5236, 0xA8EE, 0x5237, 0xA8EA, 0x5238, 0xA8E9,
+	0x523A, 0xA8EB, 0x523B, 0xA8E8, 0x5241, 0xA8EF, 0x5243, 0xAB63,
+	0x5244, 0xCDF0, 0x5246, 0xCBD3, 0x5247, 0xAB68, 0x5249, 0xCDF1,
+	0x524A, 0xAB64, 0x524B, 0xAB67, 0x524C, 0xAB66, 0x524D, 0xAB65,
+	0x524E, 0xAB62, 0x5252, 0xD0E8, 0x5254, 0xADE7, 0x5255, 0xD0EB,
+	0x5256, 0xADE5, 0x525A, 0xD0E7, 0x525B, 0xADE8, 0x525C, 0xADE6,
+	0x525D, 0xADE9, 0x525E, 0xD0E9, 0x525F, 0xD0EA, 0x5261, 0xD0E6,
+	0x5262, 0xD0EC, 0x5269, 0xB3D1, 0x526A, 0xB0C5, 0x526B, 0xD469,
+	0x526C, 0xD46B, 0x526D, 0xD46A, 0x526E, 0xD46C, 0x526F, 0xB0C6,
+	0x5272, 0xB3CE, 0x5274, 0xB3CF, 0x5275, 0xB3D0, 0x5277, 0xB6D0,
+	0x5278, 0xDCC7, 0x527A, 0xDCC6, 0x527B, 0xDCC8, 0x527C, 0xDCC9,
+	0x527D, 0xB6D1, 0x527F, 0xB6CF, 0x5280, 0xE141, 0x5281, 0xE142,
+	0x5282, 0xB9BB, 0x5283, 0xB9BA, 0x5284, 0xE35A, 0x5287, 0xBC40,
+	0x5288, 0xBC41, 0x5289, 0xBC42, 0x528A, 0xBC44, 0x528B, 0xE4F2,
+	0x528C, 0xE4F3, 0x528D, 0xBC43, 0x5291, 0xBEAF, 0x5293, 0xBEB0,
+	0x5296, 0xF1ED, 0x5297, 0xF5C3, 0x5298, 0xF5C2, 0x5299, 0xF7D1,
+	0x529B, 0xA44F, 0x529F, 0xA55C, 0x52A0, 0xA55B, 0x52A3, 0xA648,
+	0x52A6, 0xC9C0, 0x52A9, 0xA755, 0x52AA, 0xA756, 0x52AB, 0xA754,
+	0x52AC, 0xA757, 0x52AD, 0xCA6F, 0x52AE, 0xCA70, 0x52BB, 0xA8F1,
+	0x52BC, 0xCBD5, 0x52BE, 0xA8F0, 0x52C0, 0xCDF2, 0x52C1, 0xAB6C,
+	0x52C2, 0xCDF3, 0x52C3, 0xAB6B, 0x52C7, 0xAB69, 0x52C9, 0xAB6A,
+	0x52CD, 0xD0ED, 0x52D2, 0xB0C7, 0x52D3, 0xD46E, 0x52D5, 0xB0CA,
+	0x52D6, 0xD46D, 0x52D7, 0xB1E5, 0x52D8, 0xB0C9, 0x52D9, 0xB0C8,
+	0x52DB, 0xB3D4, 0x52DD, 0xB3D3, 0x52DE, 0xB3D2, 0x52DF, 0xB6D2,
+	0x52E2, 0xB6D5, 0x52E3, 0xB6D6, 0x52E4, 0xB6D4, 0x52E6, 0xB6D3,
+	0x52E9, 0xE143, 0x52EB, 0xE144, 0x52EF, 0xE4F5, 0x52F0, 0xBC45,
+	0x52F1, 0xE4F4, 0x52F3, 0xBEB1, 0x52F4, 0xECBF, 0x52F5, 0xC079,
+	0x52F7, 0xF1EE, 0x52F8, 0xC455, 0x52FA, 0xA463, 0x52FB, 0xA4C3,
+	0x52FC, 0xC956, 0x52FE, 0xA4C4, 0x52FF, 0xA4C5, 0x5305, 0xA55D,
+	0x5306, 0xA55E, 0x5308, 0xA649, 0x5309, 0xCA71, 0x530A, 0xCBD6,
+	0x530B, 0xCBD7, 0x530D, 0xAB6D, 0x530E, 0xD0EE, 0x530F, 0xB0CC,
+	0x5310, 0xB0CB, 0x5311, 0xD863, 0x5312, 0xD862, 0x5315, 0xA450,
+	0x5316, 0xA4C6, 0x5317, 0xA55F, 0x5319, 0xB0CD, 0x531A, 0xC943,
+	0x531C, 0xC96C, 0x531D, 0xA560, 0x531F, 0xC9C2, 0x5320, 0xA64B,
+	0x5321, 0xA64A, 0x5322, 0xC9C1, 0x5323, 0xA758, 0x532A, 0xADEA,
+	0x532D, 0xD46F, 0x532F, 0xB6D7, 0x5330, 0xE145, 0x5331, 0xB9BC,
+	0x5334, 0xE8FA, 0x5337, 0xF3FD, 0x5339, 0xA4C7, 0x533C, 0xCBD8,
+	0x533D, 0xCDF4, 0x533E, 0xB0D0, 0x533F, 0xB0CE, 0x5340, 0xB0CF,
+	0x5341, 0xA2CC, 0x5341, 0xA451, 0x5343, 0xA464, 0x5344, 0xA2CD,
+	0x5345, 0xA2CE, 0x5345, 0xA4CA, 0x5347, 0xA4C9, 0x5348, 0xA4C8,
+	0x5349, 0xA563, 0x534A, 0xA562, 0x534C, 0xC96D, 0x534D, 0xC9C3,
+	0x5351, 0xA8F5, 0x5352, 0xA8F2, 0x5353, 0xA8F4, 0x5354, 0xA8F3,
+	0x5357, 0xAB6E, 0x535A, 0xB3D5, 0x535C, 0xA452, 0x535E, 0xA4CB,
+	0x5360, 0xA565, 0x5361, 0xA564, 0x5363, 0xCA72, 0x5366, 0xA8F6,
+	0x536C, 0xC957, 0x536E, 0xA567, 0x536F, 0xA566, 0x5370, 0xA64C,
+	0x5371, 0xA64D, 0x5372, 0xCA73, 0x5373, 0xA759, 0x5375, 0xA75A,
+	0x5377, 0xA8F7, 0x5378, 0xA8F8, 0x5379, 0xA8F9, 0x537B, 0xAB6F,
+	0x537C, 0xCDF5, 0x537F, 0xADEB, 0x5382, 0xC944, 0x5384, 0xA4CC,
+	0x538A, 0xC9C4, 0x538E, 0xCA74, 0x538F, 0xCA75, 0x5392, 0xCBD9,
+	0x5394, 0xCBDA, 0x5396, 0xCDF7, 0x5397, 0xCDF6, 0x5398, 0xCDF9,
+	0x5399, 0xCDF8, 0x539A, 0xAB70, 0x539C, 0xD470, 0x539D, 0xADED,
+	0x539E, 0xD0EF, 0x539F, 0xADEC, 0x53A4, 0xD864, 0x53A5, 0xB3D6,
+	0x53A7, 0xD865, 0x53AC, 0xE146, 0x53AD, 0xB9BD, 0x53B2, 0xBC46,
+	0x53B4, 0xF1EF, 0x53B9, 0xC958, 0x53BB, 0xA568, 0x53C3, 0xB0D1,
+	0x53C8, 0xA453, 0x53C9, 0xA465, 0x53CA, 0xA4CE, 0x53CB, 0xA4CD,
+	0x53CD, 0xA4CF, 0x53D4, 0xA8FB, 0x53D6, 0xA8FA, 0x53D7, 0xA8FC,
+	0x53DB, 0xAB71, 0x53DF, 0xADEE, 0x53E1, 0xE8FB, 0x53E2, 0xC24F,
+	0x53E3, 0xA466, 0x53E4, 0xA56A, 0x53E5, 0xA579, 0x53E6, 0xA574,
+	0x53E8, 0xA56F, 0x53E9, 0xA56E, 0x53EA, 0xA575, 0x53EB, 0xA573,
+	0x53EC, 0xA56C, 0x53ED, 0xA57A, 0x53EE, 0xA56D, 0x53EF, 0xA569,
+	0x53F0, 0xA578, 0x53F1, 0xA577, 0x53F2, 0xA576, 0x53F3, 0xA56B,
+	0x53F5, 0xA572, 0x53F8, 0xA571, 0x53FB, 0xA57B, 0x53FC, 0xA570,
+	0x5401, 0xA653, 0x5403, 0xA659, 0x5404, 0xA655, 0x5406, 0xA65B,
+	0x5407, 0xC9C5, 0x5408, 0xA658, 0x5409, 0xA64E, 0x540A, 0xA651,
+	0x540B, 0xA654, 0x540C, 0xA650, 0x540D, 0xA657, 0x540E, 0xA65A,
+	0x540F, 0xA64F, 0x5410, 0xA652, 0x5411, 0xA656, 0x5412, 0xA65C,
+	0x5418, 0xCA7E, 0x5419, 0xCA7B, 0x541B, 0xA767, 0x541C, 0xCA7C,
+	0x541D, 0xA75B, 0x541E, 0xA75D, 0x541F, 0xA775, 0x5420, 0xA770,
+	0x5424, 0xCAA5, 0x5425, 0xCA7D, 0x5426, 0xA75F, 0x5427, 0xA761,
+	0x5428, 0xCAA4, 0x5429, 0xA768, 0x542A, 0xCA78, 0x542B, 0xA774,
+	0x542C, 0xA776, 0x542D, 0xA75C, 0x542E, 0xA76D, 0x5430, 0xCA76,
+	0x5431, 0xA773, 0x5433, 0xA764, 0x5435, 0xA76E, 0x5436, 0xA76F,
+	0x5437, 0xCA77, 0x5438, 0xA76C, 0x5439, 0xA76A, 0x543B, 0xA76B,
+	0x543C, 0xA771, 0x543D, 0xCAA1, 0x543E, 0xA75E, 0x5440, 0xA772,
+	0x5441, 0xCAA3, 0x5442, 0xA766, 0x5443, 0xA763, 0x5445, 0xCA7A,
+	0x5446, 0xA762, 0x5447, 0xCAA6, 0x5448, 0xA765, 0x544A, 0xA769,
+	0x544E, 0xA760, 0x544F, 0xCAA2, 0x5454, 0xCA79, 0x5460, 0xCBEB,
+	0x5461, 0xCBEA, 0x5462, 0xA94F, 0x5463, 0xCBED, 0x5464, 0xCBEF,
+	0x5465, 0xCBE4, 0x5466, 0xCBE7, 0x5467, 0xCBEE, 0x5468, 0xA950,
+	0x546B, 0xCBE1, 0x546C, 0xCBE5, 0x546F, 0xCBE9, 0x5470, 0xCE49,
+	0x5471, 0xA94B, 0x5472, 0xCE4D, 0x5473, 0xA8FD, 0x5474, 0xCBE6,
+	0x5475, 0xA8FE, 0x5476, 0xA94C, 0x5477, 0xA945, 0x5478, 0xA941,
+	0x547A, 0xCBE2, 0x547B, 0xA944, 0x547C, 0xA949, 0x547D, 0xA952,
+	0x547E, 0xCBE3, 0x547F, 0xCBDC, 0x5480, 0xA943, 0x5481, 0xCBDD,
+	0x5482, 0xCBDF, 0x5484, 0xA946, 0x5486, 0xA948, 0x5487, 0xCBDB,
+	0x5488, 0xCBE0, 0x548B, 0xA951, 0x548C, 0xA94D, 0x548D, 0xCBE8,
+	0x548E, 0xA953, 0x5490, 0xA94A, 0x5491, 0xCBDE, 0x5492, 0xA947,
+	0x5495, 0xA942, 0x5496, 0xA940, 0x5498, 0xCBEC, 0x549A, 0xA94E,
+	0x54A0, 0xCE48, 0x54A1, 0xCDFB, 0x54A2, 0xCE4B, 0x54A5, 0xCDFD,
+	0x54A6, 0xAB78, 0x54A7, 0xABA8, 0x54A8, 0xAB74, 0x54A9, 0xABA7,
+	0x54AA, 0xAB7D, 0x54AB, 0xABA4, 0x54AC, 0xAB72, 0x54AD, 0xCDFC,
+	0x54AE, 0xCE43, 0x54AF, 0xABA3, 0x54B0, 0xCE4F, 0x54B1, 0xABA5,
+	0x54B3, 0xAB79, 0x54B6, 0xCE45, 0x54B7, 0xCE42, 0x54B8, 0xAB77,
+	0x54BA, 0xCDFA, 0x54BB, 0xABA6, 0x54BC, 0xCE4A, 0x54BD, 0xAB7C,
+	0x54BE, 0xCE4C, 0x54BF, 0xABA9, 0x54C0, 0xAB73, 0x54C1, 0xAB7E,
+	0x54C2, 0xAB7B, 0x54C3, 0xCE40, 0x54C4, 0xABA1, 0x54C5, 0xCE46,
+	0x54C6, 0xCE47, 0x54C7, 0xAB7A, 0x54C8, 0xABA2, 0x54C9, 0xAB76,
+	0x54CE, 0xAB75, 0x54CF, 0xCDFE, 0x54D6, 0xCE44, 0x54DE, 0xCE4E,
+	0x54E0, 0xD144, 0x54E1, 0xADFB, 0x54E2, 0xD0F1, 0x54E4, 0xD0F6,
+	0x54E5, 0xADF4, 0x54E6, 0xAE40, 0x54E7, 0xD0F4, 0x54E8, 0xADEF,
+	0x54E9, 0xADF9, 0x54EA, 0xADFE, 0x54EB, 0xD0FB, 0x54ED, 0xADFA,
+	0x54EE, 0xADFD, 0x54F1, 0xD0FE, 0x54F2, 0xADF5, 0x54F3, 0xD0F5,
+	0x54F7, 0xD142, 0x54F8, 0xD143, 0x54FA, 0xADF7, 0x54FB, 0xD141,
+	0x54FC, 0xADF3, 0x54FD, 0xAE43, 0x54FF, 0xD0F8, 0x5501, 0xADF1,
+	0x5503, 0xD146, 0x5504, 0xD0F9, 0x5505, 0xD0FD, 0x5506, 0xADF6,
+	0x5507, 0xAE42, 0x5508, 0xD0FA, 0x5509, 0xADFC, 0x550A, 0xD140,
+	0x550B, 0xD147, 0x550C, 0xD4A1, 0x550E, 0xD145, 0x550F, 0xAE44,
+	0x5510, 0xADF0, 0x5511, 0xD0FC, 0x5512, 0xD0F3, 0x5514, 0xADF8,
+	0x5517, 0xD0F2, 0x551A, 0xD0F7, 0x5526, 0xD0F0, 0x5527, 0xAE41,
+	0x552A, 0xD477, 0x552C, 0xB0E4, 0x552D, 0xD4A7, 0x552E, 0xB0E2,
+	0x552F, 0xB0DF, 0x5530, 0xD47C, 0x5531, 0xB0DB, 0x5532, 0xD4A2,
+	0x5533, 0xB0E6, 0x5534, 0xD476, 0x5535, 0xD47B, 0x5536, 0xD47A,
+	0x5537, 0xADF2, 0x5538, 0xB0E1, 0x5539, 0xD4A5, 0x553B, 0xD4A8,
+	0x553C, 0xD473, 0x553E, 0xB3E8, 0x5540, 0xD4A9, 0x5541, 0xB0E7,
+	0x5543, 0xB0D9, 0x5544, 0xB0D6, 0x5545, 0xD47E, 0x5546, 0xB0D3,
+	0x5548, 0xD4A6, 0x554A, 0xB0DA, 0x554B, 0xD4AA, 0x554D, 0xD474,
+	0x554E, 0xD4A4, 0x554F, 0xB0DD, 0x5550, 0xD475, 0x5551, 0xD478,
+	0x5552, 0xD47D, 0x5555, 0xB0DE, 0x5556, 0xB0DC, 0x5557, 0xB0E8,
+	0x555C, 0xB0E3, 0x555E, 0xB0D7, 0x555F, 0xB1D2, 0x5561, 0xB0D8,
+	0x5562, 0xD479, 0x5563, 0xB0E5, 0x5564, 0xB0E0, 0x5565, 0xD4A3,
+	0x5566, 0xB0D5, 0x556A, 0xB0D4, 0x5575, 0xD471, 0x5576, 0xD472,
+	0x5577, 0xD86A, 0x557B, 0xB3D7, 0x557C, 0xB3DA, 0x557D, 0xD875,
+	0x557E, 0xB3EE, 0x557F, 0xD878, 0x5580, 0xB3D8, 0x5581, 0xD871,
+	0x5582, 0xB3DE, 0x5583, 0xB3E4, 0x5584, 0xB5BD, 0x5587, 0xB3E2,
+	0x5588, 0xD86E, 0x5589, 0xB3EF, 0x558A, 0xB3DB, 0x558B, 0xB3E3,
+	0x558C, 0xD876, 0x558D, 0xDCD7, 0x558E, 0xD87B, 0x558F, 0xD86F,
+	0x5591, 0xD866, 0x5592, 0xD873, 0x5593, 0xD86D, 0x5594, 0xB3E1,
+	0x5595, 0xD879, 0x5598, 0xB3DD, 0x5599, 0xB3F1, 0x559A, 0xB3EA,
+	0x559C, 0xB3DF, 0x559D, 0xB3DC, 0x559F, 0xB3E7, 0x55A1, 0xD87A,
+	0x55A2, 0xD86C, 0x55A3, 0xD872, 0x55A4, 0xD874, 0x55A5, 0xD868,
+	0x55A6, 0xD877, 0x55A7, 0xB3D9, 0x55A8, 0xD867, 0x55AA, 0xB3E0,
+	0x55AB, 0xB3F0, 0x55AC, 0xB3EC, 0x55AD, 0xD869, 0x55AE, 0xB3E6,
+	0x55B1, 0xB3ED, 0x55B2, 0xB3E9, 0x55B3, 0xB3E5, 0x55B5, 0xD870,
+	0x55BB, 0xB3EB, 0x55BF, 0xDCD5, 0x55C0, 0xDCD1, 0x55C2, 0xDCE0,
+	0x55C3, 0xDCCA, 0x55C4, 0xDCD3, 0x55C5, 0xB6E5, 0x55C6, 0xB6E6,
+	0x55C7, 0xB6DE, 0x55C8, 0xDCDC, 0x55C9, 0xB6E8, 0x55CA, 0xDCCF,
+	0x55CB, 0xDCCE, 0x55CC, 0xDCCC, 0x55CD, 0xDCDE, 0x55CE, 0xB6DC,
+	0x55CF, 0xDCD8, 0x55D0, 0xDCCD, 0x55D1, 0xB6DF, 0x55D2, 0xDCD6,
+	0x55D3, 0xB6DA, 0x55D4, 0xDCD2, 0x55D5, 0xDCD9, 0x55D6, 0xDCDB,
+	0x55D9, 0xDCDF, 0x55DA, 0xB6E3, 0x55DB, 0xDCCB, 0x55DC, 0xB6DD,
+	0x55DD, 0xDCD0, 0x55DF, 0xB6D8, 0x55E1, 0xB6E4, 0x55E2, 0xDCDA,
+	0x55E3, 0xB6E0, 0x55E4, 0xB6E1, 0x55E5, 0xB6E7, 0x55E6, 0xB6DB,
+	0x55E7, 0xA25F, 0x55E8, 0xB6D9, 0x55E9, 0xDCD4, 0x55EF, 0xB6E2,
+	0x55F2, 0xDCDD, 0x55F6, 0xB9CD, 0x55F7, 0xB9C8, 0x55F9, 0xE155,
+	0x55FA, 0xE151, 0x55FC, 0xE14B, 0x55FD, 0xB9C2, 0x55FE, 0xB9BE,
+	0x55FF, 0xE154, 0x5600, 0xB9BF, 0x5601, 0xE14E, 0x5602, 0xE150,
+	0x5604, 0xE153, 0x5606, 0xB9C4, 0x5608, 0xB9CB, 0x5609, 0xB9C5,
+	0x560C, 0xE149, 0x560D, 0xB9C6, 0x560E, 0xB9C7, 0x560F, 0xE14C,
+	0x5610, 0xB9CC, 0x5612, 0xE14A, 0x5613, 0xE14F, 0x5614, 0xB9C3,
+	0x5615, 0xE148, 0x5616, 0xB9C9, 0x5617, 0xB9C1, 0x561B, 0xB9C0,
+	0x561C, 0xE14D, 0x561D, 0xE152, 0x561F, 0xB9CA, 0x5627, 0xE147,
+	0x5629, 0xBC4D, 0x562A, 0xE547, 0x562C, 0xE544, 0x562E, 0xBC47,
+	0x562F, 0xBC53, 0x5630, 0xBC54, 0x5632, 0xBC4A, 0x5633, 0xE542,
+	0x5634, 0xBC4C, 0x5635, 0xE4F9, 0x5636, 0xBC52, 0x5638, 0xE546,
+	0x5639, 0xBC49, 0x563A, 0xE548, 0x563B, 0xBC48, 0x563D, 0xE543,
+	0x563E, 0xE545, 0x563F, 0xBC4B, 0x5640, 0xE541, 0x5641, 0xE4FA,
+	0x5642, 0xE4F7, 0x5645, 0xD86B, 0x5646, 0xE4FD, 0x5648, 0xE4F6,
+	0x5649, 0xE4FC, 0x564A, 0xE4FB, 0x564C, 0xE4F8, 0x564E, 0xBC4F,
+	0x5653, 0xBC4E, 0x5657, 0xBC50, 0x5658, 0xE4FE, 0x5659, 0xBEB2,
+	0x565A, 0xE540, 0x565E, 0xE945, 0x5660, 0xE8FD, 0x5662, 0xBEBE,
+	0x5663, 0xE942, 0x5664, 0xBEB6, 0x5665, 0xBEBA, 0x5666, 0xE941,
+	0x5668, 0xBEB9, 0x5669, 0xBEB5, 0x566A, 0xBEB8, 0x566B, 0xBEB3,
+	0x566C, 0xBEBD, 0x566D, 0xE943, 0x566E, 0xE8FE, 0x566F, 0xBEBC,
+	0x5670, 0xE8FC, 0x5671, 0xBEBB, 0x5672, 0xE944, 0x5673, 0xE940,
+	0x5674, 0xBC51, 0x5676, 0xBEBF, 0x5677, 0xE946, 0x5678, 0xBEB7,
+	0x5679, 0xBEB4, 0x567E, 0xECC6, 0x567F, 0xECC8, 0x5680, 0xC07B,
+	0x5681, 0xECC9, 0x5682, 0xECC7, 0x5683, 0xECC5, 0x5684, 0xECC4,
+	0x5685, 0xC07D, 0x5686, 0xECC3, 0x5687, 0xC07E, 0x568C, 0xECC1,
+	0x568D, 0xECC2, 0x568E, 0xC07A, 0x568F, 0xC0A1, 0x5690, 0xC07C,
+	0x5693, 0xECC0, 0x5695, 0xC250, 0x5697, 0xEFBC, 0x5698, 0xEFBA,
+	0x5699, 0xEFBF, 0x569A, 0xEFBD, 0x569C, 0xEFBB, 0x569D, 0xEFBE,
+	0x56A5, 0xC360, 0x56A6, 0xF1F2, 0x56A7, 0xF1F3, 0x56A8, 0xC456,
+	0x56AA, 0xF1F4, 0x56AB, 0xF1F0, 0x56AC, 0xF1F5, 0x56AD, 0xF1F1,
+	0x56AE, 0xC251, 0x56B2, 0xF3FE, 0x56B3, 0xF441, 0x56B4, 0xC459,
+	0x56B5, 0xF440, 0x56B6, 0xC458, 0x56B7, 0xC457, 0x56BC, 0xC45A,
+	0x56BD, 0xF5C5, 0x56BE, 0xF5C6, 0x56C0, 0xC4DA, 0x56C1, 0xC4D9,
+	0x56C2, 0xC4DB, 0x56C3, 0xF5C4, 0x56C5, 0xF6D8, 0x56C6, 0xF6D7,
+	0x56C8, 0xC56D, 0x56C9, 0xC56F, 0x56CA, 0xC56E, 0x56CB, 0xF6D9,
+	0x56CC, 0xC5C8, 0x56CD, 0xF8A6, 0x56D1, 0xC5F1, 0x56D3, 0xF8A5,
+	0x56D4, 0xF8EE, 0x56D7, 0xC949, 0x56DA, 0xA57D, 0x56DB, 0xA57C,
+	0x56DD, 0xA65F, 0x56DE, 0xA65E, 0x56DF, 0xC9C7, 0x56E0, 0xA65D,
+	0x56E1, 0xC9C6, 0x56E4, 0xA779, 0x56E5, 0xCAA9, 0x56E7, 0xCAA8,
+	0x56EA, 0xA777, 0x56EB, 0xA77A, 0x56EE, 0xCAA7, 0x56F0, 0xA778,
+	0x56F7, 0xCBF0, 0x56F9, 0xCBF1, 0x56FA, 0xA954, 0x56FF, 0xABAA,
+	0x5701, 0xD148, 0x5702, 0xD149, 0x5703, 0xAE45, 0x5704, 0xAE46,
+	0x5707, 0xD4AC, 0x5708, 0xB0E9, 0x5709, 0xB0EB, 0x570A, 0xD4AB,
+	0x570B, 0xB0EA, 0x570C, 0xD87C, 0x570D, 0xB3F2, 0x5712, 0xB6E9,
+	0x5713, 0xB6EA, 0x5714, 0xDCE1, 0x5716, 0xB9CF, 0x5718, 0xB9CE,
+	0x571A, 0xE549, 0x571B, 0xE948, 0x571C, 0xE947, 0x571E, 0xF96B,
+	0x571F, 0xA467, 0x5720, 0xC959, 0x5722, 0xC96E, 0x5723, 0xC96F,
+	0x5728, 0xA662, 0x5729, 0xA666, 0x572A, 0xC9C9, 0x572C, 0xA664,
+	0x572D, 0xA663, 0x572E, 0xC9C8, 0x572F, 0xA665, 0x5730, 0xA661,
+	0x5733, 0xA660, 0x5734, 0xC9CA, 0x573B, 0xA7A6, 0x573E, 0xA7A3,
+	0x5740, 0xA77D, 0x5741, 0xCAAA, 0x5745, 0xCAAB, 0x5747, 0xA7A1,
+	0x5749, 0xCAAD, 0x574A, 0xA77B, 0x574B, 0xCAAE, 0x574C, 0xCAAC,
+	0x574D, 0xA77E, 0x574E, 0xA7A2, 0x574F, 0xA7A5, 0x5750, 0xA7A4,
+	0x5751, 0xA77C, 0x5752, 0xCAAF, 0x5761, 0xA959, 0x5762, 0xCBFE,
+	0x5764, 0xA95B, 0x5766, 0xA95A, 0x5768, 0xCC40, 0x5769, 0xA958,
+	0x576A, 0xA957, 0x576B, 0xCBF5, 0x576D, 0xCBF4, 0x576F, 0xCBF2,
+	0x5770, 0xCBF7, 0x5771, 0xCBF6, 0x5772, 0xCBF3, 0x5773, 0xCBFC,
+	0x5774, 0xCBFD, 0x5775, 0xCBFA, 0x5776, 0xCBF8, 0x5777, 0xA956,
+	0x577B, 0xCBFB, 0x577C, 0xA95C, 0x577D, 0xCC41, 0x5780, 0xCBF9,
+	0x5782, 0xABAB, 0x5783, 0xA955, 0x578B, 0xABAC, 0x578C, 0xCE54,
+	0x578F, 0xCE5A, 0x5793, 0xABB2, 0x5794, 0xCE58, 0x5795, 0xCE5E,
+	0x5797, 0xCE55, 0x5798, 0xCE59, 0x5799, 0xCE5B, 0x579A, 0xCE5D,
+	0x579B, 0xCE57, 0x579D, 0xCE56, 0x579E, 0xCE51, 0x579F, 0xCE52,
+	0x57A0, 0xABAD, 0x57A2, 0xABAF, 0x57A3, 0xABAE, 0x57A4, 0xCE53,
+	0x57A5, 0xCE5C, 0x57AE, 0xABB1, 0x57B5, 0xCE50, 0x57B6, 0xD153,
+	0x57B8, 0xD152, 0x57B9, 0xD157, 0x57BA, 0xD14E, 0x57BC, 0xD151,
+	0x57BD, 0xD150, 0x57BF, 0xD154, 0x57C1, 0xD158, 0x57C2, 0xAE47,
+	0x57C3, 0xAE4A, 0x57C6, 0xD14F, 0x57C7, 0xD155, 0x57CB, 0xAE49,
+	0x57CC, 0xD14A, 0x57CE, 0xABB0, 0x57CF, 0xD4BA, 0x57D0, 0xD156,
+	0x57D2, 0xD14D, 0x57D4, 0xAE48, 0x57D5, 0xD14C, 0x57DC, 0xD4B1,
+	0x57DF, 0xB0EC, 0x57E0, 0xB0F0, 0x57E1, 0xD4C1, 0x57E2, 0xD4AF,
+	0x57E3, 0xD4BD, 0x57E4, 0xB0F1, 0x57E5, 0xD4BF, 0x57E7, 0xD4C5,
+	0x57E9, 0xD4C9, 0x57EC, 0xD4C0, 0x57ED, 0xD4B4, 0x57EE, 0xD4BC,
+	0x57F0, 0xD4CA, 0x57F1, 0xD4C8, 0x57F2, 0xD4BE, 0x57F3, 0xD4B9,
+	0x57F4, 0xD4B2, 0x57F5, 0xD8A6, 0x57F6, 0xD4B0, 0x57F7, 0xB0F5,
+	0x57F8, 0xD4B7, 0x57F9, 0xB0F6, 0x57FA, 0xB0F2, 0x57FB, 0xD4AD,
+	0x57FC, 0xD4C3, 0x57FD, 0xD4B5, 0x5800, 0xD4B3, 0x5801, 0xD4C6,
+	0x5802, 0xB0F3, 0x5804, 0xD4CC, 0x5805, 0xB0ED, 0x5806, 0xB0EF,
+	0x5807, 0xD4BB, 0x5808, 0xD4B6, 0x5809, 0xAE4B, 0x580A, 0xB0EE,
+	0x580B, 0xD4B8, 0x580C, 0xD4C7, 0x580D, 0xD4CB, 0x580E, 0xD4C2,
+	0x5810, 0xD4C4, 0x5814, 0xD4AE, 0x5819, 0xD8A1, 0x581B, 0xD8AA,
+	0x581C, 0xD8A9, 0x581D, 0xB3FA, 0x581E, 0xD8A2, 0x5820, 0xB3FB,
+	0x5821, 0xB3F9, 0x5823, 0xD8A4, 0x5824, 0xB3F6, 0x5825, 0xD8A8,
+	0x5827, 0xD8A3, 0x5828, 0xD8A5, 0x5829, 0xD87D, 0x582A, 0xB3F4,
+	0x582C, 0xD8B2, 0x582D, 0xD8B1, 0x582E, 0xD8AE, 0x582F, 0xB3F3,
+	0x5830, 0xB3F7, 0x5831, 0xB3F8, 0x5832, 0xD14B, 0x5833, 0xD8AB,
+	0x5834, 0xB3F5, 0x5835, 0xB0F4, 0x5836, 0xD8AD, 0x5837, 0xD87E,
+	0x5838, 0xD8B0, 0x5839, 0xD8AF, 0x583B, 0xD8B3, 0x583D, 0xDCEF,
+	0x583F, 0xD8AC, 0x5848, 0xD8A7, 0x5849, 0xDCE7, 0x584A, 0xB6F4,
+	0x584B, 0xB6F7, 0x584C, 0xB6F2, 0x584D, 0xDCE6, 0x584E, 0xDCEA,
+	0x584F, 0xDCE5, 0x5851, 0xB6EC, 0x5852, 0xB6F6, 0x5853, 0xDCE2,
+	0x5854, 0xB6F0, 0x5855, 0xDCE9, 0x5857, 0xB6EE, 0x5858, 0xB6ED,
+	0x5859, 0xDCEC, 0x585A, 0xB6EF, 0x585B, 0xDCEE, 0x585D, 0xDCEB,
+	0x585E, 0xB6EB, 0x5862, 0xB6F5, 0x5863, 0xDCF0, 0x5864, 0xDCE4,
+	0x5865, 0xDCED, 0x5868, 0xDCE3, 0x586B, 0xB6F1, 0x586D, 0xB6F3,
+	0x586F, 0xDCE8, 0x5871, 0xDCF1, 0x5874, 0xE15D, 0x5875, 0xB9D0,
+	0x5876, 0xE163, 0x5879, 0xB9D5, 0x587A, 0xE15F, 0x587B, 0xE166,
+	0x587C, 0xE157, 0x587D, 0xB9D7, 0x587E, 0xB9D1, 0x587F, 0xE15C,
+	0x5880, 0xBC55, 0x5881, 0xE15B, 0x5882, 0xE164, 0x5883, 0xB9D2,
+	0x5885, 0xB9D6, 0x5886, 0xE15A, 0x5887, 0xE160, 0x5888, 0xE165,
+	0x5889, 0xE156, 0x588A, 0xB9D4, 0x588B, 0xE15E, 0x588E, 0xE162,
+	0x588F, 0xE168, 0x5890, 0xE158, 0x5891, 0xE161, 0x5893, 0xB9D3,
+	0x5894, 0xE167, 0x5898, 0xE159, 0x589C, 0xBC59, 0x589D, 0xE54B,
+	0x589E, 0xBC57, 0x589F, 0xBC56, 0x58A0, 0xE54D, 0x58A1, 0xE552,
+	0x58A3, 0xE54E, 0x58A5, 0xE551, 0x58A6, 0xBC5C, 0x58A8, 0xBEA5,
+	0x58A9, 0xBC5B, 0x58AB, 0xE54A, 0x58AC, 0xE550, 0x58AE, 0xBC5A,
+	0x58AF, 0xE54F, 0x58B1, 0xE54C, 0x58B3, 0xBC58, 0x58BA, 0xE94D,
+	0x58BB, 0xF9D9, 0x58BC, 0xE94F, 0x58BD, 0xE94A, 0x58BE, 0xBEC1,
+	0x58BF, 0xE94C, 0x58C1, 0xBEC0, 0x58C2, 0xE94E, 0x58C5, 0xBEC3,
+	0x58C6, 0xE950, 0x58C7, 0xBEC2, 0x58C8, 0xE949, 0x58C9, 0xE94B,
+	0x58CE, 0xC0A5, 0x58CF, 0xECCC, 0x58D1, 0xC0A4, 0x58D2, 0xECCD,
+	0x58D3, 0xC0A3, 0x58D4, 0xECCB, 0x58D5, 0xC0A2, 0x58D6, 0xECCA,
+	0x58D8, 0xC253, 0x58D9, 0xC252, 0x58DA, 0xF1F6, 0x58DB, 0xF1F8,
+	0x58DD, 0xF1F7, 0x58DE, 0xC361, 0x58DF, 0xC362, 0x58E2, 0xC363,
+	0x58E3, 0xF442, 0x58E4, 0xC45B, 0x58E7, 0xF7D3, 0x58E8, 0xF7D2,
+	0x58E9, 0xC5F2, 0x58EB, 0xA468, 0x58EC, 0xA4D0, 0x58EF, 0xA7A7,
+	0x58F4, 0xCE5F, 0x58F9, 0xB3FC, 0x58FA, 0xB3FD, 0x58FC, 0xDCF2,
+	0x58FD, 0xB9D8, 0x58FE, 0xE169, 0x58FF, 0xE553, 0x5903, 0xC95A,
+	0x5906, 0xCAB0, 0x590C, 0xCC42, 0x590D, 0xCE60, 0x590E, 0xD159,
+	0x590F, 0xAE4C, 0x5912, 0xF1F9, 0x5914, 0xC4DC, 0x5915, 0xA469,
+	0x5916, 0xA57E, 0x5917, 0xC970, 0x5919, 0xA667, 0x591A, 0xA668,
+	0x591C, 0xA95D, 0x5920, 0xB0F7, 0x5922, 0xB9DA, 0x5924, 0xB9DB,
+	0x5925, 0xB9D9, 0x5927, 0xA46A, 0x5929, 0xA4D1, 0x592A, 0xA4D3,
+	0x592B, 0xA4D2, 0x592C, 0xC95B, 0x592D, 0xA4D4, 0x592E, 0xA5A1,
+	0x592F, 0xC971, 0x5931, 0xA5A2, 0x5937, 0xA669, 0x5938, 0xA66A,
+	0x593C, 0xC9CB, 0x593E, 0xA7A8, 0x5940, 0xCAB1, 0x5944, 0xA961,
+	0x5945, 0xCC43, 0x5947, 0xA95F, 0x5948, 0xA960, 0x5949, 0xA95E,
+	0x594A, 0xD15A, 0x594E, 0xABB6, 0x594F, 0xABB5, 0x5950, 0xABB7,
+	0x5951, 0xABB4, 0x5953, 0xCE61, 0x5954, 0xA962, 0x5955, 0xABB3,
+	0x5957, 0xAE4D, 0x5958, 0xAE4E, 0x595A, 0xAE4F, 0x595C, 0xD4CD,
+	0x5960, 0xB3FE, 0x5961, 0xD8B4, 0x5962, 0xB0F8, 0x5967, 0xB6F8,
+	0x5969, 0xB9DD, 0x596A, 0xB9DC, 0x596B, 0xE16A, 0x596D, 0xBC5D,
+	0x596E, 0xBEC4, 0x5970, 0xEFC0, 0x5971, 0xF6DA, 0x5972, 0xF7D4,
+	0x5973, 0xA46B, 0x5974, 0xA5A3, 0x5976, 0xA5A4, 0x5977, 0xC9D1,
+	0x5978, 0xA66C, 0x5979, 0xA66F, 0x597B, 0xC9CF, 0x597C, 0xC9CD,
+	0x597D, 0xA66E, 0x597E, 0xC9D0, 0x597F, 0xC9D2, 0x5980, 0xC9CC,
+	0x5981, 0xA671, 0x5982, 0xA670, 0x5983, 0xA66D, 0x5984, 0xA66B,
+	0x5985, 0xC9CE, 0x598A, 0xA7B3, 0x598D, 0xA7B0, 0x598E, 0xCAB6,
+	0x598F, 0xCAB9, 0x5990, 0xCAB8, 0x5992, 0xA7AA, 0x5993, 0xA7B2,
+	0x5996, 0xA7AF, 0x5997, 0xCAB5, 0x5998, 0xCAB3, 0x5999, 0xA7AE,
+	0x599D, 0xA7A9, 0x599E, 0xA7AC, 0x59A0, 0xCAB4, 0x59A1, 0xCABB,
+	0x59A2, 0xCAB7, 0x59A3, 0xA7AD, 0x59A4, 0xA7B1, 0x59A5, 0xA7B4,
+	0x59A6, 0xCAB2, 0x59A7, 0xCABA, 0x59A8, 0xA7AB, 0x59AE, 0xA967,
+	0x59AF, 0xA96F, 0x59B1, 0xCC4F, 0x59B2, 0xCC48, 0x59B3, 0xA970,
+	0x59B4, 0xCC53, 0x59B5, 0xCC44, 0x59B6, 0xCC4B, 0x59B9, 0xA966,
+	0x59BA, 0xCC45, 0x59BB, 0xA964, 0x59BC, 0xCC4C, 0x59BD, 0xCC50,
+	0x59BE, 0xA963, 0x59C0, 0xCC51, 0x59C1, 0xCC4A, 0x59C3, 0xCC4D,
+	0x59C5, 0xA972, 0x59C6, 0xA969, 0x59C7, 0xCC54, 0x59C8, 0xCC52,
+	0x59CA, 0xA96E, 0x59CB, 0xA96C, 0x59CC, 0xCC49, 0x59CD, 0xA96B,
+	0x59CE, 0xCC47, 0x59CF, 0xCC46, 0x59D0, 0xA96A, 0x59D1, 0xA968,
+	0x59D2, 0xA971, 0x59D3, 0xA96D, 0x59D4, 0xA965, 0x59D6, 0xCC4E,
+	0x59D8, 0xABB9, 0x59DA, 0xABC0, 0x59DB, 0xCE6F, 0x59DC, 0xABB8,
+	0x59DD, 0xCE67, 0x59DE, 0xCE63, 0x59E0, 0xCE73, 0x59E1, 0xCE62,
+	0x59E3, 0xABBB, 0x59E4, 0xCE6C, 0x59E5, 0xABBE, 0x59E6, 0xABC1,
+	0x59E8, 0xABBC, 0x59E9, 0xCE70, 0x59EA, 0xABBF, 0x59EC, 0xAE56,
+	0x59ED, 0xCE76, 0x59EE, 0xCE64, 0x59F1, 0xCE66, 0x59F2, 0xCE6D,
+	0x59F3, 0xCE71, 0x59F4, 0xCE75, 0x59F5, 0xCE72, 0x59F6, 0xCE6B,
+	0x59F7, 0xCE6E, 0x59FA, 0xCE68, 0x59FB, 0xABC3, 0x59FC, 0xCE6A,
+	0x59FD, 0xCE69, 0x59FE, 0xCE74, 0x59FF, 0xABBA, 0x5A00, 0xCE65,
+	0x5A01, 0xABC2, 0x5A03, 0xABBD, 0x5A09, 0xAE5C, 0x5A0A, 0xD162,
+	0x5A0C, 0xAE5B, 0x5A0F, 0xD160, 0x5A11, 0xAE50, 0x5A13, 0xAE55,
+	0x5A15, 0xD15F, 0x5A16, 0xD15C, 0x5A17, 0xD161, 0x5A18, 0xAE51,
+	0x5A19, 0xD15B, 0x5A1B, 0xAE54, 0x5A1C, 0xAE52, 0x5A1E, 0xD163,
+	0x5A1F, 0xAE53, 0x5A20, 0xAE57, 0x5A23, 0xAE58, 0x5A25, 0xAE5A,
+	0x5A29, 0xAE59, 0x5A2D, 0xD15D, 0x5A2E, 0xD15E, 0x5A33, 0xD164,
+	0x5A35, 0xD4D4, 0x5A36, 0xB0F9, 0x5A37, 0xD8C2, 0x5A38, 0xD4D3,
+	0x5A39, 0xD4E6, 0x5A3C, 0xB140, 0x5A3E, 0xD4E4, 0x5A40, 0xB0FE,
+	0x5A41, 0xB0FA, 0x5A42, 0xD4ED, 0x5A43, 0xD4DD, 0x5A44, 0xD4E0,
+	0x5A46, 0xB143, 0x5A47, 0xD4EA, 0x5A48, 0xD4E2, 0x5A49, 0xB0FB,
+	0x5A4A, 0xB144, 0x5A4C, 0xD4E7, 0x5A4D, 0xD4E5, 0x5A50, 0xD4D6,
+	0x5A51, 0xD4EB, 0x5A52, 0xD4DF, 0x5A53, 0xD4DA, 0x5A55, 0xD4D0,
+	0x5A56, 0xD4EC, 0x5A57, 0xD4DC, 0x5A58, 0xD4CF, 0x5A5A, 0xB142,
+	0x5A5B, 0xD4E1, 0x5A5C, 0xD4EE, 0x5A5D, 0xD4DE, 0x5A5E, 0xD4D2,
+	0x5A5F, 0xD4D7, 0x5A60, 0xD4CE, 0x5A62, 0xB141, 0x5A64, 0xD4DB,
+	0x5A65, 0xD4D8, 0x5A66, 0xB0FC, 0x5A67, 0xD4D1, 0x5A69, 0xD4E9,
+	0x5A6A, 0xB0FD, 0x5A6C, 0xD4D9, 0x5A6D, 0xD4D5, 0x5A70, 0xD4E8,
+	0x5A77, 0xB440, 0x5A78, 0xD8BB, 0x5A7A, 0xD8B8, 0x5A7B, 0xD8C9,
+	0x5A7C, 0xD8BD, 0x5A7D, 0xD8CA, 0x5A7F, 0xB442, 0x5A83, 0xD8C6,
+	0x5A84, 0xD8C3, 0x5A8A, 0xD8C4, 0x5A8B, 0xD8C7, 0x5A8C, 0xD8CB,
+	0x5A8E, 0xD4E3, 0x5A8F, 0xD8CD, 0x5A90, 0xDD47, 0x5A92, 0xB443,
+	0x5A93, 0xD8CE, 0x5A94, 0xD8B6, 0x5A95, 0xD8C0, 0x5A97, 0xD8C5,
+	0x5A9A, 0xB441, 0x5A9B, 0xB444, 0x5A9C, 0xD8CC, 0x5A9D, 0xD8CF,
+	0x5A9E, 0xD8BA, 0x5A9F, 0xD8B7, 0x5AA2, 0xD8B9, 0x5AA5, 0xD8BE,
+	0x5AA6, 0xD8BC, 0x5AA7, 0xB445, 0x5AA9, 0xD8C8, 0x5AAC, 0xD8BF,
+	0x5AAE, 0xD8C1, 0x5AAF, 0xD8B5, 0x5AB0, 0xDCFA, 0x5AB1, 0xDCF8,
+	0x5AB2, 0xB742, 0x5AB3, 0xB740, 0x5AB4, 0xDD43, 0x5AB5, 0xDCF9,
+	0x5AB6, 0xDD44, 0x5AB7, 0xDD40, 0x5AB8, 0xDCF7, 0x5AB9, 0xDD46,
+	0x5ABA, 0xDCF6, 0x5ABB, 0xDCFD, 0x5ABC, 0xB6FE, 0x5ABD, 0xB6FD,
+	0x5ABE, 0xB6FC, 0x5ABF, 0xDCFB, 0x5AC0, 0xDD41, 0x5AC1, 0xB6F9,
+	0x5AC2, 0xB741, 0x5AC4, 0xDCF4, 0x5AC6, 0xDCFE, 0x5AC7, 0xDCF3,
+	0x5AC8, 0xDCFC, 0x5AC9, 0xB6FA, 0x5ACA, 0xDD42, 0x5ACB, 0xDCF5,
+	0x5ACC, 0xB6FB, 0x5ACD, 0xDD45, 0x5AD5, 0xE16E, 0x5AD6, 0xB9E2,
+	0x5AD7, 0xB9E1, 0x5AD8, 0xB9E3, 0x5AD9, 0xE17A, 0x5ADA, 0xE170,
+	0x5ADB, 0xE176, 0x5ADC, 0xE16B, 0x5ADD, 0xE179, 0x5ADE, 0xE178,
+	0x5ADF, 0xE17C, 0x5AE0, 0xE175, 0x5AE1, 0xB9DE, 0x5AE2, 0xE174,
+	0x5AE3, 0xB9E4, 0x5AE5, 0xE16D, 0x5AE6, 0xB9DF, 0x5AE8, 0xE17B,
+	0x5AE9, 0xB9E0, 0x5AEA, 0xE16F, 0x5AEB, 0xE172, 0x5AEC, 0xE177,
+	0x5AED, 0xE171, 0x5AEE, 0xE16C, 0x5AF3, 0xE173, 0x5AF4, 0xE555,
+	0x5AF5, 0xBC61, 0x5AF6, 0xE558, 0x5AF7, 0xE557, 0x5AF8, 0xE55A,
+	0x5AF9, 0xE55C, 0x5AFA, 0xF9DC, 0x5AFB, 0xBC5F, 0x5AFD, 0xE556,
+	0x5AFF, 0xE554, 0x5B01, 0xE55D, 0x5B02, 0xE55B, 0x5B03, 0xE559,
+	0x5B05, 0xE55F, 0x5B07, 0xE55E, 0x5B08, 0xBC63, 0x5B09, 0xBC5E,
+	0x5B0B, 0xBC60, 0x5B0C, 0xBC62, 0x5B0F, 0xE560, 0x5B10, 0xE957,
+	0x5B13, 0xE956, 0x5B14, 0xE955, 0x5B16, 0xE958, 0x5B17, 0xE951,
+	0x5B19, 0xE952, 0x5B1A, 0xE95A, 0x5B1B, 0xE953, 0x5B1D, 0xBEC5,
+	0x5B1E, 0xE95C, 0x5B20, 0xE95B, 0x5B21, 0xE954, 0x5B23, 0xECD1,
+	0x5B24, 0xC0A8, 0x5B25, 0xECCF, 0x5B26, 0xECD4, 0x5B27, 0xECD3,
+	0x5B28, 0xE959, 0x5B2A, 0xC0A7, 0x5B2C, 0xECD2, 0x5B2D, 0xECCE,
+	0x5B2E, 0xECD6, 0x5B2F, 0xECD5, 0x5B30, 0xC0A6, 0x5B32, 0xECD0,
+	0x5B34, 0xBEC6, 0x5B38, 0xC254, 0x5B3C, 0xEFC1, 0x5B3D, 0xF1FA,
+	0x5B3E, 0xF1FB, 0x5B3F, 0xF1FC, 0x5B40, 0xC45C, 0x5B43, 0xC45D,
+	0x5B45, 0xF443, 0x5B47, 0xF5C8, 0x5B48, 0xF5C7, 0x5B4B, 0xF6DB,
+	0x5B4C, 0xF6DC, 0x5B4D, 0xF7D5, 0x5B4E, 0xF8A7, 0x5B50, 0xA46C,
+	0x5B51, 0xA46D, 0x5B53, 0xA46E, 0x5B54, 0xA4D5, 0x5B55, 0xA5A5,
+	0x5B56, 0xC9D3, 0x5B57, 0xA672, 0x5B58, 0xA673, 0x5B5A, 0xA7B7,
+	0x5B5B, 0xA7B8, 0x5B5C, 0xA7B6, 0x5B5D, 0xA7B5, 0x5B5F, 0xA973,
+	0x5B62, 0xCC55, 0x5B63, 0xA975, 0x5B64, 0xA974, 0x5B65, 0xCC56,
+	0x5B69, 0xABC4, 0x5B6B, 0xAE5D, 0x5B6C, 0xD165, 0x5B6E, 0xD4F0,
+	0x5B70, 0xB145, 0x5B71, 0xB447, 0x5B72, 0xD4EF, 0x5B73, 0xB446,
+	0x5B75, 0xB9E5, 0x5B77, 0xE17D, 0x5B78, 0xBEC7, 0x5B7A, 0xC0A9,
+	0x5B7B, 0xECD7, 0x5B7D, 0xC45E, 0x5B7F, 0xC570, 0x5B81, 0xC972,
+	0x5B83, 0xA5A6, 0x5B84, 0xC973, 0x5B85, 0xA676, 0x5B87, 0xA674,
+	0x5B88, 0xA675, 0x5B89, 0xA677, 0x5B8B, 0xA7BA, 0x5B8C, 0xA7B9,
+	0x5B8E, 0xCABC, 0x5B8F, 0xA7BB, 0x5B92, 0xCABD, 0x5B93, 0xCC57,
+	0x5B95, 0xCC58, 0x5B97, 0xA976, 0x5B98, 0xA978, 0x5B99, 0xA97A,
+	0x5B9A, 0xA977, 0x5B9B, 0xA97B, 0x5B9C, 0xA979, 0x5BA2, 0xABC8,
+	0x5BA3, 0xABC5, 0x5BA4, 0xABC7, 0x5BA5, 0xABC9, 0x5BA6, 0xABC6,
+	0x5BA7, 0xD166, 0x5BA8, 0xCE77, 0x5BAC, 0xD168, 0x5BAD, 0xD167,
+	0x5BAE, 0xAE63, 0x5BB0, 0xAE5F, 0x5BB3, 0xAE60, 0x5BB4, 0xAE62,
+	0x5BB5, 0xAE64, 0x5BB6, 0xAE61, 0x5BB8, 0xAE66, 0x5BB9, 0xAE65,
+	0x5BBF, 0xB14A, 0x5BC0, 0xD4F2, 0x5BC1, 0xD4F1, 0x5BC2, 0xB149,
+	0x5BC4, 0xB148, 0x5BC5, 0xB147, 0x5BC6, 0xB14B, 0x5BC7, 0xB146,
+	0x5BCA, 0xD8D5, 0x5BCB, 0xD8D2, 0x5BCC, 0xB449, 0x5BCD, 0xD8D1,
+	0x5BCE, 0xD8D6, 0x5BD0, 0xB44B, 0x5BD1, 0xD8D4, 0x5BD2, 0xB448,
+	0x5BD3, 0xB44A, 0x5BD4, 0xD8D3, 0x5BD6, 0xDD48, 0x5BD8, 0xDD49,
+	0x5BD9, 0xDD4A, 0x5BDE, 0xB9E6, 0x5BDF, 0xB9EE, 0x5BE0, 0xE17E,
+	0x5BE1, 0xB9E8, 0x5BE2, 0xB9EC, 0x5BE3, 0xE1A1, 0x5BE4, 0xB9ED,
+	0x5BE5, 0xB9E9, 0x5BE6, 0xB9EA, 0x5BE7, 0xB9E7, 0x5BE8, 0xB9EB,
+	0x5BE9, 0xBC66, 0x5BEA, 0xD8D0, 0x5BEB, 0xBC67, 0x5BEC, 0xBC65,
+	0x5BEE, 0xBC64, 0x5BEF, 0xE95D, 0x5BF0, 0xBEC8, 0x5BF1, 0xECD8,
+	0x5BF2, 0xECD9, 0x5BF5, 0xC364, 0x5BF6, 0xC45F, 0x5BF8, 0xA46F,
+	0x5BFA, 0xA678, 0x5C01, 0xABCA, 0x5C03, 0xD169, 0x5C04, 0xAE67,
+	0x5C07, 0xB14E, 0x5C08, 0xB14D, 0x5C09, 0xB14C, 0x5C0A, 0xB44C,
+	0x5C0B, 0xB44D, 0x5C0C, 0xD8D7, 0x5C0D, 0xB9EF, 0x5C0E, 0xBEC9,
+	0x5C0F, 0xA470, 0x5C10, 0xC95C, 0x5C11, 0xA4D6, 0x5C12, 0xC974,
+	0x5C15, 0xC9D4, 0x5C16, 0xA679, 0x5C1A, 0xA97C, 0x5C1F, 0xDD4B,
+	0x5C22, 0xA471, 0x5C24, 0xA4D7, 0x5C25, 0xC9D5, 0x5C28, 0xCABE,
+	0x5C2A, 0xCABF, 0x5C2C, 0xA7BC, 0x5C30, 0xD8D8, 0x5C31, 0xB44E,
+	0x5C33, 0xDD4C, 0x5C37, 0xC0AA, 0x5C38, 0xA472, 0x5C39, 0xA4A8,
+	0x5C3A, 0xA4D8, 0x5C3B, 0xC975, 0x5C3C, 0xA5A7, 0x5C3E, 0xA7C0,
+	0x5C3F, 0xA7BF, 0x5C40, 0xA7BD, 0x5C41, 0xA7BE, 0x5C44, 0xCC59,
+	0x5C45, 0xA97E, 0x5C46, 0xA9A1, 0x5C47, 0xCC5A, 0x5C48, 0xA97D,
+	0x5C4B, 0xABCE, 0x5C4C, 0xCE78, 0x5C4D, 0xABCD, 0x5C4E, 0xABCB,
+	0x5C4F, 0xABCC, 0x5C50, 0xAE6A, 0x5C51, 0xAE68, 0x5C54, 0xD16B,
+	0x5C55, 0xAE69, 0x5C56, 0xD16A, 0x5C58, 0xAE5E, 0x5C59, 0xD4F3,
+	0x5C5C, 0xB150, 0x5C5D, 0xB151, 0x5C60, 0xB14F, 0x5C62, 0xB9F0,
+	0x5C63, 0xE1A2, 0x5C64, 0xBC68, 0x5C65, 0xBC69, 0x5C67, 0xE561,
+	0x5C68, 0xC0AB, 0x5C69, 0xEFC2, 0x5C6A, 0xEFC3, 0x5C6C, 0xC4DD,
+	0x5C6D, 0xF8A8, 0x5C6E, 0xC94B, 0x5C6F, 0xA4D9, 0x5C71, 0xA473,
+	0x5C73, 0xC977, 0x5C74, 0xC976, 0x5C79, 0xA67A, 0x5C7A, 0xC9D7,
+	0x5C7B, 0xC9D8, 0x5C7C, 0xC9D6, 0x5C7E, 0xC9D9, 0x5C86, 0xCAC7,
+	0x5C88, 0xCAC2, 0x5C89, 0xCAC4, 0x5C8A, 0xCAC6, 0x5C8B, 0xCAC3,
+	0x5C8C, 0xA7C4, 0x5C8D, 0xCAC0, 0x5C8F, 0xCAC1, 0x5C90, 0xA7C1,
+	0x5C91, 0xA7C2, 0x5C92, 0xCAC5, 0x5C93, 0xCAC8, 0x5C94, 0xA7C3,
+	0x5C95, 0xCAC9, 0x5C9D, 0xCC68, 0x5C9F, 0xCC62, 0x5CA0, 0xCC5D,
+	0x5CA1, 0xA9A3, 0x5CA2, 0xCC65, 0x5CA3, 0xCC63, 0x5CA4, 0xCC5C,
+	0x5CA5, 0xCC69, 0x5CA6, 0xCC6C, 0x5CA7, 0xCC67, 0x5CA8, 0xCC60,
+	0x5CA9, 0xA9A5, 0x5CAA, 0xCC66, 0x5CAB, 0xA9A6, 0x5CAC, 0xCC61,
+	0x5CAD, 0xCC64, 0x5CAE, 0xCC5B, 0x5CAF, 0xCC5F, 0x5CB0, 0xCC6B,
+	0x5CB1, 0xA9A7, 0x5CB3, 0xA9A8, 0x5CB5, 0xCC5E, 0x5CB6, 0xCC6A,
+	0x5CB7, 0xA9A2, 0x5CB8, 0xA9A4, 0x5CC6, 0xCEAB, 0x5CC7, 0xCEA4,
+	0x5CC8, 0xCEAA, 0x5CC9, 0xCEA3, 0x5CCA, 0xCEA5, 0x5CCB, 0xCE7D,
+	0x5CCC, 0xCE7B, 0x5CCE, 0xCEAC, 0x5CCF, 0xCEA9, 0x5CD0, 0xCE79,
+	0x5CD2, 0xABD0, 0x5CD3, 0xCEA7, 0x5CD4, 0xCEA8, 0x5CD6, 0xCEA6,
+	0x5CD7, 0xCE7C, 0x5CD8, 0xCE7A, 0x5CD9, 0xABCF, 0x5CDA, 0xCEA2,
+	0x5CDB, 0xCE7E, 0x5CDE, 0xCEA1, 0x5CDF, 0xCEAD, 0x5CE8, 0xAE6F,
+	0x5CEA, 0xAE6E, 0x5CEC, 0xD16C, 0x5CED, 0xAE6B, 0x5CEE, 0xD16E,
+	0x5CF0, 0xAE70, 0x5CF1, 0xD16F, 0x5CF4, 0xAE73, 0x5CF6, 0xAE71,
+	0x5CF7, 0xD170, 0x5CF8, 0xCEAE, 0x5CF9, 0xD172, 0x5CFB, 0xAE6D,
+	0x5CFD, 0xAE6C, 0x5CFF, 0xD16D, 0x5D00, 0xD171, 0x5D01, 0xAE72,
+	0x5D06, 0xB153, 0x5D07, 0xB152, 0x5D0B, 0xD4F5, 0x5D0C, 0xD4F9,
+	0x5D0D, 0xD4FB, 0x5D0E, 0xB154, 0x5D0F, 0xD4FE, 0x5D11, 0xB158,
+	0x5D12, 0xD541, 0x5D14, 0xB15A, 0x5D16, 0xB156, 0x5D17, 0xB15E,
+	0x5D19, 0xB15B, 0x5D1A, 0xD4F7, 0x5D1B, 0xB155, 0x5D1D, 0xD4F6,
+	0x5D1E, 0xD4F4, 0x5D1F, 0xD543, 0x5D20, 0xD4F8, 0x5D22, 0xB157,
+	0x5D23, 0xD542, 0x5D24, 0xB15C, 0x5D25, 0xD4FD, 0x5D26, 0xD4FC,
+	0x5D27, 0xB15D, 0x5D28, 0xD4FA, 0x5D29, 0xB159, 0x5D2E, 0xD544,
+	0x5D30, 0xD540, 0x5D31, 0xD8E7, 0x5D32, 0xD8EE, 0x5D33, 0xD8E3,
+	0x5D34, 0xB451, 0x5D35, 0xD8DF, 0x5D36, 0xD8EF, 0x5D37, 0xD8D9,
+	0x5D38, 0xD8EC, 0x5D39, 0xD8EA, 0x5D3A, 0xD8E4, 0x5D3C, 0xD8ED,
+	0x5D3D, 0xD8E6, 0x5D3F, 0xD8DE, 0x5D40, 0xD8F0, 0x5D41, 0xD8DC,
+	0x5D42, 0xD8E9, 0x5D43, 0xD8DA, 0x5D45, 0xD8F1, 0x5D47, 0xB452,
+	0x5D49, 0xD8EB, 0x5D4A, 0xDD4F, 0x5D4B, 0xD8DD, 0x5D4C, 0xB44F,
+	0x5D4E, 0xD8E1, 0x5D50, 0xB450, 0x5D51, 0xD8E0, 0x5D52, 0xD8E5,
+	0x5D55, 0xD8E2, 0x5D59, 0xD8E8, 0x5D5E, 0xDD53, 0x5D62, 0xDD56,
+	0x5D63, 0xDD4E, 0x5D65, 0xDD50, 0x5D67, 0xDD55, 0x5D68, 0xDD54,
+	0x5D69, 0xB743, 0x5D6B, 0xD8DB, 0x5D6C, 0xDD52, 0x5D6F, 0xB744,
+	0x5D71, 0xDD4D, 0x5D72, 0xDD51, 0x5D77, 0xE1A9, 0x5D79, 0xE1B0,
+	0x5D7A, 0xE1A7, 0x5D7C, 0xE1AE, 0x5D7D, 0xE1A5, 0x5D7E, 0xE1AD,
+	0x5D7F, 0xE1B1, 0x5D80, 0xE1A4, 0x5D81, 0xE1A8, 0x5D82, 0xE1A3,
+	0x5D84, 0xB9F1, 0x5D86, 0xE1A6, 0x5D87, 0xB9F2, 0x5D88, 0xE1AC,
+	0x5D89, 0xE1AB, 0x5D8A, 0xE1AA, 0x5D8D, 0xE1AF, 0x5D92, 0xE565,
+	0x5D93, 0xE567, 0x5D94, 0xBC6B, 0x5D95, 0xE568, 0x5D97, 0xE563,
+	0x5D99, 0xE562, 0x5D9A, 0xE56C, 0x5D9C, 0xE56A, 0x5D9D, 0xBC6A,
+	0x5D9E, 0xE56D, 0x5D9F, 0xE564, 0x5DA0, 0xE569, 0x5DA1, 0xE56B,
+	0x5DA2, 0xE566, 0x5DA7, 0xE961, 0x5DA8, 0xE966, 0x5DA9, 0xE960,
+	0x5DAA, 0xE965, 0x5DAC, 0xE95E, 0x5DAD, 0xE968, 0x5DAE, 0xE964,
+	0x5DAF, 0xE969, 0x5DB0, 0xE963, 0x5DB1, 0xE95F, 0x5DB2, 0xE967,
+	0x5DB4, 0xE96A, 0x5DB5, 0xE962, 0x5DB7, 0xECDA, 0x5DB8, 0xC0AF,
+	0x5DBA, 0xC0AD, 0x5DBC, 0xC0AC, 0x5DBD, 0xC0AE, 0x5DC0, 0xEFC4,
+	0x5DC2, 0xF172, 0x5DC3, 0xF1FD, 0x5DC6, 0xF444, 0x5DC7, 0xF445,
+	0x5DC9, 0xC460, 0x5DCB, 0xF5C9, 0x5DCD, 0xC4DE, 0x5DCF, 0xF5CA,
+	0x5DD1, 0xF6DE, 0x5DD2, 0xC572, 0x5DD4, 0xC571, 0x5DD5, 0xF6DD,
+	0x5DD6, 0xC5C9, 0x5DD8, 0xF7D6, 0x5DDD, 0xA474, 0x5DDE, 0xA67B,
+	0x5DDF, 0xC9DA, 0x5DE0, 0xCACA, 0x5DE1, 0xA8B5, 0x5DE2, 0xB15F,
+	0x5DE5, 0xA475, 0x5DE6, 0xA5AA, 0x5DE7, 0xA5A9, 0x5DE8, 0xA5A8,
+	0x5DEB, 0xA7C5, 0x5DEE, 0xAE74, 0x5DF0, 0xDD57, 0x5DF1, 0xA476,
+	0x5DF2, 0xA477, 0x5DF3, 0xA478, 0x5DF4, 0xA4DA, 0x5DF7, 0xABD1,
+	0x5DF9, 0xCEAF, 0x5DFD, 0xB453, 0x5DFE, 0xA479, 0x5DFF, 0xC95D,
+	0x5E02, 0xA5AB, 0x5E03, 0xA5AC, 0x5E04, 0xC978, 0x5E06, 0xA67C,
+	0x5E0A, 0xCACB, 0x5E0C, 0xA7C6, 0x5E0E, 0xCACC, 0x5E11, 0xA9AE,
+	0x5E14, 0xCC6E, 0x5E15, 0xA9AC, 0x5E16, 0xA9AB, 0x5E17, 0xCC6D,
+	0x5E18, 0xA9A9, 0x5E19, 0xCC6F, 0x5E1A, 0xA9AA, 0x5E1B, 0xA9AD,
+	0x5E1D, 0xABD2, 0x5E1F, 0xABD4, 0x5E20, 0xCEB3, 0x5E21, 0xCEB0,
+	0x5E22, 0xCEB1, 0x5E23, 0xCEB2, 0x5E24, 0xCEB4, 0x5E25, 0xABD3,
+	0x5E28, 0xD174, 0x5E29, 0xD173, 0x5E2B, 0xAE76, 0x5E2D, 0xAE75,
+	0x5E33, 0xB162, 0x5E34, 0xD546, 0x5E36, 0xB161, 0x5E37, 0xB163,
+	0x5E38, 0xB160, 0x5E3D, 0xB455, 0x5E3E, 0xD545, 0x5E40, 0xB456,
+	0x5E41, 0xD8F3, 0x5E43, 0xB457, 0x5E44, 0xD8F2, 0x5E45, 0xB454,
+	0x5E4A, 0xDD5A, 0x5E4B, 0xDD5C, 0x5E4C, 0xB745, 0x5E4D, 0xDD5B,
+	0x5E4E, 0xDD59, 0x5E4F, 0xDD58, 0x5E53, 0xE1B4, 0x5E54, 0xB9F7,
+	0x5E55, 0xB9F5, 0x5E57, 0xB9F6, 0x5E58, 0xE1B2, 0x5E59, 0xE1B3,
+	0x5E5B, 0xB9F3, 0x5E5C, 0xE571, 0x5E5D, 0xE56F, 0x5E5F, 0xBC6D,
+	0x5E60, 0xE570, 0x5E61, 0xBC6E, 0x5E62, 0xBC6C, 0x5E63, 0xB9F4,
+	0x5E66, 0xE96D, 0x5E67, 0xE96B, 0x5E68, 0xE96C, 0x5E69, 0xE56E,
+	0x5E6A, 0xECDC, 0x5E6B, 0xC0B0, 0x5E6C, 0xECDB, 0x5E6D, 0xEFC5,
+	0x5E6E, 0xEFC6, 0x5E6F, 0xE96E, 0x5E70, 0xF1FE, 0x5E72, 0xA47A,
+	0x5E73, 0xA5AD, 0x5E74, 0xA67E, 0x5E75, 0xC9DB, 0x5E76, 0xA67D,
+	0x5E78, 0xA9AF, 0x5E79, 0xB746, 0x5E7B, 0xA4DB, 0x5E7C, 0xA5AE,
+	0x5E7D, 0xABD5, 0x5E7E, 0xB458, 0x5E80, 0xC979, 0x5E82, 0xC97A,
+	0x5E84, 0xC9DC, 0x5E87, 0xA7C8, 0x5E88, 0xCAD0, 0x5E89, 0xCACE,
+	0x5E8A, 0xA7C9, 0x5E8B, 0xCACD, 0x5E8C, 0xCACF, 0x5E8D, 0xCAD1,
+	0x5E8F, 0xA7C7, 0x5E95, 0xA9B3, 0x5E96, 0xA9B4, 0x5E97, 0xA9B1,
+	0x5E9A, 0xA9B0, 0x5E9B, 0xCEB8, 0x5E9C, 0xA9B2, 0x5EA0, 0xABD6,
+	0x5EA2, 0xCEB7, 0x5EA3, 0xCEB9, 0x5EA4, 0xCEB6, 0x5EA5, 0xCEBA,
+	0x5EA6, 0xABD7, 0x5EA7, 0xAE79, 0x5EA8, 0xD175, 0x5EAA, 0xD177,
+	0x5EAB, 0xAE77, 0x5EAC, 0xD178, 0x5EAD, 0xAE78, 0x5EAE, 0xD176,
+	0x5EB0, 0xCEB5, 0x5EB1, 0xD547, 0x5EB2, 0xD54A, 0x5EB3, 0xD54B,
+	0x5EB4, 0xD548, 0x5EB5, 0xB167, 0x5EB6, 0xB166, 0x5EB7, 0xB164,
+	0x5EB8, 0xB165, 0x5EB9, 0xD549, 0x5EBE, 0xB168, 0x5EC1, 0xB45A,
+	0x5EC2, 0xB45B, 0x5EC4, 0xB45C, 0x5EC5, 0xDD5D, 0x5EC6, 0xDD5F,
+	0x5EC7, 0xDD61, 0x5EC8, 0xB748, 0x5EC9, 0xB747, 0x5ECA, 0xB459,
+	0x5ECB, 0xDD60, 0x5ECC, 0xDD5E, 0x5ECE, 0xE1B8, 0x5ED1, 0xE1B6,
+	0x5ED2, 0xE1BC, 0x5ED3, 0xB9F8, 0x5ED4, 0xE1BD, 0x5ED5, 0xE1BA,
+	0x5ED6, 0xB9F9, 0x5ED7, 0xE1B7, 0x5ED8, 0xE1B5, 0x5ED9, 0xE1BB,
+	0x5EDA, 0xBC70, 0x5EDB, 0xE573, 0x5EDC, 0xE1B9, 0x5EDD, 0xBC72,
+	0x5EDE, 0xE574, 0x5EDF, 0xBC71, 0x5EE0, 0xBC74, 0x5EE1, 0xE575,
+	0x5EE2, 0xBC6F, 0x5EE3, 0xBC73, 0x5EE5, 0xE973, 0x5EE6, 0xE971,
+	0x5EE7, 0xE970, 0x5EE8, 0xE972, 0x5EE9, 0xE96F, 0x5EEC, 0xC366,
+	0x5EEE, 0xF446, 0x5EEF, 0xF447, 0x5EF1, 0xF5CB, 0x5EF2, 0xF6DF,
+	0x5EF3, 0xC655, 0x5EF6, 0xA9B5, 0x5EF7, 0xA7CA, 0x5EFA, 0xABD8,
+	0x5EFE, 0xA47B, 0x5EFF, 0xA4DC, 0x5F01, 0xA5AF, 0x5F02, 0xC9DD,
+	0x5F04, 0xA7CB, 0x5F05, 0xCAD2, 0x5F07, 0xCEBB, 0x5F08, 0xABD9,
+	0x5F0A, 0xB9FA, 0x5F0B, 0xA47C, 0x5F0F, 0xA6A1, 0x5F12, 0xB749,
+	0x5F13, 0xA47D, 0x5F14, 0xA4DD, 0x5F15, 0xA4DE, 0x5F17, 0xA5B1,
+	0x5F18, 0xA5B0, 0x5F1A, 0xC9DE, 0x5F1B, 0xA6A2, 0x5F1D, 0xCAD3,
+	0x5F1F, 0xA7CC, 0x5F22, 0xCC71, 0x5F23, 0xCC72, 0x5F24, 0xCC73,
+	0x5F26, 0xA9B6, 0x5F27, 0xA9B7, 0x5F28, 0xCC70, 0x5F29, 0xA9B8,
+	0x5F2D, 0xABDA, 0x5F2E, 0xCEBC, 0x5F30, 0xD17A, 0x5F31, 0xAE7A,
+	0x5F33, 0xD179, 0x5F35, 0xB169, 0x5F36, 0xD54C, 0x5F37, 0xB16A,
+	0x5F38, 0xD54D, 0x5F3C, 0xB45D, 0x5F40, 0xDD62, 0x5F43, 0xE1BF,
+	0x5F44, 0xE1BE, 0x5F46, 0xB9FB, 0x5F48, 0xBC75, 0x5F49, 0xE576,
+	0x5F4A, 0xBECA, 0x5F4B, 0xE974, 0x5F4C, 0xC0B1, 0x5F4E, 0xC573,
+	0x5F4F, 0xF7D8, 0x5F54, 0xCC74, 0x5F56, 0xCEBD, 0x5F57, 0xB16B,
+	0x5F58, 0xD8F4, 0x5F59, 0xB74A, 0x5F5D, 0xC255, 0x5F62, 0xA7CE,
+	0x5F64, 0xA7CD, 0x5F65, 0xABDB, 0x5F67, 0xD17B, 0x5F69, 0xB16D,
+	0x5F6A, 0xB343, 0x5F6B, 0xB16E, 0x5F6C, 0xB16C, 0x5F6D, 0xB45E,
+	0x5F6F, 0xE1C0, 0x5F70, 0xB9FC, 0x5F71, 0xBC76, 0x5F73, 0xC94C,
+	0x5F74, 0xC9DF, 0x5F76, 0xCAD5, 0x5F77, 0xA7CF, 0x5F78, 0xCAD4,
+	0x5F79, 0xA7D0, 0x5F7C, 0xA9BC, 0x5F7D, 0xCC77, 0x5F7E, 0xCC76,
+	0x5F7F, 0xA9BB, 0x5F80, 0xA9B9, 0x5F81, 0xA9BA, 0x5F82, 0xCC75,
+	0x5F85, 0xABDD, 0x5F86, 0xCEBE, 0x5F87, 0xABE0, 0x5F88, 0xABDC,
+	0x5F89, 0xABE2, 0x5F8A, 0xABDE, 0x5F8B, 0xABDF, 0x5F8C, 0xABE1,
+	0x5F90, 0xAE7D, 0x5F91, 0xAE7C, 0x5F92, 0xAE7B, 0x5F96, 0xD54F,
+	0x5F97, 0xB16F, 0x5F98, 0xB172, 0x5F99, 0xB170, 0x5F9B, 0xD54E,
+	0x5F9C, 0xB175, 0x5F9E, 0xB171, 0x5F9F, 0xD550, 0x5FA0, 0xB174,
+	0x5FA1, 0xB173, 0x5FA5, 0xD8F6, 0x5FA6, 0xD8F5, 0x5FA8, 0xB461,
+	0x5FA9, 0xB45F, 0x5FAA, 0xB460, 0x5FAB, 0xD8F7, 0x5FAC, 0xB74B,
+	0x5FAD, 0xDD64, 0x5FAE, 0xB74C, 0x5FAF, 0xDD63, 0x5FB2, 0xE577,
+	0x5FB5, 0xBC78, 0x5FB6, 0xE1C1, 0x5FB7, 0xBC77, 0x5FB9, 0xB9FD,
+	0x5FBB, 0xECDE, 0x5FBC, 0xE975, 0x5FBD, 0xC0B2, 0x5FBE, 0xECDD,
+	0x5FBF, 0xF240, 0x5FC0, 0xF448, 0x5FC1, 0xF449, 0x5FC3, 0xA4DF,
+	0x5FC5, 0xA5B2, 0x5FC9, 0xC97B, 0x5FCC, 0xA7D2, 0x5FCD, 0xA7D4,
+	0x5FCF, 0xC9E2, 0x5FD0, 0xCAD8, 0x5FD1, 0xCAD7, 0x5FD2, 0xCAD6,
+	0x5FD4, 0xC9E1, 0x5FD5, 0xC9E0, 0x5FD6, 0xA6A4, 0x5FD7, 0xA7D3,
+	0x5FD8, 0xA7D1, 0x5FD9, 0xA6A3, 0x5FDD, 0xA9BD, 0x5FDE, 0xCC78,
+	0x5FE0, 0xA9BE, 0x5FE1, 0xCADD, 0x5FE3, 0xCADF, 0x5FE4, 0xCADE,
+	0x5FE5, 0xCC79, 0x5FE8, 0xCADA, 0x5FEA, 0xA7D8, 0x5FEB, 0xA7D6,
+	0x5FED, 0xCAD9, 0x5FEE, 0xCADB, 0x5FEF, 0xCAE1, 0x5FF1, 0xA7D5,
+	0x5FF3, 0xCADC, 0x5FF4, 0xCAE5, 0x5FF5, 0xA9C0, 0x5FF7, 0xCAE2,
+	0x5FF8, 0xA7D7, 0x5FFA, 0xCAE0, 0x5FFB, 0xCAE3, 0x5FFD, 0xA9BF,
+	0x5FFF, 0xA9C1, 0x6000, 0xCAE4, 0x6009, 0xCCAF, 0x600A, 0xCCA2,
+	0x600B, 0xCC7E, 0x600C, 0xCCAE, 0x600D, 0xCCA9, 0x600E, 0xABE7,
+	0x600F, 0xA9C2, 0x6010, 0xCCAA, 0x6011, 0xCCAD, 0x6012, 0xABE3,
+	0x6013, 0xCCAC, 0x6014, 0xA9C3, 0x6015, 0xA9C8, 0x6016, 0xA9C6,
+	0x6017, 0xCCA3, 0x6019, 0xCC7C, 0x601A, 0xCCA5, 0x601B, 0xA9CD,
+	0x601C, 0xCCB0, 0x601D, 0xABE4, 0x601E, 0xCCA6, 0x6020, 0xABE5,
+	0x6021, 0xA9C9, 0x6022, 0xCCA8, 0x6024, 0xCECD, 0x6025, 0xABE6,
+	0x6026, 0xCC7B, 0x6027, 0xA9CA, 0x6028, 0xABE8, 0x6029, 0xA9CB,
+	0x602A, 0xA9C7, 0x602B, 0xA9CC, 0x602C, 0xCCA7, 0x602D, 0xCC7A,
+	0x602E, 0xCCAB, 0x602F, 0xA9C4, 0x6032, 0xCC7D, 0x6033, 0xCCA4,
+	0x6034, 0xCCA1, 0x6035, 0xA9C5, 0x6037, 0xCEBF, 0x6039, 0xCEC0,
+	0x6040, 0xCECA, 0x6041, 0xD1A1, 0x6042, 0xCECB, 0x6043, 0xABEE,
+	0x6044, 0xCECE, 0x6045, 0xCEC4, 0x6046, 0xABED, 0x6047, 0xCEC6,
+	0x6049, 0xCEC7, 0x604C, 0xCEC9, 0x604D, 0xABE9, 0x6050, 0xAEA3,
+	0x6052, 0xF9DA, 0x6053, 0xCEC5, 0x6054, 0xCEC1, 0x6055, 0xAEA4,
+	0x6058, 0xCECF, 0x6059, 0xAE7E, 0x605A, 0xD17D, 0x605B, 0xCEC8,
+	0x605D, 0xD17C, 0x605E, 0xCEC3, 0x605F, 0xCECC, 0x6062, 0xABEC,
+	0x6063, 0xAEA1, 0x6064, 0xABF2, 0x6065, 0xAEA2, 0x6066, 0xCED0,
+	0x6067, 0xD17E, 0x6068, 0xABEB, 0x6069, 0xAEA6, 0x606A, 0xABF1,
+	0x606B, 0xABF0, 0x606C, 0xABEF, 0x606D, 0xAEA5, 0x606E, 0xCED1,
+	0x606F, 0xAEA7, 0x6070, 0xABEA, 0x6072, 0xCEC2, 0x607F, 0xB176,
+	0x6080, 0xD1A4, 0x6081, 0xD1A6, 0x6083, 0xD1A8, 0x6084, 0xAEA8,
+	0x6085, 0xAEAE, 0x6086, 0xD553, 0x6087, 0xD1AC, 0x6088, 0xD1A3,
+	0x6089, 0xB178, 0x608A, 0xD551, 0x608C, 0xAEAD, 0x608D, 0xAEAB,
+	0x608E, 0xD1AE, 0x6090, 0xD552, 0x6092, 0xD1A5, 0x6094, 0xAEAC,
+	0x6095, 0xD1A9, 0x6096, 0xAEAF, 0x6097, 0xD1AB, 0x609A, 0xAEAA,
+	0x609B, 0xD1AA, 0x609C, 0xD1AD, 0x609D, 0xD1A7, 0x609F, 0xAEA9,
+	0x60A0, 0xB179, 0x60A2, 0xD1A2, 0x60A3, 0xB177, 0x60A8, 0xB17A,
+	0x60B0, 0xD555, 0x60B1, 0xD55E, 0x60B2, 0xB464, 0x60B4, 0xB17C,
+	0x60B5, 0xB1A3, 0x60B6, 0xB465, 0x60B7, 0xD560, 0x60B8, 0xB1AA,
+	0x60B9, 0xD8F9, 0x60BA, 0xD556, 0x60BB, 0xB1A2, 0x60BC, 0xB1A5,
+	0x60BD, 0xB17E, 0x60BE, 0xD554, 0x60BF, 0xD562, 0x60C0, 0xD565,
+	0x60C1, 0xD949, 0x60C3, 0xD563, 0x60C4, 0xD8FD, 0x60C5, 0xB1A1,
+	0x60C6, 0xB1A8, 0x60C7, 0xB1AC, 0x60C8, 0xD55D, 0x60C9, 0xD8F8,
+	0x60CA, 0xD561, 0x60CB, 0xB17B, 0x60CC, 0xD8FA, 0x60CD, 0xD564,
+	0x60CE, 0xD8FC, 0x60CF, 0xD559, 0x60D1, 0xB462, 0x60D3, 0xD557,
+	0x60D4, 0xD558, 0x60D5, 0xB1A7, 0x60D8, 0xB1A6, 0x60D9, 0xD55B,
+	0x60DA, 0xB1AB, 0x60DB, 0xD55F, 0x60DC, 0xB1A4, 0x60DD, 0xD55C,
+	0x60DF, 0xB1A9, 0x60E0, 0xB466, 0x60E1, 0xB463, 0x60E2, 0xD8FB,
+	0x60E4, 0xD55A, 0x60E6, 0xB17D, 0x60F0, 0xB46B, 0x60F1, 0xB46F,
+	0x60F2, 0xD940, 0x60F3, 0xB751, 0x60F4, 0xB46D, 0x60F5, 0xD944,
+	0x60F6, 0xB471, 0x60F7, 0xDD65, 0x60F8, 0xD946, 0x60F9, 0xB753,
+	0x60FA, 0xB469, 0x60FB, 0xB46C, 0x60FC, 0xD947, 0x60FE, 0xD948,
+	0x60FF, 0xD94E, 0x6100, 0xB473, 0x6101, 0xB754, 0x6103, 0xD94A,
+	0x6104, 0xD94F, 0x6105, 0xD943, 0x6106, 0xB75E, 0x6108, 0xB755,
+	0x6109, 0xB472, 0x610A, 0xD941, 0x610B, 0xD950, 0x610D, 0xB75D,
+	0x610E, 0xB470, 0x610F, 0xB74E, 0x6110, 0xD94D, 0x6112, 0xB474,
+	0x6113, 0xD945, 0x6114, 0xD8FE, 0x6115, 0xB46A, 0x6116, 0xD942,
+	0x6118, 0xD94B, 0x611A, 0xB74D, 0x611B, 0xB752, 0x611C, 0xB467,
+	0x611D, 0xD94C, 0x611F, 0xB750, 0x6123, 0xB468, 0x6127, 0xB75C,
+	0x6128, 0xE1C3, 0x6129, 0xDD70, 0x612B, 0xDD68, 0x612C, 0xE1C2,
+	0x612E, 0xDD6C, 0x612F, 0xDD6E, 0x6132, 0xDD6B, 0x6134, 0xB75B,
+	0x6136, 0xDD6A, 0x6137, 0xB75F, 0x613B, 0xE1D2, 0x613E, 0xB75A,
+	0x613F, 0xBA40, 0x6140, 0xDD71, 0x6141, 0xE1C4, 0x6144, 0xB758,
+	0x6145, 0xDD69, 0x6146, 0xDD6D, 0x6147, 0xB9FE, 0x6148, 0xB74F,
+	0x6149, 0xDD66, 0x614A, 0xDD67, 0x614B, 0xBA41, 0x614C, 0xB757,
+	0x614D, 0xB759, 0x614E, 0xB756, 0x614F, 0xDD6F, 0x6152, 0xE1C8,
+	0x6153, 0xE1C9, 0x6154, 0xE1CE, 0x6155, 0xBC7D, 0x6156, 0xE1D5,
+	0x6158, 0xBA47, 0x615A, 0xBA46, 0x615B, 0xE1D0, 0x615D, 0xBC7C,
+	0x615E, 0xE1C5, 0x615F, 0xBA45, 0x6161, 0xE1D4, 0x6162, 0xBA43,
+	0x6163, 0xBA44, 0x6165, 0xE1D1, 0x6166, 0xE5AA, 0x6167, 0xBC7A,
+	0x6168, 0xB46E, 0x616A, 0xE1D3, 0x616B, 0xBCA3, 0x616C, 0xE1CB,
+	0x616E, 0xBC7B, 0x6170, 0xBCA2, 0x6171, 0xE1C6, 0x6172, 0xE1CA,
+	0x6173, 0xE1C7, 0x6174, 0xE1CD, 0x6175, 0xBA48, 0x6176, 0xBC79,
+	0x6177, 0xBA42, 0x6179, 0xE57A, 0x617A, 0xE1CF, 0x617C, 0xBCA1,
+	0x617E, 0xBCA4, 0x6180, 0xE1CC, 0x6182, 0xBC7E, 0x6183, 0xE579,
+	0x6189, 0xE57E, 0x618A, 0xBECE, 0x618B, 0xE578, 0x618C, 0xE9A3,
+	0x618D, 0xE5A9, 0x618E, 0xBCA8, 0x6190, 0xBCA6, 0x6191, 0xBECC,
+	0x6192, 0xE5A6, 0x6193, 0xE5A2, 0x6194, 0xBCAC, 0x6196, 0xE978,
+	0x619A, 0xBCAA, 0x619B, 0xE5A1, 0x619D, 0xE976, 0x619F, 0xE5A5,
+	0x61A1, 0xE5A8, 0x61A2, 0xE57D, 0x61A4, 0xBCAB, 0x61A7, 0xBCA5,
+	0x61A8, 0xE977, 0x61A9, 0xBECD, 0x61AA, 0xE5A7, 0x61AB, 0xBCA7,
+	0x61AC, 0xBCA9, 0x61AD, 0xE5A4, 0x61AE, 0xBCAD, 0x61AF, 0xE5A3,
+	0x61B0, 0xE57C, 0x61B1, 0xE57B, 0x61B2, 0xBECB, 0x61B3, 0xE5AB,
+	0x61B4, 0xE97A, 0x61B5, 0xECE0, 0x61B6, 0xBED0, 0x61B8, 0xE9A2,
+	0x61BA, 0xE97E, 0x61BC, 0xECE1, 0x61BE, 0xBED1, 0x61BF, 0xE9A1,
+	0x61C1, 0xE97C, 0x61C2, 0xC0B4, 0x61C3, 0xECDF, 0x61C5, 0xE979,
+	0x61C6, 0xE97B, 0x61C7, 0xC0B5, 0x61C8, 0xBED3, 0x61C9, 0xC0B3,
+	0x61CA, 0xBED2, 0x61CB, 0xC0B7, 0x61CC, 0xE97D, 0x61CD, 0xBECF,
+	0x61D6, 0xEFCF, 0x61D8, 0xEFC7, 0x61DE, 0xECE7, 0x61DF, 0xEFC8,
+	0x61E0, 0xECE3, 0x61E3, 0xC256, 0x61E4, 0xECE5, 0x61E5, 0xECE4,
+	0x61E6, 0xC0B6, 0x61E7, 0xECE2, 0x61E8, 0xECE6, 0x61E9, 0xEFD0,
+	0x61EA, 0xEFCC, 0x61EB, 0xEFCE, 0x61ED, 0xEFC9, 0x61EE, 0xEFCA,
+	0x61F0, 0xEFCD, 0x61F1, 0xEFCB, 0x61F2, 0xC367, 0x61F5, 0xC36A,
+	0x61F6, 0xC369, 0x61F7, 0xC368, 0x61F8, 0xC461, 0x61F9, 0xF44A,
+	0x61FA, 0xC462, 0x61FB, 0xF241, 0x61FC, 0xC4DF, 0x61FD, 0xF5CC,
+	0x61FE, 0xC4E0, 0x61FF, 0xC574, 0x6200, 0xC5CA, 0x6201, 0xF7D9,
+	0x6203, 0xF7DA, 0x6204, 0xF7DB, 0x6207, 0xF9BA, 0x6208, 0xA4E0,
+	0x6209, 0xC97C, 0x620A, 0xA5B3, 0x620C, 0xA6A6, 0x620D, 0xA6A7,
+	0x620E, 0xA6A5, 0x6210, 0xA6A8, 0x6211, 0xA7DA, 0x6212, 0xA7D9,
+	0x6214, 0xCCB1, 0x6215, 0xA9CF, 0x6216, 0xA9CE, 0x6219, 0xD1AF,
+	0x621A, 0xB1AD, 0x621B, 0xB1AE, 0x621F, 0xB475, 0x6220, 0xDD72,
+	0x6221, 0xB760, 0x6222, 0xB761, 0x6223, 0xDD74, 0x6224, 0xDD76,
+	0x6225, 0xDD75, 0x6227, 0xE1D7, 0x6229, 0xE1D6, 0x622A, 0xBA49,
+	0x622B, 0xE1D8, 0x622D, 0xE5AC, 0x622E, 0xBCAE, 0x6230, 0xBED4,
+	0x6232, 0xC0B8, 0x6233, 0xC257, 0x6234, 0xC0B9, 0x6236, 0xA4E1,
+	0x623A, 0xCAE6, 0x623D, 0xCCB2, 0x623E, 0xA9D1, 0x623F, 0xA9D0,
+	0x6240, 0xA9D2, 0x6241, 0xABF3, 0x6242, 0xCED2, 0x6243, 0xCED3,
+	0x6246, 0xD1B0, 0x6247, 0xAEB0, 0x6248, 0xB1AF, 0x6249, 0xB476,
+	0x624A, 0xD951, 0x624B, 0xA4E2, 0x624D, 0xA47E, 0x624E, 0xA4E3,
+	0x6250, 0xC97D, 0x6251, 0xA5B7, 0x6252, 0xA5B6, 0x6253, 0xA5B4,
+	0x6254, 0xA5B5, 0x6258, 0xA6AB, 0x6259, 0xC9E9, 0x625A, 0xC9EB,
+	0x625B, 0xA6AA, 0x625C, 0xC9E3, 0x625E, 0xC9E4, 0x6260, 0xC9EA,
+	0x6261, 0xC9E6, 0x6262, 0xC9E8, 0x6263, 0xA6A9, 0x6264, 0xC9E5,
+	0x6265, 0xC9EC, 0x6266, 0xC9E7, 0x626D, 0xA7E1, 0x626E, 0xA7EA,
+	0x626F, 0xA7E8, 0x6270, 0xCAF0, 0x6271, 0xCAED, 0x6272, 0xCAF5,
+	0x6273, 0xA7E6, 0x6274, 0xCAF6, 0x6276, 0xA7DF, 0x6277, 0xCAF3,
+	0x6279, 0xA7E5, 0x627A, 0xCAEF, 0x627B, 0xCAEE, 0x627C, 0xA7E3,
+	0x627D, 0xCAF4, 0x627E, 0xA7E4, 0x627F, 0xA9D3, 0x6280, 0xA7DE,
+	0x6281, 0xCAF1, 0x6283, 0xCAE7, 0x6284, 0xA7DB, 0x6286, 0xA7EE,
+	0x6287, 0xCAEC, 0x6288, 0xCAF2, 0x6289, 0xA7E0, 0x628A, 0xA7E2,
+	0x628C, 0xCAE8, 0x628E, 0xCAE9, 0x628F, 0xCAEA, 0x6291, 0xA7ED,
+	0x6292, 0xA7E7, 0x6293, 0xA7EC, 0x6294, 0xCAEB, 0x6295, 0xA7EB,
+	0x6296, 0xA7DD, 0x6297, 0xA7DC, 0x6298, 0xA7E9, 0x62A8, 0xA9E1,
+	0x62A9, 0xCCBE, 0x62AA, 0xCCB7, 0x62AB, 0xA9DC, 0x62AC, 0xA9EF,
+	0x62AD, 0xCCB3, 0x62AE, 0xCCBA, 0x62AF, 0xCCBC, 0x62B0, 0xCCBF,
+	0x62B1, 0xA9EA, 0x62B3, 0xCCBB, 0x62B4, 0xCCB4, 0x62B5, 0xA9E8,
+	0x62B6, 0xCCB8, 0x62B8, 0xCCC0, 0x62B9, 0xA9D9, 0x62BB, 0xCCBD,
+	0x62BC, 0xA9E3, 0x62BD, 0xA9E2, 0x62BE, 0xCCB6, 0x62BF, 0xA9D7,
+	0x62C2, 0xA9D8, 0x62C4, 0xA9D6, 0x62C6, 0xA9EE, 0x62C7, 0xA9E6,
+	0x62C8, 0xA9E0, 0x62C9, 0xA9D4, 0x62CA, 0xCCB9, 0x62CB, 0xA9DF,
+	0x62CC, 0xA9D5, 0x62CD, 0xA9E7, 0x62CE, 0xA9F0, 0x62CF, 0xCED4,
+	0x62D0, 0xA9E4, 0x62D1, 0xCCB5, 0x62D2, 0xA9DA, 0x62D3, 0xA9DD,
+	0x62D4, 0xA9DE, 0x62D6, 0xA9EC, 0x62D7, 0xA9ED, 0x62D8, 0xA9EB,
+	0x62D9, 0xA9E5, 0x62DA, 0xA9E9, 0x62DB, 0xA9DB, 0x62DC, 0xABF4,
+	0x62EB, 0xCEDA, 0x62EC, 0xAC41, 0x62ED, 0xABF8, 0x62EE, 0xABFA,
+	0x62EF, 0xAC40, 0x62F0, 0xCEE6, 0x62F1, 0xABFD, 0x62F2, 0xD1B1,
+	0x62F3, 0xAEB1, 0x62F4, 0xAC43, 0x62F5, 0xCED7, 0x62F6, 0xCEDF,
+	0x62F7, 0xABFE, 0x62F8, 0xCEDE, 0x62F9, 0xCEDB, 0x62FA, 0xCEE3,
+	0x62FB, 0xCEE5, 0x62FC, 0xABF7, 0x62FD, 0xABFB, 0x62FE, 0xAC42,
+	0x62FF, 0xAEB3, 0x6300, 0xCEE0, 0x6301, 0xABF9, 0x6302, 0xAC45,
+	0x6303, 0xCED9, 0x6307, 0xABFC, 0x6308, 0xAEB2, 0x6309, 0xABF6,
+	0x630B, 0xCED6, 0x630C, 0xCEDD, 0x630D, 0xCED5, 0x630E, 0xCED8,
+	0x630F, 0xCEDC, 0x6310, 0xD1B2, 0x6311, 0xAC44, 0x6313, 0xCEE1,
+	0x6314, 0xCEE2, 0x6315, 0xCEE4, 0x6316, 0xABF5, 0x6328, 0xAEC1,
+	0x6329, 0xD1BE, 0x632A, 0xAEBF, 0x632B, 0xAEC0, 0x632C, 0xD1B4,
+	0x632D, 0xD1C4, 0x632F, 0xAEB6, 0x6332, 0xD566, 0x6333, 0xD1C6,
+	0x6334, 0xD1C0, 0x6336, 0xD1B7, 0x6338, 0xD1C9, 0x6339, 0xD1BA,
+	0x633A, 0xAEBC, 0x633B, 0xD57D, 0x633C, 0xD1BD, 0x633D, 0xAEBE,
+	0x633E, 0xAEB5, 0x6340, 0xD1CB, 0x6341, 0xD1BF, 0x6342, 0xAEB8,
+	0x6343, 0xD1B8, 0x6344, 0xD1B5, 0x6345, 0xD1B6, 0x6346, 0xAEB9,
+	0x6347, 0xD1C5, 0x6348, 0xD1CC, 0x6349, 0xAEBB, 0x634A, 0xD1BC,
+	0x634B, 0xD1BB, 0x634C, 0xAEC3, 0x634D, 0xAEC2, 0x634E, 0xAEB4,
+	0x634F, 0xAEBA, 0x6350, 0xAEBD, 0x6351, 0xD1C8, 0x6354, 0xD1C2,
+	0x6355, 0xAEB7, 0x6356, 0xD1B3, 0x6357, 0xD1CA, 0x6358, 0xD1C1,
+	0x6359, 0xD1C3, 0x635A, 0xD1C7, 0x6365, 0xD567, 0x6367, 0xB1B7,
+	0x6368, 0xB1CB, 0x6369, 0xB1CA, 0x636B, 0xB1BF, 0x636D, 0xD579,
+	0x636E, 0xD575, 0x636F, 0xD572, 0x6370, 0xD5A6, 0x6371, 0xB1BA,
+	0x6372, 0xB1B2, 0x6375, 0xD577, 0x6376, 0xB4A8, 0x6377, 0xB1B6,
+	0x6378, 0xD5A1, 0x637A, 0xB1CC, 0x637B, 0xB1C9, 0x637C, 0xD57B,
+	0x637D, 0xD56A, 0x6380, 0xB1C8, 0x6381, 0xD5A3, 0x6382, 0xD569,
+	0x6383, 0xB1BD, 0x6384, 0xB1C1, 0x6385, 0xD5A2, 0x6387, 0xD573,
+	0x6388, 0xB1C2, 0x6389, 0xB1BC, 0x638A, 0xD568, 0x638C, 0xB478,
+	0x638D, 0xD5A5, 0x638E, 0xD571, 0x638F, 0xB1C7, 0x6390, 0xD574,
+	0x6391, 0xD5A4, 0x6392, 0xB1C6, 0x6394, 0xD952, 0x6396, 0xB1B3,
+	0x6397, 0xD56F, 0x6398, 0xB1B8, 0x6399, 0xB1C3, 0x639B, 0xB1BE,
+	0x639C, 0xD578, 0x639D, 0xD56E, 0x639E, 0xD56C, 0x639F, 0xD57E,
+	0x63A0, 0xB1B0, 0x63A1, 0xB1C4, 0x63A2, 0xB1B4, 0x63A3, 0xB477,
+	0x63A4, 0xD57C, 0x63A5, 0xB1B5, 0x63A7, 0xB1B1, 0x63A8, 0xB1C0,
+	0x63A9, 0xB1BB, 0x63AA, 0xB1B9, 0x63AB, 0xD570, 0x63AC, 0xB1C5,
+	0x63AD, 0xD56D, 0x63AE, 0xD57A, 0x63AF, 0xD576, 0x63B0, 0xD954,
+	0x63B1, 0xD953, 0x63BD, 0xD56B, 0x63BE, 0xD964, 0x63C0, 0xB47A,
+	0x63C2, 0xD96A, 0x63C3, 0xD959, 0x63C4, 0xD967, 0x63C5, 0xDD77,
+	0x63C6, 0xB47D, 0x63C7, 0xD96B, 0x63C8, 0xD96E, 0x63C9, 0xB47C,
+	0x63CA, 0xD95C, 0x63CB, 0xD96D, 0x63CC, 0xD96C, 0x63CD, 0xB47E,
+	0x63CE, 0xD955, 0x63CF, 0xB479, 0x63D0, 0xB4A3, 0x63D2, 0xB4A1,
+	0x63D3, 0xD969, 0x63D5, 0xD95F, 0x63D6, 0xB4A5, 0x63D7, 0xD970,
+	0x63D8, 0xD968, 0x63D9, 0xD971, 0x63DA, 0xB4AD, 0x63DB, 0xB4AB,
+	0x63DC, 0xD966, 0x63DD, 0xD965, 0x63DF, 0xD963, 0x63E0, 0xD95D,
+	0x63E1, 0xB4A4, 0x63E3, 0xB4A2, 0x63E4, 0xD1B9, 0x63E5, 0xD956,
+	0x63E7, 0xDDB7, 0x63E8, 0xD957, 0x63E9, 0xB47B, 0x63EA, 0xB4AA,
+	0x63EB, 0xDD79, 0x63ED, 0xB4A6, 0x63EE, 0xB4A7, 0x63EF, 0xD958,
+	0x63F0, 0xD96F, 0x63F1, 0xDD78, 0x63F2, 0xD960, 0x63F3, 0xD95B,
+	0x63F4, 0xB4A9, 0x63F5, 0xD961, 0x63F6, 0xD95E, 0x63F9, 0xB4AE,
+	0x6406, 0xB770, 0x6409, 0xDD7C, 0x640A, 0xDDB1, 0x640B, 0xDDB6,
+	0x640C, 0xDDAA, 0x640D, 0xB76C, 0x640E, 0xDDBB, 0x640F, 0xB769,
+	0x6410, 0xDD7A, 0x6412, 0xDD7B, 0x6413, 0xB762, 0x6414, 0xB76B,
+	0x6415, 0xDDA4, 0x6416, 0xB76E, 0x6417, 0xB76F, 0x6418, 0xDDA5,
+	0x641A, 0xDDB2, 0x641B, 0xDDB8, 0x641C, 0xB76A, 0x641E, 0xB764,
+	0x641F, 0xDDA3, 0x6420, 0xDD7D, 0x6421, 0xDDBA, 0x6422, 0xDDA8,
+	0x6423, 0xDDA9, 0x6424, 0xDD7E, 0x6425, 0xDDB4, 0x6426, 0xDDAB,
+	0x6427, 0xDDB5, 0x6428, 0xDDAD, 0x642A, 0xB765, 0x642B, 0xE1D9,
+	0x642C, 0xB768, 0x642D, 0xB766, 0x642E, 0xDDB9, 0x642F, 0xDDB0,
+	0x6430, 0xDDAC, 0x6433, 0xDDA1, 0x6434, 0xBA53, 0x6435, 0xDDAF,
+	0x6436, 0xB76D, 0x6437, 0xDDA7, 0x6439, 0xDDA6, 0x643D, 0xB767,
+	0x643E, 0xB763, 0x643F, 0xE1EE, 0x6440, 0xDDB3, 0x6441, 0xDDAE,
+	0x6443, 0xDDA2, 0x644B, 0xE1E9, 0x644D, 0xE1DA, 0x644E, 0xE1E5,
+	0x6450, 0xE1EC, 0x6451, 0xBA51, 0x6452, 0xB4AC, 0x6453, 0xE1EA,
+	0x6454, 0xBA4C, 0x6458, 0xBA4B, 0x6459, 0xE1F1, 0x645B, 0xE1DB,
+	0x645C, 0xE1E8, 0x645D, 0xE1DC, 0x645E, 0xE1E7, 0x645F, 0xBA4F,
+	0x6460, 0xE1EB, 0x6461, 0xD962, 0x6465, 0xE1F2, 0x6466, 0xE1E3,
+	0x6467, 0xBA52, 0x6468, 0xE5BA, 0x6469, 0xBCAF, 0x646B, 0xE1F0,
+	0x646C, 0xE1EF, 0x646D, 0xBA54, 0x646E, 0xE5AD, 0x646F, 0xBCB0,
+	0x6470, 0xE5AE, 0x6472, 0xE1DF, 0x6473, 0xE1E0, 0x6474, 0xE1DD,
+	0x6475, 0xE1E2, 0x6476, 0xE1DE, 0x6477, 0xE1F3, 0x6478, 0xBA4E,
+	0x6479, 0xBCB1, 0x647A, 0xBA50, 0x647B, 0xBA55, 0x647D, 0xE1E1,
+	0x647F, 0xE1ED, 0x6482, 0xE1E6, 0x6485, 0xE5B1, 0x6487, 0xBA4A,
+	0x6488, 0xBCB4, 0x6489, 0xE9AA, 0x648A, 0xE5B6, 0x648B, 0xE5B5,
+	0x648C, 0xE5B7, 0x648F, 0xE5B4, 0x6490, 0xBCB5, 0x6492, 0xBCBB,
+	0x6493, 0xBCB8, 0x6495, 0xBCB9, 0x6496, 0xE5AF, 0x6497, 0xE5B2,
+	0x6498, 0xE5BC, 0x6499, 0xBCC1, 0x649A, 0xBCBF, 0x649C, 0xE5B3,
+	0x649D, 0xD95A, 0x649E, 0xBCB2, 0x649F, 0xE5B9, 0x64A0, 0xE5B0,
+	0x64A2, 0xBCC2, 0x64A3, 0xE5B8, 0x64A4, 0xBA4D, 0x64A5, 0xBCB7,
+	0x64A6, 0xE1E4, 0x64A9, 0xBCBA, 0x64AB, 0xBCBE, 0x64AC, 0xBCC0,
+	0x64AD, 0xBCBD, 0x64AE, 0xBCBC, 0x64B0, 0xBCB6, 0x64B1, 0xE5BB,
+	0x64B2, 0xBCB3, 0x64B3, 0xBCC3, 0x64BB, 0xBED8, 0x64BC, 0xBED9,
+	0x64BD, 0xE9A9, 0x64BE, 0xBEE2, 0x64BF, 0xBEDF, 0x64C1, 0xBED6,
+	0x64C2, 0xBEDD, 0x64C3, 0xE9AB, 0x64C4, 0xBEDB, 0x64C5, 0xBED5,
+	0x64C7, 0xBEDC, 0x64C9, 0xE9A8, 0x64CA, 0xC0BB, 0x64CB, 0xBED7,
+	0x64CD, 0xBEDE, 0x64CE, 0xC0BA, 0x64CF, 0xE9A7, 0x64D0, 0xE9A6,
+	0x64D2, 0xBEE0, 0x64D4, 0xBEE1, 0x64D6, 0xE9A5, 0x64D7, 0xE9A4,
+	0x64D8, 0xC0BC, 0x64D9, 0xE9AE, 0x64DA, 0xBEDA, 0x64DB, 0xE9AC,
+	0x64E0, 0xC0BD, 0x64E2, 0xC0C2, 0x64E3, 0xECEA, 0x64E4, 0xECEC,
+	0x64E6, 0xC0BF, 0x64E8, 0xECED, 0x64E9, 0xECE9, 0x64EB, 0xECEB,
+	0x64EC, 0xC0C0, 0x64ED, 0xC0C3, 0x64EF, 0xECE8, 0x64F0, 0xC0BE,
+	0x64F1, 0xC0C1, 0x64F2, 0xC259, 0x64F3, 0xE9AD, 0x64F4, 0xC258,
+	0x64F7, 0xC25E, 0x64F8, 0xEFD4, 0x64FA, 0xC25C, 0x64FB, 0xC25D,
+	0x64FC, 0xEFD7, 0x64FD, 0xEFD3, 0x64FE, 0xC25A, 0x64FF, 0xEFD1,
+	0x6500, 0xC36B, 0x6501, 0xEFD5, 0x6503, 0xEFD6, 0x6504, 0xEFD2,
+	0x6506, 0xC25B, 0x6507, 0xF242, 0x6509, 0xF245, 0x650C, 0xF246,
+	0x650D, 0xF244, 0x650E, 0xF247, 0x650F, 0xC36C, 0x6510, 0xF243,
+	0x6513, 0xF44E, 0x6514, 0xC464, 0x6515, 0xF44D, 0x6516, 0xF44C,
+	0x6517, 0xF44B, 0x6518, 0xC463, 0x6519, 0xC465, 0x651B, 0xF5CD,
+	0x651C, 0xC4E2, 0x651D, 0xC4E1, 0x6520, 0xF6E1, 0x6521, 0xF6E0,
+	0x6522, 0xF6E3, 0x6523, 0xC5CB, 0x6524, 0xC575, 0x6525, 0xF7DD,
+	0x6526, 0xF6E2, 0x6529, 0xF7DC, 0x652A, 0xC5CD, 0x652B, 0xC5CC,
+	0x652C, 0xC5F3, 0x652D, 0xF8A9, 0x652E, 0xF8EF, 0x652F, 0xA4E4,
+	0x6532, 0xD972, 0x6533, 0xE9AF, 0x6536, 0xA6AC, 0x6537, 0xCAF7,
+	0x6538, 0xA7F1, 0x6539, 0xA7EF, 0x653B, 0xA7F0, 0x653D, 0xCCC1,
+	0x653E, 0xA9F1, 0x653F, 0xAC46, 0x6541, 0xCEE7, 0x6543, 0xCEE8,
+	0x6545, 0xAC47, 0x6546, 0xD1CE, 0x6548, 0xAEC4, 0x6549, 0xAEC5,
+	0x654A, 0xD1CD, 0x654F, 0xB1D3, 0x6551, 0xB1CF, 0x6553, 0xD5A7,
+	0x6554, 0xB1D6, 0x6555, 0xB1D5, 0x6556, 0xB1CE, 0x6557, 0xB1D1,
+	0x6558, 0xB1D4, 0x6559, 0xB1D0, 0x655C, 0xD976, 0x655D, 0xB1CD,
+	0x655E, 0xB4AF, 0x6562, 0xB4B1, 0x6563, 0xB4B2, 0x6564, 0xD975,
+	0x6565, 0xD978, 0x6566, 0xB4B0, 0x6567, 0xD973, 0x6568, 0xD977,
+	0x656A, 0xD974, 0x656C, 0xB771, 0x656F, 0xDDBC, 0x6572, 0xBA56,
+	0x6573, 0xE1F4, 0x6574, 0xBEE3, 0x6575, 0xBCC4, 0x6576, 0xE5BD,
+	0x6577, 0xBCC5, 0x6578, 0xBCC6, 0x6579, 0xE5BF, 0x657A, 0xE5BE,
+	0x657B, 0xE5C0, 0x657C, 0xE9B1, 0x657F, 0xE9B0, 0x6580, 0xECEF,
+	0x6581, 0xECEE, 0x6582, 0xC0C4, 0x6583, 0xC0C5, 0x6584, 0xF248,
+	0x6587, 0xA4E5, 0x658C, 0xD979, 0x6590, 0xB4B4, 0x6591, 0xB4B3,
+	0x6592, 0xDDBD, 0x6594, 0xEFD8, 0x6595, 0xC4E3, 0x6596, 0xF7DE,
+	0x6597, 0xA4E6, 0x6599, 0xAEC6, 0x659B, 0xB1D8, 0x659C, 0xB1D7,
+	0x659D, 0xD97A, 0x659E, 0xD97B, 0x659F, 0xB772, 0x65A0, 0xE1F5,
+	0x65A1, 0xBA57, 0x65A2, 0xE9B2, 0x65A4, 0xA4E7, 0x65A5, 0xA5B8,
+	0x65A7, 0xA9F2, 0x65A8, 0xCCC2, 0x65AA, 0xCEE9, 0x65AB, 0xAC48,
+	0x65AC, 0xB1D9, 0x65AE, 0xD97C, 0x65AF, 0xB4B5, 0x65B0, 0xB773,
+	0x65B2, 0xE5C1, 0x65B3, 0xE5C2, 0x65B6, 0xECF0, 0x65B7, 0xC25F,
+	0x65B8, 0xF8F0, 0x65B9, 0xA4E8, 0x65BB, 0xCCC3, 0x65BC, 0xA9F3,
+	0x65BD, 0xAC49, 0x65BF, 0xCEEA, 0x65C1, 0xAEC7, 0x65C2, 0xD1D2,
+	0x65C3, 0xD1D0, 0x65C4, 0xD1D1, 0x65C5, 0xAEC8, 0x65C6, 0xD1CF,
+	0x65CB, 0xB1DB, 0x65CC, 0xB1DC, 0x65CD, 0xD5A8, 0x65CE, 0xB1DD,
+	0x65CF, 0xB1DA, 0x65D0, 0xD97D, 0x65D2, 0xD97E, 0x65D3, 0xDDBE,
+	0x65D6, 0xBA59, 0x65D7, 0xBA58, 0x65DA, 0xECF1, 0x65DB, 0xEFD9,
+	0x65DD, 0xF24A, 0x65DE, 0xF249, 0x65DF, 0xF44F, 0x65E1, 0xC95E,
+	0x65E2, 0xAC4A, 0x65E5, 0xA4E9, 0x65E6, 0xA5B9, 0x65E8, 0xA6AE,
+	0x65E9, 0xA6AD, 0x65EC, 0xA6AF, 0x65ED, 0xA6B0, 0x65EE, 0xC9EE,
+	0x65EF, 0xC9ED, 0x65F0, 0xCAF8, 0x65F1, 0xA7F2, 0x65F2, 0xCAFB,
+	0x65F3, 0xCAFA, 0x65F4, 0xCAF9, 0x65F5, 0xCAFC, 0x65FA, 0xA9F4,
+	0x65FB, 0xCCC9, 0x65FC, 0xCCC5, 0x65FD, 0xCCCE, 0x6600, 0xA9FB,
+	0x6602, 0xA9F9, 0x6603, 0xCCCA, 0x6604, 0xCCC6, 0x6605, 0xCCCD,
+	0x6606, 0xA9F8, 0x6607, 0xAA40, 0x6608, 0xCCC8, 0x6609, 0xCCC4,
+	0x660A, 0xA9FE, 0x660B, 0xCCCB, 0x660C, 0xA9F7, 0x660D, 0xCCCC,
+	0x660E, 0xA9FA, 0x660F, 0xA9FC, 0x6610, 0xCCD0, 0x6611, 0xCCCF,
+	0x6612, 0xCCC7, 0x6613, 0xA9F6, 0x6614, 0xA9F5, 0x6615, 0xA9FD,
+	0x661C, 0xCEEF, 0x661D, 0xCEF5, 0x661F, 0xAC50, 0x6620, 0xAC4D,
+	0x6621, 0xCEEC, 0x6622, 0xCEF1, 0x6624, 0xAC53, 0x6625, 0xAC4B,
+	0x6626, 0xCEF0, 0x6627, 0xAC4E, 0x6628, 0xAC51, 0x662B, 0xCEF3,
+	0x662D, 0xAC4C, 0x662E, 0xCEF8, 0x662F, 0xAC4F, 0x6631, 0xAC52,
+	0x6632, 0xCEED, 0x6633, 0xCEF2, 0x6634, 0xCEF6, 0x6635, 0xCEEE,
+	0x6636, 0xCEEB, 0x6639, 0xCEF7, 0x663A, 0xCEF4, 0x6641, 0xAED0,
+	0x6642, 0xAEC9, 0x6643, 0xAECC, 0x6645, 0xAECF, 0x6647, 0xD1D5,
+	0x6649, 0xAECA, 0x664A, 0xD1D3, 0x664C, 0xAECE, 0x664F, 0xAECB,
+	0x6651, 0xD1D6, 0x6652, 0xAECD, 0x6659, 0xD5AC, 0x665A, 0xB1DF,
+	0x665B, 0xD5AB, 0x665C, 0xD5AD, 0x665D, 0xB1DE, 0x665E, 0xB1E3,
+	0x665F, 0xD1D4, 0x6661, 0xD5AA, 0x6662, 0xD5AE, 0x6664, 0xB1E0,
+	0x6665, 0xD5A9, 0x6666, 0xB1E2, 0x6668, 0xB1E1, 0x666A, 0xD9A7,
+	0x666C, 0xD9A2, 0x666E, 0xB4B6, 0x666F, 0xB4BA, 0x6670, 0xB4B7,
+	0x6671, 0xD9A5, 0x6672, 0xD9A8, 0x6674, 0xB4B8, 0x6676, 0xB4B9,
+	0x6677, 0xB4BE, 0x6678, 0xDDC7, 0x6679, 0xD9A6, 0x667A, 0xB4BC,
+	0x667B, 0xD9A3, 0x667C, 0xD9A1, 0x667E, 0xB4BD, 0x6680, 0xD9A4,
+	0x6684, 0xB779, 0x6686, 0xDDBF, 0x6687, 0xB776, 0x6688, 0xB777,
+	0x6689, 0xB775, 0x668A, 0xDDC4, 0x668B, 0xDDC3, 0x668C, 0xDDC0,
+	0x668D, 0xB77B, 0x6690, 0xDDC2, 0x6691, 0xB4BB, 0x6694, 0xDDC6,
+	0x6695, 0xDDC1, 0x6696, 0xB778, 0x6697, 0xB774, 0x6698, 0xB77A,
+	0x6699, 0xDDC5, 0x669D, 0xBA5C, 0x669F, 0xE1F8, 0x66A0, 0xE1F7,
+	0x66A1, 0xE1F6, 0x66A2, 0xBA5A, 0x66A8, 0xBA5B, 0x66A9, 0xE5C5,
+	0x66AA, 0xE5C8, 0x66AB, 0xBCC8, 0x66AE, 0xBCC7, 0x66AF, 0xE5C9,
+	0x66B0, 0xE5C4, 0x66B1, 0xBCCA, 0x66B2, 0xE5C6, 0x66B4, 0xBCC9,
+	0x66B5, 0xE5C3, 0x66B7, 0xE5C7, 0x66B8, 0xBEE9, 0x66B9, 0xBEE6,
+	0x66BA, 0xE9BB, 0x66BB, 0xE9BA, 0x66BD, 0xE9B9, 0x66BE, 0xE9B4,
+	0x66C0, 0xE9B5, 0x66C4, 0xBEE7, 0x66C6, 0xBEE4, 0x66C7, 0xBEE8,
+	0x66C8, 0xE9B3, 0x66C9, 0xBEE5, 0x66CA, 0xE9B6, 0x66CB, 0xE9B7,
+	0x66CC, 0xE9BC, 0x66CF, 0xE9B8, 0x66D2, 0xECF2, 0x66D6, 0xC0C7,
+	0x66D8, 0xEFDC, 0x66D9, 0xC0C6, 0x66DA, 0xEFDA, 0x66DB, 0xEFDB,
+	0x66DC, 0xC260, 0x66DD, 0xC36E, 0x66DE, 0xF24B, 0x66E0, 0xC36D,
+	0x66E3, 0xF451, 0x66E4, 0xF452, 0x66E6, 0xC466, 0x66E8, 0xF450,
+	0x66E9, 0xC4E4, 0x66EB, 0xF7DF, 0x66EC, 0xC5CE, 0x66ED, 0xF8AA,
+	0x66EE, 0xF8AB, 0x66F0, 0xA4EA, 0x66F2, 0xA6B1, 0x66F3, 0xA6B2,
+	0x66F4, 0xA7F3, 0x66F6, 0xCCD1, 0x66F7, 0xAC54, 0x66F8, 0xAED1,
+	0x66F9, 0xB1E4, 0x66FC, 0xB0D2, 0x66FE, 0xB4BF, 0x66FF, 0xB4C0,
+	0x6700, 0xB3CC, 0x6701, 0xD9A9, 0x6703, 0xB77C, 0x6704, 0xE1FA,
+	0x6705, 0xE1F9, 0x6708, 0xA4EB, 0x6709, 0xA6B3, 0x670A, 0xCCD2,
+	0x670B, 0xAA42, 0x670D, 0xAA41, 0x670F, 0xCEF9, 0x6710, 0xCEFA,
+	0x6712, 0xD1D7, 0x6713, 0xD1D8, 0x6714, 0xAED2, 0x6715, 0xAED3,
+	0x6717, 0xAED4, 0x6718, 0xD5AF, 0x671B, 0xB1E6, 0x671D, 0xB4C2,
+	0x671F, 0xB4C1, 0x6720, 0xDDC8, 0x6721, 0xDF7A, 0x6722, 0xE1FB,
+	0x6723, 0xE9BD, 0x6726, 0xC261, 0x6727, 0xC467, 0x6728, 0xA4EC,
+	0x672A, 0xA5BC, 0x672B, 0xA5BD, 0x672C, 0xA5BB, 0x672D, 0xA5BE,
+	0x672E, 0xA5BA, 0x6731, 0xA6B6, 0x6733, 0xC9F6, 0x6734, 0xA6B5,
+	0x6735, 0xA6B7, 0x6738, 0xC9F1, 0x6739, 0xC9F0, 0x673A, 0xC9F3,
+	0x673B, 0xC9F2, 0x673C, 0xC9F5, 0x673D, 0xA6B4, 0x673E, 0xC9EF,
+	0x673F, 0xC9F4, 0x6745, 0xCAFD, 0x6746, 0xA7FD, 0x6747, 0xCAFE,
+	0x6748, 0xCB43, 0x6749, 0xA7FC, 0x674B, 0xCB47, 0x674C, 0xCB42,
+	0x674D, 0xCB45, 0x674E, 0xA7F5, 0x674F, 0xA7F6, 0x6750, 0xA7F7,
+	0x6751, 0xA7F8, 0x6753, 0xA840, 0x6755, 0xCB41, 0x6756, 0xA7FA,
+	0x6757, 0xA841, 0x6759, 0xCB40, 0x675A, 0xCB46, 0x675C, 0xA7F9,
+	0x675D, 0xCB44, 0x675E, 0xA7FB, 0x675F, 0xA7F4, 0x6760, 0xA7FE,
+	0x676A, 0xAA57, 0x676C, 0xCCD4, 0x676D, 0xAA43, 0x676F, 0xAA4D,
+	0x6770, 0xAA4E, 0x6771, 0xAA46, 0x6772, 0xAA58, 0x6773, 0xAA48,
+	0x6774, 0xCCDC, 0x6775, 0xAA53, 0x6776, 0xCCD7, 0x6777, 0xAA49,
+	0x6778, 0xCCE6, 0x6779, 0xCCE7, 0x677A, 0xCCDF, 0x677B, 0xCCD8,
+	0x677C, 0xAA56, 0x677D, 0xCCE4, 0x677E, 0xAA51, 0x677F, 0xAA4F,
+	0x6781, 0xCCE5, 0x6783, 0xCCE3, 0x6784, 0xCCDB, 0x6785, 0xCCD3,
+	0x6786, 0xCCDA, 0x6787, 0xAA4A, 0x6789, 0xAA50, 0x678B, 0xAA44,
+	0x678C, 0xCCDE, 0x678D, 0xCCDD, 0x678E, 0xCCD5, 0x6790, 0xAA52,
+	0x6791, 0xCCE1, 0x6792, 0xCCD6, 0x6793, 0xAA55, 0x6794, 0xCCE8,
+	0x6795, 0xAA45, 0x6797, 0xAA4C, 0x6798, 0xCCD9, 0x6799, 0xCCE2,
+	0x679A, 0xAA54, 0x679C, 0xAA47, 0x679D, 0xAA4B, 0x679F, 0xCCE0,
+	0x67AE, 0xCF5B, 0x67AF, 0xAC5C, 0x67B0, 0xAC69, 0x67B2, 0xCF56,
+	0x67B3, 0xCF4C, 0x67B4, 0xAC62, 0x67B5, 0xCF4A, 0x67B6, 0xAC5B,
+	0x67B7, 0xCF45, 0x67B8, 0xAC65, 0x67B9, 0xCF52, 0x67BA, 0xCEFE,
+	0x67BB, 0xCF41, 0x67C0, 0xCF44, 0x67C1, 0xCEFB, 0x67C2, 0xCF51,
+	0x67C3, 0xCF61, 0x67C4, 0xAC60, 0x67C5, 0xCF46, 0x67C6, 0xCF58,
+	0x67C8, 0xCEFD, 0x67C9, 0xCF5F, 0x67CA, 0xCF60, 0x67CB, 0xCF63,
+	0x67CC, 0xCF5A, 0x67CD, 0xCF4B, 0x67CE, 0xCF53, 0x67CF, 0xAC66,
+	0x67D0, 0xAC59, 0x67D1, 0xAC61, 0x67D2, 0xAC6D, 0x67D3, 0xAC56,
+	0x67D4, 0xAC58, 0x67D8, 0xCF43, 0x67D9, 0xAC6A, 0x67DA, 0xAC63,
+	0x67DB, 0xCF5D, 0x67DC, 0xCF40, 0x67DD, 0xAC6C, 0x67DE, 0xAC67,
+	0x67DF, 0xCF49, 0x67E2, 0xAC6B, 0x67E3, 0xCF50, 0x67E4, 0xCF48,
+	0x67E5, 0xAC64, 0x67E6, 0xCF5C, 0x67E7, 0xCF54, 0x67E9, 0xAC5E,
+	0x67EA, 0xCF62, 0x67EB, 0xCF47, 0x67EC, 0xAC5A, 0x67ED, 0xCF59,
+	0x67EE, 0xCF4F, 0x67EF, 0xAC5F, 0x67F0, 0xCF55, 0x67F1, 0xAC57,
+	0x67F2, 0xCEFC, 0x67F3, 0xAC68, 0x67F4, 0xAEE3, 0x67F5, 0xAC5D,
+	0x67F6, 0xCF4E, 0x67F7, 0xCF4D, 0x67F8, 0xCF42, 0x67FA, 0xCF5E,
+	0x67FC, 0xCF57, 0x67FF, 0xAC55, 0x6812, 0xD1EC, 0x6813, 0xAEEA,
+	0x6814, 0xD1ED, 0x6816, 0xD1E1, 0x6817, 0xAEDF, 0x6818, 0xAEEB,
+	0x681A, 0xD1DA, 0x681C, 0xD1E3, 0x681D, 0xD1EB, 0x681F, 0xD1D9,
+	0x6820, 0xD1F4, 0x6821, 0xAED5, 0x6825, 0xD1F3, 0x6826, 0xD1EE,
+	0x6828, 0xD1EF, 0x6829, 0xAEDD, 0x682A, 0xAEE8, 0x682B, 0xD1E5,
+	0x682D, 0xD1E6, 0x682E, 0xD1F0, 0x682F, 0xD1E7, 0x6831, 0xD1E2,
+	0x6832, 0xD1DC, 0x6833, 0xD1DD, 0x6834, 0xD1EA, 0x6835, 0xD1E4,
+	0x6838, 0xAED6, 0x6839, 0xAEDA, 0x683A, 0xD1F2, 0x683B, 0xD1DE,
+	0x683C, 0xAEE6, 0x683D, 0xAEE2, 0x6840, 0xAEE5, 0x6841, 0xAEEC,
+	0x6842, 0xAEDB, 0x6843, 0xAEE7, 0x6844, 0xD1E9, 0x6845, 0xAEE9,
+	0x6846, 0xAED8, 0x6848, 0xAED7, 0x6849, 0xD1DB, 0x684B, 0xD1DF,
+	0x684C, 0xAEE0, 0x684D, 0xD1F1, 0x684E, 0xD1E8, 0x684F, 0xD1E0,
+	0x6850, 0xAEE4, 0x6851, 0xAEE1, 0x6853, 0xAED9, 0x6854, 0xAEDC,
+	0x686B, 0xD5C4, 0x686D, 0xD5B4, 0x686E, 0xD5B5, 0x686F, 0xD5B9,
+	0x6871, 0xD5C8, 0x6872, 0xD5C5, 0x6874, 0xD5BE, 0x6875, 0xD5BD,
+	0x6876, 0xB1ED, 0x6877, 0xD5C1, 0x6878, 0xD5D0, 0x6879, 0xD5B0,
+	0x687B, 0xD5D1, 0x687C, 0xD5C3, 0x687D, 0xD5D5, 0x687E, 0xD5C9,
+	0x687F, 0xB1EC, 0x6880, 0xD5C7, 0x6881, 0xB1E7, 0x6882, 0xB1FC,
+	0x6883, 0xB1F2, 0x6885, 0xB1F6, 0x6886, 0xB1F5, 0x6887, 0xD5B1,
+	0x6889, 0xD5CE, 0x688A, 0xD5D4, 0x688B, 0xD5CC, 0x688C, 0xD5D3,
+	0x688F, 0xD5C0, 0x6890, 0xD5B2, 0x6891, 0xD5D2, 0x6892, 0xD5C2,
+	0x6893, 0xB1EA, 0x6894, 0xB1F7, 0x6896, 0xD5CB, 0x6897, 0xB1F0,
+	0x689B, 0xD5CA, 0x689C, 0xD5B3, 0x689D, 0xB1F8, 0x689F, 0xB1FA,
+	0x68A0, 0xD5CD, 0x68A1, 0xB1FB, 0x68A2, 0xB1E9, 0x68A3, 0xD5BA,
+	0x68A4, 0xD5CF, 0x68A7, 0xB1EF, 0x68A8, 0xB1F9, 0x68A9, 0xD5BC,
+	0x68AA, 0xD5C6, 0x68AB, 0xD5B7, 0x68AC, 0xD5BB, 0x68AD, 0xB1F4,
+	0x68AE, 0xD5B6, 0x68AF, 0xB1E8, 0x68B0, 0xB1F1, 0x68B1, 0xB1EE,
+	0x68B2, 0xD5BF, 0x68B3, 0xAEDE, 0x68B4, 0xD9C0, 0x68B5, 0xB1EB,
+	0x68C4, 0xB1F3, 0x68C6, 0xD9C3, 0x68C7, 0xD9D9, 0x68C8, 0xD9CE,
+	0x68C9, 0xB4D6, 0x68CB, 0xB4D1, 0x68CC, 0xD9BD, 0x68CD, 0xB4D2,
+	0x68CE, 0xD9CD, 0x68D0, 0xD9C6, 0x68D1, 0xD9D3, 0x68D2, 0xB4CE,
+	0x68D3, 0xD9AB, 0x68D4, 0xD9D5, 0x68D5, 0xB4C4, 0x68D6, 0xD9B3,
+	0x68D7, 0xB4C7, 0x68D8, 0xB4C6, 0x68DA, 0xB4D7, 0x68DC, 0xD9AD,
+	0x68DD, 0xD9CF, 0x68DE, 0xD9D0, 0x68DF, 0xB4C9, 0x68E0, 0xB4C5,
+	0x68E1, 0xD9BB, 0x68E3, 0xB4D0, 0x68E4, 0xD9B6, 0x68E6, 0xD9D1,
+	0x68E7, 0xB4CC, 0x68E8, 0xD9C9, 0x68E9, 0xD9D6, 0x68EA, 0xD9B0,
+	0x68EB, 0xD9B5, 0x68EC, 0xD9AF, 0x68EE, 0xB4CB, 0x68EF, 0xD9C2,
+	0x68F0, 0xDDDE, 0x68F1, 0xD9B1, 0x68F2, 0xB4CF, 0x68F3, 0xD9BA,
+	0x68F4, 0xD9D2, 0x68F5, 0xB4CA, 0x68F6, 0xD9B7, 0x68F7, 0xD9B4,
+	0x68F8, 0xD9C5, 0x68F9, 0xB4CD, 0x68FA, 0xB4C3, 0x68FB, 0xB4D9,
+	0x68FC, 0xD9C8, 0x68FD, 0xD9C7, 0x6904, 0xD9AC, 0x6905, 0xB4C8,
+	0x6906, 0xD9D4, 0x6907, 0xD9BC, 0x6908, 0xD9BE, 0x690A, 0xD9CB,
+	0x690B, 0xD9CA, 0x690C, 0xD9AA, 0x690D, 0xB4D3, 0x690E, 0xB4D5,
+	0x690F, 0xD9B2, 0x6910, 0xD9B9, 0x6911, 0xD9C1, 0x6912, 0xB4D4,
+	0x6913, 0xD9B8, 0x6914, 0xD9C4, 0x6915, 0xD9D7, 0x6917, 0xD9CC,
+	0x6925, 0xD9D8, 0x692A, 0xD9AE, 0x692F, 0xDDF2, 0x6930, 0xB7A6,
+	0x6932, 0xDDF0, 0x6933, 0xDDDB, 0x6934, 0xDDE0, 0x6935, 0xDDD9,
+	0x6937, 0xDDEC, 0x6938, 0xDDCB, 0x6939, 0xDDD2, 0x693B, 0xDDEA,
+	0x693C, 0xDDF4, 0x693D, 0xDDDC, 0x693F, 0xDDCF, 0x6940, 0xDDE2,
+	0x6941, 0xDDE7, 0x6942, 0xDDD3, 0x6944, 0xDDE4, 0x6945, 0xDDD0,
+	0x6948, 0xDDD7, 0x6949, 0xDDD8, 0x694A, 0xB7A8, 0x694B, 0xDDEB,
+	0x694C, 0xDDE9, 0x694E, 0xDDCC, 0x694F, 0xDDEE, 0x6951, 0xDDEF,
+	0x6952, 0xDDF1, 0x6953, 0xB7AC, 0x6954, 0xB7A4, 0x6956, 0xD5B8,
+	0x6957, 0xDDD4, 0x6958, 0xDDE6, 0x6959, 0xDDD5, 0x695A, 0xB7A1,
+	0x695B, 0xB7B1, 0x695C, 0xDDED, 0x695D, 0xB7AF, 0x695E, 0xB7AB,
+	0x695F, 0xDDCA, 0x6960, 0xB7A3, 0x6962, 0xDDCD, 0x6963, 0xB7B0,
+	0x6965, 0xDDDD, 0x6966, 0xDDC9, 0x6968, 0xB7A9, 0x6969, 0xDDE1,
+	0x696A, 0xDDD1, 0x696B, 0xB7AA, 0x696C, 0xDDDA, 0x696D, 0xB77E,
+	0x696E, 0xB4D8, 0x696F, 0xDDE3, 0x6970, 0xD9BF, 0x6971, 0xDDCE,
+	0x6974, 0xDDE8, 0x6975, 0xB7A5, 0x6976, 0xDDE5, 0x6977, 0xB7A2,
+	0x6978, 0xDDDF, 0x6979, 0xB7AD, 0x697A, 0xDDD6, 0x697B, 0xDDF3,
+	0x6982, 0xB7A7, 0x6983, 0xDEC6, 0x6986, 0xB7AE, 0x698D, 0xE24A,
+	0x698E, 0xE248, 0x6990, 0xE25E, 0x6991, 0xE246, 0x6993, 0xE258,
+	0x6994, 0xB77D, 0x6995, 0xBA5F, 0x6996, 0xE242, 0x6997, 0xE25D,
+	0x6999, 0xE247, 0x699A, 0xE255, 0x699B, 0xBA64, 0x699C, 0xBA5D,
+	0x699E, 0xE25B, 0x69A0, 0xE240, 0x69A1, 0xE25A, 0x69A3, 0xBA6F,
+	0x69A4, 0xE251, 0x69A5, 0xE261, 0x69A6, 0xBA6D, 0x69A7, 0xE249,
+	0x69A8, 0xBA5E, 0x69A9, 0xE24B, 0x69AA, 0xE259, 0x69AB, 0xBA67,
+	0x69AC, 0xE244, 0x69AD, 0xBA6B, 0x69AE, 0xBA61, 0x69AF, 0xE24D,
+	0x69B0, 0xE243, 0x69B1, 0xE1FC, 0x69B3, 0xE257, 0x69B4, 0xBA68,
+	0x69B5, 0xE260, 0x69B6, 0xE1FD, 0x69B7, 0xBA65, 0x69B9, 0xE253,
+	0x69BB, 0xBA66, 0x69BC, 0xE245, 0x69BD, 0xE250, 0x69BE, 0xE24C,
+	0x69BF, 0xE24E, 0x69C1, 0xBA60, 0x69C2, 0xE25F, 0x69C3, 0xBA6E,
+	0x69C4, 0xE24F, 0x69C6, 0xE262, 0x69C9, 0xE1FE, 0x69CA, 0xE254,
+	0x69CB, 0xBA63, 0x69CC, 0xBA6C, 0x69CD, 0xBA6A, 0x69CE, 0xE241,
+	0x69CF, 0xE256, 0x69D0, 0xBA69, 0x69D3, 0xBA62, 0x69D4, 0xE252,
+	0x69D9, 0xE25C, 0x69E2, 0xE5D5, 0x69E4, 0xE5D1, 0x69E5, 0xE5CD,
+	0x69E6, 0xE5E1, 0x69E7, 0xE5DE, 0x69E8, 0xBCCD, 0x69EB, 0xE5E5,
+	0x69EC, 0xE5D4, 0x69ED, 0xBCD8, 0x69EE, 0xE5DB, 0x69F1, 0xE5D0,
+	0x69F2, 0xE5DA, 0x69F3, 0xBCD5, 0x69F4, 0xE5EE, 0x69F6, 0xE5EB,
+	0x69F7, 0xE5DD, 0x69F8, 0xE5CE, 0x69FB, 0xE5E2, 0x69FC, 0xE5E4,
+	0x69FD, 0xBCD1, 0x69FE, 0xE5D8, 0x69FF, 0xE5D3, 0x6A00, 0xE5CA,
+	0x6A01, 0xBCCE, 0x6A02, 0xBCD6, 0x6A04, 0xE5E7, 0x6A05, 0xBCD7,
+	0x6A06, 0xE5CB, 0x6A07, 0xE5ED, 0x6A08, 0xE5E0, 0x6A09, 0xE5E6,
+	0x6A0A, 0xBCD4, 0x6A0D, 0xE5E3, 0x6A0F, 0xE5EA, 0x6A11, 0xBCD9,
+	0x6A13, 0xBCD3, 0x6A14, 0xE5DC, 0x6A15, 0xE5CF, 0x6A16, 0xE5EF,
+	0x6A17, 0xE5CC, 0x6A18, 0xE5E8, 0x6A19, 0xBCD0, 0x6A1B, 0xE5D6,
+	0x6A1D, 0xE5D7, 0x6A1E, 0xBCCF, 0x6A1F, 0xBCCC, 0x6A20, 0xE5D2,
+	0x6A21, 0xBCD2, 0x6A23, 0xBCCB, 0x6A25, 0xE5E9, 0x6A26, 0xE5EC,
+	0x6A27, 0xE5D9, 0x6A28, 0xE9CA, 0x6A32, 0xE9C2, 0x6A34, 0xE9BE,
+	0x6A35, 0xBEF6, 0x6A38, 0xBEEB, 0x6A39, 0xBEF0, 0x6A3A, 0xBEEC,
+	0x6A3B, 0xE9CC, 0x6A3C, 0xE9D7, 0x6A3D, 0xBEEA, 0x6A3E, 0xE9C4,
+	0x6A3F, 0xE9CD, 0x6A40, 0xE5DF, 0x6A41, 0xE9CE, 0x6A44, 0xBEF1,
+	0x6A46, 0xE9DD, 0x6A47, 0xBEF5, 0x6A48, 0xBEF8, 0x6A49, 0xE9C0,
+	0x6A4B, 0xBEF4, 0x6A4D, 0xE9DB, 0x6A4E, 0xE9DC, 0x6A4F, 0xE9D2,
+	0x6A50, 0xE9D1, 0x6A51, 0xE9C9, 0x6A54, 0xE9D3, 0x6A55, 0xE9DA,
+	0x6A56, 0xE9D9, 0x6A58, 0xBEEF, 0x6A59, 0xBEED, 0x6A5A, 0xE9CB,
+	0x6A5B, 0xE9C8, 0x6A5D, 0xE9C5, 0x6A5E, 0xE9D8, 0x6A5F, 0xBEF7,
+	0x6A60, 0xE9D6, 0x6A61, 0xBEF3, 0x6A62, 0xBEF2, 0x6A64, 0xE9D0,
+	0x6A66, 0xE9BF, 0x6A67, 0xE9C1, 0x6A68, 0xE9C3, 0x6A69, 0xE9D5,
+	0x6A6A, 0xE9CF, 0x6A6B, 0xBEEE, 0x6A6D, 0xE9C6, 0x6A6F, 0xE9D4,
+	0x6A76, 0xE9C7, 0x6A7E, 0xC0CF, 0x6A7F, 0xED45, 0x6A80, 0xC0C8,
+	0x6A81, 0xECF5, 0x6A83, 0xED41, 0x6A84, 0xC0CA, 0x6A85, 0xED48,
+	0x6A87, 0xECFC, 0x6A89, 0xECF7, 0x6A8C, 0xED49, 0x6A8D, 0xECF3,
+	0x6A8E, 0xECFE, 0x6A90, 0xC0D1, 0x6A91, 0xED44, 0x6A92, 0xED4A,
+	0x6A93, 0xECFD, 0x6A94, 0xC0C9, 0x6A95, 0xED40, 0x6A96, 0xECF4,
+	0x6A97, 0xC0D0, 0x6A9A, 0xED47, 0x6A9B, 0xECF9, 0x6A9C, 0xC0CC,
+	0x6A9E, 0xECFB, 0x6A9F, 0xECF8, 0x6AA0, 0xC0D2, 0x6AA1, 0xECFA,
+	0x6AA2, 0xC0CB, 0x6AA3, 0xC0CE, 0x6AA4, 0xED43, 0x6AA5, 0xECF6,
+	0x6AA6, 0xED46, 0x6AA8, 0xED42, 0x6AAC, 0xC263, 0x6AAD, 0xEFE7,
+	0x6AAE, 0xC268, 0x6AAF, 0xC269, 0x6AB3, 0xC262, 0x6AB4, 0xEFE6,
+	0x6AB6, 0xEFE3, 0x6AB7, 0xEFE4, 0x6AB8, 0xC266, 0x6AB9, 0xEFDE,
+	0x6ABA, 0xEFE2, 0x6ABB, 0xC265, 0x6ABD, 0xEFDF, 0x6AC2, 0xC267,
+	0x6AC3, 0xC264, 0x6AC5, 0xEFDD, 0x6AC6, 0xEFE1, 0x6AC7, 0xEFE5,
+	0x6ACB, 0xF251, 0x6ACC, 0xF24E, 0x6ACD, 0xF257, 0x6ACF, 0xF256,
+	0x6AD0, 0xF254, 0x6AD1, 0xF24F, 0x6AD3, 0xC372, 0x6AD9, 0xF250,
+	0x6ADA, 0xC371, 0x6ADB, 0xC0CD, 0x6ADC, 0xF253, 0x6ADD, 0xC370,
+	0x6ADE, 0xF258, 0x6ADF, 0xF252, 0x6AE0, 0xF24D, 0x6AE1, 0xEFE0,
+	0x6AE5, 0xC36F, 0x6AE7, 0xF24C, 0x6AE8, 0xF456, 0x6AEA, 0xF455,
+	0x6AEB, 0xF255, 0x6AEC, 0xC468, 0x6AEE, 0xF459, 0x6AEF, 0xF45A,
+	0x6AF0, 0xF454, 0x6AF1, 0xF458, 0x6AF3, 0xF453, 0x6AF8, 0xF5D1,
+	0x6AF9, 0xF457, 0x6AFA, 0xC4E7, 0x6AFB, 0xC4E5, 0x6AFC, 0xF5CF,
+	0x6B00, 0xF5D2, 0x6B02, 0xF5CE, 0x6B03, 0xF5D0, 0x6B04, 0xC4E6,
+	0x6B08, 0xF6E5, 0x6B09, 0xF6E6, 0x6B0A, 0xC576, 0x6B0B, 0xF6E4,
+	0x6B0F, 0xF7E2, 0x6B10, 0xC5CF, 0x6B11, 0xF7E0, 0x6B12, 0xF7E1,
+	0x6B13, 0xF8AC, 0x6B16, 0xC656, 0x6B17, 0xF8F3, 0x6B18, 0xF8F1,
+	0x6B19, 0xF8F2, 0x6B1A, 0xF8F4, 0x6B1E, 0xF9BB, 0x6B20, 0xA4ED,
+	0x6B21, 0xA6B8, 0x6B23, 0xAA59, 0x6B25, 0xCCE9, 0x6B28, 0xCF64,
+	0x6B2C, 0xD1F5, 0x6B2D, 0xD1F7, 0x6B2F, 0xD1F6, 0x6B31, 0xD1F8,
+	0x6B32, 0xB1FD, 0x6B33, 0xD5D7, 0x6B34, 0xD1F9, 0x6B36, 0xD5D6,
+	0x6B37, 0xD5D8, 0x6B38, 0xD5D9, 0x6B39, 0xD9DA, 0x6B3A, 0xB4DB,
+	0x6B3B, 0xD9DB, 0x6B3C, 0xD9DD, 0x6B3D, 0xB4DC, 0x6B3E, 0xB4DA,
+	0x6B3F, 0xD9DC, 0x6B41, 0xDDFA, 0x6B42, 0xDDF8, 0x6B43, 0xDDF7,
+	0x6B45, 0xDDF6, 0x6B46, 0xDDF5, 0x6B47, 0xB7B2, 0x6B48, 0xDDF9,
+	0x6B49, 0xBA70, 0x6B4A, 0xE263, 0x6B4B, 0xE265, 0x6B4C, 0xBA71,
+	0x6B4D, 0xE264, 0x6B4E, 0xBCDB, 0x6B50, 0xBCDA, 0x6B51, 0xE5F0,
+	0x6B54, 0xE9DF, 0x6B55, 0xE9DE, 0x6B56, 0xE9E0, 0x6B59, 0xBEF9,
+	0x6B5B, 0xED4B, 0x6B5C, 0xC0D3, 0x6B5E, 0xEFE8, 0x6B5F, 0xC26A,
+	0x6B60, 0xF259, 0x6B61, 0xC577, 0x6B62, 0xA4EE, 0x6B63, 0xA5BF,
+	0x6B64, 0xA6B9, 0x6B65, 0xA842, 0x6B66, 0xAA5A, 0x6B67, 0xAA5B,
+	0x6B6A, 0xAC6E, 0x6B6D, 0xD1FA, 0x6B72, 0xB7B3, 0x6B76, 0xE6D1,
+	0x6B77, 0xBEFA, 0x6B78, 0xC26B, 0x6B79, 0xA4EF, 0x6B7B, 0xA6BA,
+	0x6B7E, 0xCCEB, 0x6B7F, 0xAA5C, 0x6B80, 0xCCEA, 0x6B82, 0xCF65,
+	0x6B83, 0xAC6F, 0x6B84, 0xCF66, 0x6B86, 0xAC70, 0x6B88, 0xD1FC,
+	0x6B89, 0xAEEE, 0x6B8A, 0xAEED, 0x6B8C, 0xD5DE, 0x6B8D, 0xD5DC,
+	0x6B8E, 0xD5DD, 0x6B8F, 0xD5DB, 0x6B91, 0xD5DA, 0x6B94, 0xD9DE,
+	0x6B95, 0xD9E1, 0x6B96, 0xB4DE, 0x6B97, 0xD9DF, 0x6B98, 0xB4DD,
+	0x6B99, 0xD9E0, 0x6B9B, 0xDDFB, 0x6B9E, 0xE266, 0x6B9F, 0xE267,
+	0x6BA0, 0xE268, 0x6BA2, 0xE5F3, 0x6BA3, 0xE5F2, 0x6BA4, 0xBCDC,
+	0x6BA5, 0xE5F1, 0x6BA6, 0xE5F4, 0x6BA7, 0xE9E1, 0x6BAA, 0xE9E2,
+	0x6BAB, 0xE9E3, 0x6BAD, 0xED4C, 0x6BAE, 0xC0D4, 0x6BAF, 0xC26C,
+	0x6BB0, 0xF25A, 0x6BB2, 0xC4E8, 0x6BB3, 0xC95F, 0x6BB5, 0xAC71,
+	0x6BB6, 0xCF67, 0x6BB7, 0xAEEF, 0x6BBA, 0xB1FE, 0x6BBC, 0xB4DF,
+	0x6BBD, 0xD9E2, 0x6BBF, 0xB7B5, 0x6BC0, 0xB7B4, 0x6BC3, 0xE269,
+	0x6BC4, 0xE26A, 0x6BC5, 0xBCDD, 0x6BC6, 0xBCDE, 0x6BC7, 0xE9E5,
+	0x6BC8, 0xE9E4, 0x6BC9, 0xEFE9, 0x6BCA, 0xF7E3, 0x6BCB, 0xA4F0,
+	0x6BCC, 0xC960, 0x6BCD, 0xA5C0, 0x6BCF, 0xA843, 0x6BD0, 0xCB48,
+	0x6BD2, 0xAC72, 0x6BD3, 0xB7B6, 0x6BD4, 0xA4F1, 0x6BD6, 0xCF68,
+	0x6BD7, 0xAC73, 0x6BD8, 0xCF69, 0x6BDA, 0xC0D5, 0x6BDB, 0xA4F2,
+	0x6BDE, 0xCCEC, 0x6BE0, 0xCF6A, 0x6BE2, 0xD242, 0x6BE3, 0xD241,
+	0x6BE4, 0xD1FE, 0x6BE6, 0xD1FD, 0x6BE7, 0xD243, 0x6BE8, 0xD240,
+	0x6BEB, 0xB240, 0x6BEC, 0xB241, 0x6BEF, 0xB4E0, 0x6BF0, 0xD9E3,
+	0x6BF2, 0xD9E4, 0x6BF3, 0xD9E5, 0x6BF7, 0xDE41, 0x6BF8, 0xDE42,
+	0x6BF9, 0xDE40, 0x6BFB, 0xDDFD, 0x6BFC, 0xDDFE, 0x6BFD, 0xB7B7,
+	0x6BFE, 0xE26B, 0x6BFF, 0xE5F7, 0x6C00, 0xE5F6, 0x6C01, 0xE5F5,
+	0x6C02, 0xE5F8, 0x6C03, 0xE9E7, 0x6C04, 0xE9E6, 0x6C05, 0xBEFB,
+	0x6C06, 0xE9E8, 0x6C08, 0xC0D6, 0x6C09, 0xED4D, 0x6C0B, 0xEFEA,
+	0x6C0C, 0xF25B, 0x6C0D, 0xF6E7, 0x6C0F, 0xA4F3, 0x6C10, 0xA5C2,
+	0x6C11, 0xA5C1, 0x6C13, 0xAA5D, 0x6C14, 0xC961, 0x6C15, 0xC97E,
+	0x6C16, 0xA6BB, 0x6C18, 0xC9F7, 0x6C19, 0xCB49, 0x6C1A, 0xCB4A,
+	0x6C1B, 0xAA5E, 0x6C1D, 0xCCED, 0x6C1F, 0xAC74, 0x6C20, 0xCF6B,
+	0x6C21, 0xCF6C, 0x6C23, 0xAEF0, 0x6C24, 0xAEF4, 0x6C25, 0xD244,
+	0x6C26, 0xAEF3, 0x6C27, 0xAEF1, 0x6C28, 0xAEF2, 0x6C2A, 0xD5DF,
+	0x6C2B, 0xB242, 0x6C2C, 0xB4E3, 0x6C2E, 0xB4E1, 0x6C2F, 0xB4E2,
+	0x6C30, 0xD9E6, 0x6C33, 0xBA72, 0x6C34, 0xA4F4, 0x6C36, 0xC9A1,
+	0x6C38, 0xA5C3, 0x6C3B, 0xC9A4, 0x6C3E, 0xA5C6, 0x6C3F, 0xC9A3,
+	0x6C40, 0xA5C5, 0x6C41, 0xA5C4, 0x6C42, 0xA844, 0x6C43, 0xC9A2,
+	0x6C46, 0xC9F8, 0x6C4A, 0xC9FC, 0x6C4B, 0xC9FE, 0x6C4C, 0xCA40,
+	0x6C4D, 0xA6C5, 0x6C4E, 0xA6C6, 0x6C4F, 0xC9FB, 0x6C50, 0xA6C1,
+	0x6C52, 0xC9F9, 0x6C54, 0xC9FD, 0x6C55, 0xA6C2, 0x6C57, 0xA6BD,
+	0x6C59, 0xA6BE, 0x6C5B, 0xA6C4, 0x6C5C, 0xC9FA, 0x6C5D, 0xA6BC,
+	0x6C5E, 0xA845, 0x6C5F, 0xA6BF, 0x6C60, 0xA6C0, 0x6C61, 0xA6C3,
+	0x6C65, 0xCB5B, 0x6C66, 0xCB59, 0x6C67, 0xCB4C, 0x6C68, 0xA851,
+	0x6C69, 0xCB53, 0x6C6A, 0xA84C, 0x6C6B, 0xCB4D, 0x6C6D, 0xCB55,
+	0x6C6F, 0xCB52, 0x6C70, 0xA84F, 0x6C71, 0xCB51, 0x6C72, 0xA856,
+	0x6C73, 0xCB5A, 0x6C74, 0xA858, 0x6C76, 0xA85A, 0x6C78, 0xCB4B,
+	0x6C7A, 0xA84D, 0x6C7B, 0xCB5C, 0x6C7D, 0xA854, 0x6C7E, 0xA857,
+	0x6C80, 0xCD45, 0x6C81, 0xA847, 0x6C82, 0xA85E, 0x6C83, 0xA855,
+	0x6C84, 0xCB4E, 0x6C85, 0xA84A, 0x6C86, 0xA859, 0x6C87, 0xCB56,
+	0x6C88, 0xA848, 0x6C89, 0xA849, 0x6C8A, 0xCD43, 0x6C8B, 0xCB4F,
+	0x6C8C, 0xA850, 0x6C8D, 0xA85B, 0x6C8E, 0xCB5D, 0x6C8F, 0xCB50,
+	0x6C90, 0xA84E, 0x6C92, 0xA853, 0x6C93, 0xCCEE, 0x6C94, 0xA85C,
+	0x6C95, 0xCB57, 0x6C96, 0xA852, 0x6C98, 0xA85D, 0x6C99, 0xA846,
+	0x6C9A, 0xCB54, 0x6C9B, 0xA84B, 0x6C9C, 0xCB58, 0x6C9D, 0xCD44,
+	0x6CAB, 0xAA6A, 0x6CAC, 0xAA7A, 0x6CAD, 0xCCF5, 0x6CAE, 0xAA71,
+	0x6CB0, 0xCD4B, 0x6CB1, 0xAA62, 0x6CB3, 0xAA65, 0x6CB4, 0xCD42,
+	0x6CB6, 0xCCF3, 0x6CB7, 0xCCF7, 0x6CB8, 0xAA6D, 0x6CB9, 0xAA6F,
+	0x6CBA, 0xCCFA, 0x6CBB, 0xAA76, 0x6CBC, 0xAA68, 0x6CBD, 0xAA66,
+	0x6CBE, 0xAA67, 0x6CBF, 0xAA75, 0x6CC0, 0xCD47, 0x6CC1, 0xAA70,
+	0x6CC2, 0xCCF9, 0x6CC3, 0xCCFB, 0x6CC4, 0xAA6E, 0x6CC5, 0xAA73,
+	0x6CC6, 0xCCFC, 0x6CC7, 0xCD4A, 0x6CC9, 0xAC75, 0x6CCA, 0xAA79,
+	0x6CCC, 0xAA63, 0x6CCD, 0xCD49, 0x6CCF, 0xCD4D, 0x6CD0, 0xCCF8,
+	0x6CD1, 0xCD4F, 0x6CD2, 0xCD40, 0x6CD3, 0xAA6C, 0x6CD4, 0xCCF4,
+	0x6CD5, 0xAA6B, 0x6CD6, 0xAA7D, 0x6CD7, 0xAA72, 0x6CD9, 0xCCF2,
+	0x6CDA, 0xCF75, 0x6CDB, 0xAA78, 0x6CDC, 0xAA7C, 0x6CDD, 0xCD41,
+	0x6CDE, 0xCD46, 0x6CE0, 0xAA7E, 0x6CE1, 0xAA77, 0x6CE2, 0xAA69,
+	0x6CE3, 0xAA5F, 0x6CE5, 0xAA64, 0x6CE7, 0xCCF6, 0x6CE8, 0xAA60,
+	0x6CE9, 0xCD4E, 0x6CEB, 0xCCF0, 0x6CEC, 0xCCEF, 0x6CED, 0xCCFD,
+	0x6CEE, 0xCCF1, 0x6CEF, 0xAA7B, 0x6CF0, 0xAEF5, 0x6CF1, 0xAA74,
+	0x6CF2, 0xCCFE, 0x6CF3, 0xAA61, 0x6CF5, 0xACA6, 0x6CF9, 0xCD4C,
+	0x6D00, 0xCF7C, 0x6D01, 0xCFA1, 0x6D03, 0xCFA4, 0x6D04, 0xCF77,
+	0x6D07, 0xCFA7, 0x6D08, 0xCFAA, 0x6D09, 0xCFAC, 0x6D0A, 0xCF74,
+	0x6D0B, 0xAC76, 0x6D0C, 0xAC7B, 0x6D0D, 0xD249, 0x6D0E, 0xACAD,
+	0x6D0F, 0xCFA5, 0x6D10, 0xCFAD, 0x6D11, 0xCF7B, 0x6D12, 0xCF73,
+	0x6D16, 0xD264, 0x6D17, 0xAC7E, 0x6D18, 0xCFA2, 0x6D19, 0xCF78,
+	0x6D1A, 0xCF7A, 0x6D1B, 0xACA5, 0x6D1D, 0xCF7D, 0x6D1E, 0xAC7D,
+	0x6D1F, 0xCF70, 0x6D20, 0xCFA8, 0x6D22, 0xCFAB, 0x6D25, 0xAC7A,
+	0x6D27, 0xACA8, 0x6D28, 0xCF6D, 0x6D29, 0xACAA, 0x6D2A, 0xAC78,
+	0x6D2B, 0xACAE, 0x6D2C, 0xCFA9, 0x6D2D, 0xCF6F, 0x6D2E, 0xACAB,
+	0x6D2F, 0xD25E, 0x6D30, 0xCD48, 0x6D31, 0xAC7C, 0x6D32, 0xAC77,
+	0x6D33, 0xCF76, 0x6D34, 0xCF6E, 0x6D35, 0xACAC, 0x6D36, 0xACA4,
+	0x6D37, 0xCFA3, 0x6D38, 0xACA9, 0x6D39, 0xACA7, 0x6D3A, 0xCF79,
+	0x6D3B, 0xACA1, 0x6D3C, 0xCF71, 0x6D3D, 0xACA2, 0x6D3E, 0xACA3,
+	0x6D3F, 0xCF72, 0x6D40, 0xCFA6, 0x6D41, 0xAC79, 0x6D42, 0xCF7E,
+	0x6D58, 0xD24C, 0x6D59, 0xAEFD, 0x6D5A, 0xAF43, 0x6D5E, 0xD255,
+	0x6D5F, 0xD25B, 0x6D60, 0xD257, 0x6D61, 0xD24A, 0x6D62, 0xD24D,
+	0x6D63, 0xD246, 0x6D64, 0xD247, 0x6D65, 0xAF4A, 0x6D66, 0xAEFA,
+	0x6D67, 0xD256, 0x6D68, 0xD25F, 0x6D69, 0xAF45, 0x6D6A, 0xAEF6,
+	0x6D6C, 0xAF40, 0x6D6D, 0xD24E, 0x6D6E, 0xAF42, 0x6D6F, 0xD24F,
+	0x6D70, 0xD259, 0x6D74, 0xAF44, 0x6D75, 0xD268, 0x6D76, 0xD248,
+	0x6D77, 0xAEFC, 0x6D78, 0xAEFB, 0x6D79, 0xAF48, 0x6D7A, 0xD245,
+	0x6D7B, 0xD266, 0x6D7C, 0xD25A, 0x6D7D, 0xD267, 0x6D7E, 0xD261,
+	0x6D7F, 0xD253, 0x6D80, 0xD262, 0x6D82, 0xD25C, 0x6D83, 0xD265,
+	0x6D84, 0xD263, 0x6D85, 0xAF49, 0x6D86, 0xD254, 0x6D87, 0xAEF9,
+	0x6D88, 0xAEF8, 0x6D89, 0xAF41, 0x6D8A, 0xAF47, 0x6D8B, 0xD260,
+	0x6D8C, 0xAF46, 0x6D8D, 0xD251, 0x6D8E, 0xB243, 0x6D90, 0xD269,
+	0x6D91, 0xD250, 0x6D92, 0xD24B, 0x6D93, 0xAEFE, 0x6D94, 0xAF4B,
+	0x6D95, 0xAEF7, 0x6D97, 0xD258, 0x6D98, 0xD25D, 0x6DAA, 0xB265,
+	0x6DAB, 0xD5E1, 0x6DAC, 0xD5E5, 0x6DAE, 0xB252, 0x6DAF, 0xB250,
+	0x6DB2, 0xB247, 0x6DB3, 0xD5E3, 0x6DB4, 0xD5E2, 0x6DB5, 0xB25B,
+	0x6DB7, 0xD5E8, 0x6DB8, 0xB255, 0x6DBA, 0xD5FA, 0x6DBB, 0xD647,
+	0x6DBC, 0xB244, 0x6DBD, 0xD5F7, 0x6DBE, 0xD5F0, 0x6DBF, 0xB267,
+	0x6DC0, 0xD5E0, 0x6DC2, 0xD5FC, 0x6DC4, 0xB264, 0x6DC5, 0xB258,
+	0x6DC6, 0xB263, 0x6DC7, 0xB24E, 0x6DC8, 0xD5EC, 0x6DC9, 0xD5FE,
+	0x6DCA, 0xD5F6, 0x6DCB, 0xB24F, 0x6DCC, 0xB249, 0x6DCD, 0xD645,
+	0x6DCF, 0xD5FD, 0x6DD0, 0xD640, 0x6DD1, 0xB251, 0x6DD2, 0xB259,
+	0x6DD3, 0xD642, 0x6DD4, 0xD5EA, 0x6DD5, 0xD5FB, 0x6DD6, 0xD5EF,
+	0x6DD7, 0xD644, 0x6DD8, 0xB25E, 0x6DD9, 0xB246, 0x6DDA, 0xB25C,
+	0x6DDB, 0xD5F4, 0x6DDC, 0xD5F2, 0x6DDD, 0xD5F3, 0x6DDE, 0xB253,
+	0x6DDF, 0xD5EE, 0x6DE0, 0xD5ED, 0x6DE1, 0xB248, 0x6DE2, 0xD5E7,
+	0x6DE3, 0xD646, 0x6DE4, 0xB24A, 0x6DE5, 0xD5F1, 0x6DE6, 0xB268,
+	0x6DE8, 0xB262, 0x6DE9, 0xD5E6, 0x6DEA, 0xB25F, 0x6DEB, 0xB25D,
+	0x6DEC, 0xB266, 0x6DED, 0xD5F8, 0x6DEE, 0xB261, 0x6DEF, 0xD252,
+	0x6DF0, 0xD5F9, 0x6DF1, 0xB260, 0x6DF2, 0xD641, 0x6DF3, 0xB245,
+	0x6DF4, 0xD5F5, 0x6DF5, 0xB257, 0x6DF6, 0xD5E9, 0x6DF7, 0xB256,
+	0x6DF9, 0xB254, 0x6DFA, 0xB24C, 0x6DFB, 0xB24B, 0x6DFC, 0xD9E7,
+	0x6DFD, 0xD643, 0x6E00, 0xD5EB, 0x6E03, 0xD9FC, 0x6E05, 0xB24D,
+	0x6E19, 0xB541, 0x6E1A, 0xB25A, 0x6E1B, 0xB4EE, 0x6E1C, 0xD9F6,
+	0x6E1D, 0xB4FC, 0x6E1F, 0xD9EA, 0x6E20, 0xB4EB, 0x6E21, 0xB4E7,
+	0x6E22, 0xDA49, 0x6E23, 0xB4ED, 0x6E24, 0xB4F1, 0x6E25, 0xB4EC,
+	0x6E26, 0xB4F5, 0x6E27, 0xDA4D, 0x6E28, 0xDA44, 0x6E2B, 0xD9F1,
+	0x6E2C, 0xB4FA, 0x6E2D, 0xB4F4, 0x6E2E, 0xD9FD, 0x6E2F, 0xB4E4,
+	0x6E30, 0xDA4A, 0x6E31, 0xDA43, 0x6E32, 0xB4E8, 0x6E33, 0xD9F7,
+	0x6E34, 0xB4F7, 0x6E35, 0xDA55, 0x6E36, 0xDA56, 0x6E38, 0xB4E5,
+	0x6E39, 0xDA48, 0x6E3A, 0xB4F9, 0x6E3B, 0xD9FB, 0x6E3C, 0xD9ED,
+	0x6E3D, 0xD9EE, 0x6E3E, 0xB4FD, 0x6E3F, 0xD9F2, 0x6E40, 0xD9F9,
+	0x6E41, 0xD9F3, 0x6E43, 0xB4FB, 0x6E44, 0xB544, 0x6E45, 0xD9EF,
+	0x6E46, 0xD9E8, 0x6E47, 0xD9E9, 0x6E49, 0xD9EB, 0x6E4A, 0xB4EA,
+	0x6E4B, 0xD9F8, 0x6E4D, 0xB4F8, 0x6E4E, 0xB542, 0x6E51, 0xD9FA,
+	0x6E52, 0xDA53, 0x6E53, 0xDA4B, 0x6E54, 0xB4E6, 0x6E55, 0xDA51,
+	0x6E56, 0xB4F2, 0x6E58, 0xB4F0, 0x6E5A, 0xDA57, 0x6E5B, 0xB4EF,
+	0x6E5C, 0xDA41, 0x6E5D, 0xD9F4, 0x6E5E, 0xD9FE, 0x6E5F, 0xB547,
+	0x6E60, 0xDA45, 0x6E61, 0xDA42, 0x6E62, 0xD9F0, 0x6E63, 0xB543,
+	0x6E64, 0xDA4F, 0x6E65, 0xDA4C, 0x6E66, 0xDA54, 0x6E67, 0xB4E9,
+	0x6E68, 0xDA40, 0x6E69, 0xB546, 0x6E6B, 0xDA47, 0x6E6E, 0xB4F3,
+	0x6E6F, 0xB4F6, 0x6E71, 0xDA46, 0x6E72, 0xB545, 0x6E73, 0xD9F5,
+	0x6E74, 0xD5E4, 0x6E77, 0xDA50, 0x6E78, 0xDA4E, 0x6E79, 0xDA52,
+	0x6E88, 0xD9EC, 0x6E89, 0xB540, 0x6E8D, 0xDE61, 0x6E8E, 0xDE60,
+	0x6E8F, 0xDE46, 0x6E90, 0xB7BD, 0x6E92, 0xDE5F, 0x6E93, 0xDE49,
+	0x6E94, 0xDE4A, 0x6E96, 0xB7C7, 0x6E97, 0xDE68, 0x6E98, 0xB7C2,
+	0x6E99, 0xDE5E, 0x6E9B, 0xDE43, 0x6E9C, 0xB7C8, 0x6E9D, 0xB7BE,
+	0x6E9E, 0xDE52, 0x6E9F, 0xDE48, 0x6EA0, 0xDE4B, 0x6EA1, 0xDE63,
+	0x6EA2, 0xB7B8, 0x6EA3, 0xDE6A, 0x6EA4, 0xDE62, 0x6EA5, 0xB7C1,
+	0x6EA6, 0xDE57, 0x6EA7, 0xB7CC, 0x6EAA, 0xB7CB, 0x6EAB, 0xB7C5,
+	0x6EAE, 0xDE69, 0x6EAF, 0xB7B9, 0x6EB0, 0xDE55, 0x6EB1, 0xDE4C,
+	0x6EB2, 0xDE59, 0x6EB3, 0xDE65, 0x6EB4, 0xB7CD, 0x6EB6, 0xB7BB,
+	0x6EB7, 0xDE54, 0x6EB9, 0xDE4D, 0x6EBA, 0xB7C4, 0x6EBC, 0xB7C3,
+	0x6EBD, 0xDE50, 0x6EBE, 0xDE5A, 0x6EBF, 0xDE64, 0x6EC0, 0xDE47,
+	0x6EC1, 0xDE51, 0x6EC2, 0xB7BC, 0x6EC3, 0xDE5B, 0x6EC4, 0xB7C9,
+	0x6EC5, 0xB7C0, 0x6EC6, 0xDE4E, 0x6EC7, 0xB7BF, 0x6EC8, 0xDE45,
+	0x6EC9, 0xDE53, 0x6ECA, 0xDE67, 0x6ECB, 0xB4FE, 0x6ECC, 0xBAB0,
+	0x6ECD, 0xDE56, 0x6ECE, 0xE26C, 0x6ECF, 0xDE58, 0x6ED0, 0xDE66,
+	0x6ED1, 0xB7C6, 0x6ED2, 0xDE4F, 0x6ED3, 0xB7BA, 0x6ED4, 0xB7CA,
+	0x6ED5, 0xBCF0, 0x6ED6, 0xDE44, 0x6ED8, 0xDE5D, 0x6EDC, 0xDE5C,
+	0x6EEB, 0xE2AA, 0x6EEC, 0xBAAD, 0x6EED, 0xE27D, 0x6EEE, 0xE2A4,
+	0x6EEF, 0xBAA2, 0x6EF1, 0xE26E, 0x6EF2, 0xBAAF, 0x6EF4, 0xBA77,
+	0x6EF5, 0xE26D, 0x6EF6, 0xE2B0, 0x6EF7, 0xBAB1, 0x6EF8, 0xE271,
+	0x6EF9, 0xE2A3, 0x6EFB, 0xE273, 0x6EFC, 0xE2B3, 0x6EFD, 0xE2AF,
+	0x6EFE, 0xBA75, 0x6EFF, 0xBAA1, 0x6F00, 0xE653, 0x6F01, 0xBAAE,
+	0x6F02, 0xBA7D, 0x6F03, 0xE26F, 0x6F05, 0xE2AE, 0x6F06, 0xBAA3,
+	0x6F07, 0xE2AB, 0x6F08, 0xE2B8, 0x6F09, 0xE275, 0x6F0A, 0xE27E,
+	0x6F0D, 0xE2B6, 0x6F0E, 0xE2AC, 0x6F0F, 0xBA7C, 0x6F12, 0xE27C,
+	0x6F13, 0xBA76, 0x6F14, 0xBA74, 0x6F15, 0xBAA8, 0x6F18, 0xE27A,
+	0x6F19, 0xE277, 0x6F1A, 0xE278, 0x6F1C, 0xE2B2, 0x6F1E, 0xE2B7,
+	0x6F1F, 0xE2B5, 0x6F20, 0xBA7A, 0x6F21, 0xE2B9, 0x6F22, 0xBA7E,
+	0x6F23, 0xBAA7, 0x6F25, 0xE270, 0x6F26, 0xE5FA, 0x6F27, 0xE279,
+	0x6F29, 0xBA78, 0x6F2A, 0xBAAC, 0x6F2B, 0xBAA9, 0x6F2C, 0xBA7B,
+	0x6F2D, 0xE2A5, 0x6F2E, 0xE274, 0x6F2F, 0xBAAA, 0x6F30, 0xE2A7,
+	0x6F31, 0xBAA4, 0x6F32, 0xBAA6, 0x6F33, 0xBA73, 0x6F35, 0xE2A9,
+	0x6F36, 0xE2A1, 0x6F37, 0xE272, 0x6F38, 0xBAA5, 0x6F39, 0xE2B1,
+	0x6F3A, 0xE2B4, 0x6F3B, 0xE27B, 0x6F3C, 0xE2A8, 0x6F3E, 0xBA79,
+	0x6F3F, 0xBCDF, 0x6F40, 0xE2A6, 0x6F41, 0xE5F9, 0x6F43, 0xE2AD,
+	0x6F4E, 0xE276, 0x6F4F, 0xE644, 0x6F50, 0xE64E, 0x6F51, 0xBCE2,
+	0x6F52, 0xE64D, 0x6F53, 0xE659, 0x6F54, 0xBCE4, 0x6F55, 0xE64B,
+	0x6F57, 0xE64F, 0x6F58, 0xBCEF, 0x6F5A, 0xE646, 0x6F5B, 0xBCE7,
+	0x6F5D, 0xE652, 0x6F5E, 0xE9F0, 0x6F5F, 0xBCF3, 0x6F60, 0xBCF2,
+	0x6F61, 0xE654, 0x6F62, 0xE643, 0x6F63, 0xE65E, 0x6F64, 0xBCED,
+	0x6F66, 0xBCE3, 0x6F67, 0xE657, 0x6F69, 0xE65B, 0x6F6A, 0xE660,
+	0x6F6B, 0xE655, 0x6F6C, 0xE649, 0x6F6D, 0xBCE6, 0x6F6E, 0xBCE9,
+	0x6F6F, 0xBCF1, 0x6F70, 0xBCEC, 0x6F72, 0xE64C, 0x6F73, 0xE2A2,
+	0x6F76, 0xE648, 0x6F77, 0xE65F, 0x6F78, 0xBCE8, 0x6F7A, 0xBCEB,
+	0x6F7B, 0xE661, 0x6F7C, 0xBCE0, 0x6F7D, 0xE656, 0x6F7E, 0xE5FB,
+	0x6F7F, 0xE65C, 0x6F80, 0xC0DF, 0x6F82, 0xE64A, 0x6F84, 0xBCE1,
+	0x6F85, 0xE645, 0x6F86, 0xBCE5, 0x6F87, 0xE5FC, 0x6F88, 0xBAAB,
+	0x6F89, 0xE641, 0x6F8B, 0xE65A, 0x6F8C, 0xE642, 0x6F8D, 0xE640,
+	0x6F8E, 0xBCEA, 0x6F90, 0xE658, 0x6F92, 0xE5FE, 0x6F93, 0xE651,
+	0x6F94, 0xE650, 0x6F95, 0xE65D, 0x6F96, 0xE647, 0x6F97, 0xBCEE,
+	0x6F9E, 0xE9F3, 0x6FA0, 0xBF49, 0x6FA1, 0xBEFE, 0x6FA2, 0xEA40,
+	0x6FA3, 0xE9EB, 0x6FA4, 0xBF41, 0x6FA5, 0xE9F7, 0x6FA6, 0xBF48,
+	0x6FA7, 0xBF43, 0x6FA8, 0xE9F5, 0x6FA9, 0xED4F, 0x6FAA, 0xE9FB,
+	0x6FAB, 0xEA42, 0x6FAC, 0xE9FA, 0x6FAD, 0xE9E9, 0x6FAE, 0xE9F8,
+	0x6FAF, 0xEA44, 0x6FB0, 0xEA46, 0x6FB1, 0xBEFD, 0x6FB2, 0xEA45,
+	0x6FB3, 0xBF44, 0x6FB4, 0xBF4A, 0x6FB6, 0xBF47, 0x6FB8, 0xE9FE,
+	0x6FB9, 0xBF46, 0x6FBA, 0xE9F9, 0x6FBC, 0xE9ED, 0x6FBD, 0xE9F2,
+	0x6FBF, 0xE9FD, 0x6FC0, 0xBF45, 0x6FC1, 0xBF42, 0x6FC2, 0xBEFC,
+	0x6FC3, 0xBF40, 0x6FC4, 0xE9F1, 0x6FC6, 0xE5FD, 0x6FC7, 0xE9EC,
+	0x6FC8, 0xE9EF, 0x6FC9, 0xEA41, 0x6FCA, 0xE9F4, 0x6FCB, 0xE9EA,
+	0x6FCC, 0xED4E, 0x6FCD, 0xEA43, 0x6FCE, 0xE9EE, 0x6FCF, 0xE9FC,
+	0x6FD4, 0xED51, 0x6FD5, 0xC0E3, 0x6FD8, 0xC0D7, 0x6FDB, 0xC0DB,
+	0x6FDC, 0xED53, 0x6FDD, 0xED59, 0x6FDE, 0xED57, 0x6FDF, 0xC0D9,
+	0x6FE0, 0xC0DA, 0x6FE1, 0xC0E1, 0x6FE2, 0xED5A, 0x6FE3, 0xED52,
+	0x6FE4, 0xC0DC, 0x6FE6, 0xED56, 0x6FE7, 0xED55, 0x6FE8, 0xED5B,
+	0x6FE9, 0xC0E2, 0x6FEB, 0xC0DD, 0x6FEC, 0xC0E0, 0x6FED, 0xED54,
+	0x6FEE, 0xC0E4, 0x6FEF, 0xC0DE, 0x6FF0, 0xC0E5, 0x6FF1, 0xC0D8,
+	0x6FF2, 0xED58, 0x6FF4, 0xED50, 0x6FF7, 0xEFF7, 0x6FFA, 0xC271,
+	0x6FFB, 0xEFF4, 0x6FFC, 0xEFF6, 0x6FFE, 0xC26F, 0x6FFF, 0xEFF2,
+	0x7000, 0xEFF3, 0x7001, 0xEFEE, 0x7004, 0xE9F6, 0x7005, 0xEFEF,
+	0x7006, 0xC270, 0x7007, 0xEFEB, 0x7009, 0xC26D, 0x700A, 0xEFF8,
+	0x700B, 0xC26E, 0x700C, 0xEFEC, 0x700D, 0xEFED, 0x700E, 0xEFF1,
+	0x700F, 0xC273, 0x7011, 0xC272, 0x7014, 0xEFF0, 0x7015, 0xC378,
+	0x7016, 0xF25F, 0x7017, 0xF265, 0x7018, 0xC379, 0x7019, 0xF25C,
+	0x701A, 0xC376, 0x701B, 0xC373, 0x701C, 0xF267, 0x701D, 0xC377,
+	0x701F, 0xC374, 0x7020, 0xF25E, 0x7021, 0xF261, 0x7022, 0xF262,
+	0x7023, 0xF263, 0x7024, 0xF266, 0x7026, 0xEFF5, 0x7027, 0xF25D,
+	0x7028, 0xC375, 0x7029, 0xF264, 0x702A, 0xF268, 0x702B, 0xF260,
+	0x702F, 0xF45D, 0x7030, 0xC46A, 0x7031, 0xF460, 0x7032, 0xC46B,
+	0x7033, 0xF468, 0x7034, 0xF45F, 0x7035, 0xF45C, 0x7037, 0xF45E,
+	0x7038, 0xF462, 0x7039, 0xF465, 0x703A, 0xF464, 0x703B, 0xF467,
+	0x703C, 0xF45B, 0x703E, 0xC469, 0x703F, 0xF463, 0x7040, 0xF466,
+	0x7041, 0xF469, 0x7042, 0xF461, 0x7043, 0xF5D3, 0x7044, 0xF5D4,
+	0x7045, 0xF5D8, 0x7046, 0xF5D9, 0x7048, 0xF5D6, 0x7049, 0xF5D7,
+	0x704A, 0xF5D5, 0x704C, 0xC4E9, 0x7051, 0xC578, 0x7052, 0xF6EB,
+	0x7055, 0xF6E8, 0x7056, 0xF6E9, 0x7057, 0xF6EA, 0x7058, 0xC579,
+	0x705A, 0xF7E5, 0x705B, 0xF7E4, 0x705D, 0xF8AF, 0x705E, 0xC5F4,
+	0x705F, 0xF8AD, 0x7060, 0xF8B0, 0x7061, 0xF8AE, 0x7062, 0xF8F5,
+	0x7063, 0xC657, 0x7064, 0xC665, 0x7065, 0xF9A3, 0x7066, 0xF96C,
+	0x7068, 0xF9A2, 0x7069, 0xF9D0, 0x706A, 0xF9D1, 0x706B, 0xA4F5,
+	0x7070, 0xA6C7, 0x7071, 0xCA41, 0x7074, 0xCB5E, 0x7076, 0xA85F,
+	0x7078, 0xA862, 0x707A, 0xCB5F, 0x707C, 0xA860, 0x707D, 0xA861,
+	0x7082, 0xCD58, 0x7083, 0xCD5A, 0x7084, 0xCD55, 0x7085, 0xCD52,
+	0x7086, 0xCD54, 0x708A, 0xAAA4, 0x708E, 0xAAA2, 0x7091, 0xCD56,
+	0x7092, 0xAAA3, 0x7093, 0xCD53, 0x7094, 0xCD50, 0x7095, 0xAAA1,
+	0x7096, 0xCD57, 0x7098, 0xCD51, 0x7099, 0xAAA5, 0x709A, 0xCD59,
+	0x709F, 0xCFAF, 0x70A1, 0xCFB3, 0x70A4, 0xACB7, 0x70A9, 0xCFB6,
+	0x70AB, 0xACAF, 0x70AC, 0xACB2, 0x70AD, 0xACB4, 0x70AE, 0xACB6,
+	0x70AF, 0xACB3, 0x70B0, 0xCFB2, 0x70B1, 0xCFB1, 0x70B3, 0xACB1,
+	0x70B4, 0xCFB4, 0x70B5, 0xCFB5, 0x70B7, 0xCFAE, 0x70B8, 0xACB5,
+	0x70BA, 0xACB0, 0x70BE, 0xCFB0, 0x70C5, 0xD277, 0x70C6, 0xD278,
+	0x70C7, 0xD279, 0x70C8, 0xAF50, 0x70CA, 0xAF4C, 0x70CB, 0xD26E,
+	0x70CD, 0xD276, 0x70CE, 0xD27B, 0x70CF, 0xAF51, 0x70D1, 0xD26C,
+	0x70D2, 0xD272, 0x70D3, 0xD26B, 0x70D4, 0xD275, 0x70D7, 0xD271,
+	0x70D8, 0xAF4D, 0x70D9, 0xAF4F, 0x70DA, 0xD27A, 0x70DC, 0xD26A,
+	0x70DD, 0xD26D, 0x70DE, 0xD273, 0x70E0, 0xD274, 0x70E1, 0xD27C,
+	0x70E2, 0xD270, 0x70E4, 0xAF4E, 0x70EF, 0xB26D, 0x70F0, 0xD64E,
+	0x70F3, 0xD650, 0x70F4, 0xD64C, 0x70F6, 0xD658, 0x70F7, 0xD64A,
+	0x70F8, 0xD657, 0x70F9, 0xB269, 0x70FA, 0xD648, 0x70FB, 0xDA5B,
+	0x70FC, 0xD652, 0x70FD, 0xB26C, 0x70FF, 0xD653, 0x7100, 0xD656,
+	0x7102, 0xD65A, 0x7104, 0xD64F, 0x7106, 0xD654, 0x7109, 0xB26A,
+	0x710A, 0xB26B, 0x710B, 0xD659, 0x710C, 0xD64D, 0x710D, 0xD649,
+	0x710E, 0xD65B, 0x7110, 0xD651, 0x7113, 0xD655, 0x7117, 0xD64B,
+	0x7119, 0xB548, 0x711A, 0xB549, 0x711B, 0xDA65, 0x711C, 0xB54F,
+	0x711E, 0xDA59, 0x711F, 0xDA62, 0x7120, 0xDA58, 0x7121, 0xB54C,
+	0x7122, 0xDA60, 0x7123, 0xDA5E, 0x7125, 0xDA5F, 0x7126, 0xB54A,
+	0x7128, 0xDA63, 0x712E, 0xDA5C, 0x712F, 0xDA5A, 0x7130, 0xB54B,
+	0x7131, 0xDA5D, 0x7132, 0xDA61, 0x7136, 0xB54D, 0x713A, 0xDA64,
+	0x7141, 0xDE70, 0x7142, 0xDE77, 0x7143, 0xDE79, 0x7144, 0xDEA1,
+	0x7146, 0xB7DA, 0x7147, 0xDE6B, 0x7149, 0xB7D2, 0x714B, 0xDE7A,
+	0x714C, 0xB7D7, 0x714D, 0xDEA2, 0x714E, 0xB7CE, 0x7150, 0xDE7D,
+	0x7152, 0xDE6D, 0x7153, 0xDE7E, 0x7154, 0xDE6C, 0x7156, 0xB7DC,
+	0x7158, 0xDE78, 0x7159, 0xB7CF, 0x715A, 0xDEA3, 0x715C, 0xB7D4,
+	0x715D, 0xDE71, 0x715E, 0xB7D9, 0x715F, 0xDE7C, 0x7160, 0xDE6F,
+	0x7161, 0xDE76, 0x7162, 0xDE72, 0x7163, 0xDE6E, 0x7164, 0xB7D1,
+	0x7165, 0xB7D8, 0x7166, 0xB7D6, 0x7167, 0xB7D3, 0x7168, 0xB7DB,
+	0x7169, 0xB7D0, 0x716A, 0xDE75, 0x716C, 0xB7D5, 0x716E, 0xB54E,
+	0x7170, 0xDE7B, 0x7172, 0xDE73, 0x7178, 0xDE74, 0x717B, 0xE2C1,
+	0x717D, 0xBAB4, 0x7180, 0xE2BD, 0x7181, 0xE2C3, 0x7182, 0xE2BF,
+	0x7184, 0xBAB6, 0x7185, 0xE2BE, 0x7186, 0xE2C2, 0x7187, 0xE2BA,
+	0x7189, 0xE2BC, 0x718A, 0xBAB5, 0x718F, 0xE2C0, 0x7190, 0xE2BB,
+	0x7192, 0xBAB7, 0x7194, 0xBAB2, 0x7197, 0xE2C4, 0x7199, 0xBAB3,
+	0x719A, 0xE667, 0x719B, 0xE664, 0x719C, 0xE670, 0x719D, 0xE66A,
+	0x719E, 0xE66C, 0x719F, 0xBCF4, 0x71A0, 0xE666, 0x71A1, 0xE66E,
+	0x71A4, 0xE66D, 0x71A5, 0xE66B, 0x71A7, 0xE671, 0x71A8, 0xBCF7,
+	0x71A9, 0xE668, 0x71AA, 0xE66F, 0x71AC, 0xBCF5, 0x71AF, 0xE663,
+	0x71B0, 0xE665, 0x71B1, 0xBCF6, 0x71B2, 0xE662, 0x71B3, 0xE672,
+	0x71B5, 0xE669, 0x71B8, 0xEA4A, 0x71B9, 0xBF51, 0x71BC, 0xEA55,
+	0x71BD, 0xEA53, 0x71BE, 0xBF4B, 0x71BF, 0xEA49, 0x71C0, 0xEA4C,
+	0x71C1, 0xEA4D, 0x71C2, 0xEA48, 0x71C3, 0xBF55, 0x71C4, 0xBF56,
+	0x71C5, 0xEA47, 0x71C6, 0xEA56, 0x71C7, 0xEA51, 0x71C8, 0xBF4F,
+	0x71C9, 0xBF4C, 0x71CA, 0xEA50, 0x71CB, 0xEA4E, 0x71CE, 0xBF52,
+	0x71CF, 0xEA52, 0x71D0, 0xBF4D, 0x71D2, 0xBF4E, 0x71D4, 0xEA4F,
+	0x71D5, 0xBF50, 0x71D6, 0xEA4B, 0x71D8, 0xEA54, 0x71D9, 0xBF53,
+	0x71DA, 0xEA57, 0x71DB, 0xEA58, 0x71DC, 0xBF54, 0x71DF, 0xC0E7,
+	0x71E0, 0xC0EE, 0x71E1, 0xED5C, 0x71E2, 0xED62, 0x71E4, 0xED60,
+	0x71E5, 0xC0EA, 0x71E6, 0xC0E9, 0x71E7, 0xC0E6, 0x71E8, 0xED5E,
+	0x71EC, 0xC0EC, 0x71ED, 0xC0EB, 0x71EE, 0xC0E8, 0x71F0, 0xED61,
+	0x71F1, 0xED5D, 0x71F2, 0xED5F, 0x71F4, 0xC0ED, 0x71F8, 0xC277,
+	0x71F9, 0xEFFB, 0x71FB, 0xC274, 0x71FC, 0xC275, 0x71FD, 0xEFFD,
+	0x71FE, 0xC276, 0x71FF, 0xEFFA, 0x7201, 0xEFF9, 0x7202, 0xF26C,
+	0x7203, 0xEFFC, 0x7205, 0xF26D, 0x7206, 0xC37A, 0x7207, 0xF26B,
+	0x720A, 0xF26A, 0x720C, 0xF269, 0x720D, 0xC37B, 0x7210, 0xC46C,
+	0x7213, 0xF46A, 0x7214, 0xF46B, 0x7219, 0xF5DC, 0x721A, 0xF5DB,
+	0x721B, 0xC4EA, 0x721D, 0xF5DA, 0x721E, 0xF6EC, 0x721F, 0xF6ED,
+	0x7222, 0xF7E6, 0x7223, 0xF8B1, 0x7226, 0xF8F6, 0x7227, 0xF9BC,
+	0x7228, 0xC679, 0x7229, 0xF9C6, 0x722A, 0xA4F6, 0x722C, 0xAAA6,
+	0x722D, 0xAAA7, 0x7230, 0xACB8, 0x7235, 0xC0EF, 0x7236, 0xA4F7,
+	0x7238, 0xAAA8, 0x7239, 0xAF52, 0x723A, 0xB7DD, 0x723B, 0xA4F8,
+	0x723D, 0xB26E, 0x723E, 0xBAB8, 0x723F, 0xC962, 0x7241, 0xCFB7,
+	0x7242, 0xD27D, 0x7244, 0xE2C5, 0x7246, 0xC0F0, 0x7247, 0xA4F9,
+	0x7248, 0xAAA9, 0x7249, 0xCFB8, 0x724A, 0xCFB9, 0x724B, 0xDA66,
+	0x724C, 0xB550, 0x724F, 0xDEA4, 0x7252, 0xB7DE, 0x7253, 0xE2C6,
+	0x7256, 0xBCF8, 0x7258, 0xC37C, 0x7259, 0xA4FA, 0x725A, 0xDA67,
+	0x725B, 0xA4FB, 0x725D, 0xA6C9, 0x725E, 0xCA42, 0x725F, 0xA6C8,
+	0x7260, 0xA865, 0x7261, 0xA864, 0x7262, 0xA863, 0x7263, 0xCB60,
+	0x7267, 0xAAAA, 0x7269, 0xAAAB, 0x726A, 0xCD5B, 0x726C, 0xCFBA,
+	0x726E, 0xCFBD, 0x726F, 0xACBA, 0x7270, 0xCFBB, 0x7272, 0xACB9,
+	0x7273, 0xCFBC, 0x7274, 0xACBB, 0x7276, 0xD2A2, 0x7277, 0xD2A1,
+	0x7278, 0xD27E, 0x7279, 0xAF53, 0x727B, 0xD65D, 0x727C, 0xD65E,
+	0x727D, 0xB26F, 0x727E, 0xD65C, 0x727F, 0xD65F, 0x7280, 0xB552,
+	0x7281, 0xB270, 0x7284, 0xB551, 0x7285, 0xDA6B, 0x7286, 0xDA6A,
+	0x7288, 0xDA68, 0x7289, 0xDA69, 0x728B, 0xDA6C, 0x728C, 0xDEA6,
+	0x728D, 0xDEA5, 0x728E, 0xDEA9, 0x7290, 0xDEA8, 0x7291, 0xDEA7,
+	0x7292, 0xBAB9, 0x7293, 0xE2C9, 0x7295, 0xE2C8, 0x7296, 0xBABA,
+	0x7297, 0xE2C7, 0x7298, 0xE673, 0x729A, 0xE674, 0x729B, 0xBCF9,
+	0x729D, 0xEA59, 0x729E, 0xEA5A, 0x72A1, 0xF272, 0x72A2, 0xC37D,
+	0x72A3, 0xF271, 0x72A4, 0xF270, 0x72A5, 0xF26E, 0x72A6, 0xF26F,
+	0x72A7, 0xC4EB, 0x72A8, 0xF46C, 0x72A9, 0xF6EE, 0x72AA, 0xF8F7,
+	0x72AC, 0xA4FC, 0x72AE, 0xC9A5, 0x72AF, 0xA5C7, 0x72B0, 0xC9A6,
+	0x72B4, 0xCA43, 0x72B5, 0xCA44, 0x72BA, 0xCB66, 0x72BD, 0xCB62,
+	0x72BF, 0xCB61, 0x72C0, 0xAAAC, 0x72C1, 0xCB65, 0x72C2, 0xA867,
+	0x72C3, 0xCB63, 0x72C4, 0xA866, 0x72C5, 0xCB67, 0x72C6, 0xCB64,
+	0x72C9, 0xCD5F, 0x72CA, 0xCFBE, 0x72CB, 0xCD5D, 0x72CC, 0xCD64,
+	0x72CE, 0xAAAD, 0x72D0, 0xAAB0, 0x72D1, 0xCD65, 0x72D2, 0xCD61,
+	0x72D4, 0xCD62, 0x72D6, 0xCD5C, 0x72D7, 0xAAAF, 0x72D8, 0xCD5E,
+	0x72D9, 0xAAAE, 0x72DA, 0xCD63, 0x72DC, 0xCD60, 0x72DF, 0xCFC2,
+	0x72E0, 0xACBD, 0x72E1, 0xACBE, 0x72E3, 0xCFC5, 0x72E4, 0xCFBF,
+	0x72E6, 0xCFC4, 0x72E8, 0xCFC0, 0x72E9, 0xACBC, 0x72EA, 0xCFC3,
+	0x72EB, 0xCFC1, 0x72F3, 0xD2A8, 0x72F4, 0xD2A5, 0x72F6, 0xD2A7,
+	0x72F7, 0xAF58, 0x72F8, 0xAF57, 0x72F9, 0xAF55, 0x72FA, 0xD2A4,
+	0x72FB, 0xD2A9, 0x72FC, 0xAF54, 0x72FD, 0xAF56, 0x72FE, 0xD2A6,
+	0x72FF, 0xD667, 0x7300, 0xD2A3, 0x7301, 0xD2AA, 0x7307, 0xD662,
+	0x7308, 0xD666, 0x730A, 0xD665, 0x730B, 0xDA6E, 0x730C, 0xDA79,
+	0x730F, 0xD668, 0x7311, 0xD663, 0x7312, 0xDA6D, 0x7313, 0xB274,
+	0x7316, 0xB273, 0x7317, 0xD661, 0x7318, 0xD664, 0x7319, 0xB275,
+	0x731B, 0xB272, 0x731C, 0xB271, 0x731D, 0xD660, 0x731E, 0xD669,
+	0x7322, 0xDA70, 0x7323, 0xDA77, 0x7325, 0xB554, 0x7326, 0xDA76,
+	0x7327, 0xDA73, 0x7329, 0xB556, 0x732D, 0xDA75, 0x7330, 0xDA6F,
+	0x7331, 0xDA71, 0x7332, 0xDA74, 0x7333, 0xDA72, 0x7334, 0xB555,
+	0x7335, 0xDA78, 0x7336, 0xB553, 0x7337, 0xB7DF, 0x733A, 0xDEAD,
+	0x733B, 0xDEAC, 0x733C, 0xDEAA, 0x733E, 0xB7E2, 0x733F, 0xB7E1,
+	0x7340, 0xDEAE, 0x7342, 0xDEAB, 0x7343, 0xE2CA, 0x7344, 0xBABB,
+	0x7345, 0xB7E0, 0x7349, 0xDEB0, 0x734A, 0xDEAF, 0x734C, 0xE2CD,
+	0x734D, 0xE2CB, 0x734E, 0xBCFA, 0x7350, 0xBABC, 0x7351, 0xE2CC,
+	0x7352, 0xE676, 0x7357, 0xBCFB, 0x7358, 0xE675, 0x7359, 0xE67E,
+	0x735A, 0xE67D, 0x735B, 0xE67B, 0x735D, 0xE67A, 0x735E, 0xE677,
+	0x735F, 0xE678, 0x7360, 0xE679, 0x7361, 0xE67C, 0x7362, 0xE6A1,
+	0x7365, 0xEA5F, 0x7366, 0xEA5C, 0x7367, 0xEA5D, 0x7368, 0xBF57,
+	0x7369, 0xEA5B, 0x736A, 0xEA61, 0x736B, 0xEA60, 0x736C, 0xEA5E,
+	0x736E, 0xED64, 0x736F, 0xED65, 0x7370, 0xC0F1, 0x7372, 0xC0F2,
+	0x7373, 0xED63, 0x7375, 0xC279, 0x7376, 0xEFFE, 0x7377, 0xC278,
+	0x7378, 0xC37E, 0x737A, 0xC3A1, 0x737B, 0xC46D, 0x737C, 0xF46E,
+	0x737D, 0xF46D, 0x737E, 0xF5DD, 0x737F, 0xF6EF, 0x7380, 0xC57A,
+	0x7381, 0xF7E8, 0x7382, 0xF7E7, 0x7383, 0xF7E9, 0x7384, 0xA5C8,
+	0x7385, 0xCFC6, 0x7386, 0xAF59, 0x7387, 0xB276, 0x7388, 0xD66A,
+	0x7389, 0xA5C9, 0x738A, 0xC9A7, 0x738B, 0xA4FD, 0x738E, 0xCA45,
+	0x7392, 0xCB6C, 0x7393, 0xCB6A, 0x7394, 0xCB6B, 0x7395, 0xCB68,
+	0x7396, 0xA868, 0x7397, 0xCB69, 0x739D, 0xCD6D, 0x739F, 0xAAB3,
+	0x73A0, 0xCD6B, 0x73A1, 0xCD67, 0x73A2, 0xCD6A, 0x73A4, 0xCD66,
+	0x73A5, 0xAAB5, 0x73A6, 0xCD69, 0x73A8, 0xAAB2, 0x73A9, 0xAAB1,
+	0x73AB, 0xAAB4, 0x73AC, 0xCD6C, 0x73AD, 0xCD68, 0x73B2, 0xACC2,
+	0x73B3, 0xACC5, 0x73B4, 0xCFCE, 0x73B5, 0xCFCD, 0x73B6, 0xCFCC,
+	0x73B7, 0xACBF, 0x73B8, 0xCFD5, 0x73B9, 0xCFCB, 0x73BB, 0xACC1,
+	0x73BC, 0xD2AF, 0x73BE, 0xCFD2, 0x73BF, 0xCFD0, 0x73C0, 0xACC4,
+	0x73C2, 0xCFC8, 0x73C3, 0xCFD3, 0x73C5, 0xCFCA, 0x73C6, 0xCFD4,
+	0x73C7, 0xCFD1, 0x73C8, 0xCFC9, 0x73CA, 0xACC0, 0x73CB, 0xCFD6,
+	0x73CC, 0xCFC7, 0x73CD, 0xACC3, 0x73D2, 0xD2B4, 0x73D3, 0xD2AB,
+	0x73D4, 0xD2B6, 0x73D6, 0xD2AE, 0x73D7, 0xD2B9, 0x73D8, 0xD2BA,
+	0x73D9, 0xD2AC, 0x73DA, 0xD2B8, 0x73DB, 0xD2B5, 0x73DC, 0xD2B3,
+	0x73DD, 0xD2B7, 0x73DE, 0xAF5F, 0x73E0, 0xAF5D, 0x73E3, 0xD2B1,
+	0x73E5, 0xD2AD, 0x73E7, 0xD2B0, 0x73E8, 0xD2BB, 0x73E9, 0xD2B2,
+	0x73EA, 0xAF5E, 0x73EB, 0xCFCF, 0x73ED, 0xAF5A, 0x73EE, 0xAF5C,
+	0x73F4, 0xD678, 0x73F5, 0xD66D, 0x73F6, 0xD66B, 0x73F8, 0xD66C,
+	0x73FA, 0xD673, 0x73FC, 0xD674, 0x73FD, 0xD670, 0x73FE, 0xB27B,
+	0x73FF, 0xD675, 0x7400, 0xD672, 0x7401, 0xD66F, 0x7403, 0xB279,
+	0x7404, 0xD66E, 0x7405, 0xB277, 0x7406, 0xB27A, 0x7407, 0xD671,
+	0x7408, 0xD679, 0x7409, 0xAF5B, 0x740A, 0xB278, 0x740B, 0xD677,
+	0x740C, 0xD676, 0x740D, 0xB27C, 0x7416, 0xDA7E, 0x741A, 0xDAA1,
+	0x741B, 0xB560, 0x741D, 0xDAA7, 0x7420, 0xDAA9, 0x7421, 0xDAA2,
+	0x7422, 0xB55A, 0x7423, 0xDAA6, 0x7424, 0xDAA5, 0x7425, 0xB55B,
+	0x7426, 0xB561, 0x7428, 0xB562, 0x7429, 0xDAA8, 0x742A, 0xB558,
+	0x742B, 0xDA7D, 0x742C, 0xDA7B, 0x742D, 0xDAA3, 0x742E, 0xDA7A,
+	0x742F, 0xB55F, 0x7430, 0xDA7C, 0x7431, 0xDAA4, 0x7432, 0xDAAA,
+	0x7433, 0xB559, 0x7434, 0xB55E, 0x7435, 0xB55C, 0x7436, 0xB55D,
+	0x743A, 0xB557, 0x743F, 0xB7E9, 0x7440, 0xDEB7, 0x7441, 0xB7E8,
+	0x7442, 0xDEBB, 0x7444, 0xDEB1, 0x7446, 0xDEBC, 0x744A, 0xDEB2,
+	0x744B, 0xDEB3, 0x744D, 0xDEBD, 0x744E, 0xDEBA, 0x744F, 0xDEB8,
+	0x7450, 0xDEB9, 0x7451, 0xDEB5, 0x7452, 0xDEB4, 0x7454, 0xDEBE,
+	0x7455, 0xB7E5, 0x7457, 0xDEB6, 0x7459, 0xB7EA, 0x745A, 0xB7E4,
+	0x745B, 0xB7EB, 0x745C, 0xB7EC, 0x745E, 0xB7E7, 0x745F, 0xB7E6,
+	0x7462, 0xE2CE, 0x7463, 0xBABE, 0x7464, 0xBABD, 0x7467, 0xE2D3,
+	0x7469, 0xBCFC, 0x746A, 0xBABF, 0x746D, 0xBAC1, 0x746E, 0xE2D4,
+	0x746F, 0xB7E3, 0x7470, 0xBAC0, 0x7471, 0xE2D0, 0x7472, 0xE2D2,
+	0x7473, 0xE2CF, 0x7475, 0xE2D1, 0x7479, 0xE6AB, 0x747C, 0xE6AA,
+	0x747D, 0xE6A7, 0x747E, 0xBD40, 0x747F, 0xEA62, 0x7480, 0xBD41,
+	0x7481, 0xE6A6, 0x7483, 0xBCFE, 0x7485, 0xE6A8, 0x7486, 0xE6A5,
+	0x7487, 0xE6A2, 0x7488, 0xE6A9, 0x7489, 0xE6A3, 0x748A, 0xE6A4,
+	0x748B, 0xBCFD, 0x7490, 0xED69, 0x7492, 0xEA66, 0x7494, 0xEA65,
+	0x7495, 0xEA67, 0x7497, 0xED66, 0x7498, 0xBF5A, 0x749A, 0xEA63,
+	0x749C, 0xBF58, 0x749E, 0xBF5C, 0x749F, 0xBF5B, 0x74A0, 0xEA64,
+	0x74A1, 0xEA68, 0x74A3, 0xBF59, 0x74A5, 0xED6D, 0x74A6, 0xC0F5,
+	0x74A7, 0xC27A, 0x74A8, 0xC0F6, 0x74A9, 0xC0F3, 0x74AA, 0xED6A,
+	0x74AB, 0xED68, 0x74AD, 0xED6B, 0x74AF, 0xED6E, 0x74B0, 0xC0F4,
+	0x74B1, 0xED6C, 0x74B2, 0xED67, 0x74B5, 0xF042, 0x74B6, 0xF045,
+	0x74B7, 0xF275, 0x74B8, 0xF040, 0x74BA, 0xF46F, 0x74BB, 0xF046,
+	0x74BD, 0xC3A2, 0x74BE, 0xF044, 0x74BF, 0xC27B, 0x74C0, 0xF041,
+	0x74C1, 0xF043, 0x74C2, 0xF047, 0x74C3, 0xF276, 0x74C5, 0xF274,
+	0x74CA, 0xC3A3, 0x74CB, 0xF273, 0x74CF, 0xC46E, 0x74D4, 0xC4ED,
+	0x74D5, 0xF6F1, 0x74D6, 0xC4EC, 0x74D7, 0xF6F3, 0x74D8, 0xF6F0,
+	0x74D9, 0xF6F2, 0x74DA, 0xC5D0, 0x74DB, 0xF8B2, 0x74DC, 0xA5CA,
+	0x74DD, 0xCD6E, 0x74DE, 0xD2BC, 0x74DF, 0xD2BD, 0x74E0, 0xB27D,
+	0x74E1, 0xDEBF, 0x74E2, 0xBF5D, 0x74E3, 0xC3A4, 0x74E4, 0xC57B,
+	0x74E5, 0xF8B3, 0x74E6, 0xA5CB, 0x74E8, 0xCD6F, 0x74E9, 0xA260,
+	0x74EC, 0xCFD7, 0x74EE, 0xCFD8, 0x74F4, 0xD2BE, 0x74F5, 0xD2BF,
+	0x74F6, 0xB27E, 0x74F7, 0xB2A1, 0x74FB, 0xDAAB, 0x74FD, 0xDEC2,
+	0x74FE, 0xDEC1, 0x74FF, 0xDEC0, 0x7500, 0xE2D5, 0x7502, 0xE2D6,
+	0x7503, 0xE2D7, 0x7504, 0xBAC2, 0x7507, 0xE6AD, 0x7508, 0xE6AC,
+	0x750B, 0xEA69, 0x750C, 0xBF5E, 0x750D, 0xBF5F, 0x750F, 0xED72,
+	0x7510, 0xED6F, 0x7511, 0xED70, 0x7512, 0xED71, 0x7513, 0xF049,
+	0x7514, 0xF048, 0x7515, 0xC27C, 0x7516, 0xF277, 0x7517, 0xF5DE,
+	0x7518, 0xA5CC, 0x751A, 0xACC6, 0x751C, 0xB2A2, 0x751D, 0xDEC3,
+	0x751F, 0xA5CD, 0x7521, 0xD2C0, 0x7522, 0xB2A3, 0x7525, 0xB563,
+	0x7526, 0xB564, 0x7528, 0xA5CE, 0x7529, 0xA5CF, 0x752A, 0xCA46,
+	0x752B, 0xA86A, 0x752C, 0xA869, 0x752D, 0xACC7, 0x752E, 0xCFD9,
+	0x752F, 0xDAAC, 0x7530, 0xA5D0, 0x7531, 0xA5D1, 0x7532, 0xA5D2,
+	0x7533, 0xA5D3, 0x7537, 0xA86B, 0x7538, 0xA86C, 0x7539, 0xCB6E,
+	0x753A, 0xCB6D, 0x753D, 0xAAB6, 0x753E, 0xCD72, 0x753F, 0xCD70,
+	0x7540, 0xCD71, 0x7547, 0xCFDA, 0x7548, 0xCFDB, 0x754B, 0xACCB,
+	0x754C, 0xACC9, 0x754E, 0xACCA, 0x754F, 0xACC8, 0x7554, 0xAF60,
+	0x7559, 0xAF64, 0x755A, 0xAF63, 0x755B, 0xD2C1, 0x755C, 0xAF62,
+	0x755D, 0xAF61, 0x755F, 0xD2C2, 0x7562, 0xB2A6, 0x7563, 0xD67B,
+	0x7564, 0xD67A, 0x7565, 0xB2A4, 0x7566, 0xB2A5, 0x756A, 0xB566,
+	0x756B, 0xB565, 0x756C, 0xDAAE, 0x756F, 0xDAAD, 0x7570, 0xB2A7,
+	0x7576, 0xB7ED, 0x7577, 0xDEC5, 0x7578, 0xB7EE, 0x7579, 0xDEC4,
+	0x757D, 0xE2D8, 0x757E, 0xE6AE, 0x757F, 0xBD42, 0x7580, 0xEA6A,
+	0x7584, 0xED73, 0x7586, 0xC3A6, 0x7587, 0xC3A5, 0x758A, 0xC57C,
+	0x758B, 0xA5D4, 0x758C, 0xCD73, 0x758F, 0xB2A8, 0x7590, 0xE2D9,
+	0x7591, 0xBAC3, 0x7594, 0xCB6F, 0x7595, 0xCB70, 0x7598, 0xCD74,
+	0x7599, 0xAAB8, 0x759A, 0xAAB9, 0x759D, 0xAAB7, 0x75A2, 0xACCF,
+	0x75A3, 0xACD0, 0x75A4, 0xACCD, 0x75A5, 0xACCE, 0x75A7, 0xCFDC,
+	0x75AA, 0xCFDD, 0x75AB, 0xACCC, 0x75B0, 0xD2C3, 0x75B2, 0xAF68,
+	0x75B3, 0xAF69, 0x75B5, 0xB2AB, 0x75B6, 0xD2C9, 0x75B8, 0xAF6E,
+	0x75B9, 0xAF6C, 0x75BA, 0xD2CA, 0x75BB, 0xD2C5, 0x75BC, 0xAF6B,
+	0x75BD, 0xAF6A, 0x75BE, 0xAF65, 0x75BF, 0xD2C8, 0x75C0, 0xD2C7,
+	0x75C1, 0xD2C4, 0x75C2, 0xAF6D, 0x75C4, 0xD2C6, 0x75C5, 0xAF66,
+	0x75C7, 0xAF67, 0x75CA, 0xB2AC, 0x75CB, 0xD6A1, 0x75CC, 0xD6A2,
+	0x75CD, 0xB2AD, 0x75CE, 0xD67C, 0x75CF, 0xD67E, 0x75D0, 0xD6A4,
+	0x75D1, 0xD6A3, 0x75D2, 0xD67D, 0x75D4, 0xB2A9, 0x75D5, 0xB2AA,
+	0x75D7, 0xDAB6, 0x75D8, 0xB56B, 0x75D9, 0xB56A, 0x75DA, 0xDAB0,
+	0x75DB, 0xB568, 0x75DD, 0xDAB3, 0x75DE, 0xB56C, 0x75DF, 0xDAB4,
+	0x75E0, 0xB56D, 0x75E1, 0xDAB1, 0x75E2, 0xB567, 0x75E3, 0xB569,
+	0x75E4, 0xDAB5, 0x75E6, 0xDAB2, 0x75E7, 0xDAAF, 0x75ED, 0xDED2,
+	0x75EF, 0xDEC7, 0x75F0, 0xB7F0, 0x75F1, 0xB7F3, 0x75F2, 0xB7F2,
+	0x75F3, 0xB7F7, 0x75F4, 0xB7F6, 0x75F5, 0xDED3, 0x75F6, 0xDED1,
+	0x75F7, 0xDECA, 0x75F8, 0xDECE, 0x75F9, 0xDECD, 0x75FA, 0xB7F4,
+	0x75FB, 0xDED0, 0x75FC, 0xDECC, 0x75FD, 0xDED4, 0x75FE, 0xDECB,
+	0x75FF, 0xB7F5, 0x7600, 0xB7EF, 0x7601, 0xB7F1, 0x7603, 0xDEC9,
+	0x7608, 0xE2DB, 0x7609, 0xBAC7, 0x760A, 0xE2DF, 0x760B, 0xBAC6,
+	0x760C, 0xE2DC, 0x760D, 0xBAC5, 0x760F, 0xDEC8, 0x7610, 0xDECF,
+	0x7611, 0xE2DE, 0x7613, 0xBAC8, 0x7614, 0xE2E0, 0x7615, 0xE2DD,
+	0x7616, 0xE2DA, 0x7619, 0xE6B1, 0x761A, 0xE6B5, 0x761B, 0xE6B7,
+	0x761C, 0xE6B3, 0x761D, 0xE6B2, 0x761E, 0xE6B0, 0x761F, 0xBD45,
+	0x7620, 0xBD43, 0x7621, 0xBD48, 0x7622, 0xBD49, 0x7623, 0xE6B4,
+	0x7624, 0xBD46, 0x7625, 0xE6AF, 0x7626, 0xBD47, 0x7627, 0xBAC4,
+	0x7628, 0xE6B6, 0x7629, 0xBD44, 0x762D, 0xEA6C, 0x762F, 0xEA6B,
+	0x7630, 0xEA73, 0x7631, 0xEA6D, 0x7632, 0xEA72, 0x7633, 0xEA6F,
+	0x7634, 0xBF60, 0x7635, 0xEA71, 0x7638, 0xBF61, 0x763A, 0xBF62,
+	0x763C, 0xEA70, 0x763D, 0xEA6E, 0x7642, 0xC0F8, 0x7643, 0xED74,
+	0x7646, 0xC0F7, 0x7647, 0xED77, 0x7648, 0xED75, 0x7649, 0xED76,
+	0x764C, 0xC0F9, 0x7650, 0xF04D, 0x7652, 0xC2A1, 0x7653, 0xF04E,
+	0x7656, 0xC27D, 0x7657, 0xF04F, 0x7658, 0xC27E, 0x7659, 0xF04C,
+	0x765A, 0xF050, 0x765C, 0xF04A, 0x765F, 0xC3A7, 0x7660, 0xF278,
+	0x7661, 0xC3A8, 0x7662, 0xC46F, 0x7664, 0xF04B, 0x7665, 0xC470,
+	0x7669, 0xC4EE, 0x766A, 0xF5DF, 0x766C, 0xC57E, 0x766D, 0xF6F4,
+	0x766E, 0xC57D, 0x7670, 0xF7EA, 0x7671, 0xC5F5, 0x7672, 0xC5F6,
+	0x7675, 0xF9CC, 0x7678, 0xACD1, 0x7679, 0xCFDE, 0x767B, 0xB56E,
+	0x767C, 0xB56F, 0x767D, 0xA5D5, 0x767E, 0xA6CA, 0x767F, 0xCA47,
+	0x7681, 0xCB71, 0x7682, 0xA86D, 0x7684, 0xAABA, 0x7686, 0xACD2,
+	0x7687, 0xACD3, 0x7688, 0xACD4, 0x7689, 0xD6A6, 0x768A, 0xD2CB,
+	0x768B, 0xAF6F, 0x768E, 0xB2AE, 0x768F, 0xD6A5, 0x7692, 0xDAB8,
+	0x7693, 0xB571, 0x7695, 0xDAB7, 0x7696, 0xB570, 0x7699, 0xDED5,
+	0x769A, 0xBD4A, 0x769B, 0xE6BB, 0x769C, 0xE6B8, 0x769D, 0xE6B9,
+	0x769E, 0xE6BA, 0x76A4, 0xED78, 0x76A6, 0xF051, 0x76AA, 0xF471,
+	0x76AB, 0xF470, 0x76AD, 0xF6F5, 0x76AE, 0xA5D6, 0x76AF, 0xCD75,
+	0x76B0, 0xAF70, 0x76B4, 0xB572, 0x76B5, 0xDED6, 0x76B8, 0xE2E1,
+	0x76BA, 0xBD4B, 0x76BB, 0xEA74, 0x76BD, 0xF052, 0x76BE, 0xF472,
+	0x76BF, 0xA5D7, 0x76C2, 0xAABB, 0x76C3, 0xACD7, 0x76C4, 0xCFDF,
+	0x76C5, 0xACD8, 0x76C6, 0xACD6, 0x76C8, 0xACD5, 0x76C9, 0xD2CC,
+	0x76CA, 0xAF71, 0x76CD, 0xAF72, 0x76CE, 0xAF73, 0x76D2, 0xB2B0,
+	0x76D3, 0xD6A7, 0x76D4, 0xB2AF, 0x76DA, 0xDAB9, 0x76DB, 0xB2B1,
+	0x76DC, 0xB573, 0x76DD, 0xDED7, 0x76DE, 0xB7F8, 0x76DF, 0xB7F9,
+	0x76E1, 0xBAC9, 0x76E3, 0xBACA, 0x76E4, 0xBD4C, 0x76E5, 0xBF64,
+	0x76E6, 0xEA75, 0x76E7, 0xBF63, 0x76E9, 0xED79, 0x76EA, 0xC0FA,
+	0x76EC, 0xF053, 0x76ED, 0xF473, 0x76EE, 0xA5D8, 0x76EF, 0xA86E,
+	0x76F0, 0xCD78, 0x76F1, 0xCD77, 0x76F2, 0xAABC, 0x76F3, 0xCD76,
+	0x76F4, 0xAABD, 0x76F5, 0xCD79, 0x76F7, 0xCFE5, 0x76F8, 0xACDB,
+	0x76F9, 0xACDA, 0x76FA, 0xCFE7, 0x76FB, 0xCFE6, 0x76FC, 0xACDF,
+	0x76FE, 0xACDE, 0x7701, 0xACD9, 0x7703, 0xCFE1, 0x7704, 0xCFE2,
+	0x7705, 0xCFE3, 0x7707, 0xACE0, 0x7708, 0xCFE0, 0x7709, 0xACDC,
+	0x770A, 0xCFE4, 0x770B, 0xACDD, 0x7710, 0xD2CF, 0x7711, 0xD2D3,
+	0x7712, 0xD2D1, 0x7713, 0xD2D0, 0x7715, 0xD2D4, 0x7719, 0xD2D5,
+	0x771A, 0xD2D6, 0x771B, 0xD2CE, 0x771D, 0xD2CD, 0x771F, 0xAF75,
+	0x7720, 0xAF76, 0x7722, 0xD2D7, 0x7723, 0xD2D2, 0x7725, 0xD6B0,
+	0x7727, 0xD2D8, 0x7728, 0xAF77, 0x7729, 0xAF74, 0x772D, 0xD6AA,
+	0x772F, 0xD6A9, 0x7731, 0xD6AB, 0x7732, 0xD6AC, 0x7733, 0xD6AE,
+	0x7734, 0xD6AD, 0x7735, 0xD6B2, 0x7736, 0xB2B5, 0x7737, 0xB2B2,
+	0x7738, 0xB2B6, 0x7739, 0xD6A8, 0x773A, 0xB2B7, 0x773B, 0xD6B1,
+	0x773C, 0xB2B4, 0x773D, 0xD6AF, 0x773E, 0xB2B3, 0x7744, 0xDABC,
+	0x7745, 0xDABE, 0x7746, 0xDABA, 0x7747, 0xDABB, 0x774A, 0xDABF,
+	0x774B, 0xDAC1, 0x774C, 0xDAC2, 0x774D, 0xDABD, 0x774E, 0xDAC0,
+	0x774F, 0xB574, 0x7752, 0xDEDB, 0x7754, 0xDEE0, 0x7755, 0xDED8,
+	0x7756, 0xDEDC, 0x7759, 0xDEE1, 0x775A, 0xDEDD, 0x775B, 0xB7FA,
+	0x775C, 0xB843, 0x775E, 0xB7FD, 0x775F, 0xDED9, 0x7760, 0xDEDA,
+	0x7761, 0xBACE, 0x7762, 0xB846, 0x7763, 0xB7FE, 0x7765, 0xB844,
+	0x7766, 0xB7FC, 0x7767, 0xDEDF, 0x7768, 0xB845, 0x7769, 0xDEDE,
+	0x776A, 0xB841, 0x776B, 0xB7FB, 0x776C, 0xB842, 0x776D, 0xDEE2,
+	0x776E, 0xE2E6, 0x776F, 0xE2E8, 0x7779, 0xB840, 0x777C, 0xE2E3,
+	0x777D, 0xBACC, 0x777E, 0xE2E9, 0x777F, 0xBACD, 0x7780, 0xE2E7,
+	0x7781, 0xE2E2, 0x7782, 0xE2E5, 0x7783, 0xE2EA, 0x7784, 0xBACB,
+	0x7785, 0xE2E4, 0x7787, 0xBD4E, 0x7788, 0xE6BF, 0x7789, 0xE6BE,
+	0x778B, 0xBD51, 0x778C, 0xBD4F, 0x778D, 0xE6BC, 0x778E, 0xBD4D,
+	0x778F, 0xE6BD, 0x7791, 0xBD50, 0x7795, 0xEA7D, 0x7797, 0xEAA1,
+	0x7799, 0xEA7E, 0x779A, 0xEA76, 0x779B, 0xEA7A, 0x779C, 0xEA79,
+	0x779D, 0xEA77, 0x779E, 0xBF66, 0x779F, 0xBF67, 0x77A0, 0xBF65,
+	0x77A1, 0xEA78, 0x77A2, 0xEA7B, 0x77A3, 0xEA7C, 0x77A5, 0xBF68,
+	0x77A7, 0xC140, 0x77A8, 0xEDA3, 0x77AA, 0xC0FC, 0x77AB, 0xED7B,
+	0x77AC, 0xC0FE, 0x77AD, 0xC141, 0x77B0, 0xC0FD, 0x77B1, 0xEDA2,
+	0x77B2, 0xED7C, 0x77B3, 0xC0FB, 0x77B4, 0xEDA1, 0x77B5, 0xED7A,
+	0x77B6, 0xED7E, 0x77B7, 0xED7D, 0x77BA, 0xF055, 0x77BB, 0xC2A4,
+	0x77BC, 0xC2A5, 0x77BD, 0xC2A2, 0x77BF, 0xC2A3, 0x77C2, 0xF054,
+	0x77C4, 0xF27B, 0x77C7, 0xC3A9, 0x77C9, 0xF279, 0x77CA, 0xF27A,
+	0x77CC, 0xF474, 0x77CD, 0xF477, 0x77CE, 0xF475, 0x77CF, 0xF476,
+	0x77D0, 0xF5E0, 0x77D3, 0xC4EF, 0x77D4, 0xF7EB, 0x77D5, 0xF8B4,
+	0x77D7, 0xC5F7, 0x77D8, 0xF8F8, 0x77D9, 0xF8F9, 0x77DA, 0xC666,
+	0x77DB, 0xA5D9, 0x77DC, 0xACE1, 0x77DE, 0xDAC3, 0x77E0, 0xDEE3,
+	0x77E2, 0xA5DA, 0x77E3, 0xA86F, 0x77E5, 0xAABE, 0x77E7, 0xCFE8,
+	0x77E8, 0xCFE9, 0x77E9, 0xAF78, 0x77EC, 0xDAC4, 0x77ED, 0xB575,
+	0x77EE, 0xB847, 0x77EF, 0xC142, 0x77F0, 0xEDA4, 0x77F1, 0xF27C,
+	0x77F2, 0xF478, 0x77F3, 0xA5DB, 0x77F7, 0xCDA1, 0x77F8, 0xCD7A,
+	0x77F9, 0xCD7C, 0x77FA, 0xCD7E, 0x77FB, 0xCD7D, 0x77FC, 0xCD7B,
+	0x77FD, 0xAABF, 0x7802, 0xACE2, 0x7803, 0xCFF2, 0x7805, 0xCFED,
+	0x7806, 0xCFEA, 0x7809, 0xCFF1, 0x780C, 0xACE4, 0x780D, 0xACE5,
+	0x780E, 0xCFF0, 0x780F, 0xCFEF, 0x7810, 0xCFEE, 0x7811, 0xCFEB,
+	0x7812, 0xCFEC, 0x7813, 0xCFF3, 0x7814, 0xACE3, 0x781D, 0xAF7C,
+	0x781F, 0xAFA4, 0x7820, 0xAFA3, 0x7821, 0xD2E1, 0x7822, 0xD2DB,
+	0x7823, 0xD2D9, 0x7825, 0xAFA1, 0x7826, 0xD6B9, 0x7827, 0xAF7A,
+	0x7828, 0xD2DE, 0x7829, 0xD2E2, 0x782A, 0xD2E4, 0x782B, 0xD2E0,
+	0x782C, 0xD2DA, 0x782D, 0xAFA2, 0x782E, 0xD2DF, 0x782F, 0xD2DD,
+	0x7830, 0xAF79, 0x7831, 0xD2E5, 0x7832, 0xAFA5, 0x7833, 0xD2E3,
+	0x7834, 0xAF7D, 0x7835, 0xD2DC, 0x7837, 0xAF7E, 0x7838, 0xAF7B,
+	0x7843, 0xB2B9, 0x7845, 0xD6BA, 0x7848, 0xD6B3, 0x7849, 0xD6B5,
+	0x784A, 0xD6B7, 0x784C, 0xD6B8, 0x784D, 0xD6B6, 0x784E, 0xB2BA,
+	0x7850, 0xD6BB, 0x7852, 0xD6B4, 0x785C, 0xDAC8, 0x785D, 0xB576,
+	0x785E, 0xDAD0, 0x7860, 0xDAC5, 0x7862, 0xDAD1, 0x7864, 0xDAC6,
+	0x7865, 0xDAC7, 0x7868, 0xDACF, 0x7869, 0xDACE, 0x786A, 0xDACB,
+	0x786B, 0xB2B8, 0x786C, 0xB577, 0x786D, 0xDAC9, 0x786E, 0xDACC,
+	0x786F, 0xB578, 0x7870, 0xDACD, 0x7871, 0xDACA, 0x7879, 0xDEEE,
+	0x787B, 0xDEF2, 0x787C, 0xB84E, 0x787E, 0xE2F0, 0x787F, 0xB851,
+	0x7880, 0xDEF0, 0x7881, 0xF9D6, 0x7883, 0xDEED, 0x7884, 0xDEE8,
+	0x7885, 0xDEEA, 0x7886, 0xDEEB, 0x7887, 0xDEE4, 0x7889, 0xB84D,
+	0x788C, 0xB84C, 0x788E, 0xB848, 0x788F, 0xDEE7, 0x7891, 0xB84F,
+	0x7893, 0xB850, 0x7894, 0xDEE6, 0x7895, 0xDEE9, 0x7896, 0xDEF1,
+	0x7897, 0xB84A, 0x7898, 0xB84B, 0x7899, 0xDEEF, 0x789A, 0xDEE5,
+	0x789E, 0xE2F2, 0x789F, 0xBAD0, 0x78A0, 0xE2F4, 0x78A1, 0xDEEC,
+	0x78A2, 0xE2F6, 0x78A3, 0xBAD4, 0x78A4, 0xE2F7, 0x78A5, 0xE2F3,
+	0x78A7, 0xBAD1, 0x78A8, 0xE2EF, 0x78A9, 0xBAD3, 0x78AA, 0xE2EC,
+	0x78AB, 0xE2F1, 0x78AC, 0xE2F5, 0x78AD, 0xE2EE, 0x78B0, 0xB849,
+	0x78B2, 0xE2EB, 0x78B3, 0xBAD2, 0x78B4, 0xE2ED, 0x78BA, 0xBD54,
+	0x78BB, 0xE6C1, 0x78BC, 0xBD58, 0x78BE, 0xBD56, 0x78C1, 0xBACF,
+	0x78C3, 0xE6C8, 0x78C4, 0xE6C9, 0x78C5, 0xBD53, 0x78C8, 0xE6C7,
+	0x78C9, 0xE6CA, 0x78CA, 0xBD55, 0x78CB, 0xBD52, 0x78CC, 0xE6C3,
+	0x78CD, 0xE6C0, 0x78CE, 0xE6C5, 0x78CF, 0xE6C2, 0x78D0, 0xBD59,
+	0x78D1, 0xE6C4, 0x78D4, 0xE6C6, 0x78D5, 0xBD57, 0x78DA, 0xBF6A,
+	0x78DB, 0xEAA8, 0x78DD, 0xEAA2, 0x78DE, 0xEAA6, 0x78DF, 0xEAAC,
+	0x78E0, 0xEAAD, 0x78E1, 0xEAA9, 0x78E2, 0xEAAA, 0x78E3, 0xEAA7,
+	0x78E5, 0xEAA4, 0x78E7, 0xBF6C, 0x78E8, 0xBF69, 0x78E9, 0xEAA3,
+	0x78EA, 0xEAA5, 0x78EC, 0xBF6B, 0x78ED, 0xEAAB, 0x78EF, 0xC146,
+	0x78F2, 0xEDAA, 0x78F3, 0xEDA5, 0x78F4, 0xC145, 0x78F7, 0xC143,
+	0x78F9, 0xEDAC, 0x78FA, 0xC144, 0x78FB, 0xEDA8, 0x78FC, 0xEDA9,
+	0x78FD, 0xEDA6, 0x78FE, 0xEDAD, 0x78FF, 0xF056, 0x7901, 0xC147,
+	0x7902, 0xEDA7, 0x7904, 0xEDAE, 0x7905, 0xEDAB, 0x7909, 0xF05A,
+	0x790C, 0xF057, 0x790E, 0xC2A6, 0x7910, 0xF05B, 0x7911, 0xF05D,
+	0x7912, 0xF05C, 0x7913, 0xF058, 0x7914, 0xF059, 0x7917, 0xF2A3,
+	0x7919, 0xC3AA, 0x791B, 0xF27E, 0x791C, 0xF2A2, 0x791D, 0xF27D,
+	0x791E, 0xF2A4, 0x7921, 0xF2A1, 0x7923, 0xF47A, 0x7924, 0xF47D,
+	0x7925, 0xF479, 0x7926, 0xC471, 0x7927, 0xF47B, 0x7928, 0xF47C,
+	0x7929, 0xF47E, 0x792A, 0xC472, 0x792B, 0xC474, 0x792C, 0xC473,
+	0x792D, 0xF5E1, 0x792F, 0xF5E3, 0x7931, 0xF5E2, 0x7935, 0xF6F6,
+	0x7938, 0xF8B5, 0x7939, 0xF8FA, 0x793A, 0xA5DC, 0x793D, 0xCB72,
+	0x793E, 0xAAC0, 0x793F, 0xCDA3, 0x7940, 0xAAC1, 0x7941, 0xAAC2,
+	0x7942, 0xCDA2, 0x7944, 0xCFF8, 0x7945, 0xCFF7, 0x7946, 0xACE6,
+	0x7947, 0xACE9, 0x7948, 0xACE8, 0x7949, 0xACE7, 0x794A, 0xCFF4,
+	0x794B, 0xCFF6, 0x794C, 0xCFF5, 0x794F, 0xD2E8, 0x7950, 0xAFA7,
+	0x7951, 0xD2EC, 0x7952, 0xD2EB, 0x7953, 0xD2EA, 0x7954, 0xD2E6,
+	0x7955, 0xAFA6, 0x7956, 0xAFAA, 0x7957, 0xAFAD, 0x795A, 0xAFAE,
+	0x795B, 0xD2E7, 0x795C, 0xD2E9, 0x795D, 0xAFAC, 0x795E, 0xAFAB,
+	0x795F, 0xAFA9, 0x7960, 0xAFA8, 0x7961, 0xD6C2, 0x7963, 0xD6C0,
+	0x7964, 0xD6BC, 0x7965, 0xB2BB, 0x7967, 0xD6BD, 0x7968, 0xB2BC,
+	0x7969, 0xD6BE, 0x796A, 0xD6BF, 0x796B, 0xD6C1, 0x796D, 0xB2BD,
+	0x7970, 0xDAD5, 0x7972, 0xDAD4, 0x7973, 0xDAD3, 0x7974, 0xDAD2,
+	0x7979, 0xDEF6, 0x797A, 0xB852, 0x797C, 0xDEF3, 0x797D, 0xDEF5,
+	0x797F, 0xB853, 0x7981, 0xB854, 0x7982, 0xDEF4, 0x7988, 0xE341,
+	0x798A, 0xE2F9, 0x798B, 0xE2FA, 0x798D, 0xBAD7, 0x798E, 0xBAD5,
+	0x798F, 0xBAD6, 0x7990, 0xE343, 0x7992, 0xE342, 0x7993, 0xE2FE,
+	0x7994, 0xE2FD, 0x7995, 0xE2FC, 0x7996, 0xE2FB, 0x7997, 0xE340,
+	0x7998, 0xE2F8, 0x799A, 0xE6CB, 0x799B, 0xE6D0, 0x799C, 0xE6CE,
+	0x79A0, 0xE6CD, 0x79A1, 0xE6CC, 0x79A2, 0xE6CF, 0x79A4, 0xEAAE,
+	0x79A6, 0xBF6D, 0x79A7, 0xC148, 0x79A8, 0xEDB0, 0x79AA, 0xC149,
+	0x79AB, 0xEDAF, 0x79AC, 0xF05F, 0x79AD, 0xF05E, 0x79AE, 0xC2A7,
+	0x79B0, 0xF2A5, 0x79B1, 0xC3AB, 0x79B2, 0xF4A1, 0x79B3, 0xC5A1,
+	0x79B4, 0xF6F7, 0x79B6, 0xF8B7, 0x79B7, 0xF8B6, 0x79B8, 0xC9A8,
+	0x79B9, 0xACEA, 0x79BA, 0xACEB, 0x79BB, 0xD6C3, 0x79BD, 0xB856,
+	0x79BE, 0xA5DD, 0x79BF, 0xA872, 0x79C0, 0xA871, 0x79C1, 0xA870,
+	0x79C5, 0xCDA4, 0x79C8, 0xAAC4, 0x79C9, 0xAAC3, 0x79CB, 0xACEE,
+	0x79CD, 0xCFFA, 0x79CE, 0xCFFD, 0x79CF, 0xCFFB, 0x79D1, 0xACEC,
+	0x79D2, 0xACED, 0x79D5, 0xCFF9, 0x79D6, 0xCFFC, 0x79D8, 0xAFB5,
+	0x79DC, 0xD2F3, 0x79DD, 0xD2F5, 0x79DE, 0xD2F4, 0x79DF, 0xAFB2,
+	0x79E0, 0xD2EF, 0x79E3, 0xAFB0, 0x79E4, 0xAFAF, 0x79E6, 0xAFB3,
+	0x79E7, 0xAFB1, 0x79E9, 0xAFB4, 0x79EA, 0xD2F2, 0x79EB, 0xD2ED,
+	0x79EC, 0xD2EE, 0x79ED, 0xD2F1, 0x79EE, 0xD2F0, 0x79F6, 0xD6C6,
+	0x79F7, 0xD6C7, 0x79F8, 0xD6C5, 0x79FA, 0xD6C4, 0x79FB, 0xB2BE,
+	0x7A00, 0xB57D, 0x7A02, 0xDAD6, 0x7A03, 0xDAD8, 0x7A04, 0xDADA,
+	0x7A05, 0xB57C, 0x7A08, 0xB57A, 0x7A0A, 0xDAD7, 0x7A0B, 0xB57B,
+	0x7A0C, 0xDAD9, 0x7A0D, 0xB579, 0x7A10, 0xDF41, 0x7A11, 0xDEF7,
+	0x7A12, 0xDEFA, 0x7A13, 0xDEFE, 0x7A14, 0xB85A, 0x7A15, 0xDEFC,
+	0x7A17, 0xDEFB, 0x7A18, 0xDEF8, 0x7A19, 0xDEF9, 0x7A1A, 0xB858,
+	0x7A1B, 0xDF40, 0x7A1C, 0xB857, 0x7A1E, 0xB85C, 0x7A1F, 0xB85B,
+	0x7A20, 0xB859, 0x7A22, 0xDEFD, 0x7A26, 0xE349, 0x7A28, 0xE348,
+	0x7A2B, 0xE344, 0x7A2E, 0xBAD8, 0x7A2F, 0xE347, 0x7A30, 0xE346,
+	0x7A31, 0xBAD9, 0x7A37, 0xBD5E, 0x7A39, 0xE6D2, 0x7A3B, 0xBD5F,
+	0x7A3C, 0xBD5B, 0x7A3D, 0xBD5D, 0x7A3F, 0xBD5A, 0x7A40, 0xBD5C,
+	0x7A44, 0xEAAF, 0x7A46, 0xBF70, 0x7A47, 0xEAB1, 0x7A48, 0xEAB0,
+	0x7A4A, 0xE345, 0x7A4B, 0xBF72, 0x7A4C, 0xBF71, 0x7A4D, 0xBF6E,
+	0x7A4E, 0xBF6F, 0x7A54, 0xEDB5, 0x7A56, 0xEDB3, 0x7A57, 0xC14A,
+	0x7A58, 0xEDB4, 0x7A5A, 0xEDB6, 0x7A5B, 0xEDB2, 0x7A5C, 0xEDB1,
+	0x7A5F, 0xF060, 0x7A60, 0xC2AA, 0x7A61, 0xC2A8, 0x7A62, 0xC2A9,
+	0x7A67, 0xF2A6, 0x7A68, 0xF2A7, 0x7A69, 0xC3AD, 0x7A6B, 0xC3AC,
+	0x7A6C, 0xF4A3, 0x7A6D, 0xF4A4, 0x7A6E, 0xF4A2, 0x7A70, 0xF6F8,
+	0x7A71, 0xF6F9, 0x7A74, 0xA5DE, 0x7A75, 0xCA48, 0x7A76, 0xA873,
+	0x7A78, 0xCDA5, 0x7A79, 0xAAC6, 0x7A7A, 0xAAC5, 0x7A7B, 0xCDA6,
+	0x7A7E, 0xD040, 0x7A7F, 0xACEF, 0x7A80, 0xCFFE, 0x7A81, 0xACF0,
+	0x7A84, 0xAFB6, 0x7A85, 0xD2F8, 0x7A86, 0xD2F6, 0x7A87, 0xD2FC,
+	0x7A88, 0xAFB7, 0x7A89, 0xD2F7, 0x7A8A, 0xD2FB, 0x7A8B, 0xD2F9,
+	0x7A8C, 0xD2FA, 0x7A8F, 0xD6C8, 0x7A90, 0xD6CA, 0x7A92, 0xB2BF,
+	0x7A94, 0xD6C9, 0x7A95, 0xB2C0, 0x7A96, 0xB5A2, 0x7A97, 0xB5A1,
+	0x7A98, 0xB57E, 0x7A99, 0xDADB, 0x7A9E, 0xDF44, 0x7A9F, 0xB85D,
+	0x7AA0, 0xB85E, 0x7AA2, 0xDF43, 0x7AA3, 0xDF42, 0x7AA8, 0xE34A,
+	0x7AA9, 0xBADB, 0x7AAA, 0xBADA, 0x7AAB, 0xE34B, 0x7AAC, 0xE34C,
+	0x7AAE, 0xBD61, 0x7AAF, 0xBD60, 0x7AB1, 0xEAB5, 0x7AB2, 0xE6D3,
+	0x7AB3, 0xE6D5, 0x7AB4, 0xE6D4, 0x7AB5, 0xEAB4, 0x7AB6, 0xEAB2,
+	0x7AB7, 0xEAB6, 0x7AB8, 0xEAB3, 0x7ABA, 0xBF73, 0x7ABE, 0xEDB7,
+	0x7ABF, 0xC14B, 0x7AC0, 0xEDB8, 0x7AC1, 0xEDB9, 0x7AC4, 0xC2AB,
+	0x7AC5, 0xC2AC, 0x7AC7, 0xC475, 0x7ACA, 0xC5D1, 0x7ACB, 0xA5DF,
+	0x7AD1, 0xD041, 0x7AD8, 0xD2FD, 0x7AD9, 0xAFB8, 0x7ADF, 0xB3BA,
+	0x7AE0, 0xB3B9, 0x7AE3, 0xB5A4, 0x7AE4, 0xDADD, 0x7AE5, 0xB5A3,
+	0x7AE6, 0xDADC, 0x7AEB, 0xDF45, 0x7AED, 0xBADC, 0x7AEE, 0xE34D,
+	0x7AEF, 0xBADD, 0x7AF6, 0xC476, 0x7AF7, 0xF4A5, 0x7AF9, 0xA6CB,
+	0x7AFA, 0xAAC7, 0x7AFB, 0xCDA7, 0x7AFD, 0xACF2, 0x7AFF, 0xACF1,
+	0x7B00, 0xD042, 0x7B01, 0xD043, 0x7B04, 0xD340, 0x7B05, 0xD342,
+	0x7B06, 0xAFB9, 0x7B08, 0xD344, 0x7B09, 0xD347, 0x7B0A, 0xD345,
+	0x7B0E, 0xD346, 0x7B0F, 0xD343, 0x7B10, 0xD2FE, 0x7B11, 0xAFBA,
+	0x7B12, 0xD348, 0x7B13, 0xD341, 0x7B18, 0xD6D3, 0x7B19, 0xB2C6,
+	0x7B1A, 0xD6DC, 0x7B1B, 0xB2C3, 0x7B1D, 0xD6D5, 0x7B1E, 0xB2C7,
+	0x7B20, 0xB2C1, 0x7B22, 0xD6D0, 0x7B23, 0xD6DD, 0x7B24, 0xD6D1,
+	0x7B25, 0xD6CE, 0x7B26, 0xB2C5, 0x7B28, 0xB2C2, 0x7B2A, 0xD6D4,
+	0x7B2B, 0xD6D7, 0x7B2C, 0xB2C4, 0x7B2D, 0xD6D8, 0x7B2E, 0xB2C8,
+	0x7B2F, 0xD6D9, 0x7B30, 0xD6CF, 0x7B31, 0xD6D6, 0x7B32, 0xD6DA,
+	0x7B33, 0xD6D2, 0x7B34, 0xD6CD, 0x7B35, 0xD6CB, 0x7B38, 0xD6DB,
+	0x7B3B, 0xDADF, 0x7B40, 0xDAE4, 0x7B44, 0xDAE0, 0x7B45, 0xDAE6,
+	0x7B46, 0xB5A7, 0x7B47, 0xD6CC, 0x7B48, 0xDAE1, 0x7B49, 0xB5A5,
+	0x7B4A, 0xDADE, 0x7B4B, 0xB5AC, 0x7B4C, 0xDAE2, 0x7B4D, 0xB5AB,
+	0x7B4E, 0xDAE3, 0x7B4F, 0xB5AD, 0x7B50, 0xB5A8, 0x7B51, 0xB5AE,
+	0x7B52, 0xB5A9, 0x7B54, 0xB5AA, 0x7B56, 0xB5A6, 0x7B58, 0xDAE5,
+	0x7B60, 0xB861, 0x7B61, 0xDF50, 0x7B63, 0xDF53, 0x7B64, 0xDF47,
+	0x7B65, 0xDF4C, 0x7B66, 0xDF46, 0x7B67, 0xB863, 0x7B69, 0xDF4A,
+	0x7B6D, 0xDF48, 0x7B6E, 0xB862, 0x7B70, 0xDF4F, 0x7B71, 0xDF4E,
+	0x7B72, 0xDF4B, 0x7B73, 0xDF4D, 0x7B74, 0xDF49, 0x7B75, 0xBAE1,
+	0x7B76, 0xDF52, 0x7B77, 0xB85F, 0x7B78, 0xDF51, 0x7B82, 0xE35D,
+	0x7B84, 0xBAE8, 0x7B85, 0xE358, 0x7B87, 0xBAE7, 0x7B88, 0xE34E,
+	0x7B8A, 0xE350, 0x7B8B, 0xBAE0, 0x7B8C, 0xE355, 0x7B8D, 0xE354,
+	0x7B8E, 0xE357, 0x7B8F, 0xBAE5, 0x7B90, 0xE352, 0x7B91, 0xE351,
+	0x7B94, 0xBAE4, 0x7B95, 0xBADF, 0x7B96, 0xE353, 0x7B97, 0xBAE2,
+	0x7B98, 0xE359, 0x7B99, 0xE35B, 0x7B9B, 0xE356, 0x7B9C, 0xE34F,
+	0x7B9D, 0xBAE3, 0x7BA0, 0xBD69, 0x7BA1, 0xBADE, 0x7BA4, 0xE35C,
+	0x7BAC, 0xE6D9, 0x7BAD, 0xBD62, 0x7BAF, 0xE6DB, 0x7BB1, 0xBD63,
+	0x7BB4, 0xBD65, 0x7BB5, 0xE6DE, 0x7BB7, 0xE6D6, 0x7BB8, 0xBAE6,
+	0x7BB9, 0xE6DC, 0x7BBE, 0xE6D8, 0x7BC0, 0xB860, 0x7BC1, 0xBD68,
+	0x7BC4, 0xBD64, 0x7BC6, 0xBD66, 0x7BC7, 0xBD67, 0x7BC9, 0xBF76,
+	0x7BCA, 0xE6DD, 0x7BCB, 0xE6D7, 0x7BCC, 0xBD6A, 0x7BCE, 0xE6DA,
+	0x7BD4, 0xEAC0, 0x7BD5, 0xEABB, 0x7BD8, 0xEAC5, 0x7BD9, 0xBF74,
+	0x7BDA, 0xEABD, 0x7BDB, 0xBF78, 0x7BDC, 0xEAC3, 0x7BDD, 0xEABA,
+	0x7BDE, 0xEAB7, 0x7BDF, 0xEAC6, 0x7BE0, 0xC151, 0x7BE1, 0xBF79,
+	0x7BE2, 0xEAC2, 0x7BE3, 0xEAB8, 0x7BE4, 0xBF77, 0x7BE5, 0xEABC,
+	0x7BE6, 0xBF7B, 0x7BE7, 0xEAB9, 0x7BE8, 0xEABE, 0x7BE9, 0xBF7A,
+	0x7BEA, 0xEAC1, 0x7BEB, 0xEAC4, 0x7BF0, 0xEDCB, 0x7BF1, 0xEDCC,
+	0x7BF2, 0xEDBC, 0x7BF3, 0xEDC3, 0x7BF4, 0xEDC1, 0x7BF7, 0xC14F,
+	0x7BF8, 0xEDC8, 0x7BF9, 0xEABF, 0x7BFB, 0xEDBF, 0x7BFD, 0xEDC9,
+	0x7BFE, 0xC14E, 0x7BFF, 0xEDBE, 0x7C00, 0xEDBD, 0x7C01, 0xEDC7,
+	0x7C02, 0xEDC4, 0x7C03, 0xEDC6, 0x7C05, 0xEDBA, 0x7C06, 0xEDCA,
+	0x7C07, 0xC14C, 0x7C09, 0xEDC5, 0x7C0A, 0xEDCE, 0x7C0B, 0xEDC2,
+	0x7C0C, 0xC150, 0x7C0D, 0xC14D, 0x7C0E, 0xEDC0, 0x7C0F, 0xEDBB,
+	0x7C10, 0xEDCD, 0x7C11, 0xBF75, 0x7C19, 0xF063, 0x7C1C, 0xF061,
+	0x7C1D, 0xF067, 0x7C1E, 0xC2B0, 0x7C1F, 0xF065, 0x7C20, 0xF064,
+	0x7C21, 0xC2B2, 0x7C22, 0xF06A, 0x7C23, 0xC2B1, 0x7C25, 0xF06B,
+	0x7C26, 0xF068, 0x7C27, 0xC2AE, 0x7C28, 0xF069, 0x7C29, 0xF062,
+	0x7C2A, 0xC2AF, 0x7C2B, 0xC2AD, 0x7C2C, 0xF2AB, 0x7C2D, 0xF066,
+	0x7C30, 0xF06C, 0x7C33, 0xF2A8, 0x7C37, 0xC3B2, 0x7C38, 0xC3B0,
+	0x7C39, 0xF2AA, 0x7C3B, 0xF2AC, 0x7C3C, 0xF2A9, 0x7C3D, 0xC3B1,
+	0x7C3E, 0xC3AE, 0x7C3F, 0xC3AF, 0x7C40, 0xC3B3, 0x7C43, 0xC478,
+	0x7C45, 0xF4AA, 0x7C47, 0xF4A9, 0x7C48, 0xF4A7, 0x7C49, 0xF4A6,
+	0x7C4A, 0xF4A8, 0x7C4C, 0xC477, 0x7C4D, 0xC479, 0x7C50, 0xC4F0,
+	0x7C53, 0xF5E5, 0x7C54, 0xF5E4, 0x7C57, 0xF6FA, 0x7C59, 0xF6FC,
+	0x7C5A, 0xF6FE, 0x7C5B, 0xF6FD, 0x7C5C, 0xF6FB, 0x7C5F, 0xC5A3,
+	0x7C60, 0xC5A2, 0x7C63, 0xC5D3, 0x7C64, 0xC5D2, 0x7C65, 0xC5D4,
+	0x7C66, 0xF7ED, 0x7C67, 0xF7EC, 0x7C69, 0xF8FB, 0x7C6A, 0xF8B8,
+	0x7C6B, 0xF8FC, 0x7C6C, 0xC658, 0x7C6E, 0xC659, 0x7C6F, 0xF96D,
+	0x7C72, 0xC67E, 0x7C73, 0xA6CC, 0x7C75, 0xCDA8, 0x7C78, 0xD045,
+	0x7C79, 0xD046, 0x7C7A, 0xD044, 0x7C7D, 0xACF3, 0x7C7F, 0xD047,
+	0x7C80, 0xD048, 0x7C81, 0xD049, 0x7C84, 0xD349, 0x7C85, 0xD34F,
+	0x7C88, 0xD34D, 0x7C89, 0xAFBB, 0x7C8A, 0xD34B, 0x7C8C, 0xD34C,
+	0x7C8D, 0xD34E, 0x7C91, 0xD34A, 0x7C92, 0xB2C9, 0x7C94, 0xD6DE,
+	0x7C95, 0xB2CB, 0x7C96, 0xD6E0, 0x7C97, 0xB2CA, 0x7C98, 0xD6DF,
+	0x7C9E, 0xDAE8, 0x7C9F, 0xB5AF, 0x7CA1, 0xDAEA, 0x7CA2, 0xDAE7,
+	0x7CA3, 0xD6E1, 0x7CA5, 0xB5B0, 0x7CA7, 0xF9DB, 0x7CA8, 0xDAE9,
+	0x7CAF, 0xDF56, 0x7CB1, 0xB864, 0x7CB2, 0xDF54, 0x7CB3, 0xB865,
+	0x7CB4, 0xDF55, 0x7CB5, 0xB866, 0x7CB9, 0xBAE9, 0x7CBA, 0xE361,
+	0x7CBB, 0xE35E, 0x7CBC, 0xE360, 0x7CBD, 0xBAEA, 0x7CBE, 0xBAEB,
+	0x7CBF, 0xE35F, 0x7CC5, 0xE6DF, 0x7CC8, 0xE6E0, 0x7CCA, 0xBD6B,
+	0x7CCB, 0xE6E2, 0x7CCC, 0xE6E1, 0x7CCE, 0xA261, 0x7CD0, 0xEACA,
+	0x7CD1, 0xEACB, 0x7CD2, 0xEAC7, 0x7CD4, 0xEAC8, 0x7CD5, 0xBF7C,
+	0x7CD6, 0xBF7D, 0x7CD7, 0xEAC9, 0x7CD9, 0xC157, 0x7CDC, 0xC153,
+	0x7CDD, 0xC158, 0x7CDE, 0xC154, 0x7CDF, 0xC156, 0x7CE0, 0xC152,
+	0x7CE2, 0xC155, 0x7CE7, 0xC2B3, 0x7CE8, 0xEDCF, 0x7CEA, 0xF2AE,
+	0x7CEC, 0xF2AD, 0x7CEE, 0xF4AB, 0x7CEF, 0xC47A, 0x7CF0, 0xC47B,
+	0x7CF1, 0xF741, 0x7CF2, 0xF5E6, 0x7CF4, 0xF740, 0x7CF6, 0xF8FD,
+	0x7CF7, 0xF9A4, 0x7CF8, 0xA6CD, 0x7CFB, 0xA874, 0x7CFD, 0xCDA9,
+	0x7CFE, 0xAAC8, 0x7D00, 0xACF6, 0x7D01, 0xD04C, 0x7D02, 0xACF4,
+	0x7D03, 0xD04A, 0x7D04, 0xACF9, 0x7D05, 0xACF5, 0x7D06, 0xACFA,
+	0x7D07, 0xACF8, 0x7D08, 0xD04B, 0x7D09, 0xACF7, 0x7D0A, 0xAFBF,
+	0x7D0B, 0xAFBE, 0x7D0C, 0xD35A, 0x7D0D, 0xAFC7, 0x7D0E, 0xD353,
+	0x7D0F, 0xD359, 0x7D10, 0xAFC3, 0x7D11, 0xD352, 0x7D12, 0xD358,
+	0x7D13, 0xD356, 0x7D14, 0xAFC2, 0x7D15, 0xAFC4, 0x7D16, 0xD355,
+	0x7D17, 0xAFBD, 0x7D18, 0xD354, 0x7D19, 0xAFC8, 0x7D1A, 0xAFC5,
+	0x7D1B, 0xAFC9, 0x7D1C, 0xAFC6, 0x7D1D, 0xD351, 0x7D1E, 0xD350,
+	0x7D1F, 0xD357, 0x7D20, 0xAFC0, 0x7D21, 0xAFBC, 0x7D22, 0xAFC1,
+	0x7D28, 0xD6F0, 0x7D29, 0xD6E9, 0x7D2B, 0xB5B5, 0x7D2C, 0xD6E8,
+	0x7D2E, 0xB2CF, 0x7D2F, 0xB2D6, 0x7D30, 0xB2D3, 0x7D31, 0xB2D9,
+	0x7D32, 0xB2D8, 0x7D33, 0xB2D4, 0x7D35, 0xD6E2, 0x7D36, 0xD6E5,
+	0x7D38, 0xD6E4, 0x7D39, 0xB2D0, 0x7D3A, 0xD6E6, 0x7D3B, 0xD6EF,
+	0x7D3C, 0xB2D1, 0x7D3D, 0xD6E3, 0x7D3E, 0xD6EC, 0x7D3F, 0xD6ED,
+	0x7D40, 0xB2D2, 0x7D41, 0xD6EA, 0x7D42, 0xB2D7, 0x7D43, 0xB2CD,
+	0x7D44, 0xB2D5, 0x7D45, 0xD6E7, 0x7D46, 0xB2CC, 0x7D47, 0xD6EB,
+	0x7D4A, 0xD6EE, 0x7D4E, 0xDAFB, 0x7D4F, 0xDAF2, 0x7D50, 0xB5B2,
+	0x7D51, 0xDAF9, 0x7D52, 0xDAF6, 0x7D53, 0xDAEE, 0x7D54, 0xDAF7,
+	0x7D55, 0xB5B4, 0x7D56, 0xDAEF, 0x7D58, 0xDAEB, 0x7D5B, 0xB86C,
+	0x7D5C, 0xDAF4, 0x7D5E, 0xB5B1, 0x7D5F, 0xDAFA, 0x7D61, 0xB5B8,
+	0x7D62, 0xB5BA, 0x7D63, 0xDAED, 0x7D66, 0xB5B9, 0x7D67, 0xDAF0,
+	0x7D68, 0xB5B3, 0x7D69, 0xDAF8, 0x7D6A, 0xDAF1, 0x7D6B, 0xDAF5,
+	0x7D6D, 0xDAF3, 0x7D6E, 0xB5B6, 0x7D6F, 0xDAEC, 0x7D70, 0xB5BB,
+	0x7D71, 0xB2CE, 0x7D72, 0xB5B7, 0x7D73, 0xB5BC, 0x7D79, 0xB868,
+	0x7D7A, 0xDF5D, 0x7D7B, 0xDF5F, 0x7D7C, 0xDF61, 0x7D7D, 0xDF65,
+	0x7D7F, 0xDF5B, 0x7D80, 0xDF59, 0x7D81, 0xB86A, 0x7D83, 0xDF60,
+	0x7D84, 0xDF64, 0x7D85, 0xDF5C, 0x7D86, 0xDF58, 0x7D88, 0xDF57,
+	0x7D8C, 0xDF62, 0x7D8D, 0xDF5A, 0x7D8E, 0xDF5E, 0x7D8F, 0xB86B,
+	0x7D91, 0xB869, 0x7D92, 0xDF66, 0x7D93, 0xB867, 0x7D94, 0xDF63,
+	0x7D96, 0xE372, 0x7D9C, 0xBAEE, 0x7D9D, 0xE36A, 0x7D9E, 0xBD78,
+	0x7D9F, 0xE374, 0x7DA0, 0xBAF1, 0x7DA1, 0xE378, 0x7DA2, 0xBAF7,
+	0x7DA3, 0xE365, 0x7DA6, 0xE375, 0x7DA7, 0xE362, 0x7DA9, 0xE377,
+	0x7DAA, 0xE366, 0x7DAC, 0xBAFE, 0x7DAD, 0xBAFB, 0x7DAE, 0xE376,
+	0x7DAF, 0xE370, 0x7DB0, 0xBAED, 0x7DB1, 0xBAF5, 0x7DB2, 0xBAF4,
+	0x7DB4, 0xBAF3, 0x7DB5, 0xBAF9, 0x7DB7, 0xE363, 0x7DB8, 0xBAFA,
+	0x7DB9, 0xE371, 0x7DBA, 0xBAF6, 0x7DBB, 0xBAEC, 0x7DBC, 0xE373,
+	0x7DBD, 0xBAEF, 0x7DBE, 0xBAF0, 0x7DBF, 0xBAF8, 0x7DC0, 0xE368,
+	0x7DC1, 0xE367, 0x7DC2, 0xE364, 0x7DC4, 0xE36C, 0x7DC5, 0xE369,
+	0x7DC6, 0xE36D, 0x7DC7, 0xBAFD, 0x7DC9, 0xE379, 0x7DCA, 0xBAF2,
+	0x7DCB, 0xE36E, 0x7DCC, 0xE36F, 0x7DCE, 0xE36B, 0x7DD2, 0xBAFC,
+	0x7DD7, 0xE6E7, 0x7DD8, 0xBD70, 0x7DD9, 0xBD79, 0x7DDA, 0xBD75,
+	0x7DDB, 0xE6E4, 0x7DDD, 0xBD72, 0x7DDE, 0xBD76, 0x7DDF, 0xE6F0,
+	0x7DE0, 0xBD6C, 0x7DE1, 0xE6E8, 0x7DE3, 0xBD74, 0x7DE6, 0xE6EB,
+	0x7DE7, 0xE6E6, 0x7DE8, 0xBD73, 0x7DE9, 0xBD77, 0x7DEA, 0xE6E5,
+	0x7DEC, 0xBD71, 0x7DEE, 0xE6EF, 0x7DEF, 0xBD6E, 0x7DF0, 0xE6EE,
+	0x7DF1, 0xE6ED, 0x7DF2, 0xBD7A, 0x7DF3, 0xE572, 0x7DF4, 0xBD6D,
+	0x7DF6, 0xE6EC, 0x7DF7, 0xE6E3, 0x7DF9, 0xBD7B, 0x7DFA, 0xE6EA,
+	0x7DFB, 0xBD6F, 0x7E03, 0xE6E9, 0x7E08, 0xBFA2, 0x7E09, 0xBFA7,
+	0x7E0A, 0xBF7E, 0x7E0B, 0xEAD8, 0x7E0C, 0xEACF, 0x7E0D, 0xEADB,
+	0x7E0E, 0xEAD3, 0x7E0F, 0xEAD9, 0x7E10, 0xBFA8, 0x7E11, 0xBFA1,
+	0x7E12, 0xEACC, 0x7E13, 0xEAD2, 0x7E14, 0xEADC, 0x7E15, 0xEAD5,
+	0x7E16, 0xEADA, 0x7E17, 0xEACE, 0x7E1A, 0xEAD6, 0x7E1B, 0xBFA3,
+	0x7E1C, 0xEAD4, 0x7E1D, 0xBFA6, 0x7E1E, 0xBFA5, 0x7E1F, 0xEAD0,
+	0x7E20, 0xEAD1, 0x7E21, 0xEACD, 0x7E22, 0xEAD7, 0x7E23, 0xBFA4,
+	0x7E24, 0xEADE, 0x7E25, 0xEADD, 0x7E29, 0xEDDA, 0x7E2A, 0xEDD6,
+	0x7E2B, 0xC15F, 0x7E2D, 0xEDD0, 0x7E2E, 0xC159, 0x7E2F, 0xC169,
+	0x7E30, 0xEDDC, 0x7E31, 0xC161, 0x7E32, 0xC15D, 0x7E33, 0xEDD3,
+	0x7E34, 0xC164, 0x7E35, 0xC167, 0x7E36, 0xEDDE, 0x7E37, 0xC15C,
+	0x7E38, 0xEDD5, 0x7E39, 0xC165, 0x7E3A, 0xEDE0, 0x7E3B, 0xEDDD,
+	0x7E3C, 0xEDD1, 0x7E3D, 0xC160, 0x7E3E, 0xC15A, 0x7E3F, 0xC168,
+	0x7E40, 0xEDD8, 0x7E41, 0xC163, 0x7E42, 0xEDD2, 0x7E43, 0xC15E,
+	0x7E44, 0xEDDF, 0x7E45, 0xC162, 0x7E46, 0xC15B, 0x7E47, 0xEDD9,
+	0x7E48, 0xC166, 0x7E49, 0xEDD7, 0x7E4C, 0xEDDB, 0x7E50, 0xF06E,
+	0x7E51, 0xF074, 0x7E52, 0xC2B9, 0x7E53, 0xF077, 0x7E54, 0xC2B4,
+	0x7E55, 0xC2B5, 0x7E56, 0xF06F, 0x7E57, 0xF076, 0x7E58, 0xF071,
+	0x7E59, 0xC2BA, 0x7E5A, 0xC2B7, 0x7E5C, 0xF06D, 0x7E5E, 0xC2B6,
+	0x7E5F, 0xF073, 0x7E60, 0xF075, 0x7E61, 0xC2B8, 0x7E62, 0xF072,
+	0x7E63, 0xF070, 0x7E68, 0xF2B8, 0x7E69, 0xC3B7, 0x7E6A, 0xC3B8,
+	0x7E6B, 0xC3B4, 0x7E6D, 0xC3B5, 0x7E6F, 0xF2B4, 0x7E70, 0xF2B2,
+	0x7E72, 0xF2B6, 0x7E73, 0xC3BA, 0x7E74, 0xF2B7, 0x7E75, 0xF2B0,
+	0x7E76, 0xF2AF, 0x7E77, 0xF2B3, 0x7E78, 0xF2B1, 0x7E79, 0xC3B6,
+	0x7E7A, 0xF2B5, 0x7E7B, 0xF4AC, 0x7E7C, 0xC47E, 0x7E7D, 0xC47D,
+	0x7E7E, 0xF4AD, 0x7E80, 0xF4AF, 0x7E81, 0xF4AE, 0x7E82, 0xC4A1,
+	0x7E86, 0xF5EB, 0x7E87, 0xF5E8, 0x7E88, 0xF5E9, 0x7E8A, 0xF5E7,
+	0x7E8B, 0xF5EA, 0x7E8C, 0xC4F2, 0x7E8D, 0xF5EC, 0x7E8F, 0xC4F1,
+	0x7E91, 0xF742, 0x7E93, 0xC5D5, 0x7E94, 0xC5D7, 0x7E95, 0xF7EE,
+	0x7E96, 0xC5D6, 0x7E97, 0xF8B9, 0x7E98, 0xF940, 0x7E99, 0xF942,
+	0x7E9A, 0xF8FE, 0x7E9B, 0xF941, 0x7E9C, 0xC66C, 0x7F36, 0xA6CE,
+	0x7F38, 0xACFB, 0x7F39, 0xD26F, 0x7F3A, 0xAFCA, 0x7F3D, 0xB2DA,
+	0x7F3E, 0xDAFC, 0x7F3F, 0xDAFD, 0x7F43, 0xEADF, 0x7F44, 0xC16A,
+	0x7F45, 0xEDE1, 0x7F48, 0xC2BB, 0x7F4A, 0xF2BA, 0x7F4B, 0xF2B9,
+	0x7F4C, 0xC4A2, 0x7F4D, 0xF5ED, 0x7F4F, 0xF743, 0x7F50, 0xC5F8,
+	0x7F51, 0xCA49, 0x7F54, 0xAAC9, 0x7F55, 0xA875, 0x7F58, 0xD04D,
+	0x7F5B, 0xD360, 0x7F5C, 0xD35B, 0x7F5D, 0xD35F, 0x7F5E, 0xD35D,
+	0x7F5F, 0xAFCB, 0x7F60, 0xD35E, 0x7F61, 0xD35C, 0x7F63, 0xD6F1,
+	0x7F65, 0xDAFE, 0x7F66, 0xDB40, 0x7F67, 0xDF69, 0x7F68, 0xDF6A,
+	0x7F69, 0xB86E, 0x7F6A, 0xB86F, 0x7F6B, 0xDF68, 0x7F6C, 0xDF6B,
+	0x7F6D, 0xDF67, 0x7F6E, 0xB86D, 0x7F70, 0xBB40, 0x7F72, 0xB870,
+	0x7F73, 0xE37A, 0x7F75, 0xBD7C, 0x7F76, 0xE6F1, 0x7F77, 0xBD7D,
+	0x7F79, 0xBFA9, 0x7F7A, 0xEAE2, 0x7F7B, 0xEAE0, 0x7F7C, 0xEAE1,
+	0x7F7D, 0xEDE4, 0x7F7E, 0xEDE3, 0x7F7F, 0xEDE2, 0x7F83, 0xF2BB,
+	0x7F85, 0xC3B9, 0x7F86, 0xF2BC, 0x7F87, 0xF744, 0x7F88, 0xC5F9,
+	0x7F89, 0xF8BA, 0x7F8A, 0xA6CF, 0x7F8B, 0xAACB, 0x7F8C, 0xAACA,
+	0x7F8D, 0xD04F, 0x7F8E, 0xACFC, 0x7F91, 0xD04E, 0x7F92, 0xD362,
+	0x7F94, 0xAFCC, 0x7F95, 0xD6F2, 0x7F96, 0xD361, 0x7F9A, 0xB2DC,
+	0x7F9B, 0xD6F5, 0x7F9C, 0xD6F3, 0x7F9D, 0xD6F4, 0x7F9E, 0xB2DB,
+	0x7FA0, 0xDB42, 0x7FA1, 0xDB43, 0x7FA2, 0xDB41, 0x7FA4, 0xB873,
+	0x7FA5, 0xDF6D, 0x7FA6, 0xDF6C, 0x7FA7, 0xDF6E, 0x7FA8, 0xB872,
+	0x7FA9, 0xB871, 0x7FAC, 0xE6F2, 0x7FAD, 0xE6F4, 0x7FAF, 0xBD7E,
+	0x7FB0, 0xE6F3, 0x7FB1, 0xEAE3, 0x7FB2, 0xBFAA, 0x7FB3, 0xF079,
+	0x7FB5, 0xF078, 0x7FB6, 0xC3BB, 0x7FB7, 0xF2BD, 0x7FB8, 0xC3BD,
+	0x7FB9, 0xC3BC, 0x7FBA, 0xF4B0, 0x7FBB, 0xF5EE, 0x7FBC, 0xC4F3,
+	0x7FBD, 0xA6D0, 0x7FBE, 0xD050, 0x7FBF, 0xACFD, 0x7FC0, 0xD365,
+	0x7FC1, 0xAFCE, 0x7FC2, 0xD364, 0x7FC3, 0xD363, 0x7FC5, 0xAFCD,
+	0x7FC7, 0xD6FB, 0x7FC9, 0xD6FD, 0x7FCA, 0xD6F6, 0x7FCB, 0xD6F7,
+	0x7FCC, 0xB2DD, 0x7FCD, 0xD6F8, 0x7FCE, 0xB2DE, 0x7FCF, 0xD6FC,
+	0x7FD0, 0xD6F9, 0x7FD1, 0xD6FA, 0x7FD2, 0xB2DF, 0x7FD4, 0xB5BE,
+	0x7FD5, 0xB5BF, 0x7FD7, 0xDB44, 0x7FDB, 0xDF6F, 0x7FDC, 0xDF70,
+	0x7FDE, 0xE37E, 0x7FDF, 0xBB43, 0x7FE0, 0xBB41, 0x7FE1, 0xBB42,
+	0x7FE2, 0xE37B, 0x7FE3, 0xE37C, 0x7FE5, 0xE37D, 0x7FE6, 0xE6F9,
+	0x7FE8, 0xE6FA, 0x7FE9, 0xBDA1, 0x7FEA, 0xE6F7, 0x7FEB, 0xE6F6,
+	0x7FEC, 0xE6F8, 0x7FED, 0xE6F5, 0x7FEE, 0xBFAD, 0x7FEF, 0xEAE4,
+	0x7FF0, 0xBFAB, 0x7FF1, 0xBFAC, 0x7FF2, 0xEDE6, 0x7FF3, 0xC16B,
+	0x7FF4, 0xEDE5, 0x7FF5, 0xEFA8, 0x7FF7, 0xF07A, 0x7FF8, 0xF07B,
+	0x7FF9, 0xC2BC, 0x7FFB, 0xC2BD, 0x7FFC, 0xC16C, 0x7FFD, 0xF2BE,
+	0x7FFE, 0xF2BF, 0x7FFF, 0xF4B1, 0x8000, 0xC4A3, 0x8001, 0xA6D1,
+	0x8003, 0xA6D2, 0x8004, 0xACFE, 0x8005, 0xAACC, 0x8006, 0xAFCF,
+	0x8007, 0xD051, 0x800B, 0xB5C0, 0x800C, 0xA6D3, 0x800D, 0xAD41,
+	0x800E, 0xD052, 0x800F, 0xD053, 0x8010, 0xAD40, 0x8011, 0xAD42,
+	0x8012, 0xA6D4, 0x8014, 0xD054, 0x8015, 0xAFD1, 0x8016, 0xD366,
+	0x8017, 0xAFD3, 0x8018, 0xAFD0, 0x8019, 0xAFD2, 0x801B, 0xD741,
+	0x801C, 0xB2E0, 0x801E, 0xD740, 0x801F, 0xD6FE, 0x8021, 0xDF71,
+	0x8024, 0xE3A1, 0x8026, 0xBDA2, 0x8028, 0xBFAE, 0x8029, 0xEAE6,
+	0x802A, 0xEAE5, 0x802C, 0xEDE7, 0x8030, 0xF5EF, 0x8033, 0xA6D5,
+	0x8034, 0xCB73, 0x8035, 0xCDAA, 0x8036, 0xAD43, 0x8037, 0xD055,
+	0x8039, 0xD368, 0x803D, 0xAFD4, 0x803E, 0xD367, 0x803F, 0xAFD5,
+	0x8043, 0xD743, 0x8046, 0xB2E2, 0x8047, 0xD742, 0x8048, 0xD744,
+	0x804A, 0xB2E1, 0x804F, 0xDB46, 0x8050, 0xDB47, 0x8051, 0xDB45,
+	0x8052, 0xB5C1, 0x8056, 0xB874, 0x8058, 0xB875, 0x805A, 0xBB45,
+	0x805C, 0xE3A3, 0x805D, 0xE3A2, 0x805E, 0xBB44, 0x8064, 0xE6FB,
+	0x8067, 0xE6FC, 0x806C, 0xEAE7, 0x806F, 0xC170, 0x8070, 0xC16F,
+	0x8071, 0xC16D, 0x8072, 0xC16E, 0x8073, 0xC171, 0x8075, 0xF07C,
+	0x8076, 0xC2BF, 0x8077, 0xC2BE, 0x8078, 0xF2C0, 0x8079, 0xF4B2,
+	0x807D, 0xC5A5, 0x807E, 0xC5A4, 0x807F, 0xA6D6, 0x8082, 0xD1FB,
+	0x8084, 0xB877, 0x8085, 0xB5C2, 0x8086, 0xB876, 0x8087, 0xBB46,
+	0x8089, 0xA6D7, 0x808A, 0xC9A9, 0x808B, 0xA6D8, 0x808C, 0xA6D9,
+	0x808F, 0xCDAB, 0x8090, 0xCB76, 0x8092, 0xCB77, 0x8093, 0xA877,
+	0x8095, 0xCB74, 0x8096, 0xA876, 0x8098, 0xA879, 0x8099, 0xCB75,
+	0x809A, 0xA87B, 0x809B, 0xA87A, 0x809C, 0xCB78, 0x809D, 0xA878,
+	0x80A1, 0xAAD1, 0x80A2, 0xAACF, 0x80A3, 0xCDAD, 0x80A5, 0xAACE,
+	0x80A9, 0xAAD3, 0x80AA, 0xAAD5, 0x80AB, 0xAAD2, 0x80AD, 0xCDB0,
+	0x80AE, 0xCDAC, 0x80AF, 0xAAD6, 0x80B1, 0xAAD0, 0x80B2, 0xA87C,
+	0x80B4, 0xAAD4, 0x80B5, 0xCDAF, 0x80B8, 0xCDAE, 0x80BA, 0xAACD,
+	0x80C2, 0xD05B, 0x80C3, 0xAD47, 0x80C4, 0xAD48, 0x80C5, 0xD05D,
+	0x80C7, 0xD057, 0x80C8, 0xD05A, 0x80C9, 0xD063, 0x80CA, 0xD061,
+	0x80CC, 0xAD49, 0x80CD, 0xD067, 0x80CE, 0xAD4C, 0x80CF, 0xD064,
+	0x80D0, 0xD05C, 0x80D1, 0xD059, 0x80D4, 0xDB49, 0x80D5, 0xD062,
+	0x80D6, 0xAD44, 0x80D7, 0xD065, 0x80D8, 0xD056, 0x80D9, 0xD05F,
+	0x80DA, 0xAD46, 0x80DB, 0xAD4B, 0x80DC, 0xD060, 0x80DD, 0xAD4F,
+	0x80DE, 0xAD4D, 0x80E0, 0xD058, 0x80E1, 0xAD4A, 0x80E3, 0xD05E,
+	0x80E4, 0xAD4E, 0x80E5, 0xAD45, 0x80E6, 0xD066, 0x80ED, 0xAFDA,
+	0x80EF, 0xAFE3, 0x80F0, 0xAFD8, 0x80F1, 0xAFD6, 0x80F2, 0xD36A,
+	0x80F3, 0xAFDE, 0x80F4, 0xAFDB, 0x80F5, 0xD36C, 0x80F8, 0xAFDD,
+	0x80F9, 0xD36B, 0x80FA, 0xD369, 0x80FB, 0xD36E, 0x80FC, 0xAFE2,
+	0x80FD, 0xAFE0, 0x80FE, 0xDB48, 0x8100, 0xD36F, 0x8101, 0xD36D,
+	0x8102, 0xAFD7, 0x8105, 0xAFD9, 0x8106, 0xAFDC, 0x8108, 0xAFDF,
+	0x810A, 0xAFE1, 0x8115, 0xD74E, 0x8116, 0xB2E4, 0x8118, 0xD745,
+	0x8119, 0xD747, 0x811B, 0xD748, 0x811D, 0xD750, 0x811E, 0xD74C,
+	0x811F, 0xD74A, 0x8121, 0xD74D, 0x8122, 0xD751, 0x8123, 0xB2E5,
+	0x8124, 0xB2E9, 0x8125, 0xD746, 0x8127, 0xD74F, 0x8129, 0xB2E7,
+	0x812B, 0xB2E6, 0x812C, 0xD74B, 0x812D, 0xD749, 0x812F, 0xB2E3,
+	0x8130, 0xB2E8, 0x8139, 0xB5C8, 0x813A, 0xDB51, 0x813D, 0xDB4F,
+	0x813E, 0xB5CA, 0x8143, 0xDB4A, 0x8144, 0xDFA1, 0x8146, 0xB5C9,
+	0x8147, 0xDB4E, 0x814A, 0xDB4B, 0x814B, 0xB5C5, 0x814C, 0xB5CB,
+	0x814D, 0xDB50, 0x814E, 0xB5C7, 0x814F, 0xDB4D, 0x8150, 0xBB47,
+	0x8151, 0xB5C6, 0x8152, 0xDB4C, 0x8153, 0xB5CC, 0x8154, 0xB5C4,
+	0x8155, 0xB5C3, 0x815B, 0xDF77, 0x815C, 0xDF75, 0x815E, 0xDF7B,
+	0x8160, 0xDF73, 0x8161, 0xDFA2, 0x8162, 0xDF78, 0x8164, 0xDF72,
+	0x8165, 0xB87B, 0x8166, 0xB8A3, 0x8167, 0xDF7D, 0x8169, 0xDF76,
+	0x816B, 0xB87E, 0x816E, 0xB87C, 0x816F, 0xDF7E, 0x8170, 0xB879,
+	0x8171, 0xB878, 0x8172, 0xDF79, 0x8173, 0xB87D, 0x8174, 0xB5CD,
+	0x8176, 0xDF7C, 0x8177, 0xDF74, 0x8178, 0xB87A, 0x8179, 0xB8A1,
+	0x817A, 0xB8A2, 0x817F, 0xBB4C, 0x8180, 0xBB48, 0x8182, 0xBB4D,
+	0x8183, 0xE3A6, 0x8186, 0xE3A5, 0x8187, 0xE3A7, 0x8188, 0xBB4A,
+	0x8189, 0xE3A4, 0x818A, 0xBB4B, 0x818B, 0xE3AA, 0x818C, 0xE3A9,
+	0x818D, 0xE3A8, 0x818F, 0xBB49, 0x8195, 0xE741, 0x8197, 0xE744,
+	0x8198, 0xBDA8, 0x8199, 0xE743, 0x819A, 0xBDA7, 0x819B, 0xBDA3,
+	0x819C, 0xBDA4, 0x819D, 0xBDA5, 0x819E, 0xE740, 0x819F, 0xE6FE,
+	0x81A0, 0xBDA6, 0x81A2, 0xE742, 0x81A3, 0xE6FD, 0x81A6, 0xEAE9,
+	0x81A7, 0xEAF3, 0x81A8, 0xBFB1, 0x81A9, 0xBFB0, 0x81AB, 0xEAED,
+	0x81AC, 0xEAEF, 0x81AE, 0xEAEA, 0x81B0, 0xEAEE, 0x81B1, 0xEAE8,
+	0x81B2, 0xEAF1, 0x81B3, 0xBFAF, 0x81B4, 0xEAF0, 0x81B5, 0xEAEC,
+	0x81B7, 0xEAF2, 0x81B9, 0xEAEB, 0x81BA, 0xC174, 0x81BB, 0xEDE8,
+	0x81BC, 0xEDEE, 0x81BD, 0xC178, 0x81BE, 0xC17A, 0x81BF, 0xC177,
+	0x81C0, 0xC176, 0x81C2, 0xC175, 0x81C3, 0xC173, 0x81C4, 0xEDE9,
+	0x81C5, 0xEDEC, 0x81C6, 0xC172, 0x81C7, 0xEDED, 0x81C9, 0xC179,
+	0x81CA, 0xEDEB, 0x81CC, 0xEDEA, 0x81CD, 0xC2C0, 0x81CF, 0xC2C1,
+	0x81D0, 0xF0A1, 0x81D1, 0xF07D, 0x81D2, 0xF07E, 0x81D5, 0xF2C2,
+	0x81D7, 0xF2C1, 0x81D8, 0xC3BE, 0x81D9, 0xF4B4, 0x81DA, 0xC4A4,
+	0x81DB, 0xF4B3, 0x81DD, 0xF5F0, 0x81DE, 0xF745, 0x81DF, 0xC5A6,
+	0x81E0, 0xF943, 0x81E1, 0xF944, 0x81E2, 0xC5D8, 0x81E3, 0xA6DA,
+	0x81E5, 0xAAD7, 0x81E6, 0xDB52, 0x81E7, 0xBB4E, 0x81E8, 0xC17B,
+	0x81E9, 0xEDEF, 0x81EA, 0xA6DB, 0x81EC, 0xAFE5, 0x81ED, 0xAFE4,
+	0x81EE, 0xDB53, 0x81F2, 0xEAF4, 0x81F3, 0xA6DC, 0x81F4, 0xAD50,
+	0x81F7, 0xDB54, 0x81F8, 0xDB55, 0x81F9, 0xDB56, 0x81FA, 0xBB4F,
+	0x81FB, 0xBFB2, 0x81FC, 0xA6DD, 0x81FE, 0xAAD8, 0x81FF, 0xD068,
+	0x8200, 0xAFE6, 0x8201, 0xD370, 0x8202, 0xB2EA, 0x8204, 0xDB57,
+	0x8205, 0xB8A4, 0x8207, 0xBB50, 0x8208, 0xBFB3, 0x8209, 0xC17C,
+	0x820A, 0xC2C2, 0x820B, 0xF4B5, 0x820C, 0xA6DE, 0x820D, 0xAAD9,
+	0x8210, 0xAFE7, 0x8211, 0xD752, 0x8212, 0xB5CE, 0x8214, 0xBB51,
+	0x8215, 0xE3AB, 0x8216, 0xE745, 0x821B, 0xA6DF, 0x821C, 0xB5CF,
+	0x821D, 0xDFA3, 0x821E, 0xBB52, 0x821F, 0xA6E0, 0x8220, 0xCDB1,
+	0x8221, 0xD069, 0x8222, 0xAD51, 0x8225, 0xD372, 0x8228, 0xAFEA,
+	0x822A, 0xAFE8, 0x822B, 0xAFE9, 0x822C, 0xAFEB, 0x822F, 0xD371,
+	0x8232, 0xD757, 0x8233, 0xD754, 0x8234, 0xD756, 0x8235, 0xB2EB,
+	0x8236, 0xB2ED, 0x8237, 0xB2EC, 0x8238, 0xD753, 0x8239, 0xB2EE,
+	0x823A, 0xD755, 0x823C, 0xDB58, 0x823D, 0xDB59, 0x823F, 0xDB5A,
+	0x8240, 0xDFA6, 0x8242, 0xDFA7, 0x8244, 0xDFA5, 0x8245, 0xDFA8,
+	0x8247, 0xB8A5, 0x8249, 0xDFA4, 0x824B, 0xBB53, 0x824E, 0xE74A,
+	0x824F, 0xE746, 0x8250, 0xE749, 0x8251, 0xE74B, 0x8252, 0xE748,
+	0x8253, 0xE747, 0x8255, 0xEAF5, 0x8256, 0xEAF6, 0x8257, 0xEAF7,
+	0x8258, 0xBFB4, 0x8259, 0xBFB5, 0x825A, 0xEDF1, 0x825B, 0xEDF0,
+	0x825C, 0xEDF2, 0x825E, 0xF0A3, 0x825F, 0xF0A2, 0x8261, 0xF2C4,
+	0x8263, 0xF2C5, 0x8264, 0xF2C3, 0x8266, 0xC4A5, 0x8268, 0xF4B6,
+	0x8269, 0xF4B7, 0x826B, 0xF746, 0x826C, 0xF7EF, 0x826D, 0xF8BB,
+	0x826E, 0xA6E1, 0x826F, 0xA87D, 0x8271, 0xC17D, 0x8272, 0xA6E2,
+	0x8274, 0xD758, 0x8275, 0xDB5B, 0x8277, 0xC641, 0x8278, 0xCA4A,
+	0x827C, 0xCA4B, 0x827D, 0xCA4D, 0x827E, 0xA6E3, 0x827F, 0xCA4E,
+	0x8280, 0xCA4C, 0x8283, 0xCBA2, 0x8284, 0xCBA3, 0x8285, 0xCB7B,
+	0x828A, 0xCBA1, 0x828B, 0xA8A1, 0x828D, 0xA8A2, 0x828E, 0xCB7C,
+	0x828F, 0xCB7A, 0x8290, 0xCB79, 0x8291, 0xCB7D, 0x8292, 0xA87E,
+	0x8293, 0xCB7E, 0x8294, 0xD06A, 0x8298, 0xCDB6, 0x8299, 0xAADC,
+	0x829A, 0xCDB5, 0x829B, 0xCDB7, 0x829D, 0xAADB, 0x829E, 0xCDBC,
+	0x829F, 0xAADF, 0x82A0, 0xCDB2, 0x82A1, 0xCDC0, 0x82A2, 0xCDC6,
+	0x82A3, 0xAAE6, 0x82A4, 0xCDC3, 0x82A5, 0xAAE3, 0x82A7, 0xCDB9,
+	0x82A8, 0xCDBF, 0x82A9, 0xCDC1, 0x82AB, 0xCDB4, 0x82AC, 0xAAE2,
+	0x82AD, 0xAADD, 0x82AE, 0xCDBA, 0x82AF, 0xAAE4, 0x82B0, 0xAAE7,
+	0x82B1, 0xAAE1, 0x82B3, 0xAADA, 0x82B4, 0xCDBE, 0x82B5, 0xCDB8,
+	0x82B6, 0xCDC5, 0x82B7, 0xAAE9, 0x82B8, 0xAAE5, 0x82B9, 0xAAE0,
+	0x82BA, 0xCDBD, 0x82BB, 0xAFEC, 0x82BC, 0xCDBB, 0x82BD, 0xAADE,
+	0x82BE, 0xAAE8, 0x82C0, 0xCDB3, 0x82C2, 0xCDC2, 0x82C3, 0xCDC4,
+	0x82D1, 0xAD62, 0x82D2, 0xAD5C, 0x82D3, 0xAD64, 0x82D4, 0xAD61,
+	0x82D5, 0xD071, 0x82D6, 0xD074, 0x82D7, 0xAD5D, 0x82D9, 0xD06B,
+	0x82DB, 0xAD56, 0x82DC, 0xAD60, 0x82DE, 0xAD63, 0x82DF, 0xAD65,
+	0x82E0, 0xD0A2, 0x82E1, 0xD077, 0x82E3, 0xAD55, 0x82E4, 0xD0A1,
+	0x82E5, 0xAD59, 0x82E6, 0xAD57, 0x82E7, 0xAD52, 0x82E8, 0xD06F,
+	0x82EA, 0xD07E, 0x82EB, 0xD073, 0x82EC, 0xD076, 0x82ED, 0xD0A5,
+	0x82EF, 0xAD66, 0x82F0, 0xD07D, 0x82F1, 0xAD5E, 0x82F2, 0xD078,
+	0x82F3, 0xD0A4, 0x82F4, 0xD075, 0x82F5, 0xD079, 0x82F6, 0xD07C,
+	0x82F9, 0xD06D, 0x82FA, 0xD0A3, 0x82FB, 0xD07B, 0x82FE, 0xD06C,
+	0x8300, 0xD070, 0x8301, 0xAD5F, 0x8302, 0xAD5A, 0x8303, 0xAD53,
+	0x8304, 0xAD58, 0x8305, 0xAD54, 0x8306, 0xAD67, 0x8307, 0xD06E,
+	0x8308, 0xD3A5, 0x8309, 0xAD5B, 0x830C, 0xD07A, 0x830D, 0xCE41,
+	0x8316, 0xD3A8, 0x8317, 0xAFFA, 0x8319, 0xD376, 0x831B, 0xD3A3,
+	0x831C, 0xD37D, 0x831E, 0xD3B2, 0x8320, 0xD3AA, 0x8322, 0xD37E,
+	0x8324, 0xD3A9, 0x8325, 0xD378, 0x8326, 0xD37C, 0x8327, 0xD3B5,
+	0x8328, 0xAFFD, 0x8329, 0xD3AD, 0x832A, 0xD3A4, 0x832B, 0xAFED,
+	0x832C, 0xD3B3, 0x832D, 0xD374, 0x832F, 0xD3AC, 0x8331, 0xAFFC,
+	0x8332, 0xAFF7, 0x8333, 0xD373, 0x8334, 0xAFF5, 0x8335, 0xAFF4,
+	0x8336, 0xAFF9, 0x8337, 0xD3AB, 0x8338, 0xAFF1, 0x8339, 0xAFF8,
+	0x833A, 0xD072, 0x833B, 0xDB5C, 0x833C, 0xD3A6, 0x833F, 0xD37A,
+	0x8340, 0xAFFB, 0x8341, 0xD37B, 0x8342, 0xD3A1, 0x8343, 0xAFFE,
+	0x8344, 0xD375, 0x8345, 0xD3AF, 0x8347, 0xD3AE, 0x8348, 0xD3B6,
+	0x8349, 0xAFF3, 0x834A, 0xAFF0, 0x834B, 0xD3B4, 0x834C, 0xD3B0,
+	0x834D, 0xD3A7, 0x834E, 0xD3A2, 0x834F, 0xAFF6, 0x8350, 0xAFF2,
+	0x8351, 0xD377, 0x8352, 0xAFEE, 0x8353, 0xD3B1, 0x8354, 0xAFEF,
+	0x8356, 0xD379, 0x8373, 0xD75E, 0x8374, 0xD760, 0x8375, 0xD765,
+	0x8376, 0xD779, 0x8377, 0xB2FC, 0x8378, 0xB2F2, 0x837A, 0xD75D,
+	0x837B, 0xB2FD, 0x837C, 0xB2FE, 0x837D, 0xD768, 0x837E, 0xD76F,
+	0x837F, 0xD775, 0x8381, 0xD762, 0x8383, 0xD769, 0x8386, 0xB340,
+	0x8387, 0xD777, 0x8388, 0xD772, 0x8389, 0xB2FA, 0x838A, 0xB2F8,
+	0x838B, 0xD76E, 0x838C, 0xD76A, 0x838D, 0xD75C, 0x838E, 0xB2EF,
+	0x838F, 0xD761, 0x8390, 0xD759, 0x8392, 0xB2F7, 0x8393, 0xB2F9,
+	0x8394, 0xD766, 0x8395, 0xD763, 0x8396, 0xB2F4, 0x8397, 0xD773,
+	0x8398, 0xB2F1, 0x8399, 0xD764, 0x839A, 0xD77A, 0x839B, 0xD76C,
+	0x839D, 0xD76B, 0x839E, 0xB2F0, 0x83A0, 0xB2FB, 0x83A2, 0xB2F3,
+	0x83A3, 0xD75A, 0x83A4, 0xD75F, 0x83A5, 0xD770, 0x83A6, 0xD776,
+	0x83A7, 0xB341, 0x83A8, 0xD75B, 0x83A9, 0xD767, 0x83AA, 0xD76D,
+	0x83AB, 0xB2F6, 0x83AE, 0xD778, 0x83AF, 0xD771, 0x83B0, 0xD774,
+	0x83BD, 0xB2F5, 0x83BF, 0xDB6C, 0x83C0, 0xDB60, 0x83C1, 0xB5D7,
+	0x83C2, 0xDB7D, 0x83C3, 0xDBA7, 0x83C4, 0xDBAA, 0x83C5, 0xB5D5,
+	0x83C6, 0xDB68, 0x83C7, 0xDBA3, 0x83C8, 0xDB69, 0x83C9, 0xDB77,
+	0x83CA, 0xB5E2, 0x83CB, 0xDB73, 0x83CC, 0xB5DF, 0x83CE, 0xDB74,
+	0x83CF, 0xDB5D, 0x83D1, 0xDBA4, 0x83D4, 0xB5E8, 0x83D5, 0xDBA1,
+	0x83D6, 0xDB75, 0x83D7, 0xDBAC, 0x83D8, 0xDB70, 0x83D9, 0xDFC8,
+	0x83DB, 0xDBAF, 0x83DC, 0xB5E6, 0x83DD, 0xDB6E, 0x83DE, 0xDB7A,
+	0x83DF, 0xB5E9, 0x83E0, 0xB5D4, 0x83E1, 0xDB72, 0x83E2, 0xDBAD,
+	0x83E3, 0xDB6B, 0x83E4, 0xDB64, 0x83E5, 0xDB6F, 0x83E7, 0xDB63,
+	0x83E8, 0xDB61, 0x83E9, 0xB5D0, 0x83EA, 0xDBA5, 0x83EB, 0xDB6A,
+	0x83EC, 0xDBA8, 0x83EE, 0xDBA9, 0x83EF, 0xB5D8, 0x83F0, 0xB5DD,
+	0x83F1, 0xB5D9, 0x83F2, 0xB5E1, 0x83F3, 0xDB7E, 0x83F4, 0xB5DA,
+	0x83F5, 0xDB76, 0x83F6, 0xDB66, 0x83F8, 0xB5D2, 0x83F9, 0xDB5E,
+	0x83FA, 0xDBA2, 0x83FB, 0xDBAB, 0x83FC, 0xDB65, 0x83FD, 0xB5E0,
+	0x83FE, 0xDBB0, 0x83FF, 0xDB71, 0x8401, 0xDB6D, 0x8403, 0xB5D1,
+	0x8404, 0xB5E5, 0x8406, 0xDB7C, 0x8407, 0xB5E7, 0x8409, 0xDB78,
+	0x840A, 0xB5DC, 0x840B, 0xB5D6, 0x840C, 0xB5DE, 0x840D, 0xB5D3,
+	0x840E, 0xB5E4, 0x840F, 0xDB79, 0x8410, 0xDB67, 0x8411, 0xDB7B,
+	0x8412, 0xDB62, 0x8413, 0xDBA6, 0x841B, 0xDBAE, 0x8423, 0xDB5F,
+	0x8429, 0xDFC7, 0x842B, 0xDFDD, 0x842C, 0xB855, 0x842D, 0xDFCC,
+	0x842F, 0xDFCA, 0x8430, 0xDFB5, 0x8431, 0xB8A9, 0x8432, 0xDFC5,
+	0x8433, 0xDFD9, 0x8434, 0xDFC1, 0x8435, 0xB8B1, 0x8436, 0xDFD8,
+	0x8437, 0xDFBF, 0x8438, 0xB5E3, 0x8439, 0xDFCF, 0x843A, 0xDFC0,
+	0x843B, 0xDFD6, 0x843C, 0xB8B0, 0x843D, 0xB8A8, 0x843F, 0xDFAA,
+	0x8440, 0xDFB2, 0x8442, 0xDFCB, 0x8443, 0xDFC3, 0x8444, 0xDFDC,
+	0x8445, 0xDFC6, 0x8446, 0xB8B6, 0x8447, 0xDFD7, 0x8449, 0xB8AD,
+	0x844B, 0xDFC9, 0x844C, 0xDFD1, 0x844D, 0xDFB6, 0x844E, 0xDFD0,
+	0x8450, 0xDFE1, 0x8451, 0xDFB1, 0x8452, 0xDFD2, 0x8454, 0xDFDF,
+	0x8456, 0xDFAB, 0x8457, 0xB5DB, 0x8459, 0xDFB9, 0x845A, 0xDFB8,
+	0x845B, 0xB8AF, 0x845D, 0xDFBC, 0x845E, 0xDFBE, 0x845F, 0xDFCD,
+	0x8460, 0xDFDE, 0x8461, 0xB8B2, 0x8463, 0xB8B3, 0x8465, 0xDFB0,
+	0x8466, 0xB8AB, 0x8467, 0xDFB4, 0x8468, 0xDFDA, 0x8469, 0xB8B4,
+	0x846B, 0xB8AC, 0x846C, 0xB8AE, 0x846D, 0xB8B5, 0x846E, 0xDFE0,
+	0x846F, 0xDFD3, 0x8470, 0xDFCE, 0x8473, 0xDFBB, 0x8474, 0xDFBA,
+	0x8475, 0xB8AA, 0x8476, 0xDFAC, 0x8477, 0xB8A7, 0x8478, 0xDFC4,
+	0x8479, 0xDFAD, 0x847A, 0xDFC2, 0x847D, 0xDFB7, 0x847E, 0xDFDB,
+	0x8482, 0xB8A6, 0x8486, 0xDFB3, 0x848D, 0xDFAF, 0x848E, 0xDFD5,
+	0x848F, 0xDFAE, 0x8490, 0xBB60, 0x8491, 0xE3D3, 0x8494, 0xE3C2,
+	0x8497, 0xE3AC, 0x8498, 0xE3CA, 0x8499, 0xBB58, 0x849A, 0xE3BB,
+	0x849B, 0xE3C5, 0x849C, 0xBB5B, 0x849D, 0xE3BE, 0x849E, 0xBB59,
+	0x849F, 0xE3AF, 0x84A0, 0xE3CD, 0x84A1, 0xE3AE, 0x84A2, 0xE3C1,
+	0x84A4, 0xE3AD, 0x84A7, 0xE3BF, 0x84A8, 0xE3C8, 0x84A9, 0xE3C6,
+	0x84AA, 0xE3BA, 0x84AB, 0xE3B5, 0x84AC, 0xE3B3, 0x84AE, 0xE3B4,
+	0x84AF, 0xE3C7, 0x84B0, 0xE3D2, 0x84B1, 0xE3BC, 0x84B2, 0xBB5A,
+	0x84B4, 0xE3B7, 0x84B6, 0xE3CB, 0x84B8, 0xBB5D, 0x84B9, 0xE3B6,
+	0x84BA, 0xE3B0, 0x84BB, 0xE3C0, 0x84BC, 0xBB61, 0x84BF, 0xBB55,
+	0x84C0, 0xBB5E, 0x84C1, 0xE3B8, 0x84C2, 0xE3B2, 0x84C4, 0xBB57,
+	0x84C5, 0xDFD4, 0x84C6, 0xBB56, 0x84C7, 0xE3C3, 0x84C9, 0xBB54,
+	0x84CA, 0xBB63, 0x84CB, 0xBB5C, 0x84CC, 0xE3C4, 0x84CD, 0xE3B9,
+	0x84CE, 0xE3B1, 0x84CF, 0xE3CC, 0x84D0, 0xE3BD, 0x84D1, 0xBB62,
+	0x84D2, 0xE3D0, 0x84D3, 0xBB5F, 0x84D4, 0xE3CF, 0x84D6, 0xE3C9,
+	0x84D7, 0xE3CE, 0x84DB, 0xE3D1, 0x84E7, 0xE773, 0x84E8, 0xE774,
+	0x84E9, 0xE767, 0x84EA, 0xE766, 0x84EB, 0xE762, 0x84EC, 0xBDB4,
+	0x84EE, 0xBDAC, 0x84EF, 0xE776, 0x84F0, 0xE775, 0x84F1, 0xDFA9,
+	0x84F2, 0xE75F, 0x84F3, 0xE763, 0x84F4, 0xE75D, 0x84F6, 0xE770,
+	0x84F7, 0xE761, 0x84F9, 0xE777, 0x84FA, 0xE75A, 0x84FB, 0xE758,
+	0x84FC, 0xE764, 0x84FD, 0xE76E, 0x84FE, 0xE769, 0x84FF, 0xBDB6,
+	0x8500, 0xE74F, 0x8502, 0xE76D, 0x8506, 0xBDB7, 0x8507, 0xDFBD,
+	0x8508, 0xE75B, 0x8509, 0xE752, 0x850A, 0xE755, 0x850B, 0xE77B,
+	0x850C, 0xE75C, 0x850D, 0xE753, 0x850E, 0xE751, 0x850F, 0xE74E,
+	0x8511, 0xBDB0, 0x8512, 0xE765, 0x8513, 0xBDAF, 0x8514, 0xBDB3,
+	0x8515, 0xE760, 0x8516, 0xE768, 0x8517, 0xBDA9, 0x8518, 0xE778,
+	0x8519, 0xE77C, 0x851A, 0xBDAB, 0x851C, 0xE757, 0x851D, 0xE76B,
+	0x851E, 0xE76F, 0x851F, 0xE754, 0x8520, 0xE779, 0x8521, 0xBDB2,
+	0x8523, 0xBDB1, 0x8524, 0xE74C, 0x8525, 0xBDB5, 0x8526, 0xE772,
+	0x8527, 0xE756, 0x8528, 0xE76A, 0x8529, 0xE750, 0x852A, 0xE75E,
+	0x852B, 0xE759, 0x852C, 0xBDAD, 0x852D, 0xBDAE, 0x852E, 0xE76C,
+	0x852F, 0xE77D, 0x8530, 0xE77A, 0x8531, 0xE771, 0x853B, 0xE74D,
+	0x853D, 0xBDAA, 0x853E, 0xEB49, 0x8540, 0xEB40, 0x8541, 0xEB43,
+	0x8543, 0xBFBB, 0x8544, 0xEB45, 0x8545, 0xEAF9, 0x8546, 0xEB41,
+	0x8547, 0xEB47, 0x8548, 0xBFB8, 0x8549, 0xBFBC, 0x854A, 0xBFB6,
+	0x854D, 0xEAFB, 0x854E, 0xEB4C, 0x8551, 0xEB46, 0x8553, 0xEAFC,
+	0x8554, 0xEB55, 0x8555, 0xEB4F, 0x8556, 0xEAF8, 0x8557, 0xEE46,
+	0x8558, 0xEAFE, 0x8559, 0xBFB7, 0x855B, 0xEB4A, 0x855D, 0xEB54,
+	0x855E, 0xBFBF, 0x8560, 0xEB51, 0x8561, 0xEAFD, 0x8562, 0xEB44,
+	0x8563, 0xEB48, 0x8564, 0xEB42, 0x8565, 0xEB56, 0x8566, 0xEB53,
+	0x8567, 0xEB50, 0x8568, 0xBFB9, 0x8569, 0xBFBA, 0x856A, 0xBFBE,
+	0x856B, 0xEAFA, 0x856C, 0xEB57, 0x856D, 0xBFBD, 0x856E, 0xEB4D,
+	0x8571, 0xEB4B, 0x8575, 0xEB4E, 0x8576, 0xEE53, 0x8577, 0xEE40,
+	0x8578, 0xEE45, 0x8579, 0xEE52, 0x857A, 0xEE44, 0x857B, 0xEDFB,
+	0x857C, 0xEE41, 0x857E, 0xC1A2, 0x8580, 0xEDF4, 0x8581, 0xEE4D,
+	0x8582, 0xEE4F, 0x8583, 0xEDF3, 0x8584, 0xC1A1, 0x8585, 0xEE51,
+	0x8586, 0xEE49, 0x8587, 0xC1A8, 0x8588, 0xEE50, 0x8589, 0xEE42,
+	0x858A, 0xC1AA, 0x858B, 0xEDF9, 0x858C, 0xEB52, 0x858D, 0xEE4A,
+	0x858E, 0xEE47, 0x858F, 0xEDF5, 0x8590, 0xEE55, 0x8591, 0xC1A4,
+	0x8594, 0xC1A5, 0x8595, 0xEDF7, 0x8596, 0xEE48, 0x8598, 0xEE54,
+	0x8599, 0xEE4B, 0x859A, 0xEDFD, 0x859B, 0xC1A7, 0x859C, 0xC1A3,
+	0x859D, 0xEE4C, 0x859E, 0xEDFE, 0x859F, 0xEE56, 0x85A0, 0xEDF8,
+	0x85A1, 0xEE43, 0x85A2, 0xEE4E, 0x85A3, 0xEDFA, 0x85A4, 0xEDFC,
+	0x85A6, 0xC2CB, 0x85A7, 0xEDF6, 0x85A8, 0xC1A9, 0x85A9, 0xC2C4,
+	0x85AA, 0xC17E, 0x85AF, 0xC1A6, 0x85B0, 0xC2C8, 0x85B1, 0xF0B3,
+	0x85B3, 0xF0A9, 0x85B4, 0xF0A4, 0x85B5, 0xF0AA, 0x85B6, 0xF0B4,
+	0x85B7, 0xF0B8, 0x85B8, 0xF0B7, 0x85B9, 0xC2CA, 0x85BA, 0xC2C9,
+	0x85BD, 0xF0AB, 0x85BE, 0xF0B9, 0x85BF, 0xF0AE, 0x85C0, 0xF0A6,
+	0x85C2, 0xF0A8, 0x85C3, 0xF0A7, 0x85C4, 0xF0AD, 0x85C5, 0xF0B2,
+	0x85C6, 0xF0A5, 0x85C7, 0xF0AC, 0x85C8, 0xF0B1, 0x85C9, 0xC2C7,
+	0x85CB, 0xF0AF, 0x85CD, 0xC2C5, 0x85CE, 0xF0B0, 0x85CF, 0xC2C3,
+	0x85D0, 0xC2C6, 0x85D1, 0xF2D5, 0x85D2, 0xF0B5, 0x85D5, 0xC3C2,
+	0x85D7, 0xF2CD, 0x85D8, 0xF2D1, 0x85D9, 0xF2C9, 0x85DA, 0xF2CC,
+	0x85DC, 0xF2D4, 0x85DD, 0xC3C0, 0x85DE, 0xF2D9, 0x85DF, 0xF2D2,
+	0x85E1, 0xF2CA, 0x85E2, 0xF2DA, 0x85E3, 0xF2D3, 0x85E4, 0xC3C3,
+	0x85E5, 0xC3C4, 0x85E6, 0xF2D7, 0x85E8, 0xF2CB, 0x85E9, 0xC3BF,
+	0x85EA, 0xC3C1, 0x85EB, 0xF2C6, 0x85EC, 0xF2CE, 0x85ED, 0xF2C8,
+	0x85EF, 0xF2D8, 0x85F0, 0xF2D6, 0x85F1, 0xF2C7, 0x85F2, 0xF2CF,
+	0x85F6, 0xF4BE, 0x85F7, 0xC3C5, 0x85F8, 0xF2D0, 0x85F9, 0xC4A7,
+	0x85FA, 0xC4A9, 0x85FB, 0xC4A6, 0x85FD, 0xF4C3, 0x85FE, 0xF4BB,
+	0x85FF, 0xF4B9, 0x8600, 0xF4BD, 0x8601, 0xF4BA, 0x8604, 0xF4BF,
+	0x8605, 0xF4C1, 0x8606, 0xC4AA, 0x8607, 0xC4AC, 0x8609, 0xF4C0,
+	0x860A, 0xC4AD, 0x860B, 0xC4AB, 0x860C, 0xF4C2, 0x8611, 0xC4A8,
+	0x8617, 0xC4F4, 0x8618, 0xF5F1, 0x8619, 0xF5F7, 0x861A, 0xC4F6,
+	0x861B, 0xF4BC, 0x861C, 0xF5F6, 0x861E, 0xF5FD, 0x861F, 0xF5F4,
+	0x8620, 0xF5FB, 0x8621, 0xF5FA, 0x8622, 0xF4B8, 0x8623, 0xF5F5,
+	0x8624, 0xF0B6, 0x8625, 0xF5FE, 0x8626, 0xF5F3, 0x8627, 0xF5F8,
+	0x8629, 0xF5FC, 0x862A, 0xF5F2, 0x862C, 0xF74A, 0x862D, 0xC4F5,
+	0x862E, 0xF5F9, 0x8631, 0xF7F4, 0x8632, 0xF74B, 0x8633, 0xF749,
+	0x8634, 0xF747, 0x8635, 0xF748, 0x8636, 0xF74C, 0x8638, 0xC5D9,
+	0x8639, 0xF7F2, 0x863A, 0xF7F0, 0x863B, 0xF7F5, 0x863C, 0xF7F3,
+	0x863E, 0xF7F6, 0x863F, 0xC5DA, 0x8640, 0xF7F1, 0x8643, 0xF8BC,
+	0x8646, 0xF945, 0x8647, 0xF946, 0x8648, 0xF947, 0x864B, 0xF9C7,
+	0x864C, 0xF9BD, 0x864D, 0xCA4F, 0x864E, 0xAAEA, 0x8650, 0xAD68,
+	0x8652, 0xD3B8, 0x8653, 0xD3B7, 0x8654, 0xB040, 0x8655, 0xB342,
+	0x8656, 0xD77C, 0x8659, 0xD77B, 0x865B, 0xB5EA, 0x865C, 0xB8B8,
+	0x865E, 0xB8B7, 0x865F, 0xB8B9, 0x8661, 0xE3D4, 0x8662, 0xE77E,
+	0x8663, 0xEB58, 0x8664, 0xEB5A, 0x8665, 0xEB59, 0x8667, 0xC1AB,
+	0x8668, 0xEE57, 0x8669, 0xF0BA, 0x866A, 0xF9A5, 0x866B, 0xA6E4,
+	0x866D, 0xCDC9, 0x866E, 0xCDCA, 0x866F, 0xCDC8, 0x8670, 0xCDC7,
+	0x8671, 0xAAEB, 0x8673, 0xD0A9, 0x8674, 0xD0A7, 0x8677, 0xD0A6,
+	0x8679, 0xAD69, 0x867A, 0xAD6B, 0x867B, 0xAD6A, 0x867C, 0xD0A8,
+	0x8685, 0xD3C4, 0x8686, 0xD3C1, 0x8687, 0xD3BF, 0x868A, 0xB041,
+	0x868B, 0xD3C2, 0x868C, 0xB046, 0x868D, 0xD3BC, 0x868E, 0xD3CB,
+	0x8690, 0xD3CD, 0x8691, 0xD3BD, 0x8693, 0xB043, 0x8694, 0xD3CE,
+	0x8695, 0xD3C9, 0x8696, 0xD3BB, 0x8697, 0xD3C0, 0x8698, 0xD3CA,
+	0x8699, 0xD3C6, 0x869A, 0xD3C3, 0x869C, 0xB048, 0x869D, 0xD3CC,
+	0x869E, 0xD3BE, 0x86A1, 0xD3C7, 0x86A2, 0xD3B9, 0x86A3, 0xB047,
+	0x86A4, 0xB044, 0x86A5, 0xD3C5, 0x86A7, 0xD3C8, 0x86A8, 0xD3BA,
+	0x86A9, 0xB045, 0x86AA, 0xB042, 0x86AF, 0xB34C, 0x86B0, 0xD7A5,
+	0x86B1, 0xB34B, 0x86B3, 0xD7A8, 0x86B4, 0xD7AB, 0x86B5, 0xB348,
+	0x86B6, 0xB346, 0x86B7, 0xD77E, 0x86B8, 0xD7A9, 0x86B9, 0xD7A7,
+	0x86BA, 0xD7A4, 0x86BB, 0xD7AC, 0x86BC, 0xD7AD, 0x86BD, 0xD7AF,
+	0x86BE, 0xD7B0, 0x86BF, 0xD77D, 0x86C0, 0xB345, 0x86C1, 0xD7A2,
+	0x86C2, 0xD7A1, 0x86C3, 0xD7AE, 0x86C4, 0xB347, 0x86C5, 0xD7A3,
+	0x86C6, 0xB349, 0x86C7, 0xB344, 0x86C8, 0xD7A6, 0x86C9, 0xB34D,
+	0x86CB, 0xB34A, 0x86CC, 0xD7AA, 0x86D0, 0xB5F1, 0x86D1, 0xDBBF,
+	0x86D3, 0xDBB4, 0x86D4, 0xB5EE, 0x86D6, 0xDFE7, 0x86D7, 0xDBBD,
+	0x86D8, 0xDBB1, 0x86D9, 0xB5EC, 0x86DA, 0xDBB6, 0x86DB, 0xB5EF,
+	0x86DC, 0xDBBA, 0x86DD, 0xDBB8, 0x86DE, 0xB5F2, 0x86DF, 0xB5EB,
+	0x86E2, 0xDBB2, 0x86E3, 0xDBB5, 0x86E4, 0xB5F0, 0x86E6, 0xDBB3,
+	0x86E8, 0xDBBE, 0x86E9, 0xDBBC, 0x86EA, 0xDBB7, 0x86EB, 0xDBB9,
+	0x86EC, 0xDBBB, 0x86ED, 0xB5ED, 0x86F5, 0xDFE8, 0x86F6, 0xDFEE,
+	0x86F7, 0xDFE4, 0x86F8, 0xDFEA, 0x86F9, 0xB8BA, 0x86FA, 0xDFE6,
+	0x86FB, 0xB8C0, 0x86FE, 0xB8BF, 0x8700, 0xB8BE, 0x8701, 0xDFED,
+	0x8702, 0xB8C1, 0x8703, 0xB8C2, 0x8704, 0xDFE3, 0x8705, 0xDFF0,
+	0x8706, 0xB8C3, 0x8707, 0xB8BD, 0x8708, 0xB8BC, 0x8709, 0xDFEC,
+	0x870A, 0xB8C4, 0x870B, 0xDFE2, 0x870C, 0xDFE5, 0x870D, 0xDFEF,
+	0x870E, 0xDFEB, 0x8711, 0xE3F4, 0x8712, 0xE3E9, 0x8713, 0xB8BB,
+	0x8718, 0xBB6A, 0x8719, 0xE3DD, 0x871A, 0xE3F2, 0x871B, 0xE3DE,
+	0x871C, 0xBB65, 0x871E, 0xE3DB, 0x8720, 0xE3E4, 0x8721, 0xE3DC,
+	0x8722, 0xBB67, 0x8723, 0xE3D6, 0x8724, 0xE3F1, 0x8725, 0xBB68,
+	0x8726, 0xE3EE, 0x8727, 0xE3EF, 0x8728, 0xE3D7, 0x8729, 0xBB6D,
+	0x872A, 0xE3E6, 0x872C, 0xE3E0, 0x872D, 0xE3E7, 0x872E, 0xE3DA,
+	0x8730, 0xE3F3, 0x8731, 0xE3EB, 0x8732, 0xE3E5, 0x8733, 0xE3D5,
+	0x8734, 0xBB69, 0x8735, 0xE3EC, 0x8737, 0xBB6C, 0x8738, 0xE3F0,
+	0x873A, 0xE3EA, 0x873B, 0xBB66, 0x873C, 0xE3E8, 0x873E, 0xE3E2,
+	0x873F, 0xBB64, 0x8740, 0xE3D9, 0x8741, 0xE3E1, 0x8742, 0xE3ED,
+	0x8743, 0xE3DF, 0x8746, 0xE3E3, 0x874C, 0xBDC1, 0x874D, 0xDFE9,
+	0x874E, 0xE7B2, 0x874F, 0xE7BB, 0x8750, 0xE7B1, 0x8751, 0xE7AD,
+	0x8752, 0xE7AA, 0x8753, 0xBDC2, 0x8754, 0xE7A8, 0x8755, 0xBB6B,
+	0x8756, 0xE7A1, 0x8757, 0xBDC0, 0x8758, 0xE7A7, 0x8759, 0xBDBF,
+	0x875A, 0xE7AC, 0x875B, 0xE7A9, 0x875C, 0xE7B9, 0x875D, 0xE7B4,
+	0x875E, 0xE7AE, 0x875F, 0xE7B3, 0x8760, 0xBDBB, 0x8761, 0xE7AB,
+	0x8762, 0xE7BE, 0x8763, 0xE7A2, 0x8764, 0xE7A3, 0x8765, 0xE7BA,
+	0x8766, 0xBDBC, 0x8767, 0xE7BF, 0x8768, 0xBDBE, 0x8769, 0xE7C0,
+	0x876A, 0xE7B0, 0x876B, 0xE3D8, 0x876C, 0xE7B6, 0x876D, 0xE7AF,
+	0x876E, 0xE7B8, 0x876F, 0xE7B5, 0x8773, 0xE7A6, 0x8774, 0xBDB9,
+	0x8775, 0xE7BD, 0x8776, 0xBDBA, 0x8777, 0xE7A4, 0x8778, 0xBDBD,
+	0x8779, 0xEB64, 0x877A, 0xE7B7, 0x877B, 0xE7BC, 0x8781, 0xEB61,
+	0x8782, 0xBDB8, 0x8783, 0xBFC0, 0x8784, 0xEB6B, 0x8785, 0xEB67,
+	0x8787, 0xEB65, 0x8788, 0xEB60, 0x8789, 0xEB6F, 0x878D, 0xBFC4,
+	0x878F, 0xEB5C, 0x8790, 0xEB68, 0x8791, 0xEB69, 0x8792, 0xEB5F,
+	0x8793, 0xEB5E, 0x8794, 0xEB6C, 0x8796, 0xEB62, 0x8797, 0xEB5D,
+	0x8798, 0xEB63, 0x879A, 0xEB6E, 0x879B, 0xEB5B, 0x879C, 0xEB6D,
+	0x879D, 0xEB6A, 0x879E, 0xBFC2, 0x879F, 0xBFC1, 0x87A2, 0xBFC3,
+	0x87A3, 0xEB66, 0x87A4, 0xF0CB, 0x87AA, 0xEE59, 0x87AB, 0xC1B1,
+	0x87AC, 0xEE5D, 0x87AD, 0xEE5A, 0x87AE, 0xEE61, 0x87AF, 0xEE67,
+	0x87B0, 0xEE5C, 0x87B2, 0xEE70, 0x87B3, 0xC1AE, 0x87B4, 0xEE6A,
+	0x87B5, 0xEE5F, 0x87B6, 0xEE6B, 0x87B7, 0xEE66, 0x87B8, 0xEE6D,
+	0x87B9, 0xEE5E, 0x87BA, 0xC1B3, 0x87BB, 0xC1B2, 0x87BC, 0xEE60,
+	0x87BD, 0xEE6E, 0x87BE, 0xEE58, 0x87BF, 0xEE6C, 0x87C0, 0xC1AC,
+	0x87C2, 0xEE64, 0x87C3, 0xEE63, 0x87C4, 0xEE68, 0x87C5, 0xEE5B,
+	0x87C6, 0xC1B0, 0x87C8, 0xC1B4, 0x87C9, 0xEE62, 0x87CA, 0xEE69,
+	0x87CB, 0xC1B5, 0x87CC, 0xEE65, 0x87D1, 0xC1AD, 0x87D2, 0xC1AF,
+	0x87D3, 0xF0C7, 0x87D4, 0xF0C5, 0x87D7, 0xF0CC, 0x87D8, 0xF0C9,
+	0x87D9, 0xF0CD, 0x87DB, 0xF0BE, 0x87DC, 0xF0C6, 0x87DD, 0xF0D1,
+	0x87DE, 0xEE6F, 0x87DF, 0xF0C2, 0x87E0, 0xC2CF, 0x87E1, 0xE7A5,
+	0x87E2, 0xF0BD, 0x87E3, 0xF0CA, 0x87E4, 0xF0C4, 0x87E5, 0xF0C1,
+	0x87E6, 0xF0BC, 0x87E7, 0xF0BB, 0x87E8, 0xF0D0, 0x87EA, 0xF0C0,
+	0x87EB, 0xF0BF, 0x87EC, 0xC2CD, 0x87ED, 0xF0C8, 0x87EF, 0xC2CC,
+	0x87F2, 0xC2CE, 0x87F3, 0xF0C3, 0x87F4, 0xF0CF, 0x87F6, 0xF2DE,
+	0x87F7, 0xF2DF, 0x87F9, 0xC3C9, 0x87FA, 0xF2DC, 0x87FB, 0xC3C6,
+	0x87FC, 0xF2E4, 0x87FE, 0xC3CA, 0x87FF, 0xF2E6, 0x8800, 0xF2DB,
+	0x8801, 0xF0CE, 0x8802, 0xF2E8, 0x8803, 0xF2DD, 0x8805, 0xC3C7,
+	0x8806, 0xF2E3, 0x8808, 0xF2E5, 0x8809, 0xF2E0, 0x880A, 0xF2E7,
+	0x880B, 0xF2E2, 0x880C, 0xF2E1, 0x880D, 0xC3C8, 0x8810, 0xF4C5,
+	0x8811, 0xF4C6, 0x8813, 0xF4C8, 0x8814, 0xC4AE, 0x8815, 0xC4AF,
+	0x8816, 0xF4C9, 0x8817, 0xF4C7, 0x8819, 0xF4C4, 0x881B, 0xF642,
+	0x881C, 0xF645, 0x881D, 0xF641, 0x881F, 0xC4FA, 0x8820, 0xF643,
+	0x8821, 0xC4F9, 0x8822, 0xC4F8, 0x8823, 0xC4F7, 0x8824, 0xF644,
+	0x8825, 0xF751, 0x8826, 0xF74F, 0x8828, 0xF74E, 0x8829, 0xF640,
+	0x882A, 0xF750, 0x882B, 0xF646, 0x882C, 0xF74D, 0x882E, 0xF7F9,
+	0x882F, 0xF7D7, 0x8830, 0xF7F7, 0x8831, 0xC5DB, 0x8832, 0xF7F8,
+	0x8833, 0xF7FA, 0x8835, 0xF8BF, 0x8836, 0xC5FA, 0x8837, 0xF8BE,
+	0x8838, 0xF8BD, 0x8839, 0xC5FB, 0x883B, 0xC65A, 0x883C, 0xF96E,
+	0x883D, 0xF9A7, 0x883E, 0xF9A6, 0x883F, 0xF9A8, 0x8840, 0xA6E5,
+	0x8841, 0xD0AA, 0x8843, 0xD3CF, 0x8844, 0xD3D0, 0x8848, 0xDBC0,
+	0x884A, 0xF647, 0x884B, 0xF8C0, 0x884C, 0xA6E6, 0x884D, 0xAD6C,
+	0x884E, 0xD0AB, 0x8852, 0xD7B1, 0x8853, 0xB34E, 0x8855, 0xDBC2,
+	0x8856, 0xDBC1, 0x8857, 0xB5F3, 0x8859, 0xB8C5, 0x885A, 0xE7C1,
+	0x885B, 0xBDC3, 0x885D, 0xBDC4, 0x8861, 0xBFC5, 0x8862, 0xC5FC,
+	0x8863, 0xA6E7, 0x8867, 0xD0AC, 0x8868, 0xAAED, 0x8869, 0xD0AE,
+	0x886A, 0xD0AD, 0x886B, 0xAD6D, 0x886D, 0xD3D1, 0x886F, 0xD3D8,
+	0x8870, 0xB049, 0x8871, 0xD3D6, 0x8872, 0xD3D4, 0x8874, 0xD3DB,
+	0x8875, 0xD3D2, 0x8876, 0xD3D3, 0x8877, 0xB04A, 0x8879, 0xB04E,
+	0x887C, 0xD3DC, 0x887D, 0xB04D, 0x887E, 0xD3DA, 0x887F, 0xD3D7,
+	0x8880, 0xD3D5, 0x8881, 0xB04B, 0x8882, 0xB04C, 0x8883, 0xD3D9,
+	0x8888, 0xB350, 0x8889, 0xD7B2, 0x888B, 0xB355, 0x888C, 0xD7C2,
+	0x888D, 0xB354, 0x888E, 0xD7C4, 0x8891, 0xD7B8, 0x8892, 0xB352,
+	0x8893, 0xD7C3, 0x8895, 0xD7B3, 0x8896, 0xB353, 0x8897, 0xD7BF,
+	0x8898, 0xD7BB, 0x8899, 0xD7BD, 0x889A, 0xD7B7, 0x889B, 0xD7BE,
+	0x889E, 0xB34F, 0x889F, 0xD7BA, 0x88A1, 0xD7B9, 0x88A2, 0xD7B5,
+	0x88A4, 0xD7C0, 0x88A7, 0xD7BC, 0x88A8, 0xD7B4, 0x88AA, 0xD7B6,
+	0x88AB, 0xB351, 0x88AC, 0xD7C1, 0x88B1, 0xB5F6, 0x88B2, 0xDBCD,
+	0x88B6, 0xDBC9, 0x88B7, 0xDBCB, 0x88B8, 0xDBC6, 0x88B9, 0xDBC5,
+	0x88BA, 0xDBC3, 0x88BC, 0xDBCA, 0x88BD, 0xDBCC, 0x88BE, 0xDBC8,
+	0x88C0, 0xDBC7, 0x88C1, 0xB5F4, 0x88C2, 0xB5F5, 0x88C9, 0xDBCF,
+	0x88CA, 0xB8CD, 0x88CB, 0xDFF2, 0x88CC, 0xDFF8, 0x88CD, 0xDFF3,
+	0x88CE, 0xDFF4, 0x88CF, 0xF9D8, 0x88D0, 0xDFF9, 0x88D2, 0xB8CF,
+	0x88D4, 0xB8C7, 0x88D5, 0xB8CE, 0x88D6, 0xDFF1, 0x88D7, 0xDBC4,
+	0x88D8, 0xB8CA, 0x88D9, 0xB8C8, 0x88DA, 0xDFF7, 0x88DB, 0xDFF6,
+	0x88DC, 0xB8C9, 0x88DD, 0xB8CB, 0x88DE, 0xDFF5, 0x88DF, 0xB8C6,
+	0x88E1, 0xB8CC, 0x88E7, 0xE3F6, 0x88E8, 0xBB74, 0x88EB, 0xE442,
+	0x88EC, 0xE441, 0x88EE, 0xE3FB, 0x88EF, 0xBB76, 0x88F0, 0xE440,
+	0x88F1, 0xE3F7, 0x88F2, 0xE3F8, 0x88F3, 0xBB6E, 0x88F4, 0xBB70,
+	0x88F6, 0xE3FD, 0x88F7, 0xE3F5, 0x88F8, 0xBB72, 0x88F9, 0xBB71,
+	0x88FA, 0xE3F9, 0x88FB, 0xE3FE, 0x88FC, 0xE3FC, 0x88FD, 0xBB73,
+	0x88FE, 0xE3FA, 0x8901, 0xDBCE, 0x8902, 0xBB6F, 0x8905, 0xE7C2,
+	0x8906, 0xE7C9, 0x8907, 0xBDC6, 0x8909, 0xE7CD, 0x890A, 0xBDCA,
+	0x890B, 0xE7C5, 0x890C, 0xE7C3, 0x890E, 0xE7CC, 0x8910, 0xBDC5,
+	0x8911, 0xE7CB, 0x8912, 0xBDC7, 0x8913, 0xBDC8, 0x8914, 0xE7C4,
+	0x8915, 0xBDC9, 0x8916, 0xE7CA, 0x8917, 0xE7C6, 0x8918, 0xE7C7,
+	0x8919, 0xE7C8, 0x891A, 0xBB75, 0x891E, 0xEB70, 0x891F, 0xEB7C,
+	0x8921, 0xBFCA, 0x8922, 0xEB77, 0x8923, 0xEB79, 0x8925, 0xBFC8,
+	0x8926, 0xEB71, 0x8927, 0xEB75, 0x8929, 0xEB78, 0x892A, 0xBFC6,
+	0x892B, 0xBFC9, 0x892C, 0xEB7B, 0x892D, 0xEB73, 0x892E, 0xEB74,
+	0x892F, 0xEB7A, 0x8930, 0xEB72, 0x8931, 0xEB76, 0x8932, 0xBFC7,
+	0x8933, 0xEE72, 0x8935, 0xEE71, 0x8936, 0xC1B7, 0x8937, 0xEE77,
+	0x8938, 0xC1B9, 0x893B, 0xC1B6, 0x893C, 0xEE73, 0x893D, 0xC1BA,
+	0x893E, 0xEE74, 0x8941, 0xEE75, 0x8942, 0xEE78, 0x8944, 0xC1B8,
+	0x8946, 0xF0D6, 0x8949, 0xF0D9, 0x894B, 0xF0D3, 0x894C, 0xF0D5,
+	0x894F, 0xF0D4, 0x8950, 0xF0D7, 0x8951, 0xF0D8, 0x8952, 0xEE76,
+	0x8953, 0xF0D2, 0x8956, 0xC3CD, 0x8957, 0xF2EC, 0x8958, 0xF2EF,
+	0x8959, 0xF2F1, 0x895A, 0xF2EA, 0x895B, 0xF2EB, 0x895C, 0xF2EE,
+	0x895D, 0xF2F0, 0x895E, 0xC3CE, 0x895F, 0xC3CC, 0x8960, 0xC3CB,
+	0x8961, 0xF2ED, 0x8962, 0xF2E9, 0x8963, 0xF4CA, 0x8964, 0xC4B0,
+	0x8966, 0xF4CB, 0x8969, 0xF649, 0x896A, 0xC4FB, 0x896B, 0xF64B,
+	0x896C, 0xC4FC, 0x896D, 0xF648, 0x896E, 0xF64A, 0x896F, 0xC5A8,
+	0x8971, 0xF752, 0x8972, 0xC5A7, 0x8973, 0xF7FD, 0x8974, 0xF7FC,
+	0x8976, 0xF7FB, 0x8979, 0xF948, 0x897A, 0xF949, 0x897B, 0xF94B,
+	0x897C, 0xF94A, 0x897E, 0xCA50, 0x897F, 0xA6E8, 0x8981, 0xAD6E,
+	0x8982, 0xD7C5, 0x8983, 0xB5F7, 0x8985, 0xDFFA, 0x8986, 0xC2D0,
+	0x8988, 0xF2F2, 0x898B, 0xA8A3, 0x898F, 0xB357, 0x8993, 0xB356,
+	0x8995, 0xDBD0, 0x8996, 0xB5F8, 0x8997, 0xDBD2, 0x8998, 0xDBD1,
+	0x899B, 0xDFFB, 0x899C, 0xB8D0, 0x899D, 0xE443, 0x899E, 0xE446,
+	0x899F, 0xE445, 0x89A1, 0xE444, 0x89A2, 0xE7CE, 0x89A3, 0xE7D0,
+	0x89A4, 0xE7CF, 0x89A6, 0xBFCC, 0x89AA, 0xBFCB, 0x89AC, 0xC1BB,
+	0x89AD, 0xEE79, 0x89AE, 0xEE7B, 0x89AF, 0xEE7A, 0x89B2, 0xC2D1,
+	0x89B6, 0xF2F4, 0x89B7, 0xF2F3, 0x89B9, 0xF4CC, 0x89BA, 0xC4B1,
+	0x89BD, 0xC4FD, 0x89BE, 0xF754, 0x89BF, 0xF753, 0x89C0, 0xC65B,
+	0x89D2, 0xA8A4, 0x89D3, 0xD0AF, 0x89D4, 0xAD6F, 0x89D5, 0xD7C8,
+	0x89D6, 0xD7C6, 0x89D9, 0xD7C7, 0x89DA, 0xDBD4, 0x89DB, 0xDBD5,
+	0x89DC, 0xE043, 0x89DD, 0xDBD3, 0x89DF, 0xDFFC, 0x89E0, 0xE041,
+	0x89E1, 0xE040, 0x89E2, 0xE042, 0x89E3, 0xB8D1, 0x89E4, 0xDFFE,
+	0x89E5, 0xDFFD, 0x89E6, 0xE044, 0x89E8, 0xE449, 0x89E9, 0xE447,
+	0x89EB, 0xE448, 0x89EC, 0xE7D3, 0x89ED, 0xE7D1, 0x89F0, 0xE7D2,
+	0x89F1, 0xEB7D, 0x89F2, 0xEE7C, 0x89F3, 0xEE7D, 0x89F4, 0xC2D2,
+	0x89F6, 0xF2F5, 0x89F7, 0xF4CD, 0x89F8, 0xC4B2, 0x89FA, 0xF64C,
+	0x89FB, 0xF755, 0x89FC, 0xC5A9, 0x89FE, 0xF7FE, 0x89FF, 0xF94C,
+	0x8A00, 0xA8A5, 0x8A02, 0xAD71, 0x8A03, 0xAD72, 0x8A04, 0xD0B0,
+	0x8A07, 0xD0B1, 0x8A08, 0xAD70, 0x8A0A, 0xB054, 0x8A0C, 0xB052,
+	0x8A0E, 0xB051, 0x8A0F, 0xB058, 0x8A10, 0xB050, 0x8A11, 0xB059,
+	0x8A12, 0xD3DD, 0x8A13, 0xB056, 0x8A15, 0xB053, 0x8A16, 0xB057,
+	0x8A17, 0xB055, 0x8A18, 0xB04F, 0x8A1B, 0xB35F, 0x8A1D, 0xB359,
+	0x8A1E, 0xD7CC, 0x8A1F, 0xB35E, 0x8A22, 0xB360, 0x8A23, 0xB35A,
+	0x8A25, 0xB35B, 0x8A27, 0xD7CA, 0x8A2A, 0xB358, 0x8A2C, 0xD7CB,
+	0x8A2D, 0xB35D, 0x8A30, 0xD7C9, 0x8A31, 0xB35C, 0x8A34, 0xB644,
+	0x8A36, 0xB646, 0x8A39, 0xDBD8, 0x8A3A, 0xB645, 0x8A3B, 0xB5F9,
+	0x8A3C, 0xB5FD, 0x8A3E, 0xB8E4, 0x8A3F, 0xE049, 0x8A40, 0xDBDA,
+	0x8A41, 0xB5FE, 0x8A44, 0xDBDD, 0x8A45, 0xDBDE, 0x8A46, 0xB643,
+	0x8A48, 0xDBE0, 0x8A4A, 0xDBE2, 0x8A4C, 0xDBE3, 0x8A4D, 0xDBD7,
+	0x8A4E, 0xDBD6, 0x8A4F, 0xDBE4, 0x8A50, 0xB642, 0x8A51, 0xDBE1,
+	0x8A52, 0xDBDF, 0x8A54, 0xB640, 0x8A55, 0xB5FB, 0x8A56, 0xB647,
+	0x8A57, 0xDBDB, 0x8A58, 0xDBDC, 0x8A59, 0xDBD9, 0x8A5B, 0xB641,
+	0x8A5E, 0xB5FC, 0x8A60, 0xB5FA, 0x8A61, 0xE048, 0x8A62, 0xB8DF,
+	0x8A63, 0xB8DA, 0x8A66, 0xB8D5, 0x8A68, 0xB8E5, 0x8A69, 0xB8D6,
+	0x8A6B, 0xB8D2, 0x8A6C, 0xB8E1, 0x8A6D, 0xB8DE, 0x8A6E, 0xB8E0,
+	0x8A70, 0xB8D7, 0x8A71, 0xB8DC, 0x8A72, 0xB8D3, 0x8A73, 0xB8D4,
+	0x8A74, 0xE050, 0x8A75, 0xE04D, 0x8A76, 0xE045, 0x8A77, 0xE04A,
+	0x8A79, 0xB8E2, 0x8A7A, 0xE051, 0x8A7B, 0xB8E3, 0x8A7C, 0xB8D9,
+	0x8A7F, 0xE047, 0x8A81, 0xE04F, 0x8A82, 0xE04B, 0x8A83, 0xE04E,
+	0x8A84, 0xE04C, 0x8A85, 0xB8DD, 0x8A86, 0xE046, 0x8A87, 0xB8D8,
+	0x8A8B, 0xE44C, 0x8A8C, 0xBB78, 0x8A8D, 0xBB7B, 0x8A8F, 0xE44E,
+	0x8A91, 0xBBA5, 0x8A92, 0xE44D, 0x8A93, 0xBB7D, 0x8A95, 0xBDCF,
+	0x8A96, 0xE44F, 0x8A98, 0xBBA4, 0x8A99, 0xE44B, 0x8A9A, 0xBBA6,
+	0x8A9E, 0xBB79, 0x8AA0, 0xB8DB, 0x8AA1, 0xBB7C, 0x8AA3, 0xBB7A,
+	0x8AA4, 0xBB7E, 0x8AA5, 0xBBA2, 0x8AA6, 0xBB77, 0x8AA7, 0xBBA7,
+	0x8AA8, 0xBBA3, 0x8AAA, 0xBBA1, 0x8AAB, 0xE44A, 0x8AB0, 0xBDD6,
+	0x8AB2, 0xBDD2, 0x8AB6, 0xBDD9, 0x8AB8, 0xE7D6, 0x8AB9, 0xBDDA,
+	0x8ABA, 0xE7E2, 0x8ABB, 0xE7DB, 0x8ABC, 0xBDCB, 0x8ABD, 0xE7E3,
+	0x8ABE, 0xE7DD, 0x8ABF, 0xBDD5, 0x8AC0, 0xE7DE, 0x8AC2, 0xBDD4,
+	0x8AC3, 0xE7E1, 0x8AC4, 0xBDCE, 0x8AC5, 0xE7DF, 0x8AC6, 0xE7D5,
+	0x8AC7, 0xBDCD, 0x8AC8, 0xEBAA, 0x8AC9, 0xBDD3, 0x8ACB, 0xBDD0,
+	0x8ACD, 0xBDD8, 0x8ACF, 0xE7D4, 0x8AD1, 0xE7D8, 0x8AD2, 0xBDCC,
+	0x8AD3, 0xE7D7, 0x8AD4, 0xE7D9, 0x8AD5, 0xE7DA, 0x8AD6, 0xBDD7,
+	0x8AD7, 0xE7DC, 0x8AD8, 0xE7E0, 0x8AD9, 0xE7E4, 0x8ADB, 0xBDDB,
+	0x8ADC, 0xBFD2, 0x8ADD, 0xEBA5, 0x8ADE, 0xEBAB, 0x8ADF, 0xEBA8,
+	0x8AE0, 0xEB7E, 0x8AE1, 0xEBAC, 0x8AE2, 0xEBA1, 0x8AE4, 0xEBA7,
+	0x8AE6, 0xBFCD, 0x8AE7, 0xBFD3, 0x8AE8, 0xEBAD, 0x8AEB, 0xBFCF,
+	0x8AED, 0xBFD9, 0x8AEE, 0xBFD4, 0x8AEF, 0xEBAF, 0x8AF0, 0xEBA9,
+	0x8AF1, 0xBFD0, 0x8AF2, 0xEBA2, 0x8AF3, 0xBFDA, 0x8AF4, 0xEBA3,
+	0x8AF5, 0xEBA4, 0x8AF6, 0xBFDB, 0x8AF7, 0xBFD8, 0x8AF8, 0xBDD1,
+	0x8AFA, 0xBFCE, 0x8AFB, 0xEBB0, 0x8AFC, 0xBFDC, 0x8AFE, 0xBFD5,
+	0x8AFF, 0xEBAE, 0x8B00, 0xBFD1, 0x8B01, 0xBFD6, 0x8B02, 0xBFD7,
+	0x8B04, 0xC1C3, 0x8B05, 0xEEA4, 0x8B06, 0xEEAD, 0x8B07, 0xEEAA,
+	0x8B08, 0xEEAC, 0x8B0A, 0xC1C0, 0x8B0B, 0xEEA5, 0x8B0D, 0xEEAB,
+	0x8B0E, 0xC1BC, 0x8B0F, 0xEEA7, 0x8B10, 0xC1C4, 0x8B11, 0xEEA3,
+	0x8B12, 0xEEA8, 0x8B13, 0xEEAF, 0x8B14, 0xEBA6, 0x8B15, 0xEEA9,
+	0x8B16, 0xEEA2, 0x8B17, 0xC1BD, 0x8B18, 0xEEA1, 0x8B19, 0xC1BE,
+	0x8B1A, 0xEEB0, 0x8B1B, 0xC1BF, 0x8B1C, 0xEEAE, 0x8B1D, 0xC1C2,
+	0x8B1E, 0xEE7E, 0x8B20, 0xC1C1, 0x8B22, 0xEEA6, 0x8B23, 0xF0DC,
+	0x8B24, 0xF0EA, 0x8B25, 0xF0E5, 0x8B26, 0xF0E7, 0x8B27, 0xF0DB,
+	0x8B28, 0xC2D3, 0x8B2A, 0xF0DA, 0x8B2B, 0xC2D6, 0x8B2C, 0xC2D5,
+	0x8B2E, 0xF0E9, 0x8B2F, 0xF0E1, 0x8B30, 0xF0DE, 0x8B31, 0xF0E4,
+	0x8B33, 0xF0DD, 0x8B35, 0xF0DF, 0x8B36, 0xF0E8, 0x8B37, 0xF0E6,
+	0x8B39, 0xC2D4, 0x8B3A, 0xF0ED, 0x8B3B, 0xF0EB, 0x8B3C, 0xF0E2,
+	0x8B3D, 0xF0EC, 0x8B3E, 0xF0E3, 0x8B40, 0xF2F9, 0x8B41, 0xC3CF,
+	0x8B42, 0xF341, 0x8B45, 0xF64F, 0x8B46, 0xC3D6, 0x8B47, 0xF0E0,
+	0x8B48, 0xF2F7, 0x8B49, 0xC3D2, 0x8B4A, 0xF2F8, 0x8B4B, 0xF2FD,
+	0x8B4E, 0xC3D4, 0x8B4F, 0xC3D5, 0x8B50, 0xF2F6, 0x8B51, 0xF340,
+	0x8B52, 0xF342, 0x8B53, 0xF2FA, 0x8B54, 0xF2FC, 0x8B55, 0xF2FE,
+	0x8B56, 0xF2FB, 0x8B57, 0xF343, 0x8B58, 0xC3D1, 0x8B59, 0xC3D7,
+	0x8B5A, 0xC3D3, 0x8B5C, 0xC3D0, 0x8B5D, 0xF4D0, 0x8B5F, 0xC4B7,
+	0x8B60, 0xF4CE, 0x8B63, 0xF4D2, 0x8B65, 0xF4D3, 0x8B66, 0xC4B5,
+	0x8B67, 0xF4D4, 0x8B68, 0xF4D1, 0x8B6A, 0xF4CF, 0x8B6B, 0xC4B8,
+	0x8B6C, 0xC4B4, 0x8B6D, 0xF4D5, 0x8B6F, 0xC4B6, 0x8B70, 0xC4B3,
+	0x8B74, 0xC4FE, 0x8B77, 0xC540, 0x8B78, 0xF64E, 0x8B79, 0xF64D,
+	0x8B7A, 0xF650, 0x8B7B, 0xF651, 0x8B7D, 0xC541, 0x8B7E, 0xF756,
+	0x8B7F, 0xF75B, 0x8B80, 0xC5AA, 0x8B82, 0xF758, 0x8B84, 0xF757,
+	0x8B85, 0xF75A, 0x8B86, 0xF759, 0x8B88, 0xF843, 0x8B8A, 0xC5DC,
+	0x8B8B, 0xF842, 0x8B8C, 0xF840, 0x8B8E, 0xF841, 0x8B92, 0xC5FE,
+	0x8B93, 0xC5FD, 0x8B94, 0xF8C1, 0x8B95, 0xF8C2, 0x8B96, 0xC640,
+	0x8B98, 0xF94D, 0x8B99, 0xF94E, 0x8B9A, 0xC667, 0x8B9C, 0xC66D,
+	0x8B9E, 0xF9A9, 0x8B9F, 0xF9C8, 0x8C37, 0xA8A6, 0x8C39, 0xD7CD,
+	0x8C3B, 0xD7CE, 0x8C3C, 0xE052, 0x8C3D, 0xE450, 0x8C3E, 0xE7E5,
+	0x8C3F, 0xC1C6, 0x8C41, 0xC1C5, 0x8C42, 0xF0EE, 0x8C43, 0xF344,
+	0x8C45, 0xF844, 0x8C46, 0xA8A7, 0x8C47, 0xD3DE, 0x8C48, 0xB05A,
+	0x8C49, 0xB361, 0x8C4A, 0xE054, 0x8C4B, 0xE053, 0x8C4C, 0xBDDC,
+	0x8C4D, 0xE7E6, 0x8C4E, 0xBDDD, 0x8C4F, 0xEEB1, 0x8C50, 0xC2D7,
+	0x8C54, 0xC676, 0x8C55, 0xA8A8, 0x8C56, 0xCDCB, 0x8C57, 0xD3DF,
+	0x8C5A, 0xB362, 0x8C5C, 0xD7CF, 0x8C5D, 0xD7D0, 0x8C5F, 0xDBE5,
+	0x8C61, 0xB648, 0x8C62, 0xB8E6, 0x8C64, 0xE056, 0x8C65, 0xE055,
+	0x8C66, 0xE057, 0x8C68, 0xE451, 0x8C69, 0xE452, 0x8C6A, 0xBBA8,
+	0x8C6B, 0xBFDD, 0x8C6C, 0xBDDE, 0x8C6D, 0xBFDE, 0x8C6F, 0xEEB5,
+	0x8C70, 0xEEB2, 0x8C71, 0xEEB4, 0x8C72, 0xEEB3, 0x8C73, 0xC1C7,
+	0x8C75, 0xF0EF, 0x8C76, 0xF346, 0x8C77, 0xF345, 0x8C78, 0xCBA4,
+	0x8C79, 0xB05C, 0x8C7A, 0xB05B, 0x8C7B, 0xD3E0, 0x8C7D, 0xD7D1,
+	0x8C80, 0xDBE7, 0x8C81, 0xDBE6, 0x8C82, 0xB649, 0x8C84, 0xE059,
+	0x8C85, 0xE05A, 0x8C86, 0xE058, 0x8C89, 0xB8E8, 0x8C8A, 0xB8E7,
+	0x8C8C, 0xBBAA, 0x8C8D, 0xBBA9, 0x8C8F, 0xE7E7, 0x8C90, 0xEBB3,
+	0x8C91, 0xEBB1, 0x8C92, 0xEBB2, 0x8C93, 0xBFDF, 0x8C94, 0xEEB7,
+	0x8C95, 0xEEB6, 0x8C97, 0xF0F2, 0x8C98, 0xF0F1, 0x8C99, 0xF0F0,
+	0x8C9A, 0xF347, 0x8C9C, 0xF9AA, 0x8C9D, 0xA8A9, 0x8C9E, 0xAD73,
+	0x8CA0, 0xAD74, 0x8CA1, 0xB05D, 0x8CA2, 0xB05E, 0x8CA3, 0xD3E2,
+	0x8CA4, 0xD3E1, 0x8CA5, 0xD7D2, 0x8CA7, 0xB368, 0x8CA8, 0xB366,
+	0x8CA9, 0xB363, 0x8CAA, 0xB367, 0x8CAB, 0xB365, 0x8CAC, 0xB364,
+	0x8CAF, 0xB64A, 0x8CB0, 0xDBEA, 0x8CB2, 0xB8ED, 0x8CB3, 0xB64C,
+	0x8CB4, 0xB651, 0x8CB5, 0xDBEC, 0x8CB6, 0xB653, 0x8CB7, 0xB652,
+	0x8CB8, 0xB655, 0x8CB9, 0xDBEB, 0x8CBA, 0xDBE8, 0x8CBB, 0xB64F,
+	0x8CBC, 0xB64B, 0x8CBD, 0xB64D, 0x8CBE, 0xDBE9, 0x8CBF, 0xB654,
+	0x8CC0, 0xB650, 0x8CC1, 0xB64E, 0x8CC2, 0xB8EF, 0x8CC3, 0xB8EE,
+	0x8CC4, 0xB8EC, 0x8CC5, 0xB8F0, 0x8CC7, 0xB8EA, 0x8CC8, 0xB8EB,
+	0x8CCA, 0xB8E9, 0x8CCC, 0xE05B, 0x8CCF, 0xE454, 0x8CD1, 0xBBAC,
+	0x8CD2, 0xBBAD, 0x8CD3, 0xBBAB, 0x8CD5, 0xE453, 0x8CD7, 0xE455,
+	0x8CD9, 0xE7EA, 0x8CDA, 0xE7EC, 0x8CDC, 0xBDE7, 0x8CDD, 0xE7ED,
+	0x8CDE, 0xBDE0, 0x8CDF, 0xE7E9, 0x8CE0, 0xBDDF, 0x8CE1, 0xBDE9,
+	0x8CE2, 0xBDE5, 0x8CE3, 0xBDE6, 0x8CE4, 0xBDE2, 0x8CE5, 0xE7E8,
+	0x8CE6, 0xBDE1, 0x8CE7, 0xE7EE, 0x8CE8, 0xE7EB, 0x8CEA, 0xBDE8,
+	0x8CEC, 0xBDE3, 0x8CED, 0xBDE4, 0x8CEE, 0xEBB5, 0x8CF0, 0xEBB7,
+	0x8CF1, 0xEBB6, 0x8CF3, 0xEBB8, 0x8CF4, 0xBFE0, 0x8CF5, 0xEBB4,
+	0x8CF8, 0xC1CB, 0x8CF9, 0xEEB8, 0x8CFA, 0xC1C8, 0x8CFB, 0xC1CC,
+	0x8CFC, 0xC1CA, 0x8CFD, 0xC1C9, 0x8CFE, 0xF0F3, 0x8D00, 0xF0F6,
+	0x8D02, 0xF0F5, 0x8D04, 0xF0F4, 0x8D05, 0xC2D8, 0x8D06, 0xF348,
+	0x8D07, 0xF349, 0x8D08, 0xC3D8, 0x8D09, 0xF34A, 0x8D0A, 0xC3D9,
+	0x8D0D, 0xC4BA, 0x8D0F, 0xC4B9, 0x8D10, 0xF652, 0x8D13, 0xC542,
+	0x8D14, 0xF653, 0x8D15, 0xF75C, 0x8D16, 0xC5AB, 0x8D17, 0xC5AC,
+	0x8D19, 0xF845, 0x8D1B, 0xC642, 0x8D64, 0xA8AA, 0x8D66, 0xB36A,
+	0x8D67, 0xB369, 0x8D68, 0xE05C, 0x8D69, 0xE05D, 0x8D6B, 0xBBAE,
+	0x8D6C, 0xEBB9, 0x8D6D, 0xBDEA, 0x8D6E, 0xEBBA, 0x8D6F, 0xEEB9,
+	0x8D70, 0xA8AB, 0x8D72, 0xD0B2, 0x8D73, 0xAD76, 0x8D74, 0xAD75,
+	0x8D76, 0xD3E3, 0x8D77, 0xB05F, 0x8D78, 0xD3E4, 0x8D79, 0xD7D5,
+	0x8D7B, 0xD7D4, 0x8D7D, 0xD7D3, 0x8D80, 0xDBEE, 0x8D81, 0xB658,
+	0x8D84, 0xDBED, 0x8D85, 0xB657, 0x8D89, 0xDBEF, 0x8D8A, 0xB656,
+	0x8D8C, 0xE05F, 0x8D8D, 0xE062, 0x8D8E, 0xE060, 0x8D8F, 0xE061,
+	0x8D90, 0xE065, 0x8D91, 0xE05E, 0x8D92, 0xE066, 0x8D93, 0xE063,
+	0x8D94, 0xE064, 0x8D95, 0xBBB0, 0x8D96, 0xE456, 0x8D99, 0xBBAF,
+	0x8D9B, 0xE7F2, 0x8D9C, 0xE7F0, 0x8D9F, 0xBDEB, 0x8DA0, 0xE7EF,
+	0x8DA1, 0xE7F1, 0x8DA3, 0xBDEC, 0x8DA5, 0xEBBB, 0x8DA7, 0xEBBC,
+	0x8DA8, 0xC1CD, 0x8DAA, 0xF34C, 0x8DAB, 0xF34E, 0x8DAC, 0xF34B,
+	0x8DAD, 0xF34D, 0x8DAE, 0xF4D6, 0x8DAF, 0xF654, 0x8DB2, 0xF96F,
+	0x8DB3, 0xA8AC, 0x8DB4, 0xAD77, 0x8DB5, 0xD3E5, 0x8DB6, 0xD3E7,
+	0x8DB7, 0xD3E6, 0x8DB9, 0xD7D8, 0x8DBA, 0xB36C, 0x8DBC, 0xD7D6,
+	0x8DBE, 0xB36B, 0x8DBF, 0xD7D9, 0x8DC1, 0xD7DA, 0x8DC2, 0xD7D7,
+	0x8DC5, 0xDBFB, 0x8DC6, 0xB660, 0x8DC7, 0xDBF3, 0x8DC8, 0xDBF9,
+	0x8DCB, 0xB65B, 0x8DCC, 0xB65E, 0x8DCD, 0xDBF2, 0x8DCE, 0xB659,
+	0x8DCF, 0xDBF6, 0x8DD0, 0xE06C, 0x8DD1, 0xB65D, 0x8DD3, 0xDBF1,
+	0x8DD5, 0xDBF7, 0x8DD6, 0xDBF4, 0x8DD7, 0xDBFA, 0x8DD8, 0xDBF0,
+	0x8DD9, 0xDBF8, 0x8DDA, 0xB65C, 0x8DDB, 0xB65F, 0x8DDC, 0xDBF5,
+	0x8DDD, 0xB65A, 0x8DDF, 0xB8F2, 0x8DE0, 0xE068, 0x8DE1, 0xB8F1,
+	0x8DE2, 0xE06F, 0x8DE3, 0xE06E, 0x8DE4, 0xB8F8, 0x8DE6, 0xB8F9,
+	0x8DE7, 0xE070, 0x8DE8, 0xB8F3, 0x8DE9, 0xE06D, 0x8DEA, 0xB8F7,
+	0x8DEB, 0xE072, 0x8DEC, 0xE069, 0x8DEE, 0xE06B, 0x8DEF, 0xB8F4,
+	0x8DF0, 0xE067, 0x8DF1, 0xE06A, 0x8DF2, 0xE071, 0x8DF3, 0xB8F5,
+	0x8DF4, 0xE073, 0x8DFA, 0xB8F6, 0x8DFC, 0xBBB1, 0x8DFD, 0xE45B,
+	0x8DFE, 0xE461, 0x8DFF, 0xE459, 0x8E00, 0xE462, 0x8E02, 0xE458,
+	0x8E03, 0xE45D, 0x8E04, 0xE463, 0x8E05, 0xE460, 0x8E06, 0xE45F,
+	0x8E07, 0xE45E, 0x8E09, 0xE457, 0x8E0A, 0xE45C, 0x8E0D, 0xE45A,
+	0x8E0F, 0xBDF1, 0x8E10, 0xBDEE, 0x8E11, 0xE7FB, 0x8E12, 0xE841,
+	0x8E13, 0xE843, 0x8E14, 0xE840, 0x8E15, 0xE7F8, 0x8E16, 0xE7FA,
+	0x8E17, 0xE845, 0x8E18, 0xE842, 0x8E19, 0xE7FC, 0x8E1A, 0xE846,
+	0x8E1B, 0xE7F9, 0x8E1C, 0xE844, 0x8E1D, 0xBDEF, 0x8E1E, 0xBDF5,
+	0x8E1F, 0xBDF3, 0x8E20, 0xE7F3, 0x8E21, 0xBDF4, 0x8E22, 0xBDF0,
+	0x8E23, 0xE7F4, 0x8E24, 0xE7F6, 0x8E25, 0xE7F5, 0x8E26, 0xE7FD,
+	0x8E27, 0xE7FE, 0x8E29, 0xBDF2, 0x8E2B, 0xBDED, 0x8E2E, 0xE7F7,
+	0x8E30, 0xEBC6, 0x8E31, 0xBFE2, 0x8E33, 0xEBBD, 0x8E34, 0xBFE3,
+	0x8E35, 0xBFE6, 0x8E36, 0xEBC2, 0x8E38, 0xEBBF, 0x8E39, 0xBFE5,
+	0x8E3C, 0xEBC3, 0x8E3D, 0xEBC4, 0x8E3E, 0xEBBE, 0x8E3F, 0xEBC7,
+	0x8E40, 0xEBC0, 0x8E41, 0xEBC5, 0x8E42, 0xBFE4, 0x8E44, 0xBFE1,
+	0x8E45, 0xEBC1, 0x8E47, 0xEEBF, 0x8E48, 0xC1D0, 0x8E49, 0xC1CE,
+	0x8E4A, 0xC1D1, 0x8E4B, 0xC1CF, 0x8E4C, 0xEEBE, 0x8E4D, 0xEEBB,
+	0x8E4E, 0xEEBA, 0x8E50, 0xEEBD, 0x8E53, 0xEEBC, 0x8E54, 0xF145,
+	0x8E55, 0xC2DE, 0x8E56, 0xF0FB, 0x8E57, 0xF0FA, 0x8E59, 0xC2D9,
+	0x8E5A, 0xF141, 0x8E5B, 0xF140, 0x8E5C, 0xF0F7, 0x8E5D, 0xF143,
+	0x8E5E, 0xF0FC, 0x8E5F, 0xC2DD, 0x8E60, 0xF0F9, 0x8E61, 0xF142,
+	0x8E62, 0xF0F8, 0x8E63, 0xC2DA, 0x8E64, 0xC2DC, 0x8E65, 0xF0FD,
+	0x8E66, 0xC2DB, 0x8E67, 0xF0FE, 0x8E69, 0xF144, 0x8E6A, 0xF352,
+	0x8E6C, 0xC3DE, 0x8E6D, 0xF34F, 0x8E6F, 0xF353, 0x8E72, 0xC3DB,
+	0x8E73, 0xF351, 0x8E74, 0xC3E0, 0x8E76, 0xC3DD, 0x8E78, 0xF350,
+	0x8E7A, 0xC3DF, 0x8E7B, 0xF354, 0x8E7C, 0xC3DA, 0x8E81, 0xC4BC,
+	0x8E82, 0xC4BE, 0x8E84, 0xF4D9, 0x8E85, 0xC4BD, 0x8E86, 0xF4D7,
+	0x8E87, 0xC3DC, 0x8E88, 0xF4D8, 0x8E89, 0xC4BB, 0x8E8A, 0xC543,
+	0x8E8B, 0xC545, 0x8E8C, 0xF656, 0x8E8D, 0xC544, 0x8E8E, 0xF655,
+	0x8E90, 0xF761, 0x8E91, 0xC5AD, 0x8E92, 0xF760, 0x8E93, 0xC5AE,
+	0x8E94, 0xF75E, 0x8E95, 0xF75D, 0x8E96, 0xF762, 0x8E97, 0xF763,
+	0x8E98, 0xF846, 0x8E9A, 0xF75F, 0x8E9D, 0xF8C6, 0x8E9E, 0xF8C3,
+	0x8E9F, 0xF8C4, 0x8EA0, 0xF8C5, 0x8EA1, 0xC65C, 0x8EA3, 0xF951,
+	0x8EA4, 0xF950, 0x8EA5, 0xF94F, 0x8EA6, 0xF970, 0x8EA8, 0xF9BE,
+	0x8EA9, 0xF9AB, 0x8EAA, 0xC66E, 0x8EAB, 0xA8AD, 0x8EAC, 0xB060,
+	0x8EB2, 0xB8FA, 0x8EBA, 0xBDF6, 0x8EBD, 0xEBC8, 0x8EC0, 0xC2DF,
+	0x8EC2, 0xF355, 0x8EC9, 0xF9AC, 0x8ECA, 0xA8AE, 0x8ECB, 0xAAEE,
+	0x8ECC, 0xAD79, 0x8ECD, 0xAD78, 0x8ECF, 0xB063, 0x8ED1, 0xD3E8,
+	0x8ED2, 0xB061, 0x8ED3, 0xD3E9, 0x8ED4, 0xB062, 0x8ED7, 0xD7DF,
+	0x8ED8, 0xD7DB, 0x8EDB, 0xB36D, 0x8EDC, 0xD7DE, 0x8EDD, 0xD7DD,
+	0x8EDE, 0xD7DC, 0x8EDF, 0xB36E, 0x8EE0, 0xD7E0, 0x8EE1, 0xD7E1,
+	0x8EE5, 0xDC43, 0x8EE6, 0xDC41, 0x8EE7, 0xDC45, 0x8EE8, 0xDC46,
+	0x8EE9, 0xDC4C, 0x8EEB, 0xDC48, 0x8EEC, 0xDC4A, 0x8EEE, 0xDC42,
+	0x8EEF, 0xDBFC, 0x8EF1, 0xDC49, 0x8EF4, 0xDC4B, 0x8EF5, 0xDC44,
+	0x8EF6, 0xDC47, 0x8EF7, 0xDBFD, 0x8EF8, 0xB662, 0x8EF9, 0xDC40,
+	0x8EFA, 0xDBFE, 0x8EFB, 0xB661, 0x8EFC, 0xB663, 0x8EFE, 0xB8FD,
+	0x8EFF, 0xE075, 0x8F00, 0xE077, 0x8F01, 0xE076, 0x8F02, 0xE07B,
+	0x8F03, 0xB8FB, 0x8F05, 0xE078, 0x8F06, 0xE074, 0x8F07, 0xE079,
+	0x8F08, 0xE07A, 0x8F09, 0xB8FC, 0x8F0A, 0xB8FE, 0x8F0B, 0xE07C,
+	0x8F0D, 0xE467, 0x8F0E, 0xE466, 0x8F10, 0xE464, 0x8F11, 0xE465,
+	0x8F12, 0xBBB3, 0x8F13, 0xBBB5, 0x8F14, 0xBBB2, 0x8F15, 0xBBB4,
+	0x8F16, 0xE84D, 0x8F17, 0xE84E, 0x8F18, 0xE849, 0x8F1A, 0xE84A,
+	0x8F1B, 0xBDF8, 0x8F1C, 0xBDFD, 0x8F1D, 0xBDF7, 0x8F1E, 0xBDFE,
+	0x8F1F, 0xBDF9, 0x8F20, 0xE84B, 0x8F23, 0xE84C, 0x8F24, 0xE848,
+	0x8F25, 0xBE40, 0x8F26, 0xBDFB, 0x8F29, 0xBDFA, 0x8F2A, 0xBDFC,
+	0x8F2C, 0xE847, 0x8F2E, 0xEBCA, 0x8F2F, 0xBFE8, 0x8F32, 0xEBCC,
+	0x8F33, 0xBFEA, 0x8F34, 0xEBCF, 0x8F35, 0xEBCB, 0x8F36, 0xEBC9,
+	0x8F37, 0xEBCE, 0x8F38, 0xBFE9, 0x8F39, 0xEBCD, 0x8F3B, 0xBFE7,
+	0x8F3E, 0xC1D3, 0x8F3F, 0xC1D6, 0x8F40, 0xEEC1, 0x8F42, 0xC1D4,
+	0x8F43, 0xEEC0, 0x8F44, 0xC1D2, 0x8F45, 0xC1D5, 0x8F46, 0xF146,
+	0x8F47, 0xF147, 0x8F48, 0xF148, 0x8F49, 0xC2E0, 0x8F4B, 0xF149,
+	0x8F4D, 0xC2E1, 0x8F4E, 0xC3E2, 0x8F4F, 0xF358, 0x8F50, 0xF359,
+	0x8F51, 0xF357, 0x8F52, 0xF356, 0x8F53, 0xF35A, 0x8F54, 0xC3E1,
+	0x8F55, 0xF4DD, 0x8F56, 0xF4DB, 0x8F57, 0xF4DC, 0x8F58, 0xF4DE,
+	0x8F59, 0xF4DA, 0x8F5A, 0xF4DF, 0x8F5B, 0xF658, 0x8F5D, 0xF659,
+	0x8F5E, 0xF657, 0x8F5F, 0xC546, 0x8F60, 0xF764, 0x8F61, 0xC5AF,
+	0x8F62, 0xF765, 0x8F63, 0xF848, 0x8F64, 0xF847, 0x8F9B, 0xA8AF,
+	0x8F9C, 0xB664, 0x8F9F, 0xB940, 0x8FA3, 0xBBB6, 0x8FA6, 0xBFEC,
+	0x8FA8, 0xBFEB, 0x8FAD, 0xC3E3, 0x8FAE, 0xC47C, 0x8FAF, 0xC547,
+	0x8FB0, 0xA8B0, 0x8FB1, 0xB064, 0x8FB2, 0xB941, 0x8FB4, 0xF35B,
+	0x8FBF, 0xCBA6, 0x8FC2, 0xA8B1, 0x8FC4, 0xA8B4, 0x8FC5, 0xA8B3,
+	0x8FC6, 0xA8B2, 0x8FC9, 0xCBA5, 0x8FCB, 0xCDCD, 0x8FCD, 0xCDCF,
+	0x8FCE, 0xAAEF, 0x8FD1, 0xAAF1, 0x8FD2, 0xCDCC, 0x8FD3, 0xCDCE,
+	0x8FD4, 0xAAF0, 0x8FD5, 0xCDD1, 0x8FD6, 0xCDD0, 0x8FD7, 0xCDD2,
+	0x8FE0, 0xD0B6, 0x8FE1, 0xD0B4, 0x8FE2, 0xAD7C, 0x8FE3, 0xD0B3,
+	0x8FE4, 0xADA3, 0x8FE5, 0xAD7E, 0x8FE6, 0xAD7B, 0x8FE8, 0xADA4,
+	0x8FEA, 0xAD7D, 0x8FEB, 0xADA2, 0x8FED, 0xADA1, 0x8FEE, 0xD0B5,
+	0x8FF0, 0xAD7A, 0x8FF4, 0xB06A, 0x8FF5, 0xD3EB, 0x8FF6, 0xD3F1,
+	0x8FF7, 0xB067, 0x8FF8, 0xB06E, 0x8FFA, 0xB069, 0x8FFB, 0xD3EE,
+	0x8FFC, 0xD3F0, 0x8FFD, 0xB06C, 0x8FFE, 0xD3EA, 0x8FFF, 0xD3ED,
+	0x9000, 0xB068, 0x9001, 0xB065, 0x9002, 0xD3EC, 0x9003, 0xB06B,
+	0x9004, 0xD3EF, 0x9005, 0xB06D, 0x9006, 0xB066, 0x900B, 0xD7E3,
+	0x900C, 0xD7E6, 0x900D, 0xB370, 0x900F, 0xB37A, 0x9010, 0xB376,
+	0x9011, 0xD7E4, 0x9014, 0xB37E, 0x9015, 0xB377, 0x9016, 0xB37C,
+	0x9017, 0xB372, 0x9019, 0xB36F, 0x901A, 0xB371, 0x901B, 0xB37D,
+	0x901C, 0xD7E5, 0x901D, 0xB375, 0x901E, 0xB378, 0x901F, 0xB374,
+	0x9020, 0xB379, 0x9021, 0xD7E7, 0x9022, 0xB37B, 0x9023, 0xB373,
+	0x9024, 0xD7E2, 0x902D, 0xDC4D, 0x902E, 0xB665, 0x902F, 0xDC4F,
+	0x9031, 0xB667, 0x9032, 0xB669, 0x9034, 0xDC4E, 0x9035, 0xB666,
+	0x9036, 0xB66A, 0x9038, 0xB668, 0x903C, 0xB947, 0x903D, 0xE0A3,
+	0x903E, 0xB94F, 0x903F, 0xE07E, 0x9041, 0xB950, 0x9042, 0xB945,
+	0x9044, 0xE0A1, 0x9047, 0xB94A, 0x9049, 0xE0A2, 0x904A, 0xB943,
+	0x904B, 0xB942, 0x904D, 0xB94D, 0x904E, 0xB94C, 0x904F, 0xB94B,
+	0x9050, 0xB949, 0x9051, 0xB94E, 0x9052, 0xE07D, 0x9053, 0xB944,
+	0x9054, 0xB946, 0x9055, 0xB948, 0x9058, 0xBBB8, 0x9059, 0xBBBB,
+	0x905B, 0xBBBF, 0x905C, 0xBBB9, 0x905D, 0xBBBE, 0x905E, 0xBBBC,
+	0x9060, 0xBBB7, 0x9062, 0xBBBD, 0x9063, 0xBBBA, 0x9067, 0xE852,
+	0x9068, 0xBE43, 0x9069, 0xBE41, 0x906B, 0xE853, 0x906D, 0xBE44,
+	0x906E, 0xBE42, 0x906F, 0xE851, 0x9070, 0xE850, 0x9072, 0xBFF0,
+	0x9073, 0xE84F, 0x9074, 0xBFEE, 0x9075, 0xBFED, 0x9076, 0xEBD0,
+	0x9077, 0xBE45, 0x9078, 0xBFEF, 0x9079, 0xEBD1, 0x907A, 0xBFF2,
+	0x907B, 0xEBD2, 0x907C, 0xBFF1, 0x907D, 0xC1D8, 0x907E, 0xEEC3,
+	0x907F, 0xC1D7, 0x9080, 0xC1DC, 0x9081, 0xC1DA, 0x9082, 0xC1DB,
+	0x9083, 0xC2E3, 0x9084, 0xC1D9, 0x9085, 0xEEC2, 0x9086, 0xEBD3,
+	0x9087, 0xC2E2, 0x9088, 0xC2E4, 0x908A, 0xC3E4, 0x908B, 0xC3E5,
+	0x908D, 0xF4E0, 0x908F, 0xC5DE, 0x9090, 0xC5DD, 0x9091, 0xA8B6,
+	0x9094, 0xCA55, 0x9095, 0xB06F, 0x9097, 0xCA52, 0x9098, 0xCA53,
+	0x9099, 0xCA51, 0x909B, 0xCA54, 0x909E, 0xCBAA, 0x909F, 0xCBA7,
+	0x90A0, 0xCBAC, 0x90A1, 0xCBA8, 0x90A2, 0xA8B7, 0x90A3, 0xA8BA,
+	0x90A5, 0xCBA9, 0x90A6, 0xA8B9, 0x90A7, 0xCBAB, 0x90AA, 0xA8B8,
+	0x90AF, 0xCDD5, 0x90B0, 0xCDD7, 0x90B1, 0xAAF4, 0x90B2, 0xCDD3,
+	0x90B3, 0xCDD6, 0x90B4, 0xCDD4, 0x90B5, 0xAAF2, 0x90B6, 0xAAF5,
+	0x90B8, 0xAAF3, 0x90BD, 0xD0B8, 0x90BE, 0xD0BC, 0x90BF, 0xD0B9,
+	0x90C1, 0xADA7, 0x90C3, 0xADA8, 0x90C5, 0xD0BB, 0x90C7, 0xD0BD,
+	0x90C8, 0xD0BF, 0x90CA, 0xADA5, 0x90CB, 0xD0BE, 0x90CE, 0xADA6,
+	0x90D4, 0xD7EE, 0x90D5, 0xD0BA, 0x90D6, 0xD3F2, 0x90D7, 0xD3FB,
+	0x90D8, 0xD3F9, 0x90D9, 0xD3F4, 0x90DA, 0xD3F5, 0x90DB, 0xD3FA,
+	0x90DC, 0xD3FC, 0x90DD, 0xB071, 0x90DF, 0xD3F7, 0x90E0, 0xD3F3,
+	0x90E1, 0xB070, 0x90E2, 0xB072, 0x90E3, 0xD3F6, 0x90E4, 0xD3FD,
+	0x90E5, 0xD3F8, 0x90E8, 0xB3A1, 0x90E9, 0xD7F1, 0x90EA, 0xD7E9,
+	0x90EB, 0xD7EF, 0x90EC, 0xD7F0, 0x90ED, 0xB3A2, 0x90EF, 0xD7E8,
+	0x90F0, 0xD7EA, 0x90F1, 0xD0B7, 0x90F2, 0xD7EC, 0x90F3, 0xD7ED,
+	0x90F4, 0xD7EB, 0x90F5, 0xB66C, 0x90F9, 0xDC56, 0x90FA, 0xEBD4,
+	0x90FB, 0xDC57, 0x90FC, 0xDC54, 0x90FD, 0xB3A3, 0x90FE, 0xB66E,
+	0x90FF, 0xDC53, 0x9100, 0xDC59, 0x9101, 0xDC58, 0x9102, 0xB66B,
+	0x9103, 0xDC5C, 0x9104, 0xDC52, 0x9105, 0xDC5B, 0x9106, 0xDC50,
+	0x9107, 0xDC5A, 0x9108, 0xDC55, 0x9109, 0xB66D, 0x910B, 0xE0AA,
+	0x910D, 0xE0A5, 0x910E, 0xE0AB, 0x910F, 0xE0A6, 0x9110, 0xE0A4,
+	0x9111, 0xE0A7, 0x9112, 0xB951, 0x9114, 0xE0A9, 0x9116, 0xE0A8,
+	0x9117, 0xB952, 0x9118, 0xBBC1, 0x9119, 0xBBC0, 0x911A, 0xE46E,
+	0x911B, 0xE471, 0x911C, 0xE469, 0x911D, 0xE46D, 0x911E, 0xBBC2,
+	0x911F, 0xE46C, 0x9120, 0xE46A, 0x9121, 0xE470, 0x9122, 0xE46B,
+	0x9123, 0xE468, 0x9124, 0xE46F, 0x9126, 0xE859, 0x9127, 0xBE48,
+	0x9128, 0xF14A, 0x9129, 0xE856, 0x912A, 0xE857, 0x912B, 0xE855,
+	0x912C, 0xDC51, 0x912D, 0xBE47, 0x912E, 0xE85A, 0x912F, 0xE854,
+	0x9130, 0xBE46, 0x9131, 0xBE49, 0x9132, 0xE858, 0x9133, 0xEBD5,
+	0x9134, 0xBFF3, 0x9135, 0xEBD6, 0x9136, 0xEBD7, 0x9138, 0xEEC4,
+	0x9139, 0xC1DD, 0x913A, 0xF14B, 0x913B, 0xF14C, 0x913E, 0xF14D,
+	0x913F, 0xF35D, 0x9140, 0xF35C, 0x9141, 0xF4E2, 0x9143, 0xF4E1,
+	0x9144, 0xF65B, 0x9145, 0xF65C, 0x9146, 0xF65A, 0x9147, 0xF766,
+	0x9148, 0xC5B0, 0x9149, 0xA8BB, 0x914A, 0xADAA, 0x914B, 0xADA9,
+	0x914C, 0xB075, 0x914D, 0xB074, 0x914E, 0xD440, 0x914F, 0xD441,
+	0x9150, 0xD3FE, 0x9152, 0xB073, 0x9153, 0xD7F5, 0x9155, 0xD7F6,
+	0x9156, 0xD7F2, 0x9157, 0xB3A4, 0x9158, 0xD7F3, 0x915A, 0xD7F4,
+	0x915F, 0xDC5F, 0x9160, 0xDC61, 0x9161, 0xDC5D, 0x9162, 0xDC60,
+	0x9163, 0xB66F, 0x9164, 0xDC5E, 0x9165, 0xB670, 0x9168, 0xDD73,
+	0x9169, 0xB955, 0x916A, 0xB954, 0x916C, 0xB953, 0x916E, 0xE0AC,
+	0x916F, 0xE0AD, 0x9172, 0xE473, 0x9173, 0xE475, 0x9174, 0xBBC6,
+	0x9175, 0xBBC3, 0x9177, 0xBBC5, 0x9178, 0xBBC4, 0x9179, 0xE474,
+	0x917A, 0xE472, 0x9180, 0xE861, 0x9181, 0xE85E, 0x9182, 0xE85F,
+	0x9183, 0xBE4D, 0x9184, 0xE860, 0x9185, 0xE85B, 0x9186, 0xE85C,
+	0x9187, 0xBE4A, 0x9189, 0xBE4B, 0x918A, 0xE85D, 0x918B, 0xBE4C,
+	0x918D, 0xEBDB, 0x918F, 0xEBDC, 0x9190, 0xEBD9, 0x9191, 0xEBDA,
+	0x9192, 0xBFF4, 0x9193, 0xEBD8, 0x9199, 0xEEC8, 0x919A, 0xEEC5,
+	0x919B, 0xEEC7, 0x919C, 0xC1E0, 0x919D, 0xEECB, 0x919E, 0xC1DF,
+	0x919F, 0xEEC9, 0x91A0, 0xEECC, 0x91A1, 0xEECA, 0x91A2, 0xEEC6,
+	0x91A3, 0xC1DE, 0x91A5, 0xF14F, 0x91A7, 0xF150, 0x91A8, 0xF14E,
+	0x91AA, 0xF152, 0x91AB, 0xC2E5, 0x91AC, 0xC2E6, 0x91AD, 0xF35F,
+	0x91AE, 0xC3E7, 0x91AF, 0xF151, 0x91B0, 0xF35E, 0x91B1, 0xC3E6,
+	0x91B2, 0xF4E5, 0x91B3, 0xF4E6, 0x91B4, 0xC4BF, 0x91B5, 0xF4E4,
+	0x91B7, 0xF4E3, 0x91B9, 0xF65D, 0x91BA, 0xC548, 0x91BC, 0xF849,
+	0x91BD, 0xF8C8, 0x91BE, 0xF8C7, 0x91C0, 0xC643, 0x91C1, 0xC65D,
+	0x91C2, 0xF8C9, 0x91C3, 0xF971, 0x91C5, 0xC66F, 0x91C6, 0xA8BC,
+	0x91C7, 0xAAF6, 0x91C9, 0xB956, 0x91CB, 0xC4C0, 0x91CC, 0xA8BD,
+	0x91CD, 0xADAB, 0x91CE, 0xB3A5, 0x91CF, 0xB671, 0x91D0, 0xC2E7,
+	0x91D1, 0xAAF7, 0x91D3, 0xD0C1, 0x91D4, 0xD0C0, 0x91D5, 0xD442,
+	0x91D7, 0xB078, 0x91D8, 0xB076, 0x91D9, 0xB07A, 0x91DA, 0xD444,
+	0x91DC, 0xB079, 0x91DD, 0xB077, 0x91E2, 0xD443, 0x91E3, 0xB3A8,
+	0x91E4, 0xD7FC, 0x91E6, 0xB3A7, 0x91E7, 0xB3A9, 0x91E8, 0xD842,
+	0x91E9, 0xB3AB, 0x91EA, 0xD7FE, 0x91EB, 0xD840, 0x91EC, 0xD7F7,
+	0x91ED, 0xB3AA, 0x91EE, 0xD843, 0x91F1, 0xD7F9, 0x91F3, 0xD7FA,
+	0x91F4, 0xD7F8, 0x91F5, 0xB3A6, 0x91F7, 0xD841, 0x91F8, 0xD7FB,
+	0x91F9, 0xD7FD, 0x91FD, 0xDC6D, 0x91FF, 0xDC6C, 0x9200, 0xDC6A,
+	0x9201, 0xDC62, 0x9202, 0xDC71, 0x9203, 0xDC65, 0x9204, 0xDC6F,
+	0x9205, 0xDC76, 0x9206, 0xDC6E, 0x9207, 0xB679, 0x9209, 0xB675,
+	0x920A, 0xDC63, 0x920C, 0xDC69, 0x920D, 0xB677, 0x920F, 0xDC68,
+	0x9210, 0xB678, 0x9211, 0xB67A, 0x9212, 0xDC6B, 0x9214, 0xB672,
+	0x9215, 0xB673, 0x9216, 0xDC77, 0x9217, 0xDC75, 0x9219, 0xDC74,
+	0x921A, 0xDC66, 0x921C, 0xDC72, 0x921E, 0xB676, 0x9223, 0xB674,
+	0x9224, 0xDC73, 0x9225, 0xDC64, 0x9226, 0xDC67, 0x9227, 0xDC70,
+	0x922D, 0xE4BA, 0x922E, 0xE0B7, 0x9230, 0xE0B0, 0x9231, 0xE0C3,
+	0x9232, 0xE0CC, 0x9233, 0xE0B3, 0x9234, 0xB961, 0x9236, 0xE0C0,
+	0x9237, 0xB957, 0x9238, 0xB959, 0x9239, 0xB965, 0x923A, 0xE0B1,
+	0x923D, 0xB95A, 0x923E, 0xB95C, 0x923F, 0xB966, 0x9240, 0xB95B,
+	0x9245, 0xB964, 0x9246, 0xE0B9, 0x9248, 0xE0AE, 0x9249, 0xB962,
+	0x924A, 0xE0B8, 0x924B, 0xB95E, 0x924C, 0xE0CA, 0x924D, 0xB963,
+	0x924E, 0xE0C8, 0x924F, 0xE0BC, 0x9250, 0xE0C6, 0x9251, 0xB960,
+	0x9252, 0xE0AF, 0x9253, 0xE0C9, 0x9254, 0xE0C4, 0x9256, 0xE0CB,
+	0x9257, 0xB958, 0x925A, 0xB967, 0x925B, 0xB95D, 0x925E, 0xE0B5,
+	0x9260, 0xE0BD, 0x9261, 0xE0C1, 0x9263, 0xE0C5, 0x9264, 0xB95F,
+	0x9265, 0xE0B4, 0x9266, 0xE0B2, 0x9267, 0xE0BE, 0x926C, 0xE0BB,
+	0x926D, 0xE0BA, 0x926F, 0xE0BF, 0x9270, 0xE0C2, 0x9272, 0xE0C7,
+	0x9276, 0xE478, 0x9278, 0xBBC7, 0x9279, 0xE4A4, 0x927A, 0xE47A,
+	0x927B, 0xBBCC, 0x927C, 0xBBD0, 0x927D, 0xE4AD, 0x927E, 0xE4B5,
+	0x927F, 0xE4A6, 0x9280, 0xBBC8, 0x9282, 0xE4AA, 0x9283, 0xE0B6,
+	0x9285, 0xBBC9, 0x9286, 0xE4B1, 0x9287, 0xE4B6, 0x9288, 0xE4AE,
+	0x928A, 0xE4B0, 0x928B, 0xE4B9, 0x928C, 0xE4B2, 0x928D, 0xE47E,
+	0x928E, 0xE4A9, 0x9291, 0xBBD1, 0x9293, 0xBBCD, 0x9294, 0xE47C,
+	0x9295, 0xE4AB, 0x9296, 0xBBCB, 0x9297, 0xE4A5, 0x9298, 0xBBCA,
+	0x9299, 0xE4B3, 0x929A, 0xE4A2, 0x929B, 0xE479, 0x929C, 0xBBCE,
+	0x929D, 0xE4B8, 0x92A0, 0xE47B, 0x92A1, 0xE4AF, 0x92A2, 0xE4AC,
+	0x92A3, 0xE4A7, 0x92A4, 0xE477, 0x92A5, 0xE476, 0x92A6, 0xE4A1,
+	0x92A7, 0xE4B4, 0x92A8, 0xBBCF, 0x92A9, 0xE4B7, 0x92AA, 0xE47D,
+	0x92AB, 0xE4A3, 0x92AC, 0xBE52, 0x92B2, 0xBE5A, 0x92B3, 0xBE55,
+	0x92B4, 0xE8A4, 0x92B5, 0xE8A1, 0x92B6, 0xE867, 0x92B7, 0xBE50,
+	0x92B9, 0xF9D7, 0x92BB, 0xBE4F, 0x92BC, 0xBE56, 0x92C0, 0xE865,
+	0x92C1, 0xBE54, 0x92C2, 0xE871, 0x92C3, 0xE863, 0x92C4, 0xE864,
+	0x92C5, 0xBE4E, 0x92C6, 0xE8A3, 0x92C7, 0xBE58, 0x92C8, 0xE874,
+	0x92C9, 0xE879, 0x92CA, 0xE873, 0x92CB, 0xEBEE, 0x92CC, 0xE86F,
+	0x92CD, 0xE877, 0x92CE, 0xE875, 0x92CF, 0xE868, 0x92D0, 0xE862,
+	0x92D1, 0xE87D, 0x92D2, 0xBE57, 0x92D3, 0xE87E, 0x92D5, 0xE878,
+	0x92D7, 0xE86D, 0x92D8, 0xE86B, 0x92D9, 0xE866, 0x92DD, 0xE86E,
+	0x92DE, 0xE87B, 0x92DF, 0xE86A, 0x92E0, 0xE87A, 0x92E1, 0xE8A2,
+	0x92E4, 0xBE53, 0x92E6, 0xE876, 0x92E7, 0xE87C, 0x92E8, 0xE872,
+	0x92E9, 0xE86C, 0x92EA, 0xBE51, 0x92EE, 0xE4A8, 0x92EF, 0xE870,
+	0x92F0, 0xBE59, 0x92F1, 0xE869, 0x92F7, 0xEBF4, 0x92F8, 0xBFF7,
+	0x92F9, 0xEBF3, 0x92FA, 0xEBF0, 0x92FB, 0xEC44, 0x92FC, 0xBFFB,
+	0x92FE, 0xEC41, 0x92FF, 0xEBF8, 0x9300, 0xEC43, 0x9301, 0xEBE9,
+	0x9302, 0xEBF6, 0x9304, 0xBFFD, 0x9306, 0xEBE1, 0x9308, 0xEBDF,
+	0x9309, 0xEC42, 0x930B, 0xEC40, 0x930C, 0xEBFE, 0x930D, 0xEBED,
+	0x930E, 0xEBEC, 0x930F, 0xEBE2, 0x9310, 0xC040, 0x9312, 0xEBE8,
+	0x9313, 0xEBF2, 0x9314, 0xEBFD, 0x9315, 0xC043, 0x9316, 0xEC45,
+	0x9318, 0xC1E8, 0x9319, 0xC045, 0x931A, 0xBFFE, 0x931B, 0xEBE6,
+	0x931D, 0xEBEF, 0x931E, 0xEBDE, 0x931F, 0xEBE0, 0x9320, 0xBFF5,
+	0x9321, 0xC042, 0x9322, 0xBFFA, 0x9323, 0xEBE7, 0x9324, 0xEBF7,
+	0x9325, 0xEBF1, 0x9326, 0xC041, 0x9327, 0xEBDD, 0x9328, 0xC1E3,
+	0x9329, 0xEBF9, 0x932A, 0xEBFC, 0x932B, 0xBFFC, 0x932D, 0xEBEB,
+	0x932E, 0xC044, 0x932F, 0xBFF9, 0x9333, 0xBFF8, 0x9334, 0xEBF5,
+	0x9335, 0xEBFB, 0x9336, 0xBFF6, 0x9338, 0xEBE4, 0x9339, 0xEBFA,
+	0x933C, 0xEBE5, 0x9346, 0xEBEA, 0x9347, 0xEED2, 0x9349, 0xEED7,
+	0x934A, 0xC1E5, 0x934B, 0xC1E7, 0x934C, 0xEEDD, 0x934D, 0xC1E1,
+	0x934E, 0xEEEC, 0x934F, 0xEEE3, 0x9350, 0xEED8, 0x9351, 0xEED9,
+	0x9352, 0xEEE2, 0x9354, 0xC1EE, 0x9355, 0xEEE1, 0x9356, 0xEED1,
+	0x9357, 0xEEE0, 0x9358, 0xEED4, 0x9359, 0xEEED, 0x935A, 0xC1ED,
+	0x935B, 0xC1EB, 0x935C, 0xEED5, 0x935E, 0xEEE8, 0x9360, 0xEEDA,
+	0x9361, 0xEEE7, 0x9363, 0xEEE9, 0x9364, 0xEED0, 0x9365, 0xC1E6,
+	0x9367, 0xEEEA, 0x936A, 0xEEDE, 0x936C, 0xC1EA, 0x936D, 0xEEDB,
+	0x9370, 0xC1EC, 0x9371, 0xEEE4, 0x9375, 0xC1E4, 0x9376, 0xEED6,
+	0x9377, 0xEEE5, 0x9379, 0xEEDF, 0x937A, 0xEBE3, 0x937B, 0xEEE6,
+	0x937C, 0xEED3, 0x937E, 0xC1E9, 0x9380, 0xEEEB, 0x9382, 0xC1E2,
+	0x9383, 0xEECE, 0x9388, 0xF160, 0x9389, 0xF159, 0x938A, 0xC2E9,
+	0x938C, 0xF154, 0x938D, 0xF163, 0x938E, 0xF15B, 0x938F, 0xEEDC,
+	0x9391, 0xF165, 0x9392, 0xF155, 0x9394, 0xC2E8, 0x9395, 0xF15F,
+	0x9396, 0xC2EA, 0x9397, 0xC2F2, 0x9398, 0xC2F0, 0x9399, 0xF161,
+	0x939A, 0xC2F1, 0x939B, 0xF157, 0x939D, 0xF158, 0x939E, 0xF15D,
+	0x939F, 0xF162, 0x93A1, 0xEECD, 0x93A2, 0xC2EB, 0x93A3, 0xF16A,
+	0x93A4, 0xF167, 0x93A5, 0xF16B, 0x93A6, 0xF15E, 0x93A7, 0xF15A,
+	0x93A8, 0xF168, 0x93A9, 0xF36A, 0x93AA, 0xF15C, 0x93AC, 0xC2EE,
+	0x93AE, 0xC2ED, 0x93AF, 0xEECF, 0x93B0, 0xC2EF, 0x93B1, 0xF164,
+	0x93B2, 0xF166, 0x93B3, 0xC2EC, 0x93B4, 0xF169, 0x93B5, 0xF153,
+	0x93B7, 0xF156, 0x93C0, 0xF373, 0x93C2, 0xF363, 0x93C3, 0xC3EB,
+	0x93C4, 0xF371, 0x93C7, 0xF361, 0x93C8, 0xC3EC, 0x93CA, 0xF36C,
+	0x93CC, 0xF368, 0x93CD, 0xC3F1, 0x93CE, 0xF372, 0x93CF, 0xF362,
+	0x93D0, 0xF365, 0x93D1, 0xC3E9, 0x93D2, 0xF374, 0x93D4, 0xF36D,
+	0x93D5, 0xF370, 0x93D6, 0xC3EF, 0x93D7, 0xC3F4, 0x93D8, 0xC3F2,
+	0x93D9, 0xF369, 0x93DA, 0xF364, 0x93DC, 0xC3ED, 0x93DD, 0xC3EE,
+	0x93DE, 0xF360, 0x93DF, 0xC3EA, 0x93E1, 0xC3E8, 0x93E2, 0xC3F0,
+	0x93E3, 0xF36F, 0x93E4, 0xC3F3, 0x93E6, 0xF36B, 0x93E7, 0xF375,
+	0x93E8, 0xC3F5, 0x93EC, 0xF367, 0x93EE, 0xF36E, 0x93F5, 0xF4F3,
+	0x93F6, 0xF542, 0x93F7, 0xF4F5, 0x93F8, 0xF4FC, 0x93F9, 0xF366,
+	0x93FA, 0xF4FA, 0x93FB, 0xF4E9, 0x93FC, 0xF540, 0x93FD, 0xC4C3,
+	0x93FE, 0xF4ED, 0x93FF, 0xF4FE, 0x9400, 0xF4F4, 0x9403, 0xC4C2,
+	0x9406, 0xF544, 0x9407, 0xF4F6, 0x9409, 0xF4FB, 0x940A, 0xF4FD,
+	0x940B, 0xF4E7, 0x940C, 0xF541, 0x940D, 0xF4F2, 0x940E, 0xF4F7,
+	0x940F, 0xF4EB, 0x9410, 0xF4EF, 0x9411, 0xF543, 0x9412, 0xF4F9,
+	0x9413, 0xF4E8, 0x9414, 0xF4EC, 0x9415, 0xF4EE, 0x9416, 0xF4F8,
+	0x9418, 0xC4C1, 0x9419, 0xF4F1, 0x9420, 0xF4EA, 0x9428, 0xF4F0,
+	0x9429, 0xF661, 0x942A, 0xF666, 0x942B, 0xC54F, 0x942C, 0xF668,
+	0x942E, 0xC549, 0x9430, 0xF664, 0x9431, 0xF66A, 0x9432, 0xC54E,
+	0x9433, 0xC54A, 0x9435, 0xC54B, 0x9436, 0xF660, 0x9437, 0xF667,
+	0x9438, 0xC54D, 0x9439, 0xF665, 0x943A, 0xC54C, 0x943B, 0xF65F,
+	0x943C, 0xF663, 0x943D, 0xF662, 0x943F, 0xF65E, 0x9440, 0xF669,
+	0x9444, 0xC5B1, 0x9445, 0xF76D, 0x9446, 0xF770, 0x9447, 0xF76C,
+	0x9448, 0xF76E, 0x9449, 0xF76F, 0x944A, 0xF769, 0x944B, 0xF76A,
+	0x944C, 0xF767, 0x944F, 0xF76B, 0x9450, 0xF768, 0x9451, 0xC5B2,
+	0x9452, 0xC5B3, 0x9455, 0xF84B, 0x9457, 0xF84D, 0x945D, 0xF84C,
+	0x945E, 0xF84E, 0x9460, 0xC5E0, 0x9462, 0xF84A, 0x9463, 0xC5DF,
+	0x9464, 0xC5E1, 0x9468, 0xF8CB, 0x9469, 0xF8CC, 0x946A, 0xC644,
+	0x946B, 0xF8CA, 0x946D, 0xF953, 0x946E, 0xF952, 0x946F, 0xF954,
+	0x9470, 0xC65F, 0x9471, 0xF955, 0x9472, 0xC65E, 0x9473, 0xF956,
+	0x9474, 0xF972, 0x9475, 0xF975, 0x9476, 0xF974, 0x9477, 0xC668,
+	0x9478, 0xF973, 0x947C, 0xC672, 0x947D, 0xC670, 0x947E, 0xC671,
+	0x947F, 0xC677, 0x9480, 0xF9C0, 0x9481, 0xF9C1, 0x9482, 0xF9BF,
+	0x9483, 0xF9C9, 0x9577, 0xAAF8, 0x957A, 0xD844, 0x957B, 0xDC78,
+	0x957C, 0xE8A5, 0x957D, 0xF376, 0x9580, 0xAAF9, 0x9582, 0xADAC,
+	0x9583, 0xB07B, 0x9586, 0xD845, 0x9588, 0xD846, 0x9589, 0xB3AC,
+	0x958B, 0xB67D, 0x958C, 0xDC7A, 0x958D, 0xDC79, 0x958E, 0xB6A3,
+	0x958F, 0xB67C, 0x9590, 0xDC7B, 0x9591, 0xB67E, 0x9592, 0xB6A2,
+	0x9593, 0xB6A1, 0x9594, 0xB67B, 0x9598, 0xB968, 0x959B, 0xE0D0,
+	0x959C, 0xE0CE, 0x959E, 0xE0CF, 0x959F, 0xE0CD, 0x95A1, 0xBBD2,
+	0x95A3, 0xBBD5, 0x95A4, 0xBBD7, 0x95A5, 0xBBD6, 0x95A8, 0xBBD3,
+	0x95A9, 0xBBD4, 0x95AB, 0xE8A7, 0x95AC, 0xE8A6, 0x95AD, 0xBE5B,
+	0x95AE, 0xE8A8, 0x95B0, 0xE8A9, 0x95B1, 0xBE5C, 0x95B5, 0xEC4D,
+	0x95B6, 0xEC4B, 0x95B7, 0xEEF3, 0x95B9, 0xEC49, 0x95BA, 0xEC4A,
+	0x95BB, 0xC046, 0x95BC, 0xEC46, 0x95BD, 0xEC4E, 0x95BE, 0xEC48,
+	0x95BF, 0xEC4C, 0x95C0, 0xEEEF, 0x95C3, 0xEEF1, 0x95C5, 0xEEF2,
+	0x95C6, 0xC1F3, 0x95C7, 0xEEEE, 0x95C8, 0xC1F2, 0x95C9, 0xEEF0,
+	0x95CA, 0xC1EF, 0x95CB, 0xC1F0, 0x95CC, 0xC1F1, 0x95CD, 0xEC47,
+	0x95D0, 0xC2F5, 0x95D1, 0xF16E, 0x95D2, 0xF16C, 0x95D3, 0xF16D,
+	0x95D4, 0xC2F3, 0x95D5, 0xC2F6, 0x95D6, 0xC2F4, 0x95DA, 0xF377,
+	0x95DB, 0xF378, 0x95DC, 0xC3F6, 0x95DE, 0xF545, 0x95DF, 0xF547,
+	0x95E0, 0xF546, 0x95E1, 0xC4C4, 0x95E2, 0xC550, 0x95E3, 0xF66D,
+	0x95E4, 0xF66C, 0x95E5, 0xF66B, 0x961C, 0xAAFA, 0x961E, 0xC9AA,
+	0x9620, 0xCA58, 0x9621, 0xA6E9, 0x9622, 0xCA56, 0x9623, 0xCA59,
+	0x9624, 0xCA57, 0x9628, 0xCBAE, 0x962A, 0xA8C1, 0x962C, 0xA8C2,
+	0x962D, 0xCBB0, 0x962E, 0xA8BF, 0x962F, 0xCBAF, 0x9630, 0xCBAD,
+	0x9631, 0xA8C0, 0x9632, 0xA8BE, 0x9639, 0xCDD8, 0x963A, 0xCDDB,
+	0x963B, 0xAAFD, 0x963C, 0xCDDA, 0x963D, 0xCDD9, 0x963F, 0xAAFC,
+	0x9640, 0xAAFB, 0x9642, 0xAB40, 0x9643, 0xCDDC, 0x9644, 0xAAFE,
+	0x964A, 0xD0C6, 0x964B, 0xADAE, 0x964C, 0xADAF, 0x964D, 0xADB0,
+	0x964E, 0xD0C7, 0x964F, 0xD0C3, 0x9650, 0xADAD, 0x9651, 0xD0C4,
+	0x9653, 0xD0C5, 0x9654, 0xD0C2, 0x9658, 0xB0A4, 0x965B, 0xB0A1,
+	0x965C, 0xD445, 0x965D, 0xB0A2, 0x965E, 0xB0A5, 0x965F, 0xD446,
+	0x9661, 0xB07E, 0x9662, 0xB07C, 0x9663, 0xB07D, 0x9664, 0xB0A3,
+	0x966A, 0xB3AD, 0x966B, 0xD849, 0x966C, 0xB3B5, 0x966D, 0xD848,
+	0x966F, 0xD84B, 0x9670, 0xB3B1, 0x9671, 0xD84A, 0x9672, 0xB6AB,
+	0x9673, 0xB3AF, 0x9674, 0xB3B2, 0x9675, 0xB3AE, 0x9676, 0xB3B3,
+	0x9677, 0xB3B4, 0x9678, 0xB3B0, 0x967C, 0xD847, 0x967D, 0xB6A7,
+	0x967E, 0xDC7D, 0x9680, 0xDCA3, 0x9683, 0xDCA2, 0x9684, 0xB6AC,
+	0x9685, 0xB6A8, 0x9686, 0xB6A9, 0x9687, 0xDC7C, 0x9688, 0xDC7E,
+	0x9689, 0xDCA1, 0x968A, 0xB6A4, 0x968B, 0xB6A6, 0x968D, 0xB6AA,
+	0x968E, 0xB6A5, 0x9691, 0xE0D3, 0x9692, 0xE0D1, 0x9693, 0xE0D2,
+	0x9694, 0xB96A, 0x9695, 0xB96B, 0x9697, 0xE0D4, 0x9698, 0xB969,
+	0x9699, 0xBBD8, 0x969B, 0xBBDA, 0x969C, 0xBBD9, 0x969E, 0xE4BB,
+	0x96A1, 0xE4BC, 0x96A2, 0xE8AB, 0x96A4, 0xE8AA, 0x96A7, 0xC047,
+	0x96A8, 0xC048, 0x96A9, 0xEC4F, 0x96AA, 0xC049, 0x96AC, 0xEEF6,
+	0x96AE, 0xEEF4, 0x96B0, 0xEEF5, 0x96B1, 0xC1F4, 0x96B3, 0xF16F,
+	0x96B4, 0xC3F7, 0x96B8, 0xC1F5, 0x96B9, 0xAB41, 0x96BB, 0xB0A6,
+	0x96BC, 0xD447, 0x96BF, 0xD84C, 0x96C0, 0xB3B6, 0x96C1, 0xB6AD,
+	0x96C2, 0xDCA4, 0x96C3, 0xDCA6, 0x96C4, 0xB6AF, 0x96C5, 0xB6AE,
+	0x96C6, 0xB6B0, 0x96C7, 0xB6B1, 0x96C8, 0xDCA5, 0x96C9, 0xB96E,
+	0x96CA, 0xB96F, 0x96CB, 0xB96D, 0x96CC, 0xBBDB, 0x96CD, 0xB96C,
+	0x96CE, 0xE0D5, 0x96D2, 0xBBDC, 0x96D3, 0xE8AC, 0x96D4, 0xEC50,
+	0x96D5, 0xC04A, 0x96D6, 0xC1F6, 0x96D7, 0xF170, 0x96D8, 0xF174,
+	0x96D9, 0xC2F9, 0x96DA, 0xF171, 0x96DB, 0xC2FA, 0x96DC, 0xC2F8,
+	0x96DD, 0xF175, 0x96DE, 0xC2FB, 0x96DF, 0xF173, 0x96E1, 0xF379,
+	0x96E2, 0xC2F7, 0x96E3, 0xC3F8, 0x96E5, 0xF8CD, 0x96E8, 0xAB42,
+	0x96E9, 0xB3B8, 0x96EA, 0xB3B7, 0x96EF, 0xB6B2, 0x96F0, 0xDCA8,
+	0x96F1, 0xDCA7, 0x96F2, 0xB6B3, 0x96F5, 0xE0D9, 0x96F6, 0xB973,
+	0x96F7, 0xB970, 0x96F8, 0xE0D8, 0x96F9, 0xB972, 0x96FA, 0xE0D6,
+	0x96FB, 0xB971, 0x96FD, 0xE0D7, 0x96FF, 0xE4BD, 0x9700, 0xBBDD,
+	0x9702, 0xE8AF, 0x9704, 0xBE5D, 0x9705, 0xE8AD, 0x9706, 0xBE5E,
+	0x9707, 0xBE5F, 0x9708, 0xE8AE, 0x9709, 0xBE60, 0x970B, 0xEC51,
+	0x970D, 0xC04E, 0x970E, 0xC04B, 0x970F, 0xC050, 0x9710, 0xEC53,
+	0x9711, 0xC04C, 0x9712, 0xEC52, 0x9713, 0xC04F, 0x9716, 0xC04D,
+	0x9718, 0xEEF9, 0x9719, 0xEEFB, 0x971C, 0xC1F7, 0x971D, 0xEEFA,
+	0x971E, 0xC1F8, 0x971F, 0xEEF8, 0x9720, 0xEEF7, 0x9722, 0xF177,
+	0x9723, 0xF176, 0x9724, 0xC2FC, 0x9725, 0xF178, 0x9726, 0xF37E,
+	0x9727, 0xC3FA, 0x9728, 0xF37D, 0x9729, 0xF37A, 0x972A, 0xC3F9,
+	0x972B, 0xF37B, 0x972C, 0xF37C, 0x972E, 0xF548, 0x972F, 0xF549,
+	0x9730, 0xC4C5, 0x9732, 0xC553, 0x9735, 0xF66E, 0x9738, 0xC551,
+	0x9739, 0xC552, 0x973A, 0xF66F, 0x973D, 0xC5B4, 0x973E, 0xC5B5,
+	0x973F, 0xF771, 0x9742, 0xC645, 0x9743, 0xF8CF, 0x9744, 0xC647,
+	0x9746, 0xF8CE, 0x9747, 0xF8D0, 0x9748, 0xC646, 0x9749, 0xF957,
+	0x974B, 0xF9AD, 0x9752, 0xAB43, 0x9756, 0xB974, 0x9758, 0xE4BE,
+	0x975A, 0xE8B0, 0x975B, 0xC051, 0x975C, 0xC052, 0x975E, 0xAB44,
+	0x9760, 0xBE61, 0x9761, 0xC3FB, 0x9762, 0xADB1, 0x9766, 0xC053,
+	0x9768, 0xC5E2, 0x9769, 0xADB2, 0x976A, 0xD84D, 0x976C, 0xDCA9,
+	0x976E, 0xDCAB, 0x9770, 0xDCAA, 0x9772, 0xE0DD, 0x9773, 0xE0DA,
+	0x9774, 0xB975, 0x9776, 0xB976, 0x9777, 0xE0DB, 0x9778, 0xE0DC,
+	0x977A, 0xE4C0, 0x977B, 0xE4C5, 0x977C, 0xBBDE, 0x977D, 0xE4BF,
+	0x977E, 0xE4C1, 0x977F, 0xE4C8, 0x9780, 0xE4C3, 0x9781, 0xE4C7,
+	0x9782, 0xE4C4, 0x9783, 0xE4C2, 0x9784, 0xE4C6, 0x9785, 0xBBDF,
+	0x9788, 0xE8B3, 0x978A, 0xE8B1, 0x978B, 0xBE63, 0x978D, 0xBE62,
+	0x978E, 0xE8B2, 0x978F, 0xBE64, 0x9794, 0xEC56, 0x9797, 0xEC55,
+	0x9798, 0xC054, 0x9799, 0xEC54, 0x979A, 0xEEFC, 0x979C, 0xEEFE,
+	0x979D, 0xEF41, 0x979E, 0xEF40, 0x97A0, 0xC1F9, 0x97A1, 0xEEFD,
+	0x97A2, 0xF1A1, 0x97A3, 0xC2FD, 0x97A4, 0xF17D, 0x97A5, 0xF1A2,
+	0x97A6, 0xC2FE, 0x97A8, 0xF17B, 0x97AA, 0xF17E, 0x97AB, 0xF17C,
+	0x97AC, 0xF179, 0x97AD, 0xC340, 0x97AE, 0xF17A, 0x97B3, 0xF3A1,
+	0x97B6, 0xF3A3, 0x97B7, 0xF3A2, 0x97B9, 0xF54A, 0x97BB, 0xF54B,
+	0x97BF, 0xF670, 0x97C1, 0xC5B7, 0x97C3, 0xC5B6, 0x97C4, 0xF84F,
+	0x97C5, 0xF850, 0x97C6, 0xC648, 0x97C7, 0xF8D1, 0x97C9, 0xC669,
+	0x97CB, 0xADB3, 0x97CC, 0xB6B4, 0x97CD, 0xE4CA, 0x97CE, 0xE4C9,
+	0x97CF, 0xE8B5, 0x97D0, 0xE8B4, 0x97D3, 0xC1FA, 0x97D4, 0xEF43,
+	0x97D5, 0xEF42, 0x97D6, 0xF1A5, 0x97D7, 0xF1A3, 0x97D8, 0xF1A6,
+	0x97D9, 0xF1A4, 0x97DC, 0xC3FC, 0x97DD, 0xF3A4, 0x97DE, 0xF3A5,
+	0x97DF, 0xF3A6, 0x97E1, 0xF671, 0x97E3, 0xF772, 0x97E5, 0xF8D2,
+	0x97ED, 0xADB4, 0x97F0, 0xEC57, 0x97F1, 0xEF44, 0x97F3, 0xADB5,
+	0x97F6, 0xBBE0, 0x97F8, 0xEC58, 0x97F9, 0xC341, 0x97FA, 0xF1A7,
+	0x97FB, 0xC3FD, 0x97FD, 0xF54C, 0x97FE, 0xF54D, 0x97FF, 0xC554,
+	0x9800, 0xF851, 0x9801, 0xADB6, 0x9802, 0xB3BB, 0x9803, 0xB3BC,
+	0x9804, 0xD84E, 0x9805, 0xB6B5, 0x9806, 0xB6B6, 0x9807, 0xDCAC,
+	0x9808, 0xB6B7, 0x980A, 0xB97A, 0x980C, 0xB97C, 0x980D, 0xE0DF,
+	0x980E, 0xE0E0, 0x980F, 0xE0DE, 0x9810, 0xB977, 0x9811, 0xB978,
+	0x9812, 0xB97B, 0x9813, 0xB979, 0x9816, 0xE4CB, 0x9817, 0xBBE1,
+	0x9818, 0xBBE2, 0x981B, 0xE8BC, 0x981C, 0xBE67, 0x981D, 0xE8B7,
+	0x981E, 0xE8B6, 0x9820, 0xE8BB, 0x9821, 0xBE65, 0x9824, 0xC05B,
+	0x9826, 0xE8B8, 0x9827, 0xE8BD, 0x9828, 0xE8BA, 0x9829, 0xE8B9,
+	0x982B, 0xBE66, 0x982D, 0xC059, 0x982F, 0xEC5A, 0x9830, 0xC055,
+	0x9832, 0xEC5B, 0x9835, 0xEC59, 0x9837, 0xC058, 0x9838, 0xC056,
+	0x9839, 0xC05A, 0x983B, 0xC057, 0x9841, 0xEF45, 0x9843, 0xEF4A,
+	0x9844, 0xEF46, 0x9845, 0xEF49, 0x9846, 0xC1FB, 0x9848, 0xEDD4,
+	0x9849, 0xEF48, 0x984A, 0xEF47, 0x984C, 0xC344, 0x984D, 0xC342,
+	0x984E, 0xC345, 0x984F, 0xC343, 0x9850, 0xF1A8, 0x9851, 0xF1A9,
+	0x9852, 0xF1AA, 0x9853, 0xC346, 0x9857, 0xF3AA, 0x9858, 0xC440,
+	0x9859, 0xF3A8, 0x985B, 0xC441, 0x985C, 0xF3A7, 0x985D, 0xF3A9,
+	0x985E, 0xC3FE, 0x985F, 0xF551, 0x9860, 0xF54E, 0x9862, 0xF54F,
+	0x9863, 0xF550, 0x9864, 0xF672, 0x9865, 0xC556, 0x9867, 0xC555,
+	0x9869, 0xF774, 0x986A, 0xF773, 0x986B, 0xC5B8, 0x986F, 0xC5E3,
+	0x9870, 0xC649, 0x9871, 0xC660, 0x9872, 0xF958, 0x9873, 0xF9AE,
+	0x9874, 0xF9AF, 0x98A8, 0xADB7, 0x98A9, 0xDCAD, 0x98AC, 0xE0E1,
+	0x98AD, 0xE4CC, 0x98AE, 0xE4CD, 0x98AF, 0xBBE3, 0x98B1, 0xBBE4,
+	0x98B2, 0xE8BE, 0x98B3, 0xBE68, 0x98B6, 0xC1FC, 0x98B8, 0xF1AB,
+	0x98BA, 0xC347, 0x98BB, 0xF3AD, 0x98BC, 0xC442, 0x98BD, 0xF3AC,
+	0x98BE, 0xF3AE, 0x98BF, 0xF3AB, 0x98C0, 0xF675, 0x98C1, 0xF552,
+	0x98C2, 0xF553, 0x98C4, 0xC4C6, 0x98C6, 0xF674, 0x98C9, 0xF673,
+	0x98CB, 0xF775, 0x98CC, 0xF9B0, 0x98DB, 0xADB8, 0x98DF, 0xADB9,
+	0x98E2, 0xB0A7, 0x98E3, 0xD448, 0x98E5, 0xD84F, 0x98E7, 0xB6B8,
+	0x98E9, 0xB6BB, 0x98EA, 0xB6B9, 0x98EB, 0xDCAE, 0x98ED, 0xB6BD,
+	0x98EF, 0xB6BA, 0x98F2, 0xB6BC, 0x98F4, 0xB97E, 0x98F6, 0xE0E2,
+	0x98F9, 0xE0E3, 0x98FA, 0xE8C0, 0x98FC, 0xB97D, 0x98FD, 0xB9A1,
+	0x98FE, 0xB9A2, 0x9900, 0xE4CF, 0x9902, 0xE4CE, 0x9903, 0xBBE5,
+	0x9905, 0xBBE6, 0x9907, 0xE4D0, 0x9908, 0xE8BF, 0x9909, 0xBBE8,
+	0x990A, 0xBE69, 0x990C, 0xBBE7, 0x9910, 0xC05C, 0x9911, 0xE8C1,
+	0x9912, 0xBE6B, 0x9913, 0xBE6A, 0x9914, 0xE8C2, 0x9915, 0xE8C5,
+	0x9916, 0xE8C3, 0x9917, 0xE8C4, 0x9918, 0xBE6C, 0x991A, 0xC061,
+	0x991B, 0xC05F, 0x991E, 0xC05E, 0x991F, 0xEC5D, 0x9921, 0xC060,
+	0x9924, 0xEC5C, 0x9925, 0xEF4B, 0x9927, 0xEC5E, 0x9928, 0xC05D,
+	0x9929, 0xEC5F, 0x992A, 0xEF4E, 0x992B, 0xEF4C, 0x992C, 0xEF4D,
+	0x992D, 0xEF52, 0x992E, 0xC34B, 0x992F, 0xEF51, 0x9930, 0xEF54,
+	0x9931, 0xEF53, 0x9932, 0xEF50, 0x9933, 0xEF4F, 0x9935, 0xC1FD,
+	0x993A, 0xF1AE, 0x993C, 0xF1AD, 0x993D, 0xC34A, 0x993E, 0xC348,
+	0x993F, 0xC349, 0x9941, 0xF1AC, 0x9943, 0xF3B1, 0x9945, 0xC443,
+	0x9947, 0xF3B0, 0x9948, 0xF3AF, 0x9949, 0xC444, 0x994B, 0xF558,
+	0x994C, 0xF557, 0x994E, 0xF555, 0x9950, 0xF554, 0x9951, 0xC4C8,
+	0x9952, 0xC4C7, 0x9953, 0xF559, 0x9954, 0xF776, 0x9955, 0xC5B9,
+	0x9956, 0xF677, 0x9957, 0xC557, 0x9958, 0xF676, 0x9959, 0xF556,
+	0x995B, 0xF777, 0x995C, 0xC5E4, 0x995E, 0xC661, 0x995F, 0xF959,
+	0x9961, 0xF9B1, 0x9996, 0xADBA, 0x9997, 0xD850, 0x9998, 0xEF55,
+	0x9999, 0xADBB, 0x999C, 0xE4D2, 0x999D, 0xE4D1, 0x999E, 0xEC60,
+	0x99A1, 0xEF57, 0x99A3, 0xEF56, 0x99A5, 0xC34C, 0x99A6, 0xF3B2,
+	0x99A7, 0xF3B3, 0x99A8, 0xC4C9, 0x99AB, 0xF9B2, 0x99AC, 0xB0A8,
+	0x99AD, 0xB6BF, 0x99AE, 0xB6BE, 0x99AF, 0xE0E4, 0x99B0, 0xE0E6,
+	0x99B1, 0xB9A4, 0x99B2, 0xE0E5, 0x99B3, 0xB9A3, 0x99B4, 0xB9A5,
+	0x99B5, 0xE0E7, 0x99B9, 0xE4D4, 0x99BA, 0xE4D6, 0x99BB, 0xE4D5,
+	0x99BD, 0xE4D8, 0x99C1, 0xBBE9, 0x99C2, 0xE4D7, 0x99C3, 0xE4D3,
+	0x99C7, 0xE4D9, 0x99C9, 0xE8CC, 0x99CB, 0xE8CF, 0x99CC, 0xE8D1,
+	0x99CD, 0xE8C7, 0x99CE, 0xE8CB, 0x99CF, 0xE8C8, 0x99D0, 0xBE6E,
+	0x99D1, 0xBE71, 0x99D2, 0xBE73, 0x99D3, 0xE8C9, 0x99D4, 0xE8CA,
+	0x99D5, 0xBE72, 0x99D6, 0xE8CD, 0x99D7, 0xE8D0, 0x99D8, 0xE8CE,
+	0x99D9, 0xBE74, 0x99DB, 0xBE70, 0x99DC, 0xE8C6, 0x99DD, 0xBE6D,
+	0x99DF, 0xBE6F, 0x99E2, 0xC063, 0x99E3, 0xEC66, 0x99E4, 0xEC64,
+	0x99E5, 0xEC63, 0x99E7, 0xEC69, 0x99E9, 0xEC68, 0x99EA, 0xEC67,
+	0x99EC, 0xEC62, 0x99ED, 0xC062, 0x99EE, 0xEC61, 0x99F0, 0xEC65,
+	0x99F1, 0xC064, 0x99F4, 0xEF5A, 0x99F6, 0xEF5E, 0x99F7, 0xEF5B,
+	0x99F8, 0xEF5D, 0x99F9, 0xEF5C, 0x99FA, 0xEF59, 0x99FB, 0xEF5F,
+	0x99FC, 0xEF62, 0x99FD, 0xEF60, 0x99FE, 0xEF61, 0x99FF, 0xC240,
+	0x9A01, 0xC1FE, 0x9A02, 0xEF58, 0x9A03, 0xEF63, 0x9A04, 0xF1B3,
+	0x9A05, 0xF1B6, 0x9A06, 0xF1B8, 0x9A07, 0xF1B7, 0x9A09, 0xF1B1,
+	0x9A0A, 0xF1B5, 0x9A0B, 0xF1B0, 0x9A0D, 0xF1B2, 0x9A0E, 0xC34D,
+	0x9A0F, 0xF1AF, 0x9A11, 0xF1B4, 0x9A14, 0xF3C0, 0x9A15, 0xF3B5,
+	0x9A16, 0xC445, 0x9A19, 0xC446, 0x9A1A, 0xF3B4, 0x9A1B, 0xF3B9,
+	0x9A1C, 0xF3BF, 0x9A1D, 0xF3B7, 0x9A1E, 0xF3BE, 0x9A20, 0xF3BB,
+	0x9A22, 0xF3BA, 0x9A23, 0xF3BD, 0x9A24, 0xF3B8, 0x9A25, 0xF3B6,
+	0x9A27, 0xF3BC, 0x9A29, 0xF560, 0x9A2A, 0xF55E, 0x9A2B, 0xC4CA,
+	0x9A2C, 0xF55D, 0x9A2D, 0xF563, 0x9A2E, 0xF561, 0x9A30, 0xC4CB,
+	0x9A31, 0xF55C, 0x9A32, 0xF55A, 0x9A34, 0xF55B, 0x9A35, 0xC4CD,
+	0x9A36, 0xF55F, 0x9A37, 0xC4CC, 0x9A38, 0xF562, 0x9A39, 0xF678,
+	0x9A3A, 0xF67E, 0x9A3D, 0xF679, 0x9A3E, 0xC55B, 0x9A3F, 0xF6A1,
+	0x9A40, 0xC55A, 0x9A41, 0xF67D, 0x9A42, 0xF67C, 0x9A43, 0xC559,
+	0x9A44, 0xF67B, 0x9A45, 0xC558, 0x9A46, 0xF67A, 0x9A48, 0xF77D,
+	0x9A49, 0xF7A1, 0x9A4A, 0xF77E, 0x9A4C, 0xF77B, 0x9A4D, 0xC5BB,
+	0x9A4E, 0xF778, 0x9A4F, 0xF77C, 0x9A50, 0xF7A3, 0x9A52, 0xF7A2,
+	0x9A53, 0xF779, 0x9A54, 0xF77A, 0x9A55, 0xC5BA, 0x9A56, 0xF852,
+	0x9A57, 0xC5E7, 0x9A59, 0xF853, 0x9A5A, 0xC5E5, 0x9A5B, 0xC5E6,
+	0x9A5E, 0xF8D3, 0x9A5F, 0xC64A, 0x9A60, 0xF976, 0x9A62, 0xC66A,
+	0x9A64, 0xF9B3, 0x9A65, 0xC66B, 0x9A66, 0xF9B4, 0x9A67, 0xF9B5,
+	0x9A68, 0xF9C3, 0x9A69, 0xF9C2, 0x9A6A, 0xC67A, 0x9A6B, 0xF9CD,
+	0x9AA8, 0xB0A9, 0x9AAB, 0xE0E9, 0x9AAD, 0xE0E8, 0x9AAF, 0xBBEA,
+	0x9AB0, 0xBBEB, 0x9AB1, 0xE4DA, 0x9AB3, 0xE8D2, 0x9AB4, 0xEC6C,
+	0x9AB7, 0xBE75, 0x9AB8, 0xC065, 0x9AB9, 0xEC6A, 0x9ABB, 0xEC6D,
+	0x9ABC, 0xC066, 0x9ABE, 0xEF64, 0x9ABF, 0xEC6B, 0x9AC0, 0xF1B9,
+	0x9AC1, 0xC34E, 0x9AC2, 0xF3C1, 0x9AC6, 0xF566, 0x9AC7, 0xF564,
+	0x9ACA, 0xF565, 0x9ACD, 0xF6A2, 0x9ACF, 0xC55C, 0x9AD0, 0xF7A4,
+	0x9AD1, 0xC5EA, 0x9AD2, 0xC5BC, 0x9AD3, 0xC5E8, 0x9AD4, 0xC5E9,
+	0x9AD5, 0xF8D4, 0x9AD6, 0xC662, 0x9AD8, 0xB0AA, 0x9ADC, 0xF1BA,
+	0x9ADF, 0xD449, 0x9AE1, 0xB9A6, 0x9AE3, 0xE4DB, 0x9AE6, 0xBBEC,
+	0x9AE7, 0xE4DC, 0x9AEB, 0xE8D4, 0x9AEC, 0xE8D3, 0x9AED, 0xC068,
+	0x9AEE, 0xBE76, 0x9AEF, 0xBE77, 0x9AF1, 0xE8D7, 0x9AF2, 0xE8D6,
+	0x9AF3, 0xE8D5, 0x9AF6, 0xEC6E, 0x9AF7, 0xEC71, 0x9AF9, 0xEC70,
+	0x9AFA, 0xEC6F, 0x9AFB, 0xC067, 0x9AFC, 0xEF68, 0x9AFD, 0xEF66,
+	0x9AFE, 0xEF65, 0x9B01, 0xEF67, 0x9B03, 0xC34F, 0x9B04, 0xF1BC,
+	0x9B05, 0xF1BD, 0x9B06, 0xC350, 0x9B08, 0xF1BB, 0x9B0A, 0xF3C3,
+	0x9B0B, 0xF3C2, 0x9B0C, 0xF3C5, 0x9B0D, 0xC447, 0x9B0E, 0xF3C4,
+	0x9B10, 0xF567, 0x9B11, 0xF569, 0x9B12, 0xF568, 0x9B15, 0xF6A3,
+	0x9B16, 0xF6A6, 0x9B17, 0xF6A4, 0x9B18, 0xF6A5, 0x9B19, 0xF7A5,
+	0x9B1A, 0xC5BD, 0x9B1E, 0xF854, 0x9B1F, 0xF855, 0x9B20, 0xF856,
+	0x9B22, 0xC64B, 0x9B23, 0xC663, 0x9B24, 0xF9B6, 0x9B25, 0xB0AB,
+	0x9B27, 0xBE78, 0x9B28, 0xC069, 0x9B29, 0xF1BE, 0x9B2B, 0xF7A6,
+	0x9B2E, 0xF9C4, 0x9B2F, 0xD44A, 0x9B31, 0xC67B, 0x9B32, 0xB0AC,
+	0x9B33, 0xEC72, 0x9B35, 0xF1BF, 0x9B37, 0xF3C6, 0x9B3A, 0xF6A7,
+	0x9B3B, 0xF7A7, 0x9B3C, 0xB0AD, 0x9B3E, 0xE4DD, 0x9B3F, 0xE4DE,
+	0x9B41, 0xBBED, 0x9B42, 0xBBEE, 0x9B43, 0xE8D9, 0x9B44, 0xBE7A,
+	0x9B45, 0xBE79, 0x9B46, 0xE8D8, 0x9B48, 0xEF69, 0x9B4A, 0xF1C0,
+	0x9B4B, 0xF1C2, 0x9B4C, 0xF1C1, 0x9B4D, 0xC353, 0x9B4E, 0xC352,
+	0x9B4F, 0xC351, 0x9B51, 0xC55E, 0x9B52, 0xF6A8, 0x9B54, 0xC55D,
+	0x9B55, 0xF7A9, 0x9B56, 0xF7A8, 0x9B58, 0xC64C, 0x9B59, 0xF8D5,
+	0x9B5A, 0xB3BD, 0x9B5B, 0xE0EA, 0x9B5F, 0xE4E1, 0x9B60, 0xE4DF,
+	0x9B61, 0xE4E0, 0x9B64, 0xE8E2, 0x9B66, 0xE8DD, 0x9B67, 0xE8DA,
+	0x9B68, 0xE8E1, 0x9B6C, 0xE8E3, 0x9B6F, 0xBE7C, 0x9B70, 0xE8E0,
+	0x9B71, 0xE8DC, 0x9B74, 0xE8DB, 0x9B75, 0xE8DF, 0x9B76, 0xE8DE,
+	0x9B77, 0xBE7B, 0x9B7A, 0xEC7D, 0x9B7B, 0xEC78, 0x9B7C, 0xEC76,
+	0x9B7D, 0xECA1, 0x9B7E, 0xEC77, 0x9B80, 0xEC73, 0x9B82, 0xEC79,
+	0x9B85, 0xEC74, 0x9B86, 0xEF72, 0x9B87, 0xEC75, 0x9B88, 0xECA2,
+	0x9B90, 0xEC7C, 0x9B91, 0xC06A, 0x9B92, 0xEC7B, 0x9B93, 0xEC7A,
+	0x9B95, 0xEC7E, 0x9B9A, 0xEF6A, 0x9B9B, 0xEF6D, 0x9B9E, 0xEF6C,
+	0x9BA0, 0xEF74, 0x9BA1, 0xEF6F, 0x9BA2, 0xEF73, 0x9BA4, 0xEF71,
+	0x9BA5, 0xEF70, 0x9BA6, 0xEF6E, 0x9BA8, 0xEF6B, 0x9BAA, 0xC243,
+	0x9BAB, 0xC242, 0x9BAD, 0xC244, 0x9BAE, 0xC241, 0x9BAF, 0xEF75,
+	0x9BB5, 0xF1C8, 0x9BB6, 0xF1CB, 0x9BB8, 0xF1C9, 0x9BB9, 0xF1CD,
+	0x9BBD, 0xF1CE, 0x9BBF, 0xF1C6, 0x9BC0, 0xC358, 0x9BC1, 0xF1C7,
+	0x9BC3, 0xF1C5, 0x9BC4, 0xF1CC, 0x9BC6, 0xF1C4, 0x9BC7, 0xF1C3,
+	0x9BC8, 0xC357, 0x9BC9, 0xC355, 0x9BCA, 0xC354, 0x9BD3, 0xF1CA,
+	0x9BD4, 0xF3CF, 0x9BD5, 0xF3D5, 0x9BD6, 0xC44A, 0x9BD7, 0xF3D0,
+	0x9BD9, 0xF3D3, 0x9BDA, 0xF3D7, 0x9BDB, 0xC44B, 0x9BDC, 0xF3D2,
+	0x9BDE, 0xF3CA, 0x9BE0, 0xF3C9, 0x9BE1, 0xF3D6, 0x9BE2, 0xF3CD,
+	0x9BE4, 0xF3CB, 0x9BE5, 0xF3D4, 0x9BE6, 0xF3CC, 0x9BE7, 0xC449,
+	0x9BE8, 0xC448, 0x9BEA, 0xF3C7, 0x9BEB, 0xF3C8, 0x9BEC, 0xF3D1,
+	0x9BF0, 0xF3CE, 0x9BF7, 0xF56C, 0x9BF8, 0xF56F, 0x9BFD, 0xC356,
+	0x9C05, 0xF56D, 0x9C06, 0xF573, 0x9C07, 0xF571, 0x9C08, 0xF56B,
+	0x9C09, 0xF576, 0x9C0B, 0xF56A, 0x9C0D, 0xC4CF, 0x9C0E, 0xF572,
+	0x9C12, 0xF56E, 0x9C13, 0xC4CE, 0x9C14, 0xF575, 0x9C17, 0xF574,
+	0x9C1C, 0xF6AB, 0x9C1D, 0xF6AA, 0x9C21, 0xF6B1, 0x9C23, 0xF6AD,
+	0x9C24, 0xF6B0, 0x9C25, 0xC560, 0x9C28, 0xF6AE, 0x9C29, 0xF6AF,
+	0x9C2B, 0xF6A9, 0x9C2C, 0xF6AC, 0x9C2D, 0xC55F, 0x9C31, 0xC5BF,
+	0x9C32, 0xF7B4, 0x9C33, 0xF7AF, 0x9C34, 0xF7B3, 0x9C36, 0xF7B6,
+	0x9C37, 0xF7B2, 0x9C39, 0xF7AE, 0x9C3B, 0xC5C1, 0x9C3C, 0xF7B1,
+	0x9C3D, 0xF7B5, 0x9C3E, 0xC5C0, 0x9C3F, 0xF7AC, 0x9C40, 0xF570,
+	0x9C41, 0xF7B0, 0x9C44, 0xF7AD, 0x9C46, 0xF7AA, 0x9C48, 0xF7AB,
+	0x9C49, 0xC5BE, 0x9C4A, 0xF85A, 0x9C4B, 0xF85C, 0x9C4C, 0xF85F,
+	0x9C4D, 0xF85B, 0x9C4E, 0xF860, 0x9C50, 0xF859, 0x9C52, 0xF857,
+	0x9C54, 0xC5EB, 0x9C55, 0xF85D, 0x9C56, 0xC5ED, 0x9C57, 0xC5EC,
+	0x9C58, 0xF858, 0x9C59, 0xF85E, 0x9C5E, 0xF8DA, 0x9C5F, 0xC64D,
+	0x9C60, 0xF8DB, 0x9C62, 0xF8D9, 0x9C63, 0xF8D6, 0x9C66, 0xF8D8,
+	0x9C67, 0xF8D7, 0x9C68, 0xF95A, 0x9C6D, 0xF95C, 0x9C6E, 0xF95B,
+	0x9C71, 0xF979, 0x9C73, 0xF978, 0x9C74, 0xF977, 0x9C75, 0xF97A,
+	0x9C77, 0xC673, 0x9C78, 0xC674, 0x9C79, 0xF9CA, 0x9C7A, 0xF9CE,
+	0x9CE5, 0xB3BE, 0x9CE6, 0xDCAF, 0x9CE7, 0xE0ED, 0x9CE9, 0xB9A7,
+	0x9CEA, 0xE0EB, 0x9CED, 0xE0EC, 0x9CF1, 0xE4E2, 0x9CF2, 0xE4E3,
+	0x9CF3, 0xBBF1, 0x9CF4, 0xBBEF, 0x9CF5, 0xE4E4, 0x9CF6, 0xBBF0,
+	0x9CF7, 0xE8E8, 0x9CF9, 0xE8EB, 0x9CFA, 0xE8E5, 0x9CFB, 0xE8EC,
+	0x9CFC, 0xE8E4, 0x9CFD, 0xE8E6, 0x9CFF, 0xE8E7, 0x9D00, 0xE8EA,
+	0x9D03, 0xBEA1, 0x9D04, 0xE8EF, 0x9D05, 0xE8EE, 0x9D06, 0xBE7D,
+	0x9D07, 0xE8E9, 0x9D08, 0xE8ED, 0x9D09, 0xBE7E, 0x9D10, 0xECAC,
+	0x9D12, 0xC06F, 0x9D14, 0xECA7, 0x9D15, 0xC06B, 0x9D17, 0xECA4,
+	0x9D18, 0xECAA, 0x9D19, 0xECAD, 0x9D1B, 0xC070, 0x9D1D, 0xECA9,
+	0x9D1E, 0xECA6, 0x9D1F, 0xECAE, 0x9D20, 0xECA5, 0x9D22, 0xECAB,
+	0x9D23, 0xC06C, 0x9D25, 0xECA3, 0x9D26, 0xC06D, 0x9D28, 0xC06E,
+	0x9D29, 0xECA8, 0x9D2D, 0xEFA9, 0x9D2E, 0xEF7A, 0x9D2F, 0xEF7B,
+	0x9D30, 0xEF7E, 0x9D31, 0xEF7C, 0x9D33, 0xEF76, 0x9D36, 0xEF79,
+	0x9D37, 0xEFA5, 0x9D38, 0xEF7D, 0x9D3B, 0xC245, 0x9D3D, 0xEFA7,
+	0x9D3E, 0xEFA4, 0x9D3F, 0xC246, 0x9D40, 0xEFA6, 0x9D41, 0xEF77,
+	0x9D42, 0xEFA2, 0x9D43, 0xEFA3, 0x9D45, 0xEFA1, 0x9D4A, 0xF1D2,
+	0x9D4B, 0xF1D4, 0x9D4C, 0xF1D7, 0x9D4F, 0xF1D1, 0x9D51, 0xC359,
+	0x9D52, 0xF1D9, 0x9D53, 0xF1D0, 0x9D54, 0xF1DA, 0x9D56, 0xF1D6,
+	0x9D57, 0xF1D8, 0x9D58, 0xF1DC, 0x9D59, 0xF1D5, 0x9D5A, 0xF1DD,
+	0x9D5B, 0xF1D3, 0x9D5C, 0xF1CF, 0x9D5D, 0xC35A, 0x9D5F, 0xF1DB,
+	0x9D60, 0xC35B, 0x9D61, 0xC44D, 0x9D67, 0xEF78, 0x9D68, 0xF3F1,
+	0x9D69, 0xF3E8, 0x9D6A, 0xC44F, 0x9D6B, 0xF3E4, 0x9D6C, 0xC450,
+	0x9D6F, 0xF3ED, 0x9D70, 0xF3E7, 0x9D71, 0xF3DD, 0x9D72, 0xC44E,
+	0x9D73, 0xF3EA, 0x9D74, 0xF3E5, 0x9D75, 0xF3E6, 0x9D77, 0xF3D8,
+	0x9D78, 0xF3DF, 0x9D79, 0xF3EE, 0x9D7B, 0xF3EB, 0x9D7D, 0xF3E3,
+	0x9D7F, 0xF3EF, 0x9D80, 0xF3DE, 0x9D81, 0xF3D9, 0x9D82, 0xF3EC,
+	0x9D84, 0xF3DB, 0x9D85, 0xF3E9, 0x9D86, 0xF3E0, 0x9D87, 0xF3F0,
+	0x9D88, 0xF3DC, 0x9D89, 0xC44C, 0x9D8A, 0xF3DA, 0x9D8B, 0xF3E1,
+	0x9D8C, 0xF3E2, 0x9D90, 0xF57D, 0x9D92, 0xF57B, 0x9D94, 0xF5A2,
+	0x9D96, 0xF5AE, 0x9D97, 0xF5A5, 0x9D98, 0xF57C, 0x9D99, 0xF578,
+	0x9D9A, 0xF5A7, 0x9D9B, 0xF57E, 0x9D9C, 0xF5A3, 0x9D9D, 0xF57A,
+	0x9D9E, 0xF5AA, 0x9D9F, 0xF577, 0x9DA0, 0xF5A1, 0x9DA1, 0xF5A6,
+	0x9DA2, 0xF5A8, 0x9DA3, 0xF5AB, 0x9DA4, 0xF579, 0x9DA6, 0xF5AF,
+	0x9DA7, 0xF5B0, 0x9DA8, 0xF5A9, 0x9DA9, 0xF5AD, 0x9DAA, 0xF5A4,
+	0x9DAC, 0xF6C1, 0x9DAD, 0xF6C4, 0x9DAF, 0xC561, 0x9DB1, 0xF6C3,
+	0x9DB2, 0xF6C8, 0x9DB3, 0xF6C6, 0x9DB4, 0xC562, 0x9DB5, 0xF6BD,
+	0x9DB6, 0xF6B3, 0x9DB7, 0xF6B2, 0x9DB8, 0xC564, 0x9DB9, 0xF6BF,
+	0x9DBA, 0xF6C0, 0x9DBB, 0xF6BC, 0x9DBC, 0xF6B4, 0x9DBE, 0xF6B9,
+	0x9DBF, 0xF5AC, 0x9DC1, 0xF6B5, 0x9DC2, 0xC563, 0x9DC3, 0xF6BB,
+	0x9DC5, 0xF6BA, 0x9DC7, 0xF6B6, 0x9DC8, 0xF6C2, 0x9DCA, 0xF6B7,
+	0x9DCB, 0xF7BB, 0x9DCC, 0xF6C5, 0x9DCD, 0xF6C7, 0x9DCE, 0xF6BE,
+	0x9DCF, 0xF6B8, 0x9DD0, 0xF7BC, 0x9DD1, 0xF7BE, 0x9DD2, 0xF7B8,
+	0x9DD3, 0xC5C2, 0x9DD5, 0xF7C5, 0x9DD6, 0xF7C3, 0x9DD7, 0xC5C3,
+	0x9DD8, 0xF7C2, 0x9DD9, 0xF7C1, 0x9DDA, 0xF7BA, 0x9DDB, 0xF7B7,
+	0x9DDC, 0xF7BD, 0x9DDD, 0xF7C6, 0x9DDE, 0xF7B9, 0x9DDF, 0xF7BF,
+	0x9DE1, 0xF869, 0x9DE2, 0xF86E, 0x9DE3, 0xF864, 0x9DE4, 0xF867,
+	0x9DE5, 0xC5EE, 0x9DE6, 0xF86B, 0x9DE8, 0xF872, 0x9DE9, 0xF7C0,
+	0x9DEB, 0xF865, 0x9DEC, 0xF86F, 0x9DED, 0xF873, 0x9DEE, 0xF86A,
+	0x9DEF, 0xF863, 0x9DF0, 0xF86D, 0x9DF2, 0xF86C, 0x9DF3, 0xF871,
+	0x9DF4, 0xF870, 0x9DF5, 0xF7C4, 0x9DF6, 0xF868, 0x9DF7, 0xF862,
+	0x9DF8, 0xF866, 0x9DF9, 0xC64E, 0x9DFA, 0xC64F, 0x9DFB, 0xF861,
+	0x9DFD, 0xF8E6, 0x9DFE, 0xF8DD, 0x9DFF, 0xF8E5, 0x9E00, 0xF8E2,
+	0x9E01, 0xF8E3, 0x9E02, 0xF8DC, 0x9E03, 0xF8DF, 0x9E04, 0xF8E7,
+	0x9E05, 0xF8E1, 0x9E06, 0xF8E0, 0x9E07, 0xF8DE, 0x9E09, 0xF8E4,
+	0x9E0B, 0xF95D, 0x9E0D, 0xF95E, 0x9E0F, 0xF960, 0x9E10, 0xF95F,
+	0x9E11, 0xF962, 0x9E12, 0xF961, 0x9E13, 0xF97C, 0x9E14, 0xF97B,
+	0x9E15, 0xF9B7, 0x9E17, 0xF9B8, 0x9E19, 0xF9C5, 0x9E1A, 0xC678,
+	0x9E1B, 0xC67C, 0x9E1D, 0xF9CF, 0x9E1E, 0xC67D, 0x9E75, 0xB3BF,
+	0x9E79, 0xC4D0, 0x9E7A, 0xF6C9, 0x9E7C, 0xC650, 0x9E7D, 0xC651,
+	0x9E7F, 0xB3C0, 0x9E80, 0xE0EE, 0x9E82, 0xB9A8, 0x9E83, 0xE8F0,
+	0x9E86, 0xECB0, 0x9E87, 0xECB1, 0x9E88, 0xECAF, 0x9E89, 0xEFAB,
+	0x9E8A, 0xEFAA, 0x9E8B, 0xC247, 0x9E8C, 0xF1DF, 0x9E8D, 0xEFAC,
+	0x9E8E, 0xF1DE, 0x9E91, 0xF3F3, 0x9E92, 0xC451, 0x9E93, 0xC453,
+	0x9E94, 0xF3F2, 0x9E97, 0xC452, 0x9E99, 0xF5B1, 0x9E9A, 0xF5B3,
+	0x9E9B, 0xF5B2, 0x9E9C, 0xF6CA, 0x9E9D, 0xC565, 0x9E9F, 0xC5EF,
+	0x9EA0, 0xF8E8, 0x9EA1, 0xF963, 0x9EA4, 0xF9D2, 0x9EA5, 0xB3C1,
+	0x9EA7, 0xE4E5, 0x9EA9, 0xBEA2, 0x9EAD, 0xECB3, 0x9EAE, 0xECB2,
+	0x9EB0, 0xEFAD, 0x9EB4, 0xC454, 0x9EB5, 0xC4D1, 0x9EB6, 0xF7C7,
+	0x9EB7, 0xF9CB, 0x9EBB, 0xB3C2, 0x9EBC, 0xBBF2, 0x9EBE, 0xBEA3,
+	0x9EC0, 0xF3F4, 0x9EC2, 0xF874, 0x9EC3, 0xB6C0, 0x9EC8, 0xEFAE,
+	0x9ECC, 0xC664, 0x9ECD, 0xB6C1, 0x9ECE, 0xBEA4, 0x9ECF, 0xC248,
+	0x9ED0, 0xF875, 0x9ED1, 0xB6C2, 0x9ED3, 0xE8F1, 0x9ED4, 0xC072,
+	0x9ED5, 0xECB4, 0x9ED6, 0xECB5, 0x9ED8, 0xC071, 0x9EDA, 0xEFAF,
+	0x9EDB, 0xC24C, 0x9EDC, 0xC24A, 0x9EDD, 0xC24B, 0x9EDE, 0xC249,
+	0x9EDF, 0xF1E0, 0x9EE0, 0xC35C, 0x9EE4, 0xF5B5, 0x9EE5, 0xF5B4,
+	0x9EE6, 0xF5B7, 0x9EE7, 0xF5B6, 0x9EE8, 0xC4D2, 0x9EEB, 0xF6CB,
+	0x9EED, 0xF6CD, 0x9EEE, 0xF6CC, 0x9EEF, 0xC566, 0x9EF0, 0xF7C8,
+	0x9EF2, 0xF876, 0x9EF3, 0xF877, 0x9EF4, 0xC5F0, 0x9EF5, 0xF964,
+	0x9EF6, 0xF97D, 0x9EF7, 0xC675, 0x9EF9, 0xDCB0, 0x9EFA, 0xECB6,
+	0x9EFB, 0xEFB0, 0x9EFC, 0xF3F5, 0x9EFD, 0xE0EF, 0x9EFF, 0xEFB1,
+	0x9F00, 0xF1E2, 0x9F01, 0xF1E1, 0x9F06, 0xF878, 0x9F07, 0xC652,
+	0x9F09, 0xF965, 0x9F0A, 0xF97E, 0x9F0E, 0xB9A9, 0x9F0F, 0xE8F2,
+	0x9F10, 0xE8F3, 0x9F12, 0xECB7, 0x9F13, 0xB9AA, 0x9F15, 0xC35D,
+	0x9F16, 0xF1E3, 0x9F18, 0xF6CF, 0x9F19, 0xC567, 0x9F1A, 0xF6D0,
+	0x9F1B, 0xF6CE, 0x9F1C, 0xF879, 0x9F1E, 0xF8E9, 0x9F20, 0xB9AB,
+	0x9F22, 0xEFB4, 0x9F23, 0xEFB3, 0x9F24, 0xEFB2, 0x9F25, 0xF1E4,
+	0x9F28, 0xF1E8, 0x9F29, 0xF1E7, 0x9F2A, 0xF1E6, 0x9F2B, 0xF1E5,
+	0x9F2C, 0xC35E, 0x9F2D, 0xF3F6, 0x9F2E, 0xF5B9, 0x9F2F, 0xC4D3,
+	0x9F30, 0xF5B8, 0x9F31, 0xF6D1, 0x9F32, 0xF7CB, 0x9F33, 0xF7CA,
+	0x9F34, 0xC5C4, 0x9F35, 0xF7C9, 0x9F36, 0xF87C, 0x9F37, 0xF87B,
+	0x9F38, 0xF87A, 0x9F3B, 0xBBF3, 0x9F3D, 0xECB8, 0x9F3E, 0xC24D,
+	0x9F40, 0xF3F7, 0x9F41, 0xF3F8, 0x9F42, 0xF7CC, 0x9F43, 0xF87D,
+	0x9F46, 0xF8EA, 0x9F47, 0xF966, 0x9F48, 0xF9B9, 0x9F49, 0xF9D4,
+	0x9F4A, 0xBBF4, 0x9F4B, 0xC24E, 0x9F4C, 0xF1E9, 0x9F4D, 0xF3F9,
+	0x9F4E, 0xF6D2, 0x9F4F, 0xF87E, 0x9F52, 0xBEA6, 0x9F54, 0xEFB5,
+	0x9F55, 0xF1EA, 0x9F56, 0xF3FA, 0x9F57, 0xF3FB, 0x9F58, 0xF3FC,
+	0x9F59, 0xF5BE, 0x9F5B, 0xF5BA, 0x9F5C, 0xC568, 0x9F5D, 0xF5BD,
+	0x9F5E, 0xF5BC, 0x9F5F, 0xC4D4, 0x9F60, 0xF5BB, 0x9F61, 0xC4D6,
+	0x9F63, 0xC4D5, 0x9F64, 0xF6D4, 0x9F65, 0xF6D3, 0x9F66, 0xC569,
+	0x9F67, 0xC56A, 0x9F6A, 0xC5C6, 0x9F6B, 0xF7CD, 0x9F6C, 0xC5C5,
+	0x9F6E, 0xF8A3, 0x9F6F, 0xF8A4, 0x9F70, 0xF8A2, 0x9F71, 0xF8A1,
+	0x9F72, 0xC654, 0x9F74, 0xF8EB, 0x9F75, 0xF8EC, 0x9F76, 0xF8ED,
+	0x9F77, 0xC653, 0x9F78, 0xF967, 0x9F79, 0xF96A, 0x9F7A, 0xF969,
+	0x9F7B, 0xF968, 0x9F7E, 0xF9D3, 0x9F8D, 0xC073, 0x9F90, 0xC365,
+	0x9F91, 0xF5BF, 0x9F92, 0xF6D5, 0x9F94, 0xC5C7, 0x9F95, 0xF7CE,
+	0x9F98, 0xF9D5, 0x9F9C, 0xC074, 0x9FA0, 0xEFB6, 0x9FA2, 0xF7CF,
+	0x9FA4, 0xF9A1, 0xFA0C, 0xC94A, 0xFA0D, 0xDDFC, 0xFE30, 0xA14A,
+	0xFE31, 0xA157, 0xFE33, 0xA159, 0xFE34, 0xA15B, 0xFE35, 0xA15F,
+	0xFE36, 0xA160, 0xFE37, 0xA163, 0xFE38, 0xA164, 0xFE39, 0xA167,
+	0xFE3A, 0xA168, 0xFE3B, 0xA16B, 0xFE3C, 0xA16C, 0xFE3D, 0xA16F,
+	0xFE3E, 0xA170, 0xFE3F, 0xA173, 0xFE40, 0xA174, 0xFE41, 0xA177,
+	0xFE42, 0xA178, 0xFE43, 0xA17B, 0xFE44, 0xA17C, 0xFE49, 0xA1C6,
+	0xFE4A, 0xA1C7, 0xFE4B, 0xA1CA, 0xFE4C, 0xA1CB, 0xFE4D, 0xA1C8,
+	0xFE4E, 0xA1C9, 0xFE4F, 0xA15C, 0xFE50, 0xA14D, 0xFE51, 0xA14E,
+	0xFE52, 0xA14F, 0xFE54, 0xA151, 0xFE55, 0xA152, 0xFE56, 0xA153,
+	0xFE57, 0xA154, 0xFE59, 0xA17D, 0xFE5A, 0xA17E, 0xFE5B, 0xA1A1,
+	0xFE5C, 0xA1A2, 0xFE5D, 0xA1A3, 0xFE5E, 0xA1A4, 0xFE5F, 0xA1CC,
+	0xFE60, 0xA1CD, 0xFE61, 0xA1CE, 0xFE62, 0xA1DE, 0xFE63, 0xA1DF,
+	0xFE64, 0xA1E0, 0xFE65, 0xA1E1, 0xFE66, 0xA1E2, 0xFE68, 0xA242,
+	0xFE69, 0xA24C, 0xFE6A, 0xA24D, 0xFE6B, 0xA24E, 0xFF01, 0xA149,
+	0xFF03, 0xA1AD, 0xFF04, 0xA243, 0xFF05, 0xA248, 0xFF06, 0xA1AE,
+	0xFF08, 0xA15D, 0xFF09, 0xA15E, 0xFF0A, 0xA1AF, 0xFF0B, 0xA1CF,
+	0xFF0C, 0xA141, 0xFF0D, 0xA1D0, 0xFF0E, 0xA144, 0xFF0F, 0xA1FE,
+	0xFF10, 0xA2AF, 0xFF11, 0xA2B0, 0xFF12, 0xA2B1, 0xFF13, 0xA2B2,
+	0xFF14, 0xA2B3, 0xFF15, 0xA2B4, 0xFF16, 0xA2B5, 0xFF17, 0xA2B6,
+	0xFF18, 0xA2B7, 0xFF19, 0xA2B8, 0xFF1A, 0xA147, 0xFF1B, 0xA146,
+	0xFF1C, 0xA1D5, 0xFF1D, 0xA1D7, 0xFF1E, 0xA1D6, 0xFF1F, 0xA148,
+	0xFF20, 0xA249, 0xFF21, 0xA2CF, 0xFF22, 0xA2D0, 0xFF23, 0xA2D1,
+	0xFF24, 0xA2D2, 0xFF25, 0xA2D3, 0xFF26, 0xA2D4, 0xFF27, 0xA2D5,
+	0xFF28, 0xA2D6, 0xFF29, 0xA2D7, 0xFF2A, 0xA2D8, 0xFF2B, 0xA2D9,
+	0xFF2C, 0xA2DA, 0xFF2D, 0xA2DB, 0xFF2E, 0xA2DC, 0xFF2F, 0xA2DD,
+	0xFF30, 0xA2DE, 0xFF31, 0xA2DF, 0xFF32, 0xA2E0, 0xFF33, 0xA2E1,
+	0xFF34, 0xA2E2, 0xFF35, 0xA2E3, 0xFF36, 0xA2E4, 0xFF37, 0xA2E5,
+	0xFF38, 0xA2E6, 0xFF39, 0xA2E7, 0xFF3A, 0xA2E8, 0xFF3C, 0xA240,
+	0xFF3F, 0xA1C4, 0xFF41, 0xA2E9, 0xFF42, 0xA2EA, 0xFF43, 0xA2EB,
+	0xFF44, 0xA2EC, 0xFF45, 0xA2ED, 0xFF46, 0xA2EE, 0xFF47, 0xA2EF,
+	0xFF48, 0xA2F0, 0xFF49, 0xA2F1, 0xFF4A, 0xA2F2, 0xFF4B, 0xA2F3,
+	0xFF4C, 0xA2F4, 0xFF4D, 0xA2F5, 0xFF4E, 0xA2F6, 0xFF4F, 0xA2F7,
+	0xFF50, 0xA2F8, 0xFF51, 0xA2F9, 0xFF52, 0xA2FA, 0xFF53, 0xA2FB,
+	0xFF54, 0xA2FC, 0xFF55, 0xA2FD, 0xFF56, 0xA2FE, 0xFF57, 0xA340,
+	0xFF58, 0xA341, 0xFF59, 0xA342, 0xFF5A, 0xA343, 0xFF5B, 0xA161,
+	0xFF5C, 0xA155, 0xFF5D, 0xA162, 0xFF5E, 0xA1E3, 0xFFE0, 0xA246,
+	0xFFE1, 0xA247, 0xFFE3, 0xA1C3, 0xFFE5, 0xA244, 0, 0
+};
+
+static
+const WCHAR oem2uni[] = {
+/*	OEM - Unicode,  OEM - Unicode,  OEM - Unicode,  OEM - Unicode */
+	0xA140, 0x3000, 0xA141, 0xFF0C, 0xA142, 0x3001, 0xA143, 0x3002,
+	0xA144, 0xFF0E, 0xA145, 0x2027, 0xA146, 0xFF1B, 0xA147, 0xFF1A,
+	0xA148, 0xFF1F, 0xA149, 0xFF01, 0xA14A, 0xFE30, 0xA14B, 0x2026,
+	0xA14C, 0x2025, 0xA14D, 0xFE50, 0xA14E, 0xFE51, 0xA14F, 0xFE52,
+	0xA150, 0x00B7, 0xA151, 0xFE54, 0xA152, 0xFE55, 0xA153, 0xFE56,
+	0xA154, 0xFE57, 0xA155, 0xFF5C, 0xA156, 0x2013, 0xA157, 0xFE31,
+	0xA158, 0x2014, 0xA159, 0xFE33, 0xA15A, 0x2574, 0xA15B, 0xFE34,
+	0xA15C, 0xFE4F, 0xA15D, 0xFF08, 0xA15E, 0xFF09, 0xA15F, 0xFE35,
+	0xA160, 0xFE36, 0xA161, 0xFF5B, 0xA162, 0xFF5D, 0xA163, 0xFE37,
+	0xA164, 0xFE38, 0xA165, 0x3014, 0xA166, 0x3015, 0xA167, 0xFE39,
+	0xA168, 0xFE3A, 0xA169, 0x3010, 0xA16A, 0x3011, 0xA16B, 0xFE3B,
+	0xA16C, 0xFE3C, 0xA16D, 0x300A, 0xA16E, 0x300B, 0xA16F, 0xFE3D,
+	0xA170, 0xFE3E, 0xA171, 0x3008, 0xA172, 0x3009, 0xA173, 0xFE3F,
+	0xA174, 0xFE40, 0xA175, 0x300C, 0xA176, 0x300D, 0xA177, 0xFE41,
+	0xA178, 0xFE42, 0xA179, 0x300E, 0xA17A, 0x300F, 0xA17B, 0xFE43,
+	0xA17C, 0xFE44, 0xA17D, 0xFE59, 0xA17E, 0xFE5A, 0xA1A1, 0xFE5B,
+	0xA1A2, 0xFE5C, 0xA1A3, 0xFE5D, 0xA1A4, 0xFE5E, 0xA1A5, 0x2018,
+	0xA1A6, 0x2019, 0xA1A7, 0x201C, 0xA1A8, 0x201D, 0xA1A9, 0x301D,
+	0xA1AA, 0x301E, 0xA1AB, 0x2035, 0xA1AC, 0x2032, 0xA1AD, 0xFF03,
+	0xA1AE, 0xFF06, 0xA1AF, 0xFF0A, 0xA1B0, 0x203B, 0xA1B1, 0x00A7,
+	0xA1B2, 0x3003, 0xA1B3, 0x25CB, 0xA1B4, 0x25CF, 0xA1B5, 0x25B3,
+	0xA1B6, 0x25B2, 0xA1B7, 0x25CE, 0xA1B8, 0x2606, 0xA1B9, 0x2605,
+	0xA1BA, 0x25C7, 0xA1BB, 0x25C6, 0xA1BC, 0x25A1, 0xA1BD, 0x25A0,
+	0xA1BE, 0x25BD, 0xA1BF, 0x25BC, 0xA1C0, 0x32A3, 0xA1C1, 0x2105,
+	0xA1C2, 0x00AF, 0xA1C3, 0xFFE3, 0xA1C4, 0xFF3F, 0xA1C5, 0x02CD,
+	0xA1C6, 0xFE49, 0xA1C7, 0xFE4A, 0xA1C8, 0xFE4D, 0xA1C9, 0xFE4E,
+	0xA1CA, 0xFE4B, 0xA1CB, 0xFE4C, 0xA1CC, 0xFE5F, 0xA1CD, 0xFE60,
+	0xA1CE, 0xFE61, 0xA1CF, 0xFF0B, 0xA1D0, 0xFF0D, 0xA1D1, 0x00D7,
+	0xA1D2, 0x00F7, 0xA1D3, 0x00B1, 0xA1D4, 0x221A, 0xA1D5, 0xFF1C,
+	0xA1D6, 0xFF1E, 0xA1D7, 0xFF1D, 0xA1D8, 0x2266, 0xA1D9, 0x2267,
+	0xA1DA, 0x2260, 0xA1DB, 0x221E, 0xA1DC, 0x2252, 0xA1DD, 0x2261,
+	0xA1DE, 0xFE62, 0xA1DF, 0xFE63, 0xA1E0, 0xFE64, 0xA1E1, 0xFE65,
+	0xA1E2, 0xFE66, 0xA1E3, 0xFF5E, 0xA1E4, 0x2229, 0xA1E5, 0x222A,
+	0xA1E6, 0x22A5, 0xA1E7, 0x2220, 0xA1E8, 0x221F, 0xA1E9, 0x22BF,
+	0xA1EA, 0x33D2, 0xA1EB, 0x33D1, 0xA1EC, 0x222B, 0xA1ED, 0x222E,
+	0xA1EE, 0x2235, 0xA1EF, 0x2234, 0xA1F0, 0x2640, 0xA1F1, 0x2642,
+	0xA1F2, 0x2295, 0xA1F3, 0x2299, 0xA1F4, 0x2191, 0xA1F5, 0x2193,
+	0xA1F6, 0x2190, 0xA1F7, 0x2192, 0xA1F8, 0x2196, 0xA1F9, 0x2197,
+	0xA1FA, 0x2199, 0xA1FB, 0x2198, 0xA1FC, 0x2225, 0xA1FD, 0x2223,
+	0xA1FE, 0xFF0F, 0xA240, 0xFF3C, 0xA241, 0x2215, 0xA242, 0xFE68,
+	0xA243, 0xFF04, 0xA244, 0xFFE5, 0xA245, 0x3012, 0xA246, 0xFFE0,
+	0xA247, 0xFFE1, 0xA248, 0xFF05, 0xA249, 0xFF20, 0xA24A, 0x2103,
+	0xA24B, 0x2109, 0xA24C, 0xFE69, 0xA24D, 0xFE6A, 0xA24E, 0xFE6B,
+	0xA24F, 0x33D5, 0xA250, 0x339C, 0xA251, 0x339D, 0xA252, 0x339E,
+	0xA253, 0x33CE, 0xA254, 0x33A1, 0xA255, 0x338E, 0xA256, 0x338F,
+	0xA257, 0x33C4, 0xA258, 0x00B0, 0xA259, 0x5159, 0xA25A, 0x515B,
+	0xA25B, 0x515E, 0xA25C, 0x515D, 0xA25D, 0x5161, 0xA25E, 0x5163,
+	0xA25F, 0x55E7, 0xA260, 0x74E9, 0xA261, 0x7CCE, 0xA262, 0x2581,
+	0xA263, 0x2582, 0xA264, 0x2583, 0xA265, 0x2584, 0xA266, 0x2585,
+	0xA267, 0x2586, 0xA268, 0x2587, 0xA269, 0x2588, 0xA26A, 0x258F,
+	0xA26B, 0x258E, 0xA26C, 0x258D, 0xA26D, 0x258C, 0xA26E, 0x258B,
+	0xA26F, 0x258A, 0xA270, 0x2589, 0xA271, 0x253C, 0xA272, 0x2534,
+	0xA273, 0x252C, 0xA274, 0x2524, 0xA275, 0x251C, 0xA276, 0x2594,
+	0xA277, 0x2500, 0xA278, 0x2502, 0xA279, 0x2595, 0xA27A, 0x250C,
+	0xA27B, 0x2510, 0xA27C, 0x2514, 0xA27D, 0x2518, 0xA27E, 0x256D,
+	0xA2A1, 0x256E, 0xA2A2, 0x2570, 0xA2A3, 0x256F, 0xA2A4, 0x2550,
+	0xA2A5, 0x255E, 0xA2A6, 0x256A, 0xA2A7, 0x2561, 0xA2A8, 0x25E2,
+	0xA2A9, 0x25E3, 0xA2AA, 0x25E5, 0xA2AB, 0x25E4, 0xA2AC, 0x2571,
+	0xA2AD, 0x2572, 0xA2AE, 0x2573, 0xA2AF, 0xFF10, 0xA2B0, 0xFF11,
+	0xA2B1, 0xFF12, 0xA2B2, 0xFF13, 0xA2B3, 0xFF14, 0xA2B4, 0xFF15,
+	0xA2B5, 0xFF16, 0xA2B6, 0xFF17, 0xA2B7, 0xFF18, 0xA2B8, 0xFF19,
+	0xA2B9, 0x2160, 0xA2BA, 0x2161, 0xA2BB, 0x2162, 0xA2BC, 0x2163,
+	0xA2BD, 0x2164, 0xA2BE, 0x2165, 0xA2BF, 0x2166, 0xA2C0, 0x2167,
+	0xA2C1, 0x2168, 0xA2C2, 0x2169, 0xA2C3, 0x3021, 0xA2C4, 0x3022,
+	0xA2C5, 0x3023, 0xA2C6, 0x3024, 0xA2C7, 0x3025, 0xA2C8, 0x3026,
+	0xA2C9, 0x3027, 0xA2CA, 0x3028, 0xA2CB, 0x3029, 0xA2CC, 0x5341,
+	0xA2CD, 0x5344, 0xA2CE, 0x5345, 0xA2CF, 0xFF21, 0xA2D0, 0xFF22,
+	0xA2D1, 0xFF23, 0xA2D2, 0xFF24, 0xA2D3, 0xFF25, 0xA2D4, 0xFF26,
+	0xA2D5, 0xFF27, 0xA2D6, 0xFF28, 0xA2D7, 0xFF29, 0xA2D8, 0xFF2A,
+	0xA2D9, 0xFF2B, 0xA2DA, 0xFF2C, 0xA2DB, 0xFF2D, 0xA2DC, 0xFF2E,
+	0xA2DD, 0xFF2F, 0xA2DE, 0xFF30, 0xA2DF, 0xFF31, 0xA2E0, 0xFF32,
+	0xA2E1, 0xFF33, 0xA2E2, 0xFF34, 0xA2E3, 0xFF35, 0xA2E4, 0xFF36,
+	0xA2E5, 0xFF37, 0xA2E6, 0xFF38, 0xA2E7, 0xFF39, 0xA2E8, 0xFF3A,
+	0xA2E9, 0xFF41, 0xA2EA, 0xFF42, 0xA2EB, 0xFF43, 0xA2EC, 0xFF44,
+	0xA2ED, 0xFF45, 0xA2EE, 0xFF46, 0xA2EF, 0xFF47, 0xA2F0, 0xFF48,
+	0xA2F1, 0xFF49, 0xA2F2, 0xFF4A, 0xA2F3, 0xFF4B, 0xA2F4, 0xFF4C,
+	0xA2F5, 0xFF4D, 0xA2F6, 0xFF4E, 0xA2F7, 0xFF4F, 0xA2F8, 0xFF50,
+	0xA2F9, 0xFF51, 0xA2FA, 0xFF52, 0xA2FB, 0xFF53, 0xA2FC, 0xFF54,
+	0xA2FD, 0xFF55, 0xA2FE, 0xFF56, 0xA340, 0xFF57, 0xA341, 0xFF58,
+	0xA342, 0xFF59, 0xA343, 0xFF5A, 0xA344, 0x0391, 0xA345, 0x0392,
+	0xA346, 0x0393, 0xA347, 0x0394, 0xA348, 0x0395, 0xA349, 0x0396,
+	0xA34A, 0x0397, 0xA34B, 0x0398, 0xA34C, 0x0399, 0xA34D, 0x039A,
+	0xA34E, 0x039B, 0xA34F, 0x039C, 0xA350, 0x039D, 0xA351, 0x039E,
+	0xA352, 0x039F, 0xA353, 0x03A0, 0xA354, 0x03A1, 0xA355, 0x03A3,
+	0xA356, 0x03A4, 0xA357, 0x03A5, 0xA358, 0x03A6, 0xA359, 0x03A7,
+	0xA35A, 0x03A8, 0xA35B, 0x03A9, 0xA35C, 0x03B1, 0xA35D, 0x03B2,
+	0xA35E, 0x03B3, 0xA35F, 0x03B4, 0xA360, 0x03B5, 0xA361, 0x03B6,
+	0xA362, 0x03B7, 0xA363, 0x03B8, 0xA364, 0x03B9, 0xA365, 0x03BA,
+	0xA366, 0x03BB, 0xA367, 0x03BC, 0xA368, 0x03BD, 0xA369, 0x03BE,
+	0xA36A, 0x03BF, 0xA36B, 0x03C0, 0xA36C, 0x03C1, 0xA36D, 0x03C3,
+	0xA36E, 0x03C4, 0xA36F, 0x03C5, 0xA370, 0x03C6, 0xA371, 0x03C7,
+	0xA372, 0x03C8, 0xA373, 0x03C9, 0xA374, 0x3105, 0xA375, 0x3106,
+	0xA376, 0x3107, 0xA377, 0x3108, 0xA378, 0x3109, 0xA379, 0x310A,
+	0xA37A, 0x310B, 0xA37B, 0x310C, 0xA37C, 0x310D, 0xA37D, 0x310E,
+	0xA37E, 0x310F, 0xA3A1, 0x3110, 0xA3A2, 0x3111, 0xA3A3, 0x3112,
+	0xA3A4, 0x3113, 0xA3A5, 0x3114, 0xA3A6, 0x3115, 0xA3A7, 0x3116,
+	0xA3A8, 0x3117, 0xA3A9, 0x3118, 0xA3AA, 0x3119, 0xA3AB, 0x311A,
+	0xA3AC, 0x311B, 0xA3AD, 0x311C, 0xA3AE, 0x311D, 0xA3AF, 0x311E,
+	0xA3B0, 0x311F, 0xA3B1, 0x3120, 0xA3B2, 0x3121, 0xA3B3, 0x3122,
+	0xA3B4, 0x3123, 0xA3B5, 0x3124, 0xA3B6, 0x3125, 0xA3B7, 0x3126,
+	0xA3B8, 0x3127, 0xA3B9, 0x3128, 0xA3BA, 0x3129, 0xA3BB, 0x02D9,
+	0xA3BC, 0x02C9, 0xA3BD, 0x02CA, 0xA3BE, 0x02C7, 0xA3BF, 0x02CB,
+	0xA3E1, 0x20AC, 0xA440, 0x4E00, 0xA441, 0x4E59, 0xA442, 0x4E01,
+	0xA443, 0x4E03, 0xA444, 0x4E43, 0xA445, 0x4E5D, 0xA446, 0x4E86,
+	0xA447, 0x4E8C, 0xA448, 0x4EBA, 0xA449, 0x513F, 0xA44A, 0x5165,
+	0xA44B, 0x516B, 0xA44C, 0x51E0, 0xA44D, 0x5200, 0xA44E, 0x5201,
+	0xA44F, 0x529B, 0xA450, 0x5315, 0xA451, 0x5341, 0xA452, 0x535C,
+	0xA453, 0x53C8, 0xA454, 0x4E09, 0xA455, 0x4E0B, 0xA456, 0x4E08,
+	0xA457, 0x4E0A, 0xA458, 0x4E2B, 0xA459, 0x4E38, 0xA45A, 0x51E1,
+	0xA45B, 0x4E45, 0xA45C, 0x4E48, 0xA45D, 0x4E5F, 0xA45E, 0x4E5E,
+	0xA45F, 0x4E8E, 0xA460, 0x4EA1, 0xA461, 0x5140, 0xA462, 0x5203,
+	0xA463, 0x52FA, 0xA464, 0x5343, 0xA465, 0x53C9, 0xA466, 0x53E3,
+	0xA467, 0x571F, 0xA468, 0x58EB, 0xA469, 0x5915, 0xA46A, 0x5927,
+	0xA46B, 0x5973, 0xA46C, 0x5B50, 0xA46D, 0x5B51, 0xA46E, 0x5B53,
+	0xA46F, 0x5BF8, 0xA470, 0x5C0F, 0xA471, 0x5C22, 0xA472, 0x5C38,
+	0xA473, 0x5C71, 0xA474, 0x5DDD, 0xA475, 0x5DE5, 0xA476, 0x5DF1,
+	0xA477, 0x5DF2, 0xA478, 0x5DF3, 0xA479, 0x5DFE, 0xA47A, 0x5E72,
+	0xA47B, 0x5EFE, 0xA47C, 0x5F0B, 0xA47D, 0x5F13, 0xA47E, 0x624D,
+	0xA4A1, 0x4E11, 0xA4A2, 0x4E10, 0xA4A3, 0x4E0D, 0xA4A4, 0x4E2D,
+	0xA4A5, 0x4E30, 0xA4A6, 0x4E39, 0xA4A7, 0x4E4B, 0xA4A8, 0x5C39,
+	0xA4A9, 0x4E88, 0xA4AA, 0x4E91, 0xA4AB, 0x4E95, 0xA4AC, 0x4E92,
+	0xA4AD, 0x4E94, 0xA4AE, 0x4EA2, 0xA4AF, 0x4EC1, 0xA4B0, 0x4EC0,
+	0xA4B1, 0x4EC3, 0xA4B2, 0x4EC6, 0xA4B3, 0x4EC7, 0xA4B4, 0x4ECD,
+	0xA4B5, 0x4ECA, 0xA4B6, 0x4ECB, 0xA4B7, 0x4EC4, 0xA4B8, 0x5143,
+	0xA4B9, 0x5141, 0xA4BA, 0x5167, 0xA4BB, 0x516D, 0xA4BC, 0x516E,
+	0xA4BD, 0x516C, 0xA4BE, 0x5197, 0xA4BF, 0x51F6, 0xA4C0, 0x5206,
+	0xA4C1, 0x5207, 0xA4C2, 0x5208, 0xA4C3, 0x52FB, 0xA4C4, 0x52FE,
+	0xA4C5, 0x52FF, 0xA4C6, 0x5316, 0xA4C7, 0x5339, 0xA4C8, 0x5348,
+	0xA4C9, 0x5347, 0xA4CA, 0x5345, 0xA4CB, 0x535E, 0xA4CC, 0x5384,
+	0xA4CD, 0x53CB, 0xA4CE, 0x53CA, 0xA4CF, 0x53CD, 0xA4D0, 0x58EC,
+	0xA4D1, 0x5929, 0xA4D2, 0x592B, 0xA4D3, 0x592A, 0xA4D4, 0x592D,
+	0xA4D5, 0x5B54, 0xA4D6, 0x5C11, 0xA4D7, 0x5C24, 0xA4D8, 0x5C3A,
+	0xA4D9, 0x5C6F, 0xA4DA, 0x5DF4, 0xA4DB, 0x5E7B, 0xA4DC, 0x5EFF,
+	0xA4DD, 0x5F14, 0xA4DE, 0x5F15, 0xA4DF, 0x5FC3, 0xA4E0, 0x6208,
+	0xA4E1, 0x6236, 0xA4E2, 0x624B, 0xA4E3, 0x624E, 0xA4E4, 0x652F,
+	0xA4E5, 0x6587, 0xA4E6, 0x6597, 0xA4E7, 0x65A4, 0xA4E8, 0x65B9,
+	0xA4E9, 0x65E5, 0xA4EA, 0x66F0, 0xA4EB, 0x6708, 0xA4EC, 0x6728,
+	0xA4ED, 0x6B20, 0xA4EE, 0x6B62, 0xA4EF, 0x6B79, 0xA4F0, 0x6BCB,
+	0xA4F1, 0x6BD4, 0xA4F2, 0x6BDB, 0xA4F3, 0x6C0F, 0xA4F4, 0x6C34,
+	0xA4F5, 0x706B, 0xA4F6, 0x722A, 0xA4F7, 0x7236, 0xA4F8, 0x723B,
+	0xA4F9, 0x7247, 0xA4FA, 0x7259, 0xA4FB, 0x725B, 0xA4FC, 0x72AC,
+	0xA4FD, 0x738B, 0xA4FE, 0x4E19, 0xA540, 0x4E16, 0xA541, 0x4E15,
+	0xA542, 0x4E14, 0xA543, 0x4E18, 0xA544, 0x4E3B, 0xA545, 0x4E4D,
+	0xA546, 0x4E4F, 0xA547, 0x4E4E, 0xA548, 0x4EE5, 0xA549, 0x4ED8,
+	0xA54A, 0x4ED4, 0xA54B, 0x4ED5, 0xA54C, 0x4ED6, 0xA54D, 0x4ED7,
+	0xA54E, 0x4EE3, 0xA54F, 0x4EE4, 0xA550, 0x4ED9, 0xA551, 0x4EDE,
+	0xA552, 0x5145, 0xA553, 0x5144, 0xA554, 0x5189, 0xA555, 0x518A,
+	0xA556, 0x51AC, 0xA557, 0x51F9, 0xA558, 0x51FA, 0xA559, 0x51F8,
+	0xA55A, 0x520A, 0xA55B, 0x52A0, 0xA55C, 0x529F, 0xA55D, 0x5305,
+	0xA55E, 0x5306, 0xA55F, 0x5317, 0xA560, 0x531D, 0xA561, 0x4EDF,
+	0xA562, 0x534A, 0xA563, 0x5349, 0xA564, 0x5361, 0xA565, 0x5360,
+	0xA566, 0x536F, 0xA567, 0x536E, 0xA568, 0x53BB, 0xA569, 0x53EF,
+	0xA56A, 0x53E4, 0xA56B, 0x53F3, 0xA56C, 0x53EC, 0xA56D, 0x53EE,
+	0xA56E, 0x53E9, 0xA56F, 0x53E8, 0xA570, 0x53FC, 0xA571, 0x53F8,
+	0xA572, 0x53F5, 0xA573, 0x53EB, 0xA574, 0x53E6, 0xA575, 0x53EA,
+	0xA576, 0x53F2, 0xA577, 0x53F1, 0xA578, 0x53F0, 0xA579, 0x53E5,
+	0xA57A, 0x53ED, 0xA57B, 0x53FB, 0xA57C, 0x56DB, 0xA57D, 0x56DA,
+	0xA57E, 0x5916, 0xA5A1, 0x592E, 0xA5A2, 0x5931, 0xA5A3, 0x5974,
+	0xA5A4, 0x5976, 0xA5A5, 0x5B55, 0xA5A6, 0x5B83, 0xA5A7, 0x5C3C,
+	0xA5A8, 0x5DE8, 0xA5A9, 0x5DE7, 0xA5AA, 0x5DE6, 0xA5AB, 0x5E02,
+	0xA5AC, 0x5E03, 0xA5AD, 0x5E73, 0xA5AE, 0x5E7C, 0xA5AF, 0x5F01,
+	0xA5B0, 0x5F18, 0xA5B1, 0x5F17, 0xA5B2, 0x5FC5, 0xA5B3, 0x620A,
+	0xA5B4, 0x6253, 0xA5B5, 0x6254, 0xA5B6, 0x6252, 0xA5B7, 0x6251,
+	0xA5B8, 0x65A5, 0xA5B9, 0x65E6, 0xA5BA, 0x672E, 0xA5BB, 0x672C,
+	0xA5BC, 0x672A, 0xA5BD, 0x672B, 0xA5BE, 0x672D, 0xA5BF, 0x6B63,
+	0xA5C0, 0x6BCD, 0xA5C1, 0x6C11, 0xA5C2, 0x6C10, 0xA5C3, 0x6C38,
+	0xA5C4, 0x6C41, 0xA5C5, 0x6C40, 0xA5C6, 0x6C3E, 0xA5C7, 0x72AF,
+	0xA5C8, 0x7384, 0xA5C9, 0x7389, 0xA5CA, 0x74DC, 0xA5CB, 0x74E6,
+	0xA5CC, 0x7518, 0xA5CD, 0x751F, 0xA5CE, 0x7528, 0xA5CF, 0x7529,
+	0xA5D0, 0x7530, 0xA5D1, 0x7531, 0xA5D2, 0x7532, 0xA5D3, 0x7533,
+	0xA5D4, 0x758B, 0xA5D5, 0x767D, 0xA5D6, 0x76AE, 0xA5D7, 0x76BF,
+	0xA5D8, 0x76EE, 0xA5D9, 0x77DB, 0xA5DA, 0x77E2, 0xA5DB, 0x77F3,
+	0xA5DC, 0x793A, 0xA5DD, 0x79BE, 0xA5DE, 0x7A74, 0xA5DF, 0x7ACB,
+	0xA5E0, 0x4E1E, 0xA5E1, 0x4E1F, 0xA5E2, 0x4E52, 0xA5E3, 0x4E53,
+	0xA5E4, 0x4E69, 0xA5E5, 0x4E99, 0xA5E6, 0x4EA4, 0xA5E7, 0x4EA6,
+	0xA5E8, 0x4EA5, 0xA5E9, 0x4EFF, 0xA5EA, 0x4F09, 0xA5EB, 0x4F19,
+	0xA5EC, 0x4F0A, 0xA5ED, 0x4F15, 0xA5EE, 0x4F0D, 0xA5EF, 0x4F10,
+	0xA5F0, 0x4F11, 0xA5F1, 0x4F0F, 0xA5F2, 0x4EF2, 0xA5F3, 0x4EF6,
+	0xA5F4, 0x4EFB, 0xA5F5, 0x4EF0, 0xA5F6, 0x4EF3, 0xA5F7, 0x4EFD,
+	0xA5F8, 0x4F01, 0xA5F9, 0x4F0B, 0xA5FA, 0x5149, 0xA5FB, 0x5147,
+	0xA5FC, 0x5146, 0xA5FD, 0x5148, 0xA5FE, 0x5168, 0xA640, 0x5171,
+	0xA641, 0x518D, 0xA642, 0x51B0, 0xA643, 0x5217, 0xA644, 0x5211,
+	0xA645, 0x5212, 0xA646, 0x520E, 0xA647, 0x5216, 0xA648, 0x52A3,
+	0xA649, 0x5308, 0xA64A, 0x5321, 0xA64B, 0x5320, 0xA64C, 0x5370,
+	0xA64D, 0x5371, 0xA64E, 0x5409, 0xA64F, 0x540F, 0xA650, 0x540C,
+	0xA651, 0x540A, 0xA652, 0x5410, 0xA653, 0x5401, 0xA654, 0x540B,
+	0xA655, 0x5404, 0xA656, 0x5411, 0xA657, 0x540D, 0xA658, 0x5408,
+	0xA659, 0x5403, 0xA65A, 0x540E, 0xA65B, 0x5406, 0xA65C, 0x5412,
+	0xA65D, 0x56E0, 0xA65E, 0x56DE, 0xA65F, 0x56DD, 0xA660, 0x5733,
+	0xA661, 0x5730, 0xA662, 0x5728, 0xA663, 0x572D, 0xA664, 0x572C,
+	0xA665, 0x572F, 0xA666, 0x5729, 0xA667, 0x5919, 0xA668, 0x591A,
+	0xA669, 0x5937, 0xA66A, 0x5938, 0xA66B, 0x5984, 0xA66C, 0x5978,
+	0xA66D, 0x5983, 0xA66E, 0x597D, 0xA66F, 0x5979, 0xA670, 0x5982,
+	0xA671, 0x5981, 0xA672, 0x5B57, 0xA673, 0x5B58, 0xA674, 0x5B87,
+	0xA675, 0x5B88, 0xA676, 0x5B85, 0xA677, 0x5B89, 0xA678, 0x5BFA,
+	0xA679, 0x5C16, 0xA67A, 0x5C79, 0xA67B, 0x5DDE, 0xA67C, 0x5E06,
+	0xA67D, 0x5E76, 0xA67E, 0x5E74, 0xA6A1, 0x5F0F, 0xA6A2, 0x5F1B,
+	0xA6A3, 0x5FD9, 0xA6A4, 0x5FD6, 0xA6A5, 0x620E, 0xA6A6, 0x620C,
+	0xA6A7, 0x620D, 0xA6A8, 0x6210, 0xA6A9, 0x6263, 0xA6AA, 0x625B,
+	0xA6AB, 0x6258, 0xA6AC, 0x6536, 0xA6AD, 0x65E9, 0xA6AE, 0x65E8,
+	0xA6AF, 0x65EC, 0xA6B0, 0x65ED, 0xA6B1, 0x66F2, 0xA6B2, 0x66F3,
+	0xA6B3, 0x6709, 0xA6B4, 0x673D, 0xA6B5, 0x6734, 0xA6B6, 0x6731,
+	0xA6B7, 0x6735, 0xA6B8, 0x6B21, 0xA6B9, 0x6B64, 0xA6BA, 0x6B7B,
+	0xA6BB, 0x6C16, 0xA6BC, 0x6C5D, 0xA6BD, 0x6C57, 0xA6BE, 0x6C59,
+	0xA6BF, 0x6C5F, 0xA6C0, 0x6C60, 0xA6C1, 0x6C50, 0xA6C2, 0x6C55,
+	0xA6C3, 0x6C61, 0xA6C4, 0x6C5B, 0xA6C5, 0x6C4D, 0xA6C6, 0x6C4E,
+	0xA6C7, 0x7070, 0xA6C8, 0x725F, 0xA6C9, 0x725D, 0xA6CA, 0x767E,
+	0xA6CB, 0x7AF9, 0xA6CC, 0x7C73, 0xA6CD, 0x7CF8, 0xA6CE, 0x7F36,
+	0xA6CF, 0x7F8A, 0xA6D0, 0x7FBD, 0xA6D1, 0x8001, 0xA6D2, 0x8003,
+	0xA6D3, 0x800C, 0xA6D4, 0x8012, 0xA6D5, 0x8033, 0xA6D6, 0x807F,
+	0xA6D7, 0x8089, 0xA6D8, 0x808B, 0xA6D9, 0x808C, 0xA6DA, 0x81E3,
+	0xA6DB, 0x81EA, 0xA6DC, 0x81F3, 0xA6DD, 0x81FC, 0xA6DE, 0x820C,
+	0xA6DF, 0x821B, 0xA6E0, 0x821F, 0xA6E1, 0x826E, 0xA6E2, 0x8272,
+	0xA6E3, 0x827E, 0xA6E4, 0x866B, 0xA6E5, 0x8840, 0xA6E6, 0x884C,
+	0xA6E7, 0x8863, 0xA6E8, 0x897F, 0xA6E9, 0x9621, 0xA6EA, 0x4E32,
+	0xA6EB, 0x4EA8, 0xA6EC, 0x4F4D, 0xA6ED, 0x4F4F, 0xA6EE, 0x4F47,
+	0xA6EF, 0x4F57, 0xA6F0, 0x4F5E, 0xA6F1, 0x4F34, 0xA6F2, 0x4F5B,
+	0xA6F3, 0x4F55, 0xA6F4, 0x4F30, 0xA6F5, 0x4F50, 0xA6F6, 0x4F51,
+	0xA6F7, 0x4F3D, 0xA6F8, 0x4F3A, 0xA6F9, 0x4F38, 0xA6FA, 0x4F43,
+	0xA6FB, 0x4F54, 0xA6FC, 0x4F3C, 0xA6FD, 0x4F46, 0xA6FE, 0x4F63,
+	0xA740, 0x4F5C, 0xA741, 0x4F60, 0xA742, 0x4F2F, 0xA743, 0x4F4E,
+	0xA744, 0x4F36, 0xA745, 0x4F59, 0xA746, 0x4F5D, 0xA747, 0x4F48,
+	0xA748, 0x4F5A, 0xA749, 0x514C, 0xA74A, 0x514B, 0xA74B, 0x514D,
+	0xA74C, 0x5175, 0xA74D, 0x51B6, 0xA74E, 0x51B7, 0xA74F, 0x5225,
+	0xA750, 0x5224, 0xA751, 0x5229, 0xA752, 0x522A, 0xA753, 0x5228,
+	0xA754, 0x52AB, 0xA755, 0x52A9, 0xA756, 0x52AA, 0xA757, 0x52AC,
+	0xA758, 0x5323, 0xA759, 0x5373, 0xA75A, 0x5375, 0xA75B, 0x541D,
+	0xA75C, 0x542D, 0xA75D, 0x541E, 0xA75E, 0x543E, 0xA75F, 0x5426,
+	0xA760, 0x544E, 0xA761, 0x5427, 0xA762, 0x5446, 0xA763, 0x5443,
+	0xA764, 0x5433, 0xA765, 0x5448, 0xA766, 0x5442, 0xA767, 0x541B,
+	0xA768, 0x5429, 0xA769, 0x544A, 0xA76A, 0x5439, 0xA76B, 0x543B,
+	0xA76C, 0x5438, 0xA76D, 0x542E, 0xA76E, 0x5435, 0xA76F, 0x5436,
+	0xA770, 0x5420, 0xA771, 0x543C, 0xA772, 0x5440, 0xA773, 0x5431,
+	0xA774, 0x542B, 0xA775, 0x541F, 0xA776, 0x542C, 0xA777, 0x56EA,
+	0xA778, 0x56F0, 0xA779, 0x56E4, 0xA77A, 0x56EB, 0xA77B, 0x574A,
+	0xA77C, 0x5751, 0xA77D, 0x5740, 0xA77E, 0x574D, 0xA7A1, 0x5747,
+	0xA7A2, 0x574E, 0xA7A3, 0x573E, 0xA7A4, 0x5750, 0xA7A5, 0x574F,
+	0xA7A6, 0x573B, 0xA7A7, 0x58EF, 0xA7A8, 0x593E, 0xA7A9, 0x599D,
+	0xA7AA, 0x5992, 0xA7AB, 0x59A8, 0xA7AC, 0x599E, 0xA7AD, 0x59A3,
+	0xA7AE, 0x5999, 0xA7AF, 0x5996, 0xA7B0, 0x598D, 0xA7B1, 0x59A4,
+	0xA7B2, 0x5993, 0xA7B3, 0x598A, 0xA7B4, 0x59A5, 0xA7B5, 0x5B5D,
+	0xA7B6, 0x5B5C, 0xA7B7, 0x5B5A, 0xA7B8, 0x5B5B, 0xA7B9, 0x5B8C,
+	0xA7BA, 0x5B8B, 0xA7BB, 0x5B8F, 0xA7BC, 0x5C2C, 0xA7BD, 0x5C40,
+	0xA7BE, 0x5C41, 0xA7BF, 0x5C3F, 0xA7C0, 0x5C3E, 0xA7C1, 0x5C90,
+	0xA7C2, 0x5C91, 0xA7C3, 0x5C94, 0xA7C4, 0x5C8C, 0xA7C5, 0x5DEB,
+	0xA7C6, 0x5E0C, 0xA7C7, 0x5E8F, 0xA7C8, 0x5E87, 0xA7C9, 0x5E8A,
+	0xA7CA, 0x5EF7, 0xA7CB, 0x5F04, 0xA7CC, 0x5F1F, 0xA7CD, 0x5F64,
+	0xA7CE, 0x5F62, 0xA7CF, 0x5F77, 0xA7D0, 0x5F79, 0xA7D1, 0x5FD8,
+	0xA7D2, 0x5FCC, 0xA7D3, 0x5FD7, 0xA7D4, 0x5FCD, 0xA7D5, 0x5FF1,
+	0xA7D6, 0x5FEB, 0xA7D7, 0x5FF8, 0xA7D8, 0x5FEA, 0xA7D9, 0x6212,
+	0xA7DA, 0x6211, 0xA7DB, 0x6284, 0xA7DC, 0x6297, 0xA7DD, 0x6296,
+	0xA7DE, 0x6280, 0xA7DF, 0x6276, 0xA7E0, 0x6289, 0xA7E1, 0x626D,
+	0xA7E2, 0x628A, 0xA7E3, 0x627C, 0xA7E4, 0x627E, 0xA7E5, 0x6279,
+	0xA7E6, 0x6273, 0xA7E7, 0x6292, 0xA7E8, 0x626F, 0xA7E9, 0x6298,
+	0xA7EA, 0x626E, 0xA7EB, 0x6295, 0xA7EC, 0x6293, 0xA7ED, 0x6291,
+	0xA7EE, 0x6286, 0xA7EF, 0x6539, 0xA7F0, 0x653B, 0xA7F1, 0x6538,
+	0xA7F2, 0x65F1, 0xA7F3, 0x66F4, 0xA7F4, 0x675F, 0xA7F5, 0x674E,
+	0xA7F6, 0x674F, 0xA7F7, 0x6750, 0xA7F8, 0x6751, 0xA7F9, 0x675C,
+	0xA7FA, 0x6756, 0xA7FB, 0x675E, 0xA7FC, 0x6749, 0xA7FD, 0x6746,
+	0xA7FE, 0x6760, 0xA840, 0x6753, 0xA841, 0x6757, 0xA842, 0x6B65,
+	0xA843, 0x6BCF, 0xA844, 0x6C42, 0xA845, 0x6C5E, 0xA846, 0x6C99,
+	0xA847, 0x6C81, 0xA848, 0x6C88, 0xA849, 0x6C89, 0xA84A, 0x6C85,
+	0xA84B, 0x6C9B, 0xA84C, 0x6C6A, 0xA84D, 0x6C7A, 0xA84E, 0x6C90,
+	0xA84F, 0x6C70, 0xA850, 0x6C8C, 0xA851, 0x6C68, 0xA852, 0x6C96,
+	0xA853, 0x6C92, 0xA854, 0x6C7D, 0xA855, 0x6C83, 0xA856, 0x6C72,
+	0xA857, 0x6C7E, 0xA858, 0x6C74, 0xA859, 0x6C86, 0xA85A, 0x6C76,
+	0xA85B, 0x6C8D, 0xA85C, 0x6C94, 0xA85D, 0x6C98, 0xA85E, 0x6C82,
+	0xA85F, 0x7076, 0xA860, 0x707C, 0xA861, 0x707D, 0xA862, 0x7078,
+	0xA863, 0x7262, 0xA864, 0x7261, 0xA865, 0x7260, 0xA866, 0x72C4,
+	0xA867, 0x72C2, 0xA868, 0x7396, 0xA869, 0x752C, 0xA86A, 0x752B,
+	0xA86B, 0x7537, 0xA86C, 0x7538, 0xA86D, 0x7682, 0xA86E, 0x76EF,
+	0xA86F, 0x77E3, 0xA870, 0x79C1, 0xA871, 0x79C0, 0xA872, 0x79BF,
+	0xA873, 0x7A76, 0xA874, 0x7CFB, 0xA875, 0x7F55, 0xA876, 0x8096,
+	0xA877, 0x8093, 0xA878, 0x809D, 0xA879, 0x8098, 0xA87A, 0x809B,
+	0xA87B, 0x809A, 0xA87C, 0x80B2, 0xA87D, 0x826F, 0xA87E, 0x8292,
+	0xA8A1, 0x828B, 0xA8A2, 0x828D, 0xA8A3, 0x898B, 0xA8A4, 0x89D2,
+	0xA8A5, 0x8A00, 0xA8A6, 0x8C37, 0xA8A7, 0x8C46, 0xA8A8, 0x8C55,
+	0xA8A9, 0x8C9D, 0xA8AA, 0x8D64, 0xA8AB, 0x8D70, 0xA8AC, 0x8DB3,
+	0xA8AD, 0x8EAB, 0xA8AE, 0x8ECA, 0xA8AF, 0x8F9B, 0xA8B0, 0x8FB0,
+	0xA8B1, 0x8FC2, 0xA8B2, 0x8FC6, 0xA8B3, 0x8FC5, 0xA8B4, 0x8FC4,
+	0xA8B5, 0x5DE1, 0xA8B6, 0x9091, 0xA8B7, 0x90A2, 0xA8B8, 0x90AA,
+	0xA8B9, 0x90A6, 0xA8BA, 0x90A3, 0xA8BB, 0x9149, 0xA8BC, 0x91C6,
+	0xA8BD, 0x91CC, 0xA8BE, 0x9632, 0xA8BF, 0x962E, 0xA8C0, 0x9631,
+	0xA8C1, 0x962A, 0xA8C2, 0x962C, 0xA8C3, 0x4E26, 0xA8C4, 0x4E56,
+	0xA8C5, 0x4E73, 0xA8C6, 0x4E8B, 0xA8C7, 0x4E9B, 0xA8C8, 0x4E9E,
+	0xA8C9, 0x4EAB, 0xA8CA, 0x4EAC, 0xA8CB, 0x4F6F, 0xA8CC, 0x4F9D,
+	0xA8CD, 0x4F8D, 0xA8CE, 0x4F73, 0xA8CF, 0x4F7F, 0xA8D0, 0x4F6C,
+	0xA8D1, 0x4F9B, 0xA8D2, 0x4F8B, 0xA8D3, 0x4F86, 0xA8D4, 0x4F83,
+	0xA8D5, 0x4F70, 0xA8D6, 0x4F75, 0xA8D7, 0x4F88, 0xA8D8, 0x4F69,
+	0xA8D9, 0x4F7B, 0xA8DA, 0x4F96, 0xA8DB, 0x4F7E, 0xA8DC, 0x4F8F,
+	0xA8DD, 0x4F91, 0xA8DE, 0x4F7A, 0xA8DF, 0x5154, 0xA8E0, 0x5152,
+	0xA8E1, 0x5155, 0xA8E2, 0x5169, 0xA8E3, 0x5177, 0xA8E4, 0x5176,
+	0xA8E5, 0x5178, 0xA8E6, 0x51BD, 0xA8E7, 0x51FD, 0xA8E8, 0x523B,
+	0xA8E9, 0x5238, 0xA8EA, 0x5237, 0xA8EB, 0x523A, 0xA8EC, 0x5230,
+	0xA8ED, 0x522E, 0xA8EE, 0x5236, 0xA8EF, 0x5241, 0xA8F0, 0x52BE,
+	0xA8F1, 0x52BB, 0xA8F2, 0x5352, 0xA8F3, 0x5354, 0xA8F4, 0x5353,
+	0xA8F5, 0x5351, 0xA8F6, 0x5366, 0xA8F7, 0x5377, 0xA8F8, 0x5378,
+	0xA8F9, 0x5379, 0xA8FA, 0x53D6, 0xA8FB, 0x53D4, 0xA8FC, 0x53D7,
+	0xA8FD, 0x5473, 0xA8FE, 0x5475, 0xA940, 0x5496, 0xA941, 0x5478,
+	0xA942, 0x5495, 0xA943, 0x5480, 0xA944, 0x547B, 0xA945, 0x5477,
+	0xA946, 0x5484, 0xA947, 0x5492, 0xA948, 0x5486, 0xA949, 0x547C,
+	0xA94A, 0x5490, 0xA94B, 0x5471, 0xA94C, 0x5476, 0xA94D, 0x548C,
+	0xA94E, 0x549A, 0xA94F, 0x5462, 0xA950, 0x5468, 0xA951, 0x548B,
+	0xA952, 0x547D, 0xA953, 0x548E, 0xA954, 0x56FA, 0xA955, 0x5783,
+	0xA956, 0x5777, 0xA957, 0x576A, 0xA958, 0x5769, 0xA959, 0x5761,
+	0xA95A, 0x5766, 0xA95B, 0x5764, 0xA95C, 0x577C, 0xA95D, 0x591C,
+	0xA95E, 0x5949, 0xA95F, 0x5947, 0xA960, 0x5948, 0xA961, 0x5944,
+	0xA962, 0x5954, 0xA963, 0x59BE, 0xA964, 0x59BB, 0xA965, 0x59D4,
+	0xA966, 0x59B9, 0xA967, 0x59AE, 0xA968, 0x59D1, 0xA969, 0x59C6,
+	0xA96A, 0x59D0, 0xA96B, 0x59CD, 0xA96C, 0x59CB, 0xA96D, 0x59D3,
+	0xA96E, 0x59CA, 0xA96F, 0x59AF, 0xA970, 0x59B3, 0xA971, 0x59D2,
+	0xA972, 0x59C5, 0xA973, 0x5B5F, 0xA974, 0x5B64, 0xA975, 0x5B63,
+	0xA976, 0x5B97, 0xA977, 0x5B9A, 0xA978, 0x5B98, 0xA979, 0x5B9C,
+	0xA97A, 0x5B99, 0xA97B, 0x5B9B, 0xA97C, 0x5C1A, 0xA97D, 0x5C48,
+	0xA97E, 0x5C45, 0xA9A1, 0x5C46, 0xA9A2, 0x5CB7, 0xA9A3, 0x5CA1,
+	0xA9A4, 0x5CB8, 0xA9A5, 0x5CA9, 0xA9A6, 0x5CAB, 0xA9A7, 0x5CB1,
+	0xA9A8, 0x5CB3, 0xA9A9, 0x5E18, 0xA9AA, 0x5E1A, 0xA9AB, 0x5E16,
+	0xA9AC, 0x5E15, 0xA9AD, 0x5E1B, 0xA9AE, 0x5E11, 0xA9AF, 0x5E78,
+	0xA9B0, 0x5E9A, 0xA9B1, 0x5E97, 0xA9B2, 0x5E9C, 0xA9B3, 0x5E95,
+	0xA9B4, 0x5E96, 0xA9B5, 0x5EF6, 0xA9B6, 0x5F26, 0xA9B7, 0x5F27,
+	0xA9B8, 0x5F29, 0xA9B9, 0x5F80, 0xA9BA, 0x5F81, 0xA9BB, 0x5F7F,
+	0xA9BC, 0x5F7C, 0xA9BD, 0x5FDD, 0xA9BE, 0x5FE0, 0xA9BF, 0x5FFD,
+	0xA9C0, 0x5FF5, 0xA9C1, 0x5FFF, 0xA9C2, 0x600F, 0xA9C3, 0x6014,
+	0xA9C4, 0x602F, 0xA9C5, 0x6035, 0xA9C6, 0x6016, 0xA9C7, 0x602A,
+	0xA9C8, 0x6015, 0xA9C9, 0x6021, 0xA9CA, 0x6027, 0xA9CB, 0x6029,
+	0xA9CC, 0x602B, 0xA9CD, 0x601B, 0xA9CE, 0x6216, 0xA9CF, 0x6215,
+	0xA9D0, 0x623F, 0xA9D1, 0x623E, 0xA9D2, 0x6240, 0xA9D3, 0x627F,
+	0xA9D4, 0x62C9, 0xA9D5, 0x62CC, 0xA9D6, 0x62C4, 0xA9D7, 0x62BF,
+	0xA9D8, 0x62C2, 0xA9D9, 0x62B9, 0xA9DA, 0x62D2, 0xA9DB, 0x62DB,
+	0xA9DC, 0x62AB, 0xA9DD, 0x62D3, 0xA9DE, 0x62D4, 0xA9DF, 0x62CB,
+	0xA9E0, 0x62C8, 0xA9E1, 0x62A8, 0xA9E2, 0x62BD, 0xA9E3, 0x62BC,
+	0xA9E4, 0x62D0, 0xA9E5, 0x62D9, 0xA9E6, 0x62C7, 0xA9E7, 0x62CD,
+	0xA9E8, 0x62B5, 0xA9E9, 0x62DA, 0xA9EA, 0x62B1, 0xA9EB, 0x62D8,
+	0xA9EC, 0x62D6, 0xA9ED, 0x62D7, 0xA9EE, 0x62C6, 0xA9EF, 0x62AC,
+	0xA9F0, 0x62CE, 0xA9F1, 0x653E, 0xA9F2, 0x65A7, 0xA9F3, 0x65BC,
+	0xA9F4, 0x65FA, 0xA9F5, 0x6614, 0xA9F6, 0x6613, 0xA9F7, 0x660C,
+	0xA9F8, 0x6606, 0xA9F9, 0x6602, 0xA9FA, 0x660E, 0xA9FB, 0x6600,
+	0xA9FC, 0x660F, 0xA9FD, 0x6615, 0xA9FE, 0x660A, 0xAA40, 0x6607,
+	0xAA41, 0x670D, 0xAA42, 0x670B, 0xAA43, 0x676D, 0xAA44, 0x678B,
+	0xAA45, 0x6795, 0xAA46, 0x6771, 0xAA47, 0x679C, 0xAA48, 0x6773,
+	0xAA49, 0x6777, 0xAA4A, 0x6787, 0xAA4B, 0x679D, 0xAA4C, 0x6797,
+	0xAA4D, 0x676F, 0xAA4E, 0x6770, 0xAA4F, 0x677F, 0xAA50, 0x6789,
+	0xAA51, 0x677E, 0xAA52, 0x6790, 0xAA53, 0x6775, 0xAA54, 0x679A,
+	0xAA55, 0x6793, 0xAA56, 0x677C, 0xAA57, 0x676A, 0xAA58, 0x6772,
+	0xAA59, 0x6B23, 0xAA5A, 0x6B66, 0xAA5B, 0x6B67, 0xAA5C, 0x6B7F,
+	0xAA5D, 0x6C13, 0xAA5E, 0x6C1B, 0xAA5F, 0x6CE3, 0xAA60, 0x6CE8,
+	0xAA61, 0x6CF3, 0xAA62, 0x6CB1, 0xAA63, 0x6CCC, 0xAA64, 0x6CE5,
+	0xAA65, 0x6CB3, 0xAA66, 0x6CBD, 0xAA67, 0x6CBE, 0xAA68, 0x6CBC,
+	0xAA69, 0x6CE2, 0xAA6A, 0x6CAB, 0xAA6B, 0x6CD5, 0xAA6C, 0x6CD3,
+	0xAA6D, 0x6CB8, 0xAA6E, 0x6CC4, 0xAA6F, 0x6CB9, 0xAA70, 0x6CC1,
+	0xAA71, 0x6CAE, 0xAA72, 0x6CD7, 0xAA73, 0x6CC5, 0xAA74, 0x6CF1,
+	0xAA75, 0x6CBF, 0xAA76, 0x6CBB, 0xAA77, 0x6CE1, 0xAA78, 0x6CDB,
+	0xAA79, 0x6CCA, 0xAA7A, 0x6CAC, 0xAA7B, 0x6CEF, 0xAA7C, 0x6CDC,
+	0xAA7D, 0x6CD6, 0xAA7E, 0x6CE0, 0xAAA1, 0x7095, 0xAAA2, 0x708E,
+	0xAAA3, 0x7092, 0xAAA4, 0x708A, 0xAAA5, 0x7099, 0xAAA6, 0x722C,
+	0xAAA7, 0x722D, 0xAAA8, 0x7238, 0xAAA9, 0x7248, 0xAAAA, 0x7267,
+	0xAAAB, 0x7269, 0xAAAC, 0x72C0, 0xAAAD, 0x72CE, 0xAAAE, 0x72D9,
+	0xAAAF, 0x72D7, 0xAAB0, 0x72D0, 0xAAB1, 0x73A9, 0xAAB2, 0x73A8,
+	0xAAB3, 0x739F, 0xAAB4, 0x73AB, 0xAAB5, 0x73A5, 0xAAB6, 0x753D,
+	0xAAB7, 0x759D, 0xAAB8, 0x7599, 0xAAB9, 0x759A, 0xAABA, 0x7684,
+	0xAABB, 0x76C2, 0xAABC, 0x76F2, 0xAABD, 0x76F4, 0xAABE, 0x77E5,
+	0xAABF, 0x77FD, 0xAAC0, 0x793E, 0xAAC1, 0x7940, 0xAAC2, 0x7941,
+	0xAAC3, 0x79C9, 0xAAC4, 0x79C8, 0xAAC5, 0x7A7A, 0xAAC6, 0x7A79,
+	0xAAC7, 0x7AFA, 0xAAC8, 0x7CFE, 0xAAC9, 0x7F54, 0xAACA, 0x7F8C,
+	0xAACB, 0x7F8B, 0xAACC, 0x8005, 0xAACD, 0x80BA, 0xAACE, 0x80A5,
+	0xAACF, 0x80A2, 0xAAD0, 0x80B1, 0xAAD1, 0x80A1, 0xAAD2, 0x80AB,
+	0xAAD3, 0x80A9, 0xAAD4, 0x80B4, 0xAAD5, 0x80AA, 0xAAD6, 0x80AF,
+	0xAAD7, 0x81E5, 0xAAD8, 0x81FE, 0xAAD9, 0x820D, 0xAADA, 0x82B3,
+	0xAADB, 0x829D, 0xAADC, 0x8299, 0xAADD, 0x82AD, 0xAADE, 0x82BD,
+	0xAADF, 0x829F, 0xAAE0, 0x82B9, 0xAAE1, 0x82B1, 0xAAE2, 0x82AC,
+	0xAAE3, 0x82A5, 0xAAE4, 0x82AF, 0xAAE5, 0x82B8, 0xAAE6, 0x82A3,
+	0xAAE7, 0x82B0, 0xAAE8, 0x82BE, 0xAAE9, 0x82B7, 0xAAEA, 0x864E,
+	0xAAEB, 0x8671, 0xAAEC, 0x521D, 0xAAED, 0x8868, 0xAAEE, 0x8ECB,
+	0xAAEF, 0x8FCE, 0xAAF0, 0x8FD4, 0xAAF1, 0x8FD1, 0xAAF2, 0x90B5,
+	0xAAF3, 0x90B8, 0xAAF4, 0x90B1, 0xAAF5, 0x90B6, 0xAAF6, 0x91C7,
+	0xAAF7, 0x91D1, 0xAAF8, 0x9577, 0xAAF9, 0x9580, 0xAAFA, 0x961C,
+	0xAAFB, 0x9640, 0xAAFC, 0x963F, 0xAAFD, 0x963B, 0xAAFE, 0x9644,
+	0xAB40, 0x9642, 0xAB41, 0x96B9, 0xAB42, 0x96E8, 0xAB43, 0x9752,
+	0xAB44, 0x975E, 0xAB45, 0x4E9F, 0xAB46, 0x4EAD, 0xAB47, 0x4EAE,
+	0xAB48, 0x4FE1, 0xAB49, 0x4FB5, 0xAB4A, 0x4FAF, 0xAB4B, 0x4FBF,
+	0xAB4C, 0x4FE0, 0xAB4D, 0x4FD1, 0xAB4E, 0x4FCF, 0xAB4F, 0x4FDD,
+	0xAB50, 0x4FC3, 0xAB51, 0x4FB6, 0xAB52, 0x4FD8, 0xAB53, 0x4FDF,
+	0xAB54, 0x4FCA, 0xAB55, 0x4FD7, 0xAB56, 0x4FAE, 0xAB57, 0x4FD0,
+	0xAB58, 0x4FC4, 0xAB59, 0x4FC2, 0xAB5A, 0x4FDA, 0xAB5B, 0x4FCE,
+	0xAB5C, 0x4FDE, 0xAB5D, 0x4FB7, 0xAB5E, 0x5157, 0xAB5F, 0x5192,
+	0xAB60, 0x5191, 0xAB61, 0x51A0, 0xAB62, 0x524E, 0xAB63, 0x5243,
+	0xAB64, 0x524A, 0xAB65, 0x524D, 0xAB66, 0x524C, 0xAB67, 0x524B,
+	0xAB68, 0x5247, 0xAB69, 0x52C7, 0xAB6A, 0x52C9, 0xAB6B, 0x52C3,
+	0xAB6C, 0x52C1, 0xAB6D, 0x530D, 0xAB6E, 0x5357, 0xAB6F, 0x537B,
+	0xAB70, 0x539A, 0xAB71, 0x53DB, 0xAB72, 0x54AC, 0xAB73, 0x54C0,
+	0xAB74, 0x54A8, 0xAB75, 0x54CE, 0xAB76, 0x54C9, 0xAB77, 0x54B8,
+	0xAB78, 0x54A6, 0xAB79, 0x54B3, 0xAB7A, 0x54C7, 0xAB7B, 0x54C2,
+	0xAB7C, 0x54BD, 0xAB7D, 0x54AA, 0xAB7E, 0x54C1, 0xABA1, 0x54C4,
+	0xABA2, 0x54C8, 0xABA3, 0x54AF, 0xABA4, 0x54AB, 0xABA5, 0x54B1,
+	0xABA6, 0x54BB, 0xABA7, 0x54A9, 0xABA8, 0x54A7, 0xABA9, 0x54BF,
+	0xABAA, 0x56FF, 0xABAB, 0x5782, 0xABAC, 0x578B, 0xABAD, 0x57A0,
+	0xABAE, 0x57A3, 0xABAF, 0x57A2, 0xABB0, 0x57CE, 0xABB1, 0x57AE,
+	0xABB2, 0x5793, 0xABB3, 0x5955, 0xABB4, 0x5951, 0xABB5, 0x594F,
+	0xABB6, 0x594E, 0xABB7, 0x5950, 0xABB8, 0x59DC, 0xABB9, 0x59D8,
+	0xABBA, 0x59FF, 0xABBB, 0x59E3, 0xABBC, 0x59E8, 0xABBD, 0x5A03,
+	0xABBE, 0x59E5, 0xABBF, 0x59EA, 0xABC0, 0x59DA, 0xABC1, 0x59E6,
+	0xABC2, 0x5A01, 0xABC3, 0x59FB, 0xABC4, 0x5B69, 0xABC5, 0x5BA3,
+	0xABC6, 0x5BA6, 0xABC7, 0x5BA4, 0xABC8, 0x5BA2, 0xABC9, 0x5BA5,
+	0xABCA, 0x5C01, 0xABCB, 0x5C4E, 0xABCC, 0x5C4F, 0xABCD, 0x5C4D,
+	0xABCE, 0x5C4B, 0xABCF, 0x5CD9, 0xABD0, 0x5CD2, 0xABD1, 0x5DF7,
+	0xABD2, 0x5E1D, 0xABD3, 0x5E25, 0xABD4, 0x5E1F, 0xABD5, 0x5E7D,
+	0xABD6, 0x5EA0, 0xABD7, 0x5EA6, 0xABD8, 0x5EFA, 0xABD9, 0x5F08,
+	0xABDA, 0x5F2D, 0xABDB, 0x5F65, 0xABDC, 0x5F88, 0xABDD, 0x5F85,
+	0xABDE, 0x5F8A, 0xABDF, 0x5F8B, 0xABE0, 0x5F87, 0xABE1, 0x5F8C,
+	0xABE2, 0x5F89, 0xABE3, 0x6012, 0xABE4, 0x601D, 0xABE5, 0x6020,
+	0xABE6, 0x6025, 0xABE7, 0x600E, 0xABE8, 0x6028, 0xABE9, 0x604D,
+	0xABEA, 0x6070, 0xABEB, 0x6068, 0xABEC, 0x6062, 0xABED, 0x6046,
+	0xABEE, 0x6043, 0xABEF, 0x606C, 0xABF0, 0x606B, 0xABF1, 0x606A,
+	0xABF2, 0x6064, 0xABF3, 0x6241, 0xABF4, 0x62DC, 0xABF5, 0x6316,
+	0xABF6, 0x6309, 0xABF7, 0x62FC, 0xABF8, 0x62ED, 0xABF9, 0x6301,
+	0xABFA, 0x62EE, 0xABFB, 0x62FD, 0xABFC, 0x6307, 0xABFD, 0x62F1,
+	0xABFE, 0x62F7, 0xAC40, 0x62EF, 0xAC41, 0x62EC, 0xAC42, 0x62FE,
+	0xAC43, 0x62F4, 0xAC44, 0x6311, 0xAC45, 0x6302, 0xAC46, 0x653F,
+	0xAC47, 0x6545, 0xAC48, 0x65AB, 0xAC49, 0x65BD, 0xAC4A, 0x65E2,
+	0xAC4B, 0x6625, 0xAC4C, 0x662D, 0xAC4D, 0x6620, 0xAC4E, 0x6627,
+	0xAC4F, 0x662F, 0xAC50, 0x661F, 0xAC51, 0x6628, 0xAC52, 0x6631,
+	0xAC53, 0x6624, 0xAC54, 0x66F7, 0xAC55, 0x67FF, 0xAC56, 0x67D3,
+	0xAC57, 0x67F1, 0xAC58, 0x67D4, 0xAC59, 0x67D0, 0xAC5A, 0x67EC,
+	0xAC5B, 0x67B6, 0xAC5C, 0x67AF, 0xAC5D, 0x67F5, 0xAC5E, 0x67E9,
+	0xAC5F, 0x67EF, 0xAC60, 0x67C4, 0xAC61, 0x67D1, 0xAC62, 0x67B4,
+	0xAC63, 0x67DA, 0xAC64, 0x67E5, 0xAC65, 0x67B8, 0xAC66, 0x67CF,
+	0xAC67, 0x67DE, 0xAC68, 0x67F3, 0xAC69, 0x67B0, 0xAC6A, 0x67D9,
+	0xAC6B, 0x67E2, 0xAC6C, 0x67DD, 0xAC6D, 0x67D2, 0xAC6E, 0x6B6A,
+	0xAC6F, 0x6B83, 0xAC70, 0x6B86, 0xAC71, 0x6BB5, 0xAC72, 0x6BD2,
+	0xAC73, 0x6BD7, 0xAC74, 0x6C1F, 0xAC75, 0x6CC9, 0xAC76, 0x6D0B,
+	0xAC77, 0x6D32, 0xAC78, 0x6D2A, 0xAC79, 0x6D41, 0xAC7A, 0x6D25,
+	0xAC7B, 0x6D0C, 0xAC7C, 0x6D31, 0xAC7D, 0x6D1E, 0xAC7E, 0x6D17,
+	0xACA1, 0x6D3B, 0xACA2, 0x6D3D, 0xACA3, 0x6D3E, 0xACA4, 0x6D36,
+	0xACA5, 0x6D1B, 0xACA6, 0x6CF5, 0xACA7, 0x6D39, 0xACA8, 0x6D27,
+	0xACA9, 0x6D38, 0xACAA, 0x6D29, 0xACAB, 0x6D2E, 0xACAC, 0x6D35,
+	0xACAD, 0x6D0E, 0xACAE, 0x6D2B, 0xACAF, 0x70AB, 0xACB0, 0x70BA,
+	0xACB1, 0x70B3, 0xACB2, 0x70AC, 0xACB3, 0x70AF, 0xACB4, 0x70AD,
+	0xACB5, 0x70B8, 0xACB6, 0x70AE, 0xACB7, 0x70A4, 0xACB8, 0x7230,
+	0xACB9, 0x7272, 0xACBA, 0x726F, 0xACBB, 0x7274, 0xACBC, 0x72E9,
+	0xACBD, 0x72E0, 0xACBE, 0x72E1, 0xACBF, 0x73B7, 0xACC0, 0x73CA,
+	0xACC1, 0x73BB, 0xACC2, 0x73B2, 0xACC3, 0x73CD, 0xACC4, 0x73C0,
+	0xACC5, 0x73B3, 0xACC6, 0x751A, 0xACC7, 0x752D, 0xACC8, 0x754F,
+	0xACC9, 0x754C, 0xACCA, 0x754E, 0xACCB, 0x754B, 0xACCC, 0x75AB,
+	0xACCD, 0x75A4, 0xACCE, 0x75A5, 0xACCF, 0x75A2, 0xACD0, 0x75A3,
+	0xACD1, 0x7678, 0xACD2, 0x7686, 0xACD3, 0x7687, 0xACD4, 0x7688,
+	0xACD5, 0x76C8, 0xACD6, 0x76C6, 0xACD7, 0x76C3, 0xACD8, 0x76C5,
+	0xACD9, 0x7701, 0xACDA, 0x76F9, 0xACDB, 0x76F8, 0xACDC, 0x7709,
+	0xACDD, 0x770B, 0xACDE, 0x76FE, 0xACDF, 0x76FC, 0xACE0, 0x7707,
+	0xACE1, 0x77DC, 0xACE2, 0x7802, 0xACE3, 0x7814, 0xACE4, 0x780C,
+	0xACE5, 0x780D, 0xACE6, 0x7946, 0xACE7, 0x7949, 0xACE8, 0x7948,
+	0xACE9, 0x7947, 0xACEA, 0x79B9, 0xACEB, 0x79BA, 0xACEC, 0x79D1,
+	0xACED, 0x79D2, 0xACEE, 0x79CB, 0xACEF, 0x7A7F, 0xACF0, 0x7A81,
+	0xACF1, 0x7AFF, 0xACF2, 0x7AFD, 0xACF3, 0x7C7D, 0xACF4, 0x7D02,
+	0xACF5, 0x7D05, 0xACF6, 0x7D00, 0xACF7, 0x7D09, 0xACF8, 0x7D07,
+	0xACF9, 0x7D04, 0xACFA, 0x7D06, 0xACFB, 0x7F38, 0xACFC, 0x7F8E,
+	0xACFD, 0x7FBF, 0xACFE, 0x8004, 0xAD40, 0x8010, 0xAD41, 0x800D,
+	0xAD42, 0x8011, 0xAD43, 0x8036, 0xAD44, 0x80D6, 0xAD45, 0x80E5,
+	0xAD46, 0x80DA, 0xAD47, 0x80C3, 0xAD48, 0x80C4, 0xAD49, 0x80CC,
+	0xAD4A, 0x80E1, 0xAD4B, 0x80DB, 0xAD4C, 0x80CE, 0xAD4D, 0x80DE,
+	0xAD4E, 0x80E4, 0xAD4F, 0x80DD, 0xAD50, 0x81F4, 0xAD51, 0x8222,
+	0xAD52, 0x82E7, 0xAD53, 0x8303, 0xAD54, 0x8305, 0xAD55, 0x82E3,
+	0xAD56, 0x82DB, 0xAD57, 0x82E6, 0xAD58, 0x8304, 0xAD59, 0x82E5,
+	0xAD5A, 0x8302, 0xAD5B, 0x8309, 0xAD5C, 0x82D2, 0xAD5D, 0x82D7,
+	0xAD5E, 0x82F1, 0xAD5F, 0x8301, 0xAD60, 0x82DC, 0xAD61, 0x82D4,
+	0xAD62, 0x82D1, 0xAD63, 0x82DE, 0xAD64, 0x82D3, 0xAD65, 0x82DF,
+	0xAD66, 0x82EF, 0xAD67, 0x8306, 0xAD68, 0x8650, 0xAD69, 0x8679,
+	0xAD6A, 0x867B, 0xAD6B, 0x867A, 0xAD6C, 0x884D, 0xAD6D, 0x886B,
+	0xAD6E, 0x8981, 0xAD6F, 0x89D4, 0xAD70, 0x8A08, 0xAD71, 0x8A02,
+	0xAD72, 0x8A03, 0xAD73, 0x8C9E, 0xAD74, 0x8CA0, 0xAD75, 0x8D74,
+	0xAD76, 0x8D73, 0xAD77, 0x8DB4, 0xAD78, 0x8ECD, 0xAD79, 0x8ECC,
+	0xAD7A, 0x8FF0, 0xAD7B, 0x8FE6, 0xAD7C, 0x8FE2, 0xAD7D, 0x8FEA,
+	0xAD7E, 0x8FE5, 0xADA1, 0x8FED, 0xADA2, 0x8FEB, 0xADA3, 0x8FE4,
+	0xADA4, 0x8FE8, 0xADA5, 0x90CA, 0xADA6, 0x90CE, 0xADA7, 0x90C1,
+	0xADA8, 0x90C3, 0xADA9, 0x914B, 0xADAA, 0x914A, 0xADAB, 0x91CD,
+	0xADAC, 0x9582, 0xADAD, 0x9650, 0xADAE, 0x964B, 0xADAF, 0x964C,
+	0xADB0, 0x964D, 0xADB1, 0x9762, 0xADB2, 0x9769, 0xADB3, 0x97CB,
+	0xADB4, 0x97ED, 0xADB5, 0x97F3, 0xADB6, 0x9801, 0xADB7, 0x98A8,
+	0xADB8, 0x98DB, 0xADB9, 0x98DF, 0xADBA, 0x9996, 0xADBB, 0x9999,
+	0xADBC, 0x4E58, 0xADBD, 0x4EB3, 0xADBE, 0x500C, 0xADBF, 0x500D,
+	0xADC0, 0x5023, 0xADC1, 0x4FEF, 0xADC2, 0x5026, 0xADC3, 0x5025,
+	0xADC4, 0x4FF8, 0xADC5, 0x5029, 0xADC6, 0x5016, 0xADC7, 0x5006,
+	0xADC8, 0x503C, 0xADC9, 0x501F, 0xADCA, 0x501A, 0xADCB, 0x5012,
+	0xADCC, 0x5011, 0xADCD, 0x4FFA, 0xADCE, 0x5000, 0xADCF, 0x5014,
+	0xADD0, 0x5028, 0xADD1, 0x4FF1, 0xADD2, 0x5021, 0xADD3, 0x500B,
+	0xADD4, 0x5019, 0xADD5, 0x5018, 0xADD6, 0x4FF3, 0xADD7, 0x4FEE,
+	0xADD8, 0x502D, 0xADD9, 0x502A, 0xADDA, 0x4FFE, 0xADDB, 0x502B,
+	0xADDC, 0x5009, 0xADDD, 0x517C, 0xADDE, 0x51A4, 0xADDF, 0x51A5,
+	0xADE0, 0x51A2, 0xADE1, 0x51CD, 0xADE2, 0x51CC, 0xADE3, 0x51C6,
+	0xADE4, 0x51CB, 0xADE5, 0x5256, 0xADE6, 0x525C, 0xADE7, 0x5254,
+	0xADE8, 0x525B, 0xADE9, 0x525D, 0xADEA, 0x532A, 0xADEB, 0x537F,
+	0xADEC, 0x539F, 0xADED, 0x539D, 0xADEE, 0x53DF, 0xADEF, 0x54E8,
+	0xADF0, 0x5510, 0xADF1, 0x5501, 0xADF2, 0x5537, 0xADF3, 0x54FC,
+	0xADF4, 0x54E5, 0xADF5, 0x54F2, 0xADF6, 0x5506, 0xADF7, 0x54FA,
+	0xADF8, 0x5514, 0xADF9, 0x54E9, 0xADFA, 0x54ED, 0xADFB, 0x54E1,
+	0xADFC, 0x5509, 0xADFD, 0x54EE, 0xADFE, 0x54EA, 0xAE40, 0x54E6,
+	0xAE41, 0x5527, 0xAE42, 0x5507, 0xAE43, 0x54FD, 0xAE44, 0x550F,
+	0xAE45, 0x5703, 0xAE46, 0x5704, 0xAE47, 0x57C2, 0xAE48, 0x57D4,
+	0xAE49, 0x57CB, 0xAE4A, 0x57C3, 0xAE4B, 0x5809, 0xAE4C, 0x590F,
+	0xAE4D, 0x5957, 0xAE4E, 0x5958, 0xAE4F, 0x595A, 0xAE50, 0x5A11,
+	0xAE51, 0x5A18, 0xAE52, 0x5A1C, 0xAE53, 0x5A1F, 0xAE54, 0x5A1B,
+	0xAE55, 0x5A13, 0xAE56, 0x59EC, 0xAE57, 0x5A20, 0xAE58, 0x5A23,
+	0xAE59, 0x5A29, 0xAE5A, 0x5A25, 0xAE5B, 0x5A0C, 0xAE5C, 0x5A09,
+	0xAE5D, 0x5B6B, 0xAE5E, 0x5C58, 0xAE5F, 0x5BB0, 0xAE60, 0x5BB3,
+	0xAE61, 0x5BB6, 0xAE62, 0x5BB4, 0xAE63, 0x5BAE, 0xAE64, 0x5BB5,
+	0xAE65, 0x5BB9, 0xAE66, 0x5BB8, 0xAE67, 0x5C04, 0xAE68, 0x5C51,
+	0xAE69, 0x5C55, 0xAE6A, 0x5C50, 0xAE6B, 0x5CED, 0xAE6C, 0x5CFD,
+	0xAE6D, 0x5CFB, 0xAE6E, 0x5CEA, 0xAE6F, 0x5CE8, 0xAE70, 0x5CF0,
+	0xAE71, 0x5CF6, 0xAE72, 0x5D01, 0xAE73, 0x5CF4, 0xAE74, 0x5DEE,
+	0xAE75, 0x5E2D, 0xAE76, 0x5E2B, 0xAE77, 0x5EAB, 0xAE78, 0x5EAD,
+	0xAE79, 0x5EA7, 0xAE7A, 0x5F31, 0xAE7B, 0x5F92, 0xAE7C, 0x5F91,
+	0xAE7D, 0x5F90, 0xAE7E, 0x6059, 0xAEA1, 0x6063, 0xAEA2, 0x6065,
+	0xAEA3, 0x6050, 0xAEA4, 0x6055, 0xAEA5, 0x606D, 0xAEA6, 0x6069,
+	0xAEA7, 0x606F, 0xAEA8, 0x6084, 0xAEA9, 0x609F, 0xAEAA, 0x609A,
+	0xAEAB, 0x608D, 0xAEAC, 0x6094, 0xAEAD, 0x608C, 0xAEAE, 0x6085,
+	0xAEAF, 0x6096, 0xAEB0, 0x6247, 0xAEB1, 0x62F3, 0xAEB2, 0x6308,
+	0xAEB3, 0x62FF, 0xAEB4, 0x634E, 0xAEB5, 0x633E, 0xAEB6, 0x632F,
+	0xAEB7, 0x6355, 0xAEB8, 0x6342, 0xAEB9, 0x6346, 0xAEBA, 0x634F,
+	0xAEBB, 0x6349, 0xAEBC, 0x633A, 0xAEBD, 0x6350, 0xAEBE, 0x633D,
+	0xAEBF, 0x632A, 0xAEC0, 0x632B, 0xAEC1, 0x6328, 0xAEC2, 0x634D,
+	0xAEC3, 0x634C, 0xAEC4, 0x6548, 0xAEC5, 0x6549, 0xAEC6, 0x6599,
+	0xAEC7, 0x65C1, 0xAEC8, 0x65C5, 0xAEC9, 0x6642, 0xAECA, 0x6649,
+	0xAECB, 0x664F, 0xAECC, 0x6643, 0xAECD, 0x6652, 0xAECE, 0x664C,
+	0xAECF, 0x6645, 0xAED0, 0x6641, 0xAED1, 0x66F8, 0xAED2, 0x6714,
+	0xAED3, 0x6715, 0xAED4, 0x6717, 0xAED5, 0x6821, 0xAED6, 0x6838,
+	0xAED7, 0x6848, 0xAED8, 0x6846, 0xAED9, 0x6853, 0xAEDA, 0x6839,
+	0xAEDB, 0x6842, 0xAEDC, 0x6854, 0xAEDD, 0x6829, 0xAEDE, 0x68B3,
+	0xAEDF, 0x6817, 0xAEE0, 0x684C, 0xAEE1, 0x6851, 0xAEE2, 0x683D,
+	0xAEE3, 0x67F4, 0xAEE4, 0x6850, 0xAEE5, 0x6840, 0xAEE6, 0x683C,
+	0xAEE7, 0x6843, 0xAEE8, 0x682A, 0xAEE9, 0x6845, 0xAEEA, 0x6813,
+	0xAEEB, 0x6818, 0xAEEC, 0x6841, 0xAEED, 0x6B8A, 0xAEEE, 0x6B89,
+	0xAEEF, 0x6BB7, 0xAEF0, 0x6C23, 0xAEF1, 0x6C27, 0xAEF2, 0x6C28,
+	0xAEF3, 0x6C26, 0xAEF4, 0x6C24, 0xAEF5, 0x6CF0, 0xAEF6, 0x6D6A,
+	0xAEF7, 0x6D95, 0xAEF8, 0x6D88, 0xAEF9, 0x6D87, 0xAEFA, 0x6D66,
+	0xAEFB, 0x6D78, 0xAEFC, 0x6D77, 0xAEFD, 0x6D59, 0xAEFE, 0x6D93,
+	0xAF40, 0x6D6C, 0xAF41, 0x6D89, 0xAF42, 0x6D6E, 0xAF43, 0x6D5A,
+	0xAF44, 0x6D74, 0xAF45, 0x6D69, 0xAF46, 0x6D8C, 0xAF47, 0x6D8A,
+	0xAF48, 0x6D79, 0xAF49, 0x6D85, 0xAF4A, 0x6D65, 0xAF4B, 0x6D94,
+	0xAF4C, 0x70CA, 0xAF4D, 0x70D8, 0xAF4E, 0x70E4, 0xAF4F, 0x70D9,
+	0xAF50, 0x70C8, 0xAF51, 0x70CF, 0xAF52, 0x7239, 0xAF53, 0x7279,
+	0xAF54, 0x72FC, 0xAF55, 0x72F9, 0xAF56, 0x72FD, 0xAF57, 0x72F8,
+	0xAF58, 0x72F7, 0xAF59, 0x7386, 0xAF5A, 0x73ED, 0xAF5B, 0x7409,
+	0xAF5C, 0x73EE, 0xAF5D, 0x73E0, 0xAF5E, 0x73EA, 0xAF5F, 0x73DE,
+	0xAF60, 0x7554, 0xAF61, 0x755D, 0xAF62, 0x755C, 0xAF63, 0x755A,
+	0xAF64, 0x7559, 0xAF65, 0x75BE, 0xAF66, 0x75C5, 0xAF67, 0x75C7,
+	0xAF68, 0x75B2, 0xAF69, 0x75B3, 0xAF6A, 0x75BD, 0xAF6B, 0x75BC,
+	0xAF6C, 0x75B9, 0xAF6D, 0x75C2, 0xAF6E, 0x75B8, 0xAF6F, 0x768B,
+	0xAF70, 0x76B0, 0xAF71, 0x76CA, 0xAF72, 0x76CD, 0xAF73, 0x76CE,
+	0xAF74, 0x7729, 0xAF75, 0x771F, 0xAF76, 0x7720, 0xAF77, 0x7728,
+	0xAF78, 0x77E9, 0xAF79, 0x7830, 0xAF7A, 0x7827, 0xAF7B, 0x7838,
+	0xAF7C, 0x781D, 0xAF7D, 0x7834, 0xAF7E, 0x7837, 0xAFA1, 0x7825,
+	0xAFA2, 0x782D, 0xAFA3, 0x7820, 0xAFA4, 0x781F, 0xAFA5, 0x7832,
+	0xAFA6, 0x7955, 0xAFA7, 0x7950, 0xAFA8, 0x7960, 0xAFA9, 0x795F,
+	0xAFAA, 0x7956, 0xAFAB, 0x795E, 0xAFAC, 0x795D, 0xAFAD, 0x7957,
+	0xAFAE, 0x795A, 0xAFAF, 0x79E4, 0xAFB0, 0x79E3, 0xAFB1, 0x79E7,
+	0xAFB2, 0x79DF, 0xAFB3, 0x79E6, 0xAFB4, 0x79E9, 0xAFB5, 0x79D8,
+	0xAFB6, 0x7A84, 0xAFB7, 0x7A88, 0xAFB8, 0x7AD9, 0xAFB9, 0x7B06,
+	0xAFBA, 0x7B11, 0xAFBB, 0x7C89, 0xAFBC, 0x7D21, 0xAFBD, 0x7D17,
+	0xAFBE, 0x7D0B, 0xAFBF, 0x7D0A, 0xAFC0, 0x7D20, 0xAFC1, 0x7D22,
+	0xAFC2, 0x7D14, 0xAFC3, 0x7D10, 0xAFC4, 0x7D15, 0xAFC5, 0x7D1A,
+	0xAFC6, 0x7D1C, 0xAFC7, 0x7D0D, 0xAFC8, 0x7D19, 0xAFC9, 0x7D1B,
+	0xAFCA, 0x7F3A, 0xAFCB, 0x7F5F, 0xAFCC, 0x7F94, 0xAFCD, 0x7FC5,
+	0xAFCE, 0x7FC1, 0xAFCF, 0x8006, 0xAFD0, 0x8018, 0xAFD1, 0x8015,
+	0xAFD2, 0x8019, 0xAFD3, 0x8017, 0xAFD4, 0x803D, 0xAFD5, 0x803F,
+	0xAFD6, 0x80F1, 0xAFD7, 0x8102, 0xAFD8, 0x80F0, 0xAFD9, 0x8105,
+	0xAFDA, 0x80ED, 0xAFDB, 0x80F4, 0xAFDC, 0x8106, 0xAFDD, 0x80F8,
+	0xAFDE, 0x80F3, 0xAFDF, 0x8108, 0xAFE0, 0x80FD, 0xAFE1, 0x810A,
+	0xAFE2, 0x80FC, 0xAFE3, 0x80EF, 0xAFE4, 0x81ED, 0xAFE5, 0x81EC,
+	0xAFE6, 0x8200, 0xAFE7, 0x8210, 0xAFE8, 0x822A, 0xAFE9, 0x822B,
+	0xAFEA, 0x8228, 0xAFEB, 0x822C, 0xAFEC, 0x82BB, 0xAFED, 0x832B,
+	0xAFEE, 0x8352, 0xAFEF, 0x8354, 0xAFF0, 0x834A, 0xAFF1, 0x8338,
+	0xAFF2, 0x8350, 0xAFF3, 0x8349, 0xAFF4, 0x8335, 0xAFF5, 0x8334,
+	0xAFF6, 0x834F, 0xAFF7, 0x8332, 0xAFF8, 0x8339, 0xAFF9, 0x8336,
+	0xAFFA, 0x8317, 0xAFFB, 0x8340, 0xAFFC, 0x8331, 0xAFFD, 0x8328,
+	0xAFFE, 0x8343, 0xB040, 0x8654, 0xB041, 0x868A, 0xB042, 0x86AA,
+	0xB043, 0x8693, 0xB044, 0x86A4, 0xB045, 0x86A9, 0xB046, 0x868C,
+	0xB047, 0x86A3, 0xB048, 0x869C, 0xB049, 0x8870, 0xB04A, 0x8877,
+	0xB04B, 0x8881, 0xB04C, 0x8882, 0xB04D, 0x887D, 0xB04E, 0x8879,
+	0xB04F, 0x8A18, 0xB050, 0x8A10, 0xB051, 0x8A0E, 0xB052, 0x8A0C,
+	0xB053, 0x8A15, 0xB054, 0x8A0A, 0xB055, 0x8A17, 0xB056, 0x8A13,
+	0xB057, 0x8A16, 0xB058, 0x8A0F, 0xB059, 0x8A11, 0xB05A, 0x8C48,
+	0xB05B, 0x8C7A, 0xB05C, 0x8C79, 0xB05D, 0x8CA1, 0xB05E, 0x8CA2,
+	0xB05F, 0x8D77, 0xB060, 0x8EAC, 0xB061, 0x8ED2, 0xB062, 0x8ED4,
+	0xB063, 0x8ECF, 0xB064, 0x8FB1, 0xB065, 0x9001, 0xB066, 0x9006,
+	0xB067, 0x8FF7, 0xB068, 0x9000, 0xB069, 0x8FFA, 0xB06A, 0x8FF4,
+	0xB06B, 0x9003, 0xB06C, 0x8FFD, 0xB06D, 0x9005, 0xB06E, 0x8FF8,
+	0xB06F, 0x9095, 0xB070, 0x90E1, 0xB071, 0x90DD, 0xB072, 0x90E2,
+	0xB073, 0x9152, 0xB074, 0x914D, 0xB075, 0x914C, 0xB076, 0x91D8,
+	0xB077, 0x91DD, 0xB078, 0x91D7, 0xB079, 0x91DC, 0xB07A, 0x91D9,
+	0xB07B, 0x9583, 0xB07C, 0x9662, 0xB07D, 0x9663, 0xB07E, 0x9661,
+	0xB0A1, 0x965B, 0xB0A2, 0x965D, 0xB0A3, 0x9664, 0xB0A4, 0x9658,
+	0xB0A5, 0x965E, 0xB0A6, 0x96BB, 0xB0A7, 0x98E2, 0xB0A8, 0x99AC,
+	0xB0A9, 0x9AA8, 0xB0AA, 0x9AD8, 0xB0AB, 0x9B25, 0xB0AC, 0x9B32,
+	0xB0AD, 0x9B3C, 0xB0AE, 0x4E7E, 0xB0AF, 0x507A, 0xB0B0, 0x507D,
+	0xB0B1, 0x505C, 0xB0B2, 0x5047, 0xB0B3, 0x5043, 0xB0B4, 0x504C,
+	0xB0B5, 0x505A, 0xB0B6, 0x5049, 0xB0B7, 0x5065, 0xB0B8, 0x5076,
+	0xB0B9, 0x504E, 0xB0BA, 0x5055, 0xB0BB, 0x5075, 0xB0BC, 0x5074,
+	0xB0BD, 0x5077, 0xB0BE, 0x504F, 0xB0BF, 0x500F, 0xB0C0, 0x506F,
+	0xB0C1, 0x506D, 0xB0C2, 0x515C, 0xB0C3, 0x5195, 0xB0C4, 0x51F0,
+	0xB0C5, 0x526A, 0xB0C6, 0x526F, 0xB0C7, 0x52D2, 0xB0C8, 0x52D9,
+	0xB0C9, 0x52D8, 0xB0CA, 0x52D5, 0xB0CB, 0x5310, 0xB0CC, 0x530F,
+	0xB0CD, 0x5319, 0xB0CE, 0x533F, 0xB0CF, 0x5340, 0xB0D0, 0x533E,
+	0xB0D1, 0x53C3, 0xB0D2, 0x66FC, 0xB0D3, 0x5546, 0xB0D4, 0x556A,
+	0xB0D5, 0x5566, 0xB0D6, 0x5544, 0xB0D7, 0x555E, 0xB0D8, 0x5561,
+	0xB0D9, 0x5543, 0xB0DA, 0x554A, 0xB0DB, 0x5531, 0xB0DC, 0x5556,
+	0xB0DD, 0x554F, 0xB0DE, 0x5555, 0xB0DF, 0x552F, 0xB0E0, 0x5564,
+	0xB0E1, 0x5538, 0xB0E2, 0x552E, 0xB0E3, 0x555C, 0xB0E4, 0x552C,
+	0xB0E5, 0x5563, 0xB0E6, 0x5533, 0xB0E7, 0x5541, 0xB0E8, 0x5557,
+	0xB0E9, 0x5708, 0xB0EA, 0x570B, 0xB0EB, 0x5709, 0xB0EC, 0x57DF,
+	0xB0ED, 0x5805, 0xB0EE, 0x580A, 0xB0EF, 0x5806, 0xB0F0, 0x57E0,
+	0xB0F1, 0x57E4, 0xB0F2, 0x57FA, 0xB0F3, 0x5802, 0xB0F4, 0x5835,
+	0xB0F5, 0x57F7, 0xB0F6, 0x57F9, 0xB0F7, 0x5920, 0xB0F8, 0x5962,
+	0xB0F9, 0x5A36, 0xB0FA, 0x5A41, 0xB0FB, 0x5A49, 0xB0FC, 0x5A66,
+	0xB0FD, 0x5A6A, 0xB0FE, 0x5A40, 0xB140, 0x5A3C, 0xB141, 0x5A62,
+	0xB142, 0x5A5A, 0xB143, 0x5A46, 0xB144, 0x5A4A, 0xB145, 0x5B70,
+	0xB146, 0x5BC7, 0xB147, 0x5BC5, 0xB148, 0x5BC4, 0xB149, 0x5BC2,
+	0xB14A, 0x5BBF, 0xB14B, 0x5BC6, 0xB14C, 0x5C09, 0xB14D, 0x5C08,
+	0xB14E, 0x5C07, 0xB14F, 0x5C60, 0xB150, 0x5C5C, 0xB151, 0x5C5D,
+	0xB152, 0x5D07, 0xB153, 0x5D06, 0xB154, 0x5D0E, 0xB155, 0x5D1B,
+	0xB156, 0x5D16, 0xB157, 0x5D22, 0xB158, 0x5D11, 0xB159, 0x5D29,
+	0xB15A, 0x5D14, 0xB15B, 0x5D19, 0xB15C, 0x5D24, 0xB15D, 0x5D27,
+	0xB15E, 0x5D17, 0xB15F, 0x5DE2, 0xB160, 0x5E38, 0xB161, 0x5E36,
+	0xB162, 0x5E33, 0xB163, 0x5E37, 0xB164, 0x5EB7, 0xB165, 0x5EB8,
+	0xB166, 0x5EB6, 0xB167, 0x5EB5, 0xB168, 0x5EBE, 0xB169, 0x5F35,
+	0xB16A, 0x5F37, 0xB16B, 0x5F57, 0xB16C, 0x5F6C, 0xB16D, 0x5F69,
+	0xB16E, 0x5F6B, 0xB16F, 0x5F97, 0xB170, 0x5F99, 0xB171, 0x5F9E,
+	0xB172, 0x5F98, 0xB173, 0x5FA1, 0xB174, 0x5FA0, 0xB175, 0x5F9C,
+	0xB176, 0x607F, 0xB177, 0x60A3, 0xB178, 0x6089, 0xB179, 0x60A0,
+	0xB17A, 0x60A8, 0xB17B, 0x60CB, 0xB17C, 0x60B4, 0xB17D, 0x60E6,
+	0xB17E, 0x60BD, 0xB1A1, 0x60C5, 0xB1A2, 0x60BB, 0xB1A3, 0x60B5,
+	0xB1A4, 0x60DC, 0xB1A5, 0x60BC, 0xB1A6, 0x60D8, 0xB1A7, 0x60D5,
+	0xB1A8, 0x60C6, 0xB1A9, 0x60DF, 0xB1AA, 0x60B8, 0xB1AB, 0x60DA,
+	0xB1AC, 0x60C7, 0xB1AD, 0x621A, 0xB1AE, 0x621B, 0xB1AF, 0x6248,
+	0xB1B0, 0x63A0, 0xB1B1, 0x63A7, 0xB1B2, 0x6372, 0xB1B3, 0x6396,
+	0xB1B4, 0x63A2, 0xB1B5, 0x63A5, 0xB1B6, 0x6377, 0xB1B7, 0x6367,
+	0xB1B8, 0x6398, 0xB1B9, 0x63AA, 0xB1BA, 0x6371, 0xB1BB, 0x63A9,
+	0xB1BC, 0x6389, 0xB1BD, 0x6383, 0xB1BE, 0x639B, 0xB1BF, 0x636B,
+	0xB1C0, 0x63A8, 0xB1C1, 0x6384, 0xB1C2, 0x6388, 0xB1C3, 0x6399,
+	0xB1C4, 0x63A1, 0xB1C5, 0x63AC, 0xB1C6, 0x6392, 0xB1C7, 0x638F,
+	0xB1C8, 0x6380, 0xB1C9, 0x637B, 0xB1CA, 0x6369, 0xB1CB, 0x6368,
+	0xB1CC, 0x637A, 0xB1CD, 0x655D, 0xB1CE, 0x6556, 0xB1CF, 0x6551,
+	0xB1D0, 0x6559, 0xB1D1, 0x6557, 0xB1D2, 0x555F, 0xB1D3, 0x654F,
+	0xB1D4, 0x6558, 0xB1D5, 0x6555, 0xB1D6, 0x6554, 0xB1D7, 0x659C,
+	0xB1D8, 0x659B, 0xB1D9, 0x65AC, 0xB1DA, 0x65CF, 0xB1DB, 0x65CB,
+	0xB1DC, 0x65CC, 0xB1DD, 0x65CE, 0xB1DE, 0x665D, 0xB1DF, 0x665A,
+	0xB1E0, 0x6664, 0xB1E1, 0x6668, 0xB1E2, 0x6666, 0xB1E3, 0x665E,
+	0xB1E4, 0x66F9, 0xB1E5, 0x52D7, 0xB1E6, 0x671B, 0xB1E7, 0x6881,
+	0xB1E8, 0x68AF, 0xB1E9, 0x68A2, 0xB1EA, 0x6893, 0xB1EB, 0x68B5,
+	0xB1EC, 0x687F, 0xB1ED, 0x6876, 0xB1EE, 0x68B1, 0xB1EF, 0x68A7,
+	0xB1F0, 0x6897, 0xB1F1, 0x68B0, 0xB1F2, 0x6883, 0xB1F3, 0x68C4,
+	0xB1F4, 0x68AD, 0xB1F5, 0x6886, 0xB1F6, 0x6885, 0xB1F7, 0x6894,
+	0xB1F8, 0x689D, 0xB1F9, 0x68A8, 0xB1FA, 0x689F, 0xB1FB, 0x68A1,
+	0xB1FC, 0x6882, 0xB1FD, 0x6B32, 0xB1FE, 0x6BBA, 0xB240, 0x6BEB,
+	0xB241, 0x6BEC, 0xB242, 0x6C2B, 0xB243, 0x6D8E, 0xB244, 0x6DBC,
+	0xB245, 0x6DF3, 0xB246, 0x6DD9, 0xB247, 0x6DB2, 0xB248, 0x6DE1,
+	0xB249, 0x6DCC, 0xB24A, 0x6DE4, 0xB24B, 0x6DFB, 0xB24C, 0x6DFA,
+	0xB24D, 0x6E05, 0xB24E, 0x6DC7, 0xB24F, 0x6DCB, 0xB250, 0x6DAF,
+	0xB251, 0x6DD1, 0xB252, 0x6DAE, 0xB253, 0x6DDE, 0xB254, 0x6DF9,
+	0xB255, 0x6DB8, 0xB256, 0x6DF7, 0xB257, 0x6DF5, 0xB258, 0x6DC5,
+	0xB259, 0x6DD2, 0xB25A, 0x6E1A, 0xB25B, 0x6DB5, 0xB25C, 0x6DDA,
+	0xB25D, 0x6DEB, 0xB25E, 0x6DD8, 0xB25F, 0x6DEA, 0xB260, 0x6DF1,
+	0xB261, 0x6DEE, 0xB262, 0x6DE8, 0xB263, 0x6DC6, 0xB264, 0x6DC4,
+	0xB265, 0x6DAA, 0xB266, 0x6DEC, 0xB267, 0x6DBF, 0xB268, 0x6DE6,
+	0xB269, 0x70F9, 0xB26A, 0x7109, 0xB26B, 0x710A, 0xB26C, 0x70FD,
+	0xB26D, 0x70EF, 0xB26E, 0x723D, 0xB26F, 0x727D, 0xB270, 0x7281,
+	0xB271, 0x731C, 0xB272, 0x731B, 0xB273, 0x7316, 0xB274, 0x7313,
+	0xB275, 0x7319, 0xB276, 0x7387, 0xB277, 0x7405, 0xB278, 0x740A,
+	0xB279, 0x7403, 0xB27A, 0x7406, 0xB27B, 0x73FE, 0xB27C, 0x740D,
+	0xB27D, 0x74E0, 0xB27E, 0x74F6, 0xB2A1, 0x74F7, 0xB2A2, 0x751C,
+	0xB2A3, 0x7522, 0xB2A4, 0x7565, 0xB2A5, 0x7566, 0xB2A6, 0x7562,
+	0xB2A7, 0x7570, 0xB2A8, 0x758F, 0xB2A9, 0x75D4, 0xB2AA, 0x75D5,
+	0xB2AB, 0x75B5, 0xB2AC, 0x75CA, 0xB2AD, 0x75CD, 0xB2AE, 0x768E,
+	0xB2AF, 0x76D4, 0xB2B0, 0x76D2, 0xB2B1, 0x76DB, 0xB2B2, 0x7737,
+	0xB2B3, 0x773E, 0xB2B4, 0x773C, 0xB2B5, 0x7736, 0xB2B6, 0x7738,
+	0xB2B7, 0x773A, 0xB2B8, 0x786B, 0xB2B9, 0x7843, 0xB2BA, 0x784E,
+	0xB2BB, 0x7965, 0xB2BC, 0x7968, 0xB2BD, 0x796D, 0xB2BE, 0x79FB,
+	0xB2BF, 0x7A92, 0xB2C0, 0x7A95, 0xB2C1, 0x7B20, 0xB2C2, 0x7B28,
+	0xB2C3, 0x7B1B, 0xB2C4, 0x7B2C, 0xB2C5, 0x7B26, 0xB2C6, 0x7B19,
+	0xB2C7, 0x7B1E, 0xB2C8, 0x7B2E, 0xB2C9, 0x7C92, 0xB2CA, 0x7C97,
+	0xB2CB, 0x7C95, 0xB2CC, 0x7D46, 0xB2CD, 0x7D43, 0xB2CE, 0x7D71,
+	0xB2CF, 0x7D2E, 0xB2D0, 0x7D39, 0xB2D1, 0x7D3C, 0xB2D2, 0x7D40,
+	0xB2D3, 0x7D30, 0xB2D4, 0x7D33, 0xB2D5, 0x7D44, 0xB2D6, 0x7D2F,
+	0xB2D7, 0x7D42, 0xB2D8, 0x7D32, 0xB2D9, 0x7D31, 0xB2DA, 0x7F3D,
+	0xB2DB, 0x7F9E, 0xB2DC, 0x7F9A, 0xB2DD, 0x7FCC, 0xB2DE, 0x7FCE,
+	0xB2DF, 0x7FD2, 0xB2E0, 0x801C, 0xB2E1, 0x804A, 0xB2E2, 0x8046,
+	0xB2E3, 0x812F, 0xB2E4, 0x8116, 0xB2E5, 0x8123, 0xB2E6, 0x812B,
+	0xB2E7, 0x8129, 0xB2E8, 0x8130, 0xB2E9, 0x8124, 0xB2EA, 0x8202,
+	0xB2EB, 0x8235, 0xB2EC, 0x8237, 0xB2ED, 0x8236, 0xB2EE, 0x8239,
+	0xB2EF, 0x838E, 0xB2F0, 0x839E, 0xB2F1, 0x8398, 0xB2F2, 0x8378,
+	0xB2F3, 0x83A2, 0xB2F4, 0x8396, 0xB2F5, 0x83BD, 0xB2F6, 0x83AB,
+	0xB2F7, 0x8392, 0xB2F8, 0x838A, 0xB2F9, 0x8393, 0xB2FA, 0x8389,
+	0xB2FB, 0x83A0, 0xB2FC, 0x8377, 0xB2FD, 0x837B, 0xB2FE, 0x837C,
+	0xB340, 0x8386, 0xB341, 0x83A7, 0xB342, 0x8655, 0xB343, 0x5F6A,
+	0xB344, 0x86C7, 0xB345, 0x86C0, 0xB346, 0x86B6, 0xB347, 0x86C4,
+	0xB348, 0x86B5, 0xB349, 0x86C6, 0xB34A, 0x86CB, 0xB34B, 0x86B1,
+	0xB34C, 0x86AF, 0xB34D, 0x86C9, 0xB34E, 0x8853, 0xB34F, 0x889E,
+	0xB350, 0x8888, 0xB351, 0x88AB, 0xB352, 0x8892, 0xB353, 0x8896,
+	0xB354, 0x888D, 0xB355, 0x888B, 0xB356, 0x8993, 0xB357, 0x898F,
+	0xB358, 0x8A2A, 0xB359, 0x8A1D, 0xB35A, 0x8A23, 0xB35B, 0x8A25,
+	0xB35C, 0x8A31, 0xB35D, 0x8A2D, 0xB35E, 0x8A1F, 0xB35F, 0x8A1B,
+	0xB360, 0x8A22, 0xB361, 0x8C49, 0xB362, 0x8C5A, 0xB363, 0x8CA9,
+	0xB364, 0x8CAC, 0xB365, 0x8CAB, 0xB366, 0x8CA8, 0xB367, 0x8CAA,
+	0xB368, 0x8CA7, 0xB369, 0x8D67, 0xB36A, 0x8D66, 0xB36B, 0x8DBE,
+	0xB36C, 0x8DBA, 0xB36D, 0x8EDB, 0xB36E, 0x8EDF, 0xB36F, 0x9019,
+	0xB370, 0x900D, 0xB371, 0x901A, 0xB372, 0x9017, 0xB373, 0x9023,
+	0xB374, 0x901F, 0xB375, 0x901D, 0xB376, 0x9010, 0xB377, 0x9015,
+	0xB378, 0x901E, 0xB379, 0x9020, 0xB37A, 0x900F, 0xB37B, 0x9022,
+	0xB37C, 0x9016, 0xB37D, 0x901B, 0xB37E, 0x9014, 0xB3A1, 0x90E8,
+	0xB3A2, 0x90ED, 0xB3A3, 0x90FD, 0xB3A4, 0x9157, 0xB3A5, 0x91CE,
+	0xB3A6, 0x91F5, 0xB3A7, 0x91E6, 0xB3A8, 0x91E3, 0xB3A9, 0x91E7,
+	0xB3AA, 0x91ED, 0xB3AB, 0x91E9, 0xB3AC, 0x9589, 0xB3AD, 0x966A,
+	0xB3AE, 0x9675, 0xB3AF, 0x9673, 0xB3B0, 0x9678, 0xB3B1, 0x9670,
+	0xB3B2, 0x9674, 0xB3B3, 0x9676, 0xB3B4, 0x9677, 0xB3B5, 0x966C,
+	0xB3B6, 0x96C0, 0xB3B7, 0x96EA, 0xB3B8, 0x96E9, 0xB3B9, 0x7AE0,
+	0xB3BA, 0x7ADF, 0xB3BB, 0x9802, 0xB3BC, 0x9803, 0xB3BD, 0x9B5A,
+	0xB3BE, 0x9CE5, 0xB3BF, 0x9E75, 0xB3C0, 0x9E7F, 0xB3C1, 0x9EA5,
+	0xB3C2, 0x9EBB, 0xB3C3, 0x50A2, 0xB3C4, 0x508D, 0xB3C5, 0x5085,
+	0xB3C6, 0x5099, 0xB3C7, 0x5091, 0xB3C8, 0x5080, 0xB3C9, 0x5096,
+	0xB3CA, 0x5098, 0xB3CB, 0x509A, 0xB3CC, 0x6700, 0xB3CD, 0x51F1,
+	0xB3CE, 0x5272, 0xB3CF, 0x5274, 0xB3D0, 0x5275, 0xB3D1, 0x5269,
+	0xB3D2, 0x52DE, 0xB3D3, 0x52DD, 0xB3D4, 0x52DB, 0xB3D5, 0x535A,
+	0xB3D6, 0x53A5, 0xB3D7, 0x557B, 0xB3D8, 0x5580, 0xB3D9, 0x55A7,
+	0xB3DA, 0x557C, 0xB3DB, 0x558A, 0xB3DC, 0x559D, 0xB3DD, 0x5598,
+	0xB3DE, 0x5582, 0xB3DF, 0x559C, 0xB3E0, 0x55AA, 0xB3E1, 0x5594,
+	0xB3E2, 0x5587, 0xB3E3, 0x558B, 0xB3E4, 0x5583, 0xB3E5, 0x55B3,
+	0xB3E6, 0x55AE, 0xB3E7, 0x559F, 0xB3E8, 0x553E, 0xB3E9, 0x55B2,
+	0xB3EA, 0x559A, 0xB3EB, 0x55BB, 0xB3EC, 0x55AC, 0xB3ED, 0x55B1,
+	0xB3EE, 0x557E, 0xB3EF, 0x5589, 0xB3F0, 0x55AB, 0xB3F1, 0x5599,
+	0xB3F2, 0x570D, 0xB3F3, 0x582F, 0xB3F4, 0x582A, 0xB3F5, 0x5834,
+	0xB3F6, 0x5824, 0xB3F7, 0x5830, 0xB3F8, 0x5831, 0xB3F9, 0x5821,
+	0xB3FA, 0x581D, 0xB3FB, 0x5820, 0xB3FC, 0x58F9, 0xB3FD, 0x58FA,
+	0xB3FE, 0x5960, 0xB440, 0x5A77, 0xB441, 0x5A9A, 0xB442, 0x5A7F,
+	0xB443, 0x5A92, 0xB444, 0x5A9B, 0xB445, 0x5AA7, 0xB446, 0x5B73,
+	0xB447, 0x5B71, 0xB448, 0x5BD2, 0xB449, 0x5BCC, 0xB44A, 0x5BD3,
+	0xB44B, 0x5BD0, 0xB44C, 0x5C0A, 0xB44D, 0x5C0B, 0xB44E, 0x5C31,
+	0xB44F, 0x5D4C, 0xB450, 0x5D50, 0xB451, 0x5D34, 0xB452, 0x5D47,
+	0xB453, 0x5DFD, 0xB454, 0x5E45, 0xB455, 0x5E3D, 0xB456, 0x5E40,
+	0xB457, 0x5E43, 0xB458, 0x5E7E, 0xB459, 0x5ECA, 0xB45A, 0x5EC1,
+	0xB45B, 0x5EC2, 0xB45C, 0x5EC4, 0xB45D, 0x5F3C, 0xB45E, 0x5F6D,
+	0xB45F, 0x5FA9, 0xB460, 0x5FAA, 0xB461, 0x5FA8, 0xB462, 0x60D1,
+	0xB463, 0x60E1, 0xB464, 0x60B2, 0xB465, 0x60B6, 0xB466, 0x60E0,
+	0xB467, 0x611C, 0xB468, 0x6123, 0xB469, 0x60FA, 0xB46A, 0x6115,
+	0xB46B, 0x60F0, 0xB46C, 0x60FB, 0xB46D, 0x60F4, 0xB46E, 0x6168,
+	0xB46F, 0x60F1, 0xB470, 0x610E, 0xB471, 0x60F6, 0xB472, 0x6109,
+	0xB473, 0x6100, 0xB474, 0x6112, 0xB475, 0x621F, 0xB476, 0x6249,
+	0xB477, 0x63A3, 0xB478, 0x638C, 0xB479, 0x63CF, 0xB47A, 0x63C0,
+	0xB47B, 0x63E9, 0xB47C, 0x63C9, 0xB47D, 0x63C6, 0xB47E, 0x63CD,
+	0xB4A1, 0x63D2, 0xB4A2, 0x63E3, 0xB4A3, 0x63D0, 0xB4A4, 0x63E1,
+	0xB4A5, 0x63D6, 0xB4A6, 0x63ED, 0xB4A7, 0x63EE, 0xB4A8, 0x6376,
+	0xB4A9, 0x63F4, 0xB4AA, 0x63EA, 0xB4AB, 0x63DB, 0xB4AC, 0x6452,
+	0xB4AD, 0x63DA, 0xB4AE, 0x63F9, 0xB4AF, 0x655E, 0xB4B0, 0x6566,
+	0xB4B1, 0x6562, 0xB4B2, 0x6563, 0xB4B3, 0x6591, 0xB4B4, 0x6590,
+	0xB4B5, 0x65AF, 0xB4B6, 0x666E, 0xB4B7, 0x6670, 0xB4B8, 0x6674,
+	0xB4B9, 0x6676, 0xB4BA, 0x666F, 0xB4BB, 0x6691, 0xB4BC, 0x667A,
+	0xB4BD, 0x667E, 0xB4BE, 0x6677, 0xB4BF, 0x66FE, 0xB4C0, 0x66FF,
+	0xB4C1, 0x671F, 0xB4C2, 0x671D, 0xB4C3, 0x68FA, 0xB4C4, 0x68D5,
+	0xB4C5, 0x68E0, 0xB4C6, 0x68D8, 0xB4C7, 0x68D7, 0xB4C8, 0x6905,
+	0xB4C9, 0x68DF, 0xB4CA, 0x68F5, 0xB4CB, 0x68EE, 0xB4CC, 0x68E7,
+	0xB4CD, 0x68F9, 0xB4CE, 0x68D2, 0xB4CF, 0x68F2, 0xB4D0, 0x68E3,
+	0xB4D1, 0x68CB, 0xB4D2, 0x68CD, 0xB4D3, 0x690D, 0xB4D4, 0x6912,
+	0xB4D5, 0x690E, 0xB4D6, 0x68C9, 0xB4D7, 0x68DA, 0xB4D8, 0x696E,
+	0xB4D9, 0x68FB, 0xB4DA, 0x6B3E, 0xB4DB, 0x6B3A, 0xB4DC, 0x6B3D,
+	0xB4DD, 0x6B98, 0xB4DE, 0x6B96, 0xB4DF, 0x6BBC, 0xB4E0, 0x6BEF,
+	0xB4E1, 0x6C2E, 0xB4E2, 0x6C2F, 0xB4E3, 0x6C2C, 0xB4E4, 0x6E2F,
+	0xB4E5, 0x6E38, 0xB4E6, 0x6E54, 0xB4E7, 0x6E21, 0xB4E8, 0x6E32,
+	0xB4E9, 0x6E67, 0xB4EA, 0x6E4A, 0xB4EB, 0x6E20, 0xB4EC, 0x6E25,
+	0xB4ED, 0x6E23, 0xB4EE, 0x6E1B, 0xB4EF, 0x6E5B, 0xB4F0, 0x6E58,
+	0xB4F1, 0x6E24, 0xB4F2, 0x6E56, 0xB4F3, 0x6E6E, 0xB4F4, 0x6E2D,
+	0xB4F5, 0x6E26, 0xB4F6, 0x6E6F, 0xB4F7, 0x6E34, 0xB4F8, 0x6E4D,
+	0xB4F9, 0x6E3A, 0xB4FA, 0x6E2C, 0xB4FB, 0x6E43, 0xB4FC, 0x6E1D,
+	0xB4FD, 0x6E3E, 0xB4FE, 0x6ECB, 0xB540, 0x6E89, 0xB541, 0x6E19,
+	0xB542, 0x6E4E, 0xB543, 0x6E63, 0xB544, 0x6E44, 0xB545, 0x6E72,
+	0xB546, 0x6E69, 0xB547, 0x6E5F, 0xB548, 0x7119, 0xB549, 0x711A,
+	0xB54A, 0x7126, 0xB54B, 0x7130, 0xB54C, 0x7121, 0xB54D, 0x7136,
+	0xB54E, 0x716E, 0xB54F, 0x711C, 0xB550, 0x724C, 0xB551, 0x7284,
+	0xB552, 0x7280, 0xB553, 0x7336, 0xB554, 0x7325, 0xB555, 0x7334,
+	0xB556, 0x7329, 0xB557, 0x743A, 0xB558, 0x742A, 0xB559, 0x7433,
+	0xB55A, 0x7422, 0xB55B, 0x7425, 0xB55C, 0x7435, 0xB55D, 0x7436,
+	0xB55E, 0x7434, 0xB55F, 0x742F, 0xB560, 0x741B, 0xB561, 0x7426,
+	0xB562, 0x7428, 0xB563, 0x7525, 0xB564, 0x7526, 0xB565, 0x756B,
+	0xB566, 0x756A, 0xB567, 0x75E2, 0xB568, 0x75DB, 0xB569, 0x75E3,
+	0xB56A, 0x75D9, 0xB56B, 0x75D8, 0xB56C, 0x75DE, 0xB56D, 0x75E0,
+	0xB56E, 0x767B, 0xB56F, 0x767C, 0xB570, 0x7696, 0xB571, 0x7693,
+	0xB572, 0x76B4, 0xB573, 0x76DC, 0xB574, 0x774F, 0xB575, 0x77ED,
+	0xB576, 0x785D, 0xB577, 0x786C, 0xB578, 0x786F, 0xB579, 0x7A0D,
+	0xB57A, 0x7A08, 0xB57B, 0x7A0B, 0xB57C, 0x7A05, 0xB57D, 0x7A00,
+	0xB57E, 0x7A98, 0xB5A1, 0x7A97, 0xB5A2, 0x7A96, 0xB5A3, 0x7AE5,
+	0xB5A4, 0x7AE3, 0xB5A5, 0x7B49, 0xB5A6, 0x7B56, 0xB5A7, 0x7B46,
+	0xB5A8, 0x7B50, 0xB5A9, 0x7B52, 0xB5AA, 0x7B54, 0xB5AB, 0x7B4D,
+	0xB5AC, 0x7B4B, 0xB5AD, 0x7B4F, 0xB5AE, 0x7B51, 0xB5AF, 0x7C9F,
+	0xB5B0, 0x7CA5, 0xB5B1, 0x7D5E, 0xB5B2, 0x7D50, 0xB5B3, 0x7D68,
+	0xB5B4, 0x7D55, 0xB5B5, 0x7D2B, 0xB5B6, 0x7D6E, 0xB5B7, 0x7D72,
+	0xB5B8, 0x7D61, 0xB5B9, 0x7D66, 0xB5BA, 0x7D62, 0xB5BB, 0x7D70,
+	0xB5BC, 0x7D73, 0xB5BD, 0x5584, 0xB5BE, 0x7FD4, 0xB5BF, 0x7FD5,
+	0xB5C0, 0x800B, 0xB5C1, 0x8052, 0xB5C2, 0x8085, 0xB5C3, 0x8155,
+	0xB5C4, 0x8154, 0xB5C5, 0x814B, 0xB5C6, 0x8151, 0xB5C7, 0x814E,
+	0xB5C8, 0x8139, 0xB5C9, 0x8146, 0xB5CA, 0x813E, 0xB5CB, 0x814C,
+	0xB5CC, 0x8153, 0xB5CD, 0x8174, 0xB5CE, 0x8212, 0xB5CF, 0x821C,
+	0xB5D0, 0x83E9, 0xB5D1, 0x8403, 0xB5D2, 0x83F8, 0xB5D3, 0x840D,
+	0xB5D4, 0x83E0, 0xB5D5, 0x83C5, 0xB5D6, 0x840B, 0xB5D7, 0x83C1,
+	0xB5D8, 0x83EF, 0xB5D9, 0x83F1, 0xB5DA, 0x83F4, 0xB5DB, 0x8457,
+	0xB5DC, 0x840A, 0xB5DD, 0x83F0, 0xB5DE, 0x840C, 0xB5DF, 0x83CC,
+	0xB5E0, 0x83FD, 0xB5E1, 0x83F2, 0xB5E2, 0x83CA, 0xB5E3, 0x8438,
+	0xB5E4, 0x840E, 0xB5E5, 0x8404, 0xB5E6, 0x83DC, 0xB5E7, 0x8407,
+	0xB5E8, 0x83D4, 0xB5E9, 0x83DF, 0xB5EA, 0x865B, 0xB5EB, 0x86DF,
+	0xB5EC, 0x86D9, 0xB5ED, 0x86ED, 0xB5EE, 0x86D4, 0xB5EF, 0x86DB,
+	0xB5F0, 0x86E4, 0xB5F1, 0x86D0, 0xB5F2, 0x86DE, 0xB5F3, 0x8857,
+	0xB5F4, 0x88C1, 0xB5F5, 0x88C2, 0xB5F6, 0x88B1, 0xB5F7, 0x8983,
+	0xB5F8, 0x8996, 0xB5F9, 0x8A3B, 0xB5FA, 0x8A60, 0xB5FB, 0x8A55,
+	0xB5FC, 0x8A5E, 0xB5FD, 0x8A3C, 0xB5FE, 0x8A41, 0xB640, 0x8A54,
+	0xB641, 0x8A5B, 0xB642, 0x8A50, 0xB643, 0x8A46, 0xB644, 0x8A34,
+	0xB645, 0x8A3A, 0xB646, 0x8A36, 0xB647, 0x8A56, 0xB648, 0x8C61,
+	0xB649, 0x8C82, 0xB64A, 0x8CAF, 0xB64B, 0x8CBC, 0xB64C, 0x8CB3,
+	0xB64D, 0x8CBD, 0xB64E, 0x8CC1, 0xB64F, 0x8CBB, 0xB650, 0x8CC0,
+	0xB651, 0x8CB4, 0xB652, 0x8CB7, 0xB653, 0x8CB6, 0xB654, 0x8CBF,
+	0xB655, 0x8CB8, 0xB656, 0x8D8A, 0xB657, 0x8D85, 0xB658, 0x8D81,
+	0xB659, 0x8DCE, 0xB65A, 0x8DDD, 0xB65B, 0x8DCB, 0xB65C, 0x8DDA,
+	0xB65D, 0x8DD1, 0xB65E, 0x8DCC, 0xB65F, 0x8DDB, 0xB660, 0x8DC6,
+	0xB661, 0x8EFB, 0xB662, 0x8EF8, 0xB663, 0x8EFC, 0xB664, 0x8F9C,
+	0xB665, 0x902E, 0xB666, 0x9035, 0xB667, 0x9031, 0xB668, 0x9038,
+	0xB669, 0x9032, 0xB66A, 0x9036, 0xB66B, 0x9102, 0xB66C, 0x90F5,
+	0xB66D, 0x9109, 0xB66E, 0x90FE, 0xB66F, 0x9163, 0xB670, 0x9165,
+	0xB671, 0x91CF, 0xB672, 0x9214, 0xB673, 0x9215, 0xB674, 0x9223,
+	0xB675, 0x9209, 0xB676, 0x921E, 0xB677, 0x920D, 0xB678, 0x9210,
+	0xB679, 0x9207, 0xB67A, 0x9211, 0xB67B, 0x9594, 0xB67C, 0x958F,
+	0xB67D, 0x958B, 0xB67E, 0x9591, 0xB6A1, 0x9593, 0xB6A2, 0x9592,
+	0xB6A3, 0x958E, 0xB6A4, 0x968A, 0xB6A5, 0x968E, 0xB6A6, 0x968B,
+	0xB6A7, 0x967D, 0xB6A8, 0x9685, 0xB6A9, 0x9686, 0xB6AA, 0x968D,
+	0xB6AB, 0x9672, 0xB6AC, 0x9684, 0xB6AD, 0x96C1, 0xB6AE, 0x96C5,
+	0xB6AF, 0x96C4, 0xB6B0, 0x96C6, 0xB6B1, 0x96C7, 0xB6B2, 0x96EF,
+	0xB6B3, 0x96F2, 0xB6B4, 0x97CC, 0xB6B5, 0x9805, 0xB6B6, 0x9806,
+	0xB6B7, 0x9808, 0xB6B8, 0x98E7, 0xB6B9, 0x98EA, 0xB6BA, 0x98EF,
+	0xB6BB, 0x98E9, 0xB6BC, 0x98F2, 0xB6BD, 0x98ED, 0xB6BE, 0x99AE,
+	0xB6BF, 0x99AD, 0xB6C0, 0x9EC3, 0xB6C1, 0x9ECD, 0xB6C2, 0x9ED1,
+	0xB6C3, 0x4E82, 0xB6C4, 0x50AD, 0xB6C5, 0x50B5, 0xB6C6, 0x50B2,
+	0xB6C7, 0x50B3, 0xB6C8, 0x50C5, 0xB6C9, 0x50BE, 0xB6CA, 0x50AC,
+	0xB6CB, 0x50B7, 0xB6CC, 0x50BB, 0xB6CD, 0x50AF, 0xB6CE, 0x50C7,
+	0xB6CF, 0x527F, 0xB6D0, 0x5277, 0xB6D1, 0x527D, 0xB6D2, 0x52DF,
+	0xB6D3, 0x52E6, 0xB6D4, 0x52E4, 0xB6D5, 0x52E2, 0xB6D6, 0x52E3,
+	0xB6D7, 0x532F, 0xB6D8, 0x55DF, 0xB6D9, 0x55E8, 0xB6DA, 0x55D3,
+	0xB6DB, 0x55E6, 0xB6DC, 0x55CE, 0xB6DD, 0x55DC, 0xB6DE, 0x55C7,
+	0xB6DF, 0x55D1, 0xB6E0, 0x55E3, 0xB6E1, 0x55E4, 0xB6E2, 0x55EF,
+	0xB6E3, 0x55DA, 0xB6E4, 0x55E1, 0xB6E5, 0x55C5, 0xB6E6, 0x55C6,
+	0xB6E7, 0x55E5, 0xB6E8, 0x55C9, 0xB6E9, 0x5712, 0xB6EA, 0x5713,
+	0xB6EB, 0x585E, 0xB6EC, 0x5851, 0xB6ED, 0x5858, 0xB6EE, 0x5857,
+	0xB6EF, 0x585A, 0xB6F0, 0x5854, 0xB6F1, 0x586B, 0xB6F2, 0x584C,
+	0xB6F3, 0x586D, 0xB6F4, 0x584A, 0xB6F5, 0x5862, 0xB6F6, 0x5852,
+	0xB6F7, 0x584B, 0xB6F8, 0x5967, 0xB6F9, 0x5AC1, 0xB6FA, 0x5AC9,
+	0xB6FB, 0x5ACC, 0xB6FC, 0x5ABE, 0xB6FD, 0x5ABD, 0xB6FE, 0x5ABC,
+	0xB740, 0x5AB3, 0xB741, 0x5AC2, 0xB742, 0x5AB2, 0xB743, 0x5D69,
+	0xB744, 0x5D6F, 0xB745, 0x5E4C, 0xB746, 0x5E79, 0xB747, 0x5EC9,
+	0xB748, 0x5EC8, 0xB749, 0x5F12, 0xB74A, 0x5F59, 0xB74B, 0x5FAC,
+	0xB74C, 0x5FAE, 0xB74D, 0x611A, 0xB74E, 0x610F, 0xB74F, 0x6148,
+	0xB750, 0x611F, 0xB751, 0x60F3, 0xB752, 0x611B, 0xB753, 0x60F9,
+	0xB754, 0x6101, 0xB755, 0x6108, 0xB756, 0x614E, 0xB757, 0x614C,
+	0xB758, 0x6144, 0xB759, 0x614D, 0xB75A, 0x613E, 0xB75B, 0x6134,
+	0xB75C, 0x6127, 0xB75D, 0x610D, 0xB75E, 0x6106, 0xB75F, 0x6137,
+	0xB760, 0x6221, 0xB761, 0x6222, 0xB762, 0x6413, 0xB763, 0x643E,
+	0xB764, 0x641E, 0xB765, 0x642A, 0xB766, 0x642D, 0xB767, 0x643D,
+	0xB768, 0x642C, 0xB769, 0x640F, 0xB76A, 0x641C, 0xB76B, 0x6414,
+	0xB76C, 0x640D, 0xB76D, 0x6436, 0xB76E, 0x6416, 0xB76F, 0x6417,
+	0xB770, 0x6406, 0xB771, 0x656C, 0xB772, 0x659F, 0xB773, 0x65B0,
+	0xB774, 0x6697, 0xB775, 0x6689, 0xB776, 0x6687, 0xB777, 0x6688,
+	0xB778, 0x6696, 0xB779, 0x6684, 0xB77A, 0x6698, 0xB77B, 0x668D,
+	0xB77C, 0x6703, 0xB77D, 0x6994, 0xB77E, 0x696D, 0xB7A1, 0x695A,
+	0xB7A2, 0x6977, 0xB7A3, 0x6960, 0xB7A4, 0x6954, 0xB7A5, 0x6975,
+	0xB7A6, 0x6930, 0xB7A7, 0x6982, 0xB7A8, 0x694A, 0xB7A9, 0x6968,
+	0xB7AA, 0x696B, 0xB7AB, 0x695E, 0xB7AC, 0x6953, 0xB7AD, 0x6979,
+	0xB7AE, 0x6986, 0xB7AF, 0x695D, 0xB7B0, 0x6963, 0xB7B1, 0x695B,
+	0xB7B2, 0x6B47, 0xB7B3, 0x6B72, 0xB7B4, 0x6BC0, 0xB7B5, 0x6BBF,
+	0xB7B6, 0x6BD3, 0xB7B7, 0x6BFD, 0xB7B8, 0x6EA2, 0xB7B9, 0x6EAF,
+	0xB7BA, 0x6ED3, 0xB7BB, 0x6EB6, 0xB7BC, 0x6EC2, 0xB7BD, 0x6E90,
+	0xB7BE, 0x6E9D, 0xB7BF, 0x6EC7, 0xB7C0, 0x6EC5, 0xB7C1, 0x6EA5,
+	0xB7C2, 0x6E98, 0xB7C3, 0x6EBC, 0xB7C4, 0x6EBA, 0xB7C5, 0x6EAB,
+	0xB7C6, 0x6ED1, 0xB7C7, 0x6E96, 0xB7C8, 0x6E9C, 0xB7C9, 0x6EC4,
+	0xB7CA, 0x6ED4, 0xB7CB, 0x6EAA, 0xB7CC, 0x6EA7, 0xB7CD, 0x6EB4,
+	0xB7CE, 0x714E, 0xB7CF, 0x7159, 0xB7D0, 0x7169, 0xB7D1, 0x7164,
+	0xB7D2, 0x7149, 0xB7D3, 0x7167, 0xB7D4, 0x715C, 0xB7D5, 0x716C,
+	0xB7D6, 0x7166, 0xB7D7, 0x714C, 0xB7D8, 0x7165, 0xB7D9, 0x715E,
+	0xB7DA, 0x7146, 0xB7DB, 0x7168, 0xB7DC, 0x7156, 0xB7DD, 0x723A,
+	0xB7DE, 0x7252, 0xB7DF, 0x7337, 0xB7E0, 0x7345, 0xB7E1, 0x733F,
+	0xB7E2, 0x733E, 0xB7E3, 0x746F, 0xB7E4, 0x745A, 0xB7E5, 0x7455,
+	0xB7E6, 0x745F, 0xB7E7, 0x745E, 0xB7E8, 0x7441, 0xB7E9, 0x743F,
+	0xB7EA, 0x7459, 0xB7EB, 0x745B, 0xB7EC, 0x745C, 0xB7ED, 0x7576,
+	0xB7EE, 0x7578, 0xB7EF, 0x7600, 0xB7F0, 0x75F0, 0xB7F1, 0x7601,
+	0xB7F2, 0x75F2, 0xB7F3, 0x75F1, 0xB7F4, 0x75FA, 0xB7F5, 0x75FF,
+	0xB7F6, 0x75F4, 0xB7F7, 0x75F3, 0xB7F8, 0x76DE, 0xB7F9, 0x76DF,
+	0xB7FA, 0x775B, 0xB7FB, 0x776B, 0xB7FC, 0x7766, 0xB7FD, 0x775E,
+	0xB7FE, 0x7763, 0xB840, 0x7779, 0xB841, 0x776A, 0xB842, 0x776C,
+	0xB843, 0x775C, 0xB844, 0x7765, 0xB845, 0x7768, 0xB846, 0x7762,
+	0xB847, 0x77EE, 0xB848, 0x788E, 0xB849, 0x78B0, 0xB84A, 0x7897,
+	0xB84B, 0x7898, 0xB84C, 0x788C, 0xB84D, 0x7889, 0xB84E, 0x787C,
+	0xB84F, 0x7891, 0xB850, 0x7893, 0xB851, 0x787F, 0xB852, 0x797A,
+	0xB853, 0x797F, 0xB854, 0x7981, 0xB855, 0x842C, 0xB856, 0x79BD,
+	0xB857, 0x7A1C, 0xB858, 0x7A1A, 0xB859, 0x7A20, 0xB85A, 0x7A14,
+	0xB85B, 0x7A1F, 0xB85C, 0x7A1E, 0xB85D, 0x7A9F, 0xB85E, 0x7AA0,
+	0xB85F, 0x7B77, 0xB860, 0x7BC0, 0xB861, 0x7B60, 0xB862, 0x7B6E,
+	0xB863, 0x7B67, 0xB864, 0x7CB1, 0xB865, 0x7CB3, 0xB866, 0x7CB5,
+	0xB867, 0x7D93, 0xB868, 0x7D79, 0xB869, 0x7D91, 0xB86A, 0x7D81,
+	0xB86B, 0x7D8F, 0xB86C, 0x7D5B, 0xB86D, 0x7F6E, 0xB86E, 0x7F69,
+	0xB86F, 0x7F6A, 0xB870, 0x7F72, 0xB871, 0x7FA9, 0xB872, 0x7FA8,
+	0xB873, 0x7FA4, 0xB874, 0x8056, 0xB875, 0x8058, 0xB876, 0x8086,
+	0xB877, 0x8084, 0xB878, 0x8171, 0xB879, 0x8170, 0xB87A, 0x8178,
+	0xB87B, 0x8165, 0xB87C, 0x816E, 0xB87D, 0x8173, 0xB87E, 0x816B,
+	0xB8A1, 0x8179, 0xB8A2, 0x817A, 0xB8A3, 0x8166, 0xB8A4, 0x8205,
+	0xB8A5, 0x8247, 0xB8A6, 0x8482, 0xB8A7, 0x8477, 0xB8A8, 0x843D,
+	0xB8A9, 0x8431, 0xB8AA, 0x8475, 0xB8AB, 0x8466, 0xB8AC, 0x846B,
+	0xB8AD, 0x8449, 0xB8AE, 0x846C, 0xB8AF, 0x845B, 0xB8B0, 0x843C,
+	0xB8B1, 0x8435, 0xB8B2, 0x8461, 0xB8B3, 0x8463, 0xB8B4, 0x8469,
+	0xB8B5, 0x846D, 0xB8B6, 0x8446, 0xB8B7, 0x865E, 0xB8B8, 0x865C,
+	0xB8B9, 0x865F, 0xB8BA, 0x86F9, 0xB8BB, 0x8713, 0xB8BC, 0x8708,
+	0xB8BD, 0x8707, 0xB8BE, 0x8700, 0xB8BF, 0x86FE, 0xB8C0, 0x86FB,
+	0xB8C1, 0x8702, 0xB8C2, 0x8703, 0xB8C3, 0x8706, 0xB8C4, 0x870A,
+	0xB8C5, 0x8859, 0xB8C6, 0x88DF, 0xB8C7, 0x88D4, 0xB8C8, 0x88D9,
+	0xB8C9, 0x88DC, 0xB8CA, 0x88D8, 0xB8CB, 0x88DD, 0xB8CC, 0x88E1,
+	0xB8CD, 0x88CA, 0xB8CE, 0x88D5, 0xB8CF, 0x88D2, 0xB8D0, 0x899C,
+	0xB8D1, 0x89E3, 0xB8D2, 0x8A6B, 0xB8D3, 0x8A72, 0xB8D4, 0x8A73,
+	0xB8D5, 0x8A66, 0xB8D6, 0x8A69, 0xB8D7, 0x8A70, 0xB8D8, 0x8A87,
+	0xB8D9, 0x8A7C, 0xB8DA, 0x8A63, 0xB8DB, 0x8AA0, 0xB8DC, 0x8A71,
+	0xB8DD, 0x8A85, 0xB8DE, 0x8A6D, 0xB8DF, 0x8A62, 0xB8E0, 0x8A6E,
+	0xB8E1, 0x8A6C, 0xB8E2, 0x8A79, 0xB8E3, 0x8A7B, 0xB8E4, 0x8A3E,
+	0xB8E5, 0x8A68, 0xB8E6, 0x8C62, 0xB8E7, 0x8C8A, 0xB8E8, 0x8C89,
+	0xB8E9, 0x8CCA, 0xB8EA, 0x8CC7, 0xB8EB, 0x8CC8, 0xB8EC, 0x8CC4,
+	0xB8ED, 0x8CB2, 0xB8EE, 0x8CC3, 0xB8EF, 0x8CC2, 0xB8F0, 0x8CC5,
+	0xB8F1, 0x8DE1, 0xB8F2, 0x8DDF, 0xB8F3, 0x8DE8, 0xB8F4, 0x8DEF,
+	0xB8F5, 0x8DF3, 0xB8F6, 0x8DFA, 0xB8F7, 0x8DEA, 0xB8F8, 0x8DE4,
+	0xB8F9, 0x8DE6, 0xB8FA, 0x8EB2, 0xB8FB, 0x8F03, 0xB8FC, 0x8F09,
+	0xB8FD, 0x8EFE, 0xB8FE, 0x8F0A, 0xB940, 0x8F9F, 0xB941, 0x8FB2,
+	0xB942, 0x904B, 0xB943, 0x904A, 0xB944, 0x9053, 0xB945, 0x9042,
+	0xB946, 0x9054, 0xB947, 0x903C, 0xB948, 0x9055, 0xB949, 0x9050,
+	0xB94A, 0x9047, 0xB94B, 0x904F, 0xB94C, 0x904E, 0xB94D, 0x904D,
+	0xB94E, 0x9051, 0xB94F, 0x903E, 0xB950, 0x9041, 0xB951, 0x9112,
+	0xB952, 0x9117, 0xB953, 0x916C, 0xB954, 0x916A, 0xB955, 0x9169,
+	0xB956, 0x91C9, 0xB957, 0x9237, 0xB958, 0x9257, 0xB959, 0x9238,
+	0xB95A, 0x923D, 0xB95B, 0x9240, 0xB95C, 0x923E, 0xB95D, 0x925B,
+	0xB95E, 0x924B, 0xB95F, 0x9264, 0xB960, 0x9251, 0xB961, 0x9234,
+	0xB962, 0x9249, 0xB963, 0x924D, 0xB964, 0x9245, 0xB965, 0x9239,
+	0xB966, 0x923F, 0xB967, 0x925A, 0xB968, 0x9598, 0xB969, 0x9698,
+	0xB96A, 0x9694, 0xB96B, 0x9695, 0xB96C, 0x96CD, 0xB96D, 0x96CB,
+	0xB96E, 0x96C9, 0xB96F, 0x96CA, 0xB970, 0x96F7, 0xB971, 0x96FB,
+	0xB972, 0x96F9, 0xB973, 0x96F6, 0xB974, 0x9756, 0xB975, 0x9774,
+	0xB976, 0x9776, 0xB977, 0x9810, 0xB978, 0x9811, 0xB979, 0x9813,
+	0xB97A, 0x980A, 0xB97B, 0x9812, 0xB97C, 0x980C, 0xB97D, 0x98FC,
+	0xB97E, 0x98F4, 0xB9A1, 0x98FD, 0xB9A2, 0x98FE, 0xB9A3, 0x99B3,
+	0xB9A4, 0x99B1, 0xB9A5, 0x99B4, 0xB9A6, 0x9AE1, 0xB9A7, 0x9CE9,
+	0xB9A8, 0x9E82, 0xB9A9, 0x9F0E, 0xB9AA, 0x9F13, 0xB9AB, 0x9F20,
+	0xB9AC, 0x50E7, 0xB9AD, 0x50EE, 0xB9AE, 0x50E5, 0xB9AF, 0x50D6,
+	0xB9B0, 0x50ED, 0xB9B1, 0x50DA, 0xB9B2, 0x50D5, 0xB9B3, 0x50CF,
+	0xB9B4, 0x50D1, 0xB9B5, 0x50F1, 0xB9B6, 0x50CE, 0xB9B7, 0x50E9,
+	0xB9B8, 0x5162, 0xB9B9, 0x51F3, 0xB9BA, 0x5283, 0xB9BB, 0x5282,
+	0xB9BC, 0x5331, 0xB9BD, 0x53AD, 0xB9BE, 0x55FE, 0xB9BF, 0x5600,
+	0xB9C0, 0x561B, 0xB9C1, 0x5617, 0xB9C2, 0x55FD, 0xB9C3, 0x5614,
+	0xB9C4, 0x5606, 0xB9C5, 0x5609, 0xB9C6, 0x560D, 0xB9C7, 0x560E,
+	0xB9C8, 0x55F7, 0xB9C9, 0x5616, 0xB9CA, 0x561F, 0xB9CB, 0x5608,
+	0xB9CC, 0x5610, 0xB9CD, 0x55F6, 0xB9CE, 0x5718, 0xB9CF, 0x5716,
+	0xB9D0, 0x5875, 0xB9D1, 0x587E, 0xB9D2, 0x5883, 0xB9D3, 0x5893,
+	0xB9D4, 0x588A, 0xB9D5, 0x5879, 0xB9D6, 0x5885, 0xB9D7, 0x587D,
+	0xB9D8, 0x58FD, 0xB9D9, 0x5925, 0xB9DA, 0x5922, 0xB9DB, 0x5924,
+	0xB9DC, 0x596A, 0xB9DD, 0x5969, 0xB9DE, 0x5AE1, 0xB9DF, 0x5AE6,
+	0xB9E0, 0x5AE9, 0xB9E1, 0x5AD7, 0xB9E2, 0x5AD6, 0xB9E3, 0x5AD8,
+	0xB9E4, 0x5AE3, 0xB9E5, 0x5B75, 0xB9E6, 0x5BDE, 0xB9E7, 0x5BE7,
+	0xB9E8, 0x5BE1, 0xB9E9, 0x5BE5, 0xB9EA, 0x5BE6, 0xB9EB, 0x5BE8,
+	0xB9EC, 0x5BE2, 0xB9ED, 0x5BE4, 0xB9EE, 0x5BDF, 0xB9EF, 0x5C0D,
+	0xB9F0, 0x5C62, 0xB9F1, 0x5D84, 0xB9F2, 0x5D87, 0xB9F3, 0x5E5B,
+	0xB9F4, 0x5E63, 0xB9F5, 0x5E55, 0xB9F6, 0x5E57, 0xB9F7, 0x5E54,
+	0xB9F8, 0x5ED3, 0xB9F9, 0x5ED6, 0xB9FA, 0x5F0A, 0xB9FB, 0x5F46,
+	0xB9FC, 0x5F70, 0xB9FD, 0x5FB9, 0xB9FE, 0x6147, 0xBA40, 0x613F,
+	0xBA41, 0x614B, 0xBA42, 0x6177, 0xBA43, 0x6162, 0xBA44, 0x6163,
+	0xBA45, 0x615F, 0xBA46, 0x615A, 0xBA47, 0x6158, 0xBA48, 0x6175,
+	0xBA49, 0x622A, 0xBA4A, 0x6487, 0xBA4B, 0x6458, 0xBA4C, 0x6454,
+	0xBA4D, 0x64A4, 0xBA4E, 0x6478, 0xBA4F, 0x645F, 0xBA50, 0x647A,
+	0xBA51, 0x6451, 0xBA52, 0x6467, 0xBA53, 0x6434, 0xBA54, 0x646D,
+	0xBA55, 0x647B, 0xBA56, 0x6572, 0xBA57, 0x65A1, 0xBA58, 0x65D7,
+	0xBA59, 0x65D6, 0xBA5A, 0x66A2, 0xBA5B, 0x66A8, 0xBA5C, 0x669D,
+	0xBA5D, 0x699C, 0xBA5E, 0x69A8, 0xBA5F, 0x6995, 0xBA60, 0x69C1,
+	0xBA61, 0x69AE, 0xBA62, 0x69D3, 0xBA63, 0x69CB, 0xBA64, 0x699B,
+	0xBA65, 0x69B7, 0xBA66, 0x69BB, 0xBA67, 0x69AB, 0xBA68, 0x69B4,
+	0xBA69, 0x69D0, 0xBA6A, 0x69CD, 0xBA6B, 0x69AD, 0xBA6C, 0x69CC,
+	0xBA6D, 0x69A6, 0xBA6E, 0x69C3, 0xBA6F, 0x69A3, 0xBA70, 0x6B49,
+	0xBA71, 0x6B4C, 0xBA72, 0x6C33, 0xBA73, 0x6F33, 0xBA74, 0x6F14,
+	0xBA75, 0x6EFE, 0xBA76, 0x6F13, 0xBA77, 0x6EF4, 0xBA78, 0x6F29,
+	0xBA79, 0x6F3E, 0xBA7A, 0x6F20, 0xBA7B, 0x6F2C, 0xBA7C, 0x6F0F,
+	0xBA7D, 0x6F02, 0xBA7E, 0x6F22, 0xBAA1, 0x6EFF, 0xBAA2, 0x6EEF,
+	0xBAA3, 0x6F06, 0xBAA4, 0x6F31, 0xBAA5, 0x6F38, 0xBAA6, 0x6F32,
+	0xBAA7, 0x6F23, 0xBAA8, 0x6F15, 0xBAA9, 0x6F2B, 0xBAAA, 0x6F2F,
+	0xBAAB, 0x6F88, 0xBAAC, 0x6F2A, 0xBAAD, 0x6EEC, 0xBAAE, 0x6F01,
+	0xBAAF, 0x6EF2, 0xBAB0, 0x6ECC, 0xBAB1, 0x6EF7, 0xBAB2, 0x7194,
+	0xBAB3, 0x7199, 0xBAB4, 0x717D, 0xBAB5, 0x718A, 0xBAB6, 0x7184,
+	0xBAB7, 0x7192, 0xBAB8, 0x723E, 0xBAB9, 0x7292, 0xBABA, 0x7296,
+	0xBABB, 0x7344, 0xBABC, 0x7350, 0xBABD, 0x7464, 0xBABE, 0x7463,
+	0xBABF, 0x746A, 0xBAC0, 0x7470, 0xBAC1, 0x746D, 0xBAC2, 0x7504,
+	0xBAC3, 0x7591, 0xBAC4, 0x7627, 0xBAC5, 0x760D, 0xBAC6, 0x760B,
+	0xBAC7, 0x7609, 0xBAC8, 0x7613, 0xBAC9, 0x76E1, 0xBACA, 0x76E3,
+	0xBACB, 0x7784, 0xBACC, 0x777D, 0xBACD, 0x777F, 0xBACE, 0x7761,
+	0xBACF, 0x78C1, 0xBAD0, 0x789F, 0xBAD1, 0x78A7, 0xBAD2, 0x78B3,
+	0xBAD3, 0x78A9, 0xBAD4, 0x78A3, 0xBAD5, 0x798E, 0xBAD6, 0x798F,
+	0xBAD7, 0x798D, 0xBAD8, 0x7A2E, 0xBAD9, 0x7A31, 0xBADA, 0x7AAA,
+	0xBADB, 0x7AA9, 0xBADC, 0x7AED, 0xBADD, 0x7AEF, 0xBADE, 0x7BA1,
+	0xBADF, 0x7B95, 0xBAE0, 0x7B8B, 0xBAE1, 0x7B75, 0xBAE2, 0x7B97,
+	0xBAE3, 0x7B9D, 0xBAE4, 0x7B94, 0xBAE5, 0x7B8F, 0xBAE6, 0x7BB8,
+	0xBAE7, 0x7B87, 0xBAE8, 0x7B84, 0xBAE9, 0x7CB9, 0xBAEA, 0x7CBD,
+	0xBAEB, 0x7CBE, 0xBAEC, 0x7DBB, 0xBAED, 0x7DB0, 0xBAEE, 0x7D9C,
+	0xBAEF, 0x7DBD, 0xBAF0, 0x7DBE, 0xBAF1, 0x7DA0, 0xBAF2, 0x7DCA,
+	0xBAF3, 0x7DB4, 0xBAF4, 0x7DB2, 0xBAF5, 0x7DB1, 0xBAF6, 0x7DBA,
+	0xBAF7, 0x7DA2, 0xBAF8, 0x7DBF, 0xBAF9, 0x7DB5, 0xBAFA, 0x7DB8,
+	0xBAFB, 0x7DAD, 0xBAFC, 0x7DD2, 0xBAFD, 0x7DC7, 0xBAFE, 0x7DAC,
+	0xBB40, 0x7F70, 0xBB41, 0x7FE0, 0xBB42, 0x7FE1, 0xBB43, 0x7FDF,
+	0xBB44, 0x805E, 0xBB45, 0x805A, 0xBB46, 0x8087, 0xBB47, 0x8150,
+	0xBB48, 0x8180, 0xBB49, 0x818F, 0xBB4A, 0x8188, 0xBB4B, 0x818A,
+	0xBB4C, 0x817F, 0xBB4D, 0x8182, 0xBB4E, 0x81E7, 0xBB4F, 0x81FA,
+	0xBB50, 0x8207, 0xBB51, 0x8214, 0xBB52, 0x821E, 0xBB53, 0x824B,
+	0xBB54, 0x84C9, 0xBB55, 0x84BF, 0xBB56, 0x84C6, 0xBB57, 0x84C4,
+	0xBB58, 0x8499, 0xBB59, 0x849E, 0xBB5A, 0x84B2, 0xBB5B, 0x849C,
+	0xBB5C, 0x84CB, 0xBB5D, 0x84B8, 0xBB5E, 0x84C0, 0xBB5F, 0x84D3,
+	0xBB60, 0x8490, 0xBB61, 0x84BC, 0xBB62, 0x84D1, 0xBB63, 0x84CA,
+	0xBB64, 0x873F, 0xBB65, 0x871C, 0xBB66, 0x873B, 0xBB67, 0x8722,
+	0xBB68, 0x8725, 0xBB69, 0x8734, 0xBB6A, 0x8718, 0xBB6B, 0x8755,
+	0xBB6C, 0x8737, 0xBB6D, 0x8729, 0xBB6E, 0x88F3, 0xBB6F, 0x8902,
+	0xBB70, 0x88F4, 0xBB71, 0x88F9, 0xBB72, 0x88F8, 0xBB73, 0x88FD,
+	0xBB74, 0x88E8, 0xBB75, 0x891A, 0xBB76, 0x88EF, 0xBB77, 0x8AA6,
+	0xBB78, 0x8A8C, 0xBB79, 0x8A9E, 0xBB7A, 0x8AA3, 0xBB7B, 0x8A8D,
+	0xBB7C, 0x8AA1, 0xBB7D, 0x8A93, 0xBB7E, 0x8AA4, 0xBBA1, 0x8AAA,
+	0xBBA2, 0x8AA5, 0xBBA3, 0x8AA8, 0xBBA4, 0x8A98, 0xBBA5, 0x8A91,
+	0xBBA6, 0x8A9A, 0xBBA7, 0x8AA7, 0xBBA8, 0x8C6A, 0xBBA9, 0x8C8D,
+	0xBBAA, 0x8C8C, 0xBBAB, 0x8CD3, 0xBBAC, 0x8CD1, 0xBBAD, 0x8CD2,
+	0xBBAE, 0x8D6B, 0xBBAF, 0x8D99, 0xBBB0, 0x8D95, 0xBBB1, 0x8DFC,
+	0xBBB2, 0x8F14, 0xBBB3, 0x8F12, 0xBBB4, 0x8F15, 0xBBB5, 0x8F13,
+	0xBBB6, 0x8FA3, 0xBBB7, 0x9060, 0xBBB8, 0x9058, 0xBBB9, 0x905C,
+	0xBBBA, 0x9063, 0xBBBB, 0x9059, 0xBBBC, 0x905E, 0xBBBD, 0x9062,
+	0xBBBE, 0x905D, 0xBBBF, 0x905B, 0xBBC0, 0x9119, 0xBBC1, 0x9118,
+	0xBBC2, 0x911E, 0xBBC3, 0x9175, 0xBBC4, 0x9178, 0xBBC5, 0x9177,
+	0xBBC6, 0x9174, 0xBBC7, 0x9278, 0xBBC8, 0x9280, 0xBBC9, 0x9285,
+	0xBBCA, 0x9298, 0xBBCB, 0x9296, 0xBBCC, 0x927B, 0xBBCD, 0x9293,
+	0xBBCE, 0x929C, 0xBBCF, 0x92A8, 0xBBD0, 0x927C, 0xBBD1, 0x9291,
+	0xBBD2, 0x95A1, 0xBBD3, 0x95A8, 0xBBD4, 0x95A9, 0xBBD5, 0x95A3,
+	0xBBD6, 0x95A5, 0xBBD7, 0x95A4, 0xBBD8, 0x9699, 0xBBD9, 0x969C,
+	0xBBDA, 0x969B, 0xBBDB, 0x96CC, 0xBBDC, 0x96D2, 0xBBDD, 0x9700,
+	0xBBDE, 0x977C, 0xBBDF, 0x9785, 0xBBE0, 0x97F6, 0xBBE1, 0x9817,
+	0xBBE2, 0x9818, 0xBBE3, 0x98AF, 0xBBE4, 0x98B1, 0xBBE5, 0x9903,
+	0xBBE6, 0x9905, 0xBBE7, 0x990C, 0xBBE8, 0x9909, 0xBBE9, 0x99C1,
+	0xBBEA, 0x9AAF, 0xBBEB, 0x9AB0, 0xBBEC, 0x9AE6, 0xBBED, 0x9B41,
+	0xBBEE, 0x9B42, 0xBBEF, 0x9CF4, 0xBBF0, 0x9CF6, 0xBBF1, 0x9CF3,
+	0xBBF2, 0x9EBC, 0xBBF3, 0x9F3B, 0xBBF4, 0x9F4A, 0xBBF5, 0x5104,
+	0xBBF6, 0x5100, 0xBBF7, 0x50FB, 0xBBF8, 0x50F5, 0xBBF9, 0x50F9,
+	0xBBFA, 0x5102, 0xBBFB, 0x5108, 0xBBFC, 0x5109, 0xBBFD, 0x5105,
+	0xBBFE, 0x51DC, 0xBC40, 0x5287, 0xBC41, 0x5288, 0xBC42, 0x5289,
+	0xBC43, 0x528D, 0xBC44, 0x528A, 0xBC45, 0x52F0, 0xBC46, 0x53B2,
+	0xBC47, 0x562E, 0xBC48, 0x563B, 0xBC49, 0x5639, 0xBC4A, 0x5632,
+	0xBC4B, 0x563F, 0xBC4C, 0x5634, 0xBC4D, 0x5629, 0xBC4E, 0x5653,
+	0xBC4F, 0x564E, 0xBC50, 0x5657, 0xBC51, 0x5674, 0xBC52, 0x5636,
+	0xBC53, 0x562F, 0xBC54, 0x5630, 0xBC55, 0x5880, 0xBC56, 0x589F,
+	0xBC57, 0x589E, 0xBC58, 0x58B3, 0xBC59, 0x589C, 0xBC5A, 0x58AE,
+	0xBC5B, 0x58A9, 0xBC5C, 0x58A6, 0xBC5D, 0x596D, 0xBC5E, 0x5B09,
+	0xBC5F, 0x5AFB, 0xBC60, 0x5B0B, 0xBC61, 0x5AF5, 0xBC62, 0x5B0C,
+	0xBC63, 0x5B08, 0xBC64, 0x5BEE, 0xBC65, 0x5BEC, 0xBC66, 0x5BE9,
+	0xBC67, 0x5BEB, 0xBC68, 0x5C64, 0xBC69, 0x5C65, 0xBC6A, 0x5D9D,
+	0xBC6B, 0x5D94, 0xBC6C, 0x5E62, 0xBC6D, 0x5E5F, 0xBC6E, 0x5E61,
+	0xBC6F, 0x5EE2, 0xBC70, 0x5EDA, 0xBC71, 0x5EDF, 0xBC72, 0x5EDD,
+	0xBC73, 0x5EE3, 0xBC74, 0x5EE0, 0xBC75, 0x5F48, 0xBC76, 0x5F71,
+	0xBC77, 0x5FB7, 0xBC78, 0x5FB5, 0xBC79, 0x6176, 0xBC7A, 0x6167,
+	0xBC7B, 0x616E, 0xBC7C, 0x615D, 0xBC7D, 0x6155, 0xBC7E, 0x6182,
+	0xBCA1, 0x617C, 0xBCA2, 0x6170, 0xBCA3, 0x616B, 0xBCA4, 0x617E,
+	0xBCA5, 0x61A7, 0xBCA6, 0x6190, 0xBCA7, 0x61AB, 0xBCA8, 0x618E,
+	0xBCA9, 0x61AC, 0xBCAA, 0x619A, 0xBCAB, 0x61A4, 0xBCAC, 0x6194,
+	0xBCAD, 0x61AE, 0xBCAE, 0x622E, 0xBCAF, 0x6469, 0xBCB0, 0x646F,
+	0xBCB1, 0x6479, 0xBCB2, 0x649E, 0xBCB3, 0x64B2, 0xBCB4, 0x6488,
+	0xBCB5, 0x6490, 0xBCB6, 0x64B0, 0xBCB7, 0x64A5, 0xBCB8, 0x6493,
+	0xBCB9, 0x6495, 0xBCBA, 0x64A9, 0xBCBB, 0x6492, 0xBCBC, 0x64AE,
+	0xBCBD, 0x64AD, 0xBCBE, 0x64AB, 0xBCBF, 0x649A, 0xBCC0, 0x64AC,
+	0xBCC1, 0x6499, 0xBCC2, 0x64A2, 0xBCC3, 0x64B3, 0xBCC4, 0x6575,
+	0xBCC5, 0x6577, 0xBCC6, 0x6578, 0xBCC7, 0x66AE, 0xBCC8, 0x66AB,
+	0xBCC9, 0x66B4, 0xBCCA, 0x66B1, 0xBCCB, 0x6A23, 0xBCCC, 0x6A1F,
+	0xBCCD, 0x69E8, 0xBCCE, 0x6A01, 0xBCCF, 0x6A1E, 0xBCD0, 0x6A19,
+	0xBCD1, 0x69FD, 0xBCD2, 0x6A21, 0xBCD3, 0x6A13, 0xBCD4, 0x6A0A,
+	0xBCD5, 0x69F3, 0xBCD6, 0x6A02, 0xBCD7, 0x6A05, 0xBCD8, 0x69ED,
+	0xBCD9, 0x6A11, 0xBCDA, 0x6B50, 0xBCDB, 0x6B4E, 0xBCDC, 0x6BA4,
+	0xBCDD, 0x6BC5, 0xBCDE, 0x6BC6, 0xBCDF, 0x6F3F, 0xBCE0, 0x6F7C,
+	0xBCE1, 0x6F84, 0xBCE2, 0x6F51, 0xBCE3, 0x6F66, 0xBCE4, 0x6F54,
+	0xBCE5, 0x6F86, 0xBCE6, 0x6F6D, 0xBCE7, 0x6F5B, 0xBCE8, 0x6F78,
+	0xBCE9, 0x6F6E, 0xBCEA, 0x6F8E, 0xBCEB, 0x6F7A, 0xBCEC, 0x6F70,
+	0xBCED, 0x6F64, 0xBCEE, 0x6F97, 0xBCEF, 0x6F58, 0xBCF0, 0x6ED5,
+	0xBCF1, 0x6F6F, 0xBCF2, 0x6F60, 0xBCF3, 0x6F5F, 0xBCF4, 0x719F,
+	0xBCF5, 0x71AC, 0xBCF6, 0x71B1, 0xBCF7, 0x71A8, 0xBCF8, 0x7256,
+	0xBCF9, 0x729B, 0xBCFA, 0x734E, 0xBCFB, 0x7357, 0xBCFC, 0x7469,
+	0xBCFD, 0x748B, 0xBCFE, 0x7483, 0xBD40, 0x747E, 0xBD41, 0x7480,
+	0xBD42, 0x757F, 0xBD43, 0x7620, 0xBD44, 0x7629, 0xBD45, 0x761F,
+	0xBD46, 0x7624, 0xBD47, 0x7626, 0xBD48, 0x7621, 0xBD49, 0x7622,
+	0xBD4A, 0x769A, 0xBD4B, 0x76BA, 0xBD4C, 0x76E4, 0xBD4D, 0x778E,
+	0xBD4E, 0x7787, 0xBD4F, 0x778C, 0xBD50, 0x7791, 0xBD51, 0x778B,
+	0xBD52, 0x78CB, 0xBD53, 0x78C5, 0xBD54, 0x78BA, 0xBD55, 0x78CA,
+	0xBD56, 0x78BE, 0xBD57, 0x78D5, 0xBD58, 0x78BC, 0xBD59, 0x78D0,
+	0xBD5A, 0x7A3F, 0xBD5B, 0x7A3C, 0xBD5C, 0x7A40, 0xBD5D, 0x7A3D,
+	0xBD5E, 0x7A37, 0xBD5F, 0x7A3B, 0xBD60, 0x7AAF, 0xBD61, 0x7AAE,
+	0xBD62, 0x7BAD, 0xBD63, 0x7BB1, 0xBD64, 0x7BC4, 0xBD65, 0x7BB4,
+	0xBD66, 0x7BC6, 0xBD67, 0x7BC7, 0xBD68, 0x7BC1, 0xBD69, 0x7BA0,
+	0xBD6A, 0x7BCC, 0xBD6B, 0x7CCA, 0xBD6C, 0x7DE0, 0xBD6D, 0x7DF4,
+	0xBD6E, 0x7DEF, 0xBD6F, 0x7DFB, 0xBD70, 0x7DD8, 0xBD71, 0x7DEC,
+	0xBD72, 0x7DDD, 0xBD73, 0x7DE8, 0xBD74, 0x7DE3, 0xBD75, 0x7DDA,
+	0xBD76, 0x7DDE, 0xBD77, 0x7DE9, 0xBD78, 0x7D9E, 0xBD79, 0x7DD9,
+	0xBD7A, 0x7DF2, 0xBD7B, 0x7DF9, 0xBD7C, 0x7F75, 0xBD7D, 0x7F77,
+	0xBD7E, 0x7FAF, 0xBDA1, 0x7FE9, 0xBDA2, 0x8026, 0xBDA3, 0x819B,
+	0xBDA4, 0x819C, 0xBDA5, 0x819D, 0xBDA6, 0x81A0, 0xBDA7, 0x819A,
+	0xBDA8, 0x8198, 0xBDA9, 0x8517, 0xBDAA, 0x853D, 0xBDAB, 0x851A,
+	0xBDAC, 0x84EE, 0xBDAD, 0x852C, 0xBDAE, 0x852D, 0xBDAF, 0x8513,
+	0xBDB0, 0x8511, 0xBDB1, 0x8523, 0xBDB2, 0x8521, 0xBDB3, 0x8514,
+	0xBDB4, 0x84EC, 0xBDB5, 0x8525, 0xBDB6, 0x84FF, 0xBDB7, 0x8506,
+	0xBDB8, 0x8782, 0xBDB9, 0x8774, 0xBDBA, 0x8776, 0xBDBB, 0x8760,
+	0xBDBC, 0x8766, 0xBDBD, 0x8778, 0xBDBE, 0x8768, 0xBDBF, 0x8759,
+	0xBDC0, 0x8757, 0xBDC1, 0x874C, 0xBDC2, 0x8753, 0xBDC3, 0x885B,
+	0xBDC4, 0x885D, 0xBDC5, 0x8910, 0xBDC6, 0x8907, 0xBDC7, 0x8912,
+	0xBDC8, 0x8913, 0xBDC9, 0x8915, 0xBDCA, 0x890A, 0xBDCB, 0x8ABC,
+	0xBDCC, 0x8AD2, 0xBDCD, 0x8AC7, 0xBDCE, 0x8AC4, 0xBDCF, 0x8A95,
+	0xBDD0, 0x8ACB, 0xBDD1, 0x8AF8, 0xBDD2, 0x8AB2, 0xBDD3, 0x8AC9,
+	0xBDD4, 0x8AC2, 0xBDD5, 0x8ABF, 0xBDD6, 0x8AB0, 0xBDD7, 0x8AD6,
+	0xBDD8, 0x8ACD, 0xBDD9, 0x8AB6, 0xBDDA, 0x8AB9, 0xBDDB, 0x8ADB,
+	0xBDDC, 0x8C4C, 0xBDDD, 0x8C4E, 0xBDDE, 0x8C6C, 0xBDDF, 0x8CE0,
+	0xBDE0, 0x8CDE, 0xBDE1, 0x8CE6, 0xBDE2, 0x8CE4, 0xBDE3, 0x8CEC,
+	0xBDE4, 0x8CED, 0xBDE5, 0x8CE2, 0xBDE6, 0x8CE3, 0xBDE7, 0x8CDC,
+	0xBDE8, 0x8CEA, 0xBDE9, 0x8CE1, 0xBDEA, 0x8D6D, 0xBDEB, 0x8D9F,
+	0xBDEC, 0x8DA3, 0xBDED, 0x8E2B, 0xBDEE, 0x8E10, 0xBDEF, 0x8E1D,
+	0xBDF0, 0x8E22, 0xBDF1, 0x8E0F, 0xBDF2, 0x8E29, 0xBDF3, 0x8E1F,
+	0xBDF4, 0x8E21, 0xBDF5, 0x8E1E, 0xBDF6, 0x8EBA, 0xBDF7, 0x8F1D,
+	0xBDF8, 0x8F1B, 0xBDF9, 0x8F1F, 0xBDFA, 0x8F29, 0xBDFB, 0x8F26,
+	0xBDFC, 0x8F2A, 0xBDFD, 0x8F1C, 0xBDFE, 0x8F1E, 0xBE40, 0x8F25,
+	0xBE41, 0x9069, 0xBE42, 0x906E, 0xBE43, 0x9068, 0xBE44, 0x906D,
+	0xBE45, 0x9077, 0xBE46, 0x9130, 0xBE47, 0x912D, 0xBE48, 0x9127,
+	0xBE49, 0x9131, 0xBE4A, 0x9187, 0xBE4B, 0x9189, 0xBE4C, 0x918B,
+	0xBE4D, 0x9183, 0xBE4E, 0x92C5, 0xBE4F, 0x92BB, 0xBE50, 0x92B7,
+	0xBE51, 0x92EA, 0xBE52, 0x92AC, 0xBE53, 0x92E4, 0xBE54, 0x92C1,
+	0xBE55, 0x92B3, 0xBE56, 0x92BC, 0xBE57, 0x92D2, 0xBE58, 0x92C7,
+	0xBE59, 0x92F0, 0xBE5A, 0x92B2, 0xBE5B, 0x95AD, 0xBE5C, 0x95B1,
+	0xBE5D, 0x9704, 0xBE5E, 0x9706, 0xBE5F, 0x9707, 0xBE60, 0x9709,
+	0xBE61, 0x9760, 0xBE62, 0x978D, 0xBE63, 0x978B, 0xBE64, 0x978F,
+	0xBE65, 0x9821, 0xBE66, 0x982B, 0xBE67, 0x981C, 0xBE68, 0x98B3,
+	0xBE69, 0x990A, 0xBE6A, 0x9913, 0xBE6B, 0x9912, 0xBE6C, 0x9918,
+	0xBE6D, 0x99DD, 0xBE6E, 0x99D0, 0xBE6F, 0x99DF, 0xBE70, 0x99DB,
+	0xBE71, 0x99D1, 0xBE72, 0x99D5, 0xBE73, 0x99D2, 0xBE74, 0x99D9,
+	0xBE75, 0x9AB7, 0xBE76, 0x9AEE, 0xBE77, 0x9AEF, 0xBE78, 0x9B27,
+	0xBE79, 0x9B45, 0xBE7A, 0x9B44, 0xBE7B, 0x9B77, 0xBE7C, 0x9B6F,
+	0xBE7D, 0x9D06, 0xBE7E, 0x9D09, 0xBEA1, 0x9D03, 0xBEA2, 0x9EA9,
+	0xBEA3, 0x9EBE, 0xBEA4, 0x9ECE, 0xBEA5, 0x58A8, 0xBEA6, 0x9F52,
+	0xBEA7, 0x5112, 0xBEA8, 0x5118, 0xBEA9, 0x5114, 0xBEAA, 0x5110,
+	0xBEAB, 0x5115, 0xBEAC, 0x5180, 0xBEAD, 0x51AA, 0xBEAE, 0x51DD,
+	0xBEAF, 0x5291, 0xBEB0, 0x5293, 0xBEB1, 0x52F3, 0xBEB2, 0x5659,
+	0xBEB3, 0x566B, 0xBEB4, 0x5679, 0xBEB5, 0x5669, 0xBEB6, 0x5664,
+	0xBEB7, 0x5678, 0xBEB8, 0x566A, 0xBEB9, 0x5668, 0xBEBA, 0x5665,
+	0xBEBB, 0x5671, 0xBEBC, 0x566F, 0xBEBD, 0x566C, 0xBEBE, 0x5662,
+	0xBEBF, 0x5676, 0xBEC0, 0x58C1, 0xBEC1, 0x58BE, 0xBEC2, 0x58C7,
+	0xBEC3, 0x58C5, 0xBEC4, 0x596E, 0xBEC5, 0x5B1D, 0xBEC6, 0x5B34,
+	0xBEC7, 0x5B78, 0xBEC8, 0x5BF0, 0xBEC9, 0x5C0E, 0xBECA, 0x5F4A,
+	0xBECB, 0x61B2, 0xBECC, 0x6191, 0xBECD, 0x61A9, 0xBECE, 0x618A,
+	0xBECF, 0x61CD, 0xBED0, 0x61B6, 0xBED1, 0x61BE, 0xBED2, 0x61CA,
+	0xBED3, 0x61C8, 0xBED4, 0x6230, 0xBED5, 0x64C5, 0xBED6, 0x64C1,
+	0xBED7, 0x64CB, 0xBED8, 0x64BB, 0xBED9, 0x64BC, 0xBEDA, 0x64DA,
+	0xBEDB, 0x64C4, 0xBEDC, 0x64C7, 0xBEDD, 0x64C2, 0xBEDE, 0x64CD,
+	0xBEDF, 0x64BF, 0xBEE0, 0x64D2, 0xBEE1, 0x64D4, 0xBEE2, 0x64BE,
+	0xBEE3, 0x6574, 0xBEE4, 0x66C6, 0xBEE5, 0x66C9, 0xBEE6, 0x66B9,
+	0xBEE7, 0x66C4, 0xBEE8, 0x66C7, 0xBEE9, 0x66B8, 0xBEEA, 0x6A3D,
+	0xBEEB, 0x6A38, 0xBEEC, 0x6A3A, 0xBEED, 0x6A59, 0xBEEE, 0x6A6B,
+	0xBEEF, 0x6A58, 0xBEF0, 0x6A39, 0xBEF1, 0x6A44, 0xBEF2, 0x6A62,
+	0xBEF3, 0x6A61, 0xBEF4, 0x6A4B, 0xBEF5, 0x6A47, 0xBEF6, 0x6A35,
+	0xBEF7, 0x6A5F, 0xBEF8, 0x6A48, 0xBEF9, 0x6B59, 0xBEFA, 0x6B77,
+	0xBEFB, 0x6C05, 0xBEFC, 0x6FC2, 0xBEFD, 0x6FB1, 0xBEFE, 0x6FA1,
+	0xBF40, 0x6FC3, 0xBF41, 0x6FA4, 0xBF42, 0x6FC1, 0xBF43, 0x6FA7,
+	0xBF44, 0x6FB3, 0xBF45, 0x6FC0, 0xBF46, 0x6FB9, 0xBF47, 0x6FB6,
+	0xBF48, 0x6FA6, 0xBF49, 0x6FA0, 0xBF4A, 0x6FB4, 0xBF4B, 0x71BE,
+	0xBF4C, 0x71C9, 0xBF4D, 0x71D0, 0xBF4E, 0x71D2, 0xBF4F, 0x71C8,
+	0xBF50, 0x71D5, 0xBF51, 0x71B9, 0xBF52, 0x71CE, 0xBF53, 0x71D9,
+	0xBF54, 0x71DC, 0xBF55, 0x71C3, 0xBF56, 0x71C4, 0xBF57, 0x7368,
+	0xBF58, 0x749C, 0xBF59, 0x74A3, 0xBF5A, 0x7498, 0xBF5B, 0x749F,
+	0xBF5C, 0x749E, 0xBF5D, 0x74E2, 0xBF5E, 0x750C, 0xBF5F, 0x750D,
+	0xBF60, 0x7634, 0xBF61, 0x7638, 0xBF62, 0x763A, 0xBF63, 0x76E7,
+	0xBF64, 0x76E5, 0xBF65, 0x77A0, 0xBF66, 0x779E, 0xBF67, 0x779F,
+	0xBF68, 0x77A5, 0xBF69, 0x78E8, 0xBF6A, 0x78DA, 0xBF6B, 0x78EC,
+	0xBF6C, 0x78E7, 0xBF6D, 0x79A6, 0xBF6E, 0x7A4D, 0xBF6F, 0x7A4E,
+	0xBF70, 0x7A46, 0xBF71, 0x7A4C, 0xBF72, 0x7A4B, 0xBF73, 0x7ABA,
+	0xBF74, 0x7BD9, 0xBF75, 0x7C11, 0xBF76, 0x7BC9, 0xBF77, 0x7BE4,
+	0xBF78, 0x7BDB, 0xBF79, 0x7BE1, 0xBF7A, 0x7BE9, 0xBF7B, 0x7BE6,
+	0xBF7C, 0x7CD5, 0xBF7D, 0x7CD6, 0xBF7E, 0x7E0A, 0xBFA1, 0x7E11,
+	0xBFA2, 0x7E08, 0xBFA3, 0x7E1B, 0xBFA4, 0x7E23, 0xBFA5, 0x7E1E,
+	0xBFA6, 0x7E1D, 0xBFA7, 0x7E09, 0xBFA8, 0x7E10, 0xBFA9, 0x7F79,
+	0xBFAA, 0x7FB2, 0xBFAB, 0x7FF0, 0xBFAC, 0x7FF1, 0xBFAD, 0x7FEE,
+	0xBFAE, 0x8028, 0xBFAF, 0x81B3, 0xBFB0, 0x81A9, 0xBFB1, 0x81A8,
+	0xBFB2, 0x81FB, 0xBFB3, 0x8208, 0xBFB4, 0x8258, 0xBFB5, 0x8259,
+	0xBFB6, 0x854A, 0xBFB7, 0x8559, 0xBFB8, 0x8548, 0xBFB9, 0x8568,
+	0xBFBA, 0x8569, 0xBFBB, 0x8543, 0xBFBC, 0x8549, 0xBFBD, 0x856D,
+	0xBFBE, 0x856A, 0xBFBF, 0x855E, 0xBFC0, 0x8783, 0xBFC1, 0x879F,
+	0xBFC2, 0x879E, 0xBFC3, 0x87A2, 0xBFC4, 0x878D, 0xBFC5, 0x8861,
+	0xBFC6, 0x892A, 0xBFC7, 0x8932, 0xBFC8, 0x8925, 0xBFC9, 0x892B,
+	0xBFCA, 0x8921, 0xBFCB, 0x89AA, 0xBFCC, 0x89A6, 0xBFCD, 0x8AE6,
+	0xBFCE, 0x8AFA, 0xBFCF, 0x8AEB, 0xBFD0, 0x8AF1, 0xBFD1, 0x8B00,
+	0xBFD2, 0x8ADC, 0xBFD3, 0x8AE7, 0xBFD4, 0x8AEE, 0xBFD5, 0x8AFE,
+	0xBFD6, 0x8B01, 0xBFD7, 0x8B02, 0xBFD8, 0x8AF7, 0xBFD9, 0x8AED,
+	0xBFDA, 0x8AF3, 0xBFDB, 0x8AF6, 0xBFDC, 0x8AFC, 0xBFDD, 0x8C6B,
+	0xBFDE, 0x8C6D, 0xBFDF, 0x8C93, 0xBFE0, 0x8CF4, 0xBFE1, 0x8E44,
+	0xBFE2, 0x8E31, 0xBFE3, 0x8E34, 0xBFE4, 0x8E42, 0xBFE5, 0x8E39,
+	0xBFE6, 0x8E35, 0xBFE7, 0x8F3B, 0xBFE8, 0x8F2F, 0xBFE9, 0x8F38,
+	0xBFEA, 0x8F33, 0xBFEB, 0x8FA8, 0xBFEC, 0x8FA6, 0xBFED, 0x9075,
+	0xBFEE, 0x9074, 0xBFEF, 0x9078, 0xBFF0, 0x9072, 0xBFF1, 0x907C,
+	0xBFF2, 0x907A, 0xBFF3, 0x9134, 0xBFF4, 0x9192, 0xBFF5, 0x9320,
+	0xBFF6, 0x9336, 0xBFF7, 0x92F8, 0xBFF8, 0x9333, 0xBFF9, 0x932F,
+	0xBFFA, 0x9322, 0xBFFB, 0x92FC, 0xBFFC, 0x932B, 0xBFFD, 0x9304,
+	0xBFFE, 0x931A, 0xC040, 0x9310, 0xC041, 0x9326, 0xC042, 0x9321,
+	0xC043, 0x9315, 0xC044, 0x932E, 0xC045, 0x9319, 0xC046, 0x95BB,
+	0xC047, 0x96A7, 0xC048, 0x96A8, 0xC049, 0x96AA, 0xC04A, 0x96D5,
+	0xC04B, 0x970E, 0xC04C, 0x9711, 0xC04D, 0x9716, 0xC04E, 0x970D,
+	0xC04F, 0x9713, 0xC050, 0x970F, 0xC051, 0x975B, 0xC052, 0x975C,
+	0xC053, 0x9766, 0xC054, 0x9798, 0xC055, 0x9830, 0xC056, 0x9838,
+	0xC057, 0x983B, 0xC058, 0x9837, 0xC059, 0x982D, 0xC05A, 0x9839,
+	0xC05B, 0x9824, 0xC05C, 0x9910, 0xC05D, 0x9928, 0xC05E, 0x991E,
+	0xC05F, 0x991B, 0xC060, 0x9921, 0xC061, 0x991A, 0xC062, 0x99ED,
+	0xC063, 0x99E2, 0xC064, 0x99F1, 0xC065, 0x9AB8, 0xC066, 0x9ABC,
+	0xC067, 0x9AFB, 0xC068, 0x9AED, 0xC069, 0x9B28, 0xC06A, 0x9B91,
+	0xC06B, 0x9D15, 0xC06C, 0x9D23, 0xC06D, 0x9D26, 0xC06E, 0x9D28,
+	0xC06F, 0x9D12, 0xC070, 0x9D1B, 0xC071, 0x9ED8, 0xC072, 0x9ED4,
+	0xC073, 0x9F8D, 0xC074, 0x9F9C, 0xC075, 0x512A, 0xC076, 0x511F,
+	0xC077, 0x5121, 0xC078, 0x5132, 0xC079, 0x52F5, 0xC07A, 0x568E,
+	0xC07B, 0x5680, 0xC07C, 0x5690, 0xC07D, 0x5685, 0xC07E, 0x5687,
+	0xC0A1, 0x568F, 0xC0A2, 0x58D5, 0xC0A3, 0x58D3, 0xC0A4, 0x58D1,
+	0xC0A5, 0x58CE, 0xC0A6, 0x5B30, 0xC0A7, 0x5B2A, 0xC0A8, 0x5B24,
+	0xC0A9, 0x5B7A, 0xC0AA, 0x5C37, 0xC0AB, 0x5C68, 0xC0AC, 0x5DBC,
+	0xC0AD, 0x5DBA, 0xC0AE, 0x5DBD, 0xC0AF, 0x5DB8, 0xC0B0, 0x5E6B,
+	0xC0B1, 0x5F4C, 0xC0B2, 0x5FBD, 0xC0B3, 0x61C9, 0xC0B4, 0x61C2,
+	0xC0B5, 0x61C7, 0xC0B6, 0x61E6, 0xC0B7, 0x61CB, 0xC0B8, 0x6232,
+	0xC0B9, 0x6234, 0xC0BA, 0x64CE, 0xC0BB, 0x64CA, 0xC0BC, 0x64D8,
+	0xC0BD, 0x64E0, 0xC0BE, 0x64F0, 0xC0BF, 0x64E6, 0xC0C0, 0x64EC,
+	0xC0C1, 0x64F1, 0xC0C2, 0x64E2, 0xC0C3, 0x64ED, 0xC0C4, 0x6582,
+	0xC0C5, 0x6583, 0xC0C6, 0x66D9, 0xC0C7, 0x66D6, 0xC0C8, 0x6A80,
+	0xC0C9, 0x6A94, 0xC0CA, 0x6A84, 0xC0CB, 0x6AA2, 0xC0CC, 0x6A9C,
+	0xC0CD, 0x6ADB, 0xC0CE, 0x6AA3, 0xC0CF, 0x6A7E, 0xC0D0, 0x6A97,
+	0xC0D1, 0x6A90, 0xC0D2, 0x6AA0, 0xC0D3, 0x6B5C, 0xC0D4, 0x6BAE,
+	0xC0D5, 0x6BDA, 0xC0D6, 0x6C08, 0xC0D7, 0x6FD8, 0xC0D8, 0x6FF1,
+	0xC0D9, 0x6FDF, 0xC0DA, 0x6FE0, 0xC0DB, 0x6FDB, 0xC0DC, 0x6FE4,
+	0xC0DD, 0x6FEB, 0xC0DE, 0x6FEF, 0xC0DF, 0x6F80, 0xC0E0, 0x6FEC,
+	0xC0E1, 0x6FE1, 0xC0E2, 0x6FE9, 0xC0E3, 0x6FD5, 0xC0E4, 0x6FEE,
+	0xC0E5, 0x6FF0, 0xC0E6, 0x71E7, 0xC0E7, 0x71DF, 0xC0E8, 0x71EE,
+	0xC0E9, 0x71E6, 0xC0EA, 0x71E5, 0xC0EB, 0x71ED, 0xC0EC, 0x71EC,
+	0xC0ED, 0x71F4, 0xC0EE, 0x71E0, 0xC0EF, 0x7235, 0xC0F0, 0x7246,
+	0xC0F1, 0x7370, 0xC0F2, 0x7372, 0xC0F3, 0x74A9, 0xC0F4, 0x74B0,
+	0xC0F5, 0x74A6, 0xC0F6, 0x74A8, 0xC0F7, 0x7646, 0xC0F8, 0x7642,
+	0xC0F9, 0x764C, 0xC0FA, 0x76EA, 0xC0FB, 0x77B3, 0xC0FC, 0x77AA,
+	0xC0FD, 0x77B0, 0xC0FE, 0x77AC, 0xC140, 0x77A7, 0xC141, 0x77AD,
+	0xC142, 0x77EF, 0xC143, 0x78F7, 0xC144, 0x78FA, 0xC145, 0x78F4,
+	0xC146, 0x78EF, 0xC147, 0x7901, 0xC148, 0x79A7, 0xC149, 0x79AA,
+	0xC14A, 0x7A57, 0xC14B, 0x7ABF, 0xC14C, 0x7C07, 0xC14D, 0x7C0D,
+	0xC14E, 0x7BFE, 0xC14F, 0x7BF7, 0xC150, 0x7C0C, 0xC151, 0x7BE0,
+	0xC152, 0x7CE0, 0xC153, 0x7CDC, 0xC154, 0x7CDE, 0xC155, 0x7CE2,
+	0xC156, 0x7CDF, 0xC157, 0x7CD9, 0xC158, 0x7CDD, 0xC159, 0x7E2E,
+	0xC15A, 0x7E3E, 0xC15B, 0x7E46, 0xC15C, 0x7E37, 0xC15D, 0x7E32,
+	0xC15E, 0x7E43, 0xC15F, 0x7E2B, 0xC160, 0x7E3D, 0xC161, 0x7E31,
+	0xC162, 0x7E45, 0xC163, 0x7E41, 0xC164, 0x7E34, 0xC165, 0x7E39,
+	0xC166, 0x7E48, 0xC167, 0x7E35, 0xC168, 0x7E3F, 0xC169, 0x7E2F,
+	0xC16A, 0x7F44, 0xC16B, 0x7FF3, 0xC16C, 0x7FFC, 0xC16D, 0x8071,
+	0xC16E, 0x8072, 0xC16F, 0x8070, 0xC170, 0x806F, 0xC171, 0x8073,
+	0xC172, 0x81C6, 0xC173, 0x81C3, 0xC174, 0x81BA, 0xC175, 0x81C2,
+	0xC176, 0x81C0, 0xC177, 0x81BF, 0xC178, 0x81BD, 0xC179, 0x81C9,
+	0xC17A, 0x81BE, 0xC17B, 0x81E8, 0xC17C, 0x8209, 0xC17D, 0x8271,
+	0xC17E, 0x85AA, 0xC1A1, 0x8584, 0xC1A2, 0x857E, 0xC1A3, 0x859C,
+	0xC1A4, 0x8591, 0xC1A5, 0x8594, 0xC1A6, 0x85AF, 0xC1A7, 0x859B,
+	0xC1A8, 0x8587, 0xC1A9, 0x85A8, 0xC1AA, 0x858A, 0xC1AB, 0x8667,
+	0xC1AC, 0x87C0, 0xC1AD, 0x87D1, 0xC1AE, 0x87B3, 0xC1AF, 0x87D2,
+	0xC1B0, 0x87C6, 0xC1B1, 0x87AB, 0xC1B2, 0x87BB, 0xC1B3, 0x87BA,
+	0xC1B4, 0x87C8, 0xC1B5, 0x87CB, 0xC1B6, 0x893B, 0xC1B7, 0x8936,
+	0xC1B8, 0x8944, 0xC1B9, 0x8938, 0xC1BA, 0x893D, 0xC1BB, 0x89AC,
+	0xC1BC, 0x8B0E, 0xC1BD, 0x8B17, 0xC1BE, 0x8B19, 0xC1BF, 0x8B1B,
+	0xC1C0, 0x8B0A, 0xC1C1, 0x8B20, 0xC1C2, 0x8B1D, 0xC1C3, 0x8B04,
+	0xC1C4, 0x8B10, 0xC1C5, 0x8C41, 0xC1C6, 0x8C3F, 0xC1C7, 0x8C73,
+	0xC1C8, 0x8CFA, 0xC1C9, 0x8CFD, 0xC1CA, 0x8CFC, 0xC1CB, 0x8CF8,
+	0xC1CC, 0x8CFB, 0xC1CD, 0x8DA8, 0xC1CE, 0x8E49, 0xC1CF, 0x8E4B,
+	0xC1D0, 0x8E48, 0xC1D1, 0x8E4A, 0xC1D2, 0x8F44, 0xC1D3, 0x8F3E,
+	0xC1D4, 0x8F42, 0xC1D5, 0x8F45, 0xC1D6, 0x8F3F, 0xC1D7, 0x907F,
+	0xC1D8, 0x907D, 0xC1D9, 0x9084, 0xC1DA, 0x9081, 0xC1DB, 0x9082,
+	0xC1DC, 0x9080, 0xC1DD, 0x9139, 0xC1DE, 0x91A3, 0xC1DF, 0x919E,
+	0xC1E0, 0x919C, 0xC1E1, 0x934D, 0xC1E2, 0x9382, 0xC1E3, 0x9328,
+	0xC1E4, 0x9375, 0xC1E5, 0x934A, 0xC1E6, 0x9365, 0xC1E7, 0x934B,
+	0xC1E8, 0x9318, 0xC1E9, 0x937E, 0xC1EA, 0x936C, 0xC1EB, 0x935B,
+	0xC1EC, 0x9370, 0xC1ED, 0x935A, 0xC1EE, 0x9354, 0xC1EF, 0x95CA,
+	0xC1F0, 0x95CB, 0xC1F1, 0x95CC, 0xC1F2, 0x95C8, 0xC1F3, 0x95C6,
+	0xC1F4, 0x96B1, 0xC1F5, 0x96B8, 0xC1F6, 0x96D6, 0xC1F7, 0x971C,
+	0xC1F8, 0x971E, 0xC1F9, 0x97A0, 0xC1FA, 0x97D3, 0xC1FB, 0x9846,
+	0xC1FC, 0x98B6, 0xC1FD, 0x9935, 0xC1FE, 0x9A01, 0xC240, 0x99FF,
+	0xC241, 0x9BAE, 0xC242, 0x9BAB, 0xC243, 0x9BAA, 0xC244, 0x9BAD,
+	0xC245, 0x9D3B, 0xC246, 0x9D3F, 0xC247, 0x9E8B, 0xC248, 0x9ECF,
+	0xC249, 0x9EDE, 0xC24A, 0x9EDC, 0xC24B, 0x9EDD, 0xC24C, 0x9EDB,
+	0xC24D, 0x9F3E, 0xC24E, 0x9F4B, 0xC24F, 0x53E2, 0xC250, 0x5695,
+	0xC251, 0x56AE, 0xC252, 0x58D9, 0xC253, 0x58D8, 0xC254, 0x5B38,
+	0xC255, 0x5F5D, 0xC256, 0x61E3, 0xC257, 0x6233, 0xC258, 0x64F4,
+	0xC259, 0x64F2, 0xC25A, 0x64FE, 0xC25B, 0x6506, 0xC25C, 0x64FA,
+	0xC25D, 0x64FB, 0xC25E, 0x64F7, 0xC25F, 0x65B7, 0xC260, 0x66DC,
+	0xC261, 0x6726, 0xC262, 0x6AB3, 0xC263, 0x6AAC, 0xC264, 0x6AC3,
+	0xC265, 0x6ABB, 0xC266, 0x6AB8, 0xC267, 0x6AC2, 0xC268, 0x6AAE,
+	0xC269, 0x6AAF, 0xC26A, 0x6B5F, 0xC26B, 0x6B78, 0xC26C, 0x6BAF,
+	0xC26D, 0x7009, 0xC26E, 0x700B, 0xC26F, 0x6FFE, 0xC270, 0x7006,
+	0xC271, 0x6FFA, 0xC272, 0x7011, 0xC273, 0x700F, 0xC274, 0x71FB,
+	0xC275, 0x71FC, 0xC276, 0x71FE, 0xC277, 0x71F8, 0xC278, 0x7377,
+	0xC279, 0x7375, 0xC27A, 0x74A7, 0xC27B, 0x74BF, 0xC27C, 0x7515,
+	0xC27D, 0x7656, 0xC27E, 0x7658, 0xC2A1, 0x7652, 0xC2A2, 0x77BD,
+	0xC2A3, 0x77BF, 0xC2A4, 0x77BB, 0xC2A5, 0x77BC, 0xC2A6, 0x790E,
+	0xC2A7, 0x79AE, 0xC2A8, 0x7A61, 0xC2A9, 0x7A62, 0xC2AA, 0x7A60,
+	0xC2AB, 0x7AC4, 0xC2AC, 0x7AC5, 0xC2AD, 0x7C2B, 0xC2AE, 0x7C27,
+	0xC2AF, 0x7C2A, 0xC2B0, 0x7C1E, 0xC2B1, 0x7C23, 0xC2B2, 0x7C21,
+	0xC2B3, 0x7CE7, 0xC2B4, 0x7E54, 0xC2B5, 0x7E55, 0xC2B6, 0x7E5E,
+	0xC2B7, 0x7E5A, 0xC2B8, 0x7E61, 0xC2B9, 0x7E52, 0xC2BA, 0x7E59,
+	0xC2BB, 0x7F48, 0xC2BC, 0x7FF9, 0xC2BD, 0x7FFB, 0xC2BE, 0x8077,
+	0xC2BF, 0x8076, 0xC2C0, 0x81CD, 0xC2C1, 0x81CF, 0xC2C2, 0x820A,
+	0xC2C3, 0x85CF, 0xC2C4, 0x85A9, 0xC2C5, 0x85CD, 0xC2C6, 0x85D0,
+	0xC2C7, 0x85C9, 0xC2C8, 0x85B0, 0xC2C9, 0x85BA, 0xC2CA, 0x85B9,
+	0xC2CB, 0x85A6, 0xC2CC, 0x87EF, 0xC2CD, 0x87EC, 0xC2CE, 0x87F2,
+	0xC2CF, 0x87E0, 0xC2D0, 0x8986, 0xC2D1, 0x89B2, 0xC2D2, 0x89F4,
+	0xC2D3, 0x8B28, 0xC2D4, 0x8B39, 0xC2D5, 0x8B2C, 0xC2D6, 0x8B2B,
+	0xC2D7, 0x8C50, 0xC2D8, 0x8D05, 0xC2D9, 0x8E59, 0xC2DA, 0x8E63,
+	0xC2DB, 0x8E66, 0xC2DC, 0x8E64, 0xC2DD, 0x8E5F, 0xC2DE, 0x8E55,
+	0xC2DF, 0x8EC0, 0xC2E0, 0x8F49, 0xC2E1, 0x8F4D, 0xC2E2, 0x9087,
+	0xC2E3, 0x9083, 0xC2E4, 0x9088, 0xC2E5, 0x91AB, 0xC2E6, 0x91AC,
+	0xC2E7, 0x91D0, 0xC2E8, 0x9394, 0xC2E9, 0x938A, 0xC2EA, 0x9396,
+	0xC2EB, 0x93A2, 0xC2EC, 0x93B3, 0xC2ED, 0x93AE, 0xC2EE, 0x93AC,
+	0xC2EF, 0x93B0, 0xC2F0, 0x9398, 0xC2F1, 0x939A, 0xC2F2, 0x9397,
+	0xC2F3, 0x95D4, 0xC2F4, 0x95D6, 0xC2F5, 0x95D0, 0xC2F6, 0x95D5,
+	0xC2F7, 0x96E2, 0xC2F8, 0x96DC, 0xC2F9, 0x96D9, 0xC2FA, 0x96DB,
+	0xC2FB, 0x96DE, 0xC2FC, 0x9724, 0xC2FD, 0x97A3, 0xC2FE, 0x97A6,
+	0xC340, 0x97AD, 0xC341, 0x97F9, 0xC342, 0x984D, 0xC343, 0x984F,
+	0xC344, 0x984C, 0xC345, 0x984E, 0xC346, 0x9853, 0xC347, 0x98BA,
+	0xC348, 0x993E, 0xC349, 0x993F, 0xC34A, 0x993D, 0xC34B, 0x992E,
+	0xC34C, 0x99A5, 0xC34D, 0x9A0E, 0xC34E, 0x9AC1, 0xC34F, 0x9B03,
+	0xC350, 0x9B06, 0xC351, 0x9B4F, 0xC352, 0x9B4E, 0xC353, 0x9B4D,
+	0xC354, 0x9BCA, 0xC355, 0x9BC9, 0xC356, 0x9BFD, 0xC357, 0x9BC8,
+	0xC358, 0x9BC0, 0xC359, 0x9D51, 0xC35A, 0x9D5D, 0xC35B, 0x9D60,
+	0xC35C, 0x9EE0, 0xC35D, 0x9F15, 0xC35E, 0x9F2C, 0xC35F, 0x5133,
+	0xC360, 0x56A5, 0xC361, 0x58DE, 0xC362, 0x58DF, 0xC363, 0x58E2,
+	0xC364, 0x5BF5, 0xC365, 0x9F90, 0xC366, 0x5EEC, 0xC367, 0x61F2,
+	0xC368, 0x61F7, 0xC369, 0x61F6, 0xC36A, 0x61F5, 0xC36B, 0x6500,
+	0xC36C, 0x650F, 0xC36D, 0x66E0, 0xC36E, 0x66DD, 0xC36F, 0x6AE5,
+	0xC370, 0x6ADD, 0xC371, 0x6ADA, 0xC372, 0x6AD3, 0xC373, 0x701B,
+	0xC374, 0x701F, 0xC375, 0x7028, 0xC376, 0x701A, 0xC377, 0x701D,
+	0xC378, 0x7015, 0xC379, 0x7018, 0xC37A, 0x7206, 0xC37B, 0x720D,
+	0xC37C, 0x7258, 0xC37D, 0x72A2, 0xC37E, 0x7378, 0xC3A1, 0x737A,
+	0xC3A2, 0x74BD, 0xC3A3, 0x74CA, 0xC3A4, 0x74E3, 0xC3A5, 0x7587,
+	0xC3A6, 0x7586, 0xC3A7, 0x765F, 0xC3A8, 0x7661, 0xC3A9, 0x77C7,
+	0xC3AA, 0x7919, 0xC3AB, 0x79B1, 0xC3AC, 0x7A6B, 0xC3AD, 0x7A69,
+	0xC3AE, 0x7C3E, 0xC3AF, 0x7C3F, 0xC3B0, 0x7C38, 0xC3B1, 0x7C3D,
+	0xC3B2, 0x7C37, 0xC3B3, 0x7C40, 0xC3B4, 0x7E6B, 0xC3B5, 0x7E6D,
+	0xC3B6, 0x7E79, 0xC3B7, 0x7E69, 0xC3B8, 0x7E6A, 0xC3B9, 0x7F85,
+	0xC3BA, 0x7E73, 0xC3BB, 0x7FB6, 0xC3BC, 0x7FB9, 0xC3BD, 0x7FB8,
+	0xC3BE, 0x81D8, 0xC3BF, 0x85E9, 0xC3C0, 0x85DD, 0xC3C1, 0x85EA,
+	0xC3C2, 0x85D5, 0xC3C3, 0x85E4, 0xC3C4, 0x85E5, 0xC3C5, 0x85F7,
+	0xC3C6, 0x87FB, 0xC3C7, 0x8805, 0xC3C8, 0x880D, 0xC3C9, 0x87F9,
+	0xC3CA, 0x87FE, 0xC3CB, 0x8960, 0xC3CC, 0x895F, 0xC3CD, 0x8956,
+	0xC3CE, 0x895E, 0xC3CF, 0x8B41, 0xC3D0, 0x8B5C, 0xC3D1, 0x8B58,
+	0xC3D2, 0x8B49, 0xC3D3, 0x8B5A, 0xC3D4, 0x8B4E, 0xC3D5, 0x8B4F,
+	0xC3D6, 0x8B46, 0xC3D7, 0x8B59, 0xC3D8, 0x8D08, 0xC3D9, 0x8D0A,
+	0xC3DA, 0x8E7C, 0xC3DB, 0x8E72, 0xC3DC, 0x8E87, 0xC3DD, 0x8E76,
+	0xC3DE, 0x8E6C, 0xC3DF, 0x8E7A, 0xC3E0, 0x8E74, 0xC3E1, 0x8F54,
+	0xC3E2, 0x8F4E, 0xC3E3, 0x8FAD, 0xC3E4, 0x908A, 0xC3E5, 0x908B,
+	0xC3E6, 0x91B1, 0xC3E7, 0x91AE, 0xC3E8, 0x93E1, 0xC3E9, 0x93D1,
+	0xC3EA, 0x93DF, 0xC3EB, 0x93C3, 0xC3EC, 0x93C8, 0xC3ED, 0x93DC,
+	0xC3EE, 0x93DD, 0xC3EF, 0x93D6, 0xC3F0, 0x93E2, 0xC3F1, 0x93CD,
+	0xC3F2, 0x93D8, 0xC3F3, 0x93E4, 0xC3F4, 0x93D7, 0xC3F5, 0x93E8,
+	0xC3F6, 0x95DC, 0xC3F7, 0x96B4, 0xC3F8, 0x96E3, 0xC3F9, 0x972A,
+	0xC3FA, 0x9727, 0xC3FB, 0x9761, 0xC3FC, 0x97DC, 0xC3FD, 0x97FB,
+	0xC3FE, 0x985E, 0xC440, 0x9858, 0xC441, 0x985B, 0xC442, 0x98BC,
+	0xC443, 0x9945, 0xC444, 0x9949, 0xC445, 0x9A16, 0xC446, 0x9A19,
+	0xC447, 0x9B0D, 0xC448, 0x9BE8, 0xC449, 0x9BE7, 0xC44A, 0x9BD6,
+	0xC44B, 0x9BDB, 0xC44C, 0x9D89, 0xC44D, 0x9D61, 0xC44E, 0x9D72,
+	0xC44F, 0x9D6A, 0xC450, 0x9D6C, 0xC451, 0x9E92, 0xC452, 0x9E97,
+	0xC453, 0x9E93, 0xC454, 0x9EB4, 0xC455, 0x52F8, 0xC456, 0x56A8,
+	0xC457, 0x56B7, 0xC458, 0x56B6, 0xC459, 0x56B4, 0xC45A, 0x56BC,
+	0xC45B, 0x58E4, 0xC45C, 0x5B40, 0xC45D, 0x5B43, 0xC45E, 0x5B7D,
+	0xC45F, 0x5BF6, 0xC460, 0x5DC9, 0xC461, 0x61F8, 0xC462, 0x61FA,
+	0xC463, 0x6518, 0xC464, 0x6514, 0xC465, 0x6519, 0xC466, 0x66E6,
+	0xC467, 0x6727, 0xC468, 0x6AEC, 0xC469, 0x703E, 0xC46A, 0x7030,
+	0xC46B, 0x7032, 0xC46C, 0x7210, 0xC46D, 0x737B, 0xC46E, 0x74CF,
+	0xC46F, 0x7662, 0xC470, 0x7665, 0xC471, 0x7926, 0xC472, 0x792A,
+	0xC473, 0x792C, 0xC474, 0x792B, 0xC475, 0x7AC7, 0xC476, 0x7AF6,
+	0xC477, 0x7C4C, 0xC478, 0x7C43, 0xC479, 0x7C4D, 0xC47A, 0x7CEF,
+	0xC47B, 0x7CF0, 0xC47C, 0x8FAE, 0xC47D, 0x7E7D, 0xC47E, 0x7E7C,
+	0xC4A1, 0x7E82, 0xC4A2, 0x7F4C, 0xC4A3, 0x8000, 0xC4A4, 0x81DA,
+	0xC4A5, 0x8266, 0xC4A6, 0x85FB, 0xC4A7, 0x85F9, 0xC4A8, 0x8611,
+	0xC4A9, 0x85FA, 0xC4AA, 0x8606, 0xC4AB, 0x860B, 0xC4AC, 0x8607,
+	0xC4AD, 0x860A, 0xC4AE, 0x8814, 0xC4AF, 0x8815, 0xC4B0, 0x8964,
+	0xC4B1, 0x89BA, 0xC4B2, 0x89F8, 0xC4B3, 0x8B70, 0xC4B4, 0x8B6C,
+	0xC4B5, 0x8B66, 0xC4B6, 0x8B6F, 0xC4B7, 0x8B5F, 0xC4B8, 0x8B6B,
+	0xC4B9, 0x8D0F, 0xC4BA, 0x8D0D, 0xC4BB, 0x8E89, 0xC4BC, 0x8E81,
+	0xC4BD, 0x8E85, 0xC4BE, 0x8E82, 0xC4BF, 0x91B4, 0xC4C0, 0x91CB,
+	0xC4C1, 0x9418, 0xC4C2, 0x9403, 0xC4C3, 0x93FD, 0xC4C4, 0x95E1,
+	0xC4C5, 0x9730, 0xC4C6, 0x98C4, 0xC4C7, 0x9952, 0xC4C8, 0x9951,
+	0xC4C9, 0x99A8, 0xC4CA, 0x9A2B, 0xC4CB, 0x9A30, 0xC4CC, 0x9A37,
+	0xC4CD, 0x9A35, 0xC4CE, 0x9C13, 0xC4CF, 0x9C0D, 0xC4D0, 0x9E79,
+	0xC4D1, 0x9EB5, 0xC4D2, 0x9EE8, 0xC4D3, 0x9F2F, 0xC4D4, 0x9F5F,
+	0xC4D5, 0x9F63, 0xC4D6, 0x9F61, 0xC4D7, 0x5137, 0xC4D8, 0x5138,
+	0xC4D9, 0x56C1, 0xC4DA, 0x56C0, 0xC4DB, 0x56C2, 0xC4DC, 0x5914,
+	0xC4DD, 0x5C6C, 0xC4DE, 0x5DCD, 0xC4DF, 0x61FC, 0xC4E0, 0x61FE,
+	0xC4E1, 0x651D, 0xC4E2, 0x651C, 0xC4E3, 0x6595, 0xC4E4, 0x66E9,
+	0xC4E5, 0x6AFB, 0xC4E6, 0x6B04, 0xC4E7, 0x6AFA, 0xC4E8, 0x6BB2,
+	0xC4E9, 0x704C, 0xC4EA, 0x721B, 0xC4EB, 0x72A7, 0xC4EC, 0x74D6,
+	0xC4ED, 0x74D4, 0xC4EE, 0x7669, 0xC4EF, 0x77D3, 0xC4F0, 0x7C50,
+	0xC4F1, 0x7E8F, 0xC4F2, 0x7E8C, 0xC4F3, 0x7FBC, 0xC4F4, 0x8617,
+	0xC4F5, 0x862D, 0xC4F6, 0x861A, 0xC4F7, 0x8823, 0xC4F8, 0x8822,
+	0xC4F9, 0x8821, 0xC4FA, 0x881F, 0xC4FB, 0x896A, 0xC4FC, 0x896C,
+	0xC4FD, 0x89BD, 0xC4FE, 0x8B74, 0xC540, 0x8B77, 0xC541, 0x8B7D,
+	0xC542, 0x8D13, 0xC543, 0x8E8A, 0xC544, 0x8E8D, 0xC545, 0x8E8B,
+	0xC546, 0x8F5F, 0xC547, 0x8FAF, 0xC548, 0x91BA, 0xC549, 0x942E,
+	0xC54A, 0x9433, 0xC54B, 0x9435, 0xC54C, 0x943A, 0xC54D, 0x9438,
+	0xC54E, 0x9432, 0xC54F, 0x942B, 0xC550, 0x95E2, 0xC551, 0x9738,
+	0xC552, 0x9739, 0xC553, 0x9732, 0xC554, 0x97FF, 0xC555, 0x9867,
+	0xC556, 0x9865, 0xC557, 0x9957, 0xC558, 0x9A45, 0xC559, 0x9A43,
+	0xC55A, 0x9A40, 0xC55B, 0x9A3E, 0xC55C, 0x9ACF, 0xC55D, 0x9B54,
+	0xC55E, 0x9B51, 0xC55F, 0x9C2D, 0xC560, 0x9C25, 0xC561, 0x9DAF,
+	0xC562, 0x9DB4, 0xC563, 0x9DC2, 0xC564, 0x9DB8, 0xC565, 0x9E9D,
+	0xC566, 0x9EEF, 0xC567, 0x9F19, 0xC568, 0x9F5C, 0xC569, 0x9F66,
+	0xC56A, 0x9F67, 0xC56B, 0x513C, 0xC56C, 0x513B, 0xC56D, 0x56C8,
+	0xC56E, 0x56CA, 0xC56F, 0x56C9, 0xC570, 0x5B7F, 0xC571, 0x5DD4,
+	0xC572, 0x5DD2, 0xC573, 0x5F4E, 0xC574, 0x61FF, 0xC575, 0x6524,
+	0xC576, 0x6B0A, 0xC577, 0x6B61, 0xC578, 0x7051, 0xC579, 0x7058,
+	0xC57A, 0x7380, 0xC57B, 0x74E4, 0xC57C, 0x758A, 0xC57D, 0x766E,
+	0xC57E, 0x766C, 0xC5A1, 0x79B3, 0xC5A2, 0x7C60, 0xC5A3, 0x7C5F,
+	0xC5A4, 0x807E, 0xC5A5, 0x807D, 0xC5A6, 0x81DF, 0xC5A7, 0x8972,
+	0xC5A8, 0x896F, 0xC5A9, 0x89FC, 0xC5AA, 0x8B80, 0xC5AB, 0x8D16,
+	0xC5AC, 0x8D17, 0xC5AD, 0x8E91, 0xC5AE, 0x8E93, 0xC5AF, 0x8F61,
+	0xC5B0, 0x9148, 0xC5B1, 0x9444, 0xC5B2, 0x9451, 0xC5B3, 0x9452,
+	0xC5B4, 0x973D, 0xC5B5, 0x973E, 0xC5B6, 0x97C3, 0xC5B7, 0x97C1,
+	0xC5B8, 0x986B, 0xC5B9, 0x9955, 0xC5BA, 0x9A55, 0xC5BB, 0x9A4D,
+	0xC5BC, 0x9AD2, 0xC5BD, 0x9B1A, 0xC5BE, 0x9C49, 0xC5BF, 0x9C31,
+	0xC5C0, 0x9C3E, 0xC5C1, 0x9C3B, 0xC5C2, 0x9DD3, 0xC5C3, 0x9DD7,
+	0xC5C4, 0x9F34, 0xC5C5, 0x9F6C, 0xC5C6, 0x9F6A, 0xC5C7, 0x9F94,
+	0xC5C8, 0x56CC, 0xC5C9, 0x5DD6, 0xC5CA, 0x6200, 0xC5CB, 0x6523,
+	0xC5CC, 0x652B, 0xC5CD, 0x652A, 0xC5CE, 0x66EC, 0xC5CF, 0x6B10,
+	0xC5D0, 0x74DA, 0xC5D1, 0x7ACA, 0xC5D2, 0x7C64, 0xC5D3, 0x7C63,
+	0xC5D4, 0x7C65, 0xC5D5, 0x7E93, 0xC5D6, 0x7E96, 0xC5D7, 0x7E94,
+	0xC5D8, 0x81E2, 0xC5D9, 0x8638, 0xC5DA, 0x863F, 0xC5DB, 0x8831,
+	0xC5DC, 0x8B8A, 0xC5DD, 0x9090, 0xC5DE, 0x908F, 0xC5DF, 0x9463,
+	0xC5E0, 0x9460, 0xC5E1, 0x9464, 0xC5E2, 0x9768, 0xC5E3, 0x986F,
+	0xC5E4, 0x995C, 0xC5E5, 0x9A5A, 0xC5E6, 0x9A5B, 0xC5E7, 0x9A57,
+	0xC5E8, 0x9AD3, 0xC5E9, 0x9AD4, 0xC5EA, 0x9AD1, 0xC5EB, 0x9C54,
+	0xC5EC, 0x9C57, 0xC5ED, 0x9C56, 0xC5EE, 0x9DE5, 0xC5EF, 0x9E9F,
+	0xC5F0, 0x9EF4, 0xC5F1, 0x56D1, 0xC5F2, 0x58E9, 0xC5F3, 0x652C,
+	0xC5F4, 0x705E, 0xC5F5, 0x7671, 0xC5F6, 0x7672, 0xC5F7, 0x77D7,
+	0xC5F8, 0x7F50, 0xC5F9, 0x7F88, 0xC5FA, 0x8836, 0xC5FB, 0x8839,
+	0xC5FC, 0x8862, 0xC5FD, 0x8B93, 0xC5FE, 0x8B92, 0xC640, 0x8B96,
+	0xC641, 0x8277, 0xC642, 0x8D1B, 0xC643, 0x91C0, 0xC644, 0x946A,
+	0xC645, 0x9742, 0xC646, 0x9748, 0xC647, 0x9744, 0xC648, 0x97C6,
+	0xC649, 0x9870, 0xC64A, 0x9A5F, 0xC64B, 0x9B22, 0xC64C, 0x9B58,
+	0xC64D, 0x9C5F, 0xC64E, 0x9DF9, 0xC64F, 0x9DFA, 0xC650, 0x9E7C,
+	0xC651, 0x9E7D, 0xC652, 0x9F07, 0xC653, 0x9F77, 0xC654, 0x9F72,
+	0xC655, 0x5EF3, 0xC656, 0x6B16, 0xC657, 0x7063, 0xC658, 0x7C6C,
+	0xC659, 0x7C6E, 0xC65A, 0x883B, 0xC65B, 0x89C0, 0xC65C, 0x8EA1,
+	0xC65D, 0x91C1, 0xC65E, 0x9472, 0xC65F, 0x9470, 0xC660, 0x9871,
+	0xC661, 0x995E, 0xC662, 0x9AD6, 0xC663, 0x9B23, 0xC664, 0x9ECC,
+	0xC665, 0x7064, 0xC666, 0x77DA, 0xC667, 0x8B9A, 0xC668, 0x9477,
+	0xC669, 0x97C9, 0xC66A, 0x9A62, 0xC66B, 0x9A65, 0xC66C, 0x7E9C,
+	0xC66D, 0x8B9C, 0xC66E, 0x8EAA, 0xC66F, 0x91C5, 0xC670, 0x947D,
+	0xC671, 0x947E, 0xC672, 0x947C, 0xC673, 0x9C77, 0xC674, 0x9C78,
+	0xC675, 0x9EF7, 0xC676, 0x8C54, 0xC677, 0x947F, 0xC678, 0x9E1A,
+	0xC679, 0x7228, 0xC67A, 0x9A6A, 0xC67B, 0x9B31, 0xC67C, 0x9E1B,
+	0xC67D, 0x9E1E, 0xC67E, 0x7C72, 0xC940, 0x4E42, 0xC941, 0x4E5C,
+	0xC942, 0x51F5, 0xC943, 0x531A, 0xC944, 0x5382, 0xC945, 0x4E07,
+	0xC946, 0x4E0C, 0xC947, 0x4E47, 0xC948, 0x4E8D, 0xC949, 0x56D7,
+	0xC94A, 0xFA0C, 0xC94B, 0x5C6E, 0xC94C, 0x5F73, 0xC94D, 0x4E0F,
+	0xC94E, 0x5187, 0xC94F, 0x4E0E, 0xC950, 0x4E2E, 0xC951, 0x4E93,
+	0xC952, 0x4EC2, 0xC953, 0x4EC9, 0xC954, 0x4EC8, 0xC955, 0x5198,
+	0xC956, 0x52FC, 0xC957, 0x536C, 0xC958, 0x53B9, 0xC959, 0x5720,
+	0xC95A, 0x5903, 0xC95B, 0x592C, 0xC95C, 0x5C10, 0xC95D, 0x5DFF,
+	0xC95E, 0x65E1, 0xC95F, 0x6BB3, 0xC960, 0x6BCC, 0xC961, 0x6C14,
+	0xC962, 0x723F, 0xC963, 0x4E31, 0xC964, 0x4E3C, 0xC965, 0x4EE8,
+	0xC966, 0x4EDC, 0xC967, 0x4EE9, 0xC968, 0x4EE1, 0xC969, 0x4EDD,
+	0xC96A, 0x4EDA, 0xC96B, 0x520C, 0xC96C, 0x531C, 0xC96D, 0x534C,
+	0xC96E, 0x5722, 0xC96F, 0x5723, 0xC970, 0x5917, 0xC971, 0x592F,
+	0xC972, 0x5B81, 0xC973, 0x5B84, 0xC974, 0x5C12, 0xC975, 0x5C3B,
+	0xC976, 0x5C74, 0xC977, 0x5C73, 0xC978, 0x5E04, 0xC979, 0x5E80,
+	0xC97A, 0x5E82, 0xC97B, 0x5FC9, 0xC97C, 0x6209, 0xC97D, 0x6250,
+	0xC97E, 0x6C15, 0xC9A1, 0x6C36, 0xC9A2, 0x6C43, 0xC9A3, 0x6C3F,
+	0xC9A4, 0x6C3B, 0xC9A5, 0x72AE, 0xC9A6, 0x72B0, 0xC9A7, 0x738A,
+	0xC9A8, 0x79B8, 0xC9A9, 0x808A, 0xC9AA, 0x961E, 0xC9AB, 0x4F0E,
+	0xC9AC, 0x4F18, 0xC9AD, 0x4F2C, 0xC9AE, 0x4EF5, 0xC9AF, 0x4F14,
+	0xC9B0, 0x4EF1, 0xC9B1, 0x4F00, 0xC9B2, 0x4EF7, 0xC9B3, 0x4F08,
+	0xC9B4, 0x4F1D, 0xC9B5, 0x4F02, 0xC9B6, 0x4F05, 0xC9B7, 0x4F22,
+	0xC9B8, 0x4F13, 0xC9B9, 0x4F04, 0xC9BA, 0x4EF4, 0xC9BB, 0x4F12,
+	0xC9BC, 0x51B1, 0xC9BD, 0x5213, 0xC9BE, 0x5209, 0xC9BF, 0x5210,
+	0xC9C0, 0x52A6, 0xC9C1, 0x5322, 0xC9C2, 0x531F, 0xC9C3, 0x534D,
+	0xC9C4, 0x538A, 0xC9C5, 0x5407, 0xC9C6, 0x56E1, 0xC9C7, 0x56DF,
+	0xC9C8, 0x572E, 0xC9C9, 0x572A, 0xC9CA, 0x5734, 0xC9CB, 0x593C,
+	0xC9CC, 0x5980, 0xC9CD, 0x597C, 0xC9CE, 0x5985, 0xC9CF, 0x597B,
+	0xC9D0, 0x597E, 0xC9D1, 0x5977, 0xC9D2, 0x597F, 0xC9D3, 0x5B56,
+	0xC9D4, 0x5C15, 0xC9D5, 0x5C25, 0xC9D6, 0x5C7C, 0xC9D7, 0x5C7A,
+	0xC9D8, 0x5C7B, 0xC9D9, 0x5C7E, 0xC9DA, 0x5DDF, 0xC9DB, 0x5E75,
+	0xC9DC, 0x5E84, 0xC9DD, 0x5F02, 0xC9DE, 0x5F1A, 0xC9DF, 0x5F74,
+	0xC9E0, 0x5FD5, 0xC9E1, 0x5FD4, 0xC9E2, 0x5FCF, 0xC9E3, 0x625C,
+	0xC9E4, 0x625E, 0xC9E5, 0x6264, 0xC9E6, 0x6261, 0xC9E7, 0x6266,
+	0xC9E8, 0x6262, 0xC9E9, 0x6259, 0xC9EA, 0x6260, 0xC9EB, 0x625A,
+	0xC9EC, 0x6265, 0xC9ED, 0x65EF, 0xC9EE, 0x65EE, 0xC9EF, 0x673E,
+	0xC9F0, 0x6739, 0xC9F1, 0x6738, 0xC9F2, 0x673B, 0xC9F3, 0x673A,
+	0xC9F4, 0x673F, 0xC9F5, 0x673C, 0xC9F6, 0x6733, 0xC9F7, 0x6C18,
+	0xC9F8, 0x6C46, 0xC9F9, 0x6C52, 0xC9FA, 0x6C5C, 0xC9FB, 0x6C4F,
+	0xC9FC, 0x6C4A, 0xC9FD, 0x6C54, 0xC9FE, 0x6C4B, 0xCA40, 0x6C4C,
+	0xCA41, 0x7071, 0xCA42, 0x725E, 0xCA43, 0x72B4, 0xCA44, 0x72B5,
+	0xCA45, 0x738E, 0xCA46, 0x752A, 0xCA47, 0x767F, 0xCA48, 0x7A75,
+	0xCA49, 0x7F51, 0xCA4A, 0x8278, 0xCA4B, 0x827C, 0xCA4C, 0x8280,
+	0xCA4D, 0x827D, 0xCA4E, 0x827F, 0xCA4F, 0x864D, 0xCA50, 0x897E,
+	0xCA51, 0x9099, 0xCA52, 0x9097, 0xCA53, 0x9098, 0xCA54, 0x909B,
+	0xCA55, 0x9094, 0xCA56, 0x9622, 0xCA57, 0x9624, 0xCA58, 0x9620,
+	0xCA59, 0x9623, 0xCA5A, 0x4F56, 0xCA5B, 0x4F3B, 0xCA5C, 0x4F62,
+	0xCA5D, 0x4F49, 0xCA5E, 0x4F53, 0xCA5F, 0x4F64, 0xCA60, 0x4F3E,
+	0xCA61, 0x4F67, 0xCA62, 0x4F52, 0xCA63, 0x4F5F, 0xCA64, 0x4F41,
+	0xCA65, 0x4F58, 0xCA66, 0x4F2D, 0xCA67, 0x4F33, 0xCA68, 0x4F3F,
+	0xCA69, 0x4F61, 0xCA6A, 0x518F, 0xCA6B, 0x51B9, 0xCA6C, 0x521C,
+	0xCA6D, 0x521E, 0xCA6E, 0x5221, 0xCA6F, 0x52AD, 0xCA70, 0x52AE,
+	0xCA71, 0x5309, 0xCA72, 0x5363, 0xCA73, 0x5372, 0xCA74, 0x538E,
+	0xCA75, 0x538F, 0xCA76, 0x5430, 0xCA77, 0x5437, 0xCA78, 0x542A,
+	0xCA79, 0x5454, 0xCA7A, 0x5445, 0xCA7B, 0x5419, 0xCA7C, 0x541C,
+	0xCA7D, 0x5425, 0xCA7E, 0x5418, 0xCAA1, 0x543D, 0xCAA2, 0x544F,
+	0xCAA3, 0x5441, 0xCAA4, 0x5428, 0xCAA5, 0x5424, 0xCAA6, 0x5447,
+	0xCAA7, 0x56EE, 0xCAA8, 0x56E7, 0xCAA9, 0x56E5, 0xCAAA, 0x5741,
+	0xCAAB, 0x5745, 0xCAAC, 0x574C, 0xCAAD, 0x5749, 0xCAAE, 0x574B,
+	0xCAAF, 0x5752, 0xCAB0, 0x5906, 0xCAB1, 0x5940, 0xCAB2, 0x59A6,
+	0xCAB3, 0x5998, 0xCAB4, 0x59A0, 0xCAB5, 0x5997, 0xCAB6, 0x598E,
+	0xCAB7, 0x59A2, 0xCAB8, 0x5990, 0xCAB9, 0x598F, 0xCABA, 0x59A7,
+	0xCABB, 0x59A1, 0xCABC, 0x5B8E, 0xCABD, 0x5B92, 0xCABE, 0x5C28,
+	0xCABF, 0x5C2A, 0xCAC0, 0x5C8D, 0xCAC1, 0x5C8F, 0xCAC2, 0x5C88,
+	0xCAC3, 0x5C8B, 0xCAC4, 0x5C89, 0xCAC5, 0x5C92, 0xCAC6, 0x5C8A,
+	0xCAC7, 0x5C86, 0xCAC8, 0x5C93, 0xCAC9, 0x5C95, 0xCACA, 0x5DE0,
+	0xCACB, 0x5E0A, 0xCACC, 0x5E0E, 0xCACD, 0x5E8B, 0xCACE, 0x5E89,
+	0xCACF, 0x5E8C, 0xCAD0, 0x5E88, 0xCAD1, 0x5E8D, 0xCAD2, 0x5F05,
+	0xCAD3, 0x5F1D, 0xCAD4, 0x5F78, 0xCAD5, 0x5F76, 0xCAD6, 0x5FD2,
+	0xCAD7, 0x5FD1, 0xCAD8, 0x5FD0, 0xCAD9, 0x5FED, 0xCADA, 0x5FE8,
+	0xCADB, 0x5FEE, 0xCADC, 0x5FF3, 0xCADD, 0x5FE1, 0xCADE, 0x5FE4,
+	0xCADF, 0x5FE3, 0xCAE0, 0x5FFA, 0xCAE1, 0x5FEF, 0xCAE2, 0x5FF7,
+	0xCAE3, 0x5FFB, 0xCAE4, 0x6000, 0xCAE5, 0x5FF4, 0xCAE6, 0x623A,
+	0xCAE7, 0x6283, 0xCAE8, 0x628C, 0xCAE9, 0x628E, 0xCAEA, 0x628F,
+	0xCAEB, 0x6294, 0xCAEC, 0x6287, 0xCAED, 0x6271, 0xCAEE, 0x627B,
+	0xCAEF, 0x627A, 0xCAF0, 0x6270, 0xCAF1, 0x6281, 0xCAF2, 0x6288,
+	0xCAF3, 0x6277, 0xCAF4, 0x627D, 0xCAF5, 0x6272, 0xCAF6, 0x6274,
+	0xCAF7, 0x6537, 0xCAF8, 0x65F0, 0xCAF9, 0x65F4, 0xCAFA, 0x65F3,
+	0xCAFB, 0x65F2, 0xCAFC, 0x65F5, 0xCAFD, 0x6745, 0xCAFE, 0x6747,
+	0xCB40, 0x6759, 0xCB41, 0x6755, 0xCB42, 0x674C, 0xCB43, 0x6748,
+	0xCB44, 0x675D, 0xCB45, 0x674D, 0xCB46, 0x675A, 0xCB47, 0x674B,
+	0xCB48, 0x6BD0, 0xCB49, 0x6C19, 0xCB4A, 0x6C1A, 0xCB4B, 0x6C78,
+	0xCB4C, 0x6C67, 0xCB4D, 0x6C6B, 0xCB4E, 0x6C84, 0xCB4F, 0x6C8B,
+	0xCB50, 0x6C8F, 0xCB51, 0x6C71, 0xCB52, 0x6C6F, 0xCB53, 0x6C69,
+	0xCB54, 0x6C9A, 0xCB55, 0x6C6D, 0xCB56, 0x6C87, 0xCB57, 0x6C95,
+	0xCB58, 0x6C9C, 0xCB59, 0x6C66, 0xCB5A, 0x6C73, 0xCB5B, 0x6C65,
+	0xCB5C, 0x6C7B, 0xCB5D, 0x6C8E, 0xCB5E, 0x7074, 0xCB5F, 0x707A,
+	0xCB60, 0x7263, 0xCB61, 0x72BF, 0xCB62, 0x72BD, 0xCB63, 0x72C3,
+	0xCB64, 0x72C6, 0xCB65, 0x72C1, 0xCB66, 0x72BA, 0xCB67, 0x72C5,
+	0xCB68, 0x7395, 0xCB69, 0x7397, 0xCB6A, 0x7393, 0xCB6B, 0x7394,
+	0xCB6C, 0x7392, 0xCB6D, 0x753A, 0xCB6E, 0x7539, 0xCB6F, 0x7594,
+	0xCB70, 0x7595, 0xCB71, 0x7681, 0xCB72, 0x793D, 0xCB73, 0x8034,
+	0xCB74, 0x8095, 0xCB75, 0x8099, 0xCB76, 0x8090, 0xCB77, 0x8092,
+	0xCB78, 0x809C, 0xCB79, 0x8290, 0xCB7A, 0x828F, 0xCB7B, 0x8285,
+	0xCB7C, 0x828E, 0xCB7D, 0x8291, 0xCB7E, 0x8293, 0xCBA1, 0x828A,
+	0xCBA2, 0x8283, 0xCBA3, 0x8284, 0xCBA4, 0x8C78, 0xCBA5, 0x8FC9,
+	0xCBA6, 0x8FBF, 0xCBA7, 0x909F, 0xCBA8, 0x90A1, 0xCBA9, 0x90A5,
+	0xCBAA, 0x909E, 0xCBAB, 0x90A7, 0xCBAC, 0x90A0, 0xCBAD, 0x9630,
+	0xCBAE, 0x9628, 0xCBAF, 0x962F, 0xCBB0, 0x962D, 0xCBB1, 0x4E33,
+	0xCBB2, 0x4F98, 0xCBB3, 0x4F7C, 0xCBB4, 0x4F85, 0xCBB5, 0x4F7D,
+	0xCBB6, 0x4F80, 0xCBB7, 0x4F87, 0xCBB8, 0x4F76, 0xCBB9, 0x4F74,
+	0xCBBA, 0x4F89, 0xCBBB, 0x4F84, 0xCBBC, 0x4F77, 0xCBBD, 0x4F4C,
+	0xCBBE, 0x4F97, 0xCBBF, 0x4F6A, 0xCBC0, 0x4F9A, 0xCBC1, 0x4F79,
+	0xCBC2, 0x4F81, 0xCBC3, 0x4F78, 0xCBC4, 0x4F90, 0xCBC5, 0x4F9C,
+	0xCBC6, 0x4F94, 0xCBC7, 0x4F9E, 0xCBC8, 0x4F92, 0xCBC9, 0x4F82,
+	0xCBCA, 0x4F95, 0xCBCB, 0x4F6B, 0xCBCC, 0x4F6E, 0xCBCD, 0x519E,
+	0xCBCE, 0x51BC, 0xCBCF, 0x51BE, 0xCBD0, 0x5235, 0xCBD1, 0x5232,
+	0xCBD2, 0x5233, 0xCBD3, 0x5246, 0xCBD4, 0x5231, 0xCBD5, 0x52BC,
+	0xCBD6, 0x530A, 0xCBD7, 0x530B, 0xCBD8, 0x533C, 0xCBD9, 0x5392,
+	0xCBDA, 0x5394, 0xCBDB, 0x5487, 0xCBDC, 0x547F, 0xCBDD, 0x5481,
+	0xCBDE, 0x5491, 0xCBDF, 0x5482, 0xCBE0, 0x5488, 0xCBE1, 0x546B,
+	0xCBE2, 0x547A, 0xCBE3, 0x547E, 0xCBE4, 0x5465, 0xCBE5, 0x546C,
+	0xCBE6, 0x5474, 0xCBE7, 0x5466, 0xCBE8, 0x548D, 0xCBE9, 0x546F,
+	0xCBEA, 0x5461, 0xCBEB, 0x5460, 0xCBEC, 0x5498, 0xCBED, 0x5463,
+	0xCBEE, 0x5467, 0xCBEF, 0x5464, 0xCBF0, 0x56F7, 0xCBF1, 0x56F9,
+	0xCBF2, 0x576F, 0xCBF3, 0x5772, 0xCBF4, 0x576D, 0xCBF5, 0x576B,
+	0xCBF6, 0x5771, 0xCBF7, 0x5770, 0xCBF8, 0x5776, 0xCBF9, 0x5780,
+	0xCBFA, 0x5775, 0xCBFB, 0x577B, 0xCBFC, 0x5773, 0xCBFD, 0x5774,
+	0xCBFE, 0x5762, 0xCC40, 0x5768, 0xCC41, 0x577D, 0xCC42, 0x590C,
+	0xCC43, 0x5945, 0xCC44, 0x59B5, 0xCC45, 0x59BA, 0xCC46, 0x59CF,
+	0xCC47, 0x59CE, 0xCC48, 0x59B2, 0xCC49, 0x59CC, 0xCC4A, 0x59C1,
+	0xCC4B, 0x59B6, 0xCC4C, 0x59BC, 0xCC4D, 0x59C3, 0xCC4E, 0x59D6,
+	0xCC4F, 0x59B1, 0xCC50, 0x59BD, 0xCC51, 0x59C0, 0xCC52, 0x59C8,
+	0xCC53, 0x59B4, 0xCC54, 0x59C7, 0xCC55, 0x5B62, 0xCC56, 0x5B65,
+	0xCC57, 0x5B93, 0xCC58, 0x5B95, 0xCC59, 0x5C44, 0xCC5A, 0x5C47,
+	0xCC5B, 0x5CAE, 0xCC5C, 0x5CA4, 0xCC5D, 0x5CA0, 0xCC5E, 0x5CB5,
+	0xCC5F, 0x5CAF, 0xCC60, 0x5CA8, 0xCC61, 0x5CAC, 0xCC62, 0x5C9F,
+	0xCC63, 0x5CA3, 0xCC64, 0x5CAD, 0xCC65, 0x5CA2, 0xCC66, 0x5CAA,
+	0xCC67, 0x5CA7, 0xCC68, 0x5C9D, 0xCC69, 0x5CA5, 0xCC6A, 0x5CB6,
+	0xCC6B, 0x5CB0, 0xCC6C, 0x5CA6, 0xCC6D, 0x5E17, 0xCC6E, 0x5E14,
+	0xCC6F, 0x5E19, 0xCC70, 0x5F28, 0xCC71, 0x5F22, 0xCC72, 0x5F23,
+	0xCC73, 0x5F24, 0xCC74, 0x5F54, 0xCC75, 0x5F82, 0xCC76, 0x5F7E,
+	0xCC77, 0x5F7D, 0xCC78, 0x5FDE, 0xCC79, 0x5FE5, 0xCC7A, 0x602D,
+	0xCC7B, 0x6026, 0xCC7C, 0x6019, 0xCC7D, 0x6032, 0xCC7E, 0x600B,
+	0xCCA1, 0x6034, 0xCCA2, 0x600A, 0xCCA3, 0x6017, 0xCCA4, 0x6033,
+	0xCCA5, 0x601A, 0xCCA6, 0x601E, 0xCCA7, 0x602C, 0xCCA8, 0x6022,
+	0xCCA9, 0x600D, 0xCCAA, 0x6010, 0xCCAB, 0x602E, 0xCCAC, 0x6013,
+	0xCCAD, 0x6011, 0xCCAE, 0x600C, 0xCCAF, 0x6009, 0xCCB0, 0x601C,
+	0xCCB1, 0x6214, 0xCCB2, 0x623D, 0xCCB3, 0x62AD, 0xCCB4, 0x62B4,
+	0xCCB5, 0x62D1, 0xCCB6, 0x62BE, 0xCCB7, 0x62AA, 0xCCB8, 0x62B6,
+	0xCCB9, 0x62CA, 0xCCBA, 0x62AE, 0xCCBB, 0x62B3, 0xCCBC, 0x62AF,
+	0xCCBD, 0x62BB, 0xCCBE, 0x62A9, 0xCCBF, 0x62B0, 0xCCC0, 0x62B8,
+	0xCCC1, 0x653D, 0xCCC2, 0x65A8, 0xCCC3, 0x65BB, 0xCCC4, 0x6609,
+	0xCCC5, 0x65FC, 0xCCC6, 0x6604, 0xCCC7, 0x6612, 0xCCC8, 0x6608,
+	0xCCC9, 0x65FB, 0xCCCA, 0x6603, 0xCCCB, 0x660B, 0xCCCC, 0x660D,
+	0xCCCD, 0x6605, 0xCCCE, 0x65FD, 0xCCCF, 0x6611, 0xCCD0, 0x6610,
+	0xCCD1, 0x66F6, 0xCCD2, 0x670A, 0xCCD3, 0x6785, 0xCCD4, 0x676C,
+	0xCCD5, 0x678E, 0xCCD6, 0x6792, 0xCCD7, 0x6776, 0xCCD8, 0x677B,
+	0xCCD9, 0x6798, 0xCCDA, 0x6786, 0xCCDB, 0x6784, 0xCCDC, 0x6774,
+	0xCCDD, 0x678D, 0xCCDE, 0x678C, 0xCCDF, 0x677A, 0xCCE0, 0x679F,
+	0xCCE1, 0x6791, 0xCCE2, 0x6799, 0xCCE3, 0x6783, 0xCCE4, 0x677D,
+	0xCCE5, 0x6781, 0xCCE6, 0x6778, 0xCCE7, 0x6779, 0xCCE8, 0x6794,
+	0xCCE9, 0x6B25, 0xCCEA, 0x6B80, 0xCCEB, 0x6B7E, 0xCCEC, 0x6BDE,
+	0xCCED, 0x6C1D, 0xCCEE, 0x6C93, 0xCCEF, 0x6CEC, 0xCCF0, 0x6CEB,
+	0xCCF1, 0x6CEE, 0xCCF2, 0x6CD9, 0xCCF3, 0x6CB6, 0xCCF4, 0x6CD4,
+	0xCCF5, 0x6CAD, 0xCCF6, 0x6CE7, 0xCCF7, 0x6CB7, 0xCCF8, 0x6CD0,
+	0xCCF9, 0x6CC2, 0xCCFA, 0x6CBA, 0xCCFB, 0x6CC3, 0xCCFC, 0x6CC6,
+	0xCCFD, 0x6CED, 0xCCFE, 0x6CF2, 0xCD40, 0x6CD2, 0xCD41, 0x6CDD,
+	0xCD42, 0x6CB4, 0xCD43, 0x6C8A, 0xCD44, 0x6C9D, 0xCD45, 0x6C80,
+	0xCD46, 0x6CDE, 0xCD47, 0x6CC0, 0xCD48, 0x6D30, 0xCD49, 0x6CCD,
+	0xCD4A, 0x6CC7, 0xCD4B, 0x6CB0, 0xCD4C, 0x6CF9, 0xCD4D, 0x6CCF,
+	0xCD4E, 0x6CE9, 0xCD4F, 0x6CD1, 0xCD50, 0x7094, 0xCD51, 0x7098,
+	0xCD52, 0x7085, 0xCD53, 0x7093, 0xCD54, 0x7086, 0xCD55, 0x7084,
+	0xCD56, 0x7091, 0xCD57, 0x7096, 0xCD58, 0x7082, 0xCD59, 0x709A,
+	0xCD5A, 0x7083, 0xCD5B, 0x726A, 0xCD5C, 0x72D6, 0xCD5D, 0x72CB,
+	0xCD5E, 0x72D8, 0xCD5F, 0x72C9, 0xCD60, 0x72DC, 0xCD61, 0x72D2,
+	0xCD62, 0x72D4, 0xCD63, 0x72DA, 0xCD64, 0x72CC, 0xCD65, 0x72D1,
+	0xCD66, 0x73A4, 0xCD67, 0x73A1, 0xCD68, 0x73AD, 0xCD69, 0x73A6,
+	0xCD6A, 0x73A2, 0xCD6B, 0x73A0, 0xCD6C, 0x73AC, 0xCD6D, 0x739D,
+	0xCD6E, 0x74DD, 0xCD6F, 0x74E8, 0xCD70, 0x753F, 0xCD71, 0x7540,
+	0xCD72, 0x753E, 0xCD73, 0x758C, 0xCD74, 0x7598, 0xCD75, 0x76AF,
+	0xCD76, 0x76F3, 0xCD77, 0x76F1, 0xCD78, 0x76F0, 0xCD79, 0x76F5,
+	0xCD7A, 0x77F8, 0xCD7B, 0x77FC, 0xCD7C, 0x77F9, 0xCD7D, 0x77FB,
+	0xCD7E, 0x77FA, 0xCDA1, 0x77F7, 0xCDA2, 0x7942, 0xCDA3, 0x793F,
+	0xCDA4, 0x79C5, 0xCDA5, 0x7A78, 0xCDA6, 0x7A7B, 0xCDA7, 0x7AFB,
+	0xCDA8, 0x7C75, 0xCDA9, 0x7CFD, 0xCDAA, 0x8035, 0xCDAB, 0x808F,
+	0xCDAC, 0x80AE, 0xCDAD, 0x80A3, 0xCDAE, 0x80B8, 0xCDAF, 0x80B5,
+	0xCDB0, 0x80AD, 0xCDB1, 0x8220, 0xCDB2, 0x82A0, 0xCDB3, 0x82C0,
+	0xCDB4, 0x82AB, 0xCDB5, 0x829A, 0xCDB6, 0x8298, 0xCDB7, 0x829B,
+	0xCDB8, 0x82B5, 0xCDB9, 0x82A7, 0xCDBA, 0x82AE, 0xCDBB, 0x82BC,
+	0xCDBC, 0x829E, 0xCDBD, 0x82BA, 0xCDBE, 0x82B4, 0xCDBF, 0x82A8,
+	0xCDC0, 0x82A1, 0xCDC1, 0x82A9, 0xCDC2, 0x82C2, 0xCDC3, 0x82A4,
+	0xCDC4, 0x82C3, 0xCDC5, 0x82B6, 0xCDC6, 0x82A2, 0xCDC7, 0x8670,
+	0xCDC8, 0x866F, 0xCDC9, 0x866D, 0xCDCA, 0x866E, 0xCDCB, 0x8C56,
+	0xCDCC, 0x8FD2, 0xCDCD, 0x8FCB, 0xCDCE, 0x8FD3, 0xCDCF, 0x8FCD,
+	0xCDD0, 0x8FD6, 0xCDD1, 0x8FD5, 0xCDD2, 0x8FD7, 0xCDD3, 0x90B2,
+	0xCDD4, 0x90B4, 0xCDD5, 0x90AF, 0xCDD6, 0x90B3, 0xCDD7, 0x90B0,
+	0xCDD8, 0x9639, 0xCDD9, 0x963D, 0xCDDA, 0x963C, 0xCDDB, 0x963A,
+	0xCDDC, 0x9643, 0xCDDD, 0x4FCD, 0xCDDE, 0x4FC5, 0xCDDF, 0x4FD3,
+	0xCDE0, 0x4FB2, 0xCDE1, 0x4FC9, 0xCDE2, 0x4FCB, 0xCDE3, 0x4FC1,
+	0xCDE4, 0x4FD4, 0xCDE5, 0x4FDC, 0xCDE6, 0x4FD9, 0xCDE7, 0x4FBB,
+	0xCDE8, 0x4FB3, 0xCDE9, 0x4FDB, 0xCDEA, 0x4FC7, 0xCDEB, 0x4FD6,
+	0xCDEC, 0x4FBA, 0xCDED, 0x4FC0, 0xCDEE, 0x4FB9, 0xCDEF, 0x4FEC,
+	0xCDF0, 0x5244, 0xCDF1, 0x5249, 0xCDF2, 0x52C0, 0xCDF3, 0x52C2,
+	0xCDF4, 0x533D, 0xCDF5, 0x537C, 0xCDF6, 0x5397, 0xCDF7, 0x5396,
+	0xCDF8, 0x5399, 0xCDF9, 0x5398, 0xCDFA, 0x54BA, 0xCDFB, 0x54A1,
+	0xCDFC, 0x54AD, 0xCDFD, 0x54A5, 0xCDFE, 0x54CF, 0xCE40, 0x54C3,
+	0xCE41, 0x830D, 0xCE42, 0x54B7, 0xCE43, 0x54AE, 0xCE44, 0x54D6,
+	0xCE45, 0x54B6, 0xCE46, 0x54C5, 0xCE47, 0x54C6, 0xCE48, 0x54A0,
+	0xCE49, 0x5470, 0xCE4A, 0x54BC, 0xCE4B, 0x54A2, 0xCE4C, 0x54BE,
+	0xCE4D, 0x5472, 0xCE4E, 0x54DE, 0xCE4F, 0x54B0, 0xCE50, 0x57B5,
+	0xCE51, 0x579E, 0xCE52, 0x579F, 0xCE53, 0x57A4, 0xCE54, 0x578C,
+	0xCE55, 0x5797, 0xCE56, 0x579D, 0xCE57, 0x579B, 0xCE58, 0x5794,
+	0xCE59, 0x5798, 0xCE5A, 0x578F, 0xCE5B, 0x5799, 0xCE5C, 0x57A5,
+	0xCE5D, 0x579A, 0xCE5E, 0x5795, 0xCE5F, 0x58F4, 0xCE60, 0x590D,
+	0xCE61, 0x5953, 0xCE62, 0x59E1, 0xCE63, 0x59DE, 0xCE64, 0x59EE,
+	0xCE65, 0x5A00, 0xCE66, 0x59F1, 0xCE67, 0x59DD, 0xCE68, 0x59FA,
+	0xCE69, 0x59FD, 0xCE6A, 0x59FC, 0xCE6B, 0x59F6, 0xCE6C, 0x59E4,
+	0xCE6D, 0x59F2, 0xCE6E, 0x59F7, 0xCE6F, 0x59DB, 0xCE70, 0x59E9,
+	0xCE71, 0x59F3, 0xCE72, 0x59F5, 0xCE73, 0x59E0, 0xCE74, 0x59FE,
+	0xCE75, 0x59F4, 0xCE76, 0x59ED, 0xCE77, 0x5BA8, 0xCE78, 0x5C4C,
+	0xCE79, 0x5CD0, 0xCE7A, 0x5CD8, 0xCE7B, 0x5CCC, 0xCE7C, 0x5CD7,
+	0xCE7D, 0x5CCB, 0xCE7E, 0x5CDB, 0xCEA1, 0x5CDE, 0xCEA2, 0x5CDA,
+	0xCEA3, 0x5CC9, 0xCEA4, 0x5CC7, 0xCEA5, 0x5CCA, 0xCEA6, 0x5CD6,
+	0xCEA7, 0x5CD3, 0xCEA8, 0x5CD4, 0xCEA9, 0x5CCF, 0xCEAA, 0x5CC8,
+	0xCEAB, 0x5CC6, 0xCEAC, 0x5CCE, 0xCEAD, 0x5CDF, 0xCEAE, 0x5CF8,
+	0xCEAF, 0x5DF9, 0xCEB0, 0x5E21, 0xCEB1, 0x5E22, 0xCEB2, 0x5E23,
+	0xCEB3, 0x5E20, 0xCEB4, 0x5E24, 0xCEB5, 0x5EB0, 0xCEB6, 0x5EA4,
+	0xCEB7, 0x5EA2, 0xCEB8, 0x5E9B, 0xCEB9, 0x5EA3, 0xCEBA, 0x5EA5,
+	0xCEBB, 0x5F07, 0xCEBC, 0x5F2E, 0xCEBD, 0x5F56, 0xCEBE, 0x5F86,
+	0xCEBF, 0x6037, 0xCEC0, 0x6039, 0xCEC1, 0x6054, 0xCEC2, 0x6072,
+	0xCEC3, 0x605E, 0xCEC4, 0x6045, 0xCEC5, 0x6053, 0xCEC6, 0x6047,
+	0xCEC7, 0x6049, 0xCEC8, 0x605B, 0xCEC9, 0x604C, 0xCECA, 0x6040,
+	0xCECB, 0x6042, 0xCECC, 0x605F, 0xCECD, 0x6024, 0xCECE, 0x6044,
+	0xCECF, 0x6058, 0xCED0, 0x6066, 0xCED1, 0x606E, 0xCED2, 0x6242,
+	0xCED3, 0x6243, 0xCED4, 0x62CF, 0xCED5, 0x630D, 0xCED6, 0x630B,
+	0xCED7, 0x62F5, 0xCED8, 0x630E, 0xCED9, 0x6303, 0xCEDA, 0x62EB,
+	0xCEDB, 0x62F9, 0xCEDC, 0x630F, 0xCEDD, 0x630C, 0xCEDE, 0x62F8,
+	0xCEDF, 0x62F6, 0xCEE0, 0x6300, 0xCEE1, 0x6313, 0xCEE2, 0x6314,
+	0xCEE3, 0x62FA, 0xCEE4, 0x6315, 0xCEE5, 0x62FB, 0xCEE6, 0x62F0,
+	0xCEE7, 0x6541, 0xCEE8, 0x6543, 0xCEE9, 0x65AA, 0xCEEA, 0x65BF,
+	0xCEEB, 0x6636, 0xCEEC, 0x6621, 0xCEED, 0x6632, 0xCEEE, 0x6635,
+	0xCEEF, 0x661C, 0xCEF0, 0x6626, 0xCEF1, 0x6622, 0xCEF2, 0x6633,
+	0xCEF3, 0x662B, 0xCEF4, 0x663A, 0xCEF5, 0x661D, 0xCEF6, 0x6634,
+	0xCEF7, 0x6639, 0xCEF8, 0x662E, 0xCEF9, 0x670F, 0xCEFA, 0x6710,
+	0xCEFB, 0x67C1, 0xCEFC, 0x67F2, 0xCEFD, 0x67C8, 0xCEFE, 0x67BA,
+	0xCF40, 0x67DC, 0xCF41, 0x67BB, 0xCF42, 0x67F8, 0xCF43, 0x67D8,
+	0xCF44, 0x67C0, 0xCF45, 0x67B7, 0xCF46, 0x67C5, 0xCF47, 0x67EB,
+	0xCF48, 0x67E4, 0xCF49, 0x67DF, 0xCF4A, 0x67B5, 0xCF4B, 0x67CD,
+	0xCF4C, 0x67B3, 0xCF4D, 0x67F7, 0xCF4E, 0x67F6, 0xCF4F, 0x67EE,
+	0xCF50, 0x67E3, 0xCF51, 0x67C2, 0xCF52, 0x67B9, 0xCF53, 0x67CE,
+	0xCF54, 0x67E7, 0xCF55, 0x67F0, 0xCF56, 0x67B2, 0xCF57, 0x67FC,
+	0xCF58, 0x67C6, 0xCF59, 0x67ED, 0xCF5A, 0x67CC, 0xCF5B, 0x67AE,
+	0xCF5C, 0x67E6, 0xCF5D, 0x67DB, 0xCF5E, 0x67FA, 0xCF5F, 0x67C9,
+	0xCF60, 0x67CA, 0xCF61, 0x67C3, 0xCF62, 0x67EA, 0xCF63, 0x67CB,
+	0xCF64, 0x6B28, 0xCF65, 0x6B82, 0xCF66, 0x6B84, 0xCF67, 0x6BB6,
+	0xCF68, 0x6BD6, 0xCF69, 0x6BD8, 0xCF6A, 0x6BE0, 0xCF6B, 0x6C20,
+	0xCF6C, 0x6C21, 0xCF6D, 0x6D28, 0xCF6E, 0x6D34, 0xCF6F, 0x6D2D,
+	0xCF70, 0x6D1F, 0xCF71, 0x6D3C, 0xCF72, 0x6D3F, 0xCF73, 0x6D12,
+	0xCF74, 0x6D0A, 0xCF75, 0x6CDA, 0xCF76, 0x6D33, 0xCF77, 0x6D04,
+	0xCF78, 0x6D19, 0xCF79, 0x6D3A, 0xCF7A, 0x6D1A, 0xCF7B, 0x6D11,
+	0xCF7C, 0x6D00, 0xCF7D, 0x6D1D, 0xCF7E, 0x6D42, 0xCFA1, 0x6D01,
+	0xCFA2, 0x6D18, 0xCFA3, 0x6D37, 0xCFA4, 0x6D03, 0xCFA5, 0x6D0F,
+	0xCFA6, 0x6D40, 0xCFA7, 0x6D07, 0xCFA8, 0x6D20, 0xCFA9, 0x6D2C,
+	0xCFAA, 0x6D08, 0xCFAB, 0x6D22, 0xCFAC, 0x6D09, 0xCFAD, 0x6D10,
+	0xCFAE, 0x70B7, 0xCFAF, 0x709F, 0xCFB0, 0x70BE, 0xCFB1, 0x70B1,
+	0xCFB2, 0x70B0, 0xCFB3, 0x70A1, 0xCFB4, 0x70B4, 0xCFB5, 0x70B5,
+	0xCFB6, 0x70A9, 0xCFB7, 0x7241, 0xCFB8, 0x7249, 0xCFB9, 0x724A,
+	0xCFBA, 0x726C, 0xCFBB, 0x7270, 0xCFBC, 0x7273, 0xCFBD, 0x726E,
+	0xCFBE, 0x72CA, 0xCFBF, 0x72E4, 0xCFC0, 0x72E8, 0xCFC1, 0x72EB,
+	0xCFC2, 0x72DF, 0xCFC3, 0x72EA, 0xCFC4, 0x72E6, 0xCFC5, 0x72E3,
+	0xCFC6, 0x7385, 0xCFC7, 0x73CC, 0xCFC8, 0x73C2, 0xCFC9, 0x73C8,
+	0xCFCA, 0x73C5, 0xCFCB, 0x73B9, 0xCFCC, 0x73B6, 0xCFCD, 0x73B5,
+	0xCFCE, 0x73B4, 0xCFCF, 0x73EB, 0xCFD0, 0x73BF, 0xCFD1, 0x73C7,
+	0xCFD2, 0x73BE, 0xCFD3, 0x73C3, 0xCFD4, 0x73C6, 0xCFD5, 0x73B8,
+	0xCFD6, 0x73CB, 0xCFD7, 0x74EC, 0xCFD8, 0x74EE, 0xCFD9, 0x752E,
+	0xCFDA, 0x7547, 0xCFDB, 0x7548, 0xCFDC, 0x75A7, 0xCFDD, 0x75AA,
+	0xCFDE, 0x7679, 0xCFDF, 0x76C4, 0xCFE0, 0x7708, 0xCFE1, 0x7703,
+	0xCFE2, 0x7704, 0xCFE3, 0x7705, 0xCFE4, 0x770A, 0xCFE5, 0x76F7,
+	0xCFE6, 0x76FB, 0xCFE7, 0x76FA, 0xCFE8, 0x77E7, 0xCFE9, 0x77E8,
+	0xCFEA, 0x7806, 0xCFEB, 0x7811, 0xCFEC, 0x7812, 0xCFED, 0x7805,
+	0xCFEE, 0x7810, 0xCFEF, 0x780F, 0xCFF0, 0x780E, 0xCFF1, 0x7809,
+	0xCFF2, 0x7803, 0xCFF3, 0x7813, 0xCFF4, 0x794A, 0xCFF5, 0x794C,
+	0xCFF6, 0x794B, 0xCFF7, 0x7945, 0xCFF8, 0x7944, 0xCFF9, 0x79D5,
+	0xCFFA, 0x79CD, 0xCFFB, 0x79CF, 0xCFFC, 0x79D6, 0xCFFD, 0x79CE,
+	0xCFFE, 0x7A80, 0xD040, 0x7A7E, 0xD041, 0x7AD1, 0xD042, 0x7B00,
+	0xD043, 0x7B01, 0xD044, 0x7C7A, 0xD045, 0x7C78, 0xD046, 0x7C79,
+	0xD047, 0x7C7F, 0xD048, 0x7C80, 0xD049, 0x7C81, 0xD04A, 0x7D03,
+	0xD04B, 0x7D08, 0xD04C, 0x7D01, 0xD04D, 0x7F58, 0xD04E, 0x7F91,
+	0xD04F, 0x7F8D, 0xD050, 0x7FBE, 0xD051, 0x8007, 0xD052, 0x800E,
+	0xD053, 0x800F, 0xD054, 0x8014, 0xD055, 0x8037, 0xD056, 0x80D8,
+	0xD057, 0x80C7, 0xD058, 0x80E0, 0xD059, 0x80D1, 0xD05A, 0x80C8,
+	0xD05B, 0x80C2, 0xD05C, 0x80D0, 0xD05D, 0x80C5, 0xD05E, 0x80E3,
+	0xD05F, 0x80D9, 0xD060, 0x80DC, 0xD061, 0x80CA, 0xD062, 0x80D5,
+	0xD063, 0x80C9, 0xD064, 0x80CF, 0xD065, 0x80D7, 0xD066, 0x80E6,
+	0xD067, 0x80CD, 0xD068, 0x81FF, 0xD069, 0x8221, 0xD06A, 0x8294,
+	0xD06B, 0x82D9, 0xD06C, 0x82FE, 0xD06D, 0x82F9, 0xD06E, 0x8307,
+	0xD06F, 0x82E8, 0xD070, 0x8300, 0xD071, 0x82D5, 0xD072, 0x833A,
+	0xD073, 0x82EB, 0xD074, 0x82D6, 0xD075, 0x82F4, 0xD076, 0x82EC,
+	0xD077, 0x82E1, 0xD078, 0x82F2, 0xD079, 0x82F5, 0xD07A, 0x830C,
+	0xD07B, 0x82FB, 0xD07C, 0x82F6, 0xD07D, 0x82F0, 0xD07E, 0x82EA,
+	0xD0A1, 0x82E4, 0xD0A2, 0x82E0, 0xD0A3, 0x82FA, 0xD0A4, 0x82F3,
+	0xD0A5, 0x82ED, 0xD0A6, 0x8677, 0xD0A7, 0x8674, 0xD0A8, 0x867C,
+	0xD0A9, 0x8673, 0xD0AA, 0x8841, 0xD0AB, 0x884E, 0xD0AC, 0x8867,
+	0xD0AD, 0x886A, 0xD0AE, 0x8869, 0xD0AF, 0x89D3, 0xD0B0, 0x8A04,
+	0xD0B1, 0x8A07, 0xD0B2, 0x8D72, 0xD0B3, 0x8FE3, 0xD0B4, 0x8FE1,
+	0xD0B5, 0x8FEE, 0xD0B6, 0x8FE0, 0xD0B7, 0x90F1, 0xD0B8, 0x90BD,
+	0xD0B9, 0x90BF, 0xD0BA, 0x90D5, 0xD0BB, 0x90C5, 0xD0BC, 0x90BE,
+	0xD0BD, 0x90C7, 0xD0BE, 0x90CB, 0xD0BF, 0x90C8, 0xD0C0, 0x91D4,
+	0xD0C1, 0x91D3, 0xD0C2, 0x9654, 0xD0C3, 0x964F, 0xD0C4, 0x9651,
+	0xD0C5, 0x9653, 0xD0C6, 0x964A, 0xD0C7, 0x964E, 0xD0C8, 0x501E,
+	0xD0C9, 0x5005, 0xD0CA, 0x5007, 0xD0CB, 0x5013, 0xD0CC, 0x5022,
+	0xD0CD, 0x5030, 0xD0CE, 0x501B, 0xD0CF, 0x4FF5, 0xD0D0, 0x4FF4,
+	0xD0D1, 0x5033, 0xD0D2, 0x5037, 0xD0D3, 0x502C, 0xD0D4, 0x4FF6,
+	0xD0D5, 0x4FF7, 0xD0D6, 0x5017, 0xD0D7, 0x501C, 0xD0D8, 0x5020,
+	0xD0D9, 0x5027, 0xD0DA, 0x5035, 0xD0DB, 0x502F, 0xD0DC, 0x5031,
+	0xD0DD, 0x500E, 0xD0DE, 0x515A, 0xD0DF, 0x5194, 0xD0E0, 0x5193,
+	0xD0E1, 0x51CA, 0xD0E2, 0x51C4, 0xD0E3, 0x51C5, 0xD0E4, 0x51C8,
+	0xD0E5, 0x51CE, 0xD0E6, 0x5261, 0xD0E7, 0x525A, 0xD0E8, 0x5252,
+	0xD0E9, 0x525E, 0xD0EA, 0x525F, 0xD0EB, 0x5255, 0xD0EC, 0x5262,
+	0xD0ED, 0x52CD, 0xD0EE, 0x530E, 0xD0EF, 0x539E, 0xD0F0, 0x5526,
+	0xD0F1, 0x54E2, 0xD0F2, 0x5517, 0xD0F3, 0x5512, 0xD0F4, 0x54E7,
+	0xD0F5, 0x54F3, 0xD0F6, 0x54E4, 0xD0F7, 0x551A, 0xD0F8, 0x54FF,
+	0xD0F9, 0x5504, 0xD0FA, 0x5508, 0xD0FB, 0x54EB, 0xD0FC, 0x5511,
+	0xD0FD, 0x5505, 0xD0FE, 0x54F1, 0xD140, 0x550A, 0xD141, 0x54FB,
+	0xD142, 0x54F7, 0xD143, 0x54F8, 0xD144, 0x54E0, 0xD145, 0x550E,
+	0xD146, 0x5503, 0xD147, 0x550B, 0xD148, 0x5701, 0xD149, 0x5702,
+	0xD14A, 0x57CC, 0xD14B, 0x5832, 0xD14C, 0x57D5, 0xD14D, 0x57D2,
+	0xD14E, 0x57BA, 0xD14F, 0x57C6, 0xD150, 0x57BD, 0xD151, 0x57BC,
+	0xD152, 0x57B8, 0xD153, 0x57B6, 0xD154, 0x57BF, 0xD155, 0x57C7,
+	0xD156, 0x57D0, 0xD157, 0x57B9, 0xD158, 0x57C1, 0xD159, 0x590E,
+	0xD15A, 0x594A, 0xD15B, 0x5A19, 0xD15C, 0x5A16, 0xD15D, 0x5A2D,
+	0xD15E, 0x5A2E, 0xD15F, 0x5A15, 0xD160, 0x5A0F, 0xD161, 0x5A17,
+	0xD162, 0x5A0A, 0xD163, 0x5A1E, 0xD164, 0x5A33, 0xD165, 0x5B6C,
+	0xD166, 0x5BA7, 0xD167, 0x5BAD, 0xD168, 0x5BAC, 0xD169, 0x5C03,
+	0xD16A, 0x5C56, 0xD16B, 0x5C54, 0xD16C, 0x5CEC, 0xD16D, 0x5CFF,
+	0xD16E, 0x5CEE, 0xD16F, 0x5CF1, 0xD170, 0x5CF7, 0xD171, 0x5D00,
+	0xD172, 0x5CF9, 0xD173, 0x5E29, 0xD174, 0x5E28, 0xD175, 0x5EA8,
+	0xD176, 0x5EAE, 0xD177, 0x5EAA, 0xD178, 0x5EAC, 0xD179, 0x5F33,
+	0xD17A, 0x5F30, 0xD17B, 0x5F67, 0xD17C, 0x605D, 0xD17D, 0x605A,
+	0xD17E, 0x6067, 0xD1A1, 0x6041, 0xD1A2, 0x60A2, 0xD1A3, 0x6088,
+	0xD1A4, 0x6080, 0xD1A5, 0x6092, 0xD1A6, 0x6081, 0xD1A7, 0x609D,
+	0xD1A8, 0x6083, 0xD1A9, 0x6095, 0xD1AA, 0x609B, 0xD1AB, 0x6097,
+	0xD1AC, 0x6087, 0xD1AD, 0x609C, 0xD1AE, 0x608E, 0xD1AF, 0x6219,
+	0xD1B0, 0x6246, 0xD1B1, 0x62F2, 0xD1B2, 0x6310, 0xD1B3, 0x6356,
+	0xD1B4, 0x632C, 0xD1B5, 0x6344, 0xD1B6, 0x6345, 0xD1B7, 0x6336,
+	0xD1B8, 0x6343, 0xD1B9, 0x63E4, 0xD1BA, 0x6339, 0xD1BB, 0x634B,
+	0xD1BC, 0x634A, 0xD1BD, 0x633C, 0xD1BE, 0x6329, 0xD1BF, 0x6341,
+	0xD1C0, 0x6334, 0xD1C1, 0x6358, 0xD1C2, 0x6354, 0xD1C3, 0x6359,
+	0xD1C4, 0x632D, 0xD1C5, 0x6347, 0xD1C6, 0x6333, 0xD1C7, 0x635A,
+	0xD1C8, 0x6351, 0xD1C9, 0x6338, 0xD1CA, 0x6357, 0xD1CB, 0x6340,
+	0xD1CC, 0x6348, 0xD1CD, 0x654A, 0xD1CE, 0x6546, 0xD1CF, 0x65C6,
+	0xD1D0, 0x65C3, 0xD1D1, 0x65C4, 0xD1D2, 0x65C2, 0xD1D3, 0x664A,
+	0xD1D4, 0x665F, 0xD1D5, 0x6647, 0xD1D6, 0x6651, 0xD1D7, 0x6712,
+	0xD1D8, 0x6713, 0xD1D9, 0x681F, 0xD1DA, 0x681A, 0xD1DB, 0x6849,
+	0xD1DC, 0x6832, 0xD1DD, 0x6833, 0xD1DE, 0x683B, 0xD1DF, 0x684B,
+	0xD1E0, 0x684F, 0xD1E1, 0x6816, 0xD1E2, 0x6831, 0xD1E3, 0x681C,
+	0xD1E4, 0x6835, 0xD1E5, 0x682B, 0xD1E6, 0x682D, 0xD1E7, 0x682F,
+	0xD1E8, 0x684E, 0xD1E9, 0x6844, 0xD1EA, 0x6834, 0xD1EB, 0x681D,
+	0xD1EC, 0x6812, 0xD1ED, 0x6814, 0xD1EE, 0x6826, 0xD1EF, 0x6828,
+	0xD1F0, 0x682E, 0xD1F1, 0x684D, 0xD1F2, 0x683A, 0xD1F3, 0x6825,
+	0xD1F4, 0x6820, 0xD1F5, 0x6B2C, 0xD1F6, 0x6B2F, 0xD1F7, 0x6B2D,
+	0xD1F8, 0x6B31, 0xD1F9, 0x6B34, 0xD1FA, 0x6B6D, 0xD1FB, 0x8082,
+	0xD1FC, 0x6B88, 0xD1FD, 0x6BE6, 0xD1FE, 0x6BE4, 0xD240, 0x6BE8,
+	0xD241, 0x6BE3, 0xD242, 0x6BE2, 0xD243, 0x6BE7, 0xD244, 0x6C25,
+	0xD245, 0x6D7A, 0xD246, 0x6D63, 0xD247, 0x6D64, 0xD248, 0x6D76,
+	0xD249, 0x6D0D, 0xD24A, 0x6D61, 0xD24B, 0x6D92, 0xD24C, 0x6D58,
+	0xD24D, 0x6D62, 0xD24E, 0x6D6D, 0xD24F, 0x6D6F, 0xD250, 0x6D91,
+	0xD251, 0x6D8D, 0xD252, 0x6DEF, 0xD253, 0x6D7F, 0xD254, 0x6D86,
+	0xD255, 0x6D5E, 0xD256, 0x6D67, 0xD257, 0x6D60, 0xD258, 0x6D97,
+	0xD259, 0x6D70, 0xD25A, 0x6D7C, 0xD25B, 0x6D5F, 0xD25C, 0x6D82,
+	0xD25D, 0x6D98, 0xD25E, 0x6D2F, 0xD25F, 0x6D68, 0xD260, 0x6D8B,
+	0xD261, 0x6D7E, 0xD262, 0x6D80, 0xD263, 0x6D84, 0xD264, 0x6D16,
+	0xD265, 0x6D83, 0xD266, 0x6D7B, 0xD267, 0x6D7D, 0xD268, 0x6D75,
+	0xD269, 0x6D90, 0xD26A, 0x70DC, 0xD26B, 0x70D3, 0xD26C, 0x70D1,
+	0xD26D, 0x70DD, 0xD26E, 0x70CB, 0xD26F, 0x7F39, 0xD270, 0x70E2,
+	0xD271, 0x70D7, 0xD272, 0x70D2, 0xD273, 0x70DE, 0xD274, 0x70E0,
+	0xD275, 0x70D4, 0xD276, 0x70CD, 0xD277, 0x70C5, 0xD278, 0x70C6,
+	0xD279, 0x70C7, 0xD27A, 0x70DA, 0xD27B, 0x70CE, 0xD27C, 0x70E1,
+	0xD27D, 0x7242, 0xD27E, 0x7278, 0xD2A1, 0x7277, 0xD2A2, 0x7276,
+	0xD2A3, 0x7300, 0xD2A4, 0x72FA, 0xD2A5, 0x72F4, 0xD2A6, 0x72FE,
+	0xD2A7, 0x72F6, 0xD2A8, 0x72F3, 0xD2A9, 0x72FB, 0xD2AA, 0x7301,
+	0xD2AB, 0x73D3, 0xD2AC, 0x73D9, 0xD2AD, 0x73E5, 0xD2AE, 0x73D6,
+	0xD2AF, 0x73BC, 0xD2B0, 0x73E7, 0xD2B1, 0x73E3, 0xD2B2, 0x73E9,
+	0xD2B3, 0x73DC, 0xD2B4, 0x73D2, 0xD2B5, 0x73DB, 0xD2B6, 0x73D4,
+	0xD2B7, 0x73DD, 0xD2B8, 0x73DA, 0xD2B9, 0x73D7, 0xD2BA, 0x73D8,
+	0xD2BB, 0x73E8, 0xD2BC, 0x74DE, 0xD2BD, 0x74DF, 0xD2BE, 0x74F4,
+	0xD2BF, 0x74F5, 0xD2C0, 0x7521, 0xD2C1, 0x755B, 0xD2C2, 0x755F,
+	0xD2C3, 0x75B0, 0xD2C4, 0x75C1, 0xD2C5, 0x75BB, 0xD2C6, 0x75C4,
+	0xD2C7, 0x75C0, 0xD2C8, 0x75BF, 0xD2C9, 0x75B6, 0xD2CA, 0x75BA,
+	0xD2CB, 0x768A, 0xD2CC, 0x76C9, 0xD2CD, 0x771D, 0xD2CE, 0x771B,
+	0xD2CF, 0x7710, 0xD2D0, 0x7713, 0xD2D1, 0x7712, 0xD2D2, 0x7723,
+	0xD2D3, 0x7711, 0xD2D4, 0x7715, 0xD2D5, 0x7719, 0xD2D6, 0x771A,
+	0xD2D7, 0x7722, 0xD2D8, 0x7727, 0xD2D9, 0x7823, 0xD2DA, 0x782C,
+	0xD2DB, 0x7822, 0xD2DC, 0x7835, 0xD2DD, 0x782F, 0xD2DE, 0x7828,
+	0xD2DF, 0x782E, 0xD2E0, 0x782B, 0xD2E1, 0x7821, 0xD2E2, 0x7829,
+	0xD2E3, 0x7833, 0xD2E4, 0x782A, 0xD2E5, 0x7831, 0xD2E6, 0x7954,
+	0xD2E7, 0x795B, 0xD2E8, 0x794F, 0xD2E9, 0x795C, 0xD2EA, 0x7953,
+	0xD2EB, 0x7952, 0xD2EC, 0x7951, 0xD2ED, 0x79EB, 0xD2EE, 0x79EC,
+	0xD2EF, 0x79E0, 0xD2F0, 0x79EE, 0xD2F1, 0x79ED, 0xD2F2, 0x79EA,
+	0xD2F3, 0x79DC, 0xD2F4, 0x79DE, 0xD2F5, 0x79DD, 0xD2F6, 0x7A86,
+	0xD2F7, 0x7A89, 0xD2F8, 0x7A85, 0xD2F9, 0x7A8B, 0xD2FA, 0x7A8C,
+	0xD2FB, 0x7A8A, 0xD2FC, 0x7A87, 0xD2FD, 0x7AD8, 0xD2FE, 0x7B10,
+	0xD340, 0x7B04, 0xD341, 0x7B13, 0xD342, 0x7B05, 0xD343, 0x7B0F,
+	0xD344, 0x7B08, 0xD345, 0x7B0A, 0xD346, 0x7B0E, 0xD347, 0x7B09,
+	0xD348, 0x7B12, 0xD349, 0x7C84, 0xD34A, 0x7C91, 0xD34B, 0x7C8A,
+	0xD34C, 0x7C8C, 0xD34D, 0x7C88, 0xD34E, 0x7C8D, 0xD34F, 0x7C85,
+	0xD350, 0x7D1E, 0xD351, 0x7D1D, 0xD352, 0x7D11, 0xD353, 0x7D0E,
+	0xD354, 0x7D18, 0xD355, 0x7D16, 0xD356, 0x7D13, 0xD357, 0x7D1F,
+	0xD358, 0x7D12, 0xD359, 0x7D0F, 0xD35A, 0x7D0C, 0xD35B, 0x7F5C,
+	0xD35C, 0x7F61, 0xD35D, 0x7F5E, 0xD35E, 0x7F60, 0xD35F, 0x7F5D,
+	0xD360, 0x7F5B, 0xD361, 0x7F96, 0xD362, 0x7F92, 0xD363, 0x7FC3,
+	0xD364, 0x7FC2, 0xD365, 0x7FC0, 0xD366, 0x8016, 0xD367, 0x803E,
+	0xD368, 0x8039, 0xD369, 0x80FA, 0xD36A, 0x80F2, 0xD36B, 0x80F9,
+	0xD36C, 0x80F5, 0xD36D, 0x8101, 0xD36E, 0x80FB, 0xD36F, 0x8100,
+	0xD370, 0x8201, 0xD371, 0x822F, 0xD372, 0x8225, 0xD373, 0x8333,
+	0xD374, 0x832D, 0xD375, 0x8344, 0xD376, 0x8319, 0xD377, 0x8351,
+	0xD378, 0x8325, 0xD379, 0x8356, 0xD37A, 0x833F, 0xD37B, 0x8341,
+	0xD37C, 0x8326, 0xD37D, 0x831C, 0xD37E, 0x8322, 0xD3A1, 0x8342,
+	0xD3A2, 0x834E, 0xD3A3, 0x831B, 0xD3A4, 0x832A, 0xD3A5, 0x8308,
+	0xD3A6, 0x833C, 0xD3A7, 0x834D, 0xD3A8, 0x8316, 0xD3A9, 0x8324,
+	0xD3AA, 0x8320, 0xD3AB, 0x8337, 0xD3AC, 0x832F, 0xD3AD, 0x8329,
+	0xD3AE, 0x8347, 0xD3AF, 0x8345, 0xD3B0, 0x834C, 0xD3B1, 0x8353,
+	0xD3B2, 0x831E, 0xD3B3, 0x832C, 0xD3B4, 0x834B, 0xD3B5, 0x8327,
+	0xD3B6, 0x8348, 0xD3B7, 0x8653, 0xD3B8, 0x8652, 0xD3B9, 0x86A2,
+	0xD3BA, 0x86A8, 0xD3BB, 0x8696, 0xD3BC, 0x868D, 0xD3BD, 0x8691,
+	0xD3BE, 0x869E, 0xD3BF, 0x8687, 0xD3C0, 0x8697, 0xD3C1, 0x8686,
+	0xD3C2, 0x868B, 0xD3C3, 0x869A, 0xD3C4, 0x8685, 0xD3C5, 0x86A5,
+	0xD3C6, 0x8699, 0xD3C7, 0x86A1, 0xD3C8, 0x86A7, 0xD3C9, 0x8695,
+	0xD3CA, 0x8698, 0xD3CB, 0x868E, 0xD3CC, 0x869D, 0xD3CD, 0x8690,
+	0xD3CE, 0x8694, 0xD3CF, 0x8843, 0xD3D0, 0x8844, 0xD3D1, 0x886D,
+	0xD3D2, 0x8875, 0xD3D3, 0x8876, 0xD3D4, 0x8872, 0xD3D5, 0x8880,
+	0xD3D6, 0x8871, 0xD3D7, 0x887F, 0xD3D8, 0x886F, 0xD3D9, 0x8883,
+	0xD3DA, 0x887E, 0xD3DB, 0x8874, 0xD3DC, 0x887C, 0xD3DD, 0x8A12,
+	0xD3DE, 0x8C47, 0xD3DF, 0x8C57, 0xD3E0, 0x8C7B, 0xD3E1, 0x8CA4,
+	0xD3E2, 0x8CA3, 0xD3E3, 0x8D76, 0xD3E4, 0x8D78, 0xD3E5, 0x8DB5,
+	0xD3E6, 0x8DB7, 0xD3E7, 0x8DB6, 0xD3E8, 0x8ED1, 0xD3E9, 0x8ED3,
+	0xD3EA, 0x8FFE, 0xD3EB, 0x8FF5, 0xD3EC, 0x9002, 0xD3ED, 0x8FFF,
+	0xD3EE, 0x8FFB, 0xD3EF, 0x9004, 0xD3F0, 0x8FFC, 0xD3F1, 0x8FF6,
+	0xD3F2, 0x90D6, 0xD3F3, 0x90E0, 0xD3F4, 0x90D9, 0xD3F5, 0x90DA,
+	0xD3F6, 0x90E3, 0xD3F7, 0x90DF, 0xD3F8, 0x90E5, 0xD3F9, 0x90D8,
+	0xD3FA, 0x90DB, 0xD3FB, 0x90D7, 0xD3FC, 0x90DC, 0xD3FD, 0x90E4,
+	0xD3FE, 0x9150, 0xD440, 0x914E, 0xD441, 0x914F, 0xD442, 0x91D5,
+	0xD443, 0x91E2, 0xD444, 0x91DA, 0xD445, 0x965C, 0xD446, 0x965F,
+	0xD447, 0x96BC, 0xD448, 0x98E3, 0xD449, 0x9ADF, 0xD44A, 0x9B2F,
+	0xD44B, 0x4E7F, 0xD44C, 0x5070, 0xD44D, 0x506A, 0xD44E, 0x5061,
+	0xD44F, 0x505E, 0xD450, 0x5060, 0xD451, 0x5053, 0xD452, 0x504B,
+	0xD453, 0x505D, 0xD454, 0x5072, 0xD455, 0x5048, 0xD456, 0x504D,
+	0xD457, 0x5041, 0xD458, 0x505B, 0xD459, 0x504A, 0xD45A, 0x5062,
+	0xD45B, 0x5015, 0xD45C, 0x5045, 0xD45D, 0x505F, 0xD45E, 0x5069,
+	0xD45F, 0x506B, 0xD460, 0x5063, 0xD461, 0x5064, 0xD462, 0x5046,
+	0xD463, 0x5040, 0xD464, 0x506E, 0xD465, 0x5073, 0xD466, 0x5057,
+	0xD467, 0x5051, 0xD468, 0x51D0, 0xD469, 0x526B, 0xD46A, 0x526D,
+	0xD46B, 0x526C, 0xD46C, 0x526E, 0xD46D, 0x52D6, 0xD46E, 0x52D3,
+	0xD46F, 0x532D, 0xD470, 0x539C, 0xD471, 0x5575, 0xD472, 0x5576,
+	0xD473, 0x553C, 0xD474, 0x554D, 0xD475, 0x5550, 0xD476, 0x5534,
+	0xD477, 0x552A, 0xD478, 0x5551, 0xD479, 0x5562, 0xD47A, 0x5536,
+	0xD47B, 0x5535, 0xD47C, 0x5530, 0xD47D, 0x5552, 0xD47E, 0x5545,
+	0xD4A1, 0x550C, 0xD4A2, 0x5532, 0xD4A3, 0x5565, 0xD4A4, 0x554E,
+	0xD4A5, 0x5539, 0xD4A6, 0x5548, 0xD4A7, 0x552D, 0xD4A8, 0x553B,
+	0xD4A9, 0x5540, 0xD4AA, 0x554B, 0xD4AB, 0x570A, 0xD4AC, 0x5707,
+	0xD4AD, 0x57FB, 0xD4AE, 0x5814, 0xD4AF, 0x57E2, 0xD4B0, 0x57F6,
+	0xD4B1, 0x57DC, 0xD4B2, 0x57F4, 0xD4B3, 0x5800, 0xD4B4, 0x57ED,
+	0xD4B5, 0x57FD, 0xD4B6, 0x5808, 0xD4B7, 0x57F8, 0xD4B8, 0x580B,
+	0xD4B9, 0x57F3, 0xD4BA, 0x57CF, 0xD4BB, 0x5807, 0xD4BC, 0x57EE,
+	0xD4BD, 0x57E3, 0xD4BE, 0x57F2, 0xD4BF, 0x57E5, 0xD4C0, 0x57EC,
+	0xD4C1, 0x57E1, 0xD4C2, 0x580E, 0xD4C3, 0x57FC, 0xD4C4, 0x5810,
+	0xD4C5, 0x57E7, 0xD4C6, 0x5801, 0xD4C7, 0x580C, 0xD4C8, 0x57F1,
+	0xD4C9, 0x57E9, 0xD4CA, 0x57F0, 0xD4CB, 0x580D, 0xD4CC, 0x5804,
+	0xD4CD, 0x595C, 0xD4CE, 0x5A60, 0xD4CF, 0x5A58, 0xD4D0, 0x5A55,
+	0xD4D1, 0x5A67, 0xD4D2, 0x5A5E, 0xD4D3, 0x5A38, 0xD4D4, 0x5A35,
+	0xD4D5, 0x5A6D, 0xD4D6, 0x5A50, 0xD4D7, 0x5A5F, 0xD4D8, 0x5A65,
+	0xD4D9, 0x5A6C, 0xD4DA, 0x5A53, 0xD4DB, 0x5A64, 0xD4DC, 0x5A57,
+	0xD4DD, 0x5A43, 0xD4DE, 0x5A5D, 0xD4DF, 0x5A52, 0xD4E0, 0x5A44,
+	0xD4E1, 0x5A5B, 0xD4E2, 0x5A48, 0xD4E3, 0x5A8E, 0xD4E4, 0x5A3E,
+	0xD4E5, 0x5A4D, 0xD4E6, 0x5A39, 0xD4E7, 0x5A4C, 0xD4E8, 0x5A70,
+	0xD4E9, 0x5A69, 0xD4EA, 0x5A47, 0xD4EB, 0x5A51, 0xD4EC, 0x5A56,
+	0xD4ED, 0x5A42, 0xD4EE, 0x5A5C, 0xD4EF, 0x5B72, 0xD4F0, 0x5B6E,
+	0xD4F1, 0x5BC1, 0xD4F2, 0x5BC0, 0xD4F3, 0x5C59, 0xD4F4, 0x5D1E,
+	0xD4F5, 0x5D0B, 0xD4F6, 0x5D1D, 0xD4F7, 0x5D1A, 0xD4F8, 0x5D20,
+	0xD4F9, 0x5D0C, 0xD4FA, 0x5D28, 0xD4FB, 0x5D0D, 0xD4FC, 0x5D26,
+	0xD4FD, 0x5D25, 0xD4FE, 0x5D0F, 0xD540, 0x5D30, 0xD541, 0x5D12,
+	0xD542, 0x5D23, 0xD543, 0x5D1F, 0xD544, 0x5D2E, 0xD545, 0x5E3E,
+	0xD546, 0x5E34, 0xD547, 0x5EB1, 0xD548, 0x5EB4, 0xD549, 0x5EB9,
+	0xD54A, 0x5EB2, 0xD54B, 0x5EB3, 0xD54C, 0x5F36, 0xD54D, 0x5F38,
+	0xD54E, 0x5F9B, 0xD54F, 0x5F96, 0xD550, 0x5F9F, 0xD551, 0x608A,
+	0xD552, 0x6090, 0xD553, 0x6086, 0xD554, 0x60BE, 0xD555, 0x60B0,
+	0xD556, 0x60BA, 0xD557, 0x60D3, 0xD558, 0x60D4, 0xD559, 0x60CF,
+	0xD55A, 0x60E4, 0xD55B, 0x60D9, 0xD55C, 0x60DD, 0xD55D, 0x60C8,
+	0xD55E, 0x60B1, 0xD55F, 0x60DB, 0xD560, 0x60B7, 0xD561, 0x60CA,
+	0xD562, 0x60BF, 0xD563, 0x60C3, 0xD564, 0x60CD, 0xD565, 0x60C0,
+	0xD566, 0x6332, 0xD567, 0x6365, 0xD568, 0x638A, 0xD569, 0x6382,
+	0xD56A, 0x637D, 0xD56B, 0x63BD, 0xD56C, 0x639E, 0xD56D, 0x63AD,
+	0xD56E, 0x639D, 0xD56F, 0x6397, 0xD570, 0x63AB, 0xD571, 0x638E,
+	0xD572, 0x636F, 0xD573, 0x6387, 0xD574, 0x6390, 0xD575, 0x636E,
+	0xD576, 0x63AF, 0xD577, 0x6375, 0xD578, 0x639C, 0xD579, 0x636D,
+	0xD57A, 0x63AE, 0xD57B, 0x637C, 0xD57C, 0x63A4, 0xD57D, 0x633B,
+	0xD57E, 0x639F, 0xD5A1, 0x6378, 0xD5A2, 0x6385, 0xD5A3, 0x6381,
+	0xD5A4, 0x6391, 0xD5A5, 0x638D, 0xD5A6, 0x6370, 0xD5A7, 0x6553,
+	0xD5A8, 0x65CD, 0xD5A9, 0x6665, 0xD5AA, 0x6661, 0xD5AB, 0x665B,
+	0xD5AC, 0x6659, 0xD5AD, 0x665C, 0xD5AE, 0x6662, 0xD5AF, 0x6718,
+	0xD5B0, 0x6879, 0xD5B1, 0x6887, 0xD5B2, 0x6890, 0xD5B3, 0x689C,
+	0xD5B4, 0x686D, 0xD5B5, 0x686E, 0xD5B6, 0x68AE, 0xD5B7, 0x68AB,
+	0xD5B8, 0x6956, 0xD5B9, 0x686F, 0xD5BA, 0x68A3, 0xD5BB, 0x68AC,
+	0xD5BC, 0x68A9, 0xD5BD, 0x6875, 0xD5BE, 0x6874, 0xD5BF, 0x68B2,
+	0xD5C0, 0x688F, 0xD5C1, 0x6877, 0xD5C2, 0x6892, 0xD5C3, 0x687C,
+	0xD5C4, 0x686B, 0xD5C5, 0x6872, 0xD5C6, 0x68AA, 0xD5C7, 0x6880,
+	0xD5C8, 0x6871, 0xD5C9, 0x687E, 0xD5CA, 0x689B, 0xD5CB, 0x6896,
+	0xD5CC, 0x688B, 0xD5CD, 0x68A0, 0xD5CE, 0x6889, 0xD5CF, 0x68A4,
+	0xD5D0, 0x6878, 0xD5D1, 0x687B, 0xD5D2, 0x6891, 0xD5D3, 0x688C,
+	0xD5D4, 0x688A, 0xD5D5, 0x687D, 0xD5D6, 0x6B36, 0xD5D7, 0x6B33,
+	0xD5D8, 0x6B37, 0xD5D9, 0x6B38, 0xD5DA, 0x6B91, 0xD5DB, 0x6B8F,
+	0xD5DC, 0x6B8D, 0xD5DD, 0x6B8E, 0xD5DE, 0x6B8C, 0xD5DF, 0x6C2A,
+	0xD5E0, 0x6DC0, 0xD5E1, 0x6DAB, 0xD5E2, 0x6DB4, 0xD5E3, 0x6DB3,
+	0xD5E4, 0x6E74, 0xD5E5, 0x6DAC, 0xD5E6, 0x6DE9, 0xD5E7, 0x6DE2,
+	0xD5E8, 0x6DB7, 0xD5E9, 0x6DF6, 0xD5EA, 0x6DD4, 0xD5EB, 0x6E00,
+	0xD5EC, 0x6DC8, 0xD5ED, 0x6DE0, 0xD5EE, 0x6DDF, 0xD5EF, 0x6DD6,
+	0xD5F0, 0x6DBE, 0xD5F1, 0x6DE5, 0xD5F2, 0x6DDC, 0xD5F3, 0x6DDD,
+	0xD5F4, 0x6DDB, 0xD5F5, 0x6DF4, 0xD5F6, 0x6DCA, 0xD5F7, 0x6DBD,
+	0xD5F8, 0x6DED, 0xD5F9, 0x6DF0, 0xD5FA, 0x6DBA, 0xD5FB, 0x6DD5,
+	0xD5FC, 0x6DC2, 0xD5FD, 0x6DCF, 0xD5FE, 0x6DC9, 0xD640, 0x6DD0,
+	0xD641, 0x6DF2, 0xD642, 0x6DD3, 0xD643, 0x6DFD, 0xD644, 0x6DD7,
+	0xD645, 0x6DCD, 0xD646, 0x6DE3, 0xD647, 0x6DBB, 0xD648, 0x70FA,
+	0xD649, 0x710D, 0xD64A, 0x70F7, 0xD64B, 0x7117, 0xD64C, 0x70F4,
+	0xD64D, 0x710C, 0xD64E, 0x70F0, 0xD64F, 0x7104, 0xD650, 0x70F3,
+	0xD651, 0x7110, 0xD652, 0x70FC, 0xD653, 0x70FF, 0xD654, 0x7106,
+	0xD655, 0x7113, 0xD656, 0x7100, 0xD657, 0x70F8, 0xD658, 0x70F6,
+	0xD659, 0x710B, 0xD65A, 0x7102, 0xD65B, 0x710E, 0xD65C, 0x727E,
+	0xD65D, 0x727B, 0xD65E, 0x727C, 0xD65F, 0x727F, 0xD660, 0x731D,
+	0xD661, 0x7317, 0xD662, 0x7307, 0xD663, 0x7311, 0xD664, 0x7318,
+	0xD665, 0x730A, 0xD666, 0x7308, 0xD667, 0x72FF, 0xD668, 0x730F,
+	0xD669, 0x731E, 0xD66A, 0x7388, 0xD66B, 0x73F6, 0xD66C, 0x73F8,
+	0xD66D, 0x73F5, 0xD66E, 0x7404, 0xD66F, 0x7401, 0xD670, 0x73FD,
+	0xD671, 0x7407, 0xD672, 0x7400, 0xD673, 0x73FA, 0xD674, 0x73FC,
+	0xD675, 0x73FF, 0xD676, 0x740C, 0xD677, 0x740B, 0xD678, 0x73F4,
+	0xD679, 0x7408, 0xD67A, 0x7564, 0xD67B, 0x7563, 0xD67C, 0x75CE,
+	0xD67D, 0x75D2, 0xD67E, 0x75CF, 0xD6A1, 0x75CB, 0xD6A2, 0x75CC,
+	0xD6A3, 0x75D1, 0xD6A4, 0x75D0, 0xD6A5, 0x768F, 0xD6A6, 0x7689,
+	0xD6A7, 0x76D3, 0xD6A8, 0x7739, 0xD6A9, 0x772F, 0xD6AA, 0x772D,
+	0xD6AB, 0x7731, 0xD6AC, 0x7732, 0xD6AD, 0x7734, 0xD6AE, 0x7733,
+	0xD6AF, 0x773D, 0xD6B0, 0x7725, 0xD6B1, 0x773B, 0xD6B2, 0x7735,
+	0xD6B3, 0x7848, 0xD6B4, 0x7852, 0xD6B5, 0x7849, 0xD6B6, 0x784D,
+	0xD6B7, 0x784A, 0xD6B8, 0x784C, 0xD6B9, 0x7826, 0xD6BA, 0x7845,
+	0xD6BB, 0x7850, 0xD6BC, 0x7964, 0xD6BD, 0x7967, 0xD6BE, 0x7969,
+	0xD6BF, 0x796A, 0xD6C0, 0x7963, 0xD6C1, 0x796B, 0xD6C2, 0x7961,
+	0xD6C3, 0x79BB, 0xD6C4, 0x79FA, 0xD6C5, 0x79F8, 0xD6C6, 0x79F6,
+	0xD6C7, 0x79F7, 0xD6C8, 0x7A8F, 0xD6C9, 0x7A94, 0xD6CA, 0x7A90,
+	0xD6CB, 0x7B35, 0xD6CC, 0x7B47, 0xD6CD, 0x7B34, 0xD6CE, 0x7B25,
+	0xD6CF, 0x7B30, 0xD6D0, 0x7B22, 0xD6D1, 0x7B24, 0xD6D2, 0x7B33,
+	0xD6D3, 0x7B18, 0xD6D4, 0x7B2A, 0xD6D5, 0x7B1D, 0xD6D6, 0x7B31,
+	0xD6D7, 0x7B2B, 0xD6D8, 0x7B2D, 0xD6D9, 0x7B2F, 0xD6DA, 0x7B32,
+	0xD6DB, 0x7B38, 0xD6DC, 0x7B1A, 0xD6DD, 0x7B23, 0xD6DE, 0x7C94,
+	0xD6DF, 0x7C98, 0xD6E0, 0x7C96, 0xD6E1, 0x7CA3, 0xD6E2, 0x7D35,
+	0xD6E3, 0x7D3D, 0xD6E4, 0x7D38, 0xD6E5, 0x7D36, 0xD6E6, 0x7D3A,
+	0xD6E7, 0x7D45, 0xD6E8, 0x7D2C, 0xD6E9, 0x7D29, 0xD6EA, 0x7D41,
+	0xD6EB, 0x7D47, 0xD6EC, 0x7D3E, 0xD6ED, 0x7D3F, 0xD6EE, 0x7D4A,
+	0xD6EF, 0x7D3B, 0xD6F0, 0x7D28, 0xD6F1, 0x7F63, 0xD6F2, 0x7F95,
+	0xD6F3, 0x7F9C, 0xD6F4, 0x7F9D, 0xD6F5, 0x7F9B, 0xD6F6, 0x7FCA,
+	0xD6F7, 0x7FCB, 0xD6F8, 0x7FCD, 0xD6F9, 0x7FD0, 0xD6FA, 0x7FD1,
+	0xD6FB, 0x7FC7, 0xD6FC, 0x7FCF, 0xD6FD, 0x7FC9, 0xD6FE, 0x801F,
+	0xD740, 0x801E, 0xD741, 0x801B, 0xD742, 0x8047, 0xD743, 0x8043,
+	0xD744, 0x8048, 0xD745, 0x8118, 0xD746, 0x8125, 0xD747, 0x8119,
+	0xD748, 0x811B, 0xD749, 0x812D, 0xD74A, 0x811F, 0xD74B, 0x812C,
+	0xD74C, 0x811E, 0xD74D, 0x8121, 0xD74E, 0x8115, 0xD74F, 0x8127,
+	0xD750, 0x811D, 0xD751, 0x8122, 0xD752, 0x8211, 0xD753, 0x8238,
+	0xD754, 0x8233, 0xD755, 0x823A, 0xD756, 0x8234, 0xD757, 0x8232,
+	0xD758, 0x8274, 0xD759, 0x8390, 0xD75A, 0x83A3, 0xD75B, 0x83A8,
+	0xD75C, 0x838D, 0xD75D, 0x837A, 0xD75E, 0x8373, 0xD75F, 0x83A4,
+	0xD760, 0x8374, 0xD761, 0x838F, 0xD762, 0x8381, 0xD763, 0x8395,
+	0xD764, 0x8399, 0xD765, 0x8375, 0xD766, 0x8394, 0xD767, 0x83A9,
+	0xD768, 0x837D, 0xD769, 0x8383, 0xD76A, 0x838C, 0xD76B, 0x839D,
+	0xD76C, 0x839B, 0xD76D, 0x83AA, 0xD76E, 0x838B, 0xD76F, 0x837E,
+	0xD770, 0x83A5, 0xD771, 0x83AF, 0xD772, 0x8388, 0xD773, 0x8397,
+	0xD774, 0x83B0, 0xD775, 0x837F, 0xD776, 0x83A6, 0xD777, 0x8387,
+	0xD778, 0x83AE, 0xD779, 0x8376, 0xD77A, 0x839A, 0xD77B, 0x8659,
+	0xD77C, 0x8656, 0xD77D, 0x86BF, 0xD77E, 0x86B7, 0xD7A1, 0x86C2,
+	0xD7A2, 0x86C1, 0xD7A3, 0x86C5, 0xD7A4, 0x86BA, 0xD7A5, 0x86B0,
+	0xD7A6, 0x86C8, 0xD7A7, 0x86B9, 0xD7A8, 0x86B3, 0xD7A9, 0x86B8,
+	0xD7AA, 0x86CC, 0xD7AB, 0x86B4, 0xD7AC, 0x86BB, 0xD7AD, 0x86BC,
+	0xD7AE, 0x86C3, 0xD7AF, 0x86BD, 0xD7B0, 0x86BE, 0xD7B1, 0x8852,
+	0xD7B2, 0x8889, 0xD7B3, 0x8895, 0xD7B4, 0x88A8, 0xD7B5, 0x88A2,
+	0xD7B6, 0x88AA, 0xD7B7, 0x889A, 0xD7B8, 0x8891, 0xD7B9, 0x88A1,
+	0xD7BA, 0x889F, 0xD7BB, 0x8898, 0xD7BC, 0x88A7, 0xD7BD, 0x8899,
+	0xD7BE, 0x889B, 0xD7BF, 0x8897, 0xD7C0, 0x88A4, 0xD7C1, 0x88AC,
+	0xD7C2, 0x888C, 0xD7C3, 0x8893, 0xD7C4, 0x888E, 0xD7C5, 0x8982,
+	0xD7C6, 0x89D6, 0xD7C7, 0x89D9, 0xD7C8, 0x89D5, 0xD7C9, 0x8A30,
+	0xD7CA, 0x8A27, 0xD7CB, 0x8A2C, 0xD7CC, 0x8A1E, 0xD7CD, 0x8C39,
+	0xD7CE, 0x8C3B, 0xD7CF, 0x8C5C, 0xD7D0, 0x8C5D, 0xD7D1, 0x8C7D,
+	0xD7D2, 0x8CA5, 0xD7D3, 0x8D7D, 0xD7D4, 0x8D7B, 0xD7D5, 0x8D79,
+	0xD7D6, 0x8DBC, 0xD7D7, 0x8DC2, 0xD7D8, 0x8DB9, 0xD7D9, 0x8DBF,
+	0xD7DA, 0x8DC1, 0xD7DB, 0x8ED8, 0xD7DC, 0x8EDE, 0xD7DD, 0x8EDD,
+	0xD7DE, 0x8EDC, 0xD7DF, 0x8ED7, 0xD7E0, 0x8EE0, 0xD7E1, 0x8EE1,
+	0xD7E2, 0x9024, 0xD7E3, 0x900B, 0xD7E4, 0x9011, 0xD7E5, 0x901C,
+	0xD7E6, 0x900C, 0xD7E7, 0x9021, 0xD7E8, 0x90EF, 0xD7E9, 0x90EA,
+	0xD7EA, 0x90F0, 0xD7EB, 0x90F4, 0xD7EC, 0x90F2, 0xD7ED, 0x90F3,
+	0xD7EE, 0x90D4, 0xD7EF, 0x90EB, 0xD7F0, 0x90EC, 0xD7F1, 0x90E9,
+	0xD7F2, 0x9156, 0xD7F3, 0x9158, 0xD7F4, 0x915A, 0xD7F5, 0x9153,
+	0xD7F6, 0x9155, 0xD7F7, 0x91EC, 0xD7F8, 0x91F4, 0xD7F9, 0x91F1,
+	0xD7FA, 0x91F3, 0xD7FB, 0x91F8, 0xD7FC, 0x91E4, 0xD7FD, 0x91F9,
+	0xD7FE, 0x91EA, 0xD840, 0x91EB, 0xD841, 0x91F7, 0xD842, 0x91E8,
+	0xD843, 0x91EE, 0xD844, 0x957A, 0xD845, 0x9586, 0xD846, 0x9588,
+	0xD847, 0x967C, 0xD848, 0x966D, 0xD849, 0x966B, 0xD84A, 0x9671,
+	0xD84B, 0x966F, 0xD84C, 0x96BF, 0xD84D, 0x976A, 0xD84E, 0x9804,
+	0xD84F, 0x98E5, 0xD850, 0x9997, 0xD851, 0x509B, 0xD852, 0x5095,
+	0xD853, 0x5094, 0xD854, 0x509E, 0xD855, 0x508B, 0xD856, 0x50A3,
+	0xD857, 0x5083, 0xD858, 0x508C, 0xD859, 0x508E, 0xD85A, 0x509D,
+	0xD85B, 0x5068, 0xD85C, 0x509C, 0xD85D, 0x5092, 0xD85E, 0x5082,
+	0xD85F, 0x5087, 0xD860, 0x515F, 0xD861, 0x51D4, 0xD862, 0x5312,
+	0xD863, 0x5311, 0xD864, 0x53A4, 0xD865, 0x53A7, 0xD866, 0x5591,
+	0xD867, 0x55A8, 0xD868, 0x55A5, 0xD869, 0x55AD, 0xD86A, 0x5577,
+	0xD86B, 0x5645, 0xD86C, 0x55A2, 0xD86D, 0x5593, 0xD86E, 0x5588,
+	0xD86F, 0x558F, 0xD870, 0x55B5, 0xD871, 0x5581, 0xD872, 0x55A3,
+	0xD873, 0x5592, 0xD874, 0x55A4, 0xD875, 0x557D, 0xD876, 0x558C,
+	0xD877, 0x55A6, 0xD878, 0x557F, 0xD879, 0x5595, 0xD87A, 0x55A1,
+	0xD87B, 0x558E, 0xD87C, 0x570C, 0xD87D, 0x5829, 0xD87E, 0x5837,
+	0xD8A1, 0x5819, 0xD8A2, 0x581E, 0xD8A3, 0x5827, 0xD8A4, 0x5823,
+	0xD8A5, 0x5828, 0xD8A6, 0x57F5, 0xD8A7, 0x5848, 0xD8A8, 0x5825,
+	0xD8A9, 0x581C, 0xD8AA, 0x581B, 0xD8AB, 0x5833, 0xD8AC, 0x583F,
+	0xD8AD, 0x5836, 0xD8AE, 0x582E, 0xD8AF, 0x5839, 0xD8B0, 0x5838,
+	0xD8B1, 0x582D, 0xD8B2, 0x582C, 0xD8B3, 0x583B, 0xD8B4, 0x5961,
+	0xD8B5, 0x5AAF, 0xD8B6, 0x5A94, 0xD8B7, 0x5A9F, 0xD8B8, 0x5A7A,
+	0xD8B9, 0x5AA2, 0xD8BA, 0x5A9E, 0xD8BB, 0x5A78, 0xD8BC, 0x5AA6,
+	0xD8BD, 0x5A7C, 0xD8BE, 0x5AA5, 0xD8BF, 0x5AAC, 0xD8C0, 0x5A95,
+	0xD8C1, 0x5AAE, 0xD8C2, 0x5A37, 0xD8C3, 0x5A84, 0xD8C4, 0x5A8A,
+	0xD8C5, 0x5A97, 0xD8C6, 0x5A83, 0xD8C7, 0x5A8B, 0xD8C8, 0x5AA9,
+	0xD8C9, 0x5A7B, 0xD8CA, 0x5A7D, 0xD8CB, 0x5A8C, 0xD8CC, 0x5A9C,
+	0xD8CD, 0x5A8F, 0xD8CE, 0x5A93, 0xD8CF, 0x5A9D, 0xD8D0, 0x5BEA,
+	0xD8D1, 0x5BCD, 0xD8D2, 0x5BCB, 0xD8D3, 0x5BD4, 0xD8D4, 0x5BD1,
+	0xD8D5, 0x5BCA, 0xD8D6, 0x5BCE, 0xD8D7, 0x5C0C, 0xD8D8, 0x5C30,
+	0xD8D9, 0x5D37, 0xD8DA, 0x5D43, 0xD8DB, 0x5D6B, 0xD8DC, 0x5D41,
+	0xD8DD, 0x5D4B, 0xD8DE, 0x5D3F, 0xD8DF, 0x5D35, 0xD8E0, 0x5D51,
+	0xD8E1, 0x5D4E, 0xD8E2, 0x5D55, 0xD8E3, 0x5D33, 0xD8E4, 0x5D3A,
+	0xD8E5, 0x5D52, 0xD8E6, 0x5D3D, 0xD8E7, 0x5D31, 0xD8E8, 0x5D59,
+	0xD8E9, 0x5D42, 0xD8EA, 0x5D39, 0xD8EB, 0x5D49, 0xD8EC, 0x5D38,
+	0xD8ED, 0x5D3C, 0xD8EE, 0x5D32, 0xD8EF, 0x5D36, 0xD8F0, 0x5D40,
+	0xD8F1, 0x5D45, 0xD8F2, 0x5E44, 0xD8F3, 0x5E41, 0xD8F4, 0x5F58,
+	0xD8F5, 0x5FA6, 0xD8F6, 0x5FA5, 0xD8F7, 0x5FAB, 0xD8F8, 0x60C9,
+	0xD8F9, 0x60B9, 0xD8FA, 0x60CC, 0xD8FB, 0x60E2, 0xD8FC, 0x60CE,
+	0xD8FD, 0x60C4, 0xD8FE, 0x6114, 0xD940, 0x60F2, 0xD941, 0x610A,
+	0xD942, 0x6116, 0xD943, 0x6105, 0xD944, 0x60F5, 0xD945, 0x6113,
+	0xD946, 0x60F8, 0xD947, 0x60FC, 0xD948, 0x60FE, 0xD949, 0x60C1,
+	0xD94A, 0x6103, 0xD94B, 0x6118, 0xD94C, 0x611D, 0xD94D, 0x6110,
+	0xD94E, 0x60FF, 0xD94F, 0x6104, 0xD950, 0x610B, 0xD951, 0x624A,
+	0xD952, 0x6394, 0xD953, 0x63B1, 0xD954, 0x63B0, 0xD955, 0x63CE,
+	0xD956, 0x63E5, 0xD957, 0x63E8, 0xD958, 0x63EF, 0xD959, 0x63C3,
+	0xD95A, 0x649D, 0xD95B, 0x63F3, 0xD95C, 0x63CA, 0xD95D, 0x63E0,
+	0xD95E, 0x63F6, 0xD95F, 0x63D5, 0xD960, 0x63F2, 0xD961, 0x63F5,
+	0xD962, 0x6461, 0xD963, 0x63DF, 0xD964, 0x63BE, 0xD965, 0x63DD,
+	0xD966, 0x63DC, 0xD967, 0x63C4, 0xD968, 0x63D8, 0xD969, 0x63D3,
+	0xD96A, 0x63C2, 0xD96B, 0x63C7, 0xD96C, 0x63CC, 0xD96D, 0x63CB,
+	0xD96E, 0x63C8, 0xD96F, 0x63F0, 0xD970, 0x63D7, 0xD971, 0x63D9,
+	0xD972, 0x6532, 0xD973, 0x6567, 0xD974, 0x656A, 0xD975, 0x6564,
+	0xD976, 0x655C, 0xD977, 0x6568, 0xD978, 0x6565, 0xD979, 0x658C,
+	0xD97A, 0x659D, 0xD97B, 0x659E, 0xD97C, 0x65AE, 0xD97D, 0x65D0,
+	0xD97E, 0x65D2, 0xD9A1, 0x667C, 0xD9A2, 0x666C, 0xD9A3, 0x667B,
+	0xD9A4, 0x6680, 0xD9A5, 0x6671, 0xD9A6, 0x6679, 0xD9A7, 0x666A,
+	0xD9A8, 0x6672, 0xD9A9, 0x6701, 0xD9AA, 0x690C, 0xD9AB, 0x68D3,
+	0xD9AC, 0x6904, 0xD9AD, 0x68DC, 0xD9AE, 0x692A, 0xD9AF, 0x68EC,
+	0xD9B0, 0x68EA, 0xD9B1, 0x68F1, 0xD9B2, 0x690F, 0xD9B3, 0x68D6,
+	0xD9B4, 0x68F7, 0xD9B5, 0x68EB, 0xD9B6, 0x68E4, 0xD9B7, 0x68F6,
+	0xD9B8, 0x6913, 0xD9B9, 0x6910, 0xD9BA, 0x68F3, 0xD9BB, 0x68E1,
+	0xD9BC, 0x6907, 0xD9BD, 0x68CC, 0xD9BE, 0x6908, 0xD9BF, 0x6970,
+	0xD9C0, 0x68B4, 0xD9C1, 0x6911, 0xD9C2, 0x68EF, 0xD9C3, 0x68C6,
+	0xD9C4, 0x6914, 0xD9C5, 0x68F8, 0xD9C6, 0x68D0, 0xD9C7, 0x68FD,
+	0xD9C8, 0x68FC, 0xD9C9, 0x68E8, 0xD9CA, 0x690B, 0xD9CB, 0x690A,
+	0xD9CC, 0x6917, 0xD9CD, 0x68CE, 0xD9CE, 0x68C8, 0xD9CF, 0x68DD,
+	0xD9D0, 0x68DE, 0xD9D1, 0x68E6, 0xD9D2, 0x68F4, 0xD9D3, 0x68D1,
+	0xD9D4, 0x6906, 0xD9D5, 0x68D4, 0xD9D6, 0x68E9, 0xD9D7, 0x6915,
+	0xD9D8, 0x6925, 0xD9D9, 0x68C7, 0xD9DA, 0x6B39, 0xD9DB, 0x6B3B,
+	0xD9DC, 0x6B3F, 0xD9DD, 0x6B3C, 0xD9DE, 0x6B94, 0xD9DF, 0x6B97,
+	0xD9E0, 0x6B99, 0xD9E1, 0x6B95, 0xD9E2, 0x6BBD, 0xD9E3, 0x6BF0,
+	0xD9E4, 0x6BF2, 0xD9E5, 0x6BF3, 0xD9E6, 0x6C30, 0xD9E7, 0x6DFC,
+	0xD9E8, 0x6E46, 0xD9E9, 0x6E47, 0xD9EA, 0x6E1F, 0xD9EB, 0x6E49,
+	0xD9EC, 0x6E88, 0xD9ED, 0x6E3C, 0xD9EE, 0x6E3D, 0xD9EF, 0x6E45,
+	0xD9F0, 0x6E62, 0xD9F1, 0x6E2B, 0xD9F2, 0x6E3F, 0xD9F3, 0x6E41,
+	0xD9F4, 0x6E5D, 0xD9F5, 0x6E73, 0xD9F6, 0x6E1C, 0xD9F7, 0x6E33,
+	0xD9F8, 0x6E4B, 0xD9F9, 0x6E40, 0xD9FA, 0x6E51, 0xD9FB, 0x6E3B,
+	0xD9FC, 0x6E03, 0xD9FD, 0x6E2E, 0xD9FE, 0x6E5E, 0xDA40, 0x6E68,
+	0xDA41, 0x6E5C, 0xDA42, 0x6E61, 0xDA43, 0x6E31, 0xDA44, 0x6E28,
+	0xDA45, 0x6E60, 0xDA46, 0x6E71, 0xDA47, 0x6E6B, 0xDA48, 0x6E39,
+	0xDA49, 0x6E22, 0xDA4A, 0x6E30, 0xDA4B, 0x6E53, 0xDA4C, 0x6E65,
+	0xDA4D, 0x6E27, 0xDA4E, 0x6E78, 0xDA4F, 0x6E64, 0xDA50, 0x6E77,
+	0xDA51, 0x6E55, 0xDA52, 0x6E79, 0xDA53, 0x6E52, 0xDA54, 0x6E66,
+	0xDA55, 0x6E35, 0xDA56, 0x6E36, 0xDA57, 0x6E5A, 0xDA58, 0x7120,
+	0xDA59, 0x711E, 0xDA5A, 0x712F, 0xDA5B, 0x70FB, 0xDA5C, 0x712E,
+	0xDA5D, 0x7131, 0xDA5E, 0x7123, 0xDA5F, 0x7125, 0xDA60, 0x7122,
+	0xDA61, 0x7132, 0xDA62, 0x711F, 0xDA63, 0x7128, 0xDA64, 0x713A,
+	0xDA65, 0x711B, 0xDA66, 0x724B, 0xDA67, 0x725A, 0xDA68, 0x7288,
+	0xDA69, 0x7289, 0xDA6A, 0x7286, 0xDA6B, 0x7285, 0xDA6C, 0x728B,
+	0xDA6D, 0x7312, 0xDA6E, 0x730B, 0xDA6F, 0x7330, 0xDA70, 0x7322,
+	0xDA71, 0x7331, 0xDA72, 0x7333, 0xDA73, 0x7327, 0xDA74, 0x7332,
+	0xDA75, 0x732D, 0xDA76, 0x7326, 0xDA77, 0x7323, 0xDA78, 0x7335,
+	0xDA79, 0x730C, 0xDA7A, 0x742E, 0xDA7B, 0x742C, 0xDA7C, 0x7430,
+	0xDA7D, 0x742B, 0xDA7E, 0x7416, 0xDAA1, 0x741A, 0xDAA2, 0x7421,
+	0xDAA3, 0x742D, 0xDAA4, 0x7431, 0xDAA5, 0x7424, 0xDAA6, 0x7423,
+	0xDAA7, 0x741D, 0xDAA8, 0x7429, 0xDAA9, 0x7420, 0xDAAA, 0x7432,
+	0xDAAB, 0x74FB, 0xDAAC, 0x752F, 0xDAAD, 0x756F, 0xDAAE, 0x756C,
+	0xDAAF, 0x75E7, 0xDAB0, 0x75DA, 0xDAB1, 0x75E1, 0xDAB2, 0x75E6,
+	0xDAB3, 0x75DD, 0xDAB4, 0x75DF, 0xDAB5, 0x75E4, 0xDAB6, 0x75D7,
+	0xDAB7, 0x7695, 0xDAB8, 0x7692, 0xDAB9, 0x76DA, 0xDABA, 0x7746,
+	0xDABB, 0x7747, 0xDABC, 0x7744, 0xDABD, 0x774D, 0xDABE, 0x7745,
+	0xDABF, 0x774A, 0xDAC0, 0x774E, 0xDAC1, 0x774B, 0xDAC2, 0x774C,
+	0xDAC3, 0x77DE, 0xDAC4, 0x77EC, 0xDAC5, 0x7860, 0xDAC6, 0x7864,
+	0xDAC7, 0x7865, 0xDAC8, 0x785C, 0xDAC9, 0x786D, 0xDACA, 0x7871,
+	0xDACB, 0x786A, 0xDACC, 0x786E, 0xDACD, 0x7870, 0xDACE, 0x7869,
+	0xDACF, 0x7868, 0xDAD0, 0x785E, 0xDAD1, 0x7862, 0xDAD2, 0x7974,
+	0xDAD3, 0x7973, 0xDAD4, 0x7972, 0xDAD5, 0x7970, 0xDAD6, 0x7A02,
+	0xDAD7, 0x7A0A, 0xDAD8, 0x7A03, 0xDAD9, 0x7A0C, 0xDADA, 0x7A04,
+	0xDADB, 0x7A99, 0xDADC, 0x7AE6, 0xDADD, 0x7AE4, 0xDADE, 0x7B4A,
+	0xDADF, 0x7B3B, 0xDAE0, 0x7B44, 0xDAE1, 0x7B48, 0xDAE2, 0x7B4C,
+	0xDAE3, 0x7B4E, 0xDAE4, 0x7B40, 0xDAE5, 0x7B58, 0xDAE6, 0x7B45,
+	0xDAE7, 0x7CA2, 0xDAE8, 0x7C9E, 0xDAE9, 0x7CA8, 0xDAEA, 0x7CA1,
+	0xDAEB, 0x7D58, 0xDAEC, 0x7D6F, 0xDAED, 0x7D63, 0xDAEE, 0x7D53,
+	0xDAEF, 0x7D56, 0xDAF0, 0x7D67, 0xDAF1, 0x7D6A, 0xDAF2, 0x7D4F,
+	0xDAF3, 0x7D6D, 0xDAF4, 0x7D5C, 0xDAF5, 0x7D6B, 0xDAF6, 0x7D52,
+	0xDAF7, 0x7D54, 0xDAF8, 0x7D69, 0xDAF9, 0x7D51, 0xDAFA, 0x7D5F,
+	0xDAFB, 0x7D4E, 0xDAFC, 0x7F3E, 0xDAFD, 0x7F3F, 0xDAFE, 0x7F65,
+	0xDB40, 0x7F66, 0xDB41, 0x7FA2, 0xDB42, 0x7FA0, 0xDB43, 0x7FA1,
+	0xDB44, 0x7FD7, 0xDB45, 0x8051, 0xDB46, 0x804F, 0xDB47, 0x8050,
+	0xDB48, 0x80FE, 0xDB49, 0x80D4, 0xDB4A, 0x8143, 0xDB4B, 0x814A,
+	0xDB4C, 0x8152, 0xDB4D, 0x814F, 0xDB4E, 0x8147, 0xDB4F, 0x813D,
+	0xDB50, 0x814D, 0xDB51, 0x813A, 0xDB52, 0x81E6, 0xDB53, 0x81EE,
+	0xDB54, 0x81F7, 0xDB55, 0x81F8, 0xDB56, 0x81F9, 0xDB57, 0x8204,
+	0xDB58, 0x823C, 0xDB59, 0x823D, 0xDB5A, 0x823F, 0xDB5B, 0x8275,
+	0xDB5C, 0x833B, 0xDB5D, 0x83CF, 0xDB5E, 0x83F9, 0xDB5F, 0x8423,
+	0xDB60, 0x83C0, 0xDB61, 0x83E8, 0xDB62, 0x8412, 0xDB63, 0x83E7,
+	0xDB64, 0x83E4, 0xDB65, 0x83FC, 0xDB66, 0x83F6, 0xDB67, 0x8410,
+	0xDB68, 0x83C6, 0xDB69, 0x83C8, 0xDB6A, 0x83EB, 0xDB6B, 0x83E3,
+	0xDB6C, 0x83BF, 0xDB6D, 0x8401, 0xDB6E, 0x83DD, 0xDB6F, 0x83E5,
+	0xDB70, 0x83D8, 0xDB71, 0x83FF, 0xDB72, 0x83E1, 0xDB73, 0x83CB,
+	0xDB74, 0x83CE, 0xDB75, 0x83D6, 0xDB76, 0x83F5, 0xDB77, 0x83C9,
+	0xDB78, 0x8409, 0xDB79, 0x840F, 0xDB7A, 0x83DE, 0xDB7B, 0x8411,
+	0xDB7C, 0x8406, 0xDB7D, 0x83C2, 0xDB7E, 0x83F3, 0xDBA1, 0x83D5,
+	0xDBA2, 0x83FA, 0xDBA3, 0x83C7, 0xDBA4, 0x83D1, 0xDBA5, 0x83EA,
+	0xDBA6, 0x8413, 0xDBA7, 0x83C3, 0xDBA8, 0x83EC, 0xDBA9, 0x83EE,
+	0xDBAA, 0x83C4, 0xDBAB, 0x83FB, 0xDBAC, 0x83D7, 0xDBAD, 0x83E2,
+	0xDBAE, 0x841B, 0xDBAF, 0x83DB, 0xDBB0, 0x83FE, 0xDBB1, 0x86D8,
+	0xDBB2, 0x86E2, 0xDBB3, 0x86E6, 0xDBB4, 0x86D3, 0xDBB5, 0x86E3,
+	0xDBB6, 0x86DA, 0xDBB7, 0x86EA, 0xDBB8, 0x86DD, 0xDBB9, 0x86EB,
+	0xDBBA, 0x86DC, 0xDBBB, 0x86EC, 0xDBBC, 0x86E9, 0xDBBD, 0x86D7,
+	0xDBBE, 0x86E8, 0xDBBF, 0x86D1, 0xDBC0, 0x8848, 0xDBC1, 0x8856,
+	0xDBC2, 0x8855, 0xDBC3, 0x88BA, 0xDBC4, 0x88D7, 0xDBC5, 0x88B9,
+	0xDBC6, 0x88B8, 0xDBC7, 0x88C0, 0xDBC8, 0x88BE, 0xDBC9, 0x88B6,
+	0xDBCA, 0x88BC, 0xDBCB, 0x88B7, 0xDBCC, 0x88BD, 0xDBCD, 0x88B2,
+	0xDBCE, 0x8901, 0xDBCF, 0x88C9, 0xDBD0, 0x8995, 0xDBD1, 0x8998,
+	0xDBD2, 0x8997, 0xDBD3, 0x89DD, 0xDBD4, 0x89DA, 0xDBD5, 0x89DB,
+	0xDBD6, 0x8A4E, 0xDBD7, 0x8A4D, 0xDBD8, 0x8A39, 0xDBD9, 0x8A59,
+	0xDBDA, 0x8A40, 0xDBDB, 0x8A57, 0xDBDC, 0x8A58, 0xDBDD, 0x8A44,
+	0xDBDE, 0x8A45, 0xDBDF, 0x8A52, 0xDBE0, 0x8A48, 0xDBE1, 0x8A51,
+	0xDBE2, 0x8A4A, 0xDBE3, 0x8A4C, 0xDBE4, 0x8A4F, 0xDBE5, 0x8C5F,
+	0xDBE6, 0x8C81, 0xDBE7, 0x8C80, 0xDBE8, 0x8CBA, 0xDBE9, 0x8CBE,
+	0xDBEA, 0x8CB0, 0xDBEB, 0x8CB9, 0xDBEC, 0x8CB5, 0xDBED, 0x8D84,
+	0xDBEE, 0x8D80, 0xDBEF, 0x8D89, 0xDBF0, 0x8DD8, 0xDBF1, 0x8DD3,
+	0xDBF2, 0x8DCD, 0xDBF3, 0x8DC7, 0xDBF4, 0x8DD6, 0xDBF5, 0x8DDC,
+	0xDBF6, 0x8DCF, 0xDBF7, 0x8DD5, 0xDBF8, 0x8DD9, 0xDBF9, 0x8DC8,
+	0xDBFA, 0x8DD7, 0xDBFB, 0x8DC5, 0xDBFC, 0x8EEF, 0xDBFD, 0x8EF7,
+	0xDBFE, 0x8EFA, 0xDC40, 0x8EF9, 0xDC41, 0x8EE6, 0xDC42, 0x8EEE,
+	0xDC43, 0x8EE5, 0xDC44, 0x8EF5, 0xDC45, 0x8EE7, 0xDC46, 0x8EE8,
+	0xDC47, 0x8EF6, 0xDC48, 0x8EEB, 0xDC49, 0x8EF1, 0xDC4A, 0x8EEC,
+	0xDC4B, 0x8EF4, 0xDC4C, 0x8EE9, 0xDC4D, 0x902D, 0xDC4E, 0x9034,
+	0xDC4F, 0x902F, 0xDC50, 0x9106, 0xDC51, 0x912C, 0xDC52, 0x9104,
+	0xDC53, 0x90FF, 0xDC54, 0x90FC, 0xDC55, 0x9108, 0xDC56, 0x90F9,
+	0xDC57, 0x90FB, 0xDC58, 0x9101, 0xDC59, 0x9100, 0xDC5A, 0x9107,
+	0xDC5B, 0x9105, 0xDC5C, 0x9103, 0xDC5D, 0x9161, 0xDC5E, 0x9164,
+	0xDC5F, 0x915F, 0xDC60, 0x9162, 0xDC61, 0x9160, 0xDC62, 0x9201,
+	0xDC63, 0x920A, 0xDC64, 0x9225, 0xDC65, 0x9203, 0xDC66, 0x921A,
+	0xDC67, 0x9226, 0xDC68, 0x920F, 0xDC69, 0x920C, 0xDC6A, 0x9200,
+	0xDC6B, 0x9212, 0xDC6C, 0x91FF, 0xDC6D, 0x91FD, 0xDC6E, 0x9206,
+	0xDC6F, 0x9204, 0xDC70, 0x9227, 0xDC71, 0x9202, 0xDC72, 0x921C,
+	0xDC73, 0x9224, 0xDC74, 0x9219, 0xDC75, 0x9217, 0xDC76, 0x9205,
+	0xDC77, 0x9216, 0xDC78, 0x957B, 0xDC79, 0x958D, 0xDC7A, 0x958C,
+	0xDC7B, 0x9590, 0xDC7C, 0x9687, 0xDC7D, 0x967E, 0xDC7E, 0x9688,
+	0xDCA1, 0x9689, 0xDCA2, 0x9683, 0xDCA3, 0x9680, 0xDCA4, 0x96C2,
+	0xDCA5, 0x96C8, 0xDCA6, 0x96C3, 0xDCA7, 0x96F1, 0xDCA8, 0x96F0,
+	0xDCA9, 0x976C, 0xDCAA, 0x9770, 0xDCAB, 0x976E, 0xDCAC, 0x9807,
+	0xDCAD, 0x98A9, 0xDCAE, 0x98EB, 0xDCAF, 0x9CE6, 0xDCB0, 0x9EF9,
+	0xDCB1, 0x4E83, 0xDCB2, 0x4E84, 0xDCB3, 0x4EB6, 0xDCB4, 0x50BD,
+	0xDCB5, 0x50BF, 0xDCB6, 0x50C6, 0xDCB7, 0x50AE, 0xDCB8, 0x50C4,
+	0xDCB9, 0x50CA, 0xDCBA, 0x50B4, 0xDCBB, 0x50C8, 0xDCBC, 0x50C2,
+	0xDCBD, 0x50B0, 0xDCBE, 0x50C1, 0xDCBF, 0x50BA, 0xDCC0, 0x50B1,
+	0xDCC1, 0x50CB, 0xDCC2, 0x50C9, 0xDCC3, 0x50B6, 0xDCC4, 0x50B8,
+	0xDCC5, 0x51D7, 0xDCC6, 0x527A, 0xDCC7, 0x5278, 0xDCC8, 0x527B,
+	0xDCC9, 0x527C, 0xDCCA, 0x55C3, 0xDCCB, 0x55DB, 0xDCCC, 0x55CC,
+	0xDCCD, 0x55D0, 0xDCCE, 0x55CB, 0xDCCF, 0x55CA, 0xDCD0, 0x55DD,
+	0xDCD1, 0x55C0, 0xDCD2, 0x55D4, 0xDCD3, 0x55C4, 0xDCD4, 0x55E9,
+	0xDCD5, 0x55BF, 0xDCD6, 0x55D2, 0xDCD7, 0x558D, 0xDCD8, 0x55CF,
+	0xDCD9, 0x55D5, 0xDCDA, 0x55E2, 0xDCDB, 0x55D6, 0xDCDC, 0x55C8,
+	0xDCDD, 0x55F2, 0xDCDE, 0x55CD, 0xDCDF, 0x55D9, 0xDCE0, 0x55C2,
+	0xDCE1, 0x5714, 0xDCE2, 0x5853, 0xDCE3, 0x5868, 0xDCE4, 0x5864,
+	0xDCE5, 0x584F, 0xDCE6, 0x584D, 0xDCE7, 0x5849, 0xDCE8, 0x586F,
+	0xDCE9, 0x5855, 0xDCEA, 0x584E, 0xDCEB, 0x585D, 0xDCEC, 0x5859,
+	0xDCED, 0x5865, 0xDCEE, 0x585B, 0xDCEF, 0x583D, 0xDCF0, 0x5863,
+	0xDCF1, 0x5871, 0xDCF2, 0x58FC, 0xDCF3, 0x5AC7, 0xDCF4, 0x5AC4,
+	0xDCF5, 0x5ACB, 0xDCF6, 0x5ABA, 0xDCF7, 0x5AB8, 0xDCF8, 0x5AB1,
+	0xDCF9, 0x5AB5, 0xDCFA, 0x5AB0, 0xDCFB, 0x5ABF, 0xDCFC, 0x5AC8,
+	0xDCFD, 0x5ABB, 0xDCFE, 0x5AC6, 0xDD40, 0x5AB7, 0xDD41, 0x5AC0,
+	0xDD42, 0x5ACA, 0xDD43, 0x5AB4, 0xDD44, 0x5AB6, 0xDD45, 0x5ACD,
+	0xDD46, 0x5AB9, 0xDD47, 0x5A90, 0xDD48, 0x5BD6, 0xDD49, 0x5BD8,
+	0xDD4A, 0x5BD9, 0xDD4B, 0x5C1F, 0xDD4C, 0x5C33, 0xDD4D, 0x5D71,
+	0xDD4E, 0x5D63, 0xDD4F, 0x5D4A, 0xDD50, 0x5D65, 0xDD51, 0x5D72,
+	0xDD52, 0x5D6C, 0xDD53, 0x5D5E, 0xDD54, 0x5D68, 0xDD55, 0x5D67,
+	0xDD56, 0x5D62, 0xDD57, 0x5DF0, 0xDD58, 0x5E4F, 0xDD59, 0x5E4E,
+	0xDD5A, 0x5E4A, 0xDD5B, 0x5E4D, 0xDD5C, 0x5E4B, 0xDD5D, 0x5EC5,
+	0xDD5E, 0x5ECC, 0xDD5F, 0x5EC6, 0xDD60, 0x5ECB, 0xDD61, 0x5EC7,
+	0xDD62, 0x5F40, 0xDD63, 0x5FAF, 0xDD64, 0x5FAD, 0xDD65, 0x60F7,
+	0xDD66, 0x6149, 0xDD67, 0x614A, 0xDD68, 0x612B, 0xDD69, 0x6145,
+	0xDD6A, 0x6136, 0xDD6B, 0x6132, 0xDD6C, 0x612E, 0xDD6D, 0x6146,
+	0xDD6E, 0x612F, 0xDD6F, 0x614F, 0xDD70, 0x6129, 0xDD71, 0x6140,
+	0xDD72, 0x6220, 0xDD73, 0x9168, 0xDD74, 0x6223, 0xDD75, 0x6225,
+	0xDD76, 0x6224, 0xDD77, 0x63C5, 0xDD78, 0x63F1, 0xDD79, 0x63EB,
+	0xDD7A, 0x6410, 0xDD7B, 0x6412, 0xDD7C, 0x6409, 0xDD7D, 0x6420,
+	0xDD7E, 0x6424, 0xDDA1, 0x6433, 0xDDA2, 0x6443, 0xDDA3, 0x641F,
+	0xDDA4, 0x6415, 0xDDA5, 0x6418, 0xDDA6, 0x6439, 0xDDA7, 0x6437,
+	0xDDA8, 0x6422, 0xDDA9, 0x6423, 0xDDAA, 0x640C, 0xDDAB, 0x6426,
+	0xDDAC, 0x6430, 0xDDAD, 0x6428, 0xDDAE, 0x6441, 0xDDAF, 0x6435,
+	0xDDB0, 0x642F, 0xDDB1, 0x640A, 0xDDB2, 0x641A, 0xDDB3, 0x6440,
+	0xDDB4, 0x6425, 0xDDB5, 0x6427, 0xDDB6, 0x640B, 0xDDB7, 0x63E7,
+	0xDDB8, 0x641B, 0xDDB9, 0x642E, 0xDDBA, 0x6421, 0xDDBB, 0x640E,
+	0xDDBC, 0x656F, 0xDDBD, 0x6592, 0xDDBE, 0x65D3, 0xDDBF, 0x6686,
+	0xDDC0, 0x668C, 0xDDC1, 0x6695, 0xDDC2, 0x6690, 0xDDC3, 0x668B,
+	0xDDC4, 0x668A, 0xDDC5, 0x6699, 0xDDC6, 0x6694, 0xDDC7, 0x6678,
+	0xDDC8, 0x6720, 0xDDC9, 0x6966, 0xDDCA, 0x695F, 0xDDCB, 0x6938,
+	0xDDCC, 0x694E, 0xDDCD, 0x6962, 0xDDCE, 0x6971, 0xDDCF, 0x693F,
+	0xDDD0, 0x6945, 0xDDD1, 0x696A, 0xDDD2, 0x6939, 0xDDD3, 0x6942,
+	0xDDD4, 0x6957, 0xDDD5, 0x6959, 0xDDD6, 0x697A, 0xDDD7, 0x6948,
+	0xDDD8, 0x6949, 0xDDD9, 0x6935, 0xDDDA, 0x696C, 0xDDDB, 0x6933,
+	0xDDDC, 0x693D, 0xDDDD, 0x6965, 0xDDDE, 0x68F0, 0xDDDF, 0x6978,
+	0xDDE0, 0x6934, 0xDDE1, 0x6969, 0xDDE2, 0x6940, 0xDDE3, 0x696F,
+	0xDDE4, 0x6944, 0xDDE5, 0x6976, 0xDDE6, 0x6958, 0xDDE7, 0x6941,
+	0xDDE8, 0x6974, 0xDDE9, 0x694C, 0xDDEA, 0x693B, 0xDDEB, 0x694B,
+	0xDDEC, 0x6937, 0xDDED, 0x695C, 0xDDEE, 0x694F, 0xDDEF, 0x6951,
+	0xDDF0, 0x6932, 0xDDF1, 0x6952, 0xDDF2, 0x692F, 0xDDF3, 0x697B,
+	0xDDF4, 0x693C, 0xDDF5, 0x6B46, 0xDDF6, 0x6B45, 0xDDF7, 0x6B43,
+	0xDDF8, 0x6B42, 0xDDF9, 0x6B48, 0xDDFA, 0x6B41, 0xDDFB, 0x6B9B,
+	0xDDFC, 0xFA0D, 0xDDFD, 0x6BFB, 0xDDFE, 0x6BFC, 0xDE40, 0x6BF9,
+	0xDE41, 0x6BF7, 0xDE42, 0x6BF8, 0xDE43, 0x6E9B, 0xDE44, 0x6ED6,
+	0xDE45, 0x6EC8, 0xDE46, 0x6E8F, 0xDE47, 0x6EC0, 0xDE48, 0x6E9F,
+	0xDE49, 0x6E93, 0xDE4A, 0x6E94, 0xDE4B, 0x6EA0, 0xDE4C, 0x6EB1,
+	0xDE4D, 0x6EB9, 0xDE4E, 0x6EC6, 0xDE4F, 0x6ED2, 0xDE50, 0x6EBD,
+	0xDE51, 0x6EC1, 0xDE52, 0x6E9E, 0xDE53, 0x6EC9, 0xDE54, 0x6EB7,
+	0xDE55, 0x6EB0, 0xDE56, 0x6ECD, 0xDE57, 0x6EA6, 0xDE58, 0x6ECF,
+	0xDE59, 0x6EB2, 0xDE5A, 0x6EBE, 0xDE5B, 0x6EC3, 0xDE5C, 0x6EDC,
+	0xDE5D, 0x6ED8, 0xDE5E, 0x6E99, 0xDE5F, 0x6E92, 0xDE60, 0x6E8E,
+	0xDE61, 0x6E8D, 0xDE62, 0x6EA4, 0xDE63, 0x6EA1, 0xDE64, 0x6EBF,
+	0xDE65, 0x6EB3, 0xDE66, 0x6ED0, 0xDE67, 0x6ECA, 0xDE68, 0x6E97,
+	0xDE69, 0x6EAE, 0xDE6A, 0x6EA3, 0xDE6B, 0x7147, 0xDE6C, 0x7154,
+	0xDE6D, 0x7152, 0xDE6E, 0x7163, 0xDE6F, 0x7160, 0xDE70, 0x7141,
+	0xDE71, 0x715D, 0xDE72, 0x7162, 0xDE73, 0x7172, 0xDE74, 0x7178,
+	0xDE75, 0x716A, 0xDE76, 0x7161, 0xDE77, 0x7142, 0xDE78, 0x7158,
+	0xDE79, 0x7143, 0xDE7A, 0x714B, 0xDE7B, 0x7170, 0xDE7C, 0x715F,
+	0xDE7D, 0x7150, 0xDE7E, 0x7153, 0xDEA1, 0x7144, 0xDEA2, 0x714D,
+	0xDEA3, 0x715A, 0xDEA4, 0x724F, 0xDEA5, 0x728D, 0xDEA6, 0x728C,
+	0xDEA7, 0x7291, 0xDEA8, 0x7290, 0xDEA9, 0x728E, 0xDEAA, 0x733C,
+	0xDEAB, 0x7342, 0xDEAC, 0x733B, 0xDEAD, 0x733A, 0xDEAE, 0x7340,
+	0xDEAF, 0x734A, 0xDEB0, 0x7349, 0xDEB1, 0x7444, 0xDEB2, 0x744A,
+	0xDEB3, 0x744B, 0xDEB4, 0x7452, 0xDEB5, 0x7451, 0xDEB6, 0x7457,
+	0xDEB7, 0x7440, 0xDEB8, 0x744F, 0xDEB9, 0x7450, 0xDEBA, 0x744E,
+	0xDEBB, 0x7442, 0xDEBC, 0x7446, 0xDEBD, 0x744D, 0xDEBE, 0x7454,
+	0xDEBF, 0x74E1, 0xDEC0, 0x74FF, 0xDEC1, 0x74FE, 0xDEC2, 0x74FD,
+	0xDEC3, 0x751D, 0xDEC4, 0x7579, 0xDEC5, 0x7577, 0xDEC6, 0x6983,
+	0xDEC7, 0x75EF, 0xDEC8, 0x760F, 0xDEC9, 0x7603, 0xDECA, 0x75F7,
+	0xDECB, 0x75FE, 0xDECC, 0x75FC, 0xDECD, 0x75F9, 0xDECE, 0x75F8,
+	0xDECF, 0x7610, 0xDED0, 0x75FB, 0xDED1, 0x75F6, 0xDED2, 0x75ED,
+	0xDED3, 0x75F5, 0xDED4, 0x75FD, 0xDED5, 0x7699, 0xDED6, 0x76B5,
+	0xDED7, 0x76DD, 0xDED8, 0x7755, 0xDED9, 0x775F, 0xDEDA, 0x7760,
+	0xDEDB, 0x7752, 0xDEDC, 0x7756, 0xDEDD, 0x775A, 0xDEDE, 0x7769,
+	0xDEDF, 0x7767, 0xDEE0, 0x7754, 0xDEE1, 0x7759, 0xDEE2, 0x776D,
+	0xDEE3, 0x77E0, 0xDEE4, 0x7887, 0xDEE5, 0x789A, 0xDEE6, 0x7894,
+	0xDEE7, 0x788F, 0xDEE8, 0x7884, 0xDEE9, 0x7895, 0xDEEA, 0x7885,
+	0xDEEB, 0x7886, 0xDEEC, 0x78A1, 0xDEED, 0x7883, 0xDEEE, 0x7879,
+	0xDEEF, 0x7899, 0xDEF0, 0x7880, 0xDEF1, 0x7896, 0xDEF2, 0x787B,
+	0xDEF3, 0x797C, 0xDEF4, 0x7982, 0xDEF5, 0x797D, 0xDEF6, 0x7979,
+	0xDEF7, 0x7A11, 0xDEF8, 0x7A18, 0xDEF9, 0x7A19, 0xDEFA, 0x7A12,
+	0xDEFB, 0x7A17, 0xDEFC, 0x7A15, 0xDEFD, 0x7A22, 0xDEFE, 0x7A13,
+	0xDF40, 0x7A1B, 0xDF41, 0x7A10, 0xDF42, 0x7AA3, 0xDF43, 0x7AA2,
+	0xDF44, 0x7A9E, 0xDF45, 0x7AEB, 0xDF46, 0x7B66, 0xDF47, 0x7B64,
+	0xDF48, 0x7B6D, 0xDF49, 0x7B74, 0xDF4A, 0x7B69, 0xDF4B, 0x7B72,
+	0xDF4C, 0x7B65, 0xDF4D, 0x7B73, 0xDF4E, 0x7B71, 0xDF4F, 0x7B70,
+	0xDF50, 0x7B61, 0xDF51, 0x7B78, 0xDF52, 0x7B76, 0xDF53, 0x7B63,
+	0xDF54, 0x7CB2, 0xDF55, 0x7CB4, 0xDF56, 0x7CAF, 0xDF57, 0x7D88,
+	0xDF58, 0x7D86, 0xDF59, 0x7D80, 0xDF5A, 0x7D8D, 0xDF5B, 0x7D7F,
+	0xDF5C, 0x7D85, 0xDF5D, 0x7D7A, 0xDF5E, 0x7D8E, 0xDF5F, 0x7D7B,
+	0xDF60, 0x7D83, 0xDF61, 0x7D7C, 0xDF62, 0x7D8C, 0xDF63, 0x7D94,
+	0xDF64, 0x7D84, 0xDF65, 0x7D7D, 0xDF66, 0x7D92, 0xDF67, 0x7F6D,
+	0xDF68, 0x7F6B, 0xDF69, 0x7F67, 0xDF6A, 0x7F68, 0xDF6B, 0x7F6C,
+	0xDF6C, 0x7FA6, 0xDF6D, 0x7FA5, 0xDF6E, 0x7FA7, 0xDF6F, 0x7FDB,
+	0xDF70, 0x7FDC, 0xDF71, 0x8021, 0xDF72, 0x8164, 0xDF73, 0x8160,
+	0xDF74, 0x8177, 0xDF75, 0x815C, 0xDF76, 0x8169, 0xDF77, 0x815B,
+	0xDF78, 0x8162, 0xDF79, 0x8172, 0xDF7A, 0x6721, 0xDF7B, 0x815E,
+	0xDF7C, 0x8176, 0xDF7D, 0x8167, 0xDF7E, 0x816F, 0xDFA1, 0x8144,
+	0xDFA2, 0x8161, 0xDFA3, 0x821D, 0xDFA4, 0x8249, 0xDFA5, 0x8244,
+	0xDFA6, 0x8240, 0xDFA7, 0x8242, 0xDFA8, 0x8245, 0xDFA9, 0x84F1,
+	0xDFAA, 0x843F, 0xDFAB, 0x8456, 0xDFAC, 0x8476, 0xDFAD, 0x8479,
+	0xDFAE, 0x848F, 0xDFAF, 0x848D, 0xDFB0, 0x8465, 0xDFB1, 0x8451,
+	0xDFB2, 0x8440, 0xDFB3, 0x8486, 0xDFB4, 0x8467, 0xDFB5, 0x8430,
+	0xDFB6, 0x844D, 0xDFB7, 0x847D, 0xDFB8, 0x845A, 0xDFB9, 0x8459,
+	0xDFBA, 0x8474, 0xDFBB, 0x8473, 0xDFBC, 0x845D, 0xDFBD, 0x8507,
+	0xDFBE, 0x845E, 0xDFBF, 0x8437, 0xDFC0, 0x843A, 0xDFC1, 0x8434,
+	0xDFC2, 0x847A, 0xDFC3, 0x8443, 0xDFC4, 0x8478, 0xDFC5, 0x8432,
+	0xDFC6, 0x8445, 0xDFC7, 0x8429, 0xDFC8, 0x83D9, 0xDFC9, 0x844B,
+	0xDFCA, 0x842F, 0xDFCB, 0x8442, 0xDFCC, 0x842D, 0xDFCD, 0x845F,
+	0xDFCE, 0x8470, 0xDFCF, 0x8439, 0xDFD0, 0x844E, 0xDFD1, 0x844C,
+	0xDFD2, 0x8452, 0xDFD3, 0x846F, 0xDFD4, 0x84C5, 0xDFD5, 0x848E,
+	0xDFD6, 0x843B, 0xDFD7, 0x8447, 0xDFD8, 0x8436, 0xDFD9, 0x8433,
+	0xDFDA, 0x8468, 0xDFDB, 0x847E, 0xDFDC, 0x8444, 0xDFDD, 0x842B,
+	0xDFDE, 0x8460, 0xDFDF, 0x8454, 0xDFE0, 0x846E, 0xDFE1, 0x8450,
+	0xDFE2, 0x870B, 0xDFE3, 0x8704, 0xDFE4, 0x86F7, 0xDFE5, 0x870C,
+	0xDFE6, 0x86FA, 0xDFE7, 0x86D6, 0xDFE8, 0x86F5, 0xDFE9, 0x874D,
+	0xDFEA, 0x86F8, 0xDFEB, 0x870E, 0xDFEC, 0x8709, 0xDFED, 0x8701,
+	0xDFEE, 0x86F6, 0xDFEF, 0x870D, 0xDFF0, 0x8705, 0xDFF1, 0x88D6,
+	0xDFF2, 0x88CB, 0xDFF3, 0x88CD, 0xDFF4, 0x88CE, 0xDFF5, 0x88DE,
+	0xDFF6, 0x88DB, 0xDFF7, 0x88DA, 0xDFF8, 0x88CC, 0xDFF9, 0x88D0,
+	0xDFFA, 0x8985, 0xDFFB, 0x899B, 0xDFFC, 0x89DF, 0xDFFD, 0x89E5,
+	0xDFFE, 0x89E4, 0xE040, 0x89E1, 0xE041, 0x89E0, 0xE042, 0x89E2,
+	0xE043, 0x89DC, 0xE044, 0x89E6, 0xE045, 0x8A76, 0xE046, 0x8A86,
+	0xE047, 0x8A7F, 0xE048, 0x8A61, 0xE049, 0x8A3F, 0xE04A, 0x8A77,
+	0xE04B, 0x8A82, 0xE04C, 0x8A84, 0xE04D, 0x8A75, 0xE04E, 0x8A83,
+	0xE04F, 0x8A81, 0xE050, 0x8A74, 0xE051, 0x8A7A, 0xE052, 0x8C3C,
+	0xE053, 0x8C4B, 0xE054, 0x8C4A, 0xE055, 0x8C65, 0xE056, 0x8C64,
+	0xE057, 0x8C66, 0xE058, 0x8C86, 0xE059, 0x8C84, 0xE05A, 0x8C85,
+	0xE05B, 0x8CCC, 0xE05C, 0x8D68, 0xE05D, 0x8D69, 0xE05E, 0x8D91,
+	0xE05F, 0x8D8C, 0xE060, 0x8D8E, 0xE061, 0x8D8F, 0xE062, 0x8D8D,
+	0xE063, 0x8D93, 0xE064, 0x8D94, 0xE065, 0x8D90, 0xE066, 0x8D92,
+	0xE067, 0x8DF0, 0xE068, 0x8DE0, 0xE069, 0x8DEC, 0xE06A, 0x8DF1,
+	0xE06B, 0x8DEE, 0xE06C, 0x8DD0, 0xE06D, 0x8DE9, 0xE06E, 0x8DE3,
+	0xE06F, 0x8DE2, 0xE070, 0x8DE7, 0xE071, 0x8DF2, 0xE072, 0x8DEB,
+	0xE073, 0x8DF4, 0xE074, 0x8F06, 0xE075, 0x8EFF, 0xE076, 0x8F01,
+	0xE077, 0x8F00, 0xE078, 0x8F05, 0xE079, 0x8F07, 0xE07A, 0x8F08,
+	0xE07B, 0x8F02, 0xE07C, 0x8F0B, 0xE07D, 0x9052, 0xE07E, 0x903F,
+	0xE0A1, 0x9044, 0xE0A2, 0x9049, 0xE0A3, 0x903D, 0xE0A4, 0x9110,
+	0xE0A5, 0x910D, 0xE0A6, 0x910F, 0xE0A7, 0x9111, 0xE0A8, 0x9116,
+	0xE0A9, 0x9114, 0xE0AA, 0x910B, 0xE0AB, 0x910E, 0xE0AC, 0x916E,
+	0xE0AD, 0x916F, 0xE0AE, 0x9248, 0xE0AF, 0x9252, 0xE0B0, 0x9230,
+	0xE0B1, 0x923A, 0xE0B2, 0x9266, 0xE0B3, 0x9233, 0xE0B4, 0x9265,
+	0xE0B5, 0x925E, 0xE0B6, 0x9283, 0xE0B7, 0x922E, 0xE0B8, 0x924A,
+	0xE0B9, 0x9246, 0xE0BA, 0x926D, 0xE0BB, 0x926C, 0xE0BC, 0x924F,
+	0xE0BD, 0x9260, 0xE0BE, 0x9267, 0xE0BF, 0x926F, 0xE0C0, 0x9236,
+	0xE0C1, 0x9261, 0xE0C2, 0x9270, 0xE0C3, 0x9231, 0xE0C4, 0x9254,
+	0xE0C5, 0x9263, 0xE0C6, 0x9250, 0xE0C7, 0x9272, 0xE0C8, 0x924E,
+	0xE0C9, 0x9253, 0xE0CA, 0x924C, 0xE0CB, 0x9256, 0xE0CC, 0x9232,
+	0xE0CD, 0x959F, 0xE0CE, 0x959C, 0xE0CF, 0x959E, 0xE0D0, 0x959B,
+	0xE0D1, 0x9692, 0xE0D2, 0x9693, 0xE0D3, 0x9691, 0xE0D4, 0x9697,
+	0xE0D5, 0x96CE, 0xE0D6, 0x96FA, 0xE0D7, 0x96FD, 0xE0D8, 0x96F8,
+	0xE0D9, 0x96F5, 0xE0DA, 0x9773, 0xE0DB, 0x9777, 0xE0DC, 0x9778,
+	0xE0DD, 0x9772, 0xE0DE, 0x980F, 0xE0DF, 0x980D, 0xE0E0, 0x980E,
+	0xE0E1, 0x98AC, 0xE0E2, 0x98F6, 0xE0E3, 0x98F9, 0xE0E4, 0x99AF,
+	0xE0E5, 0x99B2, 0xE0E6, 0x99B0, 0xE0E7, 0x99B5, 0xE0E8, 0x9AAD,
+	0xE0E9, 0x9AAB, 0xE0EA, 0x9B5B, 0xE0EB, 0x9CEA, 0xE0EC, 0x9CED,
+	0xE0ED, 0x9CE7, 0xE0EE, 0x9E80, 0xE0EF, 0x9EFD, 0xE0F0, 0x50E6,
+	0xE0F1, 0x50D4, 0xE0F2, 0x50D7, 0xE0F3, 0x50E8, 0xE0F4, 0x50F3,
+	0xE0F5, 0x50DB, 0xE0F6, 0x50EA, 0xE0F7, 0x50DD, 0xE0F8, 0x50E4,
+	0xE0F9, 0x50D3, 0xE0FA, 0x50EC, 0xE0FB, 0x50F0, 0xE0FC, 0x50EF,
+	0xE0FD, 0x50E3, 0xE0FE, 0x50E0, 0xE140, 0x51D8, 0xE141, 0x5280,
+	0xE142, 0x5281, 0xE143, 0x52E9, 0xE144, 0x52EB, 0xE145, 0x5330,
+	0xE146, 0x53AC, 0xE147, 0x5627, 0xE148, 0x5615, 0xE149, 0x560C,
+	0xE14A, 0x5612, 0xE14B, 0x55FC, 0xE14C, 0x560F, 0xE14D, 0x561C,
+	0xE14E, 0x5601, 0xE14F, 0x5613, 0xE150, 0x5602, 0xE151, 0x55FA,
+	0xE152, 0x561D, 0xE153, 0x5604, 0xE154, 0x55FF, 0xE155, 0x55F9,
+	0xE156, 0x5889, 0xE157, 0x587C, 0xE158, 0x5890, 0xE159, 0x5898,
+	0xE15A, 0x5886, 0xE15B, 0x5881, 0xE15C, 0x587F, 0xE15D, 0x5874,
+	0xE15E, 0x588B, 0xE15F, 0x587A, 0xE160, 0x5887, 0xE161, 0x5891,
+	0xE162, 0x588E, 0xE163, 0x5876, 0xE164, 0x5882, 0xE165, 0x5888,
+	0xE166, 0x587B, 0xE167, 0x5894, 0xE168, 0x588F, 0xE169, 0x58FE,
+	0xE16A, 0x596B, 0xE16B, 0x5ADC, 0xE16C, 0x5AEE, 0xE16D, 0x5AE5,
+	0xE16E, 0x5AD5, 0xE16F, 0x5AEA, 0xE170, 0x5ADA, 0xE171, 0x5AED,
+	0xE172, 0x5AEB, 0xE173, 0x5AF3, 0xE174, 0x5AE2, 0xE175, 0x5AE0,
+	0xE176, 0x5ADB, 0xE177, 0x5AEC, 0xE178, 0x5ADE, 0xE179, 0x5ADD,
+	0xE17A, 0x5AD9, 0xE17B, 0x5AE8, 0xE17C, 0x5ADF, 0xE17D, 0x5B77,
+	0xE17E, 0x5BE0, 0xE1A1, 0x5BE3, 0xE1A2, 0x5C63, 0xE1A3, 0x5D82,
+	0xE1A4, 0x5D80, 0xE1A5, 0x5D7D, 0xE1A6, 0x5D86, 0xE1A7, 0x5D7A,
+	0xE1A8, 0x5D81, 0xE1A9, 0x5D77, 0xE1AA, 0x5D8A, 0xE1AB, 0x5D89,
+	0xE1AC, 0x5D88, 0xE1AD, 0x5D7E, 0xE1AE, 0x5D7C, 0xE1AF, 0x5D8D,
+	0xE1B0, 0x5D79, 0xE1B1, 0x5D7F, 0xE1B2, 0x5E58, 0xE1B3, 0x5E59,
+	0xE1B4, 0x5E53, 0xE1B5, 0x5ED8, 0xE1B6, 0x5ED1, 0xE1B7, 0x5ED7,
+	0xE1B8, 0x5ECE, 0xE1B9, 0x5EDC, 0xE1BA, 0x5ED5, 0xE1BB, 0x5ED9,
+	0xE1BC, 0x5ED2, 0xE1BD, 0x5ED4, 0xE1BE, 0x5F44, 0xE1BF, 0x5F43,
+	0xE1C0, 0x5F6F, 0xE1C1, 0x5FB6, 0xE1C2, 0x612C, 0xE1C3, 0x6128,
+	0xE1C4, 0x6141, 0xE1C5, 0x615E, 0xE1C6, 0x6171, 0xE1C7, 0x6173,
+	0xE1C8, 0x6152, 0xE1C9, 0x6153, 0xE1CA, 0x6172, 0xE1CB, 0x616C,
+	0xE1CC, 0x6180, 0xE1CD, 0x6174, 0xE1CE, 0x6154, 0xE1CF, 0x617A,
+	0xE1D0, 0x615B, 0xE1D1, 0x6165, 0xE1D2, 0x613B, 0xE1D3, 0x616A,
+	0xE1D4, 0x6161, 0xE1D5, 0x6156, 0xE1D6, 0x6229, 0xE1D7, 0x6227,
+	0xE1D8, 0x622B, 0xE1D9, 0x642B, 0xE1DA, 0x644D, 0xE1DB, 0x645B,
+	0xE1DC, 0x645D, 0xE1DD, 0x6474, 0xE1DE, 0x6476, 0xE1DF, 0x6472,
+	0xE1E0, 0x6473, 0xE1E1, 0x647D, 0xE1E2, 0x6475, 0xE1E3, 0x6466,
+	0xE1E4, 0x64A6, 0xE1E5, 0x644E, 0xE1E6, 0x6482, 0xE1E7, 0x645E,
+	0xE1E8, 0x645C, 0xE1E9, 0x644B, 0xE1EA, 0x6453, 0xE1EB, 0x6460,
+	0xE1EC, 0x6450, 0xE1ED, 0x647F, 0xE1EE, 0x643F, 0xE1EF, 0x646C,
+	0xE1F0, 0x646B, 0xE1F1, 0x6459, 0xE1F2, 0x6465, 0xE1F3, 0x6477,
+	0xE1F4, 0x6573, 0xE1F5, 0x65A0, 0xE1F6, 0x66A1, 0xE1F7, 0x66A0,
+	0xE1F8, 0x669F, 0xE1F9, 0x6705, 0xE1FA, 0x6704, 0xE1FB, 0x6722,
+	0xE1FC, 0x69B1, 0xE1FD, 0x69B6, 0xE1FE, 0x69C9, 0xE240, 0x69A0,
+	0xE241, 0x69CE, 0xE242, 0x6996, 0xE243, 0x69B0, 0xE244, 0x69AC,
+	0xE245, 0x69BC, 0xE246, 0x6991, 0xE247, 0x6999, 0xE248, 0x698E,
+	0xE249, 0x69A7, 0xE24A, 0x698D, 0xE24B, 0x69A9, 0xE24C, 0x69BE,
+	0xE24D, 0x69AF, 0xE24E, 0x69BF, 0xE24F, 0x69C4, 0xE250, 0x69BD,
+	0xE251, 0x69A4, 0xE252, 0x69D4, 0xE253, 0x69B9, 0xE254, 0x69CA,
+	0xE255, 0x699A, 0xE256, 0x69CF, 0xE257, 0x69B3, 0xE258, 0x6993,
+	0xE259, 0x69AA, 0xE25A, 0x69A1, 0xE25B, 0x699E, 0xE25C, 0x69D9,
+	0xE25D, 0x6997, 0xE25E, 0x6990, 0xE25F, 0x69C2, 0xE260, 0x69B5,
+	0xE261, 0x69A5, 0xE262, 0x69C6, 0xE263, 0x6B4A, 0xE264, 0x6B4D,
+	0xE265, 0x6B4B, 0xE266, 0x6B9E, 0xE267, 0x6B9F, 0xE268, 0x6BA0,
+	0xE269, 0x6BC3, 0xE26A, 0x6BC4, 0xE26B, 0x6BFE, 0xE26C, 0x6ECE,
+	0xE26D, 0x6EF5, 0xE26E, 0x6EF1, 0xE26F, 0x6F03, 0xE270, 0x6F25,
+	0xE271, 0x6EF8, 0xE272, 0x6F37, 0xE273, 0x6EFB, 0xE274, 0x6F2E,
+	0xE275, 0x6F09, 0xE276, 0x6F4E, 0xE277, 0x6F19, 0xE278, 0x6F1A,
+	0xE279, 0x6F27, 0xE27A, 0x6F18, 0xE27B, 0x6F3B, 0xE27C, 0x6F12,
+	0xE27D, 0x6EED, 0xE27E, 0x6F0A, 0xE2A1, 0x6F36, 0xE2A2, 0x6F73,
+	0xE2A3, 0x6EF9, 0xE2A4, 0x6EEE, 0xE2A5, 0x6F2D, 0xE2A6, 0x6F40,
+	0xE2A7, 0x6F30, 0xE2A8, 0x6F3C, 0xE2A9, 0x6F35, 0xE2AA, 0x6EEB,
+	0xE2AB, 0x6F07, 0xE2AC, 0x6F0E, 0xE2AD, 0x6F43, 0xE2AE, 0x6F05,
+	0xE2AF, 0x6EFD, 0xE2B0, 0x6EF6, 0xE2B1, 0x6F39, 0xE2B2, 0x6F1C,
+	0xE2B3, 0x6EFC, 0xE2B4, 0x6F3A, 0xE2B5, 0x6F1F, 0xE2B6, 0x6F0D,
+	0xE2B7, 0x6F1E, 0xE2B8, 0x6F08, 0xE2B9, 0x6F21, 0xE2BA, 0x7187,
+	0xE2BB, 0x7190, 0xE2BC, 0x7189, 0xE2BD, 0x7180, 0xE2BE, 0x7185,
+	0xE2BF, 0x7182, 0xE2C0, 0x718F, 0xE2C1, 0x717B, 0xE2C2, 0x7186,
+	0xE2C3, 0x7181, 0xE2C4, 0x7197, 0xE2C5, 0x7244, 0xE2C6, 0x7253,
+	0xE2C7, 0x7297, 0xE2C8, 0x7295, 0xE2C9, 0x7293, 0xE2CA, 0x7343,
+	0xE2CB, 0x734D, 0xE2CC, 0x7351, 0xE2CD, 0x734C, 0xE2CE, 0x7462,
+	0xE2CF, 0x7473, 0xE2D0, 0x7471, 0xE2D1, 0x7475, 0xE2D2, 0x7472,
+	0xE2D3, 0x7467, 0xE2D4, 0x746E, 0xE2D5, 0x7500, 0xE2D6, 0x7502,
+	0xE2D7, 0x7503, 0xE2D8, 0x757D, 0xE2D9, 0x7590, 0xE2DA, 0x7616,
+	0xE2DB, 0x7608, 0xE2DC, 0x760C, 0xE2DD, 0x7615, 0xE2DE, 0x7611,
+	0xE2DF, 0x760A, 0xE2E0, 0x7614, 0xE2E1, 0x76B8, 0xE2E2, 0x7781,
+	0xE2E3, 0x777C, 0xE2E4, 0x7785, 0xE2E5, 0x7782, 0xE2E6, 0x776E,
+	0xE2E7, 0x7780, 0xE2E8, 0x776F, 0xE2E9, 0x777E, 0xE2EA, 0x7783,
+	0xE2EB, 0x78B2, 0xE2EC, 0x78AA, 0xE2ED, 0x78B4, 0xE2EE, 0x78AD,
+	0xE2EF, 0x78A8, 0xE2F0, 0x787E, 0xE2F1, 0x78AB, 0xE2F2, 0x789E,
+	0xE2F3, 0x78A5, 0xE2F4, 0x78A0, 0xE2F5, 0x78AC, 0xE2F6, 0x78A2,
+	0xE2F7, 0x78A4, 0xE2F8, 0x7998, 0xE2F9, 0x798A, 0xE2FA, 0x798B,
+	0xE2FB, 0x7996, 0xE2FC, 0x7995, 0xE2FD, 0x7994, 0xE2FE, 0x7993,
+	0xE340, 0x7997, 0xE341, 0x7988, 0xE342, 0x7992, 0xE343, 0x7990,
+	0xE344, 0x7A2B, 0xE345, 0x7A4A, 0xE346, 0x7A30, 0xE347, 0x7A2F,
+	0xE348, 0x7A28, 0xE349, 0x7A26, 0xE34A, 0x7AA8, 0xE34B, 0x7AAB,
+	0xE34C, 0x7AAC, 0xE34D, 0x7AEE, 0xE34E, 0x7B88, 0xE34F, 0x7B9C,
+	0xE350, 0x7B8A, 0xE351, 0x7B91, 0xE352, 0x7B90, 0xE353, 0x7B96,
+	0xE354, 0x7B8D, 0xE355, 0x7B8C, 0xE356, 0x7B9B, 0xE357, 0x7B8E,
+	0xE358, 0x7B85, 0xE359, 0x7B98, 0xE35A, 0x5284, 0xE35B, 0x7B99,
+	0xE35C, 0x7BA4, 0xE35D, 0x7B82, 0xE35E, 0x7CBB, 0xE35F, 0x7CBF,
+	0xE360, 0x7CBC, 0xE361, 0x7CBA, 0xE362, 0x7DA7, 0xE363, 0x7DB7,
+	0xE364, 0x7DC2, 0xE365, 0x7DA3, 0xE366, 0x7DAA, 0xE367, 0x7DC1,
+	0xE368, 0x7DC0, 0xE369, 0x7DC5, 0xE36A, 0x7D9D, 0xE36B, 0x7DCE,
+	0xE36C, 0x7DC4, 0xE36D, 0x7DC6, 0xE36E, 0x7DCB, 0xE36F, 0x7DCC,
+	0xE370, 0x7DAF, 0xE371, 0x7DB9, 0xE372, 0x7D96, 0xE373, 0x7DBC,
+	0xE374, 0x7D9F, 0xE375, 0x7DA6, 0xE376, 0x7DAE, 0xE377, 0x7DA9,
+	0xE378, 0x7DA1, 0xE379, 0x7DC9, 0xE37A, 0x7F73, 0xE37B, 0x7FE2,
+	0xE37C, 0x7FE3, 0xE37D, 0x7FE5, 0xE37E, 0x7FDE, 0xE3A1, 0x8024,
+	0xE3A2, 0x805D, 0xE3A3, 0x805C, 0xE3A4, 0x8189, 0xE3A5, 0x8186,
+	0xE3A6, 0x8183, 0xE3A7, 0x8187, 0xE3A8, 0x818D, 0xE3A9, 0x818C,
+	0xE3AA, 0x818B, 0xE3AB, 0x8215, 0xE3AC, 0x8497, 0xE3AD, 0x84A4,
+	0xE3AE, 0x84A1, 0xE3AF, 0x849F, 0xE3B0, 0x84BA, 0xE3B1, 0x84CE,
+	0xE3B2, 0x84C2, 0xE3B3, 0x84AC, 0xE3B4, 0x84AE, 0xE3B5, 0x84AB,
+	0xE3B6, 0x84B9, 0xE3B7, 0x84B4, 0xE3B8, 0x84C1, 0xE3B9, 0x84CD,
+	0xE3BA, 0x84AA, 0xE3BB, 0x849A, 0xE3BC, 0x84B1, 0xE3BD, 0x84D0,
+	0xE3BE, 0x849D, 0xE3BF, 0x84A7, 0xE3C0, 0x84BB, 0xE3C1, 0x84A2,
+	0xE3C2, 0x8494, 0xE3C3, 0x84C7, 0xE3C4, 0x84CC, 0xE3C5, 0x849B,
+	0xE3C6, 0x84A9, 0xE3C7, 0x84AF, 0xE3C8, 0x84A8, 0xE3C9, 0x84D6,
+	0xE3CA, 0x8498, 0xE3CB, 0x84B6, 0xE3CC, 0x84CF, 0xE3CD, 0x84A0,
+	0xE3CE, 0x84D7, 0xE3CF, 0x84D4, 0xE3D0, 0x84D2, 0xE3D1, 0x84DB,
+	0xE3D2, 0x84B0, 0xE3D3, 0x8491, 0xE3D4, 0x8661, 0xE3D5, 0x8733,
+	0xE3D6, 0x8723, 0xE3D7, 0x8728, 0xE3D8, 0x876B, 0xE3D9, 0x8740,
+	0xE3DA, 0x872E, 0xE3DB, 0x871E, 0xE3DC, 0x8721, 0xE3DD, 0x8719,
+	0xE3DE, 0x871B, 0xE3DF, 0x8743, 0xE3E0, 0x872C, 0xE3E1, 0x8741,
+	0xE3E2, 0x873E, 0xE3E3, 0x8746, 0xE3E4, 0x8720, 0xE3E5, 0x8732,
+	0xE3E6, 0x872A, 0xE3E7, 0x872D, 0xE3E8, 0x873C, 0xE3E9, 0x8712,
+	0xE3EA, 0x873A, 0xE3EB, 0x8731, 0xE3EC, 0x8735, 0xE3ED, 0x8742,
+	0xE3EE, 0x8726, 0xE3EF, 0x8727, 0xE3F0, 0x8738, 0xE3F1, 0x8724,
+	0xE3F2, 0x871A, 0xE3F3, 0x8730, 0xE3F4, 0x8711, 0xE3F5, 0x88F7,
+	0xE3F6, 0x88E7, 0xE3F7, 0x88F1, 0xE3F8, 0x88F2, 0xE3F9, 0x88FA,
+	0xE3FA, 0x88FE, 0xE3FB, 0x88EE, 0xE3FC, 0x88FC, 0xE3FD, 0x88F6,
+	0xE3FE, 0x88FB, 0xE440, 0x88F0, 0xE441, 0x88EC, 0xE442, 0x88EB,
+	0xE443, 0x899D, 0xE444, 0x89A1, 0xE445, 0x899F, 0xE446, 0x899E,
+	0xE447, 0x89E9, 0xE448, 0x89EB, 0xE449, 0x89E8, 0xE44A, 0x8AAB,
+	0xE44B, 0x8A99, 0xE44C, 0x8A8B, 0xE44D, 0x8A92, 0xE44E, 0x8A8F,
+	0xE44F, 0x8A96, 0xE450, 0x8C3D, 0xE451, 0x8C68, 0xE452, 0x8C69,
+	0xE453, 0x8CD5, 0xE454, 0x8CCF, 0xE455, 0x8CD7, 0xE456, 0x8D96,
+	0xE457, 0x8E09, 0xE458, 0x8E02, 0xE459, 0x8DFF, 0xE45A, 0x8E0D,
+	0xE45B, 0x8DFD, 0xE45C, 0x8E0A, 0xE45D, 0x8E03, 0xE45E, 0x8E07,
+	0xE45F, 0x8E06, 0xE460, 0x8E05, 0xE461, 0x8DFE, 0xE462, 0x8E00,
+	0xE463, 0x8E04, 0xE464, 0x8F10, 0xE465, 0x8F11, 0xE466, 0x8F0E,
+	0xE467, 0x8F0D, 0xE468, 0x9123, 0xE469, 0x911C, 0xE46A, 0x9120,
+	0xE46B, 0x9122, 0xE46C, 0x911F, 0xE46D, 0x911D, 0xE46E, 0x911A,
+	0xE46F, 0x9124, 0xE470, 0x9121, 0xE471, 0x911B, 0xE472, 0x917A,
+	0xE473, 0x9172, 0xE474, 0x9179, 0xE475, 0x9173, 0xE476, 0x92A5,
+	0xE477, 0x92A4, 0xE478, 0x9276, 0xE479, 0x929B, 0xE47A, 0x927A,
+	0xE47B, 0x92A0, 0xE47C, 0x9294, 0xE47D, 0x92AA, 0xE47E, 0x928D,
+	0xE4A1, 0x92A6, 0xE4A2, 0x929A, 0xE4A3, 0x92AB, 0xE4A4, 0x9279,
+	0xE4A5, 0x9297, 0xE4A6, 0x927F, 0xE4A7, 0x92A3, 0xE4A8, 0x92EE,
+	0xE4A9, 0x928E, 0xE4AA, 0x9282, 0xE4AB, 0x9295, 0xE4AC, 0x92A2,
+	0xE4AD, 0x927D, 0xE4AE, 0x9288, 0xE4AF, 0x92A1, 0xE4B0, 0x928A,
+	0xE4B1, 0x9286, 0xE4B2, 0x928C, 0xE4B3, 0x9299, 0xE4B4, 0x92A7,
+	0xE4B5, 0x927E, 0xE4B6, 0x9287, 0xE4B7, 0x92A9, 0xE4B8, 0x929D,
+	0xE4B9, 0x928B, 0xE4BA, 0x922D, 0xE4BB, 0x969E, 0xE4BC, 0x96A1,
+	0xE4BD, 0x96FF, 0xE4BE, 0x9758, 0xE4BF, 0x977D, 0xE4C0, 0x977A,
+	0xE4C1, 0x977E, 0xE4C2, 0x9783, 0xE4C3, 0x9780, 0xE4C4, 0x9782,
+	0xE4C5, 0x977B, 0xE4C6, 0x9784, 0xE4C7, 0x9781, 0xE4C8, 0x977F,
+	0xE4C9, 0x97CE, 0xE4CA, 0x97CD, 0xE4CB, 0x9816, 0xE4CC, 0x98AD,
+	0xE4CD, 0x98AE, 0xE4CE, 0x9902, 0xE4CF, 0x9900, 0xE4D0, 0x9907,
+	0xE4D1, 0x999D, 0xE4D2, 0x999C, 0xE4D3, 0x99C3, 0xE4D4, 0x99B9,
+	0xE4D5, 0x99BB, 0xE4D6, 0x99BA, 0xE4D7, 0x99C2, 0xE4D8, 0x99BD,
+	0xE4D9, 0x99C7, 0xE4DA, 0x9AB1, 0xE4DB, 0x9AE3, 0xE4DC, 0x9AE7,
+	0xE4DD, 0x9B3E, 0xE4DE, 0x9B3F, 0xE4DF, 0x9B60, 0xE4E0, 0x9B61,
+	0xE4E1, 0x9B5F, 0xE4E2, 0x9CF1, 0xE4E3, 0x9CF2, 0xE4E4, 0x9CF5,
+	0xE4E5, 0x9EA7, 0xE4E6, 0x50FF, 0xE4E7, 0x5103, 0xE4E8, 0x5130,
+	0xE4E9, 0x50F8, 0xE4EA, 0x5106, 0xE4EB, 0x5107, 0xE4EC, 0x50F6,
+	0xE4ED, 0x50FE, 0xE4EE, 0x510B, 0xE4EF, 0x510C, 0xE4F0, 0x50FD,
+	0xE4F1, 0x510A, 0xE4F2, 0x528B, 0xE4F3, 0x528C, 0xE4F4, 0x52F1,
+	0xE4F5, 0x52EF, 0xE4F6, 0x5648, 0xE4F7, 0x5642, 0xE4F8, 0x564C,
+	0xE4F9, 0x5635, 0xE4FA, 0x5641, 0xE4FB, 0x564A, 0xE4FC, 0x5649,
+	0xE4FD, 0x5646, 0xE4FE, 0x5658, 0xE540, 0x565A, 0xE541, 0x5640,
+	0xE542, 0x5633, 0xE543, 0x563D, 0xE544, 0x562C, 0xE545, 0x563E,
+	0xE546, 0x5638, 0xE547, 0x562A, 0xE548, 0x563A, 0xE549, 0x571A,
+	0xE54A, 0x58AB, 0xE54B, 0x589D, 0xE54C, 0x58B1, 0xE54D, 0x58A0,
+	0xE54E, 0x58A3, 0xE54F, 0x58AF, 0xE550, 0x58AC, 0xE551, 0x58A5,
+	0xE552, 0x58A1, 0xE553, 0x58FF, 0xE554, 0x5AFF, 0xE555, 0x5AF4,
+	0xE556, 0x5AFD, 0xE557, 0x5AF7, 0xE558, 0x5AF6, 0xE559, 0x5B03,
+	0xE55A, 0x5AF8, 0xE55B, 0x5B02, 0xE55C, 0x5AF9, 0xE55D, 0x5B01,
+	0xE55E, 0x5B07, 0xE55F, 0x5B05, 0xE560, 0x5B0F, 0xE561, 0x5C67,
+	0xE562, 0x5D99, 0xE563, 0x5D97, 0xE564, 0x5D9F, 0xE565, 0x5D92,
+	0xE566, 0x5DA2, 0xE567, 0x5D93, 0xE568, 0x5D95, 0xE569, 0x5DA0,
+	0xE56A, 0x5D9C, 0xE56B, 0x5DA1, 0xE56C, 0x5D9A, 0xE56D, 0x5D9E,
+	0xE56E, 0x5E69, 0xE56F, 0x5E5D, 0xE570, 0x5E60, 0xE571, 0x5E5C,
+	0xE572, 0x7DF3, 0xE573, 0x5EDB, 0xE574, 0x5EDE, 0xE575, 0x5EE1,
+	0xE576, 0x5F49, 0xE577, 0x5FB2, 0xE578, 0x618B, 0xE579, 0x6183,
+	0xE57A, 0x6179, 0xE57B, 0x61B1, 0xE57C, 0x61B0, 0xE57D, 0x61A2,
+	0xE57E, 0x6189, 0xE5A1, 0x619B, 0xE5A2, 0x6193, 0xE5A3, 0x61AF,
+	0xE5A4, 0x61AD, 0xE5A5, 0x619F, 0xE5A6, 0x6192, 0xE5A7, 0x61AA,
+	0xE5A8, 0x61A1, 0xE5A9, 0x618D, 0xE5AA, 0x6166, 0xE5AB, 0x61B3,
+	0xE5AC, 0x622D, 0xE5AD, 0x646E, 0xE5AE, 0x6470, 0xE5AF, 0x6496,
+	0xE5B0, 0x64A0, 0xE5B1, 0x6485, 0xE5B2, 0x6497, 0xE5B3, 0x649C,
+	0xE5B4, 0x648F, 0xE5B5, 0x648B, 0xE5B6, 0x648A, 0xE5B7, 0x648C,
+	0xE5B8, 0x64A3, 0xE5B9, 0x649F, 0xE5BA, 0x6468, 0xE5BB, 0x64B1,
+	0xE5BC, 0x6498, 0xE5BD, 0x6576, 0xE5BE, 0x657A, 0xE5BF, 0x6579,
+	0xE5C0, 0x657B, 0xE5C1, 0x65B2, 0xE5C2, 0x65B3, 0xE5C3, 0x66B5,
+	0xE5C4, 0x66B0, 0xE5C5, 0x66A9, 0xE5C6, 0x66B2, 0xE5C7, 0x66B7,
+	0xE5C8, 0x66AA, 0xE5C9, 0x66AF, 0xE5CA, 0x6A00, 0xE5CB, 0x6A06,
+	0xE5CC, 0x6A17, 0xE5CD, 0x69E5, 0xE5CE, 0x69F8, 0xE5CF, 0x6A15,
+	0xE5D0, 0x69F1, 0xE5D1, 0x69E4, 0xE5D2, 0x6A20, 0xE5D3, 0x69FF,
+	0xE5D4, 0x69EC, 0xE5D5, 0x69E2, 0xE5D6, 0x6A1B, 0xE5D7, 0x6A1D,
+	0xE5D8, 0x69FE, 0xE5D9, 0x6A27, 0xE5DA, 0x69F2, 0xE5DB, 0x69EE,
+	0xE5DC, 0x6A14, 0xE5DD, 0x69F7, 0xE5DE, 0x69E7, 0xE5DF, 0x6A40,
+	0xE5E0, 0x6A08, 0xE5E1, 0x69E6, 0xE5E2, 0x69FB, 0xE5E3, 0x6A0D,
+	0xE5E4, 0x69FC, 0xE5E5, 0x69EB, 0xE5E6, 0x6A09, 0xE5E7, 0x6A04,
+	0xE5E8, 0x6A18, 0xE5E9, 0x6A25, 0xE5EA, 0x6A0F, 0xE5EB, 0x69F6,
+	0xE5EC, 0x6A26, 0xE5ED, 0x6A07, 0xE5EE, 0x69F4, 0xE5EF, 0x6A16,
+	0xE5F0, 0x6B51, 0xE5F1, 0x6BA5, 0xE5F2, 0x6BA3, 0xE5F3, 0x6BA2,
+	0xE5F4, 0x6BA6, 0xE5F5, 0x6C01, 0xE5F6, 0x6C00, 0xE5F7, 0x6BFF,
+	0xE5F8, 0x6C02, 0xE5F9, 0x6F41, 0xE5FA, 0x6F26, 0xE5FB, 0x6F7E,
+	0xE5FC, 0x6F87, 0xE5FD, 0x6FC6, 0xE5FE, 0x6F92, 0xE640, 0x6F8D,
+	0xE641, 0x6F89, 0xE642, 0x6F8C, 0xE643, 0x6F62, 0xE644, 0x6F4F,
+	0xE645, 0x6F85, 0xE646, 0x6F5A, 0xE647, 0x6F96, 0xE648, 0x6F76,
+	0xE649, 0x6F6C, 0xE64A, 0x6F82, 0xE64B, 0x6F55, 0xE64C, 0x6F72,
+	0xE64D, 0x6F52, 0xE64E, 0x6F50, 0xE64F, 0x6F57, 0xE650, 0x6F94,
+	0xE651, 0x6F93, 0xE652, 0x6F5D, 0xE653, 0x6F00, 0xE654, 0x6F61,
+	0xE655, 0x6F6B, 0xE656, 0x6F7D, 0xE657, 0x6F67, 0xE658, 0x6F90,
+	0xE659, 0x6F53, 0xE65A, 0x6F8B, 0xE65B, 0x6F69, 0xE65C, 0x6F7F,
+	0xE65D, 0x6F95, 0xE65E, 0x6F63, 0xE65F, 0x6F77, 0xE660, 0x6F6A,
+	0xE661, 0x6F7B, 0xE662, 0x71B2, 0xE663, 0x71AF, 0xE664, 0x719B,
+	0xE665, 0x71B0, 0xE666, 0x71A0, 0xE667, 0x719A, 0xE668, 0x71A9,
+	0xE669, 0x71B5, 0xE66A, 0x719D, 0xE66B, 0x71A5, 0xE66C, 0x719E,
+	0xE66D, 0x71A4, 0xE66E, 0x71A1, 0xE66F, 0x71AA, 0xE670, 0x719C,
+	0xE671, 0x71A7, 0xE672, 0x71B3, 0xE673, 0x7298, 0xE674, 0x729A,
+	0xE675, 0x7358, 0xE676, 0x7352, 0xE677, 0x735E, 0xE678, 0x735F,
+	0xE679, 0x7360, 0xE67A, 0x735D, 0xE67B, 0x735B, 0xE67C, 0x7361,
+	0xE67D, 0x735A, 0xE67E, 0x7359, 0xE6A1, 0x7362, 0xE6A2, 0x7487,
+	0xE6A3, 0x7489, 0xE6A4, 0x748A, 0xE6A5, 0x7486, 0xE6A6, 0x7481,
+	0xE6A7, 0x747D, 0xE6A8, 0x7485, 0xE6A9, 0x7488, 0xE6AA, 0x747C,
+	0xE6AB, 0x7479, 0xE6AC, 0x7508, 0xE6AD, 0x7507, 0xE6AE, 0x757E,
+	0xE6AF, 0x7625, 0xE6B0, 0x761E, 0xE6B1, 0x7619, 0xE6B2, 0x761D,
+	0xE6B3, 0x761C, 0xE6B4, 0x7623, 0xE6B5, 0x761A, 0xE6B6, 0x7628,
+	0xE6B7, 0x761B, 0xE6B8, 0x769C, 0xE6B9, 0x769D, 0xE6BA, 0x769E,
+	0xE6BB, 0x769B, 0xE6BC, 0x778D, 0xE6BD, 0x778F, 0xE6BE, 0x7789,
+	0xE6BF, 0x7788, 0xE6C0, 0x78CD, 0xE6C1, 0x78BB, 0xE6C2, 0x78CF,
+	0xE6C3, 0x78CC, 0xE6C4, 0x78D1, 0xE6C5, 0x78CE, 0xE6C6, 0x78D4,
+	0xE6C7, 0x78C8, 0xE6C8, 0x78C3, 0xE6C9, 0x78C4, 0xE6CA, 0x78C9,
+	0xE6CB, 0x799A, 0xE6CC, 0x79A1, 0xE6CD, 0x79A0, 0xE6CE, 0x799C,
+	0xE6CF, 0x79A2, 0xE6D0, 0x799B, 0xE6D1, 0x6B76, 0xE6D2, 0x7A39,
+	0xE6D3, 0x7AB2, 0xE6D4, 0x7AB4, 0xE6D5, 0x7AB3, 0xE6D6, 0x7BB7,
+	0xE6D7, 0x7BCB, 0xE6D8, 0x7BBE, 0xE6D9, 0x7BAC, 0xE6DA, 0x7BCE,
+	0xE6DB, 0x7BAF, 0xE6DC, 0x7BB9, 0xE6DD, 0x7BCA, 0xE6DE, 0x7BB5,
+	0xE6DF, 0x7CC5, 0xE6E0, 0x7CC8, 0xE6E1, 0x7CCC, 0xE6E2, 0x7CCB,
+	0xE6E3, 0x7DF7, 0xE6E4, 0x7DDB, 0xE6E5, 0x7DEA, 0xE6E6, 0x7DE7,
+	0xE6E7, 0x7DD7, 0xE6E8, 0x7DE1, 0xE6E9, 0x7E03, 0xE6EA, 0x7DFA,
+	0xE6EB, 0x7DE6, 0xE6EC, 0x7DF6, 0xE6ED, 0x7DF1, 0xE6EE, 0x7DF0,
+	0xE6EF, 0x7DEE, 0xE6F0, 0x7DDF, 0xE6F1, 0x7F76, 0xE6F2, 0x7FAC,
+	0xE6F3, 0x7FB0, 0xE6F4, 0x7FAD, 0xE6F5, 0x7FED, 0xE6F6, 0x7FEB,
+	0xE6F7, 0x7FEA, 0xE6F8, 0x7FEC, 0xE6F9, 0x7FE6, 0xE6FA, 0x7FE8,
+	0xE6FB, 0x8064, 0xE6FC, 0x8067, 0xE6FD, 0x81A3, 0xE6FE, 0x819F,
+	0xE740, 0x819E, 0xE741, 0x8195, 0xE742, 0x81A2, 0xE743, 0x8199,
+	0xE744, 0x8197, 0xE745, 0x8216, 0xE746, 0x824F, 0xE747, 0x8253,
+	0xE748, 0x8252, 0xE749, 0x8250, 0xE74A, 0x824E, 0xE74B, 0x8251,
+	0xE74C, 0x8524, 0xE74D, 0x853B, 0xE74E, 0x850F, 0xE74F, 0x8500,
+	0xE750, 0x8529, 0xE751, 0x850E, 0xE752, 0x8509, 0xE753, 0x850D,
+	0xE754, 0x851F, 0xE755, 0x850A, 0xE756, 0x8527, 0xE757, 0x851C,
+	0xE758, 0x84FB, 0xE759, 0x852B, 0xE75A, 0x84FA, 0xE75B, 0x8508,
+	0xE75C, 0x850C, 0xE75D, 0x84F4, 0xE75E, 0x852A, 0xE75F, 0x84F2,
+	0xE760, 0x8515, 0xE761, 0x84F7, 0xE762, 0x84EB, 0xE763, 0x84F3,
+	0xE764, 0x84FC, 0xE765, 0x8512, 0xE766, 0x84EA, 0xE767, 0x84E9,
+	0xE768, 0x8516, 0xE769, 0x84FE, 0xE76A, 0x8528, 0xE76B, 0x851D,
+	0xE76C, 0x852E, 0xE76D, 0x8502, 0xE76E, 0x84FD, 0xE76F, 0x851E,
+	0xE770, 0x84F6, 0xE771, 0x8531, 0xE772, 0x8526, 0xE773, 0x84E7,
+	0xE774, 0x84E8, 0xE775, 0x84F0, 0xE776, 0x84EF, 0xE777, 0x84F9,
+	0xE778, 0x8518, 0xE779, 0x8520, 0xE77A, 0x8530, 0xE77B, 0x850B,
+	0xE77C, 0x8519, 0xE77D, 0x852F, 0xE77E, 0x8662, 0xE7A1, 0x8756,
+	0xE7A2, 0x8763, 0xE7A3, 0x8764, 0xE7A4, 0x8777, 0xE7A5, 0x87E1,
+	0xE7A6, 0x8773, 0xE7A7, 0x8758, 0xE7A8, 0x8754, 0xE7A9, 0x875B,
+	0xE7AA, 0x8752, 0xE7AB, 0x8761, 0xE7AC, 0x875A, 0xE7AD, 0x8751,
+	0xE7AE, 0x875E, 0xE7AF, 0x876D, 0xE7B0, 0x876A, 0xE7B1, 0x8750,
+	0xE7B2, 0x874E, 0xE7B3, 0x875F, 0xE7B4, 0x875D, 0xE7B5, 0x876F,
+	0xE7B6, 0x876C, 0xE7B7, 0x877A, 0xE7B8, 0x876E, 0xE7B9, 0x875C,
+	0xE7BA, 0x8765, 0xE7BB, 0x874F, 0xE7BC, 0x877B, 0xE7BD, 0x8775,
+	0xE7BE, 0x8762, 0xE7BF, 0x8767, 0xE7C0, 0x8769, 0xE7C1, 0x885A,
+	0xE7C2, 0x8905, 0xE7C3, 0x890C, 0xE7C4, 0x8914, 0xE7C5, 0x890B,
+	0xE7C6, 0x8917, 0xE7C7, 0x8918, 0xE7C8, 0x8919, 0xE7C9, 0x8906,
+	0xE7CA, 0x8916, 0xE7CB, 0x8911, 0xE7CC, 0x890E, 0xE7CD, 0x8909,
+	0xE7CE, 0x89A2, 0xE7CF, 0x89A4, 0xE7D0, 0x89A3, 0xE7D1, 0x89ED,
+	0xE7D2, 0x89F0, 0xE7D3, 0x89EC, 0xE7D4, 0x8ACF, 0xE7D5, 0x8AC6,
+	0xE7D6, 0x8AB8, 0xE7D7, 0x8AD3, 0xE7D8, 0x8AD1, 0xE7D9, 0x8AD4,
+	0xE7DA, 0x8AD5, 0xE7DB, 0x8ABB, 0xE7DC, 0x8AD7, 0xE7DD, 0x8ABE,
+	0xE7DE, 0x8AC0, 0xE7DF, 0x8AC5, 0xE7E0, 0x8AD8, 0xE7E1, 0x8AC3,
+	0xE7E2, 0x8ABA, 0xE7E3, 0x8ABD, 0xE7E4, 0x8AD9, 0xE7E5, 0x8C3E,
+	0xE7E6, 0x8C4D, 0xE7E7, 0x8C8F, 0xE7E8, 0x8CE5, 0xE7E9, 0x8CDF,
+	0xE7EA, 0x8CD9, 0xE7EB, 0x8CE8, 0xE7EC, 0x8CDA, 0xE7ED, 0x8CDD,
+	0xE7EE, 0x8CE7, 0xE7EF, 0x8DA0, 0xE7F0, 0x8D9C, 0xE7F1, 0x8DA1,
+	0xE7F2, 0x8D9B, 0xE7F3, 0x8E20, 0xE7F4, 0x8E23, 0xE7F5, 0x8E25,
+	0xE7F6, 0x8E24, 0xE7F7, 0x8E2E, 0xE7F8, 0x8E15, 0xE7F9, 0x8E1B,
+	0xE7FA, 0x8E16, 0xE7FB, 0x8E11, 0xE7FC, 0x8E19, 0xE7FD, 0x8E26,
+	0xE7FE, 0x8E27, 0xE840, 0x8E14, 0xE841, 0x8E12, 0xE842, 0x8E18,
+	0xE843, 0x8E13, 0xE844, 0x8E1C, 0xE845, 0x8E17, 0xE846, 0x8E1A,
+	0xE847, 0x8F2C, 0xE848, 0x8F24, 0xE849, 0x8F18, 0xE84A, 0x8F1A,
+	0xE84B, 0x8F20, 0xE84C, 0x8F23, 0xE84D, 0x8F16, 0xE84E, 0x8F17,
+	0xE84F, 0x9073, 0xE850, 0x9070, 0xE851, 0x906F, 0xE852, 0x9067,
+	0xE853, 0x906B, 0xE854, 0x912F, 0xE855, 0x912B, 0xE856, 0x9129,
+	0xE857, 0x912A, 0xE858, 0x9132, 0xE859, 0x9126, 0xE85A, 0x912E,
+	0xE85B, 0x9185, 0xE85C, 0x9186, 0xE85D, 0x918A, 0xE85E, 0x9181,
+	0xE85F, 0x9182, 0xE860, 0x9184, 0xE861, 0x9180, 0xE862, 0x92D0,
+	0xE863, 0x92C3, 0xE864, 0x92C4, 0xE865, 0x92C0, 0xE866, 0x92D9,
+	0xE867, 0x92B6, 0xE868, 0x92CF, 0xE869, 0x92F1, 0xE86A, 0x92DF,
+	0xE86B, 0x92D8, 0xE86C, 0x92E9, 0xE86D, 0x92D7, 0xE86E, 0x92DD,
+	0xE86F, 0x92CC, 0xE870, 0x92EF, 0xE871, 0x92C2, 0xE872, 0x92E8,
+	0xE873, 0x92CA, 0xE874, 0x92C8, 0xE875, 0x92CE, 0xE876, 0x92E6,
+	0xE877, 0x92CD, 0xE878, 0x92D5, 0xE879, 0x92C9, 0xE87A, 0x92E0,
+	0xE87B, 0x92DE, 0xE87C, 0x92E7, 0xE87D, 0x92D1, 0xE87E, 0x92D3,
+	0xE8A1, 0x92B5, 0xE8A2, 0x92E1, 0xE8A3, 0x92C6, 0xE8A4, 0x92B4,
+	0xE8A5, 0x957C, 0xE8A6, 0x95AC, 0xE8A7, 0x95AB, 0xE8A8, 0x95AE,
+	0xE8A9, 0x95B0, 0xE8AA, 0x96A4, 0xE8AB, 0x96A2, 0xE8AC, 0x96D3,
+	0xE8AD, 0x9705, 0xE8AE, 0x9708, 0xE8AF, 0x9702, 0xE8B0, 0x975A,
+	0xE8B1, 0x978A, 0xE8B2, 0x978E, 0xE8B3, 0x9788, 0xE8B4, 0x97D0,
+	0xE8B5, 0x97CF, 0xE8B6, 0x981E, 0xE8B7, 0x981D, 0xE8B8, 0x9826,
+	0xE8B9, 0x9829, 0xE8BA, 0x9828, 0xE8BB, 0x9820, 0xE8BC, 0x981B,
+	0xE8BD, 0x9827, 0xE8BE, 0x98B2, 0xE8BF, 0x9908, 0xE8C0, 0x98FA,
+	0xE8C1, 0x9911, 0xE8C2, 0x9914, 0xE8C3, 0x9916, 0xE8C4, 0x9917,
+	0xE8C5, 0x9915, 0xE8C6, 0x99DC, 0xE8C7, 0x99CD, 0xE8C8, 0x99CF,
+	0xE8C9, 0x99D3, 0xE8CA, 0x99D4, 0xE8CB, 0x99CE, 0xE8CC, 0x99C9,
+	0xE8CD, 0x99D6, 0xE8CE, 0x99D8, 0xE8CF, 0x99CB, 0xE8D0, 0x99D7,
+	0xE8D1, 0x99CC, 0xE8D2, 0x9AB3, 0xE8D3, 0x9AEC, 0xE8D4, 0x9AEB,
+	0xE8D5, 0x9AF3, 0xE8D6, 0x9AF2, 0xE8D7, 0x9AF1, 0xE8D8, 0x9B46,
+	0xE8D9, 0x9B43, 0xE8DA, 0x9B67, 0xE8DB, 0x9B74, 0xE8DC, 0x9B71,
+	0xE8DD, 0x9B66, 0xE8DE, 0x9B76, 0xE8DF, 0x9B75, 0xE8E0, 0x9B70,
+	0xE8E1, 0x9B68, 0xE8E2, 0x9B64, 0xE8E3, 0x9B6C, 0xE8E4, 0x9CFC,
+	0xE8E5, 0x9CFA, 0xE8E6, 0x9CFD, 0xE8E7, 0x9CFF, 0xE8E8, 0x9CF7,
+	0xE8E9, 0x9D07, 0xE8EA, 0x9D00, 0xE8EB, 0x9CF9, 0xE8EC, 0x9CFB,
+	0xE8ED, 0x9D08, 0xE8EE, 0x9D05, 0xE8EF, 0x9D04, 0xE8F0, 0x9E83,
+	0xE8F1, 0x9ED3, 0xE8F2, 0x9F0F, 0xE8F3, 0x9F10, 0xE8F4, 0x511C,
+	0xE8F5, 0x5113, 0xE8F6, 0x5117, 0xE8F7, 0x511A, 0xE8F8, 0x5111,
+	0xE8F9, 0x51DE, 0xE8FA, 0x5334, 0xE8FB, 0x53E1, 0xE8FC, 0x5670,
+	0xE8FD, 0x5660, 0xE8FE, 0x566E, 0xE940, 0x5673, 0xE941, 0x5666,
+	0xE942, 0x5663, 0xE943, 0x566D, 0xE944, 0x5672, 0xE945, 0x565E,
+	0xE946, 0x5677, 0xE947, 0x571C, 0xE948, 0x571B, 0xE949, 0x58C8,
+	0xE94A, 0x58BD, 0xE94B, 0x58C9, 0xE94C, 0x58BF, 0xE94D, 0x58BA,
+	0xE94E, 0x58C2, 0xE94F, 0x58BC, 0xE950, 0x58C6, 0xE951, 0x5B17,
+	0xE952, 0x5B19, 0xE953, 0x5B1B, 0xE954, 0x5B21, 0xE955, 0x5B14,
+	0xE956, 0x5B13, 0xE957, 0x5B10, 0xE958, 0x5B16, 0xE959, 0x5B28,
+	0xE95A, 0x5B1A, 0xE95B, 0x5B20, 0xE95C, 0x5B1E, 0xE95D, 0x5BEF,
+	0xE95E, 0x5DAC, 0xE95F, 0x5DB1, 0xE960, 0x5DA9, 0xE961, 0x5DA7,
+	0xE962, 0x5DB5, 0xE963, 0x5DB0, 0xE964, 0x5DAE, 0xE965, 0x5DAA,
+	0xE966, 0x5DA8, 0xE967, 0x5DB2, 0xE968, 0x5DAD, 0xE969, 0x5DAF,
+	0xE96A, 0x5DB4, 0xE96B, 0x5E67, 0xE96C, 0x5E68, 0xE96D, 0x5E66,
+	0xE96E, 0x5E6F, 0xE96F, 0x5EE9, 0xE970, 0x5EE7, 0xE971, 0x5EE6,
+	0xE972, 0x5EE8, 0xE973, 0x5EE5, 0xE974, 0x5F4B, 0xE975, 0x5FBC,
+	0xE976, 0x619D, 0xE977, 0x61A8, 0xE978, 0x6196, 0xE979, 0x61C5,
+	0xE97A, 0x61B4, 0xE97B, 0x61C6, 0xE97C, 0x61C1, 0xE97D, 0x61CC,
+	0xE97E, 0x61BA, 0xE9A1, 0x61BF, 0xE9A2, 0x61B8, 0xE9A3, 0x618C,
+	0xE9A4, 0x64D7, 0xE9A5, 0x64D6, 0xE9A6, 0x64D0, 0xE9A7, 0x64CF,
+	0xE9A8, 0x64C9, 0xE9A9, 0x64BD, 0xE9AA, 0x6489, 0xE9AB, 0x64C3,
+	0xE9AC, 0x64DB, 0xE9AD, 0x64F3, 0xE9AE, 0x64D9, 0xE9AF, 0x6533,
+	0xE9B0, 0x657F, 0xE9B1, 0x657C, 0xE9B2, 0x65A2, 0xE9B3, 0x66C8,
+	0xE9B4, 0x66BE, 0xE9B5, 0x66C0, 0xE9B6, 0x66CA, 0xE9B7, 0x66CB,
+	0xE9B8, 0x66CF, 0xE9B9, 0x66BD, 0xE9BA, 0x66BB, 0xE9BB, 0x66BA,
+	0xE9BC, 0x66CC, 0xE9BD, 0x6723, 0xE9BE, 0x6A34, 0xE9BF, 0x6A66,
+	0xE9C0, 0x6A49, 0xE9C1, 0x6A67, 0xE9C2, 0x6A32, 0xE9C3, 0x6A68,
+	0xE9C4, 0x6A3E, 0xE9C5, 0x6A5D, 0xE9C6, 0x6A6D, 0xE9C7, 0x6A76,
+	0xE9C8, 0x6A5B, 0xE9C9, 0x6A51, 0xE9CA, 0x6A28, 0xE9CB, 0x6A5A,
+	0xE9CC, 0x6A3B, 0xE9CD, 0x6A3F, 0xE9CE, 0x6A41, 0xE9CF, 0x6A6A,
+	0xE9D0, 0x6A64, 0xE9D1, 0x6A50, 0xE9D2, 0x6A4F, 0xE9D3, 0x6A54,
+	0xE9D4, 0x6A6F, 0xE9D5, 0x6A69, 0xE9D6, 0x6A60, 0xE9D7, 0x6A3C,
+	0xE9D8, 0x6A5E, 0xE9D9, 0x6A56, 0xE9DA, 0x6A55, 0xE9DB, 0x6A4D,
+	0xE9DC, 0x6A4E, 0xE9DD, 0x6A46, 0xE9DE, 0x6B55, 0xE9DF, 0x6B54,
+	0xE9E0, 0x6B56, 0xE9E1, 0x6BA7, 0xE9E2, 0x6BAA, 0xE9E3, 0x6BAB,
+	0xE9E4, 0x6BC8, 0xE9E5, 0x6BC7, 0xE9E6, 0x6C04, 0xE9E7, 0x6C03,
+	0xE9E8, 0x6C06, 0xE9E9, 0x6FAD, 0xE9EA, 0x6FCB, 0xE9EB, 0x6FA3,
+	0xE9EC, 0x6FC7, 0xE9ED, 0x6FBC, 0xE9EE, 0x6FCE, 0xE9EF, 0x6FC8,
+	0xE9F0, 0x6F5E, 0xE9F1, 0x6FC4, 0xE9F2, 0x6FBD, 0xE9F3, 0x6F9E,
+	0xE9F4, 0x6FCA, 0xE9F5, 0x6FA8, 0xE9F6, 0x7004, 0xE9F7, 0x6FA5,
+	0xE9F8, 0x6FAE, 0xE9F9, 0x6FBA, 0xE9FA, 0x6FAC, 0xE9FB, 0x6FAA,
+	0xE9FC, 0x6FCF, 0xE9FD, 0x6FBF, 0xE9FE, 0x6FB8, 0xEA40, 0x6FA2,
+	0xEA41, 0x6FC9, 0xEA42, 0x6FAB, 0xEA43, 0x6FCD, 0xEA44, 0x6FAF,
+	0xEA45, 0x6FB2, 0xEA46, 0x6FB0, 0xEA47, 0x71C5, 0xEA48, 0x71C2,
+	0xEA49, 0x71BF, 0xEA4A, 0x71B8, 0xEA4B, 0x71D6, 0xEA4C, 0x71C0,
+	0xEA4D, 0x71C1, 0xEA4E, 0x71CB, 0xEA4F, 0x71D4, 0xEA50, 0x71CA,
+	0xEA51, 0x71C7, 0xEA52, 0x71CF, 0xEA53, 0x71BD, 0xEA54, 0x71D8,
+	0xEA55, 0x71BC, 0xEA56, 0x71C6, 0xEA57, 0x71DA, 0xEA58, 0x71DB,
+	0xEA59, 0x729D, 0xEA5A, 0x729E, 0xEA5B, 0x7369, 0xEA5C, 0x7366,
+	0xEA5D, 0x7367, 0xEA5E, 0x736C, 0xEA5F, 0x7365, 0xEA60, 0x736B,
+	0xEA61, 0x736A, 0xEA62, 0x747F, 0xEA63, 0x749A, 0xEA64, 0x74A0,
+	0xEA65, 0x7494, 0xEA66, 0x7492, 0xEA67, 0x7495, 0xEA68, 0x74A1,
+	0xEA69, 0x750B, 0xEA6A, 0x7580, 0xEA6B, 0x762F, 0xEA6C, 0x762D,
+	0xEA6D, 0x7631, 0xEA6E, 0x763D, 0xEA6F, 0x7633, 0xEA70, 0x763C,
+	0xEA71, 0x7635, 0xEA72, 0x7632, 0xEA73, 0x7630, 0xEA74, 0x76BB,
+	0xEA75, 0x76E6, 0xEA76, 0x779A, 0xEA77, 0x779D, 0xEA78, 0x77A1,
+	0xEA79, 0x779C, 0xEA7A, 0x779B, 0xEA7B, 0x77A2, 0xEA7C, 0x77A3,
+	0xEA7D, 0x7795, 0xEA7E, 0x7799, 0xEAA1, 0x7797, 0xEAA2, 0x78DD,
+	0xEAA3, 0x78E9, 0xEAA4, 0x78E5, 0xEAA5, 0x78EA, 0xEAA6, 0x78DE,
+	0xEAA7, 0x78E3, 0xEAA8, 0x78DB, 0xEAA9, 0x78E1, 0xEAAA, 0x78E2,
+	0xEAAB, 0x78ED, 0xEAAC, 0x78DF, 0xEAAD, 0x78E0, 0xEAAE, 0x79A4,
+	0xEAAF, 0x7A44, 0xEAB0, 0x7A48, 0xEAB1, 0x7A47, 0xEAB2, 0x7AB6,
+	0xEAB3, 0x7AB8, 0xEAB4, 0x7AB5, 0xEAB5, 0x7AB1, 0xEAB6, 0x7AB7,
+	0xEAB7, 0x7BDE, 0xEAB8, 0x7BE3, 0xEAB9, 0x7BE7, 0xEABA, 0x7BDD,
+	0xEABB, 0x7BD5, 0xEABC, 0x7BE5, 0xEABD, 0x7BDA, 0xEABE, 0x7BE8,
+	0xEABF, 0x7BF9, 0xEAC0, 0x7BD4, 0xEAC1, 0x7BEA, 0xEAC2, 0x7BE2,
+	0xEAC3, 0x7BDC, 0xEAC4, 0x7BEB, 0xEAC5, 0x7BD8, 0xEAC6, 0x7BDF,
+	0xEAC7, 0x7CD2, 0xEAC8, 0x7CD4, 0xEAC9, 0x7CD7, 0xEACA, 0x7CD0,
+	0xEACB, 0x7CD1, 0xEACC, 0x7E12, 0xEACD, 0x7E21, 0xEACE, 0x7E17,
+	0xEACF, 0x7E0C, 0xEAD0, 0x7E1F, 0xEAD1, 0x7E20, 0xEAD2, 0x7E13,
+	0xEAD3, 0x7E0E, 0xEAD4, 0x7E1C, 0xEAD5, 0x7E15, 0xEAD6, 0x7E1A,
+	0xEAD7, 0x7E22, 0xEAD8, 0x7E0B, 0xEAD9, 0x7E0F, 0xEADA, 0x7E16,
+	0xEADB, 0x7E0D, 0xEADC, 0x7E14, 0xEADD, 0x7E25, 0xEADE, 0x7E24,
+	0xEADF, 0x7F43, 0xEAE0, 0x7F7B, 0xEAE1, 0x7F7C, 0xEAE2, 0x7F7A,
+	0xEAE3, 0x7FB1, 0xEAE4, 0x7FEF, 0xEAE5, 0x802A, 0xEAE6, 0x8029,
+	0xEAE7, 0x806C, 0xEAE8, 0x81B1, 0xEAE9, 0x81A6, 0xEAEA, 0x81AE,
+	0xEAEB, 0x81B9, 0xEAEC, 0x81B5, 0xEAED, 0x81AB, 0xEAEE, 0x81B0,
+	0xEAEF, 0x81AC, 0xEAF0, 0x81B4, 0xEAF1, 0x81B2, 0xEAF2, 0x81B7,
+	0xEAF3, 0x81A7, 0xEAF4, 0x81F2, 0xEAF5, 0x8255, 0xEAF6, 0x8256,
+	0xEAF7, 0x8257, 0xEAF8, 0x8556, 0xEAF9, 0x8545, 0xEAFA, 0x856B,
+	0xEAFB, 0x854D, 0xEAFC, 0x8553, 0xEAFD, 0x8561, 0xEAFE, 0x8558,
+	0xEB40, 0x8540, 0xEB41, 0x8546, 0xEB42, 0x8564, 0xEB43, 0x8541,
+	0xEB44, 0x8562, 0xEB45, 0x8544, 0xEB46, 0x8551, 0xEB47, 0x8547,
+	0xEB48, 0x8563, 0xEB49, 0x853E, 0xEB4A, 0x855B, 0xEB4B, 0x8571,
+	0xEB4C, 0x854E, 0xEB4D, 0x856E, 0xEB4E, 0x8575, 0xEB4F, 0x8555,
+	0xEB50, 0x8567, 0xEB51, 0x8560, 0xEB52, 0x858C, 0xEB53, 0x8566,
+	0xEB54, 0x855D, 0xEB55, 0x8554, 0xEB56, 0x8565, 0xEB57, 0x856C,
+	0xEB58, 0x8663, 0xEB59, 0x8665, 0xEB5A, 0x8664, 0xEB5B, 0x879B,
+	0xEB5C, 0x878F, 0xEB5D, 0x8797, 0xEB5E, 0x8793, 0xEB5F, 0x8792,
+	0xEB60, 0x8788, 0xEB61, 0x8781, 0xEB62, 0x8796, 0xEB63, 0x8798,
+	0xEB64, 0x8779, 0xEB65, 0x8787, 0xEB66, 0x87A3, 0xEB67, 0x8785,
+	0xEB68, 0x8790, 0xEB69, 0x8791, 0xEB6A, 0x879D, 0xEB6B, 0x8784,
+	0xEB6C, 0x8794, 0xEB6D, 0x879C, 0xEB6E, 0x879A, 0xEB6F, 0x8789,
+	0xEB70, 0x891E, 0xEB71, 0x8926, 0xEB72, 0x8930, 0xEB73, 0x892D,
+	0xEB74, 0x892E, 0xEB75, 0x8927, 0xEB76, 0x8931, 0xEB77, 0x8922,
+	0xEB78, 0x8929, 0xEB79, 0x8923, 0xEB7A, 0x892F, 0xEB7B, 0x892C,
+	0xEB7C, 0x891F, 0xEB7D, 0x89F1, 0xEB7E, 0x8AE0, 0xEBA1, 0x8AE2,
+	0xEBA2, 0x8AF2, 0xEBA3, 0x8AF4, 0xEBA4, 0x8AF5, 0xEBA5, 0x8ADD,
+	0xEBA6, 0x8B14, 0xEBA7, 0x8AE4, 0xEBA8, 0x8ADF, 0xEBA9, 0x8AF0,
+	0xEBAA, 0x8AC8, 0xEBAB, 0x8ADE, 0xEBAC, 0x8AE1, 0xEBAD, 0x8AE8,
+	0xEBAE, 0x8AFF, 0xEBAF, 0x8AEF, 0xEBB0, 0x8AFB, 0xEBB1, 0x8C91,
+	0xEBB2, 0x8C92, 0xEBB3, 0x8C90, 0xEBB4, 0x8CF5, 0xEBB5, 0x8CEE,
+	0xEBB6, 0x8CF1, 0xEBB7, 0x8CF0, 0xEBB8, 0x8CF3, 0xEBB9, 0x8D6C,
+	0xEBBA, 0x8D6E, 0xEBBB, 0x8DA5, 0xEBBC, 0x8DA7, 0xEBBD, 0x8E33,
+	0xEBBE, 0x8E3E, 0xEBBF, 0x8E38, 0xEBC0, 0x8E40, 0xEBC1, 0x8E45,
+	0xEBC2, 0x8E36, 0xEBC3, 0x8E3C, 0xEBC4, 0x8E3D, 0xEBC5, 0x8E41,
+	0xEBC6, 0x8E30, 0xEBC7, 0x8E3F, 0xEBC8, 0x8EBD, 0xEBC9, 0x8F36,
+	0xEBCA, 0x8F2E, 0xEBCB, 0x8F35, 0xEBCC, 0x8F32, 0xEBCD, 0x8F39,
+	0xEBCE, 0x8F37, 0xEBCF, 0x8F34, 0xEBD0, 0x9076, 0xEBD1, 0x9079,
+	0xEBD2, 0x907B, 0xEBD3, 0x9086, 0xEBD4, 0x90FA, 0xEBD5, 0x9133,
+	0xEBD6, 0x9135, 0xEBD7, 0x9136, 0xEBD8, 0x9193, 0xEBD9, 0x9190,
+	0xEBDA, 0x9191, 0xEBDB, 0x918D, 0xEBDC, 0x918F, 0xEBDD, 0x9327,
+	0xEBDE, 0x931E, 0xEBDF, 0x9308, 0xEBE0, 0x931F, 0xEBE1, 0x9306,
+	0xEBE2, 0x930F, 0xEBE3, 0x937A, 0xEBE4, 0x9338, 0xEBE5, 0x933C,
+	0xEBE6, 0x931B, 0xEBE7, 0x9323, 0xEBE8, 0x9312, 0xEBE9, 0x9301,
+	0xEBEA, 0x9346, 0xEBEB, 0x932D, 0xEBEC, 0x930E, 0xEBED, 0x930D,
+	0xEBEE, 0x92CB, 0xEBEF, 0x931D, 0xEBF0, 0x92FA, 0xEBF1, 0x9325,
+	0xEBF2, 0x9313, 0xEBF3, 0x92F9, 0xEBF4, 0x92F7, 0xEBF5, 0x9334,
+	0xEBF6, 0x9302, 0xEBF7, 0x9324, 0xEBF8, 0x92FF, 0xEBF9, 0x9329,
+	0xEBFA, 0x9339, 0xEBFB, 0x9335, 0xEBFC, 0x932A, 0xEBFD, 0x9314,
+	0xEBFE, 0x930C, 0xEC40, 0x930B, 0xEC41, 0x92FE, 0xEC42, 0x9309,
+	0xEC43, 0x9300, 0xEC44, 0x92FB, 0xEC45, 0x9316, 0xEC46, 0x95BC,
+	0xEC47, 0x95CD, 0xEC48, 0x95BE, 0xEC49, 0x95B9, 0xEC4A, 0x95BA,
+	0xEC4B, 0x95B6, 0xEC4C, 0x95BF, 0xEC4D, 0x95B5, 0xEC4E, 0x95BD,
+	0xEC4F, 0x96A9, 0xEC50, 0x96D4, 0xEC51, 0x970B, 0xEC52, 0x9712,
+	0xEC53, 0x9710, 0xEC54, 0x9799, 0xEC55, 0x9797, 0xEC56, 0x9794,
+	0xEC57, 0x97F0, 0xEC58, 0x97F8, 0xEC59, 0x9835, 0xEC5A, 0x982F,
+	0xEC5B, 0x9832, 0xEC5C, 0x9924, 0xEC5D, 0x991F, 0xEC5E, 0x9927,
+	0xEC5F, 0x9929, 0xEC60, 0x999E, 0xEC61, 0x99EE, 0xEC62, 0x99EC,
+	0xEC63, 0x99E5, 0xEC64, 0x99E4, 0xEC65, 0x99F0, 0xEC66, 0x99E3,
+	0xEC67, 0x99EA, 0xEC68, 0x99E9, 0xEC69, 0x99E7, 0xEC6A, 0x9AB9,
+	0xEC6B, 0x9ABF, 0xEC6C, 0x9AB4, 0xEC6D, 0x9ABB, 0xEC6E, 0x9AF6,
+	0xEC6F, 0x9AFA, 0xEC70, 0x9AF9, 0xEC71, 0x9AF7, 0xEC72, 0x9B33,
+	0xEC73, 0x9B80, 0xEC74, 0x9B85, 0xEC75, 0x9B87, 0xEC76, 0x9B7C,
+	0xEC77, 0x9B7E, 0xEC78, 0x9B7B, 0xEC79, 0x9B82, 0xEC7A, 0x9B93,
+	0xEC7B, 0x9B92, 0xEC7C, 0x9B90, 0xEC7D, 0x9B7A, 0xEC7E, 0x9B95,
+	0xECA1, 0x9B7D, 0xECA2, 0x9B88, 0xECA3, 0x9D25, 0xECA4, 0x9D17,
+	0xECA5, 0x9D20, 0xECA6, 0x9D1E, 0xECA7, 0x9D14, 0xECA8, 0x9D29,
+	0xECA9, 0x9D1D, 0xECAA, 0x9D18, 0xECAB, 0x9D22, 0xECAC, 0x9D10,
+	0xECAD, 0x9D19, 0xECAE, 0x9D1F, 0xECAF, 0x9E88, 0xECB0, 0x9E86,
+	0xECB1, 0x9E87, 0xECB2, 0x9EAE, 0xECB3, 0x9EAD, 0xECB4, 0x9ED5,
+	0xECB5, 0x9ED6, 0xECB6, 0x9EFA, 0xECB7, 0x9F12, 0xECB8, 0x9F3D,
+	0xECB9, 0x5126, 0xECBA, 0x5125, 0xECBB, 0x5122, 0xECBC, 0x5124,
+	0xECBD, 0x5120, 0xECBE, 0x5129, 0xECBF, 0x52F4, 0xECC0, 0x5693,
+	0xECC1, 0x568C, 0xECC2, 0x568D, 0xECC3, 0x5686, 0xECC4, 0x5684,
+	0xECC5, 0x5683, 0xECC6, 0x567E, 0xECC7, 0x5682, 0xECC8, 0x567F,
+	0xECC9, 0x5681, 0xECCA, 0x58D6, 0xECCB, 0x58D4, 0xECCC, 0x58CF,
+	0xECCD, 0x58D2, 0xECCE, 0x5B2D, 0xECCF, 0x5B25, 0xECD0, 0x5B32,
+	0xECD1, 0x5B23, 0xECD2, 0x5B2C, 0xECD3, 0x5B27, 0xECD4, 0x5B26,
+	0xECD5, 0x5B2F, 0xECD6, 0x5B2E, 0xECD7, 0x5B7B, 0xECD8, 0x5BF1,
+	0xECD9, 0x5BF2, 0xECDA, 0x5DB7, 0xECDB, 0x5E6C, 0xECDC, 0x5E6A,
+	0xECDD, 0x5FBE, 0xECDE, 0x5FBB, 0xECDF, 0x61C3, 0xECE0, 0x61B5,
+	0xECE1, 0x61BC, 0xECE2, 0x61E7, 0xECE3, 0x61E0, 0xECE4, 0x61E5,
+	0xECE5, 0x61E4, 0xECE6, 0x61E8, 0xECE7, 0x61DE, 0xECE8, 0x64EF,
+	0xECE9, 0x64E9, 0xECEA, 0x64E3, 0xECEB, 0x64EB, 0xECEC, 0x64E4,
+	0xECED, 0x64E8, 0xECEE, 0x6581, 0xECEF, 0x6580, 0xECF0, 0x65B6,
+	0xECF1, 0x65DA, 0xECF2, 0x66D2, 0xECF3, 0x6A8D, 0xECF4, 0x6A96,
+	0xECF5, 0x6A81, 0xECF6, 0x6AA5, 0xECF7, 0x6A89, 0xECF8, 0x6A9F,
+	0xECF9, 0x6A9B, 0xECFA, 0x6AA1, 0xECFB, 0x6A9E, 0xECFC, 0x6A87,
+	0xECFD, 0x6A93, 0xECFE, 0x6A8E, 0xED40, 0x6A95, 0xED41, 0x6A83,
+	0xED42, 0x6AA8, 0xED43, 0x6AA4, 0xED44, 0x6A91, 0xED45, 0x6A7F,
+	0xED46, 0x6AA6, 0xED47, 0x6A9A, 0xED48, 0x6A85, 0xED49, 0x6A8C,
+	0xED4A, 0x6A92, 0xED4B, 0x6B5B, 0xED4C, 0x6BAD, 0xED4D, 0x6C09,
+	0xED4E, 0x6FCC, 0xED4F, 0x6FA9, 0xED50, 0x6FF4, 0xED51, 0x6FD4,
+	0xED52, 0x6FE3, 0xED53, 0x6FDC, 0xED54, 0x6FED, 0xED55, 0x6FE7,
+	0xED56, 0x6FE6, 0xED57, 0x6FDE, 0xED58, 0x6FF2, 0xED59, 0x6FDD,
+	0xED5A, 0x6FE2, 0xED5B, 0x6FE8, 0xED5C, 0x71E1, 0xED5D, 0x71F1,
+	0xED5E, 0x71E8, 0xED5F, 0x71F2, 0xED60, 0x71E4, 0xED61, 0x71F0,
+	0xED62, 0x71E2, 0xED63, 0x7373, 0xED64, 0x736E, 0xED65, 0x736F,
+	0xED66, 0x7497, 0xED67, 0x74B2, 0xED68, 0x74AB, 0xED69, 0x7490,
+	0xED6A, 0x74AA, 0xED6B, 0x74AD, 0xED6C, 0x74B1, 0xED6D, 0x74A5,
+	0xED6E, 0x74AF, 0xED6F, 0x7510, 0xED70, 0x7511, 0xED71, 0x7512,
+	0xED72, 0x750F, 0xED73, 0x7584, 0xED74, 0x7643, 0xED75, 0x7648,
+	0xED76, 0x7649, 0xED77, 0x7647, 0xED78, 0x76A4, 0xED79, 0x76E9,
+	0xED7A, 0x77B5, 0xED7B, 0x77AB, 0xED7C, 0x77B2, 0xED7D, 0x77B7,
+	0xED7E, 0x77B6, 0xEDA1, 0x77B4, 0xEDA2, 0x77B1, 0xEDA3, 0x77A8,
+	0xEDA4, 0x77F0, 0xEDA5, 0x78F3, 0xEDA6, 0x78FD, 0xEDA7, 0x7902,
+	0xEDA8, 0x78FB, 0xEDA9, 0x78FC, 0xEDAA, 0x78F2, 0xEDAB, 0x7905,
+	0xEDAC, 0x78F9, 0xEDAD, 0x78FE, 0xEDAE, 0x7904, 0xEDAF, 0x79AB,
+	0xEDB0, 0x79A8, 0xEDB1, 0x7A5C, 0xEDB2, 0x7A5B, 0xEDB3, 0x7A56,
+	0xEDB4, 0x7A58, 0xEDB5, 0x7A54, 0xEDB6, 0x7A5A, 0xEDB7, 0x7ABE,
+	0xEDB8, 0x7AC0, 0xEDB9, 0x7AC1, 0xEDBA, 0x7C05, 0xEDBB, 0x7C0F,
+	0xEDBC, 0x7BF2, 0xEDBD, 0x7C00, 0xEDBE, 0x7BFF, 0xEDBF, 0x7BFB,
+	0xEDC0, 0x7C0E, 0xEDC1, 0x7BF4, 0xEDC2, 0x7C0B, 0xEDC3, 0x7BF3,
+	0xEDC4, 0x7C02, 0xEDC5, 0x7C09, 0xEDC6, 0x7C03, 0xEDC7, 0x7C01,
+	0xEDC8, 0x7BF8, 0xEDC9, 0x7BFD, 0xEDCA, 0x7C06, 0xEDCB, 0x7BF0,
+	0xEDCC, 0x7BF1, 0xEDCD, 0x7C10, 0xEDCE, 0x7C0A, 0xEDCF, 0x7CE8,
+	0xEDD0, 0x7E2D, 0xEDD1, 0x7E3C, 0xEDD2, 0x7E42, 0xEDD3, 0x7E33,
+	0xEDD4, 0x9848, 0xEDD5, 0x7E38, 0xEDD6, 0x7E2A, 0xEDD7, 0x7E49,
+	0xEDD8, 0x7E40, 0xEDD9, 0x7E47, 0xEDDA, 0x7E29, 0xEDDB, 0x7E4C,
+	0xEDDC, 0x7E30, 0xEDDD, 0x7E3B, 0xEDDE, 0x7E36, 0xEDDF, 0x7E44,
+	0xEDE0, 0x7E3A, 0xEDE1, 0x7F45, 0xEDE2, 0x7F7F, 0xEDE3, 0x7F7E,
+	0xEDE4, 0x7F7D, 0xEDE5, 0x7FF4, 0xEDE6, 0x7FF2, 0xEDE7, 0x802C,
+	0xEDE8, 0x81BB, 0xEDE9, 0x81C4, 0xEDEA, 0x81CC, 0xEDEB, 0x81CA,
+	0xEDEC, 0x81C5, 0xEDED, 0x81C7, 0xEDEE, 0x81BC, 0xEDEF, 0x81E9,
+	0xEDF0, 0x825B, 0xEDF1, 0x825A, 0xEDF2, 0x825C, 0xEDF3, 0x8583,
+	0xEDF4, 0x8580, 0xEDF5, 0x858F, 0xEDF6, 0x85A7, 0xEDF7, 0x8595,
+	0xEDF8, 0x85A0, 0xEDF9, 0x858B, 0xEDFA, 0x85A3, 0xEDFB, 0x857B,
+	0xEDFC, 0x85A4, 0xEDFD, 0x859A, 0xEDFE, 0x859E, 0xEE40, 0x8577,
+	0xEE41, 0x857C, 0xEE42, 0x8589, 0xEE43, 0x85A1, 0xEE44, 0x857A,
+	0xEE45, 0x8578, 0xEE46, 0x8557, 0xEE47, 0x858E, 0xEE48, 0x8596,
+	0xEE49, 0x8586, 0xEE4A, 0x858D, 0xEE4B, 0x8599, 0xEE4C, 0x859D,
+	0xEE4D, 0x8581, 0xEE4E, 0x85A2, 0xEE4F, 0x8582, 0xEE50, 0x8588,
+	0xEE51, 0x8585, 0xEE52, 0x8579, 0xEE53, 0x8576, 0xEE54, 0x8598,
+	0xEE55, 0x8590, 0xEE56, 0x859F, 0xEE57, 0x8668, 0xEE58, 0x87BE,
+	0xEE59, 0x87AA, 0xEE5A, 0x87AD, 0xEE5B, 0x87C5, 0xEE5C, 0x87B0,
+	0xEE5D, 0x87AC, 0xEE5E, 0x87B9, 0xEE5F, 0x87B5, 0xEE60, 0x87BC,
+	0xEE61, 0x87AE, 0xEE62, 0x87C9, 0xEE63, 0x87C3, 0xEE64, 0x87C2,
+	0xEE65, 0x87CC, 0xEE66, 0x87B7, 0xEE67, 0x87AF, 0xEE68, 0x87C4,
+	0xEE69, 0x87CA, 0xEE6A, 0x87B4, 0xEE6B, 0x87B6, 0xEE6C, 0x87BF,
+	0xEE6D, 0x87B8, 0xEE6E, 0x87BD, 0xEE6F, 0x87DE, 0xEE70, 0x87B2,
+	0xEE71, 0x8935, 0xEE72, 0x8933, 0xEE73, 0x893C, 0xEE74, 0x893E,
+	0xEE75, 0x8941, 0xEE76, 0x8952, 0xEE77, 0x8937, 0xEE78, 0x8942,
+	0xEE79, 0x89AD, 0xEE7A, 0x89AF, 0xEE7B, 0x89AE, 0xEE7C, 0x89F2,
+	0xEE7D, 0x89F3, 0xEE7E, 0x8B1E, 0xEEA1, 0x8B18, 0xEEA2, 0x8B16,
+	0xEEA3, 0x8B11, 0xEEA4, 0x8B05, 0xEEA5, 0x8B0B, 0xEEA6, 0x8B22,
+	0xEEA7, 0x8B0F, 0xEEA8, 0x8B12, 0xEEA9, 0x8B15, 0xEEAA, 0x8B07,
+	0xEEAB, 0x8B0D, 0xEEAC, 0x8B08, 0xEEAD, 0x8B06, 0xEEAE, 0x8B1C,
+	0xEEAF, 0x8B13, 0xEEB0, 0x8B1A, 0xEEB1, 0x8C4F, 0xEEB2, 0x8C70,
+	0xEEB3, 0x8C72, 0xEEB4, 0x8C71, 0xEEB5, 0x8C6F, 0xEEB6, 0x8C95,
+	0xEEB7, 0x8C94, 0xEEB8, 0x8CF9, 0xEEB9, 0x8D6F, 0xEEBA, 0x8E4E,
+	0xEEBB, 0x8E4D, 0xEEBC, 0x8E53, 0xEEBD, 0x8E50, 0xEEBE, 0x8E4C,
+	0xEEBF, 0x8E47, 0xEEC0, 0x8F43, 0xEEC1, 0x8F40, 0xEEC2, 0x9085,
+	0xEEC3, 0x907E, 0xEEC4, 0x9138, 0xEEC5, 0x919A, 0xEEC6, 0x91A2,
+	0xEEC7, 0x919B, 0xEEC8, 0x9199, 0xEEC9, 0x919F, 0xEECA, 0x91A1,
+	0xEECB, 0x919D, 0xEECC, 0x91A0, 0xEECD, 0x93A1, 0xEECE, 0x9383,
+	0xEECF, 0x93AF, 0xEED0, 0x9364, 0xEED1, 0x9356, 0xEED2, 0x9347,
+	0xEED3, 0x937C, 0xEED4, 0x9358, 0xEED5, 0x935C, 0xEED6, 0x9376,
+	0xEED7, 0x9349, 0xEED8, 0x9350, 0xEED9, 0x9351, 0xEEDA, 0x9360,
+	0xEEDB, 0x936D, 0xEEDC, 0x938F, 0xEEDD, 0x934C, 0xEEDE, 0x936A,
+	0xEEDF, 0x9379, 0xEEE0, 0x9357, 0xEEE1, 0x9355, 0xEEE2, 0x9352,
+	0xEEE3, 0x934F, 0xEEE4, 0x9371, 0xEEE5, 0x9377, 0xEEE6, 0x937B,
+	0xEEE7, 0x9361, 0xEEE8, 0x935E, 0xEEE9, 0x9363, 0xEEEA, 0x9367,
+	0xEEEB, 0x9380, 0xEEEC, 0x934E, 0xEEED, 0x9359, 0xEEEE, 0x95C7,
+	0xEEEF, 0x95C0, 0xEEF0, 0x95C9, 0xEEF1, 0x95C3, 0xEEF2, 0x95C5,
+	0xEEF3, 0x95B7, 0xEEF4, 0x96AE, 0xEEF5, 0x96B0, 0xEEF6, 0x96AC,
+	0xEEF7, 0x9720, 0xEEF8, 0x971F, 0xEEF9, 0x9718, 0xEEFA, 0x971D,
+	0xEEFB, 0x9719, 0xEEFC, 0x979A, 0xEEFD, 0x97A1, 0xEEFE, 0x979C,
+	0xEF40, 0x979E, 0xEF41, 0x979D, 0xEF42, 0x97D5, 0xEF43, 0x97D4,
+	0xEF44, 0x97F1, 0xEF45, 0x9841, 0xEF46, 0x9844, 0xEF47, 0x984A,
+	0xEF48, 0x9849, 0xEF49, 0x9845, 0xEF4A, 0x9843, 0xEF4B, 0x9925,
+	0xEF4C, 0x992B, 0xEF4D, 0x992C, 0xEF4E, 0x992A, 0xEF4F, 0x9933,
+	0xEF50, 0x9932, 0xEF51, 0x992F, 0xEF52, 0x992D, 0xEF53, 0x9931,
+	0xEF54, 0x9930, 0xEF55, 0x9998, 0xEF56, 0x99A3, 0xEF57, 0x99A1,
+	0xEF58, 0x9A02, 0xEF59, 0x99FA, 0xEF5A, 0x99F4, 0xEF5B, 0x99F7,
+	0xEF5C, 0x99F9, 0xEF5D, 0x99F8, 0xEF5E, 0x99F6, 0xEF5F, 0x99FB,
+	0xEF60, 0x99FD, 0xEF61, 0x99FE, 0xEF62, 0x99FC, 0xEF63, 0x9A03,
+	0xEF64, 0x9ABE, 0xEF65, 0x9AFE, 0xEF66, 0x9AFD, 0xEF67, 0x9B01,
+	0xEF68, 0x9AFC, 0xEF69, 0x9B48, 0xEF6A, 0x9B9A, 0xEF6B, 0x9BA8,
+	0xEF6C, 0x9B9E, 0xEF6D, 0x9B9B, 0xEF6E, 0x9BA6, 0xEF6F, 0x9BA1,
+	0xEF70, 0x9BA5, 0xEF71, 0x9BA4, 0xEF72, 0x9B86, 0xEF73, 0x9BA2,
+	0xEF74, 0x9BA0, 0xEF75, 0x9BAF, 0xEF76, 0x9D33, 0xEF77, 0x9D41,
+	0xEF78, 0x9D67, 0xEF79, 0x9D36, 0xEF7A, 0x9D2E, 0xEF7B, 0x9D2F,
+	0xEF7C, 0x9D31, 0xEF7D, 0x9D38, 0xEF7E, 0x9D30, 0xEFA1, 0x9D45,
+	0xEFA2, 0x9D42, 0xEFA3, 0x9D43, 0xEFA4, 0x9D3E, 0xEFA5, 0x9D37,
+	0xEFA6, 0x9D40, 0xEFA7, 0x9D3D, 0xEFA8, 0x7FF5, 0xEFA9, 0x9D2D,
+	0xEFAA, 0x9E8A, 0xEFAB, 0x9E89, 0xEFAC, 0x9E8D, 0xEFAD, 0x9EB0,
+	0xEFAE, 0x9EC8, 0xEFAF, 0x9EDA, 0xEFB0, 0x9EFB, 0xEFB1, 0x9EFF,
+	0xEFB2, 0x9F24, 0xEFB3, 0x9F23, 0xEFB4, 0x9F22, 0xEFB5, 0x9F54,
+	0xEFB6, 0x9FA0, 0xEFB7, 0x5131, 0xEFB8, 0x512D, 0xEFB9, 0x512E,
+	0xEFBA, 0x5698, 0xEFBB, 0x569C, 0xEFBC, 0x5697, 0xEFBD, 0x569A,
+	0xEFBE, 0x569D, 0xEFBF, 0x5699, 0xEFC0, 0x5970, 0xEFC1, 0x5B3C,
+	0xEFC2, 0x5C69, 0xEFC3, 0x5C6A, 0xEFC4, 0x5DC0, 0xEFC5, 0x5E6D,
+	0xEFC6, 0x5E6E, 0xEFC7, 0x61D8, 0xEFC8, 0x61DF, 0xEFC9, 0x61ED,
+	0xEFCA, 0x61EE, 0xEFCB, 0x61F1, 0xEFCC, 0x61EA, 0xEFCD, 0x61F0,
+	0xEFCE, 0x61EB, 0xEFCF, 0x61D6, 0xEFD0, 0x61E9, 0xEFD1, 0x64FF,
+	0xEFD2, 0x6504, 0xEFD3, 0x64FD, 0xEFD4, 0x64F8, 0xEFD5, 0x6501,
+	0xEFD6, 0x6503, 0xEFD7, 0x64FC, 0xEFD8, 0x6594, 0xEFD9, 0x65DB,
+	0xEFDA, 0x66DA, 0xEFDB, 0x66DB, 0xEFDC, 0x66D8, 0xEFDD, 0x6AC5,
+	0xEFDE, 0x6AB9, 0xEFDF, 0x6ABD, 0xEFE0, 0x6AE1, 0xEFE1, 0x6AC6,
+	0xEFE2, 0x6ABA, 0xEFE3, 0x6AB6, 0xEFE4, 0x6AB7, 0xEFE5, 0x6AC7,
+	0xEFE6, 0x6AB4, 0xEFE7, 0x6AAD, 0xEFE8, 0x6B5E, 0xEFE9, 0x6BC9,
+	0xEFEA, 0x6C0B, 0xEFEB, 0x7007, 0xEFEC, 0x700C, 0xEFED, 0x700D,
+	0xEFEE, 0x7001, 0xEFEF, 0x7005, 0xEFF0, 0x7014, 0xEFF1, 0x700E,
+	0xEFF2, 0x6FFF, 0xEFF3, 0x7000, 0xEFF4, 0x6FFB, 0xEFF5, 0x7026,
+	0xEFF6, 0x6FFC, 0xEFF7, 0x6FF7, 0xEFF8, 0x700A, 0xEFF9, 0x7201,
+	0xEFFA, 0x71FF, 0xEFFB, 0x71F9, 0xEFFC, 0x7203, 0xEFFD, 0x71FD,
+	0xEFFE, 0x7376, 0xF040, 0x74B8, 0xF041, 0x74C0, 0xF042, 0x74B5,
+	0xF043, 0x74C1, 0xF044, 0x74BE, 0xF045, 0x74B6, 0xF046, 0x74BB,
+	0xF047, 0x74C2, 0xF048, 0x7514, 0xF049, 0x7513, 0xF04A, 0x765C,
+	0xF04B, 0x7664, 0xF04C, 0x7659, 0xF04D, 0x7650, 0xF04E, 0x7653,
+	0xF04F, 0x7657, 0xF050, 0x765A, 0xF051, 0x76A6, 0xF052, 0x76BD,
+	0xF053, 0x76EC, 0xF054, 0x77C2, 0xF055, 0x77BA, 0xF056, 0x78FF,
+	0xF057, 0x790C, 0xF058, 0x7913, 0xF059, 0x7914, 0xF05A, 0x7909,
+	0xF05B, 0x7910, 0xF05C, 0x7912, 0xF05D, 0x7911, 0xF05E, 0x79AD,
+	0xF05F, 0x79AC, 0xF060, 0x7A5F, 0xF061, 0x7C1C, 0xF062, 0x7C29,
+	0xF063, 0x7C19, 0xF064, 0x7C20, 0xF065, 0x7C1F, 0xF066, 0x7C2D,
+	0xF067, 0x7C1D, 0xF068, 0x7C26, 0xF069, 0x7C28, 0xF06A, 0x7C22,
+	0xF06B, 0x7C25, 0xF06C, 0x7C30, 0xF06D, 0x7E5C, 0xF06E, 0x7E50,
+	0xF06F, 0x7E56, 0xF070, 0x7E63, 0xF071, 0x7E58, 0xF072, 0x7E62,
+	0xF073, 0x7E5F, 0xF074, 0x7E51, 0xF075, 0x7E60, 0xF076, 0x7E57,
+	0xF077, 0x7E53, 0xF078, 0x7FB5, 0xF079, 0x7FB3, 0xF07A, 0x7FF7,
+	0xF07B, 0x7FF8, 0xF07C, 0x8075, 0xF07D, 0x81D1, 0xF07E, 0x81D2,
+	0xF0A1, 0x81D0, 0xF0A2, 0x825F, 0xF0A3, 0x825E, 0xF0A4, 0x85B4,
+	0xF0A5, 0x85C6, 0xF0A6, 0x85C0, 0xF0A7, 0x85C3, 0xF0A8, 0x85C2,
+	0xF0A9, 0x85B3, 0xF0AA, 0x85B5, 0xF0AB, 0x85BD, 0xF0AC, 0x85C7,
+	0xF0AD, 0x85C4, 0xF0AE, 0x85BF, 0xF0AF, 0x85CB, 0xF0B0, 0x85CE,
+	0xF0B1, 0x85C8, 0xF0B2, 0x85C5, 0xF0B3, 0x85B1, 0xF0B4, 0x85B6,
+	0xF0B5, 0x85D2, 0xF0B6, 0x8624, 0xF0B7, 0x85B8, 0xF0B8, 0x85B7,
+	0xF0B9, 0x85BE, 0xF0BA, 0x8669, 0xF0BB, 0x87E7, 0xF0BC, 0x87E6,
+	0xF0BD, 0x87E2, 0xF0BE, 0x87DB, 0xF0BF, 0x87EB, 0xF0C0, 0x87EA,
+	0xF0C1, 0x87E5, 0xF0C2, 0x87DF, 0xF0C3, 0x87F3, 0xF0C4, 0x87E4,
+	0xF0C5, 0x87D4, 0xF0C6, 0x87DC, 0xF0C7, 0x87D3, 0xF0C8, 0x87ED,
+	0xF0C9, 0x87D8, 0xF0CA, 0x87E3, 0xF0CB, 0x87A4, 0xF0CC, 0x87D7,
+	0xF0CD, 0x87D9, 0xF0CE, 0x8801, 0xF0CF, 0x87F4, 0xF0D0, 0x87E8,
+	0xF0D1, 0x87DD, 0xF0D2, 0x8953, 0xF0D3, 0x894B, 0xF0D4, 0x894F,
+	0xF0D5, 0x894C, 0xF0D6, 0x8946, 0xF0D7, 0x8950, 0xF0D8, 0x8951,
+	0xF0D9, 0x8949, 0xF0DA, 0x8B2A, 0xF0DB, 0x8B27, 0xF0DC, 0x8B23,
+	0xF0DD, 0x8B33, 0xF0DE, 0x8B30, 0xF0DF, 0x8B35, 0xF0E0, 0x8B47,
+	0xF0E1, 0x8B2F, 0xF0E2, 0x8B3C, 0xF0E3, 0x8B3E, 0xF0E4, 0x8B31,
+	0xF0E5, 0x8B25, 0xF0E6, 0x8B37, 0xF0E7, 0x8B26, 0xF0E8, 0x8B36,
+	0xF0E9, 0x8B2E, 0xF0EA, 0x8B24, 0xF0EB, 0x8B3B, 0xF0EC, 0x8B3D,
+	0xF0ED, 0x8B3A, 0xF0EE, 0x8C42, 0xF0EF, 0x8C75, 0xF0F0, 0x8C99,
+	0xF0F1, 0x8C98, 0xF0F2, 0x8C97, 0xF0F3, 0x8CFE, 0xF0F4, 0x8D04,
+	0xF0F5, 0x8D02, 0xF0F6, 0x8D00, 0xF0F7, 0x8E5C, 0xF0F8, 0x8E62,
+	0xF0F9, 0x8E60, 0xF0FA, 0x8E57, 0xF0FB, 0x8E56, 0xF0FC, 0x8E5E,
+	0xF0FD, 0x8E65, 0xF0FE, 0x8E67, 0xF140, 0x8E5B, 0xF141, 0x8E5A,
+	0xF142, 0x8E61, 0xF143, 0x8E5D, 0xF144, 0x8E69, 0xF145, 0x8E54,
+	0xF146, 0x8F46, 0xF147, 0x8F47, 0xF148, 0x8F48, 0xF149, 0x8F4B,
+	0xF14A, 0x9128, 0xF14B, 0x913A, 0xF14C, 0x913B, 0xF14D, 0x913E,
+	0xF14E, 0x91A8, 0xF14F, 0x91A5, 0xF150, 0x91A7, 0xF151, 0x91AF,
+	0xF152, 0x91AA, 0xF153, 0x93B5, 0xF154, 0x938C, 0xF155, 0x9392,
+	0xF156, 0x93B7, 0xF157, 0x939B, 0xF158, 0x939D, 0xF159, 0x9389,
+	0xF15A, 0x93A7, 0xF15B, 0x938E, 0xF15C, 0x93AA, 0xF15D, 0x939E,
+	0xF15E, 0x93A6, 0xF15F, 0x9395, 0xF160, 0x9388, 0xF161, 0x9399,
+	0xF162, 0x939F, 0xF163, 0x938D, 0xF164, 0x93B1, 0xF165, 0x9391,
+	0xF166, 0x93B2, 0xF167, 0x93A4, 0xF168, 0x93A8, 0xF169, 0x93B4,
+	0xF16A, 0x93A3, 0xF16B, 0x93A5, 0xF16C, 0x95D2, 0xF16D, 0x95D3,
+	0xF16E, 0x95D1, 0xF16F, 0x96B3, 0xF170, 0x96D7, 0xF171, 0x96DA,
+	0xF172, 0x5DC2, 0xF173, 0x96DF, 0xF174, 0x96D8, 0xF175, 0x96DD,
+	0xF176, 0x9723, 0xF177, 0x9722, 0xF178, 0x9725, 0xF179, 0x97AC,
+	0xF17A, 0x97AE, 0xF17B, 0x97A8, 0xF17C, 0x97AB, 0xF17D, 0x97A4,
+	0xF17E, 0x97AA, 0xF1A1, 0x97A2, 0xF1A2, 0x97A5, 0xF1A3, 0x97D7,
+	0xF1A4, 0x97D9, 0xF1A5, 0x97D6, 0xF1A6, 0x97D8, 0xF1A7, 0x97FA,
+	0xF1A8, 0x9850, 0xF1A9, 0x9851, 0xF1AA, 0x9852, 0xF1AB, 0x98B8,
+	0xF1AC, 0x9941, 0xF1AD, 0x993C, 0xF1AE, 0x993A, 0xF1AF, 0x9A0F,
+	0xF1B0, 0x9A0B, 0xF1B1, 0x9A09, 0xF1B2, 0x9A0D, 0xF1B3, 0x9A04,
+	0xF1B4, 0x9A11, 0xF1B5, 0x9A0A, 0xF1B6, 0x9A05, 0xF1B7, 0x9A07,
+	0xF1B8, 0x9A06, 0xF1B9, 0x9AC0, 0xF1BA, 0x9ADC, 0xF1BB, 0x9B08,
+	0xF1BC, 0x9B04, 0xF1BD, 0x9B05, 0xF1BE, 0x9B29, 0xF1BF, 0x9B35,
+	0xF1C0, 0x9B4A, 0xF1C1, 0x9B4C, 0xF1C2, 0x9B4B, 0xF1C3, 0x9BC7,
+	0xF1C4, 0x9BC6, 0xF1C5, 0x9BC3, 0xF1C6, 0x9BBF, 0xF1C7, 0x9BC1,
+	0xF1C8, 0x9BB5, 0xF1C9, 0x9BB8, 0xF1CA, 0x9BD3, 0xF1CB, 0x9BB6,
+	0xF1CC, 0x9BC4, 0xF1CD, 0x9BB9, 0xF1CE, 0x9BBD, 0xF1CF, 0x9D5C,
+	0xF1D0, 0x9D53, 0xF1D1, 0x9D4F, 0xF1D2, 0x9D4A, 0xF1D3, 0x9D5B,
+	0xF1D4, 0x9D4B, 0xF1D5, 0x9D59, 0xF1D6, 0x9D56, 0xF1D7, 0x9D4C,
+	0xF1D8, 0x9D57, 0xF1D9, 0x9D52, 0xF1DA, 0x9D54, 0xF1DB, 0x9D5F,
+	0xF1DC, 0x9D58, 0xF1DD, 0x9D5A, 0xF1DE, 0x9E8E, 0xF1DF, 0x9E8C,
+	0xF1E0, 0x9EDF, 0xF1E1, 0x9F01, 0xF1E2, 0x9F00, 0xF1E3, 0x9F16,
+	0xF1E4, 0x9F25, 0xF1E5, 0x9F2B, 0xF1E6, 0x9F2A, 0xF1E7, 0x9F29,
+	0xF1E8, 0x9F28, 0xF1E9, 0x9F4C, 0xF1EA, 0x9F55, 0xF1EB, 0x5134,
+	0xF1EC, 0x5135, 0xF1ED, 0x5296, 0xF1EE, 0x52F7, 0xF1EF, 0x53B4,
+	0xF1F0, 0x56AB, 0xF1F1, 0x56AD, 0xF1F2, 0x56A6, 0xF1F3, 0x56A7,
+	0xF1F4, 0x56AA, 0xF1F5, 0x56AC, 0xF1F6, 0x58DA, 0xF1F7, 0x58DD,
+	0xF1F8, 0x58DB, 0xF1F9, 0x5912, 0xF1FA, 0x5B3D, 0xF1FB, 0x5B3E,
+	0xF1FC, 0x5B3F, 0xF1FD, 0x5DC3, 0xF1FE, 0x5E70, 0xF240, 0x5FBF,
+	0xF241, 0x61FB, 0xF242, 0x6507, 0xF243, 0x6510, 0xF244, 0x650D,
+	0xF245, 0x6509, 0xF246, 0x650C, 0xF247, 0x650E, 0xF248, 0x6584,
+	0xF249, 0x65DE, 0xF24A, 0x65DD, 0xF24B, 0x66DE, 0xF24C, 0x6AE7,
+	0xF24D, 0x6AE0, 0xF24E, 0x6ACC, 0xF24F, 0x6AD1, 0xF250, 0x6AD9,
+	0xF251, 0x6ACB, 0xF252, 0x6ADF, 0xF253, 0x6ADC, 0xF254, 0x6AD0,
+	0xF255, 0x6AEB, 0xF256, 0x6ACF, 0xF257, 0x6ACD, 0xF258, 0x6ADE,
+	0xF259, 0x6B60, 0xF25A, 0x6BB0, 0xF25B, 0x6C0C, 0xF25C, 0x7019,
+	0xF25D, 0x7027, 0xF25E, 0x7020, 0xF25F, 0x7016, 0xF260, 0x702B,
+	0xF261, 0x7021, 0xF262, 0x7022, 0xF263, 0x7023, 0xF264, 0x7029,
+	0xF265, 0x7017, 0xF266, 0x7024, 0xF267, 0x701C, 0xF268, 0x702A,
+	0xF269, 0x720C, 0xF26A, 0x720A, 0xF26B, 0x7207, 0xF26C, 0x7202,
+	0xF26D, 0x7205, 0xF26E, 0x72A5, 0xF26F, 0x72A6, 0xF270, 0x72A4,
+	0xF271, 0x72A3, 0xF272, 0x72A1, 0xF273, 0x74CB, 0xF274, 0x74C5,
+	0xF275, 0x74B7, 0xF276, 0x74C3, 0xF277, 0x7516, 0xF278, 0x7660,
+	0xF279, 0x77C9, 0xF27A, 0x77CA, 0xF27B, 0x77C4, 0xF27C, 0x77F1,
+	0xF27D, 0x791D, 0xF27E, 0x791B, 0xF2A1, 0x7921, 0xF2A2, 0x791C,
+	0xF2A3, 0x7917, 0xF2A4, 0x791E, 0xF2A5, 0x79B0, 0xF2A6, 0x7A67,
+	0xF2A7, 0x7A68, 0xF2A8, 0x7C33, 0xF2A9, 0x7C3C, 0xF2AA, 0x7C39,
+	0xF2AB, 0x7C2C, 0xF2AC, 0x7C3B, 0xF2AD, 0x7CEC, 0xF2AE, 0x7CEA,
+	0xF2AF, 0x7E76, 0xF2B0, 0x7E75, 0xF2B1, 0x7E78, 0xF2B2, 0x7E70,
+	0xF2B3, 0x7E77, 0xF2B4, 0x7E6F, 0xF2B5, 0x7E7A, 0xF2B6, 0x7E72,
+	0xF2B7, 0x7E74, 0xF2B8, 0x7E68, 0xF2B9, 0x7F4B, 0xF2BA, 0x7F4A,
+	0xF2BB, 0x7F83, 0xF2BC, 0x7F86, 0xF2BD, 0x7FB7, 0xF2BE, 0x7FFD,
+	0xF2BF, 0x7FFE, 0xF2C0, 0x8078, 0xF2C1, 0x81D7, 0xF2C2, 0x81D5,
+	0xF2C3, 0x8264, 0xF2C4, 0x8261, 0xF2C5, 0x8263, 0xF2C6, 0x85EB,
+	0xF2C7, 0x85F1, 0xF2C8, 0x85ED, 0xF2C9, 0x85D9, 0xF2CA, 0x85E1,
+	0xF2CB, 0x85E8, 0xF2CC, 0x85DA, 0xF2CD, 0x85D7, 0xF2CE, 0x85EC,
+	0xF2CF, 0x85F2, 0xF2D0, 0x85F8, 0xF2D1, 0x85D8, 0xF2D2, 0x85DF,
+	0xF2D3, 0x85E3, 0xF2D4, 0x85DC, 0xF2D5, 0x85D1, 0xF2D6, 0x85F0,
+	0xF2D7, 0x85E6, 0xF2D8, 0x85EF, 0xF2D9, 0x85DE, 0xF2DA, 0x85E2,
+	0xF2DB, 0x8800, 0xF2DC, 0x87FA, 0xF2DD, 0x8803, 0xF2DE, 0x87F6,
+	0xF2DF, 0x87F7, 0xF2E0, 0x8809, 0xF2E1, 0x880C, 0xF2E2, 0x880B,
+	0xF2E3, 0x8806, 0xF2E4, 0x87FC, 0xF2E5, 0x8808, 0xF2E6, 0x87FF,
+	0xF2E7, 0x880A, 0xF2E8, 0x8802, 0xF2E9, 0x8962, 0xF2EA, 0x895A,
+	0xF2EB, 0x895B, 0xF2EC, 0x8957, 0xF2ED, 0x8961, 0xF2EE, 0x895C,
+	0xF2EF, 0x8958, 0xF2F0, 0x895D, 0xF2F1, 0x8959, 0xF2F2, 0x8988,
+	0xF2F3, 0x89B7, 0xF2F4, 0x89B6, 0xF2F5, 0x89F6, 0xF2F6, 0x8B50,
+	0xF2F7, 0x8B48, 0xF2F8, 0x8B4A, 0xF2F9, 0x8B40, 0xF2FA, 0x8B53,
+	0xF2FB, 0x8B56, 0xF2FC, 0x8B54, 0xF2FD, 0x8B4B, 0xF2FE, 0x8B55,
+	0xF340, 0x8B51, 0xF341, 0x8B42, 0xF342, 0x8B52, 0xF343, 0x8B57,
+	0xF344, 0x8C43, 0xF345, 0x8C77, 0xF346, 0x8C76, 0xF347, 0x8C9A,
+	0xF348, 0x8D06, 0xF349, 0x8D07, 0xF34A, 0x8D09, 0xF34B, 0x8DAC,
+	0xF34C, 0x8DAA, 0xF34D, 0x8DAD, 0xF34E, 0x8DAB, 0xF34F, 0x8E6D,
+	0xF350, 0x8E78, 0xF351, 0x8E73, 0xF352, 0x8E6A, 0xF353, 0x8E6F,
+	0xF354, 0x8E7B, 0xF355, 0x8EC2, 0xF356, 0x8F52, 0xF357, 0x8F51,
+	0xF358, 0x8F4F, 0xF359, 0x8F50, 0xF35A, 0x8F53, 0xF35B, 0x8FB4,
+	0xF35C, 0x9140, 0xF35D, 0x913F, 0xF35E, 0x91B0, 0xF35F, 0x91AD,
+	0xF360, 0x93DE, 0xF361, 0x93C7, 0xF362, 0x93CF, 0xF363, 0x93C2,
+	0xF364, 0x93DA, 0xF365, 0x93D0, 0xF366, 0x93F9, 0xF367, 0x93EC,
+	0xF368, 0x93CC, 0xF369, 0x93D9, 0xF36A, 0x93A9, 0xF36B, 0x93E6,
+	0xF36C, 0x93CA, 0xF36D, 0x93D4, 0xF36E, 0x93EE, 0xF36F, 0x93E3,
+	0xF370, 0x93D5, 0xF371, 0x93C4, 0xF372, 0x93CE, 0xF373, 0x93C0,
+	0xF374, 0x93D2, 0xF375, 0x93E7, 0xF376, 0x957D, 0xF377, 0x95DA,
+	0xF378, 0x95DB, 0xF379, 0x96E1, 0xF37A, 0x9729, 0xF37B, 0x972B,
+	0xF37C, 0x972C, 0xF37D, 0x9728, 0xF37E, 0x9726, 0xF3A1, 0x97B3,
+	0xF3A2, 0x97B7, 0xF3A3, 0x97B6, 0xF3A4, 0x97DD, 0xF3A5, 0x97DE,
+	0xF3A6, 0x97DF, 0xF3A7, 0x985C, 0xF3A8, 0x9859, 0xF3A9, 0x985D,
+	0xF3AA, 0x9857, 0xF3AB, 0x98BF, 0xF3AC, 0x98BD, 0xF3AD, 0x98BB,
+	0xF3AE, 0x98BE, 0xF3AF, 0x9948, 0xF3B0, 0x9947, 0xF3B1, 0x9943,
+	0xF3B2, 0x99A6, 0xF3B3, 0x99A7, 0xF3B4, 0x9A1A, 0xF3B5, 0x9A15,
+	0xF3B6, 0x9A25, 0xF3B7, 0x9A1D, 0xF3B8, 0x9A24, 0xF3B9, 0x9A1B,
+	0xF3BA, 0x9A22, 0xF3BB, 0x9A20, 0xF3BC, 0x9A27, 0xF3BD, 0x9A23,
+	0xF3BE, 0x9A1E, 0xF3BF, 0x9A1C, 0xF3C0, 0x9A14, 0xF3C1, 0x9AC2,
+	0xF3C2, 0x9B0B, 0xF3C3, 0x9B0A, 0xF3C4, 0x9B0E, 0xF3C5, 0x9B0C,
+	0xF3C6, 0x9B37, 0xF3C7, 0x9BEA, 0xF3C8, 0x9BEB, 0xF3C9, 0x9BE0,
+	0xF3CA, 0x9BDE, 0xF3CB, 0x9BE4, 0xF3CC, 0x9BE6, 0xF3CD, 0x9BE2,
+	0xF3CE, 0x9BF0, 0xF3CF, 0x9BD4, 0xF3D0, 0x9BD7, 0xF3D1, 0x9BEC,
+	0xF3D2, 0x9BDC, 0xF3D3, 0x9BD9, 0xF3D4, 0x9BE5, 0xF3D5, 0x9BD5,
+	0xF3D6, 0x9BE1, 0xF3D7, 0x9BDA, 0xF3D8, 0x9D77, 0xF3D9, 0x9D81,
+	0xF3DA, 0x9D8A, 0xF3DB, 0x9D84, 0xF3DC, 0x9D88, 0xF3DD, 0x9D71,
+	0xF3DE, 0x9D80, 0xF3DF, 0x9D78, 0xF3E0, 0x9D86, 0xF3E1, 0x9D8B,
+	0xF3E2, 0x9D8C, 0xF3E3, 0x9D7D, 0xF3E4, 0x9D6B, 0xF3E5, 0x9D74,
+	0xF3E6, 0x9D75, 0xF3E7, 0x9D70, 0xF3E8, 0x9D69, 0xF3E9, 0x9D85,
+	0xF3EA, 0x9D73, 0xF3EB, 0x9D7B, 0xF3EC, 0x9D82, 0xF3ED, 0x9D6F,
+	0xF3EE, 0x9D79, 0xF3EF, 0x9D7F, 0xF3F0, 0x9D87, 0xF3F1, 0x9D68,
+	0xF3F2, 0x9E94, 0xF3F3, 0x9E91, 0xF3F4, 0x9EC0, 0xF3F5, 0x9EFC,
+	0xF3F6, 0x9F2D, 0xF3F7, 0x9F40, 0xF3F8, 0x9F41, 0xF3F9, 0x9F4D,
+	0xF3FA, 0x9F56, 0xF3FB, 0x9F57, 0xF3FC, 0x9F58, 0xF3FD, 0x5337,
+	0xF3FE, 0x56B2, 0xF440, 0x56B5, 0xF441, 0x56B3, 0xF442, 0x58E3,
+	0xF443, 0x5B45, 0xF444, 0x5DC6, 0xF445, 0x5DC7, 0xF446, 0x5EEE,
+	0xF447, 0x5EEF, 0xF448, 0x5FC0, 0xF449, 0x5FC1, 0xF44A, 0x61F9,
+	0xF44B, 0x6517, 0xF44C, 0x6516, 0xF44D, 0x6515, 0xF44E, 0x6513,
+	0xF44F, 0x65DF, 0xF450, 0x66E8, 0xF451, 0x66E3, 0xF452, 0x66E4,
+	0xF453, 0x6AF3, 0xF454, 0x6AF0, 0xF455, 0x6AEA, 0xF456, 0x6AE8,
+	0xF457, 0x6AF9, 0xF458, 0x6AF1, 0xF459, 0x6AEE, 0xF45A, 0x6AEF,
+	0xF45B, 0x703C, 0xF45C, 0x7035, 0xF45D, 0x702F, 0xF45E, 0x7037,
+	0xF45F, 0x7034, 0xF460, 0x7031, 0xF461, 0x7042, 0xF462, 0x7038,
+	0xF463, 0x703F, 0xF464, 0x703A, 0xF465, 0x7039, 0xF466, 0x7040,
+	0xF467, 0x703B, 0xF468, 0x7033, 0xF469, 0x7041, 0xF46A, 0x7213,
+	0xF46B, 0x7214, 0xF46C, 0x72A8, 0xF46D, 0x737D, 0xF46E, 0x737C,
+	0xF46F, 0x74BA, 0xF470, 0x76AB, 0xF471, 0x76AA, 0xF472, 0x76BE,
+	0xF473, 0x76ED, 0xF474, 0x77CC, 0xF475, 0x77CE, 0xF476, 0x77CF,
+	0xF477, 0x77CD, 0xF478, 0x77F2, 0xF479, 0x7925, 0xF47A, 0x7923,
+	0xF47B, 0x7927, 0xF47C, 0x7928, 0xF47D, 0x7924, 0xF47E, 0x7929,
+	0xF4A1, 0x79B2, 0xF4A2, 0x7A6E, 0xF4A3, 0x7A6C, 0xF4A4, 0x7A6D,
+	0xF4A5, 0x7AF7, 0xF4A6, 0x7C49, 0xF4A7, 0x7C48, 0xF4A8, 0x7C4A,
+	0xF4A9, 0x7C47, 0xF4AA, 0x7C45, 0xF4AB, 0x7CEE, 0xF4AC, 0x7E7B,
+	0xF4AD, 0x7E7E, 0xF4AE, 0x7E81, 0xF4AF, 0x7E80, 0xF4B0, 0x7FBA,
+	0xF4B1, 0x7FFF, 0xF4B2, 0x8079, 0xF4B3, 0x81DB, 0xF4B4, 0x81D9,
+	0xF4B5, 0x820B, 0xF4B6, 0x8268, 0xF4B7, 0x8269, 0xF4B8, 0x8622,
+	0xF4B9, 0x85FF, 0xF4BA, 0x8601, 0xF4BB, 0x85FE, 0xF4BC, 0x861B,
+	0xF4BD, 0x8600, 0xF4BE, 0x85F6, 0xF4BF, 0x8604, 0xF4C0, 0x8609,
+	0xF4C1, 0x8605, 0xF4C2, 0x860C, 0xF4C3, 0x85FD, 0xF4C4, 0x8819,
+	0xF4C5, 0x8810, 0xF4C6, 0x8811, 0xF4C7, 0x8817, 0xF4C8, 0x8813,
+	0xF4C9, 0x8816, 0xF4CA, 0x8963, 0xF4CB, 0x8966, 0xF4CC, 0x89B9,
+	0xF4CD, 0x89F7, 0xF4CE, 0x8B60, 0xF4CF, 0x8B6A, 0xF4D0, 0x8B5D,
+	0xF4D1, 0x8B68, 0xF4D2, 0x8B63, 0xF4D3, 0x8B65, 0xF4D4, 0x8B67,
+	0xF4D5, 0x8B6D, 0xF4D6, 0x8DAE, 0xF4D7, 0x8E86, 0xF4D8, 0x8E88,
+	0xF4D9, 0x8E84, 0xF4DA, 0x8F59, 0xF4DB, 0x8F56, 0xF4DC, 0x8F57,
+	0xF4DD, 0x8F55, 0xF4DE, 0x8F58, 0xF4DF, 0x8F5A, 0xF4E0, 0x908D,
+	0xF4E1, 0x9143, 0xF4E2, 0x9141, 0xF4E3, 0x91B7, 0xF4E4, 0x91B5,
+	0xF4E5, 0x91B2, 0xF4E6, 0x91B3, 0xF4E7, 0x940B, 0xF4E8, 0x9413,
+	0xF4E9, 0x93FB, 0xF4EA, 0x9420, 0xF4EB, 0x940F, 0xF4EC, 0x9414,
+	0xF4ED, 0x93FE, 0xF4EE, 0x9415, 0xF4EF, 0x9410, 0xF4F0, 0x9428,
+	0xF4F1, 0x9419, 0xF4F2, 0x940D, 0xF4F3, 0x93F5, 0xF4F4, 0x9400,
+	0xF4F5, 0x93F7, 0xF4F6, 0x9407, 0xF4F7, 0x940E, 0xF4F8, 0x9416,
+	0xF4F9, 0x9412, 0xF4FA, 0x93FA, 0xF4FB, 0x9409, 0xF4FC, 0x93F8,
+	0xF4FD, 0x940A, 0xF4FE, 0x93FF, 0xF540, 0x93FC, 0xF541, 0x940C,
+	0xF542, 0x93F6, 0xF543, 0x9411, 0xF544, 0x9406, 0xF545, 0x95DE,
+	0xF546, 0x95E0, 0xF547, 0x95DF, 0xF548, 0x972E, 0xF549, 0x972F,
+	0xF54A, 0x97B9, 0xF54B, 0x97BB, 0xF54C, 0x97FD, 0xF54D, 0x97FE,
+	0xF54E, 0x9860, 0xF54F, 0x9862, 0xF550, 0x9863, 0xF551, 0x985F,
+	0xF552, 0x98C1, 0xF553, 0x98C2, 0xF554, 0x9950, 0xF555, 0x994E,
+	0xF556, 0x9959, 0xF557, 0x994C, 0xF558, 0x994B, 0xF559, 0x9953,
+	0xF55A, 0x9A32, 0xF55B, 0x9A34, 0xF55C, 0x9A31, 0xF55D, 0x9A2C,
+	0xF55E, 0x9A2A, 0xF55F, 0x9A36, 0xF560, 0x9A29, 0xF561, 0x9A2E,
+	0xF562, 0x9A38, 0xF563, 0x9A2D, 0xF564, 0x9AC7, 0xF565, 0x9ACA,
+	0xF566, 0x9AC6, 0xF567, 0x9B10, 0xF568, 0x9B12, 0xF569, 0x9B11,
+	0xF56A, 0x9C0B, 0xF56B, 0x9C08, 0xF56C, 0x9BF7, 0xF56D, 0x9C05,
+	0xF56E, 0x9C12, 0xF56F, 0x9BF8, 0xF570, 0x9C40, 0xF571, 0x9C07,
+	0xF572, 0x9C0E, 0xF573, 0x9C06, 0xF574, 0x9C17, 0xF575, 0x9C14,
+	0xF576, 0x9C09, 0xF577, 0x9D9F, 0xF578, 0x9D99, 0xF579, 0x9DA4,
+	0xF57A, 0x9D9D, 0xF57B, 0x9D92, 0xF57C, 0x9D98, 0xF57D, 0x9D90,
+	0xF57E, 0x9D9B, 0xF5A1, 0x9DA0, 0xF5A2, 0x9D94, 0xF5A3, 0x9D9C,
+	0xF5A4, 0x9DAA, 0xF5A5, 0x9D97, 0xF5A6, 0x9DA1, 0xF5A7, 0x9D9A,
+	0xF5A8, 0x9DA2, 0xF5A9, 0x9DA8, 0xF5AA, 0x9D9E, 0xF5AB, 0x9DA3,
+	0xF5AC, 0x9DBF, 0xF5AD, 0x9DA9, 0xF5AE, 0x9D96, 0xF5AF, 0x9DA6,
+	0xF5B0, 0x9DA7, 0xF5B1, 0x9E99, 0xF5B2, 0x9E9B, 0xF5B3, 0x9E9A,
+	0xF5B4, 0x9EE5, 0xF5B5, 0x9EE4, 0xF5B6, 0x9EE7, 0xF5B7, 0x9EE6,
+	0xF5B8, 0x9F30, 0xF5B9, 0x9F2E, 0xF5BA, 0x9F5B, 0xF5BB, 0x9F60,
+	0xF5BC, 0x9F5E, 0xF5BD, 0x9F5D, 0xF5BE, 0x9F59, 0xF5BF, 0x9F91,
+	0xF5C0, 0x513A, 0xF5C1, 0x5139, 0xF5C2, 0x5298, 0xF5C3, 0x5297,
+	0xF5C4, 0x56C3, 0xF5C5, 0x56BD, 0xF5C6, 0x56BE, 0xF5C7, 0x5B48,
+	0xF5C8, 0x5B47, 0xF5C9, 0x5DCB, 0xF5CA, 0x5DCF, 0xF5CB, 0x5EF1,
+	0xF5CC, 0x61FD, 0xF5CD, 0x651B, 0xF5CE, 0x6B02, 0xF5CF, 0x6AFC,
+	0xF5D0, 0x6B03, 0xF5D1, 0x6AF8, 0xF5D2, 0x6B00, 0xF5D3, 0x7043,
+	0xF5D4, 0x7044, 0xF5D5, 0x704A, 0xF5D6, 0x7048, 0xF5D7, 0x7049,
+	0xF5D8, 0x7045, 0xF5D9, 0x7046, 0xF5DA, 0x721D, 0xF5DB, 0x721A,
+	0xF5DC, 0x7219, 0xF5DD, 0x737E, 0xF5DE, 0x7517, 0xF5DF, 0x766A,
+	0xF5E0, 0x77D0, 0xF5E1, 0x792D, 0xF5E2, 0x7931, 0xF5E3, 0x792F,
+	0xF5E4, 0x7C54, 0xF5E5, 0x7C53, 0xF5E6, 0x7CF2, 0xF5E7, 0x7E8A,
+	0xF5E8, 0x7E87, 0xF5E9, 0x7E88, 0xF5EA, 0x7E8B, 0xF5EB, 0x7E86,
+	0xF5EC, 0x7E8D, 0xF5ED, 0x7F4D, 0xF5EE, 0x7FBB, 0xF5EF, 0x8030,
+	0xF5F0, 0x81DD, 0xF5F1, 0x8618, 0xF5F2, 0x862A, 0xF5F3, 0x8626,
+	0xF5F4, 0x861F, 0xF5F5, 0x8623, 0xF5F6, 0x861C, 0xF5F7, 0x8619,
+	0xF5F8, 0x8627, 0xF5F9, 0x862E, 0xF5FA, 0x8621, 0xF5FB, 0x8620,
+	0xF5FC, 0x8629, 0xF5FD, 0x861E, 0xF5FE, 0x8625, 0xF640, 0x8829,
+	0xF641, 0x881D, 0xF642, 0x881B, 0xF643, 0x8820, 0xF644, 0x8824,
+	0xF645, 0x881C, 0xF646, 0x882B, 0xF647, 0x884A, 0xF648, 0x896D,
+	0xF649, 0x8969, 0xF64A, 0x896E, 0xF64B, 0x896B, 0xF64C, 0x89FA,
+	0xF64D, 0x8B79, 0xF64E, 0x8B78, 0xF64F, 0x8B45, 0xF650, 0x8B7A,
+	0xF651, 0x8B7B, 0xF652, 0x8D10, 0xF653, 0x8D14, 0xF654, 0x8DAF,
+	0xF655, 0x8E8E, 0xF656, 0x8E8C, 0xF657, 0x8F5E, 0xF658, 0x8F5B,
+	0xF659, 0x8F5D, 0xF65A, 0x9146, 0xF65B, 0x9144, 0xF65C, 0x9145,
+	0xF65D, 0x91B9, 0xF65E, 0x943F, 0xF65F, 0x943B, 0xF660, 0x9436,
+	0xF661, 0x9429, 0xF662, 0x943D, 0xF663, 0x943C, 0xF664, 0x9430,
+	0xF665, 0x9439, 0xF666, 0x942A, 0xF667, 0x9437, 0xF668, 0x942C,
+	0xF669, 0x9440, 0xF66A, 0x9431, 0xF66B, 0x95E5, 0xF66C, 0x95E4,
+	0xF66D, 0x95E3, 0xF66E, 0x9735, 0xF66F, 0x973A, 0xF670, 0x97BF,
+	0xF671, 0x97E1, 0xF672, 0x9864, 0xF673, 0x98C9, 0xF674, 0x98C6,
+	0xF675, 0x98C0, 0xF676, 0x9958, 0xF677, 0x9956, 0xF678, 0x9A39,
+	0xF679, 0x9A3D, 0xF67A, 0x9A46, 0xF67B, 0x9A44, 0xF67C, 0x9A42,
+	0xF67D, 0x9A41, 0xF67E, 0x9A3A, 0xF6A1, 0x9A3F, 0xF6A2, 0x9ACD,
+	0xF6A3, 0x9B15, 0xF6A4, 0x9B17, 0xF6A5, 0x9B18, 0xF6A6, 0x9B16,
+	0xF6A7, 0x9B3A, 0xF6A8, 0x9B52, 0xF6A9, 0x9C2B, 0xF6AA, 0x9C1D,
+	0xF6AB, 0x9C1C, 0xF6AC, 0x9C2C, 0xF6AD, 0x9C23, 0xF6AE, 0x9C28,
+	0xF6AF, 0x9C29, 0xF6B0, 0x9C24, 0xF6B1, 0x9C21, 0xF6B2, 0x9DB7,
+	0xF6B3, 0x9DB6, 0xF6B4, 0x9DBC, 0xF6B5, 0x9DC1, 0xF6B6, 0x9DC7,
+	0xF6B7, 0x9DCA, 0xF6B8, 0x9DCF, 0xF6B9, 0x9DBE, 0xF6BA, 0x9DC5,
+	0xF6BB, 0x9DC3, 0xF6BC, 0x9DBB, 0xF6BD, 0x9DB5, 0xF6BE, 0x9DCE,
+	0xF6BF, 0x9DB9, 0xF6C0, 0x9DBA, 0xF6C1, 0x9DAC, 0xF6C2, 0x9DC8,
+	0xF6C3, 0x9DB1, 0xF6C4, 0x9DAD, 0xF6C5, 0x9DCC, 0xF6C6, 0x9DB3,
+	0xF6C7, 0x9DCD, 0xF6C8, 0x9DB2, 0xF6C9, 0x9E7A, 0xF6CA, 0x9E9C,
+	0xF6CB, 0x9EEB, 0xF6CC, 0x9EEE, 0xF6CD, 0x9EED, 0xF6CE, 0x9F1B,
+	0xF6CF, 0x9F18, 0xF6D0, 0x9F1A, 0xF6D1, 0x9F31, 0xF6D2, 0x9F4E,
+	0xF6D3, 0x9F65, 0xF6D4, 0x9F64, 0xF6D5, 0x9F92, 0xF6D6, 0x4EB9,
+	0xF6D7, 0x56C6, 0xF6D8, 0x56C5, 0xF6D9, 0x56CB, 0xF6DA, 0x5971,
+	0xF6DB, 0x5B4B, 0xF6DC, 0x5B4C, 0xF6DD, 0x5DD5, 0xF6DE, 0x5DD1,
+	0xF6DF, 0x5EF2, 0xF6E0, 0x6521, 0xF6E1, 0x6520, 0xF6E2, 0x6526,
+	0xF6E3, 0x6522, 0xF6E4, 0x6B0B, 0xF6E5, 0x6B08, 0xF6E6, 0x6B09,
+	0xF6E7, 0x6C0D, 0xF6E8, 0x7055, 0xF6E9, 0x7056, 0xF6EA, 0x7057,
+	0xF6EB, 0x7052, 0xF6EC, 0x721E, 0xF6ED, 0x721F, 0xF6EE, 0x72A9,
+	0xF6EF, 0x737F, 0xF6F0, 0x74D8, 0xF6F1, 0x74D5, 0xF6F2, 0x74D9,
+	0xF6F3, 0x74D7, 0xF6F4, 0x766D, 0xF6F5, 0x76AD, 0xF6F6, 0x7935,
+	0xF6F7, 0x79B4, 0xF6F8, 0x7A70, 0xF6F9, 0x7A71, 0xF6FA, 0x7C57,
+	0xF6FB, 0x7C5C, 0xF6FC, 0x7C59, 0xF6FD, 0x7C5B, 0xF6FE, 0x7C5A,
+	0xF740, 0x7CF4, 0xF741, 0x7CF1, 0xF742, 0x7E91, 0xF743, 0x7F4F,
+	0xF744, 0x7F87, 0xF745, 0x81DE, 0xF746, 0x826B, 0xF747, 0x8634,
+	0xF748, 0x8635, 0xF749, 0x8633, 0xF74A, 0x862C, 0xF74B, 0x8632,
+	0xF74C, 0x8636, 0xF74D, 0x882C, 0xF74E, 0x8828, 0xF74F, 0x8826,
+	0xF750, 0x882A, 0xF751, 0x8825, 0xF752, 0x8971, 0xF753, 0x89BF,
+	0xF754, 0x89BE, 0xF755, 0x89FB, 0xF756, 0x8B7E, 0xF757, 0x8B84,
+	0xF758, 0x8B82, 0xF759, 0x8B86, 0xF75A, 0x8B85, 0xF75B, 0x8B7F,
+	0xF75C, 0x8D15, 0xF75D, 0x8E95, 0xF75E, 0x8E94, 0xF75F, 0x8E9A,
+	0xF760, 0x8E92, 0xF761, 0x8E90, 0xF762, 0x8E96, 0xF763, 0x8E97,
+	0xF764, 0x8F60, 0xF765, 0x8F62, 0xF766, 0x9147, 0xF767, 0x944C,
+	0xF768, 0x9450, 0xF769, 0x944A, 0xF76A, 0x944B, 0xF76B, 0x944F,
+	0xF76C, 0x9447, 0xF76D, 0x9445, 0xF76E, 0x9448, 0xF76F, 0x9449,
+	0xF770, 0x9446, 0xF771, 0x973F, 0xF772, 0x97E3, 0xF773, 0x986A,
+	0xF774, 0x9869, 0xF775, 0x98CB, 0xF776, 0x9954, 0xF777, 0x995B,
+	0xF778, 0x9A4E, 0xF779, 0x9A53, 0xF77A, 0x9A54, 0xF77B, 0x9A4C,
+	0xF77C, 0x9A4F, 0xF77D, 0x9A48, 0xF77E, 0x9A4A, 0xF7A1, 0x9A49,
+	0xF7A2, 0x9A52, 0xF7A3, 0x9A50, 0xF7A4, 0x9AD0, 0xF7A5, 0x9B19,
+	0xF7A6, 0x9B2B, 0xF7A7, 0x9B3B, 0xF7A8, 0x9B56, 0xF7A9, 0x9B55,
+	0xF7AA, 0x9C46, 0xF7AB, 0x9C48, 0xF7AC, 0x9C3F, 0xF7AD, 0x9C44,
+	0xF7AE, 0x9C39, 0xF7AF, 0x9C33, 0xF7B0, 0x9C41, 0xF7B1, 0x9C3C,
+	0xF7B2, 0x9C37, 0xF7B3, 0x9C34, 0xF7B4, 0x9C32, 0xF7B5, 0x9C3D,
+	0xF7B6, 0x9C36, 0xF7B7, 0x9DDB, 0xF7B8, 0x9DD2, 0xF7B9, 0x9DDE,
+	0xF7BA, 0x9DDA, 0xF7BB, 0x9DCB, 0xF7BC, 0x9DD0, 0xF7BD, 0x9DDC,
+	0xF7BE, 0x9DD1, 0xF7BF, 0x9DDF, 0xF7C0, 0x9DE9, 0xF7C1, 0x9DD9,
+	0xF7C2, 0x9DD8, 0xF7C3, 0x9DD6, 0xF7C4, 0x9DF5, 0xF7C5, 0x9DD5,
+	0xF7C6, 0x9DDD, 0xF7C7, 0x9EB6, 0xF7C8, 0x9EF0, 0xF7C9, 0x9F35,
+	0xF7CA, 0x9F33, 0xF7CB, 0x9F32, 0xF7CC, 0x9F42, 0xF7CD, 0x9F6B,
+	0xF7CE, 0x9F95, 0xF7CF, 0x9FA2, 0xF7D0, 0x513D, 0xF7D1, 0x5299,
+	0xF7D2, 0x58E8, 0xF7D3, 0x58E7, 0xF7D4, 0x5972, 0xF7D5, 0x5B4D,
+	0xF7D6, 0x5DD8, 0xF7D7, 0x882F, 0xF7D8, 0x5F4F, 0xF7D9, 0x6201,
+	0xF7DA, 0x6203, 0xF7DB, 0x6204, 0xF7DC, 0x6529, 0xF7DD, 0x6525,
+	0xF7DE, 0x6596, 0xF7DF, 0x66EB, 0xF7E0, 0x6B11, 0xF7E1, 0x6B12,
+	0xF7E2, 0x6B0F, 0xF7E3, 0x6BCA, 0xF7E4, 0x705B, 0xF7E5, 0x705A,
+	0xF7E6, 0x7222, 0xF7E7, 0x7382, 0xF7E8, 0x7381, 0xF7E9, 0x7383,
+	0xF7EA, 0x7670, 0xF7EB, 0x77D4, 0xF7EC, 0x7C67, 0xF7ED, 0x7C66,
+	0xF7EE, 0x7E95, 0xF7EF, 0x826C, 0xF7F0, 0x863A, 0xF7F1, 0x8640,
+	0xF7F2, 0x8639, 0xF7F3, 0x863C, 0xF7F4, 0x8631, 0xF7F5, 0x863B,
+	0xF7F6, 0x863E, 0xF7F7, 0x8830, 0xF7F8, 0x8832, 0xF7F9, 0x882E,
+	0xF7FA, 0x8833, 0xF7FB, 0x8976, 0xF7FC, 0x8974, 0xF7FD, 0x8973,
+	0xF7FE, 0x89FE, 0xF840, 0x8B8C, 0xF841, 0x8B8E, 0xF842, 0x8B8B,
+	0xF843, 0x8B88, 0xF844, 0x8C45, 0xF845, 0x8D19, 0xF846, 0x8E98,
+	0xF847, 0x8F64, 0xF848, 0x8F63, 0xF849, 0x91BC, 0xF84A, 0x9462,
+	0xF84B, 0x9455, 0xF84C, 0x945D, 0xF84D, 0x9457, 0xF84E, 0x945E,
+	0xF84F, 0x97C4, 0xF850, 0x97C5, 0xF851, 0x9800, 0xF852, 0x9A56,
+	0xF853, 0x9A59, 0xF854, 0x9B1E, 0xF855, 0x9B1F, 0xF856, 0x9B20,
+	0xF857, 0x9C52, 0xF858, 0x9C58, 0xF859, 0x9C50, 0xF85A, 0x9C4A,
+	0xF85B, 0x9C4D, 0xF85C, 0x9C4B, 0xF85D, 0x9C55, 0xF85E, 0x9C59,
+	0xF85F, 0x9C4C, 0xF860, 0x9C4E, 0xF861, 0x9DFB, 0xF862, 0x9DF7,
+	0xF863, 0x9DEF, 0xF864, 0x9DE3, 0xF865, 0x9DEB, 0xF866, 0x9DF8,
+	0xF867, 0x9DE4, 0xF868, 0x9DF6, 0xF869, 0x9DE1, 0xF86A, 0x9DEE,
+	0xF86B, 0x9DE6, 0xF86C, 0x9DF2, 0xF86D, 0x9DF0, 0xF86E, 0x9DE2,
+	0xF86F, 0x9DEC, 0xF870, 0x9DF4, 0xF871, 0x9DF3, 0xF872, 0x9DE8,
+	0xF873, 0x9DED, 0xF874, 0x9EC2, 0xF875, 0x9ED0, 0xF876, 0x9EF2,
+	0xF877, 0x9EF3, 0xF878, 0x9F06, 0xF879, 0x9F1C, 0xF87A, 0x9F38,
+	0xF87B, 0x9F37, 0xF87C, 0x9F36, 0xF87D, 0x9F43, 0xF87E, 0x9F4F,
+	0xF8A1, 0x9F71, 0xF8A2, 0x9F70, 0xF8A3, 0x9F6E, 0xF8A4, 0x9F6F,
+	0xF8A5, 0x56D3, 0xF8A6, 0x56CD, 0xF8A7, 0x5B4E, 0xF8A8, 0x5C6D,
+	0xF8A9, 0x652D, 0xF8AA, 0x66ED, 0xF8AB, 0x66EE, 0xF8AC, 0x6B13,
+	0xF8AD, 0x705F, 0xF8AE, 0x7061, 0xF8AF, 0x705D, 0xF8B0, 0x7060,
+	0xF8B1, 0x7223, 0xF8B2, 0x74DB, 0xF8B3, 0x74E5, 0xF8B4, 0x77D5,
+	0xF8B5, 0x7938, 0xF8B6, 0x79B7, 0xF8B7, 0x79B6, 0xF8B8, 0x7C6A,
+	0xF8B9, 0x7E97, 0xF8BA, 0x7F89, 0xF8BB, 0x826D, 0xF8BC, 0x8643,
+	0xF8BD, 0x8838, 0xF8BE, 0x8837, 0xF8BF, 0x8835, 0xF8C0, 0x884B,
+	0xF8C1, 0x8B94, 0xF8C2, 0x8B95, 0xF8C3, 0x8E9E, 0xF8C4, 0x8E9F,
+	0xF8C5, 0x8EA0, 0xF8C6, 0x8E9D, 0xF8C7, 0x91BE, 0xF8C8, 0x91BD,
+	0xF8C9, 0x91C2, 0xF8CA, 0x946B, 0xF8CB, 0x9468, 0xF8CC, 0x9469,
+	0xF8CD, 0x96E5, 0xF8CE, 0x9746, 0xF8CF, 0x9743, 0xF8D0, 0x9747,
+	0xF8D1, 0x97C7, 0xF8D2, 0x97E5, 0xF8D3, 0x9A5E, 0xF8D4, 0x9AD5,
+	0xF8D5, 0x9B59, 0xF8D6, 0x9C63, 0xF8D7, 0x9C67, 0xF8D8, 0x9C66,
+	0xF8D9, 0x9C62, 0xF8DA, 0x9C5E, 0xF8DB, 0x9C60, 0xF8DC, 0x9E02,
+	0xF8DD, 0x9DFE, 0xF8DE, 0x9E07, 0xF8DF, 0x9E03, 0xF8E0, 0x9E06,
+	0xF8E1, 0x9E05, 0xF8E2, 0x9E00, 0xF8E3, 0x9E01, 0xF8E4, 0x9E09,
+	0xF8E5, 0x9DFF, 0xF8E6, 0x9DFD, 0xF8E7, 0x9E04, 0xF8E8, 0x9EA0,
+	0xF8E9, 0x9F1E, 0xF8EA, 0x9F46, 0xF8EB, 0x9F74, 0xF8EC, 0x9F75,
+	0xF8ED, 0x9F76, 0xF8EE, 0x56D4, 0xF8EF, 0x652E, 0xF8F0, 0x65B8,
+	0xF8F1, 0x6B18, 0xF8F2, 0x6B19, 0xF8F3, 0x6B17, 0xF8F4, 0x6B1A,
+	0xF8F5, 0x7062, 0xF8F6, 0x7226, 0xF8F7, 0x72AA, 0xF8F8, 0x77D8,
+	0xF8F9, 0x77D9, 0xF8FA, 0x7939, 0xF8FB, 0x7C69, 0xF8FC, 0x7C6B,
+	0xF8FD, 0x7CF6, 0xF8FE, 0x7E9A, 0xF940, 0x7E98, 0xF941, 0x7E9B,
+	0xF942, 0x7E99, 0xF943, 0x81E0, 0xF944, 0x81E1, 0xF945, 0x8646,
+	0xF946, 0x8647, 0xF947, 0x8648, 0xF948, 0x8979, 0xF949, 0x897A,
+	0xF94A, 0x897C, 0xF94B, 0x897B, 0xF94C, 0x89FF, 0xF94D, 0x8B98,
+	0xF94E, 0x8B99, 0xF94F, 0x8EA5, 0xF950, 0x8EA4, 0xF951, 0x8EA3,
+	0xF952, 0x946E, 0xF953, 0x946D, 0xF954, 0x946F, 0xF955, 0x9471,
+	0xF956, 0x9473, 0xF957, 0x9749, 0xF958, 0x9872, 0xF959, 0x995F,
+	0xF95A, 0x9C68, 0xF95B, 0x9C6E, 0xF95C, 0x9C6D, 0xF95D, 0x9E0B,
+	0xF95E, 0x9E0D, 0xF95F, 0x9E10, 0xF960, 0x9E0F, 0xF961, 0x9E12,
+	0xF962, 0x9E11, 0xF963, 0x9EA1, 0xF964, 0x9EF5, 0xF965, 0x9F09,
+	0xF966, 0x9F47, 0xF967, 0x9F78, 0xF968, 0x9F7B, 0xF969, 0x9F7A,
+	0xF96A, 0x9F79, 0xF96B, 0x571E, 0xF96C, 0x7066, 0xF96D, 0x7C6F,
+	0xF96E, 0x883C, 0xF96F, 0x8DB2, 0xF970, 0x8EA6, 0xF971, 0x91C3,
+	0xF972, 0x9474, 0xF973, 0x9478, 0xF974, 0x9476, 0xF975, 0x9475,
+	0xF976, 0x9A60, 0xF977, 0x9C74, 0xF978, 0x9C73, 0xF979, 0x9C71,
+	0xF97A, 0x9C75, 0xF97B, 0x9E14, 0xF97C, 0x9E13, 0xF97D, 0x9EF6,
+	0xF97E, 0x9F0A, 0xF9A1, 0x9FA4, 0xF9A2, 0x7068, 0xF9A3, 0x7065,
+	0xF9A4, 0x7CF7, 0xF9A5, 0x866A, 0xF9A6, 0x883E, 0xF9A7, 0x883D,
+	0xF9A8, 0x883F, 0xF9A9, 0x8B9E, 0xF9AA, 0x8C9C, 0xF9AB, 0x8EA9,
+	0xF9AC, 0x8EC9, 0xF9AD, 0x974B, 0xF9AE, 0x9873, 0xF9AF, 0x9874,
+	0xF9B0, 0x98CC, 0xF9B1, 0x9961, 0xF9B2, 0x99AB, 0xF9B3, 0x9A64,
+	0xF9B4, 0x9A66, 0xF9B5, 0x9A67, 0xF9B6, 0x9B24, 0xF9B7, 0x9E15,
+	0xF9B8, 0x9E17, 0xF9B9, 0x9F48, 0xF9BA, 0x6207, 0xF9BB, 0x6B1E,
+	0xF9BC, 0x7227, 0xF9BD, 0x864C, 0xF9BE, 0x8EA8, 0xF9BF, 0x9482,
+	0xF9C0, 0x9480, 0xF9C1, 0x9481, 0xF9C2, 0x9A69, 0xF9C3, 0x9A68,
+	0xF9C4, 0x9B2E, 0xF9C5, 0x9E19, 0xF9C6, 0x7229, 0xF9C7, 0x864B,
+	0xF9C8, 0x8B9F, 0xF9C9, 0x9483, 0xF9CA, 0x9C79, 0xF9CB, 0x9EB7,
+	0xF9CC, 0x7675, 0xF9CD, 0x9A6B, 0xF9CE, 0x9C7A, 0xF9CF, 0x9E1D,
+	0xF9D0, 0x7069, 0xF9D1, 0x706A, 0xF9D2, 0x9EA4, 0xF9D3, 0x9F7E,
+	0xF9D4, 0x9F49, 0xF9D5, 0x9F98, 0xF9D6, 0x7881, 0xF9D7, 0x92B9,
+	0xF9D8, 0x88CF, 0xF9D9, 0x58BB, 0xF9DA, 0x6052, 0xF9DB, 0x7CA7,
+	0xF9DC, 0x5AFA, 0xF9DD, 0x2554, 0xF9DE, 0x2566, 0xF9DF, 0x2557,
+	0xF9E0, 0x2560, 0xF9E1, 0x256C, 0xF9E2, 0x2563, 0xF9E3, 0x255A,
+	0xF9E4, 0x2569, 0xF9E5, 0x255D, 0xF9E6, 0x2552, 0xF9E7, 0x2564,
+	0xF9E8, 0x2555, 0xF9E9, 0x255E, 0xF9EA, 0x256A, 0xF9EB, 0x2561,
+	0xF9EC, 0x2558, 0xF9ED, 0x2567, 0xF9EE, 0x255B, 0xF9EF, 0x2553,
+	0xF9F0, 0x2565, 0xF9F1, 0x2556, 0xF9F2, 0x255F, 0xF9F3, 0x256B,
+	0xF9F4, 0x2562, 0xF9F5, 0x2559, 0xF9F6, 0x2568, 0xF9F7, 0x255C,
+	0xF9F8, 0x2551, 0xF9F9, 0x2550, 0xF9FA, 0x256D, 0xF9FB, 0x256E,
+	0xF9FC, 0x2570, 0xF9FD, 0x256F, 0xF9FE, 0x2593, 0, 0
+};
+
+
+
+WCHAR ff_convert (	/* Converted code, 0 means conversion error */
+	WCHAR	chr,	/* Character code to be converted */
+	UINT	dir		/* 0: Unicode to OEM code, 1: OEM code to Unicode */
+)
+{
+	const WCHAR *p;
+	WCHAR c;
+	int i, n, li, hi;
+
+
+	if (chr < 0x80) {	/* ASCII */
+		c = chr;
+	} else {
+		if (dir) {		/* OEM code to unicode */
+			p = oem2uni;
+			hi = sizeof oem2uni / 4 - 1;
+		} else {		/* Unicode to OEM code */
+			p = uni2oem;
+			hi = sizeof uni2oem / 4 - 1;
+		}
+		li = 0;
+		for (n = 16; n; n--) {
+			i = li + (hi - li) / 2;
+			if (chr == p[i * 2]) break;
+			if (chr > p[i * 2])
+				li = i;
+			else
+				hi = i;
+		}
+		c = n ? p[i * 2 + 1] : 0;
+	}
+
+	return c;
+}
+
+
+
+
+WCHAR ff_wtoupper (
+	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 {			/* Extended characters */
+		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: UsbWattMeter/trunk/fatfs/option/ccsbcs.c
===================================================================
--- UsbWattMeter/trunk/fatfs/option/ccsbcs.c	(revision 164)
+++ UsbWattMeter/trunk/fatfs/option/ccsbcs.c	(revision 164)
@@ -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 _CODE_PAGE == 437
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP437(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
+	0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 720
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP720(0x80-0xFF) to Unicode conversion table */
+	0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
+	0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
+	0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 737
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP737(0x80-0xFF) to Unicode conversion table */
+	0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
+	0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
+	0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
+	0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 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 _CODE_PAGE == 775
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP775(0x80-0xFF) to Unicode conversion table */
+	0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
+	0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
+	0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
+	0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 850
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP850(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+	0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
+	0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
+	0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 852
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP852(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
+	0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+	0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
+	0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
+	0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 855
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP855(0x80-0xFF) to Unicode conversion table */
+	0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
+	0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
+	0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+	0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
+	0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
+	0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 857
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP857(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+	0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
+	0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
+	0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 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 _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 _CODE_PAGE == 862
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP862(0x80-0xFF) to Unicode conversion table */
+	0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+	0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
+	0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 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 _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 _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 _CODE_PAGE == 866
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP866(0x80-0xFF) to Unicode conversion table */
+	0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+	0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
+	0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+	0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 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 !_TBLDEF || !_USE_LFN
+#error This file is not needed at current configuration. Remove from the project.
+#endif
+
+
+
+
+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;
+}
+
+
+
+
+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: UsbWattMeter/trunk/fatfs/option/syscall.c
===================================================================
--- UsbWattMeter/trunk/fatfs/option/syscall.c	(revision 164)
+++ UsbWattMeter/trunk/fatfs/option/syscall.c	(revision 164)
@@ -0,0 +1,152 @@
+/*------------------------------------------------------------------------*/
+/* Sample code of OS dependent controls for FatFs                         */
+/* (C)ChaN, 2014                                                          */
+/*------------------------------------------------------------------------*/
+
+
+#include "../ff.h"
+#include <kernel.h>
+
+
+#if _FS_REENTRANT
+/*------------------------------------------------------------------------*/
+/* Create a Synchronization Object
+/*------------------------------------------------------------------------*/
+/* This function is called in f_mount() function to create a new
+/  synchronization object, such as semaphore and mutex. When a 0 is returned,
+/  the f_mount() function fails with FR_INT_ERR.
+*/
+
+int ff_cre_syncobj (	/* !=0:Function succeeded, ==0:Could not create due to any error */
+	BYTE vol,			/* Corresponding logical drive being processed */
+	_SYNC_t *sobj		/* Pointer to return the created sync object */
+)
+{
+	int ret;
+
+
+	*sobj = CreateMutex(NULL, FALSE, NULL);		/* Win32 */
+	ret = (int)(*sobj != INVALID_HANDLE_VALUE);
+
+//	*sobj = SyncObjects[vol];			/* uITRON (give a static created sync object) */
+//	ret = 1;							/* The initial value of the semaphore must be 1. */
+
+//	*sobj = OSMutexCreate(0, &err);		/* uC/OS-II */
+//	ret = (int)(err == OS_NO_ERR);
+
+//	*sobj = xSemaphoreCreateMutex();	/* FreeRTOS */
+//	ret = (int)(*sobj != NULL);
+
+	return ret;
+}
+
+
+
+/*------------------------------------------------------------------------*/
+/* Delete a Synchronization Object                                        */
+/*------------------------------------------------------------------------*/
+/* This function is called in f_mount() function to delete a synchronization
+/  object that created with ff_cre_syncobj function. When a 0 is returned,
+/  the f_mount() function fails with FR_INT_ERR.
+*/
+
+int ff_del_syncobj (	/* !=0:Function succeeded, ==0:Could not delete due to any error */
+	_SYNC_t sobj		/* Sync object tied to the logical drive to be deleted */
+)
+{
+	int ret;
+
+
+	ret = CloseHandle(sobj);	/* Win32 */
+
+//	ret = 1;					/* uITRON (nothing to do) */
+
+//	OSMutexDel(sobj, OS_DEL_ALWAYS, &err);	/* uC/OS-II */
+//	ret = (int)(err == OS_NO_ERR);
+
+//  vSemaphoreDelete(sobj);		/* FreeRTOS */
+//	ret = 1;
+
+	return ret;
+}
+
+
+
+/*------------------------------------------------------------------------*/
+/* Request Grant to Access the Volume                                     */
+/*------------------------------------------------------------------------*/
+/* This function is called on entering file functions to lock the volume.
+/  When a 0 is returned, the file function fails with FR_TIMEOUT.
+*/
+
+int ff_req_grant (	/* 1:Got a grant to access the volume, 0:Could not get a grant */
+	_SYNC_t sobj	/* Sync object to wait */
+)
+{
+	int ret;
+
+	ret = (int)(WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0);	/* Win32 */
+
+//	ret = (int)(wai_sem(sobj) == E_OK);			/* uITRON */
+
+//	OSMutexPend(sobj, _FS_TIMEOUT, &err));		/* uC/OS-II */
+//	ret = (int)(err == OS_NO_ERR);
+
+//	ret = (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE);	/* FreeRTOS */
+
+	return ret;
+}
+
+
+
+/*------------------------------------------------------------------------*/
+/* Release Grant to Access the Volume                                     */
+/*------------------------------------------------------------------------*/
+/* This function is called on leaving file functions to unlock the volume.
+*/
+
+void ff_rel_grant (
+	_SYNC_t sobj	/* Sync object to be signaled */
+)
+{
+	ReleaseMutex(sobj);		/* Win32 */
+
+//	sig_sem(sobj);			/* uITRON */
+
+//	OSMutexPost(sobj);		/* uC/OS-II */
+
+//	xSemaphoreGive(sobj);	/* FreeRTOS */
+}
+
+#endif
+
+
+
+
+#if _USE_LFN == 3	/* LFN with a working buffer on the heap */
+/*------------------------------------------------------------------------*/
+/* Allocate a memory block                                                */
+/*------------------------------------------------------------------------*/
+/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
+*/
+
+void* ff_memalloc (	/* Returns pointer to the allocated memory block */
+	UINT msize		/* Number of bytes to allocate */
+)
+{
+	return malloc(msize);	/* Allocate a new memory block with POSIX API */
+}
+
+
+/*------------------------------------------------------------------------*/
+/* Free a memory block                                                    */
+/*------------------------------------------------------------------------*/
+
+void ff_memfree (
+	void* mblock	/* Pointer to the memory block to free */
+)
+{
+	free(mblock);	/* Discard the memory block with POSIX API */
+}
+
+#endif
Index: UsbWattMeter/trunk/fatfs/option/unicode.c
===================================================================
--- UsbWattMeter/trunk/fatfs/option/unicode.c	(revision 164)
+++ UsbWattMeter/trunk/fatfs/option/unicode.c	(revision 164)
@@ -0,0 +1,17 @@
+#include "../ff.h"
+
+#if _USE_LFN != 0
+
+#if   _CODE_PAGE == 932	/* Japanese Shift_JIS */
+#include "cc932.c"
+#elif _CODE_PAGE == 936	/* Simplified Chinese GBK */
+#include "cc936.c"
+#elif _CODE_PAGE == 949	/* Korean */
+#include "cc949.c"
+#elif _CODE_PAGE == 950	/* Traditional Chinese Big5 */
+#include "cc950.c"
+#else					/* Single Byte Character-Set */
+#include "ccsbcs.c"
+#endif
+
+#endif
Index: UsbWattMeter/trunk/lwip-1.4.1/CHANGELOG
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/CHANGELOG	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/CHANGELOG	(revision 164)
@@ -0,0 +1,3349 @@
+HISTORY
+
+(CVS HEAD)
+
+  * [Enter new changes just after this line - do not remove this line]
+
+ ++ New features:
+
+
+ ++ Bugfixes:
+
+
+
+
+(STABLE-1.4.1)
+
+  ++ New features:
+
+  2012-03-25: Simon Goldschmidt (idea by Mason)
+  * posix/*: added posix-compatibility include files posix/netdb.h and posix/sys/socket.h
+    which are a simple wrapper to the correct lwIP include files.
+ 
+  2012-01-16: Simon Goldschmidt
+  * opt.h, icmp.c: Added option CHECKSUM_GEN_ICMP
+
+  2011-12-17: Simon Goldschmidt
+  * ip.h: implemented API functions to access so_options of IP pcbs (UDP, TCP, RAW)
+    (fixes bug #35061)
+
+  2011-09-27: Simon Goldschmidt
+  * opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989)
+    (define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h)
+
+  2011-09-21: Simon Goldschmidt
+  * opt.h, api.h, api_lib.c, api_msg.h/.c, sockets.c: Implemented timeout on
+    send (TCP only, bug #33820)
+
+  2011-09-21: Simon Goldschmidt
+  * init.c: Converted runtime-sanity-checks into compile-time checks that can
+    be disabled (since runtime checks can often not be seen on embedded targets)
+
+  2011-09-11: Simon Goldschmidt
+  * ppp.h, ppp_impl.h: splitted ppp.h to an internal and external header file
+    to get a clear separation of which functions an application or port may use
+    (task #11281)
+
+ 2011-09-11: Simon Goldschmidt
+  * opt.h, tcp_impl.h, tcp.c, udp.h/.c: Added a config option to randomize
+    initial local TCP/UDP ports (so that different port ranges are used after
+    a reboot; bug #33818; this one added tcp_init/udp_init functions again)
+
+  2011-09-03: Simon Goldschmidt
+  * dhcp.c: DHCP uses LWIP_RAND() for xid's (bug #30302)
+
+  2011-08-24: Simon Goldschmidt
+  * opt.h, netif.h/.c: added netif remove callback (bug #32397)
+
+  2011-07-26: Simon Goldschmidt
+  * etharp.c: ETHARP_SUPPORT_VLAN: add support for an external VLAN filter
+    function instead of only checking for one VLAN (define ETHARP_VLAN_CHECK_FN)
+
+  2011-07-21: Simon Goldschmidt (patch by hanhui)
+  * ip4.c, etharp.c, pbuf.h: bug #33634 ip_forward() have a faulty behaviour:
+    Added pbuf flags to mark incoming packets as link-layer broadcast/multicast.
+    Also added code to allow ip_forward() to forward non-broadcast packets to
+    the input netif (set IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1).
+
+  2011-06-26: Simon Goldschmidt (patch by Cameron Gutman)
+  * tcp.c, tcp_out.c: bug #33604: added some more asserts to check that
+    pcb->state != LISTEN
+
+   2011-05-14: Simon Goldschmidt (patch by Stéphane Lesage)
+  * tcpip.c/.h: patch #7449 allow tcpip callback from interrupt with static
+    memory message
+
+
+ ++ Bugfixes:
+
+  2012-09-26: Simon Goldschmidt
+  * api_msg.c: fixed bug #37405 'err_tcp()' uses already freed 'netconn' object
+
+  2012-09-26: patch by Henrik Persson
+  * dhcp.c: patch #7843 Fix corner case with dhcp timeouts
+
+  2012-09-26: patch by Henrik Persson
+  * dhcp.c: patch #7840 Segfault in dhcp_parse_reply if no end marker in dhcp packet
+
+  2012-08-22: Simon Goldschmidt
+  * memp.c: fixed bug #37166: memp_sanity check loops itself
+
+  2012-05-08: Simon Goldschmidt
+  * tcp_out.c: fixed bug: #36380 unsent_oversize mismatch in 1.4.1RC1 (this was
+    a debug-check issue only)
+
+  2012-03-27: Simon Goldschmidt
+  * vj.c: fixed bug #35756 header length calculation problem in ppp/vj.c
+
+  2012-03-27: Simon Goldschmidt (patch by Mason)
+  * tcp_out.c: fixed bug #35945: SYN packet should provide the recv MSS not the
+    send MSS
+
+  2012-03-22: Simon Goldschmidt
+  * ip4.c: fixed bug #35927: missing refragmentaion in ip_forward
+ 
+  2012-03-20: Simon Goldschmidt (patch by Mason)
+  * netdb.c: fixed bug #35907: lwip_gethostbyname_r returns an invalid h_addr_list
+ 
+  2012-03-12: Simon Goldschmidt (patch by Bostjan Meglic)
+  * ppp.c: fixed bug #35809: PPP GetMask(): Compiler warning on big endian,
+    possible bug on little endian system
+
+  2012-02-23: Simon Goldschmidt
+  * etharp.c: fixed bug #35595: Impossible to send broadcast without a gateway
+    (introduced when fixing bug# 33551)
+
+  2012-02-16: Simon Goldschmidt
+  * ppp.c: fixed pbuf leak when PPP session is aborted through pppSigHUP()
+    (bug #35541: PPP Memory Leak)
+
+  2012-02-16: Simon Goldschmidt
+  * etharp.c: fixed bug #35531: Impossible to send multicast without a gateway
+    (introduced when fixing bug# 33551)
+
+  2012-02-16: Simon Goldschmidt (patch by Stéphane Lesage)
+  * msg_in.c, msg_out.c: fixed bug #35536 SNMP: error too big response is malformed
+
+  2012-02-15: Simon Goldschmidt
+  * init.c: fixed bug #35537: MEMP_NUM_* sanity checks should be disabled with
+    MEMP_MEM_MALLOC==1
+
+  2012-02-12: Simon Goldschmidt
+  * tcp.h, tcp_in.c, tcp_out.c: partly fixed bug #25882: TCP hangs on
+    MSS > pcb->snd_wnd (by not creating segments bigger than half the window)
+
+  2012-02-11: Simon Goldschmidt
+  * tcp.c: fixed bug #35435: No pcb state check before adding it to time-wait
+    queue while closing
+
+  2012-01-22: Simon Goldschmidt
+  * tcp.c, tcp_in.c: fixed bug #35305: pcb may be freed too early on shutdown(WR)
+
+  2012-01-21: Simon Goldschmidt
+  * tcp.c: fixed bug #34636: FIN_WAIT_2 - Incorrect shutdown of TCP pcb
+
+  2012-01-20: Simon Goldschmidt
+  * dhcp.c: fixed bug #35151: DHCP asserts on incoming option lengths
+
+ 2012-01-20: Simon Goldschmidt
+  * pbuf.c: fixed bug #35291: NULL pointer in pbuf_copy
+
+  2011-11-25: Simon Goldschmidt
+  * tcp.h/.c, tcp_impl.h, tcp_in.c: fixed bug #31177: tcp timers can corrupt
+    tcp_active_pcbs in some cases
+
+  2011-11-23: Simon Goldschmidt
+  * sys.c: fixed bug #34884: sys_msleep() body needs to be surrounded with
+    '#ifndef sys_msleep'
+
+  2011-11-22: Simon Goldschmidt
+  * netif.c, etharp.h/.c: fixed bug #34684: Clear the arp table cache when
+    netif is brought down
+
+  2011-10-28: Simon Goldschmidt
+  * tcp_in.c: fixed bug #34638: Dead code in tcp_receive - pcb->dupacks
+
+  2011-10-23: Simon Goldschmidt
+  * mem.c: fixed bug #34429: possible memory corruption with
+    LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT set to 1
+
+  2011-10-18: Simon Goldschmidt
+  * arch.h, netdb.c: fixed bug #34592: lwip_gethostbyname_r uses nonstandard
+    error value
+
+  2011-10-18: Simon Goldschmidt
+  * opt.h: fixed default values of TCP_SNDLOWAT and TCP_SNDQUEUELOWAT for small
+    windows (bug #34176 select after non-blocking send times out)
+
+  2011-10-18: Simon Goldschmidt
+  * tcp_impl.h, tcp_out.c: fixed bug #34587: TCP_BUILD_MSS_OPTION doesn't
+    consider netif->mtu, causes slow network
+
+  2011-10-18: Simon Goldschmidt
+  * sockets.c: fixed bug #34581 missing parentheses in udplite sockets code
+
+  2011-10-18: Simon Goldschmidt
+  * sockets.h: fixed bug #34580 fcntl() is missing in LWIP_COMPAT_SOCKETS
+
+  2011-10-17: Simon Goldschmidt
+  * api_msg.c: fixed bug #34569: shutdown(SHUT_WR) crashes netconn/socket api
+
+  2011-10-13: Simon Goldschmidt
+  * tcp_in.c, tcp_out.c: fixed bug #34517 (persist timer is started although no
+    zero window is received) by starting the persist timer when a zero window is
+    received, not when we have more data queued for sending than fits into the
+    window
+
+  2011-10-13: Simon Goldschmidt
+  * def.h, timers.c: fixed bug #34541: LWIP_U32_DIFF is unnecessarily complex
+
+  2011-10-13: Simon Goldschmidt
+  * sockets.c, api_lib.c: fixed bug #34540: compiler error when CORE_LOCKING is
+    used and not all protocols are enabled
+
+  2011-10-12: Simon Goldschmidt
+  * pbuf.c: fixed bug #34534: Error in sending fragmented IP if MEM_ALIGNMENT > 4
+
+  2011-10-09: Simon Goldschmidt
+  * tcp_out.c: fixed bug #34426: tcp_zero_window_probe() transmits incorrect
+    byte value when pcb->unacked != NULL
+
+  2011-10-09: Simon Goldschmidt
+  * ip4.c: fixed bug #34447 LWIP_IP_ACCEPT_UDP_PORT(dst_port) wrong
+
+  2011-09-27: Simon Goldschmidt
+  * tcp_in.c, tcp_out.c: Reset pcb->unsent_oversize in 2 more places...
+
+  2011-09-27: Simon Goldschmidt
+  * tcp_in.c: fixed bug #28288: Data after FIN in oos queue
+
+  2011-09-27: Simon Goldschmidt
+  * dhcp.c: fixed bug #34406 dhcp_option_hostname() can overflow the pbuf
+
+  2011-09-24: Simon Goldschmidt
+  * mem.h: fixed bug #34377 MEM_SIZE_F is not defined if MEM_LIBC_MALLOC==1
+
+  2011-09-23: Simon Goldschmidt
+  * pbuf.h, tcp.c, tcp_in.c: fixed bug #33871: rejecting TCP_EVENT_RECV() for
+    the last packet including FIN can lose data
+
+  2011-09-22: Simon Goldschmidt
+  * tcp_impl.h: fixed bug #34355: nagle does not take snd_buf/snd_queuelen into
+    account
+
+  2011-09-21: Simon Goldschmidt
+  * opt.h: fixed default value of TCP_SND_BUF to not violate the sanity checks
+    in init.c
+
+  2011-09-20: Simon Goldschmidt
+  * timers.c: fixed bug #34337 (possible NULL pointer in sys_check_timeouts)
+
+  2011-09-11: Simon Goldschmidt
+  * tcp_out.c: use pcb->mss instead of TCP_MSS for preallocate mss-sized pbufs
+    (bug #34019)
+
+  2011-09-09: Simon Goldschmidt
+  * udp.c: fixed bug #34072: UDP broadcast is received from wrong UDP pcb if
+    udp port matches
+
+  2011-09-03: Simon Goldschmidt
+  * tcp_in.c: fixed bug #33952 PUSH flag in incoming packet is lost when packet
+    is aggregated and sent to application
+
+  2011-09-01: Simon Goldschmidt
+  * opt.h: fixed bug #31809 LWIP_EVENT_API in opts.h is inconsistent compared
+    to other options
+
+  2011-09-01: Simon Goldschmidt
+  * tcp_in.c: fixed bug #34111 RST for ACK to listening pcb has wrong seqno
+
+  2011-08-24: Simon Goldschmidt
+  * api_msg.c, sockets.c: fixed bug #33956 Wrong error returned when calling
+    accept() on UDP connections
+
+  2011-08-24: Simon Goldschmidt
+  * sockets.h: fixed bug #34057 socklen_t should be a typedef
+
+  2011-08-24: Simon Goldschmidt
+  * pbuf.c: fixed bug #34112 Odd check in pbuf_alloced_custom (typo)
+
+  2011-08-24: Simon Goldschmidt
+  * dhcp.c: fixed bug #34122 dhcp: hostname can overflow
+
+  2011-08-24: Simon Goldschmidt
+  * netif.c: fixed bug #34121 netif_add/netif_set_ipaddr fail on NULL ipaddr
+
+  2011-08-22: Simon Goldschmidt
+  * tcp_out.c: fixed bug #33962 TF_FIN not always set after FIN is sent. (This
+    merely prevents nagle from not transmitting fast after closing.)
+
+  2011-07-22: Simon Goldschmidt
+  * api_lib.c, api_msg.c, sockets.c, api.h: fixed bug #31084 (socket API returns
+    always EMSGSIZE on non-blocking sockets if data size > send buffers) -> now
+    lwip_send() sends as much as possible for non-blocking sockets
+
+  2011-07-22: Simon Goldschmidt
+  * pbuf.c/.h, timers.c: freeing ooseq pbufs when the pbuf pool is empty implemented
+    for NO_SYS==1: when not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ()
+    at regular intervals from main level.
+
+  2011-07-21: Simon Goldschmidt
+  * etharp.c: fixed bug #33551 (ARP entries may time out although in use) by
+    sending an ARP request when an ARP entry is used in the last minute before
+    it would time out.
+
+  2011-07-04: Simon Goldschmidt
+  * sys_arch.txt: Fixed documentation after changing sys arch prototypes for 1.4.0.
+
+  2011-06-26: Simon Goldschmidt
+  * tcp.c: fixed bug #31723 (tcp_kill_prio() kills pcbs with the same prio) by
+    updating its documentation only.
+
+ 2011-06-26: Simon Goldschmidt
+  * mem.c: fixed bug #33545: With MEM_USE_POOLS==1, mem_malloc can return an
+    unaligned pointer.
+
+  2011-06-26: Simon Goldschmidt
+  * mem.c: fixed bug #33544 "warning in mem.c in lwip 1.4.0 with NO_SYS=1"
+
+   2011-05-25: Simon Goldschmidt
+  * tcp.c: fixed bug #33398 (pointless conversion when checking TCP port range)
+
+
+
+(STABLE-1.4.0)
+
+  ++ New features:
+
+  2011-03-27: Simon Goldschmidt
+  * tcp_impl.h, tcp_in.c, tcp_out.c: Removed 'dataptr' from 'struct tcp_seg' and
+    calculate it in tcp_zero_window_probe (the only place where it was used).
+
+  2010-11-21: Simon Goldschmidt
+  * dhcp.c/.h: Added a function to deallocate the struct dhcp from a netif
+    (fixes bug #31525).
+
+  2010-07-12: Simon Goldschmidt (patch by Stephane Lesage)
+  * ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for
+    IP_MULTICAST_LOOP at socket- and raw-API level.
+
+  2010-06-16: Simon Goldschmidt
+  * ip.c: Added an optional define (LWIP_IP_ACCEPT_UDP_PORT) that can allow
+    link-layer-addressed UDP traffic to be received while a netif is down (just
+    like DHCP during configuration)
+
+  2010-05-22: Simon Goldschmidt
+  * many many files: bug #27352: removed packing from ip_addr_t, the packed
+    version is now only used in protocol headers. Added global storage for
+    current src/dest IP address while in input functions.
+
+  2010-05-16: Simon Goldschmidt
+  * def.h: task #10391: Add preprocessor-macros for compile-time htonl
+    calculation (and use them throughout the stack where applicable)
+
+  2010-05-16: Simon Goldschmidt
+  * opt.h, memp_std.h, memp.c, ppp_oe.h/.c: PPPoE now uses its own MEMP pool
+    instead of the heap (moved struct pppoe_softc from ppp_oe.c to ppp_oe.h)
+
+  2010-05-16: Simon Goldschmidt
+  * opt.h, memp_std.h, dns.h/.c: DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses its own
+    MEMP pool instead of the heap
+
+  2010-05-13: Simon Goldschmidt
+  * tcp.c, udp.c: task #6995: Implement SO_REUSEADDR (correctly), added
+    new option SO_REUSE_RXTOALL to pass received UDP broadcast/multicast
+    packets to more than one pcb.
+
+  2010-05-02: Simon Goldschmidt
+  * netbuf.h/.c, sockets.c, api_msg.c: use checksum-on-copy for sending
+    UDP data for LWIP_NETIF_TX_SINGLE_PBUF==1
+
+  2010-04-30: Simon Goldschmidt
+  * udp.h/.c, pbuf.h/.c: task #6849: added udp_send(_to/_if) functions that
+    take a precalculated checksum, added pbuf_fill_chksum() to copy data
+    into a pbuf and at the same time calculating the checksum for that data
+
+  2010-04-29: Simon Goldschmidt
+  * ip_addr.h, etharp.h/.c, autoip.c: Create overridable macros for copying
+    2-byte-aligned IP addresses and MAC addresses
+
+  2010-04-28: Patch by Bill Auerbach
+  * ip.c: Inline generating IP checksum to save a function call
+
+  2010-04-14: Simon Goldschmidt
+  * tcpip.h/.c, timers.c: Added an overridable define to get informed when the
+    tcpip_thread processes messages or timeouts to implement a watchdog.
+
+  2010-03-28: Simon Goldschmidt
+  * ip_frag.c: create a new (contiguous) PBUF_RAM for every outgoing
+    fragment if LWIP_NETIF_TX_SINGLE_PBUF==1
+
+  2010-03-27: Simon Goldschmidt
+  * etharp.c: Speedup TX by moving code from find_entry to etharp_output/
+    etharp_query to prevent unnecessary function calls (inspired by
+    patch #7135).
+
+  2010-03-20: Simon Goldschmidt
+  * opt.h, tcpip.c/.h: Added an option to disable tcpip_(un)timeout code
+    since the linker cannot do this automatically to save space.
+
+  2010-03-20: Simon Goldschmidt
+  * opt.h, etharp.c/.h: Added support for static ARP table entries
+
+  2010-03-14: Simon Goldschmidt
+  * tcp_impl.h, tcp_out.c, inet_chksum.h/.c: task #6849: Calculate checksum
+    when creating TCP segments, not when (re-)transmitting them.
+
+  2010-03-07: Simon Goldschmidt
+  * sockets.c: bug #28775 (select/event_callback: only check select_cb_list
+    on change) plus use SYS_LIGHTWEIGHT_PROT to protect the select code.
+    This should speed up receiving data on sockets as the select code in
+    event_callback is only executed when select is waiting.
+
+  2010-03-06: Simon Goldschmidt
+  * tcp_out.c: task #7013 (Create option to have all packets delivered to
+    netif->output in one piece): Always copy to try to create single pbufs
+    in tcp_write.
+
+  2010-03-06: Simon Goldschmidt
+  * api.h, api_lib.c, sockets.c: task #10167 (sockets: speed up TCP recv
+    by not allocating a netbuf): added function netconn_recv_tcp_pbuf()
+    for tcp netconns to receive pbufs, not netbufs; use that function
+    for tcp sockets.
+
+  2010-03-05: Jakob Ole Stoklundsen / Simon Goldschmidt
+  * opt.h, tcp.h, tcp_impl.h, tcp.c, tcp_in.c, tcp_out.c: task #7040:
+    Work on tcp_enqueue: Don't waste memory when chaining segments,
+    added option TCP_OVERSIZE to prevent creating many small pbufs when
+    calling tcp_write with many small blocks of data. Instead, pbufs are
+    allocated larger than needed and the space is used for later calls to
+    tcp_write.
+
+  2010-02-21: Simon Goldschmidt
+  * stats.c/.h: Added const char* name to mem- and memp-stats for easier
+    debugging.
+
+  2010-02-21: Simon Goldschmidt
+  * tcp.h (and usages), added tcp_impl.h: Splitted API and internal
+    implementation of tcp to make API usage cleare to application programmers
+
+  2010-02-14: Simon Goldschmidt/Stephane Lesage
+  * ip_addr.h: Improved some defines working on ip addresses, added faster
+    macro to copy addresses that cannot be NULL
+
+  2010-02-13: Simon Goldschmidt
+  * api.h, api_lib.c, api_msg.c, sockets.c: task #7865 (implement non-
+    blocking send operation)
+
+  2010-02-12: Simon Goldschmidt
+  * sockets.c/.h: Added a minimal version of posix fctl() to have a
+    standardised way to set O_NONBLOCK for nonblocking sockets.
+
+  2010-02-12: Simon Goldschmidt
+  * dhcp.c/.h, autoip.c/.h: task #10139 (Prefer statically allocated
+    memory): added autoip_set_struct() and dhcp_set_struct() to let autoip
+    and dhcp work with user-allocated structs instead of callin mem_malloc
+
+  2010-02-12: Simon Goldschmidt/Jeff Barber
+  * tcp.c/h: patch #6865 (SO_REUSEADDR for TCP): if pcb.so_options has
+    SOF_REUSEADDR set, allow binding to endpoint in TIME_WAIT
+
+  2010-02-12: Simon Goldschmidt
+  * sys layer: task #10139 (Prefer statically allocated memory): converted
+    mbox and semaphore functions to take pointers to sys_mbox_t/sys_sem_t;
+    converted sys_mbox_new/sys_sem_new to take pointers and return err_t;
+    task #7212: Add Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX
+    to let sys.h use binary semaphores instead of mutexes - as before)
+
+  2010-02-09: Simon Goldschmidt (Simon Kallweit)
+  * timers.c/.h: Added function sys_restart_timeouts() from patch #7085
+    (Restart system timeout handling)
+
+  2010-02-09: Simon Goldschmidt
+  * netif.c/.h, removed loopif.c/.h: task #10153 (Integrate loopif into
+    netif.c) - loopif does not have to be created by the port any more,
+    just define LWIP_HAVE_LOOPIF to 1.
+
+  2010-02-08: Simon Goldschmidt
+  * inet.h, ip_addr.c/.h: Added reentrant versions of inet_ntoa/ipaddr_ntoa
+    inet_ntoa_r/ipaddr_ntoa_r
+
+  2010-02-08: Simon Goldschmidt
+  * netif.h: Added netif_s/get_igmp_mac_filter() macros
+
+  2010-02-05: Simon Goldschmidt
+  * netif.h: Added function-like macros to get/set the hostname on a netif
+
+  2010-02-04: Simon Goldschmidt
+  * nearly every file: Replaced struct ip_addr by typedef ip_addr_t to
+    make changing the actual implementation behind the typedef easier.
+
+  2010-02-01: Simon Goldschmidt
+  * opt.h, memp_std.h, dns.h, netdb.c, memp.c: Let netdb use a memp pool
+    for allocating memory when getaddrinfo() is called.
+
+  2010-01-31: Simon Goldschmidt
+  * dhcp.h, dhcp.c: Reworked the code that parses DHCP options: parse
+    them once instead of parsing for every option. This also removes
+    the need for mem_malloc from dhcp_recv and makes it possible to
+    correctly retrieve the BOOTP file.
+
+  2010-01-30: simon Goldschmidt
+  * sockets.c: Use SYS_LIGHTWEIGHT_PROT instead of a semaphore to protect
+    the sockets array.
+
+  2010-01-29: Simon Goldschmidt (patch by Laura Garrett)
+  * api.h, api_msg.c, sockets.c: Added except set support in select
+    (patch #6860)
+
+  2010-01-29: Simon Goldschmidt (patch by Laura Garrett)
+  * api.h, sockets.h, err.h, api_lib.c, api_msg.c, sockets.c, err.c:
+    Add non-blocking support for connect (partly from patch #6860),
+    plus many cleanups in socket & netconn API.
+
+  2010-01-27: Simon Goldschmidt
+  * opt.h, tcp.h, init.c, api_msg.c: Added TCP_SNDQUEUELOWAT corresponding
+    to TCP_SNDLOWAT and added tcp_sndqueuelen() - this fixes bug #28605
+
+  2010-01-26: Simon Goldschmidt
+  * snmp: Use memp pools for snmp instead of the heap; added 4 new pools.
+
+  2010-01-14: Simon Goldschmidt
+  * ppp.c/.h: Fixed bug #27856: PPP: Set netif link- and status-callback
+    by adding ppp_set_netif_statuscallback()/ppp_set_netif_linkcallback()
+
+  2010-01-13: Simon Goldschmidt
+  * mem.c: The heap now may be moved to user-defined memory by defining
+    LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address
+    (patch #6966 and bug #26133)
+
+  2010-01-10: Simon Goldschmidt (Bill Auerbach)
+  * opt.h, memp.c: patch #6822 (Add option to place memory pools in
+    separate arrays)
+
+  2010-01-10: Simon Goldschmidt
+  * init.c, igmp.c: patch #6463 (IGMP - Adding Random Delay): added define
+    LWIP_RAND() for lwip-wide randomization (to be defined in cc.h)
+
+  2009-12-31: Simon Goldschmidt
+  * tcpip.c, init.c, memp.c, sys.c, memp_std.h, sys.h, tcpip.h
+    added timers.c/.h: Separated timer implementation from semaphore/mbox
+    implementation, moved timer implementation to timers.c/.h, timers are
+    now only called from tcpip_thread or by explicitly checking them.
+    (TASK#7235)
+
+  2009-12-27: Simon Goldschmidt
+  * opt.h, etharp.h/.c, init.c, tcpip.c: Added an additional option
+    LWIP_ETHERNET to support ethernet without ARP (necessary for pure PPPoE)
+
+
+  ++ Bugfixes:
+
+  2011-04-20: Simon Goldschmidt
+  * sys_arch.txt: sys_arch_timeouts() is not needed any more.
+
+  2011-04-13: Simon Goldschmidt
+  * tcp.c, udp.c: Fixed bug #33048 (Bad range for IP source port numbers) by
+    using ports in the IANA private/dynamic range (49152 through 65535).
+
+  2011-03-29: Simon Goldschmidt, patch by Emil Lhungdahl:
+  * etharp.h/.c: Fixed broken VLAN support.
+
+  2011-03-27: Simon Goldschmidt
+  * tcp.c: Fixed bug #32926 (TCP_RMV(&tcp_bound_pcbs) is called on unbound tcp
+    pcbs) by checking if the pcb was bound (local_port != 0).
+
+  2011-03-27: Simon Goldschmidt
+  * ppp.c: Fixed bug #32280 (ppp: a pbuf is freed twice)
+
+  2011-03-27: Simon Goldschmidt
+  * sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and
+    raw pcbs with LWIP_TCPIP_CORE_LOCKING==1.
+  
+  2011-03-27: Simon Goldschmidt
+  * tcp_out.c: Fixed bug #32820 (Outgoing TCP connections created before route
+    is present never times out) by starting retransmission timer before checking
+    route.
+
+  2011-03-22: Simon Goldschmidt
+  * ppp.c: Fixed bug #32648 (PPP code crashes when terminating a link) by only
+    calling sio_read_abort() if the file descriptor is valid.
+
+  2011-03-14: Simon Goldschmidt
+  * err.h/.c, sockets.c, api_msg.c: fixed bug #31748 (Calling non-blocking connect
+    more than once can render a socket useless) since it mainly involves changing
+    "FATAL" classification of error codes: ERR_USE and ERR_ISCONN just aren't fatal.
+
+  2011-03-13: Simon Goldschmidt
+  * sockets.c: fixed bug #32769 (ESHUTDOWN is linux-specific) by fixing
+    err_to_errno_table (ERR_CLSD: ENOTCONN instead of ESHUTDOWN), ERR_ISCONN:
+    use EALRADY instead of -1
+
+  2011-03-13: Simon Goldschmidt
+  * api_lib.c: netconn_accept: return ERR_ABRT instead of ERR_CLSD if the
+    connection has been aborted by err_tcp (since this is not a normal closing
+    procedure).
+
+  2011-03-13: Simon Goldschmidt
+  * tcp.c: tcp_bind: return ERR_VAL instead of ERR_ISCONN when trying to bind
+    with pcb->state != CLOSED
+
+  2011-02-17: Simon Goldschmidt
+  * rawapi.txt: Fixed bug #32561 tcp_poll argument definition out-of-order in
+    documentation
+
+  2011-02-17: Simon Goldschmidt
+  * many files: Added missing U/UL modifiers to fix 16-bit-arch portability.
+
+  2011-01-24: Simon Goldschmidt
+  * sockets.c: Fixed bug #31741: lwip_select seems to have threading problems
+
+  2010-12-02: Simon Goldschmidt
+  * err.h: Fixed ERR_IS_FATAL so that ERR_WOULDBLOCK is not fatal.
+
+  2010-11-23: Simon Goldschmidt
+  * api.h, api_lib.c, api_msg.c, sockets.c: netconn.recv_avail is only used for
+    LWIP_SO_RCVBUF and ioctl/FIONREAD.
+
+  2010-11-23: Simon Goldschmidt
+  * etharp.c: Fixed bug #31720: ARP-queueing: RFC 1122 recommends to queue at
+    least 1 packet -> ARP_QUEUEING==0 now queues the most recent packet.
+
+  2010-11-23: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #30577: tcp_input: don't discard ACK-only packets after
+    refusing 'refused_data' again.
+  
+  2010-11-22: Simon Goldschmidt
+  * sockets.c: Fixed bug #31590: getsockopt(... SO_ERROR ...) gives EINPROGRESS
+    after a successful nonblocking connection.
+
+  2010-11-22: Simon Goldschmidt
+  * etharp.c: Fixed bug #31722: IP packets sent with an AutoIP source addr
+    must be sent link-local
+
+  2010-11-22: Simon Goldschmidt
+  * timers.c: patch #7329: tcp_timer_needed prototype was ifdef'ed out for
+    LWIP_TIMERS==0
+
+  2010-11-20: Simon Goldschmidt
+  * sockets.c: Fixed bug #31170: lwip_setsockopt() does not set socket number
+
+  2010-11-20: Simon Goldschmidt
+  * sockets.h: Fixed bug #31304: Changed SHUT_RD, SHUT_WR and SHUT_RDWR to
+    resemble other stacks.
+
+  2010-11-20: Simon Goldschmidt
+  * dns.c: Fixed bug #31535: TCP_SND_QUEUELEN must be at least 2 or else
+    no-copy TCP writes will never succeed.
+
+  2010-11-20: Simon Goldschmidt
+  * dns.c: Fixed bug #31701: Error return value from dns_gethostbyname() does
+    not match documentation: return ERR_ARG instead of ERR_VAL if not
+    initialized or wrong argument.
+
+  2010-10-20: Simon Goldschmidt
+  * sockets.h: Fixed bug #31385: sizeof(struct sockaddr) is 30 but should be 16
+
+  2010-10-05: Simon Goldschmidt
+  * dhcp.c: Once again fixed #30038: DHCP/AutoIP cooperation failed when
+    replugging the network cable after an AutoIP address was assigned.
+
+  2010-08-10: Simon Goldschmidt
+  * tcp.c: Fixed bug #30728: tcp_new_port() did not check listen pcbs
+
+  2010-08-03: Simon Goldschmidt
+  * udp.c, raw.c: Don't chain empty pbufs when sending them (fixes bug #30625)
+
+  2010-08-01: Simon Goldschmidt (patch by Greg Renda)
+  * ppp.c: Applied patch #7264 (PPP protocols are rejected incorrectly on big
+    endian architectures)
+  
+  2010-07-28: Simon Goldschmidt
+  * api_lib.c, api_msg.c, sockets.c, mib2.c: Fixed compilation with TCP or UDP
+    disabled.
+  
+  2010-07-27: Simon Goldschmidt
+  * tcp.c: Fixed bug #30565 (tcp_connect() check bound list): that check did no
+    harm but never did anything
+  
+  2010-07-21: Simon Goldschmidt
+  * ip.c: Fixed invalid fix for bug #30402 (CHECKSUM_GEN_IP_INLINE does not
+    add IP options)
+
+  2010-07-16: Kieran Mansley
+  * msg_in.c: Fixed SNMP ASN constant defines to not use ! operator 
+
+  2010-07-10: Simon Goldschmidt
+  * ip.c: Fixed bug #30402: CHECKSUM_GEN_IP_INLINE does not add IP options
+
+  2010-06-30: Simon Goldschmidt
+  * api_msg.c: fixed bug #30300 (shutdown parameter was not initialized in
+    netconn_delete)
+
+  2010-06-28: Kieran Mansley
+  * timers.c remove unportable printing of C function pointers
+
+  2010-06-24: Simon Goldschmidt
+  * init.c, timers.c/.h, opt.h, memp_std.h: From patch #7221: added flag
+    NO_SYS_NO_TIMERS to drop timer support for NO_SYS==1 for easier upgrading
+
+  2010-06-24: Simon Goldschmidt
+  * api(_lib).c/.h, api_msg.c/.h, sockets.c/.h: Fixed bug #10088: Correctly
+    implemented shutdown at socket level.
+
+  2010-06-21: Simon Goldschmidt
+  * pbuf.c/.h, ip_frag.c/.h, opt.h, memp_std.h: Fixed bug #29361 (ip_frag has
+    problems with zero-copy DMA MACs) by adding custom pbufs and implementing
+    custom pbufs that reference other (original) pbufs. Additionally set
+    IP_FRAG_USES_STATIC_BUF=0 as default to be on the safe side.
+
+  2010-06-15: Simon Goldschmidt
+  * dhcp.c: Fixed bug #29970: DHCP endian issue parsing option responses
+
+  2010-06-14: Simon Goldschmidt
+  * autoip.c: Fixed bug #30039: AutoIP does not reuse previous addresses
+
+  2010-06-12: Simon Goldschmidt
+  * dhcp.c: Fixed bug #30038: dhcp_network_changed doesn't reset AUTOIP coop
+    state
+
+  2010-05-17: Simon Goldschmidt
+  * netdb.c: Correctly NULL-terminate h_addr_list
+
+  2010-05-16: Simon Goldschmidt
+  * def.h/.c: changed the semantics of LWIP_PREFIX_BYTEORDER_FUNCS to prevent
+    "symbol already defined" i.e. when linking to winsock
+
+  2010-05-05: Simon Goldschmidt
+  * def.h, timers.c: Fixed bug #29769 (sys_check_timeouts: sys_now() may
+    overflow)
+
+  2010-04-21: Simon Goldschmidt
+  * api_msg.c: Fixed bug #29617 (sometime cause stall on delete listening
+    connection)
+
+  2010-03-28: Luca Ceresoli
+  * ip_addr.c/.h: patch #7143: Add a few missing const qualifiers
+
+  2010-03-27: Luca Ceresoli
+  * mib2.c: patch #7130: remove meaningless const qualifiers
+
+  2010-03-26: Simon Goldschmidt
+  * tcp_out.c: Make LWIP_NETIF_TX_SINGLE_PBUF work for TCP, too
+
+  2010-03-26: Simon Goldschmidt
+  * various files: Fixed compiling with different options disabled (TCP/UDP),
+    triggered by bug #29345; don't allocate acceptmbox if LWIP_TCP is disabled
+
+  2010-03-25: Simon Goldschmidt
+  * sockets.c: Fixed bug #29332: lwip_select() processes readset incorrectly
+
+  2010-03-25: Simon Goldschmidt
+  * tcp_in.c, test_tcp_oos.c: Fixed bug #29080: Correctly handle remote side
+    overrunning our rcv_wnd in ooseq case.
+
+  2010-03-22: Simon Goldschmidt
+  * tcp.c: tcp_listen() did not copy the pcb's prio.
+
+  2010-03-19: Simon Goldschmidt
+  * snmp_msg.c: Fixed bug #29256: SNMP Trap address was not correctly set
+
+  2010-03-14: Simon Goldschmidt
+  * opt.h, etharp.h: Fixed bug #29148 (Incorrect PBUF_POOL_BUFSIZE for ports
+    where ETH_PAD_SIZE > 0) by moving definition of ETH_PAD_SIZE to opt.h
+    and basing PBUF_LINK_HLEN on it.
+
+  2010-03-08: Simon Goldschmidt
+  * netif.c, ipv4/ip.c: task #10241 (AutoIP: don't break existing connections
+    when assiging routable address): when checking incoming packets and
+    aborting existing connection on address change, filter out link-local
+    addresses.
+
+  2010-03-06: Simon Goldschmidt
+  * sockets.c: Fixed LWIP_NETIF_TX_SINGLE_PBUF for LWIP_TCPIP_CORE_LOCKING
+
+  2010-03-06: Simon Goldschmidt
+  * ipv4/ip.c: Don't try to forward link-local addresses
+
+  2010-03-06: Simon Goldschmidt
+  * etharp.c: Fixed bug #29087: etharp: don't send packets for LinkLocal-
+    addresses to gw
+
+  2010-03-05: Simon Goldschmidt
+  * dhcp.c: Fixed bug #29072: Correctly set ciaddr based on message-type
+    and state.
+
+  2010-03-05: Simon Goldschmidt
+  * api_msg.c: Correctly set TCP_WRITE_FLAG_MORE when netconn_write is split
+    into multiple calls to tcp_write.    
+
+  2010-02-21: Simon Goldschmidt
+  * opt.h, mem.h, dns.c: task #10140: Remove DNS_USES_STATIC_BUF (keep
+    the implementation of DNS_USES_STATIC_BUF==1)
+
+  2010-02-20: Simon Goldschmidt
+  * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Task #10088: Correctly implement
+    close() vs. shutdown(). Now the application does not get any more
+    recv callbacks after calling tcp_close(). Added tcp_shutdown().
+
+  2010-02-19: Simon Goldschmidt
+  * mem.c/.h, pbuf.c: Renamed mem_realloc() to mem_trim() to prevent
+    confusion with realloc()
+
+  2010-02-15: Simon Goldschmidt/Stephane Lesage
+  * netif.c/.h: Link status does not depend on LWIP_NETIF_LINK_CALLBACK
+    (fixes bug #28899)
+
+  2010-02-14: Simon Goldschmidt
+  * netif.c: Fixed bug #28877 (Duplicate ARP gratuitous packet with
+    LWIP_NETIF_LINK_CALLBACK set on) by only sending if both link- and
+    admin-status of a netif are up
+
+  2010-02-14: Simon Goldschmidt
+  * opt.h: Disable ETHARP_TRUST_IP_MAC by default since it slows down packet
+    reception and is not really necessary
+
+  2010-02-14: Simon Goldschmidt
+  * etharp.c/.h: Fixed ARP input processing: only add a new entry if a
+    request was directed as us (RFC 826, Packet Reception), otherwise
+    only update existing entries; internalized some functions
+
+  2010-02-14: Simon Goldschmidt
+  * netif.h, etharp.c, tcpip.c: Fixed bug #28183 (ARP and TCP/IP cannot be
+    disabled on netif used for PPPoE) by adding a new netif flag
+    (NETIF_FLAG_ETHERNET) that tells the stack the device is an ethernet
+    device but prevents usage of ARP (so that ethernet_input can be used
+    for PPPoE).
+
+  2010-02-12: Simon Goldschmidt
+  * netif.c: netif_set_link_up/down: only do something if the link state
+    actually changes
+
+  2010-02-12: Simon Goldschmidt/Stephane Lesage
+  * api_msg.c: Fixed bug #28865 (Cannot close socket/netconn in non-blocking
+    connect)
+
+  2010-02-12: Simon Goldschmidt
+  * mem.h: Fixed bug #28866 (mem_realloc function defined in mem.h)
+
+  2010-02-09: Simon Goldschmidt
+  * api_lib.c, api_msg.c, sockets.c, api.h, api_msg.h: Fixed bug #22110
+   (recv() makes receive window update for data that wasn't received by
+    application)
+
+  2010-02-09: Simon Goldschmidt/Stephane Lesage
+  * sockets.c: Fixed bug #28853 (lwip_recvfrom() returns 0 on receive time-out
+    or any netconn_recv() error)
+
+  2010-02-09: Simon Goldschmidt
+  * ppp.c: task #10154 (PPP: Update snmp in/out counters for tx/rx packets)
+
+  2010-02-09: Simon Goldschmidt
+  * netif.c: For loopback packets, adjust the stats- and snmp-counters
+    for the loopback netif.
+
+  2010-02-08: Simon Goldschmidt
+  * igmp.c/.h, ip.h: Moved most defines from igmp.h to igmp.c for clarity
+    since they are not used anywhere else.
+
+  2010-02-08: Simon Goldschmidt (Stéphane Lesage)
+  * igmp.c, igmp.h, stats.c, stats.h: Improved IGMP stats
+    (patch from bug #28798)
+
+  2010-02-08: Simon Goldschmidt (Stéphane Lesage)
+  * igmp.c: Fixed bug #28798 (Error in "Max Response Time" processing) and
+    another bug when LWIP_RAND() returns zero.
+
+  2010-02-04: Simon Goldschmidt
+  * nearly every file: Use macros defined in ip_addr.h (some of them new)
+    to work with IP addresses (preparation for bug #27352 - Change ip_addr
+    from struct to typedef (u32_t) - and better code).
+
+  2010-01-31: Simon Goldschmidt
+  * netif.c: Don't call the link-callback from netif_set_up/down() since
+    this invalidly retriggers DHCP.
+
+  2010-01-29: Simon Goldschmidt
+  * ip_addr.h, inet.h, def.h, inet.c, def.c, more: Cleanly separate the
+    portability file inet.h and its contents from the stack: moved htonX-
+    functions to def.h (and the new def.c - they are not ipv4 dependent),
+    let inet.h depend on ip_addr.h and not the other way round.
+    This fixes bug #28732.
+
+  2010-01-28: Kieran Mansley
+  * tcp.c: Ensure ssthresh >= 2*MSS
+
+  2010-01-27: Simon Goldschmidt
+  * tcp.h, tcp.c, tcp_in.c: Fixed bug #27871: Calling tcp_abort() in recv
+    callback can lead to accessing unallocated memory. As a consequence,
+    ERR_ABRT means the application has called tcp_abort()!
+
+  2010-01-25: Simon Goldschmidt
+  * snmp_structs.h, msg_in.c: Partly fixed bug #22070 (MIB_OBJECT_WRITE_ONLY
+    not implemented in SNMP): write-only or not-accessible are still
+    returned by getnext (though not by get)
+
+  2010-01-24: Simon Goldschmidt
+  * snmp: Renamed the private mib node from 'private' to 'mib_private' to
+    not use reserved C/C++ keywords
+
+  2010-01-23: Simon Goldschmidt
+  * sockets.c: Fixed bug #28716: select() returns 0 after waiting for less
+    than 1 ms
+
+  2010-01-21: Simon Goldschmidt
+  * tcp.c, api_msg.c: Fixed bug #28651 (tcp_connect: no callbacks called
+    if tcp_enqueue fails) both in raw- and netconn-API
+
+  2010-01-19: Simon Goldschmidt
+  * api_msg.c: Fixed bug #27316: netconn: Possible deadlock in err_tcp
+
+  2010-01-18: Iordan Neshev/Simon Goldschmidt
+  * src/netif/ppp: reorganised PPP sourcecode to 2.3.11 including some
+    bugfix backports from 2.4.x.
+
+  2010-01-18: Simon Goldschmidt
+  * mem.c: Fixed bug #28679: mem_realloc calculates mem_stats wrong
+
+  2010-01-17: Simon Goldschmidt
+  * api_lib.c, api_msg.c, (api_msg.h, api.h, sockets.c, tcpip.c):
+    task #10102: "netconn: clean up conn->err threading issues" by adding
+    error return value to struct api_msg_msg
+
+  2010-01-17: Simon Goldschmidt
+  * api.h, api_lib.c, sockets.c: Changed netconn_recv() and netconn_accept()
+    to return err_t (bugs #27709 and #28087)
+
+  2010-01-14: Simon Goldschmidt
+  * ...: Use typedef for function prototypes throughout the stack.
+
+  2010-01-13: Simon Goldschmidt
+  * api_msg.h/.c, api_lib.c: Fixed bug #26672 (close connection when receive
+    window = 0) by correctly draining recvmbox/acceptmbox
+
+  2010-01-11: Simon Goldschmidt
+  * pap.c: Fixed bug #13315 (PPP PAP authentication can result in
+    erroneous callbacks) by copying the code from recent pppd
+
+  2010-01-10: Simon Goldschmidt
+  * raw.c: Fixed bug #28506 (raw_bind should filter received packets)
+
+  2010-01-10: Simon Goldschmidt
+  * tcp.h/.c: bug #28127 (remove call to tcp_output() from tcp_ack(_now)())
+
+  2010-01-08: Simon Goldschmidt
+  * sockets.c: Fixed bug #28519 (lwip_recvfrom bug with len > 65535)
+
+  2010-01-08: Simon Goldschmidt
+  * dns.c: Copy hostname for DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1 since string
+    passed to dns_local_addhost() might be volatile
+
+  2010-01-07: Simon Goldschmidt
+  * timers.c, tcp.h: Call tcp_timer_needed() with NO_SYS==1, too
+
+  2010-01-06: Simon Goldschmidt
+  * netdb.h: Fixed bug #28496: missing include guards in netdb.h
+
+  2009-12-31: Simon Goldschmidt
+  * many ppp files: Reorganised PPP source code from ucip structure to pppd
+    structure to easily compare our code against the pppd code (around v2.3.1)
+
+  2009-12-27: Simon Goldschmidt
+  * tcp_in.c: Another fix for bug #28241 (ooseq processing) and adapted
+    unit test
+
+
+(STABLE-1.3.2)
+
+  ++ New features:
+
+  2009-10-27 Simon Goldschmidt/Stephan Lesage
+  * netifapi.c/.h: Added netifapi_netif_set_addr()
+
+  2009-10-07 Simon Goldschmidt/Fabian Koch
+  * api_msg.c, netbuf.c/.h, opt.h: patch #6888: Patch for UDP Netbufs to
+    support dest-addr and dest-port (optional: LWIP_NETBUF_RECVINFO)
+
+  2009-08-26 Simon Goldschmidt/Simon Kallweit
+  * slipif.c/.h: bug #26397: SLIP polling support
+
+  2009-08-25 Simon Goldschmidt
+  * opt.h, etharp.h/.c: task #9033: Support IEEE 802.1q tagged frame (VLAN),
+    New configuration options ETHARP_SUPPORT_VLAN and ETHARP_VLAN_CHECK.
+
+  2009-08-25 Simon Goldschmidt
+  * ip_addr.h, netdb.c: patch #6900: added define ip_ntoa(struct ip_addr*)
+
+  2009-08-24 Jakob Stoklund Olesen
+  * autoip.c, dhcp.c, netif.c: patch #6725: Teach AutoIP and DHCP to respond
+    to netif_set_link_up().
+
+  2009-08-23 Simon Goldschmidt
+  * tcp.h/.c: Added function tcp_debug_state_str() to convert a tcp state
+    to a human-readable string.
+
+  ++ Bugfixes:
+
+  2009-12-24: Kieran Mansley
+  * tcp_in.c Apply patches from Oleg Tyshev to improve OOS processing
+    (BUG#28241)
+
+  2009-12-06: Simon Goldschmidt
+  * ppp.h/.c: Fixed bug #27079 (Yet another leak in PPP): outpacket_buf can
+    be statically allocated (like in ucip)
+
+  2009-12-04: Simon Goldschmidt (patch by Ioardan Neshev)
+  * pap.c: patch #6969: PPP: missing PAP authentication UNTIMEOUT
+
+  2009-12-03: Simon Goldschmidt
+  * tcp.h, tcp_in.c, tcp_out.c: Fixed bug #28106: dup ack for fast retransmit
+    could have non-zero length
+
+  2009-12-02: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #27904: TCP sends too many ACKs: delay resetting
+    tcp_input_pcb until after calling the pcb's callbacks
+
+  2009-11-29: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #28054: Two segments with FIN flag on the out-of-
+    sequence queue, also fixed PBUF_POOL leak in the out-of-sequence code
+
+  2009-11-29: Simon Goldschmidt
+  * pbuf.c: Fixed bug #28064: pbuf_alloc(PBUF_POOL) is not thread-safe by
+    queueing a call into tcpip_thread to free ooseq-bufs if the pool is empty
+
+  2009-11-26: Simon Goldschmidt
+  * tcp.h: Fixed bug #28098: Nagle can prevent fast retransmit from sending
+    segment
+
+  2009-11-26: Simon Goldschmidt
+  * tcp.h, sockets.c: Fixed bug #28099: API required to disable Nagle
+    algorithm at PCB level
+
+  2009-11-22: Simon Goldschmidt
+  * tcp_out.c: Fixed bug #27905: FIN isn't combined with data on unsent
+
+  2009-11-22: Simon Goldschmidt (suggested by Bill Auerbach)
+  * tcp.c: tcp_alloc: prevent increasing stats.err for MEMP_TCP_PCB when
+    reusing time-wait pcb
+
+  2009-11-20: Simon Goldschmidt (patch by Albert Bartel)
+  * sockets.c: Fixed bug #28062: Data received directly after accepting
+    does not wake up select
+
+  2009-11-11: Simon Goldschmidt
+  * netdb.h: Fixed bug #27994: incorrect define for freeaddrinfo(addrinfo)
+
+  2009-10-30: Simon Goldschmidt
+  * opt.h: Increased default value for TCP_MSS to 536, updated default
+    value for TCP_WND to 4*TCP_MSS to keep delayed ACK working.
+
+  2009-10-28: Kieran Mansley
+  * tcp_in.c, tcp_out.c, tcp.h: re-work the fast retransmission code
+    to follow algorithm from TCP/IP Illustrated
+
+  2009-10-27: Kieran Mansley
+  * tcp_in.c: fix BUG#27445: grow cwnd with every duplicate ACK
+
+  2009-10-25: Simon Goldschmidt
+  * tcp.h: bug-fix in the TCP_EVENT_RECV macro (has to call tcp_recved if
+    pcb->recv is NULL to keep rcv_wnd correct)
+
+  2009-10-25: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #26251: RST process in TIME_WAIT TCP state
+
+  2009-10-23: Simon Goldschmidt (David Empson)
+  * tcp.c: Fixed bug #27783: Silly window avoidance for small window sizes
+
+  2009-10-21: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #27215: TCP sent() callback gives leading and
+    trailing 1 byte len (SYN/FIN)
+
+  2009-10-21: Simon Goldschmidt
+  * tcp_out.c: Fixed bug #27315: zero window probe and FIN
+
+  2009-10-19: Simon Goldschmidt
+  * dhcp.c/.h: Minor code simplification (don't store received pbuf, change
+    conditional code to assert where applicable), check pbuf length before
+    testing for valid reply
+
+  2009-10-19: Simon Goldschmidt
+  * dhcp.c: Removed most calls to udp_connect since they aren't necessary
+    when using udp_sendto_if() - always stay connected to IP_ADDR_ANY.
+
+  2009-10-16: Simon Goldschmidt
+  * ip.c: Fixed bug #27390: Source IP check in ip_input() causes it to drop
+    valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is
+    enabled
+
+  2009-10-15: Simon Goldschmidt (Oleg Tyshev)
+  * tcp_in.c: Fixed bug #27329: dupacks by unidirectional data transmit
+
+  2009-10-15: Simon Goldschmidt
+  * api_lib.c: Fixed bug #27709: conn->err race condition on netconn_recv()
+    timeout
+
+  2009-10-15: Simon Goldschmidt
+  * autoip.c: Fixed bug #27704: autoip starts with wrong address
+    LWIP_AUTOIP_CREATE_SEED_ADDR() returned address in host byte order instead
+    of network byte order
+
+  2009-10-11 Simon Goldschmidt (Jörg Kesten)
+  * tcp_out.c: Fixed bug #27504: tcp_enqueue wrongly concatenates segments
+    which are not consecutive when retransmitting unacked segments
+
+  2009-10-09 Simon Goldschmidt
+  * opt.h: Fixed default values of some stats to only be enabled if used
+    Fixes bug #27338: sys_stats is defined when NO_SYS = 1
+
+  2009-08-30 Simon Goldschmidt
+  * ip.c: Fixed bug bug #27345: "ip_frag() does not use the LWIP_NETIF_LOOPBACK
+    function" by checking for loopback before calling ip_frag
+
+  2009-08-25 Simon Goldschmidt
+  * dhcp.c: fixed invalid dependency to etharp_query if DHCP_DOES_ARP_CHECK==0
+
+  2009-08-23 Simon Goldschmidt
+  * ppp.c: bug #27078: Possible memory leak in pppInit()
+
+  2009-08-23 Simon Goldschmidt
+  * netdb.c, dns.c: bug #26657: DNS, if host name is "localhost", result
+    is error.
+
+  2009-08-23 Simon Goldschmidt
+  * opt.h, init.c: bug #26649: TCP fails when TCP_MSS > TCP_SND_BUF
+    Fixed wrong parenthesis, added check in init.c
+
+  2009-08-23 Simon Goldschmidt
+  * ppp.c: bug #27266: wait-state debug message in pppMain occurs every ms
+
+  2009-08-23 Simon Goldschmidt
+  * many ppp files: bug #27267: Added include to string.h where needed
+
+  2009-08-23 Simon Goldschmidt
+  * tcp.h: patch #6843: tcp.h macro optimization patch (for little endian)
+
+
+(STABLE-1.3.1)
+
+  ++ New features:
+
+  2009-05-10 Simon Goldschmidt
+  * opt.h, sockets.c, pbuf.c, netbuf.h, pbuf.h: task #7013: Added option
+    LWIP_NETIF_TX_SINGLE_PBUF to try to create transmit packets from only
+    one pbuf to help MACs that don't support scatter-gather DMA.
+
+  2009-05-09 Simon Goldschmidt
+  * icmp.h, icmp.c: Shrinked ICMP code, added option to NOT check icoming
+    ECHO pbuf for size (just use it): LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
+
+  2009-05-05 Simon Goldschmidt, Jakob Stoklund Olesen
+  * ip.h, ip.c: Added ip_current_netif() & ip_current_header() to receive
+    extended info about the currently received packet.
+
+  2009-04-27 Simon Goldschmidt
+  * sys.h: Made SYS_LIGHTWEIGHT_PROT and sys_now() work with NO_SYS=1
+
+  2009-04-25 Simon Goldschmidt
+  * mem.c, opt.h: Added option MEM_USE_POOLS_TRY_BIGGER_POOL to try the next
+    bigger malloc pool if one is empty (only usable with MEM_USE_POOLS).
+
+  2009-04-21 Simon Goldschmidt
+  * dns.c, init.c, dns.h, opt.h: task #7507, patch #6786: DNS supports static
+    hosts table. New configuration options DNS_LOCAL_HOSTLIST and
+    DNS_LOCAL_HOSTLIST_IS_DYNAMIC. Also, DNS_LOOKUP_LOCAL_EXTERN() can be defined
+    as an external function for lookup.
+
+  2009-04-15 Simon Goldschmidt
+  * dhcp.c: patch #6763: Global DHCP XID can be redefined to something more unique
+
+  2009-03-31 Kieran Mansley
+  * tcp.c, tcp_out.c, tcp_in.c, sys.h, tcp.h, opts.h: add support for
+    TCP timestamp options, off by default.  Rework tcp_enqueue() to
+    take option flags rather than specified option data
+
+  2009-02-18 Simon Goldschmidt
+  * cc.h: Added printf formatter for size_t: SZT_F
+
+  2009-02-16 Simon Goldschmidt (patch by Rishi Khan)
+  * icmp.c, opt.h: patch #6539: (configurable) response to broadcast- and multicast
+    pings
+
+  2009-02-12 Simon Goldschmidt
+  * init.h: Added LWIP_VERSION to get the current version of the stack
+
+  2009-02-11 Simon Goldschmidt (suggested by Gottfried Spitaler)
+  * opt.h, memp.h/.c: added MEMP_MEM_MALLOC to use mem_malloc/mem_free instead
+    of the pool allocator (can save code size with MEM_LIBC_MALLOC if libc-malloc
+    is otherwise used)
+
+  2009-01-28 Jonathan Larmour (suggested by Bill Bauerbach)
+  * ipv4/inet_chksum.c, ipv4/lwip/inet_chksum.h: inet_chksum_pseudo_partial()
+  is only used by UDPLITE at present, so conditionalise it.
+
+  2008-12-03 Simon Goldschmidt (base on patch from Luca Ceresoli)
+  * autoip.c: checked in (slightly modified) patch #6683: Customizable AUTOIP
+    "seed" address. This should reduce AUTOIP conflicts if
+    LWIP_AUTOIP_CREATE_SEED_ADDR is overridden.
+
+  2008-10-02 Jonathan Larmour and Rishi Khan
+  * sockets.c (lwip_accept): Return EWOULDBLOCK if would block on non-blocking
+    socket.
+
+  2008-06-30 Simon Goldschmidt
+  * mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from
+    interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows
+    mem_free to run between mem_malloc iterations. Added illegal counter for
+    mem stats.
+
+  2008-06-27 Simon Goldschmidt
+  * stats.h/.c, some other files: patch #6483: stats module improvement:
+    Added defines to display each module's statistic individually, added stats
+    defines for MEM, MEMP and SYS modules, removed (unused) rexmit counter.
+
+  2008-06-17 Simon Goldschmidt
+  * err.h: patch #6459: Made err_t overridable to use a more efficient type
+    (define LWIP_ERR_T in cc.h)
+
+  2008-06-17 Simon Goldschmidt
+  * slipif.c: patch #6480: Added a configuration option for slipif for symmetry
+    to loopif
+
+  2008-06-17 Simon Goldschmidt (patch by Luca Ceresoli)
+  * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly
+    modified version of patch # 6370: Moved loopif code to netif.c so that
+    loopback traffic is supported on all netifs (all local IPs).
+    Added option to limit loopback packets for each netifs.
+
+
+  ++ Bugfixes:
+  2009-08-12 Kieran Mansley
+  * tcp_in.c, tcp.c: Fix bug #27209: handle trimming of segments when
+    out of window or out of order properly
+
+  2009-08-12 Kieran Mansley
+  * tcp_in.c: Fix bug #27199: use snd_wl2 instead of snd_wl1
+
+  2009-07-28 Simon Goldschmidt
+  * mem.h: Fixed bug #27105: "realloc() cannot replace mem_realloc()"s
+
+  2009-07-27 Kieran Mansley
+  * api.h api_msg.h netdb.h sockets.h: add missing #include directives
+
+  2009-07-09 Kieran Mansley
+  * api_msg.c, sockets.c, api.h: BUG23240 use signed counters for
+    recv_avail and don't increment counters until message successfully
+    sent to mbox
+
+  2009-06-25 Kieran Mansley
+  * api_msg.c api.h: BUG26722: initialise netconn write variables 
+    in netconn_alloc
+
+  2009-06-25 Kieran Mansley
+  * tcp.h: BUG26879: set ret value in TCP_EVENT macros when function is not set
+
+  2009-06-25 Kieran Mansley
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: BUG26301 and BUG26267: correct
+    simultaneous close behaviour, and make snd_nxt have the same meaning 
+    as in the RFCs.
+
+  2009-05-12 Simon Goldschmidt
+  * etharp.h, etharp.c, netif.c: fixed bug #26507: "Gratuitous ARP depends on
+    arp_table / uses etharp_query" by adding etharp_gratuitous()
+
+  2009-05-12 Simon Goldschmidt
+  * ip.h, ip.c, igmp.c: bug #26487: Added ip_output_if_opt that can add IP options
+    to the IP header (used by igmp_ip_output_if)
+
+  2009-05-06 Simon Goldschmidt
+  * inet_chksum.c: On little endian architectures, use LWIP_PLATFORM_HTONS (if
+    defined) for SWAP_BYTES_IN_WORD to speed up checksumming.
+
+  2009-05-05 Simon Goldschmidt
+  * sockets.c: bug #26405: Prematurely released semaphore causes lwip_select()
+    to crash
+
+  2009-05-04 Simon Goldschmidt
+  * init.c: snmp was not initialized in lwip_init()
+
+  2009-05-04 Frédéric Bernon
+  * dhcp.c, netbios.c: Changes if IP_SOF_BROADCAST is enabled.
+
+  2009-05-03 Simon Goldschmidt
+  * tcp.h: bug #26349: Nagle algorithm doesn't send although segment is full
+    (and unsent->next == NULL)
+
+  2009-05-02 Simon Goldschmidt
+  * tcpip.h, tcpip.c: fixed tcpip_untimeout (does not need the time, broken after
+    1.3.0 in CVS only) - fixes compilation of ppp_oe.c
+
+  2009-05-02 Simon Goldschmidt
+  * msg_in.c: fixed bug #25636: SNMPSET value is ignored for integer fields
+
+  2009-05-01 Simon Goldschmidt
+  * pap.c: bug #21680: PPP upap_rauthnak() drops legal NAK packets
+
+  2009-05-01 Simon Goldschmidt
+  * ppp.c: bug #24228: Memory corruption with PPP and DHCP
+
+  2009-04-29 Frédéric Bernon
+  * raw.c, udp.c, init.c, opt.h, ip.h, sockets.h: bug #26309: Implement the
+    SO(F)_BROADCAST filter for all API layers. Avoid the unindented reception
+    of broadcast packets even when this option wasn't set. Port maintainers
+    which want to enable this filter have to set IP_SOF_BROADCAST=1 in opt.h.
+    If you want this option also filter broadcast on recv operations, you also
+    have to set IP_SOF_BROADCAST_RECV=1 in opt.h.
+
+  2009-04-28 Simon Goldschmidt, Jakob Stoklund Olesen
+  * dhcp.c: patch #6721, bugs #25575, #25576: Some small fixes to DHCP and
+    DHCP/AUTOIP cooperation
+
+  2009-04-25 Simon Goldschmidt, Oleg Tyshev
+  * tcp_out.c: bug #24212: Deadlocked tcp_retransmit due to exceeded pcb->cwnd
+    Fixed by sorting the unsent and unacked queues (segments are inserted at the
+    right place in tcp_output and tcp_rexmit).
+
+  2009-04-25 Simon Goldschmidt
+  * memp.c, mem.c, memp.h, mem_std.h: bug #26213 "Problem with memory allocation
+    when debugging": memp_sizes contained the wrong sizes (including sanity
+    regions); memp pools for MEM_USE_POOLS were too small
+
+  2009-04-24 Simon Goldschmidt, Frédéric Bernon
+  * inet.c: patch #6765: Fix a small problem with the last changes (incorrect
+    behavior, with with ip address string not ended by a '\0', a space or a
+    end of line)
+
+  2009-04-19 Simon Goldschmidt
+  * rawapi.txt: Fixed bug #26069: Corrected documentation: if tcp_connect fails,
+    pcb->err is called, not pcb->connected (with an error code).
+
+  2009-04-19 Simon Goldschmidt
+  * tcp_out.c: Fixed bug #26236: "TCP options (timestamp) don't work with
+    no-copy-tcpwrite": deallocate option data, only concat segments with same flags
+
+  2009-04-19 Simon Goldschmidt
+  * tcp_out.c: Fixed bug #25094: "Zero-length pbuf" (options are now allocated
+    in the header pbuf, not the data pbuf)
+
+  2009-04-18 Simon Goldschmidt
+  * api_msg.c: fixed bug #25695: Segmentation fault in do_writemore()
+
+  2009-04-15 Simon Goldschmidt
+  * sockets.c: tried to fix bug #23559: lwip_recvfrom problem with tcp
+
+  2009-04-15 Simon Goldschmidt
+  * dhcp.c: task #9192: mem_free of dhcp->options_in and dhcp->msg_in
+
+  2009-04-15 Simon Goldschmidt
+  * ip.c, ip6.c, tcp_out.c, ip.h: patch #6808: Add a utility function
+    ip_hinted_output() (for smaller code mainly)
+
+  2009-04-15 Simon Goldschmidt
+  * inet.c: patch #6765: Supporting new line characters in inet_aton()
+
+  2009-04-15 Simon Goldschmidt
+  * dhcp.c: patch #6764: DHCP rebind and renew did not send hostnam option;
+    Converted constant OPTION_MAX_MSG_SIZE to netif->mtu, check if netif->mtu
+    is big enough in dhcp_start
+
+  2009-04-15 Simon Goldschmidt
+  * netbuf.c: bug #26027: netbuf_chain resulted in pbuf memory leak
+
+  2009-04-15 Simon Goldschmidt
+  * sockets.c, ppp.c: bug #25763: corrected 4 occurrences of SMEMCPY to MEMCPY
+
+  2009-04-15 Simon Goldschmidt
+  * sockets.c: bug #26121: set_errno can be overridden
+
+  2009-04-09 Kieran Mansley (patch from Luca Ceresoli <lucaceresoli>)
+  * init.c, opt.h: Patch#6774 TCP_QUEUE_OOSEQ breaks compilation when
+    LWIP_TCP==0
+
+  2009-04-09 Kieran Mansley (patch from Roy Lee <roylee17>)
+  * tcp.h: Patch#6802 Add do-while-clauses to those function like
+    macros in tcp.h
+
+  2009-03-31 Kieran Mansley
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h, opt.h: Rework the way window
+    updates are calculated and sent (BUG20515)
+
+  * tcp_in.c: cope with SYN packets received during established states,
+    and retransmission of initial SYN.
+
+  * tcp_out.c: set push bit correctly when tcp segments are merged
+
+  2009-03-27 Kieran Mansley
+  * tcp_out.c set window correctly on probes (correcting change made
+    yesterday)
+
+  2009-03-26 Kieran Mansley
+  * tcp.c, tcp_in.c, tcp.h: add tcp_abandon() to cope with dropping
+    connections where no reset required (bug #25622)
+
+  * tcp_out.c: set TCP_ACK flag on keepalive and zero window probes 
+    (bug #20779)
+
+  2009-02-18 Simon Goldschmidt (Jonathan Larmour and Bill Auerbach)
+  * ip_frag.c: patch #6528: the buffer used for IP_FRAG_USES_STATIC_BUF could be
+    too small depending on MEM_ALIGNMENT
+
+  2009-02-16 Simon Goldschmidt
+  * sockets.h/.c, api_*.h/.c: fixed arguments of socket functions to match the standard;
+    converted size argument of netconn_write to 'size_t'
+
+  2009-02-16 Simon Goldschmidt
+  * tcp.h, tcp.c: fixed bug #24440: TCP connection close problem on 64-bit host
+    by moving accept callback function pointer to TCP_PCB_COMMON
+
+  2009-02-12 Simon Goldschmidt
+  * dhcp.c: fixed bug #25345 (DHCPDECLINE is sent with "Maximum message size"
+    option)
+
+  2009-02-11 Simon Goldschmidt
+  * dhcp.c: fixed bug #24480 (releasing old udp_pdb and pbuf in dhcp_start)
+
+  2009-02-11 Simon Goldschmidt
+  * opt.h, api_msg.c: added configurable default valud for netconn->recv_bufsize:
+    RECV_BUFSIZE_DEFAULT (fixes bug #23726: pbuf pool exhaustion on slow recv())
+
+  2009-02-10 Simon Goldschmidt
+  * tcp.c: fixed bug #25467: Listen backlog is not reset on timeout in SYN_RCVD:
+    Accepts_pending is decrease on a corresponding listen pcb when a connection
+    in state SYN_RCVD is close.
+
+  2009-01-28 Jonathan Larmour
+  * pbuf.c: reclaim pbufs from TCP out-of-sequence segments if we run
+    out of pool pbufs.
+
+  2008-12-19 Simon Goldschmidt
+  * many files: patch #6699: fixed some warnings on platform where sizeof(int) == 2 
+
+  2008-12-10 Tamas Somogyi, Frédéric Bernon
+  * sockets.c: fixed bug #25051: lwip_recvfrom problem with udp: fromaddr and
+    port uses deleted netbuf.
+
+  2008-10-18 Simon Goldschmidt
+  * tcp_in.c: fixed bug ##24596: Vulnerability on faulty TCP options length
+    in tcp_parseopt
+
+  2008-10-15 Simon Goldschmidt
+  * ip_frag.c: fixed bug #24517: IP reassembly crashes on unaligned IP headers
+    by packing the struct ip_reass_helper.
+
+  2008-10-03 David Woodhouse, Jonathan Larmour
+  * etharp.c (etharp_arp_input): Fix type aliasing problem copying ip address.
+
+  2008-10-02 Jonathan Larmour
+  * dns.c: Hard-code structure sizes, to avoid issues on some compilers where
+    padding is included.
+
+  2008-09-30 Jonathan Larmour
+  * sockets.c (lwip_accept): check addr isn't NULL. If it's valid, do an
+    assertion check that addrlen isn't NULL.
+
+  2008-09-30 Jonathan Larmour
+  * tcp.c: Fix bug #24227, wrong error message in tcp_bind.
+
+  2008-08-26 Simon Goldschmidt
+  * inet.h, ip_addr.h: fixed bug #24132: Cross-dependency between ip_addr.h and
+    inet.h -> moved declaration of struct in_addr from ip_addr.h to inet.h
+
+  2008-08-14 Simon Goldschmidt
+  * api_msg.c: fixed bug #23847: do_close_internal references freed memory (when
+    tcp_close returns != ERR_OK)
+
+  2008-07-08 Frédéric Bernon
+  * stats.h: Fix some build bugs introduced with patch #6483 (missing some parameters
+    in macros, mainly if MEM_STATS=0 and MEMP_STATS=0).
+
+  2008-06-24 Jonathan Larmour
+  * tcp_in.c: Fix for bug #23693 as suggested by Art R. Ensure cseg is unused
+    if tcp_seg_copy fails.
+
+  2008-06-17 Simon Goldschmidt
+  * inet_chksum.c: Checked in some ideas of patch #6460 (loop optimizations)
+    and created defines for swapping bytes and folding u32 to u16.
+
+  2008-05-30 Kieran Mansley
+  * tcp_in.c Remove redundant "if" statement, and use real rcv_wnd
+    rather than rcv_ann_wnd when deciding if packets are in-window.
+    Contributed by <arasmussen@consultant.datasys.swri.edu>
+
+  2008-05-30 Kieran Mansley
+  * mem.h: Fix BUG#23254.  Change macro definition of mem_* to allow
+    passing as function pointers when MEM_LIBC_MALLOC is defined.
+
+  2008-05-09 Jonathan Larmour
+  * err.h, err.c, sockets.c: Fix bug #23119: Reorder timeout error code to
+    stop it being treated as a fatal error.
+
+  2008-04-15 Simon Goldschmidt
+  * dhcp.c: fixed bug #22804: dhcp_stop doesn't clear NETIF_FLAG_DHCP
+    (flag now cleared)
+
+  2008-03-27 Simon Goldschmidt
+  * mem.c, tcpip.c, tcpip.h, opt.h: fixed bug #21433 (Calling mem_free/pbuf_free
+    from interrupt context isn't safe): set LWIP_USE_HEAP_FROM_INTERRUPT to 1
+    in lwipopts.h or use pbuf_free_callback(p)/mem_free_callback(m) to free pbufs
+    or heap memory from interrupt context
+
+  2008-03-26 Simon Goldschmidt
+  * tcp_in.c, tcp.c: fixed bug #22249: division by zero could occur if a remote
+    host sent a zero mss as TCP option.
+
+
+(STABLE-1.3.0)
+
+  ++ New features:
+
+  2008-03-10 Jonathan Larmour
+  * inet_chksum.c: Allow choice of one of the sample algorithms to be
+    made from lwipopts.h. Fix comment on how to override LWIP_CHKSUM.
+
+  2008-01-22 Frédéric Bernon
+  * tcp.c, tcp_in.c, tcp.h, opt.h: Rename LWIP_CALCULATE_EFF_SEND_MSS in 
+    TCP_CALCULATE_EFF_SEND_MSS to have coherent TCP options names.
+
+  2008-01-14 Frédéric Bernon
+  * rawapi.txt, api_msg.c, tcp.c, tcp_in.c, tcp.h: changes for task #7675 "Enable
+    to refuse data on a TCP_EVENT_RECV call". Important, behavior changes for the
+    tcp_recv callback (see rawapi.txt).
+
+  2008-01-14 Frédéric Bernon, Marc Chaland
+  * ip.c: Integrate patch #6369" ip_input : checking before realloc".
+  
+  2008-01-12 Frédéric Bernon
+  * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field
+    netconn::sem per netconn::op_completed like suggested for the task #7490
+    "Add return value to sys_mbox_post".
+
+  2008-01-12 Frédéric Bernon
+  * api_msg.c, opt.h: replace DEFAULT_RECVMBOX_SIZE per DEFAULT_TCP_RECVMBOX_SIZE,
+    DEFAULT_UDP_RECVMBOX_SIZE and DEFAULT_RAW_RECVMBOX_SIZE (to optimize queues
+    sizes), like suggested for the task #7490 "Add return value to sys_mbox_post".
+
+  2008-01-10 Frédéric Bernon
+  * tcpip.h, tcpip.c: add tcpip_callback_with_block function for the task #7490
+    "Add return value to sys_mbox_post". tcpip_callback is always defined as
+    "blocking" ("block" parameter = 1).
+
+  2008-01-10 Frédéric Bernon
+  * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field
+    netconn::mbox (sys_mbox_t) per netconn::sem (sys_sem_t) for the task #7490
+    "Add return value to sys_mbox_post".
+
+  2008-01-05 Frédéric Bernon
+  * sys_arch.txt, api.h, api_lib.c, api_msg.h, api_msg.c, tcpip.c, sys.h, opt.h:
+    Introduce changes for task #7490 "Add return value to sys_mbox_post" with some
+    modifications in the sys_mbox api: sys_mbox_new take a "size" parameters which
+    indicate the number of pointers query by the mailbox. There is three defines
+    in opt.h to indicate sizes for tcpip::mbox, netconn::recvmbox, and for the 
+    netconn::acceptmbox. Port maintainers, you can decide to just add this new 
+    parameter in your implementation, but to ignore it to keep the previous behavior.
+    The new sys_mbox_trypost function return a value to know if the mailbox is
+    full or if the message is posted. Take a look to sys_arch.txt for more details.
+    This new function is used in tcpip_input (so, can be called in an interrupt
+    context since the function is not blocking), and in recv_udp and recv_raw.
+
+  2008-01-04 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour
+  * rawapi.txt, api.h, api_lib.c, api_msg.h, api_msg.c, sockets.c, tcp.h, tcp.c,
+    tcp_in.c, init.c, opt.h: rename backlog options with TCP_ prefix, limit the
+    "backlog" parameter in an u8_t, 0 is interpreted as "smallest queue", add
+    documentation in the rawapi.txt file.
+
+  2007-12-31 Kieran Mansley (based on patch from Per-Henrik Lundbolm)
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Add TCP persist timer
+
+  2007-12-31 Frédéric Bernon, Luca Ceresoli
+  * autoip.c, etharp.c: ip_addr.h: Integrate patch #6348: "Broadcast ARP packets
+    in autoip". The change in etharp_raw could be removed, since all calls to
+    etharp_raw use ethbroadcast for the "ethdst_addr" parameter. But it could be
+    wrong in the future.
+
+  2007-12-30 Frédéric Bernon, Tom Evans
+  * ip.c: Fix bug #21846 "LwIP doesn't appear to perform any IP Source Address
+    Filtering" reported by Tom Evans.
+
+  2007-12-21 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour
+  * tcp.h, opt.h, api.h, api_msg.h, tcp.c, tcp_in.c, api_lib.c, api_msg.c,
+    sockets.c, init.c: task #7252: Implement TCP listen backlog: Warning: raw API
+    applications have to call 'tcp_accepted(pcb)' in their accept callback to
+    keep accepting new connections.
+
+  2007-12-13 Frédéric Bernon
+  * api_msg.c, err.h, err.c, sockets.c, dns.c, dns.h: replace "enum dns_result"
+    by err_t type. Add a new err_t code "ERR_INPROGRESS".
+
+  2007-12-12 Frédéric Bernon
+  * dns.h, dns.c, opt.h: move DNS options to the "right" place. Most visibles
+    are the one which have ram usage.
+
+  2007-12-05 Frédéric Bernon
+  * netdb.c: add a LWIP_DNS_API_HOSTENT_STORAGE option to decide to use a static
+    set of variables (=0) or a local one (=1). In this last case, your port should
+    provide a function "struct hostent* sys_thread_hostent( struct hostent* h)"
+    which have to do a copy of "h" and return a pointer ont the "per-thread" copy.
+
+  2007-12-03 Simon Goldschmidt
+  * ip.c: ip_input: check if a packet is for inp first before checking all other
+    netifs on netif_list (speeds up packet receiving in most cases)
+
+  2007-11-30 Simon Goldschmidt
+  * udp.c, raw.c: task #7497: Sort lists (pcb, netif, ...) for faster access
+    UDP: move a (connected) pcb selected for input to the front of the list of
+    pcbs so that it is found faster next time. Same for RAW pcbs that have eaten
+    a packet.
+
+  2007-11-28 Simon Goldschmidt
+  * etharp.c, stats.c, stats.h, opt.h: Introduced ETHARP_STATS
+
+  2007-11-25 Simon Goldschmidt
+  * dhcp.c: dhcp_unfold_reply() uses pbuf_copy_partial instead of its own copy
+    algorithm.
+
+  2007-11-24 Simon Goldschmidt
+  * netdb.h, netdb.c, sockets.h/.c: Moved lwip_gethostbyname from sockets.c
+    to the new file netdb.c; included lwip_getaddrinfo.
+
+  2007-11-21 Simon Goldschmidt
+  * tcp.h, opt.h, tcp.c, tcp_in.c: implemented calculating the effective send-mss
+    based on the MTU of the netif used to send. Enabled by default. Disable by
+    setting LWIP_CALCULATE_EFF_SEND_MSS to 0. This fixes bug #21492.
+
+  2007-11-19 Frédéric Bernon
+  * api_msg.c, dns.h, dns.c: Implement DNS_DOES_NAME_CHECK option (check if name
+    received match the name query), implement DNS_USES_STATIC_BUF (the place where
+    copy dns payload to parse the response), return an error if there is no place
+    for a new query, and fix some minor problems.
+
+  2007-11-16 Simon Goldschmidt
+  * new files: ipv4/inet.c, ipv4/inet_chksum.c, ipv6/inet6.c
+    removed files: core/inet.c, core/inet6.c
+    Moved inet files into ipv4/ipv6 directory; splitted inet.c/inet.h into
+    inet and chksum part; changed includes in all lwIP files as appropriate
+
+  2007-11-16 Simon Goldschmidt
+  * api.h, api_msg.h, api_lib.c, api_msg.c, socket.h, socket.c: Added sequential
+    dns resolver function for netconn api (netconn_gethostbyname) and socket api
+    (gethostbyname/gethostbyname_r).
+
+  2007-11-15 Jim Pettinato, Frédéric Bernon
+  * opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name
+    requests with RAW api interface. Initialization is done in lwip_init() with
+    build time options. DNS timer is added in tcpip_thread context. DHCP can set
+    DNS server ip addresses when options are received. You need to set LWIP_DNS=1
+    in your lwipopts.h file (LWIP_DNS=0 in opt.h). DNS_DEBUG can be set to get
+    some traces with LWIP_DEBUGF. Sanity check have been added. There is a "todo"
+    list with points to improve.
+
+  2007-11-06 Simon Goldschmidt
+  * opt.h, mib2.c: Patch #6215: added ifAdminStatus write support (if explicitly
+    enabled by defining SNMP_SAFE_REQUESTS to 0); added code to check link status
+    for ifOperStatus if LWIP_NETIF_LINK_CALLBACK is defined.
+
+  2007-11-06 Simon Goldschmidt
+  * api.h, api_msg.h and dependent files: Task #7410: Removed the need to include
+    core header files in api.h (ip/tcp/udp/raw.h) to hide the internal
+    implementation from netconn api applications.
+
+  2007-11-03 Frédéric Bernon
+  * api.h, api_lib.c, api_msg.c, sockets.c, opt.h: add SO_RCVBUF option for UDP &
+    RAW netconn. You need to set LWIP_SO_RCVBUF=1 in your lwipopts.h (it's disabled
+    by default). Netconn API users can use the netconn_recv_bufsize macro to access
+    it. This is a first release which have to be improve for TCP. Note it used the
+    netconn::recv_avail which need to be more "thread-safe" (note there is already
+    the problem for FIONREAD with lwip_ioctl/ioctlsocket).
+
+  2007-11-01 Frédéric Bernon, Marc Chaland
+  * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c:
+    Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api
+    layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api
+    layer. This option enable to delayed TCP PUSH flag on multiple "write" calls.
+    Note that previous "copy" parameter for "write" APIs is now called "apiflags".
+
+  2007-10-24 Frédéric Bernon
+  * api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than 
+    TCP_EVENT_xxx macros to get a code more readable. It could also help to remove
+    some code (like we have talk in "patch #5919 : Create compile switch to remove
+    select code"), but it could be done later.
+
+  2007-10-08 Simon Goldschmidt
+  * many files: Changed initialization: many init functions are not needed any
+    more since we now rely on the compiler initializing global and static
+    variables to zero!
+
+  2007-10-06 Simon Goldschmidt
+  * ip_frag.c, memp.c, mib2.c, ip_frag.h, memp_std.h, opt.h: Changed IP_REASSEMBLY
+    to enqueue the received pbufs so that multiple packets can be reassembled
+    simultaneously and no static reassembly buffer is needed.
+
+  2007-10-05 Simon Goldschmidt
+  * tcpip.c, etharp.h, etharp.c: moved ethernet_input from tcpip.c to etharp.c so
+    all netifs (or ports) can use it.
+
+  2007-10-05 Frédéric Bernon
+  * netifapi.h, netifapi.c: add function netifapi_netif_set_default. Change the 
+    common function to reduce a little bit the footprint (for all functions using
+    only the "netif" parameter).
+
+  2007-10-03 Frédéric Bernon
+  * netifapi.h, netifapi.c: add functions netifapi_netif_set_up, netifapi_netif_set_down,
+    netifapi_autoip_start and netifapi_autoip_stop. Use a common function to reduce
+    a little bit the footprint (for all functions using only the "netif" parameter).
+
+  2007-09-15 Frédéric Bernon
+  * udp.h, udp.c, sockets.c: Changes for "#20503 IGMP Improvement". Add IP_MULTICAST_IF
+    option in socket API, and a new field "multicast_ip" in "struct udp_pcb" (for
+    netconn and raw API users), only if LWIP_IGMP=1. Add getsockopt processing for
+    IP_MULTICAST_TTL and IP_MULTICAST_IF.
+
+  2007-09-10 Frédéric Bernon
+  * snmp.h, mib2.c: enable to remove SNMP timer (which consumne several cycles
+    even when it's not necessary). snmp_agent.txt tell to call snmp_inc_sysuptime()
+    each 10ms (but, it's intrusive if you use sys_timeout feature). Now, you can
+    decide to call snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but
+    call to a lower frequency). Or, you can decide to not call snmp_inc_sysuptime()
+    or snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro.
+    This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside
+    snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only
+    when it's queried (any direct call to "sysuptime" is changed by a call to 
+    snmp_get_sysuptime).
+
+  2007-09-09 Frédéric Bernon, Bill Florac
+  * igmp.h, igmp.c, netif.h, netif.c, ip.c: To enable to have interfaces with IGMP,
+    and others without it, there is a new NETIF_FLAG_IGMP flag to set in netif->flags
+    if you want IGMP on an interface. igmp_stop() is now called inside netif_remove().
+    igmp_report_groups() is now called inside netif_set_link_up() (need to have
+    LWIP_NETIF_LINK_CALLBACK=1) to resend reports once the link is up (avoid to wait
+    the next query message to receive the matching multicast streams).
+
+  2007-09-08 Frédéric Bernon
+  * sockets.c, ip.h, api.h, tcp.h: declare a "struct ip_pcb" which only contains
+    IP_PCB. Add in the netconn's "pcb" union a "struct ip_pcb *ip;" (no size change).
+    Use this new field to access to common pcb fields (ttl, tos, so_options, etc...).
+    Enable to access to these fields with LWIP_TCP=0.
+
+  2007-09-05 Frédéric Bernon
+  * udp.c, ipv4/icmp.c, ipv4/ip.c, ipv6/icmp.c, ipv6/ip6.c, ipv4/icmp.h,
+    ipv6/icmp.h, opt.h: Integrate "task #7272 : LWIP_ICMP option". The new option
+    LWIP_ICMP enable/disable ICMP module inside the IP stack (enable per default).
+    Be careful, disabling ICMP make your product non-compliant to RFC1122, but
+    help to reduce footprint, and to reduce "visibility" on the Internet.
+
+  2007-09-05 Frédéric Bernon, Bill Florac
+  * opt.h, sys.h, tcpip.c, slipif.c, ppp.c, sys_arch.txt: Change parameters list
+    for sys_thread_new (see "task #7252 : Create sys_thread_new_ex()"). Two new
+    parameters have to be provided: a task name, and a task stack size. For this
+    one, since it's platform dependant, you could define the best one for you in
+    your lwipopts.h. For port maintainers, you can just add these new parameters
+    in your sys_arch.c file, and but it's not mandatory, use them in your OS
+    specific functions.
+
+  2007-09-05 Frédéric Bernon
+  * inet.c, autoip.c, msg_in.c, msg_out.c, init.c: Move some build time checkings
+    inside init.c for task #7142 "Sanity check user-configurable values".
+
+  2007-09-04 Frédéric Bernon, Bill Florac
+  * igmp.h, igmp.c, memp_std.h, memp.c, init.c, opt.h: Replace mem_malloc call by
+    memp_malloc, and use a new MEMP_NUM_IGMP_GROUP option (see opt.h to define the
+    value). It will avoid potential fragmentation problems, use a counter to know
+    how many times a group is used on an netif, and free it when all applications
+    leave it. MEMP_NUM_IGMP_GROUP got 8 as default value (and init.c got a sanity
+    check if LWIP_IGMP!=0).
+
+  2007-09-03 Frédéric Bernon
+  * igmp.h, igmp.c, sockets.c, api_msg.c: Changes for "#20503 IGMP Improvement".
+    Initialize igmp_mac_filter to NULL in netif_add (this field should be set in
+    the netif's "init" function). Use the "imr_interface" field (for socket layer)
+    and/or the "interface" field (for netconn layer), for join/leave operations.
+    The igmp_join/leavegroup first parameter change from a netif to an ipaddr.
+    This field could be a netif's ipaddr, or "any" (same meaning than ip_addr_isany).
+
+  2007-08-30 Frédéric Bernon
+  * Add netbuf.h, netbuf.c, Change api.h, api_lib.c: #7249 "Split netbuf functions
+    from api/api_lib". Now netbuf API is independant of netconn, and can be used
+    with other API (application based on raw API, or future "socket2" API). Ports
+    maintainers just have to add src/api/netbuf.c in their makefile/projects.
+
+  2007-08-30 Frédéric Bernon, Jonathan Larmour
+  * init.c: Add first version of lwip_sanity_check for task #7142 "Sanity check
+    user-configurable values".
+
+  2007-08-29 Frédéric Bernon
+  * igmp.h, igmp.c, tcpip.c, init.c, netif.c: change igmp_init and add igmp_start.
+    igmp_start is call inside netif_add. Now, igmp initialization is in the same
+    spirit than the others modules. Modify some IGMP debug traces.
+
+  2007-08-29 Frédéric Bernon
+  * Add init.h, init.c, Change opt.h, tcpip.c: Task  #7213 "Add a lwip_init function"
+    Add lwip_init function to regroup all modules initializations, and to provide
+    a place to add code for task #7142 "Sanity check user-configurable values".
+    Ports maintainers should remove direct initializations calls from their code,
+    and add init.c in their makefiles. Note that lwip_init() function is called
+    inside tcpip_init, but can also be used by raw api users since all calls are
+    disabled when matching options are disabled. Also note that their is new options
+    in opt.h, you should configure in your lwipopts.h (they are enabled per default).
+
+  2007-08-26 Marc Boucher
+  * api_msg.c: do_close_internal(): Reset the callbacks and arg (conn) to NULL
+    since they can under certain circumstances be called with an invalid conn
+    pointer after the connection has been closed (and conn has been freed). 
+
+  2007-08-25 Frédéric Bernon (Artem Migaev's Patch)
+  * netif.h, netif.c: Integrate "patch #6163 : Function to check if link layer is up".
+    Add a netif_is_link_up() function if LWIP_NETIF_LINK_CALLBACK option is set.
+
+  2007-08-22 Frédéric Bernon
+  * netif.h, netif.c, opt.h: Rename LWIP_NETIF_CALLBACK in LWIP_NETIF_STATUS_CALLBACK
+    to be coherent with new LWIP_NETIF_LINK_CALLBACK option before next release.
+
+  2007-08-22 Frédéric Bernon
+  * tcpip.h, tcpip.c, ethernetif.c, opt.h: remove options ETHARP_TCPIP_INPUT &
+    ETHARP_TCPIP_ETHINPUT, now, only "ethinput" code is supported, even if the 
+    name is tcpip_input (we keep the name of 1.2.0 function).
+
+  2007-08-17 Jared Grubb
+  * memp_std.h, memp.h, memp.c, mem.c, stats.c: (Task #7136) Centralize mempool 
+    settings into new memp_std.h and optional user file lwippools.h. This adds
+    more dynamic mempools, and allows the user to create an arbitrary number of
+    mempools for mem_malloc.
+
+  2007-08-16 Marc Boucher
+  * api_msg.c: Initialize newconn->state to NETCONN_NONE in accept_function;
+    otherwise it was left to NETCONN_CLOSE and sent_tcp() could prematurely
+    close the connection.
+
+  2007-08-16 Marc Boucher
+  * sockets.c: lwip_accept(): check netconn_peer() error return.
+
+  2007-08-16 Marc Boucher
+  * mem.c, mem.h: Added mem_calloc().
+
+  2007-08-16 Marc Boucher
+  * tcpip.c, tcpip.h memp.c, memp.h: Added distinct memp (MEMP_TCPIP_MSG_INPKT)
+    for input packets to prevent floods from consuming all of MEMP_TCPIP_MSG
+    and starving other message types.
+    Renamed MEMP_TCPIP_MSG to MEMP_TCPIP_MSG_API
+
+  2007-08-16 Marc Boucher
+  * pbuf.c, pbuf.h, etharp.c, tcp_in.c, sockets.c: Split pbuf flags in pbuf
+    type and flgs (later renamed to flags).
+    Use enum pbuf_flag as pbuf_type.  Renumber PBUF_FLAG_*.
+    Improved lwip_recvfrom().  TCP push now propagated.
+
+  2007-08-16 Marc Boucher
+  * ethernetif.c, contrib/ports/various: ethbroadcast now a shared global
+    provided by etharp.
+
+  2007-08-16 Marc Boucher
+  * ppp_oe.c ppp_oe.h, auth.c chap.c fsm.c lcp.c ppp.c ppp.h,
+    etharp.c ethernetif.c, etharp.h, opt.h tcpip.h, tcpip.c:
+    Added PPPoE support and various PPP improvements.
+
+  2007-07-25 Simon Goldschmidt
+  * api_lib.c, ip_frag.c, pbuf.c, api.h, pbuf.h: Introduced pbuf_copy_partial,
+    making netbuf_copy_partial use this function.
+
+  2007-07-25 Simon Goldschmidt
+  * tcp_in.c: Fix bug #20506: Slow start / initial congestion window starts with
+    2 * mss (instead of 1 * mss previously) to comply with some newer RFCs and
+    other stacks.
+
+  2007-07-13 Jared Grubb (integrated by Frédéric Bernon)
+  * opt.h, netif.h, netif.c, ethernetif.c: Add new configuration option to add
+    a link callback in the netif struct, and functions to handle it. Be carefull
+    for port maintainers to add the NETIF_FLAG_LINK_UP flag (like in ethernetif.c)
+    if you want to be sure to be compatible with future changes...
+
+  2007-06-30 Frédéric Bernon
+  * sockets.h, sockets.c: Implement MSG_PEEK flag for recv/recvfrom functions.
+
+  2007-06-21 Simon Goldschmidt
+  * etharp.h, etharp.c: Combined etharp_request with etharp_raw for both
+    LWIP_AUTOIP =0 and =1 to remove redundant code.
+
+  2007-06-21 Simon Goldschmidt
+  * mem.c, memp.c, mem.h, memp.h, opt.h: task #6863: Introduced the option
+    MEM_USE_POOLS to use 4 pools with different sized elements instead of a
+    heap. This both prevents memory fragmentation and gives a higher speed
+    at the cost of more memory consumption. Turned off by default.
+
+  2007-06-21 Simon Goldschmidt
+  * api_lib.c, api_msg.c, api.h, api_msg.h: Converted the length argument of
+    netconn_write (and therefore also api_msg_msg.msg.w.len) from u16_t into
+    int to be able to send a bigger buffer than 64K with one time (mainly
+    used from lwip_send).
+
+  2007-06-21 Simon Goldschmidt
+  * tcp.h, api_msg.c: Moved the nagle algorithm from netconn_write/do_write
+    into a define (tcp_output_nagle) in tcp.h to provide it to raw api users, too.
+
+  2007-06-21 Simon Goldschmidt
+  * api.h, api_lib.c, api_msg.c: Fixed bug #20021: Moved sendbuf-processing in
+    netconn_write from api_lib.c to api_msg.c to also prevent multiple context-
+    changes on low memory or empty send-buffer.
+
+  2007-06-18 Simon Goldschmidt
+  * etharp.c, etharp.h: Changed etharp to use a defined hardware address length
+    of 6 to avoid loading netif->hwaddr_len every time (since this file is only
+    used for ethernet and struct eth_addr already had a defined length of 6).
+
+  2007-06-17 Simon Goldschmidt
+  * sockets.c, sockets.h: Implemented socket options SO_NO_CHECK for UDP sockets
+    to disable UDP checksum generation on transmit.
+
+  2007-06-13 Frédéric Bernon, Simon Goldschmidt
+  * debug.h, api_msg.c: change LWIP_ERROR to use it to check errors like invalid
+    pointers or parameters, and let the possibility to redefined it in cc.h. Use
+    this macro to check "conn" parameter in api_msg.c functions.
+
+  2007-06-11 Simon Goldschmidt
+  * sockets.c, sockets.h: Added UDP lite support for sockets
+
+  2007-06-10 Simon Goldschmidt
+  * udp.h, opt.h, api_msg.c, ip.c, udp.c: Included switch LWIP_UDPLITE (enabled
+    by default) to switch off UDP-Lite support if not needed (reduces udp.c code
+    size)
+
+  2007-06-09 Dominik Spies (integrated by Frédéric Bernon)
+  * autoip.h, autoip.c, dhcp.h, dhcp.c, netif.h, netif.c, etharp.h, etharp.c, opt.h:
+    AutoIP implementation available for IPv4, with new options LWIP_AUTOIP and
+    LWIP_DHCP_AUTOIP_COOP if you want to cooperate with DHCP. Some tips to adapt
+    (see TODO mark in the source code).
+
+  2007-06-09 Simon Goldschmidt
+  * etharp.h, etharp.c, ethernetif.c: Modified order of parameters for
+    etharp_output() to match netif->output so etharp_output() can be used
+    directly as netif->output to save one function call.
+
+  2007-06-08 Simon Goldschmidt
+  * netif.h, ethernetif.c, slipif.c, loopif.c: Added define
+    NETIF_INIT_SNMP(netif, type, speed) to initialize per-netif snmp variables,
+    added initialization of those to ethernetif, slipif and loopif.
+
+  2007-05-18 Simon Goldschmidt
+  * opt.h, ip_frag.c, ip_frag.h, ip.c: Added option IP_FRAG_USES_STATIC_BUF
+    (defaulting to off for now) that can be set to 0 to send fragmented
+    packets by passing PBUF_REFs down the stack.
+
+  2007-05-23 Frédéric Bernon
+  * api_lib.c: Implement SO_RCVTIMEO for accept and recv on TCP
+    connections, such present in patch #5959.
+
+  2007-05-23 Frédéric Bernon
+  * api.h, api_lib.c, api_msg.c, sockets.c: group the different NETCONN_UDPxxx
+    code in only one part...
+
+  2007-05-18 Simon Goldschmidt
+  * opt.h, memp.h, memp.c: Added option MEMP_OVERFLOW_CHECK to check for memp
+    elements to overflow. This is achieved by adding some bytes before and after
+    each pool element (increasing their size, of course), filling them with a
+    prominent value and checking them on freeing the element.
+    Set it to 2 to also check every element in every pool each time memp_malloc()
+    or memp_free() is called (slower but more helpful).
+
+  2007-05-10 Simon Goldschmidt
+  * opt.h, memp.h, memp.c, pbuf.c (see task #6831): use a new memp pool for
+    PBUF_POOL pbufs instead of the old pool implementation in pbuf.c to reduce
+    code size.
+
+  2007-05-11 Frédéric Bernon
+  * sockets.c, api_lib.c, api_msg.h, api_msg.c, netifapi.h, netifapi.c, tcpip.c:
+    Include a function pointer instead of a table index in the message to reduce
+    footprint. Disable some part of lwip_send and lwip_sendto if some options are
+    not set (LWIP_TCP, LWIP_UDP, LWIP_RAW).
+
+  2007-05-10 Simon Goldschmidt
+  * *.h (except netif/ppp/*.h): Included patch #5448: include '#ifdef __cplusplus
+    \ extern "C" {' in all header files. Now you can write your application using
+    the lwIP stack in C++ and simply #include the core files. Note I have left
+    out the netif/ppp/*h header files for now, since I don't know which files are
+    included by applications and which are for internal use only.
+
+  2007-05-09 Simon Goldschmidt
+  * opt.h, *.c/*.h: Included patch #5920: Create define to override C-library
+    memcpy. 2 Defines are created: MEMCPY() for normal memcpy, SMEMCPY() for
+    situations where some compilers might inline the copy and save a function
+    call. Also replaced all calls to memcpy() with calls to (S)MEMCPY().
+
+  2007-05-08 Simon Goldschmidt
+  * mem.h: If MEM_LIBC_MALLOC==1, allow the defines (e.g. mem_malloc() -> malloc())
+    to be overriden in case the C-library malloc implementation is not protected
+    against concurrent access.
+
+  2007-05-04 Simon Goldschmidt (Atte Kojo)
+  * etharp.c: Introduced fast one-entry-cache to speed up ARP lookup when sending
+    multiple packets to the same host.
+
+  2007-05-04 Frédéric Bernon, Jonathan Larmour
+  * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fix bug #19162 "lwip_sento: a possible
+    to corrupt remote addr/port connection state". Reduce problems "not enought memory" with
+    netbuf (if we receive lot of datagrams). Improve lwip_sendto (only one exchange between
+    sockets api and api_msg which run in tcpip_thread context). Add netconn_sento function.
+    Warning, if you directly access to "fromaddr" & "fromport" field from netbuf struct,
+    these fields are now renamed "addr" & "port".
+
+  2007-04-11 Jonathan Larmour
+  * sys.h, api_lib.c: Provide new sys_mbox_tryfetch function. Require ports to provide new
+    sys_arch_mbox_tryfetch function to get a message if one is there, otherwise return
+    with SYS_MBOX_EMPTY. sys_arch_mbox_tryfetch can be implemented as a function-like macro
+    by the port in sys_arch.h if desired.
+
+  2007-04-06 Frédéric Bernon, Simon Goldschmidt
+  * opt.h, tcpip.h, tcpip.c, netifapi.h, netifapi.c: New configuration option LWIP_NETIF_API
+    allow to use thread-safe functions to add/remove netif in list, and to start/stop dhcp
+    clients, using new functions from netifapi.h. Disable as default (no port change to do).
+
+  2007-04-05 Frédéric Bernon
+  * sockets.c: remplace ENOBUFS errors on alloc_socket by ENFILE to be more BSD compliant.
+
+  2007-04-04 Simon Goldschmidt
+  * arch.h, api_msg.c, dhcp.c, msg_in.c, sockets.c: Introduced #define LWIP_UNUSED_ARG(x)
+    use this for and architecture-independent form to tell the compiler you intentionally
+    are not using this variable. Can be overriden in cc.h.
+
+  2007-03-28 Frédéric Bernon
+  * opt.h, netif.h, dhcp.h, dhcp.c: New configuration option LWIP_NETIF_HOSTNAME allow to
+    define a hostname in netif struct (this is just a pointer, so, you can use a hardcoded
+    string, point on one of your's ethernetif field, or alloc a string you will free yourself).
+    It will be used by DHCP to register a client hostname, but can also be use when you call
+    snmp_set_sysname.
+
+  2007-03-28 Frédéric Bernon
+  * netif.h, netif.c: A new NETIF_FLAG_ETHARP flag is defined in netif.h, to allow to 
+    initialize a network interface's flag with. It tell this interface is an ethernet
+    device, and we can use ARP with it to do a "gratuitous ARP" (RFC 3220 "IP Mobility
+    Support for IPv4" section 4.6) when interface is "up" with netif_set_up().
+
+  2007-03-26 Frédéric Bernon, Jonathan Larmour
+  * opt.h, tcpip.c: New configuration option LWIP_ARP allow to disable ARP init at build
+    time if you only use PPP or SLIP. The default is enable. Note we don't have to call 
+    etharp_init in your port's initilization sequence if you use tcpip.c, because this call
+    is done in tcpip_init function.
+
+  2007-03-22 Frédéric Bernon
+  * stats.h, stats.c, msg_in.c: Stats counters can be change to u32_t if necessary with the
+    new option LWIP_STATS_LARGE. If you need this option, define LWIP_STATS_LARGE to 1 in
+    your lwipopts.h. More, unused counters are not defined in the stats structs, and not 
+    display by stats_display(). Note that some options (SYS_STATS and RAW_STATS) are defined
+    but never used. Fix msg_in.c with the correct #if test for a stat display.
+
+  2007-03-21 Kieran Mansley
+  * netif.c, netif.h: Apply patch#4197 with some changes (originator: rireland@hmgsl.com). 
+    Provides callback on netif up/down state change.
+
+  2007-03-11 Frédéric Bernon, Mace Gael, Steve Reynolds
+  * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, igmp.h, igmp.c,
+    ip.c, netif.h, tcpip.c, opt.h:
+    New configuration option LWIP_IGMP to enable IGMP processing. Based on only one 
+    filter per all network interfaces. Declare a new function in netif to enable to
+    control the MAC filter (to reduce lwIP traffic processing).
+
+  2007-03-11 Frédéric Bernon
+  * tcp.h, tcp.c, sockets.c, tcp_out.c, tcp_in.c, opt.h: Keepalive values can
+    be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this
+    unless you know what you're doing (default are RFC1122 compliant). Note
+    that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds.
+
+  2007-03-08 Frédéric Bernon
+  * tcp.h: Keepalive values can be configured at compile time, but don't change
+    this unless you know what you're doing (default are RFC1122 compliant).
+
+  2007-03-08 Frédéric Bernon
+  * sockets.c, api.h, api_lib.c, tcpip.c, sys.h, sys.c, err.c, opt.h:
+    Implement LWIP_SO_RCVTIMEO configuration option to enable/disable SO_RCVTIMEO
+    on UDP sockets/netconn.
+
+  2007-03-08 Simon Goldschmidt
+  * snmp_msg.h, msg_in.c: SNMP UDP ports can be configured at compile time.
+
+  2007-03-06 Frédéric Bernon
+  * api.h, api_lib.c, sockets.h, sockets.c, tcpip.c, sys.h, sys.c, err.h: 
+    Implement SO_RCVTIMEO on UDP sockets/netconn.
+
+  2007-02-28 Kieran Mansley (based on patch from Simon Goldschmidt)
+  * api_lib.c, tcpip.c, memp.c, memp.h: make API msg structs allocated
+    on the stack and remove the API msg type from memp
+
+  2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt)
+  * sockets.h, sockets.c: Move socket initialization to new
+    lwip_socket_init() function.
+    NOTE: this changes the API with ports. Ports will have to be
+    updated to call lwip_socket_init() now.
+
+  2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt)
+  * api_lib.c: Use memcpy in netbuf_copy_partial.
+
+
+  ++ Bug fixes:
+
+  2008-03-17 Frédéric Bernon, Ed Kerekes
+  * igmp.h, igmp.c: Fix bug #22613 "IGMP iphdr problem" (could have
+    some problems to fill the IP header on some targets, use now the
+    ip.h macros to do it).
+
+  2008-03-13 Frédéric Bernon
+  * sockets.c: Fix bug #22435 "lwip_recvfrom with TCP break;". Using
+    (lwip_)recvfrom with valid "from" and "fromlen" parameters, on a
+    TCP connection caused a crash. Note that using (lwip_)recvfrom
+    like this is a bit slow and that using (lwip)getpeername is the
+    good lwip way to do it (so, using recv is faster on tcp sockets).
+
+  2008-03-12 Frédéric Bernon, Jonathan Larmour
+  * api_msg.c, contrib/apps/ping.c: Fix bug #22530 "api_msg.c's
+    recv_raw() does not consume data", and the ping sample (with
+    LWIP_SOCKET=1, the code did the wrong supposition that lwip_recvfrom
+    returned the IP payload, without the IP header).
+
+  2008-03-04 Jonathan Larmour
+  * mem.c, stats.c, mem.h: apply patch #6414 to avoid compiler errors
+  and/or warnings on some systems where mem_size_t and size_t differ.
+  * pbuf.c, ppp.c: Fix warnings on some systems with mem_malloc.
+
+  2008-03-04 Kieran Mansley (contributions by others) 
+  * Numerous small compiler error/warning fixes from contributions to
+    mailing list after 1.3.0 release candidate made.
+
+  2008-01-25 Cui hengbin (integrated by Frédéric Bernon)
+  * dns.c: Fix bug #22108 "DNS problem" caused by unaligned structures.
+
+  2008-01-15 Kieran Mansley
+  * tcp_out.c: BUG20511.  Modify persist timer to start when we are
+    prevented from sending by a small send window, not just a zero
+    send window.
+
+  2008-01-09 Jonathan Larmour
+  * opt.h, ip.c: Rename IP_OPTIONS define to IP_OPTIONS_ALLOWED to avoid
+    conflict with Linux system headers.
+
+  2008-01-06 Jonathan Larmour
+  * dhcp.c: fix bug #19927: "DHCP NACK problem" by clearing any existing set IP
+    address entirely on receiving a DHCPNAK, and restarting discovery.
+
+  2007-12-21 Simon Goldschmidt
+  * sys.h, api_lib.c, api_msg.c, sockets.c: fix bug #21698: "netconn->recv_avail
+    is not protected" by using new macros for interlocked access to modify/test
+    netconn->recv_avail.
+
+  2007-12-20 Kieran Mansley (based on patch from Oleg Tyshev)
+  * tcp_in.c: fix bug# 21535 (nrtx not reset correctly in SYN_SENT state)
+
+  2007-12-20 Kieran Mansley (based on patch from Per-Henrik Lundbolm)
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: fix bug #20199 (better handling
+    of silly window avoidance and prevent lwIP from shrinking the window)
+
+  2007-12-04 Simon Goldschmidt
+  * tcp.c, tcp_in.c: fix bug #21699 (segment leak in ooseq processing when last
+    data packet was lost): add assert that all segment lists are empty in
+    tcp_pcb_remove before setting pcb to CLOSED state; don't directly set CLOSED
+    state from LAST_ACK in tcp_process
+
+  2007-12-02 Simon Goldschmidt
+  * sockets.h: fix bug #21654: exclude definition of struct timeval from #ifndef FD_SET
+    If including <sys/time.h> for system-struct timeval, LWIP_TIMEVAL_PRIVATE now
+    has to be set to 0 in lwipopts.h
+
+  2007-12-02 Simon Goldschmidt
+  * api_msg.c, api_lib.c: fix bug #21656 (recvmbox problem in netconn API): always
+    allocate a recvmbox in netconn_new_with_proto_and_callback. For a tcp-listen
+    netconn, this recvmbox is later freed and a new mbox is allocated for acceptmbox.
+    This is a fix for thread-safety and allocates all items needed for a netconn
+    when the netconn is created.
+
+  2007-11-30 Simon Goldschmidt
+  * udp.c: first attempt to fix bug #21655 (DHCP doesn't work reliably with multiple
+    netifs): if LWIP_DHCP is enabled, UDP packets to DHCP_CLIENT_PORT are passed
+    to netif->dhcp->pcb only (if that exists) and not to any other pcb for the same
+    port (only solution to let UDP pcbs 'bind' to a netif instead of an IP address)
+
+  2007-11-27 Simon Goldschmidt
+  * ip.c: fixed bug #21643 (udp_send/raw_send don't fail if netif is down) by
+    letting ip_route only use netifs that are up.
+
+  2007-11-27 Simon Goldschmidt
+  * err.h, api_lib.c, api_msg.c, sockets.c: Changed error handling: ERR_MEM, ERR_BUF
+    and ERR_RTE are seen as non-fatal, all other errors are fatal. netconns and
+    sockets block most operations once they have seen a fatal error.
+
+  2007-11-27 Simon Goldschmidt
+  * udp.h, udp.c, dhcp.c: Implemented new function udp_sendto_if which takes the
+    netif to send as an argument (to be able to send on netifs that are down).
+
+  2007-11-26 Simon Goldschmidt
+  * tcp_in.c: Fixed bug #21582: pcb->acked accounting can be wrong when ACKs
+    arrive out-of-order
+
+  2007-11-21 Simon Goldschmidt
+  * tcp.h, tcp_out.c, api_msg.c: Fixed bug #20287: tcp_output_nagle sends too early
+    Fixed the nagle algorithm; nagle now also works for all raw API applications
+    and has to be explicitly disabled with 'tcp_pcb->flags |= TF_NODELAY'
+
+  2007-11-12 Frédéric Bernon
+  * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fixed bug #20900. Now, most
+    of the netconn_peer and netconn_addr processing is done inside tcpip_thread
+    context in do_getaddr.
+
+  2007-11-10 Simon Goldschmidt
+  * etharp.c: Fixed bug: assert fired when MEMP_ARP_QUEUE was empty (which can
+    happen any time). Now the packet simply isn't enqueued when out of memory.
+
+  2007-11-01 Simon Goldschmidt
+  * tcp.c, tcp_in.c: Fixed bug #21494: The send mss (pcb->mss) is set to 536 (or
+    TCP_MSS if that is smaller) as long as no MSS option is received from the
+    remote host.
+
+  2007-11-01 Simon Goldschmidt
+  * tcp.h, tcp.c, tcp_in.c: Fixed bug #21491: The MSS option sent (with SYN)
+    is now based on TCP_MSS instead of pcb->mss (on passive open now effectively
+    sending our configured TCP_MSS instead of the one received).
+
+  2007-11-01 Simon Goldschmidt
+  * tcp_in.c: Fixed bug #21181: On active open, the initial congestion window was
+    calculated based on the configured TCP_MSS, not on the MSS option received
+    with SYN+ACK.
+
+  2007-10-09 Simon Goldschmidt
+  * udp.c, inet.c, inet.h: Fixed UDPLite: send: Checksum was always generated too
+    short and also was generated wrong if checksum coverage != tot_len;
+    receive: checksum was calculated wrong if checksum coverage != tot_len
+
+  2007-10-08 Simon Goldschmidt
+  * mem.c: lfree was not updated in mem_realloc!
+
+  2007-10-07 Frédéric Bernon
+  * sockets.c, api.h, api_lib.c: First step to fix "bug #20900 : Potential
+    crash error problem with netconn_peer & netconn_addr". VERY IMPORTANT:
+    this change cause an API breakage for netconn_addr, since a parameter
+    type change. Any compiler should cause an error without any changes in
+    yours netconn_peer calls (so, it can't be a "silent change"). It also
+    reduce a little bit the footprint for socket layer (lwip_getpeername &
+    lwip_getsockname use now a common lwip_getaddrname function since 
+    netconn_peer & netconn_addr have the same parameters).
+
+  2007-09-20 Simon Goldschmidt
+  * tcp.c: Fixed bug #21080 (tcp_bind without check pcbs in TIME_WAIT state)
+    by checking  tcp_tw_pcbs also
+
+  2007-09-19 Simon Goldschmidt
+  * icmp.c: Fixed bug #21107 (didn't reset IP TTL in ICMP echo replies)
+
+  2007-09-15 Mike Kleshov
+  * mem.c: Fixed bug #21077 (inaccuracy in calculation of lwip_stat.mem.used)
+
+  2007-09-06 Frédéric Bernon
+  * several-files: replace some #include "arch/cc.h" by "lwip/arch.h", or simply remove
+    it as long as "lwip/opt.h" is included before (this one include "lwip/debug.h" which
+    already include "lwip/arch.h"). Like that, default defines are provided by "lwip/arch.h"
+    if they are not defined in cc.h, in the same spirit than "lwip/opt.h" for lwipopts.h.
+
+  2007-08-30 Frédéric Bernon
+  * igmp.h, igmp.c: Some changes to remove some redundant code, add some traces, 
+    and fix some coding style.
+
+  2007-08-28 Frédéric Bernon
+  * tcpip.c: Fix TCPIP_MSG_INPKT processing: now, tcpip_input can be used for any
+    kind of packets. These packets are considered like Ethernet packets (payload 
+    pointing to ethhdr) if the netif got the NETIF_FLAG_ETHARP flag. Else, packets 
+    are considered like IP packets (payload pointing to iphdr).
+
+  2007-08-27 Frédéric Bernon
+  * api.h, api_lib.c, api_msg.c: First fix for "bug #20900 : Potential crash error
+    problem with netconn_peer & netconn_addr". Introduce NETCONN_LISTEN netconn_state
+    and remove obsolete ones (NETCONN_RECV & NETCONN_ACCEPT).
+
+  2007-08-24 Kieran Mansley
+  * inet.c Modify (acc >> 16) test to ((acc >> 16) != 0) to help buggy
+    compiler (Paradigm C++)
+
+  2007-08-09 Frédéric Bernon, Bill Florac
+  * stats.h, stats.c, igmp.h, igmp.c, opt.h: Fix for bug #20503 : IGMP Improvement.
+    Introduce IGMP_STATS to centralize statistics management.
+
+  2007-08-09 Frédéric Bernon, Bill Florac
+  * udp.c: Fix for bug #20503 : IGMP Improvement. Enable to receive a multicast
+    packet on a udp pcb binded on an netif's IP address, and not on "any".
+
+  2007-08-09 Frédéric Bernon, Bill Florac
+  * igmp.h, igmp.c, ip.c: Fix minor changes from bug #20503 : IGMP Improvement.
+    This is mainly on using lookup/lookfor, and some coding styles...
+
+  2007-07-26 Frédéric Bernon (and "thedoctor")
+  * igmp.c: Fix bug #20595 to accept IGMPv3 "Query" messages.
+
+  2007-07-25 Simon Goldschmidt
+  * api_msg.c, tcp.c: Another fix for bug #20021: by not returning an error if
+    tcp_output fails in tcp_close, the code in do_close_internal gets simpler
+    (tcp_output is called again later from tcp timers).
+
+  2007-07-25 Simon Goldschmidt
+  * ip_frag.c: Fixed bug #20429: use the new pbuf_copy_partial instead of the old
+    copy_from_pbuf, which illegally modified the given pbuf.
+
+  2007-07-25 Simon Goldschmidt
+  * tcp_out.c: tcp_enqueue: pcb->snd_queuelen didn't work for chaine PBUF_RAMs:
+    changed snd_queuelen++ to snd_queuelen += pbuf_clen(p).
+
+  2007-07-24 Simon Goldschmidt
+  * api_msg.c, tcp.c: Fix bug #20480: Check the pcb passed to tcp_listen() for the
+    correct state (must be CLOSED).
+
+  2007-07-13 Thomas Taranowski (commited by Jared Grubb)
+  * memp.c: Fix bug #20478: memp_malloc returned NULL+MEMP_SIZE on failed
+    allocation. It now returns NULL.
+
+  2007-07-13 Frédéric Bernon
+  * api_msg.c: Fix bug #20318: api_msg "recv" callbacks don't call pbuf_free in
+    all error cases.
+
+  2007-07-13 Frédéric Bernon
+  * api_msg.c: Fix bug #20315: possible memory leak problem if tcp_listen failed,
+    because current code doesn't follow rawapi.txt documentation.
+
+  2007-07-13 Kieran Mansley
+  * src/core/tcp_in.c Apply patch#5741 from Oleg Tyshev to fix bug in
+    out of sequence processing of received packets
+
+  2007-07-03 Simon Goldschmidt
+  * nearly-all-files: Added assertions where PBUF_RAM pbufs are used and an
+    assumption is made that this pbuf is in one piece (i.e. not chained). These
+    assumptions clash with the possibility of converting to fully pool-based
+    pbuf implementations, where PBUF_RAM pbufs might be chained.
+
+  2007-07-03 Simon Goldschmidt
+  * api.h, api_lib.c, api_msg.c: Final fix for bug #20021 and some other problems
+    when closing tcp netconns: removed conn->sem, less context switches when
+    closing, both netconn_close and netconn_delete should safely close tcp
+    connections.
+
+  2007-07-02 Simon Goldschmidt
+  * ipv4/ip.h, ipv6/ip.h, opt.h, netif.h, etharp.h, ipv4/ip.c, netif.c, raw.c,
+    tcp_out.c, udp.c, etharp.c: Added option LWIP_NETIF_HWADDRHINT (default=off)
+    to cache ARP table indices with each pcb instead of single-entry cache for
+    the complete stack.
+
+  2007-07-02 Simon Goldschmidt
+  * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Added some ASSERTS and casts to prevent
+    warnings when assigning to smaller types.
+
+  2007-06-28 Simon Goldschmidt
+  * tcp_out.c: Added check to prevent tcp_pcb->snd_queuelen from overflowing.
+
+  2007-06-28 Simon Goldschmidt
+  * tcp.h: Fixed bug #20287: Fixed nagle algorithm (sending was done too early if
+    a segment contained chained pbufs)
+
+  2007-06-28 Frédéric Bernon
+  * autoip.c: replace most of rand() calls by a macro LWIP_AUTOIP_RAND which compute
+    a "pseudo-random" value based on netif's MAC and some autoip fields. It's always
+    possible to define this macro in your own lwipopts.h to always use C library's
+    rand(). Note that autoip_create_rand_addr doesn't use this macro.
+
+  2007-06-28 Frédéric Bernon
+  * netifapi.h, netifapi.c, tcpip.h, tcpip.c: Update code to handle the option
+    LWIP_TCPIP_CORE_LOCKING, and do some changes to be coherent with last modifications
+    in api_lib/api_msg (use pointers and not type with table, etc...) 
+
+  2007-06-26 Simon Goldschmidt
+  * udp.h: Fixed bug #20259: struct udp_hdr was lacking the packin defines.
+
+  2007-06-25 Simon Goldschmidt
+  * udp.c: Fixed bug #20253: icmp_dest_unreach was called with a wrong p->payload
+    for udp packets with no matching pcb.
+
+  2007-06-25 Simon Goldschmidt
+  * udp.c: Fixed bug #20220: UDP PCB search in udp_input(): a non-local match
+    could get udp input packets if the remote side matched.
+
+  2007-06-13 Simon Goldschmidt
+  * netif.c: Fixed bug #20180 (TCP pcbs listening on IP_ADDR_ANY could get
+    changed in netif_set_ipaddr if previous netif->ip_addr.addr was 0.
+
+  2007-06-13 Simon Goldschmidt
+  * api_msg.c: pcb_new sets conn->err if protocol is not implemented
+    -> netconn_new_..() does not allocate a new connection for unsupported
+    protocols.
+
+  2007-06-13 Frédéric Bernon, Simon Goldschmidt
+  * api_lib.c: change return expression in netconn_addr and netconn_peer, because
+    conn->err was reset to ERR_OK without any reasons (and error was lost)...
+
+  2007-06-13 Frédéric Bernon, Matthias Weisser
+  * opt.h, mem.h, mem.c, memp.c, pbuf.c, ip_frag.c, vj.c: Fix bug #20162. Rename
+    MEM_ALIGN in LWIP_MEM_ALIGN and MEM_ALIGN_SIZE in LWIP_MEM_ALIGN_SIZE to avoid
+    some macro names collision with some OS macros.
+
+  2007-06-11 Simon Goldschmidt
+  * udp.c: UDP Lite: corrected the use of chksum_len (based on RFC3828: if it's 0,
+    create checksum over the complete packet. On RX, if it's < 8 (and not 0),
+    discard the packet. Also removed the duplicate 'udphdr->chksum = 0' for both
+    UDP & UDP Lite.
+
+  2007-06-11 Srinivas Gollakota & Oleg Tyshev
+  * tcp_out.c: Fix for bug #20075 : "A problem with keep-alive timer and TCP flags"
+    where TCP flags wasn't initialized in tcp_keepalive.
+
+  2007-06-03 Simon Goldschmidt
+  * udp.c: udp_input(): Input pbuf was not freed if pcb had no recv function
+    registered, p->payload was modified without modifying p->len if sending
+    icmp_dest_unreach() (had no negative effect but was definitively wrong).
+
+  2007-06-03 Simon Goldschmidt
+  * icmp.c: Corrected bug #19937: For responding to an icmp echo request, icmp
+    re-used the input pbuf even if that didn't have enough space to include the
+    link headers. Now the space is tested and a new pbuf is allocated for the
+    echo response packet if the echo request pbuf isn't big enough.
+
+  2007-06-01 Simon Goldschmidt
+  * sockets.c: Checked in patch #5914: Moved sockopt processing into tcpip_thread.
+
+  2007-05-23 Frédéric Bernon
+  * api_lib.c, sockets.c: Fixed bug #5958 for netconn_listen (acceptmbox only
+    allocated by do_listen if success) and netconn_accept errors handling. In
+    most of api_lib functions, we replace some errors checkings like "if (conn==NULL)"
+    by ASSERT, except for netconn_delete.
+
+  2007-05-23 Frédéric Bernon
+  * api_lib.c: Fixed bug #5957 "Safe-thread problem inside netconn_recv" to return
+    an error code if it's impossible to fetch a pbuf on a TCP connection (and not
+    directly close the recvmbox).
+
+  2007-05-22 Simon Goldschmidt
+  * tcp.c: Fixed bug #1895 (tcp_bind not correct) by introducing a list of
+    bound but unconnected (and non-listening) tcp_pcbs.
+
+  2007-05-22 Frédéric Bernon
+  * sys.h, sys.c, api_lib.c, tcpip.c: remove sys_mbox_fetch_timeout() (was only
+    used for LWIP_SO_RCVTIMEO option) and use sys_arch_mbox_fetch() instead of
+    sys_mbox_fetch() in api files. Now, users SHOULD NOT use internal lwIP features
+    like "sys_timeout" in their application threads.
+
+  2007-05-22 Frédéric Bernon
+  * api.h, api_lib.c, api_msg.h, api_msg.c: change the struct api_msg_msg to see
+    which parameters are used by which do_xxx function, and to avoid "misusing"
+    parameters (patch #5938).
+
+  2007-05-22 Simon Goldschmidt
+  * api_lib.c, api_msg.c, raw.c, api.h, api_msg.h, raw.h: Included patch #5938:
+    changed raw_pcb.protocol from u16_t to u8_t since for IPv4 and IPv6, proto
+    is only 8 bits wide. This affects the api, as there, the protocol was
+    u16_t, too.
+
+  2007-05-18 Simon Goldschmidt
+  * memp.c: addition to patch #5913: smaller pointer was returned but
+    memp_memory was the same size -> did not save memory.
+
+  2007-05-16 Simon Goldschmidt
+  * loopif.c, slipif.c: Fix bug #19729: free pbuf if netif->input() returns
+    != ERR_OK.
+
+  2007-05-16 Simon Goldschmidt
+  * api_msg.c, udp.c: If a udp_pcb has a local_ip set, check if it is the same
+    as the one of the netif used for sending to prevent sending from old
+    addresses after a netif address gets changed (partly fixes bug #3168).
+
+  2007-05-16 Frédéric Bernon
+  * tcpip.c, igmp.h, igmp.c: Fixed bug "#19800 : IGMP: igmp_tick() will not work
+    with NO_SYS=1". Note that igmp_init is always in tcpip_thread (and not in 
+    tcpip_init) because we have to be sure that network interfaces are already
+    added (mac filter is updated only in igmp_init for the moment).
+
+  2007-05-16 Simon Goldschmidt
+  * mem.c, memp.c: Removed semaphores from memp, changed sys_sem_wait calls
+    into sys_arch_sem_wait calls to prevent timers from running while waiting
+    for the heap. This fixes bug #19167.
+
+  2007-05-13 Simon Goldschmidt
+  * tcp.h, sockets.h, sockets.c: Fixed bug from patch #5865 by moving the defines
+    for socket options (lwip_set/-getsockopt) used with level IPPROTO_TCP from
+    tcp.h to sockets.h.
+
+  2007-05-07 Simon Goldschmidt
+  * mem.c: Another attempt to fix bug #17922.
+
+  2007-05-04 Simon Goldschmidt
+  * pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy()
+    implementation so that it can be reused (don't allocate the target
+    pbuf inside pbuf_copy()).
+
+  2007-05-04 Simon Goldschmidt
+  * memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem
+    to save a little RAM (next pointer of memp is not used while not in pool).
+
+  2007-05-03 "maq"
+  * sockets.c: Fix ioctl FIONREAD when some data remains from last recv.
+    (patch #3574).
+
+  2007-04-23 Simon Goldschmidt
+  * loopif.c, loopif.h, opt.h, src/netif/FILES: fix bug #2595: "loopif results
+    in NULL reference for incoming TCP packets". Loopif has to be configured
+    (using LWIP_LOOPIF_MULTITHREADING) to directly call netif->input()
+    (multithreading environments, e.g. netif->input() = tcpip_input()) or
+    putting packets on a list that is fed to the stack by calling loopif_poll()
+    (single-thread / NO_SYS / polling environment where e.g.
+    netif->input() = ip_input).
+
+  2007-04-17 Jonathan Larmour
+  * pbuf.c: Use s32_t in pbuf_realloc(), as an s16_t can't reliably hold
+    the difference between two u16_t's.
+  * sockets.h: FD_SETSIZE needs to match number of sockets, which is
+    MEMP_NUM_NETCONN in sockets.c right now.
+
+  2007-04-12 Jonathan Larmour
+  * icmp.c: Reset IP header TTL in ICMP ECHO responses (bug #19580).
+
+  2007-04-12 Kieran Mansley
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Modify way the retransmission
+    timer is reset to fix bug#19434, with help from Oleg Tyshev.
+
+  2007-04-11 Simon Goldschmidt
+  * etharp.c, pbuf.c, pbuf.h: 3rd fix for bug #11400 (arp-queuing): More pbufs than
+    previously thought need to be copied (everything but PBUF_ROM!). Cleaned up
+    pbuf.c: removed functions no needed any more (by etharp).
+
+  2007-04-11 Kieran Mansley
+  * inet.c, ip_addr.h, sockets.h, sys.h, tcp.h: Apply patch #5745: Fix
+    "Constant is long" warnings with 16bit compilers.  Contributed by
+    avatar@mmlab.cse.yzu.edu.tw
+
+  2007-04-05 Frédéric Bernon, Jonathan Larmour
+  * api_msg.c: Fix bug #16830: "err_tcp() posts to connection mailbox when no pend on
+    the mailbox is active". Now, the post is only done during a connect, and do_send,
+    do_write and do_join_leave_group don't do anything if a previous error was signaled.
+
+  2007-04-03 Frédéric Bernon
+  * ip.c: Don't set the IP_DF ("Don't fragment") flag in the IP header in IP output
+    packets. See patch #5834.
+
+  2007-03-30 Frédéric Bernon
+  * api_msg.c: add a "pcb_new" helper function to avoid redundant code, and to add
+    missing  pcb allocations checking (in do_bind, and for each raw_new). Fix style.
+
+  2007-03-30 Frédéric Bernon
+  * most of files: prefix all debug.h define with "LWIP_" to avoid any conflict with
+    others environment defines (these were too "generic").
+
+  2007-03-28 Frédéric Bernon
+  * api.h, api_lib.c, sockets.c: netbuf_ref doesn't check its internal pbuf_alloc call
+    result and can cause a crash. lwip_send now check netbuf_ref result.
+
+  2007-03-28 Simon Goldschmidt
+  * sockets.c Remove "#include <errno.h>" from sockets.c to avoid multiple
+    definition of macros (in errno.h and lwip/arch.h) if LWIP_PROVIDE_ERRNO is
+    defined. This is the way it should have been already (looking at
+    doc/sys_arch.txt)
+
+  2007-03-28 Kieran Mansley
+  * opt.h Change default PBUF_POOL_BUFSIZE (again) to accomodate default MSS +
+    IP and TCP headers *and* physical link headers
+
+  2007-03-26 Frédéric Bernon (based on patch from Dmitry Potapov)
+  * api_lib.c: patch for netconn_write(), fixes a possible race condition which cause
+    to send some garbage. It is not a definitive solution, but the patch does solve
+    the problem for most cases.
+
+  2007-03-22 Frédéric Bernon
+  * api_msg.h, api_msg.c: Remove obsolete API_MSG_ACCEPT and do_accept (never used).
+
+  2007-03-22 Frédéric Bernon
+  * api_lib.c: somes resources couldn't be freed if there was errors during
+    netconn_new_with_proto_and_callback.
+
+  2007-03-22 Frédéric Bernon
+  * ethernetif.c: update netif->input calls to check return value. In older ports,
+    it's a good idea to upgrade them, even if before, there could be another problem
+    (access to an uninitialized mailbox).
+
+  2007-03-21 Simon Goldschmidt
+  * sockets.c: fixed bug #5067 (essentialy a signed/unsigned warning fixed
+    by casting to unsigned).
+
+  2007-03-21 Frédéric Bernon
+  * api_lib.c, api_msg.c, tcpip.c: integrate sys_mbox_fetch(conn->mbox, NULL) calls from
+    api_lib.c to tcpip.c's tcpip_apimsg(). Now, use a local variable and not a
+    dynamic one from memp to send tcpip_msg to tcpip_thread in a synchrone call.
+    Free tcpip_msg from tcpip_apimsg is not done in tcpip_thread. This give a
+    faster and more reliable communication between api_lib and tcpip.
+
+  2007-03-21 Frédéric Bernon
+  * opt.h: Add LWIP_NETIF_CALLBACK (to avoid compiler warning) and set it to 0.
+
+  2007-03-21 Frédéric Bernon
+  * api_msg.c, igmp.c, igmp.h: Fix C++ style comments
+
+  2007-03-21 Kieran Mansley
+  * opt.h Change default PBUF_POOL_BUFSIZE to accomodate default MSS +
+    IP and TCP headers
+
+  2007-03-21 Kieran Mansley
+  * Fix all uses of pbuf_header to check the return value.  In some
+    cases just assert if it fails as I'm not sure how to fix them, but
+    this is no worse than before when they would carry on regardless
+    of the failure.
+
+  2007-03-21 Kieran Mansley
+  * sockets.c, igmp.c, igmp.h, memp.h: Fix C++ style comments and
+    comment out missing header include in icmp.c
+
+  2007-03-20 Frédéric Bernon
+  * memp.h, stats.c: Fix stats_display function where memp_names table wasn't
+    synchronized with memp.h.
+
+  2007-03-20 Frédéric Bernon
+  * tcpip.c: Initialize tcpip's mbox, and verify if initialized in tcpip_input,
+    tcpip_ethinput, tcpip_callback, tcpip_apimsg, to fix a init problem with 
+    network interfaces. Also fix a compiler warning.
+
+  2007-03-20 Kieran Mansley
+  * udp.c: Only try and use pbuf_header() to make space for headers if
+    not a ROM or REF pbuf.
+
+  2007-03-19 Frédéric Bernon
+  * api_msg.h, api_msg.c, tcpip.h, tcpip.c: Add return types to tcpip_apimsg()
+    and api_msg_post().
+
+  2007-03-19 Frédéric Bernon
+  * Remove unimplemented "memp_realloc" function from memp.h.
+
+  2007-03-11 Simon Goldschmidt
+  * pbuf.c: checked in patch #5796: pbuf_alloc: len field claculation caused
+    memory corruption.
+
+  2007-03-11 Simon Goldschmidt (based on patch from Dmitry Potapov)
+  * api_lib.c, sockets.c, api.h, api_msg.h, sockets.h: Fixed bug #19251
+    (missing `const' qualifier in socket functions), to get more compatible to
+    standard POSIX sockets.
+
+  2007-03-11 Frédéric Bernon (based on patch from Dmitry Potapov)
+  * sockets.c: Add asserts inside bind, connect and sendto to check input
+    parameters. Remove excessive set_errno() calls after get_socket(), because
+    errno is set inside of get_socket(). Move last sock_set_errno() inside
+    lwip_close.
+
+  2007-03-09 Simon Goldschmidt
+  * memp.c: Fixed bug #11400: New etharp queueing introduced bug: memp_memory
+    was allocated too small.
+
+  2007-03-06 Simon Goldschmidt
+  * tcpip.c: Initialize dhcp timers in tcpip_thread (if LWIP_DHCP) to protect
+    the stack from concurrent access.
+
+  2007-03-06 Frédéric Bernon, Dmitry Potapov
+  * tcpip.c, ip_frag.c, ethernetif.c: Fix some build problems, and a redundancy
+    call to "lwip_stats.link.recv++;" in low_level_input() & ethernetif_input().
+
+  2007-03-06 Simon Goldschmidt
+  * ip_frag.c, ip_frag.h: Reduce code size: don't include code in those files
+    if IP_FRAG == 0 and IP_REASSEMBLY == 0
+
+  2007-03-06 Frédéric Bernon, Simon Goldschmidt
+  * opt.h, ip_frag.h, tcpip.h, tcpip.c, ethernetif.c: add new configuration
+    option named ETHARP_TCPIP_ETHINPUT, which enable the new tcpip_ethinput.
+    Allow to do ARP processing for incoming packets inside tcpip_thread
+    (protecting ARP layer against concurrent access). You can also disable
+    old code using tcp_input with new define ETHARP_TCPIP_INPUT set to 0.
+    Older ports have to use tcpip_ethinput.
+
+  2007-03-06 Simon Goldschmidt (based on patch from Dmitry Potapov)
+  * err.h, err.c: fixed compiler warning "initialization dircards qualifiers
+    from pointer target type"
+
+  2007-03-05 Frédéric Bernon
+  * opt.h, sockets.h: add new configuration options (LWIP_POSIX_SOCKETS_IO_NAMES,
+    ETHARP_TRUST_IP_MAC, review SO_REUSE)
+
+  2007-03-04 Frédéric Bernon
+  * api_msg.c: Remove some compiler warnings : parameter "pcb" was never
+    referenced.
+
+  2007-03-04 Frédéric Bernon
+  * api_lib.c: Fix "[patch #5764] api_lib.c cleanup: after patch #5687" (from
+    Dmitry Potapov).
+    The api_msg struct stay on the stack (not moved to netconn struct).
+
+  2007-03-04 Simon Goldschmidt (based on patch from Dmitry Potapov)
+  * pbuf.c: Fix BUG#19168 - pbuf_free can cause deadlock (if
+    SYS_LIGHTWEIGHT_PROT=1 & freeing PBUF_RAM when mem_sem is not available)
+    Also fixed cast warning in pbuf_alloc()
+
+  2007-03-04 Simon Goldschmidt
+  * etharp.c, etharp.h, memp.c, memp.h, opt.h: Fix BUG#11400 - don't corrupt
+    existing pbuf chain when enqueuing multiple pbufs to a pending ARP request
+
+  2007-03-03 Frédéric Bernon
+  * udp.c: remove obsolete line "static struct udp_pcb *pcb_cache = NULL;"
+    It is static, and never used in udp.c except udp_init().
+
+  2007-03-02 Simon Goldschmidt
+  * tcpip.c: Moved call to ip_init(), udp_init() and tcp_init() from
+    tcpip_thread() to tcpip_init(). This way, raw API connections can be
+    initialized before tcpip_thread is running (e.g. before OS is started)
+
+  2007-03-02 Frédéric Bernon
+  * rawapi.txt: Fix documentation mismatch with etharp.h about etharp_tmr's call
+    interval.
+
+  2007-02-28 Kieran Mansley 
+  * pbuf.c: Fix BUG#17645 - ensure pbuf payload pointer is not moved
+    outside the region of the pbuf by pbuf_header()
+
+  2007-02-28 Kieran Mansley 
+  * sockets.c: Fix BUG#19161 - ensure milliseconds timeout is non-zero
+    when supplied timeout is also non-zero 
+
+(STABLE-1.2.0)
+
+  2006-12-05 Leon Woestenberg
+  * CHANGELOG: Mention STABLE-1.2.0 release.
+
+  ++ New features:
+
+  2006-12-01 Christiaan Simons
+  * mem.h, opt.h: Added MEM_LIBC_MALLOC option.
+    Note this is a workaround. Currently I have no other options left.
+
+  2006-10-26 Christiaan Simons (accepted patch by Jonathan Larmour)
+  * ipv4/ip_frag.c: rename MAX_MTU to IP_FRAG_MAX_MTU and move define
+    to include/lwip/opt.h.
+  * ipv4/lwip/ip_frag.h: Remove unused IP_REASS_INTERVAL.
+    Move IP_REASS_MAXAGE and IP_REASS_BUFSIZE to include/lwip/opt.h.
+  * opt.h: Add above new options.
+
+  2006-08-18 Christiaan Simons
+  * tcp_{in,out}.c: added SNMP counters.
+  * ipv4/ip.c: added SNMP counters.
+  * ipv4/ip_frag.c: added SNMP counters.
+
+  2006-08-08 Christiaan Simons
+  * etharp.{c,h}: added etharp_find_addr() to read
+    (stable) ethernet/IP address pair from ARP table
+
+  2006-07-14 Christiaan Simons
+  * mib_structs.c: added
+  * include/lwip/snmp_structs.h: added
+  * netif.{c,h}, netif/ethernetif.c: added SNMP statistics to netif struct
+
+  2006-07-06 Christiaan Simons
+  * snmp/asn1_{enc,dec}.c added
+  * snmp/mib2.c added
+  * snmp/msg_{in,out}.c added
+  * include/lwip/snmp_asn1.h added
+  * include/lwip/snmp_msg.h added
+  * doc/snmp_agent.txt added
+
+  2006-03-29 Christiaan Simons
+  * inet.c, inet.h: Added platform byteswap support.
+    Added LWIP_PLATFORM_BYTESWAP define (defaults to 0) and
+    optional LWIP_PLATFORM_HTONS(), LWIP_PLATFORM_HTONL() macros.
+
+  ++ Bug fixes:
+
+  2006-11-30 Christiaan Simons
+  * dhcp.c: Fixed false triggers of request_timeout.
+
+  2006-11-28 Christiaan Simons
+  * netif.c: In netif_add() fixed missing clear of ip_addr, netmask, gw and flags.
+
+  2006-10-11 Christiaan Simons
+  * api_lib.c etharp.c, ip.c, memp.c, stats.c, sys.{c,h} tcp.h:
+    Partially accepted patch #5449 for ANSI C compatibility / build fixes.
+  * ipv4/lwip/ip.h ipv6/lwip/ip.h: Corrected UDP-Lite protocol
+    identifier from 170 to 136 (bug #17574).
+
+  2006-10-10 Christiaan Simons
+  * api_msg.c: Fixed Nagle algorithm as reported by Bob Grice.
+
+  2006-08-17 Christiaan Simons
+  * udp.c: Fixed bug #17200, added check for broadcast
+    destinations for PCBs bound to a unicast address.
+
+  2006-08-07 Christiaan Simons
+  * api_msg.c: Flushing TCP output in do_close() (bug #15926).
+
+  2006-06-27 Christiaan Simons
+  * api_msg.c: Applied patch for cold case (bug #11135).
+    In accept_function() ensure newconn->callback is always initialized.
+
+  2006-06-15 Christiaan Simons
+  * mem.h: added MEM_SIZE_F alias to fix an ancient cold case (bug #1748),
+    facilitate printing of mem_size_t and u16_t statistics.
+
+  2006-06-14 Christiaan Simons
+  * api_msg.c: Applied patch #5146 to handle allocation failures
+    in accept() by Kevin Lawson.
+
+  2006-05-26 Christiaan Simons
+  * api_lib.c: Removed conn->sem creation and destruction 
+    from netconn_write() and added sys_sem_new to netconn_new_*.
+
+(STABLE-1_1_1)
+
+  2006-03-03  Christiaan Simons
+  * ipv4/ip_frag.c: Added bound-checking assertions on ip_reassbitmap
+    access and added pbuf_alloc() return value checks.
+
+  2006-01-01  Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp_{in,out}.c, tcp_out.c: Removed 'even sndbuf' fix in TCP, which is
+    now handled by the checksum routine properly.
+
+  2006-02-27  Leon Woestenberg <leon.woestenberg@gmx.net>
+   * pbuf.c: Fix alignment; pbuf_init() would not work unless
+     pbuf_pool_memory[] was properly aligned. (Patch by Curt McDowell.)
+
+  2005-12-20  Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp.c: Remove PCBs which stay in LAST_ACK state too long. Patch
+    submitted by Mitrani Hiroshi.
+
+  2005-12-15  Christiaan Simons
+  * inet.c: Disabled the added summing routine to preserve code space.
+
+  2005-12-14  Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp_in.c: Duplicate FIN ACK race condition fix by Kelvin Lawson.
+    Added Curt McDowell's optimized checksumming routine for future
+    inclusion. Need to create test case for unaliged, aligned, odd,
+    even length combination of cases on various endianess machines.
+
+  2005-12-09  Christiaan Simons
+  * inet.c: Rewrote standard checksum routine in proper portable C.
+
+  2005-11-25  Christiaan Simons
+  * udp.c tcp.c: Removed SO_REUSE hack. Should reside in socket code only.
+  * *.c: introduced cc.h LWIP_DEBUG formatters matching the u16_t, s16_t,
+    u32_t, s32_t typedefs. This solves most debug word-length assumes.
+
+  2005-07-17 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * inet.c: Fixed unaligned 16-bit access in the standard checksum
+    routine by Peter Jolasson.
+  * slipif.c: Fixed implementation assumption of single-pbuf datagrams.
+
+  2005-02-04 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp_out.c: Fixed uninitialized 'queue' referenced in memerr branch.
+  * tcp_{out|in}.c: Applied patch fixing unaligned access.
+
+  2005-01-04 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * pbuf.c: Fixed missing semicolon after LWIP_DEBUG statement.
+
+  2005-01-03 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * udp.c: UDP pcb->recv() was called even when it was NULL.
+
+(STABLE-1_1_0)
+
+  2004-12-28 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * etharp.*: Disabled multiple packets on the ARP queue.
+    This clashes with TCP queueing.
+
+  2004-11-28 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * etharp.*: Fixed race condition from ARP request to ARP timeout.
+    Halved the ARP period, doubled the period counts.
+    ETHARP_MAX_PENDING now should be at least 2. This prevents
+    the counter from reaching 0 right away (which would allow
+    too little time for ARP responses to be received).
+
+  2004-11-25 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * dhcp.c: Decline messages were not multicast but unicast.
+  * etharp.c: ETHARP_CREATE is renamed to ETHARP_TRY_HARD.
+    Do not try hard to insert arbitrary packet's source address,
+    etharp_ip_input() now calls etharp_update() without ETHARP_TRY_HARD. 
+    etharp_query() now always DOES call ETHARP_TRY_HARD so that users
+    querying an address will see it appear in the cache (DHCP could
+    suffer from this when a server invalidly gave an in-use address.)
+  * ipv4/ip_addr.h: Renamed ip_addr_maskcmp() to _netcmp() as we are
+    comparing network addresses (identifiers), not the network masks
+    themselves.
+  * ipv4/ip_addr.c: ip_addr_isbroadcast() now checks that the given
+    IP address actually belongs to the network of the given interface.
+
+  2004-11-24 Kieran Mansley <kjm25@cam.ac.uk>
+  * tcp.c: Increment pcb->snd_buf when ACK is received in SYN_SENT state.
+
+(STABLE-1_1_0-RC1)
+
+  2004-10-16 Kieran Mansley <kjm25@cam.ac.uk>
+  * tcp.c: Add code to tcp_recved() to send an ACK (window update) immediately,
+    even if one is already pending, if the rcv_wnd is above a threshold
+    (currently TCP_WND/2). This avoids waiting for a timer to expire to send a
+    delayed ACK in order to open the window if the stack is only receiving data.
+
+  2004-09-12 Kieran Mansley <kjm25@cam.ac.uk>
+  * tcp*.*: Retransmit time-out handling improvement by Sam Jansen.
+
+  2004-08-20 Tony Mountifield <tony@softins.co.uk>
+  * etharp.c: Make sure the first pbuf queued on an ARP entry
+    is properly ref counted.
+
+  2004-07-27 Tony Mountifield <tony@softins.co.uk>
+  * debug.h: Added (int) cast in LWIP_DEBUGF() to avoid compiler
+    warnings about comparison.
+  * pbuf.c: Stopped compiler complaining of empty if statement
+    when LWIP_DEBUGF() empty.  Closed an unclosed comment.
+  * tcp.c: Stopped compiler complaining of empty if statement
+    when LWIP_DEBUGF() empty.
+  * ip.h Corrected IPH_TOS() macro: returns a byte, so doesn't need htons().
+  * inet.c: Added a couple of casts to quiet the compiler.
+    No need to test isascii(c) before isdigit(c) or isxdigit(c).
+
+  2004-07-22 Tony Mountifield <tony@softins.co.uk>
+  * inet.c: Made data types consistent in inet_ntoa().
+    Added casts for return values of checksum routines, to pacify compiler.
+  * ip_frag.c, tcp_out.c, sockets.c, pbuf.c
+    Small corrections to some debugging statements, to pacify compiler.
+
+  2004-07-21 Tony Mountifield <tony@softins.co.uk>
+  * etharp.c: Removed spurious semicolon and added missing end-of-comment.
+  * ethernetif.c Updated low_level_output() to match prototype for
+    netif->linkoutput and changed low_level_input() similarly for consistency.
+  * api_msg.c: Changed recv_raw() from int to u8_t, to match prototype
+    of raw_recv() in raw.h and so avoid compiler error.
+  * sockets.c: Added trivial (int) cast to keep compiler happier.
+  * ip.c, netif.c Changed debug statements to use the tidier ip4_addrN() macros.
+
+(STABLE-1_0_0)
+
+  ++ Changes:
+
+  2004-07-05 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * sockets.*: Restructured LWIP_PRIVATE_TIMEVAL. Make sure
+    your cc.h file defines this either 1 or 0. If non-defined,
+    defaults to 1.
+  * .c: Added <string.h> and <errno.h> includes where used.
+  * etharp.c: Made some array indices unsigned.
+
+  2004-06-27 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * netif.*: Added netif_set_up()/down().
+  * dhcp.c: Changes to restart program flow.
+
+  2004-05-07 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * etharp.c: In find_entry(), instead of a list traversal per candidate, do a
+    single-pass lookup for different candidates. Should exploit locality.
+
+  2004-04-29 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp*.c: Cleaned up source comment documentation for Doxygen processing.
+  * opt.h: ETHARP_ALWAYS_INSERT option removed to comply with ARP RFC.
+  * etharp.c: update_arp_entry() only adds new ARP entries when adviced to by
+    the caller. This deprecates the ETHARP_ALWAYS_INSERT overrule option.
+
+  ++ Bug fixes:
+
+  2004-04-27 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * etharp.c: Applied patch of bug #8708 by Toni Mountifield with a solution
+    suggested by Timmy Brolin. Fix for 32-bit processors that cannot access
+    non-aligned 32-bit words, such as soms 32-bit TCP/IP header fields. Fix
+    is to prefix the 14-bit Ethernet headers with two padding bytes.
+
+  2004-04-23 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * ip_addr.c: Fix in the ip_addr_isbroadcast() check.
+  * etharp.c: Fixed the case where the packet that initiates the ARP request
+    is not queued, and gets lost. Fixed the case where the packets destination
+    address is already known; we now always queue the packet and perform an ARP
+    request.
+
+(STABLE-0_7_0)
+
+  ++ Bug fixes:
+
+  * Fixed TCP bug for SYN_SENT to ESTABLISHED state transition.
+  * Fixed TCP bug in dequeueing of FIN from out of order segment queue.
+  * Fixed two possible NULL references in rare cases.
+
+(STABLE-0_6_6)
+
+  ++ Bug fixes:
+
+  * Fixed DHCP which did not include the IP address in DECLINE messages.
+
+  ++ Changes:
+
+  * etharp.c has been hauled over a bit.
+
+(STABLE-0_6_5)
+
+  ++ Bug fixes:
+
+  * Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic.
+  * Packets sent from ARP queue had invalid source hardware address.
+
+  ++ Changes:
+
+  * Pass-by ARP requests do now update the cache.
+
+  ++ New features:
+
+  * No longer dependent on ctype.h.
+  * New socket options.
+  * Raw IP pcb support.
+
+(STABLE-0_6_4)
+
+  ++ Bug fixes:
+
+  * Some debug formatters and casts fixed.
+  * Numereous fixes in PPP.
+
+  ++ Changes:
+
+  * DEBUGF now is LWIP_DEBUGF
+  * pbuf_dechain() has been re-enabled.
+  * Mentioned the changed use of CVS branches in README.
+
+(STABLE-0_6_3)
+
+  ++ Bug fixes:
+
+  * Fixed pool pbuf memory leak in pbuf_alloc().
+    Occured if not enough PBUF_POOL pbufs for a packet pbuf chain.
+    Reported by Savin Zlobec.
+
+  * PBUF_POOL chains had their tot_len field not set for non-first
+    pbufs. Fixed in pbuf_alloc().
+
+  ++ New features:
+
+  * Added PPP stack contributed by Marc Boucher
+
+  ++ Changes:
+
+  * Now drops short packets for ICMP/UDP/TCP protocols. More robust.
+
+  * ARP queueuing now queues the latest packet instead of the first.
+    This is the RFC recommended behaviour, but can be overridden in
+    lwipopts.h.
+
+(0.6.2)
+
+  ++ Bugfixes:
+
+  * TCP has been fixed to deal with the new use of the pbuf->ref
+    counter.
+
+  * DHCP dhcp_inform() crash bug fixed.
+
+  ++ Changes:
+
+  * Removed pbuf_pool_free_cache and pbuf_pool_alloc_cache. Also removed
+    pbuf_refresh(). This has sped up pbuf pool operations considerably.
+    Implemented by David Haas.
+
+(0.6.1)
+
+  ++ New features:
+
+  * The packet buffer implementation has been enhanced to support
+    zero-copy and copy-on-demand for packet buffers which have their
+    payloads in application-managed memory.
+    Implemented by David Haas.
+
+    Use PBUF_REF to make a pbuf refer to RAM. lwIP will use zero-copy
+    if an outgoing packet can be directly sent on the link, or perform
+    a copy-on-demand when necessary.
+
+    The application can safely assume the packet is sent, and the RAM
+    is available to the application directly after calling udp_send()
+    or similar function.
+
+  ++ Bugfixes:
+
+  * ARP_QUEUEING should now correctly work for all cases, including
+    PBUF_REF.
+    Implemented by Leon Woestenberg.
+
+  ++ Changes:
+
+  * IP_ADDR_ANY is no longer a NULL pointer. Instead, it is a pointer
+    to a '0.0.0.0' IP address.
+
+  * The packet buffer implementation is changed. The pbuf->ref counter
+    meaning has changed, and several pbuf functions have been
+    adapted accordingly.
+
+  * netif drivers have to be changed to set the hardware address length field
+    that must be initialized correctly by the driver (hint: 6 for Ethernet MAC).
+    See the contrib/ports/c16x cs8900 driver as a driver example.
+
+  * netif's have a dhcp field that must be initialized to NULL by the driver.
+    See the contrib/ports/c16x cs8900 driver as a driver example.
+
+(0.5.x) This file has been unmaintained up to 0.6.1. All changes are
+  logged in CVS but have not been explained here.
+
+(0.5.3) Changes since version 0.5.2
+
+  ++ Bugfixes:
+
+  * memp_malloc(MEMP_API_MSG) could fail with multiple application
+    threads because it wasn't protected by semaphores.
+
+  ++ Other changes:
+
+  * struct ip_addr now packed.
+
+  * The name of the time variable in arp.c has been changed to ctime
+    to avoid conflicts with the time() function.
+
+(0.5.2) Changes since version 0.5.1
+
+  ++ New features:
+
+  * A new TCP function, tcp_tmr(), now handles both TCP timers.
+
+  ++ Bugfixes:
+
+  * A bug in tcp_parseopt() could cause the stack to hang because of a
+    malformed TCP option.
+
+  * The address of new connections in the accept() function in the BSD
+    socket library was not handled correctly.
+
+  * pbuf_dechain() did not update the ->tot_len field of the tail.
+
+  * Aborted TCP connections were not handled correctly in all
+    situations.
+
+  ++ Other changes:
+
+  * All protocol header structs are now packed.
+
+  * The ->len field in the tcp_seg structure now counts the actual
+    amount of data, and does not add one for SYN and FIN segments.
+
+(0.5.1) Changes since version 0.5.0
+
+  ++ New features:
+
+  * Possible to run as a user process under Linux.
+
+  * Preliminary support for cross platform packed structs.
+
+  * ARP timer now implemented.
+
+  ++ Bugfixes:
+
+  * TCP output queue length was badly initialized when opening
+    connections.
+
+  * TCP delayed ACKs were not sent correctly.
+
+  * Explicit initialization of BSS segment variables.
+
+  * read() in BSD socket library could drop data.
+
+  * Problems with memory alignment.
+
+  * Situations when all TCP buffers were used could lead to
+    starvation.
+
+  * TCP MSS option wasn't parsed correctly.
+
+  * Problems with UDP checksum calculation.
+
+  * IP multicast address tests had endianess problems.
+
+  * ARP requests had wrong destination hardware address.
+
+  ++ Other changes:
+
+  * struct eth_addr changed from u16_t[3] array to u8_t[6].
+
+  * A ->linkoutput() member was added to struct netif.
+
+  * TCP and UDP ->dest_* struct members where changed to ->remote_*.
+
+  * ntoh* macros are now null definitions for big endian CPUs.
+
+(0.5.0) Changes since version 0.4.2
+
+  ++ New features:
+
+  * Redesigned operating system emulation layer to make porting easier.
+
+  * Better control over TCP output buffers.
+
+  * Documenation added.
+
+  ++ Bugfixes:
+
+  * Locking issues in buffer management.
+
+  * Bugfixes in the sequential API.
+
+  * IP forwarding could cause memory leakage. This has been fixed.
+
+  ++ Other changes:
+
+  * Directory structure somewhat changed; the core/ tree has been
+    collapsed.
+
+(0.4.2) Changes since version 0.4.1
+
+  ++ New features:
+
+  * Experimental ARP implementation added.
+
+  * Skeleton Ethernet driver added.
+
+  * Experimental BSD socket API library added.
+
+  ++ Bugfixes:
+
+  * In very intense situations, memory leakage could occur. This has
+    been fixed.
+
+  ++ Other changes:
+
+  * Variables named "data" and "code" have been renamed in order to
+    avoid name conflicts in certain compilers.
+
+  * Variable++ have in appliciable cases been translated to ++variable
+    since some compilers generate better code in the latter case.
+
+(0.4.1) Changes since version 0.4
+
+  ++ New features:
+
+  * TCP: Connection attempts time out earlier than data
+    transmissions. Nagle algorithm implemented. Push flag set on the
+    last segment in a burst.
+
+  * UDP: experimental support for UDP-Lite extensions.
+
+  ++ Bugfixes:
+
+  * TCP: out of order segments were in some cases handled incorrectly,
+    and this has now been fixed. Delayed acknowledgements was broken
+    in 0.4, has now been fixed. Binding to an address that is in use
+    now results in an error. Reset connections sometimes hung an
+    application; this has been fixed.
+
+  * Checksum calculation sometimes failed for chained pbufs with odd
+    lengths. This has been fixed.
+
+  * API: a lot of bug fixes in the API. The UDP API has been improved
+    and tested. Error reporting and handling has been
+    improved. Logical flaws and race conditions for incoming TCP
+    connections has been found and removed.
+
+  * Memory manager: alignment issues. Reallocating memory sometimes
+    failed, this has been fixed.
+
+  * Generic library: bcopy was flawed and has been fixed.
+
+  ++ Other changes:
+
+  * API: all datatypes has been changed from generic ones such as
+    ints, to specified ones such as u16_t. Functions that return
+    errors now have the correct type (err_t).
+
+  * General: A lot of code cleaned up and debugging code removed. Many
+    portability issues have been fixed.
+
+  * The license was changed; the advertising clause was removed.
+
+  * C64 port added.
+
+  * Thanks: Huge thanks go to Dagan Galarneau, Horst Garnetzke, Petri
+    Kosunen, Mikael Caleres, and Frits Wilmink for reporting and
+    fixing bugs!
+
+(0.4) Changes since version 0.3.1
+
+  * Memory management has been radically changed; instead of
+    allocating memory from a shared heap, memory for objects that are
+    rapidly allocated and deallocated is now kept in pools. Allocation
+    and deallocation from those memory pools is very fast. The shared
+    heap is still present but is used less frequently.
+
+  * The memory, memory pool, and packet buffer subsystems now support
+    4-, 2-, or 1-byte alignment.
+
+  * "Out of memory" situations are handled in a more robust way.
+
+  * Stack usage has been reduced.
+
+  * Easier configuration of lwIP parameters such as memory usage,
+    TTLs, statistics gathering, etc. All configuration parameters are
+    now kept in a single header file "lwipopts.h".
+
+  * The directory structure has been changed slightly so that all
+    architecture specific files are kept under the src/arch
+    hierarchy.
+
+  * Error propagation has been improved, both in the protocol modules
+    and in the API.
+
+  * The code for the RTXC architecture has been implemented, tested
+    and put to use.
+
+  * Bugs have been found and corrected in the TCP, UDP, IP, API, and
+    the Internet checksum modules.
+
+  * Bugs related to porting between a 32-bit and a 16-bit architecture
+    have been found and corrected.
+
+  * The license has been changed slightly to conform more with the
+    original BSD license, including the advertisement clause.
+
+(0.3.1) Changes since version 0.3
+
+  * Fix of a fatal bug in the buffer management. Pbufs with allocated
+    RAM never returned the RAM when the pbuf was deallocated.
+
+  * TCP congestion control, window updates and retransmissions did not
+    work correctly. This has now been fixed.
+
+  * Bugfixes in the API.
+
+(0.3) Changes since version 0.2
+
+  * New and improved directory structure. All include files are now
+    kept in a dedicated include/ directory.
+
+  * The API now has proper error handling. A new function,
+    netconn_err(), now returns an error code for the connection in
+    case of errors.
+
+  * Improvements in the memory management subsystem. The system now
+    keeps a pointer to the lowest free memory block. A new function,
+    mem_malloc2() tries to allocate memory once, and if it fails tries
+    to free some memory and retry the allocation.
+
+  * Much testing has been done with limited memory
+    configurations. lwIP now does a better job when overloaded.
+
+  * Some bugfixes and improvements to the buffer (pbuf) subsystem.
+
+  * Many bugfixes in the TCP code:
+
+    - Fixed a bug in tcp_close().
+
+    - The TCP receive window was incorrectly closed when out of
+      sequence segments was received. This has been fixed.
+
+    - Connections are now timed-out of the FIN-WAIT-2 state.
+
+    - The initial congestion window could in some cases be too
+      large. This has been fixed.
+
+    - The retransmission queue could in some cases be screwed up. This
+      has been fixed.
+
+    - TCP RST flag now handled correctly.
+
+    - Out of sequence data was in some cases never delivered to the
+      application. This has been fixed.
+
+    - Retransmitted segments now contain the correct acknowledgment
+      number and advertised window.
+
+    - TCP retransmission timeout backoffs are not correctly computed
+      (ala BSD). After a number of retransmissions, TCP now gives up
+      the connection.
+
+  * TCP connections now are kept on three lists, one for active
+    connections, one for listening connections, and one for
+    connections that are in TIME-WAIT. This greatly speeds up the fast
+    timeout processing for sending delayed ACKs.
+
+  * TCP now provides proper feedback to the application when a
+    connection has been successfully set up.
+
+  * More comments have been added to the code. The code has also been
+    somewhat cleaned up.
+
+(0.2) Initial public release.
Index: UsbWattMeter/trunk/lwip-1.4.1/COPYING
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/COPYING	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/COPYING	(revision 164)
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+
Index: UsbWattMeter/trunk/lwip-1.4.1/FILES
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/FILES	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/FILES	(revision 164)
@@ -0,0 +1,4 @@
+src/      - The source code for the lwIP TCP/IP stack.
+doc/      - The documentation for lwIP.
+
+See also the FILES file in each subdirectory.
Index: UsbWattMeter/trunk/lwip-1.4.1/README
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/README	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/README	(revision 164)
@@ -0,0 +1,89 @@
+INTRODUCTION
+
+lwIP is a small independent implementation of the TCP/IP protocol
+suite that has been developed by Adam Dunkels at the Computer and
+Networks Architectures (CNA) lab at the Swedish Institute of Computer
+Science (SICS).
+
+The focus of the lwIP TCP/IP implementation is to reduce the RAM usage
+while still having a full scale TCP. This making lwIP suitable for use
+in embedded systems with tens of kilobytes of free RAM and room for
+around 40 kilobytes of code ROM.
+
+FEATURES
+
+  * IP (Internet Protocol) including packet forwarding over multiple network
+    interfaces
+  * ICMP (Internet Control Message Protocol) for network maintenance and debugging
+  * IGMP (Internet Group Management Protocol) for multicast traffic management
+  * UDP (User Datagram Protocol) including experimental UDP-lite extensions
+  * TCP (Transmission Control Protocol) with congestion control, RTT estimation
+    and fast recovery/fast retransmit
+  * Specialized raw/native API for enhanced performance
+  * Optional Berkeley-like socket API
+  * DNS (Domain names resolver)
+  * SNMP (Simple Network Management Protocol)
+  * DHCP (Dynamic Host Configuration Protocol)
+  * AUTOIP (for IPv4, conform with RFC 3927)
+  * PPP (Point-to-Point Protocol)
+  * ARP (Address Resolution Protocol) for Ethernet
+
+LICENSE
+
+lwIP is freely available under a BSD license.
+
+DEVELOPMENT
+
+lwIP has grown into an excellent TCP/IP stack for embedded devices,
+and developers using the stack often submit bug fixes, improvements,
+and additions to the stack to further increase its usefulness.
+
+Development of lwIP is hosted on Savannah, a central point for
+software development, maintenance and distribution. Everyone can
+help improve lwIP by use of Savannah's interface, CVS and the
+mailing list. A core team of developers will commit changes to the
+CVS source tree.
+
+The lwIP TCP/IP stack is maintained in the 'lwip' CVS module and
+contributions (such as platform ports) are in the 'contrib' module.
+
+See doc/savannah.txt for details on CVS server access for users and
+developers.
+
+Last night's CVS tar ball can be downloaded from:
+  http://savannah.gnu.org/cvs.backups/lwip.tar.gz [CHANGED - NEEDS FIXING]
+
+The current CVS trees are web-browsable:
+  http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/lwip/
+  http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/contrib/
+
+Submit patches and bugs via the lwIP project page:
+  http://savannah.nongnu.org/projects/lwip/
+
+
+DOCUMENTATION
+
+The original out-dated homepage of lwIP and Adam Dunkels' papers on
+lwIP are at the official lwIP home page:
+  http://www.sics.se/~adam/lwip/
+
+Self documentation of the source code is regularly extracted from the
+current CVS sources and is available from this web page:
+  http://www.nongnu.org/lwip/
+
+There is now a constantly growin wiki about lwIP at
+  http://lwip.wikia.com/wiki/LwIP_Wiki
+
+Also, there are mailing lists you can subscribe at
+  http://savannah.nongnu.org/mail/?group=lwip
+plus searchable archives:
+  http://lists.nongnu.org/archive/html/lwip-users/
+  http://lists.nongnu.org/archive/html/lwip-devel/
+
+Reading Adam's papers, the files in docs/, browsing the source code
+documentation and browsing the mailing list archives is a good way to
+become familiar with the design of lwIP.
+
+Adam Dunkels <adam@sics.se>
+Leon Woestenberg <leon.woestenberg@gmx.net>
+
Index: UsbWattMeter/trunk/lwip-1.4.1/UPGRADING
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/UPGRADING	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/UPGRADING	(revision 164)
@@ -0,0 +1,144 @@
+This file lists major changes between release versions that require
+ports or applications to be changed. Use it to update a port or an
+application written for an older version of lwIP to correctly work
+with newer versions.
+
+
+(CVS HEAD)
+
+  * [Enter new changes just after this line - do not remove this line]
+
+  ++ Application changes:
+
+  * Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for
+    compatibility to old applications, but will be removed in the future).
+
+  * Renamed mem_realloc() to mem_trim() to prevent confusion with realloc()
+
+  +++ Raw API:
+    * Changed the semantics of tcp_close() (since it was rather a
+      shutdown before): Now the application does *NOT* get any calls to the recv
+      callback (aside from NULL/closed) after calling tcp_close()
+
+    * When calling tcp_abort() from a raw API TCP callback function,
+      make sure you return ERR_ABRT to prevent accessing unallocated memory.
+      (ERR_ABRT now means the applicaiton has called tcp_abort!)
+
+  +++ Netconn API:
+    * Changed netconn_receive() and netconn_accept() to return
+      err_t, not a pointer to new data/netconn.
+
+  +++ Socket API:
+    * LWIP_SO_RCVTIMEO: when accept() or recv() time out, they
+      now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT.
+
+    * Added a minimal version of posix fctl() to have a
+      standardised way to set O_NONBLOCK for nonblocking sockets.
+
+  +++ all APIs:
+    * correctly implemented SO(F)_REUSEADDR
+
+  ++ Port changes
+
+  +++ new files:
+
+    * Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h:
+
+    * Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains
+      the actual application programmer's API
+  
+    * Separated timer implementation from sys.h/.c, moved to timers.h/.c;
+      Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you
+      still want to use your own timer implementation for NO_SYS==0 (as before).
+
+  +++ sys layer:
+
+    * Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/
+      sys_sem_t;
+
+    * Converted sys_mbox_new/sys_sem_new to take pointers and return err_t;
+
+    * Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use
+      binary semaphores instead of mutexes - as before)
+
+  +++ new options:
+
+     * Don't waste memory when chaining segments, added option TCP_OVERSIZE to
+       prevent creating many small pbufs when calling tcp_write with many small
+       blocks of data. Instead, pbufs are allocated larger than needed and the
+       space is used for later calls to tcp_write.
+
+     * Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs
+       in tcp_write/udp_send.
+
+    * Added an additional option LWIP_ETHERNET to support ethernet without ARP
+      (necessary for pure PPPoE)
+
+    * Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may
+      be used to place these pools into user-defined memory by using external
+      declaration.
+
+    * Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT
+
+  +++ new pools:
+
+     * Netdb uses a memp pool for allocating memory when getaddrinfo() is called,
+       so MEMP_NUM_NETDB has to be set accordingly.
+
+     * DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so
+       MEMP_NUM_LOCALHOSTLIST has to be set accordingly.
+
+     * Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have
+       to be set accordingly.
+
+     * PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES
+       has to be set accordingly
+
+  * Integrated loopif into netif.c - loopif does not have to be created by the
+    port any more, just define LWIP_HAVE_LOOPIF to 1.
+
+  * Added define LWIP_RAND() for lwip-wide randomization (needs to be defined
+    in cc.h, e.g. used by igmp)
+
+  * Added printf-formatter X8_F to printf u8_t as hex
+
+  * The heap now may be moved to user-defined memory by defining
+    LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address
+
+  * added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work
+    with user-allocated structs instead of calling mem_malloc
+
+  * Added const char* name to mem- and memp-stats for easier debugging.
+
+  * Calculate the TCP/UDP checksum while copying to only fetch data once:
+    Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum
+
+  * Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to
+    more than one pcb.
+
+  * Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned
+    off any more, if this is set to 0, only one packet (the most recent one) is
+    queued (like demanded by RFC 1122).
+
+  
+  ++ Major bugfixes/improvements
+
+  * Implemented tcp_shutdown() to only shut down one end of a connection
+  * Implemented shutdown() at socket- and netconn-level
+  * Added errorset support to select() + improved select speed overhead
+  * Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x)
+  * Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1
+  * Use macros defined in ip_addr.h to work with IP addresses
+  * Implemented many nonblocking socket/netconn functions
+  * Fixed ARP input processing: only add a new entry if a request was directed as us
+  * mem_realloc() to mem_trim() to prevent confusion with realloc()
+  * Some improvements for AutoIP (don't route/forward link-local addresses, don't break
+    existing connections when assigning a routable address)
+  * Correctly handle remote side overrunning our rcv_wnd in ooseq case
+  * Removed packing from ip_addr_t, the packed version is now only used in protocol headers
+  * Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0
+  * Added support for static ARP table entries
+
+(STABLE-1.3.2)
+
+  * initial version of this file
Index: UsbWattMeter/trunk/lwip-1.4.1/apps/sntp/sntp.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/apps/sntp/sntp.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/apps/sntp/sntp.c	(revision 164)
@@ -0,0 +1,606 @@
+/**
+ * @file
+ * SNTP client module
+ *
+ * This is simple "SNTP" client for the lwIP raw API.
+ * It is a minimal implementation of SNTPv4 as specified in RFC 4330.
+ * 
+ * For a list of some public NTP servers, see this link :
+ * http://support.ntp.org/bin/view/Servers/NTPPoolServers
+ *
+ * @todo:
+ * - set/change servers at runtime
+ * - complete SNTP_CHECK_RESPONSE checks 3 and 4
+ * - support broadcast/multicast mode?
+ */
+
+/*
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt (lwIP raw API part)
+ */
+
+#include "lwip/opt.h"
+
+#include "sntp.h"
+
+#include "lwip/timers.h"
+#include "lwip/udp.h"
+#include "lwip/dns.h"
+#include "lwip/ip_addr.h"
+#include "lwip/pbuf.h"
+
+#include <string.h>
+#include <time.h>
+
+#if LWIP_UDP
+
+/**
+ * SNTP_DEBUG: Enable debugging for SNTP.
+ */
+#ifndef SNTP_DEBUG
+#define SNTP_DEBUG                  LWIP_DBG_OFF
+#endif
+
+/** SNTP server port */
+#ifndef SNTP_PORT
+#define SNTP_PORT                   123
+#endif
+
+/** Set this to 1 to allow SNTP_SERVER_ADDRESS to be a DNS name */
+#ifndef SNTP_SERVER_DNS
+#define SNTP_SERVER_DNS             0
+#endif
+
+/** Set this to 1 to support more than one server */
+#ifndef SNTP_SUPPORT_MULTIPLE_SERVERS
+#define SNTP_SUPPORT_MULTIPLE_SERVERS 0
+#endif
+
+/** \def SNTP_SERVER_ADDRESS
+ * \brief SNTP server address:
+ * - as IPv4 address in "u32_t" format
+ * - as a DNS name if SNTP_SERVER_DNS is set to 1
+ * May contain multiple server names (e.g. "pool.ntp.org","second.time.server")
+ */
+#ifndef SNTP_SERVER_ADDRESS
+#if SNTP_SERVER_DNS
+#define SNTP_SERVER_ADDRESS         "pool.ntp.org"
+#else
+#define SNTP_SERVER_ADDRESS         "213.161.194.93" /* pool.ntp.org */
+#endif
+#endif
+
+/** Sanity check:
+ * Define this to
+ * - 0 to turn off sanity checks (default; smaller code)
+ * - >= 1 to check address and port of the response packet to ensure the
+ *        response comes from the server we sent the request to.
+ * - >= 2 to check returned Originate Timestamp against Transmit Timestamp
+ *        sent to the server (to ensure response to older request).
+ * - >= 3 @todo: discard reply if any of the LI, Stratum, or Transmit Timestamp
+ *        fields is 0 or the Mode field is not 4 (unicast) or 5 (broadcast).
+ * - >= 4 @todo: to check that the Root Delay and Root Dispersion fields are each
+ *        greater than or equal to 0 and less than infinity, where infinity is
+ *        currently a cozy number like one second. This check avoids using a
+ *        server whose synchronization source has expired for a very long time.
+ */
+#ifndef SNTP_CHECK_RESPONSE
+#define SNTP_CHECK_RESPONSE         0
+#endif
+
+/** According to the RFC, this shall be a random delay
+ * between 1 and 5 minutes (in milliseconds) to prevent load peaks.
+ * This can be defined to a random generation function,
+ * which must return the delay in milliseconds as u32_t.
+ * Turned off by default.
+ */
+#ifndef SNTP_STARTUP_DELAY
+#define SNTP_STARTUP_DELAY          0
+#endif
+
+/** SNTP receive timeout - in milliseconds
+ * Also used as retry timeout - this shouldn't be too low.
+ * Default is 3 seconds.
+ */
+#ifndef SNTP_RECV_TIMEOUT
+#define SNTP_RECV_TIMEOUT           3000
+#endif
+
+/** SNTP update delay - in milliseconds
+ * Default is 1 hour.
+ */
+#ifndef SNTP_UPDATE_DELAY
+#define SNTP_UPDATE_DELAY           3600000
+#endif
+#if (SNTP_UPDATE_DELAY < 15000) && !SNTP_SUPPRESS_DELAY_CHECK
+#error "SNTPv4 RFC 4330 enforces a minimum update time of 15 seconds!"
+#endif
+
+/** SNTP macro to change system time and/or the update the RTC clock */
+#ifndef SNTP_SET_SYSTEM_TIME
+#define SNTP_SET_SYSTEM_TIME(sec) ((void)sec)
+#endif
+
+/** SNTP macro to change system time including microseconds */
+#ifdef SNTP_SET_SYSTEM_TIME_US
+#define SNTP_CALC_TIME_US           1
+#define SNTP_RECEIVE_TIME_SIZE      2
+#else
+#define SNTP_SET_SYSTEM_TIME_US(sec, us)
+#define SNTP_CALC_TIME_US           0
+#define SNTP_RECEIVE_TIME_SIZE      1
+#endif
+
+/** SNTP macro to get system time, used with SNTP_CHECK_RESPONSE >= 2
+ * to send in request and compare in response.
+ */
+#ifndef SNTP_GET_SYSTEM_TIME
+#define SNTP_GET_SYSTEM_TIME(sec, us)     do { (sec) = 0; (us) = 0; } while(0)
+#endif
+
+/** Default retry timeout (in milliseconds) if the response
+ * received is invalid.
+ * This is doubled with each retry until SNTP_RETRY_TIMEOUT_MAX is reached.
+ */
+#ifndef SNTP_RETRY_TIMEOUT
+#define SNTP_RETRY_TIMEOUT          SNTP_RECV_TIMEOUT
+#endif
+
+/** Maximum retry timeout (in milliseconds). */
+#ifndef SNTP_RETRY_TIMEOUT_MAX
+#define SNTP_RETRY_TIMEOUT_MAX      (SNTP_RETRY_TIMEOUT * 10)
+#endif
+
+/** Increase retry timeout with every retry sent
+ * Default is on to conform to RFC.
+ */
+#ifndef SNTP_RETRY_TIMEOUT_EXP
+#define SNTP_RETRY_TIMEOUT_EXP      1
+#endif
+
+/* the various debug levels for this file */
+#define SNTP_DEBUG_TRACE        (SNTP_DEBUG | LWIP_DBG_TRACE)
+#define SNTP_DEBUG_STATE        (SNTP_DEBUG | LWIP_DBG_STATE)
+#define SNTP_DEBUG_WARN         (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING)
+#define SNTP_DEBUG_WARN_STATE   (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE)
+#define SNTP_DEBUG_SERIOUS      (SNTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS)
+
+#define SNTP_ERR_KOD                1
+
+/* SNTP protocol defines */
+#define SNTP_MSG_LEN                48
+
+#define SNTP_OFFSET_LI_VN_MODE      0
+#define SNTP_LI_MASK                0xC0
+#define SNTP_LI_NO_WARNING          0x00
+#define SNTP_LI_LAST_MINUTE_61_SEC  0x01
+#define SNTP_LI_LAST_MINUTE_59_SEC  0x02
+#define SNTP_LI_ALARM_CONDITION     0x03 /* (clock not synchronized) */
+
+#define SNTP_VERSION_MASK           0x38
+#define SNTP_VERSION                (4/* NTP Version 4*/<<3) 
+
+#define SNTP_MODE_MASK              0x07
+#define SNTP_MODE_CLIENT            0x03
+#define SNTP_MODE_SERVER            0x04
+#define SNTP_MODE_BROADCAST         0x05
+
+#define SNTP_OFFSET_STRATUM         1
+#define SNTP_STRATUM_KOD            0x00
+
+#define SNTP_OFFSET_ORIGINATE_TIME  24
+#define SNTP_OFFSET_RECEIVE_TIME    32
+#define SNTP_OFFSET_TRANSMIT_TIME   40
+
+/* number of seconds between 1900 and 1970 */
+#define DIFF_SEC_1900_1970         (2208988800UL)
+
+/**
+ * SNTP packet format (without optional fields)
+ * Timestamps are coded as 64 bits:
+ * - 32 bits seconds since Jan 01, 1970, 00:00
+ * - 32 bits seconds fraction (0-padded)
+ * For future use, if the MSB in the seconds part is set, seconds are based
+ * on Feb 07, 2036, 06:28:16.
+ */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct sntp_msg {
+ PACK_STRUCT_FIELD(u8_t           li_vn_mode);
+ PACK_STRUCT_FIELD(u8_t           stratum);
+ PACK_STRUCT_FIELD(u8_t           poll);
+ PACK_STRUCT_FIELD(u8_t           precision);
+ PACK_STRUCT_FIELD(u32_t          root_delay);
+ PACK_STRUCT_FIELD(u32_t          root_dispersion);
+ PACK_STRUCT_FIELD(u32_t          reference_identifier);
+ PACK_STRUCT_FIELD(u32_t          reference_timestamp[2]);
+ PACK_STRUCT_FIELD(u32_t          originate_timestamp[2]);
+ PACK_STRUCT_FIELD(u32_t          receive_timestamp[2]);
+ PACK_STRUCT_FIELD(u32_t          transmit_timestamp[2]);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/* function prototypes */
+static void sntp_request(void *arg);
+
+/** The UDP pcb used by the SNTP client */
+static struct udp_pcb* sntp_pcb;
+/** Addresses of servers */
+static char* sntp_server_addresses[] = {SNTP_SERVER_ADDRESS};
+#if SNTP_SUPPORT_MULTIPLE_SERVERS
+/** The currently used server (initialized to 0) */
+static u8_t sntp_current_server;
+static u8_t sntp_num_servers = sizeof(sntp_server_addresses)/sizeof(char*);
+#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */
+#define sntp_current_server 0
+#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */
+
+#if SNTP_RETRY_TIMEOUT_EXP
+#define SNTP_RESET_RETRY_TIMEOUT() sntp_retry_timeout = SNTP_RETRY_TIMEOUT
+/** Retry time, initialized with SNTP_RETRY_TIMEOUT and doubled with each retry. */
+static u32_t sntp_retry_timeout;
+#else /* SNTP_RETRY_TIMEOUT_EXP */
+#define SNTP_RESET_RETRY_TIMEOUT()
+#define sntp_retry_timeout SNTP_RETRY_TIMEOUT
+#endif /* SNTP_RETRY_TIMEOUT_EXP */
+
+#if SNTP_CHECK_RESPONSE >= 1
+/** Saves the last server address to compare with response */
+static ip_addr_t sntp_last_server_address;
+#endif /* SNTP_CHECK_RESPONSE >= 1 */
+
+#if SNTP_CHECK_RESPONSE >= 2
+/** Saves the last timestamp sent (which is sent back by the server)
+ * to compare against in response */
+static u32_t sntp_last_timestamp_sent[2];
+#endif /* SNTP_CHECK_RESPONSE >= 2 */
+
+/**
+ * SNTP processing of received timestamp
+ */
+static void
+sntp_process(u32_t *receive_timestamp)
+{
+  /* convert SNTP time (1900-based) to unix GMT time (1970-based)
+   * @todo: if MSB is 1, SNTP time is 2036-based!
+   */
+  time_t t = (ntohl(receive_timestamp[0]) - DIFF_SEC_1900_1970);
+
+#if SNTP_CALC_TIME_US
+  u32_t us = ntohl(receive_timestamp[1]) / 4295;
+  SNTP_SET_SYSTEM_TIME_US(t, us);
+  /* display local time from GMT time */
+  LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s, %"U32_F" us", ctime(&t), us));
+
+#else /* SNTP_CALC_TIME_US */
+
+  /* change system time and/or the update the RTC clock */
+  SNTP_SET_SYSTEM_TIME(t);
+  /* display local time from GMT time */
+  LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s", ctime(&t)));
+#endif /* SNTP_CALC_TIME_US */
+}
+
+/**
+ * Initialize request struct to be sent to server.
+ */
+static void
+sntp_initialize_request(struct sntp_msg *req)
+{
+  memset(req, 0, SNTP_MSG_LEN);
+  req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT;
+
+#if SNTP_CHECK_RESPONSE >= 2
+  {
+    u32_t sntp_time_sec, sntp_time_us;
+    /* fill in transmit timestamp and save it in 'sntp_last_timestamp_sent' */
+    SNTP_GET_SYSTEM_TIME(sntp_time_sec, sntp_time_us);
+    sntp_last_timestamp_sent[0] = htonl(sntp_time_sec + DIFF_SEC_1900_1970);
+    req->transmit_timestamp[0] = sntp_last_timestamp_sent[0];
+    /* we send/save us instead of fraction to be faster... */
+    sntp_last_timestamp_sent[1] = htonl(sntp_time_us);
+    req->transmit_timestamp[1] = sntp_last_timestamp_sent[1];
+  }
+#endif /* SNTP_CHECK_RESPONSE >= 2 */
+}
+
+/**
+ * Retry: send a new request (and increase retry timeout).
+ *
+ * @param arg is unused (only necessary to conform to sys_timeout)
+ */
+static void
+sntp_retry(void* arg)
+{
+  LWIP_UNUSED_ARG(arg);
+
+  LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_retry: Next request will be sent in %"U32_F" ms\n",
+    sntp_retry_timeout));
+
+  /* set up a timer to send a retry and increase the retry delay */
+  sys_timeout(sntp_retry_timeout, sntp_request, NULL);
+
+#if SNTP_RETRY_TIMEOUT_EXP
+  {
+    u32_t new_retry_timeout;
+    /* increase the timeout for next retry */
+    new_retry_timeout = sntp_retry_timeout << 1;
+    /* limit to maximum timeout and prevent overflow */
+    if ((new_retry_timeout <= SNTP_RETRY_TIMEOUT_MAX) &&
+        (new_retry_timeout > sntp_retry_timeout)) {
+      sntp_retry_timeout = new_retry_timeout;
+    }
+  }
+#endif /* SNTP_RETRY_TIMEOUT_EXP */
+}
+
+#if SNTP_SUPPORT_MULTIPLE_SERVERS
+/**
+ * If Kiss-of-Death is received (or another packet parsing error),
+ * try the next server or retry the current server and increase the retry
+ * timeout if only one server is available.
+ *
+ * @param arg is unused (only necessary to conform to sys_timeout)
+ */
+static void
+sntp_try_next_server(void* arg)
+{
+  LWIP_UNUSED_ARG(arg);
+
+  if (sntp_num_servers > 1) {
+    /* new server: reset retry timeout */
+    SNTP_RESET_RETRY_TIMEOUT();
+    sntp_current_server++;
+    if (sntp_current_server >= sntp_num_servers) {
+      sntp_current_server = 0;
+    }
+    LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_try_next_server: Sending request to server %"U16_F"\n",
+      (u16_t)sntp_current_server));
+    /* instantly send a request to the next server */
+    sntp_request(NULL);
+  } else {
+    sntp_retry(NULL);
+  }
+}
+#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */
+/* Always retry on error if only one server is supported */
+#define sntp_try_next_server    sntp_retry
+#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */
+
+/** UDP recv callback for the sntp pcb */
+static void
+sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
+{
+  u8_t mode;
+  u8_t stratum;
+  u32_t receive_timestamp[SNTP_RECEIVE_TIME_SIZE];
+  err_t err;
+
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(pcb);
+
+  /* packet received: stop retry timeout  */
+  sys_untimeout(sntp_try_next_server, NULL);
+  sys_untimeout(sntp_request, NULL);
+
+  err = ERR_ARG;
+#if SNTP_CHECK_RESPONSE >= 1
+  /* check server address and port */
+  if (ip_addr_cmp(addr, &sntp_last_server_address) &&
+    (port == SNTP_PORT))
+#else /* SNTP_CHECK_RESPONSE >= 1 */
+  LWIP_UNUSED_ARG(addr);
+  LWIP_UNUSED_ARG(port);
+#endif /* SNTP_CHECK_RESPONSE >= 1 */
+  {
+    /* process the response */
+    if (p->tot_len == SNTP_MSG_LEN) {
+      pbuf_copy_partial(p, &mode, 1, SNTP_OFFSET_LI_VN_MODE);
+      mode &= SNTP_MODE_MASK;
+      /* if this is a SNTP response... */
+      if ((mode == SNTP_MODE_SERVER) ||
+          (mode == SNTP_MODE_BROADCAST)) {
+        pbuf_copy_partial(p, &stratum, 1, SNTP_OFFSET_STRATUM);
+        if (stratum == SNTP_STRATUM_KOD) {
+          /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
+          err = SNTP_ERR_KOD;
+          LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n"));
+        } else {
+#if SNTP_CHECK_RESPONSE >= 2
+          /* check originate_timetamp against sntp_last_timestamp_sent */
+          u32_t originate_timestamp[2];
+          pbuf_copy_partial(p, &originate_timestamp, 8, SNTP_OFFSET_ORIGINATE_TIME);
+          if ((originate_timestamp[0] != sntp_last_timestamp_sent[0]) ||
+              (originate_timestamp[1] != sntp_last_timestamp_sent[1]))
+          {
+            LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid originate timestamp in response\n"));
+          } else
+#endif /* SNTP_CHECK_RESPONSE >= 2 */
+          /* @todo: add code for SNTP_CHECK_RESPONSE >= 3 and >= 4 here */
+          {
+            /* correct answer */
+            err = ERR_OK;
+            pbuf_copy_partial(p, &receive_timestamp, SNTP_RECEIVE_TIME_SIZE * 4, SNTP_OFFSET_RECEIVE_TIME);
+          }
+        }
+      } else {
+        LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid mode in response: %"U16_F"\n", (u16_t)mode));
+      }
+    } else {
+      LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid packet length: %"U16_F"\n", p->tot_len));
+    }
+  }
+  pbuf_free(p);
+  if (err == ERR_OK) {
+    /* Correct response, reset retry timeout */
+    SNTP_RESET_RETRY_TIMEOUT();
+
+    sntp_process(receive_timestamp);
+
+    /* Set up timeout for next request */
+    sys_timeout((u32_t)SNTP_UPDATE_DELAY, sntp_request, NULL);
+    LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Scheduled next time request: %"U32_F" ms\n",
+      (u32_t)SNTP_UPDATE_DELAY));
+  } else if (err == SNTP_ERR_KOD) {
+    /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
+    sntp_try_next_server(NULL);
+  } else {
+    /* another error, try the same server again */
+    sntp_retry(NULL);
+  }
+}
+
+/** Actually send an sntp request to a server.
+ *
+ * @param server_addr resolved IP address of the SNTP server
+ */
+static void
+sntp_send_request(ip_addr_t *server_addr)
+{
+  struct pbuf* p;
+  p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM);
+  if (p != NULL) {
+    struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload;
+    LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n"));
+    /* initialize request message */
+    sntp_initialize_request(sntpmsg);
+    /* send request */
+    udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT);
+    /* free the pbuf after sending it */
+    pbuf_free(p);
+    /* set up receive timeout: try next server or retry on timeout */
+    sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL);
+#if SNTP_CHECK_RESPONSE >= 1
+    /* save server address to verify it in sntp_recv */ 
+    ip_addr_set(&sntp_last_server_address, server_addr);
+#endif /* SNTP_CHECK_RESPONSE >= 1 */
+  } else {
+    LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n",
+      (u32_t)SNTP_RETRY_TIMEOUT));
+    /* out of memory: set up a timer to send a retry */
+    sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL);
+  }
+}
+
+#if SNTP_SERVER_DNS
+/**
+ * DNS found callback when using DNS names as server address.
+ */
+static void
+sntp_dns_found(const char* hostname, ip_addr_t *ipaddr, void *arg)
+{
+  LWIP_UNUSED_ARG(hostname);
+  LWIP_UNUSED_ARG(arg);
+
+  if (ipaddr != NULL) {
+    /* Address resolved, send request */
+    LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_dns_found: Server address resolved, sending request\n"));
+    sntp_send_request(ipaddr);
+  } else {
+    /* DNS resolving failed -> try another server */
+    LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_dns_found: Failed to resolve server address resolved, trying next server\n"));
+    sntp_try_next_server(NULL);
+  }
+}
+#endif /* SNTP_SERVER_DNS */
+
+/**
+ * Send out an sntp request.
+ *
+ * @param arg is unused (only necessary to conform to sys_timeout)
+ */
+static void
+sntp_request(void *arg)
+{
+  ip_addr_t sntp_server_address;
+  err_t err;
+
+  LWIP_UNUSED_ARG(arg);
+
+  /* initialize SNTP server address */
+#if SNTP_SERVER_DNS
+  err = dns_gethostbyname(sntp_server_addresses[sntp_current_server], &sntp_server_address,
+    sntp_dns_found, NULL);
+  if (err == ERR_INPROGRESS) {
+    /* DNS request sent, wait for sntp_dns_found being called */
+    LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_request: Waiting for server address to be resolved.\n"));
+    return;
+  }
+#else /* SNTP_SERVER_DNS */
+  err = ipaddr_aton(sntp_server_addresses[sntp_current_server], &sntp_server_address)
+    ? ERR_OK : ERR_ARG;
+
+#endif /* SNTP_SERVER_DNS */
+
+  if (err == ERR_OK) {
+    sntp_send_request(&sntp_server_address);
+  } else {
+    /* address conversion failed, try another server */
+    LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_request: Invalid server address, trying next server.\n"));
+    sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_try_next_server, NULL);
+  }
+}
+
+/**
+ * Initialize this module.
+ * Send out request instantly or after SNTP_STARTUP_DELAY.
+ */
+void
+sntp_init(void)
+{
+  if (sntp_pcb == NULL) {
+    SNTP_RESET_RETRY_TIMEOUT();
+    sntp_pcb = udp_new();
+    LWIP_ASSERT("Failed to allocate udp pcb for sntp client", sntp_pcb != NULL);
+    if (sntp_pcb != NULL) {
+      udp_recv(sntp_pcb, sntp_recv, NULL);
+#if SNTP_STARTUP_DELAY
+      sys_timeout((u32_t)SNTP_STARTUP_DELAY, sntp_request, NULL);
+#else
+      sntp_request(NULL);
+#endif
+    }
+  }
+}
+
+/**
+ * Stop this module.
+ */
+void
+sntp_stop(void)
+{
+  if (sntp_pcb != NULL) {
+    sys_untimeout(sntp_request, NULL);
+    udp_remove(sntp_pcb);
+    sntp_pcb = NULL;
+  }
+}
+#endif /* LWIP_UDP */
Index: UsbWattMeter/trunk/lwip-1.4.1/apps/sntp/sntp.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/apps/sntp/sntp.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/apps/sntp/sntp.h	(revision 164)
@@ -0,0 +1,15 @@
+#ifndef __SNTP_H__
+#define __SNTP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void sntp_init(void);
+void sntp_stop(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SNTP_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/arch/sys_arch.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/arch/sys_arch.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/arch/sys_arch.h	(revision 164)
@@ -0,0 +1,98 @@
+/*
+ * æ3ñ TOPPERSpACfAEAvP[VJ­ReXg
+ * ¼Y õm³ñÌulwIP ÌÚAvðx[XÉµÜµ½B
+ * http://www.toppers.jp/contest.html
+ *
+ *  @(#) $Id$
+ */
+#ifndef __ARCH_SYS_ARCH_H__
+#define __ARCH_SYS_ARCH_H__
+
+#include <kernel.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef _MSC_VER
+#include <sys/types.h>
+#include <sys/time.h>
+#else
+#include <time.h>
+#include <io.h>
+#endif // _MSC_VER
+#include <ff.h>
+
+typedef ID sys_sem_t;
+typedef ID sys_mbox_t;
+typedef ID sys_thread_t;
+
+#define sys_sem_valid( x ) ( ( ( *x ) == (sys_sem_t)NULL) ? 0 : 1 )
+#define sys_sem_set_invalid( x ) ( ( *x ) = (sys_sem_t)NULL )
+#define sys_mbox_valid( x ) ( ( ( *x ) == (sys_mbox_t)NULL) ? 0 : 1 )
+#define sys_mbox_set_invalid( x ) ( ( *x ) = (sys_mbox_t)NULL )
+
+extern void *sys_malloc(size_t size);
+extern void *sys_calloc(size_t count, size_t size);
+extern void *sys_realloc(void *ptr, size_t size);
+extern void  sys_free(void *mem);
+extern void *sys_trim(void *mem, size_t size);
+
+extern void sys_sleep(uint32_t ms);
+
+/* let sys.h use binary semaphores for mutexes */
+#define LWIP_COMPAT_MUTEX 1
+
+extern FIL *sys_fopen(const char *, const char *);
+#define fopen sys_fopen
+extern long sys_fseek(FIL *, long, long);
+#define fseek sys_fseek
+extern long sys_lseek(FIL *, long offset, int origin);
+#define lseek sys_lseek
+extern long sys_ftell(FIL *);
+#define ftell sys_ftell
+extern long sys_fclose(FIL *);
+#define fclose sys_fclose
+extern size_t sys_fread(void *, size_t, size_t, FIL *);
+#define fread sys_fread
+extern size_t sys_fwrite(const void *, size_t, size_t, FIL *);
+#define fwrite sys_fwrite
+extern long sys_fputs(const char *, FIL *);
+#define fputs sys_fputs
+extern long sys_fputc(long, FIL *);
+#define fputc sys_fputc
+extern long sys_fflush(FIL *);
+#define fflush sys_fflush
+extern char *sys_fgets(char *, long, FIL *);
+#define fgets sys_fgets
+extern long sys_ferror(FIL *);
+#define ferror sys_ferror
+extern long sys_rewind(FIL *);
+#define rewind sys_rewind
+extern long sys_fprintf(FIL *, const char *, ...);
+#define fprintf sys_fprintf
+
+extern void sys_exit(int error);
+#define exit sys_exit
+
+#undef stdin
+extern FIL *sys_stdin;
+#define stdin sys_stdin
+#undef stdout
+extern FIL *sys_stdout;
+#define stdout sys_stdout
+#undef stderr
+extern FIL *sys_stderr;
+#define stderr sys_stderr
+#define FILE FIL
+
+#define malloc(sz) sys_malloc(sz)
+#define calloc(cnt, sz) sys_calloc(cnt, sz)
+#define realloc(ptr, sz) sys_realloc(ptr, sz)
+#define free(ptr) sys_free(ptr)
+
+extern time_t sys_time(time_t *t);
+#define time sys_time
+extern struct tm *sys_gmtime(const time_t *pt);
+#define gmtime sys_gmtime
+struct tm *gmtime_r(const time_t *pt, struct tm* tm);
+extern void sys_set_system_time(time_t t);
+
+#endif /* __ARCH_SYS_ARCH_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/lwip_task.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/lwip_task.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/lwip_task.c	(revision 164)
@@ -0,0 +1,55 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+#include <kernel.h>
+#include "lwip_task.h"
+
+extern void ethernetif_input(struct netif *netif);
+
+void lwip_task(intptr_t exinf)
+{
+	struct lwip_task_t *lwip_task = (struct lwip_task_t *)exinf;
+	ER ret;
+
+	do {
+		ethernetif_input(&lwip_task->netif);
+		ret = wai_sem(lwip_task->sem_rev);
+	} while(ret == E_OK);
+}
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/lwip_task.cfg
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/lwip_task.cfg	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/lwip_task.cfg	(revision 164)
@@ -0,0 +1,49 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+#include "lwip_task.h"
+
+
+/*
+ * lwIP^XN
+ */
+CRE_TSK(LWIP_TASK,	{ TA_NULL, (intptr_t)&lwiptsk, lwip_task, LWIP_TASK_PRIORITY, LWIP_TASK_STACK_SIZE, NULL });
+
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/lwip_task.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/lwip_task.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/lwip_task.h	(revision 164)
@@ -0,0 +1,76 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef LWIP_TASK_H_
+#define LWIP_TASK_H_
+
+//#include "lwip_target_config.h"
+#include "lwip/netif.h"
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  uIP ^XNÖAÌèÌftHglÌè`
+ */ 
+#ifndef LWIP_TASK_PRIORITY
+#define LWIP_TASK_PRIORITY	3		/* úDæx */
+#endif /* LWIP_TASK_PRIORITY */
+
+#ifndef LWIP_TASK_STACK_SIZE
+#define LWIP_TASK_STACK_SIZE	1024	/* X^bNÌæÌTCY */
+#endif /* LWIP_TASK_STACK_SIZE */
+
+struct lwip_task_t {
+	struct netif netif;
+	ID sem_rev;		/* struct ethernetif */
+};
+
+extern struct lwip_task_t lwiptsk;
+
+void lwip_task(intptr_t exinf);
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* LWIP_TASK_H_ */
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/sys_arch.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/sys_arch.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/asp_dcre/sys_arch.c	(revision 164)
@@ -0,0 +1,563 @@
+/*
+ * æ3ñ TOPPERSpACfAEAvP[VJ­ReXg
+ * ¼Y õm³ñÌulwIP ÌÚAvðx[XÉµÜµ½B
+ * http://www.toppers.jp/contest.html
+ *
+ *  @(#) $Id$
+ */
+#include <string.h>
+#include <kernel.h>
+#include <t_syslog.h>
+
+#include "arch/sys_arch.h"
+
+#include "lwip/opt.h"
+#include "lwip/debug.h"
+#include "lwip/def.h"
+#include "lwip/sys.h"
+#include "lwip/mem.h"
+#include "lwip/stats.h"
+#include "tlsf.h"
+
+static tlsf_t lwip_tlsf;
+static pool_t lwip_pool;
+extern void *lwip_heap;
+extern size_t lwip_heapsz;
+extern ID _echonet_ecn_mem_semid;
+
+void syslog_info(const char *format, ...)
+{
+	va_list	ap;
+	va_start(ap, format);
+	vsyslog(LOG_NOTICE, format, ap);
+	va_end(ap);
+}
+
+void syslog_assert(const char *format, ...)
+{
+	va_list	ap;
+	va_start(ap, format);
+	vsyslog(LOG_EMERG, format, ap);
+	va_end(ap);
+}
+
+void sys_init(void)
+{
+	lwip_tlsf = tlsf_create(lwip_heap);
+	if (lwip_tlsf == NULL)
+		return;
+
+	lwip_pool = tlsf_add_pool(lwip_tlsf, ((uint8_t *)lwip_heap) + tlsf_size(), lwip_heapsz - tlsf_size());
+}
+
+err_t sys_sem_new(sys_sem_t *sem, u8_t count)
+{
+	err_t ret = ERR_VAL;
+
+	syslog(LOG_DEBUG, "sys_sem_new in\n");
+	if (NULL != sem) {
+		T_CSEM csem = { TA_TPRI, (uint_t)count, (uint_t)1 };
+		ID id = acre_sem(&csem);
+		if (0 < id) {
+			*sem = id;
+			ret = ERR_OK;
+			syslog(LOG_DEBUG, "sys_sem_new out %d, %d\n", *sem, count);
+		}
+		else {
+			*sem = (sys_sem_t)NULL;
+			syslog(LOG_DEBUG, "sys_sem_new out ERROR!\n");
+		}
+	}
+	return ret;
+}
+
+void sys_sem_free(sys_sem_t *sem)
+{
+	syslog(LOG_DEBUG, "sys_sem_free in %d\n", *sem);
+	del_sem(*sem);
+	*sem = (sys_sem_t)NULL;
+	syslog(LOG_DEBUG, "sys_sem_free out\n");
+	return;
+}
+
+void sys_sem_signal(sys_sem_t *sem)
+{
+	syslog(LOG_DEBUG, "sys_sem_signal in %d\n", *sem);
+	sig_sem(*sem);
+	syslog(LOG_DEBUG, "sys_sem_signal out %d\n", *sem);
+	return;
+}
+
+u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
+{
+	SYSTIM systim0, systim1;
+	ER ercd;
+
+	get_tim(&systim0);
+	syslog(LOG_DEBUG, "sys_arch_sem_wait in %d\n", *sem);
+	if (timeout) {
+		ercd = twai_sem(*sem, (TMO)timeout);
+	}
+	else {
+		ercd = wai_sem(*sem);
+	}
+
+	if (E_OK == ercd) {
+		get_tim(&systim1);
+		syslog(LOG_DEBUG, "sys_arch_sem_wait out %d, E_OK\n", *sem);
+		return (u32_t)(systim1 - systim0);
+	}
+	syslog(LOG_DEBUG, "sys_arch_sem_wait out %d, SYS_ARCH_TIMEOUT\n", *sem);
+	return SYS_ARCH_TIMEOUT;
+}
+
+err_t sys_mbox_new(sys_mbox_t *mbox, int size)
+{
+	err_t ret = ERR_VAL;
+
+	syslog(LOG_DEBUG, "sys_mbox_new in\n");
+	if (NULL != mbox) {
+		T_CDTQ cdtq = { TA_NULL, (uint_t)size, (void *)NULL };
+		ID id = acre_dtq(&cdtq);
+		if (0 < id) {
+			*mbox = id;
+			ret = ERR_OK;
+			syslog(LOG_DEBUG, "sys_mbox_new out %d, %d\n", *mbox, size);
+		}
+		else {
+			*mbox = (sys_mbox_t)NULL;
+			syslog(LOG_DEBUG, "sys_mbox_new out ERROR!\n");
+		}
+	}
+	return ret;
+}
+
+void sys_mbox_free(sys_mbox_t *mbox)
+{
+	syslog(LOG_DEBUG, "sys_mbox_free in %d\n", *mbox);
+	del_dtq(*mbox);
+	*mbox = (sys_mbox_t)NULL;
+	syslog(LOG_DEBUG, "sys_mbox_free out\n");
+	return;
+}
+
+void sys_mbox_post(sys_mbox_t *mbox, void *msg)
+{
+	syslog(LOG_DEBUG, "sys_mbox_post in %d, 0x%08x\n", *mbox, msg);
+	snd_dtq(*mbox, (intptr_t)msg);
+	syslog(LOG_DEBUG, "sys_mbox_post out %d, 0x%08x\n", *mbox, msg);
+	return;
+}
+
+err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
+{
+	err_t ret = ERR_VAL;
+
+	syslog(LOG_DEBUG, "sys_mbox_trypost in %d, 0x%08x\n", *mbox, msg);
+	if (E_OK == psnd_dtq(*mbox, (intptr_t)msg)) {
+		ret = ERR_OK;
+	}
+	syslog(LOG_DEBUG, "sys_mbox_trypost out %d, 0x%08x %d\n", *mbox, msg, ret);
+	return ret;
+}
+
+u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
+{
+	SYSTIM systim0, systim1;
+	ER ercd;
+
+	get_tim(&systim0);
+	syslog(LOG_DEBUG, "sys_arch_mbox_fetch in %d\n", *mbox);
+	if (timeout) {
+		ercd = trcv_dtq(*mbox, (intptr_t *)msg, timeout);
+	}
+	else {
+		ercd = rcv_dtq(*mbox, (intptr_t*)msg);
+	}
+
+	if (E_OK == ercd) {
+		get_tim(&systim1);
+		syslog(LOG_DEBUG, "sys_arch_mbox_fetch out %d, E_OK\n", *mbox);
+		return (u32_t)(systim1 - systim0);
+	}
+	syslog(LOG_DEBUG, "sys_arch_mbox_fetch out %d, SYS_ARCH_TIMEOUT\n", *mbox);
+	return SYS_ARCH_TIMEOUT;
+}
+
+u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
+{
+	syslog(LOG_DEBUG, "sys_arch_mbox_tryfetch in %d\n", *mbox);
+	if (E_OK == prcv_dtq(*mbox, (intptr_t *)msg)) {
+		syslog(LOG_DEBUG, "sys_arch_mbox_tryfetch out %d, 0x%08x, ERR_OK\n", *mbox, *msg);
+		return (u32_t)ERR_OK;
+	}
+	syslog(LOG_DEBUG, "sys_arch_mbox_tryfetch out %d, SYS_MBOX_EMPTY\n", *mbox);
+	return SYS_MBOX_EMPTY;
+}
+
+sys_thread_t sys_thread_new(const char *name, void(*thread)(void *), void *arg, int stacksize, int prio)
+{
+	syslog(LOG_DEBUG, "sys_thread_new in\n");
+
+	T_CTSK ctsk = { TA_ACT, (intptr_t)arg, (TASK)thread, (PRI)prio, (SIZE)stacksize, (STK_T *)NULL };
+	ID id = acre_tsk(&ctsk);
+
+	syslog(LOG_DEBUG, "sys_thread_new %s, %d, %d, %d\n", name, stacksize, prio, id);
+	return (sys_thread_t)id;
+}
+
+sys_prot_t sys_arch_protect(void)
+{
+	bool_t state = sns_loc();
+	if (!state) {
+		loc_cpu();
+	}
+	return (sys_prot_t)(~state);
+}
+
+void sys_arch_unprotect(sys_prot_t pval)
+{
+	if (pval) {
+		unl_cpu();
+	}
+	return;
+}
+
+u32_t sys_now(void)
+{
+	SYSTIM systim;
+
+	get_tim(&systim);
+	return (u32_t)systim;
+}
+
+void *sys_malloc(size_t size)
+{
+	ER ret;
+	void *p;
+
+	ret = wai_sem(_echonet_ecn_mem_semid);
+
+	p = tlsf_malloc(lwip_tlsf, size);
+
+	if (ret == E_OK)
+		sig_sem(_echonet_ecn_mem_semid);
+
+	if (p == NULL) {
+		syslog(LOG_ERROR, "tlsf_malloc %d", size);
+	}
+
+	return p;
+}
+
+void *sys_calloc(size_t count, size_t size)
+{
+	ER ret;
+	void *p;
+
+	ret = wai_sem(_echonet_ecn_mem_semid);
+
+	p = tlsf_malloc(lwip_tlsf, count * size);
+
+	if (ret == E_OK)
+		sig_sem(_echonet_ecn_mem_semid);
+
+	if (p != NULL) {
+		memset(p, 0, count * size);
+	}
+	else {
+		syslog(LOG_ERROR, "tlsf_malloc %d", size);
+	}
+
+	return p;
+}
+
+void *sys_realloc(void *ptr, size_t size)
+{
+	ER ret;
+	void *p;
+
+	ret = wai_sem(_echonet_ecn_mem_semid);
+
+	p = tlsf_realloc(lwip_tlsf, ptr, size);
+
+	if (ret == E_OK)
+		sig_sem(_echonet_ecn_mem_semid);
+
+	if (p == NULL) {
+		syslog(LOG_ERROR, "tlsf_realloc %d", size);
+	}
+
+	return p;
+}
+
+void sys_free(void *mem)
+{
+	ER ret;
+
+	ret = wai_sem(_echonet_ecn_mem_semid);
+
+	tlsf_free(lwip_tlsf, mem);
+
+	if (ret == E_OK)
+		sig_sem(_echonet_ecn_mem_semid);
+}
+
+void *sys_trim(void *mem, size_t size)
+{
+	return mem;
+}
+
+void sys_sleep(uint32_t ms)
+{
+	dly_tsk(ms);
+}
+
+void sys_sprintf(void *dst, const char *fmt, ...)
+{
+	va_list arp;
+	unsigned int r, i, j, w, f;
+	unsigned long v;
+	char s[16], c, d, *p;
+	char *pos = (char *)dst;
+
+	va_start(arp, fmt);
+
+	for (;;) {
+		c = *fmt++;					/* Get a char */
+		if (!c) break;				/* End of format? */
+		if (c != '%') {				/* Pass through it if not a % sequense */
+			*pos++ = c; continue;
+		}
+		f = 0;
+		c = *fmt++;					/* Get first char of the sequense */
+		if (c == '0') {				/* Flag: '0' padded */
+			f = 1; c = *fmt++;
+		}
+		else {
+			if (c == '-') {			/* Flag: left justified */
+				f = 2; c = *fmt++;
+			}
+		}
+		for (w = 0; c >= '0' && c <= '9'; c = *fmt++)	/* Minimum width */
+			w = w * 10 + c - '0';
+		if (c == 'l' || c == 'L') {	/* Prefix: Size is long int */
+			f |= 4; c = *fmt++;
+		}
+		if (!c) break;				/* End of format? */
+		d = c;
+		if (d >= 'a') d -= 0x20;
+		switch (d) {				/* Type is... */
+		case 'S':					/* String */
+			p = va_arg(arp, char*);
+			for (j = 0; p[j]; j++);
+			while (!(f & 2) && j++ < w) *pos++ = ' ';
+			while (*p != '\0') *pos++ = *p++;
+			while (j++ < w) *pos++ = ' ';
+			continue;
+		case 'C':					/* Character */
+			*pos++ = (char)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 (passthrough) */
+			*pos++ = c; continue;
+		}
+
+		/* Get an argument and put it in numeral */
+		v = (f & 4) ? va_arg(arp, long) : ((d == 'D') ? (long)va_arg(arp, int) : (long)va_arg(arp, unsigned int));
+		if (d == 'D' && (v & 0x80000000)) {
+			v = 0 - v;
+			f |= 8;
+		}
+		i = 0;
+		do {
+			d = (char)(v % r); v /= r;
+			if (d > 9) d += (c == 'x') ? 0x27 : 0x07;
+			s[i++] = d + '0';
+		} while (v && i < sizeof(s));
+		if (f & 8) s[i++] = '-';
+		j = i; d = (f & 1) ? '0' : ' ';
+		while (!(f & 2) && j++ < w) *pos++ = d;
+		do *pos++ = s[--i]; while (i);
+		while (j++ < w) *pos++ = ' ';
+	}
+
+	va_end(arp);
+}
+
+FIL fil[3];
+#define fil_count (sizeof(fil) / sizeof(fil[0]))
+
+FIL *sys_fopen(const char *file, const char *mode)
+{
+	FIL *result = NULL;
+	int i;
+
+	for (i = 0; i < fil_count; i++) {
+		if (fil[i].fs == NULL) {
+			result = &fil[i];
+			break;
+		}
+	}
+
+	if (result == NULL)
+		return NULL;
+
+	if (f_open(result, file, mode[0] == 'r' ? FA_READ : FA_WRITE) != FR_OK) {
+		return NULL;
+	}
+
+	return result;
+}
+
+size_t sys_fread(void *data, size_t len, size_t size, FIL *fp)
+{
+	UINT result;
+
+	switch ((intptr_t)fp) {
+	case 1:
+	case 2:
+	case 3:
+		return 0;
+	default:
+		if (f_read(fp, data, len * size, &result) != FR_OK) {
+			return 0;
+		}
+		break;
+	}
+
+	return result;
+}
+
+size_t sys_fwrite(const void *data, size_t len, size_t size, FIL *fp)
+{
+	UINT result;
+
+	switch ((intptr_t)fp) {
+	case 1:
+		syslog(LOG_ERROR, data);
+		return len * size;
+	case 2:
+		syslog(LOG_NOTICE, data);
+		return len * size;
+	case 3:
+		return 0;
+	default:
+		if (f_write(fp, data, len * size, &result) != FR_OK) {
+			return 0;
+		}
+		break;
+	}
+
+	return result;
+}
+
+long sys_fseek(FIL *fp, long ofs, long mode)
+{
+	FRESULT res;
+
+	switch (mode) {
+	case SEEK_SET:
+		res = f_lseek((fp), ofs);
+		break;
+	case SEEK_CUR:
+		res = f_lseek((fp), (fp)->fptr + ofs);
+		break;
+	case SEEK_END:
+		res = f_lseek((fp), (fp)->fsize - ofs);
+		break;
+	default:
+		return -1;
+	}
+
+	return (res == FR_OK) ? 0 : -1;
+}
+
+long sys_fclose(FIL *fp)
+{
+	if (f_close(fp) != FR_OK)
+		return EOF;
+	return 0;
+}
+
+char *sys_fgets(char *buf, long len, FIL *fp)
+{
+	return f_gets(buf, len, fp);
+}
+
+long sys_fputc(long data, FIL *fp)
+{
+	switch ((intptr_t)fp) {
+	case 1:
+		syslog(LOG_ERROR, "%c", data);
+		return 0;
+	case 2:
+		syslog(LOG_NOTICE, "%c", data);
+		return 0;
+	case 3:
+		return -1;
+	default:
+		return f_putc(data, fp);
+	}
+}
+
+long sys_fputs(const char *data, FIL *fp)
+{
+	switch ((intptr_t)fp) {
+	case 1:
+		syslog(LOG_ERROR, data);
+		return 0;
+	case 2:
+		syslog(LOG_NOTICE, data);
+		return 0;
+	case 3:
+		return -1;
+	default:
+		return f_puts(data, fp);
+	}
+}
+
+long sys_fflush(FIL *fp)
+{
+	return 0;
+}
+
+long sys_lseek(FIL *fp, long offset, int origin)
+{
+	if (f_lseek(fp, offset) != FR_OK) {
+		return -1;
+	}
+
+	return 0;
+}
+
+long sys_ftell(FIL *fp)
+{
+	return f_tell(fp);
+}
+
+long sys_ferror(FIL *fp)
+{
+	return fp->err;
+}
+
+long sys_rewind(FIL *fp)
+{
+	if (f_lseek(fp, 0) != FR_OK) {
+		return -1;
+	}
+
+	return 0;
+}
+
+void sys_exit(int error)
+{
+	abort();
+}
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/ccrx/sys/time.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/ccrx/sys/time.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/ccrx/sys/time.h	(revision 164)
@@ -0,0 +1,19 @@
+
+#ifndef _SYS_TIME_H
+#define _SYS_TIME_H
+
+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;
+    char *tm_zone;
+};
+
+#endif /* _SYS_TIME_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/ccrx/sys/types.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/ccrx/sys/types.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/ccrx/sys/types.h	(revision 164)
@@ -0,0 +1,7 @@
+
+#ifndef _SYS_TYPES_H
+#define _SYS_TYPES_H
+
+typedef long long time_t;
+
+#endif /* _SYS_TYPES_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/ccrx/time.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/ccrx/time.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/ccrx/time.h	(revision 164)
@@ -0,0 +1,10 @@
+
+#ifndef _TIME_H
+#define _TIME_H
+
+#include "sys/types.h"
+
+time_t time(time_t *time);
+struct tm* gmtime_r(const time_t* timer, struct tm* tmp);
+
+#endif /* _TIME_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/arch/bpstruct.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/arch/bpstruct.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/arch/bpstruct.h	(revision 164)
@@ -0,0 +1,7 @@
+#if defined(__CA850__)
+#pragma pack(1)
+#elif defined(__RX)
+#pragma pack
+#elif defined(_MSC_VER)
+#pragma pack(push, 1)
+#endif
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/arch/cc.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/arch/cc.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/arch/cc.h	(revision 164)
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __ARCH_CC_H__
+#define __ARCH_CC_H__
+
+//#include <stdio.h> /* printf, fflush, FILE */
+#include <stdlib.h> /* abort */
+#include <limits.h>
+
+#include <t_stddef.h>
+#include <t_syslog.h>
+#include <stdarg.h>
+
+#ifdef _MSC_VER
+#pragma warning (disable: 4244) /* disable conversion warning (implicit integer promotion!) */
+#pragma warning (disable: 4127) /* conditional expression is constant */
+#pragma warning (disable: 4996) /* 'strncpy' was declared deprecated */
+#pragma warning (disable: 4103) /* structure packing changed by including file */
+#endif
+
+/*#define LWIP_PROVIDE_ERRNO*/
+#ifdef __RX
+#define EADDRINUSE			0x1000
+#define EADDRNOTAVAIL		0x1001
+#define EAFNOSUPPORT		0x1002
+#define EALREADY			0x1003
+#define ECONNABORTED		0x1004
+#define ECONNREFUSED		0x1005
+#define ECONNRESET			0x1006
+#define EHOSTUNREACH		0x1007
+#define ENOBUFS				0x1008
+#define ENOPROTOOPT			0x1009
+#define ENOTCONN			0x100A
+#define EOPNOTSUPP			0x100B
+#define EWOULDBLOCK			0x100C
+#endif
+
+/* Define platform endianness (might already be defined) */
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif /* BYTE_ORDER */
+
+/* Define generic types used in lwIP */
+typedef unsigned   char    u8_t;
+typedef signed     char    s8_t;
+typedef unsigned   short   u16_t;
+typedef signed     short   s16_t;
+typedef unsigned   long    u32_t;
+typedef signed     long    s32_t;
+
+typedef size_t mem_ptr_t;
+typedef u32_t sys_prot_t;
+
+/* Define (sn)printf formatters for these lwIP types */
+#define X8_F  "02x"
+#define U16_F "hu"
+#define U32_F "lu"
+#define S32_F "ld"
+#define X32_F "lx"
+
+#ifdef __GNUC__
+#define S16_F "d"
+#define X16_F "uX"
+#define SZT_F "u"
+#else
+#define S16_F "hd"
+#define X16_F "hx"
+#define SZT_F "lu"
+#endif
+
+/* Compiler hints for packing structures */
+#define PACK_STRUCT_STRUCT
+#define PACK_STRUCT_USE_INCLUDES
+
+/* Plaform specific diagnostic output */
+extern void syslog_info(const char *format, ...);
+extern void syslog_assert(const char *format, ...);
+
+#ifdef __RX
+#define LWIP_PLATFORM_DIAG(x)   
+#define LWIP_PLATFORM_ASSERT(x) do { abort(); } while(0)
+#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
+  handler; } } while(0)
+#else
+#define LWIP_PLATFORM_DIAG(x)   do { syslog_info x; } while(0)
+
+#define LWIP_PLATFORM_ASSERT(x) do { syslog_assert("Assertion \"%s\" failed at line %d in %s\n", \
+                                     x, __LINE__, __FILE__); abort(); } while(0)
+
+#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
+  syslog_assert("Assertion \"%s\" failed at line %d in %s\n", message, __LINE__, __FILE__); \
+  handler; } } while(0)
+#endif
+
+
+#if 0/*def _MSC_VER*/
+/* C runtime functions redefined */
+#define snprintf _snprintf
+#endif
+
+u32_t dns_lookup_external_hosts_file(const char *name);
+
+#define LWIP_RAND() ((u32_t)rand())
+
+#endif /* __ARCH_CC_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/arch/epstruct.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/arch/epstruct.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/arch/epstruct.h	(revision 164)
@@ -0,0 +1,7 @@
+#if defined(__CA850__)
+#pragma pack(8)
+#elif defined(__RX)
+#pragma unpack
+#elif defined(_MSC_VER)
+#pragma pack(pop)
+#endif
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/arch/perf.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/arch/perf.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/arch/perf.h	(revision 164)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __PERF_H__
+#define __PERF_H__
+
+#define PERF_START    /* null definition */
+#define PERF_STOP(x)  /* null definition */
+
+#endif /* __PERF_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/ether_phy.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/ether_phy.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/ether_phy.c	(revision 164)
@@ -0,0 +1,371 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $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ÌZbg */
+		phy_write_reg(phy_addr, PHY_CONTROL_REGISTER, PHY_CONTROL_RESET);
+
+		/* 500msÒÂ */
+		/* tslp_tsk(500); svH */
+		/* continue; */
+	case PHY_STATE_RESETING:
+		/* Zbg®¹ÌmF */
+		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)
+{
+#ifndef __RX
+	static int reset = 0;
+#endif
+	uint16_t status;
+	*mode = (PHY_MODE_T)0;
+
+	switch(state){
+	case PHY_STATE_RESET:
+#ifndef __RX
+		reset++;
+		if(reset < 2){
+#endif
+		/* N®¹ÌmF */
+		if(!phy_is_link(phy_addr))
+			return PHY_STATE_RESET;
+#ifndef __RX
+		}
+		reset = 0;
+#endif
+		/* I[glSVG[VÌ¨mç¹ðLøÉÝè */
+		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);
+
+		/* I[glSVG[VðLøÉÝè */
+		phy_write_reg(phy_addr, PHY_CONTROL_REGISTER, PHY_CONTROL_SPEED_SELECT | PHY_CONTROL_A_N_ENABLE);
+
+		/* continue; */
+	case PHY_STATE_LINKED:
+#ifndef __RX
+		reset++;
+		if(reset < 2){
+#endif
+		/* I[glSVG[V®¹ÌmF */
+		if((phy_read_reg(phy_addr, PHY_STATUS_REGISTER) & PHY_STATUS_A_N_COMPLETE) == 0)
+			return PHY_STATE_LINKED;
+#ifndef __RX
+		}
+#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)
+{
+#ifdef __RX
+	/* NÌmF */
+	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 F32ÂÌA±µ½1b */
+	for (i = 0; i < 32; i++)
+		phy_write_bit(true);
+
+	/* ST Ft[Ìæªð¦·01bÌCg */
+	phy_write_bit(false);
+	phy_write_bit(true);
+
+	/* OP FANZXíÊð¦·R[hÌCg */
+	phy_write_bit(true);
+	phy_write_bit(false);
+
+	/* PHYAD FPHY-LSIÌAhXª1ÔÌêA00001bðCgiMSB ©çCgjB */
+	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 FWX^AhXª1ÔÌêA00001bðCgiMSB©çCgjB */
+	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 FMII/RMIIC^tF[XãÅf[^ÌM³ðØèÖ¦éÔ */
+	/* uoXðúviZ0Æ\Ljðs¤ */
+	phy_release_bus();
+
+	/* DATA F16rbgÌf[^BMSB©ç[h */
+	for (bit = 0x8000; bit != 0; bit >>= 1) {
+		if(phy_read_bit())
+			result |= bit;
+	}
+
+	/* IDLE FÌMIIÇtH[}bgüÍÜÅÌÒ@Ô */
+	/* ·ÅÉTAÉoXðúÏÝÅ è§äsv */
+	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 F32ÂÌA±µ½1b */
+	for (i = 0; i < 32; i++)
+		phy_write_bit(true);
+
+	/* ST Ft[Ìæªð¦·01bÌCg */
+	phy_write_bit(false);
+	phy_write_bit(true);
+
+	/* OP FANZXíÊð¦·R[hÌCg */
+	phy_write_bit(false);
+	phy_write_bit(true);
+
+	/* PHYAD FPHY-LSIÌAhXª1ÔÌêA00001bðCgiMSB ©çCgjB */
+	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 FWX^AhXª1ÔÌêA00001bðCgiMSB©çCgjB */
+	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 FMII/RMIIC^tF[XãÅf[^ÌM³ðØèÖ¦éÔ */
+	/* 10bðCg */
+	phy_write_bit(true);
+	phy_write_bit(false);
+
+	/* DATA F16rbgÌf[^BMSB©çCg */
+	for (bit = 0x8000; bit != 0; bit >>= 1) {
+		phy_write_bit((reg_data & bit) != 0);
+	}
+
+	/* IDLE FÌMIIÇtH[}bgüÍÜÅÌÒ@Ô */
+	/* uPÆoXðúviXÆ\Ljðs¤ */
+	phy_single_rel_bus();
+}
+
+#define ETHERC_PIR_WAIT 4
+
+/*
+ * 1 rbgf[^ÌCg
+ */
+static void phy_write_bit(bool_t bit)
+{
+	int i;
+	uint32_t data = bit ? ETHERC_PIR_MDO : 0;
+
+	/* PHYC^tF[XWX^ÖÌCg */
+	sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | 0/*ETHERC_PIR_MDC*/);
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHYC^tF[XWX^ÖÌCg */
+	sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | ETHERC_PIR_MDC);
+
+	for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHYC^tF[XWX^ÖÌCg */
+	sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | 0/*ETHERC_PIR_MDC*/);
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+}
+
+/*
+ * oXðú
+ */
+static void phy_release_bus()
+{
+	int i;
+
+	/* PHYC^tF[XWX^ÖÌCg */
+	sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHYC^tF[XWX^ÖÌCg */
+	sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | ETHERC_PIR_MDC);
+
+	for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHYC^tF[XWX^ÖÌCg */
+	sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+}
+
+/*
+ * 1 rbgf[^Ì[h
+ */
+static bool_t phy_read_bit()
+{
+	bool_t bit;
+	int i;
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHYC^tF[XWX^ÖÌCg */
+	sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | ETHERC_PIR_MDC);
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHYC^tF[XWX^ÖÌCg */
+	bit = (sil_rew_mem(ETHERC_PIR) & ETHERC_PIR_MDI) != 0;
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHYC^tF[XWX^ÖÌCg */
+	sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+
+	return bit;
+}
+
+/*
+ * PÆoXðú
+ */
+static void phy_single_rel_bus()
+{
+	int i;
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHYC^tF[XWX^ÖÌCg */
+	sil_wrw_mem(ETHERC_PIR, ETHERC_PIR_MMD | ETHERC_PIR_MDC);
+
+	for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHYC^tF[XWX^ÖÌCg */
+	sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+}
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/ether_phy.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/ether_phy.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/ether_phy.h	(revision 164)
@@ -0,0 +1,70 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $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_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: UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/if_rx62n.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/if_rx62n.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/if_rx62n.c	(revision 164)
@@ -0,0 +1,717 @@
+/**
+ * @file
+ * Ethernet Interface Skeleton
+ *
+ */
+
+ /*
+  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+  * All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *
+  * 1. Redistributions of source code must retain the above copyright notice,
+  *    this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright notice,
+  *    this list of conditions and the following disclaimer in the documentation
+  *    and/or other materials provided with the distribution.
+  * 3. The name of the author may not be used to endorse or promote products
+  *    derived from this software without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+  * OF SUCH DAMAGE.
+  *
+  * This file is part of the lwIP TCP/IP stack.
+  *
+  * Author: Adam Dunkels <adam@sics.se>
+  *
+  */
+
+  /*
+   * This file is a skeleton for developing Ethernet network interface
+   * drivers for lwIP. Add code to the low_level functions and do a
+   * search-and-replace for the word "ethernetif" to replace it with
+   * something that better describes your network interface.
+   */
+#ifdef _MSC_VER
+#pragma warning(disable : 4005)
+#endif
+#include "lwip/opt.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include <lwip/stats.h>
+#include <lwip/snmp.h>
+#include "netif/etharp.h"
+#include "netif/ppp_oe.h"
+#ifdef _MSC_VER
+#pragma warning(default : 4005)
+#endif
+#include <t_stddef.h>
+#include <sil.h>
+#include <kernel.h>
+#include <t_syslog.h>
+#ifdef __RX
+#include <rx630_ccrx/prc_rename.h>
+#else
+#include <rx630_msvc/prc_rename.h>
+#endif
+#include "if_rx62n.h"
+#include "if_rx62nreg.h"
+#include <string.h>
+#include "ether_phy.h"
+
+   /* Define those to better describe your network interface. */
+#define IFNAME0 'e'
+#define IFNAME1 'n'
+
+extern uint8_t mac_addr[ETHARP_HWADDR_LEN];
+
+typedef struct t_rx62n_buf
+{
+  uint8_t rx_buff[NUM_IF_RX62N_RXBUF][32 * ((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
+#endif
+T_RX62N_BUF rx62n_buf;
+#if defined(__RX)
+#pragma	section
+#endif
+
+/**
+ * Helper struct to hold private data used to operate your ethernet interface.
+ * Keeping the ethernet address of the MAC in this struct is not necessary
+ * as it is already kept in the struct netif.
+ * But this is only an example, anyway...
+ */
+struct ethernetif
+{
+  ID sem_rev;
+  struct eth_addr *ethaddr;
+  /* Add whatever per-interface state that is needed here. */
+  T_RX62N_TX_DESC *tx_write;
+  T_RX62N_RX_DESC *rx_read;
+  PHY_STATE_T state;
+  bool_t link_pre;
+  bool_t link_now;
+  bool_t over_flow;
+};
+
+/* Forward declarations. */
+void  ethernetif_input(struct netif *netif);
+
+static void rx62n_set_ecmr(struct netif *netif, PHY_MODE_T mode);
+
+/*
+ *  rx62n_bus_init -- ^[QbgË¶ÌoXÌú»
+ */
+
+void
+rx62n_bus_init (void)
+{
+  /* C[TlbgERg[Ì®ìðÂ */
+  sil_wrh_mem((uint16_t *)SYSTEM_PRCR_ADDR, (uint16_t)0xA502);  /* ÝÂ */
+  sil_wrw_mem((uint32_t *)SYSTEM_MSTPCRB_ADDR,
+    sil_rew_mem((uint32_t *)SYSTEM_MSTPCRB_ADDR) & ~SYSTEM_MSTPCRB_MSTPB15_BIT);
+  sil_wrh_mem((uint16_t *)SYSTEM_PRCR_ADDR, (uint16_t)0xA500);  /* ÝÖ~ */
+
+  /* EtherNETLø */
+  /* PA3`5 RMII_MDIO, RMII_MDC, RMII_LINKSTA */
+  sil_wrb_mem((uint8_t *)PORTA_PMR_ADDR,
+    sil_reb_mem((uint8_t *)PORTA_PMR_ADDR) | (1 << 3) | (1 << 4) | (1 << 5));
+  /* PB0`7 RXD1, RXD0, REF50CK, RX-ER, TXD-EN, TXD0, TXD1, CRS */
+  sil_wrb_mem((uint8_t *)PORTB_PMR_ADDR,
+    sil_reb_mem((uint8_t *)PORTB_PMR_ADDR) | 0xFF);
+
+  /* «ÝveNgWX^ÌÝè PFSWErbgÖÌ«ÝðÂ */
+  sil_wrb_mem((uint8_t *)(MPC_PWPR_ADDR) , 0x00);
+  /* «ÝveNgWX^ÌÝè PxxFSWX^ÖÌ«ÝðÂ */
+  sil_wrb_mem((uint8_t *)(MPC_PWPR_ADDR) , 0x40);
+
+  /* PA3ðET_MDIOÆ·é */
+  sil_wrb_mem((uint8_t *)MPC_PA3PFS_ADDR, 0x11); 
+  /* PA4ðET_MDCÆ·é */
+  sil_wrb_mem((uint8_t *)MPC_PA4PFS_ADDR, 0x11); 
+  /* PA5ðET_LINKSTAÆ·é */
+  sil_wrb_mem((uint8_t *)MPC_PA5PFS_ADDR, 0x11); 
+
+  /* PB0ðRXD1Æ·é */
+  sil_wrb_mem((uint8_t *)MPC_PB0PFS_ADDR, 0x12);
+  /* PB1ðRXD0Æ·é */
+  sil_wrb_mem((uint8_t *)MPC_PB1PFS_ADDR, 0x12);
+  /* PB2ðREF50CKÆ·é */
+  sil_wrb_mem((uint8_t *)MPC_PB2PFS_ADDR, 0x12);
+  /* PB3ðRX-ERÆ·é */
+  sil_wrb_mem((uint8_t *)MPC_PB3PFS_ADDR, 0x12);
+  /* PB4ðTXD-ENÆ·é */
+  sil_wrb_mem((uint8_t *)MPC_PB4PFS_ADDR, 0x12);
+  /* PB5ðTXD0Æ·é */
+  sil_wrb_mem((uint8_t *)MPC_PB5PFS_ADDR, 0x12);
+  /* PB6ðTXD1Æ·é */
+  sil_wrb_mem((uint8_t *)MPC_PB6PFS_ADDR, 0x12);
+  /* PB7ðCRSÆ·é */
+  sil_wrb_mem((uint8_t *)MPC_PB7PFS_ADDR, 0x12);
+
+  /* «ÝveNgWX^ÌÝè «ÝðÖ~ */
+  sil_wrb_mem((uint8_t *)(MPC_PWPR_ADDR) , 0x80);
+}
+
+/*
+ *  rx62n_init_sub -- lbg[NC^tF[XÌú»
+ *
+ *    Ó: NIC èÝÖ~óÔÅÄÑo·±ÆB
+ */
+
+static void
+rx62n_init_sub(struct netif *netif)
+{
+  struct ethernetif *ethernetif = netif->state;
+  PHY_STATE_T state = PHY_STATE_UNINIT;
+
+  /* MAC\tgEGAEZbg */
+  sil_wrw_mem(EDMAC_EDMR, sil_rew_mem(EDMAC_EDMR) | EDMAC_EDMR_SWR_BIT);
+
+  dly_tsk(1);
+
+  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]);
+
+  /* PHYZbg */
+  while ((state = phy_reset(state, 0)) != PHY_STATE_RESET);
+  ethernetif->state = state;
+
+  /* Clear all ETHERC status BFR, PSRTO, LCHNG, MPD, ICD */
+  sil_wrw_mem(ETHERC_ECSR, 0x00000037);
+
+  /* NÏ»èÝLø */
+  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);
+
+  /* óMèÝLø */
+  sil_wrw_mem(EDMAC_EESIPR, (EDMAC_EESIPR_TCIP | EDMAC_EESIPR_FRIP | EDMAC_EESIPR_RDEIP | EDMAC_EESIPR_FROFIP));
+
+  /* óMt[·ãÀiobt@TCYj */
+  sil_wrw_mem(ETHERC_RFLR, IF_RX62N_BUF_PAGE_SIZE);
+
+  /* 96rbgÔiúlj */
+  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);
+
+  /* PHYÌú»ð£· */
+  ethernetif->link_pre = false;
+  ethernetif->link_now = true;
+}
+
+/**
+ * In this function, the hardware should be initialized.
+ * Called from ethernetif_init().
+ *
+ * @param netif the already initialized lwip network interface structure
+ *        for this ethernetif
+ */
+static void
+low_level_init(struct netif *netif)
+{
+  struct ethernetif *ethernetif = netif->state;
+
+  rx62n_bus_init();
+
+  /* set MAC hardware address length */
+  netif->hwaddr_len = ETHARP_HWADDR_LEN;
+
+  /* set MAC hardware address */
+  memcpy(netif->hwaddr, mac_addr, sizeof(netif->hwaddr));
+
+  /* maximum transfer unit */
+  netif->mtu = 1500;
+
+  /* device capabilities */
+  /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
+  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
+
+  /* Do whatever else is needed to initialize interface. */
+  T_RX62N_TX_DESC *tdsc;
+  T_RX62N_RX_DESC *rdsc;
+  int i;
+  ER ret;
+
+  /* NIC ©çÌèÝðÖ~·éB*/
+  ret = dis_int(INTNO_IF_RX62N_TRX);
+  if (ret != E_OK)
+    syslog(LOG_DEBUG, "dis_int");
+
+  tdsc = (T_RX62N_TX_DESC *)rx62n_buf.tx_desc;
+  ethernetif->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;
+  ethernetif->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];
+    rdsc->rfl = 0;
+    rdsc->ract = 1;
+    rdsc++;
+  }
+  rdsc--;
+  rdsc->rdle = 1;
+
+  /* rx62n_init {ÌðÄÑo·B*/
+  rx62n_init_sub(netif);
+
+  if (sil_rew_mem(EDMAC_EDRRR) == 0) {
+    sil_wrw_mem(EDMAC_EDRRR, EDMAC_EDRRR_RR);
+  }
+
+  /* NIC ©çÌèÝðÂ·éB*/
+  ret = ena_int(INTNO_IF_RX62N_TRX);
+  if (ret != E_OK)
+    syslog(LOG_DEBUG, "dis_int");
+}
+
+/*
+*  rx62n_set_ecmr -- ECMRWX^ÌÝè
+*/
+
+static void
+rx62n_set_ecmr(struct netif *netif, 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;
+
+  /* ®ì[hÝè */
+  sil_wrw_mem(ETHERC_ECMR, ecmr);
+}
+
+/**
+ * This function should do the actual transmission of the packet. The packet is
+ * contained in the pbuf that is passed to the function. This pbuf
+ * might be chained.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
+ * @return ERR_OK if the packet could be sent
+ *         an err_t value if the packet couldn't be sent
+ *
+ * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
+ *       strange results. You might consider waiting for space in the DMA queue
+ *       to become availale since the stack doesn't retry to send a packet
+ *       dropped because of memory failure (except for the TCP timers).
+ */
+
+static err_t
+low_level_output(struct netif *netif, struct pbuf *p)
+{
+  struct ethernetif *ethernetif = netif->state;
+  struct pbuf *q;
+
+  T_RX62N_TX_DESC *desc, *next;
+  uint8_t *buf = NULL, *end;
+  int32_t len, res, pos;
+  uint32_t tfp;
+
+  for (res = p->tot_len, pos = 0; res > 0; res -= len, pos += len) {
+    desc = ethernetif->tx_write;
+
+    while (desc->tact != 0) {
+      tslp_tsk(1);
+    }
+
+    buf = (uint8_t *)desc->tba;
+
+    next = desc + 1;
+    if (next == &rx62n_buf.tx_desc[NUM_IF_RX62N_TXBUF]) {
+      next = rx62n_buf.tx_desc;
+    }
+    ethernetif->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;
+
+#if ETH_PAD_SIZE
+    pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
+#endif
+
+    end = &buf[len];
+    for (q = p; (q != NULL) && (buf < end); buf += q->len, q = q->next) {
+      /* Send the data from the pbuf to the interface, one pbuf at a
+      time. The size of the data in each pbuf is kept in the ->len
+      variable. */
+      memcpy(buf, (uint8_t *)q->payload, q->len);
+    }
+
+    desc->tbl = len;
+    desc->tfp = tfp;
+    desc->tact = 1;
+
+#if ETH_PAD_SIZE
+    pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
+#endif
+
+    LINK_STATS_INC(link.xmit);
+  }
+
+  if (sil_rew_mem(EDMAC_EDTRR) == 0) {
+    sil_wrw_mem(EDMAC_EDTRR, EDMAC_EDTRR_TR);
+  }
+
+  return ERR_OK;
+}
+
+/**
+ * Should allocate a pbuf and transfer the bytes of the incoming
+ * packet from the interface into the pbuf.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @return a pbuf filled with the received packet (including MAC header)
+ *         NULL on memory error
+ */
+static struct pbuf *
+low_level_input(struct netif *netif)
+{
+  struct ethernetif *ethernetif = netif->state;
+  struct pbuf *p, *q;
+  u16_t pos, len;
+  T_RX62N_RX_DESC *desc;
+
+  desc = ethernetif->rx_read;
+
+  if (desc->ract != 0) {
+    return NULL;
+  }
+
+  /* Obtain the size of the packet and put it into the "len"
+     variable. */
+  len = desc->rfl;
+  if (len == 0) {
+    return NULL;
+  }
+
+#if ETH_PAD_SIZE
+  len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
+#endif
+
+  /* We allocate a pbuf chain of pbufs from the pool. */
+  p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
+
+  if (p != NULL) {
+
+#if ETH_PAD_SIZE
+    pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
+#endif
+
+    /* We iterate over the pbuf chain until we have read the entire
+     * packet into the pbuf. */
+    for (q = p, pos = 0; q != NULL; pos += q->len, q = q->next) {
+      /* Read enough bytes to fill this pbuf in the chain. The
+       * available data in the pbuf is given by the q->len
+       * variable.
+       * This does not necessarily have to be a memcpy, you can also preallocate
+       * pbufs for a DMA-enabled MAC and after receiving truncate it to the
+       * actually received size. In this case, ensure the tot_len member of the
+       * pbuf is the sum of the chained pbuf len members.
+       */
+      memcpy(q->payload, (uint8_t *)desc->rba + pos, q->len);
+    }
+
+    desc->rfp = 0;
+    desc->ract = 1;
+
+    desc++;
+    if (desc == &rx62n_buf.rx_desc[NUM_IF_RX62N_RXBUF]) {
+      desc = rx62n_buf.rx_desc;
+    }
+    ethernetif->rx_read = desc;
+
+    if (sil_rew_mem(EDMAC_EDRRR) == 0) {
+      sil_wrw_mem(EDMAC_EDRRR, EDMAC_EDRRR_RR);
+    }
+
+#if ETH_PAD_SIZE
+    pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
+#endif
+
+    LINK_STATS_INC(link.recv);
+  }
+  else {
+    //drop packet();
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+  }
+
+  return p;
+}
+
+/* 
+ * rx62n_link -- NóÔÌÏ»ÉÎ·é
+ */
+bool_t
+rx62n_link(struct netif *netif)
+{
+	struct ethernetif *ethernetif;
+	PHY_MODE_T mode;
+
+	ethernetif = netif->state;
+
+	if(ethernetif->state == PHY_STATE_NEGOTIATED){
+		ethernetif->link_now = phy_is_link(0);
+		if(!ethernetif->link_now)
+			ethernetif->state = PHY_STATE_RESET;
+		return true;
+	}
+
+	/* PHYÌú» */
+	ethernetif->state = phy_initialize(ethernetif->state, 0, &mode);
+	if(ethernetif->state != PHY_STATE_NEGOTIATED){
+		return false;
+	}
+
+	/* ECMRWX^ÌÝè */
+	rx62n_set_ecmr(netif, mode);
+	return true;
+}
+
+/**
+ * This function should be called when a packet is ready to be read
+ * from the interface. It uses the function low_level_input() that
+ * should handle the actual reception of bytes from the network
+ * interface. Then the type of the received packet is determined and
+ * the appropriate input function is called.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ */
+void
+ethernetif_input(struct netif *netif)
+{
+  struct ethernetif *ethernetif;
+  struct eth_hdr *ethhdr;
+  struct pbuf *p;
+
+  ethernetif = netif->state;
+
+  if(ethernetif->link_pre != ethernetif->link_now){
+    if(rx62n_link(netif)){
+      bool_t cng = ethernetif->link_pre != ethernetif->link_now;
+      ethernetif->link_pre = ethernetif->link_now;
+      /* NóÔÉÏ» è */
+      if(cng){
+        if (ethernetif->link_pre) {
+          netif_set_link_up(netif);
+        }
+        else {
+          netif_set_link_down(netif);
+        }
+      }
+    }
+
+    if (ethernetif->state != PHY_STATE_NEGOTIATED)
+      sig_sem(ethernetif->sem_rev);
+
+    return;
+  }
+
+  /* move received packet into a new pbuf */
+  p = low_level_input(netif);
+  /* no packet could be read, silently ignore this */
+  if (p == NULL) return;
+  /* points to packet payload, which starts with an Ethernet header */
+  ethhdr = p->payload;
+
+  switch (htons(ethhdr->type)) {
+    /* IP or ARP packet? */
+  case ETHTYPE_IP:
+  case ETHTYPE_ARP:
+#if PPPOE_SUPPORT
+    /* PPPoE packet? */
+  case ETHTYPE_PPPOEDISC:
+  case ETHTYPE_PPPOE:
+#endif /* PPPOE_SUPPORT */
+    /* full packet send to tcpip_thread to process */
+    if (netif->input(p, netif) != ERR_OK) {
+      LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
+      pbuf_free(p);
+      p = NULL;
+    }
+    break;
+
+  default:
+    pbuf_free(p);
+    p = NULL;
+    break;
+  }
+}
+
+struct netif *if_rx62n;
+
+/**
+ * Should be called at the beginning of the program to set up the
+ * network interface. It calls the function low_level_init() to do the
+ * actual setup of the hardware.
+ *
+ * This function should be passed as a parameter to netif_add().
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @return ERR_OK if the loopif is initialized
+ *         ERR_MEM if private data couldn't be allocated
+ *         any other err_t on error
+ */
+err_t
+ethernetif_init(struct netif *netif)
+{
+  struct ethernetif *ethernetif;
+
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+
+  if_rx62n = netif;
+  ethernetif = (struct ethernetif *)(((intptr_t)netif) + sizeof(struct netif));
+  if (ethernetif == NULL) {
+    LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
+    return ERR_MEM;
+  }
+
+#if LWIP_NETIF_HOSTNAME
+  /* Initialize interface hostname */
+  netif->hostname = "lwip";
+#endif /* LWIP_NETIF_HOSTNAME */
+
+  /*
+   * Initialize the snmp variables and counters inside the struct netif.
+   * The last argument should be replaced with your link speed, in units
+   * of bits per second.
+   */
+  NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
+
+  netif->state = ethernetif;
+  netif->name[0] = IFNAME0;
+  netif->name[1] = IFNAME1;
+  /* We directly use etharp_output() here to save a function call.
+   * You can instead declare your own function an call etharp_output()
+   * from it if you have to do some checks before sending (e.g. if link
+   * is available...) */
+  netif->output = etharp_output;
+  netif->linkoutput = low_level_output;
+
+  ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
+
+  /* initialize the hardware */
+  low_level_init(netif);
+
+  return ERR_OK;
+}
+
+/*
+*  RX62N Ethernet Controler óMèÝnh
+*/
+
+void
+if_rx62n_trx_handler(void)
+{
+  struct netif *netif;
+  struct ethernetif *ethernetif;
+  uint32_t ecsr, eesr, psr;
+
+  i_begin_int(INTNO_IF_RX62N_TRX);
+
+  netif = if_rx62n;
+  ethernetif = netif->state;
+
+  ecsr = sil_rew_mem(ETHERC_ECSR);
+
+  if (ecsr & ETHERC_ECSR_LCHNG) {
+    /* ETHERCèÝvöNA */
+    sil_wrw_mem(ETHERC_ECSR, ETHERC_ECSR_LCHNG);
+
+    psr = sil_rew_mem(ETHERC_PSR);
+    ethernetif->link_now = (psr & ETHERC_PSR_LMON) != 0;
+
+    /* NóÔÉÏ» è */
+    if (ethernetif->link_pre != ethernetif->link_now) {
+      /* óMèÝ */
+      isig_sem(ethernetif->sem_rev);
+    }
+  }
+
+  eesr = sil_rew_mem(EDMAC_EESR);
+
+  if (eesr & EDMAC_EESR_FR) {
+    /* DMAèÝvöNA */
+    sil_wrw_mem(EDMAC_EESR, EDMAC_EESR_FR);
+
+    /* óMèÝ */
+    isig_sem(ethernetif->sem_rev);
+  }
+  if (eesr & EDMAC_EESR_TC) {
+    /* DMAèÝvöNA */
+    sil_wrw_mem(EDMAC_EESR, EDMAC_EESR_TC);
+
+    /* MèÝ */
+    isig_sem(ethernetif->sem_rev);
+  }
+  if (eesr & (EDMAC_EESR_FROF | EDMAC_EESR_RDE)) {
+    /* DMAèÝvöNA */
+    sil_wrw_mem(EDMAC_EESR, EDMAC_EESR_FROF | EDMAC_EESR_RDE);
+
+    ethernetif->over_flow = true;
+
+    /* óMèÝ */
+    isig_sem(ethernetif->sem_rev);
+  }
+
+  i_end_int(INTNO_IF_RX62N_TRX);
+}
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/if_rx62n.cfg
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/if_rx62n.cfg	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/if_rx62n.cfg	(revision 164)
@@ -0,0 +1,63 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  if_rx62n RtBM
+[Vt@C
+ */
+
+#ifdef SUPPORT_ETHER
+
+#include "if_rx62n.h"
+
+/* èÝnh */
+
+DEF_INH(INHNO_IF_RX62N_TRX, { TA_HLNG, if_rx62n_trx_handler });
+CFG_INT(INTNO_IF_RX62N_TRX, { INTATR_IF_RX62N_TRX, INTPRI_IF_RX62N_TRX });
+
+/* üoÍ¯úpZ}tH */
+
+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 });
+
+#endif	/* of #ifdef SUPPORT_ETHER */
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/if_rx62n.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/if_rx62n.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/if_rx62n.h	(revision 164)
@@ -0,0 +1,73 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $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_
+
+#include "target_config.h"
+
+#define INHNO_IF_RX62N_TRX	INT_ETH_EINT	/* pPbgóM */
+#define INTNO_IF_RX62N_TRX	INT_ETH_EINT	/* pPbgóM */
+#define INTATR_IF_RX62N_TRX	(TA_NULL)	/* Ý®«	*/
+#define INTPRI_IF_RX62N_TRX	(-1)		/* ÝDæx	*/
+
+#define NUM_IF_RX62N_RXBUF 2
+#define NUM_IF_RX62N_TXBUF 2
+#define IF_RX62N_BUF_PAGE_SIZE	1518	/* obt@TCY */
+
+/*
+ *  Ö
+ */
+
+extern void if_rx62n_trx_handler(void);
+
+#endif	/* of #ifndef _IF_RX62N_H_ */
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/if_rx62nreg.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/if_rx62nreg.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/if_rx62nreg.h	(revision 164)
@@ -0,0 +1,162 @@
+/*
+ *  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
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef RX62NRegH
+#define RX62NRegH
+
+#include "t_stddef.h"
+
+#define EDMAC_EDMR			((uint32_t *)0x000C0000)	/* EDMAC[hWX^ */
+#define EDMAC_EDMR_SWR_BIT	0x00000001
+#define EDMAC_EDMR_DE_BIT	0x00000040
+
+#define EDMAC_EDTRR			((uint32_t *)0x000C0008)	/* EDMACMvWX^ */
+#define EDMAC_EDTRR_TR		0x00000001
+
+#define EDMAC_EDRRR			((uint32_t *)0x000C0010)	/* EDMACóMvWX^ */
+#define EDMAC_EDRRR_RR		0x00000001
+
+#define EDMAC_TDLAR			((uint32_t *)0x000C0018)	/* MfBXNv^XgæªAhXWX^ */
+#define EDMAC_RDLAR			((uint32_t *)0x000C0020)	/* óMfBXNv^XgæªAhXWX^ */
+
+#define EDMAC_EESR			((uint32_t *)0x000C0028)	/* ETHERC/EDMACXe[^XWX^ */
+#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/EDMACXe[^XèÝÂWX^ */
+#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)	/* óMXe[^XRs[w¦WX^ */
+#define EDMAC_RMFCR			((uint32_t *)0x000C0040)	/* ~Xht[JE^WX^ */
+#define EDMAC_TFTR			((uint32_t *)0x000C0048)	/* MFIFOµ«¢lwèWX^ */
+#define EDMAC_FDR			((uint32_t *)0x000C0050)	/* FIFOeÊwèWX^ */
+#define EDMAC_RMCR			((uint32_t *)0x000C0058)	/* óMû®§äWX^ */
+#define EDMAC_TFUCR			((uint32_t *)0x000C0064)	/* MFIFOA_JEg */
+#define EDMAC_RFOCR			((uint32_t *)0x000C0068)	/* óMFIFOI[ot[JEg */
+#define EDMAC_IOSR			((uint32_t *)0x000C006C)	/* ÂÊoÍMÝèWX^ */
+#define EDMAC_FCFTR			((uint32_t *)0x000C0070)	/* t[§äJnFIFOµ«¢lÝèWX^ */
+#define EDMAC_RPADIR		((uint32_t *)0x000C0078)	/* óMf[^pfBO}üÝèWX^ */
+#define EDMAC_TRIMD			((uint32_t *)0x000C007C)	/* MèÝÝèWX^ */
+#define EDMAC_RBWAR			((uint32_t *)0x000C00C8)	/* óMobt@CgAhXWX^ */
+#define EDMAC_RDFAR			((uint32_t *)0x000C00CC)	/* óMfBXNv^tFb`AhXWX^ */
+#define EDMAC_TBRAR			((uint32_t *)0x000C00D4)	/* Mobt@[hAhXWX^ */
+#define EDMAC_TDFAR			((uint32_t *)0x000C00D8)	/* MfBXNv^tFb`AhXWX^ */
+
+#define ETHERC_ECMR			((uint32_t *)0x000C0100)	/* ETHERC[hWX^ */
+#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)	/* óMt[·ãÀWX^ */
+#define ETHERC_ECSR			((uint32_t *)0x000C0110)	/* ETHERCXe[^XWX^ */
+#define ETHERC_ECSR_LCHNG	0x00000004
+#define ETHERC_ECSIPR		((uint32_t *)0x000C0118)	/* ETHERCèÝÂWX^ */
+#define ETHERC_ECSIPR_LCHNGIP	0x00000004
+#define ETHERC_PIR			((uint32_t *)0x000C0120)	/* PHYC^tF[XWX^ */
+#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)	/* PHYXe[^XWX^ */
+#define ETHERC_PSR_LMON		0x00000001
+
+#define ETHERC_RDMLR		((uint32_t *)0x000C0140)	/* ¶¬JE^ãÀlÝèWX^ */
+#define ETHERC_IPGR			((uint32_t *)0x000C0150)	/* IPGÝèWX^ */
+#define ETHERC_APR			((uint32_t *)0x000C0154)	/* ©®PAUSEt[ÝèWX^ */
+#define ETHERC_MPR			((uint32_t *)0x000C0158)	/* è®PAUSEt[ÝèWX^ */
+#define ETHERC_RFCF			((uint32_t *)0x000C0160)	/* óMPAUSEt[JE^ */
+#define ETHERC_TPAUSER		((uint32_t *)0x000C0164)	/* ©®PAUSEt[ÄñÝèWX^ */
+#define ETHERC_TPAUSECR		((uint32_t *)0x000C0168)	/* PAUSEt[ÄñJE^ */
+#define ETHERC_BCFRR		((uint32_t *)0x000C016C)	/* Broadcastt[óMñÝèWX^ */
+#define ETHERC_MAHR			((uint32_t *)0x000C01C0)	/* MACAhXãÊÝèWX^ */
+#define ETHERC_MALR			((uint32_t *)0x000C01C8)	/* MACAhXºÊÝèWX^ */
+#define ETHERC_TROCR		((uint32_t *)0x000C01D0)	/* MgCI[oJE^WX^ */
+#define ETHERC_CDCR			((uint32_t *)0x000C01D4)	/* xÕËoJE^WX^ */
+#define ETHERC_LCCR			((uint32_t *)0x000C01D8)	/* LAÁ¸JE^WX^ */
+#define ETHERC_CNDCR		((uint32_t *)0x000C01DC)	/* LA¢oJE^WX^ */
+#define ETHERC_CEFCR		((uint32_t *)0x000C01E4)	/* CRCG[t[óMJE^WX^ */
+#define ETHERC_FRECR		((uint32_t *)0x000C01E8)	/* t[óMG[JE^WX^ */
+#define ETHERC_TSFRCR		((uint32_t *)0x000C01EC)	/* 64oCg¢t[óMJE^WX^ */
+#define ETHERC_TLFRCR		((uint32_t *)0x000C01F0)	/* wèoCg´t[óMJE^WX^ */
+#define ETHERC_RFCR			((uint32_t *)0x000C01F4)	/* [rbgt[óMJE^WX^ */
+#define ETHERC_MAFCR		((uint32_t *)0x000C01F8)	/* }`LXgAhXt[óMJE^WX^ */
+
+/* MfBXNv^ */
+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;
+
+/* óMfBXNv^ */
+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: UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/lwipopts.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/lwipopts.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/lwipopts.h	(revision 164)
@@ -0,0 +1,31 @@
+#define MEM_LIBC_MALLOC				1
+#define MEMP_MEM_MALLOC				1
+#define mem_free sys_free
+#define mem_malloc sys_malloc
+#define mem_calloc sys_calloc
+#define mem_trim sys_trim
+
+#define MEM_ALIGNMENT				4
+
+#define TCPIP_THREAD_STACKSIZE		(1024)
+#define DEFAULT_THREAD_STACKSIZE	(1024)
+
+#define TCPIP_MBOX_SIZE				16
+#define DEFAULT_ACCEPTMBOX_SIZE		16
+#define DEFAULT_RAW_RECVMBOX_SIZE	16
+#define DEFAULT_UDP_RECVMBOX_SIZE	16
+#define DEFAULT_TCP_RECVMBOX_SIZE	16
+
+#define DEFAULT_THREAD_PRIO			2
+
+#define LWIP_SOCKET 1
+#define LWIP_NETIF_STATUS_CALLBACK      1
+#define LWIP_NETIF_LINK_CALLBACK        1
+#define LWIP_DHCP   1
+#define LWIP_IGMP   1
+#define LWIP_DNS    1
+#define ERRNO errno
+#define sys_msleep  sys_sleep
+#define SNTP_SET_SYSTEM_TIME sys_set_system_time
+
+#include "arch/sys_arch.h"
Index: UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/wolfssl_asp_dcre.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/wolfssl_asp_dcre.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/wolfssl_asp_dcre.c	(revision 164)
@@ -0,0 +1,219 @@
+#include "stddef.h"
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/wc_port.h>
+#include <wolfssl/wolfcrypt/random.h>
+#include "lwip/sockets.h"
+#include "kernel.h"
+#include "itron.h"
+#ifdef __RX
+#include "sys/time.h"
+#endif
+#include "time.h"
+
+#ifdef __RX
+_Ctype_t _Touptab;
+
+char *getenv(const char *name)
+{
+	syslog(LOG_NOTICE, name);
+	return "";
+}
+#else
+struct tm *gmtime_r(const time_t *pt, struct tm* tm);
+#endif
+
+/* NTPT[o[ÌO[oÔ */
+static time_t sys_time_offset = 1453334400LL;
+
+time_t sys_time(time_t *t)
+{
+	if (t == NULL) {
+		time_t temp;
+		return time(&temp);
+	}
+
+	SYSTIM tim;
+	get_tim(&tim);
+	*t = (time_t)(tim / 1000) + sys_time_offset;
+	return *t;
+}
+
+void sys_set_system_time(time_t t)
+{
+	SYSTIM tim;
+	get_tim(&tim);
+	sys_time_offset = t - (time_t)(tim / 1000);
+
+	struct tm tm;
+	gmtime_r(&t, &tm);
+	syslog(LOG_NOTICE, "%d/%d/%d %d:%d:%d", 1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
+		tm.tm_hour, tm.tm_min, tm.tm_sec);
+}
+
+/* musl-1.1.12/src/time/__secs_to_tm.c */
+/* musl as a whole is licensed under the following standard MIT license:
+ * 
+ * ----------------------------------------------------------------------
+ * Copyright (C) 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.
+ * ----------------------------------------------------------------------*/
+
+/* 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)
+
+struct tm *gmtime_r(const time_t *pt, struct tm* tm)
+{
+	time_t t = *pt;
+	time_t 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 NULL;
+
+	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 (years + 100 > INT_MAX || years + 100 < INT_MIN)
+		return NULL;
+
+	tm->tm_year = years + 100;
+	tm->tm_mon = months + 2;
+	if (tm->tm_mon >= 12) {
+		tm->tm_mon -= 12;
+		tm->tm_year++;
+	}
+	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 tm;
+}
+
+struct tm *sys_gmtime(const time_t *pt)
+{
+	static struct tm tm;
+	return gmtime_r(pt, &tm);
+}
+
+DWORD get_fattime(void)
+{
+	time_t temp;
+	struct tm _tm;
+
+	time(&temp);
+	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);
+}
+
+FIL *sys_stderr = (FIL *)1;
+FIL *sys_stdout = (FIL *)2;
+FIL *sys_stdin = (FIL *)3;
+
+long sys_fprintf(FIL *fp, const char *str, ...)
+{
+	long res = 0;
+	va_list ap;
+
+	if (fp == sys_stdin)
+		return res;
+
+	va_start(ap, str);
+
+	if (fp == sys_stderr) {
+		vsyslog(LOG_ERROR, str, ap);
+	}
+	else if (fp == sys_stdout) {
+		vsyslog(LOG_NOTICE, str, ap);
+	}
+	else {
+		res = f_vprintf(fp, str, ap);
+	}
+
+	va_end(ap);
+
+	return res;
+}
+
+int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+{
+	word32 i;
+	for (i = 0; i < sz; i++)
+		output[i] = rand();
+
+	(void)os;
+
+	return 0;
+}
Index: UsbWattMeter/trunk/lwip-1.4.1/src/FILES
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/FILES	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/FILES	(revision 164)
@@ -0,0 +1,13 @@
+api/      - The code for the high-level wrapper API. Not needed if
+            you use the lowel-level call-back/raw API.
+
+core/     - The core of the TPC/IP stack; protocol implementations,
+            memory and buffer management, and the low-level raw API.
+
+include/  - lwIP include files.
+
+netif/    - Generic network interface device drivers are kept here,
+            as well as the ARP module.
+
+For more information on the various subdirectories, check the FILES
+file in each directory.
Index: UsbWattMeter/trunk/lwip-1.4.1/src/api/api_lib.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/api/api_lib.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/api/api_lib.c	(revision 164)
@@ -0,0 +1,780 @@
+/**
+ * @file
+ * Sequential API External module
+ *
+ */
+ 
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/* This is the part of the API that is linked with
+   the application */
+
+#include "lwip/opt.h"
+
+#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/api.h"
+#include "lwip/tcpip.h"
+#include "lwip/memp.h"
+
+#include "lwip/ip.h"
+#include "lwip/raw.h"
+#include "lwip/udp.h"
+#include "lwip/tcp.h"
+
+#include <string.h>
+
+/**
+ * Create a new netconn (of a specific type) that has a callback function.
+ * The corresponding pcb is also created.
+ *
+ * @param t the type of 'connection' to create (@see enum netconn_type)
+ * @param proto the IP protocol for RAW IP pcbs
+ * @param callback a function to call on status changes (RX available, TX'ed)
+ * @return a newly allocated struct netconn or
+ *         NULL on memory error
+ */
+struct netconn*
+netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback)
+{
+  struct netconn *conn;
+  struct api_msg msg;
+
+  conn = netconn_alloc(t, callback);
+  if (conn != NULL) {
+    msg.function = do_newconn;
+    msg.msg.msg.n.proto = proto;
+    msg.msg.conn = conn;
+    if (TCPIP_APIMSG(&msg) != ERR_OK) {
+      LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL);
+      LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed));
+      LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox));
+#if LWIP_TCP
+      LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox));
+#endif /* LWIP_TCP */
+      sys_sem_free(&conn->op_completed);
+      sys_mbox_free(&conn->recvmbox);
+      memp_free(MEMP_NETCONN, conn);
+      return NULL;
+    }
+  }
+  return conn;
+}
+
+/**
+ * Close a netconn 'connection' and free its resources.
+ * UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate
+ * after this returns.
+ *
+ * @param conn the netconn to delete
+ * @return ERR_OK if the connection was deleted
+ */
+err_t
+netconn_delete(struct netconn *conn)
+{
+  struct api_msg msg;
+
+  /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */
+  if (conn == NULL) {
+    return ERR_OK;
+  }
+
+  msg.function = do_delconn;
+  msg.msg.conn = conn;
+  tcpip_apimsg(&msg);
+
+  netconn_free(conn);
+
+  /* don't care for return value of do_delconn since it only calls void functions */
+
+  return ERR_OK;
+}
+
+/**
+ * Get the local or remote IP address and port of a netconn.
+ * For RAW netconns, this returns the protocol instead of a port!
+ *
+ * @param conn the netconn to query
+ * @param addr a pointer to which to save the IP address
+ * @param port a pointer to which to save the port (or protocol for RAW)
+ * @param local 1 to get the local IP address, 0 to get the remote one
+ * @return ERR_CONN for invalid connections
+ *         ERR_OK if the information was retrieved
+ */
+err_t
+netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local)
+{
+  struct api_msg msg;
+  err_t err;
+
+  LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;);
+  LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;);
+  LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;);
+
+  msg.function = do_getaddr;
+  msg.msg.conn = conn;
+  msg.msg.msg.ad.ipaddr = addr;
+  msg.msg.msg.ad.port = port;
+  msg.msg.msg.ad.local = local;
+  err = TCPIP_APIMSG(&msg);
+
+  NETCONN_SET_SAFE_ERR(conn, err);
+  return err;
+}
+
+/**
+ * Bind a netconn to a specific local IP address and port.
+ * Binding one netconn twice might not always be checked correctly!
+ *
+ * @param conn the netconn to bind
+ * @param addr the local IP address to bind the netconn to (use IP_ADDR_ANY
+ *             to bind to all addresses)
+ * @param port the local port to bind the netconn to (not used for RAW)
+ * @return ERR_OK if bound, any other err_t on failure
+ */
+err_t
+netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port)
+{
+  struct api_msg msg;
+  err_t err;
+
+  LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;);
+
+  msg.function = do_bind;
+  msg.msg.conn = conn;
+  msg.msg.msg.bc.ipaddr = addr;
+  msg.msg.msg.bc.port = port;
+  err = TCPIP_APIMSG(&msg);
+
+  NETCONN_SET_SAFE_ERR(conn, err);
+  return err;
+}
+
+/**
+ * Connect a netconn to a specific remote IP address and port.
+ *
+ * @param conn the netconn to connect
+ * @param addr the remote IP address to connect to
+ * @param port the remote port to connect to (no used for RAW)
+ * @return ERR_OK if connected, return value of tcp_/udp_/raw_connect otherwise
+ */
+err_t
+netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port)
+{
+  struct api_msg msg;
+  err_t err;
+
+  LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;);
+
+  msg.function = do_connect;
+  msg.msg.conn = conn;
+  msg.msg.msg.bc.ipaddr = addr;
+  msg.msg.msg.bc.port = port;
+  /* This is the only function which need to not block tcpip_thread */
+  err = tcpip_apimsg(&msg);
+
+  NETCONN_SET_SAFE_ERR(conn, err);
+  return err;
+}
+
+/**
+ * Disconnect a netconn from its current peer (only valid for UDP netconns).
+ *
+ * @param conn the netconn to disconnect
+ * @return TODO: return value is not set here...
+ */
+err_t
+netconn_disconnect(struct netconn *conn)
+{
+  struct api_msg msg;
+  err_t err;
+
+  LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;);
+
+  msg.function = do_disconnect;
+  msg.msg.conn = conn;
+  err = TCPIP_APIMSG(&msg);
+
+  NETCONN_SET_SAFE_ERR(conn, err);
+  return err;
+}
+
+/**
+ * Set a TCP netconn into listen mode
+ *
+ * @param conn the tcp netconn to set to listen mode
+ * @param backlog the listen backlog, only used if TCP_LISTEN_BACKLOG==1
+ * @return ERR_OK if the netconn was set to listen (UDP and RAW netconns
+ *         don't return any error (yet?))
+ */
+err_t
+netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
+{
+#if LWIP_TCP
+  struct api_msg msg;
+  err_t err;
+
+  /* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */
+  LWIP_UNUSED_ARG(backlog);
+
+  LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;);
+
+  msg.function = do_listen;
+  msg.msg.conn = conn;
+#if TCP_LISTEN_BACKLOG
+  msg.msg.msg.lb.backlog = backlog;
+#endif /* TCP_LISTEN_BACKLOG */
+  err = TCPIP_APIMSG(&msg);
+
+  NETCONN_SET_SAFE_ERR(conn, err);
+  return err;
+#else /* LWIP_TCP */
+  LWIP_UNUSED_ARG(conn);
+  LWIP_UNUSED_ARG(backlog);
+  return ERR_ARG;
+#endif /* LWIP_TCP */
+}
+
+/**
+ * Accept a new connection on a TCP listening netconn.
+ *
+ * @param conn the TCP listen netconn
+ * @param new_conn pointer where the new connection is stored
+ * @return ERR_OK if a new connection has been received or an error
+ *                code otherwise
+ */
+err_t
+netconn_accept(struct netconn *conn, struct netconn **new_conn)
+{
+#if LWIP_TCP
+  struct netconn *newconn;
+  err_t err;
+#if TCP_LISTEN_BACKLOG
+  struct api_msg msg;
+#endif /* TCP_LISTEN_BACKLOG */
+
+  LWIP_ERROR("netconn_accept: invalid pointer",    (new_conn != NULL),                  return ERR_ARG;);
+  *new_conn = NULL;
+  LWIP_ERROR("netconn_accept: invalid conn",       (conn != NULL),                      return ERR_ARG;);
+  LWIP_ERROR("netconn_accept: invalid acceptmbox", sys_mbox_valid(&conn->acceptmbox),   return ERR_ARG;);
+
+  err = conn->last_err;
+  if (ERR_IS_FATAL(err)) {
+    /* don't recv on fatal errors: this might block the application task
+       waiting on acceptmbox forever! */
+    return err;
+  }
+
+#if LWIP_SO_RCVTIMEO
+  if (sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
+    NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
+    return ERR_TIMEOUT;
+  }
+#else
+  sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, 0);
+#endif /* LWIP_SO_RCVTIMEO*/
+  /* Register event with callback */
+  API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
+
+  if (newconn == NULL) {
+    /* connection has been aborted */
+    NETCONN_SET_SAFE_ERR(conn, ERR_ABRT);
+    return ERR_ABRT;
+  }
+#if TCP_LISTEN_BACKLOG
+  /* Let the stack know that we have accepted the connection. */
+  msg.function = do_recv;
+  msg.msg.conn = conn;
+  /* don't care for the return value of do_recv */
+  TCPIP_APIMSG(&msg);
+#endif /* TCP_LISTEN_BACKLOG */
+
+  *new_conn = newconn;
+  /* don't set conn->last_err: it's only ERR_OK, anyway */
+  return ERR_OK;
+#else /* LWIP_TCP */
+  LWIP_UNUSED_ARG(conn);
+  LWIP_UNUSED_ARG(new_conn);
+  return ERR_ARG;
+#endif /* LWIP_TCP */
+}
+
+/**
+ * Receive data: actual implementation that doesn't care whether pbuf or netbuf
+ * is received
+ *
+ * @param conn the netconn from which to receive data
+ * @param new_buf pointer where a new pbuf/netbuf is stored when received data
+ * @return ERR_OK if data has been received, an error code otherwise (timeout,
+ *                memory error or another error)
+ */
+static err_t
+netconn_recv_data(struct netconn *conn, void **new_buf)
+{
+  void *buf = NULL;
+  u16_t len;
+  err_t err;
+#if LWIP_TCP
+  struct api_msg msg;
+#endif /* LWIP_TCP */
+
+  LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
+  *new_buf = NULL;
+  LWIP_ERROR("netconn_recv: invalid conn",    (conn != NULL),    return ERR_ARG;);
+  LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;);
+
+  err = conn->last_err;
+  if (ERR_IS_FATAL(err)) {
+    /* don't recv on fatal errors: this might block the application task
+       waiting on recvmbox forever! */
+    /* @todo: this does not allow us to fetch data that has been put into recvmbox
+       before the fatal error occurred - is that a problem? */
+    return err;
+  }
+
+#if LWIP_SO_RCVTIMEO
+  if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
+    NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
+    return ERR_TIMEOUT;
+  }
+#else
+  sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0);
+#endif /* LWIP_SO_RCVTIMEO*/
+
+#if LWIP_TCP
+#if (LWIP_UDP || LWIP_RAW)
+  if (conn->type == NETCONN_TCP)
+#endif /* (LWIP_UDP || LWIP_RAW) */
+  {
+    if (!netconn_get_noautorecved(conn) || (buf == NULL)) {
+      /* Let the stack know that we have taken the data. */
+      /* TODO: Speedup: Don't block and wait for the answer here
+         (to prevent multiple thread-switches). */
+      msg.function = do_recv;
+      msg.msg.conn = conn;
+      if (buf != NULL) {
+        msg.msg.msg.r.len = ((struct pbuf *)buf)->tot_len;
+      } else {
+        msg.msg.msg.r.len = 1;
+      }
+      /* don't care for the return value of do_recv */
+      TCPIP_APIMSG(&msg);
+    }
+
+    /* If we are closed, we indicate that we no longer wish to use the socket */
+    if (buf == NULL) {
+      API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
+      /* Avoid to lose any previous error code */
+      NETCONN_SET_SAFE_ERR(conn, ERR_CLSD);
+      return ERR_CLSD;
+    }
+    len = ((struct pbuf *)buf)->tot_len;
+  }
+#endif /* LWIP_TCP */
+#if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
+  else
+#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
+#if (LWIP_UDP || LWIP_RAW)
+  {
+    LWIP_ASSERT("buf != NULL", buf != NULL);
+    len = netbuf_len((struct netbuf *)buf);
+  }
+#endif /* (LWIP_UDP || LWIP_RAW) */
+
+#if LWIP_SO_RCVBUF
+  SYS_ARCH_DEC(conn->recv_avail, len);
+#endif /* LWIP_SO_RCVBUF */
+  /* Register event with callback */
+  API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);
+
+  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len));
+
+  *new_buf = buf;
+  /* don't set conn->last_err: it's only ERR_OK, anyway */
+  return ERR_OK;
+}
+
+/**
+ * Receive data (in form of a pbuf) from a TCP netconn
+ *
+ * @param conn the netconn from which to receive data
+ * @param new_buf pointer where a new pbuf is stored when received data
+ * @return ERR_OK if data has been received, an error code otherwise (timeout,
+ *                memory error or another error)
+ *         ERR_ARG if conn is not a TCP netconn
+ */
+err_t
+netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf)
+{
+  LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL) &&
+             netconn_type(conn) == NETCONN_TCP, return ERR_ARG;);
+
+  return netconn_recv_data(conn, (void **)new_buf);
+}
+
+/**
+ * Receive data (in form of a netbuf containing a packet buffer) from a netconn
+ *
+ * @param conn the netconn from which to receive data
+ * @param new_buf pointer where a new netbuf is stored when received data
+ * @return ERR_OK if data has been received, an error code otherwise (timeout,
+ *                memory error or another error)
+ */
+err_t
+netconn_recv(struct netconn *conn, struct netbuf **new_buf)
+{
+#if LWIP_TCP
+  struct netbuf *buf = NULL;
+  err_t err;
+#endif /* LWIP_TCP */
+
+  LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
+  *new_buf = NULL;
+  LWIP_ERROR("netconn_recv: invalid conn",    (conn != NULL),    return ERR_ARG;);
+  LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;);
+
+#if LWIP_TCP
+#if (LWIP_UDP || LWIP_RAW)
+  if (conn->type == NETCONN_TCP)
+#endif /* (LWIP_UDP || LWIP_RAW) */
+  {
+    struct pbuf *p = NULL;
+    /* This is not a listening netconn, since recvmbox is set */
+
+    buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
+    if (buf == NULL) {
+      NETCONN_SET_SAFE_ERR(conn, ERR_MEM);
+      return ERR_MEM;
+    }
+
+    err = netconn_recv_data(conn, (void **)&p);
+    if (err != ERR_OK) {
+      memp_free(MEMP_NETBUF, buf);
+      return err;
+    }
+    LWIP_ASSERT("p != NULL", p != NULL);
+
+    buf->p = p;
+    buf->ptr = p;
+    buf->port = 0;
+    ip_addr_set_any(&buf->addr);
+    *new_buf = buf;
+    /* don't set conn->last_err: it's only ERR_OK, anyway */
+    return ERR_OK;
+  }
+#endif /* LWIP_TCP */
+#if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
+  else
+#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
+  {
+#if (LWIP_UDP || LWIP_RAW)
+    return netconn_recv_data(conn, (void **)new_buf);
+#endif /* (LWIP_UDP || LWIP_RAW) */
+  }
+}
+
+/**
+ * TCP: update the receive window: by calling this, the application
+ * tells the stack that it has processed data and is able to accept
+ * new data.
+ * ATTENTION: use with care, this is mainly used for sockets!
+ * Can only be used when calling netconn_set_noautorecved(conn, 1) before.
+ *
+ * @param conn the netconn for which to update the receive window
+ * @param length amount of data processed (ATTENTION: this must be accurate!)
+ */
+void
+netconn_recved(struct netconn *conn, u32_t length)
+{
+#if LWIP_TCP
+  if ((conn != NULL) && (conn->type == NETCONN_TCP) &&
+      (netconn_get_noautorecved(conn))) {
+    struct api_msg msg;
+    /* Let the stack know that we have taken the data. */
+    /* TODO: Speedup: Don't block and wait for the answer here
+       (to prevent multiple thread-switches). */
+    msg.function = do_recv;
+    msg.msg.conn = conn;
+    msg.msg.msg.r.len = length;
+    /* don't care for the return value of do_recv */
+    TCPIP_APIMSG(&msg);
+  }
+#else /* LWIP_TCP */
+  LWIP_UNUSED_ARG(conn);
+  LWIP_UNUSED_ARG(length);
+#endif /* LWIP_TCP */
+}
+
+/**
+ * Send data (in form of a netbuf) to a specific remote IP address and port.
+ * Only to be used for UDP and RAW netconns (not TCP).
+ *
+ * @param conn the netconn over which to send data
+ * @param buf a netbuf containing the data to send
+ * @param addr the remote IP address to which to send the data
+ * @param port the remote port to which to send the data
+ * @return ERR_OK if data was sent, any other err_t on error
+ */
+err_t
+netconn_sendto(struct netconn *conn, struct netbuf *buf, ip_addr_t *addr, u16_t port)
+{
+  if (buf != NULL) {
+    ip_addr_set(&buf->addr, addr);
+    buf->port = port;
+    return netconn_send(conn, buf);
+  }
+  return ERR_VAL;
+}
+
+/**
+ * Send data over a UDP or RAW netconn (that is already connected).
+ *
+ * @param conn the UDP or RAW netconn over which to send data
+ * @param buf a netbuf containing the data to send
+ * @return ERR_OK if data was sent, any other err_t on error
+ */
+err_t
+netconn_send(struct netconn *conn, struct netbuf *buf)
+{
+  struct api_msg msg;
+  err_t err;
+
+  LWIP_ERROR("netconn_send: invalid conn",  (conn != NULL), return ERR_ARG;);
+
+  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len));
+  msg.function = do_send;
+  msg.msg.conn = conn;
+  msg.msg.msg.b = buf;
+  err = TCPIP_APIMSG(&msg);
+
+  NETCONN_SET_SAFE_ERR(conn, err);
+  return err;
+}
+
+/**
+ * Send data over a TCP netconn.
+ *
+ * @param conn the TCP netconn over which to send data
+ * @param dataptr pointer to the application buffer that contains the data to send
+ * @param size size of the application data to send
+ * @param apiflags combination of following flags :
+ * - NETCONN_COPY: data will be copied into memory belonging to the stack
+ * - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent
+ * - NETCONN_DONTBLOCK: only write the data if all dat can be written at once
+ * @param bytes_written pointer to a location that receives the number of written bytes
+ * @return ERR_OK if data was sent, any other err_t on error
+ */
+err_t
+netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
+                     u8_t apiflags, size_t *bytes_written)
+{
+  struct api_msg msg;
+  err_t err;
+  u8_t dontblock;
+
+  LWIP_ERROR("netconn_write: invalid conn",  (conn != NULL), return ERR_ARG;);
+  LWIP_ERROR("netconn_write: invalid conn->type",  (conn->type == NETCONN_TCP), return ERR_VAL;);
+  if (size == 0) {
+    return ERR_OK;
+  }
+  dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK);
+  if (dontblock && !bytes_written) {
+    /* This implies netconn_write() cannot be used for non-blocking send, since
+       it has no way to return the number of bytes written. */
+    return ERR_VAL;
+  }
+
+  /* non-blocking write sends as much  */
+  msg.function = do_write;
+  msg.msg.conn = conn;
+  msg.msg.msg.w.dataptr = dataptr;
+  msg.msg.msg.w.apiflags = apiflags;
+  msg.msg.msg.w.len = size;
+#if LWIP_SO_SNDTIMEO
+  if (conn->send_timeout != 0) {
+    /* get the time we started, which is later compared to
+        sys_now() + conn->send_timeout */
+    msg.msg.msg.w.time_started = sys_now();
+  } else {
+    msg.msg.msg.w.time_started = 0;
+  }
+#endif /* LWIP_SO_SNDTIMEO */
+
+  /* For locking the core: this _can_ be delayed on low memory/low send buffer,
+     but if it is, this is done inside api_msg.c:do_write(), so we can use the
+     non-blocking version here. */
+  err = TCPIP_APIMSG(&msg);
+  if ((err == ERR_OK) && (bytes_written != NULL)) {
+    if (dontblock
+#if LWIP_SO_SNDTIMEO
+        || (conn->send_timeout != 0)
+#endif /* LWIP_SO_SNDTIMEO */
+       ) {
+      /* nonblocking write: maybe the data has been sent partly */
+      *bytes_written = msg.msg.msg.w.len;
+    } else {
+      /* blocking call succeeded: all data has been sent if it */
+      *bytes_written = size;
+    }
+  }
+
+  NETCONN_SET_SAFE_ERR(conn, err);
+  return err;
+}
+
+/**
+ * Close ot shutdown a TCP netconn (doesn't delete it).
+ *
+ * @param conn the TCP netconn to close or shutdown
+ * @param how fully close or only shutdown one side?
+ * @return ERR_OK if the netconn was closed, any other err_t on error
+ */
+static err_t
+netconn_close_shutdown(struct netconn *conn, u8_t how)
+{
+  struct api_msg msg;
+  err_t err;
+
+  LWIP_ERROR("netconn_close: invalid conn",  (conn != NULL), return ERR_ARG;);
+
+  msg.function = do_close;
+  msg.msg.conn = conn;
+  /* shutting down both ends is the same as closing */
+  msg.msg.msg.sd.shut = how;
+  /* because of the LWIP_TCPIP_CORE_LOCKING implementation of do_close,
+     don't use TCPIP_APIMSG here */
+  err = tcpip_apimsg(&msg);
+
+  NETCONN_SET_SAFE_ERR(conn, err);
+  return err;
+}
+
+/**
+ * Close a TCP netconn (doesn't delete it).
+ *
+ * @param conn the TCP netconn to close
+ * @return ERR_OK if the netconn was closed, any other err_t on error
+ */
+err_t
+netconn_close(struct netconn *conn)
+{
+  /* shutting down both ends is the same as closing */
+  return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR);
+}
+
+/**
+ * Shut down one or both sides of a TCP netconn (doesn't delete it).
+ *
+ * @param conn the TCP netconn to shut down
+ * @return ERR_OK if the netconn was closed, any other err_t on error
+ */
+err_t
+netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx)
+{
+  return netconn_close_shutdown(conn, (shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0));
+}
+
+#if LWIP_IGMP
+/**
+ * Join multicast groups for UDP netconns.
+ *
+ * @param conn the UDP netconn for which to change multicast addresses
+ * @param multiaddr IP address of the multicast group to join or leave
+ * @param netif_addr the IP address of the network interface on which to send
+ *                  the igmp message
+ * @param join_or_leave flag whether to send a join- or leave-message
+ * @return ERR_OK if the action was taken, any err_t on error
+ */
+err_t
+netconn_join_leave_group(struct netconn *conn,
+                         ip_addr_t *multiaddr,
+                         ip_addr_t *netif_addr,
+                         enum netconn_igmp join_or_leave)
+{
+  struct api_msg msg;
+  err_t err;
+
+  LWIP_ERROR("netconn_join_leave_group: invalid conn",  (conn != NULL), return ERR_ARG;);
+
+  msg.function = do_join_leave_group;
+  msg.msg.conn = conn;
+  msg.msg.msg.jl.multiaddr = multiaddr;
+  msg.msg.msg.jl.netif_addr = netif_addr;
+  msg.msg.msg.jl.join_or_leave = join_or_leave;
+  err = TCPIP_APIMSG(&msg);
+
+  NETCONN_SET_SAFE_ERR(conn, err);
+  return err;
+}
+#endif /* LWIP_IGMP */
+
+#if LWIP_DNS
+/**
+ * Execute a DNS query, only one IP address is returned
+ *
+ * @param name a string representation of the DNS host name to query
+ * @param addr a preallocated ip_addr_t where to store the resolved IP address
+ * @return ERR_OK: resolving succeeded
+ *         ERR_MEM: memory error, try again later
+ *         ERR_ARG: dns client not initialized or invalid hostname
+ *         ERR_VAL: dns server response was invalid
+ */
+err_t
+netconn_gethostbyname(const char *name, ip_addr_t *addr)
+{
+  struct dns_api_msg msg;
+  err_t err;
+  sys_sem_t sem;
+
+  LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;);
+  LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;);
+
+  err = sys_sem_new(&sem, 0);
+  if (err != ERR_OK) {
+    return err;
+  }
+
+  msg.name = name;
+  msg.addr = addr;
+  msg.err = &err;
+  msg.sem = &sem;
+
+  tcpip_callback(do_gethostbyname, &msg);
+  sys_sem_wait(&sem);
+  sys_sem_free(&sem);
+
+  return err;
+}
+#endif /* LWIP_DNS*/
+
+#endif /* LWIP_NETCONN */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/api/api_msg.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/api/api_msg.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/api/api_msg.c	(revision 164)
@@ -0,0 +1,1565 @@
+/**
+ * @file
+ * Sequential API Internal module
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/api_msg.h"
+
+#include "lwip/ip.h"
+#include "lwip/udp.h"
+#include "lwip/tcp.h"
+#include "lwip/raw.h"
+
+#include "lwip/memp.h"
+#include "lwip/tcpip.h"
+#include "lwip/igmp.h"
+#include "lwip/dns.h"
+
+#include <string.h>
+
+#define SET_NONBLOCKING_CONNECT(conn, val)  do { if(val) { \
+  (conn)->flags |= NETCONN_FLAG_IN_NONBLOCKING_CONNECT; \
+} else { \
+  (conn)->flags &= ~ NETCONN_FLAG_IN_NONBLOCKING_CONNECT; }} while(0)
+#define IN_NONBLOCKING_CONNECT(conn) (((conn)->flags & NETCONN_FLAG_IN_NONBLOCKING_CONNECT) != 0)
+
+/* forward declarations */
+#if LWIP_TCP
+static err_t do_writemore(struct netconn *conn);
+static void do_close_internal(struct netconn *conn);
+#endif
+
+#if LWIP_RAW
+/**
+ * Receive callback function for RAW netconns.
+ * Doesn't 'eat' the packet, only references it and sends it to
+ * conn->recvmbox
+ *
+ * @see raw.h (struct raw_pcb.recv) for parameters and return value
+ */
+static u8_t
+recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
+    ip_addr_t *addr)
+{
+  struct pbuf *q;
+  struct netbuf *buf;
+  struct netconn *conn;
+
+  LWIP_UNUSED_ARG(addr);
+  conn = (struct netconn *)arg;
+
+  if ((conn != NULL) && sys_mbox_valid(&conn->recvmbox)) {
+#if LWIP_SO_RCVBUF
+    int recv_avail;
+    SYS_ARCH_GET(conn->recv_avail, recv_avail);
+    if ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize) {
+      return 0;
+    }
+#endif /* LWIP_SO_RCVBUF */
+    /* copy the whole packet into new pbufs */
+    q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
+    if(q != NULL) {
+      if (pbuf_copy(q, p) != ERR_OK) {
+        pbuf_free(q);
+        q = NULL;
+      }
+    }
+
+    if (q != NULL) {
+      u16_t len;
+      buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
+      if (buf == NULL) {
+        pbuf_free(q);
+        return 0;
+      }
+
+      buf->p = q;
+      buf->ptr = q;
+      ip_addr_copy(buf->addr, *ip_current_src_addr());
+      buf->port = pcb->protocol;
+
+      len = q->tot_len;
+      if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) {
+        netbuf_delete(buf);
+        return 0;
+      } else {
+#if LWIP_SO_RCVBUF
+        SYS_ARCH_INC(conn->recv_avail, len);
+#endif /* LWIP_SO_RCVBUF */
+        /* Register event with callback */
+        API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
+      }
+    }
+  }
+
+  return 0; /* do not eat the packet */
+}
+#endif /* LWIP_RAW*/
+
+#if LWIP_UDP
+/**
+ * Receive callback function for UDP netconns.
+ * Posts the packet to conn->recvmbox or deletes it on memory error.
+ *
+ * @see udp.h (struct udp_pcb.recv) for parameters
+ */
+static void
+recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
+   ip_addr_t *addr, u16_t port)
+{
+  struct netbuf *buf;
+  struct netconn *conn;
+  u16_t len;
+#if LWIP_SO_RCVBUF
+  int recv_avail;
+#endif /* LWIP_SO_RCVBUF */
+
+  LWIP_UNUSED_ARG(pcb); /* only used for asserts... */
+  LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL);
+  LWIP_ASSERT("recv_udp must have an argument", arg != NULL);
+  conn = (struct netconn *)arg;
+  LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb);
+
+#if LWIP_SO_RCVBUF
+  SYS_ARCH_GET(conn->recv_avail, recv_avail);
+  if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox) ||
+      ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
+#else  /* LWIP_SO_RCVBUF */
+  if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox)) {
+#endif /* LWIP_SO_RCVBUF */
+    pbuf_free(p);
+    return;
+  }
+
+  buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
+  if (buf == NULL) {
+    pbuf_free(p);
+    return;
+  } else {
+    buf->p = p;
+    buf->ptr = p;
+    ip_addr_set(&buf->addr, addr);
+    buf->port = port;
+#if LWIP_NETBUF_RECVINFO
+    {
+      const struct ip_hdr* iphdr = ip_current_header();
+      /* get the UDP header - always in the first pbuf, ensured by udp_input */
+      const struct udp_hdr* udphdr = (void*)(((char*)iphdr) + IPH_LEN(iphdr));
+#if LWIP_CHECKSUM_ON_COPY
+      buf->flags = NETBUF_FLAG_DESTADDR;
+#endif /* LWIP_CHECKSUM_ON_COPY */
+      ip_addr_set(&buf->toaddr, ip_current_dest_addr());
+      buf->toport_chksum = udphdr->dest;
+    }
+#endif /* LWIP_NETBUF_RECVINFO */
+  }
+
+  len = p->tot_len;
+  if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) {
+    netbuf_delete(buf);
+    return;
+  } else {
+#if LWIP_SO_RCVBUF
+    SYS_ARCH_INC(conn->recv_avail, len);
+#endif /* LWIP_SO_RCVBUF */
+    /* Register event with callback */
+    API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
+  }
+}
+#endif /* LWIP_UDP */
+
+#if LWIP_TCP
+/**
+ * Receive callback function for TCP netconns.
+ * Posts the packet to conn->recvmbox, but doesn't delete it on errors.
+ *
+ * @see tcp.h (struct tcp_pcb.recv) for parameters and return value
+ */
+static err_t
+recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
+{
+  struct netconn *conn;
+  u16_t len;
+
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL);
+  LWIP_ASSERT("recv_tcp must have an argument", arg != NULL);
+  conn = (struct netconn *)arg;
+  LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb);
+
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+  if (!sys_mbox_valid(&conn->recvmbox)) {
+    /* recvmbox already deleted */
+    if (p != NULL) {
+      tcp_recved(pcb, p->tot_len);
+      pbuf_free(p);
+    }
+    return ERR_OK;
+  }
+  /* Unlike for UDP or RAW pcbs, don't check for available space
+     using recv_avail since that could break the connection
+     (data is already ACKed) */
+
+  /* don't overwrite fatal errors! */
+  NETCONN_SET_SAFE_ERR(conn, err);
+
+  if (p != NULL) {
+    len = p->tot_len;
+  } else {
+    len = 0;
+  }
+
+  if (sys_mbox_trypost(&conn->recvmbox, p) != ERR_OK) {
+    /* don't deallocate p: it is presented to us later again from tcp_fasttmr! */
+    return ERR_MEM;
+  } else {
+#if LWIP_SO_RCVBUF
+    SYS_ARCH_INC(conn->recv_avail, len);
+#endif /* LWIP_SO_RCVBUF */
+    /* Register event with callback */
+    API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
+  }
+
+  return ERR_OK;
+}
+
+/**
+ * Poll callback function for TCP netconns.
+ * Wakes up an application thread that waits for a connection to close
+ * or data to be sent. The application thread then takes the
+ * appropriate action to go on.
+ *
+ * Signals the conn->sem.
+ * netconn_close waits for conn->sem if closing failed.
+ *
+ * @see tcp.h (struct tcp_pcb.poll) for parameters and return value
+ */
+static err_t
+poll_tcp(void *arg, struct tcp_pcb *pcb)
+{
+  struct netconn *conn = (struct netconn *)arg;
+
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_ASSERT("conn != NULL", (conn != NULL));
+
+  if (conn->state == NETCONN_WRITE) {
+    do_writemore(conn);
+  } else if (conn->state == NETCONN_CLOSE) {
+    do_close_internal(conn);
+  }
+  /* @todo: implement connect timeout here? */
+
+  /* Did a nonblocking write fail before? Then check available write-space. */
+  if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) {
+    /* If the queued byte- or pbuf-count drops below the configured low-water limit,
+       let select mark this pcb as writable again. */
+    if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) &&
+      (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) {
+      conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
+      API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
+    }
+  }
+
+  return ERR_OK;
+}
+
+/**
+ * Sent callback function for TCP netconns.
+ * Signals the conn->sem and calls API_EVENT.
+ * netconn_write waits for conn->sem if send buffer is low.
+ *
+ * @see tcp.h (struct tcp_pcb.sent) for parameters and return value
+ */
+static err_t
+sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
+{
+  struct netconn *conn = (struct netconn *)arg;
+
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_ASSERT("conn != NULL", (conn != NULL));
+
+  if (conn->state == NETCONN_WRITE) {
+    do_writemore(conn);
+  } else if (conn->state == NETCONN_CLOSE) {
+    do_close_internal(conn);
+  }
+
+  if (conn) {
+    /* If the queued byte- or pbuf-count drops below the configured low-water limit,
+       let select mark this pcb as writable again. */
+    if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) &&
+      (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) {
+      conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
+      API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);
+    }
+  }
+  
+  return ERR_OK;
+}
+
+/**
+ * Error callback function for TCP netconns.
+ * Signals conn->sem, posts to all conn mboxes and calls API_EVENT.
+ * The application thread has then to decide what to do.
+ *
+ * @see tcp.h (struct tcp_pcb.err) for parameters
+ */
+static void
+err_tcp(void *arg, err_t err)
+{
+  struct netconn *conn;
+  enum netconn_state old_state;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  conn = (struct netconn *)arg;
+  LWIP_ASSERT("conn != NULL", (conn != NULL));
+
+  conn->pcb.tcp = NULL;
+
+  /* no check since this is always fatal! */
+  SYS_ARCH_PROTECT(lev);
+  conn->last_err = err;
+  SYS_ARCH_UNPROTECT(lev);
+
+  /* reset conn->state now before waking up other threads */
+  old_state = conn->state;
+  conn->state = NETCONN_NONE;
+
+  /* Notify the user layer about a connection error. Used to signal
+     select. */
+  API_EVENT(conn, NETCONN_EVT_ERROR, 0);
+  /* Try to release selects pending on 'read' or 'write', too.
+     They will get an error if they actually try to read or write. */
+  API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
+  API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
+
+  /* pass NULL-message to recvmbox to wake up pending recv */
+  if (sys_mbox_valid(&conn->recvmbox)) {
+    /* use trypost to prevent deadlock */
+    sys_mbox_trypost(&conn->recvmbox, NULL);
+  }
+  /* pass NULL-message to acceptmbox to wake up pending accept */
+  if (sys_mbox_valid(&conn->acceptmbox)) {
+    /* use trypost to preven deadlock */
+    sys_mbox_trypost(&conn->acceptmbox, NULL);
+  }
+
+  if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
+      (old_state == NETCONN_CONNECT)) {
+    /* calling do_writemore/do_close_internal is not necessary
+       since the pcb has already been deleted! */
+    int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn);
+    SET_NONBLOCKING_CONNECT(conn, 0);
+
+    if (!was_nonblocking_connect) {
+      /* set error return code */
+      LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
+      conn->current_msg->err = err;
+      conn->current_msg = NULL;
+      /* wake up the waiting task */
+      sys_sem_signal(&conn->op_completed);
+    }
+  } else {
+    LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL);
+  }
+}
+
+/**
+ * Setup a tcp_pcb with the correct callback function pointers
+ * and their arguments.
+ *
+ * @param conn the TCP netconn to setup
+ */
+static void
+setup_tcp(struct netconn *conn)
+{
+  struct tcp_pcb *pcb;
+
+  pcb = conn->pcb.tcp;
+  tcp_arg(pcb, conn);
+  tcp_recv(pcb, recv_tcp);
+  tcp_sent(pcb, sent_tcp);
+  tcp_poll(pcb, poll_tcp, 4);
+  tcp_err(pcb, err_tcp);
+}
+
+/**
+ * Accept callback function for TCP netconns.
+ * Allocates a new netconn and posts that to conn->acceptmbox.
+ *
+ * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value
+ */
+static err_t
+accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
+{
+  struct netconn *newconn;
+  struct netconn *conn = (struct netconn *)arg;
+
+  LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->tate: %s\n", tcp_debug_state_str(newpcb->state)));
+
+  if (!sys_mbox_valid(&conn->acceptmbox)) {
+    LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n"));
+    return ERR_VAL;
+  }
+
+  /* We have to set the callback here even though
+   * the new socket is unknown. conn->socket is marked as -1. */
+  newconn = netconn_alloc(conn->type, conn->callback);
+  if (newconn == NULL) {
+    return ERR_MEM;
+  }
+  newconn->pcb.tcp = newpcb;
+  setup_tcp(newconn);
+  /* no protection: when creating the pcb, the netconn is not yet known
+     to the application thread */
+  newconn->last_err = err;
+
+  if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) {
+    /* When returning != ERR_OK, the pcb is aborted in tcp_process(),
+       so do nothing here! */
+    /* remove all references to this netconn from the pcb */
+    struct tcp_pcb* pcb = newconn->pcb.tcp;
+    tcp_arg(pcb, NULL);
+    tcp_recv(pcb, NULL);
+    tcp_sent(pcb, NULL);
+    tcp_poll(pcb, NULL, 4);
+    tcp_err(pcb, NULL);
+    /* remove reference from to the pcb from this netconn */
+    newconn->pcb.tcp = NULL;
+    /* no need to drain since we know the recvmbox is empty. */
+    sys_mbox_free(&newconn->recvmbox);
+    sys_mbox_set_invalid(&newconn->recvmbox);
+    netconn_free(newconn);
+    return ERR_MEM;
+  } else {
+    /* Register event with callback */
+    API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
+  }
+
+  return ERR_OK;
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Create a new pcb of a specific type.
+ * Called from do_newconn().
+ *
+ * @param msg the api_msg_msg describing the connection type
+ * @return msg->conn->err, but the return value is currently ignored
+ */
+static void
+pcb_new(struct api_msg_msg *msg)
+{
+  LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL);
+
+  /* Allocate a PCB for this connection */
+  switch(NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+  case NETCONN_RAW:
+    msg->conn->pcb.raw = raw_new(msg->msg.n.proto);
+    if(msg->conn->pcb.raw == NULL) {
+      msg->err = ERR_MEM;
+      break;
+    }
+    raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
+    break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+  case NETCONN_UDP:
+    msg->conn->pcb.udp = udp_new();
+    if(msg->conn->pcb.udp == NULL) {
+      msg->err = ERR_MEM;
+      break;
+    }
+#if LWIP_UDPLITE
+    if (msg->conn->type==NETCONN_UDPLITE) {
+      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
+    }
+#endif /* LWIP_UDPLITE */
+    if (msg->conn->type==NETCONN_UDPNOCHKSUM) {
+      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
+    }
+    udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
+    break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+  case NETCONN_TCP:
+    msg->conn->pcb.tcp = tcp_new();
+    if(msg->conn->pcb.tcp == NULL) {
+      msg->err = ERR_MEM;
+      break;
+    }
+    setup_tcp(msg->conn);
+    break;
+#endif /* LWIP_TCP */
+  default:
+    /* Unsupported netconn type, e.g. protocol disabled */
+    msg->err = ERR_VAL;
+    break;
+  }
+}
+
+/**
+ * Create a new pcb of a specific type inside a netconn.
+ * Called from netconn_new_with_proto_and_callback.
+ *
+ * @param msg the api_msg_msg describing the connection type
+ */
+void
+do_newconn(struct api_msg_msg *msg)
+{
+  msg->err = ERR_OK;
+  if(msg->conn->pcb.tcp == NULL) {
+    pcb_new(msg);
+  }
+  /* Else? This "new" connection already has a PCB allocated. */
+  /* Is this an error condition? Should it be deleted? */
+  /* We currently just are happy and return. */
+
+  TCPIP_APIMSG_ACK(msg);
+}
+
+/**
+ * Create a new netconn (of a specific type) that has a callback function.
+ * The corresponding pcb is NOT created!
+ *
+ * @param t the type of 'connection' to create (@see enum netconn_type)
+ * @param proto the IP protocol for RAW IP pcbs
+ * @param callback a function to call on status changes (RX available, TX'ed)
+ * @return a newly allocated struct netconn or
+ *         NULL on memory error
+ */
+struct netconn*
+netconn_alloc(enum netconn_type t, netconn_callback callback)
+{
+  struct netconn *conn;
+  int size;
+
+  conn = (struct netconn *)memp_malloc(MEMP_NETCONN);
+  if (conn == NULL) {
+    return NULL;
+  }
+
+  conn->last_err = ERR_OK;
+  conn->type = t;
+  conn->pcb.tcp = NULL;
+
+#if (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_UDP_RECVMBOX_SIZE) && \
+    (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_TCP_RECVMBOX_SIZE)
+  size = DEFAULT_RAW_RECVMBOX_SIZE;
+#else
+  switch(NETCONNTYPE_GROUP(t)) {
+#if LWIP_RAW
+  case NETCONN_RAW:
+    size = DEFAULT_RAW_RECVMBOX_SIZE;
+    break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+  case NETCONN_UDP:
+    size = DEFAULT_UDP_RECVMBOX_SIZE;
+    break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+  case NETCONN_TCP:
+    size = DEFAULT_TCP_RECVMBOX_SIZE;
+    break;
+#endif /* LWIP_TCP */
+  default:
+    LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0);
+    goto free_and_return;
+  }
+#endif
+
+  if (sys_sem_new(&conn->op_completed, 0) != ERR_OK) {
+    goto free_and_return;
+  }
+  if (sys_mbox_new(&conn->recvmbox, size) != ERR_OK) {
+    sys_sem_free(&conn->op_completed);
+    goto free_and_return;
+  }
+
+#if LWIP_TCP
+  sys_mbox_set_invalid(&conn->acceptmbox);
+#endif
+  conn->state        = NETCONN_NONE;
+#if LWIP_SOCKET
+  /* initialize socket to -1 since 0 is a valid socket */
+  conn->socket       = -1;
+#endif /* LWIP_SOCKET */
+  conn->callback     = callback;
+#if LWIP_TCP
+  conn->current_msg  = NULL;
+  conn->write_offset = 0;
+#endif /* LWIP_TCP */
+#if LWIP_SO_SNDTIMEO
+  conn->send_timeout = 0;
+#endif /* LWIP_SO_SNDTIMEO */
+#if LWIP_SO_RCVTIMEO
+  conn->recv_timeout = 0;
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+  conn->recv_bufsize = RECV_BUFSIZE_DEFAULT;
+  conn->recv_avail   = 0;
+#endif /* LWIP_SO_RCVBUF */
+  conn->flags = 0;
+  return conn;
+free_and_return:
+  memp_free(MEMP_NETCONN, conn);
+  return NULL;
+}
+
+/**
+ * Delete a netconn and all its resources.
+ * The pcb is NOT freed (since we might not be in the right thread context do this).
+ *
+ * @param conn the netconn to free
+ */
+void
+netconn_free(struct netconn *conn)
+{
+  LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL);
+  LWIP_ASSERT("recvmbox must be deallocated before calling this function",
+    !sys_mbox_valid(&conn->recvmbox));
+#if LWIP_TCP
+  LWIP_ASSERT("acceptmbox must be deallocated before calling this function",
+    !sys_mbox_valid(&conn->acceptmbox));
+#endif /* LWIP_TCP */
+
+  sys_sem_free(&conn->op_completed);
+  sys_sem_set_invalid(&conn->op_completed);
+
+  memp_free(MEMP_NETCONN, conn);
+}
+
+/**
+ * Delete rcvmbox and acceptmbox of a netconn and free the left-over data in
+ * these mboxes
+ *
+ * @param conn the netconn to free
+ * @bytes_drained bytes drained from recvmbox
+ * @accepts_drained pending connections drained from acceptmbox
+ */
+static void
+netconn_drain(struct netconn *conn)
+{
+  void *mem;
+#if LWIP_TCP
+  struct pbuf *p;
+#endif /* LWIP_TCP */
+
+  /* This runs in tcpip_thread, so we don't need to lock against rx packets */
+
+  /* Delete and drain the recvmbox. */
+  if (sys_mbox_valid(&conn->recvmbox)) {
+    while (sys_mbox_tryfetch(&conn->recvmbox, &mem) != SYS_MBOX_EMPTY) {
+#if LWIP_TCP
+      if (conn->type == NETCONN_TCP) {
+        if(mem != NULL) {
+          p = (struct pbuf*)mem;
+          /* pcb might be set to NULL already by err_tcp() */
+          if (conn->pcb.tcp != NULL) {
+            tcp_recved(conn->pcb.tcp, p->tot_len);
+          }
+          pbuf_free(p);
+        }
+      } else
+#endif /* LWIP_TCP */
+      {
+        netbuf_delete((struct netbuf *)mem);
+      }
+    }
+    sys_mbox_free(&conn->recvmbox);
+    sys_mbox_set_invalid(&conn->recvmbox);
+  }
+
+  /* Delete and drain the acceptmbox. */
+#if LWIP_TCP
+  if (sys_mbox_valid(&conn->acceptmbox)) {
+    while (sys_mbox_tryfetch(&conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) {
+      struct netconn *newconn = (struct netconn *)mem;
+      /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */
+      /* pcb might be set to NULL already by err_tcp() */
+      if (conn->pcb.tcp != NULL) {
+        tcp_accepted(conn->pcb.tcp);
+      }
+      /* drain recvmbox */
+      netconn_drain(newconn);
+      if (newconn->pcb.tcp != NULL) {
+        tcp_abort(newconn->pcb.tcp);
+        newconn->pcb.tcp = NULL;
+      }
+      netconn_free(newconn);
+    }
+    sys_mbox_free(&conn->acceptmbox);
+    sys_mbox_set_invalid(&conn->acceptmbox);
+  }
+#endif /* LWIP_TCP */
+}
+
+#if LWIP_TCP
+/**
+ * Internal helper function to close a TCP netconn: since this sometimes
+ * doesn't work at the first attempt, this function is called from multiple
+ * places.
+ *
+ * @param conn the TCP netconn to close
+ */
+static void
+do_close_internal(struct netconn *conn)
+{
+  err_t err;
+  u8_t shut, shut_rx, shut_tx, close;
+
+  LWIP_ASSERT("invalid conn", (conn != NULL));
+  LWIP_ASSERT("this is for tcp netconns only", (conn->type == NETCONN_TCP));
+  LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE));
+  LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL));
+  LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
+
+  shut = conn->current_msg->msg.sd.shut;
+  shut_rx = shut & NETCONN_SHUT_RD;
+  shut_tx = shut & NETCONN_SHUT_WR;
+  /* shutting down both ends is the same as closing */
+  close = shut == NETCONN_SHUT_RDWR;
+
+  /* Set back some callback pointers */
+  if (close) {
+    tcp_arg(conn->pcb.tcp, NULL);
+  }
+  if (conn->pcb.tcp->state == LISTEN) {
+    tcp_accept(conn->pcb.tcp, NULL);
+  } else {
+    /* some callbacks have to be reset if tcp_close is not successful */
+    if (shut_rx) {
+      tcp_recv(conn->pcb.tcp, NULL);
+      tcp_accept(conn->pcb.tcp, NULL);
+    }
+    if (shut_tx) {
+      tcp_sent(conn->pcb.tcp, NULL);
+    }
+    if (close) {
+      tcp_poll(conn->pcb.tcp, NULL, 4);
+      tcp_err(conn->pcb.tcp, NULL);
+    }
+  }
+  /* Try to close the connection */
+  if (close) {
+    err = tcp_close(conn->pcb.tcp);
+  } else {
+    err = tcp_shutdown(conn->pcb.tcp, shut_rx, shut_tx);
+  }
+  if (err == ERR_OK) {
+    /* Closing succeeded */
+    conn->current_msg->err = ERR_OK;
+    conn->current_msg = NULL;
+    conn->state = NETCONN_NONE;
+    if (close) {
+      /* Set back some callback pointers as conn is going away */
+      conn->pcb.tcp = NULL;
+      /* Trigger select() in socket layer. Make sure everybody notices activity
+       on the connection, error first! */
+      API_EVENT(conn, NETCONN_EVT_ERROR, 0);
+    }
+    if (shut_rx) {
+      API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
+    }
+    if (shut_tx) {
+      API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
+    }
+    /* wake up the application task */
+    sys_sem_signal(&conn->op_completed);
+  } else {
+    /* Closing failed, restore some of the callbacks */
+    /* Closing of listen pcb will never fail! */
+    LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN));
+    tcp_sent(conn->pcb.tcp, sent_tcp);
+    tcp_poll(conn->pcb.tcp, poll_tcp, 4);
+    tcp_err(conn->pcb.tcp, err_tcp);
+    tcp_arg(conn->pcb.tcp, conn);
+    /* don't restore recv callback: we don't want to receive any more data */
+  }
+  /* If closing didn't succeed, we get called again either
+     from poll_tcp or from sent_tcp */
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Delete the pcb inside a netconn.
+ * Called from netconn_delete.
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_delconn(struct api_msg_msg *msg)
+{
+  /* @todo TCP: abort running write/connect? */
+ if ((msg->conn->state != NETCONN_NONE) &&
+     (msg->conn->state != NETCONN_LISTEN) &&
+     (msg->conn->state != NETCONN_CONNECT)) {
+    /* this only happens for TCP netconns */
+    LWIP_ASSERT("msg->conn->type == NETCONN_TCP", msg->conn->type == NETCONN_TCP);
+    msg->err = ERR_INPROGRESS;
+  } else {
+    LWIP_ASSERT("blocking connect in progress",
+      (msg->conn->state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn));
+    /* Drain and delete mboxes */
+    netconn_drain(msg->conn);
+
+    if (msg->conn->pcb.tcp != NULL) {
+
+      switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+      case NETCONN_RAW:
+        raw_remove(msg->conn->pcb.raw);
+        break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+      case NETCONN_UDP:
+        msg->conn->pcb.udp->recv_arg = NULL;
+        udp_remove(msg->conn->pcb.udp);
+        break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+      case NETCONN_TCP:
+        LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
+          msg->conn->write_offset == 0);
+        msg->conn->state = NETCONN_CLOSE;
+        msg->msg.sd.shut = NETCONN_SHUT_RDWR;
+        msg->conn->current_msg = msg;
+        do_close_internal(msg->conn);
+        /* API_EVENT is called inside do_close_internal, before releasing
+           the application thread, so we can return at this point! */
+        return;
+#endif /* LWIP_TCP */
+      default:
+        break;
+      }
+      msg->conn->pcb.tcp = NULL;
+    }
+    /* tcp netconns don't come here! */
+
+    /* @todo: this lets select make the socket readable and writable,
+       which is wrong! errfd instead? */
+    API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0);
+    API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0);
+  }
+  if (sys_sem_valid(&msg->conn->op_completed)) {
+    sys_sem_signal(&msg->conn->op_completed);
+  }
+}
+
+/**
+ * Bind a pcb contained in a netconn
+ * Called from netconn_bind.
+ *
+ * @param msg the api_msg_msg pointing to the connection and containing
+ *            the IP address and port to bind to
+ */
+void
+do_bind(struct api_msg_msg *msg)
+{
+  if (ERR_IS_FATAL(msg->conn->last_err)) {
+    msg->err = msg->conn->last_err;
+  } else {
+    msg->err = ERR_VAL;
+    if (msg->conn->pcb.tcp != NULL) {
+      switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+      case NETCONN_RAW:
+        msg->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
+        break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+      case NETCONN_UDP:
+        msg->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
+        break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+      case NETCONN_TCP:
+        msg->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port);
+        break;
+#endif /* LWIP_TCP */
+      default:
+        break;
+      }
+    }
+  }
+  TCPIP_APIMSG_ACK(msg);
+}
+
+#if LWIP_TCP
+/**
+ * TCP callback function if a connection (opened by tcp_connect/do_connect) has
+ * been established (or reset by the remote host).
+ *
+ * @see tcp.h (struct tcp_pcb.connected) for parameters and return values
+ */
+static err_t
+do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
+{
+  struct netconn *conn;
+  int was_blocking;
+
+  LWIP_UNUSED_ARG(pcb);
+
+  conn = (struct netconn *)arg;
+
+  if (conn == NULL) {
+    return ERR_VAL;
+  }
+
+  LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT);
+  LWIP_ASSERT("(conn->current_msg != NULL) || conn->in_non_blocking_connect",
+    (conn->current_msg != NULL) || IN_NONBLOCKING_CONNECT(conn));
+
+  if (conn->current_msg != NULL) {
+    conn->current_msg->err = err;
+  }
+  if ((conn->type == NETCONN_TCP) && (err == ERR_OK)) {
+    setup_tcp(conn);
+  }
+  was_blocking = !IN_NONBLOCKING_CONNECT(conn);
+  SET_NONBLOCKING_CONNECT(conn, 0);
+  conn->current_msg = NULL;
+  conn->state = NETCONN_NONE;
+  if (!was_blocking) {
+    NETCONN_SET_SAFE_ERR(conn, ERR_OK);
+  }
+  API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
+
+  if (was_blocking) {
+    sys_sem_signal(&conn->op_completed);
+  }
+  return ERR_OK;
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Connect a pcb contained inside a netconn
+ * Called from netconn_connect.
+ *
+ * @param msg the api_msg_msg pointing to the connection and containing
+ *            the IP address and port to connect to
+ */
+void
+do_connect(struct api_msg_msg *msg)
+{
+  if (msg->conn->pcb.tcp == NULL) {
+    /* This may happen when calling netconn_connect() a second time */
+    msg->err = ERR_CLSD;
+  } else {
+    switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+  case NETCONN_RAW:
+    msg->err = raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
+    break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+  case NETCONN_UDP:
+    msg->err = udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
+    break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+  case NETCONN_TCP:
+    /* Prevent connect while doing any other action. */
+    if (msg->conn->state != NETCONN_NONE) {
+      msg->err = ERR_ISCONN;
+    } else {
+      setup_tcp(msg->conn);
+      msg->err = tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr,
+        msg->msg.bc.port, do_connected);
+      if (msg->err == ERR_OK) {
+        u8_t non_blocking = netconn_is_nonblocking(msg->conn);
+        msg->conn->state = NETCONN_CONNECT;
+        SET_NONBLOCKING_CONNECT(msg->conn, non_blocking);
+        if (non_blocking) {
+          msg->err = ERR_INPROGRESS;
+        } else {
+          msg->conn->current_msg = msg;
+          /* sys_sem_signal() is called from do_connected (or err_tcp()),
+          * when the connection is established! */
+          return;
+        }
+      }
+    }
+    break;
+#endif /* LWIP_TCP */
+  default:
+    LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL; }while(0));
+    break;
+    }
+  }
+  sys_sem_signal(&msg->conn->op_completed);
+}
+
+/**
+ * Connect a pcb contained inside a netconn
+ * Only used for UDP netconns.
+ * Called from netconn_disconnect.
+ *
+ * @param msg the api_msg_msg pointing to the connection to disconnect
+ */
+void
+do_disconnect(struct api_msg_msg *msg)
+{
+#if LWIP_UDP
+  if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
+    udp_disconnect(msg->conn->pcb.udp);
+    msg->err = ERR_OK;
+  } else
+#endif /* LWIP_UDP */
+  {
+    msg->err = ERR_VAL;
+  }
+  TCPIP_APIMSG_ACK(msg);
+}
+
+#if LWIP_TCP
+/**
+ * Set a TCP pcb contained in a netconn into listen mode
+ * Called from netconn_listen.
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_listen(struct api_msg_msg *msg)
+{
+  if (ERR_IS_FATAL(msg->conn->last_err)) {
+    msg->err = msg->conn->last_err;
+  } else {
+    msg->err = ERR_CONN;
+    if (msg->conn->pcb.tcp != NULL) {
+      if (msg->conn->type == NETCONN_TCP) {
+        if (msg->conn->state == NETCONN_NONE) {
+#if TCP_LISTEN_BACKLOG
+          struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);
+#else  /* TCP_LISTEN_BACKLOG */
+          struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp);
+#endif /* TCP_LISTEN_BACKLOG */
+          if (lpcb == NULL) {
+            /* in this case, the old pcb is still allocated */
+            msg->err = ERR_MEM;
+          } else {
+            /* delete the recvmbox and allocate the acceptmbox */
+            if (sys_mbox_valid(&msg->conn->recvmbox)) {
+              /** @todo: should we drain the recvmbox here? */
+              sys_mbox_free(&msg->conn->recvmbox);
+              sys_mbox_set_invalid(&msg->conn->recvmbox);
+            }
+            msg->err = ERR_OK;
+            if (!sys_mbox_valid(&msg->conn->acceptmbox)) {
+              msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE);
+            }
+            if (msg->err == ERR_OK) {
+              msg->conn->state = NETCONN_LISTEN;
+              msg->conn->pcb.tcp = lpcb;
+              tcp_arg(msg->conn->pcb.tcp, msg->conn);
+              tcp_accept(msg->conn->pcb.tcp, accept_function);
+            } else {
+              /* since the old pcb is already deallocated, free lpcb now */
+              tcp_close(lpcb);
+              msg->conn->pcb.tcp = NULL;
+            }
+          }
+        }
+      } else {
+        msg->err = ERR_ARG;
+      }
+    }
+  }
+  TCPIP_APIMSG_ACK(msg);
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Send some data on a RAW or UDP pcb contained in a netconn
+ * Called from netconn_send
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_send(struct api_msg_msg *msg)
+{
+  if (ERR_IS_FATAL(msg->conn->last_err)) {
+    msg->err = msg->conn->last_err;
+  } else {
+    msg->err = ERR_CONN;
+    if (msg->conn->pcb.tcp != NULL) {
+      switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+      case NETCONN_RAW:
+        if (ip_addr_isany(&msg->msg.b->addr)) {
+          msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p);
+        } else {
+          msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr);
+        }
+        break;
+#endif
+#if LWIP_UDP
+      case NETCONN_UDP:
+#if LWIP_CHECKSUM_ON_COPY
+        if (ip_addr_isany(&msg->msg.b->addr)) {
+          msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p,
+            msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
+        } else {
+          msg->err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p,
+            &msg->msg.b->addr, msg->msg.b->port,
+            msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
+        }
+#else /* LWIP_CHECKSUM_ON_COPY */
+        if (ip_addr_isany(&msg->msg.b->addr)) {
+          msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);
+        } else {
+          msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port);
+        }
+#endif /* LWIP_CHECKSUM_ON_COPY */
+        break;
+#endif /* LWIP_UDP */
+      default:
+        break;
+      }
+    }
+  }
+  TCPIP_APIMSG_ACK(msg);
+}
+
+#if LWIP_TCP
+/**
+ * Indicate data has been received from a TCP pcb contained in a netconn
+ * Called from netconn_recv
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_recv(struct api_msg_msg *msg)
+{
+  msg->err = ERR_OK;
+  if (msg->conn->pcb.tcp != NULL) {
+    if (msg->conn->type == NETCONN_TCP) {
+#if TCP_LISTEN_BACKLOG
+      if (msg->conn->pcb.tcp->state == LISTEN) {
+        tcp_accepted(msg->conn->pcb.tcp);
+      } else
+#endif /* TCP_LISTEN_BACKLOG */
+      {
+        u32_t remaining = msg->msg.r.len;
+        do {
+          u16_t recved = (remaining > 0xffff) ? 0xffff : (u16_t)remaining;
+          tcp_recved(msg->conn->pcb.tcp, recved);
+          remaining -= recved;
+        }while(remaining != 0);
+      }
+    }
+  }
+  TCPIP_APIMSG_ACK(msg);
+}
+
+/**
+ * See if more data needs to be written from a previous call to netconn_write.
+ * Called initially from do_write. If the first call can't send all data
+ * (because of low memory or empty send-buffer), this function is called again
+ * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the
+ * blocking application thread (waiting in netconn_write) is released.
+ *
+ * @param conn netconn (that is currently in state NETCONN_WRITE) to process
+ * @return ERR_OK
+ *         ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished
+ */
+static err_t
+do_writemore(struct netconn *conn)
+{
+  err_t err;
+  void *dataptr;
+  u16_t len, available;
+  u8_t write_finished = 0;
+  size_t diff;
+  u8_t dontblock = netconn_is_nonblocking(conn) ||
+       (conn->current_msg->msg.w.apiflags & NETCONN_DONTBLOCK);
+  u8_t apiflags = conn->current_msg->msg.w.apiflags;
+
+  LWIP_ASSERT("conn != NULL", conn != NULL);
+  LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE));
+  LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
+  LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL);
+  LWIP_ASSERT("conn->write_offset < conn->current_msg->msg.w.len",
+    conn->write_offset < conn->current_msg->msg.w.len);
+
+#if LWIP_SO_SNDTIMEO
+  if ((conn->send_timeout != 0) &&
+      ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) {
+    write_finished = 1;
+    if (conn->write_offset == 0) {
+      /* nothing has been written */
+      err = ERR_WOULDBLOCK;
+      conn->current_msg->msg.w.len = 0;
+    } else {
+      /* partial write */
+      err = ERR_OK;
+      conn->current_msg->msg.w.len = conn->write_offset;
+    }
+  } else
+#endif /* LWIP_SO_SNDTIMEO */
+  {
+    dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset;
+    diff = conn->current_msg->msg.w.len - conn->write_offset;
+    if (diff > 0xffffUL) { /* max_u16_t */
+      len = 0xffff;
+#if LWIP_TCPIP_CORE_LOCKING
+      conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
+#endif
+      apiflags |= TCP_WRITE_FLAG_MORE;
+    } else {
+      len = (u16_t)diff;
+    }
+    available = tcp_sndbuf(conn->pcb.tcp);
+    if (available < len) {
+      /* don't try to write more than sendbuf */
+      len = available;
+      if (dontblock){ 
+        if (!len) {
+          err = ERR_WOULDBLOCK;
+          goto err_mem;
+        }
+      } else {
+#if LWIP_TCPIP_CORE_LOCKING
+        conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
+#endif
+        apiflags |= TCP_WRITE_FLAG_MORE;
+      }
+    }
+    LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len));
+    err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags);
+    /* if OK or memory error, check available space */
+    if ((err == ERR_OK) || (err == ERR_MEM)) {
+err_mem:
+      if (dontblock && (len < conn->current_msg->msg.w.len)) {
+        /* non-blocking write did not write everything: mark the pcb non-writable
+           and let poll_tcp check writable space to mark the pcb writable again */
+        API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
+        conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE;
+      } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) ||
+                 (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) {
+        /* The queued byte- or pbuf-count exceeds the configured low-water limit,
+           let select mark this pcb as non-writable. */
+        API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
+      }
+    }
+
+    if (err == ERR_OK) {
+      conn->write_offset += len;
+      if ((conn->write_offset == conn->current_msg->msg.w.len) || dontblock) {
+        /* return sent length */
+        conn->current_msg->msg.w.len = conn->write_offset;
+        /* everything was written */
+        write_finished = 1;
+        conn->write_offset = 0;
+      }
+      tcp_output(conn->pcb.tcp);
+    } else if ((err == ERR_MEM) && !dontblock) {
+      /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called
+         we do NOT return to the application thread, since ERR_MEM is
+         only a temporary error! */
+
+      /* tcp_write returned ERR_MEM, try tcp_output anyway */
+      tcp_output(conn->pcb.tcp);
+
+#if LWIP_TCPIP_CORE_LOCKING
+      conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
+#endif
+    } else {
+      /* On errors != ERR_MEM, we don't try writing any more but return
+         the error to the application thread. */
+      write_finished = 1;
+      conn->current_msg->msg.w.len = 0;
+    }
+  }
+  if (write_finished) {
+    /* everything was written: set back connection state
+       and back to application task */
+    conn->current_msg->err = err;
+    conn->current_msg = NULL;
+    conn->state = NETCONN_NONE;
+#if LWIP_TCPIP_CORE_LOCKING
+    if ((conn->flags & NETCONN_FLAG_WRITE_DELAYED) != 0)
+#endif
+    {
+      sys_sem_signal(&conn->op_completed);
+    }
+  }
+#if LWIP_TCPIP_CORE_LOCKING
+  else
+    return ERR_MEM;
+#endif
+  return ERR_OK;
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Send some data on a TCP pcb contained in a netconn
+ * Called from netconn_write
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_write(struct api_msg_msg *msg)
+{
+  if (ERR_IS_FATAL(msg->conn->last_err)) {
+    msg->err = msg->conn->last_err;
+  } else {
+    if (msg->conn->type == NETCONN_TCP) {
+#if LWIP_TCP
+      if (msg->conn->state != NETCONN_NONE) {
+        /* netconn is connecting, closing or in blocking write */
+        msg->err = ERR_INPROGRESS;
+      } else if (msg->conn->pcb.tcp != NULL) {
+        msg->conn->state = NETCONN_WRITE;
+        /* set all the variables used by do_writemore */
+        LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
+          msg->conn->write_offset == 0);
+        LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0);
+        msg->conn->current_msg = msg;
+        msg->conn->write_offset = 0;
+#if LWIP_TCPIP_CORE_LOCKING
+        msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED;
+        if (do_writemore(msg->conn) != ERR_OK) {
+          LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE);
+          UNLOCK_TCPIP_CORE();
+          sys_arch_sem_wait(&msg->conn->op_completed, 0);
+          LOCK_TCPIP_CORE();
+          LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
+        }
+#else /* LWIP_TCPIP_CORE_LOCKING */
+        do_writemore(msg->conn);
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+        /* for both cases: if do_writemore was called, don't ACK the APIMSG
+           since do_writemore ACKs it! */
+        return;
+      } else {
+        msg->err = ERR_CONN;
+      }
+#else /* LWIP_TCP */
+      msg->err = ERR_VAL;
+#endif /* LWIP_TCP */
+#if (LWIP_UDP || LWIP_RAW)
+    } else {
+      msg->err = ERR_VAL;
+#endif /* (LWIP_UDP || LWIP_RAW) */
+    }
+  }
+  TCPIP_APIMSG_ACK(msg);
+}
+
+/**
+ * Return a connection's local or remote address
+ * Called from netconn_getaddr
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_getaddr(struct api_msg_msg *msg)
+{
+  if (msg->conn->pcb.ip != NULL) {
+    *(msg->msg.ad.ipaddr) = (msg->msg.ad.local ? msg->conn->pcb.ip->local_ip :
+                             msg->conn->pcb.ip->remote_ip);
+
+    msg->err = ERR_OK;
+    switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+    case NETCONN_RAW:
+      if (msg->msg.ad.local) {
+        *(msg->msg.ad.port) = msg->conn->pcb.raw->protocol;
+      } else {
+        /* return an error as connecting is only a helper for upper layers */
+        msg->err = ERR_CONN;
+      }
+      break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+    case NETCONN_UDP:
+      if (msg->msg.ad.local) {
+        *(msg->msg.ad.port) = msg->conn->pcb.udp->local_port;
+      } else {
+        if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) {
+          msg->err = ERR_CONN;
+        } else {
+          *(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port;
+        }
+      }
+      break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+    case NETCONN_TCP:
+      *(msg->msg.ad.port) = (msg->msg.ad.local?msg->conn->pcb.tcp->local_port:msg->conn->pcb.tcp->remote_port);
+      break;
+#endif /* LWIP_TCP */
+    default:
+      LWIP_ASSERT("invalid netconn_type", 0);
+      break;
+    }
+  } else {
+    msg->err = ERR_CONN;
+  }
+  TCPIP_APIMSG_ACK(msg);
+}
+
+/**
+ * Close a TCP pcb contained in a netconn
+ * Called from netconn_close
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_close(struct api_msg_msg *msg)
+{
+#if LWIP_TCP
+  /* @todo: abort running write/connect? */
+  if ((msg->conn->state != NETCONN_NONE) && (msg->conn->state != NETCONN_LISTEN)) {
+    /* this only happens for TCP netconns */
+    LWIP_ASSERT("msg->conn->type == NETCONN_TCP", msg->conn->type == NETCONN_TCP);
+    msg->err = ERR_INPROGRESS;
+  } else if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
+    if ((msg->msg.sd.shut != NETCONN_SHUT_RDWR) && (msg->conn->state == NETCONN_LISTEN)) {
+      /* LISTEN doesn't support half shutdown */
+      msg->err = ERR_CONN;
+    } else {
+      if (msg->msg.sd.shut & NETCONN_SHUT_RD) {
+        /* Drain and delete mboxes */
+        netconn_drain(msg->conn);
+      }
+      LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
+        msg->conn->write_offset == 0);
+      msg->conn->state = NETCONN_CLOSE;
+      msg->conn->current_msg = msg;
+      do_close_internal(msg->conn);
+      /* for tcp netconns, do_close_internal ACKs the message */
+      return;
+    }
+  } else
+#endif /* LWIP_TCP */
+  {
+    msg->err = ERR_VAL;
+  }
+  sys_sem_signal(&msg->conn->op_completed);
+}
+
+#if LWIP_IGMP
+/**
+ * Join multicast groups for UDP netconns.
+ * Called from netconn_join_leave_group
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_join_leave_group(struct api_msg_msg *msg)
+{ 
+  if (ERR_IS_FATAL(msg->conn->last_err)) {
+    msg->err = msg->conn->last_err;
+  } else {
+    if (msg->conn->pcb.tcp != NULL) {
+      if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
+#if LWIP_UDP
+        if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
+          msg->err = igmp_joingroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr);
+        } else {
+          msg->err = igmp_leavegroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr);
+        }
+#endif /* LWIP_UDP */
+#if (LWIP_TCP || LWIP_RAW)
+      } else {
+        msg->err = ERR_VAL;
+#endif /* (LWIP_TCP || LWIP_RAW) */
+      }
+    } else {
+      msg->err = ERR_CONN;
+    }
+  }
+  TCPIP_APIMSG_ACK(msg);
+}
+#endif /* LWIP_IGMP */
+
+#if LWIP_DNS
+/**
+ * Callback function that is called when DNS name is resolved
+ * (or on timeout). A waiting application thread is waked up by
+ * signaling the semaphore.
+ */
+static void
+do_dns_found(const char *name, ip_addr_t *ipaddr, void *arg)
+{
+  struct dns_api_msg *msg = (struct dns_api_msg*)arg;
+
+  LWIP_ASSERT("DNS response for wrong host name", strcmp(msg->name, name) == 0);
+  LWIP_UNUSED_ARG(name);
+
+  if (ipaddr == NULL) {
+    /* timeout or memory error */
+    *msg->err = ERR_VAL;
+  } else {
+    /* address was resolved */
+    *msg->err = ERR_OK;
+    *msg->addr = *ipaddr;
+  }
+  /* wake up the application task waiting in netconn_gethostbyname */
+  sys_sem_signal(msg->sem);
+}
+
+/**
+ * Execute a DNS query
+ * Called from netconn_gethostbyname
+ *
+ * @param arg the dns_api_msg pointing to the query
+ */
+void
+do_gethostbyname(void *arg)
+{
+  struct dns_api_msg *msg = (struct dns_api_msg*)arg;
+
+  *msg->err = dns_gethostbyname(msg->name, msg->addr, do_dns_found, msg);
+  if (*msg->err != ERR_INPROGRESS) {
+    /* on error or immediate success, wake up the application
+     * task waiting in netconn_gethostbyname */
+    sys_sem_signal(msg->sem);
+  }
+}
+#endif /* LWIP_DNS */
+
+#endif /* LWIP_NETCONN */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/api/err.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/api/err.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/api/err.c	(revision 164)
@@ -0,0 +1,75 @@
+/**
+ * @file
+ * Error Management module
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/err.h"
+
+#ifdef LWIP_DEBUG
+
+static const char *err_strerr[] = {
+           "Ok.",                    /* ERR_OK          0  */
+           "Out of memory error.",   /* ERR_MEM        -1  */
+           "Buffer error.",          /* ERR_BUF        -2  */
+           "Timeout.",               /* ERR_TIMEOUT    -3  */
+           "Routing problem.",       /* ERR_RTE        -4  */
+           "Operation in progress.", /* ERR_INPROGRESS -5  */
+           "Illegal value.",         /* ERR_VAL        -6  */
+           "Operation would block.", /* ERR_WOULDBLOCK -7  */
+           "Address in use.",        /* ERR_USE        -8  */
+           "Already connected.",     /* ERR_ISCONN     -9  */
+           "Connection aborted.",    /* ERR_ABRT       -10 */
+           "Connection reset.",      /* ERR_RST        -11 */
+           "Connection closed.",     /* ERR_CLSD       -12 */
+           "Not connected.",         /* ERR_CONN       -13 */
+           "Illegal argument.",      /* ERR_ARG        -14 */
+           "Low-level netif error.", /* ERR_IF         -15 */
+};
+
+/**
+ * Convert an lwip internal error to a string representation.
+ *
+ * @param err an lwip internal err_t
+ * @return a string representation for err
+ */
+const char *
+lwip_strerr(err_t err)
+{
+  return err_strerr[-err];
+
+}
+
+#endif /* LWIP_DEBUG */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/api/netbuf.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/api/netbuf.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/api/netbuf.c	(revision 164)
@@ -0,0 +1,245 @@
+/**
+ * @file
+ * Network buffer management
+ *
+ */
+ 
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/netbuf.h"
+#include "lwip/memp.h"
+
+#include <string.h>
+
+/**
+ * Create (allocate) and initialize a new netbuf.
+ * The netbuf doesn't yet contain a packet buffer!
+ *
+ * @return a pointer to a new netbuf
+ *         NULL on lack of memory
+ */
+struct
+netbuf *netbuf_new(void)
+{
+  struct netbuf *buf;
+
+  buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
+  if (buf != NULL) {
+    buf->p = NULL;
+    buf->ptr = NULL;
+    ip_addr_set_any(&buf->addr);
+    buf->port = 0;
+#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY
+#if LWIP_CHECKSUM_ON_COPY
+    buf->flags = 0;
+#endif /* LWIP_CHECKSUM_ON_COPY */
+    buf->toport_chksum = 0;
+#if LWIP_NETBUF_RECVINFO
+    ip_addr_set_any(&buf->toaddr);
+#endif /* LWIP_NETBUF_RECVINFO */
+#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */
+    return buf;
+  } else {
+    return NULL;
+  }
+}
+
+/**
+ * Deallocate a netbuf allocated by netbuf_new().
+ *
+ * @param buf pointer to a netbuf allocated by netbuf_new()
+ */
+void
+netbuf_delete(struct netbuf *buf)
+{
+  if (buf != NULL) {
+    if (buf->p != NULL) {
+      pbuf_free(buf->p);
+      buf->p = buf->ptr = NULL;
+    }
+    memp_free(MEMP_NETBUF, buf);
+  }
+}
+
+/**
+ * Allocate memory for a packet buffer for a given netbuf.
+ *
+ * @param buf the netbuf for which to allocate a packet buffer
+ * @param size the size of the packet buffer to allocate
+ * @return pointer to the allocated memory
+ *         NULL if no memory could be allocated
+ */
+void *
+netbuf_alloc(struct netbuf *buf, u16_t size)
+{
+  LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;);
+
+  /* Deallocate any previously allocated memory. */
+  if (buf->p != NULL) {
+    pbuf_free(buf->p);
+  }
+  buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
+  if (buf->p == NULL) {
+     return NULL;
+  }
+  LWIP_ASSERT("check that first pbuf can hold size",
+             (buf->p->len >= size));
+  buf->ptr = buf->p;
+  return buf->p->payload;
+}
+
+/**
+ * Free the packet buffer included in a netbuf
+ *
+ * @param buf pointer to the netbuf which contains the packet buffer to free
+ */
+void
+netbuf_free(struct netbuf *buf)
+{
+  LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;);
+  if (buf->p != NULL) {
+    pbuf_free(buf->p);
+  }
+  buf->p = buf->ptr = NULL;
+}
+
+/**
+ * Let a netbuf reference existing (non-volatile) data.
+ *
+ * @param buf netbuf which should reference the data
+ * @param dataptr pointer to the data to reference
+ * @param size size of the data
+ * @return ERR_OK if data is referenced
+ *         ERR_MEM if data couldn't be referenced due to lack of memory
+ */
+err_t
+netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size)
+{
+  LWIP_ERROR("netbuf_ref: invalid buf", (buf != NULL), return ERR_ARG;);
+  if (buf->p != NULL) {
+    pbuf_free(buf->p);
+  }
+  buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);
+  if (buf->p == NULL) {
+    buf->ptr = NULL;
+    return ERR_MEM;
+  }
+  buf->p->payload = (void*)dataptr;
+  buf->p->len = buf->p->tot_len = size;
+  buf->ptr = buf->p;
+  return ERR_OK;
+}
+
+/**
+ * Chain one netbuf to another (@see pbuf_chain)
+ *
+ * @param head the first netbuf
+ * @param tail netbuf to chain after head, freed by this function, may not be reference after returning
+ */
+void
+netbuf_chain(struct netbuf *head, struct netbuf *tail)
+{
+  LWIP_ERROR("netbuf_ref: invalid head", (head != NULL), return;);
+  LWIP_ERROR("netbuf_chain: invalid tail", (tail != NULL), return;);
+  pbuf_cat(head->p, tail->p);
+  head->ptr = head->p;
+  memp_free(MEMP_NETBUF, tail);
+}
+
+/**
+ * Get the data pointer and length of the data inside a netbuf.
+ *
+ * @param buf netbuf to get the data from
+ * @param dataptr pointer to a void pointer where to store the data pointer
+ * @param len pointer to an u16_t where the length of the data is stored
+ * @return ERR_OK if the information was retreived,
+ *         ERR_BUF on error.
+ */
+err_t
+netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len)
+{
+  LWIP_ERROR("netbuf_data: invalid buf", (buf != NULL), return ERR_ARG;);
+  LWIP_ERROR("netbuf_data: invalid dataptr", (dataptr != NULL), return ERR_ARG;);
+  LWIP_ERROR("netbuf_data: invalid len", (len != NULL), return ERR_ARG;);
+
+  if (buf->ptr == NULL) {
+    return ERR_BUF;
+  }
+  *dataptr = buf->ptr->payload;
+  *len = buf->ptr->len;
+  return ERR_OK;
+}
+
+/**
+ * Move the current data pointer of a packet buffer contained in a netbuf
+ * to the next part.
+ * The packet buffer itself is not modified.
+ *
+ * @param buf the netbuf to modify
+ * @return -1 if there is no next part
+ *         1  if moved to the next part but now there is no next part
+ *         0  if moved to the next part and there are still more parts
+ */
+s8_t
+netbuf_next(struct netbuf *buf)
+{
+  LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return -1;);
+  if (buf->ptr->next == NULL) {
+    return -1;
+  }
+  buf->ptr = buf->ptr->next;
+  if (buf->ptr->next == NULL) {
+    return 1;
+  }
+  return 0;
+}
+
+/**
+ * Move the current data pointer of a packet buffer contained in a netbuf
+ * to the beginning of the packet.
+ * The packet buffer itself is not modified.
+ *
+ * @param buf the netbuf to modify
+ */
+void
+netbuf_first(struct netbuf *buf)
+{
+  LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;);
+  buf->ptr = buf->p;
+}
+
+#endif /* LWIP_NETCONN */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/api/netdb.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/api/netdb.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/api/netdb.c	(revision 164)
@@ -0,0 +1,353 @@
+/**
+ * @file
+ * API functions for name resolving
+ *
+ */
+
+/*
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt
+ *
+ */
+
+#include "lwip/netdb.h"
+
+#if LWIP_DNS && LWIP_SOCKET
+
+#include "lwip/err.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/ip_addr.h"
+#include "lwip/api.h"
+#include "lwip/dns.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+/** helper struct for gethostbyname_r to access the char* buffer */
+struct gethostbyname_r_helper {
+  ip_addr_t *addr_list[2];
+  ip_addr_t addr;
+  char *aliases;
+};
+
+/** h_errno is exported in netdb.h for access by applications. */
+#if LWIP_DNS_API_DECLARE_H_ERRNO
+int h_errno;
+#endif /* LWIP_DNS_API_DECLARE_H_ERRNO */
+
+/** define "hostent" variables storage: 0 if we use a static (but unprotected)
+ * set of variables for lwip_gethostbyname, 1 if we use a local storage */
+#ifndef LWIP_DNS_API_HOSTENT_STORAGE
+#define LWIP_DNS_API_HOSTENT_STORAGE 0
+#endif
+
+/** define "hostent" variables storage */
+#if LWIP_DNS_API_HOSTENT_STORAGE
+#define HOSTENT_STORAGE
+#else
+#define HOSTENT_STORAGE static
+#endif /* LWIP_DNS_API_STATIC_HOSTENT */
+
+/**
+ * Returns an entry containing addresses of address family AF_INET
+ * for the host with name name.
+ * Due to dns_gethostbyname limitations, only one address is returned.
+ *
+ * @param name the hostname to resolve
+ * @return an entry containing addresses of address family AF_INET
+ *         for the host with name name
+ */
+struct hostent*
+lwip_gethostbyname(const char *name)
+{
+  err_t err;
+  ip_addr_t addr;
+
+  /* buffer variables for lwip_gethostbyname() */
+  HOSTENT_STORAGE struct hostent s_hostent;
+  HOSTENT_STORAGE char *s_aliases;
+  HOSTENT_STORAGE ip_addr_t s_hostent_addr;
+  HOSTENT_STORAGE ip_addr_t *s_phostent_addr[2];
+
+  /* query host IP address */
+  err = netconn_gethostbyname(name, &addr);
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
+    h_errno = HOST_NOT_FOUND;
+    return NULL;
+  }
+
+  /* fill hostent */
+  s_hostent_addr = addr;
+  s_phostent_addr[0] = &s_hostent_addr;
+  s_phostent_addr[1] = NULL;
+  s_hostent.h_name = (char*)name;
+  s_hostent.h_aliases = &s_aliases;
+  s_hostent.h_addrtype = AF_INET;
+  s_hostent.h_length = sizeof(ip_addr_t);
+  s_hostent.h_addr_list = (char**)&s_phostent_addr;
+
+#if DNS_DEBUG
+  /* dump hostent */
+  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name           == %s\n", s_hostent.h_name));
+  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases        == %p\n", s_hostent.h_aliases));
+  if (s_hostent.h_aliases != NULL) {
+    u8_t idx;
+    for ( idx=0; s_hostent.h_aliases[idx]; idx++) {
+      LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]->   == %p\n", idx, s_hostent.h_aliases[idx]));
+      LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]->   == %s\n", idx, s_hostent.h_aliases[idx]));
+    }
+  }
+  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype       == %d\n", s_hostent.h_addrtype));
+  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length         == %d\n", s_hostent.h_length));
+  LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list      == %p\n", s_hostent.h_addr_list));
+  if (s_hostent.h_addr_list != NULL) {
+    u8_t idx;
+    for ( idx=0; s_hostent.h_addr_list[idx]; idx++) {
+      LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]   == %p\n", idx, s_hostent.h_addr_list[idx]));
+      LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ip_ntoa((ip_addr_t*)s_hostent.h_addr_list[idx])));
+    }
+  }
+#endif /* DNS_DEBUG */
+
+#if LWIP_DNS_API_HOSTENT_STORAGE
+  /* this function should return the "per-thread" hostent after copy from s_hostent */
+  return sys_thread_hostent(&s_hostent);
+#else
+  return &s_hostent;
+#endif /* LWIP_DNS_API_HOSTENT_STORAGE */
+}
+
+/**
+ * Thread-safe variant of lwip_gethostbyname: instead of using a static
+ * buffer, this function takes buffer and errno pointers as arguments
+ * and uses these for the result.
+ *
+ * @param name the hostname to resolve
+ * @param ret pre-allocated struct where to store the result
+ * @param buf pre-allocated buffer where to store additional data
+ * @param buflen the size of buf
+ * @param result pointer to a hostent pointer that is set to ret on success
+ *               and set to zero on error
+ * @param h_errnop pointer to an int where to store errors (instead of modifying
+ *                 the global h_errno)
+ * @return 0 on success, non-zero on error, additional error information
+ *         is stored in *h_errnop instead of h_errno to be thread-safe
+ */
+int
+lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
+                size_t buflen, struct hostent **result, int *h_errnop)
+{
+  err_t err;
+  struct gethostbyname_r_helper *h;
+  char *hostname;
+  size_t namelen;
+  int lh_errno;
+
+  if (h_errnop == NULL) {
+    /* ensure h_errnop is never NULL */
+    h_errnop = &lh_errno;
+  }
+
+  if (result == NULL) {
+    /* not all arguments given */
+    *h_errnop = EINVAL;
+    return -1;
+  }
+  /* first thing to do: set *result to nothing */
+  *result = NULL;
+  if ((name == NULL) || (ret == NULL) || (buf == NULL)) {
+    /* not all arguments given */
+    *h_errnop = EINVAL;
+    return -1;
+  }
+
+  namelen = strlen(name);
+  if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) {
+    /* buf can't hold the data needed + a copy of name */
+    *h_errnop = ERANGE;
+    return -1;
+  }
+
+  h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf);
+  hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper);
+
+  /* query host IP address */
+  err = netconn_gethostbyname(name, &h->addr);
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
+    *h_errnop = HOST_NOT_FOUND;
+    return -1;
+  }
+
+  /* copy the hostname into buf */
+  MEMCPY(hostname, name, namelen);
+  hostname[namelen] = 0;
+
+  /* fill hostent */
+  h->addr_list[0] = &h->addr;
+  h->addr_list[1] = NULL;
+  h->aliases = NULL;
+  ret->h_name = hostname;
+  ret->h_aliases = &h->aliases;
+  ret->h_addrtype = AF_INET;
+  ret->h_length = sizeof(ip_addr_t);
+  ret->h_addr_list = (char**)&h->addr_list;
+
+  /* set result != NULL */
+  *result = ret;
+
+  /* return success */
+  return 0;
+}
+
+/**
+ * Frees one or more addrinfo structures returned by getaddrinfo(), along with
+ * any additional storage associated with those structures. If the ai_next field
+ * of the structure is not null, the entire list of structures is freed.
+ *
+ * @param ai struct addrinfo to free
+ */
+void
+lwip_freeaddrinfo(struct addrinfo *ai)
+{
+  struct addrinfo *next;
+
+  while (ai != NULL) {
+    next = ai->ai_next;
+    memp_free(MEMP_NETDB, ai);
+    ai = next;
+  }
+}
+
+/**
+ * Translates the name of a service location (for example, a host name) and/or
+ * a service name and returns a set of socket addresses and associated
+ * information to be used in creating a socket with which to address the
+ * specified service.
+ * Memory for the result is allocated internally and must be freed by calling
+ * lwip_freeaddrinfo()!
+ *
+ * Due to a limitation in dns_gethostbyname, only the first address of a
+ * host is returned.
+ * Also, service names are not supported (only port numbers)!
+ *
+ * @param nodename descriptive name or address string of the host
+ *                 (may be NULL -> local address)
+ * @param servname port number as string of NULL 
+ * @param hints structure containing input values that set socktype and protocol
+ * @param res pointer to a pointer where to store the result (set to NULL on failure)
+ * @return 0 on success, non-zero on failure
+ */
+int
+lwip_getaddrinfo(const char *nodename, const char *servname,
+       const struct addrinfo *hints, struct addrinfo **res)
+{
+  err_t err;
+  ip_addr_t addr;
+  struct addrinfo *ai;
+  struct sockaddr_in *sa = NULL;
+  int port_nr = 0;
+  size_t total_size;
+  size_t namelen = 0;
+
+  if (res == NULL) {
+    return EAI_FAIL;
+  }
+  *res = NULL;
+  if ((nodename == NULL) && (servname == NULL)) {
+    return EAI_NONAME;
+  }
+
+  if (servname != NULL) {
+    /* service name specified: convert to port number
+     * @todo?: currently, only ASCII integers (port numbers) are supported! */
+    port_nr = atoi(servname);
+    if ((port_nr <= 0) || (port_nr > 0xffff)) {
+      return EAI_SERVICE;
+    }
+  }
+
+  if (nodename != NULL) {
+    /* service location specified, try to resolve */
+    err = netconn_gethostbyname(nodename, &addr);
+    if (err != ERR_OK) {
+      return EAI_FAIL;
+    }
+  } else {
+    /* service location specified, use loopback address */
+    ip_addr_set_loopback(&addr);
+  }
+
+  total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_in);
+  if (nodename != NULL) {
+    namelen = strlen(nodename);
+    LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1);
+    total_size += namelen + 1;
+  }
+  /* If this fails, please report to lwip-devel! :-) */
+  LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!",
+    total_size <= NETDB_ELEM_SIZE);
+  ai = (struct addrinfo *)memp_malloc(MEMP_NETDB);
+  if (ai == NULL) {
+    goto memerr;
+  }
+  memset(ai, 0, total_size);
+  sa = (struct sockaddr_in*)((u8_t*)ai + sizeof(struct addrinfo));
+  /* set up sockaddr */
+  inet_addr_from_ipaddr(&sa->sin_addr, &addr);
+  sa->sin_family = AF_INET;
+  sa->sin_len = sizeof(struct sockaddr_in);
+  sa->sin_port = htons((u16_t)port_nr);
+
+  /* set up addrinfo */
+  ai->ai_family = AF_INET;
+  if (hints != NULL) {
+    /* copy socktype & protocol from hints if specified */
+    ai->ai_socktype = hints->ai_socktype;
+    ai->ai_protocol = hints->ai_protocol;
+  }
+  if (nodename != NULL) {
+    /* copy nodename to canonname if specified */
+    ai->ai_canonname = ((char*)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
+    MEMCPY(ai->ai_canonname, nodename, namelen);
+    ai->ai_canonname[namelen] = 0;
+  }
+  ai->ai_addrlen = sizeof(struct sockaddr_in);
+  ai->ai_addr = (struct sockaddr*)sa;
+
+  *res = ai;
+
+  return 0;
+memerr:
+  if (ai != NULL) {
+    memp_free(MEMP_NETDB, ai);
+  }
+  return EAI_MEMORY;
+}
+
+#endif /* LWIP_DNS && LWIP_SOCKET */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/api/netifapi.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/api/netifapi.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/api/netifapi.c	(revision 164)
@@ -0,0 +1,160 @@
+/**
+ * @file
+ * Network Interface Sequential API module
+ *
+ */
+
+/*
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/netifapi.h"
+#include "lwip/tcpip.h"
+
+/**
+ * Call netif_add() inside the tcpip_thread context.
+ */
+void
+do_netifapi_netif_add(struct netifapi_msg_msg *msg)
+{
+  if (!netif_add( msg->netif,
+                  msg->msg.add.ipaddr,
+                  msg->msg.add.netmask,
+                  msg->msg.add.gw,
+                  msg->msg.add.state,
+                  msg->msg.add.init,
+                  msg->msg.add.input)) {
+    msg->err = ERR_IF;
+  } else {
+    msg->err = ERR_OK;
+  }
+  TCPIP_NETIFAPI_ACK(msg);
+}
+
+/**
+ * Call netif_set_addr() inside the tcpip_thread context.
+ */
+void
+do_netifapi_netif_set_addr(struct netifapi_msg_msg *msg)
+{
+  netif_set_addr( msg->netif,
+                  msg->msg.add.ipaddr,
+                  msg->msg.add.netmask,
+                  msg->msg.add.gw);
+  msg->err = ERR_OK;
+  TCPIP_NETIFAPI_ACK(msg);
+}
+
+/**
+ * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the
+ * tcpip_thread context.
+ */
+void
+do_netifapi_netif_common(struct netifapi_msg_msg *msg)
+{
+  if (msg->msg.common.errtfunc != NULL) {
+    msg->err = msg->msg.common.errtfunc(msg->netif);
+  } else {
+    msg->err = ERR_OK;
+    msg->msg.common.voidfunc(msg->netif);
+  }
+  TCPIP_NETIFAPI_ACK(msg);
+}
+
+/**
+ * Call netif_add() in a thread-safe way by running that function inside the
+ * tcpip_thread context.
+ *
+ * @note for params @see netif_add()
+ */
+err_t
+netifapi_netif_add(struct netif *netif,
+                   ip_addr_t *ipaddr,
+                   ip_addr_t *netmask,
+                   ip_addr_t *gw,
+                   void *state,
+                   netif_init_fn init,
+                   netif_input_fn input)
+{
+  struct netifapi_msg msg;
+  msg.function = do_netifapi_netif_add;
+  msg.msg.netif = netif;
+  msg.msg.msg.add.ipaddr  = ipaddr;
+  msg.msg.msg.add.netmask = netmask;
+  msg.msg.msg.add.gw      = gw;
+  msg.msg.msg.add.state   = state;
+  msg.msg.msg.add.init    = init;
+  msg.msg.msg.add.input   = input;
+  TCPIP_NETIFAPI(&msg);
+  return msg.msg.err;
+}
+
+/**
+ * Call netif_set_addr() in a thread-safe way by running that function inside the
+ * tcpip_thread context.
+ *
+ * @note for params @see netif_set_addr()
+ */
+err_t
+netifapi_netif_set_addr(struct netif *netif,
+                        ip_addr_t *ipaddr,
+                        ip_addr_t *netmask,
+                        ip_addr_t *gw)
+{
+  struct netifapi_msg msg;
+  msg.function = do_netifapi_netif_set_addr;
+  msg.msg.netif = netif;
+  msg.msg.msg.add.ipaddr  = ipaddr;
+  msg.msg.msg.add.netmask = netmask;
+  msg.msg.msg.add.gw      = gw;
+  TCPIP_NETIFAPI(&msg);
+  return msg.msg.err;
+}
+
+/**
+ * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe
+ * way by running that function inside the tcpip_thread context.
+ *
+ * @note use only for functions where there is only "netif" parameter.
+ */
+err_t
+netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
+                       netifapi_errt_fn errtfunc)
+{
+  struct netifapi_msg msg;
+  msg.function = do_netifapi_netif_common;
+  msg.msg.netif = netif;
+  msg.msg.msg.common.voidfunc = voidfunc;
+  msg.msg.msg.common.errtfunc = errtfunc;
+  TCPIP_NETIFAPI(&msg);
+  return msg.msg.err;
+}
+
+#endif /* LWIP_NETIF_API */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/api/sockets.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/api/sockets.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/api/sockets.c	(revision 164)
@@ -0,0 +1,2374 @@
+/**
+ * @file
+ * Sockets BSD-Like API module
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * Improved by Marc Boucher <marc@mbsi.ca> and David Haas <dhaas@alum.rpi.edu>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/sockets.h"
+#include "lwip/api.h"
+#include "lwip/sys.h"
+#include "lwip/igmp.h"
+#include "lwip/inet.h"
+#include "lwip/tcp.h"
+#include "lwip/raw.h"
+#include "lwip/udp.h"
+#include "lwip/tcpip.h"
+#include "lwip/pbuf.h"
+#if LWIP_CHECKSUM_ON_COPY
+#include "lwip/inet_chksum.h"
+#endif
+
+#include <string.h>
+
+#define NUM_SOCKETS MEMP_NUM_NETCONN
+
+/** Contains all internal pointers and states used for a socket */
+struct lwip_sock {
+  /** sockets currently are built on netconns, each socket has one netconn */
+  struct netconn *conn;
+  /** data that was left from the previous read */
+  void *lastdata;
+  /** offset in the data that was left from the previous read */
+  u16_t lastoffset;
+  /** number of times data was received, set by event_callback(),
+      tested by the receive and select functions */
+  s16_t rcvevent;
+  /** number of times data was ACKed (free send buffer), set by event_callback(),
+      tested by select */
+  u16_t sendevent;
+  /** error happened for this socket, set by event_callback(), tested by select */
+  u16_t errevent; 
+  /** last error that occurred on this socket */
+  int err;
+  /** counter of how many threads are waiting for this socket using select */
+  int select_waiting;
+};
+
+/** Description for a task waiting in select */
+struct lwip_select_cb {
+  /** Pointer to the next waiting task */
+  struct lwip_select_cb *next;
+  /** Pointer to the previous waiting task */
+  struct lwip_select_cb *prev;
+  /** readset passed to select */
+  fd_set *readset;
+  /** writeset passed to select */
+  fd_set *writeset;
+  /** unimplemented: exceptset passed to select */
+  fd_set *exceptset;
+  /** don't signal the same semaphore twice: set to 1 when signalled */
+  int sem_signalled;
+  /** semaphore to wake up a task waiting for select */
+  sys_sem_t sem;
+};
+
+/** This struct is used to pass data to the set/getsockopt_internal
+ * functions running in tcpip_thread context (only a void* is allowed) */
+struct lwip_setgetsockopt_data {
+  /** socket struct for which to change options */
+  struct lwip_sock *sock;
+#ifdef LWIP_DEBUG
+  /** socket index for which to change options */
+  int s;
+#endif /* LWIP_DEBUG */
+  /** level of the option to process */
+  int level;
+  /** name of the option to process */
+  int optname;
+  /** set: value to set the option to
+    * get: value of the option is stored here */
+  void *optval;
+  /** size of *optval */
+  socklen_t *optlen;
+  /** if an error occures, it is temporarily stored here */
+  err_t err;
+};
+
+/** The global array of available sockets */
+static struct lwip_sock sockets[NUM_SOCKETS];
+/** The global list of tasks waiting for select */
+static struct lwip_select_cb *select_cb_list;
+/** This counter is increased from lwip_select when the list is chagned
+    and checked in event_callback to see if it has changed. */
+static volatile int select_cb_ctr;
+
+/** Table to quickly map an lwIP error (err_t) to a socket error
+  * by using -err as an index */
+static const int err_to_errno_table[] = {
+  0,             /* ERR_OK          0      No error, everything OK. */
+  ENOMEM,        /* ERR_MEM        -1      Out of memory error.     */
+  ENOBUFS,       /* ERR_BUF        -2      Buffer error.            */
+  EWOULDBLOCK,   /* ERR_TIMEOUT    -3      Timeout                  */
+  EHOSTUNREACH,  /* ERR_RTE        -4      Routing problem.         */
+  EINPROGRESS,   /* ERR_INPROGRESS -5      Operation in progress    */
+  EINVAL,        /* ERR_VAL        -6      Illegal value.           */
+  EWOULDBLOCK,   /* ERR_WOULDBLOCK -7      Operation would block.   */
+  EADDRINUSE,    /* ERR_USE        -8      Address in use.          */
+  EALREADY,      /* ERR_ISCONN     -9      Already connected.       */
+  ECONNABORTED,  /* ERR_ABRT       -10     Connection aborted.      */
+  ECONNRESET,    /* ERR_RST        -11     Connection reset.        */
+  ENOTCONN,      /* ERR_CLSD       -12     Connection closed.       */
+  ENOTCONN,      /* ERR_CONN       -13     Not connected.           */
+  EIO,           /* ERR_ARG        -14     Illegal argument.        */
+  -1,            /* ERR_IF         -15     Low-level netif error    */
+};
+
+#define ERR_TO_ERRNO_TABLE_SIZE \
+  (sizeof(err_to_errno_table)/sizeof(err_to_errno_table[0]))
+
+#define err_to_errno(err) \
+  ((unsigned)(-(err)) < ERR_TO_ERRNO_TABLE_SIZE ? \
+    err_to_errno_table[-(err)] : EIO)
+
+#ifdef ERRNO
+#ifndef set_errno
+#define set_errno(err) errno = (err)
+#endif
+#else /* ERRNO */
+#define set_errno(err)
+#endif /* ERRNO */
+
+#define sock_set_errno(sk, e) do { \
+  sk->err = (e); \
+  set_errno(sk->err); \
+} while (0)
+
+/* Forward delcaration of some functions */
+static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);
+static void lwip_getsockopt_internal(void *arg);
+static void lwip_setsockopt_internal(void *arg);
+
+/**
+ * Initialize this module. This function has to be called before any other
+ * functions in this module!
+ */
+void
+lwip_socket_init(void)
+{
+}
+
+/**
+ * Map a externally used socket index to the internal socket representation.
+ *
+ * @param s externally used socket index
+ * @return struct lwip_sock for the socket or NULL if not found
+ */
+static struct lwip_sock *
+get_socket(int s)
+{
+  struct lwip_sock *sock;
+
+  if ((s < 0) || (s >= NUM_SOCKETS)) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s));
+    set_errno(EBADF);
+    return NULL;
+  }
+
+  sock = &sockets[s];
+
+  if (!sock->conn) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s));
+    set_errno(EBADF);
+    return NULL;
+  }
+
+  return sock;
+}
+
+/**
+ * Same as get_socket but doesn't set errno
+ *
+ * @param s externally used socket index
+ * @return struct lwip_sock for the socket or NULL if not found
+ */
+static struct lwip_sock *
+tryget_socket(int s)
+{
+  if ((s < 0) || (s >= NUM_SOCKETS)) {
+    return NULL;
+  }
+  if (!sockets[s].conn) {
+    return NULL;
+  }
+  return &sockets[s];
+}
+
+/**
+ * Allocate a new socket for a given netconn.
+ *
+ * @param newconn the netconn for which to allocate a socket
+ * @param accepted 1 if socket has been created by accept(),
+ *                 0 if socket has been created by socket()
+ * @return the index of the new socket; -1 on error
+ */
+static int
+alloc_socket(struct netconn *newconn, int accepted)
+{
+  int i;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  /* allocate a new socket identifier */
+  for (i = 0; i < NUM_SOCKETS; ++i) {
+    /* Protect socket array */
+    SYS_ARCH_PROTECT(lev);
+    if (!sockets[i].conn) {
+      sockets[i].conn       = newconn;
+      /* The socket is not yet known to anyone, so no need to protect
+         after having marked it as used. */
+      SYS_ARCH_UNPROTECT(lev);
+      sockets[i].lastdata   = NULL;
+      sockets[i].lastoffset = 0;
+      sockets[i].rcvevent   = 0;
+      /* TCP sendbuf is empty, but the socket is not yet writable until connected
+       * (unless it has been created by accept()). */
+      sockets[i].sendevent  = (newconn->type == NETCONN_TCP ? (accepted != 0) : 1);
+      sockets[i].errevent   = 0;
+      sockets[i].err        = 0;
+      sockets[i].select_waiting = 0;
+      return i;
+    }
+    SYS_ARCH_UNPROTECT(lev);
+  }
+  return -1;
+}
+
+/** Free a socket. The socket's netconn must have been
+ * delete before!
+ *
+ * @param sock the socket to free
+ * @param is_tcp != 0 for TCP sockets, used to free lastdata
+ */
+static void
+free_socket(struct lwip_sock *sock, int is_tcp)
+{
+  void *lastdata;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  lastdata         = sock->lastdata;
+  sock->lastdata   = NULL;
+  sock->lastoffset = 0;
+  sock->err        = 0;
+
+  /* Protect socket array */
+  SYS_ARCH_PROTECT(lev);
+  sock->conn       = NULL;
+  SYS_ARCH_UNPROTECT(lev);
+  /* don't use 'sock' after this line, as another task might have allocated it */
+
+  if (lastdata != NULL) {
+    if (is_tcp) {
+      pbuf_free((struct pbuf *)lastdata);
+    } else {
+      netbuf_delete((struct netbuf *)lastdata);
+    }
+  }
+}
+
+/* Below this, the well-known socket functions are implemented.
+ * Use google.com or opengroup.org to get a good description :-)
+ *
+ * Exceptions are documented!
+ */
+
+int
+lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
+{
+  struct lwip_sock *sock, *nsock;
+  struct netconn *newconn;
+  ip_addr_t naddr;
+  u16_t port;
+  int newsock;
+  struct sockaddr_in sin;
+  err_t err;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s));
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  if (netconn_is_nonblocking(sock->conn) && (sock->rcvevent <= 0)) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): returning EWOULDBLOCK\n", s));
+    sock_set_errno(sock, EWOULDBLOCK);
+    return -1;
+  }
+
+  /* wait for a new connection */
+  err = netconn_accept(sock->conn, &newconn);
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err));
+    if (netconn_type(sock->conn) != NETCONN_TCP) {
+      sock_set_errno(sock, EOPNOTSUPP);
+      return EOPNOTSUPP;
+    }
+    sock_set_errno(sock, err_to_errno(err));
+    return -1;
+  }
+  LWIP_ASSERT("newconn != NULL", newconn != NULL);
+  /* Prevent automatic window updates, we do this on our own! */
+  netconn_set_noautorecved(newconn, 1);
+
+  /* get the IP address and port of the remote host */
+  err = netconn_peer(newconn, &naddr, &port);
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err));
+    netconn_delete(newconn);
+    sock_set_errno(sock, err_to_errno(err));
+    return -1;
+  }
+
+  /* Note that POSIX only requires us to check addr is non-NULL. addrlen must
+   * not be NULL if addr is valid.
+   */
+  if (NULL != addr) {
+    LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL);
+    memset(&sin, 0, sizeof(sin));
+    sin.sin_len = sizeof(sin);
+    sin.sin_family = AF_INET;
+    sin.sin_port = htons(port);
+    inet_addr_from_ipaddr(&sin.sin_addr, &naddr);
+
+    if (*addrlen > sizeof(sin))
+      *addrlen = sizeof(sin);
+
+    MEMCPY(addr, &sin, *addrlen);
+  }
+
+  newsock = alloc_socket(newconn, 1);
+  if (newsock == -1) {
+    netconn_delete(newconn);
+    sock_set_errno(sock, ENFILE);
+    return -1;
+  }
+  LWIP_ASSERT("invalid socket index", (newsock >= 0) && (newsock < NUM_SOCKETS));
+  LWIP_ASSERT("newconn->callback == event_callback", newconn->callback == event_callback);
+  nsock = &sockets[newsock];
+
+  /* See event_callback: If data comes in right away after an accept, even
+   * though the server task might not have created a new socket yet.
+   * In that case, newconn->socket is counted down (newconn->socket--),
+   * so nsock->rcvevent is >= 1 here!
+   */
+  SYS_ARCH_PROTECT(lev);
+  nsock->rcvevent += (s16_t)(-1 - newconn->socket);
+  newconn->socket = newsock;
+  SYS_ARCH_UNPROTECT(lev);
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock));
+  ip_addr_debug_print(SOCKETS_DEBUG, &naddr);
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port));
+
+  sock_set_errno(sock, 0);
+  return newsock;
+}
+
+int
+lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)
+{
+  struct lwip_sock *sock;
+  ip_addr_t local_addr;
+  u16_t local_port;
+  err_t err;
+  const struct sockaddr_in *name_in;
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  /* check size, familiy and alignment of 'name' */
+  LWIP_ERROR("lwip_bind: invalid address", ((namelen == sizeof(struct sockaddr_in)) &&
+             ((name->sa_family) == AF_INET) && ((((mem_ptr_t)name) % 4) == 0)),
+             sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
+  name_in = (const struct sockaddr_in *)(void*)name;
+
+  inet_addr_to_ipaddr(&local_addr, &name_in->sin_addr);
+  local_port = name_in->sin_port;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s));
+  ip_addr_debug_print(SOCKETS_DEBUG, &local_addr);
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(local_port)));
+
+  err = netconn_bind(sock->conn, &local_addr, ntohs(local_port));
+
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err));
+    sock_set_errno(sock, err_to_errno(err));
+    return -1;
+  }
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s));
+  sock_set_errno(sock, 0);
+  return 0;
+}
+
+int
+lwip_close(int s)
+{
+  struct lwip_sock *sock;
+  int is_tcp = 0;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s));
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  if(sock->conn != NULL) {
+    is_tcp = netconn_type(sock->conn) == NETCONN_TCP;
+  } else {
+    LWIP_ASSERT("sock->lastdata == NULL", sock->lastdata == NULL);
+  }
+
+  netconn_delete(sock->conn);
+
+  free_socket(sock, is_tcp);
+  set_errno(0);
+  return 0;
+}
+
+int
+lwip_connect(int s, const struct sockaddr *name, socklen_t namelen)
+{
+  struct lwip_sock *sock;
+  err_t err;
+  const struct sockaddr_in *name_in;
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  /* check size, familiy and alignment of 'name' */
+  LWIP_ERROR("lwip_connect: invalid address", ((namelen == sizeof(struct sockaddr_in)) &&
+             ((name->sa_family) == AF_INET) && ((((mem_ptr_t)name) % 4) == 0)),
+             sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
+  name_in = (const struct sockaddr_in *)(void*)name;
+
+  if (name_in->sin_family == AF_UNSPEC) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s));
+    err = netconn_disconnect(sock->conn);
+  } else {
+    ip_addr_t remote_addr;
+    u16_t remote_port;
+
+    inet_addr_to_ipaddr(&remote_addr, &name_in->sin_addr);
+    remote_port = name_in->sin_port;
+
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s));
+    ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);
+    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(remote_port)));
+
+    err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
+  }
+
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err));
+    sock_set_errno(sock, err_to_errno(err));
+    return -1;
+  }
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s));
+  sock_set_errno(sock, 0);
+  return 0;
+}
+
+/**
+ * Set a socket into listen mode.
+ * The socket may not have been used for another connection previously.
+ *
+ * @param s the socket to set to listening mode
+ * @param backlog (ATTENTION: needs TCP_LISTEN_BACKLOG=1)
+ * @return 0 on success, non-zero on failure
+ */
+int
+lwip_listen(int s, int backlog)
+{
+  struct lwip_sock *sock;
+  err_t err;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog));
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  /* limit the "backlog" parameter to fit in an u8_t */
+  backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff);
+
+  err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog);
+
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err));
+    if (netconn_type(sock->conn) != NETCONN_TCP) {
+      sock_set_errno(sock, EOPNOTSUPP);
+      return EOPNOTSUPP;
+    }
+    sock_set_errno(sock, err_to_errno(err));
+    return -1;
+  }
+
+  sock_set_errno(sock, 0);
+  return 0;
+}
+
+int
+lwip_recvfrom(int s, void *mem, size_t len, int flags,
+        struct sockaddr *from, socklen_t *fromlen)
+{
+  struct lwip_sock *sock;
+  void             *buf = NULL;
+  struct pbuf      *p;
+  u16_t            buflen, copylen;
+  int              off = 0;
+  ip_addr_t        *addr;
+  u16_t            port;
+  u8_t             done = 0;
+  err_t            err;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags));
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  do {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: top while sock->lastdata=%p\n", sock->lastdata));
+    /* Check if there is data left from the last recv operation. */
+    if (sock->lastdata) {
+      buf = sock->lastdata;
+    } else {
+      /* If this is non-blocking call, then check first */
+      if (((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) && 
+          (sock->rcvevent <= 0)) {
+        if (off > 0) {
+          /* update receive window */
+          netconn_recved(sock->conn, (u32_t)off);
+          /* already received data, return that */
+          sock_set_errno(sock, 0);
+          return off;
+        }
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s));
+        sock_set_errno(sock, EWOULDBLOCK);
+        return -1;
+      }
+
+      /* No data was left from the previous operation, so we try to get
+         some from the network. */
+      if (netconn_type(sock->conn) == NETCONN_TCP) {
+        err = netconn_recv_tcp_pbuf(sock->conn, (struct pbuf **)&buf);
+      } else {
+        err = netconn_recv(sock->conn, (struct netbuf **)&buf);
+      }
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: netconn_recv err=%d, netbuf=%p\n",
+        err, buf));
+
+      if (err != ERR_OK) {
+        if (off > 0) {
+          /* update receive window */
+          netconn_recved(sock->conn, (u32_t)off);
+          /* already received data, return that */
+          sock_set_errno(sock, 0);
+          return off;
+        }
+        /* We should really do some error checking here. */
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL, error is \"%s\"!\n",
+          s, lwip_strerr(err)));
+        sock_set_errno(sock, err_to_errno(err));
+        if (err == ERR_CLSD) {
+          return 0;
+        } else {
+          return -1;
+        }
+      }
+      LWIP_ASSERT("buf != NULL", buf != NULL);
+      sock->lastdata = buf;
+    }
+
+    if (netconn_type(sock->conn) == NETCONN_TCP) {
+      p = (struct pbuf *)buf;
+    } else {
+      p = ((struct netbuf *)buf)->p;
+    }
+    buflen = p->tot_len;
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: buflen=%"U16_F" len=%"SZT_F" off=%d sock->lastoffset=%"U16_F"\n",
+      buflen, len, off, sock->lastoffset));
+
+    buflen -= sock->lastoffset;
+
+    if (len > buflen) {
+      copylen = buflen;
+    } else {
+      copylen = (u16_t)len;
+    }
+
+    /* copy the contents of the received buffer into
+    the supplied memory pointer mem */
+    pbuf_copy_partial(p, (u8_t*)mem + off, copylen, sock->lastoffset);
+
+    off += copylen;
+
+    if (netconn_type(sock->conn) == NETCONN_TCP) {
+      LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen);
+      len -= copylen;
+      if ( (len <= 0) || 
+           (p->flags & PBUF_FLAG_PUSH) || 
+           (sock->rcvevent <= 0) || 
+           ((flags & MSG_PEEK)!=0)) {
+        done = 1;
+      }
+    } else {
+      done = 1;
+    }
+
+    /* Check to see from where the data was.*/
+    if (done) {
+      ip_addr_t fromaddr;
+      if (from && fromlen) {
+        struct sockaddr_in sin;
+
+        if (netconn_type(sock->conn) == NETCONN_TCP) {
+          addr = &fromaddr;
+          netconn_getaddr(sock->conn, addr, &port, 0);
+        } else {
+          addr = netbuf_fromaddr((struct netbuf *)buf);
+          port = netbuf_fromport((struct netbuf *)buf);
+        }
+
+        memset(&sin, 0, sizeof(sin));
+        sin.sin_len = sizeof(sin);
+        sin.sin_family = AF_INET;
+        sin.sin_port = htons(port);
+        inet_addr_from_ipaddr(&sin.sin_addr, addr);
+
+        if (*fromlen > sizeof(sin)) {
+          *fromlen = sizeof(sin);
+        }
+
+        MEMCPY(from, &sin, *fromlen);
+
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
+        ip_addr_debug_print(SOCKETS_DEBUG, addr);
+        LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off));
+      } else {
+#if SOCKETS_DEBUG
+        if (netconn_type(sock->conn) == NETCONN_TCP) {
+          addr = &fromaddr;
+          netconn_getaddr(sock->conn, addr, &port, 0);
+        } else {
+          addr = netbuf_fromaddr((struct netbuf *)buf);
+          port = netbuf_fromport((struct netbuf *)buf);
+        }
+
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
+        ip_addr_debug_print(SOCKETS_DEBUG, addr);
+        LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off));
+#endif /*  SOCKETS_DEBUG */
+      }
+    }
+
+    /* If we don't peek the incoming message... */
+    if ((flags & MSG_PEEK) == 0) {
+      /* If this is a TCP socket, check if there is data left in the
+         buffer. If so, it should be saved in the sock structure for next
+         time around. */
+      if ((netconn_type(sock->conn) == NETCONN_TCP) && (buflen - copylen > 0)) {
+        sock->lastdata = buf;
+        sock->lastoffset += copylen;
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: lastdata now netbuf=%p\n", buf));
+      } else {
+        sock->lastdata = NULL;
+        sock->lastoffset = 0;
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", buf));
+        if (netconn_type(sock->conn) == NETCONN_TCP) {
+          pbuf_free((struct pbuf *)buf);
+        } else {
+          netbuf_delete((struct netbuf *)buf);
+        }
+      }
+    }
+  } while (!done);
+
+  if (off > 0) {
+    /* update receive window */
+    netconn_recved(sock->conn, (u32_t)off);
+  }
+  sock_set_errno(sock, 0);
+  return off;
+}
+
+int
+lwip_read(int s, void *mem, size_t len)
+{
+  return lwip_recvfrom(s, mem, len, 0, NULL, NULL);
+}
+
+int
+lwip_recv(int s, void *mem, size_t len, int flags)
+{
+  return lwip_recvfrom(s, mem, len, flags, NULL, NULL);
+}
+
+int
+lwip_send(int s, const void *data, size_t size, int flags)
+{
+  struct lwip_sock *sock;
+  err_t err;
+  u8_t write_flags;
+  size_t written;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n",
+                              s, data, size, flags));
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  if (sock->conn->type != NETCONN_TCP) {
+#if (LWIP_UDP || LWIP_RAW)
+    return lwip_sendto(s, data, size, flags, NULL, 0);
+#else /* (LWIP_UDP || LWIP_RAW) */
+    sock_set_errno(sock, err_to_errno(ERR_ARG));
+    return -1;
+#endif /* (LWIP_UDP || LWIP_RAW) */
+  }
+
+  write_flags = NETCONN_COPY |
+    ((flags & MSG_MORE)     ? NETCONN_MORE      : 0) |
+    ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0);
+  written = 0;
+  err = netconn_write_partly(sock->conn, data, size, write_flags, &written);
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d written=%"SZT_F"\n", s, err, written));
+  sock_set_errno(sock, err_to_errno(err));
+  return (err == ERR_OK ? (int)written : -1);
+}
+
+int
+lwip_sendto(int s, const void *data, size_t size, int flags,
+       const struct sockaddr *to, socklen_t tolen)
+{
+  struct lwip_sock *sock;
+  err_t err;
+  u16_t short_size;
+  const struct sockaddr_in *to_in;
+  u16_t remote_port;
+#if !LWIP_TCPIP_CORE_LOCKING
+  struct netbuf buf;
+#endif
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  if (sock->conn->type == NETCONN_TCP) {
+#if LWIP_TCP
+    return lwip_send(s, data, size, flags);
+#else /* LWIP_TCP */
+    LWIP_UNUSED_ARG(flags);
+    sock_set_errno(sock, err_to_errno(ERR_ARG));
+    return -1;
+#endif /* LWIP_TCP */
+  }
+
+  /* @todo: split into multiple sendto's? */
+  LWIP_ASSERT("lwip_sendto: size must fit in u16_t", size <= 0xffff);
+  short_size = (u16_t)size;
+  LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) ||
+             ((tolen == sizeof(struct sockaddr_in)) &&
+             ((to->sa_family) == AF_INET) && ((((mem_ptr_t)to) % 4) == 0))),
+             sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
+  to_in = (const struct sockaddr_in *)(void*)to;
+
+#if LWIP_TCPIP_CORE_LOCKING
+  /* Should only be consider like a sample or a simple way to experiment this option (no check of "to" field...) */
+  {
+    struct pbuf* p;
+    ip_addr_t *remote_addr;
+
+#if LWIP_NETIF_TX_SINGLE_PBUF
+    p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_RAM);
+    if (p != NULL) {
+#if LWIP_CHECKSUM_ON_COPY
+      u16_t chksum = 0;
+      if (sock->conn->type != NETCONN_RAW) {
+        chksum = LWIP_CHKSUM_COPY(p->payload, data, short_size);
+      } else
+#endif /* LWIP_CHECKSUM_ON_COPY */
+      MEMCPY(p->payload, data, size);
+#else /* LWIP_NETIF_TX_SINGLE_PBUF */
+    p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_REF);
+    if (p != NULL) {
+      p->payload = (void*)data;
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
+
+      if (to_in != NULL) {
+        inet_addr_to_ipaddr_p(remote_addr, &to_in->sin_addr);
+        remote_port = ntohs(to_in->sin_port);
+      } else {
+        remote_addr = &sock->conn->pcb.ip->remote_ip;
+#if LWIP_UDP
+        if (NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_UDP) {
+          remote_port = sock->conn->pcb.udp->remote_port;
+        } else
+#endif /* LWIP_UDP */
+        {
+          remote_port = 0;
+        }
+      }
+
+      LOCK_TCPIP_CORE();
+      if (netconn_type(sock->conn) == NETCONN_RAW) {
+#if LWIP_RAW
+        err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, remote_addr);
+#else /* LWIP_RAW */
+        err = ERR_ARG;
+#endif /* LWIP_RAW */
+      }
+#if LWIP_UDP && LWIP_RAW
+      else
+#endif /* LWIP_UDP && LWIP_RAW */
+      {
+#if LWIP_UDP
+#if LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF
+        err = sock->conn->last_err = udp_sendto_chksum(sock->conn->pcb.udp, p,
+          remote_addr, remote_port, 1, chksum);
+#else /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */
+        err = sock->conn->last_err = udp_sendto(sock->conn->pcb.udp, p,
+          remote_addr, remote_port);
+#endif /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */
+#else /* LWIP_UDP */
+        err = ERR_ARG;
+#endif /* LWIP_UDP */
+      }
+      UNLOCK_TCPIP_CORE();
+      
+      pbuf_free(p);
+    } else {
+      err = ERR_MEM;
+    }
+  }
+#else /* LWIP_TCPIP_CORE_LOCKING */
+  /* initialize a buffer */
+  buf.p = buf.ptr = NULL;
+#if LWIP_CHECKSUM_ON_COPY
+  buf.flags = 0;
+#endif /* LWIP_CHECKSUM_ON_COPY */
+  if (to) {
+    inet_addr_to_ipaddr(&buf.addr, &to_in->sin_addr);
+    remote_port           = ntohs(to_in->sin_port);
+    netbuf_fromport(&buf) = remote_port;
+  } else {
+    remote_port           = 0;
+    ip_addr_set_any(&buf.addr);
+    netbuf_fromport(&buf) = 0;
+  }
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=",
+              s, data, short_size, flags));
+  ip_addr_debug_print(SOCKETS_DEBUG, &buf.addr);
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port));
+
+  /* make the buffer point to the data that should be sent */
+#if LWIP_NETIF_TX_SINGLE_PBUF
+  /* Allocate a new netbuf and copy the data into it. */
+  if (netbuf_alloc(&buf, short_size) == NULL) {
+    err = ERR_MEM;
+  } else {
+#if LWIP_CHECKSUM_ON_COPY
+    if (sock->conn->type != NETCONN_RAW) {
+      u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size);
+      netbuf_set_chksum(&buf, chksum);
+      err = ERR_OK;
+    } else
+#endif /* LWIP_CHECKSUM_ON_COPY */
+    {
+      err = netbuf_take(&buf, data, short_size);
+    }
+  }
+#else /* LWIP_NETIF_TX_SINGLE_PBUF */
+  err = netbuf_ref(&buf, data, short_size);
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
+  if (err == ERR_OK) {
+    /* send the data */
+    err = netconn_send(sock->conn, &buf);
+  }
+
+  /* deallocated the buffer */
+  netbuf_free(&buf);
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+  sock_set_errno(sock, err_to_errno(err));
+  return (err == ERR_OK ? short_size : -1);
+}
+
+int
+lwip_socket(int domain, int type, int protocol)
+{
+  struct netconn *conn;
+  int i;
+
+  LWIP_UNUSED_ARG(domain);
+
+  /* create a netconn */
+  switch (type) {
+  case SOCK_RAW:
+    conn = netconn_new_with_proto_and_callback(NETCONN_RAW, (u8_t)protocol, event_callback);
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ",
+                                 domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
+    break;
+  case SOCK_DGRAM:
+    conn = netconn_new_with_callback( (protocol == IPPROTO_UDPLITE) ?
+                 NETCONN_UDPLITE : NETCONN_UDP, event_callback);
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ",
+                                 domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
+    break;
+  case SOCK_STREAM:
+    conn = netconn_new_with_callback(NETCONN_TCP, event_callback);
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ",
+                                 domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
+    if (conn != NULL) {
+      /* Prevent automatic window updates, we do this on our own! */
+      netconn_set_noautorecved(conn, 1);
+    }
+    break;
+  default:
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n",
+                                 domain, type, protocol));
+    set_errno(EINVAL);
+    return -1;
+  }
+
+  if (!conn) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n"));
+    set_errno(ENOBUFS);
+    return -1;
+  }
+
+  i = alloc_socket(conn, 0);
+
+  if (i == -1) {
+    netconn_delete(conn);
+    set_errno(ENFILE);
+    return -1;
+  }
+  conn->socket = i;
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i));
+  set_errno(0);
+  return i;
+}
+
+int
+lwip_write(int s, const void *data, size_t size)
+{
+  return lwip_send(s, data, size, 0);
+}
+
+/**
+ * Go through the readset and writeset lists and see which socket of the sockets
+ * set in the sets has events. On return, readset, writeset and exceptset have
+ * the sockets enabled that had events.
+ *
+ * exceptset is not used for now!!!
+ *
+ * @param maxfdp1 the highest socket index in the sets
+ * @param readset_in:    set of sockets to check for read events
+ * @param writeset_in:   set of sockets to check for write events
+ * @param exceptset_in:  set of sockets to check for error events
+ * @param readset_out:   set of sockets that had read events
+ * @param writeset_out:  set of sockets that had write events
+ * @param exceptset_out: set os sockets that had error events
+ * @return number of sockets that had events (read/write/exception) (>= 0)
+ */
+static int
+lwip_selscan(int maxfdp1, fd_set *readset_in, fd_set *writeset_in, fd_set *exceptset_in,
+             fd_set *readset_out, fd_set *writeset_out, fd_set *exceptset_out)
+{
+  int i, nready = 0;
+  fd_set lreadset, lwriteset, lexceptset;
+  struct lwip_sock *sock;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  FD_ZERO(&lreadset);
+  FD_ZERO(&lwriteset);
+  FD_ZERO(&lexceptset);
+
+  /* Go through each socket in each list to count number of sockets which
+     currently match */
+  for(i = 0; i < maxfdp1; i++) {
+    void* lastdata = NULL;
+    s16_t rcvevent = 0;
+    u16_t sendevent = 0;
+    u16_t errevent = 0;
+    /* First get the socket's status (protected)... */
+    SYS_ARCH_PROTECT(lev);
+    sock = tryget_socket(i);
+    if (sock != NULL) {
+      lastdata = sock->lastdata;
+      rcvevent = sock->rcvevent;
+      sendevent = sock->sendevent;
+      errevent = sock->errevent;
+    }
+    SYS_ARCH_UNPROTECT(lev);
+    /* ... then examine it: */
+    /* See if netconn of this socket is ready for read */
+    if (readset_in && FD_ISSET(i, readset_in) && ((lastdata != NULL) || (rcvevent > 0))) {
+      FD_SET(i, &lreadset);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i));
+      nready++;
+    }
+    /* See if netconn of this socket is ready for write */
+    if (writeset_in && FD_ISSET(i, writeset_in) && (sendevent != 0)) {
+      FD_SET(i, &lwriteset);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i));
+      nready++;
+    }
+    /* See if netconn of this socket had an error */
+    if (exceptset_in && FD_ISSET(i, exceptset_in) && (errevent != 0)) {
+      FD_SET(i, &lexceptset);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for exception\n", i));
+      nready++;
+    }
+  }
+  /* copy local sets to the ones provided as arguments */
+  *readset_out = lreadset;
+  *writeset_out = lwriteset;
+  *exceptset_out = lexceptset;
+
+  LWIP_ASSERT("nready >= 0", nready >= 0);
+  return nready;
+}
+
+/**
+ * Processing exceptset is not yet implemented.
+ */
+int
+lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
+            struct timeval *timeout)
+{
+  u32_t waitres = 0;
+  int nready;
+  fd_set lreadset, lwriteset, lexceptset;
+  u32_t msectimeout;
+  struct lwip_select_cb select_cb;
+  err_t err;
+  int i;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n",
+                  maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset,
+                  timeout ? (s32_t)timeout->tv_sec : (s32_t)-1,
+                  timeout ? (s32_t)timeout->tv_usec : (s32_t)-1));
+
+  /* Go through each socket in each list to count number of sockets which
+     currently match */
+  nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
+
+  /* If we don't have any current events, then suspend if we are supposed to */
+  if (!nready) {
+    if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) {
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n"));
+      /* This is OK as the local fdsets are empty and nready is zero,
+         or we would have returned earlier. */
+      goto return_copy_fdsets;
+    }
+
+    /* None ready: add our semaphore to list:
+       We don't actually need any dynamic memory. Our entry on the
+       list is only valid while we are in this function, so it's ok
+       to use local variables. */
+
+    select_cb.next = NULL;
+    select_cb.prev = NULL;
+    select_cb.readset = readset;
+    select_cb.writeset = writeset;
+    select_cb.exceptset = exceptset;
+    select_cb.sem_signalled = 0;
+    err = sys_sem_new(&select_cb.sem, 0);
+    if (err != ERR_OK) {
+      /* failed to create semaphore */
+      set_errno(ENOMEM);
+      return -1;
+    }
+
+    /* Protect the select_cb_list */
+    SYS_ARCH_PROTECT(lev);
+
+    /* Put this select_cb on top of list */
+    select_cb.next = select_cb_list;
+    if (select_cb_list != NULL) {
+      select_cb_list->prev = &select_cb;
+    }
+    select_cb_list = &select_cb;
+    /* Increasing this counter tells even_callback that the list has changed. */
+    select_cb_ctr++;
+
+    /* Now we can safely unprotect */
+    SYS_ARCH_UNPROTECT(lev);
+
+    /* Increase select_waiting for each socket we are interested in */
+    for(i = 0; i < maxfdp1; i++) {
+      if ((readset && FD_ISSET(i, readset)) ||
+          (writeset && FD_ISSET(i, writeset)) ||
+          (exceptset && FD_ISSET(i, exceptset))) {
+        struct lwip_sock *sock = tryget_socket(i);
+        LWIP_ASSERT("sock != NULL", sock != NULL);
+        SYS_ARCH_PROTECT(lev);
+        sock->select_waiting++;
+        LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0);
+        SYS_ARCH_UNPROTECT(lev);
+      }
+    }
+
+    /* Call lwip_selscan again: there could have been events between
+       the last scan (whithout us on the list) and putting us on the list! */
+    nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
+    if (!nready) {
+      /* Still none ready, just wait to be woken */
+      if (timeout == 0) {
+        /* Wait forever */
+        msectimeout = 0;
+      } else {
+        msectimeout =  ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000));
+        if (msectimeout == 0) {
+          /* Wait 1ms at least (0 means wait forever) */
+          msectimeout = 1;
+        }
+      }
+
+      waitres = sys_arch_sem_wait(&select_cb.sem, msectimeout);
+    }
+    /* Increase select_waiting for each socket we are interested in */
+    for(i = 0; i < maxfdp1; i++) {
+      if ((readset && FD_ISSET(i, readset)) ||
+          (writeset && FD_ISSET(i, writeset)) ||
+          (exceptset && FD_ISSET(i, exceptset))) {
+        struct lwip_sock *sock = tryget_socket(i);
+        LWIP_ASSERT("sock != NULL", sock != NULL);
+        SYS_ARCH_PROTECT(lev);
+        sock->select_waiting--;
+        LWIP_ASSERT("sock->select_waiting >= 0", sock->select_waiting >= 0);
+        SYS_ARCH_UNPROTECT(lev);
+      }
+    }
+    /* Take us off the list */
+    SYS_ARCH_PROTECT(lev);
+    if (select_cb.next != NULL) {
+      select_cb.next->prev = select_cb.prev;
+    }
+    if (select_cb_list == &select_cb) {
+      LWIP_ASSERT("select_cb.prev == NULL", select_cb.prev == NULL);
+      select_cb_list = select_cb.next;
+    } else {
+      LWIP_ASSERT("select_cb.prev != NULL", select_cb.prev != NULL);
+      select_cb.prev->next = select_cb.next;
+    }
+    /* Increasing this counter tells even_callback that the list has changed. */
+    select_cb_ctr++;
+    SYS_ARCH_UNPROTECT(lev);
+
+    sys_sem_free(&select_cb.sem);
+    if (waitres == SYS_ARCH_TIMEOUT)  {
+      /* Timeout */
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));
+      /* This is OK as the local fdsets are empty and nready is zero,
+         or we would have returned earlier. */
+      goto return_copy_fdsets;
+    }
+
+    /* See what's set */
+    nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
+  }
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
+return_copy_fdsets:
+  set_errno(0);
+  if (readset) {
+    *readset = lreadset;
+  }
+  if (writeset) {
+    *writeset = lwriteset;
+  }
+  if (exceptset) {
+    *exceptset = lexceptset;
+  }
+
+
+  return nready;
+}
+
+/**
+ * Callback registered in the netconn layer for each socket-netconn.
+ * Processes recvevent (data available) and wakes up tasks waiting for select.
+ */
+static void
+event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
+{
+  int s;
+  struct lwip_sock *sock;
+  struct lwip_select_cb *scb;
+  int last_select_cb_ctr;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  LWIP_UNUSED_ARG(len);
+
+  /* Get socket */
+  if (conn) {
+    s = conn->socket;
+    if (s < 0) {
+      /* Data comes in right away after an accept, even though
+       * the server task might not have created a new socket yet.
+       * Just count down (or up) if that's the case and we
+       * will use the data later. Note that only receive events
+       * can happen before the new socket is set up. */
+      SYS_ARCH_PROTECT(lev);
+      if (conn->socket < 0) {
+        if (evt == NETCONN_EVT_RCVPLUS) {
+          conn->socket--;
+        }
+        SYS_ARCH_UNPROTECT(lev);
+        return;
+      }
+      s = conn->socket;
+      SYS_ARCH_UNPROTECT(lev);
+    }
+
+    sock = get_socket(s);
+    if (!sock) {
+      return;
+    }
+  } else {
+    return;
+  }
+
+  SYS_ARCH_PROTECT(lev);
+  /* Set event as required */
+  switch (evt) {
+    case NETCONN_EVT_RCVPLUS:
+      sock->rcvevent++;
+      break;
+    case NETCONN_EVT_RCVMINUS:
+      sock->rcvevent--;
+      break;
+    case NETCONN_EVT_SENDPLUS:
+      sock->sendevent = 1;
+      break;
+    case NETCONN_EVT_SENDMINUS:
+      sock->sendevent = 0;
+      break;
+    case NETCONN_EVT_ERROR:
+      sock->errevent = 1;
+      break;
+    default:
+      LWIP_ASSERT("unknown event", 0);
+      break;
+  }
+
+  if (sock->select_waiting == 0) {
+    /* noone is waiting for this socket, no need to check select_cb_list */
+    SYS_ARCH_UNPROTECT(lev);
+    return;
+  }
+
+  /* Now decide if anyone is waiting for this socket */
+  /* NOTE: This code goes through the select_cb_list list multiple times
+     ONLY IF a select was actually waiting. We go through the list the number
+     of waiting select calls + 1. This list is expected to be small. */
+
+  /* At this point, SYS_ARCH is still protected! */
+again:
+  for (scb = select_cb_list; scb != NULL; scb = scb->next) {
+    if (scb->sem_signalled == 0) {
+      /* semaphore not signalled yet */
+      int do_signal = 0;
+      /* Test this select call for our socket */
+      if (sock->rcvevent > 0) {
+        if (scb->readset && FD_ISSET(s, scb->readset)) {
+          do_signal = 1;
+        }
+      }
+      if (sock->sendevent != 0) {
+        if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) {
+          do_signal = 1;
+        }
+      }
+      if (sock->errevent != 0) {
+        if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) {
+          do_signal = 1;
+        }
+      }
+      if (do_signal) {
+        scb->sem_signalled = 1;
+        /* Don't call SYS_ARCH_UNPROTECT() before signaling the semaphore, as this might
+           lead to the select thread taking itself off the list, invalidagin the semaphore. */
+        sys_sem_signal(&scb->sem);
+      }
+    }
+    /* unlock interrupts with each step */
+    last_select_cb_ctr = select_cb_ctr;
+    SYS_ARCH_UNPROTECT(lev);
+    /* this makes sure interrupt protection time is short */
+    SYS_ARCH_PROTECT(lev);
+    if (last_select_cb_ctr != select_cb_ctr) {
+      /* someone has changed select_cb_list, restart at the beginning */
+      goto again;
+    }
+  }
+  SYS_ARCH_UNPROTECT(lev);
+}
+
+/**
+ * Unimplemented: Close one end of a full-duplex connection.
+ * Currently, the full connection is closed.
+ */
+int
+lwip_shutdown(int s, int how)
+{
+  struct lwip_sock *sock;
+  err_t err;
+  u8_t shut_rx = 0, shut_tx = 0;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how));
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  if (sock->conn != NULL) {
+    if (netconn_type(sock->conn) != NETCONN_TCP) {
+      sock_set_errno(sock, EOPNOTSUPP);
+      return EOPNOTSUPP;
+    }
+  } else {
+    sock_set_errno(sock, ENOTCONN);
+    return ENOTCONN;
+  }
+
+  if (how == SHUT_RD) {
+    shut_rx = 1;
+  } else if (how == SHUT_WR) {
+    shut_tx = 1;
+  } else if(how == SHUT_RDWR) {
+    shut_rx = 1;
+    shut_tx = 1;
+  } else {
+    sock_set_errno(sock, EINVAL);
+    return EINVAL;
+  }
+  err = netconn_shutdown(sock->conn, shut_rx, shut_tx);
+
+  sock_set_errno(sock, err_to_errno(err));
+  return (err == ERR_OK ? 0 : -1);
+}
+
+static int
+lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local)
+{
+  struct lwip_sock *sock;
+  struct sockaddr_in sin;
+  ip_addr_t naddr;
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  memset(&sin, 0, sizeof(sin));
+  sin.sin_len = sizeof(sin);
+  sin.sin_family = AF_INET;
+
+  /* get the IP address and port */
+  netconn_getaddr(sock->conn, &naddr, &sin.sin_port, local);
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s));
+  ip_addr_debug_print(SOCKETS_DEBUG, &naddr);
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", sin.sin_port));
+
+  sin.sin_port = htons(sin.sin_port);
+  inet_addr_from_ipaddr(&sin.sin_addr, &naddr);
+
+  if (*namelen > sizeof(sin)) {
+    *namelen = sizeof(sin);
+  }
+
+  MEMCPY(name, &sin, *namelen);
+  sock_set_errno(sock, 0);
+  return 0;
+}
+
+int
+lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen)
+{
+  return lwip_getaddrname(s, name, namelen, 0);
+}
+
+int
+lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen)
+{
+  return lwip_getaddrname(s, name, namelen, 1);
+}
+
+int
+lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
+{
+  err_t err = ERR_OK;
+  struct lwip_sock *sock = get_socket(s);
+  struct lwip_setgetsockopt_data data;
+
+  if (!sock) {
+    return -1;
+  }
+
+  if ((NULL == optval) || (NULL == optlen)) {
+    sock_set_errno(sock, EFAULT);
+    return -1;
+  }
+
+  /* Do length and type checks for the various options first, to keep it readable. */
+  switch (level) {
+   
+/* Level: SOL_SOCKET */
+  case SOL_SOCKET:
+    switch (optname) {
+       
+    case SO_ACCEPTCONN:
+    case SO_BROADCAST:
+    /* UNIMPL case SO_DEBUG: */
+    /* UNIMPL case SO_DONTROUTE: */
+    case SO_ERROR:
+    case SO_KEEPALIVE:
+    /* UNIMPL case SO_CONTIMEO: */
+#if LWIP_SO_SNDTIMEO
+    case SO_SNDTIMEO:
+#endif /* LWIP_SO_SNDTIMEO */
+#if LWIP_SO_RCVTIMEO
+    case SO_RCVTIMEO:
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+    case SO_RCVBUF:
+#endif /* LWIP_SO_RCVBUF */
+    /* UNIMPL case SO_OOBINLINE: */
+    /* UNIMPL case SO_SNDBUF: */
+    /* UNIMPL case SO_RCVLOWAT: */
+    /* UNIMPL case SO_SNDLOWAT: */
+#if SO_REUSE
+    case SO_REUSEADDR:
+    case SO_REUSEPORT:
+#endif /* SO_REUSE */
+    case SO_TYPE:
+    /* UNIMPL case SO_USELOOPBACK: */
+      if (*optlen < sizeof(int)) {
+        err = EINVAL;
+      }
+      break;
+
+    case SO_NO_CHECK:
+      if (*optlen < sizeof(int)) {
+        err = EINVAL;
+      }
+#if LWIP_UDP
+      if ((sock->conn->type != NETCONN_UDP) ||
+          ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) {
+        /* this flag is only available for UDP, not for UDP lite */
+        err = EAFNOSUPPORT;
+      }
+#endif /* LWIP_UDP */
+      break;
+
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n",
+                                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+                     
+/* Level: IPPROTO_IP */
+  case IPPROTO_IP:
+    switch (optname) {
+    /* UNIMPL case IP_HDRINCL: */
+    /* UNIMPL case IP_RCVDSTADDR: */
+    /* UNIMPL case IP_RCVIF: */
+    case IP_TTL:
+    case IP_TOS:
+      if (*optlen < sizeof(int)) {
+        err = EINVAL;
+      }
+      break;
+#if LWIP_IGMP
+    case IP_MULTICAST_TTL:
+      if (*optlen < sizeof(u8_t)) {
+        err = EINVAL;
+      }
+      break;
+    case IP_MULTICAST_IF:
+      if (*optlen < sizeof(struct in_addr)) {
+        err = EINVAL;
+      }
+      break;
+    case IP_MULTICAST_LOOP:
+      if (*optlen < sizeof(u8_t)) {
+        err = EINVAL;
+      }
+      if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
+        err = EAFNOSUPPORT;
+      }
+      break;
+#endif /* LWIP_IGMP */
+
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n",
+                                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+         
+#if LWIP_TCP
+/* Level: IPPROTO_TCP */
+  case IPPROTO_TCP:
+    if (*optlen < sizeof(int)) {
+      err = EINVAL;
+      break;
+    }
+    
+    /* If this is no TCP socket, ignore any options. */
+    if (sock->conn->type != NETCONN_TCP)
+      return 0;
+
+    switch (optname) {
+    case TCP_NODELAY:
+    case TCP_KEEPALIVE:
+#if LWIP_TCP_KEEPALIVE
+    case TCP_KEEPIDLE:
+    case TCP_KEEPINTVL:
+    case TCP_KEEPCNT:
+#endif /* LWIP_TCP_KEEPALIVE */
+      break;
+       
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
+                                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_TCP */
+#if LWIP_UDP && LWIP_UDPLITE
+/* Level: IPPROTO_UDPLITE */
+  case IPPROTO_UDPLITE:
+    if (*optlen < sizeof(int)) {
+      err = EINVAL;
+      break;
+    }
+    
+    /* If this is no UDP lite socket, ignore any options. */
+    if (sock->conn->type != NETCONN_UDPLITE) {
+      return 0;
+    }
+
+    switch (optname) {
+    case UDPLITE_SEND_CSCOV:
+    case UDPLITE_RECV_CSCOV:
+      break;
+       
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n",
+                                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_UDP && LWIP_UDPLITE*/
+/* UNDEFINED LEVEL */
+  default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n",
+                                  s, level, optname));
+      err = ENOPROTOOPT;
+  }  /* switch */
+
+   
+  if (err != ERR_OK) {
+    sock_set_errno(sock, err);
+    return -1;
+  }
+
+  /* Now do the actual option processing */
+  data.sock = sock;
+#ifdef LWIP_DEBUG
+  data.s = s;
+#endif /* LWIP_DEBUG */
+  data.level = level;
+  data.optname = optname;
+  data.optval = optval;
+  data.optlen = optlen;
+  data.err = err;
+  tcpip_callback(lwip_getsockopt_internal, &data);
+  sys_arch_sem_wait(&sock->conn->op_completed, 0);
+  /* maybe lwip_getsockopt_internal has changed err */
+  err = data.err;
+
+  sock_set_errno(sock, err);
+  return err ? -1 : 0;
+}
+
+static void
+lwip_getsockopt_internal(void *arg)
+{
+  struct lwip_sock *sock;
+#ifdef LWIP_DEBUG
+  int s;
+#endif /* LWIP_DEBUG */
+  int level, optname;
+  void *optval;
+  struct lwip_setgetsockopt_data *data;
+
+  LWIP_ASSERT("arg != NULL", arg != NULL);
+
+  data = (struct lwip_setgetsockopt_data*)arg;
+  sock = data->sock;
+#ifdef LWIP_DEBUG
+  s = data->s;
+#endif /* LWIP_DEBUG */
+  level = data->level;
+  optname = data->optname;
+  optval = data->optval;
+
+  switch (level) {
+
+/* Level: SOL_SOCKET */
+  case SOL_SOCKET:
+    switch (optname) {
+
+    /* The option flags */
+    case SO_ACCEPTCONN:
+    case SO_BROADCAST:
+    /* UNIMPL case SO_DEBUG: */
+    /* UNIMPL case SO_DONTROUTE: */
+    case SO_KEEPALIVE:
+    /* UNIMPL case SO_OOBINCLUDE: */
+#if SO_REUSE
+    case SO_REUSEADDR:
+    case SO_REUSEPORT:
+#endif /* SO_REUSE */
+    /*case SO_USELOOPBACK: UNIMPL */
+      *(int*)optval = ip_get_option(sock->conn->pcb.ip, optname);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n",
+                                  s, optname, (*(int*)optval?"on":"off")));
+      break;
+
+    case SO_TYPE:
+      switch (NETCONNTYPE_GROUP(sock->conn->type)) {
+      case NETCONN_RAW:
+        *(int*)optval = SOCK_RAW;
+        break;
+      case NETCONN_TCP:
+        *(int*)optval = SOCK_STREAM;
+        break;
+      case NETCONN_UDP:
+        *(int*)optval = SOCK_DGRAM;
+        break;
+      default: /* unrecognized socket type */
+        *(int*)optval = sock->conn->type;
+        LWIP_DEBUGF(SOCKETS_DEBUG,
+                    ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n",
+                    s, *(int *)optval));
+      }  /* switch (sock->conn->type) */
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n",
+                  s, *(int *)optval));
+      break;
+
+    case SO_ERROR:
+      /* only overwrite ERR_OK or tempoary errors */
+      if ((sock->err == 0) || (sock->err == EINPROGRESS)) {
+        sock_set_errno(sock, err_to_errno(sock->conn->last_err));
+      } 
+      *(int *)optval = sock->err;
+      sock->err = 0;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n",
+                  s, *(int *)optval));
+      break;
+
+#if LWIP_SO_SNDTIMEO
+    case SO_SNDTIMEO:
+      *(int *)optval = netconn_get_sendtimeout(sock->conn);
+      break;
+#endif /* LWIP_SO_SNDTIMEO */
+#if LWIP_SO_RCVTIMEO
+    case SO_RCVTIMEO:
+      *(int *)optval = netconn_get_recvtimeout(sock->conn);
+      break;
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+    case SO_RCVBUF:
+      *(int *)optval = netconn_get_recvbufsize(sock->conn);
+      break;
+#endif /* LWIP_SO_RCVBUF */
+#if LWIP_UDP
+    case SO_NO_CHECK:
+      *(int*)optval = (udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_NOCHKSUM) ? 1 : 0;
+      break;
+#endif /* LWIP_UDP*/
+    default:
+      LWIP_ASSERT("unhandled optname", 0);
+      break;
+    }  /* switch (optname) */
+    break;
+
+/* Level: IPPROTO_IP */
+  case IPPROTO_IP:
+    switch (optname) {
+    case IP_TTL:
+      *(int*)optval = sock->conn->pcb.ip->ttl;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n",
+                  s, *(int *)optval));
+      break;
+    case IP_TOS:
+      *(int*)optval = sock->conn->pcb.ip->tos;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n",
+                  s, *(int *)optval));
+      break;
+#if LWIP_IGMP
+    case IP_MULTICAST_TTL:
+      *(u8_t*)optval = sock->conn->pcb.ip->ttl;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n",
+                  s, *(int *)optval));
+      break;
+    case IP_MULTICAST_IF:
+      inet_addr_from_ipaddr((struct in_addr*)optval, &sock->conn->pcb.udp->multicast_ip);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n",
+                  s, *(u32_t *)optval));
+      break;
+    case IP_MULTICAST_LOOP:
+      if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) {
+        *(u8_t*)optval = 1;
+      } else {
+        *(u8_t*)optval = 0;
+      }
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n",
+                  s, *(int *)optval));
+      break;
+#endif /* LWIP_IGMP */
+    default:
+      LWIP_ASSERT("unhandled optname", 0);
+      break;
+    }  /* switch (optname) */
+    break;
+
+#if LWIP_TCP
+/* Level: IPPROTO_TCP */
+  case IPPROTO_TCP:
+    switch (optname) {
+    case TCP_NODELAY:
+      *(int*)optval = tcp_nagle_disabled(sock->conn->pcb.tcp);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n",
+                  s, (*(int*)optval)?"on":"off") );
+      break;
+    case TCP_KEEPALIVE:
+      *(int*)optval = (int)sock->conn->pcb.tcp->keep_idle;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n",
+                  s, *(int *)optval));
+      break;
+
+#if LWIP_TCP_KEEPALIVE
+    case TCP_KEEPIDLE:
+      *(int*)optval = (int)(sock->conn->pcb.tcp->keep_idle/1000);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPIDLE) = %d\n",
+                  s, *(int *)optval));
+      break;
+    case TCP_KEEPINTVL:
+      *(int*)optval = (int)(sock->conn->pcb.tcp->keep_intvl/1000);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPINTVL) = %d\n",
+                  s, *(int *)optval));
+      break;
+    case TCP_KEEPCNT:
+      *(int*)optval = (int)sock->conn->pcb.tcp->keep_cnt;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPCNT) = %d\n",
+                  s, *(int *)optval));
+      break;
+#endif /* LWIP_TCP_KEEPALIVE */
+    default:
+      LWIP_ASSERT("unhandled optname", 0);
+      break;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_TCP */
+#if LWIP_UDP && LWIP_UDPLITE
+  /* Level: IPPROTO_UDPLITE */
+  case IPPROTO_UDPLITE:
+    switch (optname) {
+    case UDPLITE_SEND_CSCOV:
+      *(int*)optval = sock->conn->pcb.udp->chksum_len_tx;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n",
+                  s, (*(int*)optval)) );
+      break;
+    case UDPLITE_RECV_CSCOV:
+      *(int*)optval = sock->conn->pcb.udp->chksum_len_rx;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n",
+                  s, (*(int*)optval)) );
+      break;
+    default:
+      LWIP_ASSERT("unhandled optname", 0);
+      break;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_UDP */
+  default:
+    LWIP_ASSERT("unhandled level", 0);
+    break;
+  } /* switch (level) */
+  sys_sem_signal(&sock->conn->op_completed);
+}
+
+int
+lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
+{
+  struct lwip_sock *sock = get_socket(s);
+  err_t err = ERR_OK;
+  struct lwip_setgetsockopt_data data;
+
+  if (!sock) {
+    return -1;
+  }
+
+  if (NULL == optval) {
+    sock_set_errno(sock, EFAULT);
+    return -1;
+  }
+
+  /* Do length and type checks for the various options first, to keep it readable. */
+  switch (level) {
+
+/* Level: SOL_SOCKET */
+  case SOL_SOCKET:
+    switch (optname) {
+
+    case SO_BROADCAST:
+    /* UNIMPL case SO_DEBUG: */
+    /* UNIMPL case SO_DONTROUTE: */
+    case SO_KEEPALIVE:
+    /* UNIMPL case case SO_CONTIMEO: */
+#if LWIP_SO_SNDTIMEO
+    case SO_SNDTIMEO:
+#endif /* LWIP_SO_SNDTIMEO */
+#if LWIP_SO_RCVTIMEO
+    case SO_RCVTIMEO:
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+    case SO_RCVBUF:
+#endif /* LWIP_SO_RCVBUF */
+    /* UNIMPL case SO_OOBINLINE: */
+    /* UNIMPL case SO_SNDBUF: */
+    /* UNIMPL case SO_RCVLOWAT: */
+    /* UNIMPL case SO_SNDLOWAT: */
+#if SO_REUSE
+    case SO_REUSEADDR:
+    case SO_REUSEPORT:
+#endif /* SO_REUSE */
+    /* UNIMPL case SO_USELOOPBACK: */
+      if (optlen < sizeof(int)) {
+        err = EINVAL;
+      }
+      break;
+    case SO_NO_CHECK:
+      if (optlen < sizeof(int)) {
+        err = EINVAL;
+      }
+#if LWIP_UDP
+      if ((sock->conn->type != NETCONN_UDP) ||
+          ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) {
+        /* this flag is only available for UDP, not for UDP lite */
+        err = EAFNOSUPPORT;
+      }
+#endif /* LWIP_UDP */
+      break;
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n",
+                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+
+/* Level: IPPROTO_IP */
+  case IPPROTO_IP:
+    switch (optname) {
+    /* UNIMPL case IP_HDRINCL: */
+    /* UNIMPL case IP_RCVDSTADDR: */
+    /* UNIMPL case IP_RCVIF: */
+    case IP_TTL:
+    case IP_TOS:
+      if (optlen < sizeof(int)) {
+        err = EINVAL;
+      }
+      break;
+#if LWIP_IGMP
+    case IP_MULTICAST_TTL:
+      if (optlen < sizeof(u8_t)) {
+        err = EINVAL;
+      }
+      if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
+        err = EAFNOSUPPORT;
+      }
+      break;
+    case IP_MULTICAST_IF:
+      if (optlen < sizeof(struct in_addr)) {
+        err = EINVAL;
+      }
+      if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
+        err = EAFNOSUPPORT;
+      }
+      break;
+    case IP_MULTICAST_LOOP:
+      if (optlen < sizeof(u8_t)) {
+        err = EINVAL;
+      }
+      if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
+        err = EAFNOSUPPORT;
+      }
+      break;
+    case IP_ADD_MEMBERSHIP:
+    case IP_DROP_MEMBERSHIP:
+      if (optlen < sizeof(struct ip_mreq)) {
+        err = EINVAL;
+      }
+      if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
+        err = EAFNOSUPPORT;
+      }
+      break;
+#endif /* LWIP_IGMP */
+      default:
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n",
+                    s, optname));
+        err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+
+#if LWIP_TCP
+/* Level: IPPROTO_TCP */
+  case IPPROTO_TCP:
+    if (optlen < sizeof(int)) {
+      err = EINVAL;
+      break;
+    }
+
+    /* If this is no TCP socket, ignore any options. */
+    if (sock->conn->type != NETCONN_TCP)
+      return 0;
+
+    switch (optname) {
+    case TCP_NODELAY:
+    case TCP_KEEPALIVE:
+#if LWIP_TCP_KEEPALIVE
+    case TCP_KEEPIDLE:
+    case TCP_KEEPINTVL:
+    case TCP_KEEPCNT:
+#endif /* LWIP_TCP_KEEPALIVE */
+      break;
+
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
+                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_TCP */
+#if LWIP_UDP && LWIP_UDPLITE
+/* Level: IPPROTO_UDPLITE */
+  case IPPROTO_UDPLITE:
+    if (optlen < sizeof(int)) {
+      err = EINVAL;
+      break;
+    }
+
+    /* If this is no UDP lite socket, ignore any options. */
+    if (sock->conn->type != NETCONN_UDPLITE)
+      return 0;
+
+    switch (optname) {
+    case UDPLITE_SEND_CSCOV:
+    case UDPLITE_RECV_CSCOV:
+      break;
+
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n",
+                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_UDP && LWIP_UDPLITE */
+/* UNDEFINED LEVEL */
+  default:
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n",
+                s, level, optname));
+    err = ENOPROTOOPT;
+  }  /* switch (level) */
+
+
+  if (err != ERR_OK) {
+    sock_set_errno(sock, err);
+    return -1;
+  }
+
+
+  /* Now do the actual option processing */
+  data.sock = sock;
+#ifdef LWIP_DEBUG
+  data.s = s;
+#endif /* LWIP_DEBUG */
+  data.level = level;
+  data.optname = optname;
+  data.optval = (void*)optval;
+  data.optlen = &optlen;
+  data.err = err;
+  tcpip_callback(lwip_setsockopt_internal, &data);
+  sys_arch_sem_wait(&sock->conn->op_completed, 0);
+  /* maybe lwip_setsockopt_internal has changed err */
+  err = data.err;
+
+  sock_set_errno(sock, err);
+  return err ? -1 : 0;
+}
+
+static void
+lwip_setsockopt_internal(void *arg)
+{
+  struct lwip_sock *sock;
+#ifdef LWIP_DEBUG
+  int s;
+#endif /* LWIP_DEBUG */
+  int level, optname;
+  const void *optval;
+  struct lwip_setgetsockopt_data *data;
+
+  LWIP_ASSERT("arg != NULL", arg != NULL);
+
+  data = (struct lwip_setgetsockopt_data*)arg;
+  sock = data->sock;
+#ifdef LWIP_DEBUG
+  s = data->s;
+#endif /* LWIP_DEBUG */
+  level = data->level;
+  optname = data->optname;
+  optval = data->optval;
+
+  switch (level) {
+
+/* Level: SOL_SOCKET */
+  case SOL_SOCKET:
+    switch (optname) {
+
+    /* The option flags */
+    case SO_BROADCAST:
+    /* UNIMPL case SO_DEBUG: */
+    /* UNIMPL case SO_DONTROUTE: */
+    case SO_KEEPALIVE:
+    /* UNIMPL case SO_OOBINCLUDE: */
+#if SO_REUSE
+    case SO_REUSEADDR:
+    case SO_REUSEPORT:
+#endif /* SO_REUSE */
+    /* UNIMPL case SO_USELOOPBACK: */
+      if (*(int*)optval) {
+        ip_set_option(sock->conn->pcb.ip, optname);
+      } else {
+        ip_reset_option(sock->conn->pcb.ip, optname);
+      }
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n",
+                  s, optname, (*(int*)optval?"on":"off")));
+      break;
+#if LWIP_SO_SNDTIMEO
+    case SO_SNDTIMEO:
+      netconn_set_sendtimeout(sock->conn, (s32_t)*(int*)optval);
+      break;
+#endif /* LWIP_SO_SNDTIMEO */
+#if LWIP_SO_RCVTIMEO
+    case SO_RCVTIMEO:
+      netconn_set_recvtimeout(sock->conn, *(int*)optval);
+      break;
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+    case SO_RCVBUF:
+      netconn_set_recvbufsize(sock->conn, *(int*)optval);
+      break;
+#endif /* LWIP_SO_RCVBUF */
+#if LWIP_UDP
+    case SO_NO_CHECK:
+      if (*(int*)optval) {
+        udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_NOCHKSUM);
+      } else {
+        udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_NOCHKSUM);
+      }
+      break;
+#endif /* LWIP_UDP */
+    default:
+      LWIP_ASSERT("unhandled optname", 0);
+      break;
+    }  /* switch (optname) */
+    break;
+
+/* Level: IPPROTO_IP */
+  case IPPROTO_IP:
+    switch (optname) {
+    case IP_TTL:
+      sock->conn->pcb.ip->ttl = (u8_t)(*(int*)optval);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n",
+                  s, sock->conn->pcb.ip->ttl));
+      break;
+    case IP_TOS:
+      sock->conn->pcb.ip->tos = (u8_t)(*(int*)optval);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n",
+                  s, sock->conn->pcb.ip->tos));
+      break;
+#if LWIP_IGMP
+    case IP_MULTICAST_TTL:
+      sock->conn->pcb.udp->ttl = (u8_t)(*(u8_t*)optval);
+      break;
+    case IP_MULTICAST_IF:
+      inet_addr_to_ipaddr(&sock->conn->pcb.udp->multicast_ip, (struct in_addr*)optval);
+      break;
+    case IP_MULTICAST_LOOP:
+      if (*(u8_t*)optval) {
+        udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP);
+      } else {
+        udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP);
+      }
+      break;
+    case IP_ADD_MEMBERSHIP:
+    case IP_DROP_MEMBERSHIP:
+      {
+        /* If this is a TCP or a RAW socket, ignore these options. */
+        struct ip_mreq *imr = (struct ip_mreq *)optval;
+        ip_addr_t if_addr;
+        ip_addr_t multi_addr;
+        inet_addr_to_ipaddr(&if_addr, &imr->imr_interface);
+        inet_addr_to_ipaddr(&multi_addr, &imr->imr_multiaddr);
+        if(optname == IP_ADD_MEMBERSHIP){
+          data->err = igmp_joingroup(&if_addr, &multi_addr);
+        } else {
+          data->err = igmp_leavegroup(&if_addr, &multi_addr);
+        }
+        if(data->err != ERR_OK) {
+          data->err = EADDRNOTAVAIL;
+        }
+      }
+      break;
+#endif /* LWIP_IGMP */
+    default:
+      LWIP_ASSERT("unhandled optname", 0);
+      break;
+    }  /* switch (optname) */
+    break;
+
+#if LWIP_TCP
+/* Level: IPPROTO_TCP */
+  case IPPROTO_TCP:
+    switch (optname) {
+    case TCP_NODELAY:
+      if (*(int*)optval) {
+        tcp_nagle_disable(sock->conn->pcb.tcp);
+      } else {
+        tcp_nagle_enable(sock->conn->pcb.tcp);
+      }
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n",
+                  s, (*(int *)optval)?"on":"off") );
+      break;
+    case TCP_KEEPALIVE:
+      sock->conn->pcb.tcp->keep_idle = (u32_t)(*(int*)optval);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n",
+                  s, sock->conn->pcb.tcp->keep_idle));
+      break;
+
+#if LWIP_TCP_KEEPALIVE
+    case TCP_KEEPIDLE:
+      sock->conn->pcb.tcp->keep_idle = 1000*(u32_t)(*(int*)optval);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n",
+                  s, sock->conn->pcb.tcp->keep_idle));
+      break;
+    case TCP_KEEPINTVL:
+      sock->conn->pcb.tcp->keep_intvl = 1000*(u32_t)(*(int*)optval);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n",
+                  s, sock->conn->pcb.tcp->keep_intvl));
+      break;
+    case TCP_KEEPCNT:
+      sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(int*)optval);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n",
+                  s, sock->conn->pcb.tcp->keep_cnt));
+      break;
+#endif /* LWIP_TCP_KEEPALIVE */
+    default:
+      LWIP_ASSERT("unhandled optname", 0);
+      break;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_TCP*/
+#if LWIP_UDP && LWIP_UDPLITE
+  /* Level: IPPROTO_UDPLITE */
+  case IPPROTO_UDPLITE:
+    switch (optname) {
+    case UDPLITE_SEND_CSCOV:
+      if ((*(int*)optval != 0) && ((*(int*)optval < 8) || (*(int*)optval > 0xffff))) {
+        /* don't allow illegal values! */
+        sock->conn->pcb.udp->chksum_len_tx = 8;
+      } else {
+        sock->conn->pcb.udp->chksum_len_tx = (u16_t)*(int*)optval;
+      }
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n",
+                  s, (*(int*)optval)) );
+      break;
+    case UDPLITE_RECV_CSCOV:
+      if ((*(int*)optval != 0) && ((*(int*)optval < 8) || (*(int*)optval > 0xffff))) {
+        /* don't allow illegal values! */
+        sock->conn->pcb.udp->chksum_len_rx = 8;
+      } else {
+        sock->conn->pcb.udp->chksum_len_rx = (u16_t)*(int*)optval;
+      }
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n",
+                  s, (*(int*)optval)) );
+      break;
+    default:
+      LWIP_ASSERT("unhandled optname", 0);
+      break;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_UDP */
+  default:
+    LWIP_ASSERT("unhandled level", 0);
+    break;
+  }  /* switch (level) */
+  sys_sem_signal(&sock->conn->op_completed);
+}
+
+int
+lwip_ioctl(int s, long cmd, void *argp)
+{
+  struct lwip_sock *sock = get_socket(s);
+  u8_t val;
+#if LWIP_SO_RCVBUF
+  u16_t buflen = 0;
+  s16_t recv_avail;
+#endif /* LWIP_SO_RCVBUF */
+
+  if (!sock) {
+    return -1;
+  }
+
+  switch (cmd) {
+#if LWIP_SO_RCVBUF
+  case FIONREAD:
+    if (!argp) {
+      sock_set_errno(sock, EINVAL);
+      return -1;
+    }
+
+    SYS_ARCH_GET(sock->conn->recv_avail, recv_avail);
+    if (recv_avail < 0) {
+      recv_avail = 0;
+    }
+    *((u16_t*)argp) = (u16_t)recv_avail;
+
+    /* Check if there is data left from the last recv operation. /maq 041215 */
+    if (sock->lastdata) {
+      struct pbuf *p = (struct pbuf *)sock->lastdata;
+      if (netconn_type(sock->conn) != NETCONN_TCP) {
+        p = ((struct netbuf *)p)->p;
+      }
+      buflen = p->tot_len;
+      buflen -= sock->lastoffset;
+
+      *((u16_t*)argp) += buflen;
+    }
+
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t*)argp)));
+    sock_set_errno(sock, 0);
+    return 0;
+#endif /* LWIP_SO_RCVBUF */
+
+  case FIONBIO:
+    val = 0;
+    if (argp && *(u32_t*)argp) {
+      val = 1;
+    }
+    netconn_set_nonblocking(sock->conn, val);
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, val));
+    sock_set_errno(sock, 0);
+    return 0;
+
+  default:
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp));
+    sock_set_errno(sock, ENOSYS); /* not yet implemented */
+    return -1;
+  } /* switch (cmd) */
+}
+
+/** A minimal implementation of fcntl.
+ * Currently only the commands F_GETFL and F_SETFL are implemented.
+ * Only the flag O_NONBLOCK is implemented.
+ */
+int
+lwip_fcntl(int s, int cmd, int val)
+{
+  struct lwip_sock *sock = get_socket(s);
+  int ret = -1;
+
+  if (!sock || !sock->conn) {
+    return -1;
+  }
+
+  switch (cmd) {
+  case F_GETFL:
+    ret = netconn_is_nonblocking(sock->conn) ? O_NONBLOCK : 0;
+    break;
+  case F_SETFL:
+    if ((val & ~O_NONBLOCK) == 0) {
+      /* only O_NONBLOCK, all other bits are zero */
+      netconn_set_nonblocking(sock->conn, val & O_NONBLOCK);
+      ret = 0;
+    }
+    break;
+  default:
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val));
+    break;
+  }
+  return ret;
+}
+
+#endif /* LWIP_SOCKET */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/api/tcpip.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/api/tcpip.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/api/tcpip.c	(revision 164)
@@ -0,0 +1,511 @@
+/**
+ * @file
+ * Sequential API Main thread module
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if !NO_SYS /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/sys.h"
+#include "lwip/memp.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/tcpip.h"
+#include "lwip/init.h"
+#include "netif/etharp.h"
+#include "netif/ppp_oe.h"
+
+/* global variables */
+static tcpip_init_done_fn tcpip_init_done;
+static void *tcpip_init_done_arg;
+static sys_mbox_t mbox;
+
+#if LWIP_TCPIP_CORE_LOCKING
+/** The global semaphore to lock the stack. */
+sys_mutex_t lock_tcpip_core;
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+
+
+/**
+ * The main lwIP thread. This thread has exclusive access to lwIP core functions
+ * (unless access to them is not locked). Other threads communicate with this
+ * thread using message boxes.
+ *
+ * It also starts all the timers to make sure they are running in the right
+ * thread context.
+ *
+ * @param arg unused argument
+ */
+static void
+tcpip_thread(void *arg)
+{
+  struct tcpip_msg *msg;
+  LWIP_UNUSED_ARG(arg);
+
+  if (tcpip_init_done != NULL) {
+    tcpip_init_done(tcpip_init_done_arg);
+  }
+
+  LOCK_TCPIP_CORE();
+  while (1) {                          /* MAIN Loop */
+    UNLOCK_TCPIP_CORE();
+    LWIP_TCPIP_THREAD_ALIVE();
+    /* wait for a message, timeouts are processed while waiting */
+    sys_timeouts_mbox_fetch(&mbox, (void **)&msg);
+    LOCK_TCPIP_CORE();
+    switch (msg->type) {
+#if LWIP_NETCONN
+    case TCPIP_MSG_API:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
+      msg->msg.apimsg->function(&(msg->msg.apimsg->msg));
+      break;
+#endif /* LWIP_NETCONN */
+
+#if !LWIP_TCPIP_CORE_LOCKING_INPUT
+    case TCPIP_MSG_INPKT:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
+#if LWIP_ETHERNET
+      if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
+        ethernet_input(msg->msg.inp.p, msg->msg.inp.netif);
+      } else
+#endif /* LWIP_ETHERNET */
+      {
+        ip_input(msg->msg.inp.p, msg->msg.inp.netif);
+      }
+      memp_free(MEMP_TCPIP_MSG_INPKT, msg);
+      break;
+#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
+
+#if LWIP_NETIF_API
+    case TCPIP_MSG_NETIFAPI:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg));
+      msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg));
+      break;
+#endif /* LWIP_NETIF_API */
+
+#if LWIP_TCPIP_TIMEOUT
+    case TCPIP_MSG_TIMEOUT:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
+      sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
+      memp_free(MEMP_TCPIP_MSG_API, msg);
+      break;
+    case TCPIP_MSG_UNTIMEOUT:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
+      sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
+      memp_free(MEMP_TCPIP_MSG_API, msg);
+      break;
+#endif /* LWIP_TCPIP_TIMEOUT */
+
+    case TCPIP_MSG_CALLBACK:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
+      msg->msg.cb.function(msg->msg.cb.ctx);
+      memp_free(MEMP_TCPIP_MSG_API, msg);
+      break;
+
+    case TCPIP_MSG_CALLBACK_STATIC:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg));
+      msg->msg.cb.function(msg->msg.cb.ctx);
+      break;
+
+    default:
+      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
+      LWIP_ASSERT("tcpip_thread: invalid message", 0);
+      break;
+    }
+  }
+}
+
+/**
+ * Pass a received packet to tcpip_thread for input processing
+ *
+ * @param p the received packet, p->payload pointing to the Ethernet header or
+ *          to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or
+ *          NETIF_FLAG_ETHERNET flags)
+ * @param inp the network interface on which the packet was received
+ */
+err_t
+tcpip_input(struct pbuf *p, struct netif *inp)
+{
+#if LWIP_TCPIP_CORE_LOCKING_INPUT
+  err_t ret;
+  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp));
+  LOCK_TCPIP_CORE();
+#if LWIP_ETHERNET
+  if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
+    ret = ethernet_input(p, inp);
+  } else
+#endif /* LWIP_ETHERNET */
+  {
+    ret = ip_input(p, inp);
+  }
+  UNLOCK_TCPIP_CORE();
+  return ret;
+#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
+  struct tcpip_msg *msg;
+
+  if (!sys_mbox_valid(&mbox)) {
+    return ERR_VAL;
+  }
+  msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
+  if (msg == NULL) {
+    return ERR_MEM;
+  }
+
+  msg->type = TCPIP_MSG_INPKT;
+  msg->msg.inp.p = p;
+  msg->msg.inp.netif = inp;
+  if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
+    memp_free(MEMP_TCPIP_MSG_INPKT, msg);
+    return ERR_MEM;
+  }
+  return ERR_OK;
+#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
+}
+
+/**
+ * Call a specific function in the thread context of
+ * tcpip_thread for easy access synchronization.
+ * A function called in that way may access lwIP core code
+ * without fearing concurrent access.
+ *
+ * @param f the function to call
+ * @param ctx parameter passed to f
+ * @param block 1 to block until the request is posted, 0 to non-blocking mode
+ * @return ERR_OK if the function was called, another err_t if not
+ */
+err_t
+tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
+{
+  struct tcpip_msg *msg;
+
+  if (sys_mbox_valid(&mbox)) {
+    msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
+    if (msg == NULL) {
+      return ERR_MEM;
+    }
+
+    msg->type = TCPIP_MSG_CALLBACK;
+    msg->msg.cb.function = function;
+    msg->msg.cb.ctx = ctx;
+    if (block) {
+      sys_mbox_post(&mbox, msg);
+    } else {
+      if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
+        memp_free(MEMP_TCPIP_MSG_API, msg);
+        return ERR_MEM;
+      }
+    }
+    return ERR_OK;
+  }
+  return ERR_VAL;
+}
+
+#if LWIP_TCPIP_TIMEOUT
+/**
+ * call sys_timeout in tcpip_thread
+ *
+ * @param msec time in milliseconds for timeout
+ * @param h function to be called on timeout
+ * @param arg argument to pass to timeout function h
+ * @return ERR_MEM on memory error, ERR_OK otherwise
+ */
+err_t
+tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
+{
+  struct tcpip_msg *msg;
+
+  if (sys_mbox_valid(&mbox)) {
+    msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
+    if (msg == NULL) {
+      return ERR_MEM;
+    }
+
+    msg->type = TCPIP_MSG_TIMEOUT;
+    msg->msg.tmo.msecs = msecs;
+    msg->msg.tmo.h = h;
+    msg->msg.tmo.arg = arg;
+    sys_mbox_post(&mbox, msg);
+    return ERR_OK;
+  }
+  return ERR_VAL;
+}
+
+/**
+ * call sys_untimeout in tcpip_thread
+ *
+ * @param msec time in milliseconds for timeout
+ * @param h function to be called on timeout
+ * @param arg argument to pass to timeout function h
+ * @return ERR_MEM on memory error, ERR_OK otherwise
+ */
+err_t
+tcpip_untimeout(sys_timeout_handler h, void *arg)
+{
+  struct tcpip_msg *msg;
+
+  if (sys_mbox_valid(&mbox)) {
+    msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
+    if (msg == NULL) {
+      return ERR_MEM;
+    }
+
+    msg->type = TCPIP_MSG_UNTIMEOUT;
+    msg->msg.tmo.h = h;
+    msg->msg.tmo.arg = arg;
+    sys_mbox_post(&mbox, msg);
+    return ERR_OK;
+  }
+  return ERR_VAL;
+}
+#endif /* LWIP_TCPIP_TIMEOUT */
+
+#if LWIP_NETCONN
+/**
+ * Call the lower part of a netconn_* function
+ * This function is then running in the thread context
+ * of tcpip_thread and has exclusive access to lwIP core code.
+ *
+ * @param apimsg a struct containing the function to call and its parameters
+ * @return ERR_OK if the function was called, another err_t if not
+ */
+err_t
+tcpip_apimsg(struct api_msg *apimsg)
+{
+  struct tcpip_msg msg;
+#ifdef LWIP_DEBUG
+  /* catch functions that don't set err */
+  apimsg->msg.err = ERR_VAL;
+#endif
+  
+  if (sys_mbox_valid(&mbox)) {
+    msg.type = TCPIP_MSG_API;
+    msg.msg.apimsg = apimsg;
+    sys_mbox_post(&mbox, &msg);
+    sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0);
+    return apimsg->msg.err;
+  }
+  return ERR_VAL;
+}
+
+#if LWIP_TCPIP_CORE_LOCKING
+/**
+ * Call the lower part of a netconn_* function
+ * This function has exclusive access to lwIP core code by locking it
+ * before the function is called.
+ *
+ * @param apimsg a struct containing the function to call and its parameters
+ * @return ERR_OK (only for compatibility fo tcpip_apimsg())
+ */
+err_t
+tcpip_apimsg_lock(struct api_msg *apimsg)
+{
+#ifdef LWIP_DEBUG
+  /* catch functions that don't set err */
+  apimsg->msg.err = ERR_VAL;
+#endif
+
+  LOCK_TCPIP_CORE();
+  apimsg->function(&(apimsg->msg));
+  UNLOCK_TCPIP_CORE();
+  return apimsg->msg.err;
+
+}
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+#endif /* LWIP_NETCONN */
+
+#if LWIP_NETIF_API
+#if !LWIP_TCPIP_CORE_LOCKING
+/**
+ * Much like tcpip_apimsg, but calls the lower part of a netifapi_*
+ * function.
+ *
+ * @param netifapimsg a struct containing the function to call and its parameters
+ * @return error code given back by the function that was called
+ */
+err_t
+tcpip_netifapi(struct netifapi_msg* netifapimsg)
+{
+  struct tcpip_msg msg;
+  
+  if (sys_mbox_valid(&mbox)) {
+    err_t err = sys_sem_new(&netifapimsg->msg.sem, 0);
+    if (err != ERR_OK) {
+      netifapimsg->msg.err = err;
+      return err;
+    }
+    
+    msg.type = TCPIP_MSG_NETIFAPI;
+    msg.msg.netifapimsg = netifapimsg;
+    sys_mbox_post(&mbox, &msg);
+    sys_sem_wait(&netifapimsg->msg.sem);
+    sys_sem_free(&netifapimsg->msg.sem);
+    return netifapimsg->msg.err;
+  }
+  return ERR_VAL;
+}
+#else /* !LWIP_TCPIP_CORE_LOCKING */
+/**
+ * Call the lower part of a netifapi_* function
+ * This function has exclusive access to lwIP core code by locking it
+ * before the function is called.
+ *
+ * @param netifapimsg a struct containing the function to call and its parameters
+ * @return ERR_OK (only for compatibility fo tcpip_netifapi())
+ */
+err_t
+tcpip_netifapi_lock(struct netifapi_msg* netifapimsg)
+{
+  LOCK_TCPIP_CORE();  
+  netifapimsg->function(&(netifapimsg->msg));
+  UNLOCK_TCPIP_CORE();
+  return netifapimsg->msg.err;
+}
+#endif /* !LWIP_TCPIP_CORE_LOCKING */
+#endif /* LWIP_NETIF_API */
+
+/**
+ * Allocate a structure for a static callback message and initialize it.
+ * This is intended to be used to send "static" messages from interrupt context.
+ *
+ * @param function the function to call
+ * @param ctx parameter passed to function
+ * @return a struct pointer to pass to tcpip_trycallback().
+ */
+struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx)
+{
+  struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
+  if (msg == NULL) {
+    return NULL;
+  }
+  msg->type = TCPIP_MSG_CALLBACK_STATIC;
+  msg->msg.cb.function = function;
+  msg->msg.cb.ctx = ctx;
+  return (struct tcpip_callback_msg*)msg;
+}
+
+/**
+ * Free a callback message allocated by tcpip_callbackmsg_new().
+ *
+ * @param msg the message to free
+ */
+void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg)
+{
+  memp_free(MEMP_TCPIP_MSG_API, msg);
+}
+
+/**
+ * Try to post a callback-message to the tcpip_thread mbox
+ * This is intended to be used to send "static" messages from interrupt context.
+ *
+ * @param msg pointer to the message to post
+ * @return sys_mbox_trypost() return code
+ */
+err_t
+tcpip_trycallback(struct tcpip_callback_msg* msg)
+{
+  if (!sys_mbox_valid(&mbox)) {
+    return ERR_VAL;
+  }
+  return sys_mbox_trypost(&mbox, msg);
+}
+
+/**
+ * Initialize this module:
+ * - initialize all sub modules
+ * - start the tcpip_thread
+ *
+ * @param initfunc a function to call when tcpip_thread is running and finished initializing
+ * @param arg argument to pass to initfunc
+ */
+void
+tcpip_init(tcpip_init_done_fn initfunc, void *arg)
+{
+  lwip_init();
+
+  tcpip_init_done = initfunc;
+  tcpip_init_done_arg = arg;
+  if(sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) {
+    LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
+  }
+#if LWIP_TCPIP_CORE_LOCKING
+  if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) {
+    LWIP_ASSERT("failed to create lock_tcpip_core", 0);
+  }
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+
+  sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
+}
+
+/**
+ * Simple callback function used with tcpip_callback to free a pbuf
+ * (pbuf_free has a wrong signature for tcpip_callback)
+ *
+ * @param p The pbuf (chain) to be dereferenced.
+ */
+static void
+pbuf_free_int(void *p)
+{
+  struct pbuf *q = (struct pbuf *)p;
+  pbuf_free(q);
+}
+
+/**
+ * A simple wrapper function that allows you to free a pbuf from interrupt context.
+ *
+ * @param p The pbuf (chain) to be dereferenced.
+ * @return ERR_OK if callback could be enqueued, an err_t if not
+ */
+err_t
+pbuf_free_callback(struct pbuf *p)
+{
+  return tcpip_callback_with_block(pbuf_free_int, p, 0);
+}
+
+/**
+ * A simple wrapper function that allows you to free heap memory from
+ * interrupt context.
+ *
+ * @param m the heap memory to free
+ * @return ERR_OK if callback could be enqueued, an err_t if not
+ */
+err_t
+mem_free_callback(void *m)
+{
+  return tcpip_callback_with_block(mem_free, m, 0);
+}
+
+#endif /* !NO_SYS */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/def.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/def.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/def.c	(revision 164)
@@ -0,0 +1,108 @@
+/**
+ * @file
+ * Common functions used throughout the stack.
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt
+ *
+ */
+
+#include "lwip/opt.h"
+#include "lwip/def.h"
+
+/**
+ * These are reference implementations of the byte swapping functions.
+ * Again with the aim of being simple, correct and fully portable.
+ * Byte swapping is the second thing you would want to optimize. You will
+ * need to port it to your architecture and in your cc.h:
+ * 
+ * #define LWIP_PLATFORM_BYTESWAP 1
+ * #define LWIP_PLATFORM_HTONS(x) <your_htons>
+ * #define LWIP_PLATFORM_HTONL(x) <your_htonl>
+ *
+ * Note ntohs() and ntohl() are merely references to the htonx counterparts.
+ */
+
+#if (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN)
+
+/**
+ * Convert an u16_t from host- to network byte order.
+ *
+ * @param n u16_t in host byte order
+ * @return n in network byte order
+ */
+u16_t
+lwip_htons(u16_t n)
+{
+  return ((n & 0xff) << 8) | ((n & 0xff00) >> 8);
+}
+
+/**
+ * Convert an u16_t from network- to host byte order.
+ *
+ * @param n u16_t in network byte order
+ * @return n in host byte order
+ */
+u16_t
+lwip_ntohs(u16_t n)
+{
+  return lwip_htons(n);
+}
+
+/**
+ * Convert an u32_t from host- to network byte order.
+ *
+ * @param n u32_t in host byte order
+ * @return n in network byte order
+ */
+u32_t
+lwip_htonl(u32_t n)
+{
+  return ((n & 0xff) << 24) |
+    ((n & 0xff00) << 8) |
+    ((n & 0xff0000UL) >> 8) |
+    ((n & 0xff000000UL) >> 24);
+}
+
+/**
+ * Convert an u32_t from network- to host byte order.
+ *
+ * @param n u32_t in network byte order
+ * @return n in host byte order
+ */
+u32_t
+lwip_ntohl(u32_t n)
+{
+  return lwip_htonl(n);
+}
+
+#endif /* (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/dhcp.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/dhcp.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/dhcp.c	(revision 164)
@@ -0,0 +1,1770 @@
+/**
+ * @file
+ * Dynamic Host Configuration Protocol client
+ *
+ */
+
+/*
+ *
+ * Copyright (c) 2001-2004 Leon Woestenberg <leon.woestenberg@gmx.net>
+ * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is a contribution to the lwIP TCP/IP stack.
+ * The Swedish Institute of Computer Science and Adam Dunkels
+ * are specifically granted permission to redistribute this
+ * source code.
+ *
+ * Author: Leon Woestenberg <leon.woestenberg@gmx.net>
+ *
+ * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform
+ * with RFC 2131 and RFC 2132.
+ *
+ * TODO:
+ * - Support for interfaces other than Ethernet (SLIP, PPP, ...)
+ *
+ * Please coordinate changes and requests with Leon Woestenberg
+ * <leon.woestenberg@gmx.net>
+ *
+ * Integration with your code:
+ *
+ * In lwip/dhcp.h
+ * #define DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute)
+ * #define DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer)
+ *
+ * Then have your application call dhcp_coarse_tmr() and
+ * dhcp_fine_tmr() on the defined intervals.
+ *
+ * dhcp_start(struct netif *netif);
+ * starts a DHCP client instance which configures the interface by
+ * obtaining an IP address lease and maintaining it.
+ *
+ * Use dhcp_release(netif) to end the lease and use dhcp_stop(netif)
+ * to remove the DHCP client.
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/stats.h"
+#include "lwip/mem.h"
+#include "lwip/udp.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/def.h"
+#include "lwip/dhcp.h"
+#include "lwip/autoip.h"
+#include "lwip/dns.h"
+#include "netif/etharp.h"
+
+#include <string.h>
+
+/** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using
+ * LWIP_RAND() (this overrides DHCP_GLOBAL_XID)
+ */
+#ifndef DHCP_CREATE_RAND_XID
+#define DHCP_CREATE_RAND_XID 1
+#endif
+
+/** Default for DHCP_GLOBAL_XID is 0xABCD0000
+ * This can be changed by defining DHCP_GLOBAL_XID and DHCP_GLOBAL_XID_HEADER, e.g.
+ *  #define DHCP_GLOBAL_XID_HEADER "stdlib.h"
+ *  #define DHCP_GLOBAL_XID rand()
+ */
+#ifdef DHCP_GLOBAL_XID_HEADER
+#include DHCP_GLOBAL_XID_HEADER /* include optional starting XID generation prototypes */
+#endif
+
+/** DHCP_OPTION_MAX_MSG_SIZE is set to the MTU
+ * MTU is checked to be big enough in dhcp_start */
+#define DHCP_MAX_MSG_LEN(netif)        (netif->mtu)
+#define DHCP_MAX_MSG_LEN_MIN_REQUIRED  576
+/** Minimum length for reply before packet is parsed */
+#define DHCP_MIN_REPLY_LEN             44
+
+#define REBOOT_TRIES 2
+
+/** Option handling: options are parsed in dhcp_parse_reply
+ * and saved in an array where other functions can load them from.
+ * This might be moved into the struct dhcp (not necessarily since
+ * lwIP is single-threaded and the array is only used while in recv
+ * callback). */
+#define DHCP_OPTION_IDX_OVERLOAD    0
+#define DHCP_OPTION_IDX_MSG_TYPE    1
+#define DHCP_OPTION_IDX_SERVER_ID   2
+#define DHCP_OPTION_IDX_LEASE_TIME  3
+#define DHCP_OPTION_IDX_T1          4
+#define DHCP_OPTION_IDX_T2          5
+#define DHCP_OPTION_IDX_SUBNET_MASK 6
+#define DHCP_OPTION_IDX_ROUTER      7
+#define DHCP_OPTION_IDX_DNS_SERVER  8
+#define DHCP_OPTION_IDX_MAX         (DHCP_OPTION_IDX_DNS_SERVER + DNS_MAX_SERVERS)
+
+/** Holds the decoded option values, only valid while in dhcp_recv.
+    @todo: move this into struct dhcp? */
+u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX];
+/** Holds a flag which option was received and is contained in dhcp_rx_options_val,
+    only valid while in dhcp_recv.
+    @todo: move this into struct dhcp? */
+u8_t  dhcp_rx_options_given[DHCP_OPTION_IDX_MAX];
+
+#ifdef DHCP_GLOBAL_XID
+static u32_t xid;
+static u8_t xid_initialised;
+#endif /* DHCP_GLOBAL_XID */
+
+#define dhcp_option_given(dhcp, idx)          (dhcp_rx_options_given[idx] != 0)
+#define dhcp_got_option(dhcp, idx)            (dhcp_rx_options_given[idx] = 1)
+#define dhcp_clear_option(dhcp, idx)          (dhcp_rx_options_given[idx] = 0)
+#define dhcp_clear_all_options(dhcp)          (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given)))
+#define dhcp_get_option_value(dhcp, idx)      (dhcp_rx_options_val[idx])
+#define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val))
+
+
+/* DHCP client state machine functions */
+static err_t dhcp_discover(struct netif *netif);
+static err_t dhcp_select(struct netif *netif);
+static void dhcp_bind(struct netif *netif);
+#if DHCP_DOES_ARP_CHECK
+static err_t dhcp_decline(struct netif *netif);
+#endif /* DHCP_DOES_ARP_CHECK */
+static err_t dhcp_rebind(struct netif *netif);
+static err_t dhcp_reboot(struct netif *netif);
+static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state);
+
+/* receive, unfold, parse and free incoming messages */
+static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port);
+
+/* set the DHCP timers */
+static void dhcp_timeout(struct netif *netif);
+static void dhcp_t1_timeout(struct netif *netif);
+static void dhcp_t2_timeout(struct netif *netif);
+
+/* build outgoing messages */
+/* create a DHCP message, fill in common headers */
+static err_t dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type);
+/* free a DHCP request */
+static void dhcp_delete_msg(struct dhcp *dhcp);
+/* add a DHCP option (type, then length in bytes) */
+static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len);
+/* add option values */
+static void dhcp_option_byte(struct dhcp *dhcp, u8_t value);
+static void dhcp_option_short(struct dhcp *dhcp, u16_t value);
+static void dhcp_option_long(struct dhcp *dhcp, u32_t value);
+#if LWIP_NETIF_HOSTNAME
+static void dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif);
+#endif /* LWIP_NETIF_HOSTNAME */
+/* always add the DHCP options trailer to end and pad */
+static void dhcp_option_trailer(struct dhcp *dhcp);
+
+/**
+ * Back-off the DHCP client (because of a received NAK response).
+ *
+ * Back-off the DHCP client because of a received NAK. Receiving a
+ * NAK means the client asked for something non-sensible, for
+ * example when it tries to renew a lease obtained on another network.
+ *
+ * We clear any existing set IP address and restart DHCP negotiation
+ * afresh (as per RFC2131 3.2.3).
+ *
+ * @param netif the netif under DHCP control
+ */
+static void
+dhcp_handle_nak(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n", 
+    (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
+  /* Set the interface down since the address must no longer be used, as per RFC2131 */
+  netif_set_down(netif);
+  /* remove IP address from interface */
+  netif_set_ipaddr(netif, IP_ADDR_ANY);
+  netif_set_gw(netif, IP_ADDR_ANY);
+  netif_set_netmask(netif, IP_ADDR_ANY); 
+  /* Change to a defined state */
+  dhcp_set_state(dhcp, DHCP_BACKING_OFF);
+  /* We can immediately restart discovery */
+  dhcp_discover(netif);
+}
+
+#if DHCP_DOES_ARP_CHECK
+/**
+ * Checks if the offered IP address is already in use.
+ *
+ * It does so by sending an ARP request for the offered address and
+ * entering CHECKING state. If no ARP reply is received within a small
+ * interval, the address is assumed to be free for use by us.
+ *
+ * @param netif the netif under DHCP control
+ */
+static void
+dhcp_check(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+  err_t result;
+  u16_t msecs;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0],
+    (s16_t)netif->name[1]));
+  dhcp_set_state(dhcp, DHCP_CHECKING);
+  /* create an ARP query for the offered IP address, expecting that no host
+     responds, as the IP address should not be in use. */
+  result = etharp_query(netif, &dhcp->offered_ip_addr, NULL);
+  if (result != ERR_OK) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_check: could not perform ARP query\n"));
+  }
+  dhcp->tries++;
+  msecs = 500;
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs));
+}
+#endif /* DHCP_DOES_ARP_CHECK */
+
+/**
+ * Remember the configuration offered by a DHCP server.
+ *
+ * @param netif the netif under DHCP control
+ */
+static void
+dhcp_handle_offer(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n",
+    (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
+  /* obtain the server address */
+  if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) {
+    ip4_addr_set_u32(&dhcp->server_ip_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SERVER_ID)));
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n",
+      ip4_addr_get_u32(&dhcp->server_ip_addr)));
+    /* remember offered address */
+    ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n",
+      ip4_addr_get_u32(&dhcp->offered_ip_addr)));
+
+    dhcp_select(netif);
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
+      ("dhcp_handle_offer(netif=%p) did not get server ID!\n", (void*)netif));
+  }
+}
+
+/**
+ * Select a DHCP server offer out of all offers.
+ *
+ * Simply select the first offer received.
+ *
+ * @param netif the netif under DHCP control
+ * @return lwIP specific error (see error.h)
+ */
+static err_t
+dhcp_select(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+  err_t result;
+  u16_t msecs;
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_select(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
+  dhcp_set_state(dhcp, DHCP_REQUESTING);
+
+  /* create and initialize the DHCP message header */
+  result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST);
+  if (result == ERR_OK) {
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
+    dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
+
+    /* MUST request the offered IP address */
+    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
+    dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
+
+    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
+    dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->server_ip_addr)));
+
+    dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/);
+    dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
+    dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
+    dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
+    dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
+
+#if LWIP_NETIF_HOSTNAME
+    dhcp_option_hostname(dhcp, netif);
+#endif /* LWIP_NETIF_HOSTNAME */
+
+    dhcp_option_trailer(dhcp);
+    /* shrink the pbuf to the actual content length */
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
+
+    /* send broadcast to any DHCP server */
+    udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
+    dhcp_delete_msg(dhcp);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n"));
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_select: could not allocate DHCP request\n"));
+  }
+  dhcp->tries++;
+  msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000;
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs));
+  return result;
+}
+
+/**
+ * The DHCP timer that checks for lease renewal/rebind timeouts.
+ */
+void
+dhcp_coarse_tmr()
+{
+  struct netif *netif = netif_list;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n"));
+  /* iterate through all network interfaces */
+  while (netif != NULL) {
+    /* only act on DHCP configured interfaces */
+    if (netif->dhcp != NULL) {
+      /* timer is active (non zero), and triggers (zeroes) now? */
+      if (netif->dhcp->t2_timeout-- == 1) {
+        LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n"));
+        /* this clients' rebind timeout triggered */
+        dhcp_t2_timeout(netif);
+      /* timer is active (non zero), and triggers (zeroes) now */
+      } else if (netif->dhcp->t1_timeout-- == 1) {
+        LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n"));
+        /* this clients' renewal timeout triggered */
+        dhcp_t1_timeout(netif);
+      }
+    }
+    /* proceed to next netif */
+    netif = netif->next;
+  }
+}
+
+/**
+ * DHCP transaction timeout handling
+ *
+ * A DHCP server is expected to respond within a short period of time.
+ * This timer checks whether an outstanding DHCP request is timed out.
+ */
+void
+dhcp_fine_tmr()
+{
+  struct netif *netif = netif_list;
+  /* loop through netif's */
+  while (netif != NULL) {
+    /* only act on DHCP configured interfaces */
+    if (netif->dhcp != NULL) {
+      /* timer is active (non zero), and is about to trigger now */      
+      if (netif->dhcp->request_timeout > 1) {
+        netif->dhcp->request_timeout--;
+      }
+      else if (netif->dhcp->request_timeout == 1) {
+        netif->dhcp->request_timeout--;
+        /* { netif->dhcp->request_timeout == 0 } */
+        LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n"));
+        /* this client's request timeout triggered */
+        dhcp_timeout(netif);
+      }
+    }
+    /* proceed to next network interface */
+    netif = netif->next;
+  }
+}
+
+/**
+ * A DHCP negotiation transaction, or ARP request, has timed out.
+ *
+ * The timer that was started with the DHCP or ARP request has
+ * timed out, indicating no response was received in time.
+ *
+ * @param netif the netif under DHCP control
+ */
+static void
+dhcp_timeout(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout()\n"));
+  /* back-off period has passed, or server selection timed out */
+  if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery\n"));
+    dhcp_discover(netif);
+  /* receiving the requested lease timed out */
+  } else if (dhcp->state == DHCP_REQUESTING) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n"));
+    if (dhcp->tries <= 5) {
+      dhcp_select(netif);
+    } else {
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n"));
+      dhcp_release(netif);
+      dhcp_discover(netif);
+    }
+#if DHCP_DOES_ARP_CHECK
+  /* received no ARP reply for the offered address (which is good) */
+  } else if (dhcp->state == DHCP_CHECKING) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n"));
+    if (dhcp->tries <= 1) {
+      dhcp_check(netif);
+    /* no ARP replies on the offered address,
+       looks like the IP address is indeed free */
+    } else {
+      /* bind the interface to the offered address */
+      dhcp_bind(netif);
+    }
+#endif /* DHCP_DOES_ARP_CHECK */
+  }
+  /* did not get response to renew request? */
+  else if (dhcp->state == DHCP_RENEWING) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n"));
+    /* just retry renewal */
+    /* note that the rebind timer will eventually time-out if renew does not work */
+    dhcp_renew(netif);
+  /* did not get response to rebind request? */
+  } else if (dhcp->state == DHCP_REBINDING) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n"));
+    if (dhcp->tries <= 8) {
+      dhcp_rebind(netif);
+    } else {
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n"));
+      dhcp_release(netif);
+      dhcp_discover(netif);
+    }
+  } else if (dhcp->state == DHCP_REBOOTING) {
+    if (dhcp->tries < REBOOT_TRIES) {
+      dhcp_reboot(netif);
+    } else {
+      dhcp_discover(netif);
+    }
+  }
+}
+
+/**
+ * The renewal period has timed out.
+ *
+ * @param netif the netif under DHCP control
+ */
+static void
+dhcp_t1_timeout(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n"));
+  if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) ||
+      (dhcp->state == DHCP_RENEWING)) {
+    /* just retry to renew - note that the rebind timer (t2) will
+     * eventually time-out if renew tries fail. */
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+                ("dhcp_t1_timeout(): must renew\n"));
+    /* This slightly different to RFC2131: DHCPREQUEST will be sent from state
+       DHCP_RENEWING, not DHCP_BOUND */
+    dhcp_renew(netif);
+  }
+}
+
+/**
+ * The rebind period has timed out.
+ *
+ * @param netif the netif under DHCP control
+ */
+static void
+dhcp_t2_timeout(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n"));
+  if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) ||
+      (dhcp->state == DHCP_RENEWING)) {
+    /* just retry to rebind */
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+                ("dhcp_t2_timeout(): must rebind\n"));
+    /* This slightly different to RFC2131: DHCPREQUEST will be sent from state
+       DHCP_REBINDING, not DHCP_BOUND */
+    dhcp_rebind(netif);
+  }
+}
+
+/**
+ * Handle a DHCP ACK packet
+ *
+ * @param netif the netif under DHCP control
+ */
+static void
+dhcp_handle_ack(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+#if LWIP_DNS
+  u8_t n;
+#endif /* LWIP_DNS */
+
+  /* clear options we might not get from the ACK */
+  ip_addr_set_zero(&dhcp->offered_sn_mask);
+  ip_addr_set_zero(&dhcp->offered_gw_addr);
+#if LWIP_DHCP_BOOTP_FILE
+  ip_addr_set_zero(&dhcp->offered_si_addr);
+#endif /* LWIP_DHCP_BOOTP_FILE */
+
+  /* lease time given? */
+  if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_LEASE_TIME)) {
+    /* remember offered lease time */
+    dhcp->offered_t0_lease = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_LEASE_TIME);
+  }
+  /* renewal period given? */
+  if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T1)) {
+    /* remember given renewal period */
+    dhcp->offered_t1_renew = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T1);
+  } else {
+    /* calculate safe periods for renewal */
+    dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2;
+  }
+
+  /* renewal period given? */
+  if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T2)) {
+    /* remember given rebind period */
+    dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2);
+  } else {
+    /* calculate safe periods for rebinding */
+    dhcp->offered_t2_rebind = dhcp->offered_t0_lease;
+  }
+
+  /* (y)our internet address */
+  ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr);
+
+#if LWIP_DHCP_BOOTP_FILE
+  /* copy boot server address,
+     boot file name copied in dhcp_parse_reply if not overloaded */
+  ip_addr_copy(dhcp->offered_si_addr, dhcp->msg_in->siaddr);
+#endif /* LWIP_DHCP_BOOTP_FILE */
+
+  /* subnet mask given? */
+  if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)) {
+    /* remember given subnet mask */
+    ip4_addr_set_u32(&dhcp->offered_sn_mask, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)));
+    dhcp->subnet_mask_given = 1;
+  } else {
+    dhcp->subnet_mask_given = 0;
+  }
+
+  /* gateway router */
+  if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) {
+    ip4_addr_set_u32(&dhcp->offered_gw_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER)));
+  }
+  
+#if LWIP_DNS
+  /* DNS servers */
+  n = 0;
+  while(dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n) && (n < DNS_MAX_SERVERS)) {
+    ip_addr_t dns_addr;
+    ip4_addr_set_u32(&dns_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n)));
+    dns_setserver(n, &dns_addr);
+    n++;
+  }
+#endif /* LWIP_DNS */
+}
+
+/** Set a statically allocated struct dhcp to work with.
+ * Using this prevents dhcp_start to allocate it using mem_malloc.
+ *
+ * @param netif the netif for which to set the struct dhcp
+ * @param dhcp (uninitialised) dhcp struct allocated by the application
+ */
+void
+dhcp_set_struct(struct netif *netif, struct dhcp *dhcp)
+{
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+  LWIP_ASSERT("dhcp != NULL", dhcp != NULL);
+  LWIP_ASSERT("netif already has a struct dhcp set", netif->dhcp == NULL);
+
+  /* clear data structure */
+  memset(dhcp, 0, sizeof(struct dhcp));
+  /* dhcp_set_state(&dhcp, DHCP_OFF); */
+  netif->dhcp = dhcp;
+}
+
+/** Removes a struct dhcp from a netif.
+ *
+ * ATTENTION: Only use this when not using dhcp_set_struct() to allocate the
+ *            struct dhcp since the memory is passed back to the heap.
+ *
+ * @param netif the netif from which to remove the struct dhcp
+ */
+void dhcp_cleanup(struct netif *netif)
+{
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+
+  if (netif->dhcp != NULL) {
+    mem_free(netif->dhcp);
+    netif->dhcp = NULL;
+  }
+}
+
+/**
+ * Start DHCP negotiation for a network interface.
+ *
+ * If no DHCP client instance was attached to this interface,
+ * a new client is created first. If a DHCP client instance
+ * was already present, it restarts negotiation.
+ *
+ * @param netif The lwIP network interface
+ * @return lwIP error code
+ * - ERR_OK - No error
+ * - ERR_MEM - Out of memory
+ */
+err_t
+dhcp_start(struct netif *netif)
+{
+  struct dhcp *dhcp;
+  err_t result = ERR_OK;
+
+  LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;);
+  dhcp = netif->dhcp;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
+  /* Remove the flag that says this netif is handled by DHCP,
+     it is set when we succeeded starting. */
+  netif->flags &= ~NETIF_FLAG_DHCP;
+
+  /* check hwtype of the netif */
+  if ((netif->flags & NETIF_FLAG_ETHARP) == 0) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): No ETHARP netif\n"));
+    return ERR_ARG;
+  }
+
+  /* check MTU of the netif */
+  if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): Cannot use this netif with DHCP: MTU is too small\n"));
+    return ERR_MEM;
+  }
+
+  /* no DHCP client attached yet? */
+  if (dhcp == NULL) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting new DHCP client\n"));
+    dhcp = (struct dhcp *)mem_malloc(sizeof(struct dhcp));
+    if (dhcp == NULL) {
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n"));
+      return ERR_MEM;
+    }
+    /* store this dhcp client in the netif */
+    netif->dhcp = dhcp;
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp"));
+  /* already has DHCP client attached */
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(): restarting DHCP configuration\n"));
+    if (dhcp->pcb != NULL) {
+      udp_remove(dhcp->pcb);
+    }
+    LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL);
+    LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL );
+  }
+    
+  /* clear data structure */
+  memset(dhcp, 0, sizeof(struct dhcp));
+  /* dhcp_set_state(&dhcp, DHCP_OFF); */
+  /* allocate UDP PCB */
+  dhcp->pcb = udp_new();
+  if (dhcp->pcb == NULL) {
+    LWIP_DEBUGF(DHCP_DEBUG  | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n"));
+    return ERR_MEM;
+  }
+  ip_set_option(dhcp->pcb, SOF_BROADCAST);
+  /* set up local and remote port for the pcb */
+  udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
+  udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
+  /* set up the recv callback and argument */
+  udp_recv(dhcp->pcb, dhcp_recv, netif);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n"));
+  /* (re)start the DHCP negotiation */
+  result = dhcp_discover(netif);
+  if (result != ERR_OK) {
+    /* free resources allocated above */
+    dhcp_stop(netif);
+    return ERR_MEM;
+  }
+  /* Set the flag that says this netif is handled by DHCP. */
+  netif->flags |= NETIF_FLAG_DHCP;
+  return result;
+}
+
+/**
+ * Inform a DHCP server of our manual configuration.
+ *
+ * This informs DHCP servers of our fixed IP address configuration
+ * by sending an INFORM message. It does not involve DHCP address
+ * configuration, it is just here to be nice to the network.
+ *
+ * @param netif The lwIP network interface
+ */
+void
+dhcp_inform(struct netif *netif)
+{
+  struct dhcp dhcp;
+  err_t result = ERR_OK;
+  struct udp_pcb *pcb;
+
+  LWIP_ERROR("netif != NULL", (netif != NULL), return;);
+
+  memset(&dhcp, 0, sizeof(struct dhcp));
+  dhcp_set_state(&dhcp, DHCP_INFORM);
+
+  if ((netif->dhcp != NULL) && (netif->dhcp->pcb != NULL)) {
+    /* re-use existing pcb */
+    pcb = netif->dhcp->pcb;
+  } else {
+    pcb = udp_new();
+    if (pcb == NULL) {
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform(): could not obtain pcb"));
+      return;
+    }
+    dhcp.pcb = pcb;
+    ip_set_option(dhcp.pcb, SOF_BROADCAST);
+    udp_bind(dhcp.pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n"));
+  }
+  /* create and initialize the DHCP message header */
+  result = dhcp_create_msg(netif, &dhcp, DHCP_INFORM);
+  if (result == ERR_OK) {
+    dhcp_option(&dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
+    dhcp_option_short(&dhcp, DHCP_MAX_MSG_LEN(netif));
+
+    dhcp_option_trailer(&dhcp);
+
+    pbuf_realloc(dhcp.p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp.options_out_len);
+
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n"));
+    udp_sendto_if(pcb, dhcp.p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
+    dhcp_delete_msg(&dhcp);
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform: could not allocate DHCP request\n"));
+  }
+
+  if (dhcp.pcb != NULL) {
+    /* otherwise, the existing pcb was used */
+    udp_remove(dhcp.pcb);
+  }
+}
+
+/** Handle a possible change in the network configuration.
+ *
+ * This enters the REBOOTING state to verify that the currently bound
+ * address is still valid.
+ */
+void
+dhcp_network_changed(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+  if (!dhcp)
+    return;
+  switch (dhcp->state) {
+  case DHCP_REBINDING:
+  case DHCP_RENEWING:
+  case DHCP_BOUND:
+  case DHCP_REBOOTING:
+    netif_set_down(netif);
+    dhcp->tries = 0;
+    dhcp_reboot(netif);
+    break;
+  case DHCP_OFF:
+    /* stay off */
+    break;
+  default:
+    dhcp->tries = 0;
+#if LWIP_DHCP_AUTOIP_COOP
+    if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
+      autoip_stop(netif);
+      dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
+    }
+#endif /* LWIP_DHCP_AUTOIP_COOP */
+    dhcp_discover(netif);
+    break;
+  }
+}
+
+#if DHCP_DOES_ARP_CHECK
+/**
+ * Match an ARP reply with the offered IP address.
+ *
+ * @param netif the network interface on which the reply was received
+ * @param addr The IP address we received a reply from
+ */
+void dhcp_arp_reply(struct netif *netif, ip_addr_t *addr)
+{
+  LWIP_ERROR("netif != NULL", (netif != NULL), return;);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_arp_reply()\n"));
+  /* is a DHCP client doing an ARP check? */
+  if ((netif->dhcp != NULL) && (netif->dhcp->state == DHCP_CHECKING)) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n",
+      ip4_addr_get_u32(addr)));
+    /* did a host respond with the address we
+       were offered by the DHCP server? */
+    if (ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) {
+      /* we will not accept the offered address */
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
+        ("dhcp_arp_reply(): arp reply matched with offered address, declining\n"));
+      dhcp_decline(netif);
+    }
+  }
+}
+
+/**
+ * Decline an offered lease.
+ *
+ * Tell the DHCP server we do not accept the offered address.
+ * One reason to decline the lease is when we find out the address
+ * is already in use by another host (through ARP).
+ *
+ * @param netif the netif under DHCP control
+ */
+static err_t
+dhcp_decline(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+  err_t result = ERR_OK;
+  u16_t msecs;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline()\n"));
+  dhcp_set_state(dhcp, DHCP_BACKING_OFF);
+  /* create and initialize the DHCP message header */
+  result = dhcp_create_msg(netif, dhcp, DHCP_DECLINE);
+  if (result == ERR_OK) {
+    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
+    dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
+
+    dhcp_option_trailer(dhcp);
+    /* resize pbuf to reflect true size of options */
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
+
+    /* per section 4.4.4, broadcast DECLINE messages */
+    udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
+    dhcp_delete_msg(dhcp);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_decline: BACKING OFF\n"));
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
+      ("dhcp_decline: could not allocate DHCP request\n"));
+  }
+  dhcp->tries++;
+  msecs = 10*1000;
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs));
+  return result;
+}
+#endif /* DHCP_DOES_ARP_CHECK */
+
+
+/**
+ * Start the DHCP process, discover a DHCP server.
+ *
+ * @param netif the netif under DHCP control
+ */
+static err_t
+dhcp_discover(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+  err_t result = ERR_OK;
+  u16_t msecs;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover()\n"));
+  ip_addr_set_any(&dhcp->offered_ip_addr);
+  dhcp_set_state(dhcp, DHCP_SELECTING);
+  /* create and initialize the DHCP message header */
+  result = dhcp_create_msg(netif, dhcp, DHCP_DISCOVER);
+  if (result == ERR_OK) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n"));
+
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
+    dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
+
+    dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/);
+    dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
+    dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
+    dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
+    dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
+
+    dhcp_option_trailer(dhcp);
+
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: realloc()ing\n"));
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
+
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n"));
+    udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n"));
+    dhcp_delete_msg(dhcp);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n"));
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_discover: could not allocate DHCP request\n"));
+  }
+  dhcp->tries++;
+#if LWIP_DHCP_AUTOIP_COOP
+  if(dhcp->tries >= LWIP_DHCP_AUTOIP_COOP_TRIES && dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_OFF) {
+    dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON;
+    autoip_start(netif);
+  }
+#endif /* LWIP_DHCP_AUTOIP_COOP */
+  msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000;
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs));
+  return result;
+}
+
+
+/**
+ * Bind the interface to the offered IP address.
+ *
+ * @param netif network interface to bind to the offered address
+ */
+static void
+dhcp_bind(struct netif *netif)
+{
+  u32_t timeout;
+  struct dhcp *dhcp;
+  ip_addr_t sn_mask, gw_addr;
+  LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;);
+  dhcp = netif->dhcp;
+  LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
+
+  /* temporary DHCP lease? */
+  if (dhcp->offered_t1_renew != 0xffffffffUL) {
+    /* set renewal period timer */
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew));
+    timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
+    if(timeout > 0xffff) {
+      timeout = 0xffff;
+    }
+    dhcp->t1_timeout = (u16_t)timeout;
+    if (dhcp->t1_timeout == 0) {
+      dhcp->t1_timeout = 1;
+    }
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000));
+  }
+  /* set renewal period timer */
+  if (dhcp->offered_t2_rebind != 0xffffffffUL) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind));
+    timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
+    if(timeout > 0xffff) {
+      timeout = 0xffff;
+    }
+    dhcp->t2_timeout = (u16_t)timeout;
+    if (dhcp->t2_timeout == 0) {
+      dhcp->t2_timeout = 1;
+    }
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000));
+  }
+
+  /* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. */
+  if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) {
+    dhcp->t1_timeout = 0;
+  }
+
+  if (dhcp->subnet_mask_given) {
+    /* copy offered network mask */
+    ip_addr_copy(sn_mask, dhcp->offered_sn_mask);
+  } else {
+    /* subnet mask not given, choose a safe subnet mask given the network class */
+    u8_t first_octet = ip4_addr1(&dhcp->offered_ip_addr);
+    if (first_octet <= 127) {
+      ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000UL));
+    } else if (first_octet >= 192) {
+      ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00UL));
+    } else {
+      ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000UL));
+    }
+  }
+
+  ip_addr_copy(gw_addr, dhcp->offered_gw_addr);
+  /* gateway address not given? */
+  if (ip_addr_isany(&gw_addr)) {
+    /* copy network address */
+    ip_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask);
+    /* use first host address on network as gateway */
+    ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL));
+  }
+
+#if LWIP_DHCP_AUTOIP_COOP
+  if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
+    autoip_stop(netif);
+    dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
+  }
+#endif /* LWIP_DHCP_AUTOIP_COOP */
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F"\n",
+    ip4_addr_get_u32(&dhcp->offered_ip_addr)));
+  netif_set_ipaddr(netif, &dhcp->offered_ip_addr);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): SN: 0x%08"X32_F"\n",
+    ip4_addr_get_u32(&sn_mask)));
+  netif_set_netmask(netif, &sn_mask);
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): GW: 0x%08"X32_F"\n",
+    ip4_addr_get_u32(&gw_addr)));
+  netif_set_gw(netif, &gw_addr);
+  /* bring the interface up */
+  netif_set_up(netif);
+  /* netif is now bound to DHCP leased address */
+  dhcp_set_state(dhcp, DHCP_BOUND);
+}
+
+/**
+ * Renew an existing DHCP lease at the involved DHCP server.
+ *
+ * @param netif network interface which must renew its lease
+ */
+err_t
+dhcp_renew(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+  err_t result;
+  u16_t msecs;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_renew()\n"));
+  dhcp_set_state(dhcp, DHCP_RENEWING);
+
+  /* create and initialize the DHCP message header */
+  result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST);
+  if (result == ERR_OK) {
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
+    dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
+
+#if 0
+    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
+    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
+#endif
+
+#if 0
+    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
+    dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
+#endif
+
+#if LWIP_NETIF_HOSTNAME
+    dhcp_option_hostname(dhcp, netif);
+#endif /* LWIP_NETIF_HOSTNAME */
+
+    /* append DHCP message trailer */
+    dhcp_option_trailer(dhcp);
+
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
+
+    udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif);
+    dhcp_delete_msg(dhcp);
+
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n"));
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_renew: could not allocate DHCP request\n"));
+  }
+  dhcp->tries++;
+  /* back-off on retries, but to a maximum of 20 seconds */
+  msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000;
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs));
+  return result;
+}
+
+/**
+ * Rebind with a DHCP server for an existing DHCP lease.
+ *
+ * @param netif network interface which must rebind with a DHCP server
+ */
+static err_t
+dhcp_rebind(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+  err_t result;
+  u16_t msecs;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind()\n"));
+  dhcp_set_state(dhcp, DHCP_REBINDING);
+
+  /* create and initialize the DHCP message header */
+  result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST);
+  if (result == ERR_OK) {
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
+    dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
+
+#if LWIP_NETIF_HOSTNAME
+    dhcp_option_hostname(dhcp, netif);
+#endif /* LWIP_NETIF_HOSTNAME */
+
+#if 0
+    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
+    dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
+
+    dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
+    dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
+#endif
+
+    dhcp_option_trailer(dhcp);
+
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
+
+    /* broadcast to server */
+    udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
+    dhcp_delete_msg(dhcp);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n"));
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_rebind: could not allocate DHCP request\n"));
+  }
+  dhcp->tries++;
+  msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs));
+  return result;
+}
+
+/**
+ * Enter REBOOTING state to verify an existing lease
+ *
+ * @param netif network interface which must reboot
+ */
+static err_t
+dhcp_reboot(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+  err_t result;
+  u16_t msecs;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot()\n"));
+  dhcp_set_state(dhcp, DHCP_REBOOTING);
+
+  /* create and initialize the DHCP message header */
+  result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST);
+  if (result == ERR_OK) {
+    dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
+    dhcp_option_short(dhcp, 576);
+
+    dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
+    dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
+
+    dhcp_option_trailer(dhcp);
+
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
+
+    /* broadcast to server */
+    udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
+    dhcp_delete_msg(dhcp);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n"));
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_reboot: could not allocate DHCP request\n"));
+  }
+  dhcp->tries++;
+  msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs));
+  return result;
+}
+
+
+/**
+ * Release a DHCP lease.
+ *
+ * @param netif network interface which must release its lease
+ */
+err_t
+dhcp_release(struct netif *netif)
+{
+  struct dhcp *dhcp = netif->dhcp;
+  err_t result;
+  u16_t msecs;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n"));
+
+  /* idle DHCP client */
+  dhcp_set_state(dhcp, DHCP_OFF);
+  /* clean old DHCP offer */
+  ip_addr_set_zero(&dhcp->server_ip_addr);
+  ip_addr_set_zero(&dhcp->offered_ip_addr);
+  ip_addr_set_zero(&dhcp->offered_sn_mask);
+  ip_addr_set_zero(&dhcp->offered_gw_addr);
+#if LWIP_DHCP_BOOTP_FILE
+  ip_addr_set_zero(&dhcp->offered_si_addr);
+#endif /* LWIP_DHCP_BOOTP_FILE */
+  dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;
+  
+  /* create and initialize the DHCP message header */
+  result = dhcp_create_msg(netif, dhcp, DHCP_RELEASE);
+  if (result == ERR_OK) {
+    dhcp_option_trailer(dhcp);
+
+    pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
+
+    udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif);
+    dhcp_delete_msg(dhcp);
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n"));
+  } else {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n"));
+  }
+  dhcp->tries++;
+  msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
+  dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release(): set request timeout %"U16_F" msecs\n", msecs));
+  /* bring the interface down */
+  netif_set_down(netif);
+  /* remove IP address from interface */
+  netif_set_ipaddr(netif, IP_ADDR_ANY);
+  netif_set_gw(netif, IP_ADDR_ANY);
+  netif_set_netmask(netif, IP_ADDR_ANY);
+  
+  return result;
+}
+
+/**
+ * Remove the DHCP client from the interface.
+ *
+ * @param netif The network interface to stop DHCP on
+ */
+void
+dhcp_stop(struct netif *netif)
+{
+  struct dhcp *dhcp;
+  LWIP_ERROR("dhcp_stop: netif != NULL", (netif != NULL), return;);
+  dhcp = netif->dhcp;
+  /* Remove the flag that says this netif is handled by DHCP. */
+  netif->flags &= ~NETIF_FLAG_DHCP;
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_stop()\n"));
+  /* netif is DHCP configured? */
+  if (dhcp != NULL) {
+#if LWIP_DHCP_AUTOIP_COOP
+    if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
+      autoip_stop(netif);
+      dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
+    }
+#endif /* LWIP_DHCP_AUTOIP_COOP */
+
+    if (dhcp->pcb != NULL) {
+      udp_remove(dhcp->pcb);
+      dhcp->pcb = NULL;
+    }
+    LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL);
+    dhcp_set_state(dhcp, DHCP_OFF);
+  }
+}
+
+/*
+ * Set the DHCP state of a DHCP client.
+ *
+ * If the state changed, reset the number of tries.
+ */
+static void
+dhcp_set_state(struct dhcp *dhcp, u8_t new_state)
+{
+  if (new_state != dhcp->state) {
+    dhcp->state = new_state;
+    dhcp->tries = 0;
+    dhcp->request_timeout = 0;
+  }
+}
+
+/*
+ * Concatenate an option type and length field to the outgoing
+ * DHCP message.
+ *
+ */
+static void
+dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len)
+{
+  LWIP_ASSERT("dhcp_option: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN);
+  dhcp->msg_out->options[dhcp->options_out_len++] = option_type;
+  dhcp->msg_out->options[dhcp->options_out_len++] = option_len;
+}
+/*
+ * Concatenate a single byte to the outgoing DHCP message.
+ *
+ */
+static void
+dhcp_option_byte(struct dhcp *dhcp, u8_t value)
+{
+  LWIP_ASSERT("dhcp_option_byte: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN);
+  dhcp->msg_out->options[dhcp->options_out_len++] = value;
+}
+
+static void
+dhcp_option_short(struct dhcp *dhcp, u16_t value)
+{
+  LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U <= DHCP_OPTIONS_LEN);
+  dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff00U) >> 8);
+  dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t) (value & 0x00ffU);
+}
+
+static void
+dhcp_option_long(struct dhcp *dhcp, u32_t value)
+{
+  LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4U <= DHCP_OPTIONS_LEN);
+  dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff000000UL) >> 24);
+  dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x00ff0000UL) >> 16);
+  dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x0000ff00UL) >> 8);
+  dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x000000ffUL));
+}
+
+#if LWIP_NETIF_HOSTNAME
+static void
+dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif)
+{
+  if (netif->hostname != NULL) {
+    size_t namelen = strlen(netif->hostname);
+    if (namelen > 0) {
+      u8_t len;
+      const char *p = netif->hostname;
+      /* Shrink len to available bytes (need 2 bytes for OPTION_HOSTNAME
+         and 1 byte for trailer) */
+      size_t available = DHCP_OPTIONS_LEN - dhcp->options_out_len - 3;
+      LWIP_ASSERT("DHCP: hostname is too long!", namelen <= available);
+      len = LWIP_MIN(namelen, available);
+      dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, len);
+      while (len--) {
+        dhcp_option_byte(dhcp, *p++);
+      }
+    }
+  }
+}
+#endif /* LWIP_NETIF_HOSTNAME */
+
+/**
+ * Extract the DHCP message and the DHCP options.
+ *
+ * Extract the DHCP message and the DHCP options, each into a contiguous
+ * piece of memory. As a DHCP message is variable sized by its options,
+ * and also allows overriding some fields for options, the easy approach
+ * is to first unfold the options into a conitguous piece of memory, and
+ * use that further on.
+ *
+ */
+static err_t
+dhcp_parse_reply(struct dhcp *dhcp, struct pbuf *p)
+{
+  u8_t *options;
+  u16_t offset;
+  u16_t offset_max;
+  u16_t options_idx;
+  u16_t options_idx_max;
+  struct pbuf *q;
+  int parse_file_as_options = 0;
+  int parse_sname_as_options = 0;
+
+  /* clear received options */
+  dhcp_clear_all_options(dhcp);
+  /* check that beginning of dhcp_msg (up to and including chaddr) is in first pbuf */
+  if (p->len < DHCP_SNAME_OFS) {
+    return ERR_BUF;
+  }
+  dhcp->msg_in = (struct dhcp_msg *)p->payload;
+#if LWIP_DHCP_BOOTP_FILE
+  /* clear boot file name */
+  dhcp->boot_file_name[0] = 0;
+#endif /* LWIP_DHCP_BOOTP_FILE */
+
+  /* parse options */
+
+  /* start with options field */
+  options_idx = DHCP_OPTIONS_OFS;
+  /* parse options to the end of the received packet */
+  options_idx_max = p->tot_len;
+again:
+  q = p;
+  while((q != NULL) && (options_idx >= q->len)) {
+    options_idx -= q->len;
+    options_idx_max -= q->len;
+    q = q->next;
+  }
+  if (q == NULL) {
+    return ERR_BUF;
+  }
+  offset = options_idx;
+  offset_max = options_idx_max;
+  options = (u8_t*)q->payload;
+  /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */
+  while((q != NULL) && (options[offset] != DHCP_OPTION_END) && (offset < offset_max)) {
+    u8_t op = options[offset];
+    u8_t len;
+    u8_t decode_len = 0;
+    int decode_idx = -1;
+    u16_t val_offset = offset + 2;
+    /* len byte might be in the next pbuf */
+    if (offset + 1 < q->len) {
+      len = options[offset + 1];
+    } else {
+      len = (q->next != NULL ? ((u8_t*)q->next->payload)[0] : 0);
+    }
+    /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */
+    decode_len = len;
+    switch(op) {
+      /* case(DHCP_OPTION_END): handled above */
+      case(DHCP_OPTION_PAD):
+        /* special option: no len encoded */
+        decode_len = len = 0;
+        /* will be increased below */
+        offset--;
+        break;
+      case(DHCP_OPTION_SUBNET_MASK):
+        LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_SUBNET_MASK;
+        break;
+      case(DHCP_OPTION_ROUTER):
+        decode_len = 4; /* only copy the first given router */
+        LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_ROUTER;
+        break;
+      case(DHCP_OPTION_DNS_SERVER):
+        /* special case: there might be more than one server */
+        LWIP_ERROR("len % 4 == 0", len % 4 == 0, return ERR_VAL;);
+        /* limit number of DNS servers */
+        decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS);
+        LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_DNS_SERVER;
+        break;
+      case(DHCP_OPTION_LEASE_TIME):
+        LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_LEASE_TIME;
+        break;
+      case(DHCP_OPTION_OVERLOAD):
+        LWIP_ERROR("len == 1", len == 1, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_OVERLOAD;
+        break;
+      case(DHCP_OPTION_MESSAGE_TYPE):
+        LWIP_ERROR("len == 1", len == 1, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_MSG_TYPE;
+        break;
+      case(DHCP_OPTION_SERVER_ID):
+        LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_SERVER_ID;
+        break;
+      case(DHCP_OPTION_T1):
+        LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_T1;
+        break;
+      case(DHCP_OPTION_T2):
+        LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+        decode_idx = DHCP_OPTION_IDX_T2;
+        break;
+      default:
+        decode_len = 0;
+        LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", op));
+        break;
+    }
+    offset += len + 2;
+    if (decode_len > 0) {
+      u32_t value = 0;
+      u16_t copy_len;
+decode_next:
+      LWIP_ASSERT("check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX);
+      if (!dhcp_option_given(dhcp, decode_idx)) {
+        copy_len = LWIP_MIN(decode_len, 4);
+        pbuf_copy_partial(q, &value, copy_len, val_offset);
+        if (decode_len > 4) {
+          /* decode more than one u32_t */
+          LWIP_ERROR("decode_len % 4 == 0", decode_len % 4 == 0, return ERR_VAL;);
+          dhcp_got_option(dhcp, decode_idx);
+          dhcp_set_option_value(dhcp, decode_idx, htonl(value));
+          decode_len -= 4;
+          val_offset += 4;
+          decode_idx++;
+          goto decode_next;
+        } else if (decode_len == 4) {
+          value = ntohl(value);
+        } else {
+          LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;);
+          value = ((u8_t*)&value)[0];
+        }
+        dhcp_got_option(dhcp, decode_idx);
+        dhcp_set_option_value(dhcp, decode_idx, value);
+      }
+    }
+    if (offset >= q->len) {
+      offset -= q->len;
+      offset_max -= q->len;
+      if ((offset < offset_max) && offset_max) {
+        q = q->next;
+        LWIP_ASSERT("next pbuf was null", q);
+        options = (u8_t*)q->payload;
+      } else {
+        // We've run out of bytes, probably no end marker. Don't proceed.
+        break;
+      }
+    }
+  }
+  /* is this an overloaded message? */
+  if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_OVERLOAD)) {
+    u32_t overload = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_OVERLOAD);
+    dhcp_clear_option(dhcp, DHCP_OPTION_IDX_OVERLOAD);
+    if (overload == DHCP_OVERLOAD_FILE) {
+      parse_file_as_options = 1;
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n"));
+    } else if (overload == DHCP_OVERLOAD_SNAME) {
+      parse_sname_as_options = 1;
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n"));
+    } else if (overload == DHCP_OVERLOAD_SNAME_FILE) {
+      parse_sname_as_options = 1;
+      parse_file_as_options = 1;
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n"));
+    } else {
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("invalid overload option: %d\n", (int)overload));
+    }
+#if LWIP_DHCP_BOOTP_FILE
+    if (!parse_file_as_options) {
+      /* only do this for ACK messages */
+      if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) &&
+        (dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK))
+      /* copy bootp file name, don't care for sname (server hostname) */
+      pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN-1, DHCP_FILE_OFS);
+      /* make sure the string is really NULL-terminated */
+      dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0;
+    }
+#endif /* LWIP_DHCP_BOOTP_FILE */
+  }
+  if (parse_file_as_options) {
+    /* if both are overloaded, parse file first and then sname (RFC 2131 ch. 4.1) */
+    parse_file_as_options = 0;
+    options_idx = DHCP_FILE_OFS;
+    options_idx_max = DHCP_FILE_OFS + DHCP_FILE_LEN;
+    goto again;
+  } else if (parse_sname_as_options) {
+    parse_sname_as_options = 0;
+    options_idx = DHCP_SNAME_OFS;
+    options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN;
+    goto again;
+  }
+  return ERR_OK;
+}
+
+/**
+ * If an incoming DHCP message is in response to us, then trigger the state machine
+ */
+static void
+dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
+{
+  struct netif *netif = (struct netif *)arg;
+  struct dhcp *dhcp = netif->dhcp;
+  struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload;
+  u8_t msg_type;
+  u8_t i;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void*)p,
+    ip4_addr1_16(addr), ip4_addr2_16(addr), ip4_addr3_16(addr), ip4_addr4_16(addr), port));
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len));
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len));
+  /* prevent warnings about unused arguments */
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(addr);
+  LWIP_UNUSED_ARG(port);
+
+  LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL);
+
+  if (p->len < DHCP_MIN_REPLY_LEN) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP reply message or pbuf too short\n"));
+    goto free_pbuf_and_return;
+  }
+
+  if (reply_msg->op != DHCP_BOOTREPLY) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op));
+    goto free_pbuf_and_return;
+  }
+  /* iterate through hardware address and match against DHCP message */
+  for (i = 0; i < netif->hwaddr_len; i++) {
+    if (netif->hwaddr[i] != reply_msg->chaddr[i]) {
+      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
+        ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n",
+        (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i]));
+      goto free_pbuf_and_return;
+    }
+  }
+  /* match transaction ID against what we expected */
+  if (ntohl(reply_msg->xid) != dhcp->xid) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
+      ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n",ntohl(reply_msg->xid),dhcp->xid));
+    goto free_pbuf_and_return;
+  }
+  /* option fields could be unfold? */
+  if (dhcp_parse_reply(dhcp, p) != ERR_OK) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
+      ("problem unfolding DHCP message - too short on memory?\n"));
+    goto free_pbuf_and_return;
+  }
+
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n"));
+  /* obtain pointer to DHCP message type */
+  if (!dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE)) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP_OPTION_MESSAGE_TYPE option not found\n"));
+    goto free_pbuf_and_return;
+  }
+
+  /* read DHCP message type */
+  msg_type = (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE);
+  /* message type is DHCP ACK? */
+  if (msg_type == DHCP_ACK) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_ACK received\n"));
+    /* in requesting state? */
+    if (dhcp->state == DHCP_REQUESTING) {
+      dhcp_handle_ack(netif);
+#if DHCP_DOES_ARP_CHECK
+      /* check if the acknowledged lease address is already in use */
+      dhcp_check(netif);
+#else
+      /* bind interface to the acknowledged lease address */
+      dhcp_bind(netif);
+#endif
+    }
+    /* already bound to the given lease address? */
+    else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) {
+      dhcp_bind(netif);
+    }
+  }
+  /* received a DHCP_NAK in appropriate state? */
+  else if ((msg_type == DHCP_NAK) &&
+    ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) ||
+     (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING  ))) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n"));
+    dhcp_handle_nak(netif);
+  }
+  /* received a DHCP_OFFER in DHCP_SELECTING state? */
+  else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_OFFER received in DHCP_SELECTING state\n"));
+    dhcp->request_timeout = 0;
+    /* remember offered lease */
+    dhcp_handle_offer(netif);
+  }
+free_pbuf_and_return:
+  dhcp->msg_in = NULL;
+  pbuf_free(p);
+}
+
+/**
+ * Create a DHCP request, fill in common headers
+ *
+ * @param netif the netif under DHCP control
+ * @param dhcp dhcp control struct
+ * @param message_type message type of the request
+ */
+static err_t
+dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type)
+{
+  u16_t i;
+#ifndef DHCP_GLOBAL_XID
+  /** default global transaction identifier starting value (easy to match
+   *  with a packet analyser). We simply increment for each new request.
+   *  Predefine DHCP_GLOBAL_XID to a better value or a function call to generate one
+   *  at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */
+#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
+  static u32_t xid;
+#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
+  static u32_t xid = 0xABCD0000;
+#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
+#else
+  if (!xid_initialised) {
+    xid = DHCP_GLOBAL_XID;
+    xid_initialised = !xid_initialised;
+  }
+#endif
+  LWIP_ERROR("dhcp_create_msg: netif != NULL", (netif != NULL), return ERR_ARG;);
+  LWIP_ERROR("dhcp_create_msg: dhcp != NULL", (dhcp != NULL), return ERR_VAL;);
+  LWIP_ASSERT("dhcp_create_msg: dhcp->p_out == NULL", dhcp->p_out == NULL);
+  LWIP_ASSERT("dhcp_create_msg: dhcp->msg_out == NULL", dhcp->msg_out == NULL);
+  dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM);
+  if (dhcp->p_out == NULL) {
+    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
+      ("dhcp_create_msg(): could not allocate pbuf\n"));
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg",
+           (dhcp->p_out->len >= sizeof(struct dhcp_msg)));
+
+  /* reuse transaction identifier in retransmissions */
+  if (dhcp->tries == 0) {
+#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
+    xid = LWIP_RAND();
+#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
+    xid++;
+#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
+  }
+  dhcp->xid = xid;
+  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
+              ("transaction id xid(%"X32_F")\n", xid));
+
+  dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload;
+
+  dhcp->msg_out->op = DHCP_BOOTREQUEST;
+  /* TODO: make link layer independent */
+  dhcp->msg_out->htype = DHCP_HTYPE_ETH;
+  dhcp->msg_out->hlen = netif->hwaddr_len;
+  dhcp->msg_out->hops = 0;
+  dhcp->msg_out->xid = htonl(dhcp->xid);
+  dhcp->msg_out->secs = 0;
+  /* we don't need the broadcast flag since we can receive unicast traffic
+     before being fully configured! */
+  dhcp->msg_out->flags = 0;
+  ip_addr_set_zero(&dhcp->msg_out->ciaddr);
+  /* set ciaddr to netif->ip_addr based on message_type and state */
+  if ((message_type == DHCP_INFORM) || (message_type == DHCP_DECLINE) ||
+      ((message_type == DHCP_REQUEST) && /* DHCP_BOUND not used for sending! */
+       ((dhcp->state==DHCP_RENEWING) || dhcp->state==DHCP_REBINDING))) {
+    ip_addr_copy(dhcp->msg_out->ciaddr, netif->ip_addr);
+  }
+  ip_addr_set_zero(&dhcp->msg_out->yiaddr);
+  ip_addr_set_zero(&dhcp->msg_out->siaddr);
+  ip_addr_set_zero(&dhcp->msg_out->giaddr);
+  for (i = 0; i < DHCP_CHADDR_LEN; i++) {
+    /* copy netif hardware address, pad with zeroes */
+    dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len) ? netif->hwaddr[i] : 0/* pad byte*/;
+  }
+  for (i = 0; i < DHCP_SNAME_LEN; i++) {
+    dhcp->msg_out->sname[i] = 0;
+  }
+  for (i = 0; i < DHCP_FILE_LEN; i++) {
+    dhcp->msg_out->file[i] = 0;
+  }
+  dhcp->msg_out->cookie = PP_HTONL(DHCP_MAGIC_COOKIE);
+  dhcp->options_out_len = 0;
+  /* fill options field with an incrementing array (for debugging purposes) */
+  for (i = 0; i < DHCP_OPTIONS_LEN; i++) {
+    dhcp->msg_out->options[i] = (u8_t)i; /* for debugging only, no matter if truncated */
+  }
+  /* Add option MESSAGE_TYPE */
+  dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
+  dhcp_option_byte(dhcp, message_type);
+  return ERR_OK;
+}
+
+/**
+ * Free previously allocated memory used to send a DHCP request.
+ *
+ * @param dhcp the dhcp struct to free the request from
+ */
+static void
+dhcp_delete_msg(struct dhcp *dhcp)
+{
+  LWIP_ERROR("dhcp_delete_msg: dhcp != NULL", (dhcp != NULL), return;);
+  LWIP_ASSERT("dhcp_delete_msg: dhcp->p_out != NULL", dhcp->p_out != NULL);
+  LWIP_ASSERT("dhcp_delete_msg: dhcp->msg_out != NULL", dhcp->msg_out != NULL);
+  if (dhcp->p_out != NULL) {
+    pbuf_free(dhcp->p_out);
+  }
+  dhcp->p_out = NULL;
+  dhcp->msg_out = NULL;
+}
+
+/**
+ * Add a DHCP message trailer
+ *
+ * Adds the END option to the DHCP message, and if
+ * necessary, up to three padding bytes.
+ *
+ * @param dhcp DHCP state structure
+ */
+static void
+dhcp_option_trailer(struct dhcp *dhcp)
+{
+  LWIP_ERROR("dhcp_option_trailer: dhcp != NULL", (dhcp != NULL), return;);
+  LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL);
+  LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);
+  dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END;
+  /* packet is too small, or not 4 byte aligned? */
+  while (((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) &&
+         (dhcp->options_out_len < DHCP_OPTIONS_LEN)) {
+    /* add a fill/padding byte */
+    dhcp->msg_out->options[dhcp->options_out_len++] = 0;
+  }
+}
+
+#endif /* LWIP_DHCP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/dns.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/dns.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/dns.c	(revision 164)
@@ -0,0 +1,970 @@
+/**
+ * @file
+ * DNS - host name to IP address resolver.
+ *
+ */
+
+/**
+
+ * This file implements a DNS host name to IP address resolver.
+
+ * Port to lwIP from uIP
+ * by Jim Pettinato April 2007
+
+ * uIP version Copyright (c) 2002-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * DNS.C
+ *
+ * The lwIP DNS resolver functions are used to lookup a host name and
+ * map it to a numerical IP address. It maintains a list of resolved
+ * hostnames that can be queried with the dns_lookup() function.
+ * New hostnames can be resolved using the dns_query() function.
+ *
+ * The lwIP version of the resolver also adds a non-blocking version of
+ * gethostbyname() that will work with a raw API application. This function
+ * checks for an IP address string first and converts it if it is valid.
+ * gethostbyname() then does a dns_lookup() to see if the name is 
+ * already in the table. If so, the IP is returned. If not, a query is 
+ * issued and the function returns with a ERR_INPROGRESS status. The app
+ * using the dns client must then go into a waiting state.
+ *
+ * Once a hostname has been resolved (or found to be non-existent),
+ * the resolver code calls a specified callback function (which 
+ * must be implemented by the module that uses the resolver).
+ */
+
+/*-----------------------------------------------------------------------------
+ * RFC 1035 - Domain names - implementation and specification
+ * RFC 2181 - Clarifications to the DNS Specification
+ *----------------------------------------------------------------------------*/
+
+/** @todo: define good default values (rfc compliance) */
+/** @todo: improve answer parsing, more checkings... */
+/** @todo: check RFC1035 - 7.3. Processing responses */
+
+/*-----------------------------------------------------------------------------
+ * Includes
+ *----------------------------------------------------------------------------*/
+
+#include "lwip/opt.h"
+
+#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/udp.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/dns.h"
+
+#include <string.h>
+
+/** DNS server IP address */
+#ifndef DNS_SERVER_ADDRESS
+#define DNS_SERVER_ADDRESS(ipaddr)        (ip4_addr_set_u32(ipaddr, ipaddr_addr("208.67.222.222"))) /* resolver1.opendns.com */
+#endif
+
+/** DNS server port address */
+#ifndef DNS_SERVER_PORT
+#define DNS_SERVER_PORT           53
+#endif
+
+/** DNS maximum number of retries when asking for a name, before "timeout". */
+#ifndef DNS_MAX_RETRIES
+#define DNS_MAX_RETRIES           4
+#endif
+
+/** DNS resource record max. TTL (one week as default) */
+#ifndef DNS_MAX_TTL
+#define DNS_MAX_TTL               604800
+#endif
+
+/* DNS protocol flags */
+#define DNS_FLAG1_RESPONSE        0x80
+#define DNS_FLAG1_OPCODE_STATUS   0x10
+#define DNS_FLAG1_OPCODE_INVERSE  0x08
+#define DNS_FLAG1_OPCODE_STANDARD 0x00
+#define DNS_FLAG1_AUTHORATIVE     0x04
+#define DNS_FLAG1_TRUNC           0x02
+#define DNS_FLAG1_RD              0x01
+#define DNS_FLAG2_RA              0x80
+#define DNS_FLAG2_ERR_MASK        0x0f
+#define DNS_FLAG2_ERR_NONE        0x00
+#define DNS_FLAG2_ERR_NAME        0x03
+
+/* DNS protocol states */
+#define DNS_STATE_UNUSED          0
+#define DNS_STATE_NEW             1
+#define DNS_STATE_ASKING          2
+#define DNS_STATE_DONE            3
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+/** DNS message header */
+struct dns_hdr {
+  PACK_STRUCT_FIELD(u16_t id);
+  PACK_STRUCT_FIELD(u8_t flags1);
+  PACK_STRUCT_FIELD(u8_t flags2);
+  PACK_STRUCT_FIELD(u16_t numquestions);
+  PACK_STRUCT_FIELD(u16_t numanswers);
+  PACK_STRUCT_FIELD(u16_t numauthrr);
+  PACK_STRUCT_FIELD(u16_t numextrarr);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+#define SIZEOF_DNS_HDR 12
+
+/** DNS query message structure.
+    No packing needed: only used locally on the stack. */
+struct dns_query {
+  /* DNS query record starts with either a domain name or a pointer
+     to a name already present somewhere in the packet. */
+  u16_t type;
+  u16_t cls;
+};
+#define SIZEOF_DNS_QUERY 4
+
+/** DNS answer message structure.
+    No packing needed: only used locally on the stack. */
+struct dns_answer {
+  /* DNS answer record starts with either a domain name or a pointer
+     to a name already present somewhere in the packet. */
+  u16_t type;
+  u16_t cls;
+  u32_t ttl;
+  u16_t len;
+};
+#define SIZEOF_DNS_ANSWER 10
+
+/** DNS table entry */
+struct dns_table_entry {
+  u8_t  state;
+  u8_t  numdns;
+  u8_t  tmr;
+  u8_t  retries;
+  u8_t  seqno;
+  u8_t  err;
+  u32_t ttl;
+  char name[DNS_MAX_NAME_LENGTH];
+  ip_addr_t ipaddr;
+  /* pointer to callback on DNS query done */
+  dns_found_callback found;
+  void *arg;
+};
+
+#if DNS_LOCAL_HOSTLIST
+
+#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
+/** Local host-list. For hostnames in this list, no
+ *  external name resolution is performed */
+static struct local_hostlist_entry *local_hostlist_dynamic;
+#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+
+/** Defining this allows the local_hostlist_static to be placed in a different
+ * linker section (e.g. FLASH) */
+#ifndef DNS_LOCAL_HOSTLIST_STORAGE_PRE
+#define DNS_LOCAL_HOSTLIST_STORAGE_PRE static
+#endif /* DNS_LOCAL_HOSTLIST_STORAGE_PRE */
+/** Defining this allows the local_hostlist_static to be placed in a different
+ * linker section (e.g. FLASH) */
+#ifndef DNS_LOCAL_HOSTLIST_STORAGE_POST
+#define DNS_LOCAL_HOSTLIST_STORAGE_POST
+#endif /* DNS_LOCAL_HOSTLIST_STORAGE_POST */
+DNS_LOCAL_HOSTLIST_STORAGE_PRE struct local_hostlist_entry local_hostlist_static[]
+  DNS_LOCAL_HOSTLIST_STORAGE_POST = DNS_LOCAL_HOSTLIST_INIT;
+
+#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+
+static void dns_init_local();
+#endif /* DNS_LOCAL_HOSTLIST */
+
+
+/* forward declarations */
+static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port);
+static void dns_check_entries(void);
+
+/*-----------------------------------------------------------------------------
+ * Globales
+ *----------------------------------------------------------------------------*/
+
+/* DNS variables */
+static struct udp_pcb        *dns_pcb;
+static u8_t                   dns_seqno;
+static struct dns_table_entry dns_table[DNS_TABLE_SIZE];
+static ip_addr_t              dns_servers[DNS_MAX_SERVERS];
+/** Contiguous buffer for processing responses */
+static u8_t                   dns_payload_buffer[LWIP_MEM_ALIGN_BUFFER(DNS_MSG_SIZE)];
+static u8_t*                  dns_payload;
+
+/**
+ * Initialize the resolver: set up the UDP pcb and configure the default server
+ * (DNS_SERVER_ADDRESS).
+ */
+void
+dns_init()
+{
+  ip_addr_t dnsserver;
+
+  dns_payload = (u8_t *)LWIP_MEM_ALIGN(dns_payload_buffer);
+  
+  /* initialize default DNS server address */
+  DNS_SERVER_ADDRESS(&dnsserver);
+
+  LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n"));
+
+  /* if dns client not yet initialized... */
+  if (dns_pcb == NULL) {
+    dns_pcb = udp_new();
+
+    if (dns_pcb != NULL) {
+      /* initialize DNS table not needed (initialized to zero since it is a
+       * global variable) */
+      LWIP_ASSERT("For implicit initialization to work, DNS_STATE_UNUSED needs to be 0",
+        DNS_STATE_UNUSED == 0);
+
+      /* initialize DNS client */
+      udp_bind(dns_pcb, IP_ADDR_ANY, 0);
+      udp_recv(dns_pcb, dns_recv, NULL);
+
+      /* initialize default DNS primary server */
+      dns_setserver(0, &dnsserver);
+    }
+  }
+#if DNS_LOCAL_HOSTLIST
+  dns_init_local();
+#endif
+}
+
+/**
+ * Initialize one of the DNS servers.
+ *
+ * @param numdns the index of the DNS server to set must be < DNS_MAX_SERVERS
+ * @param dnsserver IP address of the DNS server to set
+ */
+void
+dns_setserver(u8_t numdns, ip_addr_t *dnsserver)
+{
+  if ((numdns < DNS_MAX_SERVERS) && (dns_pcb != NULL) &&
+      (dnsserver != NULL) && !ip_addr_isany(dnsserver)) {
+    dns_servers[numdns] = (*dnsserver);
+  }
+}
+
+/**
+ * Obtain one of the currently configured DNS server.
+ *
+ * @param numdns the index of the DNS server
+ * @return IP address of the indexed DNS server or "ip_addr_any" if the DNS
+ *         server has not been configured.
+ */
+ip_addr_t
+dns_getserver(u8_t numdns)
+{
+  if (numdns < DNS_MAX_SERVERS) {
+    return dns_servers[numdns];
+  } else {
+    return *IP_ADDR_ANY;
+  }
+}
+
+/**
+ * The DNS resolver client timer - handle retries and timeouts and should
+ * be called every DNS_TMR_INTERVAL milliseconds (every second by default).
+ */
+void
+dns_tmr(void)
+{
+  if (dns_pcb != NULL) {
+    LWIP_DEBUGF(DNS_DEBUG, ("dns_tmr: dns_check_entries\n"));
+    dns_check_entries();
+  }
+}
+
+#if DNS_LOCAL_HOSTLIST
+static void
+dns_init_local()
+{
+#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT)
+  int i;
+  struct local_hostlist_entry *entry;
+  /* Dynamic: copy entries from DNS_LOCAL_HOSTLIST_INIT to list */
+  struct local_hostlist_entry local_hostlist_init[] = DNS_LOCAL_HOSTLIST_INIT;
+  size_t namelen;
+  for (i = 0; i < sizeof(local_hostlist_init) / sizeof(struct local_hostlist_entry); i++) {
+    struct local_hostlist_entry *init_entry = &local_hostlist_init[i];
+    LWIP_ASSERT("invalid host name (NULL)", init_entry->name != NULL);
+    namelen = strlen(init_entry->name);
+    LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN);
+    entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST);
+    LWIP_ASSERT("mem-error in dns_init_local", entry != NULL);
+    if (entry != NULL) {
+      entry->name = (char*)entry + sizeof(struct local_hostlist_entry);
+      MEMCPY((char*)entry->name, init_entry->name, namelen);
+      ((char*)entry->name)[namelen] = 0;
+      entry->addr = init_entry->addr;
+      entry->next = local_hostlist_dynamic;
+      local_hostlist_dynamic = entry;
+    }
+  }
+#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) */
+}
+
+/**
+ * Scans the local host-list for a hostname.
+ *
+ * @param hostname Hostname to look for in the local host-list
+ * @return The first IP address for the hostname in the local host-list or
+ *         IPADDR_NONE if not found.
+ */
+static u32_t
+dns_lookup_local(const char *hostname)
+{
+#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
+  struct local_hostlist_entry *entry = local_hostlist_dynamic;
+  while(entry != NULL) {
+    if(strcmp(entry->name, hostname) == 0) {
+      return ip4_addr_get_u32(&entry->addr);
+    }
+    entry = entry->next;
+  }
+#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+  int i;
+  for (i = 0; i < sizeof(local_hostlist_static) / sizeof(struct local_hostlist_entry); i++) {
+    if(strcmp(local_hostlist_static[i].name, hostname) == 0) {
+      return ip4_addr_get_u32(&local_hostlist_static[i].addr);
+    }
+  }
+#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+  return IPADDR_NONE;
+}
+
+#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
+/** Remove all entries from the local host-list for a specific hostname
+ * and/or IP addess
+ *
+ * @param hostname hostname for which entries shall be removed from the local
+ *                 host-list
+ * @param addr address for which entries shall be removed from the local host-list
+ * @return the number of removed entries
+ */
+int
+dns_local_removehost(const char *hostname, const ip_addr_t *addr)
+{
+  int removed = 0;
+  struct local_hostlist_entry *entry = local_hostlist_dynamic;
+  struct local_hostlist_entry *last_entry = NULL;
+  while (entry != NULL) {
+    if (((hostname == NULL) || !strcmp(entry->name, hostname)) &&
+        ((addr == NULL) || ip_addr_cmp(&entry->addr, addr))) {
+      struct local_hostlist_entry *free_entry;
+      if (last_entry != NULL) {
+        last_entry->next = entry->next;
+      } else {
+        local_hostlist_dynamic = entry->next;
+      }
+      free_entry = entry;
+      entry = entry->next;
+      memp_free(MEMP_LOCALHOSTLIST, free_entry);
+      removed++;
+    } else {
+      last_entry = entry;
+      entry = entry->next;
+    }
+  }
+  return removed;
+}
+
+/**
+ * Add a hostname/IP address pair to the local host-list.
+ * Duplicates are not checked.
+ *
+ * @param hostname hostname of the new entry
+ * @param addr IP address of the new entry
+ * @return ERR_OK if succeeded or ERR_MEM on memory error
+ */
+err_t
+dns_local_addhost(const char *hostname, const ip_addr_t *addr)
+{
+  struct local_hostlist_entry *entry;
+  size_t namelen;
+  LWIP_ASSERT("invalid host name (NULL)", hostname != NULL);
+  namelen = strlen(hostname);
+  LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN);
+  entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST);
+  if (entry == NULL) {
+    return ERR_MEM;
+  }
+  entry->name = (char*)entry + sizeof(struct local_hostlist_entry);
+  MEMCPY((char*)entry->name, hostname, namelen);
+  ((char*)entry->name)[namelen] = 0;
+  ip_addr_copy(entry->addr, *addr);
+  entry->next = local_hostlist_dynamic;
+  local_hostlist_dynamic = entry;
+  return ERR_OK;
+}
+#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC*/
+#endif /* DNS_LOCAL_HOSTLIST */
+
+/**
+ * Look up a hostname in the array of known hostnames.
+ *
+ * @note This function only looks in the internal array of known
+ * hostnames, it does not send out a query for the hostname if none
+ * was found. The function dns_enqueue() can be used to send a query
+ * for a hostname.
+ *
+ * @param name the hostname to look up
+ * @return the hostname's IP address, as u32_t (instead of ip_addr_t to
+ *         better check for failure: != IPADDR_NONE) or IPADDR_NONE if the hostname
+ *         was not found in the cached dns_table.
+ */
+static u32_t
+dns_lookup(const char *name)
+{
+  u8_t i;
+#if DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN)
+  u32_t addr;
+#endif /* DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) */
+#if DNS_LOCAL_HOSTLIST
+  if ((addr = dns_lookup_local(name)) != IPADDR_NONE) {
+    return addr;
+  }
+#endif /* DNS_LOCAL_HOSTLIST */
+#ifdef DNS_LOOKUP_LOCAL_EXTERN
+  if((addr = DNS_LOOKUP_LOCAL_EXTERN(name)) != IPADDR_NONE) {
+    return addr;
+  }
+#endif /* DNS_LOOKUP_LOCAL_EXTERN */
+
+  /* Walk through name list, return entry if found. If not, return NULL. */
+  for (i = 0; i < DNS_TABLE_SIZE; ++i) {
+    if ((dns_table[i].state == DNS_STATE_DONE) &&
+        (strcmp(name, dns_table[i].name) == 0)) {
+      LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name));
+      ip_addr_debug_print(DNS_DEBUG, &(dns_table[i].ipaddr));
+      LWIP_DEBUGF(DNS_DEBUG, ("\n"));
+      return ip4_addr_get_u32(&dns_table[i].ipaddr);
+    }
+  }
+
+  return IPADDR_NONE;
+}
+
+#if DNS_DOES_NAME_CHECK
+/**
+ * Compare the "dotted" name "query" with the encoded name "response"
+ * to make sure an answer from the DNS server matches the current dns_table
+ * entry (otherwise, answers might arrive late for hostname not on the list
+ * any more).
+ *
+ * @param query hostname (not encoded) from the dns_table
+ * @param response encoded hostname in the DNS response
+ * @return 0: names equal; 1: names differ
+ */
+static u8_t
+dns_compare_name(unsigned char *query, unsigned char *response)
+{
+  unsigned char n;
+
+  do {
+    n = *response++;
+    /** @see RFC 1035 - 4.1.4. Message compression */
+    if ((n & 0xc0) == 0xc0) {
+      /* Compressed name */
+      break;
+    } else {
+      /* Not compressed name */
+      while (n > 0) {
+        if ((*query) != (*response)) {
+          return 1;
+        }
+        ++response;
+        ++query;
+        --n;
+      };
+      ++query;
+    }
+  } while (*response != 0);
+
+  return 0;
+}
+#endif /* DNS_DOES_NAME_CHECK */
+
+/**
+ * Walk through a compact encoded DNS name and return the end of the name.
+ *
+ * @param query encoded DNS name in the DNS server response
+ * @return end of the name
+ */
+static unsigned char *
+dns_parse_name(unsigned char *query)
+{
+  unsigned char n;
+
+  do {
+    n = *query++;
+    /** @see RFC 1035 - 4.1.4. Message compression */
+    if ((n & 0xc0) == 0xc0) {
+      /* Compressed name */
+      break;
+    } else {
+      /* Not compressed name */
+      while (n > 0) {
+        ++query;
+        --n;
+      };
+    }
+  } while (*query != 0);
+
+  return query + 1;
+}
+
+/**
+ * Send a DNS query packet.
+ *
+ * @param numdns index of the DNS server in the dns_servers table
+ * @param name hostname to query
+ * @param id index of the hostname in dns_table, used as transaction ID in the
+ *        DNS query packet
+ * @return ERR_OK if packet is sent; an err_t indicating the problem otherwise
+ */
+static err_t
+dns_send(u8_t numdns, const char* name, u8_t id)
+{
+  err_t err;
+  struct dns_hdr *hdr;
+  struct dns_query qry;
+  struct pbuf *p;
+  char *query, *nptr;
+  const char *pHostname;
+  u8_t n;
+
+  LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n",
+              (u16_t)(numdns), name));
+  LWIP_ASSERT("dns server out of array", numdns < DNS_MAX_SERVERS);
+  LWIP_ASSERT("dns server has no IP address set", !ip_addr_isany(&dns_servers[numdns]));
+
+  /* if here, we have either a new query or a retry on a previous query to process */
+  p = pbuf_alloc(PBUF_TRANSPORT, SIZEOF_DNS_HDR + DNS_MAX_NAME_LENGTH +
+                 SIZEOF_DNS_QUERY, PBUF_RAM);
+  if (p != NULL) {
+    LWIP_ASSERT("pbuf must be in one piece", p->next == NULL);
+    /* fill dns header */
+    hdr = (struct dns_hdr*)p->payload;
+    memset(hdr, 0, SIZEOF_DNS_HDR);
+    hdr->id = htons(id);
+    hdr->flags1 = DNS_FLAG1_RD;
+    hdr->numquestions = PP_HTONS(1);
+    query = (char*)hdr + SIZEOF_DNS_HDR;
+    pHostname = name;
+    --pHostname;
+
+    /* convert hostname into suitable query format. */
+    do {
+      ++pHostname;
+      nptr = query;
+      ++query;
+      for(n = 0; *pHostname != '.' && *pHostname != 0; ++pHostname) {
+        *query = *pHostname;
+        ++query;
+        ++n;
+      }
+      *nptr = n;
+    } while(*pHostname != 0);
+    *query++='\0';
+
+    /* fill dns query */
+    qry.type = PP_HTONS(DNS_RRTYPE_A);
+    qry.cls = PP_HTONS(DNS_RRCLASS_IN);
+    SMEMCPY(query, &qry, SIZEOF_DNS_QUERY);
+
+    /* resize pbuf to the exact dns query */
+    pbuf_realloc(p, (u16_t)((query + SIZEOF_DNS_QUERY) - ((char*)(p->payload))));
+
+    /* connect to the server for faster receiving */
+    udp_connect(dns_pcb, &dns_servers[numdns], DNS_SERVER_PORT);
+    /* send dns packet */
+    err = udp_sendto(dns_pcb, p, &dns_servers[numdns], DNS_SERVER_PORT);
+
+    /* free pbuf */
+    pbuf_free(p);
+  } else {
+    err = ERR_MEM;
+  }
+
+  return err;
+}
+
+/**
+ * dns_check_entry() - see if pEntry has not yet been queried and, if so, sends out a query.
+ * Check an entry in the dns_table:
+ * - send out query for new entries
+ * - retry old pending entries on timeout (also with different servers)
+ * - remove completed entries from the table if their TTL has expired
+ *
+ * @param i index of the dns_table entry to check
+ */
+static void
+dns_check_entry(u8_t i)
+{
+  err_t err;
+  struct dns_table_entry *pEntry = &dns_table[i];
+
+  LWIP_ASSERT("array index out of bounds", i < DNS_TABLE_SIZE);
+
+  switch(pEntry->state) {
+
+    case DNS_STATE_NEW: {
+      /* initialize new entry */
+      pEntry->state   = DNS_STATE_ASKING;
+      pEntry->numdns  = 0;
+      pEntry->tmr     = 1;
+      pEntry->retries = 0;
+      
+      /* send DNS packet for this entry */
+      err = dns_send(pEntry->numdns, pEntry->name, i);
+      if (err != ERR_OK) {
+        LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING,
+                    ("dns_send returned error: %s\n", lwip_strerr(err)));
+      }
+      break;
+    }
+
+    case DNS_STATE_ASKING: {
+      if (--pEntry->tmr == 0) {
+        if (++pEntry->retries == DNS_MAX_RETRIES) {
+          if ((pEntry->numdns+1<DNS_MAX_SERVERS) && !ip_addr_isany(&dns_servers[pEntry->numdns+1])) {
+            /* change of server */
+            pEntry->numdns++;
+            pEntry->tmr     = 1;
+            pEntry->retries = 0;
+            break;
+          } else {
+            LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": timeout\n", pEntry->name));
+            /* call specified callback function if provided */
+            if (pEntry->found)
+              (*pEntry->found)(pEntry->name, NULL, pEntry->arg);
+            /* flush this entry */
+            pEntry->state   = DNS_STATE_UNUSED;
+            pEntry->found   = NULL;
+            break;
+          }
+        }
+
+        /* wait longer for the next retry */
+        pEntry->tmr = pEntry->retries;
+
+        /* send DNS packet for this entry */
+        err = dns_send(pEntry->numdns, pEntry->name, i);
+        if (err != ERR_OK) {
+          LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING,
+                      ("dns_send returned error: %s\n", lwip_strerr(err)));
+        }
+      }
+      break;
+    }
+
+    case DNS_STATE_DONE: {
+      /* if the time to live is nul */
+      if (--pEntry->ttl == 0) {
+        LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": flush\n", pEntry->name));
+        /* flush this entry */
+        pEntry->state = DNS_STATE_UNUSED;
+        pEntry->found = NULL;
+      }
+      break;
+    }
+    case DNS_STATE_UNUSED:
+      /* nothing to do */
+      break;
+    default:
+      LWIP_ASSERT("unknown dns_table entry state:", 0);
+      break;
+  }
+}
+
+/**
+ * Call dns_check_entry for each entry in dns_table - check all entries.
+ */
+static void
+dns_check_entries(void)
+{
+  u8_t i;
+
+  for (i = 0; i < DNS_TABLE_SIZE; ++i) {
+    dns_check_entry(i);
+  }
+}
+
+/**
+ * Receive input function for DNS response packets arriving for the dns UDP pcb.
+ *
+ * @params see udp.h
+ */
+static void
+dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
+{
+  u16_t i;
+  char *pHostname;
+  struct dns_hdr *hdr;
+  struct dns_answer ans;
+  struct dns_table_entry *pEntry;
+  u16_t nquestions, nanswers;
+
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(addr);
+  LWIP_UNUSED_ARG(port);
+
+  /* is the dns message too big ? */
+  if (p->tot_len > DNS_MSG_SIZE) {
+    LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too big\n"));
+    /* free pbuf and return */
+    goto memerr;
+  }
+
+  /* is the dns message big enough ? */
+  if (p->tot_len < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY + SIZEOF_DNS_ANSWER)) {
+    LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too small\n"));
+    /* free pbuf and return */
+    goto memerr;
+  }
+
+  /* copy dns payload inside static buffer for processing */ 
+  if (pbuf_copy_partial(p, dns_payload, p->tot_len, 0) == p->tot_len) {
+    /* The ID in the DNS header should be our entry into the name table. */
+    hdr = (struct dns_hdr*)dns_payload;
+    i = htons(hdr->id);
+    if (i < DNS_TABLE_SIZE) {
+      pEntry = &dns_table[i];
+      if(pEntry->state == DNS_STATE_ASKING) {
+        /* This entry is now completed. */
+        pEntry->state = DNS_STATE_DONE;
+        pEntry->err   = hdr->flags2 & DNS_FLAG2_ERR_MASK;
+
+        /* We only care about the question(s) and the answers. The authrr
+           and the extrarr are simply discarded. */
+        nquestions = htons(hdr->numquestions);
+        nanswers   = htons(hdr->numanswers);
+
+        /* Check for error. If so, call callback to inform. */
+        if (((hdr->flags1 & DNS_FLAG1_RESPONSE) == 0) || (pEntry->err != 0) || (nquestions != 1)) {
+          LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", pEntry->name));
+          /* call callback to indicate error, clean up memory and return */
+          goto responseerr;
+        }
+
+#if DNS_DOES_NAME_CHECK
+        /* Check if the name in the "question" part match with the name in the entry. */
+        if (dns_compare_name((unsigned char *)(pEntry->name), (unsigned char *)dns_payload + SIZEOF_DNS_HDR) != 0) {
+          LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", pEntry->name));
+          /* call callback to indicate error, clean up memory and return */
+          goto responseerr;
+        }
+#endif /* DNS_DOES_NAME_CHECK */
+
+        /* Skip the name in the "question" part */
+        pHostname = (char *) dns_parse_name((unsigned char *)dns_payload + SIZEOF_DNS_HDR) + SIZEOF_DNS_QUERY;
+
+        while (nanswers > 0) {
+          /* skip answer resource record's host name */
+          pHostname = (char *) dns_parse_name((unsigned char *)pHostname);
+
+          /* Check for IP address type and Internet class. Others are discarded. */
+          SMEMCPY(&ans, pHostname, SIZEOF_DNS_ANSWER);
+          if((ans.type == PP_HTONS(DNS_RRTYPE_A)) && (ans.cls == PP_HTONS(DNS_RRCLASS_IN)) &&
+             (ans.len == PP_HTONS(sizeof(ip_addr_t))) ) {
+            /* read the answer resource record's TTL, and maximize it if needed */
+            pEntry->ttl = ntohl(ans.ttl);
+            if (pEntry->ttl > DNS_MAX_TTL) {
+              pEntry->ttl = DNS_MAX_TTL;
+            }
+            /* read the IP address after answer resource record's header */
+            SMEMCPY(&(pEntry->ipaddr), (pHostname+SIZEOF_DNS_ANSWER), sizeof(ip_addr_t));
+            LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = ", pEntry->name));
+            ip_addr_debug_print(DNS_DEBUG, (&(pEntry->ipaddr)));
+            LWIP_DEBUGF(DNS_DEBUG, ("\n"));
+            /* call specified callback function if provided */
+            if (pEntry->found) {
+              (*pEntry->found)(pEntry->name, &pEntry->ipaddr, pEntry->arg);
+            }
+            /* deallocate memory and return */
+            goto memerr;
+          } else {
+            pHostname = pHostname + SIZEOF_DNS_ANSWER + htons(ans.len);
+          }
+          --nanswers;
+        }
+        LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in response\n", pEntry->name));
+        /* call callback to indicate error, clean up memory and return */
+        goto responseerr;
+      }
+    }
+  }
+
+  /* deallocate memory and return */
+  goto memerr;
+
+responseerr:
+  /* ERROR: call specified callback function with NULL as name to indicate an error */
+  if (pEntry->found) {
+    (*pEntry->found)(pEntry->name, NULL, pEntry->arg);
+  }
+  /* flush this entry */
+  pEntry->state = DNS_STATE_UNUSED;
+  pEntry->found = NULL;
+
+memerr:
+  /* free pbuf */
+  pbuf_free(p);
+  return;
+}
+
+/**
+ * Queues a new hostname to resolve and sends out a DNS query for that hostname
+ *
+ * @param name the hostname that is to be queried
+ * @param found a callback founction to be called on success, failure or timeout
+ * @param callback_arg argument to pass to the callback function
+ * @return @return a err_t return code.
+ */
+static err_t
+dns_enqueue(const char *name, dns_found_callback found, void *callback_arg)
+{
+  u8_t i;
+  u8_t lseq, lseqi;
+  struct dns_table_entry *pEntry = NULL;
+  size_t namelen;
+
+  /* search an unused entry, or the oldest one */
+  lseq = lseqi = 0;
+  for (i = 0; i < DNS_TABLE_SIZE; ++i) {
+    pEntry = &dns_table[i];
+    /* is it an unused entry ? */
+    if (pEntry->state == DNS_STATE_UNUSED)
+      break;
+
+    /* check if this is the oldest completed entry */
+    if (pEntry->state == DNS_STATE_DONE) {
+      if ((dns_seqno - pEntry->seqno) > lseq) {
+        lseq = dns_seqno - pEntry->seqno;
+        lseqi = i;
+      }
+    }
+  }
+
+  /* if we don't have found an unused entry, use the oldest completed one */
+  if (i == DNS_TABLE_SIZE) {
+    if ((lseqi >= DNS_TABLE_SIZE) || (dns_table[lseqi].state != DNS_STATE_DONE)) {
+      /* no entry can't be used now, table is full */
+      LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": DNS entries table is full\n", name));
+      return ERR_MEM;
+    } else {
+      /* use the oldest completed one */
+      i = lseqi;
+      pEntry = &dns_table[i];
+    }
+  }
+
+  /* use this entry */
+  LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS entry %"U16_F"\n", name, (u16_t)(i)));
+
+  /* fill the entry */
+  pEntry->state = DNS_STATE_NEW;
+  pEntry->seqno = dns_seqno++;
+  pEntry->found = found;
+  pEntry->arg   = callback_arg;
+  namelen = LWIP_MIN(strlen(name), DNS_MAX_NAME_LENGTH-1);
+  MEMCPY(pEntry->name, name, namelen);
+  pEntry->name[namelen] = 0;
+
+  /* force to send query without waiting timer */
+  dns_check_entry(i);
+
+  /* dns query is enqueued */
+  return ERR_INPROGRESS;
+}
+
+/**
+ * Resolve a hostname (string) into an IP address.
+ * NON-BLOCKING callback version for use with raw API!!!
+ *
+ * Returns immediately with one of err_t return codes:
+ * - ERR_OK if hostname is a valid IP address string or the host
+ *   name is already in the local names table.
+ * - ERR_INPROGRESS enqueue a request to be sent to the DNS server
+ *   for resolution if no errors are present.
+ * - ERR_ARG: dns client not initialized or invalid hostname
+ *
+ * @param hostname the hostname that is to be queried
+ * @param addr pointer to a ip_addr_t where to store the address if it is already
+ *             cached in the dns_table (only valid if ERR_OK is returned!)
+ * @param found a callback function to be called on success, failure or timeout (only if
+ *              ERR_INPROGRESS is returned!)
+ * @param callback_arg argument to pass to the callback function
+ * @return a err_t return code.
+ */
+err_t
+dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found,
+                  void *callback_arg)
+{
+  u32_t ipaddr;
+  /* not initialized or no valid server yet, or invalid addr pointer
+   * or invalid hostname or invalid hostname length */
+  if ((dns_pcb == NULL) || (addr == NULL) ||
+      (!hostname) || (!hostname[0]) ||
+      (strlen(hostname) >= DNS_MAX_NAME_LENGTH)) {
+    return ERR_ARG;
+  }
+
+#if LWIP_HAVE_LOOPIF
+  if (strcmp(hostname, "localhost")==0) {
+    ip_addr_set_loopback(addr);
+    return ERR_OK;
+  }
+#endif /* LWIP_HAVE_LOOPIF */
+
+  /* host name already in octet notation? set ip addr and return ERR_OK */
+  ipaddr = ipaddr_addr(hostname);
+  if (ipaddr == IPADDR_NONE) {
+    /* already have this address cached? */
+    ipaddr = dns_lookup(hostname);
+  }
+  if (ipaddr != IPADDR_NONE) {
+    ip4_addr_set_u32(addr, ipaddr);
+    return ERR_OK;
+  }
+
+  /* queue query with specified callback */
+  return dns_enqueue(hostname, found, callback_arg);
+}
+
+#endif /* LWIP_DNS */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/init.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/init.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/init.c	(revision 164)
@@ -0,0 +1,332 @@
+/**
+ * @file
+ * Modules initialization
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/init.h"
+#include "lwip/stats.h"
+#include "lwip/sys.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/pbuf.h"
+#include "lwip/netif.h"
+#include "lwip/sockets.h"
+#include "lwip/ip.h"
+#include "lwip/raw.h"
+#include "lwip/udp.h"
+#include "lwip/tcp_impl.h"
+#include "lwip/snmp_msg.h"
+#include "lwip/autoip.h"
+#include "lwip/igmp.h"
+#include "lwip/dns.h"
+#include "lwip/timers.h"
+#include "netif/etharp.h"
+#include "lwip/api.h"
+
+/* Compile-time sanity checks for configuration errors.
+ * These can be done independently of LWIP_DEBUG, without penalty.
+ */
+#ifndef BYTE_ORDER
+  #error "BYTE_ORDER is not defined, you have to define it in your cc.h"
+#endif
+#if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV)
+  #error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h"
+#endif
+#if (!LWIP_UDP && LWIP_UDPLITE)
+  #error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h"
+#endif
+#if (!LWIP_UDP && LWIP_SNMP)
+  #error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h"
+#endif
+#if (!LWIP_UDP && LWIP_DHCP)
+  #error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h"
+#endif
+#if (!LWIP_UDP && LWIP_IGMP)
+  #error "If you want to use IGMP, you have to define LWIP_UDP=1 in your lwipopts.h"
+#endif
+#if (!LWIP_UDP && LWIP_SNMP)
+  #error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h"
+#endif
+#if (!LWIP_UDP && LWIP_DNS)
+  #error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h"
+#endif
+#if !MEMP_MEM_MALLOC /* MEMP_NUM_* checks are disabled when not using the pool allocator */
+#if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0))
+  #error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h"
+#endif
+#if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0))
+  #error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h"
+#endif
+#if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0))
+  #error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h"
+#endif
+#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0))
+  #error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h"
+#endif
+#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1))
+  #error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h"
+#endif
+#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0))
+  #error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h"
+#endif
+/* There must be sufficient timeouts, taking into account requirements of the subsystems. */
+#if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT))
+  #error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts"
+#endif
+#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS))
+  #error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!"
+#endif
+#endif /* !MEMP_MEM_MALLOC */
+#if (LWIP_TCP && (TCP_WND > 0xffff))
+  #error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
+#endif
+#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff))
+  #error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
+#endif
+#if (LWIP_TCP && (TCP_SND_QUEUELEN < 2))
+  #error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work"
+#endif
+#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12)))
+  #error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h"
+#endif
+#if (LWIP_TCP && TCP_LISTEN_BACKLOG && (TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff))
+  #error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t"
+#endif
+#if (LWIP_NETIF_API && (NO_SYS==1))
+  #error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h"
+#endif
+#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1))
+  #error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h"
+#endif
+#if (!LWIP_NETCONN && LWIP_SOCKET)
+  #error "If you want to use Socket API, you have to define LWIP_NETCONN=1 in your lwipopts.h"
+#endif
+#if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP)
+  #error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h"
+#endif
+#if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK)
+  #error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h"
+#endif
+#if (!LWIP_ARP && LWIP_AUTOIP)
+  #error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h"
+#endif
+#if (LWIP_SNMP && (SNMP_CONCURRENT_REQUESTS<=0))
+  #error "If you want to use SNMP, you have to define SNMP_CONCURRENT_REQUESTS>=1 in your lwipopts.h"
+#endif
+#if (LWIP_SNMP && (SNMP_TRAP_DESTINATIONS<=0))
+  #error "If you want to use SNMP, you have to define SNMP_TRAP_DESTINATIONS>=1 in your lwipopts.h"
+#endif
+#if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API)))
+  #error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h"
+#endif
+#if (MEM_LIBC_MALLOC && MEM_USE_POOLS)
+  #error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h"
+#endif
+#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS)
+  #error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h"
+#endif
+#if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT)
+  #error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf"
+#endif
+#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT)))
+  #error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST"
+#endif
+#if PPP_SUPPORT && !PPPOS_SUPPORT & !PPPOE_SUPPORT
+  #error "PPP_SUPPORT needs either PPPOS_SUPPORT or PPPOE_SUPPORT turned on"
+#endif
+#if !LWIP_ETHERNET && (LWIP_ARP || PPPOE_SUPPORT)
+  #error "LWIP_ETHERNET needs to be turned on for LWIP_ARP or PPPOE_SUPPORT"
+#endif
+#if LWIP_IGMP && !defined(LWIP_RAND)
+  #error "When using IGMP, LWIP_RAND() needs to be defined to a random-function returning an u32_t random value"
+#endif
+#if LWIP_TCPIP_CORE_LOCKING_INPUT && !LWIP_TCPIP_CORE_LOCKING
+  #error "When using LWIP_TCPIP_CORE_LOCKING_INPUT, LWIP_TCPIP_CORE_LOCKING must be enabled, too"
+#endif
+#if LWIP_TCP && LWIP_NETIF_TX_SINGLE_PBUF && !TCP_OVERSIZE
+  #error "LWIP_NETIF_TX_SINGLE_PBUF needs TCP_OVERSIZE enabled to create single-pbuf TCP packets"
+#endif
+#if IP_FRAG && IP_FRAG_USES_STATIC_BUF && LWIP_NETIF_TX_SINGLE_PBUF
+  #error "LWIP_NETIF_TX_SINGLE_PBUF does not work with IP_FRAG_USES_STATIC_BUF==1 as that creates pbuf queues"
+#endif
+#if LWIP_NETCONN && LWIP_TCP
+#if NETCONN_COPY != TCP_WRITE_FLAG_COPY
+  #error "NETCONN_COPY != TCP_WRITE_FLAG_COPY"
+#endif
+#if NETCONN_MORE != TCP_WRITE_FLAG_MORE
+  #error "NETCONN_MORE != TCP_WRITE_FLAG_MORE"
+#endif
+#endif /* LWIP_NETCONN && LWIP_TCP */ 
+#if LWIP_SOCKET
+/* Check that the SO_* socket options and SOF_* lwIP-internal flags match */
+#if SO_ACCEPTCONN != SOF_ACCEPTCONN
+  #error "SO_ACCEPTCONN != SOF_ACCEPTCONN"
+#endif
+#if SO_REUSEADDR != SOF_REUSEADDR
+  #error "WARNING: SO_REUSEADDR != SOF_REUSEADDR"
+#endif
+#if SO_KEEPALIVE != SOF_KEEPALIVE
+  #error "WARNING: SO_KEEPALIVE != SOF_KEEPALIVE"
+#endif
+#if SO_BROADCAST != SOF_BROADCAST
+  #error "WARNING: SO_BROADCAST != SOF_BROADCAST"
+#endif
+#if SO_LINGER != SOF_LINGER
+  #error "WARNING: SO_LINGER != SOF_LINGER"
+#endif
+#endif /* LWIP_SOCKET */
+
+
+/* Compile-time checks for deprecated options.
+ */
+#ifdef MEMP_NUM_TCPIP_MSG
+  #error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h."
+#endif
+#ifdef MEMP_NUM_API_MSG
+  #error "MEMP_NUM_API_MSG option is deprecated. Remove it from your lwipopts.h."
+#endif
+#ifdef TCP_REXMIT_DEBUG
+  #error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h."
+#endif
+#ifdef RAW_STATS
+  #error "RAW_STATS option is deprecated. Remove it from your lwipopts.h."
+#endif
+#ifdef ETHARP_QUEUE_FIRST
+  #error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h."
+#endif
+#ifdef ETHARP_ALWAYS_INSERT
+  #error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h."
+#endif
+
+#ifndef LWIP_DISABLE_TCP_SANITY_CHECKS
+#define LWIP_DISABLE_TCP_SANITY_CHECKS  0
+#endif
+#ifndef LWIP_DISABLE_MEMP_SANITY_CHECKS
+#define LWIP_DISABLE_MEMP_SANITY_CHECKS 0
+#endif
+
+/* MEMP sanity checks */
+#if !LWIP_DISABLE_MEMP_SANITY_CHECKS
+#if LWIP_NETCONN
+#if MEMP_MEM_MALLOC
+#if !MEMP_NUM_NETCONN && LWIP_SOCKET
+#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN cannot be 0 when using sockets!"
+#endif
+#else /* MEMP_MEM_MALLOC */
+#if MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB)
+#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN. If you know what you are doing, define LWIP_DISABLE_MEMP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#endif /* MEMP_MEM_MALLOC */
+#endif /* LWIP_NETCONN */
+#endif /* !LWIP_DISABLE_MEMP_SANITY_CHECKS */
+
+/* TCP sanity checks */
+#if !LWIP_DISABLE_TCP_SANITY_CHECKS
+#if LWIP_TCP
+#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN)
+  #error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#if TCP_SND_BUF < (2 * TCP_MSS)
+  #error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#if TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS))
+  #error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#if TCP_SNDLOWAT >= TCP_SND_BUF
+  #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN
+  #error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#if !MEMP_MEM_MALLOC && (TCP_WND > (PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - (PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))))
+  #error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#if TCP_WND < TCP_MSS
+  #error "lwip_sanity_check: WARNING: TCP_WND is smaller than MSS. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
+#endif
+#endif /* LWIP_TCP */
+#endif /* !LWIP_DISABLE_TCP_SANITY_CHECKS */
+
+/**
+ * Perform Sanity check of user-configurable values, and initialize all modules.
+ */
+void
+lwip_init(void)
+{
+  /* Modules initialization */
+  stats_init();
+#if !NO_SYS
+  sys_init();
+#endif /* !NO_SYS */
+  mem_init();
+  memp_init();
+  pbuf_init();
+  netif_init();
+#if LWIP_SOCKET
+  lwip_socket_init();
+#endif /* LWIP_SOCKET */
+  ip_init();
+#if LWIP_ARP
+  etharp_init();
+#endif /* LWIP_ARP */
+#if LWIP_RAW
+  raw_init();
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+  udp_init();
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+  tcp_init();
+#endif /* LWIP_TCP */
+#if LWIP_SNMP
+  snmp_init();
+#endif /* LWIP_SNMP */
+#if LWIP_AUTOIP
+  autoip_init();
+#endif /* LWIP_AUTOIP */
+#if LWIP_IGMP
+  igmp_init();
+#endif /* LWIP_IGMP */
+#if LWIP_DNS
+  dns_init();
+#endif /* LWIP_DNS */
+
+#if LWIP_TIMERS
+  sys_timeouts_init();
+#endif /* LWIP_TIMERS */
+}
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/autoip.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/autoip.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/autoip.c	(revision 164)
@@ -0,0 +1,528 @@
+/**
+ * @file
+ * AutoIP Automatic LinkLocal IP Configuration
+ *
+ */
+
+/*
+ *
+ * Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Dominik Spies <kontakt@dspies.de>
+ *
+ * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform
+ * with RFC 3927.
+ *
+ *
+ * Please coordinate changes and requests with Dominik Spies
+ * <kontakt@dspies.de>
+ */
+
+/*******************************************************************************
+ * USAGE:
+ * 
+ * define LWIP_AUTOIP 1  in your lwipopts.h
+ * 
+ * If you don't use tcpip.c (so, don't call, you don't call tcpip_init):
+ * - First, call autoip_init().
+ * - call autoip_tmr() all AUTOIP_TMR_INTERVAL msces,
+ *   that should be defined in autoip.h.
+ *   I recommend a value of 100. The value must divide 1000 with a remainder almost 0.
+ *   Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 ....
+ *
+ * Without DHCP:
+ * - Call autoip_start() after netif_add().
+ * 
+ * With DHCP:
+ * - define LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h.
+ * - Configure your DHCP Client.
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/mem.h"
+#include "lwip/udp.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/autoip.h"
+#include "netif/etharp.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/* 169.254.0.0 */
+#define AUTOIP_NET         0xA9FE0000
+/* 169.254.1.0 */
+#define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100)
+/* 169.254.254.255 */
+#define AUTOIP_RANGE_END   (AUTOIP_NET | 0xFEFF)
+
+
+/** Pseudo random macro based on netif informations.
+ * You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */
+#ifndef LWIP_AUTOIP_RAND
+#define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \
+                                   ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \
+                                   ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \
+                                   ((u32_t)((netif->hwaddr[4]) & 0xff))) + \
+                                   (netif->autoip?netif->autoip->tried_llipaddr:0))
+#endif /* LWIP_AUTOIP_RAND */
+
+/**
+ * Macro that generates the initial IP address to be tried by AUTOIP.
+ * If you want to override this, define it to something else in lwipopts.h.
+ */
+#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR
+#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \
+  htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \
+                 ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))
+#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */
+
+/* static functions */
+static void autoip_handle_arp_conflict(struct netif *netif);
+
+/* creates a pseudo random LL IP-Address for a network interface */
+static void autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr);
+
+/* sends an ARP probe */
+static err_t autoip_arp_probe(struct netif *netif);
+
+/* sends an ARP announce */
+static err_t autoip_arp_announce(struct netif *netif);
+
+/* configure interface for use with current LL IP-Address */
+static err_t autoip_bind(struct netif *netif);
+
+/* start sending probes for llipaddr */
+static void autoip_start_probing(struct netif *netif);
+
+
+/** Set a statically allocated struct autoip to work with.
+ * Using this prevents autoip_start to allocate it using mem_malloc.
+ *
+ * @param netif the netif for which to set the struct autoip
+ * @param dhcp (uninitialised) dhcp struct allocated by the application
+ */
+void
+autoip_set_struct(struct netif *netif, struct autoip *autoip)
+{
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+  LWIP_ASSERT("autoip != NULL", autoip != NULL);
+  LWIP_ASSERT("netif already has a struct autoip set", netif->autoip == NULL);
+
+  /* clear data structure */
+  memset(autoip, 0, sizeof(struct autoip));
+  /* autoip->state = AUTOIP_STATE_OFF; */
+  netif->autoip = autoip;
+}
+
+/** Restart AutoIP client and check the next address (conflict detected)
+ *
+ * @param netif The netif under AutoIP control
+ */
+static void
+autoip_restart(struct netif *netif)
+{
+  netif->autoip->tried_llipaddr++;
+  autoip_start(netif);
+}
+
+/**
+ * Handle a IP address conflict after an ARP conflict detection
+ */
+static void
+autoip_handle_arp_conflict(struct netif *netif)
+{
+  /* Somehow detect if we are defending or retreating */
+  unsigned char defend = 1; /* tbd */
+
+  if (defend) {
+    if (netif->autoip->lastconflict > 0) {
+      /* retreat, there was a conflicting ARP in the last
+       * DEFEND_INTERVAL seconds
+       */
+      LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+        ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
+
+      /* TODO: close all TCP sessions */
+      autoip_restart(netif);
+    } else {
+      LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+        ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
+      autoip_arp_announce(netif);
+      netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
+    }
+  } else {
+    LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+      ("autoip_handle_arp_conflict(): we do not defend, retreating\n"));
+    /* TODO: close all TCP sessions */
+    autoip_restart(netif);
+  }
+}
+
+/**
+ * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255
+ *
+ * @param netif network interface on which create the IP-Address
+ * @param ipaddr ip address to initialize
+ */
+static void
+autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr)
+{
+  /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255
+   * compliant to RFC 3927 Section 2.1
+   * We have 254 * 256 possibilities */
+
+  u32_t addr = ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));
+  addr += netif->autoip->tried_llipaddr;
+  addr = AUTOIP_NET | (addr & 0xffff);
+  /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */ 
+
+  if (addr < AUTOIP_RANGE_START) {
+    addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
+  }
+  if (addr > AUTOIP_RANGE_END) {
+    addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
+  }
+  LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
+    (addr <= AUTOIP_RANGE_END));
+  ip4_addr_set_u32(ipaddr, htonl(addr));
+  
+  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+    ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+    (u16_t)(netif->autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr),
+    ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
+}
+
+/**
+ * Sends an ARP probe from a network interface
+ *
+ * @param netif network interface used to send the probe
+ */
+static err_t
+autoip_arp_probe(struct netif *netif)
+{
+  return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
+    (struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, &ethzero,
+    &netif->autoip->llipaddr, ARP_REQUEST);
+}
+
+/**
+ * Sends an ARP announce from a network interface
+ *
+ * @param netif network interface used to send the announce
+ */
+static err_t
+autoip_arp_announce(struct netif *netif)
+{
+  return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
+    (struct eth_addr *)netif->hwaddr, &netif->autoip->llipaddr, &ethzero,
+    &netif->autoip->llipaddr, ARP_REQUEST);
+}
+
+/**
+ * Configure interface for use with current LL IP-Address
+ *
+ * @param netif network interface to configure with current LL IP-Address
+ */
+static err_t
+autoip_bind(struct netif *netif)
+{
+  struct autoip *autoip = netif->autoip;
+  ip_addr_t sn_mask, gw_addr;
+
+  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
+    ("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+    (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num,
+    ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
+    ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
+
+  IP4_ADDR(&sn_mask, 255, 255, 0, 0);
+  IP4_ADDR(&gw_addr, 0, 0, 0, 0);
+
+  netif_set_ipaddr(netif, &autoip->llipaddr);
+  netif_set_netmask(netif, &sn_mask);
+  netif_set_gw(netif, &gw_addr);  
+
+  /* bring the interface up */
+  netif_set_up(netif);
+
+  return ERR_OK;
+}
+
+/**
+ * Start AutoIP client
+ *
+ * @param netif network interface on which start the AutoIP client
+ */
+err_t
+autoip_start(struct netif *netif)
+{
+  struct autoip *autoip = netif->autoip;
+  err_t result = ERR_OK;
+
+  if (netif_is_up(netif)) {
+    netif_set_down(netif);
+  }
+
+  /* Set IP-Address, Netmask and Gateway to 0 to make sure that
+   * ARP Packets are formed correctly
+   */
+  ip_addr_set_zero(&netif->ip_addr);
+  ip_addr_set_zero(&netif->netmask);
+  ip_addr_set_zero(&netif->gw);
+
+  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+    ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0],
+    netif->name[1], (u16_t)netif->num));
+  if (autoip == NULL) {
+    /* no AutoIP client attached yet? */
+    LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
+      ("autoip_start(): starting new AUTOIP client\n"));
+    autoip = (struct autoip *)mem_malloc(sizeof(struct autoip));
+    if (autoip == NULL) {
+      LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
+        ("autoip_start(): could not allocate autoip\n"));
+      return ERR_MEM;
+    }
+    memset(autoip, 0, sizeof(struct autoip));
+    /* store this AutoIP client in the netif */
+    netif->autoip = autoip;
+    LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip"));
+  } else {
+    autoip->state = AUTOIP_STATE_OFF;
+    autoip->ttw = 0;
+    autoip->sent_num = 0;
+    ip_addr_set_zero(&autoip->llipaddr);
+    autoip->lastconflict = 0;
+  }
+
+  autoip_create_addr(netif, &(autoip->llipaddr));
+  autoip_start_probing(netif);
+
+  return result;
+}
+
+static void
+autoip_start_probing(struct netif *netif)
+{
+  struct autoip *autoip = netif->autoip;
+
+  autoip->state = AUTOIP_STATE_PROBING;
+  autoip->sent_num = 0;
+  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+     ("autoip_start_probing(): changing state to PROBING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+      ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
+      ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
+
+  /* time to wait to first probe, this is randomly
+   * choosen out of 0 to PROBE_WAIT seconds.
+   * compliant to RFC 3927 Section 2.2.1
+   */
+  autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND));
+
+  /*
+   * if we tried more then MAX_CONFLICTS we must limit our rate for
+   * accquiring and probing address
+   * compliant to RFC 3927 Section 2.2.1
+   */
+  if (autoip->tried_llipaddr > MAX_CONFLICTS) {
+    autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
+  }
+}
+
+/**
+ * Handle a possible change in the network configuration.
+ *
+ * If there is an AutoIP address configured, take the interface down
+ * and begin probing with the same address.
+ */
+void
+autoip_network_changed(struct netif *netif)
+{
+  if (netif->autoip && netif->autoip->state != AUTOIP_STATE_OFF) {
+    netif_set_down(netif);
+    autoip_start_probing(netif);
+  }
+}
+
+/**
+ * Stop AutoIP client
+ *
+ * @param netif network interface on which stop the AutoIP client
+ */
+err_t
+autoip_stop(struct netif *netif)
+{
+  netif->autoip->state = AUTOIP_STATE_OFF;
+  netif_set_down(netif);
+  return ERR_OK;
+}
+
+/**
+ * Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds
+ */
+void
+autoip_tmr()
+{
+  struct netif *netif = netif_list;
+  /* loop through netif's */
+  while (netif != NULL) {
+    /* only act on AutoIP configured interfaces */
+    if (netif->autoip != NULL) {
+      if (netif->autoip->lastconflict > 0) {
+        netif->autoip->lastconflict--;
+      }
+
+      LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
+        ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
+        (u16_t)(netif->autoip->state), netif->autoip->ttw));
+
+      switch(netif->autoip->state) {
+        case AUTOIP_STATE_PROBING:
+          if (netif->autoip->ttw > 0) {
+            netif->autoip->ttw--;
+          } else {
+            if (netif->autoip->sent_num >= PROBE_NUM) {
+              netif->autoip->state = AUTOIP_STATE_ANNOUNCING;
+              netif->autoip->sent_num = 0;
+              netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
+              LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+                 ("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+                  ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
+                  ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
+            } else {
+              autoip_arp_probe(netif);
+              LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
+                ("autoip_tmr() PROBING Sent Probe\n"));
+              netif->autoip->sent_num++;
+              /* calculate time to wait to next probe */
+              netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
+                ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
+                PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
+            }
+          }
+          break;
+
+        case AUTOIP_STATE_ANNOUNCING:
+          if (netif->autoip->ttw > 0) {
+            netif->autoip->ttw--;
+          } else {
+            if (netif->autoip->sent_num == 0) {
+             /* We are here the first time, so we waited ANNOUNCE_WAIT seconds
+              * Now we can bind to an IP address and use it.
+              *
+              * autoip_bind calls netif_set_up. This triggers a gratuitous ARP
+              * which counts as an announcement.
+              */
+              autoip_bind(netif);
+            } else {
+              autoip_arp_announce(netif);
+              LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
+                ("autoip_tmr() ANNOUNCING Sent Announce\n"));
+            }
+            netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
+            netif->autoip->sent_num++;
+
+            if (netif->autoip->sent_num >= ANNOUNCE_NUM) {
+                netif->autoip->state = AUTOIP_STATE_BOUND;
+                netif->autoip->sent_num = 0;
+                netif->autoip->ttw = 0;
+                 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+                    ("autoip_tmr(): changing state to BOUND: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+                     ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
+                     ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
+            }
+          }
+          break;
+      }
+    }
+    /* proceed to next network interface */
+    netif = netif->next;
+  }
+}
+
+/**
+ * Handles every incoming ARP Packet, called by etharp_arp_input.
+ *
+ * @param netif network interface to use for autoip processing
+ * @param hdr Incoming ARP packet
+ */
+void
+autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
+{
+  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n"));
+  if ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) {
+   /* when ip.src == llipaddr && hw.src != netif->hwaddr
+    *
+    * when probing  ip.dst == llipaddr && hw.src != netif->hwaddr
+    * we have a conflict and must solve it
+    */
+    ip_addr_t sipaddr, dipaddr;
+    struct eth_addr netifaddr;
+    ETHADDR16_COPY(netifaddr.addr, netif->hwaddr);
+
+    /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without
+     * structure packing (not using structure copy which breaks strict-aliasing rules).
+     */
+    IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
+    IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
+      
+    if ((netif->autoip->state == AUTOIP_STATE_PROBING) ||
+        ((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) &&
+         (netif->autoip->sent_num == 0))) {
+     /* RFC 3927 Section 2.2.1:
+      * from beginning to after ANNOUNCE_WAIT
+      * seconds we have a conflict if
+      * ip.src == llipaddr OR
+      * ip.dst == llipaddr && hw.src != own hwaddr
+      */
+      if ((ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr)) ||
+          (ip_addr_cmp(&dipaddr, &netif->autoip->llipaddr) &&
+           !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) {
+        LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
+          ("autoip_arp_reply(): Probe Conflict detected\n"));
+        autoip_restart(netif);
+      }
+    } else {
+     /* RFC 3927 Section 2.5:
+      * in any state we have a conflict if
+      * ip.src == llipaddr && hw.src != own hwaddr
+      */
+      if (ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr) &&
+          !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
+        LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
+          ("autoip_arp_reply(): Conflicting ARP-Packet detected\n"));
+        autoip_handle_arp_conflict(netif);
+      }
+    }
+  }
+}
+
+#endif /* LWIP_AUTOIP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/icmp.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/icmp.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/icmp.c	(revision 164)
@@ -0,0 +1,339 @@
+/**
+ * @file
+ * ICMP - Internet Control Message Protocol
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/* Some ICMP messages should be passed to the transport protocols. This
+   is not implemented. */
+
+#include "lwip/opt.h"
+
+#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/icmp.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/ip.h"
+#include "lwip/def.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+
+#include <string.h>
+
+/** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be
+ * used to modify and send a response packet (and to 1 if this is not the case,
+ * e.g. when link header is stripped of when receiving) */
+#ifndef LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
+#define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1
+#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
+
+/* The amount of data from the original packet to return in a dest-unreachable */
+#define ICMP_DEST_UNREACH_DATASIZE 8
+
+static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code);
+
+/**
+ * Processes ICMP input packets, called from ip_input().
+ *
+ * Currently only processes icmp echo requests and sends
+ * out the echo response.
+ *
+ * @param p the icmp echo request packet, p->payload pointing to the ip header
+ * @param inp the netif on which this packet was received
+ */
+void
+icmp_input(struct pbuf *p, struct netif *inp)
+{
+  u8_t type;
+#ifdef LWIP_DEBUG
+  u8_t code;
+#endif /* LWIP_DEBUG */
+  struct icmp_echo_hdr *iecho;
+  struct ip_hdr *iphdr;
+  s16_t hlen;
+
+  ICMP_STATS_INC(icmp.recv);
+  snmp_inc_icmpinmsgs();
+
+
+  iphdr = (struct ip_hdr *)p->payload;
+  hlen = IPH_HL(iphdr) * 4;
+  if (pbuf_header(p, -hlen) || (p->tot_len < sizeof(u16_t)*2)) {
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));
+    goto lenerr;
+  }
+
+  type = *((u8_t *)p->payload);
+#ifdef LWIP_DEBUG
+  code = *(((u8_t *)p->payload)+1);
+#endif /* LWIP_DEBUG */
+  switch (type) {
+  case ICMP_ER:
+    /* This is OK, echo reply might have been parsed by a raw PCB
+       (as obviously, an echo request has been sent, too). */
+    break; 
+  case ICMP_ECHO:
+#if !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING
+    {
+      int accepted = 1;
+#if !LWIP_MULTICAST_PING
+      /* multicast destination address? */
+      if (ip_addr_ismulticast(&current_iphdr_dest)) {
+        accepted = 0;
+      }
+#endif /* LWIP_MULTICAST_PING */
+#if !LWIP_BROADCAST_PING
+      /* broadcast destination address? */
+      if (ip_addr_isbroadcast(&current_iphdr_dest, inp)) {
+        accepted = 0;
+      }
+#endif /* LWIP_BROADCAST_PING */
+      /* broadcast or multicast destination address not acceptd? */
+      if (!accepted) {
+        LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast or broadcast pings\n"));
+        ICMP_STATS_INC(icmp.err);
+        pbuf_free(p);
+        return;
+      }
+    }
+#endif /* !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
+    if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
+      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
+      goto lenerr;
+    }
+    if (inet_chksum_pbuf(p) != 0) {
+      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
+      pbuf_free(p);
+      ICMP_STATS_INC(icmp.chkerr);
+      snmp_inc_icmpinerrors();
+      return;
+    }
+#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
+    if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN))) {
+      /* p is not big enough to contain link headers
+       * allocate a new one and copy p into it
+       */
+      struct pbuf *r;
+      /* switch p->payload to ip header */
+      if (pbuf_header(p, hlen)) {
+        LWIP_ASSERT("icmp_input: moving p->payload to ip header failed\n", 0);
+        goto memerr;
+      }
+      /* allocate new packet buffer with space for link headers */
+      r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
+      if (r == NULL) {
+        LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n"));
+        goto memerr;
+      }
+      LWIP_ASSERT("check that first pbuf can hold struct the ICMP header",
+                  (r->len >= hlen + sizeof(struct icmp_echo_hdr)));
+      /* copy the whole packet including ip header */
+      if (pbuf_copy(r, p) != ERR_OK) {
+        LWIP_ASSERT("icmp_input: copying to new pbuf failed\n", 0);
+        goto memerr;
+      }
+      iphdr = (struct ip_hdr *)r->payload;
+      /* switch r->payload back to icmp header */
+      if (pbuf_header(r, -hlen)) {
+        LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0);
+        goto memerr;
+      }
+      /* free the original p */
+      pbuf_free(p);
+      /* we now have an identical copy of p that has room for link headers */
+      p = r;
+    } else {
+      /* restore p->payload to point to icmp header */
+      if (pbuf_header(p, -(s16_t)(PBUF_IP_HLEN + PBUF_LINK_HLEN))) {
+        LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0);
+        goto memerr;
+      }
+    }
+#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
+    /* At this point, all checks are OK. */
+    /* We generate an answer by switching the dest and src ip addresses,
+     * setting the icmp type to ECHO_RESPONSE and updating the checksum. */
+    iecho = (struct icmp_echo_hdr *)p->payload;
+    ip_addr_copy(iphdr->src, *ip_current_dest_addr());
+    ip_addr_copy(iphdr->dest, *ip_current_src_addr());
+    ICMPH_TYPE_SET(iecho, ICMP_ER);
+#if CHECKSUM_GEN_ICMP
+    /* adjust the checksum */
+    if (iecho->chksum >= PP_HTONS(0xffffU - (ICMP_ECHO << 8))) {
+      iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1;
+    } else {
+      iecho->chksum += PP_HTONS(ICMP_ECHO << 8);
+    }
+#else /* CHECKSUM_GEN_ICMP */
+    iecho->chksum = 0;
+#endif /* CHECKSUM_GEN_ICMP */
+
+    /* Set the correct TTL and recalculate the header checksum. */
+    IPH_TTL_SET(iphdr, ICMP_TTL);
+    IPH_CHKSUM_SET(iphdr, 0);
+#if CHECKSUM_GEN_IP
+    IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
+#endif /* CHECKSUM_GEN_IP */
+
+    ICMP_STATS_INC(icmp.xmit);
+    /* increase number of messages attempted to send */
+    snmp_inc_icmpoutmsgs();
+    /* increase number of echo replies attempted to send */
+    snmp_inc_icmpoutechoreps();
+
+    if(pbuf_header(p, hlen)) {
+      LWIP_ASSERT("Can't move over header in packet", 0);
+    } else {
+      err_t ret;
+      /* send an ICMP packet, src addr is the dest addr of the curren packet */
+      ret = ip_output_if(p, ip_current_dest_addr(), IP_HDRINCL,
+                   ICMP_TTL, 0, IP_PROTO_ICMP, inp);
+      if (ret != ERR_OK) {
+        LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %c.\n", ret));
+      }
+    }
+    break;
+  default:
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n", 
+                (s16_t)type, (s16_t)code));
+    ICMP_STATS_INC(icmp.proterr);
+    ICMP_STATS_INC(icmp.drop);
+  }
+  pbuf_free(p);
+  return;
+lenerr:
+  pbuf_free(p);
+  ICMP_STATS_INC(icmp.lenerr);
+  snmp_inc_icmpinerrors();
+  return;
+#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
+memerr:
+  pbuf_free(p);
+  ICMP_STATS_INC(icmp.err);
+  snmp_inc_icmpinerrors();
+  return;
+#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
+}
+
+/**
+ * Send an icmp 'destination unreachable' packet, called from ip_input() if
+ * the transport layer protocol is unknown and from udp_input() if the local
+ * port is not bound.
+ *
+ * @param p the input packet for which the 'unreachable' should be sent,
+ *          p->payload pointing to the IP header
+ * @param t type of the 'unreachable' packet
+ */
+void
+icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
+{
+  icmp_send_response(p, ICMP_DUR, t);
+}
+
+#if IP_FORWARD || IP_REASSEMBLY
+/**
+ * Send a 'time exceeded' packet, called from ip_forward() if TTL is 0.
+ *
+ * @param p the input packet for which the 'time exceeded' should be sent,
+ *          p->payload pointing to the IP header
+ * @param t type of the 'time exceeded' packet
+ */
+void
+icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
+{
+  icmp_send_response(p, ICMP_TE, t);
+}
+
+#endif /* IP_FORWARD || IP_REASSEMBLY */
+
+/**
+ * Send an icmp packet in response to an incoming packet.
+ *
+ * @param p the input packet for which the 'unreachable' should be sent,
+ *          p->payload pointing to the IP header
+ * @param type Type of the ICMP header
+ * @param code Code of the ICMP header
+ */
+static void
+icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
+{
+  struct pbuf *q;
+  struct ip_hdr *iphdr;
+  /* we can use the echo header here */
+  struct icmp_echo_hdr *icmphdr;
+  ip_addr_t iphdr_src;
+
+  /* ICMP header + IP header + 8 bytes of data */
+  q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE,
+                 PBUF_RAM);
+  if (q == NULL) {
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n"));
+    return;
+  }
+  LWIP_ASSERT("check that first pbuf can hold icmp message",
+             (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE)));
+
+  iphdr = (struct ip_hdr *)p->payload;
+  LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from "));
+  ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src));
+  LWIP_DEBUGF(ICMP_DEBUG, (" to "));
+  ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest));
+  LWIP_DEBUGF(ICMP_DEBUG, ("\n"));
+
+  icmphdr = (struct icmp_echo_hdr *)q->payload;
+  icmphdr->type = type;
+  icmphdr->code = code;
+  icmphdr->id = 0;
+  icmphdr->seqno = 0;
+
+  /* copy fields from original packet */
+  SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload,
+          IP_HLEN + ICMP_DEST_UNREACH_DATASIZE);
+
+  /* calculate checksum */
+  icmphdr->chksum = 0;
+  icmphdr->chksum = inet_chksum(icmphdr, q->len);
+  ICMP_STATS_INC(icmp.xmit);
+  /* increase number of messages attempted to send */
+  snmp_inc_icmpoutmsgs();
+  /* increase number of destination unreachable messages attempted to send */
+  snmp_inc_icmpouttimeexcds();
+  ip_addr_copy(iphdr_src, iphdr->src);
+  ip_output(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP);
+  pbuf_free(q);
+}
+
+#endif /* LWIP_ICMP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/igmp.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/igmp.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/igmp.c	(revision 164)
@@ -0,0 +1,805 @@
+/**
+ * @file
+ * IGMP - Internet Group Management Protocol
+ *
+ */
+
+/*
+ * Copyright (c) 2002 CITEL Technologies Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is a contribution to the lwIP TCP/IP stack.
+ * The Swedish Institute of Computer Science and Adam Dunkels
+ * are specifically granted permission to redistribute this
+ * source code.
+*/
+
+/*-------------------------------------------------------------
+Note 1)
+Although the rfc requires V1 AND V2 capability
+we will only support v2 since now V1 is very old (August 1989)
+V1 can be added if required
+
+a debug print and statistic have been implemented to
+show this up.
+-------------------------------------------------------------
+-------------------------------------------------------------
+Note 2)
+A query for a specific group address (as opposed to ALLHOSTS)
+has now been implemented as I am unsure if it is required
+
+a debug print and statistic have been implemented to
+show this up.
+-------------------------------------------------------------
+-------------------------------------------------------------
+Note 3)
+The router alert rfc 2113 is implemented in outgoing packets
+but not checked rigorously incoming
+-------------------------------------------------------------
+Steve Reynolds
+------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+ * RFC 988  - Host extensions for IP multicasting                         - V0
+ * RFC 1054 - Host extensions for IP multicasting                         -
+ * RFC 1112 - Host extensions for IP multicasting                         - V1
+ * RFC 2236 - Internet Group Management Protocol, Version 2               - V2  <- this code is based on this RFC (it's the "de facto" standard)
+ * RFC 3376 - Internet Group Management Protocol, Version 3               - V3
+ * RFC 4604 - Using Internet Group Management Protocol Version 3...       - V3+
+ * RFC 2113 - IP Router Alert Option                                      - 
+ *----------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+ * Includes
+ *----------------------------------------------------------------------------*/
+
+#include "lwip/opt.h"
+
+#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/igmp.h"
+#include "lwip/debug.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/ip.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/netif.h"
+#include "lwip/icmp.h"
+#include "lwip/udp.h"
+#include "lwip/tcp.h"
+#include "lwip/stats.h"
+
+#include "string.h"
+
+/* 
+ * IGMP constants
+ */
+#define IGMP_TTL                       1
+#define IGMP_MINLEN                    8
+#define ROUTER_ALERT                   0x9404U
+#define ROUTER_ALERTLEN                4
+
+/*
+ * IGMP message types, including version number.
+ */
+#define IGMP_MEMB_QUERY                0x11 /* Membership query         */
+#define IGMP_V1_MEMB_REPORT            0x12 /* Ver. 1 membership report */
+#define IGMP_V2_MEMB_REPORT            0x16 /* Ver. 2 membership report */
+#define IGMP_LEAVE_GROUP               0x17 /* Leave-group message      */
+
+/* Group  membership states */
+#define IGMP_GROUP_NON_MEMBER          0
+#define IGMP_GROUP_DELAYING_MEMBER     1
+#define IGMP_GROUP_IDLE_MEMBER         2
+
+/**
+ * IGMP packet format.
+ */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct igmp_msg {
+ PACK_STRUCT_FIELD(u8_t           igmp_msgtype);
+ PACK_STRUCT_FIELD(u8_t           igmp_maxresp);
+ PACK_STRUCT_FIELD(u16_t          igmp_checksum);
+ PACK_STRUCT_FIELD(ip_addr_p_t    igmp_group_address);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+
+static struct igmp_group *igmp_lookup_group(struct netif *ifp, ip_addr_t *addr);
+static err_t  igmp_remove_group(struct igmp_group *group);
+static void   igmp_timeout( struct igmp_group *group);
+static void   igmp_start_timer(struct igmp_group *group, u8_t max_time);
+static void   igmp_delaying_member(struct igmp_group *group, u8_t maxresp);
+static err_t  igmp_ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, struct netif *netif);
+static void   igmp_send(struct igmp_group *group, u8_t type);
+
+
+static struct igmp_group* igmp_group_list;
+static ip_addr_t     allsystems;
+static ip_addr_t     allrouters;
+
+
+/**
+ * Initialize the IGMP module
+ */
+void
+igmp_init(void)
+{
+  LWIP_DEBUGF(IGMP_DEBUG, ("igmp_init: initializing\n"));
+
+  IP4_ADDR(&allsystems, 224, 0, 0, 1);
+  IP4_ADDR(&allrouters, 224, 0, 0, 2);
+}
+
+#ifdef LWIP_DEBUG
+/**
+ * Dump global IGMP groups list
+ */
+void
+igmp_dump_group_list()
+{ 
+  struct igmp_group *group = igmp_group_list;
+
+  while (group != NULL) {
+    LWIP_DEBUGF(IGMP_DEBUG, ("igmp_dump_group_list: [%"U32_F"] ", (u32_t)(group->group_state)));
+    ip_addr_debug_print(IGMP_DEBUG, &group->group_address);
+    LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->netif));
+    group = group->next;
+  }
+  LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
+}
+#else
+#define igmp_dump_group_list()
+#endif /* LWIP_DEBUG */
+
+/**
+ * Start IGMP processing on interface
+ *
+ * @param netif network interface on which start IGMP processing
+ */
+err_t
+igmp_start(struct netif *netif)
+{
+  struct igmp_group* group;
+
+  LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: starting IGMP processing on if %p\n", netif));
+
+  group = igmp_lookup_group(netif, &allsystems);
+
+  if (group != NULL) {
+    group->group_state = IGMP_GROUP_IDLE_MEMBER;
+    group->use++;
+
+    /* Allow the igmp messages at the MAC level */
+    if (netif->igmp_mac_filter != NULL) {
+      LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: igmp_mac_filter(ADD "));
+      ip_addr_debug_print(IGMP_DEBUG, &allsystems);
+      LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif));
+      netif->igmp_mac_filter(netif, &allsystems, IGMP_ADD_MAC_FILTER);
+    }
+
+    return ERR_OK;
+  }
+
+  return ERR_MEM;
+}
+
+/**
+ * Stop IGMP processing on interface
+ *
+ * @param netif network interface on which stop IGMP processing
+ */
+err_t
+igmp_stop(struct netif *netif)
+{
+  struct igmp_group *group = igmp_group_list;
+  struct igmp_group *prev  = NULL;
+  struct igmp_group *next;
+
+  /* look for groups joined on this interface further down the list */
+  while (group != NULL) {
+    next = group->next;
+    /* is it a group joined on this interface? */
+    if (group->netif == netif) {
+      /* is it the first group of the list? */
+      if (group == igmp_group_list) {
+        igmp_group_list = next;
+      }
+      /* is there a "previous" group defined? */
+      if (prev != NULL) {
+        prev->next = next;
+      }
+      /* disable the group at the MAC level */
+      if (netif->igmp_mac_filter != NULL) {
+        LWIP_DEBUGF(IGMP_DEBUG, ("igmp_stop: igmp_mac_filter(DEL "));
+        ip_addr_debug_print(IGMP_DEBUG, &group->group_address);
+        LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif));
+        netif->igmp_mac_filter(netif, &(group->group_address), IGMP_DEL_MAC_FILTER);
+      }
+      /* free group */
+      memp_free(MEMP_IGMP_GROUP, group);
+    } else {
+      /* change the "previous" */
+      prev = group;
+    }
+    /* move to "next" */
+    group = next;
+  }
+  return ERR_OK;
+}
+
+/**
+ * Report IGMP memberships for this interface
+ *
+ * @param netif network interface on which report IGMP memberships
+ */
+void
+igmp_report_groups(struct netif *netif)
+{
+  struct igmp_group *group = igmp_group_list;
+
+  LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", netif));
+
+  while (group != NULL) {
+    if (group->netif == netif) {
+      igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
+    }
+    group = group->next;
+  }
+}
+
+/**
+ * Search for a group in the global igmp_group_list
+ *
+ * @param ifp the network interface for which to look
+ * @param addr the group ip address to search for
+ * @return a struct igmp_group* if the group has been found,
+ *         NULL if the group wasn't found.
+ */
+struct igmp_group *
+igmp_lookfor_group(struct netif *ifp, ip_addr_t *addr)
+{
+  struct igmp_group *group = igmp_group_list;
+
+  while (group != NULL) {
+    if ((group->netif == ifp) && (ip_addr_cmp(&(group->group_address), addr))) {
+      return group;
+    }
+    group = group->next;
+  }
+
+  /* to be clearer, we return NULL here instead of
+   * 'group' (which is also NULL at this point).
+   */
+  return NULL;
+}
+
+/**
+ * Search for a specific igmp group and create a new one if not found-
+ *
+ * @param ifp the network interface for which to look
+ * @param addr the group ip address to search
+ * @return a struct igmp_group*,
+ *         NULL on memory error.
+ */
+struct igmp_group *
+igmp_lookup_group(struct netif *ifp, ip_addr_t *addr)
+{
+  struct igmp_group *group = igmp_group_list;
+  
+  /* Search if the group already exists */
+  group = igmp_lookfor_group(ifp, addr);
+  if (group != NULL) {
+    /* Group already exists. */
+    return group;
+  }
+
+  /* Group doesn't exist yet, create a new one */
+  group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP);
+  if (group != NULL) {
+    group->netif              = ifp;
+    ip_addr_set(&(group->group_address), addr);
+    group->timer              = 0; /* Not running */
+    group->group_state        = IGMP_GROUP_NON_MEMBER;
+    group->last_reporter_flag = 0;
+    group->use                = 0;
+    group->next               = igmp_group_list;
+    
+    igmp_group_list = group;
+  }
+
+  LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group?"":"impossible to ")));
+  ip_addr_debug_print(IGMP_DEBUG, addr);
+  LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", ifp));
+
+  return group;
+}
+
+/**
+ * Remove a group in the global igmp_group_list
+ *
+ * @param group the group to remove from the global igmp_group_list
+ * @return ERR_OK if group was removed from the list, an err_t otherwise
+ */
+static err_t
+igmp_remove_group(struct igmp_group *group)
+{
+  err_t err = ERR_OK;
+
+  /* Is it the first group? */
+  if (igmp_group_list == group) {
+    igmp_group_list = group->next;
+  } else {
+    /* look for group further down the list */
+    struct igmp_group *tmpGroup;
+    for (tmpGroup = igmp_group_list; tmpGroup != NULL; tmpGroup = tmpGroup->next) {
+      if (tmpGroup->next == group) {
+        tmpGroup->next = group->next;
+        break;
+      }
+    }
+    /* Group not found in the global igmp_group_list */
+    if (tmpGroup == NULL)
+      err = ERR_ARG;
+  }
+  /* free group */
+  memp_free(MEMP_IGMP_GROUP, group);
+
+  return err;
+}
+
+/**
+ * Called from ip_input() if a new IGMP packet is received.
+ *
+ * @param p received igmp packet, p->payload pointing to the ip header
+ * @param inp network interface on which the packet was received
+ * @param dest destination ip address of the igmp packet
+ */
+void
+igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest)
+{
+  struct ip_hdr *    iphdr;
+  struct igmp_msg*   igmp;
+  struct igmp_group* group;
+  struct igmp_group* groupref;
+
+  IGMP_STATS_INC(igmp.recv);
+
+  /* Note that the length CAN be greater than 8 but only 8 are used - All are included in the checksum */    
+  iphdr = (struct ip_hdr *)p->payload;
+  if (pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4)) || (p->len < IGMP_MINLEN)) {
+    pbuf_free(p);
+    IGMP_STATS_INC(igmp.lenerr);
+    LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: length error\n"));
+    return;
+  }
+
+  LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: message from "));
+  ip_addr_debug_print(IGMP_DEBUG, &(iphdr->src));
+  LWIP_DEBUGF(IGMP_DEBUG, (" to address "));
+  ip_addr_debug_print(IGMP_DEBUG, &(iphdr->dest));
+  LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", inp));
+
+  /* Now calculate and check the checksum */
+  igmp = (struct igmp_msg *)p->payload;
+  if (inet_chksum(igmp, p->len)) {
+    pbuf_free(p);
+    IGMP_STATS_INC(igmp.chkerr);
+    LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: checksum error\n"));
+    return;
+  }
+
+  /* Packet is ok so find an existing group */
+  group = igmp_lookfor_group(inp, dest); /* use the destination IP address of incoming packet */
+  
+  /* If group can be found or create... */
+  if (!group) {
+    pbuf_free(p);
+    IGMP_STATS_INC(igmp.drop);
+    LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n"));
+    return;
+  }
+
+  /* NOW ACT ON THE INCOMING MESSAGE TYPE... */
+  switch (igmp->igmp_msgtype) {
+   case IGMP_MEMB_QUERY: {
+     /* IGMP_MEMB_QUERY to the "all systems" address ? */
+     if ((ip_addr_cmp(dest, &allsystems)) && ip_addr_isany(&igmp->igmp_group_address)) {
+       /* THIS IS THE GENERAL QUERY */
+       LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
+
+       if (igmp->igmp_maxresp == 0) {
+         IGMP_STATS_INC(igmp.rx_v1);
+         LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n"));
+         igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR;
+       } else {
+         IGMP_STATS_INC(igmp.rx_general);
+       }
+
+       groupref = igmp_group_list;
+       while (groupref) {
+         /* Do not send messages on the all systems group address! */
+         if ((groupref->netif == inp) && (!(ip_addr_cmp(&(groupref->group_address), &allsystems)))) {
+           igmp_delaying_member(groupref, igmp->igmp_maxresp);
+         }
+         groupref = groupref->next;
+       }
+     } else {
+       /* IGMP_MEMB_QUERY to a specific group ? */
+       if (!ip_addr_isany(&igmp->igmp_group_address)) {
+         LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_MEMB_QUERY to a specific group "));
+         ip_addr_debug_print(IGMP_DEBUG, &igmp->igmp_group_address);
+         if (ip_addr_cmp(dest, &allsystems)) {
+           ip_addr_t groupaddr;
+           LWIP_DEBUGF(IGMP_DEBUG, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
+           /* we first need to re-look for the group since we used dest last time */
+           ip_addr_copy(groupaddr, igmp->igmp_group_address);
+           group = igmp_lookfor_group(inp, &groupaddr);
+         } else {
+           LWIP_DEBUGF(IGMP_DEBUG, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
+         }
+
+         if (group != NULL) {
+           IGMP_STATS_INC(igmp.rx_group);
+           igmp_delaying_member(group, igmp->igmp_maxresp);
+         } else {
+           IGMP_STATS_INC(igmp.drop);
+         }
+       } else {
+         IGMP_STATS_INC(igmp.proterr);
+       }
+     }
+     break;
+   }
+   case IGMP_V2_MEMB_REPORT: {
+     LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n"));
+     IGMP_STATS_INC(igmp.rx_report);
+     if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) {
+       /* This is on a specific group we have already looked up */
+       group->timer = 0; /* stopped */
+       group->group_state = IGMP_GROUP_IDLE_MEMBER;
+       group->last_reporter_flag = 0;
+     }
+     break;
+   }
+   default: {
+     LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n",
+       igmp->igmp_msgtype, group->group_state, &group, group->netif));
+     IGMP_STATS_INC(igmp.proterr);
+     break;
+   }
+  }
+
+  pbuf_free(p);
+  return;
+}
+
+/**
+ * Join a group on one network interface.
+ *
+ * @param ifaddr ip address of the network interface which should join a new group
+ * @param groupaddr the ip address of the group which to join
+ * @return ERR_OK if group was joined on the netif(s), an err_t otherwise
+ */
+err_t
+igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr)
+{
+  err_t              err = ERR_VAL; /* no matching interface */
+  struct igmp_group *group;
+  struct netif      *netif;
+
+  /* make sure it is multicast address */
+  LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;);
+  LWIP_ERROR("igmp_joingroup: attempt to join allsystems address", (!ip_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
+
+  /* loop through netif's */
+  netif = netif_list;
+  while (netif != NULL) {
+    /* Should we join this interface ? */
+    if ((netif->flags & NETIF_FLAG_IGMP) && ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr)))) {
+      /* find group or create a new one if not found */
+      group = igmp_lookup_group(netif, groupaddr);
+
+      if (group != NULL) {
+        /* This should create a new group, check the state to make sure */
+        if (group->group_state != IGMP_GROUP_NON_MEMBER) {
+          LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to group not in state IGMP_GROUP_NON_MEMBER\n"));
+        } else {
+          /* OK - it was new group */
+          LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to new group: "));
+          ip_addr_debug_print(IGMP_DEBUG, groupaddr);
+          LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
+
+          /* If first use of the group, allow the group at the MAC level */
+          if ((group->use==0) && (netif->igmp_mac_filter != NULL)) {
+            LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: igmp_mac_filter(ADD "));
+            ip_addr_debug_print(IGMP_DEBUG, groupaddr);
+            LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif));
+            netif->igmp_mac_filter(netif, groupaddr, IGMP_ADD_MAC_FILTER);
+          }
+
+          IGMP_STATS_INC(igmp.tx_join);
+          igmp_send(group, IGMP_V2_MEMB_REPORT);
+
+          igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
+
+          /* Need to work out where this timer comes from */
+          group->group_state = IGMP_GROUP_DELAYING_MEMBER;
+        }
+        /* Increment group use */
+        group->use++;
+        /* Join on this interface */
+        err = ERR_OK;
+      } else {
+        /* Return an error even if some network interfaces are joined */
+        /** @todo undo any other netif already joined */
+        LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: Not enought memory to join to group\n"));
+        return ERR_MEM;
+      }
+    }
+    /* proceed to next network interface */
+    netif = netif->next;
+  }
+
+  return err;
+}
+
+/**
+ * Leave a group on one network interface.
+ *
+ * @param ifaddr ip address of the network interface which should leave a group
+ * @param groupaddr the ip address of the group which to leave
+ * @return ERR_OK if group was left on the netif(s), an err_t otherwise
+ */
+err_t
+igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr)
+{
+  err_t              err = ERR_VAL; /* no matching interface */
+  struct igmp_group *group;
+  struct netif      *netif;
+
+  /* make sure it is multicast address */
+  LWIP_ERROR("igmp_leavegroup: attempt to leave non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;);
+  LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
+
+  /* loop through netif's */
+  netif = netif_list;
+  while (netif != NULL) {
+    /* Should we leave this interface ? */
+    if ((netif->flags & NETIF_FLAG_IGMP) && ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr)))) {
+      /* find group */
+      group = igmp_lookfor_group(netif, groupaddr);
+
+      if (group != NULL) {
+        /* Only send a leave if the flag is set according to the state diagram */
+        LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: Leaving group: "));
+        ip_addr_debug_print(IGMP_DEBUG, groupaddr);
+        LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
+
+        /* If there is no other use of the group */
+        if (group->use <= 1) {
+          /* If we are the last reporter for this group */
+          if (group->last_reporter_flag) {
+            LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: sending leaving group\n"));
+            IGMP_STATS_INC(igmp.tx_leave);
+            igmp_send(group, IGMP_LEAVE_GROUP);
+          }
+          
+          /* Disable the group at the MAC level */
+          if (netif->igmp_mac_filter != NULL) {
+            LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: igmp_mac_filter(DEL "));
+            ip_addr_debug_print(IGMP_DEBUG, groupaddr);
+            LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif));
+            netif->igmp_mac_filter(netif, groupaddr, IGMP_DEL_MAC_FILTER);
+          }
+          
+          LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: remove group: "));
+          ip_addr_debug_print(IGMP_DEBUG, groupaddr);
+          LWIP_DEBUGF(IGMP_DEBUG, ("\n"));          
+          
+          /* Free the group */
+          igmp_remove_group(group);
+        } else {
+          /* Decrement group use */
+          group->use--;
+        }
+        /* Leave on this interface */
+        err = ERR_OK;
+      } else {
+        /* It's not a fatal error on "leavegroup" */
+        LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: not member of group\n"));
+      }
+    }
+    /* proceed to next network interface */
+    netif = netif->next;
+  }
+
+  return err;
+}
+
+/**
+ * The igmp timer function (both for NO_SYS=1 and =0)
+ * Should be called every IGMP_TMR_INTERVAL milliseconds (100 ms is default).
+ */
+void
+igmp_tmr(void)
+{
+  struct igmp_group *group = igmp_group_list;
+
+  while (group != NULL) {
+    if (group->timer > 0) {
+      group->timer--;
+      if (group->timer == 0) {
+        igmp_timeout(group);
+      }
+    }
+    group = group->next;
+  }
+}
+
+/**
+ * Called if a timeout for one group is reached.
+ * Sends a report for this group.
+ *
+ * @param group an igmp_group for which a timeout is reached
+ */
+static void
+igmp_timeout(struct igmp_group *group)
+{
+  /* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group */
+  if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) {
+    LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address "));
+    ip_addr_debug_print(IGMP_DEBUG, &(group->group_address));
+    LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->netif));
+
+    IGMP_STATS_INC(igmp.tx_report);
+    igmp_send(group, IGMP_V2_MEMB_REPORT);
+  }
+}
+
+/**
+ * Start a timer for an igmp group
+ *
+ * @param group the igmp_group for which to start a timer
+ * @param max_time the time in multiples of IGMP_TMR_INTERVAL (decrease with
+ *        every call to igmp_tmr())
+ */
+static void
+igmp_start_timer(struct igmp_group *group, u8_t max_time)
+{
+  /* ensure the input value is > 0 */
+  if (max_time <= 1) {
+    max_time = 2;
+  }
+  /* ensure the random value is > 0 */
+  group->timer = (LWIP_RAND() % (max_time - 1)) + 1;
+}
+
+/**
+ * Delaying membership report for a group if necessary
+ *
+ * @param group the igmp_group for which "delaying" membership report
+ * @param maxresp query delay
+ */
+static void
+igmp_delaying_member(struct igmp_group *group, u8_t maxresp)
+{
+  if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) ||
+     ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) &&
+      ((group->timer == 0) || (maxresp < group->timer)))) {
+    igmp_start_timer(group, maxresp);
+    group->group_state = IGMP_GROUP_DELAYING_MEMBER;
+  }
+}
+
+
+/**
+ * Sends an IP packet on a network interface. This function constructs the IP header
+ * and calculates the IP header checksum. If the source IP address is NULL,
+ * the IP address of the outgoing network interface is filled in as source address.
+ *
+ * @param p the packet to send (p->payload points to the data, e.g. next
+            protocol header; if dest == IP_HDRINCL, p already includes an IP
+            header and p->payload points to that IP header)
+ * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
+ *         IP  address of the netif used to send is used as source address)
+ * @param dest the destination IP address to send the packet to
+ * @param ttl the TTL value to be set in the IP header
+ * @param proto the PROTOCOL to be set in the IP header
+ * @param netif the netif on which to send this packet
+ * @return ERR_OK if the packet was sent OK
+ *         ERR_BUF if p doesn't have enough space for IP/LINK headers
+ *         returns errors returned by netif->output
+ */
+static err_t
+igmp_ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, struct netif *netif)
+{
+  /* This is the "router alert" option */
+  u16_t ra[2];
+  ra[0] = PP_HTONS(ROUTER_ALERT);
+  ra[1] = 0x0000; /* Router shall examine packet */
+  IGMP_STATS_INC(igmp.xmit);
+  return ip_output_if_opt(p, src, dest, IGMP_TTL, 0, IP_PROTO_IGMP, netif, ra, ROUTER_ALERTLEN);
+}
+
+/**
+ * Send an igmp packet to a specific group.
+ *
+ * @param group the group to which to send the packet
+ * @param type the type of igmp packet to send
+ */
+static void
+igmp_send(struct igmp_group *group, u8_t type)
+{
+  struct pbuf*     p    = NULL;
+  struct igmp_msg* igmp = NULL;
+  ip_addr_t   src  = *IP_ADDR_ANY;
+  ip_addr_t*  dest = NULL;
+
+  /* IP header + "router alert" option + IGMP header */
+  p = pbuf_alloc(PBUF_TRANSPORT, IGMP_MINLEN, PBUF_RAM);
+  
+  if (p) {
+    igmp = (struct igmp_msg *)p->payload;
+    LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg",
+               (p->len >= sizeof(struct igmp_msg)));
+    ip_addr_copy(src, group->netif->ip_addr);
+     
+    if (type == IGMP_V2_MEMB_REPORT) {
+      dest = &(group->group_address);
+      ip_addr_copy(igmp->igmp_group_address, group->group_address);
+      group->last_reporter_flag = 1; /* Remember we were the last to report */
+    } else {
+      if (type == IGMP_LEAVE_GROUP) {
+        dest = &allrouters;
+        ip_addr_copy(igmp->igmp_group_address, group->group_address);
+      }
+    }
+
+    if ((type == IGMP_V2_MEMB_REPORT) || (type == IGMP_LEAVE_GROUP)) {
+      igmp->igmp_msgtype  = type;
+      igmp->igmp_maxresp  = 0;
+      igmp->igmp_checksum = 0;
+      igmp->igmp_checksum = inet_chksum(igmp, IGMP_MINLEN);
+
+      igmp_ip_output_if(p, &src, dest, group->netif);
+    }
+
+    pbuf_free(p);
+  } else {
+    LWIP_DEBUGF(IGMP_DEBUG, ("igmp_send: not enough memory for igmp_send\n"));
+    IGMP_STATS_INC(igmp.memerr);
+  }
+}
+
+#endif /* LWIP_IGMP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/inet.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/inet.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/inet.c	(revision 164)
@@ -0,0 +1,42 @@
+/**
+ * @file
+ * Functions common to all TCP/IPv4 modules, such as the byte order functions.
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/inet.h"
+
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/inet_chksum.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/inet_chksum.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/inet_chksum.c	(revision 164)
@@ -0,0 +1,450 @@
+/**
+ * @file
+ * Incluse internet checksum functions.
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/inet_chksum.h"
+#include "lwip/def.h"
+
+#include <stddef.h>
+#include <string.h>
+
+/* These are some reference implementations of the checksum algorithm, with the
+ * aim of being simple, correct and fully portable. Checksumming is the
+ * first thing you would want to optimize for your platform. If you create
+ * your own version, link it in and in your cc.h put:
+ * 
+ * #define LWIP_CHKSUM <your_checksum_routine> 
+ *
+ * Or you can select from the implementations below by defining
+ * LWIP_CHKSUM_ALGORITHM to 1, 2 or 3.
+ */
+
+#ifndef LWIP_CHKSUM
+# define LWIP_CHKSUM lwip_standard_chksum
+# ifndef LWIP_CHKSUM_ALGORITHM
+#  define LWIP_CHKSUM_ALGORITHM 2
+# endif
+#endif
+/* If none set: */
+#ifndef LWIP_CHKSUM_ALGORITHM
+# define LWIP_CHKSUM_ALGORITHM 0
+#endif
+
+#if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */
+/**
+ * lwip checksum
+ *
+ * @param dataptr points to start of data to be summed at any boundary
+ * @param len length of data to be summed
+ * @return host order (!) lwip checksum (non-inverted Internet sum) 
+ *
+ * @note accumulator size limits summable length to 64k
+ * @note host endianess is irrelevant (p3 RFC1071)
+ */
+static u16_t
+lwip_standard_chksum(void *dataptr, u16_t len)
+{
+  u32_t acc;
+  u16_t src;
+  u8_t *octetptr;
+
+  acc = 0;
+  /* dataptr may be at odd or even addresses */
+  octetptr = (u8_t*)dataptr;
+  while (len > 1) {
+    /* declare first octet as most significant
+       thus assume network order, ignoring host order */
+    src = (*octetptr) << 8;
+    octetptr++;
+    /* declare second octet as least significant */
+    src |= (*octetptr);
+    octetptr++;
+    acc += src;
+    len -= 2;
+  }
+  if (len > 0) {
+    /* accumulate remaining octet */
+    src = (*octetptr) << 8;
+    acc += src;
+  }
+  /* add deferred carry bits */
+  acc = (acc >> 16) + (acc & 0x0000ffffUL);
+  if ((acc & 0xffff0000UL) != 0) {
+    acc = (acc >> 16) + (acc & 0x0000ffffUL);
+  }
+  /* This maybe a little confusing: reorder sum using htons()
+     instead of ntohs() since it has a little less call overhead.
+     The caller must invert bits for Internet sum ! */
+  return htons((u16_t)acc);
+}
+#endif
+
+#if (LWIP_CHKSUM_ALGORITHM == 2) /* Alternative version #2 */
+/*
+ * Curt McDowell
+ * Broadcom Corp.
+ * csm@broadcom.com
+ *
+ * IP checksum two bytes at a time with support for
+ * unaligned buffer.
+ * Works for len up to and including 0x20000.
+ * by Curt McDowell, Broadcom Corp. 12/08/2005
+ *
+ * @param dataptr points to start of data to be summed at any boundary
+ * @param len length of data to be summed
+ * @return host order (!) lwip checksum (non-inverted Internet sum) 
+ */
+
+static u16_t
+lwip_standard_chksum(void *dataptr, int len)
+{
+  u8_t *pb = (u8_t *)dataptr;
+  u16_t *ps, t = 0;
+  u32_t sum = 0;
+  int odd = ((mem_ptr_t)pb & 1);
+
+  /* Get aligned to u16_t */
+  if (odd && len > 0) {
+    ((u8_t *)&t)[1] = *pb++;
+    len--;
+  }
+
+  /* Add the bulk of the data */
+  ps = (u16_t *)(void *)pb;
+  while (len > 1) {
+    sum += *ps++;
+    len -= 2;
+  }
+
+  /* Consume left-over byte, if any */
+  if (len > 0) {
+    ((u8_t *)&t)[0] = *(u8_t *)ps;
+  }
+
+  /* Add end bytes */
+  sum += t;
+
+  /* Fold 32-bit sum to 16 bits
+     calling this twice is propably faster than if statements... */
+  sum = FOLD_U32T(sum);
+  sum = FOLD_U32T(sum);
+
+  /* Swap if alignment was odd */
+  if (odd) {
+    sum = SWAP_BYTES_IN_WORD(sum);
+  }
+
+  return (u16_t)sum;
+}
+#endif
+
+#if (LWIP_CHKSUM_ALGORITHM == 3) /* Alternative version #3 */
+/**
+ * An optimized checksum routine. Basically, it uses loop-unrolling on
+ * the checksum loop, treating the head and tail bytes specially, whereas
+ * the inner loop acts on 8 bytes at a time. 
+ *
+ * @arg start of buffer to be checksummed. May be an odd byte address.
+ * @len number of bytes in the buffer to be checksummed.
+ * @return host order (!) lwip checksum (non-inverted Internet sum) 
+ * 
+ * by Curt McDowell, Broadcom Corp. December 8th, 2005
+ */
+
+static u16_t
+lwip_standard_chksum(void *dataptr, int len)
+{
+  u8_t *pb = (u8_t *)dataptr;
+  u16_t *ps, t = 0;
+  u32_t *pl;
+  u32_t sum = 0, tmp;
+  /* starts at odd byte address? */
+  int odd = ((mem_ptr_t)pb & 1);
+
+  if (odd && len > 0) {
+    ((u8_t *)&t)[1] = *pb++;
+    len--;
+  }
+
+  ps = (u16_t *)pb;
+
+  if (((mem_ptr_t)ps & 3) && len > 1) {
+    sum += *ps++;
+    len -= 2;
+  }
+
+  pl = (u32_t *)ps;
+
+  while (len > 7)  {
+    tmp = sum + *pl++;          /* ping */
+    if (tmp < sum) {
+      tmp++;                    /* add back carry */
+    }
+
+    sum = tmp + *pl++;          /* pong */
+    if (sum < tmp) {
+      sum++;                    /* add back carry */
+    }
+
+    len -= 8;
+  }
+
+  /* make room in upper bits */
+  sum = FOLD_U32T(sum);
+
+  ps = (u16_t *)pl;
+
+  /* 16-bit aligned word remaining? */
+  while (len > 1) {
+    sum += *ps++;
+    len -= 2;
+  }
+
+  /* dangling tail byte remaining? */
+  if (len > 0) {                /* include odd byte */
+    ((u8_t *)&t)[0] = *(u8_t *)ps;
+  }
+
+  sum += t;                     /* add end bytes */
+
+  /* Fold 32-bit sum to 16 bits
+     calling this twice is propably faster than if statements... */
+  sum = FOLD_U32T(sum);
+  sum = FOLD_U32T(sum);
+
+  if (odd) {
+    sum = SWAP_BYTES_IN_WORD(sum);
+  }
+
+  return (u16_t)sum;
+}
+#endif
+
+/* inet_chksum_pseudo:
+ *
+ * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
+ * IP addresses are expected to be in network byte order.
+ *
+ * @param p chain of pbufs over that a checksum should be calculated (ip data part)
+ * @param src source ip address (used for checksum of pseudo header)
+ * @param dst destination ip address (used for checksum of pseudo header)
+ * @param proto ip protocol (used for checksum of pseudo header)
+ * @param proto_len length of the ip data part (used for checksum of pseudo header)
+ * @return checksum (as u16_t) to be saved directly in the protocol header
+ */
+u16_t
+inet_chksum_pseudo(struct pbuf *p,
+       ip_addr_t *src, ip_addr_t *dest,
+       u8_t proto, u16_t proto_len)
+{
+  u32_t acc;
+  u32_t addr;
+  struct pbuf *q;
+  u8_t swapped;
+
+  acc = 0;
+  swapped = 0;
+  /* iterate through all pbuf in chain */
+  for(q = p; q != NULL; q = q->next) {
+    LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
+      (void *)q, (void *)q->next));
+    acc += LWIP_CHKSUM(q->payload, q->len);
+    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
+    /* just executing this next line is probably faster that the if statement needed
+       to check whether we really need to execute it, and does no harm */
+    acc = FOLD_U32T(acc);
+    if (q->len % 2 != 0) {
+      swapped = 1 - swapped;
+      acc = SWAP_BYTES_IN_WORD(acc);
+    }
+    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
+  }
+
+  if (swapped) {
+    acc = SWAP_BYTES_IN_WORD(acc);
+  }
+  addr = ip4_addr_get_u32(src);
+  acc += (addr & 0xffffUL);
+  acc += ((addr >> 16) & 0xffffUL);
+  addr = ip4_addr_get_u32(dest);
+  acc += (addr & 0xffffUL);
+  acc += ((addr >> 16) & 0xffffUL);
+  acc += (u32_t)htons((u16_t)proto);
+  acc += (u32_t)htons(proto_len);
+
+  /* Fold 32-bit sum to 16 bits
+     calling this twice is propably faster than if statements... */
+  acc = FOLD_U32T(acc);
+  acc = FOLD_U32T(acc);
+  LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
+  return (u16_t)~(acc & 0xffffUL);
+}
+
+/* inet_chksum_pseudo:
+ *
+ * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
+ * IP addresses are expected to be in network byte order.
+ *
+ * @param p chain of pbufs over that a checksum should be calculated (ip data part)
+ * @param src source ip address (used for checksum of pseudo header)
+ * @param dst destination ip address (used for checksum of pseudo header)
+ * @param proto ip protocol (used for checksum of pseudo header)
+ * @param proto_len length of the ip data part (used for checksum of pseudo header)
+ * @return checksum (as u16_t) to be saved directly in the protocol header
+ */
+u16_t
+inet_chksum_pseudo_partial(struct pbuf *p,
+       ip_addr_t *src, ip_addr_t *dest,
+       u8_t proto, u16_t proto_len, u16_t chksum_len)
+{
+  u32_t acc;
+  u32_t addr;
+  struct pbuf *q;
+  u8_t swapped;
+  u16_t chklen;
+
+  acc = 0;
+  swapped = 0;
+  /* iterate through all pbuf in chain */
+  for(q = p; (q != NULL) && (chksum_len > 0); q = q->next) {
+    LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
+      (void *)q, (void *)q->next));
+    chklen = q->len;
+    if (chklen > chksum_len) {
+      chklen = chksum_len;
+    }
+    acc += LWIP_CHKSUM(q->payload, chklen);
+    chksum_len -= chklen;
+    LWIP_ASSERT("delete me", chksum_len < 0x7fff);
+    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
+    /* fold the upper bit down */
+    acc = FOLD_U32T(acc);
+    if (q->len % 2 != 0) {
+      swapped = 1 - swapped;
+      acc = SWAP_BYTES_IN_WORD(acc);
+    }
+    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
+  }
+
+  if (swapped) {
+    acc = SWAP_BYTES_IN_WORD(acc);
+  }
+  addr = ip4_addr_get_u32(src);
+  acc += (addr & 0xffffUL);
+  acc += ((addr >> 16) & 0xffffUL);
+  addr = ip4_addr_get_u32(dest);
+  acc += (addr & 0xffffUL);
+  acc += ((addr >> 16) & 0xffffUL);
+  acc += (u32_t)htons((u16_t)proto);
+  acc += (u32_t)htons(proto_len);
+
+  /* Fold 32-bit sum to 16 bits
+     calling this twice is propably faster than if statements... */
+  acc = FOLD_U32T(acc);
+  acc = FOLD_U32T(acc);
+  LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
+  return (u16_t)~(acc & 0xffffUL);
+}
+
+/* inet_chksum:
+ *
+ * Calculates the Internet checksum over a portion of memory. Used primarily for IP
+ * and ICMP.
+ *
+ * @param dataptr start of the buffer to calculate the checksum (no alignment needed)
+ * @param len length of the buffer to calculate the checksum
+ * @return checksum (as u16_t) to be saved directly in the protocol header
+ */
+
+u16_t
+inet_chksum(void *dataptr, u16_t len)
+{
+  return ~LWIP_CHKSUM(dataptr, len);
+}
+
+/**
+ * Calculate a checksum over a chain of pbufs (without pseudo-header, much like
+ * inet_chksum only pbufs are used).
+ *
+ * @param p pbuf chain over that the checksum should be calculated
+ * @return checksum (as u16_t) to be saved directly in the protocol header
+ */
+u16_t
+inet_chksum_pbuf(struct pbuf *p)
+{
+  u32_t acc;
+  struct pbuf *q;
+  u8_t swapped;
+
+  acc = 0;
+  swapped = 0;
+  for(q = p; q != NULL; q = q->next) {
+    acc += LWIP_CHKSUM(q->payload, q->len);
+    acc = FOLD_U32T(acc);
+    if (q->len % 2 != 0) {
+      swapped = 1 - swapped;
+      acc = SWAP_BYTES_IN_WORD(acc);
+    }
+  }
+
+  if (swapped) {
+    acc = SWAP_BYTES_IN_WORD(acc);
+  }
+  return (u16_t)~(acc & 0xffffUL);
+}
+
+/* These are some implementations for LWIP_CHKSUM_COPY, which copies data
+ * like MEMCPY but generates a checksum at the same time. Since this is a
+ * performance-sensitive function, you might want to create your own version
+ * in assembly targeted at your hardware by defining it in lwipopts.h:
+ *   #define LWIP_CHKSUM_COPY(dst, src, len) your_chksum_copy(dst, src, len)
+ */
+
+#if (LWIP_CHKSUM_COPY_ALGORITHM == 1) /* Version #1 */
+/** Safe but slow: first call MEMCPY, then call LWIP_CHKSUM.
+ * For architectures with big caches, data might still be in cache when
+ * generating the checksum after copying.
+ */
+u16_t
+lwip_chksum_copy(void *dst, const void *src, u16_t len)
+{
+  MEMCPY(dst, src, len);
+  return LWIP_CHKSUM(dst, len);
+}
+#endif /* (LWIP_CHKSUM_COPY_ALGORITHM == 1) */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/ip.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/ip.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/ip.c	(revision 164)
@@ -0,0 +1,924 @@
+/**
+ * @file
+ * This is the IPv4 layer implementation for incoming and outgoing IP traffic.
+ * 
+ * @see ip_frag.c
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+#include "lwip/ip.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/ip_frag.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/netif.h"
+#include "lwip/icmp.h"
+#include "lwip/igmp.h"
+#include "lwip/raw.h"
+#include "lwip/udp.h"
+#include "lwip/tcp_impl.h"
+#include "lwip/snmp.h"
+#include "lwip/dhcp.h"
+#include "lwip/autoip.h"
+#include "lwip/stats.h"
+#include "arch/perf.h"
+
+#include <string.h>
+
+/** Set this to 0 in the rare case of wanting to call an extra function to
+ * generate the IP checksum (in contrast to calculating it on-the-fly). */
+#ifndef LWIP_INLINE_IP_CHKSUM
+#define LWIP_INLINE_IP_CHKSUM   1
+#endif
+#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP
+#define CHECKSUM_GEN_IP_INLINE  1
+#else
+#define CHECKSUM_GEN_IP_INLINE  0
+#endif
+
+#if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT)
+#define IP_ACCEPT_LINK_LAYER_ADDRESSING 1
+
+/** Some defines for DHCP to let link-layer-addressed packets through while the
+ * netif is down.
+ * To use this in your own application/protocol, define LWIP_IP_ACCEPT_UDP_PORT
+ * to return 1 if the port is accepted and 0 if the port is not accepted.
+ */
+#if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT)
+/* accept DHCP client port and custom port */
+#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(DHCP_CLIENT_PORT)) \
+         || (LWIP_IP_ACCEPT_UDP_PORT(port)))
+#elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
+/* accept custom port only */
+#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port))
+#else /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
+/* accept DHCP client port only */
+#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(DHCP_CLIENT_PORT))
+#endif /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
+
+#else /* LWIP_DHCP */
+#define IP_ACCEPT_LINK_LAYER_ADDRESSING 0
+#endif /* LWIP_DHCP */
+
+/**
+ * The interface that provided the packet for the current callback
+ * invocation.
+ */
+struct netif *current_netif;
+
+/**
+ * Header of the input packet currently being processed.
+ */
+const struct ip_hdr *current_header;
+/** Source IP address of current_header */
+ip_addr_t current_iphdr_src;
+/** Destination IP address of current_header */
+ip_addr_t current_iphdr_dest;
+
+/** The IP header ID of the next outgoing IP packet */
+static u16_t ip_id;
+
+/**
+ * Finds the appropriate network interface for a given IP address. It
+ * searches the list of network interfaces linearly. A match is found
+ * if the masked IP address of the network interface equals the masked
+ * IP address given to the function.
+ *
+ * @param dest the destination IP address for which to find the route
+ * @return the netif on which to send to reach dest
+ */
+struct netif *
+ip_route(ip_addr_t *dest)
+{
+  struct netif *netif;
+
+#ifdef LWIP_HOOK_IP4_ROUTE
+  netif = LWIP_HOOK_IP4_ROUTE(dest);
+  if (netif != NULL) {
+    return netif;
+  }
+#endif
+
+  /* iterate through netifs */
+  for (netif = netif_list; netif != NULL; netif = netif->next) {
+    /* network mask matches? */
+    if (netif_is_up(netif)) {
+      if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
+        /* return netif on which to forward IP packet */
+        return netif;
+      }
+    }
+  }
+  if ((netif_default == NULL) || (!netif_is_up(netif_default))) {
+    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+      ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
+    IP_STATS_INC(ip.rterr);
+    snmp_inc_ipoutnoroutes();
+    return NULL;
+  }
+  /* no matching netif found, use default netif */
+  return netif_default;
+}
+
+#if IP_FORWARD
+/**
+ * Determine whether an IP address is in a reserved set of addresses
+ * that may not be forwarded, or whether datagrams to that destination
+ * may be forwarded.
+ * @param p the packet to forward
+ * @param dest the destination IP address
+ * @return 1: can forward 0: discard
+ */
+static int
+ip_canforward(struct pbuf *p)
+{
+  u32_t addr = ip4_addr_get_u32(ip_current_dest_addr());
+
+  if (p->flags & PBUF_FLAG_LLBCAST) {
+    /* don't route link-layer broadcasts */
+    return 0;
+  }
+  if ((p->flags & PBUF_FLAG_LLMCAST) && !IP_MULTICAST(addr)) {
+    /* don't route link-layer multicasts unless the destination address is an IP
+       multicast address */
+    return 0;
+  }
+  if (IP_EXPERIMENTAL(addr)) {
+    return 0;
+  }
+  if (IP_CLASSA(addr)) {
+    u32_t net = addr & IP_CLASSA_NET;
+    if ((net == 0) || (net == (IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) {
+      /* don't route loopback packets */
+      return 0;
+    }
+  }
+  return 1;
+}
+
+/**
+ * Forwards an IP packet. It finds an appropriate route for the
+ * packet, decrements the TTL value of the packet, adjusts the
+ * checksum and outputs the packet on the appropriate interface.
+ *
+ * @param p the packet to forward (p->payload points to IP header)
+ * @param iphdr the IP header of the input packet
+ * @param inp the netif on which this packet was received
+ */
+static void
+ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
+{
+  struct netif *netif;
+
+  PERF_START;
+
+  if (!ip_canforward(p)) {
+    goto return_noroute;
+  }
+
+  /* RFC3927 2.7: do not forward link-local addresses */
+  if (ip_addr_islinklocal(&current_iphdr_dest)) {
+    LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+      ip4_addr1_16(&current_iphdr_dest), ip4_addr2_16(&current_iphdr_dest),
+      ip4_addr3_16(&current_iphdr_dest), ip4_addr4_16(&current_iphdr_dest)));
+    goto return_noroute;
+  }
+
+  /* Find network interface where to forward this IP packet to. */
+  netif = ip_route(&current_iphdr_dest);
+  if (netif == NULL) {
+    LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n",
+      ip4_addr1_16(&current_iphdr_dest), ip4_addr2_16(&current_iphdr_dest),
+      ip4_addr3_16(&current_iphdr_dest), ip4_addr4_16(&current_iphdr_dest)));
+    /* @todo: send ICMP_DUR_NET? */
+    goto return_noroute;
+  }
+#if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF
+  /* Do not forward packets onto the same network interface on which
+   * they arrived. */
+  if (netif == inp) {
+    LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
+    goto return_noroute;
+  }
+#endif /* IP_FORWARD_ALLOW_TX_ON_RX_NETIF */
+
+  /* decrement TTL */
+  IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
+  /* send ICMP if TTL == 0 */
+  if (IPH_TTL(iphdr) == 0) {
+    snmp_inc_ipinhdrerrors();
+#if LWIP_ICMP
+    /* Don't send ICMP messages in response to ICMP messages */
+    if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
+      icmp_time_exceeded(p, ICMP_TE_TTL);
+    }
+#endif /* LWIP_ICMP */
+    return;
+  }
+
+  /* Incrementally update the IP checksum. */
+  if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) {
+    IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1);
+  } else {
+    IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100));
+  }
+
+  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+    ip4_addr1_16(&current_iphdr_dest), ip4_addr2_16(&current_iphdr_dest),
+    ip4_addr3_16(&current_iphdr_dest), ip4_addr4_16(&current_iphdr_dest)));
+
+  IP_STATS_INC(ip.fw);
+  IP_STATS_INC(ip.xmit);
+  snmp_inc_ipforwdatagrams();
+
+  PERF_STOP("ip_forward");
+  /* don't fragment if interface has mtu set to 0 [loopif] */
+  if (netif->mtu && (p->tot_len > netif->mtu)) {
+    if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) {
+#if IP_FRAG
+      ip_frag(p, netif, ip_current_dest_addr());
+#else /* IP_FRAG */
+      /* @todo: send ICMP Destination Unreacheable code 13 "Communication administratively prohibited"? */
+#endif /* IP_FRAG */
+    } else {
+      /* send ICMP Destination Unreacheable code 4: "Fragmentation Needed and DF Set" */
+      icmp_dest_unreach(p, ICMP_DUR_FRAG);
+    }
+    return;
+  }
+  /* transmit pbuf on chosen interface */
+  netif->output(netif, p, &current_iphdr_dest);
+  return;
+return_noroute:
+  snmp_inc_ipoutnoroutes();
+}
+#endif /* IP_FORWARD */
+
+/**
+ * This function is called by the network interface device driver when
+ * an IP packet is received. The function does the basic checks of the
+ * IP header such as packet size being at least larger than the header
+ * size etc. If the packet was not destined for us, the packet is
+ * forwarded (using ip_forward). The IP checksum is always checked.
+ *
+ * Finally, the packet is sent to the upper layer protocol input function.
+ * 
+ * @param p the received IP packet (p->payload points to IP header)
+ * @param inp the netif on which this packet was received
+ * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't
+ *         processed, but currently always returns ERR_OK)
+ */
+err_t
+ip_input(struct pbuf *p, struct netif *inp)
+{
+  struct ip_hdr *iphdr;
+  struct netif *netif;
+  u16_t iphdr_hlen;
+  u16_t iphdr_len;
+#if IP_ACCEPT_LINK_LAYER_ADDRESSING
+  int check_ip_src=1;
+#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
+
+  IP_STATS_INC(ip.recv);
+  snmp_inc_ipinreceives();
+
+  /* identify the IP header */
+  iphdr = (struct ip_hdr *)p->payload;
+  if (IPH_V(iphdr) != 4) {
+    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr)));
+    ip_debug_print(p);
+    pbuf_free(p);
+    IP_STATS_INC(ip.err);
+    IP_STATS_INC(ip.drop);
+    snmp_inc_ipinhdrerrors();
+    return ERR_OK;
+  }
+
+#ifdef LWIP_HOOK_IP4_INPUT
+  if (LWIP_HOOK_IP4_INPUT(p, inp)) {
+    /* the packet has been eaten */
+    return ERR_OK;
+  }
+#endif
+
+  /* obtain IP header length in number of 32-bit words */
+  iphdr_hlen = IPH_HL(iphdr);
+  /* calculate IP header length in bytes */
+  iphdr_hlen *= 4;
+  /* obtain ip length in bytes */
+  iphdr_len = ntohs(IPH_LEN(iphdr));
+
+  /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
+  if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) {
+    if (iphdr_hlen > p->len) {
+      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+        ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
+        iphdr_hlen, p->len));
+    }
+    if (iphdr_len > p->tot_len) {
+      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+        ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
+        iphdr_len, p->tot_len));
+    }
+    /* free (drop) packet pbufs */
+    pbuf_free(p);
+    IP_STATS_INC(ip.lenerr);
+    IP_STATS_INC(ip.drop);
+    snmp_inc_ipindiscards();
+    return ERR_OK;
+  }
+
+  /* verify checksum */
+#if CHECKSUM_CHECK_IP
+  if (inet_chksum(iphdr, iphdr_hlen) != 0) {
+
+    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+      ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
+    ip_debug_print(p);
+    pbuf_free(p);
+    IP_STATS_INC(ip.chkerr);
+    IP_STATS_INC(ip.drop);
+    snmp_inc_ipinhdrerrors();
+    return ERR_OK;
+  }
+#endif
+
+  /* Trim pbuf. This should have been done at the netif layer,
+   * but we'll do it anyway just to be sure that its done. */
+  pbuf_realloc(p, iphdr_len);
+
+  /* copy IP addresses to aligned ip_addr_t */
+  ip_addr_copy(current_iphdr_dest, iphdr->dest);
+  ip_addr_copy(current_iphdr_src, iphdr->src);
+
+  /* match packet against an interface, i.e. is this packet for us? */
+#if LWIP_IGMP
+  if (ip_addr_ismulticast(&current_iphdr_dest)) {
+    if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, &current_iphdr_dest))) {
+      netif = inp;
+    } else {
+      netif = NULL;
+    }
+  } else
+#endif /* LWIP_IGMP */
+  {
+    /* start trying with inp. if that's not acceptable, start walking the
+       list of configured netifs.
+       'first' is used as a boolean to mark whether we started walking the list */
+    int first = 1;
+    netif = inp;
+    do {
+      LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n",
+          ip4_addr_get_u32(&iphdr->dest), ip4_addr_get_u32(&netif->ip_addr),
+          ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(&netif->netmask),
+          ip4_addr_get_u32(&netif->ip_addr) & ip4_addr_get_u32(&netif->netmask),
+          ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(&netif->netmask)));
+
+      /* interface is up and configured? */
+      if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) {
+        /* unicast to this interface address? */
+        if (ip_addr_cmp(&current_iphdr_dest, &(netif->ip_addr)) ||
+            /* or broadcast on this interface network address? */
+            ip_addr_isbroadcast(&current_iphdr_dest, netif)) {
+          LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
+              netif->name[0], netif->name[1]));
+          /* break out of for loop */
+          break;
+        }
+#if LWIP_AUTOIP
+        /* connections to link-local addresses must persist after changing
+           the netif's address (RFC3927 ch. 1.9) */
+        if ((netif->autoip != NULL) &&
+            ip_addr_cmp(&current_iphdr_dest, &(netif->autoip->llipaddr))) {
+          LWIP_DEBUGF(IP_DEBUG, ("ip_input: LLA packet accepted on interface %c%c\n",
+              netif->name[0], netif->name[1]));
+          /* break out of for loop */
+          break;
+        }
+#endif /* LWIP_AUTOIP */
+      }
+      if (first) {
+        first = 0;
+        netif = netif_list;
+      } else {
+        netif = netif->next;
+      }
+      if (netif == inp) {
+        netif = netif->next;
+      }
+    } while(netif != NULL);
+  }
+
+#if IP_ACCEPT_LINK_LAYER_ADDRESSING
+  /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
+   * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
+   * According to RFC 1542 section 3.1.1, referred by RFC 2131).
+   *
+   * If you want to accept private broadcast communication while a netif is down,
+   * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.:
+   *
+   * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345))
+   */
+  if (netif == NULL) {
+    /* remote port is DHCP server? */
+    if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
+      struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen);
+      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n",
+        ntohs(udphdr->dest)));
+      if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) {
+        LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n"));
+        netif = inp;
+        check_ip_src = 0;
+      }
+    }
+  }
+#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
+
+  /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */
+#if IP_ACCEPT_LINK_LAYER_ADDRESSING
+  /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */
+  if (check_ip_src && !ip_addr_isany(&current_iphdr_src))
+#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
+  {  if ((ip_addr_isbroadcast(&current_iphdr_src, inp)) ||
+         (ip_addr_ismulticast(&current_iphdr_src))) {
+      /* packet source is not valid */
+      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n"));
+      /* free (drop) packet pbufs */
+      pbuf_free(p);
+      IP_STATS_INC(ip.drop);
+      snmp_inc_ipinaddrerrors();
+      snmp_inc_ipindiscards();
+      return ERR_OK;
+    }
+  }
+
+  /* packet not for us? */
+  if (netif == NULL) {
+    /* packet not for us, route or discard */
+    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n"));
+#if IP_FORWARD
+    /* non-broadcast packet? */
+    if (!ip_addr_isbroadcast(&current_iphdr_dest, inp)) {
+      /* try to forward IP packet on (other) interfaces */
+      ip_forward(p, iphdr, inp);
+    } else
+#endif /* IP_FORWARD */
+    {
+      snmp_inc_ipinaddrerrors();
+      snmp_inc_ipindiscards();
+    }
+    pbuf_free(p);
+    return ERR_OK;
+  }
+  /* packet consists of multiple fragments? */
+  if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) {
+#if IP_REASSEMBLY /* packet fragment reassembly code present? */
+    LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n",
+      ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
+    /* reassemble the packet*/
+    p = ip_reass(p);
+    /* packet not fully reassembled yet? */
+    if (p == NULL) {
+      return ERR_OK;
+    }
+    iphdr = (struct ip_hdr *)p->payload;
+#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
+    pbuf_free(p);
+    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
+      ntohs(IPH_OFFSET(iphdr))));
+    IP_STATS_INC(ip.opterr);
+    IP_STATS_INC(ip.drop);
+    /* unsupported protocol feature */
+    snmp_inc_ipinunknownprotos();
+    return ERR_OK;
+#endif /* IP_REASSEMBLY */
+  }
+
+#if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */
+
+#if LWIP_IGMP
+  /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */
+  if((iphdr_hlen > IP_HLEN) &&  (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) {
+#else
+  if (iphdr_hlen > IP_HLEN) {
+#endif /* LWIP_IGMP */
+    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n"));
+    pbuf_free(p);
+    IP_STATS_INC(ip.opterr);
+    IP_STATS_INC(ip.drop);
+    /* unsupported protocol feature */
+    snmp_inc_ipinunknownprotos();
+    return ERR_OK;
+  }
+#endif /* IP_OPTIONS_ALLOWED == 0 */
+
+  /* send to upper layers */
+  LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));
+  ip_debug_print(p);
+  LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
+
+  current_netif = inp;
+  current_header = iphdr;
+
+#if LWIP_RAW
+  /* raw input did not eat the packet? */
+  if (raw_input(p, inp) == 0)
+#endif /* LWIP_RAW */
+  {
+    switch (IPH_PROTO(iphdr)) {
+#if LWIP_UDP
+    case IP_PROTO_UDP:
+#if LWIP_UDPLITE
+    case IP_PROTO_UDPLITE:
+#endif /* LWIP_UDPLITE */
+      snmp_inc_ipindelivers();
+      udp_input(p, inp);
+      break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+    case IP_PROTO_TCP:
+      snmp_inc_ipindelivers();
+      tcp_input(p, inp);
+      break;
+#endif /* LWIP_TCP */
+#if LWIP_ICMP
+    case IP_PROTO_ICMP:
+      snmp_inc_ipindelivers();
+      icmp_input(p, inp);
+      break;
+#endif /* LWIP_ICMP */
+#if LWIP_IGMP
+    case IP_PROTO_IGMP:
+      igmp_input(p, inp, &current_iphdr_dest);
+      break;
+#endif /* LWIP_IGMP */
+    default:
+#if LWIP_ICMP
+      /* send ICMP destination protocol unreachable unless is was a broadcast */
+      if (!ip_addr_isbroadcast(&current_iphdr_dest, inp) &&
+          !ip_addr_ismulticast(&current_iphdr_dest)) {
+        p->payload = iphdr;
+        icmp_dest_unreach(p, ICMP_DUR_PROTO);
+      }
+#endif /* LWIP_ICMP */
+      pbuf_free(p);
+
+      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr)));
+
+      IP_STATS_INC(ip.proterr);
+      IP_STATS_INC(ip.drop);
+      snmp_inc_ipinunknownprotos();
+    }
+  }
+
+  current_netif = NULL;
+  current_header = NULL;
+  ip_addr_set_any(&current_iphdr_src);
+  ip_addr_set_any(&current_iphdr_dest);
+
+  return ERR_OK;
+}
+
+/**
+ * Sends an IP packet on a network interface. This function constructs
+ * the IP header and calculates the IP header checksum. If the source
+ * IP address is NULL, the IP address of the outgoing network
+ * interface is filled in as source address.
+ * If the destination IP address is IP_HDRINCL, p is assumed to already
+ * include an IP header and p->payload points to it instead of the data.
+ *
+ * @param p the packet to send (p->payload points to the data, e.g. next
+            protocol header; if dest == IP_HDRINCL, p already includes an IP
+            header and p->payload points to that IP header)
+ * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
+ *         IP  address of the netif used to send is used as source address)
+ * @param dest the destination IP address to send the packet to
+ * @param ttl the TTL value to be set in the IP header
+ * @param tos the TOS value to be set in the IP header
+ * @param proto the PROTOCOL to be set in the IP header
+ * @param netif the netif on which to send this packet
+ * @return ERR_OK if the packet was sent OK
+ *         ERR_BUF if p doesn't have enough space for IP/LINK headers
+ *         returns errors returned by netif->output
+ *
+ * @note ip_id: RFC791 "some host may be able to simply use
+ *  unique identifiers independent of destination"
+ */
+err_t
+ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
+             u8_t ttl, u8_t tos,
+             u8_t proto, struct netif *netif)
+{
+#if IP_OPTIONS_SEND
+  return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0);
+}
+
+/**
+ * Same as ip_output_if() but with the possibility to include IP options:
+ *
+ * @ param ip_options pointer to the IP options, copied into the IP header
+ * @ param optlen length of ip_options
+ */
+err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
+       u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
+       u16_t optlen)
+{
+#endif /* IP_OPTIONS_SEND */
+  struct ip_hdr *iphdr;
+  ip_addr_t dest_addr;
+#if CHECKSUM_GEN_IP_INLINE
+  u32_t chk_sum = 0;
+#endif /* CHECKSUM_GEN_IP_INLINE */
+
+  /* pbufs passed to IP must have a ref-count of 1 as their payload pointer
+     gets altered as the packet is passed down the stack */
+  LWIP_ASSERT("p->ref == 1", p->ref == 1);
+
+  snmp_inc_ipoutrequests();
+
+  /* Should the IP header be generated or is it already included in p? */
+  if (dest != IP_HDRINCL) {
+    u16_t ip_hlen = IP_HLEN;
+#if IP_OPTIONS_SEND
+    u16_t optlen_aligned = 0;
+    if (optlen != 0) {
+#if CHECKSUM_GEN_IP_INLINE
+      int i;
+#endif /* CHECKSUM_GEN_IP_INLINE */
+      /* round up to a multiple of 4 */
+      optlen_aligned = ((optlen + 3) & ~3);
+      ip_hlen += optlen_aligned;
+      /* First write in the IP options */
+      if (pbuf_header(p, optlen_aligned)) {
+        LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output_if_opt: not enough room for IP options in pbuf\n"));
+        IP_STATS_INC(ip.err);
+        snmp_inc_ipoutdiscards();
+        return ERR_BUF;
+      }
+      MEMCPY(p->payload, ip_options, optlen);
+      if (optlen < optlen_aligned) {
+        /* zero the remaining bytes */
+        memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen);
+      }
+#if CHECKSUM_GEN_IP_INLINE
+      for (i = 0; i < optlen_aligned/2; i++) {
+        chk_sum += ((u16_t*)p->payload)[i];
+      }
+#endif /* CHECKSUM_GEN_IP_INLINE */
+    }
+#endif /* IP_OPTIONS_SEND */
+    /* generate IP header */
+    if (pbuf_header(p, IP_HLEN)) {
+      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n"));
+
+      IP_STATS_INC(ip.err);
+      snmp_inc_ipoutdiscards();
+      return ERR_BUF;
+    }
+
+    iphdr = (struct ip_hdr *)p->payload;
+    LWIP_ASSERT("check that first pbuf can hold struct ip_hdr",
+               (p->len >= sizeof(struct ip_hdr)));
+
+    IPH_TTL_SET(iphdr, ttl);
+    IPH_PROTO_SET(iphdr, proto);
+#if CHECKSUM_GEN_IP_INLINE
+    chk_sum += LWIP_MAKE_U16(proto, ttl);
+#endif /* CHECKSUM_GEN_IP_INLINE */
+
+    /* dest cannot be NULL here */
+    ip_addr_copy(iphdr->dest, *dest);
+#if CHECKSUM_GEN_IP_INLINE
+    chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF;
+    chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16;
+#endif /* CHECKSUM_GEN_IP_INLINE */
+
+    IPH_VHL_SET(iphdr, 4, ip_hlen / 4);
+    IPH_TOS_SET(iphdr, tos);
+#if CHECKSUM_GEN_IP_INLINE
+    chk_sum += LWIP_MAKE_U16(tos, iphdr->_v_hl);
+#endif /* CHECKSUM_GEN_IP_INLINE */
+    IPH_LEN_SET(iphdr, htons(p->tot_len));
+#if CHECKSUM_GEN_IP_INLINE
+    chk_sum += iphdr->_len;
+#endif /* CHECKSUM_GEN_IP_INLINE */
+    IPH_OFFSET_SET(iphdr, 0);
+    IPH_ID_SET(iphdr, htons(ip_id));
+#if CHECKSUM_GEN_IP_INLINE
+    chk_sum += iphdr->_id;
+#endif /* CHECKSUM_GEN_IP_INLINE */
+    ++ip_id;
+
+    if (ip_addr_isany(src)) {
+      ip_addr_copy(iphdr->src, netif->ip_addr);
+    } else {
+      /* src cannot be NULL here */
+      ip_addr_copy(iphdr->src, *src);
+    }
+
+#if CHECKSUM_GEN_IP_INLINE
+    chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF;
+    chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16;
+    chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
+    chk_sum = (chk_sum >> 16) + chk_sum;
+    chk_sum = ~chk_sum;
+    iphdr->_chksum = chk_sum; /* network order */
+#else /* CHECKSUM_GEN_IP_INLINE */
+    IPH_CHKSUM_SET(iphdr, 0);
+#if CHECKSUM_GEN_IP
+    IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
+#endif
+#endif /* CHECKSUM_GEN_IP_INLINE */
+  } else {
+    /* IP header already included in p */
+    iphdr = (struct ip_hdr *)p->payload;
+    ip_addr_copy(dest_addr, iphdr->dest);
+    dest = &dest_addr;
+  }
+
+  IP_STATS_INC(ip.xmit);
+
+  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));
+  ip_debug_print(p);
+
+#if ENABLE_LOOPBACK
+  if (ip_addr_cmp(dest, &netif->ip_addr)) {
+    /* Packet to self, enqueue it for loopback */
+    LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
+    return netif_loop_output(netif, p, dest);
+  }
+#if LWIP_IGMP
+  if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
+    netif_loop_output(netif, p, dest);
+  }
+#endif /* LWIP_IGMP */
+#endif /* ENABLE_LOOPBACK */
+#if IP_FRAG
+  /* don't fragment if interface has mtu set to 0 [loopif] */
+  if (netif->mtu && (p->tot_len > netif->mtu)) {
+    return ip_frag(p, netif, dest);
+  }
+#endif /* IP_FRAG */
+
+  LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
+  return netif->output(netif, p, dest);
+}
+
+/**
+ * Simple interface to ip_output_if. It finds the outgoing network
+ * interface and calls upon ip_output_if to do the actual work.
+ *
+ * @param p the packet to send (p->payload points to the data, e.g. next
+            protocol header; if dest == IP_HDRINCL, p already includes an IP
+            header and p->payload points to that IP header)
+ * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
+ *         IP  address of the netif used to send is used as source address)
+ * @param dest the destination IP address to send the packet to
+ * @param ttl the TTL value to be set in the IP header
+ * @param tos the TOS value to be set in the IP header
+ * @param proto the PROTOCOL to be set in the IP header
+ *
+ * @return ERR_RTE if no route is found
+ *         see ip_output_if() for more return values
+ */
+err_t
+ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
+          u8_t ttl, u8_t tos, u8_t proto)
+{
+  struct netif *netif;
+
+  /* pbufs passed to IP must have a ref-count of 1 as their payload pointer
+     gets altered as the packet is passed down the stack */
+  LWIP_ASSERT("p->ref == 1", p->ref == 1);
+
+  if ((netif = ip_route(dest)) == NULL) {
+    LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+      ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
+    IP_STATS_INC(ip.rterr);
+    return ERR_RTE;
+  }
+
+  return ip_output_if(p, src, dest, ttl, tos, proto, netif);
+}
+
+#if LWIP_NETIF_HWADDRHINT
+/** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint
+ *  before calling ip_output_if.
+ *
+ * @param p the packet to send (p->payload points to the data, e.g. next
+            protocol header; if dest == IP_HDRINCL, p already includes an IP
+            header and p->payload points to that IP header)
+ * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
+ *         IP  address of the netif used to send is used as source address)
+ * @param dest the destination IP address to send the packet to
+ * @param ttl the TTL value to be set in the IP header
+ * @param tos the TOS value to be set in the IP header
+ * @param proto the PROTOCOL to be set in the IP header
+ * @param addr_hint address hint pointer set to netif->addr_hint before
+ *        calling ip_output_if()
+ *
+ * @return ERR_RTE if no route is found
+ *         see ip_output_if() for more return values
+ */
+err_t
+ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
+          u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint)
+{
+  struct netif *netif;
+  err_t err;
+
+  /* pbufs passed to IP must have a ref-count of 1 as their payload pointer
+     gets altered as the packet is passed down the stack */
+  LWIP_ASSERT("p->ref == 1", p->ref == 1);
+
+  if ((netif = ip_route(dest)) == NULL) {
+    LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+      ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
+    IP_STATS_INC(ip.rterr);
+    return ERR_RTE;
+  }
+
+  NETIF_SET_HWADDRHINT(netif, addr_hint);
+  err = ip_output_if(p, src, dest, ttl, tos, proto, netif);
+  NETIF_SET_HWADDRHINT(netif, NULL);
+
+  return err;
+}
+#endif /* LWIP_NETIF_HWADDRHINT*/
+
+#if IP_DEBUG
+/* Print an IP header by using LWIP_DEBUGF
+ * @param p an IP packet, p->payload pointing to the IP header
+ */
+void
+ip_debug_print(struct pbuf *p)
+{
+  struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
+
+  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" |  0x%02"X16_F" |     %5"U16_F"     | (v, hl, tos, len)\n",
+                    IPH_V(iphdr),
+                    IPH_HL(iphdr),
+                    IPH_TOS(iphdr),
+                    ntohs(IPH_LEN(iphdr))));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("|    %5"U16_F"      |%"U16_F"%"U16_F"%"U16_F"|    %4"U16_F"   | (id, flags, offset)\n",
+                    ntohs(IPH_ID(iphdr)),
+                    ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
+                    ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
+                    ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
+                    ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |    0x%04"X16_F"     | (ttl, proto, chksum)\n",
+                    IPH_TTL(iphdr),
+                    IPH_PROTO(iphdr),
+                    ntohs(IPH_CHKSUM(iphdr))));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (src)\n",
+                    ip4_addr1_16(&iphdr->src),
+                    ip4_addr2_16(&iphdr->src),
+                    ip4_addr3_16(&iphdr->src),
+                    ip4_addr4_16(&iphdr->src)));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (dest)\n",
+                    ip4_addr1_16(&iphdr->dest),
+                    ip4_addr2_16(&iphdr->dest),
+                    ip4_addr3_16(&iphdr->dest),
+                    ip4_addr4_16(&iphdr->dest)));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+}
+#endif /* IP_DEBUG */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/ip_addr.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/ip_addr.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/ip_addr.c	(revision 164)
@@ -0,0 +1,312 @@
+/**
+ * @file
+ * This is the IPv4 address tools implementation.
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+
+/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
+const ip_addr_t ip_addr_any = { IPADDR_ANY };
+const ip_addr_t ip_addr_broadcast = { IPADDR_BROADCAST };
+
+/**
+ * Determine if an address is a broadcast address on a network interface 
+ * 
+ * @param addr address to be checked
+ * @param netif the network interface against which the address is checked
+ * @return returns non-zero if the address is a broadcast address
+ */
+u8_t
+ip4_addr_isbroadcast(u32_t addr, const struct netif *netif)
+{
+  ip_addr_t ipaddr;
+  ip4_addr_set_u32(&ipaddr, addr);
+
+  /* all ones (broadcast) or all zeroes (old skool broadcast) */
+  if ((~addr == IPADDR_ANY) ||
+      (addr == IPADDR_ANY)) {
+    return 1;
+  /* no broadcast support on this network interface? */
+  } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) {
+    /* the given address cannot be a broadcast address
+     * nor can we check against any broadcast addresses */
+    return 0;
+  /* address matches network interface address exactly? => no broadcast */
+  } else if (addr == ip4_addr_get_u32(&netif->ip_addr)) {
+    return 0;
+  /*  on the same (sub) network... */
+  } else if (ip_addr_netcmp(&ipaddr, &(netif->ip_addr), &(netif->netmask))
+         /* ...and host identifier bits are all ones? =>... */
+          && ((addr & ~ip4_addr_get_u32(&netif->netmask)) ==
+           (IPADDR_BROADCAST & ~ip4_addr_get_u32(&netif->netmask)))) {
+    /* => network broadcast address */
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+/** Checks if a netmask is valid (starting with ones, then only zeros)
+ *
+ * @param netmask the IPv4 netmask to check (in network byte order!)
+ * @return 1 if the netmask is valid, 0 if it is not
+ */
+u8_t
+ip4_addr_netmask_valid(u32_t netmask)
+{
+  u32_t mask;
+  u32_t nm_hostorder = lwip_htonl(netmask);
+
+  /* first, check for the first zero */
+  for (mask = 1UL << 31 ; mask != 0; mask >>= 1) {
+    if ((nm_hostorder & mask) == 0) {
+      break;
+    }
+  }
+  /* then check that there is no one */
+  for (; mask != 0; mask >>= 1) {
+    if ((nm_hostorder & mask) != 0) {
+      /* there is a one after the first zero -> invalid */
+      return 0;
+    }
+  }
+  /* no one after the first zero -> valid */
+  return 1;
+}
+
+/* Here for now until needed in other places in lwIP */
+#ifndef isprint
+#define in_range(c, lo, up)  ((u8_t)c >= lo && (u8_t)c <= up)
+#define isprint(c)           in_range(c, 0x20, 0x7f)
+#define isdigit(c)           in_range(c, '0', '9')
+#define isxdigit(c)          (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
+#define islower(c)           in_range(c, 'a', 'z')
+#define isspace(c)           (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
+#endif
+
+/**
+ * Ascii internet address interpretation routine.
+ * The value returned is in network order.
+ *
+ * @param cp IP address in ascii represenation (e.g. "127.0.0.1")
+ * @return ip address in network order
+ */
+u32_t
+ipaddr_addr(const char *cp)
+{
+  ip_addr_t val;
+
+  if (ipaddr_aton(cp, &val)) {
+    return ip4_addr_get_u32(&val);
+  }
+  return (IPADDR_NONE);
+}
+
+/**
+ * Check whether "cp" is a valid ascii representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broadcast address.
+ *
+ * @param cp IP address in ascii represenation (e.g. "127.0.0.1")
+ * @param addr pointer to which to save the ip address in network order
+ * @return 1 if cp could be converted to addr, 0 on failure
+ */
+int
+ipaddr_aton(const char *cp, ip_addr_t *addr)
+{
+  u32_t val;
+  u8_t base;
+  char c;
+  u32_t parts[4];
+  u32_t *pp = parts;
+
+  c = *cp;
+  for (;;) {
+    /*
+     * Collect number up to ``.''.
+     * Values are specified as for C:
+     * 0x=hex, 0=octal, 1-9=decimal.
+     */
+    if (!isdigit(c))
+      return (0);
+    val = 0;
+    base = 10;
+    if (c == '0') {
+      c = *++cp;
+      if (c == 'x' || c == 'X') {
+        base = 16;
+        c = *++cp;
+      } else
+        base = 8;
+    }
+    for (;;) {
+      if (isdigit(c)) {
+        val = (val * base) + (int)(c - '0');
+        c = *++cp;
+      } else if (base == 16 && isxdigit(c)) {
+        val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A'));
+        c = *++cp;
+      } else
+        break;
+    }
+    if (c == '.') {
+      /*
+       * Internet format:
+       *  a.b.c.d
+       *  a.b.c   (with c treated as 16 bits)
+       *  a.b (with b treated as 24 bits)
+       */
+      if (pp >= parts + 3) {
+        return (0);
+      }
+      *pp++ = val;
+      c = *++cp;
+    } else
+      break;
+  }
+  /*
+   * Check for trailing characters.
+   */
+  if (c != '\0' && !isspace(c)) {
+    return (0);
+  }
+  /*
+   * Concoct the address according to
+   * the number of parts specified.
+   */
+  switch (pp - parts + 1) {
+
+  case 0:
+    return (0);       /* initial nondigit */
+
+  case 1:             /* a -- 32 bits */
+    break;
+
+  case 2:             /* a.b -- 8.24 bits */
+    if (val > 0xffffffUL) {
+      return (0);
+    }
+    val |= parts[0] << 24;
+    break;
+
+  case 3:             /* a.b.c -- 8.8.16 bits */
+    if (val > 0xffff) {
+      return (0);
+    }
+    val |= (parts[0] << 24) | (parts[1] << 16);
+    break;
+
+  case 4:             /* a.b.c.d -- 8.8.8.8 bits */
+    if (val > 0xff) {
+      return (0);
+    }
+    val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+    break;
+  default:
+    LWIP_ASSERT("unhandled", 0);
+    break;
+  }
+  if (addr) {
+    ip4_addr_set_u32(addr, htonl(val));
+  }
+  return (1);
+}
+
+/**
+ * Convert numeric IP address into decimal dotted ASCII representation.
+ * returns ptr to static buffer; not reentrant!
+ *
+ * @param addr ip address in network order to convert
+ * @return pointer to a global static (!) buffer that holds the ASCII
+ *         represenation of addr
+ */
+char *
+ipaddr_ntoa(const ip_addr_t *addr)
+{
+  static char str[16];
+  return ipaddr_ntoa_r(addr, str, 16);
+}
+
+/**
+ * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used.
+ *
+ * @param addr ip address in network order to convert
+ * @param buf target buffer where the string is stored
+ * @param buflen length of buf
+ * @return either pointer to buf which now holds the ASCII
+ *         representation of addr or NULL if buf was too small
+ */
+char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen)
+{
+  u32_t s_addr;
+  char inv[3];
+  char *rp;
+  u8_t *ap;
+  u8_t rem;
+  u8_t n;
+  u8_t i;
+  int len = 0;
+
+  s_addr = ip4_addr_get_u32(addr);
+
+  rp = buf;
+  ap = (u8_t *)&s_addr;
+  for(n = 0; n < 4; n++) {
+    i = 0;
+    do {
+      rem = *ap % (u8_t)10;
+      *ap /= (u8_t)10;
+      inv[i++] = '0' + rem;
+    } while(*ap);
+    while(i--) {
+      if (len++ >= buflen) {
+        return NULL;
+      }
+      *rp++ = inv[i];
+    }
+    if (len++ >= buflen) {
+      return NULL;
+    }
+    *rp++ = '.';
+    ap++;
+  }
+  *--rp = 0;
+  return buf;
+}
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/ip_frag.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/ip_frag.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv4/ip_frag.c	(revision 164)
@@ -0,0 +1,863 @@
+/**
+ * @file
+ * This is the IPv4 packet segmentation and reassembly implementation.
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Jani Monoses <jani@iv.ro> 
+ *         Simon Goldschmidt
+ * original reassembly code by Adam Dunkels <adam@sics.se>
+ * 
+ */
+
+#include "lwip/opt.h"
+#include "lwip/ip_frag.h"
+#include "lwip/def.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/netif.h"
+#include "lwip/snmp.h"
+#include "lwip/stats.h"
+#include "lwip/icmp.h"
+
+#include <string.h>
+
+#if IP_REASSEMBLY
+/**
+ * The IP reassembly code currently has the following limitations:
+ * - IP header options are not supported
+ * - fragments must not overlap (e.g. due to different routes),
+ *   currently, overlapping or duplicate fragments are thrown away
+ *   if IP_REASS_CHECK_OVERLAP=1 (the default)!
+ *
+ * @todo: work with IP header options
+ */
+
+/** Setting this to 0, you can turn off checking the fragments for overlapping
+ * regions. The code gets a little smaller. Only use this if you know that
+ * overlapping won't occur on your network! */
+#ifndef IP_REASS_CHECK_OVERLAP
+#define IP_REASS_CHECK_OVERLAP 1
+#endif /* IP_REASS_CHECK_OVERLAP */
+
+/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is
+ * full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller.
+ * Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA
+ * is set to 1, so one datagram can be reassembled at a time, only. */
+#ifndef IP_REASS_FREE_OLDEST
+#define IP_REASS_FREE_OLDEST 1
+#endif /* IP_REASS_FREE_OLDEST */
+
+#define IP_REASS_FLAG_LASTFRAG 0x01
+
+/** This is a helper struct which holds the starting
+ * offset and the ending offset of this fragment to
+ * easily chain the fragments.
+ * It has the same packing requirements as the IP header, since it replaces
+ * the IP header in memory in incoming fragments (after copying it) to keep
+ * track of the various fragments. (-> If the IP header doesn't need packing,
+ * this struct doesn't need packing, too.)
+ */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip_reass_helper {
+  PACK_STRUCT_FIELD(struct pbuf *next_pbuf);
+  PACK_STRUCT_FIELD(u16_t start);
+  PACK_STRUCT_FIELD(u16_t end);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB)  \
+  (ip_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \
+   ip_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \
+   IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0
+
+/* global variables */
+static struct ip_reassdata *reassdatagrams;
+static u16_t ip_reass_pbufcount;
+
+/* function prototypes */
+static void ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev);
+static int ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev);
+
+/**
+ * Reassembly timer base function
+ * for both NO_SYS == 0 and 1 (!).
+ *
+ * Should be called every 1000 msec (defined by IP_TMR_INTERVAL).
+ */
+void
+ip_reass_tmr(void)
+{
+  struct ip_reassdata *r, *prev = NULL;
+
+  r = reassdatagrams;
+  while (r != NULL) {
+    /* Decrement the timer. Once it reaches 0,
+     * clean up the incomplete fragment assembly */
+    if (r->timer > 0) {
+      r->timer--;
+      LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n",(u16_t)r->timer));
+      prev = r;
+      r = r->next;
+    } else {
+      /* reassembly timed out */
+      struct ip_reassdata *tmp;
+      LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer timed out\n"));
+      tmp = r;
+      /* get the next pointer before freeing */
+      r = r->next;
+      /* free the helper struct and all enqueued pbufs */
+      ip_reass_free_complete_datagram(tmp, prev);
+     }
+   }
+}
+
+/**
+ * Free a datagram (struct ip_reassdata) and all its pbufs.
+ * Updates the total count of enqueued pbufs (ip_reass_pbufcount),
+ * SNMP counters and sends an ICMP time exceeded packet.
+ *
+ * @param ipr datagram to free
+ * @param prev the previous datagram in the linked list
+ * @return the number of pbufs freed
+ */
+static int
+ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
+{
+  u16_t pbufs_freed = 0;
+  u8_t clen;
+  struct pbuf *p;
+  struct ip_reass_helper *iprh;
+
+  LWIP_ASSERT("prev != ipr", prev != ipr);
+  if (prev != NULL) {
+    LWIP_ASSERT("prev->next == ipr", prev->next == ipr);
+  }
+
+  snmp_inc_ipreasmfails();
+#if LWIP_ICMP
+  iprh = (struct ip_reass_helper *)ipr->p->payload;
+  if (iprh->start == 0) {
+    /* The first fragment was received, send ICMP time exceeded. */
+    /* First, de-queue the first pbuf from r->p. */
+    p = ipr->p;
+    ipr->p = iprh->next_pbuf;
+    /* Then, copy the original header into it. */
+    SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN);
+    icmp_time_exceeded(p, ICMP_TE_FRAG);
+    clen = pbuf_clen(p);
+    LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
+    pbufs_freed += clen;
+    pbuf_free(p);
+  }
+#endif /* LWIP_ICMP */
+
+  /* First, free all received pbufs.  The individual pbufs need to be released 
+     separately as they have not yet been chained */
+  p = ipr->p;
+  while (p != NULL) {
+    struct pbuf *pcur;
+    iprh = (struct ip_reass_helper *)p->payload;
+    pcur = p;
+    /* get the next pointer before freeing */
+    p = iprh->next_pbuf;
+    clen = pbuf_clen(pcur);
+    LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
+    pbufs_freed += clen;
+    pbuf_free(pcur);
+  }
+  /* Then, unchain the struct ip_reassdata from the list and free it. */
+  ip_reass_dequeue_datagram(ipr, prev);
+  LWIP_ASSERT("ip_reass_pbufcount >= clen", ip_reass_pbufcount >= pbufs_freed);
+  ip_reass_pbufcount -= pbufs_freed;
+
+  return pbufs_freed;
+}
+
+#if IP_REASS_FREE_OLDEST
+/**
+ * Free the oldest datagram to make room for enqueueing new fragments.
+ * The datagram 'fraghdr' belongs to is not freed!
+ *
+ * @param fraghdr IP header of the current fragment
+ * @param pbufs_needed number of pbufs needed to enqueue
+ *        (used for freeing other datagrams if not enough space)
+ * @return the number of pbufs freed
+ */
+static int
+ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed)
+{
+  /* @todo Can't we simply remove the last datagram in the
+   *       linked list behind reassdatagrams?
+   */
+  struct ip_reassdata *r, *oldest, *prev;
+  int pbufs_freed = 0, pbufs_freed_current;
+  int other_datagrams;
+
+  /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs,
+   * but don't free the datagram that 'fraghdr' belongs to! */
+  do {
+    oldest = NULL;
+    prev = NULL;
+    other_datagrams = 0;
+    r = reassdatagrams;
+    while (r != NULL) {
+      if (!IP_ADDRESSES_AND_ID_MATCH(&r->iphdr, fraghdr)) {
+        /* Not the same datagram as fraghdr */
+        other_datagrams++;
+        if (oldest == NULL) {
+          oldest = r;
+        } else if (r->timer <= oldest->timer) {
+          /* older than the previous oldest */
+          oldest = r;
+        }
+      }
+      if (r->next != NULL) {
+        prev = r;
+      }
+      r = r->next;
+    }
+    if (oldest != NULL) {
+      pbufs_freed_current = ip_reass_free_complete_datagram(oldest, prev);
+      pbufs_freed += pbufs_freed_current;
+    }
+  } while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1));
+  return pbufs_freed;
+}
+#endif /* IP_REASS_FREE_OLDEST */
+
+/**
+ * Enqueues a new fragment into the fragment queue
+ * @param fraghdr points to the new fragments IP hdr
+ * @param clen number of pbufs needed to enqueue (used for freeing other datagrams if not enough space)
+ * @return A pointer to the queue location into which the fragment was enqueued
+ */
+static struct ip_reassdata*
+ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen)
+{
+  struct ip_reassdata* ipr;
+  /* No matching previous fragment found, allocate a new reassdata struct */
+  ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA);
+  if (ipr == NULL) {
+#if IP_REASS_FREE_OLDEST
+    if (ip_reass_remove_oldest_datagram(fraghdr, clen) >= clen) {
+      ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA);
+    }
+    if (ipr == NULL)
+#endif /* IP_REASS_FREE_OLDEST */
+    {
+      IPFRAG_STATS_INC(ip_frag.memerr);
+      LWIP_DEBUGF(IP_REASS_DEBUG,("Failed to alloc reassdata struct\n"));
+      return NULL;
+    }
+  }
+  memset(ipr, 0, sizeof(struct ip_reassdata));
+  ipr->timer = IP_REASS_MAXAGE;
+
+  /* enqueue the new structure to the front of the list */
+  ipr->next = reassdatagrams;
+  reassdatagrams = ipr;
+  /* copy the ip header for later tests and input */
+  /* @todo: no ip options supported? */
+  SMEMCPY(&(ipr->iphdr), fraghdr, IP_HLEN);
+  return ipr;
+}
+
+/**
+ * Dequeues a datagram from the datagram queue. Doesn't deallocate the pbufs.
+ * @param ipr points to the queue entry to dequeue
+ */
+static void
+ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
+{
+  
+  /* dequeue the reass struct  */
+  if (reassdatagrams == ipr) {
+    /* it was the first in the list */
+    reassdatagrams = ipr->next;
+  } else {
+    /* it wasn't the first, so it must have a valid 'prev' */
+    LWIP_ASSERT("sanity check linked list", prev != NULL);
+    prev->next = ipr->next;
+  }
+
+  /* now we can free the ip_reass struct */
+  memp_free(MEMP_REASSDATA, ipr);
+}
+
+/**
+ * Chain a new pbuf into the pbuf list that composes the datagram.  The pbuf list
+ * will grow over time as  new pbufs are rx.
+ * Also checks that the datagram passes basic continuity checks (if the last
+ * fragment was received at least once).
+ * @param root_p points to the 'root' pbuf for the current datagram being assembled.
+ * @param new_p points to the pbuf for the current fragment
+ * @return 0 if invalid, >0 otherwise
+ */
+static int
+ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p)
+{
+  struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL;
+  struct pbuf *q;
+  u16_t offset,len;
+  struct ip_hdr *fraghdr;
+  int valid = 1;
+
+  /* Extract length and fragment offset from current fragment */
+  fraghdr = (struct ip_hdr*)new_p->payload; 
+  len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
+  offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
+
+  /* overwrite the fragment's ip header from the pbuf with our helper struct,
+   * and setup the embedded helper structure. */
+  /* make sure the struct ip_reass_helper fits into the IP header */
+  LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN",
+              sizeof(struct ip_reass_helper) <= IP_HLEN);
+  iprh = (struct ip_reass_helper*)new_p->payload;
+  iprh->next_pbuf = NULL;
+  iprh->start = offset;
+  iprh->end = offset + len;
+
+  /* Iterate through until we either get to the end of the list (append),
+   * or we find on with a larger offset (insert). */
+  for (q = ipr->p; q != NULL;) {
+    iprh_tmp = (struct ip_reass_helper*)q->payload;
+    if (iprh->start < iprh_tmp->start) {
+      /* the new pbuf should be inserted before this */
+      iprh->next_pbuf = q;
+      if (iprh_prev != NULL) {
+        /* not the fragment with the lowest offset */
+#if IP_REASS_CHECK_OVERLAP
+        if ((iprh->start < iprh_prev->end) || (iprh->end > iprh_tmp->start)) {
+          /* fragment overlaps with previous or following, throw away */
+          goto freepbuf;
+        }
+#endif /* IP_REASS_CHECK_OVERLAP */
+        iprh_prev->next_pbuf = new_p;
+      } else {
+        /* fragment with the lowest offset */
+        ipr->p = new_p;
+      }
+      break;
+    } else if(iprh->start == iprh_tmp->start) {
+      /* received the same datagram twice: no need to keep the datagram */
+      goto freepbuf;
+#if IP_REASS_CHECK_OVERLAP
+    } else if(iprh->start < iprh_tmp->end) {
+      /* overlap: no need to keep the new datagram */
+      goto freepbuf;
+#endif /* IP_REASS_CHECK_OVERLAP */
+    } else {
+      /* Check if the fragments received so far have no wholes. */
+      if (iprh_prev != NULL) {
+        if (iprh_prev->end != iprh_tmp->start) {
+          /* There is a fragment missing between the current
+           * and the previous fragment */
+          valid = 0;
+        }
+      }
+    }
+    q = iprh_tmp->next_pbuf;
+    iprh_prev = iprh_tmp;
+  }
+
+  /* If q is NULL, then we made it to the end of the list. Determine what to do now */
+  if (q == NULL) {
+    if (iprh_prev != NULL) {
+      /* this is (for now), the fragment with the highest offset:
+       * chain it to the last fragment */
+#if IP_REASS_CHECK_OVERLAP
+      LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start);
+#endif /* IP_REASS_CHECK_OVERLAP */
+      iprh_prev->next_pbuf = new_p;
+      if (iprh_prev->end != iprh->start) {
+        valid = 0;
+      }
+    } else {
+#if IP_REASS_CHECK_OVERLAP
+      LWIP_ASSERT("no previous fragment, this must be the first fragment!",
+        ipr->p == NULL);
+#endif /* IP_REASS_CHECK_OVERLAP */
+      /* this is the first fragment we ever received for this ip datagram */
+      ipr->p = new_p;
+    }
+  }
+
+  /* At this point, the validation part begins: */
+  /* If we already received the last fragment */
+  if ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0) {
+    /* and had no wholes so far */
+    if (valid) {
+      /* then check if the rest of the fragments is here */
+      /* Check if the queue starts with the first datagram */
+      if (((struct ip_reass_helper*)ipr->p->payload)->start != 0) {
+        valid = 0;
+      } else {
+        /* and check that there are no wholes after this datagram */
+        iprh_prev = iprh;
+        q = iprh->next_pbuf;
+        while (q != NULL) {
+          iprh = (struct ip_reass_helper*)q->payload;
+          if (iprh_prev->end != iprh->start) {
+            valid = 0;
+            break;
+          }
+          iprh_prev = iprh;
+          q = iprh->next_pbuf;
+        }
+        /* if still valid, all fragments are received
+         * (because to the MF==0 already arrived */
+        if (valid) {
+          LWIP_ASSERT("sanity check", ipr->p != NULL);
+          LWIP_ASSERT("sanity check",
+            ((struct ip_reass_helper*)ipr->p->payload) != iprh);
+          LWIP_ASSERT("validate_datagram:next_pbuf!=NULL",
+            iprh->next_pbuf == NULL);
+          LWIP_ASSERT("validate_datagram:datagram end!=datagram len",
+            iprh->end == ipr->datagram_len);
+        }
+      }
+    }
+    /* If valid is 0 here, there are some fragments missing in the middle
+     * (since MF == 0 has already arrived). Such datagrams simply time out if
+     * no more fragments are received... */
+    return valid;
+  }
+  /* If we come here, not all fragments were received, yet! */
+  return 0; /* not yet valid! */
+#if IP_REASS_CHECK_OVERLAP
+freepbuf:
+  ip_reass_pbufcount -= pbuf_clen(new_p);
+  pbuf_free(new_p);
+  return 0;
+#endif /* IP_REASS_CHECK_OVERLAP */
+}
+
+/**
+ * Reassembles incoming IP fragments into an IP datagram.
+ *
+ * @param p points to a pbuf chain of the fragment
+ * @return NULL if reassembly is incomplete, ? otherwise
+ */
+struct pbuf *
+ip_reass(struct pbuf *p)
+{
+  struct pbuf *r;
+  struct ip_hdr *fraghdr;
+  struct ip_reassdata *ipr;
+  struct ip_reass_helper *iprh;
+  u16_t offset, len;
+  u8_t clen;
+  struct ip_reassdata *ipr_prev = NULL;
+
+  IPFRAG_STATS_INC(ip_frag.recv);
+  snmp_inc_ipreasmreqds();
+
+  fraghdr = (struct ip_hdr*)p->payload;
+
+  if ((IPH_HL(fraghdr) * 4) != IP_HLEN) {
+    LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: IP options currently not supported!\n"));
+    IPFRAG_STATS_INC(ip_frag.err);
+    goto nullreturn;
+  }
+
+  offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
+  len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
+
+  /* Check if we are allowed to enqueue more datagrams. */
+  clen = pbuf_clen(p);
+  if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) {
+#if IP_REASS_FREE_OLDEST
+    if (!ip_reass_remove_oldest_datagram(fraghdr, clen) ||
+        ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS))
+#endif /* IP_REASS_FREE_OLDEST */
+    {
+      /* No datagram could be freed and still too many pbufs enqueued */
+      LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n",
+        ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS));
+      IPFRAG_STATS_INC(ip_frag.memerr);
+      /* @todo: send ICMP time exceeded here? */
+      /* drop this pbuf */
+      goto nullreturn;
+    }
+  }
+
+  /* Look for the datagram the fragment belongs to in the current datagram queue,
+   * remembering the previous in the queue for later dequeueing. */
+  for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) {
+    /* Check if the incoming fragment matches the one currently present
+       in the reassembly buffer. If so, we proceed with copying the
+       fragment into the buffer. */
+    if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) {
+      LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching previous fragment ID=%"X16_F"\n",
+        ntohs(IPH_ID(fraghdr))));
+      IPFRAG_STATS_INC(ip_frag.cachehit);
+      break;
+    }
+    ipr_prev = ipr;
+  }
+
+  if (ipr == NULL) {
+  /* Enqueue a new datagram into the datagram queue */
+    ipr = ip_reass_enqueue_new_datagram(fraghdr, clen);
+    /* Bail if unable to enqueue */
+    if(ipr == NULL) {
+      goto nullreturn;
+    }
+  } else {
+    if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) && 
+      ((ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) {
+      /* ipr->iphdr is not the header from the first fragment, but fraghdr is
+       * -> copy fraghdr into ipr->iphdr since we want to have the header
+       * of the first fragment (for ICMP time exceeded and later, for copying
+       * all options, if supported)*/
+      SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN);
+    }
+  }
+  /* Track the current number of pbufs current 'in-flight', in order to limit 
+  the number of fragments that may be enqueued at any one time */
+  ip_reass_pbufcount += clen;
+
+  /* At this point, we have either created a new entry or pointing 
+   * to an existing one */
+
+  /* check for 'no more fragments', and update queue entry*/
+  if ((IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0) {
+    ipr->flags |= IP_REASS_FLAG_LASTFRAG;
+    ipr->datagram_len = offset + len;
+    LWIP_DEBUGF(IP_REASS_DEBUG,
+     ("ip_reass: last fragment seen, total len %"S16_F"\n",
+      ipr->datagram_len));
+  }
+  /* find the right place to insert this pbuf */
+  /* @todo: trim pbufs if fragments are overlapping */
+  if (ip_reass_chain_frag_into_datagram_and_validate(ipr, p)) {
+    /* the totally last fragment (flag more fragments = 0) was received at least
+     * once AND all fragments are received */
+    ipr->datagram_len += IP_HLEN;
+
+    /* save the second pbuf before copying the header over the pointer */
+    r = ((struct ip_reass_helper*)ipr->p->payload)->next_pbuf;
+
+    /* copy the original ip header back to the first pbuf */
+    fraghdr = (struct ip_hdr*)(ipr->p->payload);
+    SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN);
+    IPH_LEN_SET(fraghdr, htons(ipr->datagram_len));
+    IPH_OFFSET_SET(fraghdr, 0);
+    IPH_CHKSUM_SET(fraghdr, 0);
+    /* @todo: do we need to set calculate the correct checksum? */
+    IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN));
+
+    p = ipr->p;
+
+    /* chain together the pbufs contained within the reass_data list. */
+    while(r != NULL) {
+      iprh = (struct ip_reass_helper*)r->payload;
+
+      /* hide the ip header for every succeding fragment */
+      pbuf_header(r, -IP_HLEN);
+      pbuf_cat(p, r);
+      r = iprh->next_pbuf;
+    }
+    /* release the sources allocate for the fragment queue entry */
+    ip_reass_dequeue_datagram(ipr, ipr_prev);
+
+    /* and adjust the number of pbufs currently queued for reassembly. */
+    ip_reass_pbufcount -= pbuf_clen(p);
+
+    /* Return the pbuf chain */
+    return p;
+  }
+  /* the datagram is not (yet?) reassembled completely */
+  LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount));
+  return NULL;
+
+nullreturn:
+  LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: nullreturn\n"));
+  IPFRAG_STATS_INC(ip_frag.drop);
+  pbuf_free(p);
+  return NULL;
+}
+#endif /* IP_REASSEMBLY */
+
+#if IP_FRAG
+#if IP_FRAG_USES_STATIC_BUF
+static u8_t buf[LWIP_MEM_ALIGN_SIZE(IP_FRAG_MAX_MTU + MEM_ALIGNMENT - 1)];
+#else /* IP_FRAG_USES_STATIC_BUF */
+
+#if !LWIP_NETIF_TX_SINGLE_PBUF
+/** Allocate a new struct pbuf_custom_ref */
+static struct pbuf_custom_ref*
+ip_frag_alloc_pbuf_custom_ref(void)
+{
+  return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF);
+}
+
+/** Free a struct pbuf_custom_ref */
+static void
+ip_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p)
+{
+  LWIP_ASSERT("p != NULL", p != NULL);
+  memp_free(MEMP_FRAG_PBUF, p);
+}
+
+/** Free-callback function to free a 'struct pbuf_custom_ref', called by
+ * pbuf_free. */
+static void
+ipfrag_free_pbuf_custom(struct pbuf *p)
+{
+  struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p;
+  LWIP_ASSERT("pcr != NULL", pcr != NULL);
+  LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p);
+  if (pcr->original != NULL) {
+    pbuf_free(pcr->original);
+  }
+  ip_frag_free_pbuf_custom_ref(pcr);
+}
+#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */
+#endif /* IP_FRAG_USES_STATIC_BUF */
+
+/**
+ * Fragment an IP datagram if too large for the netif.
+ *
+ * Chop the datagram in MTU sized chunks and send them in order
+ * by using a fixed size static memory buffer (PBUF_REF) or
+ * point PBUF_REFs into p (depending on IP_FRAG_USES_STATIC_BUF).
+ *
+ * @param p ip packet to send
+ * @param netif the netif on which to send
+ * @param dest destination ip address to which to send
+ *
+ * @return ERR_OK if sent successfully, err_t otherwise
+ */
+err_t 
+ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest)
+{
+  struct pbuf *rambuf;
+#if IP_FRAG_USES_STATIC_BUF
+  struct pbuf *header;
+#else
+#if !LWIP_NETIF_TX_SINGLE_PBUF
+  struct pbuf *newpbuf;
+#endif
+  struct ip_hdr *original_iphdr;
+#endif
+  struct ip_hdr *iphdr;
+  u16_t nfb;
+  u16_t left, cop;
+  u16_t mtu = netif->mtu;
+  u16_t ofo, omf;
+  u16_t last;
+  u16_t poff = IP_HLEN;
+  u16_t tmp;
+#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF
+  u16_t newpbuflen = 0;
+  u16_t left_to_copy;
+#endif
+
+  /* Get a RAM based MTU sized pbuf */
+#if IP_FRAG_USES_STATIC_BUF
+  /* When using a static buffer, we use a PBUF_REF, which we will
+   * use to reference the packet (without link header).
+   * Layer and length is irrelevant.
+   */
+  rambuf = pbuf_alloc(PBUF_LINK, 0, PBUF_REF);
+  if (rambuf == NULL) {
+    LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc(PBUF_LINK, 0, PBUF_REF) failed\n"));
+    return ERR_MEM;
+  }
+  rambuf->tot_len = rambuf->len = mtu;
+  rambuf->payload = LWIP_MEM_ALIGN((void *)buf);
+
+  /* Copy the IP header in it */
+  iphdr = (struct ip_hdr *)rambuf->payload;
+  SMEMCPY(iphdr, p->payload, IP_HLEN);
+#else /* IP_FRAG_USES_STATIC_BUF */
+  original_iphdr = (struct ip_hdr *)p->payload;
+  iphdr = original_iphdr;
+#endif /* IP_FRAG_USES_STATIC_BUF */
+
+  /* Save original offset */
+  tmp = ntohs(IPH_OFFSET(iphdr));
+  ofo = tmp & IP_OFFMASK;
+  omf = tmp & IP_MF;
+
+  left = p->tot_len - IP_HLEN;
+
+  nfb = (mtu - IP_HLEN) / 8;
+
+  while (left) {
+    last = (left <= mtu - IP_HLEN);
+
+    /* Set new offset and MF flag */
+    tmp = omf | (IP_OFFMASK & (ofo));
+    if (!last) {
+      tmp = tmp | IP_MF;
+    }
+
+    /* Fill this fragment */
+    cop = last ? left : nfb * 8;
+
+#if IP_FRAG_USES_STATIC_BUF
+    poff += pbuf_copy_partial(p, (u8_t*)iphdr + IP_HLEN, cop, poff);
+#else /* IP_FRAG_USES_STATIC_BUF */
+#if LWIP_NETIF_TX_SINGLE_PBUF
+    rambuf = pbuf_alloc(PBUF_IP, cop, PBUF_RAM);
+    if (rambuf == NULL) {
+      return ERR_MEM;
+    }
+    LWIP_ASSERT("this needs a pbuf in one piece!",
+      (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
+    poff += pbuf_copy_partial(p, rambuf->payload, cop, poff);
+    /* make room for the IP header */
+    if(pbuf_header(rambuf, IP_HLEN)) {
+      pbuf_free(rambuf);
+      return ERR_MEM;
+    }
+    /* fill in the IP header */
+    SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
+    iphdr = rambuf->payload;
+#else /* LWIP_NETIF_TX_SINGLE_PBUF */
+    /* When not using a static buffer, create a chain of pbufs.
+     * The first will be a PBUF_RAM holding the link and IP header.
+     * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged,
+     * but limited to the size of an mtu.
+     */
+    rambuf = pbuf_alloc(PBUF_LINK, IP_HLEN, PBUF_RAM);
+    if (rambuf == NULL) {
+      return ERR_MEM;
+    }
+    LWIP_ASSERT("this needs a pbuf in one piece!",
+                (p->len >= (IP_HLEN)));
+    SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
+    iphdr = (struct ip_hdr *)rambuf->payload;
+
+    /* Can just adjust p directly for needed offset. */
+    p->payload = (u8_t *)p->payload + poff;
+    p->len -= poff;
+
+    left_to_copy = cop;
+    while (left_to_copy) {
+      struct pbuf_custom_ref *pcr;
+      newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len;
+      /* Is this pbuf already empty? */
+      if (!newpbuflen) {
+        p = p->next;
+        continue;
+      }
+      pcr = ip_frag_alloc_pbuf_custom_ref();
+      if (pcr == NULL) {
+        pbuf_free(rambuf);
+        return ERR_MEM;
+      }
+      /* Mirror this pbuf, although we might not need all of it. */
+      newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen);
+      if (newpbuf == NULL) {
+        ip_frag_free_pbuf_custom_ref(pcr);
+        pbuf_free(rambuf);
+        return ERR_MEM;
+      }
+      pbuf_ref(p);
+      pcr->original = p;
+      pcr->pc.custom_free_function = ipfrag_free_pbuf_custom;
+
+      /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain
+       * so that it is removed when pbuf_dechain is later called on rambuf.
+       */
+      pbuf_cat(rambuf, newpbuf);
+      left_to_copy -= newpbuflen;
+      if (left_to_copy) {
+        p = p->next;
+      }
+    }
+    poff = newpbuflen;
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
+#endif /* IP_FRAG_USES_STATIC_BUF */
+
+    /* Correct header */
+    IPH_OFFSET_SET(iphdr, htons(tmp));
+    IPH_LEN_SET(iphdr, htons(cop + IP_HLEN));
+    IPH_CHKSUM_SET(iphdr, 0);
+    IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
+
+#if IP_FRAG_USES_STATIC_BUF
+    if (last) {
+      pbuf_realloc(rambuf, left + IP_HLEN);
+    }
+
+    /* This part is ugly: we alloc a RAM based pbuf for 
+     * the link level header for each chunk and then 
+     * free it.A PBUF_ROM style pbuf for which pbuf_header
+     * worked would make things simpler.
+     */
+    header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM);
+    if (header != NULL) {
+      pbuf_chain(header, rambuf);
+      netif->output(netif, header, dest);
+      IPFRAG_STATS_INC(ip_frag.xmit);
+      snmp_inc_ipfragcreates();
+      pbuf_free(header);
+    } else {
+      LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc() for header failed\n"));
+      pbuf_free(rambuf);
+      return ERR_MEM;
+    }
+#else /* IP_FRAG_USES_STATIC_BUF */
+    /* No need for separate header pbuf - we allowed room for it in rambuf
+     * when allocated.
+     */
+    netif->output(netif, rambuf, dest);
+    IPFRAG_STATS_INC(ip_frag.xmit);
+
+    /* Unfortunately we can't reuse rambuf - the hardware may still be
+     * using the buffer. Instead we free it (and the ensuing chain) and
+     * recreate it next time round the loop. If we're lucky the hardware
+     * will have already sent the packet, the free will really free, and
+     * there will be zero memory penalty.
+     */
+    
+    pbuf_free(rambuf);
+#endif /* IP_FRAG_USES_STATIC_BUF */
+    left -= cop;
+    ofo += nfb;
+  }
+#if IP_FRAG_USES_STATIC_BUF
+  pbuf_free(rambuf);
+#endif /* IP_FRAG_USES_STATIC_BUF */
+  snmp_inc_ipfragoks();
+  return ERR_OK;
+}
+#endif /* IP_FRAG */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/README
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/README	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/README	(revision 164)
@@ -0,0 +1,1 @@
+IPv6 support in lwIP is very experimental.
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/icmp6.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/icmp6.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/icmp6.c	(revision 164)
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/* Some ICMP messages should be passed to the transport protocols. This
+   is not implemented. */
+
+#include "lwip/opt.h"
+
+#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/icmp.h"
+#include "lwip/inet.h"
+#include "lwip/ip.h"
+#include "lwip/def.h"
+#include "lwip/stats.h"
+
+void
+icmp_input(struct pbuf *p, struct netif *inp)
+{
+  u8_t type;
+  struct icmp_echo_hdr *iecho;
+  struct ip_hdr *iphdr;
+  struct ip_addr tmpaddr;
+
+  ICMP_STATS_INC(icmp.recv);
+
+  /* TODO: check length before accessing payload! */
+
+  type = ((u8_t *)p->payload)[0];
+
+  switch (type) {
+  case ICMP6_ECHO:
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
+
+    if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
+      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
+
+      pbuf_free(p);
+      ICMP_STATS_INC(icmp.lenerr);
+      return;
+    }
+    iecho = p->payload;
+    iphdr = (struct ip_hdr *)((u8_t *)p->payload - IP_HLEN);
+    if (inet_chksum_pbuf(p) != 0) {
+      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%"X16_F")\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len)));
+      ICMP_STATS_INC(icmp.chkerr);
+    /*      return;*/
+    }
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp: p->len %"S16_F" p->tot_len %"S16_F"\n", p->len, p->tot_len));
+    ip_addr_set(&tmpaddr, &(iphdr->src));
+    ip_addr_set(&(iphdr->src), &(iphdr->dest));
+    ip_addr_set(&(iphdr->dest), &tmpaddr);
+    iecho->type = ICMP6_ER;
+    /* adjust the checksum */
+    if (iecho->chksum >= htons(0xffff - (ICMP6_ECHO << 8))) {
+      iecho->chksum += htons(ICMP6_ECHO << 8) + 1;
+    } else {
+      iecho->chksum += htons(ICMP6_ECHO << 8);
+    }
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%"X16_F")\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len)));
+    ICMP_STATS_INC(icmp.xmit);
+
+    /*    LWIP_DEBUGF("icmp: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len);*/
+    ip_output_if (p, &(iphdr->src), IP_HDRINCL,
+     iphdr->hoplim, IP_PROTO_ICMP, inp);
+    break;
+  default:
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" not supported.\n", (s16_t)type));
+    ICMP_STATS_INC(icmp.proterr);
+    ICMP_STATS_INC(icmp.drop);
+  }
+
+  pbuf_free(p);
+}
+
+void
+icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
+{
+  struct pbuf *q;
+  struct ip_hdr *iphdr;
+  struct icmp_dur_hdr *idur;
+
+  /* @todo: can this be PBUF_LINK instead of PBUF_IP? */
+  q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);
+  /* ICMP header + IP header + 8 bytes of data */
+  if (q == NULL) {
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_dest_unreach: failed to allocate pbuf for ICMP packet.\n"));
+    pbuf_free(p);
+    return;
+  }
+  LWIP_ASSERT("check that first pbuf can hold icmp message",
+             (q->len >= (8 + IP_HLEN + 8)));
+
+  iphdr = p->payload;
+
+  idur = q->payload;
+  idur->type = (u8_t)ICMP6_DUR;
+  idur->icode = (u8_t)t;
+
+  SMEMCPY((u8_t *)q->payload + 8, p->payload, IP_HLEN + 8);
+
+  /* calculate checksum */
+  idur->chksum = 0;
+  idur->chksum = inet_chksum(idur, q->len);
+  ICMP_STATS_INC(icmp.xmit);
+
+  ip_output(q, NULL,
+      (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
+  pbuf_free(q);
+}
+
+void
+icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
+{
+  struct pbuf *q;
+  struct ip_hdr *iphdr;
+  struct icmp_te_hdr *tehdr;
+
+  LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded\n"));
+
+  /* @todo: can this be PBUF_LINK instead of PBUF_IP? */
+  q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);
+  /* ICMP header + IP header + 8 bytes of data */
+  if (q == NULL) {
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_dest_unreach: failed to allocate pbuf for ICMP packet.\n"));
+    pbuf_free(p);
+    return;
+  }
+  LWIP_ASSERT("check that first pbuf can hold icmp message",
+             (q->len >= (8 + IP_HLEN + 8)));
+
+  iphdr = p->payload;
+
+  tehdr = q->payload;
+  tehdr->type = (u8_t)ICMP6_TE;
+  tehdr->icode = (u8_t)t;
+
+  /* copy fields from original packet */
+  SMEMCPY((u8_t *)q->payload + 8, (u8_t *)p->payload, IP_HLEN + 8);
+
+  /* calculate checksum */
+  tehdr->chksum = 0;
+  tehdr->chksum = inet_chksum(tehdr, q->len);
+  ICMP_STATS_INC(icmp.xmit);
+  ip_output(q, NULL,
+      (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
+  pbuf_free(q);
+}
+
+#endif /* LWIP_ICMP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/inet6.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/inet6.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/inet6.c	(revision 164)
@@ -0,0 +1,163 @@
+/**
+ * @file
+ * Functions common to all TCP/IPv6 modules, such as the Internet checksum and the
+ * byte order functions.
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/def.h"
+#include "lwip/inet.h"
+
+/* chksum:
+ *
+ * Sums up all 16 bit words in a memory portion. Also includes any odd byte.
+ * This function is used by the other checksum functions.
+ *
+ * For now, this is not optimized. Must be optimized for the particular processor
+ * arcitecture on which it is to run. Preferebly coded in assembler.
+ */
+
+static u32_t
+chksum(void *dataptr, u16_t len)
+{
+  u16_t *sdataptr = dataptr;
+  u32_t acc;
+  
+  
+  for(acc = 0; len > 1; len -= 2) {
+    acc += *sdataptr++;
+  }
+
+  /* add up any odd byte */
+  if (len == 1) {
+    acc += htons((u16_t)(*(u8_t *)dataptr) << 8);
+  }
+
+  return acc;
+
+}
+
+/* inet_chksum_pseudo:
+ *
+ * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
+ */
+
+u16_t
+inet_chksum_pseudo(struct pbuf *p,
+       struct ip_addr *src, struct ip_addr *dest,
+       u8_t proto, u32_t proto_len)
+{
+  u32_t acc;
+  struct pbuf *q;
+  u8_t swapped, i;
+
+  acc = 0;
+  swapped = 0;
+  for(q = p; q != NULL; q = q->next) {    
+    acc += chksum(q->payload, q->len);
+    while (acc >> 16) {
+      acc = (acc & 0xffff) + (acc >> 16);
+    }
+    if (q->len % 2 != 0) {
+      swapped = 1 - swapped;
+      acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
+    }
+  }
+
+  if (swapped) {
+    acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
+  }
+  
+  for(i = 0; i < 8; i++) {
+    acc += ((u16_t *)src->addr)[i] & 0xffff;
+    acc += ((u16_t *)dest->addr)[i] & 0xffff;
+    while (acc >> 16) {
+      acc = (acc & 0xffff) + (acc >> 16);
+    }
+  }
+  acc += (u16_t)htons((u16_t)proto);
+  acc += ((u16_t *)&proto_len)[0] & 0xffff;
+  acc += ((u16_t *)&proto_len)[1] & 0xffff;
+
+  while (acc >> 16) {
+    acc = (acc & 0xffff) + (acc >> 16);
+  }
+  return ~(acc & 0xffff);
+}
+
+/* inet_chksum:
+ *
+ * Calculates the Internet checksum over a portion of memory. Used primarely for IP
+ * and ICMP.
+ */
+
+u16_t
+inet_chksum(void *dataptr, u16_t len)
+{
+  u32_t acc, sum;
+
+  acc = chksum(dataptr, len);
+  sum = (acc & 0xffff) + (acc >> 16);
+  sum += (sum >> 16);
+  return ~(sum & 0xffff);
+}
+
+u16_t
+inet_chksum_pbuf(struct pbuf *p)
+{
+  u32_t acc;
+  struct pbuf *q;
+  u8_t swapped;
+  
+  acc = 0;
+  swapped = 0;
+  for(q = p; q != NULL; q = q->next) {
+    acc += chksum(q->payload, q->len);
+    while (acc >> 16) {
+      acc = (acc & 0xffff) + (acc >> 16);
+    }    
+    if (q->len % 2 != 0) {
+      swapped = 1 - swapped;
+      acc = (acc & 0xff << 8) | (acc & 0xff00 >> 8);
+    }
+  }
+ 
+  if (swapped) {
+    acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
+  }
+  return ~(acc & 0xffff);
+}
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/ip6.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/ip6.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/ip6.c	(revision 164)
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+
+
+/* ip.c
+ *
+ * This is the code for the IP layer for IPv6.
+ *
+ */
+
+
+#include "lwip/opt.h"
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/ip.h"
+#include "lwip/inet.h"
+#include "lwip/netif.h"
+#include "lwip/icmp.h"
+#include "lwip/udp.h"
+#include "lwip/tcp_impl.h"
+
+#include "lwip/stats.h"
+
+#include "arch/perf.h"
+
+/* ip_init:
+ *
+ * Initializes the IP layer.
+ */
+
+void
+ip_init(void)
+{
+}
+
+/* ip_route:
+ *
+ * Finds the appropriate network interface for a given IP address. It searches the
+ * list of network interfaces linearly. A match is found if the masked IP address of
+ * the network interface equals the masked IP address given to the function.
+ */
+
+struct netif *
+ip_route(struct ip_addr *dest)
+{
+  struct netif *netif;
+
+  for(netif = netif_list; netif != NULL; netif = netif->next) {
+    if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
+      return netif;
+    }
+  }
+
+  return netif_default;
+}
+
+/* ip_forward:
+ *
+ * Forwards an IP packet. It finds an appropriate route for the packet, decrements
+ * the TTL value of the packet, adjusts the checksum and outputs the packet on the
+ * appropriate interface.
+ */
+
+static void
+ip_forward(struct pbuf *p, struct ip_hdr *iphdr)
+{
+  struct netif *netif;
+
+  PERF_START;
+
+  if ((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) {
+
+    LWIP_DEBUGF(IP_DEBUG, ("ip_input: no forwarding route found for "));
+#if IP_DEBUG
+    ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest)));
+#endif /* IP_DEBUG */
+    LWIP_DEBUGF(IP_DEBUG, ("\n"));
+    pbuf_free(p);
+    return;
+  }
+  /* Decrement TTL and send ICMP if ttl == 0. */
+  if (--iphdr->hoplim == 0) {
+#if LWIP_ICMP
+    /* Don't send ICMP messages in response to ICMP messages */
+    if (iphdr->nexthdr != IP_PROTO_ICMP) {
+      icmp_time_exceeded(p, ICMP_TE_TTL);
+    }
+#endif /* LWIP_ICMP */
+    pbuf_free(p);
+    return;
+  }
+
+  /* Incremental update of the IP checksum. */
+  /*  if (iphdr->chksum >= htons(0xffff - 0x100)) {
+    iphdr->chksum += htons(0x100) + 1;
+  } else {
+    iphdr->chksum += htons(0x100);
+    }*/
+
+
+  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to "));
+#if IP_DEBUG
+  ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest)));
+#endif /* IP_DEBUG */
+  LWIP_DEBUGF(IP_DEBUG, ("\n"));
+
+  IP_STATS_INC(ip.fw);
+  IP_STATS_INC(ip.xmit);
+
+  PERF_STOP("ip_forward");
+
+  netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
+}
+
+/* ip_input:
+ *
+ * This function is called by the network interface device driver when an IP packet is
+ * received. The function does the basic checks of the IP header such as packet size
+ * being at least larger than the header size etc. If the packet was not destined for
+ * us, the packet is forwarded (using ip_forward). The IP checksum is always checked.
+ *
+ * Finally, the packet is sent to the upper layer protocol input function.
+ */
+
+void
+ip_input(struct pbuf *p, struct netif *inp) {
+  struct ip_hdr *iphdr;
+  struct netif *netif;
+
+
+  PERF_START;
+
+#if IP_DEBUG
+  ip_debug_print(p);
+#endif /* IP_DEBUG */
+
+
+  IP_STATS_INC(ip.recv);
+
+  /* identify the IP header */
+  iphdr = p->payload;
+
+
+  if (iphdr->v != 6) {
+    LWIP_DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number\n"));
+#if IP_DEBUG
+    ip_debug_print(p);
+#endif /* IP_DEBUG */
+    pbuf_free(p);
+    IP_STATS_INC(ip.err);
+    IP_STATS_INC(ip.drop);
+    return;
+  }
+
+  /* is this packet for us? */
+  for(netif = netif_list; netif != NULL; netif = netif->next) {
+#if IP_DEBUG
+    LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest "));
+    ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest)));
+    LWIP_DEBUGF(IP_DEBUG, ("netif->ip_addr "));
+    ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest)));
+    LWIP_DEBUGF(IP_DEBUG, ("\n"));
+#endif /* IP_DEBUG */
+    if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr))) {
+      break;
+    }
+  }
+
+
+  if (netif == NULL) {
+    /* packet not for us, route or discard */
+#if IP_FORWARD
+    ip_forward(p, iphdr);
+#endif
+    pbuf_free(p);
+    return;
+  }
+
+  pbuf_realloc(p, IP_HLEN + ntohs(iphdr->len));
+
+  /* send to upper layers */
+#if IP_DEBUG
+  /*  LWIP_DEBUGF("ip_input: \n");
+  ip_debug_print(p);
+  LWIP_DEBUGF("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len);*/
+#endif /* IP_DEBUG */
+
+  if(pbuf_header(p, -IP_HLEN)) {
+    LWIP_ASSERT("Can't move over header in packet", 0);
+    return;
+  }
+
+  switch (iphdr->nexthdr) {
+  case IP_PROTO_UDP:
+    udp_input(p, inp);
+    break;
+  case IP_PROTO_TCP:
+    tcp_input(p, inp);
+    break;
+#if LWIP_ICMP
+  case IP_PROTO_ICMP:
+    icmp_input(p, inp);
+    break;
+#endif /* LWIP_ICMP */
+  default:
+#if LWIP_ICMP
+    /* send ICMP destination protocol unreachable */
+    icmp_dest_unreach(p, ICMP_DUR_PROTO);
+#endif /* LWIP_ICMP */
+    pbuf_free(p);
+    LWIP_DEBUGF(IP_DEBUG, ("Unsupported transport protocol %"U16_F"\n",
+          iphdr->nexthdr));
+
+    IP_STATS_INC(ip.proterr);
+    IP_STATS_INC(ip.drop);
+  }
+  PERF_STOP("ip_input");
+}
+
+
+/* ip_output_if:
+ *
+ * Sends an IP packet on a network interface. This function constructs the IP header
+ * and calculates the IP header checksum. If the source IP address is NULL,
+ * the IP address of the outgoing network interface is filled in as source address.
+ */
+
+err_t
+ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
+       u8_t ttl,
+       u8_t proto, struct netif *netif)
+{
+  struct ip_hdr *iphdr;
+
+  PERF_START;
+
+  LWIP_DEBUGF(IP_DEBUG, ("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len));
+  if (pbuf_header(p, IP_HLEN)) {
+    LWIP_DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n"));
+    IP_STATS_INC(ip.err);
+
+    return ERR_BUF;
+  }
+  LWIP_DEBUGF(IP_DEBUG, ("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len));
+
+  iphdr = p->payload;
+
+
+  if (dest != IP_HDRINCL) {
+    LWIP_DEBUGF(IP_DEBUG, ("!IP_HDRLINCL\n"));
+    iphdr->hoplim = ttl;
+    iphdr->nexthdr = proto;
+    iphdr->len = htons(p->tot_len - IP_HLEN);
+    ip_addr_set(&(iphdr->dest), dest);
+
+    iphdr->v = 6;
+
+    if (ip_addr_isany(src)) {
+      ip_addr_set(&(iphdr->src), &(netif->ip_addr));
+    } else {
+      ip_addr_set(&(iphdr->src), src);
+    }
+
+  } else {
+    dest = &(iphdr->dest);
+  }
+
+  IP_STATS_INC(ip.xmit);
+
+  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c (len %"U16_F")\n", netif->name[0], netif->name[1], p->tot_len));
+#if IP_DEBUG
+  ip_debug_print(p);
+#endif /* IP_DEBUG */
+
+  PERF_STOP("ip_output_if");
+  return netif->output(netif, p, dest);
+}
+
+/* ip_output:
+ *
+ * Simple interface to ip_output_if. It finds the outgoing network interface and
+ * calls upon ip_output_if to do the actual work.
+ */
+
+err_t
+ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
+    u8_t ttl, u8_t proto)
+{
+  struct netif *netif;
+  if ((netif = ip_route(dest)) == NULL) {
+    LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr));
+    IP_STATS_INC(ip.rterr);
+    return ERR_RTE;
+  }
+
+  return ip_output_if (p, src, dest, ttl, proto, netif);
+}
+
+#if LWIP_NETIF_HWADDRHINT
+err_t
+ip_output_hinted(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
+          u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint)
+{
+  struct netif *netif;
+  err_t err;
+
+  if ((netif = ip_route(dest)) == NULL) {
+    LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr));
+    IP_STATS_INC(ip.rterr);
+    return ERR_RTE;
+  }
+
+  LWIP_NETIF_HWADDRHINT(netif, addr_hint);
+  err = ip_output_if(p, src, dest, ttl, tos, proto, netif);
+  LWIP_NETIF_HWADDRHINT(netif, NULL);
+
+  return err;
+}
+#endif /* LWIP_NETIF_HWADDRHINT*/
+
+#if IP_DEBUG
+void
+ip_debug_print(struct pbuf *p)
+{
+  struct ip_hdr *iphdr = p->payload;
+
+  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |  %"X16_F"%"X16_F"  |      %"X16_F"%"X16_F"           | (v, traffic class, flow label)\n",
+        iphdr->v,
+        iphdr->tclass1, iphdr->tclass2,
+        iphdr->flow1, iphdr->flow2));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("|    %5"U16_F"      | %2"U16_F"  |  %2"U16_F"   | (len, nexthdr, hoplim)\n",
+        ntohs(iphdr->len),
+        iphdr->nexthdr,
+        iphdr->hoplim));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (src)\n",
+        (ntohl(iphdr->src.addr[0]) >> 16) & 0xffff,
+        ntohl(iphdr->src.addr[0]) & 0xffff));
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (src)\n",
+        (ntohl(iphdr->src.addr[1]) >> 16) & 0xffff,
+        ntohl(iphdr->src.addr[1]) & 0xffff));
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (src)\n",
+        (ntohl(iphdr->src.addr[2]) >> 16) & 0xffff,
+        ntohl(iphdr->src.addr[2]) & 0xffff));
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (src)\n",
+        (ntohl(iphdr->src.addr[3]) >> 16) & 0xffff,
+        ntohl(iphdr->src.addr[3]) & 0xffff));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (dest)\n",
+        (ntohl(iphdr->dest.addr[0]) >> 16) & 0xffff,
+        ntohl(iphdr->dest.addr[0]) & 0xffff));
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (dest)\n",
+        (ntohl(iphdr->dest.addr[1]) >> 16) & 0xffff,
+        ntohl(iphdr->dest.addr[1]) & 0xffff));
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (dest)\n",
+        (ntohl(iphdr->dest.addr[2]) >> 16) & 0xffff,
+        ntohl(iphdr->dest.addr[2]) & 0xffff));
+  LWIP_DEBUGF(IP_DEBUG, ("|       %4"X32_F"      |       %4"X32_F"     | (dest)\n",
+        (ntohl(iphdr->dest.addr[3]) >> 16) & 0xffff,
+        ntohl(iphdr->dest.addr[3]) & 0xffff));
+  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
+}
+#endif /* IP_DEBUG */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/ip6_addr.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/ip6_addr.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/ipv6/ip6_addr.c	(revision 164)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+#include "lwip/ip_addr.h"
+#include "lwip/inet.h"
+
+u8_t
+ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2,
+                struct ip_addr *mask)
+{
+  return((addr1->addr[0] & mask->addr[0]) == (addr2->addr[0] & mask->addr[0]) &&
+         (addr1->addr[1] & mask->addr[1]) == (addr2->addr[1] & mask->addr[1]) &&
+         (addr1->addr[2] & mask->addr[2]) == (addr2->addr[2] & mask->addr[2]) &&
+         (addr1->addr[3] & mask->addr[3]) == (addr2->addr[3] & mask->addr[3]));
+        
+}
+
+u8_t
+ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2)
+{
+  return(addr1->addr[0] == addr2->addr[0] &&
+         addr1->addr[1] == addr2->addr[1] &&
+         addr1->addr[2] == addr2->addr[2] &&
+         addr1->addr[3] == addr2->addr[3]);
+}
+
+void
+ip_addr_set(struct ip_addr *dest, struct ip_addr *src)
+{
+  SMEMCPY(dest, src, sizeof(struct ip_addr));
+  /*  dest->addr[0] = src->addr[0];
+  dest->addr[1] = src->addr[1];
+  dest->addr[2] = src->addr[2];
+  dest->addr[3] = src->addr[3];*/
+}
+
+u8_t
+ip_addr_isany(struct ip_addr *addr)
+{
+  if (addr == NULL) return 1;
+  return((addr->addr[0] | addr->addr[1] | addr->addr[2] | addr->addr[3]) == 0);
+}
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/mem.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/mem.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/mem.c	(revision 164)
@@ -0,0 +1,659 @@
+/**
+ * @file
+ * Dynamic memory manager
+ *
+ * This is a lightweight replacement for the standard C library malloc().
+ *
+ * If you want to use the standard C library malloc() instead, define
+ * MEM_LIBC_MALLOC to 1 in your lwipopts.h
+ *
+ * To let mem_malloc() use pools (prevents fragmentation and is much faster than
+ * a heap but might waste some memory), define MEM_USE_POOLS to 1, define
+ * MEM_USE_CUSTOM_POOLS to 1 and create a file "lwippools.h" that includes a list
+ * of pools like this (more pools can be added between _START and _END):
+ *
+ * Define three pools with sizes 256, 512, and 1512 bytes
+ * LWIP_MALLOC_MEMPOOL_START
+ * LWIP_MALLOC_MEMPOOL(20, 256)
+ * LWIP_MALLOC_MEMPOOL(10, 512)
+ * LWIP_MALLOC_MEMPOOL(5, 1512)
+ * LWIP_MALLOC_MEMPOOL_END
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *         Simon Goldschmidt
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if !MEM_LIBC_MALLOC /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/sys.h"
+#include "lwip/stats.h"
+#include "lwip/err.h"
+
+#include <string.h>
+
+#if MEM_USE_POOLS
+/* lwIP head implemented with different sized pools */
+
+/**
+ * Allocate memory: determine the smallest pool that is big enough
+ * to contain an element of 'size' and get an element from that pool.
+ *
+ * @param size the size in bytes of the memory needed
+ * @return a pointer to the allocated memory or NULL if the pool is empty
+ */
+void *
+mem_malloc(mem_size_t size)
+{
+  void *ret;
+  struct memp_malloc_helper *element;
+  memp_t poolnr;
+  mem_size_t required_size = size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper));
+
+  for (poolnr = MEMP_POOL_FIRST; poolnr <= MEMP_POOL_LAST; poolnr = (memp_t)(poolnr + 1)) {
+#if MEM_USE_POOLS_TRY_BIGGER_POOL
+again:
+#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */
+    /* is this pool big enough to hold an element of the required size
+       plus a struct memp_malloc_helper that saves the pool this element came from? */
+    if (required_size <= memp_sizes[poolnr]) {
+      break;
+    }
+  }
+  if (poolnr > MEMP_POOL_LAST) {
+    LWIP_ASSERT("mem_malloc(): no pool is that big!", 0);
+    return NULL;
+  }
+  element = (struct memp_malloc_helper*)memp_malloc(poolnr);
+  if (element == NULL) {
+    /* No need to DEBUGF or ASSERT: This error is already
+       taken care of in memp.c */
+#if MEM_USE_POOLS_TRY_BIGGER_POOL
+    /** Try a bigger pool if this one is empty! */
+    if (poolnr < MEMP_POOL_LAST) {
+      poolnr++;
+      goto again;
+    }
+#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */
+    return NULL;
+  }
+
+  /* save the pool number this element came from */
+  element->poolnr = poolnr;
+  /* and return a pointer to the memory directly after the struct memp_malloc_helper */
+  ret = (u8_t*)element + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper));
+
+  return ret;
+}
+
+/**
+ * Free memory previously allocated by mem_malloc. Loads the pool number
+ * and calls memp_free with that pool number to put the element back into
+ * its pool
+ *
+ * @param rmem the memory element to free
+ */
+void
+mem_free(void *rmem)
+{
+  struct memp_malloc_helper *hmem;
+
+  LWIP_ASSERT("rmem != NULL", (rmem != NULL));
+  LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem)));
+
+  /* get the original struct memp_malloc_helper */
+  hmem = (struct memp_malloc_helper*)(void*)((u8_t*)rmem - LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)));
+
+  LWIP_ASSERT("hmem != NULL", (hmem != NULL));
+  LWIP_ASSERT("hmem == MEM_ALIGN(hmem)", (hmem == LWIP_MEM_ALIGN(hmem)));
+  LWIP_ASSERT("hmem->poolnr < MEMP_MAX", (hmem->poolnr < MEMP_MAX));
+
+  /* and put it in the pool we saved earlier */
+  memp_free(hmem->poolnr, hmem);
+}
+
+#else /* MEM_USE_POOLS */
+/* lwIP replacement for your libc malloc() */
+
+/**
+ * The heap is made up as a list of structs of this type.
+ * This does not have to be aligned since for getting its size,
+ * we only use the macro SIZEOF_STRUCT_MEM, which automatically alignes.
+ */
+struct mem {
+  /** index (-> ram[next]) of the next struct */
+  mem_size_t next;
+  /** index (-> ram[prev]) of the previous struct */
+  mem_size_t prev;
+  /** 1: this area is used; 0: this area is unused */
+  u8_t used;
+};
+
+/** All allocated blocks will be MIN_SIZE bytes big, at least!
+ * MIN_SIZE can be overridden to suit your needs. Smaller values save space,
+ * larger values could prevent too small blocks to fragment the RAM too much. */
+#ifndef MIN_SIZE
+#define MIN_SIZE             12
+#endif /* MIN_SIZE */
+/* some alignment macros: we define them here for better source code layout */
+#define MIN_SIZE_ALIGNED     LWIP_MEM_ALIGN_SIZE(MIN_SIZE)
+#define SIZEOF_STRUCT_MEM    LWIP_MEM_ALIGN_SIZE(sizeof(struct mem))
+#define MEM_SIZE_ALIGNED     LWIP_MEM_ALIGN_SIZE(MEM_SIZE)
+
+/** If you want to relocate the heap to external memory, simply define
+ * LWIP_RAM_HEAP_POINTER as a void-pointer to that location.
+ * If so, make sure the memory at that location is big enough (see below on
+ * how that space is calculated). */
+#ifndef LWIP_RAM_HEAP_POINTER
+/** the heap. we need one struct mem at the end and some room for alignment */
+u8_t ram_heap[MEM_SIZE_ALIGNED + (2*SIZEOF_STRUCT_MEM) + MEM_ALIGNMENT];
+#define LWIP_RAM_HEAP_POINTER ram_heap
+#endif /* LWIP_RAM_HEAP_POINTER */
+
+/** pointer to the heap (ram_heap): for alignment, ram is now a pointer instead of an array */
+static u8_t *ram;
+/** the last entry, always unused! */
+static struct mem *ram_end;
+/** pointer to the lowest free block, this is used for faster search */
+static struct mem *lfree;
+
+/** concurrent access protection */
+#if !NO_SYS
+static sys_mutex_t mem_mutex;
+#endif
+
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+
+static volatile u8_t mem_free_count;
+
+/* Allow mem_free from other (e.g. interrupt) context */
+#define LWIP_MEM_FREE_DECL_PROTECT()  SYS_ARCH_DECL_PROTECT(lev_free)
+#define LWIP_MEM_FREE_PROTECT()       SYS_ARCH_PROTECT(lev_free)
+#define LWIP_MEM_FREE_UNPROTECT()     SYS_ARCH_UNPROTECT(lev_free)
+#define LWIP_MEM_ALLOC_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_alloc)
+#define LWIP_MEM_ALLOC_PROTECT()      SYS_ARCH_PROTECT(lev_alloc)
+#define LWIP_MEM_ALLOC_UNPROTECT()    SYS_ARCH_UNPROTECT(lev_alloc)
+
+#else /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+
+/* Protect the heap only by using a semaphore */
+#define LWIP_MEM_FREE_DECL_PROTECT()
+#define LWIP_MEM_FREE_PROTECT()    sys_mutex_lock(&mem_mutex)
+#define LWIP_MEM_FREE_UNPROTECT()  sys_mutex_unlock(&mem_mutex)
+/* mem_malloc is protected using semaphore AND LWIP_MEM_ALLOC_PROTECT */
+#define LWIP_MEM_ALLOC_DECL_PROTECT()
+#define LWIP_MEM_ALLOC_PROTECT()
+#define LWIP_MEM_ALLOC_UNPROTECT()
+
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+
+
+/**
+ * "Plug holes" by combining adjacent empty struct mems.
+ * After this function is through, there should not exist
+ * one empty struct mem pointing to another empty struct mem.
+ *
+ * @param mem this points to a struct mem which just has been freed
+ * @internal this function is only called by mem_free() and mem_trim()
+ *
+ * This assumes access to the heap is protected by the calling function
+ * already.
+ */
+static void
+plug_holes(struct mem *mem)
+{
+  struct mem *nmem;
+  struct mem *pmem;
+
+  LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram);
+  LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end);
+  LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0);
+
+  /* plug hole forward */
+  LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", mem->next <= MEM_SIZE_ALIGNED);
+
+  nmem = (struct mem *)(void *)&ram[mem->next];
+  if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) {
+    /* if mem->next is unused and not end of ram, combine mem and mem->next */
+    if (lfree == nmem) {
+      lfree = mem;
+    }
+    mem->next = nmem->next;
+    ((struct mem *)(void *)&ram[nmem->next])->prev = (mem_size_t)((u8_t *)mem - ram);
+  }
+
+  /* plug hole backward */
+  pmem = (struct mem *)(void *)&ram[mem->prev];
+  if (pmem != mem && pmem->used == 0) {
+    /* if mem->prev is unused, combine mem and mem->prev */
+    if (lfree == mem) {
+      lfree = pmem;
+    }
+    pmem->next = mem->next;
+    ((struct mem *)(void *)&ram[mem->next])->prev = (mem_size_t)((u8_t *)pmem - ram);
+  }
+}
+
+/**
+ * Zero the heap and initialize start, end and lowest-free
+ */
+void
+mem_init(void)
+{
+  struct mem *mem;
+
+  LWIP_ASSERT("Sanity check alignment",
+    (SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT-1)) == 0);
+
+  /* align the heap */
+  ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER);
+  /* initialize the start of the heap */
+  mem = (struct mem *)(void *)ram;
+  mem->next = MEM_SIZE_ALIGNED;
+  mem->prev = 0;
+  mem->used = 0;
+  /* initialize the end of the heap */
+  ram_end = (struct mem *)(void *)&ram[MEM_SIZE_ALIGNED];
+  ram_end->used = 1;
+  ram_end->next = MEM_SIZE_ALIGNED;
+  ram_end->prev = MEM_SIZE_ALIGNED;
+
+  /* initialize the lowest-free pointer to the start of the heap */
+  lfree = (struct mem *)(void *)ram;
+
+  MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED);
+
+  if(sys_mutex_new(&mem_mutex) != ERR_OK) {
+    LWIP_ASSERT("failed to create mem_mutex", 0);
+  }
+}
+
+/**
+ * Put a struct mem back on the heap
+ *
+ * @param rmem is the data portion of a struct mem as returned by a previous
+ *             call to mem_malloc()
+ */
+void
+mem_free(void *rmem)
+{
+  struct mem *mem;
+  LWIP_MEM_FREE_DECL_PROTECT();
+
+  if (rmem == NULL) {
+    LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("mem_free(p == NULL) was called.\n"));
+    return;
+  }
+  LWIP_ASSERT("mem_free: sanity check alignment", (((mem_ptr_t)rmem) & (MEM_ALIGNMENT-1)) == 0);
+
+  LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
+    (u8_t *)rmem < (u8_t *)ram_end);
+
+  if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
+    SYS_ARCH_DECL_PROTECT(lev);
+    LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory\n"));
+    /* protect mem stats from concurrent access */
+    SYS_ARCH_PROTECT(lev);
+    MEM_STATS_INC(illegal);
+    SYS_ARCH_UNPROTECT(lev);
+    return;
+  }
+  /* protect the heap from concurrent access */
+  LWIP_MEM_FREE_PROTECT();
+  /* Get the corresponding struct mem ... */
+  mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
+  /* ... which has to be in a used state ... */
+  LWIP_ASSERT("mem_free: mem->used", mem->used);
+  /* ... and is now unused. */
+  mem->used = 0;
+
+  if (mem < lfree) {
+    /* the newly freed struct is now the lowest */
+    lfree = mem;
+  }
+
+  MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram)));
+
+  /* finally, see if prev or next are free also */
+  plug_holes(mem);
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+  mem_free_count = 1;
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+  LWIP_MEM_FREE_UNPROTECT();
+}
+
+/**
+ * Shrink memory returned by mem_malloc().
+ *
+ * @param rmem pointer to memory allocated by mem_malloc the is to be shrinked
+ * @param newsize required size after shrinking (needs to be smaller than or
+ *                equal to the previous size)
+ * @return for compatibility reasons: is always == rmem, at the moment
+ *         or NULL if newsize is > old size, in which case rmem is NOT touched
+ *         or freed!
+ */
+void *
+mem_trim(void *rmem, mem_size_t newsize)
+{
+  mem_size_t size;
+  mem_size_t ptr, ptr2;
+  struct mem *mem, *mem2;
+  /* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */
+  LWIP_MEM_FREE_DECL_PROTECT();
+
+  /* Expand the size of the allocated memory region so that we can
+     adjust for alignment. */
+  newsize = LWIP_MEM_ALIGN_SIZE(newsize);
+
+  if(newsize < MIN_SIZE_ALIGNED) {
+    /* every data block must be at least MIN_SIZE_ALIGNED long */
+    newsize = MIN_SIZE_ALIGNED;
+  }
+
+  if (newsize > MEM_SIZE_ALIGNED) {
+    return NULL;
+  }
+
+  LWIP_ASSERT("mem_trim: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
+   (u8_t *)rmem < (u8_t *)ram_end);
+
+  if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
+    SYS_ARCH_DECL_PROTECT(lev);
+    LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_trim: illegal memory\n"));
+    /* protect mem stats from concurrent access */
+    SYS_ARCH_PROTECT(lev);
+    MEM_STATS_INC(illegal);
+    SYS_ARCH_UNPROTECT(lev);
+    return rmem;
+  }
+  /* Get the corresponding struct mem ... */
+  mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
+  /* ... and its offset pointer */
+  ptr = (mem_size_t)((u8_t *)mem - ram);
+
+  size = mem->next - ptr - SIZEOF_STRUCT_MEM;
+  LWIP_ASSERT("mem_trim can only shrink memory", newsize <= size);
+  if (newsize > size) {
+    /* not supported */
+    return NULL;
+  }
+  if (newsize == size) {
+    /* No change in size, simply return */
+    return rmem;
+  }
+
+  /* protect the heap from concurrent access */
+  LWIP_MEM_FREE_PROTECT();
+
+  mem2 = (struct mem *)(void *)&ram[mem->next];
+  if(mem2->used == 0) {
+    /* The next struct is unused, we can simply move it at little */
+    mem_size_t next;
+    /* remember the old next pointer */
+    next = mem2->next;
+    /* create new struct mem which is moved directly after the shrinked mem */
+    ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;
+    if (lfree == mem2) {
+      lfree = (struct mem *)(void *)&ram[ptr2];
+    }
+    mem2 = (struct mem *)(void *)&ram[ptr2];
+    mem2->used = 0;
+    /* restore the next pointer */
+    mem2->next = next;
+    /* link it back to mem */
+    mem2->prev = ptr;
+    /* link mem to it */
+    mem->next = ptr2;
+    /* last thing to restore linked list: as we have moved mem2,
+     * let 'mem2->next->prev' point to mem2 again. but only if mem2->next is not
+     * the end of the heap */
+    if (mem2->next != MEM_SIZE_ALIGNED) {
+      ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2;
+    }
+    MEM_STATS_DEC_USED(used, (size - newsize));
+    /* no need to plug holes, we've already done that */
+  } else if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED <= size) {
+    /* Next struct is used but there's room for another struct mem with
+     * at least MIN_SIZE_ALIGNED of data.
+     * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem
+     * ('SIZEOF_STRUCT_MEM') with some data ('MIN_SIZE_ALIGNED').
+     * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty
+     *       region that couldn't hold data, but when mem->next gets freed,
+     *       the 2 regions would be combined, resulting in more free memory */
+    ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;
+    mem2 = (struct mem *)(void *)&ram[ptr2];
+    if (mem2 < lfree) {
+      lfree = mem2;
+    }
+    mem2->used = 0;
+    mem2->next = mem->next;
+    mem2->prev = ptr;
+    mem->next = ptr2;
+    if (mem2->next != MEM_SIZE_ALIGNED) {
+      ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2;
+    }
+    MEM_STATS_DEC_USED(used, (size - newsize));
+    /* the original mem->next is used, so no need to plug holes! */
+  }
+  /* else {
+    next struct mem is used but size between mem and mem2 is not big enough
+    to create another struct mem
+    -> don't do anyhting. 
+    -> the remaining space stays unused since it is too small
+  } */
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+  mem_free_count = 1;
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+  LWIP_MEM_FREE_UNPROTECT();
+  return rmem;
+}
+
+/**
+ * Adam's mem_malloc() plus solution for bug #17922
+ * Allocate a block of memory with a minimum of 'size' bytes.
+ *
+ * @param size is the minimum size of the requested block in bytes.
+ * @return pointer to allocated memory or NULL if no free memory was found.
+ *
+ * Note that the returned value will always be aligned (as defined by MEM_ALIGNMENT).
+ */
+void *
+mem_malloc(mem_size_t size)
+{
+  mem_size_t ptr, ptr2;
+  struct mem *mem, *mem2;
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+  u8_t local_mem_free_count = 0;
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+  LWIP_MEM_ALLOC_DECL_PROTECT();
+
+  if (size == 0) {
+    return NULL;
+  }
+
+  /* Expand the size of the allocated memory region so that we can
+     adjust for alignment. */
+  size = LWIP_MEM_ALIGN_SIZE(size);
+
+  if(size < MIN_SIZE_ALIGNED) {
+    /* every data block must be at least MIN_SIZE_ALIGNED long */
+    size = MIN_SIZE_ALIGNED;
+  }
+
+  if (size > MEM_SIZE_ALIGNED) {
+    return NULL;
+  }
+
+  /* protect the heap from concurrent access */
+  sys_mutex_lock(&mem_mutex);
+  LWIP_MEM_ALLOC_PROTECT();
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+  /* run as long as a mem_free disturbed mem_malloc or mem_trim */
+  do {
+    local_mem_free_count = 0;
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+
+    /* Scan through the heap searching for a free block that is big enough,
+     * beginning with the lowest free block.
+     */
+    for (ptr = (mem_size_t)((u8_t *)lfree - ram); ptr < MEM_SIZE_ALIGNED - size;
+         ptr = ((struct mem *)(void *)&ram[ptr])->next) {
+      mem = (struct mem *)(void *)&ram[ptr];
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+      mem_free_count = 0;
+      LWIP_MEM_ALLOC_UNPROTECT();
+      /* allow mem_free or mem_trim to run */
+      LWIP_MEM_ALLOC_PROTECT();
+      if (mem_free_count != 0) {
+        /* If mem_free or mem_trim have run, we have to restart since they
+           could have altered our current struct mem. */
+        local_mem_free_count = 1;
+        break;
+      }
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+
+      if ((!mem->used) &&
+          (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) {
+        /* mem is not used and at least perfect fit is possible:
+         * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */
+
+        if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) {
+          /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing
+           * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem')
+           * -> split large block, create empty remainder,
+           * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if
+           * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size,
+           * struct mem would fit in but no data between mem2 and mem2->next
+           * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty
+           *       region that couldn't hold data, but when mem->next gets freed,
+           *       the 2 regions would be combined, resulting in more free memory
+           */
+          ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
+          /* create mem2 struct */
+          mem2 = (struct mem *)(void *)&ram[ptr2];
+          mem2->used = 0;
+          mem2->next = mem->next;
+          mem2->prev = ptr;
+          /* and insert it between mem and mem->next */
+          mem->next = ptr2;
+          mem->used = 1;
+
+          if (mem2->next != MEM_SIZE_ALIGNED) {
+            ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2;
+          }
+          MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM));
+        } else {
+          /* (a mem2 struct does no fit into the user data space of mem and mem->next will always
+           * be used at this point: if not we have 2 unused structs in a row, plug_holes should have
+           * take care of this).
+           * -> near fit or excact fit: do not split, no mem2 creation
+           * also can't move mem->next directly behind mem, since mem->next
+           * will always be used at this point!
+           */
+          mem->used = 1;
+          MEM_STATS_INC_USED(used, mem->next - (mem_size_t)((u8_t *)mem - ram));
+        }
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+mem_malloc_adjust_lfree:
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+        if (mem == lfree) {
+          struct mem *cur = lfree;
+          /* Find next free block after mem and update lowest free pointer */
+          while (cur->used && cur != ram_end) {
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+            mem_free_count = 0;
+            LWIP_MEM_ALLOC_UNPROTECT();
+            /* prevent high interrupt latency... */
+            LWIP_MEM_ALLOC_PROTECT();
+            if (mem_free_count != 0) {
+              /* If mem_free or mem_trim have run, we have to restart since they
+                 could have altered our current struct mem or lfree. */
+              goto mem_malloc_adjust_lfree;
+            }
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+            cur = (struct mem *)(void *)&ram[cur->next];
+          }
+          lfree = cur;
+          LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used)));
+        }
+        LWIP_MEM_ALLOC_UNPROTECT();
+        sys_mutex_unlock(&mem_mutex);
+        LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
+         (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);
+        LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
+         ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
+        LWIP_ASSERT("mem_malloc: sanity check alignment",
+          (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0);
+
+        return (u8_t *)mem + SIZEOF_STRUCT_MEM;
+      }
+    }
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+    /* if we got interrupted by a mem_free, try again */
+  } while(local_mem_free_count != 0);
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+  LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size));
+  MEM_STATS_INC(err);
+  LWIP_MEM_ALLOC_UNPROTECT();
+  sys_mutex_unlock(&mem_mutex);
+  return NULL;
+}
+
+#endif /* MEM_USE_POOLS */
+/**
+ * Contiguously allocates enough space for count objects that are size bytes
+ * of memory each and returns a pointer to the allocated memory.
+ *
+ * The allocated memory is filled with bytes of value zero.
+ *
+ * @param count number of objects to allocate
+ * @param size size of the objects to allocate
+ * @return pointer to allocated memory / NULL pointer if there is an error
+ */
+void *mem_calloc(mem_size_t count, mem_size_t size)
+{
+  void *p;
+
+  /* allocate 'count' objects of size 'size' */
+  p = mem_malloc(count * size);
+  if (p) {
+    /* zero the memory */
+    memset(p, 0, count * size);
+  }
+  return p;
+}
+
+#endif /* !MEM_LIBC_MALLOC */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/memp.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/memp.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/memp.c	(revision 164)
@@ -0,0 +1,470 @@
+/**
+ * @file
+ * Dynamic pool memory manager
+ *
+ * lwIP has dedicated pools for many structures (netconn, protocol control blocks,
+ * packet buffers, ...). All these pools are managed here.
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/memp.h"
+#include "lwip/pbuf.h"
+#include "lwip/udp.h"
+#include "lwip/raw.h"
+#include "lwip/tcp_impl.h"
+#include "lwip/igmp.h"
+#include "lwip/api.h"
+#include "lwip/api_msg.h"
+#include "lwip/tcpip.h"
+#include "lwip/sys.h"
+#include "lwip/timers.h"
+#include "lwip/stats.h"
+#include "netif/etharp.h"
+#include "lwip/ip_frag.h"
+#include "lwip/snmp_structs.h"
+#include "lwip/snmp_msg.h"
+#include "lwip/dns.h"
+#include "netif/ppp_oe.h"
+
+#include <string.h>
+
+#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */
+
+struct memp {
+  struct memp *next;
+#if MEMP_OVERFLOW_CHECK
+  const char *file;
+  int line;
+#endif /* MEMP_OVERFLOW_CHECK */
+};
+
+#if MEMP_OVERFLOW_CHECK
+/* if MEMP_OVERFLOW_CHECK is turned on, we reserve some bytes at the beginning
+ * and at the end of each element, initialize them as 0xcd and check
+ * them later. */
+/* If MEMP_OVERFLOW_CHECK is >= 2, on every call to memp_malloc or memp_free,
+ * every single element in each pool is checked!
+ * This is VERY SLOW but also very helpful. */
+/* MEMP_SANITY_REGION_BEFORE and MEMP_SANITY_REGION_AFTER can be overridden in
+ * lwipopts.h to change the amount reserved for checking. */
+#ifndef MEMP_SANITY_REGION_BEFORE
+#define MEMP_SANITY_REGION_BEFORE  16
+#endif /* MEMP_SANITY_REGION_BEFORE*/
+#if MEMP_SANITY_REGION_BEFORE > 0
+#define MEMP_SANITY_REGION_BEFORE_ALIGNED    LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_BEFORE)
+#else
+#define MEMP_SANITY_REGION_BEFORE_ALIGNED    0
+#endif /* MEMP_SANITY_REGION_BEFORE*/
+#ifndef MEMP_SANITY_REGION_AFTER
+#define MEMP_SANITY_REGION_AFTER   16
+#endif /* MEMP_SANITY_REGION_AFTER*/
+#if MEMP_SANITY_REGION_AFTER > 0
+#define MEMP_SANITY_REGION_AFTER_ALIGNED     LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_AFTER)
+#else
+#define MEMP_SANITY_REGION_AFTER_ALIGNED     0
+#endif /* MEMP_SANITY_REGION_AFTER*/
+
+/* MEMP_SIZE: save space for struct memp and for sanity check */
+#define MEMP_SIZE          (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE_ALIGNED)
+#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER_ALIGNED)
+
+#else /* MEMP_OVERFLOW_CHECK */
+
+/* No sanity checks
+ * We don't need to preserve the struct memp while not allocated, so we
+ * can save a little space and set MEMP_SIZE to 0.
+ */
+#define MEMP_SIZE           0
+#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
+
+#endif /* MEMP_OVERFLOW_CHECK */
+
+/** This array holds the first free element of each pool.
+ *  Elements form a linked list. */
+static struct memp *memp_tab[MEMP_MAX];
+
+#else /* MEMP_MEM_MALLOC */
+
+#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
+
+#endif /* MEMP_MEM_MALLOC */
+
+/** This array holds the element sizes of each pool. */
+#if !MEM_USE_POOLS && !MEMP_MEM_MALLOC
+static
+#endif
+const u16_t memp_sizes[MEMP_MAX] = {
+#define LWIP_MEMPOOL(name,num,size,desc)  LWIP_MEM_ALIGN_SIZE(size),
+#include "lwip/memp_std.h"
+};
+
+#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */
+
+/** This array holds the number of elements in each pool. */
+static const u16_t memp_num[MEMP_MAX] = {
+#define LWIP_MEMPOOL(name,num,size,desc)  (num),
+#include "lwip/memp_std.h"
+};
+
+/** This array holds a textual description of each pool. */
+#ifdef LWIP_DEBUG
+static const char *memp_desc[MEMP_MAX] = {
+#define LWIP_MEMPOOL(name,num,size,desc)  (desc),
+#include "lwip/memp_std.h"
+};
+#endif /* LWIP_DEBUG */
+
+#if MEMP_SEPARATE_POOLS
+
+/** This creates each memory pool. These are named memp_memory_XXX_base (where
+ * XXX is the name of the pool defined in memp_std.h).
+ * To relocate a pool, declare it as extern in cc.h. Example for GCC:
+ *   extern u8_t __attribute__((section(".onchip_mem"))) memp_memory_UDP_PCB_base[];
+ */
+#define LWIP_MEMPOOL(name,num,size,desc) u8_t memp_memory_ ## name ## _base \
+  [((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))];   
+#include "lwip/memp_std.h"
+
+/** This array holds the base of each memory pool. */
+static u8_t *const memp_bases[] = { 
+#define LWIP_MEMPOOL(name,num,size,desc) memp_memory_ ## name ## _base,   
+#include "lwip/memp_std.h"
+};
+
+#else /* MEMP_SEPARATE_POOLS */
+
+/** This is the actual memory used by the pools (all pools in one big block). */
+static u8_t memp_memory[MEM_ALIGNMENT - 1 
+#define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
+#include "lwip/memp_std.h"
+];
+
+#endif /* MEMP_SEPARATE_POOLS */
+
+#if MEMP_SANITY_CHECK
+/**
+ * Check that memp-lists don't form a circle, using "Floyd's cycle-finding algorithm".
+ */
+static int
+memp_sanity(void)
+{
+  s16_t i;
+  struct memp *t, *h;
+
+  for (i = 0; i < MEMP_MAX; i++) {
+    t = memp_tab[i];
+    if(t != NULL) {
+      for (h = t->next; (t != NULL) && (h != NULL); t = t->next,
+        h = (((h->next != NULL) && (h->next->next != NULL)) ? h->next->next : NULL)) {
+        if (t == h) {
+          return 0;
+        }
+      }
+    }
+  }
+  return 1;
+}
+#endif /* MEMP_SANITY_CHECK*/
+#if MEMP_OVERFLOW_CHECK
+#if defined(LWIP_DEBUG) && MEMP_STATS
+static const char * memp_overflow_names[] = {
+#define LWIP_MEMPOOL(name,num,size,desc) "/"desc,
+#include "lwip/memp_std.h"
+  };
+#endif
+
+/**
+ * Check if a memp element was victim of an overflow
+ * (e.g. the restricted area after it has been altered)
+ *
+ * @param p the memp element to check
+ * @param memp_type the pool p comes from
+ */
+static void
+memp_overflow_check_element_overflow(struct memp *p, u16_t memp_type)
+{
+  u16_t k;
+  u8_t *m;
+#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
+  m = (u8_t*)p + MEMP_SIZE + memp_sizes[memp_type];
+  for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) {
+    if (m[k] != 0xcd) {
+      char errstr[128] = "detected memp overflow in pool ";
+      char digit[] = "0";
+      if(memp_type >= 10) {
+        digit[0] = '0' + (memp_type/10);
+        strcat(errstr, digit);
+      }
+      digit[0] = '0' + (memp_type%10);
+      strcat(errstr, digit);
+#if defined(LWIP_DEBUG) && MEMP_STATS
+      strcat(errstr, memp_overflow_names[memp_type]);
+#endif
+      LWIP_ASSERT(errstr, 0);
+    }
+  }
+#endif
+}
+
+/**
+ * Check if a memp element was victim of an underflow
+ * (e.g. the restricted area before it has been altered)
+ *
+ * @param p the memp element to check
+ * @param memp_type the pool p comes from
+ */
+static void
+memp_overflow_check_element_underflow(struct memp *p, u16_t memp_type)
+{
+  u16_t k;
+  u8_t *m;
+#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
+  m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED;
+  for (k = 0; k < MEMP_SANITY_REGION_BEFORE_ALIGNED; k++) {
+    if (m[k] != 0xcd) {
+      char errstr[128] = "detected memp underflow in pool ";
+      char digit[] = "0";
+      if(memp_type >= 10) {
+        digit[0] = '0' + (memp_type/10);
+        strcat(errstr, digit);
+      }
+      digit[0] = '0' + (memp_type%10);
+      strcat(errstr, digit);
+#if defined(LWIP_DEBUG) && MEMP_STATS
+      strcat(errstr, memp_overflow_names[memp_type]);
+#endif
+      LWIP_ASSERT(errstr, 0);
+    }
+  }
+#endif
+}
+
+/**
+ * Do an overflow check for all elements in every pool.
+ *
+ * @see memp_overflow_check_element for a description of the check
+ */
+static void
+memp_overflow_check_all(void)
+{
+  u16_t i, j;
+  struct memp *p;
+
+  p = (struct memp *)LWIP_MEM_ALIGN(memp_memory);
+  for (i = 0; i < MEMP_MAX; ++i) {
+    p = p;
+    for (j = 0; j < memp_num[i]; ++j) {
+      memp_overflow_check_element_overflow(p, i);
+      p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
+    }
+  }
+  p = (struct memp *)LWIP_MEM_ALIGN(memp_memory);
+  for (i = 0; i < MEMP_MAX; ++i) {
+    p = p;
+    for (j = 0; j < memp_num[i]; ++j) {
+      memp_overflow_check_element_underflow(p, i);
+      p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
+    }
+  }
+}
+
+/**
+ * Initialize the restricted areas of all memp elements in every pool.
+ */
+static void
+memp_overflow_init(void)
+{
+  u16_t i, j;
+  struct memp *p;
+  u8_t *m;
+
+  p = (struct memp *)LWIP_MEM_ALIGN(memp_memory);
+  for (i = 0; i < MEMP_MAX; ++i) {
+    p = p;
+    for (j = 0; j < memp_num[i]; ++j) {
+#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
+      m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED;
+      memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED);
+#endif
+#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
+      m = (u8_t*)p + MEMP_SIZE + memp_sizes[i];
+      memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED);
+#endif
+      p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
+    }
+  }
+}
+#endif /* MEMP_OVERFLOW_CHECK */
+
+/**
+ * Initialize this module.
+ * 
+ * Carves out memp_memory into linked lists for each pool-type.
+ */
+void
+memp_init(void)
+{
+  struct memp *memp;
+  u16_t i, j;
+
+  for (i = 0; i < MEMP_MAX; ++i) {
+    MEMP_STATS_AVAIL(used, i, 0);
+    MEMP_STATS_AVAIL(max, i, 0);
+    MEMP_STATS_AVAIL(err, i, 0);
+    MEMP_STATS_AVAIL(avail, i, memp_num[i]);
+  }
+
+#if !MEMP_SEPARATE_POOLS
+  memp = (struct memp *)LWIP_MEM_ALIGN(memp_memory);
+#endif /* !MEMP_SEPARATE_POOLS */
+  /* for every pool: */
+  for (i = 0; i < MEMP_MAX; ++i) {
+    memp_tab[i] = NULL;
+#if MEMP_SEPARATE_POOLS
+    memp = (struct memp*)memp_bases[i];
+#endif /* MEMP_SEPARATE_POOLS */
+    /* create a linked list of memp elements */
+    for (j = 0; j < memp_num[i]; ++j) {
+      memp->next = memp_tab[i];
+      memp_tab[i] = memp;
+      memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i]
+#if MEMP_OVERFLOW_CHECK
+        + MEMP_SANITY_REGION_AFTER_ALIGNED
+#endif
+      );
+    }
+  }
+#if MEMP_OVERFLOW_CHECK
+  memp_overflow_init();
+  /* check everything a first time to see if it worked */
+  memp_overflow_check_all();
+#endif /* MEMP_OVERFLOW_CHECK */
+}
+
+/**
+ * Get an element from a specific pool.
+ *
+ * @param type the pool to get an element from
+ *
+ * the debug version has two more parameters:
+ * @param file file name calling this function
+ * @param line number of line where this function is called
+ *
+ * @return a pointer to the allocated memory or a NULL pointer on error
+ */
+void *
+#if !MEMP_OVERFLOW_CHECK
+memp_malloc(memp_t type)
+#else
+memp_malloc_fn(memp_t type, const char* file, const int line)
+#endif
+{
+  struct memp *memp;
+  SYS_ARCH_DECL_PROTECT(old_level);
+ 
+  LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;);
+
+  SYS_ARCH_PROTECT(old_level);
+#if MEMP_OVERFLOW_CHECK >= 2
+  memp_overflow_check_all();
+#endif /* MEMP_OVERFLOW_CHECK >= 2 */
+
+  memp = memp_tab[type];
+  
+  if (memp != NULL) {
+    memp_tab[type] = memp->next;
+#if MEMP_OVERFLOW_CHECK
+    memp->next = NULL;
+    memp->file = file;
+    memp->line = line;
+#endif /* MEMP_OVERFLOW_CHECK */
+    MEMP_STATS_INC_USED(used, type);
+    LWIP_ASSERT("memp_malloc: memp properly aligned",
+                ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
+    memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE);
+  } else {
+    LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));
+    MEMP_STATS_INC(err, type);
+  }
+
+  SYS_ARCH_UNPROTECT(old_level);
+
+  return memp;
+}
+
+/**
+ * Put an element back into its pool.
+ *
+ * @param type the pool where to put mem
+ * @param mem the memp element to free
+ */
+void
+memp_free(memp_t type, void *mem)
+{
+  struct memp *memp;
+  SYS_ARCH_DECL_PROTECT(old_level);
+
+  if (mem == NULL) {
+    return;
+  }
+  LWIP_ASSERT("memp_free: mem properly aligned",
+                ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0);
+
+  memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE);
+
+  SYS_ARCH_PROTECT(old_level);
+#if MEMP_OVERFLOW_CHECK
+#if MEMP_OVERFLOW_CHECK >= 2
+  memp_overflow_check_all();
+#else
+  memp_overflow_check_element_overflow(memp, type);
+  memp_overflow_check_element_underflow(memp, type);
+#endif /* MEMP_OVERFLOW_CHECK >= 2 */
+#endif /* MEMP_OVERFLOW_CHECK */
+
+  MEMP_STATS_DEC(used, type); 
+  
+  memp->next = memp_tab[type]; 
+  memp_tab[type] = memp;
+
+#if MEMP_SANITY_CHECK
+  LWIP_ASSERT("memp sanity", memp_sanity());
+#endif /* MEMP_SANITY_CHECK */
+
+  SYS_ARCH_UNPROTECT(old_level);
+}
+
+#endif /* MEMP_MEM_MALLOC */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/netif.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/netif.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/netif.c	(revision 164)
@@ -0,0 +1,774 @@
+/**
+ * @file
+ * lwIP network interface abstraction
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/def.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/tcp_impl.h"
+#include "lwip/snmp.h"
+#include "lwip/igmp.h"
+#include "netif/etharp.h"
+#include "lwip/stats.h"
+#if ENABLE_LOOPBACK
+#include "lwip/sys.h"
+#if LWIP_NETIF_LOOPBACK_MULTITHREADING
+#include "lwip/tcpip.h"
+#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
+#endif /* ENABLE_LOOPBACK */
+
+#if LWIP_AUTOIP
+#include "lwip/autoip.h"
+#endif /* LWIP_AUTOIP */
+#if LWIP_DHCP
+#include "lwip/dhcp.h"
+#endif /* LWIP_DHCP */
+
+#if LWIP_NETIF_STATUS_CALLBACK
+#define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0)
+#else
+#define NETIF_STATUS_CALLBACK(n)
+#endif /* LWIP_NETIF_STATUS_CALLBACK */ 
+
+#if LWIP_NETIF_LINK_CALLBACK
+#define NETIF_LINK_CALLBACK(n) do{ if (n->link_callback) { (n->link_callback)(n); }}while(0)
+#else
+#define NETIF_LINK_CALLBACK(n)
+#endif /* LWIP_NETIF_LINK_CALLBACK */ 
+
+struct netif *netif_list;
+struct netif *netif_default;
+
+static u8_t netif_num;
+
+#if LWIP_HAVE_LOOPIF
+static struct netif loop_netif;
+
+/**
+ * Initialize a lwip network interface structure for a loopback interface
+ *
+ * @param netif the lwip network interface structure for this loopif
+ * @return ERR_OK if the loopif is initialized
+ *         ERR_MEM if private data couldn't be allocated
+ */
+static err_t
+netif_loopif_init(struct netif *netif)
+{
+  /* initialize the snmp variables and counters inside the struct netif
+   * ifSpeed: no assumption can be made!
+   */
+  NETIF_INIT_SNMP(netif, snmp_ifType_softwareLoopback, 0);
+
+  netif->name[0] = 'l';
+  netif->name[1] = 'o';
+  netif->output = netif_loop_output;
+  return ERR_OK;
+}
+#endif /* LWIP_HAVE_LOOPIF */
+
+void
+netif_init(void)
+{
+#if LWIP_HAVE_LOOPIF
+  ip_addr_t loop_ipaddr, loop_netmask, loop_gw;
+  IP4_ADDR(&loop_gw, 127,0,0,1);
+  IP4_ADDR(&loop_ipaddr, 127,0,0,1);
+  IP4_ADDR(&loop_netmask, 255,0,0,0);
+
+#if NO_SYS
+  netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, ip_input);
+#else  /* NO_SYS */
+  netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, tcpip_input);
+#endif /* NO_SYS */
+  netif_set_up(&loop_netif);
+
+#endif /* LWIP_HAVE_LOOPIF */
+}
+
+/**
+ * Add a network interface to the list of lwIP netifs.
+ *
+ * @param netif a pre-allocated netif structure
+ * @param ipaddr IP address for the new netif
+ * @param netmask network mask for the new netif
+ * @param gw default gateway IP address for the new netif
+ * @param state opaque data passed to the new netif
+ * @param init callback function that initializes the interface
+ * @param input callback function that is called to pass
+ * ingress packets up in the protocol layer stack.
+ *
+ * @return netif, or NULL if failed.
+ */
+struct netif *
+netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask,
+  ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input)
+{
+
+  LWIP_ASSERT("No init function given", init != NULL);
+
+  /* reset new interface configuration state */
+  ip_addr_set_zero(&netif->ip_addr);
+  ip_addr_set_zero(&netif->netmask);
+  ip_addr_set_zero(&netif->gw);
+  netif->flags = 0;
+#if LWIP_DHCP
+  /* netif not under DHCP control by default */
+  netif->dhcp = NULL;
+#endif /* LWIP_DHCP */
+#if LWIP_AUTOIP
+  /* netif not under AutoIP control by default */
+  netif->autoip = NULL;
+#endif /* LWIP_AUTOIP */
+#if LWIP_NETIF_STATUS_CALLBACK
+  netif->status_callback = NULL;
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#if LWIP_NETIF_LINK_CALLBACK
+  netif->link_callback = NULL;
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+#if LWIP_IGMP
+  netif->igmp_mac_filter = NULL;
+#endif /* LWIP_IGMP */
+#if ENABLE_LOOPBACK
+  netif->loop_first = NULL;
+  netif->loop_last = NULL;
+#endif /* ENABLE_LOOPBACK */
+
+  /* remember netif specific state information data */
+  netif->state = state;
+  netif->num = netif_num++;
+  netif->input = input;
+  NETIF_SET_HWADDRHINT(netif, NULL);
+#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS
+  netif->loop_cnt_current = 0;
+#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */
+
+  netif_set_addr(netif, ipaddr, netmask, gw);
+
+  /* call user specified initialization function for netif */
+  if (init(netif) != ERR_OK) {
+    return NULL;
+  }
+
+  /* add this netif to the list */
+  netif->next = netif_list;
+  netif_list = netif;
+  snmp_inc_iflist();
+
+#if LWIP_IGMP
+  /* start IGMP processing */
+  if (netif->flags & NETIF_FLAG_IGMP) {
+    igmp_start(netif);
+  }
+#endif /* LWIP_IGMP */
+
+  LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ",
+    netif->name[0], netif->name[1]));
+  ip_addr_debug_print(NETIF_DEBUG, ipaddr);
+  LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));
+  ip_addr_debug_print(NETIF_DEBUG, netmask);
+  LWIP_DEBUGF(NETIF_DEBUG, (" gw "));
+  ip_addr_debug_print(NETIF_DEBUG, gw);
+  LWIP_DEBUGF(NETIF_DEBUG, ("\n"));
+  return netif;
+}
+
+/**
+ * Change IP address configuration for a network interface (including netmask
+ * and default gateway).
+ *
+ * @param netif the network interface to change
+ * @param ipaddr the new IP address
+ * @param netmask the new netmask
+ * @param gw the new default gateway
+ */
+void
+netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask,
+    ip_addr_t *gw)
+{
+  netif_set_ipaddr(netif, ipaddr);
+  netif_set_netmask(netif, netmask);
+  netif_set_gw(netif, gw);
+}
+
+/**
+ * Remove a network interface from the list of lwIP netifs.
+ *
+ * @param netif the network interface to remove
+ */
+void
+netif_remove(struct netif *netif)
+{
+  if (netif == NULL) {
+    return;
+  }
+
+#if LWIP_IGMP
+  /* stop IGMP processing */
+  if (netif->flags & NETIF_FLAG_IGMP) {
+    igmp_stop(netif);
+  }
+#endif /* LWIP_IGMP */
+  if (netif_is_up(netif)) {
+    /* set netif down before removing (call callback function) */
+    netif_set_down(netif);
+  }
+
+  snmp_delete_ipaddridx_tree(netif);
+
+  /*  is it the first netif? */
+  if (netif_list == netif) {
+    netif_list = netif->next;
+  } else {
+    /*  look for netif further down the list */
+    struct netif * tmpNetif;
+    for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) {
+      if (tmpNetif->next == netif) {
+        tmpNetif->next = netif->next;
+        break;
+      }
+    }
+    if (tmpNetif == NULL)
+      return; /*  we didn't find any netif today */
+  }
+  snmp_dec_iflist();
+  /* this netif is default? */
+  if (netif_default == netif) {
+    /* reset default netif */
+    netif_set_default(NULL);
+  }
+#if LWIP_NETIF_REMOVE_CALLBACK
+  if (netif->remove_callback) {
+    netif->remove_callback(netif);
+  }
+#endif /* LWIP_NETIF_REMOVE_CALLBACK */
+  LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );
+}
+
+/**
+ * Find a network interface by searching for its name
+ *
+ * @param name the name of the netif (like netif->name) plus concatenated number
+ * in ascii representation (e.g. 'en0')
+ */
+struct netif *
+netif_find(char *name)
+{
+  struct netif *netif;
+  u8_t num;
+
+  if (name == NULL) {
+    return NULL;
+  }
+
+  num = name[2] - '0';
+
+  for(netif = netif_list; netif != NULL; netif = netif->next) {
+    if (num == netif->num &&
+       name[0] == netif->name[0] &&
+       name[1] == netif->name[1]) {
+      LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1]));
+      return netif;
+    }
+  }
+  LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1]));
+  return NULL;
+}
+
+/**
+ * Change the IP address of a network interface
+ *
+ * @param netif the network interface to change
+ * @param ipaddr the new IP address
+ *
+ * @note call netif_set_addr() if you also want to change netmask and
+ * default gateway
+ */
+void
+netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr)
+{
+  /* TODO: Handling of obsolete pcbs */
+  /* See:  http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */
+#if LWIP_TCP
+  struct tcp_pcb *pcb;
+  struct tcp_pcb_listen *lpcb;
+
+  /* address is actually being changed? */
+  if (ipaddr && (ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) {
+    /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */
+    LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n"));
+    pcb = tcp_active_pcbs;
+    while (pcb != NULL) {
+      /* PCB bound to current local interface address? */
+      if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))
+#if LWIP_AUTOIP
+        /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */
+        && !ip_addr_islinklocal(&(pcb->local_ip))
+#endif /* LWIP_AUTOIP */
+        ) {
+        /* this connection must be aborted */
+        struct tcp_pcb *next = pcb->next;
+        LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
+        tcp_abort(pcb);
+        pcb = next;
+      } else {
+        pcb = pcb->next;
+      }
+    }
+    for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
+      /* PCB bound to current local interface address? */
+      if ((!(ip_addr_isany(&(lpcb->local_ip)))) &&
+          (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr)))) {
+        /* The PCB is listening to the old ipaddr and
+         * is set to listen to the new one instead */
+        ip_addr_set(&(lpcb->local_ip), ipaddr);
+      }
+    }
+  }
+#endif
+  snmp_delete_ipaddridx_tree(netif);
+  snmp_delete_iprteidx_tree(0,netif);
+  /* set new IP address to netif */
+  ip_addr_set(&(netif->ip_addr), ipaddr);
+  snmp_insert_ipaddridx_tree(netif);
+  snmp_insert_iprteidx_tree(0,netif);
+
+  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+    netif->name[0], netif->name[1],
+    ip4_addr1_16(&netif->ip_addr),
+    ip4_addr2_16(&netif->ip_addr),
+    ip4_addr3_16(&netif->ip_addr),
+    ip4_addr4_16(&netif->ip_addr)));
+}
+
+/**
+ * Change the default gateway for a network interface
+ *
+ * @param netif the network interface to change
+ * @param gw the new default gateway
+ *
+ * @note call netif_set_addr() if you also want to change ip address and netmask
+ */
+void
+netif_set_gw(struct netif *netif, ip_addr_t *gw)
+{
+  ip_addr_set(&(netif->gw), gw);
+  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+    netif->name[0], netif->name[1],
+    ip4_addr1_16(&netif->gw),
+    ip4_addr2_16(&netif->gw),
+    ip4_addr3_16(&netif->gw),
+    ip4_addr4_16(&netif->gw)));
+}
+
+/**
+ * Change the netmask of a network interface
+ *
+ * @param netif the network interface to change
+ * @param netmask the new netmask
+ *
+ * @note call netif_set_addr() if you also want to change ip address and
+ * default gateway
+ */
+void
+netif_set_netmask(struct netif *netif, ip_addr_t *netmask)
+{
+  snmp_delete_iprteidx_tree(0, netif);
+  /* set new netmask to netif */
+  ip_addr_set(&(netif->netmask), netmask);
+  snmp_insert_iprteidx_tree(0, netif);
+  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+    netif->name[0], netif->name[1],
+    ip4_addr1_16(&netif->netmask),
+    ip4_addr2_16(&netif->netmask),
+    ip4_addr3_16(&netif->netmask),
+    ip4_addr4_16(&netif->netmask)));
+}
+
+/**
+ * Set a network interface as the default network interface
+ * (used to output all packets for which no specific route is found)
+ *
+ * @param netif the default network interface
+ */
+void
+netif_set_default(struct netif *netif)
+{
+  if (netif == NULL) {
+    /* remove default route */
+    snmp_delete_iprteidx_tree(1, netif);
+  } else {
+    /* install default route */
+    snmp_insert_iprteidx_tree(1, netif);
+  }
+  netif_default = netif;
+  LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",
+           netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));
+}
+
+/**
+ * Bring an interface up, available for processing
+ * traffic.
+ * 
+ * @note: Enabling DHCP on a down interface will make it come
+ * up once configured.
+ * 
+ * @see dhcp_start()
+ */ 
+void netif_set_up(struct netif *netif)
+{
+  if (!(netif->flags & NETIF_FLAG_UP)) {
+    netif->flags |= NETIF_FLAG_UP;
+    
+#if LWIP_SNMP
+    snmp_get_sysuptime(&netif->ts);
+#endif /* LWIP_SNMP */
+
+    NETIF_STATUS_CALLBACK(netif);
+
+    if (netif->flags & NETIF_FLAG_LINK_UP) {
+#if LWIP_ARP
+      /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ 
+      if (netif->flags & (NETIF_FLAG_ETHARP)) {
+        etharp_gratuitous(netif);
+      }
+#endif /* LWIP_ARP */
+
+#if LWIP_IGMP
+      /* resend IGMP memberships */
+      if (netif->flags & NETIF_FLAG_IGMP) {
+        igmp_report_groups( netif);
+      }
+#endif /* LWIP_IGMP */
+    }
+  }
+}
+
+/**
+ * Bring an interface down, disabling any traffic processing.
+ *
+ * @note: Enabling DHCP on a down interface will make it come
+ * up once configured.
+ * 
+ * @see dhcp_start()
+ */ 
+void netif_set_down(struct netif *netif)
+{
+  if (netif->flags & NETIF_FLAG_UP) {
+    netif->flags &= ~NETIF_FLAG_UP;
+#if LWIP_SNMP
+    snmp_get_sysuptime(&netif->ts);
+#endif
+
+#if LWIP_ARP
+    if (netif->flags & NETIF_FLAG_ETHARP) {
+      etharp_cleanup_netif(netif);
+    }
+#endif /* LWIP_ARP */
+    NETIF_STATUS_CALLBACK(netif);
+  }
+}
+
+#if LWIP_NETIF_STATUS_CALLBACK
+/**
+ * Set callback to be called when interface is brought up/down
+ */
+void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback)
+{
+  if (netif) {
+    netif->status_callback = status_callback;
+  }
+}
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+
+#if LWIP_NETIF_REMOVE_CALLBACK
+/**
+ * Set callback to be called when the interface has been removed
+ */
+void
+netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback)
+{
+  if (netif) {
+    netif->remove_callback = remove_callback;
+  }
+}
+#endif /* LWIP_NETIF_REMOVE_CALLBACK */
+
+/**
+ * Called by a driver when its link goes up
+ */
+void netif_set_link_up(struct netif *netif )
+{
+  if (!(netif->flags & NETIF_FLAG_LINK_UP)) {
+    netif->flags |= NETIF_FLAG_LINK_UP;
+
+#if LWIP_DHCP
+    if (netif->dhcp) {
+      dhcp_network_changed(netif);
+    }
+#endif /* LWIP_DHCP */
+
+#if LWIP_AUTOIP
+    if (netif->autoip) {
+      autoip_network_changed(netif);
+    }
+#endif /* LWIP_AUTOIP */
+
+    if (netif->flags & NETIF_FLAG_UP) {
+#if LWIP_ARP
+      /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ 
+      if (netif->flags & NETIF_FLAG_ETHARP) {
+        etharp_gratuitous(netif);
+      }
+#endif /* LWIP_ARP */
+
+#if LWIP_IGMP
+      /* resend IGMP memberships */
+      if (netif->flags & NETIF_FLAG_IGMP) {
+        igmp_report_groups( netif);
+      }
+#endif /* LWIP_IGMP */
+    }
+    NETIF_LINK_CALLBACK(netif);
+  }
+}
+
+/**
+ * Called by a driver when its link goes down
+ */
+void netif_set_link_down(struct netif *netif )
+{
+  if (netif->flags & NETIF_FLAG_LINK_UP) {
+    netif->flags &= ~NETIF_FLAG_LINK_UP;
+    NETIF_LINK_CALLBACK(netif);
+  }
+}
+
+#if LWIP_NETIF_LINK_CALLBACK
+/**
+ * Set callback to be called when link is brought up/down
+ */
+void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback)
+{
+  if (netif) {
+    netif->link_callback = link_callback;
+  }
+}
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+
+#if ENABLE_LOOPBACK
+/**
+ * Send an IP packet to be received on the same netif (loopif-like).
+ * The pbuf is simply copied and handed back to netif->input.
+ * In multithreaded mode, this is done directly since netif->input must put
+ * the packet on a queue.
+ * In callback mode, the packet is put on an internal queue and is fed to
+ * netif->input by netif_poll().
+ *
+ * @param netif the lwip network interface structure
+ * @param p the (IP) packet to 'send'
+ * @param ipaddr the ip address to send the packet to (not used)
+ * @return ERR_OK if the packet has been sent
+ *         ERR_MEM if the pbuf used to copy the packet couldn't be allocated
+ */
+err_t
+netif_loop_output(struct netif *netif, struct pbuf *p,
+       ip_addr_t *ipaddr)
+{
+  struct pbuf *r;
+  err_t err;
+  struct pbuf *last;
+#if LWIP_LOOPBACK_MAX_PBUFS
+  u8_t clen = 0;
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+  /* If we have a loopif, SNMP counters are adjusted for it,
+   * if not they are adjusted for 'netif'. */
+#if LWIP_SNMP
+#if LWIP_HAVE_LOOPIF
+  struct netif *stats_if = &loop_netif;
+#else /* LWIP_HAVE_LOOPIF */
+  struct netif *stats_if = netif;
+#endif /* LWIP_HAVE_LOOPIF */
+#endif /* LWIP_SNMP */
+  SYS_ARCH_DECL_PROTECT(lev);
+  LWIP_UNUSED_ARG(ipaddr);
+
+  /* Allocate a new pbuf */
+  r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
+  if (r == NULL) {
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    snmp_inc_ifoutdiscards(stats_if);
+    return ERR_MEM;
+  }
+#if LWIP_LOOPBACK_MAX_PBUFS
+  clen = pbuf_clen(r);
+  /* check for overflow or too many pbuf on queue */
+  if(((netif->loop_cnt_current + clen) < netif->loop_cnt_current) ||
+     ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) {
+    pbuf_free(r);
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    snmp_inc_ifoutdiscards(stats_if);
+    return ERR_MEM;
+  }
+  netif->loop_cnt_current += clen;
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+
+  /* Copy the whole pbuf queue p into the single pbuf r */
+  if ((err = pbuf_copy(r, p)) != ERR_OK) {
+    pbuf_free(r);
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    snmp_inc_ifoutdiscards(stats_if);
+    return err;
+  }
+
+  /* Put the packet on a linked list which gets emptied through calling
+     netif_poll(). */
+
+  /* let last point to the last pbuf in chain r */
+  for (last = r; last->next != NULL; last = last->next);
+
+  SYS_ARCH_PROTECT(lev);
+  if(netif->loop_first != NULL) {
+    LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL);
+    netif->loop_last->next = r;
+    netif->loop_last = last;
+  } else {
+    netif->loop_first = r;
+    netif->loop_last = last;
+  }
+  SYS_ARCH_UNPROTECT(lev);
+
+  LINK_STATS_INC(link.xmit);
+  snmp_add_ifoutoctets(stats_if, p->tot_len);
+  snmp_inc_ifoutucastpkts(stats_if);
+
+#if LWIP_NETIF_LOOPBACK_MULTITHREADING
+  /* For multithreading environment, schedule a call to netif_poll */
+  tcpip_callback((tcpip_callback_fn)netif_poll, netif);
+#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
+
+  return ERR_OK;
+}
+
+/**
+ * Call netif_poll() in the main loop of your application. This is to prevent
+ * reentering non-reentrant functions like tcp_input(). Packets passed to
+ * netif_loop_output() are put on a list that is passed to netif->input() by
+ * netif_poll().
+ */
+void
+netif_poll(struct netif *netif)
+{
+  struct pbuf *in;
+  /* If we have a loopif, SNMP counters are adjusted for it,
+   * if not they are adjusted for 'netif'. */
+#if LWIP_SNMP
+#if LWIP_HAVE_LOOPIF
+  struct netif *stats_if = &loop_netif;
+#else /* LWIP_HAVE_LOOPIF */
+  struct netif *stats_if = netif;
+#endif /* LWIP_HAVE_LOOPIF */
+#endif /* LWIP_SNMP */
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  do {
+    /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */
+    SYS_ARCH_PROTECT(lev);
+    in = netif->loop_first;
+    if (in != NULL) {
+      struct pbuf *in_end = in;
+#if LWIP_LOOPBACK_MAX_PBUFS
+      u8_t clen = pbuf_clen(in);
+      /* adjust the number of pbufs on queue */
+      LWIP_ASSERT("netif->loop_cnt_current underflow",
+        ((netif->loop_cnt_current - clen) < netif->loop_cnt_current));
+      netif->loop_cnt_current -= clen;
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+      while (in_end->len != in_end->tot_len) {
+        LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL);
+        in_end = in_end->next;
+      }
+      /* 'in_end' now points to the last pbuf from 'in' */
+      if (in_end == netif->loop_last) {
+        /* this was the last pbuf in the list */
+        netif->loop_first = netif->loop_last = NULL;
+      } else {
+        /* pop the pbuf off the list */
+        netif->loop_first = in_end->next;
+        LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL);
+      }
+      /* De-queue the pbuf from its successors on the 'loop_' list. */
+      in_end->next = NULL;
+    }
+    SYS_ARCH_UNPROTECT(lev);
+
+    if (in != NULL) {
+      LINK_STATS_INC(link.recv);
+      snmp_add_ifinoctets(stats_if, in->tot_len);
+      snmp_inc_ifinucastpkts(stats_if);
+      /* loopback packets are always IP packets! */
+      if (ip_input(in, netif) != ERR_OK) {
+        pbuf_free(in);
+      }
+      /* Don't reference the packet any more! */
+      in = NULL;
+    }
+  /* go on while there is a packet on the list */
+  } while (netif->loop_first != NULL);
+}
+
+#if !LWIP_NETIF_LOOPBACK_MULTITHREADING
+/**
+ * Calls netif_poll() for every netif on the netif_list.
+ */
+void
+netif_poll_all(void)
+{
+  struct netif *netif = netif_list;
+  /* loop through netifs */
+  while (netif != NULL) {
+    netif_poll(netif);
+    /* proceed to next network interface */
+    netif = netif->next;
+  }
+}
+#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
+#endif /* ENABLE_LOOPBACK */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/pbuf.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/pbuf.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/pbuf.c	(revision 164)
@@ -0,0 +1,1179 @@
+/**
+ * @file
+ * Packet buffer management
+ *
+ * Packets are built from the pbuf data structure. It supports dynamic
+ * memory allocation for packet contents or can reference externally
+ * managed packet contents both in RAM and ROM. Quick allocation for
+ * incoming packets is provided through pools with fixed sized pbufs.
+ *
+ * A packet may span over multiple pbufs, chained as a singly linked
+ * list. This is called a "pbuf chain".
+ *
+ * Multiple packets may be queued, also using this singly linked list.
+ * This is called a "packet queue".
+ * 
+ * So, a packet queue consists of one or more pbuf chains, each of
+ * which consist of one or more pbufs. CURRENTLY, PACKET QUEUES ARE
+ * NOT SUPPORTED!!! Use helper structs to queue multiple packets.
+ * 
+ * The differences between a pbuf chain and a packet queue are very
+ * precise but subtle. 
+ *
+ * The last pbuf of a packet has a ->tot_len field that equals the
+ * ->len field. It can be found by traversing the list. If the last
+ * pbuf of a packet has a ->next field other than NULL, more packets
+ * are on the queue.
+ *
+ * Therefore, looping through a pbuf of a single packet, has an
+ * loop end condition (tot_len == p->len), NOT (next == NULL).
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/stats.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/pbuf.h"
+#include "lwip/sys.h"
+#include "arch/perf.h"
+#if LWIP_TCP && TCP_QUEUE_OOSEQ
+#include "lwip/tcp_impl.h"
+#endif
+#if LWIP_CHECKSUM_ON_COPY
+#include "lwip/inet_chksum.h"
+#endif
+
+#include <string.h>
+
+#define SIZEOF_STRUCT_PBUF        LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf))
+/* Since the pool is created in memp, PBUF_POOL_BUFSIZE will be automatically
+   aligned there. Therefore, PBUF_POOL_BUFSIZE_ALIGNED can be used here. */
+#define PBUF_POOL_BUFSIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE)
+
+#if !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ
+#define PBUF_POOL_IS_EMPTY()
+#else /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */
+
+#if !NO_SYS
+#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL
+#include "lwip/tcpip.h"
+#define PBUF_POOL_FREE_OOSEQ_QUEUE_CALL()  do { \
+  if(tcpip_callback_with_block(pbuf_free_ooseq_callback, NULL, 0) != ERR_OK) { \
+      SYS_ARCH_PROTECT(old_level); \
+      pbuf_free_ooseq_pending = 0; \
+      SYS_ARCH_UNPROTECT(old_level); \
+  } } while(0)
+#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */
+#endif /* !NO_SYS */
+
+volatile u8_t pbuf_free_ooseq_pending;
+#define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty()
+
+/**
+ * Attempt to reclaim some memory from queued out-of-sequence TCP segments
+ * if we run out of pool pbufs. It's better to give priority to new packets
+ * if we're running out.
+ *
+ * This must be done in the correct thread context therefore this function
+ * can only be used with NO_SYS=0 and through tcpip_callback.
+ */
+#if !NO_SYS
+static
+#endif /* !NO_SYS */
+void
+pbuf_free_ooseq(void)
+{
+  struct tcp_pcb* pcb;
+  SYS_ARCH_DECL_PROTECT(old_level);
+
+  SYS_ARCH_PROTECT(old_level);
+  pbuf_free_ooseq_pending = 0;
+  SYS_ARCH_UNPROTECT(old_level);
+
+  for (pcb = tcp_active_pcbs; NULL != pcb; pcb = pcb->next) {
+    if (NULL != pcb->ooseq) {
+      /** Free the ooseq pbufs of one PCB only */
+      LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free_ooseq: freeing out-of-sequence pbufs\n"));
+      tcp_segs_free(pcb->ooseq);
+      pcb->ooseq = NULL;
+      return;
+    }
+  }
+}
+
+#if !NO_SYS
+/**
+ * Just a callback function for tcpip_timeout() that calls pbuf_free_ooseq().
+ */
+static void
+pbuf_free_ooseq_callback(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+  pbuf_free_ooseq();
+}
+#endif /* !NO_SYS */
+
+/** Queue a call to pbuf_free_ooseq if not already queued. */
+static void
+pbuf_pool_is_empty(void)
+{
+#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL
+  SYS_ARCH_DECL_PROTECT(old_level);
+  SYS_ARCH_PROTECT(old_level);
+  pbuf_free_ooseq_pending = 1;
+  SYS_ARCH_UNPROTECT(old_level);
+#else /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */
+  u8_t queued;
+  SYS_ARCH_DECL_PROTECT(old_level);
+  SYS_ARCH_PROTECT(old_level);
+  queued = pbuf_free_ooseq_pending;
+  pbuf_free_ooseq_pending = 1;
+  SYS_ARCH_UNPROTECT(old_level);
+
+  if(!queued) {
+    /* queue a call to pbuf_free_ooseq if not already queued */
+    PBUF_POOL_FREE_OOSEQ_QUEUE_CALL();
+  }
+#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */
+}
+#endif /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */
+
+/**
+ * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type).
+ *
+ * The actual memory allocated for the pbuf is determined by the
+ * layer at which the pbuf is allocated and the requested size
+ * (from the size parameter).
+ *
+ * @param layer flag to define header size
+ * @param length size of the pbuf's payload
+ * @param type this parameter decides how and where the pbuf
+ * should be allocated as follows:
+ *
+ * - PBUF_RAM: buffer memory for pbuf is allocated as one large
+ *             chunk. This includes protocol headers as well.
+ * - PBUF_ROM: no buffer memory is allocated for the pbuf, even for
+ *             protocol headers. Additional headers must be prepended
+ *             by allocating another pbuf and chain in to the front of
+ *             the ROM pbuf. It is assumed that the memory used is really
+ *             similar to ROM in that it is immutable and will not be
+ *             changed. Memory which is dynamic should generally not
+ *             be attached to PBUF_ROM pbufs. Use PBUF_REF instead.
+ * - PBUF_REF: no buffer memory is allocated for the pbuf, even for
+ *             protocol headers. It is assumed that the pbuf is only
+ *             being used in a single thread. If the pbuf gets queued,
+ *             then pbuf_take should be called to copy the buffer.
+ * - PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from
+ *              the pbuf pool that is allocated during pbuf_init().
+ *
+ * @return the allocated pbuf. If multiple pbufs where allocated, this
+ * is the first pbuf of a pbuf chain.
+ */
+struct pbuf *
+pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
+{
+  struct pbuf *p, *q, *r;
+  u16_t offset;
+  s32_t rem_len; /* remaining length */
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length));
+
+  /* determine header offset */
+  switch (layer) {
+  case PBUF_TRANSPORT:
+    /* add room for transport (often TCP) layer header */
+    offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN;
+    break;
+  case PBUF_IP:
+    /* add room for IP layer header */
+    offset = PBUF_LINK_HLEN + PBUF_IP_HLEN;
+    break;
+  case PBUF_LINK:
+    /* add room for link layer header */
+    offset = PBUF_LINK_HLEN;
+    break;
+  case PBUF_RAW:
+    offset = 0;
+    break;
+  default:
+    LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0);
+    return NULL;
+  }
+
+  switch (type) {
+  case PBUF_POOL:
+    /* allocate head of pbuf chain into p */
+    p = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL);
+    LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc: allocated pbuf %p\n", (void *)p));
+    if (p == NULL) {
+      PBUF_POOL_IS_EMPTY();
+      return NULL;
+    }
+    p->type = type;
+    p->next = NULL;
+
+    /* make the payload pointer point 'offset' bytes into pbuf data memory */
+    p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + (SIZEOF_STRUCT_PBUF + offset)));
+    LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned",
+            ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
+    /* the total length of the pbuf chain is the requested size */
+    p->tot_len = length;
+    /* set the length of the first pbuf in the chain */
+    p->len = LWIP_MIN(length, PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset));
+    LWIP_ASSERT("check p->payload + p->len does not overflow pbuf",
+                ((u8_t*)p->payload + p->len <=
+                 (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED));
+    LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT",
+      (PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)) > 0 );
+    /* set reference count (needed here in case we fail) */
+    p->ref = 1;
+
+    /* now allocate the tail of the pbuf chain */
+
+    /* remember first pbuf for linkage in next iteration */
+    r = p;
+    /* remaining length to be allocated */
+    rem_len = length - p->len;
+    /* any remaining pbufs to be allocated? */
+    while (rem_len > 0) {
+      q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL);
+      if (q == NULL) {
+        PBUF_POOL_IS_EMPTY();
+        /* free chain so far allocated */
+        pbuf_free(p);
+        /* bail out unsuccesfully */
+        return NULL;
+      }
+      q->type = type;
+      q->flags = 0;
+      q->next = NULL;
+      /* make previous pbuf point to this pbuf */
+      r->next = q;
+      /* set total length of this pbuf and next in chain */
+      LWIP_ASSERT("rem_len < max_u16_t", rem_len < 0xffff);
+      q->tot_len = (u16_t)rem_len;
+      /* this pbuf length is pool size, unless smaller sized tail */
+      q->len = LWIP_MIN((u16_t)rem_len, PBUF_POOL_BUFSIZE_ALIGNED);
+      q->payload = (void *)((u8_t *)q + SIZEOF_STRUCT_PBUF);
+      LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned",
+              ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0);
+      LWIP_ASSERT("check p->payload + p->len does not overflow pbuf",
+                  ((u8_t*)p->payload + p->len <=
+                   (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED));
+      q->ref = 1;
+      /* calculate remaining length to be allocated */
+      rem_len -= q->len;
+      /* remember this pbuf for linkage in next iteration */
+      r = q;
+    }
+    /* end of chain */
+    /*r->next = NULL;*/
+
+    break;
+  case PBUF_RAM:
+    /* If pbuf is to be allocated in RAM, allocate memory for it. */
+    p = (struct pbuf*)mem_malloc(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length));
+    if (p == NULL) {
+      return NULL;
+    }
+    /* Set up internal structure of the pbuf. */
+    p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset));
+    p->len = p->tot_len = length;
+    p->next = NULL;
+    p->type = type;
+
+    LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
+           ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
+    break;
+  /* pbuf references existing (non-volatile static constant) ROM payload? */
+  case PBUF_ROM:
+  /* pbuf references existing (externally allocated) RAM payload? */
+  case PBUF_REF:
+    /* only allocate memory for the pbuf structure */
+    p = (struct pbuf *)memp_malloc(MEMP_PBUF);
+    if (p == NULL) {
+      LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                  ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n",
+                  (type == PBUF_ROM) ? "ROM" : "REF"));
+      return NULL;
+    }
+    /* caller must set this field properly, afterwards */
+    p->payload = NULL;
+    p->len = p->tot_len = length;
+    p->next = NULL;
+    p->type = type;
+    break;
+  default:
+    LWIP_ASSERT("pbuf_alloc: erroneous type", 0);
+    return NULL;
+  }
+  /* set reference count */
+  p->ref = 1;
+  /* set flags */
+  p->flags = 0;
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p));
+  return p;
+}
+
+#if LWIP_SUPPORT_CUSTOM_PBUF
+/** Initialize a custom pbuf (already allocated).
+ *
+ * @param layer flag to define header size
+ * @param length size of the pbuf's payload
+ * @param type type of the pbuf (only used to treat the pbuf accordingly, as
+ *        this function allocates no memory)
+ * @param p pointer to the custom pbuf to initialize (already allocated)
+ * @param payload_mem pointer to the buffer that is used for payload and headers,
+ *        must be at least big enough to hold 'length' plus the header size,
+ *        may be NULL if set later.
+ *        ATTENTION: The caller is responsible for correct alignment of this buffer!!
+ * @param payload_mem_len the size of the 'payload_mem' buffer, must be at least
+ *        big enough to hold 'length' plus the header size
+ */
+struct pbuf*
+pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_custom *p,
+                    void *payload_mem, u16_t payload_mem_len)
+{
+  u16_t offset;
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloced_custom(length=%"U16_F")\n", length));
+
+  /* determine header offset */
+  switch (l) {
+  case PBUF_TRANSPORT:
+    /* add room for transport (often TCP) layer header */
+    offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN;
+    break;
+  case PBUF_IP:
+    /* add room for IP layer header */
+    offset = PBUF_LINK_HLEN + PBUF_IP_HLEN;
+    break;
+  case PBUF_LINK:
+    /* add room for link layer header */
+    offset = PBUF_LINK_HLEN;
+    break;
+  case PBUF_RAW:
+    offset = 0;
+    break;
+  default:
+    LWIP_ASSERT("pbuf_alloced_custom: bad pbuf layer", 0);
+    return NULL;
+  }
+
+  if (LWIP_MEM_ALIGN_SIZE(offset) + length > payload_mem_len) {
+    LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_WARNING, ("pbuf_alloced_custom(length=%"U16_F") buffer too short\n", length));
+    return NULL;
+  }
+
+  p->pbuf.next = NULL;
+  if (payload_mem != NULL) {
+    p->pbuf.payload = (u8_t *)payload_mem + LWIP_MEM_ALIGN_SIZE(offset);
+  } else {
+    p->pbuf.payload = NULL;
+  }
+  p->pbuf.flags = PBUF_FLAG_IS_CUSTOM;
+  p->pbuf.len = p->pbuf.tot_len = length;
+  p->pbuf.type = type;
+  p->pbuf.ref = 1;
+  return &p->pbuf;
+}
+#endif /* LWIP_SUPPORT_CUSTOM_PBUF */
+
+/**
+ * Shrink a pbuf chain to a desired length.
+ *
+ * @param p pbuf to shrink.
+ * @param new_len desired new length of pbuf chain
+ *
+ * Depending on the desired length, the first few pbufs in a chain might
+ * be skipped and left unchanged. The new last pbuf in the chain will be
+ * resized, and any remaining pbufs will be freed.
+ *
+ * @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted.
+ * @note May not be called on a packet queue.
+ *
+ * @note Despite its name, pbuf_realloc cannot grow the size of a pbuf (chain).
+ */
+void
+pbuf_realloc(struct pbuf *p, u16_t new_len)
+{
+  struct pbuf *q;
+  u16_t rem_len; /* remaining length */
+  s32_t grow;
+
+  LWIP_ASSERT("pbuf_realloc: p != NULL", p != NULL);
+  LWIP_ASSERT("pbuf_realloc: sane p->type", p->type == PBUF_POOL ||
+              p->type == PBUF_ROM ||
+              p->type == PBUF_RAM ||
+              p->type == PBUF_REF);
+
+  /* desired length larger than current length? */
+  if (new_len >= p->tot_len) {
+    /* enlarging not yet supported */
+    return;
+  }
+
+  /* the pbuf chain grows by (new_len - p->tot_len) bytes
+   * (which may be negative in case of shrinking) */
+  grow = new_len - p->tot_len;
+
+  /* first, step over any pbufs that should remain in the chain */
+  rem_len = new_len;
+  q = p;
+  /* should this pbuf be kept? */
+  while (rem_len > q->len) {
+    /* decrease remaining length by pbuf length */
+    rem_len -= q->len;
+    /* decrease total length indicator */
+    LWIP_ASSERT("grow < max_u16_t", grow < 0xffff);
+    q->tot_len += (u16_t)grow;
+    /* proceed to next pbuf in chain */
+    q = q->next;
+    LWIP_ASSERT("pbuf_realloc: q != NULL", q != NULL);
+  }
+  /* we have now reached the new last pbuf (in q) */
+  /* rem_len == desired length for pbuf q */
+
+  /* shrink allocated memory for PBUF_RAM */
+  /* (other types merely adjust their length fields */
+  if ((q->type == PBUF_RAM) && (rem_len != q->len)) {
+    /* reallocate and adjust the length of the pbuf that will be split */
+    q = (struct pbuf *)mem_trim(q, (u16_t)((u8_t *)q->payload - (u8_t *)q) + rem_len);
+    LWIP_ASSERT("mem_trim returned q == NULL", q != NULL);
+  }
+  /* adjust length fields for new last pbuf */
+  q->len = rem_len;
+  q->tot_len = q->len;
+
+  /* any remaining pbufs in chain? */
+  if (q->next != NULL) {
+    /* free remaining pbufs in chain */
+    pbuf_free(q->next);
+  }
+  /* q is last packet in chain */
+  q->next = NULL;
+
+}
+
+/**
+ * Adjusts the payload pointer to hide or reveal headers in the payload.
+ *
+ * Adjusts the ->payload pointer so that space for a header
+ * (dis)appears in the pbuf payload.
+ *
+ * The ->payload, ->tot_len and ->len fields are adjusted.
+ *
+ * @param p pbuf to change the header size.
+ * @param header_size_increment Number of bytes to increment header size which
+ * increases the size of the pbuf. New space is on the front.
+ * (Using a negative value decreases the header size.)
+ * If hdr_size_inc is 0, this function does nothing and returns succesful.
+ *
+ * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so
+ * the call will fail. A check is made that the increase in header size does
+ * not move the payload pointer in front of the start of the buffer.
+ * @return non-zero on failure, zero on success.
+ *
+ */
+u8_t
+pbuf_header(struct pbuf *p, s16_t header_size_increment)
+{
+  u16_t type;
+  void *payload;
+  u16_t increment_magnitude;
+
+  LWIP_ASSERT("p != NULL", p != NULL);
+  if ((header_size_increment == 0) || (p == NULL)) {
+    return 0;
+  }
+ 
+  if (header_size_increment < 0){
+    increment_magnitude = -header_size_increment;
+    /* Check that we aren't going to move off the end of the pbuf */
+    LWIP_ERROR("increment_magnitude <= p->len", (increment_magnitude <= p->len), return 1;);
+  } else {
+    increment_magnitude = header_size_increment;
+#if 0
+    /* Can't assert these as some callers speculatively call
+         pbuf_header() to see if it's OK.  Will return 1 below instead. */
+    /* Check that we've got the correct type of pbuf to work with */
+    LWIP_ASSERT("p->type == PBUF_RAM || p->type == PBUF_POOL", 
+                p->type == PBUF_RAM || p->type == PBUF_POOL);
+    /* Check that we aren't going to move off the beginning of the pbuf */
+    LWIP_ASSERT("p->payload - increment_magnitude >= p + SIZEOF_STRUCT_PBUF",
+                (u8_t *)p->payload - increment_magnitude >= (u8_t *)p + SIZEOF_STRUCT_PBUF);
+#endif
+  }
+
+  type = p->type;
+  /* remember current payload pointer */
+  payload = p->payload;
+
+  /* pbuf types containing payloads? */
+  if (type == PBUF_RAM || type == PBUF_POOL) {
+    /* set new payload pointer */
+    p->payload = (u8_t *)p->payload - header_size_increment;
+    /* boundary check fails? */
+    if ((u8_t *)p->payload < (u8_t *)p + SIZEOF_STRUCT_PBUF) {
+      LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+        ("pbuf_header: failed as %p < %p (not enough space for new header size)\n",
+        (void *)p->payload, (void *)(p + 1)));
+      /* restore old payload pointer */
+      p->payload = payload;
+      /* bail out unsuccesfully */
+      return 1;
+    }
+  /* pbuf types refering to external payloads? */
+  } else if (type == PBUF_REF || type == PBUF_ROM) {
+    /* hide a header in the payload? */
+    if ((header_size_increment < 0) && (increment_magnitude <= p->len)) {
+      /* increase payload pointer */
+      p->payload = (u8_t *)p->payload - header_size_increment;
+    } else {
+      /* cannot expand payload to front (yet!)
+       * bail out unsuccesfully */
+      return 1;
+    }
+  } else {
+    /* Unknown type */
+    LWIP_ASSERT("bad pbuf type", 0);
+    return 1;
+  }
+  /* modify pbuf length fields */
+  p->len += header_size_increment;
+  p->tot_len += header_size_increment;
+
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_header: old %p new %p (%"S16_F")\n",
+    (void *)payload, (void *)p->payload, header_size_increment));
+
+  return 0;
+}
+
+/**
+ * Dereference a pbuf chain or queue and deallocate any no-longer-used
+ * pbufs at the head of this chain or queue.
+ *
+ * Decrements the pbuf reference count. If it reaches zero, the pbuf is
+ * deallocated.
+ *
+ * For a pbuf chain, this is repeated for each pbuf in the chain,
+ * up to the first pbuf which has a non-zero reference count after
+ * decrementing. So, when all reference counts are one, the whole
+ * chain is free'd.
+ *
+ * @param p The pbuf (chain) to be dereferenced.
+ *
+ * @return the number of pbufs that were de-allocated
+ * from the head of the chain.
+ *
+ * @note MUST NOT be called on a packet queue (Not verified to work yet).
+ * @note the reference counter of a pbuf equals the number of pointers
+ * that refer to the pbuf (or into the pbuf).
+ *
+ * @internal examples:
+ *
+ * Assuming existing chains a->b->c with the following reference
+ * counts, calling pbuf_free(a) results in:
+ * 
+ * 1->2->3 becomes ...1->3
+ * 3->3->3 becomes 2->3->3
+ * 1->1->2 becomes ......1
+ * 2->1->1 becomes 1->1->1
+ * 1->1->1 becomes .......
+ *
+ */
+u8_t
+pbuf_free(struct pbuf *p)
+{
+  u16_t type;
+  struct pbuf *q;
+  u8_t count;
+
+  if (p == NULL) {
+    LWIP_ASSERT("p != NULL", p != NULL);
+    /* if assertions are disabled, proceed with debug output */
+    LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+      ("pbuf_free(p == NULL) was called.\n"));
+    return 0;
+  }
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p));
+
+  PERF_START;
+
+  LWIP_ASSERT("pbuf_free: sane type",
+    p->type == PBUF_RAM || p->type == PBUF_ROM ||
+    p->type == PBUF_REF || p->type == PBUF_POOL);
+
+  count = 0;
+  /* de-allocate all consecutive pbufs from the head of the chain that
+   * obtain a zero reference count after decrementing*/
+  while (p != NULL) {
+    u16_t ref;
+    SYS_ARCH_DECL_PROTECT(old_level);
+    /* Since decrementing ref cannot be guaranteed to be a single machine operation
+     * we must protect it. We put the new ref into a local variable to prevent
+     * further protection. */
+    SYS_ARCH_PROTECT(old_level);
+    /* all pbufs in a chain are referenced at least once */
+    LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0);
+    /* decrease reference count (number of pointers to pbuf) */
+    ref = --(p->ref);
+    SYS_ARCH_UNPROTECT(old_level);
+    /* this pbuf is no longer referenced to? */
+    if (ref == 0) {
+      /* remember next pbuf in chain for next iteration */
+      q = p->next;
+      LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p));
+      type = p->type;
+#if LWIP_SUPPORT_CUSTOM_PBUF
+      /* is this a custom pbuf? */
+      if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) {
+        struct pbuf_custom *pc = (struct pbuf_custom*)p;
+        LWIP_ASSERT("pc->custom_free_function != NULL", pc->custom_free_function != NULL);
+        pc->custom_free_function(p);
+      } else
+#endif /* LWIP_SUPPORT_CUSTOM_PBUF */
+      {
+        /* is this a pbuf from the pool? */
+        if (type == PBUF_POOL) {
+          memp_free(MEMP_PBUF_POOL, p);
+        /* is this a ROM or RAM referencing pbuf? */
+        } else if (type == PBUF_ROM || type == PBUF_REF) {
+          memp_free(MEMP_PBUF, p);
+        /* type == PBUF_RAM */
+        } else {
+          mem_free(p);
+        }
+      }
+      count++;
+      /* proceed to next pbuf */
+      p = q;
+    /* p->ref > 0, this pbuf is still referenced to */
+    /* (and so the remaining pbufs in chain as well) */
+    } else {
+      LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, ref));
+      /* stop walking through the chain */
+      p = NULL;
+    }
+  }
+  PERF_STOP("pbuf_free");
+  /* return number of de-allocated pbufs */
+  return count;
+}
+
+/**
+ * Count number of pbufs in a chain
+ *
+ * @param p first pbuf of chain
+ * @return the number of pbufs in a chain
+ */
+
+u8_t
+pbuf_clen(struct pbuf *p)
+{
+  u8_t len;
+
+  len = 0;
+  while (p != NULL) {
+    ++len;
+    p = p->next;
+  }
+  return len;
+}
+
+/**
+ * Increment the reference count of the pbuf.
+ *
+ * @param p pbuf to increase reference counter of
+ *
+ */
+void
+pbuf_ref(struct pbuf *p)
+{
+  SYS_ARCH_DECL_PROTECT(old_level);
+  /* pbuf given? */
+  if (p != NULL) {
+    SYS_ARCH_PROTECT(old_level);
+    ++(p->ref);
+    SYS_ARCH_UNPROTECT(old_level);
+  }
+}
+
+/**
+ * Concatenate two pbufs (each may be a pbuf chain) and take over
+ * the caller's reference of the tail pbuf.
+ * 
+ * @note The caller MAY NOT reference the tail pbuf afterwards.
+ * Use pbuf_chain() for that purpose.
+ * 
+ * @see pbuf_chain()
+ */
+
+void
+pbuf_cat(struct pbuf *h, struct pbuf *t)
+{
+  struct pbuf *p;
+
+  LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)",
+             ((h != NULL) && (t != NULL)), return;);
+
+  /* proceed to last pbuf of chain */
+  for (p = h; p->next != NULL; p = p->next) {
+    /* add total length of second chain to all totals of first chain */
+    p->tot_len += t->tot_len;
+  }
+  /* { p is last pbuf of first h chain, p->next == NULL } */
+  LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len);
+  LWIP_ASSERT("p->next == NULL", p->next == NULL);
+  /* add total length of second chain to last pbuf total of first chain */
+  p->tot_len += t->tot_len;
+  /* chain last pbuf of head (p) with first of tail (t) */
+  p->next = t;
+  /* p->next now references t, but the caller will drop its reference to t,
+   * so netto there is no change to the reference count of t.
+   */
+}
+
+/**
+ * Chain two pbufs (or pbuf chains) together.
+ * 
+ * The caller MUST call pbuf_free(t) once it has stopped
+ * using it. Use pbuf_cat() instead if you no longer use t.
+ * 
+ * @param h head pbuf (chain)
+ * @param t tail pbuf (chain)
+ * @note The pbufs MUST belong to the same packet.
+ * @note MAY NOT be called on a packet queue.
+ *
+ * The ->tot_len fields of all pbufs of the head chain are adjusted.
+ * The ->next field of the last pbuf of the head chain is adjusted.
+ * The ->ref field of the first pbuf of the tail chain is adjusted.
+ *
+ */
+void
+pbuf_chain(struct pbuf *h, struct pbuf *t)
+{
+  pbuf_cat(h, t);
+  /* t is now referenced by h */
+  pbuf_ref(t);
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t));
+}
+
+/**
+ * Dechains the first pbuf from its succeeding pbufs in the chain.
+ *
+ * Makes p->tot_len field equal to p->len.
+ * @param p pbuf to dechain
+ * @return remainder of the pbuf chain, or NULL if it was de-allocated.
+ * @note May not be called on a packet queue.
+ */
+struct pbuf *
+pbuf_dechain(struct pbuf *p)
+{
+  struct pbuf *q;
+  u8_t tail_gone = 1;
+  /* tail */
+  q = p->next;
+  /* pbuf has successor in chain? */
+  if (q != NULL) {
+    /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */
+    LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len);
+    /* enforce invariant if assertion is disabled */
+    q->tot_len = p->tot_len - p->len;
+    /* decouple pbuf from remainder */
+    p->next = NULL;
+    /* total length of pbuf p is its own length only */
+    p->tot_len = p->len;
+    /* q is no longer referenced by p, free it */
+    LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_dechain: unreferencing %p\n", (void *)q));
+    tail_gone = pbuf_free(q);
+    if (tail_gone > 0) {
+      LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE,
+                  ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q));
+    }
+    /* return remaining tail or NULL if deallocated */
+  }
+  /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */
+  LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len);
+  return ((tail_gone > 0) ? NULL : q);
+}
+
+/**
+ *
+ * Create PBUF_RAM copies of pbufs.
+ *
+ * Used to queue packets on behalf of the lwIP stack, such as
+ * ARP based queueing.
+ *
+ * @note You MUST explicitly use p = pbuf_take(p);
+ *
+ * @note Only one packet is copied, no packet queue!
+ *
+ * @param p_to pbuf destination of the copy
+ * @param p_from pbuf source of the copy
+ *
+ * @return ERR_OK if pbuf was copied
+ *         ERR_ARG if one of the pbufs is NULL or p_to is not big
+ *                 enough to hold p_from
+ */
+err_t
+pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
+{
+  u16_t offset_to=0, offset_from=0, len;
+
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n",
+    (void*)p_to, (void*)p_from));
+
+  /* is the target big enough to hold the source? */
+  LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) &&
+             (p_from != NULL) && (p_to->tot_len >= p_from->tot_len)), return ERR_ARG;);
+
+  /* iterate through pbuf chain */
+  do
+  {
+    /* copy one part of the original chain */
+    if ((p_to->len - offset_to) >= (p_from->len - offset_from)) {
+      /* complete current p_from fits into current p_to */
+      len = p_from->len - offset_from;
+    } else {
+      /* current p_from does not fit into current p_to */
+      len = p_to->len - offset_to;
+    }
+    MEMCPY((u8_t*)p_to->payload + offset_to, (u8_t*)p_from->payload + offset_from, len);
+    offset_to += len;
+    offset_from += len;
+    LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len);
+    LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len);
+    if (offset_from >= p_from->len) {
+      /* on to next p_from (if any) */
+      offset_from = 0;
+      p_from = p_from->next;
+    }
+    if (offset_to == p_to->len) {
+      /* on to next p_to (if any) */
+      offset_to = 0;
+      p_to = p_to->next;
+      LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL) , return ERR_ARG;);
+    }
+
+    if((p_from != NULL) && (p_from->len == p_from->tot_len)) {
+      /* don't copy more than one packet! */
+      LWIP_ERROR("pbuf_copy() does not allow packet queues!\n",
+                 (p_from->next == NULL), return ERR_VAL;);
+    }
+    if((p_to != NULL) && (p_to->len == p_to->tot_len)) {
+      /* don't copy more than one packet! */
+      LWIP_ERROR("pbuf_copy() does not allow packet queues!\n",
+                  (p_to->next == NULL), return ERR_VAL;);
+    }
+  } while (p_from);
+  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n"));
+  return ERR_OK;
+}
+
+/**
+ * Copy (part of) the contents of a packet buffer
+ * to an application supplied buffer.
+ *
+ * @param buf the pbuf from which to copy data
+ * @param dataptr the application supplied buffer
+ * @param len length of data to copy (dataptr must be big enough). No more 
+ * than buf->tot_len will be copied, irrespective of len
+ * @param offset offset into the packet buffer from where to begin copying len bytes
+ * @return the number of bytes copied, or 0 on failure
+ */
+u16_t
+pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
+{
+  struct pbuf *p;
+  u16_t left;
+  u16_t buf_copy_len;
+  u16_t copied_total = 0;
+
+  LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;);
+  LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;);
+
+  left = 0;
+
+  if((buf == NULL) || (dataptr == NULL)) {
+    return 0;
+  }
+
+  /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */
+  for(p = buf; len != 0 && p != NULL; p = p->next) {
+    if ((offset != 0) && (offset >= p->len)) {
+      /* don't copy from this buffer -> on to the next */
+      offset -= p->len;
+    } else {
+      /* copy from this buffer. maybe only partially. */
+      buf_copy_len = p->len - offset;
+      if (buf_copy_len > len)
+          buf_copy_len = len;
+      /* copy the necessary parts of the buffer */
+      MEMCPY(&((char*)dataptr)[left], &((char*)p->payload)[offset], buf_copy_len);
+      copied_total += buf_copy_len;
+      left += buf_copy_len;
+      len -= buf_copy_len;
+      offset = 0;
+    }
+  }
+  return copied_total;
+}
+
+/**
+ * Copy application supplied data into a pbuf.
+ * This function can only be used to copy the equivalent of buf->tot_len data.
+ *
+ * @param buf pbuf to fill with data
+ * @param dataptr application supplied data buffer
+ * @param len length of the application supplied data buffer
+ *
+ * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough
+ */
+err_t
+pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len)
+{
+  struct pbuf *p;
+  u16_t buf_copy_len;
+  u16_t total_copy_len = len;
+  u16_t copied_total = 0;
+
+  LWIP_ERROR("pbuf_take: invalid buf", (buf != NULL), return 0;);
+  LWIP_ERROR("pbuf_take: invalid dataptr", (dataptr != NULL), return 0;);
+
+  if ((buf == NULL) || (dataptr == NULL) || (buf->tot_len < len)) {
+    return ERR_ARG;
+  }
+
+  /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */
+  for(p = buf; total_copy_len != 0; p = p->next) {
+    LWIP_ASSERT("pbuf_take: invalid pbuf", p != NULL);
+    buf_copy_len = total_copy_len;
+    if (buf_copy_len > p->len) {
+      /* this pbuf cannot hold all remaining data */
+      buf_copy_len = p->len;
+    }
+    /* copy the necessary parts of the buffer */
+    MEMCPY(p->payload, &((char*)dataptr)[copied_total], buf_copy_len);
+    total_copy_len -= buf_copy_len;
+    copied_total += buf_copy_len;
+  }
+  LWIP_ASSERT("did not copy all data", total_copy_len == 0 && copied_total == len);
+  return ERR_OK;
+}
+
+/**
+ * Creates a single pbuf out of a queue of pbufs.
+ *
+ * @remark: Either the source pbuf 'p' is freed by this function or the original
+ *          pbuf 'p' is returned, therefore the caller has to check the result!
+ *
+ * @param p the source pbuf
+ * @param layer pbuf_layer of the new pbuf
+ *
+ * @return a new, single pbuf (p->next is NULL)
+ *         or the old pbuf if allocation fails
+ */
+struct pbuf*
+pbuf_coalesce(struct pbuf *p, pbuf_layer layer)
+{
+  struct pbuf *q;
+  err_t err;
+  if (p->next == NULL) {
+    return p;
+  }
+  q = pbuf_alloc(layer, p->tot_len, PBUF_RAM);
+  if (q == NULL) {
+    /* @todo: what do we do now? */
+    return p;
+  }
+  err = pbuf_copy(q, p);
+  LWIP_ASSERT("pbuf_copy failed", err == ERR_OK);
+  pbuf_free(p);
+  return q;
+}
+
+#if LWIP_CHECKSUM_ON_COPY
+/**
+ * Copies data into a single pbuf (*not* into a pbuf queue!) and updates
+ * the checksum while copying
+ *
+ * @param p the pbuf to copy data into
+ * @param start_offset offset of p->payload where to copy the data to
+ * @param dataptr data to copy into the pbuf
+ * @param len length of data to copy into the pbuf
+ * @param chksum pointer to the checksum which is updated
+ * @return ERR_OK if successful, another error if the data does not fit
+ *         within the (first) pbuf (no pbuf queues!)
+ */
+err_t
+pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr,
+                 u16_t len, u16_t *chksum)
+{
+  u32_t acc;
+  u16_t copy_chksum;
+  char *dst_ptr;
+  LWIP_ASSERT("p != NULL", p != NULL);
+  LWIP_ASSERT("dataptr != NULL", dataptr != NULL);
+  LWIP_ASSERT("chksum != NULL", chksum != NULL);
+  LWIP_ASSERT("len != 0", len != 0);
+
+  if ((start_offset >= p->len) || (start_offset + len > p->len)) {
+    return ERR_ARG;
+  }
+
+  dst_ptr = ((char*)p->payload) + start_offset;
+  copy_chksum = LWIP_CHKSUM_COPY(dst_ptr, dataptr, len);
+  if ((start_offset & 1) != 0) {
+    copy_chksum = SWAP_BYTES_IN_WORD(copy_chksum);
+  }
+  acc = *chksum;
+  acc += copy_chksum;
+  *chksum = FOLD_U32T(acc);
+  return ERR_OK;
+}
+#endif /* LWIP_CHECKSUM_ON_COPY */
+
+ /** Get one byte from the specified position in a pbuf
+ * WARNING: returns zero for offset >= p->tot_len
+ *
+ * @param p pbuf to parse
+ * @param offset offset into p of the byte to return
+ * @return byte at an offset into p OR ZERO IF 'offset' >= p->tot_len
+ */
+u8_t
+pbuf_get_at(struct pbuf* p, u16_t offset)
+{
+  u16_t copy_from = offset;
+  struct pbuf* q = p;
+
+  /* get the correct pbuf */
+  while ((q != NULL) && (q->len <= copy_from)) {
+    copy_from -= q->len;
+    q = q->next;
+  }
+  /* return requested data if pbuf is OK */
+  if ((q != NULL) && (q->len > copy_from)) {
+    return ((u8_t*)q->payload)[copy_from];
+  }
+  return 0;
+}
+
+/** Compare pbuf contents at specified offset with memory s2, both of length n
+ *
+ * @param p pbuf to compare
+ * @param offset offset into p at wich to start comparing
+ * @param s2 buffer to compare
+ * @param n length of buffer to compare
+ * @return zero if equal, nonzero otherwise
+ *         (0xffff if p is too short, diffoffset+1 otherwise)
+ */
+u16_t
+pbuf_memcmp(struct pbuf* p, u16_t offset, const void* s2, u16_t n)
+{
+  u16_t start = offset;
+  struct pbuf* q = p;
+
+  /* get the correct pbuf */
+  while ((q != NULL) && (q->len <= start)) {
+    start -= q->len;
+    q = q->next;
+  }
+  /* return requested data if pbuf is OK */
+  if ((q != NULL) && (q->len > start)) {
+    u16_t i;
+    for(i = 0; i < n; i++) {
+      u8_t a = pbuf_get_at(q, start + i);
+      u8_t b = ((u8_t*)s2)[i];
+      if (a != b) {
+        return i+1;
+      }
+    }
+    return 0;
+  }
+  return 0xffff;
+}
+
+/** Find occurrence of mem (with length mem_len) in pbuf p, starting at offset
+ * start_offset.
+ *
+ * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as
+ *        return value 'not found'
+ * @param mem search for the contents of this buffer
+ * @param mem_len length of 'mem'
+ * @param start_offset offset into p at which to start searching
+ * @return 0xFFFF if substr was not found in p or the index where it was found
+ */
+u16_t
+pbuf_memfind(struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset)
+{
+  u16_t i;
+  u16_t max = p->tot_len - mem_len;
+  if (p->tot_len >= mem_len + start_offset) {
+    for(i = start_offset; i <= max; ) {
+      u16_t plus = pbuf_memcmp(p, i, mem, mem_len);
+      if (plus == 0) {
+        return i;
+      } else {
+        i += plus;
+      }
+    }
+  }
+  return 0xFFFF;
+}
+
+/** Find occurrence of substr with length substr_len in pbuf p, start at offset
+ * start_offset
+ * WARNING: in contrast to strstr(), this one does not stop at the first \0 in
+ * the pbuf/source string!
+ *
+ * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as
+ *        return value 'not found'
+ * @param substr string to search for in p, maximum length is 0xFFFE
+ * @return 0xFFFF if substr was not found in p or the index where it was found
+ */
+u16_t
+pbuf_strstr(struct pbuf* p, const char* substr)
+{
+  size_t substr_len;
+  if ((substr == NULL) || (substr[0] == 0) || (p->tot_len == 0xFFFF)) {
+    return 0xFFFF;
+  }
+  substr_len = strlen(substr);
+  if (substr_len >= 0xFFFF) {
+    return 0xFFFF;
+  }
+  return pbuf_memfind(p, substr, (u16_t)substr_len, 0);
+}
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/raw.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/raw.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/raw.c	(revision 164)
@@ -0,0 +1,350 @@
+/**
+ * @file
+ * Implementation of raw protocol PCBs for low-level handling of
+ * different types of protocols besides (or overriding) those
+ * already available in lwIP.
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/def.h"
+#include "lwip/memp.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/raw.h"
+#include "lwip/stats.h"
+#include "arch/perf.h"
+
+#include <string.h>
+
+/** The list of RAW PCBs */
+static struct raw_pcb *raw_pcbs;
+
+/**
+ * Determine if in incoming IP packet is covered by a RAW PCB
+ * and if so, pass it to a user-provided receive callback function.
+ *
+ * Given an incoming IP datagram (as a chain of pbufs) this function
+ * finds a corresponding RAW PCB and calls the corresponding receive
+ * callback function.
+ *
+ * @param p pbuf to be demultiplexed to a RAW PCB.
+ * @param inp network interface on which the datagram was received.
+ * @return - 1 if the packet has been eaten by a RAW PCB receive
+ *           callback function. The caller MAY NOT not reference the
+ *           packet any longer, and MAY NOT call pbuf_free().
+ * @return - 0 if packet is not eaten (pbuf is still referenced by the
+ *           caller).
+ *
+ */
+u8_t
+raw_input(struct pbuf *p, struct netif *inp)
+{
+  struct raw_pcb *pcb, *prev;
+  struct ip_hdr *iphdr;
+  s16_t proto;
+  u8_t eaten = 0;
+
+  LWIP_UNUSED_ARG(inp);
+
+  iphdr = (struct ip_hdr *)p->payload;
+  proto = IPH_PROTO(iphdr);
+
+  prev = NULL;
+  pcb = raw_pcbs;
+  /* loop through all raw pcbs until the packet is eaten by one */
+  /* this allows multiple pcbs to match against the packet by design */
+  while ((eaten == 0) && (pcb != NULL)) {
+    if ((pcb->protocol == proto) &&
+        (ip_addr_isany(&pcb->local_ip) ||
+         ip_addr_cmp(&(pcb->local_ip), &current_iphdr_dest))) {
+#if IP_SOF_BROADCAST_RECV
+      /* broadcast filter? */
+      if (ip_get_option(pcb, SOF_BROADCAST) || !ip_addr_isbroadcast(&current_iphdr_dest, inp))
+#endif /* IP_SOF_BROADCAST_RECV */
+      {
+        /* receive callback function available? */
+        if (pcb->recv != NULL) {
+          /* the receive callback function did not eat the packet? */
+          if (pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr()) != 0) {
+            /* receive function ate the packet */
+            p = NULL;
+            eaten = 1;
+            if (prev != NULL) {
+            /* move the pcb to the front of raw_pcbs so that is
+               found faster next time */
+              prev->next = pcb->next;
+              pcb->next = raw_pcbs;
+              raw_pcbs = pcb;
+            }
+          }
+        }
+        /* no receive callback function was set for this raw PCB */
+      }
+      /* drop the packet */
+    }
+    prev = pcb;
+    pcb = pcb->next;
+  }
+  return eaten;
+}
+
+/**
+ * Bind a RAW PCB.
+ *
+ * @param pcb RAW PCB to be bound with a local address ipaddr.
+ * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to
+ * bind to all local interfaces.
+ *
+ * @return lwIP error code.
+ * - ERR_OK. Successful. No error occured.
+ * - ERR_USE. The specified IP address is already bound to by
+ * another RAW PCB.
+ *
+ * @see raw_disconnect()
+ */
+err_t
+raw_bind(struct raw_pcb *pcb, ip_addr_t *ipaddr)
+{
+  ip_addr_set(&pcb->local_ip, ipaddr);
+  return ERR_OK;
+}
+
+/**
+ * Connect an RAW PCB. This function is required by upper layers
+ * of lwip. Using the raw api you could use raw_sendto() instead
+ *
+ * This will associate the RAW PCB with the remote address.
+ *
+ * @param pcb RAW PCB to be connected with remote address ipaddr and port.
+ * @param ipaddr remote IP address to connect with.
+ *
+ * @return lwIP error code
+ *
+ * @see raw_disconnect() and raw_sendto()
+ */
+err_t
+raw_connect(struct raw_pcb *pcb, ip_addr_t *ipaddr)
+{
+  ip_addr_set(&pcb->remote_ip, ipaddr);
+  return ERR_OK;
+}
+
+
+/**
+ * Set the callback function for received packets that match the
+ * raw PCB's protocol and binding. 
+ * 
+ * The callback function MUST either
+ * - eat the packet by calling pbuf_free() and returning non-zero. The
+ *   packet will not be passed to other raw PCBs or other protocol layers.
+ * - not free the packet, and return zero. The packet will be matched
+ *   against further PCBs and/or forwarded to another protocol layers.
+ * 
+ * @return non-zero if the packet was free()d, zero if the packet remains
+ * available for others.
+ */
+void
+raw_recv(struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg)
+{
+  /* remember recv() callback and user data */
+  pcb->recv = recv;
+  pcb->recv_arg = recv_arg;
+}
+
+/**
+ * Send the raw IP packet to the given address. Note that actually you cannot
+ * modify the IP headers (this is inconsistent with the receive callback where
+ * you actually get the IP headers), you can only specify the IP payload here.
+ * It requires some more changes in lwIP. (there will be a raw_send() function
+ * then.)
+ *
+ * @param pcb the raw pcb which to send
+ * @param p the IP payload to send
+ * @param ipaddr the destination address of the IP packet
+ *
+ */
+err_t
+raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
+{
+  err_t err;
+  struct netif *netif;
+  ip_addr_t *src_ip;
+  struct pbuf *q; /* q will be sent down the stack */
+  
+  LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
+  
+  /* not enough space to add an IP header to first pbuf in given p chain? */
+  if (pbuf_header(p, IP_HLEN)) {
+    /* allocate header in new pbuf */
+    q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
+    /* new header pbuf could not be allocated? */
+    if (q == NULL) {
+      LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n"));
+      return ERR_MEM;
+    }
+    if (p->tot_len != 0) {
+      /* chain header q in front of given pbuf p */
+      pbuf_chain(q, p);
+    }
+    /* { first pbuf q points to header pbuf } */
+    LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
+  }  else {
+    /* first pbuf q equals given pbuf */
+    q = p;
+    if(pbuf_header(q, -IP_HLEN)) {
+      LWIP_ASSERT("Can't restore header we just removed!", 0);
+      return ERR_MEM;
+    }
+  }
+
+  if ((netif = ip_route(ipaddr)) == NULL) {
+    LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+      ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
+    /* free any temporary header pbuf allocated by pbuf_header() */
+    if (q != p) {
+      pbuf_free(q);
+    }
+    return ERR_RTE;
+  }
+
+#if IP_SOF_BROADCAST
+  /* broadcast filter? */
+  if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(ipaddr, netif)) {
+    LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
+    /* free any temporary header pbuf allocated by pbuf_header() */
+    if (q != p) {
+      pbuf_free(q);
+    }
+    return ERR_VAL;
+  }
+#endif /* IP_SOF_BROADCAST */
+
+  if (ip_addr_isany(&pcb->local_ip)) {
+    /* use outgoing network interface IP address as source address */
+    src_ip = &(netif->ip_addr);
+  } else {
+    /* use RAW PCB local IP address as source address */
+    src_ip = &(pcb->local_ip);
+  }
+
+  NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint);
+  err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif);
+  NETIF_SET_HWADDRHINT(netif, NULL);
+
+  /* did we chain a header earlier? */
+  if (q != p) {
+    /* free the header */
+    pbuf_free(q);
+  }
+  return err;
+}
+
+/**
+ * Send the raw IP packet to the address given by raw_connect()
+ *
+ * @param pcb the raw pcb which to send
+ * @param p the IP payload to send
+ *
+ */
+err_t
+raw_send(struct raw_pcb *pcb, struct pbuf *p)
+{
+  return raw_sendto(pcb, p, &pcb->remote_ip);
+}
+
+/**
+ * Remove an RAW PCB.
+ *
+ * @param pcb RAW PCB to be removed. The PCB is removed from the list of
+ * RAW PCB's and the data structure is freed from memory.
+ *
+ * @see raw_new()
+ */
+void
+raw_remove(struct raw_pcb *pcb)
+{
+  struct raw_pcb *pcb2;
+  /* pcb to be removed is first in list? */
+  if (raw_pcbs == pcb) {
+    /* make list start at 2nd pcb */
+    raw_pcbs = raw_pcbs->next;
+    /* pcb not 1st in list */
+  } else {
+    for(pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
+      /* find pcb in raw_pcbs list */
+      if (pcb2->next != NULL && pcb2->next == pcb) {
+        /* remove pcb from list */
+        pcb2->next = pcb->next;
+      }
+    }
+  }
+  memp_free(MEMP_RAW_PCB, pcb);
+}
+
+/**
+ * Create a RAW PCB.
+ *
+ * @return The RAW PCB which was created. NULL if the PCB data structure
+ * could not be allocated.
+ *
+ * @param proto the protocol number of the IPs payload (e.g. IP_PROTO_ICMP)
+ *
+ * @see raw_remove()
+ */
+struct raw_pcb *
+raw_new(u8_t proto)
+{
+  struct raw_pcb *pcb;
+
+  LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_new\n"));
+
+  pcb = (struct raw_pcb *)memp_malloc(MEMP_RAW_PCB);
+  /* could allocate RAW PCB? */
+  if (pcb != NULL) {
+    /* initialize PCB to all zeroes */
+    memset(pcb, 0, sizeof(struct raw_pcb));
+    pcb->protocol = proto;
+    pcb->ttl = RAW_TTL;
+    pcb->next = raw_pcbs;
+    raw_pcbs = pcb;
+  }
+  return pcb;
+}
+
+#endif /* LWIP_RAW */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/asn1_dec.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/asn1_dec.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/asn1_dec.c	(revision 164)
@@ -0,0 +1,657 @@
+/**
+ * @file
+ * Abstract Syntax Notation One (ISO 8824, 8825) decoding
+ *
+ * @todo not optimised (yet), favor correctness over speed, favor speed over size
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/snmp_asn1.h"
+
+/**
+ * Retrieves type field from incoming pbuf chain.
+ *
+ * @param p points to a pbuf holding an ASN1 coded type field
+ * @param ofs points to the offset within the pbuf chain of the ASN1 coded type field
+ * @param type return ASN1 type
+ * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
+ */
+err_t
+snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type)
+{
+  u16_t plen, base;
+  u8_t *msg_ptr;
+
+  plen = 0;
+  while (p != NULL)
+  {
+    base = plen;
+    plen += p->len;
+    if (ofs < plen)
+    {
+      msg_ptr = (u8_t*)p->payload;
+      msg_ptr += ofs - base;
+      *type = *msg_ptr;
+      return ERR_OK;
+    }
+    p = p->next;
+  }
+  /* p == NULL, ofs >= plen */
+  return ERR_ARG;
+}
+
+/**
+ * Decodes length field from incoming pbuf chain into host length.
+ *
+ * @param p points to a pbuf holding an ASN1 coded length
+ * @param ofs points to the offset within the pbuf chain of the ASN1 coded length
+ * @param octets_used returns number of octets used by the length code
+ * @param length return host order length, upto 64k
+ * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
+ */
+err_t
+snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length)
+{
+  u16_t plen, base;
+  u8_t *msg_ptr;
+
+  plen = 0;
+  while (p != NULL)
+  {
+    base = plen;
+    plen += p->len;
+    if (ofs < plen)
+    {
+      msg_ptr = (u8_t*)p->payload;
+      msg_ptr += ofs - base;
+
+      if (*msg_ptr < 0x80)
+      {
+        /* primitive definite length format */
+        *octets_used = 1;
+        *length = *msg_ptr;
+        return ERR_OK;
+      }
+      else if (*msg_ptr == 0x80)
+      {
+        /* constructed indefinite length format, termination with two zero octets */
+        u8_t zeros;
+        u8_t i;
+
+        *length = 0;
+        zeros = 0;
+        while (zeros != 2)
+        {
+          i = 2;
+          while (i > 0)
+          {
+            i--;
+            (*length) += 1;
+            ofs += 1;
+            if (ofs >= plen)
+            {
+              /* next octet in next pbuf */
+              p = p->next;
+              if (p == NULL) { return ERR_ARG; }
+              msg_ptr = (u8_t*)p->payload;
+              plen += p->len;
+            }
+            else
+            {
+              /* next octet in same pbuf */
+              msg_ptr++;
+            }
+            if (*msg_ptr == 0)
+            {
+              zeros++;
+              if (zeros == 2)
+              {
+                /* stop while (i > 0) */
+                i = 0;
+              }
+            }
+            else
+            {
+              zeros = 0;
+            }
+          }
+        }
+        *octets_used = 1;
+        return ERR_OK;
+      }
+      else if (*msg_ptr == 0x81)
+      {
+        /* constructed definite length format, one octet */
+        ofs += 1;
+        if (ofs >= plen)
+        {
+          /* next octet in next pbuf */
+          p = p->next;
+          if (p == NULL) { return ERR_ARG; }
+          msg_ptr = (u8_t*)p->payload;
+        }
+        else
+        {
+          /* next octet in same pbuf */
+          msg_ptr++;
+        }
+        *length = *msg_ptr;
+        *octets_used = 2;
+        return ERR_OK;
+      }
+      else if (*msg_ptr == 0x82)
+      {
+        u8_t i;
+
+        /* constructed definite length format, two octets */
+        i = 2;
+        while (i > 0)
+        {
+          i--;
+          ofs += 1;
+          if (ofs >= plen)
+          {
+            /* next octet in next pbuf */
+            p = p->next;
+            if (p == NULL) { return ERR_ARG; }
+            msg_ptr = (u8_t*)p->payload;
+            plen += p->len;
+          }
+          else
+          {
+            /* next octet in same pbuf */
+            msg_ptr++;
+          }
+          if (i == 0)
+          {
+            /* least significant length octet */
+            *length |= *msg_ptr;
+          }
+          else
+          {
+            /* most significant length octet */
+            *length = (*msg_ptr) << 8;
+          }
+        }
+        *octets_used = 3;
+        return ERR_OK;
+      }
+      else
+      {
+        /* constructed definite length format 3..127 octets, this is too big (>64k) */
+        /**  @todo: do we need to accept inefficient codings with many leading zero's? */
+        *octets_used = 1 + ((*msg_ptr) & 0x7f);
+        return ERR_ARG;
+      }
+    }
+    p = p->next;
+  }
+
+  /* p == NULL, ofs >= plen */
+  return ERR_ARG;
+}
+
+/**
+ * Decodes positive integer (counter, gauge, timeticks) into u32_t.
+ *
+ * @param p points to a pbuf holding an ASN1 coded integer
+ * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer
+ * @param len length of the coded integer field
+ * @param value return host order integer
+ * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
+ *
+ * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded
+ * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value
+ * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!!
+ */
+err_t
+snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value)
+{
+  u16_t plen, base;
+  u8_t *msg_ptr;
+
+  plen = 0;
+  while (p != NULL)
+  {
+    base = plen;
+    plen += p->len;
+    if (ofs < plen)
+    {
+      msg_ptr = (u8_t*)p->payload;
+      msg_ptr += ofs - base;
+      if ((len > 0) && (len < 6))
+      {
+        /* start from zero */
+        *value = 0;
+        if (*msg_ptr & 0x80)
+        {
+          /* negative, expecting zero sign bit! */
+          return ERR_ARG;
+        }
+        else
+        {
+          /* positive */
+          if ((len > 1) && (*msg_ptr == 0))
+          {
+            /* skip leading "sign byte" octet 0x00 */
+            len--;
+            ofs += 1;
+            if (ofs >= plen)
+            {
+              /* next octet in next pbuf */
+              p = p->next;
+              if (p == NULL) { return ERR_ARG; }
+              msg_ptr = (u8_t*)p->payload;
+              plen += p->len;
+            }
+            else
+            {
+              /* next octet in same pbuf */
+              msg_ptr++;
+            }
+          }
+        }
+        /* OR octets with value */
+        while (len > 1)
+        {
+          len--;
+          *value |= *msg_ptr;
+          *value <<= 8;
+          ofs += 1;
+          if (ofs >= plen)
+          {
+            /* next octet in next pbuf */
+            p = p->next;
+            if (p == NULL) { return ERR_ARG; }
+            msg_ptr = (u8_t*)p->payload;
+            plen += p->len;
+          }
+          else
+          {
+            /* next octet in same pbuf */
+            msg_ptr++;
+          }
+        }
+        *value |= *msg_ptr;
+        return ERR_OK;
+      }
+      else
+      {
+        return ERR_ARG;
+      }
+    }
+    p = p->next;
+  }
+  /* p == NULL, ofs >= plen */
+  return ERR_ARG;
+}
+
+/**
+ * Decodes integer into s32_t.
+ *
+ * @param p points to a pbuf holding an ASN1 coded integer
+ * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer
+ * @param len length of the coded integer field
+ * @param value return host order integer
+ * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
+ *
+ * @note ASN coded integers are _always_ signed!
+ */
+err_t
+snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value)
+{
+  u16_t plen, base;
+  u8_t *msg_ptr;
+#if BYTE_ORDER == LITTLE_ENDIAN
+  u8_t *lsb_ptr = (u8_t*)value;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+  u8_t *lsb_ptr = (u8_t*)value + sizeof(s32_t) - 1;
+#endif
+  u8_t sign;
+
+  plen = 0;
+  while (p != NULL)
+  {
+    base = plen;
+    plen += p->len;
+    if (ofs < plen)
+    {
+      msg_ptr = (u8_t*)p->payload;
+      msg_ptr += ofs - base;
+      if ((len > 0) && (len < 5))
+      {
+        if (*msg_ptr & 0x80)
+        {
+          /* negative, start from -1 */
+          *value = -1;
+          sign = 1;
+        }
+        else
+        {
+          /* positive, start from 0 */
+          *value = 0;
+          sign = 0;
+        }
+        /* OR/AND octets with value */
+        while (len > 1)
+        {
+          len--;
+          if (sign)
+          {
+            *lsb_ptr &= *msg_ptr;
+            *value <<= 8;
+            *lsb_ptr |= 255;
+          }
+          else
+          {
+            *lsb_ptr |= *msg_ptr;
+            *value <<= 8;
+          }
+          ofs += 1;
+          if (ofs >= plen)
+          {
+            /* next octet in next pbuf */
+            p = p->next;
+            if (p == NULL) { return ERR_ARG; }
+            msg_ptr = (u8_t*)p->payload;
+            plen += p->len;
+          }
+          else
+          {
+            /* next octet in same pbuf */
+            msg_ptr++;
+          }
+        }
+        if (sign)
+        {
+          *lsb_ptr &= *msg_ptr;
+        }
+        else
+        {
+          *lsb_ptr |= *msg_ptr;
+        }
+        return ERR_OK;
+      }
+      else
+      {
+        return ERR_ARG;
+      }
+    }
+    p = p->next;
+  }
+  /* p == NULL, ofs >= plen */
+  return ERR_ARG;
+}
+
+/**
+ * Decodes object identifier from incoming message into array of s32_t.
+ *
+ * @param p points to a pbuf holding an ASN1 coded object identifier
+ * @param ofs points to the offset within the pbuf chain of the ASN1 coded object identifier
+ * @param len length of the coded object identifier
+ * @param oid return object identifier struct
+ * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
+ */
+err_t
+snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid)
+{
+  u16_t plen, base;
+  u8_t *msg_ptr;
+  s32_t *oid_ptr;
+
+  plen = 0;
+  while (p != NULL)
+  {
+    base = plen;
+    plen += p->len;
+    if (ofs < plen)
+    {
+      msg_ptr = (u8_t*)p->payload;
+      msg_ptr += ofs - base;
+
+      oid->len = 0;
+      oid_ptr = &oid->id[0];
+      if (len > 0)
+      {
+        /* first compressed octet */
+        if (*msg_ptr == 0x2B)
+        {
+          /* (most) common case 1.3 (iso.org) */
+          *oid_ptr = 1;
+          oid_ptr++;
+          *oid_ptr = 3;
+          oid_ptr++;
+        }
+        else if (*msg_ptr < 40)
+        {
+          *oid_ptr = 0;
+          oid_ptr++;
+          *oid_ptr = *msg_ptr;
+          oid_ptr++;
+        }
+        else if (*msg_ptr < 80)
+        {
+          *oid_ptr = 1;
+          oid_ptr++;
+          *oid_ptr = (*msg_ptr) - 40;
+          oid_ptr++;
+        }
+        else
+        {
+          *oid_ptr = 2;
+          oid_ptr++;
+          *oid_ptr = (*msg_ptr) - 80;
+          oid_ptr++;
+        }
+        oid->len = 2;
+      }
+      else
+      {
+        /* accepting zero length identifiers e.g. for
+           getnext operation. uncommon but valid */
+        return ERR_OK;
+      }
+      len--;
+      if (len > 0)
+      {
+        ofs += 1;
+        if (ofs >= plen)
+        {
+          /* next octet in next pbuf */
+          p = p->next;
+          if (p == NULL) { return ERR_ARG; }
+          msg_ptr = (u8_t*)p->payload;
+          plen += p->len;
+        }
+        else
+        {
+          /* next octet in same pbuf */
+          msg_ptr++;
+        }
+      }
+      while ((len > 0) && (oid->len < LWIP_SNMP_OBJ_ID_LEN))
+      {
+        /* sub-identifier uses multiple octets */
+        if (*msg_ptr & 0x80)
+        {
+          s32_t sub_id = 0;
+
+          while ((*msg_ptr & 0x80) && (len > 1))
+          {
+            len--;
+            sub_id = (sub_id << 7) + (*msg_ptr & ~0x80);
+            ofs += 1;
+            if (ofs >= plen)
+            {
+              /* next octet in next pbuf */
+              p = p->next;
+              if (p == NULL) { return ERR_ARG; }
+              msg_ptr = (u8_t*)p->payload;
+              plen += p->len;
+            }
+            else
+            {
+              /* next octet in same pbuf */
+              msg_ptr++;
+            }
+          }
+          if (!(*msg_ptr & 0x80) && (len > 0))
+          {
+            /* last octet sub-identifier */
+            len--;
+            sub_id = (sub_id << 7) + *msg_ptr;
+            *oid_ptr = sub_id;
+          }
+        }
+        else
+        {
+          /* !(*msg_ptr & 0x80) sub-identifier uses single octet */
+          len--;
+          *oid_ptr = *msg_ptr;
+        }
+        if (len > 0)
+        {
+          /* remaining oid bytes available ... */
+          ofs += 1;
+          if (ofs >= plen)
+          {
+            /* next octet in next pbuf */
+            p = p->next;
+            if (p == NULL) { return ERR_ARG; }
+            msg_ptr = (u8_t*)p->payload;
+            plen += p->len;
+          }
+          else
+          {
+            /* next octet in same pbuf */
+            msg_ptr++;
+          }
+        }
+        oid_ptr++;
+        oid->len++;
+      }
+      if (len == 0)
+      {
+        /* len == 0, end of oid */
+        return ERR_OK;
+      }
+      else
+      {
+        /* len > 0, oid->len == LWIP_SNMP_OBJ_ID_LEN or malformed encoding */
+        return ERR_ARG;
+      }
+
+    }
+    p = p->next;
+  }
+  /* p == NULL, ofs >= plen */
+  return ERR_ARG;
+}
+
+/**
+ * Decodes (copies) raw data (ip-addresses, octet strings, opaque encoding)
+ * from incoming message into array.
+ *
+ * @param p points to a pbuf holding an ASN1 coded raw data
+ * @param ofs points to the offset within the pbuf chain of the ASN1 coded raw data
+ * @param len length of the coded raw data (zero is valid, e.g. empty string!)
+ * @param raw_len length of the raw return value
+ * @param raw return raw bytes
+ * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
+ */
+err_t
+snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw)
+{
+  u16_t plen, base;
+  u8_t *msg_ptr;
+
+  if (len > 0)
+  {
+    plen = 0;
+    while (p != NULL)
+    {
+      base = plen;
+      plen += p->len;
+      if (ofs < plen)
+      {
+        msg_ptr = (u8_t*)p->payload;
+        msg_ptr += ofs - base;
+        if (raw_len >= len)
+        {
+          while (len > 1)
+          {
+            /* copy len - 1 octets */
+            len--;
+            *raw = *msg_ptr;
+            raw++;
+            ofs += 1;
+            if (ofs >= plen)
+            {
+              /* next octet in next pbuf */
+              p = p->next;
+              if (p == NULL) { return ERR_ARG; }
+              msg_ptr = (u8_t*)p->payload;
+              plen += p->len;
+            }
+            else
+            {
+              /* next octet in same pbuf */
+              msg_ptr++;
+            }
+          }
+          /* copy last octet */
+          *raw = *msg_ptr;
+          return ERR_OK;
+        }
+        else
+        {
+          /* raw_len < len, not enough dst space */
+          return ERR_ARG;
+        }
+      }
+      p = p->next;
+    }
+    /* p == NULL, ofs >= plen */
+    return ERR_ARG;
+  }
+  else
+  {
+    /* len == 0, empty string */
+    return ERR_OK;
+  }
+}
+
+#endif /* LWIP_SNMP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/asn1_enc.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/asn1_enc.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/asn1_enc.c	(revision 164)
@@ -0,0 +1,611 @@
+/**
+ * @file
+ * Abstract Syntax Notation One (ISO 8824, 8825) encoding
+ *
+ * @todo not optimised (yet), favor correctness over speed, favor speed over size
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/snmp_asn1.h"
+
+/**
+ * Returns octet count for length.
+ *
+ * @param length
+ * @param octets_needed points to the return value
+ */
+void
+snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed)
+{
+  if (length < 0x80U)
+  {
+    *octets_needed = 1;
+  }
+  else if (length < 0x100U)
+  {
+    *octets_needed = 2;
+  }
+  else
+  {
+    *octets_needed = 3;
+  }
+}
+
+/**
+ * Returns octet count for an u32_t.
+ *
+ * @param value
+ * @param octets_needed points to the return value
+ *
+ * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded
+ * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value
+ * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!!
+ */
+void
+snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed)
+{
+  if (value < 0x80UL)
+  {
+    *octets_needed = 1;
+  }
+  else if (value < 0x8000UL)
+  {
+    *octets_needed = 2;
+  }
+  else if (value < 0x800000UL)
+  {
+    *octets_needed = 3;
+  }
+  else if (value < 0x80000000UL)
+  {
+    *octets_needed = 4;
+  }
+  else
+  {
+    *octets_needed = 5;
+  }
+}
+
+/**
+ * Returns octet count for an s32_t.
+ *
+ * @param value
+ * @param octets_needed points to the return value
+ *
+ * @note ASN coded integers are _always_ signed.
+ */
+void
+snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed)
+{
+  if (value < 0)
+  {
+    value = ~value;
+  }
+  if (value < 0x80L)
+  {
+    *octets_needed = 1;
+  }
+  else if (value < 0x8000L)
+  {
+    *octets_needed = 2;
+  }
+  else if (value < 0x800000L)
+  {
+    *octets_needed = 3;
+  }
+  else
+  {
+    *octets_needed = 4;
+  }
+}
+
+/**
+ * Returns octet count for an object identifier.
+ *
+ * @param ident_len object identifier array length
+ * @param ident points to object identifier array
+ * @param octets_needed points to the return value
+ */
+void
+snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed)
+{
+  s32_t sub_id;
+  u8_t cnt;
+
+  cnt = 0;
+  if (ident_len > 1)
+  {
+    /* compressed prefix in one octet */
+    cnt++;
+    ident_len -= 2;
+    ident += 2;
+  }
+  while(ident_len > 0)
+  {
+    ident_len--;
+    sub_id = *ident;
+
+    sub_id >>= 7;
+    cnt++;
+    while(sub_id > 0)
+    {
+      sub_id >>= 7;
+      cnt++;
+    }
+    ident++;
+  }
+  *octets_needed = cnt;
+}
+
+/**
+ * Encodes ASN type field into a pbuf chained ASN1 msg.
+ *
+ * @param p points to output pbuf to encode value into
+ * @param ofs points to the offset within the pbuf chain
+ * @param type input ASN1 type
+ * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode
+ */
+err_t
+snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type)
+{
+  u16_t plen, base;
+  u8_t *msg_ptr;
+
+  plen = 0;
+  while (p != NULL)
+  {
+    base = plen;
+    plen += p->len;
+    if (ofs < plen)
+    {
+      msg_ptr = (u8_t*)p->payload;
+      msg_ptr += ofs - base;
+      *msg_ptr = type;
+      return ERR_OK;
+    }
+    p = p->next;
+  }
+  /* p == NULL, ofs >= plen */
+  return ERR_ARG;
+}
+
+/**
+ * Encodes host order length field into a pbuf chained ASN1 msg.
+ *
+ * @param p points to output pbuf to encode length into
+ * @param ofs points to the offset within the pbuf chain
+ * @param length is the host order length to be encoded
+ * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode
+ */
+err_t
+snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length)
+{
+  u16_t plen, base;
+  u8_t *msg_ptr;
+
+  plen = 0;
+  while (p != NULL)
+  {
+    base = plen;
+    plen += p->len;
+    if (ofs < plen)
+    {
+      msg_ptr = (u8_t*)p->payload;
+      msg_ptr += ofs - base;
+
+      if (length < 0x80)
+      {
+        *msg_ptr = (u8_t)length;
+        return ERR_OK;
+      }
+      else if (length < 0x100)
+      {
+        *msg_ptr = 0x81;
+        ofs += 1;
+        if (ofs >= plen)
+        {
+          /* next octet in next pbuf */
+          p = p->next;
+          if (p == NULL) { return ERR_ARG; }
+          msg_ptr = (u8_t*)p->payload;
+        }
+        else
+        {
+          /* next octet in same pbuf */
+          msg_ptr++;
+        }
+        *msg_ptr = (u8_t)length;
+        return ERR_OK;
+      }
+      else
+      {
+        u8_t i;
+
+        /* length >= 0x100 && length <= 0xFFFF */
+        *msg_ptr = 0x82;
+        i = 2;
+        while (i > 0)
+        {
+          i--;
+          ofs += 1;
+          if (ofs >= plen)
+          {
+            /* next octet in next pbuf */
+            p = p->next;
+            if (p == NULL) { return ERR_ARG; }
+            msg_ptr = (u8_t*)p->payload;
+            plen += p->len;
+          }
+          else
+          {
+            /* next octet in same pbuf */
+            msg_ptr++;
+          }
+          if (i == 0)
+          {
+            /* least significant length octet */
+            *msg_ptr = (u8_t)length;
+          }
+          else
+          {
+            /* most significant length octet */
+            *msg_ptr = (u8_t)(length >> 8);
+          }
+        }
+        return ERR_OK;
+      }
+    }
+    p = p->next;
+  }
+  /* p == NULL, ofs >= plen */
+  return ERR_ARG;
+}
+
+/**
+ * Encodes u32_t (counter, gauge, timeticks) into a pbuf chained ASN1 msg.
+ *
+ * @param p points to output pbuf to encode value into
+ * @param ofs points to the offset within the pbuf chain
+ * @param octets_needed encoding length (from snmp_asn1_enc_u32t_cnt())
+ * @param value is the host order u32_t value to be encoded
+ * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode
+ *
+ * @see snmp_asn1_enc_u32t_cnt()
+ */
+err_t
+snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value)
+{
+  u16_t plen, base;
+  u8_t *msg_ptr;
+
+  plen = 0;
+  while (p != NULL)
+  {
+    base = plen;
+    plen += p->len;
+    if (ofs < plen)
+    {
+      msg_ptr = (u8_t*)p->payload;
+      msg_ptr += ofs - base;
+
+      if (octets_needed == 5)
+      {
+        /* not enough bits in 'value' add leading 0x00 */
+        octets_needed--;
+        *msg_ptr = 0x00;
+        ofs += 1;
+        if (ofs >= plen)
+        {
+          /* next octet in next pbuf */
+          p = p->next;
+          if (p == NULL) { return ERR_ARG; }
+          msg_ptr = (u8_t*)p->payload;
+          plen += p->len;
+        }
+        else
+        {
+          /* next octet in same pbuf */
+          msg_ptr++;
+        }
+      }
+      while (octets_needed > 1)
+      {
+        octets_needed--;
+        *msg_ptr = (u8_t)(value >> (octets_needed << 3));
+        ofs += 1;
+        if (ofs >= plen)
+        {
+          /* next octet in next pbuf */
+          p = p->next;
+          if (p == NULL) { return ERR_ARG; }
+          msg_ptr = (u8_t*)p->payload;
+          plen += p->len;
+        }
+        else
+        {
+          /* next octet in same pbuf */
+          msg_ptr++;
+        }
+      }
+      /* (only) one least significant octet */
+      *msg_ptr = (u8_t)value;
+      return ERR_OK;
+    }
+    p = p->next;
+  }
+  /* p == NULL, ofs >= plen */
+  return ERR_ARG;
+}
+
+/**
+ * Encodes s32_t integer into a pbuf chained ASN1 msg.
+ *
+ * @param p points to output pbuf to encode value into
+ * @param ofs points to the offset within the pbuf chain
+ * @param octets_needed encoding length (from snmp_asn1_enc_s32t_cnt())
+ * @param value is the host order s32_t value to be encoded
+ * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode
+ *
+ * @see snmp_asn1_enc_s32t_cnt()
+ */
+err_t
+snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value)
+{
+  u16_t plen, base;
+  u8_t *msg_ptr;
+
+  plen = 0;
+  while (p != NULL)
+  {
+    base = plen;
+    plen += p->len;
+    if (ofs < plen)
+    {
+      msg_ptr = (u8_t*)p->payload;
+      msg_ptr += ofs - base;
+
+      while (octets_needed > 1)
+      {
+        octets_needed--;
+        *msg_ptr = (u8_t)(value >> (octets_needed << 3));
+        ofs += 1;
+        if (ofs >= plen)
+        {
+          /* next octet in next pbuf */
+          p = p->next;
+          if (p == NULL) { return ERR_ARG; }
+          msg_ptr = (u8_t*)p->payload;
+          plen += p->len;
+        }
+        else
+        {
+          /* next octet in same pbuf */
+          msg_ptr++;
+        }
+      }
+      /* (only) one least significant octet */
+      *msg_ptr = (u8_t)value;
+      return ERR_OK;
+    }
+    p = p->next;
+  }
+  /* p == NULL, ofs >= plen */
+  return ERR_ARG;
+}
+
+/**
+ * Encodes object identifier into a pbuf chained ASN1 msg.
+ *
+ * @param p points to output pbuf to encode oid into
+ * @param ofs points to the offset within the pbuf chain
+ * @param ident_len object identifier array length
+ * @param ident points to object identifier array
+ * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode
+ */
+err_t
+snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident)
+{
+  u16_t plen, base;
+  u8_t *msg_ptr;
+
+  plen = 0;
+  while (p != NULL)
+  {
+    base = plen;
+    plen += p->len;
+    if (ofs < plen)
+    {
+      msg_ptr = (u8_t*)p->payload;
+      msg_ptr += ofs - base;
+
+      if (ident_len > 1)
+      {
+        if ((ident[0] == 1) && (ident[1] == 3))
+        {
+          /* compressed (most common) prefix .iso.org */
+          *msg_ptr = 0x2b;
+        }
+        else
+        {
+          /* calculate prefix */
+          *msg_ptr = (u8_t)((ident[0] * 40) + ident[1]);
+        }
+        ofs += 1;
+        if (ofs >= plen)
+        {
+          /* next octet in next pbuf */
+          p = p->next;
+          if (p == NULL) { return ERR_ARG; }
+          msg_ptr = (u8_t*)p->payload;
+          plen += p->len;
+        }
+        else
+        {
+          /* next octet in same pbuf */
+          msg_ptr++;
+        }
+        ident_len -= 2;
+        ident += 2;
+      }
+      else
+      {
+/* @bug:  allow empty varbinds for symmetry (we must decode them for getnext), allow partial compression??  */
+        /* ident_len <= 1, at least we need zeroDotZero (0.0) (ident_len == 2) */
+        return ERR_ARG;
+      }
+      while (ident_len > 0)
+      {
+        s32_t sub_id;
+        u8_t shift, tail;
+
+        ident_len--;
+        sub_id = *ident;
+        tail = 0;
+        shift = 28;
+        while(shift > 0)
+        {
+          u8_t code;
+
+          code = (u8_t)(sub_id >> shift);
+          if ((code != 0) || (tail != 0))
+          {
+            tail = 1;
+            *msg_ptr = code | 0x80;
+            ofs += 1;
+            if (ofs >= plen)
+            {
+              /* next octet in next pbuf */
+              p = p->next;
+              if (p == NULL) { return ERR_ARG; }
+              msg_ptr = (u8_t*)p->payload;
+              plen += p->len;
+            }
+            else
+            {
+              /* next octet in same pbuf */
+              msg_ptr++;
+            }
+          }
+          shift -= 7;
+        }
+        *msg_ptr = (u8_t)sub_id & 0x7F;
+        if (ident_len > 0)
+        {
+          ofs += 1;
+          if (ofs >= plen)
+          {
+            /* next octet in next pbuf */
+            p = p->next;
+            if (p == NULL) { return ERR_ARG; }
+            msg_ptr = (u8_t*)p->payload;
+            plen += p->len;
+          }
+          else
+          {
+            /* next octet in same pbuf */
+            msg_ptr++;
+          }
+        }
+        /* proceed to next sub-identifier */
+        ident++;
+      }
+      return ERR_OK;
+    }
+    p = p->next;
+  }
+  /* p == NULL, ofs >= plen */
+  return ERR_ARG;
+}
+
+/**
+ * Encodes raw data (octet string, opaque) into a pbuf chained ASN1 msg.
+ *
+ * @param p points to output pbuf to encode raw data into
+ * @param ofs points to the offset within the pbuf chain
+ * @param raw_len raw data length
+ * @param raw points raw data
+ * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode
+ */
+err_t
+snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw)
+{
+  u16_t plen, base;
+  u8_t *msg_ptr;
+
+  plen = 0;
+  while (p != NULL)
+  {
+    base = plen;
+    plen += p->len;
+    if (ofs < plen)
+    {
+      msg_ptr = (u8_t*)p->payload;
+      msg_ptr += ofs - base;
+
+      while (raw_len > 1)
+      {
+        /* copy raw_len - 1 octets */
+        raw_len--;
+        *msg_ptr = *raw;
+        raw++;
+        ofs += 1;
+        if (ofs >= plen)
+        {
+          /* next octet in next pbuf */
+          p = p->next;
+          if (p == NULL) { return ERR_ARG; }
+          msg_ptr = (u8_t*)p->payload;
+          plen += p->len;
+        }
+        else
+        {
+          /* next octet in same pbuf */
+          msg_ptr++;
+        }
+      }
+      if (raw_len > 0)
+      {
+        /* copy last or single octet */
+        *msg_ptr = *raw;
+      }
+      return ERR_OK;
+    }
+    p = p->next;
+  }
+  /* p == NULL, ofs >= plen */
+  return ERR_ARG;
+}
+
+#endif /* LWIP_SNMP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/mib2.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/mib2.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/mib2.c	(revision 164)
@@ -0,0 +1,4146 @@
+/**
+ * @file
+ * Management Information Base II (RFC1213) objects and functions.
+ *
+ * @note the object identifiers for this MIB-2 and private MIB tree
+ * must be kept in sorted ascending order. This to ensure correct getnext operation.
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/snmp.h"
+#include "lwip/netif.h"
+#include "lwip/ip.h"
+#include "lwip/ip_frag.h"
+#include "lwip/mem.h"
+#include "lwip/tcp_impl.h"
+#include "lwip/udp.h"
+#include "lwip/snmp_asn1.h"
+#include "lwip/snmp_structs.h"
+#include "lwip/sys.h"
+#include "netif/etharp.h"
+
+/**
+ * IANA assigned enterprise ID for lwIP is 26381
+ * @see http://www.iana.org/assignments/enterprise-numbers
+ *
+ * @note this enterprise ID is assigned to the lwIP project,
+ * all object identifiers living under this ID are assigned
+ * by the lwIP maintainers (contact Christiaan Simons)!
+ * @note don't change this define, use snmp_set_sysobjid()
+ *
+ * If you need to create your own private MIB you'll need
+ * to apply for your own enterprise ID with IANA:
+ * http://www.iana.org/numbers.html
+ */
+#define SNMP_ENTERPRISE_ID 26381
+#define SNMP_SYSOBJID_LEN 7
+#define SNMP_SYSOBJID {1, 3, 6, 1, 4, 1, SNMP_ENTERPRISE_ID}
+
+#ifndef SNMP_SYSSERVICES
+#define SNMP_SYSSERVICES ((1 << 6) | (1 << 3) | ((IP_FORWARD) << 2))
+#endif
+
+#ifndef SNMP_GET_SYSUPTIME
+#define SNMP_GET_SYSUPTIME(sysuptime)  (sysuptime = (sys_now() / 10))
+#endif
+
+static void system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void system_get_value(struct obj_def *od, u16_t len, void *value);
+static u8_t system_set_test(struct obj_def *od, u16_t len, void *value);
+static void system_set_value(struct obj_def *od, u16_t len, void *value);
+static void interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void interfaces_get_value(struct obj_def *od, u16_t len, void *value);
+static void ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void ifentry_get_value(struct obj_def *od, u16_t len, void *value);
+#if !SNMP_SAFE_REQUESTS
+static u8_t ifentry_set_test (struct obj_def *od, u16_t len, void *value);
+static void ifentry_set_value (struct obj_def *od, u16_t len, void *value);
+#endif /* SNMP_SAFE_REQUESTS */
+static void atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void atentry_get_value(struct obj_def *od, u16_t len, void *value);
+static void ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void ip_get_value(struct obj_def *od, u16_t len, void *value);
+static u8_t ip_set_test(struct obj_def *od, u16_t len, void *value);
+static void ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value);
+static void ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value);
+static void ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value);
+static void icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void icmp_get_value(struct obj_def *od, u16_t len, void *value);
+#if LWIP_TCP
+static void tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void tcp_get_value(struct obj_def *od, u16_t len, void *value);
+#ifdef THIS_SEEMS_UNUSED
+static void tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value);
+#endif
+#endif
+static void udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void udp_get_value(struct obj_def *od, u16_t len, void *value);
+static void udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void udpentry_get_value(struct obj_def *od, u16_t len, void *value);
+static void snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void snmp_get_value(struct obj_def *od, u16_t len, void *value);
+static u8_t snmp_set_test(struct obj_def *od, u16_t len, void *value);
+static void snmp_set_value(struct obj_def *od, u16_t len, void *value);
+
+
+/* snmp .1.3.6.1.2.1.11 */
+const mib_scalar_node snmp_scalar = {
+  &snmp_get_object_def,
+  &snmp_get_value,
+  &snmp_set_test,
+  &snmp_set_value,
+  MIB_NODE_SC,
+  0
+};
+const s32_t snmp_ids[28] = {
+  1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+  17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30
+};
+struct mib_node* const snmp_nodes[28] = {
+  (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
+  (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
+  (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
+  (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
+  (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
+  (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
+  (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
+  (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
+  (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
+  (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
+  (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
+  (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
+  (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
+  (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar
+};
+const struct mib_array_node snmp = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  28,
+  snmp_ids,
+  snmp_nodes
+};
+
+/* dot3 and EtherLike MIB not planned. (transmission .1.3.6.1.2.1.10) */
+/* historical (some say hysterical). (cmot .1.3.6.1.2.1.9) */
+/* lwIP has no EGP, thus may not implement it. (egp .1.3.6.1.2.1.8) */
+
+/* udp .1.3.6.1.2.1.7 */
+/** index root node for udpTable */
+struct mib_list_rootnode udp_root = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_LR,
+  0,
+  NULL,
+  NULL,
+  0
+};
+const s32_t udpentry_ids[2] = { 1, 2 };
+struct mib_node* const udpentry_nodes[2] = {
+  (struct mib_node*)&udp_root, (struct mib_node*)&udp_root,
+};
+const struct mib_array_node udpentry = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  2,
+  udpentry_ids,
+  udpentry_nodes
+};
+
+s32_t udptable_id = 1;
+struct mib_node* udptable_node = (struct mib_node*)&udpentry;
+struct mib_ram_array_node udptable = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_RA,
+  0,
+  &udptable_id,
+  &udptable_node
+};
+
+const mib_scalar_node udp_scalar = {
+  &udp_get_object_def,
+  &udp_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_SC,
+  0
+};
+const s32_t udp_ids[5] = { 1, 2, 3, 4, 5 };
+struct mib_node* const udp_nodes[5] = {
+  (struct mib_node*)&udp_scalar, (struct mib_node*)&udp_scalar,
+  (struct mib_node*)&udp_scalar, (struct mib_node*)&udp_scalar,
+  (struct mib_node*)&udptable
+};
+const struct mib_array_node udp = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  5,
+  udp_ids,
+  udp_nodes
+};
+
+/* tcp .1.3.6.1.2.1.6 */
+#if LWIP_TCP
+/* only if the TCP protocol is available may implement this group */
+/** index root node for tcpConnTable */
+struct mib_list_rootnode tcpconntree_root = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_LR,
+  0,
+  NULL,
+  NULL,
+  0
+};
+const s32_t tcpconnentry_ids[5] = { 1, 2, 3, 4, 5 };
+struct mib_node* const tcpconnentry_nodes[5] = {
+  (struct mib_node*)&tcpconntree_root, (struct mib_node*)&tcpconntree_root,
+  (struct mib_node*)&tcpconntree_root, (struct mib_node*)&tcpconntree_root,
+  (struct mib_node*)&tcpconntree_root
+};
+const struct mib_array_node tcpconnentry = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  5,
+  tcpconnentry_ids,
+  tcpconnentry_nodes
+};
+
+s32_t tcpconntable_id = 1;
+struct mib_node* tcpconntable_node = (struct mib_node*)&tcpconnentry;
+struct mib_ram_array_node tcpconntable = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_RA,
+/** @todo update maxlength when inserting / deleting from table
+   0 when table is empty, 1 when more than one entry */
+  0,
+  &tcpconntable_id,
+  &tcpconntable_node
+};
+
+const mib_scalar_node tcp_scalar = {
+  &tcp_get_object_def,
+  &tcp_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_SC,
+  0
+};
+const s32_t tcp_ids[15] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+struct mib_node* const tcp_nodes[15] = {
+  (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar,
+  (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar,
+  (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar,
+  (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar,
+  (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar,
+  (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar,
+  (struct mib_node*)&tcpconntable, (struct mib_node*)&tcp_scalar,
+  (struct mib_node*)&tcp_scalar
+};
+const struct mib_array_node tcp = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  15,
+  tcp_ids,
+  tcp_nodes
+};
+#endif
+
+/* icmp .1.3.6.1.2.1.5 */
+const mib_scalar_node icmp_scalar = {
+  &icmp_get_object_def,
+  &icmp_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_SC,
+  0
+};
+const s32_t icmp_ids[26] = { 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 };
+struct mib_node* const icmp_nodes[26] = {
+  (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
+  (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
+  (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
+  (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
+  (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
+  (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
+  (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
+  (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
+  (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
+  (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
+  (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
+  (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
+  (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar
+};
+const struct mib_array_node icmp = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  26,
+  icmp_ids,
+  icmp_nodes
+};
+
+/** index root node for ipNetToMediaTable */
+struct mib_list_rootnode ipntomtree_root = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_LR,
+  0,
+  NULL,
+  NULL,
+  0
+};
+const s32_t ipntomentry_ids[4] = { 1, 2, 3, 4 };
+struct mib_node* const ipntomentry_nodes[4] = {
+  (struct mib_node*)&ipntomtree_root, (struct mib_node*)&ipntomtree_root,
+  (struct mib_node*)&ipntomtree_root, (struct mib_node*)&ipntomtree_root
+};
+const struct mib_array_node ipntomentry = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  4,
+  ipntomentry_ids,
+  ipntomentry_nodes
+};
+
+s32_t ipntomtable_id = 1;
+struct mib_node* ipntomtable_node = (struct mib_node*)&ipntomentry;
+struct mib_ram_array_node ipntomtable = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_RA,
+  0,
+  &ipntomtable_id,
+  &ipntomtable_node
+};
+
+/** index root node for ipRouteTable */
+struct mib_list_rootnode iprtetree_root = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_LR,
+  0,
+  NULL,
+  NULL,
+  0
+};
+const s32_t iprteentry_ids[13] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
+struct mib_node* const iprteentry_nodes[13] = {
+  (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root,
+  (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root,
+  (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root,
+  (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root,
+  (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root,
+  (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root,
+  (struct mib_node*)&iprtetree_root
+};
+const struct mib_array_node iprteentry = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  13,
+  iprteentry_ids,
+  iprteentry_nodes
+};
+
+s32_t iprtetable_id = 1;
+struct mib_node* iprtetable_node = (struct mib_node*)&iprteentry;
+struct mib_ram_array_node iprtetable = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_RA,
+  0,
+  &iprtetable_id,
+  &iprtetable_node
+};
+
+/** index root node for ipAddrTable */
+struct mib_list_rootnode ipaddrtree_root = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_LR,
+  0,
+  NULL,
+  NULL,
+  0
+};
+const s32_t ipaddrentry_ids[5] = { 1, 2, 3, 4, 5 };
+struct mib_node* const ipaddrentry_nodes[5] = {
+  (struct mib_node*)&ipaddrtree_root,
+  (struct mib_node*)&ipaddrtree_root,
+  (struct mib_node*)&ipaddrtree_root,
+  (struct mib_node*)&ipaddrtree_root,
+  (struct mib_node*)&ipaddrtree_root
+};
+const struct mib_array_node ipaddrentry = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  5,
+  ipaddrentry_ids,
+  ipaddrentry_nodes
+};
+
+s32_t ipaddrtable_id = 1;
+struct mib_node* ipaddrtable_node = (struct mib_node*)&ipaddrentry;
+struct mib_ram_array_node ipaddrtable = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_RA,
+  0,
+  &ipaddrtable_id,
+  &ipaddrtable_node
+};
+
+/* ip .1.3.6.1.2.1.4 */
+const mib_scalar_node ip_scalar = {
+  &ip_get_object_def,
+  &ip_get_value,
+  &ip_set_test,
+  &noleafs_set_value,
+  MIB_NODE_SC,
+  0
+};
+const s32_t ip_ids[23] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };
+struct mib_node* const ip_nodes[23] = {
+  (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
+  (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
+  (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
+  (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
+  (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
+  (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
+  (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
+  (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
+  (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
+  (struct mib_node*)&ip_scalar, (struct mib_node*)&ipaddrtable,
+  (struct mib_node*)&iprtetable, (struct mib_node*)&ipntomtable,
+  (struct mib_node*)&ip_scalar
+};
+const struct mib_array_node mib2_ip = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  23,
+  ip_ids,
+  ip_nodes
+};
+
+/** index root node for atTable */
+struct mib_list_rootnode arptree_root = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_LR,
+  0,
+  NULL,
+  NULL,
+  0
+};
+const s32_t atentry_ids[3] = { 1, 2, 3 };
+struct mib_node* const atentry_nodes[3] = {
+  (struct mib_node*)&arptree_root,
+  (struct mib_node*)&arptree_root,
+  (struct mib_node*)&arptree_root
+};
+const struct mib_array_node atentry = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  3,
+  atentry_ids,
+  atentry_nodes
+};
+
+const s32_t attable_id = 1;
+struct mib_node* const attable_node = (struct mib_node*)&atentry;
+const struct mib_array_node attable = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  1,
+  &attable_id,
+  &attable_node
+};
+
+/* at .1.3.6.1.2.1.3 */
+s32_t at_id = 1;
+struct mib_node* mib2_at_node = (struct mib_node*)&attable;
+struct mib_ram_array_node at = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_RA,
+  0,
+  &at_id,
+  &mib2_at_node
+};
+
+/** index root node for ifTable */
+struct mib_list_rootnode iflist_root = {
+  &ifentry_get_object_def,
+  &ifentry_get_value,
+#if SNMP_SAFE_REQUESTS
+  &noleafs_set_test,
+  &noleafs_set_value,
+#else /* SNMP_SAFE_REQUESTS */
+  &ifentry_set_test,
+  &ifentry_set_value,
+#endif /* SNMP_SAFE_REQUESTS */
+  MIB_NODE_LR,
+  0,
+  NULL,
+  NULL,
+  0
+};
+const s32_t ifentry_ids[22] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 };
+struct mib_node* const ifentry_nodes[22] = {
+  (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
+  (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
+  (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
+  (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
+  (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
+  (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
+  (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
+  (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
+  (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
+  (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
+  (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root
+};
+const struct mib_array_node ifentry = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  22,
+  ifentry_ids,
+  ifentry_nodes
+};
+
+s32_t iftable_id = 1;
+struct mib_node* iftable_node = (struct mib_node*)&ifentry;
+struct mib_ram_array_node iftable = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_RA,
+  0,
+  &iftable_id,
+  &iftable_node
+};
+
+/* interfaces .1.3.6.1.2.1.2 */
+const mib_scalar_node interfaces_scalar = {
+  &interfaces_get_object_def,
+  &interfaces_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_SC,
+  0
+};
+const s32_t interfaces_ids[2] = { 1, 2 };
+struct mib_node* const interfaces_nodes[2] = {
+  (struct mib_node*)&interfaces_scalar, (struct mib_node*)&iftable
+};
+const struct mib_array_node interfaces = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  2,
+  interfaces_ids,
+  interfaces_nodes
+};
+
+
+/*             0 1 2 3 4 5 6 */
+/* system .1.3.6.1.2.1.1 */
+const mib_scalar_node sys_tem_scalar = {
+  &system_get_object_def,
+  &system_get_value,
+  &system_set_test,
+  &system_set_value,
+  MIB_NODE_SC,
+  0
+};
+const s32_t sys_tem_ids[7] = { 1, 2, 3, 4, 5, 6, 7 };
+struct mib_node* const sys_tem_nodes[7] = {
+  (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar,
+  (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar,
+  (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar,
+  (struct mib_node*)&sys_tem_scalar
+};
+/* work around name issue with 'sys_tem', some compiler(s?) seem to reserve 'system' */
+const struct mib_array_node sys_tem = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  7,
+  sys_tem_ids,
+  sys_tem_nodes
+};
+
+/* mib-2 .1.3.6.1.2.1 */
+#if LWIP_TCP
+#define MIB2_GROUPS 8
+#else
+#define MIB2_GROUPS 7
+#endif
+const s32_t mib2_ids[MIB2_GROUPS] =
+{
+  1,
+  2,
+  3,
+  4,
+  5,
+#if LWIP_TCP
+  6,
+#endif
+  7,
+  11
+};
+struct mib_node* const mib2_nodes[MIB2_GROUPS] = {
+  (struct mib_node*)&sys_tem,
+  (struct mib_node*)&interfaces,
+  (struct mib_node*)&at,
+  (struct mib_node*)&mib2_ip,
+  (struct mib_node*)&icmp,
+#if LWIP_TCP
+  (struct mib_node*)&tcp,
+#endif
+  (struct mib_node*)&udp,
+  (struct mib_node*)&snmp
+};
+
+const struct mib_array_node mib2 = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  MIB2_GROUPS,
+  mib2_ids,
+  mib2_nodes
+};
+
+/* mgmt .1.3.6.1.2 */
+const s32_t mgmt_ids[1] = { 1 };
+struct mib_node* const mgmt_nodes[1] = { (struct mib_node*)&mib2 };
+const struct mib_array_node mgmt = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  1,
+  mgmt_ids,
+  mgmt_nodes
+};
+
+/* internet .1.3.6.1 */
+#if SNMP_PRIVATE_MIB
+/* When using a private MIB, you have to create a file 'private_mib.h' that contains
+ * a 'struct mib_array_node mib_private' which contains your MIB. */
+s32_t internet_ids[2] = { 2, 4 };
+struct mib_node* const internet_nodes[2] = { (struct mib_node*)&mgmt, (struct mib_node*)&mib_private };
+const struct mib_array_node internet = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  2,
+  internet_ids,
+  internet_nodes
+};
+#else
+const s32_t internet_ids[1] = { 2 };
+struct mib_node* const internet_nodes[1] = { (struct mib_node*)&mgmt };
+const struct mib_array_node internet = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  &noleafs_set_test,
+  &noleafs_set_value,
+  MIB_NODE_AR,
+  1,
+  internet_ids,
+  internet_nodes
+};
+#endif
+
+/** mib-2.system.sysObjectID  */
+static struct snmp_obj_id sysobjid = {SNMP_SYSOBJID_LEN, SNMP_SYSOBJID};
+/** enterprise ID for generic TRAPs, .iso.org.dod.internet.mgmt.mib-2.snmp */
+static struct snmp_obj_id snmpgrp_id = {7,{1,3,6,1,2,1,11}};
+/** mib-2.system.sysServices */
+static const s32_t sysservices = SNMP_SYSSERVICES;
+
+/** mib-2.system.sysDescr */
+static const u8_t sysdescr_len_default = 4;
+static const u8_t sysdescr_default[] = "lwIP";
+static u8_t* sysdescr_len_ptr = (u8_t*)&sysdescr_len_default;
+static u8_t* sysdescr_ptr = (u8_t*)&sysdescr_default[0];
+/** mib-2.system.sysContact */
+static const u8_t syscontact_len_default = 0;
+static const u8_t syscontact_default[] = "";
+static u8_t* syscontact_len_ptr = (u8_t*)&syscontact_len_default;
+static u8_t* syscontact_ptr = (u8_t*)&syscontact_default[0];
+/** mib-2.system.sysName */
+static const u8_t sysname_len_default = 8;
+static const u8_t sysname_default[] = "FQDN-unk";
+static u8_t* sysname_len_ptr = (u8_t*)&sysname_len_default;
+static u8_t* sysname_ptr = (u8_t*)&sysname_default[0];
+/** mib-2.system.sysLocation */
+static const u8_t syslocation_len_default = 0;
+static const u8_t syslocation_default[] = "";
+static u8_t* syslocation_len_ptr = (u8_t*)&syslocation_len_default;
+static u8_t* syslocation_ptr = (u8_t*)&syslocation_default[0];
+/** mib-2.snmp.snmpEnableAuthenTraps */
+static const u8_t snmpenableauthentraps_default = 2; /* disabled */
+static u8_t* snmpenableauthentraps_ptr = (u8_t*)&snmpenableauthentraps_default;
+
+/** mib-2.interfaces.ifTable.ifEntry.ifSpecific (zeroDotZero) */
+static const struct snmp_obj_id ifspecific = {2, {0, 0}};
+/** mib-2.ip.ipRouteTable.ipRouteEntry.ipRouteInfo (zeroDotZero) */
+static const struct snmp_obj_id iprouteinfo = {2, {0, 0}};
+
+
+
+/* mib-2.system counter(s) */
+static u32_t sysuptime = 0;
+
+/* mib-2.ip counter(s) */
+static u32_t ipinreceives = 0,
+             ipinhdrerrors = 0,
+             ipinaddrerrors = 0,
+             ipforwdatagrams = 0,
+             ipinunknownprotos = 0,
+             ipindiscards = 0,
+             ipindelivers = 0,
+             ipoutrequests = 0,
+             ipoutdiscards = 0,
+             ipoutnoroutes = 0,
+             ipreasmreqds = 0,
+             ipreasmoks = 0,
+             ipreasmfails = 0,
+             ipfragoks = 0,
+             ipfragfails = 0,
+             ipfragcreates = 0,
+             iproutingdiscards = 0;
+/* mib-2.icmp counter(s) */
+static u32_t icmpinmsgs = 0,
+             icmpinerrors = 0,
+             icmpindestunreachs = 0,
+             icmpintimeexcds = 0,
+             icmpinparmprobs = 0,
+             icmpinsrcquenchs = 0,
+             icmpinredirects = 0,
+             icmpinechos = 0,
+             icmpinechoreps = 0,
+             icmpintimestamps = 0,
+             icmpintimestampreps = 0,
+             icmpinaddrmasks = 0,
+             icmpinaddrmaskreps = 0,
+             icmpoutmsgs = 0,
+             icmpouterrors = 0,
+             icmpoutdestunreachs = 0,
+             icmpouttimeexcds = 0,
+             icmpoutparmprobs = 0,
+             icmpoutsrcquenchs = 0,
+             icmpoutredirects = 0,
+             icmpoutechos = 0,
+             icmpoutechoreps = 0,
+             icmpouttimestamps = 0,
+             icmpouttimestampreps = 0,
+             icmpoutaddrmasks = 0,
+             icmpoutaddrmaskreps = 0;
+/* mib-2.tcp counter(s) */
+static u32_t tcpactiveopens = 0,
+             tcppassiveopens = 0,
+             tcpattemptfails = 0,
+             tcpestabresets = 0,
+             tcpinsegs = 0,
+             tcpoutsegs = 0,
+             tcpretranssegs = 0,
+             tcpinerrs = 0,
+             tcpoutrsts = 0;
+/* mib-2.udp counter(s) */
+static u32_t udpindatagrams = 0,
+             udpnoports = 0,
+             udpinerrors = 0,
+             udpoutdatagrams = 0;
+/* mib-2.snmp counter(s) */
+static u32_t snmpinpkts = 0,
+             snmpoutpkts = 0,
+             snmpinbadversions = 0,
+             snmpinbadcommunitynames = 0,
+             snmpinbadcommunityuses = 0,
+             snmpinasnparseerrs = 0,
+             snmpintoobigs = 0,
+             snmpinnosuchnames = 0,
+             snmpinbadvalues = 0,
+             snmpinreadonlys = 0,
+             snmpingenerrs = 0,
+             snmpintotalreqvars = 0,
+             snmpintotalsetvars = 0,
+             snmpingetrequests = 0,
+             snmpingetnexts = 0,
+             snmpinsetrequests = 0,
+             snmpingetresponses = 0,
+             snmpintraps = 0,
+             snmpouttoobigs = 0,
+             snmpoutnosuchnames = 0,
+             snmpoutbadvalues = 0,
+             snmpoutgenerrs = 0,
+             snmpoutgetrequests = 0,
+             snmpoutgetnexts = 0,
+             snmpoutsetrequests = 0,
+             snmpoutgetresponses = 0,
+             snmpouttraps = 0;
+
+
+
+/* prototypes of the following functions are in lwip/src/include/lwip/snmp.h */
+/**
+ * Copy octet string.
+ *
+ * @param dst points to destination
+ * @param src points to source
+ * @param n number of octets to copy.
+ */
+static void ocstrncpy(u8_t *dst, u8_t *src, u16_t n)
+{
+  u16_t i = n;
+  while (i > 0) {
+    i--;
+    *dst++ = *src++;
+  }
+}
+
+/**
+ * Copy object identifier (s32_t) array.
+ *
+ * @param dst points to destination
+ * @param src points to source
+ * @param n number of sub identifiers to copy.
+ */
+void objectidncpy(s32_t *dst, s32_t *src, u8_t n)
+{
+  u8_t i = n;
+  while(i > 0) {
+    i--;
+    *dst++ = *src++;
+  }
+}
+
+/**
+ * Initializes sysDescr pointers.
+ *
+ * @param str if non-NULL then copy str pointer
+ * @param len points to string length, excluding zero terminator
+ */
+void snmp_set_sysdesr(u8_t *str, u8_t *len)
+{
+  if (str != NULL)
+  {
+    sysdescr_ptr = str;
+    sysdescr_len_ptr = len;
+  }
+}
+
+void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid)
+{
+  *oid = &sysobjid;
+}
+
+/**
+ * Initializes sysObjectID value.
+ *
+ * @param oid points to stuct snmp_obj_id to copy
+ */
+void snmp_set_sysobjid(struct snmp_obj_id *oid)
+{
+  sysobjid = *oid;
+}
+
+/**
+ * Must be called at regular 10 msec interval from a timer interrupt
+ * or signal handler depending on your runtime environment.
+ */
+void snmp_inc_sysuptime(void)
+{
+  sysuptime++;
+}
+
+void snmp_add_sysuptime(u32_t value)
+{
+  sysuptime+=value;
+}
+
+void snmp_get_sysuptime(u32_t *value)
+{
+  SNMP_GET_SYSUPTIME(sysuptime);
+  *value = sysuptime;
+}
+
+/**
+ * Initializes sysContact pointers,
+ * e.g. ptrs to non-volatile memory external to lwIP.
+ *
+ * @param ocstr if non-NULL then copy str pointer
+ * @param ocstrlen points to string length, excluding zero terminator
+ */
+void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen)
+{
+  if (ocstr != NULL)
+  {
+    syscontact_ptr = ocstr;
+    syscontact_len_ptr = ocstrlen;
+  }
+}
+
+/**
+ * Initializes sysName pointers,
+ * e.g. ptrs to non-volatile memory external to lwIP.
+ *
+ * @param ocstr if non-NULL then copy str pointer
+ * @param ocstrlen points to string length, excluding zero terminator
+ */
+void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen)
+{
+  if (ocstr != NULL)
+  {
+    sysname_ptr = ocstr;
+    sysname_len_ptr = ocstrlen;
+  }
+}
+
+/**
+ * Initializes sysLocation pointers,
+ * e.g. ptrs to non-volatile memory external to lwIP.
+ *
+ * @param ocstr if non-NULL then copy str pointer
+ * @param ocstrlen points to string length, excluding zero terminator
+ */
+void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen)
+{
+  if (ocstr != NULL)
+  {
+    syslocation_ptr = ocstr;
+    syslocation_len_ptr = ocstrlen;
+  }
+}
+
+
+void snmp_add_ifinoctets(struct netif *ni, u32_t value)
+{
+  ni->ifinoctets += value;
+}
+
+void snmp_inc_ifinucastpkts(struct netif *ni)
+{
+  (ni->ifinucastpkts)++;
+}
+
+void snmp_inc_ifinnucastpkts(struct netif *ni)
+{
+  (ni->ifinnucastpkts)++;
+}
+
+void snmp_inc_ifindiscards(struct netif *ni)
+{
+  (ni->ifindiscards)++;
+}
+
+void snmp_add_ifoutoctets(struct netif *ni, u32_t value)
+{
+  ni->ifoutoctets += value;
+}
+
+void snmp_inc_ifoutucastpkts(struct netif *ni)
+{
+  (ni->ifoutucastpkts)++;
+}
+
+void snmp_inc_ifoutnucastpkts(struct netif *ni)
+{
+  (ni->ifoutnucastpkts)++;
+}
+
+void snmp_inc_ifoutdiscards(struct netif *ni)
+{
+  (ni->ifoutdiscards)++;
+}
+
+void snmp_inc_iflist(void)
+{
+  struct mib_list_node *if_node = NULL;
+
+  snmp_mib_node_insert(&iflist_root, iflist_root.count + 1, &if_node);
+  /* enable getnext traversal on filled table */
+  iftable.maxlength = 1;
+}
+
+void snmp_dec_iflist(void)
+{
+  snmp_mib_node_delete(&iflist_root, iflist_root.tail);
+  /* disable getnext traversal on empty table */
+  if(iflist_root.count == 0) iftable.maxlength = 0;
+}
+
+/**
+ * Inserts ARP table indexes (.xIfIndex.xNetAddress)
+ * into arp table index trees (both atTable and ipNetToMediaTable).
+ */
+void snmp_insert_arpidx_tree(struct netif *ni, ip_addr_t *ip)
+{
+  struct mib_list_rootnode *at_rn;
+  struct mib_list_node *at_node;
+  s32_t arpidx[5];
+  u8_t level, tree;
+
+  LWIP_ASSERT("ni != NULL", ni != NULL);
+  snmp_netiftoifindex(ni, &arpidx[0]);
+  snmp_iptooid(ip, &arpidx[1]);
+
+  for (tree = 0; tree < 2; tree++)
+  {
+    if (tree == 0)
+    {
+      at_rn = &arptree_root;
+    }
+    else
+    {
+      at_rn = &ipntomtree_root;
+    }
+    for (level = 0; level < 5; level++)
+    {
+      at_node = NULL;
+      snmp_mib_node_insert(at_rn, arpidx[level], &at_node);
+      if ((level != 4) && (at_node != NULL))
+      {
+        if (at_node->nptr == NULL)
+        {
+          at_rn = snmp_mib_lrn_alloc();
+          at_node->nptr = (struct mib_node*)at_rn;
+          if (at_rn != NULL)
+          {
+            if (level == 3)
+            {
+              if (tree == 0)
+              {
+                at_rn->get_object_def = atentry_get_object_def;
+                at_rn->get_value = atentry_get_value;
+              }
+              else
+              {
+                at_rn->get_object_def = ip_ntomentry_get_object_def;
+                at_rn->get_value = ip_ntomentry_get_value;
+              }
+              at_rn->set_test = noleafs_set_test;
+              at_rn->set_value = noleafs_set_value;
+            }
+          }
+          else
+          {
+            /* at_rn == NULL, malloc failure */
+            LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_arpidx_tree() insert failed, mem full"));
+            break;
+          }
+        }
+        else
+        {
+          at_rn = (struct mib_list_rootnode*)at_node->nptr;
+        }
+      }
+    }
+  }
+  /* enable getnext traversal on filled tables */
+  at.maxlength = 1;
+  ipntomtable.maxlength = 1;
+}
+
+/**
+ * Removes ARP table indexes (.xIfIndex.xNetAddress)
+ * from arp table index trees.
+ */
+void snmp_delete_arpidx_tree(struct netif *ni, ip_addr_t *ip)
+{
+  struct mib_list_rootnode *at_rn, *next, *del_rn[5];
+  struct mib_list_node *at_n, *del_n[5];
+  s32_t arpidx[5];
+  u8_t fc, tree, level, del_cnt;
+
+  snmp_netiftoifindex(ni, &arpidx[0]);
+  snmp_iptooid(ip, &arpidx[1]);
+
+  for (tree = 0; tree < 2; tree++)
+  {
+    /* mark nodes for deletion */
+    if (tree == 0)
+    {
+      at_rn = &arptree_root;
+    }
+    else
+    {
+      at_rn = &ipntomtree_root;
+    }
+    level = 0;
+    del_cnt = 0;
+    while ((level < 5) && (at_rn != NULL))
+    {
+      fc = snmp_mib_node_find(at_rn, arpidx[level], &at_n);
+      if (fc == 0)
+      {
+        /* arpidx[level] does not exist */
+        del_cnt = 0;
+        at_rn = NULL;
+      }
+      else if (fc == 1)
+      {
+        del_rn[del_cnt] = at_rn;
+        del_n[del_cnt] = at_n;
+        del_cnt++;
+        at_rn = (struct mib_list_rootnode*)(at_n->nptr);
+      }
+      else if (fc == 2)
+      {
+        /* reset delete (2 or more childs) */
+        del_cnt = 0;
+        at_rn = (struct mib_list_rootnode*)(at_n->nptr);
+      }
+      level++;
+    }
+    /* delete marked index nodes */
+    while (del_cnt > 0)
+    {
+      del_cnt--;
+
+      at_rn = del_rn[del_cnt];
+      at_n = del_n[del_cnt];
+
+      next = snmp_mib_node_delete(at_rn, at_n);
+      if (next != NULL)
+      {
+        LWIP_ASSERT("next_count == 0",next->count == 0);
+        snmp_mib_lrn_free(next);
+      }
+    }
+  }
+  /* disable getnext traversal on empty tables */
+  if(arptree_root.count == 0) at.maxlength = 0;
+  if(ipntomtree_root.count == 0) ipntomtable.maxlength = 0;
+}
+
+void snmp_inc_ipinreceives(void)
+{
+  ipinreceives++;
+}
+
+void snmp_inc_ipinhdrerrors(void)
+{
+  ipinhdrerrors++;
+}
+
+void snmp_inc_ipinaddrerrors(void)
+{
+  ipinaddrerrors++;
+}
+
+void snmp_inc_ipforwdatagrams(void)
+{
+  ipforwdatagrams++;
+}
+
+void snmp_inc_ipinunknownprotos(void)
+{
+  ipinunknownprotos++;
+}
+
+void snmp_inc_ipindiscards(void)
+{
+  ipindiscards++;
+}
+
+void snmp_inc_ipindelivers(void)
+{
+  ipindelivers++;
+}
+
+void snmp_inc_ipoutrequests(void)
+{
+  ipoutrequests++;
+}
+
+void snmp_inc_ipoutdiscards(void)
+{
+  ipoutdiscards++;
+}
+
+void snmp_inc_ipoutnoroutes(void)
+{
+  ipoutnoroutes++;
+}
+
+void snmp_inc_ipreasmreqds(void)
+{
+  ipreasmreqds++;
+}
+
+void snmp_inc_ipreasmoks(void)
+{
+  ipreasmoks++;
+}
+
+void snmp_inc_ipreasmfails(void)
+{
+  ipreasmfails++;
+}
+
+void snmp_inc_ipfragoks(void)
+{
+  ipfragoks++;
+}
+
+void snmp_inc_ipfragfails(void)
+{
+  ipfragfails++;
+}
+
+void snmp_inc_ipfragcreates(void)
+{
+  ipfragcreates++;
+}
+
+void snmp_inc_iproutingdiscards(void)
+{
+  iproutingdiscards++;
+}
+
+/**
+ * Inserts ipAddrTable indexes (.ipAdEntAddr)
+ * into index tree.
+ */
+void snmp_insert_ipaddridx_tree(struct netif *ni)
+{
+  struct mib_list_rootnode *ipa_rn;
+  struct mib_list_node *ipa_node;
+  s32_t ipaddridx[4];
+  u8_t level;
+
+  LWIP_ASSERT("ni != NULL", ni != NULL);
+  snmp_iptooid(&ni->ip_addr, &ipaddridx[0]);
+
+  level = 0;
+  ipa_rn = &ipaddrtree_root;
+  while (level < 4)
+  {
+    ipa_node = NULL;
+    snmp_mib_node_insert(ipa_rn, ipaddridx[level], &ipa_node);
+    if ((level != 3) && (ipa_node != NULL))
+    {
+      if (ipa_node->nptr == NULL)
+      {
+        ipa_rn = snmp_mib_lrn_alloc();
+        ipa_node->nptr = (struct mib_node*)ipa_rn;
+        if (ipa_rn != NULL)
+        {
+          if (level == 2)
+          {
+            ipa_rn->get_object_def = ip_addrentry_get_object_def;
+            ipa_rn->get_value = ip_addrentry_get_value;
+            ipa_rn->set_test = noleafs_set_test;
+            ipa_rn->set_value = noleafs_set_value;
+          }
+        }
+        else
+        {
+          /* ipa_rn == NULL, malloc failure */
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_ipaddridx_tree() insert failed, mem full"));
+          break;
+        }
+      }
+      else
+      {
+        ipa_rn = (struct mib_list_rootnode*)ipa_node->nptr;
+      }
+    }
+    level++;
+  }
+  /* enable getnext traversal on filled table */
+  ipaddrtable.maxlength = 1;
+}
+
+/**
+ * Removes ipAddrTable indexes (.ipAdEntAddr)
+ * from index tree.
+ */
+void snmp_delete_ipaddridx_tree(struct netif *ni)
+{
+  struct mib_list_rootnode *ipa_rn, *next, *del_rn[4];
+  struct mib_list_node *ipa_n, *del_n[4];
+  s32_t ipaddridx[4];
+  u8_t fc, level, del_cnt;
+
+  LWIP_ASSERT("ni != NULL", ni != NULL);
+  snmp_iptooid(&ni->ip_addr, &ipaddridx[0]);
+
+  /* mark nodes for deletion */
+  level = 0;
+  del_cnt = 0;
+  ipa_rn = &ipaddrtree_root;
+  while ((level < 4) && (ipa_rn != NULL))
+  {
+    fc = snmp_mib_node_find(ipa_rn, ipaddridx[level], &ipa_n);
+    if (fc == 0)
+    {
+      /* ipaddridx[level] does not exist */
+      del_cnt = 0;
+      ipa_rn = NULL;
+    }
+    else if (fc == 1)
+    {
+      del_rn[del_cnt] = ipa_rn;
+      del_n[del_cnt] = ipa_n;
+      del_cnt++;
+      ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr);
+    }
+    else if (fc == 2)
+    {
+      /* reset delete (2 or more childs) */
+      del_cnt = 0;
+      ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr);
+    }
+    level++;
+  }
+  /* delete marked index nodes */
+  while (del_cnt > 0)
+  {
+    del_cnt--;
+
+    ipa_rn = del_rn[del_cnt];
+    ipa_n = del_n[del_cnt];
+
+    next = snmp_mib_node_delete(ipa_rn, ipa_n);
+    if (next != NULL)
+    {
+      LWIP_ASSERT("next_count == 0",next->count == 0);
+      snmp_mib_lrn_free(next);
+    }
+  }
+  /* disable getnext traversal on empty table */
+  if (ipaddrtree_root.count == 0) ipaddrtable.maxlength = 0;
+}
+
+/**
+ * Inserts ipRouteTable indexes (.ipRouteDest)
+ * into index tree.
+ *
+ * @param dflt non-zero for the default rte, zero for network rte
+ * @param ni points to network interface for this rte
+ *
+ * @todo record sysuptime for _this_ route when it is installed
+ *   (needed for ipRouteAge) in the netif.
+ */
+void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni)
+{
+  u8_t insert = 0;
+  ip_addr_t dst;
+
+  if (dflt != 0)
+  {
+    /* the default route 0.0.0.0 */
+    ip_addr_set_any(&dst);
+    insert = 1;
+  }
+  else
+  {
+    /* route to the network address */
+    ip_addr_get_network(&dst, &ni->ip_addr, &ni->netmask);
+    /* exclude 0.0.0.0 network (reserved for default rte) */
+    if (!ip_addr_isany(&dst)) {
+      insert = 1;
+    }
+  }
+  if (insert)
+  {
+    struct mib_list_rootnode *iprte_rn;
+    struct mib_list_node *iprte_node;
+    s32_t iprteidx[4];
+    u8_t level;
+
+    snmp_iptooid(&dst, &iprteidx[0]);
+    level = 0;
+    iprte_rn = &iprtetree_root;
+    while (level < 4)
+    {
+      iprte_node = NULL;
+      snmp_mib_node_insert(iprte_rn, iprteidx[level], &iprte_node);
+      if ((level != 3) && (iprte_node != NULL))
+      {
+        if (iprte_node->nptr == NULL)
+        {
+          iprte_rn = snmp_mib_lrn_alloc();
+          iprte_node->nptr = (struct mib_node*)iprte_rn;
+          if (iprte_rn != NULL)
+          {
+            if (level == 2)
+            {
+              iprte_rn->get_object_def = ip_rteentry_get_object_def;
+              iprte_rn->get_value = ip_rteentry_get_value;
+              iprte_rn->set_test = noleafs_set_test;
+              iprte_rn->set_value = noleafs_set_value;
+            }
+          }
+          else
+          {
+            /* iprte_rn == NULL, malloc failure */
+            LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_iprteidx_tree() insert failed, mem full"));
+            break;
+          }
+        }
+        else
+        {
+          iprte_rn = (struct mib_list_rootnode*)iprte_node->nptr;
+        }
+      }
+      level++;
+    }
+  }
+  /* enable getnext traversal on filled table */
+  iprtetable.maxlength = 1;
+}
+
+/**
+ * Removes ipRouteTable indexes (.ipRouteDest)
+ * from index tree.
+ *
+ * @param dflt non-zero for the default rte, zero for network rte
+ * @param ni points to network interface for this rte or NULL
+ *   for default route to be removed.
+ */
+void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni)
+{
+  u8_t del = 0;
+  ip_addr_t dst;
+
+  if (dflt != 0)
+  {
+    /* the default route 0.0.0.0 */
+    ip_addr_set_any(&dst);
+    del = 1;
+  }
+  else
+  {
+    /* route to the network address */
+    ip_addr_get_network(&dst, &ni->ip_addr, &ni->netmask);
+    /* exclude 0.0.0.0 network (reserved for default rte) */
+    if (!ip_addr_isany(&dst)) {
+      del = 1;
+    }
+  }
+  if (del)
+  {
+    struct mib_list_rootnode *iprte_rn, *next, *del_rn[4];
+    struct mib_list_node *iprte_n, *del_n[4];
+    s32_t iprteidx[4];
+    u8_t fc, level, del_cnt;
+
+    snmp_iptooid(&dst, &iprteidx[0]);
+    /* mark nodes for deletion */
+    level = 0;
+    del_cnt = 0;
+    iprte_rn = &iprtetree_root;
+    while ((level < 4) && (iprte_rn != NULL))
+    {
+      fc = snmp_mib_node_find(iprte_rn, iprteidx[level], &iprte_n);
+      if (fc == 0)
+      {
+        /* iprteidx[level] does not exist */
+        del_cnt = 0;
+        iprte_rn = NULL;
+      }
+      else if (fc == 1)
+      {
+        del_rn[del_cnt] = iprte_rn;
+        del_n[del_cnt] = iprte_n;
+        del_cnt++;
+        iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr);
+      }
+      else if (fc == 2)
+      {
+        /* reset delete (2 or more childs) */
+        del_cnt = 0;
+        iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr);
+      }
+      level++;
+    }
+    /* delete marked index nodes */
+    while (del_cnt > 0)
+    {
+      del_cnt--;
+
+      iprte_rn = del_rn[del_cnt];
+      iprte_n = del_n[del_cnt];
+
+      next = snmp_mib_node_delete(iprte_rn, iprte_n);
+      if (next != NULL)
+      {
+        LWIP_ASSERT("next_count == 0",next->count == 0);
+        snmp_mib_lrn_free(next);
+      }
+    }
+  }
+  /* disable getnext traversal on empty table */
+  if (iprtetree_root.count == 0) iprtetable.maxlength = 0;
+}
+
+
+void snmp_inc_icmpinmsgs(void)
+{
+  icmpinmsgs++;
+}
+
+void snmp_inc_icmpinerrors(void)
+{
+  icmpinerrors++;
+}
+
+void snmp_inc_icmpindestunreachs(void)
+{
+  icmpindestunreachs++;
+}
+
+void snmp_inc_icmpintimeexcds(void)
+{
+  icmpintimeexcds++;
+}
+
+void snmp_inc_icmpinparmprobs(void)
+{
+  icmpinparmprobs++;
+}
+
+void snmp_inc_icmpinsrcquenchs(void)
+{
+  icmpinsrcquenchs++;
+}
+
+void snmp_inc_icmpinredirects(void)
+{
+  icmpinredirects++;
+}
+
+void snmp_inc_icmpinechos(void)
+{
+  icmpinechos++;
+}
+
+void snmp_inc_icmpinechoreps(void)
+{
+  icmpinechoreps++;
+}
+
+void snmp_inc_icmpintimestamps(void)
+{
+  icmpintimestamps++;
+}
+
+void snmp_inc_icmpintimestampreps(void)
+{
+  icmpintimestampreps++;
+}
+
+void snmp_inc_icmpinaddrmasks(void)
+{
+  icmpinaddrmasks++;
+}
+
+void snmp_inc_icmpinaddrmaskreps(void)
+{
+  icmpinaddrmaskreps++;
+}
+
+void snmp_inc_icmpoutmsgs(void)
+{
+  icmpoutmsgs++;
+}
+
+void snmp_inc_icmpouterrors(void)
+{
+  icmpouterrors++;
+}
+
+void snmp_inc_icmpoutdestunreachs(void)
+{
+  icmpoutdestunreachs++;
+}
+
+void snmp_inc_icmpouttimeexcds(void)
+{
+  icmpouttimeexcds++;
+}
+
+void snmp_inc_icmpoutparmprobs(void)
+{
+  icmpoutparmprobs++;
+}
+
+void snmp_inc_icmpoutsrcquenchs(void)
+{
+  icmpoutsrcquenchs++;
+}
+
+void snmp_inc_icmpoutredirects(void)
+{
+  icmpoutredirects++;
+}
+
+void snmp_inc_icmpoutechos(void)
+{
+  icmpoutechos++;
+}
+
+void snmp_inc_icmpoutechoreps(void)
+{
+  icmpoutechoreps++;
+}
+
+void snmp_inc_icmpouttimestamps(void)
+{
+  icmpouttimestamps++;
+}
+
+void snmp_inc_icmpouttimestampreps(void)
+{
+  icmpouttimestampreps++;
+}
+
+void snmp_inc_icmpoutaddrmasks(void)
+{
+  icmpoutaddrmasks++;
+}
+
+void snmp_inc_icmpoutaddrmaskreps(void)
+{
+  icmpoutaddrmaskreps++;
+}
+
+void snmp_inc_tcpactiveopens(void)
+{
+  tcpactiveopens++;
+}
+
+void snmp_inc_tcppassiveopens(void)
+{
+  tcppassiveopens++;
+}
+
+void snmp_inc_tcpattemptfails(void)
+{
+  tcpattemptfails++;
+}
+
+void snmp_inc_tcpestabresets(void)
+{
+  tcpestabresets++;
+}
+
+void snmp_inc_tcpinsegs(void)
+{
+  tcpinsegs++;
+}
+
+void snmp_inc_tcpoutsegs(void)
+{
+  tcpoutsegs++;
+}
+
+void snmp_inc_tcpretranssegs(void)
+{
+  tcpretranssegs++;
+}
+
+void snmp_inc_tcpinerrs(void)
+{
+  tcpinerrs++;
+}
+
+void snmp_inc_tcpoutrsts(void)
+{
+  tcpoutrsts++;
+}
+
+void snmp_inc_udpindatagrams(void)
+{
+  udpindatagrams++;
+}
+
+void snmp_inc_udpnoports(void)
+{
+  udpnoports++;
+}
+
+void snmp_inc_udpinerrors(void)
+{
+  udpinerrors++;
+}
+
+void snmp_inc_udpoutdatagrams(void)
+{
+  udpoutdatagrams++;
+}
+
+/**
+ * Inserts udpTable indexes (.udpLocalAddress.udpLocalPort)
+ * into index tree.
+ */
+void snmp_insert_udpidx_tree(struct udp_pcb *pcb)
+{
+  struct mib_list_rootnode *udp_rn;
+  struct mib_list_node *udp_node;
+  s32_t udpidx[5];
+  u8_t level;
+
+  LWIP_ASSERT("pcb != NULL", pcb != NULL);
+  snmp_iptooid(&pcb->local_ip, &udpidx[0]);
+  udpidx[4] = pcb->local_port;
+
+  udp_rn = &udp_root;
+  for (level = 0; level < 5; level++)
+  {
+    udp_node = NULL;
+    snmp_mib_node_insert(udp_rn, udpidx[level], &udp_node);
+    if ((level != 4) && (udp_node != NULL))
+    {
+      if (udp_node->nptr == NULL)
+      {
+        udp_rn = snmp_mib_lrn_alloc();
+        udp_node->nptr = (struct mib_node*)udp_rn;
+        if (udp_rn != NULL)
+        {
+          if (level == 3)
+          {
+            udp_rn->get_object_def = udpentry_get_object_def;
+            udp_rn->get_value = udpentry_get_value;
+            udp_rn->set_test = noleafs_set_test;
+            udp_rn->set_value = noleafs_set_value;
+          }
+        }
+        else
+        {
+          /* udp_rn == NULL, malloc failure */
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_udpidx_tree() insert failed, mem full"));
+          break;
+        }
+      }
+      else
+      {
+        udp_rn = (struct mib_list_rootnode*)udp_node->nptr;
+      }
+    }
+  }
+  udptable.maxlength = 1;
+}
+
+/**
+ * Removes udpTable indexes (.udpLocalAddress.udpLocalPort)
+ * from index tree.
+ */
+void snmp_delete_udpidx_tree(struct udp_pcb *pcb)
+{
+  struct udp_pcb *npcb;
+  struct mib_list_rootnode *udp_rn, *next, *del_rn[5];
+  struct mib_list_node *udp_n, *del_n[5];
+  s32_t udpidx[5];
+  u8_t bindings, fc, level, del_cnt;
+
+  LWIP_ASSERT("pcb != NULL", pcb != NULL);
+  snmp_iptooid(&pcb->local_ip, &udpidx[0]);
+  udpidx[4] = pcb->local_port;
+
+  /* count PCBs for a given binding
+     (e.g. when reusing ports or for temp output PCBs) */
+  bindings = 0;
+  npcb = udp_pcbs;
+  while ((npcb != NULL))
+  {
+    if (ip_addr_cmp(&npcb->local_ip, &pcb->local_ip) &&
+        (npcb->local_port == udpidx[4]))
+    {
+      bindings++;
+    }
+    npcb = npcb->next;
+  }
+  if (bindings == 1)
+  {
+    /* selectively remove */
+    /* mark nodes for deletion */
+    level = 0;
+    del_cnt = 0;
+    udp_rn = &udp_root;
+    while ((level < 5) && (udp_rn != NULL))
+    {
+      fc = snmp_mib_node_find(udp_rn, udpidx[level], &udp_n);
+      if (fc == 0)
+      {
+        /* udpidx[level] does not exist */
+        del_cnt = 0;
+        udp_rn = NULL;
+      }
+      else if (fc == 1)
+      {
+        del_rn[del_cnt] = udp_rn;
+        del_n[del_cnt] = udp_n;
+        del_cnt++;
+        udp_rn = (struct mib_list_rootnode*)(udp_n->nptr);
+      }
+      else if (fc == 2)
+      {
+        /* reset delete (2 or more childs) */
+        del_cnt = 0;
+        udp_rn = (struct mib_list_rootnode*)(udp_n->nptr);
+      }
+      level++;
+    }
+    /* delete marked index nodes */
+    while (del_cnt > 0)
+    {
+      del_cnt--;
+
+      udp_rn = del_rn[del_cnt];
+      udp_n = del_n[del_cnt];
+
+      next = snmp_mib_node_delete(udp_rn, udp_n);
+      if (next != NULL)
+      {
+        LWIP_ASSERT("next_count == 0",next->count == 0);
+        snmp_mib_lrn_free(next);
+      }
+    }
+  }
+  /* disable getnext traversal on empty table */
+  if (udp_root.count == 0) udptable.maxlength = 0;
+}
+
+
+void snmp_inc_snmpinpkts(void)
+{
+  snmpinpkts++;
+}
+
+void snmp_inc_snmpoutpkts(void)
+{
+  snmpoutpkts++;
+}
+
+void snmp_inc_snmpinbadversions(void)
+{
+  snmpinbadversions++;
+}
+
+void snmp_inc_snmpinbadcommunitynames(void)
+{
+  snmpinbadcommunitynames++;
+}
+
+void snmp_inc_snmpinbadcommunityuses(void)
+{
+  snmpinbadcommunityuses++;
+}
+
+void snmp_inc_snmpinasnparseerrs(void)
+{
+  snmpinasnparseerrs++;
+}
+
+void snmp_inc_snmpintoobigs(void)
+{
+  snmpintoobigs++;
+}
+
+void snmp_inc_snmpinnosuchnames(void)
+{
+  snmpinnosuchnames++;
+}
+
+void snmp_inc_snmpinbadvalues(void)
+{
+  snmpinbadvalues++;
+}
+
+void snmp_inc_snmpinreadonlys(void)
+{
+  snmpinreadonlys++;
+}
+
+void snmp_inc_snmpingenerrs(void)
+{
+  snmpingenerrs++;
+}
+
+void snmp_add_snmpintotalreqvars(u8_t value)
+{
+  snmpintotalreqvars += value;
+}
+
+void snmp_add_snmpintotalsetvars(u8_t value)
+{
+  snmpintotalsetvars += value;
+}
+
+void snmp_inc_snmpingetrequests(void)
+{
+  snmpingetrequests++;
+}
+
+void snmp_inc_snmpingetnexts(void)
+{
+  snmpingetnexts++;
+}
+
+void snmp_inc_snmpinsetrequests(void)
+{
+  snmpinsetrequests++;
+}
+
+void snmp_inc_snmpingetresponses(void)
+{
+  snmpingetresponses++;
+}
+
+void snmp_inc_snmpintraps(void)
+{
+  snmpintraps++;
+}
+
+void snmp_inc_snmpouttoobigs(void)
+{
+  snmpouttoobigs++;
+}
+
+void snmp_inc_snmpoutnosuchnames(void)
+{
+  snmpoutnosuchnames++;
+}
+
+void snmp_inc_snmpoutbadvalues(void)
+{
+  snmpoutbadvalues++;
+}
+
+void snmp_inc_snmpoutgenerrs(void)
+{
+  snmpoutgenerrs++;
+}
+
+void snmp_inc_snmpoutgetrequests(void)
+{
+  snmpoutgetrequests++;
+}
+
+void snmp_inc_snmpoutgetnexts(void)
+{
+  snmpoutgetnexts++;
+}
+
+void snmp_inc_snmpoutsetrequests(void)
+{
+  snmpoutsetrequests++;
+}
+
+void snmp_inc_snmpoutgetresponses(void)
+{
+  snmpoutgetresponses++;
+}
+
+void snmp_inc_snmpouttraps(void)
+{
+  snmpouttraps++;
+}
+
+void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid)
+{
+  *oid = &snmpgrp_id;
+}
+
+void snmp_set_snmpenableauthentraps(u8_t *value)
+{
+  if (value != NULL)
+  {
+    snmpenableauthentraps_ptr = value;
+  }
+}
+
+void snmp_get_snmpenableauthentraps(u8_t *value)
+{
+  *value = *snmpenableauthentraps_ptr;
+}
+
+void
+noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  LWIP_UNUSED_ARG(ident_len);
+  LWIP_UNUSED_ARG(ident);
+  od->instance = MIB_OBJECT_NONE;
+}
+
+void
+noleafs_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  LWIP_UNUSED_ARG(od);
+  LWIP_UNUSED_ARG(len);
+  LWIP_UNUSED_ARG(value);
+}
+
+u8_t
+noleafs_set_test(struct obj_def *od, u16_t len, void *value)
+{
+  LWIP_UNUSED_ARG(od);
+  LWIP_UNUSED_ARG(len);
+  LWIP_UNUSED_ARG(value);
+  /* can't set */
+  return 0;
+}
+
+void
+noleafs_set_value(struct obj_def *od, u16_t len, void *value)
+{
+  LWIP_UNUSED_ARG(od);
+  LWIP_UNUSED_ARG(len);
+  LWIP_UNUSED_ARG(value);
+}
+
+
+/**
+ * Returns systems object definitions.
+ *
+ * @param ident_len the address length (2)
+ * @param ident points to objectname.0 (object id trailer)
+ * @param od points to object definition.
+ */
+static void
+system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  u8_t id;
+
+  /* return to object name, adding index depth (1) */
+  ident_len += 1;
+  ident -= 1;
+  if (ident_len == 2)
+  {
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
+    id = (u8_t)ident[0];
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def system.%"U16_F".0\n",(u16_t)id));
+    switch (id)
+    {
+      case 1: /* sysDescr */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
+        od->v_len = *sysdescr_len_ptr;
+        break;
+      case 2: /* sysObjectID */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID);
+        od->v_len = sysobjid.len * sizeof(s32_t);
+        break;
+      case 3: /* sysUpTime */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS);
+        od->v_len = sizeof(u32_t);
+        break;
+      case 4: /* sysContact */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
+        od->v_len = *syscontact_len_ptr;
+        break;
+      case 5: /* sysName */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
+        od->v_len = *sysname_len_ptr;
+        break;
+      case 6: /* sysLocation */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
+        od->v_len = *syslocation_len_ptr;
+        break;
+      case 7: /* sysServices */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no such object\n"));
+        od->instance = MIB_OBJECT_NONE;
+        break;
+    };
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no scalar\n"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+/**
+ * Returns system object value.
+ *
+ * @param ident_len the address length (2)
+ * @param ident points to objectname.0 (object id trailer)
+ * @param len return value space (in bytes)
+ * @param value points to (varbind) space to copy value into.
+ */
+static void
+system_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u8_t id;
+
+  LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+  id = (u8_t)od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 1: /* sysDescr */
+      ocstrncpy((u8_t*)value, sysdescr_ptr, len);
+      break;
+    case 2: /* sysObjectID */
+      objectidncpy((s32_t*)value, (s32_t*)sysobjid.id, (u8_t)(len / sizeof(s32_t)));
+      break;
+    case 3: /* sysUpTime */
+      {
+        snmp_get_sysuptime((u32_t*)value);
+      }
+      break;
+    case 4: /* sysContact */
+      ocstrncpy((u8_t*)value, syscontact_ptr, len);
+      break;
+    case 5: /* sysName */
+      ocstrncpy((u8_t*)value, sysname_ptr, len);
+      break;
+    case 6: /* sysLocation */
+      ocstrncpy((u8_t*)value, syslocation_ptr, len);
+      break;
+    case 7: /* sysServices */
+      {
+        s32_t *sint_ptr = (s32_t*)value;
+        *sint_ptr = sysservices;
+      }
+      break;
+  };
+}
+
+static u8_t
+system_set_test(struct obj_def *od, u16_t len, void *value)
+{
+  u8_t id, set_ok;
+
+  LWIP_UNUSED_ARG(value);
+  set_ok = 0;
+  LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+  id = (u8_t)od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 4: /* sysContact */
+      if ((syscontact_ptr != syscontact_default) &&
+          (len <= 255))
+      {
+        set_ok = 1;
+      }
+      break;
+    case 5: /* sysName */
+      if ((sysname_ptr != sysname_default) &&
+          (len <= 255))
+      {
+        set_ok = 1;
+      }
+      break;
+    case 6: /* sysLocation */
+      if ((syslocation_ptr != syslocation_default) &&
+          (len <= 255))
+      {
+        set_ok = 1;
+      }
+      break;
+  };
+  return set_ok;
+}
+
+static void
+system_set_value(struct obj_def *od, u16_t len, void *value)
+{
+  u8_t id;
+
+  LWIP_ASSERT("invalid len", len <= 0xff);
+  LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+  id = (u8_t)od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 4: /* sysContact */
+      ocstrncpy(syscontact_ptr, (u8_t*)value, len);
+      *syscontact_len_ptr = (u8_t)len;
+      break;
+    case 5: /* sysName */
+      ocstrncpy(sysname_ptr, (u8_t*)value, len);
+      *sysname_len_ptr = (u8_t)len;
+      break;
+    case 6: /* sysLocation */
+      ocstrncpy(syslocation_ptr, (u8_t*)value, len);
+      *syslocation_len_ptr = (u8_t)len;
+      break;
+  };
+}
+
+/**
+ * Returns interfaces.ifnumber object definition.
+ *
+ * @param ident_len the address length (2)
+ * @param ident points to objectname.index
+ * @param od points to object definition.
+ */
+static void
+interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  /* return to object name, adding index depth (1) */
+  ident_len += 1;
+  ident -= 1;
+  if (ident_len == 2)
+  {
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    od->instance = MIB_OBJECT_SCALAR;
+    od->access = MIB_OBJECT_READ_ONLY;
+    od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+    od->v_len = sizeof(s32_t);
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("interfaces_get_object_def: no scalar\n"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+/**
+ * Returns interfaces.ifnumber object value.
+ *
+ * @param ident_len the address length (2)
+ * @param ident points to objectname.0 (object id trailer)
+ * @param len return value space (in bytes)
+ * @param value points to (varbind) space to copy value into.
+ */
+static void
+interfaces_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  LWIP_UNUSED_ARG(len);
+  if (od->id_inst_ptr[0] == 1)
+  {
+    s32_t *sint_ptr = (s32_t*)value;
+    *sint_ptr = iflist_root.count;
+  }
+}
+
+/**
+ * Returns ifentry object definitions.
+ *
+ * @param ident_len the address length (2)
+ * @param ident points to objectname.index
+ * @param od points to object definition.
+ */
+static void
+ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  u8_t id;
+
+  /* return to object name, adding index depth (1) */
+  ident_len += 1;
+  ident -= 1;
+  if (ident_len == 2)
+  {
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
+    id = (u8_t)ident[0];
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ifentry.%"U16_F"\n",(u16_t)id));
+    switch (id)
+    {
+      case 1: /* ifIndex */
+      case 3: /* ifType */
+      case 4: /* ifMtu */
+      case 8: /* ifOperStatus */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      case 2: /* ifDescr */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
+        /** @todo this should be some sort of sizeof(struct netif.name) */
+        od->v_len = 2;
+        break;
+      case 5: /* ifSpeed */
+      case 21: /* ifOutQLen */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE);
+        od->v_len = sizeof(u32_t);
+        break;
+      case 6: /* ifPhysAddress */
+        {
+          struct netif *netif;
+
+          snmp_ifindextonetif(ident[1], &netif);
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_ONLY;
+          od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
+          od->v_len = netif->hwaddr_len;
+        }
+        break;
+      case 7: /* ifAdminStatus */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      case 9: /* ifLastChange */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS);
+        od->v_len = sizeof(u32_t);
+        break;
+      case 10: /* ifInOctets */
+      case 11: /* ifInUcastPkts */
+      case 12: /* ifInNUcastPkts */
+      case 13: /* ifInDiscarts */
+      case 14: /* ifInErrors */
+      case 15: /* ifInUnkownProtos */
+      case 16: /* ifOutOctets */
+      case 17: /* ifOutUcastPkts */
+      case 18: /* ifOutNUcastPkts */
+      case 19: /* ifOutDiscarts */
+      case 20: /* ifOutErrors */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
+        od->v_len = sizeof(u32_t);
+        break;
+      case 22: /* ifSpecific */
+        /** @note returning zeroDotZero (0.0) no media specific MIB support */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID);
+        od->v_len = ifspecific.len * sizeof(s32_t);
+        break;
+      default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no such object\n"));
+        od->instance = MIB_OBJECT_NONE;
+        break;
+    };
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no scalar\n"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+/**
+ * Returns ifentry object value.
+ *
+ * @param ident_len the address length (2)
+ * @param ident points to objectname.0 (object id trailer)
+ * @param len return value space (in bytes)
+ * @param value points to (varbind) space to copy value into.
+ */
+static void
+ifentry_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  struct netif *netif;
+  u8_t id;
+
+  snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
+  LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+  id = (u8_t)od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 1: /* ifIndex */
+      {
+        s32_t *sint_ptr = (s32_t*)value;
+        *sint_ptr = od->id_inst_ptr[1];
+      }
+      break;
+    case 2: /* ifDescr */
+      ocstrncpy((u8_t*)value, (u8_t*)netif->name, len);
+      break;
+    case 3: /* ifType */
+      {
+        s32_t *sint_ptr = (s32_t*)value;
+        *sint_ptr = netif->link_type;
+      }
+      break;
+    case 4: /* ifMtu */
+      {
+        s32_t *sint_ptr = (s32_t*)value;
+        *sint_ptr = netif->mtu;
+      }
+      break;
+    case 5: /* ifSpeed */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = netif->link_speed;
+      }
+      break;
+    case 6: /* ifPhysAddress */
+      ocstrncpy((u8_t*)value, netif->hwaddr, len);
+      break;
+    case 7: /* ifAdminStatus */
+      {
+        s32_t *sint_ptr = (s32_t*)value;
+        if (netif_is_up(netif))
+        {
+          if (netif_is_link_up(netif))
+          {
+            *sint_ptr = 1; /* up */
+          }
+          else
+          {
+            *sint_ptr = 7; /* lowerLayerDown */
+          }
+        }
+        else
+        {
+          *sint_ptr = 2; /* down */
+        }
+      }
+      break;
+    case 8: /* ifOperStatus */
+      {
+        s32_t *sint_ptr = (s32_t*)value;
+        if (netif_is_up(netif))
+        {
+          *sint_ptr = 1;
+        }
+        else
+        {
+          *sint_ptr = 2;
+        }
+      }
+      break;
+    case 9: /* ifLastChange */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = netif->ts;
+      }
+      break;
+    case 10: /* ifInOctets */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = netif->ifinoctets;
+      }
+      break;
+    case 11: /* ifInUcastPkts */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = netif->ifinucastpkts;
+      }
+      break;
+    case 12: /* ifInNUcastPkts */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = netif->ifinnucastpkts;
+      }
+      break;
+    case 13: /* ifInDiscarts */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = netif->ifindiscards;
+      }
+      break;
+    case 14: /* ifInErrors */
+    case 15: /* ifInUnkownProtos */
+      /** @todo add these counters! */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = 0;
+      }
+      break;
+    case 16: /* ifOutOctets */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = netif->ifoutoctets;
+      }
+      break;
+    case 17: /* ifOutUcastPkts */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = netif->ifoutucastpkts;
+      }
+      break;
+    case 18: /* ifOutNUcastPkts */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = netif->ifoutnucastpkts;
+      }
+      break;
+    case 19: /* ifOutDiscarts */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = netif->ifoutdiscards;
+      }
+      break;
+    case 20: /* ifOutErrors */
+       /** @todo add this counter! */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = 0;
+      }
+      break;
+    case 21: /* ifOutQLen */
+      /** @todo figure out if this must be 0 (no queue) or 1? */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = 0;
+      }
+      break;
+    case 22: /* ifSpecific */
+      objectidncpy((s32_t*)value, (s32_t*)ifspecific.id, (u8_t)(len / sizeof(s32_t)));
+      break;
+  };
+}
+
+#if !SNMP_SAFE_REQUESTS
+static u8_t
+ifentry_set_test(struct obj_def *od, u16_t len, void *value)
+{
+  struct netif *netif;
+  u8_t id, set_ok;
+  LWIP_UNUSED_ARG(len);
+
+  set_ok = 0;
+  snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
+  id = (u8_t)od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 7: /* ifAdminStatus */
+      {
+        s32_t *sint_ptr = (s32_t*)value;
+        if (*sint_ptr == 1 || *sint_ptr == 2)
+          set_ok = 1;
+      }
+      break;
+  }
+  return set_ok;
+}
+
+static void
+ifentry_set_value(struct obj_def *od, u16_t len, void *value)
+{
+  struct netif *netif;
+  u8_t id;
+  LWIP_UNUSED_ARG(len);
+
+  snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
+  id = (u8_t)od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 7: /* ifAdminStatus */
+      {
+        s32_t *sint_ptr = (s32_t*)value;
+        if (*sint_ptr == 1)
+        {
+          netif_set_up(netif);
+        }
+        else if (*sint_ptr == 2)
+        {
+          netif_set_down(netif);
+         }
+      }
+      break;
+  }
+}
+#endif /* SNMP_SAFE_REQUESTS */
+
+/**
+ * Returns atentry object definitions.
+ *
+ * @param ident_len the address length (6)
+ * @param ident points to objectname.atifindex.atnetaddress
+ * @param od points to object definition.
+ */
+static void
+atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  /* return to object name, adding index depth (5) */
+  ident_len += 5;
+  ident -= 5;
+
+  if (ident_len == 6)
+  {
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    switch (ident[0])
+    {
+      case 1: /* atIfIndex */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      case 2: /* atPhysAddress */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
+        od->v_len = 6; /** @todo try to use netif::hwaddr_len */
+        break;
+      case 3: /* atNetAddress */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
+        od->v_len = 4;
+        break;
+      default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no such object\n"));
+        od->instance = MIB_OBJECT_NONE;
+        break;
+    }
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no scalar\n"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+atentry_get_value(struct obj_def *od, u16_t len, void *value)
+{
+#if LWIP_ARP
+  u8_t id;
+  struct eth_addr* ethaddr_ret;
+  ip_addr_t* ipaddr_ret;
+#endif /* LWIP_ARP */
+  ip_addr_t ip;
+  struct netif *netif;
+
+  LWIP_UNUSED_ARG(len);
+  LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */
+
+  snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
+  snmp_oidtoip(&od->id_inst_ptr[2], &ip);
+
+#if LWIP_ARP /** @todo implement a netif_find_addr */
+  if (etharp_find_addr(netif, &ip, &ethaddr_ret, &ipaddr_ret) > -1)
+  {
+    LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+    id = (u8_t)od->id_inst_ptr[0];
+    switch (id)
+    {
+      case 1: /* atIfIndex */
+        {
+          s32_t *sint_ptr = (s32_t*)value;
+          *sint_ptr = od->id_inst_ptr[1];
+        }
+        break;
+      case 2: /* atPhysAddress */
+        {
+          struct eth_addr *dst = (struct eth_addr*)value;
+
+          *dst = *ethaddr_ret;
+        }
+        break;
+      case 3: /* atNetAddress */
+        {
+          ip_addr_t *dst = (ip_addr_t*)value;
+
+          *dst = *ipaddr_ret;
+        }
+        break;
+    }
+  }
+#endif /* LWIP_ARP */
+}
+
+static void
+ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  u8_t id;
+
+  /* return to object name, adding index depth (1) */
+  ident_len += 1;
+  ident -= 1;
+  if (ident_len == 2)
+  {
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
+    id = (u8_t)ident[0];
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ip.%"U16_F".0\n",(u16_t)id));
+    switch (id)
+    {
+      case 1: /* ipForwarding */
+      case 2: /* ipDefaultTTL */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      case 3: /* ipInReceives */
+      case 4: /* ipInHdrErrors */
+      case 5: /* ipInAddrErrors */
+      case 6: /* ipForwDatagrams */
+      case 7: /* ipInUnknownProtos */
+      case 8: /* ipInDiscards */
+      case 9: /* ipInDelivers */
+      case 10: /* ipOutRequests */
+      case 11: /* ipOutDiscards */
+      case 12: /* ipOutNoRoutes */
+      case 14: /* ipReasmReqds */
+      case 15: /* ipReasmOKs */
+      case 16: /* ipReasmFails */
+      case 17: /* ipFragOKs */
+      case 18: /* ipFragFails */
+      case 19: /* ipFragCreates */
+      case 23: /* ipRoutingDiscards */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
+        od->v_len = sizeof(u32_t);
+        break;
+      case 13: /* ipReasmTimeout */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no such object\n"));
+        od->instance = MIB_OBJECT_NONE;
+        break;
+    };
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no scalar\n"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+ip_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u8_t id;
+
+  LWIP_UNUSED_ARG(len);
+  LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+  id = (u8_t)od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 1: /* ipForwarding */
+      {
+        s32_t *sint_ptr = (s32_t*)value;
+#if IP_FORWARD
+        /* forwarding */
+        *sint_ptr = 1;
+#else
+        /* not-forwarding */
+        *sint_ptr = 2;
+#endif
+      }
+      break;
+    case 2: /* ipDefaultTTL */
+      {
+        s32_t *sint_ptr = (s32_t*)value;
+        *sint_ptr = IP_DEFAULT_TTL;
+      }
+      break;
+    case 3: /* ipInReceives */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipinreceives;
+      }
+      break;
+    case 4: /* ipInHdrErrors */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipinhdrerrors;
+      }
+      break;
+    case 5: /* ipInAddrErrors */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipinaddrerrors;
+      }
+      break;
+    case 6: /* ipForwDatagrams */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipforwdatagrams;
+      }
+      break;
+    case 7: /* ipInUnknownProtos */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipinunknownprotos;
+      }
+      break;
+    case 8: /* ipInDiscards */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipindiscards;
+      }
+      break;
+    case 9: /* ipInDelivers */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipindelivers;
+      }
+      break;
+    case 10: /* ipOutRequests */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipoutrequests;
+      }
+      break;
+    case 11: /* ipOutDiscards */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipoutdiscards;
+      }
+      break;
+    case 12: /* ipOutNoRoutes */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipoutnoroutes;
+      }
+      break;
+    case 13: /* ipReasmTimeout */
+      {
+        s32_t *sint_ptr = (s32_t*)value;
+#if IP_REASSEMBLY
+        *sint_ptr = IP_REASS_MAXAGE;
+#else
+        *sint_ptr = 0;
+#endif
+      }
+      break;
+    case 14: /* ipReasmReqds */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipreasmreqds;
+      }
+      break;
+    case 15: /* ipReasmOKs */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipreasmoks;
+      }
+      break;
+    case 16: /* ipReasmFails */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipreasmfails;
+      }
+      break;
+    case 17: /* ipFragOKs */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipfragoks;
+      }
+      break;
+    case 18: /* ipFragFails */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipfragfails;
+      }
+      break;
+    case 19: /* ipFragCreates */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = ipfragcreates;
+      }
+      break;
+    case 23: /* ipRoutingDiscards */
+      /** @todo can lwIP discard routes at all?? hardwire this to 0?? */
+      {
+        u32_t *uint_ptr = (u32_t*)value;
+        *uint_ptr = iproutingdiscards;
+      }
+      break;
+  };
+}
+
+/**
+ * Test ip object value before setting.
+ *
+ * @param od is the object definition
+ * @param len return value space (in bytes)
+ * @param value points to (varbind) space to copy value from.
+ *
+ * @note we allow set if the value matches the hardwired value,
+ *   otherwise return badvalue.
+ */
+static u8_t
+ip_set_test(struct obj_def *od, u16_t len, void *value)
+{
+  u8_t id, set_ok;
+  s32_t *sint_ptr = (s32_t*)value;
+
+  LWIP_UNUSED_ARG(len);
+  set_ok = 0;
+  LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+  id = (u8_t)od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 1: /* ipForwarding */
+#if IP_FORWARD
+      /* forwarding */
+      if (*sint_ptr == 1)
+#else
+      /* not-forwarding */
+      if (*sint_ptr == 2)
+#endif
+      {
+        set_ok = 1;
+      }
+      break;
+    case 2: /* ipDefaultTTL */
+      if (*sint_ptr == IP_DEFAULT_TTL)
+      {
+        set_ok = 1;
+      }
+      break;
+  };
+  return set_ok;
+}
+
+static void
+ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  /* return to object name, adding index depth (4) */
+  ident_len += 4;
+  ident -= 4;
+
+  if (ident_len == 5)
+  {
+    u8_t id;
+
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
+    id = (u8_t)ident[0];
+    switch (id)
+    {
+      case 1: /* ipAdEntAddr */
+      case 3: /* ipAdEntNetMask */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
+        od->v_len = 4;
+        break;
+      case 2: /* ipAdEntIfIndex */
+      case 4: /* ipAdEntBcastAddr */
+      case 5: /* ipAdEntReasmMaxSize */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no such object\n"));
+        od->instance = MIB_OBJECT_NONE;
+        break;
+    }
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no scalar\n"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u8_t id;
+  u16_t ifidx;
+  ip_addr_t ip;
+  struct netif *netif = netif_list;
+
+  LWIP_UNUSED_ARG(len);
+  snmp_oidtoip(&od->id_inst_ptr[1], &ip);
+  ifidx = 0;
+  while ((netif != NULL) && !ip_addr_cmp(&ip, &netif->ip_addr))
+  {
+    netif = netif->next;
+    ifidx++;
+  }
+
+  if (netif != NULL)
+  {
+    LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+    id = (u8_t)od->id_inst_ptr[0];
+    switch (id)
+    {
+      case 1: /* ipAdEntAddr */
+        {
+          ip_addr_t *dst = (ip_addr_t*)value;
+          *dst = netif->ip_addr;
+        }
+        break;
+      case 2: /* ipAdEntIfIndex */
+        {
+          s32_t *sint_ptr = (s32_t*)value;
+          *sint_ptr = ifidx + 1;
+        }
+        break;
+      case 3: /* ipAdEntNetMask */
+        {
+          ip_addr_t *dst = (ip_addr_t*)value;
+          *dst = netif->netmask;
+        }
+        break;
+      case 4: /* ipAdEntBcastAddr */
+        {
+          s32_t *sint_ptr = (s32_t*)value;
+
+          /* lwIP oddity, there's no broadcast
+            address in the netif we can rely on */
+          *sint_ptr = IPADDR_BROADCAST & 1;
+        }
+        break;
+      case 5: /* ipAdEntReasmMaxSize */
+        {
+          s32_t *sint_ptr = (s32_t*)value;
+#if IP_REASSEMBLY
+          /* @todo The theoretical maximum is IP_REASS_MAX_PBUFS * size of the pbufs,
+           * but only if receiving one fragmented packet at a time.
+           * The current solution is to calculate for 2 simultaneous packets...
+           */
+          *sint_ptr = (IP_HLEN + ((IP_REASS_MAX_PBUFS/2) *
+            (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN - IP_HLEN)));
+#else
+          /** @todo returning MTU would be a bad thing and
+             returning a wild guess like '576' isn't good either */
+          *sint_ptr = 0;
+#endif
+        }
+        break;
+    }
+  }
+}
+
+/**
+ * @note
+ * lwIP IP routing is currently using the network addresses in netif_list.
+ * if no suitable network IP is found in netif_list, the default_netif is used.
+ */
+static void
+ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  u8_t id;
+
+  /* return to object name, adding index depth (4) */
+  ident_len += 4;
+  ident -= 4;
+
+  if (ident_len == 5)
+  {
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
+    id = (u8_t)ident[0];
+    switch (id)
+    {
+      case 1: /* ipRouteDest */
+      case 7: /* ipRouteNextHop */
+      case 11: /* ipRouteMask */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
+        od->v_len = 4;
+        break;
+      case 2: /* ipRouteIfIndex */
+      case 3: /* ipRouteMetric1 */
+      case 4: /* ipRouteMetric2 */
+      case 5: /* ipRouteMetric3 */
+      case 6: /* ipRouteMetric4 */
+      case 8: /* ipRouteType */
+      case 10: /* ipRouteAge */
+      case 12: /* ipRouteMetric5 */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      case 9: /* ipRouteProto */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      case 13: /* ipRouteInfo */
+        /** @note returning zeroDotZero (0.0) no routing protocol specific MIB */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID);
+        od->v_len = iprouteinfo.len * sizeof(s32_t);
+        break;
+      default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no such object\n"));
+        od->instance = MIB_OBJECT_NONE;
+        break;
+    }
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no scalar\n"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  struct netif *netif;
+  ip_addr_t dest;
+  s32_t *ident;
+  u8_t id;
+
+  ident = od->id_inst_ptr;
+  snmp_oidtoip(&ident[1], &dest);
+
+  if (ip_addr_isany(&dest))
+  {
+    /* ip_route() uses default netif for default route */
+    netif = netif_default;
+  }
+  else
+  {
+    /* not using ip_route(), need exact match! */
+    netif = netif_list;
+    while ((netif != NULL) &&
+            !ip_addr_netcmp(&dest, &(netif->ip_addr), &(netif->netmask)) )
+    {
+      netif = netif->next;
+    }
+  }
+  if (netif != NULL)
+  {
+    LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
+    id = (u8_t)ident[0];
+    switch (id)
+    {
+      case 1: /* ipRouteDest */
+        {
+          ip_addr_t *dst = (ip_addr_t*)value;
+
+          if (ip_addr_isany(&dest))
+          {
+            /* default rte has 0.0.0.0 dest */
+            ip_addr_set_zero(dst);
+          }
+          else
+          {
+            /* netifs have netaddress dest */
+            ip_addr_get_network(dst, &netif->ip_addr, &netif->netmask);
+          }
+        }
+        break;
+      case 2: /* ipRouteIfIndex */
+        {
+          s32_t *sint_ptr = (s32_t*)value;
+
+          snmp_netiftoifindex(netif, sint_ptr);
+        }
+        break;
+      case 3: /* ipRouteMetric1 */
+        {
+          s32_t *sint_ptr = (s32_t*)value;
+
+          if (ip_addr_isany(&dest))
+          {
+            /* default rte has metric 1 */
+            *sint_ptr = 1;
+          }
+          else
+          {
+            /* other rtes have metric 0 */
+            *sint_ptr = 0;
+          }
+        }
+        break;
+      case 4: /* ipRouteMetric2 */
+      case 5: /* ipRouteMetric3 */
+      case 6: /* ipRouteMetric4 */
+      case 12: /* ipRouteMetric5 */
+        {
+          s32_t *sint_ptr = (s32_t*)value;
+          /* not used */
+          *sint_ptr = -1;
+        }
+        break;
+      case 7: /* ipRouteNextHop */
+        {
+          ip_addr_t *dst = (ip_addr_t*)value;
+
+          if (ip_addr_isany(&dest))
+          {
+            /* default rte: gateway */
+            *dst = netif->gw;
+          }
+          else
+          {
+            /* other rtes: netif ip_addr  */
+            *dst = netif->ip_addr;
+          }
+        }
+        break;
+      case 8: /* ipRouteType */
+        {
+          s32_t *sint_ptr = (s32_t*)value;
+
+          if (ip_addr_isany(&dest))
+          {
+            /* default rte is indirect */
+            *sint_ptr = 4;
+          }
+          else
+          {
+            /* other rtes are direct */
+            *sint_ptr = 3;
+          }
+        }
+        break;
+      case 9: /* ipRouteProto */
+        {
+          s32_t *sint_ptr = (s32_t*)value;
+          /* locally defined routes */
+          *sint_ptr = 2;
+        }
+        break;
+      case 10: /* ipRouteAge */
+        {
+          s32_t *sint_ptr = (s32_t*)value;
+          /** @todo (sysuptime - timestamp last change) / 100
+              @see snmp_insert_iprteidx_tree() */
+          *sint_ptr = 0;
+        }
+        break;
+      case 11: /* ipRouteMask */
+        {
+          ip_addr_t *dst = (ip_addr_t*)value;
+
+          if (ip_addr_isany(&dest))
+          {
+            /* default rte use 0.0.0.0 mask */
+            ip_addr_set_zero(dst);
+          }
+          else
+          {
+            /* other rtes use netmask */
+            *dst = netif->netmask;
+          }
+        }
+        break;
+      case 13: /* ipRouteInfo */
+        objectidncpy((s32_t*)value, (s32_t*)iprouteinfo.id, (u8_t)(len / sizeof(s32_t)));
+        break;
+    }
+  }
+}
+
+static void
+ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  /* return to object name, adding index depth (5) */
+  ident_len += 5;
+  ident -= 5;
+
+  if (ident_len == 6)
+  {
+    u8_t id;
+
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
+    id = (u8_t)ident[0];
+    switch (id)
+    {
+      case 1: /* ipNetToMediaIfIndex */
+      case 4: /* ipNetToMediaType */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      case 2: /* ipNetToMediaPhysAddress */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
+        od->v_len = 6; /** @todo try to use netif::hwaddr_len */
+        break;
+      case 3: /* ipNetToMediaNetAddress */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
+        od->v_len = 4;
+        break;
+      default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no such object\n"));
+        od->instance = MIB_OBJECT_NONE;
+        break;
+    }
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no scalar\n"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value)
+{
+#if LWIP_ARP
+  u8_t id;
+  struct eth_addr* ethaddr_ret;
+  ip_addr_t* ipaddr_ret;
+#endif /* LWIP_ARP */
+  ip_addr_t ip;
+  struct netif *netif;
+
+  LWIP_UNUSED_ARG(len);
+  LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */
+
+  snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
+  snmp_oidtoip(&od->id_inst_ptr[2], &ip);
+
+#if LWIP_ARP /** @todo implement a netif_find_addr */
+  if (etharp_find_addr(netif, &ip, &ethaddr_ret, &ipaddr_ret) > -1)
+  {
+    LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+    id = (u8_t)od->id_inst_ptr[0];
+    switch (id)
+    {
+      case 1: /* ipNetToMediaIfIndex */
+        {
+          s32_t *sint_ptr = (s32_t*)value;
+          *sint_ptr = od->id_inst_ptr[1];
+        }
+        break;
+      case 2: /* ipNetToMediaPhysAddress */
+        {
+          struct eth_addr *dst = (struct eth_addr*)value;
+
+          *dst = *ethaddr_ret;
+        }
+        break;
+      case 3: /* ipNetToMediaNetAddress */
+        {
+          ip_addr_t *dst = (ip_addr_t*)value;
+
+          *dst = *ipaddr_ret;
+        }
+        break;
+      case 4: /* ipNetToMediaType */
+        {
+          s32_t *sint_ptr = (s32_t*)value;
+          /* dynamic (?) */
+          *sint_ptr = 3;
+        }
+        break;
+    }
+  }
+#endif /* LWIP_ARP */
+}
+
+static void
+icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  /* return to object name, adding index depth (1) */
+  ident_len += 1;
+  ident -= 1;
+  if ((ident_len == 2) &&
+      (ident[0] > 0) && (ident[0] < 27))
+  {
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    od->instance = MIB_OBJECT_SCALAR;
+    od->access = MIB_OBJECT_READ_ONLY;
+    od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
+    od->v_len = sizeof(u32_t);
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("icmp_get_object_def: no scalar\n"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+icmp_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u32_t *uint_ptr = (u32_t*)value;
+  u8_t id;
+
+  LWIP_UNUSED_ARG(len);
+  LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+  id = (u8_t)od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 1: /* icmpInMsgs */
+      *uint_ptr = icmpinmsgs;
+      break;
+    case 2: /* icmpInErrors */
+      *uint_ptr = icmpinerrors;
+      break;
+    case 3: /* icmpInDestUnreachs */
+      *uint_ptr = icmpindestunreachs;
+      break;
+    case 4: /* icmpInTimeExcds */
+      *uint_ptr = icmpintimeexcds;
+      break;
+    case 5: /* icmpInParmProbs */
+      *uint_ptr = icmpinparmprobs;
+      break;
+    case 6: /* icmpInSrcQuenchs */
+      *uint_ptr = icmpinsrcquenchs;
+      break;
+    case 7: /* icmpInRedirects */
+      *uint_ptr = icmpinredirects;
+      break;
+    case 8: /* icmpInEchos */
+      *uint_ptr = icmpinechos;
+      break;
+    case 9: /* icmpInEchoReps */
+      *uint_ptr = icmpinechoreps;
+      break;
+    case 10: /* icmpInTimestamps */
+      *uint_ptr = icmpintimestamps;
+      break;
+    case 11: /* icmpInTimestampReps */
+      *uint_ptr = icmpintimestampreps;
+      break;
+    case 12: /* icmpInAddrMasks */
+      *uint_ptr = icmpinaddrmasks;
+      break;
+    case 13: /* icmpInAddrMaskReps */
+      *uint_ptr = icmpinaddrmaskreps;
+      break;
+    case 14: /* icmpOutMsgs */
+      *uint_ptr = icmpoutmsgs;
+      break;
+    case 15: /* icmpOutErrors */
+      *uint_ptr = icmpouterrors;
+      break;
+    case 16: /* icmpOutDestUnreachs */
+      *uint_ptr = icmpoutdestunreachs;
+      break;
+    case 17: /* icmpOutTimeExcds */
+      *uint_ptr = icmpouttimeexcds;
+      break;
+    case 18: /* icmpOutParmProbs */
+      *uint_ptr = icmpoutparmprobs;
+      break;
+    case 19: /* icmpOutSrcQuenchs */
+      *uint_ptr = icmpoutsrcquenchs;
+      break;
+    case 20: /* icmpOutRedirects */
+      *uint_ptr = icmpoutredirects;
+      break;
+    case 21: /* icmpOutEchos */
+      *uint_ptr = icmpoutechos;
+      break;
+    case 22: /* icmpOutEchoReps */
+      *uint_ptr = icmpoutechoreps;
+      break;
+    case 23: /* icmpOutTimestamps */
+      *uint_ptr = icmpouttimestamps;
+      break;
+    case 24: /* icmpOutTimestampReps */
+      *uint_ptr = icmpouttimestampreps;
+      break;
+    case 25: /* icmpOutAddrMasks */
+      *uint_ptr = icmpoutaddrmasks;
+      break;
+    case 26: /* icmpOutAddrMaskReps */
+      *uint_ptr = icmpoutaddrmaskreps;
+      break;
+  }
+}
+
+#if LWIP_TCP
+/** @todo tcp grp */
+static void
+tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  u8_t id;
+
+  /* return to object name, adding index depth (1) */
+  ident_len += 1;
+  ident -= 1;
+  if (ident_len == 2)
+  {
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
+    id = (u8_t)ident[0];
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id));
+
+    switch (id)
+    {
+      case 1: /* tcpRtoAlgorithm */
+      case 2: /* tcpRtoMin */
+      case 3: /* tcpRtoMax */
+      case 4: /* tcpMaxConn */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      case 5: /* tcpActiveOpens */
+      case 6: /* tcpPassiveOpens */
+      case 7: /* tcpAttemptFails */
+      case 8: /* tcpEstabResets */
+      case 10: /* tcpInSegs */
+      case 11: /* tcpOutSegs */
+      case 12: /* tcpRetransSegs */
+      case 14: /* tcpInErrs */
+      case 15: /* tcpOutRsts */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
+        od->v_len = sizeof(u32_t);
+        break;
+      case 9: /* tcpCurrEstab */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE);
+        od->v_len = sizeof(u32_t);
+        break;
+      default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no such object\n"));
+        od->instance = MIB_OBJECT_NONE;
+        break;
+    };
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no scalar\n"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+tcp_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u32_t *uint_ptr = (u32_t*)value;
+  s32_t *sint_ptr = (s32_t*)value;
+  u8_t id;
+
+  LWIP_UNUSED_ARG(len);
+  LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+  id = (u8_t)od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 1: /* tcpRtoAlgorithm, vanj(4) */
+      *sint_ptr = 4;
+      break;
+    case 2: /* tcpRtoMin */
+      /* @todo not the actual value, a guess,
+          needs to be calculated */
+      *sint_ptr = 1000;
+      break;
+    case 3: /* tcpRtoMax */
+      /* @todo not the actual value, a guess,
+         needs to be calculated */
+      *sint_ptr = 60000;
+      break;
+    case 4: /* tcpMaxConn */
+      *sint_ptr = MEMP_NUM_TCP_PCB;
+      break;
+    case 5: /* tcpActiveOpens */
+      *uint_ptr = tcpactiveopens;
+      break;
+    case 6: /* tcpPassiveOpens */
+      *uint_ptr = tcppassiveopens;
+      break;
+    case 7: /* tcpAttemptFails */
+      *uint_ptr = tcpattemptfails;
+      break;
+    case 8: /* tcpEstabResets */
+      *uint_ptr = tcpestabresets;
+      break;
+    case 9: /* tcpCurrEstab */
+      {
+        u16_t tcpcurrestab = 0;
+        struct tcp_pcb *pcb = tcp_active_pcbs;
+        while (pcb != NULL)
+        {
+          if ((pcb->state == ESTABLISHED) ||
+              (pcb->state == CLOSE_WAIT))
+          {
+            tcpcurrestab++;
+          }
+          pcb = pcb->next;
+        }
+        *uint_ptr = tcpcurrestab;
+      }
+      break;
+    case 10: /* tcpInSegs */
+      *uint_ptr = tcpinsegs;
+      break;
+    case 11: /* tcpOutSegs */
+      *uint_ptr = tcpoutsegs;
+      break;
+    case 12: /* tcpRetransSegs */
+      *uint_ptr = tcpretranssegs;
+      break;
+    case 14: /* tcpInErrs */
+      *uint_ptr = tcpinerrs;
+      break;
+    case 15: /* tcpOutRsts */
+      *uint_ptr = tcpoutrsts;
+      break;
+  }
+}
+#ifdef THIS_SEEMS_UNUSED
+static void
+tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  /* return to object name, adding index depth (10) */
+  ident_len += 10;
+  ident -= 10;
+
+  if (ident_len == 11)
+  {
+    u8_t id;
+
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    id = ident[0];
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id));
+
+    switch (id)
+    {
+      case 1: /* tcpConnState */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      case 2: /* tcpConnLocalAddress */
+      case 4: /* tcpConnRemAddress */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
+        od->v_len = 4;
+        break;
+      case 3: /* tcpConnLocalPort */
+      case 5: /* tcpConnRemPort */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n"));
+        od->instance = MIB_OBJECT_NONE;
+        break;
+    };
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  ip_addr_t lip, rip;
+  u16_t lport, rport;
+  s32_t *ident;
+
+  ident = od->id_inst_ptr;
+  snmp_oidtoip(&ident[1], &lip);
+  lport = ident[5];
+  snmp_oidtoip(&ident[6], &rip);
+  rport = ident[10];
+
+  /** @todo find matching PCB */
+}
+#endif /* if 0 */
+#endif
+
+static void
+udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  /* return to object name, adding index depth (1) */
+  ident_len += 1;
+  ident -= 1;
+  if ((ident_len == 2) &&
+      (ident[0] > 0) && (ident[0] < 6))
+  {
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    od->instance = MIB_OBJECT_SCALAR;
+    od->access = MIB_OBJECT_READ_ONLY;
+    od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
+    od->v_len = sizeof(u32_t);
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("udp_get_object_def: no scalar\n"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+udp_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u32_t *uint_ptr = (u32_t*)value;
+  u8_t id;
+
+  LWIP_UNUSED_ARG(len);
+  LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+  id = (u8_t)od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 1: /* udpInDatagrams */
+      *uint_ptr = udpindatagrams;
+      break;
+    case 2: /* udpNoPorts */
+      *uint_ptr = udpnoports;
+      break;
+    case 3: /* udpInErrors */
+      *uint_ptr = udpinerrors;
+      break;
+    case 4: /* udpOutDatagrams */
+      *uint_ptr = udpoutdatagrams;
+      break;
+  }
+}
+
+static void
+udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  /* return to object name, adding index depth (5) */
+  ident_len += 5;
+  ident -= 5;
+
+  if (ident_len == 6)
+  {
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    switch (ident[0])
+    {
+      case 1: /* udpLocalAddress */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
+        od->v_len = 4;
+        break;
+      case 2: /* udpLocalPort */
+        od->instance = MIB_OBJECT_TAB;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no such object\n"));
+        od->instance = MIB_OBJECT_NONE;
+        break;
+    }
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no scalar\n"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+udpentry_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u8_t id;
+  struct udp_pcb *pcb;
+  ip_addr_t ip;
+  u16_t port;
+
+  LWIP_UNUSED_ARG(len);
+  snmp_oidtoip(&od->id_inst_ptr[1], &ip);
+  LWIP_ASSERT("invalid port", (od->id_inst_ptr[5] >= 0) && (od->id_inst_ptr[5] <= 0xffff));
+  port = (u16_t)od->id_inst_ptr[5];
+
+  pcb = udp_pcbs;
+  while ((pcb != NULL) &&
+         !(ip_addr_cmp(&pcb->local_ip, &ip) &&
+           (pcb->local_port == port)))
+  {
+    pcb = pcb->next;
+  }
+
+  if (pcb != NULL)
+  {
+    LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+    id = (u8_t)od->id_inst_ptr[0];
+    switch (id)
+    {
+      case 1: /* udpLocalAddress */
+        {
+          ip_addr_t *dst = (ip_addr_t*)value;
+          *dst = pcb->local_ip;
+        }
+        break;
+      case 2: /* udpLocalPort */
+        {
+          s32_t *sint_ptr = (s32_t*)value;
+          *sint_ptr = pcb->local_port;
+        }
+        break;
+    }
+  }
+}
+
+static void
+snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  /* return to object name, adding index depth (1) */
+  ident_len += 1;
+  ident -= 1;
+  if (ident_len == 2)
+  {
+    u8_t id;
+
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
+    id = (u8_t)ident[0];
+    switch (id)
+    {
+      case 1: /* snmpInPkts */
+      case 2: /* snmpOutPkts */
+      case 3: /* snmpInBadVersions */
+      case 4: /* snmpInBadCommunityNames */
+      case 5: /* snmpInBadCommunityUses */
+      case 6: /* snmpInASNParseErrs */
+      case 8: /* snmpInTooBigs */
+      case 9: /* snmpInNoSuchNames */
+      case 10: /* snmpInBadValues */
+      case 11: /* snmpInReadOnlys */
+      case 12: /* snmpInGenErrs */
+      case 13: /* snmpInTotalReqVars */
+      case 14: /* snmpInTotalSetVars */
+      case 15: /* snmpInGetRequests */
+      case 16: /* snmpInGetNexts */
+      case 17: /* snmpInSetRequests */
+      case 18: /* snmpInGetResponses */
+      case 19: /* snmpInTraps */
+      case 20: /* snmpOutTooBigs */
+      case 21: /* snmpOutNoSuchNames */
+      case 22: /* snmpOutBadValues */
+      case 24: /* snmpOutGenErrs */
+      case 25: /* snmpOutGetRequests */
+      case 26: /* snmpOutGetNexts */
+      case 27: /* snmpOutSetRequests */
+      case 28: /* snmpOutGetResponses */
+      case 29: /* snmpOutTraps */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
+        od->v_len = sizeof(u32_t);
+        break;
+      case 30: /* snmpEnableAuthenTraps */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no such object\n"));
+        od->instance = MIB_OBJECT_NONE;
+        break;
+    };
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no scalar\n"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+snmp_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u32_t *uint_ptr = (u32_t*)value;
+  u8_t id;
+
+  LWIP_UNUSED_ARG(len);
+  LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+  id = (u8_t)od->id_inst_ptr[0];
+  switch (id)
+  {
+      case 1: /* snmpInPkts */
+        *uint_ptr = snmpinpkts;
+        break;
+      case 2: /* snmpOutPkts */
+        *uint_ptr = snmpoutpkts;
+        break;
+      case 3: /* snmpInBadVersions */
+        *uint_ptr = snmpinbadversions;
+        break;
+      case 4: /* snmpInBadCommunityNames */
+        *uint_ptr = snmpinbadcommunitynames;
+        break;
+      case 5: /* snmpInBadCommunityUses */
+        *uint_ptr = snmpinbadcommunityuses;
+        break;
+      case 6: /* snmpInASNParseErrs */
+        *uint_ptr = snmpinasnparseerrs;
+        break;
+      case 8: /* snmpInTooBigs */
+        *uint_ptr = snmpintoobigs;
+        break;
+      case 9: /* snmpInNoSuchNames */
+        *uint_ptr = snmpinnosuchnames;
+        break;
+      case 10: /* snmpInBadValues */
+        *uint_ptr = snmpinbadvalues;
+        break;
+      case 11: /* snmpInReadOnlys */
+        *uint_ptr = snmpinreadonlys;
+        break;
+      case 12: /* snmpInGenErrs */
+        *uint_ptr = snmpingenerrs;
+        break;
+      case 13: /* snmpInTotalReqVars */
+        *uint_ptr = snmpintotalreqvars;
+        break;
+      case 14: /* snmpInTotalSetVars */
+        *uint_ptr = snmpintotalsetvars;
+        break;
+      case 15: /* snmpInGetRequests */
+        *uint_ptr = snmpingetrequests;
+        break;
+      case 16: /* snmpInGetNexts */
+        *uint_ptr = snmpingetnexts;
+        break;
+      case 17: /* snmpInSetRequests */
+        *uint_ptr = snmpinsetrequests;
+        break;
+      case 18: /* snmpInGetResponses */
+        *uint_ptr = snmpingetresponses;
+        break;
+      case 19: /* snmpInTraps */
+        *uint_ptr = snmpintraps;
+        break;
+      case 20: /* snmpOutTooBigs */
+        *uint_ptr = snmpouttoobigs;
+        break;
+      case 21: /* snmpOutNoSuchNames */
+        *uint_ptr = snmpoutnosuchnames;
+        break;
+      case 22: /* snmpOutBadValues */
+        *uint_ptr = snmpoutbadvalues;
+        break;
+      case 24: /* snmpOutGenErrs */
+        *uint_ptr = snmpoutgenerrs;
+        break;
+      case 25: /* snmpOutGetRequests */
+        *uint_ptr = snmpoutgetrequests;
+        break;
+      case 26: /* snmpOutGetNexts */
+        *uint_ptr = snmpoutgetnexts;
+        break;
+      case 27: /* snmpOutSetRequests */
+        *uint_ptr = snmpoutsetrequests;
+        break;
+      case 28: /* snmpOutGetResponses */
+        *uint_ptr = snmpoutgetresponses;
+        break;
+      case 29: /* snmpOutTraps */
+        *uint_ptr = snmpouttraps;
+        break;
+      case 30: /* snmpEnableAuthenTraps */
+        *uint_ptr = *snmpenableauthentraps_ptr;
+        break;
+  };
+}
+
+/**
+ * Test snmp object value before setting.
+ *
+ * @param od is the object definition
+ * @param len return value space (in bytes)
+ * @param value points to (varbind) space to copy value from.
+ */
+static u8_t
+snmp_set_test(struct obj_def *od, u16_t len, void *value)
+{
+  u8_t id, set_ok;
+
+  LWIP_UNUSED_ARG(len);
+  set_ok = 0;
+  LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+  id = (u8_t)od->id_inst_ptr[0];
+  if (id == 30)
+  {
+    /* snmpEnableAuthenTraps */
+    s32_t *sint_ptr = (s32_t*)value;
+
+    if (snmpenableauthentraps_ptr != &snmpenableauthentraps_default)
+    {
+      /* we should have writable non-volatile mem here */
+      if ((*sint_ptr == 1) || (*sint_ptr == 2))
+      {
+        set_ok = 1;
+      }
+    }
+    else
+    {
+      /* const or hardwired value */
+      if (*sint_ptr == snmpenableauthentraps_default)
+      {
+        set_ok = 1;
+      }
+    }
+  }
+  return set_ok;
+}
+
+static void
+snmp_set_value(struct obj_def *od, u16_t len, void *value)
+{
+  u8_t id;
+
+  LWIP_UNUSED_ARG(len);
+  LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
+  id = (u8_t)od->id_inst_ptr[0];
+  if (id == 30)
+  {
+    /* snmpEnableAuthenTraps */
+    /* @todo @fixme: which kind of pointer is 'value'? s32_t or u8_t??? */
+    u8_t *ptr = (u8_t*)value;
+    *snmpenableauthentraps_ptr = *ptr;
+  }
+}
+
+#endif /* LWIP_SNMP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/mib_structs.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/mib_structs.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/mib_structs.c	(revision 164)
@@ -0,0 +1,1174 @@
+/**
+ * @file
+ * MIB tree access/construction functions.
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/snmp_structs.h"
+#include "lwip/memp.h"
+#include "lwip/netif.h"
+
+/** .iso.org.dod.internet address prefix, @see snmp_iso_*() */
+const s32_t prefix[4] = {1, 3, 6, 1};
+
+#define NODE_STACK_SIZE (LWIP_SNMP_OBJ_ID_LEN)
+/** node stack entry (old news?) */
+struct nse
+{
+  /** right child */
+  struct mib_node* r_ptr;
+  /** right child identifier */
+  s32_t r_id;
+  /** right child next level */
+  u8_t r_nl;
+};
+static u8_t node_stack_cnt;
+static struct nse node_stack[NODE_STACK_SIZE];
+
+/**
+ * Pushes nse struct onto stack.
+ */
+static void
+push_node(struct nse* node)
+{
+  LWIP_ASSERT("node_stack_cnt < NODE_STACK_SIZE",node_stack_cnt < NODE_STACK_SIZE);
+  LWIP_DEBUGF(SNMP_MIB_DEBUG,("push_node() node=%p id=%"S32_F"\n",(void*)(node->r_ptr),node->r_id));
+  if (node_stack_cnt < NODE_STACK_SIZE)
+  {
+    node_stack[node_stack_cnt] = *node;
+    node_stack_cnt++;
+  }
+}
+
+/**
+ * Pops nse struct from stack.
+ */
+static void
+pop_node(struct nse* node)
+{
+  if (node_stack_cnt > 0)
+  {
+    node_stack_cnt--;
+    *node = node_stack[node_stack_cnt];
+  }
+  LWIP_DEBUGF(SNMP_MIB_DEBUG,("pop_node() node=%p id=%"S32_F"\n",(void *)(node->r_ptr),node->r_id));
+}
+
+/**
+ * Conversion from ifIndex to lwIP netif
+ * @param ifindex is a s32_t object sub-identifier
+ * @param netif points to returned netif struct pointer
+ */
+void
+snmp_ifindextonetif(s32_t ifindex, struct netif **netif)
+{
+  struct netif *nif = netif_list;
+  s32_t i, ifidx;
+
+  ifidx = ifindex - 1;
+  i = 0;
+  while ((nif != NULL) && (i < ifidx))
+  {
+    nif = nif->next;
+    i++;
+  }
+  *netif = nif;
+}
+
+/**
+ * Conversion from lwIP netif to ifIndex
+ * @param netif points to a netif struct
+ * @param ifidx points to s32_t object sub-identifier
+ */
+void
+snmp_netiftoifindex(struct netif *netif, s32_t *ifidx)
+{
+  struct netif *nif = netif_list;
+  u16_t i;
+
+  i = 0;
+  while ((nif != NULL) && (nif != netif))
+  {
+    nif = nif->next;
+    i++;
+  }
+  *ifidx = i+1;
+}
+
+/**
+ * Conversion from oid to lwIP ip_addr
+ * @param ident points to s32_t ident[4] input
+ * @param ip points to output struct
+ */
+void
+snmp_oidtoip(s32_t *ident, ip_addr_t *ip)
+{
+  IP4_ADDR(ip, ident[0], ident[1], ident[2], ident[3]);
+}
+
+/**
+ * Conversion from lwIP ip_addr to oid
+ * @param ip points to input struct
+ * @param ident points to s32_t ident[4] output
+ */
+void
+snmp_iptooid(ip_addr_t *ip, s32_t *ident)
+{
+  ident[0] = ip4_addr1(ip);
+  ident[1] = ip4_addr2(ip);
+  ident[2] = ip4_addr3(ip);
+  ident[3] = ip4_addr4(ip);
+}
+
+struct mib_list_node *
+snmp_mib_ln_alloc(s32_t id)
+{
+  struct mib_list_node *ln;
+
+  ln = (struct mib_list_node *)memp_malloc(MEMP_SNMP_NODE);
+  if (ln != NULL)
+  {
+    ln->prev = NULL;
+    ln->next = NULL;
+    ln->objid = id;
+    ln->nptr = NULL;
+  }
+  return ln;
+}
+
+void
+snmp_mib_ln_free(struct mib_list_node *ln)
+{
+  memp_free(MEMP_SNMP_NODE, ln);
+}
+
+struct mib_list_rootnode *
+snmp_mib_lrn_alloc(void)
+{
+  struct mib_list_rootnode *lrn;
+
+  lrn = (struct mib_list_rootnode*)memp_malloc(MEMP_SNMP_ROOTNODE);
+  if (lrn != NULL)
+  {
+    lrn->get_object_def = noleafs_get_object_def;
+    lrn->get_value = noleafs_get_value;
+    lrn->set_test = noleafs_set_test;
+    lrn->set_value = noleafs_set_value;
+    lrn->node_type = MIB_NODE_LR;
+    lrn->maxlength = 0;
+    lrn->head = NULL;
+    lrn->tail = NULL;
+    lrn->count = 0;
+  }
+  return lrn;
+}
+
+void
+snmp_mib_lrn_free(struct mib_list_rootnode *lrn)
+{
+  memp_free(MEMP_SNMP_ROOTNODE, lrn);
+}
+
+/**
+ * Inserts node in idx list in a sorted
+ * (ascending order) fashion and
+ * allocates the node if needed.
+ *
+ * @param rn points to the root node
+ * @param objid is the object sub identifier
+ * @param insn points to a pointer to the inserted node
+ *   used for constructing the tree.
+ * @return -1 if failed, 1 if inserted, 2 if present.
+ */
+s8_t
+snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn)
+{
+  struct mib_list_node *nn;
+  s8_t insert;
+
+  LWIP_ASSERT("rn != NULL",rn != NULL);
+
+  /* -1 = malloc failure, 0 = not inserted, 1 = inserted, 2 = was present */
+  insert = 0;
+  if (rn->head == NULL)
+  {
+    /* empty list, add first node */
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc empty list objid==%"S32_F"\n",objid));
+    nn = snmp_mib_ln_alloc(objid);
+    if (nn != NULL)
+    {
+      rn->head = nn;
+      rn->tail = nn;
+      *insn = nn;
+      insert = 1;
+    }
+    else
+    {
+      insert = -1;
+    }
+  }
+  else
+  {
+    struct mib_list_node *n;
+    /* at least one node is present */
+    n = rn->head;
+    while ((n != NULL) && (insert == 0))
+    {
+      if (n->objid == objid)
+      {
+        /* node is already there */
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("node already there objid==%"S32_F"\n",objid));
+        *insn = n;
+        insert = 2;
+      }
+      else if (n->objid < objid)
+      {
+        if (n->next == NULL)
+        {
+          /* alloc and insert at the tail */
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins tail objid==%"S32_F"\n",objid));
+          nn = snmp_mib_ln_alloc(objid);
+          if (nn != NULL)
+          {
+            nn->next = NULL;
+            nn->prev = n;
+            n->next = nn;
+            rn->tail = nn;
+            *insn = nn;
+            insert = 1;
+          }
+          else
+          {
+            /* insertion failure */
+            insert = -1;
+          }
+        }
+        else
+        {
+          /* there's more to explore: traverse list */
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("traverse list\n"));
+          n = n->next;
+        }
+      }
+      else
+      {
+        /* n->objid > objid */
+        /* alloc and insert between n->prev and n */
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins n->prev, objid==%"S32_F", n\n",objid));
+        nn = snmp_mib_ln_alloc(objid);
+        if (nn != NULL)
+        {
+          if (n->prev == NULL)
+          {
+            /* insert at the head */
+            nn->next = n;
+            nn->prev = NULL;
+            rn->head = nn;
+            n->prev = nn;
+          }
+          else
+          {
+            /* insert in the middle */
+            nn->next = n;
+            nn->prev = n->prev;
+            n->prev->next = nn;
+            n->prev = nn;
+          }
+          *insn = nn;
+          insert = 1;
+        }
+        else
+        {
+          /* insertion failure */
+          insert = -1;
+        }
+      }
+    }
+  }
+  if (insert == 1)
+  {
+    rn->count += 1;
+  }
+  LWIP_ASSERT("insert != 0",insert != 0);
+  return insert;
+}
+
+/**
+ * Finds node in idx list and returns deletion mark.
+ *
+ * @param rn points to the root node
+ * @param objid  is the object sub identifier
+ * @param fn returns pointer to found node
+ * @return 0 if not found, 1 if deletable,
+ *   2 can't delete (2 or more children), 3 not a list_node
+ */
+s8_t
+snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn)
+{
+  s8_t fc;
+  struct mib_list_node *n;
+
+  LWIP_ASSERT("rn != NULL",rn != NULL);
+  n = rn->head;
+  while ((n != NULL) && (n->objid != objid))
+  {
+    n = n->next;
+  }
+  if (n == NULL)
+  {
+    fc = 0;
+  }
+  else if (n->nptr == NULL)
+  {
+    /* leaf, can delete node */
+    fc = 1;
+  }
+  else
+  {
+    struct mib_list_rootnode *r;
+
+    if (n->nptr->node_type == MIB_NODE_LR)
+    {
+      r = (struct mib_list_rootnode *)n->nptr;
+      if (r->count > 1)
+      {
+        /* can't delete node */
+        fc = 2;
+      }
+      else
+      {
+        /* count <= 1, can delete node */
+        fc = 1;
+      }
+    }
+    else
+    {
+      /* other node type */
+      fc = 3;
+    }
+  }
+  *fn = n;
+  return fc;
+}
+
+/**
+ * Removes node from idx list
+ * if it has a single child left.
+ *
+ * @param rn points to the root node
+ * @param n points to the node to delete
+ * @return the nptr to be freed by caller
+ */
+struct mib_list_rootnode *
+snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n)
+{
+  struct mib_list_rootnode *next;
+
+  LWIP_ASSERT("rn != NULL",rn != NULL);
+  LWIP_ASSERT("n != NULL",n != NULL);
+
+  /* caller must remove this sub-tree */
+  next = (struct mib_list_rootnode*)(n->nptr);
+  rn->count -= 1;
+
+  if (n == rn->head)
+  {
+    rn->head = n->next;
+    if (n->next != NULL)
+    {
+      /* not last node, new list begin */
+      n->next->prev = NULL;
+    }
+  }
+  else if (n == rn->tail)
+  {
+    rn->tail = n->prev;
+    if (n->prev != NULL)
+    {
+      /* not last node, new list end */
+      n->prev->next = NULL;
+    }
+  }
+  else
+  {
+    /* node must be in the middle */
+    n->prev->next = n->next;
+    n->next->prev = n->prev;
+  }
+  LWIP_DEBUGF(SNMP_MIB_DEBUG,("free list objid==%"S32_F"\n",n->objid));
+  snmp_mib_ln_free(n);
+  if (rn->count == 0)
+  {
+    rn->head = NULL;
+    rn->tail = NULL;
+  }
+  return next;
+}
+
+
+
+/**
+ * Searches tree for the supplied (scalar?) object identifier.
+ *
+ * @param node points to the root of the tree ('.internet')
+ * @param ident_len the length of the supplied object identifier
+ * @param ident points to the array of sub identifiers
+ * @param np points to the found object instance (return)
+ * @return pointer to the requested parent (!) node if success, NULL otherwise
+ */
+struct mib_node *
+snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np)
+{
+  u8_t node_type, ext_level;
+
+  ext_level = 0;
+  LWIP_DEBUGF(SNMP_MIB_DEBUG,("node==%p *ident==%"S32_F"\n",(void*)node,*ident));
+  while (node != NULL)
+  {
+    node_type = node->node_type;
+    if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA))
+    {
+      struct mib_array_node *an;
+      u16_t i;
+
+      if (ident_len > 0)
+      {
+        /* array node (internal ROM or RAM, fixed length) */
+        an = (struct mib_array_node *)node;
+        i = 0;
+        while ((i < an->maxlength) && (an->objid[i] != *ident))
+        {
+          i++;
+        }
+        if (i < an->maxlength)
+        {
+          /* found it, if available proceed to child, otherwise inspect leaf */
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident));
+          if (an->nptr[i] == NULL)
+          {
+            /* a scalar leaf OR table,
+               inspect remaining instance number / table index */
+            np->ident_len = ident_len;
+            np->ident = ident;
+            return (struct mib_node*)an;
+          }
+          else
+          {
+            /* follow next child pointer */
+            ident++;
+            ident_len--;
+            node = an->nptr[i];
+          }
+        }
+        else
+        {
+          /* search failed, identifier mismatch (nosuchname) */
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed *ident==%"S32_F"\n",*ident));
+          return NULL;
+        }
+      }
+      else
+      {
+        /* search failed, short object identifier (nosuchname) */
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed, short object identifier\n"));
+        return NULL;
+      }
+    }
+    else if(node_type == MIB_NODE_LR)
+    {
+      struct mib_list_rootnode *lrn;
+      struct mib_list_node *ln;
+
+      if (ident_len > 0)
+      {
+        /* list root node (internal 'RAM', variable length) */
+        lrn = (struct mib_list_rootnode *)node;
+        ln = lrn->head;
+        /* iterate over list, head to tail */
+        while ((ln != NULL) && (ln->objid != *ident))
+        {
+          ln = ln->next;
+        }
+        if (ln != NULL)
+        {
+          /* found it, proceed to child */;
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident));
+          if (ln->nptr == NULL)
+          {
+            np->ident_len = ident_len;
+            np->ident = ident;
+            return (struct mib_node*)lrn;
+          }
+          else
+          {
+            /* follow next child pointer */
+            ident_len--;
+            ident++;
+            node = ln->nptr;
+          }
+        }
+        else
+        {
+          /* search failed */
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed *ident==%"S32_F"\n",*ident));
+          return NULL;
+        }
+      }
+      else
+      {
+        /* search failed, short object identifier (nosuchname) */
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed, short object identifier\n"));
+        return NULL;
+      }
+    }
+    else if(node_type == MIB_NODE_EX)
+    {
+      struct mib_external_node *en;
+      u16_t i, len;
+
+      if (ident_len > 0)
+      {
+        /* external node (addressing and access via functions) */
+        en = (struct mib_external_node *)node;
+
+        i = 0;
+        len = en->level_length(en->addr_inf,ext_level);
+        while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) != 0))
+        {
+          i++;
+        }
+        if (i < len)
+        {
+          s32_t debug_id;
+
+          en->get_objid(en->addr_inf,ext_level,i,&debug_id);
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid==%"S32_F" *ident==%"S32_F"\n",debug_id,*ident));
+          if ((ext_level + 1) == en->tree_levels)
+          {
+            np->ident_len = ident_len;
+            np->ident = ident;
+            return (struct mib_node*)en;
+          }
+          else
+          {
+            /* found it, proceed to child */
+            ident_len--;
+            ident++;
+            ext_level++;
+          }
+        }
+        else
+        {
+          /* search failed */
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed *ident==%"S32_F"\n",*ident));
+          return NULL;
+        }
+      }
+      else
+      {
+        /* search failed, short object identifier (nosuchname) */
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed, short object identifier\n"));
+        return NULL;
+      }
+    }
+    else if (node_type == MIB_NODE_SC)
+    {
+      mib_scalar_node *sn;
+
+      sn = (mib_scalar_node *)node;
+      if ((ident_len == 1) && (*ident == 0))
+      {
+        np->ident_len = ident_len;
+        np->ident = ident;
+        return (struct mib_node*)sn;
+      }
+      else
+      {
+        /* search failed, short object identifier (nosuchname) */
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, invalid object identifier length\n"));
+        return NULL;
+      }
+    }
+    else
+    {
+      /* unknown node_type */
+      LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node_type %"U16_F" unkown\n",(u16_t)node_type));
+      return NULL;
+    }
+  }
+  /* done, found nothing */
+  LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node==%p\n",(void*)node));
+  return NULL;
+}
+
+/**
+ * Test table for presence of at least one table entry.
+ */
+static u8_t
+empty_table(struct mib_node *node)
+{
+  u8_t node_type;
+  u8_t empty = 0;
+
+  if (node != NULL)
+  {
+    node_type = node->node_type;
+    if (node_type == MIB_NODE_LR)
+    {
+      struct mib_list_rootnode *lrn;
+      lrn = (struct mib_list_rootnode *)node;
+      if ((lrn->count == 0) || (lrn->head == NULL))
+      {
+        empty = 1;
+      }
+    }
+    else if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA))
+    {
+      struct mib_array_node *an;
+      an = (struct mib_array_node *)node;
+      if ((an->maxlength == 0) || (an->nptr == NULL))
+      {
+        empty = 1;
+      }
+    }
+    else if (node_type == MIB_NODE_EX)
+    {
+      struct mib_external_node *en;
+      en = (struct mib_external_node *)node;
+      if (en->tree_levels == 0)
+      {
+        empty = 1;
+      }
+    }
+  }
+  return empty;
+}
+
+/**
+ * Tree expansion.
+ */
+struct mib_node *
+snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret)
+{
+  u8_t node_type, ext_level, climb_tree;
+
+  ext_level = 0;
+  /* reset node stack */
+  node_stack_cnt = 0;
+  while (node != NULL)
+  {
+    climb_tree = 0;
+    node_type = node->node_type;
+    if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA))
+    {
+      struct mib_array_node *an;
+      u16_t i;
+
+      /* array node (internal ROM or RAM, fixed length) */
+      an = (struct mib_array_node *)node;
+      if (ident_len > 0)
+      {
+        i = 0;
+        while ((i < an->maxlength) && (an->objid[i] < *ident))
+        {
+          i++;
+        }
+        if (i < an->maxlength)
+        {
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident));
+          /* add identifier to oidret */
+          oidret->id[oidret->len] = an->objid[i];
+          (oidret->len)++;
+
+          if (an->nptr[i] == NULL)
+          {
+            LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n"));
+            /* leaf node (e.g. in a fixed size table) */
+            if (an->objid[i] > *ident)
+            {
+              return (struct mib_node*)an;
+            }
+            else if ((i + 1) < an->maxlength)
+            {
+              /* an->objid[i] == *ident */
+              (oidret->len)--;
+              oidret->id[oidret->len] = an->objid[i + 1];
+              (oidret->len)++;
+              return (struct mib_node*)an;
+            }
+            else
+            {
+              /* (i + 1) == an->maxlength */
+              (oidret->len)--;
+              climb_tree = 1;
+            }
+          }
+          else
+          {
+            u8_t j;
+            struct nse cur_node;
+
+            LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n"));
+            /* non-leaf, store right child ptr and id */
+            LWIP_ASSERT("i < 0xff", i < 0xff);
+            j = (u8_t)i + 1;
+            while ((j < an->maxlength) && (empty_table(an->nptr[j])))
+            {
+              j++;
+            }
+            if (j < an->maxlength)
+            {
+              cur_node.r_ptr = an->nptr[j];
+              cur_node.r_id = an->objid[j];
+              cur_node.r_nl = 0;
+            }
+            else
+            {
+              cur_node.r_ptr = NULL;
+            }
+            push_node(&cur_node);
+            if (an->objid[i] == *ident)
+            {
+              ident_len--;
+              ident++;
+            }
+            else
+            {
+              /* an->objid[i] < *ident */
+              ident_len = 0;
+            }
+            /* follow next child pointer */
+            node = an->nptr[i];
+          }
+        }
+        else
+        {
+          /* i == an->maxlength */
+          climb_tree = 1;
+        }
+      }
+      else
+      {
+        u8_t j;
+        /* ident_len == 0, complete with leftmost '.thing' */
+        j = 0;
+        while ((j < an->maxlength) && empty_table(an->nptr[j]))
+        {
+          j++;
+        }
+        if (j < an->maxlength)
+        {
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("left an->objid[j]==%"S32_F"\n",an->objid[j]));
+          oidret->id[oidret->len] = an->objid[j];
+          (oidret->len)++;
+          if (an->nptr[j] == NULL)
+          {
+            /* leaf node */
+            return (struct mib_node*)an;
+          }
+          else
+          {
+            /* no leaf, continue */
+            node = an->nptr[j];
+          }
+        }
+        else
+        {
+          /* j == an->maxlength */
+          climb_tree = 1;
+        }
+      }
+    }
+    else if(node_type == MIB_NODE_LR)
+    {
+      struct mib_list_rootnode *lrn;
+      struct mib_list_node *ln;
+
+      /* list root node (internal 'RAM', variable length) */
+      lrn = (struct mib_list_rootnode *)node;
+      if (ident_len > 0)
+      {
+        ln = lrn->head;
+        /* iterate over list, head to tail */
+        while ((ln != NULL) && (ln->objid < *ident))
+        {
+          ln = ln->next;
+        }
+        if (ln != NULL)
+        {
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident));
+          oidret->id[oidret->len] = ln->objid;
+          (oidret->len)++;
+          if (ln->nptr == NULL)
+          {
+            /* leaf node */
+            if (ln->objid > *ident)
+            {
+              return (struct mib_node*)lrn;
+            }
+            else if (ln->next != NULL)
+            {
+              /* ln->objid == *ident */
+              (oidret->len)--;
+              oidret->id[oidret->len] = ln->next->objid;
+              (oidret->len)++;
+              return (struct mib_node*)lrn;
+            }
+            else
+            {
+              /* ln->next == NULL */
+              (oidret->len)--;
+              climb_tree = 1;
+            }
+          }
+          else
+          {
+            struct mib_list_node *jn;
+            struct nse cur_node;
+
+            /* non-leaf, store right child ptr and id */
+            jn = ln->next;
+            while ((jn != NULL) && empty_table(jn->nptr))
+            {
+              jn = jn->next;
+            }
+            if (jn != NULL)
+            {
+              cur_node.r_ptr = jn->nptr;
+              cur_node.r_id = jn->objid;
+              cur_node.r_nl = 0;
+            }
+            else
+            {
+              cur_node.r_ptr = NULL;
+            }
+            push_node(&cur_node);
+            if (ln->objid == *ident)
+            {
+              ident_len--;
+              ident++;
+            }
+            else
+            {
+              /* ln->objid < *ident */
+              ident_len = 0;
+            }
+            /* follow next child pointer */
+            node = ln->nptr;
+          }
+
+        }
+        else
+        {
+          /* ln == NULL */
+          climb_tree = 1;
+        }
+      }
+      else
+      {
+        struct mib_list_node *jn;
+        /* ident_len == 0, complete with leftmost '.thing' */
+        jn = lrn->head;
+        while ((jn != NULL) && empty_table(jn->nptr))
+        {
+          jn = jn->next;
+        }
+        if (jn != NULL)
+        {
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("left jn->objid==%"S32_F"\n",jn->objid));
+          oidret->id[oidret->len] = jn->objid;
+          (oidret->len)++;
+          if (jn->nptr == NULL)
+          {
+            /* leaf node */
+            LWIP_DEBUGF(SNMP_MIB_DEBUG,("jn->nptr == NULL\n"));
+            return (struct mib_node*)lrn;
+          }
+          else
+          {
+            /* no leaf, continue */
+            node = jn->nptr;
+          }
+        }
+        else
+        {
+          /* jn == NULL */
+          climb_tree = 1;
+        }
+      }
+    }
+    else if(node_type == MIB_NODE_EX)
+    {
+      struct mib_external_node *en;
+      s32_t ex_id;
+
+      /* external node (addressing and access via functions) */
+      en = (struct mib_external_node *)node;
+      if (ident_len > 0)
+      {
+        u16_t i, len;
+
+        i = 0;
+        len = en->level_length(en->addr_inf,ext_level);
+        while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) < 0))
+        {
+          i++;
+        }
+        if (i < len)
+        {
+          /* add identifier to oidret */
+          en->get_objid(en->addr_inf,ext_level,i,&ex_id);
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,ex_id,*ident));
+          oidret->id[oidret->len] = ex_id;
+          (oidret->len)++;
+
+          if ((ext_level + 1) == en->tree_levels)
+          {
+            LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n"));
+            /* leaf node */
+            if (ex_id > *ident)
+            {
+              return (struct mib_node*)en;
+            }
+            else if ((i + 1) < len)
+            {
+              /* ex_id == *ident */
+              en->get_objid(en->addr_inf,ext_level,i + 1,&ex_id);
+              (oidret->len)--;
+              oidret->id[oidret->len] = ex_id;
+              (oidret->len)++;
+              return (struct mib_node*)en;
+            }
+            else
+            {
+              /* (i + 1) == len */
+              (oidret->len)--;
+              climb_tree = 1;
+            }
+          }
+          else
+          {
+            u8_t j;
+            struct nse cur_node;
+
+            LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n"));
+            /* non-leaf, store right child ptr and id */
+            LWIP_ASSERT("i < 0xff", i < 0xff);
+            j = (u8_t)i + 1;
+            if (j < len)
+            {
+              /* right node is the current external node */
+              cur_node.r_ptr = node;
+              en->get_objid(en->addr_inf,ext_level,j,&cur_node.r_id);
+              cur_node.r_nl = ext_level + 1;
+            }
+            else
+            {
+              cur_node.r_ptr = NULL;
+            }
+            push_node(&cur_node);
+            if (en->ident_cmp(en->addr_inf,ext_level,i,*ident) == 0)
+            {
+              ident_len--;
+              ident++;
+            }
+            else
+            {
+              /* external id < *ident */
+              ident_len = 0;
+            }
+            /* proceed to child */
+            ext_level++;
+          }
+        }
+        else
+        {
+          /* i == len (en->level_len()) */
+          climb_tree = 1;
+        }
+      }
+      else
+      {
+        /* ident_len == 0, complete with leftmost '.thing' */
+        en->get_objid(en->addr_inf,ext_level,0,&ex_id);
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("left en->objid==%"S32_F"\n",ex_id));
+        oidret->id[oidret->len] = ex_id;
+        (oidret->len)++;
+        if ((ext_level + 1) == en->tree_levels)
+        {
+          /* leaf node */
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("(ext_level + 1) == en->tree_levels\n"));
+          return (struct mib_node*)en;
+        }
+        else
+        {
+          /* no leaf, proceed to child */
+          ext_level++;
+        }
+      }
+    }
+    else if(node_type == MIB_NODE_SC)
+    {
+      mib_scalar_node *sn;
+
+      /* scalar node  */
+      sn = (mib_scalar_node *)node;
+      if (ident_len > 0)
+      {
+        /* at .0 */
+        climb_tree = 1;
+      }
+      else
+      {
+        /* ident_len == 0, complete object identifier */
+        oidret->id[oidret->len] = 0;
+        (oidret->len)++;
+        /* leaf node */
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("completed scalar leaf\n"));
+        return (struct mib_node*)sn;
+      }
+    }
+    else
+    {
+      /* unknown/unhandled node_type */
+      LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node_type %"U16_F" unkown\n",(u16_t)node_type));
+      return NULL;
+    }
+
+    if (climb_tree)
+    {
+      struct nse child;
+
+      /* find right child ptr */
+      child.r_ptr = NULL;
+      child.r_id = 0;
+      child.r_nl = 0;
+      while ((node_stack_cnt > 0) && (child.r_ptr == NULL))
+      {
+        pop_node(&child);
+        /* trim returned oid */
+        (oidret->len)--;
+      }
+      if (child.r_ptr != NULL)
+      {
+        /* incoming ident is useless beyond this point */
+        ident_len = 0;
+        oidret->id[oidret->len] = child.r_id;
+        oidret->len++;
+        node = child.r_ptr;
+        ext_level = child.r_nl;
+      }
+      else
+      {
+        /* tree ends here ... */
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed, tree ends here\n"));
+        return NULL;
+      }
+    }
+  }
+  /* done, found nothing */
+  LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node==%p\n",(void*)node));
+  return NULL;
+}
+
+/**
+ * Test object identifier for the iso.org.dod.internet prefix.
+ *
+ * @param ident_len the length of the supplied object identifier
+ * @param ident points to the array of sub identifiers
+ * @return 1 if it matches, 0 otherwise
+ */
+u8_t
+snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident)
+{
+  if ((ident_len > 3) &&
+      (ident[0] == 1) && (ident[1] == 3) &&
+      (ident[2] == 6) && (ident[3] == 1))
+  {
+    return 1;
+  }
+  else
+  {
+    return 0;
+  }
+}
+
+/**
+ * Expands object identifier to the iso.org.dod.internet
+ * prefix for use in getnext operation.
+ *
+ * @param ident_len the length of the supplied object identifier
+ * @param ident points to the array of sub identifiers
+ * @param oidret points to returned expanded object identifier
+ * @return 1 if it matches, 0 otherwise
+ *
+ * @note ident_len 0 is allowed, expanding to the first known object id!!
+ */
+u8_t
+snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret)
+{
+  const s32_t *prefix_ptr;
+  s32_t *ret_ptr;
+  u8_t i;
+
+  i = 0;
+  prefix_ptr = &prefix[0];
+  ret_ptr = &oidret->id[0];
+  ident_len = ((ident_len < 4)?ident_len:4);
+  while ((i < ident_len) && ((*ident) <= (*prefix_ptr)))
+  {
+    *ret_ptr++ = *prefix_ptr++;
+    ident++;
+    i++;
+  }
+  if (i == ident_len)
+  {
+    /* match, complete missing bits */
+    while (i < 4)
+    {
+      *ret_ptr++ = *prefix_ptr++;
+      i++;
+    }
+    oidret->len = i;
+    return 1;
+  }
+  else
+  {
+    /* i != ident_len */
+    return 0;
+  }
+}
+
+#endif /* LWIP_SNMP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/msg_in.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/msg_in.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/msg_in.c	(revision 164)
@@ -0,0 +1,1453 @@
+/**
+ * @file
+ * SNMP input message processing (RFC1157).
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/snmp.h"
+#include "lwip/snmp_asn1.h"
+#include "lwip/snmp_msg.h"
+#include "lwip/snmp_structs.h"
+#include "lwip/ip_addr.h"
+#include "lwip/memp.h"
+#include "lwip/udp.h"
+#include "lwip/stats.h"
+
+#include <string.h>
+
+/* public (non-static) constants */
+/** SNMP v1 == 0 */
+const s32_t snmp_version = 0;
+/** default SNMP community string */
+const char snmp_publiccommunity[7] = "public";
+
+/* statically allocated buffers for SNMP_CONCURRENT_REQUESTS */
+struct snmp_msg_pstat msg_input_list[SNMP_CONCURRENT_REQUESTS];
+/* UDP Protocol Control Block */
+struct udp_pcb *snmp1_pcb;
+
+static void snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port);
+static err_t snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat);
+static err_t snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat);
+
+
+/**
+ * Starts SNMP Agent.
+ * Allocates UDP pcb and binds it to IP_ADDR_ANY port 161.
+ */
+void
+snmp_init(void)
+{
+  struct snmp_msg_pstat *msg_ps;
+  u8_t i;
+
+  snmp1_pcb = udp_new();
+  if (snmp1_pcb != NULL)
+  {
+    udp_recv(snmp1_pcb, snmp_recv, (void *)SNMP_IN_PORT);
+    udp_bind(snmp1_pcb, IP_ADDR_ANY, SNMP_IN_PORT);
+  }
+  msg_ps = &msg_input_list[0];
+  for (i=0; i<SNMP_CONCURRENT_REQUESTS; i++)
+  {
+    msg_ps->state = SNMP_MSG_EMPTY;
+    msg_ps->error_index = 0;
+    msg_ps->error_status = SNMP_ES_NOERROR;
+    msg_ps++;
+  }
+  trap_msg.pcb = snmp1_pcb;
+
+#ifdef SNMP_PRIVATE_MIB_INIT
+  /* If defined, this must be a function-like define to initialize the
+   * private MIB after the stack has been initialized.
+   * The private MIB can also be initialized in tcpip_callback (or after
+   * the stack is initialized), this define is only for convenience. */
+  SNMP_PRIVATE_MIB_INIT();
+#endif /* SNMP_PRIVATE_MIB_INIT */
+
+  /* The coldstart trap will only be output
+     if our outgoing interface is up & configured  */
+  snmp_coldstart_trap();
+}
+
+static void
+snmp_error_response(struct snmp_msg_pstat *msg_ps, u8_t error)
+{
+  /* move names back from outvb to invb */
+  int v;
+  struct snmp_varbind *vbi = msg_ps->invb.head;
+  struct snmp_varbind *vbo = msg_ps->outvb.head;
+  for (v=0; v<msg_ps->vb_idx; v++) {
+    vbi->ident_len = vbo->ident_len;
+    vbo->ident_len = 0;
+    vbi->ident = vbo->ident;
+    vbo->ident = NULL;
+    vbi = vbi->next;
+    vbo = vbo->next;
+  }
+  /* free outvb */
+  snmp_varbind_list_free(&msg_ps->outvb);
+  /* we send invb back */
+  msg_ps->outvb = msg_ps->invb;
+  msg_ps->invb.head = NULL;
+  msg_ps->invb.tail = NULL;
+  msg_ps->invb.count = 0;
+  msg_ps->error_status = error;
+  /* error index must be 0 for error too big */
+  msg_ps->error_index = (error != SNMP_ES_TOOBIG) ? (1 + msg_ps->vb_idx) : 0;
+  snmp_send_response(msg_ps);
+  snmp_varbind_list_free(&msg_ps->outvb);
+  msg_ps->state = SNMP_MSG_EMPTY;
+}
+
+static void
+snmp_ok_response(struct snmp_msg_pstat *msg_ps)
+{
+  err_t err_ret;
+
+  err_ret = snmp_send_response(msg_ps);
+  if (err_ret == ERR_MEM)
+  {
+    /* serious memory problem, can't return tooBig */
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event = %"S32_F"\n",msg_ps->error_status));
+  }
+  /* free varbinds (if available) */
+  snmp_varbind_list_free(&msg_ps->invb);
+  snmp_varbind_list_free(&msg_ps->outvb);
+  msg_ps->state = SNMP_MSG_EMPTY;
+}
+
+/**
+ * Service an internal or external event for SNMP GET.
+ *
+ * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
+ * @param msg_ps points to the assosicated message process state
+ */
+static void
+snmp_msg_get_event(u8_t request_id, struct snmp_msg_pstat *msg_ps)
+{
+  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_get_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state));
+
+  if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
+  {
+    struct mib_external_node *en;
+    struct snmp_name_ptr np;
+
+    /* get_object_def() answer*/
+    en = msg_ps->ext_mib_node;
+    np = msg_ps->ext_name_ptr;
+
+    /* translate answer into a known lifeform */
+    en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
+    if ((msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) &&
+        (msg_ps->ext_object_def.access & MIB_ACCESS_READ))
+    {
+      msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE;
+      en->get_value_q(request_id, &msg_ps->ext_object_def);
+    }
+    else
+    {
+      en->get_object_def_pc(request_id, np.ident_len, np.ident);
+      /* search failed, object id points to unknown object (nosuchname) */
+      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+    }
+  }
+  else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE)
+  {
+    struct mib_external_node *en;
+    struct snmp_varbind *vb;
+
+    /* get_value() answer */
+    en = msg_ps->ext_mib_node;
+
+    /* allocate output varbind */
+    vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND);
+    if (vb != NULL)
+    {
+      vb->next = NULL;
+      vb->prev = NULL;
+
+      /* move name from invb to outvb */
+      vb->ident = msg_ps->vb_ptr->ident;
+      vb->ident_len = msg_ps->vb_ptr->ident_len;
+      /* ensure this memory is refereced once only */
+      msg_ps->vb_ptr->ident = NULL;
+      msg_ps->vb_ptr->ident_len = 0;
+
+      vb->value_type = msg_ps->ext_object_def.asn_type;
+      LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff);
+      vb->value_len = (u8_t)msg_ps->ext_object_def.v_len;
+      if (vb->value_len > 0)
+      {
+        LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE);
+        vb->value = memp_malloc(MEMP_SNMP_VALUE);
+        if (vb->value != NULL)
+        {
+          en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value);
+          snmp_varbind_tail_add(&msg_ps->outvb, vb);
+          /* search again (if vb_idx < msg_ps->invb.count) */
+          msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+          msg_ps->vb_idx += 1;
+        }
+        else
+        {
+          en->get_value_pc(request_id, &msg_ps->ext_object_def);
+          LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no variable space\n"));
+          msg_ps->vb_ptr->ident = vb->ident;
+          msg_ps->vb_ptr->ident_len = vb->ident_len;
+          memp_free(MEMP_SNMP_VARBIND, vb);
+          snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
+        }
+      }
+      else
+      {
+        /* vb->value_len == 0, empty value (e.g. empty string) */
+        en->get_value_a(request_id, &msg_ps->ext_object_def, 0, NULL);
+        vb->value = NULL;
+        snmp_varbind_tail_add(&msg_ps->outvb, vb);
+        /* search again (if vb_idx < msg_ps->invb.count) */
+        msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+        msg_ps->vb_idx += 1;
+      }
+    }
+    else
+    {
+      en->get_value_pc(request_id, &msg_ps->ext_object_def);
+      LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no outvb space\n"));
+      snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
+    }
+  }
+
+  while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
+         (msg_ps->vb_idx < msg_ps->invb.count))
+  {
+    struct mib_node *mn;
+    struct snmp_name_ptr np;
+
+    if (msg_ps->vb_idx == 0)
+    {
+      msg_ps->vb_ptr = msg_ps->invb.head;
+    }
+    else
+    {
+      msg_ps->vb_ptr = msg_ps->vb_ptr->next;
+    }
+    /** test object identifier for .iso.org.dod.internet prefix */
+    if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len,  msg_ps->vb_ptr->ident))
+    {
+      mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
+                             msg_ps->vb_ptr->ident + 4, &np);
+      if (mn != NULL)
+      {
+        if (mn->node_type == MIB_NODE_EX)
+        {
+          /* external object */
+          struct mib_external_node *en = (struct mib_external_node*)mn;
+
+          msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
+          /* save en && args in msg_ps!! */
+          msg_ps->ext_mib_node = en;
+          msg_ps->ext_name_ptr = np;
+
+          en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
+        }
+        else
+        {
+          /* internal object */
+          struct obj_def object_def;
+
+          msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
+          mn->get_object_def(np.ident_len, np.ident, &object_def);
+          if ((object_def.instance != MIB_OBJECT_NONE) &&
+            (object_def.access & MIB_ACCESS_READ))
+          {
+            mn = mn;
+          }
+          else
+          {
+            /* search failed, object id points to unknown object (nosuchname) */
+            mn =  NULL;
+          }
+          if (mn != NULL)
+          {
+            struct snmp_varbind *vb;
+
+            msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE;
+            /* allocate output varbind */
+            vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND);
+            if (vb != NULL)
+            {
+              vb->next = NULL;
+              vb->prev = NULL;
+
+              /* move name from invb to outvb */
+              vb->ident = msg_ps->vb_ptr->ident;
+              vb->ident_len = msg_ps->vb_ptr->ident_len;
+              /* ensure this memory is refereced once only */
+              msg_ps->vb_ptr->ident = NULL;
+              msg_ps->vb_ptr->ident_len = 0;
+
+              vb->value_type = object_def.asn_type;
+              LWIP_ASSERT("invalid length", object_def.v_len <= 0xff);
+              vb->value_len = (u8_t)object_def.v_len;
+              if (vb->value_len > 0)
+              {
+                LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low",
+                  vb->value_len <= SNMP_MAX_VALUE_SIZE);
+                vb->value = memp_malloc(MEMP_SNMP_VALUE);
+                if (vb->value != NULL)
+                {
+                  mn->get_value(&object_def, vb->value_len, vb->value);
+                  snmp_varbind_tail_add(&msg_ps->outvb, vb);
+                  msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+                  msg_ps->vb_idx += 1;
+                }
+                else
+                {
+                  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate variable space\n"));
+                  msg_ps->vb_ptr->ident = vb->ident;
+                  msg_ps->vb_ptr->ident_len = vb->ident_len;
+                  vb->ident = NULL;
+                  vb->ident_len = 0;
+                  memp_free(MEMP_SNMP_VARBIND, vb);
+                  snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
+                }
+              }
+              else
+              {
+                /* vb->value_len == 0, empty value (e.g. empty string) */
+                vb->value = NULL;
+                snmp_varbind_tail_add(&msg_ps->outvb, vb);
+                msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+                msg_ps->vb_idx += 1;
+              }
+            }
+            else
+            {
+              LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate outvb space\n"));
+              snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
+            }
+          }
+        }
+      }
+    }
+    else
+    {
+      mn = NULL;
+    }
+    if (mn == NULL)
+    {
+      /* mn == NULL, noSuchName */
+      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+    }
+  }
+  if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
+      (msg_ps->vb_idx == msg_ps->invb.count))
+  {
+    snmp_ok_response(msg_ps);
+  }
+}
+
+/**
+ * Service an internal or external event for SNMP GETNEXT.
+ *
+ * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
+ * @param msg_ps points to the assosicated message process state
+ */
+static void
+snmp_msg_getnext_event(u8_t request_id, struct snmp_msg_pstat *msg_ps)
+{
+  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state));
+
+  if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
+  {
+    struct mib_external_node *en;
+
+    /* get_object_def() answer*/
+    en = msg_ps->ext_mib_node;
+
+    /* translate answer into a known lifeform */
+    en->get_object_def_a(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1], &msg_ps->ext_object_def);
+    if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
+    {
+      msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE;
+      en->get_value_q(request_id, &msg_ps->ext_object_def);
+    }
+    else
+    {
+      en->get_object_def_pc(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1]);
+      /* search failed, object id points to unknown object (nosuchname) */
+      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+    }
+  }
+  else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE)
+  {
+    struct mib_external_node *en;
+    struct snmp_varbind *vb;
+
+    /* get_value() answer */
+    en = msg_ps->ext_mib_node;
+
+    LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff);
+    vb = snmp_varbind_alloc(&msg_ps->ext_oid,
+                            msg_ps->ext_object_def.asn_type,
+                            (u8_t)msg_ps->ext_object_def.v_len);
+    if (vb != NULL)
+    {
+      en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value);
+      snmp_varbind_tail_add(&msg_ps->outvb, vb);
+      msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+      msg_ps->vb_idx += 1;
+    }
+    else
+    {
+      en->get_value_pc(request_id, &msg_ps->ext_object_def);
+      LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: couldn't allocate outvb space\n"));
+      snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
+    }
+  }
+
+  while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
+         (msg_ps->vb_idx < msg_ps->invb.count))
+  {
+    struct mib_node *mn;
+    struct snmp_obj_id oid;
+
+    if (msg_ps->vb_idx == 0)
+    {
+      msg_ps->vb_ptr = msg_ps->invb.head;
+    }
+    else
+    {
+      msg_ps->vb_ptr = msg_ps->vb_ptr->next;
+    }
+    if (snmp_iso_prefix_expand(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident, &oid))
+    {
+      if (msg_ps->vb_ptr->ident_len > 3)
+      {
+        /* can offset ident_len and ident */
+        mn = snmp_expand_tree((struct mib_node*)&internet,
+                              msg_ps->vb_ptr->ident_len - 4,
+                              msg_ps->vb_ptr->ident + 4, &oid);
+      }
+      else
+      {
+        /* can't offset ident_len -4, ident + 4 */
+        mn = snmp_expand_tree((struct mib_node*)&internet, 0, NULL, &oid);
+      }
+    }
+    else
+    {
+      mn = NULL;
+    }
+    if (mn != NULL)
+    {
+      if (mn->node_type == MIB_NODE_EX)
+      {
+        /* external object */
+        struct mib_external_node *en = (struct mib_external_node*)mn;
+
+        msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
+        /* save en && args in msg_ps!! */
+        msg_ps->ext_mib_node = en;
+        msg_ps->ext_oid = oid;
+
+        en->get_object_def_q(en->addr_inf, request_id, 1, &oid.id[oid.len - 1]);
+      }
+      else
+      {
+        /* internal object */
+        struct obj_def object_def;
+        struct snmp_varbind *vb;
+
+        msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
+        mn->get_object_def(1, &oid.id[oid.len - 1], &object_def);
+
+        LWIP_ASSERT("invalid length", object_def.v_len <= 0xff);
+        vb = snmp_varbind_alloc(&oid, object_def.asn_type, (u8_t)object_def.v_len);
+        if (vb != NULL)
+        {
+          msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE;
+          mn->get_value(&object_def, object_def.v_len, vb->value);
+          snmp_varbind_tail_add(&msg_ps->outvb, vb);
+          msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+          msg_ps->vb_idx += 1;
+        }
+        else
+        {
+          LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv couldn't allocate outvb space\n"));
+          snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
+        }
+      }
+    }
+    if (mn == NULL)
+    {
+      /* mn == NULL, noSuchName */
+      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+    }
+  }
+  if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
+      (msg_ps->vb_idx == msg_ps->invb.count))
+  {
+    snmp_ok_response(msg_ps);
+  }
+}
+
+/**
+ * Service an internal or external event for SNMP SET.
+ *
+ * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
+ * @param msg_ps points to the assosicated message process state
+ */
+static void
+snmp_msg_set_event(u8_t request_id, struct snmp_msg_pstat *msg_ps)
+{
+  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_set_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state));
+
+  if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
+  {
+    struct mib_external_node *en;
+    struct snmp_name_ptr np;
+
+    /* get_object_def() answer*/
+    en = msg_ps->ext_mib_node;
+    np = msg_ps->ext_name_ptr;
+
+    /* translate answer into a known lifeform */
+    en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
+    if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
+    {
+      msg_ps->state = SNMP_MSG_EXTERNAL_SET_TEST;
+      en->set_test_q(request_id, &msg_ps->ext_object_def);
+    }
+    else
+    {
+      en->get_object_def_pc(request_id, np.ident_len, np.ident);
+      /* search failed, object id points to unknown object (nosuchname) */
+      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+    }
+  }
+  else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_TEST)
+  {
+    struct mib_external_node *en;
+
+    /* set_test() answer*/
+    en = msg_ps->ext_mib_node;
+
+    if (msg_ps->ext_object_def.access & MIB_ACCESS_WRITE)
+    {
+       if ((msg_ps->ext_object_def.asn_type == msg_ps->vb_ptr->value_type) &&
+           (en->set_test_a(request_id,&msg_ps->ext_object_def,
+                           msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0))
+      {
+        msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+        msg_ps->vb_idx += 1;
+      }
+      else
+      {
+        en->set_test_pc(request_id,&msg_ps->ext_object_def);
+        /* bad value */
+        snmp_error_response(msg_ps,SNMP_ES_BADVALUE);
+      }
+    }
+    else
+    {
+      en->set_test_pc(request_id,&msg_ps->ext_object_def);
+      /* object not available for set */
+      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+    }
+  }
+  else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF_S)
+  {
+    struct mib_external_node *en;
+    struct snmp_name_ptr np;
+
+    /* get_object_def() answer*/
+    en = msg_ps->ext_mib_node;
+    np = msg_ps->ext_name_ptr;
+
+    /* translate answer into a known lifeform */
+    en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
+    if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
+    {
+      msg_ps->state = SNMP_MSG_EXTERNAL_SET_VALUE;
+      en->set_value_q(request_id, &msg_ps->ext_object_def,
+                      msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value);
+    }
+    else
+    {
+      en->get_object_def_pc(request_id, np.ident_len, np.ident);
+      /* set_value failed, object has disappeared for some odd reason?? */
+      snmp_error_response(msg_ps,SNMP_ES_GENERROR);
+    }
+  }
+  else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_VALUE)
+  {
+    struct mib_external_node *en;
+
+    /** set_value_a() */
+    en = msg_ps->ext_mib_node;
+    en->set_value_a(request_id, &msg_ps->ext_object_def,
+      msg_ps->vb_ptr->value_len, msg_ps->vb_ptr->value);
+
+    /** @todo use set_value_pc() if toobig */
+    msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
+    msg_ps->vb_idx += 1;
+  }
+
+  /* test all values before setting */
+  while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
+         (msg_ps->vb_idx < msg_ps->invb.count))
+  {
+    struct mib_node *mn;
+    struct snmp_name_ptr np;
+
+    if (msg_ps->vb_idx == 0)
+    {
+      msg_ps->vb_ptr = msg_ps->invb.head;
+    }
+    else
+    {
+      msg_ps->vb_ptr = msg_ps->vb_ptr->next;
+    }
+    /** test object identifier for .iso.org.dod.internet prefix */
+    if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len,  msg_ps->vb_ptr->ident))
+    {
+      mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
+                             msg_ps->vb_ptr->ident + 4, &np);
+      if (mn != NULL)
+      {
+        if (mn->node_type == MIB_NODE_EX)
+        {
+          /* external object */
+          struct mib_external_node *en = (struct mib_external_node*)mn;
+
+          msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
+          /* save en && args in msg_ps!! */
+          msg_ps->ext_mib_node = en;
+          msg_ps->ext_name_ptr = np;
+
+          en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
+        }
+        else
+        {
+          /* internal object */
+          struct obj_def object_def;
+
+          msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
+          mn->get_object_def(np.ident_len, np.ident, &object_def);
+          if (object_def.instance != MIB_OBJECT_NONE)
+          {
+            mn = mn;
+          }
+          else
+          {
+            /* search failed, object id points to unknown object (nosuchname) */
+            mn = NULL;
+          }
+          if (mn != NULL)
+          {
+            msg_ps->state = SNMP_MSG_INTERNAL_SET_TEST;
+
+            if (object_def.access & MIB_ACCESS_WRITE)
+            {
+              if ((object_def.asn_type == msg_ps->vb_ptr->value_type) &&
+                  (mn->set_test(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0))
+              {
+                msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+                msg_ps->vb_idx += 1;
+              }
+              else
+              {
+                /* bad value */
+                snmp_error_response(msg_ps,SNMP_ES_BADVALUE);
+              }
+            }
+            else
+            {
+              /* object not available for set */
+              snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+            }
+          }
+        }
+      }
+    }
+    else
+    {
+      mn = NULL;
+    }
+    if (mn == NULL)
+    {
+      /* mn == NULL, noSuchName */
+      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+    }
+  }
+
+  if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
+      (msg_ps->vb_idx == msg_ps->invb.count))
+  {
+    msg_ps->vb_idx = 0;
+    msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
+  }
+
+  /* set all values "atomically" (be as "atomic" as possible) */
+  while ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) &&
+         (msg_ps->vb_idx < msg_ps->invb.count))
+  {
+    struct mib_node *mn;
+    struct snmp_name_ptr np;
+
+    if (msg_ps->vb_idx == 0)
+    {
+      msg_ps->vb_ptr = msg_ps->invb.head;
+    }
+    else
+    {
+      msg_ps->vb_ptr = msg_ps->vb_ptr->next;
+    }
+    /* skip iso prefix test, was done previously while settesting() */
+    mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
+                           msg_ps->vb_ptr->ident + 4, &np);
+    /* check if object is still available
+       (e.g. external hot-plug thingy present?) */
+    if (mn != NULL)
+    {
+      if (mn->node_type == MIB_NODE_EX)
+      {
+        /* external object */
+        struct mib_external_node *en = (struct mib_external_node*)mn;
+
+        msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF_S;
+        /* save en && args in msg_ps!! */
+        msg_ps->ext_mib_node = en;
+        msg_ps->ext_name_ptr = np;
+
+        en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
+      }
+      else
+      {
+        /* internal object */
+        struct obj_def object_def;
+
+        msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF_S;
+        mn->get_object_def(np.ident_len, np.ident, &object_def);
+        msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
+        mn->set_value(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value);
+        msg_ps->vb_idx += 1;
+      }
+    }
+  }
+  if ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) &&
+      (msg_ps->vb_idx == msg_ps->invb.count))
+  {
+    /* simply echo the input if we can set it
+       @todo do we need to return the actual value?
+       e.g. if value is silently modified or behaves sticky? */
+    msg_ps->outvb = msg_ps->invb;
+    msg_ps->invb.head = NULL;
+    msg_ps->invb.tail = NULL;
+    msg_ps->invb.count = 0;
+    snmp_ok_response(msg_ps);
+  }
+}
+
+
+/**
+ * Handle one internal or external event.
+ * Called for one async event. (recv external/private answer)
+ *
+ * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
+ */
+void
+snmp_msg_event(u8_t request_id)
+{
+  struct snmp_msg_pstat *msg_ps;
+
+  if (request_id < SNMP_CONCURRENT_REQUESTS)
+  {
+    msg_ps = &msg_input_list[request_id];
+    if (msg_ps->rt == SNMP_ASN1_PDU_GET_NEXT_REQ)
+    {
+      snmp_msg_getnext_event(request_id, msg_ps);
+    }
+    else if (msg_ps->rt == SNMP_ASN1_PDU_GET_REQ)
+    {
+      snmp_msg_get_event(request_id, msg_ps);
+    }
+    else if(msg_ps->rt == SNMP_ASN1_PDU_SET_REQ)
+    {
+      snmp_msg_set_event(request_id, msg_ps);
+    }
+  }
+}
+
+
+/* lwIP UDP receive callback function */
+static void
+snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
+{
+  struct snmp_msg_pstat *msg_ps;
+  u8_t req_idx;
+  err_t err_ret;
+  u16_t payload_len = p->tot_len;
+  u16_t payload_ofs = 0;
+  u16_t varbind_ofs = 0;
+
+  /* suppress unused argument warning */
+  LWIP_UNUSED_ARG(arg);
+
+  /* traverse input message process list, look for SNMP_MSG_EMPTY */
+  msg_ps = &msg_input_list[0];
+  req_idx = 0;
+  while ((req_idx < SNMP_CONCURRENT_REQUESTS) && (msg_ps->state != SNMP_MSG_EMPTY))
+  {
+    req_idx++;
+    msg_ps++;
+  }
+  if (req_idx == SNMP_CONCURRENT_REQUESTS)
+  {
+    /* exceeding number of concurrent requests */
+    pbuf_free(p);
+    return;
+  }
+
+  /* accepting request */
+  snmp_inc_snmpinpkts();
+  /* record used 'protocol control block' */
+  msg_ps->pcb = pcb;
+  /* source address (network order) */
+  msg_ps->sip = *addr;
+  /* source port (host order (lwIP oddity)) */
+  msg_ps->sp = port;
+
+  /* check total length, version, community, pdu type */
+  err_ret = snmp_pdu_header_check(p, payload_ofs, payload_len, &varbind_ofs, msg_ps);
+  /* Only accept requests and requests without error (be robust) */
+  /* Reject response and trap headers or error requests as input! */
+  if ((err_ret != ERR_OK) ||
+      ((msg_ps->rt != SNMP_ASN1_PDU_GET_REQ) &&
+       (msg_ps->rt != SNMP_ASN1_PDU_GET_NEXT_REQ) &&
+       (msg_ps->rt != SNMP_ASN1_PDU_SET_REQ)) ||
+      ((msg_ps->error_status != SNMP_ES_NOERROR) ||
+       (msg_ps->error_index != 0)) )
+  {
+    /* header check failed drop request silently, do not return error! */
+    pbuf_free(p);
+    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_header_check() failed\n"));
+    return;
+  }
+  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv ok, community %s\n", msg_ps->community));
+
+  /* Builds a list of variable bindings. Copy the varbinds from the pbuf
+    chain to glue them when these are divided over two or more pbuf's. */
+  err_ret = snmp_pdu_dec_varbindlist(p, varbind_ofs, &varbind_ofs, msg_ps);
+  /* we've decoded the incoming message, release input msg now */
+  pbuf_free(p);
+  if ((err_ret != ERR_OK) || (msg_ps->invb.count == 0))
+  {
+    /* varbind-list decode failed, or varbind list empty.
+       drop request silently, do not return error!
+       (errors are only returned for a specific varbind failure) */
+    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_dec_varbindlist() failed\n"));
+    return;
+  }
+
+  msg_ps->error_status = SNMP_ES_NOERROR;
+  msg_ps->error_index = 0;
+  /* find object for each variable binding */
+  msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+  /* first variable binding from list to inspect */
+  msg_ps->vb_idx = 0;
+
+  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv varbind cnt=%"U16_F"\n",(u16_t)msg_ps->invb.count));
+
+  /* handle input event and as much objects as possible in one go */
+  snmp_msg_event(req_idx);
+}
+
+/**
+ * Checks and decodes incoming SNMP message header, logs header errors.
+ *
+ * @param p points to pbuf chain of SNMP message (UDP payload)
+ * @param ofs points to first octet of SNMP message
+ * @param pdu_len the length of the UDP payload
+ * @param ofs_ret returns the ofset of the variable bindings
+ * @param m_stat points to the current message request state return
+ * @return
+ * - ERR_OK SNMP header is sane and accepted
+ * - ERR_ARG SNMP header is either malformed or rejected
+ */
+static err_t
+snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat)
+{
+  err_t derr;
+  u16_t len, ofs_base;
+  u8_t  len_octets;
+  u8_t  type;
+  s32_t version;
+
+  ofs_base = ofs;
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+  if ((derr != ERR_OK) ||
+      (pdu_len != (1 + len_octets + len)) ||
+      (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)))
+  {
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  ofs += (1 + len_octets);
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
+  {
+    /* can't decode or no integer (version) */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &version);
+  if (derr != ERR_OK)
+  {
+    /* can't decode */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  if (version != 0)
+  {
+    /* not version 1 */
+    snmp_inc_snmpinbadversions();
+    return ERR_ARG;
+  }
+  ofs += (1 + len_octets + len);
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)))
+  {
+    /* can't decode or no octet string (community) */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, SNMP_COMMUNITY_STR_LEN, m_stat->community);
+  if (derr != ERR_OK)
+  {
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  /* add zero terminator */
+  len = ((len < (SNMP_COMMUNITY_STR_LEN))?(len):(SNMP_COMMUNITY_STR_LEN));
+  m_stat->community[len] = 0;
+  m_stat->com_strlen = (u8_t)len;
+  if (strncmp(snmp_publiccommunity, (const char*)m_stat->community, SNMP_COMMUNITY_STR_LEN) != 0)
+  {
+    /** @todo: move this if we need to check more names */
+    snmp_inc_snmpinbadcommunitynames();
+    snmp_authfail_trap();
+    return ERR_ARG;
+  }
+  ofs += (1 + len_octets + len);
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+  if (derr != ERR_OK)
+  {
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  switch(type)
+  {
+    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_REQ):
+      /* GetRequest PDU */
+      snmp_inc_snmpingetrequests();
+      derr = ERR_OK;
+      break;
+    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_NEXT_REQ):
+      /* GetNextRequest PDU */
+      snmp_inc_snmpingetnexts();
+      derr = ERR_OK;
+      break;
+    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP):
+      /* GetResponse PDU */
+      snmp_inc_snmpingetresponses();
+      derr = ERR_ARG;
+      break;
+    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_SET_REQ):
+      /* SetRequest PDU */
+      snmp_inc_snmpinsetrequests();
+      derr = ERR_OK;
+      break;
+    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP):
+      /* Trap PDU */
+      snmp_inc_snmpintraps();
+      derr = ERR_ARG;
+      break;
+    default:
+      snmp_inc_snmpinasnparseerrs();
+      derr = ERR_ARG;
+      break;
+  }
+  if (derr != ERR_OK)
+  {
+    /* unsupported input PDU for this agent (no parse error) */
+    return ERR_ARG;
+  }
+  m_stat->rt = type & 0x1F;
+  ofs += (1 + len_octets);
+  if (len != (pdu_len - (ofs - ofs_base)))
+  {
+    /* decoded PDU length does not equal actual payload length */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
+  {
+    /* can't decode or no integer (request ID) */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->rid);
+  if (derr != ERR_OK)
+  {
+    /* can't decode */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  ofs += (1 + len_octets + len);
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
+  {
+    /* can't decode or no integer (error-status) */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  /* must be noError (0) for incoming requests.
+     log errors for mib-2 completeness and for debug purposes */
+  derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_status);
+  if (derr != ERR_OK)
+  {
+    /* can't decode */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  switch (m_stat->error_status)
+  {
+    case SNMP_ES_TOOBIG:
+      snmp_inc_snmpintoobigs();
+      break;
+    case SNMP_ES_NOSUCHNAME:
+      snmp_inc_snmpinnosuchnames();
+      break;
+    case SNMP_ES_BADVALUE:
+      snmp_inc_snmpinbadvalues();
+      break;
+    case SNMP_ES_READONLY:
+      snmp_inc_snmpinreadonlys();
+      break;
+    case SNMP_ES_GENERROR:
+      snmp_inc_snmpingenerrs();
+      break;
+  }
+  ofs += (1 + len_octets + len);
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
+  {
+    /* can't decode or no integer (error-index) */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  /* must be 0 for incoming requests.
+     decode anyway to catch bad integers (and dirty tricks) */
+  derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_index);
+  if (derr != ERR_OK)
+  {
+    /* can't decode */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  ofs += (1 + len_octets + len);
+  *ofs_ret = ofs;
+  return ERR_OK;
+}
+
+static err_t
+snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat)
+{
+  err_t derr;
+  u16_t len, vb_len;
+  u8_t  len_octets;
+  u8_t type;
+
+  /* variable binding list */
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &vb_len);
+  if ((derr != ERR_OK) ||
+      (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)))
+  {
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  ofs += (1 + len_octets);
+
+  /* start with empty list */
+  m_stat->invb.count = 0;
+  m_stat->invb.head = NULL;
+  m_stat->invb.tail = NULL;
+
+  while (vb_len > 0)
+  {
+    struct snmp_obj_id oid, oid_value;
+    struct snmp_varbind *vb;
+
+    snmp_asn1_dec_type(p, ofs, &type);
+    derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+    if ((derr != ERR_OK) ||
+        (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)) ||
+        (len == 0) || (len > vb_len))
+    {
+      snmp_inc_snmpinasnparseerrs();
+      /* free varbinds (if available) */
+      snmp_varbind_list_free(&m_stat->invb);
+      return ERR_ARG;
+    }
+    ofs += (1 + len_octets);
+    vb_len -= (1 + len_octets);
+
+    snmp_asn1_dec_type(p, ofs, &type);
+    derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+    if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)))
+    {
+      /* can't decode object name length */
+      snmp_inc_snmpinasnparseerrs();
+      /* free varbinds (if available) */
+      snmp_varbind_list_free(&m_stat->invb);
+      return ERR_ARG;
+    }
+    derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid);
+    if (derr != ERR_OK)
+    {
+      /* can't decode object name */
+      snmp_inc_snmpinasnparseerrs();
+      /* free varbinds (if available) */
+      snmp_varbind_list_free(&m_stat->invb);
+      return ERR_ARG;
+    }
+    ofs += (1 + len_octets + len);
+    vb_len -= (1 + len_octets + len);
+
+    snmp_asn1_dec_type(p, ofs, &type);
+    derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+    if (derr != ERR_OK)
+    {
+      /* can't decode object value length */
+      snmp_inc_snmpinasnparseerrs();
+      /* free varbinds (if available) */
+      snmp_varbind_list_free(&m_stat->invb);
+      return ERR_ARG;
+    }
+
+    switch (type)
+    {
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG):
+        vb = snmp_varbind_alloc(&oid, type, sizeof(s32_t));
+        if (vb != NULL)
+        {
+          s32_t *vptr = (s32_t*)vb->value;
+
+          derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, vptr);
+          snmp_varbind_tail_add(&m_stat->invb, vb);
+        }
+        else
+        {
+          derr = ERR_ARG;
+        }
+        break;
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER):
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE):
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS):
+        vb = snmp_varbind_alloc(&oid, type, sizeof(u32_t));
+        if (vb != NULL)
+        {
+          u32_t *vptr = (u32_t*)vb->value;
+
+          derr = snmp_asn1_dec_u32t(p, ofs + 1 + len_octets, len, vptr);
+          snmp_varbind_tail_add(&m_stat->invb, vb);
+        }
+        else
+        {
+          derr = ERR_ARG;
+        }
+        break;
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR):
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE):
+        LWIP_ASSERT("invalid length", len <= 0xff);
+        vb = snmp_varbind_alloc(&oid, type, (u8_t)len);
+        if (vb != NULL)
+        {
+          derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value);
+          snmp_varbind_tail_add(&m_stat->invb, vb);
+        }
+        else
+        {
+          derr = ERR_ARG;
+        }
+        break;
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL):
+        vb = snmp_varbind_alloc(&oid, type, 0);
+        if (vb != NULL)
+        {
+          snmp_varbind_tail_add(&m_stat->invb, vb);
+          derr = ERR_OK;
+        }
+        else
+        {
+          derr = ERR_ARG;
+        }
+        break;
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID):
+        derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid_value);
+        if (derr == ERR_OK)
+        {
+          vb = snmp_varbind_alloc(&oid, type, oid_value.len * sizeof(s32_t));
+          if (vb != NULL)
+          {
+            u8_t i = oid_value.len;
+            s32_t *vptr = (s32_t*)vb->value;
+
+            while(i > 0)
+            {
+              i--;
+              vptr[i] = oid_value.id[i];
+            }
+            snmp_varbind_tail_add(&m_stat->invb, vb);
+            derr = ERR_OK;
+          }
+          else
+          {
+            derr = ERR_ARG;
+          }
+        }
+        break;
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR):
+        if (len == 4)
+        {
+          /* must be exactly 4 octets! */
+          vb = snmp_varbind_alloc(&oid, type, 4);
+          if (vb != NULL)
+          {
+            derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value);
+            snmp_varbind_tail_add(&m_stat->invb, vb);
+          }
+          else
+          {
+            derr = ERR_ARG;
+          }
+        }
+        else
+        {
+          derr = ERR_ARG;
+        }
+        break;
+      default:
+        derr = ERR_ARG;
+        break;
+    }
+    if (derr != ERR_OK)
+    {
+      snmp_inc_snmpinasnparseerrs();
+      /* free varbinds (if available) */
+      snmp_varbind_list_free(&m_stat->invb);
+      return ERR_ARG;
+    }
+    ofs += (1 + len_octets + len);
+    vb_len -= (1 + len_octets + len);
+  }
+
+  if (m_stat->rt == SNMP_ASN1_PDU_SET_REQ)
+  {
+    snmp_add_snmpintotalsetvars(m_stat->invb.count);
+  }
+  else
+  {
+    snmp_add_snmpintotalreqvars(m_stat->invb.count);
+  }
+
+  *ofs_ret = ofs;
+  return ERR_OK;
+}
+
+struct snmp_varbind*
+snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len)
+{
+  struct snmp_varbind *vb;
+
+  vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND);
+  if (vb != NULL)
+  {
+    u8_t i;
+
+    vb->next = NULL;
+    vb->prev = NULL;
+    i = oid->len;
+    vb->ident_len = i;
+    if (i > 0)
+    {
+      LWIP_ASSERT("SNMP_MAX_TREE_DEPTH is configured too low", i <= SNMP_MAX_TREE_DEPTH);
+      /* allocate array of s32_t for our object identifier */
+      vb->ident = (s32_t*)memp_malloc(MEMP_SNMP_VALUE);
+      if (vb->ident == NULL)
+      {
+        LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate ident value space\n"));
+        memp_free(MEMP_SNMP_VARBIND, vb);
+        return NULL;
+      }
+      while(i > 0)
+      {
+        i--;
+        vb->ident[i] = oid->id[i];
+      }
+    }
+    else
+    {
+      /* i == 0, pass zero length object identifier */
+      vb->ident = NULL;
+    }
+    vb->value_type = type;
+    vb->value_len = len;
+    if (len > 0)
+    {
+      LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE);
+      /* allocate raw bytes for our object value */
+      vb->value = memp_malloc(MEMP_SNMP_VALUE);
+      if (vb->value == NULL)
+      {
+        LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate value space\n"));
+        if (vb->ident != NULL)
+        {
+          memp_free(MEMP_SNMP_VALUE, vb->ident);
+        }
+        memp_free(MEMP_SNMP_VARBIND, vb);
+        return NULL;
+      }
+    }
+    else
+    {
+      /* ASN1_NUL type, or zero length ASN1_OC_STR */
+      vb->value = NULL;
+    }
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate varbind space\n"));
+  }
+  return vb;
+}
+
+void
+snmp_varbind_free(struct snmp_varbind *vb)
+{
+  if (vb->value != NULL )
+  {
+    memp_free(MEMP_SNMP_VALUE, vb->value);
+  }
+  if (vb->ident != NULL )
+  {
+    memp_free(MEMP_SNMP_VALUE, vb->ident);
+  }
+  memp_free(MEMP_SNMP_VARBIND, vb);
+}
+
+void
+snmp_varbind_list_free(struct snmp_varbind_root *root)
+{
+  struct snmp_varbind *vb, *prev;
+
+  vb = root->tail;
+  while ( vb != NULL )
+  {
+    prev = vb->prev;
+    snmp_varbind_free(vb);
+    vb = prev;
+  }
+  root->count = 0;
+  root->head = NULL;
+  root->tail = NULL;
+}
+
+void
+snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb)
+{
+  if (root->count == 0)
+  {
+    /* add first varbind to list */
+    root->head = vb;
+    root->tail = vb;
+  }
+  else
+  {
+    /* add nth varbind to list tail */
+    root->tail->next = vb;
+    vb->prev = root->tail;
+    root->tail = vb;
+  }
+  root->count += 1;
+}
+
+struct snmp_varbind*
+snmp_varbind_tail_remove(struct snmp_varbind_root *root)
+{
+  struct snmp_varbind* vb;
+
+  if (root->count > 0)
+  {
+    /* remove tail varbind */
+    vb = root->tail;
+    root->tail = vb->prev;
+    vb->prev->next = NULL;
+    root->count -= 1;
+  }
+  else
+  {
+    /* nothing to remove */
+    vb = NULL;
+  }
+  return vb;
+}
+
+#endif /* LWIP_SNMP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/msg_out.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/msg_out.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/snmp/msg_out.c	(revision 164)
@@ -0,0 +1,674 @@
+/**
+ * @file
+ * SNMP output message processing (RFC1157).
+ *
+ * Output responses and traps are build in two passes:
+ *
+ * Pass 0: iterate over the output message backwards to determine encoding lengths
+ * Pass 1: the actual forward encoding of internal form into ASN1
+ *
+ * The single-pass encoding method described by Comer & Stevens
+ * requires extra buffer space and copying for reversal of the packet.
+ * The buffer requirement can be prohibitively large for big payloads
+ * (>= 484) therefore we use the two encoding passes.
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/udp.h"
+#include "lwip/netif.h"
+#include "lwip/snmp.h"
+#include "lwip/snmp_asn1.h"
+#include "lwip/snmp_msg.h"
+
+struct snmp_trap_dst
+{
+  /* destination IP address in network order */
+  ip_addr_t dip;
+  /* set to 0 when disabled, >0 when enabled */
+  u8_t enable;
+};
+struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS];
+
+/** TRAP message structure */
+struct snmp_msg_trap trap_msg;
+
+static u16_t snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len);
+static u16_t snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len);
+static u16_t snmp_varbind_list_sum(struct snmp_varbind_root *root);
+
+static u16_t snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p);
+static u16_t snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p);
+static u16_t snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs);
+
+/**
+ * Sets enable switch for this trap destination.
+ * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1
+ * @param enable switch if 0 destination is disabled >0 enabled.
+ */
+void
+snmp_trap_dst_enable(u8_t dst_idx, u8_t enable)
+{
+  if (dst_idx < SNMP_TRAP_DESTINATIONS)
+  {
+    trap_dst[dst_idx].enable = enable;
+  }
+}
+
+/**
+ * Sets IPv4 address for this trap destination.
+ * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1
+ * @param dst IPv4 address in host order.
+ */
+void
+snmp_trap_dst_ip_set(u8_t dst_idx, ip_addr_t *dst)
+{
+  if (dst_idx < SNMP_TRAP_DESTINATIONS)
+  {
+    ip_addr_set(&trap_dst[dst_idx].dip, dst);
+  }
+}
+
+/**
+ * Sends a 'getresponse' message to the request originator.
+ *
+ * @param m_stat points to the current message request state source
+ * @return ERR_OK when success, ERR_MEM if we're out of memory
+ *
+ * @note the caller is responsible for filling in outvb in the m_stat
+ * and provide error-status and index (except for tooBig errors) ...
+ */
+err_t
+snmp_send_response(struct snmp_msg_pstat *m_stat)
+{
+  struct snmp_varbind_root emptyvb = {NULL, NULL, 0, 0, 0};
+  struct pbuf *p;
+  u16_t tot_len;
+  err_t err;
+
+  /* pass 0, calculate length fields */
+  tot_len = snmp_varbind_list_sum(&m_stat->outvb);
+  tot_len = snmp_resp_header_sum(m_stat, tot_len);
+
+  /* try allocating pbuf(s) for complete response */
+  p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL);
+  if (p == NULL)
+  {
+    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() tooBig\n"));
+
+    /* can't construct reply, return error-status tooBig */
+    m_stat->error_status = SNMP_ES_TOOBIG;
+    m_stat->error_index = 0;
+    /* pass 0, recalculate lengths, for empty varbind-list */
+    tot_len = snmp_varbind_list_sum(&emptyvb);
+    tot_len = snmp_resp_header_sum(m_stat, tot_len);
+    /* retry allocation once for header and empty varbind-list */
+    p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL);
+  }
+  if (p != NULL)
+  {
+    /* first pbuf alloc try or retry alloc success */
+    u16_t ofs;
+
+    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() p != NULL\n"));
+
+    /* pass 1, size error, encode packet ino the pbuf(s) */
+    ofs = snmp_resp_header_enc(m_stat, p);
+    snmp_varbind_list_enc(&m_stat->outvb, p, ofs);
+
+    switch (m_stat->error_status)
+    {
+      case SNMP_ES_TOOBIG:
+        snmp_inc_snmpouttoobigs();
+        break;
+      case SNMP_ES_NOSUCHNAME:
+        snmp_inc_snmpoutnosuchnames();
+        break;
+      case SNMP_ES_BADVALUE:
+        snmp_inc_snmpoutbadvalues();
+        break;
+      case SNMP_ES_GENERROR:
+        snmp_inc_snmpoutgenerrs();
+        break;
+    }
+    snmp_inc_snmpoutgetresponses();
+    snmp_inc_snmpoutpkts();
+
+    /** @todo do we need separate rx and tx pcbs for threaded case? */
+    /** connect to the originating source */
+    udp_connect(m_stat->pcb, &m_stat->sip, m_stat->sp);
+    err = udp_send(m_stat->pcb, p);
+    if (err == ERR_MEM)
+    {
+      /** @todo release some memory, retry and return tooBig? tooMuchHassle? */
+      err = ERR_MEM;
+    }
+    else
+    {
+      err = ERR_OK;
+    }
+    /** disassociate remote address and port with this pcb */
+    udp_disconnect(m_stat->pcb);
+
+    pbuf_free(p);
+    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() done\n"));
+    return err;
+  }
+  else
+  {
+    /* first pbuf alloc try or retry alloc failed
+       very low on memory, couldn't return tooBig */
+    return ERR_MEM;
+  }
+}
+
+
+/**
+ * Sends an generic or enterprise specific trap message.
+ *
+ * @param generic_trap is the trap code
+ * @param eoid points to enterprise object identifier
+ * @param specific_trap used for enterprise traps when generic_trap == 6
+ * @return ERR_OK when success, ERR_MEM if we're out of memory
+ *
+ * @note the caller is responsible for filling in outvb in the trap_msg
+ * @note the use of the enterpise identifier field
+ * is per RFC1215.
+ * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps
+ * and .iso.org.dod.internet.private.enterprises.yourenterprise
+ * (sysObjectID) for specific traps.
+ */
+err_t
+snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap)
+{
+  struct snmp_trap_dst *td;
+  struct netif *dst_if;
+  ip_addr_t dst_ip;
+  struct pbuf *p;
+  u16_t i,tot_len;
+
+  for (i=0, td = &trap_dst[0]; i<SNMP_TRAP_DESTINATIONS; i++, td++)
+  {
+    if ((td->enable != 0) && !ip_addr_isany(&td->dip))
+    {
+      /* network order trap destination */
+      ip_addr_copy(trap_msg.dip, td->dip);
+      /* lookup current source address for this dst */
+      dst_if = ip_route(&td->dip);
+      ip_addr_copy(dst_ip, dst_if->ip_addr);
+      /* @todo: what about IPv6? */
+      trap_msg.sip_raw[0] = ip4_addr1(&dst_ip);
+      trap_msg.sip_raw[1] = ip4_addr2(&dst_ip);
+      trap_msg.sip_raw[2] = ip4_addr3(&dst_ip);
+      trap_msg.sip_raw[3] = ip4_addr4(&dst_ip);
+      trap_msg.gen_trap = generic_trap;
+      trap_msg.spc_trap = specific_trap;
+      if (generic_trap == SNMP_GENTRAP_ENTERPRISESPC)
+      {
+        /* enterprise-Specific trap */
+        trap_msg.enterprise = eoid;
+      }
+      else
+      {
+        /* generic (MIB-II) trap */
+        snmp_get_snmpgrpid_ptr(&trap_msg.enterprise);
+      }
+      snmp_get_sysuptime(&trap_msg.ts);
+
+      /* pass 0, calculate length fields */
+      tot_len = snmp_varbind_list_sum(&trap_msg.outvb);
+      tot_len = snmp_trap_header_sum(&trap_msg, tot_len);
+
+      /* allocate pbuf(s) */
+      p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL);
+      if (p != NULL)
+      {
+        u16_t ofs;
+
+        /* pass 1, encode packet ino the pbuf(s) */
+        ofs = snmp_trap_header_enc(&trap_msg, p);
+        snmp_varbind_list_enc(&trap_msg.outvb, p, ofs);
+
+        snmp_inc_snmpouttraps();
+        snmp_inc_snmpoutpkts();
+
+        /** send to the TRAP destination */
+        udp_sendto(trap_msg.pcb, p, &trap_msg.dip, SNMP_TRAP_PORT);
+
+        pbuf_free(p);
+      }
+      else
+      {
+        return ERR_MEM;
+      }
+    }
+  }
+  return ERR_OK;
+}
+
+void
+snmp_coldstart_trap(void)
+{
+  trap_msg.outvb.head = NULL;
+  trap_msg.outvb.tail = NULL;
+  trap_msg.outvb.count = 0;
+  snmp_send_trap(SNMP_GENTRAP_COLDSTART, NULL, 0);
+}
+
+void
+snmp_authfail_trap(void)
+{
+  u8_t enable;
+  snmp_get_snmpenableauthentraps(&enable);
+  if (enable == 1)
+  {
+    trap_msg.outvb.head = NULL;
+    trap_msg.outvb.tail = NULL;
+    trap_msg.outvb.count = 0;
+    snmp_send_trap(SNMP_GENTRAP_AUTHFAIL, NULL, 0);
+  }
+}
+
+/**
+ * Sums response header field lengths from tail to head and
+ * returns resp_header_lengths for second encoding pass.
+ *
+ * @param vb_len varbind-list length
+ * @param rhl points to returned header lengths
+ * @return the required lenght for encoding the response header
+ */
+static u16_t
+snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len)
+{
+  u16_t tot_len;
+  struct snmp_resp_header_lengths *rhl;
+
+  rhl = &m_stat->rhl;
+  tot_len = vb_len;
+  snmp_asn1_enc_s32t_cnt(m_stat->error_index, &rhl->erridxlen);
+  snmp_asn1_enc_length_cnt(rhl->erridxlen, &rhl->erridxlenlen);
+  tot_len += 1 + rhl->erridxlenlen + rhl->erridxlen;
+
+  snmp_asn1_enc_s32t_cnt(m_stat->error_status, &rhl->errstatlen);
+  snmp_asn1_enc_length_cnt(rhl->errstatlen, &rhl->errstatlenlen);
+  tot_len += 1 + rhl->errstatlenlen + rhl->errstatlen;
+
+  snmp_asn1_enc_s32t_cnt(m_stat->rid, &rhl->ridlen);
+  snmp_asn1_enc_length_cnt(rhl->ridlen, &rhl->ridlenlen);
+  tot_len += 1 + rhl->ridlenlen + rhl->ridlen;
+
+  rhl->pdulen = tot_len;
+  snmp_asn1_enc_length_cnt(rhl->pdulen, &rhl->pdulenlen);
+  tot_len += 1 + rhl->pdulenlen;
+
+  rhl->comlen = m_stat->com_strlen;
+  snmp_asn1_enc_length_cnt(rhl->comlen, &rhl->comlenlen);
+  tot_len += 1 + rhl->comlenlen + rhl->comlen;
+
+  snmp_asn1_enc_s32t_cnt(snmp_version, &rhl->verlen);
+  snmp_asn1_enc_length_cnt(rhl->verlen, &rhl->verlenlen);
+  tot_len += 1 + rhl->verlen + rhl->verlenlen;
+
+  rhl->seqlen = tot_len;
+  snmp_asn1_enc_length_cnt(rhl->seqlen, &rhl->seqlenlen);
+  tot_len += 1 + rhl->seqlenlen;
+
+  return tot_len;
+}
+
+/**
+ * Sums trap header field lengths from tail to head and
+ * returns trap_header_lengths for second encoding pass.
+ *
+ * @param vb_len varbind-list length
+ * @param thl points to returned header lengths
+ * @return the required lenght for encoding the trap header
+ */
+static u16_t
+snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len)
+{
+  u16_t tot_len;
+  struct snmp_trap_header_lengths *thl;
+
+  thl = &m_trap->thl;
+  tot_len = vb_len;
+
+  snmp_asn1_enc_u32t_cnt(m_trap->ts, &thl->tslen);
+  snmp_asn1_enc_length_cnt(thl->tslen, &thl->tslenlen);
+  tot_len += 1 + thl->tslen + thl->tslenlen;
+
+  snmp_asn1_enc_s32t_cnt(m_trap->spc_trap, &thl->strplen);
+  snmp_asn1_enc_length_cnt(thl->strplen, &thl->strplenlen);
+  tot_len += 1 + thl->strplen + thl->strplenlen;
+
+  snmp_asn1_enc_s32t_cnt(m_trap->gen_trap, &thl->gtrplen);
+  snmp_asn1_enc_length_cnt(thl->gtrplen, &thl->gtrplenlen);
+  tot_len += 1 + thl->gtrplen + thl->gtrplenlen;
+
+  thl->aaddrlen = 4;
+  snmp_asn1_enc_length_cnt(thl->aaddrlen, &thl->aaddrlenlen);
+  tot_len += 1 + thl->aaddrlen + thl->aaddrlenlen;
+
+  snmp_asn1_enc_oid_cnt(m_trap->enterprise->len, &m_trap->enterprise->id[0], &thl->eidlen);
+  snmp_asn1_enc_length_cnt(thl->eidlen, &thl->eidlenlen);
+  tot_len += 1 + thl->eidlen + thl->eidlenlen;
+
+  thl->pdulen = tot_len;
+  snmp_asn1_enc_length_cnt(thl->pdulen, &thl->pdulenlen);
+  tot_len += 1 + thl->pdulenlen;
+
+  thl->comlen = sizeof(snmp_publiccommunity) - 1;
+  snmp_asn1_enc_length_cnt(thl->comlen, &thl->comlenlen);
+  tot_len += 1 + thl->comlenlen + thl->comlen;
+
+  snmp_asn1_enc_s32t_cnt(snmp_version, &thl->verlen);
+  snmp_asn1_enc_length_cnt(thl->verlen, &thl->verlenlen);
+  tot_len += 1 + thl->verlen + thl->verlenlen;
+
+  thl->seqlen = tot_len;
+  snmp_asn1_enc_length_cnt(thl->seqlen, &thl->seqlenlen);
+  tot_len += 1 + thl->seqlenlen;
+
+  return tot_len;
+}
+
+/**
+ * Sums varbind lengths from tail to head and
+ * annotates lengths in varbind for second encoding pass.
+ *
+ * @param root points to the root of the variable binding list
+ * @return the required lenght for encoding the variable bindings
+ */
+static u16_t
+snmp_varbind_list_sum(struct snmp_varbind_root *root)
+{
+  struct snmp_varbind *vb;
+  u32_t *uint_ptr;
+  s32_t *sint_ptr;
+  u16_t tot_len;
+
+  tot_len = 0;
+  vb = root->tail;
+  while ( vb != NULL )
+  {
+    /* encoded value lenght depends on type */
+    switch (vb->value_type)
+    {
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG):
+        sint_ptr = (s32_t*)vb->value;
+        snmp_asn1_enc_s32t_cnt(*sint_ptr, &vb->vlen);
+        break;
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER):
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE):
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS):
+        uint_ptr = (u32_t*)vb->value;
+        snmp_asn1_enc_u32t_cnt(*uint_ptr, &vb->vlen);
+        break;
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR):
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL):
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR):
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE):
+        vb->vlen = vb->value_len;
+        break;
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID):
+        sint_ptr = (s32_t*)vb->value;
+        snmp_asn1_enc_oid_cnt(vb->value_len / sizeof(s32_t), sint_ptr, &vb->vlen);
+        break;
+      default:
+        /* unsupported type */
+        vb->vlen = 0;
+        break;
+    };
+    /* encoding length of value length field */
+    snmp_asn1_enc_length_cnt(vb->vlen, &vb->vlenlen);
+    snmp_asn1_enc_oid_cnt(vb->ident_len, vb->ident, &vb->olen);
+    snmp_asn1_enc_length_cnt(vb->olen, &vb->olenlen);
+
+    vb->seqlen = 1 + vb->vlenlen + vb->vlen;
+    vb->seqlen += 1 + vb->olenlen + vb->olen;
+    snmp_asn1_enc_length_cnt(vb->seqlen, &vb->seqlenlen);
+
+    /* varbind seq */
+    tot_len += 1 + vb->seqlenlen + vb->seqlen;
+
+    vb = vb->prev;
+  }
+
+  /* varbind-list seq */
+  root->seqlen = tot_len;
+  snmp_asn1_enc_length_cnt(root->seqlen, &root->seqlenlen);
+  tot_len += 1 + root->seqlenlen;
+
+  return tot_len;
+}
+
+/**
+ * Encodes response header from head to tail.
+ */
+static u16_t
+snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p)
+{
+  u16_t ofs;
+
+  ofs = 0;
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_stat->rhl.seqlen);
+  ofs += m_stat->rhl.seqlenlen;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_stat->rhl.verlen);
+  ofs += m_stat->rhl.verlenlen;
+  snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.verlen, snmp_version);
+  ofs += m_stat->rhl.verlen;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_stat->rhl.comlen);
+  ofs += m_stat->rhl.comlenlen;
+  snmp_asn1_enc_raw(p, ofs, m_stat->rhl.comlen, m_stat->community);
+  ofs += m_stat->rhl.comlen;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_stat->rhl.pdulen);
+  ofs += m_stat->rhl.pdulenlen;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_stat->rhl.ridlen);
+  ofs += m_stat->rhl.ridlenlen;
+  snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.ridlen, m_stat->rid);
+  ofs += m_stat->rhl.ridlen;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_stat->rhl.errstatlen);
+  ofs += m_stat->rhl.errstatlenlen;
+  snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.errstatlen, m_stat->error_status);
+  ofs += m_stat->rhl.errstatlen;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_stat->rhl.erridxlen);
+  ofs += m_stat->rhl.erridxlenlen;
+  snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.erridxlen, m_stat->error_index);
+  ofs += m_stat->rhl.erridxlen;
+
+  return ofs;
+}
+
+/**
+ * Encodes trap header from head to tail.
+ */
+static u16_t
+snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p)
+{
+  u16_t ofs;
+
+  ofs = 0;
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_trap->thl.seqlen);
+  ofs += m_trap->thl.seqlenlen;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_trap->thl.verlen);
+  ofs += m_trap->thl.verlenlen;
+  snmp_asn1_enc_s32t(p, ofs, m_trap->thl.verlen, snmp_version);
+  ofs += m_trap->thl.verlen;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_trap->thl.comlen);
+  ofs += m_trap->thl.comlenlen;
+  snmp_asn1_enc_raw(p, ofs, m_trap->thl.comlen, (u8_t *)&snmp_publiccommunity[0]);
+  ofs += m_trap->thl.comlen;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_trap->thl.pdulen);
+  ofs += m_trap->thl.pdulenlen;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_trap->thl.eidlen);
+  ofs += m_trap->thl.eidlenlen;
+  snmp_asn1_enc_oid(p, ofs, m_trap->enterprise->len, &m_trap->enterprise->id[0]);
+  ofs += m_trap->thl.eidlen;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_trap->thl.aaddrlen);
+  ofs += m_trap->thl.aaddrlenlen;
+  snmp_asn1_enc_raw(p, ofs, m_trap->thl.aaddrlen, &m_trap->sip_raw[0]);
+  ofs += m_trap->thl.aaddrlen;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_trap->thl.gtrplen);
+  ofs += m_trap->thl.gtrplenlen;
+  snmp_asn1_enc_u32t(p, ofs, m_trap->thl.gtrplen, m_trap->gen_trap);
+  ofs += m_trap->thl.gtrplen;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_trap->thl.strplen);
+  ofs += m_trap->thl.strplenlen;
+  snmp_asn1_enc_u32t(p, ofs, m_trap->thl.strplen, m_trap->spc_trap);
+  ofs += m_trap->thl.strplen;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, m_trap->thl.tslen);
+  ofs += m_trap->thl.tslenlen;
+  snmp_asn1_enc_u32t(p, ofs, m_trap->thl.tslen, m_trap->ts);
+  ofs += m_trap->thl.tslen;
+
+  return ofs;
+}
+
+/**
+ * Encodes varbind list from head to tail.
+ */
+static u16_t
+snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs)
+{
+  struct snmp_varbind *vb;
+  s32_t *sint_ptr;
+  u32_t *uint_ptr;
+  u8_t *raw_ptr;
+
+  snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ));
+  ofs += 1;
+  snmp_asn1_enc_length(p, ofs, root->seqlen);
+  ofs += root->seqlenlen;
+
+  vb = root->head;
+  while ( vb != NULL )
+  {
+    snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ));
+    ofs += 1;
+    snmp_asn1_enc_length(p, ofs, vb->seqlen);
+    ofs += vb->seqlenlen;
+
+    snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID));
+    ofs += 1;
+    snmp_asn1_enc_length(p, ofs, vb->olen);
+    ofs += vb->olenlen;
+    snmp_asn1_enc_oid(p, ofs, vb->ident_len, &vb->ident[0]);
+    ofs += vb->olen;
+
+    snmp_asn1_enc_type(p, ofs, vb->value_type);
+    ofs += 1;
+    snmp_asn1_enc_length(p, ofs, vb->vlen);
+    ofs += vb->vlenlen;
+
+    switch (vb->value_type)
+    {
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG):
+        sint_ptr = (s32_t*)vb->value;
+        snmp_asn1_enc_s32t(p, ofs, vb->vlen, *sint_ptr);
+        break;
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER):
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE):
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS):
+        uint_ptr = (u32_t*)vb->value;
+        snmp_asn1_enc_u32t(p, ofs, vb->vlen, *uint_ptr);
+        break;
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR):
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR):
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE):
+        raw_ptr = (u8_t*)vb->value;
+        snmp_asn1_enc_raw(p, ofs, vb->vlen, raw_ptr);
+        break;
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL):
+        break;
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID):
+        sint_ptr = (s32_t*)vb->value;
+        snmp_asn1_enc_oid(p, ofs, vb->value_len / sizeof(s32_t), sint_ptr);
+        break;
+      default:
+        /* unsupported type */
+        break;
+    };
+    ofs += vb->vlen;
+    vb = vb->next;
+  }
+  return ofs;
+}
+
+#endif /* LWIP_SNMP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/stats.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/stats.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/stats.c	(revision 164)
@@ -0,0 +1,176 @@
+/**
+ * @file
+ * Statistics module
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_STATS /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/def.h"
+#include "lwip/stats.h"
+#include "lwip/mem.h"
+
+#include <string.h>
+
+struct stats_ lwip_stats;
+
+void stats_init(void)
+{
+#ifdef LWIP_DEBUG
+#if MEMP_STATS
+  const char * memp_names[] = {
+#define LWIP_MEMPOOL(name,num,size,desc) desc,
+#include "lwip/memp_std.h"
+  };
+  int i;
+  for (i = 0; i < MEMP_MAX; i++) {
+    lwip_stats.memp[i].name = memp_names[i];
+  }
+#endif /* MEMP_STATS */
+#if MEM_STATS
+  lwip_stats.mem.name = "MEM";
+#endif /* MEM_STATS */
+#endif /* LWIP_DEBUG */
+}
+
+#if LWIP_STATS_DISPLAY
+void
+stats_display_proto(struct stats_proto *proto, const char *name)
+{
+  LWIP_PLATFORM_DIAG(("\n%s\n\t", name));
+  LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", proto->xmit)); 
+  LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", proto->recv)); 
+  LWIP_PLATFORM_DIAG(("fw: %"STAT_COUNTER_F"\n\t", proto->fw)); 
+  LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", proto->drop)); 
+  LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", proto->chkerr)); 
+  LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", proto->lenerr)); 
+  LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", proto->memerr)); 
+  LWIP_PLATFORM_DIAG(("rterr: %"STAT_COUNTER_F"\n\t", proto->rterr)); 
+  LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", proto->proterr)); 
+  LWIP_PLATFORM_DIAG(("opterr: %"STAT_COUNTER_F"\n\t", proto->opterr)); 
+  LWIP_PLATFORM_DIAG(("err: %"STAT_COUNTER_F"\n\t", proto->err)); 
+  LWIP_PLATFORM_DIAG(("cachehit: %"STAT_COUNTER_F"\n", proto->cachehit)); 
+}
+
+#if IGMP_STATS
+void
+stats_display_igmp(struct stats_igmp *igmp)
+{
+  LWIP_PLATFORM_DIAG(("\nIGMP\n\t"));
+  LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", igmp->xmit)); 
+  LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", igmp->recv)); 
+  LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", igmp->drop)); 
+  LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", igmp->chkerr)); 
+  LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", igmp->lenerr)); 
+  LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", igmp->memerr)); 
+  LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", igmp->proterr)); 
+  LWIP_PLATFORM_DIAG(("rx_v1: %"STAT_COUNTER_F"\n\t", igmp->rx_v1)); 
+  LWIP_PLATFORM_DIAG(("rx_group: %"STAT_COUNTER_F"\n", igmp->rx_group));
+  LWIP_PLATFORM_DIAG(("rx_general: %"STAT_COUNTER_F"\n", igmp->rx_general));
+  LWIP_PLATFORM_DIAG(("rx_report: %"STAT_COUNTER_F"\n\t", igmp->rx_report)); 
+  LWIP_PLATFORM_DIAG(("tx_join: %"STAT_COUNTER_F"\n\t", igmp->tx_join)); 
+  LWIP_PLATFORM_DIAG(("tx_leave: %"STAT_COUNTER_F"\n\t", igmp->tx_leave)); 
+  LWIP_PLATFORM_DIAG(("tx_report: %"STAT_COUNTER_F"\n\t", igmp->tx_report)); 
+}
+#endif /* IGMP_STATS */
+
+#if MEM_STATS || MEMP_STATS
+void
+stats_display_mem(struct stats_mem *mem, const char *name)
+{
+  LWIP_PLATFORM_DIAG(("\nMEM %s\n\t", name));
+  LWIP_PLATFORM_DIAG(("avail: %"U32_F"\n\t", (u32_t)mem->avail)); 
+  LWIP_PLATFORM_DIAG(("used: %"U32_F"\n\t", (u32_t)mem->used)); 
+  LWIP_PLATFORM_DIAG(("max: %"U32_F"\n\t", (u32_t)mem->max)); 
+  LWIP_PLATFORM_DIAG(("err: %"U32_F"\n", (u32_t)mem->err));
+}
+
+#if MEMP_STATS
+void
+stats_display_memp(struct stats_mem *mem, int index)
+{
+  char * memp_names[] = {
+#define LWIP_MEMPOOL(name,num,size,desc) desc,
+#include "lwip/memp_std.h"
+  };
+  if(index < MEMP_MAX) {
+    stats_display_mem(mem, memp_names[index]);
+  }
+}
+#endif /* MEMP_STATS */
+#endif /* MEM_STATS || MEMP_STATS */
+
+#if SYS_STATS
+void
+stats_display_sys(struct stats_sys *sys)
+{
+  LWIP_PLATFORM_DIAG(("\nSYS\n\t"));
+  LWIP_PLATFORM_DIAG(("sem.used:  %"U32_F"\n\t", (u32_t)sys->sem.used)); 
+  LWIP_PLATFORM_DIAG(("sem.max:   %"U32_F"\n\t", (u32_t)sys->sem.max)); 
+  LWIP_PLATFORM_DIAG(("sem.err:   %"U32_F"\n\t", (u32_t)sys->sem.err)); 
+  LWIP_PLATFORM_DIAG(("mutex.used: %"U32_F"\n\t", (u32_t)sys->mutex.used)); 
+  LWIP_PLATFORM_DIAG(("mutex.max:  %"U32_F"\n\t", (u32_t)sys->mutex.max)); 
+  LWIP_PLATFORM_DIAG(("mutex.err:  %"U32_F"\n\t", (u32_t)sys->mutex.err)); 
+  LWIP_PLATFORM_DIAG(("mbox.used:  %"U32_F"\n\t", (u32_t)sys->mbox.used)); 
+  LWIP_PLATFORM_DIAG(("mbox.max:   %"U32_F"\n\t", (u32_t)sys->mbox.max)); 
+  LWIP_PLATFORM_DIAG(("mbox.err:   %"U32_F"\n\t", (u32_t)sys->mbox.err)); 
+}
+#endif /* SYS_STATS */
+
+void
+stats_display(void)
+{
+  s16_t i;
+
+  LINK_STATS_DISPLAY();
+  ETHARP_STATS_DISPLAY();
+  IPFRAG_STATS_DISPLAY();
+  IP_STATS_DISPLAY();
+  IGMP_STATS_DISPLAY();
+  ICMP_STATS_DISPLAY();
+  UDP_STATS_DISPLAY();
+  TCP_STATS_DISPLAY();
+  MEM_STATS_DISPLAY();
+  for (i = 0; i < MEMP_MAX; i++) {
+    MEMP_STATS_DISPLAY(i);
+  }
+  SYS_STATS_DISPLAY();
+}
+#endif /* LWIP_STATS_DISPLAY */
+
+#endif /* LWIP_STATS */
+
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/sys.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/sys.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/sys.c	(revision 164)
@@ -0,0 +1,68 @@
+/**
+ * @file
+ * lwIP Operating System abstraction
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/sys.h"
+
+/* Most of the functions defined in sys.h must be implemented in the
+ * architecture-dependent file sys_arch.c */
+
+#if !NO_SYS
+
+#ifndef sys_msleep
+/**
+ * Sleep for some ms. Timeouts are NOT processed while sleeping.
+ *
+ * @param ms number of milliseconds to sleep
+ */
+void
+sys_msleep(u32_t ms)
+{
+  if (ms > 0) {
+    sys_sem_t delaysem;
+    err_t err = sys_sem_new(&delaysem, 0);
+    if (err == ERR_OK) {
+      sys_arch_sem_wait(&delaysem, ms);
+      sys_sem_free(&delaysem);
+    }
+  }
+}
+#endif /* sys_msleep */
+
+#endif /* !NO_SYS */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/tcp.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/tcp.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/tcp.c	(revision 164)
@@ -0,0 +1,1742 @@
+/**
+ * @file
+ * Transmission Control Protocol for IP
+ *
+ * This file contains common functions for the TCP implementation, such as functinos
+ * for manipulating the data structures and the TCP timer functions. TCP functions
+ * related to input and output is found in tcp_in.c and tcp_out.c respectively.
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/snmp.h"
+#include "lwip/tcp.h"
+#include "lwip/tcp_impl.h"
+#include "lwip/debug.h"
+#include "lwip/stats.h"
+
+#include <string.h>
+
+#ifndef TCP_LOCAL_PORT_RANGE_START
+/* From http://www.iana.org/assignments/port-numbers:
+   "The Dynamic and/or Private Ports are those from 49152 through 65535" */
+#define TCP_LOCAL_PORT_RANGE_START        0xc000
+#define TCP_LOCAL_PORT_RANGE_END          0xffff
+#define TCP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START)
+#endif
+
+#if LWIP_TCP_KEEPALIVE
+#define TCP_KEEP_DUR(pcb)   ((pcb)->keep_cnt * (pcb)->keep_intvl)
+#define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl)
+#else /* LWIP_TCP_KEEPALIVE */
+#define TCP_KEEP_DUR(pcb)   TCP_MAXIDLE
+#define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT
+#endif /* LWIP_TCP_KEEPALIVE */
+
+const char * const tcp_state_str[] = {
+  "CLOSED",      
+  "LISTEN",      
+  "SYN_SENT",    
+  "SYN_RCVD",    
+  "ESTABLISHED", 
+  "FIN_WAIT_1",  
+  "FIN_WAIT_2",  
+  "CLOSE_WAIT",  
+  "CLOSING",     
+  "LAST_ACK",    
+  "TIME_WAIT"   
+};
+
+/* last local TCP port */
+static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START;
+
+/* Incremented every coarse grained timer shot (typically every 500 ms). */
+u32_t tcp_ticks;
+const u8_t tcp_backoff[13] =
+    { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
+ /* Times per slowtmr hits */
+const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 };
+
+/* The TCP PCB lists. */
+
+/** List of all TCP PCBs bound but not yet (connected || listening) */
+struct tcp_pcb *tcp_bound_pcbs;
+/** List of all TCP PCBs in LISTEN state */
+union tcp_listen_pcbs_t tcp_listen_pcbs;
+/** List of all TCP PCBs that are in a state in which
+ * they accept or send data. */
+struct tcp_pcb *tcp_active_pcbs;
+/** List of all TCP PCBs in TIME-WAIT state */
+struct tcp_pcb *tcp_tw_pcbs;
+
+#define NUM_TCP_PCB_LISTS               4
+#define NUM_TCP_PCB_LISTS_NO_TIME_WAIT  3
+/** An array with all (non-temporary) PCB lists, mainly used for smaller code size */
+struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs,
+  &tcp_active_pcbs, &tcp_tw_pcbs};
+
+/** Only used for temporary storage. */
+struct tcp_pcb *tcp_tmp_pcb;
+
+u8_t tcp_active_pcbs_changed;
+
+/** Timer counter to handle calling slow-timer from tcp_tmr() */ 
+static u8_t tcp_timer;
+static u8_t tcp_timer_ctr;
+static u16_t tcp_new_port(void);
+
+/**
+ * Initialize this module.
+ */
+void
+tcp_init(void)
+{
+#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND)
+  tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND());
+#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */
+}
+
+/**
+ * Called periodically to dispatch TCP timers.
+ */
+void
+tcp_tmr(void)
+{
+  /* Call tcp_fasttmr() every 250 ms */
+  tcp_fasttmr();
+
+  if (++tcp_timer & 1) {
+    /* Call tcp_tmr() every 500 ms, i.e., every other timer
+       tcp_tmr() is called. */
+    tcp_slowtmr();
+  }
+}
+
+/**
+ * Closes the TX side of a connection held by the PCB.
+ * For tcp_close(), a RST is sent if the application didn't receive all data
+ * (tcp_recved() not called for all data passed to recv callback).
+ *
+ * Listening pcbs are freed and may not be referenced any more.
+ * Connection pcbs are freed if not yet connected and may not be referenced
+ * any more. If a connection is established (at least SYN received or in
+ * a closing state), the connection is closed, and put in a closing state.
+ * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
+ * unsafe to reference it.
+ *
+ * @param pcb the tcp_pcb to close
+ * @return ERR_OK if connection has been closed
+ *         another err_t if closing failed and pcb is not freed
+ */
+static err_t
+tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
+{
+  err_t err;
+
+  if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) {
+    if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND)) {
+      /* Not all data received by application, send RST to tell the remote
+         side about this. */
+      LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED);
+
+      /* don't call tcp_abort here: we must not deallocate the pcb since
+         that might not be expected when calling tcp_close */
+      tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
+        pcb->local_port, pcb->remote_port);
+
+      tcp_pcb_purge(pcb);
+      TCP_RMV_ACTIVE(pcb);
+      if (pcb->state == ESTABLISHED) {
+        /* move to TIME_WAIT since we close actively */
+        pcb->state = TIME_WAIT;
+        TCP_REG(&tcp_tw_pcbs, pcb);
+      } else {
+        /* CLOSE_WAIT: deallocate the pcb since we already sent a RST for it */
+        memp_free(MEMP_TCP_PCB, pcb);
+      }
+      return ERR_OK;
+    }
+  }
+
+  switch (pcb->state) {
+  case CLOSED:
+    /* Closing a pcb in the CLOSED state might seem erroneous,
+     * however, it is in this state once allocated and as yet unused
+     * and the user needs some way to free it should the need arise.
+     * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
+     * or for a pcb that has been used and then entered the CLOSED state 
+     * is erroneous, but this should never happen as the pcb has in those cases
+     * been freed, and so any remaining handles are bogus. */
+    err = ERR_OK;
+    if (pcb->local_port != 0) {
+      TCP_RMV(&tcp_bound_pcbs, pcb);
+    }
+    memp_free(MEMP_TCP_PCB, pcb);
+    pcb = NULL;
+    break;
+  case LISTEN:
+    err = ERR_OK;
+    tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb);
+    memp_free(MEMP_TCP_PCB_LISTEN, pcb);
+    pcb = NULL;
+    break;
+  case SYN_SENT:
+    err = ERR_OK;
+    TCP_PCB_REMOVE_ACTIVE(pcb);
+    memp_free(MEMP_TCP_PCB, pcb);
+    pcb = NULL;
+    snmp_inc_tcpattemptfails();
+    break;
+  case SYN_RCVD:
+    err = tcp_send_fin(pcb);
+    if (err == ERR_OK) {
+      snmp_inc_tcpattemptfails();
+      pcb->state = FIN_WAIT_1;
+    }
+    break;
+  case ESTABLISHED:
+    err = tcp_send_fin(pcb);
+    if (err == ERR_OK) {
+      snmp_inc_tcpestabresets();
+      pcb->state = FIN_WAIT_1;
+    }
+    break;
+  case CLOSE_WAIT:
+    err = tcp_send_fin(pcb);
+    if (err == ERR_OK) {
+      snmp_inc_tcpestabresets();
+      pcb->state = LAST_ACK;
+    }
+    break;
+  default:
+    /* Has already been closed, do nothing. */
+    err = ERR_OK;
+    pcb = NULL;
+    break;
+  }
+
+  if (pcb != NULL && err == ERR_OK) {
+    /* To ensure all data has been sent when tcp_close returns, we have
+       to make sure tcp_output doesn't fail.
+       Since we don't really have to ensure all data has been sent when tcp_close
+       returns (unsent data is sent from tcp timer functions, also), we don't care
+       for the return value of tcp_output for now. */
+    /* @todo: When implementing SO_LINGER, this must be changed somehow:
+       If SOF_LINGER is set, the data should be sent and acked before close returns.
+       This can only be valid for sequential APIs, not for the raw API. */
+    tcp_output(pcb);
+  }
+  return err;
+}
+
+/**
+ * Closes the connection held by the PCB.
+ *
+ * Listening pcbs are freed and may not be referenced any more.
+ * Connection pcbs are freed if not yet connected and may not be referenced
+ * any more. If a connection is established (at least SYN received or in
+ * a closing state), the connection is closed, and put in a closing state.
+ * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
+ * unsafe to reference it (unless an error is returned).
+ *
+ * @param pcb the tcp_pcb to close
+ * @return ERR_OK if connection has been closed
+ *         another err_t if closing failed and pcb is not freed
+ */
+err_t
+tcp_close(struct tcp_pcb *pcb)
+{
+#if TCP_DEBUG
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in "));
+  tcp_debug_print_state(pcb->state);
+#endif /* TCP_DEBUG */
+
+  if (pcb->state != LISTEN) {
+    /* Set a flag not to receive any more data... */
+    pcb->flags |= TF_RXCLOSED;
+  }
+  /* ... and close */
+  return tcp_close_shutdown(pcb, 1);
+}
+
+/**
+ * Causes all or part of a full-duplex connection of this PCB to be shut down.
+ * This doesn't deallocate the PCB unless shutting down both sides!
+ * Shutting down both sides is the same as calling tcp_close, so if it succeds,
+ * the PCB should not be referenced any more.
+ *
+ * @param pcb PCB to shutdown
+ * @param shut_rx shut down receive side if this is != 0
+ * @param shut_tx shut down send side if this is != 0
+ * @return ERR_OK if shutdown succeeded (or the PCB has already been shut down)
+ *         another err_t on error.
+ */
+err_t
+tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx)
+{
+  if (pcb->state == LISTEN) {
+    return ERR_CONN;
+  }
+  if (shut_rx) {
+    /* shut down the receive side: set a flag not to receive any more data... */
+    pcb->flags |= TF_RXCLOSED;
+    if (shut_tx) {
+      /* shutting down the tx AND rx side is the same as closing for the raw API */
+      return tcp_close_shutdown(pcb, 1);
+    }
+    /* ... and free buffered data */
+    if (pcb->refused_data != NULL) {
+      pbuf_free(pcb->refused_data);
+      pcb->refused_data = NULL;
+    }
+  }
+  if (shut_tx) {
+    /* This can't happen twice since if it succeeds, the pcb's state is changed.
+       Only close in these states as the others directly deallocate the PCB */
+    switch (pcb->state) {
+    case SYN_RCVD:
+    case ESTABLISHED:
+    case CLOSE_WAIT:
+      return tcp_close_shutdown(pcb, shut_rx);
+    default:
+      /* Not (yet?) connected, cannot shutdown the TX side as that would bring us
+        into CLOSED state, where the PCB is deallocated. */
+      return ERR_CONN;
+    }
+  }
+  return ERR_OK;
+}
+
+/**
+ * Abandons a connection and optionally sends a RST to the remote
+ * host.  Deletes the local protocol control block. This is done when
+ * a connection is killed because of shortage of memory.
+ *
+ * @param pcb the tcp_pcb to abort
+ * @param reset boolean to indicate whether a reset should be sent
+ */
+void
+tcp_abandon(struct tcp_pcb *pcb, int reset)
+{
+  u32_t seqno, ackno;
+#if LWIP_CALLBACK_API  
+  tcp_err_fn errf;
+#endif /* LWIP_CALLBACK_API */
+  void *errf_arg;
+
+  /* pcb->state LISTEN not allowed here */
+  LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs",
+    pcb->state != LISTEN);
+  /* Figure out on which TCP PCB list we are, and remove us. If we
+     are in an active state, call the receive function associated with
+     the PCB with a NULL argument, and send an RST to the remote end. */
+  if (pcb->state == TIME_WAIT) {
+    tcp_pcb_remove(&tcp_tw_pcbs, pcb);
+    memp_free(MEMP_TCP_PCB, pcb);
+  } else {
+    seqno = pcb->snd_nxt;
+    ackno = pcb->rcv_nxt;
+#if LWIP_CALLBACK_API
+    errf = pcb->errf;
+#endif /* LWIP_CALLBACK_API */
+    errf_arg = pcb->callback_arg;
+    TCP_PCB_REMOVE_ACTIVE(pcb);
+    if (pcb->unacked != NULL) {
+      tcp_segs_free(pcb->unacked);
+    }
+    if (pcb->unsent != NULL) {
+      tcp_segs_free(pcb->unsent);
+    }
+#if TCP_QUEUE_OOSEQ    
+    if (pcb->ooseq != NULL) {
+      tcp_segs_free(pcb->ooseq);
+    }
+#endif /* TCP_QUEUE_OOSEQ */
+    if (reset) {
+      LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
+      tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port);
+    }
+    memp_free(MEMP_TCP_PCB, pcb);
+    TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);
+  }
+}
+
+/**
+ * Aborts the connection by sending a RST (reset) segment to the remote
+ * host. The pcb is deallocated. This function never fails.
+ *
+ * ATTENTION: When calling this from one of the TCP callbacks, make
+ * sure you always return ERR_ABRT (and never return ERR_ABRT otherwise
+ * or you will risk accessing deallocated memory or memory leaks!
+ *
+ * @param pcb the tcp pcb to abort
+ */
+void
+tcp_abort(struct tcp_pcb *pcb)
+{
+  tcp_abandon(pcb, 1);
+}
+
+/**
+ * Binds the connection to a local portnumber and IP address. If the
+ * IP address is not given (i.e., ipaddr == NULL), the IP address of
+ * the outgoing network interface is used instead.
+ *
+ * @param pcb the tcp_pcb to bind (no check is done whether this pcb is
+ *        already bound!)
+ * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind
+ *        to any local address
+ * @param port the local port to bind to
+ * @return ERR_USE if the port is already in use
+ *         ERR_VAL if bind failed because the PCB is not in a valid state
+ *         ERR_OK if bound
+ */
+err_t
+tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
+{
+  int i;
+  int max_pcb_list = NUM_TCP_PCB_LISTS;
+  struct tcp_pcb *cpcb;
+
+  LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL);
+
+#if SO_REUSE
+  /* Unless the REUSEADDR flag is set,
+     we have to check the pcbs in TIME-WAIT state, also.
+     We do not dump TIME_WAIT pcb's; they can still be matched by incoming
+     packets using both local and remote IP addresses and ports to distinguish.
+   */
+  if (ip_get_option(pcb, SOF_REUSEADDR)) {
+    max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT;
+  }
+#endif /* SO_REUSE */
+
+  if (port == 0) {
+    port = tcp_new_port();
+    if (port == 0) {
+      return ERR_BUF;
+    }
+  }
+
+  /* Check if the address already is in use (on all lists) */
+  for (i = 0; i < max_pcb_list; i++) {
+    for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
+      if (cpcb->local_port == port) {
+#if SO_REUSE
+        /* Omit checking for the same port if both pcbs have REUSEADDR set.
+           For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in
+           tcp_connect. */
+        if (!ip_get_option(pcb, SOF_REUSEADDR) ||
+            !ip_get_option(cpcb, SOF_REUSEADDR))
+#endif /* SO_REUSE */
+        {
+          if (ip_addr_isany(&(cpcb->local_ip)) ||
+              ip_addr_isany(ipaddr) ||
+              ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
+            return ERR_USE;
+          }
+        }
+      }
+    }
+  }
+
+  if (!ip_addr_isany(ipaddr)) {
+    pcb->local_ip = *ipaddr;
+  }
+  pcb->local_port = port;
+  TCP_REG(&tcp_bound_pcbs, pcb);
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));
+  return ERR_OK;
+}
+#if LWIP_CALLBACK_API
+/**
+ * Default accept callback if no accept callback is specified by the user.
+ */
+static err_t
+tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
+{
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(err);
+
+  return ERR_ABRT;
+}
+#endif /* LWIP_CALLBACK_API */
+
+/**
+ * Set the state of the connection to be LISTEN, which means that it
+ * is able to accept incoming connections. The protocol control block
+ * is reallocated in order to consume less memory. Setting the
+ * connection to LISTEN is an irreversible process.
+ *
+ * @param pcb the original tcp_pcb
+ * @param backlog the incoming connections queue limit
+ * @return tcp_pcb used for listening, consumes less memory.
+ *
+ * @note The original tcp_pcb is freed. This function therefore has to be
+ *       called like this:
+ *             tpcb = tcp_listen(tpcb);
+ */
+struct tcp_pcb *
+tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
+{
+  struct tcp_pcb_listen *lpcb;
+
+  LWIP_UNUSED_ARG(backlog);
+  LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL);
+
+  /* already listening? */
+  if (pcb->state == LISTEN) {
+    return pcb;
+  }
+#if SO_REUSE
+  if (ip_get_option(pcb, SOF_REUSEADDR)) {
+    /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage
+       is declared (listen-/connection-pcb), we have to make sure now that
+       this port is only used once for every local IP. */
+    for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
+      if (lpcb->local_port == pcb->local_port) {
+        if (ip_addr_cmp(&lpcb->local_ip, &pcb->local_ip)) {
+          /* this address/port is already used */
+          return NULL;
+        }
+      }
+    }
+  }
+#endif /* SO_REUSE */
+  lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN);
+  if (lpcb == NULL) {
+    return NULL;
+  }
+  lpcb->callback_arg = pcb->callback_arg;
+  lpcb->local_port = pcb->local_port;
+  lpcb->state = LISTEN;
+  lpcb->prio = pcb->prio;
+  lpcb->so_options = pcb->so_options;
+  ip_set_option(lpcb, SOF_ACCEPTCONN);
+  lpcb->ttl = pcb->ttl;
+  lpcb->tos = pcb->tos;
+  ip_addr_copy(lpcb->local_ip, pcb->local_ip);
+  if (pcb->local_port != 0) {
+    TCP_RMV(&tcp_bound_pcbs, pcb);
+  }
+  memp_free(MEMP_TCP_PCB, pcb);
+#if LWIP_CALLBACK_API
+  lpcb->accept = tcp_accept_null;
+#endif /* LWIP_CALLBACK_API */
+#if TCP_LISTEN_BACKLOG
+  lpcb->accepts_pending = 0;
+  lpcb->backlog = (backlog ? backlog : 1);
+#endif /* TCP_LISTEN_BACKLOG */
+  TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb);
+  return (struct tcp_pcb *)lpcb;
+}
+
+/** 
+ * Update the state that tracks the available window space to advertise.
+ *
+ * Returns how much extra window would be advertised if we sent an
+ * update now.
+ */
+u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)
+{
+  u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd;
+
+  if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) {
+    /* we can advertise more window */
+    pcb->rcv_ann_wnd = pcb->rcv_wnd;
+    return new_right_edge - pcb->rcv_ann_right_edge;
+  } else {
+    if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) {
+      /* Can happen due to other end sending out of advertised window,
+       * but within actual available (but not yet advertised) window */
+      pcb->rcv_ann_wnd = 0;
+    } else {
+      /* keep the right edge of window constant */
+      u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt;
+      LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff);
+      pcb->rcv_ann_wnd = (u16_t)new_rcv_ann_wnd;
+    }
+    return 0;
+  }
+}
+
+/**
+ * This function should be called by the application when it has
+ * processed the data. The purpose is to advertise a larger window
+ * when the data has been processed.
+ *
+ * @param pcb the tcp_pcb for which data is read
+ * @param len the amount of bytes that have been read by the application
+ */
+void
+tcp_recved(struct tcp_pcb *pcb, u16_t len)
+{
+  int wnd_inflation;
+
+  /* pcb->state LISTEN not allowed here */
+  LWIP_ASSERT("don't call tcp_recved for listen-pcbs",
+    pcb->state != LISTEN);
+  LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n",
+              len <= 0xffff - pcb->rcv_wnd );
+
+  pcb->rcv_wnd += len;
+  if (pcb->rcv_wnd > TCP_WND) {
+    pcb->rcv_wnd = TCP_WND;
+  }
+
+  wnd_inflation = tcp_update_rcv_ann_wnd(pcb);
+
+  /* If the change in the right edge of window is significant (default
+   * watermark is TCP_WND/4), then send an explicit update now.
+   * Otherwise wait for a packet to be sent in the normal course of
+   * events (or more window to be available later) */
+  if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) {
+    tcp_ack_now(pcb);
+    tcp_output(pcb);
+  }
+
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n",
+         len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
+}
+
+/**
+ * Allocate a new local TCP port.
+ *
+ * @return a new (free) local TCP port number
+ */
+static u16_t
+tcp_new_port(void)
+{
+  u8_t i;
+  u16_t n = 0;
+  struct tcp_pcb *pcb;
+  
+again:
+  if (tcp_port++ == TCP_LOCAL_PORT_RANGE_END) {
+    tcp_port = TCP_LOCAL_PORT_RANGE_START;
+  }
+  /* Check all PCB lists. */
+  for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
+    for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
+      if (pcb->local_port == tcp_port) {
+        if (++n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) {
+          return 0;
+        }
+        goto again;
+      }
+    }
+  }
+  return tcp_port;
+}
+
+/**
+ * Connects to another host. The function given as the "connected"
+ * argument will be called when the connection has been established.
+ *
+ * @param pcb the tcp_pcb used to establish the connection
+ * @param ipaddr the remote ip address to connect to
+ * @param port the remote tcp port to connect to
+ * @param connected callback function to call when connected (or on error)
+ * @return ERR_VAL if invalid arguments are given
+ *         ERR_OK if connect request has been sent
+ *         other err_t values if connect request couldn't be sent
+ */
+err_t
+tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
+      tcp_connected_fn connected)
+{
+  err_t ret;
+  u32_t iss;
+  u16_t old_local_port;
+
+  LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
+
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
+  if (ipaddr != NULL) {
+    pcb->remote_ip = *ipaddr;
+  } else {
+    return ERR_VAL;
+  }
+  pcb->remote_port = port;
+
+  /* check if we have a route to the remote host */
+  if (ip_addr_isany(&(pcb->local_ip))) {
+    /* no local IP address set, yet. */
+    struct netif *netif = ip_route(&(pcb->remote_ip));
+    if (netif == NULL) {
+      /* Don't even try to send a SYN packet if we have no route
+         since that will fail. */
+      return ERR_RTE;
+    }
+    /* Use the netif's IP address as local address. */
+    ip_addr_copy(pcb->local_ip, netif->ip_addr);
+  }
+
+  old_local_port = pcb->local_port;
+  if (pcb->local_port == 0) {
+    pcb->local_port = tcp_new_port();
+    if (pcb->local_port == 0) {
+      return ERR_BUF;
+    }
+  }
+#if SO_REUSE
+  if (ip_get_option(pcb, SOF_REUSEADDR)) {
+    /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure
+       now that the 5-tuple is unique. */
+    struct tcp_pcb *cpcb;
+    int i;
+    /* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */
+    for (i = 2; i < NUM_TCP_PCB_LISTS; i++) {
+      for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
+        if ((cpcb->local_port == pcb->local_port) &&
+            (cpcb->remote_port == port) &&
+            ip_addr_cmp(&cpcb->local_ip, &pcb->local_ip) &&
+            ip_addr_cmp(&cpcb->remote_ip, ipaddr)) {
+          /* linux returns EISCONN here, but ERR_USE should be OK for us */
+          return ERR_USE;
+        }
+      }
+    }
+  }
+#endif /* SO_REUSE */
+  iss = tcp_next_iss();
+  pcb->rcv_nxt = 0;
+  pcb->snd_nxt = iss;
+  pcb->lastack = iss - 1;
+  pcb->snd_lbb = iss - 1;
+  pcb->rcv_wnd = TCP_WND;
+  pcb->rcv_ann_wnd = TCP_WND;
+  pcb->rcv_ann_right_edge = pcb->rcv_nxt;
+  pcb->snd_wnd = TCP_WND;
+  /* As initial send MSS, we use TCP_MSS but limit it to 536.
+     The send MSS is updated when an MSS option is received. */
+  pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
+#if TCP_CALCULATE_EFF_SEND_MSS
+  pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr);
+#endif /* TCP_CALCULATE_EFF_SEND_MSS */
+  pcb->cwnd = 1;
+  pcb->ssthresh = pcb->mss * 10;
+#if LWIP_CALLBACK_API
+  pcb->connected = connected;
+#else /* LWIP_CALLBACK_API */  
+  LWIP_UNUSED_ARG(connected);
+#endif /* LWIP_CALLBACK_API */
+
+  /* Send a SYN together with the MSS option. */
+  ret = tcp_enqueue_flags(pcb, TCP_SYN);
+  if (ret == ERR_OK) {
+    /* SYN segment was enqueued, changed the pcbs state now */
+    pcb->state = SYN_SENT;
+    if (old_local_port != 0) {
+      TCP_RMV(&tcp_bound_pcbs, pcb);
+    }
+    TCP_REG_ACTIVE(pcb);
+    snmp_inc_tcpactiveopens();
+
+    tcp_output(pcb);
+  }
+  return ret;
+}
+
+/**
+ * Called every 500 ms and implements the retransmission timer and the timer that
+ * removes PCBs that have been in TIME-WAIT for enough time. It also increments
+ * various timers such as the inactivity timer in each PCB.
+ *
+ * Automatically called from tcp_tmr().
+ */
+void
+tcp_slowtmr(void)
+{
+  struct tcp_pcb *pcb, *prev;
+  u16_t eff_wnd;
+  u8_t pcb_remove;      /* flag if a PCB should be removed */
+  u8_t pcb_reset;       /* flag if a RST should be sent when removing */
+  err_t err;
+
+  err = ERR_OK;
+
+  ++tcp_ticks;
+  ++tcp_timer_ctr;
+
+tcp_slowtmr_start:
+  /* Steps through all of the active PCBs. */
+  prev = NULL;
+  pcb = tcp_active_pcbs;
+  if (pcb == NULL) {
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));
+  }
+  while (pcb != NULL) {
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));
+    LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
+    LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);
+    LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
+    if (pcb->last_timer == tcp_timer_ctr) {
+      /* skip this pcb, we have already processed it */
+      pcb = pcb->next;
+      continue;
+    }
+    pcb->last_timer = tcp_timer_ctr;
+
+    pcb_remove = 0;
+    pcb_reset = 0;
+
+    if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {
+      ++pcb_remove;
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));
+    }
+    else if (pcb->nrtx == TCP_MAXRTX) {
+      ++pcb_remove;
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
+    } else {
+      if (pcb->persist_backoff > 0) {
+        /* If snd_wnd is zero, use persist timer to send 1 byte probes
+         * instead of using the standard retransmission mechanism. */
+        pcb->persist_cnt++;
+        if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) {
+          pcb->persist_cnt = 0;
+          if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) {
+            pcb->persist_backoff++;
+          }
+          tcp_zero_window_probe(pcb);
+        }
+      } else {
+        /* Increase the retransmission timer if it is running */
+        if(pcb->rtime >= 0) {
+          ++pcb->rtime;
+        }
+
+        if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
+          /* Time for a retransmission. */
+          LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F
+                                      " pcb->rto %"S16_F"\n",
+                                      pcb->rtime, pcb->rto));
+
+          /* Double retransmission time-out unless we are trying to
+           * connect to somebody (i.e., we are in SYN_SENT). */
+          if (pcb->state != SYN_SENT) {
+            pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];
+          }
+
+          /* Reset the retransmission timer. */
+          pcb->rtime = 0;
+
+          /* Reduce congestion window and ssthresh. */
+          eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
+          pcb->ssthresh = eff_wnd >> 1;
+          if (pcb->ssthresh < (pcb->mss << 1)) {
+            pcb->ssthresh = (pcb->mss << 1);
+          }
+          pcb->cwnd = pcb->mss;
+          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F
+                                       " ssthresh %"U16_F"\n",
+                                       pcb->cwnd, pcb->ssthresh));
+ 
+          /* The following needs to be called AFTER cwnd is set to one
+             mss - STJ */
+          tcp_rexmit_rto(pcb);
+        }
+      }
+    }
+    /* Check if this PCB has stayed too long in FIN-WAIT-2 */
+    if (pcb->state == FIN_WAIT_2) {
+      /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */
+      if (pcb->flags & TF_RXCLOSED) {
+        /* PCB was fully closed (either through close() or SHUT_RDWR):
+           normal FIN-WAIT timeout handling. */
+        if ((u32_t)(tcp_ticks - pcb->tmr) >
+            TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {
+          ++pcb_remove;
+          LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));
+        }
+      }
+    }
+
+    /* Check if KEEPALIVE should be sent */
+    if(ip_get_option(pcb, SOF_KEEPALIVE) &&
+       ((pcb->state == ESTABLISHED) ||
+        (pcb->state == CLOSE_WAIT))) {
+      if((u32_t)(tcp_ticks - pcb->tmr) >
+         (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL)
+      {
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n",
+                                ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
+                                ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));
+        
+        ++pcb_remove;
+        ++pcb_reset;
+      }
+      else if((u32_t)(tcp_ticks - pcb->tmr) > 
+              (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb))
+              / TCP_SLOW_INTERVAL)
+      {
+        tcp_keepalive(pcb);
+        pcb->keep_cnt_sent++;
+      }
+    }
+
+    /* If this PCB has queued out of sequence data, but has been
+       inactive for too long, will drop the data (it will eventually
+       be retransmitted). */
+#if TCP_QUEUE_OOSEQ
+    if (pcb->ooseq != NULL &&
+        (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) {
+      tcp_segs_free(pcb->ooseq);
+      pcb->ooseq = NULL;
+      LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n"));
+    }
+#endif /* TCP_QUEUE_OOSEQ */
+
+    /* Check if this PCB has stayed too long in SYN-RCVD */
+    if (pcb->state == SYN_RCVD) {
+      if ((u32_t)(tcp_ticks - pcb->tmr) >
+          TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
+        ++pcb_remove;
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
+      }
+    }
+
+    /* Check if this PCB has stayed too long in LAST-ACK */
+    if (pcb->state == LAST_ACK) {
+      if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
+        ++pcb_remove;
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n"));
+      }
+    }
+
+    /* If the PCB should be removed, do it. */
+    if (pcb_remove) {
+      struct tcp_pcb *pcb2;
+      tcp_err_fn err_fn;
+      void *err_arg;
+      tcp_pcb_purge(pcb);
+      /* Remove PCB from tcp_active_pcbs list. */
+      if (prev != NULL) {
+        LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
+        prev->next = pcb->next;
+      } else {
+        /* This PCB was the first. */
+        LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
+        tcp_active_pcbs = pcb->next;
+      }
+
+      if (pcb_reset) {
+        tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
+          pcb->local_port, pcb->remote_port);
+      }
+
+      err_fn = pcb->errf;
+      err_arg = pcb->callback_arg;
+      pcb2 = pcb;
+      pcb = pcb->next;
+      memp_free(MEMP_TCP_PCB, pcb2);
+
+      tcp_active_pcbs_changed = 0;
+      TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT);
+      if (tcp_active_pcbs_changed) {
+        goto tcp_slowtmr_start;
+      }
+    } else {
+      /* get the 'next' element now and work with 'prev' below (in case of abort) */
+      prev = pcb;
+      pcb = pcb->next;
+
+      /* We check if we should poll the connection. */
+      ++prev->polltmr;
+      if (prev->polltmr >= prev->pollinterval) {
+        prev->polltmr = 0;
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));
+        tcp_active_pcbs_changed = 0;
+        TCP_EVENT_POLL(prev, err);
+        if (tcp_active_pcbs_changed) {
+          goto tcp_slowtmr_start;
+        }
+        /* if err == ERR_ABRT, 'prev' is already deallocated */
+        if (err == ERR_OK) {
+          tcp_output(prev);
+        }
+      }
+    }
+  }
+
+  
+  /* Steps through all of the TIME-WAIT PCBs. */
+  prev = NULL;
+  pcb = tcp_tw_pcbs;
+  while (pcb != NULL) {
+    LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
+    pcb_remove = 0;
+
+    /* Check if this PCB has stayed long enough in TIME-WAIT */
+    if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
+      ++pcb_remove;
+    }
+    
+
+
+    /* If the PCB should be removed, do it. */
+    if (pcb_remove) {
+      struct tcp_pcb *pcb2;
+      tcp_pcb_purge(pcb);
+      /* Remove PCB from tcp_tw_pcbs list. */
+      if (prev != NULL) {
+        LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
+        prev->next = pcb->next;
+      } else {
+        /* This PCB was the first. */
+        LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
+        tcp_tw_pcbs = pcb->next;
+      }
+      pcb2 = pcb;
+      pcb = pcb->next;
+      memp_free(MEMP_TCP_PCB, pcb2);
+    } else {
+      prev = pcb;
+      pcb = pcb->next;
+    }
+  }
+}
+
+/**
+ * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously
+ * "refused" by upper layer (application) and sends delayed ACKs.
+ *
+ * Automatically called from tcp_tmr().
+ */
+void
+tcp_fasttmr(void)
+{
+  struct tcp_pcb *pcb;
+
+  ++tcp_timer_ctr;
+
+tcp_fasttmr_start:
+  pcb = tcp_active_pcbs;
+
+  while(pcb != NULL) {
+    if (pcb->last_timer != tcp_timer_ctr) {
+      struct tcp_pcb *next;
+      pcb->last_timer = tcp_timer_ctr;
+      /* send delayed ACKs */
+      if (pcb->flags & TF_ACK_DELAY) {
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
+        tcp_ack_now(pcb);
+        tcp_output(pcb);
+        pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
+      }
+
+      next = pcb->next;
+
+      /* If there is data which was previously "refused" by upper layer */
+      if (pcb->refused_data != NULL) {
+        tcp_active_pcbs_changed = 0;
+        tcp_process_refused_data(pcb);
+        if (tcp_active_pcbs_changed) {
+          /* application callback has changed the pcb list: restart the loop */
+          goto tcp_fasttmr_start;
+        }
+      }
+      pcb = next;
+    }
+  }
+}
+
+/** Pass pcb->refused_data to the recv callback */
+err_t
+tcp_process_refused_data(struct tcp_pcb *pcb)
+{
+  err_t err;
+  u8_t refused_flags = pcb->refused_data->flags;
+  /* set pcb->refused_data to NULL in case the callback frees it and then
+     closes the pcb */
+  struct pbuf *refused_data = pcb->refused_data;
+  pcb->refused_data = NULL;
+  /* Notify again application with data previously received. */
+  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n"));
+  TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err);
+  if (err == ERR_OK) {
+    /* did refused_data include a FIN? */
+    if (refused_flags & PBUF_FLAG_TCP_FIN) {
+      /* correct rcv_wnd as the application won't call tcp_recved()
+         for the FIN's seqno */
+      if (pcb->rcv_wnd != TCP_WND) {
+        pcb->rcv_wnd++;
+      }
+      TCP_EVENT_CLOSED(pcb, err);
+      if (err == ERR_ABRT) {
+        return ERR_ABRT;
+      }
+    }
+  } else if (err == ERR_ABRT) {
+    /* if err == ERR_ABRT, 'pcb' is already deallocated */
+    /* Drop incoming packets because pcb is "full" (only if the incoming
+       segment contains data). */
+    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
+    return ERR_ABRT;
+  } else {
+    /* data is still refused, pbuf is still valid (go on for ACK-only packets) */
+    pcb->refused_data = refused_data;
+  }
+  return ERR_OK;
+}
+
+/**
+ * Deallocates a list of TCP segments (tcp_seg structures).
+ *
+ * @param seg tcp_seg list of TCP segments to free
+ */
+void
+tcp_segs_free(struct tcp_seg *seg)
+{
+  while (seg != NULL) {
+    struct tcp_seg *next = seg->next;
+    tcp_seg_free(seg);
+    seg = next;
+  }
+}
+
+/**
+ * Frees a TCP segment (tcp_seg structure).
+ *
+ * @param seg single tcp_seg to free
+ */
+void
+tcp_seg_free(struct tcp_seg *seg)
+{
+  if (seg != NULL) {
+    if (seg->p != NULL) {
+      pbuf_free(seg->p);
+#if TCP_DEBUG
+      seg->p = NULL;
+#endif /* TCP_DEBUG */
+    }
+    memp_free(MEMP_TCP_SEG, seg);
+  }
+}
+
+/**
+ * Sets the priority of a connection.
+ *
+ * @param pcb the tcp_pcb to manipulate
+ * @param prio new priority
+ */
+void
+tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
+{
+  pcb->prio = prio;
+}
+
+#if TCP_QUEUE_OOSEQ
+/**
+ * Returns a copy of the given TCP segment.
+ * The pbuf and data are not copied, only the pointers
+ *
+ * @param seg the old tcp_seg
+ * @return a copy of seg
+ */ 
+struct tcp_seg *
+tcp_seg_copy(struct tcp_seg *seg)
+{
+  struct tcp_seg *cseg;
+
+  cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG);
+  if (cseg == NULL) {
+    return NULL;
+  }
+  SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); 
+  pbuf_ref(cseg->p);
+  return cseg;
+}
+#endif /* TCP_QUEUE_OOSEQ */
+
+#if LWIP_CALLBACK_API
+/**
+ * Default receive callback that is called if the user didn't register
+ * a recv callback for the pcb.
+ */
+err_t
+tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
+{
+  LWIP_UNUSED_ARG(arg);
+  if (p != NULL) {
+    tcp_recved(pcb, p->tot_len);
+    pbuf_free(p);
+  } else if (err == ERR_OK) {
+    return tcp_close(pcb);
+  }
+  return ERR_OK;
+}
+#endif /* LWIP_CALLBACK_API */
+
+/**
+ * Kills the oldest active connection that has the same or lower priority than
+ * 'prio'.
+ *
+ * @param prio minimum priority
+ */
+static void
+tcp_kill_prio(u8_t prio)
+{
+  struct tcp_pcb *pcb, *inactive;
+  u32_t inactivity;
+  u8_t mprio;
+
+
+  mprio = TCP_PRIO_MAX;
+  
+  /* We kill the oldest active connection that has lower priority than prio. */
+  inactivity = 0;
+  inactive = NULL;
+  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
+    if (pcb->prio <= prio &&
+       pcb->prio <= mprio &&
+       (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
+      inactivity = tcp_ticks - pcb->tmr;
+      inactive = pcb;
+      mprio = pcb->prio;
+    }
+  }
+  if (inactive != NULL) {
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n",
+           (void *)inactive, inactivity));
+    tcp_abort(inactive);
+  }
+}
+
+/**
+ * Kills the oldest connection that is in TIME_WAIT state.
+ * Called from tcp_alloc() if no more connections are available.
+ */
+static void
+tcp_kill_timewait(void)
+{
+  struct tcp_pcb *pcb, *inactive;
+  u32_t inactivity;
+
+  inactivity = 0;
+  inactive = NULL;
+  /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */
+  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
+    if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
+      inactivity = tcp_ticks - pcb->tmr;
+      inactive = pcb;
+    }
+  }
+  if (inactive != NULL) {
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n",
+           (void *)inactive, inactivity));
+    tcp_abort(inactive);
+  }
+}
+
+/**
+ * Allocate a new tcp_pcb structure.
+ *
+ * @param prio priority for the new pcb
+ * @return a new tcp_pcb that initially is in state CLOSED
+ */
+struct tcp_pcb *
+tcp_alloc(u8_t prio)
+{
+  struct tcp_pcb *pcb;
+  u32_t iss;
+  
+  pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
+  if (pcb == NULL) {
+    /* Try killing oldest connection in TIME-WAIT. */
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));
+    tcp_kill_timewait();
+    /* Try to allocate a tcp_pcb again. */
+    pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
+    if (pcb == NULL) {
+      /* Try killing active connections with lower priority than the new one. */
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio));
+      tcp_kill_prio(prio);
+      /* Try to allocate a tcp_pcb again. */
+      pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
+      if (pcb != NULL) {
+        /* adjust err stats: memp_malloc failed twice before */
+        MEMP_STATS_DEC(err, MEMP_TCP_PCB);
+      }
+    }
+    if (pcb != NULL) {
+      /* adjust err stats: timewait PCB was freed above */
+      MEMP_STATS_DEC(err, MEMP_TCP_PCB);
+    }
+  }
+  if (pcb != NULL) {
+    memset(pcb, 0, sizeof(struct tcp_pcb));
+    pcb->prio = prio;
+    pcb->snd_buf = TCP_SND_BUF;
+    pcb->snd_queuelen = 0;
+    pcb->rcv_wnd = TCP_WND;
+    pcb->rcv_ann_wnd = TCP_WND;
+    pcb->tos = 0;
+    pcb->ttl = TCP_TTL;
+    /* As initial send MSS, we use TCP_MSS but limit it to 536.
+       The send MSS is updated when an MSS option is received. */
+    pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
+    pcb->rto = 3000 / TCP_SLOW_INTERVAL;
+    pcb->sa = 0;
+    pcb->sv = 3000 / TCP_SLOW_INTERVAL;
+    pcb->rtime = -1;
+    pcb->cwnd = 1;
+    iss = tcp_next_iss();
+    pcb->snd_wl2 = iss;
+    pcb->snd_nxt = iss;
+    pcb->lastack = iss;
+    pcb->snd_lbb = iss;   
+    pcb->tmr = tcp_ticks;
+    pcb->last_timer = tcp_timer_ctr;
+
+    pcb->polltmr = 0;
+
+#if LWIP_CALLBACK_API
+    pcb->recv = tcp_recv_null;
+#endif /* LWIP_CALLBACK_API */  
+    
+    /* Init KEEPALIVE timer */
+    pcb->keep_idle  = TCP_KEEPIDLE_DEFAULT;
+    
+#if LWIP_TCP_KEEPALIVE
+    pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
+    pcb->keep_cnt   = TCP_KEEPCNT_DEFAULT;
+#endif /* LWIP_TCP_KEEPALIVE */
+
+    pcb->keep_cnt_sent = 0;
+  }
+  return pcb;
+}
+
+/**
+ * Creates a new TCP protocol control block but doesn't place it on
+ * any of the TCP PCB lists.
+ * The pcb is not put on any list until binding using tcp_bind().
+ *
+ * @internal: Maybe there should be a idle TCP PCB list where these
+ * PCBs are put on. Port reservation using tcp_bind() is implemented but
+ * allocated pcbs that are not bound can't be killed automatically if wanting
+ * to allocate a pcb with higher prio (@see tcp_kill_prio())
+ *
+ * @return a new tcp_pcb that initially is in state CLOSED
+ */
+struct tcp_pcb *
+tcp_new(void)
+{
+  return tcp_alloc(TCP_PRIO_NORMAL);
+}
+
+/**
+ * Used to specify the argument that should be passed callback
+ * functions.
+ *
+ * @param pcb tcp_pcb to set the callback argument
+ * @param arg void pointer argument to pass to callback functions
+ */ 
+void
+tcp_arg(struct tcp_pcb *pcb, void *arg)
+{
+  /* This function is allowed to be called for both listen pcbs and
+     connection pcbs. */
+  pcb->callback_arg = arg;
+}
+#if LWIP_CALLBACK_API
+
+/**
+ * Used to specify the function that should be called when a TCP
+ * connection receives data.
+ *
+ * @param pcb tcp_pcb to set the recv callback
+ * @param recv callback function to call for this pcb when data is received
+ */ 
+void
+tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv)
+{
+  LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN);
+  pcb->recv = recv;
+}
+
+/**
+ * Used to specify the function that should be called when TCP data
+ * has been successfully delivered to the remote host.
+ *
+ * @param pcb tcp_pcb to set the sent callback
+ * @param sent callback function to call for this pcb when data is successfully sent
+ */ 
+void
+tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent)
+{
+  LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN);
+  pcb->sent = sent;
+}
+
+/**
+ * Used to specify the function that should be called when a fatal error
+ * has occured on the connection.
+ *
+ * @param pcb tcp_pcb to set the err callback
+ * @param err callback function to call for this pcb when a fatal error
+ *        has occured on the connection
+ */ 
+void
+tcp_err(struct tcp_pcb *pcb, tcp_err_fn err)
+{
+  LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN);
+  pcb->errf = err;
+}
+
+/**
+ * Used for specifying the function that should be called when a
+ * LISTENing connection has been connected to another host.
+ *
+ * @param pcb tcp_pcb to set the accept callback
+ * @param accept callback function to call for this pcb when LISTENing
+ *        connection has been connected to another host
+ */ 
+void
+tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept)
+{
+  /* This function is allowed to be called for both listen pcbs and
+     connection pcbs. */
+  pcb->accept = accept;
+}
+#endif /* LWIP_CALLBACK_API */
+
+
+/**
+ * Used to specify the function that should be called periodically
+ * from TCP. The interval is specified in terms of the TCP coarse
+ * timer interval, which is called twice a second.
+ *
+ */ 
+void
+tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval)
+{
+  LWIP_ASSERT("invalid socket state for poll", pcb->state != LISTEN);
+#if LWIP_CALLBACK_API
+  pcb->poll = poll;
+#else /* LWIP_CALLBACK_API */  
+  LWIP_UNUSED_ARG(poll);
+#endif /* LWIP_CALLBACK_API */  
+  pcb->pollinterval = interval;
+}
+
+/**
+ * Purges a TCP PCB. Removes any buffered data and frees the buffer memory
+ * (pcb->ooseq, pcb->unsent and pcb->unacked are freed).
+ *
+ * @param pcb tcp_pcb to purge. The pcb itself is not deallocated!
+ */
+void
+tcp_pcb_purge(struct tcp_pcb *pcb)
+{
+  if (pcb->state != CLOSED &&
+     pcb->state != TIME_WAIT &&
+     pcb->state != LISTEN) {
+
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
+
+#if TCP_LISTEN_BACKLOG
+    if (pcb->state == SYN_RCVD) {
+      /* Need to find the corresponding listen_pcb and decrease its accepts_pending */
+      struct tcp_pcb_listen *lpcb;
+      LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL",
+        tcp_listen_pcbs.listen_pcbs != NULL);
+      for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
+        if ((lpcb->local_port == pcb->local_port) &&
+            (ip_addr_isany(&lpcb->local_ip) ||
+             ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) {
+            /* port and address of the listen pcb match the timed-out pcb */
+            LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending",
+              lpcb->accepts_pending > 0);
+            lpcb->accepts_pending--;
+            break;
+          }
+      }
+    }
+#endif /* TCP_LISTEN_BACKLOG */
+
+
+    if (pcb->refused_data != NULL) {
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n"));
+      pbuf_free(pcb->refused_data);
+      pcb->refused_data = NULL;
+    }
+    if (pcb->unsent != NULL) {
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));
+    }
+    if (pcb->unacked != NULL) {
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n"));
+    }
+#if TCP_QUEUE_OOSEQ
+    if (pcb->ooseq != NULL) {
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
+    }
+    tcp_segs_free(pcb->ooseq);
+    pcb->ooseq = NULL;
+#endif /* TCP_QUEUE_OOSEQ */
+
+    /* Stop the retransmission timer as it will expect data on unacked
+       queue if it fires */
+    pcb->rtime = -1;
+
+    tcp_segs_free(pcb->unsent);
+    tcp_segs_free(pcb->unacked);
+    pcb->unacked = pcb->unsent = NULL;
+#if TCP_OVERSIZE
+    pcb->unsent_oversize = 0;
+#endif /* TCP_OVERSIZE */
+  }
+}
+
+/**
+ * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first.
+ *
+ * @param pcblist PCB list to purge.
+ * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated!
+ */
+void
+tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
+{
+  TCP_RMV(pcblist, pcb);
+
+  tcp_pcb_purge(pcb);
+  
+  /* if there is an outstanding delayed ACKs, send it */
+  if (pcb->state != TIME_WAIT &&
+     pcb->state != LISTEN &&
+     pcb->flags & TF_ACK_DELAY) {
+    pcb->flags |= TF_ACK_NOW;
+    tcp_output(pcb);
+  }
+
+  if (pcb->state != LISTEN) {
+    LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL);
+    LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL);
+#if TCP_QUEUE_OOSEQ
+    LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL);
+#endif /* TCP_QUEUE_OOSEQ */
+  }
+
+  pcb->state = CLOSED;
+
+  LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
+}
+
+/**
+ * Calculates a new initial sequence number for new connections.
+ *
+ * @return u32_t pseudo random sequence number
+ */
+u32_t
+tcp_next_iss(void)
+{
+  static u32_t iss = 6510;
+  
+  iss += tcp_ticks;       /* XXX */
+  return iss;
+}
+
+#if TCP_CALCULATE_EFF_SEND_MSS
+/**
+ * Calcluates the effective send mss that can be used for a specific IP address
+ * by using ip_route to determin the netif used to send to the address and
+ * calculating the minimum of TCP_MSS and that netif's mtu (if set).
+ */
+u16_t
+tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr)
+{
+  u16_t mss_s;
+  struct netif *outif;
+
+  outif = ip_route(addr);
+  if ((outif != NULL) && (outif->mtu != 0)) {
+    mss_s = outif->mtu - IP_HLEN - TCP_HLEN;
+    /* RFC 1122, chap 4.2.2.6:
+     * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize
+     * We correct for TCP options in tcp_write(), and don't support IP options.
+     */
+    sendmss = LWIP_MIN(sendmss, mss_s);
+  }
+  return sendmss;
+}
+#endif /* TCP_CALCULATE_EFF_SEND_MSS */
+
+const char*
+tcp_debug_state_str(enum tcp_state s)
+{
+  return tcp_state_str[s];
+}
+
+#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
+/**
+ * Print a tcp header for debugging purposes.
+ *
+ * @param tcphdr pointer to a struct tcp_hdr
+ */
+void
+tcp_debug_print(struct tcp_hdr *tcphdr)
+{
+  LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(TCP_DEBUG, ("|    %5"U16_F"      |    %5"U16_F"      | (src port, dest port)\n",
+         ntohs(tcphdr->src), ntohs(tcphdr->dest)));
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (seq no)\n",
+          ntohl(tcphdr->seqno)));
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (ack no)\n",
+         ntohl(tcphdr->ackno)));
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" |   |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"|     %5"U16_F"     | (hdrlen, flags (",
+       TCPH_HDRLEN(tcphdr),
+         TCPH_FLAGS(tcphdr) >> 5 & 1,
+         TCPH_FLAGS(tcphdr) >> 4 & 1,
+         TCPH_FLAGS(tcphdr) >> 3 & 1,
+         TCPH_FLAGS(tcphdr) >> 2 & 1,
+         TCPH_FLAGS(tcphdr) >> 1 & 1,
+         TCPH_FLAGS(tcphdr) & 1,
+         ntohs(tcphdr->wnd)));
+  tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
+  LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(TCP_DEBUG, ("|    0x%04"X16_F"     |     %5"U16_F"     | (chksum, urgp)\n",
+         ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));
+  LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
+}
+
+/**
+ * Print a tcp state for debugging purposes.
+ *
+ * @param s enum tcp_state to print
+ */
+void
+tcp_debug_print_state(enum tcp_state s)
+{
+  LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s]));
+}
+
+/**
+ * Print tcp flags for debugging purposes.
+ *
+ * @param flags tcp flags, all active flags are printed
+ */
+void
+tcp_debug_print_flags(u8_t flags)
+{
+  if (flags & TCP_FIN) {
+    LWIP_DEBUGF(TCP_DEBUG, ("FIN "));
+  }
+  if (flags & TCP_SYN) {
+    LWIP_DEBUGF(TCP_DEBUG, ("SYN "));
+  }
+  if (flags & TCP_RST) {
+    LWIP_DEBUGF(TCP_DEBUG, ("RST "));
+  }
+  if (flags & TCP_PSH) {
+    LWIP_DEBUGF(TCP_DEBUG, ("PSH "));
+  }
+  if (flags & TCP_ACK) {
+    LWIP_DEBUGF(TCP_DEBUG, ("ACK "));
+  }
+  if (flags & TCP_URG) {
+    LWIP_DEBUGF(TCP_DEBUG, ("URG "));
+  }
+  if (flags & TCP_ECE) {
+    LWIP_DEBUGF(TCP_DEBUG, ("ECE "));
+  }
+  if (flags & TCP_CWR) {
+    LWIP_DEBUGF(TCP_DEBUG, ("CWR "));
+  }
+  LWIP_DEBUGF(TCP_DEBUG, ("\n"));
+}
+
+/**
+ * Print all tcp_pcbs in every list for debugging purposes.
+ */
+void
+tcp_debug_print_pcbs(void)
+{
+  struct tcp_pcb *pcb;
+  LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));
+  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
+    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
+                       pcb->local_port, pcb->remote_port,
+                       pcb->snd_nxt, pcb->rcv_nxt));
+    tcp_debug_print_state(pcb->state);
+  }    
+  LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
+  for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
+    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
+                       pcb->local_port, pcb->remote_port,
+                       pcb->snd_nxt, pcb->rcv_nxt));
+    tcp_debug_print_state(pcb->state);
+  }    
+  LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));
+  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
+    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
+                       pcb->local_port, pcb->remote_port,
+                       pcb->snd_nxt, pcb->rcv_nxt));
+    tcp_debug_print_state(pcb->state);
+  }    
+}
+
+/**
+ * Check state consistency of the tcp_pcb lists.
+ */
+s16_t
+tcp_pcbs_sane(void)
+{
+  struct tcp_pcb *pcb;
+  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
+    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
+    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
+    LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
+  }
+  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
+    LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
+  }
+  return 1;
+}
+#endif /* TCP_DEBUG */
+
+#endif /* LWIP_TCP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/tcp_in.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/tcp_in.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/tcp_in.c	(revision 164)
@@ -0,0 +1,1619 @@
+/**
+ * @file
+ * Transmission Control Protocol, incoming traffic
+ *
+ * The input processing functions of the TCP layer.
+ *
+ * These functions are generally called in the order (ip_input() ->)
+ * tcp_input() -> * tcp_process() -> tcp_receive() (-> application).
+ * 
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/tcp_impl.h"
+#include "lwip/def.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#include "arch/perf.h"
+
+/* These variables are global to all functions involved in the input
+   processing of TCP segments. They are set by the tcp_input()
+   function. */
+static struct tcp_seg inseg;
+static struct tcp_hdr *tcphdr;
+static struct ip_hdr *iphdr;
+static u32_t seqno, ackno;
+static u8_t flags;
+static u16_t tcplen;
+
+static u8_t recv_flags;
+static struct pbuf *recv_data;
+
+struct tcp_pcb *tcp_input_pcb;
+
+/* Forward declarations. */
+static err_t tcp_process(struct tcp_pcb *pcb);
+static void tcp_receive(struct tcp_pcb *pcb);
+static void tcp_parseopt(struct tcp_pcb *pcb);
+
+static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);
+static err_t tcp_timewait_input(struct tcp_pcb *pcb);
+
+/**
+ * The initial input processing of TCP. It verifies the TCP header, demultiplexes
+ * the segment between the PCBs and passes it on to tcp_process(), which implements
+ * the TCP finite state machine. This function is called by the IP layer (in
+ * ip_input()).
+ *
+ * @param p received TCP segment to process (p->payload pointing to the IP header)
+ * @param inp network interface on which this segment was received
+ */
+void
+tcp_input(struct pbuf *p, struct netif *inp)
+{
+  struct tcp_pcb *pcb, *prev;
+  struct tcp_pcb_listen *lpcb;
+#if SO_REUSE
+  struct tcp_pcb *lpcb_prev = NULL;
+  struct tcp_pcb_listen *lpcb_any = NULL;
+#endif /* SO_REUSE */
+  u8_t hdrlen;
+  err_t err;
+
+  PERF_START;
+
+  TCP_STATS_INC(tcp.recv);
+  snmp_inc_tcpinsegs();
+
+  iphdr = (struct ip_hdr *)p->payload;
+  tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
+
+#if TCP_INPUT_DEBUG
+  tcp_debug_print(tcphdr);
+#endif
+
+  /* remove header from payload */
+  if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) {
+    /* drop short packets */
+    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len));
+    TCP_STATS_INC(tcp.lenerr);
+    goto dropped;
+  }
+
+  /* Don't even process incoming broadcasts/multicasts. */
+  if (ip_addr_isbroadcast(&current_iphdr_dest, inp) ||
+      ip_addr_ismulticast(&current_iphdr_dest)) {
+    TCP_STATS_INC(tcp.proterr);
+    goto dropped;
+  }
+
+#if CHECKSUM_CHECK_TCP
+  /* Verify TCP checksum. */
+  if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(),
+      IP_PROTO_TCP, p->tot_len) != 0) {
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n",
+        inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(),
+      IP_PROTO_TCP, p->tot_len)));
+#if TCP_DEBUG
+    tcp_debug_print(tcphdr);
+#endif /* TCP_DEBUG */
+    TCP_STATS_INC(tcp.chkerr);
+    goto dropped;
+  }
+#endif
+
+  /* Move the payload pointer in the pbuf so that it points to the
+     TCP data instead of the TCP header. */
+  hdrlen = TCPH_HDRLEN(tcphdr);
+  if(pbuf_header(p, -(hdrlen * 4))){
+    /* drop short packets */
+    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n"));
+    TCP_STATS_INC(tcp.lenerr);
+    goto dropped;
+  }
+
+  /* Convert fields in TCP header to host byte order. */
+  tcphdr->src = ntohs(tcphdr->src);
+  tcphdr->dest = ntohs(tcphdr->dest);
+  seqno = tcphdr->seqno = ntohl(tcphdr->seqno);
+  ackno = tcphdr->ackno = ntohl(tcphdr->ackno);
+  tcphdr->wnd = ntohs(tcphdr->wnd);
+
+  flags = TCPH_FLAGS(tcphdr);
+  tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0);
+
+  /* Demultiplex an incoming segment. First, we check if it is destined
+     for an active connection. */
+  prev = NULL;
+
+  
+  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
+    LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
+    LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
+    LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
+    if (pcb->remote_port == tcphdr->src &&
+       pcb->local_port == tcphdr->dest &&
+       ip_addr_cmp(&(pcb->remote_ip), &current_iphdr_src) &&
+       ip_addr_cmp(&(pcb->local_ip), &current_iphdr_dest)) {
+
+      /* Move this PCB to the front of the list so that subsequent
+         lookups will be faster (we exploit locality in TCP segment
+         arrivals). */
+      LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
+      if (prev != NULL) {
+        prev->next = pcb->next;
+        pcb->next = tcp_active_pcbs;
+        tcp_active_pcbs = pcb;
+      }
+      LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
+      break;
+    }
+    prev = pcb;
+  }
+
+  if (pcb == NULL) {
+    /* If it did not go to an active connection, we check the connections
+       in the TIME-WAIT state. */
+    for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
+      LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
+      if (pcb->remote_port == tcphdr->src &&
+         pcb->local_port == tcphdr->dest &&
+         ip_addr_cmp(&(pcb->remote_ip), &current_iphdr_src) &&
+         ip_addr_cmp(&(pcb->local_ip), &current_iphdr_dest)) {
+        /* We don't really care enough to move this PCB to the front
+           of the list since we are not very likely to receive that
+           many segments for connections in TIME-WAIT. */
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
+        tcp_timewait_input(pcb);
+        pbuf_free(p);
+        return;
+      }
+    }
+
+    /* Finally, if we still did not get a match, we check all PCBs that
+       are LISTENing for incoming connections. */
+    prev = NULL;
+    for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
+      if (lpcb->local_port == tcphdr->dest) {
+#if SO_REUSE
+        if (ip_addr_cmp(&(lpcb->local_ip), &current_iphdr_dest)) {
+          /* found an exact match */
+          break;
+        } else if(ip_addr_isany(&(lpcb->local_ip))) {
+          /* found an ANY-match */
+          lpcb_any = lpcb;
+          lpcb_prev = prev;
+        }
+#else /* SO_REUSE */
+        if (ip_addr_cmp(&(lpcb->local_ip), &current_iphdr_dest) ||
+            ip_addr_isany(&(lpcb->local_ip))) {
+          /* found a match */
+          break;
+        }
+#endif /* SO_REUSE */
+      }
+      prev = (struct tcp_pcb *)lpcb;
+    }
+#if SO_REUSE
+    /* first try specific local IP */
+    if (lpcb == NULL) {
+      /* only pass to ANY if no specific local IP has been found */
+      lpcb = lpcb_any;
+      prev = lpcb_prev;
+    }
+#endif /* SO_REUSE */
+    if (lpcb != NULL) {
+      /* Move this PCB to the front of the list so that subsequent
+         lookups will be faster (we exploit locality in TCP segment
+         arrivals). */
+      if (prev != NULL) {
+        ((struct tcp_pcb_listen *)prev)->next = lpcb->next;
+              /* our successor is the remainder of the listening list */
+        lpcb->next = tcp_listen_pcbs.listen_pcbs;
+              /* put this listening pcb at the head of the listening list */
+        tcp_listen_pcbs.listen_pcbs = lpcb;
+      }
+    
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
+      tcp_listen_input(lpcb);
+      pbuf_free(p);
+      return;
+    }
+  }
+
+#if TCP_INPUT_DEBUG
+  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));
+  tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
+  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));
+#endif /* TCP_INPUT_DEBUG */
+
+
+  if (pcb != NULL) {
+    /* The incoming segment belongs to a connection. */
+#if TCP_INPUT_DEBUG
+#if TCP_DEBUG
+    tcp_debug_print_state(pcb->state);
+#endif /* TCP_DEBUG */
+#endif /* TCP_INPUT_DEBUG */
+
+    /* Set up a tcp_seg structure. */
+    inseg.next = NULL;
+    inseg.len = p->tot_len;
+    inseg.p = p;
+    inseg.tcphdr = tcphdr;
+
+    recv_data = NULL;
+    recv_flags = 0;
+
+    if (flags & TCP_PSH) {
+      p->flags |= PBUF_FLAG_PUSH;
+    }
+
+    /* If there is data which was previously "refused" by upper layer */
+    if (pcb->refused_data != NULL) {
+      if ((tcp_process_refused_data(pcb) == ERR_ABRT) ||
+        ((pcb->refused_data != NULL) && (tcplen > 0))) {
+        /* pcb has been aborted or refused data is still refused and the new
+           segment contains data */
+        TCP_STATS_INC(tcp.drop);
+        snmp_inc_tcpinerrs();
+        goto aborted;
+      }
+    }
+    tcp_input_pcb = pcb;
+    err = tcp_process(pcb);
+    /* A return value of ERR_ABRT means that tcp_abort() was called
+       and that the pcb has been freed. If so, we don't do anything. */
+    if (err != ERR_ABRT) {
+      if (recv_flags & TF_RESET) {
+        /* TF_RESET means that the connection was reset by the other
+           end. We then call the error callback to inform the
+           application that the connection is dead before we
+           deallocate the PCB. */
+        TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
+        tcp_pcb_remove(&tcp_active_pcbs, pcb);
+        memp_free(MEMP_TCP_PCB, pcb);
+      } else if (recv_flags & TF_CLOSED) {
+        /* The connection has been closed and we will deallocate the
+           PCB. */
+        if (!(pcb->flags & TF_RXCLOSED)) {
+          /* Connection closed although the application has only shut down the
+             tx side: call the PCB's err callback and indicate the closure to
+             ensure the application doesn't continue using the PCB. */
+          TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD);
+        }
+        tcp_pcb_remove(&tcp_active_pcbs, pcb);
+        memp_free(MEMP_TCP_PCB, pcb);
+      } else {
+        err = ERR_OK;
+        /* If the application has registered a "sent" function to be
+           called when new send buffer space is available, we call it
+           now. */
+        if (pcb->acked > 0) {
+          TCP_EVENT_SENT(pcb, pcb->acked, err);
+          if (err == ERR_ABRT) {
+            goto aborted;
+          }
+        }
+
+        if (recv_data != NULL) {
+          LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL);
+          if (pcb->flags & TF_RXCLOSED) {
+            /* received data although already closed -> abort (send RST) to
+               notify the remote host that not all data has been processed */
+            pbuf_free(recv_data);
+            tcp_abort(pcb);
+            goto aborted;
+          }
+
+          /* Notify application that data has been received. */
+          TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
+          if (err == ERR_ABRT) {
+            goto aborted;
+          }
+
+          /* If the upper layer can't receive this data, store it */
+          if (err != ERR_OK) {
+            pcb->refused_data = recv_data;
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
+          }
+        }
+
+        /* If a FIN segment was received, we call the callback
+           function with a NULL buffer to indicate EOF. */
+        if (recv_flags & TF_GOT_FIN) {
+          if (pcb->refused_data != NULL) {
+            /* Delay this if we have refused data. */
+            pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN;
+          } else {
+            /* correct rcv_wnd as the application won't call tcp_recved()
+               for the FIN's seqno */
+            if (pcb->rcv_wnd != TCP_WND) {
+              pcb->rcv_wnd++;
+            }
+            TCP_EVENT_CLOSED(pcb, err);
+            if (err == ERR_ABRT) {
+              goto aborted;
+            }
+          }
+        }
+
+        tcp_input_pcb = NULL;
+        /* Try to send something out. */
+        tcp_output(pcb);
+#if TCP_INPUT_DEBUG
+#if TCP_DEBUG
+        tcp_debug_print_state(pcb->state);
+#endif /* TCP_DEBUG */
+#endif /* TCP_INPUT_DEBUG */
+      }
+    }
+    /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()).
+       Below this line, 'pcb' may not be dereferenced! */
+aborted:
+    tcp_input_pcb = NULL;
+    recv_data = NULL;
+
+    /* give up our reference to inseg.p */
+    if (inseg.p != NULL)
+    {
+      pbuf_free(inseg.p);
+      inseg.p = NULL;
+    }
+  } else {
+
+    /* If no matching PCB was found, send a TCP RST (reset) to the
+       sender. */
+    LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
+    if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
+      TCP_STATS_INC(tcp.proterr);
+      TCP_STATS_INC(tcp.drop);
+      tcp_rst(ackno, seqno + tcplen,
+        ip_current_dest_addr(), ip_current_src_addr(),
+        tcphdr->dest, tcphdr->src);
+    }
+    pbuf_free(p);
+  }
+
+  LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
+  PERF_STOP("tcp_input");
+  return;
+dropped:
+  TCP_STATS_INC(tcp.drop);
+  snmp_inc_tcpinerrs();
+  pbuf_free(p);
+}
+
+/**
+ * Called by tcp_input() when a segment arrives for a listening
+ * connection (from tcp_input()).
+ *
+ * @param pcb the tcp_pcb_listen for which a segment arrived
+ * @return ERR_OK if the segment was processed
+ *         another err_t on error
+ *
+ * @note the return value is not (yet?) used in tcp_input()
+ * @note the segment which arrived is saved in global variables, therefore only the pcb
+ *       involved is passed as a parameter to this function
+ */
+static err_t
+tcp_listen_input(struct tcp_pcb_listen *pcb)
+{
+  struct tcp_pcb *npcb;
+  err_t rc;
+
+  if (flags & TCP_RST) {
+    /* An incoming RST should be ignored. Return. */
+    return ERR_OK;
+  }
+
+  /* In the LISTEN state, we check for incoming SYN segments,
+     creates a new PCB, and responds with a SYN|ACK. */
+  if (flags & TCP_ACK) {
+    /* For incoming segments with the ACK flag set, respond with a
+       RST. */
+    LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
+    tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
+      ip_current_src_addr(), tcphdr->dest, tcphdr->src);
+  } else if (flags & TCP_SYN) {
+    LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
+#if TCP_LISTEN_BACKLOG
+    if (pcb->accepts_pending >= pcb->backlog) {
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest));
+      return ERR_ABRT;
+    }
+#endif /* TCP_LISTEN_BACKLOG */
+    npcb = tcp_alloc(pcb->prio);
+    /* If a new PCB could not be created (probably due to lack of memory),
+       we don't do anything, but rely on the sender will retransmit the
+       SYN at a time when we have more memory available. */
+    if (npcb == NULL) {
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
+      TCP_STATS_INC(tcp.memerr);
+      return ERR_MEM;
+    }
+#if TCP_LISTEN_BACKLOG
+    pcb->accepts_pending++;
+#endif /* TCP_LISTEN_BACKLOG */
+    /* Set up the new PCB. */
+    ip_addr_copy(npcb->local_ip, current_iphdr_dest);
+    npcb->local_port = pcb->local_port;
+    ip_addr_copy(npcb->remote_ip, current_iphdr_src);
+    npcb->remote_port = tcphdr->src;
+    npcb->state = SYN_RCVD;
+    npcb->rcv_nxt = seqno + 1;
+    npcb->rcv_ann_right_edge = npcb->rcv_nxt;
+    npcb->snd_wnd = tcphdr->wnd;
+    npcb->snd_wnd_max = tcphdr->wnd;
+    npcb->ssthresh = npcb->snd_wnd;
+    npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */
+    npcb->callback_arg = pcb->callback_arg;
+#if LWIP_CALLBACK_API
+    npcb->accept = pcb->accept;
+#endif /* LWIP_CALLBACK_API */
+    /* inherit socket options */
+    npcb->so_options = pcb->so_options & SOF_INHERITED;
+    /* Register the new PCB so that we can begin receiving segments
+       for it. */
+    TCP_REG_ACTIVE(npcb);
+
+    /* Parse any options in the SYN. */
+    tcp_parseopt(npcb);
+#if TCP_CALCULATE_EFF_SEND_MSS
+    npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip));
+#endif /* TCP_CALCULATE_EFF_SEND_MSS */
+
+    snmp_inc_tcppassiveopens();
+
+    /* Send a SYN|ACK together with the MSS option. */
+    rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK);
+    if (rc != ERR_OK) {
+      tcp_abandon(npcb, 0);
+      return rc;
+    }
+    return tcp_output(npcb);
+  }
+  return ERR_OK;
+}
+
+/**
+ * Called by tcp_input() when a segment arrives for a connection in
+ * TIME_WAIT.
+ *
+ * @param pcb the tcp_pcb for which a segment arrived
+ *
+ * @note the segment which arrived is saved in global variables, therefore only the pcb
+ *       involved is passed as a parameter to this function
+ */
+static err_t
+tcp_timewait_input(struct tcp_pcb *pcb)
+{
+  /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */
+  /* RFC 793 3.9 Event Processing - Segment Arrives:
+   * - first check sequence number - we skip that one in TIME_WAIT (always
+   *   acceptable since we only send ACKs)
+   * - second check the RST bit (... return) */
+  if (flags & TCP_RST)  {
+    return ERR_OK;
+  }
+  /* - fourth, check the SYN bit, */
+  if (flags & TCP_SYN) {
+    /* If an incoming segment is not acceptable, an acknowledgment
+       should be sent in reply */
+    if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) {
+      /* If the SYN is in the window it is an error, send a reset */
+      tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(),
+        tcphdr->dest, tcphdr->src);
+      return ERR_OK;
+    }
+  } else if (flags & TCP_FIN) {
+    /* - eighth, check the FIN bit: Remain in the TIME-WAIT state.
+         Restart the 2 MSL time-wait timeout.*/
+    pcb->tmr = tcp_ticks;
+  }
+
+  if ((tcplen > 0))  {
+    /* Acknowledge data, FIN or out-of-window SYN */
+    pcb->flags |= TF_ACK_NOW;
+    return tcp_output(pcb);
+  }
+  return ERR_OK;
+}
+
+/**
+ * Implements the TCP state machine. Called by tcp_input. In some
+ * states tcp_receive() is called to receive data. The tcp_seg
+ * argument will be freed by the caller (tcp_input()) unless the
+ * recv_data pointer in the pcb is set.
+ *
+ * @param pcb the tcp_pcb for which a segment arrived
+ *
+ * @note the segment which arrived is saved in global variables, therefore only the pcb
+ *       involved is passed as a parameter to this function
+ */
+static err_t
+tcp_process(struct tcp_pcb *pcb)
+{
+  struct tcp_seg *rseg;
+  u8_t acceptable = 0;
+  err_t err;
+
+  err = ERR_OK;
+
+  /* Process incoming RST segments. */
+  if (flags & TCP_RST) {
+    /* First, determine if the reset is acceptable. */
+    if (pcb->state == SYN_SENT) {
+      if (ackno == pcb->snd_nxt) {
+        acceptable = 1;
+      }
+    } else {
+      if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, 
+                          pcb->rcv_nxt+pcb->rcv_wnd)) {
+        acceptable = 1;
+      }
+    }
+
+    if (acceptable) {
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
+      LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
+      recv_flags |= TF_RESET;
+      pcb->flags &= ~TF_ACK_DELAY;
+      return ERR_RST;
+    } else {
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
+       seqno, pcb->rcv_nxt));
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
+       seqno, pcb->rcv_nxt));
+      return ERR_OK;
+    }
+  }
+
+  if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) { 
+    /* Cope with new connection attempt after remote end crashed */
+    tcp_ack_now(pcb);
+    return ERR_OK;
+  }
+  
+  if ((pcb->flags & TF_RXCLOSED) == 0) {
+    /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */
+    pcb->tmr = tcp_ticks;
+  }
+  pcb->keep_cnt_sent = 0;
+
+  tcp_parseopt(pcb);
+
+  /* Do different things depending on the TCP state. */
+  switch (pcb->state) {
+  case SYN_SENT:
+    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
+     pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
+    /* received SYN ACK with expected sequence number? */
+    if ((flags & TCP_ACK) && (flags & TCP_SYN)
+        && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
+      pcb->snd_buf++;
+      pcb->rcv_nxt = seqno + 1;
+      pcb->rcv_ann_right_edge = pcb->rcv_nxt;
+      pcb->lastack = ackno;
+      pcb->snd_wnd = tcphdr->wnd;
+      pcb->snd_wnd_max = tcphdr->wnd;
+      pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
+      pcb->state = ESTABLISHED;
+
+#if TCP_CALCULATE_EFF_SEND_MSS
+      pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip));
+#endif /* TCP_CALCULATE_EFF_SEND_MSS */
+
+      /* Set ssthresh again after changing pcb->mss (already set in tcp_connect
+       * but for the default value of pcb->mss) */
+      pcb->ssthresh = pcb->mss * 10;
+
+      pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
+      LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
+      --pcb->snd_queuelen;
+      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));
+      rseg = pcb->unacked;
+      pcb->unacked = rseg->next;
+      tcp_seg_free(rseg);
+
+      /* If there's nothing left to acknowledge, stop the retransmit
+         timer, otherwise reset it to start again */
+      if(pcb->unacked == NULL)
+        pcb->rtime = -1;
+      else {
+        pcb->rtime = 0;
+        pcb->nrtx = 0;
+      }
+
+      /* Call the user specified function to call when sucessfully
+       * connected. */
+      TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
+      if (err == ERR_ABRT) {
+        return ERR_ABRT;
+      }
+      tcp_ack_now(pcb);
+    }
+    /* received ACK? possibly a half-open connection */
+    else if (flags & TCP_ACK) {
+      /* send a RST to bring the other side in a non-synchronized state. */
+      tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(),
+        tcphdr->dest, tcphdr->src);
+    }
+    break;
+  case SYN_RCVD:
+    if (flags & TCP_ACK) {
+      /* expected ACK number? */
+      if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
+        u16_t old_cwnd;
+        pcb->state = ESTABLISHED;
+        LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+#if LWIP_CALLBACK_API
+        LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
+#endif
+        /* Call the accept function. */
+        TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
+        if (err != ERR_OK) {
+          /* If the accept function returns with an error, we abort
+           * the connection. */
+          /* Already aborted? */
+          if (err != ERR_ABRT) {
+            tcp_abort(pcb);
+          }
+          return ERR_ABRT;
+        }
+        old_cwnd = pcb->cwnd;
+        /* If there was any data contained within this ACK,
+         * we'd better pass it on to the application as well. */
+        tcp_receive(pcb);
+
+        /* Prevent ACK for SYN to generate a sent event */
+        if (pcb->acked != 0) {
+          pcb->acked--;
+        }
+
+        pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
+
+        if (recv_flags & TF_GOT_FIN) {
+          tcp_ack_now(pcb);
+          pcb->state = CLOSE_WAIT;
+        }
+      } else {
+        /* incorrect ACK number, send RST */
+        tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(),
+                tcphdr->dest, tcphdr->src);
+      }
+    } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
+      /* Looks like another copy of the SYN - retransmit our SYN-ACK */
+      tcp_rexmit(pcb);
+    }
+    break;
+  case CLOSE_WAIT:
+    /* FALLTHROUGH */
+  case ESTABLISHED:
+    tcp_receive(pcb);
+    if (recv_flags & TF_GOT_FIN) { /* passive close */
+      tcp_ack_now(pcb);
+      pcb->state = CLOSE_WAIT;
+    }
+    break;
+  case FIN_WAIT_1:
+    tcp_receive(pcb);
+    if (recv_flags & TF_GOT_FIN) {
+      if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
+        LWIP_DEBUGF(TCP_DEBUG,
+          ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+        tcp_ack_now(pcb);
+        tcp_pcb_purge(pcb);
+        TCP_RMV_ACTIVE(pcb);
+        pcb->state = TIME_WAIT;
+        TCP_REG(&tcp_tw_pcbs, pcb);
+      } else {
+        tcp_ack_now(pcb);
+        pcb->state = CLOSING;
+      }
+    } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
+      pcb->state = FIN_WAIT_2;
+    }
+    break;
+  case FIN_WAIT_2:
+    tcp_receive(pcb);
+    if (recv_flags & TF_GOT_FIN) {
+      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+      tcp_ack_now(pcb);
+      tcp_pcb_purge(pcb);
+      TCP_RMV_ACTIVE(pcb);
+      pcb->state = TIME_WAIT;
+      TCP_REG(&tcp_tw_pcbs, pcb);
+    }
+    break;
+  case CLOSING:
+    tcp_receive(pcb);
+    if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
+      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+      tcp_pcb_purge(pcb);
+      TCP_RMV_ACTIVE(pcb);
+      pcb->state = TIME_WAIT;
+      TCP_REG(&tcp_tw_pcbs, pcb);
+    }
+    break;
+  case LAST_ACK:
+    tcp_receive(pcb);
+    if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
+      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+      /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
+      recv_flags |= TF_CLOSED;
+    }
+    break;
+  default:
+    break;
+  }
+  return ERR_OK;
+}
+
+#if TCP_QUEUE_OOSEQ
+/**
+ * Insert segment into the list (segments covered with new one will be deleted)
+ *
+ * Called from tcp_receive()
+ */
+static void
+tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next)
+{
+  struct tcp_seg *old_seg;
+
+  if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
+    /* received segment overlaps all following segments */
+    tcp_segs_free(next);
+    next = NULL;
+  }
+  else {
+    /* delete some following segments
+       oos queue may have segments with FIN flag */
+    while (next &&
+           TCP_SEQ_GEQ((seqno + cseg->len),
+                      (next->tcphdr->seqno + next->len))) {
+      /* cseg with FIN already processed */
+      if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
+        TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN);
+      }
+      old_seg = next;
+      next = next->next;
+      tcp_seg_free(old_seg);
+    }
+    if (next &&
+        TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) {
+      /* We need to trim the incoming segment. */
+      cseg->len = (u16_t)(next->tcphdr->seqno - seqno);
+      pbuf_realloc(cseg->p, cseg->len);
+    }
+  }
+  cseg->next = next;
+}
+#endif /* TCP_QUEUE_OOSEQ */
+
+/**
+ * Called by tcp_process. Checks if the given segment is an ACK for outstanding
+ * data, and if so frees the memory of the buffered data. Next, is places the
+ * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
+ * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
+ * it has been removed from the buffer.
+ *
+ * If the incoming segment constitutes an ACK for a segment that was used for RTT
+ * estimation, the RTT is estimated here as well.
+ *
+ * Called from tcp_process().
+ */
+static void
+tcp_receive(struct tcp_pcb *pcb)
+{
+  struct tcp_seg *next;
+#if TCP_QUEUE_OOSEQ
+  struct tcp_seg *prev, *cseg;
+#endif /* TCP_QUEUE_OOSEQ */
+  struct pbuf *p;
+  s32_t off;
+  s16_t m;
+  u32_t right_wnd_edge;
+  u16_t new_tot_len;
+  int found_dupack = 0;
+#if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS
+  u32_t ooseq_blen;
+  u16_t ooseq_qlen;
+#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */
+
+  LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED);
+
+  if (flags & TCP_ACK) {
+    right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
+
+    /* Update window. */
+    if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
+       (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
+       (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {
+      pcb->snd_wnd = tcphdr->wnd;
+      /* keep track of the biggest window announced by the remote host to calculate
+         the maximum segment size */
+      if (pcb->snd_wnd_max < tcphdr->wnd) {
+        pcb->snd_wnd_max = tcphdr->wnd;
+      }
+      pcb->snd_wl1 = seqno;
+      pcb->snd_wl2 = ackno;
+      if (pcb->snd_wnd == 0) {
+        if (pcb->persist_backoff == 0) {
+          /* start persist timer */
+          pcb->persist_cnt = 0;
+          pcb->persist_backoff = 1;
+        }
+      } else if (pcb->persist_backoff > 0) {
+        /* stop persist timer */
+          pcb->persist_backoff = 0;
+      }
+      LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd));
+#if TCP_WND_DEBUG
+    } else {
+      if (pcb->snd_wnd != tcphdr->wnd) {
+        LWIP_DEBUGF(TCP_WND_DEBUG, 
+                    ("tcp_receive: no window update lastack %"U32_F" ackno %"
+                     U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
+                     pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
+      }
+#endif /* TCP_WND_DEBUG */
+    }
+
+    /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a
+     * duplicate ack if:
+     * 1) It doesn't ACK new data 
+     * 2) length of received packet is zero (i.e. no payload) 
+     * 3) the advertised window hasn't changed 
+     * 4) There is outstanding unacknowledged data (retransmission timer running)
+     * 5) The ACK is == biggest ACK sequence number so far seen (snd_una)
+     * 
+     * If it passes all five, should process as a dupack: 
+     * a) dupacks < 3: do nothing 
+     * b) dupacks == 3: fast retransmit 
+     * c) dupacks > 3: increase cwnd 
+     * 
+     * If it only passes 1-3, should reset dupack counter (and add to
+     * stats, which we don't do in lwIP)
+     *
+     * If it only passes 1, should reset dupack counter
+     *
+     */
+
+    /* Clause 1 */
+    if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {
+      pcb->acked = 0;
+      /* Clause 2 */
+      if (tcplen == 0) {
+        /* Clause 3 */
+        if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){
+          /* Clause 4 */
+          if (pcb->rtime >= 0) {
+            /* Clause 5 */
+            if (pcb->lastack == ackno) {
+              found_dupack = 1;
+              if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) {
+                ++pcb->dupacks;
+              }
+              if (pcb->dupacks > 3) {
+                /* Inflate the congestion window, but not if it means that
+                   the value overflows. */
+                if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
+                  pcb->cwnd += pcb->mss;
+                }
+              } else if (pcb->dupacks == 3) {
+                /* Do fast retransmit */
+                tcp_rexmit_fast(pcb);
+              }
+            }
+          }
+        }
+      }
+      /* If Clause (1) or more is true, but not a duplicate ack, reset
+       * count of consecutive duplicate acks */
+      if (!found_dupack) {
+        pcb->dupacks = 0;
+      }
+    } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){
+      /* We come here when the ACK acknowledges new data. */
+
+      /* Reset the "IN Fast Retransmit" flag, since we are no longer
+         in fast retransmit. Also reset the congestion window to the
+         slow start threshold. */
+      if (pcb->flags & TF_INFR) {
+        pcb->flags &= ~TF_INFR;
+        pcb->cwnd = pcb->ssthresh;
+      }
+
+      /* Reset the number of retransmissions. */
+      pcb->nrtx = 0;
+
+      /* Reset the retransmission time-out. */
+      pcb->rto = (pcb->sa >> 3) + pcb->sv;
+
+      /* Update the send buffer space. Diff between the two can never exceed 64K? */
+      pcb->acked = (u16_t)(ackno - pcb->lastack);
+
+      pcb->snd_buf += pcb->acked;
+
+      /* Reset the fast retransmit variables. */
+      pcb->dupacks = 0;
+      pcb->lastack = ackno;
+
+      /* Update the congestion control variables (cwnd and
+         ssthresh). */
+      if (pcb->state >= ESTABLISHED) {
+        if (pcb->cwnd < pcb->ssthresh) {
+          if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
+            pcb->cwnd += pcb->mss;
+          }
+          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd));
+        } else {
+          u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
+          if (new_cwnd > pcb->cwnd) {
+            pcb->cwnd = new_cwnd;
+          }
+          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd));
+        }
+      }
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
+                                    ackno,
+                                    pcb->unacked != NULL?
+                                    ntohl(pcb->unacked->tcphdr->seqno): 0,
+                                    pcb->unacked != NULL?
+                                    ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));
+
+      /* Remove segment from the unacknowledged list if the incoming
+         ACK acknowlegdes them. */
+      while (pcb->unacked != NULL &&
+             TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
+                         TCP_TCPLEN(pcb->unacked), ackno)) {
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n",
+                                      ntohl(pcb->unacked->tcphdr->seqno),
+                                      ntohl(pcb->unacked->tcphdr->seqno) +
+                                      TCP_TCPLEN(pcb->unacked)));
+
+        next = pcb->unacked;
+        pcb->unacked = pcb->unacked->next;
+
+        LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
+        LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
+        /* Prevent ACK for FIN to generate a sent event */
+        if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
+          pcb->acked--;
+        }
+
+        pcb->snd_queuelen -= pbuf_clen(next->p);
+        tcp_seg_free(next);
+
+        LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen));
+        if (pcb->snd_queuelen != 0) {
+          LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
+                      pcb->unsent != NULL);
+        }
+      }
+
+      /* If there's nothing left to acknowledge, stop the retransmit
+         timer, otherwise reset it to start again */
+      if(pcb->unacked == NULL)
+        pcb->rtime = -1;
+      else
+        pcb->rtime = 0;
+
+      pcb->polltmr = 0;
+    } else {
+      /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */
+      pcb->acked = 0;
+    }
+
+    /* We go through the ->unsent list to see if any of the segments
+       on the list are acknowledged by the ACK. This may seem
+       strange since an "unsent" segment shouldn't be acked. The
+       rationale is that lwIP puts all outstanding segments on the
+       ->unsent list after a retransmission, so these segments may
+       in fact have been sent once. */
+    while (pcb->unsent != NULL &&
+           TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + 
+                           TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) {
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",
+                                    ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +
+                                    TCP_TCPLEN(pcb->unsent)));
+
+      next = pcb->unsent;
+      pcb->unsent = pcb->unsent->next;
+#if TCP_OVERSIZE
+      if (pcb->unsent == NULL) {
+        pcb->unsent_oversize = 0;
+      }
+#endif /* TCP_OVERSIZE */ 
+      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
+      LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
+      /* Prevent ACK for FIN to generate a sent event */
+      if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
+        pcb->acked--;
+      }
+      pcb->snd_queuelen -= pbuf_clen(next->p);
+      tcp_seg_free(next);
+      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen));
+      if (pcb->snd_queuelen != 0) {
+        LWIP_ASSERT("tcp_receive: valid queue length",
+          pcb->unacked != NULL || pcb->unsent != NULL);
+      }
+    }
+    /* End of ACK for new data processing. */
+
+    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",
+                                pcb->rttest, pcb->rtseq, ackno));
+
+    /* RTT estimation calculations. This is done by checking if the
+       incoming segment acknowledges the segment we use to take a
+       round-trip time measurement. */
+    if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
+      /* diff between this shouldn't exceed 32K since this are tcp timer ticks
+         and a round-trip shouldn't be that long... */
+      m = (s16_t)(tcp_ticks - pcb->rttest);
+
+      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n",
+                                  m, m * TCP_SLOW_INTERVAL));
+
+      /* This is taken directly from VJs original code in his paper */
+      m = m - (pcb->sa >> 3);
+      pcb->sa += m;
+      if (m < 0) {
+        m = -m;
+      }
+      m = m - (pcb->sv >> 2);
+      pcb->sv += m;
+      pcb->rto = (pcb->sa >> 3) + pcb->sv;
+
+      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n",
+                                  pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
+
+      pcb->rttest = 0;
+    }
+  }
+
+  /* If the incoming segment contains data, we must process it
+     further unless the pcb already received a FIN.
+     (RFC 793, chapeter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING,
+     LAST-ACK and TIME-WAIT: "Ignore the segment text.") */
+  if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) {
+    /* This code basically does three things:
+
+    +) If the incoming segment contains data that is the next
+    in-sequence data, this data is passed to the application. This
+    might involve trimming the first edge of the data. The rcv_nxt
+    variable and the advertised window are adjusted.
+
+    +) If the incoming segment has data that is above the next
+    sequence number expected (->rcv_nxt), the segment is placed on
+    the ->ooseq queue. This is done by finding the appropriate
+    place in the ->ooseq queue (which is ordered by sequence
+    number) and trim the segment in both ends if needed. An
+    immediate ACK is sent to indicate that we received an
+    out-of-sequence segment.
+
+    +) Finally, we check if the first segment on the ->ooseq queue
+    now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
+    rcv_nxt > ooseq->seqno, we must trim the first edge of the
+    segment on ->ooseq before we adjust rcv_nxt. The data in the
+    segments that are now on sequence are chained onto the
+    incoming segment so that we only need to call the application
+    once.
+    */
+
+    /* First, we check if we must trim the first edge. We have to do
+       this if the sequence number of the incoming segment is less
+       than rcv_nxt, and the sequence number plus the length of the
+       segment is larger than rcv_nxt. */
+    /*    if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
+          if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/
+    if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){
+      /* Trimming the first edge is done by pushing the payload
+         pointer in the pbuf downwards. This is somewhat tricky since
+         we do not want to discard the full contents of the pbuf up to
+         the new starting point of the data since we have to keep the
+         TCP header which is present in the first pbuf in the chain.
+
+         What is done is really quite a nasty hack: the first pbuf in
+         the pbuf chain is pointed to by inseg.p. Since we need to be
+         able to deallocate the whole pbuf, we cannot change this
+         inseg.p pointer to point to any of the later pbufs in the
+         chain. Instead, we point the ->payload pointer in the first
+         pbuf to data in one of the later pbufs. We also set the
+         inseg.data pointer to point to the right place. This way, the
+         ->p pointer will still point to the first pbuf, but the
+         ->p->payload pointer will point to data in another pbuf.
+
+         After we are done with adjusting the pbuf pointers we must
+         adjust the ->data pointer in the seg and the segment
+         length.*/
+
+      off = pcb->rcv_nxt - seqno;
+      p = inseg.p;
+      LWIP_ASSERT("inseg.p != NULL", inseg.p);
+      LWIP_ASSERT("insane offset!", (off < 0x7fff));
+      if (inseg.p->len < off) {
+        LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off));
+        new_tot_len = (u16_t)(inseg.p->tot_len - off);
+        while (p->len < off) {
+          off -= p->len;
+          /* KJM following line changed (with addition of new_tot_len var)
+             to fix bug #9076
+             inseg.p->tot_len -= p->len; */
+          p->tot_len = new_tot_len;
+          p->len = 0;
+          p = p->next;
+        }
+        if(pbuf_header(p, (s16_t)-off)) {
+          /* Do we need to cope with this failing?  Assert for now */
+          LWIP_ASSERT("pbuf_header failed", 0);
+        }
+      } else {
+        if(pbuf_header(inseg.p, (s16_t)-off)) {
+          /* Do we need to cope with this failing?  Assert for now */
+          LWIP_ASSERT("pbuf_header failed", 0);
+        }
+      }
+      inseg.len -= (u16_t)(pcb->rcv_nxt - seqno);
+      inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
+    }
+    else {
+      if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
+        /* the whole segment is < rcv_nxt */
+        /* must be a duplicate of a packet that has already been correctly handled */
+
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno));
+        tcp_ack_now(pcb);
+      }
+    }
+
+    /* The sequence number must be within the window (above rcv_nxt
+       and below rcv_nxt + rcv_wnd) in order to be further
+       processed. */
+    if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, 
+                        pcb->rcv_nxt + pcb->rcv_wnd - 1)){
+      if (pcb->rcv_nxt == seqno) {
+        /* The incoming segment is the next in sequence. We check if
+           we have to trim the end of the segment and update rcv_nxt
+           and pass the data to the application. */
+        tcplen = TCP_TCPLEN(&inseg);
+
+        if (tcplen > pcb->rcv_wnd) {
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, 
+                      ("tcp_receive: other end overran receive window"
+                       "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
+                       seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
+          if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
+            /* Must remove the FIN from the header as we're trimming 
+             * that byte of sequence-space from the packet */
+            TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN);
+          }
+          /* Adjust length of segment to fit in the window. */
+          inseg.len = pcb->rcv_wnd;
+          if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
+            inseg.len -= 1;
+          }
+          pbuf_realloc(inseg.p, inseg.len);
+          tcplen = TCP_TCPLEN(&inseg);
+          LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
+                      (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
+        }
+#if TCP_QUEUE_OOSEQ
+        /* Received in-sequence data, adjust ooseq data if:
+           - FIN has been received or
+           - inseq overlaps with ooseq */
+        if (pcb->ooseq != NULL) {
+          if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, 
+                        ("tcp_receive: received in-order FIN, binning ooseq queue\n"));
+            /* Received in-order FIN means anything that was received
+             * out of order must now have been received in-order, so
+             * bin the ooseq queue */
+            while (pcb->ooseq != NULL) {
+              struct tcp_seg *old_ooseq = pcb->ooseq;
+              pcb->ooseq = pcb->ooseq->next;
+              tcp_seg_free(old_ooseq);
+            }
+          } else {
+            next = pcb->ooseq;
+            /* Remove all segments on ooseq that are covered by inseg already.
+             * FIN is copied from ooseq to inseg if present. */
+            while (next &&
+                   TCP_SEQ_GEQ(seqno + tcplen,
+                               next->tcphdr->seqno + next->len)) {
+              /* inseg cannot have FIN here (already processed above) */
+              if (TCPH_FLAGS(next->tcphdr) & TCP_FIN &&
+                  (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
+                TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN);
+                tcplen = TCP_TCPLEN(&inseg);
+              }
+              prev = next;
+              next = next->next;
+              tcp_seg_free(prev);
+            }
+            /* Now trim right side of inseg if it overlaps with the first
+             * segment on ooseq */
+            if (next &&
+                TCP_SEQ_GT(seqno + tcplen,
+                           next->tcphdr->seqno)) {
+              /* inseg cannot have FIN here (already processed above) */
+              inseg.len = (u16_t)(next->tcphdr->seqno - seqno);
+              if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
+                inseg.len -= 1;
+              }
+              pbuf_realloc(inseg.p, inseg.len);
+              tcplen = TCP_TCPLEN(&inseg);
+              LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
+                          (seqno + tcplen) == next->tcphdr->seqno);
+            }
+            pcb->ooseq = next;
+          }
+        }
+#endif /* TCP_QUEUE_OOSEQ */
+
+        pcb->rcv_nxt = seqno + tcplen;
+
+        /* Update the receiver's (our) window. */
+        LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen);
+        pcb->rcv_wnd -= tcplen;
+
+        tcp_update_rcv_ann_wnd(pcb);
+
+        /* If there is data in the segment, we make preparations to
+           pass this up to the application. The ->recv_data variable
+           is used for holding the pbuf that goes to the
+           application. The code for reassembling out-of-sequence data
+           chains its data on this pbuf as well.
+
+           If the segment was a FIN, we set the TF_GOT_FIN flag that will
+           be used to indicate to the application that the remote side has
+           closed its end of the connection. */
+        if (inseg.p->tot_len > 0) {
+          recv_data = inseg.p;
+          /* Since this pbuf now is the responsibility of the
+             application, we delete our reference to it so that we won't
+             (mistakingly) deallocate it. */
+          inseg.p = NULL;
+        }
+        if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
+          recv_flags |= TF_GOT_FIN;
+        }
+
+#if TCP_QUEUE_OOSEQ
+        /* We now check if we have segments on the ->ooseq queue that
+           are now in sequence. */
+        while (pcb->ooseq != NULL &&
+               pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
+
+          cseg = pcb->ooseq;
+          seqno = pcb->ooseq->tcphdr->seqno;
+
+          pcb->rcv_nxt += TCP_TCPLEN(cseg);
+          LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
+                      pcb->rcv_wnd >= TCP_TCPLEN(cseg));
+          pcb->rcv_wnd -= TCP_TCPLEN(cseg);
+
+          tcp_update_rcv_ann_wnd(pcb);
+
+          if (cseg->p->tot_len > 0) {
+            /* Chain this pbuf onto the pbuf that we will pass to
+               the application. */
+            if (recv_data) {
+              pbuf_cat(recv_data, cseg->p);
+            } else {
+              recv_data = cseg->p;
+            }
+            cseg->p = NULL;
+          }
+          if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
+            recv_flags |= TF_GOT_FIN;
+            if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
+              pcb->state = CLOSE_WAIT;
+            } 
+          }
+
+          pcb->ooseq = cseg->next;
+          tcp_seg_free(cseg);
+        }
+#endif /* TCP_QUEUE_OOSEQ */
+
+
+        /* Acknowledge the segment(s). */
+        tcp_ack(pcb);
+
+      } else {
+        /* We get here if the incoming segment is out-of-sequence. */
+        tcp_send_empty_ack(pcb);
+#if TCP_QUEUE_OOSEQ
+        /* We queue the segment on the ->ooseq queue. */
+        if (pcb->ooseq == NULL) {
+          pcb->ooseq = tcp_seg_copy(&inseg);
+        } else {
+          /* If the queue is not empty, we walk through the queue and
+             try to find a place where the sequence number of the
+             incoming segment is between the sequence numbers of the
+             previous and the next segment on the ->ooseq queue. That is
+             the place where we put the incoming segment. If needed, we
+             trim the second edges of the previous and the incoming
+             segment so that it will fit into the sequence.
+
+             If the incoming segment has the same sequence number as a
+             segment on the ->ooseq queue, we discard the segment that
+             contains less data. */
+
+          prev = NULL;
+          for(next = pcb->ooseq; next != NULL; next = next->next) {
+            if (seqno == next->tcphdr->seqno) {
+              /* The sequence number of the incoming segment is the
+                 same as the sequence number of the segment on
+                 ->ooseq. We check the lengths to see which one to
+                 discard. */
+              if (inseg.len > next->len) {
+                /* The incoming segment is larger than the old
+                   segment. We replace some segments with the new
+                   one. */
+                cseg = tcp_seg_copy(&inseg);
+                if (cseg != NULL) {
+                  if (prev != NULL) {
+                    prev->next = cseg;
+                  } else {
+                    pcb->ooseq = cseg;
+                  }
+                  tcp_oos_insert_segment(cseg, next);
+                }
+                break;
+              } else {
+                /* Either the lenghts are the same or the incoming
+                   segment was smaller than the old one; in either
+                   case, we ditch the incoming segment. */
+                break;
+              }
+            } else {
+              if (prev == NULL) {
+                if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
+                  /* The sequence number of the incoming segment is lower
+                     than the sequence number of the first segment on the
+                     queue. We put the incoming segment first on the
+                     queue. */
+                  cseg = tcp_seg_copy(&inseg);
+                  if (cseg != NULL) {
+                    pcb->ooseq = cseg;
+                    tcp_oos_insert_segment(cseg, next);
+                  }
+                  break;
+                }
+              } else {
+                /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
+                  TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/
+                if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) {
+                  /* The sequence number of the incoming segment is in
+                     between the sequence numbers of the previous and
+                     the next segment on ->ooseq. We trim trim the previous
+                     segment, delete next segments that included in received segment
+                     and trim received, if needed. */
+                  cseg = tcp_seg_copy(&inseg);
+                  if (cseg != NULL) {
+                    if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
+                      /* We need to trim the prev segment. */
+                      prev->len = (u16_t)(seqno - prev->tcphdr->seqno);
+                      pbuf_realloc(prev->p, prev->len);
+                    }
+                    prev->next = cseg;
+                    tcp_oos_insert_segment(cseg, next);
+                  }
+                  break;
+                }
+              }
+              /* If the "next" segment is the last segment on the
+                 ooseq queue, we add the incoming segment to the end
+                 of the list. */
+              if (next->next == NULL &&
+                  TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
+                if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
+                  /* segment "next" already contains all data */
+                  break;
+                }
+                next->next = tcp_seg_copy(&inseg);
+                if (next->next != NULL) {
+                  if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
+                    /* We need to trim the last segment. */
+                    next->len = (u16_t)(seqno - next->tcphdr->seqno);
+                    pbuf_realloc(next->p, next->len);
+                  }
+                  /* check if the remote side overruns our receive window */
+                  if ((u32_t)tcplen + seqno > pcb->rcv_nxt + (u32_t)pcb->rcv_wnd) {
+                    LWIP_DEBUGF(TCP_INPUT_DEBUG, 
+                                ("tcp_receive: other end overran receive window"
+                                 "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
+                                 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
+                    if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) {
+                      /* Must remove the FIN from the header as we're trimming 
+                       * that byte of sequence-space from the packet */
+                      TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) &~ TCP_FIN);
+                    }
+                    /* Adjust length of segment to fit in the window. */
+                    next->next->len = pcb->rcv_nxt + pcb->rcv_wnd - seqno;
+                    pbuf_realloc(next->next->p, next->next->len);
+                    tcplen = TCP_TCPLEN(next->next);
+                    LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
+                                (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
+                  }
+                }
+                break;
+              }
+            }
+            prev = next;
+          }
+        }
+#if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS
+        /* Check that the data on ooseq doesn't exceed one of the limits
+           and throw away everything above that limit. */
+        ooseq_blen = 0;
+        ooseq_qlen = 0;
+        prev = NULL;
+        for(next = pcb->ooseq; next != NULL; prev = next, next = next->next) {
+          struct pbuf *p = next->p;
+          ooseq_blen += p->tot_len;
+          ooseq_qlen += pbuf_clen(p);
+          if ((ooseq_blen > TCP_OOSEQ_MAX_BYTES) ||
+              (ooseq_qlen > TCP_OOSEQ_MAX_PBUFS)) {
+             /* too much ooseq data, dump this and everything after it */
+             tcp_segs_free(next);
+             if (prev == NULL) {
+               /* first ooseq segment is too much, dump the whole queue */
+               pcb->ooseq = NULL;
+             } else {
+               /* just dump 'next' and everything after it */
+               prev->next = NULL;
+             }
+             break;
+          }
+        }
+#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */
+#endif /* TCP_QUEUE_OOSEQ */
+      }
+    } else {
+      /* The incoming segment is not withing the window. */
+      tcp_send_empty_ack(pcb);
+    }
+  } else {
+    /* Segments with length 0 is taken care of here. Segments that
+       fall out of the window are ACKed. */
+    /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
+      TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
+    if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){
+      tcp_ack_now(pcb);
+    }
+  }
+}
+
+/**
+ * Parses the options contained in the incoming segment. 
+ *
+ * Called from tcp_listen_input() and tcp_process().
+ * Currently, only the MSS option is supported!
+ *
+ * @param pcb the tcp_pcb for which a segment arrived
+ */
+static void
+tcp_parseopt(struct tcp_pcb *pcb)
+{
+  u16_t c, max_c;
+  u16_t mss;
+  u8_t *opts, opt;
+#if LWIP_TCP_TIMESTAMPS
+  u32_t tsval;
+#endif
+
+  opts = (u8_t *)tcphdr + TCP_HLEN;
+
+  /* Parse the TCP MSS option, if present. */
+  if(TCPH_HDRLEN(tcphdr) > 0x5) {
+    max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2;
+    for (c = 0; c < max_c; ) {
+      opt = opts[c];
+      switch (opt) {
+      case 0x00:
+        /* End of options. */
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n"));
+        return;
+      case 0x01:
+        /* NOP option. */
+        ++c;
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n"));
+        break;
+      case 0x02:
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n"));
+        if (opts[c + 1] != 0x04 || c + 0x04 > max_c) {
+          /* Bad length */
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
+          return;
+        }
+        /* An MSS option with the right option length. */
+        mss = (opts[c + 2] << 8) | opts[c + 3];
+        /* Limit the mss to the configured TCP_MSS and prevent division by zero */
+        pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
+        /* Advance to next option */
+        c += 0x04;
+        break;
+#if LWIP_TCP_TIMESTAMPS
+      case 0x08:
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n"));
+        if (opts[c + 1] != 0x0A || c + 0x0A > max_c) {
+          /* Bad length */
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
+          return;
+        }
+        /* TCP timestamp option with valid length */
+        tsval = (opts[c+2]) | (opts[c+3] << 8) | 
+          (opts[c+4] << 16) | (opts[c+5] << 24);
+        if (flags & TCP_SYN) {
+          pcb->ts_recent = ntohl(tsval);
+          pcb->flags |= TF_TIMESTAMP;
+        } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) {
+          pcb->ts_recent = ntohl(tsval);
+        }
+        /* Advance to next option */
+        c += 0x0A;
+        break;
+#endif
+      default:
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n"));
+        if (opts[c + 1] == 0) {
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
+          /* If the length field is zero, the options are malformed
+             and we don't process them further. */
+          return;
+        }
+        /* All other options have a length field, so that we easily
+           can skip past them. */
+        c += opts[c + 1];
+      }
+    }
+  }
+}
+
+#endif /* LWIP_TCP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/tcp_out.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/tcp_out.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/tcp_out.c	(revision 164)
@@ -0,0 +1,1485 @@
+/**
+ * @file
+ * Transmission Control Protocol, outgoing traffic
+ *
+ * The output functions of TCP.
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/tcp_impl.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#if LWIP_TCP_TIMESTAMPS
+#include "lwip/sys.h"
+#endif
+
+#include <string.h>
+
+/* Define some copy-macros for checksum-on-copy so that the code looks
+   nicer by preventing too many ifdef's. */
+#if TCP_CHECKSUM_ON_COPY
+#define TCP_DATA_COPY(dst, src, len, seg) do { \
+  tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \
+                     len, &seg->chksum, &seg->chksum_swapped); \
+  seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0)
+#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped)  \
+  tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped);
+#else /* TCP_CHECKSUM_ON_COPY*/
+#define TCP_DATA_COPY(dst, src, len, seg)                     MEMCPY(dst, src, len)
+#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len)
+#endif /* TCP_CHECKSUM_ON_COPY*/
+
+/** Define this to 1 for an extra check that the output checksum is valid
+ * (usefule when the checksum is generated by the application, not the stack) */
+#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK
+#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK   0
+#endif
+
+/* Forward declarations.*/
+static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
+
+/** Allocate a pbuf and create a tcphdr at p->payload, used for output
+ * functions other than the default tcp_output -> tcp_output_segment
+ * (e.g. tcp_send_empty_ack, etc.)
+ *
+ * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr)
+ * @param optlen length of header-options
+ * @param datalen length of tcp data to reserve in pbuf
+ * @param seqno_be seqno in network byte order (big-endian)
+ * @return pbuf with p->payload being the tcp_hdr
+ */
+static struct pbuf *
+tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen,
+                      u32_t seqno_be /* already in network byte order */)
+{
+  struct tcp_hdr *tcphdr;
+  struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM);
+  if (p != NULL) {
+    LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
+                 (p->len >= TCP_HLEN + optlen));
+    tcphdr = (struct tcp_hdr *)p->payload;
+    tcphdr->src = htons(pcb->local_port);
+    tcphdr->dest = htons(pcb->remote_port);
+    tcphdr->seqno = seqno_be;
+    tcphdr->ackno = htonl(pcb->rcv_nxt);
+    TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK);
+    tcphdr->wnd = htons(pcb->rcv_ann_wnd);
+    tcphdr->chksum = 0;
+    tcphdr->urgp = 0;
+
+    /* If we're sending a packet, update the announced right window edge */
+    pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
+  }
+  return p;
+}
+
+/**
+ * Called by tcp_close() to send a segment including FIN flag but not data.
+ *
+ * @param pcb the tcp_pcb over which to send a segment
+ * @return ERR_OK if sent, another err_t otherwise
+ */
+err_t
+tcp_send_fin(struct tcp_pcb *pcb)
+{
+  /* first, try to add the fin to the last unsent segment */
+  if (pcb->unsent != NULL) {
+    struct tcp_seg *last_unsent;
+    for (last_unsent = pcb->unsent; last_unsent->next != NULL;
+         last_unsent = last_unsent->next);
+
+    if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) {
+      /* no SYN/FIN/RST flag in the header, we can add the FIN flag */
+      TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN);
+      pcb->flags |= TF_FIN;
+      return ERR_OK;
+    }
+  }
+  /* no data, no length, flags, copy=1, no optdata */
+  return tcp_enqueue_flags(pcb, TCP_FIN);
+}
+
+/**
+ * Create a TCP segment with prefilled header.
+ *
+ * Called by tcp_write and tcp_enqueue_flags.
+ *
+ * @param pcb Protocol control block for the TCP connection.
+ * @param p pbuf that is used to hold the TCP header.
+ * @param flags TCP flags for header.
+ * @param seqno TCP sequence number of this packet
+ * @param optflags options to include in TCP header
+ * @return a new tcp_seg pointing to p, or NULL.
+ * The TCP header is filled in except ackno and wnd.
+ * p is freed on failure.
+ */
+static struct tcp_seg *
+tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, u8_t optflags)
+{
+  struct tcp_seg *seg;
+  u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags);
+
+  if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no memory.\n"));
+    pbuf_free(p);
+    return NULL;
+  }
+  seg->flags = optflags;
+  seg->next = NULL;
+  seg->p = p;
+  seg->len = p->tot_len - optlen;
+#if TCP_OVERSIZE_DBGCHECK
+  seg->oversize_left = 0;
+#endif /* TCP_OVERSIZE_DBGCHECK */
+#if TCP_CHECKSUM_ON_COPY
+  seg->chksum = 0;
+  seg->chksum_swapped = 0;
+  /* check optflags */
+  LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED",
+              (optflags & TF_SEG_DATA_CHECKSUMMED) == 0);
+#endif /* TCP_CHECKSUM_ON_COPY */
+
+  /* build TCP header */
+  if (pbuf_header(p, TCP_HLEN)) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no room for TCP header in pbuf.\n"));
+    TCP_STATS_INC(tcp.err);
+    tcp_seg_free(seg);
+    return NULL;
+  }
+  seg->tcphdr = (struct tcp_hdr *)seg->p->payload;
+  seg->tcphdr->src = htons(pcb->local_port);
+  seg->tcphdr->dest = htons(pcb->remote_port);
+  seg->tcphdr->seqno = htonl(seqno);
+  /* ackno is set in tcp_output */
+  TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), flags);
+  /* wnd and chksum are set in tcp_output */
+  seg->tcphdr->urgp = 0;
+  return seg;
+} 
+
+/**
+ * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end.
+ *
+ * This function is like pbuf_alloc(layer, length, PBUF_RAM) except
+ * there may be extra bytes available at the end.
+ *
+ * @param layer flag to define header size.
+ * @param length size of the pbuf's payload.
+ * @param max_length maximum usable size of payload+oversize.
+ * @param oversize pointer to a u16_t that will receive the number of usable tail bytes.
+ * @param pcb The TCP connection that willo enqueue the pbuf.
+ * @param apiflags API flags given to tcp_write.
+ * @param first_seg true when this pbuf will be used in the first enqueued segment.
+ * @param 
+ */
+#if TCP_OVERSIZE
+static struct pbuf *
+tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length,
+                  u16_t *oversize, struct tcp_pcb *pcb, u8_t apiflags,
+                  u8_t first_seg)
+{
+  struct pbuf *p;
+  u16_t alloc = length;
+
+#if LWIP_NETIF_TX_SINGLE_PBUF
+  LWIP_UNUSED_ARG(max_length);
+  LWIP_UNUSED_ARG(pcb);
+  LWIP_UNUSED_ARG(apiflags);
+  LWIP_UNUSED_ARG(first_seg);
+  /* always create MSS-sized pbufs */
+  alloc = max_length;
+#else /* LWIP_NETIF_TX_SINGLE_PBUF */
+  if (length < max_length) {
+    /* Should we allocate an oversized pbuf, or just the minimum
+     * length required? If tcp_write is going to be called again
+     * before this segment is transmitted, we want the oversized
+     * buffer. If the segment will be transmitted immediately, we can
+     * save memory by allocating only length. We use a simple
+     * heuristic based on the following information:
+     *
+     * Did the user set TCP_WRITE_FLAG_MORE?
+     *
+     * Will the Nagle algorithm defer transmission of this segment?
+     */
+    if ((apiflags & TCP_WRITE_FLAG_MORE) ||
+        (!(pcb->flags & TF_NODELAY) &&
+         (!first_seg ||
+          pcb->unsent != NULL ||
+          pcb->unacked != NULL))) {
+      alloc = LWIP_MIN(max_length, LWIP_MEM_ALIGN_SIZE(length + TCP_OVERSIZE));
+    }
+  }
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
+  p = pbuf_alloc(layer, alloc, PBUF_RAM);
+  if (p == NULL) {
+    return NULL;
+  }
+  LWIP_ASSERT("need unchained pbuf", p->next == NULL);
+  *oversize = p->len - length;
+  /* trim p->len to the currently used size */
+  p->len = p->tot_len = length;
+  return p;
+}
+#else /* TCP_OVERSIZE */
+#define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM)
+#endif /* TCP_OVERSIZE */
+
+#if TCP_CHECKSUM_ON_COPY
+/** Add a checksum of newly added data to the segment */
+static void
+tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum,
+                   u8_t *seg_chksum_swapped)
+{
+  u32_t helper;
+  /* add chksum to old chksum and fold to u16_t */
+  helper = chksum + *seg_chksum;
+  chksum = FOLD_U32T(helper);
+  if ((len & 1) != 0) {
+    *seg_chksum_swapped = 1 - *seg_chksum_swapped;
+    chksum = SWAP_BYTES_IN_WORD(chksum);
+  }
+  *seg_chksum = chksum;
+}
+#endif /* TCP_CHECKSUM_ON_COPY */
+
+/** Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen).
+ *
+ * @param pcb the tcp pcb to check for
+ * @param len length of data to send (checked agains snd_buf)
+ * @return ERR_OK if tcp_write is allowed to proceed, another err_t otherwise
+ */
+static err_t
+tcp_write_checks(struct tcp_pcb *pcb, u16_t len)
+{
+  /* connection is in invalid state for data transmission? */
+  if ((pcb->state != ESTABLISHED) &&
+      (pcb->state != CLOSE_WAIT) &&
+      (pcb->state != SYN_SENT) &&
+      (pcb->state != SYN_RCVD)) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n"));
+    return ERR_CONN;
+  } else if (len == 0) {
+    return ERR_OK;
+  }
+
+  /* fail on too much data */
+  if (len > pcb->snd_buf) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n",
+      len, pcb->snd_buf));
+    pcb->flags |= TF_NAGLEMEMERR;
+    return ERR_MEM;
+  }
+
+  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
+
+  /* If total number of pbufs on the unsent/unacked queues exceeds the
+   * configured maximum, return an error */
+  /* check for configured max queuelen and possible overflow */
+  if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n",
+      pcb->snd_queuelen, TCP_SND_QUEUELEN));
+    TCP_STATS_INC(tcp.memerr);
+    pcb->flags |= TF_NAGLEMEMERR;
+    return ERR_MEM;
+  }
+  if (pcb->snd_queuelen != 0) {
+    LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty",
+      pcb->unacked != NULL || pcb->unsent != NULL);
+  } else {
+    LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty",
+      pcb->unacked == NULL && pcb->unsent == NULL);
+  }
+  return ERR_OK;
+}
+
+/**
+ * Write data for sending (but does not send it immediately).
+ *
+ * It waits in the expectation of more data being sent soon (as
+ * it can send them more efficiently by combining them together).
+ * To prompt the system to send data now, call tcp_output() after
+ * calling tcp_write().
+ *
+ * @param pcb Protocol control block for the TCP connection to enqueue data for.
+ * @param arg Pointer to the data to be enqueued for sending.
+ * @param len Data length in bytes
+ * @param apiflags combination of following flags :
+ * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
+ * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent,
+ * @return ERR_OK if enqueued, another err_t on error
+ */
+err_t
+tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
+{
+  struct pbuf *concat_p = NULL;
+  struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL;
+  u16_t pos = 0; /* position in 'arg' data */
+  u16_t queuelen;
+  u8_t optlen = 0;
+  u8_t optflags = 0;
+#if TCP_OVERSIZE
+  u16_t oversize = 0;
+  u16_t oversize_used = 0;
+#endif /* TCP_OVERSIZE */
+#if TCP_CHECKSUM_ON_COPY
+  u16_t concat_chksum = 0;
+  u8_t concat_chksum_swapped = 0;
+  u16_t concat_chksummed = 0;
+#endif /* TCP_CHECKSUM_ON_COPY */
+  err_t err;
+  /* don't allocate segments bigger than half the maximum window we ever received */
+  u16_t mss_local = LWIP_MIN(pcb->mss, pcb->snd_wnd_max/2);
+
+#if LWIP_NETIF_TX_SINGLE_PBUF
+  /* Always copy to try to create single pbufs for TX */
+  apiflags |= TCP_WRITE_FLAG_COPY;
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
+
+  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n",
+    (void *)pcb, arg, len, (u16_t)apiflags));
+  LWIP_ERROR("tcp_write: arg == NULL (programmer violates API)", 
+             arg != NULL, return ERR_ARG;);
+
+  err = tcp_write_checks(pcb, len);
+  if (err != ERR_OK) {
+    return err;
+  }
+  queuelen = pcb->snd_queuelen;
+
+#if LWIP_TCP_TIMESTAMPS
+  if ((pcb->flags & TF_TIMESTAMP)) {
+    optflags = TF_SEG_OPTS_TS;
+    optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
+  }
+#endif /* LWIP_TCP_TIMESTAMPS */
+
+
+  /*
+   * TCP segmentation is done in three phases with increasing complexity:
+   *
+   * 1. Copy data directly into an oversized pbuf.
+   * 2. Chain a new pbuf to the end of pcb->unsent.
+   * 3. Create new segments.
+   *
+   * We may run out of memory at any point. In that case we must
+   * return ERR_MEM and not change anything in pcb. Therefore, all
+   * changes are recorded in local variables and committed at the end
+   * of the function. Some pcb fields are maintained in local copies:
+   *
+   * queuelen = pcb->snd_queuelen
+   * oversize = pcb->unsent_oversize
+   *
+   * These variables are set consistently by the phases:
+   *
+   * seg points to the last segment tampered with.
+   *
+   * pos records progress as data is segmented.
+   */
+
+  /* Find the tail of the unsent queue. */
+  if (pcb->unsent != NULL) {
+    u16_t space;
+    u16_t unsent_optlen;
+
+    /* @todo: this could be sped up by keeping last_unsent in the pcb */
+    for (last_unsent = pcb->unsent; last_unsent->next != NULL;
+         last_unsent = last_unsent->next);
+
+    /* Usable space at the end of the last unsent segment */
+    unsent_optlen = LWIP_TCP_OPT_LENGTH(last_unsent->flags);
+    space = mss_local - (last_unsent->len + unsent_optlen);
+
+    /*
+     * Phase 1: Copy data directly into an oversized pbuf.
+     *
+     * The number of bytes copied is recorded in the oversize_used
+     * variable. The actual copying is done at the bottom of the
+     * function.
+     */
+#if TCP_OVERSIZE
+#if TCP_OVERSIZE_DBGCHECK
+    /* check that pcb->unsent_oversize matches last_unsent->unsent_oversize */
+    LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)",
+                pcb->unsent_oversize == last_unsent->oversize_left);
+#endif /* TCP_OVERSIZE_DBGCHECK */
+    oversize = pcb->unsent_oversize;
+    if (oversize > 0) {
+      LWIP_ASSERT("inconsistent oversize vs. space", oversize_used <= space);
+      seg = last_unsent;
+      oversize_used = oversize < len ? oversize : len;
+      pos += oversize_used;
+      oversize -= oversize_used;
+      space -= oversize_used;
+    }
+    /* now we are either finished or oversize is zero */
+    LWIP_ASSERT("inconsistend oversize vs. len", (oversize == 0) || (pos == len));
+#endif /* TCP_OVERSIZE */
+
+    /*
+     * Phase 2: Chain a new pbuf to the end of pcb->unsent.
+     *
+     * We don't extend segments containing SYN/FIN flags or options
+     * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at
+     * the end.
+     */
+    if ((pos < len) && (space > 0) && (last_unsent->len > 0)) {
+      u16_t seglen = space < len - pos ? space : len - pos;
+      seg = last_unsent;
+
+      /* Create a pbuf with a copy or reference to seglen bytes. We
+       * can use PBUF_RAW here since the data appears in the middle of
+       * a segment. A header will never be prepended. */
+      if (apiflags & TCP_WRITE_FLAG_COPY) {
+        /* Data is copied */
+        if ((concat_p = tcp_pbuf_prealloc(PBUF_RAW, seglen, space, &oversize, pcb, apiflags, 1)) == NULL) {
+          LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2,
+                      ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n",
+                       seglen));
+          goto memerr;
+        }
+#if TCP_OVERSIZE_DBGCHECK
+        last_unsent->oversize_left += oversize;
+#endif /* TCP_OVERSIZE_DBGCHECK */
+        TCP_DATA_COPY2(concat_p->payload, (u8_t*)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped);
+#if TCP_CHECKSUM_ON_COPY
+        concat_chksummed += seglen;
+#endif /* TCP_CHECKSUM_ON_COPY */
+      } else {
+        /* Data is not copied */
+        if ((concat_p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) {
+          LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2,
+                      ("tcp_write: could not allocate memory for zero-copy pbuf\n"));
+          goto memerr;
+        }
+#if TCP_CHECKSUM_ON_COPY
+        /* calculate the checksum of nocopy-data */
+        tcp_seg_add_chksum(~inet_chksum((u8_t*)arg + pos, seglen), seglen,
+          &concat_chksum, &concat_chksum_swapped);
+        concat_chksummed += seglen;
+#endif /* TCP_CHECKSUM_ON_COPY */
+        /* reference the non-volatile payload data */
+        concat_p->payload = (u8_t*)arg + pos;
+      }
+
+      pos += seglen;
+      queuelen += pbuf_clen(concat_p);
+    }
+  } else {
+#if TCP_OVERSIZE
+    LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)",
+                pcb->unsent_oversize == 0);
+#endif /* TCP_OVERSIZE */
+  }
+
+  /*
+   * Phase 3: Create new segments.
+   *
+   * The new segments are chained together in the local 'queue'
+   * variable, ready to be appended to pcb->unsent.
+   */
+  while (pos < len) {
+    struct pbuf *p;
+    u16_t left = len - pos;
+    u16_t max_len = mss_local - optlen;
+    u16_t seglen = left > max_len ? max_len : left;
+#if TCP_CHECKSUM_ON_COPY
+    u16_t chksum = 0;
+    u8_t chksum_swapped = 0;
+#endif /* TCP_CHECKSUM_ON_COPY */
+
+    if (apiflags & TCP_WRITE_FLAG_COPY) {
+      /* If copy is set, memory should be allocated and data copied
+       * into pbuf */
+      if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, mss_local, &oversize, pcb, apiflags, queue == NULL)) == NULL) {
+        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
+        goto memerr;
+      }
+      LWIP_ASSERT("tcp_write: check that first pbuf can hold the complete seglen",
+                  (p->len >= seglen));
+      TCP_DATA_COPY2((char *)p->payload + optlen, (u8_t*)arg + pos, seglen, &chksum, &chksum_swapped);
+    } else {
+      /* Copy is not set: First allocate a pbuf for holding the data.
+       * Since the referenced data is available at least until it is
+       * sent out on the link (as it has to be ACKed by the remote
+       * party) we can safely use PBUF_ROM instead of PBUF_REF here.
+       */
+      struct pbuf *p2;
+#if TCP_OVERSIZE
+      LWIP_ASSERT("oversize == 0", oversize == 0);
+#endif /* TCP_OVERSIZE */
+      if ((p2 = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
+        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for zero-copy pbuf\n"));
+        goto memerr;
+      }
+#if TCP_CHECKSUM_ON_COPY
+      /* calculate the checksum of nocopy-data */
+      chksum = ~inet_chksum((u8_t*)arg + pos, seglen);
+#endif /* TCP_CHECKSUM_ON_COPY */
+      /* reference the non-volatile payload data */
+      p2->payload = (u8_t*)arg + pos;
+
+      /* Second, allocate a pbuf for the headers. */
+      if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
+        /* If allocation fails, we have to deallocate the data pbuf as
+         * well. */
+        pbuf_free(p2);
+        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for header pbuf\n"));
+        goto memerr;
+      }
+      /* Concatenate the headers and data pbufs together. */
+      pbuf_cat(p/*header*/, p2/*data*/);
+    }
+
+    queuelen += pbuf_clen(p);
+
+    /* Now that there are more segments queued, we check again if the
+     * length of the queue exceeds the configured maximum or
+     * overflows. */
+    if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
+      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
+      pbuf_free(p);
+      goto memerr;
+    }
+
+    if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) {
+      goto memerr;
+    }
+#if TCP_OVERSIZE_DBGCHECK
+    seg->oversize_left = oversize;
+#endif /* TCP_OVERSIZE_DBGCHECK */
+#if TCP_CHECKSUM_ON_COPY
+    seg->chksum = chksum;
+    seg->chksum_swapped = chksum_swapped;
+    seg->flags |= TF_SEG_DATA_CHECKSUMMED;
+#endif /* TCP_CHECKSUM_ON_COPY */
+
+    /* first segment of to-be-queued data? */
+    if (queue == NULL) {
+      queue = seg;
+    } else {
+      /* Attach the segment to the end of the queued segments */
+      LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL);
+      prev_seg->next = seg;
+    }
+    /* remember last segment of to-be-queued data for next iteration */
+    prev_seg = seg;
+
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n",
+      ntohl(seg->tcphdr->seqno),
+      ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg)));
+
+    pos += seglen;
+  }
+
+  /*
+   * All three segmentation phases were successful. We can commit the
+   * transaction.
+   */
+
+  /*
+   * Phase 1: If data has been added to the preallocated tail of
+   * last_unsent, we update the length fields of the pbuf chain.
+   */
+#if TCP_OVERSIZE
+  if (oversize_used > 0) {
+    struct pbuf *p;
+    /* Bump tot_len of whole chain, len of tail */
+    for (p = last_unsent->p; p; p = p->next) {
+      p->tot_len += oversize_used;
+      if (p->next == NULL) {
+        TCP_DATA_COPY((char *)p->payload + p->len, arg, oversize_used, last_unsent);
+        p->len += oversize_used;
+      }
+    }
+    last_unsent->len += oversize_used;
+#if TCP_OVERSIZE_DBGCHECK
+    LWIP_ASSERT("last_unsent->oversize_left >= oversize_used",
+                last_unsent->oversize_left >= oversize_used);
+    last_unsent->oversize_left -= oversize_used;
+#endif /* TCP_OVERSIZE_DBGCHECK */
+  }
+  pcb->unsent_oversize = oversize;
+#endif /* TCP_OVERSIZE */
+
+  /*
+   * Phase 2: concat_p can be concatenated onto last_unsent->p
+   */
+  if (concat_p != NULL) {
+    LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty",
+      (last_unsent != NULL));
+    pbuf_cat(last_unsent->p, concat_p);
+    last_unsent->len += concat_p->tot_len;
+#if TCP_CHECKSUM_ON_COPY
+    if (concat_chksummed) {
+      tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum,
+        &last_unsent->chksum_swapped);
+      last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED;
+    }
+#endif /* TCP_CHECKSUM_ON_COPY */
+  }
+
+  /*
+   * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that
+   * is harmless
+   */
+  if (last_unsent == NULL) {
+    pcb->unsent = queue;
+  } else {
+    last_unsent->next = queue;
+  }
+
+  /*
+   * Finally update the pcb state.
+   */
+  pcb->snd_lbb += len;
+  pcb->snd_buf -= len;
+  pcb->snd_queuelen = queuelen;
+
+  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n",
+    pcb->snd_queuelen));
+  if (pcb->snd_queuelen != 0) {
+    LWIP_ASSERT("tcp_write: valid queue length",
+                pcb->unacked != NULL || pcb->unsent != NULL);
+  }
+
+  /* Set the PSH flag in the last segment that we enqueued. */
+  if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) {
+    TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
+  }
+
+  return ERR_OK;
+memerr:
+  pcb->flags |= TF_NAGLEMEMERR;
+  TCP_STATS_INC(tcp.memerr);
+
+  if (concat_p != NULL) {
+    pbuf_free(concat_p);
+  }
+  if (queue != NULL) {
+    tcp_segs_free(queue);
+  }
+  if (pcb->snd_queuelen != 0) {
+    LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL ||
+      pcb->unsent != NULL);
+  }
+  LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
+  return ERR_MEM;
+}
+
+/**
+ * Enqueue TCP options for transmission.
+ *
+ * Called by tcp_connect(), tcp_listen_input(), and tcp_send_ctrl().
+ *
+ * @param pcb Protocol control block for the TCP connection.
+ * @param flags TCP header flags to set in the outgoing segment.
+ * @param optdata pointer to TCP options, or NULL.
+ * @param optlen length of TCP options in bytes.
+ */
+err_t
+tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags)
+{
+  struct pbuf *p;
+  struct tcp_seg *seg;
+  u8_t optflags = 0;
+  u8_t optlen = 0;
+
+  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
+
+  LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)",
+              (flags & (TCP_SYN | TCP_FIN)) != 0);
+
+  /* check for configured max queuelen and possible overflow */
+  if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n",
+                                       pcb->snd_queuelen, TCP_SND_QUEUELEN));
+    TCP_STATS_INC(tcp.memerr);
+    pcb->flags |= TF_NAGLEMEMERR;
+    return ERR_MEM;
+  }
+
+  if (flags & TCP_SYN) {
+    optflags = TF_SEG_OPTS_MSS;
+  }
+#if LWIP_TCP_TIMESTAMPS
+  if ((pcb->flags & TF_TIMESTAMP)) {
+    optflags |= TF_SEG_OPTS_TS;
+  }
+#endif /* LWIP_TCP_TIMESTAMPS */
+  optlen = LWIP_TCP_OPT_LENGTH(optflags);
+
+  /* tcp_enqueue_flags is always called with either SYN or FIN in flags.
+   * We need one available snd_buf byte to do that.
+   * This means we can't send FIN while snd_buf==0. A better fix would be to
+   * not include SYN and FIN sequence numbers in the snd_buf count. */
+  if (pcb->snd_buf == 0) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: no send buffer available\n"));
+    TCP_STATS_INC(tcp.memerr);
+    return ERR_MEM;
+  }
+
+  /* Allocate pbuf with room for TCP header + options */
+  if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
+    pcb->flags |= TF_NAGLEMEMERR;
+    TCP_STATS_INC(tcp.memerr);
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen",
+              (p->len >= optlen));
+
+  /* Allocate memory for tcp_seg, and fill in fields. */
+  if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) {
+    pcb->flags |= TF_NAGLEMEMERR;
+    TCP_STATS_INC(tcp.memerr);
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0);
+  LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0);
+
+  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE,
+              ("tcp_enqueue_flags: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n",
+               ntohl(seg->tcphdr->seqno),
+               ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
+               (u16_t)flags));
+
+  /* Now append seg to pcb->unsent queue */
+  if (pcb->unsent == NULL) {
+    pcb->unsent = seg;
+  } else {
+    struct tcp_seg *useg;
+    for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
+    useg->next = seg;
+  }
+#if TCP_OVERSIZE
+  /* The new unsent tail has no space */
+  pcb->unsent_oversize = 0;
+#endif /* TCP_OVERSIZE */
+
+  /* SYN and FIN bump the sequence number */
+  if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
+    pcb->snd_lbb++;
+    /* optlen does not influence snd_buf */
+    pcb->snd_buf--;
+  }
+  if (flags & TCP_FIN) {
+    pcb->flags |= TF_FIN;
+  }
+
+  /* update number of segments on the queues */
+  pcb->snd_queuelen += pbuf_clen(seg->p);
+  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));
+  if (pcb->snd_queuelen != 0) {
+    LWIP_ASSERT("tcp_enqueue_flags: invalid queue length",
+      pcb->unacked != NULL || pcb->unsent != NULL);
+  }
+
+  return ERR_OK;
+}
+
+#if LWIP_TCP_TIMESTAMPS
+/* Build a timestamp option (12 bytes long) at the specified options pointer)
+ *
+ * @param pcb tcp_pcb
+ * @param opts option pointer where to store the timestamp option
+ */
+static void
+tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts)
+{
+  /* Pad with two NOP options to make everything nicely aligned */
+  opts[0] = PP_HTONL(0x0101080A);
+  opts[1] = htonl(sys_now());
+  opts[2] = htonl(pcb->ts_recent);
+}
+#endif
+
+/** Send an ACK without data.
+ *
+ * @param pcb Protocol control block for the TCP connection to send the ACK
+ */
+err_t
+tcp_send_empty_ack(struct tcp_pcb *pcb)
+{
+  struct pbuf *p;
+  struct tcp_hdr *tcphdr;
+  u8_t optlen = 0;
+
+#if LWIP_TCP_TIMESTAMPS
+  if (pcb->flags & TF_TIMESTAMP) {
+    optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
+  }
+#endif
+
+  p = tcp_output_alloc_header(pcb, optlen, 0, htonl(pcb->snd_nxt));
+  if (p == NULL) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
+    return ERR_BUF;
+  }
+  tcphdr = (struct tcp_hdr *)p->payload;
+  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, 
+              ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
+  /* remove ACK flags from the PCB, as we send an empty ACK now */
+  pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
+
+  /* NB. MSS option is only sent on SYNs, so ignore it here */
+#if LWIP_TCP_TIMESTAMPS
+  pcb->ts_lastacksent = pcb->rcv_nxt;
+
+  if (pcb->flags & TF_TIMESTAMP) {
+    tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1));
+  }
+#endif 
+
+#if CHECKSUM_GEN_TCP
+  tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
+        IP_PROTO_TCP, p->tot_len);
+#endif
+#if LWIP_NETIF_HWADDRHINT
+  ip_output_hinted(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
+      IP_PROTO_TCP, &(pcb->addr_hint));
+#else /* LWIP_NETIF_HWADDRHINT*/
+  ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
+      IP_PROTO_TCP);
+#endif /* LWIP_NETIF_HWADDRHINT*/
+  pbuf_free(p);
+
+  return ERR_OK;
+}
+
+/**
+ * Find out what we can send and send it
+ *
+ * @param pcb Protocol control block for the TCP connection to send data
+ * @return ERR_OK if data has been sent or nothing to send
+ *         another err_t on error
+ */
+err_t
+tcp_output(struct tcp_pcb *pcb)
+{
+  struct tcp_seg *seg, *useg;
+  u32_t wnd, snd_nxt;
+#if TCP_CWND_DEBUG
+  s16_t i = 0;
+#endif /* TCP_CWND_DEBUG */
+
+  /* pcb->state LISTEN not allowed here */
+  LWIP_ASSERT("don't call tcp_output for listen-pcbs",
+    pcb->state != LISTEN);
+
+  /* First, check if we are invoked by the TCP input processing
+     code. If so, we do not output anything. Instead, we rely on the
+     input processing code to call us when input processing is done
+     with. */
+  if (tcp_input_pcb == pcb) {
+    return ERR_OK;
+  }
+
+  wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
+
+  seg = pcb->unsent;
+
+  /* If the TF_ACK_NOW flag is set and no data will be sent (either
+   * because the ->unsent queue is empty or because the window does
+   * not allow it), construct an empty ACK segment and send it.
+   *
+   * If data is to be sent, we will just piggyback the ACK (see below).
+   */
+  if (pcb->flags & TF_ACK_NOW &&
+     (seg == NULL ||
+      ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
+     return tcp_send_empty_ack(pcb);
+  }
+
+  /* useg should point to last segment on unacked queue */
+  useg = pcb->unacked;
+  if (useg != NULL) {
+    for (; useg->next != NULL; useg = useg->next);
+  }
+
+#if TCP_OUTPUT_DEBUG
+  if (seg == NULL) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n",
+                                   (void*)pcb->unsent));
+  }
+#endif /* TCP_OUTPUT_DEBUG */
+#if TCP_CWND_DEBUG
+  if (seg == NULL) {
+    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F
+                                 ", cwnd %"U16_F", wnd %"U32_F
+                                 ", seg == NULL, ack %"U32_F"\n",
+                                 pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack));
+  } else {
+    LWIP_DEBUGF(TCP_CWND_DEBUG, 
+                ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F
+                 ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
+                 pcb->snd_wnd, pcb->cwnd, wnd,
+                 ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
+                 ntohl(seg->tcphdr->seqno), pcb->lastack));
+  }
+#endif /* TCP_CWND_DEBUG */
+  /* data available and window allows it to be sent? */
+  while (seg != NULL &&
+         ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
+    LWIP_ASSERT("RST not expected here!", 
+                (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
+    /* Stop sending if the nagle algorithm would prevent it
+     * Don't stop:
+     * - if tcp_write had a memory error before (prevent delayed ACK timeout) or
+     * - if FIN was already enqueued for this PCB (SYN is always alone in a segment -
+     *   either seg->next != NULL or pcb->unacked == NULL;
+     *   RST is no sent using tcp_write/tcp_output.
+     */
+    if((tcp_do_output_nagle(pcb) == 0) &&
+      ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){
+      break;
+    }
+#if TCP_CWND_DEBUG
+    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n",
+                            pcb->snd_wnd, pcb->cwnd, wnd,
+                            ntohl(seg->tcphdr->seqno) + seg->len -
+                            pcb->lastack,
+                            ntohl(seg->tcphdr->seqno), pcb->lastack, i));
+    ++i;
+#endif /* TCP_CWND_DEBUG */
+
+    pcb->unsent = seg->next;
+
+    if (pcb->state != SYN_SENT) {
+      TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
+      pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
+    }
+
+    tcp_output_segment(seg, pcb);
+    snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
+    if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
+      pcb->snd_nxt = snd_nxt;
+    }
+    /* put segment on unacknowledged list if length > 0 */
+    if (TCP_TCPLEN(seg) > 0) {
+      seg->next = NULL;
+      /* unacked list is empty? */
+      if (pcb->unacked == NULL) {
+        pcb->unacked = seg;
+        useg = seg;
+      /* unacked list is not empty? */
+      } else {
+        /* In the case of fast retransmit, the packet should not go to the tail
+         * of the unacked queue, but rather somewhere before it. We need to check for
+         * this case. -STJ Jul 27, 2004 */
+        if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))) {
+          /* add segment to before tail of unacked list, keeping the list sorted */
+          struct tcp_seg **cur_seg = &(pcb->unacked);
+          while (*cur_seg &&
+            TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) {
+              cur_seg = &((*cur_seg)->next );
+          }
+          seg->next = (*cur_seg);
+          (*cur_seg) = seg;
+        } else {
+          /* add segment to tail of unacked list */
+          useg->next = seg;
+          useg = useg->next;
+        }
+      }
+    /* do not queue empty segments on the unacked list */
+    } else {
+      tcp_seg_free(seg);
+    }
+    seg = pcb->unsent;
+  }
+#if TCP_OVERSIZE
+  if (pcb->unsent == NULL) {
+    /* last unsent has been removed, reset unsent_oversize */
+    pcb->unsent_oversize = 0;
+  }
+#endif /* TCP_OVERSIZE */
+
+  pcb->flags &= ~TF_NAGLEMEMERR;
+  return ERR_OK;
+}
+
+/**
+ * Called by tcp_output() to actually send a TCP segment over IP.
+ *
+ * @param seg the tcp_seg to send
+ * @param pcb the tcp_pcb for the TCP connection used to send the segment
+ */
+static void
+tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
+{
+  u16_t len;
+  struct netif *netif;
+  u32_t *opts;
+
+  /** @bug Exclude retransmitted segments from this count. */
+  snmp_inc_tcpoutsegs();
+
+  /* The TCP header has already been constructed, but the ackno and
+   wnd fields remain. */
+  seg->tcphdr->ackno = htonl(pcb->rcv_nxt);
+
+  /* advertise our receive window size in this TCP segment */
+  seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd);
+
+  pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
+
+  /* Add any requested options.  NB MSS option is only set on SYN
+     packets, so ignore it here */
+  opts = (u32_t *)(void *)(seg->tcphdr + 1);
+  if (seg->flags & TF_SEG_OPTS_MSS) {
+    u16_t mss;
+#if TCP_CALCULATE_EFF_SEND_MSS
+    mss = tcp_eff_send_mss(TCP_MSS, &pcb->remote_ip);
+#else /* TCP_CALCULATE_EFF_SEND_MSS */
+    mss = TCP_MSS;
+#endif /* TCP_CALCULATE_EFF_SEND_MSS */
+    *opts = TCP_BUILD_MSS_OPTION(mss);
+    opts += 1;
+  }
+#if LWIP_TCP_TIMESTAMPS
+  pcb->ts_lastacksent = pcb->rcv_nxt;
+
+  if (seg->flags & TF_SEG_OPTS_TS) {
+    tcp_build_timestamp_option(pcb, opts);
+    opts += 3;
+  }
+#endif
+
+  /* Set retransmission timer running if it is not currently enabled 
+     This must be set before checking the route. */
+  if (pcb->rtime == -1) {
+    pcb->rtime = 0;
+  }
+
+  /* If we don't have a local IP address, we get one by
+     calling ip_route(). */
+  if (ip_addr_isany(&(pcb->local_ip))) {
+    netif = ip_route(&(pcb->remote_ip));
+    if (netif == NULL) {
+      return;
+    }
+    ip_addr_copy(pcb->local_ip, netif->ip_addr);
+  }
+
+  if (pcb->rttest == 0) {
+    pcb->rttest = tcp_ticks;
+    pcb->rtseq = ntohl(seg->tcphdr->seqno);
+
+    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq));
+  }
+  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n",
+          htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +
+          seg->len));
+
+  len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
+
+  seg->p->len -= len;
+  seg->p->tot_len -= len;
+
+  seg->p->payload = seg->tcphdr;
+
+  seg->tcphdr->chksum = 0;
+#if CHECKSUM_GEN_TCP
+#if TCP_CHECKSUM_ON_COPY
+  {
+    u32_t acc;
+#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
+    u16_t chksum_slow = inet_chksum_pseudo(seg->p, &(pcb->local_ip),
+           &(pcb->remote_ip),
+           IP_PROTO_TCP, seg->p->tot_len);
+#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
+    if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) {
+      LWIP_ASSERT("data included but not checksummed",
+        seg->p->tot_len == (TCPH_HDRLEN(seg->tcphdr) * 4));
+    }
+
+    /* rebuild TCP header checksum (TCP header changes for retransmissions!) */
+    acc = inet_chksum_pseudo_partial(seg->p, &(pcb->local_ip),
+             &(pcb->remote_ip),
+             IP_PROTO_TCP, seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4);
+    /* add payload checksum */
+    if (seg->chksum_swapped) {
+      seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum);
+      seg->chksum_swapped = 0;
+    }
+    acc += (u16_t)~(seg->chksum);
+    seg->tcphdr->chksum = FOLD_U32T(acc);
+#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
+    if (chksum_slow != seg->tcphdr->chksum) {
+      LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING,
+                  ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n",
+                  seg->tcphdr->chksum, chksum_slow));
+      seg->tcphdr->chksum = chksum_slow;
+    }
+#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
+  }
+#else /* TCP_CHECKSUM_ON_COPY */
+  seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip),
+         &(pcb->remote_ip),
+         IP_PROTO_TCP, seg->p->tot_len);
+#endif /* TCP_CHECKSUM_ON_COPY */
+#endif /* CHECKSUM_GEN_TCP */
+  TCP_STATS_INC(tcp.xmit);
+
+#if LWIP_NETIF_HWADDRHINT
+  ip_output_hinted(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
+      IP_PROTO_TCP, &(pcb->addr_hint));
+#else /* LWIP_NETIF_HWADDRHINT*/
+  ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
+      IP_PROTO_TCP);
+#endif /* LWIP_NETIF_HWADDRHINT*/
+}
+
+/**
+ * Send a TCP RESET packet (empty segment with RST flag set) either to
+ * abort a connection or to show that there is no matching local connection
+ * for a received segment.
+ *
+ * Called by tcp_abort() (to abort a local connection), tcp_input() (if no
+ * matching local pcb was found), tcp_listen_input() (if incoming segment
+ * has ACK flag set) and tcp_process() (received segment in the wrong state)
+ *
+ * Since a RST segment is in most cases not sent for an active connection,
+ * tcp_rst() has a number of arguments that are taken from a tcp_pcb for
+ * most other segment output functions.
+ *
+ * @param seqno the sequence number to use for the outgoing segment
+ * @param ackno the acknowledge number to use for the outgoing segment
+ * @param local_ip the local IP address to send the segment from
+ * @param remote_ip the remote IP address to send the segment to
+ * @param local_port the local TCP port to send the segment from
+ * @param remote_port the remote TCP port to send the segment to
+ */
+void
+tcp_rst(u32_t seqno, u32_t ackno,
+  ip_addr_t *local_ip, ip_addr_t *remote_ip,
+  u16_t local_port, u16_t remote_port)
+{
+  struct pbuf *p;
+  struct tcp_hdr *tcphdr;
+  p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
+  if (p == NULL) {
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
+      return;
+  }
+  LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
+              (p->len >= sizeof(struct tcp_hdr)));
+
+  tcphdr = (struct tcp_hdr *)p->payload;
+  tcphdr->src = htons(local_port);
+  tcphdr->dest = htons(remote_port);
+  tcphdr->seqno = htonl(seqno);
+  tcphdr->ackno = htonl(ackno);
+  TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK);
+  tcphdr->wnd = PP_HTONS(TCP_WND);
+  tcphdr->chksum = 0;
+  tcphdr->urgp = 0;
+
+#if CHECKSUM_GEN_TCP
+  tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
+              IP_PROTO_TCP, p->tot_len);
+#endif
+  TCP_STATS_INC(tcp.xmit);
+  snmp_inc_tcpoutrsts();
+   /* Send output with hardcoded TTL since we have no access to the pcb */
+  ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
+  pbuf_free(p);
+  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
+}
+
+/**
+ * Requeue all unacked segments for retransmission
+ *
+ * Called by tcp_slowtmr() for slow retransmission.
+ *
+ * @param pcb the tcp_pcb for which to re-enqueue all unacked segments
+ */
+void
+tcp_rexmit_rto(struct tcp_pcb *pcb)
+{
+  struct tcp_seg *seg;
+
+  if (pcb->unacked == NULL) {
+    return;
+  }
+
+  /* Move all unacked segments to the head of the unsent queue */
+  for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
+  /* concatenate unsent queue after unacked queue */
+  seg->next = pcb->unsent;
+  /* unsent queue is the concatenated queue (of unacked, unsent) */
+  pcb->unsent = pcb->unacked;
+  /* unacked queue is now empty */
+  pcb->unacked = NULL;
+  /* last unsent hasn't changed, no need to reset unsent_oversize */
+
+  /* increment number of retransmissions */
+  ++pcb->nrtx;
+
+  /* Don't take any RTT measurements after retransmitting. */
+  pcb->rttest = 0;
+
+  /* Do the actual retransmission */
+  tcp_output(pcb);
+}
+
+/**
+ * Requeue the first unacked segment for retransmission
+ *
+ * Called by tcp_receive() for fast retramsmit.
+ *
+ * @param pcb the tcp_pcb for which to retransmit the first unacked segment
+ */
+void
+tcp_rexmit(struct tcp_pcb *pcb)
+{
+  struct tcp_seg *seg;
+  struct tcp_seg **cur_seg;
+
+  if (pcb->unacked == NULL) {
+    return;
+  }
+
+  /* Move the first unacked segment to the unsent queue */
+  /* Keep the unsent queue sorted. */
+  seg = pcb->unacked;
+  pcb->unacked = seg->next;
+
+  cur_seg = &(pcb->unsent);
+  while (*cur_seg &&
+    TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) {
+      cur_seg = &((*cur_seg)->next );
+  }
+  seg->next = *cur_seg;
+  *cur_seg = seg;
+#if TCP_OVERSIZE
+  if (seg->next == NULL) {
+    /* the retransmitted segment is last in unsent, so reset unsent_oversize */
+    pcb->unsent_oversize = 0;
+  }
+#endif /* TCP_OVERSIZE */
+
+  ++pcb->nrtx;
+
+  /* Don't take any rtt measurements after retransmitting. */
+  pcb->rttest = 0;
+
+  /* Do the actual retransmission. */
+  snmp_inc_tcpretranssegs();
+  /* No need to call tcp_output: we are always called from tcp_input()
+     and thus tcp_output directly returns. */
+}
+
+
+/**
+ * Handle retransmission after three dupacks received
+ *
+ * @param pcb the tcp_pcb for which to retransmit the first unacked segment
+ */
+void 
+tcp_rexmit_fast(struct tcp_pcb *pcb)
+{
+  if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) {
+    /* This is fast retransmit. Retransmit the first unacked segment. */
+    LWIP_DEBUGF(TCP_FR_DEBUG, 
+                ("tcp_receive: dupacks %"U16_F" (%"U32_F
+                 "), fast retransmit %"U32_F"\n",
+                 (u16_t)pcb->dupacks, pcb->lastack,
+                 ntohl(pcb->unacked->tcphdr->seqno)));
+    tcp_rexmit(pcb);
+
+    /* Set ssthresh to half of the minimum of the current
+     * cwnd and the advertised window */
+    if (pcb->cwnd > pcb->snd_wnd) {
+      pcb->ssthresh = pcb->snd_wnd / 2;
+    } else {
+      pcb->ssthresh = pcb->cwnd / 2;
+    }
+    
+    /* The minimum value for ssthresh should be 2 MSS */
+    if (pcb->ssthresh < 2*pcb->mss) {
+      LWIP_DEBUGF(TCP_FR_DEBUG, 
+                  ("tcp_receive: The minimum value for ssthresh %"U16_F
+                   " should be min 2 mss %"U16_F"...\n",
+                   pcb->ssthresh, 2*pcb->mss));
+      pcb->ssthresh = 2*pcb->mss;
+    }
+    
+    pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
+    pcb->flags |= TF_INFR;
+  } 
+}
+
+
+/**
+ * Send keepalive packets to keep a connection active although
+ * no data is sent over it.
+ *
+ * Called by tcp_slowtmr()
+ *
+ * @param pcb the tcp_pcb for which to send a keepalive packet
+ */
+void
+tcp_keepalive(struct tcp_pcb *pcb)
+{
+  struct pbuf *p;
+  struct tcp_hdr *tcphdr;
+
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+                          ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
+                          ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));
+
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F"   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", 
+                          tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
+   
+  p = tcp_output_alloc_header(pcb, 0, 0, htonl(pcb->snd_nxt - 1));
+  if(p == NULL) {
+    LWIP_DEBUGF(TCP_DEBUG, 
+                ("tcp_keepalive: could not allocate memory for pbuf\n"));
+    return;
+  }
+  tcphdr = (struct tcp_hdr *)p->payload;
+
+#if CHECKSUM_GEN_TCP
+  tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
+                                      IP_PROTO_TCP, p->tot_len);
+#endif
+  TCP_STATS_INC(tcp.xmit);
+
+  /* Send output to IP */
+#if LWIP_NETIF_HWADDRHINT
+  ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP,
+    &(pcb->addr_hint));
+#else /* LWIP_NETIF_HWADDRHINT*/
+  ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
+#endif /* LWIP_NETIF_HWADDRHINT*/
+
+  pbuf_free(p);
+
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n",
+                          pcb->snd_nxt - 1, pcb->rcv_nxt));
+}
+
+
+/**
+ * Send persist timer zero-window probes to keep a connection active
+ * when a window update is lost.
+ *
+ * Called by tcp_slowtmr()
+ *
+ * @param pcb the tcp_pcb for which to send a zero-window probe packet
+ */
+void
+tcp_zero_window_probe(struct tcp_pcb *pcb)
+{
+  struct pbuf *p;
+  struct tcp_hdr *tcphdr;
+  struct tcp_seg *seg;
+  u16_t len;
+  u8_t is_fin;
+
+  LWIP_DEBUGF(TCP_DEBUG, 
+              ("tcp_zero_window_probe: sending ZERO WINDOW probe to %"
+               U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+               ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
+               ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));
+
+  LWIP_DEBUGF(TCP_DEBUG, 
+              ("tcp_zero_window_probe: tcp_ticks %"U32_F
+               "   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", 
+               tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
+
+  seg = pcb->unacked;
+
+  if(seg == NULL) {
+    seg = pcb->unsent;
+  }
+  if(seg == NULL) {
+    return;
+  }
+
+  is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0);
+  /* we want to send one seqno: either FIN or data (no options) */
+  len = is_fin ? 0 : 1;
+
+  p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno);
+  if(p == NULL) {
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));
+    return;
+  }
+  tcphdr = (struct tcp_hdr *)p->payload;
+
+  if (is_fin) {
+    /* FIN segment, no data */
+    TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN);
+  } else {
+    /* Data segment, copy in one byte from the head of the unacked queue */
+    char *d = ((char *)p->payload + TCP_HLEN);
+    /* Depending on whether the segment has already been sent (unacked) or not
+       (unsent), seg->p->payload points to the IP header or TCP header.
+       Ensure we copy the first TCP data byte: */
+    pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len);
+  }
+
+#if CHECKSUM_GEN_TCP
+  tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
+                                      IP_PROTO_TCP, p->tot_len);
+#endif
+  TCP_STATS_INC(tcp.xmit);
+
+  /* Send output to IP */
+#if LWIP_NETIF_HWADDRHINT
+  ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP,
+    &(pcb->addr_hint));
+#else /* LWIP_NETIF_HWADDRHINT*/
+  ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
+#endif /* LWIP_NETIF_HWADDRHINT*/
+
+  pbuf_free(p);
+
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F
+                          " ackno %"U32_F".\n",
+                          pcb->snd_nxt - 1, pcb->rcv_nxt));
+}
+#endif /* LWIP_TCP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/timers.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/timers.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/timers.c	(revision 164)
@@ -0,0 +1,487 @@
+/**
+ * @file
+ * Stack-internal timers implementation.
+ * This file includes timer callbacks for stack-internal timers as well as
+ * functions to set up or stop timers and check for expired timers.
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *         Simon Goldschmidt
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/timers.h"
+#include "lwip/tcp_impl.h"
+
+#if LWIP_TIMERS
+
+#include "lwip/def.h"
+#include "lwip/memp.h"
+#include "lwip/tcpip.h"
+
+#include "lwip/ip_frag.h"
+#include "netif/etharp.h"
+#include "lwip/dhcp.h"
+#include "lwip/autoip.h"
+#include "lwip/igmp.h"
+#include "lwip/dns.h"
+#include "lwip/sys.h"
+#include "lwip/pbuf.h"
+
+
+/** The one and only timeout list */
+static struct sys_timeo *next_timeout;
+#if NO_SYS
+static u32_t timeouts_last_time;
+#endif /* NO_SYS */
+
+#if LWIP_TCP
+/** global variable that shows if the tcp timer is currently scheduled or not */
+static int tcpip_tcp_timer_active;
+
+/**
+ * Timer callback function that calls tcp_tmr() and reschedules itself.
+ *
+ * @param arg unused argument
+ */
+static void
+tcpip_tcp_timer(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+
+  /* call TCP timer handler */
+  tcp_tmr();
+  /* timer still needed? */
+  if (tcp_active_pcbs || tcp_tw_pcbs) {
+    /* restart timer */
+    sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
+  } else {
+    /* disable timer */
+    tcpip_tcp_timer_active = 0;
+  }
+}
+
+/**
+ * Called from TCP_REG when registering a new PCB:
+ * the reason is to have the TCP timer only running when
+ * there are active (or time-wait) PCBs.
+ */
+void
+tcp_timer_needed(void)
+{
+  /* timer is off but needed again? */
+  if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) {
+    /* enable and start timer */
+    tcpip_tcp_timer_active = 1;
+    sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
+  }
+}
+#endif /* LWIP_TCP */
+
+#if IP_REASSEMBLY
+/**
+ * Timer callback function that calls ip_reass_tmr() and reschedules itself.
+ *
+ * @param arg unused argument
+ */
+static void
+ip_reass_timer(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+  LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: ip_reass_tmr()\n"));
+  ip_reass_tmr();
+  sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL);
+}
+#endif /* IP_REASSEMBLY */
+
+#if LWIP_ARP
+/**
+ * Timer callback function that calls etharp_tmr() and reschedules itself.
+ *
+ * @param arg unused argument
+ */
+static void
+arp_timer(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+  LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: etharp_tmr()\n"));
+  etharp_tmr();
+  sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
+}
+#endif /* LWIP_ARP */
+
+#if LWIP_DHCP
+/**
+ * Timer callback function that calls dhcp_coarse_tmr() and reschedules itself.
+ *
+ * @param arg unused argument
+ */
+static void
+dhcp_timer_coarse(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+  LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_coarse_tmr()\n"));
+  dhcp_coarse_tmr();
+  sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL);
+}
+
+/**
+ * Timer callback function that calls dhcp_fine_tmr() and reschedules itself.
+ *
+ * @param arg unused argument
+ */
+static void
+dhcp_timer_fine(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+  LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_fine_tmr()\n"));
+  dhcp_fine_tmr();
+  sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL);
+}
+#endif /* LWIP_DHCP */
+
+#if LWIP_AUTOIP
+/**
+ * Timer callback function that calls autoip_tmr() and reschedules itself.
+ *
+ * @param arg unused argument
+ */
+static void
+autoip_timer(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+  LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: autoip_tmr()\n"));
+  autoip_tmr();
+  sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL);
+}
+#endif /* LWIP_AUTOIP */
+
+#if LWIP_IGMP
+/**
+ * Timer callback function that calls igmp_tmr() and reschedules itself.
+ *
+ * @param arg unused argument
+ */
+static void
+igmp_timer(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+  LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: igmp_tmr()\n"));
+  igmp_tmr();
+  sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL);
+}
+#endif /* LWIP_IGMP */
+
+#if LWIP_DNS
+/**
+ * Timer callback function that calls dns_tmr() and reschedules itself.
+ *
+ * @param arg unused argument
+ */
+static void
+dns_timer(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+  LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dns_tmr()\n"));
+  dns_tmr();
+  sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL);
+}
+#endif /* LWIP_DNS */
+
+/** Initialize this module */
+void sys_timeouts_init(void)
+{
+#if IP_REASSEMBLY
+  sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL);
+#endif /* IP_REASSEMBLY */
+#if LWIP_ARP
+  sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
+#endif /* LWIP_ARP */
+#if LWIP_DHCP
+  sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL);
+  sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL);
+#endif /* LWIP_DHCP */
+#if LWIP_AUTOIP
+  sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL);
+#endif /* LWIP_AUTOIP */
+#if LWIP_IGMP
+  sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL);
+#endif /* LWIP_IGMP */
+#if LWIP_DNS
+  sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL);
+#endif /* LWIP_DNS */
+
+#if NO_SYS
+  /* Initialise timestamp for sys_check_timeouts */
+  timeouts_last_time = sys_now();
+#endif
+}
+
+/**
+ * Create a one-shot timer (aka timeout). Timeouts are processed in the
+ * following cases:
+ * - while waiting for a message using sys_timeouts_mbox_fetch()
+ * - by calling sys_check_timeouts() (NO_SYS==1 only)
+ *
+ * @param msecs time in milliseconds after that the timer should expire
+ * @param handler callback function to call when msecs have elapsed
+ * @param arg argument to pass to the callback function
+ */
+#if LWIP_DEBUG_TIMERNAMES
+void
+sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name)
+#else /* LWIP_DEBUG_TIMERNAMES */
+void
+sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)
+#endif /* LWIP_DEBUG_TIMERNAMES */
+{
+  struct sys_timeo *timeout, *t;
+
+  timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT);
+  if (timeout == NULL) {
+    LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL);
+    return;
+  }
+  timeout->next = NULL;
+  timeout->h = handler;
+  timeout->arg = arg;
+  timeout->time = msecs;
+#if LWIP_DEBUG_TIMERNAMES
+  timeout->handler_name = handler_name;
+  LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n",
+    (void *)timeout, msecs, handler_name, (void *)arg));
+#endif /* LWIP_DEBUG_TIMERNAMES */
+
+  if (next_timeout == NULL) {
+    next_timeout = timeout;
+    return;
+  }
+
+  if (next_timeout->time > msecs) {
+    next_timeout->time -= msecs;
+    timeout->next = next_timeout;
+    next_timeout = timeout;
+  } else {
+    for(t = next_timeout; t != NULL; t = t->next) {
+      timeout->time -= t->time;
+      if (t->next == NULL || t->next->time > timeout->time) {
+        if (t->next != NULL) {
+          t->next->time -= timeout->time;
+        }
+        timeout->next = t->next;
+        t->next = timeout;
+        break;
+      }
+    }
+  }
+}
+
+/**
+ * Go through timeout list (for this task only) and remove the first matching
+ * entry, even though the timeout has not triggered yet.
+ *
+ * @note This function only works as expected if there is only one timeout
+ * calling 'handler' in the list of timeouts.
+ *
+ * @param handler callback function that would be called by the timeout
+ * @param arg callback argument that would be passed to handler
+*/
+void
+sys_untimeout(sys_timeout_handler handler, void *arg)
+{
+  struct sys_timeo *prev_t, *t;
+
+  if (next_timeout == NULL) {
+    return;
+  }
+
+  for (t = next_timeout, prev_t = NULL; t != NULL; prev_t = t, t = t->next) {
+    if ((t->h == handler) && (t->arg == arg)) {
+      /* We have a match */
+      /* Unlink from previous in list */
+      if (prev_t == NULL) {
+        next_timeout = t->next;
+      } else {
+        prev_t->next = t->next;
+      }
+      /* If not the last one, add time of this one back to next */
+      if (t->next != NULL) {
+        t->next->time += t->time;
+      }
+      memp_free(MEMP_SYS_TIMEOUT, t);
+      return;
+    }
+  }
+  return;
+}
+
+#if NO_SYS
+
+/** Handle timeouts for NO_SYS==1 (i.e. without using
+ * tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout
+ * handler functions when timeouts expire.
+ *
+ * Must be called periodically from your main loop.
+ */
+void
+sys_check_timeouts(void)
+{
+  if (next_timeout) {
+    struct sys_timeo *tmptimeout;
+    u32_t diff;
+    sys_timeout_handler handler;
+    void *arg;
+    u8_t had_one;
+    u32_t now;
+
+    now = sys_now();
+    /* this cares for wraparounds */
+    diff = now - timeouts_last_time;
+    do
+    {
+#if PBUF_POOL_FREE_OOSEQ
+      PBUF_CHECK_FREE_OOSEQ();
+#endif /* PBUF_POOL_FREE_OOSEQ */
+      had_one = 0;
+      tmptimeout = next_timeout;
+      if (tmptimeout && (tmptimeout->time <= diff)) {
+        /* timeout has expired */
+        had_one = 1;
+        timeouts_last_time = now;
+        diff -= tmptimeout->time;
+        next_timeout = tmptimeout->next;
+        handler = tmptimeout->h;
+        arg = tmptimeout->arg;
+#if LWIP_DEBUG_TIMERNAMES
+        if (handler != NULL) {
+          LWIP_DEBUGF(TIMERS_DEBUG, ("sct calling h=%s arg=%p\n",
+            tmptimeout->handler_name, arg));
+        }
+#endif /* LWIP_DEBUG_TIMERNAMES */
+        memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
+        if (handler != NULL) {
+          handler(arg);
+        }
+      }
+    /* repeat until all expired timers have been called */
+    }while(had_one);
+  }
+}
+
+/** Set back the timestamp of the last call to sys_check_timeouts()
+ * This is necessary if sys_check_timeouts() hasn't been called for a long
+ * time (e.g. while saving energy) to prevent all timer functions of that
+ * period being called.
+ */
+void
+sys_restart_timeouts(void)
+{
+  timeouts_last_time = sys_now();
+}
+
+#else /* NO_SYS */
+
+/**
+ * Wait (forever) for a message to arrive in an mbox.
+ * While waiting, timeouts are processed.
+ *
+ * @param mbox the mbox to fetch the message from
+ * @param msg the place to store the message
+ */
+void
+sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
+{
+  u32_t time_needed;
+  struct sys_timeo *tmptimeout;
+  sys_timeout_handler handler;
+  void *arg;
+
+ again:
+  if (!next_timeout) {
+    time_needed = sys_arch_mbox_fetch(mbox, msg, 0);
+  } else {
+    if (next_timeout->time > 0) {
+      time_needed = sys_arch_mbox_fetch(mbox, msg, next_timeout->time);
+    } else {
+      time_needed = SYS_ARCH_TIMEOUT;
+    }
+
+    if (time_needed == SYS_ARCH_TIMEOUT) {
+      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
+         could be fetched. We should now call the timeout handler and
+         deallocate the memory allocated for the timeout. */
+      tmptimeout = next_timeout;
+      next_timeout = tmptimeout->next;
+      handler = tmptimeout->h;
+      arg = tmptimeout->arg;
+#if LWIP_DEBUG_TIMERNAMES
+      if (handler != NULL) {
+        LWIP_DEBUGF(TIMERS_DEBUG, ("stmf calling h=%s arg=%p\n",
+          tmptimeout->handler_name, arg));
+      }
+#endif /* LWIP_DEBUG_TIMERNAMES */
+      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
+      if (handler != NULL) {
+        /* For LWIP_TCPIP_CORE_LOCKING, lock the core before calling the
+           timeout handler function. */
+        LOCK_TCPIP_CORE();
+        handler(arg);
+        UNLOCK_TCPIP_CORE();
+      }
+      LWIP_TCPIP_THREAD_ALIVE();
+
+      /* We try again to fetch a message from the mbox. */
+      goto again;
+    } else {
+      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
+         occured. The time variable is set to the number of
+         milliseconds we waited for the message. */
+      if (time_needed < next_timeout->time) {
+        next_timeout->time -= time_needed;
+      } else {
+        next_timeout->time = 0;
+      }
+    }
+  }
+}
+
+#endif /* NO_SYS */
+
+#else /* LWIP_TIMERS */
+/* Satisfy the TCP code which calls this function */
+void
+tcp_timer_needed(void)
+{
+}
+#endif /* LWIP_TIMERS */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/core/udp.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/core/udp.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/core/udp.c	(revision 164)
@@ -0,0 +1,1013 @@
+/**
+ * @file
+ * User Datagram Protocol module
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+
+/* udp.c
+ *
+ * The code for the User Datagram Protocol UDP & UDPLite (RFC 3828).
+ *
+ */
+
+/* @todo Check the use of '(struct udp_pcb).chksum_len_rx'!
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/udp.h"
+#include "lwip/def.h"
+#include "lwip/memp.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/icmp.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#include "arch/perf.h"
+#include "lwip/dhcp.h"
+
+#include <string.h>
+
+#ifndef UDP_LOCAL_PORT_RANGE_START
+/* From http://www.iana.org/assignments/port-numbers:
+   "The Dynamic and/or Private Ports are those from 49152 through 65535" */
+#define UDP_LOCAL_PORT_RANGE_START  0xc000
+#define UDP_LOCAL_PORT_RANGE_END    0xffff
+#define UDP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~UDP_LOCAL_PORT_RANGE_START) + UDP_LOCAL_PORT_RANGE_START)
+#endif
+
+/* last local UDP port */
+static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START;
+
+/* The list of UDP PCBs */
+/* exported in udp.h (was static) */
+struct udp_pcb *udp_pcbs;
+
+/**
+ * Initialize this module.
+ */
+void
+udp_init(void)
+{
+#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND)
+  udp_port = UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND());
+#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */
+}
+
+/**
+ * Allocate a new local UDP port.
+ *
+ * @return a new (free) local UDP port number
+ */
+static u16_t
+udp_new_port(void)
+{
+  u16_t n = 0;
+  struct udp_pcb *pcb;
+  
+again:
+  if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) {
+    udp_port = UDP_LOCAL_PORT_RANGE_START;
+  }
+  /* Check all PCBs. */
+  for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
+    if (pcb->local_port == udp_port) {
+      if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) {
+        return 0;
+      }
+      goto again;
+    }
+  }
+  return udp_port;
+#if 0
+  struct udp_pcb *ipcb = udp_pcbs;
+  while ((ipcb != NULL) && (udp_port != UDP_LOCAL_PORT_RANGE_END)) {
+    if (ipcb->local_port == udp_port) {
+      /* port is already used by another udp_pcb */
+      udp_port++;
+      /* restart scanning all udp pcbs */
+      ipcb = udp_pcbs;
+    } else {
+      /* go on with next udp pcb */
+      ipcb = ipcb->next;
+    }
+  }
+  if (ipcb != NULL) {
+    return 0;
+  }
+  return udp_port;
+#endif
+}
+
+/**
+ * Process an incoming UDP datagram.
+ *
+ * Given an incoming UDP datagram (as a chain of pbufs) this function
+ * finds a corresponding UDP PCB and hands over the pbuf to the pcbs
+ * recv function. If no pcb is found or the datagram is incorrect, the
+ * pbuf is freed.
+ *
+ * @param p pbuf to be demultiplexed to a UDP PCB.
+ * @param inp network interface on which the datagram was received.
+ *
+ */
+void
+udp_input(struct pbuf *p, struct netif *inp)
+{
+  struct udp_hdr *udphdr;
+  struct udp_pcb *pcb, *prev;
+  struct udp_pcb *uncon_pcb;
+  struct ip_hdr *iphdr;
+  u16_t src, dest;
+  u8_t local_match;
+  u8_t broadcast;
+
+  PERF_START;
+
+  UDP_STATS_INC(udp.recv);
+
+  iphdr = (struct ip_hdr *)p->payload;
+
+  /* Check minimum length (IP header + UDP header)
+   * and move payload pointer to UDP header */
+  if (p->tot_len < (IPH_HL(iphdr) * 4 + UDP_HLEN) || pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4))) {
+    /* drop short packets */
+    LWIP_DEBUGF(UDP_DEBUG,
+                ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len));
+    UDP_STATS_INC(udp.lenerr);
+    UDP_STATS_INC(udp.drop);
+    snmp_inc_udpinerrors();
+    pbuf_free(p);
+    goto end;
+  }
+
+  udphdr = (struct udp_hdr *)p->payload;
+
+  /* is broadcast packet ? */
+  broadcast = ip_addr_isbroadcast(&current_iphdr_dest, inp);
+
+  LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len));
+
+  /* convert src and dest ports to host byte order */
+  src = ntohs(udphdr->src);
+  dest = ntohs(udphdr->dest);
+
+  udp_debug_print(udphdr);
+
+  /* print the UDP source and destination */
+  LWIP_DEBUGF(UDP_DEBUG,
+              ("udp (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") <-- "
+               "(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",
+               ip4_addr1_16(&iphdr->dest), ip4_addr2_16(&iphdr->dest),
+               ip4_addr3_16(&iphdr->dest), ip4_addr4_16(&iphdr->dest), ntohs(udphdr->dest),
+               ip4_addr1_16(&iphdr->src), ip4_addr2_16(&iphdr->src),
+               ip4_addr3_16(&iphdr->src), ip4_addr4_16(&iphdr->src), ntohs(udphdr->src)));
+
+#if LWIP_DHCP
+  pcb = NULL;
+  /* when LWIP_DHCP is active, packets to DHCP_CLIENT_PORT may only be processed by
+     the dhcp module, no other UDP pcb may use the local UDP port DHCP_CLIENT_PORT */
+  if (dest == DHCP_CLIENT_PORT) {
+    /* all packets for DHCP_CLIENT_PORT not coming from DHCP_SERVER_PORT are dropped! */
+    if (src == DHCP_SERVER_PORT) {
+      if ((inp->dhcp != NULL) && (inp->dhcp->pcb != NULL)) {
+        /* accept the packe if 
+           (- broadcast or directed to us) -> DHCP is link-layer-addressed, local ip is always ANY!
+           - inp->dhcp->pcb->remote == ANY or iphdr->src */
+        if ((ip_addr_isany(&inp->dhcp->pcb->remote_ip) ||
+           ip_addr_cmp(&(inp->dhcp->pcb->remote_ip), &current_iphdr_src))) {
+          pcb = inp->dhcp->pcb;
+        }
+      }
+    }
+  } else
+#endif /* LWIP_DHCP */
+  {
+    prev = NULL;
+    local_match = 0;
+    uncon_pcb = NULL;
+    /* Iterate through the UDP pcb list for a matching pcb.
+     * 'Perfect match' pcbs (connected to the remote port & ip address) are
+     * preferred. If no perfect match is found, the first unconnected pcb that
+     * matches the local port and ip address gets the datagram. */
+    for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
+      local_match = 0;
+      /* print the PCB local and remote address */
+      LWIP_DEBUGF(UDP_DEBUG,
+                  ("pcb (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") --- "
+                   "(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",
+                   ip4_addr1_16(&pcb->local_ip), ip4_addr2_16(&pcb->local_ip),
+                   ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip), pcb->local_port,
+                   ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
+                   ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip), pcb->remote_port));
+
+      /* compare PCB local addr+port to UDP destination addr+port */
+      if (pcb->local_port == dest) {
+        if (
+           (!broadcast && ip_addr_isany(&pcb->local_ip)) ||
+           ip_addr_cmp(&(pcb->local_ip), &current_iphdr_dest) ||
+#if LWIP_IGMP
+           ip_addr_ismulticast(&current_iphdr_dest) ||
+#endif /* LWIP_IGMP */
+#if IP_SOF_BROADCAST_RECV
+            (broadcast && ip_get_option(pcb, SOF_BROADCAST) &&
+             (ip_addr_isany(&pcb->local_ip) ||
+              ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), &inp->netmask)))) {
+#else /* IP_SOF_BROADCAST_RECV */
+            (broadcast &&
+             (ip_addr_isany(&pcb->local_ip) ||
+              ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), &inp->netmask)))) {
+#endif /* IP_SOF_BROADCAST_RECV */ 
+          local_match = 1;
+          if ((uncon_pcb == NULL) && 
+              ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) {
+            /* the first unconnected matching PCB */
+            uncon_pcb = pcb;
+          }
+        }
+      }
+      /* compare PCB remote addr+port to UDP source addr+port */
+      if ((local_match != 0) &&
+          (pcb->remote_port == src) &&
+          (ip_addr_isany(&pcb->remote_ip) ||
+           ip_addr_cmp(&(pcb->remote_ip), &current_iphdr_src))) {
+        /* the first fully matching PCB */
+        if (prev != NULL) {
+          /* move the pcb to the front of udp_pcbs so that is
+             found faster next time */
+          prev->next = pcb->next;
+          pcb->next = udp_pcbs;
+          udp_pcbs = pcb;
+        } else {
+          UDP_STATS_INC(udp.cachehit);
+        }
+        break;
+      }
+      prev = pcb;
+    }
+    /* no fully matching pcb found? then look for an unconnected pcb */
+    if (pcb == NULL) {
+      pcb = uncon_pcb;
+    }
+  }
+
+  /* Check checksum if this is a match or if it was directed at us. */
+  if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, &current_iphdr_dest)) {
+    LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n"));
+#if LWIP_UDPLITE
+    if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
+      /* Do the UDP Lite checksum */
+#if CHECKSUM_CHECK_UDP
+      u16_t chklen = ntohs(udphdr->len);
+      if (chklen < sizeof(struct udp_hdr)) {
+        if (chklen == 0) {
+          /* For UDP-Lite, checksum length of 0 means checksum
+             over the complete packet (See RFC 3828 chap. 3.1) */
+          chklen = p->tot_len;
+        } else {
+          /* At least the UDP-Lite header must be covered by the
+             checksum! (Again, see RFC 3828 chap. 3.1) */
+          UDP_STATS_INC(udp.chkerr);
+          UDP_STATS_INC(udp.drop);
+          snmp_inc_udpinerrors();
+          pbuf_free(p);
+          goto end;
+        }
+      }
+      if (inet_chksum_pseudo_partial(p, &current_iphdr_src, &current_iphdr_dest,
+                             IP_PROTO_UDPLITE, p->tot_len, chklen) != 0) {
+       LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                   ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
+        UDP_STATS_INC(udp.chkerr);
+        UDP_STATS_INC(udp.drop);
+        snmp_inc_udpinerrors();
+        pbuf_free(p);
+        goto end;
+      }
+#endif /* CHECKSUM_CHECK_UDP */
+    } else
+#endif /* LWIP_UDPLITE */
+    {
+#if CHECKSUM_CHECK_UDP
+      if (udphdr->chksum != 0) {
+        if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(),
+                               IP_PROTO_UDP, p->tot_len) != 0) {
+          LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+                      ("udp_input: UDP datagram discarded due to failing checksum\n"));
+          UDP_STATS_INC(udp.chkerr);
+          UDP_STATS_INC(udp.drop);
+          snmp_inc_udpinerrors();
+          pbuf_free(p);
+          goto end;
+        }
+      }
+#endif /* CHECKSUM_CHECK_UDP */
+    }
+    if(pbuf_header(p, -UDP_HLEN)) {
+      /* Can we cope with this failing? Just assert for now */
+      LWIP_ASSERT("pbuf_header failed\n", 0);
+      UDP_STATS_INC(udp.drop);
+      snmp_inc_udpinerrors();
+      pbuf_free(p);
+      goto end;
+    }
+    if (pcb != NULL) {
+      snmp_inc_udpindatagrams();
+#if SO_REUSE && SO_REUSE_RXTOALL
+      if ((broadcast || ip_addr_ismulticast(&current_iphdr_dest)) &&
+          ip_get_option(pcb, SOF_REUSEADDR)) {
+        /* pass broadcast- or multicast packets to all multicast pcbs
+           if SOF_REUSEADDR is set on the first match */
+        struct udp_pcb *mpcb;
+        u8_t p_header_changed = 0;
+        for (mpcb = udp_pcbs; mpcb != NULL; mpcb = mpcb->next) {
+          if (mpcb != pcb) {
+            /* compare PCB local addr+port to UDP destination addr+port */
+            if ((mpcb->local_port == dest) &&
+                ((!broadcast && ip_addr_isany(&mpcb->local_ip)) ||
+                 ip_addr_cmp(&(mpcb->local_ip), &current_iphdr_dest) ||
+#if LWIP_IGMP
+                 ip_addr_ismulticast(&current_iphdr_dest) ||
+#endif /* LWIP_IGMP */
+#if IP_SOF_BROADCAST_RECV
+                 (broadcast && ip_get_option(mpcb, SOF_BROADCAST)))) {
+#else  /* IP_SOF_BROADCAST_RECV */
+                 (broadcast))) {
+#endif /* IP_SOF_BROADCAST_RECV */
+              /* pass a copy of the packet to all local matches */
+              if (mpcb->recv != NULL) {
+                struct pbuf *q;
+                /* for that, move payload to IP header again */
+                if (p_header_changed == 0) {
+                  pbuf_header(p, (s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN));
+                  p_header_changed = 1;
+                }
+                q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
+                if (q != NULL) {
+                  err_t err = pbuf_copy(q, p);
+                  if (err == ERR_OK) {
+                    /* move payload to UDP data */
+                    pbuf_header(q, -(s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN));
+                    mpcb->recv(mpcb->recv_arg, mpcb, q, ip_current_src_addr(), src);
+                  }
+                }
+              }
+            }
+          }
+        }
+        if (p_header_changed) {
+          /* and move payload to UDP data again */
+          pbuf_header(p, -(s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN));
+        }
+      }
+#endif /* SO_REUSE && SO_REUSE_RXTOALL */
+      /* callback */
+      if (pcb->recv != NULL) {
+        /* now the recv function is responsible for freeing p */
+        pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr(), src);
+      } else {
+        /* no recv function registered? then we have to free the pbuf! */
+        pbuf_free(p);
+        goto end;
+      }
+    } else {
+      LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n"));
+
+#if LWIP_ICMP
+      /* No match was found, send ICMP destination port unreachable unless
+         destination address was broadcast/multicast. */
+      if (!broadcast &&
+          !ip_addr_ismulticast(&current_iphdr_dest)) {
+        /* move payload pointer back to ip header */
+        pbuf_header(p, (IPH_HL(iphdr) * 4) + UDP_HLEN);
+        LWIP_ASSERT("p->payload == iphdr", (p->payload == iphdr));
+        icmp_dest_unreach(p, ICMP_DUR_PORT);
+      }
+#endif /* LWIP_ICMP */
+      UDP_STATS_INC(udp.proterr);
+      UDP_STATS_INC(udp.drop);
+      snmp_inc_udpnoports();
+      pbuf_free(p);
+    }
+  } else {
+    pbuf_free(p);
+  }
+end:
+  PERF_STOP("udp_input");
+}
+
+/**
+ * Send data using UDP.
+ *
+ * @param pcb UDP PCB used to send the data.
+ * @param p chain of pbuf's to be sent.
+ *
+ * The datagram will be sent to the current remote_ip & remote_port
+ * stored in pcb. If the pcb is not bound to a port, it will
+ * automatically be bound to a random port.
+ *
+ * @return lwIP error code.
+ * - ERR_OK. Successful. No error occured.
+ * - ERR_MEM. Out of memory.
+ * - ERR_RTE. Could not find route to destination address.
+ * - More errors could be returned by lower protocol layers.
+ *
+ * @see udp_disconnect() udp_sendto()
+ */
+err_t
+udp_send(struct udp_pcb *pcb, struct pbuf *p)
+{
+  /* send to the packet using remote ip and port stored in the pcb */
+  return udp_sendto(pcb, p, &pcb->remote_ip, pcb->remote_port);
+}
+
+#if LWIP_CHECKSUM_ON_COPY
+/** Same as udp_send() but with checksum
+ */
+err_t
+udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p,
+                u8_t have_chksum, u16_t chksum)
+{
+  /* send to the packet using remote ip and port stored in the pcb */
+  return udp_sendto_chksum(pcb, p, &pcb->remote_ip, pcb->remote_port,
+    have_chksum, chksum);
+}
+#endif /* LWIP_CHECKSUM_ON_COPY */
+
+/**
+ * Send data to a specified address using UDP.
+ *
+ * @param pcb UDP PCB used to send the data.
+ * @param p chain of pbuf's to be sent.
+ * @param dst_ip Destination IP address.
+ * @param dst_port Destination UDP port.
+ *
+ * dst_ip & dst_port are expected to be in the same byte order as in the pcb.
+ *
+ * If the PCB already has a remote address association, it will
+ * be restored after the data is sent.
+ * 
+ * @return lwIP error code (@see udp_send for possible error codes)
+ *
+ * @see udp_disconnect() udp_send()
+ */
+err_t
+udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
+  ip_addr_t *dst_ip, u16_t dst_port)
+{
+#if LWIP_CHECKSUM_ON_COPY
+  return udp_sendto_chksum(pcb, p, dst_ip, dst_port, 0, 0);
+}
+
+/** Same as udp_sendto(), but with checksum */
+err_t
+udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
+                  u16_t dst_port, u8_t have_chksum, u16_t chksum)
+{
+#endif /* LWIP_CHECKSUM_ON_COPY */
+  struct netif *netif;
+
+  LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n"));
+
+  /* find the outgoing network interface for this packet */
+#if LWIP_IGMP
+  netif = ip_route((ip_addr_ismulticast(dst_ip))?(&(pcb->multicast_ip)):(dst_ip));
+#else
+  netif = ip_route(dst_ip);
+#endif /* LWIP_IGMP */
+
+  /* no outgoing network interface could be found? */
+  if (netif == NULL) {
+    LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+      ip4_addr1_16(dst_ip), ip4_addr2_16(dst_ip), ip4_addr3_16(dst_ip), ip4_addr4_16(dst_ip)));
+    UDP_STATS_INC(udp.rterr);
+    return ERR_RTE;
+  }
+#if LWIP_CHECKSUM_ON_COPY
+  return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum);
+#else /* LWIP_CHECKSUM_ON_COPY */
+  return udp_sendto_if(pcb, p, dst_ip, dst_port, netif);
+#endif /* LWIP_CHECKSUM_ON_COPY */
+}
+
+/**
+ * Send data to a specified address using UDP.
+ * The netif used for sending can be specified.
+ *
+ * This function exists mainly for DHCP, to be able to send UDP packets
+ * on a netif that is still down.
+ *
+ * @param pcb UDP PCB used to send the data.
+ * @param p chain of pbuf's to be sent.
+ * @param dst_ip Destination IP address.
+ * @param dst_port Destination UDP port.
+ * @param netif the netif used for sending.
+ *
+ * dst_ip & dst_port are expected to be in the same byte order as in the pcb.
+ *
+ * @return lwIP error code (@see udp_send for possible error codes)
+ *
+ * @see udp_disconnect() udp_send()
+ */
+err_t
+udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p,
+  ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif)
+{
+#if LWIP_CHECKSUM_ON_COPY
+  return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0);
+}
+
+/** Same as udp_sendto_if(), but with checksum */
+err_t
+udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
+                     u16_t dst_port, struct netif *netif, u8_t have_chksum,
+                     u16_t chksum)
+{
+#endif /* LWIP_CHECKSUM_ON_COPY */
+  struct udp_hdr *udphdr;
+  ip_addr_t *src_ip;
+  err_t err;
+  struct pbuf *q; /* q will be sent down the stack */
+
+#if IP_SOF_BROADCAST
+  /* broadcast filter? */
+  if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(dst_ip, netif)) {
+    LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
+      ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
+    return ERR_VAL;
+  }
+#endif /* IP_SOF_BROADCAST */
+
+  /* if the PCB is not yet bound to a port, bind it here */
+  if (pcb->local_port == 0) {
+    LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n"));
+    err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
+    if (err != ERR_OK) {
+      LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n"));
+      return err;
+    }
+  }
+
+  /* not enough space to add an UDP header to first pbuf in given p chain? */
+  if (pbuf_header(p, UDP_HLEN)) {
+    /* allocate header in a separate new pbuf */
+    q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
+    /* new header pbuf could not be allocated? */
+    if (q == NULL) {
+      LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n"));
+      return ERR_MEM;
+    }
+    if (p->tot_len != 0) {
+      /* chain header q in front of given pbuf p (only if p contains data) */
+      pbuf_chain(q, p);
+    }
+    /* first pbuf q points to header pbuf */
+    LWIP_DEBUGF(UDP_DEBUG,
+                ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
+  } else {
+    /* adding space for header within p succeeded */
+    /* first pbuf q equals given pbuf */
+    q = p;
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
+  }
+  LWIP_ASSERT("check that first pbuf can hold struct udp_hdr",
+              (q->len >= sizeof(struct udp_hdr)));
+  /* q now represents the packet to be sent */
+  udphdr = (struct udp_hdr *)q->payload;
+  udphdr->src = htons(pcb->local_port);
+  udphdr->dest = htons(dst_port);
+  /* in UDP, 0 checksum means 'no checksum' */
+  udphdr->chksum = 0x0000; 
+
+  /* Multicast Loop? */
+#if LWIP_IGMP
+  if (ip_addr_ismulticast(dst_ip) && ((pcb->flags & UDP_FLAGS_MULTICAST_LOOP) != 0)) {
+    q->flags |= PBUF_FLAG_MCASTLOOP;
+  }
+#endif /* LWIP_IGMP */
+
+
+  /* PCB local address is IP_ANY_ADDR? */
+  if (ip_addr_isany(&pcb->local_ip)) {
+    /* use outgoing network interface IP address as source address */
+    src_ip = &(netif->ip_addr);
+  } else {
+    /* check if UDP PCB local IP address is correct
+     * this could be an old address if netif->ip_addr has changed */
+    if (!ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {
+      /* local_ip doesn't match, drop the packet */
+      if (q != p) {
+        /* free the header pbuf */
+        pbuf_free(q);
+        q = NULL;
+        /* p is still referenced by the caller, and will live on */
+      }
+      return ERR_VAL;
+    }
+    /* use UDP PCB local IP address as source address */
+    src_ip = &(pcb->local_ip);
+  }
+
+  LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len));
+
+#if LWIP_UDPLITE
+  /* UDP Lite protocol? */
+  if (pcb->flags & UDP_FLAGS_UDPLITE) {
+    u16_t chklen, chklen_hdr;
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len));
+    /* set UDP message length in UDP header */
+    chklen_hdr = chklen = pcb->chksum_len_tx;
+    if ((chklen < sizeof(struct udp_hdr)) || (chklen > q->tot_len)) {
+      if (chklen != 0) {
+        LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen));
+      }
+      /* For UDP-Lite, checksum length of 0 means checksum
+         over the complete packet. (See RFC 3828 chap. 3.1)
+         At least the UDP-Lite header must be covered by the
+         checksum, therefore, if chksum_len has an illegal
+         value, we generate the checksum over the complete
+         packet to be safe. */
+      chklen_hdr = 0;
+      chklen = q->tot_len;
+    }
+    udphdr->len = htons(chklen_hdr);
+    /* calculate checksum */
+#if CHECKSUM_GEN_UDP
+    udphdr->chksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip,
+      IP_PROTO_UDPLITE, q->tot_len,
+#if !LWIP_CHECKSUM_ON_COPY
+      chklen);
+#else /* !LWIP_CHECKSUM_ON_COPY */
+      (have_chksum ? UDP_HLEN : chklen));
+    if (have_chksum) {
+      u32_t acc;
+      acc = udphdr->chksum + (u16_t)~(chksum);
+      udphdr->chksum = FOLD_U32T(acc);
+    }
+#endif /* !LWIP_CHECKSUM_ON_COPY */
+
+    /* chksum zero must become 0xffff, as zero means 'no checksum' */
+    if (udphdr->chksum == 0x0000) {
+      udphdr->chksum = 0xffff;
+    }
+#endif /* CHECKSUM_GEN_UDP */
+    /* output to IP */
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));
+    NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint);
+    err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);
+    NETIF_SET_HWADDRHINT(netif, NULL);
+  } else
+#endif /* LWIP_UDPLITE */
+  {      /* UDP */
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len));
+    udphdr->len = htons(q->tot_len);
+    /* calculate checksum */
+#if CHECKSUM_GEN_UDP
+    if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
+      u16_t udpchksum;
+#if LWIP_CHECKSUM_ON_COPY
+      if (have_chksum) {
+        u32_t acc;
+        udpchksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip, IP_PROTO_UDP,
+          q->tot_len, UDP_HLEN);
+        acc = udpchksum + (u16_t)~(chksum);
+        udpchksum = FOLD_U32T(acc);
+      } else
+#endif /* LWIP_CHECKSUM_ON_COPY */
+      {
+        udpchksum = inet_chksum_pseudo(q, src_ip, dst_ip, IP_PROTO_UDP, q->tot_len);
+      }
+
+      /* chksum zero must become 0xffff, as zero means 'no checksum' */
+      if (udpchksum == 0x0000) {
+        udpchksum = 0xffff;
+      }
+      udphdr->chksum = udpchksum;
+    }
+#endif /* CHECKSUM_GEN_UDP */
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
+    /* output to IP */
+    NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint);
+    err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);
+    NETIF_SET_HWADDRHINT(netif, NULL);
+  }
+  /* TODO: must this be increased even if error occured? */
+  snmp_inc_udpoutdatagrams();
+
+  /* did we chain a separate header pbuf earlier? */
+  if (q != p) {
+    /* free the header pbuf */
+    pbuf_free(q);
+    q = NULL;
+    /* p is still referenced by the caller, and will live on */
+  }
+
+  UDP_STATS_INC(udp.xmit);
+  return err;
+}
+
+/**
+ * Bind an UDP PCB.
+ *
+ * @param pcb UDP PCB to be bound with a local address ipaddr and port.
+ * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to
+ * bind to all local interfaces.
+ * @param port local UDP port to bind with. Use 0 to automatically bind
+ * to a random port between UDP_LOCAL_PORT_RANGE_START and
+ * UDP_LOCAL_PORT_RANGE_END.
+ *
+ * ipaddr & port are expected to be in the same byte order as in the pcb.
+ *
+ * @return lwIP error code.
+ * - ERR_OK. Successful. No error occured.
+ * - ERR_USE. The specified ipaddr and port are already bound to by
+ * another UDP PCB.
+ *
+ * @see udp_disconnect()
+ */
+err_t
+udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
+{
+  struct udp_pcb *ipcb;
+  u8_t rebind;
+
+  LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = "));
+  ip_addr_debug_print(UDP_DEBUG, ipaddr);
+  LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port));
+
+  rebind = 0;
+  /* Check for double bind and rebind of the same pcb */
+  for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
+    /* is this UDP PCB already on active list? */
+    if (pcb == ipcb) {
+      /* pcb may occur at most once in active list */
+      LWIP_ASSERT("rebind == 0", rebind == 0);
+      /* pcb already in list, just rebind */
+      rebind = 1;
+    }
+
+    /* By default, we don't allow to bind to a port that any other udp
+       PCB is alread bound to, unless *all* PCBs with that port have tha
+       REUSEADDR flag set. */
+#if SO_REUSE
+    else if (!ip_get_option(pcb, SOF_REUSEADDR) &&
+             !ip_get_option(ipcb, SOF_REUSEADDR)) {
+#else /* SO_REUSE */
+    /* port matches that of PCB in list and REUSEADDR not set -> reject */
+    else {
+#endif /* SO_REUSE */
+      if ((ipcb->local_port == port) &&
+          /* IP address matches, or one is IP_ADDR_ANY? */
+          (ip_addr_isany(&(ipcb->local_ip)) ||
+           ip_addr_isany(ipaddr) ||
+           ip_addr_cmp(&(ipcb->local_ip), ipaddr))) {
+        /* other PCB already binds to this local IP and port */
+        LWIP_DEBUGF(UDP_DEBUG,
+                    ("udp_bind: local port %"U16_F" already bound by another pcb\n", port));
+        return ERR_USE;
+      }
+    }
+  }
+
+  ip_addr_set(&pcb->local_ip, ipaddr);
+
+  /* no port specified? */
+  if (port == 0) {
+    port = udp_new_port();
+    if (port == 0) {
+      /* no more ports available in local range */
+      LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));
+      return ERR_USE;
+    }
+  }
+  pcb->local_port = port;
+  snmp_insert_udpidx_tree(pcb);
+  /* pcb not active yet? */
+  if (rebind == 0) {
+    /* place the PCB on the active list if not already there */
+    pcb->next = udp_pcbs;
+    udp_pcbs = pcb;
+  }
+  LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+              ("udp_bind: bound to %"U16_F".%"U16_F".%"U16_F".%"U16_F", port %"U16_F"\n",
+               ip4_addr1_16(&pcb->local_ip), ip4_addr2_16(&pcb->local_ip),
+               ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip),
+               pcb->local_port));
+  return ERR_OK;
+}
+/**
+ * Connect an UDP PCB.
+ *
+ * This will associate the UDP PCB with the remote address.
+ *
+ * @param pcb UDP PCB to be connected with remote address ipaddr and port.
+ * @param ipaddr remote IP address to connect with.
+ * @param port remote UDP port to connect with.
+ *
+ * @return lwIP error code
+ *
+ * ipaddr & port are expected to be in the same byte order as in the pcb.
+ *
+ * The udp pcb is bound to a random local port if not already bound.
+ *
+ * @see udp_disconnect()
+ */
+err_t
+udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
+{
+  struct udp_pcb *ipcb;
+
+  if (pcb->local_port == 0) {
+    err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
+    if (err != ERR_OK) {
+      return err;
+    }
+  }
+
+  ip_addr_set(&pcb->remote_ip, ipaddr);
+  pcb->remote_port = port;
+  pcb->flags |= UDP_FLAGS_CONNECTED;
+/** TODO: this functionality belongs in upper layers */
+#ifdef LWIP_UDP_TODO
+  /* Nail down local IP for netconn_addr()/getsockname() */
+  if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) {
+    struct netif *netif;
+
+    if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {
+      LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr));
+      UDP_STATS_INC(udp.rterr);
+      return ERR_RTE;
+    }
+    /** TODO: this will bind the udp pcb locally, to the interface which
+        is used to route output packets to the remote address. However, we
+        might want to accept incoming packets on any interface! */
+    pcb->local_ip = netif->ip_addr;
+  } else if (ip_addr_isany(&pcb->remote_ip)) {
+    pcb->local_ip.addr = 0;
+  }
+#endif
+  LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
+              ("udp_connect: connected to %"U16_F".%"U16_F".%"U16_F".%"U16_F",port %"U16_F"\n",
+               ip4_addr1_16(&pcb->local_ip), ip4_addr2_16(&pcb->local_ip),
+               ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip),
+               pcb->local_port));
+
+  /* Insert UDP PCB into the list of active UDP PCBs. */
+  for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
+    if (pcb == ipcb) {
+      /* already on the list, just return */
+      return ERR_OK;
+    }
+  }
+  /* PCB not yet on the list, add PCB now */
+  pcb->next = udp_pcbs;
+  udp_pcbs = pcb;
+  return ERR_OK;
+}
+
+/**
+ * Disconnect a UDP PCB
+ *
+ * @param pcb the udp pcb to disconnect.
+ */
+void
+udp_disconnect(struct udp_pcb *pcb)
+{
+  /* reset remote address association */
+  ip_addr_set_any(&pcb->remote_ip);
+  pcb->remote_port = 0;
+  /* mark PCB as unconnected */
+  pcb->flags &= ~UDP_FLAGS_CONNECTED;
+}
+
+/**
+ * Set a receive callback for a UDP PCB
+ *
+ * This callback will be called when receiving a datagram for the pcb.
+ *
+ * @param pcb the pcb for wich to set the recv callback
+ * @param recv function pointer of the callback function
+ * @param recv_arg additional argument to pass to the callback function
+ */
+void
+udp_recv(struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg)
+{
+  /* remember recv() callback and user data */
+  pcb->recv = recv;
+  pcb->recv_arg = recv_arg;
+}
+
+/**
+ * Remove an UDP PCB.
+ *
+ * @param pcb UDP PCB to be removed. The PCB is removed from the list of
+ * UDP PCB's and the data structure is freed from memory.
+ *
+ * @see udp_new()
+ */
+void
+udp_remove(struct udp_pcb *pcb)
+{
+  struct udp_pcb *pcb2;
+
+  snmp_delete_udpidx_tree(pcb);
+  /* pcb to be removed is first in list? */
+  if (udp_pcbs == pcb) {
+    /* make list start at 2nd pcb */
+    udp_pcbs = udp_pcbs->next;
+    /* pcb not 1st in list */
+  } else {
+    for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
+      /* find pcb in udp_pcbs list */
+      if (pcb2->next != NULL && pcb2->next == pcb) {
+        /* remove pcb from list */
+        pcb2->next = pcb->next;
+      }
+    }
+  }
+  memp_free(MEMP_UDP_PCB, pcb);
+}
+
+/**
+ * Create a UDP PCB.
+ *
+ * @return The UDP PCB which was created. NULL if the PCB data structure
+ * could not be allocated.
+ *
+ * @see udp_remove()
+ */
+struct udp_pcb *
+udp_new(void)
+{
+  struct udp_pcb *pcb;
+  pcb = (struct udp_pcb *)memp_malloc(MEMP_UDP_PCB);
+  /* could allocate UDP PCB? */
+  if (pcb != NULL) {
+    /* UDP Lite: by initializing to all zeroes, chksum_len is set to 0
+     * which means checksum is generated over the whole datagram per default
+     * (recommended as default by RFC 3828). */
+    /* initialize PCB to all zeroes */
+    memset(pcb, 0, sizeof(struct udp_pcb));
+    pcb->ttl = UDP_TTL;
+  }
+  return pcb;
+}
+
+#if UDP_DEBUG
+/**
+ * Print UDP header information for debug purposes.
+ *
+ * @param udphdr pointer to the udp header in memory.
+ */
+void
+udp_debug_print(struct udp_hdr *udphdr)
+{
+  LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n"));
+  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(UDP_DEBUG, ("|     %5"U16_F"     |     %5"U16_F"     | (src port, dest port)\n",
+                          ntohs(udphdr->src), ntohs(udphdr->dest)));
+  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
+  LWIP_DEBUGF(UDP_DEBUG, ("|     %5"U16_F"     |     0x%04"X16_F"    | (len, chksum)\n",
+                          ntohs(udphdr->len), ntohs(udphdr->chksum)));
+  LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
+}
+#endif /* UDP_DEBUG */
+
+#endif /* LWIP_UDP */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/autoip.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/autoip.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/autoip.h	(revision 164)
@@ -0,0 +1,118 @@
+/**
+ * @file
+ *
+ * AutoIP Automatic LinkLocal IP Configuration
+ */
+
+/*
+ *
+ * Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Dominik Spies <kontakt@dspies.de>
+ *
+ * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform
+ * with RFC 3927.
+ *
+ *
+ * Please coordinate changes and requests with Dominik Spies
+ * <kontakt@dspies.de>
+ */
+ 
+#ifndef __LWIP_AUTOIP_H__
+#define __LWIP_AUTOIP_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/netif.h"
+#include "lwip/udp.h"
+#include "netif/etharp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* AutoIP Timing */
+#define AUTOIP_TMR_INTERVAL      100
+#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL)
+
+/* RFC 3927 Constants */
+#define PROBE_WAIT               1   /* second   (initial random delay)                 */
+#define PROBE_MIN                1   /* second   (minimum delay till repeated probe)    */
+#define PROBE_MAX                2   /* seconds  (maximum delay till repeated probe)    */
+#define PROBE_NUM                3   /*          (number of probe packets)              */
+#define ANNOUNCE_NUM             2   /*          (number of announcement packets)       */
+#define ANNOUNCE_INTERVAL        2   /* seconds  (time between announcement packets)    */
+#define ANNOUNCE_WAIT            2   /* seconds  (delay before announcing)              */
+#define MAX_CONFLICTS            10  /*          (max conflicts before rate limiting)   */
+#define RATE_LIMIT_INTERVAL      60  /* seconds  (delay between successive attempts)    */
+#define DEFEND_INTERVAL          10  /* seconds  (min. wait between defensive ARPs)     */
+
+/* AutoIP client states */
+#define AUTOIP_STATE_OFF         0
+#define AUTOIP_STATE_PROBING     1
+#define AUTOIP_STATE_ANNOUNCING  2
+#define AUTOIP_STATE_BOUND       3
+
+struct autoip
+{
+  ip_addr_t llipaddr;       /* the currently selected, probed, announced or used LL IP-Address */
+  u8_t state;               /* current AutoIP state machine state */
+  u8_t sent_num;            /* sent number of probes or announces, dependent on state */
+  u16_t ttw;                /* ticks to wait, tick is AUTOIP_TMR_INTERVAL long */
+  u8_t lastconflict;        /* ticks until a conflict can be solved by defending */
+  u8_t tried_llipaddr;      /* total number of probed/used Link Local IP-Addresses */
+};
+
+
+#define autoip_init() /* Compatibility define, no init needed. */
+
+/** Set a struct autoip allocated by the application to work with */
+void autoip_set_struct(struct netif *netif, struct autoip *autoip);
+
+/** Start AutoIP client */
+err_t autoip_start(struct netif *netif);
+
+/** Stop AutoIP client */
+err_t autoip_stop(struct netif *netif);
+
+/** Handles every incoming ARP Packet, called by etharp_arp_input */
+void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr);
+
+/** Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */
+void autoip_tmr(void);
+
+/** Handle a possible change in the network configuration */
+void autoip_network_changed(struct netif *netif);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_AUTOIP */
+
+#endif /* __LWIP_AUTOIP_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/icmp.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/icmp.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/icmp.h	(revision 164)
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_ICMP_H__
+#define __LWIP_ICMP_H__
+
+#include "lwip/opt.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ICMP_ER   0    /* echo reply */
+#define ICMP_DUR  3    /* destination unreachable */
+#define ICMP_SQ   4    /* source quench */
+#define ICMP_RD   5    /* redirect */
+#define ICMP_ECHO 8    /* echo */
+#define ICMP_TE  11    /* time exceeded */
+#define ICMP_PP  12    /* parameter problem */
+#define ICMP_TS  13    /* timestamp */
+#define ICMP_TSR 14    /* timestamp reply */
+#define ICMP_IRQ 15    /* information request */
+#define ICMP_IR  16    /* information reply */
+
+enum icmp_dur_type {
+  ICMP_DUR_NET   = 0,  /* net unreachable */
+  ICMP_DUR_HOST  = 1,  /* host unreachable */
+  ICMP_DUR_PROTO = 2,  /* protocol unreachable */
+  ICMP_DUR_PORT  = 3,  /* port unreachable */
+  ICMP_DUR_FRAG  = 4,  /* fragmentation needed and DF set */
+  ICMP_DUR_SR    = 5   /* source route failed */
+};
+
+enum icmp_te_type {
+  ICMP_TE_TTL  = 0,    /* time to live exceeded in transit */
+  ICMP_TE_FRAG = 1     /* fragment reassembly time exceeded */
+};
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+/** This is the standard ICMP header only that the u32_t data
+ *  is splitted to two u16_t like ICMP echo needs it.
+ *  This header is also used for other ICMP types that do not
+ *  use the data part.
+ */
+PACK_STRUCT_BEGIN
+struct icmp_echo_hdr {
+  PACK_STRUCT_FIELD(u8_t type);
+  PACK_STRUCT_FIELD(u8_t code);
+  PACK_STRUCT_FIELD(u16_t chksum);
+  PACK_STRUCT_FIELD(u16_t id);
+  PACK_STRUCT_FIELD(u16_t seqno);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#define ICMPH_TYPE(hdr) ((hdr)->type)
+#define ICMPH_CODE(hdr) ((hdr)->code)
+
+/** Combines type and code to an u16_t */
+#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t))
+#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c))
+
+
+#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
+
+void icmp_input(struct pbuf *p, struct netif *inp);
+void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
+void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
+
+#endif /* LWIP_ICMP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_ICMP_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/igmp.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/igmp.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/igmp.h	(revision 164)
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2002 CITEL Technologies Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is a contribution to the lwIP TCP/IP stack.
+ * The Swedish Institute of Computer Science and Adam Dunkels
+ * are specifically granted permission to redistribute this
+ * source code.
+*/
+
+#ifndef __LWIP_IGMP_H__
+#define __LWIP_IGMP_H__
+
+#include "lwip/opt.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/pbuf.h"
+
+#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* IGMP timer */
+#define IGMP_TMR_INTERVAL              100 /* Milliseconds */
+#define IGMP_V1_DELAYING_MEMBER_TMR   (1000/IGMP_TMR_INTERVAL)
+#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL)
+
+/* MAC Filter Actions, these are passed to a netif's
+ * igmp_mac_filter callback function. */
+#define IGMP_DEL_MAC_FILTER            0
+#define IGMP_ADD_MAC_FILTER            1
+
+
+/**
+ * igmp group structure - there is
+ * a list of groups for each interface
+ * these should really be linked from the interface, but
+ * if we keep them separate we will not affect the lwip original code
+ * too much
+ * 
+ * There will be a group for the all systems group address but this 
+ * will not run the state machine as it is used to kick off reports
+ * from all the other groups
+ */
+struct igmp_group {
+  /** next link */
+  struct igmp_group *next;
+  /** interface on which the group is active */
+  struct netif      *netif;
+  /** multicast address */
+  ip_addr_t          group_address;
+  /** signifies we were the last person to report */
+  u8_t               last_reporter_flag;
+  /** current state of the group */
+  u8_t               group_state;
+  /** timer for reporting, negative is OFF */
+  u16_t              timer;
+  /** counter of simultaneous uses */
+  u8_t               use;
+};
+
+/*  Prototypes */
+void   igmp_init(void);
+err_t  igmp_start(struct netif *netif);
+err_t  igmp_stop(struct netif *netif);
+void   igmp_report_groups(struct netif *netif);
+struct igmp_group *igmp_lookfor_group(struct netif *ifp, ip_addr_t *addr);
+void   igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest);
+err_t  igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr);
+err_t  igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr);
+void   igmp_tmr(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IGMP */
+
+#endif /* __LWIP_IGMP_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/inet.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/inet.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/inet.h	(revision 164)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_INET_H__
+#define __LWIP_INET_H__
+
+#include "lwip/opt.h"
+#include "lwip/def.h"
+#include "lwip/ip_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** For compatibility with BSD code */
+struct in_addr {
+  u32_t s_addr;
+};
+
+/** 255.255.255.255 */
+#define INADDR_NONE         IPADDR_NONE
+/** 127.0.0.1 */
+#define INADDR_LOOPBACK     IPADDR_LOOPBACK
+/** 0.0.0.0 */
+#define INADDR_ANY          IPADDR_ANY
+/** 255.255.255.255 */
+#define INADDR_BROADCAST    IPADDR_BROADCAST
+
+/* Definitions of the bits in an Internet address integer.
+
+   On subnets, host and network parts are found according to
+   the subnet mask, not these masks.  */
+#define IN_CLASSA(a)        IP_CLASSA(a)
+#define IN_CLASSA_NET       IP_CLASSA_NET
+#define IN_CLASSA_NSHIFT    IP_CLASSA_NSHIFT
+#define IN_CLASSA_HOST      IP_CLASSA_HOST
+#define IN_CLASSA_MAX       IP_CLASSA_MAX
+
+#define IN_CLASSB(b)        IP_CLASSB(b)
+#define IN_CLASSB_NET       IP_CLASSB_NET
+#define IN_CLASSB_NSHIFT    IP_CLASSB_NSHIFT
+#define IN_CLASSB_HOST      IP_CLASSB_HOST
+#define IN_CLASSB_MAX       IP_CLASSB_MAX
+
+#define IN_CLASSC(c)        IP_CLASSC(c)
+#define IN_CLASSC_NET       IP_CLASSC_NET
+#define IN_CLASSC_NSHIFT    IP_CLASSC_NSHIFT
+#define IN_CLASSC_HOST      IP_CLASSC_HOST
+#define IN_CLASSC_MAX       IP_CLASSC_MAX
+
+#define IN_CLASSD(d)        IP_CLASSD(d)
+#define IN_CLASSD_NET       IP_CLASSD_NET     /* These ones aren't really */
+#define IN_CLASSD_NSHIFT    IP_CLASSD_NSHIFT  /*   net and host fields, but */
+#define IN_CLASSD_HOST      IP_CLASSD_HOST    /*   routing needn't know. */
+#define IN_CLASSD_MAX       IP_CLASSD_MAX
+
+#define IN_MULTICAST(a)     IP_MULTICAST(a)
+
+#define IN_EXPERIMENTAL(a)  IP_EXPERIMENTAL(a)
+#define IN_BADCLASS(a)      IP_BADCLASS(a)
+
+#define IN_LOOPBACKNET      IP_LOOPBACKNET
+
+#define inet_addr_from_ipaddr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
+#define inet_addr_to_ipaddr(target_ipaddr, source_inaddr)   (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
+/* ATTENTION: the next define only works because both s_addr and ip_addr_t are an u32_t effectively! */
+#define inet_addr_to_ipaddr_p(target_ipaddr_p, source_inaddr)   ((target_ipaddr_p) = (ip_addr_t*)&((source_inaddr)->s_addr))
+
+/* directly map this to the lwip internal functions */
+#define inet_addr(cp)         ipaddr_addr(cp)
+#define inet_aton(cp, addr)   ipaddr_aton(cp, (ip_addr_t*)addr)
+#define inet_ntoa(addr)       ipaddr_ntoa((ip_addr_t*)&(addr))
+#define inet_ntoa_r(addr, buf, buflen) ipaddr_ntoa_r((ip_addr_t*)&(addr), buf, buflen)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_INET_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h	(revision 164)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_INET_CHKSUM_H__
+#define __LWIP_INET_CHKSUM_H__
+
+#include "lwip/opt.h"
+
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+
+/** Swap the bytes in an u16_t: much like htons() for little-endian */
+#ifndef SWAP_BYTES_IN_WORD
+#if LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN)
+/* little endian and PLATFORM_BYTESWAP defined */
+#define SWAP_BYTES_IN_WORD(w) LWIP_PLATFORM_HTONS(w)
+#else /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) */
+/* can't use htons on big endian (or PLATFORM_BYTESWAP not defined)... */
+#define SWAP_BYTES_IN_WORD(w) (((w) & 0xff) << 8) | (((w) & 0xff00) >> 8)
+#endif /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN)*/
+#endif /* SWAP_BYTES_IN_WORD */
+
+/** Split an u32_t in two u16_ts and add them up */
+#ifndef FOLD_U32T
+#define FOLD_U32T(u)          (((u) >> 16) + ((u) & 0x0000ffffUL))
+#endif
+
+#if LWIP_CHECKSUM_ON_COPY
+/** Function-like macro: same as MEMCPY but returns the checksum of copied data
+    as u16_t */
+#ifndef LWIP_CHKSUM_COPY
+#define LWIP_CHKSUM_COPY(dst, src, len) lwip_chksum_copy(dst, src, len)
+#ifndef LWIP_CHKSUM_COPY_ALGORITHM
+#define LWIP_CHKSUM_COPY_ALGORITHM 1
+#endif /* LWIP_CHKSUM_COPY_ALGORITHM */
+#endif /* LWIP_CHKSUM_COPY */
+#else /* LWIP_CHECKSUM_ON_COPY */
+#define LWIP_CHKSUM_COPY_ALGORITHM 0
+#endif /* LWIP_CHECKSUM_ON_COPY */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+u16_t inet_chksum(void *dataptr, u16_t len);
+u16_t inet_chksum_pbuf(struct pbuf *p);
+u16_t inet_chksum_pseudo(struct pbuf *p,
+       ip_addr_t *src, ip_addr_t *dest,
+       u8_t proto, u16_t proto_len);
+u16_t inet_chksum_pseudo_partial(struct pbuf *p,
+       ip_addr_t *src, ip_addr_t *dest,
+       u8_t proto, u16_t proto_len, u16_t chksum_len);
+#if LWIP_CHKSUM_COPY_ALGORITHM
+u16_t lwip_chksum_copy(void *dst, const void *src, u16_t len);
+#endif /* LWIP_CHKSUM_COPY_ALGORITHM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_INET_H__ */
+
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/ip.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/ip.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/ip.h	(revision 164)
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_IP_H__
+#define __LWIP_IP_H__
+
+#include "lwip/opt.h"
+
+#include "lwip/def.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+#include "lwip/err.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Currently, the function ip_output_if_opt() is only used with IGMP */
+#define IP_OPTIONS_SEND   LWIP_IGMP
+
+#define IP_HLEN 20
+
+#define IP_PROTO_ICMP    1
+#define IP_PROTO_IGMP    2
+#define IP_PROTO_UDP     17
+#define IP_PROTO_UDPLITE 136
+#define IP_PROTO_TCP     6
+
+/* This is passed as the destination address to ip_output_if (not
+   to ip_output), meaning that an IP header already is constructed
+   in the pbuf. This is used when TCP retransmits. */
+#ifdef IP_HDRINCL
+#undef IP_HDRINCL
+#endif /* IP_HDRINCL */
+#define IP_HDRINCL  NULL
+
+#if LWIP_NETIF_HWADDRHINT
+#define IP_PCB_ADDRHINT ;u8_t addr_hint
+#else
+#define IP_PCB_ADDRHINT
+#endif /* LWIP_NETIF_HWADDRHINT */
+
+/* This is the common part of all PCB types. It needs to be at the
+   beginning of a PCB type definition. It is located here so that
+   changes to this common part are made in one location instead of
+   having to change all PCB structs. */
+#define IP_PCB \
+  /* ip addresses in network byte order */ \
+  ip_addr_t local_ip; \
+  ip_addr_t remote_ip; \
+   /* Socket options */  \
+  u8_t so_options;      \
+   /* Type Of Service */ \
+  u8_t tos;              \
+  /* Time To Live */     \
+  u8_t ttl               \
+  /* link layer address resolution hint */ \
+  IP_PCB_ADDRHINT
+
+struct ip_pcb {
+/* Common members of all PCB types */
+  IP_PCB;
+};
+
+/*
+ * Option flags per-socket. These are the same like SO_XXX.
+ */
+/*#define SOF_DEBUG       0x01U     Unimplemented: turn on debugging info recording */
+#define SOF_ACCEPTCONN    0x02U  /* socket has had listen() */
+#define SOF_REUSEADDR     0x04U  /* allow local address reuse */
+#define SOF_KEEPALIVE     0x08U  /* keep connections alive */
+/*#define SOF_DONTROUTE   0x10U     Unimplemented: just use interface addresses */
+#define SOF_BROADCAST     0x20U  /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
+/*#define SOF_USELOOPBACK 0x40U     Unimplemented: bypass hardware when possible */
+#define SOF_LINGER        0x80U  /* linger on close if data present */
+/*#define SOF_OOBINLINE   0x0100U   Unimplemented: leave received OOB data in line */
+/*#define SOF_REUSEPORT   0x0200U   Unimplemented: allow local address & port reuse */
+
+/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */
+#define SOF_INHERITED   (SOF_REUSEADDR|SOF_KEEPALIVE|SOF_LINGER/*|SOF_DEBUG|SOF_DONTROUTE|SOF_OOBINLINE*/)
+
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip_hdr {
+  /* version / header length */
+  PACK_STRUCT_FIELD(u8_t _v_hl);
+  /* type of service */
+  PACK_STRUCT_FIELD(u8_t _tos);
+  /* total length */
+  PACK_STRUCT_FIELD(u16_t _len);
+  /* identification */
+  PACK_STRUCT_FIELD(u16_t _id);
+  /* fragment offset field */
+  PACK_STRUCT_FIELD(u16_t _offset);
+#define IP_RF 0x8000U        /* reserved fragment flag */
+#define IP_DF 0x4000U        /* dont fragment flag */
+#define IP_MF 0x2000U        /* more fragments flag */
+#define IP_OFFMASK 0x1fffU   /* mask for fragmenting bits */
+  /* time to live */
+  PACK_STRUCT_FIELD(u8_t _ttl);
+  /* protocol*/
+  PACK_STRUCT_FIELD(u8_t _proto);
+  /* checksum */
+  PACK_STRUCT_FIELD(u16_t _chksum);
+  /* source and destination IP addresses */
+  PACK_STRUCT_FIELD(ip_addr_p_t src);
+  PACK_STRUCT_FIELD(ip_addr_p_t dest); 
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#define IPH_V(hdr)  ((hdr)->_v_hl >> 4)
+#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f)
+#define IPH_TOS(hdr) ((hdr)->_tos)
+#define IPH_LEN(hdr) ((hdr)->_len)
+#define IPH_ID(hdr) ((hdr)->_id)
+#define IPH_OFFSET(hdr) ((hdr)->_offset)
+#define IPH_TTL(hdr) ((hdr)->_ttl)
+#define IPH_PROTO(hdr) ((hdr)->_proto)
+#define IPH_CHKSUM(hdr) ((hdr)->_chksum)
+
+#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (((v) << 4) | (hl))
+#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos)
+#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len)
+#define IPH_ID_SET(hdr, id) (hdr)->_id = (id)
+#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off)
+#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl)
+#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto)
+#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum)
+
+/** The interface that provided the packet for the current callback invocation. */
+extern struct netif *current_netif;
+/** Header of the input packet currently being processed. */
+extern const struct ip_hdr *current_header;
+/** Source IP address of current_header */
+extern ip_addr_t current_iphdr_src;
+/** Destination IP address of current_header */
+extern ip_addr_t current_iphdr_dest;
+
+#define ip_init() /* Compatibility define, not init needed. */
+struct netif *ip_route(ip_addr_t *dest);
+err_t ip_input(struct pbuf *p, struct netif *inp);
+err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
+       u8_t ttl, u8_t tos, u8_t proto);
+err_t ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
+       u8_t ttl, u8_t tos, u8_t proto,
+       struct netif *netif);
+#if LWIP_NETIF_HWADDRHINT
+err_t ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
+       u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint);
+#endif /* LWIP_NETIF_HWADDRHINT */
+#if IP_OPTIONS_SEND
+err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
+       u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
+       u16_t optlen);
+#endif /* IP_OPTIONS_SEND */
+/** Get the interface that received the current packet.
+ * This function must only be called from a receive callback (udp_recv,
+ * raw_recv, tcp_accept). It will return NULL otherwise. */
+#define ip_current_netif()  (current_netif)
+/** Get the IP header of the current packet.
+ * This function must only be called from a receive callback (udp_recv,
+ * raw_recv, tcp_accept). It will return NULL otherwise. */
+#define ip_current_header() (current_header)
+/** Source IP address of current_header */
+#define ip_current_src_addr()  (&current_iphdr_src)
+/** Destination IP address of current_header */
+#define ip_current_dest_addr() (&current_iphdr_dest)
+
+/** Gets an IP pcb option (SOF_* flags) */
+#define ip_get_option(pcb, opt)   ((pcb)->so_options & (opt))
+/** Sets an IP pcb option (SOF_* flags) */
+#define ip_set_option(pcb, opt)   ((pcb)->so_options |= (opt))
+/** Resets an IP pcb option (SOF_* flags) */
+#define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt))
+
+#if IP_DEBUG
+void ip_debug_print(struct pbuf *p);
+#else
+#define ip_debug_print(p)
+#endif /* IP_DEBUG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_IP_H__ */
+
+
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h	(revision 164)
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_IP_ADDR_H__
+#define __LWIP_IP_ADDR_H__
+
+#include "lwip/opt.h"
+#include "lwip/def.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This is the aligned version of ip_addr_t,
+   used as local variable, on the stack, etc. */
+struct ip_addr {
+  u32_t addr;
+};
+
+/* This is the packed version of ip_addr_t,
+   used in network headers that are itself packed */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip_addr_packed {
+  PACK_STRUCT_FIELD(u32_t addr);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/** ip_addr_t uses a struct for convenience only, so that the same defines can
+ * operate both on ip_addr_t as well as on ip_addr_p_t. */
+typedef struct ip_addr ip_addr_t;
+typedef struct ip_addr_packed ip_addr_p_t;
+
+/*
+ * struct ipaddr2 is used in the definition of the ARP packet format in
+ * order to support compilers that don't have structure packing.
+ */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip_addr2 {
+  PACK_STRUCT_FIELD(u16_t addrw[2]);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/* Forward declaration to not include netif.h */
+struct netif;
+
+extern const ip_addr_t ip_addr_any;
+extern const ip_addr_t ip_addr_broadcast;
+
+/** IP_ADDR_ can be used as a fixed IP address
+ *  for the wildcard and the broadcast address
+ */
+#define IP_ADDR_ANY         ((ip_addr_t *)&ip_addr_any)
+#define IP_ADDR_BROADCAST   ((ip_addr_t *)&ip_addr_broadcast)
+
+/** 255.255.255.255 */
+#define IPADDR_NONE         ((u32_t)0xffffffffUL)
+/** 127.0.0.1 */
+#define IPADDR_LOOPBACK     ((u32_t)0x7f000001UL)
+/** 0.0.0.0 */
+#define IPADDR_ANY          ((u32_t)0x00000000UL)
+/** 255.255.255.255 */
+#define IPADDR_BROADCAST    ((u32_t)0xffffffffUL)
+
+/* Definitions of the bits in an Internet address integer.
+
+   On subnets, host and network parts are found according to
+   the subnet mask, not these masks.  */
+#define IP_CLASSA(a)        ((((u32_t)(a)) & 0x80000000UL) == 0)
+#define IP_CLASSA_NET       0xff000000
+#define IP_CLASSA_NSHIFT    24
+#define IP_CLASSA_HOST      (0xffffffff & ~IP_CLASSA_NET)
+#define IP_CLASSA_MAX       128
+
+#define IP_CLASSB(a)        ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL)
+#define IP_CLASSB_NET       0xffff0000
+#define IP_CLASSB_NSHIFT    16
+#define IP_CLASSB_HOST      (0xffffffff & ~IP_CLASSB_NET)
+#define IP_CLASSB_MAX       65536
+
+#define IP_CLASSC(a)        ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL)
+#define IP_CLASSC_NET       0xffffff00
+#define IP_CLASSC_NSHIFT    8
+#define IP_CLASSC_HOST      (0xffffffff & ~IP_CLASSC_NET)
+
+#define IP_CLASSD(a)        (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL)
+#define IP_CLASSD_NET       0xf0000000          /* These ones aren't really */
+#define IP_CLASSD_NSHIFT    28                  /*   net and host fields, but */
+#define IP_CLASSD_HOST      0x0fffffff          /*   routing needn't know. */
+#define IP_MULTICAST(a)     IP_CLASSD(a)
+
+#define IP_EXPERIMENTAL(a)  (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL)
+#define IP_BADCLASS(a)      (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL)
+
+#define IP_LOOPBACKNET      127                 /* official! */
+
+
+#if BYTE_ORDER == BIG_ENDIAN
+/** Set an IP address given by the four byte-parts */
+#define IP4_ADDR(ipaddr, a,b,c,d) \
+        (ipaddr)->addr = ((u32_t)((a) & 0xff) << 24) | \
+                         ((u32_t)((b) & 0xff) << 16) | \
+                         ((u32_t)((c) & 0xff) << 8)  | \
+                          (u32_t)((d) & 0xff)
+#else
+/** Set an IP address given by the four byte-parts.
+    Little-endian version that prevents the use of htonl. */
+#define IP4_ADDR(ipaddr, a,b,c,d) \
+        (ipaddr)->addr = ((u32_t)((d) & 0xff) << 24) | \
+                         ((u32_t)((c) & 0xff) << 16) | \
+                         ((u32_t)((b) & 0xff) << 8)  | \
+                          (u32_t)((a) & 0xff)
+#endif
+
+/** MEMCPY-like copying of IP addresses where addresses are known to be
+ * 16-bit-aligned if the port is correctly configured (so a port could define
+ * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */
+#ifndef IPADDR2_COPY
+#define IPADDR2_COPY(dest, src) SMEMCPY(dest, src, sizeof(ip_addr_t))
+#endif
+
+/** Copy IP address - faster than ip_addr_set: no NULL check */
+#define ip_addr_copy(dest, src) ((dest).addr = (src).addr)
+/** Safely copy one IP address to another (src may be NULL) */
+#define ip_addr_set(dest, src) ((dest)->addr = \
+                                    ((src) == NULL ? 0 : \
+                                    (src)->addr))
+/** Set complete address to zero */
+#define ip_addr_set_zero(ipaddr)      ((ipaddr)->addr = 0)
+/** Set address to IPADDR_ANY (no need for htonl()) */
+#define ip_addr_set_any(ipaddr)       ((ipaddr)->addr = IPADDR_ANY)
+/** Set address to loopback address */
+#define ip_addr_set_loopback(ipaddr)  ((ipaddr)->addr = PP_HTONL(IPADDR_LOOPBACK))
+/** Safely copy one IP address to another and change byte order
+ * from host- to network-order. */
+#define ip_addr_set_hton(dest, src) ((dest)->addr = \
+                               ((src) == NULL ? 0:\
+                               htonl((src)->addr)))
+/** IPv4 only: set the IP address given as an u32_t */
+#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32))
+/** IPv4 only: get the IP address as an u32_t */
+#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr)
+
+/** Get the network address by combining host address with netmask */
+#define ip_addr_get_network(target, host, netmask) ((target)->addr = ((host)->addr) & ((netmask)->addr))
+
+/**
+ * Determine if two address are on the same network.
+ *
+ * @arg addr1 IP address 1
+ * @arg addr2 IP address 2
+ * @arg mask network identifier mask
+ * @return !0 if the network identifiers of both address match
+ */
+#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \
+                                              (mask)->addr) == \
+                                             ((addr2)->addr & \
+                                              (mask)->addr))
+#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)
+
+#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == IPADDR_ANY)
+
+#define ip_addr_isbroadcast(ipaddr, netif) ip4_addr_isbroadcast((ipaddr)->addr, (netif))
+u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif);
+
+#define ip_addr_netmask_valid(netmask) ip4_addr_netmask_valid((netmask)->addr)
+u8_t ip4_addr_netmask_valid(u32_t netmask);
+
+#define ip_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL))
+
+#define ip_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL))
+
+#define ip_addr_debug_print(debug, ipaddr) \
+  LWIP_DEBUGF(debug, ("%"U16_F".%"U16_F".%"U16_F".%"U16_F,             \
+                      ipaddr != NULL ? ip4_addr1_16(ipaddr) : 0,       \
+                      ipaddr != NULL ? ip4_addr2_16(ipaddr) : 0,       \
+                      ipaddr != NULL ? ip4_addr3_16(ipaddr) : 0,       \
+                      ipaddr != NULL ? ip4_addr4_16(ipaddr) : 0))
+
+/* Get one byte from the 4-byte address */
+#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0])
+#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1])
+#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2])
+#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3])
+/* These are cast to u16_t, with the intent that they are often arguments
+ * to printf using the U16_F format from cc.h. */
+#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr))
+#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr))
+#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr))
+#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr))
+
+/** For backwards compatibility */
+#define ip_ntoa(ipaddr)  ipaddr_ntoa(ipaddr)
+
+u32_t ipaddr_addr(const char *cp);
+int ipaddr_aton(const char *cp, ip_addr_t *addr);
+/** returns ptr to static buffer; not reentrant! */
+char *ipaddr_ntoa(const ip_addr_t *addr);
+char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_IP_ADDR_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/ip_frag.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/ip_frag.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv4/lwip/ip_frag.h	(revision 164)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Jani Monoses <jani@iv.ro>
+ *
+ */
+
+#ifndef __LWIP_IP_FRAG_H__
+#define __LWIP_IP_FRAG_H__
+
+#include "lwip/opt.h"
+#include "lwip/err.h"
+#include "lwip/pbuf.h"
+#include "lwip/netif.h"
+#include "lwip/ip_addr.h"
+#include "lwip/ip.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if IP_REASSEMBLY
+/* The IP reassembly timer interval in milliseconds. */
+#define IP_TMR_INTERVAL 1000
+
+/* IP reassembly helper struct.
+ * This is exported because memp needs to know the size.
+ */
+struct ip_reassdata {
+  struct ip_reassdata *next;
+  struct pbuf *p;
+  struct ip_hdr iphdr;
+  u16_t datagram_len;
+  u8_t flags;
+  u8_t timer;
+};
+
+void ip_reass_init(void);
+void ip_reass_tmr(void);
+struct pbuf * ip_reass(struct pbuf *p);
+#endif /* IP_REASSEMBLY */
+
+#if IP_FRAG
+#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF
+/** A custom pbuf that holds a reference to another pbuf, which is freed
+ * when this custom pbuf is freed. This is used to create a custom PBUF_REF
+ * that points into the original pbuf. */
+struct pbuf_custom_ref {
+  /** 'base class' */
+  struct pbuf_custom pc;
+  /** pointer to the original pbuf that is referenced */
+  struct pbuf *original;
+};
+#endif /* !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */
+
+err_t ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest);
+#endif /* IP_FRAG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_IP_FRAG_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv6/lwip/icmp.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv6/lwip/icmp.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv6/lwip/icmp.h	(revision 164)
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_ICMP_H__
+#define __LWIP_ICMP_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/pbuf.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ICMP6_DUR  1
+#define ICMP6_TE   3
+#define ICMP6_ECHO 128    /* echo */
+#define ICMP6_ER   129      /* echo reply */
+
+
+enum icmp_dur_type {
+  ICMP_DUR_NET = 0,    /* net unreachable */
+  ICMP_DUR_HOST = 1,   /* host unreachable */
+  ICMP_DUR_PROTO = 2,  /* protocol unreachable */
+  ICMP_DUR_PORT = 3,   /* port unreachable */
+  ICMP_DUR_FRAG = 4,   /* fragmentation needed and DF set */
+  ICMP_DUR_SR = 5      /* source route failed */
+};
+
+enum icmp_te_type {
+  ICMP_TE_TTL = 0,     /* time to live exceeded in transit */
+  ICMP_TE_FRAG = 1     /* fragment reassembly time exceeded */
+};
+
+void icmp_input(struct pbuf *p, struct netif *inp);
+
+void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
+void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
+
+struct icmp_echo_hdr {
+  u8_t type;
+  u8_t icode;
+  u16_t chksum;
+  u16_t id;
+  u16_t seqno;
+};
+
+struct icmp_dur_hdr {
+  u8_t type;
+  u8_t icode;
+  u16_t chksum;
+  u32_t unused;
+};
+
+struct icmp_te_hdr {
+  u8_t type;
+  u8_t icode;
+  u16_t chksum;
+  u32_t unused;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_ICMP */
+
+#endif /* __LWIP_ICMP_H__ */
+
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv6/lwip/inet.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv6/lwip/inet.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv6/lwip/inet.h	(revision 164)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_INET_H__
+#define __LWIP_INET_H__
+
+#include "lwip/opt.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+u16_t inet_chksum(void *data, u16_t len);
+u16_t inet_chksum_pbuf(struct pbuf *p);
+u16_t inet_chksum_pseudo(struct pbuf *p,
+       struct ip_addr *src, struct ip_addr *dest,
+       u8_t proto, u32_t proto_len);
+
+u32_t inet_addr(const char *cp);
+s8_t inet_aton(const char *cp, struct in_addr *addr);
+
+#ifndef _MACHINE_ENDIAN_H_
+#ifndef _NETINET_IN_H
+#ifndef _LINUX_BYTEORDER_GENERIC_H
+u16_t htons(u16_t n);
+u16_t ntohs(u16_t n);
+u32_t htonl(u32_t n);
+u32_t ntohl(u32_t n);
+#endif /* _LINUX_BYTEORDER_GENERIC_H */
+#endif /* _NETINET_IN_H */
+#endif /* _MACHINE_ENDIAN_H_ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_INET_H__ */
+
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv6/lwip/ip.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv6/lwip/ip.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv6/lwip/ip.h	(revision 164)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_IP_H__
+#define __LWIP_IP_H__
+
+#include "lwip/opt.h"
+#include "lwip/def.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define IP_HLEN 40
+
+#define IP_PROTO_ICMP    58
+#define IP_PROTO_UDP     17
+#define IP_PROTO_UDPLITE 136
+#define IP_PROTO_TCP     6
+
+/* This is passed as the destination address to ip_output_if (not
+   to ip_output), meaning that an IP header already is constructed
+   in the pbuf. This is used when TCP retransmits. */
+#ifdef IP_HDRINCL
+#undef IP_HDRINCL
+#endif /* IP_HDRINCL */
+#define IP_HDRINCL  NULL
+
+#if LWIP_NETIF_HWADDRHINT
+#define IP_PCB_ADDRHINT ;u8_t addr_hint
+#else
+#define IP_PCB_ADDRHINT
+#endif /* LWIP_NETIF_HWADDRHINT */
+
+/* This is the common part of all PCB types. It needs to be at the
+   beginning of a PCB type definition. It is located here so that
+   changes to this common part are made in one location instead of
+   having to change all PCB structs. */
+#define IP_PCB struct ip_addr local_ip; \
+  struct ip_addr remote_ip; \
+   /* Socket options */  \
+  u16_t so_options;      \
+   /* Type Of Service */ \
+  u8_t tos;              \
+  /* Time To Live */     \
+  u8_t ttl;              \
+  /* link layer address resolution hint */ \
+  IP_PCB_ADDRHINT
+
+
+/* The IPv6 header. */
+struct ip_hdr {
+#if BYTE_ORDER == LITTLE_ENDIAN
+  u8_t tclass1:4, v:4;
+  u8_t flow1:4, tclass2:4;  
+#else
+  u8_t v:4, tclass1:4;
+  u8_t tclass2:8, flow1:4;
+#endif
+  u16_t flow2;
+  u16_t len;                /* payload length */
+  u8_t nexthdr;             /* next header */
+  u8_t hoplim;              /* hop limit (TTL) */
+  struct ip_addr src, dest;          /* source and destination IP addresses */
+};
+
+#define IPH_PROTO(hdr) (iphdr->nexthdr)
+
+void ip_init(void);
+
+#include "lwip/netif.h"
+
+struct netif *ip_route(struct ip_addr *dest);
+
+void ip_input(struct pbuf *p, struct netif *inp);
+
+/* source and destination addresses in network byte order, please */
+err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
+         u8_t ttl, u8_t proto);
+
+err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
+      u8_t ttl, u8_t proto,
+      struct netif *netif);
+
+#define ip_current_netif() NULL
+#define ip_current_header() NULL
+
+#if IP_DEBUG
+void ip_debug_print(struct pbuf *p);
+#endif /* IP_DEBUG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_IP_H__ */
+
+
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv6/lwip/ip_addr.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv6/lwip/ip_addr.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/ipv6/lwip/ip_addr.h	(revision 164)
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_IP_ADDR_H__
+#define __LWIP_IP_ADDR_H__
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define IP_ADDR_ANY 0
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+ struct ip_addr {
+  PACK_STRUCT_FIELD(u32_t addr[4]);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+/*
+ * struct ipaddr2 is used in the definition of the ARP packet format in
+ * order to support compilers that don't have structure packing.
+ */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct ip_addr2 {
+  PACK_STRUCT_FIELD(u16_t addrw[2]);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#define IP6_ADDR(ipaddr, a,b,c,d,e,f,g,h) do { (ipaddr)->addr[0] = htonl((u32_t)((a & 0xffff) << 16) | (b & 0xffff)); \
+                                               (ipaddr)->addr[1] = htonl(((c & 0xffff) << 16) | (d & 0xffff)); \
+                                               (ipaddr)->addr[2] = htonl(((e & 0xffff) << 16) | (f & 0xffff)); \
+                                               (ipaddr)->addr[3] = htonl(((g & 0xffff) << 16) | (h & 0xffff)); } while(0)
+
+u8_t ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2,
+        struct ip_addr *mask);
+u8_t ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2);
+void ip_addr_set(struct ip_addr *dest, struct ip_addr *src);
+u8_t ip_addr_isany(struct ip_addr *addr);
+
+#define ip_addr_debug_print(debug, ipaddr) \
+        LWIP_DEBUGF(debug, ("%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F"\n", \
+         (ntohl(ipaddr->addr[0]) >> 16) & 0xffff, \
+         ntohl(ipaddr->addr[0]) & 0xffff, \
+         (ntohl(ipaddr->addr[1]) >> 16) & 0xffff, \
+         ntohl(ipaddr->addr[1]) & 0xffff, \
+         (ntohl(ipaddr->addr[2]) >> 16) & 0xffff, \
+         ntohl(ipaddr->addr[2]) & 0xffff, \
+         (ntohl(ipaddr->addr[3]) >> 16) & 0xffff, \
+         ntohl(ipaddr->addr[3]) & 0xffff));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_IP_ADDR_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/api.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/api.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/api.h	(revision 164)
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_API_H__
+#define __LWIP_API_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
+
+#include <stddef.h> /* for size_t */
+
+#include "lwip/netbuf.h"
+#include "lwip/sys.h"
+#include "lwip/ip_addr.h"
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Throughout this file, IP addresses and port numbers are expected to be in
+ * the same byte order as in the corresponding pcb.
+ */
+
+/* Flags for netconn_write (u8_t) */
+#define NETCONN_NOFLAG    0x00
+#define NETCONN_NOCOPY    0x00 /* Only for source code compatibility */
+#define NETCONN_COPY      0x01
+#define NETCONN_MORE      0x02
+#define NETCONN_DONTBLOCK 0x04
+
+/* Flags for struct netconn.flags (u8_t) */
+/** TCP: when data passed to netconn_write doesn't fit into the send buffer,
+    this temporarily stores whether to wake up the original application task
+    if data couldn't be sent in the first try. */
+#define NETCONN_FLAG_WRITE_DELAYED            0x01
+/** Should this netconn avoid blocking? */
+#define NETCONN_FLAG_NON_BLOCKING             0x02
+/** Was the last connect action a non-blocking one? */
+#define NETCONN_FLAG_IN_NONBLOCKING_CONNECT   0x04
+/** If this is set, a TCP netconn must call netconn_recved() to update
+    the TCP receive window (done automatically if not set). */
+#define NETCONN_FLAG_NO_AUTO_RECVED           0x08
+/** If a nonblocking write has been rejected before, poll_tcp needs to
+    check if the netconn is writable again */
+#define NETCONN_FLAG_CHECK_WRITESPACE         0x10
+
+
+/* Helpers to process several netconn_types by the same code */
+#define NETCONNTYPE_GROUP(t)    (t&0xF0)
+#define NETCONNTYPE_DATAGRAM(t) (t&0xE0)
+
+/** Protocol family and type of the netconn */
+enum netconn_type {
+  NETCONN_INVALID    = 0,
+  /* NETCONN_TCP Group */
+  NETCONN_TCP        = 0x10,
+  /* NETCONN_UDP Group */
+  NETCONN_UDP        = 0x20,
+  NETCONN_UDPLITE    = 0x21,
+  NETCONN_UDPNOCHKSUM= 0x22,
+  /* NETCONN_RAW Group */
+  NETCONN_RAW        = 0x40
+};
+
+/** Current state of the netconn. Non-TCP netconns are always
+ * in state NETCONN_NONE! */
+enum netconn_state {
+  NETCONN_NONE,
+  NETCONN_WRITE,
+  NETCONN_LISTEN,
+  NETCONN_CONNECT,
+  NETCONN_CLOSE
+};
+
+/** Use to inform the callback function about changes */
+enum netconn_evt {
+  NETCONN_EVT_RCVPLUS,
+  NETCONN_EVT_RCVMINUS,
+  NETCONN_EVT_SENDPLUS,
+  NETCONN_EVT_SENDMINUS,
+  NETCONN_EVT_ERROR
+};
+
+#if LWIP_IGMP
+/** Used for netconn_join_leave_group() */
+enum netconn_igmp {
+  NETCONN_JOIN,
+  NETCONN_LEAVE
+};
+#endif /* LWIP_IGMP */
+
+/* forward-declare some structs to avoid to include their headers */
+struct ip_pcb;
+struct tcp_pcb;
+struct udp_pcb;
+struct raw_pcb;
+struct netconn;
+struct api_msg_msg;
+
+/** A callback prototype to inform about events for a netconn */
+typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len);
+
+/** A netconn descriptor */
+struct netconn {
+  /** type of the netconn (TCP, UDP or RAW) */
+  enum netconn_type type;
+  /** current state of the netconn */
+  enum netconn_state state;
+  /** the lwIP internal protocol control block */
+  union {
+    struct ip_pcb  *ip;
+    struct tcp_pcb *tcp;
+    struct udp_pcb *udp;
+    struct raw_pcb *raw;
+  } pcb;
+  /** the last error this netconn had */
+  err_t last_err;
+  /** sem that is used to synchroneously execute functions in the core context */
+  sys_sem_t op_completed;
+  /** mbox where received packets are stored until they are fetched
+      by the netconn application thread (can grow quite big) */
+  sys_mbox_t recvmbox;
+#if LWIP_TCP
+  /** mbox where new connections are stored until processed
+      by the application thread */
+  sys_mbox_t acceptmbox;
+#endif /* LWIP_TCP */
+  /** only used for socket layer */
+#if LWIP_SOCKET
+  int socket;
+#endif /* LWIP_SOCKET */
+#if LWIP_SO_SNDTIMEO
+  /** timeout to wait for sending data (which means enqueueing data for sending
+      in internal buffers) */
+  s32_t send_timeout;
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVTIMEO
+  /** timeout to wait for new data to be received
+      (or connections to arrive for listening netconns) */
+  int recv_timeout;
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+  /** maximum amount of bytes queued in recvmbox
+      not used for TCP: adjust TCP_WND instead! */
+  int recv_bufsize;
+  /** number of bytes currently in recvmbox to be received,
+      tested against recv_bufsize to limit bytes on recvmbox
+      for UDP and RAW, used for FIONREAD */
+  s16_t recv_avail;
+#endif /* LWIP_SO_RCVBUF */
+  /** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */
+  u8_t flags;
+#if LWIP_TCP
+  /** TCP: when data passed to netconn_write doesn't fit into the send buffer,
+      this temporarily stores how much is already sent. */
+  size_t write_offset;
+  /** TCP: when data passed to netconn_write doesn't fit into the send buffer,
+      this temporarily stores the message.
+      Also used during connect and close. */
+  struct api_msg_msg *current_msg;
+#endif /* LWIP_TCP */
+  /** A callback function that is informed about events for this netconn */
+  netconn_callback callback;
+};
+
+/** Register an Network connection event */
+#define API_EVENT(c,e,l) if (c->callback) {         \
+                           (*c->callback)(c, e, l); \
+                         }
+
+/** Set conn->last_err to err but don't overwrite fatal errors */
+#define NETCONN_SET_SAFE_ERR(conn, err) do { \
+  SYS_ARCH_DECL_PROTECT(lev); \
+  SYS_ARCH_PROTECT(lev); \
+  if (!ERR_IS_FATAL((conn)->last_err)) { \
+    (conn)->last_err = err; \
+  } \
+  SYS_ARCH_UNPROTECT(lev); \
+} while(0);
+
+/* Network connection functions: */
+#define netconn_new(t)                  netconn_new_with_proto_and_callback(t, 0, NULL)
+#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c)
+struct
+netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto,
+                                             netconn_callback callback);
+err_t   netconn_delete(struct netconn *conn);
+/** Get the type of a netconn (as enum netconn_type). */
+#define netconn_type(conn) (conn->type)
+
+err_t   netconn_getaddr(struct netconn *conn, ip_addr_t *addr,
+                        u16_t *port, u8_t local);
+#define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0)
+#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1)
+
+err_t   netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port);
+err_t   netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port);
+err_t   netconn_disconnect (struct netconn *conn);
+err_t   netconn_listen_with_backlog(struct netconn *conn, u8_t backlog);
+#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG)
+err_t   netconn_accept(struct netconn *conn, struct netconn **new_conn);
+err_t   netconn_recv(struct netconn *conn, struct netbuf **new_buf);
+err_t   netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf);
+void    netconn_recved(struct netconn *conn, u32_t length);
+err_t   netconn_sendto(struct netconn *conn, struct netbuf *buf,
+                       ip_addr_t *addr, u16_t port);
+err_t   netconn_send(struct netconn *conn, struct netbuf *buf);
+err_t   netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
+                             u8_t apiflags, size_t *bytes_written);
+#define netconn_write(conn, dataptr, size, apiflags) \
+          netconn_write_partly(conn, dataptr, size, apiflags, NULL)
+err_t   netconn_close(struct netconn *conn);
+err_t   netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx);
+
+#if LWIP_IGMP
+err_t   netconn_join_leave_group(struct netconn *conn, ip_addr_t *multiaddr,
+                                 ip_addr_t *netif_addr, enum netconn_igmp join_or_leave);
+#endif /* LWIP_IGMP */
+#if LWIP_DNS
+err_t   netconn_gethostbyname(const char *name, ip_addr_t *addr);
+#endif /* LWIP_DNS */
+
+#define netconn_err(conn)               ((conn)->last_err)
+#define netconn_recv_bufsize(conn)      ((conn)->recv_bufsize)
+
+/** Set the blocking status of netconn calls (@todo: write/send is missing) */
+#define netconn_set_nonblocking(conn, val)  do { if(val) { \
+  (conn)->flags |= NETCONN_FLAG_NON_BLOCKING; \
+} else { \
+  (conn)->flags &= ~ NETCONN_FLAG_NON_BLOCKING; }} while(0)
+/** Get the blocking status of netconn calls (@todo: write/send is missing) */
+#define netconn_is_nonblocking(conn)        (((conn)->flags & NETCONN_FLAG_NON_BLOCKING) != 0)
+
+/** TCP: Set the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */
+#define netconn_set_noautorecved(conn, val)  do { if(val) { \
+  (conn)->flags |= NETCONN_FLAG_NO_AUTO_RECVED; \
+} else { \
+  (conn)->flags &= ~ NETCONN_FLAG_NO_AUTO_RECVED; }} while(0)
+/** TCP: Get the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */
+#define netconn_get_noautorecved(conn)        (((conn)->flags & NETCONN_FLAG_NO_AUTO_RECVED) != 0)
+
+#if LWIP_SO_SNDTIMEO
+/** Set the send timeout in milliseconds */
+#define netconn_set_sendtimeout(conn, timeout)      ((conn)->send_timeout = (timeout))
+/** Get the send timeout in milliseconds */
+#define netconn_get_sendtimeout(conn)               ((conn)->send_timeout)
+#endif /* LWIP_SO_SNDTIMEO */
+#if LWIP_SO_RCVTIMEO
+/** Set the receive timeout in milliseconds */
+#define netconn_set_recvtimeout(conn, timeout)      ((conn)->recv_timeout = (timeout))
+/** Get the receive timeout in milliseconds */
+#define netconn_get_recvtimeout(conn)               ((conn)->recv_timeout)
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+/** Set the receive buffer in bytes */
+#define netconn_set_recvbufsize(conn, recvbufsize)  ((conn)->recv_bufsize = (recvbufsize))
+/** Get the receive buffer in bytes */
+#define netconn_get_recvbufsize(conn)               ((conn)->recv_bufsize)
+#endif /* LWIP_SO_RCVBUF*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_NETCONN */
+
+#endif /* __LWIP_API_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/api_msg.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/api_msg.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/api_msg.h	(revision 164)
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_API_MSG_H__
+#define __LWIP_API_MSG_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
+
+#include <stddef.h> /* for size_t */
+
+#include "lwip/ip_addr.h"
+#include "lwip/err.h"
+#include "lwip/sys.h"
+#include "lwip/igmp.h"
+#include "lwip/api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For the netconn API, these values are use as a bitmask! */
+#define NETCONN_SHUT_RD   1
+#define NETCONN_SHUT_WR   2
+#define NETCONN_SHUT_RDWR (NETCONN_SHUT_RD | NETCONN_SHUT_WR)
+
+/* IP addresses and port numbers are expected to be in
+ * the same byte order as in the corresponding pcb.
+ */
+/** This struct includes everything that is necessary to execute a function
+    for a netconn in another thread context (mainly used to process netconns
+    in the tcpip_thread context to be thread safe). */
+struct api_msg_msg {
+  /** The netconn which to process - always needed: it includes the semaphore
+      which is used to block the application thread until the function finished. */
+  struct netconn *conn;
+  /** The return value of the function executed in tcpip_thread. */
+  err_t err;
+  /** Depending on the executed function, one of these union members is used */
+  union {
+    /** used for do_send */
+    struct netbuf *b;
+    /** used for do_newconn */
+    struct {
+      u8_t proto;
+    } n;
+    /** used for do_bind and do_connect */
+    struct {
+      ip_addr_t *ipaddr;
+      u16_t port;
+    } bc;
+    /** used for do_getaddr */
+    struct {
+      ip_addr_t *ipaddr;
+      u16_t *port;
+      u8_t local;
+    } ad;
+    /** used for do_write */
+    struct {
+      const void *dataptr;
+      size_t len;
+      u8_t apiflags;
+#if LWIP_SO_SNDTIMEO
+      u32_t time_started;
+#endif /* LWIP_SO_SNDTIMEO */
+    } w;
+    /** used for do_recv */
+    struct {
+      u32_t len;
+    } r;
+    /** used for do_close (/shutdown) */
+    struct {
+      u8_t shut;
+    } sd;
+#if LWIP_IGMP
+    /** used for do_join_leave_group */
+    struct {
+      ip_addr_t *multiaddr;
+      ip_addr_t *netif_addr;
+      enum netconn_igmp join_or_leave;
+    } jl;
+#endif /* LWIP_IGMP */
+#if TCP_LISTEN_BACKLOG
+    struct {
+      u8_t backlog;
+    } lb;
+#endif /* TCP_LISTEN_BACKLOG */
+  } msg;
+};
+
+/** This struct contains a function to execute in another thread context and
+    a struct api_msg_msg that serves as an argument for this function.
+    This is passed to tcpip_apimsg to execute functions in tcpip_thread context. */
+struct api_msg {
+  /** function to execute in tcpip_thread context */
+  void (* function)(struct api_msg_msg *msg);
+  /** arguments for this function */
+  struct api_msg_msg msg;
+};
+
+#if LWIP_DNS
+/** As do_gethostbyname requires more arguments but doesn't require a netconn,
+    it has its own struct (to avoid struct api_msg getting bigger than necessary).
+    do_gethostbyname must be called using tcpip_callback instead of tcpip_apimsg
+    (see netconn_gethostbyname). */
+struct dns_api_msg {
+  /** Hostname to query or dotted IP address string */
+  const char *name;
+  /** Rhe resolved address is stored here */
+  ip_addr_t *addr;
+  /** This semaphore is posted when the name is resolved, the application thread
+      should wait on it. */
+  sys_sem_t *sem;
+  /** Errors are given back here */
+  err_t *err;
+};
+#endif /* LWIP_DNS */
+
+void do_newconn         ( struct api_msg_msg *msg);
+void do_delconn         ( struct api_msg_msg *msg);
+void do_bind            ( struct api_msg_msg *msg);
+void do_connect         ( struct api_msg_msg *msg);
+void do_disconnect      ( struct api_msg_msg *msg);
+void do_listen          ( struct api_msg_msg *msg);
+void do_send            ( struct api_msg_msg *msg);
+void do_recv            ( struct api_msg_msg *msg);
+void do_write           ( struct api_msg_msg *msg);
+void do_getaddr         ( struct api_msg_msg *msg);
+void do_close           ( struct api_msg_msg *msg);
+void do_shutdown        ( struct api_msg_msg *msg);
+#if LWIP_IGMP
+void do_join_leave_group( struct api_msg_msg *msg);
+#endif /* LWIP_IGMP */
+
+#if LWIP_DNS
+void do_gethostbyname(void *arg);
+#endif /* LWIP_DNS */
+
+struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback);
+void netconn_free(struct netconn *conn);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_NETCONN */
+
+#endif /* __LWIP_API_MSG_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/arch.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/arch.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/arch.h	(revision 164)
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_ARCH_H__
+#define __LWIP_ARCH_H__
+
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 1234
+#endif
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 4321
+#endif
+
+#include "arch/cc.h"
+
+/** Temporary: define format string for size_t if not defined in cc.h */
+#ifndef SZT_F
+#define SZT_F U32_F
+#endif /* SZT_F */
+/** Temporary upgrade helper: define format string for u8_t as hex if not
+    defined in cc.h */
+#ifndef X8_F
+#define X8_F  "02x"
+#endif /* X8_F */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef PACK_STRUCT_BEGIN
+#define PACK_STRUCT_BEGIN
+#endif /* PACK_STRUCT_BEGIN */
+
+#ifndef PACK_STRUCT_END
+#define PACK_STRUCT_END
+#endif /* PACK_STRUCT_END */
+
+#ifndef PACK_STRUCT_FIELD
+#define PACK_STRUCT_FIELD(x) x
+#endif /* PACK_STRUCT_FIELD */
+
+
+#ifndef LWIP_UNUSED_ARG
+#define LWIP_UNUSED_ARG(x) (void)x
+#endif /* LWIP_UNUSED_ARG */ 
+
+
+#ifdef LWIP_PROVIDE_ERRNO
+
+#define  EPERM         1  /* Operation not permitted */
+#define  ENOENT        2  /* No such file or directory */
+#define  ESRCH         3  /* No such process */
+#define  EINTR         4  /* Interrupted system call */
+#define  EIO           5  /* I/O error */
+#define  ENXIO         6  /* No such device or address */
+#define  E2BIG         7  /* Arg list too long */
+#define  ENOEXEC       8  /* Exec format error */
+#define  EBADF         9  /* Bad file number */
+#define  ECHILD       10  /* No child processes */
+#define  EAGAIN       11  /* Try again */
+#define  ENOMEM       12  /* Out of memory */
+#define  EACCES       13  /* Permission denied */
+#define  EFAULT       14  /* Bad address */
+#define  ENOTBLK      15  /* Block device required */
+#define  EBUSY        16  /* Device or resource busy */
+#define  EEXIST       17  /* File exists */
+#define  EXDEV        18  /* Cross-device link */
+#define  ENODEV       19  /* No such device */
+#define  ENOTDIR      20  /* Not a directory */
+#define  EISDIR       21  /* Is a directory */
+#define  EINVAL       22  /* Invalid argument */
+#define  ENFILE       23  /* File table overflow */
+#define  EMFILE       24  /* Too many open files */
+#define  ENOTTY       25  /* Not a typewriter */
+#define  ETXTBSY      26  /* Text file busy */
+#define  EFBIG        27  /* File too large */
+#define  ENOSPC       28  /* No space left on device */
+#define  ESPIPE       29  /* Illegal seek */
+#define  EROFS        30  /* Read-only file system */
+#define  EMLINK       31  /* Too many links */
+#define  EPIPE        32  /* Broken pipe */
+#define  EDOM         33  /* Math argument out of domain of func */
+#define  ERANGE       34  /* Math result not representable */
+#define  EDEADLK      35  /* Resource deadlock would occur */
+#define  ENAMETOOLONG 36  /* File name too long */
+#define  ENOLCK       37  /* No record locks available */
+#define  ENOSYS       38  /* Function not implemented */
+#define  ENOTEMPTY    39  /* Directory not empty */
+#define  ELOOP        40  /* Too many symbolic links encountered */
+#define  EWOULDBLOCK  EAGAIN  /* Operation would block */
+#define  ENOMSG       42  /* No message of desired type */
+#define  EIDRM        43  /* Identifier removed */
+#define  ECHRNG       44  /* Channel number out of range */
+#define  EL2NSYNC     45  /* Level 2 not synchronized */
+#define  EL3HLT       46  /* Level 3 halted */
+#define  EL3RST       47  /* Level 3 reset */
+#define  ELNRNG       48  /* Link number out of range */
+#define  EUNATCH      49  /* Protocol driver not attached */
+#define  ENOCSI       50  /* No CSI structure available */
+#define  EL2HLT       51  /* Level 2 halted */
+#define  EBADE        52  /* Invalid exchange */
+#define  EBADR        53  /* Invalid request descriptor */
+#define  EXFULL       54  /* Exchange full */
+#define  ENOANO       55  /* No anode */
+#define  EBADRQC      56  /* Invalid request code */
+#define  EBADSLT      57  /* Invalid slot */
+
+#define  EDEADLOCK    EDEADLK
+
+#define  EBFONT       59  /* Bad font file format */
+#define  ENOSTR       60  /* Device not a stream */
+#define  ENODATA      61  /* No data available */
+#define  ETIME        62  /* Timer expired */
+#define  ENOSR        63  /* Out of streams resources */
+#define  ENONET       64  /* Machine is not on the network */
+#define  ENOPKG       65  /* Package not installed */
+#define  EREMOTE      66  /* Object is remote */
+#define  ENOLINK      67  /* Link has been severed */
+#define  EADV         68  /* Advertise error */
+#define  ESRMNT       69  /* Srmount error */
+#define  ECOMM        70  /* Communication error on send */
+#define  EPROTO       71  /* Protocol error */
+#define  EMULTIHOP    72  /* Multihop attempted */
+#define  EDOTDOT      73  /* RFS specific error */
+#define  EBADMSG      74  /* Not a data message */
+#define  EOVERFLOW    75  /* Value too large for defined data type */
+#define  ENOTUNIQ     76  /* Name not unique on network */
+#define  EBADFD       77  /* File descriptor in bad state */
+#define  EREMCHG      78  /* Remote address changed */
+#define  ELIBACC      79  /* Can not access a needed shared library */
+#define  ELIBBAD      80  /* Accessing a corrupted shared library */
+#define  ELIBSCN      81  /* .lib section in a.out corrupted */
+#define  ELIBMAX      82  /* Attempting to link in too many shared libraries */
+#define  ELIBEXEC     83  /* Cannot exec a shared library directly */
+#define  EILSEQ       84  /* Illegal byte sequence */
+#define  ERESTART     85  /* Interrupted system call should be restarted */
+#define  ESTRPIPE     86  /* Streams pipe error */
+#define  EUSERS       87  /* Too many users */
+#define  ENOTSOCK     88  /* Socket operation on non-socket */
+#define  EDESTADDRREQ 89  /* Destination address required */
+#define  EMSGSIZE     90  /* Message too long */
+#define  EPROTOTYPE   91  /* Protocol wrong type for socket */
+#define  ENOPROTOOPT  92  /* Protocol not available */
+#define  EPROTONOSUPPORT 93  /* Protocol not supported */
+#define  ESOCKTNOSUPPORT 94  /* Socket type not supported */
+#define  EOPNOTSUPP      95  /* Operation not supported on transport endpoint */
+#define  EPFNOSUPPORT    96  /* Protocol family not supported */
+#define  EAFNOSUPPORT    97  /* Address family not supported by protocol */
+#define  EADDRINUSE      98  /* Address already in use */
+#define  EADDRNOTAVAIL   99  /* Cannot assign requested address */
+#define  ENETDOWN       100  /* Network is down */
+#define  ENETUNREACH    101  /* Network is unreachable */
+#define  ENETRESET      102  /* Network dropped connection because of reset */
+#define  ECONNABORTED   103  /* Software caused connection abort */
+#define  ECONNRESET     104  /* Connection reset by peer */
+#define  ENOBUFS        105  /* No buffer space available */
+#define  EISCONN        106  /* Transport endpoint is already connected */
+#define  ENOTCONN       107  /* Transport endpoint is not connected */
+#define  ESHUTDOWN      108  /* Cannot send after transport endpoint shutdown */
+#define  ETOOMANYREFS   109  /* Too many references: cannot splice */
+#define  ETIMEDOUT      110  /* Connection timed out */
+#define  ECONNREFUSED   111  /* Connection refused */
+#define  EHOSTDOWN      112  /* Host is down */
+#define  EHOSTUNREACH   113  /* No route to host */
+#define  EALREADY       114  /* Operation already in progress */
+#define  EINPROGRESS    115  /* Operation now in progress */
+#define  ESTALE         116  /* Stale NFS file handle */
+#define  EUCLEAN        117  /* Structure needs cleaning */
+#define  ENOTNAM        118  /* Not a XENIX named type file */
+#define  ENAVAIL        119  /* No XENIX semaphores available */
+#define  EISNAM         120  /* Is a named type file */
+#define  EREMOTEIO      121  /* Remote I/O error */
+#define  EDQUOT         122  /* Quota exceeded */
+
+#define  ENOMEDIUM      123  /* No medium found */
+#define  EMEDIUMTYPE    124  /* Wrong medium type */
+
+#ifndef errno
+extern int errno;
+#endif
+
+#endif /* LWIP_PROVIDE_ERRNO */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_ARCH_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/debug.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/debug.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/debug.h	(revision 164)
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_DEBUG_H__
+#define __LWIP_DEBUG_H__
+
+#include "lwip/arch.h"
+#include "lwip/opt.h"
+
+/** lower two bits indicate debug level
+ * - 0 all
+ * - 1 warning
+ * - 2 serious
+ * - 3 severe
+ */
+#define LWIP_DBG_LEVEL_ALL     0x00
+#define LWIP_DBG_LEVEL_OFF     LWIP_DBG_LEVEL_ALL /* compatibility define only */
+#define LWIP_DBG_LEVEL_WARNING 0x01 /* bad checksums, dropped packets, ... */
+#define LWIP_DBG_LEVEL_SERIOUS 0x02 /* memory allocation failures, ... */
+#define LWIP_DBG_LEVEL_SEVERE  0x03
+#define LWIP_DBG_MASK_LEVEL    0x03
+
+/** flag for LWIP_DEBUGF to enable that debug message */
+#define LWIP_DBG_ON            0x80U
+/** flag for LWIP_DEBUGF to disable that debug message */
+#define LWIP_DBG_OFF           0x00U
+
+/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */
+#define LWIP_DBG_TRACE         0x40U
+/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */
+#define LWIP_DBG_STATE         0x20U
+/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */
+#define LWIP_DBG_FRESH         0x10U
+/** flag for LWIP_DEBUGF to halt after printing this debug message */
+#define LWIP_DBG_HALT          0x08U
+
+#ifndef LWIP_NOASSERT
+#define LWIP_ASSERT(message, assertion) do { if(!(assertion)) \
+  LWIP_PLATFORM_ASSERT(message); } while(0)
+#else  /* LWIP_NOASSERT */
+#define LWIP_ASSERT(message, assertion) 
+#endif /* LWIP_NOASSERT */
+
+/** if "expression" isn't true, then print "message" and execute "handler" expression */
+#ifndef LWIP_ERROR
+#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
+  LWIP_PLATFORM_ASSERT(message); handler;}} while(0)
+#endif /* LWIP_ERROR */
+
+#ifdef LWIP_DEBUG
+/** print debug message only if debug message type is enabled...
+ *  AND is of correct type AND is at least LWIP_DBG_LEVEL
+ */
+#define LWIP_DEBUGF(debug, message) do { \
+                               if ( \
+                                   ((debug) & LWIP_DBG_ON) && \
+                                   ((debug) & LWIP_DBG_TYPES_ON) && \
+                                   ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \
+                                 LWIP_PLATFORM_DIAG(message); \
+                                 if ((debug) & LWIP_DBG_HALT) { \
+                                   while(1); \
+                                 } \
+                               } \
+                             } while(0)
+
+#else  /* LWIP_DEBUG */
+#define LWIP_DEBUGF(debug, message) 
+#endif /* LWIP_DEBUG */
+
+#endif /* __LWIP_DEBUG_H__ */
+
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/def.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/def.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/def.h	(revision 164)
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_DEF_H__
+#define __LWIP_DEF_H__
+
+/* arch.h might define NULL already */
+#include "lwip/arch.h"
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LWIP_MAX(x , y)  (((x) > (y)) ? (x) : (y))
+#define LWIP_MIN(x , y)  (((x) < (y)) ? (x) : (y))
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+/* Endianess-optimized shifting of two u8_t to create one u16_t */
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define LWIP_MAKE_U16(a, b) ((a << 8) | b)
+#else
+#define LWIP_MAKE_U16(a, b) ((b << 8) | a)
+#endif 
+
+#ifndef LWIP_PLATFORM_BYTESWAP
+#define LWIP_PLATFORM_BYTESWAP 0
+#endif
+
+#ifndef LWIP_PREFIX_BYTEORDER_FUNCS
+/* workaround for naming collisions on some platforms */
+
+#ifdef htons
+#undef htons
+#endif /* htons */
+#ifdef htonl
+#undef htonl
+#endif /* htonl */
+#ifdef ntohs
+#undef ntohs
+#endif /* ntohs */
+#ifdef ntohl
+#undef ntohl
+#endif /* ntohl */
+
+#define htons(x) lwip_htons(x)
+#define ntohs(x) lwip_ntohs(x)
+#define htonl(x) lwip_htonl(x)
+#define ntohl(x) lwip_ntohl(x)
+#endif /* LWIP_PREFIX_BYTEORDER_FUNCS */
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define lwip_htons(x) (x)
+#define lwip_ntohs(x) (x)
+#define lwip_htonl(x) (x)
+#define lwip_ntohl(x) (x)
+#define PP_HTONS(x) (x)
+#define PP_NTOHS(x) (x)
+#define PP_HTONL(x) (x)
+#define PP_NTOHL(x) (x)
+#else /* BYTE_ORDER != BIG_ENDIAN */
+#if LWIP_PLATFORM_BYTESWAP
+#define lwip_htons(x) LWIP_PLATFORM_HTONS(x)
+#define lwip_ntohs(x) LWIP_PLATFORM_HTONS(x)
+#define lwip_htonl(x) LWIP_PLATFORM_HTONL(x)
+#define lwip_ntohl(x) LWIP_PLATFORM_HTONL(x)
+#else /* LWIP_PLATFORM_BYTESWAP */
+u16_t lwip_htons(u16_t x);
+u16_t lwip_ntohs(u16_t x);
+u32_t lwip_htonl(u32_t x);
+u32_t lwip_ntohl(u32_t x);
+#endif /* LWIP_PLATFORM_BYTESWAP */
+
+/* These macros should be calculated by the preprocessor and are used
+   with compile-time constants only (so that there is no little-endian
+   overhead at runtime). */
+#define PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
+#define PP_NTOHS(x) PP_HTONS(x)
+#define PP_HTONL(x) ((((x) & 0xff) << 24) | \
+                     (((x) & 0xff00) << 8) | \
+                     (((x) & 0xff0000UL) >> 8) | \
+                     (((x) & 0xff000000UL) >> 24))
+#define PP_NTOHL(x) PP_HTONL(x)
+
+#endif /* BYTE_ORDER == BIG_ENDIAN */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_DEF_H__ */
+
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/dhcp.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/dhcp.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/dhcp.h	(revision 164)
@@ -0,0 +1,242 @@
+/** @file
+ */
+
+#ifndef __LWIP_DHCP_H__
+#define __LWIP_DHCP_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/netif.h"
+#include "lwip/udp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** period (in seconds) of the application calling dhcp_coarse_tmr() */
+#define DHCP_COARSE_TIMER_SECS 60 
+/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */
+#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL)
+/** period (in milliseconds) of the application calling dhcp_fine_tmr() */
+#define DHCP_FINE_TIMER_MSECS 500 
+
+#define DHCP_CHADDR_LEN 16U
+#define DHCP_SNAME_LEN  64U
+#define DHCP_FILE_LEN   128U
+
+struct dhcp
+{
+  /** transaction identifier of last sent request */ 
+  u32_t xid;
+  /** our connection to the DHCP server */ 
+  struct udp_pcb *pcb;
+  /** incoming msg */
+  struct dhcp_msg *msg_in;
+  /** current DHCP state machine state */
+  u8_t state;
+  /** retries of current request */
+  u8_t tries;
+#if LWIP_DHCP_AUTOIP_COOP
+  u8_t autoip_coop_state;
+#endif
+  u8_t subnet_mask_given;
+
+  struct pbuf *p_out; /* pbuf of outcoming msg */
+  struct dhcp_msg *msg_out; /* outgoing msg */
+  u16_t options_out_len; /* outgoing msg options length */
+  u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */
+  u16_t t1_timeout;  /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */
+  u16_t t2_timeout;  /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */
+  ip_addr_t server_ip_addr; /* dhcp server address that offered this lease */
+  ip_addr_t offered_ip_addr;
+  ip_addr_t offered_sn_mask;
+  ip_addr_t offered_gw_addr;
+ 
+  u32_t offered_t0_lease; /* lease period (in seconds) */
+  u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */
+  u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period)  */
+  /* @todo: LWIP_DHCP_BOOTP_FILE configuration option?
+     integrate with possible TFTP-client for booting? */
+#if LWIP_DHCP_BOOTP_FILE
+  ip_addr_t offered_si_addr;
+  char boot_file_name[DHCP_FILE_LEN];
+#endif /* LWIP_DHCP_BOOTPFILE */
+};
+
+/* MUST be compiled with "pack structs" or equivalent! */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+/** minimum set of fields of any DHCP message */
+struct dhcp_msg
+{
+  PACK_STRUCT_FIELD(u8_t op);
+  PACK_STRUCT_FIELD(u8_t htype);
+  PACK_STRUCT_FIELD(u8_t hlen);
+  PACK_STRUCT_FIELD(u8_t hops);
+  PACK_STRUCT_FIELD(u32_t xid);
+  PACK_STRUCT_FIELD(u16_t secs);
+  PACK_STRUCT_FIELD(u16_t flags);
+  PACK_STRUCT_FIELD(ip_addr_p_t ciaddr);
+  PACK_STRUCT_FIELD(ip_addr_p_t yiaddr);
+  PACK_STRUCT_FIELD(ip_addr_p_t siaddr);
+  PACK_STRUCT_FIELD(ip_addr_p_t giaddr);
+  PACK_STRUCT_FIELD(u8_t chaddr[DHCP_CHADDR_LEN]);
+  PACK_STRUCT_FIELD(u8_t sname[DHCP_SNAME_LEN]);
+  PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]);
+  PACK_STRUCT_FIELD(u32_t cookie);
+#define DHCP_MIN_OPTIONS_LEN 68U
+/** make sure user does not configure this too small */
+#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN))
+#  undef DHCP_OPTIONS_LEN
+#endif
+/** allow this to be configured in lwipopts.h, but not too small */
+#if (!defined(DHCP_OPTIONS_LEN))
+/** set this to be sufficient for your options in outgoing DHCP msgs */
+#  define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN
+#endif
+  PACK_STRUCT_FIELD(u8_t options[DHCP_OPTIONS_LEN]);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp);
+/** Remove a struct dhcp previously set to the netif using dhcp_set_struct() */
+#define dhcp_remove_struct(netif) do { (netif)->dhcp = NULL; } while(0)
+void dhcp_cleanup(struct netif *netif);
+/** start DHCP configuration */
+err_t dhcp_start(struct netif *netif);
+/** enforce early lease renewal (not needed normally)*/
+err_t dhcp_renew(struct netif *netif);
+/** release the DHCP lease, usually called before dhcp_stop()*/
+err_t dhcp_release(struct netif *netif);
+/** stop DHCP configuration */
+void dhcp_stop(struct netif *netif);
+/** inform server of our manual IP address */
+void dhcp_inform(struct netif *netif);
+/** Handle a possible change in the network configuration */
+void dhcp_network_changed(struct netif *netif);
+
+/** if enabled, check whether the offered IP address is not in use, using ARP */
+#if DHCP_DOES_ARP_CHECK
+void dhcp_arp_reply(struct netif *netif, ip_addr_t *addr);
+#endif
+
+/** to be called every minute */
+void dhcp_coarse_tmr(void);
+/** to be called every half second */
+void dhcp_fine_tmr(void);
+ 
+/** DHCP message item offsets and length */
+#define DHCP_OP_OFS       0
+#define DHCP_HTYPE_OFS    1
+#define DHCP_HLEN_OFS     2
+#define DHCP_HOPS_OFS     3
+#define DHCP_XID_OFS      4
+#define DHCP_SECS_OFS     8
+#define DHCP_FLAGS_OFS    10
+#define DHCP_CIADDR_OFS   12
+#define DHCP_YIADDR_OFS   16
+#define DHCP_SIADDR_OFS   20
+#define DHCP_GIADDR_OFS   24
+#define DHCP_CHADDR_OFS   28
+#define DHCP_SNAME_OFS    44
+#define DHCP_FILE_OFS     108
+#define DHCP_MSG_LEN      236
+
+#define DHCP_COOKIE_OFS   DHCP_MSG_LEN
+#define DHCP_OPTIONS_OFS  (DHCP_MSG_LEN + 4)
+
+#define DHCP_CLIENT_PORT  68  
+#define DHCP_SERVER_PORT  67
+
+/** DHCP client states */
+#define DHCP_OFF          0
+#define DHCP_REQUESTING   1
+#define DHCP_INIT         2
+#define DHCP_REBOOTING    3
+#define DHCP_REBINDING    4
+#define DHCP_RENEWING     5
+#define DHCP_SELECTING    6
+#define DHCP_INFORMING    7
+#define DHCP_CHECKING     8
+#define DHCP_PERMANENT    9
+#define DHCP_BOUND        10
+/** not yet implemented #define DHCP_RELEASING 11 */
+#define DHCP_BACKING_OFF  12
+
+/** AUTOIP cooperatation flags */
+#define DHCP_AUTOIP_COOP_STATE_OFF  0
+#define DHCP_AUTOIP_COOP_STATE_ON   1
+ 
+#define DHCP_BOOTREQUEST  1
+#define DHCP_BOOTREPLY    2
+
+/** DHCP message types */
+#define DHCP_DISCOVER 1
+#define DHCP_OFFER    2
+#define DHCP_REQUEST  3
+#define DHCP_DECLINE  4
+#define DHCP_ACK      5
+#define DHCP_NAK      6
+#define DHCP_RELEASE  7
+#define DHCP_INFORM   8
+
+/** DHCP hardware type, currently only ethernet is supported */
+#define DHCP_HTYPE_ETH 1
+
+#define DHCP_MAGIC_COOKIE 0x63825363UL
+
+/* This is a list of options for BOOTP and DHCP, see RFC 2132 for descriptions */
+
+/** BootP options */
+#define DHCP_OPTION_PAD 0
+#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */
+#define DHCP_OPTION_ROUTER 3
+#define DHCP_OPTION_DNS_SERVER 6 
+#define DHCP_OPTION_HOSTNAME 12
+#define DHCP_OPTION_IP_TTL 23
+#define DHCP_OPTION_MTU 26
+#define DHCP_OPTION_BROADCAST 28
+#define DHCP_OPTION_TCP_TTL 37
+#define DHCP_OPTION_END 255
+
+/** DHCP options */
+#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */
+#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */
+#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */
+
+#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */
+#define DHCP_OPTION_MESSAGE_TYPE_LEN 1
+
+#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */
+#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */
+
+#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */
+#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2
+
+#define DHCP_OPTION_T1 58 /* T1 renewal time */
+#define DHCP_OPTION_T2 59 /* T2 rebinding time */
+#define DHCP_OPTION_US 60
+#define DHCP_OPTION_CLIENT_ID 61
+#define DHCP_OPTION_TFTP_SERVERNAME 66
+#define DHCP_OPTION_BOOTFILE 67
+
+/** possible combinations of overloading the file and sname fields with options */
+#define DHCP_OVERLOAD_NONE 0
+#define DHCP_OVERLOAD_FILE 1
+#define DHCP_OVERLOAD_SNAME  2
+#define DHCP_OVERLOAD_SNAME_FILE 3
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_DHCP */
+
+#endif /*__LWIP_DHCP_H__*/
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/dns.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/dns.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/dns.h	(revision 164)
@@ -0,0 +1,124 @@
+/**
+ * lwip DNS resolver header file.
+
+ * Author: Jim Pettinato 
+ *   April 2007
+
+ * ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __LWIP_DNS_H__
+#define __LWIP_DNS_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** DNS timer period */
+#define DNS_TMR_INTERVAL          1000
+
+/** DNS field TYPE used for "Resource Records" */
+#define DNS_RRTYPE_A              1     /* a host address */
+#define DNS_RRTYPE_NS             2     /* an authoritative name server */
+#define DNS_RRTYPE_MD             3     /* a mail destination (Obsolete - use MX) */
+#define DNS_RRTYPE_MF             4     /* a mail forwarder (Obsolete - use MX) */
+#define DNS_RRTYPE_CNAME          5     /* the canonical name for an alias */
+#define DNS_RRTYPE_SOA            6     /* marks the start of a zone of authority */
+#define DNS_RRTYPE_MB             7     /* a mailbox domain name (EXPERIMENTAL) */
+#define DNS_RRTYPE_MG             8     /* a mail group member (EXPERIMENTAL) */
+#define DNS_RRTYPE_MR             9     /* a mail rename domain name (EXPERIMENTAL) */
+#define DNS_RRTYPE_NULL           10    /* a null RR (EXPERIMENTAL) */
+#define DNS_RRTYPE_WKS            11    /* a well known service description */
+#define DNS_RRTYPE_PTR            12    /* a domain name pointer */
+#define DNS_RRTYPE_HINFO          13    /* host information */
+#define DNS_RRTYPE_MINFO          14    /* mailbox or mail list information */
+#define DNS_RRTYPE_MX             15    /* mail exchange */
+#define DNS_RRTYPE_TXT            16    /* text strings */
+
+/** DNS field CLASS used for "Resource Records" */
+#define DNS_RRCLASS_IN            1     /* the Internet */
+#define DNS_RRCLASS_CS            2     /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
+#define DNS_RRCLASS_CH            3     /* the CHAOS class */
+#define DNS_RRCLASS_HS            4     /* Hesiod [Dyer 87] */
+#define DNS_RRCLASS_FLUSH         0x800 /* Flush bit */
+
+/* The size used for the next line is rather a hack, but it prevents including socket.h in all files
+   that include memp.h, and that would possibly break portability (since socket.h defines some types
+   and constants possibly already define by the OS).
+   Calculation rule:
+   sizeof(struct addrinfo) + sizeof(struct sockaddr_in) + DNS_MAX_NAME_LENGTH + 1 byte zero-termination */
+#define NETDB_ELEM_SIZE           (32 + 16 + DNS_MAX_NAME_LENGTH + 1)
+
+#if DNS_LOCAL_HOSTLIST
+/** struct used for local host-list */
+struct local_hostlist_entry {
+  /** static hostname */
+  const char *name;
+  /** static host address in network byteorder */
+  ip_addr_t addr;
+  struct local_hostlist_entry *next;
+};
+#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
+#ifndef DNS_LOCAL_HOSTLIST_MAX_NAMELEN
+#define DNS_LOCAL_HOSTLIST_MAX_NAMELEN  DNS_MAX_NAME_LENGTH
+#endif
+#define LOCALHOSTLIST_ELEM_SIZE ((sizeof(struct local_hostlist_entry) + DNS_LOCAL_HOSTLIST_MAX_NAMELEN + 1))
+#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+#endif /* DNS_LOCAL_HOSTLIST */
+
+/** Callback which is invoked when a hostname is found.
+ * A function of this type must be implemented by the application using the DNS resolver.
+ * @param name pointer to the name that was looked up.
+ * @param ipaddr pointer to an ip_addr_t containing the IP address of the hostname,
+ *        or NULL if the name could not be found (or on any other error).
+ * @param callback_arg a user-specified callback argument passed to dns_gethostbyname
+*/
+typedef void (*dns_found_callback)(const char *name, ip_addr_t *ipaddr, void *callback_arg);
+
+void           dns_init(void);
+void           dns_tmr(void);
+void           dns_setserver(u8_t numdns, ip_addr_t *dnsserver);
+ip_addr_t      dns_getserver(u8_t numdns);
+err_t          dns_gethostbyname(const char *hostname, ip_addr_t *addr,
+                                 dns_found_callback found, void *callback_arg);
+
+#if DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC
+int            dns_local_removehost(const char *hostname, const ip_addr_t *addr);
+err_t          dns_local_addhost(const char *hostname, const ip_addr_t *addr);
+#endif /* DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_DNS */
+
+#endif /* __LWIP_DNS_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/err.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/err.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/err.h	(revision 164)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_ERR_H__
+#define __LWIP_ERR_H__
+
+#include "lwip/opt.h"
+#include "lwip/arch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Define LWIP_ERR_T in cc.h if you want to use
+ *  a different type for your platform (must be signed). */
+#ifdef LWIP_ERR_T
+typedef LWIP_ERR_T err_t;
+#else /* LWIP_ERR_T */
+typedef s8_t err_t;
+#endif /* LWIP_ERR_T*/
+
+/* Definitions for error constants. */
+
+#define ERR_OK          0    /* No error, everything OK. */
+#define ERR_MEM        -1    /* Out of memory error.     */
+#define ERR_BUF        -2    /* Buffer error.            */
+#define ERR_TIMEOUT    -3    /* Timeout.                 */
+#define ERR_RTE        -4    /* Routing problem.         */
+#define ERR_INPROGRESS -5    /* Operation in progress    */
+#define ERR_VAL        -6    /* Illegal value.           */
+#define ERR_WOULDBLOCK -7    /* Operation would block.   */
+#define ERR_USE        -8    /* Address in use.          */
+#define ERR_ISCONN     -9    /* Already connected.       */
+
+#define ERR_IS_FATAL(e) ((e) < ERR_ISCONN)
+
+#define ERR_ABRT       -10   /* Connection aborted.      */
+#define ERR_RST        -11   /* Connection reset.        */
+#define ERR_CLSD       -12   /* Connection closed.       */
+#define ERR_CONN       -13   /* Not connected.           */
+
+#define ERR_ARG        -14   /* Illegal argument.        */
+
+#define ERR_IF         -15   /* Low-level netif error    */
+
+
+#ifdef LWIP_DEBUG
+extern const char *lwip_strerr(err_t err);
+#else
+#define lwip_strerr(x) ""
+#endif /* LWIP_DEBUG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_ERR_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/init.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/init.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/init.h	(revision 164)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_INIT_H__
+#define __LWIP_INIT_H__
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** X.x.x: Major version of the stack */
+#define LWIP_VERSION_MAJOR      1U
+/** x.X.x: Minor version of the stack */
+#define LWIP_VERSION_MINOR      4U
+/** x.x.X: Revision of the stack */
+#define LWIP_VERSION_REVISION   1U
+/** For release candidates, this is set to 1..254
+  * For official releases, this is set to 255 (LWIP_RC_RELEASE)
+  * For development versions (CVS), this is set to 0 (LWIP_RC_DEVELOPMENT) */
+#define LWIP_VERSION_RC         255U
+
+/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */
+#define LWIP_RC_RELEASE         255U
+/** LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for CVS versions */
+#define LWIP_RC_DEVELOPMENT     0U
+
+#define LWIP_VERSION_IS_RELEASE     (LWIP_VERSION_RC == LWIP_RC_RELEASE)
+#define LWIP_VERSION_IS_DEVELOPMENT (LWIP_VERSION_RC == LWIP_RC_DEVELOPMENT)
+#define LWIP_VERSION_IS_RC          ((LWIP_VERSION_RC != LWIP_RC_RELEASE) && (LWIP_VERSION_RC != LWIP_RC_DEVELOPMENT))
+
+/** Provides the version of the stack */
+#define LWIP_VERSION   (LWIP_VERSION_MAJOR << 24   | LWIP_VERSION_MINOR << 16 | \
+                        LWIP_VERSION_REVISION << 8 | LWIP_VERSION_RC)
+
+/* Modules initialization */
+void lwip_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_INIT_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/mem.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/mem.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/mem.h	(revision 164)
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_MEM_H__
+#define __LWIP_MEM_H__
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if MEM_LIBC_MALLOC
+
+#include <stddef.h> /* for size_t */
+
+typedef size_t mem_size_t;
+#define MEM_SIZE_F SZT_F
+
+/* aliases for C library malloc() */
+#define mem_init()
+/* in case C library malloc() needs extra protection,
+ * allow these defines to be overridden.
+ */
+#ifndef mem_free
+#define mem_free free
+#endif
+#ifndef mem_malloc
+#define mem_malloc malloc
+#endif
+#ifndef mem_calloc
+#define mem_calloc calloc
+#endif
+/* Since there is no C library allocation function to shrink memory without
+   moving it, define this to nothing. */
+#ifndef mem_trim
+#define mem_trim(mem, size) (mem)
+#endif
+#else /* MEM_LIBC_MALLOC */
+
+/* MEM_SIZE would have to be aligned, but using 64000 here instead of
+ * 65535 leaves some room for alignment...
+ */
+#if MEM_SIZE > 64000L
+typedef u32_t mem_size_t;
+#define MEM_SIZE_F U32_F
+#else
+typedef u16_t mem_size_t;
+#define MEM_SIZE_F U16_F
+#endif /* MEM_SIZE > 64000 */
+
+#if MEM_USE_POOLS
+/** mem_init is not used when using pools instead of a heap */
+#define mem_init()
+/** mem_trim is not used when using pools instead of a heap:
+    we can't free part of a pool element and don't want to copy the rest */
+#define mem_trim(mem, size) (mem)
+#else /* MEM_USE_POOLS */
+/* lwIP alternative malloc */
+void  mem_init(void);
+void *mem_trim(void *mem, mem_size_t size);
+#endif /* MEM_USE_POOLS */
+void *mem_malloc(mem_size_t size);
+void *mem_calloc(mem_size_t count, mem_size_t size);
+void  mem_free(void *mem);
+#endif /* MEM_LIBC_MALLOC */
+
+/** Calculate memory size for an aligned buffer - returns the next highest
+ * multiple of MEM_ALIGNMENT (e.g. LWIP_MEM_ALIGN_SIZE(3) and
+ * LWIP_MEM_ALIGN_SIZE(4) will both yield 4 for MEM_ALIGNMENT == 4).
+ */
+#ifndef LWIP_MEM_ALIGN_SIZE
+#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1))
+#endif
+
+/** Calculate safe memory size for an aligned buffer when using an unaligned
+ * type as storage. This includes a safety-margin on (MEM_ALIGNMENT - 1) at the
+ * start (e.g. if buffer is u8_t[] and actual data will be u32_t*)
+ */
+#ifndef LWIP_MEM_ALIGN_BUFFER
+#define LWIP_MEM_ALIGN_BUFFER(size) (((size) + MEM_ALIGNMENT - 1))
+#endif
+
+/** Align a memory pointer to the alignment defined by MEM_ALIGNMENT
+ * so that ADDR % MEM_ALIGNMENT == 0
+ */
+#ifndef LWIP_MEM_ALIGN
+#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1)))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_MEM_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/memp.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/memp.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/memp.h	(revision 164)
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __LWIP_MEMP_H__
+#define __LWIP_MEMP_H__
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Create the list of all memory pools managed by memp. MEMP_MAX represents a NULL pool at the end */
+typedef enum {
+#define LWIP_MEMPOOL(name,num,size,desc)  MEMP_##name,
+#include "lwip/memp_std.h"
+  MEMP_MAX
+} memp_t;
+
+#if MEM_USE_POOLS
+/* Use a helper type to get the start and end of the user "memory pools" for mem_malloc */
+typedef enum {
+    /* Get the first (via:
+       MEMP_POOL_HELPER_START = ((u8_t) 1*MEMP_POOL_A + 0*MEMP_POOL_B + 0*MEMP_POOL_C + 0)*/
+    MEMP_POOL_HELPER_FIRST = ((u8_t)
+#define LWIP_MEMPOOL(name,num,size,desc)
+#define LWIP_MALLOC_MEMPOOL_START 1
+#define LWIP_MALLOC_MEMPOOL(num, size) * MEMP_POOL_##size + 0
+#define LWIP_MALLOC_MEMPOOL_END
+#include "lwip/memp_std.h"
+    ) ,
+    /* Get the last (via:
+       MEMP_POOL_HELPER_END = ((u8_t) 0 + MEMP_POOL_A*0 + MEMP_POOL_B*0 + MEMP_POOL_C*1) */
+    MEMP_POOL_HELPER_LAST = ((u8_t)
+#define LWIP_MEMPOOL(name,num,size,desc)
+#define LWIP_MALLOC_MEMPOOL_START
+#define LWIP_MALLOC_MEMPOOL(num, size) 0 + MEMP_POOL_##size *
+#define LWIP_MALLOC_MEMPOOL_END 1
+#include "lwip/memp_std.h"
+    )
+} memp_pool_helper_t;
+
+/* The actual start and stop values are here (cast them over)
+   We use this helper type and these defines so we can avoid using const memp_t values */
+#define MEMP_POOL_FIRST ((memp_t) MEMP_POOL_HELPER_FIRST)
+#define MEMP_POOL_LAST   ((memp_t) MEMP_POOL_HELPER_LAST)
+#endif /* MEM_USE_POOLS */
+
+#if MEMP_MEM_MALLOC || MEM_USE_POOLS
+extern const u16_t memp_sizes[MEMP_MAX];
+#endif /* MEMP_MEM_MALLOC || MEM_USE_POOLS */
+
+#if MEMP_MEM_MALLOC
+
+#include "mem.h"
+
+#define memp_init()
+#define memp_malloc(type)     mem_malloc(memp_sizes[type])
+#define memp_free(type, mem)  mem_free(mem)
+
+#else /* MEMP_MEM_MALLOC */
+
+#if MEM_USE_POOLS
+/** This structure is used to save the pool one element came from. */
+struct memp_malloc_helper
+{
+   memp_t poolnr;
+};
+#endif /* MEM_USE_POOLS */
+
+void  memp_init(void);
+
+#if MEMP_OVERFLOW_CHECK
+void *memp_malloc_fn(memp_t type, const char* file, const int line);
+#define memp_malloc(t) memp_malloc_fn((t), __FILE__, __LINE__)
+#else
+void *memp_malloc(memp_t type);
+#endif
+void  memp_free(memp_t type, void *mem);
+
+#endif /* MEMP_MEM_MALLOC */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_MEMP_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/memp_std.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/memp_std.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/memp_std.h	(revision 164)
@@ -0,0 +1,122 @@
+/*
+ * SETUP: Make sure we define everything we will need.
+ *
+ * We have create three types of pools:
+ *   1) MEMPOOL - standard pools
+ *   2) MALLOC_MEMPOOL - to be used by mem_malloc in mem.c
+ *   3) PBUF_MEMPOOL - a mempool of pbuf's, so include space for the pbuf struct
+ *
+ * If the include'r doesn't require any special treatment of each of the types
+ * above, then will declare #2 & #3 to be just standard mempools.
+ */
+#ifndef LWIP_MALLOC_MEMPOOL
+/* This treats "malloc pools" just like any other pool.
+   The pools are a little bigger to provide 'size' as the amount of user data. */
+#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, (size + sizeof(struct memp_malloc_helper)), "MALLOC_"#size)
+#define LWIP_MALLOC_MEMPOOL_START
+#define LWIP_MALLOC_MEMPOOL_END
+#endif /* LWIP_MALLOC_MEMPOOL */ 
+
+#ifndef LWIP_PBUF_MEMPOOL
+/* This treats "pbuf pools" just like any other pool.
+ * Allocates buffers for a pbuf struct AND a payload size */
+#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, (MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(payload)), desc)
+#endif /* LWIP_PBUF_MEMPOOL */
+
+
+/*
+ * A list of internal pools used by LWIP.
+ *
+ * LWIP_MEMPOOL(pool_name, number_elements, element_size, pool_description)
+ *     creates a pool name MEMP_pool_name. description is used in stats.c
+ */
+#if LWIP_RAW
+LWIP_MEMPOOL(RAW_PCB,        MEMP_NUM_RAW_PCB,         sizeof(struct raw_pcb),        "RAW_PCB")
+#endif /* LWIP_RAW */
+
+#if LWIP_UDP
+LWIP_MEMPOOL(UDP_PCB,        MEMP_NUM_UDP_PCB,         sizeof(struct udp_pcb),        "UDP_PCB")
+#endif /* LWIP_UDP */
+
+#if LWIP_TCP
+LWIP_MEMPOOL(TCP_PCB,        MEMP_NUM_TCP_PCB,         sizeof(struct tcp_pcb),        "TCP_PCB")
+LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN,  sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN")
+LWIP_MEMPOOL(TCP_SEG,        MEMP_NUM_TCP_SEG,         sizeof(struct tcp_seg),        "TCP_SEG")
+#endif /* LWIP_TCP */
+
+#if IP_REASSEMBLY
+LWIP_MEMPOOL(REASSDATA,      MEMP_NUM_REASSDATA,       sizeof(struct ip_reassdata),   "REASSDATA")
+#endif /* IP_REASSEMBLY */
+#if IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF
+LWIP_MEMPOOL(FRAG_PBUF,      MEMP_NUM_FRAG_PBUF,       sizeof(struct pbuf_custom_ref),"FRAG_PBUF")
+#endif /* IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */
+
+#if LWIP_NETCONN
+LWIP_MEMPOOL(NETBUF,         MEMP_NUM_NETBUF,          sizeof(struct netbuf),         "NETBUF")
+LWIP_MEMPOOL(NETCONN,        MEMP_NUM_NETCONN,         sizeof(struct netconn),        "NETCONN")
+#endif /* LWIP_NETCONN */
+
+#if NO_SYS==0
+LWIP_MEMPOOL(TCPIP_MSG_API,  MEMP_NUM_TCPIP_MSG_API,   sizeof(struct tcpip_msg),      "TCPIP_MSG_API")
+#if !LWIP_TCPIP_CORE_LOCKING_INPUT
+LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg),      "TCPIP_MSG_INPKT")
+#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */
+#endif /* NO_SYS==0 */
+
+#if LWIP_ARP && ARP_QUEUEING
+LWIP_MEMPOOL(ARP_QUEUE,      MEMP_NUM_ARP_QUEUE,       sizeof(struct etharp_q_entry), "ARP_QUEUE")
+#endif /* LWIP_ARP && ARP_QUEUEING */
+
+#if LWIP_IGMP
+LWIP_MEMPOOL(IGMP_GROUP,     MEMP_NUM_IGMP_GROUP,      sizeof(struct igmp_group),     "IGMP_GROUP")
+#endif /* LWIP_IGMP */
+
+#if (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) /* LWIP_TIMERS */
+LWIP_MEMPOOL(SYS_TIMEOUT,    MEMP_NUM_SYS_TIMEOUT,     sizeof(struct sys_timeo),      "SYS_TIMEOUT")
+#endif /* LWIP_TIMERS */
+
+#if LWIP_SNMP
+LWIP_MEMPOOL(SNMP_ROOTNODE,  MEMP_NUM_SNMP_ROOTNODE,   sizeof(struct mib_list_rootnode), "SNMP_ROOTNODE")
+LWIP_MEMPOOL(SNMP_NODE,      MEMP_NUM_SNMP_NODE,       sizeof(struct mib_list_node),     "SNMP_NODE")
+LWIP_MEMPOOL(SNMP_VARBIND,   MEMP_NUM_SNMP_VARBIND,    sizeof(struct snmp_varbind),      "SNMP_VARBIND")
+LWIP_MEMPOOL(SNMP_VALUE,     MEMP_NUM_SNMP_VALUE,      SNMP_MAX_VALUE_SIZE,              "SNMP_VALUE")
+#endif /* LWIP_SNMP */
+#if LWIP_DNS && LWIP_SOCKET
+LWIP_MEMPOOL(NETDB,          MEMP_NUM_NETDB,           NETDB_ELEM_SIZE,               "NETDB")
+#endif /* LWIP_DNS && LWIP_SOCKET */
+#if LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC
+LWIP_MEMPOOL(LOCALHOSTLIST,  MEMP_NUM_LOCALHOSTLIST,   LOCALHOSTLIST_ELEM_SIZE,       "LOCALHOSTLIST")
+#endif /* LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+#if PPP_SUPPORT && PPPOE_SUPPORT
+LWIP_MEMPOOL(PPPOE_IF,      MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc),    "PPPOE_IF")
+#endif /* PPP_SUPPORT && PPPOE_SUPPORT */
+
+/*
+ * A list of pools of pbuf's used by LWIP.
+ *
+ * LWIP_PBUF_MEMPOOL(pool_name, number_elements, pbuf_payload_size, pool_description)
+ *     creates a pool name MEMP_pool_name. description is used in stats.c
+ *     This allocates enough space for the pbuf struct and a payload.
+ *     (Example: pbuf_payload_size=0 allocates only size for the struct)
+ */
+LWIP_PBUF_MEMPOOL(PBUF,      MEMP_NUM_PBUF,            0,                             "PBUF_REF/ROM")
+LWIP_PBUF_MEMPOOL(PBUF_POOL, PBUF_POOL_SIZE,           PBUF_POOL_BUFSIZE,             "PBUF_POOL")
+
+
+/*
+ * Allow for user-defined pools; this must be explicitly set in lwipopts.h
+ * since the default is to NOT look for lwippools.h
+ */
+#if MEMP_USE_CUSTOM_POOLS
+#include "lwippools.h"
+#endif /* MEMP_USE_CUSTOM_POOLS */
+
+/*
+ * REQUIRED CLEANUP: Clear up so we don't get "multiply defined" error later
+ * (#undef is ignored for something that is not defined)
+ */
+#undef LWIP_MEMPOOL
+#undef LWIP_MALLOC_MEMPOOL
+#undef LWIP_MALLOC_MEMPOOL_START
+#undef LWIP_MALLOC_MEMPOOL_END
+#undef LWIP_PBUF_MEMPOOL
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/netbuf.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/netbuf.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/netbuf.h	(revision 164)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_NETBUF_H__
+#define __LWIP_NETBUF_H__
+
+#include "lwip/opt.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** This netbuf has dest-addr/port set */
+#define NETBUF_FLAG_DESTADDR    0x01
+/** This netbuf includes a checksum */
+#define NETBUF_FLAG_CHKSUM      0x02
+
+struct netbuf {
+  struct pbuf *p, *ptr;
+  ip_addr_t addr;
+  u16_t port;
+#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY
+#if LWIP_CHECKSUM_ON_COPY
+  u8_t flags;
+#endif /* LWIP_CHECKSUM_ON_COPY */
+  u16_t toport_chksum;
+#if LWIP_NETBUF_RECVINFO
+  ip_addr_t toaddr;
+#endif /* LWIP_NETBUF_RECVINFO */
+#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */
+};
+
+/* Network buffer functions: */
+struct netbuf *   netbuf_new      (void);
+void              netbuf_delete   (struct netbuf *buf);
+void *            netbuf_alloc    (struct netbuf *buf, u16_t size);
+void              netbuf_free     (struct netbuf *buf);
+err_t             netbuf_ref      (struct netbuf *buf,
+                                   const void *dataptr, u16_t size);
+void              netbuf_chain    (struct netbuf *head,
+           struct netbuf *tail);
+
+err_t             netbuf_data     (struct netbuf *buf,
+                                   void **dataptr, u16_t *len);
+s8_t              netbuf_next     (struct netbuf *buf);
+void              netbuf_first    (struct netbuf *buf);
+
+
+#define netbuf_copy_partial(buf, dataptr, len, offset) \
+  pbuf_copy_partial((buf)->p, (dataptr), (len), (offset))
+#define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0)
+#define netbuf_take(buf, dataptr, len) pbuf_take((buf)->p, dataptr, len)
+#define netbuf_len(buf)              ((buf)->p->tot_len)
+#define netbuf_fromaddr(buf)         (&((buf)->addr))
+#define netbuf_set_fromaddr(buf, fromaddr) ip_addr_set((&(buf)->addr), fromaddr)
+#define netbuf_fromport(buf)         ((buf)->port)
+#if LWIP_NETBUF_RECVINFO
+#define netbuf_destaddr(buf)         (&((buf)->toaddr))
+#define netbuf_set_destaddr(buf, destaddr) ip_addr_set((&(buf)->addr), destaddr)
+#define netbuf_destport(buf)         (((buf)->flags & NETBUF_FLAG_DESTADDR) ? (buf)->toport_chksum : 0)
+#endif /* LWIP_NETBUF_RECVINFO */
+#if LWIP_CHECKSUM_ON_COPY
+#define netbuf_set_chksum(buf, chksum) do { (buf)->flags = NETBUF_FLAG_CHKSUM; \
+                                            (buf)->toport_chksum = chksum; } while(0)
+#endif /* LWIP_CHECKSUM_ON_COPY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_NETBUF_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/netdb.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/netdb.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/netdb.h	(revision 164)
@@ -0,0 +1,124 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt
+ *
+ */
+#ifndef __LWIP_NETDB_H__
+#define __LWIP_NETDB_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_DNS && LWIP_SOCKET
+
+#include <stddef.h> /* for size_t */
+
+#include "lwip/inet.h"
+#include "lwip/sockets.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* some rarely used options */
+#ifndef LWIP_DNS_API_DECLARE_H_ERRNO
+#define LWIP_DNS_API_DECLARE_H_ERRNO 1
+#endif
+
+#ifndef LWIP_DNS_API_DEFINE_ERRORS
+#define LWIP_DNS_API_DEFINE_ERRORS 1
+#endif
+
+#ifndef LWIP_DNS_API_DECLARE_STRUCTS
+#define LWIP_DNS_API_DECLARE_STRUCTS 1
+#endif
+
+#if LWIP_DNS_API_DEFINE_ERRORS
+/** Errors used by the DNS API functions, h_errno can be one of them */
+#define EAI_NONAME      200
+#define EAI_SERVICE     201
+#define EAI_FAIL        202
+#define EAI_MEMORY      203
+
+#define HOST_NOT_FOUND  210
+#define NO_DATA         211
+#define NO_RECOVERY     212
+#define TRY_AGAIN       213
+#endif /* LWIP_DNS_API_DEFINE_ERRORS */
+
+#if LWIP_DNS_API_DECLARE_STRUCTS
+struct hostent {
+    char  *h_name;      /* Official name of the host. */
+    char **h_aliases;   /* A pointer to an array of pointers to alternative host names,
+                           terminated by a null pointer. */
+    int    h_addrtype;  /* Address type. */
+    int    h_length;    /* The length, in bytes, of the address. */
+    char **h_addr_list; /* A pointer to an array of pointers to network addresses (in
+                           network byte order) for the host, terminated by a null pointer. */
+#define h_addr h_addr_list[0] /* for backward compatibility */
+};
+
+struct addrinfo {
+    int               ai_flags;      /* Input flags. */
+    int               ai_family;     /* Address family of socket. */
+    int               ai_socktype;   /* Socket type. */
+    int               ai_protocol;   /* Protocol of socket. */
+    socklen_t         ai_addrlen;    /* Length of socket address. */
+    struct sockaddr  *ai_addr;       /* Socket address of socket. */
+    char             *ai_canonname;  /* Canonical name of service location. */
+    struct addrinfo  *ai_next;       /* Pointer to next in list. */
+};
+#endif /* LWIP_DNS_API_DECLARE_STRUCTS */
+
+#if LWIP_DNS_API_DECLARE_H_ERRNO
+/* application accessable error code set by the DNS API functions */
+extern int h_errno;
+#endif /* LWIP_DNS_API_DECLARE_H_ERRNO*/
+
+struct hostent *lwip_gethostbyname(const char *name);
+int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
+                size_t buflen, struct hostent **result, int *h_errnop);
+void lwip_freeaddrinfo(struct addrinfo *ai);
+int lwip_getaddrinfo(const char *nodename,
+       const char *servname,
+       const struct addrinfo *hints,
+       struct addrinfo **res);
+
+#if LWIP_COMPAT_SOCKETS
+#define gethostbyname(name) lwip_gethostbyname(name)
+#define gethostbyname_r(name, ret, buf, buflen, result, h_errnop) \
+       lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop)
+#define freeaddrinfo(addrinfo) lwip_freeaddrinfo(addrinfo)
+#define getaddrinfo(nodname, servname, hints, res) \
+       lwip_getaddrinfo(nodname, servname, hints, res)
+#endif /* LWIP_COMPAT_SOCKETS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_DNS && LWIP_SOCKET */
+
+#endif /* __LWIP_NETDB_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/netif.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/netif.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/netif.h	(revision 164)
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_NETIF_H__
+#define __LWIP_NETIF_H__
+
+#include "lwip/opt.h"
+
+#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF)
+
+#include "lwip/err.h"
+
+#include "lwip/ip_addr.h"
+
+#include "lwip/def.h"
+#include "lwip/pbuf.h"
+#include "lwip/sys.h"
+#if LWIP_DHCP
+struct dhcp;
+#endif
+#if LWIP_AUTOIP
+struct autoip;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Throughout this file, IP addresses are expected to be in
+ * the same byte order as in IP_PCB. */
+
+/** must be the maximum of all used hardware address lengths
+    across all types of interfaces in use */
+#define NETIF_MAX_HWADDR_LEN 6U
+
+/** Whether the network interface is 'up'. This is
+ * a software flag used to control whether this network
+ * interface is enabled and processes traffic.
+ * It is set by the startup code (for static IP configuration) or
+ * by dhcp/autoip when an address has been assigned.
+ */
+#define NETIF_FLAG_UP           0x01U
+/** If set, the netif has broadcast capability.
+ * Set by the netif driver in its init function. */
+#define NETIF_FLAG_BROADCAST    0x02U
+/** If set, the netif is one end of a point-to-point connection.
+ * Set by the netif driver in its init function. */
+#define NETIF_FLAG_POINTTOPOINT 0x04U
+/** If set, the interface is configured using DHCP.
+ * Set by the DHCP code when starting or stopping DHCP. */
+#define NETIF_FLAG_DHCP         0x08U
+/** If set, the interface has an active link
+ *  (set by the network interface driver).
+ * Either set by the netif driver in its init function (if the link
+ * is up at that time) or at a later point once the link comes up
+ * (if link detection is supported by the hardware). */
+#define NETIF_FLAG_LINK_UP      0x10U
+/** If set, the netif is an ethernet device using ARP.
+ * Set by the netif driver in its init function.
+ * Used to check input packet types and use of DHCP. */
+#define NETIF_FLAG_ETHARP       0x20U
+/** If set, the netif is an ethernet device. It might not use
+ * ARP or TCP/IP if it is used for PPPoE only.
+ */
+#define NETIF_FLAG_ETHERNET     0x40U
+/** If set, the netif has IGMP capability.
+ * Set by the netif driver in its init function. */
+#define NETIF_FLAG_IGMP         0x80U
+
+/** Function prototype for netif init functions. Set up flags and output/linkoutput
+ * callback functions in this function.
+ *
+ * @param netif The netif to initialize
+ */
+typedef err_t (*netif_init_fn)(struct netif *netif);
+/** Function prototype for netif->input functions. This function is saved as 'input'
+ * callback function in the netif struct. Call it when a packet has been received.
+ *
+ * @param p The received packet, copied into a pbuf
+ * @param inp The netif which received the packet
+ */
+typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp);
+/** Function prototype for netif->output functions. Called by lwIP when a packet
+ * shall be sent. For ethernet netif, set this to 'etharp_output' and set
+ * 'linkoutput'.
+ *
+ * @param netif The netif which shall send a packet
+ * @param p The packet to send (p->payload points to IP header)
+ * @param ipaddr The IP address to which the packet shall be sent
+ */
+typedef err_t (*netif_output_fn)(struct netif *netif, struct pbuf *p,
+       ip_addr_t *ipaddr);
+/** Function prototype for netif->linkoutput functions. Only used for ethernet
+ * netifs. This function is called by ARP when a packet shall be sent.
+ *
+ * @param netif The netif which shall send a packet
+ * @param p The packet to send (raw ethernet packet)
+ */
+typedef err_t (*netif_linkoutput_fn)(struct netif *netif, struct pbuf *p);
+/** Function prototype for netif status- or link-callback functions. */
+typedef void (*netif_status_callback_fn)(struct netif *netif);
+/** Function prototype for netif igmp_mac_filter functions */
+typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif,
+       ip_addr_t *group, u8_t action);
+
+/** Generic data structure used for all lwIP network interfaces.
+ *  The following fields should be filled in by the initialization
+ *  function for the device driver: hwaddr_len, hwaddr[], mtu, flags */
+struct netif {
+  /** pointer to next in linked list */
+  struct netif *next;
+
+  /** IP address configuration in network byte order */
+  ip_addr_t ip_addr;
+  ip_addr_t netmask;
+  ip_addr_t gw;
+
+  /** This function is called by the network device driver
+   *  to pass a packet up the TCP/IP stack. */
+  netif_input_fn input;
+  /** This function is called by the IP module when it wants
+   *  to send a packet on the interface. This function typically
+   *  first resolves the hardware address, then sends the packet. */
+  netif_output_fn output;
+  /** This function is called by the ARP module when it wants
+   *  to send a packet on the interface. This function outputs
+   *  the pbuf as-is on the link medium. */
+  netif_linkoutput_fn linkoutput;
+#if LWIP_NETIF_STATUS_CALLBACK
+  /** This function is called when the netif state is set to up or down
+   */
+  netif_status_callback_fn status_callback;
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#if LWIP_NETIF_LINK_CALLBACK
+  /** This function is called when the netif link is set to up or down
+   */
+  netif_status_callback_fn link_callback;
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+#if LWIP_NETIF_REMOVE_CALLBACK
+  /** This function is called when the netif has been removed */
+  netif_status_callback_fn remove_callback;
+#endif /* LWIP_NETIF_REMOVE_CALLBACK */
+  /** This field can be set by the device driver and could point
+   *  to state information for the device. */
+  void *state;
+#if LWIP_DHCP
+  /** the DHCP client state information for this netif */
+  struct dhcp *dhcp;
+#endif /* LWIP_DHCP */
+#if LWIP_AUTOIP
+  /** the AutoIP client state information for this netif */
+  struct autoip *autoip;
+#endif
+#if LWIP_NETIF_HOSTNAME
+  /* the hostname for this netif, NULL is a valid value */
+  char*  hostname;
+#endif /* LWIP_NETIF_HOSTNAME */
+  /** maximum transfer unit (in bytes) */
+  u16_t mtu;
+  /** number of bytes used in hwaddr */
+  u8_t hwaddr_len;
+  /** link level hardware address of this interface */
+  u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
+  /** flags (see NETIF_FLAG_ above) */
+  u8_t flags;
+  /** descriptive abbreviation */
+  char name[2];
+  /** number of this interface */
+  u8_t num;
+#if LWIP_SNMP
+  /** link type (from "snmp_ifType" enum from snmp.h) */
+  u8_t link_type;
+  /** (estimate) link speed */
+  u32_t link_speed;
+  /** timestamp at last change made (up/down) */
+  u32_t ts;
+  /** counters */
+  u32_t ifinoctets;
+  u32_t ifinucastpkts;
+  u32_t ifinnucastpkts;
+  u32_t ifindiscards;
+  u32_t ifoutoctets;
+  u32_t ifoutucastpkts;
+  u32_t ifoutnucastpkts;
+  u32_t ifoutdiscards;
+#endif /* LWIP_SNMP */
+#if LWIP_IGMP
+  /** This function could be called to add or delete a entry in the multicast
+      filter table of the ethernet MAC.*/
+  netif_igmp_mac_filter_fn igmp_mac_filter;
+#endif /* LWIP_IGMP */
+#if LWIP_NETIF_HWADDRHINT
+  u8_t *addr_hint;
+#endif /* LWIP_NETIF_HWADDRHINT */
+#if ENABLE_LOOPBACK
+  /* List of packets to be queued for ourselves. */
+  struct pbuf *loop_first;
+  struct pbuf *loop_last;
+#if LWIP_LOOPBACK_MAX_PBUFS
+  u16_t loop_cnt_current;
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+#endif /* ENABLE_LOOPBACK */
+};
+
+#if LWIP_SNMP
+#define NETIF_INIT_SNMP(netif, type, speed) \
+  /* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \
+  (netif)->link_type = (type);    \
+  /* your link speed here (units: bits per second) */  \
+  (netif)->link_speed = (speed);  \
+  (netif)->ts = 0;              \
+  (netif)->ifinoctets = 0;      \
+  (netif)->ifinucastpkts = 0;   \
+  (netif)->ifinnucastpkts = 0;  \
+  (netif)->ifindiscards = 0;    \
+  (netif)->ifoutoctets = 0;     \
+  (netif)->ifoutucastpkts = 0;  \
+  (netif)->ifoutnucastpkts = 0; \
+  (netif)->ifoutdiscards = 0
+#else /* LWIP_SNMP */
+#define NETIF_INIT_SNMP(netif, type, speed)
+#endif /* LWIP_SNMP */
+
+
+/** The list of network interfaces. */
+extern struct netif *netif_list;
+/** The default network interface. */
+extern struct netif *netif_default;
+
+void netif_init(void);
+
+struct netif *netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask,
+      ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input);
+
+void
+netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask,
+      ip_addr_t *gw);
+void netif_remove(struct netif * netif);
+
+/* Returns a network interface given its name. The name is of the form
+   "et0", where the first two letters are the "name" field in the
+   netif structure, and the digit is in the num field in the same
+   structure. */
+struct netif *netif_find(char *name);
+
+void netif_set_default(struct netif *netif);
+
+void netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr);
+void netif_set_netmask(struct netif *netif, ip_addr_t *netmask);
+void netif_set_gw(struct netif *netif, ip_addr_t *gw);
+
+void netif_set_up(struct netif *netif);
+void netif_set_down(struct netif *netif);
+/** Ask if an interface is up */
+#define netif_is_up(netif) (((netif)->flags & NETIF_FLAG_UP) ? (u8_t)1 : (u8_t)0)
+
+#if LWIP_NETIF_STATUS_CALLBACK
+void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#if LWIP_NETIF_REMOVE_CALLBACK
+void netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback);
+#endif /* LWIP_NETIF_REMOVE_CALLBACK */
+
+void netif_set_link_up(struct netif *netif);
+void netif_set_link_down(struct netif *netif);
+/** Ask if a link is up */ 
+#define netif_is_link_up(netif) (((netif)->flags & NETIF_FLAG_LINK_UP) ? (u8_t)1 : (u8_t)0)
+
+#if LWIP_NETIF_LINK_CALLBACK
+void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback);
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+
+#if LWIP_NETIF_HOSTNAME
+#define netif_set_hostname(netif, name) do { if((netif) != NULL) { (netif)->hostname = name; }}while(0)
+#define netif_get_hostname(netif) (((netif) != NULL) ? ((netif)->hostname) : NULL)
+#endif /* LWIP_NETIF_HOSTNAME */
+
+#if LWIP_IGMP
+#define netif_set_igmp_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->igmp_mac_filter = function; }}while(0)
+#define netif_get_igmp_mac_filter(netif) (((netif) != NULL) ? ((netif)->igmp_mac_filter) : NULL)
+#endif /* LWIP_IGMP */
+
+#if ENABLE_LOOPBACK
+err_t netif_loop_output(struct netif *netif, struct pbuf *p, ip_addr_t *dest_ip);
+void netif_poll(struct netif *netif);
+#if !LWIP_NETIF_LOOPBACK_MULTITHREADING
+void netif_poll_all(void);
+#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
+#endif /* ENABLE_LOOPBACK */
+
+#if LWIP_NETIF_HWADDRHINT
+#define NETIF_SET_HWADDRHINT(netif, hint) ((netif)->addr_hint = (hint))
+#else /* LWIP_NETIF_HWADDRHINT */
+#define NETIF_SET_HWADDRHINT(netif, hint)
+#endif /* LWIP_NETIF_HWADDRHINT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_NETIF_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/netifapi.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/netifapi.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/netifapi.h	(revision 164)
@@ -0,0 +1,108 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ */
+ 
+#ifndef __LWIP_NETIFAPI_H__
+#define __LWIP_NETIFAPI_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/sys.h"
+#include "lwip/netif.h"
+#include "lwip/dhcp.h"
+#include "lwip/autoip.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*netifapi_void_fn)(struct netif *netif);
+typedef err_t (*netifapi_errt_fn)(struct netif *netif);
+
+struct netifapi_msg_msg {
+#if !LWIP_TCPIP_CORE_LOCKING
+  sys_sem_t sem;
+#endif /* !LWIP_TCPIP_CORE_LOCKING */
+  err_t err;
+  struct netif *netif;
+  union {
+    struct {
+      ip_addr_t *ipaddr;
+      ip_addr_t *netmask;
+      ip_addr_t *gw;
+      void *state;
+      netif_init_fn init;
+      netif_input_fn input;
+    } add;
+    struct {
+      netifapi_void_fn voidfunc;
+      netifapi_errt_fn errtfunc;
+    } common;
+  } msg;
+};
+
+struct netifapi_msg {
+  void (* function)(struct netifapi_msg_msg *msg);
+  struct netifapi_msg_msg msg;
+};
+
+
+/* API for application */
+err_t netifapi_netif_add       ( struct netif *netif,
+                                 ip_addr_t *ipaddr,
+                                 ip_addr_t *netmask,
+                                 ip_addr_t *gw,
+                                 void *state,
+                                 netif_init_fn init,
+                                 netif_input_fn input);
+
+err_t netifapi_netif_set_addr  ( struct netif *netif,
+                                 ip_addr_t *ipaddr,
+                                 ip_addr_t *netmask,
+                                 ip_addr_t *gw );
+
+err_t netifapi_netif_common    ( struct netif *netif,
+                                 netifapi_void_fn voidfunc,
+                                 netifapi_errt_fn errtfunc);
+
+#define netifapi_netif_remove(n)      netifapi_netif_common(n, netif_remove, NULL)
+#define netifapi_netif_set_up(n)      netifapi_netif_common(n, netif_set_up, NULL)
+#define netifapi_netif_set_down(n)    netifapi_netif_common(n, netif_set_down, NULL)
+#define netifapi_netif_set_default(n) netifapi_netif_common(n, netif_set_default, NULL)
+#define netifapi_dhcp_start(n)        netifapi_netif_common(n, NULL, dhcp_start)
+#define netifapi_dhcp_stop(n)         netifapi_netif_common(n, dhcp_stop, NULL)
+#define netifapi_autoip_start(n)      netifapi_netif_common(n, NULL, autoip_start)
+#define netifapi_autoip_stop(n)       netifapi_netif_common(n, NULL, autoip_stop)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_NETIF_API */
+
+#endif /* __LWIP_NETIFAPI_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/opt.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/opt.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/opt.h	(revision 164)
@@ -0,0 +1,2133 @@
+/**
+ * @file
+ *
+ * lwIP Options Configuration
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_OPT_H__
+#define __LWIP_OPT_H__
+
+/*
+ * Include user defined options first. Anything not defined in these files
+ * will be set to standard values. Override anything you dont like!
+ */
+#include "lwipopts.h"
+#include "lwip/debug.h"
+
+/*
+   -----------------------------------------------
+   ---------- Platform specific locking ----------
+   -----------------------------------------------
+*/
+
+/**
+ * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
+ * critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#ifndef SYS_LIGHTWEIGHT_PROT
+#define SYS_LIGHTWEIGHT_PROT            0
+#endif
+
+/** 
+ * NO_SYS==1: Provides VERY minimal functionality. Otherwise,
+ * use lwIP facilities.
+ */
+#ifndef NO_SYS
+#define NO_SYS                          0
+#endif
+
+/**
+ * NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1
+ * Mainly for compatibility to old versions.
+ */
+#ifndef NO_SYS_NO_TIMERS
+#define NO_SYS_NO_TIMERS                0
+#endif
+
+/**
+ * MEMCPY: override this if you have a faster implementation at hand than the
+ * one included in your C library
+ */
+#ifndef MEMCPY
+#define MEMCPY(dst,src,len)             memcpy(dst,src,len)
+#endif
+
+/**
+ * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a
+ * call to memcpy() if the length is known at compile time and is small.
+ */
+#ifndef SMEMCPY
+#define SMEMCPY(dst,src,len)            memcpy(dst,src,len)
+#endif
+
+/*
+   ------------------------------------
+   ---------- Memory options ----------
+   ------------------------------------
+*/
+/**
+ * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library
+ * instead of the lwip internal allocator. Can save code size if you
+ * already use it.
+ */
+#ifndef MEM_LIBC_MALLOC
+#define MEM_LIBC_MALLOC                 0
+#endif
+
+/**
+* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator.
+* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution
+* speed and usage from interrupts!
+*/
+#ifndef MEMP_MEM_MALLOC
+#define MEMP_MEM_MALLOC                 0
+#endif
+
+/**
+ * MEM_ALIGNMENT: should be set to the alignment of the CPU
+ *    4 byte alignment -> #define MEM_ALIGNMENT 4
+ *    2 byte alignment -> #define MEM_ALIGNMENT 2
+ */
+#ifndef MEM_ALIGNMENT
+#define MEM_ALIGNMENT                   1
+#endif
+
+/**
+ * MEM_SIZE: the size of the heap memory. If the application will send
+ * a lot of data that needs to be copied, this should be set high.
+ */
+#ifndef MEM_SIZE
+#define MEM_SIZE                        1600
+#endif
+
+/**
+ * MEMP_SEPARATE_POOLS: if defined to 1, each pool is placed in its own array.
+ * This can be used to individually change the location of each pool.
+ * Default is one big array for all pools
+ */
+#ifndef MEMP_SEPARATE_POOLS
+#define MEMP_SEPARATE_POOLS             0
+#endif
+
+/**
+ * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable
+ * amount of bytes before and after each memp element in every pool and fills
+ * it with a prominent default value.
+ *    MEMP_OVERFLOW_CHECK == 0 no checking
+ *    MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed
+ *    MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time
+ *      memp_malloc() or memp_free() is called (useful but slow!)
+ */
+#ifndef MEMP_OVERFLOW_CHECK
+#define MEMP_OVERFLOW_CHECK             0
+#endif
+
+/**
+ * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make
+ * sure that there are no cycles in the linked lists.
+ */
+#ifndef MEMP_SANITY_CHECK
+#define MEMP_SANITY_CHECK               0
+#endif
+
+/**
+ * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set
+ * of memory pools of various sizes. When mem_malloc is called, an element of
+ * the smallest pool that can provide the length needed is returned.
+ * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled.
+ */
+#ifndef MEM_USE_POOLS
+#define MEM_USE_POOLS                   0
+#endif
+
+/**
+ * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next
+ * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more
+ * reliable. */
+#ifndef MEM_USE_POOLS_TRY_BIGGER_POOL
+#define MEM_USE_POOLS_TRY_BIGGER_POOL   0
+#endif
+
+/**
+ * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h
+ * that defines additional pools beyond the "standard" ones required
+ * by lwIP. If you set this to 1, you must have lwippools.h in your 
+ * inlude path somewhere. 
+ */
+#ifndef MEMP_USE_CUSTOM_POOLS
+#define MEMP_USE_CUSTOM_POOLS           0
+#endif
+
+/**
+ * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from
+ * interrupt context (or another context that doesn't allow waiting for a
+ * semaphore).
+ * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT,
+ * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs
+ * with each loop so that mem_free can run.
+ *
+ * ATTENTION: As you can see from the above description, this leads to dis-/
+ * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc
+ * can need longer.
+ *
+ * If you don't want that, at least for NO_SYS=0, you can still use the following
+ * functions to enqueue a deallocation call which then runs in the tcpip_thread
+ * context:
+ * - pbuf_free_callback(p);
+ * - mem_free_callback(m);
+ */
+#ifndef LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+#endif
+
+/*
+   ------------------------------------------------
+   ---------- Internal Memory Pool Sizes ----------
+   ------------------------------------------------
+*/
+/**
+ * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF).
+ * If the application sends a lot of data out of ROM (or other static memory),
+ * this should be set high.
+ */
+#ifndef MEMP_NUM_PBUF
+#define MEMP_NUM_PBUF                   16
+#endif
+
+/**
+ * MEMP_NUM_RAW_PCB: Number of raw connection PCBs
+ * (requires the LWIP_RAW option)
+ */
+#ifndef MEMP_NUM_RAW_PCB
+#define MEMP_NUM_RAW_PCB                4
+#endif
+
+/**
+ * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
+ * per active UDP "connection".
+ * (requires the LWIP_UDP option)
+ */
+#ifndef MEMP_NUM_UDP_PCB
+#define MEMP_NUM_UDP_PCB                4
+#endif
+
+/**
+ * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections.
+ * (requires the LWIP_TCP option)
+ */
+#ifndef MEMP_NUM_TCP_PCB
+#define MEMP_NUM_TCP_PCB                5
+#endif
+
+/**
+ * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections.
+ * (requires the LWIP_TCP option)
+ */
+#ifndef MEMP_NUM_TCP_PCB_LISTEN
+#define MEMP_NUM_TCP_PCB_LISTEN         8
+#endif
+
+/**
+ * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments.
+ * (requires the LWIP_TCP option)
+ */
+#ifndef MEMP_NUM_TCP_SEG
+#define MEMP_NUM_TCP_SEG                16
+#endif
+
+/**
+ * MEMP_NUM_REASSDATA: the number of IP packets simultaneously queued for
+ * reassembly (whole packets, not fragments!)
+ */
+#ifndef MEMP_NUM_REASSDATA
+#define MEMP_NUM_REASSDATA              5
+#endif
+
+/**
+ * MEMP_NUM_FRAG_PBUF: the number of IP fragments simultaneously sent
+ * (fragments, not whole packets!).
+ * This is only used with IP_FRAG_USES_STATIC_BUF==0 and
+ * LWIP_NETIF_TX_SINGLE_PBUF==0 and only has to be > 1 with DMA-enabled MACs
+ * where the packet is not yet sent when netif->output returns.
+ */
+#ifndef MEMP_NUM_FRAG_PBUF
+#define MEMP_NUM_FRAG_PBUF              15
+#endif
+
+/**
+ * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing
+ * packets (pbufs) that are waiting for an ARP request (to resolve
+ * their destination address) to finish.
+ * (requires the ARP_QUEUEING option)
+ */
+#ifndef MEMP_NUM_ARP_QUEUE
+#define MEMP_NUM_ARP_QUEUE              30
+#endif
+
+/**
+ * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces
+ * can be members et the same time (one per netif - allsystems group -, plus one
+ * per netif membership).
+ * (requires the LWIP_IGMP option)
+ */
+#ifndef MEMP_NUM_IGMP_GROUP
+#define MEMP_NUM_IGMP_GROUP             8
+#endif
+
+/**
+ * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts.
+ * (requires NO_SYS==0)
+ * The default number of timeouts is calculated here for all enabled modules.
+ * The formula expects settings to be either '0' or '1'.
+ */
+#ifndef MEMP_NUM_SYS_TIMEOUT
+#define MEMP_NUM_SYS_TIMEOUT            (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT)
+#endif
+
+/**
+ * MEMP_NUM_NETBUF: the number of struct netbufs.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#ifndef MEMP_NUM_NETBUF
+#define MEMP_NUM_NETBUF                 2
+#endif
+
+/**
+ * MEMP_NUM_NETCONN: the number of struct netconns.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#ifndef MEMP_NUM_NETCONN
+#define MEMP_NUM_NETCONN                4
+#endif
+
+/**
+ * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used
+ * for callback/timeout API communication. 
+ * (only needed if you use tcpip.c)
+ */
+#ifndef MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_TCPIP_MSG_API          8
+#endif
+
+/**
+ * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used
+ * for incoming packets. 
+ * (only needed if you use tcpip.c)
+ */
+#ifndef MEMP_NUM_TCPIP_MSG_INPKT
+#define MEMP_NUM_TCPIP_MSG_INPKT        8
+#endif
+
+/**
+ * MEMP_NUM_SNMP_NODE: the number of leafs in the SNMP tree.
+ */
+#ifndef MEMP_NUM_SNMP_NODE
+#define MEMP_NUM_SNMP_NODE              50
+#endif
+
+/**
+ * MEMP_NUM_SNMP_ROOTNODE: the number of branches in the SNMP tree.
+ * Every branch has one leaf (MEMP_NUM_SNMP_NODE) at least!
+ */
+#ifndef MEMP_NUM_SNMP_ROOTNODE
+#define MEMP_NUM_SNMP_ROOTNODE          30
+#endif
+
+/**
+ * MEMP_NUM_SNMP_VARBIND: the number of concurrent requests (does not have to
+ * be changed normally) - 2 of these are used per request (1 for input,
+ * 1 for output)
+ */
+#ifndef MEMP_NUM_SNMP_VARBIND
+#define MEMP_NUM_SNMP_VARBIND           2
+#endif
+
+/**
+ * MEMP_NUM_SNMP_VALUE: the number of OID or values concurrently used
+ * (does not have to be changed normally) - 3 of these are used per request
+ * (1 for the value read and 2 for OIDs - input and output)
+ */
+#ifndef MEMP_NUM_SNMP_VALUE
+#define MEMP_NUM_SNMP_VALUE             3
+#endif
+
+/**
+ * MEMP_NUM_NETDB: the number of concurrently running lwip_addrinfo() calls
+ * (before freeing the corresponding memory using lwip_freeaddrinfo()).
+ */
+#ifndef MEMP_NUM_NETDB
+#define MEMP_NUM_NETDB                  1
+#endif
+
+/**
+ * MEMP_NUM_LOCALHOSTLIST: the number of host entries in the local host list
+ * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1.
+ */
+#ifndef MEMP_NUM_LOCALHOSTLIST
+#define MEMP_NUM_LOCALHOSTLIST          1
+#endif
+
+/**
+ * MEMP_NUM_PPPOE_INTERFACES: the number of concurrently active PPPoE
+ * interfaces (only used with PPPOE_SUPPORT==1)
+ */
+#ifndef MEMP_NUM_PPPOE_INTERFACES
+#define MEMP_NUM_PPPOE_INTERFACES       1
+#endif
+
+/**
+ * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. 
+ */
+#ifndef PBUF_POOL_SIZE
+#define PBUF_POOL_SIZE                  16
+#endif
+
+/*
+   ---------------------------------
+   ---------- ARP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_ARP==1: Enable ARP functionality.
+ */
+#ifndef LWIP_ARP
+#define LWIP_ARP                        1
+#endif
+
+/**
+ * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached.
+ */
+#ifndef ARP_TABLE_SIZE
+#define ARP_TABLE_SIZE                  10
+#endif
+
+/**
+ * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address
+ * resolution. By default, only the most recent packet is queued per IP address.
+ * This is sufficient for most protocols and mainly reduces TCP connection
+ * startup time. Set this to 1 if you know your application sends more than one
+ * packet in a row to an IP address that is not in the ARP cache.
+ */
+#ifndef ARP_QUEUEING
+#define ARP_QUEUEING                    0
+#endif
+
+/**
+ * ETHARP_TRUST_IP_MAC==1: Incoming IP packets cause the ARP table to be
+ * updated with the source MAC and IP addresses supplied in the packet.
+ * You may want to disable this if you do not trust LAN peers to have the
+ * correct addresses, or as a limited approach to attempt to handle
+ * spoofing. If disabled, lwIP will need to make a new ARP request if
+ * the peer is not already in the ARP table, adding a little latency.
+ * The peer *is* in the ARP table if it requested our address before.
+ * Also notice that this slows down input processing of every IP packet!
+ */
+#ifndef ETHARP_TRUST_IP_MAC
+#define ETHARP_TRUST_IP_MAC             0
+#endif
+
+/**
+ * ETHARP_SUPPORT_VLAN==1: support receiving ethernet packets with VLAN header.
+ * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check.
+ * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted.
+ * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted.
+ * Alternatively, define a function/define ETHARP_VLAN_CHECK_FN(eth_hdr, vlan)
+ * that returns 1 to accept a packet or 0 to drop a packet.
+ */
+#ifndef ETHARP_SUPPORT_VLAN
+#define ETHARP_SUPPORT_VLAN             0
+#endif
+
+/** LWIP_ETHERNET==1: enable ethernet support for PPPoE even though ARP
+ * might be disabled
+ */
+#ifndef LWIP_ETHERNET
+#define LWIP_ETHERNET                   (LWIP_ARP || PPPOE_SUPPORT)
+#endif
+
+/** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure
+ * alignment of payload after that header. Since the header is 14 bytes long,
+ * without this padding e.g. addresses in the IP header will not be aligned
+ * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms.
+ */
+#ifndef ETH_PAD_SIZE
+#define ETH_PAD_SIZE                    0
+#endif
+
+/** ETHARP_SUPPORT_STATIC_ENTRIES==1: enable code to support static ARP table
+ * entries (using etharp_add_static_entry/etharp_remove_static_entry).
+ */
+#ifndef ETHARP_SUPPORT_STATIC_ENTRIES
+#define ETHARP_SUPPORT_STATIC_ENTRIES   0
+#endif
+
+
+/*
+   --------------------------------
+   ---------- IP options ----------
+   --------------------------------
+*/
+/**
+ * IP_FORWARD==1: Enables the ability to forward IP packets across network
+ * interfaces. If you are going to run lwIP on a device with only one network
+ * interface, define this to 0.
+ */
+#ifndef IP_FORWARD
+#define IP_FORWARD                      0
+#endif
+
+/**
+ * IP_OPTIONS_ALLOWED: Defines the behavior for IP options.
+ *      IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped.
+ *      IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed).
+ */
+#ifndef IP_OPTIONS_ALLOWED
+#define IP_OPTIONS_ALLOWED              1
+#endif
+
+/**
+ * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that
+ * this option does not affect outgoing packet sizes, which can be controlled
+ * via IP_FRAG.
+ */
+#ifndef IP_REASSEMBLY
+#define IP_REASSEMBLY                   1
+#endif
+
+/**
+ * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note
+ * that this option does not affect incoming packet sizes, which can be
+ * controlled via IP_REASSEMBLY.
+ */
+#ifndef IP_FRAG
+#define IP_FRAG                         1
+#endif
+
+/**
+ * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally)
+ * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived
+ * in this time, the whole packet is discarded.
+ */
+#ifndef IP_REASS_MAXAGE
+#define IP_REASS_MAXAGE                 3
+#endif
+
+/**
+ * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled.
+ * Since the received pbufs are enqueued, be sure to configure
+ * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive
+ * packets even if the maximum amount of fragments is enqueued for reassembly!
+ */
+#ifndef IP_REASS_MAX_PBUFS
+#define IP_REASS_MAX_PBUFS              10
+#endif
+
+/**
+ * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP
+ * fragmentation. Otherwise pbufs are allocated and reference the original
+ * packet data to be fragmented (or with LWIP_NETIF_TX_SINGLE_PBUF==1,
+ * new PBUF_RAM pbufs are used for fragments).
+ * ATTENTION: IP_FRAG_USES_STATIC_BUF==1 may not be used for DMA-enabled MACs!
+ */
+#ifndef IP_FRAG_USES_STATIC_BUF
+#define IP_FRAG_USES_STATIC_BUF         0
+#endif
+
+/**
+ * IP_FRAG_MAX_MTU: Assumed max MTU on any interface for IP frag buffer
+ * (requires IP_FRAG_USES_STATIC_BUF==1)
+ */
+#if IP_FRAG_USES_STATIC_BUF && !defined(IP_FRAG_MAX_MTU)
+#define IP_FRAG_MAX_MTU                 1500
+#endif
+
+/**
+ * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers.
+ */
+#ifndef IP_DEFAULT_TTL
+#define IP_DEFAULT_TTL                  255
+#endif
+
+/**
+ * IP_SOF_BROADCAST=1: Use the SOF_BROADCAST field to enable broadcast
+ * filter per pcb on udp and raw send operations. To enable broadcast filter
+ * on recv operations, you also have to set IP_SOF_BROADCAST_RECV=1.
+ */
+#ifndef IP_SOF_BROADCAST
+#define IP_SOF_BROADCAST                0
+#endif
+
+/**
+ * IP_SOF_BROADCAST_RECV (requires IP_SOF_BROADCAST=1) enable the broadcast
+ * filter on recv operations.
+ */
+#ifndef IP_SOF_BROADCAST_RECV
+#define IP_SOF_BROADCAST_RECV           0
+#endif
+
+/**
+ * IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1: allow ip_forward() to send packets back
+ * out on the netif where it was received. This should only be used for
+ * wireless networks.
+ * ATTENTION: When this is 1, make sure your netif driver correctly marks incoming
+ * link-layer-broadcast/multicast packets as such using the corresponding pbuf flags!
+ */
+#ifndef IP_FORWARD_ALLOW_TX_ON_RX_NETIF
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#endif
+
+/**
+ * LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first
+ * local TCP/UDP pcb (default==0). This can prevent creating predictable port
+ * numbers after booting a device.
+ */
+#ifndef LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS
+#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 0
+#endif
+
+/*
+   ----------------------------------
+   ---------- ICMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_ICMP==1: Enable ICMP module inside the IP stack.
+ * Be careful, disable that make your product non-compliant to RFC1122
+ */
+#ifndef LWIP_ICMP
+#define LWIP_ICMP                       1
+#endif
+
+/**
+ * ICMP_TTL: Default value for Time-To-Live used by ICMP packets.
+ */
+#ifndef ICMP_TTL
+#define ICMP_TTL                       (IP_DEFAULT_TTL)
+#endif
+
+/**
+ * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only)
+ */
+#ifndef LWIP_BROADCAST_PING
+#define LWIP_BROADCAST_PING             0
+#endif
+
+/**
+ * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only)
+ */
+#ifndef LWIP_MULTICAST_PING
+#define LWIP_MULTICAST_PING             0
+#endif
+
+/*
+   ---------------------------------
+   ---------- RAW options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
+ */
+#ifndef LWIP_RAW
+#define LWIP_RAW                        1
+#endif
+
+/**
+ * LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
+ */
+#ifndef RAW_TTL
+#define RAW_TTL                        (IP_DEFAULT_TTL)
+#endif
+
+/*
+   ----------------------------------
+   ---------- DHCP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_DHCP==1: Enable DHCP module.
+ */
+#ifndef LWIP_DHCP
+#define LWIP_DHCP                       0
+#endif
+
+/**
+ * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address.
+ */
+#ifndef DHCP_DOES_ARP_CHECK
+#define DHCP_DOES_ARP_CHECK             ((LWIP_DHCP) && (LWIP_ARP))
+#endif
+
+/*
+   ------------------------------------
+   ---------- AUTOIP options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_AUTOIP==1: Enable AUTOIP module.
+ */
+#ifndef LWIP_AUTOIP
+#define LWIP_AUTOIP                     0
+#endif
+
+/**
+ * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on
+ * the same interface at the same time.
+ */
+#ifndef LWIP_DHCP_AUTOIP_COOP
+#define LWIP_DHCP_AUTOIP_COOP           0
+#endif
+
+/**
+ * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes
+ * that should be sent before falling back on AUTOIP. This can be set
+ * as low as 1 to get an AutoIP address very quickly, but you should
+ * be prepared to handle a changing IP address when DHCP overrides
+ * AutoIP.
+ */
+#ifndef LWIP_DHCP_AUTOIP_COOP_TRIES
+#define LWIP_DHCP_AUTOIP_COOP_TRIES     9
+#endif
+
+/*
+   ----------------------------------
+   ---------- SNMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP
+ * transport.
+ */
+#ifndef LWIP_SNMP
+#define LWIP_SNMP                       0
+#endif
+
+/**
+ * SNMP_CONCURRENT_REQUESTS: Number of concurrent requests the module will
+ * allow. At least one request buffer is required.
+ * Does not have to be changed unless external MIBs answer request asynchronously
+ */
+#ifndef SNMP_CONCURRENT_REQUESTS
+#define SNMP_CONCURRENT_REQUESTS        1
+#endif
+
+/**
+ * SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap
+ * destination is required
+ */
+#ifndef SNMP_TRAP_DESTINATIONS
+#define SNMP_TRAP_DESTINATIONS          1
+#endif
+
+/**
+ * SNMP_PRIVATE_MIB: 
+ * When using a private MIB, you have to create a file 'private_mib.h' that contains
+ * a 'struct mib_array_node mib_private' which contains your MIB.
+ */
+#ifndef SNMP_PRIVATE_MIB
+#define SNMP_PRIVATE_MIB                0
+#endif
+
+/**
+ * Only allow SNMP write actions that are 'safe' (e.g. disabeling netifs is not
+ * a safe action and disabled when SNMP_SAFE_REQUESTS = 1).
+ * Unsafe requests are disabled by default!
+ */
+#ifndef SNMP_SAFE_REQUESTS
+#define SNMP_SAFE_REQUESTS              1
+#endif
+
+/**
+ * The maximum length of strings used. This affects the size of
+ * MEMP_SNMP_VALUE elements.
+ */
+#ifndef SNMP_MAX_OCTET_STRING_LEN
+#define SNMP_MAX_OCTET_STRING_LEN       127
+#endif
+
+/**
+ * The maximum depth of the SNMP tree.
+ * With private MIBs enabled, this depends on your MIB!
+ * This affects the size of MEMP_SNMP_VALUE elements.
+ */
+#ifndef SNMP_MAX_TREE_DEPTH
+#define SNMP_MAX_TREE_DEPTH             15
+#endif
+
+/**
+ * The size of the MEMP_SNMP_VALUE elements, normally calculated from
+ * SNMP_MAX_OCTET_STRING_LEN and SNMP_MAX_TREE_DEPTH.
+ */
+#ifndef SNMP_MAX_VALUE_SIZE
+#define SNMP_MAX_VALUE_SIZE             LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN)+1, sizeof(s32_t)*(SNMP_MAX_TREE_DEPTH))
+#endif
+
+/*
+   ----------------------------------
+   ---------- IGMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_IGMP==1: Turn on IGMP module. 
+ */
+#ifndef LWIP_IGMP
+#define LWIP_IGMP                       0
+#endif
+
+/*
+   ----------------------------------
+   ---------- DNS options -----------
+   ----------------------------------
+*/
+/**
+ * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS
+ * transport.
+ */
+#ifndef LWIP_DNS
+#define LWIP_DNS                        0
+#endif
+
+/** DNS maximum number of entries to maintain locally. */
+#ifndef DNS_TABLE_SIZE
+#define DNS_TABLE_SIZE                  4
+#endif
+
+/** DNS maximum host name length supported in the name table. */
+#ifndef DNS_MAX_NAME_LENGTH
+#define DNS_MAX_NAME_LENGTH             256
+#endif
+
+/** The maximum of DNS servers */
+#ifndef DNS_MAX_SERVERS
+#define DNS_MAX_SERVERS                 2
+#endif
+
+/** DNS do a name checking between the query and the response. */
+#ifndef DNS_DOES_NAME_CHECK
+#define DNS_DOES_NAME_CHECK             1
+#endif
+
+/** DNS message max. size. Default value is RFC compliant. */
+#ifndef DNS_MSG_SIZE
+#define DNS_MSG_SIZE                    512
+#endif
+
+/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled,
+ *  you have to define
+ *    #define DNS_LOCAL_HOSTLIST_INIT {{"host1", 0x123}, {"host2", 0x234}}
+ *  (an array of structs name/address, where address is an u32_t in network
+ *  byte order).
+ *
+ *  Instead, you can also use an external function:
+ *  #define DNS_LOOKUP_LOCAL_EXTERN(x) extern u32_t my_lookup_function(const char *name)
+ *  that returns the IP address or INADDR_NONE if not found.
+ */
+#ifndef DNS_LOCAL_HOSTLIST
+#define DNS_LOCAL_HOSTLIST              0
+#endif /* DNS_LOCAL_HOSTLIST */
+
+/** If this is turned on, the local host-list can be dynamically changed
+ *  at runtime. */
+#ifndef DNS_LOCAL_HOSTLIST_IS_DYNAMIC
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC   0
+#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
+
+/*
+   ---------------------------------
+   ---------- UDP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_UDP==1: Turn on UDP.
+ */
+#ifndef LWIP_UDP
+#define LWIP_UDP                        1
+#endif
+
+/**
+ * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP)
+ */
+#ifndef LWIP_UDPLITE
+#define LWIP_UDPLITE                    0
+#endif
+
+/**
+ * UDP_TTL: Default Time-To-Live value.
+ */
+#ifndef UDP_TTL
+#define UDP_TTL                         (IP_DEFAULT_TTL)
+#endif
+
+/**
+ * LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf.
+ */
+#ifndef LWIP_NETBUF_RECVINFO
+#define LWIP_NETBUF_RECVINFO            0
+#endif
+
+/*
+   ---------------------------------
+   ---------- TCP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_TCP==1: Turn on TCP.
+ */
+#ifndef LWIP_TCP
+#define LWIP_TCP                        1
+#endif
+
+/**
+ * TCP_TTL: Default Time-To-Live value.
+ */
+#ifndef TCP_TTL
+#define TCP_TTL                         (IP_DEFAULT_TTL)
+#endif
+
+/**
+ * TCP_WND: The size of a TCP window.  This must be at least 
+ * (2 * TCP_MSS) for things to work well
+ */
+#ifndef TCP_WND
+#define TCP_WND                         (4 * TCP_MSS)
+#endif 
+
+/**
+ * TCP_MAXRTX: Maximum number of retransmissions of data segments.
+ */
+#ifndef TCP_MAXRTX
+#define TCP_MAXRTX                      12
+#endif
+
+/**
+ * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments.
+ */
+#ifndef TCP_SYNMAXRTX
+#define TCP_SYNMAXRTX                   6
+#endif
+
+/**
+ * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order.
+ * Define to 0 if your device is low on memory.
+ */
+#ifndef TCP_QUEUE_OOSEQ
+#define TCP_QUEUE_OOSEQ                 (LWIP_TCP)
+#endif
+
+/**
+ * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default,
+ * you might want to increase this.)
+ * For the receive side, this MSS is advertised to the remote side
+ * when opening a connection. For the transmit size, this MSS sets
+ * an upper limit on the MSS advertised by the remote host.
+ */
+#ifndef TCP_MSS
+#define TCP_MSS                         536
+#endif
+
+/**
+ * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really
+ * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which
+ * reflects the available reassembly buffer size at the remote host) and the
+ * largest size permitted by the IP layer" (RFC 1122)
+ * Setting this to 1 enables code that checks TCP_MSS against the MTU of the
+ * netif used for a connection and limits the MSS if it would be too big otherwise.
+ */
+#ifndef TCP_CALCULATE_EFF_SEND_MSS
+#define TCP_CALCULATE_EFF_SEND_MSS      1
+#endif
+
+
+/**
+ * TCP_SND_BUF: TCP sender buffer space (bytes).
+ * To achieve good performance, this should be at least 2 * TCP_MSS.
+ */
+#ifndef TCP_SND_BUF
+#define TCP_SND_BUF                     (2 * TCP_MSS)
+#endif
+
+/**
+ * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
+ * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work.
+ */
+#ifndef TCP_SND_QUEUELEN
+#define TCP_SND_QUEUELEN                ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#endif
+
+/**
+ * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than
+ * TCP_SND_BUF. It is the amount of space which must be available in the
+ * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT).
+ */
+#ifndef TCP_SNDLOWAT
+#define TCP_SNDLOWAT                    LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#endif
+
+/**
+ * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be less
+ * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below
+ * this number, select returns writable (combined with TCP_SNDLOWAT).
+ */
+#ifndef TCP_SNDQUEUELOWAT
+#define TCP_SNDQUEUELOWAT               LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#endif
+
+/**
+ * TCP_OOSEQ_MAX_BYTES: The maximum number of bytes queued on ooseq per pcb.
+ * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0.
+ */
+#ifndef TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_BYTES             0
+#endif
+
+/**
+ * TCP_OOSEQ_MAX_PBUFS: The maximum number of pbufs queued on ooseq per pcb.
+ * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0.
+ */
+#ifndef TCP_OOSEQ_MAX_PBUFS
+#define TCP_OOSEQ_MAX_PBUFS             0
+#endif
+
+/**
+ * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb.
+ */
+#ifndef TCP_LISTEN_BACKLOG
+#define TCP_LISTEN_BACKLOG              0
+#endif
+
+/**
+ * The maximum allowed backlog for TCP listen netconns.
+ * This backlog is used unless another is explicitly specified.
+ * 0xff is the maximum (u8_t).
+ */
+#ifndef TCP_DEFAULT_LISTEN_BACKLOG
+#define TCP_DEFAULT_LISTEN_BACKLOG      0xff
+#endif
+
+/**
+ * TCP_OVERSIZE: The maximum number of bytes that tcp_write may
+ * allocate ahead of time in an attempt to create shorter pbuf chains
+ * for transmission. The meaningful range is 0 to TCP_MSS. Some
+ * suggested values are:
+ *
+ * 0:         Disable oversized allocation. Each tcp_write() allocates a new
+              pbuf (old behaviour).
+ * 1:         Allocate size-aligned pbufs with minimal excess. Use this if your
+ *            scatter-gather DMA requires aligned fragments.
+ * 128:       Limit the pbuf/memory overhead to 20%.
+ * TCP_MSS:   Try to create unfragmented TCP packets.
+ * TCP_MSS/4: Try to create 4 fragments or less per TCP packet.
+ */
+#ifndef TCP_OVERSIZE
+#define TCP_OVERSIZE                    TCP_MSS
+#endif
+
+/**
+ * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option.
+ */
+#ifndef LWIP_TCP_TIMESTAMPS
+#define LWIP_TCP_TIMESTAMPS             0
+#endif
+
+/**
+ * TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an
+ * explicit window update
+ */
+#ifndef TCP_WND_UPDATE_THRESHOLD
+#define TCP_WND_UPDATE_THRESHOLD   (TCP_WND / 4)
+#endif
+
+/**
+ * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1.
+ *     LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all
+ *         events (accept, sent, etc) that happen in the system.
+ *     LWIP_CALLBACK_API==1: The PCB callback function is called directly
+ *         for the event. This is the default.
+ */
+#if !defined(LWIP_EVENT_API) && !defined(LWIP_CALLBACK_API)
+#define LWIP_EVENT_API                  0
+#define LWIP_CALLBACK_API               1
+#endif
+
+
+/*
+   ----------------------------------
+   ---------- Pbuf options ----------
+   ----------------------------------
+*/
+/**
+ * PBUF_LINK_HLEN: the number of bytes that should be allocated for a
+ * link level header. The default is 14, the standard value for
+ * Ethernet.
+ */
+#ifndef PBUF_LINK_HLEN
+#define PBUF_LINK_HLEN                  (14 + ETH_PAD_SIZE)
+#endif
+
+/**
+ * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is
+ * designed to accomodate single full size TCP frame in one pbuf, including
+ * TCP_MSS, IP header, and link header.
+ */
+#ifndef PBUF_POOL_BUFSIZE
+#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN)
+#endif
+
+/*
+   ------------------------------------------------
+   ---------- Network Interfaces options ----------
+   ------------------------------------------------
+*/
+/**
+ * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname
+ * field.
+ */
+#ifndef LWIP_NETIF_HOSTNAME
+#define LWIP_NETIF_HOSTNAME             0
+#endif
+
+/**
+ * LWIP_NETIF_API==1: Support netif api (in netifapi.c)
+ */
+#ifndef LWIP_NETIF_API
+#define LWIP_NETIF_API                  0
+#endif
+
+/**
+ * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface
+ * changes its up/down status (i.e., due to DHCP IP acquistion)
+ */
+#ifndef LWIP_NETIF_STATUS_CALLBACK
+#define LWIP_NETIF_STATUS_CALLBACK      0
+#endif
+
+/**
+ * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface
+ * whenever the link changes (i.e., link down)
+ */
+#ifndef LWIP_NETIF_LINK_CALLBACK
+#define LWIP_NETIF_LINK_CALLBACK        0
+#endif
+
+/**
+ * LWIP_NETIF_REMOVE_CALLBACK==1: Support a callback function that is called
+ * when a netif has been removed
+ */
+#ifndef LWIP_NETIF_REMOVE_CALLBACK
+#define LWIP_NETIF_REMOVE_CALLBACK      0
+#endif
+
+/**
+ * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table
+ * indices) in struct netif. TCP and UDP can make use of this to prevent
+ * scanning the ARP table for every sent packet. While this is faster for big
+ * ARP tables or many concurrent connections, it might be counterproductive
+ * if you have a tiny ARP table or if there never are concurrent connections.
+ */
+#ifndef LWIP_NETIF_HWADDRHINT
+#define LWIP_NETIF_HWADDRHINT           0
+#endif
+
+/**
+ * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP
+ * address equal to the netif IP address, looping them back up the stack.
+ */
+#ifndef LWIP_NETIF_LOOPBACK
+#define LWIP_NETIF_LOOPBACK             0
+#endif
+
+/**
+ * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback
+ * sending for each netif (0 = disabled)
+ */
+#ifndef LWIP_LOOPBACK_MAX_PBUFS
+#define LWIP_LOOPBACK_MAX_PBUFS         0
+#endif
+
+/**
+ * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in
+ * the system, as netifs must change how they behave depending on this setting
+ * for the LWIP_NETIF_LOOPBACK option to work.
+ * Setting this is needed to avoid reentering non-reentrant functions like
+ * tcp_input().
+ *    LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a
+ *       multithreaded environment like tcpip.c. In this case, netif->input()
+ *       is called directly.
+ *    LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup.
+ *       The packets are put on a list and netif_poll() must be called in
+ *       the main application loop.
+ */
+#ifndef LWIP_NETIF_LOOPBACK_MULTITHREADING
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING    (!NO_SYS)
+#endif
+
+/**
+ * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data
+ * to be sent into one single pbuf. This is for compatibility with DMA-enabled
+ * MACs that do not support scatter-gather.
+ * Beware that this might involve CPU-memcpy before transmitting that would not
+ * be needed without this flag! Use this only if you need to!
+ *
+ * @todo: TCP and IP-frag do not work with this, yet:
+ */
+#ifndef LWIP_NETIF_TX_SINGLE_PBUF
+#define LWIP_NETIF_TX_SINGLE_PBUF             0
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
+
+/*
+   ------------------------------------
+   ---------- LOOPIF options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c
+ */
+#ifndef LWIP_HAVE_LOOPIF
+#define LWIP_HAVE_LOOPIF                0
+#endif
+
+/*
+   ------------------------------------
+   ---------- SLIPIF options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_HAVE_SLIPIF==1: Support slip interface and slipif.c
+ */
+#ifndef LWIP_HAVE_SLIPIF
+#define LWIP_HAVE_SLIPIF                0
+#endif
+
+/*
+   ------------------------------------
+   ---------- Thread options ----------
+   ------------------------------------
+*/
+/**
+ * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread.
+ */
+#ifndef TCPIP_THREAD_NAME
+#define TCPIP_THREAD_NAME              "tcpip_thread"
+#endif
+
+/**
+ * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread.
+ * The stack size value itself is platform-dependent, but is passed to
+ * sys_thread_new() when the thread is created.
+ */
+#ifndef TCPIP_THREAD_STACKSIZE
+#define TCPIP_THREAD_STACKSIZE          0
+#endif
+
+/**
+ * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread.
+ * The priority value itself is platform-dependent, but is passed to
+ * sys_thread_new() when the thread is created.
+ */
+#ifndef TCPIP_THREAD_PRIO
+#define TCPIP_THREAD_PRIO               1
+#endif
+
+/**
+ * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages
+ * The queue size value itself is platform-dependent, but is passed to
+ * sys_mbox_new() when tcpip_init is called.
+ */
+#ifndef TCPIP_MBOX_SIZE
+#define TCPIP_MBOX_SIZE                 0
+#endif
+
+/**
+ * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread.
+ */
+#ifndef SLIPIF_THREAD_NAME
+#define SLIPIF_THREAD_NAME             "slipif_loop"
+#endif
+
+/**
+ * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread.
+ * The stack size value itself is platform-dependent, but is passed to
+ * sys_thread_new() when the thread is created.
+ */
+#ifndef SLIPIF_THREAD_STACKSIZE
+#define SLIPIF_THREAD_STACKSIZE         0
+#endif
+
+/**
+ * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread.
+ * The priority value itself is platform-dependent, but is passed to
+ * sys_thread_new() when the thread is created.
+ */
+#ifndef SLIPIF_THREAD_PRIO
+#define SLIPIF_THREAD_PRIO              1
+#endif
+
+/**
+ * PPP_THREAD_NAME: The name assigned to the pppInputThread.
+ */
+#ifndef PPP_THREAD_NAME
+#define PPP_THREAD_NAME                "pppInputThread"
+#endif
+
+/**
+ * PPP_THREAD_STACKSIZE: The stack size used by the pppInputThread.
+ * The stack size value itself is platform-dependent, but is passed to
+ * sys_thread_new() when the thread is created.
+ */
+#ifndef PPP_THREAD_STACKSIZE
+#define PPP_THREAD_STACKSIZE            0
+#endif
+
+/**
+ * PPP_THREAD_PRIO: The priority assigned to the pppInputThread.
+ * The priority value itself is platform-dependent, but is passed to
+ * sys_thread_new() when the thread is created.
+ */
+#ifndef PPP_THREAD_PRIO
+#define PPP_THREAD_PRIO                 1
+#endif
+
+/**
+ * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread.
+ */
+#ifndef DEFAULT_THREAD_NAME
+#define DEFAULT_THREAD_NAME            "lwIP"
+#endif
+
+/**
+ * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread.
+ * The stack size value itself is platform-dependent, but is passed to
+ * sys_thread_new() when the thread is created.
+ */
+#ifndef DEFAULT_THREAD_STACKSIZE
+#define DEFAULT_THREAD_STACKSIZE        0
+#endif
+
+/**
+ * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread.
+ * The priority value itself is platform-dependent, but is passed to
+ * sys_thread_new() when the thread is created.
+ */
+#ifndef DEFAULT_THREAD_PRIO
+#define DEFAULT_THREAD_PRIO             1
+#endif
+
+/**
+ * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
+ * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed
+ * to sys_mbox_new() when the recvmbox is created.
+ */
+#ifndef DEFAULT_RAW_RECVMBOX_SIZE
+#define DEFAULT_RAW_RECVMBOX_SIZE       0
+#endif
+
+/**
+ * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
+ * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed
+ * to sys_mbox_new() when the recvmbox is created.
+ */
+#ifndef DEFAULT_UDP_RECVMBOX_SIZE
+#define DEFAULT_UDP_RECVMBOX_SIZE       0
+#endif
+
+/**
+ * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
+ * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed
+ * to sys_mbox_new() when the recvmbox is created.
+ */
+#ifndef DEFAULT_TCP_RECVMBOX_SIZE
+#define DEFAULT_TCP_RECVMBOX_SIZE       0
+#endif
+
+/**
+ * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections.
+ * The queue size value itself is platform-dependent, but is passed to
+ * sys_mbox_new() when the acceptmbox is created.
+ */
+#ifndef DEFAULT_ACCEPTMBOX_SIZE
+#define DEFAULT_ACCEPTMBOX_SIZE         0
+#endif
+
+/*
+   ----------------------------------------------
+   ---------- Sequential layer options ----------
+   ----------------------------------------------
+*/
+/**
+ * LWIP_TCPIP_CORE_LOCKING: (EXPERIMENTAL!)
+ * Don't use it if you're not an active lwIP project member
+ */
+#ifndef LWIP_TCPIP_CORE_LOCKING
+#define LWIP_TCPIP_CORE_LOCKING         0
+#endif
+
+/**
+ * LWIP_TCPIP_CORE_LOCKING_INPUT: (EXPERIMENTAL!)
+ * Don't use it if you're not an active lwIP project member
+ */
+#ifndef LWIP_TCPIP_CORE_LOCKING_INPUT
+#define LWIP_TCPIP_CORE_LOCKING_INPUT   0
+#endif
+
+/**
+ * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
+ */
+#ifndef LWIP_NETCONN
+#define LWIP_NETCONN                    1
+#endif
+
+/** LWIP_TCPIP_TIMEOUT==1: Enable tcpip_timeout/tcpip_untimeout tod create
+ * timers running in tcpip_thread from another thread.
+ */
+#ifndef LWIP_TCPIP_TIMEOUT
+#define LWIP_TCPIP_TIMEOUT              1
+#endif
+
+/*
+   ------------------------------------
+   ---------- Socket options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
+ */
+#ifndef LWIP_SOCKET
+#define LWIP_SOCKET                     1
+#endif
+
+/**
+ * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names.
+ * (only used if you use sockets.c)
+ */
+#ifndef LWIP_COMPAT_SOCKETS
+#define LWIP_COMPAT_SOCKETS             1
+#endif
+
+/**
+ * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names.
+ * Disable this option if you use a POSIX operating system that uses the same
+ * names (read, write & close). (only used if you use sockets.c)
+ */
+#ifndef LWIP_POSIX_SOCKETS_IO_NAMES
+#define LWIP_POSIX_SOCKETS_IO_NAMES     1
+#endif
+
+/**
+ * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT
+ * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set
+ * in seconds. (does not require sockets.c, and will affect tcp.c)
+ */
+#ifndef LWIP_TCP_KEEPALIVE
+#define LWIP_TCP_KEEPALIVE              0
+#endif
+
+/**
+ * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and
+ * SO_SNDTIMEO processing.
+ */
+#ifndef LWIP_SO_SNDTIMEO
+#define LWIP_SO_SNDTIMEO                0
+#endif
+
+/**
+ * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and
+ * SO_RCVTIMEO processing.
+ */
+#ifndef LWIP_SO_RCVTIMEO
+#define LWIP_SO_RCVTIMEO                0
+#endif
+
+/**
+ * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing.
+ */
+#ifndef LWIP_SO_RCVBUF
+#define LWIP_SO_RCVBUF                  0
+#endif
+
+/**
+ * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize.
+ */
+#ifndef RECV_BUFSIZE_DEFAULT
+#define RECV_BUFSIZE_DEFAULT            INT_MAX
+#endif
+
+/**
+ * SO_REUSE==1: Enable SO_REUSEADDR option.
+ */
+#ifndef SO_REUSE
+#define SO_REUSE                        0
+#endif
+
+/**
+ * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets
+ * to all local matches if SO_REUSEADDR is turned on.
+ * WARNING: Adds a memcpy for every packet if passing to more than one pcb!
+ */
+#ifndef SO_REUSE_RXTOALL
+#define SO_REUSE_RXTOALL                0
+#endif
+
+/*
+   ----------------------------------------
+   ---------- Statistics options ----------
+   ----------------------------------------
+*/
+/**
+ * LWIP_STATS==1: Enable statistics collection in lwip_stats.
+ */
+#ifndef LWIP_STATS
+#define LWIP_STATS                      1
+#endif
+
+#if LWIP_STATS
+
+/**
+ * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions.
+ */
+#ifndef LWIP_STATS_DISPLAY
+#define LWIP_STATS_DISPLAY              0
+#endif
+
+/**
+ * LINK_STATS==1: Enable link stats.
+ */
+#ifndef LINK_STATS
+#define LINK_STATS                      1
+#endif
+
+/**
+ * ETHARP_STATS==1: Enable etharp stats.
+ */
+#ifndef ETHARP_STATS
+#define ETHARP_STATS                    (LWIP_ARP)
+#endif
+
+/**
+ * IP_STATS==1: Enable IP stats.
+ */
+#ifndef IP_STATS
+#define IP_STATS                        1
+#endif
+
+/**
+ * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is
+ * on if using either frag or reass.
+ */
+#ifndef IPFRAG_STATS
+#define IPFRAG_STATS                    (IP_REASSEMBLY || IP_FRAG)
+#endif
+
+/**
+ * ICMP_STATS==1: Enable ICMP stats.
+ */
+#ifndef ICMP_STATS
+#define ICMP_STATS                      1
+#endif
+
+/**
+ * IGMP_STATS==1: Enable IGMP stats.
+ */
+#ifndef IGMP_STATS
+#define IGMP_STATS                      (LWIP_IGMP)
+#endif
+
+/**
+ * UDP_STATS==1: Enable UDP stats. Default is on if
+ * UDP enabled, otherwise off.
+ */
+#ifndef UDP_STATS
+#define UDP_STATS                       (LWIP_UDP)
+#endif
+
+/**
+ * TCP_STATS==1: Enable TCP stats. Default is on if TCP
+ * enabled, otherwise off.
+ */
+#ifndef TCP_STATS
+#define TCP_STATS                       (LWIP_TCP)
+#endif
+
+/**
+ * MEM_STATS==1: Enable mem.c stats.
+ */
+#ifndef MEM_STATS
+#define MEM_STATS                       ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#endif
+
+/**
+ * MEMP_STATS==1: Enable memp.c pool stats.
+ */
+#ifndef MEMP_STATS
+#define MEMP_STATS                      (MEMP_MEM_MALLOC == 0)
+#endif
+
+/**
+ * SYS_STATS==1: Enable system stats (sem and mbox counts, etc).
+ */
+#ifndef SYS_STATS
+#define SYS_STATS                       (NO_SYS == 0)
+#endif
+
+#else
+
+#define LINK_STATS                      0
+#define IP_STATS                        0
+#define IPFRAG_STATS                    0
+#define ICMP_STATS                      0
+#define IGMP_STATS                      0
+#define UDP_STATS                       0
+#define TCP_STATS                       0
+#define MEM_STATS                       0
+#define MEMP_STATS                      0
+#define SYS_STATS                       0
+#define LWIP_STATS_DISPLAY              0
+
+#endif /* LWIP_STATS */
+
+/*
+   ---------------------------------
+   ---------- PPP options ----------
+   ---------------------------------
+*/
+/**
+ * PPP_SUPPORT==1: Enable PPP.
+ */
+#ifndef PPP_SUPPORT
+#define PPP_SUPPORT                     0
+#endif
+
+/**
+ * PPPOE_SUPPORT==1: Enable PPP Over Ethernet
+ */
+#ifndef PPPOE_SUPPORT
+#define PPPOE_SUPPORT                   0
+#endif
+
+/**
+ * PPPOS_SUPPORT==1: Enable PPP Over Serial
+ */
+#ifndef PPPOS_SUPPORT
+#define PPPOS_SUPPORT                   PPP_SUPPORT
+#endif
+
+#if PPP_SUPPORT
+
+/**
+ * NUM_PPP: Max PPP sessions.
+ */
+#ifndef NUM_PPP
+#define NUM_PPP                         1
+#endif
+
+/**
+ * PAP_SUPPORT==1: Support PAP.
+ */
+#ifndef PAP_SUPPORT
+#define PAP_SUPPORT                     0
+#endif
+
+/**
+ * CHAP_SUPPORT==1: Support CHAP.
+ */
+#ifndef CHAP_SUPPORT
+#define CHAP_SUPPORT                    0
+#endif
+
+/**
+ * MSCHAP_SUPPORT==1: Support MSCHAP. CURRENTLY NOT SUPPORTED! DO NOT SET!
+ */
+#ifndef MSCHAP_SUPPORT
+#define MSCHAP_SUPPORT                  0
+#endif
+
+/**
+ * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET!
+ */
+#ifndef CBCP_SUPPORT
+#define CBCP_SUPPORT                    0
+#endif
+
+/**
+ * CCP_SUPPORT==1: Support CCP. CURRENTLY NOT SUPPORTED! DO NOT SET!
+ */
+#ifndef CCP_SUPPORT
+#define CCP_SUPPORT                     0
+#endif
+
+/**
+ * VJ_SUPPORT==1: Support VJ header compression.
+ */
+#ifndef VJ_SUPPORT
+#define VJ_SUPPORT                      0
+#endif
+
+/**
+ * MD5_SUPPORT==1: Support MD5 (see also CHAP).
+ */
+#ifndef MD5_SUPPORT
+#define MD5_SUPPORT                     0
+#endif
+
+/*
+ * Timeouts
+ */
+#ifndef FSM_DEFTIMEOUT
+#define FSM_DEFTIMEOUT                  6       /* Timeout time in seconds */
+#endif
+
+#ifndef FSM_DEFMAXTERMREQS
+#define FSM_DEFMAXTERMREQS              2       /* Maximum Terminate-Request transmissions */
+#endif
+
+#ifndef FSM_DEFMAXCONFREQS
+#define FSM_DEFMAXCONFREQS              10      /* Maximum Configure-Request transmissions */
+#endif
+
+#ifndef FSM_DEFMAXNAKLOOPS
+#define FSM_DEFMAXNAKLOOPS              5       /* Maximum number of nak loops */
+#endif
+
+#ifndef UPAP_DEFTIMEOUT
+#define UPAP_DEFTIMEOUT                 6       /* Timeout (seconds) for retransmitting req */
+#endif
+
+#ifndef UPAP_DEFREQTIME
+#define UPAP_DEFREQTIME                 30      /* Time to wait for auth-req from peer */
+#endif
+
+#ifndef CHAP_DEFTIMEOUT
+#define CHAP_DEFTIMEOUT                 6       /* Timeout time in seconds */
+#endif
+
+#ifndef CHAP_DEFTRANSMITS
+#define CHAP_DEFTRANSMITS               10      /* max # times to send challenge */
+#endif
+
+/* Interval in seconds between keepalive echo requests, 0 to disable. */
+#ifndef LCP_ECHOINTERVAL
+#define LCP_ECHOINTERVAL                0
+#endif
+
+/* Number of unanswered echo requests before failure. */
+#ifndef LCP_MAXECHOFAILS
+#define LCP_MAXECHOFAILS                3
+#endif
+
+/* Max Xmit idle time (in jiffies) before resend flag char. */
+#ifndef PPP_MAXIDLEFLAG
+#define PPP_MAXIDLEFLAG                 100
+#endif
+
+/*
+ * Packet sizes
+ *
+ * Note - lcp shouldn't be allowed to negotiate stuff outside these
+ *    limits.  See lcp.h in the pppd directory.
+ * (XXX - these constants should simply be shared by lcp.c instead
+ *    of living in lcp.h)
+ */
+#define PPP_MTU                         1500     /* Default MTU (size of Info field) */
+#ifndef PPP_MAXMTU
+/* #define PPP_MAXMTU  65535 - (PPP_HDRLEN + PPP_FCSLEN) */
+#define PPP_MAXMTU                      1500 /* Largest MTU we allow */
+#endif
+#define PPP_MINMTU                      64
+#define PPP_MRU                         1500     /* default MRU = max length of info field */
+#define PPP_MAXMRU                      1500     /* Largest MRU we allow */
+#ifndef PPP_DEFMRU
+#define PPP_DEFMRU                      296             /* Try for this */
+#endif
+#define PPP_MINMRU                      128             /* No MRUs below this */
+
+#ifndef MAXNAMELEN
+#define MAXNAMELEN                      256     /* max length of hostname or name for auth */
+#endif
+#ifndef MAXSECRETLEN
+#define MAXSECRETLEN                    256     /* max length of password or secret */
+#endif
+
+#endif /* PPP_SUPPORT */
+
+/*
+   --------------------------------------
+   ---------- Checksum options ----------
+   --------------------------------------
+*/
+/**
+ * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.
+ */
+#ifndef CHECKSUM_GEN_IP
+#define CHECKSUM_GEN_IP                 1
+#endif
+ 
+/**
+ * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.
+ */
+#ifndef CHECKSUM_GEN_UDP
+#define CHECKSUM_GEN_UDP                1
+#endif
+ 
+/**
+ * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.
+ */
+#ifndef CHECKSUM_GEN_TCP
+#define CHECKSUM_GEN_TCP                1
+#endif
+
+/**
+ * CHECKSUM_GEN_ICMP==1: Generate checksums in software for outgoing ICMP packets.
+ */
+#ifndef CHECKSUM_GEN_ICMP
+#define CHECKSUM_GEN_ICMP               1
+#endif
+ 
+/**
+ * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.
+ */
+#ifndef CHECKSUM_CHECK_IP
+#define CHECKSUM_CHECK_IP               1
+#endif
+ 
+/**
+ * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.
+ */
+#ifndef CHECKSUM_CHECK_UDP
+#define CHECKSUM_CHECK_UDP              1
+#endif
+
+/**
+ * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.
+ */
+#ifndef CHECKSUM_CHECK_TCP
+#define CHECKSUM_CHECK_TCP              1
+#endif
+
+/**
+ * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from
+ * application buffers to pbufs.
+ */
+#ifndef LWIP_CHECKSUM_ON_COPY
+#define LWIP_CHECKSUM_ON_COPY           0
+#endif
+
+/*
+   ---------------------------------------
+   ---------- Hook options ---------------
+   ---------------------------------------
+*/
+
+/* Hooks are undefined by default, define them to a function if you need them. */
+
+/**
+ * LWIP_HOOK_IP4_INPUT(pbuf, input_netif):
+ * - called from ip_input() (IPv4)
+ * - pbuf: received struct pbuf passed to ip_input()
+ * - input_netif: struct netif on which the packet has been received
+ * Return values:
+ * - 0: Hook has not consumed the packet, packet is processed as normal
+ * - != 0: Hook has consumed the packet.
+ * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook
+ * (i.e. free it when done).
+ */
+
+/**
+ * LWIP_HOOK_IP4_ROUTE(dest):
+ * - called from ip_route() (IPv4)
+ * - dest: destination IPv4 address
+ * Returns the destination netif or NULL if no destination netif is found. In
+ * that case, ip_route() continues as normal.
+ */
+
+/*
+   ---------------------------------------
+   ---------- Debugging options ----------
+   ---------------------------------------
+*/
+/**
+ * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is
+ * compared against this value. If it is smaller, then debugging
+ * messages are written.
+ */
+#ifndef LWIP_DBG_MIN_LEVEL
+#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_ALL
+#endif
+
+/**
+ * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable
+ * debug messages of certain types.
+ */
+#ifndef LWIP_DBG_TYPES_ON
+#define LWIP_DBG_TYPES_ON               LWIP_DBG_ON
+#endif
+
+/**
+ * ETHARP_DEBUG: Enable debugging in etharp.c.
+ */
+#ifndef ETHARP_DEBUG
+#define ETHARP_DEBUG                    LWIP_DBG_OFF
+#endif
+
+/**
+ * NETIF_DEBUG: Enable debugging in netif.c.
+ */
+#ifndef NETIF_DEBUG
+#define NETIF_DEBUG                     LWIP_DBG_OFF
+#endif
+
+/**
+ * PBUF_DEBUG: Enable debugging in pbuf.c.
+ */
+#ifndef PBUF_DEBUG
+#define PBUF_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * API_LIB_DEBUG: Enable debugging in api_lib.c.
+ */
+#ifndef API_LIB_DEBUG
+#define API_LIB_DEBUG                   LWIP_DBG_OFF
+#endif
+
+/**
+ * API_MSG_DEBUG: Enable debugging in api_msg.c.
+ */
+#ifndef API_MSG_DEBUG
+#define API_MSG_DEBUG                   LWIP_DBG_OFF
+#endif
+
+/**
+ * SOCKETS_DEBUG: Enable debugging in sockets.c.
+ */
+#ifndef SOCKETS_DEBUG
+#define SOCKETS_DEBUG                   LWIP_DBG_OFF
+#endif
+
+/**
+ * ICMP_DEBUG: Enable debugging in icmp.c.
+ */
+#ifndef ICMP_DEBUG
+#define ICMP_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * IGMP_DEBUG: Enable debugging in igmp.c.
+ */
+#ifndef IGMP_DEBUG
+#define IGMP_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * INET_DEBUG: Enable debugging in inet.c.
+ */
+#ifndef INET_DEBUG
+#define INET_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * IP_DEBUG: Enable debugging for IP.
+ */
+#ifndef IP_DEBUG
+#define IP_DEBUG                        LWIP_DBG_OFF
+#endif
+
+/**
+ * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass.
+ */
+#ifndef IP_REASS_DEBUG
+#define IP_REASS_DEBUG                  LWIP_DBG_OFF
+#endif
+
+/**
+ * RAW_DEBUG: Enable debugging in raw.c.
+ */
+#ifndef RAW_DEBUG
+#define RAW_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * MEM_DEBUG: Enable debugging in mem.c.
+ */
+#ifndef MEM_DEBUG
+#define MEM_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * MEMP_DEBUG: Enable debugging in memp.c.
+ */
+#ifndef MEMP_DEBUG
+#define MEMP_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * SYS_DEBUG: Enable debugging in sys.c.
+ */
+#ifndef SYS_DEBUG
+#define SYS_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * TIMERS_DEBUG: Enable debugging in timers.c.
+ */
+#ifndef TIMERS_DEBUG
+#define TIMERS_DEBUG                    LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_DEBUG: Enable debugging for TCP.
+ */
+#ifndef TCP_DEBUG
+#define TCP_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug.
+ */
+#ifndef TCP_INPUT_DEBUG
+#define TCP_INPUT_DEBUG                 LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit.
+ */
+#ifndef TCP_FR_DEBUG
+#define TCP_FR_DEBUG                    LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit
+ * timeout.
+ */
+#ifndef TCP_RTO_DEBUG
+#define TCP_RTO_DEBUG                   LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_CWND_DEBUG: Enable debugging for TCP congestion window.
+ */
+#ifndef TCP_CWND_DEBUG
+#define TCP_CWND_DEBUG                  LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating.
+ */
+#ifndef TCP_WND_DEBUG
+#define TCP_WND_DEBUG                   LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions.
+ */
+#ifndef TCP_OUTPUT_DEBUG
+#define TCP_OUTPUT_DEBUG                LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_RST_DEBUG: Enable debugging for TCP with the RST message.
+ */
+#ifndef TCP_RST_DEBUG
+#define TCP_RST_DEBUG                   LWIP_DBG_OFF
+#endif
+
+/**
+ * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths.
+ */
+#ifndef TCP_QLEN_DEBUG
+#define TCP_QLEN_DEBUG                  LWIP_DBG_OFF
+#endif
+
+/**
+ * UDP_DEBUG: Enable debugging in UDP.
+ */
+#ifndef UDP_DEBUG
+#define UDP_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * TCPIP_DEBUG: Enable debugging in tcpip.c.
+ */
+#ifndef TCPIP_DEBUG
+#define TCPIP_DEBUG                     LWIP_DBG_OFF
+#endif
+
+/**
+ * PPP_DEBUG: Enable debugging for PPP.
+ */
+#ifndef PPP_DEBUG
+#define PPP_DEBUG                       LWIP_DBG_OFF
+#endif
+
+/**
+ * SLIP_DEBUG: Enable debugging in slipif.c.
+ */
+#ifndef SLIP_DEBUG
+#define SLIP_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * DHCP_DEBUG: Enable debugging in dhcp.c.
+ */
+#ifndef DHCP_DEBUG
+#define DHCP_DEBUG                      LWIP_DBG_OFF
+#endif
+
+/**
+ * AUTOIP_DEBUG: Enable debugging in autoip.c.
+ */
+#ifndef AUTOIP_DEBUG
+#define AUTOIP_DEBUG                    LWIP_DBG_OFF
+#endif
+
+/**
+ * SNMP_MSG_DEBUG: Enable debugging for SNMP messages.
+ */
+#ifndef SNMP_MSG_DEBUG
+#define SNMP_MSG_DEBUG                  LWIP_DBG_OFF
+#endif
+
+/**
+ * SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs.
+ */
+#ifndef SNMP_MIB_DEBUG
+#define SNMP_MIB_DEBUG                  LWIP_DBG_OFF
+#endif
+
+/**
+ * DNS_DEBUG: Enable debugging for DNS.
+ */
+#ifndef DNS_DEBUG
+#define DNS_DEBUG                       LWIP_DBG_OFF
+#endif
+
+#endif /* __LWIP_OPT_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/pbuf.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/pbuf.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/pbuf.h	(revision 164)
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __LWIP_PBUF_H__
+#define __LWIP_PBUF_H__
+
+#include "lwip/opt.h"
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Currently, the pbuf_custom code is only needed for one specific configuration
+ * of IP_FRAG */
+#define LWIP_SUPPORT_CUSTOM_PBUF (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF)
+
+#define PBUF_TRANSPORT_HLEN 20
+#define PBUF_IP_HLEN        20
+
+typedef enum {
+  PBUF_TRANSPORT,
+  PBUF_IP,
+  PBUF_LINK,
+  PBUF_RAW
+} pbuf_layer;
+
+typedef enum {
+  PBUF_RAM, /* pbuf data is stored in RAM */
+  PBUF_ROM, /* pbuf data is stored in ROM */
+  PBUF_REF, /* pbuf comes from the pbuf pool */
+  PBUF_POOL /* pbuf payload refers to RAM */
+} pbuf_type;
+
+
+/** indicates this packet's data should be immediately passed to the application */
+#define PBUF_FLAG_PUSH      0x01U
+/** indicates this is a custom pbuf: pbuf_free and pbuf_header handle such a
+    a pbuf differently */
+#define PBUF_FLAG_IS_CUSTOM 0x02U
+/** indicates this pbuf is UDP multicast to be looped back */
+#define PBUF_FLAG_MCASTLOOP 0x04U
+/** indicates this pbuf was received as link-level broadcast */
+#define PBUF_FLAG_LLBCAST   0x08U
+/** indicates this pbuf was received as link-level multicast */
+#define PBUF_FLAG_LLMCAST   0x10U
+/** indicates this pbuf includes a TCP FIN flag */
+#define PBUF_FLAG_TCP_FIN   0x20U
+
+struct pbuf {
+  /** next pbuf in singly linked pbuf chain */
+  struct pbuf *next;
+
+  /** pointer to the actual data in the buffer */
+  void *payload;
+
+  /**
+   * total length of this buffer and all next buffers in chain
+   * belonging to the same packet.
+   *
+   * For non-queue packet chains this is the invariant:
+   * p->tot_len == p->len + (p->next? p->next->tot_len: 0)
+   */
+  u16_t tot_len;
+
+  /** length of this buffer */
+  u16_t len;
+
+  /** pbuf_type as u8_t instead of enum to save space */
+  u8_t /*pbuf_type*/ type;
+
+  /** misc flags */
+  u8_t flags;
+
+  /**
+   * the reference count always equals the number of pointers
+   * that refer to this pbuf. This can be pointers from an application,
+   * the stack itself, or pbuf->next pointers from a chain.
+   */
+  u16_t ref;
+};
+
+#if LWIP_SUPPORT_CUSTOM_PBUF
+/** Prototype for a function to free a custom pbuf */
+typedef void (*pbuf_free_custom_fn)(struct pbuf *p);
+
+/** A custom pbuf: like a pbuf, but following a function pointer to free it. */
+struct pbuf_custom {
+  /** The actual pbuf */
+  struct pbuf pbuf;
+  /** This function is called when pbuf_free deallocates this pbuf(_custom) */
+  pbuf_free_custom_fn custom_free_function;
+};
+#endif /* LWIP_SUPPORT_CUSTOM_PBUF */
+
+#if LWIP_TCP && TCP_QUEUE_OOSEQ
+/** Define this to 0 to prevent freeing ooseq pbufs when the PBUF_POOL is empty */
+#ifndef PBUF_POOL_FREE_OOSEQ
+#define PBUF_POOL_FREE_OOSEQ 1
+#endif /* PBUF_POOL_FREE_OOSEQ */
+#if NO_SYS && PBUF_POOL_FREE_OOSEQ
+extern volatile u8_t pbuf_free_ooseq_pending;
+void pbuf_free_ooseq();
+/** When not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ()
+    at regular intervals from main level to check if ooseq pbufs need to be
+    freed! */
+#define PBUF_CHECK_FREE_OOSEQ() do { if(pbuf_free_ooseq_pending) { \
+  /* pbuf_alloc() reported PBUF_POOL to be empty -> try to free some \
+     ooseq queued pbufs now */ \
+  pbuf_free_ooseq(); }}while(0)
+#endif /* NO_SYS && PBUF_POOL_FREE_OOSEQ*/
+#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ */
+
+/* Initializes the pbuf module. This call is empty for now, but may not be in future. */
+#define pbuf_init()
+
+struct pbuf *pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type);
+#if LWIP_SUPPORT_CUSTOM_PBUF
+struct pbuf *pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type,
+                                 struct pbuf_custom *p, void *payload_mem,
+                                 u16_t payload_mem_len);
+#endif /* LWIP_SUPPORT_CUSTOM_PBUF */
+void pbuf_realloc(struct pbuf *p, u16_t size); 
+u8_t pbuf_header(struct pbuf *p, s16_t header_size);
+void pbuf_ref(struct pbuf *p);
+u8_t pbuf_free(struct pbuf *p);
+u8_t pbuf_clen(struct pbuf *p);  
+void pbuf_cat(struct pbuf *head, struct pbuf *tail);
+void pbuf_chain(struct pbuf *head, struct pbuf *tail);
+struct pbuf *pbuf_dechain(struct pbuf *p);
+err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from);
+u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset);
+err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len);
+struct pbuf *pbuf_coalesce(struct pbuf *p, pbuf_layer layer);
+#if LWIP_CHECKSUM_ON_COPY
+err_t pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr,
+                       u16_t len, u16_t *chksum);
+#endif /* LWIP_CHECKSUM_ON_COPY */
+
+u8_t pbuf_get_at(struct pbuf* p, u16_t offset);
+u16_t pbuf_memcmp(struct pbuf* p, u16_t offset, const void* s2, u16_t n);
+u16_t pbuf_memfind(struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset);
+u16_t pbuf_strstr(struct pbuf* p, const char* substr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_PBUF_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/raw.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/raw.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/raw.h	(revision 164)
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_RAW_H__
+#define __LWIP_RAW_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/pbuf.h"
+#include "lwip/def.h"
+#include "lwip/ip.h"
+#include "lwip/ip_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct raw_pcb;
+
+/** Function prototype for raw pcb receive callback functions.
+ * @param arg user supplied argument (raw_pcb.recv_arg)
+ * @param pcb the raw_pcb which received data
+ * @param p the packet buffer that was received
+ * @param addr the remote IP address from which the packet was received
+ * @return 1 if the packet was 'eaten' (aka. deleted),
+ *         0 if the packet lives on
+ * If returning 1, the callback is responsible for freeing the pbuf
+ * if it's not used any more.
+ */
+typedef u8_t (*raw_recv_fn)(void *arg, struct raw_pcb *pcb, struct pbuf *p,
+    ip_addr_t *addr);
+
+struct raw_pcb {
+  /* Common members of all PCB types */
+  IP_PCB;
+
+  struct raw_pcb *next;
+
+  u8_t protocol;
+
+  /** receive callback function */
+  raw_recv_fn recv;
+  /* user-supplied argument for the recv callback */
+  void *recv_arg;
+};
+
+/* The following functions is the application layer interface to the
+   RAW code. */
+struct raw_pcb * raw_new        (u8_t proto);
+void             raw_remove     (struct raw_pcb *pcb);
+err_t            raw_bind       (struct raw_pcb *pcb, ip_addr_t *ipaddr);
+err_t            raw_connect    (struct raw_pcb *pcb, ip_addr_t *ipaddr);
+
+void             raw_recv       (struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg);
+err_t            raw_sendto     (struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr);
+err_t            raw_send       (struct raw_pcb *pcb, struct pbuf *p);
+
+/* The following functions are the lower layer interface to RAW. */
+u8_t             raw_input      (struct pbuf *p, struct netif *inp);
+#define raw_init() /* Compatibility define, not init needed. */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_RAW */
+
+#endif /* __LWIP_RAW_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/sio.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/sio.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/sio.h	(revision 164)
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ */
+
+/*
+ * This is the interface to the platform specific serial IO module
+ * It needs to be implemented by those platforms which need SLIP or PPP
+ */
+
+#ifndef __SIO_H__
+#define __SIO_H__
+
+#include "lwip/arch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* If you want to define sio_fd_t elsewhere or differently,
+   define this in your cc.h file. */
+#ifndef __sio_fd_t_defined
+typedef void * sio_fd_t;
+#endif
+
+/* The following functions can be defined to something else in your cc.h file
+   or be implemented in your custom sio.c file. */
+
+#ifndef sio_open
+/**
+ * Opens a serial device for communication.
+ * 
+ * @param devnum device number
+ * @return handle to serial device if successful, NULL otherwise
+ */
+sio_fd_t sio_open(u8_t devnum);
+#endif
+
+#ifndef sio_send
+/**
+ * Sends a single character to the serial device.
+ * 
+ * @param c character to send
+ * @param fd serial device handle
+ * 
+ * @note This function will block until the character can be sent.
+ */
+void sio_send(u8_t c, sio_fd_t fd);
+#endif
+
+#ifndef sio_recv
+/**
+ * Receives a single character from the serial device.
+ * 
+ * @param fd serial device handle
+ * 
+ * @note This function will block until a character is received.
+ */
+u8_t sio_recv(sio_fd_t fd);
+#endif
+
+#ifndef sio_read
+/**
+ * Reads from the serial device.
+ * 
+ * @param fd serial device handle
+ * @param data pointer to data buffer for receiving
+ * @param len maximum length (in bytes) of data to receive
+ * @return number of bytes actually received - may be 0 if aborted by sio_read_abort
+ * 
+ * @note This function will block until data can be received. The blocking
+ * can be cancelled by calling sio_read_abort().
+ */
+u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len);
+#endif
+
+#ifndef sio_tryread
+/**
+ * Tries to read from the serial device. Same as sio_read but returns
+ * immediately if no data is available and never blocks.
+ * 
+ * @param fd serial device handle
+ * @param data pointer to data buffer for receiving
+ * @param len maximum length (in bytes) of data to receive
+ * @return number of bytes actually received
+ */
+u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len);
+#endif
+
+#ifndef sio_write
+/**
+ * Writes to the serial device.
+ * 
+ * @param fd serial device handle
+ * @param data pointer to data to send
+ * @param len length (in bytes) of data to send
+ * @return number of bytes actually sent
+ * 
+ * @note This function will block until all data can be sent.
+ */
+u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len);
+#endif
+
+#ifndef sio_read_abort
+/**
+ * Aborts a blocking sio_read() call.
+ * 
+ * @param fd serial device handle
+ */
+void sio_read_abort(sio_fd_t fd);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SIO_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/snmp.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/snmp.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/snmp.h	(revision 164)
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2001, 2002 Leon Woestenberg <leon.woestenberg@axon.tv>
+ * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Leon Woestenberg <leon.woestenberg@axon.tv>
+ *
+ */
+#ifndef __LWIP_SNMP_H__
+#define __LWIP_SNMP_H__
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "lwip/ip_addr.h"
+
+struct udp_pcb;
+struct netif;
+
+/**
+ * @see RFC1213, "MIB-II, 6. Definitions"
+ */
+enum snmp_ifType {
+  snmp_ifType_other=1,                /* none of the following */
+  snmp_ifType_regular1822,
+  snmp_ifType_hdh1822,
+  snmp_ifType_ddn_x25,
+  snmp_ifType_rfc877_x25,
+  snmp_ifType_ethernet_csmacd,
+  snmp_ifType_iso88023_csmacd,
+  snmp_ifType_iso88024_tokenBus,
+  snmp_ifType_iso88025_tokenRing,
+  snmp_ifType_iso88026_man,
+  snmp_ifType_starLan,
+  snmp_ifType_proteon_10Mbit,
+  snmp_ifType_proteon_80Mbit,
+  snmp_ifType_hyperchannel,
+  snmp_ifType_fddi,
+  snmp_ifType_lapb,
+  snmp_ifType_sdlc,
+  snmp_ifType_ds1,                    /* T-1 */
+  snmp_ifType_e1,                     /* european equiv. of T-1 */
+  snmp_ifType_basicISDN,
+  snmp_ifType_primaryISDN,            /* proprietary serial */
+  snmp_ifType_propPointToPointSerial,
+  snmp_ifType_ppp,
+  snmp_ifType_softwareLoopback,
+  snmp_ifType_eon,                    /* CLNP over IP [11] */
+  snmp_ifType_ethernet_3Mbit,
+  snmp_ifType_nsip,                   /* XNS over IP */
+  snmp_ifType_slip,                   /* generic SLIP */
+  snmp_ifType_ultra,                  /* ULTRA technologies */
+  snmp_ifType_ds3,                    /* T-3 */
+  snmp_ifType_sip,                    /* SMDS */
+  snmp_ifType_frame_relay
+};
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+/** SNMP "sysuptime" Interval */
+#define SNMP_SYSUPTIME_INTERVAL 10
+
+/** fixed maximum length for object identifier type */
+#define LWIP_SNMP_OBJ_ID_LEN 32
+
+/** internal object identifier representation */
+struct snmp_obj_id
+{
+  u8_t len;
+  s32_t id[LWIP_SNMP_OBJ_ID_LEN];
+};
+
+/* system */
+void snmp_set_sysdesr(u8_t* str, u8_t* len);
+void snmp_set_sysobjid(struct snmp_obj_id *oid);
+void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid);
+void snmp_inc_sysuptime(void);
+void snmp_add_sysuptime(u32_t value);
+void snmp_get_sysuptime(u32_t *value);
+void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen);
+void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen);
+void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen);
+
+/* network interface */
+void snmp_add_ifinoctets(struct netif *ni, u32_t value); 
+void snmp_inc_ifinucastpkts(struct netif *ni);
+void snmp_inc_ifinnucastpkts(struct netif *ni);
+void snmp_inc_ifindiscards(struct netif *ni);
+void snmp_add_ifoutoctets(struct netif *ni, u32_t value);
+void snmp_inc_ifoutucastpkts(struct netif *ni);
+void snmp_inc_ifoutnucastpkts(struct netif *ni);
+void snmp_inc_ifoutdiscards(struct netif *ni);
+void snmp_inc_iflist(void);
+void snmp_dec_iflist(void);
+
+/* ARP (for atTable and ipNetToMediaTable) */
+void snmp_insert_arpidx_tree(struct netif *ni, ip_addr_t *ip);
+void snmp_delete_arpidx_tree(struct netif *ni, ip_addr_t *ip);
+
+/* IP */
+void snmp_inc_ipinreceives(void);
+void snmp_inc_ipinhdrerrors(void);
+void snmp_inc_ipinaddrerrors(void);
+void snmp_inc_ipforwdatagrams(void);
+void snmp_inc_ipinunknownprotos(void);
+void snmp_inc_ipindiscards(void);
+void snmp_inc_ipindelivers(void);
+void snmp_inc_ipoutrequests(void);
+void snmp_inc_ipoutdiscards(void);
+void snmp_inc_ipoutnoroutes(void);
+void snmp_inc_ipreasmreqds(void);
+void snmp_inc_ipreasmoks(void);
+void snmp_inc_ipreasmfails(void);
+void snmp_inc_ipfragoks(void);
+void snmp_inc_ipfragfails(void);
+void snmp_inc_ipfragcreates(void);
+void snmp_inc_iproutingdiscards(void);
+void snmp_insert_ipaddridx_tree(struct netif *ni);
+void snmp_delete_ipaddridx_tree(struct netif *ni);
+void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni);
+void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni);
+
+/* ICMP */
+void snmp_inc_icmpinmsgs(void);
+void snmp_inc_icmpinerrors(void);
+void snmp_inc_icmpindestunreachs(void);
+void snmp_inc_icmpintimeexcds(void);
+void snmp_inc_icmpinparmprobs(void);
+void snmp_inc_icmpinsrcquenchs(void);
+void snmp_inc_icmpinredirects(void);
+void snmp_inc_icmpinechos(void);
+void snmp_inc_icmpinechoreps(void);
+void snmp_inc_icmpintimestamps(void);
+void snmp_inc_icmpintimestampreps(void);
+void snmp_inc_icmpinaddrmasks(void);
+void snmp_inc_icmpinaddrmaskreps(void);
+void snmp_inc_icmpoutmsgs(void);
+void snmp_inc_icmpouterrors(void);
+void snmp_inc_icmpoutdestunreachs(void);
+void snmp_inc_icmpouttimeexcds(void);
+void snmp_inc_icmpoutparmprobs(void);
+void snmp_inc_icmpoutsrcquenchs(void);
+void snmp_inc_icmpoutredirects(void); 
+void snmp_inc_icmpoutechos(void);
+void snmp_inc_icmpoutechoreps(void);
+void snmp_inc_icmpouttimestamps(void);
+void snmp_inc_icmpouttimestampreps(void);
+void snmp_inc_icmpoutaddrmasks(void);
+void snmp_inc_icmpoutaddrmaskreps(void);
+
+/* TCP */
+void snmp_inc_tcpactiveopens(void);
+void snmp_inc_tcppassiveopens(void);
+void snmp_inc_tcpattemptfails(void);
+void snmp_inc_tcpestabresets(void);
+void snmp_inc_tcpinsegs(void);
+void snmp_inc_tcpoutsegs(void);
+void snmp_inc_tcpretranssegs(void);
+void snmp_inc_tcpinerrs(void);
+void snmp_inc_tcpoutrsts(void);
+
+/* UDP */
+void snmp_inc_udpindatagrams(void);
+void snmp_inc_udpnoports(void);
+void snmp_inc_udpinerrors(void);
+void snmp_inc_udpoutdatagrams(void);
+void snmp_insert_udpidx_tree(struct udp_pcb *pcb);
+void snmp_delete_udpidx_tree(struct udp_pcb *pcb);
+
+/* SNMP */
+void snmp_inc_snmpinpkts(void);
+void snmp_inc_snmpoutpkts(void);
+void snmp_inc_snmpinbadversions(void);
+void snmp_inc_snmpinbadcommunitynames(void);
+void snmp_inc_snmpinbadcommunityuses(void);
+void snmp_inc_snmpinasnparseerrs(void);
+void snmp_inc_snmpintoobigs(void);
+void snmp_inc_snmpinnosuchnames(void);
+void snmp_inc_snmpinbadvalues(void);
+void snmp_inc_snmpinreadonlys(void);
+void snmp_inc_snmpingenerrs(void);
+void snmp_add_snmpintotalreqvars(u8_t value);
+void snmp_add_snmpintotalsetvars(u8_t value);
+void snmp_inc_snmpingetrequests(void);
+void snmp_inc_snmpingetnexts(void);
+void snmp_inc_snmpinsetrequests(void);
+void snmp_inc_snmpingetresponses(void);
+void snmp_inc_snmpintraps(void);
+void snmp_inc_snmpouttoobigs(void);
+void snmp_inc_snmpoutnosuchnames(void);
+void snmp_inc_snmpoutbadvalues(void);
+void snmp_inc_snmpoutgenerrs(void);
+void snmp_inc_snmpoutgetrequests(void);
+void snmp_inc_snmpoutgetnexts(void);
+void snmp_inc_snmpoutsetrequests(void);
+void snmp_inc_snmpoutgetresponses(void);
+void snmp_inc_snmpouttraps(void);
+void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid);
+void snmp_set_snmpenableauthentraps(u8_t *value);
+void snmp_get_snmpenableauthentraps(u8_t *value);
+
+/* LWIP_SNMP support not available */
+/* define everything to be empty */
+#else
+
+/* system */
+#define snmp_set_sysdesr(str, len)
+#define snmp_set_sysobjid(oid);
+#define snmp_get_sysobjid_ptr(oid)
+#define snmp_inc_sysuptime()
+#define snmp_add_sysuptime(value)
+#define snmp_get_sysuptime(value)
+#define snmp_set_syscontact(ocstr, ocstrlen);
+#define snmp_set_sysname(ocstr, ocstrlen);
+#define snmp_set_syslocation(ocstr, ocstrlen);
+
+/* network interface */
+#define snmp_add_ifinoctets(ni,value) 
+#define snmp_inc_ifinucastpkts(ni)
+#define snmp_inc_ifinnucastpkts(ni)
+#define snmp_inc_ifindiscards(ni)
+#define snmp_add_ifoutoctets(ni,value)
+#define snmp_inc_ifoutucastpkts(ni)
+#define snmp_inc_ifoutnucastpkts(ni)
+#define snmp_inc_ifoutdiscards(ni)
+#define snmp_inc_iflist()
+#define snmp_dec_iflist()
+
+/* ARP */
+#define snmp_insert_arpidx_tree(ni,ip)
+#define snmp_delete_arpidx_tree(ni,ip)
+
+/* IP */
+#define snmp_inc_ipinreceives()
+#define snmp_inc_ipinhdrerrors()
+#define snmp_inc_ipinaddrerrors()
+#define snmp_inc_ipforwdatagrams()
+#define snmp_inc_ipinunknownprotos()
+#define snmp_inc_ipindiscards()
+#define snmp_inc_ipindelivers()
+#define snmp_inc_ipoutrequests()
+#define snmp_inc_ipoutdiscards()
+#define snmp_inc_ipoutnoroutes()
+#define snmp_inc_ipreasmreqds()
+#define snmp_inc_ipreasmoks()
+#define snmp_inc_ipreasmfails()
+#define snmp_inc_ipfragoks()
+#define snmp_inc_ipfragfails()
+#define snmp_inc_ipfragcreates()
+#define snmp_inc_iproutingdiscards()
+#define snmp_insert_ipaddridx_tree(ni)
+#define snmp_delete_ipaddridx_tree(ni)
+#define snmp_insert_iprteidx_tree(dflt, ni)
+#define snmp_delete_iprteidx_tree(dflt, ni)
+
+/* ICMP */
+#define snmp_inc_icmpinmsgs()
+#define snmp_inc_icmpinerrors() 
+#define snmp_inc_icmpindestunreachs() 
+#define snmp_inc_icmpintimeexcds()
+#define snmp_inc_icmpinparmprobs() 
+#define snmp_inc_icmpinsrcquenchs() 
+#define snmp_inc_icmpinredirects() 
+#define snmp_inc_icmpinechos() 
+#define snmp_inc_icmpinechoreps()
+#define snmp_inc_icmpintimestamps() 
+#define snmp_inc_icmpintimestampreps()
+#define snmp_inc_icmpinaddrmasks()
+#define snmp_inc_icmpinaddrmaskreps()
+#define snmp_inc_icmpoutmsgs()
+#define snmp_inc_icmpouterrors()
+#define snmp_inc_icmpoutdestunreachs() 
+#define snmp_inc_icmpouttimeexcds() 
+#define snmp_inc_icmpoutparmprobs()
+#define snmp_inc_icmpoutsrcquenchs()
+#define snmp_inc_icmpoutredirects() 
+#define snmp_inc_icmpoutechos() 
+#define snmp_inc_icmpoutechoreps()
+#define snmp_inc_icmpouttimestamps()
+#define snmp_inc_icmpouttimestampreps()
+#define snmp_inc_icmpoutaddrmasks()
+#define snmp_inc_icmpoutaddrmaskreps()
+/* TCP */
+#define snmp_inc_tcpactiveopens()
+#define snmp_inc_tcppassiveopens()
+#define snmp_inc_tcpattemptfails()
+#define snmp_inc_tcpestabresets()
+#define snmp_inc_tcpinsegs()
+#define snmp_inc_tcpoutsegs()
+#define snmp_inc_tcpretranssegs()
+#define snmp_inc_tcpinerrs()
+#define snmp_inc_tcpoutrsts()
+
+/* UDP */
+#define snmp_inc_udpindatagrams()
+#define snmp_inc_udpnoports()
+#define snmp_inc_udpinerrors()
+#define snmp_inc_udpoutdatagrams()
+#define snmp_insert_udpidx_tree(pcb)
+#define snmp_delete_udpidx_tree(pcb)
+
+/* SNMP */
+#define snmp_inc_snmpinpkts()
+#define snmp_inc_snmpoutpkts()
+#define snmp_inc_snmpinbadversions()
+#define snmp_inc_snmpinbadcommunitynames()
+#define snmp_inc_snmpinbadcommunityuses()
+#define snmp_inc_snmpinasnparseerrs()
+#define snmp_inc_snmpintoobigs()
+#define snmp_inc_snmpinnosuchnames()
+#define snmp_inc_snmpinbadvalues()
+#define snmp_inc_snmpinreadonlys()
+#define snmp_inc_snmpingenerrs()
+#define snmp_add_snmpintotalreqvars(value)
+#define snmp_add_snmpintotalsetvars(value)
+#define snmp_inc_snmpingetrequests()
+#define snmp_inc_snmpingetnexts()
+#define snmp_inc_snmpinsetrequests()
+#define snmp_inc_snmpingetresponses()
+#define snmp_inc_snmpintraps()
+#define snmp_inc_snmpouttoobigs()
+#define snmp_inc_snmpoutnosuchnames()
+#define snmp_inc_snmpoutbadvalues()
+#define snmp_inc_snmpoutgenerrs()
+#define snmp_inc_snmpoutgetrequests()
+#define snmp_inc_snmpoutgetnexts()
+#define snmp_inc_snmpoutsetrequests()
+#define snmp_inc_snmpoutgetresponses()
+#define snmp_inc_snmpouttraps()
+#define snmp_get_snmpgrpid_ptr(oid)
+#define snmp_set_snmpenableauthentraps(value)
+#define snmp_get_snmpenableauthentraps(value)
+
+#endif /* LWIP_SNMP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_SNMP_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/snmp_asn1.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/snmp_asn1.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/snmp_asn1.h	(revision 164)
@@ -0,0 +1,101 @@
+/**
+ * @file
+ * Abstract Syntax Notation One (ISO 8824, 8825) codec.
+ */
+ 
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#ifndef __LWIP_SNMP_ASN1_H__
+#define __LWIP_SNMP_ASN1_H__
+
+#include "lwip/opt.h"
+#include "lwip/err.h"
+#include "lwip/pbuf.h"
+#include "lwip/snmp.h"
+
+#if LWIP_SNMP
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SNMP_ASN1_UNIV   (0)    /* (!0x80 | !0x40) */
+#define SNMP_ASN1_APPLIC (0x40) /* (!0x80 |  0x40) */
+#define SNMP_ASN1_CONTXT (0x80) /* ( 0x80 | !0x40) */
+
+#define SNMP_ASN1_CONSTR (0x20) /* ( 0x20) */
+#define SNMP_ASN1_PRIMIT (0)    /* (!0x20) */
+
+/* universal tags */
+#define SNMP_ASN1_INTEG  2
+#define SNMP_ASN1_OC_STR 4
+#define SNMP_ASN1_NUL    5
+#define SNMP_ASN1_OBJ_ID 6
+#define SNMP_ASN1_SEQ    16
+
+/* application specific (SNMP) tags */
+#define SNMP_ASN1_IPADDR 0    /* octet string size(4) */
+#define SNMP_ASN1_COUNTER 1   /* u32_t */
+#define SNMP_ASN1_GAUGE 2     /* u32_t */
+#define SNMP_ASN1_TIMETICKS 3 /* u32_t */
+#define SNMP_ASN1_OPAQUE 4    /* octet string */
+
+/* context specific (SNMP) tags */
+#define SNMP_ASN1_PDU_GET_REQ 0
+#define SNMP_ASN1_PDU_GET_NEXT_REQ 1
+#define SNMP_ASN1_PDU_GET_RESP 2
+#define SNMP_ASN1_PDU_SET_REQ 3
+#define SNMP_ASN1_PDU_TRAP 4
+
+err_t snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type);
+err_t snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length);
+err_t snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value);
+err_t snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value);
+err_t snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid);
+err_t snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw);
+
+void snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed);
+void snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed);
+void snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed);
+void snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed);
+err_t snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type);
+err_t snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length);
+err_t snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value);
+err_t snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value);
+err_t snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident);
+err_t snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_SNMP */
+
+#endif /* __LWIP_SNMP_ASN1_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/snmp_msg.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/snmp_msg.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/snmp_msg.h	(revision 164)
@@ -0,0 +1,315 @@
+/**
+ * @file
+ * SNMP Agent message handling structures.
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#ifndef __LWIP_SNMP_MSG_H__
+#define __LWIP_SNMP_MSG_H__
+
+#include "lwip/opt.h"
+#include "lwip/snmp.h"
+#include "lwip/snmp_structs.h"
+#include "lwip/ip_addr.h"
+#include "lwip/err.h"
+
+#if LWIP_SNMP
+
+#if SNMP_PRIVATE_MIB
+/* When using a private MIB, you have to create a file 'private_mib.h' that contains
+ * a 'struct mib_array_node mib_private' which contains your MIB. */
+#include "private_mib.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The listen port of the SNMP agent. Clients have to make their requests to
+   this port. Most standard clients won't work if you change this! */
+#ifndef SNMP_IN_PORT
+#define SNMP_IN_PORT 161
+#endif
+/* The remote port the SNMP agent sends traps to. Most standard trap sinks won't
+   work if you change this! */
+#ifndef SNMP_TRAP_PORT
+#define SNMP_TRAP_PORT 162
+#endif
+
+#define SNMP_ES_NOERROR 0
+#define SNMP_ES_TOOBIG 1
+#define SNMP_ES_NOSUCHNAME 2
+#define SNMP_ES_BADVALUE 3
+#define SNMP_ES_READONLY 4
+#define SNMP_ES_GENERROR 5
+
+#define SNMP_GENTRAP_COLDSTART 0
+#define SNMP_GENTRAP_WARMSTART 1
+#define SNMP_GENTRAP_AUTHFAIL 4
+#define SNMP_GENTRAP_ENTERPRISESPC 6
+
+struct snmp_varbind
+{
+  /* next pointer, NULL for last in list */
+  struct snmp_varbind *next;
+  /* previous pointer, NULL for first in list */
+  struct snmp_varbind *prev;
+
+  /* object identifier length (in s32_t) */
+  u8_t ident_len;
+  /* object identifier array */
+  s32_t *ident;
+
+  /* object value ASN1 type */
+  u8_t value_type;
+  /* object value length (in u8_t) */
+  u8_t value_len;
+  /* object value */
+  void *value;
+
+  /* encoding varbind seq length length */
+  u8_t seqlenlen;
+  /* encoding object identifier length length */
+  u8_t olenlen;
+  /* encoding object value length length */
+  u8_t vlenlen;
+  /* encoding varbind seq length */
+  u16_t seqlen;
+  /* encoding object identifier length */
+  u16_t olen;
+  /* encoding object value length */
+  u16_t vlen;
+};
+
+struct snmp_varbind_root
+{
+  struct snmp_varbind *head;
+  struct snmp_varbind *tail;
+  /* number of variable bindings in list */
+  u8_t count;
+  /* encoding varbind-list seq length length */
+  u8_t seqlenlen;
+  /* encoding varbind-list seq length */
+  u16_t seqlen;
+};
+
+/** output response message header length fields */
+struct snmp_resp_header_lengths
+{
+  /* encoding error-index length length */
+  u8_t erridxlenlen;
+  /* encoding error-status length length */
+  u8_t errstatlenlen;
+  /* encoding request id length length */
+  u8_t ridlenlen;
+  /* encoding pdu length length */
+  u8_t pdulenlen;
+  /* encoding community length length */
+  u8_t comlenlen;
+  /* encoding version length length */
+  u8_t verlenlen;
+  /* encoding sequence length length */
+  u8_t seqlenlen;
+
+  /* encoding error-index length */
+  u16_t erridxlen;
+  /* encoding error-status length */
+  u16_t errstatlen;
+  /* encoding request id length */
+  u16_t ridlen;
+  /* encoding pdu length */
+  u16_t pdulen;
+  /* encoding community length */
+  u16_t comlen;
+  /* encoding version length */
+  u16_t verlen;
+  /* encoding sequence length */
+  u16_t seqlen;
+};
+
+/** output response message header length fields */
+struct snmp_trap_header_lengths
+{
+  /* encoding timestamp length length */
+  u8_t tslenlen;
+  /* encoding specific-trap length length */
+  u8_t strplenlen;
+  /* encoding generic-trap length length */
+  u8_t gtrplenlen;
+  /* encoding agent-addr length length */
+  u8_t aaddrlenlen;
+  /* encoding enterprise-id length length */
+  u8_t eidlenlen;
+  /* encoding pdu length length */
+  u8_t pdulenlen;
+  /* encoding community length length */
+  u8_t comlenlen;
+  /* encoding version length length */
+  u8_t verlenlen;
+  /* encoding sequence length length */
+  u8_t seqlenlen;
+
+  /* encoding timestamp length */
+  u16_t tslen;
+  /* encoding specific-trap length */
+  u16_t strplen;
+  /* encoding generic-trap length */
+  u16_t gtrplen;
+  /* encoding agent-addr length */
+  u16_t aaddrlen;
+  /* encoding enterprise-id length */
+  u16_t eidlen;
+  /* encoding pdu length */
+  u16_t pdulen;
+  /* encoding community length */
+  u16_t comlen;
+  /* encoding version length */
+  u16_t verlen;
+  /* encoding sequence length */
+  u16_t seqlen;
+};
+
+/* Accepting new SNMP messages. */
+#define SNMP_MSG_EMPTY                 0
+/* Search for matching object for variable binding. */
+#define SNMP_MSG_SEARCH_OBJ            1
+/* Perform SNMP operation on in-memory object.
+   Pass-through states, for symmetry only. */
+#define SNMP_MSG_INTERNAL_GET_OBJDEF   2
+#define SNMP_MSG_INTERNAL_GET_VALUE    3
+#define SNMP_MSG_INTERNAL_SET_TEST     4
+#define SNMP_MSG_INTERNAL_GET_OBJDEF_S 5
+#define SNMP_MSG_INTERNAL_SET_VALUE    6
+/* Perform SNMP operation on object located externally.
+   In theory this could be used for building a proxy agent.
+   Practical use is for an enterprise spc. app. gateway. */
+#define SNMP_MSG_EXTERNAL_GET_OBJDEF   7
+#define SNMP_MSG_EXTERNAL_GET_VALUE    8
+#define SNMP_MSG_EXTERNAL_SET_TEST     9
+#define SNMP_MSG_EXTERNAL_GET_OBJDEF_S 10
+#define SNMP_MSG_EXTERNAL_SET_VALUE    11
+
+#define SNMP_COMMUNITY_STR_LEN 64
+struct snmp_msg_pstat
+{
+  /* lwIP local port (161) binding */
+  struct udp_pcb *pcb;
+  /* source IP address */
+  ip_addr_t sip;
+  /* source UDP port */
+  u16_t sp;
+  /* request type */
+  u8_t rt;
+  /* request ID */
+  s32_t rid;
+  /* error status */
+  s32_t error_status;
+  /* error index */
+  s32_t error_index;
+  /* community name (zero terminated) */
+  u8_t community[SNMP_COMMUNITY_STR_LEN + 1];
+  /* community string length (exclusive zero term) */
+  u8_t com_strlen;
+  /* one out of MSG_EMPTY, MSG_DEMUX, MSG_INTERNAL, MSG_EXTERNAL_x */
+  u8_t state;
+  /* saved arguments for MSG_EXTERNAL_x */
+  struct mib_external_node *ext_mib_node;
+  struct snmp_name_ptr ext_name_ptr;
+  struct obj_def ext_object_def;
+  struct snmp_obj_id ext_oid;
+  /* index into input variable binding list */
+  u8_t vb_idx;
+  /* ptr into input variable binding list */
+  struct snmp_varbind *vb_ptr;
+  /* list of variable bindings from input */
+  struct snmp_varbind_root invb;
+  /* list of variable bindings to output */
+  struct snmp_varbind_root outvb;
+  /* output response lengths used in ASN encoding */
+  struct snmp_resp_header_lengths rhl;
+};
+
+struct snmp_msg_trap
+{
+  /* lwIP local port (161) binding */
+  struct udp_pcb *pcb;
+  /* destination IP address in network order */
+  ip_addr_t dip;
+
+  /* source enterprise ID (sysObjectID) */
+  struct snmp_obj_id *enterprise;
+  /* source IP address, raw network order format */
+  u8_t sip_raw[4];
+  /* generic trap code */
+  u32_t gen_trap;
+  /* specific trap code */
+  u32_t spc_trap;
+  /* timestamp */
+  u32_t ts;
+  /* list of variable bindings to output */
+  struct snmp_varbind_root outvb;
+  /* output trap lengths used in ASN encoding */
+  struct snmp_trap_header_lengths thl;
+};
+
+/** Agent Version constant, 0 = v1 oddity */
+extern const s32_t snmp_version;
+/** Agent default "public" community string */
+extern const char snmp_publiccommunity[7];
+
+extern struct snmp_msg_trap trap_msg;
+
+/** Agent setup, start listening to port 161. */
+void snmp_init(void);
+void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable);
+void snmp_trap_dst_ip_set(u8_t dst_idx, ip_addr_t *dst);
+
+/** Varbind-list functions. */
+struct snmp_varbind* snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len);
+void snmp_varbind_free(struct snmp_varbind *vb);
+void snmp_varbind_list_free(struct snmp_varbind_root *root);
+void snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb);
+struct snmp_varbind* snmp_varbind_tail_remove(struct snmp_varbind_root *root);
+
+/** Handle an internal (recv) or external (private response) event. */
+void snmp_msg_event(u8_t request_id);
+err_t snmp_send_response(struct snmp_msg_pstat *m_stat);
+err_t snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap);
+void snmp_coldstart_trap(void);
+void snmp_authfail_trap(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_SNMP */
+
+#endif /* __LWIP_SNMP_MSG_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/snmp_structs.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/snmp_structs.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/snmp_structs.h	(revision 164)
@@ -0,0 +1,268 @@
+/**
+ * @file
+ * Generic MIB tree structures.
+ *
+ * @todo namespace prefixes
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#ifndef __LWIP_SNMP_STRUCTS_H__
+#define __LWIP_SNMP_STRUCTS_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/snmp.h"
+
+#if SNMP_PRIVATE_MIB
+/* When using a private MIB, you have to create a file 'private_mib.h' that contains
+ * a 'struct mib_array_node mib_private' which contains your MIB. */
+#include "private_mib.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* MIB object instance */
+#define MIB_OBJECT_NONE 0 
+#define MIB_OBJECT_SCALAR 1
+#define MIB_OBJECT_TAB 2
+
+/* MIB access types */
+#define MIB_ACCESS_READ   1
+#define MIB_ACCESS_WRITE  2
+
+/* MIB object access */
+#define MIB_OBJECT_READ_ONLY      MIB_ACCESS_READ
+#define MIB_OBJECT_READ_WRITE     (MIB_ACCESS_READ | MIB_ACCESS_WRITE)
+#define MIB_OBJECT_WRITE_ONLY     MIB_ACCESS_WRITE
+#define MIB_OBJECT_NOT_ACCESSIBLE 0
+
+/** object definition returned by (get_object_def)() */
+struct obj_def
+{
+  /* MIB_OBJECT_NONE (0), MIB_OBJECT_SCALAR (1), MIB_OBJECT_TAB (2) */
+  u8_t instance;
+  /* 0 read-only, 1 read-write, 2 write-only, 3 not-accessible */
+  u8_t access;
+  /* ASN type for this object */
+  u8_t asn_type;
+  /* value length (host length) */
+  u16_t v_len;
+  /* length of instance part of supplied object identifier */
+  u8_t  id_inst_len;
+  /* instance part of supplied object identifier */
+  s32_t *id_inst_ptr;
+};
+
+struct snmp_name_ptr
+{
+  u8_t ident_len;
+  s32_t *ident;
+};
+
+/** MIB const scalar (.0) node */
+#define MIB_NODE_SC 0x01
+/** MIB const array node */
+#define MIB_NODE_AR 0x02
+/** MIB array node (mem_malloced from RAM) */
+#define MIB_NODE_RA 0x03
+/** MIB list root node (mem_malloced from RAM) */
+#define MIB_NODE_LR 0x04
+/** MIB node for external objects */
+#define MIB_NODE_EX 0x05
+
+/** node "base class" layout, the mandatory fields for a node  */
+struct mib_node
+{
+  /** returns struct obj_def for the given object identifier */
+  void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
+  /** returns object value for the given object identifier,
+     @note the caller must allocate at least len bytes for the value */
+  void (*get_value)(struct obj_def *od, u16_t len, void *value);
+  /** tests length and/or range BEFORE setting */
+  u8_t (*set_test)(struct obj_def *od, u16_t len, void *value);
+  /** sets object value, only to be called when set_test()  */
+  void (*set_value)(struct obj_def *od, u16_t len, void *value);  
+  /** One out of MIB_NODE_AR, MIB_NODE_LR or MIB_NODE_EX */
+  u8_t node_type;
+  /* array or max list length */
+  u16_t maxlength;
+};
+
+/** derived node for scalars .0 index */
+typedef struct mib_node mib_scalar_node;
+
+/** derived node, points to a fixed size const array
+    of sub-identifiers plus a 'child' pointer */
+struct mib_array_node
+{
+  /* inherited "base class" members */
+  void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
+  void (*get_value)(struct obj_def *od, u16_t len, void *value);
+  u8_t (*set_test)(struct obj_def *od, u16_t len, void *value);
+  void (*set_value)(struct obj_def *od, u16_t len, void *value);
+
+  u8_t node_type;
+  u16_t maxlength;
+
+  /* additional struct members */
+  const s32_t *objid;
+  struct mib_node* const *nptr;
+};
+
+/** derived node, points to a fixed size mem_malloced array
+    of sub-identifiers plus a 'child' pointer */
+struct mib_ram_array_node
+{
+  /* inherited "base class" members */
+  void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
+  void (*get_value)(struct obj_def *od, u16_t len, void *value);
+  u8_t (*set_test)(struct obj_def *od, u16_t len, void *value);
+  void (*set_value)(struct obj_def *od, u16_t len, void *value);
+
+  u8_t node_type;
+  u16_t maxlength;
+
+  /* aditional struct members */
+  s32_t *objid;
+  struct mib_node **nptr;
+};
+
+struct mib_list_node
+{
+  struct mib_list_node *prev;  
+  struct mib_list_node *next;
+  s32_t objid;
+  struct mib_node *nptr;
+};
+
+/** derived node, points to a doubly linked list
+    of sub-identifiers plus a 'child' pointer */
+struct mib_list_rootnode
+{
+  /* inherited "base class" members */
+  void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
+  void (*get_value)(struct obj_def *od, u16_t len, void *value);
+  u8_t (*set_test)(struct obj_def *od, u16_t len, void *value);
+  void (*set_value)(struct obj_def *od, u16_t len, void *value);
+
+  u8_t node_type;
+  u16_t maxlength;
+
+  /* additional struct members */
+  struct mib_list_node *head;
+  struct mib_list_node *tail;
+  /* counts list nodes in list  */
+  u16_t count;
+};
+
+/** derived node, has access functions for mib object in external memory or device
+    using 'tree_level' and 'idx', with a range 0 .. (level_length() - 1) */
+struct mib_external_node
+{
+  /* inherited "base class" members */
+  void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
+  void (*get_value)(struct obj_def *od, u16_t len, void *value);
+  u8_t (*set_test)(struct obj_def *od, u16_t len, void *value);
+  void (*set_value)(struct obj_def *od, u16_t len, void *value);
+
+  u8_t node_type;
+  u16_t maxlength;
+
+  /* additional struct members */
+  /** points to an external (in memory) record of some sort of addressing
+      information, passed to and interpreted by the funtions below */
+  void* addr_inf;
+  /** tree levels under this node */
+  u8_t tree_levels;
+  /** number of objects at this level */
+  u16_t (*level_length)(void* addr_inf, u8_t level);
+  /** compares object sub identifier with external id
+      return zero when equal, nonzero when unequal */
+  s32_t (*ident_cmp)(void* addr_inf, u8_t level, u16_t idx, s32_t sub_id);
+  void (*get_objid)(void* addr_inf, u8_t level, u16_t idx, s32_t *sub_id);
+
+  /** async Questions */
+  void (*get_object_def_q)(void* addr_inf, u8_t rid, u8_t ident_len, s32_t *ident);
+  void (*get_value_q)(u8_t rid, struct obj_def *od);
+  void (*set_test_q)(u8_t rid, struct obj_def *od);
+  void (*set_value_q)(u8_t rid, struct obj_def *od, u16_t len, void *value);
+  /** async Answers */
+  void (*get_object_def_a)(u8_t rid, u8_t ident_len, s32_t *ident, struct obj_def *od);
+  void (*get_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value);
+  u8_t (*set_test_a)(u8_t rid, struct obj_def *od, u16_t len, void *value);
+  void (*set_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value);
+  /** async Panic Close (agent returns error reply, 
+      e.g. used for external transaction cleanup) */
+  void (*get_object_def_pc)(u8_t rid, u8_t ident_len, s32_t *ident);
+  void (*get_value_pc)(u8_t rid, struct obj_def *od);
+  void (*set_test_pc)(u8_t rid, struct obj_def *od);
+  void (*set_value_pc)(u8_t rid, struct obj_def *od);
+};
+
+/** export MIB tree from mib2.c */
+extern const struct mib_array_node internet;
+
+/** dummy function pointers for non-leaf MIB nodes from mib2.c */
+void noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+void noleafs_get_value(struct obj_def *od, u16_t len, void *value);
+u8_t noleafs_set_test(struct obj_def *od, u16_t len, void *value);
+void noleafs_set_value(struct obj_def *od, u16_t len, void *value);
+
+void snmp_oidtoip(s32_t *ident, ip_addr_t *ip);
+void snmp_iptooid(ip_addr_t *ip, s32_t *ident);
+void snmp_ifindextonetif(s32_t ifindex, struct netif **netif);
+void snmp_netiftoifindex(struct netif *netif, s32_t *ifidx);
+
+struct mib_list_node* snmp_mib_ln_alloc(s32_t id);
+void snmp_mib_ln_free(struct mib_list_node *ln);
+struct mib_list_rootnode* snmp_mib_lrn_alloc(void);
+void snmp_mib_lrn_free(struct mib_list_rootnode *lrn);
+
+s8_t snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn);
+s8_t snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn);
+struct mib_list_rootnode *snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n);
+
+struct mib_node* snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np);
+struct mib_node* snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret);
+u8_t snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident);
+u8_t snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_SNMP */
+
+#endif /* __LWIP_SNMP_STRUCTS_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/sockets.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/sockets.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/sockets.h	(revision 164)
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+
+#ifndef __LWIP_SOCKETS_H__
+#define __LWIP_SOCKETS_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
+
+#include <stddef.h> /* for size_t */
+
+#include "lwip/ip_addr.h"
+#include "lwip/inet.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* members are in network byte order */
+struct sockaddr_in {
+  u8_t sin_len;
+  u8_t sin_family;
+  u16_t sin_port;
+  struct in_addr sin_addr;
+  char sin_zero[8];
+};
+
+struct sockaddr {
+  u8_t sa_len;
+  u8_t sa_family;
+  char sa_data[14];
+};
+
+/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
+typedef u32_t socklen_t;
+#endif
+
+/* Socket protocol types (TCP/UDP/RAW) */
+#define SOCK_STREAM     1
+#define SOCK_DGRAM      2
+#define SOCK_RAW        3
+
+/*
+ * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c)
+ */
+#define  SO_DEBUG       0x0001 /* Unimplemented: turn on debugging info recording */
+#define  SO_ACCEPTCONN  0x0002 /* socket has had listen() */
+#define  SO_REUSEADDR   0x0004 /* Allow local address reuse */
+#define  SO_KEEPALIVE   0x0008 /* keep connections alive */
+#define  SO_DONTROUTE   0x0010 /* Unimplemented: just use interface addresses */
+#define  SO_BROADCAST   0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
+#define  SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */
+#define  SO_LINGER      0x0080 /* linger on close if data present */
+#define  SO_OOBINLINE   0x0100 /* Unimplemented: leave received OOB data in line */
+#define  SO_REUSEPORT   0x0200 /* Unimplemented: allow local address & port reuse */
+
+#define SO_DONTLINGER   ((int)(~SO_LINGER))
+
+/*
+ * Additional options, not kept in so_options.
+ */
+#define SO_SNDBUF    0x1001    /* Unimplemented: send buffer size */
+#define SO_RCVBUF    0x1002    /* receive buffer size */
+#define SO_SNDLOWAT  0x1003    /* Unimplemented: send low-water mark */
+#define SO_RCVLOWAT  0x1004    /* Unimplemented: receive low-water mark */
+#define SO_SNDTIMEO  0x1005    /* Unimplemented: send timeout */
+#define SO_RCVTIMEO  0x1006    /* receive timeout */
+#define SO_ERROR     0x1007    /* get error status and clear */
+#define SO_TYPE      0x1008    /* get socket type */
+#define SO_CONTIMEO  0x1009    /* Unimplemented: connect timeout */
+#define SO_NO_CHECK  0x100a    /* don't create UDP checksum */
+
+
+/*
+ * Structure used for manipulating linger option.
+ */
+struct linger {
+       int l_onoff;                /* option on/off */
+       int l_linger;               /* linger time */
+};
+
+/*
+ * Level number for (get/set)sockopt() to apply to socket itself.
+ */
+#define  SOL_SOCKET  0xfff    /* options for socket level */
+
+
+#define AF_UNSPEC       0
+#define AF_INET         2
+#define PF_INET         AF_INET
+#define PF_UNSPEC       AF_UNSPEC
+
+#define IPPROTO_IP      0
+#define IPPROTO_TCP     6
+#define IPPROTO_UDP     17
+#define IPPROTO_UDPLITE 136
+
+/* Flags we can use with send and recv. */
+#define MSG_PEEK       0x01    /* Peeks at an incoming message */
+#define MSG_WAITALL    0x02    /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */
+#define MSG_OOB        0x04    /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
+#define MSG_DONTWAIT   0x08    /* Nonblocking i/o for this operation only */
+#define MSG_MORE       0x10    /* Sender will send more */
+
+
+/*
+ * Options for level IPPROTO_IP
+ */
+#define IP_TOS             1
+#define IP_TTL             2
+
+#if LWIP_TCP
+/*
+ * Options for level IPPROTO_TCP
+ */
+#define TCP_NODELAY    0x01    /* don't delay send to coalesce packets */
+#define TCP_KEEPALIVE  0x02    /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
+#define TCP_KEEPIDLE   0x03    /* set pcb->keep_idle  - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */
+#define TCP_KEEPINTVL  0x04    /* set pcb->keep_intvl - Use seconds for get/setsockopt */
+#define TCP_KEEPCNT    0x05    /* set pcb->keep_cnt   - Use number of probes sent for get/setsockopt */
+#endif /* LWIP_TCP */
+
+#if LWIP_UDP && LWIP_UDPLITE
+/*
+ * Options for level IPPROTO_UDPLITE
+ */
+#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
+#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
+#endif /* LWIP_UDP && LWIP_UDPLITE*/
+
+
+#if LWIP_IGMP
+/*
+ * Options and types for UDP multicast traffic handling
+ */
+#define IP_ADD_MEMBERSHIP  3
+#define IP_DROP_MEMBERSHIP 4
+#define IP_MULTICAST_TTL   5
+#define IP_MULTICAST_IF    6
+#define IP_MULTICAST_LOOP  7
+
+typedef struct ip_mreq {
+    struct in_addr imr_multiaddr; /* IP multicast address of group */
+    struct in_addr imr_interface; /* local IP address of interface */
+} ip_mreq;
+#endif /* LWIP_IGMP */
+
+/*
+ * The Type of Service provides an indication of the abstract
+ * parameters of the quality of service desired.  These parameters are
+ * to be used to guide the selection of the actual service parameters
+ * when transmitting a datagram through a particular network.  Several
+ * networks offer service precedence, which somehow treats high
+ * precedence traffic as more important than other traffic (generally
+ * by accepting only traffic above a certain precedence at time of high
+ * load).  The major choice is a three way tradeoff between low-delay,
+ * high-reliability, and high-throughput.
+ * The use of the Delay, Throughput, and Reliability indications may
+ * increase the cost (in some sense) of the service.  In many networks
+ * better performance for one of these parameters is coupled with worse
+ * performance on another.  Except for very unusual cases at most two
+ * of these three indications should be set.
+ */
+#define IPTOS_TOS_MASK          0x1E
+#define IPTOS_TOS(tos)          ((tos) & IPTOS_TOS_MASK)
+#define IPTOS_LOWDELAY          0x10
+#define IPTOS_THROUGHPUT        0x08
+#define IPTOS_RELIABILITY       0x04
+#define IPTOS_LOWCOST           0x02
+#define IPTOS_MINCOST           IPTOS_LOWCOST
+
+/*
+ * The Network Control precedence designation is intended to be used
+ * within a network only.  The actual use and control of that
+ * designation is up to each network. The Internetwork Control
+ * designation is intended for use by gateway control originators only.
+ * If the actual use of these precedence designations is of concern to
+ * a particular network, it is the responsibility of that network to
+ * control the access to, and use of, those precedence designations.
+ */
+#define IPTOS_PREC_MASK                 0xe0
+#define IPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)
+#define IPTOS_PREC_NETCONTROL           0xe0
+#define IPTOS_PREC_INTERNETCONTROL      0xc0
+#define IPTOS_PREC_CRITIC_ECP           0xa0
+#define IPTOS_PREC_FLASHOVERRIDE        0x80
+#define IPTOS_PREC_FLASH                0x60
+#define IPTOS_PREC_IMMEDIATE            0x40
+#define IPTOS_PREC_PRIORITY             0x20
+#define IPTOS_PREC_ROUTINE              0x00
+
+
+/*
+ * Commands for ioctlsocket(),  taken from the BSD file fcntl.h.
+ * lwip_ioctl only supports FIONREAD and FIONBIO, for now
+ *
+ * Ioctl's have the command encoded in the lower word,
+ * and the size of any in or out parameters in the upper
+ * word.  The high 2 bits of the upper word are used
+ * to encode the in/out status of the parameter; for now
+ * we restrict parameters to at most 128 bytes.
+ */
+#if !defined(FIONREAD) || !defined(FIONBIO)
+#define IOCPARM_MASK    0x7fU           /* parameters must be < 128 bytes */
+#define IOC_VOID        0x20000000UL    /* no parameters */
+#define IOC_OUT         0x40000000UL    /* copy out parameters */
+#define IOC_IN          0x80000000UL    /* copy in parameters */
+#define IOC_INOUT       (IOC_IN|IOC_OUT)
+                                        /* 0x20000000 distinguishes new &
+                                           old ioctl's */
+#define _IO(x,y)        (IOC_VOID|((x)<<8)|(y))
+
+#define _IOR(x,y,t)     (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
+
+#define _IOW(x,y,t)     (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
+#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
+
+#ifndef FIONREAD
+#define FIONREAD    _IOR('f', 127, unsigned long) /* get # bytes to read */
+#endif
+#ifndef FIONBIO
+#define FIONBIO     _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
+#endif
+
+/* Socket I/O Controls: unimplemented */
+#ifndef SIOCSHIWAT
+#define SIOCSHIWAT  _IOW('s',  0, unsigned long)  /* set high watermark */
+#define SIOCGHIWAT  _IOR('s',  1, unsigned long)  /* get high watermark */
+#define SIOCSLOWAT  _IOW('s',  2, unsigned long)  /* set low watermark */
+#define SIOCGLOWAT  _IOR('s',  3, unsigned long)  /* get low watermark */
+#define SIOCATMARK  _IOR('s',  7, unsigned long)  /* at oob mark? */
+#endif
+
+/* commands for fnctl */
+#ifndef F_GETFL
+#define F_GETFL 3
+#endif
+#ifndef F_SETFL
+#define F_SETFL 4
+#endif
+
+/* File status flags and file access modes for fnctl,
+   these are bits in an int. */
+#ifndef O_NONBLOCK
+#define O_NONBLOCK  1 /* nonblocking I/O */
+#endif
+#ifndef O_NDELAY
+#define O_NDELAY    1 /* same as O_NONBLOCK, for compatibility */
+#endif
+
+#ifndef SHUT_RD
+  #define SHUT_RD   0
+  #define SHUT_WR   1
+  #define SHUT_RDWR 2
+#endif
+
+/* FD_SET used for lwip_select */
+#ifndef FD_SET
+  #undef  FD_SETSIZE
+  /* Make FD_SETSIZE match NUM_SOCKETS in socket.c */
+  #define FD_SETSIZE    MEMP_NUM_NETCONN
+  #define FD_SET(n, p)  ((p)->fd_bits[(n)/8] |=  (1 << ((n) & 7)))
+  #define FD_CLR(n, p)  ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7)))
+  #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] &   (1 << ((n) & 7)))
+  #define FD_ZERO(p)    memset((void*)(p),0,sizeof(*(p)))
+
+  typedef struct fd_set {
+          unsigned char fd_bits [(FD_SETSIZE+7)/8];
+        } fd_set;
+
+#endif /* FD_SET */
+
+/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
+ * by your system, set this to 0 and include <sys/time.h> in cc.h */ 
+#ifndef LWIP_TIMEVAL_PRIVATE
+#define LWIP_TIMEVAL_PRIVATE 1
+#endif
+
+#if LWIP_TIMEVAL_PRIVATE
+struct timeval {
+  long    tv_sec;         /* seconds */
+  long    tv_usec;        /* and microseconds */
+};
+#endif /* LWIP_TIMEVAL_PRIVATE */
+
+void lwip_socket_init(void);
+
+int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
+int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen);
+int lwip_shutdown(int s, int how);
+int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen);
+int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen);
+int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
+int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
+int lwip_close(int s);
+int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen);
+int lwip_listen(int s, int backlog);
+int lwip_recv(int s, void *mem, size_t len, int flags);
+int lwip_read(int s, void *mem, size_t len);
+int lwip_recvfrom(int s, void *mem, size_t len, int flags,
+      struct sockaddr *from, socklen_t *fromlen);
+int lwip_send(int s, const void *dataptr, size_t size, int flags);
+int lwip_sendto(int s, const void *dataptr, size_t size, int flags,
+    const struct sockaddr *to, socklen_t tolen);
+int lwip_socket(int domain, int type, int protocol);
+int lwip_write(int s, const void *dataptr, size_t size);
+int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
+                struct timeval *timeout);
+int lwip_ioctl(int s, long cmd, void *argp);
+int lwip_fcntl(int s, int cmd, int val);
+
+#if LWIP_COMPAT_SOCKETS
+#define accept(a,b,c)         lwip_accept(a,b,c)
+#define bind(a,b,c)           lwip_bind(a,b,c)
+#define shutdown(a,b)         lwip_shutdown(a,b)
+#define closesocket(s)        lwip_close(s)
+#define connect(a,b,c)        lwip_connect(a,b,c)
+#define getsockname(a,b,c)    lwip_getsockname(a,b,c)
+#define getpeername(a,b,c)    lwip_getpeername(a,b,c)
+#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e)
+#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e)
+#define listen(a,b)           lwip_listen(a,b)
+#define recv(a,b,c,d)         lwip_recv(a,b,c,d)
+#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f)
+#define send(a,b,c,d)         lwip_send(a,b,c,d)
+#define sendto(a,b,c,d,e,f)   lwip_sendto(a,b,c,d,e,f)
+#define socket(a,b,c)         lwip_socket(a,b,c)
+#define select(a,b,c,d,e)     lwip_select(a,b,c,d,e)
+#define ioctlsocket(a,b,c)    lwip_ioctl(a,b,c)
+
+#if LWIP_POSIX_SOCKETS_IO_NAMES
+#define read(a,b,c)           lwip_read(a,b,c)
+#define write(a,b,c)          lwip_write(a,b,c)
+#define close(s)              lwip_close(s)
+#define fcntl(a,b,c)          lwip_fcntl(a,b,c)
+#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
+
+#endif /* LWIP_COMPAT_SOCKETS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_SOCKET */
+
+#endif /* __LWIP_SOCKETS_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/stats.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/stats.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/stats.h	(revision 164)
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_STATS_H__
+#define __LWIP_STATS_H__
+
+#include "lwip/opt.h"
+
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_STATS
+
+#ifndef LWIP_STATS_LARGE
+#define LWIP_STATS_LARGE 0
+#endif
+
+#if LWIP_STATS_LARGE
+#define STAT_COUNTER     u32_t
+#define STAT_COUNTER_F   U32_F
+#else
+#define STAT_COUNTER     u16_t
+#define STAT_COUNTER_F   U16_F
+#endif 
+
+struct stats_proto {
+  STAT_COUNTER xmit;             /* Transmitted packets. */
+  STAT_COUNTER recv;             /* Received packets. */
+  STAT_COUNTER fw;               /* Forwarded packets. */
+  STAT_COUNTER drop;             /* Dropped packets. */
+  STAT_COUNTER chkerr;           /* Checksum error. */
+  STAT_COUNTER lenerr;           /* Invalid length error. */
+  STAT_COUNTER memerr;           /* Out of memory error. */
+  STAT_COUNTER rterr;            /* Routing error. */
+  STAT_COUNTER proterr;          /* Protocol error. */
+  STAT_COUNTER opterr;           /* Error in options. */
+  STAT_COUNTER err;              /* Misc error. */
+  STAT_COUNTER cachehit;
+};
+
+struct stats_igmp {
+  STAT_COUNTER xmit;             /* Transmitted packets. */
+  STAT_COUNTER recv;             /* Received packets. */
+  STAT_COUNTER drop;             /* Dropped packets. */
+  STAT_COUNTER chkerr;           /* Checksum error. */
+  STAT_COUNTER lenerr;           /* Invalid length error. */
+  STAT_COUNTER memerr;           /* Out of memory error. */
+  STAT_COUNTER proterr;          /* Protocol error. */
+  STAT_COUNTER rx_v1;            /* Received v1 frames. */
+  STAT_COUNTER rx_group;         /* Received group-specific queries. */
+  STAT_COUNTER rx_general;       /* Received general queries. */
+  STAT_COUNTER rx_report;        /* Received reports. */
+  STAT_COUNTER tx_join;          /* Sent joins. */
+  STAT_COUNTER tx_leave;         /* Sent leaves. */
+  STAT_COUNTER tx_report;        /* Sent reports. */
+};
+
+struct stats_mem {
+#ifdef LWIP_DEBUG
+  const char *name;
+#endif /* LWIP_DEBUG */
+  mem_size_t avail;
+  mem_size_t used;
+  mem_size_t max;
+  STAT_COUNTER err;
+  STAT_COUNTER illegal;
+};
+
+struct stats_syselem {
+  STAT_COUNTER used;
+  STAT_COUNTER max;
+  STAT_COUNTER err;
+};
+
+struct stats_sys {
+  struct stats_syselem sem;
+  struct stats_syselem mutex;
+  struct stats_syselem mbox;
+};
+
+struct stats_ {
+#if LINK_STATS
+  struct stats_proto link;
+#endif
+#if ETHARP_STATS
+  struct stats_proto etharp;
+#endif
+#if IPFRAG_STATS
+  struct stats_proto ip_frag;
+#endif
+#if IP_STATS
+  struct stats_proto ip;
+#endif
+#if ICMP_STATS
+  struct stats_proto icmp;
+#endif
+#if IGMP_STATS
+  struct stats_igmp igmp;
+#endif
+#if UDP_STATS
+  struct stats_proto udp;
+#endif
+#if TCP_STATS
+  struct stats_proto tcp;
+#endif
+#if MEM_STATS
+  struct stats_mem mem;
+#endif
+#if MEMP_STATS
+  struct stats_mem memp[MEMP_MAX];
+#endif
+#if SYS_STATS
+  struct stats_sys sys;
+#endif
+};
+
+extern struct stats_ lwip_stats;
+
+void stats_init(void);
+
+#define STATS_INC(x) ++lwip_stats.x
+#define STATS_DEC(x) --lwip_stats.x
+#define STATS_INC_USED(x, y) do { lwip_stats.x.used += y; \
+                                if (lwip_stats.x.max < lwip_stats.x.used) { \
+                                    lwip_stats.x.max = lwip_stats.x.used; \
+                                } \
+                             } while(0)
+#else /* LWIP_STATS */
+#define stats_init()
+#define STATS_INC(x)
+#define STATS_DEC(x)
+#define STATS_INC_USED(x)
+#endif /* LWIP_STATS */
+
+#if TCP_STATS
+#define TCP_STATS_INC(x) STATS_INC(x)
+#define TCP_STATS_DISPLAY() stats_display_proto(&lwip_stats.tcp, "TCP")
+#else
+#define TCP_STATS_INC(x)
+#define TCP_STATS_DISPLAY()
+#endif
+
+#if UDP_STATS
+#define UDP_STATS_INC(x) STATS_INC(x)
+#define UDP_STATS_DISPLAY() stats_display_proto(&lwip_stats.udp, "UDP")
+#else
+#define UDP_STATS_INC(x)
+#define UDP_STATS_DISPLAY()
+#endif
+
+#if ICMP_STATS
+#define ICMP_STATS_INC(x) STATS_INC(x)
+#define ICMP_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp, "ICMP")
+#else
+#define ICMP_STATS_INC(x)
+#define ICMP_STATS_DISPLAY()
+#endif
+
+#if IGMP_STATS
+#define IGMP_STATS_INC(x) STATS_INC(x)
+#define IGMP_STATS_DISPLAY() stats_display_igmp(&lwip_stats.igmp)
+#else
+#define IGMP_STATS_INC(x)
+#define IGMP_STATS_DISPLAY()
+#endif
+
+#if IP_STATS
+#define IP_STATS_INC(x) STATS_INC(x)
+#define IP_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip, "IP")
+#else
+#define IP_STATS_INC(x)
+#define IP_STATS_DISPLAY()
+#endif
+
+#if IPFRAG_STATS
+#define IPFRAG_STATS_INC(x) STATS_INC(x)
+#define IPFRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG")
+#else
+#define IPFRAG_STATS_INC(x)
+#define IPFRAG_STATS_DISPLAY()
+#endif
+
+#if ETHARP_STATS
+#define ETHARP_STATS_INC(x) STATS_INC(x)
+#define ETHARP_STATS_DISPLAY() stats_display_proto(&lwip_stats.etharp, "ETHARP")
+#else
+#define ETHARP_STATS_INC(x)
+#define ETHARP_STATS_DISPLAY()
+#endif
+
+#if LINK_STATS
+#define LINK_STATS_INC(x) STATS_INC(x)
+#define LINK_STATS_DISPLAY() stats_display_proto(&lwip_stats.link, "LINK")
+#else
+#define LINK_STATS_INC(x)
+#define LINK_STATS_DISPLAY()
+#endif
+
+#if MEM_STATS
+#define MEM_STATS_AVAIL(x, y) lwip_stats.mem.x = y
+#define MEM_STATS_INC(x) STATS_INC(mem.x)
+#define MEM_STATS_INC_USED(x, y) STATS_INC_USED(mem, y)
+#define MEM_STATS_DEC_USED(x, y) lwip_stats.mem.x -= y
+#define MEM_STATS_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP")
+#else
+#define MEM_STATS_AVAIL(x, y)
+#define MEM_STATS_INC(x)
+#define MEM_STATS_INC_USED(x, y)
+#define MEM_STATS_DEC_USED(x, y)
+#define MEM_STATS_DISPLAY()
+#endif
+
+#if MEMP_STATS
+#define MEMP_STATS_AVAIL(x, i, y) lwip_stats.memp[i].x = y
+#define MEMP_STATS_INC(x, i) STATS_INC(memp[i].x)
+#define MEMP_STATS_DEC(x, i) STATS_DEC(memp[i].x)
+#define MEMP_STATS_INC_USED(x, i) STATS_INC_USED(memp[i], 1)
+#define MEMP_STATS_DISPLAY(i) stats_display_memp(&lwip_stats.memp[i], i)
+#else
+#define MEMP_STATS_AVAIL(x, i, y)
+#define MEMP_STATS_INC(x, i)
+#define MEMP_STATS_DEC(x, i)
+#define MEMP_STATS_INC_USED(x, i)
+#define MEMP_STATS_DISPLAY(i)
+#endif
+
+#if SYS_STATS
+#define SYS_STATS_INC(x) STATS_INC(sys.x)
+#define SYS_STATS_DEC(x) STATS_DEC(sys.x)
+#define SYS_STATS_INC_USED(x) STATS_INC_USED(sys.x, 1)
+#define SYS_STATS_DISPLAY() stats_display_sys(&lwip_stats.sys)
+#else
+#define SYS_STATS_INC(x)
+#define SYS_STATS_DEC(x)
+#define SYS_STATS_INC_USED(x)
+#define SYS_STATS_DISPLAY()
+#endif
+
+/* Display of statistics */
+#if LWIP_STATS_DISPLAY
+void stats_display(void);
+void stats_display_proto(struct stats_proto *proto, const char *name);
+void stats_display_igmp(struct stats_igmp *igmp);
+void stats_display_mem(struct stats_mem *mem, const char *name);
+void stats_display_memp(struct stats_mem *mem, int index);
+void stats_display_sys(struct stats_sys *sys);
+#else /* LWIP_STATS_DISPLAY */
+#define stats_display()
+#define stats_display_proto(proto, name)
+#define stats_display_igmp(igmp)
+#define stats_display_mem(mem, name)
+#define stats_display_memp(mem, index)
+#define stats_display_sys(sys)
+#endif /* LWIP_STATS_DISPLAY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_STATS_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/sys.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/sys.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/sys.h	(revision 164)
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_SYS_H__
+#define __LWIP_SYS_H__
+
+#include "lwip/opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if NO_SYS
+
+/* For a totally minimal and standalone system, we provide null
+   definitions of the sys_ functions. */
+typedef u8_t sys_sem_t;
+typedef u8_t sys_mutex_t;
+typedef u8_t sys_mbox_t;
+
+#define sys_sem_new(s, c) ERR_OK
+#define sys_sem_signal(s)
+#define sys_sem_wait(s)
+#define sys_arch_sem_wait(s,t)
+#define sys_sem_free(s)
+#define sys_sem_valid(s) 0
+#define sys_sem_set_invalid(s)
+#define sys_mutex_new(mu) ERR_OK
+#define sys_mutex_lock(mu)
+#define sys_mutex_unlock(mu)
+#define sys_mutex_free(mu)
+#define sys_mutex_valid(mu) 0
+#define sys_mutex_set_invalid(mu)
+#define sys_mbox_new(m, s) ERR_OK
+#define sys_mbox_fetch(m,d)
+#define sys_mbox_tryfetch(m,d)
+#define sys_mbox_post(m,d)
+#define sys_mbox_trypost(m,d)
+#define sys_mbox_free(m)
+#define sys_mbox_valid(m)
+#define sys_mbox_set_invalid(m)
+
+#define sys_thread_new(n,t,a,s,p)
+
+#define sys_msleep(t)
+
+#else /* NO_SYS */
+
+/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */
+#define SYS_ARCH_TIMEOUT 0xffffffffUL
+
+/** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate.
+ * For now we use the same magic value, but we allow this to change in future.
+ */
+#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT 
+
+#include "lwip/err.h"
+#include "arch/sys_arch.h"
+
+/** Function prototype for thread functions */
+typedef void (*lwip_thread_fn)(void *arg);
+
+/* Function prototypes for functions to be implemented by platform ports
+   (in sys_arch.c) */
+
+/* Mutex functions: */
+
+/** Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores
+    should be used instead */
+#if LWIP_COMPAT_MUTEX
+/* for old ports that don't have mutexes: define them to binary semaphores */
+#define sys_mutex_t                   sys_sem_t
+#define sys_mutex_new(mutex)          sys_sem_new(mutex, 1)
+#define sys_mutex_lock(mutex)         sys_sem_wait(mutex)
+#define sys_mutex_unlock(mutex)       sys_sem_signal(mutex)
+#define sys_mutex_free(mutex)         sys_sem_free(mutex)
+#define sys_mutex_valid(mutex)        sys_sem_valid(mutex)
+#define sys_mutex_set_invalid(mutex)  sys_sem_set_invalid(mutex)
+
+#else /* LWIP_COMPAT_MUTEX */
+
+/** Create a new mutex
+ * @param mutex pointer to the mutex to create
+ * @return a new mutex */
+err_t sys_mutex_new(sys_mutex_t *mutex);
+/** Lock a mutex
+ * @param mutex the mutex to lock */
+void sys_mutex_lock(sys_mutex_t *mutex);
+/** Unlock a mutex
+ * @param mutex the mutex to unlock */
+void sys_mutex_unlock(sys_mutex_t *mutex);
+/** Delete a semaphore
+ * @param mutex the mutex to delete */
+void sys_mutex_free(sys_mutex_t *mutex); 
+#ifndef sys_mutex_valid
+/** Check if a mutex is valid/allocated: return 1 for valid, 0 for invalid */
+int sys_mutex_valid(sys_mutex_t *mutex);
+#endif
+#ifndef sys_mutex_set_invalid
+/** Set a mutex invalid so that sys_mutex_valid returns 0 */
+void sys_mutex_set_invalid(sys_mutex_t *mutex);
+#endif
+#endif /* LWIP_COMPAT_MUTEX */
+
+/* Semaphore functions: */
+
+/** Create a new semaphore
+ * @param sem pointer to the semaphore to create
+ * @param count initial count of the semaphore
+ * @return ERR_OK if successful, another err_t otherwise */
+err_t sys_sem_new(sys_sem_t *sem, u8_t count);
+/** Signals a semaphore
+ * @param sem the semaphore to signal */
+void sys_sem_signal(sys_sem_t *sem);
+/** Wait for a semaphore for the specified timeout
+ * @param sem the semaphore to wait for
+ * @param timeout timeout in milliseconds to wait (0 = wait forever)
+ * @return time (in milliseconds) waited for the semaphore
+ *         or SYS_ARCH_TIMEOUT on timeout */
+u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout);
+/** Delete a semaphore
+ * @param sem semaphore to delete */
+void sys_sem_free(sys_sem_t *sem);
+/** Wait for a semaphore - forever/no timeout */
+#define sys_sem_wait(sem)                  sys_arch_sem_wait(sem, 0)
+#ifndef sys_sem_valid
+/** Check if a sempahore is valid/allocated: return 1 for valid, 0 for invalid */
+int sys_sem_valid(sys_sem_t *sem);
+#endif
+#ifndef sys_sem_set_invalid
+/** Set a semaphore invalid so that sys_sem_valid returns 0 */
+void sys_sem_set_invalid(sys_sem_t *sem);
+#endif
+
+/* Time functions. */
+#ifndef sys_msleep
+void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */
+#endif
+
+/* Mailbox functions. */
+
+/** Create a new mbox of specified size
+ * @param mbox pointer to the mbox to create
+ * @param size (miminum) number of messages in this mbox
+ * @return ERR_OK if successful, another err_t otherwise */
+err_t sys_mbox_new(sys_mbox_t *mbox, int size);
+/** Post a message to an mbox - may not fail
+ * -> blocks if full, only used from tasks not from ISR
+ * @param mbox mbox to posts the message
+ * @param msg message to post (ATTENTION: can be NULL) */
+void sys_mbox_post(sys_mbox_t *mbox, void *msg);
+/** Try to post a message to an mbox - may fail if full or ISR
+ * @param mbox mbox to posts the message
+ * @param msg message to post (ATTENTION: can be NULL) */
+err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg);
+/** Wait for a new message to arrive in the mbox
+ * @param mbox mbox to get a message from
+ * @param msg pointer where the message is stored
+ * @param timeout maximum time (in milliseconds) to wait for a message
+ * @return time (in milliseconds) waited for a message, may be 0 if not waited
+           or SYS_ARCH_TIMEOUT on timeout
+ *         The returned time has to be accurate to prevent timer jitter! */
+u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout);
+/* Allow port to override with a macro, e.g. special timout for sys_arch_mbox_fetch() */
+#ifndef sys_arch_mbox_tryfetch
+/** Wait for a new message to arrive in the mbox
+ * @param mbox mbox to get a message from
+ * @param msg pointer where the message is stored
+ * @param timeout maximum time (in milliseconds) to wait for a message
+ * @return 0 (milliseconds) if a message has been received
+ *         or SYS_MBOX_EMPTY if the mailbox is empty */
+u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg);
+#endif
+/** For now, we map straight to sys_arch implementation. */
+#define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg)
+/** Delete an mbox
+ * @param mbox mbox to delete */
+void sys_mbox_free(sys_mbox_t *mbox);
+#define sys_mbox_fetch(mbox, msg) sys_arch_mbox_fetch(mbox, msg, 0)
+#ifndef sys_mbox_valid
+/** Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid */
+int sys_mbox_valid(sys_mbox_t *mbox);
+#endif
+#ifndef sys_mbox_set_invalid
+/** Set an mbox invalid so that sys_mbox_valid returns 0 */
+void sys_mbox_set_invalid(sys_mbox_t *mbox);
+#endif
+
+/** The only thread function:
+ * Creates a new thread
+ * @param name human-readable name for the thread (used for debugging purposes)
+ * @param thread thread-function
+ * @param arg parameter passed to 'thread'
+ * @param stacksize stack size in bytes for the new thread (may be ignored by ports)
+ * @param prio priority of the new thread (may be ignored by ports) */
+sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio);
+
+#endif /* NO_SYS */
+
+/* sys_init() must be called before anthing else. */
+void sys_init(void);
+
+#ifndef sys_jiffies
+/** Ticks/jiffies since power up. */
+u32_t sys_jiffies(void);
+#endif
+
+/** Returns the current time in milliseconds,
+ * may be the same as sys_jiffies or at least based on it. */
+u32_t sys_now(void);
+
+/* Critical Region Protection */
+/* These functions must be implemented in the sys_arch.c file.
+   In some implementations they can provide a more light-weight protection
+   mechanism than using semaphores. Otherwise semaphores can be used for
+   implementation */
+#ifndef SYS_ARCH_PROTECT
+/** SYS_LIGHTWEIGHT_PROT
+ * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
+ * for certain critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#if SYS_LIGHTWEIGHT_PROT
+
+/** SYS_ARCH_DECL_PROTECT
+ * declare a protection variable. This macro will default to defining a variable of
+ * type sys_prot_t. If a particular port needs a different implementation, then
+ * this macro may be defined in sys_arch.h.
+ */
+#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev
+/** SYS_ARCH_PROTECT
+ * Perform a "fast" protect. This could be implemented by
+ * disabling interrupts for an embedded system or by using a semaphore or
+ * mutex. The implementation should allow calling SYS_ARCH_PROTECT when
+ * already protected. The old protection level is returned in the variable
+ * "lev". This macro will default to calling the sys_arch_protect() function
+ * which should be implemented in sys_arch.c. If a particular port needs a
+ * different implementation, then this macro may be defined in sys_arch.h
+ */
+#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect()
+/** SYS_ARCH_UNPROTECT
+ * Perform a "fast" set of the protection level to "lev". This could be
+ * implemented by setting the interrupt level to "lev" within the MACRO or by
+ * using a semaphore or mutex.  This macro will default to calling the
+ * sys_arch_unprotect() function which should be implemented in
+ * sys_arch.c. If a particular port needs a different implementation, then
+ * this macro may be defined in sys_arch.h
+ */
+#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev)
+sys_prot_t sys_arch_protect(void);
+void sys_arch_unprotect(sys_prot_t pval);
+
+#else
+
+#define SYS_ARCH_DECL_PROTECT(lev)
+#define SYS_ARCH_PROTECT(lev)
+#define SYS_ARCH_UNPROTECT(lev)
+
+#endif /* SYS_LIGHTWEIGHT_PROT */
+
+#endif /* SYS_ARCH_PROTECT */
+
+/*
+ * Macros to set/get and increase/decrease variables in a thread-safe way.
+ * Use these for accessing variable that are used from more than one thread.
+ */
+
+#ifndef SYS_ARCH_INC
+#define SYS_ARCH_INC(var, val) do { \
+                                SYS_ARCH_DECL_PROTECT(old_level); \
+                                SYS_ARCH_PROTECT(old_level); \
+                                var += val; \
+                                SYS_ARCH_UNPROTECT(old_level); \
+                              } while(0)
+#endif /* SYS_ARCH_INC */
+
+#ifndef SYS_ARCH_DEC
+#define SYS_ARCH_DEC(var, val) do { \
+                                SYS_ARCH_DECL_PROTECT(old_level); \
+                                SYS_ARCH_PROTECT(old_level); \
+                                var -= val; \
+                                SYS_ARCH_UNPROTECT(old_level); \
+                              } while(0)
+#endif /* SYS_ARCH_DEC */
+
+#ifndef SYS_ARCH_GET
+#define SYS_ARCH_GET(var, ret) do { \
+                                SYS_ARCH_DECL_PROTECT(old_level); \
+                                SYS_ARCH_PROTECT(old_level); \
+                                ret = var; \
+                                SYS_ARCH_UNPROTECT(old_level); \
+                              } while(0)
+#endif /* SYS_ARCH_GET */
+
+#ifndef SYS_ARCH_SET
+#define SYS_ARCH_SET(var, val) do { \
+                                SYS_ARCH_DECL_PROTECT(old_level); \
+                                SYS_ARCH_PROTECT(old_level); \
+                                var = val; \
+                                SYS_ARCH_UNPROTECT(old_level); \
+                              } while(0)
+#endif /* SYS_ARCH_SET */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_SYS_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/tcp.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/tcp.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/tcp.h	(revision 164)
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_TCP_H__
+#define __LWIP_TCP_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip.h"
+#include "lwip/icmp.h"
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct tcp_pcb;
+
+/** Function prototype for tcp accept callback functions. Called when a new
+ * connection can be accepted on a listening pcb.
+ *
+ * @param arg Additional argument to pass to the callback function (@see tcp_arg())
+ * @param newpcb The new connection pcb
+ * @param err An error code if there has been an error accepting.
+ *            Only return ERR_ABRT if you have called tcp_abort from within the
+ *            callback function!
+ */
+typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err);
+
+/** Function prototype for tcp receive callback functions. Called when data has
+ * been received.
+ *
+ * @param arg Additional argument to pass to the callback function (@see tcp_arg())
+ * @param tpcb The connection pcb which received data
+ * @param p The received data (or NULL when the connection has been closed!)
+ * @param err An error code if there has been an error receiving
+ *            Only return ERR_ABRT if you have called tcp_abort from within the
+ *            callback function!
+ */
+typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb,
+                             struct pbuf *p, err_t err);
+
+/** Function prototype for tcp sent callback functions. Called when sent data has
+ * been acknowledged by the remote side. Use it to free corresponding resources.
+ * This also means that the pcb has now space available to send new data.
+ *
+ * @param arg Additional argument to pass to the callback function (@see tcp_arg())
+ * @param tpcb The connection pcb for which data has been acknowledged
+ * @param len The amount of bytes acknowledged
+ * @return ERR_OK: try to send some data by calling tcp_output
+ *            Only return ERR_ABRT if you have called tcp_abort from within the
+ *            callback function!
+ */
+typedef err_t (*tcp_sent_fn)(void *arg, struct tcp_pcb *tpcb,
+                              u16_t len);
+
+/** Function prototype for tcp poll callback functions. Called periodically as
+ * specified by @see tcp_poll.
+ *
+ * @param arg Additional argument to pass to the callback function (@see tcp_arg())
+ * @param tpcb tcp pcb
+ * @return ERR_OK: try to send some data by calling tcp_output
+ *            Only return ERR_ABRT if you have called tcp_abort from within the
+ *            callback function!
+ */
+typedef err_t (*tcp_poll_fn)(void *arg, struct tcp_pcb *tpcb);
+
+/** Function prototype for tcp error callback functions. Called when the pcb
+ * receives a RST or is unexpectedly closed for any other reason.
+ *
+ * @note The corresponding pcb is already freed when this callback is called!
+ *
+ * @param arg Additional argument to pass to the callback function (@see tcp_arg())
+ * @param err Error code to indicate why the pcb has been closed
+ *            ERR_ABRT: aborted through tcp_abort or by a TCP timer
+ *            ERR_RST: the connection was reset by the remote host
+ */
+typedef void  (*tcp_err_fn)(void *arg, err_t err);
+
+/** Function prototype for tcp connected callback functions. Called when a pcb
+ * is connected to the remote side after initiating a connection attempt by
+ * calling tcp_connect().
+ *
+ * @param arg Additional argument to pass to the callback function (@see tcp_arg())
+ * @param tpcb The connection pcb which is connected
+ * @param err An unused error code, always ERR_OK currently ;-) TODO!
+ *            Only return ERR_ABRT if you have called tcp_abort from within the
+ *            callback function!
+ *
+ * @note When a connection attempt fails, the error callback is currently called!
+ */
+typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err);
+
+enum tcp_state {
+  CLOSED      = 0,
+  LISTEN      = 1,
+  SYN_SENT    = 2,
+  SYN_RCVD    = 3,
+  ESTABLISHED = 4,
+  FIN_WAIT_1  = 5,
+  FIN_WAIT_2  = 6,
+  CLOSE_WAIT  = 7,
+  CLOSING     = 8,
+  LAST_ACK    = 9,
+  TIME_WAIT   = 10
+};
+
+#if LWIP_CALLBACK_API
+  /* Function to call when a listener has been connected.
+   * @param arg user-supplied argument (tcp_pcb.callback_arg)
+   * @param pcb a new tcp_pcb that now is connected
+   * @param err an error argument (TODO: that is current always ERR_OK?)
+   * @return ERR_OK: accept the new connection,
+   *                 any other err_t abortsthe new connection
+   */
+#define DEF_ACCEPT_CALLBACK  tcp_accept_fn accept;
+#else /* LWIP_CALLBACK_API */
+#define DEF_ACCEPT_CALLBACK
+#endif /* LWIP_CALLBACK_API */
+
+/**
+ * members common to struct tcp_pcb and struct tcp_listen_pcb
+ */
+#define TCP_PCB_COMMON(type) \
+  type *next; /* for the linked list */ \
+  void *callback_arg; \
+  /* the accept callback for listen- and normal pcbs, if LWIP_CALLBACK_API */ \
+  DEF_ACCEPT_CALLBACK \
+  enum tcp_state state; /* TCP state */ \
+  u8_t prio; \
+  /* ports are in host byte order */ \
+  u16_t local_port
+
+
+/* the TCP protocol control block */
+struct tcp_pcb {
+/** common PCB members */
+  IP_PCB;
+/** protocol specific PCB members */
+  TCP_PCB_COMMON(struct tcp_pcb);
+
+  /* ports are in host byte order */
+  u16_t remote_port;
+  
+  u8_t flags;
+#define TF_ACK_DELAY   ((u8_t)0x01U)   /* Delayed ACK. */
+#define TF_ACK_NOW     ((u8_t)0x02U)   /* Immediate ACK. */
+#define TF_INFR        ((u8_t)0x04U)   /* In fast recovery. */
+#define TF_TIMESTAMP   ((u8_t)0x08U)   /* Timestamp option enabled */
+#define TF_RXCLOSED    ((u8_t)0x10U)   /* rx closed by tcp_shutdown */
+#define TF_FIN         ((u8_t)0x20U)   /* Connection was closed locally (FIN segment enqueued). */
+#define TF_NODELAY     ((u8_t)0x40U)   /* Disable Nagle algorithm */
+#define TF_NAGLEMEMERR ((u8_t)0x80U)   /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */
+
+  /* the rest of the fields are in host byte order
+     as we have to do some math with them */
+
+  /* Timers */
+  u8_t polltmr, pollinterval;
+  u8_t last_timer;
+  u32_t tmr;
+
+  /* receiver variables */
+  u32_t rcv_nxt;   /* next seqno expected */
+  u16_t rcv_wnd;   /* receiver window available */
+  u16_t rcv_ann_wnd; /* receiver window to announce */
+  u32_t rcv_ann_right_edge; /* announced right edge of window */
+
+  /* Retransmission timer. */
+  s16_t rtime;
+
+  u16_t mss;   /* maximum segment size */
+
+  /* RTT (round trip time) estimation variables */
+  u32_t rttest; /* RTT estimate in 500ms ticks */
+  u32_t rtseq;  /* sequence number being timed */
+  s16_t sa, sv; /* @todo document this */
+
+  s16_t rto;    /* retransmission time-out */
+  u8_t nrtx;    /* number of retransmissions */
+
+  /* fast retransmit/recovery */
+  u8_t dupacks;
+  u32_t lastack; /* Highest acknowledged seqno. */
+
+  /* congestion avoidance/control variables */
+  u16_t cwnd;
+  u16_t ssthresh;
+
+  /* sender variables */
+  u32_t snd_nxt;   /* next new seqno to be sent */
+  u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last
+                             window update. */
+  u32_t snd_lbb;       /* Sequence number of next byte to be buffered. */
+  u16_t snd_wnd;   /* sender window */
+  u16_t snd_wnd_max; /* the maximum sender window announced by the remote host */
+
+  u16_t acked;
+
+  u16_t snd_buf;   /* Available buffer space for sending (in bytes). */
+#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3)
+  u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */
+
+#if TCP_OVERSIZE
+  /* Extra bytes available at the end of the last pbuf in unsent. */
+  u16_t unsent_oversize;
+#endif /* TCP_OVERSIZE */ 
+
+  /* These are ordered by sequence number: */
+  struct tcp_seg *unsent;   /* Unsent (queued) segments. */
+  struct tcp_seg *unacked;  /* Sent but unacknowledged segments. */
+#if TCP_QUEUE_OOSEQ  
+  struct tcp_seg *ooseq;    /* Received out of sequence segments. */
+#endif /* TCP_QUEUE_OOSEQ */
+
+  struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */
+
+#if LWIP_CALLBACK_API
+  /* Function to be called when more send buffer space is available. */
+  tcp_sent_fn sent;
+  /* Function to be called when (in-sequence) data has arrived. */
+  tcp_recv_fn recv;
+  /* Function to be called when a connection has been set up. */
+  tcp_connected_fn connected;
+  /* Function which is called periodically. */
+  tcp_poll_fn poll;
+  /* Function to be called whenever a fatal error occurs. */
+  tcp_err_fn errf;
+#endif /* LWIP_CALLBACK_API */
+
+#if LWIP_TCP_TIMESTAMPS
+  u32_t ts_lastacksent;
+  u32_t ts_recent;
+#endif /* LWIP_TCP_TIMESTAMPS */
+
+  /* idle time before KEEPALIVE is sent */
+  u32_t keep_idle;
+#if LWIP_TCP_KEEPALIVE
+  u32_t keep_intvl;
+  u32_t keep_cnt;
+#endif /* LWIP_TCP_KEEPALIVE */
+  
+  /* Persist timer counter */
+  u8_t persist_cnt;
+  /* Persist timer back-off */
+  u8_t persist_backoff;
+
+  /* KEEPALIVE counter */
+  u8_t keep_cnt_sent;
+};
+
+struct tcp_pcb_listen {  
+/* Common members of all PCB types */
+  IP_PCB;
+/* Protocol specific PCB members */
+  TCP_PCB_COMMON(struct tcp_pcb_listen);
+
+#if TCP_LISTEN_BACKLOG
+  u8_t backlog;
+  u8_t accepts_pending;
+#endif /* TCP_LISTEN_BACKLOG */
+};
+
+#if LWIP_EVENT_API
+
+enum lwip_event {
+  LWIP_EVENT_ACCEPT,
+  LWIP_EVENT_SENT,
+  LWIP_EVENT_RECV,
+  LWIP_EVENT_CONNECTED,
+  LWIP_EVENT_POLL,
+  LWIP_EVENT_ERR
+};
+
+err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
+         enum lwip_event,
+         struct pbuf *p,
+         u16_t size,
+         err_t err);
+
+#endif /* LWIP_EVENT_API */
+
+/* Application program's interface: */
+struct tcp_pcb * tcp_new     (void);
+
+void             tcp_arg     (struct tcp_pcb *pcb, void *arg);
+void             tcp_accept  (struct tcp_pcb *pcb, tcp_accept_fn accept);
+void             tcp_recv    (struct tcp_pcb *pcb, tcp_recv_fn recv);
+void             tcp_sent    (struct tcp_pcb *pcb, tcp_sent_fn sent);
+void             tcp_poll    (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval);
+void             tcp_err     (struct tcp_pcb *pcb, tcp_err_fn err);
+
+#define          tcp_mss(pcb)             (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12)  : (pcb)->mss)
+#define          tcp_sndbuf(pcb)          ((pcb)->snd_buf)
+#define          tcp_sndqueuelen(pcb)     ((pcb)->snd_queuelen)
+#define          tcp_nagle_disable(pcb)   ((pcb)->flags |= TF_NODELAY)
+#define          tcp_nagle_enable(pcb)    ((pcb)->flags &= ~TF_NODELAY)
+#define          tcp_nagle_disabled(pcb)  (((pcb)->flags & TF_NODELAY) != 0)
+
+#if TCP_LISTEN_BACKLOG
+#define          tcp_accepted(pcb) do { \
+  LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", pcb->state == LISTEN); \
+  (((struct tcp_pcb_listen *)(pcb))->accepts_pending--); } while(0)
+#else  /* TCP_LISTEN_BACKLOG */
+#define          tcp_accepted(pcb) LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", \
+                                               (pcb)->state == LISTEN)
+#endif /* TCP_LISTEN_BACKLOG */
+
+void             tcp_recved  (struct tcp_pcb *pcb, u16_t len);
+err_t            tcp_bind    (struct tcp_pcb *pcb, ip_addr_t *ipaddr,
+                              u16_t port);
+err_t            tcp_connect (struct tcp_pcb *pcb, ip_addr_t *ipaddr,
+                              u16_t port, tcp_connected_fn connected);
+
+struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog);
+#define          tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG)
+
+void             tcp_abort (struct tcp_pcb *pcb);
+err_t            tcp_close   (struct tcp_pcb *pcb);
+err_t            tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx);
+
+/* Flags for "apiflags" parameter in tcp_write */
+#define TCP_WRITE_FLAG_COPY 0x01
+#define TCP_WRITE_FLAG_MORE 0x02
+
+err_t            tcp_write   (struct tcp_pcb *pcb, const void *dataptr, u16_t len,
+                              u8_t apiflags);
+
+void             tcp_setprio (struct tcp_pcb *pcb, u8_t prio);
+
+#define TCP_PRIO_MIN    1
+#define TCP_PRIO_NORMAL 64
+#define TCP_PRIO_MAX    127
+
+err_t            tcp_output  (struct tcp_pcb *pcb);
+
+
+const char* tcp_debug_state_str(enum tcp_state s);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_TCP */
+
+#endif /* __LWIP_TCP_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/tcp_impl.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/tcp_impl.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/tcp_impl.h	(revision 164)
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_TCP_IMPL_H__
+#define __LWIP_TCP_IMPL_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/tcp.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/ip.h"
+#include "lwip/icmp.h"
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Functions for interfacing with TCP: */
+
+/* Lower layer interface to TCP: */
+void             tcp_init    (void);  /* Initialize this module. */
+void             tcp_tmr     (void);  /* Must be called every
+                                         TCP_TMR_INTERVAL
+                                         ms. (Typically 250 ms). */
+/* It is also possible to call these two functions at the right
+   intervals (instead of calling tcp_tmr()). */
+void             tcp_slowtmr (void);
+void             tcp_fasttmr (void);
+
+
+/* Only used by IP to pass a TCP segment to TCP: */
+void             tcp_input   (struct pbuf *p, struct netif *inp);
+/* Used within the TCP code only: */
+struct tcp_pcb * tcp_alloc   (u8_t prio);
+void             tcp_abandon (struct tcp_pcb *pcb, int reset);
+err_t            tcp_send_empty_ack(struct tcp_pcb *pcb);
+void             tcp_rexmit  (struct tcp_pcb *pcb);
+void             tcp_rexmit_rto  (struct tcp_pcb *pcb);
+void             tcp_rexmit_fast (struct tcp_pcb *pcb);
+u32_t            tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb);
+err_t            tcp_process_refused_data(struct tcp_pcb *pcb);
+
+/**
+ * This is the Nagle algorithm: try to combine user data to send as few TCP
+ * segments as possible. Only send if
+ * - no previously transmitted data on the connection remains unacknowledged or
+ * - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or
+ * - the only unsent segment is at least pcb->mss bytes long (or there is more
+ *   than one unsent segment - with lwIP, this can happen although unsent->len < mss)
+ * - or if we are in fast-retransmit (TF_INFR)
+ */
+#define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \
+                            ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \
+                            (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \
+                              ((tpcb)->unsent->len >= (tpcb)->mss))) || \
+                            ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \
+                            ) ? 1 : 0)
+#define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK)
+
+
+#define TCP_SEQ_LT(a,b)     ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0)
+#define TCP_SEQ_LEQ(a,b)    ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0)
+#define TCP_SEQ_GT(a,b)     ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0)
+#define TCP_SEQ_GEQ(a,b)    ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0)
+/* is b<=a<=c? */
+#if 0 /* see bug #10548 */
+#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b))
+#endif
+#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))
+#define TCP_FIN 0x01U
+#define TCP_SYN 0x02U
+#define TCP_RST 0x04U
+#define TCP_PSH 0x08U
+#define TCP_ACK 0x10U
+#define TCP_URG 0x20U
+#define TCP_ECE 0x40U
+#define TCP_CWR 0x80U
+
+#define TCP_FLAGS 0x3fU
+
+/* Length of the TCP header, excluding options. */
+#define TCP_HLEN 20
+
+#ifndef TCP_TMR_INTERVAL
+#define TCP_TMR_INTERVAL       250  /* The TCP timer interval in milliseconds. */
+#endif /* TCP_TMR_INTERVAL */
+
+#ifndef TCP_FAST_INTERVAL
+#define TCP_FAST_INTERVAL      TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */
+#endif /* TCP_FAST_INTERVAL */
+
+#ifndef TCP_SLOW_INTERVAL
+#define TCP_SLOW_INTERVAL      (2*TCP_TMR_INTERVAL)  /* the coarse grained timeout in milliseconds */
+#endif /* TCP_SLOW_INTERVAL */
+
+#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */
+#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */
+
+#define TCP_OOSEQ_TIMEOUT        6U /* x RTO */
+
+#ifndef TCP_MSL
+#define TCP_MSL 60000UL /* The maximum segment lifetime in milliseconds */
+#endif
+
+/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */
+#ifndef  TCP_KEEPIDLE_DEFAULT
+#define  TCP_KEEPIDLE_DEFAULT     7200000UL /* Default KEEPALIVE timer in milliseconds */
+#endif
+
+#ifndef  TCP_KEEPINTVL_DEFAULT
+#define  TCP_KEEPINTVL_DEFAULT    75000UL   /* Default Time between KEEPALIVE probes in milliseconds */
+#endif
+
+#ifndef  TCP_KEEPCNT_DEFAULT
+#define  TCP_KEEPCNT_DEFAULT      9U        /* Default Counter for KEEPALIVE probes */
+#endif
+
+#define  TCP_MAXIDLE              TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT  /* Maximum KEEPALIVE probe time */
+
+/* Fields are (of course) in network byte order.
+ * Some fields are converted to host byte order in tcp_input().
+ */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct tcp_hdr {
+  PACK_STRUCT_FIELD(u16_t src);
+  PACK_STRUCT_FIELD(u16_t dest);
+  PACK_STRUCT_FIELD(u32_t seqno);
+  PACK_STRUCT_FIELD(u32_t ackno);
+  PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);
+  PACK_STRUCT_FIELD(u16_t wnd);
+  PACK_STRUCT_FIELD(u16_t chksum);
+  PACK_STRUCT_FIELD(u16_t urgp);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)
+#define TCPH_FLAGS(phdr)  (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)
+
+#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr))
+#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags))
+#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | (flags))
+
+#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags))
+#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) )
+
+#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0))
+
+/** Flags used on input processing, not on pcb->flags
+*/
+#define TF_RESET     (u8_t)0x08U   /* Connection was reset. */
+#define TF_CLOSED    (u8_t)0x10U   /* Connection was sucessfully closed. */
+#define TF_GOT_FIN   (u8_t)0x20U   /* Connection was closed by the remote end. */
+
+
+#if LWIP_EVENT_API
+
+#define TCP_EVENT_ACCEPT(pcb,err,ret)    ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
+                LWIP_EVENT_ACCEPT, NULL, 0, err)
+#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
+                   LWIP_EVENT_SENT, NULL, space, ERR_OK)
+#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
+                LWIP_EVENT_RECV, (p), 0, (err))
+#define TCP_EVENT_CLOSED(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
+                LWIP_EVENT_RECV, NULL, 0, ERR_OK)
+#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
+                LWIP_EVENT_CONNECTED, NULL, 0, (err))
+#define TCP_EVENT_POLL(pcb,ret)       ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
+                LWIP_EVENT_POLL, NULL, 0, ERR_OK)
+#define TCP_EVENT_ERR(errf,arg,err)  lwip_tcp_event((arg), NULL, \
+                LWIP_EVENT_ERR, NULL, 0, (err))
+
+#else /* LWIP_EVENT_API */
+
+#define TCP_EVENT_ACCEPT(pcb,err,ret)                          \
+  do {                                                         \
+    if((pcb)->accept != NULL)                                  \
+      (ret) = (pcb)->accept((pcb)->callback_arg,(pcb),(err));  \
+    else (ret) = ERR_ARG;                                      \
+  } while (0)
+
+#define TCP_EVENT_SENT(pcb,space,ret)                          \
+  do {                                                         \
+    if((pcb)->sent != NULL)                                    \
+      (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space));  \
+    else (ret) = ERR_OK;                                       \
+  } while (0)
+
+#define TCP_EVENT_RECV(pcb,p,err,ret)                          \
+  do {                                                         \
+    if((pcb)->recv != NULL) {                                  \
+      (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err));\
+    } else {                                                   \
+      (ret) = tcp_recv_null(NULL, (pcb), (p), (err));          \
+    }                                                          \
+  } while (0)
+
+#define TCP_EVENT_CLOSED(pcb,ret)                                \
+  do {                                                           \
+    if(((pcb)->recv != NULL)) {                                  \
+      (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),NULL,ERR_OK);\
+    } else {                                                     \
+      (ret) = ERR_OK;                                            \
+    }                                                            \
+  } while (0)
+
+#define TCP_EVENT_CONNECTED(pcb,err,ret)                         \
+  do {                                                           \
+    if((pcb)->connected != NULL)                                 \
+      (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \
+    else (ret) = ERR_OK;                                         \
+  } while (0)
+
+#define TCP_EVENT_POLL(pcb,ret)                                \
+  do {                                                         \
+    if((pcb)->poll != NULL)                                    \
+      (ret) = (pcb)->poll((pcb)->callback_arg,(pcb));          \
+    else (ret) = ERR_OK;                                       \
+  } while (0)
+
+#define TCP_EVENT_ERR(errf,arg,err)                            \
+  do {                                                         \
+    if((errf) != NULL)                                         \
+      (errf)((arg),(err));                                     \
+  } while (0)
+
+#endif /* LWIP_EVENT_API */
+
+/** Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled */
+#if TCP_OVERSIZE && defined(LWIP_DEBUG)
+#define TCP_OVERSIZE_DBGCHECK 1
+#else
+#define TCP_OVERSIZE_DBGCHECK 0
+#endif
+
+/** Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled */
+#define TCP_CHECKSUM_ON_COPY  (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP)
+
+/* This structure represents a TCP segment on the unsent, unacked and ooseq queues */
+struct tcp_seg {
+  struct tcp_seg *next;    /* used when putting segements on a queue */
+  struct pbuf *p;          /* buffer containing data + TCP header */
+  u16_t len;               /* the TCP length of this segment */
+#if TCP_OVERSIZE_DBGCHECK
+  u16_t oversize_left;     /* Extra bytes available at the end of the last
+                              pbuf in unsent (used for asserting vs.
+                              tcp_pcb.unsent_oversized only) */
+#endif /* TCP_OVERSIZE_DBGCHECK */ 
+#if TCP_CHECKSUM_ON_COPY
+  u16_t chksum;
+  u8_t  chksum_swapped;
+#endif /* TCP_CHECKSUM_ON_COPY */
+  u8_t  flags;
+#define TF_SEG_OPTS_MSS         (u8_t)0x01U /* Include MSS option. */
+#define TF_SEG_OPTS_TS          (u8_t)0x02U /* Include timestamp option. */
+#define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is
+                                               checksummed into 'chksum' */
+  struct tcp_hdr *tcphdr;  /* the TCP header */
+};
+
+#define LWIP_TCP_OPT_LENGTH(flags)              \
+  (flags & TF_SEG_OPTS_MSS ? 4  : 0) +          \
+  (flags & TF_SEG_OPTS_TS  ? 12 : 0)
+
+/** This returns a TCP header option for MSS in an u32_t */
+#define TCP_BUILD_MSS_OPTION(mss) htonl(0x02040000 | ((mss) & 0xFFFF))
+
+/* Global variables: */
+extern struct tcp_pcb *tcp_input_pcb;
+extern u32_t tcp_ticks;
+extern u8_t tcp_active_pcbs_changed;
+
+/* The TCP PCB lists. */
+union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */
+  struct tcp_pcb_listen *listen_pcbs; 
+  struct tcp_pcb *pcbs;
+};
+extern struct tcp_pcb *tcp_bound_pcbs;
+extern union tcp_listen_pcbs_t tcp_listen_pcbs;
+extern struct tcp_pcb *tcp_active_pcbs;  /* List of all TCP PCBs that are in a
+              state in which they accept or send
+              data. */
+extern struct tcp_pcb *tcp_tw_pcbs;      /* List of all TCP PCBs in TIME-WAIT. */
+
+extern struct tcp_pcb *tcp_tmp_pcb;      /* Only used for temporary storage. */
+
+/* Axioms about the above lists:   
+   1) Every TCP PCB that is not CLOSED is in one of the lists.
+   2) A PCB is only in one of the lists.
+   3) All PCBs in the tcp_listen_pcbs list is in LISTEN state.
+   4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state.
+*/
+/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB
+   with a PCB list or removes a PCB from a list, respectively. */
+#ifndef TCP_DEBUG_PCB_LISTS
+#define TCP_DEBUG_PCB_LISTS 0
+#endif
+#if TCP_DEBUG_PCB_LISTS
+#define TCP_REG(pcbs, npcb) do {\
+                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", (npcb), (npcb)->local_port)); \
+                            for(tcp_tmp_pcb = *(pcbs); \
+          tcp_tmp_pcb != NULL; \
+        tcp_tmp_pcb = tcp_tmp_pcb->next) { \
+                                LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \
+                            } \
+                            LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \
+                            (npcb)->next = *(pcbs); \
+                            LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \
+                            *(pcbs) = (npcb); \
+                            LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
+              tcp_timer_needed(); \
+                            } while(0)
+#define TCP_RMV(pcbs, npcb) do { \
+                            LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \
+                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (npcb), *(pcbs))); \
+                            if(*(pcbs) == (npcb)) { \
+                               *(pcbs) = (*pcbs)->next; \
+                            } else for(tcp_tmp_pcb = *(pcbs); tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
+                               if(tcp_tmp_pcb->next == (npcb)) { \
+                                  tcp_tmp_pcb->next = (npcb)->next; \
+                                  break; \
+                               } \
+                            } \
+                            (npcb)->next = NULL; \
+                            LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
+                            LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (npcb), *(pcbs))); \
+                            } while(0)
+
+#else /* LWIP_DEBUG */
+
+#define TCP_REG(pcbs, npcb)                        \
+  do {                                             \
+    (npcb)->next = *pcbs;                          \
+    *(pcbs) = (npcb);                              \
+    tcp_timer_needed();                            \
+  } while (0)
+
+#define TCP_RMV(pcbs, npcb)                        \
+  do {                                             \
+    if(*(pcbs) == (npcb)) {                        \
+      (*(pcbs)) = (*pcbs)->next;                   \
+    }                                              \
+    else {                                         \
+      for(tcp_tmp_pcb = *pcbs;                     \
+          tcp_tmp_pcb != NULL;                     \
+          tcp_tmp_pcb = tcp_tmp_pcb->next) {       \
+        if(tcp_tmp_pcb->next == (npcb)) {          \
+          tcp_tmp_pcb->next = (npcb)->next;        \
+          break;                                   \
+        }                                          \
+      }                                            \
+    }                                              \
+    (npcb)->next = NULL;                           \
+  } while(0)
+
+#endif /* LWIP_DEBUG */
+
+#define TCP_REG_ACTIVE(npcb)                       \
+  do {                                             \
+    TCP_REG(&tcp_active_pcbs, npcb);               \
+    tcp_active_pcbs_changed = 1;                   \
+  } while (0)
+
+#define TCP_RMV_ACTIVE(npcb)                       \
+  do {                                             \
+    TCP_RMV(&tcp_active_pcbs, npcb);               \
+    tcp_active_pcbs_changed = 1;                   \
+  } while (0)
+
+#define TCP_PCB_REMOVE_ACTIVE(pcb)                 \
+  do {                                             \
+    tcp_pcb_remove(&tcp_active_pcbs, pcb);         \
+    tcp_active_pcbs_changed = 1;                   \
+  } while (0)
+
+
+/* Internal functions: */
+struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);
+void tcp_pcb_purge(struct tcp_pcb *pcb);
+void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);
+
+void tcp_segs_free(struct tcp_seg *seg);
+void tcp_seg_free(struct tcp_seg *seg);
+struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
+
+#define tcp_ack(pcb)                               \
+  do {                                             \
+    if((pcb)->flags & TF_ACK_DELAY) {              \
+      (pcb)->flags &= ~TF_ACK_DELAY;               \
+      (pcb)->flags |= TF_ACK_NOW;                  \
+    }                                              \
+    else {                                         \
+      (pcb)->flags |= TF_ACK_DELAY;                \
+    }                                              \
+  } while (0)
+
+#define tcp_ack_now(pcb)                           \
+  do {                                             \
+    (pcb)->flags |= TF_ACK_NOW;                    \
+  } while (0)
+
+err_t tcp_send_fin(struct tcp_pcb *pcb);
+err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags);
+
+void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);
+
+void tcp_rst(u32_t seqno, u32_t ackno,
+       ip_addr_t *local_ip, ip_addr_t *remote_ip,
+       u16_t local_port, u16_t remote_port);
+
+u32_t tcp_next_iss(void);
+
+void tcp_keepalive(struct tcp_pcb *pcb);
+void tcp_zero_window_probe(struct tcp_pcb *pcb);
+
+#if TCP_CALCULATE_EFF_SEND_MSS
+u16_t tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr);
+#endif /* TCP_CALCULATE_EFF_SEND_MSS */
+
+#if LWIP_CALLBACK_API
+err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
+#endif /* LWIP_CALLBACK_API */
+
+#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
+void tcp_debug_print(struct tcp_hdr *tcphdr);
+void tcp_debug_print_flags(u8_t flags);
+void tcp_debug_print_state(enum tcp_state s);
+void tcp_debug_print_pcbs(void);
+s16_t tcp_pcbs_sane(void);
+#else
+#  define tcp_debug_print(tcphdr)
+#  define tcp_debug_print_flags(flags)
+#  define tcp_debug_print_state(s)
+#  define tcp_debug_print_pcbs()
+#  define tcp_pcbs_sane() 1
+#endif /* TCP_DEBUG */
+
+/** External function (implemented in timers.c), called when TCP detects
+ * that a timer is needed (i.e. active- or time-wait-pcb found). */
+void tcp_timer_needed(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_TCP */
+
+#endif /* __LWIP_TCP_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/tcpip.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/tcpip.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/tcpip.h	(revision 164)
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_TCPIP_H__
+#define __LWIP_TCPIP_H__
+
+#include "lwip/opt.h"
+
+#if !NO_SYS /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/api_msg.h"
+#include "lwip/netifapi.h"
+#include "lwip/pbuf.h"
+#include "lwip/api.h"
+#include "lwip/sys.h"
+#include "lwip/timers.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Define this to something that triggers a watchdog. This is called from
+ * tcpip_thread after processing a message. */
+#ifndef LWIP_TCPIP_THREAD_ALIVE
+#define LWIP_TCPIP_THREAD_ALIVE()
+#endif
+
+#if LWIP_TCPIP_CORE_LOCKING
+/** The global semaphore to lock the stack. */
+extern sys_mutex_t lock_tcpip_core;
+#define LOCK_TCPIP_CORE()     sys_mutex_lock(&lock_tcpip_core)
+#define UNLOCK_TCPIP_CORE()   sys_mutex_unlock(&lock_tcpip_core)
+#define TCPIP_APIMSG(m)       tcpip_apimsg_lock(m)
+#define TCPIP_APIMSG_ACK(m)
+#define TCPIP_NETIFAPI(m)     tcpip_netifapi_lock(m)
+#define TCPIP_NETIFAPI_ACK(m)
+#else /* LWIP_TCPIP_CORE_LOCKING */
+#define LOCK_TCPIP_CORE()
+#define UNLOCK_TCPIP_CORE()
+#define TCPIP_APIMSG(m)       tcpip_apimsg(m)
+#define TCPIP_APIMSG_ACK(m)   sys_sem_signal(&m->conn->op_completed)
+#define TCPIP_NETIFAPI(m)     tcpip_netifapi(m)
+#define TCPIP_NETIFAPI_ACK(m) sys_sem_signal(&m->sem)
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+
+/** Function prototype for the init_done function passed to tcpip_init */
+typedef void (*tcpip_init_done_fn)(void *arg);
+/** Function prototype for functions passed to tcpip_callback() */
+typedef void (*tcpip_callback_fn)(void *ctx);
+
+/* Forward declarations */
+struct tcpip_callback_msg;
+
+void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg);
+
+#if LWIP_NETCONN
+err_t tcpip_apimsg(struct api_msg *apimsg);
+#if LWIP_TCPIP_CORE_LOCKING
+err_t tcpip_apimsg_lock(struct api_msg *apimsg);
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+#endif /* LWIP_NETCONN */
+
+err_t tcpip_input(struct pbuf *p, struct netif *inp);
+
+#if LWIP_NETIF_API
+err_t tcpip_netifapi(struct netifapi_msg *netifapimsg);
+#if LWIP_TCPIP_CORE_LOCKING
+err_t tcpip_netifapi_lock(struct netifapi_msg *netifapimsg);
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+#endif /* LWIP_NETIF_API */
+
+err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block);
+#define tcpip_callback(f, ctx)              tcpip_callback_with_block(f, ctx, 1)
+
+struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx);
+void   tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg);
+err_t  tcpip_trycallback(struct tcpip_callback_msg* msg);
+
+/* free pbufs or heap memory from another context without blocking */
+err_t pbuf_free_callback(struct pbuf *p);
+err_t mem_free_callback(void *m);
+
+#if LWIP_TCPIP_TIMEOUT
+err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg);
+err_t tcpip_untimeout(sys_timeout_handler h, void *arg);
+#endif /* LWIP_TCPIP_TIMEOUT */
+
+enum tcpip_msg_type {
+#if LWIP_NETCONN
+  TCPIP_MSG_API,
+#endif /* LWIP_NETCONN */
+  TCPIP_MSG_INPKT,
+#if LWIP_NETIF_API
+  TCPIP_MSG_NETIFAPI,
+#endif /* LWIP_NETIF_API */
+#if LWIP_TCPIP_TIMEOUT
+  TCPIP_MSG_TIMEOUT,
+  TCPIP_MSG_UNTIMEOUT,
+#endif /* LWIP_TCPIP_TIMEOUT */
+  TCPIP_MSG_CALLBACK,
+  TCPIP_MSG_CALLBACK_STATIC
+};
+
+struct tcpip_msg {
+  enum tcpip_msg_type type;
+  sys_sem_t *sem;
+  union {
+#if LWIP_NETCONN
+    struct api_msg *apimsg;
+#endif /* LWIP_NETCONN */
+#if LWIP_NETIF_API
+    struct netifapi_msg *netifapimsg;
+#endif /* LWIP_NETIF_API */
+    struct {
+      struct pbuf *p;
+      struct netif *netif;
+    } inp;
+    struct {
+      tcpip_callback_fn function;
+      void *ctx;
+    } cb;
+#if LWIP_TCPIP_TIMEOUT
+    struct {
+      u32_t msecs;
+      sys_timeout_handler h;
+      void *arg;
+    } tmo;
+#endif /* LWIP_TCPIP_TIMEOUT */
+  } msg;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !NO_SYS */
+
+#endif /* __LWIP_TCPIP_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/timers.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/timers.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/timers.h	(revision 164)
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *         Simon Goldschmidt
+ *
+ */
+#ifndef __LWIP_TIMERS_H__
+#define __LWIP_TIMERS_H__
+
+#include "lwip/opt.h"
+
+/* Timers are not supported when NO_SYS==1 and NO_SYS_NO_TIMERS==1 */
+#define LWIP_TIMERS (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS))
+
+#if LWIP_TIMERS
+
+#include "lwip/err.h"
+#if !NO_SYS
+#include "lwip/sys.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef LWIP_DEBUG_TIMERNAMES
+#ifdef LWIP_DEBUG
+#define LWIP_DEBUG_TIMERNAMES SYS_DEBUG
+#else /* LWIP_DEBUG */
+#define LWIP_DEBUG_TIMERNAMES 0
+#endif /* LWIP_DEBUG*/
+#endif
+
+/** Function prototype for a timeout callback function. Register such a function
+ * using sys_timeout().
+ *
+ * @param arg Additional argument to pass to the function - set up by sys_timeout()
+ */
+typedef void (* sys_timeout_handler)(void *arg);
+
+struct sys_timeo {
+  struct sys_timeo *next;
+  u32_t time;
+  sys_timeout_handler h;
+  void *arg;
+#if LWIP_DEBUG_TIMERNAMES
+  const char* handler_name;
+#endif /* LWIP_DEBUG_TIMERNAMES */
+};
+
+void sys_timeouts_init(void);
+
+#if LWIP_DEBUG_TIMERNAMES
+void sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name);
+#define sys_timeout(msecs, handler, arg) sys_timeout_debug(msecs, handler, arg, #handler)
+#else /* LWIP_DEBUG_TIMERNAMES */
+void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg);
+#endif /* LWIP_DEBUG_TIMERNAMES */
+
+void sys_untimeout(sys_timeout_handler handler, void *arg);
+#if NO_SYS
+void sys_check_timeouts(void);
+void sys_restart_timeouts(void);
+#else /* NO_SYS */
+void sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg);
+#endif /* NO_SYS */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_TIMERS */
+#endif /* __LWIP_TIMERS_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/udp.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/udp.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/lwip/udp.h	(revision 164)
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __LWIP_UDP_H__
+#define __LWIP_UDP_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/pbuf.h"
+#include "lwip/netif.h"
+#include "lwip/ip_addr.h"
+#include "lwip/ip.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UDP_HLEN 8
+
+/* Fields are (of course) in network byte order. */
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct udp_hdr {
+  PACK_STRUCT_FIELD(u16_t src);
+  PACK_STRUCT_FIELD(u16_t dest);  /* src/dest UDP ports */
+  PACK_STRUCT_FIELD(u16_t len);
+  PACK_STRUCT_FIELD(u16_t chksum);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#define UDP_FLAGS_NOCHKSUM       0x01U
+#define UDP_FLAGS_UDPLITE        0x02U
+#define UDP_FLAGS_CONNECTED      0x04U
+#define UDP_FLAGS_MULTICAST_LOOP 0x08U
+
+struct udp_pcb;
+
+/** Function prototype for udp pcb receive callback functions
+ * addr and port are in same byte order as in the pcb
+ * The callback is responsible for freeing the pbuf
+ * if it's not used any more.
+ *
+ * ATTENTION: Be aware that 'addr' points into the pbuf 'p' so freeing this pbuf
+ *            makes 'addr' invalid, too.
+ *
+ * @param arg user supplied argument (udp_pcb.recv_arg)
+ * @param pcb the udp_pcb which received data
+ * @param p the packet buffer that was received
+ * @param addr the remote IP address from which the packet was received
+ * @param port the remote port from which the packet was received
+ */
+typedef void (*udp_recv_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p,
+    ip_addr_t *addr, u16_t port);
+
+
+struct udp_pcb {
+/* Common members of all PCB types */
+  IP_PCB;
+
+/* Protocol specific PCB members */
+
+  struct udp_pcb *next;
+
+  u8_t flags;
+  /** ports are in host byte order */
+  u16_t local_port, remote_port;
+
+#if LWIP_IGMP
+  /** outgoing network interface for multicast packets */
+  ip_addr_t multicast_ip;
+#endif /* LWIP_IGMP */
+
+#if LWIP_UDPLITE
+  /** used for UDP_LITE only */
+  u16_t chksum_len_rx, chksum_len_tx;
+#endif /* LWIP_UDPLITE */
+
+  /** receive callback function */
+  udp_recv_fn recv;
+  /** user-supplied argument for the recv callback */
+  void *recv_arg;  
+};
+/* udp_pcbs export for exernal reference (e.g. SNMP agent) */
+extern struct udp_pcb *udp_pcbs;
+
+/* The following functions is the application layer interface to the
+   UDP code. */
+struct udp_pcb * udp_new        (void);
+void             udp_remove     (struct udp_pcb *pcb);
+err_t            udp_bind       (struct udp_pcb *pcb, ip_addr_t *ipaddr,
+                                 u16_t port);
+err_t            udp_connect    (struct udp_pcb *pcb, ip_addr_t *ipaddr,
+                                 u16_t port);
+void             udp_disconnect (struct udp_pcb *pcb);
+void             udp_recv       (struct udp_pcb *pcb, udp_recv_fn recv,
+                                 void *recv_arg);
+err_t            udp_sendto_if  (struct udp_pcb *pcb, struct pbuf *p,
+                                 ip_addr_t *dst_ip, u16_t dst_port,
+                                 struct netif *netif);
+err_t            udp_sendto     (struct udp_pcb *pcb, struct pbuf *p,
+                                 ip_addr_t *dst_ip, u16_t dst_port);
+err_t            udp_send       (struct udp_pcb *pcb, struct pbuf *p);
+
+#if LWIP_CHECKSUM_ON_COPY
+err_t            udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p,
+                                 ip_addr_t *dst_ip, u16_t dst_port,
+                                 struct netif *netif, u8_t have_chksum,
+                                 u16_t chksum);
+err_t            udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p,
+                                 ip_addr_t *dst_ip, u16_t dst_port,
+                                 u8_t have_chksum, u16_t chksum);
+err_t            udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p,
+                                 u8_t have_chksum, u16_t chksum);
+#endif /* LWIP_CHECKSUM_ON_COPY */
+
+#define          udp_flags(pcb) ((pcb)->flags)
+#define          udp_setflags(pcb, f)  ((pcb)->flags = (f))
+
+/* The following functions are the lower layer interface to UDP. */
+void             udp_input      (struct pbuf *p, struct netif *inp);
+
+void             udp_init       (void);
+
+#if UDP_DEBUG
+void udp_debug_print(struct udp_hdr *udphdr);
+#else
+#define udp_debug_print(udphdr)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_UDP */
+
+#endif /* __LWIP_UDP_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/netif/etharp.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/netif/etharp.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/netif/etharp.h	(revision 164)
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
+ * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __NETIF_ETHARP_H__
+#define __NETIF_ETHARP_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_ARP || LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/pbuf.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/ip.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ETHARP_HWADDR_LEN
+#define ETHARP_HWADDR_LEN     6
+#endif
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct eth_addr {
+  PACK_STRUCT_FIELD(u8_t addr[ETHARP_HWADDR_LEN]);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+/** Ethernet header */
+struct eth_hdr {
+#if ETH_PAD_SIZE
+  PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]);
+#endif
+  PACK_STRUCT_FIELD(struct eth_addr dest);
+  PACK_STRUCT_FIELD(struct eth_addr src);
+  PACK_STRUCT_FIELD(u16_t type);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE)
+
+#if ETHARP_SUPPORT_VLAN
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+/** VLAN header inserted between ethernet header and payload
+ * if 'type' in ethernet header is ETHTYPE_VLAN.
+ * See IEEE802.Q */
+struct eth_vlan_hdr {
+  PACK_STRUCT_FIELD(u16_t prio_vid);
+  PACK_STRUCT_FIELD(u16_t tpid);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#define SIZEOF_VLAN_HDR 4
+#define VLAN_ID(vlan_hdr) (htons((vlan_hdr)->prio_vid) & 0xFFF)
+
+#endif /* ETHARP_SUPPORT_VLAN */
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+/** the ARP message, see RFC 826 ("Packet format") */
+struct etharp_hdr {
+  PACK_STRUCT_FIELD(u16_t hwtype);
+  PACK_STRUCT_FIELD(u16_t proto);
+  PACK_STRUCT_FIELD(u8_t  hwlen);
+  PACK_STRUCT_FIELD(u8_t  protolen);
+  PACK_STRUCT_FIELD(u16_t opcode);
+  PACK_STRUCT_FIELD(struct eth_addr shwaddr);
+  PACK_STRUCT_FIELD(struct ip_addr2 sipaddr);
+  PACK_STRUCT_FIELD(struct eth_addr dhwaddr);
+  PACK_STRUCT_FIELD(struct ip_addr2 dipaddr);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#define SIZEOF_ETHARP_HDR 28
+#define SIZEOF_ETHARP_PACKET (SIZEOF_ETH_HDR + SIZEOF_ETHARP_HDR)
+
+/** 5 seconds period */
+#define ARP_TMR_INTERVAL 5000
+
+#define ETHTYPE_ARP       0x0806U
+#define ETHTYPE_IP        0x0800U
+#define ETHTYPE_VLAN      0x8100U
+#define ETHTYPE_PPPOEDISC 0x8863U  /* PPP Over Ethernet Discovery Stage */
+#define ETHTYPE_PPPOE     0x8864U  /* PPP Over Ethernet Session Stage */
+
+/** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables
+ * or known to be 32-bit aligned within the protocol header. */
+#ifndef ETHADDR32_COPY
+#define ETHADDR32_COPY(src, dst)  SMEMCPY(src, dst, ETHARP_HWADDR_LEN)
+#endif
+
+/** MEMCPY-like macro to copy to/from struct eth_addr's that are no local
+ * variables and known to be 16-bit aligned within the protocol header. */
+#ifndef ETHADDR16_COPY
+#define ETHADDR16_COPY(src, dst)  SMEMCPY(src, dst, ETHARP_HWADDR_LEN)
+#endif
+
+#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */
+
+/** ARP message types (opcodes) */
+#define ARP_REQUEST 1
+#define ARP_REPLY   2
+
+/** Define this to 1 and define LWIP_ARP_FILTER_NETIF_FN(pbuf, netif, type)
+ * to a filter function that returns the correct netif when using multiple
+ * netifs on one hardware interface where the netif's low-level receive
+ * routine cannot decide for the correct netif (e.g. when mapping multiple
+ * IP addresses to one hardware interface).
+ */
+#ifndef LWIP_ARP_FILTER_NETIF
+#define LWIP_ARP_FILTER_NETIF 0
+#endif
+
+#if ARP_QUEUEING
+/** struct for queueing outgoing packets for unknown address
+  * defined here to be accessed by memp.h
+  */
+struct etharp_q_entry {
+  struct etharp_q_entry *next;
+  struct pbuf *p;
+};
+#endif /* ARP_QUEUEING */
+
+#define etharp_init() /* Compatibility define, not init needed. */
+void etharp_tmr(void);
+s8_t etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr,
+         struct eth_addr **eth_ret, ip_addr_t **ip_ret);
+err_t etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr);
+err_t etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q);
+err_t etharp_request(struct netif *netif, ip_addr_t *ipaddr);
+/** For Ethernet network interfaces, we might want to send "gratuitous ARP";
+ *  this is an ARP packet sent by a node in order to spontaneously cause other
+ *  nodes to update an entry in their ARP cache.
+ *  From RFC 3220 "IP Mobility Support for IPv4" section 4.6. */
+#define etharp_gratuitous(netif) etharp_request((netif), &(netif)->ip_addr)
+void etharp_cleanup_netif(struct netif *netif);
+
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+err_t etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr);
+err_t etharp_remove_static_entry(ip_addr_t *ipaddr);
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+
+#if LWIP_AUTOIP
+err_t etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
+                 const struct eth_addr *ethdst_addr,
+                 const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr,
+                 const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr,
+                 const u16_t opcode);
+#endif /* LWIP_AUTOIP */
+
+#endif /* LWIP_ARP */
+
+err_t ethernet_input(struct pbuf *p, struct netif *netif);
+
+#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETHARP_HWADDR_LEN) == 0)
+
+extern const struct eth_addr ethbroadcast, ethzero;
+
+#endif /* LWIP_ARP || LWIP_ETHERNET */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __NETIF_ARP_H__ */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/netif/ppp_oe.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/netif/ppp_oe.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/netif/ppp_oe.h	(revision 164)
@@ -0,0 +1,190 @@
+/*****************************************************************************
+* ppp_oe.h - PPP Over Ethernet implementation for lwIP.
+*
+* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 06-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+*****************************************************************************/
+
+
+
+/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Martin Husemann <martin@NetBSD.org>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef PPP_OE_H
+#define PPP_OE_H
+
+#include "lwip/opt.h"
+
+#if PPPOE_SUPPORT > 0
+
+#include "netif/etharp.h"
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct pppoehdr {
+  PACK_STRUCT_FIELD(u8_t vertype);
+  PACK_STRUCT_FIELD(u8_t code);
+  PACK_STRUCT_FIELD(u16_t session);
+  PACK_STRUCT_FIELD(u16_t plen);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/bpstruct.h"
+#endif
+PACK_STRUCT_BEGIN
+struct pppoetag {
+  PACK_STRUCT_FIELD(u16_t tag);
+  PACK_STRUCT_FIELD(u16_t len);
+} PACK_STRUCT_STRUCT;
+PACK_STRUCT_END
+#ifdef PACK_STRUCT_USE_INCLUDES
+#  include "arch/epstruct.h"
+#endif
+
+
+#define PPPOE_STATE_INITIAL   0
+#define PPPOE_STATE_PADI_SENT 1
+#define PPPOE_STATE_PADR_SENT 2
+#define PPPOE_STATE_SESSION   3
+#define PPPOE_STATE_CLOSING   4
+/* passive */
+#define PPPOE_STATE_PADO_SENT 1
+
+#define PPPOE_HEADERLEN       sizeof(struct pppoehdr)
+#define PPPOE_VERTYPE         0x11    /* VER=1, TYPE = 1 */
+
+#define PPPOE_TAG_EOL         0x0000  /* end of list */
+#define PPPOE_TAG_SNAME       0x0101  /* service name */
+#define PPPOE_TAG_ACNAME      0x0102  /* access concentrator name */
+#define PPPOE_TAG_HUNIQUE     0x0103  /* host unique */
+#define PPPOE_TAG_ACCOOKIE    0x0104  /* AC cookie */
+#define PPPOE_TAG_VENDOR      0x0105  /* vendor specific */
+#define PPPOE_TAG_RELAYSID    0x0110  /* relay session id */
+#define PPPOE_TAG_SNAME_ERR   0x0201  /* service name error */
+#define PPPOE_TAG_ACSYS_ERR   0x0202  /* AC system error */
+#define PPPOE_TAG_GENERIC_ERR 0x0203  /* gerneric error */
+
+#define PPPOE_CODE_PADI       0x09    /* Active Discovery Initiation */
+#define PPPOE_CODE_PADO       0x07    /* Active Discovery Offer */
+#define PPPOE_CODE_PADR       0x19    /* Active Discovery Request */
+#define PPPOE_CODE_PADS       0x65    /* Active Discovery Session confirmation */
+#define PPPOE_CODE_PADT       0xA7    /* Active Discovery Terminate */
+
+#ifndef ETHERMTU
+#define ETHERMTU 1500
+#endif
+
+/* two byte PPP protocol discriminator, then IP data */
+#define PPPOE_MAXMTU          (ETHERMTU-PPPOE_HEADERLEN-2)
+
+#ifndef PPPOE_MAX_AC_COOKIE_LEN
+#define PPPOE_MAX_AC_COOKIE_LEN   64
+#endif
+
+struct pppoe_softc {
+  struct pppoe_softc *next;
+  struct netif *sc_ethif;      /* ethernet interface we are using */
+  int sc_pd;                   /* ppp unit number */
+  void (*sc_linkStatusCB)(int pd, int up);
+
+  int sc_state;                /* discovery phase or session connected */
+  struct eth_addr sc_dest;     /* hardware address of concentrator */
+  u16_t sc_session;            /* PPPoE session id */
+
+#ifdef PPPOE_TODO
+  char *sc_service_name;       /* if != NULL: requested name of service */
+  char *sc_concentrator_name;  /* if != NULL: requested concentrator id */
+#endif /* PPPOE_TODO */
+  u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */
+  size_t sc_ac_cookie_len;     /* length of cookie data */
+#ifdef PPPOE_SERVER
+  u8_t *sc_hunique;            /* content of host unique we must echo back */
+  size_t sc_hunique_len;       /* length of host unique */
+#endif
+  int sc_padi_retried;         /* number of PADI retries already done */
+  int sc_padr_retried;         /* number of PADR retries already done */
+};
+
+
+#define pppoe_init() /* compatibility define, no initialization needed */
+
+err_t pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr);
+err_t pppoe_destroy(struct netif *ifp);
+
+int pppoe_connect(struct pppoe_softc *sc);
+void pppoe_disconnect(struct pppoe_softc *sc);
+
+void pppoe_disc_input(struct netif *netif, struct pbuf *p);
+void pppoe_data_input(struct netif *netif, struct pbuf *p);
+
+err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb);
+
+/** used in ppp.c */
+#define PPPOE_HDRLEN (sizeof(struct eth_hdr) + PPPOE_HEADERLEN)
+
+#endif /* PPPOE_SUPPORT */
+
+#endif /* PPP_OE_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/netif/slipif.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/netif/slipif.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/netif/slipif.h	(revision 164)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef __NETIF_SLIPIF_H__
+#define __NETIF_SLIPIF_H__
+
+#include "lwip/opt.h"
+#include "lwip/netif.h"
+
+/** Set this to 1 to start a thread that blocks reading on the serial line
+ * (using sio_read()).
+ */
+#ifndef SLIP_USE_RX_THREAD
+#define SLIP_USE_RX_THREAD !NO_SYS
+#endif
+
+/** Set this to 1 to enable functions to pass in RX bytes from ISR context.
+ * If enabled, slipif_received_byte[s]() process incoming bytes and put assembled
+ * packets on a queue, which is fed into lwIP from slipif_poll().
+ * If disabled, slipif_poll() polls the serila line (using sio_tryread()).
+ */
+#ifndef SLIP_RX_FROM_ISR
+#define SLIP_RX_FROM_ISR 0
+#endif
+
+/** Set this to 1 (default for SLIP_RX_FROM_ISR) to queue incoming packets
+ * received by slipif_received_byte[s]() as long as PBUF_POOL pbufs are available.
+ * If disabled, packets will be dropped if more than one packet is received.
+ */
+#ifndef SLIP_RX_QUEUE
+#define SLIP_RX_QUEUE SLIP_RX_FROM_ISR
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+err_t slipif_init(struct netif * netif);
+void slipif_poll(struct netif *netif);
+#if SLIP_RX_FROM_ISR
+void slipif_process_rxqueue(struct netif *netif);
+void slipif_received_byte(struct netif *netif, u8_t data);
+void slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len);
+#endif /* SLIP_RX_FROM_ISR */
+
+#ifdef __cplusplus
+}
+#endif
+ 
+#endif 
+
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/posix/netdb.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/posix/netdb.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/posix/netdb.h	(revision 164)
@@ -0,0 +1,33 @@
+/**
+ * @file
+ * This file is a posix wrapper for lwip/netdb.h.
+ */
+
+/*
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#include "lwip/netdb.h"
Index: UsbWattMeter/trunk/lwip-1.4.1/src/include/posix/sys/socket.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/include/posix/sys/socket.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/include/posix/sys/socket.h	(revision 164)
@@ -0,0 +1,33 @@
+/**
+ * @file
+ * This file is a posix wrapper for lwip/sockets.h.
+ */
+
+/*
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+
+#include "lwip/sockets.h"
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/FILES
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/FILES	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/FILES	(revision 164)
@@ -0,0 +1,29 @@
+This directory contains generic network interface device drivers that
+do not contain any hardware or architecture specific code. The files
+are:
+
+etharp.c
+          Implements the ARP (Address Resolution Protocol) over
+          Ethernet. The code in this file should be used together with
+          Ethernet device drivers. Note that this module has been
+          largely made Ethernet independent so you should be able to
+          adapt this for other link layers (such as Firewire).
+
+ethernetif.c
+          An example of how an Ethernet device driver could look. This
+          file can be used as a "skeleton" for developing new Ethernet
+          network device drivers. It uses the etharp.c ARP code.
+
+loopif.c
+          A "loopback" network interface driver. It requires configuration
+          through the define LWIP_LOOPIF_MULTITHREADING (see opt.h).
+
+slipif.c
+          A generic implementation of the SLIP (Serial Line IP)
+          protocol. It requires a sio (serial I/O) module to work.
+
+ppp/      Point-to-Point Protocol stack
+          The PPP stack has been ported from ucip (http://ucip.sourceforge.net).
+          It matches quite well to pppd 2.3.1 (http://ppp.samba.org), although
+          compared to that, it has some modifications for embedded systems and
+          the source code has been reordered a bit.
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/etharp.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/etharp.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/etharp.c	(revision 164)
@@ -0,0 +1,1399 @@
+/**
+ * @file
+ * Address Resolution Protocol module for IP over Ethernet
+ *
+ * Functionally, ARP is divided into two parts. The first maps an IP address
+ * to a physical address when sending a packet, and the second part answers
+ * requests from other machines for our physical address.
+ *
+ * This implementation complies with RFC 826 (Ethernet ARP). It supports
+ * Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6
+ * if an interface calls etharp_gratuitous(our_netif) upon address change.
+ */
+
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
+ * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ */
+ 
+#include "lwip/opt.h"
+
+#if LWIP_ARP || LWIP_ETHERNET
+
+#include "lwip/ip_addr.h"
+#include "lwip/def.h"
+#include "lwip/ip.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#include "lwip/dhcp.h"
+#include "lwip/autoip.h"
+#include "netif/etharp.h"
+
+#if PPPOE_SUPPORT
+#include "netif/ppp_oe.h"
+#endif /* PPPOE_SUPPORT */
+
+#include <string.h>
+
+const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
+const struct eth_addr ethzero = {{0,0,0,0,0,0}};
+
+/** The 24-bit IANA multicast OUI is 01-00-5e: */
+#define LL_MULTICAST_ADDR_0 0x01
+#define LL_MULTICAST_ADDR_1 0x00
+#define LL_MULTICAST_ADDR_2 0x5e
+
+#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */
+
+/** the time an ARP entry stays valid after its last update,
+ *  for ARP_TMR_INTERVAL = 5000, this is
+ *  (240 * 5) seconds = 20 minutes.
+ */
+#define ARP_MAXAGE              240
+/** Re-request a used ARP entry 1 minute before it would expire to prevent
+ *  breaking a steadily used connection because the ARP entry timed out. */
+#define ARP_AGE_REREQUEST_USED  (ARP_MAXAGE - 12)
+
+/** the time an ARP entry stays pending after first request,
+ *  for ARP_TMR_INTERVAL = 5000, this is
+ *  (2 * 5) seconds = 10 seconds.
+ * 
+ *  @internal Keep this number at least 2, otherwise it might
+ *  run out instantly if the timeout occurs directly after a request.
+ */
+#define ARP_MAXPENDING 2
+
+#define HWTYPE_ETHERNET 1
+
+enum etharp_state {
+  ETHARP_STATE_EMPTY = 0,
+  ETHARP_STATE_PENDING,
+  ETHARP_STATE_STABLE,
+  ETHARP_STATE_STABLE_REREQUESTING
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+  ,ETHARP_STATE_STATIC
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+};
+
+struct etharp_entry {
+#if ARP_QUEUEING
+  /** Pointer to queue of pending outgoing packets on this ARP entry. */
+  struct etharp_q_entry *q;
+#else /* ARP_QUEUEING */
+  /** Pointer to a single pending outgoing packet on this ARP entry. */
+  struct pbuf *q;
+#endif /* ARP_QUEUEING */
+  ip_addr_t ipaddr;
+  struct netif *netif;
+  struct eth_addr ethaddr;
+  u8_t state;
+  u8_t ctime;
+};
+
+static struct etharp_entry arp_table[ARP_TABLE_SIZE];
+
+#if !LWIP_NETIF_HWADDRHINT
+static u8_t etharp_cached_entry;
+#endif /* !LWIP_NETIF_HWADDRHINT */
+
+/** Try hard to create a new entry - we want the IP address to appear in
+    the cache (even if this means removing an active entry or so). */
+#define ETHARP_FLAG_TRY_HARD     1
+#define ETHARP_FLAG_FIND_ONLY    2
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+#define ETHARP_FLAG_STATIC_ENTRY 4
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+
+#if LWIP_NETIF_HWADDRHINT
+#define ETHARP_SET_HINT(netif, hint)  if (((netif) != NULL) && ((netif)->addr_hint != NULL))  \
+                                      *((netif)->addr_hint) = (hint);
+#else /* LWIP_NETIF_HWADDRHINT */
+#define ETHARP_SET_HINT(netif, hint)  (etharp_cached_entry = (hint))
+#endif /* LWIP_NETIF_HWADDRHINT */
+
+
+/* Some checks, instead of etharp_init(): */
+#if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f))
+  #error "ARP_TABLE_SIZE must fit in an s8_t, you have to reduce it in your lwipopts.h"
+#endif
+
+
+#if ARP_QUEUEING
+/**
+ * Free a complete queue of etharp entries
+ *
+ * @param q a qeueue of etharp_q_entry's to free
+ */
+static void
+free_etharp_q(struct etharp_q_entry *q)
+{
+  struct etharp_q_entry *r;
+  LWIP_ASSERT("q != NULL", q != NULL);
+  LWIP_ASSERT("q->p != NULL", q->p != NULL);
+  while (q) {
+    r = q;
+    q = q->next;
+    LWIP_ASSERT("r->p != NULL", (r->p != NULL));
+    pbuf_free(r->p);
+    memp_free(MEMP_ARP_QUEUE, r);
+  }
+}
+#else /* ARP_QUEUEING */
+
+/** Compatibility define: free the queued pbuf */
+#define free_etharp_q(q) pbuf_free(q)
+
+#endif /* ARP_QUEUEING */
+
+/** Clean up ARP table entries */
+static void
+etharp_free_entry(int i)
+{
+  /* remove from SNMP ARP index tree */
+  snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr);
+  /* and empty packet queue */
+  if (arp_table[i].q != NULL) {
+    /* remove all queued packets */
+    LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q)));
+    free_etharp_q(arp_table[i].q);
+    arp_table[i].q = NULL;
+  }
+  /* recycle entry for re-use */
+  arp_table[i].state = ETHARP_STATE_EMPTY;
+#ifdef LWIP_DEBUG
+  /* for debugging, clean out the complete entry */
+  arp_table[i].ctime = 0;
+  arp_table[i].netif = NULL;
+  ip_addr_set_zero(&arp_table[i].ipaddr);
+  arp_table[i].ethaddr = ethzero;
+#endif /* LWIP_DEBUG */
+}
+
+/**
+ * Clears expired entries in the ARP table.
+ *
+ * This function should be called every ETHARP_TMR_INTERVAL milliseconds (5 seconds),
+ * in order to expire entries in the ARP table.
+ */
+void
+etharp_tmr(void)
+{
+  u8_t i;
+
+  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
+  /* remove expired entries from the ARP table */
+  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
+    u8_t state = arp_table[i].state;
+    if (state != ETHARP_STATE_EMPTY
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+      && (state != ETHARP_STATE_STATIC)
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+      ) {
+      arp_table[i].ctime++;
+      if ((arp_table[i].ctime >= ARP_MAXAGE) ||
+          ((arp_table[i].state == ETHARP_STATE_PENDING)  &&
+           (arp_table[i].ctime >= ARP_MAXPENDING))) {
+        /* pending or stable entry has become old! */
+        LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n",
+             arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i));
+        /* clean up entries that have just been expired */
+        etharp_free_entry(i);
+      }
+      else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING) {
+        /* Reset state to stable, so that the next transmitted packet will
+           re-send an ARP request. */
+        arp_table[i].state = ETHARP_STATE_STABLE;
+      }
+#if ARP_QUEUEING
+      /* still pending entry? (not expired) */
+      if (arp_table[i].state == ETHARP_STATE_PENDING) {
+        /* resend an ARP query here? */
+      }
+#endif /* ARP_QUEUEING */
+    }
+  }
+}
+
+/**
+ * Search the ARP table for a matching or new entry.
+ * 
+ * If an IP address is given, return a pending or stable ARP entry that matches
+ * the address. If no match is found, create a new entry with this address set,
+ * but in state ETHARP_EMPTY. The caller must check and possibly change the
+ * state of the returned entry.
+ * 
+ * If ipaddr is NULL, return a initialized new entry in state ETHARP_EMPTY.
+ * 
+ * In all cases, attempt to create new entries from an empty entry. If no
+ * empty entries are available and ETHARP_FLAG_TRY_HARD flag is set, recycle
+ * old entries. Heuristic choose the least important entry for recycling.
+ *
+ * @param ipaddr IP address to find in ARP cache, or to add if not found.
+ * @param flags @see definition of ETHARP_FLAG_*
+ * @param netif netif related to this address (used for NETIF_HWADDRHINT)
+ *  
+ * @return The ARP entry index that matched or is created, ERR_MEM if no
+ * entry is found or could be recycled.
+ */
+static s8_t
+etharp_find_entry(ip_addr_t *ipaddr, u8_t flags)
+{
+  s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
+  s8_t empty = ARP_TABLE_SIZE;
+  u8_t i = 0, age_pending = 0, age_stable = 0;
+  /* oldest entry with packets on queue */
+  s8_t old_queue = ARP_TABLE_SIZE;
+  /* its age */
+  u8_t age_queue = 0;
+
+  /**
+   * a) do a search through the cache, remember candidates
+   * b) select candidate entry
+   * c) create new entry
+   */
+
+  /* a) in a single search sweep, do all of this
+   * 1) remember the first empty entry (if any)
+   * 2) remember the oldest stable entry (if any)
+   * 3) remember the oldest pending entry without queued packets (if any)
+   * 4) remember the oldest pending entry with queued packets (if any)
+   * 5) search for a matching IP entry, either pending or stable
+   *    until 5 matches, or all entries are searched for.
+   */
+
+  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
+    u8_t state = arp_table[i].state;
+    /* no empty entry found yet and now we do find one? */
+    if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) {
+      LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %"U16_F"\n", (u16_t)i));
+      /* remember first empty entry */
+      empty = i;
+    } else if (state != ETHARP_STATE_EMPTY) {
+      LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE",
+        state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE);
+      /* if given, does IP address match IP address in ARP entry? */
+      if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %"U16_F"\n", (u16_t)i));
+        /* found exact IP address match, simply bail out */
+        return i;
+      }
+      /* pending entry? */
+      if (state == ETHARP_STATE_PENDING) {
+        /* pending with queued packets? */
+        if (arp_table[i].q != NULL) {
+          if (arp_table[i].ctime >= age_queue) {
+            old_queue = i;
+            age_queue = arp_table[i].ctime;
+          }
+        } else
+        /* pending without queued packets? */
+        {
+          if (arp_table[i].ctime >= age_pending) {
+            old_pending = i;
+            age_pending = arp_table[i].ctime;
+          }
+        }
+      /* stable entry? */
+      } else if (state >= ETHARP_STATE_STABLE) {
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+        /* don't record old_stable for static entries since they never expire */
+        if (state < ETHARP_STATE_STATIC)
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+        {
+          /* remember entry with oldest stable entry in oldest, its age in maxtime */
+          if (arp_table[i].ctime >= age_stable) {
+            old_stable = i;
+            age_stable = arp_table[i].ctime;
+          }
+        }
+      }
+    }
+  }
+  /* { we have no match } => try to create a new entry */
+   
+  /* don't create new entry, only search? */
+  if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) ||
+      /* or no empty entry found and not allowed to recycle? */
+      ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n"));
+    return (s8_t)ERR_MEM;
+  }
+  
+  /* b) choose the least destructive entry to recycle:
+   * 1) empty entry
+   * 2) oldest stable entry
+   * 3) oldest pending entry without queued packets
+   * 4) oldest pending entry with queued packets
+   * 
+   * { ETHARP_FLAG_TRY_HARD is set at this point }
+   */ 
+
+  /* 1) empty entry available? */
+  if (empty < ARP_TABLE_SIZE) {
+    i = empty;
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %"U16_F"\n", (u16_t)i));
+  } else {
+    /* 2) found recyclable stable entry? */
+    if (old_stable < ARP_TABLE_SIZE) {
+      /* recycle oldest stable*/
+      i = old_stable;
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i));
+      /* no queued packets should exist on stable entries */
+      LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL);
+    /* 3) found recyclable pending entry without queued packets? */
+    } else if (old_pending < ARP_TABLE_SIZE) {
+      /* recycle oldest pending */
+      i = old_pending;
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i));
+    /* 4) found recyclable pending entry with queued packets? */
+    } else if (old_queue < ARP_TABLE_SIZE) {
+      /* recycle oldest pending (queued packets are free in etharp_free_entry) */
+      i = old_queue;
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q)));
+      /* no empty or recyclable entries found */
+    } else {
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n"));
+      return (s8_t)ERR_MEM;
+    }
+
+    /* { empty or recyclable entry found } */
+    LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
+    etharp_free_entry(i);
+  }
+
+  LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
+  LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY",
+    arp_table[i].state == ETHARP_STATE_EMPTY);
+
+  /* IP address given? */
+  if (ipaddr != NULL) {
+    /* set IP address */
+    ip_addr_copy(arp_table[i].ipaddr, *ipaddr);
+  }
+  arp_table[i].ctime = 0;
+  return (err_t)i;
+}
+
+/**
+ * Send an IP packet on the network using netif->linkoutput
+ * The ethernet header is filled in before sending.
+ *
+ * @params netif the lwIP network interface on which to send the packet
+ * @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header
+ * @params src the source MAC address to be copied into the ethernet header
+ * @params dst the destination MAC address to be copied into the ethernet header
+ * @return ERR_OK if the packet was sent, any other err_t on failure
+ */
+static err_t
+etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst)
+{
+  struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload;
+
+  LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
+              (netif->hwaddr_len == ETHARP_HWADDR_LEN));
+  ETHADDR32_COPY(&ethhdr->dest, dst);
+  ETHADDR16_COPY(&ethhdr->src, src);
+  ethhdr->type = PP_HTONS(ETHTYPE_IP);
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p));
+  /* send the packet */
+  return netif->linkoutput(netif, p);
+}
+
+/**
+ * Update (or insert) a IP/MAC address pair in the ARP cache.
+ *
+ * If a pending entry is resolved, any queued packets will be sent
+ * at this point.
+ * 
+ * @param netif netif related to this entry (used for NETIF_ADDRHINT)
+ * @param ipaddr IP address of the inserted ARP entry.
+ * @param ethaddr Ethernet address of the inserted ARP entry.
+ * @param flags @see definition of ETHARP_FLAG_*
+ *
+ * @return
+ * - ERR_OK Succesfully updated ARP cache.
+ * - ERR_MEM If we could not add a new ARP entry when ETHARP_FLAG_TRY_HARD was set.
+ * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
+ *
+ * @see pbuf_free()
+ */
+static err_t
+etharp_update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags)
+{
+  s8_t i;
+  LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN);
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
+    ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
+    ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
+    ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
+  /* non-unicast address? */
+  if (ip_addr_isany(ipaddr) ||
+      ip_addr_isbroadcast(ipaddr, netif) ||
+      ip_addr_ismulticast(ipaddr)) {
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
+    return ERR_ARG;
+  }
+  /* find or create ARP entry */
+  i = etharp_find_entry(ipaddr, flags);
+  /* bail out if no entry could be found */
+  if (i < 0) {
+    return (err_t)i;
+  }
+
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+  if (flags & ETHARP_FLAG_STATIC_ENTRY) {
+    /* record static type */
+    arp_table[i].state = ETHARP_STATE_STATIC;
+  } else
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+  {
+    /* mark it stable */
+    arp_table[i].state = ETHARP_STATE_STABLE;
+  }
+
+  /* record network interface */
+  arp_table[i].netif = netif;
+  /* insert in SNMP ARP index tree */
+  snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr);
+
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));
+  /* update address */
+  ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
+  /* reset time stamp */
+  arp_table[i].ctime = 0;
+  /* this is where we will send out queued packets! */
+#if ARP_QUEUEING
+  while (arp_table[i].q != NULL) {
+    struct pbuf *p;
+    /* remember remainder of queue */
+    struct etharp_q_entry *q = arp_table[i].q;
+    /* pop first item off the queue */
+    arp_table[i].q = q->next;
+    /* get the packet pointer */
+    p = q->p;
+    /* now queue entry can be freed */
+    memp_free(MEMP_ARP_QUEUE, q);
+#else /* ARP_QUEUEING */
+  if (arp_table[i].q != NULL) {
+    struct pbuf *p = arp_table[i].q;
+    arp_table[i].q = NULL;
+#endif /* ARP_QUEUEING */
+    /* send the queued IP packet */
+    etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr);
+    /* free the queued IP packet */
+    pbuf_free(p);
+  }
+  return ERR_OK;
+}
+
+#if ETHARP_SUPPORT_STATIC_ENTRIES
+/** Add a new static entry to the ARP table. If an entry exists for the
+ * specified IP address, this entry is overwritten.
+ * If packets are queued for the specified IP address, they are sent out.
+ *
+ * @param ipaddr IP address for the new static entry
+ * @param ethaddr ethernet address for the new static entry
+ * @return @see return values of etharp_add_static_entry
+ */
+err_t
+etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr)
+{
+  struct netif *netif;
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
+    ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
+    ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
+    ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
+
+  netif = ip_route(ipaddr);
+  if (netif == NULL) {
+    return ERR_RTE;
+  }
+
+  return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
+}
+
+/** Remove a static entry from the ARP table previously added with a call to
+ * etharp_add_static_entry.
+ *
+ * @param ipaddr IP address of the static entry to remove
+ * @return ERR_OK: entry removed
+ *         ERR_MEM: entry wasn't found
+ *         ERR_ARG: entry wasn't a static entry but a dynamic one
+ */
+err_t
+etharp_remove_static_entry(ip_addr_t *ipaddr)
+{
+  s8_t i;
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+    ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
+
+  /* find or create ARP entry */
+  i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
+  /* bail out if no entry could be found */
+  if (i < 0) {
+    return (err_t)i;
+  }
+
+  if (arp_table[i].state != ETHARP_STATE_STATIC) {
+    /* entry wasn't a static entry, cannot remove it */
+    return ERR_ARG;
+  }
+  /* entry found, free it */
+  etharp_free_entry(i);
+  return ERR_OK;
+}
+#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
+
+/**
+ * Remove all ARP table entries of the specified netif.
+ *
+ * @param netif points to a network interface
+ */
+void etharp_cleanup_netif(struct netif *netif)
+{
+  u8_t i;
+
+  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
+    u8_t state = arp_table[i].state;
+    if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) {
+      etharp_free_entry(i);
+    }
+  }
+}
+
+/**
+ * Finds (stable) ethernet/IP address pair from ARP table
+ * using interface and IP address index.
+ * @note the addresses in the ARP table are in network order!
+ *
+ * @param netif points to interface index
+ * @param ipaddr points to the (network order) IP address index
+ * @param eth_ret points to return pointer
+ * @param ip_ret points to return pointer
+ * @return table index if found, -1 otherwise
+ */
+s8_t
+etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr,
+         struct eth_addr **eth_ret, ip_addr_t **ip_ret)
+{
+  s8_t i;
+
+  LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL",
+    eth_ret != NULL && ip_ret != NULL);
+
+  LWIP_UNUSED_ARG(netif);
+
+  i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
+  if((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
+      *eth_ret = &arp_table[i].ethaddr;
+      *ip_ret = &arp_table[i].ipaddr;
+      return i;
+  }
+  return -1;
+}
+
+#if ETHARP_TRUST_IP_MAC
+/**
+ * Updates the ARP table using the given IP packet.
+ *
+ * Uses the incoming IP packet's source address to update the
+ * ARP cache for the local network. The function does not alter
+ * or free the packet. This function must be called before the
+ * packet p is passed to the IP layer.
+ *
+ * @param netif The lwIP network interface on which the IP packet pbuf arrived.
+ * @param p The IP packet that arrived on netif.
+ *
+ * @return NULL
+ *
+ * @see pbuf_free()
+ */
+static void
+etharp_ip_input(struct netif *netif, struct pbuf *p)
+{
+  struct eth_hdr *ethhdr;
+  struct ip_hdr *iphdr;
+  ip_addr_t iphdr_src;
+  LWIP_ERROR("netif != NULL", (netif != NULL), return;);
+
+  /* Only insert an entry if the source IP address of the
+     incoming IP packet comes from a host on the local network. */
+  ethhdr = (struct eth_hdr *)p->payload;
+  iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
+#if ETHARP_SUPPORT_VLAN
+  if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) {
+    iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
+  }
+#endif /* ETHARP_SUPPORT_VLAN */
+
+  ip_addr_copy(iphdr_src, iphdr->src);
+
+  /* source is not on the local network? */
+  if (!ip_addr_netcmp(&iphdr_src, &(netif->ip_addr), &(netif->netmask))) {
+    /* do nothing */
+    return;
+  }
+
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
+  /* update the source IP address in the cache, if present */
+  /* @todo We could use ETHARP_FLAG_TRY_HARD if we think we are going to talk
+   * back soon (for example, if the destination IP address is ours. */
+  etharp_update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY);
+}
+#endif /* ETHARP_TRUST_IP_MAC */
+
+/**
+ * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache  
+ * send out queued IP packets. Updates cache with snooped address pairs.
+ *
+ * Should be called for incoming ARP packets. The pbuf in the argument
+ * is freed by this function.
+ *
+ * @param netif The lwIP network interface on which the ARP packet pbuf arrived.
+ * @param ethaddr Ethernet address of netif.
+ * @param p The ARP packet that arrived on netif. Is freed by this function.
+ *
+ * @return NULL
+ *
+ * @see pbuf_free()
+ */
+static void
+etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
+{
+  struct etharp_hdr *hdr;
+  struct eth_hdr *ethhdr;
+  /* these are aligned properly, whereas the ARP header fields might not be */
+  ip_addr_t sipaddr, dipaddr;
+  u8_t for_us;
+#if LWIP_AUTOIP
+  const u8_t * ethdst_hwaddr;
+#endif /* LWIP_AUTOIP */
+
+  LWIP_ERROR("netif != NULL", (netif != NULL), return;);
+
+  /* drop short ARP packets: we have to check for p->len instead of p->tot_len here
+     since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */
+  if (p->len < SIZEOF_ETHARP_PACKET) {
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
+      ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len,
+      (s16_t)SIZEOF_ETHARP_PACKET));
+    ETHARP_STATS_INC(etharp.lenerr);
+    ETHARP_STATS_INC(etharp.drop);
+    pbuf_free(p);
+    return;
+  }
+
+  ethhdr = (struct eth_hdr *)p->payload;
+  hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
+#if ETHARP_SUPPORT_VLAN
+  if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) {
+    hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
+  }
+#endif /* ETHARP_SUPPORT_VLAN */
+
+  /* RFC 826 "Packet Reception": */
+  if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) ||
+      (hdr->hwlen != ETHARP_HWADDR_LEN) ||
+      (hdr->protolen != sizeof(ip_addr_t)) ||
+      (hdr->proto != PP_HTONS(ETHTYPE_IP)))  {
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
+      ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",
+      hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen));
+    ETHARP_STATS_INC(etharp.proterr);
+    ETHARP_STATS_INC(etharp.drop);
+    pbuf_free(p);
+    return;
+  }
+  ETHARP_STATS_INC(etharp.recv);
+
+#if LWIP_AUTOIP
+  /* We have to check if a host already has configured our random
+   * created link local address and continously check if there is
+   * a host with this IP-address so we can detect collisions */
+  autoip_arp_reply(netif, hdr);
+#endif /* LWIP_AUTOIP */
+
+  /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without
+   * structure packing (not using structure copy which breaks strict-aliasing rules). */
+  IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
+  IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
+
+  /* this interface is not configured? */
+  if (ip_addr_isany(&netif->ip_addr)) {
+    for_us = 0;
+  } else {
+    /* ARP packet directed to us? */
+    for_us = (u8_t)ip_addr_cmp(&dipaddr, &(netif->ip_addr));
+  }
+
+  /* ARP message directed to us?
+      -> add IP address in ARP cache; assume requester wants to talk to us,
+         can result in directly sending the queued packets for this host.
+     ARP message not directed to us?
+      ->  update the source IP address in the cache, if present */
+  etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr),
+                   for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
+
+  /* now act on the message itself */
+  switch (hdr->opcode) {
+  /* ARP request? */
+  case PP_HTONS(ARP_REQUEST):
+    /* ARP request. If it asked for our address, we send out a
+     * reply. In any case, we time-stamp any existing ARP entry,
+     * and possiby send out an IP packet that was queued on it. */
+
+    LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
+    /* ARP request for our address? */
+    if (for_us) {
+
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
+      /* Re-use pbuf to send ARP reply.
+         Since we are re-using an existing pbuf, we can't call etharp_raw since
+         that would allocate a new pbuf. */
+      hdr->opcode = htons(ARP_REPLY);
+
+      IPADDR2_COPY(&hdr->dipaddr, &hdr->sipaddr);
+      IPADDR2_COPY(&hdr->sipaddr, &netif->ip_addr);
+
+      LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
+                  (netif->hwaddr_len == ETHARP_HWADDR_LEN));
+#if LWIP_AUTOIP
+      /* If we are using Link-Local, all ARP packets that contain a Link-Local
+       * 'sender IP address' MUST be sent using link-layer broadcast instead of
+       * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */
+      ethdst_hwaddr = ip_addr_islinklocal(&netif->ip_addr) ? (u8_t*)(ethbroadcast.addr) : hdr->shwaddr.addr;
+#endif /* LWIP_AUTOIP */
+
+      ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr);
+#if LWIP_AUTOIP
+      ETHADDR16_COPY(&ethhdr->dest, ethdst_hwaddr);
+#else  /* LWIP_AUTOIP */
+      ETHADDR16_COPY(&ethhdr->dest, &hdr->shwaddr);
+#endif /* LWIP_AUTOIP */
+      ETHADDR16_COPY(&hdr->shwaddr, ethaddr);
+      ETHADDR16_COPY(&ethhdr->src, ethaddr);
+
+      /* hwtype, hwaddr_len, proto, protolen and the type in the ethernet header
+         are already correct, we tested that before */
+
+      /* return ARP reply */
+      netif->linkoutput(netif, p);
+    /* we are not configured? */
+    } else if (ip_addr_isany(&netif->ip_addr)) {
+      /* { for_us == 0 and netif->ip_addr.addr == 0 } */
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
+    /* request was not directed to us */
+    } else {
+      /* { for_us == 0 and netif->ip_addr.addr != 0 } */
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n"));
+    }
+    break;
+  case PP_HTONS(ARP_REPLY):
+    /* ARP reply. We already updated the ARP cache earlier. */
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
+#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
+    /* DHCP wants to know about ARP replies from any host with an
+     * IP address also offered to us by the DHCP server. We do not
+     * want to take a duplicate IP address on a single network.
+     * @todo How should we handle redundant (fail-over) interfaces? */
+    dhcp_arp_reply(netif, &sipaddr);
+#endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */
+    break;
+  default:
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode)));
+    ETHARP_STATS_INC(etharp.err);
+    break;
+  }
+  /* free ARP packet */
+  pbuf_free(p);
+}
+
+/** Just a small helper function that sends a pbuf to an ethernet address
+ * in the arp_table specified by the index 'arp_idx'.
+ */
+static err_t
+etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx)
+{
+  LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
+              arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
+  /* if arp table entry is about to expire: re-request it,
+     but only if its state is ETHARP_STATE_STABLE to prevent flooding the
+     network with ARP requests if this address is used frequently. */
+  if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) && 
+      (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED)) {
+    if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) {
+      arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING;
+    }
+  }
+  
+  return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr),
+    &arp_table[arp_idx].ethaddr);
+}
+
+/**
+ * Resolve and fill-in Ethernet address header for outgoing IP packet.
+ *
+ * For IP multicast and broadcast, corresponding Ethernet addresses
+ * are selected and the packet is transmitted on the link.
+ *
+ * For unicast addresses, the packet is submitted to etharp_query(). In
+ * case the IP address is outside the local network, the IP address of
+ * the gateway is used.
+ *
+ * @param netif The lwIP network interface which the IP packet will be sent on.
+ * @param q The pbuf(s) containing the IP packet to be sent.
+ * @param ipaddr The IP address of the packet destination.
+ *
+ * @return
+ * - ERR_RTE No route to destination (no gateway to external networks),
+ * or the return type of either etharp_query() or etharp_send_ip().
+ */
+err_t
+etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr)
+{
+  struct eth_addr *dest;
+  struct eth_addr mcastaddr;
+  ip_addr_t *dst_addr = ipaddr;
+
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+  LWIP_ASSERT("q != NULL", q != NULL);
+  LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL);
+
+  /* make room for Ethernet header - should not fail */
+  if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
+    /* bail out */
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
+      ("etharp_output: could not allocate room for header.\n"));
+    LINK_STATS_INC(link.lenerr);
+    return ERR_BUF;
+  }
+
+  /* Determine on destination hardware address. Broadcasts and multicasts
+   * are special, other IP addresses are looked up in the ARP table. */
+
+  /* broadcast destination IP address? */
+  if (ip_addr_isbroadcast(ipaddr, netif)) {
+    /* broadcast on Ethernet also */
+    dest = (struct eth_addr *)&ethbroadcast;
+  /* multicast destination IP address? */
+  } else if (ip_addr_ismulticast(ipaddr)) {
+    /* Hash IP multicast address to MAC address.*/
+    mcastaddr.addr[0] = LL_MULTICAST_ADDR_0;
+    mcastaddr.addr[1] = LL_MULTICAST_ADDR_1;
+    mcastaddr.addr[2] = LL_MULTICAST_ADDR_2;
+    mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
+    mcastaddr.addr[4] = ip4_addr3(ipaddr);
+    mcastaddr.addr[5] = ip4_addr4(ipaddr);
+    /* destination Ethernet address is multicast */
+    dest = &mcastaddr;
+  /* unicast destination IP address? */
+  } else {
+    s8_t i;
+    /* outside local network? if so, this can neither be a global broadcast nor
+       a subnet broadcast. */
+    if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) &&
+        !ip_addr_islinklocal(ipaddr)) {
+#if LWIP_AUTOIP
+      struct ip_hdr *iphdr = (struct ip_hdr*)((u8_t*)q->payload +
+        sizeof(struct eth_hdr));
+      /* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with
+         a link-local source address must always be "directly to its destination
+         on the same physical link. The host MUST NOT send the packet to any
+         router for forwarding". */
+      if (!ip_addr_islinklocal(&iphdr->src))
+#endif /* LWIP_AUTOIP */
+      {
+        /* interface has default gateway? */
+        if (!ip_addr_isany(&netif->gw)) {
+          /* send to hardware address of default gateway IP address */
+          dst_addr = &(netif->gw);
+        /* no default gateway available */
+        } else {
+          /* no route to destination error (default gateway missing) */
+          return ERR_RTE;
+        }
+      }
+    }
+#if LWIP_NETIF_HWADDRHINT
+    if (netif->addr_hint != NULL) {
+      /* per-pcb cached entry was given */
+      u8_t etharp_cached_entry = *(netif->addr_hint);
+      if (etharp_cached_entry < ARP_TABLE_SIZE) {
+#endif /* LWIP_NETIF_HWADDRHINT */
+        if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) &&
+            (ip_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) {
+          /* the per-pcb-cached entry is stable and the right one! */
+          ETHARP_STATS_INC(etharp.cachehit);
+          return etharp_output_to_arp_index(netif, q, etharp_cached_entry);
+        }
+#if LWIP_NETIF_HWADDRHINT
+      }
+    }
+#endif /* LWIP_NETIF_HWADDRHINT */
+
+    /* find stable entry: do this here since this is a critical path for
+       throughput and etharp_find_entry() is kind of slow */
+    for (i = 0; i < ARP_TABLE_SIZE; i++) {
+      if ((arp_table[i].state >= ETHARP_STATE_STABLE) &&
+          (ip_addr_cmp(dst_addr, &arp_table[i].ipaddr))) {
+        /* found an existing, stable entry */
+        ETHARP_SET_HINT(netif, i);
+        return etharp_output_to_arp_index(netif, q, i);
+      }
+    }
+    /* no stable entry found, use the (slower) query function:
+       queue on destination Ethernet address belonging to ipaddr */
+    return etharp_query(netif, dst_addr, q);
+  }
+
+  /* continuation for multicast/broadcast destinations */
+  /* obtain source Ethernet address of the given interface */
+  /* send packet directly on the link */
+  return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), dest);
+}
+
+/**
+ * Send an ARP request for the given IP address and/or queue a packet.
+ *
+ * If the IP address was not yet in the cache, a pending ARP cache entry
+ * is added and an ARP request is sent for the given address. The packet
+ * is queued on this entry.
+ *
+ * If the IP address was already pending in the cache, a new ARP request
+ * is sent for the given address. The packet is queued on this entry.
+ *
+ * If the IP address was already stable in the cache, and a packet is
+ * given, it is directly sent and no ARP request is sent out. 
+ * 
+ * If the IP address was already stable in the cache, and no packet is
+ * given, an ARP request is sent out.
+ * 
+ * @param netif The lwIP network interface on which ipaddr
+ * must be queried for.
+ * @param ipaddr The IP address to be resolved.
+ * @param q If non-NULL, a pbuf that must be delivered to the IP address.
+ * q is not freed by this function.
+ *
+ * @note q must only be ONE packet, not a packet queue!
+ *
+ * @return
+ * - ERR_BUF Could not make room for Ethernet header.
+ * - ERR_MEM Hardware address unknown, and no more ARP entries available
+ *   to query for address or queue the packet.
+ * - ERR_MEM Could not queue packet due to memory shortage.
+ * - ERR_RTE No route to destination (no gateway to external networks).
+ * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
+ *
+ */
+err_t
+etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q)
+{
+  struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr;
+  err_t result = ERR_MEM;
+  s8_t i; /* ARP entry index */
+
+  /* non-unicast address? */
+  if (ip_addr_isbroadcast(ipaddr, netif) ||
+      ip_addr_ismulticast(ipaddr) ||
+      ip_addr_isany(ipaddr)) {
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));
+    return ERR_ARG;
+  }
+
+  /* find entry in ARP cache, ask to create entry if queueing packet */
+  i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD);
+
+  /* could not find or create entry? */
+  if (i < 0) {
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n"));
+    if (q) {
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n"));
+      ETHARP_STATS_INC(etharp.memerr);
+    }
+    return (err_t)i;
+  }
+
+  /* mark a fresh entry as pending (we just sent a request) */
+  if (arp_table[i].state == ETHARP_STATE_EMPTY) {
+    arp_table[i].state = ETHARP_STATE_PENDING;
+  }
+
+  /* { i is either a STABLE or (new or existing) PENDING entry } */
+  LWIP_ASSERT("arp_table[i].state == PENDING or STABLE",
+  ((arp_table[i].state == ETHARP_STATE_PENDING) ||
+   (arp_table[i].state >= ETHARP_STATE_STABLE)));
+
+  /* do we have a pending entry? or an implicit query request? */
+  if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) {
+    /* try to resolve it; send out ARP request */
+    result = etharp_request(netif, ipaddr);
+    if (result != ERR_OK) {
+      /* ARP request couldn't be sent */
+      /* We don't re-send arp request in etharp_tmr, but we still queue packets,
+         since this failure could be temporary, and the next packet calling
+         etharp_query again could lead to sending the queued packets. */
+    }
+    if (q == NULL) {
+      return result;
+    }
+  }
+
+  /* packet given? */
+  LWIP_ASSERT("q != NULL", q != NULL);
+  /* stable entry? */
+  if (arp_table[i].state >= ETHARP_STATE_STABLE) {
+    /* we have a valid IP->Ethernet address mapping */
+    ETHARP_SET_HINT(netif, i);
+    /* send the packet */
+    result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr));
+  /* pending entry? (either just created or already pending */
+  } else if (arp_table[i].state == ETHARP_STATE_PENDING) {
+    /* entry is still pending, queue the given packet 'q' */
+    struct pbuf *p;
+    int copy_needed = 0;
+    /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but
+     * to copy the whole queue into a new PBUF_RAM (see bug #11400) 
+     * PBUF_ROMs can be left as they are, since ROM must not get changed. */
+    p = q;
+    while (p) {
+      LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0));
+      if(p->type != PBUF_ROM) {
+        copy_needed = 1;
+        break;
+      }
+      p = p->next;
+    }
+    if(copy_needed) {
+      /* copy the whole packet into new pbufs */
+      p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
+      if(p != NULL) {
+        if (pbuf_copy(p, q) != ERR_OK) {
+          pbuf_free(p);
+          p = NULL;
+        }
+      }
+    } else {
+      /* referencing the old pbuf is enough */
+      p = q;
+      pbuf_ref(p);
+    }
+    /* packet could be taken over? */
+    if (p != NULL) {
+      /* queue packet ... */
+#if ARP_QUEUEING
+      struct etharp_q_entry *new_entry;
+      /* allocate a new arp queue entry */
+      new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE);
+      if (new_entry != NULL) {
+        new_entry->next = 0;
+        new_entry->p = p;
+        if(arp_table[i].q != NULL) {
+          /* queue was already existent, append the new entry to the end */
+          struct etharp_q_entry *r;
+          r = arp_table[i].q;
+          while (r->next != NULL) {
+            r = r->next;
+          }
+          r->next = new_entry;
+        } else {
+          /* queue did not exist, first item in queue */
+          arp_table[i].q = new_entry;
+        }
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
+        result = ERR_OK;
+      } else {
+        /* the pool MEMP_ARP_QUEUE is empty */
+        pbuf_free(p);
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
+        result = ERR_MEM;
+      }
+#else /* ARP_QUEUEING */
+      /* always queue one packet per ARP request only, freeing a previously queued packet */
+      if (arp_table[i].q != NULL) {
+        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
+        pbuf_free(arp_table[i].q);
+      }
+      arp_table[i].q = p;
+      result = ERR_OK;
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
+#endif /* ARP_QUEUEING */
+    } else {
+      ETHARP_STATS_INC(etharp.memerr);
+      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
+      result = ERR_MEM;
+    }
+  }
+  return result;
+}
+
+/**
+ * Send a raw ARP packet (opcode and all addresses can be modified)
+ *
+ * @param netif the lwip network interface on which to send the ARP packet
+ * @param ethsrc_addr the source MAC address for the ethernet header
+ * @param ethdst_addr the destination MAC address for the ethernet header
+ * @param hwsrc_addr the source MAC address for the ARP protocol header
+ * @param ipsrc_addr the source IP address for the ARP protocol header
+ * @param hwdst_addr the destination MAC address for the ARP protocol header
+ * @param ipdst_addr the destination IP address for the ARP protocol header
+ * @param opcode the type of the ARP packet
+ * @return ERR_OK if the ARP packet has been sent
+ *         ERR_MEM if the ARP packet couldn't be allocated
+ *         any other err_t on failure
+ */
+#if !LWIP_AUTOIP
+static
+#endif /* LWIP_AUTOIP */
+err_t
+etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
+           const struct eth_addr *ethdst_addr,
+           const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr,
+           const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr,
+           const u16_t opcode)
+{
+  struct pbuf *p;
+  err_t result = ERR_OK;
+  struct eth_hdr *ethhdr;
+  struct etharp_hdr *hdr;
+#if LWIP_AUTOIP
+  const u8_t * ethdst_hwaddr;
+#endif /* LWIP_AUTOIP */
+
+  LWIP_ASSERT("netif != NULL", netif != NULL);
+
+  /* allocate a pbuf for the outgoing ARP request packet */
+  p = pbuf_alloc(PBUF_RAW, SIZEOF_ETHARP_PACKET, PBUF_RAM);
+  /* could allocate a pbuf for an ARP request? */
+  if (p == NULL) {
+    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
+      ("etharp_raw: could not allocate pbuf for ARP request.\n"));
+    ETHARP_STATS_INC(etharp.memerr);
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr",
+              (p->len >= SIZEOF_ETHARP_PACKET));
+
+  ethhdr = (struct eth_hdr *)p->payload;
+  hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n"));
+  hdr->opcode = htons(opcode);
+
+  LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
+              (netif->hwaddr_len == ETHARP_HWADDR_LEN));
+#if LWIP_AUTOIP
+  /* If we are using Link-Local, all ARP packets that contain a Link-Local
+   * 'sender IP address' MUST be sent using link-layer broadcast instead of
+   * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */
+  ethdst_hwaddr = ip_addr_islinklocal(ipsrc_addr) ? (u8_t*)(ethbroadcast.addr) : ethdst_addr->addr;
+#endif /* LWIP_AUTOIP */
+  /* Write the ARP MAC-Addresses */
+  ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr);
+  ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr);
+  /* Write the Ethernet MAC-Addresses */
+#if LWIP_AUTOIP
+  ETHADDR16_COPY(&ethhdr->dest, ethdst_hwaddr);
+#else  /* LWIP_AUTOIP */
+  ETHADDR16_COPY(&ethhdr->dest, ethdst_addr);
+#endif /* LWIP_AUTOIP */
+  ETHADDR16_COPY(&ethhdr->src, ethsrc_addr);
+  /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without
+   * structure packing. */ 
+  IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr);
+  IPADDR2_COPY(&hdr->dipaddr, ipdst_addr);
+
+  hdr->hwtype = PP_HTONS(HWTYPE_ETHERNET);
+  hdr->proto = PP_HTONS(ETHTYPE_IP);
+  /* set hwlen and protolen */
+  hdr->hwlen = ETHARP_HWADDR_LEN;
+  hdr->protolen = sizeof(ip_addr_t);
+
+  ethhdr->type = PP_HTONS(ETHTYPE_ARP);
+  /* send ARP query */
+  result = netif->linkoutput(netif, p);
+  ETHARP_STATS_INC(etharp.xmit);
+  /* free ARP query packet */
+  pbuf_free(p);
+  p = NULL;
+  /* could not allocate pbuf for ARP request */
+
+  return result;
+}
+
+/**
+ * Send an ARP request packet asking for ipaddr.
+ *
+ * @param netif the lwip network interface on which to send the request
+ * @param ipaddr the IP address for which to ask
+ * @return ERR_OK if the request has been sent
+ *         ERR_MEM if the ARP packet couldn't be allocated
+ *         any other err_t on failure
+ */
+err_t
+etharp_request(struct netif *netif, ip_addr_t *ipaddr)
+{
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n"));
+  return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
+                    (struct eth_addr *)netif->hwaddr, &netif->ip_addr, &ethzero,
+                    ipaddr, ARP_REQUEST);
+}
+#endif /* LWIP_ARP */
+
+/**
+ * Process received ethernet frames. Using this function instead of directly
+ * calling ip_input and passing ARP frames through etharp in ethernetif_input,
+ * the ARP cache is protected from concurrent access.
+ *
+ * @param p the recevied packet, p->payload pointing to the ethernet header
+ * @param netif the network interface on which the packet was received
+ */
+err_t
+ethernet_input(struct pbuf *p, struct netif *netif)
+{
+  struct eth_hdr* ethhdr;
+  u16_t type;
+#if LWIP_ARP || ETHARP_SUPPORT_VLAN
+  s16_t ip_hdr_offset = SIZEOF_ETH_HDR;
+#endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */
+
+  if (p->len <= SIZEOF_ETH_HDR) {
+    /* a packet with only an ethernet header (or less) is not valid for us */
+    ETHARP_STATS_INC(etharp.proterr);
+    ETHARP_STATS_INC(etharp.drop);
+    goto free_and_return;
+  }
+
+  /* points to packet payload, which starts with an Ethernet header */
+  ethhdr = (struct eth_hdr *)p->payload;
+  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
+    ("ethernet_input: dest:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", src:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", type:%"X16_F"\n",
+     (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2],
+     (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5],
+     (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2],
+     (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5],
+     (unsigned)htons(ethhdr->type)));
+
+  type = ethhdr->type;
+#if ETHARP_SUPPORT_VLAN
+  if (type == PP_HTONS(ETHTYPE_VLAN)) {
+    struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR);
+    if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) {
+      /* a packet with only an ethernet/vlan header (or less) is not valid for us */
+      ETHARP_STATS_INC(etharp.proterr);
+      ETHARP_STATS_INC(etharp.drop);
+      goto free_and_return;
+    }
+#if defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) /* if not, allow all VLANs */
+#ifdef ETHARP_VLAN_CHECK_FN
+    if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) {
+#elif defined(ETHARP_VLAN_CHECK)
+    if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) {
+#endif
+      /* silently ignore this packet: not for our VLAN */
+      pbuf_free(p);
+      return ERR_OK;
+    }
+#endif /* defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) */
+    type = vlan->tpid;
+    ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR;
+  }
+#endif /* ETHARP_SUPPORT_VLAN */
+
+#if LWIP_ARP_FILTER_NETIF
+  netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, htons(type));
+#endif /* LWIP_ARP_FILTER_NETIF*/
+
+  if (ethhdr->dest.addr[0] & 1) {
+    /* this might be a multicast or broadcast packet */
+    if (ethhdr->dest.addr[0] == LL_MULTICAST_ADDR_0) {
+      if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) &&
+          (ethhdr->dest.addr[2] == LL_MULTICAST_ADDR_2)) {
+        /* mark the pbuf as link-layer multicast */
+        p->flags |= PBUF_FLAG_LLMCAST;
+      }
+    } else if (eth_addr_cmp(&ethhdr->dest, &ethbroadcast)) {
+      /* mark the pbuf as link-layer broadcast */
+      p->flags |= PBUF_FLAG_LLBCAST;
+    }
+  }
+
+  switch (type) {
+#if LWIP_ARP
+    /* IP packet? */
+    case PP_HTONS(ETHTYPE_IP):
+      if (!(netif->flags & NETIF_FLAG_ETHARP)) {
+        goto free_and_return;
+      }
+#if ETHARP_TRUST_IP_MAC
+      /* update ARP table */
+      etharp_ip_input(netif, p);
+#endif /* ETHARP_TRUST_IP_MAC */
+      /* skip Ethernet header */
+      if(pbuf_header(p, -ip_hdr_offset)) {
+        LWIP_ASSERT("Can't move over header in packet", 0);
+        goto free_and_return;
+      } else {
+        /* pass to IP layer */
+        ip_input(p, netif);
+      }
+      break;
+      
+    case PP_HTONS(ETHTYPE_ARP):
+      if (!(netif->flags & NETIF_FLAG_ETHARP)) {
+        goto free_and_return;
+      }
+      /* pass p to ARP module */
+      etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p);
+      break;
+#endif /* LWIP_ARP */
+#if PPPOE_SUPPORT
+    case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */
+      pppoe_disc_input(netif, p);
+      break;
+
+    case PP_HTONS(ETHTYPE_PPPOE): /* PPP Over Ethernet Session Stage */
+      pppoe_data_input(netif, p);
+      break;
+#endif /* PPPOE_SUPPORT */
+
+    default:
+      ETHARP_STATS_INC(etharp.proterr);
+      ETHARP_STATS_INC(etharp.drop);
+      goto free_and_return;
+  }
+
+  /* This means the pbuf is freed or consumed,
+     so the caller doesn't have to free it again */
+  return ERR_OK;
+
+free_and_return:
+  pbuf_free(p);
+  return ERR_OK;
+}
+#endif /* LWIP_ARP || LWIP_ETHERNET */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ethernetif.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ethernetif.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ethernetif.c	(revision 164)
@@ -0,0 +1,317 @@
+/**
+ * @file
+ * Ethernet Interface Skeleton
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/*
+ * This file is a skeleton for developing Ethernet network interface
+ * drivers for lwIP. Add code to the low_level functions and do a
+ * search-and-replace for the word "ethernetif" to replace it with
+ * something that better describes your network interface.
+ */
+
+#include "lwip/opt.h"
+
+#if 0 /* don't build, this is only a skeleton, see previous comment */
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include <lwip/stats.h>
+#include <lwip/snmp.h>
+#include "netif/etharp.h"
+#include "netif/ppp_oe.h"
+
+/* Define those to better describe your network interface. */
+#define IFNAME0 'e'
+#define IFNAME1 'n'
+
+/**
+ * Helper struct to hold private data used to operate your ethernet interface.
+ * Keeping the ethernet address of the MAC in this struct is not necessary
+ * as it is already kept in the struct netif.
+ * But this is only an example, anyway...
+ */
+struct ethernetif {
+  struct eth_addr *ethaddr;
+  /* Add whatever per-interface state that is needed here. */
+};
+
+/* Forward declarations. */
+static void  ethernetif_input(struct netif *netif);
+
+/**
+ * In this function, the hardware should be initialized.
+ * Called from ethernetif_init().
+ *
+ * @param netif the already initialized lwip network interface structure
+ *        for this ethernetif
+ */
+static void
+low_level_init(struct netif *netif)
+{
+  struct ethernetif *ethernetif = netif->state;
+  
+  /* set MAC hardware address length */
+  netif->hwaddr_len = ETHARP_HWADDR_LEN;
+
+  /* set MAC hardware address */
+  netif->hwaddr[0] = ;
+  ...
+  netif->hwaddr[5] = ;
+
+  /* maximum transfer unit */
+  netif->mtu = 1500;
+  
+  /* device capabilities */
+  /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
+  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
+ 
+  /* Do whatever else is needed to initialize interface. */  
+}
+
+/**
+ * This function should do the actual transmission of the packet. The packet is
+ * contained in the pbuf that is passed to the function. This pbuf
+ * might be chained.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
+ * @return ERR_OK if the packet could be sent
+ *         an err_t value if the packet couldn't be sent
+ *
+ * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
+ *       strange results. You might consider waiting for space in the DMA queue
+ *       to become availale since the stack doesn't retry to send a packet
+ *       dropped because of memory failure (except for the TCP timers).
+ */
+
+static err_t
+low_level_output(struct netif *netif, struct pbuf *p)
+{
+  struct ethernetif *ethernetif = netif->state;
+  struct pbuf *q;
+
+  initiate transfer();
+  
+#if ETH_PAD_SIZE
+  pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
+#endif
+
+  for(q = p; q != NULL; q = q->next) {
+    /* Send the data from the pbuf to the interface, one pbuf at a
+       time. The size of the data in each pbuf is kept in the ->len
+       variable. */
+    send data from(q->payload, q->len);
+  }
+
+  signal that packet should be sent();
+
+#if ETH_PAD_SIZE
+  pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
+#endif
+  
+  LINK_STATS_INC(link.xmit);
+
+  return ERR_OK;
+}
+
+/**
+ * Should allocate a pbuf and transfer the bytes of the incoming
+ * packet from the interface into the pbuf.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @return a pbuf filled with the received packet (including MAC header)
+ *         NULL on memory error
+ */
+static struct pbuf *
+low_level_input(struct netif *netif)
+{
+  struct ethernetif *ethernetif = netif->state;
+  struct pbuf *p, *q;
+  u16_t len;
+
+  /* Obtain the size of the packet and put it into the "len"
+     variable. */
+  len = ;
+
+#if ETH_PAD_SIZE
+  len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
+#endif
+
+  /* We allocate a pbuf chain of pbufs from the pool. */
+  p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
+  
+  if (p != NULL) {
+
+#if ETH_PAD_SIZE
+    pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
+#endif
+
+    /* We iterate over the pbuf chain until we have read the entire
+     * packet into the pbuf. */
+    for(q = p; q != NULL; q = q->next) {
+      /* Read enough bytes to fill this pbuf in the chain. The
+       * available data in the pbuf is given by the q->len
+       * variable.
+       * This does not necessarily have to be a memcpy, you can also preallocate
+       * pbufs for a DMA-enabled MAC and after receiving truncate it to the
+       * actually received size. In this case, ensure the tot_len member of the
+       * pbuf is the sum of the chained pbuf len members.
+       */
+      read data into(q->payload, q->len);
+    }
+    acknowledge that packet has been read();
+
+#if ETH_PAD_SIZE
+    pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
+#endif
+
+    LINK_STATS_INC(link.recv);
+  } else {
+    drop packet();
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+  }
+
+  return p;  
+}
+
+/**
+ * This function should be called when a packet is ready to be read
+ * from the interface. It uses the function low_level_input() that
+ * should handle the actual reception of bytes from the network
+ * interface. Then the type of the received packet is determined and
+ * the appropriate input function is called.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ */
+static void
+ethernetif_input(struct netif *netif)
+{
+  struct ethernetif *ethernetif;
+  struct eth_hdr *ethhdr;
+  struct pbuf *p;
+
+  ethernetif = netif->state;
+
+  /* move received packet into a new pbuf */
+  p = low_level_input(netif);
+  /* no packet could be read, silently ignore this */
+  if (p == NULL) return;
+  /* points to packet payload, which starts with an Ethernet header */
+  ethhdr = p->payload;
+
+  switch (htons(ethhdr->type)) {
+  /* IP or ARP packet? */
+  case ETHTYPE_IP:
+  case ETHTYPE_ARP:
+#if PPPOE_SUPPORT
+  /* PPPoE packet? */
+  case ETHTYPE_PPPOEDISC:
+  case ETHTYPE_PPPOE:
+#endif /* PPPOE_SUPPORT */
+    /* full packet send to tcpip_thread to process */
+    if (netif->input(p, netif)!=ERR_OK)
+     { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
+       pbuf_free(p);
+       p = NULL;
+     }
+    break;
+
+  default:
+    pbuf_free(p);
+    p = NULL;
+    break;
+  }
+}
+
+/**
+ * Should be called at the beginning of the program to set up the
+ * network interface. It calls the function low_level_init() to do the
+ * actual setup of the hardware.
+ *
+ * This function should be passed as a parameter to netif_add().
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @return ERR_OK if the loopif is initialized
+ *         ERR_MEM if private data couldn't be allocated
+ *         any other err_t on error
+ */
+err_t
+ethernetif_init(struct netif *netif)
+{
+  struct ethernetif *ethernetif;
+
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+    
+  ethernetif = mem_malloc(sizeof(struct ethernetif));
+  if (ethernetif == NULL) {
+    LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
+    return ERR_MEM;
+  }
+
+#if LWIP_NETIF_HOSTNAME
+  /* Initialize interface hostname */
+  netif->hostname = "lwip";
+#endif /* LWIP_NETIF_HOSTNAME */
+
+  /*
+   * Initialize the snmp variables and counters inside the struct netif.
+   * The last argument should be replaced with your link speed, in units
+   * of bits per second.
+   */
+  NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
+
+  netif->state = ethernetif;
+  netif->name[0] = IFNAME0;
+  netif->name[1] = IFNAME1;
+  /* We directly use etharp_output() here to save a function call.
+   * You can instead declare your own function an call etharp_output()
+   * from it if you have to do some checks before sending (e.g. if link
+   * is available...) */
+  netif->output = etharp_output;
+  netif->linkoutput = low_level_output;
+  
+  ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
+  
+  /* initialize the hardware */
+  low_level_init(netif);
+
+  return ERR_OK;
+}
+
+#endif /* 0 */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/auth.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/auth.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/auth.c	(revision 164)
@@ -0,0 +1,1334 @@
+/*****************************************************************************
+* auth.c - Network Authentication and Phase Control program file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* Copyright (c) 1997 by Global Election Systems Inc.  All rights reserved.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Ported from public pppd code.
+*****************************************************************************/
+/*
+ * 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.
+ */
+
+#include "lwip/opt.h"
+
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "ppp_impl.h"
+#include "pppdebug.h"
+
+#include "fsm.h"
+#include "lcp.h"
+#include "pap.h"
+#include "chap.h"
+#include "auth.h"
+#include "ipcp.h"
+
+#if CBCP_SUPPORT
+#include "cbcp.h"
+#endif /* CBCP_SUPPORT */
+
+#include "lwip/inet.h"
+
+#include <string.h>
+
+#if 0 /* UNUSED */
+/* Bits in scan_authfile return value */
+#define NONWILD_SERVER  1
+#define NONWILD_CLIENT  2
+
+#define ISWILD(word)  (word[0] == '*' && word[1] == 0)
+#endif /* UNUSED */
+
+#if PAP_SUPPORT || CHAP_SUPPORT
+/* The name by which the peer authenticated itself to us. */
+static char peer_authname[MAXNAMELEN];
+#endif /* PAP_SUPPORT || CHAP_SUPPORT */
+
+/* Records which authentication operations haven't completed yet. */
+static int auth_pending[NUM_PPP];
+
+/* Set if we have successfully called plogin() */
+static int logged_in;
+
+/* Set if we have run the /etc/ppp/auth-up script. */
+static int did_authup; /* @todo, we don't need this in lwip*/
+
+/* List of addresses which the peer may use. */
+static struct wordlist *addresses[NUM_PPP];
+
+#if 0 /* UNUSED */
+/* Wordlist giving addresses which the peer may use
+   without authenticating itself. */
+static struct wordlist *noauth_addrs;
+
+/* Extra options to apply, from the secrets file entry for the peer. */
+static struct wordlist *extra_options;
+#endif /* UNUSED */
+
+/* Number of network protocols which we have opened. */
+static int num_np_open;
+
+/* Number of network protocols which have come up. */
+static int num_np_up;
+
+#if PAP_SUPPORT || CHAP_SUPPORT
+/* Set if we got the contents of passwd[] from the pap-secrets file. */
+static int passwd_from_file;
+#endif /* PAP_SUPPORT || CHAP_SUPPORT */
+
+#if 0 /* UNUSED */
+/* Set if we require authentication only because we have a default route. */
+static bool default_auth;
+
+/* Hook to enable a plugin to control the idle time limit */
+int (*idle_time_hook) __P((struct ppp_idle *)) = NULL;
+
+/* Hook for a plugin to say whether we can possibly authenticate any peer */
+int (*pap_check_hook) __P((void)) = NULL;
+
+/* Hook for a plugin to check the PAP user and password */
+int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp,
+        struct wordlist **paddrs,
+        struct wordlist **popts)) = NULL;
+
+/* Hook for a plugin to know about the PAP user logout */
+void (*pap_logout_hook) __P((void)) = NULL;
+
+/* Hook for a plugin to get the PAP password for authenticating us */
+int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL;
+
+/*
+ * This is used to ensure that we don't start an auth-up/down
+ * script while one is already running.
+ */
+enum script_state {
+    s_down,
+    s_up
+};
+
+static enum script_state auth_state = s_down;
+static enum script_state auth_script_state = s_down;
+static pid_t auth_script_pid = 0;
+
+/*
+ * Option variables.
+ * lwip: some of these are present in the ppp_settings structure
+ */
+bool uselogin = 0;            /* Use /etc/passwd for checking PAP */
+bool cryptpap = 0;            /* Passwords in pap-secrets are encrypted */
+bool refuse_pap = 0;          /* Don't wanna auth. ourselves with PAP */
+bool refuse_chap = 0;         /* Don't wanna auth. ourselves with CHAP */
+bool usehostname = 0;         /* Use hostname for our_name */
+bool auth_required = 0;       /* Always require authentication from peer */
+bool allow_any_ip = 0;        /* Allow peer to use any IP address */
+bool explicit_remote = 0;     /* User specified explicit remote name */
+char remote_name[MAXNAMELEN]; /* Peer's name for authentication */
+
+#endif /* UNUSED */
+
+/* Bits in auth_pending[] */
+#define PAP_WITHPEER    1
+#define PAP_PEER        2
+#define CHAP_WITHPEER   4
+#define CHAP_PEER       8
+
+/* @todo, move this somewhere */
+/* Used for storing a sequence of words.  Usually malloced. */
+struct wordlist {
+  struct wordlist *next;
+  char        word[1];
+};
+
+
+extern char *crypt (const char *, const char *);
+
+/* Prototypes for procedures local to this file. */
+
+static void network_phase (int);
+static void check_idle (void *);
+static void connect_time_expired (void *);
+#if 0
+static int  plogin (char *, char *, char **, int *);
+#endif
+static void plogout (void);
+static int  null_login (int);
+static int  get_pap_passwd (int, char *, char *);
+static int  have_pap_secret (void);
+static int  have_chap_secret (char *, char *, u32_t);
+static int  ip_addr_check (u32_t, struct wordlist *);
+
+#if 0 /* PAP_SUPPORT || CHAP_SUPPORT */
+static int  scan_authfile (FILE *, char *, char *, char *,
+             struct wordlist **, struct wordlist **,
+             char *);
+static void free_wordlist (struct wordlist *);
+static void auth_script (char *);
+static void auth_script_done (void *);
+static void set_allowed_addrs (int unit, struct wordlist *addrs);
+static int  some_ip_ok (struct wordlist *);
+static int  setupapfile (char **);
+static int  privgroup (char **);
+static int  set_noauth_addr (char **);
+static void check_access (FILE *, char *);
+#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */
+
+#if 0 /* UNUSED */
+/*
+ * Authentication-related options.
+ */
+option_t auth_options[] = {
+    { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap,
+      "Require PAP authentication from peer", 1, &auth_required },
+    { "+pap", o_bool, &lcp_wantoptions[0].neg_upap,
+      "Require PAP authentication from peer", 1, &auth_required },
+    { "refuse-pap", o_bool, &refuse_pap,
+      "Don't agree to auth to peer with PAP", 1 },
+    { "-pap", o_bool, &refuse_pap,
+      "Don't allow PAP authentication with peer", 1 },
+    { "require-chap", o_bool, &lcp_wantoptions[0].neg_chap,
+      "Require CHAP authentication from peer", 1, &auth_required },
+    { "+chap", o_bool, &lcp_wantoptions[0].neg_chap,
+      "Require CHAP authentication from peer", 1, &auth_required },
+    { "refuse-chap", o_bool, &refuse_chap,
+      "Don't agree to auth to peer with CHAP", 1 },
+    { "-chap", o_bool, &refuse_chap,
+      "Don't allow CHAP authentication with peer", 1 },
+    { "name", o_string, our_name,
+      "Set local name for authentication",
+      OPT_PRIV|OPT_STATIC, NULL, MAXNAMELEN },
+    { "user", o_string, user,
+      "Set name for auth with peer", OPT_STATIC, NULL, MAXNAMELEN },
+    { "usehostname", o_bool, &usehostname,
+      "Must use hostname for authentication", 1 },
+    { "remotename", o_string, remote_name,
+      "Set remote name for authentication", OPT_STATIC,
+      &explicit_remote, MAXNAMELEN },
+    { "auth", o_bool, &auth_required,
+      "Require authentication from peer", 1 },
+    { "noauth", o_bool, &auth_required,
+      "Don't require peer to authenticate", OPT_PRIV, &allow_any_ip },
+    {  "login", o_bool, &uselogin,
+      "Use system password database for PAP", 1 },
+    { "papcrypt", o_bool, &cryptpap,
+      "PAP passwords are encrypted", 1 },
+    { "+ua", o_special, (void *)setupapfile,
+      "Get PAP user and password from file" },
+    { "password", o_string, passwd,
+      "Password for authenticating us to the peer", OPT_STATIC,
+      NULL, MAXSECRETLEN },
+    { "privgroup", o_special, (void *)privgroup,
+      "Allow group members to use privileged options", OPT_PRIV },
+    { "allow-ip", o_special, (void *)set_noauth_addr,
+      "Set IP address(es) which can be used without authentication",
+      OPT_PRIV },
+    { NULL }
+};
+#endif /* UNUSED */
+#if 0 /* UNUSED */
+/*
+ * setupapfile - specifies UPAP info for authenticating with peer.
+ */
+static int
+setupapfile(char **argv)
+{
+    FILE * ufile;
+    int l;
+
+    lcp_allowoptions[0].neg_upap = 1;
+
+    /* open user info file */
+    seteuid(getuid());
+    ufile = fopen(*argv, "r");
+    seteuid(0);
+    if (ufile == NULL) {
+      option_error("unable to open user login data file %s", *argv);
+      return 0;
+    }
+    check_access(ufile, *argv);
+
+    /* get username */
+    if (fgets(user, MAXNAMELEN - 1, ufile) == NULL
+        || fgets(passwd, MAXSECRETLEN - 1, ufile) == NULL){
+      option_error("unable to read user login data file %s", *argv);
+      return 0;
+    }
+    fclose(ufile);
+
+    /* get rid of newlines */
+    l = strlen(user);
+    if (l > 0 && user[l-1] == '\n')
+      user[l-1] = 0;
+    l = strlen(passwd);
+    if (l > 0 && passwd[l-1] == '\n')
+      passwd[l-1] = 0;
+
+    return (1);
+}
+#endif /* UNUSED */
+
+#if 0 /* UNUSED */
+/*
+ * privgroup - allow members of the group to have privileged access.
+ */
+static int
+privgroup(char **argv)
+{
+    struct group *g;
+    int i;
+
+    g = getgrnam(*argv);
+    if (g == 0) {
+      option_error("group %s is unknown", *argv);
+      return 0;
+    }
+    for (i = 0; i < ngroups; ++i) {
+      if (groups[i] == g->gr_gid) {
+        privileged = 1;
+        break;
+      }
+    }
+    return 1;
+}
+#endif
+
+#if 0 /* UNUSED */
+/*
+ * set_noauth_addr - set address(es) that can be used without authentication.
+ * Equivalent to specifying an entry like `"" * "" addr' in pap-secrets.
+ */
+static int
+set_noauth_addr(char **argv)
+{
+    char *addr = *argv;
+    int l = strlen(addr);
+    struct wordlist *wp;
+
+    wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l + 1);
+    if (wp == NULL)
+      novm("allow-ip argument");
+    wp->word = (char *) (wp + 1);
+    wp->next = noauth_addrs;
+    BCOPY(addr, wp->word, l);
+    noauth_addrs = wp;
+    return 1;
+}
+#endif /* UNUSED */
+
+/*
+ * An Open on LCP has requested a change from Dead to Establish phase.
+ * Do what's necessary to bring the physical layer up.
+ */
+void
+link_required(int unit)
+{
+  LWIP_UNUSED_ARG(unit);
+
+  AUTHDEBUG(LOG_INFO, ("link_required: %d\n", unit));
+}
+
+/*
+ * LCP has terminated the link; go to the Dead phase and take the
+ * physical layer down.
+ */
+void
+link_terminated(int unit)
+{
+  AUTHDEBUG(LOG_INFO, ("link_terminated: %d\n", unit));
+  if (lcp_phase[unit] == PHASE_DEAD) {
+    return;
+  }
+  if (logged_in) {
+    plogout();
+  }
+  lcp_phase[unit] = PHASE_DEAD;
+  AUTHDEBUG(LOG_NOTICE, ("Connection terminated.\n"));
+  pppLinkTerminated(unit);
+}
+
+/*
+ * LCP has gone down; it will either die or try to re-establish.
+ */
+void
+link_down(int unit)
+{
+  int i;
+  struct protent *protp;
+
+  AUTHDEBUG(LOG_INFO, ("link_down: %d\n", unit));
+
+  if (did_authup) {
+    /* XXX Do link down processing. */
+    did_authup = 0;
+  }
+  for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
+    if (!protp->enabled_flag) {
+      continue;
+    }
+    if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) {
+      (*protp->lowerdown)(unit);
+    }
+    if (protp->protocol < 0xC000 && protp->close != NULL) {
+      (*protp->close)(unit, "LCP down");
+    }
+  }
+  num_np_open = 0;  /* number of network protocols we have opened */
+  num_np_up = 0;    /* Number of network protocols which have come up */
+
+  if (lcp_phase[unit] != PHASE_DEAD) {
+    lcp_phase[unit] = PHASE_TERMINATE;
+  }
+  pppLinkDown(unit);
+}
+
+/*
+ * The link is established.
+ * Proceed to the Dead, Authenticate or Network phase as appropriate.
+ */
+void
+link_established(int unit)
+{
+  int auth;
+  int i;
+  struct protent *protp;
+  lcp_options *wo = &lcp_wantoptions[unit];
+  lcp_options *go = &lcp_gotoptions[unit];
+#if PAP_SUPPORT || CHAP_SUPPORT
+  lcp_options *ho = &lcp_hisoptions[unit];
+#endif /* PAP_SUPPORT || CHAP_SUPPORT */
+
+  AUTHDEBUG(LOG_INFO, ("link_established: unit %d; Lowering up all protocols...\n", unit));
+  /*
+   * Tell higher-level protocols that LCP is up.
+   */
+  for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
+    if (protp->protocol != PPP_LCP && protp->enabled_flag && protp->lowerup != NULL) {
+      (*protp->lowerup)(unit);
+    }
+  }
+  if (ppp_settings.auth_required && !(go->neg_chap || go->neg_upap)) {
+    /*
+     * We wanted the peer to authenticate itself, and it refused:
+     * treat it as though it authenticated with PAP using a username
+     * of "" and a password of "".  If that's not OK, boot it out.
+     */
+    if (!wo->neg_upap || !null_login(unit)) {
+      AUTHDEBUG(LOG_WARNING, ("peer refused to authenticate\n"));
+      lcp_close(unit, "peer refused to authenticate");
+      return;
+    }
+  }
+
+  lcp_phase[unit] = PHASE_AUTHENTICATE;
+  auth = 0;
+#if CHAP_SUPPORT
+  if (go->neg_chap) {
+    ChapAuthPeer(unit, ppp_settings.our_name, go->chap_mdtype);
+    auth |= CHAP_PEER;
+  } 
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT && CHAP_SUPPORT
+  else
+#endif /* PAP_SUPPORT && CHAP_SUPPORT */
+#if PAP_SUPPORT
+  if (go->neg_upap) {
+    upap_authpeer(unit);
+    auth |= PAP_PEER;
+  }
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+  if (ho->neg_chap) {
+    ChapAuthWithPeer(unit, ppp_settings.user, ho->chap_mdtype);
+    auth |= CHAP_WITHPEER;
+  }
+#endif /* CHAP_SUPPORT */
+#if PAP_SUPPORT && CHAP_SUPPORT
+  else
+#endif /* PAP_SUPPORT && CHAP_SUPPORT */
+#if PAP_SUPPORT
+  if (ho->neg_upap) {
+    if (ppp_settings.passwd[0] == 0) {
+      passwd_from_file = 1;
+      if (!get_pap_passwd(unit, ppp_settings.user, ppp_settings.passwd)) {
+        AUTHDEBUG(LOG_ERR, ("No secret found for PAP login\n"));
+      }
+    }
+    upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd);
+    auth |= PAP_WITHPEER;
+  }
+#endif /* PAP_SUPPORT */
+  auth_pending[unit] = auth;
+
+  if (!auth) {
+    network_phase(unit);
+  }
+}
+
+/*
+ * Proceed to the network phase.
+ */
+static void
+network_phase(int unit)
+{
+  int i;
+  struct protent *protp;
+  lcp_options *go = &lcp_gotoptions[unit];
+
+  /*
+   * If the peer had to authenticate, run the auth-up script now.
+   */
+  if ((go->neg_chap || go->neg_upap) && !did_authup) {
+    /* XXX Do setup for peer authentication. */
+    did_authup = 1;
+  }
+
+#if CBCP_SUPPORT
+  /*
+   * If we negotiated callback, do it now.
+   */
+  if (go->neg_cbcp) {
+    lcp_phase[unit] = PHASE_CALLBACK;
+    (*cbcp_protent.open)(unit);
+    return;
+  }
+#endif /* CBCP_SUPPORT */
+
+  lcp_phase[unit] = PHASE_NETWORK;
+  for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
+    if (protp->protocol < 0xC000 && protp->enabled_flag && protp->open != NULL) {
+      (*protp->open)(unit);
+      if (protp->protocol != PPP_CCP) {
+        ++num_np_open;
+      }
+    }
+  }
+
+  if (num_np_open == 0) {
+    /* nothing to do */
+    lcp_close(0, "No network protocols running");
+  }
+}
+/* @todo: add void start_networks(void) here (pppd 2.3.11) */
+
+/*
+ * The peer has failed to authenticate himself using `protocol'.
+ */
+void
+auth_peer_fail(int unit, u16_t protocol)
+{
+  LWIP_UNUSED_ARG(protocol);
+
+  AUTHDEBUG(LOG_INFO, ("auth_peer_fail: %d proto=%X\n", unit, protocol));
+  /*
+   * Authentication failure: take the link down
+   */
+  lcp_close(unit, "Authentication failed");
+}
+
+
+#if PAP_SUPPORT || CHAP_SUPPORT
+/*
+ * The peer has been successfully authenticated using `protocol'.
+ */
+void
+auth_peer_success(int unit, u16_t protocol, char *name, int namelen)
+{
+  int pbit;
+
+  AUTHDEBUG(LOG_INFO, ("auth_peer_success: %d proto=%X\n", unit, protocol));
+  switch (protocol) {
+    case PPP_CHAP:
+      pbit = CHAP_PEER;
+      break;
+    case PPP_PAP:
+      pbit = PAP_PEER;
+      break;
+    default:
+      AUTHDEBUG(LOG_WARNING, ("auth_peer_success: unknown protocol %x\n", protocol));
+      return;
+  }
+
+  /*
+   * Save the authenticated name of the peer for later.
+   */
+  if (namelen > (int)sizeof(peer_authname) - 1) {
+    namelen = sizeof(peer_authname) - 1;
+  }
+  BCOPY(name, peer_authname, namelen);
+  peer_authname[namelen] = 0;
+  
+  /*
+   * If there is no more authentication still to be done,
+   * proceed to the network (or callback) phase.
+   */
+  if ((auth_pending[unit] &= ~pbit) == 0) {
+    network_phase(unit);
+  }
+}
+
+/*
+ * We have failed to authenticate ourselves to the peer using `protocol'.
+ */
+void
+auth_withpeer_fail(int unit, u16_t protocol)
+{
+  int errCode = PPPERR_AUTHFAIL;
+
+  LWIP_UNUSED_ARG(protocol);
+
+  AUTHDEBUG(LOG_INFO, ("auth_withpeer_fail: %d proto=%X\n", unit, protocol));
+  if (passwd_from_file) {
+    BZERO(ppp_settings.passwd, MAXSECRETLEN);
+  }
+
+  /*
+   * We've failed to authenticate ourselves to our peer.
+   * He'll probably take the link down, and there's not much
+   * we can do except wait for that.
+   */
+  pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode);
+  lcp_close(unit, "Failed to authenticate ourselves to peer");
+}
+
+/*
+ * We have successfully authenticated ourselves with the peer using `protocol'.
+ */
+void
+auth_withpeer_success(int unit, u16_t protocol)
+{
+  int pbit;
+
+  AUTHDEBUG(LOG_INFO, ("auth_withpeer_success: %d proto=%X\n", unit, protocol));
+  switch (protocol) {
+    case PPP_CHAP:
+      pbit = CHAP_WITHPEER;
+      break;
+    case PPP_PAP:
+      if (passwd_from_file) {
+        BZERO(ppp_settings.passwd, MAXSECRETLEN);
+      }
+      pbit = PAP_WITHPEER;
+      break;
+    default:
+      AUTHDEBUG(LOG_WARNING, ("auth_peer_success: unknown protocol %x\n", protocol));
+      pbit = 0;
+  }
+
+  /*
+   * If there is no more authentication still being done,
+   * proceed to the network (or callback) phase.
+   */
+  if ((auth_pending[unit] &= ~pbit) == 0) {
+    network_phase(unit);
+  }
+}
+#endif /* PAP_SUPPORT || CHAP_SUPPORT */
+
+
+/*
+ * np_up - a network protocol has come up.
+ */
+void
+np_up(int unit, u16_t proto)
+{
+  LWIP_UNUSED_ARG(unit);
+  LWIP_UNUSED_ARG(proto);
+
+  AUTHDEBUG(LOG_INFO, ("np_up: %d proto=%X\n", unit, proto));
+  if (num_np_up == 0) {
+    AUTHDEBUG(LOG_INFO, ("np_up: maxconnect=%d idle_time_limit=%d\n",ppp_settings.maxconnect,ppp_settings.idle_time_limit));
+    /*
+     * At this point we consider that the link has come up successfully.
+     */
+    if (ppp_settings.idle_time_limit > 0) {
+      TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit);
+    }
+
+    /*
+     * Set a timeout to close the connection once the maximum
+     * connect time has expired.
+     */
+    if (ppp_settings.maxconnect > 0) {
+      TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect);
+    }
+  }
+  ++num_np_up;
+}
+
+/*
+ * np_down - a network protocol has gone down.
+ */
+void
+np_down(int unit, u16_t proto)
+{
+  LWIP_UNUSED_ARG(unit);
+  LWIP_UNUSED_ARG(proto);
+
+  AUTHDEBUG(LOG_INFO, ("np_down: %d proto=%X\n", unit, proto));
+  if (--num_np_up == 0 && ppp_settings.idle_time_limit > 0) {
+    UNTIMEOUT(check_idle, NULL);
+  }
+}
+
+/*
+ * np_finished - a network protocol has finished using the link.
+ */
+void
+np_finished(int unit, u16_t proto)
+{
+  LWIP_UNUSED_ARG(unit);
+  LWIP_UNUSED_ARG(proto);
+
+  AUTHDEBUG(LOG_INFO, ("np_finished: %d proto=%X\n", unit, proto));
+  if (--num_np_open <= 0) {
+    /* no further use for the link: shut up shop. */
+    lcp_close(0, "No network protocols running");
+  }
+}
+
+/*
+ * check_idle - check whether the link has been idle for long
+ * enough that we can shut it down.
+ */
+static void
+check_idle(void *arg)
+{
+  struct ppp_idle idle;
+  u_short itime;
+  
+  LWIP_UNUSED_ARG(arg);
+  if (!get_idle_time(0, &idle)) {
+    return;
+  }
+  itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle);
+  if (itime >= ppp_settings.idle_time_limit) {
+    /* link is idle: shut it down. */
+    AUTHDEBUG(LOG_INFO, ("Terminating connection due to lack of activity.\n"));
+    lcp_close(0, "Link inactive");
+  } else {
+    TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit - itime);
+  }
+}
+
+/*
+ * connect_time_expired - log a message and close the connection.
+ */
+static void
+connect_time_expired(void *arg)
+{
+  LWIP_UNUSED_ARG(arg);
+
+  AUTHDEBUG(LOG_INFO, ("Connect time expired\n"));
+  lcp_close(0, "Connect time expired");   /* Close connection */
+}
+
+#if 0 /* UNUSED */
+/*
+ * auth_check_options - called to check authentication options.
+ */
+void
+auth_check_options(void)
+{
+  lcp_options *wo = &lcp_wantoptions[0];
+  int can_auth;
+  ipcp_options *ipwo = &ipcp_wantoptions[0];
+  u32_t remote;
+
+  /* Default our_name to hostname, and user to our_name */
+  if (ppp_settings.our_name[0] == 0 || ppp_settings.usehostname) {
+      strcpy(ppp_settings.our_name, ppp_settings.hostname);
+  }
+
+  if (ppp_settings.user[0] == 0) {
+    strcpy(ppp_settings.user, ppp_settings.our_name);
+  }
+
+  /* If authentication is required, ask peer for CHAP or PAP. */
+  if (ppp_settings.auth_required && !wo->neg_chap && !wo->neg_upap) {
+    wo->neg_chap = 1;
+    wo->neg_upap = 1;
+  }
+  
+  /*
+   * Check whether we have appropriate secrets to use
+   * to authenticate the peer.
+   */
+  can_auth = wo->neg_upap && have_pap_secret();
+  if (!can_auth && wo->neg_chap) {
+    remote = ipwo->accept_remote? 0: ipwo->hisaddr;
+    can_auth = have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote);
+  }
+
+  if (ppp_settings.auth_required && !can_auth) {
+    ppp_panic("No auth secret");
+  }
+}
+#endif /* UNUSED */
+
+/*
+ * auth_reset - called when LCP is starting negotiations to recheck
+ * authentication options, i.e. whether we have appropriate secrets
+ * to use for authenticating ourselves and/or the peer.
+ */
+void
+auth_reset(int unit)
+{
+  lcp_options *go = &lcp_gotoptions[unit];
+  lcp_options *ao = &lcp_allowoptions[0];
+  ipcp_options *ipwo = &ipcp_wantoptions[0];
+  u32_t remote;
+
+  AUTHDEBUG(LOG_INFO, ("auth_reset: %d\n", unit));
+  ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(unit, NULL, NULL));
+  ao->neg_chap = !ppp_settings.refuse_chap && ppp_settings.passwd[0] != 0 /*have_chap_secret(ppp_settings.user, ppp_settings.remote_name, (u32_t)0)*/;
+
+  if (go->neg_upap && !have_pap_secret()) {
+    go->neg_upap = 0;
+  }
+  if (go->neg_chap) {
+    remote = ipwo->accept_remote? 0: ipwo->hisaddr;
+    if (!have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote)) {
+      go->neg_chap = 0;
+    }
+  }
+}
+
+#if PAP_SUPPORT
+/*
+ * check_passwd - Check the user name and passwd against the PAP secrets
+ * file.  If requested, also check against the system password database,
+ * and login the user if OK.
+ *
+ * returns:
+ *  UPAP_AUTHNAK: Authentication failed.
+ *  UPAP_AUTHACK: Authentication succeeded.
+ * In either case, msg points to an appropriate message.
+ */
+u_char
+check_passwd( int unit, char *auser, int userlen, char *apasswd, int passwdlen, char **msg, int *msglen)
+{
+#if 1 /* XXX Assume all entries OK. */
+  LWIP_UNUSED_ARG(unit);
+  LWIP_UNUSED_ARG(auser);
+  LWIP_UNUSED_ARG(userlen);
+  LWIP_UNUSED_ARG(apasswd);
+  LWIP_UNUSED_ARG(passwdlen);
+  LWIP_UNUSED_ARG(msglen);
+  *msg = (char *) 0;
+  return UPAP_AUTHACK;     /* XXX Assume all entries OK. */
+#else
+  u_char ret = 0;
+  struct wordlist *addrs = NULL;
+  char passwd[256], user[256];
+  char secret[MAXWORDLEN];
+  static u_short attempts = 0;
+  
+  /*
+   * Make copies of apasswd and auser, then null-terminate them.
+   */
+  BCOPY(apasswd, passwd, passwdlen);
+  passwd[passwdlen] = '\0';
+  BCOPY(auser, user, userlen);
+  user[userlen] = '\0';
+  *msg = (char *) 0;
+
+  /* XXX Validate user name and password. */
+  ret = UPAP_AUTHACK;     /* XXX Assume all entries OK. */
+      
+  if (ret == UPAP_AUTHNAK) {
+    if (*msg == (char *) 0) {
+      *msg = "Login incorrect";
+    }
+    *msglen = strlen(*msg);
+    /*
+     * Frustrate passwd stealer programs.
+     * Allow 10 tries, but start backing off after 3 (stolen from login).
+     * On 10'th, drop the connection.
+     */
+    if (attempts++ >= 10) {
+      AUTHDEBUG(LOG_WARNING, ("%d LOGIN FAILURES BY %s\n", attempts, user));
+      /*ppp_panic("Excess Bad Logins");*/
+    }
+    if (attempts > 3) {
+      /* @todo: this was sleep(), i.e. seconds, not milliseconds
+       * I don't think we really need this in lwIP - we would block tcpip_thread!
+       */
+      /*sys_msleep((attempts - 3) * 5);*/
+    }
+    if (addrs != NULL) {
+      free_wordlist(addrs);
+    }
+  } else {
+    attempts = 0; /* Reset count */
+    if (*msg == (char *) 0) {
+      *msg = "Login ok";
+    }
+    *msglen = strlen(*msg);
+    set_allowed_addrs(unit, addrs);
+  }
+
+  BZERO(passwd, sizeof(passwd));
+  BZERO(secret, sizeof(secret));
+
+  return ret;
+#endif
+}
+#endif /* PAP_SUPPORT */
+
+#if 0 /* UNUSED */
+/*
+ * This function is needed for PAM.
+ */
+
+#ifdef USE_PAM
+
+/* lwip does not support PAM*/
+
+#endif  /* USE_PAM */
+
+#endif /* UNUSED */
+
+
+#if 0 /* UNUSED */
+/*
+ * plogin - Check the user name and password against the system
+ * password database, and login the user if OK.
+ *
+ * returns:
+ *  UPAP_AUTHNAK: Login failed.
+ *  UPAP_AUTHACK: Login succeeded.
+ * In either case, msg points to an appropriate message.
+ */
+static int
+plogin(char *user, char *passwd, char **msg, int *msglen)
+{
+
+  LWIP_UNUSED_ARG(user);
+  LWIP_UNUSED_ARG(passwd);
+  LWIP_UNUSED_ARG(msg);
+  LWIP_UNUSED_ARG(msglen);
+
+
+ /* The new lines are here align the file when 
+  * compared against the pppd 2.3.11 code */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  /* XXX Fail until we decide that we want to support logins. */
+  return (UPAP_AUTHNAK);
+}
+#endif
+
+
+
+/*
+ * plogout - Logout the user.
+ */
+static void
+plogout(void)
+{
+  logged_in = 0;
+}
+
+/*
+ * null_login - Check if a username of "" and a password of "" are
+ * acceptable, and iff so, set the list of acceptable IP addresses
+ * and return 1.
+ */
+static int
+null_login(int unit)
+{
+  LWIP_UNUSED_ARG(unit);
+  /* XXX Fail until we decide that we want to support logins. */
+  return 0;
+}
+
+
+/*
+ * get_pap_passwd - get a password for authenticating ourselves with
+ * our peer using PAP.  Returns 1 on success, 0 if no suitable password
+ * could be found.
+ */
+static int
+get_pap_passwd(int unit, char *user, char *passwd)
+{
+  LWIP_UNUSED_ARG(unit);
+/* normally we would reject PAP if no password is provided,
+   but this causes problems with some providers (like CHT in Taiwan)
+   who incorrectly request PAP and expect a bogus/empty password, so
+   always provide a default user/passwd of "none"/"none"
+
+   @todo: This should be configured by the user, instead of being hardcoded here!
+*/
+  if(user) {
+    strcpy(user, "none");
+  }
+  if(passwd) {
+    strcpy(passwd, "none");
+  }
+  return 1;
+}
+
+/*
+ * have_pap_secret - check whether we have a PAP file with any
+ * secrets that we could possibly use for authenticating the peer.
+ */
+static int
+have_pap_secret(void)
+{
+  /* XXX Fail until we set up our passwords. */
+  return 0;
+}
+
+/*
+ * have_chap_secret - check whether we have a CHAP file with a
+ * secret that we could possibly use for authenticating `client'
+ * on `server'.  Either can be the null string, meaning we don't
+ * know the identity yet.
+ */
+static int
+have_chap_secret(char *client, char *server, u32_t remote)
+{
+  LWIP_UNUSED_ARG(client);
+  LWIP_UNUSED_ARG(server);
+  LWIP_UNUSED_ARG(remote);
+
+  /* XXX Fail until we set up our passwords. */
+  return 0;
+}
+#if CHAP_SUPPORT
+
+/*
+ * get_secret - open the CHAP secret file and return the secret
+ * for authenticating the given client on the given server.
+ * (We could be either client or server).
+ */
+int
+get_secret(int unit, char *client, char *server, char *secret, int *secret_len, int save_addrs)
+{
+#if 1
+  int len;
+  struct wordlist *addrs;
+
+  LWIP_UNUSED_ARG(unit);
+  LWIP_UNUSED_ARG(server);
+  LWIP_UNUSED_ARG(save_addrs);
+
+  addrs = NULL;
+
+  if(!client || !client[0] || strcmp(client, ppp_settings.user)) {
+    return 0;
+  }
+
+  len = (int)strlen(ppp_settings.passwd);
+  if (len > MAXSECRETLEN) {
+    AUTHDEBUG(LOG_ERR, ("Secret for %s on %s is too long\n", client, server));
+    len = MAXSECRETLEN;
+  }
+
+  BCOPY(ppp_settings.passwd, secret, len);
+  *secret_len = len;
+
+  return 1;
+#else
+  int ret = 0, len;
+  struct wordlist *addrs;
+  char secbuf[MAXWORDLEN];
+  
+  addrs = NULL;
+  secbuf[0] = 0;
+
+  /* XXX Find secret. */
+  if (ret < 0) {
+    return 0;
+  }
+
+  if (save_addrs) {
+    set_allowed_addrs(unit, addrs);
+  }
+
+  len = strlen(secbuf);
+  if (len > MAXSECRETLEN) {
+    AUTHDEBUG(LOG_ERR, ("Secret for %s on %s is too long\n", client, server));
+    len = MAXSECRETLEN;
+  }
+
+  BCOPY(secbuf, secret, len);
+  BZERO(secbuf, sizeof(secbuf));
+  *secret_len = len;
+
+  return 1;
+#endif
+}
+#endif /* CHAP_SUPPORT */
+
+
+#if 0 /* PAP_SUPPORT || CHAP_SUPPORT */
+/*
+ * set_allowed_addrs() - set the list of allowed addresses.
+ */
+static void
+set_allowed_addrs(int unit, struct wordlist *addrs)
+{
+  if (addresses[unit] != NULL) {
+    free_wordlist(addresses[unit]);
+  }
+  addresses[unit] = addrs;
+
+#if 0
+  /*
+   * If there's only one authorized address we might as well
+   * ask our peer for that one right away
+   */
+  if (addrs != NULL && addrs->next == NULL) {
+    char *p = addrs->word;
+    struct ipcp_options *wo = &ipcp_wantoptions[unit];
+    u32_t a;
+    struct hostent *hp;
+    
+    if (wo->hisaddr == 0 && *p != '!' && *p != '-' && strchr(p, '/') == NULL) {
+      hp = gethostbyname(p);
+      if (hp != NULL && hp->h_addrtype == AF_INET) {
+        a = *(u32_t *)hp->h_addr;
+      } else {
+        a = inet_addr(p);
+      }
+      if (a != (u32_t) -1) {
+        wo->hisaddr = a;
+      }
+    }
+  }
+#endif
+}
+#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */
+
+/*
+ * auth_ip_addr - check whether the peer is authorized to use
+ * a given IP address.  Returns 1 if authorized, 0 otherwise.
+ */
+int
+auth_ip_addr(int unit, u32_t addr)
+{
+  return ip_addr_check(addr, addresses[unit]);
+}
+
+static int /* @todo: integrate this funtion into auth_ip_addr()*/
+ip_addr_check(u32_t addr, struct wordlist *addrs)
+{
+  /* don't allow loopback or multicast address */
+  if (bad_ip_adrs(addr)) {
+    return 0;
+  }
+
+  if (addrs == NULL) {
+    return !ppp_settings.auth_required; /* no addresses authorized */
+  }
+
+  /* XXX All other addresses allowed. */
+  return 1;
+}
+
+/*
+ * bad_ip_adrs - return 1 if the IP address is one we don't want
+ * to use, such as an address in the loopback net or a multicast address.
+ * addr is in network byte order.
+ */
+int
+bad_ip_adrs(u32_t addr)
+{
+  addr = ntohl(addr);
+  return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
+      || IN_MULTICAST(addr) || IN_BADCLASS(addr);
+}
+
+#if 0 /* UNUSED */ /* PAP_SUPPORT || CHAP_SUPPORT */
+/*
+ * some_ip_ok - check a wordlist to see if it authorizes any
+ * IP address(es).
+ */
+static int
+some_ip_ok(struct wordlist *addrs)
+{
+    for (; addrs != 0; addrs = addrs->next) {
+      if (addrs->word[0] == '-')
+        break;
+      if (addrs->word[0] != '!')
+        return 1; /* some IP address is allowed */
+    }
+    return 0;
+}
+
+/*
+ * check_access - complain if a secret file has too-liberal permissions.
+ */
+static void
+check_access(FILE *f, char *filename)
+{
+    struct stat sbuf;
+
+    if (fstat(fileno(f), &sbuf) < 0) {
+      warn("cannot stat secret file %s: %m", filename);
+    } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
+      warn("Warning - secret file %s has world and/or group access",
+            filename);
+    }
+}
+
+
+/*
+ * scan_authfile - Scan an authorization file for a secret suitable
+ * for authenticating `client' on `server'.  The return value is -1
+ * if no secret is found, otherwise >= 0.  The return value has
+ * NONWILD_CLIENT set if the secret didn't have "*" for the client, and
+ * NONWILD_SERVER set if the secret didn't have "*" for the server.
+ * Any following words on the line up to a "--" (i.e. address authorization
+ * info) are placed in a wordlist and returned in *addrs.  Any
+ * following words (extra options) are placed in a wordlist and
+ * returned in *opts.
+ * We assume secret is NULL or points to MAXWORDLEN bytes of space.
+ */
+static int
+scan_authfile(FILE *f, char *client, char *server, char *secret, struct wordlist **addrs, struct wordlist **opts, char *filename)
+{
+  /* We do not (currently) need this in lwip  */
+  return 0; /* dummy */
+}
+/*
+ * free_wordlist - release memory allocated for a wordlist.
+ */
+static void
+free_wordlist(struct wordlist *wp)
+{
+  struct wordlist *next;
+
+  while (wp != NULL) {
+    next = wp->next;
+    free(wp);
+    wp = next;
+  }
+}
+
+/*
+ * auth_script_done - called when the auth-up or auth-down script
+ * has finished.
+ */
+static void
+auth_script_done(void *arg)
+{
+    auth_script_pid = 0;
+    switch (auth_script_state) {
+    case s_up:
+      if (auth_state == s_down) {
+        auth_script_state = s_down;
+        auth_script(_PATH_AUTHDOWN);
+      }
+      break;
+    case s_down:
+      if (auth_state == s_up) {
+        auth_script_state = s_up;
+        auth_script(_PATH_AUTHUP);
+      }
+      break;
+    }
+}
+
+/*
+ * auth_script - execute a script with arguments
+ * interface-name peer-name real-user tty speed
+ */
+static void
+auth_script(char *script)
+{
+    char strspeed[32];
+    struct passwd *pw;
+    char struid[32];
+    char *user_name;
+    char *argv[8];
+
+    if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL)
+      user_name = pw->pw_name;
+    else {
+      slprintf(struid, sizeof(struid), "%d", getuid());
+      user_name = struid;
+    }
+    slprintf(strspeed, sizeof(strspeed), "%d", baud_rate);
+
+    argv[0] = script;
+    argv[1] = ifname;
+    argv[2] = peer_authname;
+    argv[3] = user_name;
+    argv[4] = devnam;
+    argv[5] = strspeed;
+    argv[6] = NULL;
+
+    auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL);
+}
+#endif  /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */
+#endif /* PPP_SUPPORT */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/auth.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/auth.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/auth.h	(revision 164)
@@ -0,0 +1,111 @@
+/*****************************************************************************
+* auth.h -  PPP Authentication and phase control header file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1998 Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Original derived from BSD pppd.h.
+*****************************************************************************/
+/*
+ * pppd.h - PPP daemon global declarations.
+ *
+ * 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.
+ *
+ */
+
+#ifndef AUTH_H
+#define AUTH_H
+
+/***********************
+*** PUBLIC FUNCTIONS ***
+***********************/
+
+/* we are starting to use the link */
+void link_required (int);
+
+/* we are finished with the link */
+void link_terminated (int);
+
+/* the LCP layer has left the Opened state */
+void link_down (int);
+
+/* the link is up; authenticate now */
+void link_established (int);
+
+/* a network protocol has come up */
+void np_up (int, u16_t);
+
+/* a network protocol has gone down */
+void np_down (int, u16_t);
+
+/* a network protocol no longer needs link */
+void np_finished (int, u16_t);
+
+/* peer failed to authenticate itself */
+void auth_peer_fail (int, u16_t);
+
+/* peer successfully authenticated itself */
+void auth_peer_success (int, u16_t, char *, int);
+
+/* we failed to authenticate ourselves */
+void auth_withpeer_fail (int, u16_t);
+
+/* we successfully authenticated ourselves */
+void auth_withpeer_success (int, u16_t);
+
+/* check authentication options supplied */
+void auth_check_options (void);
+
+/* check what secrets we have */
+void auth_reset (int);
+
+/* Check peer-supplied username/password */
+u_char check_passwd (int, char *, int, char *, int, char **, int *);
+
+/* get "secret" for chap */
+int  get_secret (int, char *, char *, char *, int *, int);
+
+/* check if IP address is authorized */
+int  auth_ip_addr (int, u32_t);
+
+/* check if IP address is unreasonable */
+int  bad_ip_adrs (u32_t);
+
+#endif /* AUTH_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/chap.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/chap.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/chap.c	(revision 164)
@@ -0,0 +1,908 @@
+/*** WARNING - THIS HAS NEVER BEEN FINISHED ***/
+/*****************************************************************************
+* chap.c - Network Challenge Handshake Authentication Protocol program file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 by Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Original based on BSD chap.c.
+*****************************************************************************/
+/*
+ * chap.c - Challenge Handshake Authentication Protocol.
+ *
+ * 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) 1991 Gregory M. Christy.
+ * 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 Gregory M. Christy.  The name of the author 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.
+ */
+
+#include "lwip/opt.h"
+
+#if PPP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
+
+#if CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "ppp_impl.h"
+#include "pppdebug.h"
+
+#include "magic.h"
+#include "randm.h"
+#include "auth.h"
+#include "md5.h"
+#include "chap.h"
+#include "chpms.h"
+
+#include <string.h>
+
+#if 0 /* UNUSED */
+/*
+ * Command-line options.
+ */
+static option_t chap_option_list[] = {
+    { "chap-restart", o_int, &chap[0].timeouttime,
+      "Set timeout for CHAP" },
+    { "chap-max-challenge", o_int, &chap[0].max_transmits,
+      "Set max #xmits for challenge" },
+    { "chap-interval", o_int, &chap[0].chal_interval,
+      "Set interval for rechallenge" },
+#ifdef MSLANMAN
+    { "ms-lanman", o_bool, &ms_lanman,
+      "Use LanMan passwd when using MS-CHAP", 1 },
+#endif
+    { NULL }
+};
+#endif /* UNUSED */
+
+/*
+ * Protocol entry points.
+ */
+static void ChapInit (int);
+static void ChapLowerUp (int);
+static void ChapLowerDown (int);
+static void ChapInput (int, u_char *, int);
+static void ChapProtocolReject (int);
+#if PPP_ADDITIONAL_CALLBACKS
+static int  ChapPrintPkt (u_char *, int, void (*) (void *, char *, ...), void *);
+#endif
+
+struct protent chap_protent = {
+  PPP_CHAP,
+  ChapInit,
+  ChapInput,
+  ChapProtocolReject,
+  ChapLowerUp,
+  ChapLowerDown,
+  NULL,
+  NULL,
+#if PPP_ADDITIONAL_CALLBACKS
+  ChapPrintPkt,
+  NULL,
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+  1,
+  "CHAP",
+#if PPP_ADDITIONAL_CALLBACKS
+  NULL,
+  NULL,
+  NULL
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+};
+
+chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */
+
+static void ChapChallengeTimeout (void *);
+static void ChapResponseTimeout (void *);
+static void ChapReceiveChallenge (chap_state *, u_char *, u_char, int);
+static void ChapRechallenge (void *);
+static void ChapReceiveResponse (chap_state *, u_char *, int, int);
+static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len);
+static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len);
+static void ChapSendStatus (chap_state *, int);
+static void ChapSendChallenge (chap_state *);
+static void ChapSendResponse (chap_state *);
+static void ChapGenChallenge (chap_state *);
+
+/*
+ * ChapInit - Initialize a CHAP unit.
+ */
+static void
+ChapInit(int unit)
+{
+  chap_state *cstate = &chap[unit];
+
+  BZERO(cstate, sizeof(*cstate));
+  cstate->unit = unit;
+  cstate->clientstate = CHAPCS_INITIAL;
+  cstate->serverstate = CHAPSS_INITIAL;
+  cstate->timeouttime = CHAP_DEFTIMEOUT;
+  cstate->max_transmits = CHAP_DEFTRANSMITS;
+  /* random number generator is initialized in magic_init */
+}
+
+
+/*
+ * ChapAuthWithPeer - Authenticate us with our peer (start client).
+ *
+ */
+void
+ChapAuthWithPeer(int unit, char *our_name, u_char digest)
+{
+  chap_state *cstate = &chap[unit];
+
+  cstate->resp_name = our_name;
+  cstate->resp_type = digest;
+
+  if (cstate->clientstate == CHAPCS_INITIAL ||
+      cstate->clientstate == CHAPCS_PENDING) {
+    /* lower layer isn't up - wait until later */
+    cstate->clientstate = CHAPCS_PENDING;
+    return;
+  }
+
+  /*
+   * We get here as a result of LCP coming up.
+   * So even if CHAP was open before, we will 
+   * have to re-authenticate ourselves.
+   */
+  cstate->clientstate = CHAPCS_LISTEN;
+}
+
+
+/*
+ * ChapAuthPeer - Authenticate our peer (start server).
+ */
+void
+ChapAuthPeer(int unit, char *our_name, u_char digest)
+{
+  chap_state *cstate = &chap[unit];
+
+  cstate->chal_name = our_name;
+  cstate->chal_type = digest;
+  
+  if (cstate->serverstate == CHAPSS_INITIAL ||
+      cstate->serverstate == CHAPSS_PENDING) {
+    /* lower layer isn't up - wait until later */
+    cstate->serverstate = CHAPSS_PENDING;
+    return;
+  }
+
+  ChapGenChallenge(cstate);
+  ChapSendChallenge(cstate);    /* crank it up dude! */
+  cstate->serverstate = CHAPSS_INITIAL_CHAL;
+}
+
+
+/*
+ * ChapChallengeTimeout - Timeout expired on sending challenge.
+ */
+static void
+ChapChallengeTimeout(void *arg)
+{
+  chap_state *cstate = (chap_state *) arg;
+
+  /* if we aren't sending challenges, don't worry.  then again we */
+  /* probably shouldn't be here either */
+  if (cstate->serverstate != CHAPSS_INITIAL_CHAL &&
+      cstate->serverstate != CHAPSS_RECHALLENGE) {
+    return;
+  }
+
+  if (cstate->chal_transmits >= cstate->max_transmits) {
+    /* give up on peer */
+    CHAPDEBUG(LOG_ERR, ("Peer failed to respond to CHAP challenge\n"));
+    cstate->serverstate = CHAPSS_BADAUTH;
+    auth_peer_fail(cstate->unit, PPP_CHAP);
+    return;
+  }
+
+  ChapSendChallenge(cstate); /* Re-send challenge */
+}
+
+
+/*
+ * ChapResponseTimeout - Timeout expired on sending response.
+ */
+static void
+ChapResponseTimeout(void *arg)
+{
+  chap_state *cstate = (chap_state *) arg;
+
+  /* if we aren't sending a response, don't worry. */
+  if (cstate->clientstate != CHAPCS_RESPONSE) {
+    return;
+  }
+
+  ChapSendResponse(cstate);    /* re-send response */
+}
+
+
+/*
+ * ChapRechallenge - Time to challenge the peer again.
+ */
+static void
+ChapRechallenge(void *arg)
+{
+  chap_state *cstate = (chap_state *) arg;
+  
+  /* if we aren't sending a response, don't worry. */
+  if (cstate->serverstate != CHAPSS_OPEN) {
+    return;
+  }
+
+  ChapGenChallenge(cstate);
+  ChapSendChallenge(cstate);
+  cstate->serverstate = CHAPSS_RECHALLENGE;
+}
+
+
+/*
+ * ChapLowerUp - The lower layer is up.
+ *
+ * Start up if we have pending requests.
+ */
+static void
+ChapLowerUp(int unit)
+{
+  chap_state *cstate = &chap[unit];
+
+  if (cstate->clientstate == CHAPCS_INITIAL) {
+    cstate->clientstate = CHAPCS_CLOSED;
+  } else if (cstate->clientstate == CHAPCS_PENDING) {
+    cstate->clientstate = CHAPCS_LISTEN;
+  }
+
+  if (cstate->serverstate == CHAPSS_INITIAL) {
+    cstate->serverstate = CHAPSS_CLOSED;
+  } else if (cstate->serverstate == CHAPSS_PENDING) {
+    ChapGenChallenge(cstate);
+    ChapSendChallenge(cstate);
+    cstate->serverstate = CHAPSS_INITIAL_CHAL;
+  }
+}
+
+
+/*
+ * ChapLowerDown - The lower layer is down.
+ *
+ * Cancel all timeouts.
+ */
+static void
+ChapLowerDown(int unit)
+{
+  chap_state *cstate = &chap[unit];
+
+  /* Timeout(s) pending?  Cancel if so. */
+  if (cstate->serverstate == CHAPSS_INITIAL_CHAL ||
+      cstate->serverstate == CHAPSS_RECHALLENGE) {
+    UNTIMEOUT(ChapChallengeTimeout, cstate);
+  } else if (cstate->serverstate == CHAPSS_OPEN
+      && cstate->chal_interval != 0) {
+    UNTIMEOUT(ChapRechallenge, cstate);
+  }
+  if (cstate->clientstate == CHAPCS_RESPONSE) {
+    UNTIMEOUT(ChapResponseTimeout, cstate);
+  }
+  cstate->clientstate = CHAPCS_INITIAL;
+  cstate->serverstate = CHAPSS_INITIAL;
+}
+
+
+/*
+ * ChapProtocolReject - Peer doesn't grok CHAP.
+ */
+static void
+ChapProtocolReject(int unit)
+{
+  chap_state *cstate = &chap[unit];
+  
+  if (cstate->serverstate != CHAPSS_INITIAL &&
+      cstate->serverstate != CHAPSS_CLOSED) {
+    auth_peer_fail(unit, PPP_CHAP);
+  }
+  if (cstate->clientstate != CHAPCS_INITIAL &&
+      cstate->clientstate != CHAPCS_CLOSED) {
+    auth_withpeer_fail(unit, PPP_CHAP); /* lwip: just sets the PPP error code on this unit to PPPERR_AUTHFAIL */
+  }
+  ChapLowerDown(unit); /* shutdown chap */
+}
+
+
+/*
+ * ChapInput - Input CHAP packet.
+ */
+static void
+ChapInput(int unit, u_char *inpacket, int packet_len)
+{
+  chap_state *cstate = &chap[unit];
+  u_char *inp;
+  u_char code, id;
+  int len;
+  
+  /*
+   * Parse header (code, id and length).
+   * If packet too short, drop it.
+   */
+  inp = inpacket;
+  if (packet_len < CHAP_HEADERLEN) {
+    CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd short header.\n"));
+    return;
+  }
+  GETCHAR(code, inp);
+  GETCHAR(id, inp);
+  GETSHORT(len, inp);
+  if (len < CHAP_HEADERLEN) {
+    CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd illegal length.\n"));
+    return;
+  }
+  if (len > packet_len) {
+    CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd short packet.\n"));
+    return;
+  }
+  len -= CHAP_HEADERLEN;
+  
+  /*
+   * Action depends on code (as in fact it usually does :-).
+   */
+  switch (code) {
+    case CHAP_CHALLENGE:
+      ChapReceiveChallenge(cstate, inp, id, len);
+      break;
+    
+    case CHAP_RESPONSE:
+      ChapReceiveResponse(cstate, inp, id, len);
+      break;
+    
+    case CHAP_FAILURE:
+      ChapReceiveFailure(cstate, inp, id, len);
+      break;
+    
+    case CHAP_SUCCESS:
+      ChapReceiveSuccess(cstate, inp, id, len);
+      break;
+    
+    default:        /* Need code reject? */
+      CHAPDEBUG(LOG_WARNING, ("Unknown CHAP code (%d) received.\n", code));
+      break;
+  }
+}
+
+
+/*
+ * ChapReceiveChallenge - Receive Challenge and send Response.
+ */
+static void
+ChapReceiveChallenge(chap_state *cstate, u_char *inp, u_char id, int len)
+{
+  int rchallenge_len;
+  u_char *rchallenge;
+  int secret_len;
+  char secret[MAXSECRETLEN];
+  char rhostname[256];
+  MD5_CTX mdContext;
+  u_char hash[MD5_SIGNATURE_SIZE];
+
+  CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: Rcvd id %d.\n", id));
+  if (cstate->clientstate == CHAPCS_CLOSED ||
+    cstate->clientstate == CHAPCS_PENDING) {
+    CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: in state %d\n",
+         cstate->clientstate));
+    return;
+  }
+
+  if (len < 2) {
+    CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: rcvd short packet.\n"));
+    return;
+  }
+
+  GETCHAR(rchallenge_len, inp);
+  len -= sizeof (u_char) + rchallenge_len;  /* now name field length */
+  if (len < 0) {
+    CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: rcvd short packet.\n"));
+    return;
+  }
+  rchallenge = inp;
+  INCPTR(rchallenge_len, inp);
+
+  if (len >= (int)sizeof(rhostname)) {
+    len = sizeof(rhostname) - 1;
+  }
+  BCOPY(inp, rhostname, len);
+  rhostname[len] = '\000';
+
+  CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: received name field '%s'\n",
+             rhostname));
+
+  /* Microsoft doesn't send their name back in the PPP packet */
+  if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rhostname[0] == 0)) {
+    strncpy(rhostname, ppp_settings.remote_name, sizeof(rhostname));
+    rhostname[sizeof(rhostname) - 1] = 0;
+    CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: using '%s' as remote name\n",
+               rhostname));
+  }
+
+  /* get secret for authenticating ourselves with the specified host */
+  if (!get_secret(cstate->unit, cstate->resp_name, rhostname,
+                  secret, &secret_len, 0)) {
+    secret_len = 0;    /* assume null secret if can't find one */
+    CHAPDEBUG(LOG_WARNING, ("No CHAP secret found for authenticating us to %s\n",
+               rhostname));
+  }
+
+  /* cancel response send timeout if necessary */
+  if (cstate->clientstate == CHAPCS_RESPONSE) {
+    UNTIMEOUT(ChapResponseTimeout, cstate);
+  }
+
+  cstate->resp_id = id;
+  cstate->resp_transmits = 0;
+
+  /*  generate MD based on negotiated type */
+  switch (cstate->resp_type) { 
+
+  case CHAP_DIGEST_MD5:
+    MD5Init(&mdContext);
+    MD5Update(&mdContext, &cstate->resp_id, 1);
+    MD5Update(&mdContext, (u_char*)secret, secret_len);
+    MD5Update(&mdContext, rchallenge, rchallenge_len);
+    MD5Final(hash, &mdContext);
+    BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE);
+    cstate->resp_length = MD5_SIGNATURE_SIZE;
+    break;
+  
+#if MSCHAP_SUPPORT
+  case CHAP_MICROSOFT:
+    ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);
+    break;
+#endif
+
+  default:
+    CHAPDEBUG(LOG_INFO, ("unknown digest type %d\n", cstate->resp_type));
+    return;
+  }
+
+  BZERO(secret, sizeof(secret));
+  ChapSendResponse(cstate);
+}
+
+
+/*
+ * ChapReceiveResponse - Receive and process response.
+ */
+static void
+ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len)
+{
+  u_char *remmd, remmd_len;
+  int secret_len, old_state;
+  int code;
+  char rhostname[256];
+  MD5_CTX mdContext;
+  char secret[MAXSECRETLEN];
+  u_char hash[MD5_SIGNATURE_SIZE];
+
+  CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: Rcvd id %d.\n", id));
+  
+  if (cstate->serverstate == CHAPSS_CLOSED ||
+      cstate->serverstate == CHAPSS_PENDING) {
+    CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: in state %d\n",
+    cstate->serverstate));
+    return;
+  }
+
+  if (id != cstate->chal_id) {
+    return;      /* doesn't match ID of last challenge */
+  }
+
+  /*
+  * If we have received a duplicate or bogus Response,
+  * we have to send the same answer (Success/Failure)
+  * as we did for the first Response we saw.
+  */
+  if (cstate->serverstate == CHAPSS_OPEN) {
+    ChapSendStatus(cstate, CHAP_SUCCESS);
+    return;
+  }
+  if (cstate->serverstate == CHAPSS_BADAUTH) {
+    ChapSendStatus(cstate, CHAP_FAILURE);
+    return;
+  }
+  
+  if (len < 2) {
+    CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: rcvd short packet.\n"));
+    return;
+  }
+  GETCHAR(remmd_len, inp); /* get length of MD */
+  remmd = inp;             /* get pointer to MD */
+  INCPTR(remmd_len, inp);
+  
+  len -= sizeof (u_char) + remmd_len;
+  if (len < 0) {
+    CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: rcvd short packet.\n"));
+    return;
+  }
+
+  UNTIMEOUT(ChapChallengeTimeout, cstate);
+  
+  if (len >= (int)sizeof(rhostname)) {
+    len = sizeof(rhostname) - 1;
+  }
+  BCOPY(inp, rhostname, len);
+  rhostname[len] = '\000';
+
+  CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: received name field: %s\n",
+             rhostname));
+
+  /*
+  * Get secret for authenticating them with us,
+  * do the hash ourselves, and compare the result.
+  */
+  code = CHAP_FAILURE;
+  if (!get_secret(cstate->unit, rhostname, cstate->chal_name,
+                  secret, &secret_len, 1)) {
+    CHAPDEBUG(LOG_WARNING, ("No CHAP secret found for authenticating %s\n",
+               rhostname));
+  } else {
+    /*  generate MD based on negotiated type */
+    switch (cstate->chal_type) {
+
+      case CHAP_DIGEST_MD5:    /* only MD5 is defined for now */
+        if (remmd_len != MD5_SIGNATURE_SIZE) {
+          break;      /* it's not even the right length */
+        }
+        MD5Init(&mdContext);
+        MD5Update(&mdContext, &cstate->chal_id, 1);
+        MD5Update(&mdContext, (u_char*)secret, secret_len);
+        MD5Update(&mdContext, cstate->challenge, cstate->chal_len);
+        MD5Final(hash, &mdContext); 
+        
+        /* compare local and remote MDs and send the appropriate status */
+        if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0) {
+          code = CHAP_SUCCESS;  /* they are the same! */
+        }
+        break;
+      
+      default:
+        CHAPDEBUG(LOG_INFO, ("unknown digest type %d\n", cstate->chal_type));
+    }
+  }
+  
+  BZERO(secret, sizeof(secret));
+  ChapSendStatus(cstate, code);
+
+  if (code == CHAP_SUCCESS) {
+    old_state = cstate->serverstate;
+    cstate->serverstate = CHAPSS_OPEN;
+    if (old_state == CHAPSS_INITIAL_CHAL) {
+      auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len);
+    }
+    if (cstate->chal_interval != 0) {
+      TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);
+    }
+  } else {
+    CHAPDEBUG(LOG_ERR, ("CHAP peer authentication failed\n"));
+    cstate->serverstate = CHAPSS_BADAUTH;
+    auth_peer_fail(cstate->unit, PPP_CHAP);
+  }
+}
+
+/*
+ * ChapReceiveSuccess - Receive Success
+ */
+static void
+ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len)
+{
+  LWIP_UNUSED_ARG(id);
+  LWIP_UNUSED_ARG(inp);
+
+  CHAPDEBUG(LOG_INFO, ("ChapReceiveSuccess: Rcvd id %d.\n", id));
+
+  if (cstate->clientstate == CHAPCS_OPEN) {
+    /* presumably an answer to a duplicate response */
+    return;
+  }
+
+  if (cstate->clientstate != CHAPCS_RESPONSE) {
+    /* don't know what this is */
+    CHAPDEBUG(LOG_INFO, ("ChapReceiveSuccess: in state %d\n",
+               cstate->clientstate));
+    return;
+  }
+  
+  UNTIMEOUT(ChapResponseTimeout, cstate);
+  
+  /*
+   * Print message.
+   */
+  if (len > 0) {
+    PRINTMSG(inp, len);
+  }
+
+  cstate->clientstate = CHAPCS_OPEN;
+
+  auth_withpeer_success(cstate->unit, PPP_CHAP);
+}
+
+
+/*
+ * ChapReceiveFailure - Receive failure.
+ */
+static void
+ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len)
+{
+  LWIP_UNUSED_ARG(id);
+  LWIP_UNUSED_ARG(inp);
+
+  CHAPDEBUG(LOG_INFO, ("ChapReceiveFailure: Rcvd id %d.\n", id));
+
+  if (cstate->clientstate != CHAPCS_RESPONSE) {
+    /* don't know what this is */
+    CHAPDEBUG(LOG_INFO, ("ChapReceiveFailure: in state %d\n",
+               cstate->clientstate));
+    return;
+  }
+
+  UNTIMEOUT(ChapResponseTimeout, cstate);
+
+  /*
+   * Print message.
+   */
+  if (len > 0) {
+    PRINTMSG(inp, len);
+  }
+
+  CHAPDEBUG(LOG_ERR, ("CHAP authentication failed\n"));
+  auth_withpeer_fail(cstate->unit, PPP_CHAP); /* lwip: just sets the PPP error code on this unit to PPPERR_AUTHFAIL */
+}
+
+
+/*
+ * ChapSendChallenge - Send an Authenticate challenge.
+ */
+static void
+ChapSendChallenge(chap_state *cstate)
+{
+  u_char *outp;
+  int chal_len, name_len;
+  int outlen;
+  
+  chal_len = cstate->chal_len;
+  name_len = (int)strlen(cstate->chal_name);
+  outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;
+  outp = outpacket_buf[cstate->unit];
+
+  MAKEHEADER(outp, PPP_CHAP);    /* paste in a CHAP header */
+
+  PUTCHAR(CHAP_CHALLENGE, outp);
+  PUTCHAR(cstate->chal_id, outp);
+  PUTSHORT(outlen, outp);
+
+  PUTCHAR(chal_len, outp);    /* put length of challenge */
+  BCOPY(cstate->challenge, outp, chal_len);
+  INCPTR(chal_len, outp);
+
+  BCOPY(cstate->chal_name, outp, name_len);  /* append hostname */
+  
+  pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
+
+  CHAPDEBUG(LOG_INFO, ("ChapSendChallenge: Sent id %d.\n", cstate->chal_id));
+  
+  TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime);
+  ++cstate->chal_transmits;
+}
+
+
+/*
+ * ChapSendStatus - Send a status response (ack or nak).
+ */
+static void
+ChapSendStatus(chap_state *cstate, int code)
+{
+  u_char *outp;
+  int outlen, msglen;
+  char msg[256]; /* @todo: this can be a char*, no strcpy needed */
+
+  if (code == CHAP_SUCCESS) {
+    strcpy(msg, "Welcome!");
+  } else {
+    strcpy(msg, "I don't like you.  Go 'way.");
+  }
+  msglen = (int)strlen(msg);
+
+  outlen = CHAP_HEADERLEN + msglen;
+  outp = outpacket_buf[cstate->unit];
+
+  MAKEHEADER(outp, PPP_CHAP);    /* paste in a header */
+  
+  PUTCHAR(code, outp);
+  PUTCHAR(cstate->chal_id, outp);
+  PUTSHORT(outlen, outp);
+  BCOPY(msg, outp, msglen);
+  pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
+
+  CHAPDEBUG(LOG_INFO, ("ChapSendStatus: Sent code %d, id %d.\n", code,
+             cstate->chal_id));
+}
+
+/*
+ * ChapGenChallenge is used to generate a pseudo-random challenge string of
+ * a pseudo-random length between min_len and max_len.  The challenge
+ * string and its length are stored in *cstate, and various other fields of
+ * *cstate are initialized.
+ */
+
+static void
+ChapGenChallenge(chap_state *cstate)
+{
+  int chal_len;
+  u_char *ptr = cstate->challenge;
+  int i;
+
+  /* pick a random challenge length between MIN_CHALLENGE_LENGTH and 
+     MAX_CHALLENGE_LENGTH */  
+  chal_len = (unsigned)
+        ((((magic() >> 16) *
+              (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) >> 16)
+           + MIN_CHALLENGE_LENGTH);
+  LWIP_ASSERT("chal_len <= 0xff", chal_len <= 0xffff);
+  cstate->chal_len = (u_char)chal_len;
+  cstate->chal_id = ++cstate->id;
+  cstate->chal_transmits = 0;
+
+  /* generate a random string */
+  for (i = 0; i < chal_len; i++ ) {
+    *ptr++ = (char) (magic() & 0xff);
+  }
+}
+
+/*
+ * ChapSendResponse - send a response packet with values as specified
+ * in *cstate.
+ */
+/* ARGSUSED */
+static void
+ChapSendResponse(chap_state *cstate)
+{
+  u_char *outp;
+  int outlen, md_len, name_len;
+
+  md_len = cstate->resp_length;
+  name_len = (int)strlen(cstate->resp_name);
+  outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;
+  outp = outpacket_buf[cstate->unit];
+
+  MAKEHEADER(outp, PPP_CHAP);
+  
+  PUTCHAR(CHAP_RESPONSE, outp);  /* we are a response */
+  PUTCHAR(cstate->resp_id, outp);  /* copy id from challenge packet */
+  PUTSHORT(outlen, outp);      /* packet length */
+  
+  PUTCHAR(md_len, outp);      /* length of MD */
+  BCOPY(cstate->response, outp, md_len);    /* copy MD to buffer */
+  INCPTR(md_len, outp);
+
+  BCOPY(cstate->resp_name, outp, name_len);  /* append our name */
+
+  /* send the packet */
+  pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
+
+  cstate->clientstate = CHAPCS_RESPONSE;
+  TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime);
+  ++cstate->resp_transmits;
+}
+
+#if PPP_ADDITIONAL_CALLBACKS
+static char *ChapCodenames[] = {
+  "Challenge", "Response", "Success", "Failure"
+};
+/*
+ * ChapPrintPkt - print the contents of a CHAP packet.
+ */
+static int
+ChapPrintPkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg)
+{
+  int code, id, len;
+  int clen, nlen;
+  u_char x;
+
+  if (plen < CHAP_HEADERLEN) {
+    return 0;
+  }
+  GETCHAR(code, p);
+  GETCHAR(id, p);
+  GETSHORT(len, p);
+  if (len < CHAP_HEADERLEN || len > plen) {
+    return 0;
+  }
+
+  if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *)) {
+    printer(arg, " %s", ChapCodenames[code-1]);
+  } else {
+    printer(arg, " code=0x%x", code);
+  }
+  printer(arg, " id=0x%x", id);
+  len -= CHAP_HEADERLEN;
+  switch (code) {
+    case CHAP_CHALLENGE:
+    case CHAP_RESPONSE:
+      if (len < 1) {
+        break;
+      }
+      clen = p[0];
+      if (len < clen + 1) {
+        break;
+      }
+      ++p;
+      nlen = len - clen - 1;
+      printer(arg, " <");
+      for (; clen > 0; --clen) {
+        GETCHAR(x, p);
+        printer(arg, "%.2x", x);
+      }
+      printer(arg, ">, name = %.*Z", nlen, p);
+      break;
+    case CHAP_FAILURE:
+    case CHAP_SUCCESS:
+      printer(arg, " %.*Z", len, p);
+      break;
+    default:
+      for (clen = len; clen > 0; --clen) {
+        GETCHAR(x, p);
+        printer(arg, " %.2x", x);
+      }
+  }
+
+  return len + CHAP_HEADERLEN;
+}
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+
+#endif /* CHAP_SUPPORT */
+
+#endif /* PPP_SUPPORT */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/chap.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/chap.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/chap.h	(revision 164)
@@ -0,0 +1,150 @@
+/*****************************************************************************
+* chap.h - Network Challenge Handshake Authentication Protocol header file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1998 Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-12-03 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Original built from BSD network code.
+******************************************************************************/
+/*
+ * chap.h - Challenge Handshake Authentication Protocol definitions.
+ *
+ * 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) 1991 Gregory M. Christy
+ * 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 author.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef CHAP_H
+#define CHAP_H
+
+/* Code + ID + length */
+#define CHAP_HEADERLEN 4
+
+/*
+ * CHAP codes.
+ */
+
+#define CHAP_DIGEST_MD5      5    /* use MD5 algorithm */
+#define MD5_SIGNATURE_SIZE   16   /* 16 bytes in a MD5 message digest */
+#define CHAP_MICROSOFT       0x80 /* use Microsoft-compatible alg. */
+#define MS_CHAP_RESPONSE_LEN 49   /* Response length for MS-CHAP */
+
+#define CHAP_CHALLENGE       1
+#define CHAP_RESPONSE        2
+#define CHAP_SUCCESS         3
+#define CHAP_FAILURE         4
+
+/*
+ *  Challenge lengths (for challenges we send) and other limits.
+ */
+#define MIN_CHALLENGE_LENGTH 32
+#define MAX_CHALLENGE_LENGTH 64
+#define MAX_RESPONSE_LENGTH  64 /* sufficient for MD5 or MS-CHAP */
+
+/*
+ * Each interface is described by a chap structure.
+ */
+
+typedef struct chap_state {
+  int unit;                               /* Interface unit number */
+  int clientstate;                        /* Client state */
+  int serverstate;                        /* Server state */
+  u_char challenge[MAX_CHALLENGE_LENGTH]; /* last challenge string sent */
+  u_char chal_len;                        /* challenge length */
+  u_char chal_id;                         /* ID of last challenge */
+  u_char chal_type;                       /* hash algorithm for challenges */
+  u_char id;                              /* Current id */
+  char *chal_name;                        /* Our name to use with challenge */
+  int chal_interval;                      /* Time until we challenge peer again */
+  int timeouttime;                        /* Timeout time in seconds */
+  int max_transmits;                      /* Maximum # of challenge transmissions */
+  int chal_transmits;                     /* Number of transmissions of challenge */
+  int resp_transmits;                     /* Number of transmissions of response */
+  u_char response[MAX_RESPONSE_LENGTH];   /* Response to send */
+  u_char resp_length;                     /* length of response */
+  u_char resp_id;                         /* ID for response messages */
+  u_char resp_type;                       /* hash algorithm for responses */
+  char *resp_name;                        /* Our name to send with response */
+} chap_state;
+
+
+/*
+ * Client (peer) states.
+ */
+#define CHAPCS_INITIAL       0 /* Lower layer down, not opened */
+#define CHAPCS_CLOSED        1 /* Lower layer up, not opened */
+#define CHAPCS_PENDING       2 /* Auth us to peer when lower up */
+#define CHAPCS_LISTEN        3 /* Listening for a challenge */
+#define CHAPCS_RESPONSE      4 /* Sent response, waiting for status */
+#define CHAPCS_OPEN          5 /* We've received Success */
+
+/*
+ * Server (authenticator) states.
+ */
+#define CHAPSS_INITIAL       0 /* Lower layer down, not opened */
+#define CHAPSS_CLOSED        1 /* Lower layer up, not opened */
+#define CHAPSS_PENDING       2 /* Auth peer when lower up */
+#define CHAPSS_INITIAL_CHAL  3 /* We've sent the first challenge */
+#define CHAPSS_OPEN          4 /* We've sent a Success msg */
+#define CHAPSS_RECHALLENGE   5 /* We've sent another challenge */
+#define CHAPSS_BADAUTH       6 /* We've sent a Failure msg */
+
+extern chap_state chap[];
+
+void ChapAuthWithPeer (int, char *, u_char);
+void ChapAuthPeer (int, char *, u_char);
+
+extern struct protent chap_protent;
+
+#endif /* CHAP_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/chpms.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/chpms.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/chpms.c	(revision 164)
@@ -0,0 +1,396 @@
+/*** WARNING - THIS CODE HAS NOT BEEN FINISHED! ***/
+/*** The original PPPD code is written in a way to require either the UNIX DES
+     encryption functions encrypt(3) and setkey(3) or the DES library libdes.
+     Since both is not included in lwIP, MSCHAP currently does not work! */
+/*****************************************************************************
+* chpms.c - Network MicroSoft Challenge Handshake Authentication Protocol program file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* Copyright (c) 1997 by Global Election Systems Inc.  All rights reserved.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Original based on BSD chap_ms.c.
+*****************************************************************************/
+/*
+ * chap_ms.c - Microsoft MS-CHAP compatible implementation.
+ *
+ * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
+ * http://www.strataware.com/
+ *
+ * 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 Eric Rosenquist.  The name of the author 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.
+ */
+
+/*
+ * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997
+ *
+ *   Implemented LANManager type password response to MS-CHAP challenges.
+ *   Now pppd provides both NT style and LANMan style blocks, and the
+ *   prefered is set by option "ms-lanman". Default is to use NT.
+ *   The hash text (StdText) was taken from Win95 RASAPI32.DLL.
+ *
+ *   You should also use DOMAIN\\USERNAME as described in README.MSCHAP80
+ */
+
+#define USE_CRYPT
+
+#include "lwip/opt.h"
+
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#if MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "ppp_impl.h"
+#include "pppdebug.h"
+
+#include "md4.h"
+#ifndef USE_CRYPT
+#include "des.h"
+#endif
+#include "chap.h"
+#include "chpms.h"
+
+#include <string.h>
+
+
+/*************************/
+/*** LOCAL DEFINITIONS ***/
+/*************************/
+
+
+/************************/
+/*** LOCAL DATA TYPES ***/
+/************************/
+typedef struct {
+    u_char LANManResp[24];
+    u_char NTResp[24];
+    u_char UseNT; /* If 1, ignore the LANMan response field */
+} MS_ChapResponse;
+/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse),
+   in case this struct gets padded. */
+
+
+
+/***********************************/
+/*** LOCAL FUNCTION DECLARATIONS ***/
+/***********************************/
+
+/* XXX Don't know what to do with these. */
+extern void setkey(const char *);
+extern void encrypt(char *, int);
+
+static void DesEncrypt (u_char *, u_char *, u_char *);
+static void MakeKey (u_char *, u_char *);
+
+#ifdef USE_CRYPT
+static void Expand (u_char *, u_char *);
+static void Collapse (u_char *, u_char *);
+#endif
+
+static void ChallengeResponse(
+  u_char *challenge, /* IN   8 octets */
+  u_char *pwHash,    /* IN  16 octets */
+  u_char *response   /* OUT 24 octets */
+);
+static void ChapMS_NT(
+  char *rchallenge,
+  int rchallenge_len,
+  char *secret,
+  int secret_len,
+  MS_ChapResponse *response
+);
+static u_char Get7Bits(
+  u_char *input,
+  int startBit
+);
+
+static void
+ChallengeResponse( u_char *challenge, /* IN   8 octets */
+                   u_char *pwHash,    /* IN  16 octets */
+                   u_char *response   /* OUT 24 octets */)
+{
+  u_char    ZPasswordHash[21];
+
+  BZERO(ZPasswordHash, sizeof(ZPasswordHash));
+  BCOPY(pwHash, ZPasswordHash, 16);
+
+#if 0
+  log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash", LOG_DEBUG);
+#endif
+
+  DesEncrypt(challenge, ZPasswordHash +  0, response + 0);
+  DesEncrypt(challenge, ZPasswordHash +  7, response + 8);
+  DesEncrypt(challenge, ZPasswordHash + 14, response + 16);
+
+#if 0
+  log_packet(response, 24, "ChallengeResponse - response", LOG_DEBUG);
+#endif
+}
+
+
+#ifdef USE_CRYPT
+static void
+DesEncrypt( u_char *clear, /* IN  8 octets */
+            u_char *key,   /* IN  7 octets */
+            u_char *cipher /* OUT 8 octets */)
+{
+  u_char des_key[8];
+  u_char crypt_key[66];
+  u_char des_input[66];
+
+  MakeKey(key, des_key);
+
+  Expand(des_key, crypt_key);
+  setkey((char*)crypt_key);
+
+#if 0
+  CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",
+             clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
+#endif
+
+  Expand(clear, des_input);
+  encrypt((char*)des_input, 0);
+  Collapse(des_input, cipher);
+
+#if 0
+  CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
+             cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
+#endif
+}
+
+#else /* USE_CRYPT */
+
+static void
+DesEncrypt( u_char *clear, /* IN  8 octets */
+            u_char *key,   /* IN  7 octets */
+            u_char *cipher /* OUT 8 octets */)
+{
+  des_cblock    des_key;
+  des_key_schedule  key_schedule;
+
+  MakeKey(key, des_key);
+
+  des_set_key(&des_key, key_schedule);
+
+#if 0
+  CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",
+             clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
+#endif
+
+  des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
+
+#if 0
+  CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
+             cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
+#endif
+}
+
+#endif /* USE_CRYPT */
+
+
+static u_char
+Get7Bits( u_char *input, int startBit)
+{
+  register unsigned int  word;
+
+  word  = (unsigned)input[startBit / 8] << 8;
+  word |= (unsigned)input[startBit / 8 + 1];
+
+  word >>= 15 - (startBit % 8 + 7);
+
+  return word & 0xFE;
+}
+
+#ifdef USE_CRYPT
+
+/* in == 8-byte string (expanded version of the 56-bit key)
+ * out == 64-byte string where each byte is either 1 or 0
+ * Note that the low-order "bit" is always ignored by by setkey()
+ */
+static void
+Expand(u_char *in, u_char *out)
+{
+  int j, c;
+  int i;
+
+  for(i = 0; i < 64; in++){
+    c = *in;
+    for(j = 7; j >= 0; j--) {
+      *out++ = (c >> j) & 01;
+    }
+    i += 8;
+  }
+}
+
+/* The inverse of Expand
+ */
+static void
+Collapse(u_char *in, u_char *out)
+{
+  int j;
+  int i;
+  unsigned int c;
+
+  for (i = 0; i < 64; i += 8, out++) {
+    c = 0;
+    for (j = 7; j >= 0; j--, in++) {
+      c |= *in << j;
+    }
+    *out = c & 0xff;
+  }
+}
+#endif
+
+static void
+MakeKey( u_char *key,    /* IN  56 bit DES key missing parity bits */
+         u_char *des_key /* OUT 64 bit DES key with parity bits added */)
+{
+  des_key[0] = Get7Bits(key,  0);
+  des_key[1] = Get7Bits(key,  7);
+  des_key[2] = Get7Bits(key, 14);
+  des_key[3] = Get7Bits(key, 21);
+  des_key[4] = Get7Bits(key, 28);
+  des_key[5] = Get7Bits(key, 35);
+  des_key[6] = Get7Bits(key, 42);
+  des_key[7] = Get7Bits(key, 49);
+  
+#ifndef USE_CRYPT
+  des_set_odd_parity((des_cblock *)des_key);
+#endif
+  
+#if 0
+  CHAPDEBUG(LOG_INFO, ("MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X\n",
+             key[0], key[1], key[2], key[3], key[4], key[5], key[6]));
+  CHAPDEBUG(LOG_INFO, ("MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
+             des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7]));
+#endif
+}
+
+static void
+ChapMS_NT( char *rchallenge,
+           int rchallenge_len,
+           char *secret,
+           int secret_len,
+           MS_ChapResponse *response)
+{
+  int      i;
+  MDstruct  md4Context;
+  u_char    unicodePassword[MAX_NT_PASSWORD * 2];
+  static int  low_byte_first = -1;
+
+  LWIP_UNUSED_ARG(rchallenge_len);
+
+  /* Initialize the Unicode version of the secret (== password). */
+  /* This implicitly supports 8-bit ISO8859/1 characters. */
+  BZERO(unicodePassword, sizeof(unicodePassword));
+  for (i = 0; i < secret_len; i++) {
+    unicodePassword[i * 2] = (u_char)secret[i];
+  }
+  MDbegin(&md4Context);
+  MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8);  /* Unicode is 2 bytes/char, *8 for bit count */
+
+  if (low_byte_first == -1) {
+    low_byte_first = (PP_HTONS((unsigned short int)1) != 1);
+  }
+  if (low_byte_first == 0) {
+    /* @todo: arg type - u_long* or u_int* ? */
+    MDreverse((unsigned int*)&md4Context);  /*  sfb 961105 */
+  }
+
+  MDupdate(&md4Context, NULL, 0);  /* Tell MD4 we're done */
+
+  ChallengeResponse((u_char*)rchallenge, (u_char*)md4Context.buffer, response->NTResp);
+}
+
+#ifdef MSLANMAN
+static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
+
+static void
+ChapMS_LANMan( char *rchallenge,
+               int rchallenge_len,
+               char *secret,
+               int secret_len,
+               MS_ChapResponse  *response)
+{
+  int      i;
+  u_char    UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */
+  u_char    PasswordHash[16];
+  
+  /* LANMan password is case insensitive */
+  BZERO(UcasePassword, sizeof(UcasePassword));
+  for (i = 0; i < secret_len; i++) {
+    UcasePassword[i] = (u_char)toupper(secret[i]);
+  }
+  DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 );
+  DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 );
+  ChallengeResponse(rchallenge, PasswordHash, response->LANManResp);
+}
+#endif
+
+void
+ChapMS( chap_state *cstate, char *rchallenge, int rchallenge_len, char *secret, int secret_len)
+{
+  MS_ChapResponse response;
+#ifdef MSLANMAN
+  extern int ms_lanman;
+#endif
+
+#if 0
+  CHAPDEBUG(LOG_INFO, ("ChapMS: secret is '%.*s'\n", secret_len, secret));
+#endif
+  BZERO(&response, sizeof(response));
+
+  /* Calculate both always */
+  ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response);
+
+#ifdef MSLANMAN
+  ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response);
+
+  /* prefered method is set by option  */
+  response.UseNT = !ms_lanman;
+#else
+  response.UseNT = 1;
+#endif
+
+  BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);
+  cstate->resp_length = MS_CHAP_RESPONSE_LEN;
+}
+
+#endif /* MSCHAP_SUPPORT */
+
+#endif /* PPP_SUPPORT */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/chpms.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/chpms.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/chpms.h	(revision 164)
@@ -0,0 +1,64 @@
+/*****************************************************************************
+* chpms.h - Network Microsoft Challenge Handshake Protocol header file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1998 Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 98-01-30 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Original built from BSD network code.
+******************************************************************************/
+/*
+ * chap.h - Challenge Handshake Authentication Protocol definitions.
+ *
+ * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
+ * http://www.strataware.com/
+ *
+ * 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 Eric Rosenquist.  The name of the author 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.
+ *
+ * $Id$
+ */
+
+#ifndef CHPMS_H
+#define CHPMS_H
+
+#define MAX_NT_PASSWORD 256 /* Maximum number of (Unicode) chars in an NT password */
+
+void ChapMS (chap_state *, char *, int, char *, int);
+
+#endif /* CHPMS_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/fsm.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/fsm.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/fsm.c	(revision 164)
@@ -0,0 +1,890 @@
+/*****************************************************************************
+* fsm.c - Network Control Protocol Finite State Machine program file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 by Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Original based on BSD fsm.c.
+*****************************************************************************/
+/*
+ * 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.
+ */
+
+/*
+ * TODO:
+ * Randomize fsm id on link/init.
+ * Deal with variable outgoing MTU.
+ */
+
+#include "lwip/opt.h"
+
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "ppp_impl.h"
+#include "pppdebug.h"
+
+#include "fsm.h"
+
+#include <string.h>
+
+#if PPP_DEBUG
+static const char *ppperr_strerr[] = {
+           "LS_INITIAL",  /* LS_INITIAL  0 */
+           "LS_STARTING", /* LS_STARTING 1 */
+           "LS_CLOSED",   /* LS_CLOSED   2 */
+           "LS_STOPPED",  /* LS_STOPPED  3 */
+           "LS_CLOSING",  /* LS_CLOSING  4 */
+           "LS_STOPPING", /* LS_STOPPING 5 */
+           "LS_REQSENT",  /* LS_REQSENT  6 */
+           "LS_ACKRCVD",  /* LS_ACKRCVD  7 */
+           "LS_ACKSENT",  /* LS_ACKSENT  8 */
+           "LS_OPENED"    /* LS_OPENED   9 */
+};
+#endif /* PPP_DEBUG */
+
+static void fsm_timeout (void *);
+static void fsm_rconfreq (fsm *, u_char, u_char *, int);
+static void fsm_rconfack (fsm *, int, u_char *, int);
+static void fsm_rconfnakrej (fsm *, int, int, u_char *, int);
+static void fsm_rtermreq (fsm *, int, u_char *, int);
+static void fsm_rtermack (fsm *);
+static void fsm_rcoderej (fsm *, u_char *, int);
+static void fsm_sconfreq (fsm *, int);
+
+#define PROTO_NAME(f) ((f)->callbacks->proto_name)
+
+int peer_mru[NUM_PPP];
+
+
+/*
+ * fsm_init - Initialize fsm.
+ *
+ * Initialize fsm state.
+ */
+void
+fsm_init(fsm *f)
+{
+  f->state = LS_INITIAL;
+  f->flags = 0;
+  f->id = 0;        /* XXX Start with random id? */
+  f->timeouttime = FSM_DEFTIMEOUT;
+  f->maxconfreqtransmits = FSM_DEFMAXCONFREQS;
+  f->maxtermtransmits = FSM_DEFMAXTERMREQS;
+  f->maxnakloops = FSM_DEFMAXNAKLOOPS;
+  f->term_reason_len = 0;
+}
+
+
+/*
+ * fsm_lowerup - The lower layer is up.
+ */
+void
+fsm_lowerup(fsm *f)
+{
+  int oldState = f->state;
+
+  LWIP_UNUSED_ARG(oldState);
+
+  switch( f->state ) {
+    case LS_INITIAL:
+      f->state = LS_CLOSED;
+      break;
+
+    case LS_STARTING:
+      if( f->flags & OPT_SILENT ) {
+        f->state = LS_STOPPED;
+      } else {
+        /* Send an initial configure-request */
+        fsm_sconfreq(f, 0);
+        f->state = LS_REQSENT;
+      }
+    break;
+
+    default:
+      FSMDEBUG(LOG_INFO, ("%s: Up event in state %d (%s)!\n",
+          PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
+  }
+
+  FSMDEBUG(LOG_INFO, ("%s: lowerup state %d (%s) -> %d (%s)\n",
+      PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
+}
+
+
+/*
+ * fsm_lowerdown - The lower layer is down.
+ *
+ * Cancel all timeouts and inform upper layers.
+ */
+void
+fsm_lowerdown(fsm *f)
+{
+  int oldState = f->state;
+
+  LWIP_UNUSED_ARG(oldState);
+
+  switch( f->state ) {
+    case LS_CLOSED:
+      f->state = LS_INITIAL;
+      break;
+
+    case LS_STOPPED:
+      f->state = LS_STARTING;
+      if( f->callbacks->starting ) {
+        (*f->callbacks->starting)(f);
+      }
+      break;
+
+    case LS_CLOSING:
+      f->state = LS_INITIAL;
+      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
+      break;
+
+    case LS_STOPPING:
+    case LS_REQSENT:
+    case LS_ACKRCVD:
+    case LS_ACKSENT:
+      f->state = LS_STARTING;
+      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
+      break;
+
+    case LS_OPENED:
+      if( f->callbacks->down ) {
+        (*f->callbacks->down)(f);
+      }
+      f->state = LS_STARTING;
+      break;
+
+    default:
+      FSMDEBUG(LOG_INFO, ("%s: Down event in state %d (%s)!\n",
+          PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
+  }
+
+  FSMDEBUG(LOG_INFO, ("%s: lowerdown state %d (%s) -> %d (%s)\n",
+      PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
+}
+
+
+/*
+ * fsm_open - Link is allowed to come up.
+ */
+void
+fsm_open(fsm *f)
+{
+  int oldState = f->state;
+
+  LWIP_UNUSED_ARG(oldState);
+
+  switch( f->state ) {
+    case LS_INITIAL:
+      f->state = LS_STARTING;
+      if( f->callbacks->starting ) {
+        (*f->callbacks->starting)(f);
+      }
+      break;
+
+    case LS_CLOSED:
+      if( f->flags & OPT_SILENT ) {
+        f->state = LS_STOPPED;
+      } else {
+        /* Send an initial configure-request */
+        fsm_sconfreq(f, 0);
+        f->state = LS_REQSENT;
+      }
+      break;
+  
+    case LS_CLOSING:
+      f->state = LS_STOPPING;
+      /* fall through */
+    case LS_STOPPED:
+    case LS_OPENED:
+      if( f->flags & OPT_RESTART ) {
+        fsm_lowerdown(f);
+        fsm_lowerup(f);
+      }
+      break;
+  }
+
+  FSMDEBUG(LOG_INFO, ("%s: open state %d (%s) -> %d (%s)\n",
+      PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
+}
+
+#if 0 /* backport pppd 2.4.4b1; */
+/*
+ * terminate_layer - Start process of shutting down the FSM
+ *
+ * Cancel any timeout running, notify upper layers we're done, and
+ * send a terminate-request message as configured.
+ */
+static void
+terminate_layer(fsm *f, int nextstate)
+{
+  /* @todo */
+}
+#endif
+
+/*
+ * fsm_close - Start closing connection.
+ *
+ * Cancel timeouts and either initiate close or possibly go directly to
+ * the LS_CLOSED state.
+ */
+void
+fsm_close(fsm *f, char *reason)
+{
+  int oldState = f->state;
+
+  LWIP_UNUSED_ARG(oldState);
+
+  f->term_reason = reason;
+  f->term_reason_len = (reason == NULL ? 0 : (int)strlen(reason));
+  switch( f->state ) {
+    case LS_STARTING:
+      f->state = LS_INITIAL;
+      break;
+    case LS_STOPPED:
+      f->state = LS_CLOSED;
+      break;
+    case LS_STOPPING:
+      f->state = LS_CLOSING;
+      break;
+
+    case LS_REQSENT:
+    case LS_ACKRCVD:
+    case LS_ACKSENT:
+    case LS_OPENED:
+      if( f->state != LS_OPENED ) {
+        UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
+      } else if( f->callbacks->down ) {
+        (*f->callbacks->down)(f);  /* Inform upper layers we're down */
+      }
+      /* Init restart counter, send Terminate-Request */
+      f->retransmits = f->maxtermtransmits;
+      fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
+            (u_char *) f->term_reason, f->term_reason_len);
+      TIMEOUT(fsm_timeout, f, f->timeouttime);
+      --f->retransmits;
+
+      f->state = LS_CLOSING;
+      break;
+  }
+
+  FSMDEBUG(LOG_INFO, ("%s: close reason=%s state %d (%s) -> %d (%s)\n",
+      PROTO_NAME(f), reason, oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
+}
+
+
+/*
+ * fsm_timeout - Timeout expired.
+ */
+static void
+fsm_timeout(void *arg)
+{
+  fsm *f = (fsm *) arg;
+
+  switch (f->state) {
+    case LS_CLOSING:
+    case LS_STOPPING:
+      if( f->retransmits <= 0 ) {
+        FSMDEBUG(LOG_WARNING, ("%s: timeout sending Terminate-Request state=%d (%s)\n",
+             PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
+        /*
+         * We've waited for an ack long enough.  Peer probably heard us.
+         */
+        f->state = (f->state == LS_CLOSING)? LS_CLOSED: LS_STOPPED;
+        if( f->callbacks->finished ) {
+          (*f->callbacks->finished)(f);
+        }
+      } else {
+        FSMDEBUG(LOG_WARNING, ("%s: timeout resending Terminate-Requests state=%d (%s)\n",
+             PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
+        /* Send Terminate-Request */
+        fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
+            (u_char *) f->term_reason, f->term_reason_len);
+        TIMEOUT(fsm_timeout, f, f->timeouttime);
+        --f->retransmits;
+      }
+      break;
+
+    case LS_REQSENT:
+    case LS_ACKRCVD:
+    case LS_ACKSENT:
+      if (f->retransmits <= 0) {
+        FSMDEBUG(LOG_WARNING, ("%s: timeout sending Config-Requests state=%d (%s)\n",
+         PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
+        f->state = LS_STOPPED;
+        if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) {
+          (*f->callbacks->finished)(f);
+        }
+      } else {
+        FSMDEBUG(LOG_WARNING, ("%s: timeout resending Config-Request state=%d (%s)\n",
+         PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
+        /* Retransmit the configure-request */
+        if (f->callbacks->retransmit) {
+          (*f->callbacks->retransmit)(f);
+        }
+        fsm_sconfreq(f, 1);    /* Re-send Configure-Request */
+        if( f->state == LS_ACKRCVD ) {
+          f->state = LS_REQSENT;
+        }
+      }
+      break;
+
+    default:
+      FSMDEBUG(LOG_INFO, ("%s: UNHANDLED timeout event in state %d (%s)!\n",
+          PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
+  }
+}
+
+
+/*
+ * fsm_input - Input packet.
+ */
+void
+fsm_input(fsm *f, u_char *inpacket, int l)
+{
+  u_char *inp = inpacket;
+  u_char code, id;
+  int len;
+
+  /*
+  * Parse header (code, id and length).
+  * If packet too short, drop it.
+  */
+  if (l < HEADERLEN) {
+    FSMDEBUG(LOG_WARNING, ("fsm_input(%x): Rcvd short header.\n",
+          f->protocol));
+    return;
+  }
+  GETCHAR(code, inp);
+  GETCHAR(id, inp);
+  GETSHORT(len, inp);
+  if (len < HEADERLEN) {
+    FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd illegal length.\n",
+        f->protocol));
+    return;
+  }
+  if (len > l) {
+    FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd short packet.\n",
+        f->protocol));
+    return;
+  }
+  len -= HEADERLEN;    /* subtract header length */
+
+  if( f->state == LS_INITIAL || f->state == LS_STARTING ) {
+    FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd packet in state %d (%s).\n",
+        f->protocol, f->state, ppperr_strerr[f->state]));
+    return;
+  }
+  FSMDEBUG(LOG_INFO, ("fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l));
+  /*
+   * Action depends on code.
+   */
+  switch (code) {
+    case CONFREQ:
+      fsm_rconfreq(f, id, inp, len);
+      break;
+    
+    case CONFACK:
+      fsm_rconfack(f, id, inp, len);
+      break;
+    
+    case CONFNAK:
+    case CONFREJ:
+      fsm_rconfnakrej(f, code, id, inp, len);
+      break;
+    
+    case TERMREQ:
+      fsm_rtermreq(f, id, inp, len);
+      break;
+    
+    case TERMACK:
+      fsm_rtermack(f);
+      break;
+    
+    case CODEREJ:
+      fsm_rcoderej(f, inp, len);
+      break;
+    
+    default:
+      FSMDEBUG(LOG_INFO, ("fsm_input(%s): default: \n", PROTO_NAME(f)));
+      if( !f->callbacks->extcode ||
+          !(*f->callbacks->extcode)(f, code, id, inp, len) ) {
+        fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);
+      }
+      break;
+  }
+}
+
+
+/*
+ * fsm_rconfreq - Receive Configure-Request.
+ */
+static void
+fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len)
+{
+  int code, reject_if_disagree;
+
+  FSMDEBUG(LOG_INFO, ("fsm_rconfreq(%s): Rcvd id %d state=%d (%s)\n", 
+        PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
+  switch( f->state ) {
+    case LS_CLOSED:
+      /* Go away, we're closed */
+      fsm_sdata(f, TERMACK, id, NULL, 0);
+      return;
+    case LS_CLOSING:
+    case LS_STOPPING:
+      return;
+
+    case LS_OPENED:
+      /* Go down and restart negotiation */
+      if( f->callbacks->down ) {
+        (*f->callbacks->down)(f);  /* Inform upper layers */
+      }
+      fsm_sconfreq(f, 0);    /* Send initial Configure-Request */
+      break;
+
+    case LS_STOPPED:
+      /* Negotiation started by our peer */
+      fsm_sconfreq(f, 0);    /* Send initial Configure-Request */
+      f->state = LS_REQSENT;
+      break;
+  }
+  
+  /*
+  * Pass the requested configuration options
+  * to protocol-specific code for checking.
+  */
+  if (f->callbacks->reqci) {    /* Check CI */
+    reject_if_disagree = (f->nakloops >= f->maxnakloops);
+    code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
+  } else if (len) {
+    code = CONFREJ;      /* Reject all CI */
+  } else {
+    code = CONFACK;
+  }
+  
+  /* send the Ack, Nak or Rej to the peer */
+  fsm_sdata(f, (u_char)code, id, inp, len);
+  
+  if (code == CONFACK) {
+    if (f->state == LS_ACKRCVD) {
+      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
+      f->state = LS_OPENED;
+      if (f->callbacks->up) {
+        (*f->callbacks->up)(f);  /* Inform upper layers */
+      }
+    } else {
+      f->state = LS_ACKSENT;
+    }
+    f->nakloops = 0;
+  } else {
+    /* we sent CONFACK or CONFREJ */
+    if (f->state != LS_ACKRCVD) {
+      f->state = LS_REQSENT;
+    }
+    if( code == CONFNAK ) {
+      ++f->nakloops;
+    }
+  }
+}
+
+
+/*
+ * fsm_rconfack - Receive Configure-Ack.
+ */
+static void
+fsm_rconfack(fsm *f, int id, u_char *inp, int len)
+{
+  FSMDEBUG(LOG_INFO, ("fsm_rconfack(%s): Rcvd id %d state=%d (%s)\n",
+        PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
+  
+  if (id != f->reqid || f->seen_ack) {   /* Expected id? */
+    return; /* Nope, toss... */
+  }
+  if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): (len == 0)) ) {
+    /* Ack is bad - ignore it */
+    FSMDEBUG(LOG_INFO, ("%s: received bad Ack (length %d)\n",
+          PROTO_NAME(f), len));
+    return;
+  }
+  f->seen_ack = 1;
+  
+  switch (f->state) {
+    case LS_CLOSED:
+    case LS_STOPPED:
+      fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
+      break;
+    
+    case LS_REQSENT:
+      f->state = LS_ACKRCVD;
+      f->retransmits = f->maxconfreqtransmits;
+      break;
+    
+    case LS_ACKRCVD:
+      /* Huh? an extra valid Ack? oh well... */
+      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
+      fsm_sconfreq(f, 0);
+      f->state = LS_REQSENT;
+      break;
+    
+    case LS_ACKSENT:
+      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
+      f->state = LS_OPENED;
+      f->retransmits = f->maxconfreqtransmits;
+      if (f->callbacks->up) {
+        (*f->callbacks->up)(f);  /* Inform upper layers */
+      }
+      break;
+    
+    case LS_OPENED:
+      /* Go down and restart negotiation */
+      if (f->callbacks->down) {
+        (*f->callbacks->down)(f);  /* Inform upper layers */
+      }
+      fsm_sconfreq(f, 0);    /* Send initial Configure-Request */
+      f->state = LS_REQSENT;
+      break;
+  }
+}
+
+
+/*
+ * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
+ */
+static void
+fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len)
+{
+  int (*proc) (fsm *, u_char *, int);
+  int ret;
+
+  FSMDEBUG(LOG_INFO, ("fsm_rconfnakrej(%s): Rcvd id %d state=%d (%s)\n",
+        PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
+
+  if (id != f->reqid || f->seen_ack) { /* Expected id? */
+    return;        /* Nope, toss... */
+  }
+  proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
+  if (!proc || !((ret = proc(f, inp, len)))) {
+    /* Nak/reject is bad - ignore it */
+    FSMDEBUG(LOG_INFO, ("%s: received bad %s (length %d)\n",
+          PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
+    return;
+  }
+  f->seen_ack = 1;
+
+  switch (f->state) {
+    case LS_CLOSED:
+    case LS_STOPPED:
+      fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
+      break;
+    
+    case LS_REQSENT:
+    case LS_ACKSENT:
+      /* They didn't agree to what we wanted - try another request */
+      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
+      if (ret < 0) {
+        f->state = LS_STOPPED;    /* kludge for stopping CCP */
+      } else {
+        fsm_sconfreq(f, 0);    /* Send Configure-Request */
+      }
+      break;
+    
+    case LS_ACKRCVD:
+      /* Got a Nak/reject when we had already had an Ack?? oh well... */
+      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
+      fsm_sconfreq(f, 0);
+      f->state = LS_REQSENT;
+      break;
+    
+    case LS_OPENED:
+      /* Go down and restart negotiation */
+      if (f->callbacks->down) {
+        (*f->callbacks->down)(f);  /* Inform upper layers */
+      }
+      fsm_sconfreq(f, 0);    /* Send initial Configure-Request */
+      f->state = LS_REQSENT;
+      break;
+  }
+}
+
+
+/*
+ * fsm_rtermreq - Receive Terminate-Req.
+ */
+static void
+fsm_rtermreq(fsm *f, int id, u_char *p, int len)
+{
+  LWIP_UNUSED_ARG(p);
+
+  FSMDEBUG(LOG_INFO, ("fsm_rtermreq(%s): Rcvd id %d state=%d (%s)\n",
+        PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
+
+  switch (f->state) {
+    case LS_ACKRCVD:
+    case LS_ACKSENT:
+      f->state = LS_REQSENT;    /* Start over but keep trying */
+      break;
+
+    case LS_OPENED:
+      if (len > 0) {
+        FSMDEBUG(LOG_INFO, ("%s terminated by peer (%p)\n", PROTO_NAME(f), p));
+      } else {
+        FSMDEBUG(LOG_INFO, ("%s terminated by peer\n", PROTO_NAME(f)));
+      }
+      if (f->callbacks->down) {
+        (*f->callbacks->down)(f);  /* Inform upper layers */
+      }
+      f->retransmits = 0;
+      f->state = LS_STOPPING;
+      TIMEOUT(fsm_timeout, f, f->timeouttime);
+      break;
+  }
+
+  fsm_sdata(f, TERMACK, (u_char)id, NULL, 0);
+}
+
+
+/*
+ * fsm_rtermack - Receive Terminate-Ack.
+ */
+static void
+fsm_rtermack(fsm *f)
+{
+  FSMDEBUG(LOG_INFO, ("fsm_rtermack(%s): state=%d (%s)\n", 
+        PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
+  
+  switch (f->state) {
+    case LS_CLOSING:
+      UNTIMEOUT(fsm_timeout, f);
+      f->state = LS_CLOSED;
+      if( f->callbacks->finished ) {
+        (*f->callbacks->finished)(f);
+      }
+      break;
+
+    case LS_STOPPING:
+      UNTIMEOUT(fsm_timeout, f);
+      f->state = LS_STOPPED;
+      if( f->callbacks->finished ) {
+        (*f->callbacks->finished)(f);
+      }
+      break;
+    
+    case LS_ACKRCVD:
+      f->state = LS_REQSENT;
+      break;
+    
+    case LS_OPENED:
+      if (f->callbacks->down) {
+        (*f->callbacks->down)(f);  /* Inform upper layers */
+      }
+      fsm_sconfreq(f, 0);
+      break;
+    default:
+      FSMDEBUG(LOG_INFO, ("fsm_rtermack(%s): UNHANDLED state=%d (%s)!!!\n", 
+                PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
+  }
+}
+
+
+/*
+ * fsm_rcoderej - Receive an Code-Reject.
+ */
+static void
+fsm_rcoderej(fsm *f, u_char *inp, int len)
+{
+  u_char code, id;
+  
+  FSMDEBUG(LOG_INFO, ("fsm_rcoderej(%s): state=%d (%s)\n", 
+        PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
+  
+  if (len < HEADERLEN) {
+    FSMDEBUG(LOG_INFO, ("fsm_rcoderej: Rcvd short Code-Reject packet!\n"));
+    return;
+  }
+  GETCHAR(code, inp);
+  GETCHAR(id, inp);
+  FSMDEBUG(LOG_WARNING, ("%s: Rcvd Code-Reject for code %d, id %d\n",
+        PROTO_NAME(f), code, id));
+  
+  if( f->state == LS_ACKRCVD ) {
+    f->state = LS_REQSENT;
+  }
+}
+
+
+/*
+ * fsm_protreject - Peer doesn't speak this protocol.
+ *
+ * Treat this as a catastrophic error (RXJ-).
+ */
+void
+fsm_protreject(fsm *f)
+{
+  switch( f->state ) {
+    case LS_CLOSING:
+      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
+      /* fall through */
+    case LS_CLOSED:
+      f->state = LS_CLOSED;
+      if( f->callbacks->finished ) {
+        (*f->callbacks->finished)(f);
+      }
+      break;
+
+    case LS_STOPPING:
+    case LS_REQSENT:
+    case LS_ACKRCVD:
+    case LS_ACKSENT:
+      UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
+      /* fall through */
+    case LS_STOPPED:
+      f->state = LS_STOPPED;
+      if( f->callbacks->finished ) {
+        (*f->callbacks->finished)(f);
+      }
+      break;
+    
+    case LS_OPENED:
+      if( f->callbacks->down ) {
+        (*f->callbacks->down)(f);
+      }
+      /* Init restart counter, send Terminate-Request */
+      f->retransmits = f->maxtermtransmits;
+      fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
+            (u_char *) f->term_reason, f->term_reason_len);
+      TIMEOUT(fsm_timeout, f, f->timeouttime);
+      --f->retransmits;
+
+      f->state = LS_STOPPING;
+      break;
+    
+    default:
+      FSMDEBUG(LOG_INFO, ("%s: Protocol-reject event in state %d (%s)!\n",
+            PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
+    }
+}
+
+
+/*
+ * fsm_sconfreq - Send a Configure-Request.
+ */
+static void
+fsm_sconfreq(fsm *f, int retransmit)
+{
+  u_char *outp;
+  int cilen;
+  
+  if( f->state != LS_REQSENT && f->state != LS_ACKRCVD && f->state != LS_ACKSENT ) {
+    /* Not currently negotiating - reset options */
+    if( f->callbacks->resetci ) {
+      (*f->callbacks->resetci)(f);
+    }
+    f->nakloops = 0;
+  }
+  
+  if( !retransmit ) {
+    /* New request - reset retransmission counter, use new ID */
+    f->retransmits = f->maxconfreqtransmits;
+    f->reqid = ++f->id;
+  }
+  
+  f->seen_ack = 0;
+  
+  /*
+   * Make up the request packet
+   */
+  outp = outpacket_buf[f->unit] + PPP_HDRLEN + HEADERLEN;
+  if( f->callbacks->cilen && f->callbacks->addci ) {
+    cilen = (*f->callbacks->cilen)(f);
+    if( cilen > peer_mru[f->unit] - (int)HEADERLEN ) {
+      cilen = peer_mru[f->unit] - HEADERLEN;
+    }
+    if (f->callbacks->addci) {
+      (*f->callbacks->addci)(f, outp, &cilen);
+    }
+  } else {
+    cilen = 0;
+  }
+
+  /* send the request to our peer */
+  fsm_sdata(f, CONFREQ, f->reqid, outp, cilen);
+  
+  /* start the retransmit timer */
+  --f->retransmits;
+  TIMEOUT(fsm_timeout, f, f->timeouttime);
+  
+  FSMDEBUG(LOG_INFO, ("%s: sending Configure-Request, id %d\n",
+        PROTO_NAME(f), f->reqid));
+}
+
+
+/*
+ * fsm_sdata - Send some data.
+ *
+ * Used for all packets sent to our peer by this module.
+ */
+void
+fsm_sdata( fsm *f, u_char code, u_char id, u_char *data, int datalen)
+{
+  u_char *outp;
+  int outlen;
+
+  /* Adjust length to be smaller than MTU */
+  outp = outpacket_buf[f->unit];
+  if (datalen > peer_mru[f->unit] - (int)HEADERLEN) {
+    datalen = peer_mru[f->unit] - HEADERLEN;
+  }
+  if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) {
+    BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);
+  }
+  outlen = datalen + HEADERLEN;
+  MAKEHEADER(outp, f->protocol);
+  PUTCHAR(code, outp);
+  PUTCHAR(id, outp);
+  PUTSHORT(outlen, outp);
+  pppWrite(f->unit, outpacket_buf[f->unit], outlen + PPP_HDRLEN);
+  FSMDEBUG(LOG_INFO, ("fsm_sdata(%s): Sent code %d,%d,%d.\n",
+        PROTO_NAME(f), code, id, outlen));
+}
+
+#endif /* PPP_SUPPORT */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/fsm.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/fsm.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/fsm.h	(revision 164)
@@ -0,0 +1,157 @@
+/*****************************************************************************
+* fsm.h - Network Control Protocol Finite State Machine header file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* Copyright (c) 1997 Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
+*   Original based on BSD code.
+*****************************************************************************/
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef FSM_H
+#define FSM_H
+
+/*
+ * LCP Packet header = Code, id, length.
+ */
+#define HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))
+
+
+/*
+ *  CP (LCP, IPCP, etc.) codes.
+ */
+#define CONFREQ     1 /* Configuration Request */
+#define CONFACK     2 /* Configuration Ack */
+#define CONFNAK     3 /* Configuration Nak */
+#define CONFREJ     4 /* Configuration Reject */
+#define TERMREQ     5 /* Termination Request */
+#define TERMACK     6 /* Termination Ack */
+#define CODEREJ     7 /* Code Reject */
+
+
+/*
+ * Each FSM is described by an fsm structure and fsm callbacks.
+ */
+typedef struct fsm {
+  int unit;                        /* Interface unit number */
+  u_short protocol;                /* Data Link Layer Protocol field value */
+  int state;                       /* State */
+  int flags;                       /* Contains option bits */
+  u_char id;                       /* Current id */
+  u_char reqid;                    /* Current request id */
+  u_char seen_ack;                 /* Have received valid Ack/Nak/Rej to Req */
+  int timeouttime;                 /* Timeout time in milliseconds */
+  int maxconfreqtransmits;         /* Maximum Configure-Request transmissions */
+  int retransmits;                 /* Number of retransmissions left */
+  int maxtermtransmits;            /* Maximum Terminate-Request transmissions */
+  int nakloops;                    /* Number of nak loops since last ack */
+  int maxnakloops;                 /* Maximum number of nak loops tolerated */
+  struct fsm_callbacks* callbacks; /* Callback routines */
+  char* term_reason;               /* Reason for closing protocol */
+  int term_reason_len;             /* Length of term_reason */
+} fsm;
+
+
+typedef struct fsm_callbacks {
+  void (*resetci)(fsm*);                            /* Reset our Configuration Information */
+  int  (*cilen)(fsm*);                              /* Length of our Configuration Information */
+  void (*addci)(fsm*, u_char*, int*);               /* Add our Configuration Information */
+  int  (*ackci)(fsm*, u_char*, int);                /* ACK our Configuration Information */
+  int  (*nakci)(fsm*, u_char*, int);                /* NAK our Configuration Information */
+  int  (*rejci)(fsm*, u_char*, int);                /* Reject our Configuration Information */
+  int  (*reqci)(fsm*, u_char*, int*, int);          /* Request peer's Configuration Information */
+  void (*up)(fsm*);                                 /* Called when fsm reaches LS_OPENED state */
+  void (*down)(fsm*);                               /* Called when fsm leaves LS_OPENED state */
+  void (*starting)(fsm*);                           /* Called when we want the lower layer */
+  void (*finished)(fsm*);                           /* Called when we don't want the lower layer */
+  void (*protreject)(int);                          /* Called when Protocol-Reject received */
+  void (*retransmit)(fsm*);                         /* Retransmission is necessary */
+  int  (*extcode)(fsm*, int, u_char, u_char*, int); /* Called when unknown code received */
+  char *proto_name;                                 /* String name for protocol (for messages) */
+} fsm_callbacks;
+
+
+/*
+ * Link states.
+ */
+#define LS_INITIAL  0 /* Down, hasn't been opened */
+#define LS_STARTING 1 /* Down, been opened */
+#define LS_CLOSED   2 /* Up, hasn't been opened */
+#define LS_STOPPED  3 /* Open, waiting for down event */
+#define LS_CLOSING  4 /* Terminating the connection, not open */
+#define LS_STOPPING 5 /* Terminating, but open */
+#define LS_REQSENT  6 /* We've sent a Config Request */
+#define LS_ACKRCVD  7 /* We've received a Config Ack */
+#define LS_ACKSENT  8 /* We've sent a Config Ack */
+#define LS_OPENED   9 /* Connection available */
+
+/*
+ * Flags - indicate options controlling FSM operation
+ */
+#define OPT_PASSIVE 1 /* Don't die if we don't get a response */
+#define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */
+#define OPT_SILENT  4 /* Wait for peer to speak first */
+
+
+/*
+ * Prototypes
+ */
+void fsm_init (fsm*);
+void fsm_lowerup (fsm*);
+void fsm_lowerdown (fsm*);
+void fsm_open (fsm*);
+void fsm_close (fsm*, char*);
+void fsm_input (fsm*, u_char*, int);
+void fsm_protreject (fsm*);
+void fsm_sdata (fsm*, u_char, u_char, u_char*, int);
+
+
+/*
+ * Variables
+ */
+extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */
+
+#endif /* FSM_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ipcp.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ipcp.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ipcp.c	(revision 164)
@@ -0,0 +1,1411 @@
+/** In contrast to pppd 2.3.1, DNS support has been added, proxy-ARP and
+    dial-on-demand has been stripped. */
+/*****************************************************************************
+* ipcp.c - Network PPP IP Control Protocol program file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 by Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Original.
+*****************************************************************************/
+/*
+ * 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.
+ */
+
+#include "lwip/opt.h"
+
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "ppp_impl.h"
+#include "pppdebug.h"
+
+#include "auth.h"
+#include "fsm.h"
+#include "vj.h"
+#include "ipcp.h"
+
+#include "lwip/inet.h"
+
+#include <string.h>
+
+/* #define OLD_CI_ADDRS 1 */ /* Support deprecated address negotiation. */
+
+/* global vars */
+ipcp_options ipcp_wantoptions[NUM_PPP];  /* Options that we want to request */
+ipcp_options ipcp_gotoptions[NUM_PPP];   /* Options that peer ack'd */
+ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
+ipcp_options ipcp_hisoptions[NUM_PPP];   /* Options that we ack'd */
+
+/* local vars */
+static int default_route_set[NUM_PPP]; /* Have set up a default route */
+static int cis_received[NUM_PPP];      /* # Conf-Reqs received */
+
+
+/*
+ * Callbacks for fsm code.  (CI = Configuration Information)
+ */
+static void ipcp_resetci (fsm *);                     /* Reset our CI */
+static int  ipcp_cilen (fsm *);                       /* Return length of our CI */
+static void ipcp_addci (fsm *, u_char *, int *);      /* Add our CI */
+static int  ipcp_ackci (fsm *, u_char *, int);        /* Peer ack'd our CI */
+static int  ipcp_nakci (fsm *, u_char *, int);        /* Peer nak'd our CI */
+static int  ipcp_rejci (fsm *, u_char *, int);        /* Peer rej'd our CI */
+static int  ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */
+static void ipcp_up (fsm *);                          /* We're UP */
+static void ipcp_down (fsm *);                        /* We're DOWN */
+#if PPP_ADDITIONAL_CALLBACKS
+static void ipcp_script (fsm *, char *); /* Run an up/down script */
+#endif
+static void ipcp_finished (fsm *);                    /* Don't need lower layer */
+
+
+fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */
+
+
+static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
+  ipcp_resetci,  /* Reset our Configuration Information */
+  ipcp_cilen,    /* Length of our Configuration Information */
+  ipcp_addci,    /* Add our Configuration Information */
+  ipcp_ackci,    /* ACK our Configuration Information */
+  ipcp_nakci,    /* NAK our Configuration Information */
+  ipcp_rejci,    /* Reject our Configuration Information */
+  ipcp_reqci,    /* Request peer's Configuration Information */
+  ipcp_up,       /* Called when fsm reaches LS_OPENED state */
+  ipcp_down,     /* Called when fsm leaves LS_OPENED state */
+  NULL,          /* Called when we want the lower layer up */
+  ipcp_finished, /* Called when we want the lower layer down */
+  NULL,          /* Called when Protocol-Reject received */
+  NULL,          /* Retransmission is necessary */
+  NULL,          /* Called to handle protocol-specific codes */
+  "IPCP"         /* String name of protocol */
+};
+
+/*
+ * Protocol entry points from main code.
+ */
+static void ipcp_init (int);
+static void ipcp_open (int);
+static void ipcp_close (int, char *);
+static void ipcp_lowerup (int);
+static void ipcp_lowerdown (int);
+static void ipcp_input (int, u_char *, int);
+static void ipcp_protrej (int);
+
+
+struct protent ipcp_protent = {
+  PPP_IPCP,
+  ipcp_init,
+  ipcp_input,
+  ipcp_protrej,
+  ipcp_lowerup,
+  ipcp_lowerdown,
+  ipcp_open,
+  ipcp_close,
+#if PPP_ADDITIONAL_CALLBACKS
+  ipcp_printpkt,
+  NULL,
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+  1,
+  "IPCP",
+#if PPP_ADDITIONAL_CALLBACKS
+  ip_check_options,
+  NULL,
+  ip_active_pkt
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+};
+
+static void ipcp_clear_addrs (int);
+
+/*
+ * Lengths of configuration options.
+ */
+#define CILEN_VOID     2
+#define CILEN_COMPRESS 4  /* min length for compression protocol opt. */
+#define CILEN_VJ       6  /* length for RFC1332 Van-Jacobson opt. */
+#define CILEN_ADDR     6  /* new-style single address option */
+#define CILEN_ADDRS    10 /* old-style dual address option */
+
+
+#define CODENAME(x) ((x) == CONFACK ? "ACK" : \
+                     (x) == CONFNAK ? "NAK" : "REJ")
+
+
+/*
+ * ipcp_init - Initialize IPCP.
+ */
+static void
+ipcp_init(int unit)
+{
+  fsm           *f = &ipcp_fsm[unit];
+  ipcp_options *wo = &ipcp_wantoptions[unit];
+  ipcp_options *ao = &ipcp_allowoptions[unit];
+
+  f->unit      = unit;
+  f->protocol  = PPP_IPCP;
+  f->callbacks = &ipcp_callbacks;
+  fsm_init(&ipcp_fsm[unit]);
+
+  memset(wo, 0, sizeof(*wo));
+  memset(ao, 0, sizeof(*ao));
+
+  wo->neg_addr      = 1;
+  wo->ouraddr       = 0;
+#if VJ_SUPPORT
+  wo->neg_vj        = 1;
+#else  /* VJ_SUPPORT */
+  wo->neg_vj        = 0;
+#endif /* VJ_SUPPORT */
+  wo->vj_protocol   = IPCP_VJ_COMP;
+  wo->maxslotindex  = MAX_SLOTS - 1;
+  wo->cflag         = 0;
+  wo->default_route = 1;
+
+  ao->neg_addr      = 1;
+#if VJ_SUPPORT
+  ao->neg_vj        = 1;
+#else  /* VJ_SUPPORT */
+  ao->neg_vj        = 0;
+#endif /* VJ_SUPPORT */
+  ao->maxslotindex  = MAX_SLOTS - 1;
+  ao->cflag         = 1;
+  ao->default_route = 1;
+}
+
+
+/*
+ * ipcp_open - IPCP is allowed to come up.
+ */
+static void
+ipcp_open(int unit)
+{
+  fsm_open(&ipcp_fsm[unit]);
+}
+
+
+/*
+ * ipcp_close - Take IPCP down.
+ */
+static void
+ipcp_close(int unit, char *reason)
+{
+  fsm_close(&ipcp_fsm[unit], reason);
+}
+
+
+/*
+ * ipcp_lowerup - The lower layer is up.
+ */
+static void
+ipcp_lowerup(int unit)
+{
+  fsm_lowerup(&ipcp_fsm[unit]);
+}
+
+
+/*
+ * ipcp_lowerdown - The lower layer is down.
+ */
+static void
+ipcp_lowerdown(int unit)
+{
+  fsm_lowerdown(&ipcp_fsm[unit]);
+}
+
+
+/*
+ * ipcp_input - Input IPCP packet.
+ */
+static void
+ipcp_input(int unit, u_char *p, int len)
+{
+  fsm_input(&ipcp_fsm[unit], p, len);
+}
+
+
+/*
+ * ipcp_protrej - A Protocol-Reject was received for IPCP.
+ *
+ * Pretend the lower layer went down, so we shut up.
+ */
+static void
+ipcp_protrej(int unit)
+{
+  fsm_lowerdown(&ipcp_fsm[unit]);
+}
+
+
+/*
+ * ipcp_resetci - Reset our CI.
+ */
+static void
+ipcp_resetci(fsm *f)
+{
+  ipcp_options *wo = &ipcp_wantoptions[f->unit];
+  
+  wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;
+  if (wo->ouraddr == 0) {
+    wo->accept_local = 1;
+  }
+  if (wo->hisaddr == 0) {
+    wo->accept_remote = 1;
+  }
+  /* Request DNS addresses from the peer */
+  wo->req_dns1 = ppp_settings.usepeerdns;
+  wo->req_dns2 = ppp_settings.usepeerdns;
+  ipcp_gotoptions[f->unit] = *wo;
+  cis_received[f->unit] = 0;
+}
+
+
+/*
+ * ipcp_cilen - Return length of our CI.
+ */
+static int
+ipcp_cilen(fsm *f)
+{
+  ipcp_options *go = &ipcp_gotoptions[f->unit];
+  ipcp_options *wo = &ipcp_wantoptions[f->unit];
+  ipcp_options *ho = &ipcp_hisoptions[f->unit];
+
+#define LENCIVJ(neg, old)   (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
+#define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)
+#define LENCIDNS(neg)       (neg ? (CILEN_ADDR) : 0)
+
+  /*
+   * First see if we want to change our options to the old
+   * forms because we have received old forms from the peer.
+   */
+  if (wo->neg_addr && !go->neg_addr && !go->old_addrs) {
+    /* use the old style of address negotiation */
+    go->neg_addr = 1;
+    go->old_addrs = 1;
+  }
+  if (wo->neg_vj && !go->neg_vj && !go->old_vj) {
+    /* try an older style of VJ negotiation */
+    if (cis_received[f->unit] == 0) {
+      /* keep trying the new style until we see some CI from the peer */
+      go->neg_vj = 1;
+    } else {
+      /* use the old style only if the peer did */
+      if (ho->neg_vj && ho->old_vj) {
+        go->neg_vj = 1;
+        go->old_vj = 1;
+        go->vj_protocol = ho->vj_protocol;
+      }
+    }
+  }
+
+  return (LENCIADDR(go->neg_addr, go->old_addrs) +
+          LENCIVJ(go->neg_vj, go->old_vj) +
+          LENCIDNS(go->req_dns1) +
+          LENCIDNS(go->req_dns2));
+}
+
+
+/*
+ * ipcp_addci - Add our desired CIs to a packet.
+ */
+static void
+ipcp_addci(fsm *f, u_char *ucp, int *lenp)
+{
+  ipcp_options *go = &ipcp_gotoptions[f->unit];
+  int len = *lenp;
+
+#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
+  if (neg) { \
+    int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
+    if (len >= vjlen) { \
+      PUTCHAR(opt, ucp); \
+      PUTCHAR(vjlen, ucp); \
+      PUTSHORT(val, ucp); \
+      if (!old) { \
+        PUTCHAR(maxslotindex, ucp); \
+        PUTCHAR(cflag, ucp); \
+      } \
+      len -= vjlen; \
+    } else { \
+      neg = 0; \
+    } \
+  }
+
+#define ADDCIADDR(opt, neg, old, val1, val2) \
+  if (neg) { \
+    int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
+    if (len >= addrlen) { \
+      u32_t l; \
+      PUTCHAR(opt, ucp); \
+      PUTCHAR(addrlen, ucp); \
+      l = ntohl(val1); \
+      PUTLONG(l, ucp); \
+      if (old) { \
+        l = ntohl(val2); \
+        PUTLONG(l, ucp); \
+      } \
+      len -= addrlen; \
+    } else { \
+      neg = 0; \
+    } \
+  }
+
+#define ADDCIDNS(opt, neg, addr) \
+  if (neg) { \
+    if (len >= CILEN_ADDR) { \
+      u32_t l; \
+      PUTCHAR(opt, ucp); \
+      PUTCHAR(CILEN_ADDR, ucp); \
+      l = ntohl(addr); \
+      PUTLONG(l, ucp); \
+      len -= CILEN_ADDR; \
+    } else { \
+      neg = 0; \
+    } \
+  }
+
+  ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
+      go->old_addrs, go->ouraddr, go->hisaddr);
+
+  ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
+      go->maxslotindex, go->cflag);
+
+  ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
+
+  ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
+
+  *lenp -= len;
+}
+
+
+/*
+ * ipcp_ackci - Ack our CIs.
+ *
+ * Returns:
+ *  0 - Ack was bad.
+ *  1 - Ack was good.
+ */
+static int
+ipcp_ackci(fsm *f, u_char *p, int len)
+{
+  ipcp_options *go = &ipcp_gotoptions[f->unit];
+  u_short cilen, citype, cishort;
+  u32_t cilong;
+  u_char cimaxslotindex, cicflag;
+
+  /*
+   * CIs must be in exactly the same order that we sent...
+   * Check packet length and CI length at each step.
+   * If we find any deviations, then this packet is bad.
+   */
+
+#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
+  if (neg) { \
+    int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
+    if ((len -= vjlen) < 0) { \
+      goto bad; \
+    } \
+    GETCHAR(citype, p); \
+    GETCHAR(cilen, p); \
+    if (cilen != vjlen || \
+        citype != opt) { \
+      goto bad; \
+    } \
+    GETSHORT(cishort, p); \
+    if (cishort != val) { \
+      goto bad; \
+    } \
+    if (!old) { \
+      GETCHAR(cimaxslotindex, p); \
+      if (cimaxslotindex != maxslotindex) { \
+        goto bad; \
+      } \
+      GETCHAR(cicflag, p); \
+      if (cicflag != cflag) { \
+        goto bad; \
+      } \
+    } \
+  }
+  
+#define ACKCIADDR(opt, neg, old, val1, val2) \
+  if (neg) { \
+    int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
+    u32_t l; \
+    if ((len -= addrlen) < 0) { \
+      goto bad; \
+    } \
+    GETCHAR(citype, p); \
+    GETCHAR(cilen, p); \
+    if (cilen != addrlen || \
+        citype != opt) { \
+      goto bad; \
+    } \
+    GETLONG(l, p); \
+    cilong = htonl(l); \
+    if (val1 != cilong) { \
+      goto bad; \
+    } \
+    if (old) { \
+      GETLONG(l, p); \
+      cilong = htonl(l); \
+      if (val2 != cilong) { \
+        goto bad; \
+      } \
+    } \
+  }
+
+#define ACKCIDNS(opt, neg, addr) \
+  if (neg) { \
+    u32_t l; \
+    if ((len -= CILEN_ADDR) < 0) { \
+      goto bad; \
+    } \
+    GETCHAR(citype, p); \
+    GETCHAR(cilen, p); \
+    if (cilen != CILEN_ADDR || \
+        citype != opt) { \
+      goto bad; \
+    } \
+    GETLONG(l, p); \
+    cilong = htonl(l); \
+    if (addr != cilong) { \
+      goto bad; \
+    } \
+  }
+
+  ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
+        go->old_addrs, go->ouraddr, go->hisaddr);
+
+  ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
+      go->maxslotindex, go->cflag);
+
+  ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
+
+  ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
+
+  /*
+   * If there are any remaining CIs, then this packet is bad.
+   */
+  if (len != 0) {
+    goto bad;
+  }
+  return (1);
+
+bad:
+  IPCPDEBUG(LOG_INFO, ("ipcp_ackci: received bad Ack!\n"));
+  return (0);
+}
+
+/*
+ * ipcp_nakci - Peer has sent a NAK for some of our CIs.
+ * This should not modify any state if the Nak is bad
+ * or if IPCP is in the LS_OPENED state.
+ *
+ * Returns:
+ *  0 - Nak was bad.
+ *  1 - Nak was good.
+ */
+static int
+ipcp_nakci(fsm *f, u_char *p, int len)
+{
+  ipcp_options *go = &ipcp_gotoptions[f->unit];
+  u_char cimaxslotindex, cicflag;
+  u_char citype, cilen, *next;
+  u_short cishort;
+  u32_t ciaddr1, ciaddr2, l, cidnsaddr;
+  ipcp_options no;    /* options we've seen Naks for */
+  ipcp_options try;    /* options to request next time */
+
+  BZERO(&no, sizeof(no));
+  try = *go;
+
+  /*
+   * Any Nak'd CIs must be in exactly the same order that we sent.
+   * Check packet length and CI length at each step.
+   * If we find any deviations, then this packet is bad.
+   */
+#define NAKCIADDR(opt, neg, old, code) \
+  if (go->neg && \
+      len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \
+      p[1] == cilen && \
+      p[0] == opt) { \
+    len -= cilen; \
+    INCPTR(2, p); \
+    GETLONG(l, p); \
+    ciaddr1 = htonl(l); \
+    if (old) { \
+      GETLONG(l, p); \
+      ciaddr2 = htonl(l); \
+      no.old_addrs = 1; \
+    } else { \
+      ciaddr2 = 0; \
+    } \
+    no.neg = 1; \
+    code \
+  }
+
+#define NAKCIVJ(opt, neg, code) \
+  if (go->neg && \
+      ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \
+      len >= cilen && \
+      p[0] == opt) { \
+    len -= cilen; \
+    INCPTR(2, p); \
+    GETSHORT(cishort, p); \
+    no.neg = 1; \
+    code \
+  }
+  
+#define NAKCIDNS(opt, neg, code) \
+  if (go->neg && \
+      ((cilen = p[1]) == CILEN_ADDR) && \
+      len >= cilen && \
+      p[0] == opt) { \
+    len -= cilen; \
+    INCPTR(2, p); \
+    GETLONG(l, p); \
+    cidnsaddr = htonl(l); \
+    no.neg = 1; \
+    code \
+  }
+
+  /*
+   * Accept the peer's idea of {our,his} address, if different
+   * from our idea, only if the accept_{local,remote} flag is set.
+   */
+  NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,
+    if (go->accept_local && ciaddr1) { /* Do we know our address? */
+      try.ouraddr = ciaddr1;
+      IPCPDEBUG(LOG_INFO, ("local IP address %s\n",
+           inet_ntoa(ciaddr1)));
+    }
+    if (go->accept_remote && ciaddr2) { /* Does he know his? */
+      try.hisaddr = ciaddr2;
+      IPCPDEBUG(LOG_INFO, ("remote IP address %s\n",
+           inet_ntoa(ciaddr2)));
+    }
+  );
+
+  /*
+   * Accept the peer's value of maxslotindex provided that it
+   * is less than what we asked for.  Turn off slot-ID compression
+   * if the peer wants.  Send old-style compress-type option if
+   * the peer wants.
+   */
+  NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
+    if (cilen == CILEN_VJ) {
+      GETCHAR(cimaxslotindex, p);
+      GETCHAR(cicflag, p);
+      if (cishort == IPCP_VJ_COMP) {
+        try.old_vj = 0;
+        if (cimaxslotindex < go->maxslotindex) {
+          try.maxslotindex = cimaxslotindex;
+        }
+        if (!cicflag) {
+          try.cflag = 0;
+        }
+      } else {
+        try.neg_vj = 0;
+      }
+    } else {
+      if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {
+        try.old_vj = 1;
+        try.vj_protocol = cishort;
+      } else {
+        try.neg_vj = 0;
+      }
+    }
+  );
+
+  NAKCIDNS(CI_MS_DNS1, req_dns1,
+      try.dnsaddr[0] = cidnsaddr;
+        IPCPDEBUG(LOG_INFO, ("primary DNS address %s\n", inet_ntoa(cidnsaddr)));
+      );
+
+  NAKCIDNS(CI_MS_DNS2, req_dns2,
+      try.dnsaddr[1] = cidnsaddr;
+        IPCPDEBUG(LOG_INFO, ("secondary DNS address %s\n", inet_ntoa(cidnsaddr)));
+      );
+
+  /*
+  * There may be remaining CIs, if the peer is requesting negotiation
+  * on an option that we didn't include in our request packet.
+  * If they want to negotiate about IP addresses, we comply.
+  * If they want us to ask for compression, we refuse.
+  */
+  while (len > CILEN_VOID) {
+    GETCHAR(citype, p);
+    GETCHAR(cilen, p);
+    if( (len -= cilen) < 0 ) {
+      goto bad;
+    }
+    next = p + cilen - 2;
+
+    switch (citype) {
+      case CI_COMPRESSTYPE:
+        if (go->neg_vj || no.neg_vj ||
+            (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) {
+          goto bad;
+        }
+        no.neg_vj = 1;
+        break;
+      case CI_ADDRS:
+        if ((go->neg_addr && go->old_addrs) || no.old_addrs
+            || cilen != CILEN_ADDRS) {
+          goto bad;
+        }
+        try.neg_addr = 1;
+        try.old_addrs = 1;
+        GETLONG(l, p);
+        ciaddr1 = htonl(l);
+        if (ciaddr1 && go->accept_local) {
+          try.ouraddr = ciaddr1;
+        }
+        GETLONG(l, p);
+        ciaddr2 = htonl(l);
+        if (ciaddr2 && go->accept_remote) {
+          try.hisaddr = ciaddr2;
+        }
+        no.old_addrs = 1;
+        break;
+      case CI_ADDR:
+        if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) {
+          goto bad;
+        }
+        try.old_addrs = 0;
+        GETLONG(l, p);
+        ciaddr1 = htonl(l);
+        if (ciaddr1 && go->accept_local) {
+          try.ouraddr = ciaddr1;
+        }
+        if (try.ouraddr != 0) {
+          try.neg_addr = 1;
+        }
+        no.neg_addr = 1;
+        break;
+    }
+    p = next;
+  }
+
+  /* If there is still anything left, this packet is bad. */
+  if (len != 0) {
+    goto bad;
+  }
+
+  /*
+   * OK, the Nak is good.  Now we can update state.
+   */
+  if (f->state != LS_OPENED) {
+    *go = try;
+  }
+
+  return 1;
+
+bad:
+  IPCPDEBUG(LOG_INFO, ("ipcp_nakci: received bad Nak!\n"));
+  return 0;
+}
+
+
+/*
+ * ipcp_rejci - Reject some of our CIs.
+ */
+static int
+ipcp_rejci(fsm *f, u_char *p, int len)
+{
+  ipcp_options *go = &ipcp_gotoptions[f->unit];
+  u_char cimaxslotindex, ciflag, cilen;
+  u_short cishort;
+  u32_t cilong;
+  ipcp_options try;    /* options to request next time */
+
+  try = *go;
+  /*
+   * Any Rejected CIs must be in exactly the same order that we sent.
+   * Check packet length and CI length at each step.
+   * If we find any deviations, then this packet is bad.
+   */
+#define REJCIADDR(opt, neg, old, val1, val2) \
+  if (go->neg && \
+      len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \
+      p[1] == cilen && \
+      p[0] == opt) { \
+    u32_t l; \
+    len -= cilen; \
+    INCPTR(2, p); \
+    GETLONG(l, p); \
+    cilong = htonl(l); \
+    /* Check rejected value. */ \
+    if (cilong != val1) { \
+      goto bad; \
+    } \
+    if (old) { \
+      GETLONG(l, p); \
+      cilong = htonl(l); \
+      /* Check rejected value. */ \
+      if (cilong != val2) { \
+        goto bad; \
+      } \
+    } \
+    try.neg = 0; \
+  }
+
+#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \
+  if (go->neg && \
+      p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \
+      len >= p[1] && \
+      p[0] == opt) { \
+    len -= p[1]; \
+    INCPTR(2, p); \
+    GETSHORT(cishort, p); \
+    /* Check rejected value. */  \
+    if (cishort != val) { \
+      goto bad; \
+    } \
+    if (!old) { \
+      GETCHAR(cimaxslotindex, p); \
+      if (cimaxslotindex != maxslot) { \
+        goto bad; \
+      } \
+      GETCHAR(ciflag, p); \
+      if (ciflag != cflag) { \
+        goto bad; \
+      } \
+    } \
+    try.neg = 0; \
+  }
+
+#define REJCIDNS(opt, neg, dnsaddr) \
+  if (go->neg && \
+      ((cilen = p[1]) == CILEN_ADDR) && \
+      len >= cilen && \
+      p[0] == opt) { \
+    u32_t l; \
+    len -= cilen; \
+    INCPTR(2, p); \
+    GETLONG(l, p); \
+    cilong = htonl(l); \
+    /* Check rejected value. */ \
+    if (cilong != dnsaddr) { \
+      goto bad; \
+    } \
+    try.neg = 0; \
+  }
+
+  REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr,
+        go->old_addrs, go->ouraddr, go->hisaddr);
+
+  REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
+      go->maxslotindex, go->cflag);
+
+  REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);
+
+  REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
+
+  /*
+   * If there are any remaining CIs, then this packet is bad.
+   */
+  if (len != 0) {
+    goto bad;
+  }
+  /*
+   * Now we can update state.
+   */
+  if (f->state != LS_OPENED) {
+    *go = try;
+  }
+  return 1;
+
+bad:
+  IPCPDEBUG(LOG_INFO, ("ipcp_rejci: received bad Reject!\n"));
+  return 0;
+}
+
+
+/*
+ * ipcp_reqci - Check the peer's requested CIs and send appropriate response.
+ *
+ * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
+ * appropriately.  If reject_if_disagree is non-zero, doesn't return
+ * CONFNAK; returns CONFREJ if it can't return CONFACK.
+ */
+static int
+ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested CIs */,int reject_if_disagree)
+{
+  ipcp_options *wo = &ipcp_wantoptions[f->unit];
+  ipcp_options *ho = &ipcp_hisoptions[f->unit];
+  ipcp_options *ao = &ipcp_allowoptions[f->unit];
+#ifdef OLD_CI_ADDRS
+  ipcp_options *go = &ipcp_gotoptions[f->unit];
+#endif
+  u_char *cip, *next;     /* Pointer to current and next CIs */
+  u_short cilen, citype;  /* Parsed len, type */
+  u_short cishort;        /* Parsed short value */
+  u32_t tl, ciaddr1;      /* Parsed address values */
+#ifdef OLD_CI_ADDRS
+  u32_t ciaddr2;          /* Parsed address values */
+#endif
+  int rc = CONFACK;       /* Final packet return code */
+  int orc;                /* Individual option return code */
+  u_char *p;              /* Pointer to next char to parse */
+  u_char *ucp = inp;      /* Pointer to current output char */
+  int l = *len;           /* Length left */
+  u_char maxslotindex, cflag;
+  int d;
+
+  cis_received[f->unit] = 1;
+
+  /*
+   * Reset all his options.
+   */
+  BZERO(ho, sizeof(*ho));
+
+  /*
+   * Process all his options.
+   */
+  next = inp;
+  while (l) {
+    orc = CONFACK;       /* Assume success */
+    cip = p = next;      /* Remember begining of CI */
+    if (l < 2 ||         /* Not enough data for CI header or */
+        p[1] < 2 ||      /*  CI length too small or */
+        p[1] > l) {      /*  CI length too big? */
+      IPCPDEBUG(LOG_INFO, ("ipcp_reqci: bad CI length!\n"));
+      orc = CONFREJ;     /* Reject bad CI */
+      cilen = (u_short)l;/* Reject till end of packet */
+      l = 0;             /* Don't loop again */
+      goto endswitch;
+    }
+    GETCHAR(citype, p);  /* Parse CI type */
+    GETCHAR(cilen, p);   /* Parse CI length */
+    l -= cilen;          /* Adjust remaining length */
+    next += cilen;       /* Step to next CI */
+
+    switch (citype) {      /* Check CI type */
+#ifdef OLD_CI_ADDRS /* Need to save space... */
+      case CI_ADDRS:
+        IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received ADDRS\n"));
+        if (!ao->neg_addr ||
+            cilen != CILEN_ADDRS) {  /* Check CI length */
+          orc = CONFREJ;    /* Reject CI */
+          break;
+        }
+
+        /*
+         * If he has no address, or if we both have his address but
+         * disagree about it, then NAK it with our idea.
+         * In particular, if we don't know his address, but he does,
+         * then accept it.
+         */
+        GETLONG(tl, p);    /* Parse source address (his) */
+        ciaddr1 = htonl(tl);
+        IPCPDEBUG(LOG_INFO, ("his addr %s\n", inet_ntoa(ciaddr1)));
+        if (ciaddr1 != wo->hisaddr
+            && (ciaddr1 == 0 || !wo->accept_remote)) {
+          orc = CONFNAK;
+          if (!reject_if_disagree) {
+            DECPTR(sizeof(u32_t), p);
+            tl = ntohl(wo->hisaddr);
+            PUTLONG(tl, p);
+          }
+        } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
+          /*
+           * If neither we nor he knows his address, reject the option.
+           */
+          orc = CONFREJ;
+          wo->req_addr = 0;  /* don't NAK with 0.0.0.0 later */
+          break;
+        }
+
+        /*
+         * If he doesn't know our address, or if we both have our address
+         * but disagree about it, then NAK it with our idea.
+         */
+        GETLONG(tl, p);    /* Parse desination address (ours) */
+        ciaddr2 = htonl(tl);
+        IPCPDEBUG(LOG_INFO, ("our addr %s\n", inet_ntoa(ciaddr2)));
+        if (ciaddr2 != wo->ouraddr) {
+          if (ciaddr2 == 0 || !wo->accept_local) {
+            orc = CONFNAK;
+            if (!reject_if_disagree) {
+              DECPTR(sizeof(u32_t), p);
+              tl = ntohl(wo->ouraddr);
+              PUTLONG(tl, p);
+            }
+          } else {
+            go->ouraddr = ciaddr2;  /* accept peer's idea */
+          }
+        }
+
+        ho->neg_addr = 1;
+        ho->old_addrs = 1;
+        ho->hisaddr = ciaddr1;
+        ho->ouraddr = ciaddr2;
+        break;
+#endif
+
+      case CI_ADDR:
+        if (!ao->neg_addr) {
+          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR not allowed\n"));
+          orc = CONFREJ;        /* Reject CI */
+          break;
+        } else if (cilen != CILEN_ADDR) {  /* Check CI length */
+          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR bad len\n"));
+          orc = CONFREJ;        /* Reject CI */
+          break;
+        }
+
+        /*
+         * If he has no address, or if we both have his address but
+         * disagree about it, then NAK it with our idea.
+         * In particular, if we don't know his address, but he does,
+         * then accept it.
+         */
+        GETLONG(tl, p);  /* Parse source address (his) */
+        ciaddr1 = htonl(tl);
+        if (ciaddr1 != wo->hisaddr
+            && (ciaddr1 == 0 || !wo->accept_remote)) {
+          orc = CONFNAK;
+          if (!reject_if_disagree) {
+            DECPTR(sizeof(u32_t), p);
+            tl = ntohl(wo->hisaddr);
+            PUTLONG(tl, p);
+          }
+          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Nak ADDR %s\n", inet_ntoa(ciaddr1)));
+        } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
+          /*
+           * Don't ACK an address of 0.0.0.0 - reject it instead.
+           */
+          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR %s\n", inet_ntoa(ciaddr1)));
+          orc = CONFREJ;
+          wo->req_addr = 0;  /* don't NAK with 0.0.0.0 later */
+          break;
+        }
+
+        ho->neg_addr = 1;
+        ho->hisaddr = ciaddr1;
+        IPCPDEBUG(LOG_INFO, ("ipcp_reqci: ADDR %s\n", inet_ntoa(ciaddr1)));
+        break;
+
+      case CI_MS_DNS1:
+      case CI_MS_DNS2:
+        /* Microsoft primary or secondary DNS request */
+        d = citype == CI_MS_DNS2;
+
+        /* If we do not have a DNS address then we cannot send it */
+        if (ao->dnsaddr[d] == 0 ||
+            cilen != CILEN_ADDR) {  /* Check CI length */
+          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting DNS%d Request\n", d+1));
+          orc = CONFREJ;        /* Reject CI */
+          break;
+        }
+        GETLONG(tl, p);
+        if (htonl(tl) != ao->dnsaddr[d]) {
+          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking DNS%d Request %s\n",
+                d+1, inet_ntoa(tl)));
+          DECPTR(sizeof(u32_t), p);
+          tl = ntohl(ao->dnsaddr[d]);
+          PUTLONG(tl, p);
+          orc = CONFNAK;
+        }
+        IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received DNS%d Request\n", d+1));
+        break;
+
+      case CI_MS_WINS1:
+      case CI_MS_WINS2:
+        /* Microsoft primary or secondary WINS request */
+        d = citype == CI_MS_WINS2;
+        IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received WINS%d Request\n", d+1));
+
+        /* If we do not have a DNS address then we cannot send it */
+        if (ao->winsaddr[d] == 0 ||
+          cilen != CILEN_ADDR) {  /* Check CI length */
+          orc = CONFREJ;      /* Reject CI */
+          break;
+        }
+        GETLONG(tl, p);
+        if (htonl(tl) != ao->winsaddr[d]) {
+          DECPTR(sizeof(u32_t), p);
+          tl = ntohl(ao->winsaddr[d]);
+          PUTLONG(tl, p);
+          orc = CONFNAK;
+        }
+        break;
+
+      case CI_COMPRESSTYPE:
+        if (!ao->neg_vj) {
+          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE not allowed\n"));
+          orc = CONFREJ;
+          break;
+        } else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) {
+          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE len=%d\n", cilen));
+          orc = CONFREJ;
+          break;
+        }
+        GETSHORT(cishort, p);
+
+        if (!(cishort == IPCP_VJ_COMP ||
+            (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {
+          IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE %d\n", cishort));
+          orc = CONFREJ;
+          break;
+        }
+
+        ho->neg_vj = 1;
+        ho->vj_protocol = cishort;
+        if (cilen == CILEN_VJ) {
+          GETCHAR(maxslotindex, p);
+          if (maxslotindex > ao->maxslotindex) { 
+            IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ max slot %d\n", maxslotindex));
+            orc = CONFNAK;
+            if (!reject_if_disagree) {
+              DECPTR(1, p);
+              PUTCHAR(ao->maxslotindex, p);
+            }
+          }
+          GETCHAR(cflag, p);
+          if (cflag && !ao->cflag) {
+            IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ cflag %d\n", cflag));
+            orc = CONFNAK;
+            if (!reject_if_disagree) {
+              DECPTR(1, p);
+              PUTCHAR(wo->cflag, p);
+            }
+          }
+          ho->maxslotindex = maxslotindex;
+          ho->cflag = cflag;
+        } else {
+          ho->old_vj = 1;
+          ho->maxslotindex = MAX_SLOTS - 1;
+          ho->cflag = 1;
+        }
+        IPCPDEBUG(LOG_INFO, (
+              "ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d\n",
+              ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag));
+        break;
+
+      default:
+        IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting unknown CI type %d\n", citype));
+        orc = CONFREJ;
+        break;
+    }
+
+endswitch:
+    if (orc == CONFACK &&    /* Good CI */
+        rc != CONFACK) {     /*  but prior CI wasnt? */
+      continue;              /* Don't send this one */
+    }
+
+    if (orc == CONFNAK) {    /* Nak this CI? */
+      if (reject_if_disagree) {  /* Getting fed up with sending NAKs? */
+        IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting too many naks\n"));
+        orc = CONFREJ;       /* Get tough if so */
+      } else {
+        if (rc == CONFREJ) { /* Rejecting prior CI? */
+          continue;          /* Don't send this one */
+        }
+        if (rc == CONFACK) { /* Ack'd all prior CIs? */
+          rc = CONFNAK;      /* Not anymore... */
+          ucp = inp;         /* Backup */
+        }
+      }
+    }
+
+    if (orc == CONFREJ &&    /* Reject this CI */
+        rc != CONFREJ) {  /*  but no prior ones? */
+      rc = CONFREJ;
+      ucp = inp;        /* Backup */
+    }
+    
+    /* Need to move CI? */
+    if (ucp != cip) {
+      BCOPY(cip, ucp, cilen);  /* Move it */
+    }
+
+    /* Update output pointer */
+    INCPTR(cilen, ucp);
+  }
+
+  /*
+   * If we aren't rejecting this packet, and we want to negotiate
+   * their address, and they didn't send their address, then we
+   * send a NAK with a CI_ADDR option appended.  We assume the
+   * input buffer is long enough that we can append the extra
+   * option safely.
+   */
+  if (rc != CONFREJ && !ho->neg_addr &&
+      wo->req_addr && !reject_if_disagree) {
+    IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Requesting peer address\n"));
+    if (rc == CONFACK) {
+      rc = CONFNAK;
+      ucp = inp;        /* reset pointer */
+      wo->req_addr = 0;    /* don't ask again */
+    }
+    PUTCHAR(CI_ADDR, ucp);
+    PUTCHAR(CILEN_ADDR, ucp);
+    tl = ntohl(wo->hisaddr);
+    PUTLONG(tl, ucp);
+  }
+
+  *len = (int)(ucp - inp);    /* Compute output length */
+  IPCPDEBUG(LOG_INFO, ("ipcp_reqci: returning Configure-%s\n", CODENAME(rc)));
+  return (rc);      /* Return final code */
+}
+
+
+#if 0
+/*
+ * ip_check_options - check that any IP-related options are OK,
+ * and assign appropriate defaults.
+ */
+static void
+ip_check_options(u_long localAddr)
+{
+  ipcp_options *wo = &ipcp_wantoptions[0];
+
+  /*
+   * Load our default IP address but allow the remote host to give us
+   * a new address.
+   */
+  if (wo->ouraddr == 0 && !ppp_settings.disable_defaultip) {
+    wo->accept_local = 1;  /* don't insist on this default value */
+    wo->ouraddr = htonl(localAddr);
+  }
+}
+#endif
+
+
+/*
+ * ipcp_up - IPCP has come UP.
+ *
+ * Configure the IP network interface appropriately and bring it up.
+ */
+static void
+ipcp_up(fsm *f)
+{
+  u32_t mask;
+  ipcp_options *ho = &ipcp_hisoptions[f->unit];
+  ipcp_options *go = &ipcp_gotoptions[f->unit];
+  ipcp_options *wo = &ipcp_wantoptions[f->unit];
+
+  np_up(f->unit, PPP_IP);
+  IPCPDEBUG(LOG_INFO, ("ipcp: up\n"));
+
+  /*
+   * We must have a non-zero IP address for both ends of the link.
+   */
+  if (!ho->neg_addr) {
+    ho->hisaddr = wo->hisaddr;
+  }
+
+  if (ho->hisaddr == 0) {
+    IPCPDEBUG(LOG_ERR, ("Could not determine remote IP address\n"));
+    ipcp_close(f->unit, "Could not determine remote IP address");
+    return;
+  }
+  if (go->ouraddr == 0) {
+    IPCPDEBUG(LOG_ERR, ("Could not determine local IP address\n"));
+    ipcp_close(f->unit, "Could not determine local IP address");
+    return;
+  }
+
+  if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {
+    /*pppGotDNSAddrs(go->dnsaddr[0], go->dnsaddr[1]);*/
+  }
+
+  /*
+   * Check that the peer is allowed to use the IP address it wants.
+   */
+  if (!auth_ip_addr(f->unit, ho->hisaddr)) {
+    IPCPDEBUG(LOG_ERR, ("Peer is not authorized to use remote address %s\n",
+        inet_ntoa(ho->hisaddr)));
+    ipcp_close(f->unit, "Unauthorized remote IP address");
+    return;
+  }
+
+  /* set tcp compression */
+  sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);
+
+  /*
+   * Set IP addresses and (if specified) netmask.
+   */
+  mask = GetMask(go->ouraddr);
+
+  if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask, go->dnsaddr[0], go->dnsaddr[1])) {
+    IPCPDEBUG(LOG_WARNING, ("sifaddr failed\n"));
+    ipcp_close(f->unit, "Interface configuration failed");
+    return;
+  }
+
+  /* bring the interface up for IP */
+  if (!sifup(f->unit)) {
+    IPCPDEBUG(LOG_WARNING, ("sifup failed\n"));
+    ipcp_close(f->unit, "Interface configuration failed");
+    return;
+  }
+
+  sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
+
+  /* assign a default route through the interface if required */
+  if (ipcp_wantoptions[f->unit].default_route) {
+    if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) {
+      default_route_set[f->unit] = 1;
+    }
+  }
+
+  IPCPDEBUG(LOG_NOTICE, ("local  IP address %s\n", inet_ntoa(go->ouraddr)));
+  IPCPDEBUG(LOG_NOTICE, ("remote IP address %s\n", inet_ntoa(ho->hisaddr)));
+  if (go->dnsaddr[0]) {
+    IPCPDEBUG(LOG_NOTICE, ("primary   DNS address %s\n", inet_ntoa(go->dnsaddr[0])));
+  }
+  if (go->dnsaddr[1]) {
+    IPCPDEBUG(LOG_NOTICE, ("secondary DNS address %s\n", inet_ntoa(go->dnsaddr[1])));
+  }
+}
+
+
+/*
+ * ipcp_down - IPCP has gone DOWN.
+ *
+ * Take the IP network interface down, clear its addresses
+ * and delete routes through it.
+ */
+static void
+ipcp_down(fsm *f)
+{
+  IPCPDEBUG(LOG_INFO, ("ipcp: down\n"));
+  np_down(f->unit, PPP_IP);
+  sifvjcomp(f->unit, 0, 0, 0);
+
+  sifdown(f->unit);
+  ipcp_clear_addrs(f->unit);
+}
+
+
+/*
+ * ipcp_clear_addrs() - clear the interface addresses, routes, etc.
+ */
+static void
+ipcp_clear_addrs(int unit)
+{
+  u32_t ouraddr, hisaddr;
+
+  ouraddr = ipcp_gotoptions[unit].ouraddr;
+  hisaddr = ipcp_hisoptions[unit].hisaddr;
+  if (default_route_set[unit]) {
+    cifdefaultroute(unit, ouraddr, hisaddr);
+    default_route_set[unit] = 0;
+  }
+  cifaddr(unit, ouraddr, hisaddr);
+}
+
+
+/*
+ * ipcp_finished - possibly shut down the lower layers.
+ */
+static void
+ipcp_finished(fsm *f)
+{
+  np_finished(f->unit, PPP_IP);
+}
+
+#if PPP_ADDITIONAL_CALLBACKS
+static int
+ipcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg)
+{
+  LWIP_UNUSED_ARG(p);
+  LWIP_UNUSED_ARG(plen);
+  LWIP_UNUSED_ARG(printer);
+  LWIP_UNUSED_ARG(arg);
+  return 0;
+}
+
+/*
+ * ip_active_pkt - see if this IP packet is worth bringing the link up for.
+ * We don't bring the link up for IP fragments or for TCP FIN packets
+ * with no data.
+ */
+#define IP_HDRLEN   20  /* bytes */
+#define IP_OFFMASK  0x1fff
+#define IPPROTO_TCP 6
+#define TCP_HDRLEN  20
+#define TH_FIN      0x01
+
+/*
+ * We use these macros because the IP header may be at an odd address,
+ * and some compilers might use word loads to get th_off or ip_hl.
+ */
+
+#define net_short(x)    (((x)[0] << 8) + (x)[1])
+#define get_iphl(x)     (((unsigned char *)(x))[0] & 0xF)
+#define get_ipoff(x)    net_short((unsigned char *)(x) + 6)
+#define get_ipproto(x)  (((unsigned char *)(x))[9])
+#define get_tcpoff(x)   (((unsigned char *)(x))[12] >> 4)
+#define get_tcpflags(x) (((unsigned char *)(x))[13])
+
+static int
+ip_active_pkt(u_char *pkt, int len)
+{
+  u_char *tcp;
+  int hlen;
+
+  len -= PPP_HDRLEN;
+  pkt += PPP_HDRLEN;
+  if (len < IP_HDRLEN) {
+    return 0;
+  }
+  if ((get_ipoff(pkt) & IP_OFFMASK) != 0) {
+    return 0;
+  }
+  if (get_ipproto(pkt) != IPPROTO_TCP) {
+    return 1;
+  }
+  hlen = get_iphl(pkt) * 4;
+  if (len < hlen + TCP_HDRLEN) {
+    return 0;
+  }
+  tcp = pkt + hlen;
+  if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) {
+    return 0;
+  }
+  return 1;
+}
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+
+#endif /* PPP_SUPPORT */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ipcp.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ipcp.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ipcp.h	(revision 164)
@@ -0,0 +1,106 @@
+/*****************************************************************************
+* ipcp.h -  PPP IP NCP: Internet Protocol Network Control Protocol header file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
+*   Original derived from BSD codes.
+*****************************************************************************/
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef IPCP_H
+#define IPCP_H
+
+/*
+ * Options.
+ */
+#define CI_ADDRS            1      /* IP Addresses */
+#define CI_COMPRESSTYPE     2      /* Compression Type */
+#define CI_ADDR             3
+
+#define CI_MS_DNS1          129    /* Primary DNS value */
+#define CI_MS_WINS1         128    /* Primary WINS value */
+#define CI_MS_DNS2          131    /* Secondary DNS value */
+#define CI_MS_WINS2         130    /* Secondary WINS value */
+
+#define IPCP_VJMODE_OLD     1      /* "old" mode (option # = 0x0037) */
+#define IPCP_VJMODE_RFC1172 2      /* "old-rfc"mode (option # = 0x002d) */
+#define IPCP_VJMODE_RFC1332 3      /* "new-rfc"mode (option # = 0x002d, */
+                                   /*  maxslot and slot number compression) */
+
+#define IPCP_VJ_COMP        0x002d /* current value for VJ compression option */
+#define IPCP_VJ_COMP_OLD    0x0037 /* "old" (i.e, broken) value for VJ */
+                                   /* compression option */ 
+
+typedef struct ipcp_options {
+  u_int   neg_addr      : 1; /* Negotiate IP Address? */
+  u_int   old_addrs     : 1; /* Use old (IP-Addresses) option? */
+  u_int   req_addr      : 1; /* Ask peer to send IP address? */
+  u_int   default_route : 1; /* Assign default route through interface? */
+  u_int   proxy_arp     : 1; /* Make proxy ARP entry for peer? */
+  u_int   neg_vj        : 1; /* Van Jacobson Compression? */
+  u_int   old_vj        : 1; /* use old (short) form of VJ option? */
+  u_int   accept_local  : 1; /* accept peer's value for ouraddr */
+  u_int   accept_remote : 1; /* accept peer's value for hisaddr */
+  u_int   req_dns1      : 1; /* Ask peer to send primary DNS address? */
+  u_int   req_dns2      : 1; /* Ask peer to send secondary DNS address? */
+  u_short vj_protocol;       /* protocol value to use in VJ option */
+  u_char  maxslotindex;      /* VJ slots - 1. */
+  u_char  cflag;             /* VJ slot compression flag. */
+  u32_t   ouraddr, hisaddr;  /* Addresses in NETWORK BYTE ORDER */
+  u32_t   dnsaddr[2];        /* Primary and secondary MS DNS entries */
+  u32_t   winsaddr[2];       /* Primary and secondary MS WINS entries */
+} ipcp_options;
+
+extern fsm ipcp_fsm[];
+extern ipcp_options ipcp_wantoptions[];
+extern ipcp_options ipcp_gotoptions[];
+extern ipcp_options ipcp_allowoptions[];
+extern ipcp_options ipcp_hisoptions[];
+
+extern struct protent ipcp_protent;
+
+#endif /* IPCP_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/lcp.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/lcp.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/lcp.c	(revision 164)
@@ -0,0 +1,2066 @@
+/*****************************************************************************
+* lcp.c - Network Link Control Protocol program file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 by Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Original.
+*****************************************************************************/
+
+/*
+ * 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.
+ */
+ 
+
+#include "lwip/opt.h"
+
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "ppp_impl.h"
+#include "pppdebug.h"
+
+#include "fsm.h"
+#include "chap.h"
+#include "magic.h"
+#include "auth.h"
+#include "lcp.h"
+
+#include <string.h>
+
+#if PPPOE_SUPPORT
+#include "netif/ppp_oe.h"
+#else
+#define PPPOE_MAXMTU PPP_MAXMRU
+#endif
+
+#if 0 /* UNUSED */
+/*
+ * LCP-related command-line options.
+ */
+int lcp_echo_interval = 0;  /* Interval between LCP echo-requests */
+int lcp_echo_fails = 0;     /* Tolerance to unanswered echo-requests */
+bool  lax_recv = 0;         /* accept control chars in asyncmap */
+
+static int setescape (char **);
+
+static option_t lcp_option_list[] = {
+    /* LCP options */
+    /* list stripped for simplicity */
+    {NULL}
+};
+#endif /* UNUSED */
+
+/* options */
+LinkPhase lcp_phase[NUM_PPP];          /* Phase of link session (RFC 1661) */
+static u_int lcp_echo_interval      = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */
+static u_int lcp_echo_fails         = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */
+
+/* global vars */
+static fsm lcp_fsm[NUM_PPP];                            /* LCP fsm structure (global)*/
+lcp_options lcp_wantoptions[NUM_PPP];  /* Options that we want to request */
+lcp_options lcp_gotoptions[NUM_PPP];   /* Options that peer ack'd */
+lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
+lcp_options lcp_hisoptions[NUM_PPP];   /* Options that we ack'd */
+ext_accm xmit_accm[NUM_PPP];           /* extended transmit ACCM */
+
+static u32_t lcp_echos_pending      = 0;                /* Number of outstanding echo msgs */
+static u32_t lcp_echo_number        = 0;                /* ID number of next echo frame */
+static u32_t lcp_echo_timer_running = 0;                /* TRUE if a timer is running */
+
+/* @todo: do we really need such a large buffer? The typical 1500 bytes seem too much. */
+static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ 
+
+/*
+ * Callbacks for fsm code.  (CI = Configuration Information)
+ */
+static void lcp_resetci (fsm*);                   /* Reset our CI */
+static int  lcp_cilen (fsm*);                     /* Return length of our CI */
+static void lcp_addci (fsm*, u_char*, int*);      /* Add our CI to pkt */
+static int  lcp_ackci (fsm*, u_char*, int);       /* Peer ack'd our CI */
+static int  lcp_nakci (fsm*, u_char*, int);       /* Peer nak'd our CI */
+static int  lcp_rejci (fsm*, u_char*, int);       /* Peer rej'd our CI */
+static int  lcp_reqci (fsm*, u_char*, int*, int); /* Rcv peer CI */
+static void lcp_up (fsm*);                        /* We're UP */
+static void lcp_down (fsm*);                      /* We're DOWN */
+static void lcp_starting (fsm*);                  /* We need lower layer up */
+static void lcp_finished (fsm*);                  /* We need lower layer down */
+static int  lcp_extcode (fsm*, int, u_char, u_char*, int);
+static void lcp_rprotrej (fsm*, u_char*, int);
+
+/*
+ * routines to send LCP echos to peer
+ */
+
+static void lcp_echo_lowerup (int);
+static void lcp_echo_lowerdown (int);
+static void LcpEchoTimeout (void*);
+static void lcp_received_echo_reply (fsm*, int, u_char*, int);
+static void LcpSendEchoRequest (fsm*);
+static void LcpLinkFailure (fsm*);
+static void LcpEchoCheck (fsm*);
+
+static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
+  lcp_resetci,  /* Reset our Configuration Information */
+  lcp_cilen,    /* Length of our Configuration Information */
+  lcp_addci,    /* Add our Configuration Information */
+  lcp_ackci,    /* ACK our Configuration Information */
+  lcp_nakci,    /* NAK our Configuration Information */
+  lcp_rejci,    /* Reject our Configuration Information */
+  lcp_reqci,    /* Request peer's Configuration Information */
+  lcp_up,       /* Called when fsm reaches LS_OPENED state */
+  lcp_down,     /* Called when fsm leaves LS_OPENED state */
+  lcp_starting, /* Called when we want the lower layer up */
+  lcp_finished, /* Called when we want the lower layer down */
+  NULL,         /* Called when Protocol-Reject received */
+  NULL,         /* Retransmission is necessary */
+  lcp_extcode,  /* Called to handle LCP-specific codes */
+  "LCP"         /* String name of protocol */
+};
+
+/*
+ * Protocol entry points.
+ * Some of these are called directly.
+ */
+
+static void lcp_input (int, u_char *, int);
+static void lcp_protrej (int);
+
+struct protent lcp_protent = {
+    PPP_LCP,
+    lcp_init,
+    lcp_input,
+    lcp_protrej,
+    lcp_lowerup,
+    lcp_lowerdown,
+    lcp_open,
+    lcp_close,
+#if PPP_ADDITIONAL_CALLBACKS
+    lcp_printpkt,
+    NULL,
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+    1,
+    "LCP",
+#if PPP_ADDITIONAL_CALLBACKS
+    NULL,
+    NULL,
+    NULL
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+};
+
+int lcp_loopbackfail = DEFLOOPBACKFAIL;
+
+/*
+ * Length of each type of configuration option (in octets)
+ */
+#define CILEN_VOID  2
+#define CILEN_CHAR  3
+#define CILEN_SHORT 4 /* CILEN_VOID + sizeof(short) */
+#define CILEN_CHAP  5 /* CILEN_VOID + sizeof(short) + 1 */
+#define CILEN_LONG  6 /* CILEN_VOID + sizeof(long) */
+#define CILEN_LQR   8 /* CILEN_VOID + sizeof(short) + sizeof(long) */
+#define CILEN_CBCP  3
+
+#define CODENAME(x)  ((x) == CONFACK ? "ACK" : (x) == CONFNAK ? "NAK" : "REJ")
+
+#if 0 /* UNUSED */
+/*
+ * setescape - add chars to the set we escape on transmission.
+ */
+static int
+setescape(argv)
+    char **argv;
+{
+    int n, ret;
+    char *p, *endp;
+
+    p = *argv;
+    ret = 1;
+    while (*p) {
+      n = strtol(p, &endp, 16);
+      if (p == endp) {
+        option_error("escape parameter contains invalid hex number '%s'", p);
+        return 0;
+      }
+      p = endp;
+      if (n < 0 || n == 0x5E || n > 0xFF) {
+        option_error("can't escape character 0x%x", n);
+        ret = 0;
+      } else
+        xmit_accm[0][n >> 5] |= 1 << (n & 0x1F);
+      while (*p == ',' || *p == ' ')
+        ++p;
+    }
+    return ret;
+}
+#endif /* UNUSED */
+
+/*
+ * lcp_init - Initialize LCP.
+ */
+void
+lcp_init(int unit)
+{
+  fsm         *f  = &lcp_fsm[unit];
+  lcp_options *wo = &lcp_wantoptions[unit];
+  lcp_options *ao = &lcp_allowoptions[unit];
+
+  f->unit      = unit;
+  f->protocol  = PPP_LCP;
+  f->callbacks = &lcp_callbacks;
+
+  fsm_init(f);
+
+  wo->passive           = 0;
+  wo->silent            = 0;
+  wo->restart           = 0;               /* Set to 1 in kernels or multi-line implementations */
+  wo->neg_mru           = 1;
+  wo->mru               = PPP_DEFMRU;
+  wo->neg_asyncmap      = 1;
+  wo->asyncmap          = 0x00000000l;     /* Assume don't need to escape any ctl chars. */
+  wo->neg_chap          = 0;               /* Set to 1 on server */
+  wo->neg_upap          = 0;               /* Set to 1 on server */
+  wo->chap_mdtype       = CHAP_DIGEST_MD5;
+  wo->neg_magicnumber   = 1;
+  wo->neg_pcompression  = 1;
+  wo->neg_accompression = 1;
+  wo->neg_lqr           = 0;               /* no LQR implementation yet */
+  wo->neg_cbcp          = 0;
+
+  ao->neg_mru           = 1;
+  ao->mru               = PPP_MAXMRU;
+  ao->neg_asyncmap      = 1;
+  ao->asyncmap          = 0x00000000l;     /* Assume don't need to escape any ctl chars. */
+  ao->neg_chap          = (CHAP_SUPPORT != 0);
+  ao->chap_mdtype       = CHAP_DIGEST_MD5;
+  ao->neg_upap          = (PAP_SUPPORT != 0);
+  ao->neg_magicnumber   = 1;
+  ao->neg_pcompression  = 1;
+  ao->neg_accompression = 1;
+  ao->neg_lqr           = 0;               /* no LQR implementation yet */
+  ao->neg_cbcp          = (CBCP_SUPPORT != 0);
+
+  /* 
+   * Set transmit escape for the flag and escape characters plus anything
+   * set for the allowable options.
+   */
+  memset(xmit_accm[unit], 0, sizeof(xmit_accm[0]));
+  xmit_accm[unit][15] = 0x60;
+  xmit_accm[unit][0]  = (u_char)((ao->asyncmap        & 0xFF));
+  xmit_accm[unit][1]  = (u_char)((ao->asyncmap >> 8)  & 0xFF);
+  xmit_accm[unit][2]  = (u_char)((ao->asyncmap >> 16) & 0xFF);
+  xmit_accm[unit][3]  = (u_char)((ao->asyncmap >> 24) & 0xFF);
+  LCPDEBUG(LOG_INFO, ("lcp_init: xmit_accm=%X %X %X %X\n",
+        xmit_accm[unit][0],
+        xmit_accm[unit][1],
+        xmit_accm[unit][2],
+        xmit_accm[unit][3]));
+  
+  lcp_phase[unit] = PHASE_INITIALIZE;
+}
+
+
+/*
+ * lcp_open - LCP is allowed to come up.
+ */
+void
+lcp_open(int unit)
+{
+  fsm         *f  = &lcp_fsm[unit];
+  lcp_options *wo = &lcp_wantoptions[unit];
+
+  f->flags = 0;
+  if (wo->passive) {
+    f->flags |= OPT_PASSIVE;
+  }
+  if (wo->silent) {
+    f->flags |= OPT_SILENT;
+  }
+  fsm_open(f);
+
+  lcp_phase[unit] = PHASE_ESTABLISH;
+}
+
+
+/*
+ * lcp_close - Take LCP down.
+ */
+void
+lcp_close(int unit, char *reason)
+{
+  fsm *f = &lcp_fsm[unit];
+
+  if (lcp_phase[unit] != PHASE_DEAD) {
+    lcp_phase[unit] = PHASE_TERMINATE;
+  }
+  if (f->state == LS_STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
+    /*
+     * This action is not strictly according to the FSM in RFC1548,
+     * but it does mean that the program terminates if you do an
+     * lcp_close() in passive/silent mode when a connection hasn't
+     * been established.
+     */
+    f->state = LS_CLOSED;
+    lcp_finished(f);
+  } else {
+    fsm_close(f, reason);
+  }
+}
+
+
+/*
+ * lcp_lowerup - The lower layer is up.
+ */
+void
+lcp_lowerup(int unit)
+{
+  lcp_options *wo = &lcp_wantoptions[unit];
+
+  /*
+   * Don't use A/C or protocol compression on transmission,
+   * but accept A/C and protocol compressed packets
+   * if we are going to ask for A/C and protocol compression.
+   */
+  ppp_set_xaccm(unit, &xmit_accm[unit]);
+  ppp_send_config(unit, PPP_MRU, 0xffffffffl, 0, 0);
+  ppp_recv_config(unit, PPP_MRU, 0x00000000l,
+  wo->neg_pcompression, wo->neg_accompression);
+  peer_mru[unit] = PPP_MRU;
+  lcp_allowoptions[unit].asyncmap = (u_long)xmit_accm[unit][0]
+                                 | ((u_long)xmit_accm[unit][1] << 8)
+                                 | ((u_long)xmit_accm[unit][2] << 16)
+                                 | ((u_long)xmit_accm[unit][3] << 24);
+  LCPDEBUG(LOG_INFO, ("lcp_lowerup: asyncmap=%X %X %X %X\n",
+            xmit_accm[unit][3],
+            xmit_accm[unit][2],
+            xmit_accm[unit][1],
+            xmit_accm[unit][0]));
+
+  fsm_lowerup(&lcp_fsm[unit]);
+}
+
+
+/*
+ * lcp_lowerdown - The lower layer is down.
+ */
+void
+lcp_lowerdown(int unit)
+{
+  fsm_lowerdown(&lcp_fsm[unit]);
+}
+
+
+/*
+ * lcp_input - Input LCP packet.
+ */
+static void
+lcp_input(int unit, u_char *p, int len)
+{
+  fsm *f = &lcp_fsm[unit];
+
+  fsm_input(f, p, len);
+}
+
+
+/*
+ * lcp_extcode - Handle a LCP-specific code.
+ */
+static int
+lcp_extcode(fsm *f, int code, u_char id, u_char *inp, int len)
+{
+  u_char *magp;
+
+  switch( code ){
+    case PROTREJ:
+      lcp_rprotrej(f, inp, len);
+      break;
+  
+    case ECHOREQ:
+      if (f->state != LS_OPENED) {
+        break;
+      }
+      LCPDEBUG(LOG_INFO, ("lcp: Echo-Request, Rcvd id %d\n", id));
+      magp = inp;
+      PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
+      fsm_sdata(f, ECHOREP, id, inp, len);
+      break;
+
+    case ECHOREP:
+      lcp_received_echo_reply(f, id, inp, len);
+      break;
+
+    case DISCREQ:
+      break;
+
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+
+/*
+ * lcp_rprotrej - Receive an Protocol-Reject.
+ *
+ * Figure out which protocol is rejected and inform it.
+ */
+static void
+lcp_rprotrej(fsm *f, u_char *inp, int len)
+{
+  int i;
+  struct protent *protp;
+  u_short prot;
+
+  if (len < (int)sizeof (u_short)) {
+    LCPDEBUG(LOG_INFO, ("lcp_rprotrej: Rcvd short Protocol-Reject packet!\n"));
+    return;
+  }
+
+  GETSHORT(prot, inp);
+
+  LCPDEBUG(LOG_INFO, ("lcp_rprotrej: Rcvd Protocol-Reject packet for %x!\n", prot));
+
+  /*
+   * Protocol-Reject packets received in any state other than the LCP
+   * LS_OPENED state SHOULD be silently discarded.
+   */
+  if( f->state != LS_OPENED ) {
+    LCPDEBUG(LOG_INFO, ("Protocol-Reject discarded: LCP in state %d\n", f->state));
+    return;
+  }
+
+  /*
+   * Upcall the proper Protocol-Reject routine.
+   */
+  for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
+    if (protp->protocol == prot && protp->enabled_flag) {
+      (*protp->protrej)(f->unit);
+      return;
+    }
+  }
+
+  LCPDEBUG(LOG_WARNING, ("Protocol-Reject for unsupported protocol 0x%x\n", prot));
+}
+
+
+/*
+ * lcp_protrej - A Protocol-Reject was received.
+ */
+static void
+lcp_protrej(int unit)
+{
+  LWIP_UNUSED_ARG(unit);
+  /*
+   * Can't reject LCP!
+   */
+  LCPDEBUG(LOG_WARNING, ("lcp_protrej: Received Protocol-Reject for LCP!\n"));
+  fsm_protreject(&lcp_fsm[unit]);
+}
+
+
+/*
+ * lcp_sprotrej - Send a Protocol-Reject for some protocol.
+ */
+void
+lcp_sprotrej(int unit, u_char *p, int len)
+{
+  /*
+   * Send back the protocol and the information field of the
+   * rejected packet.  We only get here if LCP is in the LS_OPENED state.
+   */
+
+  fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id, p, len);
+}
+
+
+/*
+ * lcp_resetci - Reset our CI.
+ */
+static void
+lcp_resetci(fsm *f)
+{
+  lcp_wantoptions[f->unit].magicnumber = magic();
+  lcp_wantoptions[f->unit].numloops = 0;
+  lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];
+  peer_mru[f->unit] = PPP_MRU;
+  auth_reset(f->unit);
+}
+
+
+/*
+ * lcp_cilen - Return length of our CI.
+ */
+static int
+lcp_cilen(fsm *f)
+{
+  lcp_options *go = &lcp_gotoptions[f->unit];
+
+#define LENCIVOID(neg)  ((neg) ? CILEN_VOID : 0)
+#define LENCICHAP(neg)  ((neg) ? CILEN_CHAP : 0)
+#define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0)
+#define LENCILONG(neg)  ((neg) ? CILEN_LONG : 0)
+#define LENCILQR(neg)   ((neg) ? CILEN_LQR: 0)
+#define LENCICBCP(neg)  ((neg) ? CILEN_CBCP: 0)
+  /*
+   * NB: we only ask for one of CHAP and UPAP, even if we will
+   * accept either.
+   */
+  return (LENCISHORT(go->neg_mru && go->mru != PPP_DEFMRU) +
+          LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) +
+          LENCICHAP(go->neg_chap) +
+          LENCISHORT(!go->neg_chap && go->neg_upap) +
+          LENCILQR(go->neg_lqr) +
+          LENCICBCP(go->neg_cbcp) +
+          LENCILONG(go->neg_magicnumber) +
+          LENCIVOID(go->neg_pcompression) +
+          LENCIVOID(go->neg_accompression));
+}
+
+
+/*
+ * lcp_addci - Add our desired CIs to a packet.
+ */
+static void
+lcp_addci(fsm *f, u_char *ucp, int *lenp)
+{
+  lcp_options *go = &lcp_gotoptions[f->unit];
+  u_char *start_ucp = ucp;
+
+#define ADDCIVOID(opt, neg) \
+  if (neg) { \
+    LCPDEBUG(LOG_INFO, ("lcp_addci: opt=%d\n", opt)); \
+    PUTCHAR(opt, ucp); \
+    PUTCHAR(CILEN_VOID, ucp); \
+  }
+#define ADDCISHORT(opt, neg, val) \
+  if (neg) { \
+    LCPDEBUG(LOG_INFO, ("lcp_addci: INT opt=%d %X\n", opt, val)); \
+    PUTCHAR(opt, ucp); \
+    PUTCHAR(CILEN_SHORT, ucp); \
+    PUTSHORT(val, ucp); \
+  }
+#define ADDCICHAP(opt, neg, val, digest) \
+  if (neg) { \
+    LCPDEBUG(LOG_INFO, ("lcp_addci: CHAP opt=%d %X\n", opt, val)); \
+    PUTCHAR(opt, ucp); \
+    PUTCHAR(CILEN_CHAP, ucp); \
+    PUTSHORT(val, ucp); \
+    PUTCHAR(digest, ucp); \
+  }
+#define ADDCILONG(opt, neg, val) \
+  if (neg) { \
+    LCPDEBUG(LOG_INFO, ("lcp_addci: L opt=%d %lX\n", opt, val)); \
+    PUTCHAR(opt, ucp); \
+    PUTCHAR(CILEN_LONG, ucp); \
+    PUTLONG(val, ucp); \
+  }
+#define ADDCILQR(opt, neg, val) \
+  if (neg) { \
+    LCPDEBUG(LOG_INFO, ("lcp_addci: LQR opt=%d %lX\n", opt, val)); \
+    PUTCHAR(opt, ucp); \
+    PUTCHAR(CILEN_LQR, ucp); \
+    PUTSHORT(PPP_LQR, ucp); \
+    PUTLONG(val, ucp); \
+  }
+#define ADDCICHAR(opt, neg, val) \
+  if (neg) { \
+    LCPDEBUG(LOG_INFO, ("lcp_addci: CHAR opt=%d %X '%z'\n", opt, val, val)); \
+    PUTCHAR(opt, ucp); \
+    PUTCHAR(CILEN_CHAR, ucp); \
+    PUTCHAR(val, ucp); \
+  }
+
+  ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);
+  ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl, go->asyncmap);
+  ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
+  ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
+  ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
+  ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
+  ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
+  ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
+  ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
+
+  if (ucp - start_ucp != *lenp) {
+    /* this should never happen, because peer_mtu should be 1500 */
+    LCPDEBUG(LOG_ERR, ("Bug in lcp_addci: wrong length\n"));
+  }
+}
+
+
+/*
+ * lcp_ackci - Ack our CIs.
+ * This should not modify any state if the Ack is bad.
+ *
+ * Returns:
+ *  0 - Ack was bad.
+ *  1 - Ack was good.
+ */
+static int
+lcp_ackci(fsm *f, u_char *p, int len)
+{
+  lcp_options *go = &lcp_gotoptions[f->unit];
+  u_char cilen, citype, cichar;
+  u_short cishort;
+  u32_t cilong;
+
+  /*
+   * CIs must be in exactly the same order that we sent.
+   * Check packet length and CI length at each step.
+   * If we find any deviations, then this packet is bad.
+   */
+#define ACKCIVOID(opt, neg) \
+  if (neg) { \
+    if ((len -= CILEN_VOID) < 0) \
+      goto bad; \
+    GETCHAR(citype, p); \
+    GETCHAR(cilen, p); \
+    if (cilen != CILEN_VOID || citype != opt) \
+      goto bad; \
+  }
+#define ACKCISHORT(opt, neg, val) \
+  if (neg) { \
+    if ((len -= CILEN_SHORT) < 0) \
+      goto bad; \
+    GETCHAR(citype, p); \
+    GETCHAR(cilen, p); \
+    if (cilen != CILEN_SHORT || citype != opt) \
+      goto bad; \
+    GETSHORT(cishort, p); \
+    if (cishort != val) \
+      goto bad; \
+  }
+#define ACKCICHAR(opt, neg, val) \
+  if (neg) { \
+    if ((len -= CILEN_CHAR) < 0) \
+      goto bad; \
+    GETCHAR(citype, p); \
+    GETCHAR(cilen, p); \
+    if (cilen != CILEN_CHAR || citype != opt) \
+      goto bad; \
+    GETCHAR(cichar, p); \
+    if (cichar != val) \
+      goto bad; \
+  }
+#define ACKCICHAP(opt, neg, val, digest) \
+  if (neg) { \
+    if ((len -= CILEN_CHAP) < 0) \
+      goto bad; \
+    GETCHAR(citype, p); \
+    GETCHAR(cilen, p); \
+    if (cilen != CILEN_CHAP || citype != opt) \
+      goto bad; \
+    GETSHORT(cishort, p); \
+    if (cishort != val) \
+      goto bad; \
+    GETCHAR(cichar, p); \
+    if (cichar != digest) \
+      goto bad; \
+  }
+#define ACKCILONG(opt, neg, val) \
+  if (neg) { \
+    if ((len -= CILEN_LONG) < 0) \
+      goto bad; \
+    GETCHAR(citype, p); \
+    GETCHAR(cilen, p); \
+    if (cilen != CILEN_LONG ||  citype != opt) \
+      goto bad; \
+    GETLONG(cilong, p); \
+    if (cilong != val) \
+      goto bad; \
+  }
+#define ACKCILQR(opt, neg, val) \
+  if (neg) { \
+    if ((len -= CILEN_LQR) < 0) \
+      goto bad; \
+    GETCHAR(citype, p); \
+    GETCHAR(cilen, p); \
+    if (cilen != CILEN_LQR || citype != opt) \
+      goto bad; \
+    GETSHORT(cishort, p); \
+    if (cishort != PPP_LQR) \
+      goto bad; \
+    GETLONG(cilong, p); \
+    if (cilong != val) \
+      goto bad; \
+  }
+
+  ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);
+  ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl, go->asyncmap);
+  ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
+  ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
+  ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
+  ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
+  ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
+  ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
+  ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
+
+  /*
+   * If there are any remaining CIs, then this packet is bad.
+   */
+  if (len != 0) {
+    goto bad;
+  }
+  LCPDEBUG(LOG_INFO, ("lcp_acki: Ack\n"));
+  return (1);
+bad:
+  LCPDEBUG(LOG_WARNING, ("lcp_acki: received bad Ack!\n"));
+  return (0);
+}
+
+
+/*
+ * lcp_nakci - Peer has sent a NAK for some of our CIs.
+ * This should not modify any state if the Nak is bad
+ * or if LCP is in the LS_OPENED state.
+ *
+ * Returns:
+ *  0 - Nak was bad.
+ *  1 - Nak was good.
+ */
+static int
+lcp_nakci(fsm *f, u_char *p, int len)
+{
+  lcp_options *go = &lcp_gotoptions[f->unit];
+  lcp_options *wo = &lcp_wantoptions[f->unit];
+  u_char citype, cichar, *next;
+  u_short cishort;
+  u32_t cilong;
+  lcp_options no;     /* options we've seen Naks for */
+  lcp_options try;    /* options to request next time */
+  int looped_back = 0;
+  int cilen;
+
+  BZERO(&no, sizeof(no));
+  try = *go;
+
+  /*
+   * Any Nak'd CIs must be in exactly the same order that we sent.
+   * Check packet length and CI length at each step.
+   * If we find any deviations, then this packet is bad.
+   */
+#define NAKCIVOID(opt, neg, code) \
+  if (go->neg && \
+      len >= CILEN_VOID && \
+      p[1] == CILEN_VOID && \
+      p[0] == opt) { \
+    len -= CILEN_VOID; \
+    INCPTR(CILEN_VOID, p); \
+    no.neg = 1; \
+    code \
+  }
+#define NAKCICHAP(opt, neg, code) \
+  if (go->neg && \
+      len >= CILEN_CHAP && \
+      p[1] == CILEN_CHAP && \
+      p[0] == opt) { \
+    len -= CILEN_CHAP; \
+    INCPTR(2, p); \
+    GETSHORT(cishort, p); \
+    GETCHAR(cichar, p); \
+    no.neg = 1; \
+    code \
+  }
+#define NAKCICHAR(opt, neg, code) \
+  if (go->neg && \
+      len >= CILEN_CHAR && \
+      p[1] == CILEN_CHAR && \
+      p[0] == opt) { \
+    len -= CILEN_CHAR; \
+    INCPTR(2, p); \
+    GETCHAR(cichar, p); \
+    no.neg = 1; \
+    code \
+  }
+#define NAKCISHORT(opt, neg, code) \
+  if (go->neg && \
+      len >= CILEN_SHORT && \
+      p[1] == CILEN_SHORT && \
+      p[0] == opt) { \
+    len -= CILEN_SHORT; \
+    INCPTR(2, p); \
+    GETSHORT(cishort, p); \
+    no.neg = 1; \
+    code \
+  }
+#define NAKCILONG(opt, neg, code) \
+  if (go->neg && \
+      len >= CILEN_LONG && \
+      p[1] == CILEN_LONG && \
+      p[0] == opt) { \
+    len -= CILEN_LONG; \
+    INCPTR(2, p); \
+    GETLONG(cilong, p); \
+    no.neg = 1; \
+    code \
+  }
+#define NAKCILQR(opt, neg, code) \
+  if (go->neg && \
+      len >= CILEN_LQR && \
+      p[1] == CILEN_LQR && \
+      p[0] == opt) { \
+    len -= CILEN_LQR; \
+    INCPTR(2, p); \
+    GETSHORT(cishort, p); \
+    GETLONG(cilong, p); \
+    no.neg = 1; \
+    code \
+  }
+
+  /*
+   * We don't care if they want to send us smaller packets than
+   * we want.  Therefore, accept any MRU less than what we asked for,
+   * but then ignore the new value when setting the MRU in the kernel.
+   * If they send us a bigger MRU than what we asked, accept it, up to
+   * the limit of the default MRU we'd get if we didn't negotiate.
+   */
+  if (go->neg_mru && go->mru != PPP_DEFMRU) {
+    NAKCISHORT(CI_MRU, neg_mru,
+      if (cishort <= wo->mru || cishort < PPP_DEFMRU) {
+        try.mru = cishort;
+      }
+    );
+  }
+
+  /*
+   * Add any characters they want to our (receive-side) asyncmap.
+   */
+  if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) {
+    NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
+      try.asyncmap = go->asyncmap | cilong;
+    );
+  }
+
+  /*
+   * If they've nak'd our authentication-protocol, check whether
+   * they are proposing a different protocol, or a different
+   * hash algorithm for CHAP.
+   */
+  if ((go->neg_chap || go->neg_upap)
+      && len >= CILEN_SHORT
+      && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
+    cilen = p[1];
+    len -= cilen;
+    no.neg_chap = go->neg_chap;
+    no.neg_upap = go->neg_upap;
+    INCPTR(2, p);
+    GETSHORT(cishort, p);
+    if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
+      /*
+       * If we were asking for CHAP, they obviously don't want to do it.
+       * If we weren't asking for CHAP, then we were asking for PAP,
+       * in which case this Nak is bad.
+       */
+      if (!go->neg_chap) {
+        goto bad;
+      }
+      try.neg_chap = 0;
+    
+    } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
+      GETCHAR(cichar, p);
+      if (go->neg_chap) {
+        /*
+         * We were asking for CHAP/MD5; they must want a different
+         * algorithm.  If they can't do MD5, we'll have to stop
+         * asking for CHAP.
+         */
+        if (cichar != go->chap_mdtype) {
+          try.neg_chap = 0;
+        }
+      } else {
+        /*
+         * Stop asking for PAP if we were asking for it.
+         */
+        try.neg_upap = 0;
+      }
+    
+    } else {
+      /*
+       * We don't recognize what they're suggesting.
+       * Stop asking for what we were asking for.
+       */
+      if (go->neg_chap) {
+        try.neg_chap = 0;
+      } else {
+        try.neg_upap = 0;
+      }
+      p += cilen - CILEN_SHORT;
+    }
+  }
+
+  /*
+   * If they can't cope with our link quality protocol, we'll have
+   * to stop asking for LQR.  We haven't got any other protocol.
+   * If they Nak the reporting period, take their value XXX ?
+   */
+  NAKCILQR(CI_QUALITY, neg_lqr,
+    if (cishort != PPP_LQR) {
+      try.neg_lqr = 0;
+    } else {
+      try.lqr_period = cilong;
+    }
+  );
+
+  /*
+   * Only implementing CBCP...not the rest of the callback options
+   */
+  NAKCICHAR(CI_CALLBACK, neg_cbcp,
+    try.neg_cbcp = 0;
+  );
+
+  /*
+   * Check for a looped-back line.
+   */
+  NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
+    try.magicnumber = magic();
+    looped_back = 1;
+  );
+
+  /*
+   * Peer shouldn't send Nak for protocol compression or
+   * address/control compression requests; they should send
+   * a Reject instead.  If they send a Nak, treat it as a Reject.
+   */
+  NAKCIVOID(CI_PCOMPRESSION, neg_pcompression,
+    try.neg_pcompression = 0;
+  );
+  NAKCIVOID(CI_ACCOMPRESSION, neg_accompression,
+    try.neg_accompression = 0;
+  );
+
+  /*
+   * There may be remaining CIs, if the peer is requesting negotiation
+   * on an option that we didn't include in our request packet.
+   * If we see an option that we requested, or one we've already seen
+   * in this packet, then this packet is bad.
+   * If we wanted to respond by starting to negotiate on the requested
+   * option(s), we could, but we don't, because except for the
+   * authentication type and quality protocol, if we are not negotiating
+   * an option, it is because we were told not to.
+   * For the authentication type, the Nak from the peer means
+   * `let me authenticate myself with you' which is a bit pointless.
+   * For the quality protocol, the Nak means `ask me to send you quality
+   * reports', but if we didn't ask for them, we don't want them.
+   * An option we don't recognize represents the peer asking to
+   * negotiate some option we don't support, so ignore it.
+   */
+  while (len > CILEN_VOID) {
+    GETCHAR(citype, p);
+    GETCHAR(cilen, p);
+    if (cilen < CILEN_VOID || (len -= cilen) < 0) {
+      goto bad;
+    }
+    next = p + cilen - 2;
+
+    switch (citype) {
+      case CI_MRU:
+        if ((go->neg_mru && go->mru != PPP_DEFMRU)
+            || no.neg_mru || cilen != CILEN_SHORT) {
+          goto bad;
+        }
+        GETSHORT(cishort, p);
+        if (cishort < PPP_DEFMRU) {
+          try.mru = cishort;
+        }
+        break;
+      case CI_ASYNCMAP:
+        if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl)
+            || no.neg_asyncmap || cilen != CILEN_LONG) {
+          goto bad;
+        }
+        break;
+      case CI_AUTHTYPE:
+        if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap) {
+          goto bad;
+        }
+        break;
+      case CI_MAGICNUMBER:
+        if (go->neg_magicnumber || no.neg_magicnumber ||
+            cilen != CILEN_LONG) {
+          goto bad;
+        }
+        break;
+      case CI_PCOMPRESSION:
+        if (go->neg_pcompression || no.neg_pcompression
+            || cilen != CILEN_VOID) {
+          goto bad;
+        }
+        break;
+      case CI_ACCOMPRESSION:
+        if (go->neg_accompression || no.neg_accompression
+            || cilen != CILEN_VOID) {
+          goto bad;
+        }
+        break;
+      case CI_QUALITY:
+        if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR) {
+          goto bad;
+        }
+        break;
+    }
+    p = next;
+  }
+
+  /* If there is still anything left, this packet is bad. */
+  if (len != 0) {
+    goto bad;
+  }
+
+  /*
+  * OK, the Nak is good.  Now we can update state.
+  */
+  if (f->state != LS_OPENED) {
+    if (looped_back) {
+      if (++try.numloops >= lcp_loopbackfail) {
+        LCPDEBUG(LOG_NOTICE, ("Serial line is looped back.\n"));
+        lcp_close(f->unit, "Loopback detected");
+      }
+    } else {
+      try.numloops = 0;
+    }
+    *go = try;
+  }
+
+  return 1;
+
+bad:
+  LCPDEBUG(LOG_WARNING, ("lcp_nakci: received bad Nak!\n"));
+  return 0;
+}
+
+
+/*
+ * lcp_rejci - Peer has Rejected some of our CIs.
+ * This should not modify any state if the Reject is bad
+ * or if LCP is in the LS_OPENED state.
+ *
+ * Returns:
+ *  0 - Reject was bad.
+ *  1 - Reject was good.
+ */
+static int
+lcp_rejci(fsm *f, u_char *p, int len)
+{
+  lcp_options *go = &lcp_gotoptions[f->unit];
+  u_char cichar;
+  u_short cishort;
+  u32_t cilong;
+  lcp_options try; /* options to request next time */
+
+  try = *go;
+
+  /*
+   * Any Rejected CIs must be in exactly the same order that we sent.
+   * Check packet length and CI length at each step.
+   * If we find any deviations, then this packet is bad.
+   */
+#define REJCIVOID(opt, neg) \
+  if (go->neg && \
+      len >= CILEN_VOID && \
+      p[1] == CILEN_VOID && \
+      p[0] == opt) { \
+    len -= CILEN_VOID; \
+    INCPTR(CILEN_VOID, p); \
+    try.neg = 0; \
+    LCPDEBUG(LOG_INFO, ("lcp_rejci: void opt %d rejected\n", opt)); \
+  }
+#define REJCISHORT(opt, neg, val) \
+  if (go->neg && \
+      len >= CILEN_SHORT && \
+      p[1] == CILEN_SHORT && \
+      p[0] == opt) { \
+    len -= CILEN_SHORT; \
+    INCPTR(2, p); \
+    GETSHORT(cishort, p); \
+    /* Check rejected value. */ \
+    if (cishort != val) { \
+      goto bad; \
+    } \
+    try.neg = 0; \
+    LCPDEBUG(LOG_INFO, ("lcp_rejci: short opt %d rejected\n", opt)); \
+  }
+#define REJCICHAP(opt, neg, val, digest) \
+  if (go->neg && \
+      len >= CILEN_CHAP && \
+      p[1] == CILEN_CHAP && \
+      p[0] == opt) { \
+    len -= CILEN_CHAP; \
+    INCPTR(2, p); \
+    GETSHORT(cishort, p); \
+    GETCHAR(cichar, p); \
+    /* Check rejected value. */ \
+    if (cishort != val || cichar != digest) { \
+      goto bad; \
+    } \
+    try.neg = 0; \
+    try.neg_upap = 0; \
+    LCPDEBUG(LOG_INFO, ("lcp_rejci: chap opt %d rejected\n", opt)); \
+  }
+#define REJCILONG(opt, neg, val) \
+  if (go->neg && \
+      len >= CILEN_LONG && \
+      p[1] == CILEN_LONG && \
+      p[0] == opt) { \
+    len -= CILEN_LONG; \
+    INCPTR(2, p); \
+    GETLONG(cilong, p); \
+    /* Check rejected value. */ \
+    if (cilong != val) { \
+      goto bad; \
+    } \
+    try.neg = 0; \
+    LCPDEBUG(LOG_INFO, ("lcp_rejci: long opt %d rejected\n", opt)); \
+  }
+#define REJCILQR(opt, neg, val) \
+  if (go->neg && \
+      len >= CILEN_LQR && \
+      p[1] == CILEN_LQR && \
+      p[0] == opt) { \
+    len -= CILEN_LQR; \
+    INCPTR(2, p); \
+    GETSHORT(cishort, p); \
+    GETLONG(cilong, p); \
+    /* Check rejected value. */ \
+    if (cishort != PPP_LQR || cilong != val) { \
+      goto bad; \
+    } \
+    try.neg = 0; \
+    LCPDEBUG(LOG_INFO, ("lcp_rejci: LQR opt %d rejected\n", opt)); \
+  }
+#define REJCICBCP(opt, neg, val) \
+  if (go->neg && \
+      len >= CILEN_CBCP && \
+      p[1] == CILEN_CBCP && \
+      p[0] == opt) { \
+    len -= CILEN_CBCP; \
+    INCPTR(2, p); \
+    GETCHAR(cichar, p); \
+    /* Check rejected value. */ \
+    if (cichar != val) { \
+      goto bad; \
+    } \
+    try.neg = 0; \
+    LCPDEBUG(LOG_INFO, ("lcp_rejci: Callback opt %d rejected\n", opt)); \
+  }
+  
+  REJCISHORT(CI_MRU, neg_mru, go->mru);
+  REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
+  REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype);
+  if (!go->neg_chap) {
+    REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
+  }
+  REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
+  REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
+  REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
+  REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
+  REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
+  
+  /*
+   * If there are any remaining CIs, then this packet is bad.
+   */
+  if (len != 0) {
+    goto bad;
+  }
+  /*
+   * Now we can update state.
+   */
+  if (f->state != LS_OPENED) {
+    *go = try;
+  }
+  return 1;
+  
+bad:
+  LCPDEBUG(LOG_WARNING, ("lcp_rejci: received bad Reject!\n"));
+  return 0;
+}
+
+
+/*
+ * lcp_reqci - Check the peer's requested CIs and send appropriate response.
+ *
+ * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
+ * appropriately.  If reject_if_disagree is non-zero, doesn't return
+ * CONFNAK; returns CONFREJ if it can't return CONFACK.
+ */
+static int
+lcp_reqci(fsm *f, 
+          u_char *inp,    /* Requested CIs */
+          int *lenp,      /* Length of requested CIs */
+          int reject_if_disagree)
+{
+  lcp_options *go = &lcp_gotoptions[f->unit];
+  lcp_options *ho = &lcp_hisoptions[f->unit];
+  lcp_options *ao = &lcp_allowoptions[f->unit];
+  u_char *cip, *next;         /* Pointer to current and next CIs */
+  int cilen, citype;          /* Parsed len, type */
+  u_char cichar;              /* Parsed char value */
+  u_short cishort;            /* Parsed short value */
+  u32_t cilong;               /* Parse long value */
+  int rc = CONFACK;           /* Final packet return code */
+  int orc;                    /* Individual option return code */
+  u_char *p;                  /* Pointer to next char to parse */
+  u_char *rejp;               /* Pointer to next char in reject frame */
+  u_char *nakp;               /* Pointer to next char in Nak frame */
+  int l = *lenp;              /* Length left */
+#if TRACELCP > 0
+  char traceBuf[80];
+  size_t traceNdx = 0;
+#endif
+
+  /*
+   * Reset all his options.
+   */
+  BZERO(ho, sizeof(*ho));
+
+  /*
+   * Process all his options.
+   */
+  next = inp;
+  nakp = nak_buffer;
+  rejp = inp;
+  while (l) {
+    orc = CONFACK;      /* Assume success */
+    cip = p = next;     /* Remember begining of CI */
+    if (l < 2 ||        /* Not enough data for CI header or */
+        p[1] < 2 ||     /*  CI length too small or */
+        p[1] > l) {     /*  CI length too big? */
+      LCPDEBUG(LOG_WARNING, ("lcp_reqci: bad CI length!\n"));
+      orc = CONFREJ;    /* Reject bad CI */
+      cilen = l;        /* Reject till end of packet */
+      l = 0;            /* Don't loop again */
+      citype = 0;
+      goto endswitch;
+    }
+    GETCHAR(citype, p); /* Parse CI type */
+    GETCHAR(cilen, p);  /* Parse CI length */
+    l -= cilen;         /* Adjust remaining length */
+    next += cilen;      /* Step to next CI */
+
+    switch (citype) {   /* Check CI type */
+      case CI_MRU:
+        if (!ao->neg_mru) {    /* Allow option? */
+          LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject MRU - not allowed\n"));
+          orc = CONFREJ;    /* Reject CI */
+          break;
+        } else if (cilen != CILEN_SHORT) {  /* Check CI length */
+          LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject MRU - bad length\n"));
+          orc = CONFREJ;    /* Reject CI */
+          break;
+        }
+        GETSHORT(cishort, p);  /* Parse MRU */
+
+        /*
+         * He must be able to receive at least our minimum.
+         * No need to check a maximum.  If he sends a large number,
+         * we'll just ignore it.
+         */
+        if (cishort < PPP_MINMRU) {
+          LCPDEBUG(LOG_INFO, ("lcp_reqci: Nak - MRU too small\n"));
+          orc = CONFNAK;    /* Nak CI */
+          PUTCHAR(CI_MRU, nakp);
+          PUTCHAR(CILEN_SHORT, nakp);
+          PUTSHORT(PPP_MINMRU, nakp);  /* Give him a hint */
+          break;
+        }
+        ho->neg_mru = 1;    /* Remember he sent MRU */
+        ho->mru = cishort;    /* And remember value */
+#if TRACELCP > 0
+        snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MRU %d", cishort);
+        traceNdx = strlen(traceBuf);
+#endif
+        break;
+
+      case CI_ASYNCMAP:
+        if (!ao->neg_asyncmap) {
+          LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject ASYNCMAP not allowed\n"));
+          orc = CONFREJ;
+          break;
+        } else if (cilen != CILEN_LONG) {
+          LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject ASYNCMAP bad length\n"));
+          orc = CONFREJ;
+          break;
+        }
+        GETLONG(cilong, p);
+        
+        /*
+         * Asyncmap must have set at least the bits
+         * which are set in lcp_allowoptions[unit].asyncmap.
+         */
+        if ((ao->asyncmap & ~cilong) != 0) {
+          LCPDEBUG(LOG_INFO, ("lcp_reqci: Nak ASYNCMAP %lX missing %lX\n", 
+                    cilong, ao->asyncmap));
+          orc = CONFNAK;
+          PUTCHAR(CI_ASYNCMAP, nakp);
+          PUTCHAR(CILEN_LONG, nakp);
+          PUTLONG(ao->asyncmap | cilong, nakp);
+          break;
+        }
+        ho->neg_asyncmap = 1;
+        ho->asyncmap = cilong;
+#if TRACELCP > 0
+        snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ASYNCMAP=%lX", cilong);
+        traceNdx = strlen(traceBuf);
+#endif
+        break;
+
+      case CI_AUTHTYPE:
+        if (cilen < CILEN_SHORT) {
+          LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject AUTHTYPE missing arg\n"));
+          orc = CONFREJ;
+          break;
+        } else if (!(ao->neg_upap || ao->neg_chap)) {
+          /*
+           * Reject the option if we're not willing to authenticate.
+           */
+          LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject AUTHTYPE not allowed\n"));
+          orc = CONFREJ;
+          break;
+        }
+        GETSHORT(cishort, p);
+        
+        /*
+         * Authtype must be UPAP or CHAP.
+         *
+         * Note: if both ao->neg_upap and ao->neg_chap are set,
+         * and the peer sends a Configure-Request with two
+         * authenticate-protocol requests, one for CHAP and one
+         * for UPAP, then we will reject the second request.
+         * Whether we end up doing CHAP or UPAP depends then on
+         * the ordering of the CIs in the peer's Configure-Request.
+         */
+        
+        if (cishort == PPP_PAP) {
+          if (ho->neg_chap) {  /* we've already accepted CHAP */
+            LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE PAP already accepted\n"));
+            orc = CONFREJ;
+            break;
+          } else if (cilen != CILEN_SHORT) {
+            LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE PAP bad len\n"));
+            orc = CONFREJ;
+            break;
+          }
+          if (!ao->neg_upap) {  /* we don't want to do PAP */
+            LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE PAP not allowed\n"));
+            orc = CONFNAK;  /* NAK it and suggest CHAP */
+            PUTCHAR(CI_AUTHTYPE, nakp);
+            PUTCHAR(CILEN_CHAP, nakp);
+            PUTSHORT(PPP_CHAP, nakp);
+            PUTCHAR(ao->chap_mdtype, nakp);
+            break;
+          }
+          ho->neg_upap = 1;
+#if TRACELCP > 0
+          snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PAP (%X)", cishort);
+          traceNdx = strlen(traceBuf);
+#endif
+          break;
+        }
+        if (cishort == PPP_CHAP) {
+          if (ho->neg_upap) {  /* we've already accepted PAP */
+            LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE CHAP accepted PAP\n"));
+            orc = CONFREJ;
+            break;
+          } else if (cilen != CILEN_CHAP) {
+            LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE CHAP bad len\n"));
+            orc = CONFREJ;
+            break;
+          }
+          if (!ao->neg_chap) {  /* we don't want to do CHAP */
+            LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE CHAP not allowed\n"));
+            orc = CONFNAK;  /* NAK it and suggest PAP */
+            PUTCHAR(CI_AUTHTYPE, nakp);
+            PUTCHAR(CILEN_SHORT, nakp);
+            PUTSHORT(PPP_PAP, nakp);
+            break;
+          }
+          GETCHAR(cichar, p);  /* get digest type*/
+          if (cichar != CHAP_DIGEST_MD5
+#if MSCHAP_SUPPORT
+              && cichar != CHAP_MICROSOFT
+#endif
+          ) {
+            LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE CHAP digest=%d\n", (int)cichar));
+            orc = CONFNAK;
+            PUTCHAR(CI_AUTHTYPE, nakp);
+            PUTCHAR(CILEN_CHAP, nakp);
+            PUTSHORT(PPP_CHAP, nakp);
+            PUTCHAR(ao->chap_mdtype, nakp);
+            break;
+          }
+#if TRACELCP > 0
+          snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CHAP %X,%d", cishort, (int)cichar);
+          traceNdx = strlen(traceBuf);
+#endif
+          ho->chap_mdtype = cichar; /* save md type */
+          ho->neg_chap = 1;
+          break;
+        }
+        
+        /*
+         * We don't recognize the protocol they're asking for.
+         * Nak it with something we're willing to do.
+         * (At this point we know ao->neg_upap || ao->neg_chap.)
+         */
+        orc = CONFNAK;
+        PUTCHAR(CI_AUTHTYPE, nakp);
+        if (ao->neg_chap) {
+          LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE %d req CHAP\n", cishort));
+          PUTCHAR(CILEN_CHAP, nakp);
+          PUTSHORT(PPP_CHAP, nakp);
+          PUTCHAR(ao->chap_mdtype, nakp);
+        } else {
+          LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE %d req PAP\n", cishort));
+          PUTCHAR(CILEN_SHORT, nakp);
+          PUTSHORT(PPP_PAP, nakp);
+        }
+        break;
+      
+      case CI_QUALITY:
+        GETSHORT(cishort, p);
+        GETLONG(cilong, p);
+#if TRACELCP > 0
+        snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " QUALITY (%x %x)", cishort, (unsigned int) cilong);
+        traceNdx = strlen(traceBuf);
+#endif
+
+        if (!ao->neg_lqr ||
+            cilen != CILEN_LQR) {
+          orc = CONFREJ;
+          break;
+        }
+        
+        /*
+         * Check the protocol and the reporting period.
+         * XXX When should we Nak this, and what with?
+         */
+        if (cishort != PPP_LQR) {
+          orc = CONFNAK;
+          PUTCHAR(CI_QUALITY, nakp);
+          PUTCHAR(CILEN_LQR, nakp);
+          PUTSHORT(PPP_LQR, nakp);
+          PUTLONG(ao->lqr_period, nakp);
+          break;
+        }
+        break;
+      
+      case CI_MAGICNUMBER:
+        if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
+            cilen != CILEN_LONG) {
+          orc = CONFREJ;
+          break;
+        }
+        GETLONG(cilong, p);
+#if TRACELCP > 0
+        snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MAGICNUMBER (%lX)", cilong);
+        traceNdx = strlen(traceBuf);
+#endif
+
+        /*
+         * He must have a different magic number.
+         */
+        if (go->neg_magicnumber &&
+            cilong == go->magicnumber) {
+          cilong = magic();  /* Don't put magic() inside macro! */
+          orc = CONFNAK;
+          PUTCHAR(CI_MAGICNUMBER, nakp);
+          PUTCHAR(CILEN_LONG, nakp);
+          PUTLONG(cilong, nakp);
+          break;
+        }
+        ho->neg_magicnumber = 1;
+        ho->magicnumber = cilong;
+        break;
+      
+      
+      case CI_PCOMPRESSION:
+#if TRACELCP > 0
+        snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PCOMPRESSION");
+        traceNdx = strlen(traceBuf);
+#endif
+        if (!ao->neg_pcompression ||
+            cilen != CILEN_VOID) {
+          orc = CONFREJ;
+          break;
+        }
+        ho->neg_pcompression = 1;
+        break;
+      
+      case CI_ACCOMPRESSION:
+#if TRACELCP > 0
+        snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ACCOMPRESSION");
+        traceNdx = strlen(traceBuf);
+#endif
+        if (!ao->neg_accompression ||
+            cilen != CILEN_VOID) {
+          orc = CONFREJ;
+          break;
+        }
+        ho->neg_accompression = 1;
+        break;
+      
+      case CI_MRRU:
+#if TRACELCP > 0
+        snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_MRRU");
+        traceNdx = strlen(traceBuf);
+#endif
+        orc = CONFREJ;
+        break;
+      
+      case CI_SSNHF:
+#if TRACELCP > 0
+        snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_SSNHF");
+        traceNdx = strlen(traceBuf);
+#endif
+        orc = CONFREJ;
+        break;
+      
+      case CI_EPDISC:
+#if TRACELCP > 0
+        snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_EPDISC");
+        traceNdx = strlen(traceBuf);
+#endif
+        orc = CONFREJ;
+        break;
+      
+      default:
+#if TRACELCP
+        snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " unknown %d", citype);
+        traceNdx = strlen(traceBuf);
+#endif
+        orc = CONFREJ;
+        break;
+    }
+
+  endswitch:
+#if TRACELCP
+    if (traceNdx >= 80 - 32) {
+      LCPDEBUG(LOG_INFO, ("lcp_reqci: rcvd%s\n", traceBuf));
+      traceNdx = 0;
+    }
+#endif
+    if (orc == CONFACK && /* Good CI */
+        rc != CONFACK) {  /*  but prior CI wasnt? */
+      continue;           /* Don't send this one */
+    }
+
+    if (orc == CONFNAK) {     /* Nak this CI? */
+      if (reject_if_disagree  /* Getting fed up with sending NAKs? */
+          && citype != CI_MAGICNUMBER) {
+        orc = CONFREJ;        /* Get tough if so */
+      } else {
+        if (rc == CONFREJ) {  /* Rejecting prior CI? */
+          continue;           /* Don't send this one */
+        }
+        rc = CONFNAK;
+      }
+    }
+    if (orc == CONFREJ) {        /* Reject this CI */
+      rc = CONFREJ;
+      if (cip != rejp) {         /* Need to move rejected CI? */
+        BCOPY(cip, rejp, cilen); /* Move it */
+      }
+      INCPTR(cilen, rejp);       /* Update output pointer */
+    }
+  }
+
+  /*
+   * If we wanted to send additional NAKs (for unsent CIs), the
+   * code would go here.  The extra NAKs would go at *nakp.
+   * At present there are no cases where we want to ask the
+   * peer to negotiate an option.
+   */
+
+  switch (rc) {
+    case CONFACK:
+      *lenp = (int)(next - inp);
+      break;
+    case CONFNAK:
+      /*
+       * Copy the Nak'd options from the nak_buffer to the caller's buffer.
+       */
+      *lenp = (int)(nakp - nak_buffer);
+      BCOPY(nak_buffer, inp, *lenp);
+      break;
+    case CONFREJ:
+      *lenp = (int)(rejp - inp);
+      break;
+  }
+
+#if TRACELCP > 0
+  if (traceNdx > 0) {
+    LCPDEBUG(LOG_INFO, ("lcp_reqci: %s\n", traceBuf));
+  }
+#endif
+  LCPDEBUG(LOG_INFO, ("lcp_reqci: returning CONF%s.\n", CODENAME(rc)));
+  return (rc);      /* Return final code */
+}
+
+
+/*
+ * lcp_up - LCP has come UP.
+ */
+static void
+lcp_up(fsm *f)
+{
+  lcp_options *wo = &lcp_wantoptions[f->unit];
+  lcp_options *ho = &lcp_hisoptions[f->unit];
+  lcp_options *go = &lcp_gotoptions[f->unit];
+  lcp_options *ao = &lcp_allowoptions[f->unit];
+
+  if (!go->neg_magicnumber) {
+    go->magicnumber = 0;
+  }
+  if (!ho->neg_magicnumber) {
+    ho->magicnumber = 0;
+  }
+
+  /*
+   * Set our MTU to the smaller of the MTU we wanted and
+   * the MRU our peer wanted.  If we negotiated an MRU,
+   * set our MRU to the larger of value we wanted and
+   * the value we got in the negotiation.
+   */
+  ppp_send_config(f->unit, LWIP_MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)),
+                 (ho->neg_asyncmap? ho->asyncmap: 0xffffffffl),
+                  ho->neg_pcompression, ho->neg_accompression);
+  /*
+   * If the asyncmap hasn't been negotiated, we really should
+   * set the receive asyncmap to ffffffff, but we set it to 0
+   * for backwards contemptibility.
+   */
+  ppp_recv_config(f->unit, (go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU),
+                 (go->neg_asyncmap? go->asyncmap: 0x00000000),
+                  go->neg_pcompression, go->neg_accompression);
+
+  if (ho->neg_mru) {
+    peer_mru[f->unit] = ho->mru;
+  }
+
+  lcp_echo_lowerup(f->unit); /* Enable echo messages */
+
+  link_established(f->unit); /* The link is up; authenticate now */
+}
+
+
+/*
+ * lcp_down - LCP has gone DOWN.
+ *
+ * Alert other protocols.
+ */
+static void
+lcp_down(fsm *f)
+{
+  lcp_options *go = &lcp_gotoptions[f->unit];
+
+  lcp_echo_lowerdown(f->unit);
+
+  link_down(f->unit);
+
+  ppp_send_config(f->unit, PPP_MRU, 0xffffffffl, 0, 0);
+  ppp_recv_config(f->unit, PPP_MRU,
+                  (go->neg_asyncmap? go->asyncmap: 0x00000000),
+                   go->neg_pcompression, go->neg_accompression);
+  peer_mru[f->unit] = PPP_MRU;
+}
+
+
+/*
+ * lcp_starting - LCP needs the lower layer up.
+ */
+static void
+lcp_starting(fsm *f)
+{
+  link_required(f->unit); /* lwip: currently does nothing */
+}
+
+
+/*
+ * lcp_finished - LCP has finished with the lower layer.
+ */
+static void
+lcp_finished(fsm *f)
+{
+  link_terminated(f->unit); /* we are finished with the link */
+}
+
+
+#if PPP_ADDITIONAL_CALLBACKS
+/*
+ * print_string - print a readable representation of a string using
+ * printer.
+ */
+static void
+print_string( char *p, int len, void (*printer) (void *, char *, ...), void *arg)
+{
+  int c;
+  
+  printer(arg, "\"");
+  for (; len > 0; --len) {
+    c = *p++;
+    if (' ' <= c && c <= '~') {
+        if (c == '\\' || c == '"') {
+          printer(arg, "\\");
+        }
+        printer(arg, "%c", c);
+    } else {
+      switch (c) {
+        case '\n':
+          printer(arg, "\\n");
+          break;
+        case '\r':
+          printer(arg, "\\r");
+          break;
+        case '\t':
+          printer(arg, "\\t");
+          break;
+        default:
+          printer(arg, "\\%.3o", c);
+        }
+    }
+  }
+  printer(arg, "\"");
+}
+
+
+/*
+ * lcp_printpkt - print the contents of an LCP packet.
+ */
+static char *lcp_codenames[] = {
+  "ConfReq", "ConfAck", "ConfNak", "ConfRej",
+  "TermReq", "TermAck", "CodeRej", "ProtRej",
+  "EchoReq", "EchoRep", "DiscReq"
+};
+
+static int
+lcp_printpkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg)
+{
+  int code, id, len, olen;
+  u_char *pstart, *optend;
+  u_short cishort;
+  u32_t cilong;
+
+  if (plen < HEADERLEN) {
+    return 0;
+  }
+  pstart = p;
+  GETCHAR(code, p);
+  GETCHAR(id, p);
+  GETSHORT(len, p);
+  if (len < HEADERLEN || len > plen) {
+    return 0;
+  }
+
+  if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *)) {
+    printer(arg, " %s", lcp_codenames[code-1]);
+  } else {
+    printer(arg, " code=0x%x", code);
+  }
+  printer(arg, " id=0x%x", id);
+  len -= HEADERLEN;
+  switch (code) {
+    case CONFREQ:
+    case CONFACK:
+    case CONFNAK:
+    case CONFREJ:
+      /* print option list */
+      while (len >= 2) {
+        GETCHAR(code, p);
+        GETCHAR(olen, p);
+        p -= 2;
+        if (olen < 2 || olen > len) {
+          break;
+        }
+        printer(arg, " <");
+        len -= olen;
+        optend = p + olen;
+        switch (code) {
+          case CI_MRU:
+            if (olen == CILEN_SHORT) {
+              p += 2;
+              GETSHORT(cishort, p);
+              printer(arg, "mru %d", cishort);
+            }
+            break;
+          case CI_ASYNCMAP:
+            if (olen == CILEN_LONG) {
+              p += 2;
+              GETLONG(cilong, p);
+              printer(arg, "asyncmap 0x%lx", cilong);
+            }
+            break;
+          case CI_AUTHTYPE:
+            if (olen >= CILEN_SHORT) {
+              p += 2;
+              printer(arg, "auth ");
+              GETSHORT(cishort, p);
+              switch (cishort) {
+                case PPP_PAP:
+                  printer(arg, "pap");
+                  break;
+                case PPP_CHAP:
+                  printer(arg, "chap");
+                  break;
+                default:
+                  printer(arg, "0x%x", cishort);
+              }
+            }
+            break;
+          case CI_QUALITY:
+            if (olen >= CILEN_SHORT) {
+              p += 2;
+              printer(arg, "quality ");
+              GETSHORT(cishort, p);
+              switch (cishort) {
+                case PPP_LQR:
+                  printer(arg, "lqr");
+                  break;
+                default:
+                  printer(arg, "0x%x", cishort);
+              }
+            }
+            break;
+          case CI_CALLBACK:
+            if (olen >= CILEN_CHAR) {
+              p += 2;
+              printer(arg, "callback ");
+              GETSHORT(cishort, p);
+              switch (cishort) {
+                case CBCP_OPT:
+                  printer(arg, "CBCP");
+                  break;
+                default:
+                  printer(arg, "0x%x", cishort);
+              }
+            }
+            break;
+          case CI_MAGICNUMBER:
+            if (olen == CILEN_LONG) {
+              p += 2;
+              GETLONG(cilong, p);
+              printer(arg, "magic 0x%x", cilong);
+            }
+            break;
+          case CI_PCOMPRESSION:
+            if (olen == CILEN_VOID) {
+              p += 2;
+              printer(arg, "pcomp");
+            }
+            break;
+          case CI_ACCOMPRESSION:
+            if (olen == CILEN_VOID) {
+              p += 2;
+              printer(arg, "accomp");
+            }
+            break;
+        }
+        while (p < optend) {
+          GETCHAR(code, p);
+          printer(arg, " %.2x", code);
+        }
+        printer(arg, ">");
+      }
+      break;
+    
+    case TERMACK:
+    case TERMREQ:
+      if (len > 0 && *p >= ' ' && *p < 0x7f) {
+        printer(arg, " ");
+        print_string((char*)p, len, printer, arg);
+        p += len;
+        len = 0;
+      }
+      break;
+    
+    case ECHOREQ:
+    case ECHOREP:
+    case DISCREQ:
+      if (len >= 4) {
+        GETLONG(cilong, p);
+        printer(arg, " magic=0x%x", cilong);
+        p += 4;
+        len -= 4;
+      }
+      break;
+  }
+
+  /* print the rest of the bytes in the packet */
+  for (; len > 0; --len) {
+    GETCHAR(code, p);
+    printer(arg, " %.2x", code);
+  }
+
+  return (int)(p - pstart);
+}
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+
+/*
+ * Time to shut down the link because there is nothing out there.
+ */
+static void
+LcpLinkFailure (fsm *f)
+{
+  if (f->state == LS_OPENED) {
+    LCPDEBUG(LOG_INFO, ("No response to %d echo-requests\n", lcp_echos_pending));
+    LCPDEBUG(LOG_NOTICE, ("Serial link appears to be disconnected.\n"));
+    lcp_close(f->unit, "Peer not responding");
+  }
+}
+
+/*
+ * Timer expired for the LCP echo requests from this process.
+ */
+static void
+LcpEchoCheck (fsm *f)
+{
+  LcpSendEchoRequest (f);
+
+  /*
+   * Start the timer for the next interval.
+   */
+  LWIP_ASSERT("lcp_echo_timer_running == 0", lcp_echo_timer_running == 0);
+
+  TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
+  lcp_echo_timer_running = 1;
+}
+
+/*
+ * LcpEchoTimeout - Timer expired on the LCP echo
+ */
+static void
+LcpEchoTimeout (void *arg)
+{
+  if (lcp_echo_timer_running != 0) {
+    lcp_echo_timer_running = 0;
+    LcpEchoCheck ((fsm *) arg);
+  }
+}
+
+/*
+ * LcpEchoReply - LCP has received a reply to the echo
+ */
+static void
+lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len)
+{
+  u32_t magic;
+
+  LWIP_UNUSED_ARG(id);
+
+  /* Check the magic number - don't count replies from ourselves. */
+  if (len < 4) {
+    LCPDEBUG(LOG_WARNING, ("lcp: received short Echo-Reply, length %d\n", len));
+    return;
+  }
+  GETLONG(magic, inp);
+  if (lcp_gotoptions[f->unit].neg_magicnumber && magic == lcp_gotoptions[f->unit].magicnumber) {
+    LCPDEBUG(LOG_WARNING, ("appear to have received our own echo-reply!\n"));
+    return;
+  }
+
+  /* Reset the number of outstanding echo frames */
+  lcp_echos_pending = 0;
+}
+
+/*
+ * LcpSendEchoRequest - Send an echo request frame to the peer
+ */
+static void
+LcpSendEchoRequest (fsm *f)
+{
+  u32_t lcp_magic;
+  u_char pkt[4], *pktp;
+
+  /*
+   * Detect the failure of the peer at this point.
+   */
+  if (lcp_echo_fails != 0) {
+    if (lcp_echos_pending >= lcp_echo_fails) {
+      LcpLinkFailure(f);
+      lcp_echos_pending = 0;
+    }
+  }
+
+  /*
+   * Make and send the echo request frame.
+   */
+  if (f->state == LS_OPENED) {
+    lcp_magic = lcp_gotoptions[f->unit].magicnumber;
+    pktp = pkt;
+    PUTLONG(lcp_magic, pktp);
+    fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt));
+    ++lcp_echos_pending;
+  }
+}
+
+/*
+ * lcp_echo_lowerup - Start the timer for the LCP frame
+ */
+
+static void
+lcp_echo_lowerup (int unit)
+{
+  fsm *f = &lcp_fsm[unit];
+
+  /* Clear the parameters for generating echo frames */
+  lcp_echos_pending      = 0;
+  lcp_echo_number        = 0;
+  lcp_echo_timer_running = 0;
+
+  /* If a timeout interval is specified then start the timer */
+  if (lcp_echo_interval != 0) {
+    LcpEchoCheck (f);
+  }
+}
+
+/*
+ * lcp_echo_lowerdown - Stop the timer for the LCP frame
+ */
+
+static void
+lcp_echo_lowerdown (int unit)
+{
+  fsm *f = &lcp_fsm[unit];
+
+  if (lcp_echo_timer_running != 0) {
+    UNTIMEOUT (LcpEchoTimeout, f);
+    lcp_echo_timer_running = 0;
+  }
+}
+
+#endif /* PPP_SUPPORT */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/lcp.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/lcp.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/lcp.h	(revision 164)
@@ -0,0 +1,151 @@
+/*****************************************************************************
+* lcp.h - Network Link Control Protocol header file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
+*   Original derived from BSD codes.
+*****************************************************************************/
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef LCP_H
+#define LCP_H
+/*
+ * Options.
+ */
+#define CI_MRU           1  /* Maximum Receive Unit */
+#define CI_ASYNCMAP      2  /* Async Control Character Map */
+#define CI_AUTHTYPE      3  /* Authentication Type */
+#define CI_QUALITY       4  /* Quality Protocol */
+#define CI_MAGICNUMBER   5  /* Magic Number */
+#define CI_PCOMPRESSION  7  /* Protocol Field Compression */
+#define CI_ACCOMPRESSION 8  /* Address/Control Field Compression */
+#define CI_CALLBACK      13 /* callback */
+#define CI_MRRU          17 /* max reconstructed receive unit; multilink */
+#define CI_SSNHF         18 /* short sequence numbers for multilink */
+#define CI_EPDISC        19 /* endpoint discriminator */
+
+/*
+ * LCP-specific packet types (code numbers).
+ */
+#define PROTREJ          8  /* Protocol Reject */
+#define ECHOREQ          9  /* Echo Request */
+#define ECHOREP          10 /* Echo Reply */
+#define DISCREQ          11 /* Discard Request */
+#define CBCP_OPT         6  /* Use callback control protocol */
+
+/*
+ * The state of options is described by an lcp_options structure.
+ */
+typedef struct lcp_options {
+    u_int passive           : 1; /* Don't die if we don't get a response */
+    u_int silent            : 1; /* Wait for the other end to start first */
+    u_int restart           : 1; /* Restart vs. exit after close */
+    u_int neg_mru           : 1; /* Negotiate the MRU? */
+    u_int neg_asyncmap      : 1; /* Negotiate the async map? */
+    u_int neg_upap          : 1; /* Ask for UPAP authentication? */
+    u_int neg_chap          : 1; /* Ask for CHAP authentication? */
+    u_int neg_magicnumber   : 1; /* Ask for magic number? */
+    u_int neg_pcompression  : 1; /* HDLC Protocol Field Compression? */
+    u_int neg_accompression : 1; /* HDLC Address/Control Field Compression? */
+    u_int neg_lqr           : 1; /* Negotiate use of Link Quality Reports */
+    u_int neg_cbcp          : 1; /* Negotiate use of CBCP */
+#ifdef PPP_MULTILINK
+    u_int neg_mrru          : 1; /* Negotiate multilink MRRU */
+    u_int neg_ssnhf         : 1; /* Negotiate short sequence numbers */
+    u_int neg_endpoint      : 1; /* Negotiate endpoint discriminator */
+#endif
+    u_short mru;                 /* Value of MRU */
+#ifdef PPP_MULTILINK
+    u_short mrru;                /* Value of MRRU, and multilink enable */
+#endif
+    u_char chap_mdtype;          /* which MD type (hashing algorithm) */
+    u32_t asyncmap;              /* Value of async map */
+    u32_t magicnumber;
+    int numloops;                /* Number of loops during magic number neg. */
+    u32_t lqr_period;            /* Reporting period for LQR 1/100ths second */
+#ifdef PPP_MULTILINK
+    struct epdisc endpoint;      /* endpoint discriminator */
+#endif
+} lcp_options;
+
+/*
+ * Values for phase from BSD pppd.h based on RFC 1661.
+ */
+typedef enum {
+  PHASE_DEAD = 0,
+  PHASE_INITIALIZE,
+  PHASE_ESTABLISH,
+  PHASE_AUTHENTICATE,
+  PHASE_CALLBACK,
+  PHASE_NETWORK,
+  PHASE_TERMINATE
+} LinkPhase;
+
+
+
+extern LinkPhase lcp_phase[NUM_PPP]; /* Phase of link session (RFC 1661) */
+extern lcp_options lcp_wantoptions[];
+extern lcp_options lcp_gotoptions[];
+extern lcp_options lcp_allowoptions[];
+extern lcp_options lcp_hisoptions[];
+extern ext_accm xmit_accm[];
+
+
+void lcp_init     (int);
+void lcp_open     (int);
+void lcp_close    (int, char *);
+void lcp_lowerup  (int);
+void lcp_lowerdown(int);
+void lcp_sprotrej (int, u_char *, int); /* send protocol reject */
+
+extern struct protent lcp_protent;
+
+/* Default number of times we receive our magic number from the peer
+   before deciding the link is looped-back. */
+#define DEFLOOPBACKFAIL 10
+
+#endif /* LCP_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/magic.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/magic.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/magic.c	(revision 164)
@@ -0,0 +1,80 @@
+/*****************************************************************************
+* magic.c - Network Random Number Generator program file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 by Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Original based on BSD magic.c.
+*****************************************************************************/
+/*
+ * magic.c - PPP Magic Number routines.
+ *
+ * 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.
+ */
+
+#include "lwip/opt.h"
+
+#if PPP_SUPPORT
+
+#include "ppp_impl.h"
+#include "randm.h"
+#include "magic.h"
+
+
+/*
+ * magicInit - Initialize the magic number generator.
+ *
+ * Since we use another random number generator that has its own
+ * initialization, we do nothing here.
+ */
+void magicInit()
+{
+  return;
+}
+
+/*
+ * magic - Returns the next magic number.
+ */
+u32_t magic()
+{
+  return avRandom();
+}
+
+#endif /* PPP_SUPPORT */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/magic.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/magic.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/magic.h	(revision 164)
@@ -0,0 +1,63 @@
+/*****************************************************************************
+* magic.h - Network Random Number Generator header file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
+*   Original derived from BSD codes.
+*****************************************************************************/
+/*
+ * magic.h - PPP Magic Number 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.
+ *
+ * $Id$
+ */
+
+#ifndef MAGIC_H
+#define MAGIC_H
+
+/* Initialize the magic number generator */
+void  magicInit(void);
+
+/* Returns the next magic number */
+u32_t magic(void);
+
+#endif /* MAGIC_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/md5.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/md5.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/md5.c	(revision 164)
@@ -0,0 +1,320 @@
+/*
+ ***********************************************************************
+ ** md5.c -- the source code for MD5 routines                         **
+ ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
+ ** Created: 2/17/90 RLR                                              **
+ ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
+ ***********************************************************************
+ */
+
+/*
+ ***********************************************************************
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
+ **                                                                   **
+ ** License to copy and use this software is granted provided that    **
+ ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
+ ** Digest Algorithm" in all material mentioning or referencing this  **
+ ** software or this function.                                        **
+ **                                                                   **
+ ** License is also granted to make and use derivative works          **
+ ** provided that such works are identified as "derived from the RSA  **
+ ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
+ ** material mentioning or referencing the derived work.              **
+ **                                                                   **
+ ** RSA Data Security, Inc. makes no representations concerning       **
+ ** either the merchantability of this software or the suitability    **
+ ** of this software for any particular purpose.  It is provided "as  **
+ ** is" without express or implied warranty of any kind.              **
+ **                                                                   **
+ ** These notices must be retained in any copies of any part of this  **
+ ** documentation and/or software.                                    **
+ ***********************************************************************
+ */
+
+#include "lwip/opt.h"
+
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#if CHAP_SUPPORT || MD5_SUPPORT
+
+#include "ppp_impl.h"
+#include "pppdebug.h"
+
+#include "md5.h"
+
+#include <string.h>
+
+/*
+ ***********************************************************************
+ **  Message-digest routines:                                         **
+ **  To form the message digest for a message M                       **
+ **    (1) Initialize a context buffer mdContext using MD5Init        **
+ **    (2) Call MD5Update on mdContext and M                          **
+ **    (3) Call MD5Final on mdContext                                 **
+ **  The message digest is now in mdContext->digest[0...15]           **
+ ***********************************************************************
+ */
+
+/* forward declaration */
+static void Transform (u32_t *buf, u32_t *in);
+
+static unsigned char PADDING[64] = {
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* F, G, H and I are basic MD5 functions */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
+/* Rotation is separate from addition to prevent recomputation */
+#define FF(a, b, c, d, x, s, ac) \
+  {(a) += F ((b), (c), (d)) + (x) + (u32_t)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+#define GG(a, b, c, d, x, s, ac) \
+  {(a) += G ((b), (c), (d)) + (x) + (u32_t)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+#define HH(a, b, c, d, x, s, ac) \
+  {(a) += H ((b), (c), (d)) + (x) + (u32_t)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+#define II(a, b, c, d, x, s, ac) \
+  {(a) += I ((b), (c), (d)) + (x) + (u32_t)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+
+#ifdef __STDC__
+#define UL(x) x##UL
+#else
+#ifdef WIN32
+#define UL(x) x##UL
+#else
+#define UL(x) x
+#endif
+#endif
+
+/* The routine MD5Init initializes the message-digest context
+   mdContext. All fields are set to zero.
+ */
+void
+MD5Init (MD5_CTX *mdContext)
+{
+  mdContext->i[0] = mdContext->i[1] = (u32_t)0;
+
+  /* Load magic initialization constants. */
+  mdContext->buf[0] = (u32_t)0x67452301UL;
+  mdContext->buf[1] = (u32_t)0xefcdab89UL;
+  mdContext->buf[2] = (u32_t)0x98badcfeUL;
+  mdContext->buf[3] = (u32_t)0x10325476UL;
+}
+
+/* The routine MD5Update updates the message-digest context to
+   account for the presence of each of the characters inBuf[0..inLen-1]
+   in the message whose digest is being computed.
+ */
+void
+MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
+{
+  u32_t in[16];
+  int mdi;
+  unsigned int i, ii;
+
+#if 0
+  PPPDEBUG(LOG_INFO, ("MD5Update: %u:%.*H\n", inLen, LWIP_MIN(inLen, 20) * 2, inBuf));
+  PPPDEBUG(LOG_INFO, ("MD5Update: %u:%s\n", inLen, inBuf));
+#endif
+  
+  /* compute number of bytes mod 64 */
+  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+  /* update number of bits */
+  if ((mdContext->i[0] + ((u32_t)inLen << 3)) < mdContext->i[0]) {
+    mdContext->i[1]++;
+  }
+  mdContext->i[0] += ((u32_t)inLen << 3);
+  mdContext->i[1] += ((u32_t)inLen >> 29);
+
+  while (inLen--) {
+    /* add new character to buffer, increment mdi */
+    mdContext->in[mdi++] = *inBuf++;
+
+    /* transform if necessary */
+    if (mdi == 0x40) {
+      for (i = 0, ii = 0; i < 16; i++, ii += 4) {
+        in[i] = (((u32_t)mdContext->in[ii+3]) << 24) |
+                (((u32_t)mdContext->in[ii+2]) << 16) |
+                (((u32_t)mdContext->in[ii+1]) << 8)  |
+                ((u32_t)mdContext->in[ii]);
+      }
+      Transform (mdContext->buf, in);
+      mdi = 0;
+    }
+  }
+}
+
+/* The routine MD5Final terminates the message-digest computation and
+   ends with the desired message digest in mdContext->digest[0...15].
+ */
+void
+MD5Final (unsigned char hash[], MD5_CTX *mdContext)
+{
+  u32_t in[16];
+  int mdi;
+  unsigned int i, ii;
+  unsigned int padLen;
+
+  /* save number of bits */
+  in[14] = mdContext->i[0];
+  in[15] = mdContext->i[1];
+
+  /* compute number of bytes mod 64 */
+  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+  /* pad out to 56 mod 64 */
+  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
+  MD5Update (mdContext, PADDING, padLen);
+
+  /* append length in bits and transform */
+  for (i = 0, ii = 0; i < 14; i++, ii += 4) {
+    in[i] = (((u32_t)mdContext->in[ii+3]) << 24) |
+            (((u32_t)mdContext->in[ii+2]) << 16) |
+            (((u32_t)mdContext->in[ii+1]) << 8)  |
+            ((u32_t)mdContext->in[ii]);
+  }
+  Transform (mdContext->buf, in);
+
+  /* store buffer in digest */
+  for (i = 0, ii = 0; i < 4; i++, ii += 4) {
+    mdContext->digest[ii]   = (unsigned char)(mdContext->buf[i] & 0xFF);
+    mdContext->digest[ii+1] =
+      (unsigned char)((mdContext->buf[i] >> 8)  & 0xFF);
+    mdContext->digest[ii+2] =
+      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
+    mdContext->digest[ii+3] =
+      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
+  }
+  SMEMCPY(hash, mdContext->digest, 16);
+}
+
+/* Basic MD5 step. Transforms buf based on in.
+ */
+static void
+Transform (u32_t *buf, u32_t *in)
+{
+  u32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3];
+
+  /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+  FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
+  FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
+  FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
+  FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
+  FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
+  FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
+  FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
+  FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
+  FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
+  FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
+  FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
+  FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
+  FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
+  FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
+  FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
+  FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
+
+  /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+  GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
+  GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
+  GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
+  GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
+  GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
+  GG ( d, a, b, c, in[10], S22, UL(  38016083)); /* 22 */
+  GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
+  GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
+  GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
+  GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
+  GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
+  GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
+  GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
+  GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
+  GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
+  GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
+
+  /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+  HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
+  HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
+  HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
+  HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
+  HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
+  HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
+  HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
+  HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
+  HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
+  HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
+  HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
+  HH ( b, c, d, a, in[ 6], S34, UL(  76029189)); /* 44 */
+  HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
+  HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
+  HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
+  HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
+
+  /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+  II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
+  II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
+  II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
+  II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
+  II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
+  II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
+  II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
+  II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
+  II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
+  II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
+  II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
+  II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
+  II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
+  II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
+  II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
+  II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
+
+  buf[0] += a;
+  buf[1] += b;
+  buf[2] += c;
+  buf[3] += d;
+}
+
+#endif /* CHAP_SUPPORT || MD5_SUPPORT */
+
+#endif /* PPP_SUPPORT */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/md5.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/md5.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/md5.h	(revision 164)
@@ -0,0 +1,55 @@
+/*
+ ***********************************************************************
+ ** md5.h -- header file for implementation of MD5                    **
+ ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
+ ** Created: 2/17/90 RLR                                              **
+ ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version               **
+ ** Revised (for MD5): RLR 4/27/91                                    **
+ **   -- G modified to have y&~z instead of y&z                       **
+ **   -- FF, GG, HH modified to add in last register done             **
+ **   -- Access pattern: round 2 works mod 5, round 3 works mod 3     **
+ **   -- distinct additive constant for each step                     **
+ **   -- round 4 added, working mod 7                                 **
+ ***********************************************************************
+ */
+
+/*
+ ***********************************************************************
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
+ **                                                                   **
+ ** License to copy and use this software is granted provided that    **
+ ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
+ ** Digest Algorithm" in all material mentioning or referencing this  **
+ ** software or this function.                                        **
+ **                                                                   **
+ ** License is also granted to make and use derivative works          **
+ ** provided that such works are identified as "derived from the RSA  **
+ ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
+ ** material mentioning or referencing the derived work.              **
+ **                                                                   **
+ ** RSA Data Security, Inc. makes no representations concerning       **
+ ** either the merchantability of this software or the suitability    **
+ ** of this software for any particular purpose.  It is provided "as  **
+ ** is" without express or implied warranty of any kind.              **
+ **                                                                   **
+ ** These notices must be retained in any copies of any part of this  **
+ ** documentation and/or software.                                    **
+ ***********************************************************************
+ */
+
+#ifndef MD5_H
+#define MD5_H
+
+/* Data structure for MD5 (Message-Digest) computation */
+typedef struct {
+  u32_t i[2];               /* number of _bits_ handled mod 2^64 */
+  u32_t buf[4];             /* scratch buffer */
+  unsigned char in[64];     /* input buffer */
+  unsigned char digest[16]; /* actual digest after MD5Final call */
+} MD5_CTX;
+
+void MD5Init  ( MD5_CTX *mdContext);
+void MD5Update( MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen);
+void MD5Final ( unsigned char hash[], MD5_CTX *mdContext);
+
+#endif /* MD5_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/pap.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/pap.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/pap.c	(revision 164)
@@ -0,0 +1,628 @@
+/*****************************************************************************
+* pap.c - Network Password Authentication Protocol program file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 by Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-12-12 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Original.
+*****************************************************************************/
+/*
+ * 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.
+ */
+
+#include "lwip/opt.h"
+
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "ppp_impl.h"
+#include "pppdebug.h"
+
+#include "auth.h"
+#include "pap.h"
+
+#include <string.h>
+
+#if 0 /* UNUSED */
+static bool hide_password = 1;
+
+/*
+ * Command-line options.
+ */
+static option_t pap_option_list[] = {
+    { "hide-password", o_bool, &hide_password,
+      "Don't output passwords to log", 1 },
+    { "show-password", o_bool, &hide_password,
+      "Show password string in debug log messages", 0 },
+    { "pap-restart", o_int, &upap[0].us_timeouttime,
+      "Set retransmit timeout for PAP" },
+    { "pap-max-authreq", o_int, &upap[0].us_maxtransmits,
+      "Set max number of transmissions for auth-reqs" },
+    { "pap-timeout", o_int, &upap[0].us_reqtimeout,
+      "Set time limit for peer PAP authentication" },
+    { NULL }
+};
+#endif
+
+/*
+ * Protocol entry points.
+ */
+static void upap_init      (int);
+static void upap_lowerup   (int);
+static void upap_lowerdown (int);
+static void upap_input     (int, u_char *, int);
+static void upap_protrej   (int);
+#if PPP_ADDITIONAL_CALLBACKS
+static int  upap_printpkt (u_char *, int, void (*)(void *, char *, ...), void *);
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+
+struct protent pap_protent = {
+  PPP_PAP,
+  upap_init,
+  upap_input,
+  upap_protrej,
+  upap_lowerup,
+  upap_lowerdown,
+  NULL,
+  NULL,
+#if PPP_ADDITIONAL_CALLBACKS
+  upap_printpkt,
+  NULL,
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+  1,
+  "PAP",
+#if PPP_ADDITIONAL_CALLBACKS
+  NULL,
+  NULL,
+  NULL
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+};
+
+upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */
+
+static void upap_timeout   (void *);
+static void upap_reqtimeout(void *);
+static void upap_rauthreq  (upap_state *, u_char *, u_char, int);
+static void upap_rauthack  (upap_state *, u_char *, int, int);
+static void upap_rauthnak  (upap_state *, u_char *, int, int);
+static void upap_sauthreq  (upap_state *);
+static void upap_sresp     (upap_state *, u_char, u_char, char *, int);
+
+
+/*
+ * upap_init - Initialize a UPAP unit.
+ */
+static void
+upap_init(int unit)
+{
+  upap_state *u = &upap[unit];
+
+  UPAPDEBUG(LOG_INFO, ("upap_init: %d\n", unit));
+  u->us_unit         = unit;
+  u->us_user         = NULL;
+  u->us_userlen      = 0;
+  u->us_passwd       = NULL;
+  u->us_passwdlen    = 0;
+  u->us_clientstate  = UPAPCS_INITIAL;
+  u->us_serverstate  = UPAPSS_INITIAL;
+  u->us_id           = 0;
+  u->us_timeouttime  = UPAP_DEFTIMEOUT;
+  u->us_maxtransmits = 10;
+  u->us_reqtimeout   = UPAP_DEFREQTIME;
+}
+
+/*
+ * upap_authwithpeer - Authenticate us with our peer (start client).
+ *
+ * Set new state and send authenticate's.
+ */
+void
+upap_authwithpeer(int unit, char *user, char *password)
+{
+  upap_state *u = &upap[unit];
+
+  UPAPDEBUG(LOG_INFO, ("upap_authwithpeer: %d user=%s password=%s s=%d\n",
+             unit, user, password, u->us_clientstate));
+
+  /* Save the username and password we're given */
+  u->us_user = user;
+  u->us_userlen = (int)strlen(user);
+  u->us_passwd = password;
+  u->us_passwdlen = (int)strlen(password);
+
+  u->us_transmits = 0;
+
+  /* Lower layer up yet? */
+  if (u->us_clientstate == UPAPCS_INITIAL ||
+      u->us_clientstate == UPAPCS_PENDING) {
+    u->us_clientstate = UPAPCS_PENDING;
+    return;
+  }
+
+  upap_sauthreq(u);      /* Start protocol */
+}
+
+
+/*
+ * upap_authpeer - Authenticate our peer (start server).
+ *
+ * Set new state.
+ */
+void
+upap_authpeer(int unit)
+{
+  upap_state *u = &upap[unit];
+
+  /* Lower layer up yet? */
+  if (u->us_serverstate == UPAPSS_INITIAL ||
+      u->us_serverstate == UPAPSS_PENDING) {
+    u->us_serverstate = UPAPSS_PENDING;
+    return;
+  }
+
+  u->us_serverstate = UPAPSS_LISTEN;
+  if (u->us_reqtimeout > 0) {
+    TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
+  }
+}
+
+/*
+ * upap_timeout - Retransmission timer for sending auth-reqs expired.
+ */
+static void
+upap_timeout(void *arg)
+{
+  upap_state *u = (upap_state *) arg;
+
+  UPAPDEBUG(LOG_INFO, ("upap_timeout: %d timeout %d expired s=%d\n", 
+        u->us_unit, u->us_timeouttime, u->us_clientstate));
+
+  if (u->us_clientstate != UPAPCS_AUTHREQ) {
+    UPAPDEBUG(LOG_INFO, ("upap_timeout: not in AUTHREQ state!\n"));
+    return;
+  }
+
+  if (u->us_transmits >= u->us_maxtransmits) {
+    /* give up in disgust */
+    UPAPDEBUG(LOG_ERR, ("No response to PAP authenticate-requests\n"));
+    u->us_clientstate = UPAPCS_BADAUTH;
+    auth_withpeer_fail(u->us_unit, PPP_PAP);
+    return;
+  }
+
+  upap_sauthreq(u);    /* Send Authenticate-Request and set upap timeout*/
+}
+
+
+/*
+ * upap_reqtimeout - Give up waiting for the peer to send an auth-req.
+ */
+static void
+upap_reqtimeout(void *arg)
+{
+  upap_state *u = (upap_state *) arg;
+
+  if (u->us_serverstate != UPAPSS_LISTEN) {
+    return; /* huh?? */
+  }
+
+  auth_peer_fail(u->us_unit, PPP_PAP);
+  u->us_serverstate = UPAPSS_BADAUTH;
+}
+
+
+/*
+ * upap_lowerup - The lower layer is up.
+ *
+ * Start authenticating if pending.
+ */
+static void
+upap_lowerup(int unit)
+{
+  upap_state *u = &upap[unit];
+
+  UPAPDEBUG(LOG_INFO, ("upap_lowerup: init %d clientstate s=%d\n", unit, u->us_clientstate));
+
+  if (u->us_clientstate == UPAPCS_INITIAL) {
+    u->us_clientstate = UPAPCS_CLOSED;
+  } else if (u->us_clientstate == UPAPCS_PENDING) {
+    upap_sauthreq(u);  /* send an auth-request */
+    /* now client state is UPAPCS__AUTHREQ */
+  }
+
+  if (u->us_serverstate == UPAPSS_INITIAL) {
+    u->us_serverstate = UPAPSS_CLOSED;
+  } else if (u->us_serverstate == UPAPSS_PENDING) {
+    u->us_serverstate = UPAPSS_LISTEN;
+    if (u->us_reqtimeout > 0) {
+      TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
+    }
+  }
+}
+
+
+/*
+ * upap_lowerdown - The lower layer is down.
+ *
+ * Cancel all timeouts.
+ */
+static void
+upap_lowerdown(int unit)
+{
+  upap_state *u = &upap[unit];
+
+  UPAPDEBUG(LOG_INFO, ("upap_lowerdown: %d s=%d\n", unit, u->us_clientstate));
+
+  if (u->us_clientstate == UPAPCS_AUTHREQ) { /* Timeout pending? */
+    UNTIMEOUT(upap_timeout, u);    /* Cancel timeout */
+  }
+  if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0) {
+    UNTIMEOUT(upap_reqtimeout, u);
+  }
+
+  u->us_clientstate = UPAPCS_INITIAL;
+  u->us_serverstate = UPAPSS_INITIAL;
+}
+
+
+/*
+ * upap_protrej - Peer doesn't speak this protocol.
+ *
+ * This shouldn't happen.  In any case, pretend lower layer went down.
+ */
+static void
+upap_protrej(int unit)
+{
+  upap_state *u = &upap[unit];
+
+  if (u->us_clientstate == UPAPCS_AUTHREQ) {
+    UPAPDEBUG(LOG_ERR, ("PAP authentication failed due to protocol-reject\n"));
+    auth_withpeer_fail(unit, PPP_PAP);
+  }
+  if (u->us_serverstate == UPAPSS_LISTEN) {
+    UPAPDEBUG(LOG_ERR, ("PAP authentication of peer failed (protocol-reject)\n"));
+    auth_peer_fail(unit, PPP_PAP);
+  }
+  upap_lowerdown(unit);
+}
+
+
+/*
+ * upap_input - Input UPAP packet.
+ */
+static void
+upap_input(int unit, u_char *inpacket, int l)
+{
+  upap_state *u = &upap[unit];
+  u_char *inp;
+  u_char code, id;
+  int len;
+
+  /*
+   * Parse header (code, id and length).
+   * If packet too short, drop it.
+   */
+  inp = inpacket;
+  if (l < (int)UPAP_HEADERLEN) {
+    UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short header.\n"));
+    return;
+  }
+  GETCHAR(code, inp);
+  GETCHAR(id, inp);
+  GETSHORT(len, inp);
+  if (len < (int)UPAP_HEADERLEN) {
+    UPAPDEBUG(LOG_INFO, ("pap_input: rcvd illegal length.\n"));
+    return;
+  }
+  if (len > l) {
+    UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short packet.\n"));
+    return;
+  }
+  len -= UPAP_HEADERLEN;
+
+  /*
+   * Action depends on code.
+   */
+  switch (code) {
+    case UPAP_AUTHREQ:
+      upap_rauthreq(u, inp, id, len);
+      break;
+
+    case UPAP_AUTHACK:
+      upap_rauthack(u, inp, id, len);
+      break;
+
+    case UPAP_AUTHNAK:
+      upap_rauthnak(u, inp, id, len);
+      break;
+
+    default:        /* XXX Need code reject */
+      UPAPDEBUG(LOG_INFO, ("pap_input: UNHANDLED default: code: %d, id: %d, len: %d.\n", code, id, len));
+      break;
+  }
+}
+
+
+/*
+ * upap_rauth - Receive Authenticate.
+ */
+static void
+upap_rauthreq(upap_state *u, u_char *inp, u_char id, int len)
+{
+  u_char ruserlen, rpasswdlen;
+  char *ruser, *rpasswd;
+  u_char retcode;
+  char *msg;
+  int msglen;
+
+  UPAPDEBUG(LOG_INFO, ("pap_rauth: Rcvd id %d.\n", id));
+
+  if (u->us_serverstate < UPAPSS_LISTEN) {
+    return;
+  }
+
+  /*
+   * If we receive a duplicate authenticate-request, we are
+   * supposed to return the same status as for the first request.
+   */
+  if (u->us_serverstate == UPAPSS_OPEN) {
+    upap_sresp(u, UPAP_AUTHACK, id, "", 0);  /* return auth-ack */
+    return;
+  }
+  if (u->us_serverstate == UPAPSS_BADAUTH) {
+    upap_sresp(u, UPAP_AUTHNAK, id, "", 0);  /* return auth-nak */
+    return;
+  }
+
+  /*
+   * Parse user/passwd.
+   */
+  if (len < (int)sizeof (u_char)) {
+    UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
+    return;
+  }
+  GETCHAR(ruserlen, inp);
+  len -= sizeof (u_char) + ruserlen + sizeof (u_char);
+  if (len < 0) {
+    UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
+    return;
+  }
+  ruser = (char *) inp;
+  INCPTR(ruserlen, inp);
+  GETCHAR(rpasswdlen, inp);
+  if (len < rpasswdlen) {
+    UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
+    return;
+  }
+  rpasswd = (char *) inp;
+
+  /*
+   * Check the username and password given.
+   */
+  retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen);
+  /* lwip: currently retcode is always UPAP_AUTHACK */
+  BZERO(rpasswd, rpasswdlen);
+
+  upap_sresp(u, retcode, id, msg, msglen);
+
+  if (retcode == UPAP_AUTHACK) {
+    u->us_serverstate = UPAPSS_OPEN;
+    auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);
+  } else {
+    u->us_serverstate = UPAPSS_BADAUTH;
+    auth_peer_fail(u->us_unit, PPP_PAP);
+  }
+
+  if (u->us_reqtimeout > 0) {
+    UNTIMEOUT(upap_reqtimeout, u);
+  }
+}
+
+
+/*
+ * upap_rauthack - Receive Authenticate-Ack.
+ */
+static void
+upap_rauthack(upap_state *u, u_char *inp, int id, int len)
+{
+  u_char msglen;
+  char *msg;
+
+  LWIP_UNUSED_ARG(id);
+
+  UPAPDEBUG(LOG_INFO, ("pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate));
+
+  if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */
+    UPAPDEBUG(LOG_INFO, ("pap_rauthack: us_clientstate != UPAPCS_AUTHREQ\n"));
+    return;
+  }
+
+  /*
+   * Parse message.
+   */
+  if (len < (int)sizeof (u_char)) {
+    UPAPDEBUG(LOG_INFO, ("pap_rauthack: ignoring missing msg-length.\n"));
+  } else {
+    GETCHAR(msglen, inp);
+    if (msglen > 0) {
+      len -= sizeof (u_char);
+      if (len < msglen) {
+        UPAPDEBUG(LOG_INFO, ("pap_rauthack: rcvd short packet.\n"));
+        return;
+      }
+      msg = (char *) inp;
+      PRINTMSG(msg, msglen);
+    }
+  }
+  UNTIMEOUT(upap_timeout, u);    /* Cancel timeout */
+  u->us_clientstate = UPAPCS_OPEN;
+
+  auth_withpeer_success(u->us_unit, PPP_PAP);
+}
+
+
+/*
+ * upap_rauthnak - Receive Authenticate-Nak.
+ */
+static void
+upap_rauthnak(upap_state *u, u_char *inp, int id, int len)
+{
+  u_char msglen;
+  char *msg;
+
+  LWIP_UNUSED_ARG(id);
+
+  UPAPDEBUG(LOG_INFO, ("pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate));
+
+  if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */
+    return;
+  }
+
+  /*
+   * Parse message.
+   */
+  if (len < sizeof (u_char)) {
+    UPAPDEBUG(LOG_INFO, ("pap_rauthnak: ignoring missing msg-length.\n"));
+  } else {
+    GETCHAR(msglen, inp);
+    if(msglen > 0) {
+      len -= sizeof (u_char);
+      if (len < msglen) {
+        UPAPDEBUG(LOG_INFO, ("pap_rauthnak: rcvd short packet.\n"));
+        return;
+      }
+      msg = (char *) inp;
+      PRINTMSG(msg, msglen);
+    }
+  }
+
+  u->us_clientstate = UPAPCS_BADAUTH;
+
+  UPAPDEBUG(LOG_ERR, ("PAP authentication failed\n"));
+  auth_withpeer_fail(u->us_unit, PPP_PAP);
+}
+
+
+/*
+ * upap_sauthreq - Send an Authenticate-Request.
+ */
+static void
+upap_sauthreq(upap_state *u)
+{
+  u_char *outp;
+  int outlen;
+
+  outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) 
+         + u->us_userlen + u->us_passwdlen;
+  outp = outpacket_buf[u->us_unit];
+
+  MAKEHEADER(outp, PPP_PAP);
+
+  PUTCHAR(UPAP_AUTHREQ, outp);
+  PUTCHAR(++u->us_id, outp);
+  PUTSHORT(outlen, outp);
+  PUTCHAR(u->us_userlen, outp);
+  BCOPY(u->us_user, outp, u->us_userlen);
+  INCPTR(u->us_userlen, outp);
+  PUTCHAR(u->us_passwdlen, outp);
+  BCOPY(u->us_passwd, outp, u->us_passwdlen);
+
+  pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
+
+  UPAPDEBUG(LOG_INFO, ("pap_sauth: Sent id %d\n", u->us_id));
+
+  TIMEOUT(upap_timeout, u, u->us_timeouttime);
+  ++u->us_transmits;
+  u->us_clientstate = UPAPCS_AUTHREQ;
+}
+
+
+/*
+ * upap_sresp - Send a response (ack or nak).
+ */
+static void
+upap_sresp(upap_state *u, u_char code, u_char id, char *msg, int msglen)
+{
+  u_char *outp;
+  int outlen;
+
+  outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
+  outp = outpacket_buf[u->us_unit];
+  MAKEHEADER(outp, PPP_PAP);
+
+  PUTCHAR(code, outp);
+  PUTCHAR(id, outp);
+  PUTSHORT(outlen, outp);
+  PUTCHAR(msglen, outp);
+  BCOPY(msg, outp, msglen);
+  pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
+
+  UPAPDEBUG(LOG_INFO, ("pap_sresp: Sent code %d, id %d s=%d\n", code, id, u->us_clientstate));
+}
+
+#if PPP_ADDITIONAL_CALLBACKS
+static char *upap_codenames[] = {
+    "AuthReq", "AuthAck", "AuthNak"
+};
+
+/*
+ * upap_printpkt - print the contents of a PAP packet.
+ */
+static int upap_printpkt(
+  u_char *p,
+  int plen,
+  void (*printer) (void *, char *, ...),
+  void *arg
+)
+{
+  LWIP_UNUSED_ARG(p);
+  LWIP_UNUSED_ARG(plen);
+  LWIP_UNUSED_ARG(printer);
+  LWIP_UNUSED_ARG(arg);
+  return 0;
+}
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+
+#endif /* PAP_SUPPORT */
+
+#endif /* PPP_SUPPORT */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/pap.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/pap.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/pap.h	(revision 164)
@@ -0,0 +1,118 @@
+/*****************************************************************************
+* pap.h -  PPP Password Authentication Protocol header file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-12-04 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
+*   Original derived from BSD codes.
+*****************************************************************************/
+/*
+ * 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.
+ */
+
+#ifndef PAP_H
+#define PAP_H
+
+#if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+/*
+ * Packet header = Code, id, length.
+ */
+#define UPAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))
+
+
+/*
+ * UPAP codes.
+ */
+#define UPAP_AUTHREQ 1 /* Authenticate-Request */
+#define UPAP_AUTHACK 2 /* Authenticate-Ack */
+#define UPAP_AUTHNAK 3 /* Authenticate-Nak */
+
+/*
+ * Each interface is described by upap structure.
+ */
+typedef struct upap_state {
+  int us_unit;           /* Interface unit number */
+  const char *us_user;   /* User */
+  int us_userlen;        /* User length */
+  const char *us_passwd; /* Password */
+  int us_passwdlen;      /* Password length */
+  int us_clientstate;    /* Client state */
+  int us_serverstate;    /* Server state */
+  u_char us_id;          /* Current id */
+  int us_timeouttime;    /* Timeout (seconds) for auth-req retrans. */
+  int us_transmits;      /* Number of auth-reqs sent */
+  int us_maxtransmits;   /* Maximum number of auth-reqs to send */
+  int us_reqtimeout;     /* Time to wait for auth-req from peer */
+} upap_state;
+
+/*
+ * Client states.
+ */
+#define UPAPCS_INITIAL 0 /* Connection down */
+#define UPAPCS_CLOSED  1 /* Connection up, haven't requested auth */
+#define UPAPCS_PENDING 2 /* Connection down, have requested auth */
+#define UPAPCS_AUTHREQ 3 /* We've sent an Authenticate-Request */
+#define UPAPCS_OPEN    4 /* We've received an Ack */
+#define UPAPCS_BADAUTH 5 /* We've received a Nak */
+
+/*
+ * Server states.
+ */
+#define UPAPSS_INITIAL 0 /* Connection down */
+#define UPAPSS_CLOSED  1 /* Connection up, haven't requested auth */
+#define UPAPSS_PENDING 2 /* Connection down, have requested auth */
+#define UPAPSS_LISTEN  3 /* Listening for an Authenticate */
+#define UPAPSS_OPEN    4 /* We've sent an Ack */
+#define UPAPSS_BADAUTH 5 /* We've sent a Nak */
+
+
+extern upap_state upap[];
+
+void upap_authwithpeer  (int, char *, char *);
+void upap_authpeer      (int);
+
+extern struct protent pap_protent;
+
+#endif /* PAP_SUPPORT */
+
+#endif /* PAP_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ppp.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ppp.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ppp.c	(revision 164)
@@ -0,0 +1,2045 @@
+/*****************************************************************************
+* ppp.c - Network Point to Point Protocol program file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 by Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-11-05 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Original.
+*****************************************************************************/
+
+/*
+ * ppp_defs.h - PPP definitions.
+ *
+ * if_pppvar.h - private structures and declarations for PPP.
+ *
+ * Copyright (c) 1994 The Australian National University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation is hereby granted, provided that the above copyright
+ * notice appears in all copies.  This software is provided without any
+ * warranty, express or implied. The Australian National University
+ * makes no representations about the suitability of this software for
+ * any purpose.
+ *
+ * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
+ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+ * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
+ * OR MODIFICATIONS.
+ */
+
+/*
+ * if_ppp.h - Point-to-Point Protocol definitions.
+ *
+ * Copyright (c) 1989 Carnegie Mellon University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by Carnegie Mellon University.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "lwip/opt.h"
+
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "ppp_impl.h"
+#include "lwip/ip.h" /* for ip_input() */
+
+#include "pppdebug.h"
+
+#include "randm.h"
+#include "fsm.h"
+#if PAP_SUPPORT
+#include "pap.h"
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+#include "chap.h"
+#endif /* CHAP_SUPPORT */
+#include "ipcp.h"
+#include "lcp.h"
+#include "magic.h"
+#include "auth.h"
+#if VJ_SUPPORT
+#include "vj.h"
+#endif /* VJ_SUPPORT */
+#if PPPOE_SUPPORT
+#include "netif/ppp_oe.h"
+#endif /* PPPOE_SUPPORT */
+
+#include "lwip/tcpip.h"
+#include "lwip/api.h"
+#include "lwip/snmp.h"
+
+#include <string.h>
+
+/*************************/
+/*** LOCAL DEFINITIONS ***/
+/*************************/
+
+/** PPP_INPROC_MULTITHREADED==1 call pppInput using tcpip_callback().
+ * Set this to 0 if pppInProc is called inside tcpip_thread or with NO_SYS==1.
+ * Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded).
+ */
+#ifndef PPP_INPROC_MULTITHREADED
+#define PPP_INPROC_MULTITHREADED (NO_SYS==0)
+#endif
+
+/** PPP_INPROC_OWNTHREAD==1: start a dedicated RX thread per PPP session.
+ * Default is 0: call pppos_input() for received raw characters, charcater
+ * reception is up to the port */
+#ifndef PPP_INPROC_OWNTHREAD
+#define PPP_INPROC_OWNTHREAD      PPP_INPROC_MULTITHREADED
+#endif
+
+#if PPP_INPROC_OWNTHREAD && !PPP_INPROC_MULTITHREADED
+  #error "PPP_INPROC_OWNTHREAD needs PPP_INPROC_MULTITHREADED==1"
+#endif
+
+/*
+ * The basic PPP frame.
+ */
+#define PPP_ADDRESS(p)  (((u_char *)(p))[0])
+#define PPP_CONTROL(p)  (((u_char *)(p))[1])
+#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3])
+
+/* PPP packet parser states.  Current state indicates operation yet to be
+ * completed. */
+typedef enum {
+  PDIDLE = 0,  /* Idle state - waiting. */
+  PDSTART,     /* Process start flag. */
+  PDADDRESS,   /* Process address field. */
+  PDCONTROL,   /* Process control field. */
+  PDPROTOCOL1, /* Process protocol field 1. */
+  PDPROTOCOL2, /* Process protocol field 2. */
+  PDDATA       /* Process data byte. */
+} PPPDevStates;
+
+#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & pppACCMMask[c & 0x07])
+
+/************************/
+/*** LOCAL DATA TYPES ***/
+/************************/
+
+/** RX buffer size: this may be configured smaller! */
+#ifndef PPPOS_RX_BUFSIZE
+#define PPPOS_RX_BUFSIZE    (PPP_MRU + PPP_HDRLEN)
+#endif
+
+typedef struct PPPControlRx_s {
+  /** unit number / ppp descriptor */
+  int pd;
+  /** the rx file descriptor */
+  sio_fd_t fd;
+  /** receive buffer - encoded data is stored here */
+#if PPP_INPROC_OWNTHREAD
+  u_char rxbuf[PPPOS_RX_BUFSIZE];
+#endif /* PPP_INPROC_OWNTHREAD */
+
+  /* The input packet. */
+  struct pbuf *inHead, *inTail;
+
+#if PPPOS_SUPPORT
+  u16_t inProtocol;             /* The input protocol code. */
+  u16_t inFCS;                  /* Input Frame Check Sequence value. */
+#endif /* PPPOS_SUPPORT */
+  PPPDevStates inState;         /* The input process state. */
+  char inEscaped;               /* Escape next character. */
+  ext_accm inACCM;              /* Async-Ctl-Char-Map for input. */
+} PPPControlRx;
+
+/*
+ * PPP interface control block.
+ */
+typedef struct PPPControl_s {
+  PPPControlRx rx;
+  char openFlag;                /* True when in use. */
+#if PPPOE_SUPPORT
+  struct netif *ethif;
+  struct pppoe_softc *pppoe_sc;
+#endif /* PPPOE_SUPPORT */
+  int  if_up;                   /* True when the interface is up. */
+  int  errCode;                 /* Code indicating why interface is down. */
+#if PPPOS_SUPPORT
+  sio_fd_t fd;                  /* File device ID of port. */
+#endif /* PPPOS_SUPPORT */
+  u16_t mtu;                    /* Peer's mru */
+  int  pcomp;                   /* Does peer accept protocol compression? */
+  int  accomp;                  /* Does peer accept addr/ctl compression? */
+  u_long lastXMit;              /* Time of last transmission. */
+  ext_accm outACCM;             /* Async-Ctl-Char-Map for output. */
+#if PPPOS_SUPPORT && VJ_SUPPORT
+  int  vjEnabled;               /* Flag indicating VJ compression enabled. */
+  struct vjcompress vjComp;     /* Van Jacobson compression header. */
+#endif /* PPPOS_SUPPORT && VJ_SUPPORT */
+
+  struct netif netif;
+
+  struct ppp_addrs addrs;
+
+  void (*linkStatusCB)(void *ctx, int errCode, void *arg);
+  void *linkStatusCtx;
+
+} PPPControl;
+
+
+/*
+ * Ioctl definitions.
+ */
+
+struct npioctl {
+  int         protocol; /* PPP procotol, e.g. PPP_IP */
+  enum NPmode mode;
+};
+
+
+
+/***********************************/
+/*** LOCAL FUNCTION DECLARATIONS ***/
+/***********************************/
+#if PPPOS_SUPPORT
+#if PPP_INPROC_OWNTHREAD
+static void pppInputThread(void *arg);
+#endif /* PPP_INPROC_OWNTHREAD */
+static void pppDrop(PPPControlRx *pcrx);
+static void pppInProc(PPPControlRx *pcrx, u_char *s, int l);
+static void pppFreeCurrentInputPacket(PPPControlRx *pcrx);
+#endif /* PPPOS_SUPPORT */
+
+
+/******************************/
+/*** PUBLIC DATA STRUCTURES ***/
+/******************************/
+u_long subnetMask;
+
+static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */
+
+/*
+ * PPP Data Link Layer "protocol" table.
+ * One entry per supported protocol.
+ * The last entry must be NULL.
+ */
+struct protent *ppp_protocols[] = {
+  &lcp_protent,
+#if PAP_SUPPORT
+  &pap_protent,
+#endif /* PAP_SUPPORT */
+#if CHAP_SUPPORT
+  &chap_protent,
+#endif /* CHAP_SUPPORT */
+#if CBCP_SUPPORT
+  &cbcp_protent,
+#endif /* CBCP_SUPPORT */
+  &ipcp_protent,
+#if CCP_SUPPORT
+  &ccp_protent,
+#endif /* CCP_SUPPORT */
+  NULL
+};
+
+
+/*
+ * Buffers for outgoing packets.  This must be accessed only from the appropriate
+ * PPP task so that it doesn't need to be protected to avoid collisions.
+ */
+u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN];
+
+
+/*****************************/
+/*** LOCAL DATA STRUCTURES ***/
+/*****************************/
+
+#if PPPOS_SUPPORT
+/*
+ * FCS lookup table as calculated by genfcstab.
+ * @todo: smaller, slower implementation for lower memory footprint?
+ */
+static const u_short fcstab[256] = {
+  0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+  0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+  0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+  0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+  0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+  0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+  0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+  0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+  0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+  0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+  0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+  0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+  0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+  0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+  0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+  0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+  0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+  0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+  0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+  0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+  0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+  0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+  0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+  0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+  0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+  0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+  0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+  0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+  0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+  0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+  0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+  0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+
+/* PPP's Asynchronous-Control-Character-Map.  The mask array is used
+ * to select the specific bit for a character. */
+static u_char pppACCMMask[] = {
+  0x01,
+  0x02,
+  0x04,
+  0x08,
+  0x10,
+  0x20,
+  0x40,
+  0x80
+};
+
+#if PPP_INPROC_OWNTHREAD
+/** Wake up the task blocked in reading from serial line (if any) */
+static void
+pppRecvWakeup(int pd)
+{
+  PPPDEBUG(LOG_DEBUG, ("pppRecvWakeup: unit %d\n", pd));
+  if (pppControl[pd].openFlag != 0) {
+    sio_read_abort(pppControl[pd].fd);
+  }
+}
+#endif /* PPP_INPROC_OWNTHREAD */
+#endif /* PPPOS_SUPPORT */
+
+void
+pppLinkTerminated(int pd)
+{
+  PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d\n", pd));
+
+#if PPPOE_SUPPORT
+  if (pppControl[pd].ethif) {
+    pppoe_disconnect(pppControl[pd].pppoe_sc);
+  } else
+#endif /* PPPOE_SUPPORT */
+  {
+#if PPPOS_SUPPORT
+    PPPControl* pc;
+#if PPP_INPROC_OWNTHREAD
+    pppRecvWakeup(pd);
+#endif /* PPP_INPROC_OWNTHREAD */
+    pc = &pppControl[pd];
+
+    PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
+    if (pc->linkStatusCB) {
+      pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL);
+    }
+
+    pc->openFlag = 0;/**/
+#endif /* PPPOS_SUPPORT */
+  }
+  PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: finished.\n"));
+}
+
+void
+pppLinkDown(int pd)
+{
+  PPPDEBUG(LOG_DEBUG, ("pppLinkDown: unit %d\n", pd));
+
+#if PPPOE_SUPPORT
+  if (pppControl[pd].ethif) {
+    pppoe_disconnect(pppControl[pd].pppoe_sc);
+  } else
+#endif /* PPPOE_SUPPORT */
+  {
+#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD
+    pppRecvWakeup(pd);
+#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD*/
+  }
+}
+
+/** Initiate LCP open request */
+static void
+pppStart(int pd)
+{
+  PPPDEBUG(LOG_DEBUG, ("pppStart: unit %d\n", pd));
+  lcp_lowerup(pd);
+  lcp_open(pd); /* Start protocol */
+  PPPDEBUG(LOG_DEBUG, ("pppStart: finished\n"));
+}
+
+/** LCP close request */
+static void
+pppStop(int pd)
+{
+  PPPDEBUG(LOG_DEBUG, ("pppStop: unit %d\n", pd));
+  lcp_close(pd, "User request");
+}
+
+/** Called when carrier/link is lost */
+static void
+pppHup(int pd)
+{
+  PPPDEBUG(LOG_DEBUG, ("pppHupCB: unit %d\n", pd));
+  lcp_lowerdown(pd);
+  link_terminated(pd);
+}
+
+/***********************************/
+/*** PUBLIC FUNCTION DEFINITIONS ***/
+/***********************************/
+/* Initialize the PPP subsystem. */
+
+struct ppp_settings ppp_settings;
+
+void
+pppInit(void)
+{
+  struct protent *protp;
+  int i, j;
+
+  memset(&ppp_settings, 0, sizeof(ppp_settings));
+  ppp_settings.usepeerdns = 1;
+  pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL);
+
+  magicInit();
+
+  subnetMask = PP_HTONL(0xffffff00UL);
+
+  for (i = 0; i < NUM_PPP; i++) {
+    /* Initialize each protocol to the standard option set. */
+    for (j = 0; (protp = ppp_protocols[j]) != NULL; ++j) {
+      (*protp->init)(i);
+    }
+  }
+}
+
+void
+pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd)
+{
+  switch(authType) {
+    case PPPAUTHTYPE_NONE:
+    default:
+#ifdef LWIP_PPP_STRICT_PAP_REJECT
+      ppp_settings.refuse_pap = 1;
+#else  /* LWIP_PPP_STRICT_PAP_REJECT */
+      /* some providers request pap and accept an empty login/pw */
+      ppp_settings.refuse_pap = 0;
+#endif /* LWIP_PPP_STRICT_PAP_REJECT */
+      ppp_settings.refuse_chap = 1;
+      break;
+
+    case PPPAUTHTYPE_ANY:
+      /* Warning: Using PPPAUTHTYPE_ANY might have security consequences.
+       * RFC 1994 says:
+       *
+       * In practice, within or associated with each PPP server, there is a
+       * database which associates "user" names with authentication
+       * information ("secrets").  It is not anticipated that a particular
+       * named user would be authenticated by multiple methods.  This would
+       * make the user vulnerable to attacks which negotiate the least secure
+       * method from among a set (such as PAP rather than CHAP).  If the same
+       * secret was used, PAP would reveal the secret to be used later with
+       * CHAP.
+       *
+       * Instead, for each user name there should be an indication of exactly
+       * one method used to authenticate that user name.  If a user needs to
+       * make use of different authentication methods under different
+       * circumstances, then distinct user names SHOULD be employed, each of
+       * which identifies exactly one authentication method.
+       *
+       */
+      ppp_settings.refuse_pap = 0;
+      ppp_settings.refuse_chap = 0;
+      break;
+
+    case PPPAUTHTYPE_PAP:
+      ppp_settings.refuse_pap = 0;
+      ppp_settings.refuse_chap = 1;
+      break;
+
+    case PPPAUTHTYPE_CHAP:
+      ppp_settings.refuse_pap = 1;
+      ppp_settings.refuse_chap = 0;
+      break;
+  }
+
+  if(user) {
+    strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1);
+    ppp_settings.user[sizeof(ppp_settings.user)-1] = '\0';
+  } else {
+    ppp_settings.user[0] = '\0';
+  }
+
+  if(passwd) {
+    strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1);
+    ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0';
+  } else {
+    ppp_settings.passwd[0] = '\0';
+  }
+}
+
+#if PPPOS_SUPPORT
+/** Open a new PPP connection using the given I/O device.
+ * This initializes the PPP control block but does not
+ * attempt to negotiate the LCP session.  If this port
+ * connects to a modem, the modem connection must be
+ * established before calling this.
+ * Return a new PPP connection descriptor on success or
+ * an error code (negative) on failure.
+ *
+ * pppOpen() is directly defined to this function.
+ */
+int
+pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx)
+{
+  PPPControl *pc;
+  int pd;
+
+  if (linkStatusCB == NULL) {
+    /* PPP is single-threaded: without a callback,
+     * there is no way to know when the link is up. */
+    return PPPERR_PARAM;
+  }
+
+  /* Find a free PPP session descriptor. */
+  for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++);
+
+  if (pd >= NUM_PPP) {
+    pd = PPPERR_OPEN;
+  } else {
+    pc = &pppControl[pd];
+    /* input pbuf left over from last session? */
+    pppFreeCurrentInputPacket(&pc->rx);
+    /* @todo: is this correct or do I overwrite something? */
+    memset(pc, 0, sizeof(PPPControl));
+    pc->rx.pd = pd;
+    pc->rx.fd = fd;
+
+    pc->openFlag = 1;
+    pc->fd = fd;
+
+#if VJ_SUPPORT
+    vj_compress_init(&pc->vjComp);
+#endif /* VJ_SUPPORT */
+
+    /* 
+     * Default the in and out accm so that escape and flag characters
+     * are always escaped. 
+     */
+    pc->rx.inACCM[15] = 0x60; /* no need to protect since RX is not running */
+    pc->outACCM[15] = 0x60;
+
+    pc->linkStatusCB = linkStatusCB;
+    pc->linkStatusCtx = linkStatusCtx;
+
+    /*
+     * Start the connection and handle incoming events (packet or timeout).
+     */
+    PPPDEBUG(LOG_INFO, ("pppOverSerialOpen: unit %d: Connecting\n", pd));
+    pppStart(pd);
+#if PPP_INPROC_OWNTHREAD
+    sys_thread_new(PPP_THREAD_NAME, pppInputThread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO);
+#endif /* PPP_INPROC_OWNTHREAD */
+  }
+
+  return pd;
+}
+#endif /* PPPOS_SUPPORT */
+
+#if PPPOE_SUPPORT
+static void pppOverEthernetLinkStatusCB(int pd, int up);
+
+void
+pppOverEthernetClose(int pd)
+{
+  PPPControl* pc = &pppControl[pd];
+
+  /* *TJL* There's no lcp_deinit */
+  lcp_close(pd, NULL);
+
+  pppoe_destroy(&pc->netif);
+}
+
+int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name,
+                        pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx)
+{
+  PPPControl *pc;
+  int pd;
+
+  LWIP_UNUSED_ARG(service_name);
+  LWIP_UNUSED_ARG(concentrator_name);
+
+  if (linkStatusCB == NULL) {
+    /* PPP is single-threaded: without a callback,
+     * there is no way to know when the link is up. */
+    return PPPERR_PARAM;
+  }
+
+  /* Find a free PPP session descriptor. Critical region? */
+  for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++);
+  if (pd >= NUM_PPP) {
+    pd = PPPERR_OPEN;
+  } else {
+    pc = &pppControl[pd];
+    memset(pc, 0, sizeof(PPPControl));
+    pc->openFlag = 1;
+    pc->ethif = ethif;
+
+    pc->linkStatusCB  = linkStatusCB;
+    pc->linkStatusCtx = linkStatusCtx;
+
+    lcp_wantoptions[pd].mru = PPPOE_MAXMTU;
+    lcp_wantoptions[pd].neg_asyncmap = 0;
+    lcp_wantoptions[pd].neg_pcompression = 0;
+    lcp_wantoptions[pd].neg_accompression = 0;
+
+    lcp_allowoptions[pd].mru = PPPOE_MAXMTU;
+    lcp_allowoptions[pd].neg_asyncmap = 0;
+    lcp_allowoptions[pd].neg_pcompression = 0;
+    lcp_allowoptions[pd].neg_accompression = 0;
+
+    if(pppoe_create(ethif, pd, pppOverEthernetLinkStatusCB, &pc->pppoe_sc) != ERR_OK) {
+      pc->openFlag = 0;
+      return PPPERR_OPEN;
+    }
+
+    pppoe_connect(pc->pppoe_sc);
+  }
+
+  return pd;
+}
+#endif /* PPPOE_SUPPORT */
+
+
+/* Close a PPP connection and release the descriptor. 
+ * Any outstanding packets in the queues are dropped.
+ * Return 0 on success, an error code on failure. */
+int
+pppClose(int pd)
+{
+  PPPControl *pc = &pppControl[pd];
+  int st = 0;
+
+  PPPDEBUG(LOG_DEBUG, ("pppClose() called\n"));
+
+  /* Disconnect */
+#if PPPOE_SUPPORT
+  if(pc->ethif) {
+    PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd));
+    pc->errCode = PPPERR_USER;
+    /* This will leave us at PHASE_DEAD. */
+    pppStop(pd);
+  } else
+#endif /* PPPOE_SUPPORT */
+  {
+#if PPPOS_SUPPORT
+    PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd));
+    pc->errCode = PPPERR_USER;
+    /* This will leave us at PHASE_DEAD. */
+    pppStop(pd);
+#if PPP_INPROC_OWNTHREAD
+    pppRecvWakeup(pd);
+#endif /* PPP_INPROC_OWNTHREAD */
+#endif /* PPPOS_SUPPORT */
+  }
+
+  return st;
+}
+
+/* This function is called when carrier is lost on the PPP channel. */
+void
+pppSigHUP(int pd)
+{
+  PPPDEBUG(LOG_DEBUG, ("pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd));
+  pppHup(pd);
+}
+
+#if PPPOS_SUPPORT
+static void
+nPut(PPPControl *pc, struct pbuf *nb)
+{
+  struct pbuf *b;
+  int c;
+
+  for(b = nb; b != NULL; b = b->next) {
+    if((c = sio_write(pc->fd, b->payload, b->len)) != b->len) {
+      PPPDEBUG(LOG_WARNING,
+               ("PPP nPut: incomplete sio_write(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pc->fd, b->len, c, c));
+      LINK_STATS_INC(link.err);
+      pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */
+      snmp_inc_ifoutdiscards(&pc->netif);
+      pbuf_free(nb);
+      return;
+    }
+  }
+
+  snmp_add_ifoutoctets(&pc->netif, nb->tot_len);
+  snmp_inc_ifoutucastpkts(&pc->netif);
+  pbuf_free(nb);
+  LINK_STATS_INC(link.xmit);
+}
+
+/* 
+ * pppAppend - append given character to end of given pbuf.  If outACCM
+ * is not NULL and the character needs to be escaped, do so.
+ * If pbuf is full, append another.
+ * Return the current pbuf.
+ */
+static struct pbuf *
+pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM)
+{
+  struct pbuf *tb = nb;
+  
+  /* Make sure there is room for the character and an escape code.
+   * Sure we don't quite fill the buffer if the character doesn't
+   * get escaped but is one character worth complicating this? */
+  /* Note: We assume no packet header. */
+  if (nb && (PBUF_POOL_BUFSIZE - nb->len) < 2) {
+    tb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
+    if (tb) {
+      nb->next = tb;
+    } else {
+      LINK_STATS_INC(link.memerr);
+    }
+    nb = tb;
+  }
+
+  if (nb) {
+    if (outACCM && ESCAPE_P(*outACCM, c)) {
+      *((u_char*)nb->payload + nb->len++) = PPP_ESCAPE;
+      *((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS;
+    } else {
+      *((u_char*)nb->payload + nb->len++) = c;
+    }
+  }
+
+  return tb;
+}
+#endif /* PPPOS_SUPPORT */
+
+#if PPPOE_SUPPORT
+static err_t
+pppifOutputOverEthernet(int pd, struct pbuf *p)
+{
+  PPPControl *pc = &pppControl[pd];
+  struct pbuf *pb;
+  u_short protocol = PPP_IP;
+  int i=0;
+  u16_t tot_len;
+
+  /* @todo: try to use pbuf_header() here! */
+  pb = pbuf_alloc(PBUF_LINK, PPPOE_HDRLEN + sizeof(protocol), PBUF_RAM);
+  if(!pb) {
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.proterr);
+    snmp_inc_ifoutdiscards(&pc->netif);
+    return ERR_MEM;
+  }
+
+  pbuf_header(pb, -(s16_t)PPPOE_HDRLEN);
+
+  pc->lastXMit = sys_jiffies();
+
+  if (!pc->pcomp || protocol > 0xFF) {
+    *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF;
+  }
+  *((u_char*)pb->payload + i) = protocol & 0xFF;
+
+  pbuf_chain(pb, p);
+  tot_len = pb->tot_len;
+
+  if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) {
+    LINK_STATS_INC(link.err);
+    snmp_inc_ifoutdiscards(&pc->netif);
+    return PPPERR_DEVICE;
+  }
+
+  snmp_add_ifoutoctets(&pc->netif, tot_len);
+  snmp_inc_ifoutucastpkts(&pc->netif);
+  LINK_STATS_INC(link.xmit);
+  return ERR_OK;
+}
+#endif /* PPPOE_SUPPORT */
+
+/* Send a packet on the given connection. */
+static err_t
+pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr)
+{
+  int pd = (int)(size_t)netif->state;
+  PPPControl *pc = &pppControl[pd];
+#if PPPOS_SUPPORT
+  u_short protocol = PPP_IP;
+  u_int fcsOut = PPP_INITFCS;
+  struct pbuf *headMB = NULL, *tailMB = NULL, *p;
+  u_char c;
+#endif /* PPPOS_SUPPORT */
+
+  LWIP_UNUSED_ARG(ipaddr);
+
+  /* Validate parameters. */
+  /* We let any protocol value go through - it can't hurt us
+   * and the peer will just drop it if it's not accepting it. */
+  if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) {
+    PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad parms prot=%d pb=%p\n",
+              pd, PPP_IP, pb));
+    LINK_STATS_INC(link.opterr);
+    LINK_STATS_INC(link.drop);
+    snmp_inc_ifoutdiscards(netif);
+    return ERR_ARG;
+  }
+
+  /* Check that the link is up. */
+  if (lcp_phase[pd] == PHASE_DEAD) {
+    PPPDEBUG(LOG_ERR, ("pppifOutput[%d]: link not up\n", pd));
+    LINK_STATS_INC(link.rterr);
+    LINK_STATS_INC(link.drop);
+    snmp_inc_ifoutdiscards(netif);
+    return ERR_RTE;
+  }
+
+#if PPPOE_SUPPORT
+  if(pc->ethif) {
+    return pppifOutputOverEthernet(pd, pb);
+  }
+#endif /* PPPOE_SUPPORT */
+
+#if PPPOS_SUPPORT
+  /* Grab an output buffer. */
+  headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
+  if (headMB == NULL) {
+    PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: first alloc fail\n", pd));
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    snmp_inc_ifoutdiscards(netif);
+    return ERR_MEM;
+  }
+
+#if VJ_SUPPORT
+  /* 
+   * Attempt Van Jacobson header compression if VJ is configured and
+   * this is an IP packet. 
+   */
+  if (protocol == PPP_IP && pc->vjEnabled) {
+    switch (vj_compress_tcp(&pc->vjComp, pb)) {
+      case TYPE_IP:
+        /* No change...
+           protocol = PPP_IP_PROTOCOL; */
+        break;
+      case TYPE_COMPRESSED_TCP:
+        protocol = PPP_VJC_COMP;
+        break;
+      case TYPE_UNCOMPRESSED_TCP:
+        protocol = PPP_VJC_UNCOMP;
+        break;
+      default:
+        PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad IP packet\n", pd));
+        LINK_STATS_INC(link.proterr);
+        LINK_STATS_INC(link.drop);
+        snmp_inc_ifoutdiscards(netif);
+        pbuf_free(headMB);
+        return ERR_VAL;
+    }
+  }
+#endif /* VJ_SUPPORT */
+
+  tailMB = headMB;
+
+  /* Build the PPP header. */
+  if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) {
+    tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
+  }
+
+  pc->lastXMit = sys_jiffies();
+  if (!pc->accomp) {
+    fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS);
+    tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM);
+    fcsOut = PPP_FCS(fcsOut, PPP_UI);
+    tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM);
+  }
+  if (!pc->pcomp || protocol > 0xFF) {
+    c = (protocol >> 8) & 0xFF;
+    fcsOut = PPP_FCS(fcsOut, c);
+    tailMB = pppAppend(c, tailMB, &pc->outACCM);
+  }
+  c = protocol & 0xFF;
+  fcsOut = PPP_FCS(fcsOut, c);
+  tailMB = pppAppend(c, tailMB, &pc->outACCM);
+
+  /* Load packet. */
+  for(p = pb; p; p = p->next) {
+    int n;
+    u_char *sPtr;
+
+    sPtr = (u_char*)p->payload;
+    n = p->len;
+    while (n-- > 0) {
+      c = *sPtr++;
+
+      /* Update FCS before checking for special characters. */
+      fcsOut = PPP_FCS(fcsOut, c);
+      
+      /* Copy to output buffer escaping special characters. */
+      tailMB = pppAppend(c, tailMB, &pc->outACCM);
+    }
+  }
+
+  /* Add FCS and trailing flag. */
+  c = ~fcsOut & 0xFF;
+  tailMB = pppAppend(c, tailMB, &pc->outACCM);
+  c = (~fcsOut >> 8) & 0xFF;
+  tailMB = pppAppend(c, tailMB, &pc->outACCM);
+  tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
+
+  /* If we failed to complete the packet, throw it away. */
+  if (!tailMB) {
+    PPPDEBUG(LOG_WARNING,
+             ("pppifOutput[%d]: Alloc err - dropping proto=%d\n", 
+              pd, protocol));
+    pbuf_free(headMB);
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    snmp_inc_ifoutdiscards(netif);
+    return ERR_MEM;
+  }
+
+  /* Send it. */
+  PPPDEBUG(LOG_INFO, ("pppifOutput[%d]: proto=0x%"X16_F"\n", pd, protocol));
+
+  nPut(pc, headMB);
+#endif /* PPPOS_SUPPORT */
+
+  return ERR_OK;
+}
+
+/* Get and set parameters for the given connection.
+ * Return 0 on success, an error code on failure. */
+int
+pppIOCtl(int pd, int cmd, void *arg)
+{
+  PPPControl *pc = &pppControl[pd];
+  int st = 0;
+
+  if (pd < 0 || pd >= NUM_PPP) {
+    st = PPPERR_PARAM;
+  } else {
+    switch(cmd) {
+    case PPPCTLG_UPSTATUS:      /* Get the PPP up status. */
+      if (arg) {
+        *(int *)arg = (int)(pc->if_up);
+      } else {
+        st = PPPERR_PARAM;
+      }
+      break;
+    case PPPCTLS_ERRCODE:       /* Set the PPP error code. */
+      if (arg) {
+        pc->errCode = *(int *)arg;
+      } else {
+        st = PPPERR_PARAM;
+      }
+      break;
+    case PPPCTLG_ERRCODE:       /* Get the PPP error code. */
+      if (arg) {
+        *(int *)arg = (int)(pc->errCode);
+      } else {
+        st = PPPERR_PARAM;
+      }
+      break;
+#if PPPOS_SUPPORT
+    case PPPCTLG_FD:            /* Get the fd associated with the ppp */
+      if (arg) {
+        *(sio_fd_t *)arg = pc->fd;
+      } else {
+        st = PPPERR_PARAM;
+      }
+      break;
+#endif /* PPPOS_SUPPORT */
+    default:
+      st = PPPERR_PARAM;
+      break;
+    }
+  }
+
+  return st;
+}
+
+/*
+ * Return the Maximum Transmission Unit for the given PPP connection.
+ */
+u_short
+pppMTU(int pd)
+{
+  PPPControl *pc = &pppControl[pd];
+  u_short st;
+
+  /* Validate parameters. */
+  if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
+    st = 0;
+  } else {
+    st = pc->mtu;
+  }
+
+  return st;
+}
+
+#if PPPOE_SUPPORT
+int
+pppWriteOverEthernet(int pd, const u_char *s, int n)
+{
+  PPPControl *pc = &pppControl[pd];
+  struct pbuf *pb;
+
+  /* skip address & flags */
+  s += 2;
+  n -= 2;
+
+  LWIP_ASSERT("PPPOE_HDRLEN + n <= 0xffff", PPPOE_HDRLEN + n <= 0xffff);
+  pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN + n), PBUF_RAM);
+  if(!pb) {
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.proterr);
+    snmp_inc_ifoutdiscards(&pc->netif);
+    return PPPERR_ALLOC;
+  }
+
+  pbuf_header(pb, -(s16_t)PPPOE_HDRLEN);
+
+  pc->lastXMit = sys_jiffies();
+
+  MEMCPY(pb->payload, s, n);
+
+  if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) {
+    LINK_STATS_INC(link.err);
+    snmp_inc_ifoutdiscards(&pc->netif);
+    return PPPERR_DEVICE;
+  }
+
+  snmp_add_ifoutoctets(&pc->netif, (u16_t)n);
+  snmp_inc_ifoutucastpkts(&pc->netif);
+  LINK_STATS_INC(link.xmit);
+  return PPPERR_NONE;
+}
+#endif /* PPPOE_SUPPORT */
+
+/*
+ * Write n characters to a ppp link.
+ *  RETURN: >= 0 Number of characters written
+ *           -1 Failed to write to device
+ */
+int
+pppWrite(int pd, const u_char *s, int n)
+{
+  PPPControl *pc = &pppControl[pd];
+#if PPPOS_SUPPORT
+  u_char c;
+  u_int fcsOut;
+  struct pbuf *headMB, *tailMB;
+#endif /* PPPOS_SUPPORT */
+
+#if PPPOE_SUPPORT
+  if(pc->ethif) {
+    return pppWriteOverEthernet(pd, s, n);
+  }
+#endif /* PPPOE_SUPPORT */
+
+#if PPPOS_SUPPORT
+  headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
+  if (headMB == NULL) {
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.proterr);
+    snmp_inc_ifoutdiscards(&pc->netif);
+    return PPPERR_ALLOC;
+  }
+
+  tailMB = headMB;
+
+  /* If the link has been idle, we'll send a fresh flag character to
+   * flush any noise. */
+  if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) {
+    tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
+  }
+  pc->lastXMit = sys_jiffies();
+
+  fcsOut = PPP_INITFCS;
+  /* Load output buffer. */
+  while (n-- > 0) {
+    c = *s++;
+
+    /* Update FCS before checking for special characters. */
+    fcsOut = PPP_FCS(fcsOut, c);
+
+    /* Copy to output buffer escaping special characters. */
+    tailMB = pppAppend(c, tailMB, &pc->outACCM);
+  }
+    
+  /* Add FCS and trailing flag. */
+  c = ~fcsOut & 0xFF;
+  tailMB = pppAppend(c, tailMB, &pc->outACCM);
+  c = (~fcsOut >> 8) & 0xFF;
+  tailMB = pppAppend(c, tailMB, &pc->outACCM);
+  tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
+
+  /* If we failed to complete the packet, throw it away.
+   * Otherwise send it. */
+  if (!tailMB) {
+    PPPDEBUG(LOG_WARNING,
+             ("pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len));
+           /*"pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */
+    pbuf_free(headMB);
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.proterr);
+    snmp_inc_ifoutdiscards(&pc->netif);
+    return PPPERR_ALLOC;
+  }
+
+  PPPDEBUG(LOG_INFO, ("pppWrite[%d]: len=%d\n", pd, headMB->len));
+                   /* "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */
+  nPut(pc, headMB);
+#endif /* PPPOS_SUPPORT */
+
+  return PPPERR_NONE;
+}
+
+/*
+ * ppp_send_config - configure the transmit characteristics of
+ * the ppp interface.
+ */
+void
+ppp_send_config( int unit, u16_t mtu, u32_t asyncmap, int pcomp, int accomp)
+{
+  PPPControl *pc = &pppControl[unit];
+  int i;
+  
+  pc->mtu = mtu;
+  pc->pcomp = pcomp;
+  pc->accomp = accomp;
+  
+  /* Load the ACCM bits for the 32 control codes. */
+  for (i = 0; i < 32/8; i++) {
+    pc->outACCM[i] = (u_char)((asyncmap >> (8 * i)) & 0xFF);
+  }
+  PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: outACCM=%X %X %X %X\n",
+            unit,
+            pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3]));
+}
+
+
+/*
+ * ppp_set_xaccm - set the extended transmit ACCM for the interface.
+ */
+void
+ppp_set_xaccm(int unit, ext_accm *accm)
+{
+  SMEMCPY(pppControl[unit].outACCM, accm, sizeof(ext_accm));
+  PPPDEBUG(LOG_INFO, ("ppp_set_xaccm[%d]: outACCM=%X %X %X %X\n",
+            unit,
+            pppControl[unit].outACCM[0],
+            pppControl[unit].outACCM[1],
+            pppControl[unit].outACCM[2],
+            pppControl[unit].outACCM[3]));
+}
+
+
+/*
+ * ppp_recv_config - configure the receive-side characteristics of
+ * the ppp interface.
+ */
+void
+ppp_recv_config( int unit, int mru, u32_t asyncmap, int pcomp, int accomp)
+{
+  PPPControl *pc = &pppControl[unit];
+  int i;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  LWIP_UNUSED_ARG(accomp);
+  LWIP_UNUSED_ARG(pcomp);
+  LWIP_UNUSED_ARG(mru);
+
+  /* Load the ACCM bits for the 32 control codes. */
+  SYS_ARCH_PROTECT(lev);
+  for (i = 0; i < 32 / 8; i++) {
+    /* @todo: does this work? ext_accm has been modified from pppd! */
+    pc->rx.inACCM[i] = (u_char)(asyncmap >> (i * 8));
+  }
+  SYS_ARCH_UNPROTECT(lev);
+  PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: inACCM=%X %X %X %X\n",
+            unit,
+            pc->rx.inACCM[0], pc->rx.inACCM[1], pc->rx.inACCM[2], pc->rx.inACCM[3]));
+}
+
+#if 0
+/*
+ * ccp_test - ask kernel whether a given compression method
+ * is acceptable for use.  Returns 1 if the method and parameters
+ * are OK, 0 if the method is known but the parameters are not OK
+ * (e.g. code size should be reduced), or -1 if the method is unknown.
+ */
+int
+ccp_test( int unit, int opt_len,  int for_transmit, u_char *opt_ptr)
+{
+  return 0; /* XXX Currently no compression. */
+}
+
+/*
+ * ccp_flags_set - inform kernel about the current state of CCP.
+ */
+void
+ccp_flags_set(int unit, int isopen, int isup)
+{
+  /* XXX */
+}
+
+/*
+ * ccp_fatal_error - returns 1 if decompression was disabled as a
+ * result of an error detected after decompression of a packet,
+ * 0 otherwise.  This is necessary because of patent nonsense.
+ */
+int
+ccp_fatal_error(int unit)
+{
+  /* XXX */
+  return 0;
+}
+#endif
+
+/*
+ * get_idle_time - return how long the link has been idle.
+ */
+int
+get_idle_time(int u, struct ppp_idle *ip)
+{
+  /* XXX */
+  LWIP_UNUSED_ARG(u);
+  LWIP_UNUSED_ARG(ip);
+
+  return 0;
+}
+
+
+/*
+ * Return user specified netmask, modified by any mask we might determine
+ * for address `addr' (in network byte order).
+ * Here we scan through the system's list of interfaces, looking for
+ * any non-point-to-point interfaces which might appear to be on the same
+ * network as `addr'.  If we find any, we OR in their netmask to the
+ * user-specified netmask.
+ */
+u32_t
+GetMask(u32_t addr)
+{
+  u32_t mask, nmask;
+
+  addr = htonl(addr);
+  if (IP_CLASSA(addr)) { /* determine network mask for address class */
+    nmask = IP_CLASSA_NET;
+  } else if (IP_CLASSB(addr)) {
+    nmask = IP_CLASSB_NET;
+  } else { 
+    nmask = IP_CLASSC_NET;
+  }
+
+  /* class D nets are disallowed by bad_ip_adrs */
+  mask = subnetMask | htonl(nmask);
+  
+  /* XXX
+   * Scan through the system's network interfaces.
+   * Get each netmask and OR them into our mask.
+   */
+
+  return mask;
+}
+
+/*
+ * sifvjcomp - config tcp header compression
+ */
+int
+sifvjcomp(int pd, int vjcomp, u8_t cidcomp, u8_t maxcid)
+{
+#if PPPOS_SUPPORT && VJ_SUPPORT
+  PPPControl *pc = &pppControl[pd];
+  
+  pc->vjEnabled = vjcomp;
+  pc->vjComp.compressSlot = cidcomp;
+  pc->vjComp.maxSlotIndex = maxcid;
+  PPPDEBUG(LOG_INFO, ("sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n",
+            vjcomp, cidcomp, maxcid));
+#else /* PPPOS_SUPPORT && VJ_SUPPORT */
+  LWIP_UNUSED_ARG(pd);
+  LWIP_UNUSED_ARG(vjcomp);
+  LWIP_UNUSED_ARG(cidcomp);
+  LWIP_UNUSED_ARG(maxcid);
+#endif /* PPPOS_SUPPORT && VJ_SUPPORT */
+
+  return 0;
+}
+
+/*
+ * pppifNetifInit - netif init callback
+ */
+static err_t
+pppifNetifInit(struct netif *netif)
+{
+  netif->name[0] = 'p';
+  netif->name[1] = 'p';
+  netif->output = pppifOutput;
+  netif->mtu = pppMTU((int)(size_t)netif->state);
+  netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP;
+#if LWIP_NETIF_HOSTNAME
+  /* @todo: Initialize interface hostname */
+  /* netif_set_hostname(netif, "lwip"); */
+#endif /* LWIP_NETIF_HOSTNAME */
+  return ERR_OK;
+}
+
+
+/*
+ * sifup - Config the interface up and enable IP packets to pass.
+ */
+int
+sifup(int pd)
+{
+  PPPControl *pc = &pppControl[pd];
+  int st = 1;
+  
+  if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
+    st = 0;
+    PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd));
+  } else {
+    netif_remove(&pc->netif);
+    if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask,
+                  &pc->addrs.his_ipaddr, (void *)(size_t)pd, pppifNetifInit, ip_input)) {
+      netif_set_up(&pc->netif);
+      pc->if_up = 1;
+      pc->errCode = PPPERR_NONE;
+
+      PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
+      if (pc->linkStatusCB) {
+        pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs);
+      }
+    } else {
+      st = 0;
+      PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", pd));
+    }
+  }
+
+  return st;
+}
+
+/*
+ * sifnpmode - Set the mode for handling packets for a given NP.
+ */
+int
+sifnpmode(int u, int proto, enum NPmode mode)
+{
+  LWIP_UNUSED_ARG(u);
+  LWIP_UNUSED_ARG(proto);
+  LWIP_UNUSED_ARG(mode);
+  return 0;
+}
+
+/*
+ * sifdown - Config the interface down and disable IP.
+ */
+int
+sifdown(int pd)
+{
+  PPPControl *pc = &pppControl[pd];
+  int st = 1;
+  
+  if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
+    st = 0;
+    PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad parms\n", pd));
+  } else {
+    pc->if_up = 0;
+    /* make sure the netif status callback is called */
+    netif_set_down(&pc->netif);
+    netif_remove(&pc->netif);
+    PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
+    if (pc->linkStatusCB) {
+      pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL);
+    }
+  }
+  return st;
+}
+
+/**
+ * sifaddr - Config the interface IP addresses and netmask.
+ * @param pd Interface unit ???
+ * @param o Our IP address ???
+ * @param h His IP address ???
+ * @param m IP subnet mask ???
+ * @param ns1 Primary DNS
+ * @param ns2 Secondary DNS
+ */
+int
+sifaddr( int pd, u32_t o, u32_t h, u32_t m, u32_t ns1, u32_t ns2)
+{
+  PPPControl *pc = &pppControl[pd];
+  int st = 1;
+  
+  if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
+    st = 0;
+    PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd));
+  } else {
+    SMEMCPY(&pc->addrs.our_ipaddr, &o, sizeof(o));
+    SMEMCPY(&pc->addrs.his_ipaddr, &h, sizeof(h));
+    SMEMCPY(&pc->addrs.netmask, &m, sizeof(m));
+    SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1));
+    SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2));
+  }
+  return st;
+}
+
+/**
+ * cifaddr - Clear the interface IP addresses, and delete routes
+ * through the interface if possible.
+ * @param pd Interface unit ???
+ * @param o Our IP address ???
+ * @param h IP broadcast address ???
+ */
+int
+cifaddr( int pd, u32_t o, u32_t h)
+{
+  PPPControl *pc = &pppControl[pd];
+  int st = 1;
+  
+  LWIP_UNUSED_ARG(o);
+  LWIP_UNUSED_ARG(h);
+  if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
+    st = 0;
+    PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd));
+  } else {
+    IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0);
+    IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0);
+    IP4_ADDR(&pc->addrs.netmask, 255,255,255,0);
+    IP4_ADDR(&pc->addrs.dns1, 0,0,0,0);
+    IP4_ADDR(&pc->addrs.dns2, 0,0,0,0);
+  }
+  return st;
+}
+
+/*
+ * sifdefaultroute - assign a default route through the address given.
+ */
+int
+sifdefaultroute(int pd, u32_t l, u32_t g)
+{
+  PPPControl *pc = &pppControl[pd];
+  int st = 1;
+
+  LWIP_UNUSED_ARG(l);
+  LWIP_UNUSED_ARG(g);
+
+  if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
+    st = 0;
+    PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd));
+  } else {
+    netif_set_default(&pc->netif);
+  }
+
+  /* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */
+
+  return st;
+}
+
+/*
+ * cifdefaultroute - delete a default route through the address given.
+ */
+int
+cifdefaultroute(int pd, u32_t l, u32_t g)
+{
+  PPPControl *pc = &pppControl[pd];
+  int st = 1;
+
+  LWIP_UNUSED_ARG(l);
+  LWIP_UNUSED_ARG(g);
+
+  if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
+    st = 0;
+    PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd));
+  } else {
+    netif_set_default(NULL);
+  }
+
+  return st;
+}
+
+/**********************************/
+/*** LOCAL FUNCTION DEFINITIONS ***/
+/**********************************/
+
+#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD
+/* The main PPP process function.  This implements the state machine according
+ * to section 4 of RFC 1661: The Point-To-Point Protocol. */
+static void
+pppInputThread(void *arg)
+{
+  int count;
+  PPPControlRx *pcrx = arg;
+
+  while (lcp_phase[pcrx->pd] != PHASE_DEAD) {
+    count = sio_read(pcrx->fd, pcrx->rxbuf, PPPOS_RX_BUFSIZE);
+    if(count > 0) {
+      pppInProc(pcrx, pcrx->rxbuf, count);
+    } else {
+      /* nothing received, give other tasks a chance to run */
+      sys_msleep(1);
+    }
+  }
+}
+#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */
+
+#if PPPOE_SUPPORT
+
+void
+pppOverEthernetInitFailed(int pd)
+{
+  PPPControl* pc;
+
+  pppHup(pd);
+  pppStop(pd);
+
+  pc = &pppControl[pd];
+  pppoe_destroy(&pc->netif);
+  pc->openFlag = 0;
+
+  if(pc->linkStatusCB) {
+    pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL);
+  }
+}
+
+static void
+pppOverEthernetLinkStatusCB(int pd, int up)
+{
+  if(up) {
+    PPPDEBUG(LOG_INFO, ("pppOverEthernetLinkStatusCB: unit %d: Connecting\n", pd));
+    pppStart(pd);
+  } else {
+    pppOverEthernetInitFailed(pd);
+  }
+}
+#endif /* PPPOE_SUPPORT */
+
+struct pbuf *
+pppSingleBuf(struct pbuf *p)
+{
+  struct pbuf *q, *b;
+  u_char *pl;
+
+  if(p->tot_len == p->len) {
+    return p;
+  }
+
+  q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
+  if(!q) {
+    PPPDEBUG(LOG_ERR,
+             ("pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len));
+    return p; /* live dangerously */
+  }
+
+  for(b = p, pl = q->payload; b != NULL; b = b->next) {
+    MEMCPY(pl, b->payload, b->len);
+    pl += b->len;
+  }
+
+  pbuf_free(p);
+
+  return q;
+}
+
+struct pppInputHeader {
+  int unit;
+  u16_t proto;
+};
+
+/*
+ * Pass the processed input packet to the appropriate handler.
+ * This function and all handlers run in the context of the tcpip_thread
+ */
+static void
+pppInput(void *arg)
+{
+  struct pbuf *nb = (struct pbuf *)arg;
+  u16_t protocol;
+  int pd;
+
+  pd = ((struct pppInputHeader *)nb->payload)->unit;
+  protocol = ((struct pppInputHeader *)nb->payload)->proto;
+    
+  if(pbuf_header(nb, -(int)sizeof(struct pppInputHeader))) {
+    LWIP_ASSERT("pbuf_header failed\n", 0);
+    goto drop;
+  }
+
+  LINK_STATS_INC(link.recv);
+  snmp_inc_ifinucastpkts(&pppControl[pd].netif);
+  snmp_add_ifinoctets(&pppControl[pd].netif, nb->tot_len);
+
+  /*
+   * Toss all non-LCP packets unless LCP is OPEN.
+   * Until we get past the authentication phase, toss all packets
+   * except LCP, LQR and authentication packets.
+   */
+  if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) {
+    if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) ||
+        (lcp_phase[pd] != PHASE_AUTHENTICATE)) {
+      PPPDEBUG(LOG_INFO, ("pppInput: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pd]));
+      goto drop;
+    }
+  }
+
+  switch(protocol) {
+    case PPP_VJC_COMP:      /* VJ compressed TCP */
+#if PPPOS_SUPPORT && VJ_SUPPORT
+      PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len));
+      /*
+       * Clip off the VJ header and prepend the rebuilt TCP/IP header and
+       * pass the result to IP.
+       */
+      if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) {
+        pppControl[pd].netif.input(nb, &pppControl[pd].netif);
+        return;
+      }
+      /* Something's wrong so drop it. */
+      PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd));
+#else  /* PPPOS_SUPPORT && VJ_SUPPORT */
+      /* No handler for this protocol so drop the packet. */
+      PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload));
+#endif /* PPPOS_SUPPORT && VJ_SUPPORT */
+      break;
+
+    case PPP_VJC_UNCOMP:    /* VJ uncompressed TCP */
+#if PPPOS_SUPPORT && VJ_SUPPORT
+      PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len));
+      /*
+       * Process the TCP/IP header for VJ header compression and then pass
+       * the packet to IP.
+       */
+      if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) {
+        pppControl[pd].netif.input(nb, &pppControl[pd].netif);
+        return;
+      }
+      /* Something's wrong so drop it. */
+      PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd));
+#else  /* PPPOS_SUPPORT && VJ_SUPPORT */
+      /* No handler for this protocol so drop the packet. */
+      PPPDEBUG(LOG_INFO,
+               ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", 
+                pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload));
+#endif /* PPPOS_SUPPORT && VJ_SUPPORT */
+      break;
+
+    case PPP_IP:            /* Internet Protocol */
+      PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len));
+      if (pppControl[pd].netif.input) {
+        pppControl[pd].netif.input(nb, &pppControl[pd].netif);
+        return;
+      }
+      break;
+
+    default: {
+      struct protent *protp;
+      int i;
+
+      /*
+       * Upcall the proper protocol input routine.
+       */
+      for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
+        if (protp->protocol == protocol && protp->enabled_flag) {
+          PPPDEBUG(LOG_INFO, ("pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len));
+          nb = pppSingleBuf(nb);
+          (*protp->input)(pd, nb->payload, nb->len);
+          PPPDEBUG(LOG_DETAIL, ("pppInput[%d]: packet processed\n", pd));
+          goto out;
+        }
+      }
+
+      /* No handler for this protocol so reject the packet. */
+      PPPDEBUG(LOG_INFO, ("pppInput[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pd, protocol, nb->len));
+      if (pbuf_header(nb, sizeof(protocol))) {
+        LWIP_ASSERT("pbuf_header failed\n", 0);
+        goto drop;
+      }
+#if BYTE_ORDER == LITTLE_ENDIAN
+      protocol = htons(protocol);
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+      SMEMCPY(nb->payload, &protocol, sizeof(protocol));
+      lcp_sprotrej(pd, nb->payload, nb->len);
+    }
+    break;
+  }
+
+drop:
+  LINK_STATS_INC(link.drop);
+  snmp_inc_ifindiscards(&pppControl[pd].netif);
+
+out:
+  pbuf_free(nb);
+  return;
+}
+
+#if PPPOS_SUPPORT
+/*
+ * Drop the input packet.
+ */
+static void
+pppFreeCurrentInputPacket(PPPControlRx *pcrx)
+{
+  if (pcrx->inHead != NULL) {
+    if (pcrx->inTail && (pcrx->inTail != pcrx->inHead)) {
+      pbuf_free(pcrx->inTail);
+    }
+    pbuf_free(pcrx->inHead);
+    pcrx->inHead = NULL;
+  }
+  pcrx->inTail = NULL;
+}
+
+/*
+ * Drop the input packet and increase error counters.
+ */
+static void
+pppDrop(PPPControlRx *pcrx)
+{
+  if (pcrx->inHead != NULL) {
+#if 0
+    PPPDEBUG(LOG_INFO, ("pppDrop: %d:%.*H\n", pcrx->inHead->len, min(60, pcrx->inHead->len * 2), pcrx->inHead->payload));
+#endif
+    PPPDEBUG(LOG_INFO, ("pppDrop: pbuf len=%d, addr %p\n", pcrx->inHead->len, (void*)pcrx->inHead));
+  }
+  pppFreeCurrentInputPacket(pcrx);
+#if VJ_SUPPORT
+  vj_uncompress_err(&pppControl[pcrx->pd].vjComp);
+#endif /* VJ_SUPPORT */
+
+  LINK_STATS_INC(link.drop);
+  snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif);
+}
+
+#if !PPP_INPROC_OWNTHREAD
+/** Pass received raw characters to PPPoS to be decoded. This function is
+ * thread-safe and can be called from a dedicated RX-thread or from a main-loop.
+ *
+ * @param pd PPP descriptor index, returned by pppOpen()
+ * @param data received data
+ * @param len length of received data
+ */
+void
+pppos_input(int pd, u_char* data, int len)
+{
+  pppInProc(&pppControl[pd].rx, data, len);
+}
+#endif
+
+/**
+ * Process a received octet string.
+ */
+static void
+pppInProc(PPPControlRx *pcrx, u_char *s, int l)
+{
+  struct pbuf *nextNBuf;
+  u_char curChar;
+  u_char escaped;
+  SYS_ARCH_DECL_PROTECT(lev);
+
+  PPPDEBUG(LOG_DEBUG, ("pppInProc[%d]: got %d bytes\n", pcrx->pd, l));
+  while (l-- > 0) {
+    curChar = *s++;
+
+    SYS_ARCH_PROTECT(lev);
+    escaped = ESCAPE_P(pcrx->inACCM, curChar);
+    SYS_ARCH_UNPROTECT(lev);
+    /* Handle special characters. */
+    if (escaped) {
+      /* Check for escape sequences. */
+      /* XXX Note that this does not handle an escaped 0x5d character which
+       * would appear as an escape character.  Since this is an ASCII ']'
+       * and there is no reason that I know of to escape it, I won't complicate
+       * the code to handle this case. GLL */
+      if (curChar == PPP_ESCAPE) {
+        pcrx->inEscaped = 1;
+      /* Check for the flag character. */
+      } else if (curChar == PPP_FLAG) {
+        /* If this is just an extra flag character, ignore it. */
+        if (pcrx->inState <= PDADDRESS) {
+          /* ignore it */;
+        /* If we haven't received the packet header, drop what has come in. */
+        } else if (pcrx->inState < PDDATA) {
+          PPPDEBUG(LOG_WARNING,
+                   ("pppInProc[%d]: Dropping incomplete packet %d\n", 
+                    pcrx->pd, pcrx->inState));
+          LINK_STATS_INC(link.lenerr);
+          pppDrop(pcrx);
+        /* If the fcs is invalid, drop the packet. */
+        } else if (pcrx->inFCS != PPP_GOODFCS) {
+          PPPDEBUG(LOG_INFO,
+                   ("pppInProc[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n", 
+                    pcrx->pd, pcrx->inFCS, pcrx->inProtocol));
+          /* Note: If you get lots of these, check for UART frame errors or try different baud rate */
+          LINK_STATS_INC(link.chkerr);
+          pppDrop(pcrx);
+        /* Otherwise it's a good packet so pass it on. */
+        } else {
+          struct pbuf *inp;
+          /* Trim off the checksum. */
+          if(pcrx->inTail->len >= 2) {
+            pcrx->inTail->len -= 2;
+
+            pcrx->inTail->tot_len = pcrx->inTail->len;
+            if (pcrx->inTail != pcrx->inHead) {
+              pbuf_cat(pcrx->inHead, pcrx->inTail);
+            }
+          } else {
+            pcrx->inTail->tot_len = pcrx->inTail->len;
+            if (pcrx->inTail != pcrx->inHead) {
+              pbuf_cat(pcrx->inHead, pcrx->inTail);
+            }
+
+            pbuf_realloc(pcrx->inHead, pcrx->inHead->tot_len - 2);
+          }
+
+          /* Dispatch the packet thereby consuming it. */
+          inp = pcrx->inHead;
+          /* Packet consumed, release our references. */
+          pcrx->inHead = NULL;
+          pcrx->inTail = NULL;
+#if PPP_INPROC_MULTITHREADED
+          if(tcpip_callback_with_block(pppInput, inp, 0) != ERR_OK) {
+            PPPDEBUG(LOG_ERR, ("pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd));
+            pbuf_free(inp);
+            LINK_STATS_INC(link.drop);
+            snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif);
+          }
+#else /* PPP_INPROC_MULTITHREADED */
+          pppInput(inp);
+#endif /* PPP_INPROC_MULTITHREADED */
+        }
+
+        /* Prepare for a new packet. */
+        pcrx->inFCS = PPP_INITFCS;
+        pcrx->inState = PDADDRESS;
+        pcrx->inEscaped = 0;
+      /* Other characters are usually control characters that may have
+       * been inserted by the physical layer so here we just drop them. */
+      } else {
+        PPPDEBUG(LOG_WARNING,
+                 ("pppInProc[%d]: Dropping ACCM char <%d>\n", pcrx->pd, curChar));
+      }
+    /* Process other characters. */
+    } else {
+      /* Unencode escaped characters. */
+      if (pcrx->inEscaped) {
+        pcrx->inEscaped = 0;
+        curChar ^= PPP_TRANS;
+      }
+
+      /* Process character relative to current state. */
+      switch(pcrx->inState) {
+        case PDIDLE:                    /* Idle state - waiting. */
+          /* Drop the character if it's not 0xff
+           * we would have processed a flag character above. */
+          if (curChar != PPP_ALLSTATIONS) {
+            break;
+          }
+
+        /* Fall through */
+        case PDSTART:                   /* Process start flag. */
+          /* Prepare for a new packet. */
+          pcrx->inFCS = PPP_INITFCS;
+
+        /* Fall through */
+        case PDADDRESS:                 /* Process address field. */
+          if (curChar == PPP_ALLSTATIONS) {
+            pcrx->inState = PDCONTROL;
+            break;
+          }
+          /* Else assume compressed address and control fields so
+           * fall through to get the protocol... */
+        case PDCONTROL:                 /* Process control field. */
+          /* If we don't get a valid control code, restart. */
+          if (curChar == PPP_UI) {
+            pcrx->inState = PDPROTOCOL1;
+            break;
+          }
+#if 0
+          else {
+            PPPDEBUG(LOG_WARNING,
+                     ("pppInProc[%d]: Invalid control <%d>\n", pcrx->pd, curChar));
+            pcrx->inState = PDSTART;
+          }
+#endif
+        case PDPROTOCOL1:               /* Process protocol field 1. */
+          /* If the lower bit is set, this is the end of the protocol
+           * field. */
+          if (curChar & 1) {
+            pcrx->inProtocol = curChar;
+            pcrx->inState = PDDATA;
+          } else {
+            pcrx->inProtocol = (u_int)curChar << 8;
+            pcrx->inState = PDPROTOCOL2;
+          }
+          break;
+        case PDPROTOCOL2:               /* Process protocol field 2. */
+          pcrx->inProtocol |= curChar;
+          pcrx->inState = PDDATA;
+          break;
+        case PDDATA:                    /* Process data byte. */
+          /* Make space to receive processed data. */
+          if (pcrx->inTail == NULL || pcrx->inTail->len == PBUF_POOL_BUFSIZE) {
+            if (pcrx->inTail != NULL) {
+              pcrx->inTail->tot_len = pcrx->inTail->len;
+              if (pcrx->inTail != pcrx->inHead) {
+                pbuf_cat(pcrx->inHead, pcrx->inTail);
+                /* give up the inTail reference now */
+                pcrx->inTail = NULL;
+              }
+            }
+            /* If we haven't started a packet, we need a packet header. */
+            nextNBuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
+            if (nextNBuf == NULL) {
+              /* No free buffers.  Drop the input packet and let the
+               * higher layers deal with it.  Continue processing
+               * the received pbuf chain in case a new packet starts. */
+              PPPDEBUG(LOG_ERR, ("pppInProc[%d]: NO FREE MBUFS!\n", pcrx->pd));
+              LINK_STATS_INC(link.memerr);
+              pppDrop(pcrx);
+              pcrx->inState = PDSTART;  /* Wait for flag sequence. */
+              break;
+            }
+            if (pcrx->inHead == NULL) {
+              struct pppInputHeader *pih = nextNBuf->payload;
+
+              pih->unit = pcrx->pd;
+              pih->proto = pcrx->inProtocol;
+
+              nextNBuf->len += sizeof(*pih);
+
+              pcrx->inHead = nextNBuf;
+            }
+            pcrx->inTail = nextNBuf;
+          }
+          /* Load character into buffer. */
+          ((u_char*)pcrx->inTail->payload)[pcrx->inTail->len++] = curChar;
+          break;
+      }
+
+      /* update the frame check sequence number. */
+      pcrx->inFCS = PPP_FCS(pcrx->inFCS, curChar);
+    }
+  } /* while (l-- > 0), all bytes processed */
+
+  avRandomize();
+}
+#endif /* PPPOS_SUPPORT */
+
+#if PPPOE_SUPPORT
+void
+pppInProcOverEthernet(int pd, struct pbuf *pb)
+{
+  struct pppInputHeader *pih;
+  u16_t inProtocol;
+
+  if(pb->len < sizeof(inProtocol)) {
+    PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: too small for protocol field\n"));
+    goto drop;
+  }
+
+  inProtocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1];
+
+  /* make room for pppInputHeader - should not fail */
+  if (pbuf_header(pb, sizeof(*pih) - sizeof(inProtocol)) != 0) {
+    PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: could not allocate room for header\n"));
+    goto drop;
+  }
+
+  pih = pb->payload;
+
+  pih->unit = pd;
+  pih->proto = inProtocol;
+
+  /* Dispatch the packet thereby consuming it. */
+  pppInput(pb);
+  return;
+
+drop:
+  LINK_STATS_INC(link.drop);
+  snmp_inc_ifindiscards(&pppControl[pd].netif);
+  pbuf_free(pb);
+  return;
+}
+#endif /* PPPOE_SUPPORT */
+
+#if LWIP_NETIF_STATUS_CALLBACK
+/** Set the status callback of a PPP's netif
+ *
+ * @param pd The PPP descriptor returned by pppOpen()
+ * @param status_callback pointer to the status callback function
+ *
+ * @see netif_set_status_callback
+ */
+void
+ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback)
+{
+  netif_set_status_callback(&pppControl[pd].netif, status_callback); 
+}
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+
+#if LWIP_NETIF_LINK_CALLBACK
+/** Set the link callback of a PPP's netif
+ *
+ * @param pd The PPP descriptor returned by pppOpen()
+ * @param link_callback pointer to the link callback function
+ *
+ * @see netif_set_link_callback
+ */
+void
+ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback)
+{
+  netif_set_link_callback(&pppControl[pd].netif, link_callback); 
+}
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+
+#endif /* PPP_SUPPORT */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ppp.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ppp.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ppp.h	(revision 164)
@@ -0,0 +1,201 @@
+/*****************************************************************************
+* ppp.h - Network Point to Point Protocol header file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
+*   Original derived from BSD codes.
+*****************************************************************************/
+
+#ifndef PPP_H
+#define PPP_H
+
+#include "lwip/opt.h"
+
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/def.h"
+#include "lwip/sio.h"
+#include "lwip/stats.h"
+#include "lwip/mem.h"
+#include "lwip/netif.h"
+#include "lwip/sys.h"
+#include "lwip/timers.h"
+
+
+#ifndef __u_char_defined
+
+/* Type definitions for BSD code. */
+typedef unsigned long  u_long;
+typedef unsigned int   u_int;
+typedef unsigned short u_short;
+typedef unsigned char  u_char;
+
+#endif
+
+
+/*************************
+*** PUBLIC DEFINITIONS ***
+*************************/
+
+/* Error codes. */
+#define PPPERR_NONE      0 /* No error. */
+#define PPPERR_PARAM    -1 /* Invalid parameter. */
+#define PPPERR_OPEN     -2 /* Unable to open PPP session. */
+#define PPPERR_DEVICE   -3 /* Invalid I/O device for PPP. */
+#define PPPERR_ALLOC    -4 /* Unable to allocate resources. */
+#define PPPERR_USER     -5 /* User interrupt. */
+#define PPPERR_CONNECT  -6 /* Connection lost. */
+#define PPPERR_AUTHFAIL -7 /* Failed authentication challenge. */
+#define PPPERR_PROTOCOL -8 /* Failed to meet protocol. */
+
+/*
+ * PPP IOCTL commands.
+ */
+/*
+ * Get the up status - 0 for down, non-zero for up.  The argument must
+ * point to an int.
+ */
+#define PPPCTLG_UPSTATUS 100 /* Get the up status - 0 down else up */
+#define PPPCTLS_ERRCODE  101 /* Set the error code */
+#define PPPCTLG_ERRCODE  102 /* Get the error code */
+#define PPPCTLG_FD       103 /* Get the fd associated with the ppp */
+
+/************************
+*** PUBLIC DATA TYPES ***
+************************/
+
+struct ppp_addrs {
+  ip_addr_t our_ipaddr, his_ipaddr, netmask, dns1, dns2;
+};
+
+
+/***********************
+*** PUBLIC FUNCTIONS ***
+***********************/
+
+/* Initialize the PPP subsystem. */
+void pppInit(void);
+
+/* Warning: Using PPPAUTHTYPE_ANY might have security consequences.
+ * RFC 1994 says:
+ *
+ * In practice, within or associated with each PPP server, there is a
+ * database which associates "user" names with authentication
+ * information ("secrets").  It is not anticipated that a particular
+ * named user would be authenticated by multiple methods.  This would
+ * make the user vulnerable to attacks which negotiate the least secure
+ * method from among a set (such as PAP rather than CHAP).  If the same
+ * secret was used, PAP would reveal the secret to be used later with
+ * CHAP.
+ *
+ * Instead, for each user name there should be an indication of exactly
+ * one method used to authenticate that user name.  If a user needs to
+ * make use of different authentication methods under different
+ * circumstances, then distinct user names SHOULD be employed, each of
+ * which identifies exactly one authentication method.
+ *
+ */
+enum pppAuthType {
+    PPPAUTHTYPE_NONE,
+    PPPAUTHTYPE_ANY,
+    PPPAUTHTYPE_PAP,
+    PPPAUTHTYPE_CHAP
+};
+
+void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd);
+
+/* Link status callback function prototype */
+typedef void (*pppLinkStatusCB_fn)(void *ctx, int errCode, void *arg);
+
+#if PPPOS_SUPPORT
+/*
+ * Open a new PPP connection using the given serial I/O device.
+ * This initializes the PPP control block but does not
+ * attempt to negotiate the LCP session.
+ * Return a new PPP connection descriptor on success or
+ * an error code (negative) on failure. 
+ */
+int pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx);
+#endif /* PPPOS_SUPPORT */
+
+#if PPPOE_SUPPORT
+/*
+ * Open a new PPP Over Ethernet (PPPOE) connection.
+ */
+int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name,
+                        pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx);
+#endif /* PPPOE_SUPPORT */
+
+/* for source code compatibility */
+#define pppOpen(fd,cb,ls) pppOverSerialOpen(fd,cb,ls)
+
+/*
+ * Close a PPP connection and release the descriptor. 
+ * Any outstanding packets in the queues are dropped.
+ * Return 0 on success, an error code on failure. 
+ */
+int pppClose(int pd);
+
+/*
+ * Indicate to the PPP process that the line has disconnected.
+ */
+void pppSigHUP(int pd);
+
+/*
+ * Get and set parameters for the given connection.
+ * Return 0 on success, an error code on failure. 
+ */
+int  pppIOCtl(int pd, int cmd, void *arg);
+
+/*
+ * Return the Maximum Transmission Unit for the given PPP connection.
+ */
+u_short pppMTU(int pd);
+
+#if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD
+/*
+ * PPP over Serial: this is the input function to be called for received data.
+ * If PPP_INPROC_OWNTHREAD==1, a seperate input thread using the blocking
+ * sio_read() is used, so this is deactivated.
+ */
+void pppos_input(int pd, u_char* data, int len);
+#endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */
+
+
+#if LWIP_NETIF_STATUS_CALLBACK
+/* Set an lwIP-style status-callback for the selected PPP device */
+void ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#if LWIP_NETIF_LINK_CALLBACK
+/* Set an lwIP-style link-callback for the selected PPP device */
+void ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback);
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+
+#endif /* PPP_SUPPORT */
+
+#endif /* PPP_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ppp_impl.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ppp_impl.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ppp_impl.h	(revision 164)
@@ -0,0 +1,363 @@
+/*****************************************************************************
+* ppp.h - Network Point to Point Protocol header file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1997 Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
+*   Original derived from BSD codes.
+*****************************************************************************/
+
+#ifndef PPP_IMPL_H
+#define PPP_IMPL_H
+
+#include "lwip/opt.h"
+
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "ppp.h"
+#include "lwip/def.h"
+#include "lwip/sio.h"
+#include "lwip/stats.h"
+#include "lwip/mem.h"
+#include "lwip/netif.h"
+#include "lwip/sys.h"
+#include "lwip/timers.h"
+
+/** Some defines for code we skip compared to the original pppd.
+ *  These are just here to minimise the use of the ugly "#if 0". */
+#define PPP_ADDITIONAL_CALLBACKS  0
+
+/** Some error checks to test for unsupported code */
+#if CBCP_SUPPORT
+#error "CBCP is not supported in lwIP PPP"
+#endif
+#if CCP_SUPPORT
+#error "CCP is not supported in lwIP PPP"
+#endif
+
+/*
+ * pppd.h - PPP daemon global declarations.
+ *
+ * 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_defs.h - PPP definitions.
+ *
+ * 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.
+ */
+
+#define TIMEOUT(f, a, t)    do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0)
+#define UNTIMEOUT(f, a)     sys_untimeout((f), (a))
+
+
+/*
+ * Constants and structures defined by the internet system,
+ * Per RFC 790, September 1981, and numerous additions.
+ */
+
+/*
+ * The basic PPP frame.
+ */
+#define PPP_HDRLEN      4       /* octets for standard ppp header */
+#define PPP_FCSLEN      2       /* octets for FCS */
+
+
+/*
+ * Significant octet values.
+ */
+#define PPP_ALLSTATIONS 0xff    /* All-Stations broadcast address */
+#define PPP_UI          0x03    /* Unnumbered Information */
+#define PPP_FLAG        0x7e    /* Flag Sequence */
+#define PPP_ESCAPE      0x7d    /* Asynchronous Control Escape */
+#define PPP_TRANS       0x20    /* Asynchronous transparency modifier */
+
+/*
+ * Protocol field values.
+ */
+#define PPP_IP          0x21    /* Internet Protocol */
+#define PPP_AT          0x29    /* AppleTalk Protocol */
+#define PPP_VJC_COMP    0x2d    /* VJ compressed TCP */
+#define PPP_VJC_UNCOMP  0x2f    /* VJ uncompressed TCP */
+#define PPP_COMP        0xfd    /* compressed packet */
+#define PPP_IPCP        0x8021  /* IP Control Protocol */
+#define PPP_ATCP        0x8029  /* AppleTalk Control Protocol */
+#define PPP_CCP         0x80fd  /* Compression Control Protocol */
+#define PPP_LCP         0xc021  /* Link Control Protocol */
+#define PPP_PAP         0xc023  /* Password Authentication Protocol */
+#define PPP_LQR         0xc025  /* Link Quality Report protocol */
+#define PPP_CHAP        0xc223  /* Cryptographic Handshake Auth. Protocol */
+#define PPP_CBCP        0xc029  /* Callback Control Protocol */
+
+/*
+ * Values for FCS calculations.
+ */
+#define PPP_INITFCS     0xffff  /* Initial FCS value */
+#define PPP_GOODFCS     0xf0b8  /* Good final FCS value */
+#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
+
+/*
+ * Extended asyncmap - allows any character to be escaped.
+ */
+typedef u_char  ext_accm[32];
+
+/*
+ * What to do with network protocol (NP) packets.
+ */
+enum NPmode {
+  NPMODE_PASS,        /* pass the packet through */
+  NPMODE_DROP,        /* silently drop the packet */
+  NPMODE_ERROR,       /* return an error */
+  NPMODE_QUEUE        /* save it up for later. */
+};
+
+/*
+ * Inline versions of get/put char/short/long.
+ * Pointer is advanced; we assume that both arguments
+ * are lvalues and will already be in registers.
+ * cp MUST be u_char *.
+ */
+#define GETCHAR(c, cp) { \
+    (c) = *(cp)++; \
+}
+#define PUTCHAR(c, cp) { \
+    *(cp)++ = (u_char) (c); \
+}
+
+
+#define GETSHORT(s, cp) { \
+    (s) = *(cp); (cp)++; (s) <<= 8; \
+    (s) |= *(cp); (cp)++; \
+}
+#define PUTSHORT(s, cp) { \
+    *(cp)++ = (u_char) ((s) >> 8); \
+    *(cp)++ = (u_char) (s & 0xff); \
+}
+
+#define GETLONG(l, cp) { \
+    (l) = *(cp); (cp)++; (l) <<= 8; \
+    (l) |= *(cp); (cp)++; (l) <<= 8; \
+    (l) |= *(cp); (cp)++; (l) <<= 8; \
+    (l) |= *(cp); (cp)++; \
+}
+#define PUTLONG(l, cp) { \
+    *(cp)++ = (u_char) ((l) >> 24); \
+    *(cp)++ = (u_char) ((l) >> 16); \
+    *(cp)++ = (u_char) ((l) >> 8); \
+    *(cp)++ = (u_char) (l); \
+}
+
+
+#define INCPTR(n, cp)   ((cp) += (n))
+#define DECPTR(n, cp)   ((cp) -= (n))
+
+#define BCMP(s0, s1, l)     memcmp((u_char *)(s0), (u_char *)(s1), (l))
+#define BCOPY(s, d, l)      MEMCPY((d), (s), (l))
+#define BZERO(s, n)         memset(s, 0, n)
+
+#if PPP_DEBUG
+#define PRINTMSG(m, l)  { m[l] = '\0'; LWIP_DEBUGF(LOG_INFO, ("Remote message: %s\n", m)); }
+#else  /* PPP_DEBUG */
+#define PRINTMSG(m, l)
+#endif /* PPP_DEBUG */
+
+/*
+ * MAKEHEADER - Add PPP Header fields to a packet.
+ */
+#define MAKEHEADER(p, t) { \
+    PUTCHAR(PPP_ALLSTATIONS, p); \
+    PUTCHAR(PPP_UI, p); \
+    PUTSHORT(t, p); }
+
+/************************
+*** PUBLIC DATA TYPES ***
+************************/
+
+/*
+ * The following struct gives the addresses of procedures to call
+ * for a particular protocol.
+ */
+struct protent {
+    u_short protocol;       /* PPP protocol number */
+    /* Initialization procedure */
+    void (*init) (int unit);
+    /* Process a received packet */
+    void (*input) (int unit, u_char *pkt, int len);
+    /* Process a received protocol-reject */
+    void (*protrej) (int unit);
+    /* Lower layer has come up */
+    void (*lowerup) (int unit);
+    /* Lower layer has gone down */
+    void (*lowerdown) (int unit);
+    /* Open the protocol */
+    void (*open) (int unit);
+    /* Close the protocol */
+    void (*close) (int unit, char *reason);
+#if PPP_ADDITIONAL_CALLBACKS
+    /* Print a packet in readable form */
+    int  (*printpkt) (u_char *pkt, int len,
+              void (*printer) (void *, char *, ...),
+              void *arg);
+    /* Process a received data packet */
+    void (*datainput) (int unit, u_char *pkt, int len);
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+    int  enabled_flag;      /* 0 if protocol is disabled */
+    char *name;         /* Text name of protocol */
+#if PPP_ADDITIONAL_CALLBACKS
+    /* Check requested options, assign defaults */
+    void (*check_options) (u_long);
+    /* Configure interface for demand-dial */
+    int  (*demand_conf) (int unit);
+    /* Say whether to bring up link for this pkt */
+    int  (*active_pkt) (u_char *pkt, int len);
+#endif /* PPP_ADDITIONAL_CALLBACKS */
+};
+
+/*
+ * The following structure records the time in seconds since
+ * the last NP packet was sent or received.
+ */
+struct ppp_idle {
+  u_short xmit_idle;      /* seconds since last NP packet sent */
+  u_short recv_idle;      /* seconds since last NP packet received */
+};
+
+struct ppp_settings {
+
+  u_int  disable_defaultip : 1;       /* Don't use hostname for default IP addrs */
+  u_int  auth_required     : 1;       /* Peer is required to authenticate */
+  u_int  explicit_remote   : 1;       /* remote_name specified with remotename opt */
+  u_int  refuse_pap        : 1;       /* Don't wanna auth. ourselves with PAP */
+  u_int  refuse_chap       : 1;       /* Don't wanna auth. ourselves with CHAP */
+  u_int  usehostname       : 1;       /* Use hostname for our_name */
+  u_int  usepeerdns        : 1;       /* Ask peer for DNS adds */
+
+  u_short idle_time_limit;            /* Shut down link if idle for this long */
+  int  maxconnect;                    /* Maximum connect time (seconds) */
+
+  char user       [MAXNAMELEN   + 1]; /* Username for PAP */
+  char passwd     [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */
+  char our_name   [MAXNAMELEN   + 1]; /* Our name for authentication purposes */
+  char remote_name[MAXNAMELEN   + 1]; /* Peer's name for authentication */
+};
+
+/*****************************
+*** PUBLIC DATA STRUCTURES ***
+*****************************/
+
+/* Buffers for outgoing packets. */
+extern u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN];
+
+extern struct ppp_settings ppp_settings;
+
+extern struct protent *ppp_protocols[]; /* Table of pointers to supported protocols */
+
+
+/***********************
+*** PUBLIC FUNCTIONS ***
+***********************/
+
+/*
+ * Write n characters to a ppp link.
+ * RETURN: >= 0 Number of characters written, -1 Failed to write to device.
+ */
+int pppWrite(int pd, const u_char *s, int n);
+
+void pppInProcOverEthernet(int pd, struct pbuf *pb);
+
+struct pbuf *pppSingleBuf(struct pbuf *p);
+
+void pppLinkTerminated(int pd);
+
+void pppLinkDown(int pd);
+
+/* Configure i/f transmit parameters */
+void ppp_send_config (int, u16_t, u32_t, int, int);
+/* Set extended transmit ACCM */
+void ppp_set_xaccm (int, ext_accm *);
+/* Configure i/f receive parameters */
+void ppp_recv_config (int, int, u32_t, int, int);
+/* Find out how long link has been idle */
+int  get_idle_time (int, struct ppp_idle *);
+
+/* Configure VJ TCP header compression */
+int  sifvjcomp (int, int, u8_t, u8_t);
+/* Configure i/f down (for IP) */
+int  sifup (int);
+/* Set mode for handling packets for proto */
+int  sifnpmode (int u, int proto, enum NPmode mode);
+/* Configure i/f down (for IP) */
+int  sifdown (int);
+/* Configure IP addresses for i/f */
+int  sifaddr (int, u32_t, u32_t, u32_t, u32_t, u32_t);
+/* Reset i/f IP addresses */
+int  cifaddr (int, u32_t, u32_t);
+/* Create default route through i/f */
+int  sifdefaultroute (int, u32_t, u32_t);
+/* Delete default route through i/f */
+int  cifdefaultroute (int, u32_t, u32_t);
+
+/* Get appropriate netmask for address */
+u32_t GetMask (u32_t); 
+
+#endif /* PPP_SUPPORT */
+
+#endif /* PPP_IMPL_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ppp_oe.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ppp_oe.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/ppp_oe.c	(revision 164)
@@ -0,0 +1,1132 @@
+/*****************************************************************************
+* ppp_oe.c - PPP Over Ethernet implementation for lwIP.
+*
+* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 06-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+*****************************************************************************/
+
+
+
+/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Martin Husemann <martin@NetBSD.org>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "lwip/opt.h"
+
+#if PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "netif/ppp_oe.h"
+
+#include "ppp_impl.h"
+#include "pppdebug.h"
+
+#include "lwip/timers.h"
+#include "lwip/memp.h"
+
+#include <string.h>
+#include <stdio.h>
+
+
+/* Add a 16 bit unsigned value to a buffer pointed to by PTR */
+#define PPPOE_ADD_16(PTR, VAL) \
+    *(PTR)++ = (u8_t)((VAL) / 256);    \
+    *(PTR)++ = (u8_t)((VAL) % 256)
+
+/* Add a complete PPPoE header to the buffer pointed to by PTR */
+#define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN)  \
+    *(PTR)++ = PPPOE_VERTYPE;  \
+    *(PTR)++ = (CODE);         \
+    PPPOE_ADD_16(PTR, SESS);   \
+    PPPOE_ADD_16(PTR, LEN)
+
+#define PPPOE_DISC_TIMEOUT (5*1000)  /* base for quick timeout calculation */
+#define PPPOE_SLOW_RETRY   (60*1000) /* persistent retry interval */
+#define PPPOE_DISC_MAXPADI  4        /* retry PADI four times (quickly) */
+#define PPPOE_DISC_MAXPADR  2        /* retry PADR twice */
+
+#ifdef PPPOE_SERVER
+#error "PPPOE_SERVER is not yet supported under lwIP!"
+/* from if_spppsubr.c */
+#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */
+#endif
+
+#ifndef PPPOE_ERRORSTRING_LEN
+#define PPPOE_ERRORSTRING_LEN     64
+#endif
+static char pppoe_error_tmp[PPPOE_ERRORSTRING_LEN];
+
+
+/* input routines */
+static void pppoe_dispatch_disc_pkt(struct netif *, struct pbuf *);
+
+/* management routines */
+static int pppoe_do_disconnect(struct pppoe_softc *);
+static void pppoe_abort_connect(struct pppoe_softc *);
+static void pppoe_clear_softc(struct pppoe_softc *, const char *);
+
+/* internal timeout handling */
+static void pppoe_timeout(void *);
+
+/* sending actual protocol controll packets */
+static err_t pppoe_send_padi(struct pppoe_softc *);
+static err_t pppoe_send_padr(struct pppoe_softc *);
+#ifdef PPPOE_SERVER
+static err_t pppoe_send_pado(struct pppoe_softc *);
+static err_t pppoe_send_pads(struct pppoe_softc *);
+#endif
+static err_t pppoe_send_padt(struct netif *, u_int, const u8_t *);
+
+/* internal helper functions */
+static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct netif *);
+static struct pppoe_softc * pppoe_find_softc_by_hunique(u8_t *, size_t, struct netif *);
+
+/** linked list of created pppoe interfaces */
+static struct pppoe_softc *pppoe_softc_list;
+
+err_t
+pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr)
+{
+  struct pppoe_softc *sc;
+
+  sc = (struct pppoe_softc *)memp_malloc(MEMP_PPPOE_IF);
+  if (sc == NULL) {
+    *scptr = NULL;
+    return ERR_MEM;
+  }
+  memset(sc, 0, sizeof(struct pppoe_softc));
+
+  /* changed to real address later */
+  MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
+
+  sc->sc_pd = pd;
+  sc->sc_linkStatusCB = linkStatusCB;
+  sc->sc_ethif = ethif;
+
+  /* put the new interface at the head of the list */
+  sc->next = pppoe_softc_list;
+  pppoe_softc_list = sc;
+
+  *scptr = sc;
+
+  return ERR_OK;
+}
+
+err_t
+pppoe_destroy(struct netif *ifp)
+{
+  struct pppoe_softc *sc, *prev = NULL;
+
+  for (sc = pppoe_softc_list; sc != NULL; prev = sc, sc = sc->next) {
+    if (sc->sc_ethif == ifp) {
+      break;
+    }
+  }
+
+  if(!(sc && (sc->sc_ethif == ifp))) {
+    return ERR_IF;
+  }
+
+  sys_untimeout(pppoe_timeout, sc);
+  if (prev == NULL) {
+    /* remove sc from the head of the list */
+    pppoe_softc_list = sc->next;
+  } else {
+    /* remove sc from the list */
+    prev->next = sc->next;
+  }
+
+#ifdef PPPOE_TODO
+  if (sc->sc_concentrator_name) {
+    mem_free(sc->sc_concentrator_name);
+  }
+  if (sc->sc_service_name) {
+    mem_free(sc->sc_service_name);
+  }
+#endif /* PPPOE_TODO */
+  memp_free(MEMP_PPPOE_IF, sc);
+
+  return ERR_OK;
+}
+
+/*
+ * Find the interface handling the specified session.
+ * Note: O(number of sessions open), this is a client-side only, mean
+ * and lean implementation, so number of open sessions typically should
+ * be 1.
+ */
+static struct pppoe_softc *
+pppoe_find_softc_by_session(u_int session, struct netif *rcvif)
+{
+  struct pppoe_softc *sc;
+
+  if (session == 0) {
+    return NULL;
+  }
+
+  for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) {
+    if (sc->sc_state == PPPOE_STATE_SESSION
+        && sc->sc_session == session) {
+      if (sc->sc_ethif == rcvif) {
+        return sc;
+      } else {
+        return NULL;
+      }
+    }
+  }
+  return NULL;
+}
+
+/* Check host unique token passed and return appropriate softc pointer,
+ * or NULL if token is bogus. */
+static struct pppoe_softc *
+pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif)
+{
+  struct pppoe_softc *sc, *t;
+
+  if (pppoe_softc_list == NULL) {
+    return NULL;
+  }
+
+  if (len != sizeof sc) {
+    return NULL;
+  }
+  MEMCPY(&t, token, len);
+
+  for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) {
+    if (sc == t) {
+      break;
+    }
+  }
+
+  if (sc == NULL) {
+    PPPDEBUG(LOG_DEBUG, ("pppoe: alien host unique tag, no session found\n"));
+    return NULL;
+  }
+
+  /* should be safe to access *sc now */
+  if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) {
+    printf("%c%c%"U16_F": host unique tag found, but it belongs to a connection in state %d\n",
+      sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_state);
+    return NULL;
+  }
+  if (sc->sc_ethif != rcvif) {
+    printf("%c%c%"U16_F": wrong interface, not accepting host unique\n",
+      sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num);
+    return NULL;
+  }
+  return sc;
+}
+
+static void
+pppoe_linkstatus_up(struct pppoe_softc *sc)
+{
+  sc->sc_linkStatusCB(sc->sc_pd, 1);
+}
+
+/* analyze and handle a single received packet while not in session state */
+static void
+pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb)
+{
+  u16_t tag, len;
+  u16_t session, plen;
+  struct pppoe_softc *sc;
+  const char *err_msg;
+  char devname[6];
+  u8_t *ac_cookie;
+  u16_t ac_cookie_len;
+#ifdef PPPOE_SERVER
+  u8_t *hunique;
+  size_t hunique_len;
+#endif
+  struct pppoehdr *ph;
+  struct pppoetag pt;
+  int off, err, errortag;
+  struct eth_hdr *ethhdr;
+
+  pb = pppSingleBuf(pb);
+
+  strcpy(devname, "pppoe");  /* as long as we don't know which instance */
+  err_msg = NULL;
+  errortag = 0;
+  if (pb->len < sizeof(*ethhdr)) {
+    goto done;
+  }
+  ethhdr = (struct eth_hdr *)pb->payload;
+  off = sizeof(*ethhdr);
+
+  ac_cookie = NULL;
+  ac_cookie_len = 0;
+#ifdef PPPOE_SERVER
+  hunique = NULL;
+  hunique_len = 0;
+#endif
+  session = 0;
+  if (pb->len - off < PPPOE_HEADERLEN) {
+    printf("pppoe: packet too short: %d\n", pb->len);
+    goto done;
+  }
+
+  ph = (struct pppoehdr *) (ethhdr + 1);
+  if (ph->vertype != PPPOE_VERTYPE) {
+    printf("pppoe: unknown version/type packet: 0x%x\n", ph->vertype);
+    goto done;
+  }
+  session = ntohs(ph->session);
+  plen = ntohs(ph->plen);
+  off += sizeof(*ph);
+
+  if (plen + off > pb->len) {
+    printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n",
+        pb->len - off, plen);
+    goto done;
+  }
+  if(pb->tot_len == pb->len) {
+    pb->tot_len = pb->len = (u16_t)off + plen; /* ignore trailing garbage */
+  }
+  tag = 0;
+  len = 0;
+  sc = NULL;
+  while (off + sizeof(pt) <= pb->len) {
+    MEMCPY(&pt, (u8_t*)pb->payload + off, sizeof(pt));
+    tag = ntohs(pt.tag);
+    len = ntohs(pt.len);
+    if (off + sizeof(pt) + len > pb->len) {
+      printf("pppoe: tag 0x%x len 0x%x is too long\n", tag, len);
+      goto done;
+    }
+    switch (tag) {
+      case PPPOE_TAG_EOL:
+        goto breakbreak;
+      case PPPOE_TAG_SNAME:
+        break;  /* ignored */
+      case PPPOE_TAG_ACNAME:
+        break;  /* ignored */
+      case PPPOE_TAG_HUNIQUE:
+        if (sc != NULL) {
+          break;
+        }
+#ifdef PPPOE_SERVER
+        hunique = (u8_t*)pb->payload + off + sizeof(pt);
+        hunique_len = len;
+#endif
+        sc = pppoe_find_softc_by_hunique((u8_t*)pb->payload + off + sizeof(pt), len, netif);
+        if (sc != NULL) {
+          snprintf(devname, sizeof(devname), "%c%c%"U16_F, sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num);
+        }
+        break;
+      case PPPOE_TAG_ACCOOKIE:
+        if (ac_cookie == NULL) {
+          ac_cookie = (u8_t*)pb->payload + off + sizeof(pt);
+          ac_cookie_len = len;
+        }
+        break;
+      case PPPOE_TAG_SNAME_ERR:
+        err_msg = "SERVICE NAME ERROR";
+        errortag = 1;
+        break;
+      case PPPOE_TAG_ACSYS_ERR:
+        err_msg = "AC SYSTEM ERROR";
+        errortag = 1;
+        break;
+      case PPPOE_TAG_GENERIC_ERR:
+        err_msg = "GENERIC ERROR";
+        errortag = 1;
+        break;
+    }
+    if (err_msg) {
+      if (errortag && len) {
+        u16_t error_len = LWIP_MIN(len, sizeof(pppoe_error_tmp)-1);
+        strncpy(pppoe_error_tmp, (char*)pb->payload + off + sizeof(pt), error_len);
+        pppoe_error_tmp[error_len-1] = '\0';
+        printf("%s: %s: %s\n", devname, err_msg, pppoe_error_tmp);
+      } else {
+        printf("%s: %s\n", devname, err_msg);
+      }
+      if (errortag) {
+        goto done;
+      }
+    }
+    off += sizeof(pt) + len;
+  }
+
+breakbreak:;
+  switch (ph->code) {
+    case PPPOE_CODE_PADI:
+#ifdef PPPOE_SERVER
+      /*
+       * got service name, concentrator name, and/or host unique.
+       * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP.
+       */
+      if (LIST_EMPTY(&pppoe_softc_list)) {
+        goto done;
+      }
+      LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
+        if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) {
+          continue;
+        }
+        if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) {
+          continue;
+        }
+        if (sc->sc_state == PPPOE_STATE_INITIAL) {
+          break;
+        }
+      }
+      if (sc == NULL) {
+        /* printf("pppoe: free passive interface is not found\n"); */
+        goto done;
+      }
+      if (hunique) {
+        if (sc->sc_hunique) {
+          mem_free(sc->sc_hunique);
+        }
+        sc->sc_hunique = mem_malloc(hunique_len);
+        if (sc->sc_hunique == NULL) {
+          goto done;
+        }
+        sc->sc_hunique_len = hunique_len;
+        MEMCPY(sc->sc_hunique, hunique, hunique_len);
+      }
+      MEMCPY(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest);
+      sc->sc_state = PPPOE_STATE_PADO_SENT;
+      pppoe_send_pado(sc);
+      break;
+#endif /* PPPOE_SERVER */
+    case PPPOE_CODE_PADR:
+#ifdef PPPOE_SERVER
+      /*
+       * get sc from ac_cookie if IFF_PASSIVE
+       */
+      if (ac_cookie == NULL) {
+        /* be quiet if there is not a single pppoe instance */
+        printf("pppoe: received PADR but not includes ac_cookie\n");
+        goto done;
+      }
+      sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, netif);
+      if (sc == NULL) {
+        /* be quiet if there is not a single pppoe instance */
+        if (!LIST_EMPTY(&pppoe_softc_list)) {
+          printf("pppoe: received PADR but could not find request for it\n");
+        }
+        goto done;
+      }
+      if (sc->sc_state != PPPOE_STATE_PADO_SENT) {
+        printf("%c%c%"U16_F": received unexpected PADR\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num);
+        goto done;
+      }
+      if (hunique) {
+        if (sc->sc_hunique) {
+          mem_free(sc->sc_hunique);
+        }
+        sc->sc_hunique = mem_malloc(hunique_len);
+        if (sc->sc_hunique == NULL) {
+          goto done;
+        }
+        sc->sc_hunique_len = hunique_len;
+        MEMCPY(sc->sc_hunique, hunique, hunique_len);
+      }
+      pppoe_send_pads(sc);
+      sc->sc_state = PPPOE_STATE_SESSION;
+      pppoe_linkstatus_up(sc); /* notify upper layers */
+      break;
+#else
+      /* ignore, we are no access concentrator */
+      goto done;
+#endif /* PPPOE_SERVER */
+    case PPPOE_CODE_PADO:
+      if (sc == NULL) {
+        /* be quiet if there is not a single pppoe instance */
+        if (pppoe_softc_list != NULL) {
+          printf("pppoe: received PADO but could not find request for it\n");
+        }
+        goto done;
+      }
+      if (sc->sc_state != PPPOE_STATE_PADI_SENT) {
+        printf("%c%c%"U16_F": received unexpected PADO\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num);
+        goto done;
+      }
+      if (ac_cookie) {
+        sc->sc_ac_cookie_len = ac_cookie_len;
+        MEMCPY(sc->sc_ac_cookie, ac_cookie, ac_cookie_len);
+      }
+      MEMCPY(&sc->sc_dest, ethhdr->src.addr, sizeof(sc->sc_dest.addr));
+      sys_untimeout(pppoe_timeout, sc);
+      sc->sc_padr_retried = 0;
+      sc->sc_state = PPPOE_STATE_PADR_SENT;
+      if ((err = pppoe_send_padr(sc)) != 0) {
+        PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
+      }
+      sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc);
+      break;
+    case PPPOE_CODE_PADS:
+      if (sc == NULL) {
+        goto done;
+      }
+      sc->sc_session = session;
+      sys_untimeout(pppoe_timeout, sc);
+      PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x connected\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, session));
+      sc->sc_state = PPPOE_STATE_SESSION;
+      pppoe_linkstatus_up(sc); /* notify upper layers */
+      break;
+    case PPPOE_CODE_PADT:
+      if (sc == NULL) {
+        goto done;
+      }
+      pppoe_clear_softc(sc, "received PADT");
+      break;
+    default:
+      if(sc) {
+        printf("%c%c%"U16_F": unknown code (0x%"X16_F") session = 0x%"X16_F"\n",
+            sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num,
+            (u16_t)ph->code, session);
+      } else {
+        printf("pppoe: unknown code (0x%"X16_F") session = 0x%"X16_F"\n", (u16_t)ph->code, session);
+      }
+      break;
+  }
+
+done:
+  pbuf_free(pb);
+  return;
+}
+
+void
+pppoe_disc_input(struct netif *netif, struct pbuf *p)
+{
+  /* avoid error messages if there is not a single pppoe instance */
+  if (pppoe_softc_list != NULL) {
+    pppoe_dispatch_disc_pkt(netif, p);
+  } else {
+    pbuf_free(p);
+  }
+}
+
+void
+pppoe_data_input(struct netif *netif, struct pbuf *pb)
+{
+  u16_t session, plen;
+  struct pppoe_softc *sc;
+  struct pppoehdr *ph;
+#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
+  u8_t shost[ETHER_ADDR_LEN];
+#endif
+
+#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
+  MEMCPY(shost, ((struct eth_hdr *)pb->payload)->src.addr, sizeof(shost));
+#endif
+  if (pbuf_header(pb, -(int)sizeof(struct eth_hdr)) != 0) {
+    /* bail out */
+    PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_header failed\n"));
+    LINK_STATS_INC(link.lenerr);
+    goto drop;
+  } 
+
+  pb = pppSingleBuf (pb);
+
+  if (pb->len <= PPPOE_HEADERLEN) {
+    printf("pppoe (data): dropping too short packet: %d bytes\n", pb->len);
+    goto drop;
+  }
+
+  if (pb->len < sizeof(*ph)) {
+    printf("pppoe_data_input: could not get PPPoE header\n");
+    goto drop;
+  }
+  ph = (struct pppoehdr *)pb->payload;
+
+  if (ph->vertype != PPPOE_VERTYPE) {
+    printf("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype);
+    goto drop;
+  }
+  if (ph->code != 0) {
+    goto drop;
+  }
+
+  session = ntohs(ph->session);
+  sc = pppoe_find_softc_by_session(session, netif);
+  if (sc == NULL) {
+#ifdef PPPOE_TERM_UNKNOWN_SESSIONS
+    printf("pppoe: input for unknown session 0x%x, sending PADT\n", session);
+    pppoe_send_padt(netif, session, shost);
+#endif
+    goto drop;
+  }
+
+  plen = ntohs(ph->plen);
+
+  if (pbuf_header(pb, -(int)(PPPOE_HEADERLEN)) != 0) {
+    /* bail out */
+    PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_header PPPOE_HEADERLEN failed\n"));
+    LINK_STATS_INC(link.lenerr);
+    goto drop;
+  } 
+
+  PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: %c%c%"U16_F": pkthdr.len=%d, pppoe.len=%d\n",
+        sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num,
+        pb->len, plen));
+
+  if (pb->len < plen) {
+    goto drop;
+  }
+
+  pppInProcOverEthernet(sc->sc_pd, pb);
+
+  return;
+
+drop:
+  pbuf_free(pb);
+}
+
+static err_t
+pppoe_output(struct pppoe_softc *sc, struct pbuf *pb)
+{
+  struct eth_hdr *ethhdr;
+  u16_t etype;
+  err_t res;
+
+  if (!sc->sc_ethif) {
+    pbuf_free(pb);
+    return ERR_IF;
+  }
+
+  ethhdr = (struct eth_hdr *)pb->payload;
+  etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHTYPE_PPPOE : ETHTYPE_PPPOEDISC;
+  ethhdr->type = htons(etype);
+  MEMCPY(ethhdr->dest.addr, sc->sc_dest.addr, sizeof(ethhdr->dest.addr));
+  MEMCPY(ethhdr->src.addr, ((struct eth_addr *)sc->sc_ethif->hwaddr)->addr, sizeof(ethhdr->src.addr));
+
+  PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F" (%x) state=%d, session=0x%x output -> %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F", len=%d\n",
+      sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, etype,
+      sc->sc_state, sc->sc_session,
+      sc->sc_dest.addr[0], sc->sc_dest.addr[1], sc->sc_dest.addr[2], sc->sc_dest.addr[3], sc->sc_dest.addr[4], sc->sc_dest.addr[5],
+      pb->tot_len));
+
+  res = sc->sc_ethif->linkoutput(sc->sc_ethif, pb);
+
+  pbuf_free(pb);
+
+  return res;
+}
+
+static err_t
+pppoe_send_padi(struct pppoe_softc *sc)
+{
+  struct pbuf *pb;
+  u8_t *p;
+  int len;
+#ifdef PPPOE_TODO
+  int l1 = 0, l2 = 0; /* XXX: gcc */
+#endif /* PPPOE_TODO */
+
+  if (sc->sc_state >PPPOE_STATE_PADI_SENT) {
+    PPPDEBUG(LOG_ERR, ("ERROR: pppoe_send_padi in state %d", sc->sc_state));
+  }
+
+  /* calculate length of frame (excluding ethernet header + pppoe header) */
+  len = 2 + 2 + 2 + 2 + sizeof sc;  /* service name tag is required, host unique is send too */
+#ifdef PPPOE_TODO
+  if (sc->sc_service_name != NULL) {
+    l1 = (int)strlen(sc->sc_service_name);
+    len += l1;
+  }
+  if (sc->sc_concentrator_name != NULL) {
+    l2 = (int)strlen(sc->sc_concentrator_name);
+    len += 2 + 2 + l2;
+  }
+#endif /* PPPOE_TODO */
+  LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff",
+    sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff);
+
+  /* allocate a buffer */
+  pb = pbuf_alloc(PBUF_LINK, (u16_t)(sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len), PBUF_RAM);
+  if (!pb) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+
+  p = (u8_t*)pb->payload + sizeof (struct eth_hdr);
+  /* fill in pkt */
+  PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, (u16_t)len);
+  PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
+#ifdef PPPOE_TODO
+  if (sc->sc_service_name != NULL) {
+    PPPOE_ADD_16(p, l1);
+    MEMCPY(p, sc->sc_service_name, l1);
+    p += l1;
+  } else
+#endif /* PPPOE_TODO */
+  {
+    PPPOE_ADD_16(p, 0);
+  }
+#ifdef PPPOE_TODO
+  if (sc->sc_concentrator_name != NULL) {
+    PPPOE_ADD_16(p, PPPOE_TAG_ACNAME);
+    PPPOE_ADD_16(p, l2);
+    MEMCPY(p, sc->sc_concentrator_name, l2);
+    p += l2;
+  }
+#endif /* PPPOE_TODO */
+  PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
+  PPPOE_ADD_16(p, sizeof(sc));
+  MEMCPY(p, &sc, sizeof sc);
+
+  /* send pkt */
+  return pppoe_output(sc, pb);
+}
+
+static void
+pppoe_timeout(void *arg)
+{
+  int retry_wait, err;
+  struct pppoe_softc *sc = (struct pppoe_softc*)arg;
+
+  PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": timeout\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
+
+  switch (sc->sc_state) {
+    case PPPOE_STATE_PADI_SENT:
+      /*
+       * We have two basic ways of retrying:
+       *  - Quick retry mode: try a few times in short sequence
+       *  - Slow retry mode: we already had a connection successfully
+       *    established and will try infinitely (without user
+       *    intervention)
+       * We only enter slow retry mode if IFF_LINK1 (aka autodial)
+       * is not set.
+       */
+
+      /* initialize for quick retry mode */
+      retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried);
+
+      sc->sc_padi_retried++;
+      if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) {
+#if 0
+        if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) {
+          /* slow retry mode */
+          retry_wait = PPPOE_SLOW_RETRY;
+        } else
+#endif
+        {
+          pppoe_abort_connect(sc);
+          return;
+        }
+      }
+      if ((err = pppoe_send_padi(sc)) != 0) {
+        sc->sc_padi_retried--;
+        PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to transmit PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
+      }
+      sys_timeout(retry_wait, pppoe_timeout, sc);
+      break;
+
+    case PPPOE_STATE_PADR_SENT:
+      sc->sc_padr_retried++;
+      if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) {
+        MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
+        sc->sc_state = PPPOE_STATE_PADI_SENT;
+        sc->sc_padr_retried = 0;
+        if ((err = pppoe_send_padi(sc)) != 0) {
+          PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
+        }
+        sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc);
+        return;
+      }
+      if ((err = pppoe_send_padr(sc)) != 0) {
+        sc->sc_padr_retried--;
+        PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
+      }
+      sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc);
+      break;
+    case PPPOE_STATE_CLOSING:
+      pppoe_do_disconnect(sc);
+      break;
+    default:
+      return;  /* all done, work in peace */
+  }
+}
+
+/* Start a connection (i.e. initiate discovery phase) */
+int
+pppoe_connect(struct pppoe_softc *sc)
+{
+  int err;
+
+  if (sc->sc_state != PPPOE_STATE_INITIAL) {
+    return EBUSY;
+  }
+
+#ifdef PPPOE_SERVER
+  /* wait PADI if IFF_PASSIVE */
+  if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) {
+    return 0;
+  }
+#endif
+  /* save state, in case we fail to send PADI */
+  sc->sc_state = PPPOE_STATE_PADI_SENT;
+  sc->sc_padr_retried = 0;
+  err = pppoe_send_padi(sc);
+  PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
+  sys_timeout(PPPOE_DISC_TIMEOUT, pppoe_timeout, sc);
+  return err;
+}
+
+/* disconnect */
+void
+pppoe_disconnect(struct pppoe_softc *sc)
+{
+  if (sc->sc_state < PPPOE_STATE_SESSION) {
+    return;
+  }
+  /*
+   * Do not call pppoe_disconnect here, the upper layer state
+   * machine gets confused by this. We must return from this
+   * function and defer disconnecting to the timeout handler.
+   */
+  sc->sc_state = PPPOE_STATE_CLOSING;
+  sys_timeout(20, pppoe_timeout, sc);
+}
+
+static int
+pppoe_do_disconnect(struct pppoe_softc *sc)
+{
+  int err;
+
+  if (sc->sc_state < PPPOE_STATE_SESSION) {
+    err = EBUSY;
+  } else {
+    PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
+    err = pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest);
+  }
+
+  /* cleanup softc */
+  sc->sc_state = PPPOE_STATE_INITIAL;
+  MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
+  sc->sc_ac_cookie_len = 0;
+#ifdef PPPOE_SERVER
+  if (sc->sc_hunique) {
+    mem_free(sc->sc_hunique);
+    sc->sc_hunique = NULL;
+  }
+  sc->sc_hunique_len = 0;
+#endif
+  sc->sc_session = 0;
+
+  sc->sc_linkStatusCB(sc->sc_pd, 0); /* notify upper layers */
+
+  return err;
+}
+
+/* Connection attempt aborted */
+static void
+pppoe_abort_connect(struct pppoe_softc *sc)
+{
+  printf("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num);
+  sc->sc_state = PPPOE_STATE_CLOSING;
+
+  sc->sc_linkStatusCB(sc->sc_pd, 0); /* notify upper layers */
+
+  /* clear connection state */
+  MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
+  sc->sc_state = PPPOE_STATE_INITIAL;
+}
+
+/* Send a PADR packet */
+static err_t
+pppoe_send_padr(struct pppoe_softc *sc)
+{
+  struct pbuf *pb;
+  u8_t *p;
+  size_t len;
+#ifdef PPPOE_TODO
+  size_t l1 = 0; /* XXX: gcc */
+#endif /* PPPOE_TODO */
+
+  if (sc->sc_state != PPPOE_STATE_PADR_SENT) {
+    return ERR_CONN;
+  }
+
+  len = 2 + 2 + 2 + 2 + sizeof(sc);    /* service name, host unique */
+#ifdef PPPOE_TODO
+  if (sc->sc_service_name != NULL) {    /* service name tag maybe empty */
+    l1 = strlen(sc->sc_service_name);
+    len += l1;
+  }
+#endif /* PPPOE_TODO */
+  if (sc->sc_ac_cookie_len > 0) {
+    len += 2 + 2 + sc->sc_ac_cookie_len;  /* AC cookie */
+  }
+  LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff",
+    sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff);
+  pb = pbuf_alloc(PBUF_LINK, (u16_t)(sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len), PBUF_RAM);
+  if (!pb) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+  p = (u8_t*)pb->payload + sizeof (struct eth_hdr);
+  PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len);
+  PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
+#ifdef PPPOE_TODO
+  if (sc->sc_service_name != NULL) {
+    PPPOE_ADD_16(p, l1);
+    MEMCPY(p, sc->sc_service_name, l1);
+    p += l1;
+  } else
+#endif /* PPPOE_TODO */
+  {
+    PPPOE_ADD_16(p, 0);
+  }
+  if (sc->sc_ac_cookie_len > 0) {
+    PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
+    PPPOE_ADD_16(p, sc->sc_ac_cookie_len);
+    MEMCPY(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len);
+    p += sc->sc_ac_cookie_len;
+  }
+  PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
+  PPPOE_ADD_16(p, sizeof(sc));
+  MEMCPY(p, &sc, sizeof sc);
+
+  return pppoe_output(sc, pb);
+}
+
+/* send a PADT packet */
+static err_t
+pppoe_send_padt(struct netif *outgoing_if, u_int session, const u8_t *dest)
+{
+  struct pbuf *pb;
+  struct eth_hdr *ethhdr;
+  err_t res;
+  u8_t *p;
+
+  pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN, PBUF_RAM);
+  if (!pb) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+
+  ethhdr = (struct eth_hdr *)pb->payload;
+  ethhdr->type = PP_HTONS(ETHTYPE_PPPOEDISC);
+  MEMCPY(ethhdr->dest.addr, dest, sizeof(ethhdr->dest.addr));
+  MEMCPY(ethhdr->src.addr, ((struct eth_addr *)outgoing_if->hwaddr)->addr, sizeof(ethhdr->src.addr));
+
+  p = (u8_t*)(ethhdr + 1);
+  PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0);
+
+  res = outgoing_if->linkoutput(outgoing_if, pb);
+
+  pbuf_free(pb);
+
+  return res;
+}
+
+#ifdef PPPOE_SERVER
+static err_t
+pppoe_send_pado(struct pppoe_softc *sc)
+{
+  struct pbuf *pb;
+  u8_t *p;
+  size_t len;
+
+  if (sc->sc_state != PPPOE_STATE_PADO_SENT) {
+    return ERR_CONN;
+  }
+
+  /* calc length */
+  len = 0;
+  /* include ac_cookie */
+  len += 2 + 2 + sizeof(sc);
+  /* include hunique */
+  len += 2 + 2 + sc->sc_hunique_len;
+  pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM);
+  if (!pb) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+  p = (u8_t*)pb->payload + sizeof (struct eth_hdr);
+  PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len);
+  PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
+  PPPOE_ADD_16(p, sizeof(sc));
+  MEMCPY(p, &sc, sizeof(sc));
+  p += sizeof(sc);
+  PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
+  PPPOE_ADD_16(p, sc->sc_hunique_len);
+  MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len);
+  return pppoe_output(sc, pb);
+}
+
+static err_t
+pppoe_send_pads(struct pppoe_softc *sc)
+{
+  struct pbuf *pb;
+  u8_t *p;
+  size_t len, l1 = 0;  /* XXX: gcc */
+
+  if (sc->sc_state != PPPOE_STATE_PADO_SENT) {
+    return ERR_CONN;
+  }
+
+  sc->sc_session = mono_time.tv_sec % 0xff + 1;
+  /* calc length */
+  len = 0;
+  /* include hunique */
+  len += 2 + 2 + 2 + 2 + sc->sc_hunique_len;  /* service name, host unique*/
+  if (sc->sc_service_name != NULL) {    /* service name tag maybe empty */
+    l1 = strlen(sc->sc_service_name);
+    len += l1;
+  }
+  pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM);
+  if (!pb) {
+    return ERR_MEM;
+  }
+  LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
+  p = (u8_t*)pb->payload + sizeof (struct eth_hdr);
+  PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len);
+  PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
+  if (sc->sc_service_name != NULL) {
+    PPPOE_ADD_16(p, l1);
+    MEMCPY(p, sc->sc_service_name, l1);
+    p += l1;
+  } else {
+    PPPOE_ADD_16(p, 0);
+  }
+  PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
+  PPPOE_ADD_16(p, sc->sc_hunique_len);
+  MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len);
+  return pppoe_output(sc, pb);
+}
+#endif
+
+err_t
+pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb)
+{
+  u8_t *p;
+  size_t len;
+
+  /* are we ready to process data yet? */
+  if (sc->sc_state < PPPOE_STATE_SESSION) {
+    /*sppp_flush(&sc->sc_sppp.pp_if);*/
+    pbuf_free(pb);
+    return ERR_CONN;
+  }
+
+  len = pb->tot_len;
+
+  /* make room for Ethernet header - should not fail */
+  if (pbuf_header(pb, sizeof(struct eth_hdr) + PPPOE_HEADERLEN) != 0) {
+    /* bail out */
+    PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
+    LINK_STATS_INC(link.lenerr);
+    pbuf_free(pb);
+    return ERR_BUF;
+  } 
+
+  p = (u8_t*)pb->payload + sizeof(struct eth_hdr);
+  PPPOE_ADD_HEADER(p, 0, sc->sc_session, len);
+
+  return pppoe_output(sc, pb);
+}
+
+#if 0 /*def PFIL_HOOKS*/
+static int
+pppoe_ifattach_hook(void *arg, struct pbuf **mp, struct netif *ifp, int dir)
+{
+  struct pppoe_softc *sc;
+  int s;
+
+  if (mp != (struct pbuf **)PFIL_IFNET_DETACH) {
+    return 0;
+  }
+
+  LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
+    if (sc->sc_ethif != ifp) {
+      continue;
+    }
+    if (sc->sc_sppp.pp_if.if_flags & IFF_UP) {
+      sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
+      printf("%c%c%"U16_F": ethernet interface detached, going down\n",
+          sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num);
+    }
+    sc->sc_ethif = NULL;
+    pppoe_clear_softc(sc, "ethernet interface detached");
+  }
+
+  return 0;
+}
+#endif
+
+static void
+pppoe_clear_softc(struct pppoe_softc *sc, const char *message)
+{
+  LWIP_UNUSED_ARG(message);
+
+  /* stop timer */
+  sys_untimeout(pppoe_timeout, sc);
+  PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x terminated, %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_session, message));
+
+  /* fix our state */
+  sc->sc_state = PPPOE_STATE_INITIAL;
+
+  /* notify upper layers */
+  sc->sc_linkStatusCB(sc->sc_pd, 0);
+
+  /* clean up softc */
+  MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
+  sc->sc_ac_cookie_len = 0;
+  sc->sc_session = 0;
+}
+
+#endif /* PPPOE_SUPPORT */
+
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/pppdebug.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/pppdebug.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/pppdebug.h	(revision 164)
@@ -0,0 +1,73 @@
+/*****************************************************************************
+* pppdebug.h - System debugging utilities.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* portions Copyright (c) 1998 Global Election Systems Inc.
+* portions Copyright (c) 2001 by Cognizant Pty Ltd.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY (please don't use tabs!)
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 98-07-29 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Original.
+*
+*****************************************************************************
+*/
+#ifndef PPPDEBUG_H
+#define PPPDEBUG_H
+
+/* Trace levels. */
+#define LOG_CRITICAL  (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE)
+#define LOG_ERR       (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE)
+#define LOG_NOTICE    (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING)
+#define LOG_WARNING   (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING)
+#define LOG_INFO      (PPP_DEBUG)
+#define LOG_DETAIL    (PPP_DEBUG)
+#define LOG_DEBUG     (PPP_DEBUG)
+
+
+#define TRACELCP PPP_DEBUG
+
+#if PPP_DEBUG
+
+#define AUTHDEBUG(a, b) LWIP_DEBUGF(a, b)
+#define IPCPDEBUG(a, b) LWIP_DEBUGF(a, b)
+#define UPAPDEBUG(a, b) LWIP_DEBUGF(a, b)
+#define LCPDEBUG(a, b)  LWIP_DEBUGF(a, b)
+#define FSMDEBUG(a, b)  LWIP_DEBUGF(a, b)
+#define CHAPDEBUG(a, b) LWIP_DEBUGF(a, b)
+#define PPPDEBUG(a, b)  LWIP_DEBUGF(a, b)
+
+#else /* PPP_DEBUG */
+
+#define AUTHDEBUG(a, b)
+#define IPCPDEBUG(a, b)
+#define UPAPDEBUG(a, b)
+#define LCPDEBUG(a, b)
+#define FSMDEBUG(a, b)
+#define CHAPDEBUG(a, b)
+#define PPPDEBUG(a, b)
+
+#endif /* PPP_DEBUG */
+
+#endif /* PPPDEBUG_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/randm.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/randm.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/randm.c	(revision 164)
@@ -0,0 +1,249 @@
+/*****************************************************************************
+* randm.c - Random number generator program file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* Copyright (c) 1998 by Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 98-06-03 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
+*   Extracted from avos.
+*****************************************************************************/
+
+#include "lwip/opt.h"
+
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "md5.h"
+#include "randm.h"
+
+#include "ppp_impl.h"
+#include "pppdebug.h"
+
+#include <string.h>
+
+#if MD5_SUPPORT /* this module depends on MD5 */
+#define RANDPOOLSZ 16   /* Bytes stored in the pool of randomness. */
+
+/*****************************/
+/*** LOCAL DATA STRUCTURES ***/
+/*****************************/
+static char randPool[RANDPOOLSZ];   /* Pool of randomness. */
+static long randCount = 0;      /* Pseudo-random incrementer */
+
+
+/***********************************/
+/*** PUBLIC FUNCTION DEFINITIONS ***/
+/***********************************/
+/*
+ * Initialize the random number generator.
+ *
+ * Since this is to be called on power up, we don't have much
+ *  system randomess to work with.  Here all we use is the
+ *  real-time clock.  We'll accumulate more randomness as soon
+ *  as things start happening.
+ */
+void
+avRandomInit()
+{
+  avChurnRand(NULL, 0);
+}
+
+/*
+ * Churn the randomness pool on a random event.  Call this early and often
+ *  on random and semi-random system events to build randomness in time for
+ *  usage.  For randomly timed events, pass a null pointer and a zero length
+ *  and this will use the system timer and other sources to add randomness.
+ *  If new random data is available, pass a pointer to that and it will be
+ *  included.
+ *
+ * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427
+ */
+void
+avChurnRand(char *randData, u32_t randLen)
+{
+  MD5_CTX md5;
+
+  /* LWIP_DEBUGF(LOG_INFO, ("churnRand: %u@%P\n", randLen, randData)); */
+  MD5Init(&md5);
+  MD5Update(&md5, (u_char *)randPool, sizeof(randPool));
+  if (randData) {
+    MD5Update(&md5, (u_char *)randData, randLen);
+  } else {
+    struct {
+      /* INCLUDE fields for any system sources of randomness */
+      char foobar;
+    } sysData;
+
+    /* Load sysData fields here. */
+    MD5Update(&md5, (u_char *)&sysData, sizeof(sysData));
+  }
+  MD5Final((u_char *)randPool, &md5);
+/*  LWIP_DEBUGF(LOG_INFO, ("churnRand: -> 0\n")); */
+}
+
+/*
+ * Use the random pool to generate random data.  This degrades to pseudo
+ *  random when used faster than randomness is supplied using churnRand().
+ * Note: It's important that there be sufficient randomness in randPool
+ *  before this is called for otherwise the range of the result may be
+ *  narrow enough to make a search feasible.
+ *
+ * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427
+ *
+ * XXX Why does he not just call churnRand() for each block?  Probably
+ *  so that you don't ever publish the seed which could possibly help
+ *  predict future values.
+ * XXX Why don't we preserve md5 between blocks and just update it with
+ *  randCount each time?  Probably there is a weakness but I wish that
+ *  it was documented.
+ */
+void
+avGenRand(char *buf, u32_t bufLen)
+{
+  MD5_CTX md5;
+  u_char tmp[16];
+  u32_t n;
+
+  while (bufLen > 0) {
+    n = LWIP_MIN(bufLen, RANDPOOLSZ);
+    MD5Init(&md5);
+    MD5Update(&md5, (u_char *)randPool, sizeof(randPool));
+    MD5Update(&md5, (u_char *)&randCount, sizeof(randCount));
+    MD5Final(tmp, &md5);
+    randCount++;
+    MEMCPY(buf, tmp, n);
+    buf += n;
+    bufLen -= n;
+  }
+}
+
+/*
+ * Return a new random number.
+ */
+u32_t
+avRandom()
+{
+  u32_t newRand;
+
+  avGenRand((char *)&newRand, sizeof(newRand));
+
+  return newRand;
+}
+
+#else /* MD5_SUPPORT */
+
+/*****************************/
+/*** LOCAL DATA STRUCTURES ***/
+/*****************************/
+static int  avRandomized = 0;       /* Set when truely randomized. */
+static u32_t avRandomSeed = 0;      /* Seed used for random number generation. */
+
+
+/***********************************/
+/*** PUBLIC FUNCTION DEFINITIONS ***/
+/***********************************/
+/*
+ * Initialize the random number generator.
+ *
+ * Here we attempt to compute a random number seed but even if
+ * it isn't random, we'll randomize it later.
+ *
+ * The current method uses the fields from the real time clock,
+ * the idle process counter, the millisecond counter, and the
+ * hardware timer tick counter.  When this is invoked
+ * in startup(), then the idle counter and timer values may
+ * repeat after each boot and the real time clock may not be
+ * operational.  Thus we call it again on the first random
+ * event.
+ */
+void
+avRandomInit()
+{
+#if 0
+  /* Get a pointer into the last 4 bytes of clockBuf. */
+  u32_t *lptr1 = (u32_t *)((char *)&clockBuf[3]);
+
+  /*
+   * Initialize our seed using the real-time clock, the idle
+   * counter, the millisecond timer, and the hardware timer
+   * tick counter.  The real-time clock and the hardware
+   * tick counter are the best sources of randomness but
+   * since the tick counter is only 16 bit (and truncated
+   * at that), the idle counter and millisecond timer
+   * (which may be small values) are added to help
+   * randomize the lower 16 bits of the seed.
+   */
+  readClk();
+  avRandomSeed += *(u32_t *)clockBuf + *lptr1 + OSIdleCtr
+           + ppp_mtime() + ((u32_t)TM1 << 16) + TM1;
+#else
+  avRandomSeed += sys_jiffies(); /* XXX */
+#endif
+
+  /* Initialize the Borland random number generator. */
+  srand((unsigned)avRandomSeed);
+}
+
+/*
+ * Randomize our random seed value.  Here we use the fact that
+ * this function is called at *truely random* times by the polling
+ * and network functions.  Here we only get 16 bits of new random
+ * value but we use the previous value to randomize the other 16
+ * bits.
+ */
+void
+avRandomize(void)
+{
+  static u32_t last_jiffies;
+
+  if (!avRandomized) {
+    avRandomized = !0;
+    avRandomInit();
+    /* The initialization function also updates the seed. */
+  } else {
+    /* avRandomSeed += (avRandomSeed << 16) + TM1; */
+    avRandomSeed += (sys_jiffies() - last_jiffies); /* XXX */
+  }
+  last_jiffies = sys_jiffies();
+}
+
+/*
+ * Return a new random number.
+ * Here we use the Borland rand() function to supply a pseudo random
+ * number which we make truely random by combining it with our own
+ * seed which is randomized by truely random events. 
+ * Thus the numbers will be truely random unless there have been no
+ * operator or network events in which case it will be pseudo random
+ * seeded by the real time clock.
+ */
+u32_t
+avRandom()
+{
+  return ((((u32_t)rand() << 16) + rand()) + avRandomSeed);
+}
+
+#endif /* MD5_SUPPORT */
+
+#endif /* PPP_SUPPORT */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/randm.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/randm.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/randm.h	(revision 164)
@@ -0,0 +1,81 @@
+/*****************************************************************************
+* randm.h - Random number generator header file.
+*
+* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
+* Copyright (c) 1998 Global Election Systems Inc.
+*
+* The authors hereby grant permission to use, copy, modify, distribute,
+* and license this software and its documentation for any purpose, provided
+* that existing copyright notices are retained in all copies and that this
+* notice and the following disclaimer are included verbatim in any 
+* distributions. No written agreement, license, or royalty fee is required
+* for any of the authorized uses.
+*
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+* REVISION HISTORY
+*
+* 03-01-01 Marc Boucher <marc@mbsi.ca>
+*   Ported to lwIP.
+* 98-05-29 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
+*   Extracted from avos.
+*****************************************************************************/
+
+#ifndef RANDM_H
+#define RANDM_H
+
+/***********************
+*** PUBLIC FUNCTIONS ***
+***********************/
+/*
+ * Initialize the random number generator.
+ */
+void avRandomInit(void);
+
+/*
+ * Churn the randomness pool on a random event.  Call this early and often
+ * on random and semi-random system events to build randomness in time for
+ * usage.  For randomly timed events, pass a null pointer and a zero length
+ * and this will use the system timer and other sources to add randomness.
+ * If new random data is available, pass a pointer to that and it will be
+ * included.
+ */
+void avChurnRand(char *randData, u32_t randLen);
+
+/*
+ * Randomize our random seed value.  To be called for truely random events
+ * such as user operations and network traffic.
+ */
+#if MD5_SUPPORT
+#define avRandomize() avChurnRand(NULL, 0)
+#else  /* MD5_SUPPORT */
+void avRandomize(void);
+#endif /* MD5_SUPPORT */
+
+/*
+ * Use the random pool to generate random data.  This degrades to pseudo
+ * random when used faster than randomness is supplied using churnRand().
+ * Thus it's important to make sure that the results of this are not
+ * published directly because one could predict the next result to at
+ * least some degree.  Also, it's important to get a good seed before
+ * the first use.
+ */
+void avGenRand(char *buf, u32_t bufLen);
+
+/*
+ * Return a new random number.
+ */
+u32_t avRandom(void);
+
+
+#endif /* RANDM_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/vj.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/vj.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/vj.c	(revision 164)
@@ -0,0 +1,652 @@
+/*
+ * Routines to compress and uncompess tcp packets (for transmission
+ * over low speed serial lines.
+ *
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
+ *   Initial distribution.
+ *
+ * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au,
+ * so that the entire packet being decompressed doesn't have
+ * to be in contiguous memory (just the compressed header).
+ *
+ * Modified March 1998 by Guy Lancaster, glanca@gesn.com,
+ * for a 16 bit processor.
+ */
+
+#include "lwip/opt.h"
+
+#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
+
+#include "ppp_impl.h"
+#include "pppdebug.h"
+
+#include "vj.h"
+
+#include <string.h>
+
+#if VJ_SUPPORT
+
+#if LINK_STATS
+#define INCR(counter) ++comp->stats.counter
+#else
+#define INCR(counter)
+#endif
+
+void
+vj_compress_init(struct vjcompress *comp)
+{
+  register u_char i;
+  register struct cstate *tstate = comp->tstate;
+  
+#if MAX_SLOTS == 0
+  memset((char *)comp, 0, sizeof(*comp));
+#endif
+  comp->maxSlotIndex = MAX_SLOTS - 1;
+  comp->compressSlot = 0;    /* Disable slot ID compression by default. */
+  for (i = MAX_SLOTS - 1; i > 0; --i) {
+    tstate[i].cs_id = i;
+    tstate[i].cs_next = &tstate[i - 1];
+  }
+  tstate[0].cs_next = &tstate[MAX_SLOTS - 1];
+  tstate[0].cs_id = 0;
+  comp->last_cs = &tstate[0];
+  comp->last_recv = 255;
+  comp->last_xmit = 255;
+  comp->flags = VJF_TOSS;
+}
+
+
+/* ENCODE encodes a number that is known to be non-zero.  ENCODEZ
+ * checks for zero (since zero has to be encoded in the long, 3 byte
+ * form).
+ */
+#define ENCODE(n) { \
+  if ((u_short)(n) >= 256) { \
+    *cp++ = 0; \
+    cp[1] = (u_char)(n); \
+    cp[0] = (u_char)((n) >> 8); \
+    cp += 2; \
+  } else { \
+    *cp++ = (u_char)(n); \
+  } \
+}
+#define ENCODEZ(n) { \
+  if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \
+    *cp++ = 0; \
+    cp[1] = (u_char)(n); \
+    cp[0] = (u_char)((n) >> 8); \
+    cp += 2; \
+  } else { \
+    *cp++ = (u_char)(n); \
+  } \
+}
+
+#define DECODEL(f) { \
+  if (*cp == 0) {\
+    u32_t tmp = ntohl(f) + ((cp[1] << 8) | cp[2]); \
+    (f) = htonl(tmp); \
+    cp += 3; \
+  } else { \
+    u32_t tmp = ntohl(f) + (u32_t)*cp++; \
+    (f) = htonl(tmp); \
+  } \
+}
+
+#define DECODES(f) { \
+  if (*cp == 0) {\
+    u_short tmp = ntohs(f) + (((u_short)cp[1] << 8) | cp[2]); \
+    (f) = htons(tmp); \
+    cp += 3; \
+  } else { \
+    u_short tmp = ntohs(f) + (u_short)*cp++; \
+    (f) = htons(tmp); \
+  } \
+}
+
+#define DECODEU(f) { \
+  if (*cp == 0) {\
+    (f) = htons(((u_short)cp[1] << 8) | cp[2]); \
+    cp += 3; \
+  } else { \
+    (f) = htons((u_short)*cp++); \
+  } \
+}
+
+/*
+ * vj_compress_tcp - Attempt to do Van Jacobson header compression on a
+ * packet.  This assumes that nb and comp are not null and that the first
+ * buffer of the chain contains a valid IP header.
+ * Return the VJ type code indicating whether or not the packet was
+ * compressed.
+ */
+u_int
+vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
+{
+  register struct ip_hdr *ip = (struct ip_hdr *)pb->payload;
+  register struct cstate *cs = comp->last_cs->cs_next;
+  register u_short hlen = IPH_HL(ip);
+  register struct tcp_hdr *oth;
+  register struct tcp_hdr *th;
+  register u_short deltaS, deltaA;
+  register u_long deltaL;
+  register u_int changes = 0;
+  u_char new_seq[16];
+  register u_char *cp = new_seq;
+
+  /*  
+   * Check that the packet is IP proto TCP.
+   */
+  if (IPH_PROTO(ip) != IP_PROTO_TCP) {
+    return (TYPE_IP);
+  }
+
+  /*
+   * Bail if this is an IP fragment or if the TCP packet isn't
+   * `compressible' (i.e., ACK isn't set or some other control bit is
+   * set).  
+   */
+  if ((IPH_OFFSET(ip) & PP_HTONS(0x3fff)) || pb->tot_len < 40) {
+    return (TYPE_IP);
+  }
+  th = (struct tcp_hdr *)&((long *)ip)[hlen];
+  if ((TCPH_FLAGS(th) & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK) {
+    return (TYPE_IP);
+  }
+  /*
+   * Packet is compressible -- we're going to send either a
+   * COMPRESSED_TCP or UNCOMPRESSED_TCP packet.  Either way we need
+   * to locate (or create) the connection state.  Special case the
+   * most recently used connection since it's most likely to be used
+   * again & we don't have to do any reordering if it's used.
+   */
+  INCR(vjs_packets);
+  if (!ip_addr_cmp(&ip->src, &cs->cs_ip.src)
+      || !ip_addr_cmp(&ip->dest, &cs->cs_ip.dest)
+      || *(long *)th != ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) {
+    /*
+     * Wasn't the first -- search for it.
+     *
+     * States are kept in a circularly linked list with
+     * last_cs pointing to the end of the list.  The
+     * list is kept in lru order by moving a state to the
+     * head of the list whenever it is referenced.  Since
+     * the list is short and, empirically, the connection
+     * we want is almost always near the front, we locate
+     * states via linear search.  If we don't find a state
+     * for the datagram, the oldest state is (re-)used.
+     */
+    register struct cstate *lcs;
+    register struct cstate *lastcs = comp->last_cs;
+    
+    do {
+      lcs = cs; cs = cs->cs_next;
+      INCR(vjs_searches);
+      if (ip_addr_cmp(&ip->src, &cs->cs_ip.src)
+          && ip_addr_cmp(&ip->dest, &cs->cs_ip.dest)
+          && *(long *)th == ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) {
+        goto found;
+      }
+    } while (cs != lastcs);
+
+    /*
+     * Didn't find it -- re-use oldest cstate.  Send an
+     * uncompressed packet that tells the other side what
+     * connection number we're using for this conversation.
+     * Note that since the state list is circular, the oldest
+     * state points to the newest and we only need to set
+     * last_cs to update the lru linkage.
+     */
+    INCR(vjs_misses);
+    comp->last_cs = lcs;
+    hlen += TCPH_HDRLEN(th);
+    hlen <<= 2;
+    /* Check that the IP/TCP headers are contained in the first buffer. */
+    if (hlen > pb->len) {
+      return (TYPE_IP);
+    }
+    goto uncompressed;
+
+    found:
+    /*
+     * Found it -- move to the front on the connection list.
+     */
+    if (cs == lastcs) {
+      comp->last_cs = lcs;
+    } else {
+      lcs->cs_next = cs->cs_next;
+      cs->cs_next = lastcs->cs_next;
+      lastcs->cs_next = cs;
+    }
+  }
+
+  oth = (struct tcp_hdr *)&((long *)&cs->cs_ip)[hlen];
+  deltaS = hlen;
+  hlen += TCPH_HDRLEN(th);
+  hlen <<= 2;
+  /* Check that the IP/TCP headers are contained in the first buffer. */
+  if (hlen > pb->len) {
+    PPPDEBUG(LOG_INFO, ("vj_compress_tcp: header len %d spans buffers\n", hlen));
+    return (TYPE_IP);
+  }
+
+  /*
+   * Make sure that only what we expect to change changed. The first
+   * line of the `if' checks the IP protocol version, header length &
+   * type of service.  The 2nd line checks the "Don't fragment" bit.
+   * The 3rd line checks the time-to-live and protocol (the protocol
+   * check is unnecessary but costless).  The 4th line checks the TCP
+   * header length.  The 5th line checks IP options, if any.  The 6th
+   * line checks TCP options, if any.  If any of these things are
+   * different between the previous & current datagram, we send the
+   * current datagram `uncompressed'.
+   */
+  if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] 
+      || ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] 
+      || ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] 
+      || TCPH_HDRLEN(th) != TCPH_HDRLEN(oth) 
+      || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) 
+      || (TCPH_HDRLEN(th) > 5 && BCMP(th + 1, oth + 1, (TCPH_HDRLEN(th) - 5) << 2))) {
+    goto uncompressed;
+  }
+
+  /*
+   * Figure out which of the changing fields changed.  The
+   * receiver expects changes in the order: urgent, window,
+   * ack, seq (the order minimizes the number of temporaries
+   * needed in this section of code).
+   */
+  if (TCPH_FLAGS(th) & TCP_URG) {
+    deltaS = ntohs(th->urgp);
+    ENCODEZ(deltaS);
+    changes |= NEW_U;
+  } else if (th->urgp != oth->urgp) {
+    /* argh! URG not set but urp changed -- a sensible
+     * implementation should never do this but RFC793
+     * doesn't prohibit the change so we have to deal
+     * with it. */
+    goto uncompressed;
+  }
+
+  if ((deltaS = (u_short)(ntohs(th->wnd) - ntohs(oth->wnd))) != 0) {
+    ENCODE(deltaS);
+    changes |= NEW_W;
+  }
+
+  if ((deltaL = ntohl(th->ackno) - ntohl(oth->ackno)) != 0) {
+    if (deltaL > 0xffff) {
+      goto uncompressed;
+    }
+    deltaA = (u_short)deltaL;
+    ENCODE(deltaA);
+    changes |= NEW_A;
+  }
+
+  if ((deltaL = ntohl(th->seqno) - ntohl(oth->seqno)) != 0) {
+    if (deltaL > 0xffff) {
+      goto uncompressed;
+    }
+    deltaS = (u_short)deltaL;
+    ENCODE(deltaS);
+    changes |= NEW_S;
+  }
+
+  switch(changes) {
+  case 0:
+    /*
+     * Nothing changed. If this packet contains data and the
+     * last one didn't, this is probably a data packet following
+     * an ack (normal on an interactive connection) and we send
+     * it compressed.  Otherwise it's probably a retransmit,
+     * retransmitted ack or window probe.  Send it uncompressed
+     * in case the other side missed the compressed version.
+     */
+    if (IPH_LEN(ip) != IPH_LEN(&cs->cs_ip) &&
+      ntohs(IPH_LEN(&cs->cs_ip)) == hlen) {
+      break;
+    }
+
+  /* (fall through) */
+
+  case SPECIAL_I:
+  case SPECIAL_D:
+    /*
+     * actual changes match one of our special case encodings --
+     * send packet uncompressed.
+     */
+    goto uncompressed;
+
+  case NEW_S|NEW_A:
+    if (deltaS == deltaA && deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) {
+      /* special case for echoed terminal traffic */
+      changes = SPECIAL_I;
+      cp = new_seq;
+    }
+    break;
+
+  case NEW_S:
+    if (deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) {
+      /* special case for data xfer */
+      changes = SPECIAL_D;
+      cp = new_seq;
+    }
+    break;
+  }
+
+  deltaS = (u_short)(ntohs(IPH_ID(ip)) - ntohs(IPH_ID(&cs->cs_ip)));
+  if (deltaS != 1) {
+    ENCODEZ(deltaS);
+    changes |= NEW_I;
+  }
+  if (TCPH_FLAGS(th) & TCP_PSH) {
+    changes |= TCP_PUSH_BIT;
+  }
+  /*
+   * Grab the cksum before we overwrite it below.  Then update our
+   * state with this packet's header.
+   */
+  deltaA = ntohs(th->chksum);
+  BCOPY(ip, &cs->cs_ip, hlen);
+
+  /*
+   * We want to use the original packet as our compressed packet.
+   * (cp - new_seq) is the number of bytes we need for compressed
+   * sequence numbers.  In addition we need one byte for the change
+   * mask, one for the connection id and two for the tcp checksum.
+   * So, (cp - new_seq) + 4 bytes of header are needed.  hlen is how
+   * many bytes of the original packet to toss so subtract the two to
+   * get the new packet size.
+   */
+  deltaS = (u_short)(cp - new_seq);
+  if (!comp->compressSlot || comp->last_xmit != cs->cs_id) {
+    comp->last_xmit = cs->cs_id;
+    hlen -= deltaS + 4;
+    if(pbuf_header(pb, -hlen)){
+      /* Can we cope with this failing?  Just assert for now */
+      LWIP_ASSERT("pbuf_header failed\n", 0);
+    }
+    cp = (u_char *)pb->payload;
+    *cp++ = (u_char)(changes | NEW_C);
+    *cp++ = cs->cs_id;
+  } else {
+    hlen -= deltaS + 3;
+    if(pbuf_header(pb, -hlen)) {
+      /* Can we cope with this failing?  Just assert for now */
+      LWIP_ASSERT("pbuf_header failed\n", 0);
+    }
+    cp = (u_char *)pb->payload;
+    *cp++ = (u_char)changes;
+  }
+  *cp++ = (u_char)(deltaA >> 8);
+  *cp++ = (u_char)deltaA;
+  BCOPY(new_seq, cp, deltaS);
+  INCR(vjs_compressed);
+  return (TYPE_COMPRESSED_TCP);
+
+  /*
+   * Update connection state cs & send uncompressed packet (that is,
+   * a regular ip/tcp packet but with the 'conversation id' we hope
+   * to use on future compressed packets in the protocol field).
+   */
+uncompressed:
+  BCOPY(ip, &cs->cs_ip, hlen);
+  IPH_PROTO_SET(ip, cs->cs_id);
+  comp->last_xmit = cs->cs_id;
+  return (TYPE_UNCOMPRESSED_TCP);
+}
+
+/*
+ * Called when we may have missed a packet.
+ */
+void
+vj_uncompress_err(struct vjcompress *comp)
+{
+  comp->flags |= VJF_TOSS;
+  INCR(vjs_errorin);
+}
+
+/*
+ * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP.
+ * Return 0 on success, -1 on failure.
+ */
+int
+vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp)
+{
+  register u_int hlen;
+  register struct cstate *cs;
+  register struct ip_hdr *ip;
+  
+  ip = (struct ip_hdr *)nb->payload;
+  hlen = IPH_HL(ip) << 2;
+  if (IPH_PROTO(ip) >= MAX_SLOTS
+      || hlen + sizeof(struct tcp_hdr) > nb->len
+      || (hlen += TCPH_HDRLEN(((struct tcp_hdr *)&((char *)ip)[hlen])) << 2)
+          > nb->len
+      || hlen > MAX_HDR) {
+    PPPDEBUG(LOG_INFO, ("vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", 
+      IPH_PROTO(ip), hlen, nb->len));
+    comp->flags |= VJF_TOSS;
+    INCR(vjs_errorin);
+    return -1;
+  }
+  cs = &comp->rstate[comp->last_recv = IPH_PROTO(ip)];
+  comp->flags &=~ VJF_TOSS;
+  IPH_PROTO_SET(ip, IP_PROTO_TCP);
+  BCOPY(ip, &cs->cs_ip, hlen);
+  cs->cs_hlen = (u_short)hlen;
+  INCR(vjs_uncompressedin);
+  return 0;
+}
+
+/*
+ * Uncompress a packet of type TYPE_COMPRESSED_TCP.
+ * The packet is composed of a buffer chain and the first buffer
+ * must contain an accurate chain length.
+ * The first buffer must include the entire compressed TCP/IP header. 
+ * This procedure replaces the compressed header with the uncompressed
+ * header and returns the length of the VJ header.
+ */
+int
+vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp)
+{
+  u_char *cp;
+  struct tcp_hdr *th;
+  struct cstate *cs;
+  u_short *bp;
+  struct pbuf *n0 = *nb;
+  u32_t tmp;
+  u_int vjlen, hlen, changes;
+
+  INCR(vjs_compressedin);
+  cp = (u_char *)n0->payload;
+  changes = *cp++;
+  if (changes & NEW_C) {
+    /* 
+     * Make sure the state index is in range, then grab the state.
+     * If we have a good state index, clear the 'discard' flag. 
+     */
+    if (*cp >= MAX_SLOTS) {
+      PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: bad cid=%d\n", *cp));
+      goto bad;
+    }
+
+    comp->flags &=~ VJF_TOSS;
+    comp->last_recv = *cp++;
+  } else {
+    /* 
+     * this packet has an implicit state index.  If we've
+     * had a line error since the last time we got an
+     * explicit state index, we have to toss the packet. 
+     */
+    if (comp->flags & VJF_TOSS) {
+      PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: tossing\n"));
+      INCR(vjs_tossed);
+      return (-1);
+    }
+  }
+  cs = &comp->rstate[comp->last_recv];
+  hlen = IPH_HL(&cs->cs_ip) << 2;
+  th = (struct tcp_hdr *)&((u_char *)&cs->cs_ip)[hlen];
+  th->chksum = htons((*cp << 8) | cp[1]);
+  cp += 2;
+  if (changes & TCP_PUSH_BIT) {
+    TCPH_SET_FLAG(th, TCP_PSH);
+  } else {
+    TCPH_UNSET_FLAG(th, TCP_PSH);
+  }
+
+  switch (changes & SPECIALS_MASK) {
+  case SPECIAL_I:
+    {
+      register u32_t i = ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen;
+      /* some compilers can't nest inline assembler.. */
+      tmp = ntohl(th->ackno) + i;
+      th->ackno = htonl(tmp);
+      tmp = ntohl(th->seqno) + i;
+      th->seqno = htonl(tmp);
+    }
+    break;
+
+  case SPECIAL_D:
+    /* some compilers can't nest inline assembler.. */
+    tmp = ntohl(th->seqno) + ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen;
+    th->seqno = htonl(tmp);
+    break;
+
+  default:
+    if (changes & NEW_U) {
+      TCPH_SET_FLAG(th, TCP_URG);
+      DECODEU(th->urgp);
+    } else {
+      TCPH_UNSET_FLAG(th, TCP_URG);
+    }
+    if (changes & NEW_W) {
+      DECODES(th->wnd);
+    }
+    if (changes & NEW_A) {
+      DECODEL(th->ackno);
+    }
+    if (changes & NEW_S) {
+      DECODEL(th->seqno);
+    }
+    break;
+  }
+  if (changes & NEW_I) {
+    DECODES(cs->cs_ip._id);
+  } else {
+    IPH_ID_SET(&cs->cs_ip, ntohs(IPH_ID(&cs->cs_ip)) + 1);
+    IPH_ID_SET(&cs->cs_ip, htons(IPH_ID(&cs->cs_ip)));
+  }
+
+  /*
+   * At this point, cp points to the first byte of data in the
+   * packet.  Fill in the IP total length and update the IP
+   * header checksum.
+   */
+  vjlen = (u_short)(cp - (u_char*)n0->payload);
+  if (n0->len < vjlen) {
+    /* 
+     * We must have dropped some characters (crc should detect
+     * this but the old slip framing won't) 
+     */
+    PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: head buffer %d too short %d\n", 
+          n0->len, vjlen));
+    goto bad;
+  }
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+  tmp = n0->tot_len - vjlen + cs->cs_hlen;
+  IPH_LEN_SET(&cs->cs_ip, htons((u_short)tmp));
+#else
+  IPH_LEN_SET(&cs->cs_ip, htons(n0->tot_len - vjlen + cs->cs_hlen));
+#endif
+
+  /* recompute the ip header checksum */
+  bp = (u_short *) &cs->cs_ip;
+  IPH_CHKSUM_SET(&cs->cs_ip, 0);
+  for (tmp = 0; hlen > 0; hlen -= 2) {
+    tmp += *bp++;
+  }
+  tmp = (tmp & 0xffff) + (tmp >> 16);
+  tmp = (tmp & 0xffff) + (tmp >> 16);
+  IPH_CHKSUM_SET(&cs->cs_ip,  (u_short)(~tmp));
+  
+  /* Remove the compressed header and prepend the uncompressed header. */
+  if(pbuf_header(n0, -((s16_t)(vjlen)))) {
+    /* Can we cope with this failing?  Just assert for now */
+    LWIP_ASSERT("pbuf_header failed\n", 0);
+    goto bad;
+  }
+
+  if(LWIP_MEM_ALIGN(n0->payload) != n0->payload) {
+    struct pbuf *np, *q;
+    u8_t *bufptr;
+
+    np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL);
+    if(!np) {
+      PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: realign failed\n"));
+      goto bad;
+    }
+
+    if(pbuf_header(np, -cs->cs_hlen)) {
+      /* Can we cope with this failing?  Just assert for now */
+      LWIP_ASSERT("pbuf_header failed\n", 0);
+      goto bad;
+    }
+
+    bufptr = n0->payload;
+    for(q = np; q != NULL; q = q->next) {
+      MEMCPY(q->payload, bufptr, q->len);
+      bufptr += q->len;
+    }
+
+    if(n0->next) {
+      pbuf_chain(np, n0->next);
+      pbuf_dechain(n0);
+    }
+    pbuf_free(n0);
+    n0 = np;
+  }
+
+  if(pbuf_header(n0, cs->cs_hlen)) {
+    struct pbuf *np;
+
+    LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE);
+    np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL);
+    if(!np) {
+      PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: prepend failed\n"));
+      goto bad;
+    }
+    pbuf_cat(np, n0);
+    n0 = np;
+  }
+  LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen);
+  MEMCPY(n0->payload, &cs->cs_ip, cs->cs_hlen);
+
+  *nb = n0;
+
+  return vjlen;
+
+bad:
+  comp->flags |= VJF_TOSS;
+  INCR(vjs_errorin);
+  return (-1);
+}
+
+#endif /* VJ_SUPPORT */
+
+#endif /* PPP_SUPPORT */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/vj.h
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/vj.h	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/ppp/vj.h	(revision 164)
@@ -0,0 +1,156 @@
+/*
+ * Definitions for tcp compression routines.
+ *
+ * $Id$
+ *
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
+ * - Initial distribution.
+ */
+
+#ifndef VJ_H
+#define VJ_H
+
+#include "lwip/ip.h"
+#include "lwip/tcp_impl.h"
+
+#define MAX_SLOTS 16 /* must be > 2 and < 256 */
+#define MAX_HDR   128
+
+/*
+ * Compressed packet format:
+ *
+ * The first octet contains the packet type (top 3 bits), TCP
+ * 'push' bit, and flags that indicate which of the 4 TCP sequence
+ * numbers have changed (bottom 5 bits).  The next octet is a
+ * conversation number that associates a saved IP/TCP header with
+ * the compressed packet.  The next two octets are the TCP checksum
+ * from the original datagram.  The next 0 to 15 octets are
+ * sequence number changes, one change per bit set in the header
+ * (there may be no changes and there are two special cases where
+ * the receiver implicitly knows what changed -- see below).
+ * 
+ * There are 5 numbers which can change (they are always inserted
+ * in the following order): TCP urgent pointer, window,
+ * acknowlegement, sequence number and IP ID.  (The urgent pointer
+ * is different from the others in that its value is sent, not the
+ * change in value.)  Since typical use of SLIP links is biased
+ * toward small packets (see comments on MTU/MSS below), changes
+ * use a variable length coding with one octet for numbers in the
+ * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the
+ * range 256 - 65535 or 0.  (If the change in sequence number or
+ * ack is more than 65535, an uncompressed packet is sent.)
+ */
+
+/*
+ * Packet types (must not conflict with IP protocol version)
+ *
+ * The top nibble of the first octet is the packet type.  There are
+ * three possible types: IP (not proto TCP or tcp with one of the
+ * control flags set); uncompressed TCP (a normal IP/TCP packet but
+ * with the 8-bit protocol field replaced by an 8-bit connection id --
+ * this type of packet syncs the sender & receiver); and compressed
+ * TCP (described above).
+ *
+ * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and
+ * is logically part of the 4-bit "changes" field that follows.  Top
+ * three bits are actual packet type.  For backward compatibility
+ * and in the interest of conserving bits, numbers are chosen so the
+ * IP protocol version number (4) which normally appears in this nibble
+ * means "IP packet".
+ */
+
+/* packet types */
+#define TYPE_IP               0x40
+#define TYPE_UNCOMPRESSED_TCP 0x70
+#define TYPE_COMPRESSED_TCP   0x80
+#define TYPE_ERROR            0x00
+
+/* Bits in first octet of compressed packet */
+#define NEW_C 0x40 /* flag bits for what changed in a packet */
+#define NEW_I 0x20
+#define NEW_S 0x08
+#define NEW_A 0x04
+#define NEW_W 0x02
+#define NEW_U 0x01
+
+/* reserved, special-case values of above */
+#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */
+#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */
+#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U)
+
+#define TCP_PUSH_BIT 0x10
+
+
+/*
+ * "state" data for each active tcp conversation on the wire.  This is
+ * basically a copy of the entire IP/TCP header from the last packet
+ * we saw from the conversation together with a small identifier
+ * the transmit & receive ends of the line use to locate saved header.
+ */
+struct cstate {
+  struct cstate *cs_next; /* next most recently used state (xmit only) */
+  u_short cs_hlen;        /* size of hdr (receive only) */
+  u_char cs_id;           /* connection # associated with this state */
+  u_char cs_filler;
+  union {
+    char csu_hdr[MAX_HDR];
+    struct ip_hdr csu_ip;     /* ip/tcp hdr from most recent packet */
+  } vjcs_u;
+};
+#define cs_ip vjcs_u.csu_ip
+#define cs_hdr vjcs_u.csu_hdr
+
+
+struct vjstat {
+  unsigned long vjs_packets;        /* outbound packets */
+  unsigned long vjs_compressed;     /* outbound compressed packets */
+  unsigned long vjs_searches;       /* searches for connection state */
+  unsigned long vjs_misses;         /* times couldn't find conn. state */
+  unsigned long vjs_uncompressedin; /* inbound uncompressed packets */
+  unsigned long vjs_compressedin;   /* inbound compressed packets */
+  unsigned long vjs_errorin;        /* inbound unknown type packets */
+  unsigned long vjs_tossed;         /* inbound packets tossed because of error */
+};
+
+/*
+ * all the state data for one serial line (we need one of these per line).
+ */
+struct vjcompress {
+  struct cstate *last_cs;          /* most recently used tstate */
+  u_char last_recv;                /* last rcvd conn. id */
+  u_char last_xmit;                /* last sent conn. id */
+  u_short flags;
+  u_char maxSlotIndex;
+  u_char compressSlot;             /* Flag indicating OK to compress slot ID. */
+#if LINK_STATS
+  struct vjstat stats;
+#endif
+  struct cstate tstate[MAX_SLOTS]; /* xmit connection states */
+  struct cstate rstate[MAX_SLOTS]; /* receive connection states */
+};
+
+/* flag values */
+#define VJF_TOSS 1U /* tossing rcvd frames because of input err */
+
+extern void  vj_compress_init    (struct vjcompress *comp);
+extern u_int vj_compress_tcp     (struct vjcompress *comp, struct pbuf *pb);
+extern void  vj_uncompress_err   (struct vjcompress *comp);
+extern int   vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp);
+extern int   vj_uncompress_tcp   (struct pbuf **nb, struct vjcompress *comp);
+
+#endif /* VJ_H */
Index: UsbWattMeter/trunk/lwip-1.4.1/src/netif/slipif.c
===================================================================
--- UsbWattMeter/trunk/lwip-1.4.1/src/netif/slipif.c	(revision 164)
+++ UsbWattMeter/trunk/lwip-1.4.1/src/netif/slipif.c	(revision 164)
@@ -0,0 +1,510 @@
+/**
+ * @file
+ * SLIP Interface
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is built upon the file: src/arch/rtxc/netif/sioslip.c
+ *
+ * Author: Magnus Ivarsson <magnus.ivarsson(at)volvo.com> 
+ *         Simon Goldschmidt
+ *
+ * Usage: This netif can be used in three ways:
+ *        1) For NO_SYS==0, an RX thread can be used which blocks on sio_read()
+ *           until data is received.
+ *        2) In your main loop, call slipif_poll() to check for new RX bytes,
+ *           completed packets are fed into netif->input().
+ *        3) Call slipif_received_byte[s]() from your serial RX ISR and
+ *           slipif_process_rxqueue() from your main loop. ISR level decodes
+ *           packets and puts completed packets on a queue which is fed into
+ *           the stack from the main loop (needs SYS_LIGHTWEIGHT_PROT for
+ *           pbuf_alloc to work on ISR level!).
+ *     
+ */
+
+/* 
+ * This is an arch independent SLIP netif. The specific serial hooks must be
+ * provided by another file. They are sio_open, sio_read/sio_tryread and sio_send
+ */
+
+#include "netif/slipif.h"
+#include "lwip/opt.h"
+
+#if LWIP_HAVE_SLIPIF
+
+#include "lwip/def.h"
+#include "lwip/pbuf.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#include "lwip/sio.h"
+#include "lwip/sys.h"
+
+#define SLIP_END     0xC0 /* 0300: start and end of every packet */
+#define SLIP_ESC     0xDB /* 0333: escape start (one byte escaped data follows) */
+#define SLIP_ESC_END 0xDC /* 0334: following escape: original byte is 0xC0 (END) */
+#define SLIP_ESC_ESC 0xDD /* 0335: following escape: original byte is 0xDB (ESC) */
+
+/** Maximum packet size that is received by this netif */
+#ifndef SLIP_MAX_SIZE
+#define SLIP_MAX_SIZE 1500
+#endif
+
+/** Define this to the interface speed for SNMP
+ * (sio_fd is the sio_fd_t returned by sio_open).
+ * The default value of zero means 'unknown'.
+ */
+#ifndef SLIP_SIO_SPEED
+#define SLIP_SIO_SPEED(sio_fd) 0
+#endif
+
+enum slipif_recv_state {
+    SLIP_RECV_NORMAL,
+    SLIP_RECV_ESCAPE,
+};
+
+struct slipif_priv {
+  sio_fd_t sd;
+  /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */
+  struct pbuf *p, *q;
+  u8_t state;
+  u16_t i, recved;
+#if SLIP_RX_FROM_ISR
+  struct pbuf *rxpackets;
+#endif
+};
+
+/**
+ * Send a pbuf doing the necessary SLIP encapsulation
+ *
+ * Uses the serial layer's sio_send()
+ *
+ * @param netif the lwip network interface structure for this slipif
+ * @param p the pbuf chaing packet to send
+ * @param ipaddr the ip address to send the packet to (not used for slipif)
+ * @return always returns ERR_OK since the serial layer does not provide return values
+ */
+err_t
+slipif_output(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr)
+{
+  struct slipif_priv *priv;
+  struct pbuf *q;
+  u16_t i;
+  u8_t c;
+
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+  LWIP_ASSERT("p != NULL", (p != NULL));
+
+  LWIP_UNUSED_ARG(ipaddr);
+
+  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_output(%"U16_F"): sending %"U16_F" bytes\n", (u16_t)netif->num, p->tot_len));
+  priv = netif->state;
+
+  /* Send pbuf out on the serial I/O device. */
+  /* Start with packet delimiter. */
+  sio_send(SLIP_END, priv->sd);
+
+  for (q = p; q != NULL; q = q->next) {
+    for (i = 0; i < q->len; i++) {
+      c = ((u8_t *)q->payload)[i];
+      switch (c) {
+      case SLIP_END:
+        /* need to escape this byte (0xC0 -> 0xDB, 0xDC) */
+        sio_send(SLIP_ESC, priv->sd);
+        sio_send(SLIP_ESC_END, priv->sd);
+        break;
+      case SLIP_ESC:
+        /* need to escape this byte (0xDB -> 0xDB, 0xDD) */
+        sio_send(SLIP_ESC, priv->sd);
+        sio_send(SLIP_ESC_ESC, priv->sd);
+        break;
+      default:
+        /* normal byte - no need for escaping */
+        sio_send(c, priv->sd);
+        break;
+      }
+    }
+  }
+  /* End with packet delimiter. */
+  sio_send(SLIP_END, priv->sd);
+  return ERR_OK;
+}
+
+/**
+ * Handle the incoming SLIP stream character by character
+ *
+ * @param netif the lwip network interface structure for this slipif
+ * @param c received character (multiple calls to this function will
+ *        return a complete packet, NULL is returned before - used for polling)
+ * @return The IP packet when SLIP_END is received
+ */
+static struct pbuf*
+slipif_rxbyte(struct netif *netif, u8_t c)
+{
+  struct slipif_priv *priv;
+  struct pbuf *t;
+
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+
+  priv = netif->state;
+
+  switch (priv->state) {
+  case SLIP_RECV_NORMAL:
+    switch (c) {
+    case SLIP_END:
+      if (priv->recved > 0) {
+        /* Received whole packet. */
+        /* Trim the pbuf to the size of the received packet. */
+        pbuf_realloc(priv->q, priv->recved);
+
+        LINK_STATS_INC(link.recv);
+
+        LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet (%"U16_F" bytes)\n", priv->recved));
+        t = priv->q;
+        priv->p = priv->q = NULL;
+        priv->i = priv->recved = 0;
+        return t;
+      }
+      return NULL;
+    case SLIP_ESC:
+      priv->state = SLIP_RECV_ESCAPE;
+      return NULL;
+    } /* end switch (c) */
+    break;
+  case SLIP_RECV_ESCAPE:
+    /* un-escape END or ESC bytes, leave other bytes
+       (although that would be a protocol error) */
+    switch (c) {
+    case SLIP_ESC_END:
+      c = SLIP_END;
+      break;
+    case SLIP_ESC_ESC:
+      c = SLIP_ESC;
+      break;
+    }
+    priv->state = SLIP_RECV_NORMAL;
+    break;
+  } /* end switch (priv->state) */
+
+  /* byte received, packet not yet completely received */
+  if (priv->p == NULL) {
+    /* allocate a new pbuf */
+    LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
+    priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN), PBUF_POOL);
+
+    if (priv->p == NULL) {
+      LINK_STATS_INC(link.drop);
+      LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
+      /* don't process any further since we got no pbuf to receive to */
+      return NULL;
+    }
+
+    if (priv->q != NULL) {
+      /* 'chain' the pbuf to the existing chain */
+      pbuf_cat(priv->q, priv->p);
+    } else {
+      /* p is the first pbuf in the chain */
+      priv->q = priv->p;
+    }
+  }
+
+  /* this automatically drops bytes if > SLIP_MAX_SIZE */
+  if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) {
+    ((u8_t *)priv->p->payload)[priv->i] = c;
+    priv->recved++;
+    priv->i++;
+    if (priv->i >= priv->p->len) {
+      /* on to the next pbuf */
+      priv->i = 0;
+      if (priv->p->next != NULL && priv->p->next->len > 0) {
+        /* p is a chain, on to the next in the chain */
+          priv->p = priv->p->next;
+      } else {
+        /* p is a single pbuf, set it to NULL so next time a new
+         * pbuf is allocated */
+          priv->p = NULL;
+      }
+    }
+  }
+  return NULL;
+}
+
+/** Like slipif_rxbyte, but passes completed packets to netif->input
+ *
+ * @param netif The lwip network interface structure for this slipif
+ * @param data received character
+ */
+static void
+slipif_rxbyte_input(struct netif *netif, u8_t c)
+{
+  struct pbuf *p;
+  p = slipif_rxbyte(netif, c);
+  if (p != NULL) {
+    if (netif->input(p, netif) != ERR_OK) {
+      pbuf_free(p);
+    }
+  }
+}
+
+#if SLIP_USE_RX_THREAD
+/**
+ * The SLIP input thread.
+ *
+ * Feed the IP layer with incoming packets
+ *
+ * @param nf the lwip network interface structure for this slipif
+ */
+static void
+slipif_loop_thread(void *nf)
+{
+  u8_t c;
+  struct netif *netif = (struct netif *)nf;
+  struct slipif_priv *priv = (struct slipif_priv *)netif->state;
+
+  while (1) {
+    if (sio_read(priv->sd, &c, 1) > 0) {
+      slipif_rxbyte_input(netif, c);
+    }
+  }
+}
+#endif /* SLIP_USE_RX_THREAD */
+
+/**
+ * SLIP netif initialization
+ *
+ * Call the arch specific sio_open and remember
+ * the opened device in the state field of the netif.
+ *
+ * @param netif the lwip network interface structure for this slipif
+ * @return ERR_OK if serial line could be opened,
+ *         ERR_MEM if no memory could be allocated,
+ *         ERR_IF is serial line couldn't be opened
+ *
+ * @note netif->num must contain the number of the serial port to open
+ *       (0 by default). If netif->state is != NULL, it is interpreted as an
+ *       u8_t pointer pointing to the serial port number instead of netif->num.
+ *
+ */
+err_t
+slipif_init(struct netif *netif)
+{
+  struct slipif_priv *priv;
+  u8_t sio_num;
+
+  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num));
+
+  /* Allocate private data */
+  priv = (struct slipif_priv *)mem_malloc(sizeof(struct slipif_priv));
+  if (!priv) {
+    return ERR_MEM;
+  }
+
+  netif->name[0] = 's';
+  netif->name[1] = 'l';
+  netif->output = slipif_output;
+  netif->mtu = SLIP_MAX_SIZE;
+  netif->flags |= NETIF_FLAG_POINTTOPOINT;
+
+  /* netif->state or netif->num contain the port number */
+  if (netif->state != NULL) {
+    sio_num = *(u8_t*)netif->state;
+  } else {
+    sio_num = netif->num;
+  }
+  /* Try to open the serial port. */
+  priv->sd = sio_open(sio_num);
+  if (!priv->sd) {
+    /* Opening the serial port failed. */
+    mem_free(priv);
+    return ERR_IF;
+  }
+
+  /* Initialize private data */
+  priv->p = NULL;
+  priv->q = NULL;
+  priv->state = SLIP_RECV_NORMAL;
+  priv->i = 0;
+  priv->recved = 0;
+#if SLIP_RX_FROM_ISR
+  priv->rxpackets = NULL;
+#endif
+
+  netif->state = priv;
+
+  /* initialize the snmp variables and counters inside the struct netif */
+  NETIF_INIT_SNMP(netif, snmp_ifType_slip, SLIP_SIO_SPEED(priv->sd));
+
+#if SLIP_USE_RX_THREAD
+  /* Create a thread to poll the serial line. */
+  sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif,
+    SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO);
+#endif /* SLIP_USE_RX_THREAD */
+  return ERR_OK;
+}
+
+/**
+ * Polls the serial device and feeds the IP layer with incoming packets.
+ *
+ * @param netif The lwip network interface structure for this slipif
+ */
+void
+slipif_poll(struct netif *netif)
+{
+  u8_t c;
+  struct slipif_priv *priv;
+
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+
+  priv = (struct slipif_priv *)netif->state;
+
+  while (sio_tryread(priv->sd, &c, 1) > 0) {
+    slipif_rxbyte_input(netif, c);
+  }
+}
+
+#if SLIP_RX_FROM_ISR
+/**
+ * Feeds the IP layer with incoming packets that were receive
+ *
+ * @param netif The lwip network interface structure for this slipif
+ */
+void
+slipif_process_rxqueue(struct netif *netif)
+{
+  struct slipif_priv *priv;
+  SYS_ARCH_DECL_PROTECT(old_level);
+
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+
+  priv = (struct slipif_priv *)netif->state;
+
+  SYS_ARCH_PROTECT(old_level);
+  while (priv->rxpackets != NULL) {
+    struct pbuf *p = priv->rxpackets;
+#if SLIP_RX_QUEUE
+    /* dequeue packet */
+    struct pbuf *q = p;
+    while ((q->len != q->tot_len) && (q->next != NULL)) {
+      q = q->next;
+    }
+    priv->rxpackets = q->next;
+    q->next = NULL;
+#else /* SLIP_RX_QUEUE */
+    priv->rxpackets = NULL;
+#endif /* SLIP_RX_QUEUE */
+    SYS_ARCH_UNPROTECT(old_level);
+    if (netif->input(p, netif) != ERR_OK) {
+      pbuf_free(p);
+    }
+    SYS_ARCH_PROTECT(old_level);
+  }
+}
+
+/** Like slipif_rxbyte, but queues completed packets.
+ *
+ * @param netif The lwip network interface structure for this slipif
+ * @param data Received serial byte
+ */
+static void
+slipif_rxbyte_enqueue(struct netif *netif, u8_t data)
+{
+  struct pbuf *p;
+  struct slipif_priv *priv = (struct slipif_priv *)netif->state;
+  SYS_ARCH_DECL_PROTECT(old_level);
+
+  p = slipif_rxbyte(netif, data);
+  if (p != NULL) {
+    SYS_ARCH_PROTECT(old_level);
+    if (priv->rxpackets != NULL) {
+#if SLIP_RX_QUEUE
+      /* queue multiple pbufs */
+      struct pbuf *q = p;
+      while(q->next != NULL) {
+        q = q->next;
+      }
+      q->next = p;
+    } else {
+#else /* SLIP_RX_QUEUE */
+      pbuf_free(priv->rxpackets);
+    }
+    {
+#endif /* SLIP_RX_QUEUE */
+      priv->rxpackets = p;
+    }
+    SYS_ARCH_UNPROTECT(old_level);
+  }
+}
+
+/**
+ * Process a received byte, completed packets are put on a queue that is
+ * fed into IP through slipif_process_rxqueue().
+ *
+ * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled.
+ *
+ * @param netif The lwip network interface structure for this slipif
+ * @param data received character
+ */
+void
+slipif_received_byte(struct netif *netif, u8_t data)
+{
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+  slipif_rxbyte_enqueue(netif, data);
+}
+
+/**
+ * Process multiple received byte, completed packets are put on a queue that is
+ * fed into IP through slipif_process_rxqueue().
+ *
+ * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled.
+ *
+ * @param netif The lwip network interface structure for this slipif
+ * @param data received character
+ * @param len Number of received characters
+ */
+void
+slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len)
+{
+  u8_t i;
+  u8_t *rxdata = data;
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
+
+  for (i = 0; i < len; i++, rxdata++) {
+    slipif_rxbyte_enqueue(netif, *rxdata);
+  }
+}
+#endif /* SLIP_RX_FROM_ISR */
+
+#endif /* LWIP_HAVE_SLIPIF */
Index: UsbWattMeter/trunk/src/usb_watt_meter/client.c
===================================================================
--- UsbWattMeter/trunk/src/usb_watt_meter/client.c	(revision 164)
+++ UsbWattMeter/trunk/src/usb_watt_meter/client.c	(revision 164)
@@ -0,0 +1,383 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+#include <lib/curl_setup.h>
+#include <curl/curl.h>
+#include <wolfssl/wolfcrypt/wc_port.h>
+#include <wolfssl/ssl.h>
+#include <lwip/sockets.h>
+#include <string.h>
+#include "main.h"
+#include "kernel_cfg.h"
+#include "ff.h"
+
+#define SKIP_PEER_VERIFICATION
+//#define SKIP_HOSTNAME_VERIFICATION
+char response[80];
+
+void client_init(void)
+{
+	uITRON4_minit(ITRON_POOL_SIZE);
+
+	curl_global_init(CURL_GLOBAL_DEFAULT);
+}
+
+size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)
+{
+	int rest = size * nmemb;
+	int len;
+
+	while (rest > 0) {
+		len = rest;
+		if (len > (sizeof(response) - 1)) {
+			len = sizeof(response) - 1;
+		}
+
+		memcpy(response, buffer, len);
+
+		response[len] = '\0';
+
+		syslog(LOG_NOTICE, response);
+
+		dly_tsk(100);
+
+		rest -= len;
+		(char *)buffer += len;
+	}
+
+	return size * nmemb;
+}
+
+size_t read_data(char *buffer, size_t size, size_t nitems, void *instream)
+{
+	FIL *file = (FIL *)instream;
+	UINT ret = 0;
+	FRESULT res;
+
+	res = f_read(file, buffer, size * nitems, &ret);
+	if (res != FR_OK)
+		return 0;
+
+	int rest = ret;
+	int len;
+
+	while (rest > 0) {
+		len = rest;
+		if (len > (sizeof(response) - 1)) {
+			len = sizeof(response) - 1;
+		}
+
+		memcpy(response, buffer, len);
+
+		response[len] = '\0';
+
+		syslog(LOG_NOTICE, response);
+
+		dly_tsk(100);
+
+		rest -= len;
+		(char *)buffer += len;
+	}
+
+	return ret;
+}
+
+char errbuf[CURL_ERROR_SIZE];
+
+static void get_logfname(char *fname)
+{
+	// fname = "0:/log/2016010100000000.log"
+	time_t t;
+	struct tm tm;
+	int tmp1, tmp2;
+	char *pos = &fname[7];
+
+	sys_time(&t);
+	gmtime_r(&t, &tm);
+
+	/* N */
+	tmp1 = 1900 + tm.tm_year;
+	tmp2 = tmp1 / 1000;
+	tmp1 -= tmp2 * 1000;
+	*pos++ = '0' + tmp2;
+	tmp2 = tmp1 / 100;
+	tmp1 -= tmp2 * 100;
+	*pos++ = '0' + tmp2;
+	tmp2 = tmp1 / 10;
+	tmp1 -= tmp2 * 10;
+	*pos++ = '0' + tmp2;
+	*pos++ = '0' + tmp1;
+	/*  */
+	tmp1 = tm.tm_mon + 1;
+	tmp2 = tmp1 / 10;
+	tmp1 -= tmp2 * 10;
+	*pos++ = '0' + tmp2;
+	*pos++ = '0' + tmp1;
+	/* ú */
+	tmp1 = tm.tm_mday;
+	tmp2 = tmp1 / 10;
+	tmp1 -= tmp2 * 10;
+	*pos++ = '0' + tmp2;
+	*pos++ = '0' + tmp1;
+	/*  */
+	tmp1 = tm.tm_hour;
+	tmp2 = tmp1 / 10;
+	tmp1 -= tmp2 * 10;
+	*pos++ = '0' + tmp2;
+	*pos++ = '0' + tmp1;
+	/* ª */
+	tmp1 = tm.tm_min;
+	tmp2 = tmp1 / 10;
+	tmp1 -= tmp2 * 10;
+	*pos++ = '0' + tmp2;
+	*pos++ = '0' + tmp1;
+	/* b */
+	tmp1 = tm.tm_sec;
+	tmp2 = tmp1 / 10;
+	tmp1 -= tmp2 * 10;
+	*pos++ = '0' + tmp2;
+	*pos++ = '0' + tmp1;
+}
+
+static FRESULT write_log(char *fname)
+{
+	FIL file;
+	FRESULT ret;
+
+	ret = f_open(&file, fname, FA_CREATE_ALWAYS | FA_WRITE);
+	if (ret != FR_OK) {
+		syslog(LOG_ERROR, "not open a upload file %d", ret);
+		return ret;
+	}
+
+	f_printf(&file, "{\"datetime\":\"");
+	for (int i = 7; i < 21; i++)
+		f_putc(fname[i], &file);
+	f_printf(&file, "\",");
+
+	for (int i = 0; i < 6; i++) {
+		struct watt_hour_meter_t *meter = &electric_energy_meter_data[i];
+		uint32_t *log;
+		int len;
+
+		f_printf(&file, "\"channel%d\":[", i + 1);
+
+		wai_sem(MAIN_SEMAPHORE);
+
+		len = 48 - meter->current_pos;
+		if (len > 0) {
+			log = &meter->integral_electric_energy_measurement_log[meter->current_pos];
+			for (int j = 1; j < len; j++) {
+				f_printf(&file, "%d,", *log);
+			}
+			f_printf(&file, "%d", *log);
+		}
+		len = 48 - len;
+		if (len > 0) {
+			f_putc(',', &file);
+
+			log = &meter->integral_electric_energy_measurement_log[0];
+			for (int j = 1; j < len; j++) {
+				f_printf(&file, "%d,", *log);
+			}
+			f_printf(&file, "%d", *log);
+		}
+
+		sig_sem(MAIN_SEMAPHORE);
+
+		f_putc(']', &file);
+		if (i != 5) {
+			f_putc(',', &file);
+		}
+	}
+
+	f_putc('}', &file);
+
+file_close:
+	f_close(&file);
+
+	return FR_OK;
+}
+
+void client_task(intptr_t exinf)
+{
+	CURL *curl;
+	CURLcode res;
+	int error = 0;
+	//const char *data = "{\"value\":\"data post\"}";
+	struct curl_slist *list = NULL;
+	FIL file;
+	FRESULT ret;
+	char fname[] = {"0:/log/20160101000000.log"};
+
+	get_logfname(fname);
+
+	ret = write_log(fname);
+	if (ret != FR_OK) {
+		syslog(LOG_ERROR, "log file write error %d", ret);
+		return;
+	}
+
+	ret = f_open(&file, fname, FA_READ);
+	if (ret != FR_OK) {
+		syslog(LOG_ERROR, "log file open error %d", ret);
+		return;
+	}
+
+	syslog(LOG_NOTICE, "cURL start");
+
+	curl = curl_easy_init();
+	if (curl == NULL) {
+		syslog(LOG_ERROR, "curl_easy_init() failed\n");
+		goto file_close;
+	}
+
+	/* ask libcurl to show us the verbose output */
+	curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
+
+	res = curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/");
+	if (res != CURLE_OK)
+		syslog(LOG_ERROR, "CURLOPT_URL failed: %s\n",
+			curl_easy_strerror(res));
+
+	/* set the error buffer as empty before performing a request */
+	errbuf[0] = 0;
+
+	/* provide a buffer to store errors in */
+	curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
+
+#ifdef SKIP_PEER_VERIFICATION
+	/*
+	* If you want to connect to a site who isn't using a certificate that is
+	* signed by one of the certs in the CA bundle you have, you can skip the
+	* verification of the server's certificate. This makes the connection
+	* A LOT LESS SECURE.
+	*
+	* If you have a CA cert for the server stored someplace else than in the
+	* default bundle, then the CURLOPT_CAPATH option might come handy for
+	* you.
+	*/
+	res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+	if (res != CURLE_OK)
+		syslog(LOG_ERROR, "CURLOPT_SSL_VERIFYPEER failed: %s\n",
+			curl_easy_strerror(res));
+#else
+	res = curl_easy_setopt(curl, CURLOPT_CAINFO, "0:/certs/ca-cert.pem");
+	if (res != CURLE_OK)
+		syslog(LOG_ERROR, "CURLOPT_CAINFO failed: %s\n",
+			curl_easy_strerror(res));
+
+	res = curl_easy_setopt(curl, CURLOPT_SSLCERT, "0:/certs/client-cert.pem");
+	if (res != CURLE_OK)
+		syslog(LOG_ERROR, "CURLOPT_SSLCERT failed: %s\n",
+			curl_easy_strerror(res));
+
+	res = curl_easy_setopt(curl, CURLOPT_SSLKEY, "0:/certs/client-key.pem");
+	if (res != CURLE_OK)
+		syslog(LOG_ERROR, "CURLOPT_SSLKEY failed: %s\n",
+			curl_easy_strerror(res));
+#endif
+
+#ifdef SKIP_HOSTNAME_VERIFICATION
+	/*
+	* If the site you're connecting to uses a different host name that what
+	* they have mentioned in their server certificate's commonName (or
+	* subjectAltName) fields, libcurl will refuse to connect. You can skip
+	* this check, but this will make the connection less secure.
+	*/
+	res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+	if (res != CURLE_OK)
+		syslog(LOG_ERROR, "CURLOPT_SSL_VERIFYHOST failed: %s\n",
+			curl_easy_strerror(res));
+#endif
+
+	/*res = curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy.example.com:8080");
+	if (res != CURLE_OK)
+		syslog(LOG_ERROR, "CURLOPT_PROXY failed: %s\n",
+			curl_easy_strerror(res));*/
+
+	curl_easy_setopt(curl, CURLOPT_POST, 1);
+
+	/* size of the POST data */
+	//curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(data));
+	curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, file.fsize);
+
+	/* pass in a pointer to the data - libcurl will not copy */
+	//curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
+
+	list = curl_slist_append(list, "Content-Type: application/json");
+
+	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
+
+	curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&error);
+
+	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
+
+	/* now specify which file to upload */
+	curl_easy_setopt(curl, CURLOPT_READDATA, &file);
+
+	/* we want to use our own read function */
+	curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_data);
+
+	syslog(LOG_NOTICE, "cURL perform the request");
+	tslp_tsk(100);
+
+	/* Perform the request, res will get the return code */
+	res = curl_easy_perform(curl);
+	/* Check for errors */
+	if (res != CURLE_OK) {
+		syslog(LOG_ERROR, "curl_easy_perform() failed: %s\n",
+			curl_easy_strerror(res));
+		syslog(LOG_ERROR, errbuf);
+	}
+
+	/* always cleanup */
+	curl_easy_cleanup(curl);
+
+	syslog(LOG_NOTICE, "cURL end");
+
+file_close:
+	f_close(&file);
+}
+
+void client_fin(void)
+{
+	curl_global_cleanup();
+}
Index: UsbWattMeter/trunk/src/usb_watt_meter/client.h
===================================================================
--- UsbWattMeter/trunk/src/usb_watt_meter/client.h	(revision 164)
+++ UsbWattMeter/trunk/src/usb_watt_meter/client.h	(revision 164)
@@ -0,0 +1,56 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _CLIENT_H_
+#define _CLIENT_H_
+
+#include <kernel.h>
+#include "target_config.h"
+
+#define CLIENT_PRIORITY		4		/* NCAg^XNÌDæx */
+
+#define CLIENT_STACK_SIZE	6144	/* X^bNÌæÌTCY */
+
+extern void client_init(void);
+extern void client_task(intptr_t exinf);
+extern void client_fin(void);
+
+#endif /* _CLIENT_H_ */
Index: UsbWattMeter/trunk/src/usb_watt_meter/echonet_app_config.h
===================================================================
--- UsbWattMeter/trunk/src/usb_watt_meter/echonet_app_config.h	(revision 164)
+++ UsbWattMeter/trunk/src/usb_watt_meter/echonet_app_config.h	(revision 164)
@@ -0,0 +1,97 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _ECHONET_APP_CONFIG_H_
+#define _ECHONET_APP_CONFIG_H_
+
+/* d¶pubNÌÍWolfSSLAlwIPÆà¤pÈÌÅâ· */
+#define NUM_ECHONET_MEMPOOL_BLOCK (300)
+
+#define ECHONET_TASK_STACK_SIZE	1024	/* ECNL UDP^XNpX^bNÌæÌTCY */
+
+/*
+ * T[rX^XNÉÇÁÌð}üµ½¢êÉè`·é
+ *
+ * ^CAEglðÔ·
+ * TMO echonet_task_get_timer();
+ * #define ECHONET_TASK_GET_TIMER echonet_task_get_timer
+ *
+ * ^C}[ÌÔðißé
+ * void echonet_task_progress(TMO interval);
+ * #define ECHONET_TASK_PROGRESS(interval) echonet_task_progress(interval)
+ *
+ * ^CAEgiÌ½ßÌÄÑoµj
+ * void echonet_task_timeout();
+ * #define ECHONET_TASK_TIMEOUT echonet_task_timeout()
+ */
+
+/*
+ * tcoÊM^XNÉÇÁÌð}üµ½¢êÉè`·é
+ *
+ * ^CAEglðÔ·
+ * TMO echonet_udp_task_get_timer();
+ * #define ECHONET_UDP_TASK_GET_TIMER echonet_udp_task_get_timer
+ *
+ * ^C}[ÌÔðißé
+ * void echonet_udp_task_progress(TMO interval);
+ * #define ECHONET_UDP_TASK_PROGRESS(interval) echonet_udp_task_progress(interval)
+ *
+ * ^CAEgiÌ½ßÌÄÑoµj
+ * void echonet_udp_task_timeout();
+ * #define ECHONET_UDP_TASK_TIMEOUT echonet_udp_task_timeout()
+ */
+
+/* fobOoÍLø»Ýè·éÆ«Éè` */
+/* #define ECN_DBG_PUT_ENA */
+
+/* fobOoÍ(CARP)Lø»Ýè·éÆ«Éè` */
+/* #define ECN_CAP_PUT_ENA */
+
+/* syslogó«Ò¿Lø»Ýè·éÆ«Éè` */
+/* #define ECN_DBG_WAI_ENA */
+
+/* WÌecn_data_prop_setðgíÈ¢Æ«Éè` */
+/* #define ECN_USER_DATA_PROP_SET */
+
+/* WÌecn_data_prop_getðgíÈ¢Æ«Éè` */
+/* #define ECN_USER_DATA_PROP_GET */
+
+#endif /* _ECHONET_APP_CONFIG_H_ */
Index: UsbWattMeter/trunk/src/usb_watt_meter/main.c
===================================================================
--- UsbWattMeter/trunk/src/usb_watt_meter/main.c	(revision 164)
+++ UsbWattMeter/trunk/src/usb_watt_meter/main.c	(revision 164)
@@ -0,0 +1,1071 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TvvO(1)Ì{Ì
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <string.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "main.h"
+#include "echonet_cfg.h"
+#ifdef __RX
+#include "rx630_ccrx/rx630.h"
+#else
+#include "rx630_msvc/rx630.h"
+#endif
+#include "lwip/netif.h"
+#include "lwip/tcpip.h"
+#include "lwip/dhcp.h"
+#include "sntp/sntp.h"
+#include "ff.h"
+#include "diskio.h"
+#include "wolfssl/wolfcrypt/settings.h"
+#include "client.h"
+
+/* TODO: MACAhXðÝè */
+uint8_t mac_addr[6] = { 0x00, 0x12, 0x34, 0x56, 0x78, 0x9A };
+
+struct lwip_task_t {
+	struct netif netif;
+	ID sem_rev;		/* struct ethernetif */
+	uint32_t ethernetif[8];
+} lwiptsk = {{0},SEM_IF_RX62N_RBUF_READY};
+
+/* TODO: [J[R[hðÝè */
+#define MAKER_CODE	0x00, 0x00, 0xB3	/* TOPPERSvWFNg */
+
+/* m[hvt@CIuWFNg */
+struct node_profile_object_t local_node_data = {
+	0x30,	/* ®ìóÔ */
+	{ 0x01, 0x0A, 0x01, 0x00 },	/* u
+îñ */
+	{
+		0xFE,	/* ºÊÊMwIDtB[h */
+		{ MAKER_CODE },	/* [J[R[h */
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },	/* j[NID([J[Æ©) */
+	},
+	0,
+	{ MAKER_CODE },	/* [J[R[h */
+};
+
+struct watt_hour_meter_t electric_energy_meter_data[6] = {
+	/* dÍÊ[^P */
+	{
+		0x30,	/* ®ìóÔ */
+		0x00,	/* Ýuê */
+		{ 0x00, 0x00, 'C', 0x00 },	/* Kiu
+îñ */
+		0x41,	/* Ùí­¶óÔ */
+		{ MAKER_CODE },	/* [J[R[h */
+		0x02,	/* ÏZdÍÊPÊ */
+		0x00000000,	/* ÏZdÍÊvªl */
+		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },	/* ÏZdÍÊvªlðP */
+	},
+	/* dÍÊ[^Q */
+	{
+		0x30,	/* ®ìóÔ */
+		0x00,	/* Ýuê */
+		{0x00, 0x00, 'C', 0x00},	/* Kiu
+îñ */
+		0x41,	/* Ùí­¶óÔ */
+		{MAKER_CODE},	/* [J[R[h */
+		0x02,	/* ÏZdÍÊPÊ */
+		0x00000000,	/* ÏZdÍÊvªl */
+		{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,},	/* ÏZdÍÊvªlðP */
+	},
+	/* dÍÊ[^R */
+	{
+		0x30,	/* ®ìóÔ */
+		0x00,	/* Ýuê */
+		{0x00, 0x00, 'C', 0x00},	/* Kiu
+îñ */
+		0x41,	/* Ùí­¶óÔ */
+		{MAKER_CODE},	/* [J[R[h */
+		0x02,	/* ÏZdÍÊPÊ */
+		0x00000000,	/* ÏZdÍÊvªl */
+		{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,},	/* ÏZdÍÊvªlðP */
+	},
+	/* dÍÊ[^S */
+	{
+		0x30,	/* ®ìóÔ */
+		0x00,	/* Ýuê */
+		{0x00, 0x00, 'C', 0x00},	/* Kiu
+îñ */
+		0x41,	/* Ùí­¶óÔ */
+		{MAKER_CODE},	/* [J[R[h */
+		0x02,	/* ÏZdÍÊPÊ */
+		0x00000000,	/* ÏZdÍÊvªl */
+		{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,},	/* ÏZdÍÊvªlðP */
+	},
+	/* dÍÊ[^T */
+	{
+		0x30,	/* ®ìóÔ */
+		0x00,	/* Ýuê */
+		{0x00, 0x00, 'C', 0x00},	/* Kiu
+îñ */
+		0x41,	/* Ùí­¶óÔ */
+		{MAKER_CODE},	/* [J[R[h */
+		0x02,	/* ÏZdÍÊPÊ */
+		0x00000000,	/* ÏZdÍÊvªl */
+		{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,},	/* ÏZdÍÊvªlðP */
+	},
+	/* dÍÊ[^U */
+	{
+		0x30,	/* ®ìóÔ */
+		0x00,	/* Ýuê */
+		{0x00, 0x00, 'C', 0x00},	/* Kiu
+îñ */
+		0x41,	/* Ùí­¶óÔ */
+		{MAKER_CODE},	/* [J[R[h */
+		0x02,	/* ÏZdÍÊPÊ */
+		0x00000000,	/* ÏZdÍÊvªl */
+		{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,},	/* ÏZdÍÊvªlðP */
+	}
+};
+
+/*
+ * ®ìóÔON/OFFÝèÖi0x30, 0x31ÌÝó¯t¯j
+ */
+int onoff_prop_set(const EPRPINIB *item, const void *src, int size, bool_t *anno)
+{
+	/* TCYªPÈOÍó¯t¯È¢ */
+	if(size != 1)
+		return 0;
+
+	*anno = *((uint8_t*)item->exinf) != *((uint8_t*)src);
+
+	switch(*(uint8_t *)src){
+	/* ONÌê */
+	case 0x30:
+		*((uint8_t *)item->exinf) = *((uint8_t *)src);
+		/* LEDÌ"."ðON */
+		sil_wrb_mem((uint8_t *)PORTE_PODR_ADDR, sil_reb_mem((uint8_t *)PORTE_PODR_ADDR) | 0x01);
+		break;
+	/* OFFÌê */
+	case 0x31:
+		*((uint8_t *)item->exinf) = *((uint8_t *)src);
+		/* LEDÌ"."ðOFF */
+		sil_wrb_mem((uint8_t *)PORTE_PODR_ADDR, sil_reb_mem((uint8_t *)PORTE_PODR_ADDR) & ~0x01);
+		break;
+	/* 0x30©0x31ÈOÍó¯t¯È¢ */
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * Ùí­¶óÔÝèÖi0x41, 0x42ÌÝó¯t¯j
+ */
+int alarm_prop_set(const EPRPINIB *item, const void *src, int size, bool_t *anno)
+{
+	/* TCYªPÈOÍó¯t¯È¢ */
+	if(size != 1)
+		return 0;
+
+	*anno = *((uint8_t *)item->exinf) != *((uint8_t *)src);
+
+	switch(*(uint8_t *)src){
+	/* Ùí­¶ èÌê */
+	case 0x41:
+	/* Ùí­¶ÈµÌê */
+	case 0x42:
+		*((uint8_t *)item->exinf) = *((uint8_t *)src);
+		break;
+	/* 0x41©0x42ÈOÍó¯t¯È¢ */
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * »ÝÝèÖ
+ */
+int time_prop_set(const EPRPINIB *item, const void *src, int size, bool_t *anno)
+{
+	uint8_t *p_src;
+
+	if (size != 2)
+		return 0;
+
+	/* Ýè */
+	p_src = (uint8_t *)src;
+	sil_wrb_mem((uint8_t *)RTC_RHRCNT_ADDR, *p_src++);
+	sil_wrb_mem((uint8_t *)RTC_RMINCNT_ADDR, *p_src++);
+	sil_wrb_mem((uint8_t *)RTC_RSECCNT_ADDR, 0x00);
+
+	return (intptr_t)p_src - (intptr_t)src;
+}
+
+/*
+ * »Ýæ¾Ö
+ */
+int time_prop_get(const EPRPINIB *item, void *dst, int size)
+{
+	uint8_t *p_dst;
+
+	if (size != 2)
+		return 0;
+
+	/* Ýè */
+	p_dst = (uint8_t *)dst;
+	*p_dst++ = sil_reb_mem((uint8_t *)RTC_RHRCNT_ADDR);
+	*p_dst++ = sil_reb_mem((uint8_t *)RTC_RMINCNT_ADDR);
+
+	return (intptr_t)p_dst - (intptr_t)dst;
+}
+
+/*
+ * »ÝNúÝèÖ
+ */
+int date_prop_set(const EPRPINIB *item, const void *src, int size, bool_t *anno)
+{
+	uint8_t *p_src;
+
+	if (size != 4)
+		return 0;
+
+	/* NúÝè */
+	p_src = (uint8_t *)src;
+	p_src++;	/* 20XX */
+	sil_wrb_mem((uint8_t *)RTC_RYRCNT_ADDR, *p_src++);
+	sil_wrb_mem((uint8_t *)RTC_RMONCNT_ADDR, *p_src++);
+	sil_wrb_mem((uint8_t *)RTC_RDAYCNT_ADDR, *p_src++);
+
+	return (intptr_t)p_src - (intptr_t)src;
+}
+
+/*
+ * »ÝNúæ¾Ö
+ */
+int date_prop_get(const EPRPINIB *item, void *dst, int size)
+{
+	uint8_t *p_dst;
+
+	if (size != 4)
+		return 0;
+
+	p_dst = (uint8_t *)dst;
+	*p_dst++ = 0x20;
+	*p_dst++ = sil_reb_mem((uint8_t *)RTC_RYRCNT_ADDR);
+	*p_dst++ = sil_reb_mem((uint8_t *)RTC_RMONCNT_ADDR);
+	*p_dst++ = sil_reb_mem((uint8_t *)RTC_RDAYCNT_ADDR);
+
+	return (intptr_t)p_dst - (intptr_t)dst;
+}
+
+/*
+ * ÏZdÍÊvªlæ¾Ö
+ */
+int watt_hour_meter_integral_electric_energy_measurement_value_get(const EPRPINIB *item, void *dst, int size)
+{
+	struct watt_hour_meter_t *meter = (struct watt_hour_meter_t *)(item->exinf - (intptr_t)&((struct watt_hour_meter_t *)0)->integral_electric_energy_measurement_value);
+
+	/* TCYª4ÈOÍó¯t¯È¢ */
+	if(size != 4)
+		return 0;
+
+	*((uint32_t *)dst) = meter->integral_electric_energy_measurement_value;
+
+	return 4;
+}
+
+int watt_hour_meter_integral_electric_energy_measurement_log_get(const EPRPINIB *item, void *dst, int size)
+{
+	struct watt_hour_meter_t *meter = (struct watt_hour_meter_t *)(item->exinf - (intptr_t)&((struct watt_hour_meter_t *)0)->integral_electric_energy_measurement_log);
+	int len;
+
+	/* TCYª192ÈOÍó¯t¯È¢ */
+	if (size != 192)
+		return 0;
+
+	wai_sem(MAIN_SEMAPHORE);
+
+	len = 48 - meter->current_pos;
+	if(len > 0)
+		memcpy(dst, &meter->integral_electric_energy_measurement_log[meter->current_pos], sizeof(uint32_t) * len);
+	dst = &((uint8_t *)dst)[len];
+	len = 48 - len;
+	if (len > 0)
+		memcpy(dst, &meter->integral_electric_energy_measurement_log[0], sizeof(uint32_t) * len);
+
+	sig_sem(MAIN_SEMAPHORE);
+
+	return 192;
+}
+
+static uint32_t whm_add_integral_value(struct watt_hour_meter_t *meter, uint32_t watt_hour)
+{
+	bool_t carry;
+	uint32_t value = watt_hour;
+	int current_pos = meter->current_pos;
+	current_pos++;
+	if (current_pos >= 48)
+		current_pos = 0;
+
+	carry = value >= 100000000;
+	if (carry)
+		value -= 100000000;
+
+	wai_sem(MAIN_SEMAPHORE);
+
+	meter->integral_electric_energy_measurement_value = value;
+	meter->integral_electric_energy_measurement_log[current_pos] = value;
+	meter->current_pos = current_pos;
+
+	sig_sem(MAIN_SEMAPHORE);
+
+	return carry ? 100000000 : 0;
+}
+
+static void fatfs_initialize();
+static void netif_initialize();
+static void netif_status_callback(struct netif *netif);
+static void netif_link_callback(struct netif *netif);
+static void main_initialize();
+static TMO main_get_timer();
+static void main_progress(TMO interval);
+static void main_recv_esv(T_EDATA *esv);
+static void main_break_wait(uint8_t *brkdat, int32_t len);
+static void main_timeout();
+
+/*
+ *  C^XN
+ */
+void main_task(intptr_t exinf)
+{
+	ER ret, ret2;
+	SYSTIM prev, now;
+	TMO timer;
+	T_EDATA *esv;
+	uint8_t brkdat[64];
+	int32_t len;
+
+	/* t@CVXeÌú» */
+	fatfs_initialize();
+
+	/* vgRX^bNÌú» */
+	netif_initialize();
+
+	/* AvP[VÌú» */
+	main_initialize();
+
+	ret2 = get_tim(&now);
+	if (ret2 != E_OK){
+		syslog(LOG_ERROR, "get_tim");
+		return;
+	}
+
+	for(;;){
+		prev = now;
+
+		/* ^C}[æ¾ */
+		timer = main_get_timer();
+
+		/* d¶Ò¿ */
+		ret = ecn_trcv_esv(&esv, timer);
+		if ((ret != E_OK) && (ret != E_WBLK) && (ret != E_TMOUT)){
+			syslog(LOG_ERROR, "ecn_trcv_esv");
+			break;
+		}
+
+		ret2 = get_tim(&now);
+		if (ret2 != E_OK){
+			syslog(LOG_ERROR, "get_tim");
+			break;
+		}
+
+		/* Ôoß */
+		main_progress(now - prev);
+
+		/* Echonetd¶óMÌê */
+		if (ret == E_OK) {
+			/* Echonetd¶óM */
+			main_recv_esv(esv);
+
+			/* Ìæðú */
+			ret = ecn_rel_esv(esv);
+			if (ret != E_OK){
+				syslog(LOG_ERROR, "ecn_rel_esv");
+				break;
+			}
+		}
+		/* d¶Ò¿ÌèÝÌê */
+		else if (ret == E_WBLK) {
+			/* d¶Ò¿ÌèÝf[^æ¾ */
+			ret = ecn_get_brk_dat(esv, brkdat, sizeof(brkdat), &len);
+			if (ret != E_OK){
+				syslog(LOG_ERROR, "ecn_get_brk_dat");
+				break;
+			}
+
+			/* d¶Ò¿ÌèÝ */
+			main_break_wait(brkdat, len);
+
+			/* Ìæðú */
+			ret = ecn_rel_esv(esv);
+			if (ret != E_OK){
+				syslog(LOG_ERROR, "ecn_rel_esv");
+				break;
+			}
+		}
+
+		/* ^CAEg */
+		main_timeout();
+	}
+}
+
+FATFS FatFs[_VOLUMES];		/* File system object for logical drive */
+
+static void fatfs_initialize()
+{
+	DSTATUS dst;
+	FRESULT res;
+	BYTE pdrv = 0, type;
+
+	if ((dst = disk_initialize(pdrv)) != RES_OK) {
+		syslog(LOG_ERROR, "disk_initialize %d", dst);
+		return;
+	}
+
+	if ((dst = disk_ioctl(pdrv, MMC_GET_TYPE, &type)) != RES_OK) {
+		syslog(LOG_ERROR, "disk_ioctl MMC_GET_TYPE NG %d", dst);
+	}
+	else {
+		switch(type){
+		case CT_MMC:
+			syslog(LOG_NOTICE, "MMC ver 3");
+			break;
+		case CT_SD1:
+			syslog(LOG_NOTICE, "SD ver 1");
+			break;
+		case CT_SD2:
+			syslog(LOG_NOTICE, "SD ver 2");
+			break;
+		case CT_SDC:
+			syslog(LOG_NOTICE, "SD");
+			break;
+		case CT_SD2 | CT_BLOCK:
+			syslog(LOG_NOTICE, "SD ver 2 (Block addressing)");
+			break;
+		default:
+			syslog(LOG_NOTICE, "???(%x)", type);
+			break;
+		}
+	}
+
+	if ((res = f_mount(&FatFs[0], "", 1)) != FR_OK) {
+		syslog(LOG_ERROR, "f_mount %d", res);
+		return;
+	}
+}
+
+bool_t started = false;
+struct dhcp dhcp;
+bool_t dhcp_enable = true;
+
+static void netif_initialize()
+{
+	extern err_t ethernetif_init(struct netif *netif);
+	ER ret;
+	struct ip_addr xIpAddr, xNetMast, xGateway;
+	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");
+
+	/* libcurlÆWolfSSLÆlwIPÌú» */
+	client_init();
+
+	IP4_ADDR(&xIpAddr, 192, 168, 2, 110);
+	IP4_ADDR(&xNetMast, 255, 255, 255, 0);
+	IP4_ADDR(&xGateway, 192, 168, 2, 1);
+
+	/* Create and configure the EMAC interface. */
+	netif_add(&lwiptsk.netif, &xIpAddr, &xNetMast,
+		&xGateway, NULL, ethernetif_init, tcpip_input);
+
+	netif_set_link_callback(&lwiptsk.netif, netif_link_callback);
+	netif_set_status_callback(&lwiptsk.netif, netif_status_callback);
+
+	dhcp_set_struct(&lwiptsk.netif, &dhcp);
+
+	/* make it the default interface */
+	netif_set_default(&lwiptsk.netif);
+
+	ret = act_tsk(LWIP_TASK);
+	if (ret != E_OK)
+		return;
+}
+
+static void netif_link_callback(struct netif *netif)
+{
+	if ((lwiptsk.netif.flags & NETIF_FLAG_LINK_UP) == 0)
+		return;
+
+	dhcp_start(&lwiptsk.netif);
+}
+
+static void netif_status_callback(struct netif *netif)
+{
+	ER ret;
+	bool_t up;
+
+	up = (lwiptsk.netif.flags & NETIF_FLAG_UP) != 0;
+	if (up && !started) {
+		started = true;
+
+		/* ECHONET~hEFAðN® */
+		ret = ecn_sta_svc();
+		if (ret != E_OK)
+			return;
+
+		/* SNTPðJn */
+		sntp_init();
+	}
+
+	/* C^XNÉÊm */
+	uint8_t data[2];
+	data[0] = 0x01;
+	data[1] = up ? 0x01 : 0x02;
+	ret = ecn_brk_wai(data, sizeof(data));
+	if (ret != E_OK) {
+		syslog(LOG_ERROR, "ecn_brk_wai");
+		return;
+	}
+}
+
+enum main_state_t{
+	main_state_idle,
+};
+
+TMO main_timer = TMO_FEVR;
+enum main_state_t main_state = main_state_idle;
+TMO main_led_timer = TMO_FEVR;
+TMO main_adv_timer = TMO_FEVR;
+int main_whm_counter;
+
+bool_t main_btn1_state;
+int main_btn1_count = 0;
+bool_t main_btn2_state;
+int main_btn2_count = 0;
+
+/*
+ * ú»
+ */
+static void main_initialize()
+{
+	uint8_t btn;
+
+	/*
+	 * W
+[Xgbv@\ÌÝè(S12AD)
+	 */
+	sil_wrh_mem((uint16_t *)SYSTEM_PRCR_ADDR, (uint16_t)0xA502);	/* ÝÂ */
+	sil_wrw_mem((uint32_t *)SYSTEM_MSTPCRA_ADDR,
+		sil_rew_mem((uint32_t *)SYSTEM_MSTPCRA_ADDR) & ~SYSTEM_MSTPCRA_MSTPA17_BIT);
+	sil_wrh_mem((uint16_t *)SYSTEM_PRCR_ADDR, (uint16_t)0xA500);	/* ÝÖ~ */
+
+	/* 7seg_1100p|[goÍÝè */
+	sil_wrb_mem((uint8_t *)PORT2_PDR_ADDR, sil_reb_mem((uint8_t *)PORT2_PDR_ADDR) | PORT_PDR_B4_BIT | PORT_PDR_B3_BIT);
+	/* 7seg_0010p|[goÍÝè */
+	sil_wrb_mem((uint8_t *)PORT5_PDR_ADDR, sil_reb_mem((uint8_t *)PORT5_PDR_ADDR) | PORT_PDR_B3_BIT);
+	/* 7seg_0001p|[goÍÝè */
+	sil_wrb_mem((uint8_t *)PORTC_PDR_ADDR, sil_reb_mem((uint8_t *)PORTC_PDR_ADDR) | PORT_PDR_B1_BIT);
+	/* 7seg_ledp|[goÍÝè */
+	sil_wrb_mem((uint8_t *)PORTD_PDR_ADDR, 0xFF);
+	/* SWITCHp|[güÍALEDp|[goÍÝè */
+	sil_wrb_mem((uint8_t *)PORTE_PDR_ADDR, 0x0F);
+
+	/* LEDð"0000"Æ\¦ */
+	sil_wrb_mem((uint8_t *)PORTE_PDR_ADDR, 0x0F);
+
+	/* 3msãÉ7SEG\¦ðXV */
+	main_led_timer = 3;
+
+	/* 10msãÉ{^óÔðmF */
+	main_timer = 10;
+
+	/* 12bitADCú» */
+	sil_wrh_mem((uint16_t *)S12AD_ADEXICR_ADDR, 0x0000);	/* ·xZToÍAàîd³ñIð */
+	sil_wrh_mem((uint16_t *)S12AD_ADANS0_ADDR, 0x00FF);		/* Ï·|[gAN000`AN007IðAAN008`AN015ñIð */
+	sil_wrh_mem((uint16_t *)S12AD_ADANS1_ADDR, 0x0000);		/* Ï·|[gAN016`AN020ñIð */
+
+	/* {^óÔÇÝÝ */
+	btn = sil_reb_mem((uint8_t *)PORT0_PIDR_ADDR);
+	main_btn1_state = (btn & 0x20) != 0;
+	main_btn2_state = (btn & 0x80) != 0;
+
+	/* 1bãÉ\¦ðXV */
+	main_adv_timer = 1000;
+}
+
+/*
+ * ^C}[æ¾
+ */
+static TMO main_get_timer()
+{
+	TMO result = main_timer;
+
+	if((result == TMO_FEVR)
+		|| ((main_led_timer != TMO_FEVR) && (main_led_timer < result))){
+		result = main_led_timer;
+	}
+
+	if ((result == TMO_FEVR)
+		|| ((main_adv_timer != TMO_FEVR) && (main_adv_timer < result))) {
+		result = main_adv_timer;
+	}
+
+	return result;
+}
+
+/*
+ * Ôoß
+ */
+static void main_progress(TMO interval)
+{
+	if(main_timer != TMO_FEVR){
+		main_timer -= interval;
+		if(main_timer < 0){
+			main_timer = 0;
+		}
+	}
+
+	if(main_led_timer != TMO_FEVR){
+		main_led_timer -= interval;
+		if(main_led_timer < 0){
+			main_led_timer = 0;
+		}
+	}
+
+	if (main_adv_timer != TMO_FEVR) {
+		main_adv_timer -= interval;
+		if (main_adv_timer < 0) {
+			main_adv_timer = 0;
+		}
+	}
+}
+
+/*
+ * Echonetd¶óM
+ */
+static void main_recv_esv(T_EDATA *esv)
+{
+	ER ret;
+	uint8_t epc;
+	uint8_t pdc;
+	uint8_t p_edt[256];
+	T_ENUM_EPC enm;
+
+	ret = ecn_itr_ini(&enm, esv);
+	if(ret != E_OK){
+		syslog(LOG_ERROR, "ecn_itr_ini");
+		return;
+	}
+
+	for(;;) {
+		while((ret = ecn_itr_nxt(&enm, &epc, &pdc, p_edt)) == E_OK) {
+			switch (epc) {
+			case 0x80:
+				break;
+			case 0x81:
+				break;
+			}
+		}
+		if(ret != E_BOVR){
+			syslog(LOG_ERROR, "ecn_itr_nxt");
+			break;
+		}
+		if(enm.is_eof)
+			break;
+	}
+}
+
+/*
+ * d¶Ò¿ÌèÝ
+ */
+static void main_break_wait(uint8_t *brkdat, int32_t len)
+{
+	char ip_addr[16], netmask[16], gateway[16];
+
+	switch(main_state){
+	case main_state_idle:
+		if (len == 0)
+			break;
+
+		switch (brkdat[0]) {
+		case 1: 
+			switch (brkdat[0]) {
+			case 1:
+				ipaddr_ntoa_r(&lwiptsk.netif.ip_addr, ip_addr, sizeof(ip_addr));
+				ipaddr_ntoa_r(&lwiptsk.netif.netmask, netmask, sizeof(netmask));
+				ipaddr_ntoa_r(&lwiptsk.netif.gw, gateway, sizeof(gateway));
+
+				syslog(LOG_NOTICE, "ip_addr %s, netmask %s, gateway %s", ip_addr, netmask, gateway);
+				tslp_tsk(100); /* OªoÍ³êéÜÅ¿åÁÆÒÂ */
+				break;
+			case 2:
+				syslog(LOG_NOTICE, "netif down");
+				break;
+			}
+			break;
+		}
+		break;
+	}
+}
+
+static void main_ontimer();
+static void main_led_ontimer();
+static void main_adv_ontimer();
+
+/*
+ * ^CAEg
+ */
+static void main_timeout()
+{
+	if(main_timer == 0){
+		main_ontimer();
+	}
+
+	if(main_led_timer == 0){
+		main_led_ontimer();
+	}
+
+	if (main_adv_timer == 0) {
+		main_adv_ontimer();
+	}
+}
+
+#define main_7seg_count 4
+static uint8_t main_7seg[main_7seg_count] = { 0xDA, 0xF2, 0xB6, 0xB6 };
+static int main_7seg_pos = 0;
+const uint8_t led_disp[] = { 0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE4, 0xFE, 0xF6, 0xEE, 0x3E, 0x1A, 0x7A, 0x9E, 0x8E };
+
+static void main_led_ontimer()
+{
+	/* 7Seg\¦ */
+	sil_wrb_mem((uint8_t *)PORTD_PODR_ADDR, ~main_7seg[main_7seg_pos]);
+
+	if (main_7seg_pos == 0)
+		sil_wrb_mem((uint8_t *)PORT2_PODR_ADDR, sil_reb_mem((uint8_t *)PORT2_PODR_ADDR)
+			& ~PORT_PODR_B4_BIT);
+	else
+		sil_wrb_mem((uint8_t *)PORT2_PODR_ADDR, sil_reb_mem((uint8_t *)PORT2_PODR_ADDR)
+			| PORT_PODR_B4_BIT);
+	if (main_7seg_pos == 1)
+		sil_wrb_mem((uint8_t *)PORT2_PODR_ADDR, sil_reb_mem((uint8_t *)PORT2_PODR_ADDR)
+			& ~PORT_PODR_B3_BIT);
+	else
+		sil_wrb_mem((uint8_t *)PORT2_PODR_ADDR, sil_reb_mem((uint8_t *)PORT2_PODR_ADDR)
+			| PORT_PODR_B3_BIT);
+	if (main_7seg_pos == 2)
+		sil_wrb_mem((uint8_t *)PORT5_PODR_ADDR, sil_reb_mem((uint8_t *)PORT5_PODR_ADDR)
+			& ~PORT_PODR_B3_BIT);
+	else
+		sil_wrb_mem((uint8_t *)PORT5_PODR_ADDR, sil_reb_mem((uint8_t *)PORT5_PODR_ADDR)
+			| PORT_PODR_B3_BIT);
+	if (main_7seg_pos == 3)
+		sil_wrb_mem((uint8_t *)PORTC_PODR_ADDR, sil_reb_mem((uint8_t *)PORTC_PODR_ADDR)
+			& ~PORT_PODR_B1_BIT);
+	else
+		sil_wrb_mem((uint8_t *)PORTC_PODR_ADDR, sil_reb_mem((uint8_t *)PORTC_PODR_ADDR)
+			| PORT_PODR_B1_BIT);
+
+	main_7seg_pos = (main_7seg_pos + 1) & 0x3;
+
+	/* 3msãÉ7SEG\¦ðXV */
+	main_led_timer = 3;
+}
+
+#define main_ad_count 8
+#define main_ad_table_count 64
+static uint16_t main_ad_table[main_ad_count][main_ad_table_count];
+static int main_ad_pos = 0;
+static uint32_t main_ad_avelage[main_ad_count];
+static uint64_t main_ad_integral[main_ad_count];
+volatile uint16_t *const main_ad_addr[main_ad_count] = {
+	(uint16_t *)S12AD_ADDR0_ADDR,
+	(uint16_t *)S12AD_ADDR1_ADDR,
+	(uint16_t *)S12AD_ADDR2_ADDR,
+	(uint16_t *)S12AD_ADDR3_ADDR,
+	(uint16_t *)S12AD_ADDR4_ADDR,
+	(uint16_t *)S12AD_ADDR5_ADDR,
+	(uint16_t *)S12AD_ADDR6_ADDR,
+	(uint16_t *)S12AD_ADDR7_ADDR,
+};
+
+uint8_t main_port_no = 1;
+static void main_7seg_view(int port_no);
+static void main_btn1_change(bool_t push);
+static void main_btn2_change(bool_t push);
+
+/*
+ * ^CAEg
+ */
+static void main_ontimer()
+{
+	uint8_t btn;
+	uint16_t ad_value;
+
+	switch(main_state){
+	case main_state_idle:
+		/* 10msãÉ{^óÔðmF */
+		main_timer = 10;
+
+		/* ADCÌÏ·Êæ¾ */
+		if((sil_reb_mem((uint8_t *)S12AD_ADCSR_ADDR) & S12AD_ADCSR_ADST_BIT) == 0){
+			for (int i = 0; i < main_ad_count; i++) {
+				main_ad_avelage[i] -= main_ad_table[i][main_ad_pos];
+				ad_value = sil_reh_mem(main_ad_addr[i]);	// 12bitlæ¾
+				main_ad_integral[i] += 5/*[V]*/ * ad_value/*[A]*/;	// 12bitÏZl
+				ad_value = (ad_value << 4) | (ad_value >> 12);	// 16bitg£
+				main_ad_table[i][main_ad_pos] = ad_value;
+				main_ad_avelage[i] += ad_value;
+			}
+
+			main_ad_pos++;
+			if (main_ad_pos >= main_ad_table_count) {
+				main_ad_pos = 0;
+			}
+
+			/* Ï·JniVOXL[hj */
+			sil_wrb_mem((uint8_t *)S12AD_ADCSR_ADDR, S12AD_ADCSR_ADST_BIT);
+		}
+
+		main_whm_counter += 10;
+		if (main_whm_counter >= 1250/* 180000=30ª */) {
+			main_whm_counter = 0;
+
+			for (int i = 0; i < 6; i++) {
+				uint64_t carry;
+				carry = whm_add_integral_value(&electric_energy_meter_data[i],
+					main_ad_integral[i] / ((uint64_t)(10LL/* 0.01kWh */ * 360000LL/*=hour*/ * ((1 << 12) - 1) / 2.4/*4095=2.4A*/)));
+
+				main_ad_integral[i] -= carry * ((uint64_t)(10LL/* 0.01kWh */ * 360000LL/*=hour*/ * ((1 << 12) - 1) / 2.4/*4095=2.4A*/));
+			}
+
+			if (electric_energy_meter_data[0].current_pos == 0) {
+				act_tsk(CLIENT_TASK);
+			}
+		}
+
+		/* {^óÔÇÝÝ */
+		btn = sil_reb_mem((uint8_t *)PORT0_PIDR_ADDR);
+
+		/* {^PÌ */
+		if(((btn & 0x20) != 0) && !main_btn1_state){
+			main_btn1_count++;
+			if(main_btn1_count > 10){
+				main_btn1_count = 0;
+				main_btn1_state = true;
+
+				main_btn1_change(true);
+			}
+		}
+		else if(((btn & 0x20) == 0) && main_btn1_state){
+			main_btn1_count++;
+			if(main_btn1_count > 10){
+				main_btn1_count = 0;
+				main_btn1_state = false;
+
+				main_btn1_change(false);
+			}
+		}
+
+		/* {^QÌ */
+		if(((btn & 0x80) != 0) && !main_btn2_state){
+			main_btn2_count++;
+			if(main_btn2_count > 10){
+				main_btn2_count = 0;
+				main_btn2_state = true;
+
+				main_btn2_change(true);
+			}
+		}
+		else if(((btn & 0x80) == 0) && main_btn2_state){
+			main_btn2_count++;
+			if(main_btn2_count > 10){
+				main_btn2_count = 0;
+				main_btn2_state = false;
+
+				main_btn2_change(false);
+			}
+		}
+
+		main_7seg_view(main_port_no);
+
+		break;
+	}
+}
+
+bool_t main_rev = false;
+
+/*
+ * {^PóÔÏ»
+ */
+static void main_btn1_change(bool_t push)
+{
+	/* ³êÄßÁ½É·é */
+	if(push)
+		return;
+
+	/* \¦|[gÔ */
+	if(!main_rev){
+		main_port_no--;
+		if(main_port_no < 1){
+			main_port_no = 1;
+			main_rev = true;
+			main_adv_timer = 2000;
+		}
+	}
+	else{
+		main_port_no++;
+		if(main_port_no > main_ad_count){
+			main_port_no = main_ad_count;
+			main_rev = false;
+			main_adv_timer = 2000;
+		}
+	}
+}
+
+/*
+ * {^QóÔÏ»
+ */
+static void main_btn2_change(bool_t push)
+{
+	/* ³êÄßÁ½É·é */
+	if(push)
+		return;
+
+	int swt = sil_reb_mem((uint8_t *)PORTE_PIDR_ADDR);
+	if ((swt & 0x20) == 0) {
+		return;
+	}
+
+	/* \¦|[gÔ */
+	if(!main_rev){
+		main_port_no++;
+		if(main_port_no > main_ad_count){
+			main_port_no = main_ad_count;
+			main_rev = false;
+			main_adv_timer = 2000;
+		}
+	}
+	else{
+		main_port_no--;
+		if(main_port_no < 1){
+			main_port_no = 1;
+			main_rev = true;
+			main_adv_timer = 2000;
+		}
+	}
+}
+
+static void main_adv_ontimer()
+{
+	int swt = sil_reb_mem((uint8_t *)PORTE_PIDR_ADDR);
+	if (swt & 0x20)
+		return;
+
+	main_port_no++;
+	if(main_port_no > main_ad_count)
+		main_port_no = 1;
+
+	main_adv_timer = 2000;
+}
+
+static void main_7seg_view(int port_no)
+{
+	if ((port_no < 1) || (port_no > main_ad_count))
+		return;
+
+	int swt = sil_reb_mem((uint8_t *)PORTE_PIDR_ADDR);
+
+	port_no--;
+
+	uint32_t adv = (main_ad_avelage[port_no] / main_ad_table_count);
+
+	if (swt & 0x10) {
+		main_7seg[0] = led_disp[port_no + 1] | 1;
+		main_7seg[1] = led_disp[(adv & 0xF000) >> 12];
+		main_7seg[2] = led_disp[(adv & 0x0F00) >> 8];
+		main_7seg[3] = led_disp[(adv & 0x00F0) >> 4];
+	}
+	else {
+		uint32_t tmp = adv / 26214;
+
+		main_7seg[0] = led_disp[port_no + 1] | 1;
+		main_7seg[1] = led_disp[tmp] | 1;
+		adv = 10 * (adv - tmp * 26214);
+		tmp = adv / 26214;
+		main_7seg[2] = led_disp[tmp];
+		adv = 10 * (adv - tmp * 26214);
+		tmp = adv / 26214;
+		main_7seg[3] = led_disp[tmp];
+	}
+}
+
+#ifdef __RX
+void abort()
+{
+	TOPPERS_assert_abort();
+}
+#endif
Index: UsbWattMeter/trunk/src/usb_watt_meter/main.cfg
===================================================================
--- UsbWattMeter/trunk/src/usb_watt_meter/main.cfg	(revision 164)
+++ UsbWattMeter/trunk/src/usb_watt_meter/main.cfg	(revision 164)
@@ -0,0 +1,304 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TvvO(1)ÌVXeRtBM
+[Vt@C
+ */
+#include "main.h"
+
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+INCLUDE("lwip_task.cfg");
+INCLUDE("../ecnl_lwip/echonet_asp.cfg");
+INCLUDE("if_rx62n.cfg");
+INCLUDE("mmc_rspi.cfg");
+
+#include "client.h"
+#include "echonet.h"
+
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, MAIN_STACK_SIZE, NULL });
+
+CRE_SEM(MAIN_SEMAPHORE, { TA_TPRI, 1, 1 });
+
+CRE_TSK(CLIENT_TASK, { TA_NULL, 0, client_task, CLIENT_PRIORITY, CLIENT_STACK_SIZE, NULL });
+
+AID_SEM(6);
+AID_DTQ(3);
+AID_TSK(2);
+DEF_KMM( { KMM_SIZE, NULL } );
+
+/*
+ *  m[hvt@CIuWFNg
+ */
+ECN_CRE_EOBJ (LOCAL_NODE_EOBJ, { EOBJ_LOCAL_NODE, EOBJ_NULL, 0, EOJ_X1_PROFILE, EOJ_X2_NODE_PROFILE, EOJ_X3_LOCAL_NODE });
+
+/* ®ìóÔ */
+ECN_DEF_EPRP (LOCAL_NODE_EOBJ, { 0x80, EPC_RULE_SET | EPC_RULE_GET, 1, (intptr_t)&local_node_data.operation_status, (EPRP_SETTER *)onoff_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* u
+îñ */
+ECN_DEF_EPRP (LOCAL_NODE_EOBJ, { 0x82, EPC_RULE_GET, 4, (intptr_t)&local_node_data.version_information, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* ¯ÊÔ */
+ECN_DEF_EPRP (LOCAL_NODE_EOBJ, { 0x83, EPC_RULE_GET, 17, (intptr_t)&local_node_data.identification_number, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* [J[R[h */
+ECN_DEF_EPRP (LOCAL_NODE_EOBJ, { 0x8A, EPC_RULE_GET, 3, (intptr_t)&local_node_data.manufacturer_code, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/*
+ *  dÍÊ[^P
+ */
+ECN_CRE_EOBJ (ELECTRIC_ENERGY_METER_1_EOBJ, { EOBJ_DEVICE, LOCAL_NODE_EOBJ, 0, EOJ_X1_AMENITY, EOJ_X2_ELECTRIC_ENERGY_METER, EOJ_X3_ELECTRIC_ENERGY_METER_1 });
+
+/* ®ìóÔ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_1_EOBJ, { 0x80, EPC_RULE_SET | EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[0], (EPRP_SETTER *)onoff_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Ýuê */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_1_EOBJ, { 0x81, EPC_RULE_SET | EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[0].installation_location, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Kiu
+îñ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_1_EOBJ, { 0x82, EPC_RULE_GET, 4, (intptr_t)&electric_energy_meter_data[0].standard_version_information, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Ùí­¶óÔ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_1_EOBJ, { 0x88, EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[0].fault_status, (EPRP_SETTER *)alarm_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* [J[R[h */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_1_EOBJ, { 0x8A, EPC_RULE_GET, 3, (intptr_t)&electric_energy_meter_data[0].manufacturer_code, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* »ÝÝè */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_1_EOBJ, { 0x97, EPC_RULE_SET | EPC_RULE_GET, 2, (intptr_t)NULL, (EPRP_SETTER *)time_prop_set, (EPRP_GETTER *)time_prop_get });
+
+/* »ÝNúÝè */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_1_EOBJ, { 0x98, EPC_RULE_SET | EPC_RULE_GET, 4, (intptr_t)NULL, (EPRP_SETTER *)date_prop_set, (EPRP_GETTER *)date_prop_get });
+
+/* ÏZdÍÊPÊ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_1_EOBJ, { 0xE2, EPC_RULE_GET, 1, (intptr_t)&electric_energy_meter_data[0].integral_electric_energy_unit, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* ÏZdÍÊvªl */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_1_EOBJ, { 0xE0, EPC_RULE_GET, 4, (intptr_t)&electric_energy_meter_data[0].integral_electric_energy_measurement_value, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)watt_hour_meter_integral_electric_energy_measurement_value_get });
+
+/* ÏZdÍÊvªlðP */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_1_EOBJ, { 0xE3, EPC_RULE_GET, 192, (intptr_t)&electric_energy_meter_data[0].integral_electric_energy_measurement_log, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)watt_hour_meter_integral_electric_energy_measurement_log_get });
+
+/*
+ *  dÍÊ[^Q
+ */
+ECN_CRE_EOBJ (ELECTRIC_ENERGY_METER_2_EOBJ, { EOBJ_DEVICE, LOCAL_NODE_EOBJ, 0, EOJ_X1_AMENITY, EOJ_X2_ELECTRIC_ENERGY_METER, EOJ_X3_ELECTRIC_ENERGY_METER_2 });
+
+/* ®ìóÔ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_2_EOBJ, { 0x80, EPC_RULE_SET | EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[1], (EPRP_SETTER *)onoff_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Ýuê */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_2_EOBJ, { 0x81, EPC_RULE_SET | EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[1].installation_location, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Kiu
+îñ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_2_EOBJ, { 0x82, EPC_RULE_GET, 4, (intptr_t)&electric_energy_meter_data[1].standard_version_information, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Ùí­¶óÔ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_2_EOBJ, { 0x88, EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[1].fault_status, (EPRP_SETTER *)alarm_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* [J[R[h */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_2_EOBJ, { 0x8A, EPC_RULE_GET, 3, (intptr_t)&electric_energy_meter_data[1].manufacturer_code, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* »ÝÝè */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_2_EOBJ, { 0x97, EPC_RULE_SET | EPC_RULE_GET, 2, (intptr_t)NULL, (EPRP_SETTER *)time_prop_set, (EPRP_GETTER *)time_prop_get });
+
+/* »ÝNúÝè */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_2_EOBJ, { 0x98, EPC_RULE_SET | EPC_RULE_GET, 4, (intptr_t)NULL, (EPRP_SETTER *)date_prop_set, (EPRP_GETTER *)date_prop_get });
+
+/* ÏZdÍÊPÊ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_2_EOBJ, { 0xE2, EPC_RULE_GET, 1, (intptr_t)&electric_energy_meter_data[1].integral_electric_energy_unit, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* ÏZdÍÊvªl */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_2_EOBJ, { 0xE0, EPC_RULE_GET, 4, (intptr_t)&electric_energy_meter_data[1].integral_electric_energy_measurement_value, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)watt_hour_meter_integral_electric_energy_measurement_value_get });
+
+/* ÏZdÍÊvªlðP */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_2_EOBJ, { 0xE3, EPC_RULE_GET, 192, (intptr_t)&electric_energy_meter_data[1].integral_electric_energy_measurement_log, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)watt_hour_meter_integral_electric_energy_measurement_log_get });
+
+/*
+ *  dÍÊ[^R
+ */
+ECN_CRE_EOBJ (ELECTRIC_ENERGY_METER_3_EOBJ, { EOBJ_DEVICE, LOCAL_NODE_EOBJ, 0, EOJ_X1_AMENITY, EOJ_X2_ELECTRIC_ENERGY_METER, EOJ_X3_ELECTRIC_ENERGY_METER_3 });
+
+/* ®ìóÔ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_3_EOBJ, { 0x80, EPC_RULE_SET | EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[2], (EPRP_SETTER *)onoff_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Ýuê */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_3_EOBJ, { 0x81, EPC_RULE_SET | EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[2].installation_location, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Kiu
+îñ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_3_EOBJ, { 0x82, EPC_RULE_GET, 4, (intptr_t)&electric_energy_meter_data[2].standard_version_information, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Ùí­¶óÔ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_3_EOBJ, { 0x88, EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[2].fault_status, (EPRP_SETTER *)alarm_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* [J[R[h */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_3_EOBJ, { 0x8A, EPC_RULE_GET, 3, (intptr_t)&electric_energy_meter_data[2].manufacturer_code, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* »ÝÝè */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_3_EOBJ, { 0x97, EPC_RULE_SET | EPC_RULE_GET, 2, (intptr_t)NULL, (EPRP_SETTER *)time_prop_set, (EPRP_GETTER *)time_prop_get });
+
+/* »ÝNúÝè */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_3_EOBJ, { 0x98, EPC_RULE_SET | EPC_RULE_GET, 4, (intptr_t)NULL, (EPRP_SETTER *)date_prop_set, (EPRP_GETTER *)date_prop_get });
+
+/* ÏZdÍÊPÊ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_3_EOBJ, { 0xE2, EPC_RULE_GET, 1, (intptr_t)&electric_energy_meter_data[2].integral_electric_energy_unit, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* ÏZdÍÊvªl */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_3_EOBJ, { 0xE0, EPC_RULE_GET, 4, (intptr_t)&electric_energy_meter_data[2].integral_electric_energy_measurement_value, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)watt_hour_meter_integral_electric_energy_measurement_value_get });
+
+/* ÏZdÍÊvªlðP */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_3_EOBJ, { 0xE3, EPC_RULE_GET, 192, (intptr_t)&electric_energy_meter_data[2].integral_electric_energy_measurement_log, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)watt_hour_meter_integral_electric_energy_measurement_log_get });
+
+/*
+ *  dÍÊ[^S
+ */
+ECN_CRE_EOBJ (ELECTRIC_ENERGY_METER_4_EOBJ, { EOBJ_DEVICE, LOCAL_NODE_EOBJ, 0, EOJ_X1_AMENITY, EOJ_X2_ELECTRIC_ENERGY_METER, EOJ_X3_ELECTRIC_ENERGY_METER_4 });
+
+/* ®ìóÔ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_4_EOBJ, { 0x80, EPC_RULE_SET | EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[3], (EPRP_SETTER *)onoff_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Ýuê */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_4_EOBJ, { 0x81, EPC_RULE_SET | EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[3].installation_location, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Kiu
+îñ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_4_EOBJ, { 0x82, EPC_RULE_GET, 4, (intptr_t)&electric_energy_meter_data[3].standard_version_information, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Ùí­¶óÔ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_4_EOBJ, { 0x88, EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[3].fault_status, (EPRP_SETTER *)alarm_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* [J[R[h */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_4_EOBJ, { 0x8A, EPC_RULE_GET, 3, (intptr_t)&electric_energy_meter_data[3].manufacturer_code, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* »ÝÝè */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_4_EOBJ, { 0x97, EPC_RULE_SET | EPC_RULE_GET, 2, (intptr_t)NULL, (EPRP_SETTER *)time_prop_set, (EPRP_GETTER *)time_prop_get });
+
+/* »ÝNúÝè */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_4_EOBJ, { 0x98, EPC_RULE_SET | EPC_RULE_GET, 4, (intptr_t)NULL, (EPRP_SETTER *)date_prop_set, (EPRP_GETTER *)date_prop_get });
+
+/* ÏZdÍÊPÊ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_4_EOBJ, { 0xE2, EPC_RULE_GET, 1, (intptr_t)&electric_energy_meter_data[3].integral_electric_energy_unit, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* ÏZdÍÊvªl */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_4_EOBJ, { 0xE0, EPC_RULE_GET, 4, (intptr_t)&electric_energy_meter_data[3].integral_electric_energy_measurement_value, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)watt_hour_meter_integral_electric_energy_measurement_value_get });
+
+/* ÏZdÍÊvªlðP */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_4_EOBJ, { 0xE3, EPC_RULE_GET, 192, (intptr_t)&electric_energy_meter_data[3].integral_electric_energy_measurement_log, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)watt_hour_meter_integral_electric_energy_measurement_log_get });
+
+/*
+ *  dÍÊ[^T
+ */
+ECN_CRE_EOBJ (ELECTRIC_ENERGY_METER_5_EOBJ, { EOBJ_DEVICE, LOCAL_NODE_EOBJ, 0, EOJ_X1_AMENITY, EOJ_X2_ELECTRIC_ENERGY_METER, EOJ_X3_ELECTRIC_ENERGY_METER_5 });
+
+/* ®ìóÔ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_5_EOBJ, { 0x80, EPC_RULE_SET | EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[4], (EPRP_SETTER *)onoff_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Ýuê */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_5_EOBJ, { 0x81, EPC_RULE_SET | EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[4].installation_location, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Kiu
+îñ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_5_EOBJ, { 0x82, EPC_RULE_GET, 4, (intptr_t)&electric_energy_meter_data[4].standard_version_information, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Ùí­¶óÔ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_5_EOBJ, { 0x88, EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[4].fault_status, (EPRP_SETTER *)alarm_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* [J[R[h */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_5_EOBJ, { 0x8A, EPC_RULE_GET, 3, (intptr_t)&electric_energy_meter_data[4].manufacturer_code, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* »ÝÝè */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_5_EOBJ, { 0x97, EPC_RULE_SET | EPC_RULE_GET, 2, (intptr_t)NULL, (EPRP_SETTER *)time_prop_set, (EPRP_GETTER *)time_prop_get });
+
+/* »ÝNúÝè */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_5_EOBJ, { 0x98, EPC_RULE_SET | EPC_RULE_GET, 4, (intptr_t)NULL, (EPRP_SETTER *)date_prop_set, (EPRP_GETTER *)date_prop_get });
+
+/* ÏZdÍÊPÊ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_5_EOBJ, { 0xE2, EPC_RULE_GET, 1, (intptr_t)&electric_energy_meter_data[4].integral_electric_energy_unit, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* ÏZdÍÊvªl */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_5_EOBJ, { 0xE0, EPC_RULE_GET, 4, (intptr_t)&electric_energy_meter_data[4].integral_electric_energy_measurement_value, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)watt_hour_meter_integral_electric_energy_measurement_value_get });
+
+/* ÏZdÍÊvªlðP */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_5_EOBJ, { 0xE3, EPC_RULE_GET, 192, (intptr_t)&electric_energy_meter_data[4].integral_electric_energy_measurement_log, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)watt_hour_meter_integral_electric_energy_measurement_log_get });
+
+/*
+ *  dÍÊ[^U
+ */
+ECN_CRE_EOBJ (ELECTRIC_ENERGY_METER_6_EOBJ, { EOBJ_DEVICE, LOCAL_NODE_EOBJ, 0, EOJ_X1_AMENITY, EOJ_X2_ELECTRIC_ENERGY_METER, EOJ_X3_ELECTRIC_ENERGY_METER_6 });
+
+/* ®ìóÔ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_6_EOBJ, { 0x80, EPC_RULE_SET | EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[5], (EPRP_SETTER *)onoff_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Ýuê */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_6_EOBJ, { 0x81, EPC_RULE_SET | EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[5].installation_location, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Kiu
+îñ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_6_EOBJ, { 0x82, EPC_RULE_GET, 4, (intptr_t)&electric_energy_meter_data[5].standard_version_information, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* Ùí­¶óÔ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_6_EOBJ, { 0x88, EPC_RULE_GET | EPC_ANNOUNCE, 1, (intptr_t)&electric_energy_meter_data[5].fault_status, (EPRP_SETTER *)alarm_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* [J[R[h */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_6_EOBJ, { 0x8A, EPC_RULE_GET, 3, (intptr_t)&electric_energy_meter_data[5].manufacturer_code, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* »ÝÝè */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_6_EOBJ, { 0x97, EPC_RULE_SET | EPC_RULE_GET, 2, (intptr_t)NULL, (EPRP_SETTER *)time_prop_set, (EPRP_GETTER *)time_prop_get });
+
+/* »ÝNúÝè */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_6_EOBJ, { 0x98, EPC_RULE_SET | EPC_RULE_GET, 4, (intptr_t)NULL, (EPRP_SETTER *)date_prop_set, (EPRP_GETTER *)date_prop_get });
+
+/* ÏZdÍÊPÊ */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_6_EOBJ, { 0xE2, EPC_RULE_GET, 1, (intptr_t)&electric_energy_meter_data[5].integral_electric_energy_unit, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)ecn_data_prop_get });
+
+/* ÏZdÍÊvªl */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_6_EOBJ, { 0xE0, EPC_RULE_GET, 4, (intptr_t)&electric_energy_meter_data[5].integral_electric_energy_measurement_value, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)watt_hour_meter_integral_electric_energy_measurement_value_get });
+
+/* ÏZdÍÊvªlðP */
+ECN_DEF_EPRP (ELECTRIC_ENERGY_METER_6_EOBJ, { 0xE3, EPC_RULE_GET, 192, (intptr_t)&electric_energy_meter_data[5].integral_electric_energy_measurement_log, (EPRP_SETTER *)ecn_data_prop_set, (EPRP_GETTER *)watt_hour_meter_integral_electric_energy_measurement_log_get });
Index: UsbWattMeter/trunk/src/usb_watt_meter/main.h
===================================================================
--- UsbWattMeter/trunk/src/usb_watt_meter/main.h	(revision 164)
+++ UsbWattMeter/trunk/src/usb_watt_meter/main.h	(revision 164)
@@ -0,0 +1,203 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
+ *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
+ *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
+ *      ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
+ *        ñ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
+ *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
+ *      ÆÓ·é±ÆD
+ * 
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
+ *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
+ *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
+ *  ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _MAIN_H_
+#define _MAIN_H_
+
+/*
+ *		TvvO(1)Ìwb_t@C
+ */
+
+/*
+ *  ^[QbgË¶Ìè`
+ */
+#include <kernel.h>
+#include "target_config.h"
+#include "echonet.h"
+
+/*
+ *  e^XNÌDæxÌè`
+ */
+
+#define MAIN_PRIORITY	5		/* C^XNÌDæx */
+
+#define MAIN_STACK_SIZE	1024	/* X^bNÌæÌTCY */
+
+#define EOJ_X3_LOCAL_NODE 1	/* m[hvt@CIuWFNgÌCX^XR[h */
+
+#define EOJ_X3_ELECTRIC_ENERGY_METER_1 1	/* dÍÊ[^PÌCX^XR[h */
+#define EOJ_X3_ELECTRIC_ENERGY_METER_2 2	/* dÍÊ[^QÌCX^XR[h */
+#define EOJ_X3_ELECTRIC_ENERGY_METER_3 3	/* dÍÊ[^RÌCX^XR[h */
+#define EOJ_X3_ELECTRIC_ENERGY_METER_4 4	/* dÍÊ[^SÌCX^XR[h */
+#define EOJ_X3_ELECTRIC_ENERGY_METER_5 5	/* dÍÊ[^TÌCX^XR[h */
+#define EOJ_X3_ELECTRIC_ENERGY_METER_6 6	/* dÍÊ[^UÌCX^XR[h */
+
+#define	KMM_SIZE	8192		/* J[lªèt¯éÌæÌTCY */
+
+/*
+ *  ÖÌvg^Cvé¾
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void main_task(intptr_t exinf);
+
+#ifdef __CA850__
+#pragma pack(1)
+#elif __RX
+#pragma pack
+#elif _MSC_VER
+#pragma pack(push, 1)
+#endif
+
+/*
+ *  u
+îñÌ^
+ */
+struct version_information_t {
+	/* W[o[W(¬_Èã) */
+	uint8_t major_version_number;
+	/* }Ci[o[W(¬_Èº) */
+	uint8_t minor_version_number;
+	/* d¶^Cv */
+	uint8_t message_type[2];
+};
+
+/*
+ *  [J[R[hÌ^
+ */
+struct manufacturer_code_t {
+	/* [J[R[h */
+	uint8_t manufacturer_code[3];
+};
+
+/*
+ *  ¯ÊÔÌ^
+ */
+struct node_identification_number_t {
+	/* ºÊÊMwIDtB[h */
+	uint8_t lower_communication_id_field;
+	/* [J[R[h */
+	struct manufacturer_code_t manufacturer_code;
+	/* j[NID([J[Æ©) */
+	uint8_t unique_id_section[13];
+};
+
+/*
+ *  Kiu
+îñÌ^
+ */
+struct standard_version_information_t {
+	/* Åè1(for future reserved) */
+	uint8_t reserved1;
+	/* Åè2(for future reserved) */
+	uint8_t reserved2;
+	/* [XðASCIIÅ¦· */
+	uint8_t order_of_release;
+	/* Åè4(for future reserved) */
+	uint8_t reserved3;
+};
+
+/*
+ *  m[hvt@CIuWFNg
+ */
+struct node_profile_object_t {
+	/* ®ìóÔ */
+	uint8_t operation_status;
+	/* u
+îñ */
+	struct version_information_t version_information;
+	/* ¯ÊÔ */
+	struct node_identification_number_t identification_number;
+	/* Ùíàe */
+	uint16_t fault_content;
+	/* [J[R[h */
+	struct manufacturer_code_t manufacturer_code;
+};
+
+/*
+ *  dÍÊ[^
+ */
+struct watt_hour_meter_t {
+	/* ®ìóÔ */
+	uint8_t operation_status;
+	/* Ýuê */
+	uint8_t installation_location;
+	/* Kiu
+îñ */
+	struct standard_version_information_t standard_version_information;
+	/* Ùí­¶óÔ */
+	uint8_t fault_status;
+	/* [J[R[h */
+	struct manufacturer_code_t manufacturer_code;
+	/* ÏZdÍÊPÊ */
+	uint8_t integral_electric_energy_unit;
+	/* ÏZdÍÊvªl */
+	uint32_t integral_electric_energy_measurement_value;
+	/* ÏZdÍÊvªlðP */
+	uint32_t integral_electric_energy_measurement_log[48];
+	int current_pos;
+};
+
+#ifdef __CA850__
+#pragma pack(8)
+#elif __RX
+#pragma unpack
+#elif _MSC_VER
+#pragma pack(pop)
+#endif
+
+extern struct node_profile_object_t local_node_data;	/* m[hvt@CIuWFNgÌf[^ */
+
+extern struct watt_hour_meter_t electric_energy_meter_data[6];	/* dÍÊ[^P`UÌf[^ */
+
+EPRP_SETTER onoff_prop_set;
+EPRP_SETTER alarm_prop_set;
+EPRP_SETTER time_prop_set;
+EPRP_GETTER time_prop_get;
+EPRP_SETTER date_prop_set;
+EPRP_GETTER date_prop_get;
+EPRP_GETTER watt_hour_meter_integral_electric_energy_measurement_value_get;
+EPRP_GETTER watt_hour_meter_integral_electric_energy_unit_get;
+EPRP_GETTER watt_hour_meter_integral_electric_energy_measurement_log_get;
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif	/* of #ifndef _MAINN_H_ */
Index: UsbWattMeter/trunk/tlsf-3.0/Readme.txt
===================================================================
--- UsbWattMeter/trunk/tlsf-3.0/Readme.txt	(revision 164)
+++ UsbWattMeter/trunk/tlsf-3.0/Readme.txt	(revision 164)
@@ -0,0 +1,102 @@
+Two Level Segregated Fit memory allocator implementation.
+Written by Matthew Conte (matt@baisoku.org).
+Public Domain, no restrictions.
+
+	http://tlsf.baisoku.org
+
+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://rtportal.upv.es/rtmalloc/allocators/tlsf/index.shtml
+
+It also leverages the TLSF 2.0 improvement to shrink the per-block overhead
+from 8 to 4 bytes.
+
+Known Issues
+------------
+* Due to the internal block structure size and the implementation
+details of tlsf_memalign, there is worst-case behavior when requesting
+small (<16 byte) blocks aligned to 8-byte boundaries. Overuse of memalign
+will generally increase fragmentation, but this particular case will leave
+lots of unusable "holes" in the pool. The solution would be to internally
+align all blocks to 8 bytes, but this will require significantl changes
+to the implementation. Contact me if you are interested.
+
+History
+-------
+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: UsbWattMeter/trunk/tlsf-3.0/tlsf.c
===================================================================
--- UsbWattMeter/trunk/tlsf-3.0/tlsf.c	(revision 164)
+++ UsbWattMeter/trunk/tlsf-3.0/tlsf.c	(revision 164)
@@ -0,0 +1,1065 @@
+//#include <assert.h>
+//#include <limits.h>
+//#include <stddef.h>
+//#include <stdio.h>
+//#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "tlsf.h"
+#include "tlsfbits.h"
+#include "t_syslog.h"
+
+#ifdef __RX
+#define printf(...)
+#else
+void printf(const char *format, ...)
+{
+	va_list	va;
+	va_start(va, format);
+	vsyslog(LOG_DEBUG, format, va);
+	va_end(va);
+}
+#endif
+
+/*
+** Constants.
+*/
+
+/* Public constants: may be modified. */
+enum tlsf_public
+{
+	/* log2 of number of linear subdivisions of block sizes. */
+	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 0 == block_size(block);
+}
+
+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)
+{
+	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 >= (1 << SL_INDEX_COUNT_LOG2))
+	{
+		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] & (~0 << sl);
+	if (!sl_map)
+	{
+		/* No block exists. Search in the next largest first-level list. */
+		const unsigned int fl_map = control->fl_bitmap & (~0 << (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)
+	{
+		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;
+	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;
+	printf("\t%p %s size: %x (%p)\n", 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()
+{
+	return sizeof(control_t);
+}
+
+size_t tlsf_align_size()
+{
+	return ALIGN_SIZE;
+}
+
+size_t tlsf_block_size_min()
+{
+	return block_size_min;
+}
+
+size_t tlsf_block_size_max()
+{
+	return block_size_max;
+}
+
+/*
+** Overhead of the TLSF structures in a given memory block passes to
+** tlsf_add_pool, equal to the overhead of a free block and the
+** sentinel block.
+*/
+size_t tlsf_pool_overhead()
+{
+	return 2 * block_header_overhead;
+}
+
+size_t tlsf_alloc_overhead()
+{
+	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)
+	{
+		printf("tlsf_add_pool: Memory must be aligned by %u bytes.\n",
+			(unsigned int)ALIGN_SIZE);
+		return 0;
+	}
+
+	if (pool_bytes < block_size_min || pool_bytes > block_size_max)
+	{
+#if defined (TLSF_64BIT)
+		printf("tlsf_add_pool: Memory size must be between 0x%x and 0x%x00 bytes.\n", 
+			(unsigned int)(pool_overhead + block_size_min),
+			(unsigned int)((pool_overhead + block_size_max) / 256));
+#else
+		printf("tlsf_add_pool: Memory size must be between %u and %u bytes.\n", 
+			(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)
+	{
+		printf("tlsf_create: %x ffs/fls tests failed!\n", 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)
+	{
+		printf("tlsf_create: Memory must be aligned to %u bytes.\n",
+			(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. */
+	const size_t aligned_size = (align <= ALIGN_SIZE) ? adjust : size_with_gap;
+
+	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: UsbWattMeter/trunk/tlsf-3.0/tlsf.h
===================================================================
--- UsbWattMeter/trunk/tlsf-3.0/tlsf.h	(revision 164)
+++ UsbWattMeter/trunk/tlsf-3.0/tlsf.h	(revision 164)
@@ -0,0 +1,68 @@
+#ifndef INCLUDED_tlsf
+#define INCLUDED_tlsf
+
+/*
+** Two Level Segregated Fit memory allocator, version 3.0.
+** Written by Matthew Conte, and placed in the Public Domain.
+**	http://tlsf.baisoku.org
+**
+** Based on the original documentation by Miguel Masmano:
+**	http://rtportal.upv.es/rtmalloc/allocators/tlsf/index.shtml
+**
+** Please see the accompanying Readme.txt for implementation
+** notes and caveats.
+**
+** This implementation was written to the specification
+** of the document, therefore no GPL restrictions apply.
+*/
+
+#include <t_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();
+size_t tlsf_align_size();
+size_t tlsf_block_size_min();
+size_t tlsf_block_size_max();
+size_t tlsf_pool_overhead();
+size_t tlsf_alloc_overhead();
+
+/* 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: UsbWattMeter/trunk/tlsf-3.0/tlsfbits.h
===================================================================
--- UsbWattMeter/trunk/tlsf-3.0/tlsfbits.h	(revision 164)
+++ UsbWattMeter/trunk/tlsf-3.0/tlsfbits.h	(revision 164)
@@ -0,0 +1,180 @@
+#ifndef INCLUDED_tlsfbits
+#define INCLUDED_tlsfbits
+
+#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__)
+
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+	return __builtin_ffs(word) - 1;
+}
+
+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
+
+#endif
Index: UsbWattMeter/trunk/wolfssl-3.7.0/COPYING
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/COPYING	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/COPYING	(revision 164)
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
Index: UsbWattMeter/trunk/wolfssl-3.7.0/LICENSING
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/LICENSING	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/LICENSING	(revision 164)
@@ -0,0 +1,11 @@
+
+wolfSSL (formerly known as CyaSSL) and wolfCrypt are either licensed for use
+under the GPLv2 or a standard commercial license. For our users who cannot use
+wolfSSL under GPLv2, a commercial license to wolfSSL and wolfCrypt is available.
+Please contact wolfSSL Inc. directly at:
+
+Email: licensing@wolfssl.com
+Phone: +1 425 245-8247
+
+More information can be found on the wolfSSL website at www.wolfssl.com.
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/README
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/README	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/README	(revision 164)
@@ -0,0 +1,1273 @@
+*** Notes, Please read ***
+
+Note 1)
+wolfSSL as of 3.6.6 no longer enables SSLv3 by default.  wolfSSL also no
+longer supports static key cipher suites with PSK, RSA, or ECDH.  This means
+if you plan to use TLS cipher suites you must enable DH (DH is on  by default),
+or enable ECC (ECC is on by default on 64bit systems), or you must enable static
+key cipher suites with
+    WOLFSSL_STATIC_DH
+    WOLFSSL_STATIC_RSA
+    or
+    WOLFSSL_STATIC_PSK
+
+though static key cipher suites are deprecated and will be removed from future
+versions of TLS.  They also lower your security by removing PFS.
+
+When compiling ssl.c wolfSSL will now issue a compiler error if no cipher suites
+are available.  You can remove this error by defining WOLFSSL_ALLOW_NO_SUITES
+in the event that you desire that, i.e., you're not using TLS cipher suites.
+
+Note 2)
+wolfSSL takes a different approach to certificate verification than OpenSSL
+does.  The default policy for the client is to verify the server, this means
+that if you don't load CAs to verify the server you'll get a connect error,
+no signer error to confirm failure (-188).
+If you want to mimic OpenSSL behavior of having SSL_connect succeed even if
+verifying the server fails and reducing security you can do this by calling:
+
+wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
+
+before calling wolfSSL_new();  Though it's not recommended.
+
+*** end Notes ***
+
+ ********* wolfSSL (Formerly CyaSSL) Release 3.7.0 (10/26/2015)
+
+Release 3.7.0 of wolfSSL has bug fixes and new features including:
+
+- ALPN extension support added for HTTP2 connections with --enable-alpn
+- Change of example/client/client max fragment flag -L -> -F
+- Throughput benchmarking, added scripts/benchmark.test
+- Sniffer API ssl_FreeDecodeBuffer added
+- Addition of AES_GCM to Sniffer
+- Sniffer change to handle unlimited decrypt buffer size
+- New option for the sniffer where it will try to pick up decoding after a
+  sequence number acknowldgement fault. Also includes some additional stats.
+- JNI API setter and getter function for jobject added
+- User RSA crypto plugin abstraction. An example placed in wolfcrypt/user-crypto
+- fix to asn configuration bug
+- AES-GCM/CCM fixes.
+- Port for Rowley added
+- Rowley Crossworks bare metal examples added
+- MDK5-ARM project update
+- FreeRTOS support updates.
+- VXWorks support updates.
+- Added the IDEA cipher and support in wolfSSL.
+- Update wolfSSL website CA.
+- CFLAGS is usable when configuring source.
+
+- No high level security fixes that requires an update though we always
+recommend updating to the latest
+
+See INSTALL file for build instructions.
+More info can be found on-line at //http://wolfssl.com/yaSSL/Docs.html
+
+ ********* wolfSSL (Formerly CyaSSL) Release 3.6.8 (09/17/2015)
+
+Release 3.6.8 of wolfSSL fixes two high severity vulnerabilities.  It also
+includes bug fixes and new features including:
+
+- Two High level security fixes, all users SHOULD update.
+  a) If using wolfSSL for DTLS on the server side of a publicly accessible
+     machine you MUST update.
+  b) If using wolfSSL for TLS on the server side with private RSA keys allowing
+     ephemeral key exchange without low memory optimizations you MUST update and
+     regenerate the private RSA keys.
+
+     Please see https://www.wolfssl.com/wolfSSL/Blog/Blog.html for more details
+
+- No filesystem build fixes for various configurations
+- Certificate generation now supports several extensions including KeyUsage,
+    SKID, AKID, and Certificate Policies
+- CRLs can be loaded from buffers as well as files now
+- SHA-512 Certificate Signing generation
+- Fixes for sniffer reassembly processing
+
+See INSTALL file for build instructions.
+More info can be found on-line at //http://wolfssl.com/yaSSL/Docs.html
+
+ ********* wolfSSL (Formerly CyaSSL) Release 3.6.6 (08/20/2015)
+
+Release 3.6.6 of wolfSSL has bug fixes and new features including:
+
+- OpenSSH  compatibility with --enable-openssh
+- stunnel  compatibility with --enable-stunnel
+- lighttpd compatibility with --enable-lighty
+- SSLv3 is now disabled by default, can be enabled with --enable-sslv3
+- Ephemeral key cipher suites only are now supported by default
+    To enable static ECDH cipher suites define WOLFSSL_STATIC_DH
+    To enable static  RSA cipher suites define WOLFSSL_STATIC_RSA
+    To enable static  PSK cipher suites define WOLFSSL_STATIC_PSK
+- Added QSH (quantum-safe handshake) extension with --enable-ntru
+- SRP is now part of wolfCrypt, enable with --enabe-srp
+- Certificate handshake messages can now be sent fragmented if the record
+  size is smaller than the total message size, no user action required.
+- DTLS duplicate message fixes
+- Visual Studio project files now support DLL and static builds for 32/64bit.
+- Support for new Freescale I/O
+- FreeRTOS FIPS support
+
+- No high level security fixes that requires an update though we always
+  recommend updating to the latest
+
+See INSTALL file for build instructions.
+More info can be found on-line at //http://wolfssl.com/yaSSL/Docs.html
+
+ **************** wolfSSL (Formerly CyaSSL) Release 3.6.0 (06/19/2015)
+
+Release 3.6.0 of wolfSSL has bug fixes and new features including:
+
+- Max Strength build that only allows TLSv1.2, AEAD ciphers, and PFS (Perfect
+   Forward Secrecy).  With --enable-maxstrength
+- Server side session ticket support, the example server and echoserver use the
+   example callback myTicketEncCb(), see wolfSSL_CTX_set_TicketEncCb()
+- FIPS version submitted for iOS.
+- TI Crypto Hardware Acceleration
+- DTLS fragmentation fixes
+- ECC key check validation with wc_ecc_check_key()
+- 32bit code options to reduce memory for Curve25519 and Ed25519
+- wolfSSL JNI build switch with --enable-jni
+- PicoTCP support improvements
+- DH min ephemeral key size enforcement with wolfSSL_CTX_SetMinDhKey_Sz()
+- KEEP_PEER_CERT and AltNames can now be used together
+- ChaCha20 big endian fix
+- SHA-512 signature algorithm support for key exchange and verify messages
+- ECC make key crash fix on RNG failure, ECC users must update.
+- Improvements to usage of time code.
+- Improvements to VS solution files.
+- GNU Binutils 2.24 ld has problems with some debug builds, to fix an ld error
+  add -fdebug-types-section to C_EXTRA_FLAGS
+
+- No high level security fixes that requires an update though we always
+  recommend updating to the latest (except note 14, ecc RNG failure)
+
+See INSTALL file for build instructions.
+More info can be found on-line at //http://wolfssl.com/yaSSL/Docs.html
+
+
+ *****************wolfSSL (Formerly CyaSSL) Release 3.4.6 (03/30/2015)
+
+Release 3.4.6 of wolfSSL has bug fixes and new features including:
+
+- Intel Assembly Speedups using instructions rdrand, rdseed, aesni, avx1/2,
+  rorx, mulx, adox, adcx .  They can be enabled with --enable-intelasm.
+  These speedup the use of RNG, SHA2, and public key algorithms.
+- Ed25519 support at the crypto level. Turn on with --enable-ed25519.  Examples
+  in wolcrypt/test/test.c ed25519_test().
+- Post Handshake Memory reductions.  wolfSSL can now hold less than 1,000 bytes
+  of memory per secure connection including cipher state.
+- wolfSSL API and wolfCrypt API fixes, you can still include the cyassl and
+  ctaocrypt headers which will enable the compatibility APIs for the
+  foreseeable future
+- INSTALL file to help direct users to build instructions for their environment
+- For ECC users with the normal math library a fix that prevents a crash when
+  verify signature fails.  Users of 3.4.0 with ECC and the normal math library
+  must update
+- RC4 is now disabled by default in autoconf mode
+- AES-GCM and ChaCha20/Poly1305 are now enabled by default to make AEAD ciphers
+  available without a switch
+- External ChaCha-Poly AEAD API, thanks to Andrew Burks for the contribution
+- DHE-PSK cipher suites can now be built without ASN or Cert support
+- Fix some NO MD5 build issues with optional features
+- Freescale CodeWarrior project updates
+- ECC curves can be individually turned on/off at build time.
+- Sniffer handles Cert Status message and other minor fixes
+- SetMinVersion() at the wolfSSL Context level instead of just SSL session level
+  to allow minimum protocol version allowed at runtime
+- RNG failure resource cleanup fix
+
+- No high level security fixes that requires an update though we always
+  recommend updating to the latest (except note 6 use case of ecc/normal math)
+
+See INSTALL file for build instructions.
+More info can be found on-line at //http://wolfssl.com/yaSSL/Docs.html
+
+
+ *****************wolfSSL (Formerly CyaSSL) Release 3.4.0 (02/23/2015)
+
+Release 3.4.0 wolfSSL has bug fixes and new features including:
+
+- wolfSSL API and wolfCrypt API, you can still include the cyassl and ctaocrypt
+  headers which will enable the compatibility APIs for the foreseeable future
+- Example use of the wolfCrypt API can be found in wolfcrypt/test/test.c
+- Example use of the wolfSSL API can be found in examples/client/client.c
+- Curve25519 now supported at the wolfCrypt level, wolfSSL layer coming soon
+- Improvements in the build configuration under AIX
+- Microchip Pic32 MZ updates
+- TIRTOS updates
+- PowerPC updates
+- Xcode project update
+- Bidirectional shutdown examples in client/server with -w (wait for full
+  shutdown) option
+- Cycle counts on benchmarks for x86_64, more coming soon
+- ALT_ECC_SIZE for reducing ecc heap use with fastmath when also using large RSA
+  keys
+- Various compile warnings
+- Scan-build warning fixes
+- Changed a memcpy to memmove in the sniffer (if using sniffer please update)
+- No high level security fixes that requires an update though we always
+  recommend updating to the latest
+
+
+ ***********CyaSSL Release 3.3.0 (12/05/2014)
+
+- Countermeasuers for Handshake message duplicates, CHANGE CIPHER without
+  FINISHED, and fast forward attempts.  Thanks to Karthikeyan Bhargavan from
+  the Prosecco team at INRIA Paris-Rocquencourt for the report.
+- FIPS version submitted
+- Removes SSLv2 Client Hello processing, can be enabled with OLD_HELLO_ALLOWED
+- User can set minimum downgrade version with CyaSSL_SetMinVersion()
+- Small stack improvements at TLS/SSL layer
+- TLS Master Secret generation and Key Expansion are now exposed
+- Adds client side Secure Renegotiation, * not recommended *
+- Client side session ticket support, not fully tested with Secure Renegotiation
+- Allows up to 4096bit DHE at TLS Key Exchange layer
+- Handles non standard SessionID sizes in Hello Messages
+- PicoTCP Support
+- Sniffer now supports SNI Virtual Hosts
+- Sniffer now handles non HTTPS protocols using STARTTLS
+- Sniffer can now parse records with multiple messages
+- TI-RTOS updates
+- Fix for ColdFire optimized fp_digit read only in explicit 32bit case
+- ADH Cipher Suite ADH-AES128-SHA for EAP-FAST
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions
+and comments about the new features please check the manual.
+
+
+***********CyaSSL Release 3.2.0 (09/10/2014)
+
+Release 3.2.0 CyaSSL has bug fixes and new features including:
+
+- ChaCha20 and Poly1305 crypto and suites
+- Small stack improvements for OCSP, CRL, TLS, DTLS
+- NTRU Encrypt and Decrypt benchmarks
+- Updated Visual Studio project files
+- Updated Keil MDK5 project files
+- Fix for DTLS sequence numbers with GCM/CCM
+- Updated HashDRBG with more secure struct declaration
+- TI-RTOS support and example Code Composer Studio project files
+- Ability to get enabled cipher suites, CyaSSL_get_ciphers()
+- AES-GCM/CCM/Direct support for Freescale mmCAU and CAU
+- Sniffer improvement checking for decrypt key setup
+- Support for raw ECC key import
+- Ability to convert ecc_key to DER, EccKeyToDer()
+- Security fix for RSA Padding check vulnerability reported by Intel Security
+  Advanced Threat Research team
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions
+and comments about the new features please check the manual.
+
+
+************ CyaSSL Release 3.1.0 (07/14/2014)
+
+Release 3.1.0 CyaSSL has bug fixes and new features including:
+
+- Fix for older versions of icc without 128-bit type
+- Intel ASM syntax for AES-NI
+- Updated NTRU support, keygen benchmark
+- FIPS check for minimum required HMAC key length
+- Small stack (--enable-smallstack) improvements for PKCS#7, ASN
+- TLS extension support for DTLS
+- Default I/O callbacks external to user
+- Updated example client with bad clock test
+- Ability to set optional ECC context info
+- Ability to enable/disable DH separate from opensslextra
+- Additional test key/cert buffers for CA and server
+- Updated example certificates
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions
+and comments about the new features please check the manual.
+
+
+************ CyaSSL Release 3.0.2 (05/30/2014)
+
+Release 3.0.2 CyaSSL has bug fixes and new features including:
+
+- Added the following cipher suites:
+  * TLS_PSK_WITH_AES_128_GCM_SHA256
+  * TLS_PSK_WITH_AES_256_GCM_SHA384
+  * TLS_PSK_WITH_AES_256_CBC_SHA384
+  * TLS_PSK_WITH_NULL_SHA384
+  * TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+  * TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+  * TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+  * TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+  * TLS_DHE_PSK_WITH_NULL_SHA256
+  * TLS_DHE_PSK_WITH_NULL_SHA384
+  * TLS_DHE_PSK_WITH_AES_128_CCM
+  * TLS_DHE_PSK_WITH_AES_256_CCM
+- Added AES-NI support for Microsoft Visual Studio builds.
+- Changed small stack build to be disabled by default.
+- Updated the Hash DRBG and provided a configure option to enable.
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions
+and comments about the new features please check the manual.
+
+
+************ CyaSSL Release 3.0.0 (04/29/2014)
+
+Release 3.0.0 CyaSSL has bug fixes and new features including:
+
+- FIPS release candidate
+- X.509 improvements that address items reported by Suman Jana with security
+  researchers at UT Austin and UC Davis
+- Small stack size improvements, --enable-smallstack. Offloads large local
+  variables to the heap. (Note this is not complete.)
+- Updated AES-CCM-8 cipher suites to use approved suite numbers.
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions
+and comments about the new features please check the manual.
+
+
+************ CyaSSL Release 2.9.4 (04/09/2014)
+
+Release 2.9.4 CyaSSL has bug fixes and new features including:
+
+- Security fixes that address items reported by Ivan Fratric of the Google
+  Security Team
+- X.509 Unknown critical extensions treated as errors, report by Suman Jana with
+  security researchers at UT Austin and UC Davis
+- Sniffer fixes for corrupted packet length and Jumbo frames
+- ARM thumb mode assembly fixes
+- Xcode 5.1 support including new clang
+- PIC32 MZ hardware support
+- CyaSSL Object has enough room to read the Record Header now w/o allocs
+- FIPS wrappers for AES, 3DES, SHA1, SHA256, SHA384, HMAC, and RSA.
+- A sample I/O pool is demonstrated with --enable-iopool to overtake memory
+  handling and reduce memory fragmentation on I/O large sizes
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+
+************ CyaSSL Release 2.9.0 (02/07/2014)
+
+Release 2.9.0 CyaSSL has bug fixes and new features including:
+- Freescale Kinetis RNGB support
+- Freescale Kinetis mmCAU support
+- TLS Hello extensions
+  - ECC
+  - Secure Renegotiation (null) 
+  - Truncated HMAC
+- SCEP support
+  - PKCS #7 Enveloped data and signed data
+  - PKCS #10 Certificate Signing Request generation
+- DTLS sliding window
+- OCSP Improvements
+  - API change to integrate into Certificate Manager
+  - IPv4/IPv6 agnostic
+  - example client/server support for OCSP
+  - OCSP nonces are optional
+- GMAC hashing
+- Windows build additions
+- Windows CYGWIN build fixes
+- Updated test certificates
+- Microchip MPLAB Harmony support
+- Update autoconf scripts
+- Additional X.509 inspection functions
+- ECC encrypt/decrypt primitives
+- ECC Certificate generation
+
+The Freescale Kinetis K53 RNGB documentation can be found in Chapter 33 of the
+K53 Sub-Family Reference Manual:
+http://cache.freescale.com/files/32bit/doc/ref_manual/K53P144M100SF2RM.pdf
+
+Freescale Kinetis K60 mmCAU (AES, DES, 3DES, MD5, SHA, SHA256) documentation
+can be found in the "ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library
+User Guide":
+http://cache.freescale.com/files/32bit/doc/user_guide/CAUAPIUG.pdf
+
+
+*****************CyaSSL Release 2.8.0 (8/30/2013)
+
+Release 2.8.0 CyaSSL has bug fixes and new features including:
+- AES-GCM and AES-CCM use AES-NI
+- NetX default IO callback handlers
+- IPv6 fixes for DTLS Hello Cookies
+- The ability to unload Certs/Keys after the handshake, CyaSSL_UnloadCertsKeys()
+- SEP certificate extensions
+- Callback getters for easier resource freeing
+- External CYASSL_MAX_ERROR_SZ for correct error buffer sizing
+- MacEncrypt and DecryptVerify Callbacks for User Atomic Record Layer Processing
+- Public Key Callbacks for ECC and RSA
+- Client now sends blank cert upon request if doesn't have one with TLS <= 1.2
+
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+
+*****************CyaSSL Release 2.7.0 (6/17/2013)
+
+Release 2.7.0 CyaSSL has bug fixes and new features including:
+- SNI support for client and server
+- KEIL MDK-ARM projects
+- Wildcard check to domain name match, and Subject altnames are checked too
+- Better error messages for certificate verification errors
+- Ability to discard session during handshake verify
+- More consistent error returns across all APIs
+- Ability to unload CAs at the CTX or CertManager level
+- Authority subject id support for Certificate matching
+- Persistent session cache functionality
+- Persistent CA cache functionality
+- Client session table lookups to push serverID table to library level
+- Camellia support to sniffer
+- User controllable settings for DTLS timeout values
+- Sniffer fixes for caching long lived sessions
+- DTLS reliability enhancements for the handshake
+- Better ThreadX support
+
+When compiling with Mingw, libtool may give the following warning due to
+path conversion errors:
+
+libtool: link: Could not determine host file name corresponding to **
+libtool: link: Continuing, but uninstalled executables may not work.
+
+If so, examples and testsuite will have problems when run, showing an
+error while loading shared libraries. To resolve, please run "make install".
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+
+************** CyaSSL Release 2.6.0 (04/15/2013)
+
+Release 2.6.0 CyaSSL has bug fixes and new features including:
+- DTLS 1.2 support including AEAD ciphers
+- SHA-3 finalist Blake2 support, it's fast and uses little resources
+- SHA-384 cipher suites including ECC ones
+- HMAC now supports SHA-512
+- Track memory use for example client/server with -t option
+- Better IPv6 examples with --enable-ipv6, before if ipv6 examples/tests were
+  turned on, localhost only was used.  Now link-local (with scope ids) and ipv6
+  hosts can be used as well.
+- Xcode v4.6 project for iOS v6.1 update
+- settings.h is now checked in all *.c files for true one file setting detection
+- Better alignment at SSL layer for hardware crypto alignment needs
+    * Note, SSL itself isn't friendly to alignment with 5 byte TLS headers and
+      13 bytes DTLS headers, but every effort is now made to align with the
+      CYASSL_GENERAL_ALIGNMENT flag which sets desired alignment requirement
+- NO_64BIT flag to turn off 64bit data type accumulators in public key code
+    * Note, some systems are faster with 32bit accumulators 
+- --enable-stacksize for example client/server stack use
+    * Note, modern desktop Operating Systems may add bytes to each stack frame
+- Updated compression/decompression with direct crypto access
+- All ./configure options are now lowercase only for consistency
+- ./configure builds default to fastmath option
+    * Note, if on ia32 and building in shared mode this may produce a problem
+      with a missing register being available because of PIC, there are at least
+      6 solutions to this:
+      1) --disable-fastmath , don't use fastmath
+      2) --disable-shared, don't build a shared library
+      3) C_EXTRA_FLAGS=-DTFM_NO_ASM , turn off assembly use
+      4) use clang, it just seems to work
+      5) play around with no PIC options to force all registers being open,
+         e.g, --without-pic
+      6) if static lib is still a problem try removing fPIE
+- Many new ./configure switches for option enable/disable for example
+    * rsa
+    * dh
+    * dsa
+    * md5
+    * sha 
+    * arc4
+    * null    (allow NULL ciphers)
+    * oldtls  (only use TLS 1.2)
+    * asn     (no certs or public keys allowed)
+- ./configure generates cyassl/options.h which allows a header the user can 
+  include in their app to make sure the same options are set at the app and
+  CyaSSL level.
+- autoconf no longer needs serial-tests which lowers version requirements of
+  automake to 1.11 and autoconf to 2.63
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+
+
+************** CyaSSL Release 2.5.0 (02/04/2013)
+
+Release 2.5.0 CyaSSL has bug fixes and new features including:
+- Fix for TLS CBC padding timing attack identified by Nadhem Alfardan and
+  Kenny Paterson: http://www.isg.rhul.ac.uk/tls/
+- Microchip PIC32 (MIPS16, MIPS32) support
+- Microchip MPLAB X example projects for PIC32 Ethernet Starter Kit
+- Updated CTaoCrypt benchmark app for embedded systems
+- 1024-bit test certs/keys and cert/key buffers
+- AES-CCM-8 crypto and cipher suites
+- Camellia crypto and cipher suites
+- Bumped minimum autoconf version to 2.65, automake version to 1.12
+- Addition of OCSP callbacks
+- STM32F2 support with hardware crypto and RNG 
+- Cavium NITROX support
+
+CTaoCrypt now has support for the Microchip PIC32 and has been tested with
+the Microchip PIC32 Ethernet Starter Kit, the XC32 compiler and
+MPLAB X IDE in both MIPS16 and MIPS32 instruction set modes. See the README
+located under the <cyassl_root>/mplabx directory for more details.
+
+To add Cavium NITROX support do:
+
+./configure --with-cavium=/home/user/cavium/software
+
+pointing to your licensed cavium/software directory.  Since Cavium doesn't
+build a library we pull in the cavium_common.o file which gives a libtool 
+warning about the portability of this.  Also, if you're using the github source
+tree you'll need to remove the -Wredundant-decls warning from the generated
+Makefile because the cavium headers don't conform to this warning.  Currently
+CyaSSL supports Cavium RNG, AES, 3DES, RC4, HMAC, and RSA directly at the crypto
+layer.  Support at the SSL level is partial and currently just does AES, 3DES,
+and RC4.  RSA and HMAC are slower until the Cavium calls can be utilized in non
+blocking mode.  The example client turns on cavium support as does the crypto
+test and benchmark.  Please see the HAVE_CAVIUM define.
+
+CyaSSL is able to use the STM32F2 hardware-based cryptography and random number
+generator through the STM32F2 Standard Peripheral Library. For necessary
+defines, see the CYASSL_STM32F2 define in settings.h. Documentation for the
+STM32F2 Standard Peripheral Library can be found in the following document: 
+http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/USER_MANUAL/DM00023896.pdf
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+
+
+*************** CyaSSL Release 2.4.6 (12/20/2012)
+
+Release 2.4.6 CyaSSL has bug fixes and a few new features including:
+- ECC into main version
+- Lean PSK build (reduced code size, RAM usage, and stack usage)
+- FreeBSD CRL monitor support
+- CyaSSL_peek()
+- CyaSSL_send() and CyaSSL_recv() for I/O flag setting
+- CodeWarrior Support
+- MQX Support
+- Freescale Kinetis support including Hardware RNG
+- autoconf builds use jobserver
+- cyassl-config
+- Sniffer memory reductions
+
+Thanks to Brian Aker for the improved autoconf system, make rpm, cyassl-config,
+warning system, and general good ideas for improving CyaSSL!
+
+The Freescale Kinetis K70 RNGA documentation can be found in Chapter 37 of the
+K70 Sub-Family Reference Manual:
+http://cache.freescale.com/files/microcontrollers/doc/ref_manual/K70P256M150SF3RM.pdf
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+
+*************** CyaSSL Release 2.4.0 (10/10/2012)
+
+Release 2.4.0 CyaSSL has bug fixes and a few new features including:
+- DTLS reliability
+- Reduced memory usage after handshake
+- Updated build process
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+
+
+*************** CyaSSL Release 2.3.0 (8/10/2012)
+
+Release 2.3.0 CyaSSL has bug fixes and a few new features including:
+- AES-GCM crypto and cipher suites
+- make test cipher suite checks
+- Subject AltName processing
+- Command line support for client/server examples
+- Sniffer SessionTicket support
+- SHA-384 cipher suites
+- Verify cipher suite validity when user overrides
+- CRL dir monitoring
+- DTLS Cookie support, reliability coming soon
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+
+
+***************CyaSSL Release 2.2.0 (5/18/2012)
+
+Release 2.2.0 CyaSSL has bug fixes and a few new features including:
+- Initial CRL support (--enable-crl)
+- Initial OCSP support (--enable-ocsp)
+- Add static ECDH suites
+- SHA-384 support
+- ECC client certificate support
+- Add medium session cache size (1055 sessions) 
+- Updated unit tests
+- Protection against mutex reinitialization
+
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+
+
+***************CyaSSL Release 2.0.8 (2/24/2012)
+
+Release 2.0.8 CyaSSL has bug fixes and a few new features including:
+- A fix for malicious certificates pointed out by Remi Gacogne (thanks)
+  resulting in NULL pointer use.
+- Respond to renegotiation attempt with no_renegoatation alert
+- Add basic path support for load_verify_locations()
+- Add set Temp EC-DHE key size
+- Extra checks on rsa test when porting into
+
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+
+
+************* CyaSSL Release 2.0.6 (1/27/2012)
+
+Release 2.0.6 CyaSSL has bug fixes and a few new features including:
+- Fixes for CA basis constraint check
+- CTX reference counting
+- Initial unit test additions
+- Lean and Mean Windows fix
+- ECC benchmarking
+- SSMTP build support
+- Ability to group handshake messages with set_group_messages(ctx/ssl)
+- CA cache addition callback
+- Export Base64_Encode for general use
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+
+
+************* CyaSSL Release 2.0.2 (12/05/2011)
+
+Release 2.0.2 CyaSSL has bug fixes and a few new features including:
+- CTaoCrypt Runtime library detection settings when directly using the crypto
+  library
+- Default certificate generation now uses SHAwRSA and adds SHA256wRSA generation
+- All test certificates now use 2048bit and SHA-1 for better modern browser
+  support
+- Direct AES block access and AES-CTR (counter) mode
+- Microchip pic32 support
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+
+
+************* CyaSSL Release 2.0.0rc3 (9/28/2011)
+
+Release 2.0.0rc3 for CyaSSL has bug fixes and a few new features including:
+- updated autoconf support
+- better make install and uninstall  (uses system directories)
+- make test / make check
+- CyaSSL headers now in <cyassl/*.h>
+- CTaocrypt headers now in <cyassl/ctaocrypt/*.h>
+- OpenSSL compatibility headers now in <cyassl/openssl/*.h>
+- examples and tests all run from home directory so can use certs in ./certs
+        (see note 1)
+
+So previous applications that used the OpenSSL compatibility header
+<openssl/ssl.h> now need to include <cyassl/openssl/ssl.h> instead, no other
+changes are required.
+
+Special Thanks to Brian Aker for his autoconf, install, and header patches.
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+************CyaSSL Release 2.0.0rc2 (6/6/2011)
+
+Release 2.0.0rc2 for CyaSSL has bug fixes and a few new features including:
+- bug fixes (Alerts, DTLS with DHE)
+- FreeRTOS support
+- lwIP support
+- Wshadow warnings removed
+- asn public header
+- CTaoCrypt public headers now all have ctc_ prefix (the manual is still being
+        updated to reflect this change)
+- and more.
+
+This is the 2nd and perhaps final release candidate for version 2.
+Please send any comments or questions to support@wolfssl.com.
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+***********CyaSSL Release 2.0.0rc1 (5/2/2011)
+
+Release 2.0.0rc1 for CyaSSL has many new features including:
+- bug fixes
+- SHA-256 cipher suites 
+- Root Certificate Verification (instead of needing all certs in the chain) 
+- PKCS #8 private key encryption (supports PKCS #5 v1-v2 and PKCS #12) 
+- Serial number retrieval for x509 
+- PBKDF2 and PKCS #12 PBKDF 
+- UID parsing for x509 
+- SHA-256 certificate signatures 
+- Client and server can send chains (SSL_CTX_use_certificate_chain_file) 
+- CA loading can now parse multiple certificates per file
+- Dynamic memory runtime hooks
+- Runtime hooks for logging
+- EDH on server side
+- More informative error codes
+- More informative logging messages
+- Version downgrade more robust (use SSL_v23*)
+- Shared build only by default through ./configure
+- Compiler visibility is now used, internal functions not polluting namespace
+- Single Makefile, no recursion, for faster and simpler building
+- Turn on all warnings possible build option, warning fixes
+- and more.
+
+Because of all the new features and the multiple OS, compiler, feature-set
+options that CyaSSL allows, there may be some configuration fixes needed.
+Please send any comments or questions to support@wolfssl.com.
+
+The CyaSSL manual is available at:
+http://www.wolfssl.com/documentation/CyaSSL-Manual.pdf.  For build instructions 
+and comments about the new features please check the manual.
+
+****************** CyaSSL Release 1.9.0 (3/2/2011)
+
+Release 1.9.0 for CyaSSL adds bug fixes, improved TLSv1.2 through testing and
+better hash/sig algo ids, --enable-webServer for the yaSSL embedded web server,
+improper AES key setup detection, user cert verify callback improvements, and
+more.
+
+The CyaSSL manual offering is included in the doc/ directory.  For build
+instructions and comments about the new features please check the manual.
+
+Please send any comments or questions to support@wolfssl.com.
+
+****************** CyaSSL Release 1.8.0 (12/23/2010)
+
+Release 1.8.0 for CyaSSL adds bug fixes, x509 v3 CA signed certificate
+generation, a C standard library abstraction layer, lower memory use, increased
+portability through the os_settings.h file, and the ability to use NTRU cipher
+suites when used in conjunction with an NTRU license and library.
+
+The initial CyaSSL manual offering is included in the doc/ directory.  For
+build instructions and comments about the new features please check the manual.
+
+Please send any comments or questions to support@wolfssl.com.
+
+Happy Holidays.
+ 
+
+********************* CyaSSL Release 1.6.5 (9/9/2010)
+
+Release 1.6.5 for CyaSSL adds bug fixes and x509 v3 self signed certificate
+generation.
+ 
+For general build instructions see doc/Building_CyaSSL.pdf.
+
+To enable certificate generation support add this option to ./configure
+./configure --enable-certgen
+
+An example is included in ctaocrypt/test/test.c and documentation is provided
+in doc/CyaSSL_Extensions_Reference.pdf item 11.
+
+********************** CyaSSL Release 1.6.0 (8/27/2010)
+
+Release 1.6.0 for CyaSSL adds bug fixes, RIPEMD-160, SHA-512, and RSA key
+generation.
+ 
+For general build instructions see doc/Building_CyaSSL.pdf.
+
+To add RIPEMD-160 support add this option to ./configure
+./configure --enable-ripemd
+
+To add SHA-512 support add this option to ./configure
+./configure --enable-sha512
+
+To add RSA key generation support add this option to ./configure
+./configure --enable-keygen
+
+Please see ctaocrypt/test/test.c for examples and usage.
+
+For Windows, RIPEMD-160 and SHA-512 are enabled by default but key generation is
+off by default.  To turn key generation on add the define CYASSL_KEY_GEN to
+CyaSSL.
+
+
+*************   CyaSSL Release 1.5.6 (7/28/2010)
+
+Release 1.5.6 for CyaSSL adds bug fixes, compatibility for our JSSE provider,
+and a fix for GCC builds on some systems.
+ 
+For general build instructions see doc/Building_CyaSSL.pdf.
+
+To add AES-NI support add this option to ./configure
+./configure --enable-aesni
+
+You'll need GCC 4.4.3 or later to make use of the assembly.
+
+**************  CyaSSL Release 1.5.4 (7/7/2010)
+
+Release 1.5.4 for CyaSSL adds bug fixes, support for AES-NI, SHA1 speed 
+improvements from loop unrolling, and support for the Mongoose Web Server.
+ 
+For general build instructions see doc/Building_CyaSSL.pdf.
+
+To add AES-NI support add this option to ./configure
+./configure --enable-aesni
+
+You'll need GCC 4.4.3 or later to make use of the assembly.
+
+***************  CyaSSL Release 1.5.0 (5/11/2010)
+
+Release 1.5.0 for CyaSSL adds bug fixes, GoAhead WebServer support, sniffer
+support, and initial swig interface support.
+
+For general build instructions see doc/Building_CyaSSL.pdf.
+
+To add support for GoAhead WebServer either --enable-opensslExtra or if you
+don't want all the features of opensslExtra you can just define GOAHEAD_WS
+instead.  GOAHEAD_WS can be added to ./configure with CFLAGS=-DGOAHEAD_WS or
+you can define it yourself.
+
+To look at the sniffer support please see the sniffertest app in
+sslSniffer/sslSnifferTest.  Build with --enable-sniffer on *nix or use the
+vcproj files on windows.  You'll need to have pcap installed on *nix and
+WinPcap on windows.
+
+A swig interface file is now located in the swig directory for using Python,
+Java, Perl, and others with CyaSSL.  This is initial support and experimental,
+please send questions or comments to support@wolfssl.com.
+
+When doing load testing with CyaSSL, on the echoserver example say, the client
+machine may run out of tcp ephemeral ports, they will end up in the TIME_WAIT
+queue, and can't be reused by default.  There are generally two ways to fix
+this.  1) Reduce the length sockets remain on the TIME_WAIT queue or 2) Allow
+items on the TIME_WAIT queue to be reused.
+
+
+To reduce the TIME_WAIT length in OS X to 3 seconds (3000 milliseconds)
+
+sudo sysctl -w net.inet.tcp.msl=3000
+
+In Linux
+
+sudo sysctl -w net.ipv4.tcp_tw_reuse=1
+
+allows reuse of sockets in TIME_WAIT
+
+sudo sysctl -w net.ipv4.tcp_tw_recycle=1
+
+works but seems to remove sockets from  TIME_WAIT entirely?
+
+sudo sysctl -w net.ipv4.tcp_fin_timeout=1
+
+doen't control TIME_WAIT, it controls FIN_WAIT(2) contrary to some posts
+
+
+******************** CyaSSL Release 1.4.0 (2/18/2010)
+
+Release 1.3.0 for CyaSSL adds bug fixes, better multi TLS/SSL version support
+through SSLv23_server_method(), and improved documentation in the doc/ folder.
+
+For general build instructions doc/Building_CyaSSL.pdf.
+
+******************** CyaSSL Release 1.3.0 (1/21/2010)
+
+Release 1.3.0 for CyaSSL adds bug fixes, a potential security problem fix,
+better porting support, removal of assert()s, and a complete THREADX port.
+
+For general build instructions see rc1 below.
+
+******************** CyaSSL Release 1.2.0 (11/2/2009)
+
+Release 1.2.0 for CyaSSL adds bug fixes and session negotiation if first use is
+read or write.
+
+For general build instructions see rc1 below.
+
+******************** CyaSSL Release 1.1.0 (9/2/2009)
+
+Release 1.1.0 for CyaSSL adds bug fixes, a check against malicious session
+cache use, support for lighttpd, and TLS 1.2.
+
+To get TLS 1.2 support please use the client and server functions:
+
+SSL_METHOD *TLSv1_2_server_method(void);
+SSL_METHOD *TLSv1_2_client_method(void);
+
+CyaSSL was tested against lighttpd 1.4.23.  To build CyaSSL for use with 
+lighttpd use the following commands from the CyaSSL install dir <CyaSSLDir>:
+
+./configure --disable-shared --enable-opensslExtra --enable-fastmath --without-zlib
+
+make
+make openssl-links
+
+Then to build lighttpd with CyaSSL use the following commands from the
+lighttpd install dir:
+
+./configure --with-openssl --with-openssl-includes=<CyaSSLDir>/include --with-openssl-libs=<CyaSSLDir>/lib LDFLAGS=-lm
+
+make
+
+On some systems you may get a linker error about a duplicate symbol for
+MD5_Init or other MD5 calls.  This seems to be caused by the lighttpd src file
+md5.c, which defines MD5_Init(), and is included in liblightcomp_la-md5.o.
+When liblightcomp is linked with the SSL_LIBs the linker may complain about
+the duplicate symbol.  This can be fixed by editing the lighttpd src file md5.c
+and adding this line to the beginning of the file:
+
+#if 0
+
+and this line to the end of the file
+
+#endif
+
+Then from the lighttpd src dir do a:
+
+make clean
+make
+
+
+If you get link errors about undefined symbols more than likely the actual
+OpenSSL libraries are found by the linker before the CyaSSL openssl-links that
+point to the CyaSSL library, causing the linker confusion.  This can be fixed
+by editing the Makefile in the lighttpd src directory and changing the line:
+
+SSL_LIB = -lssl -lcrypto
+
+to
+
+SSL_LIB = -lcyassl
+
+Then from the lighttpd src dir do a:
+
+make clean
+make
+
+This should remove any confusion the linker may be having with missing symbols.
+
+For any questions or concerns please contact support@wolfssl.com .
+
+For general build instructions see rc1 below.
+
+******************CyaSSL Release 1.0.6 (8/03/2009)
+
+Release 1.0.6 for CyaSSL adds bug fixes, an improved session cache, and faster
+math with a huge code option.
+
+The session cache now defaults to a client mode, also good for embedded servers.
+For servers not under heavy load (less than 200 new sessions per minute), define
+BIG_SESSION_CACHE.  If the server will be under heavy load, define
+HUGE_SESSION_CACHE.
+
+There is now a fasthugemath option for configure.  This enables fastmath plus
+even faster math by greatly increasing the code size of the math library. Use
+the benchmark utility to compare public key operations.
+
+
+For general build instructions see rc1 below.
+
+******************CyaSSL Release 1.0.3 (5/10/2009)
+
+Release 1.0.3 for CyaSSL adds bug fixes and add increased support for OpenSSL
+compatibility when building other applications.
+
+Release 1.0.3 includes an alpha release of DTLS for both client and servers.
+This is only for testing purposes at this time.  Rebroadcast and reordering
+aren't fully implemented at this time but will be for the next release.
+
+For general build instructions see rc1 below.
+
+******************CyaSSL Release 1.0.2 (4/3/2009)
+
+Release 1.0.2 for CyaSSL adds bug fixes for a couple I/O issues.  Some systems
+will send a SIGPIPE on socket recv() at any time and this should be handled by
+the application by turning off SIGPIPE through setsockopt() or returning from
+the handler.
+
+Release 1.0.2 includes an alpha release of DTLS for both client and servers.
+This is only for testing purposes at this time.  Rebroadcast and reordering
+aren't fully implemented at this time but will be for the next release.
+
+For general build instructions see rc1 below.
+
+*****************CyaSSL Release Candidate 3 rc3-1.0.0 (2/25/2009)
+
+
+Release Candidate 3 for CyaSSL 1.0.0 adds bug fixes and adds a project file for
+iPhone development with Xcode.  cyassl-iphone.xcodeproj is located in the root
+directory.  This release also includes a fix for supporting other
+implementations that bundle multiple messages at the record layer, this was
+lost when cyassl i/o was re-implemented but is now fixed.
+
+For general build instructions see rc1 below.
+
+*****************CyaSSL Release Candidate 2 rc2-1.0.0 (1/21/2009)
+
+
+Release Candidate 2 for CyaSSL 1.0.0 adds bug fixes and adds two new stream
+ciphers along with their respective cipher suites.  CyaSSL adds support for
+HC-128 and RABBIT stream ciphers.  The new suites are:
+
+TLS_RSA_WITH_HC_128_SHA
+TLS_RSA_WITH_RABBIT_SHA
+
+And the corresponding cipher names are
+
+HC128-SHA
+RABBIT-SHA
+
+CyaSSL also adds support for building with devkitPro for PPC by changing the
+library proper to use libogc.  The examples haven't been changed yet but if
+there's interest they can be.  Here's an example ./configure to build CyaSSL
+for devkitPro:
+
+./configure --disable-shared CC=/pathTo/devkitpro/devkitPPC/bin/powerpc-gekko-gcc --host=ppc --without-zlib --enable-singleThreaded RANLIB=/pathTo/devkitpro/devkitPPC/bin/powerpc-gekko-ranlib CFLAGS="-DDEVKITPRO -DGEKKO"
+
+For linking purposes you'll need
+
+LDFLAGS="-g -mrvl -mcpu=750 -meabi -mhard-float -Wl,-Map,$(notdir $@).map"
+
+For general build instructions see rc1 below.
+
+
+********************CyaSSL Release Candidate 1 rc1-1.0.0 (12/17/2008)
+
+
+Release Candidate 1 for CyaSSL 1.0.0 contains major internal changes.  Several
+areas have optimization improvements, less dynamic memory use, and the I/O
+strategy has been refactored to allow alternate I/O handling or Library use.
+Many thanks to Thierry Fournier for providing these ideas and most of the work.
+
+Because of these changes, this release is only a candidate since some problems
+are probably inevitable on some platform with some I/O use.  Please report any
+problems and we'll try to resolve them as soon as possible.  You can contact us
+at support@wolfssl.com or todd@wolfssl.com.
+
+Using TomsFastMath by passing --enable-fastmath to ./configure now uses assembly
+on some platforms.  This is new so please report any problems as every compiler,
+mode, OS combination hasn't been tested.  On ia32 all of the registers need to
+be available so be sure to pass these options to CFLAGS:
+
+CFLAGS="-O3 -fomit-frame-pointer"
+
+OS X will also need -mdynamic-no-pic added to CFLAGS
+
+Also if you're building in shared mode for ia32 you'll need to pass options to
+LDFLAGS as well on OS X:
+
+LDFLAGS=-Wl,-read_only_relocs,warning
+
+This gives warnings for some symbols but seems to work.
+
+
+--To build on Linux, Solaris, *BSD, Mac OS X, or Cygwin:
+
+    ./configure
+    make
+
+    from the ./testsuite/ directory run ./testsuite 
+
+to make a debug build:
+
+    ./configure --enable-debug --disable-shared
+    make
+
+
+
+--To build on Win32
+
+Choose (Re)Build All from the project workspace
+
+Run the testsuite program
+
+
+
+
+
+*************************CyaSSL version 0.9.9 (7/25/2008) 
+
+This release of CyaSSL adds bug fixes, Pre-Shared Keys, over-rideable memory
+handling, and optionally TomsFastMath.  Thanks to Mois辿s Guimar達es for the
+work on TomsFastMath.
+
+To optionally use TomsFastMath pass --enable-fastmath to ./configure
+Or define USE_FAST_MATH in each project from CyaSSL for MSVC.
+
+Please use the benchmark routine before and after to see the performance
+difference, on some platforms the gains will be little but RSA encryption
+always seems to be faster.  On x86-64 machines with GCC the normal math library
+may outperform the fast one when using CFLAGS=-m64 because TomsFastMath can't
+yet use -m64 because of GCCs inability to do 128bit division.
+
+     **** UPDATE GCC 4.2.1 can now do 128bit division ***
+
+See notes below (0.2.0) for complete build instructions.
+
+
+****************CyaSSL version 0.9.8 (5/7/2008) 
+
+This release of CyaSSL adds bug fixes, client side Diffie-Hellman, and better
+socket handling.
+
+See notes below (0.2.0) for complete build instructions.
+
+
+****************CyaSSL version 0.9.6 (1/31/2008) 
+
+This release of CyaSSL adds bug fixes, increased session management, and a fix
+for gnutls.
+
+See notes below (0.2.0) for complete build instructions.
+
+
+****************CyaSSL version 0.9.0 (10/15/2007) 
+
+This release of CyaSSL adds bug fixes, MSVC 2005 support, GCC 4.2 support, 
+IPV6 support and test, and new test certificates.
+
+See notes below (0.2.0) for complete build instructions.
+
+
+****************CyaSSL version 0.8.0 (1/10/2007) 
+
+This release of CyaSSL adds increased socket support, for non-blocking writes,
+connects, and interrupted system calls.
+
+See notes below (0.2.0) for complete build instructions.
+
+
+****************CyaSSL version 0.6.3 (10/30/2006) 
+
+This release of CyaSSL adds debug logging to stderr to aid in the debugging of
+CyaSSL on systems that may not provide the best support.
+
+If CyaSSL is built with debugging support then you need to call
+CyaSSL_Debugging_ON() to turn logging on.
+
+On Unix use ./configure --enable-debug
+
+On Windows define DEBUG_CYASSL when building CyaSSL
+
+
+To turn logging back off call CyaSSL_Debugging_OFF()
+
+See notes below (0.2.0) for complete build instructions.
+
+
+*****************CyaSSL version 0.6.2 (10/29/2006) 
+
+This release of CyaSSL adds TLS 1.1.
+
+Note that CyaSSL has certificate verification on by default, unlike OpenSSL.
+To emulate OpenSSL behavior, you must call SSL_CTX_set_verify() with
+SSL_VERIFY_NONE.  In order to have full security you should never do this, 
+provide CyaSSL with the proper certificates to eliminate impostors and call
+CyaSSL_check_domain_name() to prevent man in the middle attacks.
+
+See notes below (0.2.0) for build instructions.
+
+*****************CyaSSL version 0.6.0 (10/25/2006) 
+
+This release of CyaSSL adds more SSL functions, better autoconf, nonblocking
+I/O for accept, connect, and read.  There is now an --enable-small configure
+option that turns off TLS, AES, DES3, HMAC, and ERROR_STRINGS, see configure.in
+for the defines.  Note that TLS requires HMAC and AES requires TLS.
+
+See notes below (0.2.0) for build instructions.
+
+
+*****************CyaSSL version 0.5.5 (09/27/2006) 
+
+This mini release of CyaSSL adds better input processing through buffered input
+and big message support.  Added SSL_pending() and some sanity checks on user
+settings.
+
+See notes below (0.2.0) for build instructions.
+
+
+*****************CyaSSL version 0.5.0 (03/27/2006) 
+
+This release of CyaSSL adds AES support and minor bug fixes. 
+
+See notes below (0.2.0) for build instructions.
+
+
+*****************CyaSSL version 0.4.0 (03/15/2006)
+
+This release of CyaSSL adds TLSv1 client/server support and libtool. 
+
+See notes below for build instructions.
+
+
+*****************CyaSSL version 0.3.0 (02/26/2006)
+
+This release of CyaSSL adds SSLv3 server support and session resumption. 
+
+See notes below for build instructions.
+
+
+*****************CyaSSL version 0.2.0 (02/19/2006)
+
+
+This is the first release of CyaSSL and its crypt brother, CTaoCrypt.  CyaSSL
+is written in ANSI C with the idea of a small code size, footprint, and memory
+usage in mind.  CTaoCrypt can be as small as 32K, and the current client
+version of CyaSSL can be as small as 12K.
+
+
+The first release of CTaoCrypt supports MD5, SHA-1, 3DES, ARC4, Big Integer
+Support, RSA, ASN parsing, and basic x509 (en/de)coding.
+
+The first release of CyaSSL supports normal client RSA mode SSLv3 connections
+with support for SHA-1 and MD5 digests.  Ciphers include 3DES and RC4.
+
+
+--To build on Linux, Solaris, *BSD, Mac OS X, or Cygwin:
+
+    ./configure
+    make
+
+    from the ./testsuite/ directory run ./testsuite 
+
+to make a debug build:
+
+    ./configure --enable-debug --disable-shared
+    make
+
+
+
+--To build on Win32
+
+Choose (Re)Build All from the project workspace
+
+Run the testsuite program
+
+
+
+*** The next release of CyaSSL will support a server and more OpenSSL
+compatibility functions.
+
+
+Please send questions or comments to todd@wolfssl.com
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/src/crl.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/src/crl.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/src/crl.c	(revision 164)
@@ -0,0 +1,810 @@
+/* crl.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+  /* Name change compatibility layer no longer needs included here */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLFCRYPT_ONLY
+#ifdef HAVE_CRL
+
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+
+#ifndef NO_FILESYSTEM
+    #include <dirent.h>
+    #include <sys/stat.h>
+#endif
+
+#include <string.h>
+
+#ifdef HAVE_CRL_MONITOR
+    static int StopMonitor(int mfd);
+#endif
+
+
+/* Initialze CRL members */
+int InitCRL(WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_ENTER("InitCRL");
+
+    crl->cm = cm;
+    crl->crlList = NULL;
+    crl->monitors[0].path = NULL;
+    crl->monitors[1].path = NULL;
+#ifdef HAVE_CRL_MONITOR
+    crl->tid =  0;
+    crl->mfd = -1;   /* mfd for bsd is kqueue fd, eventfd for linux */
+#endif
+    if (InitMutex(&crl->crlLock) != 0)
+        return BAD_MUTEX_E; 
+
+    return 0;
+}
+
+
+/* Initialze CRL Entry */
+static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl)
+{
+    WOLFSSL_ENTER("InitCRL_Entry");
+
+    XMEMCPY(crle->issuerHash, dcrl->issuerHash, CRL_DIGEST_SIZE);
+    /* XMEMCPY(crle->crlHash, dcrl->crlHash, CRL_DIGEST_SIZE);
+     *   copy the hash here if needed for optimized comparisons */
+    XMEMCPY(crle->lastDate, dcrl->lastDate, MAX_DATE_SIZE);
+    XMEMCPY(crle->nextDate, dcrl->nextDate, MAX_DATE_SIZE);
+    crle->lastDateFormat = dcrl->lastDateFormat;
+    crle->nextDateFormat = dcrl->nextDateFormat;
+
+    crle->certs = dcrl->certs;   /* take ownsership */
+    dcrl->certs = NULL;
+    crle->totalCerts = dcrl->totalCerts;
+
+    return 0;
+}
+
+
+/* Free all CRL Entry resources */
+static void FreeCRL_Entry(CRL_Entry* crle)
+{
+    RevokedCert* tmp = crle->certs; 
+
+    WOLFSSL_ENTER("FreeCRL_Entry");
+
+    while(tmp) {
+        RevokedCert* next = tmp->next;
+        XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED);
+        tmp = next;
+    }
+}
+
+
+
+/* Free all CRL resources */
+void FreeCRL(WOLFSSL_CRL* crl, int dynamic)
+{
+    CRL_Entry* tmp = crl->crlList;
+
+    WOLFSSL_ENTER("FreeCRL");
+
+    if (crl->monitors[0].path)
+        XFREE(crl->monitors[0].path, NULL, DYNAMIC_TYPE_CRL_MONITOR);
+
+    if (crl->monitors[1].path)
+        XFREE(crl->monitors[1].path, NULL, DYNAMIC_TYPE_CRL_MONITOR);
+
+    while(tmp) {
+        CRL_Entry* next = tmp->next;
+        FreeCRL_Entry(tmp);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_CRL_ENTRY);
+        tmp = next;
+    }	
+
+#ifdef HAVE_CRL_MONITOR
+    if (crl->tid != 0) {
+        WOLFSSL_MSG("stopping monitor thread");
+        if (StopMonitor(crl->mfd) == 0)
+            pthread_join(crl->tid, NULL);
+        else {
+            WOLFSSL_MSG("stop monitor failed, cancel instead");
+            pthread_cancel(crl->tid);
+        }
+    }
+#endif
+    FreeMutex(&crl->crlLock);
+    if (dynamic)   /* free self */
+        XFREE(crl, NULL, DYNAMIC_TYPE_CRL);
+}
+
+
+/* Is the cert ok with CRL, return 0 on success */
+int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert)
+{
+    CRL_Entry* crle;
+    int        foundEntry = 0;
+    int        ret = 0;
+
+    WOLFSSL_ENTER("CheckCertCRL");
+
+    if (LockMutex(&crl->crlLock) != 0) {
+        WOLFSSL_MSG("LockMutex failed");
+        return BAD_MUTEX_E;
+    }
+
+    crle = crl->crlList;
+
+    while (crle) {
+        if (XMEMCMP(crle->issuerHash, cert->issuerHash, CRL_DIGEST_SIZE) == 0) {
+            int doNextDate = 1;
+
+            WOLFSSL_MSG("Found CRL Entry on list");
+            WOLFSSL_MSG("Checking next date validity");
+
+            #ifdef WOLFSSL_NO_CRL_NEXT_DATE
+                if (crle->nextDateFormat == ASN_OTHER_TYPE)
+                    doNextDate = 0;  /* skip */
+            #endif
+
+            if (doNextDate && !ValidateDate(crle->nextDate,
+                                            crle->nextDateFormat, AFTER)) {
+                WOLFSSL_MSG("CRL next date is no longer valid");
+                ret = ASN_AFTER_DATE_E;
+            }
+            else
+                foundEntry = 1;
+            break;
+        }
+        crle = crle->next;
+    }
+
+    if (foundEntry) {
+        RevokedCert* rc = crle->certs;
+
+        while (rc) {
+            if (XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) {
+                WOLFSSL_MSG("Cert revoked");
+                ret = CRL_CERT_REVOKED;
+                break;
+            }
+            rc = rc->next;	
+        }
+    }
+
+    UnLockMutex(&crl->crlLock);
+
+    if (foundEntry == 0) {
+        WOLFSSL_MSG("Couldn't find CRL for status check");
+        ret = CRL_MISSING;
+        if (crl->cm->cbMissingCRL) {
+            char url[256];
+
+            WOLFSSL_MSG("Issuing missing CRL callback");
+            url[0] = '\0';
+            if (cert->extCrlInfoSz < (int)sizeof(url) -1 ) {
+                XMEMCPY(url, cert->extCrlInfo, cert->extCrlInfoSz);
+                url[cert->extCrlInfoSz] = '\0';
+            }
+            else  {
+                WOLFSSL_MSG("CRL url too long");
+            }
+            crl->cm->cbMissingCRL(url);
+        }
+    }
+
+
+    return ret;	
+}
+
+
+/* Add Decoded CRL, 0 on success */
+static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl)
+{
+    CRL_Entry* crle;
+
+    WOLFSSL_ENTER("AddCRL");
+
+    crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), NULL, DYNAMIC_TYPE_CRL_ENTRY);
+    if (crle == NULL) {
+        WOLFSSL_MSG("alloc CRL Entry failed");
+        return -1;
+    }
+
+    if (InitCRL_Entry(crle, dcrl) < 0) {
+        WOLFSSL_MSG("Init CRL Entry failed");
+        XFREE(crle, NULL, DYNAMIC_TYPE_CRL_ENTRY);
+        return -1;
+    }
+
+    if (LockMutex(&crl->crlLock) != 0) {
+        WOLFSSL_MSG("LockMutex failed");
+        FreeCRL_Entry(crle);
+        XFREE(crle, NULL, DYNAMIC_TYPE_CRL_ENTRY);
+        return BAD_MUTEX_E;
+    }
+    crle->next = crl->crlList;
+    crl->crlList = crle;
+    UnLockMutex(&crl->crlLock);
+
+    return 0;
+}
+
+
+/* Load CRL File of type, SSL_SUCCESS on ok */
+int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type)
+{
+    int          ret = SSL_SUCCESS;
+    const byte*  myBuffer = buff;    /* if DER ok, otherwise switch */
+    buffer       der;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCRL*  dcrl;
+#else
+    DecodedCRL   dcrl[1];
+#endif
+
+    der.buffer = NULL;
+
+    WOLFSSL_ENTER("BufferLoadCRL");
+
+    if (crl == NULL || buff == NULL || sz == 0)
+        return BAD_FUNC_ARG;
+
+    if (type == SSL_FILETYPE_PEM) {
+        int eccKey = 0;   /* not used */
+        EncryptedInfo info;
+        info.ctx = NULL;
+
+        ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, &info, &eccKey);
+        if (ret == 0) {
+            myBuffer = der.buffer;
+            sz = der.length;
+        }
+        else {
+            WOLFSSL_MSG("Pem to Der failed");
+            return -1;
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    dcrl = (DecodedCRL*)XMALLOC(sizeof(DecodedCRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (dcrl == NULL) {
+        if (der.buffer)
+            XFREE(der.buffer, NULL, DYNAMIC_TYPE_CRL);
+
+        return MEMORY_E;
+    }
+#endif
+
+    InitDecodedCRL(dcrl);
+    ret = ParseCRL(dcrl, myBuffer, (word32)sz, crl->cm);
+    if (ret != 0) {
+        WOLFSSL_MSG("ParseCRL error");
+    }
+    else {
+        ret = AddCRL(crl, dcrl);
+        if (ret != 0) {
+            WOLFSSL_MSG("AddCRL error");
+        }
+    }
+
+    FreeDecodedCRL(dcrl);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (der.buffer)
+        XFREE(der.buffer, NULL, DYNAMIC_TYPE_CRL);
+
+    return ret ? ret : SSL_SUCCESS; /* convert 0 to SSL_SUCCESS */
+}
+
+
+#ifdef HAVE_CRL_MONITOR
+
+
+/* read in new CRL entries and save new list */
+static int SwapLists(WOLFSSL_CRL* crl)
+{
+    int        ret;
+    CRL_Entry* newList;
+#ifdef WOLFSSL_SMALL_STACK
+    WOLFSSL_CRL* tmp;    
+#else
+    WOLFSSL_CRL tmp[1];
+#endif
+    
+#ifdef WOLFSSL_SMALL_STACK
+    tmp = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmp == NULL)
+        return MEMORY_E;
+#endif   
+
+    if (InitCRL(tmp, crl->cm) < 0) {
+        WOLFSSL_MSG("Init tmp CRL failed");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return -1;
+    }
+
+    if (crl->monitors[0].path) {
+        ret = LoadCRL(tmp, crl->monitors[0].path, SSL_FILETYPE_PEM, 0);
+        if (ret != SSL_SUCCESS) {
+            WOLFSSL_MSG("PEM LoadCRL on dir change failed");
+            FreeCRL(tmp, 0);
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return -1;
+        }
+    }
+
+    if (crl->monitors[1].path) {
+        ret = LoadCRL(tmp, crl->monitors[1].path, SSL_FILETYPE_ASN1, 0);
+        if (ret != SSL_SUCCESS) {
+            WOLFSSL_MSG("DER LoadCRL on dir change failed");
+            FreeCRL(tmp, 0);
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return -1;
+        }
+    }
+
+    if (LockMutex(&crl->crlLock) != 0) {
+        WOLFSSL_MSG("LockMutex failed");
+        FreeCRL(tmp, 0);
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return -1;
+    }
+
+    newList = tmp->crlList;
+
+    /* swap lists */
+    tmp->crlList  = crl->crlList;
+    crl->crlList = newList;
+
+    UnLockMutex(&crl->crlLock);
+
+    FreeCRL(tmp, 0);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return 0;
+}
+
+
+#if (defined(__MACH__) || defined(__FreeBSD__))
+
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifdef __MACH__
+    #define XEVENT_MODE O_EVTONLY
+#elif defined(__FreeBSD__)
+    #define XEVENT_MODE EVFILT_VNODE
+#endif
+
+
+/* we need a unique kqueue user filter fd for crl in case user is doing custom
+ * events too */
+#ifndef CRL_CUSTOM_FD
+    #define CRL_CUSTOM_FD 123456
+#endif
+
+
+/* shutdown monitor thread, 0 on success */
+static int StopMonitor(int mfd)
+{
+    struct kevent change;
+
+    /* trigger custom shutdown */
+    EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
+    if (kevent(mfd, &change, 1, NULL, 0, NULL) < 0) {
+        WOLFSSL_MSG("kevent trigger customer event failed");
+        return -1;
+    }
+
+    return 0;
+}
+
+
+/* OS X  monitoring */
+static void* DoMonitor(void* arg)
+{
+    int fPEM, fDER;
+    struct kevent change;
+
+    WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg;
+
+    WOLFSSL_ENTER("DoMonitor");
+
+    crl->mfd = kqueue();
+    if (crl->mfd == -1) {
+        WOLFSSL_MSG("kqueue failed");
+        return NULL;
+    }
+
+    /* listen for custom shutdown event */
+    EV_SET(&change, CRL_CUSTOM_FD, EVFILT_USER, EV_ADD, 0, 0, NULL);
+    if (kevent(crl->mfd, &change, 1, NULL, 0, NULL) < 0) {
+        WOLFSSL_MSG("kevent monitor customer event failed");
+        close(crl->mfd);
+        return NULL;
+    }
+
+    fPEM = -1;
+    fDER = -1;
+
+    if (crl->monitors[0].path) {
+        fPEM = open(crl->monitors[0].path, XEVENT_MODE);
+        if (fPEM == -1) {
+            WOLFSSL_MSG("PEM event dir open failed");
+            close(crl->mfd);
+            return NULL;
+        }
+    }
+
+    if (crl->monitors[1].path) {
+        fDER = open(crl->monitors[1].path, XEVENT_MODE);
+        if (fDER == -1) {
+            WOLFSSL_MSG("DER event dir open failed");
+            close(crl->mfd);
+            return NULL;
+        }
+    }
+
+    if (fPEM != -1)
+        EV_SET(&change, fPEM, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
+                NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
+
+    if (fDER != -1)
+        EV_SET(&change, fDER, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
+                NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
+
+    for (;;) {
+        struct kevent event;
+        int           numEvents = kevent(crl->mfd, &change, 1, &event, 1, NULL);
+       
+        WOLFSSL_MSG("Got kevent");
+
+        if (numEvents == -1) {
+            WOLFSSL_MSG("kevent problem, continue");
+            continue;
+        }
+
+        if (event.filter == EVFILT_USER) {
+            WOLFSSL_MSG("Got user shutdown event, breaking out");
+            break;
+        }
+
+        if (SwapLists(crl) < 0) {
+            WOLFSSL_MSG("SwapLists problem, continue");
+        }
+    }
+
+    if (fPEM != -1)
+        close(fPEM);
+    if (fDER != -1)
+        close(fDER);
+
+    close(crl->mfd);
+
+    return NULL;
+}
+
+
+#elif defined(__linux__)
+
+#include <sys/types.h>
+#include <sys/inotify.h>
+#include <sys/eventfd.h>
+#include <unistd.h>
+
+
+#ifndef max
+    static INLINE int max(int a, int b)
+    {
+        return a > b ? a : b;
+    }
+#endif /* max */
+
+
+/* shutdown monitor thread, 0 on success */
+static int StopMonitor(int mfd)
+{
+    word64 w64 = 1;
+
+    /* write to our custom event */
+    if (write(mfd, &w64, sizeof(w64)) < 0) {
+        WOLFSSL_MSG("StopMonitor write failed");
+        return -1;
+    }
+
+    return 0;
+}
+
+
+/* linux monitoring */
+static void* DoMonitor(void* arg)
+{
+    int         notifyFd;
+    int         wd  = -1;
+    WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg;
+#ifdef WOLFSSL_SMALL_STACK
+    char*       buff;
+#else
+    char        buff[8192];
+#endif
+
+    WOLFSSL_ENTER("DoMonitor");
+
+    crl->mfd = eventfd(0, 0);  /* our custom shutdown event */
+    if (crl->mfd < 0) {
+        WOLFSSL_MSG("eventfd failed");
+        return NULL;
+    }
+
+    notifyFd = inotify_init();
+    if (notifyFd < 0) {
+        WOLFSSL_MSG("inotify failed");
+        close(crl->mfd);
+        return NULL;
+    }
+
+    if (crl->monitors[0].path) {
+        wd = inotify_add_watch(notifyFd, crl->monitors[0].path, IN_CLOSE_WRITE |
+                                                                IN_DELETE);
+        if (wd < 0) {
+            WOLFSSL_MSG("PEM notify add watch failed");
+            close(crl->mfd);
+            close(notifyFd);
+            return NULL;
+        }
+    }
+
+    if (crl->monitors[1].path) {
+        wd = inotify_add_watch(notifyFd, crl->monitors[1].path, IN_CLOSE_WRITE |
+                                                                IN_DELETE);
+        if (wd < 0) {
+            WOLFSSL_MSG("DER notify add watch failed");
+            close(crl->mfd);
+            close(notifyFd);
+            return NULL;
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    buff = (char*)XMALLOC(8192, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buff == NULL)
+        return NULL;
+#endif
+
+    for (;;) {
+        fd_set readfds;
+        int    result;
+        int    length;
+
+        FD_ZERO(&readfds);
+        FD_SET(notifyFd, &readfds);
+        FD_SET(crl->mfd, &readfds);
+
+        result = select(max(notifyFd, crl->mfd) + 1, &readfds, NULL, NULL,NULL);
+       
+        WOLFSSL_MSG("Got notify event");
+
+        if (result < 0) {
+            WOLFSSL_MSG("select problem, continue");
+            continue;
+        }
+
+        if (FD_ISSET(crl->mfd, &readfds)) {
+            WOLFSSL_MSG("got custom shutdown event, breaking out");
+            break;
+        }
+
+        length = read(notifyFd, buff, 8192);
+        if (length < 0) {
+            WOLFSSL_MSG("notify read problem, continue");
+            continue;
+        } 
+
+        if (SwapLists(crl) < 0) {
+            WOLFSSL_MSG("SwapLists problem, continue");
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (wd > 0)
+        inotify_rm_watch(notifyFd, wd);
+    close(crl->mfd);
+    close(notifyFd);
+
+    return NULL;
+}
+
+
+#else
+
+#error "CRL monitor only currently supported on linux or mach"
+
+#endif /* MACH or linux */
+
+
+/* Start Monitoring the CRL path(s) in a thread */
+static int StartMonitorCRL(WOLFSSL_CRL* crl)
+{
+    pthread_attr_t attr;
+
+    WOLFSSL_ENTER("StartMonitorCRL");
+
+    if (crl == NULL) 
+        return BAD_FUNC_ARG;
+
+    if (crl->tid != 0) {
+        WOLFSSL_MSG("Monitor thread already running");
+        return MONITOR_RUNNING_E;
+    }
+
+    pthread_attr_init(&attr);
+
+    if (pthread_create(&crl->tid, &attr, DoMonitor, crl) != 0) {
+        WOLFSSL_MSG("Thread creation error");
+        return THREAD_CREATE_E;
+    }
+
+    return SSL_SUCCESS;
+}
+
+
+#else /* HAVE_CRL_MONITOR */
+
+#ifndef NO_FILESYSTEM
+
+static int StartMonitorCRL(WOLFSSL_CRL* crl)
+{
+    (void)crl;
+
+    WOLFSSL_ENTER("StartMonitorCRL");
+    WOLFSSL_MSG("Not compiled in");
+
+    return NOT_COMPILED_IN;
+}
+
+#endif /* NO_FILESYSTEM */
+
+#endif  /* HAVE_CRL_MONITOR */
+
+#ifndef NO_FILESYSTEM
+
+/* Load CRL path files of type, SSL_SUCCESS on ok */ 
+int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor)
+{
+    struct dirent* entry;
+    DIR            dir;
+    int            ret = SSL_SUCCESS;
+#ifdef WOLFSSL_SMALL_STACK
+    char*          name;
+#else
+    char           name[MAX_FILENAME_SZ];
+#endif
+
+    WOLFSSL_ENTER("LoadCRL");
+    if (crl == NULL)
+        return BAD_FUNC_ARG;
+
+    ret = f_opendir(&dir, path);
+    if (ret != FR_OK) {
+        WOLFSSL_MSG("opendir path crl load failed");
+        return BAD_PATH_ERROR;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (name == NULL)
+        return MEMORY_E;
+#endif
+
+    while ( (entry = f_readdir(&dir)) != NULL) {
+        struct stat s;
+
+        XMEMSET(name, 0, MAX_FILENAME_SZ);
+        XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
+        XSTRNCAT(name, "/", 1);
+        XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
+
+        if (stat(name, &s) != 0) {
+            WOLFSSL_MSG("stat on name failed");
+            continue;
+        }
+        if (s.st_mode & S_IFREG) {
+
+            if (type == SSL_FILETYPE_PEM) {
+                if (strstr(entry->d_name, ".pem") == NULL) {
+                    WOLFSSL_MSG("not .pem file, skipping");
+                    continue;
+                }
+            }
+            else {
+                if (strstr(entry->d_name, ".der") == NULL &&
+                    strstr(entry->d_name, ".crl") == NULL) {
+
+                    WOLFSSL_MSG("not .der or .crl file, skipping");
+                    continue;
+                }
+            }
+
+            if (ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl)
+                                                               != SSL_SUCCESS) {
+                WOLFSSL_MSG("CRL file load failed, continuing");
+            }
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (monitor & WOLFSSL_CRL_MONITOR) {
+        WOLFSSL_MSG("monitor path requested");
+
+        if (type == SSL_FILETYPE_PEM) {
+            crl->monitors[0].path = strdup(path);
+            crl->monitors[0].type = SSL_FILETYPE_PEM;
+            if (crl->monitors[0].path == NULL)
+                ret = MEMORY_E;
+        } else {
+            crl->monitors[1].path = strdup(path);
+            crl->monitors[1].type = SSL_FILETYPE_ASN1;
+            if (crl->monitors[1].path == NULL)
+                ret = MEMORY_E;
+        }
+      
+        if (monitor & WOLFSSL_CRL_START_MON) {
+            WOLFSSL_MSG("start monitoring requested");
+    
+            ret = StartMonitorCRL(crl);
+       } 
+    }
+    
+    f_closedir(&dir);
+
+    return ret;
+}
+
+#endif /* NO_FILESYSTEM */
+
+#endif /* HAVE_CRL */
+#endif /* !WOLFCRYPT_ONLY */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/src/internal.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/src/internal.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/src/internal.c	(revision 164)
@@ -0,0 +1,15832 @@
+/* internal.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLFCRYPT_ONLY
+
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+#include <wolfssl/wolfcrypt/asn.h>
+#include <wolfssl/wolfcrypt/dh.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+#ifdef HAVE_LIBZ
+    #include "zlib.h"
+#endif
+
+#ifdef HAVE_NTRU
+    #include "libntruencrypt/ntru_crypto.h"
+#endif
+
+#if defined(DEBUG_WOLFSSL) || defined(SHOW_SECRETS) || defined(CHACHA_AEAD_TEST)
+    #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+        #if MQX_USE_IO_OLD
+            #include <fio.h>
+        #else
+            #include <nio.h>
+        #endif
+    #else
+        #include <stdio.h>
+    #endif
+#endif
+
+#ifdef __sun
+    #include <sys/filio.h>
+#endif
+
+#ifndef TRUE
+    #define TRUE  1
+#endif
+#ifndef FALSE
+    #define FALSE 0
+#endif
+
+#ifdef _MSC_VER
+    /* disable for while(0) cases at the .c level for now */
+    #pragma warning(disable:4127)
+#endif
+
+#if defined(WOLFSSL_CALLBACKS) && !defined(LARGE_STATIC_BUFFERS)
+    #error \
+WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
+#endif
+
+#if defined(HAVE_SECURE_RENEGOTIATION) && defined(HAVE_RENEGOTIATION_INDICATION)
+    #error Cannot use both secure-renegotiation and renegotiation-indication
+#endif
+
+static int BuildMessage(WOLFSSL* ssl, byte* output, int outSz,
+                        const byte* input, int inSz, int type);
+
+#ifndef NO_WOLFSSL_CLIENT
+    static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input, word32*,
+                                                                        word32);
+    static int DoServerHello(WOLFSSL* ssl, const byte* input, word32*, word32);
+    static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, word32*,
+                                                                        word32);
+    #ifndef NO_CERTS
+        static int DoCertificateRequest(WOLFSSL* ssl, const byte* input, word32*,
+                                                                        word32);
+    #endif
+    #ifdef HAVE_SESSION_TICKET
+        static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32*,
+                                                                        word32);
+    #endif
+#endif
+
+
+#ifndef NO_WOLFSSL_SERVER
+    static int DoClientHello(WOLFSSL* ssl, const byte* input, word32*, word32);
+    static int DoClientKeyExchange(WOLFSSL* ssl, byte* input, word32*, word32);
+    #if !defined(NO_RSA) || defined(HAVE_ECC)
+        static int DoCertificateVerify(WOLFSSL* ssl, byte*, word32*, word32);
+    #endif
+    #ifdef HAVE_STUNNEL
+        static int SNI_Callback(WOLFSSL* ssl);
+    #endif
+    #ifdef WOLFSSL_DTLS
+        static int SendHelloVerifyRequest(WOLFSSL*, const byte*, byte);
+    #endif /* WOLFSSL_DTLS */
+#endif
+
+
+#ifdef WOLFSSL_DTLS
+    static INLINE int DtlsCheckWindow(DtlsState* state);
+    static INLINE int DtlsUpdateWindow(DtlsState* state);
+#endif
+
+
+typedef enum {
+    doProcessInit = 0,
+#ifndef NO_WOLFSSL_SERVER
+    runProcessOldClientHello,
+#endif
+    getRecordLayerHeader,
+    getData,
+    runProcessingOneMessage
+} processReply;
+
+#ifndef NO_OLD_TLS
+static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
+                    int content, int verify);
+
+#endif
+
+#ifndef NO_CERTS
+static int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes);
+#endif
+
+static void PickHashSigAlgo(WOLFSSL* ssl,
+                                const byte* hashSigAlgo, word32 hashSigAlgoSz);
+
+#ifdef HAVE_QSH
+    int QSH_Init(WOLFSSL* ssl);
+#endif
+
+#ifdef min
+#define WOLFSSL_HAVE_MIN
+#endif
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+
+#endif /* WOLFSSL_HAVE_MIN */
+
+
+int IsTLS(const WOLFSSL* ssl)
+{
+    if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_MINOR)
+        return 1;
+
+    return 0;
+}
+
+
+int IsAtLeastTLSv1_2(const WOLFSSL* ssl)
+{
+    if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_2_MINOR)
+        return 1;
+    if (ssl->version.major == DTLS_MAJOR && ssl->version.minor <= DTLSv1_2_MINOR)
+        return 1;
+
+    return 0;
+}
+
+
+#ifdef HAVE_QSH
+/* free all structs that where used with QSH */
+static int QSH_FreeAll(WOLFSSL* ssl)
+{
+    QSHKey* key        = ssl->QSH_Key;
+    QSHKey* preKey     = NULL;
+    QSHSecret* secret  = ssl->QSH_secret;
+    QSHScheme* list    = NULL;
+    QSHScheme* preList = NULL;
+
+    /* free elements in struct */
+    while (key) {
+        preKey = key;
+        if (key->pri.buffer)
+            XFREE(key->pri.buffer, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
+        if (key->pub.buffer)
+            XFREE(key->pub.buffer, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
+        key = (QSHKey*)key->next;
+
+        /* free struct */
+        XFREE(preKey, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
+    }
+    key = NULL;
+
+
+    /* free all of peers QSH keys */
+    key = ssl->peerQSHKey;
+    while (key) {
+        preKey = key;
+        if (key->pri.buffer)
+            XFREE(key->pri.buffer, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
+        if (key->pub.buffer)
+            XFREE(key->pub.buffer, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
+        key = (QSHKey*)key->next;
+
+        /* free struct */
+        XFREE(preKey, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
+    }
+    key = NULL;
+
+    /* free secret information */
+    if (secret) {
+        /* free up the QSHScheme list in QSHSecret */
+        if (secret->list)
+            list = secret->list;
+        while (list) {
+            preList = list;
+            if (list->PK)
+                XFREE(list->PK, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
+            list = (QSHScheme*)list->next;
+            XFREE(preList, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
+        }
+
+        /* free secret buffers */
+        if (secret->SerSi) {
+            if (secret->SerSi->buffer)
+                XFREE(secret->SerSi->buffer, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
+            XFREE(secret->SerSi, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
+        }
+        if (secret->CliSi) {
+            if (secret->CliSi->buffer)
+                XFREE(secret->CliSi->buffer, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
+            XFREE(secret->CliSi, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
+        }
+    }
+    XFREE(secret, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
+    secret = NULL;
+
+    return 0;
+}
+#endif
+
+
+#ifdef HAVE_NTRU
+static WC_RNG* rng;
+static wolfSSL_Mutex* rngMutex;
+
+static word32 GetEntropy(unsigned char* out, word32 num_bytes)
+{
+    int ret = 0;
+
+    if (rng == NULL) {
+        if ((rng = XMALLOC(sizeof(WC_RNG), 0, DYNAMIC_TYPE_TLSX)) == NULL)
+            return DRBG_OUT_OF_MEMORY;
+        wc_InitRng(rng);
+    }
+
+    if (rngMutex == NULL) {
+        if ((rngMutex = XMALLOC(sizeof(wolfSSL_Mutex), 0,
+                        DYNAMIC_TYPE_TLSX)) == NULL)
+            return DRBG_OUT_OF_MEMORY;
+        InitMutex(rngMutex);
+    }
+
+    ret |= LockMutex(rngMutex);
+    ret |= wc_RNG_GenerateBlock(rng, out, num_bytes);
+    ret |= UnLockMutex(rngMutex);
+
+    if (ret != 0)
+        return DRBG_ENTROPY_FAIL;
+
+    return DRBG_OK;
+}
+#endif /* HAVE_NTRU */
+
+/* used by ssl.c too */
+void c32to24(word32 in, word24 out)
+{
+    out[0] = (in >> 16) & 0xff;
+    out[1] = (in >>  8) & 0xff;
+    out[2] =  in & 0xff;
+}
+
+
+#ifdef WOLFSSL_DTLS
+
+static INLINE void c32to48(word32 in, byte out[6])
+{
+    out[0] = 0;
+    out[1] = 0;
+    out[2] = (in >> 24) & 0xff;
+    out[3] = (in >> 16) & 0xff;
+    out[4] = (in >>  8) & 0xff;
+    out[5] =  in & 0xff;
+}
+
+#endif /* WOLFSSL_DTLS */
+
+
+/* convert 16 bit integer to opaque */
+static INLINE void c16toa(word16 u16, byte* c)
+{
+    c[0] = (u16 >> 8) & 0xff;
+    c[1] =  u16 & 0xff;
+}
+
+
+#if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \
+    || defined(HAVE_AESGCM)
+/* convert 32 bit integer to opaque */
+static INLINE void c32toa(word32 u32, byte* c)
+{
+    c[0] = (u32 >> 24) & 0xff;
+    c[1] = (u32 >> 16) & 0xff;
+    c[2] = (u32 >>  8) & 0xff;
+    c[3] =  u32 & 0xff;
+}
+#endif
+
+
+/* convert a 24 bit integer into a 32 bit one */
+static INLINE void c24to32(const word24 u24, word32* u32)
+{
+    *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
+}
+
+
+/* convert opaque to 16 bit integer */
+static INLINE void ato16(const byte* c, word16* u16)
+{
+    *u16 = (word16) ((c[0] << 8) | (c[1]));
+}
+
+
+#if defined(WOLFSSL_DTLS) || defined(HAVE_SESSION_TICKET)
+
+/* convert opaque to 32 bit integer */
+static INLINE void ato32(const byte* c, word32* u32)
+{
+    *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
+}
+
+#endif /* WOLFSSL_DTLS */
+
+
+#ifdef HAVE_LIBZ
+
+    /* alloc user allocs to work with zlib */
+    static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
+    {
+        (void)opaque;
+        return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
+    }
+
+
+    static void myFree(void* opaque, void* memory)
+    {
+        (void)opaque;
+        XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);
+    }
+
+
+    /* init zlib comp/decomp streams, 0 on success */
+    static int InitStreams(WOLFSSL* ssl)
+    {
+        ssl->c_stream.zalloc = (alloc_func)myAlloc;
+        ssl->c_stream.zfree  = (free_func)myFree;
+        ssl->c_stream.opaque = (voidpf)ssl->heap;
+
+        if (deflateInit(&ssl->c_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
+            return ZLIB_INIT_ERROR;
+
+        ssl->didStreamInit = 1;
+
+        ssl->d_stream.zalloc = (alloc_func)myAlloc;
+        ssl->d_stream.zfree  = (free_func)myFree;
+        ssl->d_stream.opaque = (voidpf)ssl->heap;
+
+        if (inflateInit(&ssl->d_stream) != Z_OK) return ZLIB_INIT_ERROR;
+
+        return 0;
+    }
+
+
+    static void FreeStreams(WOLFSSL* ssl)
+    {
+        if (ssl->didStreamInit) {
+            deflateEnd(&ssl->c_stream);
+            inflateEnd(&ssl->d_stream);
+        }
+    }
+
+
+    /* compress in to out, return out size or error */
+    static int myCompress(WOLFSSL* ssl, byte* in, int inSz, byte* out, int outSz)
+    {
+        int    err;
+        int    currTotal = (int)ssl->c_stream.total_out;
+
+        ssl->c_stream.next_in   = in;
+        ssl->c_stream.avail_in  = inSz;
+        ssl->c_stream.next_out  = out;
+        ssl->c_stream.avail_out = outSz;
+
+        err = deflate(&ssl->c_stream, Z_SYNC_FLUSH);
+        if (err != Z_OK && err != Z_STREAM_END) return ZLIB_COMPRESS_ERROR;
+
+        return (int)ssl->c_stream.total_out - currTotal;
+    }
+
+
+    /* decompress in to out, returnn out size or error */
+    static int myDeCompress(WOLFSSL* ssl, byte* in,int inSz, byte* out,int outSz)
+    {
+        int    err;
+        int    currTotal = (int)ssl->d_stream.total_out;
+
+        ssl->d_stream.next_in   = in;
+        ssl->d_stream.avail_in  = inSz;
+        ssl->d_stream.next_out  = out;
+        ssl->d_stream.avail_out = outSz;
+
+        err = inflate(&ssl->d_stream, Z_SYNC_FLUSH);
+        if (err != Z_OK && err != Z_STREAM_END) return ZLIB_DECOMPRESS_ERROR;
+
+        return (int)ssl->d_stream.total_out - currTotal;
+    }
+
+#endif /* HAVE_LIBZ */
+
+
+void InitSSL_Method(WOLFSSL_METHOD* method, ProtocolVersion pv)
+{
+    method->version    = pv;
+    method->side       = WOLFSSL_CLIENT_END;
+    method->downgrade  = 0;
+}
+
+
+/* Initialze SSL context, return 0 on success */
+int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method)
+{
+    XMEMSET(ctx, 0, sizeof(WOLFSSL_CTX));
+
+    ctx->method   = method;
+    ctx->refCount = 1;          /* so either CTX_free or SSL_free can release */
+    ctx->heap     = ctx;        /* defaults to self */
+    ctx->timeout  = WOLFSSL_SESSION_TIMEOUT;
+    ctx->minDowngrade = TLSv1_MINOR;     /* current default */
+
+    if (InitMutex(&ctx->countMutex) < 0) {
+        WOLFSSL_MSG("Mutex error on CTX init");
+        return BAD_MUTEX_E;
+    }
+
+#ifndef NO_DH
+    ctx->minDhKeySz = MIN_DHKEY_SZ;
+#endif
+
+#ifdef HAVE_ECC
+    ctx->eccTempKeySz = ECDHE_SIZE;
+#endif
+
+#ifndef WOLFSSL_USER_IO
+    ctx->CBIORecv = EmbedReceive;
+    ctx->CBIOSend = EmbedSend;
+    #ifdef WOLFSSL_DTLS
+        if (method->version.major == DTLS_MAJOR) {
+            ctx->CBIORecv   = EmbedReceiveFrom;
+            ctx->CBIOSend   = EmbedSendTo;
+        }
+    #endif
+#endif /* WOLFSSL_USER_IO */
+
+#ifdef HAVE_NETX
+    ctx->CBIORecv = NetX_Receive;
+    ctx->CBIOSend = NetX_Send;
+#endif
+
+#ifdef HAVE_NTRU
+    if (method->side == WOLFSSL_CLIENT_END)
+        ctx->haveNTRU = 1;           /* always on cliet side */
+                                     /* server can turn on by loading key */
+#endif
+#ifdef HAVE_ECC
+    if (method->side == WOLFSSL_CLIENT_END) {
+        ctx->haveECDSAsig  = 1;        /* always on cliet side */
+        ctx->haveStaticECC = 1;        /* server can turn on by loading key */
+    }
+#endif
+
+#ifdef HAVE_CAVIUM
+    ctx->devId = NO_CAVIUM_DEVICE;
+#endif
+
+#ifndef NO_CERTS
+    ctx->cm = wolfSSL_CertManagerNew();
+    if (ctx->cm == NULL) {
+        WOLFSSL_MSG("Bad Cert Manager New");
+        return BAD_CERT_MANAGER_ERROR;
+    }
+#endif
+
+#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
+    ctx->ticketHint = SESSION_TICKET_HINT_DEFAULT;
+#endif
+
+    return 0;
+}
+
+
+/* In case contexts are held in array and don't want to free actual ctx */
+void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
+{
+    XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
+    if (ctx->suites)
+        XFREE(ctx->suites, ctx->heap, DYNAMIC_TYPE_SUITES);
+
+#ifndef NO_DH
+    XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
+    XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
+#endif
+#ifndef NO_CERTS
+    XFREE(ctx->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
+    XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
+    XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
+    wolfSSL_CertManagerFree(ctx->cm);
+#endif
+#ifdef HAVE_TLS_EXTENSIONS
+    TLSX_FreeAll(ctx->extensions);
+#endif
+}
+
+
+void FreeSSL_Ctx(WOLFSSL_CTX* ctx)
+{
+    int doFree = 0;
+
+    if (LockMutex(&ctx->countMutex) != 0) {
+        WOLFSSL_MSG("Couldn't lock count mutex");
+        return;
+    }
+    ctx->refCount--;
+    if (ctx->refCount == 0)
+        doFree = 1;
+    UnLockMutex(&ctx->countMutex);
+
+    if (doFree) {
+        WOLFSSL_MSG("CTX ref count down to 0, doing full free");
+        SSL_CtxResourceFree(ctx);
+        FreeMutex(&ctx->countMutex);
+        XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
+    }
+    else {
+        (void)ctx;
+        WOLFSSL_MSG("CTX ref count not 0 yet, no free");
+    }
+}
+
+
+/* Set cipher pointers to null */
+void InitCiphers(WOLFSSL* ssl)
+{
+#ifdef BUILD_ARC4
+    ssl->encrypt.arc4 = NULL;
+    ssl->decrypt.arc4 = NULL;
+#endif
+#ifdef BUILD_DES3
+    ssl->encrypt.des3 = NULL;
+    ssl->decrypt.des3 = NULL;
+#endif
+#ifdef BUILD_AES
+    ssl->encrypt.aes = NULL;
+    ssl->decrypt.aes = NULL;
+#endif
+#ifdef HAVE_CAMELLIA
+    ssl->encrypt.cam = NULL;
+    ssl->decrypt.cam = NULL;
+#endif
+#ifdef HAVE_HC128
+    ssl->encrypt.hc128 = NULL;
+    ssl->decrypt.hc128 = NULL;
+#endif
+#ifdef BUILD_RABBIT
+    ssl->encrypt.rabbit = NULL;
+    ssl->decrypt.rabbit = NULL;
+#endif
+#ifdef HAVE_CHACHA
+    ssl->encrypt.chacha = NULL;
+    ssl->decrypt.chacha = NULL;
+#endif
+#ifdef HAVE_POLY1305
+    ssl->auth.poly1305 = NULL;
+#endif
+    ssl->encrypt.setup = 0;
+    ssl->decrypt.setup = 0;
+#ifdef HAVE_ONE_TIME_AUTH
+    ssl->auth.setup    = 0;
+#endif
+#ifdef HAVE_IDEA
+    ssl->encrypt.idea = NULL;
+    ssl->decrypt.idea = NULL;
+#endif
+}
+
+
+/* Free ciphers */
+void FreeCiphers(WOLFSSL* ssl)
+{
+    (void)ssl;
+#ifdef BUILD_ARC4
+    #ifdef HAVE_CAVIUM
+    if (ssl->devId != NO_CAVIUM_DEVICE) {
+        wc_Arc4FreeCavium(ssl->encrypt.arc4);
+        wc_Arc4FreeCavium(ssl->decrypt.arc4);
+    }
+    #endif
+    XFREE(ssl->encrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#ifdef BUILD_DES3
+    #ifdef HAVE_CAVIUM
+    if (ssl->devId != NO_CAVIUM_DEVICE) {
+        wc_Des3_FreeCavium(ssl->encrypt.des3);
+        wc_Des3_FreeCavium(ssl->decrypt.des3);
+    }
+    #endif
+    XFREE(ssl->encrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#ifdef BUILD_AES
+    #ifdef HAVE_CAVIUM
+    if (ssl->devId != NO_CAVIUM_DEVICE) {
+        wc_AesFreeCavium(ssl->encrypt.aes);
+        wc_AesFreeCavium(ssl->decrypt.aes);
+    }
+    #endif
+    XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#ifdef HAVE_CAMELLIA
+    XFREE(ssl->encrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#ifdef HAVE_HC128
+    XFREE(ssl->encrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#ifdef BUILD_RABBIT
+    XFREE(ssl->encrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#ifdef HAVE_CHACHA
+    XFREE(ssl->encrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#ifdef HAVE_POLY1305
+    XFREE(ssl->auth.poly1305, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+#ifdef HAVE_IDEA
+    XFREE(ssl->encrypt.idea, ssl->heap, DYNAMIC_TYPE_CIPHER);
+    XFREE(ssl->decrypt.idea, ssl->heap, DYNAMIC_TYPE_CIPHER);
+#endif
+}
+
+
+void InitCipherSpecs(CipherSpecs* cs)
+{
+    cs->bulk_cipher_algorithm = INVALID_BYTE;
+    cs->cipher_type           = INVALID_BYTE;
+    cs->mac_algorithm         = INVALID_BYTE;
+    cs->kea                   = INVALID_BYTE;
+    cs->sig_algo              = INVALID_BYTE;
+
+    cs->hash_size   = 0;
+    cs->static_ecdh = 0;
+    cs->key_size    = 0;
+    cs->iv_size     = 0;
+    cs->block_size  = 0;
+}
+
+static void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig,
+                                                  int haveRSAsig, int haveAnon)
+{
+    int idx = 0;
+
+    if (haveECDSAsig) {
+        #ifdef WOLFSSL_SHA512
+            suites->hashSigAlgo[idx++] = sha512_mac;
+            suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
+        #endif
+        #ifdef WOLFSSL_SHA384
+            suites->hashSigAlgo[idx++] = sha384_mac;
+            suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
+        #endif
+        #ifndef NO_SHA256
+            suites->hashSigAlgo[idx++] = sha256_mac;
+            suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
+        #endif
+        #ifndef NO_SHA
+            suites->hashSigAlgo[idx++] = sha_mac;
+            suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
+        #endif
+    }
+
+    if (haveRSAsig) {
+        #ifdef WOLFSSL_SHA512
+            suites->hashSigAlgo[idx++] = sha512_mac;
+            suites->hashSigAlgo[idx++] = rsa_sa_algo;
+        #endif
+        #ifdef WOLFSSL_SHA384
+            suites->hashSigAlgo[idx++] = sha384_mac;
+            suites->hashSigAlgo[idx++] = rsa_sa_algo;
+        #endif
+        #ifndef NO_SHA256
+            suites->hashSigAlgo[idx++] = sha256_mac;
+            suites->hashSigAlgo[idx++] = rsa_sa_algo;
+        #endif
+        #ifndef NO_SHA
+            suites->hashSigAlgo[idx++] = sha_mac;
+            suites->hashSigAlgo[idx++] = rsa_sa_algo;
+        #endif
+    }
+
+    if (haveAnon) {
+        #ifdef HAVE_ANON
+            suites->hashSigAlgo[idx++] = sha_mac;
+            suites->hashSigAlgo[idx++] = anonymous_sa_algo;
+        #endif
+    }
+
+    suites->hashSigAlgoSz = (word16)idx;
+}
+
+void InitSuites(Suites* suites, ProtocolVersion pv, word16 haveRSA,
+                word16 havePSK, word16 haveDH, word16 haveNTRU,
+                word16 haveECDSAsig, word16 haveStaticECC, int side)
+{
+    word16 idx = 0;
+    int    tls    = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR;
+    int    tls1_2 = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_2_MINOR;
+    int    dtls   = 0;
+    int    haveRSAsig = 1;
+
+    (void)tls;  /* shut up compiler */
+    (void)tls1_2;
+    (void)dtls;
+    (void)haveDH;
+    (void)havePSK;
+    (void)haveNTRU;
+    (void)haveStaticECC;
+
+    if (suites == NULL) {
+        WOLFSSL_MSG("InitSuites pointer error");
+        return;
+    }
+
+    if (suites->setSuites)
+        return;      /* trust user settings, don't override */
+
+    if (side == WOLFSSL_SERVER_END && haveStaticECC) {
+        haveRSA = 0;   /* can't do RSA with ECDSA key */
+        (void)haveRSA; /* some builds won't read */
+    }
+
+    if (side == WOLFSSL_SERVER_END && haveECDSAsig) {
+        haveRSAsig = 0;     /* can't have RSA sig if signed by ECDSA */
+        (void)haveRSAsig;   /* non ecc builds won't read */
+    }
+
+#ifdef WOLFSSL_DTLS
+    if (pv.major == DTLS_MAJOR) {
+        dtls   = 1;
+        tls    = 1;
+        tls1_2 = pv.minor <= DTLSv1_2_MINOR;
+    }
+#endif
+
+#ifdef HAVE_RENEGOTIATION_INDICATION
+    if (side == WOLFSSL_CLIENT_END) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV;
+    }
+#endif
+
+#ifdef BUILD_TLS_QSH
+    if (tls) {
+        suites->suites[idx++] = QSH_BYTE;
+        suites->suites[idx++] = TLS_QSH;
+    }
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
+   if (tls && haveNTRU && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_256_CBC_SHA;
+   }
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
+    if (tls && haveNTRU && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
+    if (!dtls && tls && haveNTRU && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_NTRU_RSA_WITH_RC4_128_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
+    if (tls && haveNTRU && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveECDSAsig) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && haveECDSAsig) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveDH && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && haveDH && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveECDSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && haveECDSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && haveDH && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && haveDH && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
+    if (tls1_2 && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_256_GCM_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
+    if (tls1_2 && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_128_GCM_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+    if (tls1_2 && haveECDSAsig) {
+        suites->suites[idx++] = CHACHA_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    if (tls && haveRSA) {
+        suites->suites[idx++] = CHACHA_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    if (tls && haveRSA) {
+        suites->suites[idx++] = CHACHA_BYTE;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+    if (tls1_2 && haveRSAsig) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+    if (tls1_2 && haveECDSAsig) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+    if (tls1_2 && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+    if (tls1_2 && haveECDSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+    if (tls1_2 && haveRSAsig) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+    if (tls1_2 && haveECDSAsig) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+    if (tls1_2 && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+    if (tls1_2 && haveECDSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+    if (tls && haveECDSAsig) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+    if (tls && haveECDSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+    if (tls && haveECDSAsig) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+    if (tls && haveECDSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+    if (!dtls && tls && haveECDSAsig) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+    if (!dtls && tls && haveECDSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+    if (tls && haveECDSAsig) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+    if (tls && haveECDSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+    if (tls && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+    if (tls && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+    if (!dtls && tls && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_RC4_128_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
+    if (!dtls && tls && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_RC4_128_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+    if (tls && haveRSAsig && haveStaticECC) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+    if (tls1_2 && haveECDSAsig) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
+    }
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
+    if (tls1_2 && haveECDSAsig) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_128_CCM_8;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_256_CCM_8;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+    if (tls1_2 && haveDH && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+    if (tls1_2 && haveDH && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+    if (tls && haveDH && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+    if (tls && haveDH && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
+    if (tls1_2 && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
+    if (tls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
+    if (tls && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+    if (tls && haveDH && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
+    if (tls && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+    if (tls && haveDH && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
+    if (tls && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
+    if (tls && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
+    if (tls && haveDH && havePSK) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CCM;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
+    if (tls && haveDH && havePSK) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CCM;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
+    if (tls && havePSK) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
+    if (tls && havePSK) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
+    if (tls && havePSK) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM_8;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
+    if (tls && havePSK) {
+        suites->suites[idx++] = ECC_BYTE;
+        suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM_8;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
+    if (tls && haveDH && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
+    if (tls && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA384;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
+    if (tls && haveDH && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
+    if (tls && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA
+    if (tls && havePSK) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA;
+    }
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
+    if (!dtls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = SSL_RSA_WITH_RC4_128_SHA;
+    }
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
+    if (!dtls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = SSL_RSA_WITH_RC4_128_MD5;
+    }
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
+    if (haveRSA ) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
+    if (!dtls && tls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_HC_128_MD5;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
+    if (!dtls && tls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_HC_128_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
+    if (!dtls && tls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_HC_128_B2B256;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
+    if (tls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_B2B256;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
+    if (tls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_B2B256;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
+    if (!dtls && tls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_RABBIT_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+    if (tls && haveDH && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+    if (tls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_WITH_RSA_CAMELLIA_256_CBC_SHA
+    if (tls && haveDH && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+    if (tls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+    if (tls && haveDH && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+    if (tls && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+    if (tls && haveDH && haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256;
+    }
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_IDEA_CBC_SHA
+    if (haveRSA) {
+        suites->suites[idx++] = 0;
+        suites->suites[idx++] = SSL_RSA_WITH_IDEA_CBC_SHA;
+    }
+#endif
+
+    suites->suiteSz = idx;
+
+    InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, 0);
+}
+
+
+#ifndef NO_CERTS
+
+
+void InitX509Name(WOLFSSL_X509_NAME* name, int dynamicFlag)
+{
+    (void)dynamicFlag;
+
+    if (name != NULL) {
+        name->name        = name->staticName;
+        name->dynamicName = 0;
+#ifdef OPENSSL_EXTRA
+        XMEMSET(&name->fullName, 0, sizeof(DecodedName));
+#endif /* OPENSSL_EXTRA */
+    }
+}
+
+
+void FreeX509Name(WOLFSSL_X509_NAME* name)
+{
+    if (name != NULL) {
+        if (name->dynamicName)
+            XFREE(name->name, NULL, DYNAMIC_TYPE_SUBJECT_CN);
+#ifdef OPENSSL_EXTRA
+        if (name->fullName.fullName != NULL)
+            XFREE(name->fullName.fullName, NULL, DYNAMIC_TYPE_X509);
+#endif /* OPENSSL_EXTRA */
+    }
+}
+
+
+/* Initialize wolfSSL X509 type */
+void InitX509(WOLFSSL_X509* x509, int dynamicFlag)
+{
+    InitX509Name(&x509->issuer, 0);
+    InitX509Name(&x509->subject, 0);
+    x509->version        = 0;
+    x509->pubKey.buffer  = NULL;
+    x509->sig.buffer     = NULL;
+    x509->derCert.buffer = NULL;
+    x509->altNames       = NULL;
+    x509->altNamesNext   = NULL;
+    x509->dynamicMemory  = (byte)dynamicFlag;
+    x509->isCa           = 0;
+#ifdef HAVE_ECC
+    x509->pkCurveOID = 0;
+#endif /* HAVE_ECC */
+#ifdef OPENSSL_EXTRA
+    x509->pathLength     = 0;
+    x509->basicConstSet  = 0;
+    x509->basicConstCrit = 0;
+    x509->basicConstPlSet = 0;
+    x509->subjAltNameSet = 0;
+    x509->subjAltNameCrit = 0;
+    x509->authKeyIdSet   = 0;
+    x509->authKeyIdCrit  = 0;
+    x509->authKeyId      = NULL;
+    x509->authKeyIdSz    = 0;
+    x509->subjKeyIdSet   = 0;
+    x509->subjKeyIdCrit  = 0;
+    x509->subjKeyId      = NULL;
+    x509->subjKeyIdSz    = 0;
+    x509->keyUsageSet    = 0;
+    x509->keyUsageCrit   = 0;
+    x509->keyUsage       = 0;
+    #ifdef WOLFSSL_SEP
+        x509->certPolicySet  = 0;
+        x509->certPolicyCrit = 0;
+    #endif /* WOLFSSL_SEP */
+#endif /* OPENSSL_EXTRA */
+}
+
+
+/* Free wolfSSL X509 type */
+void FreeX509(WOLFSSL_X509* x509)
+{
+    if (x509 == NULL)
+        return;
+
+    FreeX509Name(&x509->issuer);
+    FreeX509Name(&x509->subject);
+    if (x509->pubKey.buffer)
+        XFREE(x509->pubKey.buffer, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+    XFREE(x509->derCert.buffer, NULL, DYNAMIC_TYPE_SUBJECT_CN);
+    XFREE(x509->sig.buffer, NULL, DYNAMIC_TYPE_SIGNATURE);
+    #ifdef OPENSSL_EXTRA
+        XFREE(x509->authKeyId, NULL, 0);
+        XFREE(x509->subjKeyId, NULL, 0);
+    #endif /* OPENSSL_EXTRA */
+    if (x509->altNames)
+        FreeAltNames(x509->altNames, NULL);
+    if (x509->dynamicMemory)
+        XFREE(x509, NULL, DYNAMIC_TYPE_X509);
+}
+
+
+#ifndef NO_RSA
+
+/* Verify RSA signature, 0 on success */
+int VerifyRsaSign(const byte* sig, word32 sigSz,
+                  const byte* plain, word32 plainSz, RsaKey* key)
+{
+    #ifdef WOLFSSL_SMALL_STACK
+        byte* verifySig = NULL;
+    #else
+        byte verifySig[ENCRYPT_LEN];
+    #endif
+    byte* out = NULL;  /* inline result */
+    int   ret;
+
+    WOLFSSL_ENTER("VerifyRsaSign");
+
+    if (sig == NULL || plain == NULL || key == NULL) {
+        WOLFSSL_MSG("Null pointer input");
+        return BAD_FUNC_ARG;
+    }
+
+    if (sigSz > ENCRYPT_LEN) {
+        WOLFSSL_MSG("Signature buffer too big");
+        return BUFFER_E;
+    }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        verifySig = (byte*)XMALLOC(ENCRYPT_LEN, NULL,
+                                   DYNAMIC_TYPE_SIGNATURE);
+        if (verifySig == NULL)
+            return MEMORY_ERROR;
+    #endif
+
+    XMEMCPY(verifySig, sig, sigSz);
+    ret = wc_RsaSSL_VerifyInline(verifySig, sigSz, &out, key);
+
+    if (ret != (int)plainSz || !out || XMEMCMP(plain, out, plainSz) != 0) {
+        WOLFSSL_MSG("RSA Signature verification failed");
+        ret = RSA_SIGN_FAULT;
+    } else {
+        ret = 0;  /* RSA reset */
+    }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(verifySig, NULL, DYNAMIC_TYPE_SIGNATURE);
+    #endif
+
+    return ret;
+}
+
+#endif /* NO_RSA */
+
+#endif /* NO_CERTS */
+
+
+/* This function inherits a WOLFSSL_CTX's fields into an SSL object.
+   It is used during initialization and to switch an ssl's CTX with
+   wolfSSL_Set_SSL_CTX.  Requires ssl->suites alloc and ssl-arrays with PSK
+   SSL_SUCCESS return value on success */
+int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
+{
+    byte havePSK = 0;
+    byte haveAnon = 0;
+    byte haveRSA = 0;
+    byte newSSL = ssl->ctx == NULL;
+    (void) haveAnon; /* Squash unused var warnings */
+
+    if(!ssl || !ctx || ssl->suites == NULL)
+        return BAD_FUNC_ARG;
+
+#ifndef NO_PSK
+    if (ctx->server_hint[0] && ssl->arrays == NULL) {
+        return BAD_FUNC_ARG;  /* needed for copy below */
+    }
+#endif
+
+
+#ifndef NO_RSA
+    haveRSA = 1;
+#endif
+#ifndef NO_PSK
+    havePSK = ctx->havePSK;
+#endif /* NO_PSK */
+#ifdef HAVE_ANON
+    haveAnon = ctx->haveAnon;
+#endif /* HAVE_ANON*/
+
+    /* decrement previous CTX reference count if exists.
+     * This should only happen if switching ctxs!*/
+    if (!newSSL) {
+        WOLFSSL_MSG("freeing old ctx to decrement reference count. Switching ctx.");
+        wolfSSL_CTX_free(ssl->ctx);
+    }
+
+    /* increment CTX reference count */
+    if (LockMutex(&ctx->countMutex) != 0) {
+        WOLFSSL_MSG("Couldn't lock CTX count mutex");
+        return BAD_MUTEX_E;
+    }
+    ctx->refCount++;
+    UnLockMutex(&ctx->countMutex);
+    ssl->ctx     = ctx; /* only for passing to calls, options could change */
+    ssl->version = ctx->method->version;
+
+#ifdef HAVE_ECC
+    ssl->eccTempKeySz = ctx->eccTempKeySz;
+    ssl->pkCurveOID = ctx->pkCurveOID;
+#endif
+
+    ssl->timeout = ctx->timeout;
+    ssl->verifyCallback    = ctx->verifyCallback;
+    ssl->options.side      = ctx->method->side;
+    ssl->options.downgrade    = ctx->method->downgrade;
+    ssl->options.minDowngrade = ctx->minDowngrade;
+
+    if (ssl->options.side == WOLFSSL_SERVER_END)
+        ssl->options.haveDH = ctx->haveDH;
+
+    ssl->options.haveNTRU      = ctx->haveNTRU;
+    ssl->options.haveECDSAsig  = ctx->haveECDSAsig;
+    ssl->options.haveStaticECC = ctx->haveStaticECC;
+
+#ifndef NO_PSK
+    ssl->options.havePSK   = ctx->havePSK;
+    ssl->options.client_psk_cb = ctx->client_psk_cb;
+    ssl->options.server_psk_cb = ctx->server_psk_cb;
+#endif /* NO_PSK */
+
+#ifdef HAVE_ANON
+    ssl->options.haveAnon = ctx->haveAnon;
+#endif
+#ifndef NO_DH
+    ssl->options.minDhKeySz = ctx->minDhKeySz;
+#endif
+
+    ssl->options.sessionCacheOff      = ctx->sessionCacheOff;
+    ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
+
+    ssl->options.verifyPeer = ctx->verifyPeer;
+    ssl->options.verifyNone = ctx->verifyNone;
+    ssl->options.failNoCert = ctx->failNoCert;
+    ssl->options.sendVerify = ctx->sendVerify;
+
+    ssl->heap = ctx->heap;    /* defaults to self */
+    ssl->options.partialWrite  = ctx->partialWrite;
+    ssl->options.quietShutdown = ctx->quietShutdown;
+    ssl->options.groupMessages = ctx->groupMessages;
+
+#ifndef NO_DH
+    if (ssl->options.side == WOLFSSL_SERVER_END) {
+        ssl->buffers.serverDH_P = ctx->serverDH_P;
+        ssl->buffers.serverDH_G = ctx->serverDH_G;
+    }
+#endif
+
+#ifndef NO_CERTS
+    /* ctx still owns certificate, certChain, key, dh, and cm */
+    ssl->buffers.certificate = ctx->certificate;
+    ssl->buffers.certChain = ctx->certChain;
+    ssl->buffers.key = ctx->privateKey;
+#endif
+
+#ifdef HAVE_CAVIUM
+    ssl->devId = ctx->devId;
+#endif
+
+#ifndef NO_PSK
+    if (ctx->server_hint[0]) {   /* set in CTX */
+        XSTRNCPY(ssl->arrays->server_hint, ctx->server_hint, MAX_PSK_ID_LEN);
+        ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
+    }
+#endif /* NO_PSK */
+
+    if (ctx->suites)
+        *ssl->suites = *ctx->suites;
+    else
+        XMEMSET(ssl->suites, 0, sizeof(Suites));
+
+    /* make sure server has DH parms, and add PSK if there, add NTRU too */
+    if (ssl->options.side == WOLFSSL_SERVER_END)
+        InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
+                   ssl->options.haveDH, ssl->options.haveNTRU,
+                   ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
+                   ssl->options.side);
+    else
+        InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, TRUE,
+                   ssl->options.haveNTRU, ssl->options.haveECDSAsig,
+                   ssl->options.haveStaticECC, ssl->options.side);
+
+#ifndef NO_CERTS
+    /* make sure server has cert and key unless using PSK or Anon
+     * This should be true even if just switching ssl ctx */
+    if (ssl->options.side == WOLFSSL_SERVER_END && !havePSK && !haveAnon)
+        if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer) {
+            WOLFSSL_MSG("Server missing certificate and/or private key");
+            return NO_PRIVATE_KEY;
+        }
+#endif
+
+    return SSL_SUCCESS;
+}
+
+
+/* init everything to 0, NULL, default values before calling anything that may
+   fail so that desctructor has a "good" state to cleanup
+   0 on success */
+int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
+{
+    int  ret;
+
+    XMEMSET(ssl, 0, sizeof(WOLFSSL));
+
+    ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
+    ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
+
+    ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
+    ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
+
+#ifdef KEEP_PEER_CERT
+    InitX509(&ssl->peerCert, 0);
+#endif
+
+    ssl->rfd = -1;   /* set to invalid descriptor */
+    ssl->wfd = -1;
+
+    ssl->IOCB_ReadCtx  = &ssl->rfd;  /* prevent invalid pointer access if not */
+    ssl->IOCB_WriteCtx = &ssl->wfd;  /* correctly set */
+
+#ifdef HAVE_NETX
+    ssl->IOCB_ReadCtx  = &ssl->nxCtx;  /* default NetX IO ctx, same for read */
+    ssl->IOCB_WriteCtx = &ssl->nxCtx;  /* and write */
+#endif
+#ifdef WOLFSSL_DTLS
+    ssl->dtls_expected_rx = MAX_MTU;
+#endif
+
+    ssl->options.serverState = NULL_STATE;
+    ssl->options.clientState = NULL_STATE;
+    ssl->options.connectState = CONNECT_BEGIN;
+    ssl->options.acceptState  = ACCEPT_BEGIN;
+    ssl->options.handShakeState  = NULL_STATE;
+    ssl->options.processReply = doProcessInit;
+
+#ifdef WOLFSSL_DTLS
+    ssl->dtls_timeout_init              = DTLS_TIMEOUT_INIT;
+    ssl->dtls_timeout_max               = DTLS_TIMEOUT_MAX;
+    ssl->dtls_timeout                   = ssl->dtls_timeout_init;
+#endif
+
+    #ifndef NO_OLD_TLS
+        ssl->hmac = SSL_hmac; /* default to SSLv3 */
+    #else
+        ssl->hmac = TLS_hmac;
+    #endif
+
+
+#ifdef WOLFSSL_DTLS
+    ssl->buffers.dtlsCtx.fd = -1;
+#endif
+
+    ssl->cipher.ssl = ssl;
+
+#ifdef HAVE_TLS_EXTENSIONS
+#ifdef HAVE_MAX_FRAGMENT
+    ssl->max_fragment = MAX_RECORD_SIZE;
+#endif
+#ifdef HAVE_ALPN
+    ssl->alpn_client_list = NULL;
+#endif
+#endif
+
+    /* default alert state (none) */
+    ssl->alert_history.last_rx.code  = -1;
+    ssl->alert_history.last_rx.level = -1;
+    ssl->alert_history.last_tx.code  = -1;
+    ssl->alert_history.last_tx.level = -1;
+
+    InitCiphers(ssl);
+    InitCipherSpecs(&ssl->specs);
+
+    /* all done with init, now can return errors, call other stuff */
+
+    /* arrays */
+    ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap,
+                                                           DYNAMIC_TYPE_ARRAYS);
+    if (ssl->arrays == NULL) {
+        WOLFSSL_MSG("Arrays Memory error");
+        return MEMORY_E;
+    }
+    XMEMSET(ssl->arrays, 0, sizeof(Arrays));
+
+    /* suites */
+    ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
+                                   DYNAMIC_TYPE_SUITES);
+    if (ssl->suites == NULL) {
+        WOLFSSL_MSG("Suites Memory error");
+        return MEMORY_E;
+    }
+
+    /* Initialize SSL with the appropriate fields from it's ctx */
+    /* requires valid arrays and suites */
+    if((ret =  SetSSL_CTX(ssl, ctx)) != SSL_SUCCESS)
+        return ret;
+
+    ssl->options.dtls = ssl->version.major == DTLS_MAJOR;
+
+    /* hsHashes */
+    ssl->hsHashes = (HS_Hashes*)XMALLOC(sizeof(HS_Hashes), ssl->heap,
+                                                           DYNAMIC_TYPE_HASHES);
+    if (ssl->hsHashes == NULL) {
+        WOLFSSL_MSG("HS_Hashes Memory error");
+        return MEMORY_E;
+    }
+
+#ifndef NO_OLD_TLS
+#ifndef NO_MD5
+    wc_InitMd5(&ssl->hsHashes->hashMd5);
+#endif
+#ifndef NO_SHA
+    ret = wc_InitSha(&ssl->hsHashes->hashSha);
+    if (ret != 0) {
+        return ret;
+    }
+#endif
+#endif
+#ifndef NO_SHA256
+    ret = wc_InitSha256(&ssl->hsHashes->hashSha256);
+    if (ret != 0) {
+        return ret;
+    }
+#endif
+#ifdef WOLFSSL_SHA384
+    ret = wc_InitSha384(&ssl->hsHashes->hashSha384);
+    if (ret != 0) {
+        return ret;
+    }
+#endif
+#ifdef WOLFSSL_SHA512
+    ret = wc_InitSha512(&ssl->hsHashes->hashSha512);
+    if (ret != 0) {
+        return ret;
+    }
+#endif
+
+    /* RNG */
+    ssl->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ssl->heap, DYNAMIC_TYPE_RNG);
+    if (ssl->rng == NULL) {
+        WOLFSSL_MSG("RNG Memory error");
+        return MEMORY_E;
+    }
+
+    if ( (ret = wc_InitRng(ssl->rng)) != 0) {
+        WOLFSSL_MSG("RNG Init error");
+        return ret;
+    }
+
+#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
+    if (ssl->options.dtls && ssl->options.side == WOLFSSL_SERVER_END) {
+        ret = wolfSSL_DTLS_SetCookieSecret(ssl, NULL, 0);
+        if (ret != 0) {
+            WOLFSSL_MSG("DTLS Cookie Secret error");
+            return ret;
+        }
+    }
+#endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
+
+#ifdef HAVE_SECRET_CALLBACK
+    ssl->sessionSecretCb  = NULL;
+    ssl->sessionSecretCtx = NULL;
+#endif
+    return 0;
+}
+
+
+/* free use of temporary arrays */
+void FreeArrays(WOLFSSL* ssl, int keep)
+{
+    if (ssl->arrays && keep) {
+        /* keeps session id for user retrieval */
+        XMEMCPY(ssl->session.sessionID, ssl->arrays->sessionID, ID_LEN);
+        ssl->session.sessionIDSz = ssl->arrays->sessionIDSz;
+    }
+    if (ssl->arrays) {
+        XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
+        ssl->arrays->pendingMsg = NULL;
+    }
+    XFREE(ssl->arrays, ssl->heap, DYNAMIC_TYPE_CERT);
+    ssl->arrays = NULL;
+}
+
+
+/* In case holding SSL object in array and don't want to free actual ssl */
+void SSL_ResourceFree(WOLFSSL* ssl)
+{
+    /* Note: any resources used during the handshake should be released in the
+     * function FreeHandshakeResources(). Be careful with the special cases
+     * like the RNG which may optionally be kept for the whole session. (For
+     * example with the RNG, it isn't used beyond the handshake except when
+     * using stream ciphers where it is retained. */
+
+    FreeCiphers(ssl);
+    FreeArrays(ssl, 0);
+    wc_FreeRng(ssl->rng);
+    XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
+    XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
+    XFREE(ssl->hsHashes, ssl->heap, DYNAMIC_TYPE_HASHES);
+    XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
+
+#ifndef NO_DH
+    XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
+    XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
+    /* parameters (p,g) may be owned by ctx */
+    if (ssl->buffers.weOwnDH || ssl->options.side == WOLFSSL_CLIENT_END) {
+        XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
+        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
+    }
+#endif
+#ifndef NO_CERTS
+    if (ssl->buffers.weOwnCert)
+        XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
+    if (ssl->buffers.weOwnCertChain)
+        XFREE(ssl->buffers.certChain.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
+    if (ssl->buffers.weOwnKey)
+        XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
+#endif
+#ifndef NO_RSA
+    if (ssl->peerRsaKey) {
+        wc_FreeRsaKey(ssl->peerRsaKey);
+        XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
+    }
+#endif
+    if (ssl->buffers.inputBuffer.dynamicFlag)
+        ShrinkInputBuffer(ssl, FORCED_FREE);
+    if (ssl->buffers.outputBuffer.dynamicFlag)
+        ShrinkOutputBuffer(ssl);
+#ifdef WOLFSSL_DTLS
+    DtlsPoolDelete(ssl);
+    if (ssl->dtls_msg_list != NULL) {
+        DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
+        ssl->dtls_msg_list = NULL;
+    }
+    XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
+    ssl->buffers.dtlsCtx.peer.sa = NULL;
+#ifndef NO_WOLFSSL_SERVER
+    XFREE(ssl->buffers.dtlsCookieSecret.buffer, ssl->heap,
+          DYNAMIC_TYPE_COOKIE_PWD);
+#endif
+#endif /* WOLFSSL_DTLS */
+#if defined(KEEP_PEER_CERT) || defined(GOAHEAD_WS)
+    FreeX509(&ssl->peerCert);
+#endif
+#if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
+    wolfSSL_BIO_free(ssl->biord);
+    if (ssl->biord != ssl->biowr)        /* in case same as write */
+        wolfSSL_BIO_free(ssl->biowr);
+#endif
+#ifdef HAVE_LIBZ
+    FreeStreams(ssl);
+#endif
+#ifdef HAVE_ECC
+    if (ssl->peerEccKey) {
+        if (ssl->peerEccKeyPresent)
+            wc_ecc_free(ssl->peerEccKey);
+        XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
+    }
+    if (ssl->peerEccDsaKey) {
+        if (ssl->peerEccDsaKeyPresent)
+            wc_ecc_free(ssl->peerEccDsaKey);
+        XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
+    }
+    if (ssl->eccTempKey) {
+        if (ssl->eccTempKeyPresent)
+            wc_ecc_free(ssl->eccTempKey);
+        XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
+    }
+#endif
+#ifdef HAVE_PK_CALLBACKS
+    #ifdef HAVE_ECC
+        XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
+    #endif /* HAVE_ECC */
+    #ifndef NO_RSA
+        XFREE(ssl->buffers.peerRsaKey.buffer, ssl->heap, DYNAMIC_TYPE_RSA);
+    #endif /* NO_RSA */
+#endif /* HAVE_PK_CALLBACKS */
+#ifdef HAVE_TLS_EXTENSIONS
+    TLSX_FreeAll(ssl->extensions);
+
+#ifdef HAVE_ALPN
+    if (ssl->alpn_client_list != NULL) {
+        XFREE(ssl->alpn_client_list, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        ssl->alpn_client_list = NULL;
+    }
+#endif
+#endif /* HAVE_TLS_EXTENSIONS */
+#ifdef HAVE_NETX
+    if (ssl->nxCtx.nxPacket)
+        nx_packet_release(ssl->nxCtx.nxPacket);
+#endif
+}
+
+#ifdef WOLFSSL_TI_HASH
+static void HashFinal(WOLFSSL * ssl) {
+    byte dummyHash[32] ;
+#ifndef NO_MD5
+    wc_Md5Final(&(ssl->hsHashes->hashMd5), dummyHash) ;
+#endif
+#ifndef NO_SHA
+    wc_ShaFinal(&(ssl->hsHashes->hashSha), dummyHash) ;
+#endif
+#ifndef NO_SHA256
+    wc_Sha256Final(&(ssl->hsHashes->hashSha256), dummyHash) ;
+#endif
+}
+#else
+
+    #define HashFinal(ssl)
+
+#endif
+
+/* Free any handshake resources no longer needed */
+void FreeHandshakeResources(WOLFSSL* ssl)
+{
+
+    HashFinal(ssl) ;
+#ifdef HAVE_SECURE_RENEGOTIATION
+    if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
+        WOLFSSL_MSG("Secure Renegotiation needs to retain handshake resources");
+        return;
+    }
+#endif
+
+    /* input buffer */
+    if (ssl->buffers.inputBuffer.dynamicFlag)
+        ShrinkInputBuffer(ssl, NO_FORCED_FREE);
+
+    /* suites */
+    XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
+    ssl->suites = NULL;
+
+    /* hsHashes */
+    XFREE(ssl->hsHashes, ssl->heap, DYNAMIC_TYPE_HASHES);
+    ssl->hsHashes = NULL;
+
+    /* RNG */
+    if (ssl->specs.cipher_type == stream || ssl->options.tls1_1 == 0) {
+        wc_FreeRng(ssl->rng);
+        XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
+        ssl->rng = NULL;
+    }
+
+#ifdef WOLFSSL_DTLS
+    /* DTLS_POOL */
+    if (ssl->options.dtls) {
+        DtlsPoolDelete(ssl);
+        DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
+        ssl->dtls_msg_list = NULL;
+    }
+#endif
+
+    /* arrays */
+    if (ssl->options.saveArrays == 0)
+        FreeArrays(ssl, 1);
+
+#ifndef NO_RSA
+    /* peerRsaKey */
+    if (ssl->peerRsaKey) {
+        wc_FreeRsaKey(ssl->peerRsaKey);
+        XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
+        ssl->peerRsaKey = NULL;
+    }
+#endif
+
+#ifdef HAVE_ECC
+    if (ssl->peerEccKey)
+    {
+        if (ssl->peerEccKeyPresent) {
+            wc_ecc_free(ssl->peerEccKey);
+            ssl->peerEccKeyPresent = 0;
+        }
+        XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
+        ssl->peerEccKey = NULL;
+    }
+    if (ssl->peerEccDsaKey)
+    {
+        if (ssl->peerEccDsaKeyPresent) {
+            wc_ecc_free(ssl->peerEccDsaKey);
+            ssl->peerEccDsaKeyPresent = 0;
+        }
+        XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
+        ssl->peerEccDsaKey = NULL;
+    }
+    if (ssl->eccTempKey)
+    {
+        if (ssl->eccTempKeyPresent) {
+            wc_ecc_free(ssl->eccTempKey);
+            ssl->eccTempKeyPresent = 0;
+        }
+        XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
+        ssl->eccTempKey = NULL;
+    }
+#endif
+#ifndef NO_DH
+    XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
+    ssl->buffers.serverDH_Priv.buffer = NULL;
+    XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
+    ssl->buffers.serverDH_Pub.buffer = NULL;
+    /* parameters (p,g) may be owned by ctx */
+    if (ssl->buffers.weOwnDH || ssl->options.side == WOLFSSL_CLIENT_END) {
+        XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
+        ssl->buffers.serverDH_G.buffer = NULL;
+        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
+        ssl->buffers.serverDH_P.buffer = NULL;
+    }
+#endif
+#ifndef NO_CERTS
+    if (ssl->buffers.weOwnCert) {
+        XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
+        ssl->buffers.certificate.buffer = NULL;
+    }
+    if (ssl->buffers.weOwnCertChain) {
+        XFREE(ssl->buffers.certChain.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
+        ssl->buffers.certChain.buffer = NULL;
+    }
+    if (ssl->buffers.weOwnKey) {
+        XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
+        ssl->buffers.key.buffer = NULL;
+    }
+#endif
+#ifdef HAVE_PK_CALLBACKS
+    #ifdef HAVE_ECC
+        XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
+        ssl->buffers.peerEccDsaKey.buffer = NULL;
+    #endif /* HAVE_ECC */
+    #ifndef NO_RSA
+        XFREE(ssl->buffers.peerRsaKey.buffer, ssl->heap, DYNAMIC_TYPE_RSA);
+        ssl->buffers.peerRsaKey.buffer = NULL;
+    #endif /* NO_RSA */
+#endif /* HAVE_PK_CALLBACKS */
+
+#ifdef HAVE_QSH
+    QSH_FreeAll(ssl);
+#endif
+}
+
+
+void FreeSSL(WOLFSSL* ssl)
+{
+    if (ssl->ctx)
+        FreeSSL_Ctx(ssl->ctx);  /* will decrement and free underyling CTX if 0 */
+    SSL_ResourceFree(ssl);
+    XFREE(ssl, ssl->heap, DYNAMIC_TYPE_SSL);
+}
+
+
+#ifdef WOLFSSL_DTLS
+
+int DtlsPoolInit(WOLFSSL* ssl)
+{
+    if (ssl->dtls_pool == NULL) {
+        DtlsPool *pool = (DtlsPool*)XMALLOC(sizeof(DtlsPool),
+                                             ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
+        if (pool == NULL) {
+            WOLFSSL_MSG("DTLS Buffer Pool Memory error");
+            return MEMORY_E;
+        }
+        else {
+            int i;
+
+            for (i = 0; i < DTLS_POOL_SZ; i++) {
+                pool->buf[i].length = 0;
+                pool->buf[i].buffer = NULL;
+            }
+            pool->used = 0;
+            ssl->dtls_pool = pool;
+        }
+    }
+    return 0;
+}
+
+
+int DtlsPoolSave(WOLFSSL* ssl, const byte *src, int sz)
+{
+    DtlsPool *pool = ssl->dtls_pool;
+    if (pool != NULL && pool->used < DTLS_POOL_SZ) {
+        buffer *pBuf = &pool->buf[pool->used];
+        pBuf->buffer = (byte*)XMALLOC(sz, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
+        if (pBuf->buffer == NULL) {
+            WOLFSSL_MSG("DTLS Buffer Memory error");
+            return MEMORY_ERROR;
+        }
+        XMEMCPY(pBuf->buffer, src, sz);
+        pBuf->length = (word32)sz;
+        pool->used++;
+    }
+    return 0;
+}
+
+
+void DtlsPoolReset(WOLFSSL* ssl)
+{
+    DtlsPool *pool = ssl->dtls_pool;
+    if (pool != NULL) {
+        buffer *pBuf;
+        int i, used;
+
+        used = pool->used;
+        for (i = 0, pBuf = &pool->buf[0]; i < used; i++, pBuf++) {
+            XFREE(pBuf->buffer, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
+            pBuf->buffer = NULL;
+            pBuf->length = 0;
+        }
+        pool->used = 0;
+    }
+    ssl->dtls_timeout = ssl->dtls_timeout_init;
+}
+
+
+void DtlsPoolDelete(WOLFSSL* ssl)
+{
+    if (ssl->dtls_pool != NULL) {
+        DtlsPoolReset(ssl);
+        XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
+        ssl->dtls_pool = NULL;
+    }
+}
+
+
+int DtlsPoolTimeout(WOLFSSL* ssl)
+{
+    int result = -1;
+    if (ssl->dtls_timeout <  ssl->dtls_timeout_max) {
+        ssl->dtls_timeout *= DTLS_TIMEOUT_MULTIPLIER;
+        result = 0;
+    }
+    return result;
+}
+
+
+int DtlsPoolSend(WOLFSSL* ssl)
+{
+    int ret;
+    DtlsPool *pool = ssl->dtls_pool;
+
+    if (pool != NULL && pool->used > 0) {
+        int i;
+        for (i = 0; i < pool->used; i++) {
+            int sendResult;
+            buffer* buf = &pool->buf[i];
+
+            DtlsRecordLayerHeader* dtls = (DtlsRecordLayerHeader*)buf->buffer;
+
+            word16 message_epoch;
+            ato16(dtls->epoch, &message_epoch);
+            if (message_epoch == ssl->keys.dtls_epoch) {
+                /* Increment record sequence number on retransmitted handshake
+                 * messages */
+                c32to48(ssl->keys.dtls_sequence_number, dtls->sequence_number);
+                ssl->keys.dtls_sequence_number++;
+            }
+            else {
+                /* The Finished message is sent with the next epoch, keep its
+                 * sequence number */
+            }
+
+            if ((ret = CheckAvailableSize(ssl, buf->length)) != 0)
+                return ret;
+
+            XMEMCPY(ssl->buffers.outputBuffer.buffer, buf->buffer, buf->length);
+            ssl->buffers.outputBuffer.idx = 0;
+            ssl->buffers.outputBuffer.length = buf->length;
+
+            sendResult = SendBuffered(ssl);
+            if (sendResult < 0) {
+                return sendResult;
+            }
+        }
+    }
+    return 0;
+}
+
+
+/* functions for managing DTLS datagram reordering */
+
+/* Need to allocate space for the handshake message header. The hashing
+ * routines assume the message pointer is still within the buffer that
+ * has the headers, and will include those headers in the hash. The store
+ * routines need to take that into account as well. New will allocate
+ * extra space for the headers. */
+DtlsMsg* DtlsMsgNew(word32 sz, void* heap)
+{
+    DtlsMsg* msg = NULL;
+
+    msg = (DtlsMsg*)XMALLOC(sizeof(DtlsMsg), heap, DYNAMIC_TYPE_DTLS_MSG);
+
+    if (msg != NULL) {
+        msg->buf = (byte*)XMALLOC(sz + DTLS_HANDSHAKE_HEADER_SZ,
+                                                     heap, DYNAMIC_TYPE_NONE);
+        if (msg->buf != NULL) {
+            msg->next = NULL;
+            msg->seq = 0;
+            msg->sz = sz;
+            msg->fragSz = 0;
+            msg->msg = msg->buf + DTLS_HANDSHAKE_HEADER_SZ;
+        }
+        else {
+            XFREE(msg, heap, DYNAMIC_TYPE_DTLS_MSG);
+            msg = NULL;
+        }
+    }
+
+    return msg;
+}
+
+void DtlsMsgDelete(DtlsMsg* item, void* heap)
+{
+    (void)heap;
+
+    if (item != NULL) {
+        if (item->buf != NULL)
+            XFREE(item->buf, heap, DYNAMIC_TYPE_NONE);
+        XFREE(item, heap, DYNAMIC_TYPE_DTLS_MSG);
+    }
+}
+
+
+void DtlsMsgListDelete(DtlsMsg* head, void* heap)
+{
+    DtlsMsg* next;
+    while (head) {
+        next = head->next;
+        DtlsMsgDelete(head, heap);
+        head = next;
+    }
+}
+
+
+void DtlsMsgSet(DtlsMsg* msg, word32 seq, const byte* data, byte type,
+                                              word32 fragOffset, word32 fragSz)
+{
+    if (msg != NULL && data != NULL && msg->fragSz <= msg->sz &&
+                                             (fragOffset + fragSz) <= msg->sz) {
+
+        msg->seq = seq;
+        msg->type = type;
+        msg->fragSz += fragSz;
+        /* If fragOffset is zero, this is either a full message that is out
+         * of order, or the first fragment of a fragmented message. Copy the
+         * handshake message header with the message data. Zero length messages
+         * like Server Hello Done should be saved as well. */
+        if (fragOffset == 0)
+            XMEMCPY(msg->buf, data - DTLS_HANDSHAKE_HEADER_SZ,
+                                            fragSz + DTLS_HANDSHAKE_HEADER_SZ);
+        else {
+            /* If fragOffset is non-zero, this is an additional fragment that
+             * needs to be copied to its location in the message buffer. Also
+             * copy the total size of the message over the fragment size. The
+             * hash routines look at a defragmented message if it had actually
+             * come across as a single handshake message. */
+            XMEMCPY(msg->msg + fragOffset, data, fragSz);
+        }
+        c32to24(msg->sz, msg->msg - DTLS_HANDSHAKE_FRAG_SZ);
+    }
+}
+
+
+DtlsMsg* DtlsMsgFind(DtlsMsg* head, word32 seq)
+{
+    while (head != NULL && head->seq != seq) {
+        head = head->next;
+    }
+    return head;
+}
+
+
+DtlsMsg* DtlsMsgStore(DtlsMsg* head, word32 seq, const byte* data,
+        word32 dataSz, byte type, word32 fragOffset, word32 fragSz, void* heap)
+{
+
+    /* See if seq exists in the list. If it isn't in the list, make
+     * a new item of size dataSz, copy fragSz bytes from data to msg->msg
+     * starting at offset fragOffset, and add fragSz to msg->fragSz. If
+     * the seq is in the list and it isn't full, copy fragSz bytes from
+     * data to msg->msg starting at offset fragOffset, and add fragSz to
+     * msg->fragSz. The new item should be inserted into the list in its
+     * proper position.
+     *
+     * 1. Find seq in list, or where seq should go in list. If seq not in
+     *    list, create new item and insert into list. Either case, keep
+     *    pointer to item.
+     * 2. If msg->fragSz + fragSz < sz, copy data to msg->msg at offset
+     *    fragOffset. Add fragSz to msg->fragSz.
+     */
+
+    if (head != NULL) {
+        DtlsMsg* cur = DtlsMsgFind(head, seq);
+        if (cur == NULL) {
+            cur = DtlsMsgNew(dataSz, heap);
+            if (cur != NULL) {
+                DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz);
+                head = DtlsMsgInsert(head, cur);
+            }
+        }
+        else {
+            DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz);
+        }
+    }
+    else {
+        head = DtlsMsgNew(dataSz, heap);
+        DtlsMsgSet(head, seq, data, type, fragOffset, fragSz);
+    }
+
+    return head;
+}
+
+
+/* DtlsMsgInsert() is an in-order insert. */
+DtlsMsg* DtlsMsgInsert(DtlsMsg* head, DtlsMsg* item)
+{
+    if (head == NULL || item->seq < head->seq) {
+        item->next = head;
+        head = item;
+    }
+    else if (head->next == NULL) {
+        head->next = item;
+    }
+    else {
+        DtlsMsg* cur = head->next;
+        DtlsMsg* prev = head;
+        while (cur) {
+            if (item->seq < cur->seq) {
+                item->next = cur;
+                prev->next = item;
+                break;
+            }
+            prev = cur;
+            cur = cur->next;
+        }
+        if (cur == NULL) {
+            prev->next = item;
+        }
+    }
+
+    return head;
+}
+
+#endif /* WOLFSSL_DTLS */
+
+#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
+
+ProtocolVersion MakeSSLv3(void)
+{
+    ProtocolVersion pv;
+    pv.major = SSLv3_MAJOR;
+    pv.minor = SSLv3_MINOR;
+
+    return pv;
+}
+
+#endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
+
+
+#ifdef WOLFSSL_DTLS
+
+ProtocolVersion MakeDTLSv1(void)
+{
+    ProtocolVersion pv;
+    pv.major = DTLS_MAJOR;
+    pv.minor = DTLS_MINOR;
+
+    return pv;
+}
+
+ProtocolVersion MakeDTLSv1_2(void)
+{
+    ProtocolVersion pv;
+    pv.major = DTLS_MAJOR;
+    pv.minor = DTLSv1_2_MINOR;
+
+    return pv;
+}
+
+#endif /* WOLFSSL_DTLS */
+
+
+
+
+#ifdef USE_WINDOWS_API
+
+    word32 LowResTimer(void)
+    {
+        static int           init = 0;
+        static LARGE_INTEGER freq;
+        LARGE_INTEGER        count;
+
+        if (!init) {
+            QueryPerformanceFrequency(&freq);
+            init = 1;
+        }
+
+        QueryPerformanceCounter(&count);
+
+        return (word32)(count.QuadPart / freq.QuadPart);
+    }
+
+#elif defined(HAVE_RTP_SYS)
+
+    #include "rtptime.h"
+
+    word32 LowResTimer(void)
+    {
+        return (word32)rtp_get_system_sec();
+    }
+
+
+#elif defined(MICRIUM)
+
+    word32 LowResTimer(void)
+    {
+        NET_SECURE_OS_TICK  clk = 0;
+
+        #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
+            clk = NetSecure_OS_TimeGet();
+        #endif
+        return (word32)clk;
+    }
+
+
+#elif defined(MICROCHIP_TCPIP_V5)
+
+    word32 LowResTimer(void)
+    {
+        return (word32) TickGet();
+    }
+
+
+#elif defined(MICROCHIP_TCPIP)
+
+    #if defined(MICROCHIP_MPLAB_HARMONY)
+
+        #include <system/tmr/sys_tmr.h>
+
+        word32 LowResTimer(void)
+        {
+            return (word32) SYS_TMR_TickCountGet();
+        }
+
+    #else
+
+        word32 LowResTimer(void)
+        {
+            return (word32) SYS_TICK_Get();
+        }
+
+    #endif
+
+#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+
+    word32 LowResTimer(void)
+    {
+        TIME_STRUCT mqxTime;
+
+        _time_get_elapsed(&mqxTime);
+
+        return (word32) mqxTime.SECONDS;
+    }
+
+#elif defined(FREESCALE_KSDK_BM)
+
+    #include "fsl_pit_driver.h"
+
+    word32 LowResTimer(void)
+    {
+        return PIT_DRV_GetUs();
+    }
+
+#elif defined(WOLFSSL_TIRTOS)
+
+    word32 LowResTimer(void)
+    {
+        return (word32) Seconds_get();
+    }
+
+#elif defined(USER_TICKS)
+#if 0
+    word32 LowResTimer(void)
+    {
+        /*
+        write your own clock tick function if don't want time(0)
+        needs second accuracy but doesn't have to correlated to EPOCH
+        */
+    }
+#endif
+
+#elif defined(TIME_OVERRIDES)
+
+    /* use same asn time overrides unless user wants tick override above */
+
+    #ifndef HAVE_TIME_T_TYPE
+        typedef long time_t;
+    #endif
+    extern time_t XTIME(time_t * timer);
+
+    word32 LowResTimer(void)
+    {
+        return (word32) XTIME(0);
+    }
+
+#else /* !USE_WINDOWS_API && !HAVE_RTP_SYS && !MICRIUM && !USER_TICKS */
+
+    #include <time.h>
+
+    word32 LowResTimer(void)
+    {
+        return (word32)time(0);
+    }
+
+
+#endif /* USE_WINDOWS_API */
+
+
+#ifndef NO_CERTS
+static int HashOutputRaw(WOLFSSL* ssl, const byte* output, int sz)
+{
+#ifdef HAVE_FUZZER
+    if (ssl->fuzzerCb)
+        ssl->fuzzerCb(ssl, output, sz, FUZZ_HASH, ssl->fuzzerCtx);
+#endif
+#ifndef NO_OLD_TLS
+#ifndef NO_SHA
+    wc_ShaUpdate(&ssl->hsHashes->hashSha, output, sz);
+#endif
+#ifndef NO_MD5
+    wc_Md5Update(&ssl->hsHashes->hashMd5, output, sz);
+#endif
+#endif
+
+    if (IsAtLeastTLSv1_2(ssl)) {
+        int ret;
+
+#ifndef NO_SHA256
+        ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, output, sz);
+        if (ret != 0)
+            return ret;
+#endif
+#ifdef WOLFSSL_SHA384
+        ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, output, sz);
+        if (ret != 0)
+            return ret;
+#endif
+#ifdef WOLFSSL_SHA512
+        ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, output, sz);
+        if (ret != 0)
+            return ret;
+#endif
+    }
+
+    return 0;
+}
+#endif /* NO_CERTS */
+
+
+/* add output to md5 and sha handshake hashes, exclude record header */
+static int HashOutput(WOLFSSL* ssl, const byte* output, int sz, int ivSz)
+{
+    const byte* adj = output + RECORD_HEADER_SZ + ivSz;
+    sz -= RECORD_HEADER_SZ;
+
+#ifdef HAVE_FUZZER
+    if (ssl->fuzzerCb)
+        ssl->fuzzerCb(ssl, output, sz, FUZZ_HASH, ssl->fuzzerCtx);
+#endif
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        adj += DTLS_RECORD_EXTRA;
+        sz  -= DTLS_RECORD_EXTRA;
+    }
+#endif
+#ifndef NO_OLD_TLS
+#ifndef NO_SHA
+    wc_ShaUpdate(&ssl->hsHashes->hashSha, adj, sz);
+#endif
+#ifndef NO_MD5
+    wc_Md5Update(&ssl->hsHashes->hashMd5, adj, sz);
+#endif
+#endif
+
+    if (IsAtLeastTLSv1_2(ssl)) {
+        int ret;
+
+#ifndef NO_SHA256
+        ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, adj, sz);
+        if (ret != 0)
+            return ret;
+#endif
+#ifdef WOLFSSL_SHA384
+        ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, adj, sz);
+        if (ret != 0)
+            return ret;
+#endif
+#ifdef WOLFSSL_SHA512
+        ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, adj, sz);
+        if (ret != 0)
+            return ret;
+#endif
+    }
+
+    return 0;
+}
+
+
+/* add input to md5 and sha handshake hashes, include handshake header */
+static int HashInput(WOLFSSL* ssl, const byte* input, int sz)
+{
+    const byte* adj = input - HANDSHAKE_HEADER_SZ;
+    sz += HANDSHAKE_HEADER_SZ;
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        adj -= DTLS_HANDSHAKE_EXTRA;
+        sz  += DTLS_HANDSHAKE_EXTRA;
+    }
+#endif
+
+#ifndef NO_OLD_TLS
+#ifndef NO_SHA
+    wc_ShaUpdate(&ssl->hsHashes->hashSha, adj, sz);
+#endif
+#ifndef NO_MD5
+    wc_Md5Update(&ssl->hsHashes->hashMd5, adj, sz);
+#endif
+#endif
+
+    if (IsAtLeastTLSv1_2(ssl)) {
+        int ret;
+
+#ifndef NO_SHA256
+        ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, adj, sz);
+        if (ret != 0)
+            return ret;
+#endif
+#ifdef WOLFSSL_SHA384
+        ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, adj, sz);
+        if (ret != 0)
+            return ret;
+#endif
+#ifdef WOLFSSL_SHA512
+        ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, adj, sz);
+        if (ret != 0)
+            return ret;
+#endif
+    }
+
+    return 0;
+}
+
+
+/* add record layer header for message */
+static void AddRecordHeader(byte* output, word32 length, byte type, WOLFSSL* ssl)
+{
+    RecordLayerHeader* rl;
+
+    /* record layer header */
+    rl = (RecordLayerHeader*)output;
+    rl->type    = type;
+    rl->pvMajor = ssl->version.major;       /* type and version same in each */
+    rl->pvMinor = ssl->version.minor;
+
+#ifdef WOLFSSL_ALTERNATIVE_DOWNGRADE
+    if (ssl->options.side == WOLFSSL_CLIENT_END
+    &&  ssl->options.connectState == CONNECT_BEGIN
+    && !ssl->options.resuming)
+        rl->pvMinor = ssl->options.downgrade ? ssl->options.minDowngrade
+                                             : ssl->version.minor;
+#endif
+
+    if (!ssl->options.dtls)
+        c16toa((word16)length, rl->length);
+    else {
+#ifdef WOLFSSL_DTLS
+        DtlsRecordLayerHeader* dtls;
+
+        /* dtls record layer header extensions */
+        dtls = (DtlsRecordLayerHeader*)output;
+        c16toa(ssl->keys.dtls_epoch, dtls->epoch);
+        c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
+        c16toa((word16)length, dtls->length);
+#endif
+    }
+}
+
+
+/* add handshake header for message */
+static void AddHandShakeHeader(byte* output, word32 length,
+                               word32 fragOffset, word32 fragLength,
+                               byte type, WOLFSSL* ssl)
+{
+    HandShakeHeader* hs;
+    (void)fragOffset;
+    (void)fragLength;
+    (void)ssl;
+
+    /* handshake header */
+    hs = (HandShakeHeader*)output;
+    hs->type = type;
+    c32to24(length, hs->length);         /* type and length same for each */
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        DtlsHandShakeHeader* dtls;
+
+        /* dtls handshake header extensions */
+        dtls = (DtlsHandShakeHeader*)output;
+        c16toa(ssl->keys.dtls_handshake_number++, dtls->message_seq);
+        c32to24(fragOffset, dtls->fragment_offset);
+        c32to24(fragLength, dtls->fragment_length);
+    }
+#endif
+}
+
+
+/* add both headers for handshake message */
+static void AddHeaders(byte* output, word32 length, byte type, WOLFSSL* ssl)
+{
+    word32 lengthAdj = HANDSHAKE_HEADER_SZ;
+    word32 outputAdj = RECORD_HEADER_SZ;
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        lengthAdj += DTLS_HANDSHAKE_EXTRA;
+        outputAdj += DTLS_RECORD_EXTRA;
+    }
+#endif
+
+    AddRecordHeader(output, length + lengthAdj, handshake, ssl);
+    AddHandShakeHeader(output + outputAdj, length, 0, length, type, ssl);
+}
+
+
+#ifndef NO_CERTS
+static void AddFragHeaders(byte* output, word32 fragSz, word32 fragOffset,
+                           word32 length, byte type, WOLFSSL* ssl)
+{
+    word32 lengthAdj = HANDSHAKE_HEADER_SZ;
+    word32 outputAdj = RECORD_HEADER_SZ;
+    (void)fragSz;
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        lengthAdj += DTLS_HANDSHAKE_EXTRA;
+        outputAdj += DTLS_RECORD_EXTRA;
+    }
+#endif
+
+    AddRecordHeader(output, fragSz + lengthAdj, handshake, ssl);
+    AddHandShakeHeader(output + outputAdj, length, fragOffset, fragSz, type, ssl);
+}
+#endif /* NO_CERTS */
+
+
+/* return bytes received, -1 on error */
+static int Receive(WOLFSSL* ssl, byte* buf, word32 sz)
+{
+    int recvd;
+
+    if (ssl->ctx->CBIORecv == NULL) {
+        WOLFSSL_MSG("Your IO Recv callback is null, please set");
+        return -1;
+    }
+
+retry:
+    recvd = ssl->ctx->CBIORecv(ssl, (char *)buf, (int)sz, ssl->IOCB_ReadCtx);
+    if (recvd < 0)
+        switch (recvd) {
+            case WOLFSSL_CBIO_ERR_GENERAL:        /* general/unknown error */
+                return -1;
+
+            case WOLFSSL_CBIO_ERR_WANT_READ:      /* want read, would block */
+                return WANT_READ;
+
+            case WOLFSSL_CBIO_ERR_CONN_RST:       /* connection reset */
+                #ifdef USE_WINDOWS_API
+                if (ssl->options.dtls) {
+                    goto retry;
+                }
+                #endif
+                ssl->options.connReset = 1;
+                return -1;
+
+            case WOLFSSL_CBIO_ERR_ISR:            /* interrupt */
+                /* see if we got our timeout */
+                #ifdef WOLFSSL_CALLBACKS
+                    if (ssl->toInfoOn) {
+                        struct itimerval timeout;
+                        getitimer(ITIMER_REAL, &timeout);
+                        if (timeout.it_value.tv_sec == 0 &&
+                                                timeout.it_value.tv_usec == 0) {
+                            XSTRNCPY(ssl->timeoutInfo.timeoutName,
+                                    "recv() timeout", MAX_TIMEOUT_NAME_SZ);
+                            WOLFSSL_MSG("Got our timeout");
+                            return WANT_READ;
+                        }
+                    }
+                #endif
+                goto retry;
+
+            case WOLFSSL_CBIO_ERR_CONN_CLOSE:     /* peer closed connection */
+                ssl->options.isClosed = 1;
+                return -1;
+
+            case WOLFSSL_CBIO_ERR_TIMEOUT:
+#ifdef WOLFSSL_DTLS
+                if (DtlsPoolTimeout(ssl) == 0 && DtlsPoolSend(ssl) == 0)
+                    goto retry;
+                else
+#endif
+                    return -1;
+
+            default:
+                return recvd;
+        }
+
+    return recvd;
+}
+
+
+/* Switch dynamic output buffer back to static, buffer is assumed clear */
+void ShrinkOutputBuffer(WOLFSSL* ssl)
+{
+    WOLFSSL_MSG("Shrinking output buffer\n");
+    XFREE(ssl->buffers.outputBuffer.buffer - ssl->buffers.outputBuffer.offset,
+          ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
+    ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
+    ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
+    ssl->buffers.outputBuffer.dynamicFlag = 0;
+    ssl->buffers.outputBuffer.offset      = 0;
+}
+
+
+/* Switch dynamic input buffer back to static, keep any remaining input */
+/* forced free means cleaning up */
+void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree)
+{
+    int usedLength = ssl->buffers.inputBuffer.length -
+                     ssl->buffers.inputBuffer.idx;
+    if (!forcedFree && usedLength > STATIC_BUFFER_LEN)
+        return;
+
+    WOLFSSL_MSG("Shrinking input buffer\n");
+
+    if (!forcedFree && usedLength)
+        XMEMCPY(ssl->buffers.inputBuffer.staticBuffer,
+               ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
+               usedLength);
+
+    XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
+          ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
+    ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
+    ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
+    ssl->buffers.inputBuffer.dynamicFlag = 0;
+    ssl->buffers.inputBuffer.offset      = 0;
+    ssl->buffers.inputBuffer.idx = 0;
+    ssl->buffers.inputBuffer.length = usedLength;
+}
+
+int SendBuffered(WOLFSSL* ssl)
+{
+    if (ssl->ctx->CBIOSend == NULL) {
+        WOLFSSL_MSG("Your IO Send callback is null, please set");
+        return SOCKET_ERROR_E;
+    }
+
+    while (ssl->buffers.outputBuffer.length > 0) {
+        int sent = ssl->ctx->CBIOSend(ssl,
+                                      (char*)ssl->buffers.outputBuffer.buffer +
+                                      ssl->buffers.outputBuffer.idx,
+                                      (int)ssl->buffers.outputBuffer.length,
+                                      ssl->IOCB_WriteCtx);
+        if (sent < 0) {
+            switch (sent) {
+
+                case WOLFSSL_CBIO_ERR_WANT_WRITE:        /* would block */
+                    return WANT_WRITE;
+
+                case WOLFSSL_CBIO_ERR_CONN_RST:          /* connection reset */
+                    ssl->options.connReset = 1;
+                    break;
+
+                case WOLFSSL_CBIO_ERR_ISR:               /* interrupt */
+                    /* see if we got our timeout */
+                    #ifdef WOLFSSL_CALLBACKS
+                        if (ssl->toInfoOn) {
+                            struct itimerval timeout;
+                            getitimer(ITIMER_REAL, &timeout);
+                            if (timeout.it_value.tv_sec == 0 &&
+                                                timeout.it_value.tv_usec == 0) {
+                                XSTRNCPY(ssl->timeoutInfo.timeoutName,
+                                        "send() timeout", MAX_TIMEOUT_NAME_SZ);
+                                WOLFSSL_MSG("Got our timeout");
+                                return WANT_WRITE;
+                            }
+                        }
+                    #endif
+                    continue;
+
+                case WOLFSSL_CBIO_ERR_CONN_CLOSE: /* epipe / conn closed */
+                    ssl->options.connReset = 1;  /* treat same as reset */
+                    break;
+
+                default:
+                    return SOCKET_ERROR_E;
+            }
+
+            return SOCKET_ERROR_E;
+        }
+
+        if (sent > (int)ssl->buffers.outputBuffer.length) {
+            WOLFSSL_MSG("SendBuffered() out of bounds read");
+            return SEND_OOB_READ_E;
+        }
+
+        ssl->buffers.outputBuffer.idx += sent;
+        ssl->buffers.outputBuffer.length -= sent;
+    }
+
+    ssl->buffers.outputBuffer.idx = 0;
+
+    if (ssl->buffers.outputBuffer.dynamicFlag)
+        ShrinkOutputBuffer(ssl);
+
+    return 0;
+}
+
+
+/* Grow the output buffer */
+static INLINE int GrowOutputBuffer(WOLFSSL* ssl, int size)
+{
+    byte* tmp;
+    byte  hdrSz = ssl->options.dtls ? DTLS_RECORD_HEADER_SZ :
+                                      RECORD_HEADER_SZ;
+    byte  align = WOLFSSL_GENERAL_ALIGNMENT;
+    /* the encrypted data will be offset from the front of the buffer by
+       the header, if the user wants encrypted alignment they need
+       to define their alignment requirement */
+
+    if (align) {
+       while (align < hdrSz)
+           align *= 2;
+    }
+
+    tmp = (byte*) XMALLOC(size + ssl->buffers.outputBuffer.length + align,
+                          ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
+    WOLFSSL_MSG("growing output buffer\n");
+
+    if (!tmp) return MEMORY_E;
+    if (align)
+        tmp += align - hdrSz;
+
+    if (ssl->buffers.outputBuffer.length)
+        XMEMCPY(tmp, ssl->buffers.outputBuffer.buffer,
+               ssl->buffers.outputBuffer.length);
+
+    if (ssl->buffers.outputBuffer.dynamicFlag)
+        XFREE(ssl->buffers.outputBuffer.buffer -
+              ssl->buffers.outputBuffer.offset, ssl->heap,
+              DYNAMIC_TYPE_OUT_BUFFER);
+    ssl->buffers.outputBuffer.dynamicFlag = 1;
+    if (align)
+        ssl->buffers.outputBuffer.offset = align - hdrSz;
+    else
+        ssl->buffers.outputBuffer.offset = 0;
+    ssl->buffers.outputBuffer.buffer = tmp;
+    ssl->buffers.outputBuffer.bufferSize = size +
+                                           ssl->buffers.outputBuffer.length;
+    return 0;
+}
+
+
+/* Grow the input buffer, should only be to read cert or big app data */
+int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength)
+{
+    byte* tmp;
+    byte  hdrSz = DTLS_RECORD_HEADER_SZ;
+    byte  align = ssl->options.dtls ? WOLFSSL_GENERAL_ALIGNMENT : 0;
+    /* the encrypted data will be offset from the front of the buffer by
+       the dtls record header, if the user wants encrypted alignment they need
+       to define their alignment requirement. in tls we read record header
+       to get size of record and put actual data back at front, so don't need */
+
+    if (align) {
+       while (align < hdrSz)
+           align *= 2;
+    }
+    tmp = (byte*) XMALLOC(size + usedLength + align, ssl->heap,
+                          DYNAMIC_TYPE_IN_BUFFER);
+    WOLFSSL_MSG("growing input buffer\n");
+
+    if (!tmp) return MEMORY_E;
+    if (align)
+        tmp += align - hdrSz;
+
+    if (usedLength)
+        XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer +
+                    ssl->buffers.inputBuffer.idx, usedLength);
+
+    if (ssl->buffers.inputBuffer.dynamicFlag)
+        XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
+              ssl->heap,DYNAMIC_TYPE_IN_BUFFER);
+
+    ssl->buffers.inputBuffer.dynamicFlag = 1;
+    if (align)
+        ssl->buffers.inputBuffer.offset = align - hdrSz;
+    else
+        ssl->buffers.inputBuffer.offset = 0;
+    ssl->buffers.inputBuffer.buffer = tmp;
+    ssl->buffers.inputBuffer.bufferSize = size + usedLength;
+    ssl->buffers.inputBuffer.idx    = 0;
+    ssl->buffers.inputBuffer.length = usedLength;
+
+    return 0;
+}
+
+
+/* check available size into output buffer, make room if needed */
+int CheckAvailableSize(WOLFSSL *ssl, int size)
+{
+
+    if (size < 0) {
+        WOLFSSL_MSG("CheckAvailableSize() called with negative number");
+        return BAD_FUNC_ARG;
+    }
+
+    if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
+                                             < (word32)size) {
+        if (GrowOutputBuffer(ssl, size) < 0)
+            return MEMORY_E;
+    }
+
+    return 0;
+}
+
+
+/* do all verify and sanity checks on record header */
+static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                           RecordLayerHeader* rh, word16 *size)
+{
+    if (!ssl->options.dtls) {
+#ifdef HAVE_FUZZER
+        if (ssl->fuzzerCb)
+            ssl->fuzzerCb(ssl, input + *inOutIdx, RECORD_HEADER_SZ, FUZZ_HEAD,
+                    ssl->fuzzerCtx);
+#endif
+        XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
+        *inOutIdx += RECORD_HEADER_SZ;
+        ato16(rh->length, size);
+    }
+    else {
+#ifdef WOLFSSL_DTLS
+        /* type and version in same sport */
+        XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
+        *inOutIdx += ENUM_LEN + VERSION_SZ;
+        ato16(input + *inOutIdx, &ssl->keys.dtls_state.curEpoch);
+        *inOutIdx += 4; /* advance past epoch, skip first 2 seq bytes for now */
+        ato32(input + *inOutIdx, &ssl->keys.dtls_state.curSeq);
+        *inOutIdx += 4;  /* advance past rest of seq */
+        ato16(input + *inOutIdx, size);
+        *inOutIdx += LENGTH_SZ;
+#ifdef HAVE_FUZZER
+        if (ssl->fuzzerCb)
+            ssl->fuzzerCb(ssl, input + *inOutIdx - LENGTH_SZ - 8 - ENUM_LEN -
+                           VERSION_SZ, ENUM_LEN + VERSION_SZ + 8 + LENGTH_SZ,
+                           FUZZ_HEAD, ssl->fuzzerCtx);
+#endif
+#endif
+    }
+
+    /* catch version mismatch */
+    if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor){
+        if (ssl->options.side == WOLFSSL_SERVER_END &&
+            ssl->options.acceptState < ACCEPT_FIRST_REPLY_DONE)
+
+            WOLFSSL_MSG("Client attempting to connect with different version");
+        else if (ssl->options.side == WOLFSSL_CLIENT_END &&
+                                 ssl->options.downgrade &&
+                                 ssl->options.connectState < FIRST_REPLY_DONE)
+            WOLFSSL_MSG("Server attempting to accept with different version");
+        else if (ssl->options.dtls
+                    && (ssl->options.acceptState == ACCEPT_BEGIN
+                    || ssl->options.acceptState == CLIENT_HELLO_SENT))
+            /* Do not check version until Server Hello or Hello Again (2) */
+            WOLFSSL_MSG("Use version for formatting only in DTLS till ");
+        else {
+            WOLFSSL_MSG("SSL version error");
+            return VERSION_ERROR;              /* only use requested version */
+        }
+    }
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        if (DtlsCheckWindow(&ssl->keys.dtls_state) != 1)
+            return SEQUENCE_ERROR;
+    }
+#endif
+
+    /* record layer length check */
+#ifdef HAVE_MAX_FRAGMENT
+    if (*size > (ssl->max_fragment + MAX_COMP_EXTRA + MAX_MSG_EXTRA)) {
+        SendAlert(ssl, alert_fatal, record_overflow);
+        return LENGTH_ERROR;
+    }
+#else
+    if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
+        return LENGTH_ERROR;
+#endif
+
+    /* verify record type here as well */
+    switch (rh->type) {
+        case handshake:
+        case change_cipher_spec:
+        case application_data:
+        case alert:
+            break;
+        case no_type:
+        default:
+            WOLFSSL_MSG("Unknown Record Type");
+            return UNKNOWN_RECORD_TYPE;
+    }
+
+    /* haven't decrypted this record yet */
+    ssl->keys.decryptedCur = 0;
+
+    return 0;
+}
+
+
+static int GetHandShakeHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                              byte *type, word32 *size, word32 totalSz)
+{
+    const byte *ptr = input + *inOutIdx;
+    (void)ssl;
+
+    *inOutIdx += HANDSHAKE_HEADER_SZ;
+    if (*inOutIdx > totalSz)
+        return BUFFER_E;
+
+    *type = ptr[0];
+    c24to32(&ptr[1], size);
+
+    return 0;
+}
+
+
+#ifdef WOLFSSL_DTLS
+static int GetDtlsHandShakeHeader(WOLFSSL* ssl, const byte* input,
+                                  word32* inOutIdx, byte *type, word32 *size,
+                                  word32 *fragOffset, word32 *fragSz,
+                                  word32 totalSz)
+{
+    word32 idx = *inOutIdx;
+
+    *inOutIdx += HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA;
+    if (*inOutIdx > totalSz)
+        return BUFFER_E;
+
+    *type = input[idx++];
+    c24to32(input + idx, size);
+    idx += BYTE3_LEN;
+
+    ato16(input + idx, &ssl->keys.dtls_peer_handshake_number);
+    idx += DTLS_HANDSHAKE_SEQ_SZ;
+
+    c24to32(input + idx, fragOffset);
+    idx += DTLS_HANDSHAKE_FRAG_SZ;
+    c24to32(input + idx, fragSz);
+
+    return 0;
+}
+#endif
+
+
+#ifndef NO_OLD_TLS
+/* fill with MD5 pad size since biggest required */
+static const byte PAD1[PAD_MD5] =
+                              { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+                                0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+                                0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+                                0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+                                0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+                                0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+                              };
+static const byte PAD2[PAD_MD5] =
+                              { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+                                0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+                                0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+                                0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+                                0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+                                0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+                              };
+
+/* calculate MD5 hash for finished */
+#ifdef WOLFSSL_TI_HASH
+#include <wolfssl/wolfcrypt/hash.h>
+#endif
+
+static void BuildMD5(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
+{
+
+    byte md5_result[MD5_DIGEST_SIZE];
+
+#ifdef WOLFSSL_SMALL_STACK
+        Md5* md5   = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        Md5* md5_2 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#else
+        Md5 md5[1];
+        Md5 md5_2[1];
+#endif
+
+    /* make md5 inner */
+    md5[0] = ssl->hsHashes->hashMd5 ; /* Save current position */
+
+    wc_Md5Update(&ssl->hsHashes->hashMd5, sender, SIZEOF_SENDER);
+    wc_Md5Update(&ssl->hsHashes->hashMd5, ssl->arrays->masterSecret,SECRET_LEN);
+    wc_Md5Update(&ssl->hsHashes->hashMd5, PAD1, PAD_MD5);
+    wc_Md5GetHash(&ssl->hsHashes->hashMd5, md5_result);
+    wc_Md5RestorePos(&ssl->hsHashes->hashMd5, md5) ; /* Restore current position */
+
+    /* make md5 outer */
+    wc_InitMd5(md5_2) ;
+    wc_Md5Update(md5_2, ssl->arrays->masterSecret,SECRET_LEN);
+    wc_Md5Update(md5_2, PAD2, PAD_MD5);
+    wc_Md5Update(md5_2, md5_result, MD5_DIGEST_SIZE);
+    wc_Md5Final(md5_2, hashes->md5);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(md5_2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+}
+
+
+/* calculate SHA hash for finished */
+static void BuildSHA(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
+{
+    byte sha_result[SHA_DIGEST_SIZE];
+
+#ifdef WOLFSSL_SMALL_STACK
+        Sha* sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        Sha* sha2 = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#else
+        Sha sha[1];
+        Sha sha2[1] ;
+#endif
+    /* make sha inner */
+    sha[0] = ssl->hsHashes->hashSha ; /* Save current position */
+
+    wc_ShaUpdate(&ssl->hsHashes->hashSha, sender, SIZEOF_SENDER);
+    wc_ShaUpdate(&ssl->hsHashes->hashSha, ssl->arrays->masterSecret,SECRET_LEN);
+    wc_ShaUpdate(&ssl->hsHashes->hashSha, PAD1, PAD_SHA);
+    wc_ShaGetHash(&ssl->hsHashes->hashSha, sha_result);
+    wc_ShaRestorePos(&ssl->hsHashes->hashSha, sha) ; /* Restore current position */
+
+    /* make sha outer */
+    wc_InitSha(sha2) ;
+    wc_ShaUpdate(sha2, ssl->arrays->masterSecret,SECRET_LEN);
+    wc_ShaUpdate(sha2, PAD2, PAD_SHA);
+    wc_ShaUpdate(sha2, sha_result, SHA_DIGEST_SIZE);
+    wc_ShaFinal(sha2, hashes->sha);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(sha2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+}
+#endif
+
+/* Finished doesn't support SHA512, not SHA512 cipher suites yet */
+static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
+{
+    int ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    #ifdef WOLFSSL_SHA384
+        Sha384* sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,                                                                        DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+#else
+    #ifdef WOLFSSL_SHA384
+        Sha384 sha384[1];
+    #endif
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    if (ssl == NULL
+    #ifdef WOLFSSL_SHA384
+        || sha384 == NULL
+    #endif
+        ) {
+    #ifdef WOLFSSL_SHA384
+        XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        return MEMORY_E;
+    }
+#endif
+
+    /* store current states, building requires get_digest which resets state */
+#ifdef WOLFSSL_SHA384
+    sha384[0] = ssl->hsHashes->hashSha384;
+#endif
+
+#ifndef NO_TLS
+    if (ssl->options.tls) {
+        ret = BuildTlsFinished(ssl, hashes, sender);
+    }
+#endif
+#ifndef NO_OLD_TLS
+    if (!ssl->options.tls) {
+        BuildMD5(ssl, hashes, sender);
+        BuildSHA(ssl, hashes, sender);
+    }
+#endif
+
+    /* restore */
+    if (IsAtLeastTLSv1_2(ssl)) {
+    #ifdef WOLFSSL_SHA384
+        ssl->hsHashes->hashSha384 = sha384[0];
+    #endif
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+#ifdef WOLFSSL_SHA384
+    XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+#endif
+
+    return ret;
+}
+
+
+    /* cipher requirements */
+    enum {
+        REQUIRES_RSA,
+        REQUIRES_DHE,
+        REQUIRES_ECC_DSA,
+        REQUIRES_ECC_STATIC,
+        REQUIRES_PSK,
+        REQUIRES_NTRU,
+        REQUIRES_RSA_SIG
+    };
+
+
+
+    /* Does this cipher suite (first, second) have the requirement
+       an ephemeral key exchange will still require the key for signing
+       the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */
+    static int CipherRequires(byte first, byte second, int requirement)
+    {
+
+        if (first == CHACHA_BYTE) {
+
+        switch (second) {
+
+        case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
+            if (requirement == REQUIRES_ECC_DSA)
+                return 1;
+            break;
+
+        case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+            }
+        }
+
+        /* ECC extensions */
+        if (first == ECC_BYTE) {
+
+        switch (second) {
+
+#ifndef NO_RSA
+        case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            break;
+
+#ifndef NO_DES3
+        case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            break;
+#endif
+
+#ifndef NO_RC4
+        case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_RSA_WITH_RC4_128_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            break;
+#endif
+#endif /* NO_RSA */
+
+#ifndef NO_DES3
+        case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
+            if (requirement == REQUIRES_ECC_DSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            break;
+#endif
+#ifndef NO_RC4
+        case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
+            if (requirement == REQUIRES_ECC_DSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            break;
+#endif
+#ifndef NO_RSA
+        case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            break;
+#endif
+
+        case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_ECC_DSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            break;
+
+        case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
+            if (requirement == REQUIRES_ECC_DSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            break;
+
+        case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
+            if (requirement == REQUIRES_ECC_DSA)
+                return 1;
+            break;
+
+        case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
+            if (requirement == REQUIRES_ECC_DSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            break;
+
+        case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            break;
+
+#ifndef NO_RSA
+        case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            break;
+
+        case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_AES_128_CCM_8 :
+        case TLS_RSA_WITH_AES_256_CCM_8 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            break;
+
+        case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
+        case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            break;
+
+        case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
+        case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            break;
+#endif
+
+        case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 :
+        case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
+            if (requirement == REQUIRES_ECC_DSA)
+                return 1;
+            break;
+
+        case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
+        case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
+            if (requirement == REQUIRES_ECC_DSA)
+                return 1;
+            break;
+
+        case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
+        case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
+            if (requirement == REQUIRES_ECC_DSA)
+                return 1;
+            if (requirement == REQUIRES_ECC_STATIC)
+                return 1;
+            break;
+
+        case TLS_PSK_WITH_AES_128_CCM:
+        case TLS_PSK_WITH_AES_256_CCM:
+        case TLS_PSK_WITH_AES_128_CCM_8:
+        case TLS_PSK_WITH_AES_256_CCM_8:
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            break;
+
+        case TLS_DHE_PSK_WITH_AES_128_CCM:
+        case TLS_DHE_PSK_WITH_AES_256_CCM:
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+
+        default:
+            WOLFSSL_MSG("Unsupported cipher suite, CipherRequires ECC");
+            return 0;
+        }   /* switch */
+        }   /* if     */
+        if (first != ECC_BYTE) {   /* normal suites */
+        switch (second) {
+
+#ifndef NO_RSA
+        case SSL_RSA_WITH_RC4_128_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case SSL_RSA_WITH_RC4_128_MD5 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_NTRU_RSA_WITH_RC4_128_SHA :
+            if (requirement == REQUIRES_NTRU)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_AES_128_CBC_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
+            if (requirement == REQUIRES_NTRU)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_AES_256_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_NTRU)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_AES_256_CBC_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_NULL_SHA :
+        case TLS_RSA_WITH_NULL_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
+            if (requirement == REQUIRES_NTRU)
+                return 1;
+            break;
+
+        case SSL_RSA_WITH_IDEA_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+#endif
+
+        case TLS_PSK_WITH_AES_128_GCM_SHA256 :
+        case TLS_PSK_WITH_AES_256_GCM_SHA384 :
+        case TLS_PSK_WITH_AES_128_CBC_SHA256 :
+        case TLS_PSK_WITH_AES_256_CBC_SHA384 :
+        case TLS_PSK_WITH_AES_128_CBC_SHA :
+        case TLS_PSK_WITH_AES_256_CBC_SHA :
+        case TLS_PSK_WITH_NULL_SHA384 :
+        case TLS_PSK_WITH_NULL_SHA256 :
+        case TLS_PSK_WITH_NULL_SHA :
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            break;
+
+        case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
+        case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
+        case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
+        case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
+        case TLS_DHE_PSK_WITH_NULL_SHA384 :
+        case TLS_DHE_PSK_WITH_NULL_SHA256 :
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            if (requirement == REQUIRES_PSK)
+                return 1;
+            break;
+
+#ifndef NO_RSA
+        case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+
+        case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+
+        case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+
+        case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_HC_128_MD5 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_HC_128_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_HC_128_B2B256:
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_AES_128_CBC_B2B256:
+        case TLS_RSA_WITH_AES_256_CBC_B2B256:
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_RABBIT_SHA :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_AES_128_GCM_SHA256 :
+        case TLS_RSA_WITH_AES_256_GCM_SHA384 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
+        case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+
+        case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
+        case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
+        case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
+        case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            break;
+
+        case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
+        case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
+        case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
+        case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
+            if (requirement == REQUIRES_RSA)
+                return 1;
+            if (requirement == REQUIRES_RSA_SIG)
+                return 1;
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+#endif
+#ifdef HAVE_ANON
+        case TLS_DH_anon_WITH_AES_128_CBC_SHA :
+            if (requirement == REQUIRES_DHE)
+                return 1;
+            break;
+#endif
+
+        default:
+            WOLFSSL_MSG("Unsupported cipher suite, CipherRequires");
+            return 0;
+        }  /* switch */
+        }  /* if ECC / Normal suites else */
+
+        return 0;
+    }
+
+
+#ifndef NO_CERTS
+
+
+/* Match names with wildcards, each wildcard can represent a single name
+   component or fragment but not mulitple names, i.e.,
+   *.z.com matches y.z.com but not x.y.z.com
+
+   return 1 on success */
+static int MatchDomainName(const char* pattern, int len, const char* str)
+{
+    char p, s;
+
+    if (pattern == NULL || str == NULL || len <= 0)
+        return 0;
+
+    while (len > 0) {
+
+        p = (char)XTOLOWER((unsigned char)*pattern++);
+        if (p == 0)
+            break;
+
+        if (p == '*') {
+            while (--len > 0 &&
+                         (p = (char)XTOLOWER((unsigned char)*pattern++)) == '*')
+                ;
+
+            if (len == 0)
+                p = '\0';
+
+            while ( (s = (char)XTOLOWER((unsigned char) *str)) != '\0') {
+                if (s == p)
+                    break;
+                if (s == '.')
+                    return 0;
+                str++;
+            }
+        }
+        else {
+            if (p != (char)XTOLOWER((unsigned char) *str))
+                return 0;
+        }
+
+        if (*str != '\0')
+            str++;
+
+        if (len > 0)
+            len--;
+    }
+
+    return *str == '\0';
+}
+
+
+/* try to find an altName match to domain, return 1 on success */
+static int CheckAltNames(DecodedCert* dCert, char* domain)
+{
+    int        match = 0;
+    DNS_entry* altName = NULL;
+
+    WOLFSSL_MSG("Checking AltNames");
+
+    if (dCert)
+        altName = dCert->altNames;
+
+    while (altName) {
+        WOLFSSL_MSG("    individual AltName check");
+
+        if (MatchDomainName(altName->name,(int)XSTRLEN(altName->name), domain)){
+            match = 1;
+            break;
+        }
+
+        altName = altName->next;
+    }
+
+    return match;
+}
+
+
+#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
+
+/* Copy parts X509 needs from Decoded cert, 0 on success */
+int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert)
+{
+    int ret = 0;
+
+    if (x509 == NULL || dCert == NULL)
+        return BAD_FUNC_ARG;
+
+    x509->version = dCert->version + 1;
+
+    XSTRNCPY(x509->issuer.name, dCert->issuer, ASN_NAME_MAX);
+    x509->issuer.name[ASN_NAME_MAX - 1] = '\0';
+    x509->issuer.sz = (int)XSTRLEN(x509->issuer.name) + 1;
+#ifdef OPENSSL_EXTRA
+    if (dCert->issuerName.fullName != NULL) {
+        XMEMCPY(&x509->issuer.fullName,
+                                       &dCert->issuerName, sizeof(DecodedName));
+        x509->issuer.fullName.fullName = (char*)XMALLOC(
+                        dCert->issuerName.fullNameLen, NULL, DYNAMIC_TYPE_X509);
+        if (x509->issuer.fullName.fullName != NULL)
+            XMEMCPY(x509->issuer.fullName.fullName,
+                     dCert->issuerName.fullName, dCert->issuerName.fullNameLen);
+    }
+#endif /* OPENSSL_EXTRA */
+
+    XSTRNCPY(x509->subject.name, dCert->subject, ASN_NAME_MAX);
+    x509->subject.name[ASN_NAME_MAX - 1] = '\0';
+    x509->subject.sz = (int)XSTRLEN(x509->subject.name) + 1;
+#ifdef OPENSSL_EXTRA
+    if (dCert->subjectName.fullName != NULL) {
+        XMEMCPY(&x509->subject.fullName,
+                                      &dCert->subjectName, sizeof(DecodedName));
+        x509->subject.fullName.fullName = (char*)XMALLOC(
+                       dCert->subjectName.fullNameLen, NULL, DYNAMIC_TYPE_X509);
+        if (x509->subject.fullName.fullName != NULL)
+            XMEMCPY(x509->subject.fullName.fullName,
+                   dCert->subjectName.fullName, dCert->subjectName.fullNameLen);
+    }
+#endif /* OPENSSL_EXTRA */
+
+    XMEMCPY(x509->serial, dCert->serial, EXTERNAL_SERIAL_SIZE);
+    x509->serialSz = dCert->serialSz;
+    if (dCert->subjectCNLen < ASN_NAME_MAX) {
+        XMEMCPY(x509->subjectCN, dCert->subjectCN, dCert->subjectCNLen);
+        x509->subjectCN[dCert->subjectCNLen] = '\0';
+    }
+    else
+        x509->subjectCN[0] = '\0';
+
+#ifdef WOLFSSL_SEP
+    {
+        int minSz = min(dCert->deviceTypeSz, EXTERNAL_SERIAL_SIZE);
+        if (minSz > 0) {
+            x509->deviceTypeSz = minSz;
+            XMEMCPY(x509->deviceType, dCert->deviceType, minSz);
+        }
+        else
+            x509->deviceTypeSz = 0;
+        minSz = min(dCert->hwTypeSz, EXTERNAL_SERIAL_SIZE);
+        if (minSz != 0) {
+            x509->hwTypeSz = minSz;
+            XMEMCPY(x509->hwType, dCert->hwType, minSz);
+        }
+        else
+            x509->hwTypeSz = 0;
+        minSz = min(dCert->hwSerialNumSz, EXTERNAL_SERIAL_SIZE);
+        if (minSz != 0) {
+            x509->hwSerialNumSz = minSz;
+            XMEMCPY(x509->hwSerialNum, dCert->hwSerialNum, minSz);
+        }
+        else
+            x509->hwSerialNumSz = 0;
+    }
+#endif /* WOLFSSL_SEP */
+    {
+        int minSz = min(dCert->beforeDateLen, MAX_DATE_SZ);
+        if (minSz != 0) {
+            x509->notBeforeSz = minSz;
+            XMEMCPY(x509->notBefore, dCert->beforeDate, minSz);
+        }
+        else
+            x509->notBeforeSz = 0;
+        minSz = min(dCert->afterDateLen, MAX_DATE_SZ);
+        if (minSz != 0) {
+            x509->notAfterSz = minSz;
+            XMEMCPY(x509->notAfter, dCert->afterDate, minSz);
+        }
+        else
+            x509->notAfterSz = 0;
+    }
+
+    if (dCert->publicKey != NULL && dCert->pubKeySize != 0) {
+        x509->pubKey.buffer = (byte*)XMALLOC(
+                              dCert->pubKeySize, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+        if (x509->pubKey.buffer != NULL) {
+            x509->pubKeyOID = dCert->keyOID;
+            x509->pubKey.length = dCert->pubKeySize;
+            XMEMCPY(x509->pubKey.buffer, dCert->publicKey, dCert->pubKeySize);
+        }
+        else
+            ret = MEMORY_E;
+    }
+
+    if (dCert->signature != NULL && dCert->sigLength != 0) {
+        x509->sig.buffer = (byte*)XMALLOC(
+                                dCert->sigLength, NULL, DYNAMIC_TYPE_SIGNATURE);
+        if (x509->sig.buffer == NULL) {
+            ret = MEMORY_E;
+        }
+        else {
+            XMEMCPY(x509->sig.buffer, dCert->signature, dCert->sigLength);
+            x509->sig.length = dCert->sigLength;
+            x509->sigOID = dCert->signatureOID;
+        }
+    }
+
+    /* store cert for potential retrieval */
+    x509->derCert.buffer = (byte*)XMALLOC(dCert->maxIdx, NULL,
+                                          DYNAMIC_TYPE_CERT);
+    if (x509->derCert.buffer == NULL) {
+        ret = MEMORY_E;
+    }
+    else {
+        XMEMCPY(x509->derCert.buffer, dCert->source, dCert->maxIdx);
+        x509->derCert.length = dCert->maxIdx;
+    }
+
+    x509->altNames       = dCert->altNames;
+    dCert->weOwnAltNames = 0;
+    x509->altNamesNext   = x509->altNames;  /* index hint */
+
+    x509->isCa = dCert->isCA;
+#ifdef OPENSSL_EXTRA
+    x509->pathLength = dCert->pathLength;
+    x509->keyUsage = dCert->extKeyUsage;
+
+    x509->basicConstSet = dCert->extBasicConstSet;
+    x509->basicConstCrit = dCert->extBasicConstCrit;
+    x509->basicConstPlSet = dCert->extBasicConstPlSet;
+    x509->subjAltNameSet = dCert->extSubjAltNameSet;
+    x509->subjAltNameCrit = dCert->extSubjAltNameCrit;
+    x509->authKeyIdSet = dCert->extAuthKeyIdSet;
+    x509->authKeyIdCrit = dCert->extAuthKeyIdCrit;
+    if (dCert->extAuthKeyIdSrc != NULL && dCert->extAuthKeyIdSz != 0) {
+        x509->authKeyId = (byte*)XMALLOC(dCert->extAuthKeyIdSz, NULL, 0);
+        if (x509->authKeyId != NULL) {
+            XMEMCPY(x509->authKeyId,
+                                 dCert->extAuthKeyIdSrc, dCert->extAuthKeyIdSz);
+            x509->authKeyIdSz = dCert->extAuthKeyIdSz;
+        }
+        else
+            ret = MEMORY_E;
+    }
+    x509->subjKeyIdSet = dCert->extSubjKeyIdSet;
+    x509->subjKeyIdCrit = dCert->extSubjKeyIdCrit;
+    if (dCert->extSubjKeyIdSrc != NULL && dCert->extSubjKeyIdSz != 0) {
+        x509->subjKeyId = (byte*)XMALLOC(dCert->extSubjKeyIdSz, NULL, 0);
+        if (x509->subjKeyId != NULL) {
+            XMEMCPY(x509->subjKeyId,
+                                 dCert->extSubjKeyIdSrc, dCert->extSubjKeyIdSz);
+            x509->subjKeyIdSz = dCert->extSubjKeyIdSz;
+        }
+        else
+            ret = MEMORY_E;
+    }
+    x509->keyUsageSet = dCert->extKeyUsageSet;
+    x509->keyUsageCrit = dCert->extKeyUsageCrit;
+    #ifdef WOLFSSL_SEP
+        x509->certPolicySet = dCert->extCertPolicySet;
+        x509->certPolicyCrit = dCert->extCertPolicyCrit;
+    #endif /* WOLFSSL_SEP */
+#endif /* OPENSSL_EXTRA */
+#ifdef HAVE_ECC
+    x509->pkCurveOID = dCert->pkCurveOID;
+#endif /* HAVE_ECC */
+
+    return ret;
+}
+
+#endif /* KEEP_PEER_CERT || SESSION_CERTS */
+
+
+static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                                                                    word32 size)
+{
+    word32 listSz;
+    word32 begin = *inOutIdx;
+    int    ret = 0;
+    int    anyError = 0;
+    int    totalCerts = 0;    /* number of certs in certs buffer */
+    int    count;
+    buffer certs[MAX_CHAIN_DEPTH];
+
+#ifdef WOLFSSL_SMALL_STACK
+    char*                  domain = NULL;
+    DecodedCert*           dCert  = NULL;
+    WOLFSSL_X509_STORE_CTX* store  = NULL;
+#else
+    char                   domain[ASN_NAME_MAX];
+    DecodedCert            dCert[1];
+    WOLFSSL_X509_STORE_CTX  store[1];
+#endif
+
+    #ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
+        if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo);
+    #endif
+
+    if ((*inOutIdx - begin) + OPAQUE24_LEN > size)
+        return BUFFER_ERROR;
+
+    c24to32(input + *inOutIdx, &listSz);
+    *inOutIdx += OPAQUE24_LEN;
+
+    if (listSz > MAX_RECORD_SIZE)
+        return BUFFER_E;
+
+    if ((*inOutIdx - begin) + listSz != size)
+        return BUFFER_ERROR;
+
+    WOLFSSL_MSG("Loading peer's cert chain");
+    /* first put cert chain into buffer so can verify top down
+       we're sent bottom up */
+    while (listSz) {
+        word32 certSz;
+
+        if (totalCerts >= MAX_CHAIN_DEPTH)
+            return MAX_CHAIN_ERROR;
+
+        if ((*inOutIdx - begin) + OPAQUE24_LEN > size)
+            return BUFFER_ERROR;
+
+        c24to32(input + *inOutIdx, &certSz);
+        *inOutIdx += OPAQUE24_LEN;
+
+        if ((*inOutIdx - begin) + certSz > size)
+            return BUFFER_ERROR;
+
+        certs[totalCerts].length = certSz;
+        certs[totalCerts].buffer = input + *inOutIdx;
+
+#ifdef SESSION_CERTS
+        if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
+                                       certSz < MAX_X509_SIZE) {
+            ssl->session.chain.certs[ssl->session.chain.count].length = certSz;
+            XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
+                    input + *inOutIdx, certSz);
+            ssl->session.chain.count++;
+        } else {
+            WOLFSSL_MSG("Couldn't store chain cert for session");
+        }
+#endif
+
+        *inOutIdx += certSz;
+        listSz -= certSz + CERT_HEADER_SZ;
+
+        totalCerts++;
+        WOLFSSL_MSG("    Put another cert into chain");
+    }
+
+    count = totalCerts;
+
+#ifdef WOLFSSL_SMALL_STACK
+    dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (dCert == NULL)
+        return MEMORY_E;
+#endif
+
+    /* verify up to peer's first */
+    while (count > 1) {
+        buffer myCert = certs[count - 1];
+        byte* subjectHash;
+
+        InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap);
+        ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone,
+                                ssl->ctx->cm);
+        #ifndef NO_SKID
+            subjectHash = dCert->extSubjKeyId;
+        #else
+            subjectHash = dCert->subjectHash;
+        #endif
+
+        if (ret == 0 && dCert->isCA == 0) {
+            WOLFSSL_MSG("Chain cert is not a CA, not adding as one");
+        }
+        else if (ret == 0 && ssl->options.verifyNone) {
+            WOLFSSL_MSG("Chain cert not verified by option, not adding as CA");
+        }
+        else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, subjectHash)) {
+            buffer add;
+            add.length = myCert.length;
+            add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
+                                        DYNAMIC_TYPE_CA);
+            WOLFSSL_MSG("Adding CA from chain");
+
+            if (add.buffer == NULL)
+                return MEMORY_E;
+            XMEMCPY(add.buffer, myCert.buffer, myCert.length);
+
+            /* already verified above */
+            ret = AddCA(ssl->ctx->cm, add, WOLFSSL_CHAIN_CA, 0);
+            if (ret == 1) ret = 0;   /* SSL_SUCCESS for external */
+        }
+        else if (ret != 0) {
+            WOLFSSL_MSG("Failed to verify CA from chain");
+        }
+        else {
+            WOLFSSL_MSG("Verified CA from chain and already had it");
+        }
+
+#if defined(HAVE_OCSP) || defined(HAVE_CRL)
+        if (ret == 0) {
+            int doCrlLookup = 1;
+            (void)doCrlLookup;
+#ifdef HAVE_OCSP
+            if (ssl->ctx->cm->ocspEnabled && ssl->ctx->cm->ocspCheckAll) {
+                WOLFSSL_MSG("Doing Non Leaf OCSP check");
+                ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert);
+                doCrlLookup = (ret == OCSP_CERT_UNKNOWN);
+                if (ret != 0) {
+                    doCrlLookup = 0;
+                    WOLFSSL_MSG("\tOCSP Lookup not ok");
+                }
+            }
+#endif /* HAVE_OCSP */
+
+#ifdef HAVE_CRL
+            if (doCrlLookup && ssl->ctx->cm->crlEnabled
+                                                 && ssl->ctx->cm->crlCheckAll) {
+                WOLFSSL_MSG("Doing Non Leaf CRL check");
+                ret = CheckCertCRL(ssl->ctx->cm->crl, dCert);
+
+                if (ret != 0) {
+                    WOLFSSL_MSG("\tCRL check not ok");
+                }
+            }
+#endif /* HAVE_CRL */
+        }
+#endif /* HAVE_OCSP || HAVE_CRL */
+
+        if (ret != 0 && anyError == 0)
+            anyError = ret;   /* save error from last time */
+
+        FreeDecodedCert(dCert);
+        count--;
+    }
+
+    /* peer's, may not have one if blank client cert sent by TLSv1.2 */
+    if (count) {
+        buffer myCert = certs[0];
+        int    fatal  = 0;
+
+        WOLFSSL_MSG("Verifying Peer's cert");
+
+        InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap);
+        ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone,
+                                ssl->ctx->cm);
+        if (ret == 0) {
+            WOLFSSL_MSG("Verified Peer's cert");
+            fatal = 0;
+        }
+        else if (ret == ASN_PARSE_E) {
+            WOLFSSL_MSG("Got Peer cert ASN PARSE ERROR, fatal");
+            fatal = 1;
+        }
+        else {
+            WOLFSSL_MSG("Failed to verify Peer's cert");
+            if (ssl->verifyCallback) {
+                WOLFSSL_MSG("\tCallback override available, will continue");
+                fatal = 0;
+            }
+            else {
+                WOLFSSL_MSG("\tNo callback override available, fatal");
+                fatal = 1;
+            }
+        }
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+        if (fatal == 0 && ssl->secure_renegotiation
+                       && ssl->secure_renegotiation->enabled) {
+
+            if (ssl->keys.encryptionOn) {
+                /* compare against previous time */
+                if (XMEMCMP(dCert->subjectHash,
+                            ssl->secure_renegotiation->subject_hash,
+                            SHA_DIGEST_SIZE) != 0) {
+                    WOLFSSL_MSG("Peer sent different cert during scr, fatal");
+                    fatal = 1;
+                    ret   = SCR_DIFFERENT_CERT_E;
+                }
+            }
+
+            /* cache peer's hash */
+            if (fatal == 0) {
+                XMEMCPY(ssl->secure_renegotiation->subject_hash,
+                        dCert->subjectHash, SHA_DIGEST_SIZE);
+            }
+        }
+#endif
+
+#if defined(HAVE_OCSP) || defined(HAVE_CRL)
+        if (fatal == 0) {
+            int doCrlLookup = 1;
+            (void)doCrlLookup;
+#ifdef HAVE_OCSP
+            if (ssl->ctx->cm->ocspEnabled) {
+                ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert);
+                doCrlLookup = (ret == OCSP_CERT_UNKNOWN);
+                if (ret != 0) {
+                    WOLFSSL_MSG("\tOCSP Lookup not ok");
+                    fatal = 0;
+                }
+            }
+#endif /* HAVE_OCSP */
+
+#ifdef HAVE_CRL
+            if (doCrlLookup && ssl->ctx->cm->crlEnabled) {
+                WOLFSSL_MSG("Doing Leaf CRL check");
+                ret = CheckCertCRL(ssl->ctx->cm->crl, dCert);
+                if (ret != 0) {
+                    WOLFSSL_MSG("\tCRL check not ok");
+                    fatal = 0;
+                }
+            }
+#endif /* HAVE_CRL */
+        }
+#endif /* HAVE_OCSP || HAVE_CRL */
+
+#ifdef KEEP_PEER_CERT
+        {
+        /* set X509 format for peer cert even if fatal */
+        int copyRet = CopyDecodedToX509(&ssl->peerCert, dCert);
+        if (copyRet == MEMORY_E)
+            fatal = 1;
+        }
+#endif
+
+#ifndef IGNORE_KEY_EXTENSIONS
+        if (dCert->extKeyUsageSet) {
+            if ((ssl->specs.kea == rsa_kea) &&
+                (dCert->extKeyUsage & KEYUSE_KEY_ENCIPHER) == 0) {
+                ret = KEYUSE_ENCIPHER_E;
+            }
+            if ((ssl->specs.sig_algo == rsa_sa_algo ||
+                    (ssl->specs.sig_algo == ecc_dsa_sa_algo &&
+                         !ssl->specs.static_ecdh)) &&
+                (dCert->extKeyUsage & KEYUSE_DIGITAL_SIG) == 0) {
+                WOLFSSL_MSG("KeyUse Digital Sig not set");
+                ret = KEYUSE_SIGNATURE_E;
+            }
+        }
+
+        if (dCert->extExtKeyUsageSet) {
+            if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                if ((dCert->extExtKeyUsage &
+                        (EXTKEYUSE_ANY | EXTKEYUSE_SERVER_AUTH)) == 0) {
+                    WOLFSSL_MSG("ExtKeyUse Server Auth not set");
+                    ret = EXTKEYUSE_AUTH_E;
+                }
+            }
+            else {
+                if ((dCert->extExtKeyUsage &
+                        (EXTKEYUSE_ANY | EXTKEYUSE_CLIENT_AUTH)) == 0) {
+                    WOLFSSL_MSG("ExtKeyUse Client Auth not set");
+                    ret = EXTKEYUSE_AUTH_E;
+                }
+            }
+        }
+#endif /* IGNORE_KEY_EXTENSIONS */
+
+        if (fatal) {
+            FreeDecodedCert(dCert);
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+            ssl->error = ret;
+            return ret;
+        }
+        ssl->options.havePeerCert = 1;
+
+#ifdef WOLFSSL_SMALL_STACK
+        domain = (char*)XMALLOC(ASN_NAME_MAX, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (domain == NULL) {
+            FreeDecodedCert(dCert);
+            XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return MEMORY_E;
+        }
+#endif
+        /* store for callback use */
+        if (dCert->subjectCNLen < ASN_NAME_MAX) {
+            XMEMCPY(domain, dCert->subjectCN, dCert->subjectCNLen);
+            domain[dCert->subjectCNLen] = '\0';
+        }
+        else
+            domain[0] = '\0';
+
+        if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) {
+            if (MatchDomainName(dCert->subjectCN, dCert->subjectCNLen,
+                                (char*)ssl->buffers.domainName.buffer) == 0) {
+                WOLFSSL_MSG("DomainName match on common name failed");
+                if (CheckAltNames(dCert,
+                                 (char*)ssl->buffers.domainName.buffer) == 0 ) {
+                    WOLFSSL_MSG("DomainName match on alt names failed too");
+                    ret = DOMAIN_NAME_MISMATCH; /* try to get peer key still */
+                }
+            }
+        }
+
+        /* decode peer key */
+        switch (dCert->keyOID) {
+        #ifndef NO_RSA
+            case RSAk:
+                {
+                    word32 idx = 0;
+                    int    keyRet = 0;
+
+                    if (ssl->peerRsaKey == NULL) {
+                        ssl->peerRsaKey = (RsaKey*)XMALLOC(sizeof(RsaKey),
+                                                   ssl->heap, DYNAMIC_TYPE_RSA);
+                        if (ssl->peerRsaKey == NULL) {
+                            WOLFSSL_MSG("PeerRsaKey Memory error");
+                            keyRet = MEMORY_E;
+                        } else {
+                            keyRet = wc_InitRsaKey(ssl->peerRsaKey,
+                                                   ssl->ctx->heap);
+                        }
+                    } else if (ssl->peerRsaKeyPresent) {
+                        /* don't leak on reuse */
+                        wc_FreeRsaKey(ssl->peerRsaKey);
+                        ssl->peerRsaKeyPresent = 0;
+                        keyRet = wc_InitRsaKey(ssl->peerRsaKey, ssl->heap);
+                    }
+
+                    if (keyRet != 0 || wc_RsaPublicKeyDecode(dCert->publicKey,
+                               &idx, ssl->peerRsaKey, dCert->pubKeySize) != 0) {
+                        ret = PEER_KEY_ERROR;
+                    }
+                    else {
+                        ssl->peerRsaKeyPresent = 1;
+                        #ifdef HAVE_PK_CALLBACKS
+                            #ifndef NO_RSA
+                                ssl->buffers.peerRsaKey.buffer =
+                                       (byte*)XMALLOC(dCert->pubKeySize,
+                                               ssl->heap, DYNAMIC_TYPE_RSA);
+                                if (ssl->buffers.peerRsaKey.buffer == NULL)
+                                    ret = MEMORY_ERROR;
+                                else {
+                                    XMEMCPY(ssl->buffers.peerRsaKey.buffer,
+                                           dCert->publicKey, dCert->pubKeySize);
+                                    ssl->buffers.peerRsaKey.length =
+                                            dCert->pubKeySize;
+                                }
+                            #endif /* NO_RSA */
+                        #endif /*HAVE_PK_CALLBACKS */
+                    }
+                }
+                break;
+        #endif /* NO_RSA */
+        #ifdef HAVE_NTRU
+            case NTRUk:
+                {
+                    if (dCert->pubKeySize > sizeof(ssl->peerNtruKey)) {
+                        ret = PEER_KEY_ERROR;
+                    }
+                    else {
+                        XMEMCPY(ssl->peerNtruKey, dCert->publicKey,
+                                                             dCert->pubKeySize);
+                        ssl->peerNtruKeyLen = (word16)dCert->pubKeySize;
+                        ssl->peerNtruKeyPresent = 1;
+                    }
+                }
+                break;
+        #endif /* HAVE_NTRU */
+        #ifdef HAVE_ECC
+            case ECDSAk:
+                {
+                    if (ssl->peerEccDsaKey == NULL) {
+                        /* alloc/init on demand */
+                        ssl->peerEccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
+                                              ssl->ctx->heap, DYNAMIC_TYPE_ECC);
+                        if (ssl->peerEccDsaKey == NULL) {
+                            WOLFSSL_MSG("PeerEccDsaKey Memory error");
+                            return MEMORY_E;
+                        }
+                        wc_ecc_init(ssl->peerEccDsaKey);
+                    } else if (ssl->peerEccDsaKeyPresent) {
+                        /* don't leak on reuse */
+                        wc_ecc_free(ssl->peerEccDsaKey);
+                        ssl->peerEccDsaKeyPresent = 0;
+                        wc_ecc_init(ssl->peerEccDsaKey);
+                    }
+                    if (wc_ecc_import_x963(dCert->publicKey, dCert->pubKeySize,
+                                        ssl->peerEccDsaKey) != 0) {
+                        ret = PEER_KEY_ERROR;
+                    }
+                    else {
+                        ssl->peerEccDsaKeyPresent = 1;
+                        #ifdef HAVE_PK_CALLBACKS
+                            #ifdef HAVE_ECC
+                                ssl->buffers.peerEccDsaKey.buffer =
+                                       (byte*)XMALLOC(dCert->pubKeySize,
+                                               ssl->heap, DYNAMIC_TYPE_ECC);
+                                if (ssl->buffers.peerEccDsaKey.buffer == NULL)
+                                    ret = MEMORY_ERROR;
+                                else {
+                                    XMEMCPY(ssl->buffers.peerEccDsaKey.buffer,
+                                           dCert->publicKey, dCert->pubKeySize);
+                                    ssl->buffers.peerEccDsaKey.length =
+                                            dCert->pubKeySize;
+                                }
+                            #endif /* HAVE_ECC */
+                        #endif /*HAVE_PK_CALLBACKS */
+                    }
+                }
+                break;
+        #endif /* HAVE_ECC */
+            default:
+                break;
+        }
+
+        FreeDecodedCert(dCert);
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    store = (WOLFSSL_X509_STORE_CTX*)XMALLOC(sizeof(WOLFSSL_X509_STORE_CTX),
+                                                 NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (store == NULL) {
+        XFREE(domain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    if (anyError != 0 && ret == 0)
+        ret = anyError;
+
+    if (ret != 0) {
+        if (!ssl->options.verifyNone) {
+            int why = bad_certificate;
+
+            if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E)
+                why = certificate_expired;
+            if (ssl->verifyCallback) {
+                int ok;
+
+                store->error = ret;
+                store->error_depth = totalCerts;
+                store->discardSessionCerts = 0;
+                store->domain = domain;
+                store->userCtx = ssl->verifyCbCtx;
+#ifdef KEEP_PEER_CERT
+                store->current_cert = &ssl->peerCert;
+#else
+                store->current_cert = NULL;
+#endif
+#if defined(HAVE_FORTRESS) || defined(HAVE_STUNNEL)
+                store->ex_data = ssl;
+#endif
+                ok = ssl->verifyCallback(0, store);
+                if (ok) {
+                    WOLFSSL_MSG("Verify callback overriding error!");
+                    ret = 0;
+                }
+                #ifdef SESSION_CERTS
+                if (store->discardSessionCerts) {
+                    WOLFSSL_MSG("Verify callback requested discard sess certs");
+                    ssl->session.chain.count = 0;
+                }
+                #endif
+            }
+            if (ret != 0) {
+                SendAlert(ssl, alert_fatal, why);   /* try to send */
+                ssl->options.isClosed = 1;
+            }
+        }
+        ssl->error = ret;
+    }
+#ifdef WOLFSSL_ALWAYS_VERIFY_CB
+    else {
+        if (ssl->verifyCallback) {
+            int ok;
+
+            store->error = ret;
+            store->error_depth = totalCerts;
+            store->discardSessionCerts = 0;
+            store->domain = domain;
+            store->userCtx = ssl->verifyCbCtx;
+#ifdef KEEP_PEER_CERT
+            store->current_cert = &ssl->peerCert;
+#endif
+            store->ex_data = ssl;
+
+            ok = ssl->verifyCallback(1, store);
+            if (!ok) {
+                WOLFSSL_MSG("Verify callback overriding valid certificate!");
+                ret = -1;
+                SendAlert(ssl, alert_fatal, bad_certificate);
+                ssl->options.isClosed = 1;
+            }
+            #ifdef SESSION_CERTS
+            if (store->discardSessionCerts) {
+                WOLFSSL_MSG("Verify callback requested discard sess certs");
+                ssl->session.chain.count = 0;
+            }
+            #endif
+        }
+    }
+#endif
+
+    if (ssl->options.verifyNone &&
+                              (ret == CRL_MISSING || ret == CRL_CERT_REVOKED)) {
+        WOLFSSL_MSG("Ignoring CRL problem based on verify setting");
+        ret = ssl->error = 0;
+    }
+
+    if (ret == 0 && ssl->options.side == WOLFSSL_CLIENT_END)
+        ssl->options.serverState = SERVER_CERT_COMPLETE;
+
+    if (ssl->keys.encryptionOn) {
+        *inOutIdx += ssl->keys.padSz;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(store,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(domain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+#endif /* !NO_CERTS */
+
+
+static int DoHelloRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                                                    word32 size, word32 totalSz)
+{
+    (void)input;
+
+    if (size) /* must be 0 */
+        return BUFFER_ERROR;
+
+    if (ssl->keys.encryptionOn) {
+        /* access beyond input + size should be checked against totalSz */
+        if (*inOutIdx + ssl->keys.padSz > totalSz)
+            return BUFFER_E;
+
+        *inOutIdx += ssl->keys.padSz;
+    }
+
+    if (ssl->options.side == WOLFSSL_SERVER_END) {
+        SendAlert(ssl, alert_fatal, unexpected_message); /* try */
+        return FATAL_ERROR;
+    }
+#ifdef HAVE_SECURE_RENEGOTIATION
+    else if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
+        ssl->secure_renegotiation->startScr = 1;
+        return 0;
+    }
+#endif
+    else {
+        return SendAlert(ssl, alert_warning, no_renegotiation);
+    }
+}
+
+
+int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size,
+                                                      word32 totalSz, int sniff)
+{
+    word32 finishedSz = (ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ);
+
+    if (finishedSz != size)
+        return BUFFER_ERROR;
+
+    /* check against totalSz */
+    if (*inOutIdx + size + ssl->keys.padSz > totalSz)
+        return BUFFER_E;
+
+    #ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
+        if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
+    #endif
+
+    if (sniff == NO_SNIFF) {
+        if (XMEMCMP(input + *inOutIdx, &ssl->hsHashes->verifyHashes,size) != 0){
+            WOLFSSL_MSG("Verify finished error on hashes");
+            return VERIFY_FINISHED_ERROR;
+        }
+    }
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+    if (ssl->secure_renegotiation) {
+        /* save peer's state */
+        if (ssl->options.side == WOLFSSL_CLIENT_END)
+            XMEMCPY(ssl->secure_renegotiation->server_verify_data,
+                    input + *inOutIdx, TLS_FINISHED_SZ);
+        else
+            XMEMCPY(ssl->secure_renegotiation->client_verify_data,
+                    input + *inOutIdx, TLS_FINISHED_SZ);
+    }
+#endif
+
+    /* force input exhaustion at ProcessReply consuming padSz */
+    *inOutIdx += size + ssl->keys.padSz;
+
+    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+        ssl->options.serverState = SERVER_FINISHED_COMPLETE;
+        if (!ssl->options.resuming) {
+            ssl->options.handShakeState = HANDSHAKE_DONE;
+            ssl->options.handShakeDone  = 1;
+
+#ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                /* Other side has received our Finished, go to next epoch */
+                ssl->keys.dtls_epoch++;
+                ssl->keys.dtls_sequence_number = 1;
+            }
+#endif
+        }
+    }
+    else {
+        ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
+        if (ssl->options.resuming) {
+            ssl->options.handShakeState = HANDSHAKE_DONE;
+            ssl->options.handShakeDone  = 1;
+
+#ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                /* Other side has received our Finished, go to next epoch */
+                ssl->keys.dtls_epoch++;
+                ssl->keys.dtls_sequence_number = 1;
+            }
+#endif
+        }
+    }
+
+    return 0;
+}
+
+
+/* Make sure no duplicates, no fast forward, or other problems; 0 on success */
+static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
+{
+    /* verify not a duplicate, mark received, check state */
+    switch (type) {
+
+#ifndef NO_WOLFSSL_CLIENT
+        case hello_request:
+            if (ssl->msgsReceived.got_hello_request) {
+                WOLFSSL_MSG("Duplicate HelloRequest received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_hello_request = 1;
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_SERVER
+        case client_hello:
+            if (ssl->msgsReceived.got_client_hello) {
+                WOLFSSL_MSG("Duplicate ClientHello received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_client_hello = 1;
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+        case server_hello:
+            if (ssl->msgsReceived.got_server_hello) {
+                WOLFSSL_MSG("Duplicate ServerHello received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_server_hello = 1;
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+        case hello_verify_request:
+            if (ssl->msgsReceived.got_hello_verify_request) {
+                WOLFSSL_MSG("Duplicate HelloVerifyRequest received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_hello_verify_request = 1;
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+        case session_ticket:
+            if (ssl->msgsReceived.got_session_ticket) {
+                WOLFSSL_MSG("Duplicate SessionTicket received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_session_ticket = 1;
+
+            break;
+#endif
+
+        case certificate:
+            if (ssl->msgsReceived.got_certificate) {
+                WOLFSSL_MSG("Duplicate Certificate received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_certificate = 1;
+
+#ifndef NO_WOLFSSL_CLIENT
+            if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                if ( ssl->msgsReceived.got_server_hello == 0) {
+                    WOLFSSL_MSG("No ServerHello before Cert");
+                    return OUT_OF_ORDER_E;
+                }
+            }
+#endif
+#ifndef NO_WOLFSSL_SERVER
+            if (ssl->options.side == WOLFSSL_SERVER_END) {
+                if ( ssl->msgsReceived.got_client_hello == 0) {
+                    WOLFSSL_MSG("No ClientHello before Cert");
+                    return OUT_OF_ORDER_E;
+                }
+            }
+#endif
+            break;
+
+#ifndef NO_WOLFSSL_CLIENT
+        case server_key_exchange:
+            if (ssl->msgsReceived.got_server_key_exchange) {
+                WOLFSSL_MSG("Duplicate ServerKeyExchange received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_server_key_exchange = 1;
+
+            if ( ssl->msgsReceived.got_server_hello == 0) {
+                WOLFSSL_MSG("No ServerHello before Cert");
+                return OUT_OF_ORDER_E;
+            }
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+        case certificate_request:
+            if (ssl->msgsReceived.got_certificate_request) {
+                WOLFSSL_MSG("Duplicate CertificateRequest received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_certificate_request = 1;
+
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+        case server_hello_done:
+            if (ssl->msgsReceived.got_server_hello_done) {
+                WOLFSSL_MSG("Duplicate ServerHelloDone received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_server_hello_done = 1;
+
+            if (ssl->msgsReceived.got_certificate == 0) {
+                if (ssl->specs.kea == psk_kea ||
+                    ssl->specs.kea == dhe_psk_kea ||
+                    ssl->options.usingAnon_cipher) {
+                    WOLFSSL_MSG("No Cert required");
+                } else {
+                    WOLFSSL_MSG("No Certificate before ServerHelloDone");
+                    return OUT_OF_ORDER_E;
+                }
+            }
+            if (ssl->msgsReceived.got_server_key_exchange == 0) {
+                int pskNoServerHint = 0;  /* not required in this case */
+
+                #ifndef NO_PSK
+                    if (ssl->specs.kea == psk_kea &&
+                                               ssl->arrays->server_hint[0] == 0)
+                        pskNoServerHint = 1;
+                #endif
+                if (ssl->specs.static_ecdh == 1 ||
+                    ssl->specs.kea == rsa_kea ||
+                    ssl->specs.kea == ntru_kea ||
+                    pskNoServerHint) {
+                    WOLFSSL_MSG("No KeyExchange required");
+                } else {
+                    WOLFSSL_MSG("No ServerKeyExchange before ServerDone");
+                    return OUT_OF_ORDER_E;
+                }
+            }
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_SERVER
+        case certificate_verify:
+            if (ssl->msgsReceived.got_certificate_verify) {
+                WOLFSSL_MSG("Duplicate CertificateVerify received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_certificate_verify = 1;
+
+            if ( ssl->msgsReceived.got_certificate == 0) {
+                WOLFSSL_MSG("No Cert before CertVerify");
+                return OUT_OF_ORDER_E;
+            }
+            break;
+#endif
+
+#ifndef NO_WOLFSSL_SERVER
+        case client_key_exchange:
+            if (ssl->msgsReceived.got_client_key_exchange) {
+                WOLFSSL_MSG("Duplicate ClientKeyExchange received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_client_key_exchange = 1;
+
+            if (ssl->msgsReceived.got_client_hello == 0) {
+                WOLFSSL_MSG("No ClientHello before ClientKeyExchange");
+                return OUT_OF_ORDER_E;
+            }
+            break;
+#endif
+
+        case finished:
+            if (ssl->msgsReceived.got_finished) {
+                WOLFSSL_MSG("Duplicate Finished received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_finished = 1;
+
+            if (ssl->msgsReceived.got_change_cipher == 0) {
+                WOLFSSL_MSG("Finished received before ChangeCipher");
+                return NO_CHANGE_CIPHER_E;
+            }
+
+            break;
+
+        case change_cipher_hs:
+            if (ssl->msgsReceived.got_change_cipher) {
+                WOLFSSL_MSG("Duplicate ChangeCipher received");
+                return DUPLICATE_MSG_E;
+            }
+            ssl->msgsReceived.got_change_cipher = 1;
+
+#ifndef NO_WOLFSSL_CLIENT
+            if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                if (!ssl->options.resuming &&
+                                 ssl->msgsReceived.got_server_hello_done == 0) {
+                    WOLFSSL_MSG("No ServerHelloDone before ChangeCipher");
+                    return OUT_OF_ORDER_E;
+                }
+            }
+#endif
+#ifndef NO_WOLFSSL_SERVER
+            if (ssl->options.side == WOLFSSL_SERVER_END) {
+                if (!ssl->options.resuming &&
+                               ssl->msgsReceived.got_client_key_exchange == 0) {
+                    WOLFSSL_MSG("No ClientKeyExchange before ChangeCipher");
+                    return OUT_OF_ORDER_E;
+                }
+            }
+#endif
+
+            break;
+
+        default:
+            WOLFSSL_MSG("Unknown message type");
+            return SANITY_MSG_E;
+    }
+
+    return 0;
+}
+
+
+static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                          byte type, word32 size, word32 totalSz)
+{
+    int ret = 0;
+    (void)totalSz;
+
+    WOLFSSL_ENTER("DoHandShakeMsgType");
+
+    /* make sure can read the message */
+    if (*inOutIdx + size > totalSz)
+        return INCOMPLETE_DATA;
+
+    /* sanity check msg received */
+    if ( (ret = SanityCheckMsgReceived(ssl, type)) != 0) {
+        WOLFSSL_MSG("Sanity Check on handshake message type received failed");
+        return ret;
+    }
+
+#ifdef WOLFSSL_CALLBACKS
+    /* add name later, add on record and handshake header part back on */
+    if (ssl->toInfoOn) {
+        int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+        AddPacketInfo(0, &ssl->timeoutInfo, input + *inOutIdx - add,
+                      size + add, ssl->heap);
+        AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
+    }
+#endif
+
+    if (ssl->options.handShakeState == HANDSHAKE_DONE && type != hello_request){
+        WOLFSSL_MSG("HandShake message after handshake complete");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return OUT_OF_ORDER_E;
+    }
+
+    if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls == 0 &&
+               ssl->options.serverState == NULL_STATE && type != server_hello) {
+        WOLFSSL_MSG("First server message not server hello");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return OUT_OF_ORDER_E;
+    }
+
+    if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls &&
+            type == server_hello_done &&
+            ssl->options.serverState < SERVER_HELLO_COMPLETE) {
+        WOLFSSL_MSG("Server hello done received before server hello in DTLS");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return OUT_OF_ORDER_E;
+    }
+
+    if (ssl->options.side == WOLFSSL_SERVER_END &&
+               ssl->options.clientState == NULL_STATE && type != client_hello) {
+        WOLFSSL_MSG("First client message not client hello");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return OUT_OF_ORDER_E;
+    }
+
+    /* above checks handshake state */
+    /* hello_request not hashed */
+    /* Also, skip hashing the client_hello message here for DTLS. It will be
+     * hashed later if the DTLS cookie is correct. */
+    if (type != hello_request && !(ssl->options.dtls && type == client_hello)) {
+        ret = HashInput(ssl, input + *inOutIdx, size);
+        if (ret != 0) return ret;
+    }
+
+    switch (type) {
+
+    case hello_request:
+        WOLFSSL_MSG("processing hello request");
+        ret = DoHelloRequest(ssl, input, inOutIdx, size, totalSz);
+        break;
+
+#ifndef NO_WOLFSSL_CLIENT
+    case hello_verify_request:
+        WOLFSSL_MSG("processing hello verify request");
+        ret = DoHelloVerifyRequest(ssl, input,inOutIdx, size);
+        break;
+
+    case server_hello:
+        WOLFSSL_MSG("processing server hello");
+        ret = DoServerHello(ssl, input, inOutIdx, size);
+        break;
+
+#ifndef NO_CERTS
+    case certificate_request:
+        WOLFSSL_MSG("processing certificate request");
+        ret = DoCertificateRequest(ssl, input, inOutIdx, size);
+        break;
+#endif
+
+    case server_key_exchange:
+        WOLFSSL_MSG("processing server key exchange");
+        ret = DoServerKeyExchange(ssl, input, inOutIdx, size);
+        break;
+
+#ifdef HAVE_SESSION_TICKET
+    case session_ticket:
+        WOLFSSL_MSG("processing session ticket");
+        ret = DoSessionTicket(ssl, input, inOutIdx, size);
+        break;
+#endif /* HAVE_SESSION_TICKET */
+#endif
+
+#ifndef NO_CERTS
+    case certificate:
+        WOLFSSL_MSG("processing certificate");
+        ret =  DoCertificate(ssl, input, inOutIdx, size);
+        break;
+#endif
+
+    case server_hello_done:
+        WOLFSSL_MSG("processing server hello done");
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
+            if (ssl->toInfoOn)
+                AddLateName("ServerHelloDone", &ssl->timeoutInfo);
+        #endif
+        ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
+        if (ssl->keys.encryptionOn) {
+            *inOutIdx += ssl->keys.padSz;
+        }
+        if (ssl->options.resuming) {
+            WOLFSSL_MSG("Not resuming as thought");
+            ssl->options.resuming = 0;
+        }
+        break;
+
+    case finished:
+        WOLFSSL_MSG("processing finished");
+        ret = DoFinished(ssl, input, inOutIdx, size, totalSz, NO_SNIFF);
+        break;
+
+#ifndef NO_WOLFSSL_SERVER
+    case client_hello:
+        WOLFSSL_MSG("processing client hello");
+        ret = DoClientHello(ssl, input, inOutIdx, size);
+        break;
+
+    case client_key_exchange:
+        WOLFSSL_MSG("processing client key exchange");
+        ret = DoClientKeyExchange(ssl, input, inOutIdx, size);
+        break;
+
+#if !defined(NO_RSA) || defined(HAVE_ECC)
+    case certificate_verify:
+        WOLFSSL_MSG("processing certificate verify");
+        ret = DoCertificateVerify(ssl, input, inOutIdx, size);
+        break;
+#endif /* !NO_RSA || HAVE_ECC */
+
+#endif /* !NO_WOLFSSL_SERVER */
+
+    default:
+        WOLFSSL_MSG("Unknown handshake message type");
+        ret = UNKNOWN_HANDSHAKE_TYPE;
+        break;
+    }
+
+    WOLFSSL_LEAVE("DoHandShakeMsgType()", ret);
+    return ret;
+}
+
+
+static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                          word32 totalSz)
+{
+    int    ret = 0;
+    word32 inputLength;
+
+    WOLFSSL_ENTER("DoHandShakeMsg()");
+
+    if (ssl->arrays == NULL) {
+        byte   type;
+        word32 size;
+
+        if (GetHandShakeHeader(ssl,input,inOutIdx,&type, &size, totalSz) != 0)
+            return PARSE_ERROR;
+
+        return DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
+    }
+
+    inputLength = ssl->buffers.inputBuffer.length - *inOutIdx;
+
+    /* If there is a pending fragmented handshake message,
+     * pending message size will be non-zero. */
+    if (ssl->arrays->pendingMsgSz == 0) {
+        byte   type;
+        word32 size;
+
+        if (GetHandShakeHeader(ssl,input, inOutIdx, &type, &size, totalSz) != 0)
+            return PARSE_ERROR;
+
+        /* Cap the maximum size of a handshake message to something reasonable.
+         * By default is the maximum size of a certificate message assuming
+         * nine 2048-bit RSA certificates in the chain. */
+        if (size > MAX_HANDSHAKE_SZ) {
+            WOLFSSL_MSG("Handshake message too large");
+            return HANDSHAKE_SIZE_ERROR;
+        }
+
+        /* size is the size of the certificate message payload */
+        if (inputLength - HANDSHAKE_HEADER_SZ < size) {
+            ssl->arrays->pendingMsgType = type;
+            ssl->arrays->pendingMsgSz = size + HANDSHAKE_HEADER_SZ;
+            ssl->arrays->pendingMsg = (byte*)XMALLOC(size + HANDSHAKE_HEADER_SZ,
+                                                     ssl->heap,
+                                                     DYNAMIC_TYPE_ARRAYS);
+            if (ssl->arrays->pendingMsg == NULL)
+                return MEMORY_E;
+            XMEMCPY(ssl->arrays->pendingMsg,
+                    input + *inOutIdx - HANDSHAKE_HEADER_SZ,
+                    inputLength);
+            ssl->arrays->pendingMsgOffset = inputLength;
+            *inOutIdx += inputLength - HANDSHAKE_HEADER_SZ;
+            return 0;
+        }
+
+        ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
+    }
+    else {
+        if (inputLength + ssl->arrays->pendingMsgOffset
+                                                  > ssl->arrays->pendingMsgSz) {
+
+            return BUFFER_ERROR;
+        }
+        else {
+            XMEMCPY(ssl->arrays->pendingMsg + ssl->arrays->pendingMsgOffset,
+                    input + *inOutIdx, inputLength);
+            ssl->arrays->pendingMsgOffset += inputLength;
+            *inOutIdx += inputLength;
+        }
+
+        if (ssl->arrays->pendingMsgOffset == ssl->arrays->pendingMsgSz)
+        {
+            word32 idx = 0;
+            ret = DoHandShakeMsgType(ssl,
+                                     ssl->arrays->pendingMsg
+                                                          + HANDSHAKE_HEADER_SZ,
+                                     &idx, ssl->arrays->pendingMsgType,
+                                     ssl->arrays->pendingMsgSz
+                                                          - HANDSHAKE_HEADER_SZ,
+                                     ssl->arrays->pendingMsgSz);
+            XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
+            ssl->arrays->pendingMsg = NULL;
+            ssl->arrays->pendingMsgSz = 0;
+        }
+    }
+
+    WOLFSSL_LEAVE("DoHandShakeMsg()", ret);
+    return ret;
+}
+
+
+#ifdef WOLFSSL_DTLS
+
+static INLINE int DtlsCheckWindow(DtlsState* state)
+{
+    word32 cur;
+    word32 next;
+    DtlsSeq window;
+
+    if (state->curEpoch == state->nextEpoch) {
+        next = state->nextSeq;
+        window = state->window;
+    }
+    else if (state->curEpoch < state->nextEpoch) {
+        next = state->prevSeq;
+        window = state->prevWindow;
+    }
+    else {
+        return 0;
+    }
+
+    cur = state->curSeq;
+
+    if ((next > DTLS_SEQ_BITS) && (cur < next - DTLS_SEQ_BITS)) {
+        return 0;
+    }
+    else if ((cur < next) && (window & ((DtlsSeq)1 << (next - cur - 1)))) {
+        return 0;
+    }
+
+    return 1;
+}
+
+
+static INLINE int DtlsUpdateWindow(DtlsState* state)
+{
+    word32 cur;
+    word32* next;
+    DtlsSeq* window;
+
+    if (state->curEpoch == state->nextEpoch) {
+        next = &state->nextSeq;
+        window = &state->window;
+    }
+    else {
+        next = &state->prevSeq;
+        window = &state->prevWindow;
+    }
+
+    cur = state->curSeq;
+
+    if (cur < *next) {
+        *window |= ((DtlsSeq)1 << (*next - cur - 1));
+    }
+    else {
+        *window <<= (1 + cur - *next);
+        *window |= 1;
+        *next = cur + 1;
+    }
+
+    return 1;
+}
+
+
+static int DtlsMsgDrain(WOLFSSL* ssl)
+{
+    DtlsMsg* item = ssl->dtls_msg_list;
+    int ret = 0;
+
+    /* While there is an item in the store list, and it is the expected
+     * message, and it is complete, and there hasn't been an error in the
+     * last messge... */
+    while (item != NULL &&
+            ssl->keys.dtls_expected_peer_handshake_number == item->seq &&
+            item->fragSz == item->sz &&
+            ret == 0) {
+        word32 idx = 0;
+        ssl->keys.dtls_expected_peer_handshake_number++;
+        ret = DoHandShakeMsgType(ssl, item->msg,
+                                 &idx, item->type, item->sz, item->sz);
+        ssl->dtls_msg_list = item->next;
+        DtlsMsgDelete(item, ssl->heap);
+        item = ssl->dtls_msg_list;
+    }
+
+    return ret;
+}
+
+
+static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                          word32 totalSz)
+{
+    byte type;
+    word32 size;
+    word32 fragOffset, fragSz;
+    int ret = 0;
+
+    WOLFSSL_ENTER("DoDtlsHandShakeMsg()");
+    if (GetDtlsHandShakeHeader(ssl, input, inOutIdx, &type,
+                               &size, &fragOffset, &fragSz, totalSz) != 0)
+        return PARSE_ERROR;
+
+    if (*inOutIdx + fragSz > totalSz)
+        return INCOMPLETE_DATA;
+
+    /* Check the handshake sequence number first. If out of order,
+     * add the current message to the list. If the message is in order,
+     * but it is a fragment, add the current message to the list, then
+     * check the head of the list to see if it is complete, if so, pop
+     * it out as the current message. If the message is complete and in
+     * order, process it. Check the head of the list to see if it is in
+     * order, if so, process it. (Repeat until list exhausted.) If the
+     * head is out of order, return for more processing.
+     */
+    if (ssl->keys.dtls_peer_handshake_number >
+                                ssl->keys.dtls_expected_peer_handshake_number) {
+        /* Current message is out of order. It will get stored in the list.
+         * Storing also takes care of defragmentation. */
+        ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
+                        ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
+                        size, type, fragOffset, fragSz, ssl->heap);
+        *inOutIdx += fragSz;
+        ret = 0;
+    }
+    else if (ssl->keys.dtls_peer_handshake_number <
+                                ssl->keys.dtls_expected_peer_handshake_number) {
+        /* Already saw this message and processed it. It can be ignored. */
+        *inOutIdx += fragSz;
+        if(type == finished )
+            *inOutIdx += ssl->keys.padSz;
+        ret = 0;
+    }
+    else if (fragSz < size) {
+        /* Since this branch is in order, but fragmented, dtls_msg_list will be
+         * pointing to the message with this fragment in it. Check it to see
+         * if it is completed. */
+        ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
+                        ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
+                        size, type, fragOffset, fragSz, ssl->heap);
+        *inOutIdx += fragSz;
+        ret = 0;
+        if (ssl->dtls_msg_list != NULL &&
+            ssl->dtls_msg_list->fragSz >= ssl->dtls_msg_list->sz)
+            ret = DtlsMsgDrain(ssl);
+    }
+    else {
+        /* This branch is in order next, and a complete message. */
+        ssl->keys.dtls_expected_peer_handshake_number++;
+        ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
+        if (ret == 0 && ssl->dtls_msg_list != NULL)
+            ret = DtlsMsgDrain(ssl);
+    }
+
+    WOLFSSL_LEAVE("DoDtlsHandShakeMsg()", ret);
+    return ret;
+}
+#endif
+
+
+#if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \
+    || defined(HAVE_AESGCM)
+static INLINE word32 GetSEQIncrement(WOLFSSL* ssl, int verify)
+{
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        if (verify)
+            return ssl->keys.dtls_state.curSeq; /* explicit from peer */
+        else
+            return ssl->keys.dtls_sequence_number - 1; /* already incremented */
+    }
+#endif
+    if (verify)
+        return ssl->keys.peer_sequence_number++;
+    else
+        return ssl->keys.sequence_number++;
+}
+#endif
+
+
+#ifdef HAVE_AEAD
+static INLINE void AeadIncrementExpIV(WOLFSSL* ssl)
+{
+    int i;
+    for (i = AEAD_EXP_IV_SZ-1; i >= 0; i--) {
+        if (++ssl->keys.aead_exp_IV[i]) return;
+    }
+}
+
+
+#if defined(HAVE_POLY1305) && defined(HAVE_CHACHA)
+/*more recent rfc's concatonate input for poly1305 differently*/
+static int Poly1305Tag(WOLFSSL* ssl, byte* additional, const byte* out,
+                       byte* cipher, word16 sz, byte* tag)
+{
+    int ret       = 0;
+    int paddingSz = 0;
+    int msglen    = (sz - ssl->specs.aead_mac_size);
+    word32 keySz  = 32;
+    int blockSz   = 16;
+    byte padding[16];
+
+    if (msglen < 0)
+        return INPUT_CASE_ERROR;
+
+    XMEMSET(padding, 0, sizeof(padding));
+
+    if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0)
+        return ret;
+
+    /* additional input to poly1305 */
+    if ((ret = wc_Poly1305Update(ssl->auth.poly1305, additional, blockSz)) != 0)
+        return ret;
+
+    /* cipher input */
+    if ((ret = wc_Poly1305Update(ssl->auth.poly1305, out, msglen)) != 0)
+        return ret;
+
+    /* handle padding for cipher input to make it 16 bytes long */
+    if (msglen % 16 != 0) {
+          paddingSz = (16 - (sz - ssl->specs.aead_mac_size) % 16);
+          if (paddingSz < 0)
+              return INPUT_CASE_ERROR;
+
+          if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding, paddingSz))
+                 != 0)
+              return ret;
+    }
+
+    /* add size of AD and size of cipher to poly input */
+    XMEMSET(padding, 0, sizeof(padding));
+    padding[0] = blockSz;
+
+    /* 32 bit size of cipher to 64 bit endian */
+    padding[8]  =  msglen       & 0xff;
+    padding[9]  = (msglen >> 8) & 0xff;
+    padding[10] = (msglen >>16) & 0xff;
+    padding[11] = (msglen >>24) & 0xff;
+    if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding)))
+                != 0)
+        return ret;
+
+    /* generate tag */
+    if ((ret = wc_Poly1305Final(ssl->auth.poly1305, tag)) != 0)
+        return ret;
+
+    return ret;
+}
+
+
+/* Used for the older version of creating AEAD tags with Poly1305 */
+static int Poly1305TagOld(WOLFSSL* ssl, byte* additional, const byte* out,
+                       byte* cipher, word16 sz, byte* tag)
+{
+    int ret       = 0;
+    int msglen    = (sz - ssl->specs.aead_mac_size);
+    word32 keySz  = 32;
+    byte padding[8]; /* used to temporarly store lengths */
+
+#ifdef CHACHA_AEAD_TEST
+      printf("Using old version of poly1305 input.\n");
+#endif
+
+    if (msglen < 0)
+        return INPUT_CASE_ERROR;
+
+    if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0)
+        return ret;
+
+    /* add TLS compressed length and additional input to poly1305 */
+    additional[AEAD_AUTH_DATA_SZ - 2] = (msglen >> 8) & 0xff;
+    additional[AEAD_AUTH_DATA_SZ - 1] =  msglen       & 0xff;
+    if ((ret = wc_Poly1305Update(ssl->auth.poly1305, additional,
+                   AEAD_AUTH_DATA_SZ)) != 0)
+        return ret;
+
+    /* length of additional input plus padding */
+    XMEMSET(padding, 0, sizeof(padding));
+    padding[0] = AEAD_AUTH_DATA_SZ;
+    if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding,
+                    sizeof(padding))) != 0)
+        return ret;
+
+
+    /* add cipher info and then its length */
+    XMEMSET(padding, 0, sizeof(padding));
+    if ((ret = wc_Poly1305Update(ssl->auth.poly1305, out, msglen)) != 0)
+        return ret;
+
+    /* 32 bit size of cipher to 64 bit endian */
+    padding[0] =  msglen        & 0xff;
+    padding[1] = (msglen >>  8) & 0xff;
+    padding[2] = (msglen >> 16) & 0xff;
+    padding[3] = (msglen >> 24) & 0xff;
+    if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding)))
+        != 0)
+        return ret;
+
+    /* generate tag */
+    if ((ret = wc_Poly1305Final(ssl->auth.poly1305, tag)) != 0)
+        return ret;
+
+    return ret;
+}
+
+
+static int  ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input,
+                              word16 sz)
+{
+    const byte* additionalSrc = input - RECORD_HEADER_SZ;
+    int ret = 0;
+    byte tag[POLY1305_AUTH_SZ];
+    byte additional[CHACHA20_BLOCK_SIZE];
+    byte nonce[AEAD_NONCE_SZ];
+    byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for poly1305 */
+    #ifdef CHACHA_AEAD_TEST
+        int i;
+    #endif
+
+    XMEMSET(tag, 0, sizeof(tag));
+    XMEMSET(nonce, 0, AEAD_NONCE_SZ);
+    XMEMSET(cipher, 0, sizeof(cipher));
+    XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE);
+
+    /* get nonce */
+    c32toa(ssl->keys.sequence_number, nonce + AEAD_IMP_IV_SZ
+           + AEAD_SEQ_OFFSET);
+
+    /* opaque SEQ number stored for AD */
+    c32toa(GetSEQIncrement(ssl, 0), additional + AEAD_SEQ_OFFSET);
+
+    /* Store the type, version. Unfortunately, they are in
+     * the input buffer ahead of the plaintext. */
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            c16toa(ssl->keys.dtls_epoch, additional);
+            additionalSrc -= DTLS_HANDSHAKE_EXTRA;
+        }
+    #endif
+
+    XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
+
+    #ifdef CHACHA_AEAD_TEST
+        printf("Encrypt Additional : ");
+        for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) {
+            printf("%02x", additional[i]);
+        }
+        printf("\n\n");
+        printf("input before encryption :\n");
+        for (i = 0; i < sz; i++) {
+            printf("%02x", input[i]);
+            if ((i + 1) % 16 == 0)
+                printf("\n");
+        }
+        printf("\n");
+    #endif
+
+    /* set the nonce for chacha and get poly1305 key */
+    if ((ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 0)) != 0)
+        return ret;
+
+        if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, cipher,
+                    cipher, sizeof(cipher))) != 0)
+        return ret;
+
+    /* encrypt the plain text */
+    if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, out, input,
+                   sz - ssl->specs.aead_mac_size)) != 0)
+        return ret;
+
+    /* get the tag : future use of hmac could go here*/
+    if (ssl->options.oldPoly == 1) {
+        if ((ret = Poly1305TagOld(ssl, additional, (const byte* )out,
+                    cipher, sz, tag)) != 0)
+            return ret;
+    }
+    else {
+        if ((ret = Poly1305Tag(ssl, additional, (const byte* )out,
+                    cipher, sz, tag)) != 0)
+            return ret;
+    }
+
+    /* append tag to ciphertext */
+    XMEMCPY(out + sz - ssl->specs.aead_mac_size, tag, sizeof(tag));
+
+    AeadIncrementExpIV(ssl);
+    ForceZero(nonce, AEAD_NONCE_SZ);
+
+    #ifdef CHACHA_AEAD_TEST
+       printf("mac tag :\n");
+        for (i = 0; i < 16; i++) {
+           printf("%02x", tag[i]);
+           if ((i + 1) % 16 == 0)
+               printf("\n");
+        }
+       printf("\n\noutput after encrypt :\n");
+        for (i = 0; i < sz; i++) {
+           printf("%02x", out[i]);
+           if ((i + 1) % 16 == 0)
+               printf("\n");
+        }
+        printf("\n");
+    #endif
+
+    return ret;
+}
+
+
+static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input,
+                           word16 sz)
+{
+    byte additional[CHACHA20_BLOCK_SIZE];
+    byte nonce[AEAD_NONCE_SZ];
+    byte tag[POLY1305_AUTH_SZ];
+    byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for mac */
+    int ret = 0;
+
+    XMEMSET(tag, 0, sizeof(tag));
+    XMEMSET(cipher, 0, sizeof(cipher));
+    XMEMSET(nonce, 0, AEAD_NONCE_SZ);
+    XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE);
+
+    #ifdef CHACHA_AEAD_TEST
+       int i;
+       printf("input before decrypt :\n");
+        for (i = 0; i < sz; i++) {
+           printf("%02x", input[i]);
+           if ((i + 1) % 16 == 0)
+               printf("\n");
+        }
+        printf("\n");
+    #endif
+
+    /* get nonce */
+    c32toa(ssl->keys.peer_sequence_number, nonce + AEAD_IMP_IV_SZ
+            + AEAD_SEQ_OFFSET);
+
+    /* sequence number field is 64-bits, we only use 32-bits */
+    c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
+
+    /* get AD info */
+    additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
+    additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
+    additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
+
+    /* Store the type, version. */
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls)
+            c16toa(ssl->keys.dtls_state.curEpoch, additional);
+    #endif
+
+    #ifdef CHACHA_AEAD_TEST
+        printf("Decrypt Additional : ");
+        for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) {
+            printf("%02x", additional[i]);
+        }
+        printf("\n\n");
+    #endif
+
+    /* set nonce and get poly1305 key */
+    if ((ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 0)) != 0)
+        return ret;
+
+    if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, cipher,
+                    cipher, sizeof(cipher))) != 0)
+        return ret;
+
+    /* get the tag : future use of hmac could go here*/
+    if (ssl->options.oldPoly == 1) {
+        if ((ret = Poly1305TagOld(ssl, additional, input, cipher,
+                        sz, tag)) != 0)
+            return ret;
+    }
+    else {
+        if ((ret = Poly1305Tag(ssl, additional, input, cipher,
+                        sz, tag)) != 0)
+            return ret;
+    }
+
+    /* check mac sent along with packet */
+    if (ConstantCompare(input + sz - ssl->specs.aead_mac_size, tag,
+                ssl->specs.aead_mac_size) != 0) {
+        WOLFSSL_MSG("Mac did not match");
+        SendAlert(ssl, alert_fatal, bad_record_mac);
+        ForceZero(nonce, AEAD_NONCE_SZ);
+        return VERIFY_MAC_ERROR;
+    }
+
+    /* if mac was good decrypt message */
+    if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, plain, input,
+                   sz - ssl->specs.aead_mac_size)) != 0)
+        return ret;
+
+    #ifdef CHACHA_AEAD_TEST
+       printf("plain after decrypt :\n");
+        for (i = 0; i < sz; i++) {
+           printf("%02x", plain[i]);
+           if ((i + 1) % 16 == 0)
+               printf("\n");
+        }
+        printf("\n");
+    #endif
+
+    return ret;
+}
+#endif /* HAVE_CHACHA && HAVE_POLY1305 */
+#endif /* HAVE_AEAD */
+
+
+static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz)
+{
+    int ret = 0;
+
+    (void)out;
+    (void)input;
+    (void)sz;
+
+    if (ssl->encrypt.setup == 0) {
+        WOLFSSL_MSG("Encrypt ciphers not setup");
+        return ENCRYPT_ERROR;
+    }
+
+#ifdef HAVE_FUZZER
+    if (ssl->fuzzerCb)
+        ssl->fuzzerCb(ssl, input, sz, FUZZ_ENCRYPT, ssl->fuzzerCtx);
+#endif
+
+    switch (ssl->specs.bulk_cipher_algorithm) {
+        #ifdef BUILD_ARC4
+            case wolfssl_rc4:
+                wc_Arc4Process(ssl->encrypt.arc4, out, input, sz);
+                break;
+        #endif
+
+        #ifdef BUILD_DES3
+            case wolfssl_triple_des:
+                ret = wc_Des3_CbcEncrypt(ssl->encrypt.des3, out, input, sz);
+                break;
+        #endif
+
+        #ifdef BUILD_AES
+            case wolfssl_aes:
+                ret = wc_AesCbcEncrypt(ssl->encrypt.aes, out, input, sz);
+                break;
+        #endif
+
+        #ifdef BUILD_AESGCM
+            case wolfssl_aes_gcm:
+                {
+                    byte additional[AEAD_AUTH_DATA_SZ];
+                    byte nonce[AEAD_NONCE_SZ];
+                    const byte* additionalSrc = input - 5;
+
+                    XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
+
+                    /* sequence number field is 64-bits, we only use 32-bits */
+                    c32toa(GetSEQIncrement(ssl, 0),
+                                            additional + AEAD_SEQ_OFFSET);
+
+                    /* Store the type, version. Unfortunately, they are in
+                     * the input buffer ahead of the plaintext. */
+                    #ifdef WOLFSSL_DTLS
+                        if (ssl->options.dtls) {
+                            c16toa(ssl->keys.dtls_epoch, additional);
+                            additionalSrc -= DTLS_HANDSHAKE_EXTRA;
+                        }
+                    #endif
+                    XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
+
+                    /* Store the length of the plain text minus the explicit
+                     * IV length minus the authentication tag size. */
+                    c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
+                                                additional + AEAD_LEN_OFFSET);
+                    XMEMCPY(nonce,
+                                 ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ);
+                    XMEMCPY(nonce + AEAD_IMP_IV_SZ,
+                                     ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
+                    ret = wc_AesGcmEncrypt(ssl->encrypt.aes,
+                                 out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ,
+                                 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
+                                 nonce, AEAD_NONCE_SZ,
+                                 out + sz - ssl->specs.aead_mac_size,
+                                 ssl->specs.aead_mac_size,
+                                 additional, AEAD_AUTH_DATA_SZ);
+                    AeadIncrementExpIV(ssl);
+                    ForceZero(nonce, AEAD_NONCE_SZ);
+                }
+                break;
+        #endif
+
+        #ifdef HAVE_AESCCM
+            case wolfssl_aes_ccm:
+                {
+                    byte additional[AEAD_AUTH_DATA_SZ];
+                    byte nonce[AEAD_NONCE_SZ];
+                    const byte* additionalSrc = input - 5;
+
+                    XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
+
+                    /* sequence number field is 64-bits, we only use 32-bits */
+                    c32toa(GetSEQIncrement(ssl, 0),
+                                            additional + AEAD_SEQ_OFFSET);
+
+                    /* Store the type, version. Unfortunately, they are in
+                     * the input buffer ahead of the plaintext. */
+                    #ifdef WOLFSSL_DTLS
+                        if (ssl->options.dtls) {
+                            c16toa(ssl->keys.dtls_epoch, additional);
+                            additionalSrc -= DTLS_HANDSHAKE_EXTRA;
+                        }
+                    #endif
+                    XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
+
+                    /* Store the length of the plain text minus the explicit
+                     * IV length minus the authentication tag size. */
+                    c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
+                                                additional + AEAD_LEN_OFFSET);
+                    XMEMCPY(nonce,
+                                 ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ);
+                    XMEMCPY(nonce + AEAD_IMP_IV_SZ,
+                                     ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
+                    ret = wc_AesCcmEncrypt(ssl->encrypt.aes,
+                        out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ,
+                            sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
+                        nonce, AEAD_NONCE_SZ,
+                        out + sz - ssl->specs.aead_mac_size,
+                        ssl->specs.aead_mac_size,
+                        additional, AEAD_AUTH_DATA_SZ);
+                    AeadIncrementExpIV(ssl);
+                    ForceZero(nonce, AEAD_NONCE_SZ);
+                }
+                break;
+        #endif
+
+        #ifdef HAVE_CAMELLIA
+            case wolfssl_camellia:
+                wc_CamelliaCbcEncrypt(ssl->encrypt.cam, out, input, sz);
+                break;
+        #endif
+
+        #ifdef HAVE_HC128
+            case wolfssl_hc128:
+                ret = wc_Hc128_Process(ssl->encrypt.hc128, out, input, sz);
+                break;
+        #endif
+
+        #ifdef BUILD_RABBIT
+            case wolfssl_rabbit:
+                ret = wc_RabbitProcess(ssl->encrypt.rabbit, out, input, sz);
+                break;
+        #endif
+
+        #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
+            case wolfssl_chacha:
+                ret = ChachaAEADEncrypt(ssl, out, input, sz);
+                break;
+        #endif
+
+        #ifdef HAVE_NULL_CIPHER
+            case wolfssl_cipher_null:
+                if (input != out) {
+                    XMEMMOVE(out, input, sz);
+                }
+                break;
+        #endif
+
+        #ifdef HAVE_IDEA
+            case wolfssl_idea:
+                ret = wc_IdeaCbcEncrypt(ssl->encrypt.idea, out, input, sz);
+                break;
+        #endif
+
+            default:
+                WOLFSSL_MSG("wolfSSL Encrypt programming error");
+                ret = ENCRYPT_ERROR;
+    }
+
+    return ret;
+}
+
+
+
+static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input,
+                           word16 sz)
+{
+    int ret = 0;
+
+    (void)plain;
+    (void)input;
+    (void)sz;
+
+    if (ssl->decrypt.setup == 0) {
+        WOLFSSL_MSG("Decrypt ciphers not setup");
+        return DECRYPT_ERROR;
+    }
+
+    switch (ssl->specs.bulk_cipher_algorithm) {
+        #ifdef BUILD_ARC4
+            case wolfssl_rc4:
+                wc_Arc4Process(ssl->decrypt.arc4, plain, input, sz);
+                break;
+        #endif
+
+        #ifdef BUILD_DES3
+            case wolfssl_triple_des:
+                ret = wc_Des3_CbcDecrypt(ssl->decrypt.des3, plain, input, sz);
+                break;
+        #endif
+
+        #ifdef BUILD_AES
+            case wolfssl_aes:
+                ret = wc_AesCbcDecrypt(ssl->decrypt.aes, plain, input, sz);
+                break;
+        #endif
+
+        #ifdef BUILD_AESGCM
+            case wolfssl_aes_gcm:
+            {
+                byte additional[AEAD_AUTH_DATA_SZ];
+                byte nonce[AEAD_NONCE_SZ];
+
+                XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
+
+                /* sequence number field is 64-bits, we only use 32-bits */
+                c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
+
+                #ifdef WOLFSSL_DTLS
+                    if (ssl->options.dtls)
+                        c16toa(ssl->keys.dtls_state.curEpoch, additional);
+                #endif
+
+                additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
+                additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
+                additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
+
+                c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
+                                        additional + AEAD_LEN_OFFSET);
+                XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
+                XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
+                if (wc_AesGcmDecrypt(ssl->decrypt.aes,
+                            plain + AEAD_EXP_IV_SZ,
+                            input + AEAD_EXP_IV_SZ,
+                                sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
+                            nonce, AEAD_NONCE_SZ,
+                            input + sz - ssl->specs.aead_mac_size,
+                            ssl->specs.aead_mac_size,
+                            additional, AEAD_AUTH_DATA_SZ) < 0) {
+                    SendAlert(ssl, alert_fatal, bad_record_mac);
+                    ret = VERIFY_MAC_ERROR;
+                }
+                ForceZero(nonce, AEAD_NONCE_SZ);
+            }
+            break;
+        #endif
+
+        #ifdef HAVE_AESCCM
+            case wolfssl_aes_ccm:
+            {
+                byte additional[AEAD_AUTH_DATA_SZ];
+                byte nonce[AEAD_NONCE_SZ];
+
+                XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
+
+                /* sequence number field is 64-bits, we only use 32-bits */
+                c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
+
+                #ifdef WOLFSSL_DTLS
+                    if (ssl->options.dtls)
+                        c16toa(ssl->keys.dtls_state.curEpoch, additional);
+                #endif
+
+                additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
+                additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
+                additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
+
+                c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
+                                        additional + AEAD_LEN_OFFSET);
+                XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
+                XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
+                if (wc_AesCcmDecrypt(ssl->decrypt.aes,
+                            plain + AEAD_EXP_IV_SZ,
+                            input + AEAD_EXP_IV_SZ,
+                                sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
+                            nonce, AEAD_NONCE_SZ,
+                            input + sz - ssl->specs.aead_mac_size,
+                            ssl->specs.aead_mac_size,
+                            additional, AEAD_AUTH_DATA_SZ) < 0) {
+                    SendAlert(ssl, alert_fatal, bad_record_mac);
+                    ret = VERIFY_MAC_ERROR;
+                }
+                ForceZero(nonce, AEAD_NONCE_SZ);
+            }
+            break;
+        #endif
+
+        #ifdef HAVE_CAMELLIA
+            case wolfssl_camellia:
+                wc_CamelliaCbcDecrypt(ssl->decrypt.cam, plain, input, sz);
+                break;
+        #endif
+
+        #ifdef HAVE_HC128
+            case wolfssl_hc128:
+                ret = wc_Hc128_Process(ssl->decrypt.hc128, plain, input, sz);
+                break;
+        #endif
+
+        #ifdef BUILD_RABBIT
+            case wolfssl_rabbit:
+                ret = wc_RabbitProcess(ssl->decrypt.rabbit, plain, input, sz);
+                break;
+        #endif
+
+        #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
+            case wolfssl_chacha:
+                ret = ChachaAEADDecrypt(ssl, plain, input, sz);
+                break;
+        #endif
+
+        #ifdef HAVE_NULL_CIPHER
+            case wolfssl_cipher_null:
+                if (input != plain) {
+                    XMEMMOVE(plain, input, sz);
+                }
+                break;
+        #endif
+
+        #ifdef HAVE_IDEA
+            case wolfssl_idea:
+                ret = wc_IdeaCbcDecrypt(ssl->decrypt.idea, plain, input, sz);
+                break;
+        #endif
+
+            default:
+                WOLFSSL_MSG("wolfSSL Decrypt programming error");
+                ret = DECRYPT_ERROR;
+    }
+
+    return ret;
+}
+
+
+/* check cipher text size for sanity */
+static int SanityCheckCipherText(WOLFSSL* ssl, word32 encryptSz)
+{
+#ifdef HAVE_TRUNCATED_HMAC
+    word32 minLength = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ
+                                           : ssl->specs.hash_size;
+#else
+    word32 minLength = ssl->specs.hash_size; /* covers stream */
+#endif
+
+    if (ssl->specs.cipher_type == block) {
+        if (encryptSz % ssl->specs.block_size) {
+            WOLFSSL_MSG("Block ciphertext not block size");
+            return SANITY_CIPHER_E;
+        }
+
+        minLength++;  /* pad byte */
+
+        if (ssl->specs.block_size > minLength)
+            minLength = ssl->specs.block_size;
+
+        if (ssl->options.tls1_1)
+            minLength += ssl->specs.block_size;  /* explicit IV */
+    }
+    else if (ssl->specs.cipher_type == aead) {
+        minLength = ssl->specs.aead_mac_size;    /* authTag size */
+        if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
+           minLength += AEAD_EXP_IV_SZ;          /* explicit IV  */
+    }
+
+    if (encryptSz < minLength) {
+        WOLFSSL_MSG("Ciphertext not minimum size");
+        return SANITY_CIPHER_E;
+    }
+
+    return 0;
+}
+
+
+#ifndef NO_OLD_TLS
+
+static INLINE void Md5Rounds(int rounds, const byte* data, int sz)
+{
+    Md5 md5;
+    int i;
+
+    wc_InitMd5(&md5);
+
+    for (i = 0; i < rounds; i++)
+        wc_Md5Update(&md5, data, sz);
+    wc_Md5Free(&md5) ; /* in case needed to release resources */
+}
+
+
+
+/* do a dummy sha round */
+static INLINE void ShaRounds(int rounds, const byte* data, int sz)
+{
+    Sha sha;
+    int i;
+
+    wc_InitSha(&sha);  /* no error check on purpose, dummy round */
+
+    for (i = 0; i < rounds; i++)
+        wc_ShaUpdate(&sha, data, sz);
+    wc_ShaFree(&sha) ; /* in case needed to release resources */
+}
+#endif
+
+
+#ifndef NO_SHA256
+
+static INLINE void Sha256Rounds(int rounds, const byte* data, int sz)
+{
+    Sha256 sha256;
+    int i;
+
+    wc_InitSha256(&sha256);  /* no error check on purpose, dummy round */
+
+    for (i = 0; i < rounds; i++) {
+        wc_Sha256Update(&sha256, data, sz);
+        /* no error check on purpose, dummy round */
+    }
+    wc_Sha256Free(&sha256) ; /* in case needed to release resources */
+}
+
+#endif
+
+
+#ifdef WOLFSSL_SHA384
+
+static INLINE void Sha384Rounds(int rounds, const byte* data, int sz)
+{
+    Sha384 sha384;
+    int i;
+
+    wc_InitSha384(&sha384);  /* no error check on purpose, dummy round */
+
+    for (i = 0; i < rounds; i++) {
+        wc_Sha384Update(&sha384, data, sz);
+        /* no error check on purpose, dummy round */
+    }
+    wc_Sha384Free(&sha384) ; /* in case needed to release resources */
+}
+
+#endif
+
+
+#ifdef WOLFSSL_SHA512
+
+static INLINE void Sha512Rounds(int rounds, const byte* data, int sz)
+{
+    Sha512 sha512;
+    int i;
+
+    wc_InitSha512(&sha512);  /* no error check on purpose, dummy round */
+
+    for (i = 0; i < rounds; i++) {
+        wc_Sha512Update(&sha512, data, sz);
+        /* no error check on purpose, dummy round */
+    }
+    wc_Sha512Free(&sha512) ; /* in case needed to release resources */
+}
+
+#endif
+
+
+#ifdef WOLFSSL_RIPEMD
+
+static INLINE void RmdRounds(int rounds, const byte* data, int sz)
+{
+    RipeMd ripemd;
+    int i;
+
+    wc_InitRipeMd(&ripemd);
+
+    for (i = 0; i < rounds; i++)
+        wc_RipeMdUpdate(&ripemd, data, sz);
+}
+
+#endif
+
+
+/* Do dummy rounds */
+static INLINE void DoRounds(int type, int rounds, const byte* data, int sz)
+{
+    switch (type) {
+
+        case no_mac :
+            break;
+
+#ifndef NO_OLD_TLS
+#ifndef NO_MD5
+        case md5_mac :
+            Md5Rounds(rounds, data, sz);
+            break;
+#endif
+
+#ifndef NO_SHA
+        case sha_mac :
+            ShaRounds(rounds, data, sz);
+            break;
+#endif
+#endif
+
+#ifndef NO_SHA256
+        case sha256_mac :
+            Sha256Rounds(rounds, data, sz);
+            break;
+#endif
+
+#ifdef WOLFSSL_SHA384
+        case sha384_mac :
+            Sha384Rounds(rounds, data, sz);
+            break;
+#endif
+
+#ifdef WOLFSSL_SHA512
+        case sha512_mac :
+            Sha512Rounds(rounds, data, sz);
+            break;
+#endif
+
+#ifdef WOLFSSL_RIPEMD
+        case rmd_mac :
+            RmdRounds(rounds, data, sz);
+            break;
+#endif
+
+        default:
+            WOLFSSL_MSG("Bad round type");
+            break;
+    }
+}
+
+
+/* do number of compression rounds on dummy data */
+static INLINE void CompressRounds(WOLFSSL* ssl, int rounds, const byte* dummy)
+{
+    if (rounds)
+        DoRounds(ssl->specs.mac_algorithm, rounds, dummy, COMPRESS_LOWER);
+}
+
+
+/* check all length bytes for the pad value, return 0 on success */
+static int PadCheck(const byte* a, byte pad, int length)
+{
+    int i;
+    int compareSum = 0;
+
+    for (i = 0; i < length; i++) {
+        compareSum |= a[i] ^ pad;
+    }
+
+    return compareSum;
+}
+
+
+/* get compression extra rounds */
+static INLINE int GetRounds(int pLen, int padLen, int t)
+{
+    int  roundL1 = 1;  /* round up flags */
+    int  roundL2 = 1;
+
+    int L1 = COMPRESS_CONSTANT + pLen - t;
+    int L2 = COMPRESS_CONSTANT + pLen - padLen - 1 - t;
+
+    L1 -= COMPRESS_UPPER;
+    L2 -= COMPRESS_UPPER;
+
+    if ( (L1 % COMPRESS_LOWER) == 0)
+        roundL1 = 0;
+    if ( (L2 % COMPRESS_LOWER) == 0)
+        roundL2 = 0;
+
+    L1 /= COMPRESS_LOWER;
+    L2 /= COMPRESS_LOWER;
+
+    L1 += roundL1;
+    L2 += roundL2;
+
+    return L1 - L2;
+}
+
+
+/* timing resistant pad/verify check, return 0 on success */
+static int TimingPadVerify(WOLFSSL* ssl, const byte* input, int padLen, int t,
+                           int pLen, int content)
+{
+    byte verify[MAX_DIGEST_SIZE];
+    byte dmy[sizeof(WOLFSSL) >= MAX_PAD_SIZE ? 1 : MAX_PAD_SIZE] = {0};
+    byte* dummy = sizeof(dmy) < MAX_PAD_SIZE ? (byte*) ssl : dmy;
+    int  ret = 0;
+
+    (void)dmy;
+
+    if ( (t + padLen + 1) > pLen) {
+        WOLFSSL_MSG("Plain Len not long enough for pad/mac");
+        PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE);
+        ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */
+        ConstantCompare(verify, input + pLen - t, t);
+
+        return VERIFY_MAC_ERROR;
+    }
+
+    if (PadCheck(input + pLen - (padLen + 1), (byte)padLen, padLen + 1) != 0) {
+        WOLFSSL_MSG("PadCheck failed");
+        PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
+        ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */
+        ConstantCompare(verify, input + pLen - t, t);
+
+        return VERIFY_MAC_ERROR;
+    }
+
+    PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
+    ret = ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, content, 1);
+
+    CompressRounds(ssl, GetRounds(pLen, padLen, t), dummy);
+
+    if (ConstantCompare(verify, input + (pLen - padLen - 1 - t), t) != 0) {
+        WOLFSSL_MSG("Verify MAC compare failed");
+        return VERIFY_MAC_ERROR;
+    }
+
+    if (ret != 0)
+        return VERIFY_MAC_ERROR;
+    return 0;
+}
+
+
+int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
+{
+    word32 msgSz   = ssl->keys.encryptSz;
+    word32 idx     = *inOutIdx;
+    int    dataSz;
+    int    ivExtra = 0;
+    byte*  rawData = input + idx;  /* keep current  for hmac */
+#ifdef HAVE_LIBZ
+    byte   decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
+#endif
+
+    if (ssl->options.handShakeDone == 0) {
+        WOLFSSL_MSG("Received App data before a handshake completed");
+        SendAlert(ssl, alert_fatal, unexpected_message);
+        return OUT_OF_ORDER_E;
+    }
+
+    if (ssl->specs.cipher_type == block) {
+        if (ssl->options.tls1_1)
+            ivExtra = ssl->specs.block_size;
+    }
+    else if (ssl->specs.cipher_type == aead) {
+        if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
+            ivExtra = AEAD_EXP_IV_SZ;
+    }
+
+    dataSz = msgSz - ivExtra - ssl->keys.padSz;
+    if (dataSz < 0) {
+        WOLFSSL_MSG("App data buffer error, malicious input?");
+        return BUFFER_ERROR;
+    }
+
+    /* read data */
+    if (dataSz) {
+        int rawSz = dataSz;       /* keep raw size for idx adjustment */
+
+#ifdef HAVE_LIBZ
+        if (ssl->options.usingCompression) {
+            dataSz = myDeCompress(ssl, rawData, dataSz, decomp, sizeof(decomp));
+            if (dataSz < 0) return dataSz;
+        }
+#endif
+        idx += rawSz;
+
+        ssl->buffers.clearOutputBuffer.buffer = rawData;
+        ssl->buffers.clearOutputBuffer.length = dataSz;
+    }
+
+    idx += ssl->keys.padSz;
+
+#ifdef HAVE_LIBZ
+    /* decompress could be bigger, overwrite after verify */
+    if (ssl->options.usingCompression)
+        XMEMMOVE(rawData, decomp, dataSz);
+#endif
+
+    *inOutIdx = idx;
+    return 0;
+}
+
+
+/* process alert, return level */
+static int DoAlert(WOLFSSL* ssl, byte* input, word32* inOutIdx, int* type,
+                   word32 totalSz)
+{
+    byte level;
+    byte code;
+
+    #ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn)
+            AddPacketName("Alert", &ssl->handShakeInfo);
+        if (ssl->toInfoOn)
+            /* add record header back on to info + 2 byte level, data */
+            AddPacketInfo("Alert", &ssl->timeoutInfo, input + *inOutIdx -
+                          RECORD_HEADER_SZ, 2 + RECORD_HEADER_SZ, ssl->heap);
+    #endif
+
+    /* make sure can read the message */
+    if (*inOutIdx + ALERT_SIZE > totalSz)
+        return BUFFER_E;
+
+    level = input[(*inOutIdx)++];
+    code  = input[(*inOutIdx)++];
+    ssl->alert_history.last_rx.code = code;
+    ssl->alert_history.last_rx.level = level;
+    *type = code;
+    if (level == alert_fatal) {
+        ssl->options.isClosed = 1;  /* Don't send close_notify */
+    }
+
+    WOLFSSL_MSG("Got alert");
+    if (*type == close_notify) {
+        WOLFSSL_MSG("    close notify");
+        ssl->options.closeNotify = 1;
+    }
+    WOLFSSL_ERROR(*type);
+    if (ssl->keys.encryptionOn) {
+        if (*inOutIdx + ssl->keys.padSz > totalSz)
+            return BUFFER_E;
+        *inOutIdx += ssl->keys.padSz;
+    }
+
+    return level;
+}
+
+static int GetInputData(WOLFSSL *ssl, word32 size)
+{
+    int in;
+    int inSz;
+    int maxLength;
+    int usedLength;
+    int dtlsExtra = 0;
+
+
+    /* check max input length */
+    usedLength = ssl->buffers.inputBuffer.length - ssl->buffers.inputBuffer.idx;
+    maxLength  = ssl->buffers.inputBuffer.bufferSize - usedLength;
+    inSz       = (int)(size - usedLength);      /* from last partial read */
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        if (size < ssl->dtls_expected_rx)
+            dtlsExtra = (int)(ssl->dtls_expected_rx - size);
+        inSz = ssl->dtls_expected_rx;
+    }
+#endif
+
+    if (inSz > maxLength) {
+        if (GrowInputBuffer(ssl, size + dtlsExtra, usedLength) < 0)
+            return MEMORY_E;
+    }
+
+    if (inSz <= 0)
+        return BUFFER_ERROR;
+
+    /* Put buffer data at start if not there */
+    if (usedLength > 0 && ssl->buffers.inputBuffer.idx != 0)
+        XMEMMOVE(ssl->buffers.inputBuffer.buffer,
+                ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
+                usedLength);
+
+    /* remove processed data */
+    ssl->buffers.inputBuffer.idx    = 0;
+    ssl->buffers.inputBuffer.length = usedLength;
+
+    /* read data from network */
+    do {
+        in = Receive(ssl,
+                     ssl->buffers.inputBuffer.buffer +
+                     ssl->buffers.inputBuffer.length,
+                     inSz);
+        if (in == -1)
+            return SOCKET_ERROR_E;
+
+        if (in == WANT_READ)
+            return WANT_READ;
+
+        if (in > inSz)
+            return RECV_OVERFLOW_E;
+
+        ssl->buffers.inputBuffer.length += in;
+        inSz -= in;
+
+    } while (ssl->buffers.inputBuffer.length < size);
+
+    return 0;
+}
+
+
+static INLINE int VerifyMac(WOLFSSL* ssl, const byte* input, word32 msgSz,
+                            int content, word32* padSz)
+{
+    int    ivExtra = 0;
+    int    ret;
+    word32 pad     = 0;
+    word32 padByte = 0;
+#ifdef HAVE_TRUNCATED_HMAC
+    word32 digestSz = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ
+                                          : ssl->specs.hash_size;
+#else
+    word32 digestSz = ssl->specs.hash_size;
+#endif
+    byte   verify[MAX_DIGEST_SIZE];
+
+    if (ssl->specs.cipher_type == block) {
+        if (ssl->options.tls1_1)
+            ivExtra = ssl->specs.block_size;
+        pad = *(input + msgSz - ivExtra - 1);
+        padByte = 1;
+
+        if (ssl->options.tls) {
+            ret = TimingPadVerify(ssl, input, pad, digestSz, msgSz - ivExtra,
+                                  content);
+            if (ret != 0)
+                return ret;
+        }
+        else {  /* sslv3, some implementations have bad padding, but don't
+                 * allow bad read */
+            int  badPadLen = 0;
+            byte dmy[sizeof(WOLFSSL) >= MAX_PAD_SIZE ? 1 : MAX_PAD_SIZE] = {0};
+            byte* dummy = sizeof(dmy) < MAX_PAD_SIZE ? (byte*) ssl : dmy;
+
+            (void)dmy;
+
+            if (pad > (msgSz - digestSz - 1)) {
+                WOLFSSL_MSG("Plain Len not long enough for pad/mac");
+                pad       = 0;  /* no bad read */
+                badPadLen = 1;
+            }
+            PadCheck(dummy, (byte)pad, MAX_PAD_SIZE);  /* timing only */
+            ret = ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1,
+                            content, 1);
+            if (ConstantCompare(verify, input + msgSz - digestSz - pad - 1,
+                                digestSz) != 0)
+                return VERIFY_MAC_ERROR;
+            if (ret != 0 || badPadLen)
+                return VERIFY_MAC_ERROR;
+        }
+    }
+    else if (ssl->specs.cipher_type == stream) {
+        ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, content, 1);
+        if (ConstantCompare(verify, input + msgSz - digestSz, digestSz) != 0){
+            return VERIFY_MAC_ERROR;
+        }
+        if (ret != 0)
+            return VERIFY_MAC_ERROR;
+    }
+
+    if (ssl->specs.cipher_type == aead) {
+        *padSz = ssl->specs.aead_mac_size;
+    }
+    else {
+        *padSz = digestSz + pad + padByte;
+    }
+
+    return 0;
+}
+
+
+/* process input requests, return 0 is done, 1 is call again to complete, and
+   negative number is error */
+int ProcessReply(WOLFSSL* ssl)
+{
+    int    ret = 0, type, readSz;
+    int    atomicUser = 0;
+    word32 startIdx = 0;
+#ifdef WOLFSSL_DTLS
+    int    used;
+#endif
+
+#ifdef ATOMIC_USER
+    if (ssl->ctx->DecryptVerifyCb)
+        atomicUser = 1;
+#endif
+
+    if (ssl->error != 0 && ssl->error != WANT_READ && ssl->error != WANT_WRITE){
+        WOLFSSL_MSG("ProcessReply retry in error state, not allowed");
+        return ssl->error;
+    }
+
+    for (;;) {
+        switch (ssl->options.processReply) {
+
+        /* in the WOLFSSL_SERVER case, get the first byte for detecting
+         * old client hello */
+        case doProcessInit:
+
+            readSz = RECORD_HEADER_SZ;
+
+            #ifdef WOLFSSL_DTLS
+                if (ssl->options.dtls)
+                    readSz = DTLS_RECORD_HEADER_SZ;
+            #endif
+
+            /* get header or return error */
+            if (!ssl->options.dtls) {
+                if ((ret = GetInputData(ssl, readSz)) < 0)
+                    return ret;
+            } else {
+            #ifdef WOLFSSL_DTLS
+                /* read ahead may already have header */
+                used = ssl->buffers.inputBuffer.length -
+                       ssl->buffers.inputBuffer.idx;
+                if (used < readSz)
+                    if ((ret = GetInputData(ssl, readSz)) < 0)
+                        return ret;
+            #endif
+            }
+
+#ifdef OLD_HELLO_ALLOWED
+
+            /* see if sending SSLv2 client hello */
+            if ( ssl->options.side == WOLFSSL_SERVER_END &&
+                 ssl->options.clientState == NULL_STATE &&
+                 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx]
+                         != handshake) {
+                byte b0, b1;
+
+                ssl->options.processReply = runProcessOldClientHello;
+
+                /* sanity checks before getting size at front */
+                if (ssl->buffers.inputBuffer.buffer[
+                          ssl->buffers.inputBuffer.idx + 2] != OLD_HELLO_ID) {
+                    WOLFSSL_MSG("Not a valid old client hello");
+                    return PARSE_ERROR;
+                }
+
+                if (ssl->buffers.inputBuffer.buffer[
+                          ssl->buffers.inputBuffer.idx + 3] != SSLv3_MAJOR &&
+                    ssl->buffers.inputBuffer.buffer[
+                          ssl->buffers.inputBuffer.idx + 3] != DTLS_MAJOR) {
+                    WOLFSSL_MSG("Not a valid version in old client hello");
+                    return PARSE_ERROR;
+                }
+
+                /* how many bytes need ProcessOldClientHello */
+                b0 =
+                ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
+                b1 =
+                ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
+                ssl->curSize = (word16)(((b0 & 0x7f) << 8) | b1);
+            }
+            else {
+                ssl->options.processReply = getRecordLayerHeader;
+                continue;
+            }
+
+        /* in the WOLFSSL_SERVER case, run the old client hello */
+        case runProcessOldClientHello:
+
+            /* get sz bytes or return error */
+            if (!ssl->options.dtls) {
+                if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
+                    return ret;
+            } else {
+            #ifdef WOLFSSL_DTLS
+                /* read ahead may already have */
+                used = ssl->buffers.inputBuffer.length -
+                       ssl->buffers.inputBuffer.idx;
+                if (used < ssl->curSize)
+                    if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
+                        return ret;
+            #endif  /* WOLFSSL_DTLS */
+            }
+
+            ret = ProcessOldClientHello(ssl, ssl->buffers.inputBuffer.buffer,
+                                        &ssl->buffers.inputBuffer.idx,
+                                        ssl->buffers.inputBuffer.length -
+                                        ssl->buffers.inputBuffer.idx,
+                                        ssl->curSize);
+            if (ret < 0)
+                return ret;
+
+            else if (ssl->buffers.inputBuffer.idx ==
+                     ssl->buffers.inputBuffer.length) {
+                ssl->options.processReply = doProcessInit;
+                return 0;
+            }
+
+#endif  /* OLD_HELLO_ALLOWED */
+
+        /* get the record layer header */
+        case getRecordLayerHeader:
+
+            ret = GetRecordHeader(ssl, ssl->buffers.inputBuffer.buffer,
+                                       &ssl->buffers.inputBuffer.idx,
+                                       &ssl->curRL, &ssl->curSize);
+#ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls && ret == SEQUENCE_ERROR) {
+                ssl->options.processReply = doProcessInit;
+                ssl->buffers.inputBuffer.length = 0;
+                ssl->buffers.inputBuffer.idx = 0;
+                continue;
+            }
+#endif
+            if (ret != 0)
+                return ret;
+
+            ssl->options.processReply = getData;
+
+        /* retrieve record layer data */
+        case getData:
+
+            /* get sz bytes or return error */
+            if (!ssl->options.dtls) {
+                if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
+                    return ret;
+            } else {
+#ifdef WOLFSSL_DTLS
+                /* read ahead may already have */
+                used = ssl->buffers.inputBuffer.length -
+                       ssl->buffers.inputBuffer.idx;
+                if (used < ssl->curSize)
+                    if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
+                        return ret;
+#endif
+            }
+
+            ssl->options.processReply = runProcessingOneMessage;
+            startIdx = ssl->buffers.inputBuffer.idx;  /* in case > 1 msg per */
+
+        /* the record layer is here */
+        case runProcessingOneMessage:
+
+            #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls &&
+                ssl->keys.dtls_state.curEpoch < ssl->keys.dtls_state.nextEpoch)
+                ssl->keys.decryptedCur = 1;
+            #endif
+
+            if (ssl->keys.encryptionOn && ssl->keys.decryptedCur == 0)
+            {
+                ret = SanityCheckCipherText(ssl, ssl->curSize);
+                if (ret < 0)
+                    return ret;
+
+                if (atomicUser) {
+                #ifdef ATOMIC_USER
+                    ret = ssl->ctx->DecryptVerifyCb(ssl,
+                                  ssl->buffers.inputBuffer.buffer +
+                                  ssl->buffers.inputBuffer.idx,
+                                  ssl->buffers.inputBuffer.buffer +
+                                  ssl->buffers.inputBuffer.idx,
+                                  ssl->curSize, ssl->curRL.type, 1,
+                                  &ssl->keys.padSz, ssl->DecryptVerifyCtx);
+                    if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
+                        ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
+                        /* go past TLSv1.1 IV */
+                    if (ssl->specs.cipher_type == aead &&
+                            ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
+                        ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ;
+                #endif /* ATOMIC_USER */
+                }
+                else {
+                    ret = Decrypt(ssl, ssl->buffers.inputBuffer.buffer +
+                                  ssl->buffers.inputBuffer.idx,
+                                  ssl->buffers.inputBuffer.buffer +
+                                  ssl->buffers.inputBuffer.idx,
+                                  ssl->curSize);
+                    if (ret < 0) {
+                        WOLFSSL_MSG("Decrypt failed");
+                        WOLFSSL_ERROR(ret);
+                        return DECRYPT_ERROR;
+                    }
+                    if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
+                        ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
+                        /* go past TLSv1.1 IV */
+                    if (ssl->specs.cipher_type == aead &&
+                            ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
+                        ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ;
+
+                    ret = VerifyMac(ssl, ssl->buffers.inputBuffer.buffer +
+                                    ssl->buffers.inputBuffer.idx,
+                                    ssl->curSize, ssl->curRL.type,
+                                    &ssl->keys.padSz);
+                }
+                if (ret < 0) {
+                    WOLFSSL_MSG("VerifyMac failed");
+                    WOLFSSL_ERROR(ret);
+                    return DECRYPT_ERROR;
+                }
+                ssl->keys.encryptSz    = ssl->curSize;
+                ssl->keys.decryptedCur = 1;
+            }
+
+            if (ssl->options.dtls) {
+            #ifdef WOLFSSL_DTLS
+                DtlsUpdateWindow(&ssl->keys.dtls_state);
+            #endif /* WOLFSSL_DTLS */
+            }
+
+            WOLFSSL_MSG("received record layer msg");
+
+            switch (ssl->curRL.type) {
+                case handshake :
+                    /* debugging in DoHandShakeMsg */
+                    if (!ssl->options.dtls) {
+                        ret = DoHandShakeMsg(ssl,
+                                            ssl->buffers.inputBuffer.buffer,
+                                            &ssl->buffers.inputBuffer.idx,
+                                            ssl->buffers.inputBuffer.length);
+                    }
+                    else {
+#ifdef WOLFSSL_DTLS
+                        ret = DoDtlsHandShakeMsg(ssl,
+                                            ssl->buffers.inputBuffer.buffer,
+                                            &ssl->buffers.inputBuffer.idx,
+                                            ssl->buffers.inputBuffer.length);
+#endif
+                    }
+                    if (ret != 0)
+                        return ret;
+                    break;
+
+                case change_cipher_spec:
+                    WOLFSSL_MSG("got CHANGE CIPHER SPEC");
+                    #ifdef WOLFSSL_CALLBACKS
+                        if (ssl->hsInfoOn)
+                            AddPacketName("ChangeCipher", &ssl->handShakeInfo);
+                        /* add record header back on info */
+                        if (ssl->toInfoOn) {
+                            AddPacketInfo("ChangeCipher", &ssl->timeoutInfo,
+                                ssl->buffers.inputBuffer.buffer +
+                                ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ,
+                                1 + RECORD_HEADER_SZ, ssl->heap);
+                            AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
+                        }
+                    #endif
+
+                    /* Check for duplicate CCS message in DTLS mode.
+                     * DTLS allows for duplicate messages, and it should be
+                     * skipped. */
+                    if (ssl->options.dtls &&
+                        ssl->msgsReceived.got_change_cipher) {
+
+                        WOLFSSL_MSG("Duplicate ChangeCipher msg");
+                        if (ssl->curSize != 1) {
+                            WOLFSSL_MSG("Malicious or corrupted"
+                                        " duplicate ChangeCipher msg");
+                            return LENGTH_ERROR;
+                        }
+                        ssl->buffers.inputBuffer.idx++;
+                        break;
+                    }
+
+                    ret = SanityCheckMsgReceived(ssl, change_cipher_hs);
+                    if (ret != 0)
+                        return ret;
+
+#ifdef HAVE_SESSION_TICKET
+                    if (ssl->options.side == WOLFSSL_CLIENT_END &&
+                                                  ssl->expect_session_ticket) {
+                        WOLFSSL_MSG("Expected session ticket missing");
+                        return SESSION_TICKET_EXPECT_E;
+                    }
+#endif
+
+                    if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
+                        ssl->buffers.inputBuffer.idx += ssl->keys.padSz;
+                        ssl->curSize -= (word16) ssl->buffers.inputBuffer.idx;
+                    }
+
+                    if (ssl->curSize != 1) {
+                        WOLFSSL_MSG("Malicious or corrupted ChangeCipher msg");
+                        return LENGTH_ERROR;
+                    }
+                    #ifndef NO_CERTS
+                        if (ssl->options.side == WOLFSSL_SERVER_END &&
+                                 ssl->options.verifyPeer &&
+                                 ssl->options.havePeerCert)
+                            if (!ssl->options.havePeerVerify) {
+                                WOLFSSL_MSG("client didn't send cert verify");
+                                return NO_PEER_VERIFY;
+                            }
+                    #endif
+
+
+                    ssl->buffers.inputBuffer.idx++;
+                    ssl->keys.encryptionOn = 1;
+
+                    /* setup decrypt keys for following messages */
+                    if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
+                        return ret;
+
+                    #ifdef WOLFSSL_DTLS
+                        if (ssl->options.dtls) {
+                            DtlsPoolReset(ssl);
+                            ssl->keys.dtls_state.nextEpoch++;
+                            ssl->keys.dtls_state.nextSeq = 0;
+                        }
+                    #endif
+
+                    #ifdef HAVE_LIBZ
+                        if (ssl->options.usingCompression)
+                            if ( (ret = InitStreams(ssl)) != 0)
+                                return ret;
+                    #endif
+                    ret = BuildFinished(ssl, &ssl->hsHashes->verifyHashes,
+                                       ssl->options.side == WOLFSSL_CLIENT_END ?
+                                       server : client);
+                    if (ret != 0)
+                        return ret;
+                    break;
+
+                case application_data:
+                    WOLFSSL_MSG("got app DATA");
+                    if ((ret = DoApplicationData(ssl,
+                                                ssl->buffers.inputBuffer.buffer,
+                                               &ssl->buffers.inputBuffer.idx))
+                                                                         != 0) {
+                        WOLFSSL_ERROR(ret);
+                        return ret;
+                    }
+                    break;
+
+                case alert:
+                    WOLFSSL_MSG("got ALERT!");
+                    ret = DoAlert(ssl, ssl->buffers.inputBuffer.buffer,
+                                  &ssl->buffers.inputBuffer.idx, &type,
+                                   ssl->buffers.inputBuffer.length);
+                    if (ret == alert_fatal)
+                        return FATAL_ERROR;
+                    else if (ret < 0)
+                        return ret;
+
+                    /* catch warnings that are handled as errors */
+                    if (type == close_notify)
+                        return ssl->error = ZERO_RETURN;
+
+                    if (type == decrypt_error)
+                        return FATAL_ERROR;
+                    break;
+
+                default:
+                    WOLFSSL_ERROR(UNKNOWN_RECORD_TYPE);
+                    return UNKNOWN_RECORD_TYPE;
+            }
+
+            ssl->options.processReply = doProcessInit;
+
+            /* input exhausted? */
+            if (ssl->buffers.inputBuffer.idx == ssl->buffers.inputBuffer.length)
+                return 0;
+
+            /* more messages per record */
+            else if ((ssl->buffers.inputBuffer.idx - startIdx) < ssl->curSize) {
+                WOLFSSL_MSG("More messages in record");
+                #ifdef WOLFSSL_DTLS
+                    /* read-ahead but dtls doesn't bundle messages per record */
+                    if (ssl->options.dtls) {
+                        ssl->options.processReply = doProcessInit;
+                        continue;
+                    }
+                #endif
+                ssl->options.processReply = runProcessingOneMessage;
+
+                if (ssl->keys.encryptionOn) {
+                    WOLFSSL_MSG("Bundled encrypted messages, remove middle pad");
+                    ssl->buffers.inputBuffer.idx -= ssl->keys.padSz;
+                }
+
+                continue;
+            }
+            /* more records */
+            else {
+                WOLFSSL_MSG("More records in input");
+                ssl->options.processReply = doProcessInit;
+                continue;
+            }
+
+        default:
+            WOLFSSL_MSG("Bad process input state, programming error");
+            return INPUT_CASE_ERROR;
+        }
+    }
+}
+
+
+int SendChangeCipher(WOLFSSL* ssl)
+{
+    byte              *output;
+    int                sendSz = RECORD_HEADER_SZ + ENUM_LEN;
+    int                idx    = RECORD_HEADER_SZ;
+    int                ret;
+
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            sendSz += DTLS_RECORD_EXTRA;
+            idx    += DTLS_RECORD_EXTRA;
+        }
+    #endif
+
+    /* are we in scr */
+    if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
+        sendSz += MAX_MSG_EXTRA;
+    }
+
+    /* check for avalaible size */
+    if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+        return ret;
+
+    /* get ouput buffer */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    AddRecordHeader(output, 1, change_cipher_spec, ssl);
+
+    output[idx] = 1;             /* turn it on */
+
+    if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
+        byte input[ENUM_LEN];
+        int  inputSz = ENUM_LEN;
+
+        input[0] = 1;  /* turn it on */
+        sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
+                              change_cipher_spec);
+        if (sendSz < 0)
+            return sendSz;
+    }
+
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
+                return ret;
+        }
+    #endif
+    #ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName("ChangeCipher", &ssl->handShakeInfo);
+        if (ssl->toInfoOn)
+            AddPacketInfo("ChangeCipher", &ssl->timeoutInfo, output, sendSz,
+                           ssl->heap);
+    #endif
+    ssl->buffers.outputBuffer.length += sendSz;
+
+    if (ssl->options.groupMessages)
+        return 0;
+    #ifdef WOLFSSL_DTLS
+    else if (ssl->options.dtls) {
+        /* If using DTLS, force the ChangeCipherSpec message to be in the
+         * same datagram as the finished message. */
+        return 0;
+    }
+    #endif
+    else
+        return SendBuffered(ssl);
+}
+
+
+#ifndef NO_OLD_TLS
+static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
+                 int content, int verify)
+{
+    byte   result[MAX_DIGEST_SIZE];
+    word32 digestSz = ssl->specs.hash_size;            /* actual sizes */
+    word32 padSz    = ssl->specs.pad_size;
+    int    ret      = 0;
+
+    Md5 md5;
+    Sha sha;
+
+    /* data */
+    byte seq[SEQ_SZ];
+    byte conLen[ENUM_LEN + LENGTH_SZ];     /* content & length */
+    const byte* macSecret = wolfSSL_GetMacSecret(ssl, verify);
+
+#ifdef HAVE_FUZZER
+    if (ssl->fuzzerCb)
+        ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
+#endif
+
+    XMEMSET(seq, 0, SEQ_SZ);
+    conLen[0] = (byte)content;
+    c16toa((word16)sz, &conLen[ENUM_LEN]);
+    c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]);
+
+    if (ssl->specs.mac_algorithm == md5_mac) {
+        wc_InitMd5(&md5);
+        /* inner */
+        wc_Md5Update(&md5, macSecret, digestSz);
+        wc_Md5Update(&md5, PAD1, padSz);
+        wc_Md5Update(&md5, seq, SEQ_SZ);
+        wc_Md5Update(&md5, conLen, sizeof(conLen));
+        /* in buffer */
+        wc_Md5Update(&md5, in, sz);
+        wc_Md5Final(&md5, result);
+        /* outer */
+        wc_Md5Update(&md5, macSecret, digestSz);
+        wc_Md5Update(&md5, PAD2, padSz);
+        wc_Md5Update(&md5, result, digestSz);
+        wc_Md5Final(&md5, digest);
+    }
+    else {
+        ret = wc_InitSha(&sha);
+        if (ret != 0)
+            return ret;
+        /* inner */
+        wc_ShaUpdate(&sha, macSecret, digestSz);
+        wc_ShaUpdate(&sha, PAD1, padSz);
+        wc_ShaUpdate(&sha, seq, SEQ_SZ);
+        wc_ShaUpdate(&sha, conLen, sizeof(conLen));
+        /* in buffer */
+        wc_ShaUpdate(&sha, in, sz);
+        wc_ShaFinal(&sha, result);
+        /* outer */
+        wc_ShaUpdate(&sha, macSecret, digestSz);
+        wc_ShaUpdate(&sha, PAD2, padSz);
+        wc_ShaUpdate(&sha, result, digestSz);
+        wc_ShaFinal(&sha, digest);
+    }
+    return 0;
+}
+
+#ifndef NO_CERTS
+static void BuildMD5_CertVerify(WOLFSSL* ssl, byte* digest)
+{
+    byte md5_result[MD5_DIGEST_SIZE];
+
+#ifdef WOLFSSL_SMALL_STACK
+        Md5* md5   = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        Md5* md5_2 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#else
+        Md5 md5[1];
+        Md5 md5_2[1];
+#endif
+
+    /* make md5 inner */
+    md5[0] = ssl->hsHashes->hashMd5 ; /* Save current position */
+    wc_Md5Update(&ssl->hsHashes->hashMd5, ssl->arrays->masterSecret,SECRET_LEN);
+    wc_Md5Update(&ssl->hsHashes->hashMd5, PAD1, PAD_MD5);
+    wc_Md5GetHash(&ssl->hsHashes->hashMd5, md5_result);
+    wc_Md5RestorePos(&ssl->hsHashes->hashMd5, md5) ; /* Restore current position */
+
+    /* make md5 outer */
+    wc_InitMd5(md5_2) ;
+    wc_Md5Update(md5_2, ssl->arrays->masterSecret, SECRET_LEN);
+    wc_Md5Update(md5_2, PAD2, PAD_MD5);
+    wc_Md5Update(md5_2, md5_result, MD5_DIGEST_SIZE);
+
+    wc_Md5Final(md5_2, digest);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(md5_2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+}
+
+
+static void BuildSHA_CertVerify(WOLFSSL* ssl, byte* digest)
+{
+    byte sha_result[SHA_DIGEST_SIZE];
+
+#ifdef WOLFSSL_SMALL_STACK
+        Sha* sha   = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        Sha* sha2 = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#else
+        Sha sha[1];
+        Sha sha2[1];
+#endif
+
+    /* make sha inner */
+    sha[0] = ssl->hsHashes->hashSha ; /* Save current position */
+    wc_ShaUpdate(&ssl->hsHashes->hashSha, ssl->arrays->masterSecret,SECRET_LEN);
+    wc_ShaUpdate(&ssl->hsHashes->hashSha, PAD1, PAD_SHA);
+    wc_ShaGetHash(&ssl->hsHashes->hashSha, sha_result);
+    wc_ShaRestorePos(&ssl->hsHashes->hashSha, sha) ; /* Restore current position */
+
+    /* make sha outer */
+    wc_InitSha(sha2) ;
+    wc_ShaUpdate(sha2, ssl->arrays->masterSecret,SECRET_LEN);
+    wc_ShaUpdate(sha2, PAD2, PAD_SHA);
+    wc_ShaUpdate(sha2, sha_result, SHA_DIGEST_SIZE);
+
+    wc_ShaFinal(sha2, digest);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(sha2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+}
+#endif /* NO_CERTS */
+#endif /* NO_OLD_TLS */
+
+
+#ifndef NO_CERTS
+
+static int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes)
+{
+    /* store current states, building requires get_digest which resets state */
+    #ifdef WOLFSSL_SHA384
+        Sha384 sha384 = ssl->hsHashes->hashSha384;
+    #endif
+    #ifdef WOLFSSL_SHA512
+        Sha512 sha512 = ssl->hsHashes->hashSha512;
+    #endif
+
+    if (ssl->options.tls) {
+#if ! defined( NO_OLD_TLS )
+        wc_Md5GetHash(&ssl->hsHashes->hashMd5, hashes->md5);
+        wc_ShaGetHash(&ssl->hsHashes->hashSha, hashes->sha);
+#endif
+        if (IsAtLeastTLSv1_2(ssl)) {
+            int ret;
+
+            #ifndef NO_SHA256
+                ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256,hashes->sha256);
+                if (ret != 0)
+                    return ret;
+            #endif
+            #ifdef WOLFSSL_SHA384
+                ret = wc_Sha384Final(&ssl->hsHashes->hashSha384,hashes->sha384);
+                if (ret != 0)
+                    return ret;
+            #endif
+            #ifdef WOLFSSL_SHA512
+                ret = wc_Sha512Final(&ssl->hsHashes->hashSha512,hashes->sha512);
+                if (ret != 0)
+                    return ret;
+            #endif
+        }
+    }
+#if ! defined( NO_OLD_TLS )
+    else {
+        BuildMD5_CertVerify(ssl, hashes->md5);
+        BuildSHA_CertVerify(ssl, hashes->sha);
+    }
+
+    /* restore */
+#endif
+    if (IsAtLeastTLSv1_2(ssl)) {
+        #ifdef WOLFSSL_SHA384
+            ssl->hsHashes->hashSha384 = sha384;
+        #endif
+        #ifdef WOLFSSL_SHA512
+            ssl->hsHashes->hashSha512 = sha512;
+        #endif
+    }
+
+    return 0;
+}
+
+#endif /* WOLFSSL_LEANPSK */
+
+/* Build SSL Message, encrypted */
+static int BuildMessage(WOLFSSL* ssl, byte* output, int outSz,
+                        const byte* input, int inSz, int type)
+{
+#ifdef HAVE_TRUNCATED_HMAC
+    word32 digestSz = min(ssl->specs.hash_size,
+                ssl->truncated_hmac ? TRUNCATED_HMAC_SZ : ssl->specs.hash_size);
+#else
+    word32 digestSz = ssl->specs.hash_size;
+#endif
+    word32 sz = RECORD_HEADER_SZ + inSz + digestSz;
+    word32 pad  = 0, i;
+    word32 idx  = RECORD_HEADER_SZ;
+    word32 ivSz = 0;      /* TLSv1.1  IV */
+    word32 headerSz = RECORD_HEADER_SZ;
+    word16 size;
+    byte               iv[AES_BLOCK_SIZE];                  /* max size */
+    int ret        = 0;
+    int atomicUser = 0;
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        sz       += DTLS_RECORD_EXTRA;
+        idx      += DTLS_RECORD_EXTRA;
+        headerSz += DTLS_RECORD_EXTRA;
+    }
+#endif
+
+#ifdef ATOMIC_USER
+    if (ssl->ctx->MacEncryptCb)
+        atomicUser = 1;
+#endif
+
+    if (ssl->specs.cipher_type == block) {
+        word32 blockSz = ssl->specs.block_size;
+        if (ssl->options.tls1_1) {
+            ivSz = blockSz;
+            sz  += ivSz;
+
+            if (ivSz > (word32)sizeof(iv))
+                return BUFFER_E;
+
+            ret = wc_RNG_GenerateBlock(ssl->rng, iv, ivSz);
+            if (ret != 0)
+                return ret;
+
+        }
+        sz += 1;       /* pad byte */
+        pad = (sz - headerSz) % blockSz;
+        pad = blockSz - pad;
+        sz += pad;
+    }
+
+#ifdef HAVE_AEAD
+    if (ssl->specs.cipher_type == aead) {
+        if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
+            ivSz = AEAD_EXP_IV_SZ;
+
+        sz += (ivSz + ssl->specs.aead_mac_size - digestSz);
+        XMEMCPY(iv, ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
+    }
+#endif
+    if (sz > (word32)outSz) {
+        WOLFSSL_MSG("Oops, want to write past output buffer size");
+        return BUFFER_E;
+    }
+    size = (word16)(sz - headerSz);    /* include mac and digest */
+    AddRecordHeader(output, size, (byte)type, ssl);
+
+    /* write to output */
+    if (ivSz) {
+        XMEMCPY(output + idx, iv, min(ivSz, sizeof(iv)));
+        idx += ivSz;
+    }
+    XMEMCPY(output + idx, input, inSz);
+    idx += inSz;
+
+    if (type == handshake) {
+        ret = HashOutput(ssl, output, headerSz + inSz, ivSz);
+        if (ret != 0)
+            return ret;
+    }
+
+    if (ssl->specs.cipher_type == block) {
+        word32 tmpIdx = idx + digestSz;
+
+        for (i = 0; i <= pad; i++)
+            output[tmpIdx++] = (byte)pad; /* pad byte gets pad value too */
+    }
+
+    if (atomicUser) {   /* User Record Layer Callback handling */
+#ifdef ATOMIC_USER
+        if ( (ret = ssl->ctx->MacEncryptCb(ssl, output + idx,
+                        output + headerSz + ivSz, inSz, type, 0,
+                        output + headerSz, output + headerSz, size,
+                        ssl->MacEncryptCtx)) != 0)
+            return ret;
+#endif
+    }
+    else {
+        if (ssl->specs.cipher_type != aead) {
+#ifdef HAVE_TRUNCATED_HMAC
+            if (ssl->truncated_hmac && ssl->specs.hash_size > digestSz) {
+            #ifdef WOLFSSL_SMALL_STACK
+                byte* hmac = NULL;
+            #else
+                byte  hmac[MAX_DIGEST_SIZE];
+            #endif
+
+            #ifdef WOLFSSL_SMALL_STACK
+                hmac = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                if (hmac == NULL)
+                    return MEMORY_E;
+            #endif
+
+                ret = ssl->hmac(ssl, hmac, output + headerSz + ivSz, inSz,
+                                                                       type, 0);
+                XMEMCPY(output + idx, hmac, digestSz);
+
+            #ifdef WOLFSSL_SMALL_STACK
+                XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+            } else
+#endif
+                ret = ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz,
+                                                                       type, 0);
+        }
+        if (ret != 0)
+            return ret;
+
+        if ( (ret = Encrypt(ssl, output + headerSz, output+headerSz,size)) != 0)
+            return ret;
+    }
+
+    return sz;
+}
+
+
+int SendFinished(WOLFSSL* ssl)
+{
+    int              sendSz,
+                     finishedSz = ssl->options.tls ? TLS_FINISHED_SZ :
+                                                     FINISHED_SZ;
+    byte             input[FINISHED_SZ + DTLS_HANDSHAKE_HEADER_SZ];  /* max */
+    byte            *output;
+    Hashes*          hashes;
+    int              ret;
+    int              headerSz = HANDSHAKE_HEADER_SZ;
+    int              outputSz;
+
+    #ifdef WOLFSSL_DTLS
+        word32 sequence_number = ssl->keys.dtls_sequence_number;
+        word16 epoch           = ssl->keys.dtls_epoch;
+    #endif
+
+    /* setup encrypt keys */
+    if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
+        return ret;
+
+    /* check for available size */
+    outputSz = sizeof(input) + MAX_MSG_EXTRA;
+    if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
+        return ret;
+
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            /* Send Finished message with the next epoch, but don't commit that
+             * change until the other end confirms its reception. */
+            headerSz += DTLS_HANDSHAKE_EXTRA;
+            ssl->keys.dtls_epoch++;
+            ssl->keys.dtls_sequence_number = 0;  /* reset after epoch change */
+        }
+    #endif
+
+    /* get ouput buffer */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    AddHandShakeHeader(input, finishedSz, 0, finishedSz, finished, ssl);
+
+    /* make finished hashes */
+    hashes = (Hashes*)&input[headerSz];
+    ret = BuildFinished(ssl, hashes,
+                     ssl->options.side == WOLFSSL_CLIENT_END ? client : server);
+    if (ret != 0) return ret;
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+    if (ssl->secure_renegotiation) {
+        if (ssl->options.side == WOLFSSL_CLIENT_END)
+            XMEMCPY(ssl->secure_renegotiation->client_verify_data, hashes,
+                    TLS_FINISHED_SZ);
+        else
+            XMEMCPY(ssl->secure_renegotiation->server_verify_data, hashes,
+                    TLS_FINISHED_SZ);
+    }
+#endif
+
+    sendSz = BuildMessage(ssl, output, outputSz, input, headerSz + finishedSz,
+                          handshake);
+    if (sendSz < 0)
+        return BUILD_MSG_ERROR;
+
+    #ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        ssl->keys.dtls_epoch = epoch;
+        ssl->keys.dtls_sequence_number = sequence_number;
+    }
+    #endif
+
+    if (!ssl->options.resuming) {
+#ifndef NO_SESSION_CACHE
+        AddSession(ssl);    /* just try */
+#endif
+        if (ssl->options.side == WOLFSSL_SERVER_END) {
+            ssl->options.handShakeState = HANDSHAKE_DONE;
+            ssl->options.handShakeDone  = 1;
+            #ifdef WOLFSSL_DTLS
+                if (ssl->options.dtls) {
+                    /* Other side will soon receive our Finished, go to next
+                     * epoch. */
+                    ssl->keys.dtls_epoch++;
+                    ssl->keys.dtls_sequence_number = 1;
+                }
+            #endif
+        }
+    }
+    else {
+        if (ssl->options.side == WOLFSSL_CLIENT_END) {
+            ssl->options.handShakeState = HANDSHAKE_DONE;
+            ssl->options.handShakeDone  = 1;
+            #ifdef WOLFSSL_DTLS
+                if (ssl->options.dtls) {
+                    /* Other side will soon receive our Finished, go to next
+                     * epoch. */
+                    ssl->keys.dtls_epoch++;
+                    ssl->keys.dtls_sequence_number = 1;
+                }
+            #endif
+        }
+    }
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
+                return ret;
+        }
+    #endif
+
+    #ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
+        if (ssl->toInfoOn)
+            AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz,
+                          ssl->heap);
+    #endif
+
+    ssl->buffers.outputBuffer.length += sendSz;
+
+    return SendBuffered(ssl);
+}
+
+
+#ifndef NO_CERTS
+int SendCertificate(WOLFSSL* ssl)
+{
+    int    ret = 0;
+    word32 certSz, certChainSz, headerSz, listSz, payloadSz;
+    word32 length, maxFragment;
+
+    if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
+        return 0;  /* not needed */
+
+    if (ssl->options.sendVerify == SEND_BLANK_CERT) {
+        certSz = 0;
+        certChainSz = 0;
+        headerSz = CERT_HEADER_SZ;
+        length = CERT_HEADER_SZ;
+        listSz = 0;
+    }
+    else {
+        certSz = ssl->buffers.certificate.length;
+        headerSz = 2 * CERT_HEADER_SZ;
+        /* list + cert size */
+        length = certSz + headerSz;
+        listSz = certSz + CERT_HEADER_SZ;
+
+        /* may need to send rest of chain, already has leading size(s) */
+        if (certSz) {
+            certChainSz = ssl->buffers.certChain.length;
+            length += certChainSz;
+            listSz += certChainSz;
+        }
+        else
+            certChainSz = 0;
+    }
+
+    payloadSz = length;
+
+    if (ssl->fragOffset != 0)
+        length -= (ssl->fragOffset + headerSz);
+
+    maxFragment = MAX_RECORD_SIZE;
+    if (ssl->options.dtls) {
+    #ifdef WOLFSSL_DTLS
+        maxFragment = MAX_MTU - DTLS_RECORD_HEADER_SZ
+                      - DTLS_HANDSHAKE_HEADER_SZ - 100;
+    #endif /* WOLFSSL_DTLS */
+    }
+
+    #ifdef HAVE_MAX_FRAGMENT
+    if (ssl->max_fragment != 0 && maxFragment >= ssl->max_fragment)
+        maxFragment = ssl->max_fragment;
+    #endif /* HAVE_MAX_FRAGMENT */
+
+    while (length > 0 && ret == 0) {
+        byte*  output = NULL;
+        word32 fragSz = 0;
+        word32 i = RECORD_HEADER_SZ;
+        int    sendSz = RECORD_HEADER_SZ;
+
+        if (!ssl->options.dtls) {
+            if (ssl->fragOffset == 0)  {
+                if (headerSz + certSz + certChainSz <=
+                    maxFragment - HANDSHAKE_HEADER_SZ) {
+
+                    fragSz = headerSz + certSz + certChainSz;
+                }
+                else {
+                    fragSz = maxFragment - HANDSHAKE_HEADER_SZ;
+                }
+                sendSz += fragSz + HANDSHAKE_HEADER_SZ;
+                i += HANDSHAKE_HEADER_SZ;
+            }
+            else {
+                fragSz = min(length, maxFragment);
+                sendSz += fragSz;
+            }
+
+            if (ssl->keys.encryptionOn)
+                sendSz += MAX_MSG_EXTRA;
+        }
+        else {
+        #ifdef WOLFSSL_DTLS
+            fragSz = min(length, maxFragment);
+            sendSz += fragSz + DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA
+                      + HANDSHAKE_HEADER_SZ;
+            i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA
+                      + HANDSHAKE_HEADER_SZ;
+        #endif
+        }
+
+        /* check for available size */
+        if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+            return ret;
+
+        /* get ouput buffer */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        if (ssl->fragOffset == 0) {
+            if (!ssl->options.dtls) {
+                AddFragHeaders(output, fragSz, 0, payloadSz, certificate, ssl);
+                if (!ssl->keys.encryptionOn)
+                    HashOutputRaw(ssl, output + RECORD_HEADER_SZ,
+                                  HANDSHAKE_HEADER_SZ);
+            }
+            else {
+            #ifdef WOLFSSL_DTLS
+                AddHeaders(output, payloadSz, certificate, ssl);
+                if (!ssl->keys.encryptionOn)
+                    HashOutputRaw(ssl,
+                                  output + RECORD_HEADER_SZ + DTLS_RECORD_EXTRA,
+                                  HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA);
+                /* Adding the headers increments these, decrement them for
+                 * actual message header. */
+                ssl->keys.dtls_sequence_number--;
+                ssl->keys.dtls_handshake_number--;
+                AddFragHeaders(output, fragSz, 0, payloadSz, certificate, ssl);
+                ssl->keys.dtls_handshake_number--;
+            #endif /* WOLFSSL_DTLS */
+            }
+
+            /* list total */
+            c32to24(listSz, output + i);
+            if (!ssl->keys.encryptionOn)
+                HashOutputRaw(ssl, output + i, CERT_HEADER_SZ);
+            i += CERT_HEADER_SZ;
+            length -= CERT_HEADER_SZ;
+            fragSz -= CERT_HEADER_SZ;
+            if (certSz) {
+                c32to24(certSz, output + i);
+                if (!ssl->keys.encryptionOn)
+                    HashOutputRaw(ssl, output + i, CERT_HEADER_SZ);
+                i += CERT_HEADER_SZ;
+                length -= CERT_HEADER_SZ;
+                fragSz -= CERT_HEADER_SZ;
+
+                if (!ssl->keys.encryptionOn) {
+                    HashOutputRaw(ssl, ssl->buffers.certificate.buffer, certSz);
+                    if (certChainSz)
+                        HashOutputRaw(ssl, ssl->buffers.certChain.buffer,
+                                      certChainSz);
+                }
+            }
+        }
+        else {
+            if (!ssl->options.dtls) {
+                AddRecordHeader(output, fragSz, handshake, ssl);
+            }
+            else {
+            #ifdef WOLFSSL_DTLS
+                AddFragHeaders(output, fragSz, ssl->fragOffset + headerSz,
+                               payloadSz, certificate, ssl);
+                ssl->keys.dtls_handshake_number--;
+            #endif /* WOLFSSL_DTLS */
+            }
+        }
+
+        /* member */
+        if (certSz && ssl->fragOffset < certSz) {
+            word32 copySz = min(certSz - ssl->fragOffset, fragSz);
+            XMEMCPY(output + i,
+                    ssl->buffers.certificate.buffer + ssl->fragOffset, copySz);
+            i += copySz;
+            ssl->fragOffset += copySz;
+            length -= copySz;
+            fragSz -= copySz;
+        }
+        if (certChainSz && fragSz) {
+            word32 copySz = min(certChainSz + certSz - ssl->fragOffset, fragSz);
+            XMEMCPY(output + i,
+                    ssl->buffers.certChain.buffer + ssl->fragOffset - certSz,
+                    copySz);
+            i += copySz;
+            ssl->fragOffset += copySz;
+            length -= copySz;
+        }
+
+        if (ssl->keys.encryptionOn) {
+            byte* input;
+            int   inputSz = i - RECORD_HEADER_SZ; /* build msg adds rec hdr */
+
+            input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            if (input == NULL)
+                return MEMORY_E;
+
+            XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
+            sendSz = BuildMessage(ssl, output, sendSz, input,inputSz,handshake);
+            XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+
+            if (sendSz < 0)
+                return sendSz;
+        }
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
+                    return ret;
+            }
+        #endif
+
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName("Certificate", &ssl->handShakeInfo);
+            if (ssl->toInfoOn)
+                AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz,
+                               ssl->heap);
+        #endif
+
+        ssl->buffers.outputBuffer.length += sendSz;
+        if (!ssl->options.groupMessages)
+            ret = SendBuffered(ssl);
+    }
+
+    if (ret != WANT_WRITE) {
+        /* Clean up the fragment offset. */
+        ssl->fragOffset = 0;
+        #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls)
+            ssl->keys.dtls_handshake_number++;
+        #endif
+        if (ssl->options.side == WOLFSSL_SERVER_END)
+            ssl->options.serverState = SERVER_CERT_COMPLETE;
+    }
+
+    return ret;
+}
+
+
+int SendCertificateRequest(WOLFSSL* ssl)
+{
+    byte   *output;
+    int    ret;
+    int    sendSz;
+    word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+
+    int  typeTotal = 1;  /* only 1 for now */
+    int  reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ;  /* add auth later */
+
+    if (IsAtLeastTLSv1_2(ssl))
+        reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz;
+
+    if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
+        return 0;  /* not needed */
+
+    sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
+
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+            i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+        }
+    #endif
+    /* check for available size */
+    if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+        return ret;
+
+    /* get ouput buffer */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    AddHeaders(output, reqSz, certificate_request, ssl);
+
+    /* write to output */
+    output[i++] = (byte)typeTotal;  /* # of types */
+#ifdef HAVE_ECC
+    if (ssl->options.cipherSuite0 == ECC_BYTE &&
+                     ssl->specs.sig_algo == ecc_dsa_sa_algo) {
+        output[i++] = ecdsa_sign;
+    } else
+#endif /* HAVE_ECC */
+    {
+        output[i++] = rsa_sign;
+    }
+
+    /* supported hash/sig */
+    if (IsAtLeastTLSv1_2(ssl)) {
+        c16toa(ssl->suites->hashSigAlgoSz, &output[i]);
+        i += LENGTH_SZ;
+
+        XMEMCPY(&output[i],
+                         ssl->suites->hashSigAlgo, ssl->suites->hashSigAlgoSz);
+        i += ssl->suites->hashSigAlgoSz;
+    }
+
+    c16toa(0, &output[i]);  /* auth's */
+    /* if add more to output, adjust i
+    i += REQ_HEADER_SZ; */
+
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
+                return ret;
+        }
+    #endif
+
+    ret = HashOutput(ssl, output, sendSz, 0);
+    if (ret != 0)
+        return ret;
+
+    #ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn)
+            AddPacketName("CertificateRequest", &ssl->handShakeInfo);
+        if (ssl->toInfoOn)
+            AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output,
+                          sendSz, ssl->heap);
+    #endif
+    ssl->buffers.outputBuffer.length += sendSz;
+    if (ssl->options.groupMessages)
+        return 0;
+    else
+        return SendBuffered(ssl);
+}
+#endif /* !NO_CERTS */
+
+
+int SendData(WOLFSSL* ssl, const void* data, int sz)
+{
+    int sent = 0,  /* plainText size */
+        sendSz,
+        ret,
+        dtlsExtra = 0;
+
+    if (ssl->error == WANT_WRITE)
+        ssl->error = 0;
+
+    if (ssl->options.handShakeState != HANDSHAKE_DONE) {
+        int err;
+        WOLFSSL_MSG("handshake not complete, trying to finish");
+        if ( (err = wolfSSL_negotiate(ssl)) != SSL_SUCCESS)
+            return  err;
+    }
+
+    /* last time system socket output buffer was full, try again to send */
+    if (ssl->buffers.outputBuffer.length > 0) {
+        WOLFSSL_MSG("output buffer was full, trying to send again");
+        if ( (ssl->error = SendBuffered(ssl)) < 0) {
+            WOLFSSL_ERROR(ssl->error);
+            if (ssl->error == SOCKET_ERROR_E && ssl->options.connReset)
+                return 0;     /* peer reset */
+            return ssl->error;
+        }
+        else {
+            /* advance sent to previous sent + plain size just sent */
+            sent = ssl->buffers.prevSent + ssl->buffers.plainSz;
+            WOLFSSL_MSG("sent write buffered data");
+
+            if (sent > sz) {
+                WOLFSSL_MSG("error: write() after WANT_WRITE with short size");
+                return ssl->error = BAD_FUNC_ARG;
+            }
+        }
+    }
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        dtlsExtra = DTLS_RECORD_EXTRA;
+    }
+#endif
+
+    for (;;) {
+#ifdef HAVE_MAX_FRAGMENT
+        int   len = min(sz - sent, min(ssl->max_fragment, OUTPUT_RECORD_SIZE));
+#else
+        int   len = min(sz - sent, OUTPUT_RECORD_SIZE);
+#endif
+        byte* out;
+        byte* sendBuffer = (byte*)data + sent;  /* may switch on comp */
+        int   buffSz = len;                     /* may switch on comp */
+        int   outputSz;
+#ifdef HAVE_LIBZ
+        byte  comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
+#endif
+
+        if (sent == sz) break;
+
+#ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            len    = min(len, MAX_UDP_SIZE);
+            buffSz = len;
+        }
+#endif
+
+        /* check for available size */
+        outputSz = len + COMP_EXTRA + dtlsExtra + MAX_MSG_EXTRA;
+        if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
+            return ssl->error = ret;
+
+        /* get ouput buffer */
+        out = ssl->buffers.outputBuffer.buffer +
+              ssl->buffers.outputBuffer.length;
+
+#ifdef HAVE_LIBZ
+        if (ssl->options.usingCompression) {
+            buffSz = myCompress(ssl, sendBuffer, buffSz, comp, sizeof(comp));
+            if (buffSz < 0) {
+                return buffSz;
+            }
+            sendBuffer = comp;
+        }
+#endif
+        sendSz = BuildMessage(ssl, out, outputSz, sendBuffer, buffSz,
+                              application_data);
+        if (sendSz < 0)
+            return BUILD_MSG_ERROR;
+
+        ssl->buffers.outputBuffer.length += sendSz;
+
+        if ( (ret = SendBuffered(ssl)) < 0) {
+            WOLFSSL_ERROR(ret);
+            /* store for next call if WANT_WRITE or user embedSend() that
+               doesn't present like WANT_WRITE */
+            ssl->buffers.plainSz  = len;
+            ssl->buffers.prevSent = sent;
+            if (ret == SOCKET_ERROR_E && ssl->options.connReset)
+                return 0;  /* peer reset */
+            return ssl->error = ret;
+        }
+
+        sent += len;
+
+        /* only one message per attempt */
+        if (ssl->options.partialWrite == 1) {
+            WOLFSSL_MSG("Paritial Write on, only sending one record");
+            break;
+        }
+    }
+
+    return sent;
+}
+
+/* process input data */
+int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
+{
+    int size;
+
+    WOLFSSL_ENTER("ReceiveData()");
+
+    if (ssl->error == WANT_READ)
+        ssl->error = 0;
+
+    if (ssl->error != 0 && ssl->error != WANT_WRITE) {
+        WOLFSSL_MSG("User calling wolfSSL_read in error state, not allowed");
+        return ssl->error;
+    }
+
+    if (ssl->options.handShakeState != HANDSHAKE_DONE) {
+        int err;
+        WOLFSSL_MSG("Handshake not complete, trying to finish");
+        if ( (err = wolfSSL_negotiate(ssl)) != SSL_SUCCESS)
+            return  err;
+    }
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+startScr:
+    if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
+        int err;
+        ssl->secure_renegotiation->startScr = 0;  /* only start once */
+        WOLFSSL_MSG("Need to start scr, server requested");
+        if ( (err = wolfSSL_Rehandshake(ssl)) != SSL_SUCCESS)
+            return  err;
+    }
+#endif
+
+    while (ssl->buffers.clearOutputBuffer.length == 0) {
+        if ( (ssl->error = ProcessReply(ssl)) < 0) {
+            WOLFSSL_ERROR(ssl->error);
+            if (ssl->error == ZERO_RETURN) {
+                WOLFSSL_MSG("Zero return, no more data coming");
+                return 0;         /* no more data coming */
+            }
+            if (ssl->error == SOCKET_ERROR_E) {
+                if (ssl->options.connReset || ssl->options.isClosed) {
+                    WOLFSSL_MSG("Peer reset or closed, connection done");
+                    ssl->error = SOCKET_PEER_CLOSED_E;
+                    WOLFSSL_ERROR(ssl->error);
+                    return 0;     /* peer reset or closed */
+                }
+            }
+            return ssl->error;
+        }
+        #ifdef HAVE_SECURE_RENEGOTIATION
+            if (ssl->secure_renegotiation &&
+                ssl->secure_renegotiation->startScr) {
+                goto startScr;
+            }
+        #endif
+    }
+
+    if (sz < (int)ssl->buffers.clearOutputBuffer.length)
+        size = sz;
+    else
+        size = ssl->buffers.clearOutputBuffer.length;
+
+    XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size);
+
+    if (peek == 0) {
+        ssl->buffers.clearOutputBuffer.length -= size;
+        ssl->buffers.clearOutputBuffer.buffer += size;
+    }
+
+    if (ssl->buffers.clearOutputBuffer.length == 0 &&
+                                           ssl->buffers.inputBuffer.dynamicFlag)
+       ShrinkInputBuffer(ssl, NO_FORCED_FREE);
+
+    WOLFSSL_LEAVE("ReceiveData()", size);
+    return size;
+}
+
+
+/* send alert message */
+int SendAlert(WOLFSSL* ssl, int severity, int type)
+{
+    byte input[ALERT_SIZE];
+    byte *output;
+    int  sendSz;
+    int  ret;
+    int  outputSz;
+    int  dtlsExtra = 0;
+
+    /* if sendalert is called again for nonbloking */
+    if (ssl->options.sendAlertState != 0) {
+        ret = SendBuffered(ssl);
+        if (ret == 0)
+            ssl->options.sendAlertState = 0;
+        return ret;
+    }
+
+   #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls)
+           dtlsExtra = DTLS_RECORD_EXTRA;
+   #endif
+
+    /* check for available size */
+    outputSz = ALERT_SIZE + MAX_MSG_EXTRA + dtlsExtra;
+    if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
+        return ret;
+
+    /* get ouput buffer */
+    output = ssl->buffers.outputBuffer.buffer +
+             ssl->buffers.outputBuffer.length;
+
+    input[0] = (byte)severity;
+    input[1] = (byte)type;
+    ssl->alert_history.last_tx.code = type;
+    ssl->alert_history.last_tx.level = severity;
+    if (severity == alert_fatal) {
+        ssl->options.isClosed = 1;  /* Don't send close_notify */
+    }
+
+    /* only send encrypted alert if handshake actually complete, otherwise
+       other side may not be able to handle it */
+    if (ssl->keys.encryptionOn && ssl->options.handShakeDone)
+        sendSz = BuildMessage(ssl, output, outputSz, input, ALERT_SIZE, alert);
+    else {
+
+        AddRecordHeader(output, ALERT_SIZE, alert, ssl);
+        output += RECORD_HEADER_SZ;
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls)
+                output += DTLS_RECORD_EXTRA;
+        #endif
+        XMEMCPY(output, input, ALERT_SIZE);
+
+        sendSz = RECORD_HEADER_SZ + ALERT_SIZE;
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls)
+                sendSz += DTLS_RECORD_EXTRA;
+        #endif
+    }
+    if (sendSz < 0)
+        return BUILD_MSG_ERROR;
+
+    #ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn)
+            AddPacketName("Alert", &ssl->handShakeInfo);
+        if (ssl->toInfoOn)
+            AddPacketInfo("Alert", &ssl->timeoutInfo, output, sendSz,ssl->heap);
+    #endif
+
+    ssl->buffers.outputBuffer.length += sendSz;
+    ssl->options.sendAlertState = 1;
+
+    return SendBuffered(ssl);
+}
+
+const char* wolfSSL_ERR_reason_error_string(unsigned long e)
+{
+#ifdef NO_ERROR_STRINGS
+
+    (void)e;
+    return "no support for error strings built in";
+
+#else
+
+    int error = (int)e;
+
+    /* pass to wolfCrypt */
+    if (error < MAX_CODE_E && error > MIN_CODE_E) {
+        return wc_GetErrorString(error);
+    }
+
+    switch (error) {
+
+    case UNSUPPORTED_SUITE :
+        return "unsupported cipher suite";
+
+    case INPUT_CASE_ERROR :
+        return "input state error";
+
+    case PREFIX_ERROR :
+        return "bad index to key rounds";
+
+    case MEMORY_ERROR :
+        return "out of memory";
+
+    case VERIFY_FINISHED_ERROR :
+        return "verify problem on finished";
+
+    case VERIFY_MAC_ERROR :
+        return "verify mac problem";
+
+    case PARSE_ERROR :
+        return "parse error on header";
+
+    case SIDE_ERROR :
+        return "wrong client/server type";
+
+    case NO_PEER_CERT :
+        return "peer didn't send cert";
+
+    case UNKNOWN_HANDSHAKE_TYPE :
+        return "weird handshake type";
+
+    case SOCKET_ERROR_E :
+        return "error state on socket";
+
+    case SOCKET_NODATA :
+        return "expected data, not there";
+
+    case INCOMPLETE_DATA :
+        return "don't have enough data to complete task";
+
+    case UNKNOWN_RECORD_TYPE :
+        return "unknown type in record hdr";
+
+    case DECRYPT_ERROR :
+        return "error during decryption";
+
+    case FATAL_ERROR :
+        return "revcd alert fatal error";
+
+    case ENCRYPT_ERROR :
+        return "error during encryption";
+
+    case FREAD_ERROR :
+        return "fread problem";
+
+    case NO_PEER_KEY :
+        return "need peer's key";
+
+    case NO_PRIVATE_KEY :
+        return "need the private key";
+
+    case NO_DH_PARAMS :
+        return "server missing DH params";
+
+    case RSA_PRIVATE_ERROR :
+        return "error during rsa priv op";
+
+    case MATCH_SUITE_ERROR :
+        return "can't match cipher suite";
+
+    case BUILD_MSG_ERROR :
+        return "build message failure";
+
+    case BAD_HELLO :
+        return "client hello malformed";
+
+    case DOMAIN_NAME_MISMATCH :
+        return "peer subject name mismatch";
+
+    case WANT_READ :
+    case SSL_ERROR_WANT_READ :
+        return "non-blocking socket wants data to be read";
+
+    case NOT_READY_ERROR :
+        return "handshake layer not ready yet, complete first";
+
+    case PMS_VERSION_ERROR :
+        return "premaster secret version mismatch error";
+
+    case VERSION_ERROR :
+        return "record layer version error";
+
+    case WANT_WRITE :
+    case SSL_ERROR_WANT_WRITE :
+        return "non-blocking socket write buffer full";
+
+    case BUFFER_ERROR :
+        return "malformed buffer input error";
+
+    case VERIFY_CERT_ERROR :
+        return "verify problem on certificate";
+
+    case VERIFY_SIGN_ERROR :
+        return "verify problem based on signature";
+
+    case CLIENT_ID_ERROR :
+        return "psk client identity error";
+
+    case SERVER_HINT_ERROR:
+        return "psk server hint error";
+
+    case PSK_KEY_ERROR:
+        return "psk key callback error";
+
+    case NTRU_KEY_ERROR:
+        return "NTRU key error";
+
+    case NTRU_DRBG_ERROR:
+        return "NTRU drbg error";
+
+    case NTRU_ENCRYPT_ERROR:
+        return "NTRU encrypt error";
+
+    case NTRU_DECRYPT_ERROR:
+        return "NTRU decrypt error";
+
+    case ZLIB_INIT_ERROR:
+        return "zlib init error";
+
+    case ZLIB_COMPRESS_ERROR:
+        return "zlib compress error";
+
+    case ZLIB_DECOMPRESS_ERROR:
+        return "zlib decompress error";
+
+    case GETTIME_ERROR:
+        return "gettimeofday() error";
+
+    case GETITIMER_ERROR:
+        return "getitimer() error";
+
+    case SIGACT_ERROR:
+        return "sigaction() error";
+
+    case SETITIMER_ERROR:
+        return "setitimer() error";
+
+    case LENGTH_ERROR:
+        return "record layer length error";
+
+    case PEER_KEY_ERROR:
+        return "cant decode peer key";
+
+    case ZERO_RETURN:
+    case SSL_ERROR_ZERO_RETURN:
+        return "peer sent close notify alert";
+
+    case ECC_CURVETYPE_ERROR:
+        return "Bad ECC Curve Type or unsupported";
+
+    case ECC_CURVE_ERROR:
+        return "Bad ECC Curve or unsupported";
+
+    case ECC_PEERKEY_ERROR:
+        return "Bad ECC Peer Key";
+
+    case ECC_MAKEKEY_ERROR:
+        return "ECC Make Key failure";
+
+    case ECC_EXPORT_ERROR:
+        return "ECC Export Key failure";
+
+    case ECC_SHARED_ERROR:
+        return "ECC DHE shared failure";
+
+    case NOT_CA_ERROR:
+        return "Not a CA by basic constraint error";
+
+    case BAD_PATH_ERROR:
+        return "Bad path for opendir error";
+
+    case BAD_CERT_MANAGER_ERROR:
+        return "Bad Cert Manager error";
+
+    case OCSP_CERT_REVOKED:
+        return "OCSP Cert revoked";
+
+    case CRL_CERT_REVOKED:
+        return "CRL Cert revoked";
+
+    case CRL_MISSING:
+        return "CRL missing, not loaded";
+
+    case MONITOR_RUNNING_E:
+        return "CRL monitor already running";
+
+    case THREAD_CREATE_E:
+        return "Thread creation problem";
+
+    case OCSP_NEED_URL:
+        return "OCSP need URL";
+
+    case OCSP_CERT_UNKNOWN:
+        return "OCSP Cert unknown";
+
+    case OCSP_LOOKUP_FAIL:
+        return "OCSP Responder lookup fail";
+
+    case MAX_CHAIN_ERROR:
+        return "Maximum Chain Depth Exceeded";
+
+    case COOKIE_ERROR:
+        return "DTLS Cookie Error";
+
+    case SEQUENCE_ERROR:
+        return "DTLS Sequence Error";
+
+    case SUITES_ERROR:
+        return "Suites Pointer Error";
+
+    case SSL_NO_PEM_HEADER:
+        return "No PEM Header Error";
+
+    case OUT_OF_ORDER_E:
+        return "Out of order message, fatal";
+
+    case BAD_KEA_TYPE_E:
+        return "Bad KEA type found";
+
+    case SANITY_CIPHER_E:
+        return "Sanity check on ciphertext failed";
+
+    case RECV_OVERFLOW_E:
+        return "Receive callback returned more than requested";
+
+    case GEN_COOKIE_E:
+        return "Generate Cookie Error";
+
+    case NO_PEER_VERIFY:
+        return "Need peer certificate verify Error";
+
+    case FWRITE_ERROR:
+        return "fwrite Error";
+
+    case CACHE_MATCH_ERROR:
+        return "Cache restore header match Error";
+
+    case UNKNOWN_SNI_HOST_NAME_E:
+        return "Unrecognized host name Error";
+
+    case KEYUSE_SIGNATURE_E:
+        return "Key Use digitalSignature not set Error";
+
+    case KEYUSE_ENCIPHER_E:
+        return "Key Use keyEncipherment not set Error";
+
+    case EXTKEYUSE_AUTH_E:
+        return "Ext Key Use server/client auth not set Error";
+
+    case SEND_OOB_READ_E:
+        return "Send Callback Out of Bounds Read Error";
+
+    case SECURE_RENEGOTIATION_E:
+        return "Invalid Renegotiation Error";
+
+    case SESSION_TICKET_LEN_E:
+        return "Session Ticket Too Long Error";
+
+    case SESSION_TICKET_EXPECT_E:
+        return "Session Ticket Error";
+
+    case SCR_DIFFERENT_CERT_E:
+        return "Peer sent different cert during SCR";
+
+    case SESSION_SECRET_CB_E:
+        return "Session Secret Callback Error";
+
+    case NO_CHANGE_CIPHER_E:
+        return "Finished received from peer before Change Cipher Error";
+
+    case SANITY_MSG_E:
+        return "Sanity Check on message order Error";
+
+    case DUPLICATE_MSG_E:
+        return "Duplicate HandShake message Error";
+
+    case SNI_UNSUPPORTED:
+        return "Protocol version does not support SNI Error";
+
+    case SOCKET_PEER_CLOSED_E:
+        return "Peer closed underlying transport Error";
+
+    case BAD_TICKET_KEY_CB_SZ:
+        return "Bad user session ticket key callback Size Error";
+
+    case BAD_TICKET_MSG_SZ:
+        return "Bad session ticket message Size Error";
+
+    case BAD_TICKET_ENCRYPT:
+        return "Bad user ticket callback encrypt Error";
+
+    case DH_KEY_SIZE_E:
+        return "DH key too small Error";
+
+    case SNI_ABSENT_ERROR:
+        return "No Server Name Indication extension Error";
+
+    case RSA_SIGN_FAULT:
+        return "RSA Signature Fault Error";
+
+    case UNKNOWN_ALPN_PROTOCOL_NAME_E:
+        return "Unrecognized protocol name Error";
+
+    case HANDSHAKE_SIZE_ERROR:
+        return "Handshake message too large Error";
+
+    default :
+        return "unknown error number";
+    }
+
+#endif /* NO_ERROR_STRINGS */
+}
+
+void SetErrorString(int error, char* str)
+{
+    XSTRNCPY(str, wolfSSL_ERR_reason_error_string(error), WOLFSSL_MAX_ERROR_SZ);
+}
+
+
+/* be sure to add to cipher_name_idx too !!!! */
+static const char* const cipher_names[] =
+{
+#ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
+    "RC4-SHA",
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
+    "RC4-MD5",
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
+    "DES-CBC3-SHA",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
+    "AES128-SHA",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
+    "AES256-SHA",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_SHA
+    "NULL-SHA",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
+    "NULL-SHA256",
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+    "DHE-RSA-AES128-SHA",
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+    "DHE-RSA-AES256-SHA",
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+    "DHE-PSK-AES256-GCM-SHA384",
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+    "DHE-PSK-AES128-GCM-SHA256",
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
+    "PSK-AES256-GCM-SHA384",
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
+    "PSK-AES128-GCM-SHA256",
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+    "DHE-PSK-AES256-CBC-SHA384",
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+    "DHE-PSK-AES128-CBC-SHA256",
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
+    "PSK-AES256-CBC-SHA384",
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
+    "PSK-AES128-CBC-SHA256",
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
+    "PSK-AES128-CBC-SHA",
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
+    "PSK-AES256-CBC-SHA",
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
+    "DHE-PSK-AES128-CCM",
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
+    "DHE-PSK-AES256-CCM",
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
+    "PSK-AES128-CCM",
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
+    "PSK-AES256-CCM",
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
+    "PSK-AES128-CCM-8",
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
+    "PSK-AES256-CCM-8",
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
+    "DHE-PSK-NULL-SHA384",
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
+    "DHE-PSK-NULL-SHA256",
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
+    "PSK-NULL-SHA384",
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
+    "PSK-NULL-SHA256",
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA
+    "PSK-NULL-SHA",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
+    "HC128-MD5",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
+    "HC128-SHA",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
+    "HC128-B2B256",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
+    "AES128-B2B256",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
+    "AES256-B2B256",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
+    "RABBIT-SHA",
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
+    "NTRU-RC4-SHA",
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
+    "NTRU-DES-CBC3-SHA",
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
+    "NTRU-AES128-SHA",
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
+    "NTRU-AES256-SHA",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
+    "AES128-CCM-8",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
+    "AES256-CCM-8",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+    "ECDHE-ECDSA-AES128-CCM-8",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
+    "ECDHE-ECDSA-AES256-CCM-8",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+    "ECDHE-RSA-AES128-SHA",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+    "ECDHE-RSA-AES256-SHA",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+    "ECDHE-ECDSA-AES128-SHA",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+    "ECDHE-ECDSA-AES256-SHA",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+    "ECDHE-RSA-RC4-SHA",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+    "ECDHE-RSA-DES-CBC3-SHA",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+    "ECDHE-ECDSA-RC4-SHA",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+    "ECDHE-ECDSA-DES-CBC3-SHA",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
+    "AES128-SHA256",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
+    "AES256-SHA256",
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+    "DHE-RSA-AES128-SHA256",
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+    "DHE-RSA-AES256-SHA256",
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+    "ECDH-RSA-AES128-SHA",
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+    "ECDH-RSA-AES256-SHA",
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+    "ECDH-ECDSA-AES128-SHA",
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+    "ECDH-ECDSA-AES256-SHA",
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
+    "ECDH-RSA-RC4-SHA",
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+    "ECDH-RSA-DES-CBC3-SHA",
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+    "ECDH-ECDSA-RC4-SHA",
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+    "ECDH-ECDSA-DES-CBC3-SHA",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
+    "AES128-GCM-SHA256",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
+    "AES256-GCM-SHA384",
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+    "DHE-RSA-AES128-GCM-SHA256",
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+    "DHE-RSA-AES256-GCM-SHA384",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+    "ECDHE-RSA-AES128-GCM-SHA256",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+    "ECDHE-RSA-AES256-GCM-SHA384",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+    "ECDHE-ECDSA-AES128-GCM-SHA256",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+    "ECDHE-ECDSA-AES256-GCM-SHA384",
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+    "ECDH-RSA-AES128-GCM-SHA256",
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+    "ECDH-RSA-AES256-GCM-SHA384",
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+    "ECDH-ECDSA-AES128-GCM-SHA256",
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+    "ECDH-ECDSA-AES256-GCM-SHA384",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+    "CAMELLIA128-SHA",
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+    "DHE-RSA-CAMELLIA128-SHA",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+    "CAMELLIA256-SHA",
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+    "DHE-RSA-CAMELLIA256-SHA",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+    "CAMELLIA128-SHA256",
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+    "DHE-RSA-CAMELLIA128-SHA256",
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+    "CAMELLIA256-SHA256",
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+    "DHE-RSA-CAMELLIA256-SHA256",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+    "ECDHE-RSA-AES128-SHA256",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+    "ECDHE-ECDSA-AES128-SHA256",
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+    "ECDH-RSA-AES128-SHA256",
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+    "ECDH-ECDSA-AES128-SHA256",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+    "ECDHE-RSA-AES256-SHA384",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+    "ECDHE-ECDSA-AES256-SHA384",
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+    "ECDH-RSA-AES256-SHA384",
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+    "ECDH-ECDSA-AES256-SHA384",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    "ECDHE-RSA-CHACHA20-POLY1305",
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+    "ECDHE-ECDSA-CHACHA20-POLY1305",
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    "DHE-RSA-CHACHA20-POLY1305",
+#endif
+
+#ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
+    "ADH-AES128-SHA",
+#endif
+
+#ifdef BUILD_TLS_QSH
+    "QSH",
+#endif
+
+#ifdef HAVE_RENEGOTIATION_INDICATION
+    "RENEGOTIATION-INFO",
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_IDEA_CBC_SHA
+    "IDEA-CBC-SHA",
+#endif
+};
+
+
+/* cipher suite number that matches above name table */
+static int cipher_name_idx[] =
+{
+
+#ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
+    SSL_RSA_WITH_RC4_128_SHA,
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
+    SSL_RSA_WITH_RC4_128_MD5,
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
+    SSL_RSA_WITH_3DES_EDE_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
+    TLS_RSA_WITH_AES_128_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
+    TLS_RSA_WITH_AES_256_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_SHA
+    TLS_RSA_WITH_NULL_SHA,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
+    TLS_RSA_WITH_NULL_SHA256,
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+    TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+    TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
+    TLS_PSK_WITH_AES_256_GCM_SHA384,
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
+    TLS_PSK_WITH_AES_128_GCM_SHA256,
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+    TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+    TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
+    TLS_PSK_WITH_AES_256_CBC_SHA384,
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
+    TLS_PSK_WITH_AES_128_CBC_SHA256,
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
+    TLS_PSK_WITH_AES_128_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
+    TLS_PSK_WITH_AES_256_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
+    TLS_DHE_PSK_WITH_AES_128_CCM,
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
+    TLS_DHE_PSK_WITH_AES_256_CCM,
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
+    TLS_PSK_WITH_AES_128_CCM,
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
+    TLS_PSK_WITH_AES_256_CCM,
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
+    TLS_PSK_WITH_AES_128_CCM_8,
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
+    TLS_PSK_WITH_AES_256_CCM_8,
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
+    TLS_DHE_PSK_WITH_NULL_SHA384,
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
+    TLS_DHE_PSK_WITH_NULL_SHA256,
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
+    TLS_PSK_WITH_NULL_SHA384,
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
+    TLS_PSK_WITH_NULL_SHA256,
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA
+    TLS_PSK_WITH_NULL_SHA,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
+    TLS_RSA_WITH_HC_128_MD5,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
+    TLS_RSA_WITH_HC_128_SHA,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
+    TLS_RSA_WITH_HC_128_B2B256,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
+    TLS_RSA_WITH_AES_128_CBC_B2B256,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
+    TLS_RSA_WITH_AES_256_CBC_B2B256,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
+    TLS_RSA_WITH_RABBIT_SHA,
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
+    TLS_NTRU_RSA_WITH_RC4_128_SHA,
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
+    TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
+    TLS_NTRU_RSA_WITH_AES_128_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
+    TLS_NTRU_RSA_WITH_AES_256_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
+    TLS_RSA_WITH_AES_128_CCM_8,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
+    TLS_RSA_WITH_AES_256_CCM_8,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+    TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
+    TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+    TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
+    TLS_RSA_WITH_AES_128_CBC_SHA256,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
+    TLS_RSA_WITH_AES_256_CBC_SHA256,
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
+    TLS_ECDH_RSA_WITH_RC4_128_SHA,
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
+    TLS_RSA_WITH_AES_128_GCM_SHA256,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
+    TLS_RSA_WITH_AES_256_GCM_SHA384,
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+    TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+    TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+    TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+    TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+    TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+    TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+    TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+    TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+    TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+    TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+    TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+#endif
+
+#ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
+    TLS_DH_anon_WITH_AES_128_CBC_SHA,
+#endif
+
+#ifdef BUILD_TLS_QSH
+    TLS_QSH,
+#endif
+
+#ifdef HAVE_RENEGOTIATION_INDICATION
+    TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_IDEA_CBC_SHA
+    SSL_RSA_WITH_IDEA_CBC_SHA,
+#endif
+};
+
+
+/* returns the cipher_names array */
+const char* const* GetCipherNames(void)
+{
+    return cipher_names;
+}
+
+
+/* returns the size of the cipher_names array */
+int GetCipherNamesSize(void)
+{
+    return (int)(sizeof(cipher_names) / sizeof(char*));
+}
+
+
+/**
+Set the enabled cipher suites.
+
+@param [out] suites Suites structure.
+@param [in]  list   List of cipher suites, only supports full name from
+                    cipher_name[] delimited by ':'.
+
+@return true on success, else false.
+*/
+int SetCipherList(Suites* suites, const char* list)
+{
+    int       ret          = 0;
+    int       idx          = 0;
+    int       haveRSAsig   = 0;
+    int       haveECDSAsig = 0;
+    int       haveAnon     = 0;
+    const int suiteSz      = GetCipherNamesSize();
+    char*     next         = (char*)list;
+
+    if (suites == NULL || list == NULL) {
+        WOLFSSL_MSG("SetCipherList parameter error");
+        return 0;
+    }
+
+    if (next[0] == 0 || XSTRNCMP(next, "ALL", 3) == 0)
+        return 1; /* wolfSSL defualt */
+
+    do {
+        char*  current = next;
+        char   name[MAX_SUITE_NAME + 1];
+        int    i;
+        word32 length;
+
+        next   = XSTRSTR(next, ":");
+        length = min(sizeof(name), !next ? (word32)XSTRLEN(current) /* last */
+                                         : (word32)(next - current));
+
+        XSTRNCPY(name, current, length);
+        name[(length == sizeof(name)) ? length - 1 : length] = 0;
+
+        for (i = 0; i < suiteSz; i++) {
+            if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) {
+                suites->suites[idx++] = (XSTRSTR(name, "CHACHA")) ? CHACHA_BYTE
+                                      : (XSTRSTR(name, "QSH"))    ? QSH_BYTE
+                                      : (XSTRSTR(name, "EC"))     ? ECC_BYTE
+                                      : (XSTRSTR(name, "CCM"))    ? ECC_BYTE
+                                      : 0x00; /* normal */
+
+                suites->suites[idx++] = (byte)cipher_name_idx[i];
+
+                /* The suites are either ECDSA, RSA, PSK, or Anon. The RSA
+                 * suites don't necessarily have RSA in the name. */
+                if ((haveECDSAsig == 0) && XSTRSTR(name, "ECDSA"))
+                    haveECDSAsig = 1;
+                else if (XSTRSTR(name, "ADH"))
+                    haveAnon = 1;
+                else if ((haveRSAsig == 0) && (XSTRSTR(name, "PSK") == NULL))
+                    haveRSAsig = 1;
+
+                ret = 1; /* found at least one */
+                break;
+            }
+        }
+    }
+    while (next++); /* ++ needed to skip ':' */
+
+    if (ret) {
+        suites->setSuites = 1;
+        suites->suiteSz   = (word16)idx;
+        InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, haveAnon);
+    }
+
+    return ret;
+}
+
+
+static void PickHashSigAlgo(WOLFSSL* ssl,
+                             const byte* hashSigAlgo, word32 hashSigAlgoSz)
+{
+    word32 i;
+
+    ssl->suites->sigAlgo = ssl->specs.sig_algo;
+    ssl->suites->hashAlgo = sha_mac;
+
+    /* i+1 since peek a byte ahead for type */
+    for (i = 0; (i+1) < hashSigAlgoSz; i += 2) {
+        if (hashSigAlgo[i+1] == ssl->specs.sig_algo) {
+            if (hashSigAlgo[i] == sha_mac) {
+                break;
+            }
+            #ifndef NO_SHA256
+            else if (hashSigAlgo[i] == sha256_mac) {
+                ssl->suites->hashAlgo = sha256_mac;
+                break;
+            }
+            #endif
+            #ifdef WOLFSSL_SHA384
+            else if (hashSigAlgo[i] == sha384_mac) {
+                ssl->suites->hashAlgo = sha384_mac;
+                break;
+            }
+            #endif
+            #ifdef WOLFSSL_SHA512
+            else if (hashSigAlgo[i] == sha512_mac) {
+                ssl->suites->hashAlgo = sha512_mac;
+                break;
+            }
+            #endif
+        }
+    }
+}
+
+
+#ifdef WOLFSSL_CALLBACKS
+
+    /* Initialisze HandShakeInfo */
+    void InitHandShakeInfo(HandShakeInfo* info)
+    {
+        int i;
+
+        info->cipherName[0] = 0;
+        for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
+            info->packetNames[i][0] = 0;
+        info->numberPackets = 0;
+        info->negotiationError = 0;
+    }
+
+    /* Set Final HandShakeInfo parameters */
+    void FinishHandShakeInfo(HandShakeInfo* info, const WOLFSSL* ssl)
+    {
+        int i;
+        int sz = sizeof(cipher_name_idx)/sizeof(int);
+
+        for (i = 0; i < sz; i++)
+            if (ssl->options.cipherSuite == (byte)cipher_name_idx[i]) {
+                if (ssl->options.cipherSuite0 == ECC_BYTE)
+                    continue;   /* ECC suites at end */
+                XSTRNCPY(info->cipherName, cipher_names[i], MAX_CIPHERNAME_SZ);
+                break;
+            }
+
+        /* error max and min are negative numbers */
+        if (ssl->error <= MIN_PARAM_ERR && ssl->error >= MAX_PARAM_ERR)
+            info->negotiationError = ssl->error;
+    }
+
+
+    /* Add name to info packet names, increase packet name count */
+    void AddPacketName(const char* name, HandShakeInfo* info)
+    {
+        if (info->numberPackets < MAX_PACKETS_HANDSHAKE) {
+            XSTRNCPY(info->packetNames[info->numberPackets++], name,
+                    MAX_PACKETNAME_SZ);
+        }
+    }
+
+
+    /* Initialisze TimeoutInfo */
+    void InitTimeoutInfo(TimeoutInfo* info)
+    {
+        int i;
+
+        info->timeoutName[0] = 0;
+        info->flags          = 0;
+
+        for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++) {
+            info->packets[i].packetName[0]     = 0;
+            info->packets[i].timestamp.tv_sec  = 0;
+            info->packets[i].timestamp.tv_usec = 0;
+            info->packets[i].bufferValue       = 0;
+            info->packets[i].valueSz           = 0;
+        }
+        info->numberPackets        = 0;
+        info->timeoutValue.tv_sec  = 0;
+        info->timeoutValue.tv_usec = 0;
+    }
+
+
+    /* Free TimeoutInfo */
+    void FreeTimeoutInfo(TimeoutInfo* info, void* heap)
+    {
+        int i;
+        (void)heap;
+        for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
+            if (info->packets[i].bufferValue) {
+                XFREE(info->packets[i].bufferValue, heap, DYNAMIC_TYPE_INFO);
+                info->packets[i].bufferValue = 0;
+            }
+
+    }
+
+
+    /* Add PacketInfo to TimeoutInfo */
+    void AddPacketInfo(const char* name, TimeoutInfo* info, const byte* data,
+                       int sz, void* heap)
+    {
+        if (info->numberPackets < (MAX_PACKETS_HANDSHAKE - 1)) {
+            Timeval currTime;
+
+            /* may add name after */
+            if (name)
+                XSTRNCPY(info->packets[info->numberPackets].packetName, name,
+                        MAX_PACKETNAME_SZ);
+
+            /* add data, put in buffer if bigger than static buffer */
+            info->packets[info->numberPackets].valueSz = sz;
+            if (sz < MAX_VALUE_SZ)
+                XMEMCPY(info->packets[info->numberPackets].value, data, sz);
+            else {
+                info->packets[info->numberPackets].bufferValue =
+                           XMALLOC(sz, heap, DYNAMIC_TYPE_INFO);
+                if (!info->packets[info->numberPackets].bufferValue)
+                    /* let next alloc catch, just don't fill, not fatal here  */
+                    info->packets[info->numberPackets].valueSz = 0;
+                else
+                    XMEMCPY(info->packets[info->numberPackets].bufferValue,
+                           data, sz);
+            }
+            gettimeofday(&currTime, 0);
+            info->packets[info->numberPackets].timestamp.tv_sec  =
+                                                             currTime.tv_sec;
+            info->packets[info->numberPackets].timestamp.tv_usec =
+                                                             currTime.tv_usec;
+            info->numberPackets++;
+        }
+    }
+
+
+    /* Add packet name to previsouly added packet info */
+    void AddLateName(const char* name, TimeoutInfo* info)
+    {
+        /* make sure we have a valid previous one */
+        if (info->numberPackets > 0 && info->numberPackets <
+                                                        MAX_PACKETS_HANDSHAKE) {
+            XSTRNCPY(info->packets[info->numberPackets - 1].packetName, name,
+                    MAX_PACKETNAME_SZ);
+        }
+    }
+
+    /* Add record header to previsouly added packet info */
+    void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info)
+    {
+        /* make sure we have a valid previous one */
+        if (info->numberPackets > 0 && info->numberPackets <
+                                                        MAX_PACKETS_HANDSHAKE) {
+            if (info->packets[info->numberPackets - 1].bufferValue)
+                XMEMCPY(info->packets[info->numberPackets - 1].bufferValue, rl,
+                       RECORD_HEADER_SZ);
+            else
+                XMEMCPY(info->packets[info->numberPackets - 1].value, rl,
+                       RECORD_HEADER_SZ);
+        }
+    }
+
+#endif /* WOLFSSL_CALLBACKS */
+
+
+
+/* client only parts */
+#ifndef NO_WOLFSSL_CLIENT
+
+    int SendClientHello(WOLFSSL* ssl)
+    {
+        byte              *output;
+        word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+        int                sendSz;
+        int                idSz = ssl->options.resuming
+                                ? ssl->session.sessionIDSz
+                                : 0;
+        int                ret;
+
+        if (ssl->suites == NULL) {
+            WOLFSSL_MSG("Bad suites pointer in SendClientHello");
+            return SUITES_ERROR;
+        }
+
+#ifdef HAVE_SESSION_TICKET
+        if (ssl->options.resuming && ssl->session.ticketLen > 0) {
+            SessionTicket* ticket;
+
+            ticket = TLSX_SessionTicket_Create(0,
+                                   ssl->session.ticket, ssl->session.ticketLen);
+            if (ticket == NULL) return MEMORY_E;
+
+            ret = TLSX_UseSessionTicket(&ssl->extensions, ticket);
+            if (ret != SSL_SUCCESS) return ret;
+
+            idSz = 0;
+        }
+#endif
+        length = VERSION_SZ + RAN_LEN
+               + idSz + ENUM_LEN
+               + ssl->suites->suiteSz + SUITE_LEN
+               + COMP_LEN + ENUM_LEN;
+
+#ifdef HAVE_TLS_EXTENSIONS
+        /* auto populate extensions supported unless user defined */
+        if ((ret = TLSX_PopulateExtensions(ssl, 0)) != 0)
+            return ret;
+    #ifdef HAVE_QSH
+        if (QSH_Init(ssl) != 0)
+            return MEMORY_E;
+    #endif
+        length += TLSX_GetRequestSize(ssl);
+#else
+        if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) {
+            length += ssl->suites->hashSigAlgoSz + HELLO_EXT_SZ;
+        }
+#endif
+        sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+
+#ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            length += ENUM_LEN;   /* cookie */
+            if (ssl->arrays->cookieSz != 0) length += ssl->arrays->cookieSz;
+            sendSz  = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ;
+            idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
+        }
+#endif
+
+        if (ssl->keys.encryptionOn)
+            sendSz += MAX_MSG_EXTRA;
+
+        /* check for available size */
+        if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+            return ret;
+
+        /* get ouput buffer */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        AddHeaders(output, length, client_hello, ssl);
+#ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            DtlsRecordLayerHeader* rh = (DtlsRecordLayerHeader*)output;
+            rh->pvMajor = DTLS_MAJOR;
+            rh->pvMinor = DTLS_MINOR;
+        }
+#endif /* WOLFSSL_DTLS */
+
+            /* client hello, first version */
+        output[idx++] = ssl->version.major;
+        output[idx++] = ssl->version.minor;
+        ssl->chVersion = ssl->version;  /* store in case changed */
+
+            /* then random */
+        if (ssl->options.connectState == CONNECT_BEGIN) {
+            ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN);
+            if (ret != 0)
+                return ret;
+
+                /* store random */
+            XMEMCPY(ssl->arrays->clientRandom, output + idx, RAN_LEN);
+        } else {
+#ifdef WOLFSSL_DTLS
+                /* send same random on hello again */
+            XMEMCPY(output + idx, ssl->arrays->clientRandom, RAN_LEN);
+#endif
+        }
+        idx += RAN_LEN;
+
+            /* then session id */
+        output[idx++] = (byte)idSz;
+        if (idSz) {
+            XMEMCPY(output + idx, ssl->session.sessionID,
+                                                      ssl->session.sessionIDSz);
+            idx += ssl->session.sessionIDSz;
+        }
+
+            /* then DTLS cookie */
+#ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            byte cookieSz = ssl->arrays->cookieSz;
+
+            output[idx++] = cookieSz;
+            if (cookieSz) {
+                XMEMCPY(&output[idx], ssl->arrays->cookie, cookieSz);
+                idx += cookieSz;
+            }
+        }
+#endif
+            /* then cipher suites */
+        c16toa(ssl->suites->suiteSz, output + idx);
+        idx += 2;
+        XMEMCPY(output + idx, &ssl->suites->suites, ssl->suites->suiteSz);
+        idx += ssl->suites->suiteSz;
+
+            /* last, compression */
+        output[idx++] = COMP_LEN;
+        if (ssl->options.usingCompression)
+            output[idx++] = ZLIB_COMPRESSION;
+        else
+            output[idx++] = NO_COMPRESSION;
+
+#ifdef HAVE_TLS_EXTENSIONS
+        idx += TLSX_WriteRequest(ssl, output + idx);
+
+        (void)idx; /* suppress analyzer warning, keep idx current */
+#else
+        if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
+        {
+            int i;
+            /* add in the extensions length */
+            c16toa(HELLO_EXT_LEN + ssl->suites->hashSigAlgoSz, output + idx);
+            idx += 2;
+
+            c16toa(HELLO_EXT_SIG_ALGO, output + idx);
+            idx += 2;
+            c16toa(HELLO_EXT_SIGALGO_SZ+ssl->suites->hashSigAlgoSz, output+idx);
+            idx += 2;
+            c16toa(ssl->suites->hashSigAlgoSz, output + idx);
+            idx += 2;
+            for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, idx++) {
+                output[idx] = ssl->suites->hashSigAlgo[i];
+            }
+        }
+#endif
+
+        if (ssl->keys.encryptionOn) {
+            byte* input;
+            int   inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */
+
+            input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+            if (input == NULL)
+                return MEMORY_E;
+
+            XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
+            sendSz = BuildMessage(ssl, output, sendSz, input,inputSz,handshake);
+            XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+
+            if (sendSz < 0)
+                return sendSz;
+        } else {
+            ret = HashOutput(ssl, output, sendSz, 0);
+            if (ret != 0)
+                return ret;
+        }
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
+                    return ret;
+            }
+        #endif
+
+        ssl->options.clientState = CLIENT_HELLO_COMPLETE;
+
+#ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
+        if (ssl->toInfoOn)
+            AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz,
+                          ssl->heap);
+#endif
+
+        ssl->buffers.outputBuffer.length += sendSz;
+
+        return SendBuffered(ssl);
+    }
+
+
+    static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input,
+                                    word32* inOutIdx, word32 size)
+    {
+        ProtocolVersion pv;
+        byte            cookieSz;
+        word32          begin = *inOutIdx;
+
+#ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName("HelloVerifyRequest",
+                                         &ssl->handShakeInfo);
+        if (ssl->toInfoOn) AddLateName("HelloVerifyRequest", &ssl->timeoutInfo);
+#endif
+
+#ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            DtlsPoolReset(ssl);
+        }
+#endif
+
+        if ((*inOutIdx - begin) + OPAQUE16_LEN + OPAQUE8_LEN > size)
+            return BUFFER_ERROR;
+
+        XMEMCPY(&pv, input + *inOutIdx, OPAQUE16_LEN);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if (pv.major != DTLS_MAJOR ||
+                         (pv.minor != DTLS_MINOR && pv.minor != DTLSv1_2_MINOR))
+            return VERSION_ERROR;
+
+        cookieSz = input[(*inOutIdx)++];
+
+        if (cookieSz) {
+            if ((*inOutIdx - begin) + cookieSz > size)
+                return BUFFER_ERROR;
+
+#ifdef WOLFSSL_DTLS
+            if (cookieSz <= MAX_COOKIE_LEN) {
+                XMEMCPY(ssl->arrays->cookie, input + *inOutIdx, cookieSz);
+                ssl->arrays->cookieSz = cookieSz;
+            }
+#endif
+            *inOutIdx += cookieSz;
+        }
+
+        ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
+        return 0;
+    }
+
+
+    static INLINE int DSH_CheckSessionId(WOLFSSL* ssl)
+    {
+        int ret = 0;
+
+#ifdef HAVE_SECRET_CALLBACK
+        /* If a session secret callback exists, we are using that
+         * key instead of the saved session key. */
+        ret = ret || (ssl->sessionSecretCb != NULL);
+#endif
+
+#ifdef HAVE_SESSION_TICKET
+        /* server may send blank ticket which may not be expected to indicate
+         * exisiting one ok but will also be sending a new one */
+        ret = ret || (ssl->session.ticketLen > 0);
+#endif
+
+        ret = ret ||
+              (ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID,
+                                          ssl->session.sessionID, ID_LEN) == 0);
+
+        return ret;
+    }
+
+    static int DoServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                             word32 helloSz)
+    {
+        byte            cs0;   /* cipher suite bytes 0, 1 */
+        byte            cs1;
+        ProtocolVersion pv;
+        byte            compression;
+        word32          i = *inOutIdx;
+        word32          begin = i;
+
+#ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo);
+        if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
+#endif
+
+        /* protocol version, random and session id length check */
+        if (OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
+            return BUFFER_ERROR;
+
+        /* protocol version */
+        XMEMCPY(&pv, input + i, OPAQUE16_LEN);
+        i += OPAQUE16_LEN;
+
+        if (pv.minor > ssl->version.minor) {
+            WOLFSSL_MSG("Server using higher version, fatal error");
+            return VERSION_ERROR;
+        }
+        else if (pv.minor < ssl->version.minor) {
+            WOLFSSL_MSG("server using lower version");
+
+            if (!ssl->options.downgrade) {
+                WOLFSSL_MSG("    no downgrade allowed, fatal error");
+                return VERSION_ERROR;
+            }
+            if (pv.minor < ssl->options.minDowngrade) {
+                WOLFSSL_MSG("    version below minimum allowed, fatal error");
+                return VERSION_ERROR;
+            }
+
+            #ifdef HAVE_SECURE_RENEGOTIATION
+                if (ssl->secure_renegotiation &&
+                                         ssl->secure_renegotiation->enabled &&
+                                         ssl->options.handShakeDone) {
+                    WOLFSSL_MSG("Server changed version during scr");
+                    return VERSION_ERROR;
+                }
+            #endif
+
+            if (pv.minor == SSLv3_MINOR) {
+                /* turn off tls */
+                WOLFSSL_MSG("    downgrading to SSLv3");
+                ssl->options.tls    = 0;
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor  = SSLv3_MINOR;
+            }
+            else if (pv.minor == TLSv1_MINOR) {
+                /* turn off tls 1.1+ */
+                WOLFSSL_MSG("    downgrading to TLSv1");
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor  = TLSv1_MINOR;
+            }
+            else if (pv.minor == TLSv1_1_MINOR) {
+                WOLFSSL_MSG("    downgrading to TLSv1.1");
+                ssl->version.minor  = TLSv1_1_MINOR;
+            }
+        }
+
+        /* random */
+        XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
+        i += RAN_LEN;
+
+        /* session id */
+        ssl->arrays->sessionIDSz = input[i++];
+
+        if (ssl->arrays->sessionIDSz > ID_LEN) {
+            WOLFSSL_MSG("Invalid session ID size");
+            ssl->arrays->sessionIDSz = 0;
+            return BUFFER_ERROR;
+        }
+        else if (ssl->arrays->sessionIDSz) {
+            if ((i - begin) + ssl->arrays->sessionIDSz > helloSz)
+                return BUFFER_ERROR;
+
+            XMEMCPY(ssl->arrays->sessionID, input + i,
+                                                      ssl->arrays->sessionIDSz);
+            i += ssl->arrays->sessionIDSz;
+            ssl->options.haveSessionId = 1;
+        }
+
+
+        /* suite and compression */
+        if ((i - begin) + OPAQUE16_LEN + OPAQUE8_LEN > helloSz)
+            return BUFFER_ERROR;
+
+        cs0 = input[i++];
+        cs1 = input[i++];
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+        if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled &&
+                                         ssl->options.handShakeDone) {
+            if (ssl->options.cipherSuite0 != cs0 ||
+                ssl->options.cipherSuite  != cs1) {
+                WOLFSSL_MSG("Server changed cipher suite during scr");
+                return MATCH_SUITE_ERROR;
+            }
+        }
+#endif
+
+        ssl->options.cipherSuite0 = cs0;
+        ssl->options.cipherSuite  = cs1;
+        compression = input[i++];
+
+        if (compression != ZLIB_COMPRESSION && ssl->options.usingCompression) {
+            WOLFSSL_MSG("Server refused compression, turning off");
+            ssl->options.usingCompression = 0;  /* turn off if server refused */
+        }
+
+        *inOutIdx = i;
+
+
+        if ( (i - begin) < helloSz) {
+#ifdef HAVE_TLS_EXTENSIONS
+            if (TLSX_SupportExtensions(ssl)) {
+                int    ret = 0;
+                word16 totalExtSz;
+
+                if ((i - begin) + OPAQUE16_LEN > helloSz)
+                    return BUFFER_ERROR;
+
+                ato16(&input[i], &totalExtSz);
+                i += OPAQUE16_LEN;
+
+                if ((i - begin) + totalExtSz > helloSz)
+                    return BUFFER_ERROR;
+
+                if ((ret = TLSX_Parse(ssl, (byte *) input + i,
+                                                          totalExtSz, 0, NULL)))
+                    return ret;
+
+                i += totalExtSz;
+                *inOutIdx = i;
+            }
+            else
+#endif
+                *inOutIdx = begin + helloSz; /* skip extensions */
+        }
+
+        ssl->options.serverState = SERVER_HELLO_COMPLETE;
+
+        if (ssl->keys.encryptionOn) {
+            *inOutIdx += ssl->keys.padSz;
+        }
+
+#ifdef HAVE_SECRET_CALLBACK
+        if (ssl->sessionSecretCb != NULL) {
+            int secretSz = SECRET_LEN, ret;
+            ret = ssl->sessionSecretCb(ssl, ssl->session.masterSecret,
+                                              &secretSz, ssl->sessionSecretCtx);
+            if (ret != 0 || secretSz != SECRET_LEN)
+                return SESSION_SECRET_CB_E;
+        }
+#endif /* HAVE_SECRET_CALLBACK */
+
+        if (ssl->options.resuming) {
+            if (DSH_CheckSessionId(ssl)) {
+                if (SetCipherSpecs(ssl) == 0) {
+                    int ret = -1;
+
+                    XMEMCPY(ssl->arrays->masterSecret,
+                            ssl->session.masterSecret, SECRET_LEN);
+                    #ifdef NO_OLD_TLS
+                        ret = DeriveTlsKeys(ssl);
+                    #else
+                        #ifndef NO_TLS
+                            if (ssl->options.tls)
+                                ret = DeriveTlsKeys(ssl);
+                        #endif
+                            if (!ssl->options.tls)
+                                ret = DeriveKeys(ssl);
+                    #endif
+                    ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
+
+                    return ret;
+                }
+                else {
+                    WOLFSSL_MSG("Unsupported cipher suite, DoServerHello");
+                    return UNSUPPORTED_SUITE;
+                }
+            }
+            else {
+                WOLFSSL_MSG("Server denied resumption attempt");
+                ssl->options.resuming = 0; /* server denied resumption try */
+            }
+        }
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                DtlsPoolReset(ssl);
+            }
+        #endif
+
+        return SetCipherSpecs(ssl);
+    }
+
+
+    /* Make sure client setup is valid for this suite, true on success */
+    int VerifyClientSuite(WOLFSSL* ssl)
+    {
+        int  havePSK = 0;
+        byte first   = ssl->options.cipherSuite0;
+        byte second  = ssl->options.cipherSuite;
+
+        WOLFSSL_ENTER("VerifyClientSuite");
+
+        #ifndef NO_PSK
+            havePSK = ssl->options.havePSK;
+        #endif
+
+        if (CipherRequires(first, second, REQUIRES_PSK)) {
+            WOLFSSL_MSG("Requires PSK");
+            if (havePSK == 0) {
+                WOLFSSL_MSG("Don't have PSK");
+                return 0;
+            }
+        }
+
+        return 1;  /* success */
+    }
+
+
+#ifndef NO_CERTS
+    /* just read in and ignore for now TODO: */
+    static int DoCertificateRequest(WOLFSSL* ssl, const byte* input, word32*
+                                    inOutIdx, word32 size)
+    {
+        word16 len;
+        word32 begin = *inOutIdx;
+
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName("CertificateRequest", &ssl->handShakeInfo);
+            if (ssl->toInfoOn)
+                AddLateName("CertificateRequest", &ssl->timeoutInfo);
+        #endif
+
+        if ((*inOutIdx - begin) + OPAQUE8_LEN > size)
+            return BUFFER_ERROR;
+
+        len = input[(*inOutIdx)++];
+
+        if ((*inOutIdx - begin) + len > size)
+            return BUFFER_ERROR;
+
+        /* types, read in here */
+        *inOutIdx += len;
+
+        /* signature and hash signature algorithm */
+        if (IsAtLeastTLSv1_2(ssl)) {
+            if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+                return BUFFER_ERROR;
+
+            ato16(input + *inOutIdx, &len);
+            *inOutIdx += OPAQUE16_LEN;
+
+            if ((*inOutIdx - begin) + len > size)
+                return BUFFER_ERROR;
+
+            PickHashSigAlgo(ssl, input + *inOutIdx, len);
+            *inOutIdx += len;
+        }
+
+        /* authorities */
+        if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+            return BUFFER_ERROR;
+
+        ato16(input + *inOutIdx, &len);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if ((*inOutIdx - begin) + len > size)
+            return BUFFER_ERROR;
+
+        while (len) {
+            word16 dnSz;
+
+            if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+                return BUFFER_ERROR;
+
+            ato16(input + *inOutIdx, &dnSz);
+            *inOutIdx += OPAQUE16_LEN;
+
+            if ((*inOutIdx - begin) + dnSz > size)
+                return BUFFER_ERROR;
+
+            *inOutIdx += dnSz;
+            len -= OPAQUE16_LEN + dnSz;
+        }
+
+        /* don't send client cert or cert verify if user hasn't provided
+           cert and private key */
+        if (ssl->buffers.certificate.buffer && ssl->buffers.key.buffer)
+            ssl->options.sendVerify = SEND_CERT;
+        else if (IsTLS(ssl))
+            ssl->options.sendVerify = SEND_BLANK_CERT;
+
+        if (ssl->keys.encryptionOn)
+            *inOutIdx += ssl->keys.padSz;
+
+        return 0;
+    }
+#endif /* !NO_CERTS */
+
+
+#ifdef HAVE_ECC
+
+    static int CheckCurveId(int oid)
+    {
+        int ret = 0;
+
+        switch (oid) {
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
+            case WOLFSSL_ECC_SECP160R1:
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
+            case WOLFSSL_ECC_SECP192R1:
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
+            case WOLFSSL_ECC_SECP224R1:
+#endif
+#if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
+            case WOLFSSL_ECC_SECP256R1:
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
+            case WOLFSSL_ECC_SECP384R1:
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
+            case WOLFSSL_ECC_SECP521R1:
+#endif
+                break;
+
+            default:
+                ret = -1;
+        }
+
+        return ret;
+    }
+
+#endif /* HAVE_ECC */
+
+    static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
+                                   word32* inOutIdx, word32 size)
+    {
+    #ifdef HAVE_QSH
+        word16 name;
+        int    qshSz;
+    #endif
+        word16 length = 0;
+        word32 begin  = *inOutIdx;
+        int    ret    = 0;
+        #define ERROR_OUT(err, eLabel) do { ret = err; goto eLabel; } while(0)
+
+        (void)length; /* shut up compiler warnings */
+        (void)begin;
+        (void)ssl;
+        (void)input;
+        (void)size;
+        (void)ret;
+
+
+    #ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn)
+            AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
+        if (ssl->toInfoOn)
+            AddLateName("ServerKeyExchange", &ssl->timeoutInfo);
+    #endif
+
+    #ifndef NO_PSK
+        if (ssl->specs.kea == psk_kea) {
+
+            if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+                return BUFFER_ERROR;
+
+            ato16(input + *inOutIdx, &length);
+            *inOutIdx += OPAQUE16_LEN;
+
+            if ((*inOutIdx - begin) + length > size)
+                return BUFFER_ERROR;
+
+            XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx,
+                   min(length, MAX_PSK_ID_LEN));
+
+            ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0;
+            *inOutIdx += length;
+
+            /* QSH extensions */
+        #ifdef HAVE_QSH
+            if (ssl->peerQSHKeyPresent) {
+                /* extension name */
+                ato16(input + *inOutIdx, &name);
+                *inOutIdx += OPAQUE16_LEN;
+
+                if (name == WOLFSSL_QSH) {
+                    /* if qshSz is larger than 0 it is the length of buffer
+                       used */
+                    if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
+                                                                  size, 0)) < 0)
+                        return qshSz;
+                    *inOutIdx += qshSz;
+                }
+                else {
+                    /* unknown extension sent server ignored
+                       handshake */
+                    return BUFFER_ERROR;
+                }
+            }
+        #endif
+
+            return 0;
+        }
+    #endif
+    #ifndef NO_DH
+        if (ssl->specs.kea == diffie_hellman_kea)
+        {
+        /* p */
+        if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+            return BUFFER_ERROR;
+
+        ato16(input + *inOutIdx, &length);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if ((*inOutIdx - begin) + length > size)
+            return BUFFER_ERROR;
+
+        if (length < ssl->options.minDhKeySz) {
+            WOLFSSL_MSG("Server using a DH key that is too small");
+            SendAlert(ssl, alert_fatal, handshake_failure);
+            return DH_KEY_SIZE_E;
+        }
+
+        ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
+                                                         DYNAMIC_TYPE_DH);
+
+        if (ssl->buffers.serverDH_P.buffer)
+            ssl->buffers.serverDH_P.length = length;
+        else
+            return MEMORY_ERROR;
+
+        XMEMCPY(ssl->buffers.serverDH_P.buffer, input + *inOutIdx, length);
+        *inOutIdx += length;
+
+        ssl->options.dhKeySz = length;
+
+        /* g */
+        if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+            return BUFFER_ERROR;
+
+        ato16(input + *inOutIdx, &length);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if ((*inOutIdx - begin) + length > size)
+            return BUFFER_ERROR;
+
+        ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
+                                                         DYNAMIC_TYPE_DH);
+
+        if (ssl->buffers.serverDH_G.buffer)
+            ssl->buffers.serverDH_G.length = length;
+        else
+            return MEMORY_ERROR;
+
+        XMEMCPY(ssl->buffers.serverDH_G.buffer, input + *inOutIdx, length);
+        *inOutIdx += length;
+
+        /* pub */
+        if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+            return BUFFER_ERROR;
+
+        ato16(input + *inOutIdx, &length);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if ((*inOutIdx - begin) + length > size)
+            return BUFFER_ERROR;
+
+        ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
+                                                           DYNAMIC_TYPE_DH);
+
+        if (ssl->buffers.serverDH_Pub.buffer)
+            ssl->buffers.serverDH_Pub.length = length;
+        else
+            return MEMORY_ERROR;
+
+        XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + *inOutIdx, length);
+        *inOutIdx += length;
+        }  /* dh_kea */
+    #endif /* NO_DH */
+
+    #ifdef HAVE_ECC
+        if (ssl->specs.kea == ecc_diffie_hellman_kea)
+        {
+        byte b;
+
+        if ((*inOutIdx - begin) + ENUM_LEN + OPAQUE16_LEN + OPAQUE8_LEN > size)
+            return BUFFER_ERROR;
+
+        b = input[(*inOutIdx)++];
+
+        if (b != named_curve)
+            return ECC_CURVETYPE_ERROR;
+
+        *inOutIdx += 1;   /* curve type, eat leading 0 */
+        b = input[(*inOutIdx)++];
+
+        if (CheckCurveId(b) != 0) {
+            return ECC_CURVE_ERROR;
+        }
+
+        length = input[(*inOutIdx)++];
+
+        if ((*inOutIdx - begin) + length > size)
+            return BUFFER_ERROR;
+
+        if (ssl->peerEccKey == NULL) {
+            /* alloc/init on demand */
+            ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
+                                              ssl->ctx->heap, DYNAMIC_TYPE_ECC);
+            if (ssl->peerEccKey == NULL) {
+                WOLFSSL_MSG("PeerEccKey Memory error");
+                return MEMORY_E;
+            }
+            wc_ecc_init(ssl->peerEccKey);
+        } else if (ssl->peerEccKeyPresent) {  /* don't leak on reuse */
+            wc_ecc_free(ssl->peerEccKey);
+            ssl->peerEccKeyPresent = 0;
+            wc_ecc_init(ssl->peerEccKey);
+        }
+
+        if (wc_ecc_import_x963(input + *inOutIdx, length, ssl->peerEccKey) != 0)
+            return ECC_PEERKEY_ERROR;
+
+        *inOutIdx += length;
+        ssl->peerEccKeyPresent = 1;
+        }
+    #endif /* HAVE_ECC */
+
+    #if !defined(NO_DH) && !defined(NO_PSK)
+    if (ssl->specs.kea == dhe_psk_kea) {
+        if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+            return BUFFER_ERROR;
+
+        ato16(input + *inOutIdx, &length);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if ((*inOutIdx - begin) + length > size)
+            return BUFFER_ERROR;
+
+        XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx,
+               min(length, MAX_PSK_ID_LEN));
+
+        ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0;
+        *inOutIdx += length;
+
+        /* p */
+        if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+            return BUFFER_ERROR;
+
+        ato16(input + *inOutIdx, &length);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if ((*inOutIdx - begin) + length > size)
+            return BUFFER_ERROR;
+
+        if (length < ssl->options.minDhKeySz) {
+            WOLFSSL_MSG("Server using a DH key that is too small");
+            SendAlert(ssl, alert_fatal, handshake_failure);
+            return DH_KEY_SIZE_E;
+        }
+
+        ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
+                                                         DYNAMIC_TYPE_DH);
+
+        if (ssl->buffers.serverDH_P.buffer)
+            ssl->buffers.serverDH_P.length = length;
+        else
+            return MEMORY_ERROR;
+
+        XMEMCPY(ssl->buffers.serverDH_P.buffer, input + *inOutIdx, length);
+        *inOutIdx += length;
+
+        ssl->options.dhKeySz = length;
+
+        /* g */
+        if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+            return BUFFER_ERROR;
+
+        ato16(input + *inOutIdx, &length);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if ((*inOutIdx - begin) + length > size)
+            return BUFFER_ERROR;
+
+        ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
+                                                         DYNAMIC_TYPE_DH);
+
+        if (ssl->buffers.serverDH_G.buffer)
+            ssl->buffers.serverDH_G.length = length;
+        else
+            return MEMORY_ERROR;
+
+        XMEMCPY(ssl->buffers.serverDH_G.buffer, input + *inOutIdx, length);
+        *inOutIdx += length;
+
+        /* pub */
+        if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+            return BUFFER_ERROR;
+
+        ato16(input + *inOutIdx, &length);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if ((*inOutIdx - begin) + length > size)
+            return BUFFER_ERROR;
+
+        ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
+                                                           DYNAMIC_TYPE_DH);
+
+        if (ssl->buffers.serverDH_Pub.buffer)
+            ssl->buffers.serverDH_Pub.length = length;
+        else
+            return MEMORY_ERROR;
+
+        XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + *inOutIdx, length);
+        *inOutIdx += length;
+    }
+    #endif /* !NO_DH || !NO_PSK */
+
+    #if !defined(NO_DH) || defined(HAVE_ECC)
+    if (!ssl->options.usingAnon_cipher &&
+        (ssl->specs.kea == ecc_diffie_hellman_kea ||
+         ssl->specs.kea == diffie_hellman_kea))
+    {
+#ifndef NO_OLD_TLS
+#ifdef WOLFSSL_SMALL_STACK
+        Md5*    md5 = NULL;
+        Sha*    sha = NULL;
+#else
+        Md5     md5[1];
+        Sha     sha[1];
+#endif
+#endif
+#ifndef NO_SHA256
+#ifdef WOLFSSL_SMALL_STACK
+        Sha256* sha256  = NULL;
+        byte*   hash256 = NULL;
+#else
+        Sha256  sha256[1];
+        byte    hash256[SHA256_DIGEST_SIZE];
+#endif
+#endif
+#ifdef WOLFSSL_SHA384
+#ifdef WOLFSSL_SMALL_STACK
+        Sha384* sha384  = NULL;
+        byte*   hash384 = NULL;
+#else
+        Sha384  sha384[1];
+        byte    hash384[SHA384_DIGEST_SIZE];
+#endif
+#endif
+#ifdef WOLFSSL_SHA512
+#ifdef WOLFSSL_SMALL_STACK
+        Sha512* sha512  = NULL;
+        byte*   hash512 = NULL;
+#else
+        Sha512  sha512[1];
+        byte    hash512[SHA512_DIGEST_SIZE];
+#endif
+#endif
+#ifdef WOLFSSL_SMALL_STACK
+        byte*   hash          = NULL;
+        byte*   messageVerify = NULL;
+#else
+        byte    hash[FINISHED_SZ];
+        byte    messageVerify[MAX_DH_SZ];
+#endif
+        byte    hashAlgo = sha_mac;
+        byte    sigAlgo  = ssl->specs.sig_algo;
+        word16  verifySz = (word16) (*inOutIdx - begin);
+
+#ifndef NO_OLD_TLS
+        byte doMd5 = 0;
+        byte doSha = 0;
+#endif
+#ifndef NO_SHA256
+        byte doSha256 = 0;
+#endif
+#ifdef WOLFSSL_SHA384
+        byte doSha384 = 0;
+#endif
+#ifdef WOLFSSL_SHA512
+        byte doSha512 = 0;
+#endif
+
+        (void)hash;
+        (void)sigAlgo;
+        (void)hashAlgo;
+
+        /* save message for hash verify */
+        if (verifySz > MAX_DH_SZ)
+            ERROR_OUT(BUFFER_ERROR, done);
+
+    #ifdef WOLFSSL_SMALL_STACK
+        messageVerify = (byte*)XMALLOC(MAX_DH_SZ, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+        if (messageVerify == NULL)
+            ERROR_OUT(MEMORY_E, done);
+    #endif
+
+        XMEMCPY(messageVerify, input + begin, verifySz);
+
+        if (IsAtLeastTLSv1_2(ssl)) {
+            byte setHash = 0;
+            if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size)
+                ERROR_OUT(BUFFER_ERROR, done);
+
+            hashAlgo = input[(*inOutIdx)++];
+            sigAlgo  = input[(*inOutIdx)++];
+
+            switch (hashAlgo) {
+                case sha512_mac:
+                    #ifdef WOLFSSL_SHA512
+                        doSha512 = 1;
+                        setHash  = 1;
+                    #endif
+                    break;
+
+                case sha384_mac:
+                    #ifdef WOLFSSL_SHA384
+                        doSha384 = 1;
+                        setHash  = 1;
+                    #endif
+                    break;
+
+                case sha256_mac:
+                    #ifndef NO_SHA256
+                        doSha256 = 1;
+                        setHash  = 1;
+                    #endif
+                    break;
+
+                case sha_mac:
+                    #ifndef NO_OLD_TLS
+                        doSha = 1;
+                        setHash  = 1;
+                    #endif
+                    break;
+
+                default:
+                    ERROR_OUT(ALGO_ID_E, done);
+            }
+
+            if (setHash == 0) {
+                ERROR_OUT(ALGO_ID_E, done);
+            }
+
+        } else {
+            /* only using sha and md5 for rsa */
+            #ifndef NO_OLD_TLS
+                doSha = 1;
+                if (sigAlgo == rsa_sa_algo) {
+                    doMd5 = 1;
+                }
+            #else
+                ERROR_OUT(ALGO_ID_E, done);
+            #endif
+        }
+
+        /* signature */
+        if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+            ERROR_OUT(BUFFER_ERROR, done);
+
+        ato16(input + *inOutIdx, &length);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if ((*inOutIdx - begin) + length > size)
+            ERROR_OUT(BUFFER_ERROR, done);
+
+        /* inOutIdx updated at the end of the function */
+
+        /* verify signature */
+    #ifdef WOLFSSL_SMALL_STACK
+        hash = (byte*)XMALLOC(FINISHED_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (hash == NULL)
+            ERROR_OUT(MEMORY_E, done);
+    #endif
+
+#ifndef NO_OLD_TLS
+        /* md5 */
+    #ifdef WOLFSSL_SMALL_STACK
+        if (doMd5) {
+            md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            if (md5 == NULL)
+                ERROR_OUT(MEMORY_E, done);
+        }
+    #endif
+        if (doMd5) {
+            wc_InitMd5(md5);
+            wc_Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
+            wc_Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
+            wc_Md5Update(md5, messageVerify, verifySz);
+            wc_Md5Final(md5, hash);
+        }
+        /* sha */
+    #ifdef WOLFSSL_SMALL_STACK
+        if (doSha) {
+            sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            if (sha == NULL)
+                ERROR_OUT(MEMORY_E, done);
+        }
+    #endif
+        if (doSha) {
+            ret = wc_InitSha(sha);
+            if (ret != 0) goto done;
+            wc_ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
+            wc_ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
+            wc_ShaUpdate(sha, messageVerify, verifySz);
+            wc_ShaFinal(sha, hash + MD5_DIGEST_SIZE);
+        }
+#endif
+
+#ifndef NO_SHA256
+    #ifdef WOLFSSL_SMALL_STACK
+        if (doSha256) {
+            sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            if (sha256 == NULL || hash256 == NULL)
+                ERROR_OUT(MEMORY_E, done);
+        }
+    #endif
+        if (doSha256) {
+            if (!(ret = wc_InitSha256(sha256))
+            &&  !(ret = wc_Sha256Update(sha256, ssl->arrays->clientRandom,
+                                        RAN_LEN))
+            &&  !(ret = wc_Sha256Update(sha256, ssl->arrays->serverRandom,
+                                        RAN_LEN))
+            &&  !(ret = wc_Sha256Update(sha256, messageVerify, verifySz)))
+                  ret = wc_Sha256Final(sha256, hash256);
+            if (ret != 0) goto done;
+        }
+#endif
+
+#ifdef WOLFSSL_SHA384
+    #ifdef WOLFSSL_SMALL_STACK
+        if (doSha384) {
+            sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            if (sha384 == NULL || hash384 == NULL)
+                ERROR_OUT(MEMORY_E, done);
+        }
+    #endif
+        if (doSha384) {
+            if (!(ret = wc_InitSha384(sha384))
+            &&  !(ret = wc_Sha384Update(sha384, ssl->arrays->clientRandom,
+                                        RAN_LEN))
+            &&  !(ret = wc_Sha384Update(sha384, ssl->arrays->serverRandom,
+                                        RAN_LEN))
+            &&  !(ret = wc_Sha384Update(sha384, messageVerify, verifySz)))
+                  ret = wc_Sha384Final(sha384, hash384);
+            if (ret != 0) goto done;
+        }
+#endif
+
+#ifdef WOLFSSL_SHA512
+    #ifdef WOLFSSL_SMALL_STACK
+        if (doSha512) {
+            sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            hash512 = (byte*)XMALLOC(SHA512_DIGEST_SIZE, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            if (sha512 == NULL || hash512 == NULL)
+                ERROR_OUT(MEMORY_E, done);
+        }
+    #endif
+        if (doSha512) {
+            if (!(ret = wc_InitSha512(sha512))
+            &&  !(ret = wc_Sha512Update(sha512, ssl->arrays->clientRandom,
+                                        RAN_LEN))
+            &&  !(ret = wc_Sha512Update(sha512, ssl->arrays->serverRandom,
+                                        RAN_LEN))
+            &&  !(ret = wc_Sha512Update(sha512, messageVerify, verifySz)))
+                  ret = wc_Sha512Final(sha512, hash512);
+            if (ret != 0) goto done;
+        }
+#endif
+
+#ifndef NO_RSA
+        /* rsa */
+        if (sigAlgo == rsa_sa_algo)
+        {
+            byte*  out        = NULL;
+            byte   doUserRsa  = 0;
+            word32 verifiedSz = 0;
+
+            #ifdef HAVE_PK_CALLBACKS
+                if (ssl->ctx->RsaVerifyCb)
+                    doUserRsa = 1;
+            #endif /*HAVE_PK_CALLBACKS */
+
+            if (ssl->peerRsaKey == NULL || !ssl->peerRsaKeyPresent)
+                ERROR_OUT(NO_PEER_KEY, done);
+
+            if (doUserRsa) {
+            #ifdef HAVE_PK_CALLBACKS
+                verifiedSz = ssl->ctx->RsaVerifyCb(ssl,
+                                                 (byte *)input + *inOutIdx,
+                                                 length, &out,
+                                                 ssl->buffers.peerRsaKey.buffer,
+                                                 ssl->buffers.peerRsaKey.length,
+                                                 ssl->RsaVerifyCtx);
+            #endif /*HAVE_PK_CALLBACKS */
+            }
+            else
+                verifiedSz = wc_RsaSSL_VerifyInline((byte *)input + *inOutIdx,
+                                                 length, &out, ssl->peerRsaKey);
+
+            if (IsAtLeastTLSv1_2(ssl)) {
+                word32 encSigSz;
+#ifndef NO_OLD_TLS
+                byte*  digest = &hash[MD5_DIGEST_SIZE];
+                int    typeH = SHAh;
+                int    digestSz = SHA_DIGEST_SIZE;
+#else
+                byte*  digest = hash256;
+                int    typeH =  SHA256h;
+                int    digestSz = SHA256_DIGEST_SIZE;
+#endif
+#ifdef WOLFSSL_SMALL_STACK
+                byte*  encodedSig = NULL;
+#else
+                byte   encodedSig[MAX_ENCODED_SIG_SZ];
+#endif
+
+                if (hashAlgo == sha_mac) {
+                    #ifndef NO_SHA
+                        digest   = &hash[MD5_DIGEST_SIZE];
+                        typeH    = SHAh;
+                        digestSz = SHA_DIGEST_SIZE;
+                    #endif
+                }
+                else if (hashAlgo == sha256_mac) {
+                    #ifndef NO_SHA256
+                        digest   = hash256;
+                        typeH    = SHA256h;
+                        digestSz = SHA256_DIGEST_SIZE;
+                    #endif
+                }
+                else if (hashAlgo == sha384_mac) {
+                    #ifdef WOLFSSL_SHA384
+                        digest   = hash384;
+                        typeH    = SHA384h;
+                        digestSz = SHA384_DIGEST_SIZE;
+                    #endif
+                }
+                else if (hashAlgo == sha512_mac) {
+                    #ifdef WOLFSSL_SHA512
+                        digest   = hash512;
+                        typeH    = SHA512h;
+                        digestSz = SHA512_DIGEST_SIZE;
+                    #endif
+                }
+
+            #ifdef WOLFSSL_SMALL_STACK
+                encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                if (encodedSig == NULL)
+                    ERROR_OUT(MEMORY_E, done);
+            #endif
+
+                if (digest == NULL)
+                    ERROR_OUT(ALGO_ID_E, done);
+                encSigSz = wc_EncodeSignature(encodedSig, digest, digestSz,
+                                              typeH);
+                if (encSigSz != verifiedSz || !out || XMEMCMP(out, encodedSig,
+                                        min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0)
+                    ret = VERIFY_SIGN_ERROR;
+            #ifdef WOLFSSL_SMALL_STACK
+                XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+                if (ret != 0)
+                    goto done;
+            }
+            else if (verifiedSz != FINISHED_SZ || !out || XMEMCMP(out,
+                                                        hash, FINISHED_SZ) != 0)
+                ERROR_OUT(VERIFY_SIGN_ERROR, done);
+        } else
+#endif
+#ifdef HAVE_ECC
+        /* ecdsa */
+        if (sigAlgo == ecc_dsa_sa_algo) {
+            int verify = 0;
+#ifndef NO_OLD_TLS
+            byte* digest = &hash[MD5_DIGEST_SIZE];
+            word32 digestSz = SHA_DIGEST_SIZE;
+#else
+            byte* digest = hash256;
+            word32 digestSz = SHA256_DIGEST_SIZE;
+#endif
+            byte doUserEcc = 0;
+
+            #ifdef HAVE_PK_CALLBACKS
+                if (ssl->ctx->EccVerifyCb)
+                    doUserEcc = 1;
+            #endif
+
+            if (!ssl->peerEccDsaKeyPresent)
+                ERROR_OUT(NO_PEER_KEY, done);
+
+            if (IsAtLeastTLSv1_2(ssl)) {
+                if (hashAlgo == sha_mac) {
+                    #ifndef NO_SHA
+                        digest   = &hash[MD5_DIGEST_SIZE];
+                        digestSz = SHA_DIGEST_SIZE;
+                    #endif
+                }
+                else if (hashAlgo == sha256_mac) {
+                    #ifndef NO_SHA256
+                        digest   = hash256;
+                        digestSz = SHA256_DIGEST_SIZE;
+                    #endif
+                }
+                else if (hashAlgo == sha384_mac) {
+                    #ifdef WOLFSSL_SHA384
+                        digest   = hash384;
+                        digestSz = SHA384_DIGEST_SIZE;
+                    #endif
+                }
+                else if (hashAlgo == sha512_mac) {
+                    #ifdef WOLFSSL_SHA512
+                        digest   = hash512;
+                        digestSz = SHA512_DIGEST_SIZE;
+                    #endif
+                }
+            }
+            if (doUserEcc) {
+            #ifdef HAVE_PK_CALLBACKS
+                ret = ssl->ctx->EccVerifyCb(ssl, input + *inOutIdx, length,
+                                            digest, digestSz,
+                                            ssl->buffers.peerEccDsaKey.buffer,
+                                            ssl->buffers.peerEccDsaKey.length,
+                                            &verify, ssl->EccVerifyCtx);
+            #endif
+            }
+            else {
+                ret = wc_ecc_verify_hash(input + *inOutIdx, length,
+                                 digest, digestSz, &verify, ssl->peerEccDsaKey);
+            }
+            if (ret != 0 || verify == 0)
+                ERROR_OUT(VERIFY_SIGN_ERROR, done);
+        }
+        else
+#endif /* HAVE_ECC */
+            ERROR_OUT(ALGO_ID_E, done);
+
+        /* signature length */
+        *inOutIdx += length;
+
+        ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
+
+    done:
+#ifdef WOLFSSL_SMALL_STACK
+    #ifndef NO_OLD_TLS
+        XFREE(md5,           NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(sha,           NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+    #ifndef NO_SHA256
+        XFREE(sha256,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(hash256,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+    #ifdef WOLFSSL_SHA384
+        XFREE(sha384,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(hash384,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+    #ifdef WOLFSSL_SHA512
+        XFREE(sha512,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(hash512,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+        XFREE(hash,          NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        if (ret != 0)
+            return ret;
+    }
+
+    if (ssl->keys.encryptionOn) {
+        *inOutIdx += ssl->keys.padSz;
+    }
+
+
+    /* QSH extensions */
+#ifdef HAVE_QSH
+    if (ssl->peerQSHKeyPresent) {
+        /* extension name */
+        ato16(input + *inOutIdx, &name);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if (name == WOLFSSL_QSH) {
+            /* if qshSz is larger than 0 it is the length of buffer used */
+            if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
+                                                                  size, 0)) < 0)
+                return qshSz;
+            *inOutIdx += qshSz;
+        }
+        else {
+            /* unknown extension sent server ignored
+               handshake */
+            return BUFFER_ERROR;
+        }
+    }
+#endif
+
+    return 0;
+#else  /* !NO_DH or HAVE_ECC */
+        return NOT_COMPILED_IN;  /* not supported by build */
+#endif /* !NO_DH or HAVE_ECC */
+
+        #undef ERROR_OUT
+    }
+
+
+#ifdef HAVE_QSH
+
+#ifdef HAVE_NTRU
+/* Encrypt a byte array using ntru
+   key    a struct containing the public key to use
+   bufIn  array to be encrypted
+   inSz   size of bufIn array
+   bufOut cipher text out
+   outSz  will be set to the new size of cipher text
+ */
+static int NtruSecretEncrypt(QSHKey* key, byte* bufIn, word32 inSz,
+        byte* bufOut, word16* outSz)
+{
+    int    ret;
+    DRBG_HANDLE drbg;
+
+    /* sanity checks on input arguments */
+    if (key == NULL || bufIn == NULL || bufOut == NULL || outSz == NULL)
+        return BAD_FUNC_ARG;
+
+    if (key->pub.buffer == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (key->name) {
+        case WOLFSSL_NTRU_EESS439:
+        case WOLFSSL_NTRU_EESS593:
+        case WOLFSSL_NTRU_EESS743:
+            break;
+        default:
+            WOLFSSL_MSG("Unknown QSH encryption key!");
+            return -1;
+    }
+
+    /* set up ntru drbg */
+    ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
+    if (ret != DRBG_OK)
+        return NTRU_DRBG_ERROR;
+
+    /* encrypt the byte array */
+    ret = ntru_crypto_ntru_encrypt(drbg, key->pub.length, key->pub.buffer,
+        inSz, bufIn, outSz, bufOut);
+    ntru_crypto_drbg_uninstantiate(drbg);
+    if (ret != NTRU_OK)
+        return NTRU_ENCRYPT_ERROR;
+
+    return ret;
+}
+
+/* Decrypt a byte array using ntru
+   key    a struct containing the private key to use
+   bufIn  array to be decrypted
+   inSz   size of bufIn array
+   bufOut plain text out
+   outSz  will be set to the new size of plain text
+ */
+
+static int NtruSecretDecrypt(QSHKey* key, byte* bufIn, word32 inSz,
+        byte* bufOut, word16* outSz)
+{
+    int    ret;
+    DRBG_HANDLE drbg;
+
+    /* sanity checks on input arguments */
+    if (key == NULL || bufIn == NULL || bufOut == NULL || outSz == NULL)
+        return BAD_FUNC_ARG;
+
+    if (key->pri.buffer == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (key->name) {
+        case WOLFSSL_NTRU_EESS439:
+        case WOLFSSL_NTRU_EESS593:
+        case WOLFSSL_NTRU_EESS743:
+            break;
+        default:
+            WOLFSSL_MSG("Unknown QSH decryption key!");
+            return -1;
+    }
+
+
+    /* set up drbg */
+    ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
+    if (ret != DRBG_OK)
+        return NTRU_DRBG_ERROR;
+
+    /* decrypt cipher text */
+    ret = ntru_crypto_ntru_decrypt(key->pri.length, key->pri.buffer,
+        inSz, bufIn, outSz, bufOut);
+    ntru_crypto_drbg_uninstantiate(drbg);
+    if (ret != NTRU_OK)
+        return NTRU_ENCRYPT_ERROR;
+
+    return ret;
+}
+#endif /* HAVE_NTRU */
+
+int QSH_Init(WOLFSSL* ssl)
+{
+    /* check so not initialising twice when running DTLS */
+    if (ssl->QSH_secret != NULL)
+        return 0;
+
+    /* malloc memory for holding generated secret information */
+    if ((ssl->QSH_secret =
+             XMALLOC(sizeof(QSHSecret), NULL, DYNAMIC_TYPE_TMP_BUFFER)) == NULL)
+        return MEMORY_E;
+
+    ssl->QSH_secret->CliSi = (buffer*)XMALLOC(sizeof(buffer), NULL,
+            DYNAMIC_TYPE_TMP_BUFFER);
+    if (ssl->QSH_secret->CliSi == NULL)
+        return MEMORY_E;
+
+    ssl->QSH_secret->SerSi = (buffer*)XMALLOC(sizeof(buffer), NULL,
+            DYNAMIC_TYPE_TMP_BUFFER);
+    if (ssl->QSH_secret->SerSi == NULL)
+        return MEMORY_E;
+
+    /* initialize variables */
+    ssl->QSH_secret->list = NULL;
+    ssl->QSH_secret->CliSi->length = 0;
+    ssl->QSH_secret->CliSi->buffer = NULL;
+    ssl->QSH_secret->SerSi->length = 0;
+    ssl->QSH_secret->SerSi->buffer = NULL;
+
+    return 0;
+}
+
+
+static int QSH_Encrypt(QSHKey* key, byte* in, word32 szIn,
+                                                       byte* out, word32* szOut)
+{
+    int ret = 0;
+    word16 size = *szOut;
+
+    WOLFSSL_MSG("Encrypting QSH key material");
+
+    switch (key->name) {
+    #ifdef HAVE_NTRU
+        case WOLFSSL_NTRU_EESS439:
+        case WOLFSSL_NTRU_EESS593:
+        case WOLFSSL_NTRU_EESS743:
+            ret = NtruSecretEncrypt(key, in, szIn, out, &size);
+            break;
+    #endif
+        default:
+            WOLFSSL_MSG("Unknown QSH encryption key!");
+            return -1;
+    }
+
+    *szOut = size;
+
+    return ret;
+}
+
+
+/* Decrypt using Quantum Safe Handshake algorithms */
+int QSH_Decrypt(QSHKey* key, byte* in, word32 szIn,
+                                                       byte* out, word16* szOut)
+{
+    int ret = 0;
+    word16 size = *szOut;
+
+    WOLFSSL_MSG("Decrypting QSH key material");
+
+    switch (key->name) {
+    #ifdef HAVE_NTRU
+        case WOLFSSL_NTRU_EESS439:
+        case WOLFSSL_NTRU_EESS593:
+        case WOLFSSL_NTRU_EESS743:
+            ret = NtruSecretDecrypt(key, in, szIn, out, &size);
+            break;
+    #endif
+        default:
+            WOLFSSL_MSG("Unknown QSH decryption key!");
+            return -1;
+    }
+
+    *szOut = size;
+
+    return ret;
+}
+
+
+/* Get the max cipher text for corresponding encryption scheme
+   (encrypting  48 or max plain text whichever is smaller)
+ */
+static word32 QSH_MaxSecret(QSHKey* key)
+{
+    byte isNtru = 0;
+    word16 inSz = 48;
+    word16 outSz;
+    DRBG_HANDLE drbg = 0;
+    byte bufIn[48];
+    int ret = 0;
+
+    if (key == NULL || key->pub.length == 0)
+        return 0;
+
+    switch(key->name) {
+#ifdef HAVE_NTRU
+            case WOLFSSL_NTRU_EESS439:
+                isNtru   = 1;
+                break;
+            case WOLFSSL_NTRU_EESS593:
+                isNtru   = 1;
+                break;
+            case WOLFSSL_NTRU_EESS743:
+                isNtru   = 1;
+                break;
+#endif
+        default:
+            WOLFSSL_MSG("Unknown QSH encryption scheme size!");
+            return 0;
+    }
+
+    if (isNtru) {
+        ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
+        if (ret != DRBG_OK)
+            return NTRU_DRBG_ERROR;
+        ret = ntru_crypto_ntru_encrypt(drbg, key->pub.length,
+                            key->pub.buffer, inSz, bufIn, &outSz, NULL);
+        if (ret != NTRU_OK) {
+            return NTRU_ENCRYPT_ERROR;
+        }
+        ntru_crypto_drbg_uninstantiate(drbg);
+        return outSz;
+    }
+
+    return 0;
+}
+
+/* Generate the secret byte material for pms
+   returns length on success and -1 on fail
+ */
+static int QSH_GenerateSerCliSecret(WOLFSSL* ssl, byte isServer)
+{
+    int sz       = 0;
+    int plainSz  = 48; /* lesser of 48 and max plain text able to encrypt */
+    int offset   = 0;
+    word32 tmpSz = 0;
+    buffer* buf;
+    QSHKey* current = ssl->peerQSHKey;
+    QSHScheme* schmPre = NULL;
+    QSHScheme* schm    = NULL;
+
+    if (ssl == NULL)
+        return -1;
+
+    WOLFSSL_MSG("Generating QSH secret key material");
+
+    /* get size of buffer needed */
+    while (current) {
+        if (current->pub.length != 0) {
+            sz += plainSz;
+        }
+        current = (QSHKey*)current->next;
+    }
+
+    /* allocate memory for buffer */
+    if (isServer) {
+        buf = ssl->QSH_secret->SerSi;
+    }
+    else {
+        buf = ssl->QSH_secret->CliSi;
+    }
+    buf->length = sz;
+    buf->buffer = XMALLOC(sz, buf->buffer, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buf->buffer == NULL) {
+        WOLFSSL_ERROR(MEMORY_E);
+    }
+
+    /* create secret information */
+    sz = 0;
+    current = ssl->peerQSHKey;
+    while (current) {
+        schm = XMALLOC(sizeof(QSHScheme), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (schm == NULL)
+            return MEMORY_E;
+
+        /* initialize variables */
+        schm->name  = 0;
+        schm->PK    = NULL;
+        schm->PKLen = 0;
+        schm->next  = NULL;
+        if (ssl->QSH_secret->list == NULL) {
+            ssl->QSH_secret->list = schm;
+        }
+        else {
+            if (schmPre)
+                schmPre->next = schm;
+        }
+
+        tmpSz = QSH_MaxSecret(current);
+
+        if ((schm->PK = XMALLOC(tmpSz, 0, DYNAMIC_TYPE_TMP_BUFFER)) == NULL)
+            return -1;
+
+        /* store info for writing extension */
+        schm->name = current->name;
+
+        /* no key to use for encryption */
+        if (tmpSz == 0) {
+            current = (QSHKey*)current->next;
+            continue;
+        }
+
+        if (wc_RNG_GenerateBlock(ssl->rng, buf->buffer + offset, plainSz)
+                                                                         != 0) {
+            return -1;
+        }
+        if (QSH_Encrypt(current, buf->buffer + offset, plainSz, schm->PK,
+                                                                 &tmpSz) != 0) {
+            return -1;
+        }
+        schm->PKLen = tmpSz;
+
+        sz += tmpSz;
+        offset += plainSz;
+        schmPre = schm;
+        current = (QSHKey*)current->next;
+    }
+
+    return sz;
+}
+
+
+static word32 QSH_KeyGetSize(WOLFSSL* ssl)
+{
+    word32 sz = 0;
+    QSHKey* current = ssl->peerQSHKey;
+
+    if (ssl == NULL)
+        return -1;
+
+    sz += OPAQUE16_LEN; /* type of extension ie 0x00 0x18 */
+    sz += OPAQUE24_LEN;
+    /* get size of buffer needed */
+    while (current) {
+        sz += OPAQUE16_LEN; /* scheme id */
+        sz += OPAQUE16_LEN; /* encrypted key len*/
+        sz += QSH_MaxSecret(current);
+        current = (QSHKey*)current->next;
+    }
+
+    return sz;
+}
+
+
+/* handle QSH key Exchange
+   return 0 on success
+ */
+static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer)
+{
+    int ret = 0;
+
+    WOLFSSL_ENTER("QSH KeyExchange");
+
+    ret = QSH_GenerateSerCliSecret(ssl, isServer);
+    if (ret < 0)
+        return MEMORY_E;
+
+    return 0;
+}
+
+#endif /* HAVE_QSH */
+
+
+    int SendClientKeyExchange(WOLFSSL* ssl)
+    {
+#ifdef WOLFSSL_SMALL_STACK
+        byte*  encSecret = NULL;
+#else
+        byte   encSecret[MAX_ENCRYPT_SZ];
+#endif
+        word32 encSz = 0;
+        word32 idx = 0;
+        int    ret = 0;
+        byte   doUserRsa = 0;
+
+    #ifdef HAVE_QSH
+        word32 qshSz = 0;
+        if (ssl->peerQSHKeyPresent) {
+            qshSz = QSH_KeyGetSize(ssl);
+        }
+    #endif
+
+        (void)doUserRsa;
+
+#ifdef HAVE_PK_CALLBACKS
+    #ifndef NO_RSA
+        if (ssl->ctx->RsaEncCb)
+            doUserRsa = 1;
+    #endif /* NO_RSA */
+#endif /*HAVE_PK_CALLBACKS */
+
+    #ifdef WOLFSSL_SMALL_STACK
+        encSecret = (byte*)XMALLOC(MAX_ENCRYPT_SZ, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+        if (encSecret == NULL)
+            return MEMORY_E;
+    #endif
+
+        switch (ssl->specs.kea) {
+        #ifndef NO_RSA
+            case rsa_kea:
+                ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret,
+                                                                    SECRET_LEN);
+                if (ret != 0) {
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                #endif
+                    return ret;
+                }
+
+                ssl->arrays->preMasterSecret[0] = ssl->chVersion.major;
+                ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor;
+                ssl->arrays->preMasterSz = SECRET_LEN;
+
+                if (ssl->peerRsaKey == NULL || ssl->peerRsaKeyPresent == 0) {
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                #endif
+                    return NO_PEER_KEY;
+                }
+
+                if (doUserRsa) {
+                #ifdef HAVE_PK_CALLBACKS
+                    #ifndef NO_RSA
+                        encSz = MAX_ENCRYPT_SZ;
+                        ret = ssl->ctx->RsaEncCb(ssl,
+                                            ssl->arrays->preMasterSecret,
+                                            SECRET_LEN,
+                                            encSecret, &encSz,
+                                            ssl->buffers.peerRsaKey.buffer,
+                                            ssl->buffers.peerRsaKey.length,
+                                            ssl->RsaEncCtx);
+                    #endif /* NO_RSA */
+                #endif /*HAVE_PK_CALLBACKS */
+                }
+                else {
+                    ret = wc_RsaPublicEncrypt(ssl->arrays->preMasterSecret,
+                                 SECRET_LEN, encSecret, MAX_ENCRYPT_SZ,
+                                 ssl->peerRsaKey, ssl->rng);
+                    if (ret > 0) {
+                        encSz = ret;
+                        ret = 0;   /* set success to 0 */
+                    }
+                }
+                break;
+        #endif
+        #ifndef NO_DH
+            case diffie_hellman_kea:
+                {
+                    buffer  serverP   = ssl->buffers.serverDH_P;
+                    buffer  serverG   = ssl->buffers.serverDH_G;
+                    buffer  serverPub = ssl->buffers.serverDH_Pub;
+                #ifdef WOLFSSL_SMALL_STACK
+                    byte*   priv = NULL;
+                #else
+                    byte    priv[ENCRYPT_LEN];
+                #endif
+                    word32  privSz = 0;
+                    DhKey   key;
+
+                    if (serverP.buffer == 0 || serverG.buffer == 0 ||
+                                               serverPub.buffer == 0) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return NO_PEER_KEY;
+                    }
+
+                #ifdef WOLFSSL_SMALL_STACK
+                    priv = (byte*)XMALLOC(ENCRYPT_LEN, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                    if (priv == NULL) {
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                        return MEMORY_E;
+                    }
+                #endif
+
+                    wc_InitDhKey(&key);
+                    ret = wc_DhSetKey(&key, serverP.buffer, serverP.length,
+                                   serverG.buffer, serverG.length);
+                    if (ret == 0)
+                        /* for DH, encSecret is Yc, agree is pre-master */
+                        ret = wc_DhGenerateKeyPair(&key, ssl->rng, priv, &privSz,
+                                                encSecret, &encSz);
+                    if (ret == 0)
+                        ret = wc_DhAgree(&key, ssl->arrays->preMasterSecret,
+                                      &ssl->arrays->preMasterSz, priv, privSz,
+                                      serverPub.buffer, serverPub.length);
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                #endif
+                    wc_FreeDhKey(&key);
+                }
+                break;
+        #endif /* NO_DH */
+        #ifndef NO_PSK
+            case psk_kea:
+                {
+                    byte* pms = ssl->arrays->preMasterSecret;
+
+                    ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
+                        ssl->arrays->server_hint, ssl->arrays->client_identity,
+                        MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
+                    if (ssl->arrays->psk_keySz == 0 ||
+                        ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return PSK_KEY_ERROR;
+                    }
+                    encSz = (word32)XSTRLEN(ssl->arrays->client_identity);
+                    if (encSz > MAX_PSK_ID_LEN) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return CLIENT_ID_ERROR;
+                    }
+                    XMEMCPY(encSecret, ssl->arrays->client_identity, encSz);
+
+                    /* make psk pre master secret */
+                    /* length of key + length 0s + length of key + key */
+                    c16toa((word16)ssl->arrays->psk_keySz, pms);
+                    pms += 2;
+                    XMEMSET(pms, 0, ssl->arrays->psk_keySz);
+                    pms += ssl->arrays->psk_keySz;
+                    c16toa((word16)ssl->arrays->psk_keySz, pms);
+                    pms += 2;
+                    XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                    ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
+                    ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                    ssl->arrays->psk_keySz = 0; /* No further need */
+                }
+                break;
+        #endif /* NO_PSK */
+        #if !defined(NO_DH) && !defined(NO_PSK)
+            case dhe_psk_kea:
+                {
+                    byte* pms = ssl->arrays->preMasterSecret;
+                    byte* es  = encSecret;
+                    buffer  serverP   = ssl->buffers.serverDH_P;
+                    buffer  serverG   = ssl->buffers.serverDH_G;
+                    buffer  serverPub = ssl->buffers.serverDH_Pub;
+                #ifdef WOLFSSL_SMALL_STACK
+                    byte*   priv = NULL;
+                #else
+                    byte    priv[ENCRYPT_LEN];
+                #endif
+                    word32  privSz = 0;
+                    word32  pubSz = 0;
+                    word32  esSz = 0;
+                    DhKey   key;
+
+                    if (serverP.buffer == 0 || serverG.buffer == 0 ||
+                                               serverPub.buffer == 0) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return NO_PEER_KEY;
+                    }
+
+                    ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
+                         ssl->arrays->server_hint, ssl->arrays->client_identity,
+                         MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
+                    if (ssl->arrays->psk_keySz == 0 ||
+                                     ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return PSK_KEY_ERROR;
+                    }
+                    esSz = (word32)XSTRLEN(ssl->arrays->client_identity);
+
+                    if (esSz > MAX_PSK_ID_LEN) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return CLIENT_ID_ERROR;
+                    }
+
+                #ifdef WOLFSSL_SMALL_STACK
+                    priv = (byte*)XMALLOC(ENCRYPT_LEN, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                    if (priv == NULL) {
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                        return MEMORY_E;
+                    }
+                #endif
+                    c16toa((word16)esSz, es);
+                    es += OPAQUE16_LEN;
+                    XMEMCPY(es, ssl->arrays->client_identity, esSz);
+                    es += esSz;
+                    encSz = esSz + OPAQUE16_LEN;
+
+                    wc_InitDhKey(&key);
+                    ret = wc_DhSetKey(&key, serverP.buffer, serverP.length,
+                                   serverG.buffer, serverG.length);
+                    if (ret == 0)
+                        /* for DH, encSecret is Yc, agree is pre-master */
+                        ret = wc_DhGenerateKeyPair(&key, ssl->rng, priv, &privSz,
+                                                es + OPAQUE16_LEN, &pubSz);
+                    if (ret == 0)
+                        ret = wc_DhAgree(&key, pms + OPAQUE16_LEN,
+                                      &ssl->arrays->preMasterSz, priv, privSz,
+                                      serverPub.buffer, serverPub.length);
+                    wc_FreeDhKey(&key);
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                #endif
+                    if (ret != 0) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return ret;
+                    }
+
+                    c16toa((word16)pubSz, es);
+                    encSz += pubSz + OPAQUE16_LEN;
+                    c16toa((word16)ssl->arrays->preMasterSz, pms);
+                    ssl->arrays->preMasterSz += OPAQUE16_LEN;
+                    pms += ssl->arrays->preMasterSz;
+
+                    /* make psk pre master secret */
+                    /* length of key + length 0s + length of key + key */
+                    c16toa((word16)ssl->arrays->psk_keySz, pms);
+                    pms += OPAQUE16_LEN;
+                    XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                    ssl->arrays->preMasterSz +=
+                                          ssl->arrays->psk_keySz + OPAQUE16_LEN;
+                    ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                    ssl->arrays->psk_keySz = 0; /* No further need */
+                }
+                break;
+        #endif /* !NO_DH && !NO_PSK */
+        #ifdef HAVE_NTRU
+            case ntru_kea:
+                {
+                    word32 rc;
+                    word16 cipherLen = MAX_ENCRYPT_SZ;
+                    DRBG_HANDLE drbg;
+
+                    ret = wc_RNG_GenerateBlock(ssl->rng,
+                                      ssl->arrays->preMasterSecret, SECRET_LEN);
+                    if (ret != 0) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return ret;
+                    }
+
+                    ssl->arrays->preMasterSz = SECRET_LEN;
+
+                    if (ssl->peerNtruKeyPresent == 0) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return NO_PEER_KEY;
+                    }
+
+                    rc = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
+                    if (rc != DRBG_OK) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return NTRU_DRBG_ERROR;
+                    }
+
+                    rc = ntru_crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen,
+                                                  ssl->peerNtruKey,
+                                                  ssl->arrays->preMasterSz,
+                                                  ssl->arrays->preMasterSecret,
+                                                  &cipherLen, encSecret);
+                    ntru_crypto_drbg_uninstantiate(drbg);
+                    if (rc != NTRU_OK) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return NTRU_ENCRYPT_ERROR;
+                    }
+
+                    encSz = cipherLen;
+                    ret = 0;
+                }
+                break;
+        #endif /* HAVE_NTRU */
+        #ifdef HAVE_ECC
+            case ecc_diffie_hellman_kea:
+                {
+                    ecc_key  myKey;
+                    ecc_key* peerKey = NULL;
+                    word32   size = MAX_ENCRYPT_SZ;
+
+                    if (ssl->specs.static_ecdh) {
+                        /* TODO: EccDsa is really fixed Ecc change naming */
+                        if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent ||
+                                                   !ssl->peerEccDsaKey->dp) {
+                        #ifdef WOLFSSL_SMALL_STACK
+                            XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                        #endif
+                            return NO_PEER_KEY;
+                        }
+                        peerKey = ssl->peerEccDsaKey;
+                    }
+                    else {
+                        if (!ssl->peerEccKey || !ssl->peerEccKeyPresent ||
+                                                !ssl->peerEccKey->dp) {
+                        #ifdef WOLFSSL_SMALL_STACK
+                            XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                        #endif
+                            return NO_PEER_KEY;
+                        }
+                        peerKey = ssl->peerEccKey;
+                    }
+
+                    if (peerKey == NULL) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return NO_PEER_KEY;
+                    }
+
+                    wc_ecc_init(&myKey);
+                    ret = wc_ecc_make_key(ssl->rng, peerKey->dp->size, &myKey);
+                    if (ret != 0) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return ECC_MAKEKEY_ERROR;
+                    }
+
+                    /* precede export with 1 byte length */
+                    ret = wc_ecc_export_x963(&myKey, encSecret + 1, &size);
+                    encSecret[0] = (byte)size;
+                    encSz = size + 1;
+
+                    if (ret != 0)
+                        ret = ECC_EXPORT_ERROR;
+                    else {
+                        size = sizeof(ssl->arrays->preMasterSecret);
+                        ret  = wc_ecc_shared_secret(&myKey, peerKey,
+                                                 ssl->arrays->preMasterSecret, &size);
+                        if (ret != 0)
+                            ret = ECC_SHARED_ERROR;
+                    }
+
+                    ssl->arrays->preMasterSz = size;
+                    wc_ecc_free(&myKey);
+                }
+                break;
+        #endif /* HAVE_ECC */
+            default:
+            #ifdef WOLFSSL_SMALL_STACK
+                XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+                return ALGO_ID_E; /* unsupported kea */
+        }
+
+        if (ret == 0) {
+            byte              *output;
+            int                sendSz;
+            word32             tlsSz = 0;
+
+            if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea)
+                tlsSz = 2;
+
+            if (ssl->specs.kea == ecc_diffie_hellman_kea ||
+                ssl->specs.kea == dhe_psk_kea)  /* always off */
+                tlsSz = 0;
+
+            sendSz = encSz + tlsSz + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+            idx    = HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+
+            #ifdef WOLFSSL_DTLS
+                if (ssl->options.dtls) {
+                    sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
+                    idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
+                }
+            #endif
+
+            if (ssl->keys.encryptionOn)
+                sendSz += MAX_MSG_EXTRA;
+
+        #ifdef HAVE_QSH
+            encSz += qshSz;
+            sendSz += qshSz;
+        #endif
+
+            /* check for available size */
+            if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
+            #ifdef WOLFSSL_SMALL_STACK
+                XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+                return ret;
+            }
+
+            /* get ouput buffer */
+            output = ssl->buffers.outputBuffer.buffer +
+                     ssl->buffers.outputBuffer.length;
+
+
+#ifdef HAVE_QSH
+            if (ssl->peerQSHKeyPresent) {
+                byte idxSave = idx;
+                idx = sendSz - qshSz;
+
+                if (QSH_KeyExchangeWrite(ssl, 0) != 0)
+                    return MEMORY_E;
+
+                /* extension type */
+                c16toa(WOLFSSL_QSH, output + idx);
+                idx += OPAQUE16_LEN;
+
+                /* write to output and check amount written */
+                if (TLSX_QSHPK_Write(ssl->QSH_secret->list, output + idx)
+                                                         > qshSz - OPAQUE16_LEN)
+                    return MEMORY_E;
+
+                idx = idxSave;
+            }
+#endif
+
+            AddHeaders(output, encSz + tlsSz, client_key_exchange, ssl);
+
+#ifdef HAVE_QSH
+            if (ssl->peerQSHKeyPresent) {
+                encSz -= qshSz;
+            }
+#endif
+            if (tlsSz) {
+                c16toa((word16)encSz, &output[idx]);
+                idx += 2;
+            }
+            XMEMCPY(output + idx, encSecret, encSz);
+            idx += encSz;
+
+            if (ssl->keys.encryptionOn) {
+                byte* input;
+                int   inputSz = idx-RECORD_HEADER_SZ; /* buildmsg adds rechdr */
+
+                input = (byte*)XMALLOC(inputSz, ssl->heap,
+                                       DYNAMIC_TYPE_TMP_BUFFER);
+                if (input == NULL) {
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                #endif
+                    return MEMORY_E;
+                }
+
+                XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
+                sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
+                                      handshake);
+                XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+                if (sendSz < 0) {
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                #endif
+                    return sendSz;
+                }
+            } else {
+                ret = HashOutput(ssl, output, sendSz, 0);
+                if (ret != 0) {
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                #endif
+                    return ret;
+                }
+            }
+
+            #ifdef WOLFSSL_DTLS
+                if (ssl->options.dtls) {
+                    if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) {
+                    #ifdef WOLFSSL_SMALL_STACK
+                        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                    #endif
+                        return ret;
+                    }
+                }
+            #endif
+
+            #ifdef WOLFSSL_CALLBACKS
+                if (ssl->hsInfoOn)
+                    AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
+                if (ssl->toInfoOn)
+                    AddPacketInfo("ClientKeyExchange", &ssl->timeoutInfo,
+                                  output, sendSz, ssl->heap);
+            #endif
+
+            ssl->buffers.outputBuffer.length += sendSz;
+
+            if (ssl->options.groupMessages)
+                ret = 0;
+            else
+                ret = SendBuffered(ssl);
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+
+        if (ret == 0 || ret == WANT_WRITE) {
+            int tmpRet = MakeMasterSecret(ssl);
+            if (tmpRet != 0)
+                ret = tmpRet;   /* save WANT_WRITE unless more serious */
+            ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
+        }
+        /* No further need for PMS */
+        ForceZero(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
+        ssl->arrays->preMasterSz = 0;
+
+        return ret;
+    }
+
+#ifndef NO_CERTS
+
+
+    int SendCertificateVerify(WOLFSSL* ssl)
+    {
+        byte              *output;
+        int                sendSz = MAX_CERT_VERIFY_SZ, length, ret;
+        word32             idx = 0;
+        word32             sigOutSz = 0;
+#ifndef NO_RSA
+        RsaKey             key;
+        int                initRsaKey = 0;
+#endif
+        int                usingEcc = 0;
+#ifdef HAVE_ECC
+        ecc_key            eccKey;
+#endif
+
+        (void)idx;
+
+        if (ssl->options.sendVerify == SEND_BLANK_CERT)
+            return 0;  /* sent blank cert, can't verify */
+
+        if (ssl->keys.encryptionOn)
+            sendSz += MAX_MSG_EXTRA;
+
+        /* check for available size */
+        if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+            return ret;
+
+        /* get ouput buffer */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        ret = BuildCertHashes(ssl, &ssl->hsHashes->certHashes);
+        if (ret != 0)
+            return ret;
+
+#ifdef HAVE_ECC
+        wc_ecc_init(&eccKey);
+#endif
+#ifndef NO_RSA
+        ret = wc_InitRsaKey(&key, ssl->heap);
+        if (ret == 0) initRsaKey = 1;
+        if (ret == 0)
+            ret = wc_RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
+                                      ssl->buffers.key.length);
+        if (ret == 0)
+            sigOutSz = wc_RsaEncryptSize(&key);
+        else
+#endif
+        {
+    #ifdef HAVE_ECC
+            WOLFSSL_MSG("Trying ECC client cert, RSA didn't work");
+
+            idx = 0;
+            ret = wc_EccPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &eccKey,
+                                      ssl->buffers.key.length);
+            if (ret == 0) {
+                WOLFSSL_MSG("Using ECC client cert");
+                usingEcc = 1;
+                sigOutSz = MAX_ENCODED_SIG_SZ;
+            }
+            else {
+                WOLFSSL_MSG("Bad client cert type");
+            }
+    #endif
+        }
+        if (ret == 0) {
+            byte*  verify = (byte*)&output[RECORD_HEADER_SZ +
+                                           HANDSHAKE_HEADER_SZ];
+#ifndef NO_OLD_TLS
+            byte*  signBuffer = ssl->hsHashes->certHashes.md5;
+#else
+            byte*  signBuffer = NULL;
+#endif
+            word32 signSz = FINISHED_SZ;
+            word32 extraSz = 0;  /* tls 1.2 hash/sig */
+#ifdef WOLFSSL_SMALL_STACK
+            byte*  encodedSig = NULL;
+#else
+            byte   encodedSig[MAX_ENCODED_SIG_SZ];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+            encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            if (encodedSig == NULL) {
+            #ifndef NO_RSA
+                if (initRsaKey)
+                    wc_FreeRsaKey(&key);
+            #endif
+            #ifdef HAVE_ECC
+                wc_ecc_free(&eccKey);
+            #endif
+                return MEMORY_E;
+            }
+#endif
+
+            (void)encodedSig;
+            (void)signSz;
+            (void)signBuffer;
+
+            #ifdef WOLFSSL_DTLS
+                if (ssl->options.dtls)
+                    verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+            #endif
+            length = sigOutSz;
+            if (IsAtLeastTLSv1_2(ssl)) {
+                verify[0] = ssl->suites->hashAlgo;
+                verify[1] = usingEcc ? ecc_dsa_sa_algo : rsa_sa_algo;
+                extraSz = HASH_SIG_SIZE;
+            }
+
+            if (usingEcc) {
+#ifdef HAVE_ECC
+                word32 localSz = MAX_ENCODED_SIG_SZ;
+                word32 digestSz;
+                byte*  digest;
+                byte   doUserEcc = 0;
+#ifndef NO_OLD_TLS
+                /* old tls default */
+                digestSz = SHA_DIGEST_SIZE;
+                digest   = ssl->hsHashes->certHashes.sha;
+#else
+                /* new tls default */
+                digestSz = SHA256_DIGEST_SIZE;
+                digest   = ssl->hsHashes->certHashes.sha256;
+#endif
+
+                #ifdef HAVE_PK_CALLBACKS
+                    #ifdef HAVE_ECC
+                        if (ssl->ctx->EccSignCb)
+                            doUserEcc = 1;
+                    #endif /* HAVE_ECC */
+                #endif /*HAVE_PK_CALLBACKS */
+
+                if (IsAtLeastTLSv1_2(ssl)) {
+                    if (ssl->suites->hashAlgo == sha_mac) {
+                        #ifndef NO_SHA
+                            digest = ssl->hsHashes->certHashes.sha;
+                            digestSz = SHA_DIGEST_SIZE;
+                        #endif
+                    }
+                    else if (ssl->suites->hashAlgo == sha256_mac) {
+                        #ifndef NO_SHA256
+                            digest = ssl->hsHashes->certHashes.sha256;
+                            digestSz = SHA256_DIGEST_SIZE;
+                        #endif
+                    }
+                    else if (ssl->suites->hashAlgo == sha384_mac) {
+                        #ifdef WOLFSSL_SHA384
+                            digest = ssl->hsHashes->certHashes.sha384;
+                            digestSz = SHA384_DIGEST_SIZE;
+                        #endif
+                    }
+                    else if (ssl->suites->hashAlgo == sha512_mac) {
+                        #ifdef WOLFSSL_SHA512
+                            digest = ssl->hsHashes->certHashes.sha512;
+                            digestSz = SHA512_DIGEST_SIZE;
+                        #endif
+                    }
+                }
+
+                if (doUserEcc) {
+                #ifdef HAVE_PK_CALLBACKS
+                    #ifdef HAVE_ECC
+                        ret = ssl->ctx->EccSignCb(ssl, digest, digestSz,
+                                        encodedSig, &localSz,
+                                        ssl->buffers.key.buffer,
+                                        ssl->buffers.key.length,
+                                        ssl->EccSignCtx);
+                    #endif /* HAVE_ECC */
+                #endif /*HAVE_PK_CALLBACKS */
+                }
+                else {
+                    ret = wc_ecc_sign_hash(digest, digestSz, encodedSig,
+                                        &localSz, ssl->rng, &eccKey);
+                }
+                if (ret == 0) {
+                    length = localSz;
+                    c16toa((word16)length, verify + extraSz); /* prepend hdr */
+                    XMEMCPY(verify + extraSz + VERIFY_HEADER,encodedSig,length);
+                }
+#endif
+            }
+#ifndef NO_RSA
+            else {
+                byte doUserRsa = 0;
+
+                #ifdef HAVE_PK_CALLBACKS
+                    if (ssl->ctx->RsaSignCb)
+                        doUserRsa = 1;
+                #endif /*HAVE_PK_CALLBACKS */
+
+                if (IsAtLeastTLSv1_2(ssl)) {
+                    /*
+                     * MSVC Compiler complains because it can not
+                     * guarantee any of the conditionals will succeed in
+                     * assigning a value before wc_EncodeSignature executes.
+                     */
+                    byte* digest    = NULL;
+                    int   digestSz  = 0;
+                    int   typeH     = 0;
+                    int   didSet    = 0;
+
+                    if (ssl->suites->hashAlgo == sha_mac) {
+                        #ifndef NO_SHA
+                            digest   = ssl->hsHashes->certHashes.sha;
+                            typeH    = SHAh;
+                            digestSz = SHA_DIGEST_SIZE;
+                            didSet   = 1;
+                        #endif
+                    }
+                    else if (ssl->suites->hashAlgo == sha256_mac) {
+                        #ifndef NO_SHA256
+                            digest   = ssl->hsHashes->certHashes.sha256;
+                            typeH    = SHA256h;
+                            digestSz = SHA256_DIGEST_SIZE;
+                            didSet   = 1;
+                        #endif
+                    }
+                    else if (ssl->suites->hashAlgo == sha384_mac) {
+                        #ifdef WOLFSSL_SHA384
+                            digest   = ssl->hsHashes->certHashes.sha384;
+                            typeH    = SHA384h;
+                            digestSz = SHA384_DIGEST_SIZE;
+                            didSet   = 1;
+                        #endif
+                    }
+                    else if (ssl->suites->hashAlgo == sha512_mac) {
+                        #ifdef WOLFSSL_SHA512
+                            digest   = ssl->hsHashes->certHashes.sha512;
+                            typeH    = SHA512h;
+                            digestSz = SHA512_DIGEST_SIZE;
+                            didSet   = 1;
+                        #endif
+                    }
+
+                    if (didSet == 0) {
+                        /* defaults */
+                        #ifndef NO_OLD_TLS
+                            digest = ssl->hsHashes->certHashes.sha;
+                            digestSz = SHA_DIGEST_SIZE;
+                            typeH = SHAh;
+                        #else
+                            digest = ssl->hsHashes->certHashes.sha256;
+                            digestSz = SHA256_DIGEST_SIZE;
+                            typeH = SHA256h;
+                        #endif
+                    }
+
+                    signSz = wc_EncodeSignature(encodedSig, digest,digestSz,typeH);
+                    signBuffer = encodedSig;
+                }
+
+                c16toa((word16)length, verify + extraSz); /* prepend hdr */
+                if (doUserRsa) {
+                #ifdef HAVE_PK_CALLBACKS
+                    #ifndef NO_RSA
+                        word32 ioLen = ENCRYPT_LEN;
+                        ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
+                                            verify + extraSz + VERIFY_HEADER,
+                                            &ioLen,
+                                            ssl->buffers.key.buffer,
+                                            ssl->buffers.key.length,
+                                            ssl->RsaSignCtx);
+                    #endif /* NO_RSA */
+                #endif /*HAVE_PK_CALLBACKS */
+                }
+                else {
+                    ret = wc_RsaSSL_Sign(signBuffer, signSz, verify + extraSz +
+                                  VERIFY_HEADER, ENCRYPT_LEN, &key, ssl->rng);
+                }
+
+                if (ret > 0) {
+                    /* check for signature faults */
+                    ret = VerifyRsaSign(verify + extraSz + VERIFY_HEADER, ret,
+                                        signBuffer, signSz, &key);
+                }
+            }
+#endif
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+            if (ret == 0) {
+                AddHeaders(output, length + extraSz + VERIFY_HEADER,
+                           certificate_verify, ssl);
+
+                sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length +
+                         extraSz + VERIFY_HEADER;
+
+                #ifdef WOLFSSL_DTLS
+                    if (ssl->options.dtls) {
+                        sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                    }
+                #endif
+
+                if (ssl->keys.encryptionOn) {
+                    byte* input;
+                    int   inputSz = sendSz - RECORD_HEADER_SZ;
+                                    /* build msg adds rec hdr */
+                    input = (byte*)XMALLOC(inputSz, ssl->heap,
+                                           DYNAMIC_TYPE_TMP_BUFFER);
+                    if (input == NULL)
+                        ret = MEMORY_E;
+                    else {
+                        XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
+                        sendSz = BuildMessage(ssl, output,
+                                              MAX_CERT_VERIFY_SZ +MAX_MSG_EXTRA,
+                                              input, inputSz, handshake);
+                        XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
+
+                        if (sendSz < 0)
+                            ret = sendSz;
+                    }
+                } else {
+                    ret = HashOutput(ssl, output, sendSz, 0);
+                }
+
+                #ifdef WOLFSSL_DTLS
+                    if (ssl->options.dtls) {
+                        if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
+                            return ret;
+                    }
+                #endif
+            }
+        }
+#ifndef NO_RSA
+        if (initRsaKey)
+            wc_FreeRsaKey(&key);
+#endif
+#ifdef HAVE_ECC
+        wc_ecc_free(&eccKey);
+#endif
+
+        if (ret == 0) {
+            #ifdef WOLFSSL_CALLBACKS
+                if (ssl->hsInfoOn)
+                    AddPacketName("CertificateVerify", &ssl->handShakeInfo);
+                if (ssl->toInfoOn)
+                    AddPacketInfo("CertificateVerify", &ssl->timeoutInfo,
+                                  output, sendSz, ssl->heap);
+            #endif
+            ssl->buffers.outputBuffer.length += sendSz;
+            if (ssl->options.groupMessages)
+                return 0;
+            else
+                return SendBuffered(ssl);
+        }
+        else
+            return ret;
+    }
+#endif /* NO_CERTS */
+
+#ifdef HAVE_SESSION_TICKET
+int DoSessionTicket(WOLFSSL* ssl,
+                               const byte* input, word32* inOutIdx, word32 size)
+{
+    word32 begin = *inOutIdx;
+    word32 lifetime;
+    word16 length;
+
+    if (ssl->expect_session_ticket == 0) {
+        WOLFSSL_MSG("Unexpected session ticket");
+        return SESSION_TICKET_EXPECT_E;
+    }
+
+    if ((*inOutIdx - begin) + OPAQUE32_LEN > size)
+        return BUFFER_ERROR;
+
+    ato32(input + *inOutIdx, &lifetime);
+    *inOutIdx += OPAQUE32_LEN;
+
+    if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+        return BUFFER_ERROR;
+
+    ato16(input + *inOutIdx, &length);
+    *inOutIdx += OPAQUE16_LEN;
+
+    if (length > sizeof(ssl->session.ticket))
+        return SESSION_TICKET_LEN_E;
+
+    if ((*inOutIdx - begin) + length > size)
+        return BUFFER_ERROR;
+
+    /* If the received ticket including its length is greater than
+     * a length value, the save it. Otherwise, don't save it. */
+    if (length > 0) {
+        XMEMCPY(ssl->session.ticket, input + *inOutIdx, length);
+        *inOutIdx += length;
+        ssl->session.ticketLen = length;
+        ssl->timeout = lifetime;
+        if (ssl->session_ticket_cb != NULL) {
+            ssl->session_ticket_cb(ssl,
+                                   ssl->session.ticket, ssl->session.ticketLen,
+                                   ssl->session_ticket_ctx);
+        }
+        /* Create a fake sessionID based on the ticket, this will
+         * supercede the existing session cache info. */
+        ssl->options.haveSessionId = 1;
+        XMEMCPY(ssl->arrays->sessionID,
+                                 ssl->session.ticket + length - ID_LEN, ID_LEN);
+#ifndef NO_SESSION_CACHE
+        AddSession(ssl);
+#endif
+
+    }
+    else {
+        ssl->session.ticketLen = 0;
+    }
+
+    if (ssl->keys.encryptionOn) {
+        *inOutIdx += ssl->keys.padSz;
+    }
+
+    ssl->expect_session_ticket = 0;
+
+    return 0;
+}
+#endif /* HAVE_SESSION_TICKET */
+
+#endif /* NO_WOLFSSL_CLIENT */
+
+
+#ifndef NO_WOLFSSL_SERVER
+
+    int SendServerHello(WOLFSSL* ssl)
+    {
+        byte              *output;
+        word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+        int                sendSz;
+        int                ret;
+        byte               sessIdSz = ID_LEN;
+
+        length = VERSION_SZ + RAN_LEN
+               + ID_LEN + ENUM_LEN
+               + SUITE_LEN
+               + ENUM_LEN;
+
+#ifdef HAVE_TLS_EXTENSIONS
+        length += TLSX_GetResponseSize(ssl);
+    #ifdef HAVE_SESSION_TICKET
+        if (ssl->options.useTicket && ssl->arrays->sessionIDSz == 0) {
+            /* no session id */
+            length  -= ID_LEN;
+            sessIdSz = 0;
+        }
+    #endif /* HAVE_SESSION_TICKET */
+#endif
+
+        /* check for avalaible size */
+        if ((ret = CheckAvailableSize(ssl, MAX_HELLO_SZ)) != 0)
+            return ret;
+
+        /* get ouput buffer */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+        AddHeaders(output, length, server_hello, ssl);
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+            }
+        #endif
+        /* now write to output */
+            /* first version */
+        output[idx++] = ssl->version.major;
+        output[idx++] = ssl->version.minor;
+
+            /* then random */
+        if (!ssl->options.resuming) {
+            ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
+                                                                       RAN_LEN);
+            if (ret != 0)
+                return ret;
+        }
+
+        XMEMCPY(output + idx, ssl->arrays->serverRandom, RAN_LEN);
+        idx += RAN_LEN;
+
+#ifdef SHOW_SECRETS
+        {
+            int j;
+            printf("server random: ");
+            for (j = 0; j < RAN_LEN; j++)
+                printf("%02x", ssl->arrays->serverRandom[j]);
+            printf("\n");
+        }
+#endif
+            /* then session id */
+        output[idx++] = sessIdSz;
+        if (sessIdSz) {
+
+            if (!ssl->options.resuming) {
+                ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->sessionID,
+                                           sessIdSz);
+                if (ret != 0) return ret;
+            }
+
+            XMEMCPY(output + idx, ssl->arrays->sessionID, sessIdSz);
+            idx += sessIdSz;
+        }
+
+            /* then cipher suite */
+        output[idx++] = ssl->options.cipherSuite0;
+        output[idx++] = ssl->options.cipherSuite;
+
+            /* then compression */
+        if (ssl->options.usingCompression)
+            output[idx++] = ZLIB_COMPRESSION;
+        else
+            output[idx++] = NO_COMPRESSION;
+
+            /* last, extensions */
+#ifdef HAVE_TLS_EXTENSIONS
+        TLSX_WriteResponse(ssl, output + idx);
+#endif
+
+        ssl->buffers.outputBuffer.length += sendSz;
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
+                    return ret;
+            }
+        #endif
+
+        ret = HashOutput(ssl, output, sendSz, 0);
+        if (ret != 0)
+            return ret;
+
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName("ServerHello", &ssl->handShakeInfo);
+            if (ssl->toInfoOn)
+                AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz,
+                              ssl->heap);
+        #endif
+
+        ssl->options.serverState = SERVER_HELLO_COMPLETE;
+
+        if (ssl->options.groupMessages)
+            return 0;
+        else
+            return SendBuffered(ssl);
+    }
+
+
+#ifdef HAVE_ECC
+
+    static byte SetCurveId(int size)
+    {
+        switch(size) {
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
+            case 20:
+                return WOLFSSL_ECC_SECP160R1;
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
+            case 24:
+                return WOLFSSL_ECC_SECP192R1;
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
+            case 28:
+                return WOLFSSL_ECC_SECP224R1;
+#endif
+#if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
+            case 32:
+                return WOLFSSL_ECC_SECP256R1;
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
+            case 48:
+                return WOLFSSL_ECC_SECP384R1;
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
+            case 66:
+                return WOLFSSL_ECC_SECP521R1;
+#endif
+            default:
+                return 0;
+        }
+    }
+
+#endif /* HAVE_ECC */
+
+
+    int SendServerKeyExchange(WOLFSSL* ssl)
+    {
+        int ret = 0;
+        (void)ssl;
+        #define ERROR_OUT(err, eLabel) do { ret = err; goto eLabel; } while(0)
+
+    #ifdef HAVE_QSH
+        word32 qshSz = 0;
+        if (ssl->peerQSHKeyPresent && ssl->options.haveQSH) {
+            qshSz = QSH_KeyGetSize(ssl);
+        }
+    #endif
+
+
+    #ifndef NO_PSK
+        if (ssl->specs.kea == psk_kea)
+        {
+            byte    *output;
+            word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+            int      sendSz;
+            if (ssl->arrays->server_hint[0] == 0) return 0; /* don't send */
+
+            /* include size part */
+            length = (word32)XSTRLEN(ssl->arrays->server_hint);
+            if (length > MAX_PSK_ID_LEN)
+                return SERVER_HINT_ERROR;
+
+            length += HINT_LEN_SZ;
+            sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+
+        #ifdef HAVE_QSH
+            length += qshSz;
+            sendSz += qshSz;
+        #endif
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+            }
+        #endif
+            /* check for available size */
+            if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+               return ret;
+
+            /* get ouput buffer */
+            output = ssl->buffers.outputBuffer.buffer +
+                     ssl->buffers.outputBuffer.length;
+
+            AddHeaders(output, length, server_key_exchange, ssl);
+
+            /* key data */
+        #ifdef HAVE_QSH
+            c16toa((word16)(length - qshSz - HINT_LEN_SZ), output + idx);
+        #else
+            c16toa((word16)(length - HINT_LEN_SZ), output + idx);
+        #endif
+            idx += HINT_LEN_SZ;
+            XMEMCPY(output + idx, ssl->arrays->server_hint,length -HINT_LEN_SZ);
+
+        #ifdef HAVE_QSH
+            if (ssl->peerQSHKeyPresent) {
+                if (qshSz > 0) {
+                    idx = sendSz - qshSz;
+                    if (QSH_KeyExchangeWrite(ssl, 1) != 0)
+                        return MEMORY_E;
+
+                    /* extension type */
+                    c16toa(WOLFSSL_QSH, output + idx);
+                    idx += OPAQUE16_LEN;
+
+                    /* write to output and check amount written */
+                    if (TLSX_QSHPK_Write(ssl->QSH_secret->list, output + idx)
+                                                         > qshSz - OPAQUE16_LEN)
+                        return MEMORY_E;
+                }
+            }
+        #endif
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls)
+                if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
+                    return ret;
+        #endif
+
+            ret = HashOutput(ssl, output, sendSz, 0);
+            if (ret != 0)
+                return ret;
+
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
+            if (ssl->toInfoOn)
+                AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, output,
+                                                             sendSz, ssl->heap);
+        #endif
+
+            ssl->buffers.outputBuffer.length += sendSz;
+            if (ssl->options.groupMessages)
+                ret = 0;
+            else
+                ret = SendBuffered(ssl);
+            ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
+        }
+    #endif /*NO_PSK */
+
+    #if !defined(NO_DH) && !defined(NO_PSK)
+        if (ssl->specs.kea == dhe_psk_kea) {
+            byte    *output;
+            word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+            word32   hintLen;
+            int      sendSz;
+            DhKey    dhKey;
+
+            if (ssl->buffers.serverDH_P.buffer == NULL ||
+                ssl->buffers.serverDH_G.buffer == NULL)
+                return NO_DH_PARAMS;
+
+            if (ssl->buffers.serverDH_Pub.buffer == NULL) {
+                ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
+                        ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
+                        DYNAMIC_TYPE_DH);
+                if (ssl->buffers.serverDH_Pub.buffer == NULL)
+                    return MEMORY_E;
+            }
+
+            if (ssl->buffers.serverDH_Priv.buffer == NULL) {
+                ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
+                        ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
+                        DYNAMIC_TYPE_DH);
+                if (ssl->buffers.serverDH_Priv.buffer == NULL)
+                    return MEMORY_E;
+            }
+
+            wc_InitDhKey(&dhKey);
+            ret = wc_DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
+                                   ssl->buffers.serverDH_P.length,
+                                   ssl->buffers.serverDH_G.buffer,
+                                   ssl->buffers.serverDH_G.length);
+            if (ret == 0)
+                ret = wc_DhGenerateKeyPair(&dhKey, ssl->rng,
+                                         ssl->buffers.serverDH_Priv.buffer,
+                                        &ssl->buffers.serverDH_Priv.length,
+                                         ssl->buffers.serverDH_Pub.buffer,
+                                        &ssl->buffers.serverDH_Pub.length);
+            wc_FreeDhKey(&dhKey);
+            if (ret != 0)
+                return ret;
+
+            length = LENGTH_SZ * 3 + /* p, g, pub */
+                     ssl->buffers.serverDH_P.length +
+                     ssl->buffers.serverDH_G.length +
+                     ssl->buffers.serverDH_Pub.length;
+
+            /* include size part */
+            hintLen = (word32)XSTRLEN(ssl->arrays->server_hint);
+            if (hintLen > MAX_PSK_ID_LEN)
+                return SERVER_HINT_ERROR;
+            length += hintLen + HINT_LEN_SZ;
+            sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+
+        #ifdef HAVE_QSH
+            length += qshSz;
+            sendSz += qshSz;
+        #endif
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+            }
+        #endif
+
+            /* check for available size */
+            if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+               return ret;
+
+            /* get ouput buffer */
+            output = ssl->buffers.outputBuffer.buffer +
+                     ssl->buffers.outputBuffer.length;
+
+            AddHeaders(output, length, server_key_exchange, ssl);
+
+            /* key data */
+            c16toa((word16)hintLen, output + idx);
+            idx += HINT_LEN_SZ;
+            XMEMCPY(output + idx, ssl->arrays->server_hint, hintLen);
+            idx += hintLen;
+
+            /* add p, g, pub */
+            c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
+            idx += LENGTH_SZ;
+            XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
+                                  ssl->buffers.serverDH_P.length);
+            idx += ssl->buffers.serverDH_P.length;
+
+            /*  g */
+            c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
+            idx += LENGTH_SZ;
+            XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
+                                  ssl->buffers.serverDH_G.length);
+            idx += ssl->buffers.serverDH_G.length;
+
+            /*  pub */
+            c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
+            idx += LENGTH_SZ;
+            XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
+                                  ssl->buffers.serverDH_Pub.length);
+            idx += ssl->buffers.serverDH_Pub.length;
+            (void)idx; /* suppress analyzer warning, and keep idx current */
+
+        #ifdef HAVE_QSH
+            if (ssl->peerQSHKeyPresent) {
+                if (qshSz > 0) {
+                    idx = sendSz - qshSz;
+                    QSH_KeyExchangeWrite(ssl, 1);
+
+                    /* extension type */
+                    c16toa(WOLFSSL_QSH, output + idx);
+                    idx += OPAQUE16_LEN;
+
+                    /* write to output and check amount written */
+                    if (TLSX_QSHPK_Write(ssl->QSH_secret->list, output + idx)
+                                                         > qshSz - OPAQUE16_LEN)
+                        return MEMORY_E;
+                }
+            }
+        #endif
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls)
+                if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
+                    return ret;
+        #endif
+
+            ret = HashOutput(ssl, output, sendSz, 0);
+
+            if (ret != 0)
+                return ret;
+
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
+            if (ssl->toInfoOn)
+                AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, output,
+                                                             sendSz, ssl->heap);
+        #endif
+
+            ssl->buffers.outputBuffer.length += sendSz;
+            if (ssl->options.groupMessages)
+                ret = 0;
+            else
+                ret = SendBuffered(ssl);
+            ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
+        }
+    #endif /* !NO_DH && !NO_PSK */
+
+    #ifdef HAVE_ECC
+        if (ssl->specs.kea == ecc_diffie_hellman_kea)
+        {
+            byte    *output;
+            word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+            int      sendSz;
+            word32   sigSz;
+            word32   preSigSz, preSigIdx;
+        #ifndef NO_RSA
+            RsaKey   rsaKey;
+        #endif
+            ecc_key  dsaKey;
+        #ifdef WOLFSSL_SMALL_STACK
+            byte*    exportBuf = NULL;
+        #else
+            byte     exportBuf[MAX_EXPORT_ECC_SZ];
+        #endif
+            word32   expSz = MAX_EXPORT_ECC_SZ;
+
+        #ifndef NO_OLD_TLS
+            byte doMd5 = 0;
+            byte doSha = 0;
+        #endif
+        #ifndef NO_SHA256
+            byte doSha256 = 0;
+        #endif
+        #ifdef WOLFSSL_SHA384
+            byte doSha384 = 0;
+        #endif
+        #ifdef WOLFSSL_SHA512
+            byte doSha512 = 0;
+        #endif
+
+            if (ssl->specs.static_ecdh) {
+                WOLFSSL_MSG("Using Static ECDH, not sending ServerKeyExchagne");
+                return 0;
+            }
+
+            /* curve type, named curve, length(1) */
+            length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
+            /* pub key size */
+            WOLFSSL_MSG("Using ephemeral ECDH");
+
+            /* need ephemeral key now, create it if missing */
+            if (ssl->eccTempKey == NULL) {
+                /* alloc/init on demand */
+                ssl->eccTempKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
+                                              ssl->ctx->heap, DYNAMIC_TYPE_ECC);
+                if (ssl->eccTempKey == NULL) {
+                    WOLFSSL_MSG("EccTempKey Memory error");
+                    return MEMORY_E;
+                }
+                wc_ecc_init(ssl->eccTempKey);
+            }
+            if (ssl->eccTempKeyPresent == 0) {
+                if (wc_ecc_make_key(ssl->rng, ssl->eccTempKeySz,
+                                 ssl->eccTempKey) != 0) {
+                    return ECC_MAKEKEY_ERROR;
+                }
+                ssl->eccTempKeyPresent = 1;
+            }
+
+        #ifdef WOLFSSL_SMALL_STACK
+            exportBuf = (byte*)XMALLOC(MAX_EXPORT_ECC_SZ, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            if (exportBuf == NULL)
+                return MEMORY_E;
+        #endif
+
+            if (wc_ecc_export_x963(ssl->eccTempKey, exportBuf, &expSz) != 0)
+                ERROR_OUT(ECC_EXPORT_ERROR, done_a);
+            length += expSz;
+
+            preSigSz  = length;
+            preSigIdx = idx;
+
+        #ifndef NO_RSA
+            ret = wc_InitRsaKey(&rsaKey, ssl->heap);
+            if (ret != 0)
+                goto done_a;
+        #endif
+
+            wc_ecc_init(&dsaKey);
+
+            /* sig length */
+            length += LENGTH_SZ;
+
+            if (!ssl->buffers.key.buffer) {
+            #ifndef NO_RSA
+                wc_FreeRsaKey(&rsaKey);
+            #endif
+                wc_ecc_free(&dsaKey);
+                ERROR_OUT(NO_PRIVATE_KEY, done_a);
+            }
+
+        #ifndef NO_RSA
+            if (ssl->specs.sig_algo == rsa_sa_algo) {
+                /* rsa sig size */
+                word32 i = 0;
+                ret = wc_RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i,
+                                          &rsaKey, ssl->buffers.key.length);
+                if (ret != 0)
+                    goto done_a;
+                sigSz = wc_RsaEncryptSize(&rsaKey);
+            } else
+        #endif
+
+            if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
+                /* ecdsa sig size */
+                word32 i = 0;
+                ret = wc_EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
+                                          &dsaKey, ssl->buffers.key.length);
+                if (ret != 0)
+                    goto done_a;
+                sigSz = wc_ecc_sig_size(&dsaKey);  /* worst case estimate */
+            }
+            else {
+            #ifndef NO_RSA
+                wc_FreeRsaKey(&rsaKey);
+            #endif
+                wc_ecc_free(&dsaKey);
+                ERROR_OUT(ALGO_ID_E, done_a);  /* unsupported type */
+            }
+            length += sigSz;
+
+            if (IsAtLeastTLSv1_2(ssl))
+                length += HASH_SIG_SIZE;
+
+            sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+
+        #ifdef HAVE_QSH
+            length += qshSz;
+            sendSz += qshSz;
+        #endif
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                preSigIdx = idx;
+            }
+        #endif
+            /* check for available size */
+            if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
+            #ifndef NO_RSA
+                wc_FreeRsaKey(&rsaKey);
+            #endif
+                wc_ecc_free(&dsaKey);
+                goto done_a;
+            }
+
+            /* get ouput buffer */
+            output = ssl->buffers.outputBuffer.buffer +
+                     ssl->buffers.outputBuffer.length;
+
+            /* record and message headers will be added below, when we're sure
+               of the sig length */
+
+            /* key exchange data */
+            output[idx++] = named_curve;
+            output[idx++] = 0x00;          /* leading zero */
+            output[idx++] = SetCurveId(wc_ecc_size(ssl->eccTempKey));
+            output[idx++] = (byte)expSz;
+            XMEMCPY(output + idx, exportBuf, expSz);
+            idx += expSz;
+            if (IsAtLeastTLSv1_2(ssl)) {
+                byte setHash = 0;
+
+                output[idx++] = ssl->suites->hashAlgo;
+                output[idx++] = ssl->suites->sigAlgo;
+
+                switch (ssl->suites->hashAlgo) {
+                    case sha512_mac:
+                        #ifdef WOLFSSL_SHA512
+                            doSha512 = 1;
+                            setHash  = 1;
+                        #endif
+                        break;
+
+                    case sha384_mac:
+                        #ifdef WOLFSSL_SHA384
+                            doSha384 = 1;
+                            setHash  = 1;
+                        #endif
+                        break;
+
+                    case sha256_mac:
+                        #ifndef NO_SHA256
+                            doSha256 = 1;
+                            setHash  = 1;
+                        #endif
+                        break;
+
+                    case sha_mac:
+                        #ifndef NO_OLD_TLS
+                            doSha = 1;
+                            setHash  = 1;
+                        #endif
+                        break;
+
+                    default:
+                        WOLFSSL_MSG("Bad hash sig algo");
+                        break;
+                }
+
+                if (setHash == 0) {
+                    #ifndef NO_RSA
+                        wc_FreeRsaKey(&rsaKey);
+                    #endif
+                    wc_ecc_free(&dsaKey);
+                    ERROR_OUT(ALGO_ID_E, done_a);
+                }
+            } else {
+                /* only using sha and md5 for rsa */
+                #ifndef NO_OLD_TLS
+                    doSha = 1;
+                    if (ssl->suites->sigAlgo == rsa_sa_algo) {
+                        doMd5 = 1;
+                    }
+                #else
+                    #ifndef NO_RSA
+                        wc_FreeRsaKey(&rsaKey);
+                    #endif
+                    wc_ecc_free(&dsaKey);
+                    ERROR_OUT(ALGO_ID_E, done_a);
+                #endif
+            }
+
+            /* Signtaure length will be written later, when we're sure what it
+               is */
+
+        #ifdef HAVE_FUZZER
+            if (ssl->fuzzerCb)
+                ssl->fuzzerCb(ssl, output + preSigIdx, preSigSz, FUZZ_SIGNATURE,
+                              ssl->fuzzerCtx);
+        #endif
+
+            /* do signature */
+            {
+        #ifndef NO_OLD_TLS
+            #ifdef WOLFSSL_SMALL_STACK
+                Md5*   md5  = NULL;
+                Sha*   sha  = NULL;
+            #else
+                Md5    md5[1];
+                Sha    sha[1];
+            #endif
+        #endif
+            #ifdef WOLFSSL_SMALL_STACK
+                byte*  hash = NULL;
+            #else
+                byte   hash[FINISHED_SZ];
+            #endif
+        #ifndef NO_SHA256
+            #ifdef WOLFSSL_SMALL_STACK
+                Sha256* sha256  = NULL;
+                byte*   hash256 = NULL;
+            #else
+                Sha256  sha256[1];
+                byte    hash256[SHA256_DIGEST_SIZE];
+            #endif
+        #endif
+        #ifdef WOLFSSL_SHA384
+            #ifdef WOLFSSL_SMALL_STACK
+                Sha384* sha384  = NULL;
+                byte*   hash384 = NULL;
+            #else
+                Sha384  sha384[1];
+                byte    hash384[SHA384_DIGEST_SIZE];
+            #endif
+        #endif
+        #ifdef WOLFSSL_SHA512
+            #ifdef WOLFSSL_SMALL_STACK
+                Sha512* sha512  = NULL;
+                byte*   hash512 = NULL;
+            #else
+                Sha512  sha512[1];
+                byte    hash512[SHA512_DIGEST_SIZE];
+            #endif
+        #endif
+
+            #ifdef WOLFSSL_SMALL_STACK
+                hash = (byte*)XMALLOC(FINISHED_SZ, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                if (hash == NULL)
+                    ERROR_OUT(MEMORY_E, done_a);
+            #endif
+
+        #ifndef NO_OLD_TLS
+                /* md5 */
+            #ifdef WOLFSSL_SMALL_STACK
+                if (doMd5) {
+                    md5 = (Md5*)XMALLOC(sizeof(Md5), NULL,
+                                        DYNAMIC_TYPE_TMP_BUFFER);
+                    if (md5 == NULL)
+                        ERROR_OUT(MEMORY_E, done_a2);
+                }
+            #endif
+                if (doMd5) {
+                    wc_InitMd5(md5);
+                    wc_Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
+                    wc_Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
+                    wc_Md5Update(md5, output + preSigIdx, preSigSz);
+                    wc_Md5Final(md5, hash);
+                }
+                /* sha */
+            #ifdef WOLFSSL_SMALL_STACK
+                if (doSha) {
+                    sha = (Sha*)XMALLOC(sizeof(Sha), NULL,
+                                        DYNAMIC_TYPE_TMP_BUFFER);
+                    if (sha == NULL)
+                        ERROR_OUT(MEMORY_E, done_a2);
+                }
+            #endif
+                if (doSha) {
+                    ret = wc_InitSha(sha);
+                    if (ret != 0) goto done_a2;
+                    wc_ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
+                    wc_ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
+                    wc_ShaUpdate(sha, output + preSigIdx, preSigSz);
+                    wc_ShaFinal(sha, &hash[MD5_DIGEST_SIZE]);
+                }
+        #endif
+
+        #ifndef NO_SHA256
+            #ifdef WOLFSSL_SMALL_STACK
+                if (doSha256) {
+                    sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
+                                              DYNAMIC_TYPE_TMP_BUFFER);
+                    hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
+                                             DYNAMIC_TYPE_TMP_BUFFER);
+                    if (sha256 == NULL || hash256 == NULL)
+                        ERROR_OUT(MEMORY_E, done_a2);
+                }
+            #endif
+
+                if (doSha256) {
+                    if (!(ret = wc_InitSha256(sha256))
+                    &&  !(ret = wc_Sha256Update(sha256,
+                                            ssl->arrays->clientRandom, RAN_LEN))
+                    &&  !(ret = wc_Sha256Update(sha256,
+                                            ssl->arrays->serverRandom, RAN_LEN))
+                    &&  !(ret = wc_Sha256Update(sha256,
+                                            output + preSigIdx, preSigSz)))
+                        ret = wc_Sha256Final(sha256, hash256);
+
+                    if (ret != 0) goto done_a2;
+                }
+        #endif
+
+        #ifdef WOLFSSL_SHA384
+            #ifdef WOLFSSL_SMALL_STACK
+                if (doSha384) {
+                    sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
+                                              DYNAMIC_TYPE_TMP_BUFFER);
+                    hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
+                                             DYNAMIC_TYPE_TMP_BUFFER);
+                    if (sha384 == NULL || hash384 == NULL)
+                        ERROR_OUT(MEMORY_E, done_a2);
+                }
+            #endif
+
+                if (doSha384) {
+                    if (!(ret = wc_InitSha384(sha384))
+                    &&  !(ret = wc_Sha384Update(sha384,
+                                            ssl->arrays->clientRandom, RAN_LEN))
+                    &&  !(ret = wc_Sha384Update(sha384,
+                                            ssl->arrays->serverRandom, RAN_LEN))
+                    &&  !(ret = wc_Sha384Update(sha384,
+                                            output + preSigIdx, preSigSz)))
+                        ret = wc_Sha384Final(sha384, hash384);
+
+                    if (ret != 0) goto done_a2;
+                }
+        #endif
+
+        #ifdef WOLFSSL_SHA512
+            #ifdef WOLFSSL_SMALL_STACK
+                if (doSha512) {
+                    sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL,
+                                              DYNAMIC_TYPE_TMP_BUFFER);
+                    hash512 = (byte*)XMALLOC(SHA512_DIGEST_SIZE, NULL,
+                                             DYNAMIC_TYPE_TMP_BUFFER);
+                    if (sha512 == NULL || hash512 == NULL)
+                        ERROR_OUT(MEMORY_E, done_a2);
+                }
+            #endif
+
+                if (doSha512) {
+                    if (!(ret = wc_InitSha512(sha512))
+                    &&  !(ret = wc_Sha512Update(sha512,
+                                            ssl->arrays->clientRandom, RAN_LEN))
+                    &&  !(ret = wc_Sha512Update(sha512,
+                                            ssl->arrays->serverRandom, RAN_LEN))
+                    &&  !(ret = wc_Sha512Update(sha512,
+                                            output + preSigIdx, preSigSz)))
+                        ret = wc_Sha512Final(sha512, hash512);
+
+                    if (ret != 0) goto done_a2;
+                }
+        #endif
+
+            #ifndef NO_RSA
+                if (ssl->suites->sigAlgo == rsa_sa_algo) {
+                    byte*  signBuffer = hash;
+                    word32 signSz     = FINISHED_SZ;
+                    byte   doUserRsa = 0;
+                #ifdef WOLFSSL_SMALL_STACK
+                    byte*  encodedSig = NULL;
+                #else
+                    byte   encodedSig[MAX_ENCODED_SIG_SZ];
+                #endif
+
+                #ifdef HAVE_PK_CALLBACKS
+                    if (ssl->ctx->RsaSignCb)
+                        doUserRsa = 1;
+                #endif
+
+                #ifdef WOLFSSL_SMALL_STACK
+                    encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                    if (encodedSig == NULL)
+                        ERROR_OUT(MEMORY_E, done_a2);
+                #endif
+
+                    if (IsAtLeastTLSv1_2(ssl)) {
+                        byte* digest   = &hash[MD5_DIGEST_SIZE];
+                        int   typeH    = SHAh;
+                        int   digestSz = SHA_DIGEST_SIZE;
+
+                        if (ssl->suites->hashAlgo == sha256_mac) {
+                        #ifndef NO_SHA256
+                            digest   = hash256;
+                            typeH    = SHA256h;
+                            digestSz = SHA256_DIGEST_SIZE;
+                        #endif
+                        }
+                        else if (ssl->suites->hashAlgo == sha384_mac) {
+                        #ifdef WOLFSSL_SHA384
+                            digest   = hash384;
+                            typeH    = SHA384h;
+                            digestSz = SHA384_DIGEST_SIZE;
+                        #endif
+                        }
+                        else if (ssl->suites->hashAlgo == sha512_mac) {
+                        #ifdef WOLFSSL_SHA512
+                            digest   = hash512;
+                            typeH    = SHA512h;
+                            digestSz = SHA512_DIGEST_SIZE;
+                        #endif
+                        }
+
+                        if (digest == NULL) {
+                            #ifndef NO_RSA
+                                wc_FreeRsaKey(&rsaKey);
+                            #endif
+                            wc_ecc_free(&dsaKey);
+                            ERROR_OUT(ALGO_ID_E, done_a2);
+                        }
+                        signSz = wc_EncodeSignature(encodedSig, digest,
+                                                    digestSz, typeH);
+                        signBuffer = encodedSig;
+                    }
+                    /* write sig size here */
+                    c16toa((word16)sigSz, output + idx);
+                    idx += LENGTH_SZ;
+
+                    if (doUserRsa) {
+                    #ifdef HAVE_PK_CALLBACKS
+                        word32 ioLen = sigSz;
+                        ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
+                                            output + idx, &ioLen,
+                                            ssl->buffers.key.buffer,
+                                            ssl->buffers.key.length,
+                                            ssl->RsaSignCtx);
+                    #endif /*HAVE_PK_CALLBACKS */
+                    }
+                    else {
+                        ret = wc_RsaSSL_Sign(signBuffer, signSz, output + idx,
+                                          sigSz, &rsaKey, ssl->rng);
+                    }
+
+                    if (ret > 0) {
+                        /* check for signature faults */
+                        ret = VerifyRsaSign(output + idx, ret,
+                                            signBuffer, signSz, &rsaKey);
+                    }
+                    wc_FreeRsaKey(&rsaKey);
+                    wc_ecc_free(&dsaKey);
+
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                #endif
+
+                    if (ret < 0)
+                        goto done_a2;
+                } else
+            #endif
+
+                if (ssl->suites->sigAlgo == ecc_dsa_sa_algo) {
+                #ifndef NO_OLD_TLS
+                    byte* digest = &hash[MD5_DIGEST_SIZE];
+                    word32 digestSz = SHA_DIGEST_SIZE;
+                #else
+                    byte* digest = hash256;
+                    word32 digestSz = SHA256_DIGEST_SIZE;
+                #endif
+                    word32 sz = sigSz;
+                    byte   doUserEcc = 0;
+
+                #if defined(HAVE_PK_CALLBACKS) && defined(HAVE_ECC)
+                    if (ssl->ctx->EccSignCb)
+                        doUserEcc = 1;
+                #endif
+
+                    if (IsAtLeastTLSv1_2(ssl)) {
+                        if (ssl->suites->hashAlgo == sha_mac) {
+                        #ifndef NO_SHA
+                            digest   = &hash[MD5_DIGEST_SIZE];
+                            digestSz = SHA_DIGEST_SIZE;
+                        #endif
+                        }
+                        else if (ssl->suites->hashAlgo == sha256_mac) {
+                        #ifndef NO_SHA256
+                            digest   = hash256;
+                            digestSz = SHA256_DIGEST_SIZE;
+                        #endif
+                        }
+                        else if (ssl->suites->hashAlgo == sha384_mac) {
+                        #ifdef WOLFSSL_SHA384
+                            digest   = hash384;
+                            digestSz = SHA384_DIGEST_SIZE;
+                        #endif
+                        }
+                        else if (ssl->suites->hashAlgo == sha512_mac) {
+                        #ifdef WOLFSSL_SHA512
+                            digest   = hash512;
+                            digestSz = SHA512_DIGEST_SIZE;
+                        #endif
+                        }
+                    }
+
+                    if (doUserEcc) {
+                    #if defined(HAVE_PK_CALLBACKS) && defined(HAVE_ECC)
+                        ret = ssl->ctx->EccSignCb(ssl, digest, digestSz,
+                                                  output + LENGTH_SZ + idx, &sz,
+                                                  ssl->buffers.key.buffer,
+                                                  ssl->buffers.key.length,
+                                                  ssl->EccSignCtx);
+                    #endif
+                    }
+                    else {
+                        ret = wc_ecc_sign_hash(digest, digestSz,
+                              output + LENGTH_SZ + idx, &sz, ssl->rng, &dsaKey);
+                    }
+                #ifndef NO_RSA
+                    wc_FreeRsaKey(&rsaKey);
+                #endif
+                    wc_ecc_free(&dsaKey);
+
+                    if (ret < 0)
+                        goto done_a2;
+
+                    /* Now that we know the real sig size, write it. */
+                    c16toa((word16)sz, output + idx);
+
+                    /* And adjust length and sendSz from estimates */
+                    length += sz - sigSz;
+                    sendSz += sz - sigSz;
+                }
+
+            done_a2:
+        #ifdef WOLFSSL_SMALL_STACK
+            #ifndef NO_OLD_TLS
+                XFREE(md5,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(sha,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+                XFREE(hash,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #ifndef NO_SHA256
+                XFREE(sha256,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+            #ifdef WOLFSSL_SHA384
+                XFREE(sha384,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+            #ifdef WOLFSSL_SHA512
+                XFREE(sha512,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(hash512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+        #endif
+
+                if (ret < 0)
+                    goto done_a;
+            }
+
+#ifdef HAVE_QSH
+            if (ssl->peerQSHKeyPresent) {
+                if (qshSz > 0) {
+                    idx = sendSz - qshSz;
+                    QSH_KeyExchangeWrite(ssl, 1);
+
+                    /* extension type */
+                    c16toa(WOLFSSL_QSH, output + idx);
+                    idx += OPAQUE16_LEN;
+
+                    /* write to output and check amount written */
+                    if (TLSX_QSHPK_Write(ssl->QSH_secret->list, output + idx)
+                                                         > qshSz - OPAQUE16_LEN)
+                        return MEMORY_E;
+                }
+            }
+#endif
+
+
+            AddHeaders(output, length, server_key_exchange, ssl);
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls)
+                if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
+                    goto done_a;
+        #endif
+
+            if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0)
+                goto done_a;
+
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
+            if (ssl->toInfoOn)
+                AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
+                              output, sendSz, ssl->heap);
+        #endif
+
+            ssl->buffers.outputBuffer.length += sendSz;
+            if (ssl->options.groupMessages)
+                ret = 0;
+            else
+                ret = SendBuffered(ssl);
+            ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
+
+        done_a:
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(exportBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+
+            return ret;
+        }
+    #endif /* HAVE_ECC */
+
+    #if !defined(NO_DH) && !defined(NO_RSA)
+        if (ssl->specs.kea == diffie_hellman_kea) {
+            byte    *output;
+            word32   length = 0, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+            int      sendSz;
+            word32   sigSz = 0, i = 0;
+            word32   preSigSz = 0, preSigIdx = 0;
+            RsaKey   rsaKey;
+            DhKey    dhKey;
+
+            if (ssl->buffers.serverDH_P.buffer == NULL ||
+                ssl->buffers.serverDH_G.buffer == NULL)
+                return NO_DH_PARAMS;
+
+            if (ssl->buffers.serverDH_Pub.buffer == NULL) {
+                ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
+                        ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
+                        DYNAMIC_TYPE_DH);
+                if (ssl->buffers.serverDH_Pub.buffer == NULL)
+                    return MEMORY_E;
+            }
+
+            if (ssl->buffers.serverDH_Priv.buffer == NULL) {
+                ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
+                        ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
+                        DYNAMIC_TYPE_DH);
+                if (ssl->buffers.serverDH_Priv.buffer == NULL)
+                    return MEMORY_E;
+            }
+
+            wc_InitDhKey(&dhKey);
+            ret = wc_DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
+                                   ssl->buffers.serverDH_P.length,
+                                   ssl->buffers.serverDH_G.buffer,
+                                   ssl->buffers.serverDH_G.length);
+            if (ret == 0)
+                ret = wc_DhGenerateKeyPair(&dhKey, ssl->rng,
+                                         ssl->buffers.serverDH_Priv.buffer,
+                                        &ssl->buffers.serverDH_Priv.length,
+                                         ssl->buffers.serverDH_Pub.buffer,
+                                        &ssl->buffers.serverDH_Pub.length);
+            wc_FreeDhKey(&dhKey);
+
+            if (ret != 0) return ret;
+
+            length = LENGTH_SZ * 3;  /* p, g, pub */
+            length += ssl->buffers.serverDH_P.length +
+                      ssl->buffers.serverDH_G.length +
+                      ssl->buffers.serverDH_Pub.length;
+
+            preSigIdx = idx;
+            preSigSz  = length;
+
+            if (!ssl->options.usingAnon_cipher) {
+                ret = wc_InitRsaKey(&rsaKey, ssl->heap);
+                if (ret != 0) return ret;
+
+                /* sig length */
+                length += LENGTH_SZ;
+
+                if (!ssl->buffers.key.buffer)
+                    return NO_PRIVATE_KEY;
+
+                ret = wc_RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i, &rsaKey,
+                                          ssl->buffers.key.length);
+                if (ret == 0) {
+                    sigSz = wc_RsaEncryptSize(&rsaKey);
+                    length += sigSz;
+                }
+                else {
+                    wc_FreeRsaKey(&rsaKey);
+                    return ret;
+                }
+
+                if (IsAtLeastTLSv1_2(ssl))
+                    length += HASH_SIG_SIZE;
+            }
+
+            sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+
+        #ifdef HAVE_QSH
+            length += qshSz;
+            sendSz += qshSz;
+        #endif
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+                preSigIdx = idx;
+            }
+        #endif
+
+            /* check for available size */
+            if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
+                if (!ssl->options.usingAnon_cipher)
+                    wc_FreeRsaKey(&rsaKey);
+                return ret;
+            }
+
+            /* get ouput buffer */
+            output = ssl->buffers.outputBuffer.buffer +
+                     ssl->buffers.outputBuffer.length;
+
+            AddHeaders(output, length, server_key_exchange, ssl);
+
+            /* add p, g, pub */
+            c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
+            idx += LENGTH_SZ;
+            XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
+                                  ssl->buffers.serverDH_P.length);
+            idx += ssl->buffers.serverDH_P.length;
+
+            /*  g */
+            c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
+            idx += LENGTH_SZ;
+            XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
+                                  ssl->buffers.serverDH_G.length);
+            idx += ssl->buffers.serverDH_G.length;
+
+            /*  pub */
+            c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
+            idx += LENGTH_SZ;
+            XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
+                                  ssl->buffers.serverDH_Pub.length);
+            idx += ssl->buffers.serverDH_Pub.length;
+
+        #ifdef HAVE_FUZZER
+            if (ssl->fuzzerCb)
+                ssl->fuzzerCb(ssl, output + preSigIdx, preSigSz, FUZZ_SIGNATURE,
+                        ssl->fuzzerCtx);
+        #endif
+
+            /* Add signature */
+            if (!ssl->options.usingAnon_cipher) {
+        #ifndef NO_OLD_TLS
+            #ifdef WOLFSSL_SMALL_STACK
+                Md5*   md5  = NULL;
+                Sha*   sha  = NULL;
+            #else
+                Md5    md5[1];
+                Sha    sha[1];
+            #endif
+        #endif
+            #ifdef WOLFSSL_SMALL_STACK
+                byte*  hash = NULL;
+            #else
+                byte   hash[FINISHED_SZ];
+            #endif
+        #ifndef NO_SHA256
+            #ifdef WOLFSSL_SMALL_STACK
+                Sha256* sha256  = NULL;
+                byte*   hash256 = NULL;
+            #else
+                Sha256  sha256[1];
+                byte    hash256[SHA256_DIGEST_SIZE];
+            #endif
+        #endif
+        #ifdef WOLFSSL_SHA384
+            #ifdef WOLFSSL_SMALL_STACK
+                Sha384* sha384  = NULL;
+                byte*   hash384 = NULL;
+            #else
+                Sha384  sha384[1];
+                byte    hash384[SHA384_DIGEST_SIZE];
+            #endif
+        #endif
+        #ifdef WOLFSSL_SHA512
+            #ifdef WOLFSSL_SMALL_STACK
+                Sha512* sha512  = NULL;
+                byte*   hash512 = NULL;
+            #else
+                Sha512  sha512[1];
+                byte    hash512[SHA512_DIGEST_SIZE];
+            #endif
+        #endif
+
+        #ifndef NO_OLD_TLS
+            byte doMd5 = 0;
+            byte doSha = 0;
+        #endif
+        #ifndef NO_SHA256
+            byte doSha256 = 0;
+        #endif
+        #ifdef WOLFSSL_SHA384
+            byte doSha384 = 0;
+        #endif
+        #ifdef WOLFSSL_SHA512
+            byte doSha512 = 0;
+        #endif
+
+            /* Add hash/signature algo ID */
+            if (IsAtLeastTLSv1_2(ssl)) {
+                byte setHash = 0;
+
+                output[idx++] = ssl->suites->hashAlgo;
+                output[idx++] = ssl->suites->sigAlgo;
+
+                switch (ssl->suites->hashAlgo) {
+                    case sha512_mac:
+                        #ifdef WOLFSSL_SHA512
+                            doSha512 = 1;
+                            setHash  = 1;
+                        #endif
+                        break;
+
+                    case sha384_mac:
+                        #ifdef WOLFSSL_SHA384
+                            doSha384 = 1;
+                            setHash  = 1;
+                        #endif
+                        break;
+
+                    case sha256_mac:
+                        #ifndef NO_SHA256
+                            doSha256 = 1;
+                            setHash  = 1;
+                        #endif
+                        break;
+
+                    case sha_mac:
+                        #ifndef NO_OLD_TLS
+                            doSha = 1;
+                            setHash  = 1;
+                        #endif
+                        break;
+
+                    default:
+                        WOLFSSL_MSG("Bad hash sig algo");
+                        break;
+                }
+
+                if (setHash == 0) {
+                    wc_FreeRsaKey(&rsaKey);
+                    return ALGO_ID_E;
+                }
+            } else {
+                /* only using sha and md5 for rsa */
+                #ifndef NO_OLD_TLS
+                    doSha = 1;
+                    if (ssl->suites->sigAlgo == rsa_sa_algo) {
+                        doMd5 = 1;
+                    }
+                #else
+                    wc_FreeRsaKey(&rsaKey);
+                    return ALGO_ID_E;
+                #endif
+            }
+
+            /* signature size */
+            c16toa((word16)sigSz, output + idx);
+            idx += LENGTH_SZ;
+
+            /* do signature */
+            #ifdef WOLFSSL_SMALL_STACK
+                hash = (byte*)XMALLOC(FINISHED_SZ, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                if (hash == NULL)
+                    return MEMORY_E; /* No heap commitment before this point,
+                                        from now on, the resources are freed
+                                        at done_b. */
+            #endif
+
+        #ifndef NO_OLD_TLS
+                /* md5 */
+            #ifdef WOLFSSL_SMALL_STACK
+                if (doMd5) {
+                    md5 = (Md5*)XMALLOC(sizeof(Md5), NULL,
+                                        DYNAMIC_TYPE_TMP_BUFFER);
+                    if (md5 == NULL)
+                        ERROR_OUT(MEMORY_E, done_b);
+                }
+            #endif
+                if (doMd5) {
+                    wc_InitMd5(md5);
+                    wc_Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
+                    wc_Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
+                    wc_Md5Update(md5, output + preSigIdx, preSigSz);
+                    wc_Md5Final(md5, hash);
+                }
+
+                /* sha */
+            #ifdef WOLFSSL_SMALL_STACK
+                if (doSha) {
+                    sha = (Sha*)XMALLOC(sizeof(Sha), NULL,
+                                        DYNAMIC_TYPE_TMP_BUFFER);
+                    if (sha == NULL)
+                        ERROR_OUT(MEMORY_E, done_b);
+                }
+            #endif
+
+                if (doSha) {
+                    if ((ret = wc_InitSha(sha)) != 0)
+                        goto done_b;
+                    wc_ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
+                    wc_ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
+                    wc_ShaUpdate(sha, output + preSigIdx, preSigSz);
+                    wc_ShaFinal(sha, &hash[MD5_DIGEST_SIZE]);
+                }
+        #endif
+
+        #ifndef NO_SHA256
+            #ifdef WOLFSSL_SMALL_STACK
+                if (doSha256) {
+                    sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
+                                              DYNAMIC_TYPE_TMP_BUFFER);
+                    hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
+                                             DYNAMIC_TYPE_TMP_BUFFER);
+                    if (sha256 == NULL || hash256 == NULL)
+                        ERROR_OUT(MEMORY_E, done_b);
+                }
+            #endif
+
+                if (doSha256) {
+                    if (!(ret = wc_InitSha256(sha256))
+                    &&  !(ret = wc_Sha256Update(sha256,
+                                            ssl->arrays->clientRandom, RAN_LEN))
+                    &&  !(ret = wc_Sha256Update(sha256,
+                                            ssl->arrays->serverRandom, RAN_LEN))
+                    &&  !(ret = wc_Sha256Update(sha256,
+                                            output + preSigIdx, preSigSz)))
+                        ret = wc_Sha256Final(sha256, hash256);
+
+                    if (ret != 0) goto done_b;
+                }
+            #endif
+
+        #ifdef WOLFSSL_SHA384
+            #ifdef WOLFSSL_SMALL_STACK
+                if (doSha384) {
+                    sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
+                                              DYNAMIC_TYPE_TMP_BUFFER);
+                    hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
+                                             DYNAMIC_TYPE_TMP_BUFFER);
+                    if (sha384 == NULL || hash384 == NULL)
+                        ERROR_OUT(MEMORY_E, done_b);
+                }
+            #endif
+
+                if (doSha384) {
+                    if (!(ret = wc_InitSha384(sha384))
+                    &&  !(ret = wc_Sha384Update(sha384,
+                                            ssl->arrays->clientRandom, RAN_LEN))
+                    &&  !(ret = wc_Sha384Update(sha384,
+                                            ssl->arrays->serverRandom, RAN_LEN))
+                    &&  !(ret = wc_Sha384Update(sha384,
+                                            output + preSigIdx, preSigSz)))
+                        ret = wc_Sha384Final(sha384, hash384);
+
+                    if (ret != 0) goto done_b;
+                }
+        #endif
+
+        #ifdef WOLFSSL_SHA512
+            #ifdef WOLFSSL_SMALL_STACK
+                if (doSha512) {
+                    sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL,
+                                              DYNAMIC_TYPE_TMP_BUFFER);
+                    hash512 = (byte*)XMALLOC(SHA512_DIGEST_SIZE, NULL,
+                                             DYNAMIC_TYPE_TMP_BUFFER);
+                    if (sha512 == NULL || hash512 == NULL)
+                        ERROR_OUT(MEMORY_E, done_b);
+                }
+            #endif
+
+                if (doSha512) {
+                    if (!(ret = wc_InitSha512(sha512))
+                    &&  !(ret = wc_Sha512Update(sha512,
+                                            ssl->arrays->clientRandom, RAN_LEN))
+                    &&  !(ret = wc_Sha512Update(sha512,
+                                            ssl->arrays->serverRandom, RAN_LEN))
+                    &&  !(ret = wc_Sha512Update(sha512,
+                                            output + preSigIdx, preSigSz)))
+                        ret = wc_Sha512Final(sha512, hash512);
+
+                    if (ret != 0) goto done_b;
+                }
+        #endif
+
+            #ifndef NO_RSA
+                if (ssl->suites->sigAlgo == rsa_sa_algo) {
+                    byte*  signBuffer = hash;
+                    word32 signSz     = FINISHED_SZ;
+                #ifdef WOLFSSL_SMALL_STACK
+                    byte*  encodedSig = NULL;
+                #else
+                    byte   encodedSig[MAX_ENCODED_SIG_SZ];
+                #endif
+                    byte   doUserRsa = 0;
+
+                #ifdef HAVE_PK_CALLBACKS
+                    if (ssl->ctx->RsaSignCb)
+                        doUserRsa = 1;
+                #endif
+
+                #ifdef WOLFSSL_SMALL_STACK
+                    encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                    if (encodedSig == NULL)
+                        ERROR_OUT(MEMORY_E, done_b);
+                #endif
+
+                    if (IsAtLeastTLSv1_2(ssl)) {
+                        byte* digest   = &hash[MD5_DIGEST_SIZE];
+                        int   typeH    = SHAh;
+                        int   digestSz = SHA_DIGEST_SIZE;
+
+                        if (ssl->suites->hashAlgo == sha256_mac) {
+                        #ifndef NO_SHA256
+                            digest   = hash256;
+                            typeH    = SHA256h;
+                            digestSz = SHA256_DIGEST_SIZE;
+                        #endif
+                        }
+                        else if (ssl->suites->hashAlgo == sha384_mac) {
+                        #ifdef WOLFSSL_SHA384
+                            digest   = hash384;
+                            typeH    = SHA384h;
+                            digestSz = SHA384_DIGEST_SIZE;
+                        #endif
+                        }
+                        else if (ssl->suites->hashAlgo == sha512_mac) {
+                        #ifdef WOLFSSL_SHA512
+                            digest   = hash512;
+                            typeH    = SHA512h;
+                            digestSz = SHA512_DIGEST_SIZE;
+                        #endif
+                        }
+
+                        if (digest == NULL) {
+                            ret = ALGO_ID_E;
+                        } else {
+                            signSz = wc_EncodeSignature(encodedSig, digest,
+                                                        digestSz, typeH);
+                            signBuffer = encodedSig;
+                        }
+                    }
+                    if (doUserRsa && ret == 0) {
+                    #ifdef HAVE_PK_CALLBACKS
+                        word32 ioLen = sigSz;
+                        ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
+                                                  output + idx, &ioLen,
+                                                  ssl->buffers.key.buffer,
+                                                  ssl->buffers.key.length,
+                                                  ssl->RsaSignCtx);
+                    #endif
+                    } else if (ret == 0) {
+                        ret = wc_RsaSSL_Sign(signBuffer, signSz, output + idx,
+                                          sigSz, &rsaKey, ssl->rng);
+                    }
+
+                    if (ret > 0) {
+                        /* check for signature faults */
+                        ret = VerifyRsaSign(output + idx, ret,
+                                            signBuffer, signSz, &rsaKey);
+                    }
+
+                    wc_FreeRsaKey(&rsaKey);
+
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                #endif
+                }
+            #endif
+
+            done_b:
+        #ifdef WOLFSSL_SMALL_STACK
+            #ifndef NO_OLD_TLS
+                XFREE(md5,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(sha,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+                XFREE(hash,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #ifndef NO_SHA256
+                XFREE(sha256,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+            #ifdef WOLFSSL_SHA384
+                XFREE(sha384,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+            #ifdef WOLFSSL_SHA512
+                XFREE(sha512,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(hash512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+        #endif
+
+                if (ret < 0) return ret;
+            }
+
+    #ifdef HAVE_QSH
+            if (ssl->peerQSHKeyPresent) {
+                if (qshSz > 0) {
+                    idx = sendSz - qshSz;
+                    QSH_KeyExchangeWrite(ssl, 1);
+
+                    /* extension type */
+                    c16toa(WOLFSSL_QSH, output + idx);
+                    idx += OPAQUE16_LEN;
+
+                    /* write to output and check amount written */
+                    if (TLSX_QSHPK_Write(ssl->QSH_secret->list, output + idx)
+                                                         > qshSz - OPAQUE16_LEN)
+                        return MEMORY_E;
+                }
+            }
+    #endif
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls)
+                if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
+                    return ret;
+        #endif
+
+            if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0)
+                return ret;
+
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
+            if (ssl->toInfoOn)
+                AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
+                              output, sendSz, ssl->heap);
+        #endif
+
+            ssl->buffers.outputBuffer.length += sendSz;
+            if (ssl->options.groupMessages)
+                ret = 0;
+            else
+                ret = SendBuffered(ssl);
+            ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
+        }
+    #endif /* NO_DH */
+
+        return ret;
+        #undef ERROR_OUT
+    }
+
+
+    /* Make sure server cert/key are valid for this suite, true on success */
+    static int VerifyServerSuite(WOLFSSL* ssl, word16 idx)
+    {
+        int  haveRSA = !ssl->options.haveStaticECC;
+        int  havePSK = 0;
+        byte first;
+        byte second;
+
+        WOLFSSL_ENTER("VerifyServerSuite");
+
+        if (ssl->suites == NULL) {
+            WOLFSSL_MSG("Suites pointer error");
+            return 0;
+        }
+
+        first   = ssl->suites->suites[idx];
+        second  = ssl->suites->suites[idx+1];
+
+        #ifndef NO_PSK
+            havePSK = ssl->options.havePSK;
+        #endif
+
+        if (ssl->options.haveNTRU)
+            haveRSA = 0;
+
+        if (CipherRequires(first, second, REQUIRES_RSA)) {
+            WOLFSSL_MSG("Requires RSA");
+            if (haveRSA == 0) {
+                WOLFSSL_MSG("Don't have RSA");
+                return 0;
+            }
+        }
+
+        if (CipherRequires(first, second, REQUIRES_DHE)) {
+            WOLFSSL_MSG("Requires DHE");
+            if (ssl->options.haveDH == 0) {
+                WOLFSSL_MSG("Don't have DHE");
+                return 0;
+            }
+        }
+
+        if (CipherRequires(first, second, REQUIRES_ECC_DSA)) {
+            WOLFSSL_MSG("Requires ECCDSA");
+            if (ssl->options.haveECDSAsig == 0) {
+                WOLFSSL_MSG("Don't have ECCDSA");
+                return 0;
+            }
+        }
+
+        if (CipherRequires(first, second, REQUIRES_ECC_STATIC)) {
+            WOLFSSL_MSG("Requires static ECC");
+            if (ssl->options.haveStaticECC == 0) {
+                WOLFSSL_MSG("Don't have static ECC");
+                return 0;
+            }
+        }
+
+        if (CipherRequires(first, second, REQUIRES_PSK)) {
+            WOLFSSL_MSG("Requires PSK");
+            if (havePSK == 0) {
+                WOLFSSL_MSG("Don't have PSK");
+                return 0;
+            }
+        }
+
+        if (CipherRequires(first, second, REQUIRES_NTRU)) {
+            WOLFSSL_MSG("Requires NTRU");
+            if (ssl->options.haveNTRU == 0) {
+                WOLFSSL_MSG("Don't have NTRU");
+                return 0;
+            }
+        }
+
+        if (CipherRequires(first, second, REQUIRES_RSA_SIG)) {
+            WOLFSSL_MSG("Requires RSA Signature");
+            if (ssl->options.side == WOLFSSL_SERVER_END &&
+                                           ssl->options.haveECDSAsig == 1) {
+                WOLFSSL_MSG("Don't have RSA Signature");
+                return 0;
+            }
+        }
+
+#ifdef HAVE_SUPPORTED_CURVES
+        if (!TLSX_ValidateEllipticCurves(ssl, first, second)) {
+            WOLFSSL_MSG("Don't have matching curves");
+                return 0;
+        }
+#endif
+
+        /* ECCDHE is always supported if ECC on */
+
+#ifdef HAVE_QSH
+        /* need to negotiate a classic suite in addition to TLS_QSH */
+        if (first == QSH_BYTE && second == TLS_QSH) {
+            if (TLSX_SupportExtensions(ssl)) {
+                ssl->options.haveQSH = 1; /* matched TLS_QSH */
+            }
+            else {
+                WOLFSSL_MSG("Version of SSL connection does not support TLS_QSH");
+            }
+            return 0;
+        }
+#endif
+
+        return 1;
+    }
+
+    static int MatchSuite(WOLFSSL* ssl, Suites* peerSuites)
+    {
+        word16 i, j;
+
+        WOLFSSL_ENTER("MatchSuite");
+
+        /* & 0x1 equivalent % 2 */
+        if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
+            return MATCH_SUITE_ERROR;
+
+        if (ssl->suites == NULL)
+            return SUITES_ERROR;
+        /* start with best, if a match we are good */
+        for (i = 0; i < ssl->suites->suiteSz; i += 2)
+            for (j = 0; j < peerSuites->suiteSz; j += 2)
+                if (ssl->suites->suites[i]   == peerSuites->suites[j] &&
+                    ssl->suites->suites[i+1] == peerSuites->suites[j+1] ) {
+
+                    if (VerifyServerSuite(ssl, i)) {
+                        int result;
+                        WOLFSSL_MSG("Verified suite validity");
+                        ssl->options.cipherSuite0 = ssl->suites->suites[i];
+                        ssl->options.cipherSuite  = ssl->suites->suites[i+1];
+                        result = SetCipherSpecs(ssl);
+                        if (result == 0)
+                            PickHashSigAlgo(ssl, peerSuites->hashSigAlgo,
+                                                 peerSuites->hashSigAlgoSz);
+                        return result;
+                    }
+                    else {
+                        WOLFSSL_MSG("Could not verify suite validity, continue");
+                    }
+                }
+
+        return MATCH_SUITE_ERROR;
+    }
+
+
+#ifdef OLD_HELLO_ALLOWED
+
+    /* process old style client hello, deprecate? */
+    int ProcessOldClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                              word32 inSz, word16 sz)
+    {
+        word32          idx = *inOutIdx;
+        word16          sessionSz;
+        word16          randomSz;
+        word16          i, j;
+        ProtocolVersion pv;
+        Suites          clSuites;
+
+        (void)inSz;
+        WOLFSSL_MSG("Got old format client hello");
+#ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn)
+            AddPacketName("ClientHello", &ssl->handShakeInfo);
+        if (ssl->toInfoOn)
+            AddLateName("ClientHello", &ssl->timeoutInfo);
+#endif
+
+        /* manually hash input since different format */
+#ifndef NO_OLD_TLS
+#ifndef NO_MD5
+        wc_Md5Update(&ssl->hsHashes->hashMd5, input + idx, sz);
+#endif
+#ifndef NO_SHA
+        wc_ShaUpdate(&ssl->hsHashes->hashSha, input + idx, sz);
+#endif
+#endif
+#ifndef NO_SHA256
+        if (IsAtLeastTLSv1_2(ssl)) {
+            int shaRet = wc_Sha256Update(&ssl->hsHashes->hashSha256,
+                                         input + idx, sz);
+            if (shaRet != 0)
+                return shaRet;
+        }
+#endif
+
+        /* does this value mean client_hello? */
+        idx++;
+
+        /* version */
+        pv.major = input[idx++];
+        pv.minor = input[idx++];
+        ssl->chVersion = pv;  /* store */
+
+        if (ssl->version.minor > pv.minor) {
+            byte haveRSA = 0;
+            byte havePSK = 0;
+            if (!ssl->options.downgrade) {
+                WOLFSSL_MSG("Client trying to connect with lesser version");
+                return VERSION_ERROR;
+            }
+            if (pv.minor < ssl->options.minDowngrade) {
+                WOLFSSL_MSG("    version below minimum allowed, fatal error");
+                return VERSION_ERROR;
+            }
+            if (pv.minor == SSLv3_MINOR) {
+                /* turn off tls */
+                WOLFSSL_MSG("    downgrading to SSLv3");
+                ssl->options.tls    = 0;
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor  = SSLv3_MINOR;
+            }
+            else if (pv.minor == TLSv1_MINOR) {
+                WOLFSSL_MSG("    downgrading to TLSv1");
+                /* turn off tls 1.1+ */
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor  = TLSv1_MINOR;
+            }
+            else if (pv.minor == TLSv1_1_MINOR) {
+                WOLFSSL_MSG("    downgrading to TLSv1.1");
+                ssl->version.minor  = TLSv1_1_MINOR;
+            }
+#ifndef NO_RSA
+            haveRSA = 1;
+#endif
+#ifndef NO_PSK
+            havePSK = ssl->options.havePSK;
+#endif
+
+            InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
+                       ssl->options.haveDH, ssl->options.haveNTRU,
+                       ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
+                       ssl->options.side);
+        }
+
+        /* suite size */
+        ato16(&input[idx], &clSuites.suiteSz);
+        idx += 2;
+
+        if (clSuites.suiteSz > MAX_SUITE_SZ)
+            return BUFFER_ERROR;
+        clSuites.hashSigAlgoSz = 0;
+
+        /* session size */
+        ato16(&input[idx], &sessionSz);
+        idx += 2;
+
+        if (sessionSz > ID_LEN)
+            return BUFFER_ERROR;
+
+        /* random size */
+        ato16(&input[idx], &randomSz);
+        idx += 2;
+
+        if (randomSz > RAN_LEN)
+            return BUFFER_ERROR;
+
+        /* suites */
+        for (i = 0, j = 0; i < clSuites.suiteSz; i += 3) {
+            byte first = input[idx++];
+            if (!first) { /* implicit: skip sslv2 type */
+                XMEMCPY(&clSuites.suites[j], &input[idx], 2);
+                j += 2;
+            }
+            idx += 2;
+        }
+        clSuites.suiteSz = j;
+
+        /* session id */
+        if (sessionSz) {
+            XMEMCPY(ssl->arrays->sessionID, input + idx, sessionSz);
+            ssl->arrays->sessionIDSz = (byte)sessionSz;
+            idx += sessionSz;
+            ssl->options.resuming = 1;
+        }
+
+        /* random */
+        if (randomSz < RAN_LEN)
+            XMEMSET(ssl->arrays->clientRandom, 0, RAN_LEN - randomSz);
+        XMEMCPY(&ssl->arrays->clientRandom[RAN_LEN - randomSz], input + idx,
+               randomSz);
+        idx += randomSz;
+
+        if (ssl->options.usingCompression)
+            ssl->options.usingCompression = 0;  /* turn off */
+
+        ssl->options.clientState = CLIENT_HELLO_COMPLETE;
+        *inOutIdx = idx;
+
+        ssl->options.haveSessionId = 1;
+        /* DoClientHello uses same resume code */
+        if (ssl->options.resuming) {  /* let's try */
+            int ret = -1;
+            WOLFSSL_SESSION* session = GetSession(ssl,
+                                                  ssl->arrays->masterSecret);
+            #ifdef HAVE_SESSION_TICKET
+                if (ssl->options.useTicket == 1) {
+                    session = &ssl->session;
+                }
+            #endif
+
+            if (!session) {
+                WOLFSSL_MSG("Session lookup for resume failed");
+                ssl->options.resuming = 0;
+            } else {
+                if (MatchSuite(ssl, &clSuites) < 0) {
+                    WOLFSSL_MSG("Unsupported cipher suite, OldClientHello");
+                    return UNSUPPORTED_SUITE;
+                }
+                #ifdef SESSION_CERTS
+                    ssl->session = *session; /* restore session certs. */
+                #endif
+
+                ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
+                                                                       RAN_LEN);
+                if (ret != 0)
+                    return ret;
+
+                #ifdef NO_OLD_TLS
+                    ret = DeriveTlsKeys(ssl);
+                #else
+                    #ifndef NO_TLS
+                        if (ssl->options.tls)
+                            ret = DeriveTlsKeys(ssl);
+                    #endif
+                        if (!ssl->options.tls)
+                            ret = DeriveKeys(ssl);
+                #endif
+                ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
+
+                return ret;
+            }
+        }
+
+        return MatchSuite(ssl, &clSuites);
+    }
+
+#endif /* OLD_HELLO_ALLOWED */
+
+
+    static int DoClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                             word32 helloSz)
+    {
+        byte            b;
+        ProtocolVersion pv;
+        Suites          clSuites;
+        word32          i = *inOutIdx;
+        word32          begin = i;
+#ifdef WOLFSSL_DTLS
+        Hmac            cookieHmac;
+        byte            peerCookie[MAX_COOKIE_LEN];
+        byte            peerCookieSz = 0;
+        byte            cookieType;
+        byte            cookieSz;
+#endif /* WOLFSSL_DTLS */
+
+#ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
+        if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
+#endif
+
+        /* protocol version, random and session id length check */
+        if ((i - begin) + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
+            return BUFFER_ERROR;
+
+        /* protocol version */
+        XMEMCPY(&pv, input + i, OPAQUE16_LEN);
+        ssl->chVersion = pv;   /* store */
+#ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            int ret;
+            #if defined(NO_SHA) && defined(NO_SHA256)
+                #error "DTLS needs either SHA or SHA-256"
+            #endif /* NO_SHA && NO_SHA256 */
+
+            #ifndef NO_SHA
+                cookieType = SHA;
+                cookieSz = SHA_DIGEST_SIZE;
+            #endif /* NO_SHA */
+            #ifndef NO_SHA256
+                cookieType = SHA256;
+                cookieSz = SHA256_DIGEST_SIZE;
+            #endif /* NO_SHA256 */
+            ret = wc_HmacSetKey(&cookieHmac, cookieType,
+                                ssl->buffers.dtlsCookieSecret.buffer,
+                                ssl->buffers.dtlsCookieSecret.length);
+            if (ret != 0) return ret;
+            ret = wc_HmacUpdate(&cookieHmac,
+                                ssl->buffers.dtlsCtx.peer.sa,
+                                ssl->buffers.dtlsCtx.peer.sz);
+            if (ret != 0) return ret;
+            ret = wc_HmacUpdate(&cookieHmac, input + i, OPAQUE16_LEN);
+            if (ret != 0) return ret;
+        }
+#endif /* WOLFSSL_DTLS */
+        i += OPAQUE16_LEN;
+
+        if ((!ssl->options.dtls && ssl->version.minor > pv.minor) ||
+            (ssl->options.dtls && ssl->version.minor != DTLS_MINOR
+             && ssl->version.minor != DTLSv1_2_MINOR && pv.minor != DTLS_MINOR
+             && pv.minor != DTLSv1_2_MINOR)) {
+
+            byte haveRSA = 0;
+            byte havePSK = 0;
+
+            if (!ssl->options.downgrade) {
+                WOLFSSL_MSG("Client trying to connect with lesser version");
+                return VERSION_ERROR;
+            }
+            if (pv.minor < ssl->options.minDowngrade) {
+                WOLFSSL_MSG("    version below minimum allowed, fatal error");
+                return VERSION_ERROR;
+            }
+
+            if (pv.minor == SSLv3_MINOR) {
+                /* turn off tls */
+                WOLFSSL_MSG("    downgrading to SSLv3");
+                ssl->options.tls    = 0;
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor  = SSLv3_MINOR;
+            }
+            else if (pv.minor == TLSv1_MINOR) {
+                /* turn off tls 1.1+ */
+                WOLFSSL_MSG("    downgrading to TLSv1");
+                ssl->options.tls1_1 = 0;
+                ssl->version.minor  = TLSv1_MINOR;
+            }
+            else if (pv.minor == TLSv1_1_MINOR) {
+                WOLFSSL_MSG("    downgrading to TLSv1.1");
+                ssl->version.minor  = TLSv1_1_MINOR;
+            }
+#ifndef NO_RSA
+            haveRSA = 1;
+#endif
+#ifndef NO_PSK
+            havePSK = ssl->options.havePSK;
+#endif
+            InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
+                       ssl->options.haveDH, ssl->options.haveNTRU,
+                       ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
+                       ssl->options.side);
+        }
+
+        /* random */
+        XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
+#ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            int ret = wc_HmacUpdate(&cookieHmac, input + i, RAN_LEN);
+            if (ret != 0) return ret;
+        }
+#endif /* WOLFSSL_DTLS */
+        i += RAN_LEN;
+
+#ifdef SHOW_SECRETS
+        {
+            int j;
+            printf("client random: ");
+            for (j = 0; j < RAN_LEN; j++)
+                printf("%02x", ssl->arrays->clientRandom[j]);
+            printf("\n");
+        }
+#endif
+
+        /* session id */
+        b = input[i++];
+
+        if (b == ID_LEN) {
+            if ((i - begin) + ID_LEN > helloSz)
+                return BUFFER_ERROR;
+
+            XMEMCPY(ssl->arrays->sessionID, input + i, ID_LEN);
+#ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                int ret = wc_HmacUpdate(&cookieHmac, input + i - 1, ID_LEN + 1);
+                if (ret != 0) return ret;
+            }
+#endif /* WOLFSSL_DTLS */
+            ssl->arrays->sessionIDSz = ID_LEN;
+            i += ID_LEN;
+            ssl->options.resuming = 1; /* client wants to resume */
+            WOLFSSL_MSG("Client wants to resume session");
+        }
+        else if (b) {
+            WOLFSSL_MSG("Invalid session ID size");
+            return BUFFER_ERROR; /* session ID nor 0 neither 32 bytes long */
+        }
+
+        #ifdef WOLFSSL_DTLS
+            /* cookie */
+            if (ssl->options.dtls) {
+
+                if ((i - begin) + OPAQUE8_LEN > helloSz)
+                    return BUFFER_ERROR;
+
+                peerCookieSz = input[i++];
+
+                if (peerCookieSz) {
+                    if (peerCookieSz > MAX_COOKIE_LEN)
+                        return BUFFER_ERROR;
+
+                    if ((i - begin) + peerCookieSz > helloSz)
+                        return BUFFER_ERROR;
+
+                    XMEMCPY(peerCookie, input + i, peerCookieSz);
+
+                    i += peerCookieSz;
+                }
+            }
+        #endif
+
+        /* suites */
+        if ((i - begin) + OPAQUE16_LEN > helloSz)
+            return BUFFER_ERROR;
+
+        ato16(&input[i], &clSuites.suiteSz);
+        i += OPAQUE16_LEN;
+
+        /* suites and compression length check */
+        if ((i - begin) + clSuites.suiteSz + OPAQUE8_LEN > helloSz)
+            return BUFFER_ERROR;
+
+        if (clSuites.suiteSz > MAX_SUITE_SZ)
+            return BUFFER_ERROR;
+
+        XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
+#ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            int ret = wc_HmacUpdate(&cookieHmac,
+                                    input + i - OPAQUE16_LEN,
+                                    clSuites.suiteSz + OPAQUE16_LEN);
+            if (ret != 0) return ret;
+        }
+#endif /* WOLFSSL_DTLS */
+        i += clSuites.suiteSz;
+        clSuites.hashSigAlgoSz = 0;
+
+        /* compression length */
+        b = input[i++];
+
+        if ((i - begin) + b > helloSz)
+            return BUFFER_ERROR;
+
+#ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            byte newCookie[MAX_COOKIE_LEN];
+            int ret;
+
+            ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1);
+            if (ret != 0) return ret;
+            ret = wc_HmacFinal(&cookieHmac, newCookie);
+            if (ret != 0) return ret;
+
+            /* If a cookie callback is set, call it to overwrite the cookie.
+             * This should be deprecated. The code now calculates the cookie
+             * using an HMAC as expected. */
+            if (ssl->ctx->CBIOCookie != NULL &&
+                ssl->ctx->CBIOCookie(ssl, newCookie, cookieSz,
+                                             ssl->IOCB_CookieCtx) != cookieSz) {
+                return COOKIE_ERROR;
+            }
+
+            /* Check the cookie, see if we progress the state machine. */
+            if (peerCookieSz != cookieSz ||
+                XMEMCMP(peerCookie, newCookie, cookieSz) != 0) {
+
+                /* Send newCookie to client in a HelloVerifyRequest message
+                 * and let the state machine alone. */
+                ssl->msgsReceived.got_client_hello = 0;
+                *inOutIdx += helloSz;
+                return SendHelloVerifyRequest(ssl, newCookie, cookieSz);
+            }
+
+            /* This was skipped in the DTLS case so we could handle the hello
+             * verify request. */
+            ret = HashInput(ssl, input + *inOutIdx, helloSz);
+            if (ret != 0) return ret;
+        }
+#endif /* WOLFSSL_DTLS */
+
+        if (ssl->options.usingCompression) {
+            int match = 0;
+
+            while (b--) {
+                byte comp = input[i++];
+
+                if (comp == ZLIB_COMPRESSION)
+                    match = 1;
+            }
+
+            if (!match) {
+                WOLFSSL_MSG("Not matching compression, turning off");
+                ssl->options.usingCompression = 0;  /* turn off */
+            }
+        }
+        else
+            i += b; /* ignore, since we're not on */
+
+        *inOutIdx = i;
+
+        /* tls extensions */
+        if ((i - begin) < helloSz) {
+#ifdef HAVE_TLS_EXTENSIONS
+        #ifdef HAVE_QSH
+            QSH_Init(ssl);
+        #endif
+            if (TLSX_SupportExtensions(ssl)) {
+                int ret = 0;
+#else
+            if (IsAtLeastTLSv1_2(ssl)) {
+#endif
+                /* Process the hello extension. Skip unsupported. */
+                word16 totalExtSz;
+
+#ifdef HAVE_TLS_EXTENSIONS
+                /* auto populate extensions supported unless user defined */
+                if ((ret = TLSX_PopulateExtensions(ssl, 1)) != 0)
+                    return ret;
+#endif
+
+                if ((i - begin) + OPAQUE16_LEN > helloSz)
+                    return BUFFER_ERROR;
+
+                ato16(&input[i], &totalExtSz);
+                i += OPAQUE16_LEN;
+
+                if ((i - begin) + totalExtSz > helloSz)
+                    return BUFFER_ERROR;
+
+#ifdef HAVE_TLS_EXTENSIONS
+                /* tls extensions */
+                if ((ret = TLSX_Parse(ssl, (byte *) input + i,
+                                                     totalExtSz, 1, &clSuites)))
+                    return ret;
+#ifdef HAVE_STUNNEL
+                if((ret=SNI_Callback(ssl)))
+                    return ret;
+#endif /*HAVE_STUNNEL*/
+
+                i += totalExtSz;
+#else
+                while (totalExtSz) {
+                    word16 extId, extSz;
+
+                    if (OPAQUE16_LEN + OPAQUE16_LEN > totalExtSz)
+                        return BUFFER_ERROR;
+
+                    ato16(&input[i], &extId);
+                    i += OPAQUE16_LEN;
+                    ato16(&input[i], &extSz);
+                    i += OPAQUE16_LEN;
+
+                    if (OPAQUE16_LEN + OPAQUE16_LEN + extSz > totalExtSz)
+                        return BUFFER_ERROR;
+
+                    if (extId == HELLO_EXT_SIG_ALGO) {
+                        ato16(&input[i], &clSuites.hashSigAlgoSz);
+                        i += OPAQUE16_LEN;
+
+                        if (OPAQUE16_LEN + clSuites.hashSigAlgoSz > extSz)
+                            return BUFFER_ERROR;
+
+                        XMEMCPY(clSuites.hashSigAlgo, &input[i],
+                            min(clSuites.hashSigAlgoSz, HELLO_EXT_SIGALGO_MAX));
+                        i += clSuites.hashSigAlgoSz;
+
+                        if (clSuites.hashSigAlgoSz > HELLO_EXT_SIGALGO_MAX)
+                            clSuites.hashSigAlgoSz = HELLO_EXT_SIGALGO_MAX;
+                    }
+                    else
+                        i += extSz;
+
+                    totalExtSz -= OPAQUE16_LEN + OPAQUE16_LEN + extSz;
+                }
+#endif
+                *inOutIdx = i;
+            }
+            else
+                *inOutIdx = begin + helloSz; /* skip extensions */
+        }
+
+        ssl->options.clientState   = CLIENT_HELLO_COMPLETE;
+        ssl->options.haveSessionId = 1;
+
+        /* ProcessOld uses same resume code */
+        if (ssl->options.resuming) {
+            int ret = -1;
+            WOLFSSL_SESSION* session = GetSession(ssl,
+                                                  ssl->arrays->masterSecret);
+            #ifdef HAVE_SESSION_TICKET
+                if (ssl->options.useTicket == 1) {
+                    session = &ssl->session;
+                }
+            #endif
+
+            if (!session) {
+                WOLFSSL_MSG("Session lookup for resume failed");
+                ssl->options.resuming = 0;
+            }
+            else {
+                if (MatchSuite(ssl, &clSuites) < 0) {
+                    WOLFSSL_MSG("Unsupported cipher suite, ClientHello");
+                    return UNSUPPORTED_SUITE;
+                }
+                #ifdef SESSION_CERTS
+                    ssl->session = *session; /* restore session certs. */
+                #endif
+
+                ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
+                                                                       RAN_LEN);
+                if (ret != 0)
+                    return ret;
+
+                #ifdef NO_OLD_TLS
+                    ret = DeriveTlsKeys(ssl);
+                #else
+                    #ifndef NO_TLS
+                        if (ssl->options.tls)
+                            ret = DeriveTlsKeys(ssl);
+                    #endif
+                        if (!ssl->options.tls)
+                            ret = DeriveKeys(ssl);
+                #endif
+                ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
+
+                return ret;
+            }
+        }
+        return MatchSuite(ssl, &clSuites);
+    }
+
+#if !defined(NO_RSA) || defined(HAVE_ECC)
+    static int DoCertificateVerify(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                                   word32 size)
+    {
+        word16      sz = 0;
+        int         ret = VERIFY_CERT_ERROR;   /* start in error state */
+        byte        hashAlgo = sha_mac;
+        byte        sigAlgo = anonymous_sa_algo;
+        word32      begin = *inOutIdx;
+
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName("CertificateVerify", &ssl->handShakeInfo);
+            if (ssl->toInfoOn)
+                AddLateName("CertificateVerify", &ssl->timeoutInfo);
+        #endif
+
+
+        if (IsAtLeastTLSv1_2(ssl)) {
+            if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size)
+                return BUFFER_ERROR;
+
+            hashAlgo = input[(*inOutIdx)++];
+            sigAlgo  = input[(*inOutIdx)++];
+        }
+
+        if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+            return BUFFER_ERROR;
+
+        ato16(input + *inOutIdx, &sz);
+        *inOutIdx += OPAQUE16_LEN;
+
+        if ((*inOutIdx - begin) + sz > size || sz > ENCRYPT_LEN)
+            return BUFFER_ERROR;
+
+        /* RSA */
+#ifndef NO_RSA
+        if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) {
+            byte* out       = NULL;
+            int   outLen    = 0;
+            byte  doUserRsa = 0;
+
+            #ifdef HAVE_PK_CALLBACKS
+                if (ssl->ctx->RsaVerifyCb)
+                    doUserRsa = 1;
+            #endif /*HAVE_PK_CALLBACKS */
+
+            WOLFSSL_MSG("Doing RSA peer cert verify");
+
+            if (doUserRsa) {
+            #ifdef HAVE_PK_CALLBACKS
+                outLen = ssl->ctx->RsaVerifyCb(ssl, input + *inOutIdx, sz,
+                                            &out,
+                                            ssl->buffers.peerRsaKey.buffer,
+                                            ssl->buffers.peerRsaKey.length,
+                                            ssl->RsaVerifyCtx);
+            #endif /*HAVE_PK_CALLBACKS */
+            }
+            else {
+                outLen = wc_RsaSSL_VerifyInline(input + *inOutIdx, sz, &out,
+                                                               ssl->peerRsaKey);
+            }
+
+            if (IsAtLeastTLSv1_2(ssl)) {
+#ifdef WOLFSSL_SMALL_STACK
+                byte*  encodedSig = NULL;
+#else
+                byte   encodedSig[MAX_ENCODED_SIG_SZ];
+#endif
+                word32 sigSz;
+                byte*  digest = ssl->hsHashes->certHashes.sha;
+                int    typeH = SHAh;
+                int    digestSz = SHA_DIGEST_SIZE;
+
+#ifdef WOLFSSL_SMALL_STACK
+                encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+                if (encodedSig == NULL)
+                    return MEMORY_E;
+#endif
+
+                if (sigAlgo != rsa_sa_algo) {
+                    WOLFSSL_MSG("Oops, peer sent RSA key but not in verify");
+                }
+
+                if (hashAlgo == sha256_mac) {
+                    #ifndef NO_SHA256
+                        digest = ssl->hsHashes->certHashes.sha256;
+                        typeH    = SHA256h;
+                        digestSz = SHA256_DIGEST_SIZE;
+                    #endif
+                }
+                else if (hashAlgo == sha384_mac) {
+                    #ifdef WOLFSSL_SHA384
+                        digest = ssl->hsHashes->certHashes.sha384;
+                        typeH    = SHA384h;
+                        digestSz = SHA384_DIGEST_SIZE;
+                    #endif
+                }
+                else if (hashAlgo == sha512_mac) {
+                    #ifdef WOLFSSL_SHA512
+                        digest = ssl->hsHashes->certHashes.sha512;
+                        typeH    = SHA512h;
+                        digestSz = SHA512_DIGEST_SIZE;
+                    #endif
+                }
+
+                sigSz = wc_EncodeSignature(encodedSig, digest, digestSz, typeH);
+
+                if (outLen == (int)sigSz && out && XMEMCMP(out, encodedSig,
+                                           min(sigSz, MAX_ENCODED_SIG_SZ)) == 0)
+                    ret = 0; /* verified */
+
+#ifdef WOLFSSL_SMALL_STACK
+                XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            }
+            else {
+                if (outLen == FINISHED_SZ && out && XMEMCMP(out,
+                                            &ssl->hsHashes->certHashes,
+                                            FINISHED_SZ) == 0) {
+                    ret = 0; /* verified */
+                }
+            }
+        }
+#endif
+#ifdef HAVE_ECC
+        if (ssl->peerEccDsaKeyPresent) {
+            int verify =  0;
+            int err    = -1;
+            byte* digest = ssl->hsHashes->certHashes.sha;
+            word32 digestSz = SHA_DIGEST_SIZE;
+            byte doUserEcc = 0;
+
+            #ifdef HAVE_PK_CALLBACKS
+                if (ssl->ctx->EccVerifyCb)
+                    doUserEcc = 1;
+            #endif
+
+            WOLFSSL_MSG("Doing ECC peer cert verify");
+
+            if (IsAtLeastTLSv1_2(ssl)) {
+                if (sigAlgo != ecc_dsa_sa_algo) {
+                    WOLFSSL_MSG("Oops, peer sent ECC key but not in verify");
+                }
+
+                if (hashAlgo == sha256_mac) {
+                    #ifndef NO_SHA256
+                        digest = ssl->hsHashes->certHashes.sha256;
+                        digestSz = SHA256_DIGEST_SIZE;
+                    #endif
+                }
+                else if (hashAlgo == sha384_mac) {
+                    #ifdef WOLFSSL_SHA384
+                        digest = ssl->hsHashes->certHashes.sha384;
+                        digestSz = SHA384_DIGEST_SIZE;
+                    #endif
+                }
+                else if (hashAlgo == sha512_mac) {
+                    #ifdef WOLFSSL_SHA512
+                        digest = ssl->hsHashes->certHashes.sha512;
+                        digestSz = SHA512_DIGEST_SIZE;
+                    #endif
+                }
+            }
+
+            if (doUserEcc) {
+            #ifdef HAVE_PK_CALLBACKS
+                ret = ssl->ctx->EccVerifyCb(ssl, input + *inOutIdx, sz, digest,
+                                            digestSz,
+                                            ssl->buffers.peerEccDsaKey.buffer,
+                                            ssl->buffers.peerEccDsaKey.length,
+                                            &verify, ssl->EccVerifyCtx);
+            #endif
+            }
+            else {
+                err = wc_ecc_verify_hash(input + *inOutIdx, sz, digest,
+                                         digestSz, &verify, ssl->peerEccDsaKey);
+            }
+
+            if (err == 0 && verify == 1)
+               ret = 0; /* verified */
+        }
+#endif
+        *inOutIdx += sz;
+
+        if (ret == 0)
+            ssl->options.havePeerVerify = 1;
+
+        return ret;
+    }
+#endif /* !NO_RSA || HAVE_ECC */
+
+    int SendServerHelloDone(WOLFSSL* ssl)
+    {
+        byte              *output;
+        int                sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+        int                ret;
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls)
+                sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
+        #endif
+        /* check for available size */
+        if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+            return ret;
+
+        /* get ouput buffer */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        AddHeaders(output, 0, server_hello_done, ssl);
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->options.dtls) {
+                if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
+                    return 0;
+            }
+        #endif
+
+        ret = HashOutput(ssl, output, sendSz, 0);
+            if (ret != 0)
+                return ret;
+
+#ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn)
+            AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
+        if (ssl->toInfoOn)
+            AddPacketInfo("ServerHelloDone", &ssl->timeoutInfo, output, sendSz,
+                          ssl->heap);
+#endif
+        ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
+
+        ssl->buffers.outputBuffer.length += sendSz;
+
+        return SendBuffered(ssl);
+    }
+
+
+#ifdef HAVE_SESSION_TICKET
+
+#define WOLFSSL_TICKET_FIXED_SZ (WOLFSSL_TICKET_NAME_SZ + \
+                WOLFSSL_TICKET_IV_SZ + WOLFSSL_TICKET_MAC_SZ + LENGTH_SZ)
+#define WOLFSSL_TICKET_ENC_SZ (SESSION_TICKET_LEN - WOLFSSL_TICKET_FIXED_SZ)
+
+    /* our ticket format */
+    typedef struct InternalTicket {
+        ProtocolVersion pv;                    /* version when ticket created */
+        byte            suite[SUITE_LEN];      /* cipher suite when created */
+        byte            msecret[SECRET_LEN];   /* master secret */
+        word32          timestamp;             /* born on */
+    } InternalTicket;
+
+    /* fit within SESSION_TICKET_LEN */
+    typedef struct ExternalTicket {
+        byte key_name[WOLFSSL_TICKET_NAME_SZ];  /* key context name */
+        byte iv[WOLFSSL_TICKET_IV_SZ];          /* this ticket's iv */
+        byte enc_len[LENGTH_SZ];                /* encrypted length */
+        byte enc_ticket[WOLFSSL_TICKET_ENC_SZ]; /* encrypted internal ticket */
+        byte mac[WOLFSSL_TICKET_MAC_SZ];        /* total mac */
+        /* !! if add to structure, add to TICKET_FIXED_SZ !! */
+    } ExternalTicket;
+
+    /* create a new session ticket, 0 on success */
+    static int CreateTicket(WOLFSSL* ssl)
+    {
+        InternalTicket  it;
+        ExternalTicket* et = (ExternalTicket*)ssl->session.ticket;
+        int encLen;
+        int ret;
+        byte zeros[WOLFSSL_TICKET_MAC_SZ];   /* biggest cmp size */
+
+        /* build internal */
+        it.pv.major = ssl->version.major;
+        it.pv.minor = ssl->version.minor;
+
+        it.suite[0] = ssl->options.cipherSuite0;
+        it.suite[1] = ssl->options.cipherSuite;
+
+        XMEMCPY(it.msecret, ssl->arrays->masterSecret, SECRET_LEN);
+        c32toa(LowResTimer(), (byte*)&it.timestamp);
+
+        /* build external */
+        XMEMCPY(et->enc_ticket, &it, sizeof(InternalTicket));
+
+        /* encrypt */
+        encLen = WOLFSSL_TICKET_ENC_SZ;  /* max size user can use */
+        ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv, et->mac, 1,
+                                    et->enc_ticket, sizeof(InternalTicket),
+                                    &encLen, ssl->ctx->ticketEncCtx);
+        if (ret == WOLFSSL_TICKET_RET_OK) {
+            if (encLen < (int)sizeof(InternalTicket) ||
+                encLen > WOLFSSL_TICKET_ENC_SZ) {
+                WOLFSSL_MSG("Bad user ticket encrypt size");
+                return BAD_TICKET_KEY_CB_SZ;
+            }
+
+            /* sanity checks on encrypt callback */
+
+            /* internal ticket can't be the same if encrypted */
+            if (XMEMCMP(et->enc_ticket, &it, sizeof(InternalTicket)) == 0) {
+                WOLFSSL_MSG("User ticket encrypt didn't encrypt");
+                return BAD_TICKET_ENCRYPT;
+            }
+
+            XMEMSET(zeros, 0, sizeof(zeros));
+
+            /* name */
+            if (XMEMCMP(et->key_name, zeros, WOLFSSL_TICKET_NAME_SZ) == 0) {
+                WOLFSSL_MSG("User ticket encrypt didn't set name");
+                return BAD_TICKET_ENCRYPT;
+            }
+
+            /* iv */
+            if (XMEMCMP(et->iv, zeros, WOLFSSL_TICKET_IV_SZ) == 0) {
+                WOLFSSL_MSG("User ticket encrypt didn't set iv");
+                return BAD_TICKET_ENCRYPT;
+            }
+
+            /* mac */
+            if (XMEMCMP(et->mac, zeros, WOLFSSL_TICKET_MAC_SZ) == 0) {
+                WOLFSSL_MSG("User ticket encrypt didn't set mac");
+                return BAD_TICKET_ENCRYPT;
+            }
+
+            /* set size */
+            c16toa((word16)encLen, et->enc_len);
+            ssl->session.ticketLen = (word16)(encLen + WOLFSSL_TICKET_FIXED_SZ);
+            if (encLen < WOLFSSL_TICKET_ENC_SZ) {
+                /* move mac up since whole enc buffer not used */
+                XMEMMOVE(et->enc_ticket +encLen, et->mac,WOLFSSL_TICKET_MAC_SZ);
+            }
+        }
+
+        return ret;
+    }
+
+
+    /* Parse ticket sent by client, returns callback return value */
+    int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len)
+    {
+        ExternalTicket* et;
+        InternalTicket* it;
+        int             ret;
+        int             outLen;
+        word16          inLen;
+
+        if (len > SESSION_TICKET_LEN ||
+             len < (word32)(sizeof(InternalTicket) + WOLFSSL_TICKET_FIXED_SZ)) {
+            return BAD_TICKET_MSG_SZ;
+        }
+
+        et = (ExternalTicket*)input;
+        it = (InternalTicket*)et->enc_ticket;
+
+        /* decrypt */
+        ato16(et->enc_len, &inLen);
+        if (inLen > (word16)(len - WOLFSSL_TICKET_FIXED_SZ)) {
+            return BAD_TICKET_MSG_SZ;
+        }
+        outLen = inLen;   /* may be reduced by user padding */
+        ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv,
+                                    et->enc_ticket + inLen, 0,
+                                    et->enc_ticket, inLen, &outLen,
+                                    ssl->ctx->ticketEncCtx);
+        if (ret == WOLFSSL_TICKET_RET_FATAL || ret < 0) return ret;
+        if (outLen > inLen || outLen < (int)sizeof(InternalTicket)) {
+            WOLFSSL_MSG("Bad user ticket decrypt len");
+            return BAD_TICKET_KEY_CB_SZ;
+        }
+
+        /* get master secret */
+        if (ret == WOLFSSL_TICKET_RET_OK || ret == WOLFSSL_TICKET_RET_CREATE)
+            XMEMCPY(ssl->arrays->masterSecret, it->msecret, SECRET_LEN);
+
+        return ret;
+    }
+
+
+    /* send Session Ticket */
+    int SendTicket(WOLFSSL* ssl)
+    {
+        byte*              output;
+        int                ret;
+        int                sendSz;
+        word32             length = SESSION_HINT_SZ + LENGTH_SZ;
+        word32             idx    = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
+
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            length += DTLS_RECORD_EXTRA;
+            idx    += DTLS_RECORD_EXTRA;
+        }
+    #endif
+
+        if (ssl->options.createTicket) {
+            ret = CreateTicket(ssl);
+            if (ret != 0) return ret;
+        }
+
+        length += ssl->session.ticketLen;
+        sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
+
+        /* check for available size */
+        if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+            return ret;
+
+        /* get ouput buffer */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        AddHeaders(output, length, session_ticket, ssl);
+
+        /* hint */
+        c32toa(ssl->ctx->ticketHint, output + idx);
+        idx += SESSION_HINT_SZ;
+
+        /* length */
+        c16toa(ssl->session.ticketLen, output + idx);
+        idx += LENGTH_SZ;
+
+        /* ticket */
+        XMEMCPY(output + idx, ssl->session.ticket, ssl->session.ticketLen);
+        /* idx += ssl->session.ticketLen; */
+
+        ret = HashOutput(ssl, output, sendSz, 0);
+        if (ret != 0) return ret;
+        ssl->buffers.outputBuffer.length += sendSz;
+
+        return SendBuffered(ssl);
+    }
+
+#endif /* HAVE_SESSION_TICKET */
+
+
+#ifdef WOLFSSL_DTLS
+    static int SendHelloVerifyRequest(WOLFSSL* ssl,
+                                      const byte* cookie, byte cookieSz)
+    {
+        byte* output;
+        int   length = VERSION_SZ + ENUM_LEN + cookieSz;
+        int   idx    = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
+        int   sendSz = length + idx;
+        int   ret;
+
+        /* check for available size */
+        if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
+            return ret;
+
+        /* get ouput buffer */
+        output = ssl->buffers.outputBuffer.buffer +
+                 ssl->buffers.outputBuffer.length;
+
+        AddHeaders(output, length, hello_verify_request, ssl);
+        {
+            DtlsRecordLayerHeader* rh = (DtlsRecordLayerHeader*)output;
+            rh->pvMajor = DTLS_MAJOR;
+            rh->pvMinor = DTLS_MINOR;
+        }
+
+        output[idx++] = DTLS_MAJOR;
+        output[idx++] = DTLS_MINOR;
+
+        output[idx++] = cookieSz;
+        if (cookie == NULL || cookieSz == 0)
+            return COOKIE_ERROR;
+
+        XMEMCPY(output + idx, cookie, cookieSz);
+
+#ifdef WOLFSSL_CALLBACKS
+        if (ssl->hsInfoOn)
+            AddPacketName("HelloVerifyRequest", &ssl->handShakeInfo);
+        if (ssl->toInfoOn)
+            AddPacketInfo("HelloVerifyRequest", &ssl->timeoutInfo, output,
+                          sendSz, ssl->heap);
+#endif
+
+        ssl->buffers.outputBuffer.length += sendSz;
+
+        return SendBuffered(ssl);
+    }
+#endif
+
+    static int DoClientKeyExchange(WOLFSSL* ssl, byte* input, word32* inOutIdx,
+                                                                    word32 size)
+    {
+        #ifdef HAVE_QSH
+            word16 name;
+            int    qshSz;
+        #endif
+        int    ret = 0;
+        word32 length = 0;
+        byte*  out = NULL;
+        word32 begin = *inOutIdx;
+
+        (void)length; /* shut up compiler warnings */
+        (void)out;
+        (void)input;
+        (void)size;
+        (void)begin;
+
+        if (ssl->options.side != WOLFSSL_SERVER_END) {
+            WOLFSSL_MSG("Client received client keyexchange, attack?");
+            WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
+            return SSL_FATAL_ERROR;
+        }
+
+        if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
+            WOLFSSL_MSG("Client sending keyexchange at wrong time");
+            SendAlert(ssl, alert_fatal, unexpected_message);
+            return OUT_OF_ORDER_E;
+        }
+
+        #ifndef NO_CERTS
+            if (ssl->options.verifyPeer && ssl->options.failNoCert)
+                if (!ssl->options.havePeerCert) {
+                    WOLFSSL_MSG("client didn't present peer cert");
+                    return NO_PEER_CERT;
+                }
+        #endif
+
+        #ifdef WOLFSSL_CALLBACKS
+            if (ssl->hsInfoOn)
+                AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
+            if (ssl->toInfoOn)
+                AddLateName("ClientKeyExchange", &ssl->timeoutInfo);
+        #endif
+
+        switch (ssl->specs.kea) {
+        #ifndef NO_RSA
+            case rsa_kea:
+            {
+                word32 idx = 0;
+                RsaKey key;
+                byte   doUserRsa = 0;
+
+                #ifdef HAVE_PK_CALLBACKS
+                    if (ssl->ctx->RsaDecCb)
+                        doUserRsa = 1;
+                #endif
+
+                ret = wc_InitRsaKey(&key, ssl->heap);
+                if (ret != 0) return ret;
+
+                if (ssl->buffers.key.buffer)
+                    ret = wc_RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx,
+                                             &key, ssl->buffers.key.length);
+                else
+                    return NO_PRIVATE_KEY;
+
+                if (ret == 0) {
+                    length = wc_RsaEncryptSize(&key);
+                    ssl->arrays->preMasterSz = SECRET_LEN;
+
+                    if (ssl->options.tls) {
+                        word16 check;
+
+                        if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+                            return BUFFER_ERROR;
+
+                        ato16(input + *inOutIdx, &check);
+                        *inOutIdx += OPAQUE16_LEN;
+
+                        if ((word32) check != length) {
+                            WOLFSSL_MSG("RSA explicit size doesn't match");
+                            wc_FreeRsaKey(&key);
+                            return RSA_PRIVATE_ERROR;
+                        }
+                    }
+
+                    if ((*inOutIdx - begin) + length > size) {
+                        WOLFSSL_MSG("RSA message too big");
+                        wc_FreeRsaKey(&key);
+                        return BUFFER_ERROR;
+                    }
+
+                    if (doUserRsa) {
+                        #ifdef HAVE_PK_CALLBACKS
+                            ret = ssl->ctx->RsaDecCb(ssl,
+                                        input + *inOutIdx, length, &out,
+                                        ssl->buffers.key.buffer,
+                                        ssl->buffers.key.length,
+                                        ssl->RsaDecCtx);
+                        #endif
+                    }
+                    else {
+                        ret = wc_RsaPrivateDecryptInline(input + *inOutIdx, length,
+                                                                    &out, &key);
+                    }
+
+                    *inOutIdx += length;
+
+                    if (ret == SECRET_LEN) {
+                        XMEMCPY(ssl->arrays->preMasterSecret, out, SECRET_LEN);
+                        if (ssl->arrays->preMasterSecret[0] !=
+                                                           ssl->chVersion.major
+                            || ssl->arrays->preMasterSecret[1] !=
+                                                           ssl->chVersion.minor)
+                            ret = PMS_VERSION_ERROR;
+                        else
+                        {
+                #ifdef HAVE_QSH
+                            if (ssl->options.haveQSH) {
+                                /* extension name */
+                                ato16(input + *inOutIdx, &name);
+                                *inOutIdx += OPAQUE16_LEN;
+
+                                if (name == WOLFSSL_QSH) {
+                                    /* if qshSz is larger than 0 it is the
+                                       length of buffer used */
+                                    if ((qshSz = TLSX_QSHCipher_Parse(ssl, input
+                                                  + *inOutIdx, size - *inOutIdx
+                                                  + begin, 1)) < 0)
+                                        return qshSz;
+                                    *inOutIdx += qshSz;
+                                }
+                                else {
+                                    /* unknown extension sent client ignored
+                                       handshake */
+                                    return BUFFER_ERROR;
+                                }
+                            }
+                #endif
+                            ret = MakeMasterSecret(ssl);
+                         }
+                    }
+                    else {
+                        ret = RSA_PRIVATE_ERROR;
+                    }
+                }
+
+                wc_FreeRsaKey(&key);
+            }
+            break;
+        #endif
+        #ifndef NO_PSK
+            case psk_kea:
+            {
+                byte* pms = ssl->arrays->preMasterSecret;
+                word16 ci_sz;
+
+                if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+                    return BUFFER_ERROR;
+
+                ato16(input + *inOutIdx, &ci_sz);
+                *inOutIdx += OPAQUE16_LEN;
+
+                if (ci_sz > MAX_PSK_ID_LEN)
+                    return CLIENT_ID_ERROR;
+
+                if ((*inOutIdx - begin) + ci_sz > size)
+                    return BUFFER_ERROR;
+
+                XMEMCPY(ssl->arrays->client_identity, input + *inOutIdx, ci_sz);
+                *inOutIdx += ci_sz;
+
+                ssl->arrays->client_identity[min(ci_sz, MAX_PSK_ID_LEN-1)] = 0;
+                ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
+                    ssl->arrays->client_identity, ssl->arrays->psk_key,
+                    MAX_PSK_KEY_LEN);
+
+                if (ssl->arrays->psk_keySz == 0 ||
+                                       ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
+                    return PSK_KEY_ERROR;
+
+                /* make psk pre master secret */
+                /* length of key + length 0s + length of key + key */
+                c16toa((word16) ssl->arrays->psk_keySz, pms);
+                pms += OPAQUE16_LEN;
+
+                XMEMSET(pms, 0, ssl->arrays->psk_keySz);
+                pms += ssl->arrays->psk_keySz;
+
+                c16toa((word16) ssl->arrays->psk_keySz, pms);
+                pms += OPAQUE16_LEN;
+
+                XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
+
+            #ifdef HAVE_QSH
+                if (ssl->options.haveQSH) {
+                    /* extension name */
+                    ato16(input + *inOutIdx, &name);
+                    *inOutIdx += OPAQUE16_LEN;
+
+                    if (name == WOLFSSL_QSH) {
+                        /* if qshSz is larger than 0 it is the length of
+                           buffer used */
+                        if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
+                                              size - *inOutIdx + begin, 1)) < 0)
+                            return qshSz;
+                        *inOutIdx += qshSz;
+                    }
+                    else {
+                        /* unknown extension sent client ignored
+                           handshake */
+                        return BUFFER_ERROR;
+                    }
+                }
+            #endif
+                ret = MakeMasterSecret(ssl);
+
+                /* No further need for PSK */
+                ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                ssl->arrays->psk_keySz = 0;
+            }
+            break;
+        #endif /* NO_PSK */
+        #ifdef HAVE_NTRU
+            case ntru_kea:
+            {
+                word16 cipherLen;
+                word16 plainLen = sizeof(ssl->arrays->preMasterSecret);
+
+                if (!ssl->buffers.key.buffer)
+                    return NO_PRIVATE_KEY;
+
+                if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+                    return BUFFER_ERROR;
+
+                ato16(input + *inOutIdx, &cipherLen);
+                *inOutIdx += OPAQUE16_LEN;
+
+                if (cipherLen > MAX_NTRU_ENCRYPT_SZ)
+                    return NTRU_KEY_ERROR;
+
+                if ((*inOutIdx - begin) + cipherLen > size)
+                    return BUFFER_ERROR;
+
+                if (NTRU_OK != ntru_crypto_ntru_decrypt(
+                            (word16) ssl->buffers.key.length,
+                            ssl->buffers.key.buffer, cipherLen,
+                            input + *inOutIdx, &plainLen,
+                            ssl->arrays->preMasterSecret))
+                    return NTRU_DECRYPT_ERROR;
+
+                if (plainLen != SECRET_LEN)
+                    return NTRU_DECRYPT_ERROR;
+
+                *inOutIdx += cipherLen;
+
+            #ifdef HAVE_QSH
+                if (ssl->options.haveQSH) {
+                    /* extension name */
+                    ato16(input + *inOutIdx, &name);
+                    *inOutIdx += OPAQUE16_LEN;
+
+                    if (name == WOLFSSL_QSH) {
+                        /* if qshSz is larger than 0 it is the length of
+                           buffer used */
+                        if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
+                                              size - *inOutIdx + begin, 1)) < 0)
+                            return qshSz;
+                        *inOutIdx += qshSz;
+                    }
+                    else {
+                        /* unknown extension sent client ignored
+                           handshake */
+                        return BUFFER_ERROR;
+                    }
+                }
+            #endif
+                ssl->arrays->preMasterSz = plainLen;
+                ret = MakeMasterSecret(ssl);
+            }
+            break;
+        #endif /* HAVE_NTRU */
+        #ifdef HAVE_ECC
+            case ecc_diffie_hellman_kea:
+            {
+                if ((*inOutIdx - begin) + OPAQUE8_LEN > size)
+                    return BUFFER_ERROR;
+
+                length = input[(*inOutIdx)++];
+
+                if ((*inOutIdx - begin) + length > size)
+                    return BUFFER_ERROR;
+
+                if (ssl->peerEccKey == NULL) {
+                    /* alloc/init on demand */
+                    ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
+                                              ssl->ctx->heap, DYNAMIC_TYPE_ECC);
+                    if (ssl->peerEccKey == NULL) {
+                        WOLFSSL_MSG("PeerEccKey Memory error");
+                        return MEMORY_E;
+                    }
+                    wc_ecc_init(ssl->peerEccKey);
+                } else if (ssl->peerEccKeyPresent) {  /* don't leak on reuse */
+                    wc_ecc_free(ssl->peerEccKey);
+                    ssl->peerEccKeyPresent = 0;
+                    wc_ecc_init(ssl->peerEccKey);
+                }
+
+                if (wc_ecc_import_x963(input + *inOutIdx, length, ssl->peerEccKey))
+                    return ECC_PEERKEY_ERROR;
+
+                *inOutIdx += length;
+                ssl->peerEccKeyPresent = 1;
+
+                length = sizeof(ssl->arrays->preMasterSecret);
+
+                if (ssl->specs.static_ecdh) {
+                    ecc_key staticKey;
+                    word32 i = 0;
+
+                    wc_ecc_init(&staticKey);
+                    ret = wc_EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
+                                           &staticKey, ssl->buffers.key.length);
+
+                    if (ret == 0)
+                        ret = wc_ecc_shared_secret(&staticKey, ssl->peerEccKey,
+                                         ssl->arrays->preMasterSecret, &length);
+
+                    wc_ecc_free(&staticKey);
+                }
+                else {
+                    if (ssl->eccTempKeyPresent == 0) {
+                        WOLFSSL_MSG("Ecc ephemeral key not made correctly");
+                        ret = ECC_MAKEKEY_ERROR;
+                    } else {
+                        ret = wc_ecc_shared_secret(ssl->eccTempKey,ssl->peerEccKey,
+                                         ssl->arrays->preMasterSecret, &length);
+                    }
+                }
+
+                if (ret != 0)
+                    return ECC_SHARED_ERROR;
+
+                ssl->arrays->preMasterSz = length;
+            #ifdef HAVE_QSH
+                if (ssl->options.haveQSH) {
+                    /* extension name */
+                    ato16(input + *inOutIdx, &name);
+                    *inOutIdx += OPAQUE16_LEN;
+
+                    if (name == WOLFSSL_QSH) {
+                        /* if qshSz is larger than 0 it is the length of
+                           buffer used */
+                        if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
+                                              size - *inOutIdx + begin, 1)) < 0)
+                            return qshSz;
+                        *inOutIdx += qshSz;
+                    }
+                    else {
+                        /* unknown extension sent client ignored
+                           handshake */
+                        return BUFFER_ERROR;
+                    }
+                }
+            #endif
+                ret = MakeMasterSecret(ssl);
+            }
+            break;
+        #endif /* HAVE_ECC */
+        #ifndef NO_DH
+            case diffie_hellman_kea:
+            {
+                word16 clientPubSz;
+                DhKey  dhKey;
+
+                if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+                    return BUFFER_ERROR;
+
+                ato16(input + *inOutIdx, &clientPubSz);
+                *inOutIdx += OPAQUE16_LEN;
+
+                if ((*inOutIdx - begin) + clientPubSz > size)
+                    return BUFFER_ERROR;
+
+                wc_InitDhKey(&dhKey);
+                ret = wc_DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
+                                       ssl->buffers.serverDH_P.length,
+                                       ssl->buffers.serverDH_G.buffer,
+                                       ssl->buffers.serverDH_G.length);
+                if (ret == 0)
+                    ret = wc_DhAgree(&dhKey, ssl->arrays->preMasterSecret,
+                                         &ssl->arrays->preMasterSz,
+                                          ssl->buffers.serverDH_Priv.buffer,
+                                          ssl->buffers.serverDH_Priv.length,
+                                          input + *inOutIdx, clientPubSz);
+                wc_FreeDhKey(&dhKey);
+
+                *inOutIdx += clientPubSz;
+
+            #ifdef HAVE_QSH
+                if (ssl->options.haveQSH) {
+                    /* extension name */
+                    ato16(input + *inOutIdx, &name);
+                    *inOutIdx += OPAQUE16_LEN;
+
+                    if (name == WOLFSSL_QSH) {
+                        /* if qshSz is larger than 0 it is the length of
+                           buffer used */
+                        if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
+                                              size - *inOutIdx + begin, 1)) < 0)
+                            return qshSz;
+                        *inOutIdx += qshSz;
+                    }
+                    else {
+                        /* unknown extension sent client ignored
+                           handshake */
+                        return BUFFER_ERROR;
+                    }
+                }
+            #endif
+                if (ret == 0)
+                    ret = MakeMasterSecret(ssl);
+            }
+            break;
+        #endif /* NO_DH */
+        #if !defined(NO_DH) && !defined(NO_PSK)
+            case dhe_psk_kea:
+            {
+                byte* pms = ssl->arrays->preMasterSecret;
+                word16 clientSz;
+                DhKey  dhKey;
+
+                /* Read in the PSK hint */
+                if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+                    return BUFFER_ERROR;
+
+                ato16(input + *inOutIdx, &clientSz);
+                *inOutIdx += OPAQUE16_LEN;
+                if (clientSz > MAX_PSK_ID_LEN)
+                    return CLIENT_ID_ERROR;
+
+                if ((*inOutIdx - begin) + clientSz > size)
+                    return BUFFER_ERROR;
+
+                XMEMCPY(ssl->arrays->client_identity,
+                                                   input + *inOutIdx, clientSz);
+                *inOutIdx += clientSz;
+                ssl->arrays->client_identity[min(clientSz, MAX_PSK_ID_LEN-1)] =
+                                                                              0;
+
+                /* Read in the DHE business */
+                if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
+                    return BUFFER_ERROR;
+
+                ato16(input + *inOutIdx, &clientSz);
+                *inOutIdx += OPAQUE16_LEN;
+
+                if ((*inOutIdx - begin) + clientSz > size)
+                    return BUFFER_ERROR;
+
+                wc_InitDhKey(&dhKey);
+                ret = wc_DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
+                                       ssl->buffers.serverDH_P.length,
+                                       ssl->buffers.serverDH_G.buffer,
+                                       ssl->buffers.serverDH_G.length);
+                if (ret == 0)
+                    ret = wc_DhAgree(&dhKey, pms + OPAQUE16_LEN,
+                                          &ssl->arrays->preMasterSz,
+                                          ssl->buffers.serverDH_Priv.buffer,
+                                          ssl->buffers.serverDH_Priv.length,
+                                          input + *inOutIdx, clientSz);
+                wc_FreeDhKey(&dhKey);
+
+                *inOutIdx += clientSz;
+                c16toa((word16)ssl->arrays->preMasterSz, pms);
+                ssl->arrays->preMasterSz += OPAQUE16_LEN;
+                pms += ssl->arrays->preMasterSz;
+
+                /* Use the PSK hint to look up the PSK and add it to the
+                 * preMasterSecret here. */
+                ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
+                    ssl->arrays->client_identity, ssl->arrays->psk_key,
+                    MAX_PSK_KEY_LEN);
+
+                if (ssl->arrays->psk_keySz == 0 ||
+                                       ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
+                    return PSK_KEY_ERROR;
+
+                c16toa((word16) ssl->arrays->psk_keySz, pms);
+                pms += OPAQUE16_LEN;
+
+                XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                ssl->arrays->preMasterSz +=
+                                          ssl->arrays->psk_keySz + OPAQUE16_LEN;
+            #ifdef HAVE_QSH
+                if (ssl->options.haveQSH) {
+                    /* extension name */
+                    ato16(input + *inOutIdx, &name);
+                    *inOutIdx += OPAQUE16_LEN;
+
+                    if (name == WOLFSSL_QSH) {
+                        /* if qshSz is larger than 0 it is the length of
+                           buffer used */
+                        if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
+                                              size - *inOutIdx + begin, 1)) < 0)
+                            return qshSz;
+                        *inOutIdx += qshSz;
+                    }
+                    else {
+                        /* unknown extension sent client ignored
+                           handshake */
+                        return BUFFER_ERROR;
+                    }
+                }
+            #endif
+                if (ret == 0)
+                    ret = MakeMasterSecret(ssl);
+
+                /* No further need for PSK */
+                ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
+                ssl->arrays->psk_keySz = 0;
+            }
+            break;
+        #endif /* !NO_DH && !NO_PSK */
+            default:
+            {
+                WOLFSSL_MSG("Bad kea type");
+                ret = BAD_KEA_TYPE_E;
+            }
+            break;
+        }
+
+        /* No further need for PMS */
+        ForceZero(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
+        ssl->arrays->preMasterSz = 0;
+
+        if (ret == 0) {
+            ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
+            #ifndef NO_CERTS
+                if (ssl->options.verifyPeer)
+                    ret = BuildCertHashes(ssl, &ssl->hsHashes->certHashes);
+            #endif
+        }
+
+        return ret;
+    }
+
+#ifdef HAVE_STUNNEL
+    static int SNI_Callback(WOLFSSL* ssl)
+    {
+        /* Stunnel supports a custom sni callback to switch an SSL's ctx
+        * when SNI is received. Call it now if exists */
+        if(ssl && ssl->ctx && ssl->ctx->sniRecvCb) {
+            WOLFSSL_MSG("Calling custom sni callback");
+            if(ssl->ctx->sniRecvCb(ssl, NULL, ssl->ctx->sniRecvCbArg)
+                    == alert_fatal) {
+                WOLFSSL_MSG("Error in custom sni callback. Fatal alert");
+                SendAlert(ssl, alert_fatal, unrecognized_name);
+                return FATAL_ERROR;
+            }
+        }
+        return 0;
+    }
+#endif /* HAVE_STUNNEL */
+#endif /* NO_WOLFSSL_SERVER */
+#endif /* WOLFCRYPT_ONLY */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/src/io.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/src/io.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/src/io.c	(revision 164)
@@ -0,0 +1,1178 @@
+/* io.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLFCRYPT_ONLY
+
+#ifdef _WIN32_WCE
+    /* On WinCE winsock2.h must be included before windows.h for socket stuff */
+    #include <winsock2.h>
+#endif
+
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+
+
+/* if user writes own I/O callbacks they can define WOLFSSL_USER_IO to remove
+   automatic setting of default I/O functions EmbedSend() and EmbedReceive()
+   but they'll still need SetCallback xxx() at end of file 
+*/
+#ifndef WOLFSSL_USER_IO
+
+#ifdef HAVE_LIBZ
+    #include "zlib.h"
+#endif
+
+#ifndef USE_WINDOWS_API
+    #ifdef WOLFSSL_LWIP
+        /* lwIP needs to be configured to use sockets API in this mode */
+        /* LWIP_SOCKET 1 in lwip/opt.h or in build */
+        #include "lwip/sockets.h"
+        #include <errno.h>
+        #ifndef LWIP_PROVIDE_ERRNO
+            #define LWIP_PROVIDE_ERRNO 1
+        #endif
+    #elif defined(FREESCALE_MQX)
+        #include <posix.h>
+        #include <rtcs.h>
+    #elif defined(FREESCALE_KSDK_MQX)
+        #include <rtcs.h>
+    #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
+        #if defined(WOLFSSL_MDK5) || defined(WOLFSSL_KEIL_TCP_NET)
+            #include "cmsis_os.h"
+        #else
+            #include <rtl.h>
+        #endif
+        #include "errno.h"
+        #define SOCKET_T int
+        #include "rl_net.h"
+    #elif defined(WOLFSSL_TIRTOS)
+        #include <sys/socket.h>
+    #elif defined(FREERTOS_TCP)
+        #include "FreeRTOS_Sockets.h"
+    #elif defined(WOLFSSL_IAR_ARM)
+        /* nothing */
+    #elif defined(WOLFSSL_VXWORKS)
+        #include <sockLib.h>
+        #include <errno.h>
+    #else
+        #include <sys/types.h>
+        #include <errno.h>
+        #ifndef EBSNET
+            #include <unistd.h>
+        #endif
+        #include <fcntl.h>
+        #if !(defined(DEVKITPRO) || defined(HAVE_RTP_SYS) || defined(EBSNET)) \
+            && !(defined(WOLFSSL_PICOTCP))
+            #include <sys/socket.h>
+            #include <arpa/inet.h>
+            #include <netinet/in.h>
+            #include <netdb.h>
+            #ifdef __PPU
+                #include <netex/errno.h>
+            #else
+                #include <sys/ioctl.h>
+            #endif
+        #endif
+        #ifdef HAVE_RTP_SYS
+            #include <socket.h>
+        #endif
+        #ifdef EBSNET
+            #include "rtipapi.h"  /* errno */
+            #include "socket.h"
+        #endif
+    #endif
+#endif /* USE_WINDOWS_API */
+
+#ifdef __sun
+    #include <sys/filio.h>
+#endif
+
+#ifdef USE_WINDOWS_API 
+    /* no epipe yet */
+    #ifndef WSAEPIPE
+        #define WSAEPIPE       -12345
+    #endif
+    #define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK
+    #define SOCKET_EAGAIN      WSAETIMEDOUT
+    #define SOCKET_ECONNRESET  WSAECONNRESET
+    #define SOCKET_EINTR       WSAEINTR
+    #define SOCKET_EPIPE       WSAEPIPE
+    #define SOCKET_ECONNREFUSED WSAENOTCONN
+    #define SOCKET_ECONNABORTED WSAECONNABORTED
+    #define close(s) closesocket(s)
+#elif defined(__PPU)
+    #define SOCKET_EWOULDBLOCK SYS_NET_EWOULDBLOCK
+    #define SOCKET_EAGAIN      SYS_NET_EAGAIN
+    #define SOCKET_ECONNRESET  SYS_NET_ECONNRESET
+    #define SOCKET_EINTR       SYS_NET_EINTR
+    #define SOCKET_EPIPE       SYS_NET_EPIPE
+    #define SOCKET_ECONNREFUSED SYS_NET_ECONNREFUSED
+    #define SOCKET_ECONNABORTED SYS_NET_ECONNABORTED
+#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+    #if MQX_USE_IO_OLD
+        /* RTCS old I/O doesn't have an EWOULDBLOCK */
+        #define SOCKET_EWOULDBLOCK  EAGAIN
+        #define SOCKET_EAGAIN       EAGAIN
+        #define SOCKET_ECONNRESET   RTCSERR_TCP_CONN_RESET
+        #define SOCKET_EINTR        EINTR
+        #define SOCKET_EPIPE        EPIPE
+        #define SOCKET_ECONNREFUSED RTCSERR_TCP_CONN_REFUSED
+        #define SOCKET_ECONNABORTED RTCSERR_TCP_CONN_ABORTED
+    #else
+        #define SOCKET_EWOULDBLOCK  NIO_EWOULDBLOCK
+        #define SOCKET_EAGAIN       NIO_EAGAIN
+        #define SOCKET_ECONNRESET   NIO_ECONNRESET
+        #define SOCKET_EINTR        NIO_EINTR
+        #define SOCKET_EPIPE        NIO_EPIPE
+        #define SOCKET_ECONNREFUSED NIO_ECONNREFUSED
+        #define SOCKET_ECONNABORTED NIO_ECONNABORTED
+    #endif
+#elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET)
+    #if defined(WOLFSSL_MDK5)|| defined(WOLFSSL_KEIL_TCP_NET)
+        #define SOCKET_EWOULDBLOCK BSD_ERROR_WOULDBLOCK
+        #define SOCKET_EAGAIN      BSD_ERROR_LOCKED
+        #define SOCKET_ECONNRESET  BSD_ERROR_CLOSED
+        #define SOCKET_EINTR       BSD_ERROR
+        #define SOCKET_EPIPE       BSD_ERROR
+        #define SOCKET_ECONNREFUSED BSD_ERROR
+        #define SOCKET_ECONNABORTED BSD_ERROR
+    #else
+        #define SOCKET_EWOULDBLOCK SCK_EWOULDBLOCK
+        #define SOCKET_EAGAIN      SCK_ELOCKED
+        #define SOCKET_ECONNRESET  SCK_ECLOSED
+        #define SOCKET_EINTR       SCK_ERROR
+        #define SOCKET_EPIPE       SCK_ERROR
+        #define SOCKET_ECONNREFUSED SCK_ERROR
+        #define SOCKET_ECONNABORTED SCK_ERROR
+    #endif
+#elif defined(WOLFSSL_PICOTCP)
+    #define SOCKET_EWOULDBLOCK  PICO_ERR_EAGAIN
+    #define SOCKET_EAGAIN       PICO_ERR_EAGAIN
+    #define SOCKET_ECONNRESET   PICO_ERR_ECONNRESET
+    #define SOCKET_EINTR        PICO_ERR_EINTR
+    #define SOCKET_EPIPE        PICO_ERR_EIO
+    #define SOCKET_ECONNREFUSED PICO_ERR_ECONNREFUSED
+    #define SOCKET_ECONNABORTED PICO_ERR_ESHUTDOWN
+#elif defined(FREERTOS_TCP)
+    #define SOCKET_EWOULDBLOCK FREERTOS_EWOULDBLOCK
+    #define SOCKET_EAGAIN       FREERTOS_EWOULDBLOCK
+    #define SOCKET_ECONNRESET   FREERTOS_SOCKET_ERROR
+    #define SOCKET_EINTR        FREERTOS_SOCKET_ERROR
+    #define SOCKET_EPIPE        FREERTOS_SOCKET_ERROR
+    #define SOCKET_ECONNREFUSED FREERTOS_SOCKET_ERROR
+    #define SOCKET_ECONNABORTED FREERTOS_SOCKET_ERROR
+#else
+    #define SOCKET_EWOULDBLOCK EWOULDBLOCK
+    #define SOCKET_EAGAIN      EAGAIN
+    #define SOCKET_ECONNRESET  ECONNRESET
+    #define SOCKET_EINTR       EINTR
+    #define SOCKET_EPIPE       EPIPE
+    #define SOCKET_ECONNREFUSED ECONNREFUSED
+    #define SOCKET_ECONNABORTED ECONNABORTED
+#endif /* USE_WINDOWS_API */
+
+
+#ifdef DEVKITPRO
+    /* from network.h */
+    int net_send(int, const void*, int, unsigned int);
+    int net_recv(int, void*, int, unsigned int);
+    #define SEND_FUNCTION net_send
+    #define RECV_FUNCTION net_recv
+#elif defined(WOLFSSL_LWIP)
+    #define SEND_FUNCTION lwip_send
+    #define RECV_FUNCTION lwip_recv
+#elif defined(WOLFSSL_PICOTCP)
+    #define SEND_FUNCTION pico_send
+    #define RECV_FUNCTION pico_recv
+#elif defined(FREERTOS_TCP)
+    #define RECV_FUNCTION(a,b,c,d)  FreeRTOS_recv((Socket_t)(a),(void*)(b), (size_t)(c), (BaseType_t)(d))
+    #define SEND_FUNCTION(a,b,c,d)  FreeRTOS_send((Socket_t)(a),(void*)(b), (size_t)(c), (BaseType_t)(d))
+#else
+    #define SEND_FUNCTION send
+    #define RECV_FUNCTION recv
+#endif
+
+
+/* Translates return codes returned from 
+ * send() and recv() if need be. 
+ */
+static INLINE int TranslateReturnCode(int old, int sd)
+{
+    (void)sd;
+
+#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+    if (old == 0) {
+        errno = SOCKET_EWOULDBLOCK;
+        return -1;  /* convert to BSD style wouldblock as error */
+    }
+
+    if (old < 0) {
+        errno = RTCS_geterror(sd);
+        if (errno == RTCSERR_TCP_CONN_CLOSING)
+            return 0;   /* convert to BSD style closing */
+        if (errno == RTCSERR_TCP_CONN_RLSD)
+            errno = SOCKET_ECONNRESET;
+        if (errno == RTCSERR_TCP_TIMED_OUT)
+            errno = SOCKET_EAGAIN;
+    }
+#endif
+
+    return old;
+}
+
+static INLINE int LastError(void)
+{
+#ifdef USE_WINDOWS_API 
+    return WSAGetLastError();
+#elif defined(EBSNET)
+    return xn_getlasterror();
+#else
+    return errno;
+#endif
+}
+
+/* The receive embedded callback
+ *  return : nb bytes read, or error
+ */
+int EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
+{
+    int recvd;
+    int err;
+    int sd = *(int*)ctx;
+
+#ifdef WOLFSSL_DTLS
+    {
+        int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
+        if (wolfSSL_dtls(ssl)
+                     && !wolfSSL_get_using_nonblock(ssl)
+                     && dtls_timeout != 0) {
+            #ifdef USE_WINDOWS_API
+                DWORD timeout = dtls_timeout * 1000;
+            #else
+                struct timeval timeout;
+                XMEMSET(&timeout, 0, sizeof(timeout));
+                timeout.tv_sec = dtls_timeout;
+            #endif
+            if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
+                           sizeof(timeout)) != 0) {
+                WOLFSSL_MSG("setsockopt rcvtimeo failed");
+            }
+        }
+    }
+#endif
+
+    recvd = (int)RECV_FUNCTION(sd, buf, sz, ssl->rflags);
+
+    recvd = TranslateReturnCode(recvd, sd);
+
+    if (recvd < 0) {
+        err = LastError();
+        WOLFSSL_MSG("Embed Receive error");
+
+        if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
+            if (!wolfSSL_dtls(ssl) || wolfSSL_get_using_nonblock(ssl)) {
+                WOLFSSL_MSG("    Would block");
+                return WOLFSSL_CBIO_ERR_WANT_READ;
+            }
+            else {
+                WOLFSSL_MSG("    Socket timeout");
+                return WOLFSSL_CBIO_ERR_TIMEOUT;
+            }
+        }
+        else if (err == SOCKET_ECONNRESET) {
+            WOLFSSL_MSG("    Connection reset");
+            return WOLFSSL_CBIO_ERR_CONN_RST;
+        }
+        else if (err == SOCKET_EINTR) {
+            WOLFSSL_MSG("    Socket interrupted");
+            return WOLFSSL_CBIO_ERR_ISR;
+        }
+        else if (err == SOCKET_ECONNREFUSED) {
+            WOLFSSL_MSG("    Connection refused");
+            return WOLFSSL_CBIO_ERR_WANT_READ;
+        }
+        else if (err == SOCKET_ECONNABORTED) {
+            WOLFSSL_MSG("    Connection aborted");
+            return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+        }
+        else {
+            WOLFSSL_MSG("    General error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+    else if (recvd == 0) {
+        WOLFSSL_MSG("Embed receive connection closed");
+        return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+    }
+
+    return recvd;
+}
+
+/* The send embedded callback
+ *  return : nb bytes sent, or error
+ */
+int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx)
+{
+    int sd = *(int*)ctx;
+    int sent;
+    int len = sz;
+    int err;
+
+    sent = (int)SEND_FUNCTION(sd, &buf[sz - len], len, ssl->wflags);
+
+    sent = TranslateReturnCode(sent, sd);
+
+    if (sent < 0) {
+        err = LastError();
+        WOLFSSL_MSG("Embed Send error");
+
+        if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
+            WOLFSSL_MSG("    Would Block");
+            return WOLFSSL_CBIO_ERR_WANT_WRITE;
+        }
+        else if (err == SOCKET_ECONNRESET) {
+            WOLFSSL_MSG("    Connection reset");
+            return WOLFSSL_CBIO_ERR_CONN_RST;
+        }
+        else if (err == SOCKET_EINTR) {
+            WOLFSSL_MSG("    Socket interrupted");
+            return WOLFSSL_CBIO_ERR_ISR;
+        }
+        else if (err == SOCKET_EPIPE) {
+            WOLFSSL_MSG("    Socket EPIPE");
+            return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+        }
+        else {
+            WOLFSSL_MSG("    General error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+ 
+    return sent;
+}
+
+
+#ifdef WOLFSSL_DTLS
+
+#include <wolfssl/wolfcrypt/sha.h>
+
+#ifdef USE_WINDOWS_API
+   #define XSOCKLENT int
+#else
+   #define XSOCKLENT socklen_t
+#endif
+
+#define SENDTO_FUNCTION sendto
+#define RECVFROM_FUNCTION recvfrom
+
+
+/* The receive embedded callback
+ *  return : nb bytes read, or error
+ */
+int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
+{
+    WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
+    int recvd;
+    int err;
+    int sd = dtlsCtx->fd;
+    int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
+    struct sockaddr_storage peer;
+    XSOCKLENT peerSz = sizeof(peer);
+
+    WOLFSSL_ENTER("EmbedReceiveFrom()");
+
+    if (!wolfSSL_get_using_nonblock(ssl) && dtls_timeout != 0) {
+        #ifdef USE_WINDOWS_API
+            DWORD timeout = dtls_timeout * 1000;
+        #else
+            struct timeval timeout;
+            XMEMSET(&timeout, 0, sizeof(timeout));
+            timeout.tv_sec = dtls_timeout;
+        #endif
+        if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
+                       sizeof(timeout)) != 0) {
+                WOLFSSL_MSG("setsockopt rcvtimeo failed");
+        }
+    }
+
+    recvd = (int)RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags,
+                                  (struct sockaddr*)&peer, &peerSz);
+
+    recvd = TranslateReturnCode(recvd, sd);
+
+    if (recvd < 0) {
+        err = LastError();
+        WOLFSSL_MSG("Embed Receive From error");
+
+        if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
+            if (wolfSSL_get_using_nonblock(ssl)) {
+                WOLFSSL_MSG("    Would block");
+                return WOLFSSL_CBIO_ERR_WANT_READ;
+            }
+            else {
+                WOLFSSL_MSG("    Socket timeout");
+                return WOLFSSL_CBIO_ERR_TIMEOUT;
+            }
+        }
+        else if (err == SOCKET_ECONNRESET) {
+            WOLFSSL_MSG("    Connection reset");
+            return WOLFSSL_CBIO_ERR_CONN_RST;
+        }
+        else if (err == SOCKET_EINTR) {
+            WOLFSSL_MSG("    Socket interrupted");
+            return WOLFSSL_CBIO_ERR_ISR;
+        }
+        else if (err == SOCKET_ECONNREFUSED) {
+            WOLFSSL_MSG("    Connection refused");
+            return WOLFSSL_CBIO_ERR_WANT_READ;
+        }
+        else {
+            WOLFSSL_MSG("    General error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+    else {
+        if (dtlsCtx->peer.sz > 0
+                && peerSz != (XSOCKLENT)dtlsCtx->peer.sz
+                && memcmp(&peer, dtlsCtx->peer.sa, peerSz) != 0) {
+            WOLFSSL_MSG("    Ignored packet from invalid peer");
+            return WOLFSSL_CBIO_ERR_WANT_READ;
+        }
+    }
+
+    return recvd;
+}
+
+
+/* The send embedded callback
+ *  return : nb bytes sent, or error
+ */
+int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
+{
+    WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
+    int sd = dtlsCtx->fd;
+    int sent;
+    int len = sz;
+    int err;
+
+    WOLFSSL_ENTER("EmbedSendTo()");
+
+    sent = (int)SENDTO_FUNCTION(sd, &buf[sz - len], len, ssl->wflags,
+                                (const struct sockaddr*)dtlsCtx->peer.sa,
+                                dtlsCtx->peer.sz);
+
+    sent = TranslateReturnCode(sent, sd);
+
+    if (sent < 0) {
+        err = LastError();
+        WOLFSSL_MSG("Embed Send To error");
+
+        if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
+            WOLFSSL_MSG("    Would Block");
+            return WOLFSSL_CBIO_ERR_WANT_WRITE;
+        }
+        else if (err == SOCKET_ECONNRESET) {
+            WOLFSSL_MSG("    Connection reset");
+            return WOLFSSL_CBIO_ERR_CONN_RST;
+        }
+        else if (err == SOCKET_EINTR) {
+            WOLFSSL_MSG("    Socket interrupted");
+            return WOLFSSL_CBIO_ERR_ISR;
+        }
+        else if (err == SOCKET_EPIPE) {
+            WOLFSSL_MSG("    Socket EPIPE");
+            return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+        }
+        else {
+            WOLFSSL_MSG("    General error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+ 
+    return sent;
+}
+
+
+/* The DTLS Generate Cookie callback
+ *  return : number of bytes copied into buf, or error
+ */
+int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx)
+{
+    int sd = ssl->wfd;
+    struct sockaddr_storage peer;
+    XSOCKLENT peerSz = sizeof(peer);
+    byte digest[SHA_DIGEST_SIZE];
+    int  ret = 0;
+
+    (void)ctx;
+
+    XMEMSET(&peer, 0, sizeof(peer));
+    if (getpeername(sd, (struct sockaddr*)&peer, &peerSz) != 0) {
+        WOLFSSL_MSG("getpeername failed in EmbedGenerateCookie");
+        return GEN_COOKIE_E;
+    }
+
+    ret = wc_ShaHash((byte*)&peer, peerSz, digest);
+    if (ret != 0)
+        return ret;
+
+    if (sz > SHA_DIGEST_SIZE)
+        sz = SHA_DIGEST_SIZE;
+    XMEMCPY(buf, digest, sz);
+
+    return sz;
+}
+
+#endif /* WOLFSSL_DTLS */
+
+#ifdef HAVE_OCSP
+
+#include <stdlib.h>   /* atoi() */
+
+
+static int Word16ToString(char* d, word16 number)
+{
+    int i = 0;
+
+    if (d != NULL) {
+        word16 order = 10000;
+        word16 digit;
+
+        if (number == 0) {
+            d[i++] = '0';
+        }
+        else {
+            while (order) {
+                digit = number / order;
+                if (i > 0 || digit != 0) {
+                    d[i++] = (char)digit + '0';
+                }
+                if (digit != 0)
+                    number %= digit * order;
+                if (order > 1)
+                    order /= 10;
+                else
+                    order = 0;
+            }
+        }
+        d[i] = 0;
+    }
+
+    return i;
+}
+
+
+static int tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port)
+{
+    struct sockaddr_storage addr;
+    int sockaddr_len = sizeof(struct sockaddr_in);
+    XMEMSET(&addr, 0, sizeof(addr));
+
+    #ifdef HAVE_GETADDRINFO
+    {
+        struct addrinfo hints;
+        struct addrinfo* answer = NULL;
+        char strPort[6];
+
+        XMEMSET(&hints, 0, sizeof(hints));
+        hints.ai_family = AF_UNSPEC;
+        hints.ai_socktype = SOCK_STREAM;
+        hints.ai_protocol = IPPROTO_TCP;
+
+        if (Word16ToString(strPort, port) == 0) {
+            WOLFSSL_MSG("invalid port number for OCSP responder");
+            return -1;
+        }
+
+        if (getaddrinfo(ip, strPort, &hints, &answer) < 0 || answer == NULL) {
+            WOLFSSL_MSG("no addr info for OCSP responder");
+            return -1;
+        }
+
+        sockaddr_len = answer->ai_addrlen;
+        XMEMCPY(&addr, answer->ai_addr, sockaddr_len);
+        freeaddrinfo(answer);
+
+    }
+    #else /* HAVE_GETADDRINFO */
+    {
+        struct hostent* entry = gethostbyname(ip);
+        struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
+
+        if (entry) {
+            sin->sin_family = AF_INET;
+            sin->sin_port = htons(port);
+            XMEMCPY(&sin->sin_addr.s_addr, entry->h_addr_list[0],
+                                                               entry->h_length);
+        }
+        else {
+            WOLFSSL_MSG("no addr info for OCSP responder");
+            return -1;
+        }
+    }
+    #endif /* HAVE_GETADDRINFO */
+
+    *sockfd = socket(addr.ss_family, SOCK_STREAM, 0);
+
+#ifdef USE_WINDOWS_API
+    if (*sockfd == INVALID_SOCKET) {
+        WOLFSSL_MSG("bad socket fd, out of fds?");
+        return -1;
+    }
+#else
+     if (*sockfd < 0) {
+         WOLFSSL_MSG("bad socket fd, out of fds?");
+         return -1;
+     }
+#endif
+
+    if (connect(*sockfd, (struct sockaddr *)&addr, sockaddr_len) != 0) {
+        WOLFSSL_MSG("OCSP responder tcp connect failed");
+        return -1;
+    }
+
+    return 0;
+}
+
+
+static int build_http_request(const char* domainName, const char* path,
+                                    int ocspReqSz, byte* buf, int bufSize)
+{
+    word32 domainNameLen, pathLen, ocspReqSzStrLen, completeLen;
+    char ocspReqSzStr[6];
+
+    domainNameLen = (word32)XSTRLEN(domainName);
+    pathLen = (word32)XSTRLEN(path);
+    ocspReqSzStrLen = Word16ToString(ocspReqSzStr, (word16)ocspReqSz);
+
+    completeLen = domainNameLen + pathLen + ocspReqSzStrLen + 84;
+    if (completeLen > (word32)bufSize)
+        return 0;
+
+    XSTRNCPY((char*)buf, "POST ", 5);
+    buf += 5;
+    XSTRNCPY((char*)buf, path, pathLen);
+    buf += pathLen;
+    XSTRNCPY((char*)buf, " HTTP/1.1\r\nHost: ", 17);
+    buf += 17;
+    XSTRNCPY((char*)buf, domainName, domainNameLen);
+    buf += domainNameLen;
+    XSTRNCPY((char*)buf, "\r\nContent-Length: ", 18);
+    buf += 18;
+    XSTRNCPY((char*)buf, ocspReqSzStr, ocspReqSzStrLen);
+    buf += ocspReqSzStrLen;
+    XSTRNCPY((char*)buf,
+                      "\r\nContent-Type: application/ocsp-request\r\n\r\n", 44);
+
+    return completeLen;
+}
+
+
+static int decode_url(const char* url, int urlSz,
+    char* outName, char* outPath, word16* outPort)
+{
+    int result = -1;
+
+    if (outName != NULL && outPath != NULL && outPort != NULL)
+    {
+        if (url == NULL || urlSz == 0)
+        {
+            *outName = 0;
+            *outPath = 0;
+            *outPort = 0;
+        }
+        else
+        {
+            int i, cur;
+    
+            /* need to break the url down into scheme, address, and port */
+            /*     "http://example.com:8080/" */
+            /*     "http://[::1]:443/"        */
+            if (XSTRNCMP(url, "http://", 7) == 0) {
+                cur = 7;
+            } else cur = 0;
+    
+            i = 0;
+            if (url[cur] == '[') {
+                cur++;
+                /* copy until ']' */
+                while (url[cur] != 0 && url[cur] != ']' && cur < urlSz) {
+                    outName[i++] = url[cur++];
+                }
+                cur++; /* skip ']' */
+            }
+            else {
+                while (url[cur] != 0 && url[cur] != ':' &&
+                                               url[cur] != '/' && cur < urlSz) {
+                    outName[i++] = url[cur++];
+                }
+            }
+            outName[i] = 0;
+            /* Need to pick out the path after the domain name */
+    
+            if (cur < urlSz && url[cur] == ':') {
+                char port[6];
+                int j;
+                word32 bigPort = 0;
+                i = 0;
+                cur++;
+                while (cur < urlSz && url[cur] != 0 && url[cur] != '/' &&
+                        i < 6) {
+                    port[i++] = url[cur++];
+                }
+    
+                for (j = 0; j < i; j++) {
+                    if (port[j] < '0' || port[j] > '9') return -1;
+                    bigPort = (bigPort * 10) + (port[j] - '0');
+                }
+                *outPort = (word16)bigPort;
+            }
+            else
+                *outPort = 80;
+    
+            if (cur < urlSz && url[cur] == '/') {
+                i = 0;
+                while (cur < urlSz && url[cur] != 0 && i < 80) {
+                    outPath[i++] = url[cur++];
+                }
+                outPath[i] = 0;
+            }
+            else {
+                outPath[0] = '/';
+                outPath[1] = 0;
+            }
+            result = 0;
+        }
+    }
+
+    return result;
+}
+
+
+/* return: >0 OCSP Response Size
+ *         -1 error */
+static int process_http_response(int sfd, byte** respBuf,
+                                                  byte* httpBuf, int httpBufSz)
+{
+    int result;
+    int len = 0;
+    char *start, *end;
+    byte *recvBuf = NULL;
+    int recvBufSz = 0;
+    enum phr_state { phr_init, phr_http_start, phr_have_length,
+                     phr_have_type, phr_wait_end, phr_http_end
+    } state = phr_init;
+
+    start = end = NULL;
+    do {
+        if (end == NULL) {
+            result = (int)recv(sfd, (char*)httpBuf+len, httpBufSz-len-1, 0);
+            if (result > 0) {
+                len += result;
+                start = (char*)httpBuf;
+                start[len] = 0;
+            }
+            else {
+                WOLFSSL_MSG("process_http_response recv http from peer failed");
+                return -1;
+            }
+        }
+        end = XSTRSTR(start, "\r\n");
+
+        if (end == NULL) {
+            if (len != 0)
+                XMEMMOVE(httpBuf, start, len);
+            start = end = NULL;
+        }
+        else if (end == start) {
+            if (state == phr_wait_end) {
+                state = phr_http_end;
+                len -= 2;
+                start += 2;
+             }
+             else {
+                WOLFSSL_MSG("process_http_response header ended early");
+                return -1;
+             }
+        }
+        else {
+            *end = 0;
+            len -= (int)(end - start) + 2;
+                /* adjust len to remove the first line including the /r/n */
+
+            if (XSTRNCASECMP(start, "HTTP/1", 6) == 0) {
+                start += 9;
+                if (XSTRNCASECMP(start, "200 OK", 6) != 0 ||
+                                                           state != phr_init) {
+                    WOLFSSL_MSG("process_http_response not OK");
+                    return -1;
+                }
+                state = phr_http_start;
+            }
+            else if (XSTRNCASECMP(start, "Content-Type:", 13) == 0) {
+                start += 13;
+                while (*start == ' ' && *start != '\0') start++;
+                if (XSTRNCASECMP(start, "application/ocsp-response", 25) != 0) {
+                    WOLFSSL_MSG("process_http_response not ocsp-response");
+                    return -1;
+                }
+                
+                if (state == phr_http_start) state = phr_have_type;
+                else if (state == phr_have_length) state = phr_wait_end;
+                else {
+                    WOLFSSL_MSG("process_http_response type invalid state");
+                    return -1;
+                }
+            }
+            else if (XSTRNCASECMP(start, "Content-Length:", 15) == 0) {
+                start += 15;
+                while (*start == ' ' && *start != '\0') start++;
+                recvBufSz = atoi(start);
+
+                if (state == phr_http_start) state = phr_have_length;
+                else if (state == phr_have_type) state = phr_wait_end;
+                else {
+                    WOLFSSL_MSG("process_http_response length invalid state");
+                    return -1;
+                }
+            }
+            
+            start = end + 2;
+        }
+    } while (state != phr_http_end);
+
+    recvBuf = (byte*)XMALLOC(recvBufSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
+    if (recvBuf == NULL) {
+        WOLFSSL_MSG("process_http_response couldn't create response buffer");
+        return -1;
+    }
+
+    /* copy the remainder of the httpBuf into the respBuf */
+    if (len != 0)
+        XMEMCPY(recvBuf, start, len);
+
+    /* receive the OCSP response data */
+    do {
+        result = (int)recv(sfd, (char*)recvBuf+len, recvBufSz-len, 0);
+        if (result > 0)
+            len += result;
+        else {
+            WOLFSSL_MSG("process_http_response recv ocsp from peer failed");
+            return -1;
+        }
+    } while (len != recvBufSz);
+
+    *respBuf = recvBuf;
+    return recvBufSz;
+}
+
+
+#define SCRATCH_BUFFER_SIZE 512
+
+int EmbedOcspLookup(void* ctx, const char* url, int urlSz,
+                        byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf)
+{
+    SOCKET_T sfd = 0;
+    word16   port;
+    int      ret = -1;
+#ifdef WOLFSSL_SMALL_STACK
+    char*    path;
+    char*    domainName;
+#else
+    char     path[80];
+    char     domainName[80];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    path = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (path == NULL)
+        return -1;
+    
+    domainName = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (domainName == NULL) {
+        XFREE(path, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return -1;
+    }
+#endif
+
+    (void)ctx;
+
+    if (ocspReqBuf == NULL || ocspReqSz == 0) {
+        WOLFSSL_MSG("OCSP request is required for lookup");
+    }
+    else if (ocspRespBuf == NULL) {
+        WOLFSSL_MSG("Cannot save OCSP response");
+    }
+    else if (decode_url(url, urlSz, domainName, path, &port) < 0) {
+        WOLFSSL_MSG("Unable to decode OCSP URL");
+    }
+    else {
+        /* Note, the library uses the EmbedOcspRespFree() callback to
+         * free this buffer. */
+        int   httpBufSz = SCRATCH_BUFFER_SIZE;
+        byte* httpBuf   = (byte*)XMALLOC(httpBufSz, NULL, 
+                                                        DYNAMIC_TYPE_IN_BUFFER);
+
+        if (httpBuf == NULL) {
+            WOLFSSL_MSG("Unable to create OCSP response buffer");
+        }
+        else {
+            httpBufSz = build_http_request(domainName, path, ocspReqSz,
+                                                            httpBuf, httpBufSz);
+
+            if ((tcp_connect(&sfd, domainName, port) != 0) || (sfd <= 0)) {
+                WOLFSSL_MSG("OCSP Responder connection failed");
+            }
+            else if ((int)send(sfd, (char*)httpBuf, httpBufSz, 0) !=
+                                                                    httpBufSz) {
+                WOLFSSL_MSG("OCSP http request failed");
+            }
+            else if ((int)send(sfd, (char*)ocspReqBuf, ocspReqSz, 0) !=
+                                                                    ocspReqSz) {
+                WOLFSSL_MSG("OCSP ocsp request failed");
+            }
+            else {
+                ret = process_http_response(sfd, ocspRespBuf, httpBuf,
+                                                           SCRATCH_BUFFER_SIZE);
+            }
+
+            close(sfd);
+            XFREE(httpBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(path,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(domainName, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+void EmbedOcspRespFree(void* ctx, byte *resp)
+{
+    (void)ctx;
+
+    if (resp)
+        XFREE(resp, NULL, DYNAMIC_TYPE_IN_BUFFER);
+}
+
+
+#endif
+
+#endif /* WOLFSSL_USER_IO */
+
+WOLFSSL_API void wolfSSL_SetIORecv(WOLFSSL_CTX *ctx, CallbackIORecv CBIORecv)
+{
+    ctx->CBIORecv = CBIORecv;
+}
+
+
+WOLFSSL_API void wolfSSL_SetIOSend(WOLFSSL_CTX *ctx, CallbackIOSend CBIOSend)
+{
+    ctx->CBIOSend = CBIOSend;
+}
+
+
+WOLFSSL_API void wolfSSL_SetIOReadCtx(WOLFSSL* ssl, void *rctx)
+{
+	ssl->IOCB_ReadCtx = rctx;
+}
+
+
+WOLFSSL_API void wolfSSL_SetIOWriteCtx(WOLFSSL* ssl, void *wctx)
+{
+	ssl->IOCB_WriteCtx = wctx;
+}
+
+
+WOLFSSL_API void* wolfSSL_GetIOReadCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->IOCB_ReadCtx;
+
+    return NULL;
+}
+
+
+WOLFSSL_API void* wolfSSL_GetIOWriteCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->IOCB_WriteCtx;
+
+    return NULL;
+}
+
+
+WOLFSSL_API void wolfSSL_SetIOReadFlags(WOLFSSL* ssl, int flags)
+{
+    ssl->rflags = flags; 
+}
+
+
+WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags)
+{
+    ssl->wflags = flags;
+}
+
+
+#ifdef WOLFSSL_DTLS
+
+WOLFSSL_API void wolfSSL_CTX_SetGenCookie(WOLFSSL_CTX* ctx, CallbackGenCookie cb)
+{
+    ctx->CBIOCookie = cb;
+}
+
+
+WOLFSSL_API void wolfSSL_SetCookieCtx(WOLFSSL* ssl, void *ctx)
+{
+	ssl->IOCB_CookieCtx = ctx;
+}
+
+
+WOLFSSL_API void* wolfSSL_GetCookieCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+	    return ssl->IOCB_CookieCtx;
+
+    return NULL;
+}
+
+#endif /* WOLFSSL_DTLS */
+
+
+#ifdef HAVE_NETX
+
+/* The NetX receive callback
+ *  return :  bytes read, or error
+ */
+int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
+{
+    NetX_Ctx* nxCtx = (NetX_Ctx*)ctx;
+    ULONG left;
+    ULONG total;
+    ULONG copied = 0;
+    UINT  status;
+
+    if (nxCtx == NULL || nxCtx->nxSocket == NULL) {
+        WOLFSSL_MSG("NetX Recv NULL parameters");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    if (nxCtx->nxPacket == NULL) {
+        status = nx_tcp_socket_receive(nxCtx->nxSocket, &nxCtx->nxPacket,
+                                       nxCtx->nxWait);
+        if (status != NX_SUCCESS) {
+            WOLFSSL_MSG("NetX Recv receive error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+    }
+
+    if (nxCtx->nxPacket) {
+        status = nx_packet_length_get(nxCtx->nxPacket, &total);
+        if (status != NX_SUCCESS) {
+            WOLFSSL_MSG("NetX Recv length get error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+
+        left = total - nxCtx->nxOffset;
+        status = nx_packet_data_extract_offset(nxCtx->nxPacket, nxCtx->nxOffset,
+                                               buf, sz, &copied);
+        if (status != NX_SUCCESS) {
+            WOLFSSL_MSG("NetX Recv data extract offset error");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+        }
+
+        nxCtx->nxOffset += copied;
+
+        if (copied == left) {
+            WOLFSSL_MSG("NetX Recv Drained packet");
+            nx_packet_release(nxCtx->nxPacket);
+            nxCtx->nxPacket = NULL;
+            nxCtx->nxOffset = 0;
+        }
+    }
+
+    return copied;
+}
+
+
+/* The NetX send callback
+ *  return : bytes sent, or error
+ */
+int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx)
+{
+    NetX_Ctx*       nxCtx = (NetX_Ctx*)ctx;
+    NX_PACKET*      packet;
+    NX_PACKET_POOL* pool;   /* shorthand */
+    UINT            status;
+
+    if (nxCtx == NULL || nxCtx->nxSocket == NULL) {
+        WOLFSSL_MSG("NetX Send NULL parameters");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    pool = nxCtx->nxSocket->nx_tcp_socket_ip_ptr->nx_ip_default_packet_pool;
+    status = nx_packet_allocate(pool, &packet, NX_TCP_PACKET,
+                                nxCtx->nxWait);
+    if (status != NX_SUCCESS) {
+        WOLFSSL_MSG("NetX Send packet alloc error");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    status = nx_packet_data_append(packet, buf, sz, pool, nxCtx->nxWait);
+    if (status != NX_SUCCESS) {
+        nx_packet_release(packet);
+        WOLFSSL_MSG("NetX Send data append error");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    status = nx_tcp_socket_send(nxCtx->nxSocket, packet, nxCtx->nxWait);
+    if (status != NX_SUCCESS) {
+        nx_packet_release(packet);
+        WOLFSSL_MSG("NetX Send socket send error");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    return sz;
+}
+
+
+/* like set_fd, but for default NetX context */
+void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxSocket, ULONG waitOption)
+{
+    if (ssl) {
+        ssl->nxCtx.nxSocket = nxSocket;
+        ssl->nxCtx.nxWait   = waitOption;
+    }
+}
+
+#endif /* HAVE_NETX */
+#endif /* WOLFCRYPT_ONLY */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/src/keys.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/src/keys.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/src/keys.c	(revision 164)
@@ -0,0 +1,2851 @@
+/* keys.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Name change compatibility layer no longer needs to be included here */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLFCRYPT_ONLY
+
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+#if defined(SHOW_SECRETS) || defined(CHACHA_AEAD_TEST)
+    #ifdef FREESCALE_MQX
+        #if MQX_USE_IO_OLD
+            #include <fio.h>
+        #else
+            #include <nio.h>
+        #endif
+    #else
+        #include <stdio.h>
+    #endif
+#endif
+
+
+int SetCipherSpecs(WOLFSSL* ssl)
+{
+#ifndef NO_WOLFSSL_CLIENT
+    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+        /* server side verified before SetCipherSpecs call */
+        if (VerifyClientSuite(ssl) != 1) {
+            WOLFSSL_MSG("SetCipherSpecs() client has an unusuable suite");
+            return UNSUPPORTED_SUITE;
+        }
+    }
+#endif /* NO_WOLFSSL_CLIENT */
+
+    /* Chacha extensions, 0xcc */
+    if (ssl->options.cipherSuite0 == CHACHA_BYTE) {
+    
+    switch (ssl->options.cipherSuite) {
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+        ssl->specs.bulk_cipher_algorithm = wolfssl_chacha;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CHACHA20_256_KEY_SIZE;
+        ssl->specs.block_size            = CHACHA20_BLOCK_SIZE;
+        ssl->specs.iv_size               = CHACHA20_IV_SIZE;
+        ssl->specs.aead_mac_size         = POLY1305_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+    case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
+        ssl->specs.bulk_cipher_algorithm = wolfssl_chacha;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CHACHA20_256_KEY_SIZE;
+        ssl->specs.block_size            = CHACHA20_BLOCK_SIZE;
+        ssl->specs.iv_size               = CHACHA20_IV_SIZE;
+        ssl->specs.aead_mac_size         = POLY1305_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+        ssl->specs.bulk_cipher_algorithm = wolfssl_chacha;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CHACHA20_256_KEY_SIZE;
+        ssl->specs.block_size            = CHACHA20_BLOCK_SIZE;
+        ssl->specs.iv_size               = CHACHA20_IV_SIZE;
+        ssl->specs.aead_mac_size         = POLY1305_AUTH_SZ;
+
+        break;
+#endif
+    default:
+        WOLFSSL_MSG("Unsupported cipher suite, SetCipherSpecs ChaCha");
+        return UNSUPPORTED_SUITE;
+    }
+    }
+
+    /* ECC extensions, or AES-CCM */
+    if (ssl->options.cipherSuite0 == ECC_BYTE) {
+    
+    switch (ssl->options.cipherSuite) {
+
+#ifdef HAVE_ECC
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+    break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+    break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+    break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+    break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+    break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+    break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+    break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+    break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+    case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_triple_des;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = DES3_KEY_SIZE;
+        ssl->specs.block_size            = DES_BLOCK_SIZE;
+        ssl->specs.iv_size               = DES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+    case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_triple_des;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = DES3_KEY_SIZE;
+        ssl->specs.block_size            = DES_BLOCK_SIZE;
+        ssl->specs.iv_size               = DES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+    case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rc4;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = RC4_KEY_SIZE;
+        ssl->specs.iv_size               = 0;
+        ssl->specs.block_size            = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
+    case TLS_ECDH_RSA_WITH_RC4_128_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rc4;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = RC4_KEY_SIZE;
+        ssl->specs.iv_size               = 0;
+        ssl->specs.block_size            = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+    case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_triple_des;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = DES3_KEY_SIZE;
+        ssl->specs.block_size            = DES_BLOCK_SIZE;
+        ssl->specs.iv_size               = DES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+    case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_triple_des;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = DES3_KEY_SIZE;
+        ssl->specs.block_size            = DES_BLOCK_SIZE;
+        ssl->specs.iv_size               = DES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+    case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rc4;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = RC4_KEY_SIZE;
+        ssl->specs.iv_size               = 0;
+        ssl->specs.block_size            = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+    case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rc4;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = RC4_KEY_SIZE;
+        ssl->specs.iv_size               = 0;
+        ssl->specs.block_size            = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+    case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+    case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+    case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+    case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+    case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+    case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+    case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+    case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 1;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+    case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_8_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
+    case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = ecc_diffie_hellman_kea;
+        ssl->specs.sig_algo              = ecc_dsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_8_AUTH_SZ;
+
+        break;
+#endif
+#endif /* HAVE_ECC */
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
+    case TLS_RSA_WITH_AES_128_CCM_8 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_8_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
+    case TLS_RSA_WITH_AES_256_CCM_8 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_8_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
+    case TLS_PSK_WITH_AES_128_CCM_8 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_8_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
+    case TLS_PSK_WITH_AES_256_CCM_8 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_8_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
+    case TLS_PSK_WITH_AES_128_CCM :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_16_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
+    case TLS_PSK_WITH_AES_256_CCM :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_16_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
+    case TLS_DHE_PSK_WITH_AES_128_CCM :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_16_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
+    case TLS_DHE_PSK_WITH_AES_256_CCM :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_ccm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_CCM_16_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+    default:
+        WOLFSSL_MSG("Unsupported cipher suite, SetCipherSpecs ECC");
+        return UNSUPPORTED_SUITE;
+    }   /* switch */
+    }   /* if     */
+    if (ssl->options.cipherSuite0 != ECC_BYTE && 
+            ssl->options.cipherSuite0 != CHACHA_BYTE) {   /* normal suites */
+    switch (ssl->options.cipherSuite) {
+
+#ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
+    case SSL_RSA_WITH_RC4_128_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rc4;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = RC4_KEY_SIZE;
+        ssl->specs.iv_size               = 0;
+        ssl->specs.block_size            = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
+    case TLS_NTRU_RSA_WITH_RC4_128_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rc4;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ntru_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = RC4_KEY_SIZE;
+        ssl->specs.iv_size               = 0;
+        ssl->specs.block_size            = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
+    case SSL_RSA_WITH_RC4_128_MD5 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rc4;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = md5_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = MD5_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_MD5;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = RC4_KEY_SIZE;
+        ssl->specs.iv_size               = 0;
+        ssl->specs.block_size            = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
+    case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_triple_des;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = DES3_KEY_SIZE;
+        ssl->specs.block_size            = DES_BLOCK_SIZE;
+        ssl->specs.iv_size               = DES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
+    case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_triple_des;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ntru_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = DES3_KEY_SIZE;
+        ssl->specs.block_size            = DES_BLOCK_SIZE;
+        ssl->specs.iv_size               = DES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
+    case TLS_RSA_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
+    case TLS_RSA_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_SHA
+    case TLS_RSA_WITH_NULL_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
+    case TLS_RSA_WITH_NULL_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
+    case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ntru_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
+    case TLS_RSA_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
+    case TLS_RSA_WITH_AES_256_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
+    case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = ntru_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
+    case TLS_PSK_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
+    case TLS_PSK_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+    case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+    case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
+    case TLS_PSK_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
+    case TLS_PSK_WITH_AES_256_CBC_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+    case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+    case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
+    case TLS_PSK_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
+    case TLS_PSK_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
+    case TLS_PSK_WITH_NULL_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
+    case TLS_PSK_WITH_NULL_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_PSK_WITH_NULL_SHA
+    case TLS_PSK_WITH_NULL_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
+    case TLS_DHE_PSK_WITH_NULL_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
+    case TLS_DHE_PSK_WITH_NULL_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = dhe_psk_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = 0;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = 0;
+
+        ssl->options.usingPSK_cipher     = 1;
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
+    case TLS_RSA_WITH_HC_128_MD5 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_hc128;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = md5_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = MD5_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_MD5;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = HC_128_KEY_SIZE;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = HC_128_IV_SIZE;
+
+        break;
+#endif
+            
+#ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
+        case TLS_RSA_WITH_HC_128_SHA :
+            ssl->specs.bulk_cipher_algorithm = wolfssl_hc128;
+            ssl->specs.cipher_type           = stream;
+            ssl->specs.mac_algorithm         = sha_mac;
+            ssl->specs.kea                   = rsa_kea;
+            ssl->specs.sig_algo              = rsa_sa_algo;
+            ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+            ssl->specs.pad_size              = PAD_SHA;
+            ssl->specs.static_ecdh           = 0;
+            ssl->specs.key_size              = HC_128_KEY_SIZE;
+            ssl->specs.block_size            = 0;
+            ssl->specs.iv_size               = HC_128_IV_SIZE;
+            
+            break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
+        case TLS_RSA_WITH_HC_128_B2B256:
+            ssl->specs.bulk_cipher_algorithm = wolfssl_hc128;
+            ssl->specs.cipher_type           = stream;
+            ssl->specs.mac_algorithm         = blake2b_mac;
+            ssl->specs.kea                   = rsa_kea;
+            ssl->specs.sig_algo              = rsa_sa_algo;
+            ssl->specs.hash_size             = BLAKE2B_256;
+            ssl->specs.pad_size              = PAD_SHA;
+            ssl->specs.static_ecdh           = 0;
+            ssl->specs.key_size              = HC_128_KEY_SIZE;
+            ssl->specs.block_size            = 0;
+            ssl->specs.iv_size               = HC_128_IV_SIZE;
+            
+            break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
+        case TLS_RSA_WITH_AES_128_CBC_B2B256:
+            ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+            ssl->specs.cipher_type           = block;
+            ssl->specs.mac_algorithm         = blake2b_mac;
+            ssl->specs.kea                   = rsa_kea;
+            ssl->specs.sig_algo              = rsa_sa_algo;
+            ssl->specs.hash_size             = BLAKE2B_256;
+            ssl->specs.pad_size              = PAD_SHA;
+            ssl->specs.static_ecdh           = 0;
+            ssl->specs.key_size              = AES_128_KEY_SIZE;
+            ssl->specs.iv_size               = AES_IV_SIZE;
+            ssl->specs.block_size            = AES_BLOCK_SIZE;
+            
+            break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
+        case TLS_RSA_WITH_AES_256_CBC_B2B256:
+            ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+            ssl->specs.cipher_type           = block;
+            ssl->specs.mac_algorithm         = blake2b_mac;
+            ssl->specs.kea                   = rsa_kea;
+            ssl->specs.sig_algo              = rsa_sa_algo;
+            ssl->specs.hash_size             = BLAKE2B_256;
+            ssl->specs.pad_size              = PAD_SHA;
+            ssl->specs.static_ecdh           = 0;
+            ssl->specs.key_size              = AES_256_KEY_SIZE;
+            ssl->specs.iv_size               = AES_IV_SIZE;
+            ssl->specs.block_size            = AES_BLOCK_SIZE;
+            
+            break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
+    case TLS_RSA_WITH_RABBIT_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_rabbit;
+        ssl->specs.cipher_type           = stream;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = RABBIT_KEY_SIZE;
+        ssl->specs.block_size            = 0;
+        ssl->specs.iv_size               = RABBIT_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
+    case TLS_RSA_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
+    case TLS_RSA_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+    case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+    case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes_gcm;
+        ssl->specs.cipher_type           = aead;
+        ssl->specs.mac_algorithm         = sha384_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA384_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_256_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AEAD_IMP_IV_SZ;
+        ssl->specs.aead_mac_size         = AES_GCM_AUTH_SZ;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+    case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_128_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+    
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+    case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_256_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+    case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_128_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+    case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = rsa_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_256_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+    case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_128_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+    case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_256_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+    case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_128_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+    case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_camellia;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha256_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = rsa_sa_algo;
+        ssl->specs.hash_size             = SHA256_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = CAMELLIA_256_KEY_SIZE;
+        ssl->specs.block_size            = CAMELLIA_BLOCK_SIZE;
+        ssl->specs.iv_size               = CAMELLIA_IV_SIZE;
+
+        break;
+#endif
+
+#ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
+    case TLS_DH_anon_WITH_AES_128_CBC_SHA :
+        ssl->specs.bulk_cipher_algorithm = wolfssl_aes;
+        ssl->specs.cipher_type           = block;
+        ssl->specs.mac_algorithm         = sha_mac;
+        ssl->specs.kea                   = diffie_hellman_kea;
+        ssl->specs.sig_algo              = anonymous_sa_algo;
+        ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+        ssl->specs.pad_size              = PAD_SHA;
+        ssl->specs.static_ecdh           = 0;
+        ssl->specs.key_size              = AES_128_KEY_SIZE;
+        ssl->specs.block_size            = AES_BLOCK_SIZE;
+        ssl->specs.iv_size               = AES_IV_SIZE;
+
+        ssl->options.usingAnon_cipher    = 1;
+        break;
+#endif
+
+#ifdef BUILD_SSL_RSA_WITH_IDEA_CBC_SHA
+        case SSL_RSA_WITH_IDEA_CBC_SHA :
+            ssl->specs.bulk_cipher_algorithm = wolfssl_idea;
+            ssl->specs.cipher_type           = block;
+            ssl->specs.mac_algorithm         = sha_mac;
+            ssl->specs.kea                   = rsa_kea;
+            ssl->specs.sig_algo              = rsa_sa_algo;
+            ssl->specs.hash_size             = SHA_DIGEST_SIZE;
+            ssl->specs.pad_size              = PAD_SHA;
+            ssl->specs.static_ecdh           = 0;
+            ssl->specs.key_size              = IDEA_KEY_SIZE;
+            ssl->specs.block_size            = IDEA_BLOCK_SIZE;
+            ssl->specs.iv_size               = IDEA_IV_SIZE;
+            
+            break;
+#endif
+
+    default:
+        WOLFSSL_MSG("Unsupported cipher suite, SetCipherSpecs");
+        return UNSUPPORTED_SUITE;
+    }  /* switch */
+    }  /* if ECC / Normal suites else */
+
+    /* set TLS if it hasn't been turned off */
+    if (ssl->version.major == 3 && ssl->version.minor >= 1) {
+#ifndef NO_TLS
+        ssl->options.tls = 1;
+        ssl->hmac = TLS_hmac;
+        if (ssl->version.minor >= 2)
+            ssl->options.tls1_1 = 1;
+#endif
+    }
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls)
+        ssl->hmac = TLS_hmac;
+#endif
+
+    return 0;
+}
+
+
+enum KeyStuff {
+    MASTER_ROUNDS = 3,
+    PREFIX        = 3,     /* up to three letters for master prefix */
+    KEY_PREFIX    = 7      /* up to 7 prefix letters for key rounds */
+
+
+};
+
+#ifndef NO_OLD_TLS
+/* true or false, zero for error */
+static int SetPrefix(byte* sha_input, int idx)
+{
+    switch (idx) {
+    case 0:
+        XMEMCPY(sha_input, "A", 1);
+        break;
+    case 1:
+        XMEMCPY(sha_input, "BB", 2);
+        break;
+    case 2:
+        XMEMCPY(sha_input, "CCC", 3);
+        break;
+    case 3:
+        XMEMCPY(sha_input, "DDDD", 4);
+        break;
+    case 4:
+        XMEMCPY(sha_input, "EEEEE", 5);
+        break;
+    case 5:
+        XMEMCPY(sha_input, "FFFFFF", 6);
+        break;
+    case 6:
+        XMEMCPY(sha_input, "GGGGGGG", 7);
+        break;
+    default:
+        WOLFSSL_MSG("Set Prefix error, bad input");
+        return 0; 
+    }
+    return 1;
+}
+#endif
+
+
+static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
+                   int side, void* heap, int devId)
+{
+#ifdef BUILD_ARC4
+    word32 sz = specs->key_size;
+    if (specs->bulk_cipher_algorithm == wolfssl_rc4) {
+        if (enc && enc->arc4 == NULL)
+            enc->arc4 = (Arc4*)XMALLOC(sizeof(Arc4), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->arc4 == NULL)
+            return MEMORY_E;
+        if (dec && dec->arc4 == NULL)
+            dec->arc4 = (Arc4*)XMALLOC(sizeof(Arc4), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->arc4 == NULL)
+            return MEMORY_E;
+#ifdef HAVE_CAVIUM
+        if (devId != NO_CAVIUM_DEVICE) {
+            if (enc) {
+                if (Arc4InitCavium(enc->arc4, devId) != 0) {
+                    WOLFSSL_MSG("Arc4InitCavium failed in SetKeys");
+                    return CAVIUM_INIT_E;
+                }
+            }
+            if (dec) {
+                if (Arc4InitCavium(dec->arc4, devId) != 0) {
+                    WOLFSSL_MSG("Arc4InitCavium failed in SetKeys");
+                    return CAVIUM_INIT_E;
+                }
+            }
+        }
+#endif
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc)
+                wc_Arc4SetKey(enc->arc4, keys->client_write_key, sz);
+            if (dec)
+                wc_Arc4SetKey(dec->arc4, keys->server_write_key, sz);
+        }
+        else {
+            if (enc)
+                wc_Arc4SetKey(enc->arc4, keys->server_write_key, sz);
+            if (dec)
+                wc_Arc4SetKey(dec->arc4, keys->client_write_key, sz);
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif
+
+    
+#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
+    if (specs->bulk_cipher_algorithm == wolfssl_chacha) {
+        int chachaRet;
+        if (enc && enc->chacha == NULL)
+            enc->chacha =
+                    (ChaCha*)XMALLOC(sizeof(ChaCha), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->chacha == NULL)
+            return MEMORY_E;
+        if (dec && dec->chacha == NULL)
+            dec->chacha =
+                    (ChaCha*)XMALLOC(sizeof(ChaCha), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->chacha == NULL)
+            return MEMORY_E;
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                chachaRet = wc_Chacha_SetKey(enc->chacha, keys->client_write_key,
+                                          specs->key_size);
+                XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV,
+                        AEAD_IMP_IV_SZ);
+                if (chachaRet != 0) return chachaRet;
+            }
+            if (dec) {
+                chachaRet = wc_Chacha_SetKey(dec->chacha, keys->server_write_key,
+                                          specs->key_size);
+                XMEMCPY(keys->aead_dec_imp_IV, keys->server_write_IV,
+                        AEAD_IMP_IV_SZ);
+                if (chachaRet != 0) return chachaRet;
+            }
+        }
+        else {
+            if (enc) {
+                chachaRet = wc_Chacha_SetKey(enc->chacha, keys->server_write_key,
+                                          specs->key_size);
+                XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV,
+                        AEAD_IMP_IV_SZ);
+                if (chachaRet != 0) return chachaRet;
+            }
+            if (dec) {
+                chachaRet = wc_Chacha_SetKey(dec->chacha, keys->client_write_key,
+                                          specs->key_size);
+                XMEMCPY(keys->aead_dec_imp_IV, keys->client_write_IV,
+                        AEAD_IMP_IV_SZ);
+                if (chachaRet != 0) return chachaRet;
+            }
+        }
+
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif
+
+#ifdef HAVE_HC128
+    if (specs->bulk_cipher_algorithm == wolfssl_hc128) {
+        int hcRet;
+        if (enc && enc->hc128 == NULL)
+            enc->hc128 =
+                      (HC128*)XMALLOC(sizeof(HC128), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->hc128 == NULL)
+            return MEMORY_E;
+        if (dec && dec->hc128 == NULL)
+            dec->hc128 =
+                      (HC128*)XMALLOC(sizeof(HC128), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->hc128 == NULL)
+            return MEMORY_E;
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                hcRet = wc_Hc128_SetKey(enc->hc128, keys->client_write_key,
+                                     keys->client_write_IV);
+                if (hcRet != 0) return hcRet;
+            }
+            if (dec) {
+                hcRet = wc_Hc128_SetKey(dec->hc128, keys->server_write_key,
+                                     keys->server_write_IV);
+                if (hcRet != 0) return hcRet;
+            }
+        }
+        else {
+            if (enc) {
+                hcRet = wc_Hc128_SetKey(enc->hc128, keys->server_write_key,
+                                     keys->server_write_IV);
+                if (hcRet != 0) return hcRet;
+            }
+            if (dec) {
+                hcRet = wc_Hc128_SetKey(dec->hc128, keys->client_write_key,
+                                     keys->client_write_IV);
+                if (hcRet != 0) return hcRet;
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif
+    
+#ifdef BUILD_RABBIT
+    if (specs->bulk_cipher_algorithm == wolfssl_rabbit) {
+        int rabRet;
+        if (enc && enc->rabbit == NULL)
+            enc->rabbit =
+                    (Rabbit*)XMALLOC(sizeof(Rabbit), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->rabbit == NULL)
+            return MEMORY_E;
+        if (dec && dec->rabbit == NULL)
+            dec->rabbit =
+                    (Rabbit*)XMALLOC(sizeof(Rabbit), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->rabbit == NULL)
+            return MEMORY_E;
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                rabRet = wc_RabbitSetKey(enc->rabbit, keys->client_write_key,
+                                      keys->client_write_IV);
+                if (rabRet != 0) return rabRet;
+            }
+            if (dec) {
+                rabRet = wc_RabbitSetKey(dec->rabbit, keys->server_write_key,
+                                      keys->server_write_IV);
+                if (rabRet != 0) return rabRet;
+            }
+        }
+        else {
+            if (enc) {
+                rabRet = wc_RabbitSetKey(enc->rabbit, keys->server_write_key,
+                                      keys->server_write_IV);
+                if (rabRet != 0) return rabRet;
+            }
+            if (dec) {
+                rabRet = wc_RabbitSetKey(dec->rabbit, keys->client_write_key,
+                                      keys->client_write_IV);
+                if (rabRet != 0) return rabRet;
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif
+    
+#ifdef BUILD_DES3
+    if (specs->bulk_cipher_algorithm == wolfssl_triple_des) {
+        int desRet = 0;
+
+        if (enc && enc->des3 == NULL)
+            enc->des3 = (Des3*)XMALLOC(sizeof(Des3), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->des3 == NULL)
+            return MEMORY_E;
+        if (dec && dec->des3 == NULL)
+            dec->des3 = (Des3*)XMALLOC(sizeof(Des3), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->des3 == NULL)
+            return MEMORY_E;
+#ifdef HAVE_CAVIUM
+        if (devId != NO_CAVIUM_DEVICE) {
+            if (enc) {
+                if (Des3_InitCavium(enc->des3, devId) != 0) {
+                    WOLFSSL_MSG("Des3_InitCavium failed in SetKeys");
+                    return CAVIUM_INIT_E;
+                }
+            }
+            if (dec) {
+                if (Des3_InitCavium(dec->des3, devId) != 0) {
+                    WOLFSSL_MSG("Des3_InitCavium failed in SetKeys");
+                    return CAVIUM_INIT_E;
+                }
+            }
+        }
+#endif
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                desRet = wc_Des3_SetKey(enc->des3, keys->client_write_key,
+                                     keys->client_write_IV, DES_ENCRYPTION);
+                if (desRet != 0) return desRet;
+            }
+            if (dec) {
+                desRet = wc_Des3_SetKey(dec->des3, keys->server_write_key,
+                                     keys->server_write_IV, DES_DECRYPTION);
+                if (desRet != 0) return desRet;
+            }
+        }
+        else {
+            if (enc) {
+                desRet = wc_Des3_SetKey(enc->des3, keys->server_write_key,
+                                     keys->server_write_IV, DES_ENCRYPTION);
+                if (desRet != 0) return desRet;
+            }
+            if (dec) {
+                desRet = wc_Des3_SetKey(dec->des3, keys->client_write_key,
+                                     keys->client_write_IV, DES_DECRYPTION);
+                if (desRet != 0) return desRet;
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif
+
+#ifdef BUILD_AES
+    if (specs->bulk_cipher_algorithm == wolfssl_aes) {
+        int aesRet = 0;
+
+        if (enc && enc->aes == NULL)
+            enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->aes == NULL)
+            return MEMORY_E;
+        if (dec && dec->aes == NULL)
+            dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->aes == NULL)
+            return MEMORY_E;
+#ifdef HAVE_CAVIUM
+        if (devId != NO_CAVIUM_DEVICE) {
+            if (enc) {
+                if (wc_AesInitCavium(enc->aes, devId) != 0) {
+                    WOLFSSL_MSG("AesInitCavium failed in SetKeys");
+                    return CAVIUM_INIT_E;
+                }
+            }
+            if (dec) {
+                if (wc_AesInitCavium(dec->aes, devId) != 0) {
+                    WOLFSSL_MSG("AesInitCavium failed in SetKeys");
+                    return CAVIUM_INIT_E;
+                }
+            }
+        }
+#endif
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                aesRet = wc_AesSetKey(enc->aes, keys->client_write_key,
+                                   specs->key_size, keys->client_write_IV,
+                                   AES_ENCRYPTION);
+                if (aesRet != 0) return aesRet;
+            }
+            if (dec) {
+                aesRet = wc_AesSetKey(dec->aes, keys->server_write_key,
+                                   specs->key_size, keys->server_write_IV,
+                                   AES_DECRYPTION);
+                if (aesRet != 0) return aesRet;
+            }
+        }
+        else {
+            if (enc) {
+                aesRet = wc_AesSetKey(enc->aes, keys->server_write_key,
+                                   specs->key_size, keys->server_write_IV,
+                                   AES_ENCRYPTION);
+                if (aesRet != 0) return aesRet;
+            }
+            if (dec) {
+                aesRet = wc_AesSetKey(dec->aes, keys->client_write_key,
+                                   specs->key_size, keys->client_write_IV,
+                                   AES_DECRYPTION);
+                if (aesRet != 0) return aesRet;
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif
+
+#ifdef BUILD_AESGCM
+    if (specs->bulk_cipher_algorithm == wolfssl_aes_gcm) {
+        int gcmRet;
+
+        if (enc && enc->aes == NULL)
+            enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->aes == NULL)
+            return MEMORY_E;
+        if (dec && dec->aes == NULL)
+            dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->aes == NULL)
+            return MEMORY_E;
+
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                gcmRet = wc_AesGcmSetKey(enc->aes, keys->client_write_key,
+                                      specs->key_size);
+                if (gcmRet != 0) return gcmRet;
+                XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV,
+                        AEAD_IMP_IV_SZ);
+            }
+            if (dec) {
+                gcmRet = wc_AesGcmSetKey(dec->aes, keys->server_write_key,
+                                      specs->key_size);
+                if (gcmRet != 0) return gcmRet;
+                XMEMCPY(keys->aead_dec_imp_IV, keys->server_write_IV,
+                        AEAD_IMP_IV_SZ);
+            }
+        }
+        else {
+            if (enc) {
+                gcmRet = wc_AesGcmSetKey(enc->aes, keys->server_write_key,
+                                      specs->key_size);
+                if (gcmRet != 0) return gcmRet;
+                XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV,
+                        AEAD_IMP_IV_SZ);
+            }
+            if (dec) {
+                gcmRet = wc_AesGcmSetKey(dec->aes, keys->client_write_key,
+                                      specs->key_size);
+                if (gcmRet != 0) return gcmRet;
+                XMEMCPY(keys->aead_dec_imp_IV, keys->client_write_IV,
+                        AEAD_IMP_IV_SZ);
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif
+
+#ifdef HAVE_AESCCM
+    if (specs->bulk_cipher_algorithm == wolfssl_aes_ccm) {
+        if (enc && enc->aes == NULL)
+            enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->aes == NULL)
+            return MEMORY_E;
+        if (dec && dec->aes == NULL)
+            dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->aes == NULL)
+            return MEMORY_E;
+
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                wc_AesCcmSetKey(enc->aes, keys->client_write_key, specs->key_size);
+                XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV,
+                        AEAD_IMP_IV_SZ);
+            }
+            if (dec) {
+                wc_AesCcmSetKey(dec->aes, keys->server_write_key, specs->key_size);
+                XMEMCPY(keys->aead_dec_imp_IV, keys->server_write_IV,
+                        AEAD_IMP_IV_SZ);
+            }
+        }
+        else {
+            if (enc) {
+                wc_AesCcmSetKey(enc->aes, keys->server_write_key, specs->key_size);
+                XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV,
+                        AEAD_IMP_IV_SZ);
+            }
+            if (dec) {
+                wc_AesCcmSetKey(dec->aes, keys->client_write_key, specs->key_size);
+                XMEMCPY(keys->aead_dec_imp_IV, keys->client_write_IV,
+                        AEAD_IMP_IV_SZ);
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif
+
+#ifdef HAVE_CAMELLIA
+    if (specs->bulk_cipher_algorithm == wolfssl_camellia) {
+        int camRet;
+
+        if (enc && enc->cam == NULL)
+            enc->cam =
+                (Camellia*)XMALLOC(sizeof(Camellia), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->cam == NULL)
+            return MEMORY_E;
+
+        if (dec && dec->cam == NULL)
+            dec->cam =
+                (Camellia*)XMALLOC(sizeof(Camellia), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->cam == NULL)
+            return MEMORY_E;
+
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                camRet = wc_CamelliaSetKey(enc->cam, keys->client_write_key,
+                                        specs->key_size, keys->client_write_IV);
+                if (camRet != 0) return camRet;
+            }
+            if (dec) {
+                camRet = wc_CamelliaSetKey(dec->cam, keys->server_write_key,
+                                        specs->key_size, keys->server_write_IV);
+                if (camRet != 0) return camRet;
+            }
+        }
+        else {
+            if (enc) {
+                camRet = wc_CamelliaSetKey(enc->cam, keys->server_write_key,
+                                        specs->key_size, keys->server_write_IV);
+                if (camRet != 0) return camRet;
+            }
+            if (dec) {
+                camRet = wc_CamelliaSetKey(dec->cam, keys->client_write_key,
+                                        specs->key_size, keys->client_write_IV);
+                if (camRet != 0) return camRet;
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif
+
+#ifdef HAVE_IDEA
+    if (specs->bulk_cipher_algorithm == wolfssl_idea) {
+        int ideaRet;
+
+        if (enc && enc->idea == NULL)
+            enc->idea = (Idea*)XMALLOC(sizeof(Idea), heap, DYNAMIC_TYPE_CIPHER);
+        if (enc && enc->idea == NULL)
+            return MEMORY_E;
+
+        if (dec && dec->idea == NULL)
+            dec->idea = (Idea*)XMALLOC(sizeof(Idea), heap, DYNAMIC_TYPE_CIPHER);
+        if (dec && dec->idea == NULL)
+            return MEMORY_E;
+
+        if (side == WOLFSSL_CLIENT_END) {
+            if (enc) {
+                ideaRet = wc_IdeaSetKey(enc->idea, keys->client_write_key,
+                                        specs->key_size, keys->client_write_IV,
+                                        IDEA_ENCRYPTION);
+                if (ideaRet != 0) return ideaRet;
+            }
+            if (dec) {
+                ideaRet = wc_IdeaSetKey(dec->idea, keys->server_write_key,
+                                        specs->key_size, keys->server_write_IV,
+                                        IDEA_DECRYPTION);
+                if (ideaRet != 0) return ideaRet;
+            }
+        }
+        else {
+            if (enc) {
+                ideaRet = wc_IdeaSetKey(enc->idea, keys->server_write_key,
+                                        specs->key_size, keys->server_write_IV,
+                                        IDEA_ENCRYPTION);
+                if (ideaRet != 0) return ideaRet;
+            }
+            if (dec) {
+                ideaRet = wc_IdeaSetKey(dec->idea, keys->client_write_key,
+                                        specs->key_size, keys->client_write_IV,
+                                        IDEA_DECRYPTION);
+                if (ideaRet != 0) return ideaRet;
+            }
+        }
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif
+
+#ifdef HAVE_NULL_CIPHER
+    if (specs->bulk_cipher_algorithm == wolfssl_cipher_null) {
+        if (enc)
+            enc->setup = 1;
+        if (dec)
+            dec->setup = 1;
+    }
+#endif
+
+    if (enc)
+        keys->sequence_number      = 0;
+    if (dec)
+        keys->peer_sequence_number = 0;
+    (void)side;
+    (void)heap;
+    (void)enc;
+    (void)dec;
+    (void)specs;
+    (void)devId;
+
+    return 0;
+}
+
+
+#ifdef HAVE_ONE_TIME_AUTH
+/* set one time authentication keys */
+static int SetAuthKeys(OneTimeAuth* authentication, Keys* keys,
+                       CipherSpecs* specs, void* heap, int devId)
+{
+
+#ifdef HAVE_POLY1305
+        /* set up memory space for poly1305 */
+        if (authentication && authentication->poly1305 == NULL)
+            authentication->poly1305 =
+                (Poly1305*)XMALLOC(sizeof(Poly1305), heap, DYNAMIC_TYPE_CIPHER);
+        if (authentication && authentication->poly1305 == NULL)
+            return MEMORY_E;
+        if (authentication)
+            authentication->setup = 1;
+#endif
+        (void)heap;
+        (void)keys;
+        (void)specs;
+        (void)devId;
+
+        return 0;
+}
+#endif /* HAVE_ONE_TIME_AUTH */
+
+
+/* Set wc_encrypt/wc_decrypt or both sides of key setup
+ * note: use wc_encrypt to avoid shadowing global encrypt
+ * declared in unistd.h
+ */
+int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side)
+{
+    int devId = NO_CAVIUM_DEVICE, ret, copy = 0;
+    Ciphers* wc_encrypt = NULL;
+    Ciphers* wc_decrypt = NULL;
+    Keys*    keys    = &ssl->keys;
+
+    (void)copy;
+
+#ifdef HAVE_CAVIUM
+    devId = ssl->devId;
+#endif
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+    if (ssl->secure_renegotiation && ssl->secure_renegotiation->cache_status) {
+        keys = &ssl->secure_renegotiation->tmp_keys;
+        copy = 1;
+    }
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+    switch (side) {
+        case ENCRYPT_SIDE_ONLY:
+            wc_encrypt = &ssl->encrypt;
+            break;
+
+        case DECRYPT_SIDE_ONLY:
+            wc_decrypt = &ssl->decrypt;
+            break;
+
+        case ENCRYPT_AND_DECRYPT_SIDE:
+            wc_encrypt = &ssl->encrypt;
+            wc_decrypt = &ssl->decrypt;
+            break;
+
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+#ifdef HAVE_ONE_TIME_AUTH
+    if (!ssl->auth.setup && ssl->specs.bulk_cipher_algorithm == wolfssl_chacha){
+        ret = SetAuthKeys(&ssl->auth, keys, &ssl->specs, ssl->heap, devId);
+        if (ret != 0)
+           return ret;
+    }
+#endif
+
+    ret = SetKeys(wc_encrypt, wc_decrypt, keys, &ssl->specs, ssl->options.side,
+                  ssl->heap, devId);
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+    if (copy) {
+        int clientCopy = 0;
+
+        if (ssl->options.side == WOLFSSL_CLIENT_END && wc_encrypt)
+            clientCopy = 1;
+        else if (ssl->options.side == WOLFSSL_SERVER_END && wc_decrypt)
+            clientCopy = 1;
+
+        if (clientCopy) {
+            XMEMCPY(ssl->keys.client_write_MAC_secret,
+                    keys->client_write_MAC_secret, MAX_DIGEST_SIZE);
+            XMEMCPY(ssl->keys.client_write_key,
+                    keys->client_write_key, AES_256_KEY_SIZE);
+            XMEMCPY(ssl->keys.client_write_IV,
+                    keys->client_write_IV, AES_IV_SIZE);
+        } else {
+            XMEMCPY(ssl->keys.server_write_MAC_secret,
+                    keys->server_write_MAC_secret, MAX_DIGEST_SIZE);
+            XMEMCPY(ssl->keys.server_write_key,
+                    keys->server_write_key, AES_256_KEY_SIZE);
+            XMEMCPY(ssl->keys.server_write_IV,
+                    keys->server_write_IV, AES_IV_SIZE);
+        }
+        if (wc_encrypt) {
+            ssl->keys.sequence_number = keys->sequence_number;
+            #ifdef HAVE_AEAD
+                if (ssl->specs.cipher_type == aead) {
+                    /* Initialize the AES-GCM/CCM explicit IV to a zero. */
+                    XMEMCPY(ssl->keys.aead_exp_IV, keys->aead_exp_IV,
+                            AEAD_EXP_IV_SZ);
+
+                    /* Initialize encrypt implicit IV by encrypt side */
+                    if (ssl->options.side == WOLFSSL_CLIENT_END) {
+                        XMEMCPY(ssl->keys.aead_enc_imp_IV,
+                                keys->client_write_IV, AEAD_IMP_IV_SZ);
+                    } else {
+                        XMEMCPY(ssl->keys.aead_enc_imp_IV,
+                                keys->server_write_IV, AEAD_IMP_IV_SZ);
+                    }
+                }
+            #endif
+        }
+        if (wc_decrypt) {
+            ssl->keys.peer_sequence_number = keys->peer_sequence_number;
+            #ifdef HAVE_AEAD
+                if (ssl->specs.cipher_type == aead) {
+                    /* Initialize decrypt implicit IV by decrypt side */
+                    if (ssl->options.side == WOLFSSL_SERVER_END) {
+                        XMEMCPY(ssl->keys.aead_dec_imp_IV,
+                                keys->client_write_IV, AEAD_IMP_IV_SZ);
+                    } else {
+                        XMEMCPY(ssl->keys.aead_dec_imp_IV,
+                                keys->server_write_IV, AEAD_IMP_IV_SZ);
+                    }
+                }
+            #endif
+        }
+        ssl->secure_renegotiation->cache_status++;
+    }
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+    return ret;
+}
+
+
+/* TLS can call too */
+int StoreKeys(WOLFSSL* ssl, const byte* keyData)
+{
+    int sz, i = 0;
+    Keys* keys = &ssl->keys;
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+    if (ssl->secure_renegotiation && ssl->secure_renegotiation->cache_status ==
+                                                            SCR_CACHE_NEEDED) {
+        keys = &ssl->secure_renegotiation->tmp_keys;
+        ssl->secure_renegotiation->cache_status++;
+    }
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+    if (ssl->specs.cipher_type != aead) {
+        sz = ssl->specs.hash_size;
+        XMEMCPY(keys->client_write_MAC_secret,&keyData[i], sz);
+        i += sz;
+        XMEMCPY(keys->server_write_MAC_secret,&keyData[i], sz);
+        i += sz;
+    }
+    sz = ssl->specs.key_size;
+    XMEMCPY(keys->client_write_key, &keyData[i], sz);
+    i += sz;
+    XMEMCPY(keys->server_write_key, &keyData[i], sz);
+    i += sz;
+
+    sz = ssl->specs.iv_size;
+    XMEMCPY(keys->client_write_IV, &keyData[i], sz);
+    i += sz;
+    XMEMCPY(keys->server_write_IV, &keyData[i], sz);
+
+#ifdef HAVE_AEAD
+    if (ssl->specs.cipher_type == aead) {
+        /* Initialize the AES-GCM/CCM explicit IV to a zero. */
+        XMEMSET(keys->aead_exp_IV, 0, AEAD_EXP_IV_SZ);
+    }
+#endif
+
+    return 0;
+}
+
+#ifndef NO_OLD_TLS
+int DeriveKeys(WOLFSSL* ssl)
+{
+    int    length = 2 * ssl->specs.hash_size + 
+                    2 * ssl->specs.key_size  +
+                    2 * ssl->specs.iv_size;
+    int    rounds = (length + MD5_DIGEST_SIZE - 1 ) / MD5_DIGEST_SIZE, i;
+    int    ret = 0;
+    
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  shaOutput;
+    byte*  md5Input;
+    byte*  shaInput;
+    byte*  keyData;
+    Md5*   md5;
+    Sha*   sha;
+#else
+    byte   shaOutput[SHA_DIGEST_SIZE];
+    byte   md5Input[SECRET_LEN + SHA_DIGEST_SIZE];
+    byte   shaInput[KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN];
+    byte   keyData[KEY_PREFIX * MD5_DIGEST_SIZE];
+    Md5    md5[1];
+    Sha    sha[1];
+#endif
+    
+#ifdef WOLFSSL_SMALL_STACK
+    shaOutput = (byte*)XMALLOC(SHA_DIGEST_SIZE, 
+                                            NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    md5Input  = (byte*)XMALLOC(SECRET_LEN + SHA_DIGEST_SIZE,
+                                            NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    shaInput  = (byte*)XMALLOC(KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN,
+                                            NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    keyData   = (byte*)XMALLOC(KEY_PREFIX * MD5_DIGEST_SIZE,
+                                            NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    md5       =  (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    sha       =  (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    
+    if (shaOutput == NULL || md5Input == NULL || shaInput == NULL ||
+        keyData   == NULL || md5      == NULL || sha      == NULL) {
+        if (shaOutput) XFREE(shaOutput, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (md5Input)  XFREE(md5Input,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (shaInput)  XFREE(shaInput,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (keyData)   XFREE(keyData,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (md5)       XFREE(md5,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (sha)       XFREE(sha,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        
+        return MEMORY_E;
+    }
+#endif
+
+    wc_InitMd5(md5);
+
+    ret = wc_InitSha(sha);
+
+    if (ret == 0) {
+        XMEMCPY(md5Input, ssl->arrays->masterSecret, SECRET_LEN);
+
+        for (i = 0; i < rounds; ++i) {
+            int j   = i + 1;
+            int idx = j;
+
+            if (!SetPrefix(shaInput, i)) {
+                ret = PREFIX_ERROR;
+                break;
+            }
+
+            XMEMCPY(shaInput + idx, ssl->arrays->masterSecret, SECRET_LEN);
+            idx += SECRET_LEN;
+            XMEMCPY(shaInput + idx, ssl->arrays->serverRandom, RAN_LEN);
+            idx += RAN_LEN;
+            XMEMCPY(shaInput + idx, ssl->arrays->clientRandom, RAN_LEN);
+
+            wc_ShaUpdate(sha, shaInput, (KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN)
+                                                              - KEY_PREFIX + j);
+            wc_ShaFinal(sha, shaOutput);
+
+            XMEMCPY(md5Input + SECRET_LEN, shaOutput, SHA_DIGEST_SIZE);
+            wc_Md5Update(md5, md5Input, SECRET_LEN + SHA_DIGEST_SIZE);
+            wc_Md5Final(md5, keyData + i * MD5_DIGEST_SIZE);
+        }
+
+        if (ret == 0)
+            ret = StoreKeys(ssl, keyData);
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(shaOutput, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(md5Input,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(shaInput,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(keyData,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(md5,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(sha,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+static int CleanPreMaster(WOLFSSL* ssl)
+{
+    int i, ret, sz = ssl->arrays->preMasterSz;
+
+    for (i = 0; i < sz; i++)
+        ssl->arrays->preMasterSecret[i] = 0;
+
+    ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, sz);
+    if (ret != 0)
+        return ret;
+
+    for (i = 0; i < sz; i++)
+        ssl->arrays->preMasterSecret[i] = 0;
+
+    return 0;
+}
+
+
+/* Create and store the master secret see page 32, 6.1 */
+static int MakeSslMasterSecret(WOLFSSL* ssl)
+{
+    int    i, ret;
+    word32 idx;
+    word32 pmsSz = ssl->arrays->preMasterSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  shaOutput;
+    byte*  md5Input;
+    byte*  shaInput;
+    Md5*   md5;
+    Sha*   sha;
+#else
+    byte   shaOutput[SHA_DIGEST_SIZE];
+    byte   md5Input[ENCRYPT_LEN + SHA_DIGEST_SIZE];
+    byte   shaInput[PREFIX + ENCRYPT_LEN + 2 * RAN_LEN];
+    Md5    md5[1];
+    Sha    sha[1];
+#endif
+
+#ifdef SHOW_SECRETS
+    {
+        word32 j;
+        printf("pre master secret: ");
+        for (j = 0; j < pmsSz; j++)
+            printf("%02x", ssl->arrays->preMasterSecret[j]);
+        printf("\n");
+    }
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    shaOutput = (byte*)XMALLOC(SHA_DIGEST_SIZE,
+                                            NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    md5Input  = (byte*)XMALLOC(ENCRYPT_LEN + SHA_DIGEST_SIZE,
+                                            NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    shaInput  = (byte*)XMALLOC(PREFIX + ENCRYPT_LEN + 2 * RAN_LEN,
+                                            NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    md5       =  (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    sha       =  (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    
+    if (shaOutput == NULL || md5Input == NULL || shaInput == NULL ||
+                             md5      == NULL || sha      == NULL) {
+        if (shaOutput) XFREE(shaOutput, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (md5Input)  XFREE(md5Input,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (shaInput)  XFREE(shaInput,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (md5)       XFREE(md5,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (sha)       XFREE(sha,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        
+        return MEMORY_E;
+    }
+#endif
+
+    wc_InitMd5(md5);
+    
+    ret = wc_InitSha(sha);
+    
+    if (ret == 0) {
+        XMEMCPY(md5Input, ssl->arrays->preMasterSecret, pmsSz);
+
+        for (i = 0; i < MASTER_ROUNDS; ++i) {
+            byte prefix[KEY_PREFIX];      /* only need PREFIX bytes but static */
+            if (!SetPrefix(prefix, i)) {  /* analysis thinks will overrun      */
+                ret = PREFIX_ERROR;
+                break;
+            }
+
+            idx = 0;
+            XMEMCPY(shaInput, prefix, i + 1);
+            idx += i + 1;
+
+            XMEMCPY(shaInput + idx, ssl->arrays->preMasterSecret, pmsSz);
+            idx += pmsSz;
+            XMEMCPY(shaInput + idx, ssl->arrays->clientRandom, RAN_LEN);
+            idx += RAN_LEN;
+            XMEMCPY(shaInput + idx, ssl->arrays->serverRandom, RAN_LEN);
+            idx += RAN_LEN;
+            wc_ShaUpdate(sha, shaInput, idx);
+            wc_ShaFinal(sha, shaOutput);
+
+            idx = pmsSz;  /* preSz */
+            XMEMCPY(md5Input + idx, shaOutput, SHA_DIGEST_SIZE);
+            idx += SHA_DIGEST_SIZE;
+            wc_Md5Update(md5, md5Input, idx);
+            wc_Md5Final(md5, &ssl->arrays->masterSecret[i * MD5_DIGEST_SIZE]);
+        }
+
+#ifdef SHOW_SECRETS
+        {
+            word32 j;
+            printf("master secret: ");
+            for (j = 0; j < SECRET_LEN; j++)
+                printf("%02x", ssl->arrays->masterSecret[j]);
+            printf("\n");
+        }
+#endif
+
+        if (ret == 0)
+            ret = DeriveKeys(ssl);
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(shaOutput, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(md5Input,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(shaInput,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(md5,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(sha,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (ret == 0)
+        ret = CleanPreMaster(ssl);
+    else
+        CleanPreMaster(ssl);
+
+    return ret;
+}
+#endif
+
+
+/* Master wrapper, doesn't use SSL stack space in TLS mode */
+int MakeMasterSecret(WOLFSSL* ssl)
+{
+    /* append secret to premaster : premaster | SerSi | CliSi */
+#ifdef HAVE_QSH
+    word32 offset = 0;
+
+    if (ssl->peerQSHKeyPresent) {
+        offset += ssl->arrays->preMasterSz;
+        ssl->arrays->preMasterSz += ssl->QSH_secret->CliSi->length +
+                                                 ssl->QSH_secret->SerSi->length;
+        /* test and set flag if QSH has been used */
+        if (ssl->QSH_secret->CliSi->length > 0 ||
+                ssl->QSH_secret->SerSi->length > 0)
+            ssl->isQSH = 1;
+
+        /* append secrets to the premaster */
+        if (ssl->QSH_secret->SerSi != NULL) {
+            XMEMCPY(ssl->arrays->preMasterSecret + offset,
+                ssl->QSH_secret->SerSi->buffer, ssl->QSH_secret->SerSi->length);
+        }
+        offset += ssl->QSH_secret->SerSi->length;
+        if (ssl->QSH_secret->CliSi != NULL) {
+            XMEMCPY(ssl->arrays->preMasterSecret + offset,
+                ssl->QSH_secret->CliSi->buffer, ssl->QSH_secret->CliSi->length);
+        }
+
+        /* show secret SerSi and CliSi */
+        #ifdef SHOW_SECRETS
+            word32 j;
+            printf("QSH generated secret material\n");
+            printf("SerSi        : ");
+            for (j = 0; j < ssl->QSH_secret->SerSi->length; j++) {
+                printf("%02x", ssl->QSH_secret->SerSi->buffer[j]);
+            }
+            printf("\n");
+            printf("CliSi        : ");
+            for (j = 0; j < ssl->QSH_secret->CliSi->length; j++) {
+                printf("%02x", ssl->QSH_secret->CliSi->buffer[j]);
+            }
+            printf("\n");
+        #endif
+    }
+#endif
+
+#ifdef NO_OLD_TLS
+    return MakeTlsMasterSecret(ssl);
+#elif !defined(NO_TLS)
+    if (ssl->options.tls) return MakeTlsMasterSecret(ssl);
+#endif
+
+#ifndef NO_OLD_TLS
+    return MakeSslMasterSecret(ssl);
+#endif
+}
+
+#endif /* WOLFCRYPT_ONLY */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/src/ocsp.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/src/ocsp.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/src/ocsp.c	(revision 164)
@@ -0,0 +1,305 @@
+/* ocsp.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+  /* Name change compatibility layer no longer needs to be included here */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLFCRYPT_ONLY
+#ifdef HAVE_OCSP
+
+#include <wolfssl/error-ssl.h>
+#include <wolfssl/ocsp.h>
+#include <wolfssl/internal.h>
+
+
+int InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_ENTER("InitOCSP");
+    XMEMSET(ocsp, 0, sizeof(*ocsp));
+    ocsp->cm = cm;
+    if (InitMutex(&ocsp->ocspLock) != 0)
+        return BAD_MUTEX_E;
+
+    return 0;
+}
+
+
+static int InitOCSP_Entry(OCSP_Entry* ocspe, DecodedCert* cert)
+{
+    WOLFSSL_ENTER("InitOCSP_Entry");
+
+    XMEMSET(ocspe, 0, sizeof(*ocspe));
+    XMEMCPY(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE);
+    XMEMCPY(ocspe->issuerKeyHash, cert->issuerKeyHash, SHA_DIGEST_SIZE);
+
+    return 0;
+}
+
+
+static void FreeOCSP_Entry(OCSP_Entry* ocspe)
+{
+    CertStatus* tmp = ocspe->status;
+
+    WOLFSSL_ENTER("FreeOCSP_Entry");
+
+    while (tmp) {
+        CertStatus* next = tmp->next;
+        XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_STATUS);
+        tmp = next;
+    }
+}
+
+
+void FreeOCSP(WOLFSSL_OCSP* ocsp, int dynamic)
+{
+    OCSP_Entry* tmp = ocsp->ocspList;
+
+    WOLFSSL_ENTER("FreeOCSP");
+
+    while (tmp) {
+        OCSP_Entry* next = tmp->next;
+        FreeOCSP_Entry(tmp);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
+        tmp = next;
+    }
+
+    FreeMutex(&ocsp->ocspLock);
+    if (dynamic)
+        XFREE(ocsp, NULL, DYNAMIC_TYPE_OCSP);
+}
+
+
+static int xstat2err(int stat)
+{
+    switch (stat) {
+        case CERT_GOOD:
+            return 0;
+        case CERT_REVOKED:
+            return OCSP_CERT_REVOKED;
+        default:
+            return OCSP_CERT_UNKNOWN;
+    }
+}
+
+
+int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert)
+{
+    byte* ocspReqBuf = NULL;
+    int ocspReqSz = 2048;
+    byte* ocspRespBuf = NULL;
+    int result = -1;
+    OCSP_Entry* ocspe;
+    CertStatus* certStatus = NULL;
+    const char *url;
+    int urlSz;
+#ifdef WOLFSSL_SMALL_STACK
+    CertStatus* newStatus;
+    OcspRequest* ocspRequest;
+    OcspResponse* ocspResponse;
+#else
+    CertStatus newStatus[1];
+    OcspRequest ocspRequest[1];
+    OcspResponse ocspResponse[1];
+#endif
+
+    WOLFSSL_ENTER("CheckCertOCSP");
+
+    if (LockMutex(&ocsp->ocspLock) != 0) {
+        WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
+        return BAD_MUTEX_E;
+    }
+
+    ocspe = ocsp->ocspList;
+    while (ocspe) {
+        if (XMEMCMP(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0
+            && XMEMCMP(ocspe->issuerKeyHash, cert->issuerKeyHash,
+                                                        SHA_DIGEST_SIZE) == 0)
+            break;
+        else
+            ocspe = ocspe->next;
+    }
+
+    if (ocspe == NULL) {
+        ocspe = (OCSP_Entry*)XMALLOC(sizeof(OCSP_Entry),
+                                                NULL, DYNAMIC_TYPE_OCSP_ENTRY);
+        if (ocspe != NULL) {
+            InitOCSP_Entry(ocspe, cert);
+            ocspe->next = ocsp->ocspList;
+            ocsp->ocspList = ocspe;
+        }
+        else {
+            UnLockMutex(&ocsp->ocspLock);
+            WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
+            return MEMORY_ERROR;
+        }
+    }
+    else {
+        certStatus = ocspe->status;
+        while (certStatus) {
+            if (certStatus->serialSz == cert->serialSz &&
+                 XMEMCMP(certStatus->serial, cert->serial, cert->serialSz) == 0)
+                break;
+            else
+                certStatus = certStatus->next;
+        }
+    }
+
+    if (certStatus != NULL) {
+        if (!ValidateDate(certStatus->thisDate,
+                                        certStatus->thisDateFormat, BEFORE) ||
+            (certStatus->nextDate[0] == 0) ||
+            !ValidateDate(certStatus->nextDate,
+                                        certStatus->nextDateFormat, AFTER)) {
+            WOLFSSL_MSG("\tinvalid status date, looking up cert");
+        }
+        else {
+            result = xstat2err(certStatus->status);
+            UnLockMutex(&ocsp->ocspLock);
+            WOLFSSL_LEAVE("CheckCertOCSP", result);
+            return result;
+        }
+    }
+
+    UnLockMutex(&ocsp->ocspLock);
+
+    if (ocsp->cm->ocspUseOverrideURL) {
+        url = ocsp->cm->ocspOverrideURL;
+        if (url != NULL && url[0] != '\0')
+            urlSz = (int)XSTRLEN(url);
+        else
+            return OCSP_NEED_URL;
+    }
+    else if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
+        url = (const char *)cert->extAuthInfo;
+        urlSz = cert->extAuthInfoSz;
+    }
+    else {
+        /* cert doesn't have extAuthInfo, assuming CERT_GOOD */
+        return 0;
+    }
+
+    ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
+    if (ocspReqBuf == NULL) {
+        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
+        return MEMORY_ERROR;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (newStatus == NULL || ocspRequest == NULL || ocspResponse == NULL) {
+        if (newStatus)    XFREE(newStatus,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (ocspRequest)  XFREE(ocspRequest,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
+        return MEMORY_E;
+    }
+#endif
+
+    InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce,
+                                                         ocspReqBuf, ocspReqSz);
+    ocspReqSz = EncodeOcspRequest(ocspRequest);
+    
+    if (ocsp->cm->ocspIOCb)
+        result = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz,
+                                           ocspReqBuf, ocspReqSz, &ocspRespBuf);
+
+    if (result >= 0 && ocspRespBuf) {
+        XMEMSET(newStatus, 0, sizeof(CertStatus));
+
+        InitOcspResponse(ocspResponse, newStatus, ocspRespBuf, result);
+        OcspResponseDecode(ocspResponse);
+    
+        if (ocspResponse->responseStatus != OCSP_SUCCESSFUL)
+            result = OCSP_LOOKUP_FAIL;
+        else {
+            if (CompareOcspReqResp(ocspRequest, ocspResponse) == 0) {
+                result = xstat2err(ocspResponse->status->status);
+
+                if (LockMutex(&ocsp->ocspLock) != 0)
+                    result = BAD_MUTEX_E;
+                else {
+                    if (certStatus != NULL)
+                        /* Replace existing certificate entry with updated */
+                        XMEMCPY(certStatus, newStatus, sizeof(CertStatus));
+                    else {
+                        /* Save new certificate entry */
+                        certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus),
+                                          NULL, DYNAMIC_TYPE_OCSP_STATUS);
+                        if (certStatus != NULL) {
+                            XMEMCPY(certStatus, newStatus, sizeof(CertStatus));
+                            certStatus->next = ocspe->status;
+                            ocspe->status = certStatus;
+                            ocspe->totalStatus++;
+                        }
+                    }
+
+                    UnLockMutex(&ocsp->ocspLock);
+                }
+            }
+            else
+                result = OCSP_LOOKUP_FAIL;
+        }
+    }
+    else
+        result = OCSP_LOOKUP_FAIL;
+
+    XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(newStatus,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(ocspRequest,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (ocspRespBuf != NULL && ocsp->cm->ocspRespFreeCb)
+        ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, ocspRespBuf);
+
+    WOLFSSL_LEAVE("CheckCertOCSP", result);
+    return result;
+}
+
+
+#else /* HAVE_OCSP */
+
+
+#ifdef _MSC_VER
+    /* 4206 warning for blank file */
+    #pragma warning(disable: 4206)
+#endif
+
+
+#endif /* HAVE_OCSP */
+#endif /* WOLFCRYPT_ONLY */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/src/sniffer.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/src/sniffer.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/src/sniffer.c	(revision 164)
@@ -0,0 +1,3326 @@
+/* sniffer.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLFCRYPT_ONLY
+#ifdef WOLFSSL_SNIFFER
+
+#include <assert.h>
+#include <time.h>
+
+#ifndef _WIN32
+  #include <arpa/inet.h>
+#endif
+
+#ifdef _WIN32
+    #define SNPRINTF _snprintf
+#else
+    #define SNPRINTF snprintf
+#endif
+
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+#include <wolfssl/sniffer.h>
+#include <wolfssl/sniffer_error.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+static INLINE word32 min(word32 a, word32 b)
+{
+    return a > b ? b : a;
+}
+
+#endif /* WOLFSSL_HAVE_MIN */
+
+#ifndef WOLFSSL_SNIFFER_TIMEOUT
+    #define WOLFSSL_SNIFFER_TIMEOUT 900
+    /* Cache unclosed Sessions for 15 minutes since last used */
+#endif
+
+/* Misc constants */
+enum {
+    MAX_SERVER_ADDRESS = 128, /* maximum server address length */
+    MAX_SERVER_NAME    = 128, /* maximum server name length */
+    MAX_ERROR_LEN      = 80,  /* maximum error length */
+    ETHER_IF_ADDR_LEN  = 6,   /* ethernet interface address length */
+    LOCAL_IF_ADDR_LEN  = 4,   /* localhost interface address length, !windows */
+    TCP_PROTO          = 6,   /* TCP_PROTOCOL */
+    IP_HDR_SZ          = 20,  /* IP header legnth, min */
+    TCP_HDR_SZ         = 20,  /* TCP header legnth, min */
+    IPV4               = 4,   /* IP version 4 */
+    TCP_PROTOCOL       = 6,   /* TCP Protocol id */
+    TRACE_MSG_SZ       = 80,  /* Trace Message buffer size */
+    HASH_SIZE          = 499, /* Session Hash Table Rows */
+    PSEUDO_HDR_SZ      = 12,  /* TCP Pseudo Header size in bytes */
+    FATAL_ERROR_STATE  =  1,  /* SnifferSession fatal error state */
+    TICKET_HINT_LEN    = 4,   /* Session Ticket Hint length */
+    EXT_TYPE_SZ        = 2,   /* Extension length */
+    MAX_INPUT_SZ       = MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA +
+                         MTU_EXTRA,  /* Max input sz of reassembly */
+    TICKET_EXT_ID      = 0x23 /* Session Ticket Extension ID */
+};
+
+
+#ifdef _WIN32
+
+static HMODULE dllModule;  /* for error string resources */
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+                       DWORD  ul_reason_for_call,
+                       LPVOID lpReserved
+                     )
+{
+	static int didInit = 0;
+
+    switch (ul_reason_for_call)
+    {
+    case DLL_PROCESS_ATTACH:
+		if (didInit == 0) {
+            dllModule = hModule;
+			ssl_InitSniffer();
+			didInit = 1;
+		}
+        break;
+    case DLL_THREAD_ATTACH:
+        break;
+    case DLL_THREAD_DETACH:
+        break;
+    case DLL_PROCESS_DETACH:
+		if (didInit) {
+			ssl_FreeSniffer();
+			didInit = 0;
+		}
+        break;
+    }
+    return TRUE;
+}
+
+#endif /* _WIN32 */
+
+
+static int TraceOn = 0;         /* Trace is off by default */
+static FILE* TraceFile = 0;
+
+
+/* windows uses .rc table for this */
+#ifndef _WIN32
+
+static const char* const msgTable[] =
+{
+    /* 1 */
+    "Out of Memory",
+    "New SSL Sniffer Server Registered",
+    "Checking IP Header",
+    "SSL Sniffer Server Not Registered",
+    "Checking TCP Header",
+
+    /* 6 */
+    "SSL Sniffer Server Port Not Registered",
+    "RSA Private Decrypt Error",
+    "RSA Private Decode Error",
+    "Set Cipher Spec Error",
+    "Server Hello Input Malformed",
+
+    /* 11 */
+    "Couldn't Resume Session Error",
+    "Server Did Resumption",
+    "Client Hello Input Malformed",
+    "Client Trying to Resume",
+    "Handshake Input Malformed",
+
+    /* 16 */
+    "Got Hello Verify msg",
+    "Got Server Hello msg",
+    "Got Cert Request msg",
+    "Got Server Key Exchange msg",
+    "Got Cert msg",
+
+    /* 21 */
+    "Got Server Hello Done msg",
+    "Got Finished msg",
+    "Got Client Hello msg",
+    "Got Client Key Exchange msg",
+    "Got Cert Verify msg",
+
+    /* 26 */
+    "Got Unknown Handshake msg",
+    "New SSL Sniffer Session created",
+    "Couldn't create new SSL",
+    "Got a Packet to decode",
+    "No data present",
+
+    /* 31 */
+    "Session Not Found",
+    "Got an Old Client Hello msg",
+    "Old Client Hello Input Malformed",
+    "Old Client Hello OK",
+    "Bad Old Client Hello",
+
+    /* 36 */
+    "Bad Record Header",
+    "Record Header Input Malformed",
+    "Got a HandShake msg",
+    "Bad HandShake msg",
+    "Got a Change Cipher Spec msg",
+
+    /* 41 */
+    "Got Application Data msg",
+    "Bad Application Data",
+    "Got an Alert msg",
+    "Another msg to Process",
+    "Removing Session From Table",
+    
+    /* 46 */
+    "Bad Key File",
+    "Wrong IP Version",
+    "Wrong Protocol type",
+    "Packet Short for header processing",
+    "Got Unknown Record Type",
+    
+    /* 51 */
+    "Can't Open Trace File",
+    "Session in Fatal Error State",
+    "Partial SSL record received",
+    "Buffer Error, malformed input",
+    "Added to Partial Input",
+    
+    /* 56 */
+    "Received a Duplicate Packet",
+    "Received an Out of Order Packet",
+    "Received an Overlap Duplicate Packet",
+    "Received an Overlap Reassembly Begin Duplicate Packet",
+    "Received an Overlap Reassembly End Duplicate Packet",
+
+    /* 61 */
+    "Missed the Client Hello Entirely",
+    "Got Hello Request msg",
+    "Got Session Ticket msg",
+    "Bad Input",
+    "Bad Decrypt Type",
+
+    /* 66 */
+    "Bad Finished Message Processing",
+    "Bad Compression Type",
+    "Bad DeriveKeys Error",
+    "Saw ACK for Missing Packet Error",
+    "Bad Decrypt Operation",
+
+    /* 71 */
+    "Decrypt Keys Not Set Up",
+    "Late Key Load Error",
+    "Got Certificate Status msg",
+    "RSA Key Missing Error",
+    "Secure Renegotiation Not Supported",
+
+    /* 76 */
+    "Get Session Stats Failure",
+    "Reassembly Buffer Size Exceeded",
+    "Dropping Lost Fragment",
+    "Dropping Partial Record",
+    "Clear ACK Fault",
+
+    /* 81 */
+    "Bad Decrypt Size"
+};
+
+
+/* *nix version uses table above */
+static void GetError(int idx, char* str)
+{
+    XSTRNCPY(str, msgTable[idx - 1], MAX_ERROR_LEN);
+}
+
+
+#else /* _WIN32 */
+
+
+/* Windows version uses .rc table */
+static void GetError(int idx, char* buffer)
+{
+    if (!LoadStringA(dllModule, idx, buffer, MAX_ERROR_LEN))
+        buffer[0] = 0;
+}
+
+
+#endif /* _WIN32 */
+
+
+/* Packet Buffer for reassembly list and ready list */
+typedef struct PacketBuffer {
+    word32  begin;      /* relative sequence begin */
+    word32  end;        /* relative sequence end   */
+    byte*   data;       /* actual data             */
+    struct PacketBuffer* next; /* next on reassembly list or ready list */
+} PacketBuffer;
+
+
+#ifdef HAVE_SNI
+
+/* NamedKey maps a SNI name to a specific private key */
+typedef struct NamedKey {
+    char             name[MAX_SERVER_NAME];      /* server DNS name */
+    word32           nameSz;                     /* size of server DNS name */
+    byte*            key;                        /* DER private key */
+    word32           keySz;                      /* size of DER private key */
+    struct NamedKey* next;                       /* for list */
+} NamedKey;
+
+#endif
+
+
+/* Sniffer Server holds info for each server/port monitored */
+typedef struct SnifferServer {
+    SSL_CTX*       ctx;                          /* SSL context */
+    char           address[MAX_SERVER_ADDRESS];  /* passed in server address */
+    word32         server;                       /* netowrk order address */
+    int            port;                         /* server port */
+#ifdef HAVE_SNI
+    NamedKey*      namedKeys;                    /* mapping of names and keys */
+    wolfSSL_Mutex   namedKeysMutex;               /* mutex for namedKey list */
+#endif
+    struct SnifferServer* next;                  /* for list */
+} SnifferServer;
+
+
+/* Session Flags */
+typedef struct Flags {
+    byte           side;            /* which end is current packet headed */
+    byte           serverCipherOn;  /* indicates whether cipher is active */
+    byte           clientCipherOn;  /* indicates whether cipher is active */
+    byte           resuming;        /* did this session come from resumption */
+    byte           cached;          /* have we cached this session yet */
+    byte           clientHello;     /* processed client hello yet, for SSLv2 */
+    byte           finCount;        /* get both FINs before removing */
+    byte           fatalError;      /* fatal error state */
+    byte           cliAckFault;     /* client acked unseen data from server */
+    byte           srvAckFault;     /* server acked unseen data from client */
+    byte           cliSkipPartial;  /* client skips partial data to catch up */
+    byte           srvSkipPartial;  /* server skips partial data to catch up */
+} Flags;
+
+
+/* Out of Order FIN caputre */
+typedef struct FinCaputre {
+    word32 cliFinSeq;               /* client relative sequence FIN  0 is no */
+    word32 srvFinSeq;               /* server relative sequence FIN, 0 is no */
+    byte   cliCounted;              /* did we count yet, detects duplicates */
+    byte   srvCounted;              /* did we count yet, detects duplicates */
+} FinCaputre;
+
+
+/* Sniffer Session holds info for each client/server SSL/TLS session */
+typedef struct SnifferSession {
+    SnifferServer* context;         /* server context */
+    SSL*           sslServer;       /* SSL server side decode */
+    SSL*           sslClient;       /* SSL client side decode */
+    word32         server;          /* server address in network byte order */
+    word32         client;          /* client address in network byte order */
+    word16         srvPort;         /* server port */
+    word16         cliPort;         /* client port */
+    word32         cliSeqStart;     /* client start sequence */
+    word32         srvSeqStart;     /* server start sequence */
+    word32         cliExpected;     /* client expected sequence (relative) */
+    word32         srvExpected;     /* server expected sequence (relative) */
+    FinCaputre     finCaputre;      /* retain out of order FIN s */
+    Flags          flags;           /* session flags */
+    time_t         lastUsed;          /* last used ticks */
+    PacketBuffer*  cliReassemblyList; /* client out of order packets */
+    PacketBuffer*  srvReassemblyList; /* server out of order packets */
+    word32         cliReassemblyMemory; /* client packet memory used */
+    word32         srvReassemblyMemory; /* server packet memory used */
+    struct SnifferSession* next;      /* for hash table list */
+    byte*          ticketID;          /* mac ID of session ticket */
+} SnifferSession;
+
+
+/* Sniffer Server List and mutex */
+static SnifferServer* ServerList = 0;
+static wolfSSL_Mutex ServerListMutex;
+
+
+/* Session Hash Table, mutex, and count */
+static SnifferSession* SessionTable[HASH_SIZE];
+static wolfSSL_Mutex SessionMutex;
+static int SessionCount = 0;
+
+/* Recovery of missed data switches and stats */
+static wolfSSL_Mutex RecoveryMutex;      /* for stats */
+static int RecoveryEnabled    = 0;       /* global switch */
+static int MaxRecoveryMemory  = -1;      /* per session max recovery memory */
+static word32 MissedDataSessions = 0;    /* # of sessions with missed data */
+
+
+static void UpdateMissedDataSessions(void)
+{
+    LockMutex(&RecoveryMutex);
+    MissedDataSessions += 1;
+    UnLockMutex(&RecoveryMutex);
+}
+
+
+/* Initialize overall Sniffer */
+void ssl_InitSniffer(void)
+{
+    wolfSSL_Init();
+    InitMutex(&ServerListMutex);
+    InitMutex(&SessionMutex);
+    InitMutex(&RecoveryMutex);
+}
+
+
+#ifdef HAVE_SNI
+
+/* Free Named Key and the zero out the private key it holds */
+static void FreeNamedKey(NamedKey* in)
+{
+    if (in) {
+        if (in->key) {
+            ForceZero(in->key, in->keySz);
+            free(in->key);
+        }
+        free(in);
+    }
+}
+
+
+static void FreeNamedKeyList(NamedKey* in)
+{
+    NamedKey* next;
+
+    while (in) {
+        next = in->next;
+        FreeNamedKey(in);
+        in = next;
+    }
+}
+
+#endif
+
+
+/* Free Sniffer Server's resources/self */
+static void FreeSnifferServer(SnifferServer* srv)
+{
+    if (srv) {
+#ifdef HAVE_SNI
+        LockMutex(&srv->namedKeysMutex);
+        FreeNamedKeyList(srv->namedKeys);
+        UnLockMutex(&srv->namedKeysMutex);
+        FreeMutex(&srv->namedKeysMutex);
+#endif
+        SSL_CTX_free(srv->ctx);
+    }
+    free(srv);
+}
+
+
+/* free PacketBuffer's resources/self */
+static void FreePacketBuffer(PacketBuffer* del)
+{
+    if (del) {
+        free(del->data);
+        free(del);
+    }
+}
+
+
+/* remove PacketBuffer List */
+static void FreePacketList(PacketBuffer* in)
+{
+    if (in) {
+        PacketBuffer* del;
+        PacketBuffer* packet = in;
+        
+        while (packet) {
+            del = packet;
+            packet = packet->next;
+            FreePacketBuffer(del);
+        }
+    }
+}
+
+
+/* Free Sniffer Session's resources/self */
+static void FreeSnifferSession(SnifferSession* session)
+{
+    if (session) {
+        SSL_free(session->sslClient);
+        SSL_free(session->sslServer);
+        
+        FreePacketList(session->cliReassemblyList);
+        FreePacketList(session->srvReassemblyList);
+
+        free(session->ticketID);
+    }
+    free(session);
+}
+
+
+/* Free overall Sniffer */
+void ssl_FreeSniffer(void)
+{
+    SnifferServer*  srv;
+    SnifferServer*  removeServer;
+    SnifferSession* session;
+    SnifferSession* removeSession;
+    int i;
+
+    LockMutex(&ServerListMutex);
+    LockMutex(&SessionMutex);
+    
+    srv = ServerList;
+    while (srv) {
+        removeServer = srv;
+        srv = srv->next;
+        FreeSnifferServer(removeServer);
+    }
+
+    for (i = 0; i < HASH_SIZE; i++) {
+        session = SessionTable[i];
+        while (session) {
+            removeSession = session;
+            session = session->next;
+            FreeSnifferSession(removeSession);
+        }
+    }
+
+    UnLockMutex(&SessionMutex);
+    UnLockMutex(&ServerListMutex);
+
+    FreeMutex(&RecoveryMutex);
+    FreeMutex(&SessionMutex);
+    FreeMutex(&ServerListMutex);
+
+    if (TraceFile) {
+        TraceOn = 0;
+        fclose(TraceFile);
+        TraceFile = NULL;
+    }
+
+    wolfSSL_Cleanup();
+}
+
+
+/* Initialize a SnifferServer */
+static void InitSnifferServer(SnifferServer* sniffer)
+{
+    sniffer->ctx = 0;
+    XMEMSET(sniffer->address, 0, MAX_SERVER_ADDRESS);
+    sniffer->server   = 0;
+    sniffer->port     = 0;
+#ifdef HAVE_SNI
+    sniffer->namedKeys = 0;
+    InitMutex(&sniffer->namedKeysMutex);
+#endif
+    sniffer->next     = 0;
+}
+
+
+/* Initialize session flags */
+static void InitFlags(Flags* flags)
+{
+    flags->side           = 0;
+    flags->serverCipherOn = 0;
+    flags->clientCipherOn = 0;
+    flags->resuming       = 0;
+    flags->cached         = 0;
+    flags->clientHello    = 0;
+    flags->finCount       = 0;
+    flags->fatalError     = 0;
+    flags->cliAckFault    = 0;
+    flags->srvAckFault    = 0;
+    flags->cliSkipPartial = 0;
+    flags->srvSkipPartial = 0;
+}
+
+
+/* Initialize FIN Capture */
+static void InitFinCapture(FinCaputre* cap)
+{
+    cap->cliFinSeq  = 0;
+    cap->srvFinSeq  = 0;
+    cap->cliCounted = 0;
+    cap->srvCounted = 0;
+}
+
+
+/* Initialize a Sniffer Session */
+static void InitSession(SnifferSession* session)
+{
+    session->context        = 0;
+    session->sslServer      = 0;
+    session->sslClient      = 0;
+    session->server         = 0;
+    session->client         = 0;
+    session->srvPort        = 0;
+    session->cliPort        = 0;
+    session->cliSeqStart    = 0;
+    session->srvSeqStart    = 0;
+    session->cliExpected    = 0;
+    session->srvExpected    = 0;
+    session->lastUsed       = 0;
+    session->cliReassemblyList = 0;
+    session->srvReassemblyList = 0;
+    session->cliReassemblyMemory = 0;
+    session->srvReassemblyMemory = 0;
+    session->next           = 0;
+    session->ticketID       = 0;
+    
+    InitFlags(&session->flags);
+    InitFinCapture(&session->finCaputre);
+}
+
+
+/* IP Info from IP Header */
+typedef struct IpInfo {
+    int    length;        /* length of this header */
+    int    total;         /* total length of fragment */
+    word32 src;           /* network order source address */
+    word32 dst;           /* network order destination address */
+} IpInfo;
+
+
+/* TCP Info from TCP Header */
+typedef struct TcpInfo {
+    int    srcPort;       /* source port */
+    int    dstPort;       /* source port */
+    int    length;        /* length of this header */
+    word32 sequence;      /* sequence number */
+    word32 ackNumber;     /* ack number */
+    byte   fin;           /* FIN set */
+    byte   rst;           /* RST set */
+    byte   syn;           /* SYN set */
+    byte   ack;           /* ACK set */
+} TcpInfo;
+
+
+/* Tcp Pseudo Header for Checksum calculation */
+typedef struct TcpPseudoHdr {
+    word32  src;        /* source address */
+    word32  dst;        /* destination address */
+    byte    rsv;        /* reserved, always 0 */
+    byte    protocol;   /* IP protocol */
+    word16  legnth;     /* tcp header length + data length (doesn't include */
+                        /* pseudo header length) network order */
+} TcpPseudoHdr;
+
+
+/* Password Setting Callback */
+static int SetPassword(char* passwd, int sz, int rw, void* userdata)
+{
+    (void)rw;
+    XSTRNCPY(passwd, (const char*)userdata, sz);
+    return (int)XSTRLEN((const char*)userdata);
+}
+
+
+/* Ethernet Header */
+typedef struct EthernetHdr {
+    byte   dst[ETHER_IF_ADDR_LEN];    /* destination host address */ 
+    byte   src[ETHER_IF_ADDR_LEN];    /* source  host address */ 
+    word16 type;                      /* IP, ARP, etc */ 
+} EthernetHdr;
+
+
+/* IP Header */
+typedef struct IpHdr {
+    byte    ver_hl;              /* version/header length */
+    byte    tos;                 /* type of service */
+    word16  length;              /* total length */
+    word16  id;                  /* identification */
+    word16  offset;              /* fragment offset field */
+    byte    ttl;                 /* time to live */
+    byte    protocol;            /* protocol */
+    word16  sum;                 /* checksum */
+    word32  src;                 /* source address */
+    word32  dst;                 /* destination address */
+} IpHdr;
+
+
+#define IP_HL(ip)      ( (((ip)->ver_hl) & 0x0f) * 4)
+#define IP_V(ip)       ( ((ip)->ver_hl) >> 4)
+
+/* TCP Header */
+typedef struct TcpHdr {
+    word16  srcPort;            /* source port */
+    word16  dstPort;            /* destination port */
+    word32  sequence;           /* sequence number */ 
+    word32  ack;                /* acknoledgment number */ 
+    byte    offset;             /* data offset, reserved */
+    byte    flags;              /* option flags */
+    word16  window;             /* window */
+    word16  sum;                /* checksum */
+    word16  urgent;             /* urgent pointer */
+} TcpHdr;
+
+#define TCP_LEN(tcp)  ( (((tcp)->offset & 0xf0) >> 4) * 4)
+#define TCP_FIN 0x01
+#define TCP_SYN 0x02
+#define TCP_RST 0x04
+#define TCP_ACK 0x10
+
+
+
+
+
+/* Use platform specific GetError to write to tracfile if tracing */ 
+static void Trace(int idx) 
+{
+    if (TraceOn) {
+        char myBuffer[MAX_ERROR_LEN];
+        GetError(idx, myBuffer);
+        fprintf(TraceFile, "\t%s\n", myBuffer);
+#ifdef DEBUG_SNIFFER
+        fprintf(stderr,    "\t%s\n", myBuffer);
+#endif
+    }
+}
+
+
+/* Show TimeStamp for beginning of packet Trace */
+static void TraceHeader(void)
+{
+    if (TraceOn) {
+        time_t ticks = time(NULL);
+        fprintf(TraceFile, "\n%s", ctime(&ticks));
+    }
+}
+
+
+/* Show Set Server info for Trace */
+static void TraceSetServer(const char* srv, int port, const char* keyFile)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tTrying to install a new Sniffer Server with\n");
+        fprintf(TraceFile, "\tserver: %s, port: %d, keyFile: %s\n", srv, port,
+                                                                    keyFile);
+    }
+}
+
+
+#ifdef HAVE_SNI
+
+/* Show Set Named Server info for Trace */
+static void TraceSetNamedServer(const char* name,
+                                 const char* srv, int port, const char* keyFile)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tTrying to install a new Sniffer Server with\n");
+        fprintf(TraceFile, "\tname: %s, server: %s, port: %d, keyFile: %s\n",
+                                                      name, srv, port, keyFile);
+    }
+}
+
+#endif
+
+
+/* Trace got packet number */
+static void TracePacket(void)
+{
+    if (TraceOn) {
+        static word32 packetNumber = 0;
+        fprintf(TraceFile, "\tGot a Packet to decode, packet %u\n",
+                ++packetNumber);
+    }
+}
+
+
+/* Convert network byte order address into human readable */
+static char* IpToS(word32 addr, char* str)
+{
+    byte* p = (byte*)&addr;
+    
+    SNPRINTF(str, TRACE_MSG_SZ, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+    
+    return str;
+}
+
+
+/* Show destination and source address from Ip Hdr for packet Trace */
+static void TraceIP(IpHdr* iphdr)
+{
+    if (TraceOn) {
+        char src[TRACE_MSG_SZ];
+        char dst[TRACE_MSG_SZ];
+        fprintf(TraceFile, "\tdst:%s src:%s\n", IpToS(iphdr->dst, dst),
+                IpToS(iphdr->src, src));
+    }
+}
+
+
+/* Show destination and source port from Tcp Hdr for packet Trace */
+static void TraceTcp(TcpHdr* tcphdr)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tdstPort:%u srcPort:%u\n", ntohs(tcphdr->dstPort),
+                ntohs(tcphdr->srcPort));
+    }
+}
+
+
+/* Show sequence and payload length for Trace */
+static void TraceSequence(word32 seq, int len)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tSequence:%u, payload length:%d\n", seq, len);
+    }
+}
+
+
+/* Show sequence and payload length for Trace */
+static void TraceAck(word32 ack, word32 expected)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tAck:%u Expected:%u\n", ack, expected);
+    }
+}
+
+
+/* Show relative expected and relative received sequences */
+static void TraceRelativeSequence(word32 expected, word32 got)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tExpected sequence:%u, received sequence:%u\n",
+                expected, got);
+    }
+}
+
+
+/* Show server sequence startup from SYN */
+static void TraceServerSyn(word32 seq)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tServer SYN, Sequence Start:%u\n", seq);
+    }
+}
+
+
+/* Show client sequence startup from SYN */
+static void TraceClientSyn(word32 seq)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tClient SYN, Sequence Start:%u\n", seq);
+    }
+}
+
+
+/* Show client FIN capture */
+static void TraceClientFin(word32 finSeq, word32 relSeq)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tClient FIN capture:%u, current SEQ:%u\n",
+                finSeq, relSeq);
+    }
+}
+
+
+/* Show server FIN capture */
+static void TraceServerFin(word32 finSeq, word32 relSeq)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tServer FIN capture:%u, current SEQ:%u\n",
+                finSeq, relSeq);
+    }
+}
+
+
+/* Show number of SSL data bytes decoded, could be 0 (ok) */
+static void TraceGotData(int bytes)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\t%d bytes of SSL App data processed\n", bytes);
+    }
+}
+
+
+/* Show bytes added to old SSL App data */
+static void TraceAddedData(int newBytes, int existingBytes)
+{
+    if (TraceOn) {
+        fprintf(TraceFile,
+                "\t%d bytes added to %d exisiting bytes in User Buffer\n",
+                newBytes, existingBytes);
+    }
+}
+
+
+/* Show Stale Session */
+static void TraceStaleSession(void)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tFound a stale session\n");
+    }
+}
+
+
+/* Show Finding Stale Sessions */
+static void TraceFindingStale(void)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tTrying to find Stale Sessions\n");
+    }
+}
+
+
+/* Show Removed Session */
+static void TraceRemovedSession(void)
+{
+    if (TraceOn) {
+        fprintf(TraceFile, "\tRemoved it\n");
+    }
+}
+
+
+/* Set user error string */
+static void SetError(int idx, char* error, SnifferSession* session, int fatal)
+{
+    GetError(idx, error);
+    Trace(idx);
+    if (session && fatal == FATAL_ERROR_STATE)
+        session->flags.fatalError = 1;
+}
+
+
+/* See if this IPV4 network order address has been registered */
+/* return 1 is true, 0 is false */
+static int IsServerRegistered(word32 addr)
+{
+    int ret = 0;     /* false */
+    SnifferServer* sniffer;
+
+    LockMutex(&ServerListMutex);
+    
+    sniffer = ServerList;
+    while (sniffer) {
+        if (sniffer->server == addr) {
+            ret = 1;
+            break;
+        }
+        sniffer = sniffer->next;
+    }
+    
+    UnLockMutex(&ServerListMutex);
+
+    return ret;
+}
+
+
+/* See if this port has been registered to watch */
+/* return 1 is true, 0 is false */
+static int IsPortRegistered(word32 port)
+{
+    int ret = 0;    /* false */
+    SnifferServer* sniffer;
+    
+    LockMutex(&ServerListMutex);
+    
+    sniffer = ServerList;
+    while (sniffer) {
+        if (sniffer->port == (int)port) {
+            ret = 1; 
+            break;
+        }
+        sniffer = sniffer->next;
+    }
+    
+    UnLockMutex(&ServerListMutex);
+
+    return ret;
+}
+
+
+/* Get SnifferServer from IP and Port */
+static SnifferServer* GetSnifferServer(IpInfo* ipInfo, TcpInfo* tcpInfo)
+{
+    SnifferServer* sniffer;
+    
+    LockMutex(&ServerListMutex);
+    
+    sniffer = ServerList;
+    while (sniffer) {
+        if (sniffer->port == tcpInfo->srcPort && sniffer->server == ipInfo->src)
+            break;
+        if (sniffer->port == tcpInfo->dstPort && sniffer->server == ipInfo->dst)
+            break;
+        sniffer = sniffer->next;
+    }
+    
+    UnLockMutex(&ServerListMutex);
+    
+    return sniffer;
+}
+
+
+/* Hash the Session Info, return hash row */
+static word32 SessionHash(IpInfo* ipInfo, TcpInfo* tcpInfo)
+{
+    word32 hash = ipInfo->src * ipInfo->dst;
+    hash *= tcpInfo->srcPort * tcpInfo->dstPort;
+    
+    return hash % HASH_SIZE;
+}
+
+
+/* Get Exisiting SnifferSession from IP and Port */
+static SnifferSession* GetSnifferSession(IpInfo* ipInfo, TcpInfo* tcpInfo)
+{
+    SnifferSession* session;
+    time_t          currTime = time(NULL); 
+    word32          row = SessionHash(ipInfo, tcpInfo);
+
+    assert(row <= HASH_SIZE);
+    
+    LockMutex(&SessionMutex);
+    
+    session = SessionTable[row];
+    while (session) {
+        if (session->server == ipInfo->src && session->client == ipInfo->dst &&
+                    session->srvPort == tcpInfo->srcPort &&
+                    session->cliPort == tcpInfo->dstPort)
+            break;
+        if (session->client == ipInfo->src && session->server == ipInfo->dst &&
+                    session->cliPort == tcpInfo->srcPort &&
+                    session->srvPort == tcpInfo->dstPort)
+            break;
+        
+        session = session->next;
+    }
+
+    if (session)
+        session->lastUsed= currTime; /* keep session alive, remove stale will */
+                                     /* leave alone */   
+    UnLockMutex(&SessionMutex);
+    
+    /* determine side */
+    if (session) {
+        if (ipInfo->dst == session->context->server &&
+            tcpInfo->dstPort == session->context->port)
+            session->flags.side = WOLFSSL_SERVER_END;
+        else
+            session->flags.side = WOLFSSL_CLIENT_END;
+    }    
+    
+    return session;
+}
+
+
+#ifdef HAVE_SNI
+
+static int LoadKeyFile(byte** keyBuf, word32* keyBufSz,
+                const char* keyFile, int typeKey,
+                const char* password)
+{
+    byte* loadBuf;
+    byte* saveBuf;
+    long fileSz = 0;
+    int saveBufSz;
+    XFILE file;
+    int ret;
+
+    if (keyBuf == NULL || keyBufSz == NULL || keyFile == NULL) {
+        return -1;
+    }
+
+    file = XFOPEN(keyFile, "rb");
+    if (file == XBADFILE) return -1;
+    XFSEEK(file, 0, XSEEK_END);
+    fileSz = XFTELL(file);
+    XREWIND(file);
+
+    loadBuf = (byte*)malloc(fileSz);
+    if (loadBuf == NULL) {
+        XFCLOSE(file);
+        return -1;
+    }
+
+    ret = (int)XFREAD(loadBuf, fileSz, 1, file);
+    XFCLOSE(file);
+
+    if (typeKey == SSL_FILETYPE_PEM) {
+        saveBuf = (byte*)malloc(fileSz);
+
+        saveBufSz = wolfSSL_KeyPemToDer(loadBuf, (int)fileSz,
+                                                saveBuf, (int)fileSz, password);
+        free(loadBuf);
+
+        *keyBuf = saveBuf;
+        *keyBufSz = (word32)saveBufSz;
+    }
+    else {
+        *keyBuf = loadBuf;
+        *keyBufSz = (word32)fileSz;
+    }
+
+
+    if (ret < 0) {
+        return -1;
+    }
+
+    return ret;
+}
+
+#endif
+
+
+static int SetNamedPrivateKey(const char* name, const char* address, int port,
+            const char* keyFile, int typeKey, const char* password, char* error)
+{
+    SnifferServer* sniffer;
+    int            ret;
+    int            type = (typeKey == FILETYPE_PEM) ? SSL_FILETYPE_PEM :
+                                                      SSL_FILETYPE_ASN1;
+    int            isNew = 0;
+    word32         serverIp;
+
+#ifdef HAVE_SNI
+    NamedKey* namedKey = NULL;
+#endif
+
+    (void)name;
+#ifdef HAVE_SNI
+    if (name != NULL) {
+        namedKey = (NamedKey*)malloc(sizeof(NamedKey));
+        if (namedKey == NULL) {
+            SetError(MEMORY_STR, error, NULL, 0);
+            return -1;
+        }
+        XMEMSET(namedKey, 0, sizeof(NamedKey));
+
+        namedKey->nameSz = (word32)XSTRLEN(name);
+        XSTRNCPY(namedKey->name, name, sizeof(namedKey->name));
+        if (namedKey->nameSz >= sizeof(namedKey->name)) {
+            namedKey->nameSz = sizeof(namedKey->name) - 1;
+            namedKey->name[namedKey->nameSz] = '\0';
+        }
+
+        ret = LoadKeyFile(&namedKey->key, &namedKey->keySz,
+                          keyFile, type, password);
+        if (ret < 0) {
+            SetError(KEY_FILE_STR, error, NULL, 0);
+            FreeNamedKey(namedKey);
+            return -1;
+        }
+    }
+#endif
+
+    serverIp = inet_addr(address);
+    sniffer = ServerList;
+    while (sniffer != NULL &&
+           (sniffer->server != serverIp || sniffer->port != port)) {
+        sniffer = sniffer->next;
+    }
+
+    if (sniffer == NULL) {
+        isNew = 1;
+        sniffer = (SnifferServer*)malloc(sizeof(SnifferServer));
+        if (sniffer == NULL) {
+            SetError(MEMORY_STR, error, NULL, 0);
+#ifdef HAVE_SNI
+            FreeNamedKey(namedKey);
+#endif
+            return -1;
+        }
+        InitSnifferServer(sniffer);
+
+        XSTRNCPY(sniffer->address, address, MAX_SERVER_ADDRESS-1);
+        sniffer->address[MAX_SERVER_ADDRESS-1] = '\0';
+        sniffer->server = serverIp;
+        sniffer->port = port;
+
+        sniffer->ctx = SSL_CTX_new(TLSv1_client_method());
+        if (!sniffer->ctx) {
+            SetError(MEMORY_STR, error, NULL, 0);
+#ifdef HAVE_SNI
+            FreeNamedKey(namedKey);
+#endif
+            FreeSnifferServer(sniffer);
+            return -1;
+        }
+    }
+
+    if (name == NULL) {
+        if (password) {
+            SSL_CTX_set_default_passwd_cb(sniffer->ctx, SetPassword);
+            SSL_CTX_set_default_passwd_cb_userdata(
+                                                 sniffer->ctx, (void*)password);
+        }
+        ret = SSL_CTX_use_PrivateKey_file(sniffer->ctx, keyFile, type);
+        if (ret != SSL_SUCCESS) {
+            SetError(KEY_FILE_STR, error, NULL, 0);
+            if (isNew)
+                FreeSnifferServer(sniffer);
+            return -1;
+        }
+    }
+#ifdef HAVE_SNI
+    else {
+        LockMutex(&sniffer->namedKeysMutex);
+        namedKey->next = sniffer->namedKeys;
+        sniffer->namedKeys = namedKey;
+        UnLockMutex(&sniffer->namedKeysMutex);
+    }
+#endif
+
+    if (isNew) {
+        sniffer->next = ServerList;
+        ServerList = sniffer;
+    }
+
+    return 0;
+}
+
+
+#ifdef HAVE_SNI
+
+/* Sets the private key for a specific name, server and port  */
+/* returns 0 on success, -1 on error */
+int ssl_SetNamedPrivateKey(const char* name,
+                           const char* address, int port,
+                           const char* keyFile, int typeKey,
+                           const char* password, char* error)
+{
+    int ret;
+
+    TraceHeader();
+    TraceSetNamedServer(name, address, port, keyFile);
+
+    LockMutex(&ServerListMutex);
+    ret = SetNamedPrivateKey(name, address, port, keyFile,
+                             typeKey, password, error);
+    UnLockMutex(&ServerListMutex);
+
+    if (ret == 0)
+        Trace(NEW_SERVER_STR);
+
+    return ret;
+}
+
+#endif
+
+
+/* Sets the private key for a specific server and port  */
+/* returns 0 on success, -1 on error */
+int ssl_SetPrivateKey(const char* address, int port, const char* keyFile,
+                      int typeKey, const char* password, char* error)
+{
+    int ret;
+
+    TraceHeader();
+    TraceSetServer(address, port, keyFile);
+
+    LockMutex(&ServerListMutex);
+    ret = SetNamedPrivateKey(NULL, address, port, keyFile,
+                             typeKey, password, error);
+    UnLockMutex(&ServerListMutex);
+
+    if (ret == 0)
+        Trace(NEW_SERVER_STR);
+
+    return ret;
+}
+
+
+/* Check IP Header for IPV4, TCP, and a registered server address */
+/* returns 0 on success, -1 on error */
+static int CheckIpHdr(IpHdr* iphdr, IpInfo* info, int length, char* error)
+{
+    int    version = IP_V(iphdr);
+
+    TraceIP(iphdr);
+    Trace(IP_CHECK_STR);
+
+    if (version != IPV4) {
+        SetError(BAD_IPVER_STR, error, NULL, 0); 
+        return -1;
+    }
+
+    if (iphdr->protocol != TCP_PROTOCOL) { 
+        SetError(BAD_PROTO_STR, error, NULL, 0);
+        return -1;
+    }
+
+    if (!IsServerRegistered(iphdr->src) && !IsServerRegistered(iphdr->dst)) {
+        SetError(SERVER_NOT_REG_STR, error, NULL, 0);
+        return -1;
+    }
+
+    info->length  = IP_HL(iphdr);
+    info->total   = ntohs(iphdr->length);
+    info->src     = iphdr->src;
+    info->dst     = iphdr->dst;
+
+    if (info->total == 0)
+        info->total = length;  /* reassembled may be off */
+
+    return 0;
+}
+
+
+/* Check TCP Header for a registered port */
+/* returns 0 on success, -1 on error */
+static int CheckTcpHdr(TcpHdr* tcphdr, TcpInfo* info, char* error)
+{
+    TraceTcp(tcphdr);
+    Trace(TCP_CHECK_STR);
+    info->srcPort   = ntohs(tcphdr->srcPort);
+    info->dstPort   = ntohs(tcphdr->dstPort);
+    info->length    = TCP_LEN(tcphdr);
+    info->sequence  = ntohl(tcphdr->sequence);
+    info->fin       = tcphdr->flags & TCP_FIN;
+    info->rst       = tcphdr->flags & TCP_RST;
+    info->syn       = tcphdr->flags & TCP_SYN;
+    info->ack       = tcphdr->flags & TCP_ACK;
+    if (info->ack)
+        info->ackNumber = ntohl(tcphdr->ack); 
+
+    if (!IsPortRegistered(info->srcPort) && !IsPortRegistered(info->dstPort)) {
+        SetError(SERVER_PORT_NOT_REG_STR, error, NULL, 0);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+/* Decode Record Layer Header */
+static int GetRecordHeader(const byte* input, RecordLayerHeader* rh, int* size)
+{
+    XMEMCPY(rh, input, RECORD_HEADER_SZ);
+    *size = (rh->length[0] << 8) | rh->length[1];
+
+    if (*size > (MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA))
+        return LENGTH_ERROR;
+
+    return 0;
+}
+
+
+/* Process Client Key Exchange, RSA only */
+static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
+                                    SnifferSession* session, char* error)
+{
+    word32 idx = 0;
+    RsaKey key;
+    int    ret;
+
+    if (session->sslServer->buffers.key.buffer == NULL ||
+        session->sslServer->buffers.key.length == 0) {
+
+        SetError(RSA_KEY_MISSING_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    ret = wc_InitRsaKey(&key, 0);
+    if (ret == 0)
+        ret = wc_RsaPrivateKeyDecode(session->sslServer->buffers.key.buffer,
+                          &idx, &key, session->sslServer->buffers.key.length);
+    if (ret == 0) {
+        int length = wc_RsaEncryptSize(&key);
+
+        if (IsTLS(session->sslServer))
+            input += 2;     /* tls pre length */
+
+        if (length > *sslBytes) {
+            SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE);
+            wc_FreeRsaKey(&key);
+            return -1;
+        }
+        ret = wc_RsaPrivateDecrypt(input, length,
+                  session->sslServer->arrays->preMasterSecret,SECRET_LEN, &key);
+
+        if (ret != SECRET_LEN) {
+            SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
+            wc_FreeRsaKey(&key);
+            return -1;
+        }
+        session->sslServer->arrays->preMasterSz = SECRET_LEN;
+
+        /* store for client side as well */
+        XMEMCPY(session->sslClient->arrays->preMasterSecret,
+               session->sslServer->arrays->preMasterSecret, SECRET_LEN);
+        session->sslClient->arrays->preMasterSz = SECRET_LEN;
+
+        #ifdef SHOW_SECRETS
+        {
+            int i;
+            printf("pre master secret: ");
+            for (i = 0; i < SECRET_LEN; i++)
+                printf("%02x", session->sslServer->arrays->preMasterSecret[i]);
+            printf("\n");
+        }
+        #endif
+    }
+    else {
+        SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE);
+        wc_FreeRsaKey(&key);
+        return -1;
+    }
+
+    if (SetCipherSpecs(session->sslServer) != 0) {
+        SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
+        wc_FreeRsaKey(&key);
+        return -1;
+    }
+
+    if (SetCipherSpecs(session->sslClient) != 0) {
+        SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
+        wc_FreeRsaKey(&key);
+        return -1;
+    }
+
+    ret  = MakeMasterSecret(session->sslServer);
+    ret += MakeMasterSecret(session->sslClient);
+    ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE);
+    ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE);
+
+    if (ret != 0) {
+        SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+#ifdef SHOW_SECRETS
+    {
+        int i;
+        printf("server master secret: ");
+        for (i = 0; i < SECRET_LEN; i++)
+            printf("%02x", session->sslServer->arrays->masterSecret[i]);
+        printf("\n");
+
+        printf("client master secret: ");
+        for (i = 0; i < SECRET_LEN; i++)
+            printf("%02x", session->sslClient->arrays->masterSecret[i]);
+        printf("\n");
+
+        printf("server suite = %d\n", session->sslServer->options.cipherSuite);
+        printf("client suite = %d\n", session->sslClient->options.cipherSuite);
+    }
+#endif
+
+    wc_FreeRsaKey(&key);
+    return ret;
+}
+
+
+/* Process Session Ticket */
+static int ProcessSessionTicket(const byte* input, int* sslBytes,
+                                SnifferSession* session, char* error)
+{
+    word16 len;
+
+    /* make sure can read through hint and len */
+    if (TICKET_HINT_LEN + LENGTH_SZ > *sslBytes) {
+        SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    input     += TICKET_HINT_LEN;  /* skip over hint */
+    *sslBytes -= TICKET_HINT_LEN;
+
+    len = (word16)((input[0] << 8) | input[1]);
+    input     += LENGTH_SZ;
+    *sslBytes -= LENGTH_SZ;
+
+    /* make sure can read through ticket */
+    if (len > *sslBytes || len < ID_LEN) {
+        SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    /* store session with macID as sessionID */
+    session->sslServer->options.haveSessionId = 1;
+    XMEMCPY(session->sslServer->arrays->sessionID, input + len - ID_LEN,ID_LEN);
+
+    return 0;
+}
+
+
+/* Process Server Hello */
+static int ProcessServerHello(const byte* input, int* sslBytes,
+                              SnifferSession* session, char* error)
+{
+    ProtocolVersion pv;
+    byte            b;
+    int             toRead = VERSION_SZ + RAN_LEN + ENUM_LEN;
+    int             doResume     = 0;
+
+    /* make sure we didn't miss ClientHello */
+    if (session->flags.clientHello == 0) {
+        SetError(MISSED_CLIENT_HELLO_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    /* make sure can read through session len */
+    if (toRead > *sslBytes) {
+        SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    XMEMCPY(&pv, input, VERSION_SZ);
+    input     += VERSION_SZ;
+    *sslBytes -= VERSION_SZ;
+
+    session->sslServer->version = pv;
+    session->sslClient->version = pv;
+
+    XMEMCPY(session->sslServer->arrays->serverRandom, input, RAN_LEN);
+    XMEMCPY(session->sslClient->arrays->serverRandom, input, RAN_LEN);
+    input    += RAN_LEN;
+    *sslBytes -= RAN_LEN;
+
+    b = *input++;
+    *sslBytes -= 1;
+
+    /* make sure can read through compression */
+    if ( (b + SUITE_LEN + ENUM_LEN) > *sslBytes) {
+        SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    if (b) {
+        XMEMCPY(session->sslServer->arrays->sessionID, input, ID_LEN);
+        session->sslServer->options.haveSessionId = 1;
+    }
+    input     += b;
+    *sslBytes -= b;
+
+    /* cipher suite */
+    b = *input++;  /* first byte, ECC or not */
+    session->sslServer->options.cipherSuite0 = b;
+    session->sslClient->options.cipherSuite0 = b;
+    b = *input++;
+    session->sslServer->options.cipherSuite = b;
+    session->sslClient->options.cipherSuite = b;
+    *sslBytes -= SUITE_LEN;
+
+    /* compression */
+    b = *input++;
+    *sslBytes -= ENUM_LEN;
+
+    if (b) {
+        SetError(BAD_COMPRESSION_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    if (session->sslServer->options.haveSessionId &&
+            XMEMCMP(session->sslServer->arrays->sessionID,
+                    session->sslClient->arrays->sessionID, ID_LEN) == 0)
+        doResume = 1;
+    else if (session->sslClient->options.haveSessionId == 0 &&
+             session->sslServer->options.haveSessionId == 0 &&
+             session->ticketID)
+        doResume = 1;
+
+    if (session->ticketID && doResume) {
+        /* use ticketID to retrieve from session, prefer over sessionID */
+        XMEMCPY(session->sslServer->arrays->sessionID,session->ticketID,ID_LEN);
+        session->sslServer->options.haveSessionId = 1;  /* may not have
+                                                           actual sessionID */
+    }
+
+    if (doResume ) {
+        int ret = 0;
+        SSL_SESSION* resume = GetSession(session->sslServer,
+                                      session->sslServer->arrays->masterSecret);
+        if (resume == NULL) {
+            SetError(BAD_SESSION_RESUME_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        /* make sure client has master secret too */
+        XMEMCPY(session->sslClient->arrays->masterSecret,
+               session->sslServer->arrays->masterSecret, SECRET_LEN);
+        session->flags.resuming = 1;
+
+        Trace(SERVER_DID_RESUMPTION_STR);
+        if (SetCipherSpecs(session->sslServer) != 0) {
+            SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+
+        if (SetCipherSpecs(session->sslClient) != 0) {
+            SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+
+        if (session->sslServer->options.tls) {
+            ret =  DeriveTlsKeys(session->sslServer);
+            ret += DeriveTlsKeys(session->sslClient);
+        }
+        else {
+            ret =  DeriveKeys(session->sslServer);
+            ret += DeriveKeys(session->sslClient);
+        }
+        ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE);
+        ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE);
+
+        if (ret != 0) {
+            SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+    }
+#ifdef SHOW_SECRETS
+    {
+        int i;
+        printf("cipher suite = 0x%02x\n",
+               session->sslServer->options.cipherSuite);
+        printf("server random: ");
+        for (i = 0; i < RAN_LEN; i++)
+            printf("%02x", session->sslServer->arrays->serverRandom[i]);
+        printf("\n");
+    }
+#endif
+    return 0;
+}
+
+
+/* Process normal Client Hello */
+static int ProcessClientHello(const byte* input, int* sslBytes,
+                              SnifferSession* session, char* error)
+{
+    byte   bLen;
+    word16 len;
+    int    toRead = VERSION_SZ + RAN_LEN + ENUM_LEN;
+
+#ifdef HAVE_SNI
+    {
+        byte name[MAX_SERVER_NAME];
+        word32 nameSz = sizeof(name);
+        int ret;
+
+        ret = wolfSSL_SNI_GetFromBuffer(
+                             input - HANDSHAKE_HEADER_SZ - RECORD_HEADER_SZ,
+                             *sslBytes + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ,
+                             WOLFSSL_SNI_HOST_NAME, name, &nameSz);
+
+        if (ret == SSL_SUCCESS) {
+            NamedKey* namedKey;
+
+            if (nameSz >= sizeof(name))
+                nameSz = sizeof(name) - 1;
+            name[nameSz] = 0;
+            LockMutex(&session->context->namedKeysMutex);
+            namedKey = session->context->namedKeys;
+            while (namedKey != NULL) {
+                if (nameSz == namedKey->nameSz &&
+                           XSTRNCMP((char*)name, namedKey->name, nameSz) == 0) {
+                    if (wolfSSL_use_PrivateKey_buffer(session->sslServer,
+                                            namedKey->key, namedKey->keySz,
+                                            SSL_FILETYPE_ASN1) != SSL_SUCCESS) {
+                        UnLockMutex(&session->context->namedKeysMutex);
+                        SetError(CLIENT_HELLO_LATE_KEY_STR, error, session,
+                                                             FATAL_ERROR_STATE);
+                        return -1;
+                    }
+                    break;
+                }
+                else
+                    namedKey = namedKey->next;
+            }
+            UnLockMutex(&session->context->namedKeysMutex);
+        }
+    }
+#endif
+
+    session->flags.clientHello = 1;  /* don't process again */
+
+    /* make sure can read up to session len */
+    if (toRead > *sslBytes) {
+        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    /* skip, get negotiated one from server hello */
+    input     += VERSION_SZ;
+    *sslBytes -= VERSION_SZ;
+
+    XMEMCPY(session->sslServer->arrays->clientRandom, input, RAN_LEN);
+    XMEMCPY(session->sslClient->arrays->clientRandom, input, RAN_LEN);
+
+    input     += RAN_LEN;
+    *sslBytes -= RAN_LEN;
+
+    /* store session in case trying to resume */
+    bLen = *input++;
+    *sslBytes -= ENUM_LEN;
+    if (bLen) {
+        if (ID_LEN > *sslBytes) {
+            SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        Trace(CLIENT_RESUME_TRY_STR);
+        XMEMCPY(session->sslClient->arrays->sessionID, input, ID_LEN);
+        session->sslClient->options.haveSessionId = 1;
+    }
+#ifdef SHOW_SECRETS
+    {
+        int i;
+        printf("client random: ");
+        for (i = 0; i < RAN_LEN; i++)
+            printf("%02x", session->sslServer->arrays->clientRandom[i]);
+        printf("\n");
+    }
+#endif
+
+    input     += bLen;
+    *sslBytes -= bLen;
+
+    /* skip cipher suites */
+    /* make sure can read len */
+    if (SUITE_LEN > *sslBytes) {
+        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    len = (word16)((input[0] << 8) | input[1]);
+    input     += SUITE_LEN;
+    *sslBytes -= SUITE_LEN;
+    /* make sure can read suites + comp len */
+    if (len + ENUM_LEN > *sslBytes) {
+        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    input     += len;
+    *sslBytes -= len;
+
+    /* skip compression */
+    bLen       = *input++;
+    *sslBytes -= ENUM_LEN;
+    /* make sure can read len */
+    if (bLen > *sslBytes) {
+        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    input     += bLen;
+    *sslBytes -= bLen;
+  
+    if (*sslBytes == 0) {
+        /* no extensions */
+        return 0;
+    }
+    
+    /* skip extensions until session ticket */
+    /* make sure can read len */
+    if (SUITE_LEN > *sslBytes) {
+        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    len = (word16)((input[0] << 8) | input[1]);
+    input     += SUITE_LEN;
+    *sslBytes -= SUITE_LEN;
+    /* make sure can read through all extensions */
+    if (len > *sslBytes) {
+        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    while (len > EXT_TYPE_SZ + LENGTH_SZ) {
+        byte   extType[EXT_TYPE_SZ];
+        word16 extLen;
+
+        extType[0] = input[0];
+        extType[1] = input[1];
+        input     += EXT_TYPE_SZ;
+        *sslBytes -= EXT_TYPE_SZ;
+
+        extLen = (word16)((input[0] << 8) | input[1]);
+        input     += LENGTH_SZ;
+        *sslBytes -= LENGTH_SZ;
+
+        /* make sure can read through individual extension */
+        if (extLen > *sslBytes) {
+            SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+
+        if (extType[0] == 0x00 && extType[1] == TICKET_EXT_ID) {
+
+            /* make sure can read through ticket if there is a non blank one */
+            if (extLen && extLen < ID_LEN) {
+                SetError(CLIENT_HELLO_INPUT_STR, error, session,
+                         FATAL_ERROR_STATE);
+                return -1;
+            }
+
+            if (extLen) {
+                if (session->ticketID == 0) {
+                    session->ticketID = (byte*)malloc(ID_LEN);
+                    if (session->ticketID == 0) {
+                        SetError(MEMORY_STR, error, session,
+                                 FATAL_ERROR_STATE);
+                        return -1;
+                    }
+                }
+                XMEMCPY(session->ticketID, input + extLen - ID_LEN, ID_LEN);
+            }
+        }
+
+        input     += extLen;
+        *sslBytes -= extLen;
+        len       -= extLen + EXT_TYPE_SZ + LENGTH_SZ;
+    }
+
+    return 0;
+}
+
+
+/* Process Finished */
+static int ProcessFinished(const byte* input, int size, int* sslBytes,
+                           SnifferSession* session, char* error)
+{
+    SSL*   ssl;
+    word32 inOutIdx = 0;
+    int    ret;
+                
+    if (session->flags.side == WOLFSSL_SERVER_END)
+        ssl = session->sslServer;
+    else
+        ssl = session->sslClient;
+
+    ret = DoFinished(ssl, input, &inOutIdx, (word32) size, (word32) *sslBytes,
+                                                                         SNIFF);
+    *sslBytes -= (int)inOutIdx;
+
+    if (ret < 0) {
+        SetError(BAD_FINISHED_MSG, error, session, FATAL_ERROR_STATE);
+        return ret;
+    }
+                
+    if (ret == 0 && session->flags.cached == 0) {
+        if (session->sslServer->options.haveSessionId) {
+            WOLFSSL_SESSION* sess = GetSession(session->sslServer, NULL);
+            if (sess == NULL)
+                AddSession(session->sslServer);  /* don't re add */
+            session->flags.cached = 1;
+         }
+    }
+
+    /* If receiving a finished message from one side, free the resources
+     * from the other side's tracker. */
+    if (session->flags.side == WOLFSSL_SERVER_END)
+        FreeHandshakeResources(session->sslClient);
+    else
+        FreeHandshakeResources(session->sslServer);
+
+    return ret;
+}
+
+
+/* Process HandShake input */
+static int DoHandShake(const byte* input, int* sslBytes,
+                       SnifferSession* session, char* error)
+{
+    byte type;
+    int  size;
+    int  ret = 0;
+    int  startBytes;
+
+    if (*sslBytes < HANDSHAKE_HEADER_SZ) {
+        SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    type = input[0];
+    size = (input[1] << 16) | (input[2] << 8) | input[3];
+    
+    input     += HANDSHAKE_HEADER_SZ;
+    *sslBytes -= HANDSHAKE_HEADER_SZ;
+    startBytes = *sslBytes;
+
+    if (*sslBytes < size) {
+        SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    /* A session's arrays are released when the handshake is completed. */
+    if (session->sslServer->arrays == NULL &&
+        session->sslClient->arrays == NULL) {
+
+        SetError(NO_SECURE_RENEGOTIATION, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    
+    switch (type) {
+        case hello_verify_request:
+            Trace(GOT_HELLO_VERIFY_STR);
+            break;
+        case hello_request:
+            Trace(GOT_HELLO_REQUEST_STR);
+            break;
+        case session_ticket:
+            Trace(GOT_SESSION_TICKET_STR);
+            ret = ProcessSessionTicket(input, sslBytes, session, error);
+            break;
+        case server_hello:
+            Trace(GOT_SERVER_HELLO_STR);
+            ret = ProcessServerHello(input, sslBytes, session, error);
+            break;
+        case certificate_request:
+            Trace(GOT_CERT_REQ_STR);
+            break;
+        case server_key_exchange:
+            Trace(GOT_SERVER_KEY_EX_STR);
+            /* can't know temp key passively */
+            SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
+            ret = -1;
+            break;
+        case certificate:
+            Trace(GOT_CERT_STR);
+            break;
+        case server_hello_done:
+            Trace(GOT_SERVER_HELLO_DONE_STR);
+            break;
+        case finished:
+            Trace(GOT_FINISHED_STR);
+            ret = ProcessFinished(input, size, sslBytes, session, error);
+            break;
+        case client_hello:
+            Trace(GOT_CLIENT_HELLO_STR);
+            ret = ProcessClientHello(input, sslBytes, session, error);
+            break;
+        case client_key_exchange:
+            Trace(GOT_CLIENT_KEY_EX_STR);
+            ret = ProcessClientKeyExchange(input, sslBytes, session, error);
+            break;
+        case certificate_verify:
+            Trace(GOT_CERT_VER_STR);
+            break;
+        case certificate_status:
+            Trace(GOT_CERT_STATUS_STR);
+            break;
+        default:
+            SetError(GOT_UNKNOWN_HANDSHAKE_STR, error, session, 0);
+            return -1;
+    }
+
+    *sslBytes = startBytes - size;  /* actual bytes of full process */
+
+    return ret;
+}
+
+
+/* Decrypt input into plain output, 0 on success */
+static int Decrypt(SSL* ssl, byte* output, const byte* input, word32 sz)
+{
+    int ret = 0;
+
+    switch (ssl->specs.bulk_cipher_algorithm) {
+        #ifdef BUILD_ARC4
+        case wolfssl_rc4:
+            wc_Arc4Process(ssl->decrypt.arc4, output, input, sz);
+            break;
+        #endif
+            
+        #ifdef BUILD_DES3
+        case wolfssl_triple_des:
+            ret = wc_Des3_CbcDecrypt(ssl->decrypt.des3, output, input, sz);
+            break;
+        #endif
+            
+        #ifdef BUILD_AES
+        case wolfssl_aes:
+            ret = wc_AesCbcDecrypt(ssl->decrypt.aes, output, input, sz);
+            break;
+        #endif
+            
+        #ifdef HAVE_HC128
+        case wolfssl_hc128:
+            wc_Hc128_Process(ssl->decrypt.hc128, output, input, sz);
+            break;
+        #endif
+            
+        #ifdef BUILD_RABBIT
+        case wolfssl_rabbit:
+            wc_RabbitProcess(ssl->decrypt.rabbit, output, input, sz);
+            break;
+        #endif
+
+        #ifdef HAVE_CAMELLIA 
+        case wolfssl_camellia:
+            wc_CamelliaCbcDecrypt(ssl->decrypt.cam, output, input, sz);
+            break;
+        #endif
+
+        #ifdef HAVE_IDEA
+        case wolfssl_idea:
+            wc_IdeaCbcDecrypt(ssl->decrypt.idea, output, input, sz);
+            break;
+        #endif
+
+        #ifdef HAVE_AESGCM
+        case wolfssl_aes_gcm:
+            if (sz >= (word32)(AEAD_EXP_IV_SZ + ssl->specs.aead_mac_size))
+            {
+                byte nonce[AEAD_NONCE_SZ];
+                XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
+                XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
+
+                if (wc_AesGcmEncrypt(ssl->decrypt.aes,
+                            output,
+                            input + AEAD_EXP_IV_SZ,
+                            sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
+                            nonce, AEAD_NONCE_SZ,
+                            NULL, 0,
+                            NULL, 0) < 0) {
+                    Trace(BAD_DECRYPT);
+                    ret = -1;
+                }
+                ForceZero(nonce, AEAD_NONCE_SZ);
+            }
+            else {
+                Trace(BAD_DECRYPT_SIZE);
+                ret = -1;
+            }
+            break;
+         #endif
+
+        default:
+            Trace(BAD_DECRYPT_TYPE);
+            ret = -1;
+            break;
+    }
+
+    return ret;
+}
+
+
+/* Decrypt input message into output, adjust output steam if needed */
+static const byte* DecryptMessage(SSL* ssl, const byte* input, word32 sz,
+                                  byte* output, int* error, int* advance)
+{
+    int ivExtra = 0;
+
+    int ret = Decrypt(ssl, output, input, sz);
+    if (ret != 0) {
+        *error = ret;
+        return NULL;
+    }
+    ssl->keys.encryptSz = sz;
+    if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) {
+        output += ssl->specs.block_size;     /* go past TLSv1.1 IV */
+        ivExtra = ssl->specs.block_size;
+        *advance = ssl->specs.block_size;
+    }
+
+    if (ssl->specs.cipher_type == aead) {
+        *advance = ssl->specs.aead_mac_size;
+        ssl->keys.padSz = ssl->specs.aead_mac_size;
+    }
+    else
+        ssl->keys.padSz = ssl->specs.hash_size;
+
+    if (ssl->specs.cipher_type == block)
+        ssl->keys.padSz += *(output + sz - ivExtra - 1) + 1;
+    
+    return output;
+}
+
+
+/* remove session from table, use rowHint if no info (means we have a lock) */
+static void RemoveSession(SnifferSession* session, IpInfo* ipInfo,
+                        TcpInfo* tcpInfo, word32 rowHint)
+{
+    SnifferSession* previous = 0;
+    SnifferSession* current;
+    word32          row = rowHint;
+    int             haveLock = 0;
+   
+    if (ipInfo && tcpInfo)
+        row = SessionHash(ipInfo, tcpInfo);
+    else
+        haveLock = 1;
+    
+    assert(row <= HASH_SIZE);
+    Trace(REMOVE_SESSION_STR);
+    
+    if (!haveLock)
+        LockMutex(&SessionMutex);
+    
+    current = SessionTable[row];
+    
+    while (current) {
+        if (current == session) {
+            if (previous)
+                previous->next = current->next;
+            else
+                SessionTable[row] = current->next;
+            FreeSnifferSession(session);
+            TraceRemovedSession();
+            break;
+        }
+        previous = current;
+        current  = current->next;
+    }
+    
+    if (!haveLock)
+        UnLockMutex(&SessionMutex);
+}
+
+
+/* Remove stale sessions from the Session Table, have a lock */
+static void RemoveStaleSessions(void)
+{
+    word32 i;
+    SnifferSession* session;
+    
+    for (i = 0; i < HASH_SIZE; i++) {
+        session = SessionTable[i];
+        while (session) {
+            SnifferSession* next = session->next; 
+            if (time(NULL) >= session->lastUsed + WOLFSSL_SNIFFER_TIMEOUT) {
+                TraceStaleSession();
+                RemoveSession(session, NULL, NULL, i);
+            }
+            session = next;
+        }
+    }
+}
+
+
+/* Create a new Sniffer Session */
+static SnifferSession* CreateSession(IpInfo* ipInfo, TcpInfo* tcpInfo,
+                                     char* error)
+{
+    SnifferSession* session = 0;
+    int row;
+        
+    Trace(NEW_SESSION_STR);
+    /* create a new one */
+    session = (SnifferSession*)malloc(sizeof(SnifferSession));
+    if (session == NULL) {
+        SetError(MEMORY_STR, error, NULL, 0);
+        return 0;
+    }
+    InitSession(session);
+    session->server  = ipInfo->dst;
+    session->client  = ipInfo->src;
+    session->srvPort = (word16)tcpInfo->dstPort;
+    session->cliPort = (word16)tcpInfo->srcPort;
+    session->cliSeqStart = tcpInfo->sequence;
+    session->cliExpected = 1;  /* relative */
+    session->lastUsed= time(NULL);
+                
+    session->context = GetSnifferServer(ipInfo, tcpInfo);
+    if (session->context == NULL) {
+        SetError(SERVER_NOT_REG_STR, error, NULL, 0);
+        free(session);
+        return 0;
+    }
+        
+    session->sslServer = SSL_new(session->context->ctx);
+    if (session->sslServer == NULL) {
+        SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE);
+        free(session);
+        return 0;
+    }
+    session->sslClient = SSL_new(session->context->ctx);
+    if (session->sslClient == NULL) {
+        SSL_free(session->sslServer);
+        session->sslServer = 0;
+
+        SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE);
+        free(session);
+        return 0;
+    }
+    /* put server back into server mode */
+    session->sslServer->options.side = WOLFSSL_SERVER_END;
+        
+    row = SessionHash(ipInfo, tcpInfo);
+    
+    /* add it to the session table */
+    LockMutex(&SessionMutex);
+        
+    session->next = SessionTable[row];
+    SessionTable[row] = session;
+    
+    SessionCount++;
+    
+    if ( (SessionCount % HASH_SIZE) == 0) {
+        TraceFindingStale();
+        RemoveStaleSessions();
+    }
+        
+    UnLockMutex(&SessionMutex);
+        
+    /* determine headed side */
+    if (ipInfo->dst == session->context->server &&
+        tcpInfo->dstPort == session->context->port)
+        session->flags.side = WOLFSSL_SERVER_END;
+    else
+        session->flags.side = WOLFSSL_CLIENT_END;        
+    
+    return session;
+}
+
+
+#ifdef OLD_HELLO_ALLOWED
+
+/* Process Old Client Hello Input */
+static int DoOldHello(SnifferSession* session, const byte* sslFrame,
+                      int* rhSize, int* sslBytes, char* error)
+{
+    const byte* input = sslFrame;
+    byte        b0, b1;
+    word32      idx = 0;
+    int         ret;
+
+    Trace(GOT_OLD_CLIENT_HELLO_STR);
+    session->flags.clientHello = 1;    /* don't process again */
+    b0 = *input++;
+    b1 = *input++;
+    *sslBytes -= 2;
+    *rhSize = ((b0 & 0x7f) << 8) | b1;
+
+    if (*rhSize > *sslBytes) {
+        SetError(OLD_CLIENT_INPUT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+
+    ret = ProcessOldClientHello(session->sslServer, input, &idx, *sslBytes,
+                                (word16)*rhSize);    
+    if (ret < 0 && ret != MATCH_SUITE_ERROR) {
+        SetError(BAD_OLD_CLIENT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    
+    Trace(OLD_CLIENT_OK_STR);
+    XMEMCPY(session->sslClient->arrays->clientRandom,
+           session->sslServer->arrays->clientRandom, RAN_LEN);
+    
+    *sslBytes -= *rhSize;
+    return 0;
+}
+
+#endif /* OLD_HELLO_ALLOWED */
+
+
+#if 0
+/* Calculate the TCP checksum, see RFC 1071 */
+/* return 0 for success, -1 on error */
+/* can be called from decode() with
+   TcpChecksum(&ipInfo, &tcpInfo, sslBytes, packet + ipInfo.length);
+   could also add a 64bit version if type available and using this
+*/
+int TcpChecksum(IpInfo* ipInfo, TcpInfo* tcpInfo, int dataLen,
+                const byte* packet)
+{
+    TcpPseudoHdr  pseudo;
+    int           count = PSEUDO_HDR_SZ;
+    const word16* data = (word16*)&pseudo;
+    word32        sum = 0;
+    word16        checksum;
+    
+    pseudo.src = ipInfo->src;
+    pseudo.dst = ipInfo->dst;
+    pseudo.rsv = 0;
+    pseudo.protocol = TCP_PROTO;
+    pseudo.legnth = htons(tcpInfo->length + dataLen);
+    
+    /* pseudo header sum */
+    while (count >= 2) {
+        sum   += *data++;
+        count -= 2;
+    }
+    
+    count = tcpInfo->length + dataLen;
+    data = (word16*)packet;
+    
+    /* main sum */
+    while (count > 1) {
+        sum   += *data++;
+        count -=2;
+    }
+    
+    /* get left-over, if any */
+    packet = (byte*)data;
+    if (count > 0) {
+        sum += *packet;
+    }
+    
+    /* fold 32bit sum into 16 bits */
+    while (sum >> 16)
+        sum = (sum & 0xffff) + (sum >> 16);
+    
+    checksum = (word16)~sum;
+    /* checksum should now equal 0, since included already calcd checksum */
+    /* field, but tcp checksum offloading could negate calculation */
+    if (checksum == 0)
+        return 0;
+    return -1;
+}
+#endif
+
+
+/* Check IP and TCP headers, set payload */
+/* returns 0 on success, -1 on error */
+static int CheckHeaders(IpInfo* ipInfo, TcpInfo* tcpInfo, const byte* packet,
+                  int length, const byte** sslFrame, int* sslBytes, char* error)
+{
+    TraceHeader();
+    TracePacket();
+
+    /* ip header */
+    if (length < IP_HDR_SZ) {
+        SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
+        return -1;
+    }
+    if (CheckIpHdr((IpHdr*)packet, ipInfo, length, error) != 0)
+        return -1;
+   
+    /* tcp header */ 
+    if (length < (ipInfo->length + TCP_HDR_SZ)) {
+        SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
+        return -1;
+    }
+    if (CheckTcpHdr((TcpHdr*)(packet + ipInfo->length), tcpInfo, error) != 0)
+        return -1;
+   
+    /* setup */ 
+    *sslFrame = packet + ipInfo->length + tcpInfo->length;
+    if (*sslFrame > packet + length) {
+        SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
+        return -1;
+    }
+    *sslBytes = (int)(packet + length - *sslFrame);
+    
+    return 0;
+}
+
+
+/* Create or Find existing session */
+/* returns 0 on success (continue), -1 on error, 1 on success (end) */
+static int CheckSession(IpInfo* ipInfo, TcpInfo* tcpInfo, int sslBytes,
+                        SnifferSession** session, char* error)
+{
+    /* create a new SnifferSession on client SYN */
+    if (tcpInfo->syn && !tcpInfo->ack) {
+        TraceClientSyn(tcpInfo->sequence);
+        *session = CreateSession(ipInfo, tcpInfo, error);
+        if (*session == NULL) {
+            *session = GetSnifferSession(ipInfo, tcpInfo);
+            /* already had exisiting, so OK */
+            if (*session)
+                return 1;
+            
+            SetError(MEMORY_STR, error, NULL, 0);
+            return -1;
+        }
+        return 1;
+    }
+    /* get existing sniffer session */
+    else {
+        *session = GetSnifferSession(ipInfo, tcpInfo);
+        if (*session == NULL) {
+            /* don't worry about extraneous RST or duplicate FINs */
+            if (tcpInfo->fin || tcpInfo->rst)
+                return 1;
+            /* don't worry about duplicate ACKs either */
+            if (sslBytes == 0 && tcpInfo->ack)
+                return 1;
+            
+            SetError(BAD_SESSION_STR, error, NULL, 0);
+            return -1;
+        }        
+    }
+    return 0;
+}
+
+
+/* Create a Packet Buffer from *begin - end, adjust new *begin and bytesLeft */
+static PacketBuffer* CreateBuffer(word32* begin, word32 end, const byte* data,
+                                  int* bytesLeft)
+{
+    PacketBuffer* pb;
+    
+    int added = end - *begin + 1;
+    assert(*begin <= end);
+    
+    pb = (PacketBuffer*)malloc(sizeof(PacketBuffer));
+    if (pb == NULL) return NULL;
+    
+    pb->next  = 0;
+    pb->begin = *begin;
+    pb->end   = end;
+    pb->data = (byte*)malloc(added);
+    
+    if (pb->data == NULL) {
+        free(pb);
+        return NULL;
+    }
+    XMEMCPY(pb->data, data, added);
+    
+    *bytesLeft -= added;
+    *begin      = pb->end + 1;
+    
+    return pb;
+}
+
+
+/* Add sslFrame to Reassembly List */
+/* returns 1 (end) on success, -1, on error */
+static int AddToReassembly(byte from, word32 seq, const byte* sslFrame,
+                           int sslBytes, SnifferSession* session, char* error)
+{
+    PacketBuffer*  add;
+    PacketBuffer** front = (from == WOLFSSL_SERVER_END) ?
+                       &session->cliReassemblyList: &session->srvReassemblyList;
+    PacketBuffer*  curr = *front;
+    PacketBuffer*  prev = curr;
+    
+    word32* reassemblyMemory = (from == WOLFSSL_SERVER_END) ?
+                  &session->cliReassemblyMemory : &session->srvReassemblyMemory;
+    word32  startSeq = seq;
+    word32  added;
+    int     bytesLeft = sslBytes;  /* could be overlapping fragment */
+
+    /* if list is empty add full frame to front */
+    if (!curr) {
+        if (MaxRecoveryMemory != -1 &&
+                      (int)(*reassemblyMemory + sslBytes) > MaxRecoveryMemory) {
+            SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        add = CreateBuffer(&seq, seq + sslBytes - 1, sslFrame, &bytesLeft);
+        if (add == NULL) {
+            SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        *front = add;
+        *reassemblyMemory += sslBytes;
+        return 1;
+    }
+    
+    /* add to front if before current front, up to next->begin */
+    if (seq < curr->begin) {
+        word32 end = seq + sslBytes - 1;
+        
+        if (end >= curr->begin)
+            end = curr->begin - 1;
+        
+        if (MaxRecoveryMemory -1 &&
+                      (int)(*reassemblyMemory + sslBytes) > MaxRecoveryMemory) {
+            SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        add = CreateBuffer(&seq, end, sslFrame, &bytesLeft);
+        if (add == NULL) {
+            SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        add->next = curr;
+        *front = add;
+        *reassemblyMemory += sslBytes;
+    }
+    
+    /* while we have bytes left, try to find a gap to fill */
+    while (bytesLeft > 0) {
+        /* get previous packet in list */
+        while (curr && (seq >= curr->begin)) {
+            prev = curr;
+            curr = curr->next;
+        }
+        
+        /* don't add  duplicate data */
+        if (prev->end >= seq) {
+            if ( (seq + bytesLeft - 1) <= prev->end)
+                return 1;
+            seq = prev->end + 1;
+            bytesLeft = startSeq + sslBytes - seq;
+        }
+        
+        if (!curr)
+            /* we're at the end */
+            added = bytesLeft;
+        else 
+            /* we're in between two frames */
+            added = min((word32)bytesLeft, curr->begin - seq);
+        
+        /* data already there */
+        if (added == 0)
+            continue;
+        
+        if (MaxRecoveryMemory != -1 &&
+                         (int)(*reassemblyMemory + added) > MaxRecoveryMemory) {
+            SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        add = CreateBuffer(&seq, seq + added - 1, &sslFrame[seq - startSeq],
+                           &bytesLeft);
+        if (add == NULL) {
+            SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        add->next  = prev->next;
+        prev->next = add;
+        *reassemblyMemory += added;
+    }
+    return 1;
+}
+
+
+/* Add out of order FIN capture */
+/* returns 1 for success (end) */
+static int AddFinCapture(SnifferSession* session, word32 sequence)
+{
+    if (session->flags.side == WOLFSSL_SERVER_END) {
+        if (session->finCaputre.cliCounted == 0)
+            session->finCaputre.cliFinSeq = sequence;
+    }
+    else {
+        if (session->finCaputre.srvCounted == 0)
+            session->finCaputre.srvFinSeq = sequence;
+    }
+    return 1;
+}
+
+
+/* Adjust incoming sequence based on side */
+/* returns 0 on success (continue), -1 on error, 1 on success (end) */
+static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session,
+                          int* sslBytes, const byte** sslFrame, char* error)
+{
+    word32  seqStart = (session->flags.side == WOLFSSL_SERVER_END) ? 
+                                     session->cliSeqStart :session->srvSeqStart;
+    word32  real     = tcpInfo->sequence - seqStart;
+    word32* expected = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                  &session->cliExpected : &session->srvExpected;
+    PacketBuffer* reassemblyList = (session->flags.side == WOLFSSL_SERVER_END) ?
+                        session->cliReassemblyList : session->srvReassemblyList;
+    byte  skipPartial = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                session->flags.srvSkipPartial :
+                                session->flags.cliSkipPartial;
+    
+    /* handle rollover of sequence */
+    if (tcpInfo->sequence < seqStart)
+        real = 0xffffffffU - seqStart + tcpInfo->sequence;
+        
+    TraceRelativeSequence(*expected, real);
+    
+    if (real < *expected) {
+        Trace(DUPLICATE_STR);
+        if (real + *sslBytes > *expected) {
+            int overlap = *expected - real;
+            Trace(OVERLAP_DUPLICATE_STR);
+                
+            /* adjust to expected, remove duplicate */
+            *sslFrame += overlap;
+            *sslBytes -= overlap;
+
+            /* The following conditional block is duplicated below. It is the
+             * same action but for a different setup case. If changing this
+             * block be sure to also update the block below. */
+            if (reassemblyList) {
+                word32 newEnd = *expected + *sslBytes;
+                    
+                if (newEnd > reassemblyList->begin) {
+                    Trace(OVERLAP_REASSEMBLY_BEGIN_STR);
+                    
+                    /* remove bytes already on reassembly list */
+                    *sslBytes -= newEnd - reassemblyList->begin;
+                }
+                if (newEnd > reassemblyList->end) {
+                    Trace(OVERLAP_REASSEMBLY_END_STR);
+                    
+                    /* may be past reassembly list end (could have more on list)
+                       so try to add what's past the front->end */
+                    AddToReassembly(session->flags.side, reassemblyList->end +1,
+                                *sslFrame + reassemblyList->end - *expected + 1,
+                                 newEnd - reassemblyList->end, session, error);
+                }
+            }
+        }
+        else
+            return 1;
+    }
+    else if (real > *expected) {
+        Trace(OUT_OF_ORDER_STR);
+        if (*sslBytes > 0) {
+            int addResult = AddToReassembly(session->flags.side, real,
+                                          *sslFrame, *sslBytes, session, error);
+            if (skipPartial) {
+                *sslBytes = 0;
+                return 0;
+            }
+            else
+                return addResult;
+        }
+        else if (tcpInfo->fin)
+            return AddFinCapture(session, real);
+    }
+    else if (*sslBytes > 0) {
+        if (skipPartial) {
+            AddToReassembly(session->flags.side, real,
+                                          *sslFrame, *sslBytes, session, error);
+            *expected += *sslBytes;
+            *sslBytes = 0;
+            if (tcpInfo->fin)
+                *expected += 1;
+            return 0;
+        }
+        /* The following conditional block is duplicated above. It is the
+         * same action but for a different setup case. If changing this
+         * block be sure to also update the block above. */
+        else if (reassemblyList) {
+            word32 newEnd = *expected + *sslBytes;
+
+            if (newEnd > reassemblyList->begin) {
+                Trace(OVERLAP_REASSEMBLY_BEGIN_STR);
+
+                /* remove bytes already on reassembly list */
+                *sslBytes -= newEnd - reassemblyList->begin;
+            }
+            if (newEnd > reassemblyList->end) {
+                Trace(OVERLAP_REASSEMBLY_END_STR);
+
+                /* may be past reassembly list end (could have more on list)
+                   so try to add what's past the front->end */
+                AddToReassembly(session->flags.side, reassemblyList->end +1,
+                            *sslFrame + reassemblyList->end - *expected + 1,
+                             newEnd - reassemblyList->end, session, error);
+            }
+        }
+    }
+    /* got expected sequence */
+    *expected += *sslBytes;
+    if (tcpInfo->fin)
+        *expected += 1;
+    
+    return 0;
+}
+
+
+static int FindNextRecordInAssembly(SnifferSession* session,
+                                    const byte** sslFrame, int* sslBytes,
+                                    const byte** end, char* error)
+{
+    PacketBuffer**     front = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                    &session->cliReassemblyList :
+                                    &session->srvReassemblyList;
+    PacketBuffer*       curr = *front;
+    PacketBuffer*       prev = NULL;
+    byte*        skipPartial = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                    &session->flags.srvSkipPartial :
+                                    &session->flags.cliSkipPartial;
+    word32* reassemblyMemory = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                    &session->cliReassemblyMemory :
+                                    &session->srvReassemblyMemory;
+    SSL*                 ssl = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                    session->sslServer :
+                                    session->sslClient;
+    ProtocolVersion       pv = ssl->version;
+    word32*         expected = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                    &session->cliExpected :
+                                    &session->srvExpected;
+
+    while (curr != NULL) {
+        *expected = curr->end + 1;
+
+        if (curr->data[0] == application_data &&
+            curr->data[1] == pv.major &&
+            curr->data[2] == pv.minor) {
+
+            if (ssl->buffers.inputBuffer.length > 0)
+                Trace(DROPPING_PARTIAL_RECORD);
+
+            *sslBytes = curr->end - curr->begin + 1;
+            if ( (word32)*sslBytes > ssl->buffers.inputBuffer.bufferSize) {
+                if (GrowInputBuffer(ssl, *sslBytes, 0) < 0) {
+                    SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
+                    return -1;
+                }
+            }
+
+            XMEMCPY(ssl->buffers.inputBuffer.buffer, curr->data, *sslBytes);
+
+            *front = curr->next;
+            *reassemblyMemory -= *sslBytes;
+            FreePacketBuffer(curr);
+
+            ssl->buffers.inputBuffer.length = *sslBytes;
+            *sslFrame = ssl->buffers.inputBuffer.buffer;
+            *end = *sslFrame + *sslBytes;
+            *skipPartial = 0;
+
+            return 0;
+        }
+        else if (ssl->specs.cipher_type == block) {
+            if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes)
+                wc_AesSetIV(ssl->decrypt.aes,
+                            curr->data + curr->end - curr->begin
+                                       - ssl->specs.block_size + 1);
+            else if (ssl->specs.bulk_cipher_algorithm == wolfssl_triple_des)
+                wc_Des3_SetIV(ssl->decrypt.des3,
+                              curr->data + curr->end - curr->begin
+                                         - ssl->specs.block_size + 1);
+        }
+
+        Trace(DROPPING_LOST_FRAG_STR);
+        prev = curr;
+        curr = curr->next;
+        *reassemblyMemory -= (prev->end - prev->begin + 1);
+        FreePacketBuffer(prev);
+    }
+
+    *front = curr;
+
+    return 0;
+}
+
+
+static int FixSequence(TcpInfo* tcpInfo, SnifferSession* session)
+{
+    word32*   expected = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                &session->srvExpected : &session->cliExpected;
+    PacketBuffer* list = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                session->srvReassemblyList :
+                                session->cliReassemblyList;
+    byte*  skipPartial = (session->flags.side != WOLFSSL_SERVER_END) ?
+                                &session->flags.srvSkipPartial :
+                                &session->flags.cliSkipPartial;
+
+    *skipPartial = 1;
+    if (list != NULL)
+        *expected = list->begin;
+    else {
+        word32 seqStart = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                session->srvSeqStart : session->cliSeqStart;
+        word32     real = tcpInfo->ackNumber - seqStart;
+
+        *expected = real;
+    }
+
+    return 1;
+}
+
+
+/* Check latest ack number for missing packets
+   return 0 ok, <0 on error */
+static int CheckAck(TcpInfo* tcpInfo, SnifferSession* session)
+{
+    if (tcpInfo->ack) {
+        word32  seqStart = (session->flags.side == WOLFSSL_SERVER_END) ? 
+                                     session->srvSeqStart :session->cliSeqStart;
+        word32  real     = tcpInfo->ackNumber - seqStart;
+        word32  expected = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                  session->srvExpected : session->cliExpected;
+    
+        /* handle rollover of sequence */
+        if (tcpInfo->ackNumber < seqStart)
+            real = 0xffffffffU - seqStart + tcpInfo->ackNumber;
+        
+        TraceAck(real, expected);
+
+        if (real > expected)
+            return -1;  /* we missed a packet, ACKing data we never saw */
+    }
+    return 0;
+}
+
+
+/* Check TCP Sequence status */
+/* returns 0 on success (continue), -1 on error, 1 on success (end) */
+static int CheckSequence(IpInfo* ipInfo, TcpInfo* tcpInfo,
+                         SnifferSession* session, int* sslBytes,
+                         const byte** sslFrame, char* error)
+{
+    int actualLen;
+    byte* ackFault = (session->flags.side == WOLFSSL_SERVER_END) ?
+                        &session->flags.cliAckFault :
+                        &session->flags.srvAckFault;
+
+    /* init SEQ from server to client */
+    if (tcpInfo->syn && tcpInfo->ack) {
+        session->srvSeqStart = tcpInfo->sequence;
+        session->srvExpected = 1;
+        TraceServerSyn(tcpInfo->sequence);
+        return 1;
+    }
+    
+    /* adjust potential ethernet trailer */
+    actualLen = ipInfo->total - ipInfo->length - tcpInfo->length;
+    if (*sslBytes > actualLen) {
+        *sslBytes = actualLen;
+    }
+    
+    TraceSequence(tcpInfo->sequence, *sslBytes);
+    if (CheckAck(tcpInfo, session) < 0) {
+        if (!RecoveryEnabled) {
+            UpdateMissedDataSessions();
+            SetError(ACK_MISSED_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        else {
+            SetError(ACK_MISSED_STR, error, session, 0);
+            if (*ackFault == 0) {
+                *ackFault = 1;
+                UpdateMissedDataSessions();
+            }
+            return FixSequence(tcpInfo, session);
+        }
+    }
+    
+    if (*ackFault) {
+        Trace(CLEAR_ACK_FAULT);
+        *ackFault = 0;
+    }
+
+    return AdjustSequence(tcpInfo, session, sslBytes, sslFrame, error);    
+}
+
+
+/* Check Status before record processing */
+/* returns 0 on success (continue), -1 on error, 1 on success (end) */
+static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
+                          const byte** sslFrame, SnifferSession** session,
+                          int* sslBytes, const byte** end, char* error)
+{
+    word32 length;
+    SSL*  ssl = ((*session)->flags.side == WOLFSSL_SERVER_END) ?
+                                  (*session)->sslServer : (*session)->sslClient;
+    byte  skipPartial = ((*session)->flags.side == WOLFSSL_SERVER_END) ?
+                        (*session)->flags.srvSkipPartial :
+                        (*session)->flags.cliSkipPartial;
+    /* remove SnifferSession on 2nd FIN or RST */
+    if (tcpInfo->fin || tcpInfo->rst) {
+        /* flag FIN and RST */
+        if (tcpInfo->fin)
+            (*session)->flags.finCount += 1;
+        else if (tcpInfo->rst)
+            (*session)->flags.finCount += 2;
+        
+        if ((*session)->flags.finCount >= 2) {
+            RemoveSession(*session, ipInfo, tcpInfo, 0);
+            *session = NULL;
+            return 1;
+        }
+    }
+    
+    if ((*session)->flags.fatalError == FATAL_ERROR_STATE) {
+        SetError(FATAL_ERROR_STR, error, NULL, 0);
+        return -1;
+    }
+    
+    if (skipPartial) {
+        if (FindNextRecordInAssembly(*session,
+                                     sslFrame, sslBytes, end, error) < 0) {
+            return -1;
+        }
+    }
+
+    if (*sslBytes == 0) {
+        Trace(NO_DATA_STR);
+        return 1;
+    }
+    
+    /* if current partial data, add to end of partial */
+    /* if skipping, the data is alread at the end of partial */
+    if ( !skipPartial &&
+         (length = ssl->buffers.inputBuffer.length) ) {
+        Trace(PARTIAL_ADD_STR);
+        
+        if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) {
+            if (GrowInputBuffer(ssl, *sslBytes, length) < 0) {
+                SetError(MEMORY_STR, error, *session, FATAL_ERROR_STATE);
+                return -1;
+            }
+        }
+        XMEMCPY(&ssl->buffers.inputBuffer.buffer[length], *sslFrame, *sslBytes);
+        *sslBytes += length;
+        ssl->buffers.inputBuffer.length = *sslBytes;
+        *sslFrame = ssl->buffers.inputBuffer.buffer;
+        *end = *sslFrame + *sslBytes;
+    }
+
+    if ((*session)->flags.clientHello == 0 && **sslFrame != handshake) {
+        /* Sanity check the packet for an old style client hello. */
+        int rhSize = (((*sslFrame)[0] & 0x7f) << 8) | ((*sslFrame)[1]);
+
+        if ((rhSize <= (*sslBytes - 2)) &&
+            (*sslFrame)[2] == OLD_HELLO_ID && (*sslFrame)[3] == SSLv3_MAJOR) {
+#ifdef OLD_HELLO_ALLOWED
+        int ret = DoOldHello(*session, *sslFrame, &rhSize, sslBytes, error);
+        if (ret < 0)
+            return -1;  /* error already set */
+        if (*sslBytes <= 0)
+            return 1;
+#endif
+        }
+        else {
+#ifdef STARTTLS_ALLOWED
+            return 1;
+#endif
+        }
+    }
+
+    return 0;
+}
+
+
+/* See if input on the reassembly list is ready for consuming */
+/* returns 1 for TRUE, 0 for FALSE */
+static int HaveMoreInput(SnifferSession* session, const byte** sslFrame,
+                         int* sslBytes, const byte** end, char* error)
+{
+    /* sequence and reassembly based on from, not to */
+    int            moreInput = 0;
+    PacketBuffer** front = (session->flags.side == WOLFSSL_SERVER_END) ?
+                      &session->cliReassemblyList : &session->srvReassemblyList;
+    word32*        expected = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                  &session->cliExpected : &session->srvExpected;
+    /* buffer is on receiving end */
+    word32*        length = (session->flags.side == WOLFSSL_SERVER_END) ?
+                               &session->sslServer->buffers.inputBuffer.length :
+                               &session->sslClient->buffers.inputBuffer.length;
+    byte**         myBuffer = (session->flags.side == WOLFSSL_SERVER_END) ?
+                               &session->sslServer->buffers.inputBuffer.buffer :
+                               &session->sslClient->buffers.inputBuffer.buffer;
+    word32*       bufferSize = (session->flags.side == WOLFSSL_SERVER_END) ?
+                           &session->sslServer->buffers.inputBuffer.bufferSize :
+                           &session->sslClient->buffers.inputBuffer.bufferSize;
+    SSL*               ssl  = (session->flags.side == WOLFSSL_SERVER_END) ?
+                            session->sslServer : session->sslClient;
+    word32*     reassemblyMemory = (session->flags.side == WOLFSSL_SERVER_END) ?
+                  &session->cliReassemblyMemory : &session->srvReassemblyMemory;
+    
+    while (*front && ((*front)->begin == *expected) ) {
+        word32 room = *bufferSize - *length;
+        word32 packetLen = (*front)->end - (*front)->begin + 1;
+
+        if (packetLen > room && *bufferSize < MAX_INPUT_SZ) {
+            if (GrowInputBuffer(ssl, packetLen, *length) < 0) {
+                SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
+                return 0;
+            }
+            room = *bufferSize - *length;   /* bufferSize is now bigger */
+        }
+        
+        if (packetLen <= room) {
+            PacketBuffer* del = *front;
+            byte*         buf = *myBuffer;
+            
+            XMEMCPY(&buf[*length], (*front)->data, packetLen);
+            *length   += packetLen;
+            *expected += packetLen;
+            
+            /* remove used packet */
+            *front = (*front)->next;
+
+            *reassemblyMemory -= packetLen;
+            FreePacketBuffer(del);
+            
+            moreInput = 1;
+        }
+        else
+            break;
+    }
+    if (moreInput) {
+        *sslFrame = *myBuffer;
+        *sslBytes = *length;
+        *end      = *myBuffer + *length;
+    }
+    return moreInput;
+}
+                         
+
+
+/* Process Message(s) from sslFrame */
+/* return Number of bytes on success, 0 for no data yet, and -1 on error */
+static int ProcessMessage(const byte* sslFrame, SnifferSession* session,
+                          int sslBytes, byte** data, const byte* end,
+                          char* error)
+{
+    const byte*       sslBegin = sslFrame;
+    const byte*       recordEnd;   /* end of record indicator */
+    const byte*       inRecordEnd; /* indictor from input stream not decrypt */
+    RecordLayerHeader rh;
+    int               rhSize = 0;
+    int               ret;
+    int               errCode = 0;
+    int               decoded = 0;      /* bytes stored for user in data */
+    int               notEnough;        /* notEnough bytes yet flag */
+    int               decrypted = 0;    /* was current msg decrypted */
+    SSL*              ssl = (session->flags.side == WOLFSSL_SERVER_END) ?
+                                        session->sslServer : session->sslClient;
+doMessage:
+    notEnough = 0;
+    if (sslBytes < 0) {
+        SetError(PACKET_HDR_SHORT_STR, error, session, FATAL_ERROR_STATE);
+        return -1;
+    }
+    if (sslBytes >= RECORD_HEADER_SZ) {
+        if (GetRecordHeader(sslFrame, &rh, &rhSize) != 0) {
+            SetError(BAD_RECORD_HDR_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+    }
+    else
+        notEnough = 1;
+
+    if (notEnough || rhSize > (sslBytes - RECORD_HEADER_SZ)) {
+        /* don't have enough input yet to process full SSL record */
+        Trace(PARTIAL_INPUT_STR);
+        
+        /* store partial if not there already or we advanced */
+        if (ssl->buffers.inputBuffer.length == 0 || sslBegin != sslFrame) {
+            if (sslBytes > (int)ssl->buffers.inputBuffer.bufferSize) {
+                if (GrowInputBuffer(ssl, sslBytes, 0) < 0) { 
+                    SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
+                    return -1;
+                }
+            }
+            XMEMMOVE(ssl->buffers.inputBuffer.buffer, sslFrame, sslBytes);
+            ssl->buffers.inputBuffer.length = sslBytes;
+        }
+        if (HaveMoreInput(session, &sslFrame, &sslBytes, &end, error))
+            goto doMessage;
+        return decoded;
+    }
+    sslFrame += RECORD_HEADER_SZ;
+    sslBytes -= RECORD_HEADER_SZ;
+    recordEnd = sslFrame + rhSize;   /* may have more than one record */
+    inRecordEnd = recordEnd;
+    
+    /* decrypt if needed */
+    if ((session->flags.side == WOLFSSL_SERVER_END &&
+                                               session->flags.serverCipherOn)
+     || (session->flags.side == WOLFSSL_CLIENT_END &&
+                                               session->flags.clientCipherOn)) {
+        int ivAdvance = 0;  /* TLSv1.1 advance amount */
+        if (ssl->decrypt.setup != 1) {
+            SetError(DECRYPT_KEYS_NOT_SETUP, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        if (CheckAvailableSize(ssl, rhSize) < 0) {
+            SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+        sslFrame = DecryptMessage(ssl, sslFrame, rhSize,
+                                  ssl->buffers.outputBuffer.buffer, &errCode,
+                                  &ivAdvance);
+        recordEnd = sslFrame - ivAdvance + rhSize;  /* sslFrame moved so
+                                                       should recordEnd */
+        decrypted = 1;
+        if (errCode != 0) {
+            SetError(BAD_DECRYPT, error, session, FATAL_ERROR_STATE);
+            return -1;
+        }
+    }
+
+doPart:
+            
+    switch ((enum ContentType)rh.type) {
+        case handshake:
+            {
+                int startIdx = sslBytes;
+                int used;
+
+                Trace(GOT_HANDSHAKE_STR);
+                ret = DoHandShake(sslFrame, &sslBytes, session, error);
+                if (ret != 0) {
+                    if (session->flags.fatalError == 0)
+                        SetError(BAD_HANDSHAKE_STR, error, session,
+                                 FATAL_ERROR_STATE);
+                    return -1;
+                }
+
+                /* DoHandShake now fully decrements sslBytes to remaining */
+                used = startIdx - sslBytes;
+                sslFrame += used;
+                if (decrypted)
+                    sslFrame += ssl->keys.padSz;
+            }
+            break;
+        case change_cipher_spec:
+            if (session->flags.side == WOLFSSL_SERVER_END)
+                session->flags.serverCipherOn = 1;
+            else
+                session->flags.clientCipherOn = 1;
+            Trace(GOT_CHANGE_CIPHER_STR);
+            ssl->options.handShakeState = HANDSHAKE_DONE;
+            ssl->options.handShakeDone  = 1;
+
+            sslFrame += 1;
+            sslBytes -= 1;
+
+            break;
+        case application_data:
+            Trace(GOT_APP_DATA_STR);
+            {
+                word32 inOutIdx = 0;
+                    
+                ret = DoApplicationData(ssl, (byte*)sslFrame, &inOutIdx);
+                if (ret == 0) {
+                    ret = ssl->buffers.clearOutputBuffer.length;
+                    TraceGotData(ret);
+                    if (ret) {  /* may be blank message */
+                        byte* tmpData;  /* don't leak on realloc free */
+                        /* add an extra byte at end of allocation in case user
+                         * wants to null terminate plaintext */
+                        tmpData = (byte*)realloc(*data, decoded + ret + 1);
+                        if (tmpData == NULL) {
+                            free(*data);
+                            *data = NULL;
+                            SetError(MEMORY_STR, error, session,
+                                     FATAL_ERROR_STATE);
+                            return -1;
+                        }
+                        *data = tmpData;
+                        XMEMCPY(*data + decoded,
+                                ssl->buffers.clearOutputBuffer.buffer, ret);
+                        TraceAddedData(ret, decoded);
+                        decoded += ret;
+                        ssl->buffers.clearOutputBuffer.length = 0;
+                    }
+                }
+                else {
+                    SetError(BAD_APP_DATA_STR, error,session,FATAL_ERROR_STATE);
+                    return -1;
+                }
+                if (ssl->buffers.outputBuffer.dynamicFlag)
+                    ShrinkOutputBuffer(ssl);
+
+                sslFrame += inOutIdx;
+                sslBytes -= inOutIdx;
+            }
+            break;
+        case alert:
+            Trace(GOT_ALERT_STR);
+            sslFrame += rhSize;
+            sslBytes -= rhSize;
+            break;
+        case no_type:
+        default:
+            SetError(GOT_UNKNOWN_RECORD_STR, error, session, FATAL_ERROR_STATE);
+            return -1;
+    }
+
+    /* do we have another msg in record ? */
+    if (sslFrame < recordEnd) {
+        Trace(ANOTHER_MSG_STR);
+        goto doPart;
+    }
+
+    /* back to input stream instead of potential decrypt buffer */
+    recordEnd = inRecordEnd;
+
+    /* do we have more records ? */
+    if (recordEnd < end) {
+        Trace(ANOTHER_MSG_STR);
+        sslFrame = recordEnd;
+        sslBytes = (int)(end - recordEnd);
+        goto doMessage;
+    }
+    
+    /* clear used input */
+    ssl->buffers.inputBuffer.length = 0;
+    
+    /* could have more input ready now */
+    if (HaveMoreInput(session, &sslFrame, &sslBytes, &end, error))
+        goto doMessage;
+
+    if (ssl->buffers.inputBuffer.dynamicFlag)
+        ShrinkInputBuffer(ssl, NO_FORCED_FREE);
+    
+    return decoded;
+}
+
+
+/* See if we need to process any pending FIN captures */
+static void CheckFinCapture(IpInfo* ipInfo, TcpInfo* tcpInfo, 
+                            SnifferSession* session)
+{
+    if (session->finCaputre.cliFinSeq && session->finCaputre.cliFinSeq <= 
+                                         session->cliExpected) {
+        if (session->finCaputre.cliCounted == 0) {
+            session->flags.finCount += 1;
+            session->finCaputre.cliCounted = 1;
+            TraceClientFin(session->finCaputre.cliFinSeq, session->cliExpected);
+        }
+    }
+        
+    if (session->finCaputre.srvFinSeq && session->finCaputre.srvFinSeq <= 
+                                         session->srvExpected) {
+        if (session->finCaputre.srvCounted == 0) {
+            session->flags.finCount += 1;
+            session->finCaputre.srvCounted = 1;
+            TraceServerFin(session->finCaputre.srvFinSeq, session->srvExpected);
+        }
+    }
+                
+    if (session->flags.finCount >= 2) 
+        RemoveSession(session, ipInfo, tcpInfo, 0);
+}
+
+
+/* If session is in fatal error state free resources now 
+   return true if removed, 0 otherwise */
+static int RemoveFatalSession(IpInfo* ipInfo, TcpInfo* tcpInfo,
+                              SnifferSession* session, char* error)
+{
+    if (session && session->flags.fatalError == FATAL_ERROR_STATE) {
+        RemoveSession(session, ipInfo, tcpInfo, 0);
+        SetError(FATAL_ERROR_STR, error, NULL, 0);
+        return 1;
+    }
+    return 0;
+}
+
+
+/* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */
+/* returns Number of bytes on success, 0 for no data yet, and -1 on error */
+int ssl_DecodePacket(const byte* packet, int length, byte** data, char* error)
+{
+    TcpInfo           tcpInfo;
+    IpInfo            ipInfo;
+    const byte*       sslFrame;
+    const byte*       end = packet + length;
+    int               sslBytes;                /* ssl bytes unconsumed */
+    int               ret;
+    SnifferSession*   session = 0;
+
+    if (CheckHeaders(&ipInfo, &tcpInfo, packet, length, &sslFrame, &sslBytes,
+                     error) != 0)
+        return -1;
+    
+    ret = CheckSession(&ipInfo, &tcpInfo, sslBytes, &session, error);
+    if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
+    else if (ret == -1) return -1;
+    else if (ret ==  1) return  0;   /* done for now */
+    
+    ret = CheckSequence(&ipInfo, &tcpInfo, session, &sslBytes, &sslFrame,error);
+    if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
+    else if (ret == -1) return -1;
+    else if (ret ==  1) return  0;   /* done for now */
+    
+    ret = CheckPreRecord(&ipInfo, &tcpInfo, &sslFrame, &session, &sslBytes,
+                         &end, error);
+    if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
+    else if (ret == -1) return -1;
+    else if (ret ==  1) return  0;   /* done for now */
+
+    ret = ProcessMessage(sslFrame, session, sslBytes, data, end, error);
+    if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
+    CheckFinCapture(&ipInfo, &tcpInfo, session);
+    return ret;
+}
+
+
+/* Deallocator for the decoded data buffer. */
+/* returns 0 on success, -1 on error */
+int ssl_FreeDecodeBuffer(byte** data, char* error)
+{
+    (void)error;
+
+    if (data != NULL) {
+        free(*data);
+        *data = NULL;
+    }
+
+    return 0;
+}
+
+
+/* Enables (if traceFile)/ Disables debug tracing */
+/* returns 0 on success, -1 on error */
+int ssl_Trace(const char* traceFile, char* error)
+{
+    if (traceFile) {
+        TraceFile = fopen(traceFile, "a");
+        if (!TraceFile) {
+            SetError(BAD_TRACE_FILE_STR, error, NULL, 0);
+            return -1;
+        }
+        TraceOn = 1;
+    }
+    else 
+        TraceOn = 0;
+
+    return 0;
+}
+
+
+/* Enables/Disables Recovery of missed data if later packets allow
+ * maxMemory is number of bytes to use for reassembly buffering per session,
+ * -1 means unlimited
+ * returns 0 on success, -1 on error */
+int ssl_EnableRecovery(int onOff, int maxMemory, char* error)
+{
+    (void)error;
+
+    RecoveryEnabled = onOff;
+    if (onOff)
+        MaxRecoveryMemory = maxMemory;
+
+    return 0;
+}
+
+
+
+int ssl_GetSessionStats(unsigned int* active,     unsigned int* total,
+                        unsigned int* peak,       unsigned int* maxSessions,
+                        unsigned int* missedData, unsigned int* reassemblyMem,
+                        char* error)
+{
+    int ret;
+
+    if (missedData) {
+        LockMutex(&RecoveryMutex);
+        *missedData = MissedDataSessions;
+        UnLockMutex(&RecoveryMutex);
+    }
+
+    if (reassemblyMem) {
+        SnifferSession* session;
+        int i;
+
+        *reassemblyMem = 0;
+        LockMutex(&SessionMutex);
+        for (i = 0; i < HASH_SIZE; i++) {
+            session = SessionTable[i];
+            while (session) {
+                *reassemblyMem += session->cliReassemblyMemory;
+                *reassemblyMem += session->srvReassemblyMemory;
+                session = session->next;
+            }
+        }
+        UnLockMutex(&SessionMutex);
+    }
+
+    ret = wolfSSL_get_session_stats(active, total, peak, maxSessions);
+
+    if (ret == SSL_SUCCESS)
+        return 0;
+    else {
+        SetError(BAD_SESSION_STATS, error, NULL, 0);
+        return -1;
+    }
+}
+
+
+
+#endif /* WOLFSSL_SNIFFER */
+#endif /* WOLFCRYPT_ONLY */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/src/ssl.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/src/ssl.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/src/ssl.c	(revision 164)
@@ -0,0 +1,17109 @@
+/* ssl.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLFCRYPT_ONLY
+
+#ifdef HAVE_ERRNO_H
+    #include <errno.h>
+#endif
+
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+#include <wolfssl/wolfcrypt/coding.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+
+#ifndef WOLFSSL_ALLOW_NO_SUITES
+    #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA) \
+                  && !defined(WOLFSSL_STATIC_DH) && !defined(WOLFSSL_STATIC_PSK)
+        #error "No cipher suites defined because DH disabled, ECC disabled, and no static suites defined. Please see top of README"
+    #endif
+#endif
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
+                              defined(WOLFSSL_KEY_GEN)
+    #include <wolfssl/openssl/evp.h>
+    /* openssl headers end, wolfssl internal headers next */
+    #include <wolfssl/wolfcrypt/wc_encrypt.h>
+#endif
+
+#ifdef OPENSSL_EXTRA
+    /* openssl headers begin */
+    #include <wolfssl/openssl/hmac.h>
+    #include <wolfssl/openssl/crypto.h>
+    #include <wolfssl/openssl/des.h>
+    #include <wolfssl/openssl/bn.h>
+    #include <wolfssl/openssl/dh.h>
+    #include <wolfssl/openssl/rsa.h>
+    #include <wolfssl/openssl/pem.h>
+    #include <wolfssl/openssl/ec.h>
+    #include <wolfssl/openssl/ec25519.h>
+    #include <wolfssl/openssl/ed25519.h>
+    #include <wolfssl/openssl/ecdsa.h>
+    #include <wolfssl/openssl/ecdh.h>
+    /* openssl headers end, wolfssl internal headers next */
+    #include <wolfssl/wolfcrypt/hmac.h>
+    #include <wolfssl/wolfcrypt/random.h>
+    #include <wolfssl/wolfcrypt/des3.h>
+    #include <wolfssl/wolfcrypt/md4.h>
+    #include <wolfssl/wolfcrypt/md5.h>
+    #include <wolfssl/wolfcrypt/arc4.h>
+    #include <wolfssl/wolfcrypt/idea.h>
+    #include <wolfssl/wolfcrypt/curve25519.h>
+    #include <wolfssl/wolfcrypt/ed25519.h>
+    #ifdef HAVE_STUNNEL
+        #include <wolfssl/openssl/ocsp.h>
+    #endif /* WITH_STUNNEL */
+    #ifdef WOLFSSL_SHA512
+        #include <wolfssl/wolfcrypt/sha512.h>
+    #endif
+#endif
+
+#if defined(WOLFSSL_LWIP)
+    #include <lwip/sockets.h>
+#endif
+
+#ifndef NO_FILESYSTEM
+    #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR) \
+            && !defined(EBSNET)
+        //#include <dirent.h>
+        //#include <sys/stat.h>
+    #endif
+    #ifdef EBSNET
+        #include "vfapi.h"
+        #include "vfile.h"
+    #endif
+#endif /* NO_FILESYSTEM */
+
+#ifndef TRUE
+    #define TRUE  1
+#endif
+#ifndef FALSE
+    #define FALSE 0
+#endif
+
+#ifdef min
+#define WOLFSSL_HAVE_MIN
+#endif
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+
+#endif /* WOLFSSSL_HAVE_MIN */
+
+#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_HAVE_MAX)
+#define WOLFSSL_HAVE_MAX
+
+    static INLINE word32 max(word32 a, word32 b)
+    {
+        return a > b ? a : b;
+    }
+
+#endif /* WOLFSSL_DTLS && !WOLFSSL_HAVE_MAX */
+
+
+#ifndef WOLFSSL_LEANPSK
+char* mystrnstr(const char* s1, const char* s2, unsigned int n)
+{
+    unsigned int s2_len = (unsigned int)XSTRLEN(s2);
+
+    if (s2_len == 0)
+        return (char*)s1;
+
+    while (n >= s2_len && s1[0]) {
+        if (s1[0] == s2[0])
+            if (XMEMCMP(s1, s2, s2_len) == 0)
+                return (char*)s1;
+        s1++;
+        n--;
+    }
+
+    return NULL;
+}
+#endif
+
+
+/* prevent multiple mutex initializations */
+static volatile int initRefCount = 0;
+static wolfSSL_Mutex count_mutex;   /* init ref count mutex */
+
+
+WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
+{
+    WOLFSSL_CTX* ctx = NULL;
+
+    WOLFSSL_ENTER("WOLFSSL_CTX_new");
+
+    if (initRefCount == 0)
+        wolfSSL_Init(); /* user no longer forced to call Init themselves */
+
+    if (method == NULL)
+        return ctx;
+
+    ctx = (WOLFSSL_CTX*) XMALLOC(sizeof(WOLFSSL_CTX), 0, DYNAMIC_TYPE_CTX);
+    if (ctx) {
+        if (InitSSL_Ctx(ctx, method) < 0) {
+            WOLFSSL_MSG("Init CTX failed");
+            wolfSSL_CTX_free(ctx);
+            ctx = NULL;
+        }
+    }
+    else {
+        WOLFSSL_MSG("Alloc CTX failed, method freed");
+        XFREE(method, NULL, DYNAMIC_TYPE_METHOD);
+    }
+
+    WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
+    return ctx;
+}
+
+
+void wolfSSL_CTX_free(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_ENTER("SSL_CTX_free");
+    if (ctx)
+        FreeSSL_Ctx(ctx);
+    WOLFSSL_LEAVE("SSL_CTX_free", 0);
+}
+
+
+WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL* ssl = NULL;
+    int ret = 0;
+
+    (void)ret;
+    WOLFSSL_ENTER("SSL_new");
+
+    if (ctx == NULL)
+        return ssl;
+
+    ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap,DYNAMIC_TYPE_SSL);
+    if (ssl)
+        if ( (ret = InitSSL(ssl, ctx)) < 0) {
+            FreeSSL(ssl);
+            ssl = 0;
+        }
+
+    WOLFSSL_LEAVE("SSL_new", ret);
+    return ssl;
+}
+
+
+void wolfSSL_free(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_free");
+    if (ssl)
+        FreeSSL(ssl);
+    WOLFSSL_LEAVE("SSL_free", 0);
+}
+
+#ifdef HAVE_POLY1305
+/* set if to use old poly 1 for yes 0 to use new poly */
+int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
+{
+    WOLFSSL_ENTER("SSL_use_old_poly");
+    ssl->options.oldPoly = value;
+    WOLFSSL_LEAVE("SSL_use_old_poly", 0);
+    return 0;
+}
+#endif
+
+int wolfSSL_set_fd(WOLFSSL* ssl, int fd)
+{
+    WOLFSSL_ENTER("SSL_set_fd");
+    ssl->rfd = fd;      /* not used directly to allow IO callbacks */
+    ssl->wfd = fd;
+
+    ssl->IOCB_ReadCtx  = &ssl->rfd;
+    ssl->IOCB_WriteCtx = &ssl->wfd;
+
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
+            ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
+            ssl->buffers.dtlsCtx.fd = fd;
+        }
+    #endif
+
+    WOLFSSL_LEAVE("SSL_set_fd", SSL_SUCCESS);
+    return SSL_SUCCESS;
+}
+
+
+/**
+  * Get the name of cipher at priotity level passed in.
+  */
+char* wolfSSL_get_cipher_list(int priority)
+{
+    const char* const* ciphers = GetCipherNames();
+
+    if (priority >= GetCipherNamesSize() || priority < 0) {
+        return 0;
+    }
+
+    return (char*)ciphers[priority];
+}
+
+
+int wolfSSL_get_ciphers(char* buf, int len)
+{
+    const char* const* ciphers = GetCipherNames();
+    int  totalInc = 0;
+    int  step     = 0;
+    char delim    = ':';
+    int  size     = GetCipherNamesSize();
+    int  i;
+
+    if (buf == NULL || len <= 0)
+        return BAD_FUNC_ARG;
+
+    /* Add each member to the buffer delimitted by a : */
+    for (i = 0; i < size; i++) {
+        step = (int)(XSTRLEN(ciphers[i]) + 1);  /* delimiter */
+        totalInc += step;
+
+        /* Check to make sure buf is large enough and will not overflow */
+        if (totalInc < len) {
+            XSTRNCPY(buf, ciphers[i], XSTRLEN(ciphers[i]));
+            buf += XSTRLEN(ciphers[i]);
+
+            if (i < size - 1)
+                *buf++ = delim;
+            else
+                *buf++ = '\0';
+        }
+        else
+            return BUFFER_E;
+    }
+    return SSL_SUCCESS;
+}
+
+
+int wolfSSL_get_fd(const WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_get_fd");
+    WOLFSSL_LEAVE("SSL_get_fd", ssl->rfd);
+    return ssl->rfd;
+}
+
+
+int wolfSSL_get_using_nonblock(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_using_nonblock");
+    WOLFSSL_LEAVE("wolfSSL_get_using_nonblock", ssl->options.usingNonblock);
+    return ssl->options.usingNonblock;
+}
+
+
+int wolfSSL_dtls(WOLFSSL* ssl)
+{
+    return ssl->options.dtls;
+}
+
+
+#ifndef WOLFSSL_LEANPSK
+void wolfSSL_set_using_nonblock(WOLFSSL* ssl, int nonblock)
+{
+    WOLFSSL_ENTER("wolfSSL_set_using_nonblock");
+    ssl->options.usingNonblock = (nonblock != 0);
+}
+
+
+int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
+{
+#ifdef WOLFSSL_DTLS
+    void* sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
+    if (sa != NULL) {
+        if (ssl->buffers.dtlsCtx.peer.sa != NULL)
+            XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
+        XMEMCPY(sa, peer, peerSz);
+        ssl->buffers.dtlsCtx.peer.sa = sa;
+        ssl->buffers.dtlsCtx.peer.sz = peerSz;
+        return SSL_SUCCESS;
+    }
+    return SSL_FAILURE;
+#else
+    (void)ssl;
+    (void)peer;
+    (void)peerSz;
+    return SSL_NOT_IMPLEMENTED;
+#endif
+}
+
+int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
+{
+#ifdef WOLFSSL_DTLS
+    if (peer != NULL && peerSz != NULL
+            && *peerSz >= ssl->buffers.dtlsCtx.peer.sz) {
+        *peerSz = ssl->buffers.dtlsCtx.peer.sz;
+        XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
+        return SSL_SUCCESS;
+    }
+    return SSL_FAILURE;
+#else
+    (void)ssl;
+    (void)peer;
+    (void)peerSz;
+    return SSL_NOT_IMPLEMENTED;
+#endif
+}
+#endif /* WOLFSSL_LEANPSK */
+
+
+/* return underlying connect or accept, SSL_SUCCESS on ok */
+int wolfSSL_negotiate(WOLFSSL* ssl)
+{
+    int err = SSL_FATAL_ERROR;
+
+    WOLFSSL_ENTER("wolfSSL_negotiate");
+#ifndef NO_WOLFSSL_SERVER
+    if (ssl->options.side == WOLFSSL_SERVER_END)
+        err = wolfSSL_accept(ssl);
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+    if (ssl->options.side == WOLFSSL_CLIENT_END)
+        err = wolfSSL_connect(ssl);
+#endif
+
+    WOLFSSL_LEAVE("wolfSSL_negotiate", err);
+
+    return err;
+}
+
+
+#ifndef WOLFSSL_LEANPSK
+/* object size based on build */
+int wolfSSL_GetObjectSize(void)
+{
+#ifdef SHOW_SIZES
+    printf("sizeof suites           = %lu\n", sizeof(Suites));
+    printf("sizeof ciphers(2)       = %lu\n", sizeof(Ciphers));
+#ifndef NO_RC4
+    printf("    sizeof arc4         = %lu\n", sizeof(Arc4));
+#endif
+    printf("    sizeof aes          = %lu\n", sizeof(Aes));
+#ifndef NO_DES3
+    printf("    sizeof des3         = %lu\n", sizeof(Des3));
+#endif
+#ifndef NO_RABBIT
+    printf("    sizeof rabbit       = %lu\n", sizeof(Rabbit));
+#endif
+#ifdef HAVE_CHACHA
+    printf("    sizeof chacha       = %lu\n", sizeof(Chacha));
+#endif
+    printf("sizeof cipher specs     = %lu\n", sizeof(CipherSpecs));
+    printf("sizeof keys             = %lu\n", sizeof(Keys));
+    printf("sizeof Hashes(2)        = %lu\n", sizeof(Hashes));
+#ifndef NO_MD5
+    printf("    sizeof MD5          = %lu\n", sizeof(Md5));
+#endif
+#ifndef NO_SHA
+    printf("    sizeof SHA          = %lu\n", sizeof(Sha));
+#endif
+#ifndef NO_SHA256
+    printf("    sizeof SHA256       = %lu\n", sizeof(Sha256));
+#endif
+#ifdef WOLFSSL_SHA384
+    printf("    sizeof SHA384       = %lu\n", sizeof(Sha384));
+#endif
+#ifdef WOLFSSL_SHA384
+    printf("    sizeof SHA512       = %lu\n", sizeof(Sha512));
+#endif
+    printf("sizeof Buffers          = %lu\n", sizeof(Buffers));
+    printf("sizeof Options          = %lu\n", sizeof(Options));
+    printf("sizeof Arrays           = %lu\n", sizeof(Arrays));
+#ifndef NO_RSA
+    printf("sizeof RsaKey           = %lu\n", sizeof(RsaKey));
+#endif
+#ifdef HAVE_ECC
+    printf("sizeof ecc_key          = %lu\n", sizeof(ecc_key));
+#endif
+    printf("sizeof WOLFSSL_CIPHER    = %lu\n", sizeof(WOLFSSL_CIPHER));
+    printf("sizeof WOLFSSL_SESSION   = %lu\n", sizeof(WOLFSSL_SESSION));
+    printf("sizeof WOLFSSL           = %lu\n", sizeof(WOLFSSL));
+    printf("sizeof WOLFSSL_CTX       = %lu\n", sizeof(WOLFSSL_CTX));
+#endif
+
+    return sizeof(WOLFSSL);
+}
+#endif
+
+
+#ifndef NO_DH
+/* server Diffie-Hellman parameters, SSL_SUCCESS on ok */
+int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
+                    const unsigned char* g, int gSz)
+{
+    byte havePSK = 0;
+    byte haveRSA = 1;
+
+    WOLFSSL_ENTER("wolfSSL_SetTmpDH");
+    if (ssl == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
+
+    if (pSz < ssl->options.minDhKeySz)
+        return DH_KEY_SIZE_E;
+
+    if (ssl->options.side != WOLFSSL_SERVER_END)
+        return SIDE_ERROR;
+
+    if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH)
+        XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
+    if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH)
+        XFREE(ssl->buffers.serverDH_G.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
+
+    ssl->buffers.weOwnDH = 1;  /* SSL owns now */
+    ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->ctx->heap,
+                                                    DYNAMIC_TYPE_DH);
+    if (ssl->buffers.serverDH_P.buffer == NULL)
+        return MEMORY_E;
+
+    ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->ctx->heap,
+                                                    DYNAMIC_TYPE_DH);
+    if (ssl->buffers.serverDH_G.buffer == NULL) {
+        XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
+        return MEMORY_E;
+    }
+
+    ssl->buffers.serverDH_P.length = pSz;
+    ssl->buffers.serverDH_G.length = gSz;
+
+    XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
+    XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
+
+    ssl->options.haveDH = 1;
+    #ifndef NO_PSK
+        havePSK = ssl->options.havePSK;
+    #endif
+    #ifdef NO_RSA
+        haveRSA = 0;
+    #endif
+    InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH,
+               ssl->options.haveNTRU, ssl->options.haveECDSAsig,
+               ssl->options.haveStaticECC, ssl->options.side);
+
+    WOLFSSL_LEAVE("wolfSSL_SetTmpDH", 0);
+    return SSL_SUCCESS;
+}
+
+/* server ctx Diffie-Hellman parameters, SSL_SUCCESS on ok */
+int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
+                         const unsigned char* g, int gSz)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_SetTmpDH");
+    if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
+
+    if (pSz < ctx->minDhKeySz)
+        return DH_KEY_SIZE_E;
+
+    XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
+    XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
+
+    ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap,DYNAMIC_TYPE_DH);
+    if (ctx->serverDH_P.buffer == NULL)
+       return MEMORY_E;
+
+    ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap,DYNAMIC_TYPE_DH);
+    if (ctx->serverDH_G.buffer == NULL) {
+        XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
+        return MEMORY_E;
+    }
+
+    ctx->serverDH_P.length = pSz;
+    ctx->serverDH_G.length = gSz;
+
+    XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
+    XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
+
+    ctx->haveDH = 1;
+
+    WOLFSSL_LEAVE("wolfSSL_CTX_SetTmpDH", 0);
+    return SSL_SUCCESS;
+}
+
+
+int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz)
+{
+    if (ctx == NULL || keySz > 16000 || keySz % 8 != 0)
+        return BAD_FUNC_ARG;
+
+    ctx->minDhKeySz = keySz / 8;
+    return SSL_SUCCESS;
+}
+
+
+int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz)
+{
+    if (ssl == NULL || keySz > 16000 || keySz % 8 != 0)
+        return BAD_FUNC_ARG;
+
+    ssl->options.minDhKeySz = keySz / 8;
+    return SSL_SUCCESS;
+}
+
+
+int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    return (ssl->options.dhKeySz * 8);
+}
+
+#endif /* !NO_DH */
+
+
+int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
+{
+    int ret;
+
+    WOLFSSL_ENTER("SSL_write()");
+
+    if (ssl == NULL || data == NULL || sz < 0)
+        return BAD_FUNC_ARG;
+
+#ifdef HAVE_ERRNO_H
+    errno = 0;
+#endif
+
+    ret = SendData(ssl, data, sz);
+
+    WOLFSSL_LEAVE("SSL_write()", ret);
+
+    if (ret < 0)
+        return SSL_FATAL_ERROR;
+    else
+        return ret;
+}
+
+
+static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
+{
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_read_internal()");
+
+    if (ssl == NULL || data == NULL || sz < 0)
+        return BAD_FUNC_ARG;
+
+#ifdef HAVE_ERRNO_H
+        errno = 0;
+#endif
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls)
+        ssl->dtls_expected_rx = max(sz + 100, MAX_MTU);
+#endif
+
+#ifdef HAVE_MAX_FRAGMENT
+    ret = ReceiveData(ssl, (byte*)data,
+                      min(sz, min(ssl->max_fragment, OUTPUT_RECORD_SIZE)),peek);
+#else
+    ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE), peek);
+#endif
+
+    WOLFSSL_LEAVE("wolfSSL_read_internal()", ret);
+
+    if (ret < 0)
+        return SSL_FATAL_ERROR;
+    else
+        return ret;
+}
+
+
+int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz)
+{
+    WOLFSSL_ENTER("wolfSSL_peek()");
+
+    return wolfSSL_read_internal(ssl, data, sz, TRUE);
+}
+
+
+int wolfSSL_read(WOLFSSL* ssl, void* data, int sz)
+{
+    WOLFSSL_ENTER("wolfSSL_read()");
+
+    return wolfSSL_read_internal(ssl, data, sz, FALSE);
+}
+
+
+#ifdef HAVE_CAVIUM
+
+/* let's use cavium, SSL_SUCCESS on ok */
+int wolfSSL_UseCavium(WOLFSSL* ssl, int devId)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    ssl->devId = devId;
+
+    return SSL_SUCCESS;
+}
+
+
+/* let's use cavium, SSL_SUCCESS on ok */
+int wolfSSL_CTX_UseCavium(WOLFSSL_CTX* ctx, int devId)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    ctx->devId = devId;
+
+    return SSL_SUCCESS;
+}
+
+
+#endif /* HAVE_CAVIUM */
+
+#ifdef HAVE_SNI
+
+int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseSNI(&ssl->extensions, type, data, size);
+}
+
+int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type,
+                       const void* data, word16 size)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseSNI(&ctx->extensions, type, data, size);
+}
+
+#ifndef NO_WOLFSSL_SERVER
+
+void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
+{
+    if (ssl && ssl->extensions)
+        TLSX_SNI_SetOptions(ssl->extensions, type, options);
+}
+
+void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
+{
+    if (ctx && ctx->extensions)
+        TLSX_SNI_SetOptions(ctx->extensions, type, options);
+}
+
+byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
+{
+    return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
+}
+
+word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
+{
+    if (data)
+        *data = NULL;
+
+    if (ssl && ssl->extensions)
+        return TLSX_SNI_GetRequest(ssl->extensions, type, data);
+
+    return 0;
+}
+
+int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
+                              byte type, byte* sni, word32* inOutSz)
+{
+    if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
+        return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
+
+    return BAD_FUNC_ARG;
+}
+
+#endif /* NO_WOLFSSL_SERVER */
+
+#endif /* HAVE_SNI */
+
+
+#ifdef HAVE_MAX_FRAGMENT
+#ifndef NO_WOLFSSL_CLIENT
+int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseMaxFragment(&ssl->extensions, mfl);
+}
+
+int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseMaxFragment(&ctx->extensions, mfl);
+}
+#endif /* NO_WOLFSSL_CLIENT */
+#endif /* HAVE_MAX_FRAGMENT */
+
+#ifdef HAVE_TRUNCATED_HMAC
+#ifndef NO_WOLFSSL_CLIENT
+int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseTruncatedHMAC(&ssl->extensions);
+}
+
+int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseTruncatedHMAC(&ctx->extensions);
+}
+#endif /* NO_WOLFSSL_CLIENT */
+#endif /* HAVE_TRUNCATED_HMAC */
+
+/* Elliptic Curves */
+#ifdef HAVE_SUPPORTED_CURVES
+#ifndef NO_WOLFSSL_CLIENT
+
+int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (name) {
+        case WOLFSSL_ECC_SECP160R1:
+        case WOLFSSL_ECC_SECP192R1:
+        case WOLFSSL_ECC_SECP224R1:
+        case WOLFSSL_ECC_SECP256R1:
+        case WOLFSSL_ECC_SECP384R1:
+        case WOLFSSL_ECC_SECP521R1:
+            break;
+
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    return TLSX_UseSupportedCurve(&ssl->extensions, name);
+}
+
+int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (name) {
+        case WOLFSSL_ECC_SECP160R1:
+        case WOLFSSL_ECC_SECP192R1:
+        case WOLFSSL_ECC_SECP224R1:
+        case WOLFSSL_ECC_SECP256R1:
+        case WOLFSSL_ECC_SECP384R1:
+        case WOLFSSL_ECC_SECP521R1:
+            break;
+
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    return TLSX_UseSupportedCurve(&ctx->extensions, name);
+}
+
+#endif /* NO_WOLFSSL_CLIENT */
+#endif /* HAVE_SUPPORTED_CURVES */
+
+/* QSH quantum safe handshake */
+#ifdef HAVE_QSH
+/* returns 1 if QSH has been used 0 otherwise */
+int wolfSSL_isQSH(WOLFSSL* ssl)
+{
+    /* if no ssl struct than QSH was not used */
+    if (ssl == NULL)
+        return 0;
+
+    return ssl->isQSH;
+}
+
+
+int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, word16 name)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (name) {
+    #ifdef HAVE_NTRU
+        case WOLFSSL_NTRU_EESS439:
+        case WOLFSSL_NTRU_EESS593:
+        case WOLFSSL_NTRU_EESS743:
+            break;
+    #endif
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    ssl->user_set_QSHSchemes = 1;
+
+    return TLSX_UseQSHScheme(&ssl->extensions, name, NULL, 0);
+}
+
+#ifndef NO_WOLFSSL_CLIENT
+    /* user control over sending client public key in hello
+       when flag = 1 will send keys if flag is 0 or function is not called
+       then will not send keys in the hello extension
+       return 0 on success
+     */
+    int wolfSSL_UseClientQSHKeys(WOLFSSL* ssl, unsigned char flag)
+    {
+        if (ssl == NULL)
+            return BAD_FUNC_ARG;
+
+        ssl->sendQSHKeys = flag;
+
+        return 0;
+    }
+#endif /* NO_WOLFSSL_CLIENT */
+#endif /* HAVE_QSH */
+
+
+/* Application-Layer Procotol Name */
+#ifdef HAVE_ALPN
+
+int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
+                    word32 protocol_name_listSz, byte options)
+{
+    char    *list, *ptr, *token[10];
+    word16  len;
+    int     idx = 0;
+    int     ret = SSL_FAILURE;
+
+    WOLFSSL_ENTER("wolfSSL_UseALPN");
+
+    if (ssl == NULL || protocol_name_list == NULL)
+        return BAD_FUNC_ARG;
+
+    if (protocol_name_listSz > (WOLFSSL_MAX_ALPN_NUMBER *
+                                WOLFSSL_MAX_ALPN_PROTO_NAME_LEN +
+                                WOLFSSL_MAX_ALPN_NUMBER)) {
+        WOLFSSL_MSG("Invalid arguments, protocol name list too long");
+        return BAD_FUNC_ARG;
+    }
+
+    if (!(options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) &&
+        !(options & WOLFSSL_ALPN_FAILED_ON_MISMATCH)) {
+            WOLFSSL_MSG("Invalid arguments, options not supported");
+            return BAD_FUNC_ARG;
+        }
+
+
+    list = (char *)XMALLOC(protocol_name_listSz+1, NULL,
+                           DYNAMIC_TYPE_TMP_BUFFER);
+    if (list == NULL) {
+        WOLFSSL_MSG("Memory failure");
+        return MEMORY_ERROR;
+    }
+
+    XMEMSET(list, 0, protocol_name_listSz+1);
+    XSTRNCPY(list, protocol_name_list, protocol_name_listSz);
+
+    /* read all protocol name from the list */
+    token[idx] = XSTRTOK(list, ",", &ptr);
+    while (token[idx] != NULL)
+        token[++idx] = XSTRTOK(NULL, ",", &ptr);
+
+    /* add protocol name list in the TLS extension in reverse order */
+    while ((idx--) > 0) {
+        len = (word16)XSTRLEN(token[idx]);
+
+        ret = TLSX_UseALPN(&ssl->extensions, token[idx], len, options);
+        if (ret != SSL_SUCCESS) {
+            WOLFSSL_MSG("TLSX_UseALPN failure");
+            break;
+        }
+    }
+
+    XFREE(list, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    return ret;
+}
+
+int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, word16 *size)
+{
+    return TLSX_ALPN_GetRequest(ssl ? ssl->extensions : NULL,
+                               (void **)protocol_name, size);
+}
+
+int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz)
+{
+    if (list == NULL || listSz == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ssl->alpn_client_list == NULL)
+        return BUFFER_ERROR;
+
+    *listSz = (word16)XSTRLEN(ssl->alpn_client_list);
+    if (*listSz == 0)
+        return BUFFER_ERROR;
+
+    *list = (char *)XMALLOC((*listSz)+1, NULL, DYNAMIC_TYPE_OUT_BUFFER);
+    if (*list == NULL)
+        return MEMORY_ERROR;
+
+    XSTRNCPY(*list, ssl->alpn_client_list, (*listSz)+1);
+    (*list)[*listSz] = 0;
+
+    return SSL_SUCCESS;
+}
+
+#endif /* HAVE_ALPN */
+
+/* Secure Renegotiation */
+#ifdef HAVE_SECURE_RENEGOTIATION
+
+/* user is forcing ability to use secure renegotiation, we discourage it */
+int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
+{
+    int ret = BAD_FUNC_ARG;
+
+    if (ssl)
+        ret = TLSX_UseSecureRenegotiation(&ssl->extensions);
+
+    if (ret == SSL_SUCCESS) {
+        TLSX* extension = TLSX_Find(ssl->extensions, SECURE_RENEGOTIATION);
+
+        if (extension)
+            ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
+    }
+
+    return ret;
+}
+
+
+/* do a secure renegotiation handshake, user forced, we discourage */
+int wolfSSL_Rehandshake(WOLFSSL* ssl)
+{
+    int ret;
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ssl->secure_renegotiation == NULL) {
+        WOLFSSL_MSG("Secure Renegotiation not forced on by user");
+        return SECURE_RENEGOTIATION_E;
+    }
+
+    if (ssl->secure_renegotiation->enabled == 0) {
+        WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
+        return SECURE_RENEGOTIATION_E;
+    }
+
+    if (ssl->options.handShakeState != HANDSHAKE_DONE) {
+        WOLFSSL_MSG("Can't renegotiate until previous handshake complete");
+        return SECURE_RENEGOTIATION_E;
+    }
+
+#ifndef NO_FORCE_SCR_SAME_SUITE
+    /* force same suite */
+    if (ssl->suites) {
+        ssl->suites->suiteSz = SUITE_LEN;
+        ssl->suites->suites[0] = ssl->options.cipherSuite0;
+        ssl->suites->suites[1] = ssl->options.cipherSuite;
+    }
+#endif
+
+    /* reset handshake states */
+    ssl->options.serverState = NULL_STATE;
+    ssl->options.clientState = NULL_STATE;
+    ssl->options.connectState  = CONNECT_BEGIN;
+    ssl->options.acceptState   = ACCEPT_BEGIN;
+    ssl->options.handShakeState = NULL_STATE;
+    ssl->options.processReply  = 0;  /* TODO, move states in internal.h */
+
+    XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
+
+    ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
+
+#ifndef NO_OLD_TLS
+#ifndef NO_MD5
+    wc_InitMd5(&ssl->hsHashes->hashMd5);
+#endif
+#ifndef NO_SHA
+    ret = wc_InitSha(&ssl->hsHashes->hashSha);
+    if (ret !=0)
+        return ret;
+#endif
+#endif /* NO_OLD_TLS */
+#ifndef NO_SHA256
+    ret = wc_InitSha256(&ssl->hsHashes->hashSha256);
+    if (ret !=0)
+        return ret;
+#endif
+#ifdef WOLFSSL_SHA384
+    ret = wc_InitSha384(&ssl->hsHashes->hashSha384);
+    if (ret !=0)
+        return ret;
+#endif
+#ifdef WOLFSSL_SHA512
+    ret = wc_InitSha512(&ssl->hsHashes->hashSha512);
+    if (ret !=0)
+        return ret;
+#endif
+
+    ret = wolfSSL_negotiate(ssl);
+    return ret;
+}
+
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+/* Session Ticket */
+#if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SESSION_TICKET)
+/* SSL_SUCCESS on ok */
+int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    ctx->ticketEncCb = cb;
+
+    return SSL_SUCCESS;
+}
+
+/* set hint interval, SSL_SUCCESS on ok */
+int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    ctx->ticketHint = hint;
+
+    return SSL_SUCCESS;
+}
+
+/* set user context, SSL_SUCCESS on ok */
+int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    ctx->ticketEncCtx = userCtx;
+
+    return SSL_SUCCESS;
+}
+
+#endif /* !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET) */
+
+/* Session Ticket */
+#if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET)
+int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseSessionTicket(&ssl->extensions, NULL);
+}
+
+int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    return TLSX_UseSessionTicket(&ctx->extensions, NULL);
+}
+
+WOLFSSL_API int wolfSSL_get_SessionTicket(WOLFSSL* ssl,
+                                          byte* buf, word32* bufSz)
+{
+    if (ssl == NULL || buf == NULL || bufSz == NULL || *bufSz == 0)
+        return BAD_FUNC_ARG;
+
+    if (ssl->session.ticketLen <= *bufSz) {
+        XMEMCPY(buf, ssl->session.ticket, ssl->session.ticketLen);
+        *bufSz = ssl->session.ticketLen;
+    }
+    else
+        *bufSz = 0;
+
+    return SSL_SUCCESS;
+}
+
+WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, byte* buf, word32 bufSz)
+{
+    if (ssl == NULL || (buf == NULL && bufSz > 0))
+        return BAD_FUNC_ARG;
+
+    if (bufSz > 0)
+        XMEMCPY(ssl->session.ticket, buf, bufSz);
+    ssl->session.ticketLen = (word16)bufSz;
+
+    return SSL_SUCCESS;
+}
+
+
+WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
+                                            CallbackSessionTicket cb, void* ctx)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    ssl->session_ticket_cb = cb;
+    ssl->session_ticket_ctx = ctx;
+
+    return SSL_SUCCESS;
+}
+#endif
+
+#ifndef WOLFSSL_LEANPSK
+
+int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags)
+{
+    int ret;
+    int oldFlags;
+
+    WOLFSSL_ENTER("wolfSSL_send()");
+
+    if (ssl == NULL || data == NULL || sz < 0)
+        return BAD_FUNC_ARG;
+
+    oldFlags = ssl->wflags;
+
+    ssl->wflags = flags;
+    ret = wolfSSL_write(ssl, data, sz);
+    ssl->wflags = oldFlags;
+
+    WOLFSSL_LEAVE("wolfSSL_send()", ret);
+
+    return ret;
+}
+
+
+int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags)
+{
+    int ret;
+    int oldFlags;
+
+    WOLFSSL_ENTER("wolfSSL_recv()");
+
+    if (ssl == NULL || data == NULL || sz < 0)
+        return BAD_FUNC_ARG;
+
+    oldFlags = ssl->rflags;
+
+    ssl->rflags = flags;
+    ret = wolfSSL_read(ssl, data, sz);
+    ssl->rflags = oldFlags;
+
+    WOLFSSL_LEAVE("wolfSSL_recv()", ret);
+
+    return ret;
+}
+#endif
+
+
+/* SSL_SUCCESS on ok */
+int wolfSSL_shutdown(WOLFSSL* ssl)
+{
+    int  ret = SSL_FATAL_ERROR;
+    byte tmp;
+    WOLFSSL_ENTER("SSL_shutdown()");
+
+    if (ssl == NULL)
+        return SSL_FATAL_ERROR;
+
+    if (ssl->options.quietShutdown) {
+        WOLFSSL_MSG("quiet shutdown, no close notify sent");
+        return SSL_SUCCESS;
+    }
+
+    /* try to send close notify, not an error if can't */
+    if (!ssl->options.isClosed && !ssl->options.connReset &&
+                                  !ssl->options.sentNotify) {
+        ssl->error = SendAlert(ssl, alert_warning, close_notify);
+        if (ssl->error < 0) {
+            WOLFSSL_ERROR(ssl->error);
+            return SSL_FATAL_ERROR;
+        }
+        ssl->options.sentNotify = 1;  /* don't send close_notify twice */
+        if (ssl->options.closeNotify)
+            ret = SSL_SUCCESS;
+        else
+            ret = SSL_SHUTDOWN_NOT_DONE;
+
+        WOLFSSL_LEAVE("SSL_shutdown()", ret);
+        return ret;
+    }
+
+    /* call wolfSSL_shutdown again for bidirectional shudown */
+    if (ssl->options.sentNotify && !ssl->options.closeNotify) {
+        ret = wolfSSL_read(ssl, &tmp, 0);
+        if (ret < 0) {
+            WOLFSSL_ERROR(ssl->error);
+            ret = SSL_FATAL_ERROR;
+        } else if (ssl->options.closeNotify) {
+            ssl->error = SSL_ERROR_SYSCALL;   /* simulate OpenSSL behavior */
+            ret = SSL_SUCCESS;
+        }
+    }
+
+    WOLFSSL_LEAVE("SSL_shutdown()", ret);
+
+    return ret;
+}
+
+
+int wolfSSL_get_error(WOLFSSL* ssl, int ret)
+{
+    WOLFSSL_ENTER("SSL_get_error");
+
+    if (ret > 0)
+        return SSL_ERROR_NONE;
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    WOLFSSL_LEAVE("SSL_get_error", ssl->error);
+
+    /* make sure converted types are handled in SetErrorString() too */
+    if (ssl->error == WANT_READ)
+        return SSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
+    else if (ssl->error == WANT_WRITE)
+        return SSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
+    else if (ssl->error == ZERO_RETURN)
+        return SSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
+    return ssl->error;
+}
+
+
+/* retrive alert history, SSL_SUCCESS on ok */
+int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *h)
+{
+    if (ssl && h) {
+        *h = ssl->alert_history;
+    }
+    return SSL_SUCCESS;
+}
+
+
+/* return TRUE if current error is want read */
+int wolfSSL_want_read(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_want_read");
+    if (ssl->error == WANT_READ)
+        return 1;
+
+    return 0;
+}
+
+
+/* return TRUE if current error is want write */
+int wolfSSL_want_write(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_want_write");
+    if (ssl->error == WANT_WRITE)
+        return 1;
+
+    return 0;
+}
+
+
+char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
+{
+    static const char* msg = "Please supply a buffer for error string";
+
+    WOLFSSL_ENTER("ERR_error_string");
+    if (data) {
+        SetErrorString((int)errNumber, data);
+        return data;
+    }
+
+    return (char*)msg;
+}
+
+
+void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
+{
+    WOLFSSL_ENTER("wolfSSL_ERR_error_string_n");
+    if (len >= WOLFSSL_MAX_ERROR_SZ)
+        wolfSSL_ERR_error_string(e, buf);
+    else {
+        char tmp[WOLFSSL_MAX_ERROR_SZ];
+
+        WOLFSSL_MSG("Error buffer too short, truncating");
+        if (len) {
+            wolfSSL_ERR_error_string(e, tmp);
+            XMEMCPY(buf, tmp, len-1);
+            buf[len-1] = '\0';
+        }
+    }
+}
+
+
+/* don't free temporary arrays at end of handshake */
+void wolfSSL_KeepArrays(WOLFSSL* ssl)
+{
+    if (ssl)
+        ssl->options.saveArrays = 1;
+}
+
+
+/* user doesn't need temporary arrays anymore, Free */
+void wolfSSL_FreeArrays(WOLFSSL* ssl)
+{
+    if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
+        ssl->options.saveArrays = 0;
+        FreeArrays(ssl, 1);
+    }
+}
+
+
+const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify)
+{
+    if (ssl == NULL)
+        return NULL;
+
+    if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
+         (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
+        return ssl->keys.client_write_MAC_secret;
+    else
+        return ssl->keys.server_write_MAC_secret;
+}
+
+
+#ifdef ATOMIC_USER
+
+void  wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX* ctx, CallbackMacEncrypt cb)
+{
+    if (ctx)
+        ctx->MacEncryptCb = cb;
+}
+
+
+void  wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->MacEncryptCtx = ctx;
+}
+
+
+void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->MacEncryptCtx;
+
+    return NULL;
+}
+
+
+void  wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX* ctx, CallbackDecryptVerify cb)
+{
+    if (ctx)
+        ctx->DecryptVerifyCb = cb;
+}
+
+
+void  wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->DecryptVerifyCtx = ctx;
+}
+
+
+void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->DecryptVerifyCtx;
+
+    return NULL;
+}
+
+
+const byte* wolfSSL_GetClientWriteKey(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->keys.client_write_key;
+
+    return NULL;
+}
+
+
+const byte* wolfSSL_GetClientWriteIV(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->keys.client_write_IV;
+
+    return NULL;
+}
+
+
+const byte* wolfSSL_GetServerWriteKey(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->keys.server_write_key;
+
+    return NULL;
+}
+
+
+const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->keys.server_write_IV;
+
+    return NULL;
+}
+
+
+int wolfSSL_GetKeySize(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->specs.key_size;
+
+    return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_GetIVSize(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->specs.iv_size;
+
+    return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_GetBulkCipher(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->specs.bulk_cipher_algorithm;
+
+    return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_GetCipherType(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ssl->specs.cipher_type == block)
+        return WOLFSSL_BLOCK_TYPE;
+    if (ssl->specs.cipher_type == stream)
+        return WOLFSSL_STREAM_TYPE;
+    if (ssl->specs.cipher_type == aead)
+        return WOLFSSL_AEAD_TYPE;
+
+    return -1;
+}
+
+
+int wolfSSL_GetCipherBlockSize(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    return ssl->specs.block_size;
+}
+
+
+int wolfSSL_GetAeadMacSize(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    return ssl->specs.aead_mac_size;
+}
+
+
+int wolfSSL_IsTLSv1_1(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ssl->options.tls1_1)
+        return 1;
+
+    return 0;
+}
+
+
+int wolfSSL_GetSide(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->options.side;
+
+    return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_GetHmacSize(WOLFSSL* ssl)
+{
+    /* AEAD ciphers don't have HMAC keys */
+    if (ssl)
+        return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
+
+    return BAD_FUNC_ARG;
+}
+
+#endif /* ATOMIC_USER */
+
+#ifndef NO_CERTS
+
+WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void)
+{
+    WOLFSSL_CERT_MANAGER* cm = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerNew");
+
+    cm = (WOLFSSL_CERT_MANAGER*) XMALLOC(sizeof(WOLFSSL_CERT_MANAGER), 0,
+                                         DYNAMIC_TYPE_CERT_MANAGER);
+    if (cm) {
+        XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER));
+
+        if (InitMutex(&cm->caLock) != 0) {
+            WOLFSSL_MSG("Bad mutex init");
+            wolfSSL_CertManagerFree(cm);
+            return NULL;
+        }
+    }
+
+    return cm;
+}
+
+
+void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerFree");
+
+    if (cm) {
+        #ifdef HAVE_CRL
+            if (cm->crl)
+                FreeCRL(cm->crl, 1);
+        #endif
+        #ifdef HAVE_OCSP
+            if (cm->ocsp)
+                FreeOCSP(cm->ocsp, 1);
+        #endif
+        FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
+        FreeMutex(&cm->caLock);
+        XFREE(cm, NULL, DYNAMIC_TYPE_CERT_MANAGER);
+    }
+
+}
+
+
+/* Unload the CA signer list */
+int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerUnloadCAs");
+
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    if (LockMutex(&cm->caLock) != 0)
+        return BAD_MUTEX_E;
+
+    FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
+
+    UnLockMutex(&cm->caLock);
+
+
+    return SSL_SUCCESS;
+}
+
+
+/* Return bytes written to buff or < 0 for error */
+int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz,
+                        unsigned char* buff, int buffSz, int type)
+{
+    int            eccKey = 0;
+    int            ret;
+    buffer         der;
+#ifdef WOLFSSL_SMALL_STACK
+    EncryptedInfo* info = NULL;
+#else
+    EncryptedInfo  info[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_CertPemToDer");
+
+    if (pem == NULL || buff == NULL || buffSz <= 0) {
+        WOLFSSL_MSG("Bad pem der args");
+        return BAD_FUNC_ARG;
+    }
+
+    if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {
+        WOLFSSL_MSG("Bad cert type");
+        return BAD_FUNC_ARG;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
+                                   DYNAMIC_TYPE_TMP_BUFFER);
+    if (info == NULL)
+        return MEMORY_E;
+#endif
+
+    info->set      = 0;
+    info->ctx      = NULL;
+    info->consumed = 0;
+    der.buffer     = NULL;
+
+    ret = PemToDer(pem, pemSz, type, &der, NULL, info, &eccKey);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (ret < 0) {
+        WOLFSSL_MSG("Bad Pem To Der");
+    }
+    else {
+        if (der.length <= (word32)buffSz) {
+            XMEMCPY(buff, der.buffer, der.length);
+            ret = der.length;
+        }
+        else {
+            WOLFSSL_MSG("Bad der length");
+            ret = BAD_FUNC_ARG;
+        }
+    }
+
+    XFREE(der.buffer, NULL, DYNAMIC_TYPE_KEY);
+
+    return ret;
+}
+
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+
+static const char *EVP_AES_128_CBC = "AES-128-CBC";
+static const char *EVP_AES_192_CBC = "AES-192-CBC";
+static const char *EVP_AES_256_CBC = "AES-256-CBC";
+#if defined(OPENSSL_EXTRA)
+    static const char *EVP_AES_128_CTR = "AES-128-CTR";
+    static const char *EVP_AES_192_CTR = "AES-192-CTR";
+    static const char *EVP_AES_256_CTR = "AES-256-CTR";
+#endif
+static const int  EVP_AES_SIZE = 11;
+
+static const char *EVP_DES_CBC = "DES-CBC";
+static const int  EVP_DES_SIZE = 7;
+
+static const char *EVP_DES_EDE3_CBC = "DES-EDE3-CBC";
+static const int  EVP_DES_EDE3_SIZE = 12;
+
+#ifdef HAVE_IDEA
+static const char *EVP_IDEA_CBC = "IDEA-CBC";
+static const int  EVP_IDEA_SIZE = 8;
+#endif
+
+/* our KeyPemToDer password callback, password in userData */
+static INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
+{
+    (void)rw;
+
+    if (userdata == NULL)
+        return 0;
+
+    XSTRNCPY(passwd, (char*)userdata, sz);
+    return min((word32)sz, (word32)XSTRLEN((char*)userdata));
+}
+
+#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
+
+
+/* Return bytes written to buff or < 0 for error */
+int wolfSSL_KeyPemToDer(const unsigned char* pem, int pemSz,
+                        unsigned char* buff, int buffSz, const char* pass)
+{
+    int            eccKey = 0;
+    int            ret;
+    buffer         der;
+#ifdef WOLFSSL_SMALL_STACK
+    EncryptedInfo* info = NULL;
+#else
+    EncryptedInfo  info[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_KeyPemToDer");
+
+    if (pem == NULL || buff == NULL || buffSz <= 0) {
+        WOLFSSL_MSG("Bad pem der args");
+        return BAD_FUNC_ARG;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
+                                   DYNAMIC_TYPE_TMP_BUFFER);
+    if (info == NULL)
+        return MEMORY_E;
+#endif
+
+    info->set      = 0;
+    info->ctx      = NULL;
+    info->consumed = 0;
+    der.buffer     = NULL;
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+    if (pass) {
+        info->ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
+        if (info->ctx == NULL) {
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+            return MEMORY_E;
+        }
+
+        wolfSSL_CTX_set_default_passwd_cb(info->ctx, OurPasswordCb);
+        wolfSSL_CTX_set_default_passwd_cb_userdata(info->ctx, (void*)pass);
+    }
+#else
+    (void)pass;
+#endif
+
+    ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &eccKey);
+
+    if (info->ctx)
+        wolfSSL_CTX_free(info->ctx);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (ret < 0) {
+        WOLFSSL_MSG("Bad Pem To Der");
+    }
+    else {
+        if (der.length <= (word32)buffSz) {
+            XMEMCPY(buff, der.buffer, der.length);
+            ret = der.length;
+        }
+        else {
+            WOLFSSL_MSG("Bad der length");
+            ret = BAD_FUNC_ARG;
+        }
+    }
+
+    XFREE(der.buffer, NULL, DYNAMIC_TYPE_KEY);
+    return ret;
+}
+
+#endif /* !NO_CERTS */
+
+
+
+#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
+
+void wolfSSL_ERR_print_errors_fp(XFILE fp, int err)
+{
+    char data[WOLFSSL_MAX_ERROR_SZ + 1];
+
+    WOLFSSL_ENTER("wolfSSL_ERR_print_errors_fp");
+    SetErrorString(err, data);
+    fprintf(fp, "%s", data);
+}
+
+#endif
+
+
+int wolfSSL_pending(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_pending");
+    return ssl->buffers.clearOutputBuffer.length;
+}
+
+
+#ifndef WOLFSSL_LEANPSK
+/* turn on handshake group messages for context */
+int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
+{
+    if (ctx == NULL)
+       return BAD_FUNC_ARG;
+
+    ctx->groupMessages = 1;
+
+    return SSL_SUCCESS;
+}
+#endif
+
+
+#ifndef NO_WOLFSSL_CLIENT
+/* connect enough to get peer cert chain */
+int wolfSSL_connect_cert(WOLFSSL* ssl)
+{
+    int  ret;
+
+    if (ssl == NULL)
+        return SSL_FAILURE;
+
+    ssl->options.certOnly = 1;
+    ret = wolfSSL_connect(ssl);
+    ssl->options.certOnly   = 0;
+
+    return ret;
+}
+#endif
+
+
+#ifndef WOLFSSL_LEANPSK
+/* turn on handshake group messages for ssl object */
+int wolfSSL_set_group_messages(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+       return BAD_FUNC_ARG;
+
+    ssl->options.groupMessages = 1;
+
+    return SSL_SUCCESS;
+}
+
+
+/* make minVersion the internal equivalent SSL version */
+static int SetMinVersionHelper(byte* minVersion, int version)
+{
+    switch (version) {
+#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
+        case WOLFSSL_SSLV3:
+            *minVersion = SSLv3_MINOR;
+            break;
+#endif
+
+#ifndef NO_TLS
+    #ifndef NO_OLD_TLS
+        case WOLFSSL_TLSV1:
+            *minVersion = TLSv1_MINOR;
+            break;
+
+        case WOLFSSL_TLSV1_1:
+            *minVersion = TLSv1_1_MINOR;
+            break;
+    #endif
+        case WOLFSSL_TLSV1_2:
+            *minVersion = TLSv1_2_MINOR;
+            break;
+#endif
+
+        default:
+            WOLFSSL_MSG("Bad function argument");
+            return BAD_FUNC_ARG;
+    }
+
+    return SSL_SUCCESS;
+}
+
+
+/* Set minimum downgrade version allowed, SSL_SUCCESS on ok */
+int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_SetMinVersion");
+
+    if (ctx == NULL) {
+        WOLFSSL_MSG("Bad function argument");
+        return BAD_FUNC_ARG;
+    }
+
+    return SetMinVersionHelper(&ctx->minDowngrade, version);
+}
+
+
+/* Set minimum downgrade version allowed, SSL_SUCCESS on ok */
+int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version)
+{
+    WOLFSSL_ENTER("wolfSSL_SetMinVersion");
+
+    if (ssl == NULL) {
+        WOLFSSL_MSG("Bad function argument");
+        return BAD_FUNC_ARG;
+    }
+
+    return SetMinVersionHelper(&ssl->options.minDowngrade, version);
+}
+
+
+int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
+{
+    byte haveRSA = 1;
+    byte havePSK = 0;
+
+    WOLFSSL_ENTER("wolfSSL_SetVersion");
+
+    if (ssl == NULL) {
+        WOLFSSL_MSG("Bad function argument");
+        return BAD_FUNC_ARG;
+    }
+
+    switch (version) {
+#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
+        case WOLFSSL_SSLV3:
+            ssl->version = MakeSSLv3();
+            break;
+#endif
+
+#ifndef NO_TLS
+    #ifndef NO_OLD_TLS
+        case WOLFSSL_TLSV1:
+            ssl->version = MakeTLSv1();
+            break;
+
+        case WOLFSSL_TLSV1_1:
+            ssl->version = MakeTLSv1_1();
+            break;
+    #endif
+        case WOLFSSL_TLSV1_2:
+            ssl->version = MakeTLSv1_2();
+            break;
+#endif
+
+        default:
+            WOLFSSL_MSG("Bad function argument");
+            return BAD_FUNC_ARG;
+    }
+
+    #ifdef NO_RSA
+        haveRSA = 0;
+    #endif
+    #ifndef NO_PSK
+        havePSK = ssl->options.havePSK;
+    #endif
+
+    InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH,
+                ssl->options.haveNTRU, ssl->options.haveECDSAsig,
+                ssl->options.haveStaticECC, ssl->options.side);
+
+    return SSL_SUCCESS;
+}
+#endif /* !leanpsk */
+
+
+#if !defined(NO_CERTS) || !defined(NO_SESSION_CACHE)
+
+/* Make a work from the front of random hash */
+static INLINE word32 MakeWordFromHash(const byte* hashID)
+{
+    return (hashID[0] << 24) | (hashID[1] << 16) | (hashID[2] <<  8) |
+            hashID[3];
+}
+
+#endif /* !NO_CERTS || !NO_SESSION_CACHE */
+
+
+#ifndef NO_CERTS
+
+/* hash is the SHA digest of name, just use first 32 bits as hash */
+static INLINE word32 HashSigner(const byte* hash)
+{
+    return MakeWordFromHash(hash) % CA_TABLE_SIZE;
+}
+
+
+/* does CA already exist on signer list */
+int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash)
+{
+    Signer* signers;
+    int     ret = 0;
+    word32  row = HashSigner(hash);
+
+    if (LockMutex(&cm->caLock) != 0)
+        return  ret;
+    signers = cm->caTable[row];
+    while (signers) {
+        byte* subjectHash;
+        #ifndef NO_SKID
+            subjectHash = signers->subjectKeyIdHash;
+        #else
+            subjectHash = signers->subjectNameHash;
+        #endif
+        if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
+            ret = 1;
+            break;
+        }
+        signers = signers->next;
+    }
+    UnLockMutex(&cm->caLock);
+
+    return ret;
+}
+
+
+/* return CA if found, otherwise NULL */
+Signer* GetCA(void* vp, byte* hash)
+{
+    WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
+    Signer* ret = NULL;
+    Signer* signers;
+    word32  row = HashSigner(hash);
+
+    if (cm == NULL)
+        return NULL;
+
+    if (LockMutex(&cm->caLock) != 0)
+        return ret;
+
+    signers = cm->caTable[row];
+    while (signers) {
+        byte* subjectHash;
+        #ifndef NO_SKID
+            subjectHash = signers->subjectKeyIdHash;
+        #else
+            subjectHash = signers->subjectNameHash;
+        #endif
+        if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
+            ret = signers;
+            break;
+        }
+        signers = signers->next;
+    }
+    UnLockMutex(&cm->caLock);
+
+    return ret;
+}
+
+
+#ifndef NO_SKID
+/* return CA if found, otherwise NULL. Walk through hash table. */
+Signer* GetCAByName(void* vp, byte* hash)
+{
+    WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
+    Signer* ret = NULL;
+    Signer* signers;
+    word32  row;
+
+    if (cm == NULL)
+        return NULL;
+
+    if (LockMutex(&cm->caLock) != 0)
+        return ret;
+
+    for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
+        signers = cm->caTable[row];
+        while (signers && ret == NULL) {
+            if (XMEMCMP(hash, signers->subjectNameHash,
+                        SIGNER_DIGEST_SIZE) == 0) {
+                ret = signers;
+            }
+            signers = signers->next;
+        }
+    }
+    UnLockMutex(&cm->caLock);
+
+    return ret;
+}
+#endif
+
+
+/* owns der, internal now uses too */
+/* type flag ids from user or from chain received during verify
+   don't allow chain ones to be added w/o isCA extension */
+int AddCA(WOLFSSL_CERT_MANAGER* cm, buffer der, int type, int verify)
+{
+    int         ret;
+    Signer*     signer = 0;
+    word32      row;
+    byte*       subjectHash;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* cert = NULL;
+#else
+    DecodedCert  cert[1];
+#endif
+
+    WOLFSSL_MSG("Adding a CA");
+
+#ifdef WOLFSSL_SMALL_STACK
+    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                 DYNAMIC_TYPE_TMP_BUFFER);
+    if (cert == NULL)
+        return MEMORY_E;
+#endif
+
+    InitDecodedCert(cert, der.buffer, der.length, cm->heap);
+    ret = ParseCert(cert, CA_TYPE, verify, cm);
+    WOLFSSL_MSG("    Parsed new CA");
+
+#ifndef NO_SKID
+    subjectHash = cert->extSubjKeyId;
+#else
+    subjectHash = cert->subjectHash;
+#endif
+
+    if (ret == 0 && cert->isCA == 0 && type != WOLFSSL_USER_CA) {
+        WOLFSSL_MSG("    Can't add as CA if not actually one");
+        ret = NOT_CA_ERROR;
+    }
+#ifndef ALLOW_INVALID_CERTSIGN
+    else if (ret == 0 && cert->isCA == 1 && type != WOLFSSL_USER_CA &&
+             (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) == 0) {
+        /* Intermediate CA certs are required to have the keyCertSign
+        * extension set. User loaded root certs are not. */
+        WOLFSSL_MSG("    Doesn't have key usage certificate signing");
+        ret = NOT_CA_ERROR;
+    }
+#endif
+    else if (ret == 0 && AlreadySigner(cm, subjectHash)) {
+        WOLFSSL_MSG("    Already have this CA, not adding again");
+        (void)ret;
+    }
+    else if (ret == 0) {
+        /* take over signer parts */
+        signer = MakeSigner(cm->heap);
+        if (!signer)
+            ret = MEMORY_ERROR;
+        else {
+            signer->keyOID         = cert->keyOID;
+            signer->publicKey      = cert->publicKey;
+            signer->pubKeySize     = cert->pubKeySize;
+            signer->nameLen        = cert->subjectCNLen;
+            signer->name           = cert->subjectCN;
+        #ifndef IGNORE_NAME_CONSTRAINTS
+            signer->permittedNames = cert->permittedNames;
+            signer->excludedNames  = cert->excludedNames;
+        #endif
+        #ifndef NO_SKID
+            XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
+                    SIGNER_DIGEST_SIZE);
+        #endif
+            XMEMCPY(signer->subjectNameHash, cert->subjectHash,
+                    SIGNER_DIGEST_SIZE);
+            signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
+                                                    : 0xFFFF;
+            signer->next    = NULL; /* If Key Usage not set, all uses valid. */
+            cert->publicKey = 0;    /* in case lock fails don't free here.   */
+            cert->subjectCN = 0;
+        #ifndef IGNORE_NAME_CONSTRAINTS
+            cert->permittedNames = NULL;
+            cert->excludedNames = NULL;
+        #endif
+
+        #ifndef NO_SKID
+            row = HashSigner(signer->subjectKeyIdHash);
+        #else
+            row = HashSigner(signer->subjectNameHash);
+        #endif
+
+            if (LockMutex(&cm->caLock) == 0) {
+                signer->next = cm->caTable[row];
+                cm->caTable[row] = signer;   /* takes ownership */
+                UnLockMutex(&cm->caLock);
+                if (cm->caCacheCallback)
+                    cm->caCacheCallback(der.buffer, (int)der.length, type);
+            }
+            else {
+                WOLFSSL_MSG("    CA Mutex Lock failed");
+                ret = BAD_MUTEX_E;
+                FreeSigner(signer, cm->heap);
+            }
+        }
+    }
+
+    WOLFSSL_MSG("    Freeing Parsed CA");
+    FreeDecodedCert(cert);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+    WOLFSSL_MSG("    Freeing der CA");
+    XFREE(der.buffer, cm->heap, DYNAMIC_TYPE_CA);
+    WOLFSSL_MSG("        OK Freeing der CA");
+
+    WOLFSSL_LEAVE("AddCA", ret);
+
+    return ret == 0 ? SSL_SUCCESS : ret;
+}
+
+#endif /* !NO_CERTS */
+
+
+#ifndef NO_SESSION_CACHE
+
+    /* basic config gives a cache with 33 sessions, adequate for clients and
+       embedded servers
+
+       MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
+       aren't under heavy load, basically allows 200 new sessions per minute
+
+       BIG_SESSION_CACHE yields 20,027 sessions
+
+       HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
+       allows over 13,000 new sessions per minute or over 200 new sessions per
+       second
+
+       SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
+       or systems where the default of nearly 3kB is too much RAM, this define
+       uses less than 500 bytes RAM
+
+       default SESSION_CACHE stores 33 sessions (no XXX_SESSION_CACHE defined)
+    */
+    #ifdef HUGE_SESSION_CACHE
+        #define SESSIONS_PER_ROW 11
+        #define SESSION_ROWS 5981
+    #elif defined(BIG_SESSION_CACHE)
+        #define SESSIONS_PER_ROW 7
+        #define SESSION_ROWS 2861
+    #elif defined(MEDIUM_SESSION_CACHE)
+        #define SESSIONS_PER_ROW 5
+        #define SESSION_ROWS 211
+    #elif defined(SMALL_SESSION_CACHE)
+        #define SESSIONS_PER_ROW 2
+        #define SESSION_ROWS 3
+    #else
+        #define SESSIONS_PER_ROW 3
+        #define SESSION_ROWS 11
+    #endif
+
+    typedef struct SessionRow {
+        int nextIdx;                           /* where to place next one   */
+        int totalCount;                        /* sessions ever on this row */
+        WOLFSSL_SESSION Sessions[SESSIONS_PER_ROW];
+    } SessionRow;
+
+    static SessionRow SessionCache[SESSION_ROWS];
+
+    #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
+        static word32 PeakSessions;
+    #endif
+
+    static wolfSSL_Mutex session_mutex;   /* SessionCache mutex */
+
+    #ifndef NO_CLIENT_CACHE
+
+        typedef struct ClientSession {
+            word16 serverRow;            /* SessionCache Row id */
+            word16 serverIdx;            /* SessionCache Idx (column) */
+        } ClientSession;
+
+        typedef struct ClientRow {
+            int nextIdx;                /* where to place next one   */
+            int totalCount;             /* sessions ever on this row */
+            ClientSession Clients[SESSIONS_PER_ROW];
+        } ClientRow;
+
+        static ClientRow ClientCache[SESSION_ROWS];  /* Client Cache */
+                                                     /* uses session mutex */
+    #endif  /* NO_CLIENT_CACHE */
+
+#endif /* NO_SESSION_CACHE */
+
+int wolfSSL_Init(void)
+{
+    int ret = SSL_SUCCESS;
+
+    WOLFSSL_ENTER("wolfSSL_Init");
+
+    if (initRefCount == 0) {
+#ifndef NO_SESSION_CACHE
+        if (InitMutex(&session_mutex) != 0)
+            ret = BAD_MUTEX_E;
+#endif
+        if (InitMutex(&count_mutex) != 0)
+            ret = BAD_MUTEX_E;
+    }
+    if (ret == SSL_SUCCESS) {
+        if (LockMutex(&count_mutex) != 0) {
+            WOLFSSL_MSG("Bad Lock Mutex count");
+            return BAD_MUTEX_E;
+        }
+
+        /* Initialize crypto for use with TLS connection */
+        if (wolfcrypt_Init() != 0)
+            ret = WC_FAILURE_E;
+
+        initRefCount++;
+        UnLockMutex(&count_mutex);
+    }
+
+    return ret;
+}
+
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+
+/* SSL_SUCCESS if ok, <= 0 else */
+static int wolfssl_decrypt_buffer_key(buffer* der, byte* password,
+                                      int passwordSz, EncryptedInfo* info)
+{
+    int ret;
+
+#ifdef WOLFSSL_SMALL_STACK
+    byte* key      = NULL;
+#else
+    byte  key[AES_256_KEY_SIZE];
+#endif
+
+    WOLFSSL_ENTER("wolfssl_decrypt_buffer_key");
+
+    if (der == NULL || password == NULL || info == NULL) {
+        WOLFSSL_MSG("bad arguments");
+        return SSL_FATAL_ERROR;
+    }
+
+    /* use file's salt for key derivation, hex decode first */
+    if (Base16_Decode(info->iv, info->ivSz, info->iv, &info->ivSz) != 0) {
+        WOLFSSL_MSG("base16 decode failed");
+        return SSL_FATAL_ERROR;
+    }
+
+#ifndef NO_MD5
+
+#ifdef WOLFSSL_SMALL_STACK
+    key = (byte*)XMALLOC(AES_256_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (key == NULL) {
+        WOLFSSL_MSG("memory failure");
+        return SSL_FATAL_ERROR;
+    }
+#endif /* WOLFSSL_SMALL_STACK */
+
+    if ((ret = wolfSSL_EVP_BytesToKey(info->name, "MD5", info->iv,
+                              password, passwordSz, 1, key, NULL)) <= 0) {
+        WOLFSSL_MSG("bytes to key failure");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return SSL_FATAL_ERROR;
+    }
+#else
+    (void) passwordSz;
+#endif /* NO_MD5 */
+
+#ifndef NO_DES3
+    if (XSTRNCMP(info->name, EVP_DES_CBC, EVP_DES_SIZE) == 0)
+        ret = wc_Des_CbcDecryptWithKey(der->buffer, der->buffer, der->length,
+                                       key, info->iv);
+    else if (XSTRNCMP(info->name, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)
+        ret = wc_Des3_CbcDecryptWithKey(der->buffer, der->buffer, der->length,
+                                        key, info->iv);
+#endif /* NO_DES3 */
+#ifndef NO_AES
+    else if (XSTRNCMP(info->name, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)
+        ret = wc_AesCbcDecryptWithKey(der->buffer, der->buffer, der->length,
+                                      key, AES_128_KEY_SIZE, info->iv);
+    else if (XSTRNCMP(info->name, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)
+        ret = wc_AesCbcDecryptWithKey(der->buffer, der->buffer, der->length,
+                                      key, AES_192_KEY_SIZE, info->iv);
+    else if (XSTRNCMP(info->name, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)
+        ret = wc_AesCbcDecryptWithKey(der->buffer, der->buffer, der->length,
+                                      key, AES_256_KEY_SIZE, info->iv);
+#endif /* NO_AES */
+    else
+        ret = SSL_BAD_FILE;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (ret == MP_OKAY)
+        return SSL_SUCCESS;
+    else if (ret == SSL_BAD_FILE)
+        return SSL_BAD_FILE;
+
+    return SSL_FATAL_ERROR;
+}
+#endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) */
+
+
+#if defined(WOLFSSL_KEY_GEN) && defined(OPENSSL_EXTRA)
+static int wolfssl_encrypt_buffer_key(byte* der, word32 derSz, byte* password,
+                                      int passwordSz, EncryptedInfo* info)
+{
+    int ret;
+
+#ifdef WOLFSSL_SMALL_STACK
+    byte* key      = NULL;
+#else
+    byte  key[AES_256_KEY_SIZE];
+#endif
+
+    WOLFSSL_ENTER("wolfssl_encrypt_buffer_key");
+
+    if (der == NULL || password == NULL || info == NULL || info->ivSz == 0) {
+        WOLFSSL_MSG("bad arguments");
+        return SSL_FATAL_ERROR;
+    }
+
+#ifndef NO_MD5
+
+#ifdef WOLFSSL_SMALL_STACK
+    key = (byte*)XMALLOC(AES_256_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (key == NULL) {
+        WOLFSSL_MSG("memory failure");
+        return SSL_FATAL_ERROR;
+    }
+#endif /* WOLFSSL_SMALL_STACK */
+
+    if ((ret = wolfSSL_EVP_BytesToKey(info->name, "MD5", info->iv,
+                              password, passwordSz, 1, key, NULL)) <= 0) {
+        WOLFSSL_MSG("bytes to key failure");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return SSL_FATAL_ERROR;
+    }
+#else
+    (void) passwordSz;
+#endif /* NO_MD5 */
+
+#ifndef NO_DES3
+    if (XSTRNCMP(info->name, EVP_DES_CBC, EVP_DES_SIZE) == 0)
+        ret = wc_Des_CbcEncryptWithKey(der, der, derSz, key, info->iv);
+    else if (XSTRNCMP(info->name, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)
+        ret = wc_Des3_CbcEncryptWithKey(der, der, derSz, key, info->iv);
+#endif /* NO_DES3 */
+#ifndef NO_AES
+    else if (XSTRNCMP(info->name, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)
+        ret = wc_AesCbcEncryptWithKey(der, der, derSz,
+                                      key, AES_128_KEY_SIZE, info->iv);
+    else if (XSTRNCMP(info->name, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)
+        ret = wc_AesCbcEncryptWithKey(der, der, derSz,
+                                      key, AES_192_KEY_SIZE, info->iv);
+    else if (XSTRNCMP(info->name, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)
+        ret = wc_AesCbcEncryptWithKey(der, der, derSz,
+                                      key, AES_256_KEY_SIZE, info->iv);
+#endif /* NO_AES */
+    else
+        ret = SSL_BAD_FILE;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+    
+    if (ret == MP_OKAY)
+        return SSL_SUCCESS;
+    else if (ret == SSL_BAD_FILE)
+        return SSL_BAD_FILE;
+
+    return SSL_FATAL_ERROR;
+}
+#endif /* defined(WOLFSSL_KEY_GEN) */
+
+
+#ifndef NO_CERTS
+
+/* Remove PEM header/footer, convert to ASN1, store any encrypted data
+   info->consumed tracks of PEM bytes consumed in case multiple parts */
+int PemToDer(const unsigned char* buff, long longSz, int type,
+                  buffer* der, void* heap, EncryptedInfo* info, int* eccKey)
+{
+    const char* header      = NULL;
+    const char* footer      = NULL;
+    char*       headerEnd;
+    char*       footerEnd;
+    char*       consumedEnd;
+    char*       bufferEnd   = (char*)(buff + longSz);
+    long        neededSz;
+    int         ret         = 0;
+    int         dynamicType = 0;
+    int         sz          = (int)longSz;
+    int         encrypted_key = 0;
+
+    WOLFSSL_ENTER("PemToDer");
+
+    switch (type) {
+        case CA_TYPE:       /* same as below */
+        case CERT_TYPE:      header=BEGIN_CERT;     footer=END_CERT;     break;
+        case CRL_TYPE:       header=BEGIN_X509_CRL; footer=END_X509_CRL; break;
+        case DH_PARAM_TYPE:  header=BEGIN_DH_PARAM; footer=END_DH_PARAM; break;
+        case CERTREQ_TYPE:   header=BEGIN_CERT_REQ; footer=END_CERT_REQ; break;
+        case DSA_TYPE:       header=BEGIN_DSA_PRIV; footer=END_DSA_PRIV; break;
+        case ECC_TYPE:       header=BEGIN_EC_PRIV;  footer=END_EC_PRIV;  break;
+        case RSA_TYPE:       header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV; break;
+        case PUBLICKEY_TYPE: header=BEGIN_PUB_KEY;  footer=END_PUB_KEY;  break;
+        default:             header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV; break;
+    }
+
+    switch (type) {
+        case CA_TYPE:   dynamicType = DYNAMIC_TYPE_CA;   break;
+        case CERT_TYPE: dynamicType = DYNAMIC_TYPE_CERT; break;
+        case CRL_TYPE:  dynamicType = DYNAMIC_TYPE_CRL;  break;
+        case DSA_TYPE:  dynamicType = DYNAMIC_TYPE_DSA;  break;
+        case ECC_TYPE:  dynamicType = DYNAMIC_TYPE_ECC;  break;
+        case RSA_TYPE:  dynamicType = DYNAMIC_TYPE_RSA;  break;
+        default:        dynamicType = DYNAMIC_TYPE_KEY;  break;
+    }
+
+    /* find header */
+    for (;;) {
+        headerEnd = XSTRNSTR((char*)buff, header, sz);
+
+        if (headerEnd || type != PRIVATEKEY_TYPE) {
+            break;
+        } else if (header == BEGIN_RSA_PRIV) {
+                   header =  BEGIN_PRIV_KEY;       footer = END_PRIV_KEY;
+        } else if (header == BEGIN_PRIV_KEY) {
+                   header =  BEGIN_ENC_PRIV_KEY;   footer = END_ENC_PRIV_KEY;
+        } else if (header == BEGIN_ENC_PRIV_KEY) {
+                   header =  BEGIN_EC_PRIV;        footer = END_EC_PRIV;
+        } else if (header == BEGIN_EC_PRIV) {
+                   header =  BEGIN_DSA_PRIV;       footer = END_DSA_PRIV;
+        } else
+            break;
+    }
+
+    if (!headerEnd) {
+        WOLFSSL_MSG("Couldn't find PEM header");
+        return SSL_NO_PEM_HEADER;
+    }
+
+    headerEnd += XSTRLEN(header);
+
+    /* eat end of line */
+    if (headerEnd[0] == '\n')
+        headerEnd++;
+    else if (headerEnd[1] == '\n')
+        headerEnd += 2;
+    else {
+        if (info)
+            info->consumed = (long)(headerEnd+2 - (char*)buff);
+        return SSL_BAD_FILE;
+    }
+
+    if (type == PRIVATEKEY_TYPE) {
+        if (eccKey)
+            *eccKey = header == BEGIN_EC_PRIV;
+    }
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+    {
+        /* remove encrypted header if there */
+        char encHeader[] = "Proc-Type";
+        char* line = XSTRNSTR(headerEnd, encHeader, PEM_LINE_LEN);
+        if (line) {
+            char* newline;
+            char* finish;
+            char* start  = XSTRNSTR(line, "DES", PEM_LINE_LEN);
+
+            if (!start)
+                start = XSTRNSTR(line, "AES", PEM_LINE_LEN);
+
+            if (!start) return SSL_BAD_FILE;
+            if (!info)  return SSL_BAD_FILE;
+
+            finish = XSTRNSTR(start, ",", PEM_LINE_LEN);
+
+            if (start && finish && (start < finish)) {
+                newline = XSTRNSTR(finish, "\r", PEM_LINE_LEN);
+
+                if (XMEMCPY(info->name, start, finish - start) == NULL)
+                    return SSL_FATAL_ERROR;
+                info->name[finish - start] = 0;
+                if (XMEMCPY(info->iv, finish + 1, sizeof(info->iv)) == NULL)
+                    return SSL_FATAL_ERROR;
+
+                if (!newline) newline = XSTRNSTR(finish, "\n", PEM_LINE_LEN);
+                if (newline && (newline > finish)) {
+                    info->ivSz = (word32)(newline - (finish + 1));
+                    info->set = 1;
+                }
+                else
+                    return SSL_BAD_FILE;
+            }
+            else
+                return SSL_BAD_FILE;
+
+            /* eat blank line */
+            while (*newline == '\r' || *newline == '\n')
+                newline++;
+            headerEnd = newline;
+
+            encrypted_key = 1;
+        }
+    }
+#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
+
+    /* find footer */
+    footerEnd = XSTRNSTR((char*)buff, footer, sz);
+    if (!footerEnd) {
+        if (info)
+            info->consumed = longSz; /* No more certs if no footer */
+        return SSL_BAD_FILE;
+    }
+
+    consumedEnd = footerEnd + XSTRLEN(footer);
+
+    if (consumedEnd < bufferEnd) {  /* handle no end of line on last line */
+        /* eat end of line */
+        if (consumedEnd[0] == '\n')
+            consumedEnd++;
+        else if (consumedEnd[1] == '\n')
+            consumedEnd += 2;
+        else {
+            if (info)
+                info->consumed = (long)(consumedEnd+2 - (char*)buff);
+            return SSL_BAD_FILE;
+        }
+    }
+
+    if (info)
+        info->consumed = (long)(consumedEnd - (char*)buff);
+
+    /* set up der buffer */
+    neededSz = (long)(footerEnd - headerEnd);
+    if (neededSz > sz || neededSz < 0)
+        return SSL_BAD_FILE;
+
+    der->buffer = (byte*)XMALLOC(neededSz, heap, dynamicType);
+    if (!der->buffer)
+        return MEMORY_ERROR;
+
+    der->length = (word32)neededSz;
+
+    if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
+                      der->buffer, &der->length) < 0)
+        return SSL_BAD_FILE;
+
+    if (header == BEGIN_PRIV_KEY && !encrypted_key) {
+        /* pkcs8 key, convert and adjust length */
+        if ((ret = ToTraditional(der->buffer, der->length)) < 0)
+            return ret;
+
+        der->length = ret;
+        return 0;
+    }
+
+#if (defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)) && !defined(NO_PWDBASED)
+    if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
+        int   passwordSz;
+    #ifdef WOLFSSL_SMALL_STACK
+        char* password = NULL;
+    #else
+        char  password[80];
+    #endif
+
+        if (!info || !info->ctx || !info->ctx->passwd_cb)
+            return SSL_BAD_FILE;  /* no callback error */
+
+    #ifdef WOLFSSL_SMALL_STACK
+        password = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (password == NULL)
+            return MEMORY_E;
+    #endif
+        passwordSz = info->ctx->passwd_cb(password, sizeof(password), 0,
+                                          info->ctx->userdata);
+        /* convert and adjust length */
+        if (header == BEGIN_ENC_PRIV_KEY) {
+            ret = ToTraditionalEnc(der->buffer, der->length,
+                                   password, passwordSz);
+    #ifdef WOLFSSL_SMALL_STACK
+            XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+            if (ret < 0) {
+                XFREE(der->buffer, heap, dynamicType);
+                return ret;
+            }
+
+            der->length = ret;
+        }
+        /* decrypt the key */
+        else {
+            ret = wolfssl_decrypt_buffer_key(der, (byte*)password,
+                                             passwordSz, info);
+    #ifdef WOLFSSL_SMALL_STACK
+            XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+            if (ret != SSL_SUCCESS) {
+                XFREE(der->buffer, heap, dynamicType);
+                return ret;
+            }
+        }
+    }
+#endif  /* OPENSSL_EXTRA || HAVE_WEBSERVER || NO_PWDBASED */
+
+    return 0;
+}
+
+
+/* process the buffer buff, legnth sz, into ctx of format and type
+   used tracks bytes consumed, userChain specifies a user cert chain
+   to pass during the handshake */
+static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
+                         long sz, int format, int type, WOLFSSL* ssl,
+                         long* used, int userChain)
+{
+    buffer        der;        /* holds DER or RAW (for NTRU) */
+    int           ret;
+    int           dynamicType = 0;
+    int           eccKey = 0;
+    int           rsaKey = 0;
+    void*         heap = ctx ? ctx->heap : NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    EncryptedInfo* info = NULL;
+#else
+    EncryptedInfo  info[1];
+#endif
+
+    (void)dynamicType;
+    (void)rsaKey;
+
+    if (used)
+        *used = sz;     /* used bytes default to sz, PEM chain may shorten*/
+
+    if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM
+                                    && format != SSL_FILETYPE_RAW)
+        return SSL_BAD_FILETYPE;
+
+    if (ctx == NULL && ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    if (type == CA_TYPE)
+        dynamicType = DYNAMIC_TYPE_CA;
+    else if (type == CERT_TYPE)
+        dynamicType = DYNAMIC_TYPE_CERT;
+    else
+        dynamicType = DYNAMIC_TYPE_KEY;
+
+#ifdef WOLFSSL_SMALL_STACK
+    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
+                                   DYNAMIC_TYPE_TMP_BUFFER);
+    if (info == NULL)
+        return MEMORY_E;
+#endif
+
+    info->set      = 0;
+    info->ctx      = ctx;
+    info->consumed = 0;
+    der.buffer     = 0;
+
+    if (format == SSL_FILETYPE_PEM) {
+        ret = PemToDer(buff, sz, type, &der, heap, info, &eccKey);
+
+        if (used)
+            *used = info->consumed;
+
+        if (ret < 0) {
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+            XFREE(der.buffer, heap, dynamicType);
+            return ret;
+        }
+
+        /* we may have a user cert chain, try to consume */
+        if (userChain && type == CERT_TYPE && info->consumed < sz) {
+        #ifdef WOLFSSL_SMALL_STACK
+            byte   staticBuffer[1];                 /* force heap usage */
+        #else
+            byte   staticBuffer[FILE_BUFFER_SIZE];  /* tmp chain buffer */
+        #endif
+            byte*  chainBuffer = staticBuffer;
+            byte*  shrinked    = NULL;   /* shrinked to size chainBuffer
+                                          * or staticBuffer */
+            int    dynamicBuffer = 0;
+            word32 bufferSz = sizeof(staticBuffer);
+            long   consumed = info->consumed;
+            word32 idx = 0;
+            int    gotOne = 0;
+
+            if ( (sz - consumed) > (int)bufferSz) {
+                WOLFSSL_MSG("Growing Tmp Chain Buffer");
+                bufferSz = (word32)(sz - consumed);
+                           /* will shrink to actual size */
+                chainBuffer = (byte*)XMALLOC(bufferSz, heap, DYNAMIC_TYPE_FILE);
+                if (chainBuffer == NULL) {
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                #endif
+                    XFREE(der.buffer, heap, dynamicType);
+                    return MEMORY_E;
+                }
+                dynamicBuffer = 1;
+            }
+
+            WOLFSSL_MSG("Processing Cert Chain");
+            while (consumed < sz) {
+                buffer part;
+                info->consumed = 0;
+                part.buffer = 0;
+
+                ret = PemToDer(buff + consumed, sz - consumed, type, &part,
+                               heap, info, &eccKey);
+                if (ret == 0) {
+                    gotOne = 1;
+                    if ( (idx + part.length) > bufferSz) {
+                        WOLFSSL_MSG("   Cert Chain bigger than buffer");
+                        ret = BUFFER_E;
+                    }
+                    else {
+                        c32to24(part.length, &chainBuffer[idx]);
+                        idx += CERT_HEADER_SZ;
+                        XMEMCPY(&chainBuffer[idx], part.buffer,part.length);
+                        idx += part.length;
+                        consumed  += info->consumed;
+                        if (used)
+                            *used += info->consumed;
+                    }
+                }
+
+                XFREE(part.buffer, heap, dynamicType);
+
+                if (ret == SSL_NO_PEM_HEADER && gotOne) {
+                    WOLFSSL_MSG("We got one good PEM so stuff at end ok");
+                    break;
+                }
+
+                if (ret < 0) {
+                    WOLFSSL_MSG("   Error in Cert in Chain");
+                    if (dynamicBuffer)
+                        XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                #endif
+                    XFREE(der.buffer, heap, dynamicType);
+                    return ret;
+                }
+                WOLFSSL_MSG("   Consumed another Cert in Chain");
+            }
+            WOLFSSL_MSG("Finished Processing Cert Chain");
+
+            /* only retain actual size used */
+            shrinked = (byte*)XMALLOC(idx, heap, dynamicType);
+            if (shrinked) {
+                if (ssl) {
+                    if (ssl->buffers.certChain.buffer &&
+                        ssl->buffers.weOwnCertChain) {
+                        XFREE(ssl->buffers.certChain.buffer, heap, dynamicType);
+                    }
+                    ssl->buffers.certChain.buffer = shrinked;
+                    ssl->buffers.certChain.length = idx;
+                    XMEMCPY(ssl->buffers.certChain.buffer, chainBuffer,idx);
+                    ssl->buffers.weOwnCertChain = 1;
+                } else if (ctx) {
+                    if (ctx->certChain.buffer)
+                        XFREE(ctx->certChain.buffer, heap, dynamicType);
+                    ctx->certChain.buffer = shrinked;
+                    ctx->certChain.length = idx;
+                    XMEMCPY(ctx->certChain.buffer, chainBuffer, idx);
+                }
+            }
+
+            if (dynamicBuffer)
+                XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
+
+            if (shrinked == NULL) {
+            #ifdef WOLFSSL_SMALL_STACK
+                XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+                XFREE(der.buffer, heap, dynamicType);
+                return MEMORY_E;
+            }
+        }
+    }
+    else {  /* ASN1 (DER) or RAW (NTRU) */
+        der.buffer = (byte*) XMALLOC(sz, heap, dynamicType);
+        if (!der.buffer) {
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+            return MEMORY_ERROR;
+        }
+
+        XMEMCPY(der.buffer, buff, sz);
+        der.length = (word32)sz;
+    }
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+    /* for SSL_FILETYPE_PEM, PemToDer manage the decryption if required */
+    if (info->set && (format != SSL_FILETYPE_PEM)) {
+        /* decrypt */
+        int   passwordSz;
+#ifdef WOLFSSL_SMALL_STACK
+        char* password = NULL;
+#else
+        char  password[80];
+#endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        password = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (password == NULL)
+            ret = MEMORY_E;
+        else
+    #endif
+        if (!ctx || !ctx->passwd_cb) {
+            ret = NO_PASSWORD;
+        }
+        else {
+            passwordSz = ctx->passwd_cb(password, sizeof(password),
+                                        0, ctx->userdata);
+
+            /* decrypt the key */
+            ret = wolfssl_decrypt_buffer_key(&der, (byte*)password,
+                                             passwordSz, info);
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+
+        if (ret != SSL_SUCCESS) {
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+            XFREE(der.buffer, heap, dynamicType);
+            return ret;
+        }
+    }
+#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (type == CA_TYPE) {
+        if (ctx == NULL) {
+            WOLFSSL_MSG("Need context for CA load");
+            XFREE(der.buffer, heap, dynamicType);
+            return BAD_FUNC_ARG;
+        }
+        /* verify CA unless user set to no verify */
+        return AddCA(ctx->cm, der, WOLFSSL_USER_CA, !ctx->verifyNone);
+                                                      /* takes der over */
+    }
+    else if (type == CERT_TYPE) {
+        if (ssl) {
+            if (ssl->buffers.weOwnCert && ssl->buffers.certificate.buffer)
+                XFREE(ssl->buffers.certificate.buffer, heap, dynamicType);
+            ssl->buffers.certificate = der;
+            ssl->buffers.weOwnCert = 1;
+        }
+        else if (ctx) {
+            if (ctx->certificate.buffer)
+                XFREE(ctx->certificate.buffer, heap, dynamicType);
+            ctx->certificate = der;     /* takes der over */
+        }
+    }
+    else if (type == PRIVATEKEY_TYPE) {
+        if (ssl) {
+            if (ssl->buffers.weOwnKey && ssl->buffers.key.buffer)
+                XFREE(ssl->buffers.key.buffer, heap, dynamicType);
+            ssl->buffers.key = der;
+            ssl->buffers.weOwnKey = 1;
+        }
+        else if (ctx) {
+            if (ctx->privateKey.buffer)
+                XFREE(ctx->privateKey.buffer, heap, dynamicType);
+            ctx->privateKey = der;      /* takes der over */
+        }
+    }
+    else {
+        XFREE(der.buffer, heap, dynamicType);
+        return SSL_BAD_CERTTYPE;
+    }
+
+    if (type == PRIVATEKEY_TYPE && format != SSL_FILETYPE_RAW) {
+    #ifndef NO_RSA
+        if (!eccKey) {
+            /* make sure RSA key can be used */
+            word32 idx = 0;
+        #ifdef WOLFSSL_SMALL_STACK
+            RsaKey* key = NULL;
+        #else
+            RsaKey  key[1];
+        #endif
+
+        #ifdef WOLFSSL_SMALL_STACK
+            key = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
+                                   DYNAMIC_TYPE_TMP_BUFFER);
+            if (key == NULL)
+                return MEMORY_E;
+        #endif
+
+            ret = wc_InitRsaKey(key, 0);
+            if (ret == 0) {
+                if (wc_RsaPrivateKeyDecode(der.buffer, &idx, key, der.length)
+                    != 0) {
+                #ifdef HAVE_ECC
+                    /* could have DER ECC (or pkcs8 ecc), no easy way to tell */
+                    eccKey = 1;  /* so try it out */
+                #endif
+                    if (!eccKey)
+                        ret = SSL_BAD_FILE;
+                } else {
+                    rsaKey = 1;
+                    (void)rsaKey;  /* for no ecc builds */
+                }
+            }
+
+            wc_FreeRsaKey(key);
+
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+
+            if (ret != 0)
+                return ret;
+        }
+    #endif
+    #ifdef HAVE_ECC
+        if (!rsaKey) {
+            /* make sure ECC key can be used */
+            word32  idx = 0;
+            ecc_key key;
+
+            wc_ecc_init(&key);
+            if (wc_EccPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) {
+                wc_ecc_free(&key);
+                return SSL_BAD_FILE;
+            }
+            wc_ecc_free(&key);
+            eccKey = 1;
+            if (ctx)
+                ctx->haveStaticECC = 1;
+            if (ssl)
+                ssl->options.haveStaticECC = 1;
+        }
+    #endif /* HAVE_ECC */
+    }
+    else if (type == CERT_TYPE) {
+    #ifdef WOLFSSL_SMALL_STACK
+        DecodedCert* cert = NULL;
+    #else
+        DecodedCert  cert[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                     DYNAMIC_TYPE_TMP_BUFFER);
+        if (cert == NULL)
+            return MEMORY_E;
+    #endif
+
+        WOLFSSL_MSG("Checking cert signature type");
+        InitDecodedCert(cert, der.buffer, der.length, heap);
+
+        if (DecodeToKey(cert, 0) < 0) {
+            WOLFSSL_MSG("Decode to key failed");
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+            return SSL_BAD_FILE;
+        }
+        switch (cert->signatureOID) {
+            case CTC_SHAwECDSA:
+            case CTC_SHA256wECDSA:
+            case CTC_SHA384wECDSA:
+            case CTC_SHA512wECDSA:
+                WOLFSSL_MSG("ECDSA cert signature");
+                if (ctx)
+                    ctx->haveECDSAsig = 1;
+                if (ssl)
+                    ssl->options.haveECDSAsig = 1;
+                break;
+            default:
+                WOLFSSL_MSG("Not ECDSA cert signature");
+                break;
+        }
+
+    #ifdef HAVE_ECC
+        if (ctx)
+            ctx->pkCurveOID = cert->pkCurveOID;
+        if (ssl)
+            ssl->pkCurveOID = cert->pkCurveOID;
+    #endif
+
+        FreeDecodedCert(cert);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+    }
+
+    return SSL_SUCCESS;
+}
+
+
+/* CA PEM file for verification, may have multiple/chain certs to process */
+static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
+                            long sz, int format, int type, WOLFSSL* ssl)
+{
+    long used   = 0;
+    int  ret    = 0;
+    int  gotOne = 0;
+
+    WOLFSSL_MSG("Processing CA PEM file");
+    while (used < sz) {
+        long consumed = 0;
+
+        ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
+                            &consumed, 0);
+
+        if (ret < 0)
+        {
+            if(consumed > 0) { /* Made progress in file */
+                WOLFSSL_ERROR(ret);
+                WOLFSSL_MSG("CA Parse failed, with progress in file.");
+                WOLFSSL_MSG("Search for other certs in file");
+            } else {
+                WOLFSSL_MSG("CA Parse failed, no progress in file.");
+                WOLFSSL_MSG("Do not continue search for other certs in file");
+                break;
+            }
+        } else {
+            WOLFSSL_MSG("   Processed a CA");
+            gotOne = 1;
+        }
+        used += consumed;
+    }
+
+    if(gotOne)
+    {
+        WOLFSSL_MSG("Processed at least one valid CA. Other stuff OK");
+        return SSL_SUCCESS;
+    }
+    return ret;
+}
+
+
+static INLINE WOLFSSL_METHOD* cm_pick_method(void)
+{
+    #ifndef NO_WOLFSSL_CLIENT
+        #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
+            return wolfSSLv3_client_method();
+        #else
+            return wolfTLSv1_2_client_method();
+        #endif
+    #elif !defined(NO_WOLFSSL_SERVER)
+        #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
+            return wolfSSLv3_server_method();
+        #else
+            return wolfTLSv1_2_server_method();
+        #endif
+    #else
+        return NULL;
+    #endif
+}
+
+
+/* like load verify locations, 1 for success, < 0 for error */
+int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm,
+                                   const unsigned char* in, long sz, int format)
+{
+    int ret = SSL_FATAL_ERROR;
+    WOLFSSL_CTX* tmp;
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCABuffer");
+
+    if (cm == NULL) {
+        WOLFSSL_MSG("No CertManager error");
+        return ret;
+    }
+    tmp = wolfSSL_CTX_new(cm_pick_method());
+
+    if (tmp == NULL) {
+        WOLFSSL_MSG("CTX new failed");
+        return ret;
+    }
+
+    /* for tmp use */
+    wolfSSL_CertManagerFree(tmp->cm);
+    tmp->cm = cm;
+
+    ret = wolfSSL_CTX_load_verify_buffer(tmp, in, sz, format);
+
+    /* don't loose our good one */
+    tmp->cm = NULL;
+    wolfSSL_CTX_free(tmp);
+
+    return ret;
+}
+
+#ifdef HAVE_CRL
+
+int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm,
+                                   const unsigned char* buff, long sz, int type)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLBuffer");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    if (cm->crl == NULL) {
+        if (wolfSSL_CertManagerEnableCRL(cm, 0) != SSL_SUCCESS) {
+            WOLFSSL_MSG("Enable CRL failed");
+            return SSL_FATAL_ERROR;
+        }
+    }
+
+    return BufferLoadCRL(cm->crl, buff, sz, type);
+}
+
+#endif /* HAVE_CRL */
+
+/* turn on CRL if off and compiled in, set options */
+int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options)
+{
+    int ret = SSL_SUCCESS;
+
+    (void)options;
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerEnableCRL");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    #ifdef HAVE_CRL
+        if (cm->crl == NULL) {
+            cm->crl = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), cm->heap,
+                                           DYNAMIC_TYPE_CRL);
+            if (cm->crl == NULL)
+                return MEMORY_E;
+
+            if (InitCRL(cm->crl, cm) != 0) {
+                WOLFSSL_MSG("Init CRL failed");
+                FreeCRL(cm->crl, 1);
+                cm->crl = NULL;
+                return SSL_FAILURE;
+            }
+        }
+        cm->crlEnabled = 1;
+        if (options & WOLFSSL_CRL_CHECKALL)
+            cm->crlCheckAll = 1;
+    #else
+        ret = NOT_COMPILED_IN;
+    #endif
+
+    return ret;
+}
+
+
+int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerDisableCRL");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    cm->crlEnabled = 0;
+
+    return SSL_SUCCESS;
+}
+/* Verify the ceritficate, SSL_SUCCESS for ok, < 0 for error */
+int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
+                                    long sz, int format)
+{
+    int ret = 0;
+    buffer der;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* cert = NULL;
+#else
+    DecodedCert  cert[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerVerifyBuffer");
+
+#ifdef WOLFSSL_SMALL_STACK
+    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                 DYNAMIC_TYPE_TMP_BUFFER);
+    if (cert == NULL)
+        return MEMORY_E;
+#endif
+
+    der.buffer = NULL;
+    der.length = 0;
+
+    if (format == SSL_FILETYPE_PEM) {
+        int eccKey = 0; /* not used */
+    #ifdef WOLFSSL_SMALL_STACK
+        EncryptedInfo* info = NULL;
+    #else
+        EncryptedInfo  info[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
+                                       DYNAMIC_TYPE_TMP_BUFFER);
+        if (info == NULL) {
+            XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return MEMORY_E;
+        }
+    #endif
+
+        info->set      = 0;
+        info->ctx      = NULL;
+        info->consumed = 0;
+
+        ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, info, &eccKey);
+        InitDecodedCert(cert, der.buffer, der.length, cm->heap);
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+    }
+    else
+        InitDecodedCert(cert, (byte*)buff, (word32)sz, cm->heap);
+
+    if (ret == 0)
+        ret = ParseCertRelative(cert, CERT_TYPE, 1, cm);
+
+#ifdef HAVE_CRL
+    if (ret == 0 && cm->crlEnabled)
+        ret = CheckCertCRL(cm->crl, cert);
+#endif
+
+    FreeDecodedCert(cert);
+
+    XFREE(der.buffer, cm->heap, DYNAMIC_TYPE_CERT);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret == 0 ? SSL_SUCCESS : ret;
+}
+
+
+/* turn on OCSP if off and compiled in, set options */
+int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options)
+{
+    int ret = SSL_SUCCESS;
+
+    (void)options;
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSP");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    #ifdef HAVE_OCSP
+        if (cm->ocsp == NULL) {
+            cm->ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm->heap,
+                                              DYNAMIC_TYPE_OCSP);
+            if (cm->ocsp == NULL)
+                return MEMORY_E;
+
+            if (InitOCSP(cm->ocsp, cm) != 0) {
+                WOLFSSL_MSG("Init OCSP failed");
+                FreeOCSP(cm->ocsp, 1);
+                cm->ocsp = NULL;
+                return SSL_FAILURE;
+            }
+        }
+        cm->ocspEnabled = 1;
+        if (options & WOLFSSL_OCSP_URL_OVERRIDE)
+            cm->ocspUseOverrideURL = 1;
+        if (options & WOLFSSL_OCSP_NO_NONCE)
+            cm->ocspSendNonce = 0;
+        else
+            cm->ocspSendNonce = 1;
+        if (options & WOLFSSL_OCSP_CHECKALL)
+            cm->ocspCheckAll = 1;
+        #ifndef WOLFSSL_USER_IO
+            cm->ocspIOCb = EmbedOcspLookup;
+            cm->ocspRespFreeCb = EmbedOcspRespFree;
+        #endif /* WOLFSSL_USER_IO */
+    #else
+        ret = NOT_COMPILED_IN;
+    #endif
+
+    return ret;
+}
+
+
+int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSP");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    cm->ocspEnabled = 0;
+
+    return SSL_SUCCESS;
+}
+
+
+#ifdef HAVE_OCSP
+
+
+/* check CRL if enabled, SSL_SUCCESS  */
+int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
+{
+    int ret;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* cert = NULL;
+#else
+    DecodedCert  cert[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSP");
+
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    if (cm->ocspEnabled == 0)
+        return SSL_SUCCESS;
+
+#ifdef WOLFSSL_SMALL_STACK
+    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                 DYNAMIC_TYPE_TMP_BUFFER);
+    if (cert == NULL)
+        return MEMORY_E;
+#endif
+
+    InitDecodedCert(cert, der, sz, NULL);
+
+    if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) {
+        WOLFSSL_MSG("ParseCert failed");
+    }
+    else if ((ret = CheckCertOCSP(cm->ocsp, cert)) != 0) {
+        WOLFSSL_MSG("CheckCertOCSP failed");
+    }
+
+    FreeDecodedCert(cert);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret == 0 ? SSL_SUCCESS : ret;
+}
+
+
+int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER* cm,
+                                          const char* url)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSPOverrideURL");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    XFREE(cm->ocspOverrideURL, cm->heap, 0);
+    if (url != NULL) {
+        int urlSz = (int)XSTRLEN(url) + 1;
+        cm->ocspOverrideURL = (char*)XMALLOC(urlSz, cm->heap, 0);
+        if (cm->ocspOverrideURL != NULL) {
+            XMEMCPY(cm->ocspOverrideURL, url, urlSz);
+        }
+        else
+            return MEMORY_E;
+    }
+    else
+        cm->ocspOverrideURL = NULL;
+
+    return SSL_SUCCESS;
+}
+
+
+int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm,
+                        CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSP_Cb");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    cm->ocspIOCb = ioCb;
+    cm->ocspRespFreeCb = respFreeCb;
+    cm->ocspIOCtx = ioCbCtx;
+
+    return SSL_SUCCESS;
+}
+
+
+int wolfSSL_EnableOCSP(WOLFSSL* ssl, int options)
+{
+    WOLFSSL_ENTER("wolfSSL_EnableOCSP");
+    if (ssl)
+        return wolfSSL_CertManagerEnableOCSP(ssl->ctx->cm, options);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_DisableOCSP(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_DisableOCSP");
+    if (ssl)
+        return wolfSSL_CertManagerDisableOCSP(ssl->ctx->cm);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_SetOCSP_OverrideURL(WOLFSSL* ssl, const char* url)
+{
+    WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
+    if (ssl)
+        return wolfSSL_CertManagerSetOCSPOverrideURL(ssl->ctx->cm, url);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_SetOCSP_Cb(WOLFSSL* ssl,
+                        CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
+{
+    WOLFSSL_ENTER("wolfSSL_SetOCSP_Cb");
+    if (ssl)
+        return wolfSSL_CertManagerSetOCSP_Cb(ssl->ctx->cm,
+                                             ioCb, respFreeCb, ioCbCtx);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_EnableOCSP(WOLFSSL_CTX* ctx, int options)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSP");
+    if (ctx)
+        return wolfSSL_CertManagerEnableOCSP(ctx->cm, options);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_DisableOCSP(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSP");
+    if (ctx)
+        return wolfSSL_CertManagerDisableOCSP(ctx->cm);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX* ctx, const char* url)
+{
+    WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
+    if (ctx)
+        return wolfSSL_CertManagerSetOCSPOverrideURL(ctx->cm, url);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx, CbOCSPIO ioCb,
+                           CbOCSPRespFree respFreeCb, void* ioCbCtx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_SetOCSP_Cb");
+    if (ctx)
+        return wolfSSL_CertManagerSetOCSP_Cb(ctx->cm, ioCb,
+                                             respFreeCb, ioCbCtx);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+#endif /* HAVE_OCSP */
+
+
+#ifndef NO_FILESYSTEM
+
+/* process a file with name fname into ctx of format and type
+   userChain specifies a user certificate chain to pass during handshake */
+int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
+                WOLFSSL* ssl, int userChain, WOLFSSL_CRL* crl)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    byte   staticBuffer[1]; /* force heap usage */
+#else
+    byte   staticBuffer[FILE_BUFFER_SIZE];
+#endif
+    byte*  myBuffer = staticBuffer;
+    int    dynamic = 0;
+    int    ret;
+    long   sz = 0;
+    XFILE  file;
+    void*  heapHint = ctx ? ctx->heap : NULL;
+
+    (void)crl;
+    (void)heapHint;
+
+    if (fname == NULL) return SSL_BAD_FILE;
+
+    file = XFOPEN(fname, "rb");
+    if (file == XBADFILE) return SSL_BAD_FILE;
+    XFSEEK(file, 0, XSEEK_END);
+    sz = XFTELL(file);
+    XREWIND(file);
+
+    if (sz > (long)sizeof(staticBuffer)) {
+        WOLFSSL_MSG("Getting dynamic buffer");
+        myBuffer = (byte*)XMALLOC(sz, heapHint, DYNAMIC_TYPE_FILE);
+        if (myBuffer == NULL) {
+            XFCLOSE(file);
+            return SSL_BAD_FILE;
+        }
+        dynamic = 1;
+    }
+    else if (sz < 0) {
+        XFCLOSE(file);
+        return SSL_BAD_FILE;
+    }
+
+    if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
+        ret = SSL_BAD_FILE;
+    else {
+        if (type == CA_TYPE && format == SSL_FILETYPE_PEM)
+            ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl);
+#ifdef HAVE_CRL
+        else if (type == CRL_TYPE)
+            ret = BufferLoadCRL(crl, myBuffer, sz, format);
+#endif
+        else
+            ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL,
+                                userChain);
+    }
+
+    XFCLOSE(file);
+    if (dynamic)
+        XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
+
+    return ret;
+}
+
+
+/* loads file then loads each file in path, no c_rehash */
+int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
+                                     const char* path)
+{
+    int ret = SSL_SUCCESS;
+
+    WOLFSSL_ENTER("wolfSSL_CTX_load_verify_locations");
+    (void)path;
+
+    if (ctx == NULL || (file == NULL && path == NULL) )
+        return SSL_FAILURE;
+
+    if (file)
+        ret = ProcessFile(ctx, file, SSL_FILETYPE_PEM, CA_TYPE, NULL, 0, NULL);
+
+    if (ret == SSL_SUCCESS && path) {
+        /* try to load each regular file in path */
+    #ifdef USE_WINDOWS_API
+        WIN32_FIND_DATAA FindFileData;
+        HANDLE hFind;
+    #ifdef WOLFSSL_SMALL_STACK
+        char*  name = NULL;
+    #else
+        char   name[MAX_FILENAME_SZ];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (name == NULL)
+            return MEMORY_E;
+    #endif
+
+        XMEMSET(name, 0, MAX_FILENAME_SZ);
+        XSTRNCPY(name, path, MAX_FILENAME_SZ - 4);
+        XSTRNCAT(name, "\\*", 3);
+
+        hFind = FindFirstFileA(name, &FindFileData);
+        if (hFind == INVALID_HANDLE_VALUE) {
+            WOLFSSL_MSG("FindFirstFile for path verify locations failed");
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+            return BAD_PATH_ERROR;
+        }
+
+        do {
+            if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
+                XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 3);
+                XSTRNCAT(name, "\\", 2);
+                XSTRNCAT(name, FindFileData.cFileName, MAX_FILENAME_SZ/2);
+
+                ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE,
+                                  NULL, 0, NULL);
+            }
+        } while (ret == SSL_SUCCESS && FindNextFileA(hFind, &FindFileData));
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+
+        FindClose(hFind);
+    #elif !defined(NO_WOLFSSL_DIR)
+        FILINFO entry;
+        DIR    dir;
+        FRESULT ret = f_opendir(&dir, path);
+    #ifdef WOLFSSL_SMALL_STACK
+        char*  name = NULL;
+    #else
+        char   name[MAX_FILENAME_SZ];
+    #endif
+
+        if (ret != FR_OK) {
+            WOLFSSL_MSG("opendir path verify locations failed");
+            return BAD_PATH_ERROR;
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (name == NULL) {
+            f_closedir(&dir);
+            return MEMORY_E;
+        }
+    #endif
+
+        ret = SSL_SUCCESS;
+        while ( ret == SSL_SUCCESS && (f_readdir(&dir, &entry) == FR_OK) ) {
+            FILINFO s;
+
+            XMEMSET(name, 0, MAX_FILENAME_SZ);
+            XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
+            XSTRNCAT(name, "/", 1);
+            XSTRNCAT(name, entry.fname, MAX_FILENAME_SZ/2);
+
+            if (f_stat(name, &s) != FR_OK) {
+                WOLFSSL_MSG("stat on name failed");
+                ret = BAD_PATH_ERROR;
+            } else if ((s.fattrib & (AM_VOL|AM_LFN|AM_DIR)) == 0)
+                ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE,
+                                  NULL, 0, NULL);
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+
+        f_closedir(&dir);
+    #endif
+    }
+
+    return ret;
+}
+
+
+/* Verify the ceritficate, SSL_SUCCESS for ok, < 0 for error */
+int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname,
+                             int format)
+{
+    int    ret = SSL_FATAL_ERROR;
+#ifdef WOLFSSL_SMALL_STACK
+    byte   staticBuffer[1]; /* force heap usage */
+#else
+    byte   staticBuffer[FILE_BUFFER_SIZE];
+#endif
+    byte*  myBuffer = staticBuffer;
+    int    dynamic = 0;
+    long   sz = 0;
+    XFILE  file = XFOPEN(fname, "rb");
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerVerify");
+
+    if (file == XBADFILE) return SSL_BAD_FILE;
+    XFSEEK(file, 0, XSEEK_END);
+    sz = XFTELL(file);
+    XREWIND(file);
+
+    if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
+        WOLFSSL_MSG("CertManagerVerify file bad size");
+        XFCLOSE(file);
+        return SSL_BAD_FILE;
+    }
+
+    if (sz > (long)sizeof(staticBuffer)) {
+        WOLFSSL_MSG("Getting dynamic buffer");
+        myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE);
+        if (myBuffer == NULL) {
+            XFCLOSE(file);
+            return SSL_BAD_FILE;
+        }
+        dynamic = 1;
+    }
+
+    if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
+        ret = SSL_BAD_FILE;
+    else
+        ret = wolfSSL_CertManagerVerifyBuffer(cm, myBuffer, sz, format);
+
+    XFCLOSE(file);
+    if (dynamic)
+        XFREE(myBuffer, cm->heap, DYNAMIC_TYPE_FILE);
+
+    return ret;
+}
+
+
+/* like load verify locations, 1 for success, < 0 for error */
+int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file,
+                             const char* path)
+{
+    int ret = SSL_FATAL_ERROR;
+    WOLFSSL_CTX* tmp;
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCA");
+
+    if (cm == NULL) {
+        WOLFSSL_MSG("No CertManager error");
+        return ret;
+    }
+    tmp = wolfSSL_CTX_new(cm_pick_method());
+
+    if (tmp == NULL) {
+        WOLFSSL_MSG("CTX new failed");
+        return ret;
+    }
+
+    /* for tmp use */
+    wolfSSL_CertManagerFree(tmp->cm);
+    tmp->cm = cm;
+
+    ret = wolfSSL_CTX_load_verify_locations(tmp, file, path);
+
+    /* don't loose our good one */
+    tmp->cm = NULL;
+    wolfSSL_CTX_free(tmp);
+
+    return ret;
+}
+
+
+
+
+int wolfSSL_CTX_check_private_key(WOLFSSL_CTX* ctx)
+{
+    /* TODO: check private against public for RSA match */
+    (void)ctx;
+    WOLFSSL_ENTER("SSL_CTX_check_private_key");
+    return SSL_SUCCESS;
+}
+
+
+#ifdef HAVE_CRL
+
+
+/* check CRL if enabled, SSL_SUCCESS  */
+int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
+{
+    int ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* cert = NULL;
+#else
+    DecodedCert  cert[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_CertManagerCheckCRL");
+
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    if (cm->crlEnabled == 0)
+        return SSL_SUCCESS;
+
+#ifdef WOLFSSL_SMALL_STACK
+    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                 DYNAMIC_TYPE_TMP_BUFFER);
+    if (cert == NULL)
+        return MEMORY_E;
+#endif
+
+    InitDecodedCert(cert, der, sz, NULL);
+
+    if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) {
+        WOLFSSL_MSG("ParseCert failed");
+    }
+    else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) {
+        WOLFSSL_MSG("CheckCertCRL failed");
+    }
+
+    FreeDecodedCert(cert);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret == 0 ? SSL_SUCCESS : ret;
+}
+
+
+int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerSetCRL_Cb");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    cm->cbMissingCRL = cb;
+
+    return SSL_SUCCESS;
+}
+
+
+int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, const char* path,
+                              int type, int monitor)
+{
+    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRL");
+    if (cm == NULL)
+        return BAD_FUNC_ARG;
+
+    if (cm->crl == NULL) {
+        if (wolfSSL_CertManagerEnableCRL(cm, 0) != SSL_SUCCESS) {
+            WOLFSSL_MSG("Enable CRL failed");
+            return SSL_FATAL_ERROR;
+        }
+    }
+
+    return LoadCRL(cm->crl, path, type, monitor);
+}
+
+
+int wolfSSL_EnableCRL(WOLFSSL* ssl, int options)
+{
+    WOLFSSL_ENTER("wolfSSL_EnableCRL");
+    if (ssl)
+        return wolfSSL_CertManagerEnableCRL(ssl->ctx->cm, options);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_DisableCRL(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_DisableCRL");
+    if (ssl)
+        return wolfSSL_CertManagerDisableCRL(ssl->ctx->cm);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_LoadCRL(WOLFSSL* ssl, const char* path, int type, int monitor)
+{
+    WOLFSSL_ENTER("wolfSSL_LoadCRL");
+    if (ssl)
+        return wolfSSL_CertManagerLoadCRL(ssl->ctx->cm, path, type, monitor);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_SetCRL_Cb(WOLFSSL* ssl, CbMissingCRL cb)
+{
+    WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
+    if (ssl)
+        return wolfSSL_CertManagerSetCRL_Cb(ssl->ctx->cm, cb);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_EnableCRL(WOLFSSL_CTX* ctx, int options)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_EnableCRL");
+    if (ctx)
+        return wolfSSL_CertManagerEnableCRL(ctx->cm, options);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_DisableCRL(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_DisableCRL");
+    if (ctx)
+        return wolfSSL_CertManagerDisableCRL(ctx->cm);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_LoadCRL(WOLFSSL_CTX* ctx, const char* path,
+                        int type, int monitor)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_LoadCRL");
+    if (ctx)
+        return wolfSSL_CertManagerLoadCRL(ctx->cm, path, type, monitor);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX* ctx, CbMissingCRL cb)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_Cb");
+    if (ctx)
+        return wolfSSL_CertManagerSetCRL_Cb(ctx->cm, cb);
+    else
+        return BAD_FUNC_ARG;
+}
+
+
+#endif /* HAVE_CRL */
+
+
+#ifdef WOLFSSL_DER_LOAD
+
+/* Add format parameter to allow DER load of CA files */
+int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
+                                          int format)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_der_load_verify_locations");
+    if (ctx == NULL || file == NULL)
+        return SSL_FAILURE;
+
+    if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
+        return SSL_SUCCESS;
+
+    return SSL_FAILURE;
+}
+
+#endif /* WOLFSSL_DER_LOAD */
+
+
+#ifdef WOLFSSL_CERT_GEN
+
+/* load pem cert from file into der buffer, return der size or error */
+int wolfSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    EncryptedInfo* info = NULL;
+    byte   staticBuffer[1]; /* force XMALLOC */
+#else
+    EncryptedInfo info[1];
+    byte   staticBuffer[FILE_BUFFER_SIZE];
+#endif
+    byte*  fileBuf = staticBuffer;
+    int    dynamic = 0;
+    int    ret     = 0;
+    int    ecc     = 0;
+    long   sz      = 0;
+    XFILE  file    = XFOPEN(fileName, "rb");
+    buffer converted;
+
+    WOLFSSL_ENTER("wolfSSL_PemCertToDer");
+
+    if (file == XBADFILE)
+        ret = SSL_BAD_FILE;
+    else {
+        XFSEEK(file, 0, XSEEK_END);
+        sz = XFTELL(file);
+        XREWIND(file);
+
+        if (sz < 0) {
+            ret = SSL_BAD_FILE;
+        }
+        else if (sz > (long)sizeof(staticBuffer)) {
+            fileBuf = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
+            if (fileBuf == NULL)
+                ret = MEMORY_E;
+            else
+                dynamic = 1;
+        }
+
+        converted.buffer = 0;
+
+        if (ret == 0) {
+            if ( (ret = (int)XFREAD(fileBuf, sz, 1, file)) < 0)
+                ret = SSL_BAD_FILE;
+            else {
+            #ifdef WOLFSSL_SMALL_STACK
+                info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
+                                               DYNAMIC_TYPE_TMP_BUFFER);
+                if (info == NULL)
+                    ret = MEMORY_E;
+                else
+            #endif
+                {
+                    ret = PemToDer(fileBuf, sz, CA_TYPE, &converted,
+                                   0, info, &ecc);
+                #ifdef WOLFSSL_SMALL_STACK
+                    XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                #endif
+                }
+            }
+
+            if (ret == 0) {
+                if (converted.length < (word32)derSz) {
+                    XMEMCPY(derBuf, converted.buffer, converted.length);
+                    ret = converted.length;
+                }
+                else
+                    ret = BUFFER_E;
+            }
+
+            XFREE(converted.buffer, 0, DYNAMIC_TYPE_CA);
+        }
+
+        XFCLOSE(file);
+        if (dynamic)
+            XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE);
+    }
+
+    return ret;
+}
+
+#endif /* WOLFSSL_CERT_GEN */
+
+#ifdef WOLFSSL_CERT_EXT
+/* load pem public key from file into der buffer, return der size or error */
+int wolfSSL_PemPubKeyToDer(const char* fileName,
+                           unsigned char* derBuf, int derSz)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    byte   staticBuffer[1]; /* force XMALLOC */
+#else
+    byte   staticBuffer[FILE_BUFFER_SIZE];
+#endif
+    byte*  fileBuf = staticBuffer;
+    int    dynamic = 0;
+    int    ret     = 0;
+    long   sz      = 0;
+    XFILE  file    = XFOPEN(fileName, "rb");
+    buffer converted;
+
+    WOLFSSL_ENTER("wolfSSL_PemPubKeyToDer");
+
+    if (file == XBADFILE)
+        ret = SSL_BAD_FILE;
+    else {
+        XFSEEK(file, 0, XSEEK_END);
+        sz = XFTELL(file);
+        XREWIND(file);
+
+        if (sz < 0) {
+            ret = SSL_BAD_FILE;
+        }
+        else if (sz > (long)sizeof(staticBuffer)) {
+            fileBuf = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
+            if (fileBuf == NULL)
+                ret = MEMORY_E;
+            else
+                dynamic = 1;
+        }
+
+        converted.buffer = 0;
+
+        if (ret == 0) {
+            if ( (ret = (int)XFREAD(fileBuf, sz, 1, file)) < 0)
+                ret = SSL_BAD_FILE;
+            else
+                ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, &converted,
+                               0, NULL, NULL);
+
+            if (ret == 0) {
+                if (converted.length < (word32)derSz) {
+                    XMEMCPY(derBuf, converted.buffer, converted.length);
+                    ret = converted.length;
+                }
+                else
+                    ret = BUFFER_E;
+            }
+
+            XFREE(converted.buffer, 0, DYNAMIC_TYPE_CA);
+        }
+
+        XFCLOSE(file);
+        if (dynamic)
+            XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE);
+    }
+
+    return ret;
+}
+
+/* Return bytes written to buff or < 0 for error */
+int wolfSSL_PubKeyPemToDer(const unsigned char* pem, int pemSz,
+                           unsigned char* buff, int buffSz)
+{
+    int     ret;
+    buffer  der;
+
+    WOLFSSL_ENTER("wolfSSL_PubKeyPemToDer");
+
+    if (pem == NULL || buff == NULL || buffSz <= 0) {
+        WOLFSSL_MSG("Bad pem der args");
+        return BAD_FUNC_ARG;
+    }
+
+    der.buffer = NULL;
+
+    ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL);
+    if (ret < 0) {
+        WOLFSSL_MSG("Bad Pem To Der");
+    }
+    else {
+        if (der.length <= (word32)buffSz) {
+            XMEMCPY(buff, der.buffer, der.length);
+            ret = der.length;
+        }
+        else {
+            WOLFSSL_MSG("Bad der length");
+            ret = BAD_FUNC_ARG;
+        }
+    }
+
+    XFREE(der.buffer, NULL, DYNAMIC_TYPE_KEY);
+    return ret;
+}
+
+#endif /* WOLFSSL_CERT_EXT */
+
+int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
+                                     int format)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_file");
+    if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL) == SSL_SUCCESS)
+        return SSL_SUCCESS;
+
+    return SSL_FAILURE;
+}
+
+
+int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX* ctx, const char* file,
+                                    int format)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_file");
+    if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL)
+                    == SSL_SUCCESS)
+        return SSL_SUCCESS;
+
+    return SSL_FAILURE;
+}
+
+
+/* get cert chaining depth using ssl struct */
+long wolfSSL_get_verify_depth(WOLFSSL* ssl)
+{
+    if(ssl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+    return MAX_CHAIN_DEPTH;
+}
+
+
+/* get cert chaining depth using ctx struct */
+long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx)
+{
+    if(ctx == NULL) {
+        return BAD_FUNC_ARG;
+    }
+    return MAX_CHAIN_DEPTH;
+}
+
+
+int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX* ctx, const char* file)
+{
+   /* procces up to MAX_CHAIN_DEPTH plus subject cert */
+   WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file");
+   if (ProcessFile(ctx, file, SSL_FILETYPE_PEM,CERT_TYPE,NULL,1, NULL)
+                   == SSL_SUCCESS)
+       return SSL_SUCCESS;
+
+   return SSL_FAILURE;
+}
+
+
+#ifndef NO_DH
+
+/* server wrapper for ctx or ssl Diffie-Hellman parameters */
+static int wolfSSL_SetTmpDH_buffer_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
+                                           const unsigned char* buf,
+                                           long sz, int format)
+{
+    buffer der;
+    int    ret      = 0;
+    int    weOwnDer = 0;
+    word32 pSz = MAX_DH_SIZE;
+    word32 gSz = MAX_DH_SIZE;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  p = NULL;
+    byte*  g = NULL;
+#else
+    byte   p[MAX_DH_SIZE];
+    byte   g[MAX_DH_SIZE];
+#endif
+
+    der.buffer = (byte*)buf;
+    der.length = (word32)sz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (p == NULL || g == NULL) {
+        XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM)
+        ret = SSL_BAD_FILETYPE;
+    else {
+        if (format == SSL_FILETYPE_PEM) {
+            der.buffer = NULL;
+            ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap, NULL,NULL);
+            weOwnDer = 1;
+        }
+
+        if (ret == 0) {
+            if (wc_DhParamsLoad(der.buffer, der.length, p, &pSz, g, &gSz) < 0)
+                ret = SSL_BAD_FILETYPE;
+            else if (ssl)
+                ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
+            else
+                ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
+        }
+    }
+
+    if (weOwnDer)
+        XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+/* server Diffie-Hellman parameters, SSL_SUCCESS on ok */
+int wolfSSL_SetTmpDH_buffer(WOLFSSL* ssl, const unsigned char* buf, long sz,
+                           int format)
+{
+    return wolfSSL_SetTmpDH_buffer_wrapper(ssl->ctx, ssl, buf, sz, format);
+}
+
+
+/* server ctx Diffie-Hellman parameters, SSL_SUCCESS on ok */
+int wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX* ctx, const unsigned char* buf,
+                               long sz, int format)
+{
+    return wolfSSL_SetTmpDH_buffer_wrapper(ctx, NULL, buf, sz, format);
+}
+
+
+/* server Diffie-Hellman parameters */
+static int wolfSSL_SetTmpDH_file_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
+                                        const char* fname, int format)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    byte   staticBuffer[1]; /* force heap usage */
+#else
+    byte   staticBuffer[FILE_BUFFER_SIZE];
+#endif
+    byte*  myBuffer = staticBuffer;
+    int    dynamic = 0;
+    int    ret;
+    long   sz = 0;
+    XFILE  file = XFOPEN(fname, "rb");
+
+    if (file == XBADFILE) return SSL_BAD_FILE;
+    XFSEEK(file, 0, XSEEK_END);
+    sz = XFTELL(file);
+    XREWIND(file);
+
+    if (sz > (long)sizeof(staticBuffer)) {
+        WOLFSSL_MSG("Getting dynamic buffer");
+        myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
+        if (myBuffer == NULL) {
+            XFCLOSE(file);
+            return SSL_BAD_FILE;
+        }
+        dynamic = 1;
+    }
+    else if (sz < 0) {
+        XFCLOSE(file);
+        return SSL_BAD_FILE;
+    }
+
+    if ( (ret = (int)XFREAD(myBuffer, sz, 1, file)) < 0)
+        ret = SSL_BAD_FILE;
+    else {
+        if (ssl)
+            ret = wolfSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
+        else
+            ret = wolfSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format);
+    }
+
+    XFCLOSE(file);
+    if (dynamic)
+        XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
+
+    return ret;
+}
+
+/* server Diffie-Hellman parameters */
+int wolfSSL_SetTmpDH_file(WOLFSSL* ssl, const char* fname, int format)
+{
+    return wolfSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format);
+}
+
+
+/* server Diffie-Hellman parameters */
+int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format)
+{
+    return wolfSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format);
+}
+
+#endif /* NO_DH */
+
+
+#ifdef OPENSSL_EXTRA
+/* put SSL type in extra for now, not very common */
+
+int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format)
+{
+    WOLFSSL_ENTER("wolfSSL_use_certificate_file");
+    if (ProcessFile(ssl->ctx, file, format, CERT_TYPE,
+                    ssl, 0, NULL) == SSL_SUCCESS)
+        return SSL_SUCCESS;
+
+    return SSL_FAILURE;
+}
+
+
+int wolfSSL_use_PrivateKey_file(WOLFSSL* ssl, const char* file, int format)
+{
+    WOLFSSL_ENTER("wolfSSL_use_PrivateKey_file");
+    if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE,
+                    ssl, 0, NULL) == SSL_SUCCESS)
+        return SSL_SUCCESS;
+
+    return SSL_FAILURE;
+}
+
+
+int wolfSSL_use_certificate_chain_file(WOLFSSL* ssl, const char* file)
+{
+   /* procces up to MAX_CHAIN_DEPTH plus subject cert */
+   WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file");
+   if (ProcessFile(ssl->ctx, file, SSL_FILETYPE_PEM, CERT_TYPE,
+                   ssl, 1, NULL) == SSL_SUCCESS)
+       return SSL_SUCCESS;
+
+   return SSL_FAILURE;
+}
+
+
+
+#ifdef HAVE_ECC
+
+/* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
+int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX* ctx, word16 sz)
+{
+    if (ctx == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
+        return BAD_FUNC_ARG;
+
+    ctx->eccTempKeySz = sz;
+
+    return SSL_SUCCESS;
+}
+
+
+/* Set Temp SSL EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
+int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL* ssl, word16 sz)
+{
+    if (ssl == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
+        return BAD_FUNC_ARG;
+
+    ssl->eccTempKeySz = sz;
+
+    return SSL_SUCCESS;
+}
+
+#endif /* HAVE_ECC */
+
+
+
+
+int wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX* ctx,const char* file,
+                                   int format)
+{
+    WOLFSSL_ENTER("SSL_CTX_use_RSAPrivateKey_file");
+
+    return wolfSSL_CTX_use_PrivateKey_file(ctx, file, format);
+}
+
+
+int wolfSSL_use_RSAPrivateKey_file(WOLFSSL* ssl, const char* file, int format)
+{
+    WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_file");
+
+    return wolfSSL_use_PrivateKey_file(ssl, file, format);
+}
+
+#endif /* OPENSSL_EXTRA */
+
+#ifdef HAVE_NTRU
+
+int wolfSSL_CTX_use_NTRUPrivateKey_file(WOLFSSL_CTX* ctx, const char* file)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_use_NTRUPrivateKey_file");
+    if (ctx == NULL)
+        return SSL_FAILURE;
+
+    if (ProcessFile(ctx, file, SSL_FILETYPE_RAW, PRIVATEKEY_TYPE, NULL, 0, NULL)
+                         == SSL_SUCCESS) {
+        ctx->haveNTRU = 1;
+        return SSL_SUCCESS;
+    }
+
+    return SSL_FAILURE;
+}
+
+#endif /* HAVE_NTRU */
+
+
+#endif /* NO_FILESYSTEM */
+
+
+void wolfSSL_CTX_set_verify(WOLFSSL_CTX* ctx, int mode, VerifyCallback vc)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_verify");
+    if (mode & SSL_VERIFY_PEER) {
+        ctx->verifyPeer = 1;
+        ctx->verifyNone = 0;  /* in case perviously set */
+    }
+
+    if (mode == SSL_VERIFY_NONE) {
+        ctx->verifyNone = 1;
+        ctx->verifyPeer = 0;  /* in case previously set */
+    }
+
+    if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
+        ctx->failNoCert = 1;
+
+    ctx->verifyCallback = vc;
+}
+
+
+void wolfSSL_set_verify(WOLFSSL* ssl, int mode, VerifyCallback vc)
+{
+    WOLFSSL_ENTER("wolfSSL_set_verify");
+    if (mode & SSL_VERIFY_PEER) {
+        ssl->options.verifyPeer = 1;
+        ssl->options.verifyNone = 0;  /* in case perviously set */
+    }
+
+    if (mode == SSL_VERIFY_NONE) {
+        ssl->options.verifyNone = 1;
+        ssl->options.verifyPeer = 0;  /* in case previously set */
+    }
+
+    if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
+        ssl->options.failNoCert = 1;
+
+    ssl->verifyCallback = vc;
+}
+
+
+/* store user ctx for verify callback */
+void wolfSSL_SetCertCbCtx(WOLFSSL* ssl, void* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_SetCertCbCtx");
+    if (ssl)
+        ssl->verifyCbCtx = ctx;
+}
+
+
+/* store context CA Cache addition callback */
+void wolfSSL_CTX_SetCACb(WOLFSSL_CTX* ctx, CallbackCACache cb)
+{
+    if (ctx && ctx->cm)
+        ctx->cm->caCacheCallback = cb;
+}
+
+
+#if defined(PERSIST_CERT_CACHE)
+
+#if !defined(NO_FILESYSTEM)
+
+/* Persist cert cache to file */
+int wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_save_cert_cache");
+
+    if (ctx == NULL || fname == NULL)
+        return BAD_FUNC_ARG;
+
+    return CM_SaveCertCache(ctx->cm, fname);
+}
+
+
+/* Persist cert cache from file */
+int wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_restore_cert_cache");
+
+    if (ctx == NULL || fname == NULL)
+        return BAD_FUNC_ARG;
+
+    return CM_RestoreCertCache(ctx->cm, fname);
+}
+
+#endif /* NO_FILESYSTEM */
+
+/* Persist cert cache to memory */
+int wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX* ctx, void* mem,
+                                   int sz, int* used)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_memsave_cert_cache");
+
+    if (ctx == NULL || mem == NULL || used == NULL || sz <= 0)
+        return BAD_FUNC_ARG;
+
+    return CM_MemSaveCertCache(ctx->cm, mem, sz, used);
+}
+
+
+/* Restore cert cache from memory */
+int wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX* ctx, const void* mem, int sz)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_memrestore_cert_cache");
+
+    if (ctx == NULL || mem == NULL || sz <= 0)
+        return BAD_FUNC_ARG;
+
+    return CM_MemRestoreCertCache(ctx->cm, mem, sz);
+}
+
+
+/* get how big the the cert cache save buffer needs to be */
+int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_get_cert_cache_memsize");
+
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    return CM_GetCertCacheMemSize(ctx->cm);
+}
+
+#endif /* PERSISTE_CERT_CACHE */
+#endif /* !NO_CERTS */
+
+
+#ifndef NO_SESSION_CACHE
+
+WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_get_session");
+    if (ssl)
+        return GetSession(ssl, 0);
+
+    return NULL;
+}
+
+
+int wolfSSL_set_session(WOLFSSL* ssl, WOLFSSL_SESSION* session)
+{
+    WOLFSSL_ENTER("SSL_set_session");
+    if (session)
+        return SetSession(ssl, session);
+
+    return SSL_FAILURE;
+}
+
+
+#ifndef NO_CLIENT_CACHE
+
+/* Associate client session with serverID, find existing or store for saving
+   if newSession flag on, don't reuse existing session
+   SSL_SUCCESS on ok */
+int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
+{
+    WOLFSSL_SESSION* session = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_SetServerID");
+
+    if (ssl == NULL || id == NULL || len <= 0)
+        return BAD_FUNC_ARG;
+
+    if (newSession == 0) {
+        session = GetSessionClient(ssl, id, len);
+        if (session) {
+            if (SetSession(ssl, session) != SSL_SUCCESS) {
+                WOLFSSL_MSG("SetSession failed");
+                session = NULL;
+            }
+        }
+    }
+
+    if (session == NULL) {
+        WOLFSSL_MSG("Valid ServerID not cached already");
+
+        ssl->session.idLen = (word16)min(SERVER_ID_LEN, (word32)len);
+        XMEMCPY(ssl->session.serverID, id, ssl->session.idLen);
+    }
+
+    return SSL_SUCCESS;
+}
+
+#endif /* NO_CLIENT_CACHE */
+
+#if defined(PERSIST_SESSION_CACHE)
+
+/* for persistance, if changes to layout need to increment and modify
+   save_session_cache() and restore_session_cache and memory versions too */
+#define WOLFSSL_CACHE_VERSION 2
+
+/* Session Cache Header information */
+typedef struct {
+    int version;     /* cache layout version id */
+    int rows;        /* session rows */
+    int columns;     /* session columns */
+    int sessionSz;   /* sizeof WOLFSSL_SESSION */
+} cache_header_t;
+
+/* current persistence layout is:
+
+   1) cache_header_t
+   2) SessionCache
+   3) ClientCache
+
+   update WOLFSSL_CACHE_VERSION if change layout for the following
+   PERSISTENT_SESSION_CACHE functions
+*/
+
+
+/* get how big the the session cache save buffer needs to be */
+int wolfSSL_get_session_cache_memsize(void)
+{
+    int sz  = (int)(sizeof(SessionCache) + sizeof(cache_header_t));
+
+    #ifndef NO_CLIENT_CACHE
+        sz += (int)(sizeof(ClientCache));
+    #endif
+
+    return sz;
+}
+
+
+/* Persist session cache to memory */
+int wolfSSL_memsave_session_cache(void* mem, int sz)
+{
+    int i;
+    cache_header_t cache_header;
+    SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
+#ifndef NO_CLIENT_CACHE
+    ClientRow*     clRow;
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_memsave_session_cache");
+
+    if (sz < wolfSSL_get_session_cache_memsize()) {
+        WOLFSSL_MSG("Memory buffer too small");
+        return BUFFER_E;
+    }
+
+    cache_header.version   = WOLFSSL_CACHE_VERSION;
+    cache_header.rows      = SESSION_ROWS;
+    cache_header.columns   = SESSIONS_PER_ROW;
+    cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
+    XMEMCPY(mem, &cache_header, sizeof(cache_header));
+
+    if (LockMutex(&session_mutex) != 0) {
+        WOLFSSL_MSG("Session cache mutex lock failed");
+        return BAD_MUTEX_E;
+    }
+
+    for (i = 0; i < cache_header.rows; ++i)
+        XMEMCPY(row++, SessionCache + i, sizeof(SessionRow));
+
+#ifndef NO_CLIENT_CACHE
+    clRow = (ClientRow*)row;
+    for (i = 0; i < cache_header.rows; ++i)
+        XMEMCPY(clRow++, ClientCache + i, sizeof(ClientRow));
+#endif
+
+    UnLockMutex(&session_mutex);
+
+    WOLFSSL_LEAVE("wolfSSL_memsave_session_cache", SSL_SUCCESS);
+
+    return SSL_SUCCESS;
+}
+
+
+/* Restore the persistant session cache from memory */
+int wolfSSL_memrestore_session_cache(const void* mem, int sz)
+{
+    int    i;
+    cache_header_t cache_header;
+    SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
+#ifndef NO_CLIENT_CACHE
+    ClientRow*     clRow;
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_memrestore_session_cache");
+
+    if (sz < wolfSSL_get_session_cache_memsize()) {
+        WOLFSSL_MSG("Memory buffer too small");
+        return BUFFER_E;
+    }
+
+    XMEMCPY(&cache_header, mem, sizeof(cache_header));
+    if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
+        cache_header.rows      != SESSION_ROWS ||
+        cache_header.columns   != SESSIONS_PER_ROW ||
+        cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
+
+        WOLFSSL_MSG("Session cache header match failed");
+        return CACHE_MATCH_ERROR;
+    }
+
+    if (LockMutex(&session_mutex) != 0) {
+        WOLFSSL_MSG("Session cache mutex lock failed");
+        return BAD_MUTEX_E;
+    }
+
+    for (i = 0; i < cache_header.rows; ++i)
+        XMEMCPY(SessionCache + i, row++, sizeof(SessionRow));
+
+#ifndef NO_CLIENT_CACHE
+    clRow = (ClientRow*)row;
+    for (i = 0; i < cache_header.rows; ++i)
+        XMEMCPY(ClientCache + i, clRow++, sizeof(ClientRow));
+#endif
+
+    UnLockMutex(&session_mutex);
+
+    WOLFSSL_LEAVE("wolfSSL_memrestore_session_cache", SSL_SUCCESS);
+
+    return SSL_SUCCESS;
+}
+
+#if !defined(NO_FILESYSTEM)
+
+/* Persist session cache to file */
+/* doesn't use memsave because of additional memory use */
+int wolfSSL_save_session_cache(const char *fname)
+{
+    XFILE  file;
+    int    ret;
+    int    rc = SSL_SUCCESS;
+    int    i;
+    cache_header_t cache_header;
+
+    WOLFSSL_ENTER("wolfSSL_save_session_cache");
+
+    file = XFOPEN(fname, "w+b");
+    if (file == XBADFILE) {
+        WOLFSSL_MSG("Couldn't open session cache save file");
+        return SSL_BAD_FILE;
+    }
+    cache_header.version   = WOLFSSL_CACHE_VERSION;
+    cache_header.rows      = SESSION_ROWS;
+    cache_header.columns   = SESSIONS_PER_ROW;
+    cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
+
+    /* cache header */
+    ret = (int)XFWRITE(&cache_header, sizeof cache_header, 1, file);
+    if (ret != 1) {
+        WOLFSSL_MSG("Session cache header file write failed");
+        XFCLOSE(file);
+        return FWRITE_ERROR;
+    }
+
+    if (LockMutex(&session_mutex) != 0) {
+        WOLFSSL_MSG("Session cache mutex lock failed");
+        XFCLOSE(file);
+        return BAD_MUTEX_E;
+    }
+
+    /* session cache */
+    for (i = 0; i < cache_header.rows; ++i) {
+        ret = (int)XFWRITE(SessionCache + i, sizeof(SessionRow), 1, file);
+        if (ret != 1) {
+            WOLFSSL_MSG("Session cache member file write failed");
+            rc = FWRITE_ERROR;
+            break;
+        }
+    }
+
+#ifndef NO_CLIENT_CACHE
+    /* client cache */
+    for (i = 0; i < cache_header.rows; ++i) {
+        ret = (int)XFWRITE(ClientCache + i, sizeof(ClientRow), 1, file);
+        if (ret != 1) {
+            WOLFSSL_MSG("Client cache member file write failed");
+            rc = FWRITE_ERROR;
+            break;
+        }
+    }
+#endif /* NO_CLIENT_CACHE */
+
+    UnLockMutex(&session_mutex);
+
+    XFCLOSE(file);
+    WOLFSSL_LEAVE("wolfSSL_save_session_cache", rc);
+
+    return rc;
+}
+
+
+/* Restore the persistant session cache from file */
+/* doesn't use memstore because of additional memory use */
+int wolfSSL_restore_session_cache(const char *fname)
+{
+    XFILE  file;
+    int    rc = SSL_SUCCESS;
+    int    ret;
+    int    i;
+    cache_header_t cache_header;
+
+    WOLFSSL_ENTER("wolfSSL_restore_session_cache");
+
+    file = XFOPEN(fname, "rb");
+    if (file == XBADFILE) {
+        WOLFSSL_MSG("Couldn't open session cache save file");
+        return SSL_BAD_FILE;
+    }
+    /* cache header */
+    ret = (int)XFREAD(&cache_header, sizeof cache_header, 1, file);
+    if (ret != 1) {
+        WOLFSSL_MSG("Session cache header file read failed");
+        XFCLOSE(file);
+        return FREAD_ERROR;
+    }
+    if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
+        cache_header.rows      != SESSION_ROWS ||
+        cache_header.columns   != SESSIONS_PER_ROW ||
+        cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
+
+        WOLFSSL_MSG("Session cache header match failed");
+        XFCLOSE(file);
+        return CACHE_MATCH_ERROR;
+    }
+
+    if (LockMutex(&session_mutex) != 0) {
+        WOLFSSL_MSG("Session cache mutex lock failed");
+        XFCLOSE(file);
+        return BAD_MUTEX_E;
+    }
+
+    /* session cache */
+    for (i = 0; i < cache_header.rows; ++i) {
+        ret = (int)XFREAD(SessionCache + i, sizeof(SessionRow), 1, file);
+        if (ret != 1) {
+            WOLFSSL_MSG("Session cache member file read failed");
+            XMEMSET(SessionCache, 0, sizeof SessionCache);
+            rc = FREAD_ERROR;
+            break;
+        }
+    }
+
+#ifndef NO_CLIENT_CACHE
+    /* client cache */
+    for (i = 0; i < cache_header.rows; ++i) {
+        ret = (int)XFREAD(ClientCache + i, sizeof(ClientRow), 1, file);
+        if (ret != 1) {
+            WOLFSSL_MSG("Client cache member file read failed");
+            XMEMSET(ClientCache, 0, sizeof ClientCache);
+            rc = FREAD_ERROR;
+            break;
+        }
+    }
+
+#endif /* NO_CLIENT_CACHE */
+
+    UnLockMutex(&session_mutex);
+
+    XFCLOSE(file);
+    WOLFSSL_LEAVE("wolfSSL_restore_session_cache", rc);
+
+    return rc;
+}
+
+#endif /* !NO_FILESYSTEM */
+#endif /* PERSIST_SESSION_CACHE */
+#endif /* NO_SESSION_CACHE */
+
+
+void wolfSSL_load_error_strings(void)   /* compatibility only */
+{}
+
+
+int wolfSSL_library_init(void)
+{
+    WOLFSSL_ENTER("SSL_library_init");
+    if (wolfSSL_Init() == SSL_SUCCESS)
+        return SSL_SUCCESS;
+    else
+        return SSL_FATAL_ERROR;
+}
+
+
+#ifdef HAVE_SECRET_CALLBACK
+
+int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_set_session_secret_cb");
+    if (ssl == NULL)
+        return SSL_FATAL_ERROR;
+
+    ssl->sessionSecretCb = cb;
+    ssl->sessionSecretCtx = ctx;
+    /* If using a pre-set key, assume session resumption. */
+    ssl->session.sessionIDSz = 0;
+    ssl->options.resuming = 1;
+
+    return SSL_SUCCESS;
+}
+
+#endif
+
+
+#ifndef NO_SESSION_CACHE
+
+/* on by default if built in but allow user to turn off */
+long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX* ctx, long mode)
+{
+    WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
+    if (mode == SSL_SESS_CACHE_OFF)
+        ctx->sessionCacheOff = 1;
+
+    if (mode == SSL_SESS_CACHE_NO_AUTO_CLEAR)
+        ctx->sessionCacheFlushOff = 1;
+
+    return SSL_SUCCESS;
+}
+
+#endif /* NO_SESSION_CACHE */
+
+
+#if !defined(NO_CERTS)
+#if defined(PERSIST_CERT_CACHE)
+
+
+#define WOLFSSL_CACHE_CERT_VERSION 1
+
+typedef struct {
+    int version;                 /* cache cert layout version id */
+    int rows;                    /* hash table rows, CA_TABLE_SIZE */
+    int columns[CA_TABLE_SIZE];  /* columns per row on list */
+    int signerSz;                /* sizeof Signer object */
+} CertCacheHeader;
+
+/* current cert persistance layout is:
+
+   1) CertCacheHeader
+   2) caTable
+
+   update WOLFSSL_CERT_CACHE_VERSION if change layout for the following
+   PERSIST_CERT_CACHE functions
+*/
+
+
+/* Return memory needed to persist this signer, have lock */
+static INLINE int GetSignerMemory(Signer* signer)
+{
+    int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID)
+           + sizeof(signer->nameLen)    + sizeof(signer->subjectNameHash);
+
+#if !defined(NO_SKID)
+        sz += (int)sizeof(signer->subjectKeyIdHash);
+#endif
+
+    /* add dynamic bytes needed */
+    sz += signer->pubKeySize;
+    sz += signer->nameLen;
+
+    return sz;
+}
+
+
+/* Return memory needed to persist this row, have lock */
+static INLINE int GetCertCacheRowMemory(Signer* row)
+{
+    int sz = 0;
+
+    while (row) {
+        sz += GetSignerMemory(row);
+        row = row->next;
+    }
+
+    return sz;
+}
+
+
+/* get the size of persist cert cache, have lock */
+static INLINE int GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
+{
+    int sz;
+    int i;
+
+    sz = sizeof(CertCacheHeader);
+
+    for (i = 0; i < CA_TABLE_SIZE; i++)
+        sz += GetCertCacheRowMemory(cm->caTable[i]);
+
+    return sz;
+}
+
+
+/* Store cert cache header columns with number of items per list, have lock */
+static INLINE void SetCertHeaderColumns(WOLFSSL_CERT_MANAGER* cm, int* columns)
+{
+    int     i;
+    Signer* row;
+
+    for (i = 0; i < CA_TABLE_SIZE; i++) {
+        int count = 0;
+        row = cm->caTable[i];
+
+        while (row) {
+            ++count;
+            row = row->next;
+        }
+        columns[i] = count;
+    }
+}
+
+
+/* Restore whole cert row from memory, have lock, return bytes consumed,
+   < 0 on error, have lock */
+static INLINE int RestoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current,
+                                 int row, int listSz, const byte* end)
+{
+    int idx = 0;
+
+    if (listSz < 0) {
+        WOLFSSL_MSG("Row header corrupted, negative value");
+        return PARSE_ERROR;
+    }
+
+    while (listSz) {
+        Signer* signer;
+        byte*   start = current + idx;  /* for end checks on this signer */
+        int     minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) +
+                      sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
+        #ifndef NO_SKID
+                minSz += (int)sizeof(signer->subjectKeyIdHash);
+        #endif
+
+        if (start + minSz > end) {
+            WOLFSSL_MSG("Would overread restore buffer");
+            return BUFFER_E;
+        }
+        signer = MakeSigner(cm->heap);
+        if (signer == NULL)
+            return MEMORY_E;
+
+        /* pubKeySize */
+        XMEMCPY(&signer->pubKeySize, current + idx, sizeof(signer->pubKeySize));
+        idx += (int)sizeof(signer->pubKeySize);
+
+        /* keyOID */
+        XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID));
+        idx += (int)sizeof(signer->keyOID);
+
+        /* pulicKey */
+        if (start + minSz + signer->pubKeySize > end) {
+            WOLFSSL_MSG("Would overread restore buffer");
+            FreeSigner(signer, cm->heap);
+            return BUFFER_E;
+        }
+        signer->publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap,
+                                           DYNAMIC_TYPE_KEY);
+        if (signer->publicKey == NULL) {
+            FreeSigner(signer, cm->heap);
+            return MEMORY_E;
+        }
+
+        XMEMCPY(signer->publicKey, current + idx, signer->pubKeySize);
+        idx += signer->pubKeySize;
+
+        /* nameLen */
+        XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen));
+        idx += (int)sizeof(signer->nameLen);
+
+        /* name */
+        if (start + minSz + signer->pubKeySize + signer->nameLen > end) {
+            WOLFSSL_MSG("Would overread restore buffer");
+            FreeSigner(signer, cm->heap);
+            return BUFFER_E;
+        }
+        signer->name = (char*)XMALLOC(signer->nameLen, cm->heap,
+                                      DYNAMIC_TYPE_SUBJECT_CN);
+        if (signer->name == NULL) {
+            FreeSigner(signer, cm->heap);
+            return MEMORY_E;
+        }
+
+        XMEMCPY(signer->name, current + idx, signer->nameLen);
+        idx += signer->nameLen;
+
+        /* subjectNameHash */
+        XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE);
+        idx += SIGNER_DIGEST_SIZE;
+
+        #ifndef NO_SKID
+            /* subjectKeyIdHash */
+            XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE);
+            idx += SIGNER_DIGEST_SIZE;
+        #endif
+
+        signer->next = cm->caTable[row];
+        cm->caTable[row] = signer;
+
+        --listSz;
+    }
+
+    return idx;
+}
+
+
+/* Store whole cert row into memory, have lock, return bytes added */
+static INLINE int StoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current, int row)
+{
+    int     added  = 0;
+    Signer* list   = cm->caTable[row];
+
+    while (list) {
+        XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize));
+        added += (int)sizeof(list->pubKeySize);
+
+        XMEMCPY(current + added, &list->keyOID,     sizeof(list->keyOID));
+        added += (int)sizeof(list->keyOID);
+
+        XMEMCPY(current + added, list->publicKey, list->pubKeySize);
+        added += list->pubKeySize;
+
+        XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen));
+        added += (int)sizeof(list->nameLen);
+
+        XMEMCPY(current + added, list->name, list->nameLen);
+        added += list->nameLen;
+
+        XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE);
+        added += SIGNER_DIGEST_SIZE;
+
+        #ifndef NO_SKID
+            XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE);
+            added += SIGNER_DIGEST_SIZE;
+        #endif
+
+        list = list->next;
+    }
+
+    return added;
+}
+
+
+/* Persist cert cache to memory, have lock */
+static INLINE int DoMemSaveCertCache(WOLFSSL_CERT_MANAGER* cm,
+                                     void* mem, int sz)
+{
+    int realSz;
+    int ret = SSL_SUCCESS;
+    int i;
+
+    WOLFSSL_ENTER("DoMemSaveCertCache");
+
+    realSz = GetCertCacheMemSize(cm);
+    if (realSz > sz) {
+        WOLFSSL_MSG("Mem output buffer too small");
+        ret = BUFFER_E;
+    }
+    else {
+        byte*           current;
+        CertCacheHeader hdr;
+
+        hdr.version  = WOLFSSL_CACHE_CERT_VERSION;
+        hdr.rows     = CA_TABLE_SIZE;
+        SetCertHeaderColumns(cm, hdr.columns);
+        hdr.signerSz = (int)sizeof(Signer);
+
+        XMEMCPY(mem, &hdr, sizeof(CertCacheHeader));
+        current = (byte*)mem + sizeof(CertCacheHeader);
+
+        for (i = 0; i < CA_TABLE_SIZE; ++i)
+            current += StoreCertRow(cm, current, i);
+    }
+
+    return ret;
+}
+
+
+#if !defined(NO_FILESYSTEM)
+
+/* Persist cert cache to file */
+int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
+{
+    XFILE file;
+    int   rc = SSL_SUCCESS;
+    int   memSz;
+    byte* mem;
+
+    WOLFSSL_ENTER("CM_SaveCertCache");
+
+    file = XFOPEN(fname, "w+b");
+    if (file == XBADFILE) {
+       WOLFSSL_MSG("Couldn't open cert cache save file");
+       return SSL_BAD_FILE;
+    }
+
+    if (LockMutex(&cm->caLock) != 0) {
+        WOLFSSL_MSG("LockMutex on caLock failed");
+        XFCLOSE(file);
+        return BAD_MUTEX_E;
+    }
+
+    memSz = GetCertCacheMemSize(cm);
+    mem   = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (mem == NULL) {
+        WOLFSSL_MSG("Alloc for tmp buffer failed");
+        rc = MEMORY_E;
+    } else {
+        rc = DoMemSaveCertCache(cm, mem, memSz);
+        if (rc == SSL_SUCCESS) {
+            int ret = (int)XFWRITE(mem, memSz, 1, file);
+            if (ret != 1) {
+                WOLFSSL_MSG("Cert cache file write failed");
+                rc = FWRITE_ERROR;
+            }
+        }
+        XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+
+    UnLockMutex(&cm->caLock);
+    XFCLOSE(file);
+
+    return rc;
+}
+
+
+/* Restore cert cache from file */
+int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
+{
+    XFILE file;
+    int   rc = SSL_SUCCESS;
+    int   ret;
+    int   memSz;
+    byte* mem;
+
+    WOLFSSL_ENTER("CM_RestoreCertCache");
+
+    file = XFOPEN(fname, "rb");
+    if (file == XBADFILE) {
+       WOLFSSL_MSG("Couldn't open cert cache save file");
+       return SSL_BAD_FILE;
+    }
+
+    XFSEEK(file, 0, XSEEK_END);
+    memSz = (int)XFTELL(file);
+    XREWIND(file);
+
+    if (memSz <= 0) {
+        WOLFSSL_MSG("Bad file size");
+        XFCLOSE(file);
+        return SSL_BAD_FILE;
+    }
+
+    mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (mem == NULL) {
+        WOLFSSL_MSG("Alloc for tmp buffer failed");
+        XFCLOSE(file);
+        return MEMORY_E;
+    }
+
+    ret = (int)XFREAD(mem, memSz, 1, file);
+    if (ret != 1) {
+        WOLFSSL_MSG("Cert file read error");
+        rc = FREAD_ERROR;
+    } else {
+        rc = CM_MemRestoreCertCache(cm, mem, memSz);
+        if (rc != SSL_SUCCESS) {
+            WOLFSSL_MSG("Mem restore cert cache failed");
+        }
+    }
+
+    XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    XFCLOSE(file);
+
+    return rc;
+}
+
+#endif /* NO_FILESYSTEM */
+
+
+/* Persist cert cache to memory */
+int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz, int* used)
+{
+    int ret = SSL_SUCCESS;
+
+    WOLFSSL_ENTER("CM_MemSaveCertCache");
+
+    if (LockMutex(&cm->caLock) != 0) {
+        WOLFSSL_MSG("LockMutex on caLock failed");
+        return BAD_MUTEX_E;
+    }
+
+    ret = DoMemSaveCertCache(cm, mem, sz);
+    if (ret == SSL_SUCCESS)
+        *used  = GetCertCacheMemSize(cm);
+
+    UnLockMutex(&cm->caLock);
+
+    return ret;
+}
+
+
+/* Restore cert cache from memory */
+int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const void* mem, int sz)
+{
+    int ret = SSL_SUCCESS;
+    int i;
+    CertCacheHeader* hdr = (CertCacheHeader*)mem;
+    byte*            current = (byte*)mem + sizeof(CertCacheHeader);
+    byte*            end     = (byte*)mem + sz;  /* don't go over */
+
+    WOLFSSL_ENTER("CM_MemRestoreCertCache");
+
+    if (current > end) {
+        WOLFSSL_MSG("Cert Cache Memory buffer too small");
+        return BUFFER_E;
+    }
+
+    if (hdr->version  != WOLFSSL_CACHE_CERT_VERSION ||
+        hdr->rows     != CA_TABLE_SIZE ||
+        hdr->signerSz != (int)sizeof(Signer)) {
+
+        WOLFSSL_MSG("Cert Cache Memory header mismatch");
+        return CACHE_MATCH_ERROR;
+    }
+
+    if (LockMutex(&cm->caLock) != 0) {
+        WOLFSSL_MSG("LockMutex on caLock failed");
+        return BAD_MUTEX_E;
+    }
+
+    FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
+
+    for (i = 0; i < CA_TABLE_SIZE; ++i) {
+        int added = RestoreCertRow(cm, current, i, hdr->columns[i], end);
+        if (added < 0) {
+            WOLFSSL_MSG("RestoreCertRow error");
+            ret = added;
+            break;
+        }
+        current += added;
+    }
+
+    UnLockMutex(&cm->caLock);
+
+    return ret;
+}
+
+
+/* get how big the the cert cache save buffer needs to be */
+int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
+{
+    int sz;
+
+    WOLFSSL_ENTER("CM_GetCertCacheMemSize");
+
+    if (LockMutex(&cm->caLock) != 0) {
+        WOLFSSL_MSG("LockMutex on caLock failed");
+        return BAD_MUTEX_E;
+    }
+
+    sz = GetCertCacheMemSize(cm);
+
+    UnLockMutex(&cm->caLock);
+
+    return sz;
+}
+
+#endif /* PERSIST_CERT_CACHE */
+#endif /* NO_CERTS */
+
+
+int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list");
+
+    /* alloc/init on demand only */
+    if (ctx->suites == NULL) {
+        ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap,
+                                       DYNAMIC_TYPE_SUITES);
+        if (ctx->suites == NULL) {
+            WOLFSSL_MSG("Memory alloc for Suites failed");
+            return SSL_FAILURE;
+        }
+        XMEMSET(ctx->suites, 0, sizeof(Suites));
+    }
+
+    return (SetCipherList(ctx->suites, list)) ? SSL_SUCCESS : SSL_FAILURE;
+}
+
+
+int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list)
+{
+    WOLFSSL_ENTER("wolfSSL_set_cipher_list");
+    return (SetCipherList(ssl->suites, list)) ? SSL_SUCCESS : SSL_FAILURE;
+}
+
+
+#ifndef WOLFSSL_LEANPSK
+#ifdef WOLFSSL_DTLS
+
+int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
+{
+    (void)ssl;
+
+    return ssl->dtls_timeout;
+}
+
+
+/* user may need to alter init dtls recv timeout, SSL_SUCCESS on ok */
+int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int timeout)
+{
+    if (ssl == NULL || timeout < 0)
+        return BAD_FUNC_ARG;
+
+    if (timeout > ssl->dtls_timeout_max) {
+        WOLFSSL_MSG("Can't set dtls timeout init greater than dtls timeout max");
+        return BAD_FUNC_ARG;
+    }
+
+    ssl->dtls_timeout_init = timeout;
+    ssl->dtls_timeout = timeout;
+
+    return SSL_SUCCESS;
+}
+
+
+/* user may need to alter max dtls recv timeout, SSL_SUCCESS on ok */
+int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int timeout)
+{
+    if (ssl == NULL || timeout < 0)
+        return BAD_FUNC_ARG;
+
+    if (timeout < ssl->dtls_timeout_init) {
+        WOLFSSL_MSG("Can't set dtls timeout max less than dtls timeout init");
+        return BAD_FUNC_ARG;
+    }
+
+    ssl->dtls_timeout_max = timeout;
+
+    return SSL_SUCCESS;
+}
+
+
+int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
+{
+    int result = SSL_SUCCESS;
+
+    DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
+    ssl->dtls_msg_list = NULL;
+    if (DtlsPoolTimeout(ssl) < 0 || DtlsPoolSend(ssl) < 0) {
+        result = SSL_FATAL_ERROR;
+    }
+    return result;
+}
+
+#endif /* DTLS */
+#endif /* LEANPSK */
+
+
+#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
+
+/* Not an SSL function, return 0 for success, error code otherwise */
+/* Prereq: ssl's RNG needs to be initialized. */
+int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
+                                 const byte* secret, word32 secretSz)
+{
+    WOLFSSL_ENTER("wolfSSL_DTLS_SetCookieSecret");
+
+    if (ssl == NULL) {
+        WOLFSSL_MSG("need a SSL object");
+        return BAD_FUNC_ARG;
+    }
+
+    if (secret != NULL && secretSz == 0) {
+        WOLFSSL_MSG("can't have a new secret without a size");
+        return BAD_FUNC_ARG;
+    }
+
+    /* If secretSz is 0, use the default size. */
+    if (secretSz == 0)
+        secretSz = COOKIE_SECRET_SZ;
+
+    if (secretSz != ssl->buffers.dtlsCookieSecret.length) {
+        byte* newSecret;
+
+        if (ssl->buffers.dtlsCookieSecret.buffer != NULL) {
+            ForceZero(ssl->buffers.dtlsCookieSecret.buffer,
+                      ssl->buffers.dtlsCookieSecret.length);
+            XFREE(ssl->buffers.dtlsCookieSecret.buffer,
+                  ssl->heap, DYNAMIC_TYPE_NONE);
+        }
+
+        newSecret = (byte*)XMALLOC(secretSz, ssl->heap,DYNAMIC_TYPE_COOKIE_PWD);
+        if (newSecret == NULL) {
+            ssl->buffers.dtlsCookieSecret.buffer = NULL;
+            ssl->buffers.dtlsCookieSecret.length = 0;
+            WOLFSSL_MSG("couldn't allocate new cookie secret");
+            return MEMORY_ERROR;
+        }
+        ssl->buffers.dtlsCookieSecret.buffer = newSecret;
+        ssl->buffers.dtlsCookieSecret.length = secretSz;
+    }
+
+    /* If the supplied secret is NULL, randomly generate a new secret. */
+    if (secret == NULL)
+        wc_RNG_GenerateBlock(ssl->rng,
+                             ssl->buffers.dtlsCookieSecret.buffer, secretSz);
+    else
+        XMEMCPY(ssl->buffers.dtlsCookieSecret.buffer, secret, secretSz);
+
+    WOLFSSL_LEAVE("wolfSSL_DTLS_SetCookieSecret", 0);
+    return 0;
+}
+
+#endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
+
+
+/* client only parts */
+#ifndef NO_WOLFSSL_CLIENT
+
+    #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
+    WOLFSSL_METHOD* wolfSSLv3_client_method(void)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                        0, DYNAMIC_TYPE_METHOD);
+        WOLFSSL_ENTER("SSLv3_client_method");
+        if (method)
+            InitSSL_Method(method, MakeSSLv3());
+        return method;
+    }
+    #endif
+
+    #ifdef WOLFSSL_DTLS
+
+        #ifndef NO_OLD_TLS
+        WOLFSSL_METHOD* wolfDTLSv1_client_method(void)
+        {
+            WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                        0, DYNAMIC_TYPE_METHOD);
+            WOLFSSL_ENTER("DTLSv1_client_method");
+            if (method)
+                InitSSL_Method(method, MakeDTLSv1());
+            return method;
+        }
+        #endif  /* NO_OLD_TLS */
+
+        WOLFSSL_METHOD* wolfDTLSv1_2_client_method(void)
+        {
+            WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                        0, DYNAMIC_TYPE_METHOD);
+            WOLFSSL_ENTER("DTLSv1_2_client_method");
+            if (method)
+                InitSSL_Method(method, MakeDTLSv1_2());
+            return method;
+        }
+    #endif
+
+
+    /* please see note at top of README if you get an error from connect */
+    int wolfSSL_connect(WOLFSSL* ssl)
+    {
+        int neededState;
+
+        WOLFSSL_ENTER("SSL_connect()");
+
+        #ifdef HAVE_ERRNO_H
+            errno = 0;
+        #endif
+
+        if (ssl->options.side != WOLFSSL_CLIENT_END) {
+            WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
+            return SSL_FATAL_ERROR;
+        }
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->version.major == DTLS_MAJOR) {
+                ssl->options.dtls   = 1;
+                ssl->options.tls    = 1;
+                ssl->options.tls1_1 = 1;
+
+                if (DtlsPoolInit(ssl) != 0) {
+                    ssl->error = MEMORY_ERROR;
+                    WOLFSSL_ERROR(ssl->error);
+                    return SSL_FATAL_ERROR;
+                }
+            }
+        #endif
+
+        if (ssl->buffers.outputBuffer.length > 0) {
+            if ( (ssl->error = SendBuffered(ssl)) == 0) {
+                if (ssl->fragOffset == 0) {
+                    ssl->options.connectState++;
+                    WOLFSSL_MSG("connect state: Advanced from buffered send");
+                }
+            }
+            else {
+                WOLFSSL_ERROR(ssl->error);
+                return SSL_FATAL_ERROR;
+            }
+        }
+
+        switch (ssl->options.connectState) {
+
+        case CONNECT_BEGIN :
+            /* always send client hello first */
+            if ( (ssl->error = SendClientHello(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return SSL_FATAL_ERROR;
+            }
+            ssl->options.connectState = CLIENT_HELLO_SENT;
+            WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
+
+        case CLIENT_HELLO_SENT :
+            neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
+                                          SERVER_HELLODONE_COMPLETE;
+            #ifdef WOLFSSL_DTLS
+                /* In DTLS, when resuming, we can go straight to FINISHED,
+                 * or do a cookie exchange and then skip to FINISHED, assume
+                 * we need the cookie exchange first. */
+                if (ssl->options.dtls)
+                    neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
+            #endif
+            /* get response */
+            while (ssl->options.serverState < neededState) {
+                if ( (ssl->error = ProcessReply(ssl)) < 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return SSL_FATAL_ERROR;
+                }
+                /* if resumption failed, reset needed state */
+                else if (neededState == SERVER_FINISHED_COMPLETE)
+                    if (!ssl->options.resuming) {
+                        if (!ssl->options.dtls)
+                            neededState = SERVER_HELLODONE_COMPLETE;
+                        else
+                            neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
+                    }
+            }
+
+            ssl->options.connectState = HELLO_AGAIN;
+            WOLFSSL_MSG("connect state: HELLO_AGAIN");
+
+        case HELLO_AGAIN :
+            if (ssl->options.certOnly)
+                return SSL_SUCCESS;
+
+            #ifdef WOLFSSL_DTLS
+                if (ssl->options.dtls) {
+                    /* re-init hashes, exclude first hello and verify request */
+#ifndef NO_OLD_TLS
+                    wc_InitMd5(&ssl->hsHashes->hashMd5);
+                    if ( (ssl->error = wc_InitSha(&ssl->hsHashes->hashSha))
+                                                                         != 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return SSL_FATAL_ERROR;
+                    }
+#endif
+                    if (IsAtLeastTLSv1_2(ssl)) {
+                        #ifndef NO_SHA256
+                            if ( (ssl->error = wc_InitSha256(
+                                            &ssl->hsHashes->hashSha256)) != 0) {
+                                WOLFSSL_ERROR(ssl->error);
+                                return SSL_FATAL_ERROR;
+                            }
+                        #endif
+                        #ifdef WOLFSSL_SHA384
+                            if ( (ssl->error = wc_InitSha384(
+                                            &ssl->hsHashes->hashSha384)) != 0) {
+                                WOLFSSL_ERROR(ssl->error);
+                                return SSL_FATAL_ERROR;
+                            }
+                        #endif
+                        #ifdef WOLFSSL_SHA512
+                            if ( (ssl->error = wc_InitSha512(
+                                            &ssl->hsHashes->hashSha512)) != 0) {
+                                WOLFSSL_ERROR(ssl->error);
+                                return SSL_FATAL_ERROR;
+                            }
+                        #endif
+                    }
+                    if ( (ssl->error = SendClientHello(ssl)) != 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return SSL_FATAL_ERROR;
+                    }
+                }
+            #endif
+
+            ssl->options.connectState = HELLO_AGAIN_REPLY;
+            WOLFSSL_MSG("connect state: HELLO_AGAIN_REPLY");
+
+        case HELLO_AGAIN_REPLY :
+            #ifdef WOLFSSL_DTLS
+                if (ssl->options.dtls) {
+                    neededState = ssl->options.resuming ?
+                           SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
+
+                    /* get response */
+                    while (ssl->options.serverState < neededState) {
+                        if ( (ssl->error = ProcessReply(ssl)) < 0) {
+                                WOLFSSL_ERROR(ssl->error);
+                                return SSL_FATAL_ERROR;
+                        }
+                        /* if resumption failed, reset needed state */
+                        else if (neededState == SERVER_FINISHED_COMPLETE)
+                            if (!ssl->options.resuming)
+                                neededState = SERVER_HELLODONE_COMPLETE;
+                    }
+                }
+            #endif
+
+            ssl->options.connectState = FIRST_REPLY_DONE;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_DONE");
+
+        case FIRST_REPLY_DONE :
+            #ifndef NO_CERTS
+                if (ssl->options.sendVerify) {
+                    if ( (ssl->error = SendCertificate(ssl)) != 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return SSL_FATAL_ERROR;
+                    }
+                    WOLFSSL_MSG("sent: certificate");
+                }
+
+            #endif
+            ssl->options.connectState = FIRST_REPLY_FIRST;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_FIRST");
+
+        case FIRST_REPLY_FIRST :
+            if (!ssl->options.resuming) {
+                if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return SSL_FATAL_ERROR;
+                }
+                WOLFSSL_MSG("sent: client key exchange");
+            }
+
+            ssl->options.connectState = FIRST_REPLY_SECOND;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_SECOND");
+
+        case FIRST_REPLY_SECOND :
+            #ifndef NO_CERTS
+                if (ssl->options.sendVerify) {
+                    if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return SSL_FATAL_ERROR;
+                    }
+                    WOLFSSL_MSG("sent: certificate verify");
+                }
+            #endif
+            ssl->options.connectState = FIRST_REPLY_THIRD;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD");
+
+        case FIRST_REPLY_THIRD :
+            if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return SSL_FATAL_ERROR;
+            }
+            WOLFSSL_MSG("sent: change cipher spec");
+            ssl->options.connectState = FIRST_REPLY_FOURTH;
+            WOLFSSL_MSG("connect state: FIRST_REPLY_FOURTH");
+
+        case FIRST_REPLY_FOURTH :
+            if ( (ssl->error = SendFinished(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return SSL_FATAL_ERROR;
+            }
+            WOLFSSL_MSG("sent: finished");
+            ssl->options.connectState = FINISHED_DONE;
+            WOLFSSL_MSG("connect state: FINISHED_DONE");
+
+        case FINISHED_DONE :
+            /* get response */
+            while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
+                if ( (ssl->error = ProcessReply(ssl)) < 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return SSL_FATAL_ERROR;
+                }
+
+            ssl->options.connectState = SECOND_REPLY_DONE;
+            WOLFSSL_MSG("connect state: SECOND_REPLY_DONE");
+
+        case SECOND_REPLY_DONE:
+#ifndef NO_HANDSHAKE_DONE_CB
+            if (ssl->hsDoneCb) {
+                int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
+                if (cbret < 0) {
+                    ssl->error = cbret;
+                    WOLFSSL_MSG("HandShake Done Cb don't continue error");
+                    return SSL_FATAL_ERROR;
+                }
+            }
+#endif /* NO_HANDSHAKE_DONE_CB */
+            FreeHandshakeResources(ssl);
+            WOLFSSL_LEAVE("SSL_connect()", SSL_SUCCESS);
+            return SSL_SUCCESS;
+
+        default:
+            WOLFSSL_MSG("Unknown connect state ERROR");
+            return SSL_FATAL_ERROR; /* unknown connect state */
+        }
+    }
+
+#endif /* NO_WOLFSSL_CLIENT */
+
+
+/* server only parts */
+#ifndef NO_WOLFSSL_SERVER
+
+    #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
+    WOLFSSL_METHOD* wolfSSLv3_server_method(void)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                        0, DYNAMIC_TYPE_METHOD);
+        WOLFSSL_ENTER("SSLv3_server_method");
+        if (method) {
+            InitSSL_Method(method, MakeSSLv3());
+            method->side = WOLFSSL_SERVER_END;
+        }
+        return method;
+    }
+    #endif
+
+
+    #ifdef WOLFSSL_DTLS
+
+        #ifndef NO_OLD_TLS
+        WOLFSSL_METHOD* wolfDTLSv1_server_method(void)
+        {
+            WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                        0, DYNAMIC_TYPE_METHOD);
+            WOLFSSL_ENTER("DTLSv1_server_method");
+            if (method) {
+                InitSSL_Method(method, MakeDTLSv1());
+                method->side = WOLFSSL_SERVER_END;
+            }
+            return method;
+        }
+        #endif /* NO_OLD_TLS */
+
+        WOLFSSL_METHOD* wolfDTLSv1_2_server_method(void)
+        {
+            WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
+                                                        0, DYNAMIC_TYPE_METHOD);
+            WOLFSSL_ENTER("DTLSv1_2_server_method");
+            if (method) {
+                InitSSL_Method(method, MakeDTLSv1_2());
+                method->side = WOLFSSL_SERVER_END;
+            }
+            return method;
+        }
+    #endif
+
+
+    int wolfSSL_accept(WOLFSSL* ssl)
+    {
+        byte havePSK = 0;
+        byte haveAnon = 0;
+        WOLFSSL_ENTER("SSL_accept()");
+
+        #ifdef HAVE_ERRNO_H
+            errno = 0;
+        #endif
+
+        #ifndef NO_PSK
+            havePSK = ssl->options.havePSK;
+        #endif
+        (void)havePSK;
+
+        #ifdef HAVE_ANON
+            haveAnon = ssl->options.haveAnon;
+        #endif
+        (void)haveAnon;
+
+        if (ssl->options.side != WOLFSSL_SERVER_END) {
+            WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
+            return SSL_FATAL_ERROR;
+        }
+
+        #ifndef NO_CERTS
+            /* in case used set_accept_state after init */
+            if (!havePSK && !haveAnon &&
+                            (ssl->buffers.certificate.buffer == NULL ||
+                             ssl->buffers.key.buffer == NULL)) {
+                WOLFSSL_MSG("accept error: don't have server cert and key");
+                ssl->error = NO_PRIVATE_KEY;
+                WOLFSSL_ERROR(ssl->error);
+                return SSL_FATAL_ERROR;
+            }
+        #endif
+
+        #ifdef WOLFSSL_DTLS
+            if (ssl->version.major == DTLS_MAJOR) {
+                ssl->options.dtls   = 1;
+                ssl->options.tls    = 1;
+                ssl->options.tls1_1 = 1;
+
+                if (DtlsPoolInit(ssl) != 0) {
+                    ssl->error = MEMORY_ERROR;
+                    WOLFSSL_ERROR(ssl->error);
+                    return SSL_FATAL_ERROR;
+                }
+            }
+        #endif
+
+        if (ssl->buffers.outputBuffer.length > 0) {
+            if ( (ssl->error = SendBuffered(ssl)) == 0) {
+                if (ssl->fragOffset == 0) {
+                    ssl->options.acceptState++;
+                    WOLFSSL_MSG("accept state: Advanced from buffered send");
+                }
+            }
+            else {
+                WOLFSSL_ERROR(ssl->error);
+                return SSL_FATAL_ERROR;
+            }
+        }
+
+        switch (ssl->options.acceptState) {
+
+        case ACCEPT_BEGIN :
+            /* get response */
+            while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
+                if ( (ssl->error = ProcessReply(ssl)) < 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return SSL_FATAL_ERROR;
+                }
+            ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
+
+        case ACCEPT_CLIENT_HELLO_DONE :
+            ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
+
+        case ACCEPT_FIRST_REPLY_DONE :
+            if ( (ssl->error = SendServerHello(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return SSL_FATAL_ERROR;
+            }
+            ssl->options.acceptState = SERVER_HELLO_SENT;
+            WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
+
+        case SERVER_HELLO_SENT :
+            #ifndef NO_CERTS
+                if (!ssl->options.resuming)
+                    if ( (ssl->error = SendCertificate(ssl)) != 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return SSL_FATAL_ERROR;
+                    }
+            #endif
+            ssl->options.acceptState = CERT_SENT;
+            WOLFSSL_MSG("accept state CERT_SENT");
+
+        case CERT_SENT :
+            if (!ssl->options.resuming)
+                if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return SSL_FATAL_ERROR;
+                }
+            ssl->options.acceptState = KEY_EXCHANGE_SENT;
+            WOLFSSL_MSG("accept state KEY_EXCHANGE_SENT");
+
+        case KEY_EXCHANGE_SENT :
+            #ifndef NO_CERTS
+                if (!ssl->options.resuming)
+                    if (ssl->options.verifyPeer)
+                        if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
+                            WOLFSSL_ERROR(ssl->error);
+                            return SSL_FATAL_ERROR;
+                        }
+            #endif
+            ssl->options.acceptState = CERT_REQ_SENT;
+            WOLFSSL_MSG("accept state CERT_REQ_SENT");
+
+        case CERT_REQ_SENT :
+            if (!ssl->options.resuming)
+                if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return SSL_FATAL_ERROR;
+                }
+            ssl->options.acceptState = SERVER_HELLO_DONE;
+            WOLFSSL_MSG("accept state SERVER_HELLO_DONE");
+
+        case SERVER_HELLO_DONE :
+            if (!ssl->options.resuming) {
+                while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
+                    if ( (ssl->error = ProcessReply(ssl)) < 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return SSL_FATAL_ERROR;
+                    }
+            }
+            ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
+            WOLFSSL_MSG("accept state  ACCEPT_SECOND_REPLY_DONE");
+
+        case ACCEPT_SECOND_REPLY_DONE :
+#ifdef HAVE_SESSION_TICKET
+            if (ssl->options.createTicket) {
+                if ( (ssl->error = SendTicket(ssl)) != 0) {
+                    WOLFSSL_ERROR(ssl->error);
+                    return SSL_FATAL_ERROR;
+                }
+            }
+#endif /* HAVE_SESSION_TICKET */
+            ssl->options.acceptState = TICKET_SENT;
+            WOLFSSL_MSG("accept state  TICKET_SENT");
+
+        case TICKET_SENT:
+            if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return SSL_FATAL_ERROR;
+            }
+            ssl->options.acceptState = CHANGE_CIPHER_SENT;
+            WOLFSSL_MSG("accept state  CHANGE_CIPHER_SENT");
+
+        case CHANGE_CIPHER_SENT :
+            if ( (ssl->error = SendFinished(ssl)) != 0) {
+                WOLFSSL_ERROR(ssl->error);
+                return SSL_FATAL_ERROR;
+            }
+
+            ssl->options.acceptState = ACCEPT_FINISHED_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_FINISHED_DONE");
+
+        case ACCEPT_FINISHED_DONE :
+            if (ssl->options.resuming)
+                while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
+                    if ( (ssl->error = ProcessReply(ssl)) < 0) {
+                        WOLFSSL_ERROR(ssl->error);
+                        return SSL_FATAL_ERROR;
+                    }
+
+            ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
+            WOLFSSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
+
+        case ACCEPT_THIRD_REPLY_DONE :
+#ifndef NO_HANDSHAKE_DONE_CB
+            if (ssl->hsDoneCb) {
+                int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
+                if (cbret < 0) {
+                    ssl->error = cbret;
+                    WOLFSSL_MSG("HandShake Done Cb don't continue error");
+                    return SSL_FATAL_ERROR;
+                }
+            }
+#endif /* NO_HANDSHAKE_DONE_CB */
+            FreeHandshakeResources(ssl);
+            WOLFSSL_LEAVE("SSL_accept()", SSL_SUCCESS);
+            return SSL_SUCCESS;
+
+        default :
+            WOLFSSL_MSG("Unknown accept state ERROR");
+            return SSL_FATAL_ERROR;
+        }
+    }
+
+#endif /* NO_WOLFSSL_SERVER */
+
+
+#ifndef NO_HANDSHAKE_DONE_CB
+
+int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_SetHsDoneCb");
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    ssl->hsDoneCb  = cb;
+    ssl->hsDoneCtx = user_ctx;
+
+
+    return SSL_SUCCESS;
+}
+
+#endif /* NO_HANDSHAKE_DONE_CB */
+
+
+int wolfSSL_Cleanup(void)
+{
+    int ret = SSL_SUCCESS;
+    int release = 0;
+
+    WOLFSSL_ENTER("wolfSSL_Cleanup");
+
+    if (initRefCount == 0)
+        return ret;  /* possibly no init yet, but not failure either way */
+
+    if (LockMutex(&count_mutex) != 0) {
+        WOLFSSL_MSG("Bad Lock Mutex count");
+        return BAD_MUTEX_E;
+    }
+
+    release = initRefCount-- == 1;
+    if (initRefCount < 0)
+        initRefCount = 0;
+
+    UnLockMutex(&count_mutex);
+
+    if (!release)
+        return ret;
+
+#ifndef NO_SESSION_CACHE
+    if (FreeMutex(&session_mutex) != 0)
+        ret = BAD_MUTEX_E;
+#endif
+    if (FreeMutex(&count_mutex) != 0)
+        ret = BAD_MUTEX_E;
+
+#if defined(HAVE_ECC) && defined(FP_ECC)
+    wc_ecc_fp_free();
+#endif
+
+    return ret;
+}
+
+
+#ifndef NO_SESSION_CACHE
+
+
+/* some session IDs aren't random afterall, let's make them random */
+static INLINE word32 HashSession(const byte* sessionID, word32 len, int* error)
+{
+    byte digest[MAX_DIGEST_SIZE];
+
+#ifndef NO_MD5
+    *error =  wc_Md5Hash(sessionID, len, digest);
+#elif !defined(NO_SHA)
+    *error =  wc_ShaHash(sessionID, len, digest);
+#elif !defined(NO_SHA256)
+    *error =  wc_Sha256Hash(sessionID, len, digest);
+#else
+    #error "We need a digest to hash the session IDs"
+#endif
+
+    return *error == 0 ? MakeWordFromHash(digest) : 0; /* 0 on failure */
+}
+
+
+void wolfSSL_flush_sessions(WOLFSSL_CTX* ctx, long tm)
+{
+    /* static table now, no flusing needed */
+    (void)ctx;
+    (void)tm;
+}
+
+
+/* set ssl session timeout in seconds */
+int wolfSSL_set_timeout(WOLFSSL* ssl, unsigned int to)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    ssl->timeout = to;
+
+    return SSL_SUCCESS;
+}
+
+
+/* set ctx session timeout in seconds */
+int wolfSSL_CTX_set_timeout(WOLFSSL_CTX* ctx, unsigned int to)
+{
+    if (ctx == NULL)
+        return BAD_FUNC_ARG;
+
+    ctx->timeout = to;
+
+    return SSL_SUCCESS;
+}
+
+
+#ifndef NO_CLIENT_CACHE
+
+/* Get Session from Client cache based on id/len, return NULL on failure */
+WOLFSSL_SESSION* GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
+{
+    WOLFSSL_SESSION* ret = NULL;
+    word32          row;
+    int             idx;
+    int             count;
+    int             error = 0;
+
+    WOLFSSL_ENTER("GetSessionClient");
+
+    if (ssl->options.side == WOLFSSL_SERVER_END)
+        return NULL;
+
+    len = min(SERVER_ID_LEN, (word32)len);
+    row = HashSession(id, len, &error) % SESSION_ROWS;
+    if (error != 0) {
+        WOLFSSL_MSG("Hash session failed");
+        return NULL;
+    }
+
+    if (LockMutex(&session_mutex) != 0) {
+        WOLFSSL_MSG("Lock session mutex failed");
+        return NULL;
+    }
+
+    /* start from most recently used */
+    count = min((word32)ClientCache[row].totalCount, SESSIONS_PER_ROW);
+    idx = ClientCache[row].nextIdx - 1;
+    if (idx < 0)
+        idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
+
+    for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
+        WOLFSSL_SESSION* current;
+        ClientSession   clSess;
+
+        if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
+            WOLFSSL_MSG("Bad idx");
+            break;
+        }
+
+        clSess = ClientCache[row].Clients[idx];
+
+        current = &SessionCache[clSess.serverRow].Sessions[clSess.serverIdx];
+        if (XMEMCMP(current->serverID, id, len) == 0) {
+            WOLFSSL_MSG("Found a serverid match for client");
+            if (LowResTimer() < (current->bornOn + current->timeout)) {
+                WOLFSSL_MSG("Session valid");
+                ret = current;
+                break;
+            } else {
+                WOLFSSL_MSG("Session timed out");  /* could have more for id */
+            }
+        } else {
+            WOLFSSL_MSG("ServerID not a match from client table");
+        }
+    }
+
+    UnLockMutex(&session_mutex);
+
+    return ret;
+}
+
+#endif /* NO_CLIENT_CACHE */
+
+
+WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret)
+{
+    WOLFSSL_SESSION* ret = 0;
+    const byte*  id = NULL;
+    word32       row;
+    int          idx;
+    int          count;
+    int          error = 0;
+
+    if (ssl->options.sessionCacheOff)
+        return NULL;
+
+    if (ssl->options.haveSessionId == 0)
+        return NULL;
+
+#ifdef HAVE_SESSION_TICKET
+    if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
+        return NULL;
+#endif
+
+    if (ssl->arrays)
+        id = ssl->arrays->sessionID;
+    else
+        id = ssl->session.sessionID;
+
+    row = HashSession(id, ID_LEN, &error) % SESSION_ROWS;
+    if (error != 0) {
+        WOLFSSL_MSG("Hash session failed");
+        return NULL;
+    }
+
+    if (LockMutex(&session_mutex) != 0)
+        return 0;
+
+    /* start from most recently used */
+    count = min((word32)SessionCache[row].totalCount, SESSIONS_PER_ROW);
+    idx = SessionCache[row].nextIdx - 1;
+    if (idx < 0)
+        idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
+
+    for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
+        WOLFSSL_SESSION* current;
+
+        if (idx >= SESSIONS_PER_ROW || idx < 0) { /* sanity check */
+            WOLFSSL_MSG("Bad idx");
+            break;
+        }
+
+        current = &SessionCache[row].Sessions[idx];
+        if (XMEMCMP(current->sessionID, id, ID_LEN) == 0) {
+            WOLFSSL_MSG("Found a session match");
+            if (LowResTimer() < (current->bornOn + current->timeout)) {
+                WOLFSSL_MSG("Session valid");
+                ret = current;
+                if (masterSecret)
+                    XMEMCPY(masterSecret, current->masterSecret, SECRET_LEN);
+            } else {
+                WOLFSSL_MSG("Session timed out");
+            }
+            break;  /* no more sessionIDs whether valid or not that match */
+        } else {
+            WOLFSSL_MSG("SessionID not a match at this idx");
+        }
+    }
+
+    UnLockMutex(&session_mutex);
+
+    return ret;
+}
+
+
+int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
+{
+    if (ssl->options.sessionCacheOff)
+        return SSL_FAILURE;
+
+    if (LowResTimer() < (session->bornOn + session->timeout)) {
+        ssl->session  = *session;
+        ssl->options.resuming = 1;
+
+#ifdef SESSION_CERTS
+        ssl->version              = session->version;
+        ssl->options.cipherSuite0 = session->cipherSuite0;
+        ssl->options.cipherSuite  = session->cipherSuite;
+#endif
+
+        return SSL_SUCCESS;
+    }
+    return SSL_FAILURE;  /* session timed out */
+}
+
+
+#ifdef WOLFSSL_SESSION_STATS
+static int get_locked_session_stats(word32* active, word32* total,
+                                    word32* peak);
+#endif
+
+int AddSession(WOLFSSL* ssl)
+{
+    word32 row, idx;
+    int    error = 0;
+
+    if (ssl->options.sessionCacheOff)
+        return 0;
+
+    if (ssl->options.haveSessionId == 0)
+        return 0;
+
+#ifdef HAVE_SESSION_TICKET
+    if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
+        return 0;
+#endif
+
+    row = HashSession(ssl->arrays->sessionID, ID_LEN, &error) % SESSION_ROWS;
+    if (error != 0) {
+        WOLFSSL_MSG("Hash session failed");
+        return error;
+    }
+
+    if (LockMutex(&session_mutex) != 0)
+        return BAD_MUTEX_E;
+
+    idx = SessionCache[row].nextIdx++;
+#ifdef SESSION_INDEX
+    ssl->sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
+#endif
+
+    XMEMCPY(SessionCache[row].Sessions[idx].masterSecret,
+           ssl->arrays->masterSecret, SECRET_LEN);
+    XMEMCPY(SessionCache[row].Sessions[idx].sessionID, ssl->arrays->sessionID,
+           ID_LEN);
+    SessionCache[row].Sessions[idx].sessionIDSz = ssl->arrays->sessionIDSz;
+
+    SessionCache[row].Sessions[idx].timeout = ssl->timeout;
+    SessionCache[row].Sessions[idx].bornOn  = LowResTimer();
+
+#ifdef HAVE_SESSION_TICKET
+    SessionCache[row].Sessions[idx].ticketLen     = ssl->session.ticketLen;
+    XMEMCPY(SessionCache[row].Sessions[idx].ticket,
+                                   ssl->session.ticket, ssl->session.ticketLen);
+#endif
+
+#ifdef SESSION_CERTS
+    SessionCache[row].Sessions[idx].chain.count = ssl->session.chain.count;
+    XMEMCPY(SessionCache[row].Sessions[idx].chain.certs,
+           ssl->session.chain.certs, sizeof(x509_buffer) * MAX_CHAIN_DEPTH);
+
+    SessionCache[row].Sessions[idx].version      = ssl->version;
+    SessionCache[row].Sessions[idx].cipherSuite0 = ssl->options.cipherSuite0;
+    SessionCache[row].Sessions[idx].cipherSuite  = ssl->options.cipherSuite;
+#endif /* SESSION_CERTS */
+
+    SessionCache[row].totalCount++;
+    if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
+        SessionCache[row].nextIdx = 0;
+
+#ifndef NO_CLIENT_CACHE
+    if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->session.idLen) {
+        word32 clientRow, clientIdx;
+
+        WOLFSSL_MSG("Adding client cache entry");
+
+        SessionCache[row].Sessions[idx].idLen = ssl->session.idLen;
+        XMEMCPY(SessionCache[row].Sessions[idx].serverID, ssl->session.serverID,
+                ssl->session.idLen);
+
+        clientRow = HashSession(ssl->session.serverID, ssl->session.idLen,
+                                &error) % SESSION_ROWS;
+        if (error != 0) {
+            WOLFSSL_MSG("Hash session failed");
+        } else {
+            clientIdx = ClientCache[clientRow].nextIdx++;
+
+            ClientCache[clientRow].Clients[clientIdx].serverRow = (word16)row;
+            ClientCache[clientRow].Clients[clientIdx].serverIdx = (word16)idx;
+
+            ClientCache[clientRow].totalCount++;
+            if (ClientCache[clientRow].nextIdx == SESSIONS_PER_ROW)
+                ClientCache[clientRow].nextIdx = 0;
+        }
+    }
+    else
+        SessionCache[row].Sessions[idx].idLen = 0;
+#endif /* NO_CLIENT_CACHE */
+
+#if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
+    if (error == 0) {
+        word32 active = 0;
+
+        error = get_locked_session_stats(&active, NULL, NULL);
+        if (error == SSL_SUCCESS) {
+            error = 0;  /* back to this function ok */
+
+            if (active > PeakSessions)
+                PeakSessions = active;
+        }
+    }
+#endif /* defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS) */
+
+    if (UnLockMutex(&session_mutex) != 0)
+        return BAD_MUTEX_E;
+
+    return error;
+}
+
+
+#ifdef SESSION_INDEX
+
+int wolfSSL_GetSessionIndex(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_GetSessionIndex");
+    WOLFSSL_LEAVE("wolfSSL_GetSessionIndex", ssl->sessionIndex);
+    return ssl->sessionIndex;
+}
+
+
+int wolfSSL_GetSessionAtIndex(int idx, WOLFSSL_SESSION* session)
+{
+    int row, col, result = SSL_FAILURE;
+
+    WOLFSSL_ENTER("wolfSSL_GetSessionAtIndex");
+
+    row = idx >> SESSIDX_ROW_SHIFT;
+    col = idx & SESSIDX_IDX_MASK;
+
+    if (LockMutex(&session_mutex) != 0) {
+        return BAD_MUTEX_E;
+    }
+
+    if (row < SESSION_ROWS &&
+        col < (int)min(SessionCache[row].totalCount, SESSIONS_PER_ROW)) {
+        XMEMCPY(session,
+                 &SessionCache[row].Sessions[col], sizeof(WOLFSSL_SESSION));
+        result = SSL_SUCCESS;
+    }
+
+    if (UnLockMutex(&session_mutex) != 0)
+        result = BAD_MUTEX_E;
+
+    WOLFSSL_LEAVE("wolfSSL_GetSessionAtIndex", result);
+    return result;
+}
+
+#endif /* SESSION_INDEX */
+
+#if defined(SESSION_INDEX) && defined(SESSION_CERTS)
+
+WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session)
+{
+    WOLFSSL_X509_CHAIN* chain = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
+    if (session)
+        chain = &session->chain;
+
+    WOLFSSL_LEAVE("wolfSSL_SESSION_get_peer_chain", chain ? 1 : 0);
+    return chain;
+}
+
+#endif /* SESSION_INDEX && SESSION_CERTS */
+
+
+#ifdef WOLFSSL_SESSION_STATS
+
+/* requires session_mutex lock held, SSL_SUCCESS on ok */
+static int get_locked_session_stats(word32* active, word32* total, word32* peak)
+{
+    int result = SSL_SUCCESS;
+    int i;
+    int count;
+    int idx;
+    word32 now   = 0;
+    word32 seen  = 0;
+    word32 ticks = LowResTimer();
+
+    (void)peak;
+
+    WOLFSSL_ENTER("get_locked_session_stats");
+
+    for (i = 0; i < SESSION_ROWS; i++) {
+        seen += SessionCache[i].totalCount;
+
+        if (active == NULL)
+            continue;  /* no need to calculate what we can't set */
+
+        count = min((word32)SessionCache[i].totalCount, SESSIONS_PER_ROW);
+        idx   = SessionCache[i].nextIdx - 1;
+        if (idx < 0)
+            idx = SESSIONS_PER_ROW - 1; /* if back to front previous was end */
+
+        for (; count > 0; --count, idx = idx ? idx - 1 : SESSIONS_PER_ROW - 1) {
+            if (idx >= SESSIONS_PER_ROW || idx < 0) {  /* sanity check */
+                WOLFSSL_MSG("Bad idx");
+                break;
+            }
+
+            /* if not expried then good */
+            if (ticks < (SessionCache[i].Sessions[idx].bornOn +
+                         SessionCache[i].Sessions[idx].timeout) ) {
+                now++;
+            }
+        }
+    }
+
+    if (active)
+        *active = now;
+
+    if (total)
+        *total = seen;
+
+#ifdef WOLFSSL_PEAK_SESSIONS
+    if (peak)
+        *peak = PeakSessions;
+#endif
+
+    WOLFSSL_LEAVE("get_locked_session_stats", result);
+
+    return result;
+}
+
+
+/* return SSL_SUCCESS on ok */
+int wolfSSL_get_session_stats(word32* active, word32* total, word32* peak,
+                              word32* maxSessions)
+{
+    int result = SSL_SUCCESS;
+
+    WOLFSSL_ENTER("wolfSSL_get_session_stats");
+
+    if (maxSessions) {
+        *maxSessions = SESSIONS_PER_ROW * SESSION_ROWS;
+
+        if (active == NULL && total == NULL && peak == NULL)
+            return result;  /* we're done */
+    }
+
+    /* user must provide at least one query value */
+    if (active == NULL && total == NULL && peak == NULL)
+        return BAD_FUNC_ARG;
+
+    if (LockMutex(&session_mutex) != 0) {
+        return BAD_MUTEX_E;
+    }
+
+    result = get_locked_session_stats(active, total, peak);
+
+    if (UnLockMutex(&session_mutex) != 0)
+        result = BAD_MUTEX_E;
+
+    WOLFSSL_LEAVE("wolfSSL_get_session_stats", result);
+
+    return result;
+}
+
+#endif /* WOLFSSL_SESSION_STATS */
+
+
+    #ifdef PRINT_SESSION_STATS
+
+    /* SSL_SUCCESS on ok */
+    int wolfSSL_PrintSessionStats(void)
+    {
+        word32 totalSessionsSeen = 0;
+        word32 totalSessionsNow = 0;
+        word32 peak = 0;
+        word32 maxSessions = 0;
+        int    i;
+        int    ret;
+        double E;               /* expected freq */
+        double chiSquare = 0;
+
+        ret = wolfSSL_get_session_stats(&totalSessionsNow, &totalSessionsSeen,
+                                        &peak, &maxSessions);
+        if (ret != SSL_SUCCESS)
+            return ret;
+        printf("Total Sessions Seen = %d\n", totalSessionsSeen);
+        printf("Total Sessions Now  = %d\n", totalSessionsNow);
+#ifdef WOLFSSL_PEAK_SESSIONS
+        printf("Peak  Sessions      = %d\n", peak);
+#endif
+        printf("Max   Sessions      = %d\n", maxSessions);
+
+        E = (double)totalSessionsSeen / SESSION_ROWS;
+
+        for (i = 0; i < SESSION_ROWS; i++) {
+            double diff = SessionCache[i].totalCount - E;
+            diff *= diff;                /* square    */
+            diff /= E;                   /* normalize */
+
+            chiSquare += diff;
+        }
+        printf("  chi-square = %5.1f, d.f. = %d\n", chiSquare,
+                                                     SESSION_ROWS - 1);
+        #if (SESSION_ROWS == 11)
+            printf(" .05 p value =  18.3, chi-square should be less\n");
+        #elif (SESSION_ROWS == 211)
+            printf(".05 p value  = 244.8, chi-square should be less\n");
+        #elif (SESSION_ROWS == 5981)
+            printf(".05 p value  = 6161.0, chi-square should be less\n");
+        #elif (SESSION_ROWS == 3)
+            printf(".05 p value  =   6.0, chi-square should be less\n");
+        #elif (SESSION_ROWS == 2861)
+            printf(".05 p value  = 2985.5, chi-square should be less\n");
+        #endif
+        printf("\n");
+
+        return ret;
+    }
+
+    #endif /* SESSION_STATS */
+
+#else  /* NO_SESSION_CACHE */
+
+/* No session cache version */
+WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret)
+{
+    (void)ssl;
+    (void)masterSecret;
+
+    return NULL;
+}
+
+#endif /* NO_SESSION_CACHE */
+
+
+/* call before SSL_connect, if verifying will add name check to
+   date check and signature check */
+int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
+{
+    WOLFSSL_ENTER("wolfSSL_check_domain_name");
+    if (ssl->buffers.domainName.buffer)
+        XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
+
+    ssl->buffers.domainName.length = (word32)XSTRLEN(dn) + 1;
+    ssl->buffers.domainName.buffer = (byte*) XMALLOC(
+                ssl->buffers.domainName.length, ssl->heap, DYNAMIC_TYPE_DOMAIN);
+
+    if (ssl->buffers.domainName.buffer) {
+        XSTRNCPY((char*)ssl->buffers.domainName.buffer, dn,
+                ssl->buffers.domainName.length);
+        return SSL_SUCCESS;
+    }
+    else {
+        ssl->error = MEMORY_ERROR;
+        return SSL_FAILURE;
+    }
+}
+
+
+/* turn on wolfSSL zlib compression
+   returns SSL_SUCCESS for success, else error (not built in)
+*/
+int wolfSSL_set_compression(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_set_compression");
+    (void)ssl;
+#ifdef HAVE_LIBZ
+    ssl->options.usingCompression = 1;
+    return SSL_SUCCESS;
+#else
+    return NOT_COMPILED_IN;
+#endif
+}
+
+
+#ifndef USE_WINDOWS_API
+    #ifndef NO_WRITEV
+
+        /* simulate writev semantics, doesn't actually do block at a time though
+           because of SSL_write behavior and because front adds may be small */
+        int wolfSSL_writev(WOLFSSL* ssl, const struct iovec* iov, int iovcnt)
+        {
+        #ifdef WOLFSSL_SMALL_STACK
+            byte   staticBuffer[1]; /* force heap usage */
+        #else
+            byte   staticBuffer[FILE_BUFFER_SIZE];
+        #endif
+            byte* myBuffer  = staticBuffer;
+            int   dynamic   = 0;
+            int   sending   = 0;
+            int   idx       = 0;
+            int   i;
+            int   ret;
+
+            WOLFSSL_ENTER("wolfSSL_writev");
+
+            for (i = 0; i < iovcnt; i++)
+                sending += (int)iov[i].iov_len;
+
+            if (sending > (int)sizeof(staticBuffer)) {
+                myBuffer = (byte*)XMALLOC(sending, ssl->heap,
+                                                           DYNAMIC_TYPE_WRITEV);
+                if (!myBuffer)
+                    return MEMORY_ERROR;
+
+                dynamic = 1;
+            }
+
+            for (i = 0; i < iovcnt; i++) {
+                XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
+                idx += (int)iov[i].iov_len;
+            }
+
+            ret = wolfSSL_write(ssl, myBuffer, sending);
+
+            if (dynamic)
+                XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
+
+            return ret;
+        }
+    #endif
+#endif
+
+
+#ifdef WOLFSSL_CALLBACKS
+
+    typedef struct itimerval Itimerval;
+
+    /* don't keep calling simple functions while setting up timer and singals
+       if no inlining these are the next best */
+
+    #define AddTimes(a, b, c)                       \
+        do {                                        \
+            c.tv_sec  = a.tv_sec  + b.tv_sec;       \
+            c.tv_usec = a.tv_usec + b.tv_usec;      \
+            if (c.tv_usec >=  1000000) {            \
+                c.tv_sec++;                         \
+                c.tv_usec -= 1000000;               \
+            }                                       \
+        } while (0)
+
+
+    #define SubtractTimes(a, b, c)                  \
+        do {                                        \
+            c.tv_sec  = a.tv_sec  - b.tv_sec;       \
+            c.tv_usec = a.tv_usec - b.tv_usec;      \
+            if (c.tv_usec < 0) {                    \
+                c.tv_sec--;                         \
+                c.tv_usec += 1000000;               \
+            }                                       \
+        } while (0)
+
+    #define CmpTimes(a, b, cmp)                     \
+        ((a.tv_sec  ==  b.tv_sec) ?                 \
+            (a.tv_usec cmp b.tv_usec) :             \
+            (a.tv_sec  cmp b.tv_sec))               \
+
+
+    /* do nothing handler */
+    static void myHandler(int signo)
+    {
+        (void)signo;
+        return;
+    }
+
+
+    static int wolfSSL_ex_wrapper(WOLFSSL* ssl, HandShakeCallBack hsCb,
+                                 TimeoutCallBack toCb, Timeval timeout)
+    {
+        int       ret        = SSL_FATAL_ERROR;
+        int       oldTimerOn = 0;   /* was timer already on */
+        Timeval   startTime;
+        Timeval   endTime;
+        Timeval   totalTime;
+        Itimerval myTimeout;
+        Itimerval oldTimeout; /* if old timer adjust from total time to reset */
+        struct sigaction act, oact;
+
+        #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
+
+        if (hsCb) {
+            ssl->hsInfoOn = 1;
+            InitHandShakeInfo(&ssl->handShakeInfo);
+        }
+        if (toCb) {
+            ssl->toInfoOn = 1;
+            InitTimeoutInfo(&ssl->timeoutInfo);
+
+            if (gettimeofday(&startTime, 0) < 0)
+                ERR_OUT(GETTIME_ERROR);
+
+            /* use setitimer to simulate getitimer, init 0 myTimeout */
+            myTimeout.it_interval.tv_sec  = 0;
+            myTimeout.it_interval.tv_usec = 0;
+            myTimeout.it_value.tv_sec     = 0;
+            myTimeout.it_value.tv_usec    = 0;
+            if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
+                ERR_OUT(SETITIMER_ERROR);
+
+            if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
+                oldTimerOn = 1;
+
+                /* is old timer going to expire before ours */
+                if (CmpTimes(oldTimeout.it_value, timeout, <)) {
+                    timeout.tv_sec  = oldTimeout.it_value.tv_sec;
+                    timeout.tv_usec = oldTimeout.it_value.tv_usec;
+                }
+            }
+            myTimeout.it_value.tv_sec  = timeout.tv_sec;
+            myTimeout.it_value.tv_usec = timeout.tv_usec;
+
+            /* set up signal handler, don't restart socket send/recv */
+            act.sa_handler = myHandler;
+            sigemptyset(&act.sa_mask);
+            act.sa_flags = 0;
+#ifdef SA_INTERRUPT
+            act.sa_flags |= SA_INTERRUPT;
+#endif
+            if (sigaction(SIGALRM, &act, &oact) < 0)
+                ERR_OUT(SIGACT_ERROR);
+
+            if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
+                ERR_OUT(SETITIMER_ERROR);
+        }
+
+        /* do main work */
+#ifndef NO_WOLFSSL_CLIENT
+        if (ssl->options.side == WOLFSSL_CLIENT_END)
+            ret = wolfSSL_connect(ssl);
+#endif
+#ifndef NO_WOLFSSL_SERVER
+        if (ssl->options.side == WOLFSSL_SERVER_END)
+            ret = wolfSSL_accept(ssl);
+#endif
+
+        /* do callbacks */
+        if (toCb) {
+            if (oldTimerOn) {
+                gettimeofday(&endTime, 0);
+                SubtractTimes(endTime, startTime, totalTime);
+                /* adjust old timer for elapsed time */
+                if (CmpTimes(totalTime, oldTimeout.it_value, <))
+                    SubtractTimes(oldTimeout.it_value, totalTime,
+                                  oldTimeout.it_value);
+                else {
+                    /* reset value to interval, may be off */
+                    oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
+                    oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
+                }
+                /* keep iter the same whether there or not */
+            }
+            /* restore old handler */
+            if (sigaction(SIGALRM, &oact, 0) < 0)
+                ret = SIGACT_ERROR;    /* more pressing error, stomp */
+            else
+                /* use old settings which may turn off (expired or not there) */
+                if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
+                    ret = SETITIMER_ERROR;
+
+            /* if we had a timeout call callback */
+            if (ssl->timeoutInfo.timeoutName[0]) {
+                ssl->timeoutInfo.timeoutValue.tv_sec  = timeout.tv_sec;
+                ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
+                (toCb)(&ssl->timeoutInfo);
+            }
+            /* clean up */
+            FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
+            ssl->toInfoOn = 0;
+        }
+        if (hsCb) {
+            FinishHandShakeInfo(&ssl->handShakeInfo, ssl);
+            (hsCb)(&ssl->handShakeInfo);
+            ssl->hsInfoOn = 0;
+        }
+        return ret;
+    }
+
+
+#ifndef NO_WOLFSSL_CLIENT
+
+    int wolfSSL_connect_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
+                          TimeoutCallBack toCb, Timeval timeout)
+    {
+        WOLFSSL_ENTER("wolfSSL_connect_ex");
+        return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
+    }
+
+#endif
+
+
+#ifndef NO_WOLFSSL_SERVER
+
+    int wolfSSL_accept_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
+                         TimeoutCallBack toCb,Timeval timeout)
+    {
+        WOLFSSL_ENTER("wolfSSL_accept_ex");
+        return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
+    }
+
+#endif
+
+#endif /* WOLFSSL_CALLBACKS */
+
+
+#ifndef NO_PSK
+
+    void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX* ctx,
+                                         wc_psk_client_callback cb)
+    {
+        WOLFSSL_ENTER("SSL_CTX_set_psk_client_callback");
+        ctx->havePSK = 1;
+        ctx->client_psk_cb = cb;
+    }
+
+
+    void wolfSSL_set_psk_client_callback(WOLFSSL* ssl,wc_psk_client_callback cb)
+    {
+        byte haveRSA = 1;
+
+        WOLFSSL_ENTER("SSL_set_psk_client_callback");
+        ssl->options.havePSK = 1;
+        ssl->options.client_psk_cb = cb;
+
+        #ifdef NO_RSA
+            haveRSA = 0;
+        #endif
+        InitSuites(ssl->suites, ssl->version, haveRSA, TRUE,
+                   ssl->options.haveDH, ssl->options.haveNTRU,
+                   ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
+                   ssl->options.side);
+    }
+
+
+    void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX* ctx,
+                                         wc_psk_server_callback cb)
+    {
+        WOLFSSL_ENTER("SSL_CTX_set_psk_server_callback");
+        ctx->havePSK = 1;
+        ctx->server_psk_cb = cb;
+    }
+
+
+    void wolfSSL_set_psk_server_callback(WOLFSSL* ssl,wc_psk_server_callback cb)
+    {
+        byte haveRSA = 1;
+
+        WOLFSSL_ENTER("SSL_set_psk_server_callback");
+        ssl->options.havePSK = 1;
+        ssl->options.server_psk_cb = cb;
+
+        #ifdef NO_RSA
+            haveRSA = 0;
+        #endif
+        InitSuites(ssl->suites, ssl->version, haveRSA, TRUE,
+                   ssl->options.haveDH, ssl->options.haveNTRU,
+                   ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
+                   ssl->options.side);
+    }
+
+
+    const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl)
+    {
+        WOLFSSL_ENTER("SSL_get_psk_identity_hint");
+
+        if (ssl == NULL || ssl->arrays == NULL)
+            return NULL;
+
+        return ssl->arrays->server_hint;
+    }
+
+
+    const char* wolfSSL_get_psk_identity(const WOLFSSL* ssl)
+    {
+        WOLFSSL_ENTER("SSL_get_psk_identity");
+
+        if (ssl == NULL || ssl->arrays == NULL)
+            return NULL;
+
+        return ssl->arrays->client_identity;
+    }
+
+
+    int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX* ctx, const char* hint)
+    {
+        WOLFSSL_ENTER("SSL_CTX_use_psk_identity_hint");
+        if (hint == 0)
+            ctx->server_hint[0] = 0;
+        else {
+            XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
+            ctx->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
+        }
+        return SSL_SUCCESS;
+    }
+
+
+    int wolfSSL_use_psk_identity_hint(WOLFSSL* ssl, const char* hint)
+    {
+        WOLFSSL_ENTER("SSL_use_psk_identity_hint");
+
+        if (ssl == NULL || ssl->arrays == NULL)
+            return SSL_FAILURE;
+
+        if (hint == 0)
+            ssl->arrays->server_hint[0] = 0;
+        else {
+            XSTRNCPY(ssl->arrays->server_hint, hint, MAX_PSK_ID_LEN);
+            ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
+        }
+        return SSL_SUCCESS;
+    }
+
+#endif /* NO_PSK */
+
+
+#ifdef HAVE_ANON
+
+    int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_allow_anon_cipher");
+
+        if (ctx == NULL)
+            return SSL_FAILURE;
+
+        ctx->haveAnon = 1;
+
+        return SSL_SUCCESS;
+    }
+
+#endif /* HAVE_ANON */
+
+
+#ifndef NO_CERTS
+/* used to be defined on NO_FILESYSTEM only, but are generally useful */
+
+    /* wolfSSL extension allows DER files to be loaded from buffers as well */
+    int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX* ctx,
+                                       const unsigned char* in,
+                                       long sz, int format)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_load_verify_buffer");
+        if (format == SSL_FILETYPE_PEM)
+            return ProcessChainBuffer(ctx, in, sz, format, CA_TYPE, NULL);
+        else
+            return ProcessBuffer(ctx, in, sz, format, CA_TYPE, NULL,NULL,0);
+    }
+
+
+    int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX* ctx,
+                                 const unsigned char* in, long sz, int format)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_buffer");
+        return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 0);
+    }
+
+
+    int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX* ctx,
+                                 const unsigned char* in, long sz, int format)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_buffer");
+        return ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL,NULL,0);
+    }
+
+
+    int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
+                                 const unsigned char* in, long sz)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_buffer");
+        return ProcessBuffer(ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE, NULL,
+                             NULL, 1);
+    }
+
+    int wolfSSL_use_certificate_buffer(WOLFSSL* ssl,
+                                 const unsigned char* in, long sz, int format)
+    {
+        WOLFSSL_ENTER("wolfSSL_use_certificate_buffer");
+        return ProcessBuffer(ssl->ctx, in, sz, format,CERT_TYPE,ssl,NULL,0);
+    }
+
+
+    int wolfSSL_use_PrivateKey_buffer(WOLFSSL* ssl,
+                                 const unsigned char* in, long sz, int format)
+    {
+        WOLFSSL_ENTER("wolfSSL_use_PrivateKey_buffer");
+        return ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE,
+                             ssl, NULL, 0);
+    }
+
+
+    int wolfSSL_use_certificate_chain_buffer(WOLFSSL* ssl,
+                                 const unsigned char* in, long sz)
+    {
+        WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer");
+        return ProcessBuffer(ssl->ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE,
+                             ssl, NULL, 1);
+    }
+
+
+    /* unload any certs or keys that SSL owns, leave CTX as is
+       SSL_SUCCESS on ok */
+    int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl)
+    {
+        if (ssl == NULL) {
+            WOLFSSL_MSG("Null function arg");
+            return BAD_FUNC_ARG;
+        }
+
+        if (ssl->buffers.weOwnCert) {
+            WOLFSSL_MSG("Unloading cert");
+            XFREE(ssl->buffers.certificate.buffer, ssl->heap,DYNAMIC_TYPE_CERT);
+            ssl->buffers.weOwnCert = 0;
+            ssl->buffers.certificate.length = 0;
+            ssl->buffers.certificate.buffer = NULL;
+        }
+
+        if (ssl->buffers.weOwnCertChain) {
+            WOLFSSL_MSG("Unloading cert chain");
+            XFREE(ssl->buffers.certChain.buffer, ssl->heap,DYNAMIC_TYPE_CERT);
+            ssl->buffers.weOwnCertChain = 0;
+            ssl->buffers.certChain.length = 0;
+            ssl->buffers.certChain.buffer = NULL;
+        }
+
+        if (ssl->buffers.weOwnKey) {
+            WOLFSSL_MSG("Unloading key");
+            XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
+            ssl->buffers.weOwnKey = 0;
+            ssl->buffers.key.length = 0;
+            ssl->buffers.key.buffer = NULL;
+        }
+
+        return SSL_SUCCESS;
+    }
+
+
+    int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_UnloadCAs");
+
+        if (ctx == NULL)
+            return BAD_FUNC_ARG;
+
+        return wolfSSL_CertManagerUnloadCAs(ctx->cm);
+    }
+
+/* old NO_FILESYSTEM end */
+#endif /* !NO_CERTS */
+
+
+#if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
+
+
+    int wolfSSL_add_all_algorithms(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_add_all_algorithms");
+        wolfSSL_Init();
+        return SSL_SUCCESS;
+    }
+
+
+    long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX* ctx, long sz)
+    {
+        /* cache size fixed at compile time in wolfSSL */
+        (void)ctx;
+        (void)sz;
+        return 0;
+    }
+
+
+    void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX* ctx, int mode)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
+        if (mode)
+            ctx->quietShutdown = 1;
+    }
+
+
+    void wolfSSL_set_quiet_shutdown(WOLFSSL* ssl, int mode)
+    {
+        WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
+        if (mode)
+            ssl->options.quietShutdown = 1;
+    }
+
+
+    void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
+    {
+        WOLFSSL_ENTER("SSL_set_bio");
+        wolfSSL_set_rfd(ssl, rd->fd);
+        wolfSSL_set_wfd(ssl, wr->fd);
+
+        ssl->biord = rd;
+        ssl->biowr = wr;
+    }
+
+
+    void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
+                                       STACK_OF(WOLFSSL_X509_NAME)* names)
+    {
+        (void)ctx;
+        (void)names;
+    }
+
+
+    STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char* fname)
+    {
+        (void)fname;
+        return 0;
+    }
+
+
+    int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX* ctx)
+    {
+        /* TODO:, not needed in goahead */
+        (void)ctx;
+        return SSL_NOT_IMPLEMENTED;
+    }
+
+
+    /* keyblock size in bytes or -1 */
+    int wolfSSL_get_keyblock_size(WOLFSSL* ssl)
+    {
+        if (ssl == NULL)
+            return SSL_FATAL_ERROR;
+
+        return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
+                    ssl->specs.hash_size);
+    }
+
+
+    /* store keys returns SSL_SUCCESS or -1 on error */
+    int wolfSSL_get_keys(WOLFSSL* ssl, unsigned char** ms, unsigned int* msLen,
+                                     unsigned char** sr, unsigned int* srLen,
+                                     unsigned char** cr, unsigned int* crLen)
+    {
+        if (ssl == NULL || ssl->arrays == NULL)
+            return SSL_FATAL_ERROR;
+
+        *ms = ssl->arrays->masterSecret;
+        *sr = ssl->arrays->serverRandom;
+        *cr = ssl->arrays->clientRandom;
+
+        *msLen = SECRET_LEN;
+        *srLen = RAN_LEN;
+        *crLen = RAN_LEN;
+
+        return SSL_SUCCESS;
+    }
+
+
+    void wolfSSL_set_accept_state(WOLFSSL* ssl)
+    {
+        byte haveRSA = 1;
+        byte havePSK = 0;
+
+        WOLFSSL_ENTER("SSL_set_accept_state");
+        ssl->options.side = WOLFSSL_SERVER_END;
+        /* reset suites in case user switched */
+
+        #ifdef NO_RSA
+            haveRSA = 0;
+        #endif
+        #ifndef NO_PSK
+            havePSK = ssl->options.havePSK;
+        #endif
+        InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
+                   ssl->options.haveDH, ssl->options.haveNTRU,
+                   ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
+                   ssl->options.side);
+    }
+#endif
+
+    /* return true if connection established */
+    int wolfSSL_is_init_finished(WOLFSSL* ssl)
+    {
+        if (ssl == NULL)
+            return 0;
+
+        if (ssl->options.handShakeState == HANDSHAKE_DONE)
+            return 1;
+
+        return 0;
+    }
+
+#if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
+    void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX* ctx,
+                                      WOLFSSL_RSA*(*f)(WOLFSSL*, int, int))
+    {
+        /* wolfSSL verifies all these internally */
+        (void)ctx;
+        (void)f;
+    }
+
+
+    void wolfSSL_set_shutdown(WOLFSSL* ssl, int opt)
+    {
+        WOLFSSL_ENTER("wolfSSL_set_shutdown");
+        if(ssl==NULL) {
+            WOLFSSL_MSG("Shutdown not set. ssl is null");
+            return;
+        }
+
+        ssl->options.sentNotify =  (opt&SSL_SENT_SHUTDOWN) > 0;
+        ssl->options.closeNotify = (opt&SSL_RECEIVED_SHUTDOWN) > 0;
+    }
+
+
+    long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt)
+    {
+        /* goahead calls with 0, do nothing */
+        WOLFSSL_ENTER("SSL_CTX_set_options");
+        (void)ctx;
+        return opt;
+    }
+
+
+    int wolfSSL_set_rfd(WOLFSSL* ssl, int rfd)
+    {
+        WOLFSSL_ENTER("SSL_set_rfd");
+        ssl->rfd = rfd;      /* not used directly to allow IO callbacks */
+
+        ssl->IOCB_ReadCtx  = &ssl->rfd;
+
+        return SSL_SUCCESS;
+    }
+
+
+    int wolfSSL_set_wfd(WOLFSSL* ssl, int wfd)
+    {
+        WOLFSSL_ENTER("SSL_set_wfd");
+        ssl->wfd = wfd;      /* not used directly to allow IO callbacks */
+
+        ssl->IOCB_WriteCtx  = &ssl->wfd;
+
+        return SSL_SUCCESS;
+    }
+
+
+    WOLFSSL_RSA* wolfSSL_RSA_generate_key(int len, unsigned long bits,
+                                          void(*f)(int, int, void*), void* data)
+    {
+        /* no tmp key needed, actual generation not supported */
+        WOLFSSL_ENTER("RSA_generate_key");
+        (void)len;
+        (void)bits;
+        (void)f;
+        (void)data;
+        return NULL;
+    }
+
+
+
+    WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert(
+                                                    WOLFSSL_X509_STORE_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_current_cert");
+        if(ctx)
+            return ctx->current_cert;
+        return NULL;
+    }
+
+
+    int wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error");
+        if (ctx != NULL)
+            return ctx->error;
+        return 0;
+    }
+
+
+    int wolfSSL_X509_STORE_CTX_get_error_depth(WOLFSSL_X509_STORE_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error_depth");
+        if(ctx)
+            return ctx->error_depth;
+        return SSL_FATAL_ERROR;
+    }
+
+
+    WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void)
+    {
+        static WOLFSSL_BIO_METHOD meth;
+
+        WOLFSSL_ENTER("BIO_f_buffer");
+        meth.type = BIO_BUFFER;
+
+        return &meth;
+    }
+
+
+    long wolfSSL_BIO_set_write_buffer_size(WOLFSSL_BIO* bio, long size)
+    {
+        /* wolfSSL has internal buffer, compatibility only */
+        WOLFSSL_ENTER("BIO_set_write_buffer_size");
+        (void)bio;
+        return size;
+    }
+
+
+    WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void)
+    {
+        static WOLFSSL_BIO_METHOD meth;
+
+        WOLFSSL_ENTER("BIO_f_ssl");
+        meth.type = BIO_SSL;
+
+        return &meth;
+    }
+
+
+    WOLFSSL_BIO* wolfSSL_BIO_new_socket(int sfd, int closeF)
+    {
+        WOLFSSL_BIO* bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0,
+                                                DYNAMIC_TYPE_OPENSSL);
+
+        WOLFSSL_ENTER("BIO_new_socket");
+        if (bio) {
+            bio->type  = BIO_SOCKET;
+            bio->close = (byte)closeF;
+            bio->eof   = 0;
+            bio->ssl   = 0;
+            bio->fd    = sfd;
+            bio->prev  = 0;
+            bio->next  = 0;
+            bio->mem   = NULL;
+            bio->memLen = 0;
+        }
+        return bio;
+    }
+
+
+    int wolfSSL_BIO_eof(WOLFSSL_BIO* b)
+    {
+        WOLFSSL_ENTER("BIO_eof");
+        if (b->eof)
+            return 1;
+
+        return 0;
+    }
+
+
+    long wolfSSL_BIO_set_ssl(WOLFSSL_BIO* b, WOLFSSL* ssl, int closeF)
+    {
+        WOLFSSL_ENTER("BIO_set_ssl");
+        b->ssl   = ssl;
+        b->close = (byte)closeF;
+    /* add to ssl for bio free if SSL_free called before/instead of free_all? */
+
+        return 0;
+    }
+
+
+    WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD* method)
+    {
+        WOLFSSL_BIO* bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0,
+                                                DYNAMIC_TYPE_OPENSSL);
+        WOLFSSL_ENTER("BIO_new");
+        if (bio) {
+            bio->type   = method->type;
+            bio->close  = 0;
+            bio->eof    = 0;
+            bio->ssl    = NULL;
+            bio->mem    = NULL;
+            bio->memLen = 0;
+            bio->fd     = 0;
+            bio->prev   = NULL;
+            bio->next   = NULL;
+        }
+        return bio;
+    }
+
+
+    int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, const byte** p)
+    {
+        if (bio == NULL || p == NULL)
+            return SSL_FATAL_ERROR;
+
+        *p = bio->mem;
+
+        return bio->memLen;
+    }
+
+
+    WOLFSSL_BIO* wolfSSL_BIO_new_mem_buf(void* buf, int len)
+    {
+        WOLFSSL_BIO* bio = NULL;
+        if (buf == NULL)
+            return bio;
+
+        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
+        if (bio == NULL)
+            return bio;
+
+        bio->memLen = len;
+        bio->mem    = (byte*)XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL);
+        if (bio->mem == NULL) {
+            XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
+            return NULL;
+        }
+
+        XMEMCPY(bio->mem, buf, len);
+
+        return bio;
+    }
+
+
+#ifdef USE_WINDOWS_API
+    #define CloseSocket(s) closesocket(s)
+#elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
+    #define CloseSocket(s) closesocket(s)
+    extern int closesocket(int) ;
+#else
+    #define CloseSocket(s) close(s)
+#endif
+
+    int wolfSSL_BIO_free(WOLFSSL_BIO* bio)
+    {
+        /* unchain?, doesn't matter in goahead since from free all */
+        WOLFSSL_ENTER("BIO_free");
+        if (bio) {
+            if (bio->close) {
+                if (bio->ssl)
+                    wolfSSL_free(bio->ssl);
+                if (bio->fd)
+                    CloseSocket(bio->fd);
+            }
+            if (bio->mem)
+                XFREE(bio->mem, 0, DYNAMIC_TYPE_OPENSSL);
+            XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
+        }
+        return 0;
+    }
+
+
+    int wolfSSL_BIO_free_all(WOLFSSL_BIO* bio)
+    {
+        WOLFSSL_ENTER("BIO_free_all");
+        while (bio) {
+            WOLFSSL_BIO* next = bio->next;
+            wolfSSL_BIO_free(bio);
+            bio = next;
+        }
+        return 0;
+    }
+
+
+    int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
+    {
+        int  ret;
+        WOLFSSL* ssl = 0;
+        WOLFSSL_BIO* front = bio;
+
+        WOLFSSL_ENTER("BIO_read");
+        /* already got eof, again is error */
+        if (front->eof)
+            return SSL_FATAL_ERROR;
+
+        while(bio && ((ssl = bio->ssl) == 0) )
+            bio = bio->next;
+
+        if (ssl == 0) return BAD_FUNC_ARG;
+
+        ret = wolfSSL_read(ssl, buf, len);
+        if (ret == 0)
+            front->eof = 1;
+        else if (ret < 0) {
+            int err = wolfSSL_get_error(ssl, 0);
+            if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
+                front->eof = 1;
+        }
+        return ret;
+    }
+
+
+    int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
+    {
+        int  ret;
+        WOLFSSL* ssl = 0;
+        WOLFSSL_BIO* front = bio;
+
+        WOLFSSL_ENTER("BIO_write");
+        /* already got eof, again is error */
+        if (front->eof)
+            return SSL_FATAL_ERROR;
+
+        while(bio && ((ssl = bio->ssl) == 0) )
+            bio = bio->next;
+
+        if (ssl == 0) return BAD_FUNC_ARG;
+
+        ret = wolfSSL_write(ssl, data, len);
+        if (ret == 0)
+            front->eof = 1;
+        else if (ret < 0) {
+            int err = wolfSSL_get_error(ssl, 0);
+            if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
+                front->eof = 1;
+        }
+
+        return ret;
+    }
+
+
+    WOLFSSL_BIO* wolfSSL_BIO_push(WOLFSSL_BIO* top, WOLFSSL_BIO* append)
+    {
+        WOLFSSL_ENTER("BIO_push");
+        top->next    = append;
+        append->prev = top;
+
+        return top;
+    }
+
+
+    int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
+    {
+        /* for wolfSSL no flushing needed */
+        WOLFSSL_ENTER("BIO_flush");
+        (void)bio;
+        return 1;
+    }
+
+
+#endif /* OPENSSL_EXTRA || GOAHEAD_WS */
+
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+
+    void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
+                                                   void* userdata)
+    {
+        WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb_userdata");
+        ctx->userdata = userdata;
+    }
+
+
+    void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX* ctx, pem_password_cb cb)
+    {
+        WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb");
+        ctx->passwd_cb = cb;
+    }
+
+    int wolfSSL_num_locks(void)
+    {
+        return 0;
+    }
+
+    void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, int))
+    {
+        (void)f;
+    }
+
+    void wolfSSL_set_id_callback(unsigned long (*f)(void))
+    {
+        (void)f;
+    }
+
+    unsigned long wolfSSL_ERR_get_error(void)
+    {
+        /* TODO: */
+        return 0;
+    }
+
+#ifndef NO_MD5
+
+    int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER* type,
+                       const WOLFSSL_EVP_MD* md, const byte* salt,
+                       const byte* data, int sz, int count, byte* key, byte* iv)
+    {
+        int  keyLen = 0;
+        int  ivLen  = 0;
+        int  j;
+        int  keyLeft;
+        int  ivLeft;
+        int  keyOutput = 0;
+        byte digest[MD5_DIGEST_SIZE];
+    #ifdef WOLFSSL_SMALL_STACK
+        Md5* md5 = NULL;
+    #else
+        Md5  md5[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (md5 == NULL)
+            return 0;
+    #endif
+
+        WOLFSSL_ENTER("wolfSSL_EVP_BytesToKey");
+        wc_InitMd5(md5);
+
+        /* only support MD5 for now */
+        if (XSTRNCMP(md, "MD5", 3) != 0) return 0;
+
+        /* only support CBC DES and AES for now */
+        if (XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0) {
+            keyLen = DES_KEY_SIZE;
+            ivLen  = DES_IV_SIZE;
+        }
+        else if (XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0) {
+            keyLen = DES3_KEY_SIZE;
+            ivLen  = DES_IV_SIZE;
+        }
+        else if (XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0) {
+            keyLen = AES_128_KEY_SIZE;
+            ivLen  = AES_IV_SIZE;
+        }
+        else if (XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0) {
+            keyLen = AES_192_KEY_SIZE;
+            ivLen  = AES_IV_SIZE;
+        }
+        else if (XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0) {
+            keyLen = AES_256_KEY_SIZE;
+            ivLen  = AES_IV_SIZE;
+        }
+        else {
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+            return 0;
+        }
+
+        keyLeft   = keyLen;
+        ivLeft    = ivLen;
+
+        while (keyOutput < (keyLen + ivLen)) {
+            int digestLeft = MD5_DIGEST_SIZE;
+            /* D_(i - 1) */
+            if (keyOutput)                      /* first time D_0 is empty */
+                wc_Md5Update(md5, digest, MD5_DIGEST_SIZE);
+            /* data */
+            wc_Md5Update(md5, data, sz);
+            /* salt */
+            if (salt)
+                wc_Md5Update(md5, salt, EVP_SALT_SIZE);
+            wc_Md5Final(md5, digest);
+            /* count */
+            for (j = 1; j < count; j++) {
+                wc_Md5Update(md5, digest, MD5_DIGEST_SIZE);
+                wc_Md5Final(md5, digest);
+            }
+
+            if (keyLeft) {
+                int store = min(keyLeft, MD5_DIGEST_SIZE);
+                XMEMCPY(&key[keyLen - keyLeft], digest, store);
+
+                keyOutput  += store;
+                keyLeft    -= store;
+                digestLeft -= store;
+            }
+
+            if (ivLeft && digestLeft) {
+                int store = min(ivLeft, digestLeft);
+                if (iv != NULL)
+                    XMEMCPY(&iv[ivLen - ivLeft],
+                            &digest[MD5_DIGEST_SIZE - digestLeft], store);
+                keyOutput += store;
+                ivLeft    -= store;
+            }
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+
+        return keyOutput == (keyLen + ivLen) ? keyOutput : 0;
+    }
+
+#endif /* NO_MD5 */
+
+#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
+
+
+#ifdef OPENSSL_EXTRA
+
+    unsigned long wolfSSLeay(void)
+    {
+        return SSLEAY_VERSION_NUMBER;
+    }
+
+
+    const char* wolfSSLeay_version(int type)
+    {
+        static const char* version = "SSLeay wolfSSL compatibility";
+        (void)type;
+        return version;
+    }
+
+
+#ifndef NO_MD5
+    void wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5)
+    {
+        typedef char md5_test[sizeof(MD5_CTX) >= sizeof(Md5) ? 1 : -1];
+        (void)sizeof(md5_test);
+
+        WOLFSSL_ENTER("MD5_Init");
+        wc_InitMd5((Md5*)md5);
+    }
+
+
+    void wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input,
+                           unsigned long sz)
+    {
+        WOLFSSL_ENTER("wolfSSL_MD5_Update");
+        wc_Md5Update((Md5*)md5, (const byte*)input, (word32)sz);
+    }
+
+
+    void wolfSSL_MD5_Final(byte* input, WOLFSSL_MD5_CTX* md5)
+    {
+        WOLFSSL_ENTER("MD5_Final");
+        wc_Md5Final((Md5*)md5, input);
+    }
+#endif /* NO_MD5 */
+
+
+#ifndef NO_SHA
+    void wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha)
+    {
+        typedef char sha_test[sizeof(SHA_CTX) >= sizeof(Sha) ? 1 : -1];
+        (void)sizeof(sha_test);
+
+        WOLFSSL_ENTER("SHA_Init");
+        wc_InitSha((Sha*)sha);  /* OpenSSL compat, no ret */
+    }
+
+
+    void wolfSSL_SHA_Update(WOLFSSL_SHA_CTX* sha, const void* input,
+                           unsigned long sz)
+    {
+        WOLFSSL_ENTER("SHA_Update");
+        wc_ShaUpdate((Sha*)sha, (const byte*)input, (word32)sz);
+    }
+
+
+    void wolfSSL_SHA_Final(byte* input, WOLFSSL_SHA_CTX* sha)
+    {
+        WOLFSSL_ENTER("SHA_Final");
+        wc_ShaFinal((Sha*)sha, input);
+    }
+
+
+    void wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX* sha)
+    {
+        WOLFSSL_ENTER("SHA1_Init");
+        SHA_Init(sha);
+    }
+
+
+    void wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX* sha, const void* input,
+                            unsigned long sz)
+    {
+        WOLFSSL_ENTER("SHA1_Update");
+        SHA_Update(sha, input, sz);
+    }
+
+
+    void wolfSSL_SHA1_Final(byte* input, WOLFSSL_SHA_CTX* sha)
+    {
+        WOLFSSL_ENTER("SHA1_Final");
+        SHA_Final(input, sha);
+    }
+#endif /* NO_SHA */
+
+
+    void wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256)
+    {
+        typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(Sha256) ? 1 : -1];
+        (void)sizeof(sha_test);
+
+        WOLFSSL_ENTER("SHA256_Init");
+        wc_InitSha256((Sha256*)sha256);  /* OpenSSL compat, no error */
+    }
+
+
+    void wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX* sha, const void* input,
+                              unsigned long sz)
+    {
+        WOLFSSL_ENTER("SHA256_Update");
+        wc_Sha256Update((Sha256*)sha, (const byte*)input, (word32)sz);
+        /* OpenSSL compat, no error */
+    }
+
+
+    void wolfSSL_SHA256_Final(byte* input, WOLFSSL_SHA256_CTX* sha)
+    {
+        WOLFSSL_ENTER("SHA256_Final");
+        wc_Sha256Final((Sha256*)sha, input);
+        /* OpenSSL compat, no error */
+    }
+
+
+    #ifdef WOLFSSL_SHA384
+
+    void wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha)
+    {
+        typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(Sha384) ? 1 : -1];
+        (void)sizeof(sha_test);
+
+        WOLFSSL_ENTER("SHA384_Init");
+        wc_InitSha384((Sha384*)sha);   /* OpenSSL compat, no error */
+    }
+
+
+    void wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX* sha, const void* input,
+                           unsigned long sz)
+    {
+        WOLFSSL_ENTER("SHA384_Update");
+        wc_Sha384Update((Sha384*)sha, (const byte*)input, (word32)sz);
+        /* OpenSSL compat, no error */
+    }
+
+
+    void wolfSSL_SHA384_Final(byte* input, WOLFSSL_SHA384_CTX* sha)
+    {
+        WOLFSSL_ENTER("SHA384_Final");
+        wc_Sha384Final((Sha384*)sha, input);
+        /* OpenSSL compat, no error */
+    }
+
+    #endif /* WOLFSSL_SHA384 */
+
+
+   #ifdef WOLFSSL_SHA512
+
+    void wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha)
+    {
+        typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(Sha512) ? 1 : -1];
+        (void)sizeof(sha_test);
+
+        WOLFSSL_ENTER("SHA512_Init");
+        wc_InitSha512((Sha512*)sha);  /* OpenSSL compat, no error */
+    }
+
+
+    void wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha, const void* input,
+                           unsigned long sz)
+    {
+        WOLFSSL_ENTER("SHA512_Update");
+        wc_Sha512Update((Sha512*)sha, (const byte*)input, (word32)sz);
+        /* OpenSSL compat, no error */
+    }
+
+
+    void wolfSSL_SHA512_Final(byte* input, WOLFSSL_SHA512_CTX* sha)
+    {
+        WOLFSSL_ENTER("SHA512_Final");
+        wc_Sha512Final((Sha512*)sha, input);
+        /* OpenSSL compat, no error */
+    }
+
+    #endif /* WOLFSSL_SHA512 */
+
+
+    #ifndef NO_MD5
+
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void)
+    {
+        static const char* type = "MD5";
+        WOLFSSL_ENTER("EVP_md5");
+        return type;
+    }
+
+    #endif /* NO_MD5 */
+
+
+#ifndef NO_SHA
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void)
+    {
+        static const char* type = "SHA";
+        WOLFSSL_ENTER("EVP_sha1");
+        return type;
+    }
+#endif /* NO_SHA */
+
+
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void)
+    {
+        static const char* type = "SHA256";
+        WOLFSSL_ENTER("EVP_sha256");
+        return type;
+    }
+
+    #ifdef WOLFSSL_SHA384
+
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void)
+    {
+        static const char* type = "SHA384";
+        WOLFSSL_ENTER("EVP_sha384");
+        return type;
+    }
+
+    #endif /* WOLFSSL_SHA384 */
+
+    #ifdef WOLFSSL_SHA512
+
+    const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void)
+    {
+        static const char* type = "SHA512";
+        WOLFSSL_ENTER("EVP_sha512");
+        return type;
+    }
+
+    #endif /* WOLFSSL_SHA512 */
+
+
+    void wolfSSL_EVP_MD_CTX_init(WOLFSSL_EVP_MD_CTX* ctx)
+    {
+        WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_init");
+        (void)ctx;
+        /* do nothing */
+    }
+
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cbc");
+        return EVP_AES_128_CBC;
+    }
+
+
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cbc");
+        return EVP_AES_192_CBC;
+    }
+
+
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cbc");
+        return EVP_AES_256_CBC;
+    }
+
+
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ctr");
+        return EVP_AES_128_CTR;
+    }
+
+
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ctr");
+        return EVP_AES_192_CTR;
+    }
+
+
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ctr");
+        return EVP_AES_256_CTR;
+    }
+
+
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_des_cbc");
+        return EVP_DES_CBC;
+    }
+
+
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_cbc");
+        return EVP_DES_EDE3_CBC;
+    }
+
+
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void)
+    {
+        static const char* type = "ARC4";
+        WOLFSSL_ENTER("wolfSSL_EVP_rc4");
+        return type;
+    }
+
+#ifdef HAVE_IDEA
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_idea_cbc(void)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_idea_cbc");
+        return EVP_IDEA_CBC;
+    }
+#endif
+    const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void)
+    {
+        static const char* type = "NULL";
+        WOLFSSL_ENTER("wolfSSL_EVP_enc_null");
+        return type;
+    }
+
+
+    int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx)
+    {
+        WOLFSSL_ENTER("EVP_MD_CTX_cleanup");
+        (void)ctx;
+        return 0;
+    }
+
+
+
+    void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx)
+    {
+        WOLFSSL_ENTER("EVP_CIPHER_CTX_init");
+        if (ctx) {
+            ctx->cipherType = 0xff;   /* no init */
+            ctx->keyLen     = 0;
+            ctx->enc        = 1;      /* start in encrypt mode */
+        }
+    }
+
+
+    /* SSL_SUCCESS on ok */
+    int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx)
+    {
+        WOLFSSL_ENTER("EVP_CIPHER_CTX_cleanup");
+        if (ctx) {
+            ctx->cipherType = 0xff;  /* no more init */
+            ctx->keyLen     = 0;
+        }
+
+        return SSL_SUCCESS;
+    }
+
+
+    /* SSL_SUCCESS on ok */
+    int  wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
+                               const WOLFSSL_EVP_CIPHER* type, byte* key,
+                               byte* iv, int enc)
+    {
+#if defined(NO_AES) && defined(NO_DES3) && !defined(HAVE_IDEA)
+        (void)iv;
+        (void)enc;
+#else
+        int ret = 0;
+#endif
+
+        WOLFSSL_ENTER("wolfSSL_EVP_CipherInit");
+        if (ctx == NULL) {
+            WOLFSSL_MSG("no ctx");
+            return 0;   /* failure */
+        }
+
+        if (type == NULL && ctx->cipherType == 0xff) {
+            WOLFSSL_MSG("no type set");
+            return 0;   /* failure */
+        }
+
+#ifndef NO_AES
+        if (ctx->cipherType == AES_128_CBC_TYPE ||
+            (type && XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG(EVP_AES_128_CBC);
+            ctx->cipherType = AES_128_CBC_TYPE;
+            ctx->keyLen     = 16;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                                ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
+                if (ret != 0)
+                    return ret;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return ret;
+            }
+        }
+        else if (ctx->cipherType == AES_192_CBC_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG(EVP_AES_192_CBC);
+            ctx->cipherType = AES_192_CBC_TYPE;
+            ctx->keyLen     = 24;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                                ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
+                if (ret != 0)
+                    return ret;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return ret;
+            }
+        }
+        else if (ctx->cipherType == AES_256_CBC_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG(EVP_AES_256_CBC);
+            ctx->cipherType = AES_256_CBC_TYPE;
+            ctx->keyLen     = 32;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                                ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
+                if (ret != 0)
+                    return ret;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return ret;
+            }
+        }
+#ifdef WOLFSSL_AES_COUNTER
+        else if (ctx->cipherType == AES_128_CTR_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_128_CTR, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG(EVP_AES_128_CTR);
+            ctx->cipherType = AES_128_CTR_TYPE;
+            ctx->keyLen     = 16;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                                AES_ENCRYPTION);
+                if (ret != 0)
+                    return ret;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return ret;
+            }
+        }
+        else if (ctx->cipherType == AES_192_CTR_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_192_CTR, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG(EVP_AES_192_CTR);
+            ctx->cipherType = AES_192_CTR_TYPE;
+            ctx->keyLen     = 24;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                                AES_ENCRYPTION);
+                if (ret != 0)
+                    return ret;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return ret;
+            }
+        }
+        else if (ctx->cipherType == AES_256_CTR_TYPE ||
+                 (type && XSTRNCMP(type, EVP_AES_256_CTR, EVP_AES_SIZE) == 0)) {
+            WOLFSSL_MSG(EVP_AES_256_CTR);
+            ctx->cipherType = AES_256_CTR_TYPE;
+            ctx->keyLen     = 32;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv,
+                                AES_ENCRYPTION);
+                if (ret != 0)
+                    return ret;
+            }
+            if (iv && key == NULL) {
+                ret = wc_AesSetIV(&ctx->cipher.aes, iv);
+                if (ret != 0)
+                    return ret;
+            }
+        }
+#endif /* WOLFSSL_AES_CTR */
+#endif /* NO_AES */
+
+#ifndef NO_DES3
+        else if (ctx->cipherType == DES_CBC_TYPE ||
+                 (type && XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0)) {
+            WOLFSSL_MSG(EVP_DES_CBC);
+            ctx->cipherType = DES_CBC_TYPE;
+            ctx->keyLen     = 8;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_Des_SetKey(&ctx->cipher.des, key, iv,
+                          ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
+                if (ret != 0)
+                    return ret;
+            }
+
+            if (iv && key == NULL)
+                wc_Des_SetIV(&ctx->cipher.des, iv);
+        }
+        else if (ctx->cipherType == DES_EDE3_CBC_TYPE ||
+                 (type &&
+                  XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)) {
+            WOLFSSL_MSG(EVP_DES_EDE3_CBC);
+            ctx->cipherType = DES_EDE3_CBC_TYPE;
+            ctx->keyLen     = 24;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_Des3_SetKey(&ctx->cipher.des3, key, iv,
+                          ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION);
+                if (ret != 0)
+                    return ret;
+            }
+
+            if (iv && key == NULL) {
+                ret = wc_Des3_SetIV(&ctx->cipher.des3, iv);
+                if (ret != 0)
+                    return ret;
+            }
+        }
+#endif /* NO_DES3 */
+#ifndef NO_RC4
+        else if (ctx->cipherType == ARC4_TYPE || (type &&
+                                     XSTRNCMP(type, "ARC4", 4) == 0)) {
+            WOLFSSL_MSG("ARC4");
+            ctx->cipherType = ARC4_TYPE;
+            if (ctx->keyLen == 0)  /* user may have already set */
+                ctx->keyLen = 16;  /* default to 128 */
+            if (key)
+                wc_Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen);
+        }
+#endif /* NO_RC4 */
+#ifdef HAVE_IDEA
+        else if (ctx->cipherType == IDEA_CBC_TYPE ||
+                 (type && XSTRNCMP(type, EVP_IDEA_CBC, EVP_IDEA_SIZE) == 0)) {
+            WOLFSSL_MSG(EVP_IDEA_CBC);
+            ctx->cipherType = IDEA_CBC_TYPE;
+            ctx->keyLen     = IDEA_KEY_SIZE;
+            if (enc == 0 || enc == 1)
+                ctx->enc = enc ? 1 : 0;
+            if (key) {
+                ret = wc_IdeaSetKey(&ctx->cipher.idea, key, ctx->keyLen, iv,
+                                    ctx->enc ? IDEA_ENCRYPTION : IDEA_DECRYPTION);
+                if (ret != 0)
+                    return ret;
+            }
+
+            if (iv && key == NULL)
+                wc_IdeaSetIV(&ctx->cipher.idea, iv);
+        }
+#endif /* HAVE_IDEA */
+        else if (ctx->cipherType == NULL_CIPHER_TYPE || (type &&
+                                     XSTRNCMP(type, "NULL", 4) == 0)) {
+            WOLFSSL_MSG("NULL cipher");
+            ctx->cipherType = NULL_CIPHER_TYPE;
+            ctx->keyLen = 0;
+        }
+        else
+            return 0;   /* failure */
+
+
+        return SSL_SUCCESS;
+    }
+
+
+    /* SSL_SUCCESS on ok */
+    int wolfSSL_EVP_CIPHER_CTX_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_key_length");
+        if (ctx)
+            return ctx->keyLen;
+
+        return 0;   /* failure */
+    }
+
+
+    /* SSL_SUCCESS on ok */
+    int wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx,
+                                             int keylen)
+    {
+        WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_set_key_length");
+        if (ctx)
+            ctx->keyLen = keylen;
+        else
+            return 0;  /* failure */
+
+        return SSL_SUCCESS;
+    }
+
+
+    /* SSL_SUCCESS on ok */
+    int wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* dst, byte* src,
+                          word32 len)
+    {
+        int ret = 0;
+        WOLFSSL_ENTER("wolfSSL_EVP_Cipher");
+
+        if (ctx == NULL || dst == NULL || src == NULL) {
+            WOLFSSL_MSG("Bad function argument");
+            return 0;  /* failure */
+        }
+
+        if (ctx->cipherType == 0xff) {
+            WOLFSSL_MSG("no init");
+            return 0;  /* failure */
+        }
+
+        switch (ctx->cipherType) {
+
+#ifndef NO_AES
+            case AES_128_CBC_TYPE :
+            case AES_192_CBC_TYPE :
+            case AES_256_CBC_TYPE :
+                WOLFSSL_MSG("AES CBC");
+                if (ctx->enc)
+                    ret = wc_AesCbcEncrypt(&ctx->cipher.aes, dst, src, len);
+                else
+                    ret = wc_AesCbcDecrypt(&ctx->cipher.aes, dst, src, len);
+                break;
+
+#ifdef WOLFSSL_AES_COUNTER
+            case AES_128_CTR_TYPE :
+            case AES_192_CTR_TYPE :
+            case AES_256_CTR_TYPE :
+                    WOLFSSL_MSG("AES CTR");
+                    wc_AesCtrEncrypt(&ctx->cipher.aes, dst, src, len);
+                break;
+#endif
+#endif /* NO_AES */
+
+#ifndef NO_DES3
+            case DES_CBC_TYPE :
+                if (ctx->enc)
+                    wc_Des_CbcEncrypt(&ctx->cipher.des, dst, src, len);
+                else
+                    wc_Des_CbcDecrypt(&ctx->cipher.des, dst, src, len);
+                break;
+
+            case DES_EDE3_CBC_TYPE :
+                if (ctx->enc)
+                    ret = wc_Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len);
+                else
+                    ret = wc_Des3_CbcDecrypt(&ctx->cipher.des3, dst, src, len);
+                break;
+#endif
+
+#ifndef NO_RC4
+            case ARC4_TYPE :
+                wc_Arc4Process(&ctx->cipher.arc4, dst, src, len);
+                break;
+#endif
+
+#ifdef HAVE_IDEA
+            case IDEA_CBC_TYPE :
+                if (ctx->enc)
+                    wc_IdeaCbcEncrypt(&ctx->cipher.idea, dst, src, len);
+                else
+                    wc_IdeaCbcDecrypt(&ctx->cipher.idea, dst, src, len);
+                break;
+#endif
+            case NULL_CIPHER_TYPE :
+                XMEMCPY(dst, src, len);
+                break;
+
+            default: {
+                WOLFSSL_MSG("bad type");
+                return 0;  /* failure */
+            }
+        }
+
+        if (ret != 0) {
+            WOLFSSL_MSG("wolfSSL_EVP_Cipher failure");
+            return 0;  /* failuer */
+        }
+
+        WOLFSSL_MSG("wolfSSL_EVP_Cipher success");
+        return SSL_SUCCESS;  /* success */
+    }
+
+
+    /* store for external read of iv, SSL_SUCCESS on success */
+    int  wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
+    {
+        WOLFSSL_ENTER("wolfSSL_StoreExternalIV");
+
+        if (ctx == NULL) {
+            WOLFSSL_MSG("Bad function argument");
+            return SSL_FATAL_ERROR;
+        }
+
+        switch (ctx->cipherType) {
+
+#ifndef NO_AES
+            case AES_128_CBC_TYPE :
+            case AES_192_CBC_TYPE :
+            case AES_256_CBC_TYPE :
+                WOLFSSL_MSG("AES CBC");
+                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
+                break;
+
+#ifdef WOLFSSL_AES_COUNTER
+            case AES_128_CTR_TYPE :
+            case AES_192_CTR_TYPE :
+            case AES_256_CTR_TYPE :
+                WOLFSSL_MSG("AES CTR");
+                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
+                break;
+#endif /* WOLFSSL_AES_COUNTER */
+
+#endif /* NO_AES */
+
+#ifndef NO_DES3
+            case DES_CBC_TYPE :
+                WOLFSSL_MSG("DES CBC");
+                XMEMCPY(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
+                break;
+
+            case DES_EDE3_CBC_TYPE :
+                WOLFSSL_MSG("DES EDE3 CBC");
+                XMEMCPY(ctx->iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
+                break;
+#endif
+
+#ifdef HAVE_IDEA
+            case IDEA_CBC_TYPE :
+                WOLFSSL_MSG("IDEA CBC");
+                XMEMCPY(ctx->iv, &ctx->cipher.idea.reg, IDEA_BLOCK_SIZE);
+                break;
+#endif
+            case ARC4_TYPE :
+                WOLFSSL_MSG("ARC4");
+                break;
+
+            case NULL_CIPHER_TYPE :
+                WOLFSSL_MSG("NULL");
+                break;
+
+            default: {
+                WOLFSSL_MSG("bad type");
+                return SSL_FATAL_ERROR;
+            }
+        }
+        return SSL_SUCCESS;
+    }
+
+
+    /* set internal IV from external, SSL_SUCCESS on success */
+    int  wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
+    {
+
+        WOLFSSL_ENTER("wolfSSL_SetInternalIV");
+
+        if (ctx == NULL) {
+            WOLFSSL_MSG("Bad function argument");
+            return SSL_FATAL_ERROR;
+        }
+
+        switch (ctx->cipherType) {
+
+#ifndef NO_AES
+            case AES_128_CBC_TYPE :
+            case AES_192_CBC_TYPE :
+            case AES_256_CBC_TYPE :
+                WOLFSSL_MSG("AES CBC");
+                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
+                break;
+
+#ifdef WOLFSSL_AES_COUNTER
+            case AES_128_CTR_TYPE :
+            case AES_192_CTR_TYPE :
+            case AES_256_CTR_TYPE :
+                WOLFSSL_MSG("AES CTR");
+                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
+                break;
+#endif
+
+#endif /* NO_AES */
+
+#ifndef NO_DES3
+            case DES_CBC_TYPE :
+                WOLFSSL_MSG("DES CBC");
+                XMEMCPY(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
+                break;
+
+            case DES_EDE3_CBC_TYPE :
+                WOLFSSL_MSG("DES EDE3 CBC");
+                XMEMCPY(&ctx->cipher.des3.reg, ctx->iv, DES_BLOCK_SIZE);
+                break;
+#endif
+
+#ifdef HAVE_IDEA
+            case IDEA_CBC_TYPE :
+                WOLFSSL_MSG("IDEA CBC");
+                XMEMCPY(&ctx->cipher.idea.reg, ctx->iv, IDEA_BLOCK_SIZE);
+                break;
+#endif
+            case ARC4_TYPE :
+                WOLFSSL_MSG("ARC4");
+                break;
+
+            case NULL_CIPHER_TYPE :
+                WOLFSSL_MSG("NULL");
+                break;
+
+            default: {
+                WOLFSSL_MSG("bad type");
+                return SSL_FATAL_ERROR;
+            }
+        }
+        return SSL_SUCCESS;
+    }
+
+
+    /* SSL_SUCCESS on ok */
+    int wolfSSL_EVP_DigestInit(WOLFSSL_EVP_MD_CTX* ctx,
+                               const WOLFSSL_EVP_MD* type)
+    {
+        WOLFSSL_ENTER("EVP_DigestInit");
+        if (XSTRNCMP(type, "SHA256", 6) == 0) {
+             ctx->macType = SHA256;
+             wolfSSL_SHA256_Init((SHA256_CTX*)&ctx->hash);
+        }
+    #ifdef WOLFSSL_SHA384
+        else if (XSTRNCMP(type, "SHA384", 6) == 0) {
+             ctx->macType = SHA384;
+             wolfSSL_SHA384_Init((SHA384_CTX*)&ctx->hash);
+        }
+    #endif
+    #ifdef WOLFSSL_SHA512
+        else if (XSTRNCMP(type, "SHA512", 6) == 0) {
+             ctx->macType = SHA512;
+             wolfSSL_SHA512_Init((SHA512_CTX*)&ctx->hash);
+        }
+    #endif
+    #ifndef NO_MD5
+        else if (XSTRNCMP(type, "MD5", 3) == 0) {
+            ctx->macType = MD5;
+            wolfSSL_MD5_Init((MD5_CTX*)&ctx->hash);
+        }
+    #endif
+    #ifndef NO_SHA
+        /* has to be last since would pick or 256, 384, or 512 too */
+        else if (XSTRNCMP(type, "SHA", 3) == 0) {
+             ctx->macType = SHA;
+             wolfSSL_SHA_Init((SHA_CTX*)&ctx->hash);
+        }
+    #endif /* NO_SHA */
+        else
+             return BAD_FUNC_ARG;
+
+        return SSL_SUCCESS;
+    }
+
+
+    /* SSL_SUCCESS on ok */
+    int wolfSSL_EVP_DigestUpdate(WOLFSSL_EVP_MD_CTX* ctx, const void* data,
+                                unsigned long sz)
+    {
+        WOLFSSL_ENTER("EVP_DigestUpdate");
+
+        switch (ctx->macType) {
+#ifndef NO_MD5
+            case MD5:
+                wolfSSL_MD5_Update((MD5_CTX*)&ctx->hash, data,
+                                  (unsigned long)sz);
+                break;
+#endif
+#ifndef NO_SHA
+            case SHA:
+                wolfSSL_SHA_Update((SHA_CTX*)&ctx->hash, data,
+                                  (unsigned long)sz);
+                break;
+#endif
+#ifndef NO_SHA256
+            case SHA256:
+                wolfSSL_SHA256_Update((SHA256_CTX*)&ctx->hash, data,
+                                     (unsigned long)sz);
+                break;
+#endif
+#ifdef WOLFSSL_SHA384
+            case SHA384:
+                wolfSSL_SHA384_Update((SHA384_CTX*)&ctx->hash, data,
+                                     (unsigned long)sz);
+                break;
+#endif
+#ifdef WOLFSSL_SHA512
+            case SHA512:
+                wolfSSL_SHA512_Update((SHA512_CTX*)&ctx->hash, data,
+                                     (unsigned long)sz);
+                break;
+#endif
+            default:
+                return BAD_FUNC_ARG;
+        }
+
+        return SSL_SUCCESS;
+    }
+
+
+    /* SSL_SUCCESS on ok */
+    int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
+                               unsigned int* s)
+    {
+        WOLFSSL_ENTER("EVP_DigestFinal");
+        switch (ctx->macType) {
+#ifndef NO_MD5
+            case MD5:
+                wolfSSL_MD5_Final(md, (MD5_CTX*)&ctx->hash);
+                if (s) *s = MD5_DIGEST_SIZE;
+                break;
+#endif
+#ifndef NO_SHA
+            case SHA:
+                wolfSSL_SHA_Final(md, (SHA_CTX*)&ctx->hash);
+                if (s) *s = SHA_DIGEST_SIZE;
+                break;
+#endif
+#ifndef NO_SHA256
+            case SHA256:
+                wolfSSL_SHA256_Final(md, (SHA256_CTX*)&ctx->hash);
+                if (s) *s = SHA256_DIGEST_SIZE;
+                break;
+#endif
+#ifdef WOLFSSL_SHA384
+            case SHA384:
+                wolfSSL_SHA384_Final(md, (SHA384_CTX*)&ctx->hash);
+                if (s) *s = SHA384_DIGEST_SIZE;
+                break;
+#endif
+#ifdef WOLFSSL_SHA512
+            case SHA512:
+                wolfSSL_SHA512_Final(md, (SHA512_CTX*)&ctx->hash);
+                if (s) *s = SHA512_DIGEST_SIZE;
+                break;
+#endif
+            default:
+                return BAD_FUNC_ARG;
+        }
+
+        return SSL_SUCCESS;
+    }
+
+
+    /* SSL_SUCCESS on ok */
+    int wolfSSL_EVP_DigestFinal_ex(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
+                                   unsigned int* s)
+    {
+        WOLFSSL_ENTER("EVP_DigestFinal_ex");
+        return EVP_DigestFinal(ctx, md, s);
+    }
+
+
+    unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const void* key,
+                                int key_len, const unsigned char* d, int n,
+                                unsigned char* md, unsigned int* md_len)
+    {
+        int type;
+        unsigned char* ret = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+        Hmac* hmac = NULL;
+#else
+        Hmac  hmac[1];
+#endif
+
+        WOLFSSL_ENTER("HMAC");
+        if (!md)
+            return NULL;  /* no static buffer support */
+
+        if (XSTRNCMP(evp_md, "MD5", 3) == 0)
+            type = MD5;
+        else if (XSTRNCMP(evp_md, "SHA", 3) == 0)
+            type = SHA;
+        else
+            return NULL;
+
+    #ifdef WOLFSSL_SMALL_STACK
+        hmac = (Hmac*)XMALLOC(sizeof(Hmac), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (hmac == NULL)
+            return NULL;
+    #endif
+
+        if (wc_HmacSetKey(hmac, type, (const byte*)key, key_len) == 0)
+            if (wc_HmacUpdate(hmac, d, n) == 0)
+                if (wc_HmacFinal(hmac, md) == 0) {
+                    if (md_len)
+                        *md_len = (type == MD5) ? (int)MD5_DIGEST_SIZE
+                                                : (int)SHA_DIGEST_SIZE;
+                    ret = md;
+                }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+
+        return ret;
+    }
+
+    void wolfSSL_ERR_clear_error(void)
+    {
+        /* TODO: */
+    }
+
+
+    int wolfSSL_RAND_status(void)
+    {
+        return SSL_SUCCESS;  /* wolfCrypt provides enough seed internally */
+    }
+
+
+
+    void wolfSSL_RAND_add(const void* add, int len, double entropy)
+    {
+        (void)add;
+        (void)len;
+        (void)entropy;
+
+        /* wolfSSL seeds/adds internally, use explicit RNG if you want
+           to take control */
+    }
+
+
+#ifndef NO_DES3
+    /* SSL_SUCCESS on ok */
+    int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key,
+                              WOLFSSL_DES_key_schedule* schedule)
+    {
+        WOLFSSL_ENTER("DES_key_sched");
+        XMEMCPY(schedule, key, sizeof(const_DES_cblock));
+        return SSL_SUCCESS;
+    }
+
+
+    void wolfSSL_DES_cbc_encrypt(const unsigned char* input,
+                                 unsigned char* output, long length,
+                                 WOLFSSL_DES_key_schedule* schedule,
+                                 WOLFSSL_DES_cblock* ivec, int enc)
+    {
+        Des myDes;
+
+        WOLFSSL_ENTER("DES_cbc_encrypt");
+
+        /* OpenSSL compat, no ret */
+        wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
+
+        if (enc)
+            wc_Des_CbcEncrypt(&myDes, output, input, (word32)length);
+        else
+            wc_Des_CbcDecrypt(&myDes, output, input, (word32)length);
+    }
+
+
+    /* correctly sets ivec for next call */
+    void wolfSSL_DES_ncbc_encrypt(const unsigned char* input,
+                     unsigned char* output, long length,
+                     WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
+                     int enc)
+    {
+        Des myDes;
+
+        WOLFSSL_ENTER("DES_ncbc_encrypt");
+
+        /* OpenSSL compat, no ret */
+        wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc);
+
+        if (enc)
+            wc_Des_CbcEncrypt(&myDes, output, input, (word32)length);
+        else
+            wc_Des_CbcDecrypt(&myDes, output, input, (word32)length);
+
+        XMEMCPY(ivec, output + length - sizeof(DES_cblock), sizeof(DES_cblock));
+    }
+
+#endif /* NO_DES3 */
+
+
+    void wolfSSL_ERR_free_strings(void)
+    {
+        /* handled internally */
+    }
+
+
+    void wolfSSL_ERR_remove_state(unsigned long state)
+    {
+        /* TODO: GetErrors().Remove(); */
+        (void)state;
+    }
+
+
+    void wolfSSL_EVP_cleanup(void)
+    {
+        /* nothing to do here */
+    }
+
+
+    void wolfSSL_cleanup_all_ex_data(void)
+    {
+        /* nothing to do here */
+    }
+
+
+    int wolfSSL_clear(WOLFSSL* ssl)
+    {
+        (void)ssl;
+        /* TODO: GetErrors().Remove(); */
+        return SSL_SUCCESS;
+    }
+
+
+    long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t)
+    {
+        word32 tmptime;
+        if (!ses || t < 0)
+            return BAD_FUNC_ARG;
+
+        tmptime = t & 0xFFFFFFFF;
+
+        ses->timeout = tmptime;
+
+        return SSL_SUCCESS;
+    }
+
+
+    long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode)
+    {
+        /* SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
+
+        WOLFSSL_ENTER("SSL_CTX_set_mode");
+        if (mode == SSL_MODE_ENABLE_PARTIAL_WRITE)
+            ctx->partialWrite = 1;
+
+        return mode;
+    }
+
+
+    long wolfSSL_SSL_get_mode(WOLFSSL* ssl)
+    {
+        /* TODO: */
+        (void)ssl;
+        return 0;
+    }
+
+
+    long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx)
+    {
+        /* TODO: */
+        (void)ctx;
+        return 0;
+    }
+
+
+    void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m)
+    {
+        /* TODO: maybe? */
+        (void)ctx;
+        (void)m;
+    }
+
+
+    int wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX* ctx,
+                                           const unsigned char* sid_ctx,
+                                           unsigned int sid_ctx_len)
+    {
+        /* No application specific context needed for wolfSSL */
+        (void)ctx;
+        (void)sid_ctx;
+        (void)sid_ctx_len;
+        return SSL_SUCCESS;
+    }
+
+
+    long wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX* ctx)
+    {
+        /* TODO: maybe? */
+        (void)ctx;
+        return (~0);
+    }
+
+    unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
+                                                  const char** data, int *flags)
+    {
+        /* Not implemented */
+        (void)file;
+        (void)line;
+        (void)data;
+        (void)flags;
+        return 0;
+    }
+
+#endif /* OPENSSL_EXTRA */
+
+
+#if defined(KEEP_PEER_CERT)
+
+    WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl)
+    {
+        WOLFSSL_ENTER("SSL_get_peer_certificate");
+        if (ssl->peerCert.issuer.sz)
+            return &ssl->peerCert;
+        else
+            return 0;
+    }
+
+#endif /* KEEP_PEER_CERT */
+
+
+#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || defined(OPENSSSL_EXTRA)
+
+/* user externally called free X509, if dynamic go ahead with free, otherwise
+ * don't */
+static void ExternalFreeX509(WOLFSSL_X509* x509)
+{
+    WOLFSSL_ENTER("ExternalFreeX509");
+    if (x509) {
+        if (x509->dynamicMemory) {
+            FreeX509(x509);
+        } else {
+            WOLFSSL_MSG("free called on non dynamic object, not freeing");
+        }
+    }
+}
+
+#endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSSL_EXTRA */
+
+#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
+
+    void wolfSSL_FreeX509(WOLFSSL_X509* x509)
+    {
+        WOLFSSL_ENTER("wolfSSL_FreeX509");
+        ExternalFreeX509(x509);
+    }
+
+
+    /* return the next, if any, altname from the peer cert */
+    char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
+    {
+        char* ret = NULL;
+        WOLFSSL_ENTER("wolfSSL_X509_get_next_altname");
+
+        /* don't have any to work with */
+        if (cert == NULL || cert->altNames == NULL)
+            return NULL;
+
+        /* already went through them */
+        if (cert->altNamesNext == NULL)
+            return NULL;
+
+        ret = cert->altNamesNext->name;
+        cert->altNamesNext = cert->altNamesNext->next;
+
+        return ret;
+    }
+
+
+    WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
+    {
+        WOLFSSL_ENTER("X509_get_issuer_name");
+        if(cert)
+            return &cert->issuer;
+        return NULL;
+    }
+
+
+    WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_get_subject_name");
+        if(cert)
+            return &cert->subject;
+        return NULL;
+    }
+
+
+    int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
+    {
+        int isCA = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_get_isCA");
+
+        if (x509 != NULL)
+            isCA = x509->isCa;
+
+        WOLFSSL_LEAVE("wolfSSL_X509_get_isCA", isCA);
+
+        return isCA;
+    }
+
+
+#ifdef OPENSSL_EXTRA
+    int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509* x509, int nid)
+    {
+        int isSet = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_ext_isSet_by_NID");
+
+        if (x509 != NULL) {
+            switch (nid) {
+                case BASIC_CA_OID: isSet = x509->basicConstSet; break;
+                case ALT_NAMES_OID: isSet = x509->subjAltNameSet; break;
+                case AUTH_KEY_OID: isSet = x509->authKeyIdSet; break;
+                case SUBJ_KEY_OID: isSet = x509->subjKeyIdSet; break;
+                case KEY_USAGE_OID: isSet = x509->keyUsageSet; break;
+                #ifdef WOLFSSL_SEP
+                    case CERT_POLICY_OID: isSet = x509->certPolicySet; break;
+                #endif /* WOLFSSL_SEP */
+            }
+        }
+
+        WOLFSSL_LEAVE("wolfSSL_X509_ext_isSet_by_NID", isSet);
+
+        return isSet;
+    }
+
+
+    int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509* x509, int nid)
+    {
+        int crit = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_ext_get_critical_by_NID");
+
+        if (x509 != NULL) {
+            switch (nid) {
+                case BASIC_CA_OID: crit = x509->basicConstCrit; break;
+                case ALT_NAMES_OID: crit = x509->subjAltNameCrit; break;
+                case AUTH_KEY_OID: crit = x509->authKeyIdCrit; break;
+                case SUBJ_KEY_OID: crit = x509->subjKeyIdCrit; break;
+                case KEY_USAGE_OID: crit = x509->keyUsageCrit; break;
+                #ifdef WOLFSSL_SEP
+                    case CERT_POLICY_OID: crit = x509->certPolicyCrit; break;
+                #endif /* WOLFSSL_SEP */
+            }
+        }
+
+        WOLFSSL_LEAVE("wolfSSL_X509_ext_get_critical_by_NID", crit);
+
+        return crit;
+    }
+
+
+    int wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509* x509)
+    {
+        int isSet = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_get_isSet_pathLength");
+
+        if (x509 != NULL)
+            isSet = x509->basicConstPlSet;
+
+        WOLFSSL_LEAVE("wolfSSL_X509_get_isSet_pathLength", isSet);
+
+        return isSet;
+    }
+
+
+    word32 wolfSSL_X509_get_pathLength(WOLFSSL_X509* x509)
+    {
+        word32 pathLength = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_get_pathLength");
+
+        if (x509 != NULL)
+            pathLength = x509->pathLength;
+
+        WOLFSSL_LEAVE("wolfSSL_X509_get_pathLength", pathLength);
+
+        return pathLength;
+    }
+
+
+    unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509* x509)
+    {
+        word16 usage = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_get_keyUsage");
+
+        if (x509 != NULL)
+            usage = x509->keyUsage;
+
+        WOLFSSL_LEAVE("wolfSSL_X509_get_keyUsage", usage);
+
+        return usage;
+    }
+
+
+    byte* wolfSSL_X509_get_authorityKeyID(WOLFSSL_X509* x509,
+                                          byte* dst, int* dstLen)
+    {
+        byte *id = NULL;
+        int copySz = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_get_authorityKeyID");
+
+        if (x509 != NULL) {
+            if (x509->authKeyIdSet) {
+                copySz = min(dstLen != NULL ? *dstLen : 0,
+                             (int)x509->authKeyIdSz);
+                id = x509->authKeyId;
+            }
+
+            if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
+                XMEMCPY(dst, id, copySz);
+                id = dst;
+                *dstLen = copySz;
+            }
+        }
+
+        WOLFSSL_LEAVE("wolfSSL_X509_get_authorityKeyID", copySz);
+
+        return id;
+    }
+
+
+    byte* wolfSSL_X509_get_subjectKeyID(WOLFSSL_X509* x509,
+                                        byte* dst, int* dstLen)
+    {
+        byte *id = NULL;
+        int copySz = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_get_subjectKeyID");
+
+        if (x509 != NULL) {
+            if (x509->subjKeyIdSet) {
+                copySz = min(dstLen != NULL ? *dstLen : 0,
+                                                        (int)x509->subjKeyIdSz);
+                id = x509->subjKeyId;
+            }
+
+            if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
+                XMEMCPY(dst, id, copySz);
+                id = dst;
+                *dstLen = copySz;
+            }
+        }
+
+        WOLFSSL_LEAVE("wolfSSL_X509_get_subjectKeyID", copySz);
+
+        return id;
+    }
+
+
+    int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME* name)
+    {
+        int count = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_entry_count");
+
+        if (name != NULL)
+            count = name->fullName.entryCount;
+
+        WOLFSSL_LEAVE("wolfSSL_X509_NAME_entry_count", count);
+        return count;
+    }
+
+
+    int wolfSSL_X509_NAME_get_text_by_NID(WOLFSSL_X509_NAME* name,
+                                          int nid, char* buf, int len)
+    {
+        char *text = NULL;
+        int textSz = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_get_text_by_NID");
+
+        switch (nid) {
+            case ASN_COMMON_NAME:
+                text = name->fullName.fullName + name->fullName.cnIdx;
+                textSz = name->fullName.cnLen;
+                break;
+            case ASN_SUR_NAME:
+                text = name->fullName.fullName + name->fullName.snIdx;
+                textSz = name->fullName.snLen;
+                break;
+            case ASN_SERIAL_NUMBER:
+                text = name->fullName.fullName + name->fullName.serialIdx;
+                textSz = name->fullName.serialLen;
+                break;
+            case ASN_COUNTRY_NAME:
+                text = name->fullName.fullName + name->fullName.cIdx;
+                textSz = name->fullName.cLen;
+                break;
+            case ASN_LOCALITY_NAME:
+                text = name->fullName.fullName + name->fullName.lIdx;
+                textSz = name->fullName.lLen;
+                break;
+            case ASN_STATE_NAME:
+                text = name->fullName.fullName + name->fullName.stIdx;
+                textSz = name->fullName.stLen;
+                break;
+            case ASN_ORG_NAME:
+                text = name->fullName.fullName + name->fullName.oIdx;
+                textSz = name->fullName.oLen;
+                break;
+            case ASN_ORGUNIT_NAME:
+                text = name->fullName.fullName + name->fullName.ouIdx;
+                textSz = name->fullName.ouLen;
+                break;
+            default:
+                break;
+        }
+
+        if (buf != NULL && text != NULL) {
+            textSz = min(textSz, len);
+            XMEMCPY(buf, text, textSz);
+            buf[textSz] = '\0';
+        }
+
+        WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_text_by_NID", textSz);
+        return textSz;
+    }
+#endif
+
+
+    /* copy name into in buffer, at most sz bytes, if buffer is null will
+       malloc buffer, call responsible for freeing                     */
+    char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
+    {
+        int copySz = min(sz, name->sz);
+
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_oneline");
+        if (!name->sz) return in;
+
+        if (!in) {
+            in = (char*)XMALLOC(name->sz, 0, DYNAMIC_TYPE_OPENSSL);
+            if (!in ) return in;
+            copySz = name->sz;
+        }
+
+        if (copySz == 0)
+            return in;
+
+        XMEMCPY(in, name->name, copySz - 1);
+        in[copySz - 1] = 0;
+
+        return in;
+    }
+
+
+    int wolfSSL_X509_get_signature_type(WOLFSSL_X509* x509)
+    {
+        int type = 0;
+
+        WOLFSSL_ENTER("wolfSSL_X509_get_signature_type");
+
+        if (x509 != NULL)
+            type = x509->sigOID;
+
+        return type;
+    }
+
+
+    int wolfSSL_X509_get_signature(WOLFSSL_X509* x509,
+                                                 unsigned char* buf, int* bufSz)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_get_signature");
+        if (x509 == NULL || bufSz == NULL || *bufSz < (int)x509->sig.length)
+            return SSL_FATAL_ERROR;
+
+        if (buf != NULL)
+            XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
+        *bufSz = x509->sig.length;
+
+        return SSL_SUCCESS;
+    }
+
+
+    /* write X509 serial number in unsigned binary to buffer
+       buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
+       return SSL_SUCCESS on success */
+    int wolfSSL_X509_get_serial_number(WOLFSSL_X509* x509,
+                                       byte* in, int* inOutSz)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_get_serial_number");
+        if (x509 == NULL || in == NULL ||
+                                   inOutSz == NULL || *inOutSz < x509->serialSz)
+            return BAD_FUNC_ARG;
+
+        XMEMCPY(in, x509->serial, x509->serialSz);
+        *inOutSz = x509->serialSz;
+
+        return SSL_SUCCESS;
+    }
+
+
+    const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_get_der");
+
+        if (x509 == NULL || outSz == NULL)
+            return NULL;
+
+        *outSz = (int)x509->derCert.length;
+        return x509->derCert.buffer;
+    }
+
+
+    int wolfSSL_X509_version(WOLFSSL_X509* x509)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_version");
+
+        if (x509 == NULL)
+            return 0;
+
+        return x509->version;
+    }
+
+
+    const byte* wolfSSL_X509_notBefore(WOLFSSL_X509* x509)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_notBefore");
+
+        if (x509 == NULL)
+            return NULL;
+
+        return x509->notBefore;
+    }
+
+
+    const byte* wolfSSL_X509_notAfter(WOLFSSL_X509* x509)
+    {
+        WOLFSSL_ENTER("wolfSSL_X509_notAfter");
+
+        if (x509 == NULL)
+            return NULL;
+
+        return x509->notAfter;
+    }
+
+
+#ifdef WOLFSSL_SEP
+
+/* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
+   malloc buffer, call responsible for freeing. Actual size returned in
+   *inOutSz. Requires inOutSz be non-null */
+byte* wolfSSL_X509_get_device_type(WOLFSSL_X509* x509, byte* in, int *inOutSz)
+{
+    int copySz;
+
+    WOLFSSL_ENTER("wolfSSL_X509_get_dev_type");
+    if (inOutSz == NULL) return NULL;
+    if (!x509->deviceTypeSz) return in;
+
+    copySz = min(*inOutSz, x509->deviceTypeSz);
+
+    if (!in) {
+        in = (byte*)XMALLOC(x509->deviceTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
+        if (!in) return in;
+        copySz = x509->deviceTypeSz;
+    }
+
+    XMEMCPY(in, x509->deviceType, copySz);
+    *inOutSz = copySz;
+
+    return in;
+}
+
+
+byte* wolfSSL_X509_get_hw_type(WOLFSSL_X509* x509, byte* in, int* inOutSz)
+{
+    int copySz;
+
+    WOLFSSL_ENTER("wolfSSL_X509_get_hw_type");
+    if (inOutSz == NULL) return NULL;
+    if (!x509->hwTypeSz) return in;
+
+    copySz = min(*inOutSz, x509->hwTypeSz);
+
+    if (!in) {
+        in = (byte*)XMALLOC(x509->hwTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
+        if (!in) return in;
+        copySz = x509->hwTypeSz;
+    }
+
+    XMEMCPY(in, x509->hwType, copySz);
+    *inOutSz = copySz;
+
+    return in;
+}
+
+
+byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in,
+                                        int* inOutSz)
+{
+    int copySz;
+
+    WOLFSSL_ENTER("wolfSSL_X509_get_hw_serial_number");
+    if (inOutSz == NULL) return NULL;
+    if (!x509->hwTypeSz) return in;
+
+    copySz = min(*inOutSz, x509->hwSerialNumSz);
+
+    if (!in) {
+        in = (byte*)XMALLOC(x509->hwSerialNumSz, 0, DYNAMIC_TYPE_OPENSSL);
+        if (!in) return in;
+        copySz = x509->hwSerialNumSz;
+    }
+
+    XMEMCPY(in, x509->hwSerialNum, copySz);
+    *inOutSz = copySz;
+
+    return in;
+}
+
+#endif /* WOLFSSL_SEP */
+
+
+WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
+{
+    WOLFSSL_X509 *newX509 = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_X509_d2i");
+
+    if (in != NULL && len != 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+        DecodedCert* cert = NULL;
+    #else
+        DecodedCert  cert[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                     DYNAMIC_TYPE_TMP_BUFFER);
+        if (cert == NULL)
+            return NULL;
+    #endif
+
+        InitDecodedCert(cert, (byte*)in, len, NULL);
+        if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
+            newX509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
+                                             DYNAMIC_TYPE_X509);
+            if (newX509 != NULL) {
+                InitX509(newX509, 1);
+                if (CopyDecodedToX509(newX509, cert) != 0) {
+                    XFREE(newX509, NULL, DYNAMIC_TYPE_X509);
+                    newX509 = NULL;
+                }
+            }
+        }
+        FreeDecodedCert(cert);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+    }
+
+    if (x509 != NULL)
+        *x509 = newX509;
+
+    return newX509;
+}
+
+
+#ifndef NO_FILESYSTEM
+
+#ifndef NO_STDIO_FILESYSTEM
+
+WOLFSSL_X509* wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file)
+{
+    WOLFSSL_X509* newX509 = NULL;
+
+    WOLFSSL_ENTER("wolfSSL_X509_d2i_fp");
+
+    if (file != XBADFILE) {
+        byte* fileBuffer = NULL;
+        long sz = 0;
+
+        XFSEEK(file, 0, XSEEK_END);
+        sz = XFTELL(file);
+        XREWIND(file);
+
+        if (sz < 0) {
+            WOLFSSL_MSG("Bad tell on FILE");
+            return NULL;
+        }
+
+        fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
+        if (fileBuffer != NULL) {
+            int ret = (int)XFREAD(fileBuffer, sz, 1, file);
+            if (ret > 0) {
+                newX509 = wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
+            }
+            XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
+        }
+    }
+
+    if (x509 != NULL)
+        *x509 = newX509;
+
+    return newX509;
+}
+
+#endif /* NO_STDIO_FILESYSTEM */
+
+WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    byte  staticBuffer[1]; /* force heap usage */
+#else
+    byte  staticBuffer[FILE_BUFFER_SIZE];
+#endif
+    byte* fileBuffer = staticBuffer;
+    int   dynamic = 0;
+    int   ret;
+    long  sz = 0;
+    XFILE file;
+
+    WOLFSSL_X509* x509 = NULL;
+    buffer der;
+
+    WOLFSSL_ENTER("wolfSSL_X509_load_certificate");
+
+    /* Check the inputs */
+    if ((fname == NULL) ||
+        (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM))
+        return NULL;
+
+    file = XFOPEN(fname, "rb");
+    if (file == XBADFILE)
+        return NULL;
+
+    XFSEEK(file, 0, XSEEK_END);
+    sz = XFTELL(file);
+    XREWIND(file);
+
+    if (sz > (long)sizeof(staticBuffer)) {
+        fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
+        if (fileBuffer == NULL) {
+            XFCLOSE(file);
+            return NULL;
+        }
+        dynamic = 1;
+    }
+    else if (sz < 0) {
+        XFCLOSE(file);
+        return NULL;
+    }
+
+    ret = (int)XFREAD(fileBuffer, sz, 1, file);
+    if (ret < 0) {
+        XFCLOSE(file);
+        if (dynamic)
+            XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
+        return NULL;
+    }
+
+    XFCLOSE(file);
+
+    der.buffer = NULL;
+    der.length = 0;
+
+    if (format == SSL_FILETYPE_PEM) {
+        int ecc = 0;
+    #ifdef WOLFSSL_SMALL_STACK
+        EncryptedInfo* info = NULL;
+    #else
+        EncryptedInfo  info[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+        if (info == NULL) {
+            if (dynamic)
+                XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
+
+            return NULL;
+        }
+    #endif
+
+        info->set = 0;
+        info->ctx = NULL;
+        info->consumed = 0;
+
+        if (PemToDer(fileBuffer, sz, CERT_TYPE, &der, NULL, info, &ecc) != 0)
+        {
+            /* Only time this should fail, and leave `der` with a buffer
+               is when the Base64 Decode fails. Release `der.buffer` in
+               that case. */
+            if (der.buffer != NULL) {
+                XFREE(der.buffer, NULL, DYNAMIC_TYPE_CERT);
+                der.buffer = NULL;
+            }
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+    }
+    else {
+        der.buffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_CERT);
+        if (der.buffer != NULL) {
+            XMEMCPY(der.buffer, fileBuffer, sz);
+            der.length = (word32)sz;
+        }
+    }
+
+    if (dynamic)
+        XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
+
+    /* At this point we want `der` to have the certificate in DER format */
+    /* ready to be decoded. */
+    if (der.buffer != NULL) {
+    #ifdef WOLFSSL_SMALL_STACK
+        DecodedCert* cert = NULL;
+    #else
+        DecodedCert  cert[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+        if (cert != NULL)
+    #endif
+        {
+            InitDecodedCert(cert, der.buffer, der.length, NULL);
+            if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
+                x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
+                                                             DYNAMIC_TYPE_X509);
+                if (x509 != NULL) {
+                    InitX509(x509, 1);
+                    if (CopyDecodedToX509(x509, cert) != 0) {
+                        XFREE(x509, NULL, DYNAMIC_TYPE_X509);
+                        x509 = NULL;
+                    }
+                }
+            }
+
+            FreeDecodedCert(cert);
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+        }
+
+        XFREE(der.buffer, NULL, DYNAMIC_TYPE_CERT);
+    }
+
+    return x509;
+}
+
+#endif /* NO_FILESYSTEM */
+
+#endif /* KEEP_PEER_CERT || SESSION_CERTS */
+
+
+#ifdef OPENSSL_EXTRA
+int wolfSSL_set_session_id_context(WOLFSSL* ssl, const unsigned char* id,
+                               unsigned int len)
+{
+    (void)ssl;
+    (void)id;
+    (void)len;
+    return 0;
+}
+
+
+void wolfSSL_set_connect_state(WOLFSSL* ssl)
+{
+    (void)ssl;
+    /* client by default */
+}
+#endif
+
+int wolfSSL_get_shutdown(const WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_shutdown");
+#ifdef HAVE_STUNNEL
+    return (ssl->options.sentNotify << 1) | (ssl->options.closeNotify);
+#else
+    return (ssl->options.isClosed  ||
+            ssl->options.connReset ||
+            ssl->options.sentNotify);
+#endif
+}
+
+
+int wolfSSL_session_reused(WOLFSSL* ssl)
+{
+    return ssl->options.resuming;
+}
+
+#ifdef OPENSSL_EXTRA
+void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
+{
+    (void)session;
+}
+#endif
+
+const char* wolfSSL_get_version(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_get_version");
+    if (ssl->version.major == SSLv3_MAJOR) {
+        switch (ssl->version.minor) {
+            case SSLv3_MINOR :
+                return "SSLv3";
+            case TLSv1_MINOR :
+                return "TLSv1";
+            case TLSv1_1_MINOR :
+                return "TLSv1.1";
+            case TLSv1_2_MINOR :
+                return "TLSv1.2";
+            default:
+                return "unknown";
+        }
+    }
+    else if (ssl->version.major == DTLS_MAJOR) {
+        switch (ssl->version.minor) {
+            case DTLS_MINOR :
+                return "DTLS";
+            case DTLSv1_2_MINOR :
+                return "DTLSv1.2";
+            default:
+                return "unknown";
+        }
+    }
+    return "unknown";
+}
+
+
+/* current library version */
+const char* wolfSSL_lib_version(void)
+{
+    return LIBWOLFSSL_VERSION_STRING;
+}
+
+
+/* current library version in hex */
+word32 wolfSSL_lib_version_hex(void)
+{
+    return LIBWOLFSSL_VERSION_HEX;
+}
+
+
+int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_get_current_cipher_suite");
+    if (ssl)
+        return (ssl->options.cipherSuite0 << 8) | ssl->options.cipherSuite;
+    return 0;
+}
+
+WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("SSL_get_current_cipher");
+    if (ssl)
+        return &ssl->cipher;
+    else
+        return NULL;
+}
+
+
+const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher)
+{
+    (void)cipher;
+
+    WOLFSSL_ENTER("SSL_CIPHER_get_name");
+#ifndef NO_ERROR_STRINGS
+    if (cipher) {
+#if defined(HAVE_CHACHA)
+        if (cipher->ssl->options.cipherSuite0 == CHACHA_BYTE) {
+        /* ChaCha suites */
+        switch (cipher->ssl->options.cipherSuite) {
+#ifdef HAVE_CHACHA
+#ifndef NO_RSA
+            case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
+                return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
+
+            case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
+                return "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
+#endif
+            case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
+                return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
+#endif
+            }
+        }
+#endif
+
+#if defined(HAVE_ECC) || defined(HAVE_AESCCM)
+        /* Awkwardly, the ECC cipher suites use the ECC_BYTE as expected,
+         * but the AES-CCM cipher suites also use it, even the ones that
+         * aren't ECC. */
+        if (cipher->ssl->options.cipherSuite0 == ECC_BYTE) {
+        /* ECC suites */
+        switch (cipher->ssl->options.cipherSuite) {
+#ifdef HAVE_ECC
+#ifndef NO_RSA
+            case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
+                return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
+#endif
+            case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
+                return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
+#ifndef NO_RSA
+            case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
+                return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
+#endif
+            case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
+                return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
+#ifndef NO_RSA
+            case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
+                return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
+#endif
+            case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
+                return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
+#ifndef NO_RSA
+            case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
+                return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
+#endif
+            case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
+                return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
+#ifndef NO_SHA
+#ifndef NO_RSA
+            case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
+                return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
+            case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
+                return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
+#endif
+            case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
+                return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
+            case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
+                return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
+#ifndef NO_RC4
+    #ifndef NO_RSA
+            case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
+                return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
+    #endif
+            case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
+                return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
+#endif
+#ifndef NO_DES3
+    #ifndef NO_RSA
+            case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
+                return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
+    #endif
+            case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
+                return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
+#endif
+
+#ifndef NO_RSA
+            case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
+                return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
+            case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
+                return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
+#endif
+            case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
+                return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
+            case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
+                return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
+#ifndef NO_RC4
+    #ifndef NO_RSA
+            case TLS_ECDH_RSA_WITH_RC4_128_SHA :
+                return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
+    #endif
+            case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
+                return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
+#endif
+#ifndef NO_DES3
+    #ifndef NO_RSA
+            case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
+                return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
+    #endif
+            case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
+                return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
+#endif
+#endif /* NO_SHA */
+
+#ifdef HAVE_AESGCM
+#ifndef NO_RSA
+            case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
+                return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
+            case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
+                return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
+#endif
+            case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
+                return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
+            case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
+                return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
+#ifndef NO_RSA
+            case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
+                return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
+            case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
+                return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
+#endif
+            case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
+                return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
+            case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
+                return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
+#endif
+#endif /* HAVE_ECC */
+
+#ifdef HAVE_AESCCM
+#ifndef NO_RSA
+            case TLS_RSA_WITH_AES_128_CCM_8 :
+                return "TLS_RSA_WITH_AES_128_CCM_8";
+            case TLS_RSA_WITH_AES_256_CCM_8 :
+                return "TLS_RSA_WITH_AES_256_CCM_8";
+#endif
+#ifndef NO_PSK
+            case TLS_PSK_WITH_AES_128_CCM_8 :
+                return "TLS_PSK_WITH_AES_128_CCM_8";
+            case TLS_PSK_WITH_AES_256_CCM_8 :
+                return "TLS_PSK_WITH_AES_256_CCM_8";
+            case TLS_PSK_WITH_AES_128_CCM :
+                return "TLS_PSK_WITH_AES_128_CCM";
+            case TLS_PSK_WITH_AES_256_CCM :
+                return "TLS_PSK_WITH_AES_256_CCM";
+            case TLS_DHE_PSK_WITH_AES_128_CCM :
+                return "TLS_DHE_PSK_WITH_AES_128_CCM";
+            case TLS_DHE_PSK_WITH_AES_256_CCM :
+                return "TLS_DHE_PSK_WITH_AES_256_CCM";
+#endif
+#ifdef HAVE_ECC
+            case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
+                return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8";
+            case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
+                return "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8";
+#endif
+#endif
+
+            default:
+                return "NONE";
+        }
+        }
+#endif  /* ECC */
+        if (cipher->ssl->options.cipherSuite0 != ECC_BYTE &&
+            cipher->ssl->options.cipherSuite0 != CHACHA_BYTE) {
+
+            /* normal suites */
+        switch (cipher->ssl->options.cipherSuite) {
+#ifndef NO_RSA
+#ifndef NO_RC4
+    #ifndef NO_SHA
+            case SSL_RSA_WITH_RC4_128_SHA :
+                return "SSL_RSA_WITH_RC4_128_SHA";
+    #endif
+    #ifndef NO_MD5
+            case SSL_RSA_WITH_RC4_128_MD5 :
+                return "SSL_RSA_WITH_RC4_128_MD5";
+    #endif
+#endif
+#ifndef NO_SHA
+    #ifndef NO_DES3
+            case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
+                return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
+    #endif
+    #ifdef HAVE_IDEA
+            case SSL_RSA_WITH_IDEA_CBC_SHA :
+                return "SSL_RSA_WITH_IDEA_CBC_SHA";
+    #endif
+
+            case TLS_RSA_WITH_AES_128_CBC_SHA :
+                return "TLS_RSA_WITH_AES_128_CBC_SHA";
+            case TLS_RSA_WITH_AES_256_CBC_SHA :
+                return "TLS_RSA_WITH_AES_256_CBC_SHA";
+#endif
+            case TLS_RSA_WITH_AES_128_CBC_SHA256 :
+                return "TLS_RSA_WITH_AES_128_CBC_SHA256";
+            case TLS_RSA_WITH_AES_256_CBC_SHA256 :
+                return "TLS_RSA_WITH_AES_256_CBC_SHA256";
+    #ifdef HAVE_BLAKE2
+            case TLS_RSA_WITH_AES_128_CBC_B2B256:
+                return "TLS_RSA_WITH_AES_128_CBC_B2B256";
+            case TLS_RSA_WITH_AES_256_CBC_B2B256:
+                return "TLS_RSA_WITH_AES_256_CBC_B2B256";
+    #endif
+#ifndef NO_SHA
+            case TLS_RSA_WITH_NULL_SHA :
+                return "TLS_RSA_WITH_NULL_SHA";
+#endif
+            case TLS_RSA_WITH_NULL_SHA256 :
+                return "TLS_RSA_WITH_NULL_SHA256";
+#endif /* NO_RSA */
+#ifndef NO_PSK
+#ifndef NO_SHA
+            case TLS_PSK_WITH_AES_128_CBC_SHA :
+                return "TLS_PSK_WITH_AES_128_CBC_SHA";
+            case TLS_PSK_WITH_AES_256_CBC_SHA :
+                return "TLS_PSK_WITH_AES_256_CBC_SHA";
+#endif
+#ifndef NO_SHA256
+            case TLS_PSK_WITH_AES_128_CBC_SHA256 :
+                return "TLS_PSK_WITH_AES_128_CBC_SHA256";
+            case TLS_PSK_WITH_NULL_SHA256 :
+                return "TLS_PSK_WITH_NULL_SHA256";
+            case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
+                return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
+            case TLS_DHE_PSK_WITH_NULL_SHA256 :
+                return "TLS_DHE_PSK_WITH_NULL_SHA256";
+    #ifdef HAVE_AESGCM
+            case TLS_PSK_WITH_AES_128_GCM_SHA256 :
+                return "TLS_PSK_WITH_AES_128_GCM_SHA256";
+            case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
+                return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
+    #endif
+#endif
+#ifdef WOLFSSL_SHA384
+            case TLS_PSK_WITH_AES_256_CBC_SHA384 :
+                return "TLS_PSK_WITH_AES_256_CBC_SHA384";
+            case TLS_PSK_WITH_NULL_SHA384 :
+                return "TLS_PSK_WITH_NULL_SHA384";
+            case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
+                return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
+            case TLS_DHE_PSK_WITH_NULL_SHA384 :
+                return "TLS_DHE_PSK_WITH_NULL_SHA384";
+    #ifdef HAVE_AESGCM
+            case TLS_PSK_WITH_AES_256_GCM_SHA384 :
+                return "TLS_PSK_WITH_AES_256_GCM_SHA384";
+            case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
+                return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
+    #endif
+#endif
+#ifndef NO_SHA
+            case TLS_PSK_WITH_NULL_SHA :
+                return "TLS_PSK_WITH_NULL_SHA";
+#endif
+#endif /* NO_PSK */
+#ifndef NO_RSA
+            case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
+                return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
+            case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
+                return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
+#ifndef NO_SHA
+            case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
+                return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
+            case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
+                return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
+#endif
+#ifndef NO_HC128
+    #ifndef NO_MD5
+            case TLS_RSA_WITH_HC_128_MD5 :
+                return "TLS_RSA_WITH_HC_128_MD5";
+    #endif
+    #ifndef NO_SHA
+            case TLS_RSA_WITH_HC_128_SHA :
+                return "TLS_RSA_WITH_HC_128_SHA";
+    #endif
+    #ifdef HAVE_BLAKE2
+            case TLS_RSA_WITH_HC_128_B2B256:
+                return "TLS_RSA_WITH_HC_128_B2B256";
+    #endif
+#endif /* NO_HC128 */
+#ifndef NO_SHA
+    #ifndef NO_RABBIT
+            case TLS_RSA_WITH_RABBIT_SHA :
+                return "TLS_RSA_WITH_RABBIT_SHA";
+    #endif
+    #ifdef HAVE_NTRU
+        #ifndef NO_RC4
+            case TLS_NTRU_RSA_WITH_RC4_128_SHA :
+                return "TLS_NTRU_RSA_WITH_RC4_128_SHA";
+        #endif
+        #ifndef NO_DES3
+            case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
+                return "TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA";
+        #endif
+            case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
+                return "TLS_NTRU_RSA_WITH_AES_128_CBC_SHA";
+            case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
+                return "TLS_NTRU_RSA_WITH_AES_256_CBC_SHA";
+    #endif /* HAVE_NTRU */
+    #ifdef HAVE_QSH
+            case TLS_QSH :
+                return "TLS_QSH";
+    #endif /* HAVE_QSH*/
+#endif /* NO_SHA */
+            case TLS_RSA_WITH_AES_128_GCM_SHA256 :
+                return "TLS_RSA_WITH_AES_128_GCM_SHA256";
+            case TLS_RSA_WITH_AES_256_GCM_SHA384 :
+                return "TLS_RSA_WITH_AES_256_GCM_SHA384";
+            case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
+                return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
+            case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
+                return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
+#ifndef NO_SHA
+            case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
+                return "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA";
+            case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
+                return "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA";
+#endif
+            case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
+                return "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256";
+            case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
+                return "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256";
+#ifndef NO_SHA
+            case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
+                return "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA";
+            case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
+                return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA";
+#endif
+            case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
+                return "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256";
+            case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
+                return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256";
+#endif /* NO_RSA */
+#ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
+            case TLS_DH_anon_WITH_AES_128_CBC_SHA :
+                return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
+#endif
+            default:
+                return "NONE";
+        }  /* switch */
+        }  /* normal / ECC */
+    }
+#endif /* NO_ERROR_STRINGS */
+    return "NONE";
+}
+
+
+const char* wolfSSL_get_cipher(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_cipher");
+    return wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl));
+}
+
+#ifdef OPENSSL_EXTRA
+
+
+
+char* wolfSSL_CIPHER_description(WOLFSSL_CIPHER* cipher, char* in, int len)
+{
+    (void)cipher;
+    (void)in;
+    (void)len;
+    return 0;
+}
+
+
+WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl)  /* what's ref count */
+{
+    (void)ssl;
+    return 0;
+}
+
+
+void wolfSSL_X509_free(WOLFSSL_X509* x509)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_free");
+    ExternalFreeX509(x509);
+}
+
+
+/* was do nothing */
+/*
+void OPENSSL_free(void* buf)
+{
+    (void)buf;
+}
+*/
+
+
+int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
+                   int* ssl)
+{
+    (void)url;
+    (void)host;
+    (void)port;
+    (void)path;
+    (void)ssl;
+    return 0;
+}
+
+
+WOLFSSL_METHOD* wolfSSLv2_client_method(void)
+{
+    return 0;
+}
+
+
+WOLFSSL_METHOD* wolfSSLv2_server_method(void)
+{
+    return 0;
+}
+
+
+#ifndef NO_MD4
+
+void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX* md4)
+{
+    /* make sure we have a big enough buffer */
+    typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1];
+    (void) sizeof(ok);
+
+    WOLFSSL_ENTER("MD4_Init");
+    wc_InitMd4((Md4*)md4);
+}
+
+
+void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX* md4, const void* data,
+                       unsigned long len)
+{
+    WOLFSSL_ENTER("MD4_Update");
+    wc_Md4Update((Md4*)md4, (const byte*)data, (word32)len);
+}
+
+
+void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4)
+{
+    WOLFSSL_ENTER("MD4_Final");
+    wc_Md4Final((Md4*)md4, digest);
+}
+
+#endif /* NO_MD4 */
+
+
+WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO* top)
+{
+    (void)top;
+    return 0;
+}
+
+
+int wolfSSL_BIO_pending(WOLFSSL_BIO* bio)
+{
+    (void)bio;
+    return 0;
+}
+
+
+
+WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_mem(void)
+{
+    static WOLFSSL_BIO_METHOD meth;
+
+    WOLFSSL_ENTER("BIO_s_mem");
+    meth.type = BIO_MEMORY;
+
+    return &meth;
+}
+
+
+WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_base64(void)
+{
+    return 0;
+}
+
+
+void wolfSSL_BIO_set_flags(WOLFSSL_BIO* bio, int flags)
+{
+    (void)bio;
+    (void)flags;
+}
+
+
+
+void wolfSSL_RAND_screen(void)
+{
+
+}
+
+
+const char* wolfSSL_RAND_file_name(char* fname, unsigned long len)
+{
+    (void)fname;
+    (void)len;
+    return 0;
+}
+
+
+int wolfSSL_RAND_write_file(const char* fname)
+{
+    (void)fname;
+    return 0;
+}
+
+
+int wolfSSL_RAND_load_file(const char* fname, long len)
+{
+    (void)fname;
+    /* wolfCrypt provides enough entropy internally or will report error */
+    if (len == -1)
+        return 1024;
+    else
+        return (int)len;
+}
+
+
+int wolfSSL_RAND_egd(const char* path)
+{
+    (void)path;
+    return 0;
+}
+
+
+
+WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void)
+{
+    return 0;
+}
+
+
+WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void)
+{
+    return 0;
+}
+
+
+int wolfSSL_COMP_add_compression_method(int method, void* data)
+{
+    (void)method;
+    (void)data;
+    return 0;
+}
+
+
+void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)(
+                                                          const char*, int))
+{
+    (void)f;
+}
+
+
+void wolfSSL_set_dynlock_lock_callback(
+             void (*f)(int, WOLFSSL_dynlock_value*, const char*, int))
+{
+    (void)f;
+}
+
+
+void wolfSSL_set_dynlock_destroy_callback(
+                  void (*f)(WOLFSSL_dynlock_value*, const char*, int))
+{
+    (void)f;
+}
+
+
+
+const char* wolfSSL_X509_verify_cert_error_string(long err)
+{
+    return wolfSSL_ERR_reason_error_string(err);
+}
+
+
+
+int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir,
+                               long len)
+{
+    (void)lookup;
+    (void)dir;
+    (void)len;
+    return 0;
+}
+
+
+int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
+                                 const char* file, long len)
+{
+    (void)lookup;
+    (void)file;
+    (void)len;
+    return 0;
+}
+
+
+WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void)
+{
+    return 0;
+}
+
+
+WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
+{
+    return 0;
+}
+
+
+
+WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
+                                               WOLFSSL_X509_LOOKUP_METHOD* m)
+{
+    (void)store;
+    (void)m;
+    return 0;
+}
+
+
+int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509)
+{
+    int result = SSL_FATAL_ERROR;
+
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_add_cert");
+    if (store != NULL && store->cm != NULL && x509 != NULL) {
+        buffer derCert;
+        derCert.buffer = (byte*)XMALLOC(x509->derCert.length,
+                                                   NULL, DYNAMIC_TYPE_CERT);
+        if (derCert.buffer != NULL) {
+            derCert.length = x509->derCert.length;
+                /* AddCA() frees the buffer. */
+            XMEMCPY(derCert.buffer,
+                                x509->derCert.buffer, x509->derCert.length);
+            result = AddCA(store->cm, derCert, WOLFSSL_USER_CA, 1);
+            if (result != SSL_SUCCESS) result = SSL_FATAL_ERROR;
+        }
+    }
+
+    WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_cert", result);
+    return result;
+}
+
+
+WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
+{
+    WOLFSSL_X509_STORE* store = NULL;
+
+    store = (WOLFSSL_X509_STORE*)XMALLOC(sizeof(WOLFSSL_X509_STORE), NULL, 0);
+    if (store != NULL) {
+        store->cm = wolfSSL_CertManagerNew();
+        if (store->cm == NULL) {
+            XFREE(store, NULL, 0);
+            store = NULL;
+        }
+    }
+
+    return store;
+}
+
+
+void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store)
+{
+    if (store != NULL) {
+        if (store->cm != NULL)
+        wolfSSL_CertManagerFree(store->cm);
+        XFREE(store, NULL, 0);
+    }
+}
+
+
+int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE* store)
+{
+    (void)store;
+    return SSL_SUCCESS;
+}
+
+
+int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, int idx,
+                            WOLFSSL_X509_NAME* name, WOLFSSL_X509_OBJECT* obj)
+{
+    (void)ctx;
+    (void)idx;
+    (void)name;
+    (void)obj;
+    return 0;
+}
+
+
+WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void)
+{
+    WOLFSSL_X509_STORE_CTX* ctx = (WOLFSSL_X509_STORE_CTX*)XMALLOC(
+                                    sizeof(WOLFSSL_X509_STORE_CTX), NULL, 0);
+
+    if (ctx != NULL)
+        wolfSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL);
+
+    return ctx;
+}
+
+
+int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
+     WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509, STACK_OF(WOLFSSL_X509)* sk)
+{
+    (void)sk;
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_init");
+    if (ctx != NULL) {
+        ctx->store = store;
+        ctx->current_cert = x509;
+        ctx->domain = NULL;
+        ctx->ex_data = NULL;
+        ctx->userCtx = NULL;
+        ctx->error = 0;
+        ctx->error_depth = 0;
+        ctx->discardSessionCerts = 0;
+        return SSL_SUCCESS;
+    }
+    return SSL_FATAL_ERROR;
+}
+
+
+void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx)
+{
+    if (ctx != NULL) {
+        if (ctx->store != NULL)
+            wolfSSL_X509_STORE_free(ctx->store);
+        if (ctx->current_cert != NULL)
+            wolfSSL_FreeX509(ctx->current_cert);
+        XFREE(ctx, NULL, 0);
+    }
+}
+
+
+void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX* ctx)
+{
+    (void)ctx;
+}
+
+
+int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
+{
+    if (ctx != NULL && ctx->store != NULL && ctx->store->cm != NULL
+                                             && ctx->current_cert != NULL) {
+        return wolfSSL_CertManagerVerifyBuffer(ctx->store->cm,
+                    ctx->current_cert->derCert.buffer,
+                    ctx->current_cert->derCert.length,
+                    SSL_FILETYPE_ASN1);
+    }
+    return SSL_FATAL_ERROR;
+}
+
+
+WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
+{
+    (void)crl;
+    return 0;
+}
+
+
+WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
+{
+    (void)crl;
+    return 0;
+}
+
+
+
+WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
+{
+    WOLFSSL_EVP_PKEY* key = NULL;
+    if (x509 != NULL) {
+        key = (WOLFSSL_EVP_PKEY*)XMALLOC(
+                    sizeof(WOLFSSL_EVP_PKEY), NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+        if (key != NULL) {
+            key->type = x509->pubKeyOID;
+            key->save_type = 0;
+            key->pkey.ptr = (char*)XMALLOC(
+                        x509->pubKey.length, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+            if (key->pkey.ptr == NULL) {
+                XFREE(key, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
+                return NULL;
+            }
+            XMEMCPY(key->pkey.ptr,
+                                  x509->pubKey.buffer, x509->pubKey.length);
+            key->pkey_sz = x509->pubKey.length;
+            #ifdef HAVE_ECC
+                key->pkey_curve = (int)x509->pkCurveOID;
+            #endif /* HAVE_ECC */
+        }
+    }
+    return key;
+}
+
+
+int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
+{
+    (void)crl;
+    (void)key;
+    return 0;
+}
+
+
+void wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX* ctx, int err)
+{
+    (void)ctx;
+    (void)err;
+}
+
+
+void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj)
+{
+    (void)obj;
+}
+
+
+void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key)
+{
+    if (key != NULL) {
+        if (key->pkey.ptr != NULL)
+            XFREE(key->pkey.ptr, NULL, 0);
+        XFREE(key, NULL, 0);
+    }
+}
+
+
+int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime)
+{
+    (void)asnTime;
+    return 0;
+}
+
+
+int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED* revoked)
+{
+    (void)revoked;
+    return 0;
+}
+
+
+
+WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL* crl)
+{
+    (void)crl;
+    return 0;
+}
+
+
+WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
+                                    WOLFSSL_X509_REVOKED* revoked, int value)
+{
+    (void)revoked;
+    (void)value;
+    return 0;
+}
+
+
+
+WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
+{
+    (void)x509;
+    return 0;
+}
+
+
+int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime)
+{
+    (void)bio;
+    (void)asnTime;
+    return 0;
+}
+
+
+
+int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER* a,
+                            const WOLFSSL_ASN1_INTEGER* b)
+{
+    (void)a;
+    (void)b;
+    return 0;
+}
+
+
+long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER* i)
+{
+    (void)i;
+    return 0;
+}
+
+
+
+void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_ex_data");
+#if defined(FORTRESS) || defined(HAVE_STUNNEL)
+    if (ctx != NULL && idx == 0)
+        return ctx->ex_data;
+#else
+    (void)ctx;
+    (void)idx;
+#endif
+    return 0;
+}
+
+
+int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void)
+{
+    WOLFSSL_ENTER("wolfSSL_get_ex_data_X509_STORE_CTX_idx");
+    return 0;
+}
+
+
+void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX* ctx,
+       void (*f)(const WOLFSSL* ssl, int type, int val))
+{
+    (void)ctx;
+    (void)f;
+}
+
+
+unsigned long wolfSSL_ERR_peek_error(void)
+{
+    return 0;
+}
+
+
+int wolfSSL_ERR_GET_REASON(unsigned long err)
+{
+    (void)err;
+    return 0;
+}
+
+
+char* wolfSSL_alert_type_string_long(int alertID)
+{
+    (void)alertID;
+    return 0;
+}
+
+
+char* wolfSSL_alert_desc_string_long(int alertID)
+{
+    (void)alertID;
+    return 0;
+}
+
+
+char* wolfSSL_state_string_long(const WOLFSSL* ssl)
+{
+    (void)ssl;
+    return 0;
+}
+
+
+int wolfSSL_PEM_def_callback(char* name, int num, int w, void* key)
+{
+    (void)name;
+    (void)num;
+    (void)w;
+    (void)key;
+    return 0;
+}
+
+
+long wolfSSL_CTX_sess_accept(WOLFSSL_CTX* ctx)
+{
+    (void)ctx;
+    return 0;
+}
+
+
+long wolfSSL_CTX_sess_connect(WOLFSSL_CTX* ctx)
+{
+    (void)ctx;
+    return 0;
+}
+
+
+long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX* ctx)
+{
+    (void)ctx;
+    return 0;
+}
+
+
+long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX* ctx)
+{
+    (void)ctx;
+    return 0;
+}
+
+
+long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX* ctx)
+{
+    (void)ctx;
+    return 0;
+}
+
+
+long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX* ctx)
+{
+    (void)ctx;
+    return 0;
+}
+
+
+long wolfSSL_CTX_sess_hits(WOLFSSL_CTX* ctx)
+{
+    (void)ctx;
+    return 0;
+}
+
+
+long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX* ctx)
+{
+    (void)ctx;
+    return 0;
+}
+
+
+long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX* ctx)
+{
+    (void)ctx;
+    return 0;
+}
+
+
+long wolfSSL_CTX_sess_misses(WOLFSSL_CTX* ctx)
+{
+    (void)ctx;
+    return 0;
+}
+
+
+long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX* ctx)
+{
+    (void)ctx;
+    return 0;
+}
+
+
+long wolfSSL_CTX_sess_number(WOLFSSL_CTX* ctx)
+{
+    (void)ctx;
+    return 0;
+}
+
+#ifndef NO_DES3
+
+void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* myDes,
+                                               WOLFSSL_DES_key_schedule* key)
+{
+    (void)myDes;
+    (void)key;
+}
+
+
+void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* myDes)
+{
+    (void)myDes;
+}
+
+
+void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* desa,
+             WOLFSSL_DES_cblock* desb, WOLFSSL_DES_key_schedule* key, int len)
+{
+    (void)desa;
+    (void)desb;
+    (void)key;
+    (void)len;
+}
+
+#endif /* NO_DES3 */
+
+int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...)
+{
+    (void)bio;
+    (void)format;
+    return 0;
+}
+
+
+int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a)
+{
+    (void)bio;
+    (void)a;
+    return 0;
+}
+
+
+int  wolfSSL_sk_num(WOLFSSL_X509_REVOKED* rev)
+{
+    (void)rev;
+    return 0;
+}
+
+
+void* wolfSSL_sk_value(WOLFSSL_X509_REVOKED* rev, int i)
+{
+    (void)rev;
+    (void)i;
+    return 0;
+}
+
+
+/* stunnel 4.28 needs */
+void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX* ctx,
+                    WOLFSSL_SESSION*(*f)(WOLFSSL*, unsigned char*, int, int*))
+{
+    (void)ctx;
+    (void)f;
+}
+
+
+void wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX* ctx,
+                             int (*f)(WOLFSSL*, WOLFSSL_SESSION*))
+{
+    (void)ctx;
+    (void)f;
+}
+
+
+void wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX* ctx, void (*f)(WOLFSSL_CTX*,
+                                                        WOLFSSL_SESSION*))
+{
+    (void)ctx;
+    (void)f;
+}
+
+
+int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
+{
+    (void)sess;
+    (void)p;
+    return sizeof(WOLFSSL_SESSION);
+}
+
+
+WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
+                                const unsigned char** p, long i)
+{
+    (void)p;
+    (void)i;
+    if (sess)
+        return *sess;
+    return NULL;
+}
+
+
+long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION* sess)
+{
+    WOLFSSL_ENTER("wolfSSL_SESSION_get_timeout");
+    return sess->timeout;
+}
+
+
+long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
+{
+    WOLFSSL_ENTER("wolfSSL_SESSION_get_time");
+    return sess->bornOn;
+}
+
+
+#endif /* OPENSSL_EXTRA */
+
+
+#ifdef KEEP_PEER_CERT
+char*  wolfSSL_X509_get_subjectCN(WOLFSSL_X509* x509)
+{
+    if (x509 == NULL)
+        return NULL;
+
+    return x509->subjectCN;
+}
+#endif /* KEEP_PEER_CERT */
+
+#ifdef OPENSSL_EXTRA
+
+#ifdef FORTRESS
+int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname)
+{
+    int ret = SSL_FATAL_ERROR;
+
+    WOLFSSL_ENTER("wolfSSL_cmp_peer_cert_to_file");
+    if (ssl != NULL && fname != NULL)
+    {
+    #ifdef WOLFSSL_SMALL_STACK
+        EncryptedInfo* info = NULL;
+        byte           staticBuffer[1]; /* force heap usage */
+    #else
+        EncryptedInfo  info[1];
+        byte           staticBuffer[FILE_BUFFER_SIZE];
+    #endif
+        byte*          myBuffer  = staticBuffer;
+        int            dynamic   = 0;
+        XFILE          file      = XBADFILE;
+        long           sz        = 0;
+        int            eccKey    = 0;
+        WOLFSSL_CTX*    ctx       = ssl->ctx;
+        WOLFSSL_X509*   peer_cert = &ssl->peerCert;
+        buffer         fileDer;
+
+        fileDer.buffer = 0;
+        file = XFOPEN(fname, "rb");
+        if (file == XBADFILE)
+            return SSL_BAD_FILE;
+
+        XFSEEK(file, 0, XSEEK_END);
+        sz = XFTELL(file);
+        XREWIND(file);
+
+        if (sz > (long)sizeof(staticBuffer)) {
+            WOLFSSL_MSG("Getting dynamic buffer");
+            myBuffer = (byte*)XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
+            dynamic = 1;
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
+                                                   DYNAMIC_TYPE_TMP_BUFFER);
+        if (info == NULL)
+            ret = MEMORY_E;
+        else
+    #endif
+        {
+            info->set = 0;
+            info->ctx = ctx;
+            info->consumed = 0;
+
+            if ((myBuffer != NULL) &&
+                (sz > 0) &&
+                (XFREAD(myBuffer, sz, 1, file) > 0) &&
+                (PemToDer(myBuffer, sz, CERT_TYPE,
+                          &fileDer, ctx->heap, info, &eccKey) == 0) &&
+                (fileDer.length != 0) &&
+                (fileDer.length == peer_cert->derCert.length) &&
+                (XMEMCMP(peer_cert->derCert.buffer, fileDer.buffer,
+                                                    fileDer.length) == 0))
+            {
+                ret = 0;
+            }
+
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+        }
+
+        XFREE(fileDer.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
+        if (dynamic)
+            XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
+
+        XFCLOSE(file);
+    }
+
+    return ret;
+}
+#endif
+
+
+static WC_RNG globalRNG;
+static int initGlobalRNG = 0;
+
+/* SSL_SUCCESS on ok */
+int wolfSSL_RAND_seed(const void* seed, int len)
+{
+
+    WOLFSSL_MSG("wolfSSL_RAND_seed");
+
+    (void)seed;
+    (void)len;
+
+    if (initGlobalRNG == 0) {
+        if (wc_InitRng(&globalRNG) < 0) {
+            WOLFSSL_MSG("wolfSSL Init Global RNG failed");
+            return 0;
+        }
+        initGlobalRNG = 1;
+    }
+
+    return SSL_SUCCESS;
+}
+
+
+/* SSL_SUCCESS on ok */
+int wolfSSL_RAND_bytes(unsigned char* buf, int num)
+{
+    int     ret = 0;
+    int     initTmpRng = 0;
+    WC_RNG* rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG* tmpRNG = NULL;
+#else
+    WC_RNG  tmpRNG[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_RAND_bytes");
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmpRNG == NULL)
+        return ret;
+#endif
+
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else if (initGlobalRNG)
+        rng = &globalRNG;
+
+    if (rng) {
+        if (wc_RNG_GenerateBlock(rng, buf, num) != 0)
+            WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
+        else
+            ret = SSL_SUCCESS;
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void)
+{
+    static int ctx;  /* wolfcrypt doesn't now need ctx */
+
+    WOLFSSL_MSG("wolfSSL_BN_CTX_new");
+
+    return (WOLFSSL_BN_CTX*)&ctx;
+}
+
+void wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX* ctx)
+{
+    (void)ctx;
+    WOLFSSL_MSG("wolfSSL_BN_CTX_init");
+}
+
+
+void wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX* ctx)
+{
+    (void)ctx;
+    WOLFSSL_MSG("wolfSSL_BN_CTX_free");
+
+    /* do free since static ctx that does nothing */
+}
+
+
+static void InitwolfSSL_BigNum(WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("InitwolfSSL_BigNum");
+    if (bn) {
+        bn->neg      = 0;
+        bn->internal = NULL;
+    }
+}
+
+
+WOLFSSL_BIGNUM* wolfSSL_BN_new(void)
+{
+    WOLFSSL_BIGNUM* external;
+    mp_int*        mpi;
+
+    WOLFSSL_MSG("wolfSSL_BN_new");
+
+    mpi = (mp_int*) XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
+    if (mpi == NULL) {
+        WOLFSSL_MSG("wolfSSL_BN_new malloc mpi failure");
+        return NULL;
+    }
+
+    external = (WOLFSSL_BIGNUM*) XMALLOC(sizeof(WOLFSSL_BIGNUM), NULL,
+                                        DYNAMIC_TYPE_BIGINT);
+    if (external == NULL) {
+        WOLFSSL_MSG("wolfSSL_BN_new malloc WOLFSSL_BIGNUM failure");
+        XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
+        return NULL;
+    }
+
+    InitwolfSSL_BigNum(external);
+    external->internal = mpi;
+    if (mp_init(mpi) != MP_OKAY) {
+        wolfSSL_BN_free(external);
+        return NULL;
+    }
+
+    return external;
+}
+
+
+void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_free");
+    if (bn) {
+        if (bn->internal) {
+            mp_clear((mp_int*)bn->internal);
+            XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT);
+            bn->internal = NULL;
+        }
+        XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT);
+        bn = NULL;
+    }
+}
+
+
+void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_clear_free");
+
+    wolfSSL_BN_free(bn);
+}
+
+
+/* SSL_SUCCESS on ok */
+int wolfSSL_BN_sub(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
+                  const WOLFSSL_BIGNUM* b)
+{
+    WOLFSSL_MSG("wolfSSL_BN_sub");
+
+    if (r == NULL || a == NULL || b == NULL)
+        return 0;
+
+    if (mp_sub((mp_int*)a->internal,(mp_int*)b->internal,
+               (mp_int*)r->internal) == MP_OKAY)
+        return SSL_SUCCESS;
+
+    WOLFSSL_MSG("wolfSSL_BN_sub mp_sub failed");
+    return 0;
+}
+
+
+/* SSL_SUCCESS on ok */
+int wolfSSL_BN_mod(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
+                  const WOLFSSL_BIGNUM* b, const WOLFSSL_BN_CTX* c)
+{
+    (void)c;
+    WOLFSSL_MSG("wolfSSL_BN_mod");
+
+    if (r == NULL || a == NULL || b == NULL)
+        return 0;
+
+    if (mp_mod((mp_int*)a->internal,(mp_int*)b->internal,
+               (mp_int*)r->internal) == MP_OKAY)
+        return SSL_SUCCESS;
+
+    WOLFSSL_MSG("wolfSSL_BN_mod mp_mod failed");
+    return 0;
+}
+
+
+const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void)
+{
+    static WOLFSSL_BIGNUM* bn_one = NULL;
+
+    WOLFSSL_MSG("wolfSSL_BN_value_one");
+
+    if (bn_one == NULL) {
+        bn_one = wolfSSL_BN_new();
+        if (bn_one)
+            mp_set_int((mp_int*)bn_one->internal, 1);
+    }
+
+    return bn_one;
+}
+
+/* return compliant with OpenSSL
+ *   size of BIGNUM in bytes, 0 if error */
+int wolfSSL_BN_num_bytes(const WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_num_bytes");
+
+    if (bn == NULL || bn->internal == NULL)
+        return SSL_FAILURE;
+
+    return mp_unsigned_bin_size((mp_int*)bn->internal);
+}
+
+/* return compliant with OpenSSL
+ *   size of BIGNUM in bits, 0 if error */
+int wolfSSL_BN_num_bits(const WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_num_bits");
+
+    if (bn == NULL || bn->internal == NULL)
+        return SSL_FAILURE;
+
+    return mp_count_bits((mp_int*)bn->internal);
+}
+
+/* return compliant with OpenSSL
+ *   1 if BIGNUM is zero, 0 else */
+int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_is_zero");
+
+    if (bn == NULL || bn->internal == NULL)
+        return SSL_FAILURE;
+
+    if (mp_iszero((mp_int*)bn->internal) == MP_YES)
+        return SSL_SUCCESS;
+
+    return SSL_FAILURE;
+}
+
+/* return compliant with OpenSSL
+ *   1 if BIGNUM is one, 0 else */
+int wolfSSL_BN_is_one(const WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_is_one");
+
+    if (bn == NULL || bn->internal == NULL)
+        return SSL_FAILURE;
+
+    if (mp_cmp_d((mp_int*)bn->internal, 1) == MP_EQ)
+        return SSL_SUCCESS;
+
+    return SSL_FAILURE;
+}
+
+/* return compliant with OpenSSL
+ *   1 if BIGNUM is odd, 0 else */
+int wolfSSL_BN_is_odd(const WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_is_odd");
+
+    if (bn == NULL || bn->internal == NULL)
+        return SSL_FAILURE;
+
+    if (mp_isodd((mp_int*)bn->internal) == MP_YES)
+        return SSL_SUCCESS;
+
+    return SSL_FAILURE;
+}
+
+/* return compliant with OpenSSL
+ *   -1 if a < b, 0 if a == b and 1 if a > b
+ */
+int wolfSSL_BN_cmp(const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b)
+{
+    int ret;
+
+    WOLFSSL_MSG("wolfSSL_BN_cmp");
+
+    if (a == NULL || a->internal == NULL || b == NULL || b->internal == NULL)
+        return SSL_FATAL_ERROR;
+
+    ret = mp_cmp((mp_int*)a->internal, (mp_int*)b->internal);
+
+    return (ret == MP_EQ ? 0 : (ret == MP_GT ? 1 : -1));
+}
+
+/* return compliant with OpenSSL
+ *   length of BIGNUM in bytes, -1 if error */
+int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM* bn, unsigned char* r)
+{
+    WOLFSSL_MSG("wolfSSL_BN_bn2bin");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("NULL bn error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (r == NULL)
+        return mp_unsigned_bin_size((mp_int*)bn->internal);
+
+    if (mp_to_unsigned_bin((mp_int*)bn->internal, r) != MP_OKAY) {
+        WOLFSSL_MSG("mp_to_unsigned_bin error");
+        return SSL_FATAL_ERROR;
+    }
+
+    return mp_unsigned_bin_size((mp_int*)bn->internal);
+}
+
+
+WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char* str, int len,
+                            WOLFSSL_BIGNUM* ret)
+{
+    int weOwn = 0;
+
+    WOLFSSL_MSG("wolfSSL_BN_bin2bn");
+
+    /* if ret is null create a BN */
+    if (ret == NULL) {
+        ret = wolfSSL_BN_new();
+        weOwn = 1;
+        if (ret == NULL)
+            return NULL;
+    }
+
+    /* check ret and ret->internal then read in value */
+    if (ret && ret->internal) {
+        if (mp_read_unsigned_bin((mp_int*)ret->internal, str, len) != 0) {
+            WOLFSSL_MSG("mp_read_unsigned_bin failure");
+            if (weOwn)
+                wolfSSL_BN_free(ret);
+            return NULL;
+        }
+    }
+
+    return ret;
+}
+
+/* return compliant with OpenSSL
+ *   1 if success, 0 if error */
+int wolfSSL_mask_bits(WOLFSSL_BIGNUM* bn, int n)
+{
+    (void)bn;
+    (void)n;
+    WOLFSSL_MSG("wolfSSL_BN_mask_bits");
+
+    return SSL_FAILURE;
+}
+
+
+/* SSL_SUCCESS on ok */
+int wolfSSL_BN_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
+{
+    int           ret    = 0;
+    int           len    = bits / 8;
+    int           initTmpRng = 0;
+    WC_RNG*       rng    = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG*       tmpRNG = NULL;
+    byte*         buff   = NULL;
+#else
+    WC_RNG        tmpRNG[1];
+    byte          buff[1024];
+#endif
+
+    (void)top;
+    (void)bottom;
+    WOLFSSL_MSG("wolfSSL_BN_rand");
+
+    if (bits % 8)
+        len++;
+
+#ifdef WOLFSSL_SMALL_STACK
+    buff   = (byte*)XMALLOC(1024,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    tmpRNG = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buff == NULL || tmpRNG == NULL) {
+        XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+#endif
+
+    if (bn == NULL || bn->internal == NULL)
+        WOLFSSL_MSG("Bad function arguments");
+    else if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else if (initGlobalRNG)
+        rng = &globalRNG;
+
+    if (rng) {
+        if (wc_RNG_GenerateBlock(rng, buff, len) != 0)
+            WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
+        else {
+            buff[0]     |= 0x80 | 0x40;
+            buff[len-1] |= 0x01;
+
+            if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY)
+                WOLFSSL_MSG("mp read bin failed");
+            else
+                ret = SSL_SUCCESS;
+        }
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if bit set, 0 else
+ */
+int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM* bn, int n)
+{
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return SSL_FAILURE;
+    }
+
+    return mp_is_bit_set((mp_int*)bn->internal, n);
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 else
+ */
+int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n)
+{
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return SSL_FAILURE;
+    }
+
+    if (mp_set_bit((mp_int*)bn->internal, n) != MP_OKAY) {
+        WOLFSSL_MSG("mp_set_int error");
+        return SSL_FAILURE;
+    }
+
+    return SSL_SUCCESS;
+}
+
+
+/* SSL_SUCCESS on ok */
+int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str)
+{
+    int     ret     = 0;
+    word32  decSz   = 1024;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*   decoded = NULL;
+#else
+    byte    decoded[1024];
+#endif
+
+    WOLFSSL_MSG("wolfSSL_BN_hex2bn");
+
+#ifdef WOLFSSL_SMALL_STACK
+    decoded = (byte*)XMALLOC(decSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (decoded == NULL)
+        return ret;
+#endif
+
+    if (str == NULL)
+        WOLFSSL_MSG("Bad function argument");
+    else if (Base16_Decode((byte*)str, (int)XSTRLEN(str), decoded, &decSz) < 0)
+        WOLFSSL_MSG("Bad Base16_Decode error");
+    else if (bn == NULL)
+        ret = decSz;
+    else {
+        if (*bn == NULL)
+            *bn = wolfSSL_BN_new();
+
+        if (*bn == NULL)
+            WOLFSSL_MSG("BN new failed");
+        else if (wolfSSL_BN_bin2bn(decoded, decSz, *bn) == NULL)
+            WOLFSSL_MSG("Bad bin2bn error");
+        else
+            ret = SSL_SUCCESS;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+WOLFSSL_BIGNUM* wolfSSL_BN_dup(const WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_BIGNUM* ret;
+
+    WOLFSSL_MSG("wolfSSL_BN_dup");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return NULL;
+    }
+
+    ret = wolfSSL_BN_new();
+    if (ret == NULL) {
+        WOLFSSL_MSG("bn new error");
+        return NULL;
+    }
+
+    if (mp_copy((mp_int*)bn->internal, (mp_int*)ret->internal) != MP_OKAY) {
+        WOLFSSL_MSG("mp_copy error");
+        wolfSSL_BN_free(ret);
+        return NULL;
+    }
+
+    ret->neg = bn->neg;
+
+    return ret;
+}
+
+
+WOLFSSL_BIGNUM* wolfSSL_BN_copy(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* bn)
+{
+    WOLFSSL_MSG("wolfSSL_BN_copy");
+
+    if (mp_copy((mp_int*)bn->internal, (mp_int*)r->internal) != MP_OKAY) {
+        WOLFSSL_MSG("mp_copy error");
+        return NULL;
+    }
+
+    r->neg = bn->neg;
+
+    return r;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 else
+ */
+int wolfSSL_BN_set_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
+{
+    WOLFSSL_MSG("wolfSSL_BN_set_word");
+
+    if (mp_set_int((mp_int*)bn->internal, w) != MP_OKAY) {
+        WOLFSSL_MSG("mp_init_set_int error");
+        return SSL_FAILURE;
+    }
+
+    return SSL_SUCCESS;
+}
+
+/* return code compliant with OpenSSL :
+ *   number length in decimal if success, 0 if error
+ */
+int wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM** bn, const char* str)
+{
+    (void)bn;
+    (void)str;
+
+    WOLFSSL_MSG("wolfSSL_BN_dec2bn");
+
+    return SSL_FAILURE;
+}
+
+
+#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
+char *wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM *bn)
+{
+    int len = 0;
+    char *buf;
+
+    WOLFSSL_MSG("wolfSSL_BN_bn2dec");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return NULL;
+    }
+
+    if (mp_radix_size((mp_int*)bn->internal, 10, &len) != MP_OKAY) {
+        WOLFSSL_MSG("mp_radix_size failure");
+        return NULL;
+    }
+
+    buf = (char*) XMALLOC(len, NULL, DYNAMIC_TYPE_ECC);
+    if (buf == NULL) {
+        WOLFSSL_MSG("wolfSSL_BN_bn2hex malloc buffer failure");
+        return NULL;
+    }
+
+    if (mp_toradix((mp_int*)bn->internal, buf, 10) != MP_OKAY) {
+        XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
+        return NULL;
+    }
+    
+    return buf;
+}
+#else
+char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM* bn)
+{
+    (void)bn;
+
+    WOLFSSL_MSG("wolfSSL_BN_bn2dec");
+
+    return NULL;
+}
+#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 else
+ */
+int wolfSSL_BN_lshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
+{
+    WOLFSSL_MSG("wolfSSL_BN_lshift");
+
+    if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
+        WOLFSSL_MSG("bn NULL error");
+        return SSL_FAILURE;
+    }
+
+    if (mp_mul_2d((mp_int*)bn->internal, n, (mp_int*)r->internal) != MP_OKAY) {
+        WOLFSSL_MSG("mp_mul_2d error");
+        return SSL_FAILURE;
+    }
+
+    return SSL_SUCCESS;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 else
+ */
+int wolfSSL_BN_rshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
+{
+    WOLFSSL_MSG("wolfSSL_BN_rshift");
+
+    if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
+        WOLFSSL_MSG("bn NULL error");
+        return SSL_FAILURE;
+    }
+
+    if (mp_div_2d((mp_int*)bn->internal, n,
+                  (mp_int*)r->internal, NULL) != MP_OKAY) {
+        WOLFSSL_MSG("mp_mul_2d error");
+        return SSL_FAILURE;
+    }
+
+    return SSL_SUCCESS;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 else
+ */
+int wolfSSL_BN_add_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w)
+{
+    WOLFSSL_MSG("wolfSSL_BN_add_word");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return SSL_FAILURE;
+    }
+
+    if (mp_add_d((mp_int*)bn->internal, w, (mp_int*)bn->internal) != MP_OKAY) {
+        WOLFSSL_MSG("mp_add_d error");
+        return SSL_FAILURE;
+    }
+
+    return SSL_SUCCESS;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 else
+ */
+int wolfSSL_BN_add(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a, WOLFSSL_BIGNUM *b)
+{
+    WOLFSSL_MSG("wolfSSL_BN_add");
+
+    if (r == NULL || r->internal == NULL || a == NULL || a->internal == NULL ||
+        b == NULL || b->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return SSL_FAILURE;
+    }
+
+    if (mp_add((mp_int*)a->internal, (mp_int*)b->internal,
+               (mp_int*)r->internal) != MP_OKAY) {
+        WOLFSSL_MSG("mp_add_d error");
+        return SSL_FAILURE;
+    }
+
+    return SSL_SUCCESS;
+}
+
+#ifdef WOLFSSL_KEY_GEN
+
+/* return code compliant with OpenSSL :
+ *   1 if prime, 0 if not, -1 if error
+ */
+int wolfSSL_BN_is_prime_ex(const WOLFSSL_BIGNUM *bn, int nbchecks,
+                           WOLFSSL_BN_CTX *ctx, WOLFSSL_BN_GENCB *cb)
+{
+    int res;
+
+    (void)ctx;
+    (void)cb;
+
+    WOLFSSL_MSG("wolfSSL_BN_is_prime_ex");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (mp_prime_is_prime((mp_int*)bn->internal, nbchecks, &res) != MP_OKAY) {
+        WOLFSSL_MSG("mp_prime_is_prime error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (res != MP_YES) {
+        WOLFSSL_MSG("mp_prime_is_prime not prime");
+        return SSL_FAILURE;
+    }
+
+    return SSL_SUCCESS;
+}
+
+/* return code compliant with OpenSSL :
+ *   (bn mod w) if success, -1 if error
+ */
+WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM *bn,
+                                     WOLFSSL_BN_ULONG w)
+{
+    WOLFSSL_BN_ULONG ret = 0;
+
+    WOLFSSL_MSG("wolfSSL_BN_mod_word");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return (WOLFSSL_BN_ULONG)SSL_FATAL_ERROR;
+    }
+
+    if (mp_mod_d((mp_int*)bn->internal, w, &ret) != MP_OKAY) {
+        WOLFSSL_MSG("mp_add_d error");
+        return (WOLFSSL_BN_ULONG)SSL_FATAL_ERROR;
+    }
+
+    return ret;
+}
+#endif /* #ifdef WOLFSSL_KEY_GEN */
+
+#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
+char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn)
+{
+    int len = 0;
+    char *buf;
+
+    WOLFSSL_MSG("wolfSSL_BN_bn2hex");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return NULL;
+    }
+
+    if (mp_radix_size((mp_int*)bn->internal, 16, &len) != MP_OKAY) {
+        WOLFSSL_MSG("mp_radix_size failure");
+        return NULL;
+    }
+
+    buf = (char*) XMALLOC(len, NULL, DYNAMIC_TYPE_ECC);
+    if (buf == NULL) {
+        WOLFSSL_MSG("wolfSSL_BN_bn2hex malloc buffer failure");
+        return NULL;
+    }
+
+    if (mp_toradix((mp_int*)bn->internal, buf, 16) != MP_OKAY) {
+        XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
+        return NULL;
+    }
+
+    return buf;
+}
+
+#ifndef NO_FILESYSTEM
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_BN_print_fp(XFILE fp, const WOLFSSL_BIGNUM *bn)
+{
+    char *buf;
+
+    WOLFSSL_MSG("wolfSSL_BN_print_fp");
+
+    if (fp == NULL || bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return SSL_FAILURE;
+    }
+
+    buf = wolfSSL_BN_bn2hex(bn);
+    if (buf == NULL) {
+        WOLFSSL_MSG("wolfSSL_BN_bn2hex failure");
+        return SSL_FAILURE;
+    }
+
+    fprintf(fp, "%s", buf);
+    XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
+
+    return SSL_SUCCESS;
+}
+#endif /* !defined(NO_FILESYSTEM) */
+
+#else /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
+
+char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn)
+{
+    (void)bn;
+
+    WOLFSSL_MSG("wolfSSL_BN_bn2hex not implemented");
+
+    return (char*)"";
+}
+
+#ifndef NO_FILESYSTEM
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_BN_print_fp(XFILE fp, const WOLFSSL_BIGNUM *bn)
+{
+    (void)fp;
+    (void)bn;
+
+    WOLFSSL_MSG("wolfSSL_BN_print_fp not implemented");
+
+    return SSL_SUCCESS;
+}
+#endif /* !defined(NO_FILESYSTEM) */
+
+#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
+
+WOLFSSL_BIGNUM *wolfSSL_BN_CTX_get(WOLFSSL_BN_CTX *ctx)
+{
+    /* ctx is not used, return new Bignum */
+    (void)ctx;
+
+    WOLFSSL_ENTER("wolfSSL_BN_CTX_get");
+
+    return wolfSSL_BN_new();
+}
+
+void wolfSSL_BN_CTX_start(WOLFSSL_BN_CTX *ctx)
+{
+    (void)ctx;
+
+    WOLFSSL_ENTER("wolfSSL_BN_CTX_start");
+    WOLFSSL_MSG("wolfSSL_BN_CTX_start TBD");
+}
+
+#ifndef NO_DH
+
+static void InitwolfSSL_DH(WOLFSSL_DH* dh)
+{
+    if (dh) {
+        dh->p        = NULL;
+        dh->g        = NULL;
+        dh->pub_key  = NULL;
+        dh->priv_key = NULL;
+        dh->internal = NULL;
+        dh->inSet    = 0;
+        dh->exSet    = 0;
+    }
+}
+
+
+WOLFSSL_DH* wolfSSL_DH_new(void)
+{
+    WOLFSSL_DH* external;
+    DhKey*     key;
+
+    WOLFSSL_MSG("wolfSSL_DH_new");
+
+    key = (DhKey*) XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
+    if (key == NULL) {
+        WOLFSSL_MSG("wolfSSL_DH_new malloc DhKey failure");
+        return NULL;
+    }
+
+    external = (WOLFSSL_DH*) XMALLOC(sizeof(WOLFSSL_DH), NULL,
+                                    DYNAMIC_TYPE_DH);
+    if (external == NULL) {
+        WOLFSSL_MSG("wolfSSL_DH_new malloc WOLFSSL_DH failure");
+        XFREE(key, NULL, DYNAMIC_TYPE_DH);
+        return NULL;
+    }
+
+    InitwolfSSL_DH(external);
+    wc_InitDhKey(key);
+    external->internal = key;
+
+    return external;
+}
+
+
+void wolfSSL_DH_free(WOLFSSL_DH* dh)
+{
+    WOLFSSL_MSG("wolfSSL_DH_free");
+
+    if (dh) {
+        if (dh->internal) {
+            wc_FreeDhKey((DhKey*)dh->internal);
+            XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH);
+            dh->internal = NULL;
+        }
+        wolfSSL_BN_free(dh->priv_key);
+        wolfSSL_BN_free(dh->pub_key);
+        wolfSSL_BN_free(dh->g);
+        wolfSSL_BN_free(dh->p);
+        InitwolfSSL_DH(dh);  /* set back to NULLs for safety */
+
+        XFREE(dh, NULL, DYNAMIC_TYPE_DH);
+    }
+}
+
+
+static int SetDhInternal(WOLFSSL_DH* dh)
+{
+    int            ret = SSL_FATAL_ERROR;
+    int            pSz = 1024;
+    int            gSz = 1024;
+#ifdef WOLFSSL_SMALL_STACK
+    unsigned char* p   = NULL;
+    unsigned char* g   = NULL;
+#else
+    unsigned char  p[1024];
+    unsigned char  g[1024];
+#endif
+
+    WOLFSSL_ENTER("SetDhInternal");
+
+    if (dh == NULL || dh->p == NULL || dh->g == NULL)
+        WOLFSSL_MSG("Bad function arguments");
+    else if (wolfSSL_BN_bn2bin(dh->p, NULL) > pSz)
+        WOLFSSL_MSG("Bad p internal size");
+    else if (wolfSSL_BN_bn2bin(dh->g, NULL) > gSz)
+        WOLFSSL_MSG("Bad g internal size");
+    else {
+    #ifdef WOLFSSL_SMALL_STACK
+        p = (unsigned char*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        g = (unsigned char*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        if (p == NULL || g == NULL) {
+            XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return ret;
+        }
+    #endif
+
+        pSz = wolfSSL_BN_bn2bin(dh->p, p);
+        gSz = wolfSSL_BN_bn2bin(dh->g, g);
+
+        if (pSz <= 0 || gSz <= 0)
+            WOLFSSL_MSG("Bad BN2bin set");
+        else if (wc_DhSetKey((DhKey*)dh->internal, p, pSz, g, gSz) < 0)
+            WOLFSSL_MSG("Bad DH SetKey");
+        else {
+            dh->inSet = 1;
+            ret = SSL_SUCCESS;
+        }
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+    }
+
+
+    return ret;
+}
+
+/* return code compliant with OpenSSL :
+ *   DH prime size in bytes if success, 0 if error
+ */
+int wolfSSL_DH_size(WOLFSSL_DH* dh)
+{
+    WOLFSSL_MSG("wolfSSL_DH_size");
+
+    if (dh == NULL)
+        return SSL_FATAL_ERROR;
+
+    return wolfSSL_BN_num_bytes(dh->p);
+}
+
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
+{
+    int            ret    = SSL_FAILURE;
+    word32         pubSz  = 768;
+    word32         privSz = 768;
+    int            initTmpRng = 0;
+    WC_RNG*        rng    = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    unsigned char* pub    = NULL;
+    unsigned char* priv   = NULL;
+    WC_RNG*        tmpRNG = NULL;
+#else
+    unsigned char  pub [768];
+    unsigned char  priv[768];
+    WC_RNG         tmpRNG[1];
+#endif
+
+    WOLFSSL_MSG("wolfSSL_DH_generate_key");
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    pub    = (unsigned char*)XMALLOC(pubSz,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    priv   = (unsigned char*)XMALLOC(privSz,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (tmpRNG == NULL || pub == NULL || priv == NULL) {
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(pub,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(priv,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+#endif
+
+    if (dh == NULL || dh->p == NULL || dh->g == NULL)
+        WOLFSSL_MSG("Bad function arguments");
+    else if (dh->inSet == 0 && SetDhInternal(dh) != SSL_SUCCESS)
+            WOLFSSL_MSG("Bad DH set internal");
+    else if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+       if (wc_DhGenerateKeyPair((DhKey*)dh->internal, rng, priv, &privSz,
+                                                               pub, &pubSz) < 0)
+            WOLFSSL_MSG("Bad wc_DhGenerateKeyPair");
+       else {
+            if (dh->pub_key)
+                wolfSSL_BN_free(dh->pub_key);
+
+            dh->pub_key = wolfSSL_BN_new();
+            if (dh->pub_key == NULL) {
+                WOLFSSL_MSG("Bad DH new pub");
+            }
+            if (dh->priv_key)
+                wolfSSL_BN_free(dh->priv_key);
+
+            dh->priv_key = wolfSSL_BN_new();
+
+            if (dh->priv_key == NULL) {
+                WOLFSSL_MSG("Bad DH new priv");
+            }
+
+            if (dh->pub_key && dh->priv_key) {
+               if (wolfSSL_BN_bin2bn(pub, pubSz, dh->pub_key) == NULL)
+                   WOLFSSL_MSG("Bad DH bn2bin error pub");
+               else if (wolfSSL_BN_bin2bn(priv, privSz, dh->priv_key) == NULL)
+                   WOLFSSL_MSG("Bad DH bn2bin error priv");
+               else
+                   ret = SSL_SUCCESS;
+            }
+        }
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(pub,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(priv,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+/* return code compliant with OpenSSL :
+ *   size of shared secret if success, -1 if error
+ */
+int wolfSSL_DH_compute_key(unsigned char* key, WOLFSSL_BIGNUM* otherPub,
+                          WOLFSSL_DH* dh)
+{
+    int            ret    = SSL_FATAL_ERROR;
+    word32         keySz  = 0;
+    word32         pubSz  = 1024;
+    word32         privSz = 1024;
+#ifdef WOLFSSL_SMALL_STACK
+    unsigned char* pub    = NULL;
+    unsigned char* priv   = NULL;
+#else
+    unsigned char  pub [1024];
+    unsigned char  priv[1024];
+#endif
+
+    WOLFSSL_MSG("wolfSSL_DH_compute_key");
+
+#ifdef WOLFSSL_SMALL_STACK
+    pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pub == NULL)
+        return ret;
+
+    priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (priv == NULL) {
+        XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+#endif
+
+    if (dh == NULL || dh->priv_key == NULL || otherPub == NULL)
+        WOLFSSL_MSG("Bad function arguments");
+    else if ((keySz = (word32)DH_size(dh)) == 0)
+        WOLFSSL_MSG("Bad DH_size");
+    else if (wolfSSL_BN_bn2bin(dh->priv_key, NULL) > (int)privSz)
+        WOLFSSL_MSG("Bad priv internal size");
+    else if (wolfSSL_BN_bn2bin(otherPub, NULL) > (int)pubSz)
+        WOLFSSL_MSG("Bad otherPub size");
+    else {
+        privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv);
+        pubSz  = wolfSSL_BN_bn2bin(otherPub, pub);
+
+        if (privSz <= 0 || pubSz <= 0)
+            WOLFSSL_MSG("Bad BN2bin set");
+        else if (wc_DhAgree((DhKey*)dh->internal, key, &keySz,
+                            priv, privSz, pub, pubSz) < 0)
+            WOLFSSL_MSG("wc_DhAgree failed");
+        else
+            ret = (int)keySz;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(pub,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+#endif /* NO_DH */
+
+
+#ifndef NO_DSA
+static void InitwolfSSL_DSA(WOLFSSL_DSA* dsa)
+{
+    if (dsa) {
+        dsa->p        = NULL;
+        dsa->q        = NULL;
+        dsa->g        = NULL;
+        dsa->pub_key  = NULL;
+        dsa->priv_key = NULL;
+        dsa->internal = NULL;
+        dsa->inSet    = 0;
+        dsa->exSet    = 0;
+    }
+}
+
+
+WOLFSSL_DSA* wolfSSL_DSA_new(void)
+{
+    WOLFSSL_DSA* external;
+    DsaKey*     key;
+
+    WOLFSSL_MSG("wolfSSL_DSA_new");
+
+    key = (DsaKey*) XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
+    if (key == NULL) {
+        WOLFSSL_MSG("wolfSSL_DSA_new malloc DsaKey failure");
+        return NULL;
+    }
+
+    external = (WOLFSSL_DSA*) XMALLOC(sizeof(WOLFSSL_DSA), NULL,
+                                    DYNAMIC_TYPE_DSA);
+    if (external == NULL) {
+        WOLFSSL_MSG("wolfSSL_DSA_new malloc WOLFSSL_DSA failure");
+        XFREE(key, NULL, DYNAMIC_TYPE_DSA);
+        return NULL;
+    }
+
+    InitwolfSSL_DSA(external);
+    InitDsaKey(key);
+    external->internal = key;
+
+    return external;
+}
+
+
+void wolfSSL_DSA_free(WOLFSSL_DSA* dsa)
+{
+    WOLFSSL_MSG("wolfSSL_DSA_free");
+
+    if (dsa) {
+        if (dsa->internal) {
+            FreeDsaKey((DsaKey*)dsa->internal);
+            XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA);
+            dsa->internal = NULL;
+        }
+        wolfSSL_BN_free(dsa->priv_key);
+        wolfSSL_BN_free(dsa->pub_key);
+        wolfSSL_BN_free(dsa->g);
+        wolfSSL_BN_free(dsa->q);
+        wolfSSL_BN_free(dsa->p);
+        InitwolfSSL_DSA(dsa);  /* set back to NULLs for safety */
+
+        XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
+        dsa = NULL;
+    }
+}
+#endif /* NO_DSA */
+
+#ifndef NO_RSA
+static void InitwolfSSL_Rsa(WOLFSSL_RSA* rsa)
+{
+    if (rsa) {
+        rsa->n        = NULL;
+        rsa->e        = NULL;
+        rsa->d        = NULL;
+        rsa->p        = NULL;
+        rsa->q        = NULL;
+        rsa->dmp1     = NULL;
+        rsa->dmq1     = NULL;
+        rsa->iqmp     = NULL;
+        rsa->internal = NULL;
+        rsa->inSet    = 0;
+        rsa->exSet    = 0;
+    }
+}
+
+
+WOLFSSL_RSA* wolfSSL_RSA_new(void)
+{
+    WOLFSSL_RSA* external;
+    RsaKey*     key;
+
+    WOLFSSL_MSG("wolfSSL_RSA_new");
+
+    key = (RsaKey*) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
+    if (key == NULL) {
+        WOLFSSL_MSG("wolfSSL_RSA_new malloc RsaKey failure");
+        return NULL;
+    }
+
+    external = (WOLFSSL_RSA*) XMALLOC(sizeof(WOLFSSL_RSA), NULL,
+                                     DYNAMIC_TYPE_RSA);
+    if (external == NULL) {
+        WOLFSSL_MSG("wolfSSL_RSA_new malloc WOLFSSL_RSA failure");
+        XFREE(key, NULL, DYNAMIC_TYPE_RSA);
+        return NULL;
+    }
+
+    InitwolfSSL_Rsa(external);
+    if (wc_InitRsaKey(key, NULL) != 0) {
+        WOLFSSL_MSG("InitRsaKey WOLFSSL_RSA failure");
+        XFREE(external, NULL, DYNAMIC_TYPE_RSA);
+        XFREE(key, NULL, DYNAMIC_TYPE_RSA);
+        return NULL;
+    }
+    external->internal = key;
+
+    return external;
+}
+
+
+void wolfSSL_RSA_free(WOLFSSL_RSA* rsa)
+{
+    WOLFSSL_MSG("wolfSSL_RSA_free");
+
+    if (rsa) {
+        if (rsa->internal) {
+            wc_FreeRsaKey((RsaKey*)rsa->internal);
+            XFREE(rsa->internal, NULL, DYNAMIC_TYPE_RSA);
+            rsa->internal = NULL;
+        }
+        wolfSSL_BN_free(rsa->iqmp);
+        wolfSSL_BN_free(rsa->dmq1);
+        wolfSSL_BN_free(rsa->dmp1);
+        wolfSSL_BN_free(rsa->q);
+        wolfSSL_BN_free(rsa->p);
+        wolfSSL_BN_free(rsa->d);
+        wolfSSL_BN_free(rsa->e);
+        wolfSSL_BN_free(rsa->n);
+        InitwolfSSL_Rsa(rsa);  /* set back to NULLs for safety */
+
+        XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
+        rsa = NULL;
+    }
+}
+#endif /* NO_RSA */
+
+
+#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)) \
+    || !defined(NO_DSA) || defined(HAVE_ECC)
+static int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi)
+{
+    WOLFSSL_MSG("Entering SetIndividualExternal");
+
+    if (mpi == NULL || bn == NULL) {
+        WOLFSSL_MSG("mpi NULL error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (*bn == NULL) {
+        *bn = wolfSSL_BN_new();
+        if (*bn == NULL) {
+            WOLFSSL_MSG("SetIndividualExternal alloc failed");
+            return SSL_FATAL_ERROR;
+        }
+    }
+
+    if (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY) {
+        WOLFSSL_MSG("mp_copy error");
+        return SSL_FATAL_ERROR;
+    }
+
+    return SSL_SUCCESS;
+}
+
+static int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi)
+{
+    WOLFSSL_MSG("Entering SetIndividualInternal");
+
+    if (bn == NULL || bn->internal == NULL) {
+        WOLFSSL_MSG("bn NULL error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (mpi == NULL || (mp_init(mpi) != MP_OKAY)) {
+        WOLFSSL_MSG("mpi NULL error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (mp_copy((mp_int*)bn->internal, mpi) != MP_OKAY) {
+        WOLFSSL_MSG("mp_copy error");
+        return SSL_FATAL_ERROR;
+    }
+
+    return SSL_SUCCESS;
+}
+#endif /* !NO_RSA && !NO_DSA */
+
+
+#ifndef NO_DSA
+/* wolfSSL -> OpenSSL */
+static int SetDsaExternal(WOLFSSL_DSA* dsa)
+{
+    DsaKey* key;
+    WOLFSSL_MSG("Entering SetDsaExternal");
+
+    if (dsa == NULL || dsa->internal == NULL) {
+        WOLFSSL_MSG("dsa key NULL error");
+        return SSL_FATAL_ERROR;
+    }
+
+    key = (DsaKey*)dsa->internal;
+
+    if (SetIndividualExternal(&dsa->p, &key->p) != SSL_SUCCESS) {
+        WOLFSSL_MSG("dsa p key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&dsa->q, &key->q) != SSL_SUCCESS) {
+        WOLFSSL_MSG("dsa q key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&dsa->g, &key->g) != SSL_SUCCESS) {
+        WOLFSSL_MSG("dsa g key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&dsa->pub_key, &key->y) != SSL_SUCCESS) {
+        WOLFSSL_MSG("dsa y key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&dsa->priv_key, &key->x) != SSL_SUCCESS) {
+        WOLFSSL_MSG("dsa x key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    dsa->exSet = 1;
+
+    return SSL_SUCCESS;
+}
+
+/* Openssl -> WolfSSL */
+static int SetDsaInternal(WOLFSSL_DSA* dsa)
+{
+    DsaKey* key;
+    WOLFSSL_MSG("Entering SetDsaInternal");
+
+    if (dsa == NULL || dsa->internal == NULL) {
+        WOLFSSL_MSG("dsa key NULL error");
+        return SSL_FATAL_ERROR;
+    }
+
+    key = (DsaKey*)dsa->internal;
+
+    if (dsa->p != NULL &&
+        SetIndividualInternal(dsa->p, &key->p) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa p key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (dsa->q != NULL &&
+        SetIndividualInternal(dsa->q, &key->q) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa q key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (dsa->g != NULL &&
+        SetIndividualInternal(dsa->g, &key->g) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa g key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (dsa->pub_key != NULL) {
+        if (SetIndividualInternal(dsa->pub_key, &key->y) != SSL_SUCCESS) {
+            WOLFSSL_MSG("rsa pub_key error");
+            return SSL_FATAL_ERROR;
+        }
+
+        /* public key */
+        key->type = DSA_PUBLIC;
+    }
+
+    if (dsa->priv_key != NULL) {
+        if (SetIndividualInternal(dsa->priv_key, &key->x) != SSL_SUCCESS) {
+            WOLFSSL_MSG("rsa priv_key error");
+            return SSL_FATAL_ERROR;
+        }
+
+        /* private key */
+        key->type = DSA_PRIVATE;
+    }
+
+    dsa->inSet = 1;
+
+    return SSL_SUCCESS;
+}
+#endif /* NO_DSA */
+
+
+#if !defined(NO_RSA)
+#if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
+/* WolfSSL -> OpenSSL */
+static int SetRsaExternal(WOLFSSL_RSA* rsa)
+{
+    RsaKey* key;
+    WOLFSSL_MSG("Entering SetRsaExternal");
+
+    if (rsa == NULL || rsa->internal == NULL) {
+        WOLFSSL_MSG("rsa key NULL error");
+        return SSL_FATAL_ERROR;
+    }
+
+    key = (RsaKey*)rsa->internal;
+
+    if (SetIndividualExternal(&rsa->n, &key->n) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa n key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&rsa->e, &key->e) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa e key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&rsa->d, &key->d) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa d key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&rsa->p, &key->p) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa p key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&rsa->q, &key->q) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa q key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&rsa->dmp1, &key->dP) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa dP key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&rsa->dmq1, &key->dQ) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa dQ key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&rsa->iqmp, &key->u) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa u key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    rsa->exSet = 1;
+
+    return SSL_SUCCESS;
+}
+
+/* Openssl -> WolfSSL */
+static int SetRsaInternal(WOLFSSL_RSA* rsa)
+{
+    RsaKey* key;
+    WOLFSSL_MSG("Entering SetRsaInternal");
+
+    if (rsa == NULL || rsa->internal == NULL) {
+        WOLFSSL_MSG("rsa key NULL error");
+        return SSL_FATAL_ERROR;
+    }
+
+    key = (RsaKey*)rsa->internal;
+
+    if (SetIndividualInternal(rsa->n, &key->n) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa n key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualInternal(rsa->e, &key->e) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa e key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    /* public key */
+    key->type = RSA_PUBLIC;
+
+    if (rsa->d != NULL) {
+        if (SetIndividualInternal(rsa->d, &key->d) != SSL_SUCCESS) {
+            WOLFSSL_MSG("rsa d key error");
+            return SSL_FATAL_ERROR;
+        }
+
+        /* private key */
+        key->type = RSA_PRIVATE;
+    }
+
+    if (rsa->p != NULL &&
+        SetIndividualInternal(rsa->p, &key->p) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa p key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (rsa->q != NULL &&
+        SetIndividualInternal(rsa->q, &key->q) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa q key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (rsa->dmp1 != NULL &&
+        SetIndividualInternal(rsa->dmp1, &key->dP) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa dP key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (rsa->dmq1 != NULL &&
+        SetIndividualInternal(rsa->dmq1, &key->dQ) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa dQ key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (rsa->iqmp != NULL &&
+        SetIndividualInternal(rsa->iqmp, &key->u) != SSL_SUCCESS) {
+        WOLFSSL_MSG("rsa u key error");
+        return SSL_FATAL_ERROR;
+    }
+
+    rsa->inSet = 1;
+
+    return SSL_SUCCESS;
+}
+#endif /* HAVE_USER_RSA */
+
+/* return compliant with OpenSSL
+ *   1 if success, 0 if error
+ */
+int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn,
+                                void* cb)
+{
+    int ret = SSL_FAILURE;
+
+    (void)cb;
+    (void)bn;
+    (void)bits;
+
+    WOLFSSL_ENTER("wolfSSL_RSA_generate_key_ex");
+
+    if (rsa == NULL || rsa->internal == NULL) {
+        /* bit size checked during make key call */
+        WOLFSSL_MSG("bad arguments");
+        return SSL_FAILURE;
+    }
+
+#ifdef WOLFSSL_KEY_GEN
+    {
+    #ifdef WOLFSSL_SMALL_STACK
+        WC_RNG* rng = NULL;
+    #else
+        WC_RNG  rng[1];
+    #endif
+
+    #ifdef WOLFSSL_SMALL_STACK
+        rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (rng == NULL)
+            return SSL_FAILURE;
+    #endif
+
+        if (wc_InitRng(rng) < 0)
+            WOLFSSL_MSG("RNG init failed");
+        else if (wc_MakeRsaKey((RsaKey*)rsa->internal,
+                               bits, 65537, rng) != MP_OKAY)
+            WOLFSSL_MSG("wc_MakeRsaKey failed");
+        else if (SetRsaExternal(rsa) != SSL_SUCCESS)
+            WOLFSSL_MSG("SetRsaExternal failed");
+        else {
+            rsa->inSet = 1;
+            ret = SSL_SUCCESS;
+        }
+
+        wc_FreeRng(rng);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+    }
+#else
+    WOLFSSL_MSG("No Key Gen built in");
+#endif
+    return ret;
+}
+
+
+/* SSL_SUCCESS on ok */
+int wolfSSL_RSA_blinding_on(WOLFSSL_RSA* rsa, WOLFSSL_BN_CTX* bn)
+{
+    (void)rsa;
+    (void)bn;
+
+    WOLFSSL_MSG("wolfSSL_RSA_blinding_on");
+
+    return SSL_SUCCESS;  /* on by default */
+}
+
+/* return compliant with OpenSSL
+ *   size of encrypted data if success , -1 if error
+ */
+int wolfSSL_RSA_public_encrypt(int len, unsigned char* fr,
+                            unsigned char* to, WOLFSSL_RSA* rsa, int padding)
+{
+    (void)len;
+    (void)fr;
+    (void)to;
+    (void)rsa;
+    (void)padding;
+
+    WOLFSSL_MSG("wolfSSL_RSA_public_encrypt");
+
+    return SSL_FATAL_ERROR;
+}
+
+/* return compliant with OpenSSL
+ *   size of plain recovered data if success , -1 if error
+ */
+int wolfSSL_RSA_private_decrypt(int len, unsigned char* fr,
+                            unsigned char* to, WOLFSSL_RSA* rsa, int padding)
+{
+    (void)len;
+    (void)fr;
+    (void)to;
+    (void)rsa;
+    (void)padding;
+
+    WOLFSSL_MSG("wolfSSL_RSA_private_decrypt");
+
+    return SSL_FATAL_ERROR;
+}
+
+/* return compliant with OpenSSL
+ *   RSA modulus size in bytes, -1 if error
+ */
+int wolfSSL_RSA_size(const WOLFSSL_RSA* rsa)
+{
+    WOLFSSL_MSG("wolfSSL_RSA_size");
+
+    if (rsa == NULL)
+        return SSL_FATAL_ERROR;
+
+    return wolfSSL_BN_num_bytes(rsa->n);
+}
+#endif /* NO_RSA */
+
+#ifndef NO_DSA
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa)
+{
+    int ret = SSL_FAILURE;
+
+    WOLFSSL_ENTER("wolfSSL_DSA_generate_key");
+
+    if (dsa == NULL || dsa->internal == NULL) {
+        WOLFSSL_MSG("Bad arguments");
+        return SSL_FAILURE;
+    }
+
+    if (dsa->inSet == 0) {
+        WOLFSSL_MSG("No DSA internal set, do it");
+
+        if (SetDsaInternal(dsa) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetDsaInternal failed");
+            return ret;
+        }
+    }
+
+#ifdef WOLFSSL_KEY_GEN
+    {
+        int initTmpRng = 0;
+        WC_RNG *rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+        WC_RNG *tmpRNG = NULL;
+#else
+        WC_RNG tmpRNG[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+        tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (tmpRNG == NULL)
+            return SSL_FATAL_ERROR;
+#endif
+        if (wc_InitRng(tmpRNG) == 0) {
+            rng = tmpRNG;
+            initTmpRng = 1;
+        }
+        else {
+            WOLFSSL_MSG("Bad RNG Init, trying global");
+            if (initGlobalRNG == 0)
+                WOLFSSL_MSG("Global RNG no Init");
+            else
+                rng = &globalRNG;
+        }
+
+        if (rng) {
+            if (wc_MakeDsaKey(rng, (DsaKey*)dsa->internal) != MP_OKAY)
+                WOLFSSL_MSG("wc_MakeDsaKey failed");
+            else if (SetDsaExternal(dsa) != SSL_SUCCESS)
+                WOLFSSL_MSG("SetDsaExternal failed");
+            else
+                ret = SSL_SUCCESS;
+        }
+
+        if (initTmpRng)
+            wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+    }
+#else /* WOLFSSL_KEY_GEN */
+    WOLFSSL_MSG("No Key Gen built in");
+#endif
+    return ret;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits,
+                                       unsigned char* seed, int seedLen,
+                                       int* counterRet,
+                                       unsigned long* hRet, void* cb)
+{
+    int ret = SSL_FAILURE;
+
+    (void)bits;
+    (void)seed;
+    (void)seedLen;
+    (void)counterRet;
+    (void)hRet;
+    (void)cb;
+
+    WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters_ex");
+
+    if (dsa == NULL || dsa->internal == NULL) {
+        WOLFSSL_MSG("Bad arguments");
+        return SSL_FAILURE;
+    }
+
+#ifdef WOLFSSL_KEY_GEN
+    {
+        int initTmpRng = 0;
+        WC_RNG *rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+        WC_RNG *tmpRNG = NULL;
+#else
+        WC_RNG tmpRNG[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+        tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (tmpRNG == NULL)
+            return SSL_FATAL_ERROR;
+#endif
+        if (wc_InitRng(tmpRNG) == 0) {
+            rng = tmpRNG;
+            initTmpRng = 1;
+        }
+        else {
+            WOLFSSL_MSG("Bad RNG Init, trying global");
+            if (initGlobalRNG == 0)
+                WOLFSSL_MSG("Global RNG no Init");
+            else
+                rng = &globalRNG;
+        }
+
+        if (rng) {
+            if (wc_MakeDsaParameters(rng, bits,
+                                     (DsaKey*)dsa->internal) != MP_OKAY)
+                WOLFSSL_MSG("wc_MakeDsaParameters failed");
+            else if (SetDsaExternal(dsa) != SSL_SUCCESS)
+                WOLFSSL_MSG("SetDsaExternal failed");
+            else
+                ret = SSL_SUCCESS;
+        }
+
+        if (initTmpRng)
+            wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+    }
+#else /* WOLFSSL_KEY_GEN */
+    WOLFSSL_MSG("No Key Gen built in");
+#endif
+
+    return ret;
+}
+
+/* return SSL_SUCCESS on success, < 0 otherwise */
+int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
+                       WOLFSSL_DSA* dsa)
+{
+    int     ret = SSL_FATAL_ERROR;
+    int     initTmpRng = 0;
+    WC_RNG* rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG* tmpRNG = NULL;
+#else
+    WC_RNG  tmpRNG[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_DSA_do_sign");
+
+    if (d == NULL || sigRet == NULL || dsa == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return ret;
+    }
+
+    if (dsa->inSet == 0)
+    {
+        WOLFSSL_MSG("No DSA internal set, do it");
+
+        if (SetDsaInternal(dsa) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetDsaInternal failed");
+            return ret;
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmpRNG == NULL)
+        return SSL_FATAL_ERROR;
+#endif
+
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+        if (DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0)
+            WOLFSSL_MSG("DsaSign failed");
+        else
+            ret = SSL_SUCCESS;
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
+                        WOLFSSL_DSA* dsa, int *dsacheck)
+{
+    int    ret = SSL_FATAL_ERROR;
+
+    WOLFSSL_ENTER("wolfSSL_DSA_do_verify");
+
+    if (d == NULL || sig == NULL || dsa == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return SSL_FATAL_ERROR;
+    }
+    if (dsa->inSet == 0)
+    {
+        WOLFSSL_MSG("No DSA internal set, do it");
+
+        if (SetDsaInternal(dsa) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetDsaInternal failed");
+            return SSL_FATAL_ERROR;
+        }
+    }
+
+    ret = DsaVerify(d, sig, (DsaKey*)dsa->internal, dsacheck);
+    if (ret != 0 || *dsacheck != 1) {
+        WOLFSSL_MSG("DsaVerify failed");
+        return ret;
+    }
+
+    return SSL_SUCCESS;
+}
+#endif /* NO_DSA */
+
+
+#ifndef NO_RSA
+/* return SSL_SUCCES on ok, 0 otherwise */
+int wolfSSL_RSA_sign(int type, const unsigned char* m,
+                           unsigned int mLen, unsigned char* sigRet,
+                           unsigned int* sigLen, WOLFSSL_RSA* rsa)
+{
+    word32  outLen;
+    word32  signSz;
+    int     initTmpRng = 0;
+    WC_RNG* rng        = NULL;
+    int     ret        = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG* tmpRNG     = NULL;
+    byte*   encodedSig = NULL;
+#else
+    WC_RNG  tmpRNG[1];
+    byte    encodedSig[MAX_ENCODED_SIG_SZ];
+#endif
+
+    WOLFSSL_MSG("wolfSSL_RSA_sign");
+
+    if (m == NULL || sigRet == NULL || sigLen == NULL || rsa == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return 0;
+    }
+
+    if (type != NID_md5 && type != NID_sha1) {
+        WOLFSSL_MSG("Bad md type");
+        return 0;
+    }
+
+    if (rsa->inSet == 0)
+    {
+        WOLFSSL_MSG("No RSA internal set, do it");
+
+        if (SetRsaInternal(rsa) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetRsaInternal failed");
+            return 0;
+        }
+    }
+
+    outLen = (word32)wolfSSL_BN_num_bytes(rsa->n);
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmpRNG == NULL)
+        return 0;
+
+    encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
+                                                   DYNAMIC_TYPE_TMP_BUFFER);
+    if (encodedSig == NULL) {
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return 0;
+    }
+#endif
+
+    if (outLen == 0)
+        WOLFSSL_MSG("Bad RSA size");
+    else if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+        type = (type == NID_md5) ? MD5h : SHAh;
+
+        signSz = wc_EncodeSignature(encodedSig, m, mLen, type);
+        if (signSz == 0) {
+            WOLFSSL_MSG("Bad Encode Signature");
+        }
+        else {
+            *sigLen = wc_RsaSSL_Sign(encodedSig, signSz, sigRet, outLen,
+                                  (RsaKey*)rsa->internal, rng);
+            if (*sigLen <= 0)
+                WOLFSSL_MSG("Bad Rsa Sign");
+            else
+                ret = SSL_SUCCESS;
+        }
+
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (ret == SSL_SUCCESS)
+        WOLFSSL_MSG("wolfSSL_RSA_sign success");
+    else {
+        WOLFSSL_MSG("wolfSSL_RSA_sign failed");
+    }
+    return ret;
+}
+
+
+int wolfSSL_RSA_public_decrypt(int flen, unsigned char* from,
+                          unsigned char* to, WOLFSSL_RSA* rsa, int padding)
+{
+    int tlen = 0;
+
+    WOLFSSL_MSG("wolfSSL_RSA_public_decrypt");
+
+    if (rsa == NULL || rsa->internal == NULL || from == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return 0;
+    }
+
+    if (padding != RSA_PKCS1_PADDING) {
+        WOLFSSL_MSG("wolfSSL_RSA_public_decrypt unsupported padding");
+        return 0;
+    }
+
+    if (rsa->inSet == 0)
+    {
+        WOLFSSL_MSG("No RSA internal set, do it");
+
+        if (SetRsaInternal(rsa) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetRsaInternal failed");
+            return 0;
+        }
+    }
+
+    /* size of 'to' buffer must be size of RSA key */
+    tlen = wc_RsaSSL_Verify(from, flen, to, wolfSSL_RSA_size(rsa),
+                            (RsaKey*)rsa->internal);
+    if (tlen <= 0)
+        WOLFSSL_MSG("wolfSSL_RSA_public_decrypt failed");
+    else {
+        WOLFSSL_MSG("wolfSSL_RSA_public_decrypt success");
+    }
+    return tlen;
+}
+
+
+/* generate p-1 and q-1, SSL_SUCCESS on ok */
+int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
+{
+    int    err;
+    mp_int tmp;
+
+    WOLFSSL_MSG("wolfSSL_RsaGenAdd");
+
+    if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->d == NULL ||
+                       rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
+        WOLFSSL_MSG("rsa no init error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (mp_init(&tmp) != MP_OKAY) {
+        WOLFSSL_MSG("mp_init error");
+        return SSL_FATAL_ERROR;
+    }
+
+    err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp);
+    if (err != MP_OKAY) {
+        WOLFSSL_MSG("mp_sub_d error");
+    }
+    else
+        err = mp_mod((mp_int*)rsa->d->internal, &tmp,
+                     (mp_int*)rsa->dmp1->internal);
+
+    if (err != MP_OKAY) {
+        WOLFSSL_MSG("mp_mod error");
+    }
+    else
+        err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp);
+    if (err != MP_OKAY) {
+        WOLFSSL_MSG("mp_sub_d error");
+    }
+    else
+        err = mp_mod((mp_int*)rsa->d->internal, &tmp,
+                     (mp_int*)rsa->dmq1->internal);
+
+    mp_clear(&tmp);
+
+    if (err == MP_OKAY)
+        return SSL_SUCCESS;
+    else
+        return SSL_FATAL_ERROR;
+}
+#endif /* NO_RSA */
+
+
+void wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen,
+                  const EVP_MD* type)
+{
+    WOLFSSL_MSG("wolfSSL_HMAC_Init");
+
+    if (ctx == NULL) {
+        WOLFSSL_MSG("no ctx on init");
+        return;
+    }
+
+    if (type) {
+        WOLFSSL_MSG("init has type");
+
+        if (XSTRNCMP(type, "MD5", 3) == 0) {
+            WOLFSSL_MSG("md5 hmac");
+            ctx->type = MD5;
+        }
+        else if (XSTRNCMP(type, "SHA256", 6) == 0) {
+            WOLFSSL_MSG("sha256 hmac");
+            ctx->type = SHA256;
+        }
+
+        /* has to be last since would pick or 256, 384, or 512 too */
+        else if (XSTRNCMP(type, "SHA", 3) == 0) {
+            WOLFSSL_MSG("sha hmac");
+            ctx->type = SHA;
+        }
+        else {
+            WOLFSSL_MSG("bad init type");
+        }
+    }
+
+    if (key && keylen) {
+        WOLFSSL_MSG("keying hmac");
+        wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key, (word32)keylen);
+        /* OpenSSL compat, no error */
+    }
+}
+
+
+void wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data,
+                    int len)
+{
+    WOLFSSL_MSG("wolfSSL_HMAC_Update");
+
+    if (ctx && data) {
+        WOLFSSL_MSG("updating hmac");
+        wc_HmacUpdate(&ctx->hmac, data, (word32)len);
+        /* OpenSSL compat, no error */
+    }
+}
+
+
+void wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash,
+                   unsigned int* len)
+{
+    WOLFSSL_MSG("wolfSSL_HMAC_Final");
+
+    if (ctx && hash) {
+        WOLFSSL_MSG("final hmac");
+        wc_HmacFinal(&ctx->hmac, hash);
+        /* OpenSSL compat, no error */
+
+        if (len) {
+            WOLFSSL_MSG("setting output len");
+            switch (ctx->type) {
+                case MD5:
+                    *len = MD5_DIGEST_SIZE;
+                    break;
+
+                case SHA:
+                    *len = SHA_DIGEST_SIZE;
+                    break;
+
+                case SHA256:
+                    *len = SHA256_DIGEST_SIZE;
+                    break;
+
+                default:
+                    WOLFSSL_MSG("bad hmac type");
+            }
+        }
+    }
+}
+
+
+void wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx)
+{
+    (void)ctx;
+
+    WOLFSSL_MSG("wolfSSL_HMAC_cleanup");
+}
+
+
+const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id)
+{
+    WOLFSSL_MSG("wolfSSL_get_digestbynid");
+
+    switch(id) {
+#ifndef NO_MD5
+        case NID_md5:
+            return wolfSSL_EVP_md5();
+#endif
+#ifndef NO_SHA
+        case NID_sha1:
+            return wolfSSL_EVP_sha1();
+#endif
+        default:
+            WOLFSSL_MSG("Bad digest id value");
+    }
+
+    return NULL;
+}
+
+
+WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY* key)
+{
+    (void)key;
+    WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_RSA not implemented");
+
+    return NULL;
+}
+
+
+WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY* key)
+{
+    (void)key;
+    WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_DSA not implemented");
+
+    return NULL;
+}
+
+
+WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key)
+{
+    (void)key;
+    WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_EC_KEY not implemented");
+
+    return NULL;
+}
+
+
+void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx)
+{
+    WOLFSSL_MSG("wolfSSL_EVP_X_STATE");
+
+    if (ctx) {
+        switch (ctx->cipherType) {
+            case ARC4_TYPE:
+                WOLFSSL_MSG("returning arc4 state");
+                return (void*)&ctx->cipher.arc4.x;
+
+            default:
+                WOLFSSL_MSG("bad x state type");
+                return 0;
+        }
+    }
+
+    return NULL;
+}
+
+
+int wolfSSL_EVP_X_STATE_LEN(const WOLFSSL_EVP_CIPHER_CTX* ctx)
+{
+    WOLFSSL_MSG("wolfSSL_EVP_X_STATE_LEN");
+
+    if (ctx) {
+        switch (ctx->cipherType) {
+            case ARC4_TYPE:
+                WOLFSSL_MSG("returning arc4 state size");
+                return sizeof(Arc4);
+
+            default:
+                WOLFSSL_MSG("bad x state type");
+                return 0;
+        }
+    }
+
+    return 0;
+}
+
+
+#ifndef NO_DES3
+
+void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
+                            unsigned char* iv, int len)
+{
+    (void)len;
+
+    WOLFSSL_MSG("wolfSSL_3des_iv");
+
+    if (ctx == NULL || iv == NULL) {
+        WOLFSSL_MSG("Bad function argument");
+        return;
+    }
+
+    if (doset)
+        wc_Des3_SetIV(&ctx->cipher.des3, iv);  /* OpenSSL compat, no ret */
+    else
+        XMEMCPY(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
+}
+
+#endif /* NO_DES3 */
+
+
+#ifndef NO_AES
+
+void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
+                      unsigned char* iv, int len)
+{
+    (void)len;
+
+    WOLFSSL_MSG("wolfSSL_aes_ctr_iv");
+
+    if (ctx == NULL || iv == NULL) {
+        WOLFSSL_MSG("Bad function argument");
+        return;
+    }
+
+    if (doset)
+        wc_AesSetIV(&ctx->cipher.aes, iv);  /* OpenSSL compat, no ret */
+    else
+        XMEMCPY(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
+}
+
+#endif /* NO_AES */
+
+
+const WOLFSSL_EVP_MD* wolfSSL_EVP_ripemd160(void)
+{
+    WOLFSSL_MSG("wolfSSL_ripemd160");
+
+    return NULL;
+}
+
+
+int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* type)
+{
+    WOLFSSL_MSG("wolfSSL_EVP_MD_size");
+
+    if (type == NULL) {
+        WOLFSSL_MSG("No md type arg");
+        return BAD_FUNC_ARG;
+    }
+
+    if (XSTRNCMP(type, "SHA256", 6) == 0) {
+        return SHA256_DIGEST_SIZE;
+    }
+#ifndef NO_MD5
+    else if (XSTRNCMP(type, "MD5", 3) == 0) {
+        return MD5_DIGEST_SIZE;
+    }
+#endif
+#ifdef WOLFSSL_SHA384
+    else if (XSTRNCMP(type, "SHA384", 6) == 0) {
+        return SHA384_DIGEST_SIZE;
+    }
+#endif
+#ifdef WOLFSSL_SHA512
+    else if (XSTRNCMP(type, "SHA512", 6) == 0) {
+        return SHA512_DIGEST_SIZE;
+    }
+#endif
+#ifndef NO_SHA
+    /* has to be last since would pick or 256, 384, or 512 too */
+    else if (XSTRNCMP(type, "SHA", 3) == 0) {
+        return SHA_DIGEST_SIZE;
+    }
+#endif
+
+    return BAD_FUNC_ARG;
+}
+
+
+int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx)
+{
+    WOLFSSL_MSG("wolfSSL_EVP_CIPHER_CTX_iv_length");
+
+    switch (ctx->cipherType) {
+
+        case AES_128_CBC_TYPE :
+        case AES_192_CBC_TYPE :
+        case AES_256_CBC_TYPE :
+            WOLFSSL_MSG("AES CBC");
+            return AES_BLOCK_SIZE;
+
+#ifdef WOLFSSL_AES_COUNTER
+        case AES_128_CTR_TYPE :
+        case AES_192_CTR_TYPE :
+        case AES_256_CTR_TYPE :
+            WOLFSSL_MSG("AES CTR");
+            return AES_BLOCK_SIZE;
+#endif
+
+        case DES_CBC_TYPE :
+            WOLFSSL_MSG("DES CBC");
+            return DES_BLOCK_SIZE;
+
+        case DES_EDE3_CBC_TYPE :
+            WOLFSSL_MSG("DES EDE3 CBC");
+            return DES_BLOCK_SIZE;
+#ifdef HAVE_IDEA
+        case IDEA_CBC_TYPE :
+            WOLFSSL_MSG("IDEA CBC");
+            return IDEA_BLOCK_SIZE;
+#endif
+        case ARC4_TYPE :
+            WOLFSSL_MSG("ARC4");
+            return 0;
+
+        case NULL_CIPHER_TYPE :
+            WOLFSSL_MSG("NULL");
+            return 0;
+
+        default: {
+            WOLFSSL_MSG("bad type");
+        }
+    }
+    return 0;
+}
+
+
+void wolfSSL_OPENSSL_free(void* p)
+{
+    WOLFSSL_MSG("wolfSSL_OPENSSL_free");
+
+    XFREE(p, NULL, 0);
+}
+
+#if defined(WOLFSSL_KEY_GEN)
+
+static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher,
+                         unsigned char* passwd, int passwdSz, byte **cipherInfo)
+{
+    int ret, paddingSz;
+    word32 idx, cipherInfoSz;
+#ifdef WOLFSSL_SMALL_STACK
+    EncryptedInfo* info = NULL;
+#else
+    EncryptedInfo  info[1];
+#endif
+
+    WOLFSSL_ENTER("EncryptDerKey");
+
+    if (der == NULL || derSz == NULL || cipher == NULL ||
+        passwd == NULL || cipherInfo == NULL)
+        return BAD_FUNC_ARG;
+
+#ifdef WOLFSSL_SMALL_STACK
+    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
+                                   DYNAMIC_TYPE_TMP_BUFFER);
+    if (info == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        return SSL_FAILURE;
+    }
+#endif
+    info->set      = 0;
+    info->ctx      = NULL;
+    info->consumed = 0;
+
+    /* set iv size */
+    if (XSTRNCMP(cipher, "DES", 3) == 0)
+        info->ivSz = DES_IV_SIZE;
+    else if (XSTRNCMP(cipher, "AES", 3) == 0)
+        info->ivSz = AES_IV_SIZE;
+    else {
+        WOLFSSL_MSG("unsupported cipher");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return SSL_FAILURE;
+    }
+
+    /* set the cipher name on info */
+    XSTRNCPY(info->name, cipher, NAME_SZ);
+
+    /* Generate a random salt */
+    if (wolfSSL_RAND_bytes(info->iv, info->ivSz) != SSL_SUCCESS) {
+        WOLFSSL_MSG("generate iv failed");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return SSL_FAILURE;
+    }
+
+    /* add the padding before encryption */
+    paddingSz = ((*derSz)/info->ivSz + 1) * info->ivSz - (*derSz);
+    if (paddingSz == 0)
+        paddingSz = info->ivSz;
+    XMEMSET(der+(*derSz), (byte)paddingSz, paddingSz);
+    (*derSz) += paddingSz;
+
+    /* encrypt buffer */
+    if (wolfssl_encrypt_buffer_key(der, *derSz,
+                                   passwd, passwdSz, info) != SSL_SUCCESS) {
+        WOLFSSL_MSG("encrypt key failed");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return SSL_FAILURE;
+    }
+
+    /* create cipher info : 'cipher_name,Salt(hex)' */
+    cipherInfoSz = (word32)(2*info->ivSz + XSTRLEN(info->name) + 2);
+    *cipherInfo = (byte*)XMALLOC(cipherInfoSz, NULL,
+                                DYNAMIC_TYPE_TMP_BUFFER);
+    if (*cipherInfo == NULL) {
+        WOLFSSL_MSG("malloc failed");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return SSL_FAILURE;
+    }
+    XSTRNCPY((char*)*cipherInfo, info->name, cipherInfoSz);
+    XSTRNCAT((char*)*cipherInfo, ",", 1);
+
+    idx = (word32)XSTRLEN((char*)*cipherInfo);
+    cipherInfoSz -= idx;
+    ret = Base16_Encode(info->iv, info->ivSz, *cipherInfo+idx, &cipherInfoSz);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+    if (ret != 0) {
+        WOLFSSL_MSG("Base16_Encode failed");
+        XFREE(*cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+
+    return SSL_SUCCESS;
+}
+#endif /* defined(WOLFSSL_KEY_GEN) */
+
+#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher,
+                                        unsigned char* passwd, int passwdSz,
+                                        unsigned char **pem, int *plen)
+{
+    byte *der, *tmp, *cipherInfo = NULL;
+    int  der_max_len = 0, derSz = 0;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_write_mem_RSAPrivateKey");
+
+    if (pem == NULL || plen == NULL || rsa == NULL || rsa->internal == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return SSL_FAILURE;
+    }
+
+    if (rsa->inSet == 0) {
+        WOLFSSL_MSG("No RSA internal set, do it");
+
+        if (SetRsaInternal(rsa) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetRsaInternal failed");
+            return SSL_FAILURE;
+        }
+    }
+
+    /* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additionnal
+     *  informations
+     */
+    der_max_len = 5 * wolfSSL_RSA_size(rsa) + AES_BLOCK_SIZE;
+
+    der = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (der == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        return SSL_FAILURE;
+    }
+
+    /* Key to DER */
+    derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, der, der_max_len);
+    if (derSz < 0) {
+        WOLFSSL_MSG("wc_RsaKeyToDer failed");
+        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+
+    /* encrypt DER buffer if required */
+    if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
+        int ret;
+
+        ret = EncryptDerKey(der, &derSz, cipher,
+                            passwd, passwdSz, &cipherInfo);
+        if (ret != SSL_SUCCESS) {
+            WOLFSSL_MSG("EncryptDerKey failed");
+            XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return ret;
+        }
+
+        /* tmp buffer with a max size */
+        *plen = (derSz * 2) + sizeof(BEGIN_RSA_PRIV) +
+                sizeof(END_RSA_PRIV) + HEADER_ENCRYPTED_KEY_SIZE;
+    }
+    else /* tmp buffer with a max size */
+        *plen = (derSz * 2) + sizeof(BEGIN_RSA_PRIV) + sizeof(END_RSA_PRIV);
+
+    tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmp == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (cipherInfo != NULL)
+            XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+
+    /* DER to PEM */
+    *plen = wc_DerToPemEx(der, derSz, tmp, *plen, cipherInfo, PRIVATEKEY_TYPE);
+    if (*plen <= 0) {
+        WOLFSSL_MSG("wc_DerToPemEx failed");
+        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (cipherInfo != NULL)
+            XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (cipherInfo != NULL)
+        XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_OUT_BUFFER);
+    if (*pem == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+    XMEMSET(*pem, 0, (*plen)+1);
+
+    if (XMEMCPY(*pem, tmp, *plen) == NULL) {
+        WOLFSSL_MSG("XMEMCPY failed");
+        XFREE(pem, NULL, DYNAMIC_TYPE_OUT_BUFFER);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+    XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    return SSL_SUCCESS;
+}
+
+
+#ifndef NO_FILESYSTEM
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_RSAPrivateKey(XFILE fp, WOLFSSL_RSA *rsa,
+                                    const EVP_CIPHER *enc,
+                                    unsigned char *kstr, int klen,
+                                    pem_password_cb *cb, void *u)
+{
+    byte *pem;
+    int  plen, ret;
+
+    (void)cb;
+    (void)u;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_RSAPrivateKey");
+
+    if (fp == NULL || rsa == NULL || rsa->internal == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return SSL_FAILURE;
+    }
+
+    ret = wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, enc, kstr, klen, &pem, &plen);
+    if (ret != SSL_SUCCESS) {
+        WOLFSSL_MSG("wolfSSL_PEM_write_mem_RSAPrivateKey failed");
+        return SSL_FAILURE;
+    }
+
+    ret = (int)XFWRITE(pem, plen, 1, fp);
+    if (ret != 1) {
+        WOLFSSL_MSG("RSA private key file write failed");
+        return SSL_FAILURE;
+    }
+
+    XFREE(pem, NULL, DYNAMIC_TYPE_OUT_BUFFER);
+    return SSL_SUCCESS;
+}
+#endif /* NO_FILESYSTEM */
+
+int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, RSA* rsa,
+                                        const EVP_CIPHER* cipher,
+                                        unsigned char* passwd, int len,
+                                        pem_password_cb cb, void* arg)
+{
+    (void)bio;
+    (void)rsa;
+    (void)cipher;
+    (void)passwd;
+    (void)len;
+    (void)cb;
+    (void)arg;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_bio_RSAPrivateKey not implemented");
+
+    return SSL_FAILURE;
+}
+#endif /* defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) */
+
+#ifdef HAVE_ECC
+
+/* EC_POINT Openssl -> WolfSSL */
+static int SetECPointInternal(WOLFSSL_EC_POINT *p)
+{
+    ecc_point* point;
+    WOLFSSL_ENTER("SetECPointInternal");
+
+    if (p == NULL || p->internal == NULL) {
+        WOLFSSL_MSG("ECPoint NULL error");
+        return SSL_FATAL_ERROR;
+    }
+
+    point = (ecc_point*)p->internal;
+
+    if (p->X != NULL && SetIndividualInternal(p->X, point->x) != SSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point X error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (p->Y != NULL && SetIndividualInternal(p->Y, point->y) != SSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point Y error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (p->Z != NULL && SetIndividualInternal(p->Z, point->z) != SSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point Z error");
+        return SSL_FATAL_ERROR;
+    }
+
+    p->inSet = 1;
+
+    return SSL_SUCCESS;
+}
+
+/* EC_POINT WolfSSL -> OpenSSL */
+static int SetECPointExternal(WOLFSSL_EC_POINT *p)
+{
+    ecc_point* point;
+
+    WOLFSSL_ENTER("SetECPointExternal");
+
+    if (p == NULL || p->internal == NULL) {
+        WOLFSSL_MSG("ECPoint NULL error");
+        return SSL_FATAL_ERROR;
+    }
+
+    point = (ecc_point*)p->internal;
+
+    if (SetIndividualExternal(&p->X, point->x) != SSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point X error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&p->Y, point->y) != SSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point Y error");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetIndividualExternal(&p->Z, point->z) != SSL_SUCCESS) {
+        WOLFSSL_MSG("ecc point Z error");
+        return SSL_FATAL_ERROR;
+    }
+
+    p->exSet = 1;
+
+    return SSL_SUCCESS;
+}
+
+/* EC_KEY wolfSSL -> OpenSSL */
+static int SetECKeyExternal(WOLFSSL_EC_KEY* eckey)
+{
+    ecc_key* key;
+
+    WOLFSSL_ENTER("SetECKeyExternal");
+
+    if (eckey == NULL || eckey->internal == NULL) {
+        WOLFSSL_MSG("ec key NULL error");
+        return SSL_FATAL_ERROR;
+    }
+
+    key = (ecc_key*)eckey->internal;
+
+    /* set group (nid and idx) */
+    eckey->group->curve_nid = ecc_sets[key->idx].nid;
+    eckey->group->curve_idx = key->idx;
+
+    if (eckey->pub_key->internal != NULL) {
+        /* set the internal public key */
+        if (wc_ecc_copy_point(&key->pubkey,
+                             (ecc_point*)eckey->pub_key->internal) != MP_OKAY) {
+            WOLFSSL_MSG("SetECKeyExternal ecc_copy_point failed");
+            return SSL_FATAL_ERROR;
+        }
+
+        /* set the external pubkey (point) */
+        if (SetECPointExternal(eckey->pub_key) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetECKeyExternal SetECPointExternal failed");
+            return SSL_FATAL_ERROR;
+        }
+    }
+
+    /* set the external privkey */
+    if (key->type == ECC_PRIVATEKEY) {
+        if (SetIndividualExternal(&eckey->priv_key, &key->k) != SSL_SUCCESS) {
+            WOLFSSL_MSG("ec priv key error");
+            return SSL_FATAL_ERROR;
+        }
+    }
+
+    eckey->exSet = 1;
+
+    return SSL_SUCCESS;
+}
+
+/* EC_KEY Openssl -> WolfSSL */
+static int SetECKeyInternal(WOLFSSL_EC_KEY* eckey)
+{
+    ecc_key* key;
+
+    WOLFSSL_ENTER("SetECKeyInternal");
+
+    if (eckey == NULL || eckey->internal == NULL) {
+        WOLFSSL_MSG("ec key NULL error");
+        return SSL_FATAL_ERROR;
+    }
+
+    key = (ecc_key*)eckey->internal;
+
+    /* validate group */
+    if ((eckey->group->curve_idx < 0) ||
+        (wc_ecc_is_valid_idx(eckey->group->curve_idx) == 0)) {
+        WOLFSSL_MSG("invalid curve idx");
+        return SSL_FATAL_ERROR;
+    }
+
+    /* set group (idx of curve and corresponding domain parameters) */
+    key->idx = eckey->group->curve_idx;
+    key->dp = &ecc_sets[key->idx];
+
+    /* set pubkey (point) */
+    if (eckey->pub_key != NULL) {
+        if (SetECPointInternal(eckey->pub_key) != SSL_SUCCESS) {
+            WOLFSSL_MSG("ec key pub error");
+            return SSL_FATAL_ERROR;
+        }
+
+        /* public key */
+        key->type = ECC_PUBLICKEY;
+    }
+
+    /* set privkey */
+    if (eckey->priv_key != NULL) {
+        if (SetIndividualInternal(eckey->priv_key, &key->k) != SSL_SUCCESS) {
+            WOLFSSL_MSG("ec key priv error");
+            return SSL_FATAL_ERROR;
+        }
+
+        /* private key */
+        key->type = ECC_PRIVATEKEY;
+    }
+
+    eckey->inSet = 1;
+
+    return SSL_SUCCESS;
+}
+
+WOLFSSL_EC_POINT *wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY *key)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_public_key");
+
+    if (key == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_get0_group Bad arguments");
+        return NULL;
+    }
+
+    return key->pub_key;
+}
+
+const WOLFSSL_EC_GROUP *wolfSSL_EC_KEY_get0_group(const WOLFSSL_EC_KEY *key)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_group");
+
+    if (key == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_get0_group Bad arguments");
+        return NULL;
+    }
+
+    return key->group;
+}
+
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY *key,
+                                   const WOLFSSL_BIGNUM *priv_key)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_private_key");
+
+    if (key == NULL || priv_key == NULL) {
+        WOLFSSL_MSG("Bad arguments");
+        return SSL_FAILURE;
+    }
+
+    /* free key if previously set */
+    if (key->priv_key != NULL)
+        wolfSSL_BN_free(key->priv_key);
+
+    key->priv_key = wolfSSL_BN_dup(priv_key);
+    if (key->priv_key == NULL) {
+        WOLFSSL_MSG("key ecc priv key NULL");
+        return SSL_FAILURE;
+    }
+
+    if (SetECKeyInternal(key) != SSL_SUCCESS) {
+        WOLFSSL_MSG("SetECKeyInternal failed");
+        wolfSSL_BN_free(key->priv_key);
+        return SSL_FAILURE;
+    }
+
+    return SSL_SUCCESS;
+}
+
+
+WOLFSSL_BIGNUM *wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY *key)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_private_key");
+
+    if (key == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_get0_private_key Bad arguments");
+        return NULL;
+    }
+
+    return key->priv_key;
+}
+
+WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid)
+{
+    WOLFSSL_EC_KEY *key;
+    int x;
+
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_new_by_curve_name");
+
+    key = wolfSSL_EC_KEY_new();
+    if (key == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_new failure");
+        return NULL;
+    }
+
+    /* set the nid of the curve */
+    key->group->curve_nid = nid;
+
+    /* search and set the corresponding internal curve idx */
+    for (x = 0; ecc_sets[x].size != 0; x++)
+        if (ecc_sets[x].nid == key->group->curve_nid) {
+            key->group->curve_idx = x;
+            break;
+        }
+
+    return key;
+}
+
+static void InitwolfSSL_ECKey(WOLFSSL_EC_KEY* key)
+{
+    if (key) {
+        key->group    = NULL;
+        key->pub_key  = NULL;
+        key->priv_key = NULL;
+        key->internal = NULL;
+        key->inSet    = 0;
+        key->exSet    = 0;
+    }
+}
+
+WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void)
+{
+    WOLFSSL_EC_KEY *external;
+    ecc_key* key;
+
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_new");
+
+    external = (WOLFSSL_EC_KEY*)XMALLOC(sizeof(WOLFSSL_EC_KEY), NULL,
+                                        DYNAMIC_TYPE_ECC);
+    if (external == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_KEY failure");
+        return NULL;
+    }
+    XMEMSET(external, 0, sizeof(WOLFSSL_EC_KEY));
+
+    InitwolfSSL_ECKey(external);
+
+    external->internal = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL,
+                                           DYNAMIC_TYPE_ECC);
+    if (external->internal == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc ecc key failure");
+        wolfSSL_EC_KEY_free(external);
+        return NULL;
+    }
+    XMEMSET(external->internal, 0, sizeof(ecc_key));
+
+    wc_ecc_init((ecc_key*)external->internal);
+
+    /* public key */
+    external->pub_key = (WOLFSSL_EC_POINT*)XMALLOC(sizeof(WOLFSSL_EC_POINT),
+                                                   NULL, DYNAMIC_TYPE_ECC);
+    if (external->pub_key == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_POINT failure");
+        wolfSSL_EC_KEY_free(external);
+        return NULL;
+    }
+    XMEMSET(external->pub_key, 0, sizeof(WOLFSSL_EC_POINT));
+
+    key = (ecc_key*)external->internal;
+    external->pub_key->internal = (ecc_point*)&key->pubkey;
+
+    /* curve group */
+    external->group = (WOLFSSL_EC_GROUP*)XMALLOC(sizeof(WOLFSSL_EC_GROUP), NULL,
+                                                 DYNAMIC_TYPE_ECC);
+    if (external->group == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_GROUP failure");
+        wolfSSL_EC_KEY_free(external);
+        return NULL;
+    }
+    XMEMSET(external->group, 0, sizeof(WOLFSSL_EC_GROUP));
+
+    /* private key */
+    external->priv_key = wolfSSL_BN_new();
+    if (external->priv_key == NULL) {
+        WOLFSSL_MSG("wolfSSL_BN_new failure");
+        wolfSSL_EC_KEY_free(external);
+        return NULL;
+    }
+
+    return external;
+}
+
+void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_free");
+
+    if (key != NULL) {
+        if (key->internal != NULL) {
+            wc_ecc_free((ecc_key*)key->internal);
+            XFREE(key->internal, NULL, DYNAMIC_TYPE_ECC);
+        }
+        wolfSSL_BN_free(key->priv_key);
+        wolfSSL_EC_POINT_free(key->pub_key);
+        wolfSSL_EC_GROUP_free(key->group);
+        InitwolfSSL_ECKey(key); /* set back to NULLs for safety */
+
+        XFREE(key, NULL, DYNAMIC_TYPE_ECC);
+        key = NULL;
+    }
+}
+
+int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group)
+{
+    (void)key;
+    (void)group;
+
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_group");
+    WOLFSSL_MSG("wolfSSL_EC_KEY_set_group TBD");
+
+    return -1;
+}
+
+int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key)
+{
+    int     initTmpRng = 0;
+    WC_RNG* rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG* tmpRNG = NULL;
+#else
+    WC_RNG  tmpRNG[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_generate_key");
+
+    if (key == NULL || key->internal == NULL ||
+        key->group == NULL || key->group->curve_idx < 0) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key Bad arguments");
+        return 0;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmpRNG == NULL)
+        return 0;
+#endif
+
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to set RNG");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return 0;
+    }
+
+    if (wc_ecc_make_key(rng, ecc_sets[key->group->curve_idx].size,
+                        (ecc_key*)key->internal) != MP_OKAY) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key wc_ecc_make_key failed");
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return 0;
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    if (SetECKeyExternal(key) != SSL_SUCCESS) {
+        WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key SetECKeyExternal failed");
+        return 0;
+    }
+
+    return 1;
+}
+
+void wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY *key, int asn1_flag)
+{
+    (void)key;
+    (void)asn1_flag;
+
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_asn1_flag");
+    WOLFSSL_MSG("wolfSSL_EC_KEY_set_asn1_flag TBD");
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key,
+                                  const WOLFSSL_EC_POINT *pub)
+{
+    ecc_point *pub_p, *key_p;
+
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_public_key");
+
+    if (key == NULL || key->internal == NULL ||
+        pub == NULL || pub->internal == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order Bad arguments");
+        return SSL_FAILURE;
+    }
+
+    if (key->inSet == 0) {
+        if (SetECKeyInternal(key) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetECKeyInternal failed");
+            return SSL_FAILURE;
+        }
+    }
+
+    if (pub->inSet == 0) {
+        if (SetECPointInternal((WOLFSSL_EC_POINT *)pub) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetECPointInternal failed");
+            return SSL_FAILURE;
+        }
+    }
+
+    pub_p = (ecc_point*)pub->internal;
+    key_p = (ecc_point*)key->pub_key->internal;
+
+    /* create new point if required */
+    if (key_p == NULL)
+        key_p = wc_ecc_new_point();
+
+    if (key_p == NULL) {
+        WOLFSSL_MSG("key ecc point NULL");
+        return SSL_FAILURE;
+    }
+
+    if (wc_ecc_copy_point(pub_p, key_p) != MP_OKAY) {
+        WOLFSSL_MSG("ecc_copy_point failure");
+        return SSL_FAILURE;
+    }
+
+    if (SetECKeyExternal(key) != SSL_SUCCESS) {
+        WOLFSSL_MSG("SetECKeyInternal failed");
+        return SSL_FAILURE;
+    }
+
+#if defined(DEBUG_WOLFSSL) && !defined(NO_FILESYSTEM)
+    wolfssl_EC_POINT_dump("pub", pub);
+    wolfssl_EC_POINT_dump("key->pub_key", key->pub_key);
+#endif
+    return SSL_SUCCESS;
+}
+/* End EC_KEY */
+
+#if defined(DEBUG_WOLFSSL) && !defined(NO_FILESYSTEM)
+void wolfssl_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *p)
+{
+    char *num;
+
+    WOLFSSL_ENTER("wolfssl_EC_POINT_dump");
+
+    if (p == NULL) {
+        fprintf(stderr, "%s = NULL", msg);
+        return ;
+    }
+
+    fprintf(stderr, "%s:\n\tinSet=%d, exSet=%d\n", msg, p->inSet, p->exSet);
+    num = wolfSSL_BN_bn2hex(p->X);
+    fprintf(stderr, "\tX = %s\n", num);
+    XFREE(num, NULL, DYNAMIC_TYPE_ECC);
+    num = wolfSSL_BN_bn2hex(p->Y);
+    fprintf(stderr, "\tY = %s\n", num);
+    XFREE(num, NULL, DYNAMIC_TYPE_ECC);
+}
+#endif
+
+/* Start EC_GROUP */
+
+/* return code compliant with OpenSSL :
+ *   0 if equal, 1 if not and -1 in case of error
+ */
+int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b,
+                         WOLFSSL_BN_CTX *ctx)
+{
+    (void)ctx;
+
+    WOLFSSL_ENTER("wolfSSL_EC_GROUP_cmp");
+
+    if (a == NULL || b == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_cmp Bad arguments");
+        return SSL_FATAL_ERROR;
+    }
+
+    /* ok */
+    if ((a->curve_idx == b->curve_idx) && (a->curve_nid == b->curve_nid))
+        return 0;
+
+    /* ko */
+    return 1;
+}
+
+void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_GROUP_free");
+
+    XFREE(group, NULL, DYNAMIC_TYPE_ECC);
+    group = NULL;
+}
+
+void wolfSSL_EC_GROUP_set_asn1_flag(WOLFSSL_EC_GROUP *group, int flag)
+{
+    (void)group;
+    (void)flag;
+
+    WOLFSSL_ENTER("wolfSSL_EC_GROUP_set_asn1_flag");
+    WOLFSSL_MSG("wolfSSL_EC_GROUP_set_asn1_flag TBD");
+}
+
+WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_new_by_curve_name(int nid)
+{
+    WOLFSSL_EC_GROUP *g;
+    int x;
+
+    WOLFSSL_ENTER("wolfSSL_EC_GROUP_new_by_curve_name");
+
+    /* curve group */
+    g = (WOLFSSL_EC_GROUP*) XMALLOC(sizeof(WOLFSSL_EC_GROUP), NULL,
+                                    DYNAMIC_TYPE_ECC);
+    if (g == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_new_by_curve_name malloc failure");
+        return NULL;
+    }
+    XMEMSET(g, 0, sizeof(WOLFSSL_EC_GROUP));
+
+    /* set the nid of the curve */
+    g->curve_nid = nid;
+
+    /* search and set the corresponding internal curve idx */
+    for (x = 0; ecc_sets[x].size != 0; x++)
+        if (ecc_sets[x].nid == g->curve_nid) {
+            g->curve_idx = x;
+            break;
+        }
+
+    return g;
+}
+
+/* return code compliant with OpenSSL :
+ *   the curve nid if success, 0 if error
+ */
+int wolfSSL_EC_GROUP_get_curve_name(const WOLFSSL_EC_GROUP *group)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_curve_name");
+
+    if (group == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_curve_name Bad arguments");
+        return SSL_FAILURE;
+    }
+
+    return group->curve_nid;
+}
+
+/* return code compliant with OpenSSL :
+ *   the degree of the curve if success, 0 if error
+ */
+int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_degree");
+
+    if (group == NULL || group->curve_idx < 0) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_degree Bad arguments");
+        return SSL_FAILURE;
+    }
+
+    switch(group->curve_nid) {
+        case NID_X9_62_prime256v1:
+            return 256;
+            break;
+        case NID_secp384r1:
+            return 384;
+            break;
+        case NID_secp521r1:
+            return 521;
+            break;
+        default :
+            return SSL_FAILURE;
+            break;
+    }
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group,
+                               WOLFSSL_BIGNUM *order, WOLFSSL_BN_CTX *ctx)
+{
+    (void)ctx;
+
+    if (group == NULL || order == NULL || order->internal == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order NULL error");
+        return SSL_FAILURE;
+    }
+
+    if (mp_init((mp_int*)order->internal) != MP_OKAY) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_init failure");
+        return SSL_FAILURE;
+    }
+
+    if (mp_read_radix((mp_int*)order->internal,
+                      ecc_sets[group->curve_idx].order, 16) != MP_OKAY) {
+        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_read order failure");
+        mp_clear((mp_int*)order->internal);
+        return SSL_FAILURE;
+    }
+
+    return SSL_SUCCESS;
+}
+/* End EC_GROUP */
+
+/* Start EC_POINT */
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *group,
+                        const WOLFSSL_EC_POINT *p,
+                        unsigned char *out, unsigned int *len)
+{
+    int err;
+
+    WOLFSSL_ENTER("wolfSSL_ECPoint_i2d");
+
+    if (group == NULL || p == NULL || len == NULL) {
+        WOLFSSL_MSG("wolfSSL_ECPoint_i2d NULL error");
+        return SSL_FAILURE;
+    }
+
+    if (p->inSet == 0) {
+        WOLFSSL_MSG("No ECPoint internal set, do it");
+
+        if (SetECPointInternal((WOLFSSL_EC_POINT *)p) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetECPointInternal SetECPointInternal failed");
+            return SSL_FAILURE;
+        }
+    }
+
+#if defined(DEBUG_WOLFSSL) && !defined(NO_FILESYSTEM)
+    if (out != NULL) {
+        wolfssl_EC_POINT_dump("i2d p", p);
+    }
+#endif
+    err = wc_ecc_export_point_der(group->curve_idx, (ecc_point*)p->internal,
+                                  out, len);
+    if (err != MP_OKAY && !(out == NULL && err == LENGTH_ONLY_E)) {
+        WOLFSSL_MSG("wolfSSL_ECPoint_i2d wc_ecc_export_point_der failed");
+        return SSL_FAILURE;
+    }
+
+    return SSL_SUCCESS;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_ECPoint_d2i(unsigned char *in, unsigned int len,
+                        const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *p)
+{
+    WOLFSSL_ENTER("wolfSSL_ECPoint_d2i");
+
+    if (group == NULL || p == NULL || p->internal == NULL || in == NULL) {
+        WOLFSSL_MSG("wolfSSL_ECPoint_d2i NULL error");
+        return SSL_FAILURE;
+    }
+
+    if (wc_ecc_import_point_der(in, len, group->curve_idx,
+                                (ecc_point*)p->internal) != MP_OKAY) {
+        WOLFSSL_MSG("wc_ecc_import_point_der failed");
+        return SSL_FAILURE;
+    }
+
+    if (p->exSet == 0) {
+        WOLFSSL_MSG("No ECPoint external set, do it");
+
+        if (SetECPointExternal(p) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetECPointExternal failed");
+            return SSL_FAILURE;
+        }
+    }
+
+#if defined(DEBUG_WOLFSSL) && !defined(NO_FILESYSTEM)
+    wolfssl_EC_POINT_dump("d2i p", p);
+#endif
+    return SSL_SUCCESS;
+}
+
+WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group)
+{
+    WOLFSSL_EC_POINT *p;
+
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_new");
+
+    if (group == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_new NULL error");
+        return NULL;
+    }
+
+    p = (WOLFSSL_EC_POINT *)XMALLOC(sizeof(WOLFSSL_EC_POINT), NULL,
+                                    DYNAMIC_TYPE_ECC);
+    if (p == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_new malloc ecc point failure");
+        return NULL;
+    }
+    XMEMSET(p, 0, sizeof(WOLFSSL_EC_POINT));
+
+    p->internal = wc_ecc_new_point();
+    if (p->internal == NULL) {
+        WOLFSSL_MSG("ecc_new_point failure");
+        return NULL;
+    }
+
+    return p;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group,
+                                                const WOLFSSL_EC_POINT *point,
+                                                WOLFSSL_BIGNUM *x,
+                                                WOLFSSL_BIGNUM *y,
+                                                WOLFSSL_BN_CTX *ctx)
+{
+    (void)ctx;
+
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_get_affine_coordinates_GFp");
+
+    if (group == NULL || point == NULL || point->internal == NULL ||
+        x == NULL || y == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp NULL error");
+        return SSL_FAILURE;
+    }
+
+    if (point->inSet == 0) {
+        WOLFSSL_MSG("No ECPoint internal set, do it");
+
+        if (SetECPointInternal((WOLFSSL_EC_POINT *)point) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetECPointInternal failed");
+            return SSL_FAILURE;
+        }
+    }
+
+    BN_copy(x, point->X);
+    BN_copy(y, point->Y);
+
+    return SSL_SUCCESS;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r,
+                         const WOLFSSL_BIGNUM *n, const WOLFSSL_EC_POINT *q,
+                         const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
+{
+    mp_int prime;
+
+    (void)ctx;
+    (void)n;
+
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_mul");
+
+    if (group == NULL || r == NULL || r->internal == NULL ||
+        q == NULL || q->internal == NULL || m == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_mul NULL error");
+        return SSL_FAILURE;
+    }
+
+    if (q->inSet == 0) {
+        WOLFSSL_MSG("No ECPoint internal set, do it");
+
+        if (SetECPointInternal((WOLFSSL_EC_POINT *)q) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetECPointInternal failed");
+            return SSL_FAILURE;
+        }
+    }
+
+    /* compute the prime value of the curve */
+    if (mp_init(&prime) != MP_OKAY) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_mul init BN failed");
+        return SSL_FAILURE;
+    }
+
+    if (mp_read_radix(&prime, ecc_sets[group->curve_idx].prime, 16) != MP_OKAY){
+        WOLFSSL_MSG("wolfSSL_EC_POINT_mul read prime curve value failed");
+        return SSL_FAILURE;
+    }
+
+    /* r = q * m % prime */
+    if (wc_ecc_mulmod((mp_int*)m->internal, (ecc_point*)q->internal,
+                      (ecc_point*)r->internal, &prime, 1) != MP_OKAY) {
+        WOLFSSL_MSG("ecc_mulmod failure");
+        mp_clear(&prime);
+        return SSL_FAILURE;
+    }
+
+    mp_clear(&prime);
+
+    /* set the external value for the computed point */
+    if (SetECPointInternal(r) != SSL_SUCCESS) {
+        WOLFSSL_MSG("SetECPointInternal failed");
+        return SSL_FAILURE;
+    }
+
+    return SSL_SUCCESS;
+}
+
+void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *p)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_clear_free");
+
+    wolfSSL_EC_POINT_free(p);
+}
+
+/* return code compliant with OpenSSL :
+ *   0 if equal, 1 if not and -1 in case of error
+ */
+int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group,
+                         const WOLFSSL_EC_POINT *a, const WOLFSSL_EC_POINT *b,
+                         WOLFSSL_BN_CTX *ctx)
+{
+    int ret;
+
+	(void)ctx;
+    
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_cmp");
+
+    if (group == NULL || a == NULL || a->internal == NULL || b == NULL ||
+        b->internal == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_cmp Bad arguments");
+        return SSL_FATAL_ERROR;
+    }
+
+    ret = wc_ecc_cmp_point((ecc_point*)a->internal, (ecc_point*)b->internal);
+    if (ret == MP_EQ)
+        return 0;
+    else if (ret == MP_LT || ret == MP_GT)
+        return 1;
+
+    return SSL_FATAL_ERROR;
+}
+
+void wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT *p)
+{
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_free");
+
+    if (p != NULL) {
+        if (p->internal == NULL) {
+            wc_ecc_del_point((ecc_point*)p->internal);
+            XFREE(p->internal, NULL, DYNAMIC_TYPE_ECC);
+            p->internal = NULL;
+        }
+
+        wolfSSL_BN_free(p->X);
+        wolfSSL_BN_free(p->Y);
+        wolfSSL_BN_free(p->Z);
+        p->X = NULL;
+        p->Y = NULL;
+        p->Z = NULL;
+        p->inSet = p->exSet = 0;
+
+        XFREE(p, NULL, DYNAMIC_TYPE_ECC);
+        p = NULL;
+    }
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if point at infinity, 0 else
+ */
+int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group,
+                                    const WOLFSSL_EC_POINT *point)
+{
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_EC_POINT_is_at_infinity");
+
+    if (group == NULL || point == NULL || point->internal == NULL) {
+        WOLFSSL_MSG("wolfSSL_EC_POINT_is_at_infinity NULL error");
+        return SSL_FAILURE;
+    }
+    if (point->inSet == 0) {
+        WOLFSSL_MSG("No ECPoint internal set, do it");
+
+        if (SetECPointInternal((WOLFSSL_EC_POINT *)point) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetECPointInternal failed");
+            return SSL_FAILURE;
+        }
+    }
+
+    ret = wc_ecc_point_is_at_infinity((ecc_point*)point->internal);
+    if (ret <= 0) {
+        WOLFSSL_MSG("ecc_point_is_at_infinity failure");
+        return SSL_FAILURE;
+    }
+
+    return SSL_SUCCESS;
+}
+
+/* End EC_POINT */
+
+/* Start ECDSA_SIG */
+void wolfSSL_ECDSA_SIG_free(WOLFSSL_ECDSA_SIG *sig)
+{
+    WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_free");
+
+    if (sig) {
+        wolfSSL_BN_free(sig->r);
+        wolfSSL_BN_free(sig->s);
+
+        XFREE(sig, NULL, DYNAMIC_TYPE_ECC);
+    }
+}
+
+WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_SIG_new(void)
+{
+    WOLFSSL_ECDSA_SIG *sig;
+
+    WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_new");
+
+    sig = (WOLFSSL_ECDSA_SIG*) XMALLOC(sizeof(WOLFSSL_ECDSA_SIG), NULL,
+                                       DYNAMIC_TYPE_ECC);
+    if (sig == NULL) {
+        WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA signature failure");
+        return NULL;
+    }
+
+    sig->r = wolfSSL_BN_new();
+    if (sig->r == NULL) {
+        WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA r failure");
+        wolfSSL_ECDSA_SIG_free(sig);
+        return NULL;
+    }
+
+    sig->s = wolfSSL_BN_new();
+    if (sig->s == NULL) {
+        WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA s failure");
+        wolfSSL_ECDSA_SIG_free(sig);
+        return NULL;
+    }
+
+    return sig;
+}
+
+/* return signature structure on success, NULL otherwise */
+WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *d, int dlen,
+                                         WOLFSSL_EC_KEY *key)
+{
+    WOLFSSL_ECDSA_SIG *sig = NULL;
+    int     initTmpRng = 0;
+    WC_RNG* rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG* tmpRNG = NULL;
+#else
+    WC_RNG  tmpRNG[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_ECDSA_do_sign");
+
+    if (d == NULL || key == NULL || key->internal == NULL) {
+        WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad arguments");
+        return NULL;
+    }
+
+    /* set internal key if not done */
+    if (key->inSet == 0)
+    {
+        WOLFSSL_MSG("wolfSSL_ECDSA_do_sign No EC key internal set, do it");
+
+        if (SetECKeyInternal(key) != SSL_SUCCESS) {
+            WOLFSSL_MSG("wolfSSL_ECDSA_do_sign SetECKeyInternal failed");
+            return NULL;
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmpRNG == NULL)
+        return NULL;
+#endif
+
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad RNG Init, trying global");
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+        mp_int sig_r, sig_s;
+
+        if (mp_init_multi(&sig_r, &sig_s, NULL, NULL, NULL, NULL) == MP_OKAY) {
+            if (wc_ecc_sign_hash_ex(d, dlen, rng, (ecc_key*)key->internal,
+                                    &sig_r, &sig_s) != MP_OKAY) {
+                WOLFSSL_MSG("wc_ecc_sign_hash_ex failed");
+            }
+            else {
+                /* put signature blob in ECDSA structure */
+                sig = wolfSSL_ECDSA_SIG_new();
+                if (sig == NULL)
+                    WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new failed");
+                else if (SetIndividualExternal(&(sig->r), &sig_r)!=SSL_SUCCESS){
+                    WOLFSSL_MSG("ecdsa r key error");
+                    wolfSSL_ECDSA_SIG_free(sig);
+                }
+                else if (SetIndividualExternal(&(sig->s), &sig_s)!=SSL_SUCCESS){
+                    WOLFSSL_MSG("ecdsa s key error");
+                    wolfSSL_ECDSA_SIG_free(sig);
+                }
+
+                mp_clear(&sig_r);
+                mp_clear(&sig_s);
+            }
+        }
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return sig;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 for a valid signature, 0 for an invalid signature and -1 on error
+ */
+int wolfSSL_ECDSA_do_verify(const unsigned char *d, int dlen,
+                            const WOLFSSL_ECDSA_SIG *sig, WOLFSSL_EC_KEY *key)
+{
+    int check_sign = 0;
+
+    WOLFSSL_ENTER("wolfSSL_ECDSA_do_verify");
+
+    if (d == NULL || sig == NULL || key == NULL || key->internal == NULL) {
+        WOLFSSL_MSG("wolfSSL_ECDSA_do_verify Bad arguments");
+        return SSL_FATAL_ERROR;
+    }
+
+    /* set internal key if not done */
+    if (key->inSet == 0)
+    {
+        WOLFSSL_MSG("No EC key internal set, do it");
+
+        if (SetECKeyInternal(key) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetECKeyInternal failed");
+            return SSL_FATAL_ERROR;
+        }
+    }
+
+    if (wc_ecc_verify_hash_ex((mp_int*)sig->r->internal,
+                              (mp_int*)sig->s->internal, d, dlen, &check_sign,
+                              (ecc_key *)key->internal) != MP_OKAY) {
+        WOLFSSL_MSG("wc_ecc_verify_hash failed");
+        return SSL_FATAL_ERROR;
+    }
+    else if (check_sign == 0) {
+        WOLFSSL_MSG("wc_ecc_verify_hash incorrect signature detected");
+        return SSL_FAILURE;
+    }
+
+    return SSL_SUCCESS;
+}
+/* End ECDSA_SIG */
+
+/* Start ECDH */
+/* return code compliant with OpenSSL :
+ *   length of computed key if success, -1 if error
+ */
+int wolfSSL_ECDH_compute_key(void *out, size_t outlen,
+                             const WOLFSSL_EC_POINT *pub_key,
+                             WOLFSSL_EC_KEY *ecdh,
+                             void *(*KDF) (const void *in, size_t inlen,
+                                           void *out, size_t *outlen))
+{
+    word32 len;
+    (void)KDF;
+
+    (void)KDF;
+
+	WOLFSSL_ENTER("wolfSSL_ECDH_compute_key");
+
+    if (out == NULL || pub_key == NULL || pub_key->internal == NULL ||
+        ecdh == NULL || ecdh->internal == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return SSL_FATAL_ERROR;
+    }
+
+    /* set internal key if not done */
+    if (ecdh->inSet == 0)
+    {
+        WOLFSSL_MSG("No EC key internal set, do it");
+
+        if (SetECKeyInternal(ecdh) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetECKeyInternal failed");
+            return SSL_FATAL_ERROR;
+        }
+    }
+
+    len = (word32)outlen;
+
+    if (wc_ecc_shared_secret_ssh((ecc_key*)ecdh->internal,
+                                 (ecc_point*)pub_key->internal,
+                                 (byte *)out, &len) != MP_OKAY) {
+        WOLFSSL_MSG("wc_ecc_shared_secret failed");
+        return SSL_FATAL_ERROR;
+    }
+
+    return len;
+}
+/* End ECDH */
+
+#if !defined(NO_FILESYSTEM)
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_EC_PUBKEY(XFILE fp, WOLFSSL_EC_KEY *x)
+{
+    (void)fp;
+    (void)x;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_EC_PUBKEY not implemented");
+
+    return SSL_FAILURE;
+}
+#endif /* NO_FILESYSTEM */
+
+#if defined(WOLFSSL_KEY_GEN)
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ecc,
+                                       const EVP_CIPHER* cipher,
+                                       unsigned char* passwd, int len,
+                                       pem_password_cb cb, void* arg)
+{
+    (void)bio;
+    (void)ecc;
+    (void)cipher;
+    (void)passwd;
+    (void)len;
+    (void)cb;
+    (void)arg;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_bio_ECPrivateKey not implemented");
+
+    return SSL_FAILURE;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc,
+                                       const EVP_CIPHER* cipher,
+                                       unsigned char* passwd, int passwdSz,
+                                       unsigned char **pem, int *plen)
+{
+    byte *der, *tmp, *cipherInfo = NULL;
+    int  der_max_len = 0, derSz = 0;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey");
+
+    if (pem == NULL || plen == NULL || ecc == NULL || ecc->internal == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return SSL_FAILURE;
+    }
+
+    if (ecc->inSet == 0) {
+        WOLFSSL_MSG("No ECC internal set, do it");
+
+        if (SetECKeyInternal(ecc) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetDsaInternal failed");
+            return SSL_FAILURE;
+        }
+    }
+
+    /* 4 > size of pub, priv + ASN.1 additionnal informations
+     */
+    der_max_len = 4 * wc_ecc_size((ecc_key*)ecc->internal) + AES_BLOCK_SIZE;
+
+    der = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (der == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        return SSL_FAILURE;
+    }
+
+    /* Key to DER */
+    derSz = wc_EccKeyToDer((ecc_key*)ecc->internal, der, der_max_len);
+    if (derSz < 0) {
+        WOLFSSL_MSG("wc_DsaKeyToDer failed");
+        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+
+    /* encrypt DER buffer if required */
+    if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
+        int ret;
+
+        ret = EncryptDerKey(der, &derSz, cipher,
+                            passwd, passwdSz, &cipherInfo);
+        if (ret != SSL_SUCCESS) {
+            WOLFSSL_MSG("EncryptDerKey failed");
+            XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return ret;
+        }
+
+        /* tmp buffer with a max size */
+        *plen = (derSz * 2) + sizeof(BEGIN_EC_PRIV) +
+        sizeof(END_EC_PRIV) + HEADER_ENCRYPTED_KEY_SIZE;
+    }
+    else /* tmp buffer with a max size */
+        *plen = (derSz * 2) + sizeof(BEGIN_EC_PRIV) + sizeof(END_EC_PRIV);
+
+    tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmp == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (cipherInfo != NULL)
+            XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+
+    /* DER to PEM */
+    *plen = wc_DerToPemEx(der, derSz, tmp, *plen, cipherInfo, ECC_PRIVATEKEY_TYPE);
+    if (*plen <= 0) {
+        WOLFSSL_MSG("wc_DerToPemEx failed");
+        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (cipherInfo != NULL)
+            XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (cipherInfo != NULL)
+        XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_OUT_BUFFER);
+    if (*pem == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+    XMEMSET(*pem, 0, (*plen)+1);
+
+    if (XMEMCPY(*pem, tmp, *plen) == NULL) {
+        WOLFSSL_MSG("XMEMCPY failed");
+        XFREE(pem, NULL, DYNAMIC_TYPE_OUT_BUFFER);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+    XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    return SSL_SUCCESS;
+}
+
+#ifndef NO_FILESYSTEM
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_ECPrivateKey(XFILE fp, WOLFSSL_EC_KEY *ecc,
+                                   const EVP_CIPHER *enc,
+                                   unsigned char *kstr, int klen,
+                                   pem_password_cb *cb, void *u)
+{
+    byte *pem;
+    int  plen, ret;
+
+    (void)cb;
+    (void)u;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_ECPrivateKey");
+
+    if (fp == NULL || ecc == NULL || ecc->internal == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return SSL_FAILURE;
+    }
+
+    ret = wolfSSL_PEM_write_mem_ECPrivateKey(ecc, enc, kstr, klen, &pem, &plen);
+    if (ret != SSL_SUCCESS) {
+        WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey failed");
+        return SSL_FAILURE;
+    }
+
+    ret = (int)XFWRITE(pem, plen, 1, fp);
+    if (ret != 1) {
+        WOLFSSL_MSG("ECC private key file write failed");
+        return SSL_FAILURE;
+    }
+    
+    XFREE(pem, NULL, DYNAMIC_TYPE_OUT_BUFFER);
+    return SSL_SUCCESS;
+}
+
+#endif /* NO_FILESYSTEM */
+#endif /* defined(WOLFSSL_KEY_GEN) */
+
+#endif /* HAVE_ECC */
+
+
+#ifndef NO_DSA
+
+#if defined(WOLFSSL_KEY_GEN)
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa,
+                                       const EVP_CIPHER* cipher,
+                                       unsigned char* passwd, int len,
+                                       pem_password_cb cb, void* arg)
+{
+    (void)bio;
+    (void)dsa;
+    (void)cipher;
+    (void)passwd;
+    (void)len;
+    (void)cb;
+    (void)arg;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_bio_DSAPrivateKey not implemented");
+
+    return SSL_FAILURE;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa,
+                                        const EVP_CIPHER* cipher,
+                                        unsigned char* passwd, int passwdSz,
+                                        unsigned char **pem, int *plen)
+{
+    byte *der, *tmp, *cipherInfo = NULL;
+    int  der_max_len = 0, derSz = 0;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey");
+
+    if (pem == NULL || plen == NULL || dsa == NULL || dsa->internal == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return SSL_FAILURE;
+    }
+
+    if (dsa->inSet == 0) {
+        WOLFSSL_MSG("No DSA internal set, do it");
+
+        if (SetDsaInternal(dsa) != SSL_SUCCESS) {
+            WOLFSSL_MSG("SetDsaInternal failed");
+            return SSL_FAILURE;
+        }
+    }
+
+    /* 4 > size of pub, priv, p, q, g + ASN.1 additionnal informations
+     */
+    der_max_len = 4 * wolfSSL_BN_num_bytes(dsa->g) + AES_BLOCK_SIZE;
+
+    der = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (der == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        return SSL_FAILURE;
+    }
+
+    /* Key to DER */
+    derSz = wc_DsaKeyToDer((DsaKey*)dsa->internal, der, der_max_len);
+    if (derSz < 0) {
+        WOLFSSL_MSG("wc_DsaKeyToDer failed");
+        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+
+    /* encrypt DER buffer if required */
+    if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
+        int ret;
+
+        ret = EncryptDerKey(der, &derSz, cipher,
+                            passwd, passwdSz, &cipherInfo);
+        if (ret != SSL_SUCCESS) {
+            WOLFSSL_MSG("EncryptDerKey failed");
+            XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return ret;
+        }
+
+        /* tmp buffer with a max size */
+        *plen = (derSz * 2) + sizeof(BEGIN_DSA_PRIV) +
+        sizeof(END_DSA_PRIV) + HEADER_ENCRYPTED_KEY_SIZE;
+    }
+    else /* tmp buffer with a max size */
+        *plen = (derSz * 2) + sizeof(BEGIN_DSA_PRIV) + sizeof(END_DSA_PRIV);
+
+    tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmp == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (cipherInfo != NULL)
+            XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+
+    /* DER to PEM */
+    *plen = wc_DerToPemEx(der, derSz, tmp, *plen, cipherInfo, DSA_PRIVATEKEY_TYPE);
+    if (*plen <= 0) {
+        WOLFSSL_MSG("wc_DerToPemEx failed");
+        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (cipherInfo != NULL)
+            XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (cipherInfo != NULL)
+        XFREE(cipherInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_OUT_BUFFER);
+    if (*pem == NULL) {
+        WOLFSSL_MSG("malloc failed");
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+    XMEMSET(*pem, 0, (*plen)+1);
+
+    if (XMEMCPY(*pem, tmp, *plen) == NULL) {
+        WOLFSSL_MSG("XMEMCPY failed");
+        XFREE(pem, NULL, DYNAMIC_TYPE_OUT_BUFFER);
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return SSL_FAILURE;
+    }
+    XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    return SSL_SUCCESS;
+}
+
+#ifndef NO_FILESYSTEM
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_DSAPrivateKey(XFILE fp, WOLFSSL_DSA *dsa,
+                                    const EVP_CIPHER *enc,
+                                    unsigned char *kstr, int klen,
+                                    pem_password_cb *cb, void *u)
+{
+    byte *pem;
+    int  plen, ret;
+
+    (void)cb;
+    (void)u;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_DSAPrivateKey");
+
+    if (fp == NULL || dsa == NULL || dsa->internal == NULL) {
+        WOLFSSL_MSG("Bad function arguments");
+        return SSL_FAILURE;
+    }
+
+    ret = wolfSSL_PEM_write_mem_DSAPrivateKey(dsa, enc, kstr, klen, &pem, &plen);
+    if (ret != SSL_SUCCESS) {
+        WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey failed");
+        return SSL_FAILURE;
+    }
+
+    ret = (int)XFWRITE(pem, plen, 1, fp);
+    if (ret != 1) {
+        WOLFSSL_MSG("DSA private key file write failed");
+        return SSL_FAILURE;
+    }
+    
+    XFREE(pem, NULL, DYNAMIC_TYPE_OUT_BUFFER);
+    return SSL_SUCCESS;
+}
+
+#endif /* NO_FILESYSTEM */
+#endif /* defined(WOLFSSL_KEY_GEN) */
+
+#ifndef NO_FILESYSTEM
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_DSA_PUBKEY(XFILE fp, WOLFSSL_DSA *x)
+{
+    (void)fp;
+    (void)x;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_DSA_PUBKEY not implemented");
+
+    return SSL_FAILURE;
+}
+#endif /* NO_FILESYSTEM */
+
+#endif /* #ifndef NO_DSA */
+
+WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
+                    WOLFSSL_EVP_PKEY** key, pem_password_cb cb, void* arg)
+{
+    (void)bio;
+    (void)key;
+    (void)cb;
+    (void)arg;
+
+    WOLFSSL_MSG("wolfSSL_PEM_read_bio_PrivateKey not implemented");
+
+    return NULL;
+}
+
+
+int wolfSSL_EVP_PKEY_type(int type)
+{
+    (void)type;
+
+    WOLFSSL_MSG("wolfSSL_EVP_PKEY_type not implemented");
+
+    return SSL_FATAL_ERROR;
+}
+
+
+#if !defined(NO_FILESYSTEM)
+WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, EVP_PKEY **x,
+                                          pem_password_cb *cb, void *u)
+{
+    (void)fp;
+    (void)x;
+    (void)cb;
+    (void)u;
+
+    WOLFSSL_MSG("wolfSSL_PEM_read_PUBKEY not implemented");
+
+    return NULL;
+}
+#endif /* NO_FILESYSTEM */
+
+#ifndef NO_RSA
+
+#if !defined(NO_FILESYSTEM)
+WOLFSSL_RSA *wolfSSL_PEM_read_RSAPublicKey(XFILE fp, WOLFSSL_RSA **x,
+                                           pem_password_cb *cb, void *u)
+{
+    (void)fp;
+    (void)x;
+    (void)cb;
+    (void)u;
+
+    WOLFSSL_MSG("wolfSSL_PEM_read_RSAPublicKey not implemented");
+
+    return NULL;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_RSAPublicKey(XFILE fp, WOLFSSL_RSA *x)
+{
+    (void)fp;
+    (void)x;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_RSAPublicKey not implemented");
+
+    return SSL_FAILURE;
+}
+
+/* return code compliant with OpenSSL :
+ *   1 if success, 0 if error
+ */
+int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA *x)
+{
+    (void)fp;
+    (void)x;
+
+    WOLFSSL_MSG("wolfSSL_PEM_write_RSA_PUBKEY not implemented");
+
+    return SSL_FAILURE;
+}
+#endif /* NO_FILESYSTEM */
+
+/* return SSL_SUCCESS if success, SSL_FATAL_ERROR if error */
+int wolfSSL_RSA_LoadDer(WOLFSSL_RSA* rsa, const unsigned char* der, int derSz)
+{
+    word32 idx = 0;
+    int    ret;
+
+    WOLFSSL_ENTER("wolfSSL_RSA_LoadDer");
+
+    if (rsa == NULL || rsa->internal == NULL || der == NULL || derSz <= 0) {
+        WOLFSSL_MSG("Bad function arguments");
+        return SSL_FATAL_ERROR;
+    }
+
+    ret = wc_RsaPrivateKeyDecode(der, &idx, (RsaKey*)rsa->internal, derSz);
+    if (ret < 0) {
+        WOLFSSL_MSG("RsaPrivateKeyDecode failed");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetRsaExternal(rsa) != SSL_SUCCESS) {
+        WOLFSSL_MSG("SetRsaExternal failed");
+        return SSL_FATAL_ERROR;
+    }
+
+    rsa->inSet = 1;
+
+    return SSL_SUCCESS;
+}
+#endif /* NO_RSA */
+
+
+#ifndef NO_DSA
+/* return SSL_SUCCESS if success, SSL_FATAL_ERROR if error */
+int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* der, int derSz)
+{
+    word32 idx = 0;
+    int    ret;
+
+    WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
+
+    if (dsa == NULL || dsa->internal == NULL || der == NULL || derSz <= 0) {
+        WOLFSSL_MSG("Bad function arguments");
+        return SSL_FATAL_ERROR;
+    }
+
+    ret = DsaPrivateKeyDecode(der, &idx, (DsaKey*)dsa->internal, derSz);
+    if (ret < 0) {
+        WOLFSSL_MSG("DsaPrivateKeyDecode failed");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetDsaExternal(dsa) != SSL_SUCCESS) {
+        WOLFSSL_MSG("SetDsaExternal failed");
+        return SSL_FATAL_ERROR;
+    }
+
+    dsa->inSet = 1;
+
+    return SSL_SUCCESS;
+}
+#endif /* NO_DSA */
+
+#ifdef HAVE_ECC
+/* return SSL_SUCCESS if success, SSL_FATAL_ERROR if error */
+int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key,
+                           const unsigned char* der,  int derSz)
+{
+    word32 idx = 0;
+    int    ret;
+
+    WOLFSSL_ENTER("wolfSSL_EC_KEY_LoadDer");
+
+    if (key == NULL || key->internal == NULL || der == NULL || derSz <= 0) {
+        WOLFSSL_MSG("Bad function arguments");
+        return SSL_FATAL_ERROR;
+    }
+
+    ret = wc_EccPrivateKeyDecode(der, &idx, (ecc_key*)key->internal, derSz);
+    if (ret < 0) {
+        WOLFSSL_MSG("wc_EccPrivateKeyDecode failed");
+        return SSL_FATAL_ERROR;
+    }
+
+    if (SetECKeyExternal(key) != SSL_SUCCESS) {
+        WOLFSSL_MSG("SetECKeyExternal failed");
+        return SSL_FATAL_ERROR;
+    }
+
+    key->inSet = 1;
+
+    return SSL_SUCCESS;
+}
+#endif /* HAVE_ECC */
+
+#endif /* OPENSSL_EXTRA */
+
+
+#ifdef SESSION_CERTS
+
+
+/* Get peer's certificate chain */
+WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_peer_chain");
+    if (ssl)
+        return &ssl->session.chain;
+
+    return 0;
+}
+
+
+/* Get peer's certificate chain total count */
+int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain)
+{
+    WOLFSSL_ENTER("wolfSSL_get_chain_count");
+    if (chain)
+        return chain->count;
+
+    return 0;
+}
+
+
+/* Get peer's ASN.1 DER ceritifcate at index (idx) length in bytes */
+int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_get_chain_length");
+    if (chain)
+        return chain->certs[idx].length;
+
+    return 0;
+}
+
+
+/* Get peer's ASN.1 DER ceritifcate at index (idx) */
+byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_get_chain_cert");
+    if (chain)
+        return chain->certs[idx].buffer;
+
+    return 0;
+}
+
+
+/* Get peer's wolfSSL X509 ceritifcate at index (idx) */
+WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx)
+{
+    int          ret;
+    WOLFSSL_X509* x509 = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* cert = NULL;
+#else
+    DecodedCert  cert[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_get_chain_X509");
+    if (chain != NULL) {
+    #ifdef WOLFSSL_SMALL_STACK
+        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+        if (cert != NULL)
+    #endif
+        {
+            InitDecodedCert(cert, chain->certs[idx].buffer,
+                                  chain->certs[idx].length, NULL);
+
+            if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) != 0)
+                WOLFSSL_MSG("Failed to parse cert");
+            else {
+                x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
+                                                             DYNAMIC_TYPE_X509);
+                if (x509 == NULL) {
+                    WOLFSSL_MSG("Failed alloc X509");
+                }
+                else {
+                    InitX509(x509, 1);
+
+                    if ((ret = CopyDecodedToX509(x509, cert)) != 0) {
+                        WOLFSSL_MSG("Failed to copy decoded");
+                        XFREE(x509, NULL, DYNAMIC_TYPE_X509);
+                        x509 = NULL;
+                    }
+                }
+            }
+
+            FreeDecodedCert(cert);
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+        }
+    }
+
+    return x509;
+}
+
+
+/* Get peer's PEM ceritifcate at index (idx), output to buffer if inLen big
+   enough else return error (-1). If buffer is NULL only calculate
+   outLen. Output length is in *outLen SSL_SUCCESS on ok */
+int  wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
+                               unsigned char* buf, int inLen, int* outLen)
+{
+    const char header[] = "-----BEGIN CERTIFICATE-----\n";
+    const char footer[] = "-----END CERTIFICATE-----\n";
+
+    int headerLen = sizeof(header) - 1;
+    int footerLen = sizeof(footer) - 1;
+    int i;
+    int err;
+    word32 szNeeded = 0;
+
+    WOLFSSL_ENTER("wolfSSL_get_chain_cert_pem");
+    if (!chain || !outLen || idx < 0 || idx >= wolfSSL_get_chain_count(chain))
+        return BAD_FUNC_ARG;
+
+    /* Null output buffer return size needed in outLen */
+    if(!buf) {
+        if(Base64_Encode(chain->certs[idx].buffer, chain->certs[idx].length,
+                    NULL, &szNeeded) != LENGTH_ONLY_E)
+            return SSL_FAILURE;
+        *outLen = szNeeded + headerLen + footerLen;
+        return LENGTH_ONLY_E;
+    }
+
+    /* don't even try if inLen too short */
+    if (inLen < headerLen + footerLen + chain->certs[idx].length)
+        return BAD_FUNC_ARG;
+
+    /* header */
+    if (XMEMCPY(buf, header, headerLen) == NULL)
+        return SSL_FATAL_ERROR;
+
+    i = headerLen;
+
+    /* body */
+    *outLen = inLen;  /* input to Base64_Encode */
+    if ( (err = Base64_Encode(chain->certs[idx].buffer,
+                       chain->certs[idx].length, buf + i, (word32*)outLen)) < 0)
+        return err;
+    i += *outLen;
+
+    /* footer */
+    if ( (i + footerLen) > inLen)
+        return BAD_FUNC_ARG;
+    if (XMEMCPY(buf + i, footer, footerLen) == NULL)
+        return SSL_FATAL_ERROR;
+    *outLen += headerLen + footerLen;
+
+    return SSL_SUCCESS;
+}
+
+
+/* get session ID */
+const byte* wolfSSL_get_sessionID(const WOLFSSL_SESSION* session)
+{
+    WOLFSSL_ENTER("wolfSSL_get_sessionID");
+    if (session)
+        return session->sessionID;
+
+    return NULL;
+}
+
+
+#endif /* SESSION_CERTS */
+
+#ifdef HAVE_FUZZER
+void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx)
+{
+    if (ssl) {
+        ssl->fuzzerCb  = cbf;
+        ssl->fuzzerCtx = fCtx;
+    }
+}
+#endif
+
+#ifndef NO_CERTS
+#ifdef  HAVE_PK_CALLBACKS
+
+#ifdef HAVE_ECC
+
+void  wolfSSL_CTX_SetEccSignCb(WOLFSSL_CTX* ctx, CallbackEccSign cb)
+{
+    if (ctx)
+        ctx->EccSignCb = cb;
+}
+
+
+void  wolfSSL_SetEccSignCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->EccSignCtx = ctx;
+}
+
+
+void* wolfSSL_GetEccSignCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->EccSignCtx;
+
+    return NULL;
+}
+
+
+void  wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX* ctx, CallbackEccVerify cb)
+{
+    if (ctx)
+        ctx->EccVerifyCb = cb;
+}
+
+
+void  wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->EccVerifyCtx = ctx;
+}
+
+
+void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->EccVerifyCtx;
+
+    return NULL;
+}
+
+#endif /* HAVE_ECC */
+
+#ifndef NO_RSA
+
+void  wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX* ctx, CallbackRsaSign cb)
+{
+    if (ctx)
+        ctx->RsaSignCb = cb;
+}
+
+
+void  wolfSSL_SetRsaSignCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->RsaSignCtx = ctx;
+}
+
+
+void* wolfSSL_GetRsaSignCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->RsaSignCtx;
+
+    return NULL;
+}
+
+
+void  wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
+{
+    if (ctx)
+        ctx->RsaVerifyCb = cb;
+}
+
+
+void  wolfSSL_SetRsaVerifyCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->RsaVerifyCtx = ctx;
+}
+
+
+void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->RsaVerifyCtx;
+
+    return NULL;
+}
+
+void  wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX* ctx, CallbackRsaEnc cb)
+{
+    if (ctx)
+        ctx->RsaEncCb = cb;
+}
+
+
+void  wolfSSL_SetRsaEncCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->RsaEncCtx = ctx;
+}
+
+
+void* wolfSSL_GetRsaEncCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->RsaEncCtx;
+
+    return NULL;
+}
+
+void  wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX* ctx, CallbackRsaDec cb)
+{
+    if (ctx)
+        ctx->RsaDecCb = cb;
+}
+
+
+void  wolfSSL_SetRsaDecCtx(WOLFSSL* ssl, void *ctx)
+{
+    if (ssl)
+        ssl->RsaDecCtx = ctx;
+}
+
+
+void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
+{
+    if (ssl)
+        return ssl->RsaDecCtx;
+
+    return NULL;
+}
+
+
+#endif /* NO_RSA */
+
+#endif /* HAVE_PK_CALLBACKS */
+#endif /* NO_CERTS */
+
+
+#ifdef WOLFSSL_HAVE_WOLFSCEP
+    /* Used by autoconf to see if wolfSCEP is available */
+    void wolfSSL_wolfSCEP(void) {}
+#endif
+
+
+#ifdef WOLFSSL_HAVE_CERT_SERVICE
+    /* Used by autoconf to see if cert service is available */
+    void wolfSSL_cert_service(void) {}
+#endif
+
+
+#ifdef OPENSSL_EXTRA /*Lighttp compatibility*/
+#ifdef HAVE_LIGHTY
+
+    unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n, unsigned char *md)
+    {
+        (void) *d; (void) n; (void) *md;
+        WOLFSSL_ENTER("wolfSSL_SHA1");
+        WOLFSSL_STUB("wolfssl_SHA1");
+
+        return NULL;
+    }
+
+    char wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x) {
+        (void)ctx;
+        (void)x;
+        WOLFSSL_ENTER("wolfSSL_CTX_use_certificate");
+        WOLFSSL_STUB("wolfSSL_CTX_use_certificate");
+
+        return 0;
+    }
+
+    int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey) {
+        (void)ctx;
+        (void)pkey;
+        WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey");
+        WOLFSSL_STUB("wolfSSL_CTX_use_PrivateKey");
+
+        return 0;
+    }
+
+
+    int wolfSSL_BIO_read_filename(WOLFSSL_BIO *b, const char *name) {
+        (void)b;
+        (void)name;
+        WOLFSSL_ENTER("wolfSSL_BIO_read_filename");
+        WOLFSSL_STUB("wolfSSL_BIO_read_filename");
+
+        return 0;
+    }
+
+    WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_file(void) {
+        WOLFSSL_ENTER("wolfSSL_BIO_s_file");
+        WOLFSSL_STUB("wolfSSL_BIO_s_file");
+
+        return NULL;
+    }
+
+    const char * wolf_OBJ_nid2sn(int n) {
+        (void)n;
+        WOLFSSL_ENTER("wolf_OBJ_nid2sn");
+        WOLFSSL_STUB("wolf_OBJ_nid2sn");
+
+        return 0;
+    }
+
+    int wolf_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o) {
+        (void)o;
+        WOLFSSL_ENTER("wolf_OBJ_obj2nid");
+        WOLFSSL_STUB("wolf_OBJ_obj2nid");
+
+        return 0;
+    }
+
+    int wolf_OBJ_sn2nid(const char *sn) {
+        (void)sn;
+        WOLFSSL_ENTER("wolf_OBJ_osn2nid");
+        WOLFSSL_STUB("wolf_OBJ_osn2nid");
+
+        return 0;
+    }
+
+
+    WOLFSSL_X509 *PEM_read_bio_WOLFSSL_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u) {
+        (void)bp;
+        (void)x;
+        (void)cb;
+        (void)u;
+        WOLFSSL_ENTER("PEM_read_bio_WOLFSSL_X509");
+        WOLFSSL_STUB("PEM_read_bio_WOLFSSL_X509");
+
+        return NULL;
+    }
+
+    void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx, int depth) {
+        (void)ctx;
+        (void)depth;
+        WOLFSSL_ENTER("wolfSSL_CTX_set_verify_depth");
+        WOLFSSL_STUB("wolfSSL_CTX_set_verify_depth");
+
+    }
+
+    void* wolfSSL_get_app_data( const WOLFSSL *ssl)
+    {
+        /* checkout exdata stuff... */
+        (void)ssl;
+        WOLFSSL_ENTER("wolfSSL_get_app_data");
+        WOLFSSL_STUB("wolfSSL_get_app_data");
+
+        return 0;
+    }
+
+    void wolfSSL_set_app_data(WOLFSSL *ssl, void *arg) {
+        (void)ssl;
+        (void)arg;
+        WOLFSSL_ENTER("wolfSSL_set_app_data");
+        WOLFSSL_STUB("wolfSSL_set_app_data");
+    }
+
+    WOLFSSL_ASN1_OBJECT * wolfSSL_X509_NAME_ENTRY_get_object(WOLFSSL_X509_NAME_ENTRY *ne) {
+        (void)ne;
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_object");
+        WOLFSSL_STUB("wolfSSL_X509_NAME_ENTRY_get_object");
+
+        return NULL;
+    }
+
+    WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(WOLFSSL_X509_NAME *name, int loc) {
+        (void)name;
+        (void)loc;
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_get_entry");
+        WOLFSSL_STUB("wolfSSL_X509_NAME_get_entry");
+
+        return NULL;
+    }
+
+    void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name){
+        FreeX509Name(name);
+        WOLFSSL_ENTER("wolfSSL_X509_NAME_free");
+        WOLFSSL_STUB("wolfSSL_X509_NAME_free");
+    }
+
+    void wolfSSL_sk_X509_NAME_pop_free(STACK_OF(WOLFSSL_X509_NAME)* sk, void f (WOLFSSL_X509_NAME*)){
+        (void) sk;
+        (void) f;
+        WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_pop_free");
+        WOLFSSL_STUB("wolfSSL_sk_X509_NAME_pop_free");
+    }
+
+    int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key){
+        (void) x509;
+        (void) key;
+        WOLFSSL_ENTER("wolfSSL_X509_check_private_key");
+        WOLFSSL_STUB("wolfSSL_X509_check_private_key");
+
+        return SSL_SUCCESS;
+    }
+
+    STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list( STACK_OF(WOLFSSL_X509_NAME) *sk ){
+        (void) sk;
+        WOLFSSL_ENTER("wolfSSL_dup_CA_list");
+        WOLFSSL_STUB("wolfSSL_dup_CA_list");
+
+        return NULL;
+    }
+
+#endif
+#endif
+
+
+#ifdef OPENSSL_EXTRA
+void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
+    #ifdef HAVE_STUNNEL
+    if(ctx != NULL && idx < MAX_EX_DATA && idx >= 0) {
+        return ctx->ex_data[idx];
+    }
+    #else
+    (void)ctx;
+    (void)idx;
+    #endif
+    return NULL;
+}
+
+
+int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b,
+                                void* c)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_new_index");
+    (void)idx;
+    (void)arg;
+    (void)a;
+    (void)b;
+    (void)c;
+    return 0;
+}
+
+
+int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data");
+    #ifdef HAVE_STUNNEL
+    if (ctx != NULL && idx < MAX_EX_DATA)
+    {
+        ctx->ex_data[idx] = data;
+        return SSL_SUCCESS;
+    }
+    #else
+    (void)ctx;
+    (void)idx;
+    (void)data;
+    #endif
+    return SSL_FAILURE;
+}
+
+
+int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
+{
+    WOLFSSL_ENTER("wolfSSL_set_ex_data");
+#if defined(FORTRESS) || defined(HAVE_STUNNEL)
+    if (ssl != NULL && idx < MAX_EX_DATA)
+    {
+        ssl->ex_data[idx] = data;
+        return SSL_SUCCESS;
+    }
+#else
+    (void)ssl;
+    (void)idx;
+    (void)data;
+#endif
+    return SSL_FAILURE;
+}
+
+
+int wolfSSL_get_ex_new_index(long idx, void* data, void* cb1, void* cb2,
+                         void* cb3)
+{
+    WOLFSSL_ENTER("wolfSSL_get_ex_new_index");
+    (void)idx;
+    (void)data;
+    (void)cb1;
+    (void)cb2;
+    (void)cb3;
+    return 0;
+}
+
+
+void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_get_ex_data");
+#if defined(FORTRESS) || defined(HAVE_STUNNEL)
+    if (ssl != NULL && idx < MAX_EX_DATA && idx >= 0)
+        return ssl->ex_data[idx];
+#else
+    (void)ssl;
+    (void)idx;
+#endif
+    return 0;
+}
+#endif /* OPENSSL_EXTRA */
+
+
+#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL)
+WOLFSSL_BIO *wolfSSL_BIO_new_file(const char *filename, const char *mode) {
+    (void)filename;
+    (void)mode;
+    WOLFSSL_ENTER("wolfSSL_BIO_new_file");
+    WOLFSSL_STUB("wolfSSL_BIO_new_file");
+
+    return NULL;
+}
+
+
+WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bp, WOLFSSL_DH **x, pem_password_cb *cb, void *u)
+{
+    (void) bp;
+    (void) x;
+    (void) cb;
+    (void) u;
+
+    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DHparams");
+    WOLFSSL_STUB("wolfSSL_PEM_read_bio_DHparams");
+
+    return NULL;
+}
+
+int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 *x) {
+    (void)bp;
+    (void)x;
+    WOLFSSL_ENTER("PEM_write_bio_WOLFSSL_X509");
+    WOLFSSL_STUB("PEM_write_bio_WOLFSSL_X509");
+
+    return 0;
+}
+
+
+#ifndef NO_DH
+/* Intialize ctx->dh with dh's params. Return SSL_SUCCESS on ok */
+long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL_DH* dh)
+{
+    int pSz, gSz;
+    byte *p, *g;
+    int ret=0;
+
+    WOLFSSL_ENTER("wolfSSL_CTX_set_tmp_dh");
+
+    if(!ctx || !dh)
+        return BAD_FUNC_ARG;
+
+    /* Get needed size for p and g */
+    pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
+    gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
+
+    if(pSz <= 0 || gSz <= 0)
+        return SSL_FATAL_ERROR;
+
+    p = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_DH);
+    if(!p)
+        return MEMORY_E;
+
+    g = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_DH);
+    if(!g) {
+        XFREE(p, ctx->heap, DYNAMIC_TYPE_DH);
+        return MEMORY_E;
+    }
+
+    pSz = wolfSSL_BN_bn2bin(dh->p, p);
+    gSz = wolfSSL_BN_bn2bin(dh->g, g);
+
+    if(pSz >= 0 && gSz >= 0) /* Conversion successful */
+        ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
+
+    XFREE(p, ctx->heap, DYNAMIC_TYPE_DH);
+    XFREE(g, ctx->heap, DYNAMIC_TYPE_DH);
+
+    return pSz > 0 && gSz > 0 ? ret : SSL_FATAL_ERROR;
+}
+#endif /* NO_DH */
+#endif /* HAVE_LIGHTY || HAVE_STUNNEL */
+
+
+/* stunnel compatability functions*/
+#if defined(OPENSSL_EXTRA) && defined(HAVE_STUNNEL)
+int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION* session, int idx, void* data)
+{
+    WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data");
+    if(session != NULL && idx < MAX_EX_DATA) {
+        session->ex_data[idx] = data;
+        return SSL_SUCCESS;
+    }
+    return SSL_FAILURE;
+}
+
+
+int wolfSSL_SESSION_get_ex_new_index(long idx, void* data, void* cb1,
+       void* cb2, CRYPTO_free_func* cb3)
+{
+    WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_new_index");
+    (void)idx;
+    (void)cb1;
+    (void)cb2;
+    (void)cb3;
+    if(XSTRNCMP((const char*)data, "redirect index", 14) == 0) {
+        return 0;
+    }
+    else if(XSTRNCMP((const char*)data, "addr index", 10) == 0) {
+        return 1;
+    }
+    return SSL_FAILURE;
+}
+
+
+void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION* session, int idx)
+{
+    WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_data");
+    if (session != NULL && idx < MAX_EX_DATA && idx >= 0)
+        return session->ex_data[idx];
+    return NULL;
+}
+
+
+int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
+                                void *(*r) (void *, size_t, const char *,
+                                            int), void (*f) (void *))
+{
+    (void) m;
+    (void) r;
+    (void) f;
+    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_mem_ex_functions");
+    WOLFSSL_STUB("wolfSSL_CRYPTO_set_mem_ex_functions");
+
+    return SSL_FAILURE;
+}
+
+
+WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator,
+                           void (*callback) (int, int, void *), void *cb_arg)
+{
+    (void)prime_len;
+    (void)generator;
+    (void)callback;
+    (void)cb_arg;
+    WOLFSSL_ENTER("wolfSSL_DH_generate_parameters");
+    WOLFSSL_STUB("wolfSSL_DH_generate_parameters");
+
+    return NULL;
+}
+
+
+void wolfSSL_ERR_load_crypto_strings(void)
+{
+    WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
+    WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
+    return;
+}
+
+
+unsigned long wolfSSL_ERR_peek_last_error(void)
+{
+    unsigned long l = 0UL;
+    WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
+    WOLFSSL_STUB("wolfSSL_ERR_peek_last_error");
+
+    return l;
+}
+
+
+int wolfSSL_FIPS_mode(void)
+{
+    WOLFSSL_ENTER("wolfSSL_FIPS_mode");
+    WOLFSSL_STUB("wolfSSL_FIPS_mode");
+
+    return SSL_FAILURE;
+}
+
+int wolfSSL_FIPS_mode_set(int r)
+{
+    (void)r;
+    WOLFSSL_ENTER("wolfSSL_FIPS_mode_set");
+    WOLFSSL_STUB("wolfSSL_FIPS_mode_set");
+
+    return SSL_FAILURE;
+}
+
+
+int wolfSSL_RAND_set_rand_method(const void *meth)
+{
+    (void) meth;
+    WOLFSSL_ENTER("wolfSSL_RAND_set_rand_method");
+    WOLFSSL_STUB("wolfSSL_RAND_set_rand_method");
+
+    return SSL_FAILURE;
+}
+
+
+int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits)
+{
+    int ret = SSL_FAILURE;
+    WOLFSSL_ENTER("wolfSSL_CIPHER_get_bits");
+    if(c != NULL && c->ssl != NULL) {
+        ret = 8 * c->ssl->specs.key_size;
+        if(alg_bits != NULL) {
+            *alg_bits = ret;
+        }
+    }
+    return ret;
+}
+
+
+int wolfSSL_sk_X509_NAME_num(const STACK_OF(WOLFSSL_X509_NAME) *s)
+{
+    (void) s;
+    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_num");
+    WOLFSSL_STUB("wolfSSL_sk_X509_NAME_num");
+
+    return SSL_FAILURE;
+}
+
+
+int wolfSSL_sk_X509_num(const STACK_OF(WOLFSSL_X509) *s)
+{
+    (void) s;
+    WOLFSSL_ENTER("wolfSSL_sk_X509_num");
+    WOLFSSL_STUB("wolfSSL_sk_X509_num");
+
+    return SSL_FAILURE;
+}
+
+
+int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* nm,
+                int indent, unsigned long flags)
+{
+    (void)bio;
+    (void)nm;
+    (void)indent;
+    (void)flags;
+    WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex");
+    WOLFSSL_STUB("wolfSSL_X509_NAME_print_ex");
+
+    return SSL_FAILURE;
+}
+
+
+WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr(const WOLFSSL_X509* x)
+{
+    (void)x;
+    WOLFSSL_ENTER("wolfSSL_X509_get0_pubkey_bitstr");
+    WOLFSSL_STUB("wolfSSL_X509_get0_pubkey_bitstr");
+
+    return NULL;
+}
+
+
+int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
+{
+    (void)ctx;
+    (void)session;
+    WOLFSSL_ENTER("wolfSSL_CTX_add_session");
+    WOLFSSL_STUB("wolfSSL_CTX_add_session");
+
+    return SSL_SUCCESS;
+}
+
+
+int wolfSSL_get_state(const WOLFSSL* ssl)
+{
+    (void)ssl;
+    WOLFSSL_ENTER("wolfSSL_get_state");
+    WOLFSSL_STUB("wolfSSL_get_state");
+
+    return SSL_FAILURE;
+}
+
+
+void* wolfSSL_sk_X509_NAME_value(STACK_OF(WOLFSSL_X509_NAME)* sk, int i)
+{
+    (void)sk;
+    (void)i;
+    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_value");
+    WOLFSSL_STUB("wolfSSL_sk_X509_NAME_value");
+
+    return NULL;
+}
+
+
+void* wolfSSL_sk_X509_value(STACK_OF(WOLFSSL_X509)* sk, int i)
+{
+    (void)sk;
+    (void)i;
+    WOLFSSL_ENTER("wolfSSL_sk_X509_value");
+    WOLFSSL_STUB("wolfSSL_sk_X509_value");
+
+    return NULL;
+}
+
+
+int wolfSSL_version(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_version");
+    if (ssl->version.major == SSLv3_MAJOR) {
+        switch (ssl->version.minor) {
+            case SSLv3_MINOR :
+                return SSL3_VERSION;
+            case TLSv1_MINOR :
+            case TLSv1_1_MINOR :
+            case TLSv1_2_MINOR :
+                return TLS1_VERSION;
+            default:
+                return SSL_FAILURE;
+        }
+    }
+    else if (ssl->version.major == DTLS_MAJOR) {
+        switch (ssl->version.minor) {
+            case DTLS_MINOR :
+            case DTLSv1_2_MINOR :
+                return DTLS1_VERSION;
+            default:
+                return SSL_FAILURE;
+        }
+    }
+    return SSL_FAILURE;
+}
+
+
+STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL* ssl)
+{
+    (void)ssl;
+    WOLFSSL_ENTER("wolfSSL_get_peer_cert_chain");
+    WOLFSSL_STUB("wolfSSL_get_peer_cert_chain");
+
+    return NULL;
+}
+
+
+long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx)
+{
+    (void)ctx;
+    WOLFSSL_ENTER("wolfSSL_CTX_get_options");
+    WOLFSSL_STUB("wolfSSL_CTX_get_options");
+
+    return 0;
+}
+
+
+WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_SSL_CTX");
+    return ssl->ctx;
+}
+
+int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME* name)
+{
+    WOLFSSL_ENTER("wolfSSL_X509_NAME_get_sz");
+    if(!name)
+        return -1;
+    return name->sz;
+}
+
+
+const byte* wolfSSL_SESSION_get_id(WOLFSSL_SESSION* sess, unsigned int* idLen)
+{
+    WOLFSSL_ENTER("wolfSSL_SESSION_get_id");
+    WOLFSSL_STUB("wolfSSL_SESSION_get_id");
+    if(!sess || !idLen) {
+        WOLFSSL_MSG("Bad func args. Please provide idLen");
+        return NULL;
+    }
+    *idLen = sess->sessionIDSz;
+    return sess->sessionID;
+}
+
+
+int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name)
+{
+    int ret;
+    WOLFSSL_ENTER("wolfSSL_set_tlsext_host_name");
+    ret = wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME,
+            host_name, XSTRLEN(host_name));
+    WOLFSSL_LEAVE("wolfSSL_set_tlsext_host_name", ret);
+    return ret;
+}
+
+
+const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type)
+{
+    void * serverName = NULL;
+    if (ssl == NULL)
+        return NULL;
+    TLSX_SNI_GetRequest(ssl->extensions, type, &serverName);
+    return (const char *)serverName;
+}
+
+
+WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
+{
+    if (ssl && ctx && SetSSL_CTX(ssl, ctx) == SSL_SUCCESS)
+        return ssl->ctx;
+    return NULL;
+}
+
+
+VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_get_verify_callback");
+    if(ctx)
+        return ctx->verifyCallback;
+    return NULL;
+}
+
+
+int wolfSSL_CTX_get_verify_mode(WOLFSSL_CTX* ctx)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_get_verify_mode");
+    int mode = 0;
+
+    if(!ctx)
+        return SSL_FATAL_ERROR;
+
+    if (ctx->verifyPeer)
+        mode |= SSL_VERIFY_PEER;
+    else if (ctx->verifyNone)
+        mode |= SSL_VERIFY_NONE;
+
+    if (ctx->failNoCert)
+        mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+
+    WOLFSSL_LEAVE("wolfSSL_CTX_get_verify_mode", mode);
+    return mode;
+}
+
+
+void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
+    if (ctx)
+        ctx->sniRecvCb = cb;
+}
+
+
+void wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
+{
+    WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
+    if (ctx)
+        ctx->sniRecvCbArg = arg;
+}
+#endif /* OPENSSL_EXTRA and HAVE_STUNNEL */
+
+#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE25519)
+/* return 1 if success, 0 if error
+ * output keys are little endian format
+ */
+int wolfSSL_EC25519_generate_key(unsigned char *priv, unsigned int *privSz,
+                                 unsigned char *pub, unsigned int *pubSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    return SSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    int ret = SSL_FAILURE;
+    int initTmpRng = 0;
+    WC_RNG *rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG *tmpRNG = NULL;
+#else
+    WC_RNG tmpRNG[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_EC25519_generate_key");
+
+    if (priv == NULL || privSz == NULL || *privSz < CURVE25519_KEYSIZE ||
+        pub == NULL || pubSz == NULL || *pubSz < CURVE25519_KEYSIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return SSL_FAILURE;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmpRNG == NULL)
+        return SSL_FAILURE;
+#endif
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+        curve25519_key key;
+
+        if (wc_curve25519_init(&key) != MP_OKAY)
+            WOLFSSL_MSG("wc_curve25519_init failed");
+        else if (wc_curve25519_make_key(rng, CURVE25519_KEYSIZE, &key)!=MP_OKAY)
+            WOLFSSL_MSG("wc_curve25519_make_key failed");
+        /* export key pair */
+        else if (wc_curve25519_export_key_raw_ex(&key, priv, privSz, pub,
+                                                 pubSz, EC25519_LITTLE_ENDIAN)
+                 != MP_OKAY)
+            WOLFSSL_MSG("wc_curve25519_export_key_raw_ex failed");
+        else
+            ret = SSL_SUCCESS;
+
+        wc_curve25519_free(&key);
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+
+/* return 1 if success, 0 if error
+ * input and output keys are little endian format
+ */
+int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz,
+                               const unsigned char *priv, unsigned int privSz,
+                               const unsigned char *pub, unsigned int pubSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    return SSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    int ret = SSL_FAILURE;
+    curve25519_key privkey, pubkey;
+
+    WOLFSSL_ENTER("wolfSSL_EC25519_shared_key");
+
+    if (shared == NULL || sharedSz == NULL || *sharedSz < CURVE25519_KEYSIZE ||
+        priv == NULL || privSz < CURVE25519_KEYSIZE ||
+        pub == NULL || pubSz < CURVE25519_KEYSIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return SSL_FAILURE;
+    }
+
+    /* import private key */
+    if (wc_curve25519_init(&privkey) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve25519_init privkey failed");
+        return ret;
+    }
+    if (wc_curve25519_import_private_ex(priv, privSz, &privkey,
+                                        EC25519_LITTLE_ENDIAN) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve25519_import_private_ex failed");
+        wc_curve25519_free(&privkey);
+        return ret;
+    }
+
+    /* import public key */
+    if (wc_curve25519_init(&pubkey) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve25519_init pubkey failed");
+        wc_curve25519_free(&privkey);
+        return ret;
+    }
+    if (wc_curve25519_import_public_ex(pub, pubSz, &pubkey,
+                                       EC25519_LITTLE_ENDIAN) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve25519_import_public_ex failed");
+        wc_curve25519_free(&privkey);
+        wc_curve25519_free(&pubkey);
+        return ret;
+    }
+
+    if (wc_curve25519_shared_secret_ex(&privkey, &pubkey,
+                                       shared, sharedSz,
+                                       EC25519_LITTLE_ENDIAN) != MP_OKAY)
+        WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
+    else
+        ret = SSL_SUCCESS;
+
+    wc_curve25519_free(&privkey);
+    wc_curve25519_free(&pubkey);
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+#endif /* OPENSSL_EXTRA && HAVE_CURVE25519 */
+
+#if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519)
+/* return 1 if success, 0 if error
+ * output keys are little endian format
+ */
+int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz,
+                                 unsigned char *pub, unsigned int *pubSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    return SSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    int ret = SSL_FAILURE;
+    int initTmpRng = 0;
+    WC_RNG *rng = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+    WC_RNG *tmpRNG = NULL;
+#else
+    WC_RNG tmpRNG[1];
+#endif
+
+    WOLFSSL_ENTER("wolfSSL_ED25519_generate_key");
+
+    if (priv == NULL || privSz == NULL || *privSz < ED25519_PRV_KEY_SIZE ||
+        pub == NULL || pubSz == NULL || *pubSz < ED25519_PUB_KEY_SIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return SSL_FAILURE;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmpRNG == NULL)
+        return SSL_FATAL_ERROR;
+#endif
+    if (wc_InitRng(tmpRNG) == 0) {
+        rng = tmpRNG;
+        initTmpRng = 1;
+    }
+    else {
+        WOLFSSL_MSG("Bad RNG Init, trying global");
+        if (initGlobalRNG == 0)
+            WOLFSSL_MSG("Global RNG no Init");
+        else
+            rng = &globalRNG;
+    }
+
+    if (rng) {
+        ed25519_key key;
+
+        if (wc_ed25519_init(&key) != MP_OKAY)
+            WOLFSSL_MSG("wc_ed25519_init failed");
+        else if (wc_ed25519_make_key(rng, ED25519_KEY_SIZE, &key)!=MP_OKAY)
+            WOLFSSL_MSG("wc_ed25519_make_key failed");
+        /* export private key */
+        else if (wc_ed25519_export_key(&key, priv, privSz, pub, pubSz)!=MP_OKAY)
+            WOLFSSL_MSG("wc_ed25519_export_key failed");
+        else
+            ret = SSL_SUCCESS;
+
+        wc_ed25519_free(&key);
+    }
+
+    if (initTmpRng)
+        wc_FreeRng(tmpRNG);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+
+/* return 1 if success, 0 if error
+ * input and output keys are little endian format
+ * priv is a buffer containing private and public part of key
+ */
+int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
+                         const unsigned char *priv, unsigned int privSz,
+                         unsigned char *sig, unsigned int *sigSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    return SSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    ed25519_key key;
+    int ret = SSL_FAILURE;
+
+    WOLFSSL_ENTER("wolfSSL_ED25519_sign");
+
+    if (priv == NULL || privSz != ED25519_PRV_KEY_SIZE ||
+        msg == NULL || sig == NULL || *sigSz < ED25519_SIG_SIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return SSL_FAILURE;
+    }
+
+    /* import key */
+    if (wc_ed25519_init(&key) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve25519_init failed");
+        return ret;
+    }
+    if (wc_ed25519_import_private_key(priv, privSz/2,
+                                      priv+(privSz/2), ED25519_PUB_KEY_SIZE,
+                                      &key) != MP_OKAY){
+        WOLFSSL_MSG("wc_ed25519_import_private failed");
+        wc_ed25519_free(&key);
+        return ret;
+    }
+
+    if (wc_ed25519_sign_msg(msg, msgSz, sig, sigSz, &key) != MP_OKAY)
+        WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
+    else
+        ret = SSL_SUCCESS;
+
+    wc_ed25519_free(&key);
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+
+/* return 1 if success, 0 if error
+ * input and output keys are little endian format
+ * pub is a buffer containing public part of key
+ */
+int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
+                           const unsigned char *pub, unsigned int pubSz,
+                           const unsigned char *sig, unsigned int sigSz)
+{
+#ifndef WOLFSSL_KEY_GEN
+    WOLFSSL_MSG("No Key Gen built in");
+    return SSL_FAILURE;
+#else /* WOLFSSL_KEY_GEN */
+    ed25519_key key;
+    int ret = SSL_FAILURE, check = 0;
+
+    WOLFSSL_ENTER("wolfSSL_ED25519_verify");
+
+    if (pub == NULL || pubSz != ED25519_PUB_KEY_SIZE ||
+        msg == NULL || sig == NULL || sigSz != ED25519_SIG_SIZE) {
+        WOLFSSL_MSG("Bad arguments");
+        return SSL_FAILURE;
+    }
+
+    /* import key */
+    if (wc_ed25519_init(&key) != MP_OKAY) {
+        WOLFSSL_MSG("wc_curve25519_init failed");
+        return ret;
+    }
+    if (wc_ed25519_import_public(pub, pubSz, &key) != MP_OKAY){
+        WOLFSSL_MSG("wc_ed25519_import_public failed");
+        wc_ed25519_free(&key);
+        return ret;
+    }
+
+    if ((ret = wc_ed25519_verify_msg((byte*)sig, sigSz, msg, msgSz,
+                                     &check, &key)) != MP_OKAY) {
+        WOLFSSL_MSG("wc_ed25519_verify_msg failed");
+        fprintf(stderr, "err code = %d, sigSz=%d, msgSz=%d\n", ret, sigSz, msgSz);
+    }
+    else if (!check)
+        WOLFSSL_MSG("wc_ed25519_verify_msg failed (signature invalid)");
+    else
+        ret = SSL_SUCCESS;
+
+    wc_ed25519_free(&key);
+
+    return ret;
+#endif /* WOLFSSL_KEY_GEN */
+}
+
+#endif /* OPENSSL_EXTRA && HAVE_ED25519 */
+
+#ifdef WOLFSSL_JNI
+
+int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr)
+{
+    WOLFSSL_ENTER("wolfSSL_set_jobject");
+    if (ssl != NULL)
+    {
+        ssl->jObjectRef = objPtr;
+        return SSL_SUCCESS;
+    }
+    return SSL_FAILURE;
+}
+
+void* wolfSSL_get_jobject(WOLFSSL* ssl)
+{
+    WOLFSSL_ENTER("wolfSSL_get_jobject");
+    if (ssl != NULL)
+        return ssl->jObjectRef;
+    return NULL;
+}
+
+#endif /* WOLFSSL_JNI */
+
+#endif /* WOLFCRYPT_ONLY */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/src/tls.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/src/tls.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/src/tls.c	(revision 164)
@@ -0,0 +1,3890 @@
+/* tls.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLFCRYPT_ONLY
+
+#include <wolfssl/wolfcrypt/wc_port.h>
+#include <wolfssl/ssl.h>
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+#include <wolfssl/wolfcrypt/hmac.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+#ifdef HAVE_NTRU
+    #include "libntruencrypt/ntru_crypto.h"
+    #include <wolfssl/wolfcrypt/random.h>
+#endif
+#ifdef HAVE_QSH
+    static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key);
+    static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name);
+    static int TLSX_CreateNtruKey(WOLFSSL* ssl, int type);
+#endif
+
+
+#ifndef NO_TLS
+
+
+#ifdef min
+#define WOLFSSL_HAVE_MIN
+#endif
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+
+#endif /* WOLFSSL_HAVE_MIN */
+
+
+#ifdef WOLFSSL_SHA384
+    #define P_HASH_MAX_SIZE SHA384_DIGEST_SIZE
+#else
+    #define P_HASH_MAX_SIZE SHA256_DIGEST_SIZE
+#endif
+
+/* compute p_hash for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1 PRF */
+static int p_hash(byte* result, word32 resLen, const byte* secret,
+                   word32 secLen, const byte* seed, word32 seedLen, int hash)
+{
+    word32 len = P_HASH_MAX_SIZE;
+    word32 times;
+    word32 lastLen;
+    word32 lastTime;
+    word32 i;
+    word32 idx = 0;
+    int    ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  previous;
+    byte*  current;
+    Hmac*  hmac;
+#else
+    byte   previous[P_HASH_MAX_SIZE];  /* max size */
+    byte   current[P_HASH_MAX_SIZE];   /* max size */
+    Hmac   hmac[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    previous = (byte*)XMALLOC(P_HASH_MAX_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    current  = (byte*)XMALLOC(P_HASH_MAX_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    hmac     = (Hmac*)XMALLOC(sizeof(Hmac),    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (previous == NULL || current == NULL || hmac == NULL) {
+        if (previous) XFREE(previous, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (current)  XFREE(current,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (hmac)     XFREE(hmac,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        return MEMORY_E;
+    }
+#endif
+
+    switch (hash) {
+        #ifndef NO_MD5
+            case md5_mac:
+                hash = MD5;
+                len  = MD5_DIGEST_SIZE;
+            break;
+        #endif
+
+        #ifndef NO_SHA256
+            case sha256_mac:
+                hash = SHA256;
+                len  = SHA256_DIGEST_SIZE;
+            break;
+        #endif
+
+        #ifdef WOLFSSL_SHA384
+            case sha384_mac:
+                hash = SHA384;
+                len  = SHA384_DIGEST_SIZE;
+            break;
+        #endif
+
+        #ifndef NO_SHA
+            case sha_mac:
+            default:
+                hash = SHA;
+                len  = SHA_DIGEST_SIZE;
+            break;
+        #endif
+    }
+
+    times   = resLen / len;
+    lastLen = resLen % len;
+
+    if (lastLen)
+        times += 1;
+
+    lastTime = times - 1;
+
+    if ((ret = wc_HmacSetKey(hmac, hash, secret, secLen)) == 0) {
+        if ((ret = wc_HmacUpdate(hmac, seed, seedLen)) == 0) { /* A0 = seed */
+            if ((ret = wc_HmacFinal(hmac, previous)) == 0) {   /* A1 */
+                for (i = 0; i < times; i++) {
+                    ret = wc_HmacUpdate(hmac, previous, len);
+                    if (ret != 0)
+                        break;
+                    ret = wc_HmacUpdate(hmac, seed, seedLen);
+                    if (ret != 0)
+                        break;
+                    ret = wc_HmacFinal(hmac, current);
+                    if (ret != 0)
+                        break;
+
+                    if ((i == lastTime) && lastLen)
+                        XMEMCPY(&result[idx], current,
+                                                 min(lastLen, P_HASH_MAX_SIZE));
+                    else {
+                        XMEMCPY(&result[idx], current, len);
+                        idx += len;
+                        ret = wc_HmacUpdate(hmac, previous, len);
+                        if (ret != 0)
+                            break;
+                        ret = wc_HmacFinal(hmac, previous);
+                        if (ret != 0)
+                            break;
+                    }
+                }
+            }
+        }
+    }
+
+    ForceZero(previous,  P_HASH_MAX_SIZE);
+    ForceZero(current,   P_HASH_MAX_SIZE);
+    ForceZero(hmac,      sizeof(Hmac));
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(previous, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(current,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(hmac,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+#undef P_HASH_MAX_SIZE
+
+
+#ifndef NO_OLD_TLS
+
+/* calculate XOR for TLSv1 PRF */
+static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha)
+{
+    word32 i;
+
+    for (i = 0; i < digLen; i++)
+        digest[i] = md5[i] ^ sha[i];
+}
+
+
+/* compute TLSv1 PRF (pseudo random function using HMAC) */
+static int doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen,
+                 const byte* label, word32 labLen, const byte* seed,
+                 word32 seedLen)
+{
+    int    ret  = 0;
+    word32 half = (secLen + 1) / 2;
+
+#ifdef WOLFSSL_SMALL_STACK
+    byte* md5_half;
+    byte* sha_half;
+    byte* labelSeed;
+    byte* md5_result;
+    byte* sha_result;
+#else
+    byte  md5_half[MAX_PRF_HALF];     /* half is real size */
+    byte  sha_half[MAX_PRF_HALF];     /* half is real size */
+    byte  labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */
+    byte  md5_result[MAX_PRF_DIG];    /* digLen is real size */
+    byte  sha_result[MAX_PRF_DIG];    /* digLen is real size */
+#endif
+
+    if (half > MAX_PRF_HALF)
+        return BUFFER_E;
+    if (labLen + seedLen > MAX_PRF_LABSEED)
+        return BUFFER_E;
+    if (digLen > MAX_PRF_DIG)
+        return BUFFER_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+    md5_half   = (byte*)XMALLOC(MAX_PRF_HALF,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    sha_half   = (byte*)XMALLOC(MAX_PRF_HALF,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    labelSeed  = (byte*)XMALLOC(MAX_PRF_LABSEED, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    md5_result = (byte*)XMALLOC(MAX_PRF_DIG,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    sha_result = (byte*)XMALLOC(MAX_PRF_DIG,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (md5_half == NULL || sha_half == NULL || labelSeed == NULL ||
+                                     md5_result == NULL || sha_result == NULL) {
+        if (md5_half)   XFREE(md5_half,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (sha_half)   XFREE(sha_half,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (labelSeed)  XFREE(labelSeed,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (md5_result) XFREE(md5_result, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (sha_result) XFREE(sha_result, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        return MEMORY_E;
+    }
+#endif
+
+    XMEMSET(md5_result, 0, digLen);
+    XMEMSET(sha_result, 0, digLen);
+
+    XMEMCPY(md5_half, secret, half);
+    XMEMCPY(sha_half, secret + half - secLen % 2, half);
+
+    XMEMCPY(labelSeed, label, labLen);
+    XMEMCPY(labelSeed + labLen, seed, seedLen);
+
+    if ((ret = p_hash(md5_result, digLen, md5_half, half, labelSeed,
+                                             labLen + seedLen, md5_mac)) == 0) {
+        if ((ret = p_hash(sha_result, digLen, sha_half, half, labelSeed,
+                                             labLen + seedLen, sha_mac)) == 0) {
+            get_xor(digest, digLen, md5_result, sha_result);
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(md5_half,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(sha_half,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(labelSeed,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(md5_result, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(sha_result, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+#endif
+
+
+/* Wrapper to call straight thru to p_hash in TSL 1.2 cases to remove stack
+   use */
+static int PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
+            const byte* label, word32 labLen, const byte* seed, word32 seedLen,
+            int useAtLeastSha256, int hash_type)
+{
+    int ret = 0;
+
+    if (useAtLeastSha256) {
+#ifdef WOLFSSL_SMALL_STACK
+        byte* labelSeed;
+#else
+        byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */
+#endif
+
+        if (labLen + seedLen > MAX_PRF_LABSEED)
+            return BUFFER_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+        labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+        if (labelSeed == NULL)
+           return MEMORY_E;
+#endif
+
+        XMEMCPY(labelSeed, label, labLen);
+        XMEMCPY(labelSeed + labLen, seed, seedLen);
+
+        /* If a cipher suite wants an algorithm better than sha256, it
+         * should use better. */
+        if (hash_type < sha256_mac || hash_type == blake2b_mac)
+            hash_type = sha256_mac;
+        ret = p_hash(digest, digLen, secret, secLen, labelSeed,
+                     labLen + seedLen, hash_type);
+
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(labelSeed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+    }
+#ifndef NO_OLD_TLS
+    else {
+        ret = doPRF(digest, digLen, secret, secLen, label, labLen, seed,
+                    seedLen);
+    }
+#endif
+
+    return ret;
+}
+
+
+#ifdef WOLFSSL_SHA384
+    #define HSHASH_SZ SHA384_DIGEST_SIZE
+#else
+    #define HSHASH_SZ FINISHED_SZ
+#endif
+
+
+int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
+{
+    const byte* side;
+    byte        handshake_hash[HSHASH_SZ];
+    word32      hashSz = FINISHED_SZ;
+
+#ifndef NO_OLD_TLS
+    wc_Md5GetHash(&ssl->hsHashes->hashMd5, handshake_hash);
+    wc_ShaGetHash(&ssl->hsHashes->hashSha, &handshake_hash[MD5_DIGEST_SIZE]);
+#endif
+
+    if (IsAtLeastTLSv1_2(ssl)) {
+#ifndef NO_SHA256
+        if (ssl->specs.mac_algorithm <= sha256_mac || ssl->specs.mac_algorithm == blake2b_mac) {
+            int ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256,handshake_hash);
+
+            if (ret != 0)
+                return ret;
+
+            hashSz = SHA256_DIGEST_SIZE;
+        }
+#endif
+#ifdef WOLFSSL_SHA384
+        if (ssl->specs.mac_algorithm == sha384_mac) {
+            int ret = wc_Sha384Final(&ssl->hsHashes->hashSha384,handshake_hash);
+
+            if (ret != 0)
+                return ret;
+
+            hashSz = SHA384_DIGEST_SIZE;
+        }
+#endif
+    }
+
+    if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0)
+        side = tls_client;
+    else
+        side = tls_server;
+
+    return PRF((byte*)hashes, TLS_FINISHED_SZ, ssl->arrays->masterSecret,
+               SECRET_LEN, side, FINISHED_LABEL_SZ, handshake_hash, hashSz,
+               IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
+}
+
+
+#ifndef NO_OLD_TLS
+
+ProtocolVersion MakeTLSv1(void)
+{
+    ProtocolVersion pv;
+    pv.major = SSLv3_MAJOR;
+    pv.minor = TLSv1_MINOR;
+
+    return pv;
+}
+
+
+ProtocolVersion MakeTLSv1_1(void)
+{
+    ProtocolVersion pv;
+    pv.major = SSLv3_MAJOR;
+    pv.minor = TLSv1_1_MINOR;
+
+    return pv;
+}
+
+#endif
+
+
+ProtocolVersion MakeTLSv1_2(void)
+{
+    ProtocolVersion pv;
+    pv.major = SSLv3_MAJOR;
+    pv.minor = TLSv1_2_MINOR;
+
+    return pv;
+}
+
+
+static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret";
+static const byte key_label   [KEY_LABEL_SZ + 1]    = "key expansion";
+
+
+/* External facing wrapper so user can call as well, 0 on success */
+int wolfSSL_DeriveTlsKeys(byte* key_data, word32 keyLen,
+                         const byte* ms, word32 msLen,
+                         const byte* sr, const byte* cr,
+                         int tls1_2, int hash_type)
+{
+    byte  seed[SEED_LEN];
+
+    XMEMCPY(seed,           sr, RAN_LEN);
+    XMEMCPY(seed + RAN_LEN, cr, RAN_LEN);
+
+    return PRF(key_data, keyLen, ms, msLen, key_label, KEY_LABEL_SZ,
+               seed, SEED_LEN, tls1_2, hash_type);
+}
+
+
+int DeriveTlsKeys(WOLFSSL* ssl)
+{
+    int   ret;
+    int   length = 2 * ssl->specs.hash_size +
+                   2 * ssl->specs.key_size  +
+                   2 * ssl->specs.iv_size;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* key_data;
+#else
+    byte  key_data[MAX_PRF_DIG];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    key_data = (byte*)XMALLOC(MAX_PRF_DIG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (key_data == NULL) {
+        return MEMORY_E;
+    }
+#endif
+
+    ret = wolfSSL_DeriveTlsKeys(key_data, length,
+                           ssl->arrays->masterSecret, SECRET_LEN,
+                           ssl->arrays->serverRandom, ssl->arrays->clientRandom,
+                           IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
+    if (ret == 0)
+        ret = StoreKeys(ssl, key_data);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(key_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+/* External facing wrapper so user can call as well, 0 on success */
+int wolfSSL_MakeTlsMasterSecret(byte* ms, word32 msLen,
+                               const byte* pms, word32 pmsLen,
+                               const byte* cr, const byte* sr,
+                               int tls1_2, int hash_type)
+{
+    byte  seed[SEED_LEN];
+
+    XMEMCPY(seed,           cr, RAN_LEN);
+    XMEMCPY(seed + RAN_LEN, sr, RAN_LEN);
+
+    return PRF(ms, msLen, pms, pmsLen, master_label, MASTER_LABEL_SZ,
+               seed, SEED_LEN, tls1_2, hash_type);
+}
+
+
+int MakeTlsMasterSecret(WOLFSSL* ssl)
+{
+    int   ret;
+
+    ret = wolfSSL_MakeTlsMasterSecret(ssl->arrays->masterSecret, SECRET_LEN,
+              ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
+              ssl->arrays->clientRandom, ssl->arrays->serverRandom,
+              IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
+
+    if (ret == 0) {
+    #ifdef SHOW_SECRETS
+        int i;
+
+        printf("master secret: ");
+        for (i = 0; i < SECRET_LEN; i++)
+            printf("%02x", ssl->arrays->masterSecret[i]);
+        printf("\n");
+    #endif
+
+        ret = DeriveTlsKeys(ssl);
+    }
+
+    return ret;
+}
+
+
+/* Used by EAP-TLS and EAP-TTLS to derive keying material from
+ * the master_secret. */
+int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* msk, unsigned int len,
+                                                              const char* label)
+{
+    int   ret;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* seed;
+#else
+    byte  seed[SEED_LEN];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    seed = (byte*)XMALLOC(SEED_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (seed == NULL)
+        return MEMORY_E;
+#endif
+
+    /*
+     * As per RFC-5281, the order of the client and server randoms is reversed
+     * from that used by the TLS protocol to derive keys.
+     */
+    XMEMCPY(seed,           ssl->arrays->clientRandom, RAN_LEN);
+    XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
+
+    ret = PRF((byte*)msk, len, ssl->arrays->masterSecret, SECRET_LEN,
+              (const byte *)label, (word32)strlen(label), seed, SEED_LEN,
+              IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+/*** next for static INLINE s copied internal.c ***/
+
+/* convert 16 bit integer to opaque */
+static INLINE void c16toa(word16 u16, byte* c)
+{
+    c[0] = (u16 >> 8) & 0xff;
+    c[1] =  u16 & 0xff;
+}
+
+#ifdef HAVE_TLS_EXTENSIONS
+/* convert opaque to 16 bit integer */
+static INLINE void ato16(const byte* c, word16* u16)
+{
+    *u16 = (c[0] << 8) | (c[1]);
+}
+
+#if defined(HAVE_SNI) && !defined(NO_WOLFSSL_SERVER)
+/* convert a 24 bit integer into a 32 bit one */
+static INLINE void c24to32(const word24 u24, word32* u32)
+{
+    *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
+}
+#endif
+#endif
+
+/* convert 32 bit integer to opaque */
+static INLINE void c32toa(word32 u32, byte* c)
+{
+    c[0] = (u32 >> 24) & 0xff;
+    c[1] = (u32 >> 16) & 0xff;
+    c[2] = (u32 >>  8) & 0xff;
+    c[3] =  u32 & 0xff;
+}
+
+
+static INLINE word32 GetSEQIncrement(WOLFSSL* ssl, int verify)
+{
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls) {
+        if (verify)
+            return ssl->keys.dtls_state.curSeq; /* explicit from peer */
+        else
+            return ssl->keys.dtls_sequence_number - 1; /* already incremented */
+    }
+#endif
+    if (verify)
+        return ssl->keys.peer_sequence_number++;
+    else
+        return ssl->keys.sequence_number++;
+}
+
+
+#ifdef WOLFSSL_DTLS
+
+static INLINE word32 GetEpoch(WOLFSSL* ssl, int verify)
+{
+    if (verify)
+        return ssl->keys.dtls_state.curEpoch;
+    else
+        return ssl->keys.dtls_epoch;
+}
+
+#endif /* WOLFSSL_DTLS */
+
+
+/*** end copy ***/
+
+
+/* return HMAC digest type in wolfSSL format */
+int wolfSSL_GetHmacType(WOLFSSL* ssl)
+{
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (ssl->specs.mac_algorithm) {
+        #ifndef NO_MD5
+        case md5_mac:
+        {
+            return MD5;
+        }
+        #endif
+        #ifndef NO_SHA256
+        case sha256_mac:
+        {
+            return SHA256;
+        }
+        #endif
+        #ifdef WOLFSSL_SHA384
+        case sha384_mac:
+        {
+            return SHA384;
+        }
+
+        #endif
+        #ifndef NO_SHA
+        case sha_mac:
+        {
+            return SHA;
+        }
+        #endif
+        #ifdef HAVE_BLAKE2
+        case blake2b_mac:
+        {
+            return BLAKE2B_ID;
+        }
+        #endif
+        default:
+        {
+            return SSL_FATAL_ERROR;
+        }
+    }
+}
+
+
+int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content,
+                           int verify)
+{
+    if (ssl == NULL || inner == NULL)
+        return BAD_FUNC_ARG;
+
+    XMEMSET(inner, 0, WOLFSSL_TLS_HMAC_INNER_SZ);
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls)
+        c16toa((word16)GetEpoch(ssl, verify), inner);
+#endif
+    c32toa(GetSEQIncrement(ssl, verify), &inner[sizeof(word32)]);
+    inner[SEQ_SZ] = (byte)content;
+    inner[SEQ_SZ + ENUM_LEN]            = ssl->version.major;
+    inner[SEQ_SZ + ENUM_LEN + ENUM_LEN] = ssl->version.minor;
+    c16toa((word16)sz, inner + SEQ_SZ + ENUM_LEN + VERSION_SZ);
+
+    return 0;
+}
+
+
+/* TLS type HMAC */
+int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
+              int content, int verify)
+{
+    Hmac hmac;
+    int  ret;
+    byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+#ifdef HAVE_FUZZER
+    if (ssl->fuzzerCb)
+        ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
+#endif
+
+    wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify);
+
+    ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
+                     wolfSSL_GetMacSecret(ssl, verify), ssl->specs.hash_size);
+    if (ret != 0)
+        return ret;
+    ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
+    if (ret != 0)
+        return ret;
+    ret = wc_HmacUpdate(&hmac, in, sz);                                /* content */
+    if (ret != 0)
+        return ret;
+    ret = wc_HmacFinal(&hmac, digest);
+    if (ret != 0)
+        return ret;
+
+    return 0;
+}
+
+#ifdef HAVE_TLS_EXTENSIONS
+
+/**
+ * The TLSX semaphore is used to calculate the size of the extensions to be sent
+ * from one peer to another.
+ */
+
+/** Supports up to 64 flags. Increase as needed. */
+#define SEMAPHORE_SIZE 8
+
+/**
+ * Converts the extension type (id) to an index in the semaphore.
+ *
+ * Oficial reference for TLS extension types:
+ *   http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xml
+ *
+ * Motivation:
+ *   Previously, we used the extension type itself as the index of that
+ *   extension in the semaphore as the extension types were declared
+ *   sequentially, but maintain a semaphore as big as the number of available
+ *   extensions is no longer an option since the release of renegotiation_info.
+ *
+ * How to update:
+ *   Assign extension types that extrapolate the number of available semaphores
+ *   to the first available index going backwards in the semaphore array.
+ *   When adding a new extension type that don't extrapolate the number of
+ *   available semaphores, check for a possible collision with with a
+ *   'remapped' extension type.
+ */
+static INLINE word16 TLSX_ToSemaphore(word16 type)
+{
+    switch (type) {
+
+        case SECURE_RENEGOTIATION: /* 0xFF01 */
+            return 63;
+
+        default:
+            if (type > 62) {
+                /* This message SHOULD only happens during the adding of
+                   new TLS extensions in which its IANA number overflows
+                   the current semaphore's range, or if its number already
+                   is assigned to be used by another extension.
+                   Use this check value for the new extension and decrement
+                   the check value by one. */
+                WOLFSSL_MSG("### TLSX semaphore colision or overflow detected!");
+            }
+    }
+
+    return type;
+}
+
+/** Checks if a specific light (tls extension) is not set in the semaphore. */
+#define IS_OFF(semaphore, light) \
+    ((semaphore)[(light) / 8] ^  (byte) (0x01 << ((light) % 8)))
+
+/** Turn on a specific light (tls extension) in the semaphore. */
+#define TURN_ON(semaphore, light) \
+    ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8)))
+
+/** Creates a new extension. */
+static TLSX* TLSX_New(TLSX_Type type, void* data)
+{
+    TLSX* extension = (TLSX*)XMALLOC(sizeof(TLSX), 0, DYNAMIC_TYPE_TLSX);
+
+    if (extension) {
+        extension->type = type;
+        extension->data = data;
+        extension->resp = 0;
+        extension->next = NULL;
+    }
+
+    return extension;
+}
+
+/**
+ * Creates a new extension and pushes it to the provided list.
+ * Checks for duplicate extensions, keeps the newest.
+ */
+static int TLSX_Push(TLSX** list, TLSX_Type type, void* data)
+{
+    TLSX* extension = TLSX_New(type, data);
+
+    if (extension == NULL)
+        return MEMORY_E;
+
+    /* pushes the new extension on the list. */
+    extension->next = *list;
+    *list = extension;
+
+    /* remove duplicate extensions, there should be only one of each type. */
+    do {
+        if (extension->next && extension->next->type == type) {
+            TLSX *next = extension->next;
+
+            extension->next = next->next;
+            next->next = NULL;
+
+            TLSX_FreeAll(next);
+
+            /* there is no way to occur more than */
+            /* two extensions of the same type.   */
+            break;
+        }
+    } while ((extension = extension->next));
+
+    return 0;
+}
+
+#ifndef NO_WOLFSSL_SERVER
+
+/** Mark an extension to be sent back to the client. */
+void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type);
+
+void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type)
+{
+    TLSX *ext = TLSX_Find(ssl->extensions, type);
+
+    if (ext)
+        ext->resp = 1;
+}
+
+#endif
+
+
+#ifdef HAVE_ALPN
+/** Creates a new ALPN object, providing protocol name to use. */
+static ALPN* TLSX_ALPN_New(char *protocol_name, word16 protocol_nameSz)
+{
+    ALPN *alpn;
+
+    WOLFSSL_ENTER("TLSX_ALPN_New");
+
+    if (protocol_name == NULL ||
+        protocol_nameSz > WOLFSSL_MAX_ALPN_PROTO_NAME_LEN) {
+        WOLFSSL_MSG("Invalid arguments");
+        return NULL;
+    }
+
+    alpn = (ALPN*)XMALLOC(sizeof(ALPN), 0, DYNAMIC_TYPE_TLSX);
+    if (alpn == NULL) {
+        WOLFSSL_MSG("Memory failure");
+        return NULL;
+    }
+
+    alpn->next = NULL;
+    alpn->negociated = 0;
+    alpn->options = 0;
+
+    alpn->protocol_name = XMALLOC(protocol_nameSz + 1, 0, DYNAMIC_TYPE_TLSX);
+    if (alpn->protocol_name == NULL) {
+        WOLFSSL_MSG("Memory failure");
+        XFREE(alpn, 0, DYNAMIC_TYPE_TLSX);
+        return NULL;
+    }
+
+    XMEMCPY(alpn->protocol_name, protocol_name, protocol_nameSz);
+    alpn->protocol_name[protocol_nameSz] = 0;
+
+    return alpn;
+}
+
+/** Releases an ALPN object. */
+static void TLSX_ALPN_Free(ALPN *alpn)
+{
+    if (alpn == NULL)
+        return;
+
+    XFREE(alpn->protocol_name, 0, DYNAMIC_TYPE_TLSX);
+    XFREE(alpn, 0, DYNAMIC_TYPE_TLSX);
+}
+
+/** Releases all ALPN objects in the provided list. */
+static void TLSX_ALPN_FreeAll(ALPN *list)
+{
+    ALPN* alpn;
+
+    while ((alpn = list)) {
+        list = alpn->next;
+        TLSX_ALPN_Free(alpn);
+    }
+}
+
+/** Tells the buffered size of the ALPN objects in a list. */
+static word16 TLSX_ALPN_GetSize(ALPN *list)
+{
+    ALPN* alpn;
+    word16 length = OPAQUE16_LEN; /* list length */
+
+    while ((alpn = list)) {
+        list = alpn->next;
+
+        length++; /* protocol name length is on one byte */
+        length += (word16)XSTRLEN(alpn->protocol_name);
+    }
+    
+    return length;
+}
+
+/** Writes the ALPN objects of a list in a buffer. */
+static word16 TLSX_ALPN_Write(ALPN *list, byte *output)
+{
+    ALPN* alpn;
+    word16 length = 0;
+    word16 offset = OPAQUE16_LEN; /* list length offset */
+
+    while ((alpn = list)) {
+        list = alpn->next;
+
+        length = (word16)XSTRLEN(alpn->protocol_name);
+
+        /* protocol name length */
+        output[offset++] = (byte)length;
+
+        /* protocol name value */
+        XMEMCPY(output + offset, alpn->protocol_name, length);
+
+        offset += length;
+    }
+
+    /* writing list length */
+    c16toa(offset - OPAQUE16_LEN, output);
+    
+    return offset;
+}
+
+/** Finds a protocol name in the provided ALPN list */
+static ALPN* TLSX_ALPN_Find(ALPN *list, char *protocol_name, word16 size)
+{
+    ALPN *alpn;
+
+    if (list == NULL || protocol_name == NULL)
+        return NULL;
+
+    alpn = list;
+    while (alpn != NULL && (
+           (word16)XSTRLEN(alpn->protocol_name) != size ||
+           XSTRNCMP(alpn->protocol_name, protocol_name, size)))
+        alpn = alpn->next;
+
+    return alpn;
+}
+
+/** Set the ALPN matching client and server requirements */
+static int TLSX_SetALPN(TLSX** extensions, const void* data, word16 size)
+{
+    ALPN *alpn;
+    int  ret;
+
+    if (extensions == NULL || data == NULL)
+        return BAD_FUNC_ARG;
+
+    alpn = TLSX_ALPN_New((char *)data, size);
+    if (alpn == NULL) {
+        WOLFSSL_MSG("Memory failure");
+        return MEMORY_E;
+    }
+
+    alpn->negociated = 1;
+
+    ret = TLSX_Push(extensions, WOLFSSL_ALPN, (void*)alpn);
+    if (ret != 0) {
+        TLSX_ALPN_Free(alpn);
+        return ret;
+    }
+
+    return SSL_SUCCESS;
+}
+
+/** Parses a buffer of ALPN extensions and set the first one matching
+ * client and server requirements */
+static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length,
+                                 byte isRequest)
+{
+    word16  size = 0, offset = 0, idx = 0;
+    int     r = BUFFER_ERROR;
+    byte    match = 0;
+    TLSX    *extension;
+    ALPN    *alpn = NULL, *list;
+
+    extension = TLSX_Find(ssl->extensions, WOLFSSL_ALPN);
+    if (extension == NULL)
+        extension = TLSX_Find(ssl->ctx->extensions, WOLFSSL_ALPN);
+
+    if (extension == NULL || extension->data == NULL) {
+        WOLFSSL_MSG("No ALPN extensions not used or bad");
+        return isRequest ? 0             /* not using ALPN */
+                         : BUFFER_ERROR; /* unexpected ALPN response */
+    }
+
+    if (OPAQUE16_LEN > length)
+        return BUFFER_ERROR;
+
+    ato16(input, &size);
+    offset += OPAQUE16_LEN;
+
+    /* validating alpn list length */
+    if (length != OPAQUE16_LEN + size)
+        return BUFFER_ERROR;
+
+    list = (ALPN*)extension->data;
+
+    /* keep the list sent by client */
+    if (isRequest) {
+        if (ssl->alpn_client_list != NULL)
+            XFREE(ssl->alpn_client_list, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        ssl->alpn_client_list = (char *)XMALLOC(size, NULL,
+                                                DYNAMIC_TYPE_TMP_BUFFER);
+        if (ssl->alpn_client_list == NULL)
+            return MEMORY_ERROR;
+    }
+
+    for (size = 0; offset < length; offset += size) {
+
+        size = input[offset++];
+        if (offset + size > length)
+            return BUFFER_ERROR;
+
+        if (isRequest) {
+            XMEMCPY(ssl->alpn_client_list+idx, (char*)input + offset, size);
+            idx += size;
+            ssl->alpn_client_list[idx++] = ',';
+        }
+
+        if (!match) {
+            alpn = TLSX_ALPN_Find(list, (char*)input + offset, size);
+            if (alpn != NULL) {
+                WOLFSSL_MSG("ALPN protocol match");
+                match = 1;
+
+                /* skip reading other values if not required */
+                if (!isRequest)
+                    break;
+            }
+        }
+    }
+
+    if (isRequest)
+        ssl->alpn_client_list[idx-1] = 0;
+
+    if (!match) {
+        WOLFSSL_MSG("No ALPN protocol match");
+
+        /* do nothing if no protocol match between client and server and option
+         is set to continue (like OpenSSL) */
+        if (list->options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) {
+            WOLFSSL_MSG("Continue on mismatch");
+            return 0;
+        }
+
+        SendAlert(ssl, alert_fatal, no_application_protocol);
+        return UNKNOWN_ALPN_PROTOCOL_NAME_E;
+    }
+
+    /* set the matching negociated protocol */
+    r = TLSX_SetALPN(&ssl->extensions,
+                     alpn->protocol_name,
+                     (word16)XSTRLEN(alpn->protocol_name));
+    if (r != SSL_SUCCESS) {
+        WOLFSSL_MSG("TLSX_UseALPN failed");
+        return BUFFER_ERROR;
+    }
+
+    /* reply to ALPN extension sent from client */
+    if (isRequest) {
+#ifndef NO_WOLFSSL_SERVER
+        TLSX_SetResponse(ssl, WOLFSSL_ALPN);
+#endif
+    }
+
+    return 0;
+}
+
+/** Add a protocol name to the list of accepted usable ones */
+int TLSX_UseALPN(TLSX** extensions, const void* data, word16 size, byte options)
+{
+    ALPN *alpn;
+    TLSX *extension;
+    int  ret;
+
+    if (extensions == NULL || data == NULL)
+        return BAD_FUNC_ARG;
+
+    alpn = TLSX_ALPN_New((char *)data, size);
+    if (alpn == NULL) {
+        WOLFSSL_MSG("Memory failure");
+        return MEMORY_E;
+    }
+
+    /* Set Options of ALPN */
+    alpn->options = options;
+
+    extension = TLSX_Find(*extensions, WOLFSSL_ALPN);
+    if (extension == NULL) {
+        ret = TLSX_Push(extensions, WOLFSSL_ALPN, (void*)alpn);
+        if (ret != 0) {
+            TLSX_ALPN_Free(alpn);
+            return ret;
+        }
+    }
+    else {
+        /* push new ALPN object to extension data. */
+        alpn->next = (ALPN*)extension->data;
+        extension->data = (void*)alpn;
+    }
+
+    return SSL_SUCCESS;
+}
+
+/** Get the protocol name set by the server */
+int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz)
+{
+    TLSX *extension;
+    ALPN *alpn;
+
+    if (extensions == NULL || data == NULL || dataSz == NULL)
+        return BAD_FUNC_ARG;
+
+    extension = TLSX_Find(extensions, WOLFSSL_ALPN);
+    if (extension == NULL) {
+        WOLFSSL_MSG("TLS extension not found");
+        return SSL_ALPN_NOT_FOUND;
+    }
+
+    alpn = (ALPN *)extension->data;
+    if (alpn == NULL) {
+        WOLFSSL_MSG("ALPN extension not found");
+        *data = NULL;
+        *dataSz = 0;
+        return SSL_FATAL_ERROR;
+    }
+
+    if (alpn->negociated != 1) {
+
+        /* consider as an error */
+        if (alpn->options & WOLFSSL_ALPN_FAILED_ON_MISMATCH) {
+            WOLFSSL_MSG("No protocol match with peer -> Failed");
+            return SSL_FATAL_ERROR;
+        }
+
+        /* continue without negociated protocol */
+        WOLFSSL_MSG("No protocol match with peer -> Continue");
+        return SSL_ALPN_NOT_FOUND;
+    }
+
+    if (alpn->next != NULL) {
+        WOLFSSL_MSG("Only one protocol name must be accepted");
+        return SSL_FATAL_ERROR;
+    }
+
+    *data = alpn->protocol_name;
+    *dataSz = (word16)XSTRLEN(*data);
+
+    return SSL_SUCCESS;
+}
+
+#define ALPN_FREE_ALL     TLSX_ALPN_FreeAll
+#define ALPN_GET_SIZE     TLSX_ALPN_GetSize
+#define ALPN_WRITE        TLSX_ALPN_Write
+#define ALPN_PARSE        TLSX_ALPN_ParseAndSet
+
+#else /* HAVE_ALPN */
+
+#define ALPN_FREE_ALL(list)
+#define ALPN_GET_SIZE(list)     0
+#define ALPN_WRITE(a, b)        0
+#define ALPN_PARSE(a, b, c, d)  0
+
+#endif /* HAVE_ALPN */
+
+/* Server Name Indication */
+#ifdef HAVE_SNI
+
+/** Creates a new SNI object. */
+static SNI* TLSX_SNI_New(byte type, const void* data, word16 size)
+{
+    SNI* sni = (SNI*)XMALLOC(sizeof(SNI), 0, DYNAMIC_TYPE_TLSX);
+
+    if (sni) {
+        sni->type = type;
+        sni->next = NULL;
+
+    #ifndef NO_WOLFSSL_SERVER
+        sni->options = 0;
+        sni->status  = WOLFSSL_SNI_NO_MATCH;
+    #endif
+
+        switch (sni->type) {
+            case WOLFSSL_SNI_HOST_NAME:
+                sni->data.host_name = XMALLOC(size + 1, 0, DYNAMIC_TYPE_TLSX);
+
+                if (sni->data.host_name) {
+                    XSTRNCPY(sni->data.host_name, (const char*)data, size);
+                    sni->data.host_name[size] = 0;
+                } else {
+                    XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
+                    sni = NULL;
+                }
+            break;
+
+            default: /* invalid type */
+                XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
+                sni = NULL;
+        }
+    }
+
+    return sni;
+}
+
+/** Releases a SNI object. */
+static void TLSX_SNI_Free(SNI* sni)
+{
+    if (sni) {
+        switch (sni->type) {
+            case WOLFSSL_SNI_HOST_NAME:
+                XFREE(sni->data.host_name, 0, DYNAMIC_TYPE_TLSX);
+            break;
+        }
+
+        XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
+    }
+}
+
+/** Releases all SNI objects in the provided list. */
+static void TLSX_SNI_FreeAll(SNI* list)
+{
+    SNI* sni;
+
+    while ((sni = list)) {
+        list = sni->next;
+        TLSX_SNI_Free(sni);
+    }
+}
+
+/** Tells the buffered size of the SNI objects in a list. */
+static word16 TLSX_SNI_GetSize(SNI* list)
+{
+    SNI* sni;
+    word16 length = OPAQUE16_LEN; /* list length */
+
+    while ((sni = list)) {
+        list = sni->next;
+
+        length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */
+
+        switch (sni->type) {
+            case WOLFSSL_SNI_HOST_NAME:
+                length += XSTRLEN((char*)sni->data.host_name);
+            break;
+        }
+    }
+
+    return length;
+}
+
+/** Writes the SNI objects of a list in a buffer. */
+static word16 TLSX_SNI_Write(SNI* list, byte* output)
+{
+    SNI* sni;
+    word16 length = 0;
+    word16 offset = OPAQUE16_LEN; /* list length offset */
+
+    while ((sni = list)) {
+        list = sni->next;
+
+        output[offset++] = sni->type; /* sni type */
+
+        switch (sni->type) {
+            case WOLFSSL_SNI_HOST_NAME:
+                length = XSTRLEN((char*)sni->data.host_name);
+
+                c16toa(length, output + offset); /* sni length */
+                offset += OPAQUE16_LEN;
+
+                XMEMCPY(output + offset, sni->data.host_name, length);
+
+                offset += length;
+            break;
+        }
+    }
+
+    c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
+
+    return offset;
+}
+
+#ifndef NO_WOLFSSL_SERVER
+
+/** Finds a SNI object in the provided list. */
+static SNI* TLSX_SNI_Find(SNI *list, byte type)
+{
+    SNI *sni = list;
+
+    while (sni && sni->type != type)
+        sni = sni->next;
+
+    return sni;
+}
+
+
+/** Sets the status of a SNI object. */
+static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status)
+{
+    TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
+    SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
+
+    if (sni)
+        sni->status = status;
+}
+
+/** Gets the status of a SNI object. */
+byte TLSX_SNI_Status(TLSX* extensions, byte type)
+{
+    TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
+    SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
+
+    if (sni)
+        return sni->status;
+
+    return 0;
+}
+
+#endif /* NO_WOLFSSL_SERVER */
+
+/** Parses a buffer of SNI extensions. */
+static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+#ifndef NO_WOLFSSL_SERVER
+    word16 size = 0;
+    word16 offset = 0;
+    int cacheOnly = 0;
+#endif
+
+    TLSX *extension = TLSX_Find(ssl->extensions, SERVER_NAME_INDICATION);
+
+    if (!extension)
+        extension = TLSX_Find(ssl->ctx->extensions, SERVER_NAME_INDICATION);
+
+    (void)isRequest;
+    (void)input;
+
+    if (!extension || !extension->data) {
+#if defined(WOLFSSL_ALWAYS_KEEP_SNI) && !defined(NO_WOLFSSL_SERVER)
+        /* This will keep SNI even though TLSX_UseSNI has not been called.
+         * Enable it so that the received sni is available to functions
+         * that use a custom callback when SNI is received */
+        cacheOnly = 1;
+        WOLFSSL_MSG("Forcing SSL object to store SNI parameter");
+#else
+        return isRequest ? 0             /* not using SNI.           */
+                         : BUFFER_ERROR; /* unexpected SNI response. */
+#endif
+    }
+
+    if (!isRequest)
+        return length ? BUFFER_ERROR /* SNI response MUST be empty. */
+                      : 0;           /* nothing else to do.         */
+
+#ifndef NO_WOLFSSL_SERVER
+
+    if (OPAQUE16_LEN > length)
+        return BUFFER_ERROR;
+
+    ato16(input, &size);
+    offset += OPAQUE16_LEN;
+
+    /* validating sni list length */
+    if (length != OPAQUE16_LEN + size)
+        return BUFFER_ERROR;
+
+    for (size = 0; offset < length; offset += size) {
+        SNI *sni = NULL;
+        byte type = input[offset++];
+
+        if (offset + OPAQUE16_LEN > length)
+            return BUFFER_ERROR;
+
+        ato16(input + offset, &size);
+        offset += OPAQUE16_LEN;
+
+        if (offset + size > length)
+            return BUFFER_ERROR;
+
+        if (!cacheOnly && !(sni = TLSX_SNI_Find((SNI*)extension->data, type)))
+            continue; /* not using this type of SNI. */
+
+        switch(type) {
+            case WOLFSSL_SNI_HOST_NAME: {
+                int matchStat;
+                byte matched = cacheOnly ||
+                            ((XSTRLEN(sni->data.host_name) == size)
+                            && (XSTRNCMP(sni->data.host_name,
+                                       (const char*)input + offset, size) == 0));
+
+                if (matched || sni->options & WOLFSSL_SNI_ANSWER_ON_MISMATCH) {
+                    int r = TLSX_UseSNI(&ssl->extensions,
+                                                    type, input + offset, size);
+
+                    if (r != SSL_SUCCESS)
+                        return r; /* throws error. */
+
+                    if(cacheOnly) {
+                        WOLFSSL_MSG("Forcing storage of SNI, Fake match");
+                        matchStat = WOLFSSL_SNI_FORCE_KEEP;
+                    } else if(matched) {
+                        WOLFSSL_MSG("SNI did match!");
+                        matchStat = WOLFSSL_SNI_REAL_MATCH;
+                    } else {
+                        WOLFSSL_MSG("fake SNI match from ANSWER_ON_MISMATCH");
+                        matchStat = WOLFSSL_SNI_FAKE_MATCH;
+                    }
+
+                    TLSX_SNI_SetStatus(ssl->extensions, type, matchStat);
+
+                    if(!cacheOnly)
+                        TLSX_SetResponse(ssl, SERVER_NAME_INDICATION);
+
+                } else if (!(sni->options & WOLFSSL_SNI_CONTINUE_ON_MISMATCH)) {
+                    SendAlert(ssl, alert_fatal, unrecognized_name);
+
+                    return UNKNOWN_SNI_HOST_NAME_E;
+                }
+                break;
+            }
+        }
+    }
+
+#endif
+
+    return 0;
+}
+
+static int TLSX_SNI_VerifyParse(WOLFSSL* ssl,  byte isRequest)
+{
+    (void)ssl;
+
+    if (isRequest) {
+    #ifndef NO_WOLFSSL_SERVER
+        TLSX* ctx_ext = TLSX_Find(ssl->ctx->extensions, SERVER_NAME_INDICATION);
+        TLSX* ssl_ext = TLSX_Find(ssl->extensions,      SERVER_NAME_INDICATION);
+        SNI* ctx_sni = ctx_ext ? ctx_ext->data : NULL;
+        SNI* ssl_sni = ssl_ext ? ssl_ext->data : NULL;
+        SNI* sni = NULL;
+
+        for (; ctx_sni; ctx_sni = ctx_sni->next) {
+            if (ctx_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) {
+                sni = TLSX_SNI_Find(ssl_sni, ctx_sni->type);
+
+                if (sni) {
+                    if (sni->status != WOLFSSL_SNI_NO_MATCH)
+                        continue;
+
+                    /* if ssl level overrides ctx level, it is ok. */
+                    if ((sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) == 0)
+                        continue;
+                }
+
+                SendAlert(ssl, alert_fatal, handshake_failure);
+                return SNI_ABSENT_ERROR;
+            }
+        }
+
+        for (; ssl_sni; ssl_sni = ssl_sni->next) {
+            if (ssl_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) {
+                if (ssl_sni->status != WOLFSSL_SNI_NO_MATCH)
+                    continue;
+
+                SendAlert(ssl, alert_fatal, handshake_failure);
+                return SNI_ABSENT_ERROR;
+            }
+        }
+    #endif /* NO_WOLFSSL_SERVER */
+    }
+
+    return 0;
+}
+
+int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size)
+{
+    TLSX* extension = TLSX_Find(*extensions, SERVER_NAME_INDICATION);
+    SNI*  sni       = NULL;
+
+    if (extensions == NULL || data == NULL)
+        return BAD_FUNC_ARG;
+
+    if ((sni = TLSX_SNI_New(type, data, size)) == NULL)
+        return MEMORY_E;
+
+    if (!extension) {
+        int ret = TLSX_Push(extensions, SERVER_NAME_INDICATION, (void*)sni);
+        if (ret != 0) {
+            TLSX_SNI_Free(sni);
+            return ret;
+        }
+    }
+    else {
+        /* push new SNI object to extension data. */
+        sni->next = (SNI*)extension->data;
+        extension->data = (void*)sni;
+
+        /* remove duplicate SNI, there should be only one of each type. */
+        do {
+            if (sni->next && sni->next->type == type) {
+                SNI *next = sni->next;
+
+                sni->next = next->next;
+                TLSX_SNI_Free(next);
+
+                /* there is no way to occur more than */
+                /* two SNIs of the same type.         */
+                break;
+            }
+        } while ((sni = sni->next));
+    }
+
+    return SSL_SUCCESS;
+}
+
+#ifndef NO_WOLFSSL_SERVER
+
+/** Tells the SNI requested by the client. */
+word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data)
+{
+    TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
+    SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
+
+    if (sni && sni->status != WOLFSSL_SNI_NO_MATCH) {
+        switch (sni->type) {
+            case WOLFSSL_SNI_HOST_NAME:
+                *data = sni->data.host_name;
+                return XSTRLEN(*data);
+        }
+    }
+
+    return 0;
+}
+
+/** Sets the options for a SNI object. */
+void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options)
+{
+    TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
+    SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
+
+    if (sni)
+        sni->options = options;
+}
+
+/** Retrieves a SNI request from a client hello buffer. */
+int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
+                           byte type, byte* sni, word32* inOutSz)
+{
+    word32 offset = 0;
+    word32 len32  = 0;
+    word16 len16  = 0;
+
+    if (helloSz < RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + CLIENT_HELLO_FIRST)
+        return INCOMPLETE_DATA;
+
+    /* TLS record header */
+    if ((enum ContentType) clientHello[offset++] != handshake) {
+
+        /* checking for SSLv2.0 client hello according to: */
+        /* http://tools.ietf.org/html/rfc4346#appendix-E.1 */
+        if ((enum HandShakeType) clientHello[++offset] == client_hello) {
+            offset += ENUM_LEN + VERSION_SZ; /* skip version */
+
+            ato16(clientHello + offset, &len16);
+            offset += OPAQUE16_LEN;
+
+            if (len16 % 3) /* cipher_spec_length must be multiple of 3 */
+                return BUFFER_ERROR;
+
+            ato16(clientHello + offset, &len16);
+            offset += OPAQUE16_LEN;
+
+            if (len16 != 0) /* session_id_length must be 0 */
+                return BUFFER_ERROR;
+
+            return SNI_UNSUPPORTED;
+        }
+
+        return BUFFER_ERROR;
+    }
+
+    if (clientHello[offset++] != SSLv3_MAJOR)
+        return BUFFER_ERROR;
+
+    if (clientHello[offset++] < TLSv1_MINOR)
+        return SNI_UNSUPPORTED;
+
+    ato16(clientHello + offset, &len16);
+    offset += OPAQUE16_LEN;
+
+    if (offset + len16 > helloSz)
+        return INCOMPLETE_DATA;
+
+    /* Handshake header */
+    if ((enum HandShakeType) clientHello[offset] != client_hello)
+        return BUFFER_ERROR;
+
+    c24to32(clientHello + offset + 1, &len32);
+    offset += HANDSHAKE_HEADER_SZ;
+
+    if (offset + len32 > helloSz)
+        return BUFFER_ERROR;
+
+    /* client hello */
+    offset += VERSION_SZ + RAN_LEN; /* version, random */
+
+    if (helloSz < offset + clientHello[offset])
+        return BUFFER_ERROR;
+
+    offset += ENUM_LEN + clientHello[offset]; /* skip session id */
+
+    /* cypher suites */
+    if (helloSz < offset + OPAQUE16_LEN)
+        return BUFFER_ERROR;
+
+    ato16(clientHello + offset, &len16);
+    offset += OPAQUE16_LEN;
+
+    if (helloSz < offset + len16)
+        return BUFFER_ERROR;
+
+    offset += len16; /* skip cypher suites */
+
+    /* compression methods */
+    if (helloSz < offset + 1)
+        return BUFFER_ERROR;
+
+    if (helloSz < offset + clientHello[offset])
+        return BUFFER_ERROR;
+
+    offset += ENUM_LEN + clientHello[offset]; /* skip compression methods */
+
+    /* extensions */
+    if (helloSz < offset + OPAQUE16_LEN)
+        return 0; /* no extensions in client hello. */
+
+    ato16(clientHello + offset, &len16);
+    offset += OPAQUE16_LEN;
+
+    if (helloSz < offset + len16)
+        return BUFFER_ERROR;
+
+    while (len16 >= OPAQUE16_LEN + OPAQUE16_LEN) {
+        word16 extType;
+        word16 extLen;
+
+        ato16(clientHello + offset, &extType);
+        offset += OPAQUE16_LEN;
+
+        ato16(clientHello + offset, &extLen);
+        offset += OPAQUE16_LEN;
+
+        if (helloSz < offset + extLen)
+            return BUFFER_ERROR;
+
+        if (extType != SERVER_NAME_INDICATION) {
+            offset += extLen; /* skip extension */
+        } else {
+            word16 listLen;
+
+            ato16(clientHello + offset, &listLen);
+            offset += OPAQUE16_LEN;
+
+            if (helloSz < offset + listLen)
+                return BUFFER_ERROR;
+
+            while (listLen > ENUM_LEN + OPAQUE16_LEN) {
+                byte   sniType = clientHello[offset++];
+                word16 sniLen;
+
+                ato16(clientHello + offset, &sniLen);
+                offset += OPAQUE16_LEN;
+
+                if (helloSz < offset + sniLen)
+                    return BUFFER_ERROR;
+
+                if (sniType != type) {
+                    offset  += sniLen;
+                    listLen -= min(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen);
+                    continue;
+                }
+
+                *inOutSz = min(sniLen, *inOutSz);
+                XMEMCPY(sni, clientHello + offset, *inOutSz);
+
+                return SSL_SUCCESS;
+            }
+        }
+
+        len16 -= min(2 * OPAQUE16_LEN + extLen, len16);
+    }
+
+    return len16 ? BUFFER_ERROR : 0;
+}
+
+#endif
+
+#define SNI_FREE_ALL     TLSX_SNI_FreeAll
+#define SNI_GET_SIZE     TLSX_SNI_GetSize
+#define SNI_WRITE        TLSX_SNI_Write
+#define SNI_PARSE        TLSX_SNI_Parse
+#define SNI_VERIFY_PARSE TLSX_SNI_VerifyParse
+
+#else
+
+#define SNI_FREE_ALL(list)
+#define SNI_GET_SIZE(list)     0
+#define SNI_WRITE(a, b)        0
+#define SNI_PARSE(a, b, c, d)  0
+#define SNI_VERIFY_PARSE(a, b) 0
+
+#endif /* HAVE_SNI */
+
+#ifdef HAVE_MAX_FRAGMENT
+
+static word16 TLSX_MFL_Write(byte* data, byte* output)
+{
+    output[0] = data[0];
+
+    return ENUM_LEN;
+}
+
+static int TLSX_MFL_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+    (void)isRequest;
+
+    if (length != ENUM_LEN)
+        return BUFFER_ERROR;
+
+    switch (*input) {
+        case WOLFSSL_MFL_2_9 : ssl->max_fragment =  512; break;
+        case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
+        case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
+        case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
+        case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
+
+        default:
+            SendAlert(ssl, alert_fatal, illegal_parameter);
+
+            return UNKNOWN_MAX_FRAG_LEN_E;
+    }
+
+#ifndef NO_WOLFSSL_SERVER
+    if (isRequest) {
+        int r = TLSX_UseMaxFragment(&ssl->extensions, *input);
+
+        if (r != SSL_SUCCESS) return r; /* throw error */
+
+        TLSX_SetResponse(ssl, MAX_FRAGMENT_LENGTH);
+    }
+#endif
+
+    return 0;
+}
+
+int TLSX_UseMaxFragment(TLSX** extensions, byte mfl)
+{
+    byte* data = NULL;
+    int   ret  = 0;
+
+    if (extensions == NULL)
+        return BAD_FUNC_ARG;
+
+    if (mfl < WOLFSSL_MFL_2_9 || WOLFSSL_MFL_2_13 < mfl)
+        return BAD_FUNC_ARG;
+
+    if ((data = XMALLOC(ENUM_LEN, 0, DYNAMIC_TYPE_TLSX)) == NULL)
+        return MEMORY_E;
+
+    data[0] = mfl;
+
+    /* push new MFL extension. */
+    if ((ret = TLSX_Push(extensions, MAX_FRAGMENT_LENGTH, data)) != 0) {
+        XFREE(data, 0, DYNAMIC_TYPE_TLSX);
+        return ret;
+    }
+
+    return SSL_SUCCESS;
+}
+
+
+#define MFL_FREE_ALL(data) XFREE(data, 0, DYNAMIC_TYPE_TLSX)
+#define MFL_GET_SIZE(data) ENUM_LEN
+#define MFL_WRITE          TLSX_MFL_Write
+#define MFL_PARSE          TLSX_MFL_Parse
+
+#else
+
+#define MFL_FREE_ALL(a)
+#define MFL_GET_SIZE(a)       0
+#define MFL_WRITE(a, b)       0
+#define MFL_PARSE(a, b, c, d) 0
+
+#endif /* HAVE_MAX_FRAGMENT */
+
+#ifdef HAVE_TRUNCATED_HMAC
+
+static int TLSX_THM_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+    (void)isRequest;
+
+    if (length != 0 || input == NULL)
+        return BUFFER_ERROR;
+
+#ifndef NO_WOLFSSL_SERVER
+    if (isRequest) {
+        int r = TLSX_UseTruncatedHMAC(&ssl->extensions);
+
+        if (r != SSL_SUCCESS) return r; /* throw error */
+
+        TLSX_SetResponse(ssl, TRUNCATED_HMAC);
+    }
+#endif
+
+    ssl->truncated_hmac = 1;
+
+    return 0;
+}
+
+int TLSX_UseTruncatedHMAC(TLSX** extensions)
+{
+    int ret = 0;
+
+    if (extensions == NULL)
+        return BAD_FUNC_ARG;
+
+    if ((ret = TLSX_Push(extensions, TRUNCATED_HMAC, NULL)) != 0)
+        return ret;
+
+    return SSL_SUCCESS;
+}
+
+#define THM_PARSE TLSX_THM_Parse
+
+#else
+
+#define THM_PARSE(a, b, c, d) 0
+
+#endif /* HAVE_TRUNCATED_HMAC */
+
+#ifdef HAVE_SUPPORTED_CURVES
+
+#ifndef HAVE_ECC
+#error Elliptic Curves Extension requires Elliptic Curve Cryptography. \
+       Use --enable-ecc in the configure script or define HAVE_ECC.
+#endif
+
+static void TLSX_EllipticCurve_FreeAll(EllipticCurve* list)
+{
+    EllipticCurve* curve;
+
+    while ((curve = list)) {
+        list = curve->next;
+        XFREE(curve, 0, DYNAMIC_TYPE_TLSX);
+    }
+}
+
+static int TLSX_EllipticCurve_Append(EllipticCurve** list, word16 name)
+{
+    EllipticCurve* curve;
+
+    if (list == NULL)
+        return BAD_FUNC_ARG;
+
+    if ((curve = XMALLOC(sizeof(EllipticCurve), 0, DYNAMIC_TYPE_TLSX)) == NULL)
+        return MEMORY_E;
+
+    curve->name = name;
+    curve->next = *list;
+
+    *list = curve;
+
+    return 0;
+}
+
+#ifndef NO_WOLFSSL_CLIENT
+
+static void TLSX_EllipticCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
+{
+    int i;
+
+    for (i = 0; i < ssl->suites->suiteSz; i+= 2)
+        if (ssl->suites->suites[i] == ECC_BYTE)
+            return;
+
+    /* turns semaphore on to avoid sending this extension. */
+    TURN_ON(semaphore, TLSX_ToSemaphore(ELLIPTIC_CURVES));
+}
+
+static word16 TLSX_EllipticCurve_GetSize(EllipticCurve* list)
+{
+    EllipticCurve* curve;
+    word16 length = OPAQUE16_LEN; /* list length */
+
+    while ((curve = list)) {
+        list = curve->next;
+        length += OPAQUE16_LEN; /* curve length */
+    }
+
+    return length;
+}
+
+static word16 TLSX_EllipticCurve_WriteR(EllipticCurve* curve, byte* output);
+static word16 TLSX_EllipticCurve_WriteR(EllipticCurve* curve, byte* output)
+{
+    word16 offset = 0;
+
+    if (!curve)
+        return offset;
+
+    offset = TLSX_EllipticCurve_WriteR(curve->next, output);
+    c16toa(curve->name, output + offset);
+
+    return OPAQUE16_LEN + offset;
+}
+
+static word16 TLSX_EllipticCurve_Write(EllipticCurve* list, byte* output)
+{
+    word16 length = TLSX_EllipticCurve_WriteR(list, output + OPAQUE16_LEN);
+
+    c16toa(length, output); /* writing list length */
+
+    return OPAQUE16_LEN + length;
+}
+
+#endif /* NO_WOLFSSL_CLIENT */
+#ifndef NO_WOLFSSL_SERVER
+
+static int TLSX_EllipticCurve_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+    word16 offset;
+    word16 name;
+    int r;
+
+    (void) isRequest; /* shut up compiler! */
+
+    if (OPAQUE16_LEN > length || length % OPAQUE16_LEN)
+        return BUFFER_ERROR;
+
+    ato16(input, &offset);
+
+    /* validating curve list length */
+    if (length != OPAQUE16_LEN + offset)
+        return BUFFER_ERROR;
+
+    while (offset) {
+        ato16(input + offset, &name);
+        offset -= OPAQUE16_LEN;
+
+        r = TLSX_UseSupportedCurve(&ssl->extensions, name);
+
+        if (r != SSL_SUCCESS) return r; /* throw error */
+    }
+
+    return 0;
+}
+
+int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
+    TLSX*          extension = (first == ECC_BYTE)
+                             ? TLSX_Find(ssl->extensions, ELLIPTIC_CURVES)
+                             : NULL;
+    EllipticCurve* curve     = NULL;
+    word32         oid       = 0;
+    word16         octets    = 0; /* acording to 'ecc_set_type ecc_sets[];' */
+    int            sig       = 0; /* valitade signature */
+    int            key       = 0; /* validate key       */
+
+    (void)oid;
+    (void)octets;
+
+    if (!extension)
+        return 1; /* no suite restriction */
+
+    for (curve = extension->data; curve && !(sig && key); curve = curve->next) {
+
+        switch (curve->name) {
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
+            case WOLFSSL_ECC_SECP160R1: oid = ECC_160R1; octets = 20; break;
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
+            case WOLFSSL_ECC_SECP192R1: oid = ECC_192R1; octets = 24; break;
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
+            case WOLFSSL_ECC_SECP224R1: oid = ECC_224R1; octets = 28; break;
+#endif
+#if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
+            case WOLFSSL_ECC_SECP256R1: oid = ECC_256R1; octets = 32; break;
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
+            case WOLFSSL_ECC_SECP384R1: oid = ECC_384R1; octets = 48; break;
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
+            case WOLFSSL_ECC_SECP521R1: oid = ECC_521R1; octets = 66; break;
+#endif
+            default: continue; /* unsupported curve */
+        }
+
+        switch (second) {
+#ifndef NO_DSA
+            /* ECDHE_ECDSA */
+            case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
+            case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
+            case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
+            case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
+            case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+            case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+            case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+            case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+            case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
+            case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
+                sig |= ssl->pkCurveOID == oid;
+                key |= ssl->eccTempKeySz == octets;
+            break;
+
+            /* ECDH_ECDSA */
+            case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
+            case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
+            case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
+            case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
+            case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
+            case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
+            case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
+            case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
+                sig |= ssl->pkCurveOID == oid;
+                key |= ssl->pkCurveOID == oid;
+            break;
+#endif
+#ifndef NO_RSA
+            /* ECDHE_RSA */
+            case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
+            case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
+            case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
+            case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
+            case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+            case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
+            case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+            case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+                sig = 1;
+                key |= ssl->eccTempKeySz == octets;
+            break;
+
+            /* ECDH_RSA */
+            case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
+            case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
+            case TLS_ECDH_RSA_WITH_RC4_128_SHA:
+            case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
+            case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
+            case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
+            case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
+            case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
+                sig = 1;
+                key |= ssl->pkCurveOID == oid;
+            break;
+#endif
+            default:
+                sig = 1;
+                key = 1;
+            break;
+        }
+    }
+
+    return sig && key;
+}
+
+#endif /* NO_WOLFSSL_SERVER */
+
+int TLSX_UseSupportedCurve(TLSX** extensions, word16 name)
+{
+    TLSX*          extension = TLSX_Find(*extensions, ELLIPTIC_CURVES);
+    EllipticCurve* curve     = NULL;
+    int            ret       = 0;
+
+    if (extensions == NULL)
+        return BAD_FUNC_ARG;
+
+    if ((ret = TLSX_EllipticCurve_Append(&curve, name)) != 0)
+        return ret;
+
+    if (!extension) {
+        if ((ret = TLSX_Push(extensions, ELLIPTIC_CURVES, curve)) != 0) {
+            XFREE(curve, 0, DYNAMIC_TYPE_TLSX);
+            return ret;
+        }
+    }
+    else {
+        /* push new EllipticCurve object to extension data. */
+        curve->next = (EllipticCurve*)extension->data;
+        extension->data = (void*)curve;
+
+        /* look for another curve of the same name to remove (replacement) */
+        do {
+            if (curve->next && curve->next->name == name) {
+                EllipticCurve *next = curve->next;
+
+                curve->next = next->next;
+                XFREE(next, 0, DYNAMIC_TYPE_TLSX);
+
+                break;
+            }
+        } while ((curve = curve->next));
+    }
+
+    return SSL_SUCCESS;
+}
+
+#define EC_FREE_ALL         TLSX_EllipticCurve_FreeAll
+#define EC_VALIDATE_REQUEST TLSX_EllipticCurve_ValidateRequest
+
+#ifndef NO_WOLFSSL_CLIENT
+#define EC_GET_SIZE TLSX_EllipticCurve_GetSize
+#define EC_WRITE    TLSX_EllipticCurve_Write
+#else
+#define EC_GET_SIZE(list)         0
+#define EC_WRITE(a, b)            0
+#endif
+
+#ifndef NO_WOLFSSL_SERVER
+#define EC_PARSE TLSX_EllipticCurve_Parse
+#else
+#define EC_PARSE(a, b, c, d)      0
+#endif
+
+#else
+
+#define EC_FREE_ALL(list)
+#define EC_GET_SIZE(list)         0
+#define EC_WRITE(a, b)            0
+#define EC_PARSE(a, b, c, d)      0
+#define EC_VALIDATE_REQUEST(a, b)
+
+#endif /* HAVE_SUPPORTED_CURVES */
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+
+static byte TLSX_SecureRenegotiation_GetSize(SecureRenegotiation* data,
+                                                                  int isRequest)
+{
+    byte length = OPAQUE8_LEN; /* empty info length */
+
+    if (data->enabled) {
+        /* client sends client_verify_data only */
+        length += TLS_FINISHED_SZ;
+
+        /* server also sends server_verify_data */
+        if (!isRequest)
+            length += TLS_FINISHED_SZ;
+    }
+
+    return length;
+}
+
+static word16 TLSX_SecureRenegotiation_Write(SecureRenegotiation* data,
+                                                    byte* output, int isRequest)
+{
+    word16 offset = OPAQUE8_LEN; /* RenegotiationInfo length */
+
+    if (data->enabled) {
+        /* client sends client_verify_data only */
+        XMEMCPY(output + offset, data->client_verify_data, TLS_FINISHED_SZ);
+        offset += TLS_FINISHED_SZ;
+
+        /* server also sends server_verify_data */
+        if (!isRequest) {
+            XMEMCPY(output + offset, data->server_verify_data, TLS_FINISHED_SZ);
+            offset += TLS_FINISHED_SZ;
+        }
+    }
+
+    output[0] = offset - 1;  /* info length - self */
+
+    return offset;
+}
+
+static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, byte* input,
+                                                  word16 length, byte isRequest)
+{
+    int ret = SECURE_RENEGOTIATION_E;
+
+    if (length >= OPAQUE8_LEN) {
+        if (ssl->secure_renegotiation == NULL) {
+        #ifndef NO_WOLFSSL_SERVER
+            if (isRequest && *input == 0) {
+                ret = 0;  /* don't reply, user didn't enable */
+            }
+        #endif
+        }
+        else if (isRequest) {
+        #ifndef NO_WOLFSSL_SERVER
+            if (*input == TLS_FINISHED_SZ) {
+                /* TODO compare client_verify_data */
+                ret = 0;
+            }
+        #endif
+        }
+        else {
+        #ifndef NO_WOLFSSL_CLIENT
+            if (!ssl->secure_renegotiation->enabled) {
+                if (*input == 0) {
+                    ssl->secure_renegotiation->enabled = 1;
+                    ret = 0;
+                }
+            }
+            else if (*input == 2 * TLS_FINISHED_SZ) {
+                /* TODO compare client_verify_data and server_verify_data */
+                ret = 0;
+            }
+        #endif
+        }
+    }
+
+    if (ret != 0) {
+        /* TODO: turn on fatal error at ssl level too */
+        SendAlert(ssl, alert_fatal, handshake_failure);
+    }
+
+    return ret;
+}
+
+int TLSX_UseSecureRenegotiation(TLSX** extensions)
+{
+    int ret = 0;
+    SecureRenegotiation* data = NULL;
+
+    data = (SecureRenegotiation*)XMALLOC(sizeof(SecureRenegotiation), NULL,
+                                                             DYNAMIC_TYPE_TLSX);
+    if (data == NULL)
+        return MEMORY_E;
+
+    XMEMSET(data, 0, sizeof(SecureRenegotiation));
+
+    ret = TLSX_Push(extensions, SECURE_RENEGOTIATION, data);
+    if (ret != 0) {
+        XFREE(data, 0, DYNAMIC_TYPE_TLSX);
+        return ret;
+    }
+
+    return SSL_SUCCESS;
+}
+
+
+#define SCR_FREE_ALL(data) XFREE(data, NULL, DYNAMIC_TYPE_TLSX)
+#define SCR_GET_SIZE       TLSX_SecureRenegotiation_GetSize
+#define SCR_WRITE          TLSX_SecureRenegotiation_Write
+#define SCR_PARSE          TLSX_SecureRenegotiation_Parse
+
+#else
+
+#define SCR_FREE_ALL(a)
+#define SCR_GET_SIZE(a, b)    0
+#define SCR_WRITE(a, b, c)    0
+#define SCR_PARSE(a, b, c, d) 0
+
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+#ifdef HAVE_SESSION_TICKET
+
+static void TLSX_SessionTicket_ValidateRequest(WOLFSSL* ssl)
+{
+    TLSX*          extension = TLSX_Find(ssl->extensions, SESSION_TICKET);
+    SessionTicket* ticket    = extension ? extension->data : NULL;
+
+    if (ticket) {
+        /* TODO validate ticket timeout here! */
+        if (ticket->lifetime == 0xfffffff) {
+            /* send empty ticket on timeout */
+            TLSX_UseSessionTicket(&ssl->extensions, NULL);
+        }
+    }
+}
+
+
+static word16 TLSX_SessionTicket_GetSize(SessionTicket* ticket, int isRequest)
+{
+    (void)isRequest;
+    return ticket ? ticket->size : 0;
+}
+
+static word16 TLSX_SessionTicket_Write(SessionTicket* ticket, byte* output,
+                                                                  int isRequest)
+{
+    word16 offset = 0; /* empty ticket */
+
+    if (isRequest && ticket) {
+        XMEMCPY(output + offset, ticket->data, ticket->size);
+        offset += ticket->size;
+    }
+
+    return offset;
+}
+
+
+static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+    int ret = 0;
+
+    if (!isRequest) {
+        /* client side */
+        if (length != 0)
+            return BUFFER_ERROR;
+
+        ssl->expect_session_ticket = 1;
+    }
+#ifndef NO_WOLFSSL_SERVER
+    else {
+        /* server side */
+        if (ssl->ctx->ticketEncCb == NULL) {
+            WOLFSSL_MSG("Client sent session ticket, server has no callback");
+            return 0;
+        }
+
+        if (length == 0) {
+            /* blank ticket */
+            ret = TLSX_UseSessionTicket(&ssl->extensions, NULL);
+            if (ret == SSL_SUCCESS) {
+                ret = 0;
+                TLSX_SetResponse(ssl, SESSION_TICKET);  /* send blank ticket */
+                ssl->options.createTicket = 1;  /* will send ticket msg */
+                ssl->options.useTicket    = 1;
+            }
+        } else {
+            /* got actual ticket from client */
+            ret = DoClientTicket(ssl, input, length);
+            if (ret == WOLFSSL_TICKET_RET_OK) {    /* use ticket to resume */
+                WOLFSSL_MSG("Using exisitng client ticket");
+                ssl->options.useTicket = 1;
+                ssl->options.resuming  = 1;
+            } else if (ret == WOLFSSL_TICKET_RET_CREATE) {
+                WOLFSSL_MSG("Using existing client ticket, creating new one");
+                ret = TLSX_UseSessionTicket(&ssl->extensions, NULL);
+                if (ret == SSL_SUCCESS) {
+                    ret = 0;
+                    TLSX_SetResponse(ssl, SESSION_TICKET);
+                                                    /* send blank ticket */
+                    ssl->options.createTicket = 1;  /* will send ticket msg */
+                    ssl->options.useTicket    = 1;
+                    ssl->options.resuming     = 1;
+                }
+            } else if (ret == WOLFSSL_TICKET_RET_REJECT) {
+                WOLFSSL_MSG("Process client ticket rejected, not using");
+                ret = 0;  /* not fatal */
+            } else if (ret == WOLFSSL_TICKET_RET_FATAL || ret < 0) {
+                WOLFSSL_MSG("Process client ticket fatal error, not using");
+            }
+        }
+    }
+#endif /* NO_WOLFSSL_SERVER */
+
+    return ret;
+}
+
+WOLFSSL_LOCAL SessionTicket* TLSX_SessionTicket_Create(word32 lifetime,
+                                                       byte* data, word16 size)
+{
+    SessionTicket* ticket = (SessionTicket*)XMALLOC(sizeof(SessionTicket),
+                                                       NULL, DYNAMIC_TYPE_TLSX);
+    if (ticket) {
+        ticket->data = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_TLSX);
+        if (ticket->data == NULL) {
+            XFREE(ticket, NULL, DYNAMIC_TYPE_TLSX);
+            return NULL;
+        }
+
+        XMEMCPY(ticket->data, data, size);
+        ticket->size     = size;
+        ticket->lifetime = lifetime;
+    }
+
+    return ticket;
+}
+WOLFSSL_LOCAL void TLSX_SessionTicket_Free(SessionTicket* ticket)
+{
+    if (ticket) {
+        XFREE(ticket->data, NULL, DYNAMIC_TYPE_TLSX);
+        XFREE(ticket,       NULL, DYNAMIC_TYPE_TLSX);
+    }
+}
+
+int TLSX_UseSessionTicket(TLSX** extensions, SessionTicket* ticket)
+{
+    int ret = 0;
+
+    if (extensions == NULL)
+        return BAD_FUNC_ARG;
+
+    /* If the ticket is NULL, the client will request a new ticket from the
+       server. Otherwise, the client will use it in the next client hello. */
+    if ((ret = TLSX_Push(extensions, SESSION_TICKET, (void*)ticket)) != 0)
+        return ret;
+
+    return SSL_SUCCESS;
+}
+
+#define STK_VALIDATE_REQUEST TLSX_SessionTicket_ValidateRequest
+#define STK_GET_SIZE         TLSX_SessionTicket_GetSize
+#define STK_WRITE            TLSX_SessionTicket_Write
+#define STK_PARSE            TLSX_SessionTicket_Parse
+
+#else
+
+#define STK_VALIDATE_REQUEST(a)
+#define STK_GET_SIZE(a, b)      0
+#define STK_WRITE(a, b, c)      0
+#define STK_PARSE(a, b, c, d)   0
+
+#endif /* HAVE_SESSION_TICKET */
+
+
+#ifdef HAVE_QSH
+static WC_RNG* rng;
+static wolfSSL_Mutex* rngMutex;
+
+static void TLSX_QSH_FreeAll(QSHScheme* list)
+{
+    QSHScheme* current;
+
+    while ((current = list)) {
+        list = current->next;
+        XFREE(current, 0, DYNAMIC_TYPE_TLSX);
+    }
+}
+
+static int TLSX_QSH_Append(QSHScheme** list, word16 name, byte* pub,
+                                                                  word16 pubLen)
+{
+    QSHScheme* temp;
+
+    if (list == NULL)
+        return BAD_FUNC_ARG;
+
+    if ((temp = XMALLOC(sizeof(QSHScheme), 0, DYNAMIC_TYPE_TLSX)) == NULL)
+        return MEMORY_E;
+
+    temp->name  = name;
+    temp->PK    = pub;
+    temp->PKLen = pubLen;
+    temp->next  = *list;
+
+    *list = temp;
+
+    return 0;
+}
+
+
+/* request for server's public key : 02 indicates 0-2 requested */
+static byte TLSX_QSH_SerPKReq(byte* output, byte isRequest)
+{
+    if (isRequest) {
+        /* only request one public key from the server */
+        output[0] = 0x01;
+
+        return OPAQUE8_LEN;
+    }
+    else {
+        return 0;
+    }
+}
+
+#ifndef NO_WOLFSSL_CLIENT
+
+/* check for TLS_QSH suite */
+static void TLSX_QSH_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
+{
+    int i;
+
+    for (i = 0; i < ssl->suites->suiteSz; i+= 2)
+        if (ssl->suites->suites[i] == QSH_BYTE)
+            return;
+
+    /* No QSH suite found */
+    TURN_ON(semaphore, TLSX_ToSemaphore(WOLFSSL_QSH));
+}
+
+
+/* return the size of the QSH hello extension
+   list      the list of QSHScheme structs containing id and key
+   isRequest if 1 then is being sent to the server
+ */
+word16 TLSX_QSH_GetSize(QSHScheme* list, byte isRequest)
+{
+    QSHScheme* temp = list;
+    word16 length = 0;
+
+    /* account for size of scheme list and public key list */
+    if (isRequest)
+        length = OPAQUE16_LEN;
+    length += OPAQUE24_LEN;
+
+    /* for each non null element in list add size */
+    while ((temp)) {
+        /* add public key info Scheme | Key Length | Key */
+        length += OPAQUE16_LEN;
+        length += OPAQUE16_LEN;
+        length += temp->PKLen;
+
+        /* if client add name size for scheme list
+           advance to next QSHScheme struct in list */
+        if (isRequest)
+            length += OPAQUE16_LEN;
+        temp = temp->next;
+    }
+
+    /* add length for request server public keys */
+    if (isRequest)
+        length += OPAQUE8_LEN;
+
+    return length;
+}
+
+
+/* write out a list of QSHScheme IDs */
+static word16 TLSX_QSH_Write(QSHScheme* list, byte* output)
+{
+    QSHScheme* current = list;
+    word16 length      = 0;
+
+    length += OPAQUE16_LEN;
+
+    while (current) {
+        c16toa(current->name, output + length);
+        length += OPAQUE16_LEN;
+        current = (QSHScheme*)current->next;
+    }
+
+    c16toa(length - OPAQUE16_LEN, output); /* writing list length */
+
+    return length;
+}
+
+
+/* write public key list in extension */
+static word16 TLSX_QSHPK_WriteR(QSHScheme* format, byte* output);
+static word16 TLSX_QSHPK_WriteR(QSHScheme* format, byte* output)
+{
+    word32 offset = 0;
+    word16 public_len = 0;
+
+    if (!format)
+        return offset;
+
+    /* write scheme ID */
+    c16toa(format->name, output + offset);
+    offset += OPAQUE16_LEN;
+
+    /* write public key matching scheme */
+    public_len = format->PKLen;
+    c16toa(public_len, output + offset);
+    offset += OPAQUE16_LEN;
+    if (format->PK) {
+        XMEMCPY(output+offset, format->PK, public_len);
+    }
+
+    return public_len + offset;
+}
+
+word16 TLSX_QSHPK_Write(QSHScheme* list, byte* output)
+{
+    QSHScheme* current = list;
+    word32 length = 0;
+    word24 toWire;
+
+    length += OPAQUE24_LEN;
+
+    while (current) {
+        length += TLSX_QSHPK_WriteR(current, output + length);
+        current = (QSHScheme*)current->next;
+    }
+    /* length of public keys sent */
+    c32to24(length - OPAQUE24_LEN, toWire);
+    output[0] = toWire[0];
+    output[1] = toWire[1];
+    output[2] = toWire[2];
+
+    return length;
+}
+
+#endif /* NO_WOLFSSL_CLIENT */
+#ifndef NO_WOLFSSL_SERVER
+
+static void TLSX_QSHAgreement(TLSX** extensions)
+{
+    TLSX* extension = TLSX_Find(*extensions, WOLFSSL_QSH);
+    QSHScheme* format = NULL;
+    QSHScheme* delete = NULL;
+    QSHScheme* prev   = NULL;
+
+    if (extension == NULL)
+        return;
+
+    format = extension->data;
+    while (format) {
+        if (format->PKLen == 0) {
+            /* case of head */
+            if (format == extension->data) {
+                extension->data = format->next;
+            }
+            if (prev)
+                prev->next = format->next;
+            delete = format;
+            format = format->next;
+            XFREE(delete, 0, DYNAMIC_TYPE_TMP_ARRAY);
+            delete = NULL;
+        } else {
+            prev   = format;
+            format = format->next;
+        }
+    }
+}
+
+
+/* Parse in hello extension
+   input     the byte stream to process
+   length    length of total extension found
+   isRequest set to 1 if being sent to the server
+ */
+static int TLSX_QSH_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+    byte   numKeys    = 0;
+    word16 offset     = 0;
+    word16 schemSz    = 0;
+    word16 offset_len = 0;
+    word32 offset_pk  = 0;
+    word16 name  = 0;
+    word16 PKLen = 0;
+    byte*  PK = NULL;
+    int r;
+
+
+    if (OPAQUE16_LEN > length)
+        return BUFFER_ERROR;
+
+    if (isRequest) {
+        ato16(input, &schemSz);
+
+        /* list of public keys avialable for QSH schemes */
+        offset_len = schemSz + OPAQUE16_LEN;
+    }
+
+    offset_pk = ((input[offset_len] << 16)   & 0xFF00000) |
+                (((input[offset_len + 1]) << 8) & 0xFF00) |
+                (input[offset_len + 2] & 0xFF);
+    offset_len += OPAQUE24_LEN;
+
+    /* check buffer size */
+    if (offset_pk > length)
+        return BUFFER_ERROR;
+
+    /* set maximum number of keys the client will accept */
+    if (!isRequest)
+        numKeys = (ssl->maxRequest < 1)? 1 : ssl->maxRequest;
+
+    /* hello extension read list of scheme ids */
+    if (isRequest) {
+
+        /* read in request for public keys */
+        ssl->minRequest = (input[length -1] >> 4) & 0xFF;
+        ssl->maxRequest = input[length -1] & 0x0F;
+
+        /* choose the min between min requested by client and 1 */
+        numKeys = (ssl->minRequest > 1) ? ssl->minRequest : 1;
+
+        if (ssl->minRequest > ssl->maxRequest)
+            return BAD_FUNC_ARG;
+
+        offset  += OPAQUE16_LEN;
+        schemSz += offset;
+
+        /* check buffer size */
+        if (schemSz > length)
+            return BUFFER_ERROR;
+
+        while ((offset < schemSz) && numKeys) {
+            /* Scheme ID list */
+            ato16(input + offset, &name);
+            offset += OPAQUE16_LEN;
+
+            /* validate we have scheme id */
+            if (ssl->user_set_QSHSchemes &&
+                    !TLSX_ValidateQSHScheme(&ssl->extensions, name)) {
+                continue;
+            }
+
+            /* server create keys on demand */
+            if ((r = TLSX_CreateNtruKey(ssl, name)) != 0) {
+                WOLFSSL_MSG("Error creating ntru keys");
+                return r;
+            }
+
+            /* peer sent an agreed upon scheme */
+            r = TLSX_UseQSHScheme(&ssl->extensions, name, NULL, 0);
+
+            if (r != SSL_SUCCESS) return r; /* throw error */
+
+            numKeys--;
+        }
+
+        /* choose the min between min requested by client and 1 */
+        numKeys = (ssl->minRequest > 1) ? ssl->minRequest : 1;
+    }
+
+    /* QSHPK struct */
+    offset_pk += offset_len;
+    while ((offset_len < offset_pk) && numKeys) {
+        QSHKey * temp;
+
+        if ((temp = XMALLOC(sizeof(QSHKey), 0, DYNAMIC_TYPE_TLSX)) == NULL)
+            return MEMORY_E;
+
+        /* initialize */
+        temp->next = NULL;
+        temp->pub.buffer = NULL;
+        temp->pub.length = 0;
+        temp->pri.buffer = NULL;
+        temp->pri.length = 0;
+
+        /* scheme id */
+        ato16(input + offset_len, &(temp->name));
+        offset_len += OPAQUE16_LEN;
+
+        /* public key length */
+        ato16(input + offset_len, &PKLen);
+        temp->pub.length = PKLen;
+        offset_len += OPAQUE16_LEN;
+
+
+        if (isRequest) {
+            /* validate we have scheme id */
+            if (ssl->user_set_QSHSchemes &&
+                    (!TLSX_ValidateQSHScheme(&ssl->extensions, temp->name))) {
+                offset_len += PKLen;
+                XFREE(temp, 0, DYNAMIC_TYPE_TLSX);
+                continue;
+            }
+        }
+
+        /* read in public key */
+        if (PKLen > 0) {
+            temp->pub.buffer = (byte*)XMALLOC(temp->pub.length,
+                               0, DYNAMIC_TYPE_PUBLIC_KEY);
+            XMEMCPY(temp->pub.buffer, input + offset_len, temp->pub.length);
+            offset_len += PKLen;
+        }
+        else {
+            PK = NULL;
+        }
+
+        /* use own key when adding to extensions list for sending reply */
+        PKLen = 0;
+        PK = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, &PKLen, temp->name);
+        r  = TLSX_UseQSHScheme(&ssl->extensions, temp->name, PK, PKLen);
+
+        /* store peers key */
+        ssl->peerQSHKeyPresent = 1;
+        if (TLSX_AddQSHKey(&ssl->peerQSHKey, temp) != 0)
+            return MEMORY_E;
+
+        if (temp->pub.length == 0) {
+            XFREE(temp, 0, DYNAMIC_TYPE_TLSX);
+        }
+
+        if (r != SSL_SUCCESS) {return r;} /* throw error */
+
+        numKeys--;
+    }
+
+    /* reply to a QSH extension sent from client */
+    if (isRequest) {
+        TLSX_SetResponse(ssl, WOLFSSL_QSH);
+        /* only use schemes we have key generated for -- free the rest */
+        TLSX_QSHAgreement(&ssl->extensions);
+    }
+
+    return 0;
+}
+
+
+/* Used for parsing in QSHCipher structs on Key Exchange */
+int TLSX_QSHCipher_Parse(WOLFSSL* ssl, const byte* input, word16 length,
+                                                                  byte isServer)
+{
+    QSHKey* key;
+    word16 Max_Secret_Len = 48;
+    word16 offset     = 0;
+    word16 offset_len = 0;
+    word32 offset_pk  = 0;
+    word16 name       = 0;
+    word16 secretLen  = 0;
+    byte*  secret     = NULL;
+    word16 buffLen    = 0;
+    byte buff[145]; /* size enough for 3 secrets */
+    buffer* buf;
+
+    /* pointer to location where secret should be stored */
+    if (isServer) {
+        buf = ssl->QSH_secret->CliSi;
+    }
+    else {
+        buf = ssl->QSH_secret->SerSi;
+    }
+
+    offset_pk = ((input[offset_len] << 16)    & 0xFF0000) |
+                (((input[offset_len + 1]) << 8) & 0xFF00) |
+                (input[offset_len + 2] & 0xFF);
+    offset_len += OPAQUE24_LEN;
+
+    /* validating extension list length -- check if trying to read over edge
+       of buffer */
+    if (length < (offset_pk + OPAQUE24_LEN)) {
+        return BUFFER_ERROR;
+    }
+
+    /* QSHCipherList struct */
+    offset_pk += offset_len;
+    while (offset_len < offset_pk) {
+
+        /* scheme id */
+        ato16(input + offset_len, &name);
+        offset_len += OPAQUE16_LEN;
+
+        /* public key length */
+        ato16(input + offset_len, &secretLen);
+        offset_len += OPAQUE16_LEN;
+
+        /* read in public key */
+        if (secretLen > 0) {
+            secret = (byte*)(input + offset_len);
+            offset_len += secretLen;
+        }
+        else {
+            secret = NULL;
+        }
+
+        /* no secret sent */
+        if (secret == NULL)
+            continue;
+
+        /* find coresponding key */
+        key = ssl->QSH_Key;
+        while (key) {
+            if (key->name == name)
+                break;
+            else
+                key = (QSHKey*)key->next;
+        }
+
+        /* if we do not have the key than there was a big issue negotiation */
+        if (key == NULL) {
+            WOLFSSL_MSG("key was null for decryption!!!\n");
+            return MEMORY_E;
+        }
+
+        /* Decrypt sent secret */
+        buffLen = Max_Secret_Len;
+        QSH_Decrypt(key, secret, secretLen, buff + offset, &buffLen);
+        offset += buffLen;
+    }
+
+    /* allocate memory for buffer */
+    buf->length = offset;
+    buf->buffer = (byte*)XMALLOC(offset, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buf->buffer == NULL)
+        return MEMORY_E;
+
+    /* store secrets */
+    XMEMCPY(buf->buffer, buff, offset);
+    ForceZero(buff, offset);
+
+    return offset_len;
+}
+
+
+/* return 1 on success */
+int TLSX_ValidateQSHScheme(TLSX** extensions, word16 theirs) {
+    TLSX* extension = TLSX_Find(*extensions, WOLFSSL_QSH);
+    QSHScheme* format    = NULL;
+
+    /* if no extension is sent then do not use QSH */
+    if (!extension) {
+        WOLFSSL_MSG("No QSH Extension");
+        return 0;
+    }
+
+    for (format = (QSHScheme*)extension->data; format; format = format->next) {
+        if (format->name == theirs) {
+	        WOLFSSL_MSG("Found Matching QSH Scheme");
+            return 1; /* have QSH */
+        }
+    }
+
+    return 0;
+}
+#endif /* NO_WOLFSSL_SERVER */
+
+/* test if the QSH Scheme is implemented
+   return 1 if yes 0 if no */
+static int TLSX_HaveQSHScheme(word16 name)
+{
+    switch(name) {
+        #ifdef HAVE_NTRU
+            case WOLFSSL_NTRU_EESS439:
+            case WOLFSSL_NTRU_EESS593:
+            case WOLFSSL_NTRU_EESS743:
+                    return 1;
+        #endif
+            case WOLFSSL_LWE_XXX:
+            case WOLFSSL_HFE_XXX:
+                    return 0; /* not supported yet */
+
+        default:
+            return 0;
+    }
+}
+
+
+/* Add a QSHScheme struct to list of usable ones */
+int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz)
+{
+    TLSX*      extension = TLSX_Find(*extensions, WOLFSSL_QSH);
+    QSHScheme* format    = NULL;
+    int        ret       = 0;
+
+    /* sanity check */
+    if (extensions == NULL || (pKey == NULL && pkeySz != 0))
+        return BAD_FUNC_ARG;
+
+    /* if scheme is implemented than add */
+    if (TLSX_HaveQSHScheme(name)) {
+	    if ((ret = TLSX_QSH_Append(&format, name, pKey, pkeySz)) != 0)
+	        return ret;
+
+	    if (!extension) {
+	        if ((ret = TLSX_Push(extensions, WOLFSSL_QSH, format)) != 0) {
+	            XFREE(format, 0, DYNAMIC_TYPE_TLSX);
+	            return ret;
+	        }
+	    }
+	    else {
+	        /* push new QSH object to extension data. */
+	        format->next = (QSHScheme*)extension->data;
+	        extension->data = (void*)format;
+
+	        /* look for another format of the same name to remove (replacement) */
+	        do {
+	            if (format->next && (format->next->name == name)) {
+	                QSHScheme* next = format->next;
+
+	                format->next = next->next;
+	                XFREE(next, 0, DYNAMIC_TYPE_TLSX);
+
+	                break;
+	            }
+	        } while ((format = format->next));
+	    }
+    }
+    return SSL_SUCCESS;
+}
+
+#define QSH_FREE_ALL         TLSX_QSH_FreeAll
+#define QSH_VALIDATE_REQUEST TLSX_QSH_ValidateRequest
+
+#ifndef NO_WOLFSSL_CLIENT
+#define QSH_GET_SIZE TLSX_QSH_GetSize
+#define QSH_WRITE    TLSX_QSH_Write
+#else
+#define QSH_GET_SIZE(list)         0
+#define QSH_WRITE(a, b)            0
+#endif
+
+#ifndef NO_WOLFSSL_SERVER
+#define QSH_PARSE TLSX_QSH_Parse
+#else
+#define QSH_PARSE(a, b, c, d)      0
+#endif
+
+#define QSHPK_WRITE TLSX_QSHPK_Write
+#define QSH_SERREQ TLSX_QSH_SerPKReq
+#else
+
+#define QSH_FREE_ALL(list)
+#define QSH_GET_SIZE(list, a)      0
+#define QSH_WRITE(a, b)            0
+#define QSH_PARSE(a, b, c, d)      0
+#define QSHPK_WRITE(a, b)          0
+#define QSH_SERREQ(a, b)           0
+#define QSH_VALIDATE_REQUEST(a, b)
+
+#endif /* HAVE_QSH */
+
+
+/** Finds an extension in the provided list. */
+TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
+{
+    TLSX* extension = list;
+
+    while (extension && extension->type != type)
+        extension = extension->next;
+
+    return extension;
+}
+
+/** Releases all extensions in the provided list. */
+void TLSX_FreeAll(TLSX* list)
+{
+    TLSX* extension;
+
+    while ((extension = list)) {
+        list = extension->next;
+
+        switch (extension->type) {
+
+            case SERVER_NAME_INDICATION:
+                SNI_FREE_ALL((SNI*)extension->data);
+                break;
+
+            case MAX_FRAGMENT_LENGTH:
+                MFL_FREE_ALL(extension->data);
+                break;
+
+            case TRUNCATED_HMAC:
+                /* Nothing to do. */
+                break;
+
+            case ELLIPTIC_CURVES:
+                EC_FREE_ALL(extension->data);
+                break;
+
+            case SECURE_RENEGOTIATION:
+                SCR_FREE_ALL(extension->data);
+                break;
+
+            case SESSION_TICKET:
+                /* Nothing to do. */
+                break;
+
+            case WOLFSSL_QSH:
+                QSH_FREE_ALL(extension->data);
+                break;
+
+            case WOLFSSL_ALPN:
+                ALPN_FREE_ALL((ALPN*)extension->data);
+                break;
+        }
+
+        XFREE(extension, 0, DYNAMIC_TYPE_TLSX);
+    }
+}
+
+/** Checks if the tls extensions are supported based on the protocol version. */
+int TLSX_SupportExtensions(WOLFSSL* ssl) {
+    return ssl && (IsTLS(ssl) || ssl->version.major == DTLS_MAJOR);
+}
+
+/** Tells the buffered size of the extensions in a list. */
+static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest)
+{
+    TLSX* extension;
+    word16 length = 0;
+
+    while ((extension = list)) {
+        list = extension->next;
+
+        /* only extensions marked as response are sent back to the client. */
+        if (!isRequest && !extension->resp)
+            continue; /* skip! */
+
+        /* ssl level extensions are expected to override ctx level ones. */
+        if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type)))
+            continue; /* skip! */
+
+        /* extension type + extension data length. */
+        length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
+
+
+        switch (extension->type) {
+
+            case SERVER_NAME_INDICATION:
+                /* SNI only sends the name on the request. */
+                if (isRequest)
+                    length += SNI_GET_SIZE(extension->data);
+                break;
+
+            case MAX_FRAGMENT_LENGTH:
+                length += MFL_GET_SIZE(extension->data);
+                break;
+
+            case TRUNCATED_HMAC:
+                /* always empty. */
+                break;
+
+            case ELLIPTIC_CURVES:
+                length += EC_GET_SIZE(extension->data);
+                break;
+
+            case SECURE_RENEGOTIATION:
+                length += SCR_GET_SIZE(extension->data, isRequest);
+                break;
+
+            case SESSION_TICKET:
+                length += STK_GET_SIZE(extension->data, isRequest);
+                break;
+
+            case WOLFSSL_QSH:
+                length += QSH_GET_SIZE(extension->data, isRequest);
+                break;
+
+            case WOLFSSL_ALPN:
+                length += ALPN_GET_SIZE(extension->data);
+                break;
+
+        }
+
+        /* marks the extension as processed so ctx level */
+        /* extensions don't overlap with ssl level ones. */
+        TURN_ON(semaphore, TLSX_ToSemaphore(extension->type));
+    }
+
+    return length;
+}
+
+/** Writes the extensions of a list in a buffer. */
+static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
+                                                                 byte isRequest)
+{
+    TLSX* extension;
+    word16 offset = 0;
+    word16 length_offset = 0;
+
+    while ((extension = list)) {
+        list = extension->next;
+
+        /* only extensions marked as response are written in a response. */
+        if (!isRequest && !extension->resp)
+            continue; /* skip! */
+
+        /* ssl level extensions are expected to override ctx level ones. */
+        if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type)))
+            continue; /* skip! */
+
+        /* writes extension type. */
+        c16toa(extension->type, output + offset);
+        offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
+        length_offset = offset;
+
+        /* extension data should be written internally. */
+        switch (extension->type) {
+            case SERVER_NAME_INDICATION:
+                if (isRequest)
+                    offset += SNI_WRITE(extension->data, output + offset);
+                break;
+
+            case MAX_FRAGMENT_LENGTH:
+                offset += MFL_WRITE(extension->data, output + offset);
+                break;
+
+            case TRUNCATED_HMAC:
+                /* always empty. */
+                break;
+
+            case ELLIPTIC_CURVES:
+                offset += EC_WRITE(extension->data, output + offset);
+                break;
+
+            case SECURE_RENEGOTIATION:
+                offset += SCR_WRITE(extension->data, output + offset,
+                                                                     isRequest);
+                break;
+
+            case SESSION_TICKET:
+                offset += STK_WRITE(extension->data, output + offset,
+                                                                     isRequest);
+                break;
+
+            case WOLFSSL_QSH:
+                if (isRequest) {
+                    offset += QSH_WRITE(extension->data, output + offset);
+                }
+                offset += QSHPK_WRITE(extension->data, output + offset);
+                offset += QSH_SERREQ(output + offset, isRequest);
+                break;
+
+            case WOLFSSL_ALPN:
+                offset += ALPN_WRITE(extension->data, output + offset);
+                break;
+        }
+
+        /* writes extension data length. */
+        c16toa(offset - length_offset, output + length_offset - OPAQUE16_LEN);
+
+        /* marks the extension as processed so ctx level */
+        /* extensions don't overlap with ssl level ones. */
+        TURN_ON(semaphore, TLSX_ToSemaphore(extension->type));
+    }
+
+    return offset;
+}
+
+
+#ifdef HAVE_NTRU
+
+static word32 GetEntropy(unsigned char* out, word32 num_bytes)
+{
+    int ret = 0;
+
+    if (rng == NULL) {
+        if ((rng = XMALLOC(sizeof(WC_RNG), 0, DYNAMIC_TYPE_TLSX)) == NULL)
+            return DRBG_OUT_OF_MEMORY;
+        wc_InitRng(rng);
+    }
+
+    if (rngMutex == NULL) {
+        if ((rngMutex = XMALLOC(sizeof(wolfSSL_Mutex), 0,
+                        DYNAMIC_TYPE_TLSX)) == NULL)
+            return DRBG_OUT_OF_MEMORY;
+        InitMutex(rngMutex);
+    }
+
+    ret |= LockMutex(rngMutex);
+    ret |= wc_RNG_GenerateBlock(rng, out, num_bytes);
+    ret |= UnLockMutex(rngMutex);
+
+    if (ret != 0)
+        return DRBG_ENTROPY_FAIL;
+
+    return DRBG_OK;
+}
+#endif
+
+
+#ifdef HAVE_QSH
+static int TLSX_CreateQSHKey(WOLFSSL* ssl, int type)
+{
+    int ret;
+
+    switch (type) {
+#ifdef HAVE_NTRU
+        case WOLFSSL_NTRU_EESS439:
+        case WOLFSSL_NTRU_EESS593:
+        case WOLFSSL_NTRU_EESS743:
+            ret = TLSX_CreateNtruKey(ssl, type);
+            break;
+#endif
+        default:
+            WOLFSSL_MSG("Unknown type for creating NTRU key");
+            return -1;
+    }
+
+    return ret;
+}
+
+
+static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key)
+{
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    /* if no public key stored in key then do not add */
+    if (key->pub.length == 0 || key->pub.buffer == NULL)
+        return 0;
+
+    /* first element to be added to the list */
+    QSHKey* current = *list;
+    if (current == NULL) {
+        *list = key;
+        return 0;
+    }
+
+    while (current->next) {
+        /* can only have one of the key in the list */
+        if (current->name == key->name)
+            return -1;
+        current = (QSHKey*)current->next;
+    }
+
+    current->next = (struct QSHKey*)key;
+
+    return 0;
+}
+
+
+#ifdef HAVE_NTRU
+int TLSX_CreateNtruKey(WOLFSSL* ssl, int type)
+{
+    int ret;
+    int ntruType;
+
+    /* variable declarations for NTRU*/
+    QSHKey* temp = NULL;
+    byte   public_key[1027];
+    word16 public_key_len = sizeof(public_key);
+    byte   private_key[1120];
+    word16 private_key_len = sizeof(private_key);
+    DRBG_HANDLE drbg;
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (type) {
+        case WOLFSSL_NTRU_EESS439:
+            ntruType = NTRU_EES439EP1;
+            break;
+        case WOLFSSL_NTRU_EESS593:
+            ntruType = NTRU_EES593EP1;
+            break;
+        case WOLFSSL_NTRU_EESS743:
+            ntruType = NTRU_EES743EP1;
+            break;
+        default:
+            WOLFSSL_MSG("Unknown type for creating NTRU key");
+            return -1;
+    }
+    ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
+    if (ret != DRBG_OK) {
+        WOLFSSL_MSG("NTRU drbg instantiate failed\n");
+        return ret;
+    }
+
+    if ((ret = ntru_crypto_ntru_encrypt_keygen(drbg, ntruType,
+                     &public_key_len, NULL, &private_key_len, NULL)) != NTRU_OK)
+        return ret;
+
+    if ((ret = ntru_crypto_ntru_encrypt_keygen(drbg, ntruType,
+        &public_key_len, public_key, &private_key_len, private_key)) != NTRU_OK)
+        return ret;
+
+    ret = ntru_crypto_drbg_uninstantiate(drbg);
+    if (ret != NTRU_OK) {
+        WOLFSSL_MSG("NTRU drbg uninstantiate failed\n");
+        return ret;
+    }
+
+    if ((temp = XMALLOC(sizeof(QSHKey), 0, DYNAMIC_TYPE_TLSX)) == NULL)
+        return MEMORY_E;
+    temp->name = type;
+    temp->pub.length = public_key_len;
+    temp->pub.buffer = XMALLOC(public_key_len, public_key,
+                                DYNAMIC_TYPE_PUBLIC_KEY);
+    XMEMCPY(temp->pub.buffer, public_key, public_key_len);
+    temp->pri.length = private_key_len;
+    temp->pri.buffer = XMALLOC(private_key_len, private_key,
+                                DYNAMIC_TYPE_ARRAYS);
+    XMEMCPY(temp->pri.buffer, private_key, private_key_len);
+    temp->next = NULL;
+
+    TLSX_AddQSHKey(&ssl->QSH_Key, temp);
+
+    return ret;
+}
+#endif
+
+
+/*
+    Used to find a public key from the list of keys
+    pubLen length of array
+    name   input the name of the scheme looking for ie WOLFSSL_NTRU_ESSXXX
+
+    returns a pointer to public key byte* or NULL if not found
+ */
+static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name)
+{
+    QSHKey* current = qsh;
+
+    if (qsh == NULL || pubLen == NULL)
+        return NULL;
+
+    *pubLen = 0;
+
+    while(current) {
+        if (current->name == name) {
+            *pubLen = current->pub.length;
+            return current->pub.buffer;
+        }
+        current = (QSHKey*)current->next;
+    }
+
+    return NULL;
+}
+#endif /* HAVE_QSH */
+
+
+int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
+{
+    byte* public_key      = NULL;
+    word16 public_key_len = 0;
+    #ifdef HAVE_QSH
+        TLSX* extension;
+        QSHScheme* qsh;
+        QSHScheme* next;
+    #endif
+    int ret = 0;
+
+    #ifdef HAVE_QSH
+        /* add supported QSHSchemes */
+        WOLFSSL_MSG("Adding supported QSH Schemes");
+
+        /* server will add extension depending on whats parsed from client */
+        if (!isServer) {
+
+            /* test if user has set a specific scheme already */
+            if (!ssl->user_set_QSHSchemes) {
+                if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) {
+                    if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS743)) != 0) {
+                        WOLFSSL_MSG("Error creating ntru keys");
+                        return ret;
+                    }
+                    if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS593)) != 0) {
+                        WOLFSSL_MSG("Error creating ntru keys");
+                        return ret;
+                    }
+                    if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS439)) != 0) {
+                        WOLFSSL_MSG("Error creating ntru keys");
+                        return ret;
+                    }
+
+                /* add NTRU 256 */
+                public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
+                        &public_key_len, WOLFSSL_NTRU_EESS743);
+                }
+                if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS743,
+                        public_key, public_key_len) != SSL_SUCCESS)
+                    ret = -1;
+
+                /* add NTRU 196 */
+                if (ssl->sendQSHKeys) {
+                    public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
+                        &public_key_len, WOLFSSL_NTRU_EESS593);
+                }
+                if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS593,
+                        public_key, public_key_len) != SSL_SUCCESS)
+                    ret = -1;
+
+                /* add NTRU 128 */
+                if (ssl->sendQSHKeys) {
+                    public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
+                        &public_key_len, WOLFSSL_NTRU_EESS439);
+                }
+                if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS439,
+                        public_key, public_key_len) != SSL_SUCCESS)
+                    ret = -1;
+            }
+            else if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) {
+                /* for each scheme make a client key */
+                extension = TLSX_Find(ssl->extensions, WOLFSSL_QSH);
+                if (extension) {
+                    qsh = (QSHScheme*)extension->data;
+
+                    while (qsh) {
+                        if ((ret = TLSX_CreateQSHKey(ssl, qsh->name)) != 0)
+                            return ret;
+
+                        /* get next now because qsh could be freed */
+                        next = qsh->next;
+
+                        /* find the public key created and add to extension*/
+                        public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
+                                 &public_key_len, qsh->name);
+                        if (TLSX_UseQSHScheme(&ssl->extensions, qsh->name,
+                                    public_key, public_key_len) != SSL_SUCCESS)
+                            ret = -1;
+                        qsh = next;
+                    }
+                }
+            }
+         } /* is not server */
+    #endif
+
+    (void)isServer;
+    (void)public_key;
+    (void)public_key_len;
+    (void)ssl;
+
+    return ret;
+}
+
+
+#ifndef NO_WOLFSSL_CLIENT
+
+/** Tells the buffered size of extensions to be sent into the client hello. */
+word16 TLSX_GetRequestSize(WOLFSSL* ssl)
+{
+    word16 length = 0;
+
+    if (TLSX_SupportExtensions(ssl)) {
+        byte semaphore[SEMAPHORE_SIZE] = {0};
+
+        EC_VALIDATE_REQUEST(ssl, semaphore);
+        QSH_VALIDATE_REQUEST(ssl, semaphore);
+        STK_VALIDATE_REQUEST(ssl);
+
+        if (ssl->extensions)
+            length += TLSX_GetSize(ssl->extensions, semaphore, 1);
+
+        if (ssl->ctx && ssl->ctx->extensions)
+            length += TLSX_GetSize(ssl->ctx->extensions, semaphore, 1);
+
+        if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
+            length += ssl->suites->hashSigAlgoSz + HELLO_EXT_LEN;
+    }
+
+    if (length)
+        length += OPAQUE16_LEN; /* for total length storage. */
+
+    return length;
+}
+
+/** Writes the extensions to be sent into the client hello. */
+word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output)
+{
+    word16 offset = 0;
+
+    if (TLSX_SupportExtensions(ssl) && output) {
+        byte semaphore[SEMAPHORE_SIZE] = {0};
+
+        offset += OPAQUE16_LEN; /* extensions length */
+
+        EC_VALIDATE_REQUEST(ssl, semaphore);
+        STK_VALIDATE_REQUEST(ssl);
+        QSH_VALIDATE_REQUEST(ssl, semaphore);
+
+        if (ssl->extensions)
+            offset += TLSX_Write(ssl->extensions, output + offset,
+                                                                  semaphore, 1);
+
+        if (ssl->ctx && ssl->ctx->extensions)
+            offset += TLSX_Write(ssl->ctx->extensions, output + offset,
+                                                                  semaphore, 1);
+
+        if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
+        {
+            int i;
+            /* extension type */
+            c16toa(HELLO_EXT_SIG_ALGO, output + offset);
+            offset += HELLO_EXT_TYPE_SZ;
+
+            /* extension data length */
+            c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz, output + offset);
+            offset += OPAQUE16_LEN;
+
+            /* sig algos length */
+            c16toa(ssl->suites->hashSigAlgoSz, output + offset);
+            offset += OPAQUE16_LEN;
+
+            /* sig algos */
+            for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, offset++)
+                output[offset] = ssl->suites->hashSigAlgo[i];
+        }
+
+        if (offset > OPAQUE16_LEN)
+            c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
+    }
+
+    return offset;
+}
+
+#endif /* NO_WOLFSSL_CLIENT */
+
+#ifndef NO_WOLFSSL_SERVER
+
+/** Tells the buffered size of extensions to be sent into the server hello. */
+word16 TLSX_GetResponseSize(WOLFSSL* ssl)
+{
+    word16 length = 0;
+    byte semaphore[SEMAPHORE_SIZE] = {0};
+
+    #ifdef HAVE_QSH
+        /* change response if not using TLS_QSH */
+        if (!ssl->options.haveQSH) {
+            TLSX* ext = TLSX_Find(ssl->extensions, WOLFSSL_QSH);
+            if (ext)
+                ext->resp = 0;
+        }
+    #endif
+
+    if (TLSX_SupportExtensions(ssl))
+        length += TLSX_GetSize(ssl->extensions, semaphore, 0);
+
+    /* All the response data is set at the ssl object only, so no ctx here. */
+
+    if (length)
+        length += OPAQUE16_LEN; /* for total length storage */
+
+    return length;
+}
+
+/** Writes the server hello extensions into a buffer. */
+word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output)
+{
+    word16 offset = 0;
+
+    if (TLSX_SupportExtensions(ssl) && output) {
+        byte semaphore[SEMAPHORE_SIZE] = {0};
+
+        offset += OPAQUE16_LEN; /* extensions length */
+
+        offset += TLSX_Write(ssl->extensions, output + offset, semaphore, 0);
+
+        if (offset > OPAQUE16_LEN)
+            c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
+    }
+
+    return offset;
+}
+
+#endif /* NO_WOLFSSL_SERVER */
+
+/** Parses a buffer of TLS extensions. */
+int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest,
+                                                                 Suites *suites)
+{
+    int ret = 0;
+    word16 offset = 0;
+
+    if (!ssl || !input || (isRequest && !suites))
+        return BAD_FUNC_ARG;
+
+    while (ret == 0 && offset < length) {
+        word16 type;
+        word16 size;
+
+        if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN)
+            return BUFFER_ERROR;
+
+        ato16(input + offset, &type);
+        offset += HELLO_EXT_TYPE_SZ;
+
+        ato16(input + offset, &size);
+        offset += OPAQUE16_LEN;
+
+        if (offset + size > length)
+            return BUFFER_ERROR;
+
+        switch (type) {
+            case SERVER_NAME_INDICATION:
+                WOLFSSL_MSG("SNI extension received");
+
+                ret = SNI_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case MAX_FRAGMENT_LENGTH:
+                WOLFSSL_MSG("Max Fragment Length extension received");
+
+                ret = MFL_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case TRUNCATED_HMAC:
+                WOLFSSL_MSG("Truncated HMAC extension received");
+
+                ret = THM_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case ELLIPTIC_CURVES:
+                WOLFSSL_MSG("Elliptic Curves extension received");
+
+                ret = EC_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case SECURE_RENEGOTIATION:
+                WOLFSSL_MSG("Secure Renegotiation extension received");
+
+                ret = SCR_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case SESSION_TICKET:
+                WOLFSSL_MSG("Session Ticket extension received");
+
+                ret = STK_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case WOLFSSL_QSH:
+                WOLFSSL_MSG("Quantum-Safe-Hybrid extension received");
+
+                ret = QSH_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case WOLFSSL_ALPN:
+                WOLFSSL_MSG("ALPN extension received");
+
+                ret = ALPN_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case HELLO_EXT_SIG_ALGO:
+                if (isRequest) {
+                    /* do not mess with offset inside the switch! */
+                    if (IsAtLeastTLSv1_2(ssl)) {
+                        ato16(input + offset, &suites->hashSigAlgoSz);
+
+                        if (suites->hashSigAlgoSz > size - OPAQUE16_LEN)
+                            return BUFFER_ERROR;
+
+                        XMEMCPY(suites->hashSigAlgo,
+                                input + offset + OPAQUE16_LEN,
+                                min(suites->hashSigAlgoSz,
+                                                        HELLO_EXT_SIGALGO_MAX));
+                    }
+                } else {
+                    WOLFSSL_MSG("Servers MUST NOT send SIG ALGO extension.");
+                }
+
+                break;
+        }
+
+        /* offset should be updated here! */
+        offset += size;
+    }
+
+    if (ret == 0)
+        ret = SNI_VERIFY_PARSE(ssl, isRequest);
+
+    return ret;
+}
+
+/* undefining semaphore macros */
+#undef IS_OFF
+#undef TURN_ON
+#undef SEMAPHORE_SIZE
+
+#endif /* HAVE_TLS_EXTENSIONS */
+
+#ifndef NO_WOLFSSL_CLIENT
+
+#ifndef NO_OLD_TLS
+
+    WOLFSSL_METHOD* wolfTLSv1_client_method(void)
+    {
+        WOLFSSL_METHOD* method =
+                             (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
+                                                      DYNAMIC_TYPE_METHOD);
+        if (method)
+            InitSSL_Method(method, MakeTLSv1());
+        return method;
+    }
+
+
+    WOLFSSL_METHOD* wolfTLSv1_1_client_method(void)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
+                                                       DYNAMIC_TYPE_METHOD);
+        if (method)
+            InitSSL_Method(method, MakeTLSv1_1());
+        return method;
+    }
+
+#endif /* !NO_OLD_TLS */
+
+#ifndef NO_SHA256   /* can't use without SHA256 */
+
+    WOLFSSL_METHOD* wolfTLSv1_2_client_method(void)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
+                                                       DYNAMIC_TYPE_METHOD);
+        if (method)
+            InitSSL_Method(method, MakeTLSv1_2());
+        return method;
+    }
+
+#endif
+
+
+    WOLFSSL_METHOD* wolfSSLv23_client_method(void)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
+                                                       DYNAMIC_TYPE_METHOD);
+        if (method) {
+#ifndef NO_SHA256         /* 1.2 requires SHA256 */
+            InitSSL_Method(method, MakeTLSv1_2());
+#else
+            InitSSL_Method(method, MakeTLSv1_1());
+#endif
+#ifndef NO_OLD_TLS
+            method->downgrade = 1;
+#endif
+        }
+        return method;
+    }
+
+
+#endif /* NO_WOLFSSL_CLIENT */
+
+
+
+#ifndef NO_WOLFSSL_SERVER
+
+#ifndef NO_OLD_TLS
+
+    WOLFSSL_METHOD* wolfTLSv1_server_method(void)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
+                                                       DYNAMIC_TYPE_METHOD);
+        if (method) {
+            InitSSL_Method(method, MakeTLSv1());
+            method->side = WOLFSSL_SERVER_END;
+        }
+        return method;
+    }
+
+
+    WOLFSSL_METHOD* wolfTLSv1_1_server_method(void)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
+                                                       DYNAMIC_TYPE_METHOD);
+        if (method) {
+            InitSSL_Method(method, MakeTLSv1_1());
+            method->side = WOLFSSL_SERVER_END;
+        }
+        return method;
+    }
+
+#endif /* !NO_OLD_TLS */
+
+#ifndef NO_SHA256   /* can't use without SHA256 */
+
+    WOLFSSL_METHOD* wolfTLSv1_2_server_method(void)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
+                                                       DYNAMIC_TYPE_METHOD);
+        if (method) {
+            InitSSL_Method(method, MakeTLSv1_2());
+            method->side = WOLFSSL_SERVER_END;
+        }
+        return method;
+    }
+
+#endif
+
+
+    WOLFSSL_METHOD* wolfSSLv23_server_method(void)
+    {
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
+                                                       DYNAMIC_TYPE_METHOD);
+        if (method) {
+#ifndef NO_SHA256         /* 1.2 requires SHA256 */
+            InitSSL_Method(method, MakeTLSv1_2());
+#else
+            InitSSL_Method(method, MakeTLSv1_1());
+#endif
+            method->side      = WOLFSSL_SERVER_END;
+#ifndef NO_OLD_TLS
+            method->downgrade = 1;
+#endif /* !NO_OLD_TLS */
+        }
+        return method;
+    }
+
+
+
+#endif /* NO_WOLFSSL_SERVER */
+#endif /* NO_TLS */
+#endif /* WOLFCRYPT_ONLY */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/aes.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/aes.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/aes.c	(revision 164)
@@ -0,0 +1,3796 @@
+/* aes.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_AES
+
+#include <wolfssl/wolfcrypt/aes.h>
+
+#ifdef HAVE_FIPS
+int wc_AesSetKey(Aes* aes, const byte* key, word32 len, const byte* iv,
+                          int dir)
+{
+    return AesSetKey_fips(aes, key, len, iv, dir);
+}
+
+
+int wc_AesSetIV(Aes* aes, const byte* iv)
+{
+    return AesSetIV_fips(aes, iv);
+}
+
+
+int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    return AesCbcEncrypt_fips(aes, out, in, sz);
+}
+
+
+int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    return AesCbcDecrypt_fips(aes, out, in, sz);
+}
+
+
+/* AES-CTR */
+#ifdef WOLFSSL_AES_COUNTER
+void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+{
+    AesCtrEncrypt(aes, out, in, sz);
+}
+#endif
+
+/* AES-DIRECT */
+#if defined(WOLFSSL_AES_DIRECT)
+void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
+{
+    AesEncryptDirect(aes, out, in);
+}
+
+
+void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
+{
+    AesDecryptDirect(aes, out, in);
+}
+
+
+int wc_AesSetKeyDirect(Aes* aes, const byte* key, word32 len,
+                                const byte* iv, int dir)
+{
+    return AesSetKeyDirect(aes, key, len, iv, dir);
+}
+#endif
+
+
+#ifdef HAVE_AESGCM
+int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
+{
+    return AesGcmSetKey_fips(aes, key, len);
+}
+
+
+int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
+                              const byte* iv, word32 ivSz,
+                              byte* authTag, word32 authTagSz,
+                              const byte* authIn, word32 authInSz)
+{
+    return AesGcmEncrypt_fips(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
+                              authIn, authInSz);
+}
+
+
+int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
+                              const byte* iv, word32 ivSz,
+                              const byte* authTag, word32 authTagSz,
+                              const byte* authIn, word32 authInSz)
+{
+    return AesGcmDecrypt_fips(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
+                              authIn, authInSz);
+}
+
+
+int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
+{
+    return GmacSetKey(gmac, key, len);
+}
+
+
+int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
+                              const byte* authIn, word32 authInSz,
+                              byte* authTag, word32 authTagSz)
+{
+    return GmacUpdate(gmac, iv, ivSz, authIn, authInSz,
+                      authTag, authTagSz);
+}
+
+#endif /* HAVE_AESGCM */
+#ifdef HAVE_AESCCM
+void wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
+{
+    AesCcmSetKey(aes, key, keySz);
+}
+
+
+int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
+                              const byte* nonce, word32 nonceSz,
+                              byte* authTag, word32 authTagSz,
+                              const byte* authIn, word32 authInSz)
+{
+    /* sanity check on arugments */
+    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
+            || authTag == NULL || nonceSz < 7 || nonceSz > 13)
+        return BAD_FUNC_ARG;
+
+    AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz, authTag, authTagSz,
+                  authIn, authInSz);
+    return 0;
+}
+
+
+int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
+                              const byte* nonce, word32 nonceSz,
+                              const byte* authTag, word32 authTagSz,
+                              const byte* authIn, word32 authInSz)
+{
+    return AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz, authTag, authTagSz,
+                         authIn, authInSz);
+}
+#endif /* HAVE_AESCCM */
+
+#ifdef HAVE_CAVIUM
+int  wc_AesInitCavium(Aes* aes, int i)
+{
+    return AesInitCavium(aes, i);
+}
+
+
+void wc_AesFreeCavium(Aes* aes)
+{
+    AesFreeCavium(aes);
+}
+#endif
+#else /* HAVE_FIPS */
+
+#ifdef WOLFSSL_TI_CRYPT
+#include <wolfcrypt/src/port/ti/ti-aes.c>
+#else
+
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+#ifdef DEBUG_AESNI
+    #include <stdio.h>
+#endif
+
+
+#ifdef _MSC_VER
+    /* 4127 warning constant while(1)  */
+    #pragma warning(disable: 4127)
+#endif
+
+
+#if defined(STM32F2_CRYPTO)
+     /* STM32F2 hardware AES support for CBC, CTR modes through the STM32F2
+      * Standard Peripheral Library. Documentation located in STM32F2xx
+      * Standard Peripheral Library document (See note in README).
+      * NOTE: no support for AES-GCM/CCM/Direct */
+    #include "stm32f2xx.h"
+    #include "stm32f2xx_cryp.h"
+#elif defined(HAVE_COLDFIRE_SEC)
+    /* Freescale Coldfire SEC support for CBC mode.
+     * NOTE: no support for AES-CTR/GCM/CCM/Direct */
+    #include <wolfssl/wolfcrypt/types.h>
+    #include "sec.h"
+    #include "mcf5475_sec.h"
+    #include "mcf5475_siu.h"
+#elif defined(FREESCALE_MMCAU)
+    /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
+     * through the CAU/mmCAU library. Documentation located in
+     * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
+     * Guide (See note in README).
+     * NOTE: no support for AES-CTR */
+    #include "cau_api.h"
+
+    static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+    {    
+        int ret = wolfSSL_CryptHwMutexLock();
+        if(ret == 0) {
+            cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
+            wolfSSL_CryptHwMutexUnLock();
+        }
+        return ret;
+    }
+    static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+    {    
+        int ret = wolfSSL_CryptHwMutexLock();
+        if(ret == 0) {
+            cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
+            wolfSSL_CryptHwMutexUnLock();
+        }
+        return ret;
+    }
+#elif defined(WOLFSSL_PIC32MZ_CRYPT)
+    /* NOTE: no support for AES-CCM/Direct */
+    #define DEBUG_WOLFSSL
+    #include "wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h"
+#elif defined(HAVE_CAVIUM)
+    #include <wolfssl/wolfcrypt/logging.h>
+    #include "cavium_common.h"
+
+    /* still leave SW crypto available */
+    #define NEED_AES_TABLES
+
+    static int  wc_AesCaviumSetKey(Aes* aes, const byte* key, word32 length,
+                                const byte* iv);
+    static int  wc_AesCaviumCbcEncrypt(Aes* aes, byte* out, const byte* in,
+                                    word32 length);
+    static int  wc_AesCaviumCbcDecrypt(Aes* aes, byte* out, const byte* in,
+                                    word32 length);
+#else
+    /* using CTaoCrypt software AES implementation */
+    #define NEED_AES_TABLES
+#endif /* STM32F2_CRYPTO */
+
+
+#ifdef NEED_AES_TABLES
+
+static const word32 rcon[] = {
+    0x01000000, 0x02000000, 0x04000000, 0x08000000,
+    0x10000000, 0x20000000, 0x40000000, 0x80000000,
+    0x1B000000, 0x36000000,
+    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+static const word32 Te[5][256] = {
+{
+    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+},
+{
+    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+},
+{
+    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+},
+{
+    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+},
+{
+    0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+    0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+    0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+    0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+    0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+    0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+    0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+    0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+    0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+    0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+    0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+    0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+    0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+    0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+    0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+    0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+    0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+    0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+    0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+    0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+    0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+    0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+    0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+    0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+    0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+    0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+    0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+    0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+    0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+    0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+    0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+    0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+    0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+    0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+    0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
+    0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
+    0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
+    0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
+    0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
+    0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
+    0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
+    0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
+    0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
+    0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
+    0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
+    0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
+    0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
+    0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
+    0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
+    0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
+    0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
+    0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
+    0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
+    0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
+    0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
+    0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
+    0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
+    0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
+    0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
+    0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
+    0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
+    0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
+    0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
+    0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
+}
+};
+
+static const word32 Td[5][256] = {
+{
+    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+},
+{
+    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+},
+{
+    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+
+    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+},
+{
+    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+},
+{
+    0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
+    0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
+    0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
+    0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
+    0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
+    0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
+    0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
+    0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
+    0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
+    0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
+    0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
+    0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
+    0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
+    0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
+    0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
+    0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
+    0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
+    0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
+    0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
+    0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
+    0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
+    0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
+    0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
+    0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
+    0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
+    0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
+    0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
+    0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
+    0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
+    0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
+    0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
+    0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
+    0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
+    0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
+    0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
+    0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
+    0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
+    0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
+    0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
+    0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
+    0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
+    0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
+    0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
+    0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
+    0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
+    0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
+    0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
+    0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
+    0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
+    0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
+    0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
+    0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
+    0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
+    0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
+    0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
+    0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
+    0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
+    0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
+    0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
+    0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
+    0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
+    0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
+    0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
+    0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
+}
+};
+
+#define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
+
+#ifdef WOLFSSL_AESNI
+
+/* Each platform needs to query info type 1 from cpuid to see if aesni is
+ * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
+ */
+
+#ifndef _MSC_VER
+
+    #define cpuid(reg, func)\
+        __asm__ __volatile__ ("cpuid":\
+             "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3]) :\
+             "a" (func));
+
+    #define XASM_LINK(f) asm(f)
+#else
+
+    #include <intrin.h>
+    #define cpuid(a,b) __cpuid((int*)a,b)
+
+    #define XASM_LINK(f)
+
+#endif /* _MSC_VER */
+
+
+static int Check_CPU_support_AES(void)
+{
+    unsigned int reg[4];  /* put a,b,c,d into 0,1,2,3 */
+    cpuid(reg, 1);        /* query info 1 */
+
+    if (reg[2] & 0x2000000)
+        return 1;
+
+    return 0;
+}
+
+static int checkAESNI = 0;
+static int haveAESNI  = 0;
+
+
+/* tell C compiler these are asm functions in case any mix up of ABI underscore
+   prefix between clang/gcc/llvm etc */
+void AES_CBC_encrypt(const unsigned char* in, unsigned char* out,
+                     unsigned char* ivec, unsigned long length,
+                     const unsigned char* KS, int nr)
+                     XASM_LINK("AES_CBC_encrypt");
+
+
+void AES_CBC_decrypt(const unsigned char* in, unsigned char* out,
+                     unsigned char* ivec, unsigned long length,
+                     const unsigned char* KS, int nr)
+                     XASM_LINK("AES_CBC_decrypt");
+
+void AES_ECB_encrypt(const unsigned char* in, unsigned char* out,
+                     unsigned long length, const unsigned char* KS, int nr)
+                     XASM_LINK("AES_ECB_encrypt");
+
+
+void AES_ECB_decrypt(const unsigned char* in, unsigned char* out,
+                     unsigned long length, const unsigned char* KS, int nr)
+                     XASM_LINK("AES_ECB_decrypt");
+
+void AES_128_Key_Expansion(const unsigned char* userkey,
+                           unsigned char* key_schedule)
+                           XASM_LINK("AES_128_Key_Expansion");
+
+void AES_192_Key_Expansion(const unsigned char* userkey,
+                           unsigned char* key_schedule)
+                           XASM_LINK("AES_192_Key_Expansion");
+
+void AES_256_Key_Expansion(const unsigned char* userkey,
+                           unsigned char* key_schedule)
+                           XASM_LINK("AES_256_Key_Expansion");
+
+
+static int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+                               Aes* aes)
+{
+    if (!userKey || !aes)
+        return BAD_FUNC_ARG;
+
+    if (bits == 128) {
+       AES_128_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 10;
+       return 0;
+    }
+    else if (bits == 192) {
+       AES_192_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 12;
+       return 0;
+    }
+    else if (bits == 256) {
+       AES_256_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 14;
+       return 0;
+    }
+    return BAD_FUNC_ARG;
+}
+
+
+static int AES_set_decrypt_key(const unsigned char* userKey, const int bits,
+                               Aes* aes)
+{
+    int nr;
+    Aes temp_key;
+    __m128i *Key_Schedule = (__m128i*)aes->key;
+    __m128i *Temp_Key_Schedule = (__m128i*)temp_key.key;
+
+    if (!userKey || !aes)
+        return BAD_FUNC_ARG;
+
+    if (AES_set_encrypt_key(userKey,bits,&temp_key) == BAD_FUNC_ARG)
+        return BAD_FUNC_ARG;
+
+    nr = temp_key.rounds;
+    aes->rounds = nr;
+
+    Key_Schedule[nr] = Temp_Key_Schedule[0];
+    Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
+    Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
+    Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
+    Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
+    Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
+    Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
+    Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
+    Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
+    Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
+
+    if(nr>10) {
+        Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
+        Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
+    }
+
+    if(nr>12) {
+        Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
+        Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
+    }
+
+    Key_Schedule[0] = Temp_Key_Schedule[nr];
+
+    return 0;
+}
+
+
+
+#endif /* WOLFSSL_AESNI */
+
+
+static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+{
+    word32 s0, s1, s2, s3;
+    word32 t0, t1, t2, t3;
+    word32 r = aes->rounds >> 1;
+
+    const word32* rk = aes->key;
+    if (r > 7 || r == 0) {
+        WOLFSSL_MSG("AesEncrypt encountered improper key, set it up");
+        return;  /* stop instead of segfaulting, set up your keys! */
+    }
+#ifdef WOLFSSL_AESNI
+    if (haveAESNI && aes->use_aesni) {
+        #ifdef DEBUG_AESNI
+            printf("about to aes encrypt\n");
+            printf("in  = %p\n", inBlock);
+            printf("out = %p\n", outBlock);
+            printf("aes->key = %p\n", aes->key);
+            printf("aes->rounds = %d\n", aes->rounds);
+            printf("sz = %d\n", AES_BLOCK_SIZE);
+        #endif
+
+        /* check alignment, decrypt doesn't need alignment */
+        if ((wolfssl_word)inBlock % 16) {
+        #ifndef NO_WOLFSSL_ALLOC_ALIGN
+            byte* tmp = (byte*)XMALLOC(AES_BLOCK_SIZE, NULL,
+                                                      DYNAMIC_TYPE_TMP_BUFFER);
+            if (tmp == NULL) return;
+
+            XMEMCPY(tmp, inBlock, AES_BLOCK_SIZE);
+            AES_ECB_encrypt(tmp, tmp, AES_BLOCK_SIZE, (byte*)aes->key,
+                            aes->rounds);
+            XMEMCPY(outBlock, tmp, AES_BLOCK_SIZE);
+            XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return;
+        #else
+            WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
+            return;
+        #endif
+        }
+
+        AES_ECB_encrypt(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,
+                        aes->rounds);
+
+        return;
+    }
+    else {
+        #ifdef DEBUG_AESNI
+            printf("Skipping AES-NI\n");
+        #endif
+    }
+#endif
+
+    /*
+     * map byte array block to cipher state
+     * and add initial round key:
+     */
+    XMEMCPY(&s0, inBlock,                  sizeof(s0));
+    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
+    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
+    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
+
+    #ifdef LITTLE_ENDIAN_ORDER
+        s0 = ByteReverseWord32(s0);
+        s1 = ByteReverseWord32(s1);
+        s2 = ByteReverseWord32(s2);
+        s3 = ByteReverseWord32(s3);
+    #endif
+
+    s0 ^= rk[0];
+    s1 ^= rk[1];
+    s2 ^= rk[2];
+    s3 ^= rk[3];
+
+    /*
+     * Nr - 1 full rounds:
+     */
+
+    for (;;) {
+        t0 =
+            Te[0][GETBYTE(s0, 3)]  ^
+            Te[1][GETBYTE(s1, 2)]  ^
+            Te[2][GETBYTE(s2, 1)]  ^
+            Te[3][GETBYTE(s3, 0)]  ^
+            rk[4];
+        t1 =
+            Te[0][GETBYTE(s1, 3)]  ^
+            Te[1][GETBYTE(s2, 2)]  ^
+            Te[2][GETBYTE(s3, 1)]  ^
+            Te[3][GETBYTE(s0, 0)]  ^
+            rk[5];
+        t2 =
+            Te[0][GETBYTE(s2, 3)] ^
+            Te[1][GETBYTE(s3, 2)]  ^
+            Te[2][GETBYTE(s0, 1)]  ^
+            Te[3][GETBYTE(s1, 0)]  ^
+            rk[6];
+        t3 =
+            Te[0][GETBYTE(s3, 3)] ^
+            Te[1][GETBYTE(s0, 2)]  ^
+            Te[2][GETBYTE(s1, 1)]  ^
+            Te[3][GETBYTE(s2, 0)]  ^
+            rk[7];
+
+        rk += 8;
+        if (--r == 0) {
+            break;
+        }
+
+        s0 =
+            Te[0][GETBYTE(t0, 3)] ^
+            Te[1][GETBYTE(t1, 2)] ^
+            Te[2][GETBYTE(t2, 1)] ^
+            Te[3][GETBYTE(t3, 0)] ^
+            rk[0];
+        s1 =
+            Te[0][GETBYTE(t1, 3)] ^
+            Te[1][GETBYTE(t2, 2)] ^
+            Te[2][GETBYTE(t3, 1)] ^
+            Te[3][GETBYTE(t0, 0)] ^
+            rk[1];
+        s2 =
+            Te[0][GETBYTE(t2, 3)] ^
+            Te[1][GETBYTE(t3, 2)] ^
+            Te[2][GETBYTE(t0, 1)] ^
+            Te[3][GETBYTE(t1, 0)] ^
+            rk[2];
+        s3 =
+            Te[0][GETBYTE(t3, 3)] ^
+            Te[1][GETBYTE(t0, 2)] ^
+            Te[2][GETBYTE(t1, 1)] ^
+            Te[3][GETBYTE(t2, 0)] ^
+            rk[3];
+    }
+
+    /*
+     * apply last round and
+     * map cipher state to byte array block:
+     */
+
+    s0 =
+        (Te[4][GETBYTE(t0, 3)] & 0xff000000) ^
+        (Te[4][GETBYTE(t1, 2)] & 0x00ff0000) ^
+        (Te[4][GETBYTE(t2, 1)] & 0x0000ff00) ^
+        (Te[4][GETBYTE(t3, 0)] & 0x000000ff) ^
+        rk[0];
+    s1 =
+        (Te[4][GETBYTE(t1, 3)] & 0xff000000) ^
+        (Te[4][GETBYTE(t2, 2)] & 0x00ff0000) ^
+        (Te[4][GETBYTE(t3, 1)] & 0x0000ff00) ^
+        (Te[4][GETBYTE(t0, 0)] & 0x000000ff) ^
+        rk[1];
+    s2 =
+        (Te[4][GETBYTE(t2, 3)] & 0xff000000) ^
+        (Te[4][GETBYTE(t3, 2)] & 0x00ff0000) ^
+        (Te[4][GETBYTE(t0, 1)] & 0x0000ff00) ^
+        (Te[4][GETBYTE(t1, 0)] & 0x000000ff) ^
+        rk[2];
+    s3 =
+        (Te[4][GETBYTE(t3, 3)] & 0xff000000) ^
+        (Te[4][GETBYTE(t0, 2)] & 0x00ff0000) ^
+        (Te[4][GETBYTE(t1, 1)] & 0x0000ff00) ^
+        (Te[4][GETBYTE(t2, 0)] & 0x000000ff) ^
+        rk[3];
+
+    /* write out */
+    #ifdef LITTLE_ENDIAN_ORDER
+        s0 = ByteReverseWord32(s0);
+        s1 = ByteReverseWord32(s1);
+        s2 = ByteReverseWord32(s2);
+        s3 = ByteReverseWord32(s3);
+    #endif
+
+    XMEMCPY(outBlock,                  &s0, sizeof(s0));
+    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
+    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
+    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
+}
+
+static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+{
+    word32 s0, s1, s2, s3;
+    word32 t0, t1, t2, t3;
+    word32 r = aes->rounds >> 1;
+
+    const word32* rk = aes->key;
+    if (r > 7 || r == 0) {
+        WOLFSSL_MSG("AesDecrypt encountered improper key, set it up");
+        return;  /* stop instead of segfaulting, set up your keys! */
+    }
+#ifdef WOLFSSL_AESNI
+    if (haveAESNI && aes->use_aesni) {
+        #ifdef DEBUG_AESNI
+            printf("about to aes decrypt\n");
+            printf("in  = %p\n", inBlock);
+            printf("out = %p\n", outBlock);
+            printf("aes->key = %p\n", aes->key);
+            printf("aes->rounds = %d\n", aes->rounds);
+            printf("sz = %d\n", AES_BLOCK_SIZE);
+        #endif
+
+        /* if input and output same will overwrite input iv */
+        XMEMCPY(aes->tmp, inBlock, AES_BLOCK_SIZE);
+        AES_ECB_decrypt(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,
+                        aes->rounds);
+        return;
+    }
+    else {
+        #ifdef DEBUG_AESNI
+            printf("Skipping AES-NI\n");
+        #endif
+    }
+#endif
+
+    /*
+     * map byte array block to cipher state
+     * and add initial round key:
+     */
+    XMEMCPY(&s0, inBlock,                  sizeof(s0));
+    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
+    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
+    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
+
+    #ifdef LITTLE_ENDIAN_ORDER
+        s0 = ByteReverseWord32(s0);
+        s1 = ByteReverseWord32(s1);
+        s2 = ByteReverseWord32(s2);
+        s3 = ByteReverseWord32(s3);
+    #endif
+
+    s0 ^= rk[0];
+    s1 ^= rk[1];
+    s2 ^= rk[2];
+    s3 ^= rk[3];
+
+    /*
+     * Nr - 1 full rounds:
+     */
+
+    for (;;) {
+        t0 =
+            Td[0][GETBYTE(s0, 3)] ^
+            Td[1][GETBYTE(s3, 2)] ^
+            Td[2][GETBYTE(s2, 1)] ^
+            Td[3][GETBYTE(s1, 0)] ^
+            rk[4];
+        t1 =
+            Td[0][GETBYTE(s1, 3)] ^
+            Td[1][GETBYTE(s0, 2)] ^
+            Td[2][GETBYTE(s3, 1)] ^
+            Td[3][GETBYTE(s2, 0)] ^
+            rk[5];
+        t2 =
+            Td[0][GETBYTE(s2, 3)] ^
+            Td[1][GETBYTE(s1, 2)] ^
+            Td[2][GETBYTE(s0, 1)] ^
+            Td[3][GETBYTE(s3, 0)] ^
+            rk[6];
+        t3 =
+            Td[0][GETBYTE(s3, 3)] ^
+            Td[1][GETBYTE(s2, 2)] ^
+            Td[2][GETBYTE(s1, 1)] ^
+            Td[3][GETBYTE(s0, 0)] ^
+            rk[7];
+
+        rk += 8;
+        if (--r == 0) {
+            break;
+        }
+
+        s0 =
+            Td[0][GETBYTE(t0, 3)] ^
+            Td[1][GETBYTE(t3, 2)] ^
+            Td[2][GETBYTE(t2, 1)] ^
+            Td[3][GETBYTE(t1, 0)] ^
+            rk[0];
+        s1 =
+            Td[0][GETBYTE(t1, 3)] ^
+            Td[1][GETBYTE(t0, 2)] ^
+            Td[2][GETBYTE(t3, 1)] ^
+            Td[3][GETBYTE(t2, 0)] ^
+            rk[1];
+        s2 =
+            Td[0][GETBYTE(t2, 3)] ^
+            Td[1][GETBYTE(t1, 2)] ^
+            Td[2][GETBYTE(t0, 1)] ^
+            Td[3][GETBYTE(t3, 0)] ^
+            rk[2];
+        s3 =
+            Td[0][GETBYTE(t3, 3)] ^
+            Td[1][GETBYTE(t2, 2)] ^
+            Td[2][GETBYTE(t1, 1)] ^
+            Td[3][GETBYTE(t0, 0)] ^
+            rk[3];
+    }
+    /*
+     * apply last round and
+     * map cipher state to byte array block:
+     */
+    s0 =
+        (Td[4][GETBYTE(t0, 3)] & 0xff000000) ^
+        (Td[4][GETBYTE(t3, 2)] & 0x00ff0000) ^
+        (Td[4][GETBYTE(t2, 1)] & 0x0000ff00) ^
+        (Td[4][GETBYTE(t1, 0)] & 0x000000ff) ^
+        rk[0];
+    s1 =
+        (Td[4][GETBYTE(t1, 3)] & 0xff000000) ^
+        (Td[4][GETBYTE(t0, 2)] & 0x00ff0000) ^
+        (Td[4][GETBYTE(t3, 1)] & 0x0000ff00) ^
+        (Td[4][GETBYTE(t2, 0)] & 0x000000ff) ^
+        rk[1];
+    s2 =
+        (Td[4][GETBYTE(t2, 3)] & 0xff000000) ^
+        (Td[4][GETBYTE(t1, 2)] & 0x00ff0000) ^
+        (Td[4][GETBYTE(t0, 1)] & 0x0000ff00) ^
+        (Td[4][GETBYTE(t3, 0)] & 0x000000ff) ^
+        rk[2];
+    s3 =
+        (Td[4][GETBYTE(t3, 3)] & 0xff000000) ^
+        (Td[4][GETBYTE(t2, 2)] & 0x00ff0000) ^
+        (Td[4][GETBYTE(t1, 1)] & 0x0000ff00) ^
+        (Td[4][GETBYTE(t0, 0)] & 0x000000ff) ^
+        rk[3];
+
+    /* write out */
+    #ifdef LITTLE_ENDIAN_ORDER
+        s0 = ByteReverseWord32(s0);
+        s1 = ByteReverseWord32(s1);
+        s2 = ByteReverseWord32(s2);
+        s3 = ByteReverseWord32(s3);
+    #endif
+
+    XMEMCPY(outBlock,                  &s0, sizeof(s0));
+    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
+    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
+    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
+}
+
+#endif /* NEED_AES_TABLES */
+
+
+/* wc_AesSetKey */
+#ifdef STM32F2_CRYPTO
+    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
+                  int dir)
+    {
+        word32 *rk = aes->key;
+
+        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
+            return BAD_FUNC_ARG;
+
+        aes->rounds = keylen/4 + 6;
+        XMEMCPY(rk, userKey, keylen);
+        ByteReverseWords(rk, rk, keylen);
+
+        return wc_AesSetIV(aes, iv);
+    }
+
+    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
+                        const byte* iv, int dir)
+    {
+        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
+    }
+
+#elif defined(HAVE_COLDFIRE_SEC)
+    #if defined (HAVE_THREADX)
+        #include "memory_pools.h"
+        extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
+    #endif
+
+    #define AES_BUFFER_SIZE (AES_BLOCK_SIZE * 64)
+    static unsigned char *AESBuffIn = NULL;
+    static unsigned char *AESBuffOut = NULL;
+    static byte *secReg;
+    static byte *secKey;
+    static volatile SECdescriptorType *secDesc;
+
+    static wolfSSL_Mutex Mutex_AesSEC;
+
+    #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
+    #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
+
+    extern volatile unsigned char __MBAR[];
+
+    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
+                  int dir)
+    {
+        if (AESBuffIn == NULL) {
+            #if defined (HAVE_THREADX)
+			    int s1, s2, s3, s4, s5 ;
+                s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
+                                      sizeof(SECdescriptorType), TX_NO_WAIT);
+                s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
+                                      AES_BUFFER_SIZE, TX_NO_WAIT);
+                s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
+                                      AES_BUFFER_SIZE, TX_NO_WAIT);
+                s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
+                                      AES_BLOCK_SIZE*2, TX_NO_WAIT);
+                s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
+                                      AES_BLOCK_SIZE, TX_NO_WAIT);
+
+                if(s1 || s2 || s3 || s4 || s5)
+                    return BAD_FUNC_ARG;
+            #else
+                #warning "Allocate non-Cache buffers"
+            #endif
+
+            InitMutex(&Mutex_AesSEC);
+        }
+
+        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
+            return BAD_FUNC_ARG;
+
+        if (aes == NULL)
+            return BAD_FUNC_ARG;
+
+        aes->rounds = keylen/4 + 6;
+        XMEMCPY(aes->key, userKey, keylen);
+
+        if (iv)
+            XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
+
+        return 0;
+    }
+#elif defined(FREESCALE_MMCAU)
+    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
+                  int dir)
+    {
+        int ret;
+        byte *rk = (byte*)aes->key;
+
+        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
+            return BAD_FUNC_ARG;
+
+        if (rk == NULL)
+            return BAD_FUNC_ARG;
+
+        aes->rounds = keylen/4 + 6;
+		
+        ret = wolfSSL_CryptHwMutexLock();
+        if(ret == 0) {
+            cau_aes_set_key(userKey, keylen*8, rk);
+            wolfSSL_CryptHwMutexUnLock();
+            
+            ret = wc_AesSetIV(aes, iv);
+        }
+        
+        return ret;
+    }
+
+    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
+                        const byte* iv, int dir)
+    {
+        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
+    }
+#else
+    static int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
+                const byte* iv, int dir)
+    {
+        word32 temp, *rk = aes->key;
+        unsigned int i = 0;
+
+        #ifdef WOLFSSL_AESNI
+            aes->use_aesni = 0;
+        #endif /* WOLFSSL_AESNI */
+        #ifdef WOLFSSL_AES_COUNTER
+            aes->left = 0;
+        #endif /* WOLFSSL_AES_COUNTER */
+
+        aes->rounds = keylen/4 + 6;
+
+        XMEMCPY(rk, userKey, keylen);
+        #ifdef LITTLE_ENDIAN_ORDER
+            ByteReverseWords(rk, rk, keylen);
+        #endif
+
+        #ifdef WOLFSSL_PIC32MZ_CRYPT
+        {
+            word32 *akey1 = aes->key_ce;
+            word32 *areg = aes->iv_ce ;
+            aes->keylen = keylen ;
+            XMEMCPY(akey1, userKey, keylen);
+            if (iv)
+                XMEMCPY(areg, iv, AES_BLOCK_SIZE);
+            else
+                XMEMSET(areg,  0, AES_BLOCK_SIZE);
+        }
+        #endif
+
+        switch(keylen)
+        {
+        case 16:
+            while (1)
+            {
+                temp  = rk[3];
+                rk[4] = rk[0] ^
+                    (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
+                    (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
+                    (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
+                    (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
+                    rcon[i];
+                rk[5] = rk[1] ^ rk[4];
+                rk[6] = rk[2] ^ rk[5];
+                rk[7] = rk[3] ^ rk[6];
+                if (++i == 10)
+                    break;
+                rk += 4;
+            }
+            break;
+
+        case 24:
+            /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
+            while (1)
+            {
+                temp = rk[ 5];
+                rk[ 6] = rk[ 0] ^
+                    (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
+                    (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
+                    (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
+                    (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
+                    rcon[i];
+                rk[ 7] = rk[ 1] ^ rk[ 6];
+                rk[ 8] = rk[ 2] ^ rk[ 7];
+                rk[ 9] = rk[ 3] ^ rk[ 8];
+                if (++i == 8)
+                    break;
+                rk[10] = rk[ 4] ^ rk[ 9];
+                rk[11] = rk[ 5] ^ rk[10];
+                rk += 6;
+            }
+            break;
+
+        case 32:
+            while (1)
+            {
+                temp = rk[ 7];
+                rk[ 8] = rk[ 0] ^
+                    (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
+                    (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
+                    (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
+                    (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
+                    rcon[i];
+                rk[ 9] = rk[ 1] ^ rk[ 8];
+                rk[10] = rk[ 2] ^ rk[ 9];
+                rk[11] = rk[ 3] ^ rk[10];
+                if (++i == 7)
+                    break;
+                temp = rk[11];
+                rk[12] = rk[ 4] ^
+                    (Te[4][GETBYTE(temp, 3)] & 0xff000000) ^
+                    (Te[4][GETBYTE(temp, 2)] & 0x00ff0000) ^
+                    (Te[4][GETBYTE(temp, 1)] & 0x0000ff00) ^
+                    (Te[4][GETBYTE(temp, 0)] & 0x000000ff);
+                rk[13] = rk[ 5] ^ rk[12];
+                rk[14] = rk[ 6] ^ rk[13];
+                rk[15] = rk[ 7] ^ rk[14];
+
+                rk += 8;
+            }
+            break;
+
+        default:
+            return BAD_FUNC_ARG;
+        }
+
+        if (dir == AES_DECRYPTION)
+        {
+            unsigned int j;
+            rk = aes->key;
+
+            /* invert the order of the round keys: */
+            for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
+                temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
+                temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+                temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+                temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+            }
+            /* apply the inverse MixColumn transform to all round keys but the
+               first and the last: */
+            for (i = 1; i < aes->rounds; i++) {
+                rk += 4;
+                rk[0] =
+                    Td[0][Te[4][GETBYTE(rk[0], 3)] & 0xff] ^
+                    Td[1][Te[4][GETBYTE(rk[0], 2)] & 0xff] ^
+                    Td[2][Te[4][GETBYTE(rk[0], 1)] & 0xff] ^
+                    Td[3][Te[4][GETBYTE(rk[0], 0)] & 0xff];
+                rk[1] =
+                    Td[0][Te[4][GETBYTE(rk[1], 3)] & 0xff] ^
+                    Td[1][Te[4][GETBYTE(rk[1], 2)] & 0xff] ^
+                    Td[2][Te[4][GETBYTE(rk[1], 1)] & 0xff] ^
+                    Td[3][Te[4][GETBYTE(rk[1], 0)] & 0xff];
+                rk[2] =
+                    Td[0][Te[4][GETBYTE(rk[2], 3)] & 0xff] ^
+                    Td[1][Te[4][GETBYTE(rk[2], 2)] & 0xff] ^
+                    Td[2][Te[4][GETBYTE(rk[2], 1)] & 0xff] ^
+                    Td[3][Te[4][GETBYTE(rk[2], 0)] & 0xff];
+                rk[3] =
+                    Td[0][Te[4][GETBYTE(rk[3], 3)] & 0xff] ^
+                    Td[1][Te[4][GETBYTE(rk[3], 2)] & 0xff] ^
+                    Td[2][Te[4][GETBYTE(rk[3], 1)] & 0xff] ^
+                    Td[3][Te[4][GETBYTE(rk[3], 0)] & 0xff];
+            }
+        }
+
+        return wc_AesSetIV(aes, iv);
+    }
+
+    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
+                  int dir)
+    {
+
+        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
+            return BAD_FUNC_ARG;
+
+        #ifdef HAVE_CAVIUM
+        if (aes->magic == WOLFSSL_AES_CAVIUM_MAGIC)
+            return wc_AesCaviumSetKey(aes, userKey, keylen, iv);
+        #endif
+
+        #ifdef WOLFSSL_AESNI
+        if (checkAESNI == 0) {
+            haveAESNI  = Check_CPU_support_AES();
+            checkAESNI = 1;
+        }
+        if (haveAESNI) {
+            aes->use_aesni = 1;
+            if (iv)
+                XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
+            if (dir == AES_ENCRYPTION)
+                return AES_set_encrypt_key(userKey, keylen * 8, aes);
+            else
+                return AES_set_decrypt_key(userKey, keylen * 8, aes);
+        }
+        #endif /* WOLFSSL_AESNI */
+
+        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);
+    }
+
+    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
+
+    /* AES-CTR and AES-DIRECT need to use this for key setup, no aesni yet */
+    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
+                        const byte* iv, int dir)
+    {
+        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);
+    }
+
+    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
+#endif /* STM32F2_CRYPTO, wc_AesSetKey block */
+
+
+/* wc_AesSetIV is shared between software and hardware */
+int wc_AesSetIV(Aes* aes, const byte* iv)
+{
+    if (aes == NULL)
+        return BAD_FUNC_ARG;
+
+    if (iv)
+        XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
+    else
+        XMEMSET(aes->reg,  0, AES_BLOCK_SIZE);
+
+    return 0;
+}
+
+
+
+
+/* AES-DIRECT */
+#if defined(WOLFSSL_AES_DIRECT)
+    #if defined(STM32F2_CRYPTO)
+        #error "STM32F2 crypto doesn't yet support AES direct"
+
+    #elif defined(HAVE_COLDFIRE_SEC)
+        #error "Coldfire SEC doesn't yet support AES direct"
+
+    #elif defined(WOLFSSL_PIC32MZ_CRYPT)
+        #error "PIC32MZ doesn't yet support AES direct"
+
+    #else
+        /* Allow direct access to one block encrypt */
+        void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
+        {
+            wc_AesEncrypt(aes, in, out);
+        }
+
+        /* Allow direct access to one block decrypt */
+        void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
+        {
+            wc_AesDecrypt(aes, in, out);
+        }
+
+    #endif /* AES direct block */
+#endif /* WOLFSSL_AES_DIRECT */
+
+
+/* AES-CBC */
+#ifdef STM32F2_CRYPTO
+    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        word32 *enc_key, *iv;
+        CRYP_InitTypeDef AES_CRYP_InitStructure;
+        CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
+        CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
+
+        enc_key = aes->key;
+        iv = aes->reg;
+
+        /* crypto structure initialization */
+        CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
+        CRYP_StructInit(&AES_CRYP_InitStructure);
+        CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
+
+        /* reset registers to their default values */
+        CRYP_DeInit();
+
+        /* load key into correct registers */
+        switch(aes->rounds)
+        {
+            case 10: /* 128-bit key */
+                AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
+                AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[0];
+                AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1];
+                AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[2];
+                AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3];
+                break;
+
+            case 12: /* 192-bit key */
+                AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
+                AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[0];
+                AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1];
+                AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[2];
+                AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3];
+                AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[4];
+                AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5];
+                break;
+
+            case 14: /* 256-bit key */
+                AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
+                AES_CRYP_KeyInitStructure.CRYP_Key0Left  = enc_key[0];
+                AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1];
+                AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[2];
+                AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3];
+                AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[4];
+                AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5];
+                AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[6];
+                AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7];
+                break;
+
+            default:
+                break;
+        }
+        CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
+
+        /* set iv */
+        ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
+        AES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
+        AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
+        AES_CRYP_IVInitStructure.CRYP_IV1Left  = iv[2];
+        AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3];
+        CRYP_IVInit(&AES_CRYP_IVInitStructure);
+
+        /* set direction, mode, and datatype */
+        AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
+        AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
+        AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
+        CRYP_Init(&AES_CRYP_InitStructure);
+
+        /* enable crypto processor */
+        CRYP_Cmd(ENABLE);
+
+        while (sz > 0)
+        {
+            /* flush IN/OUT FIFOs */
+            CRYP_FIFOFlush();
+
+            CRYP_DataIn(*(uint32_t*)&in[0]);
+            CRYP_DataIn(*(uint32_t*)&in[4]);
+            CRYP_DataIn(*(uint32_t*)&in[8]);
+            CRYP_DataIn(*(uint32_t*)&in[12]);
+
+            /* wait until the complete message has been processed */
+            while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+            *(uint32_t*)&out[0]  = CRYP_DataOut();
+            *(uint32_t*)&out[4]  = CRYP_DataOut();
+            *(uint32_t*)&out[8]  = CRYP_DataOut();
+            *(uint32_t*)&out[12] = CRYP_DataOut();
+
+            /* store iv for next call */
+            XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+
+            sz  -= 16;
+            in  += 16;
+            out += 16;
+        }
+
+        /* disable crypto processor */
+        CRYP_Cmd(DISABLE);
+
+        return 0;
+    }
+
+    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        word32 *dec_key, *iv;
+        CRYP_InitTypeDef AES_CRYP_InitStructure;
+        CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
+        CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
+
+        dec_key = aes->key;
+        iv = aes->reg;
+
+        /* crypto structure initialization */
+        CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
+        CRYP_StructInit(&AES_CRYP_InitStructure);
+        CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
+
+        /* if input and output same will overwrite input iv */
+        XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+
+        /* reset registers to their default values */
+        CRYP_DeInit();
+
+        /* load key into correct registers */
+        switch(aes->rounds)
+        {
+            case 10: /* 128-bit key */
+                AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
+                AES_CRYP_KeyInitStructure.CRYP_Key2Left  = dec_key[0];
+                AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[1];
+                AES_CRYP_KeyInitStructure.CRYP_Key3Left  = dec_key[2];
+                AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[3];
+                break;
+
+            case 12: /* 192-bit key */
+                AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
+                AES_CRYP_KeyInitStructure.CRYP_Key1Left  = dec_key[0];
+                AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[1];
+                AES_CRYP_KeyInitStructure.CRYP_Key2Left  = dec_key[2];
+                AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[3];
+                AES_CRYP_KeyInitStructure.CRYP_Key3Left  = dec_key[4];
+                AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[5];
+                break;
+
+            case 14: /* 256-bit key */
+                AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
+                AES_CRYP_KeyInitStructure.CRYP_Key0Left  = dec_key[0];
+                AES_CRYP_KeyInitStructure.CRYP_Key0Right = dec_key[1];
+                AES_CRYP_KeyInitStructure.CRYP_Key1Left  = dec_key[2];
+                AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[3];
+                AES_CRYP_KeyInitStructure.CRYP_Key2Left  = dec_key[4];
+                AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[5];
+                AES_CRYP_KeyInitStructure.CRYP_Key3Left  = dec_key[6];
+                AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[7];
+                break;
+
+            default:
+                break;
+        }
+
+        /* set direction, mode, and datatype for key preparation */
+        AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
+        AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
+        AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b;
+        CRYP_Init(&AES_CRYP_InitStructure);
+        CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
+
+        /* enable crypto processor */
+        CRYP_Cmd(ENABLE);
+
+        /* wait until key has been prepared */
+        while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+        /* set direction, mode, and datatype for decryption */
+        AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
+        AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
+        AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
+        CRYP_Init(&AES_CRYP_InitStructure);
+
+        /* set iv */
+        ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
+
+        AES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
+        AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
+        AES_CRYP_IVInitStructure.CRYP_IV1Left  = iv[2];
+        AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3];
+        CRYP_IVInit(&AES_CRYP_IVInitStructure);
+
+        /* enable crypto processor */
+        CRYP_Cmd(ENABLE);
+
+        while (sz > 0)
+        {
+            /* flush IN/OUT FIFOs */
+            CRYP_FIFOFlush();
+
+            CRYP_DataIn(*(uint32_t*)&in[0]);
+            CRYP_DataIn(*(uint32_t*)&in[4]);
+            CRYP_DataIn(*(uint32_t*)&in[8]);
+            CRYP_DataIn(*(uint32_t*)&in[12]);
+
+            /* wait until the complete message has been processed */
+            while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+            *(uint32_t*)&out[0]  = CRYP_DataOut();
+            *(uint32_t*)&out[4]  = CRYP_DataOut();
+            *(uint32_t*)&out[8]  = CRYP_DataOut();
+            *(uint32_t*)&out[12] = CRYP_DataOut();
+
+            /* store iv for next call */
+            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
+
+            sz -= 16;
+            in += 16;
+            out += 16;
+        }
+
+        /* disable crypto processor */
+        CRYP_Cmd(DISABLE);
+
+        return 0;
+    }
+
+#elif defined(HAVE_COLDFIRE_SEC)
+    static int wc_AesCbcCrypt(Aes* aes, byte* po, const byte* pi, word32 sz,
+                           word32 descHeader)
+    {
+        #ifdef DEBUG_WOLFSSL
+            int i; int stat1, stat2; int ret;
+	    #endif
+
+        int size;
+        volatile int v;
+
+        if ((pi == NULL) || (po == NULL))
+            return BAD_FUNC_ARG;    /*wrong pointer*/
+
+        LockMutex(&Mutex_AesSEC);
+
+        /* Set descriptor for SEC */
+        secDesc->length1 = 0x0;
+        secDesc->pointer1 = NULL;
+
+        secDesc->length2 = AES_BLOCK_SIZE;
+        secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
+
+        switch(aes->rounds) {
+            case 10: secDesc->length3 = 16 ; break ;
+            case 12: secDesc->length3 = 24 ; break ;
+            case 14: secDesc->length3 = 32 ; break ;
+        }
+        XMEMCPY(secKey, aes->key, secDesc->length3);
+
+        secDesc->pointer3 = (byte *)secKey;
+        secDesc->pointer4 = AESBuffIn;
+        secDesc->pointer5 = AESBuffOut;
+        secDesc->length6 = 0x0;
+        secDesc->pointer6 = NULL;
+        secDesc->length7 = 0x0;
+        secDesc->pointer7 = NULL;
+        secDesc->nextDescriptorPtr = NULL;
+
+        while (sz) {
+            secDesc->header = descHeader;
+            XMEMCPY(secReg, aes->reg, AES_BLOCK_SIZE);
+            if ((sz % AES_BUFFER_SIZE) == sz) {
+                size = sz;
+                sz = 0;
+            } else {
+                size = AES_BUFFER_SIZE;
+                sz -= AES_BUFFER_SIZE;
+            }
+            secDesc->length4 = size;
+            secDesc->length5 = size;
+
+            XMEMCPY(AESBuffIn, pi, size);
+            if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
+                XMEMCPY((void*)aes->tmp, (void*)&(pi[size-AES_BLOCK_SIZE]),
+                        AES_BLOCK_SIZE);
+            }
+
+            /* Point SEC to the location of the descriptor */
+            MCF_SEC_FR0 = (uint32)secDesc;
+            /* Initialize SEC and wait for encryption to complete */
+            MCF_SEC_CCCR0 = 0x0000001a;
+            /* poll SISR to determine when channel is complete */
+            v=0;
+
+            while ((secDesc->header>> 24) != 0xff) v++;
+
+            #ifdef DEBUG_WOLFSSL
+                ret = MCF_SEC_SISRH;
+                stat1 = MCF_SEC_AESSR;
+                stat2 = MCF_SEC_AESISR;
+                if (ret & 0xe0000000) {
+                    db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
+                              "AESISR=%08x\n", i, ret, stat1, stat2);
+                }
+            #endif
+
+            XMEMCPY(po, AESBuffOut, size);
+
+            if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
+                XMEMCPY((void*)aes->reg, (void*)&(po[size-AES_BLOCK_SIZE]),
+                        AES_BLOCK_SIZE);
+            } else {
+                XMEMCPY((void*)aes->reg, (void*)aes->tmp, AES_BLOCK_SIZE);
+            }
+
+            pi += size;
+            po += size;
+        }
+
+        UnLockMutex(&Mutex_AesSEC);
+        return 0;
+    }
+
+    int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
+    {
+        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
+    }
+
+    int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
+    {
+        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
+    }
+
+#elif defined(FREESCALE_MMCAU)
+    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        int i;
+        int offset = 0;
+        int len = sz;
+
+        byte *iv;
+        byte temp_block[AES_BLOCK_SIZE];
+
+        iv      = (byte*)aes->reg;
+
+        if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
+            WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
+            return BAD_ALIGN_E;
+        }
+
+        while (len > 0)
+        {
+            XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
+
+            /* XOR block with IV for CBC */
+            for (i = 0; i < AES_BLOCK_SIZE; i++)
+                temp_block[i] ^= iv[i];
+
+            wc_AesEncrypt(aes, temp_block, out + offset);
+
+            len    -= AES_BLOCK_SIZE;
+            offset += AES_BLOCK_SIZE;
+
+            /* store IV for next block */
+            XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+        }
+
+        return 0;
+    }
+
+    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        int i;
+        int offset = 0;
+        int len = sz;
+
+        byte* iv;
+        byte temp_block[AES_BLOCK_SIZE];
+
+        iv      = (byte*)aes->reg;
+
+        if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
+            WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
+            return BAD_ALIGN_E;
+        }
+
+        while (len > 0)
+        {
+            XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
+
+            wc_AesEncrypt(aes, in + offset, out + offset);
+            
+            /* XOR block with IV for CBC */
+            for (i = 0; i < AES_BLOCK_SIZE; i++)
+                (out + offset)[i] ^= iv[i];
+
+            /* store IV for next block */
+            XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
+
+            len    -= AES_BLOCK_SIZE;
+            offset += AES_BLOCK_SIZE;
+        }
+
+        return 0;
+    }
+
+#elif defined(WOLFSSL_PIC32MZ_CRYPT)
+    /* core hardware crypt engine driver */
+    static void wc_AesCrypt(Aes *aes, byte* out, const byte* in, word32 sz,
+                                            int dir, int algo, int cryptoalgo)
+    {
+        securityAssociation *sa_p ;
+        bufferDescriptor *bd_p ;
+
+        volatile securityAssociation sa __attribute__((aligned (8)));
+        volatile bufferDescriptor bd __attribute__((aligned (8)));
+        volatile int k ;
+
+        /* get uncached address */
+        sa_p = KVA0_TO_KVA1(&sa) ;
+        bd_p = KVA0_TO_KVA1(&bd) ;
+
+        /* Sync cache and physical memory */
+        if(PIC32MZ_IF_RAM(in)) {
+            XMEMCPY((void *)KVA0_TO_KVA1(in), (void *)in, sz);
+        }
+        XMEMSET((void *)KVA0_TO_KVA1(out), 0, sz);
+        /* Set up the Security Association */
+        XMEMSET((byte *)KVA0_TO_KVA1(&sa), 0, sizeof(sa));
+        sa_p->SA_CTRL.ALGO = algo ; /* AES */
+        sa_p->SA_CTRL.LNC = 1;
+        sa_p->SA_CTRL.LOADIV = 1;
+        sa_p->SA_CTRL.FB = 1;
+        sa_p->SA_CTRL.ENCTYPE = dir ; /* Encryption/Decryption */
+        sa_p->SA_CTRL.CRYPTOALGO = cryptoalgo;
+
+        if(cryptoalgo == PIC32_CRYPTOALGO_AES_GCM){
+            switch(aes->keylen) {
+            case 32:
+                sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_256 ;
+                break ;
+            case 24:
+                sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_192 ;
+                break ;
+            case 16:
+                sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_128 ;
+                break ;
+            }
+        } else
+            sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_128 ;
+
+        ByteReverseWords(
+        (word32 *)KVA0_TO_KVA1(sa.SA_ENCKEY + 8 - aes->keylen/sizeof(word32)),
+                         (word32 *)aes->key_ce, aes->keylen);
+        ByteReverseWords(
+        (word32*)KVA0_TO_KVA1(sa.SA_ENCIV), (word32 *)aes->iv_ce, 16);
+
+        XMEMSET((byte *)KVA0_TO_KVA1(&bd), 0, sizeof(bd));
+        /* Set up the Buffer Descriptor */
+        bd_p->BD_CTRL.BUFLEN = sz;
+        if(cryptoalgo == PIC32_CRYPTOALGO_AES_GCM) {
+            if(sz % 0x10)
+                bd_p->BD_CTRL.BUFLEN = (sz/0x10 + 1) * 0x10 ;
+        }
+        bd_p->BD_CTRL.LIFM = 1;
+        bd_p->BD_CTRL.SA_FETCH_EN = 1;
+        bd_p->BD_CTRL.LAST_BD = 1;
+        bd_p->BD_CTRL.DESC_EN = 1;
+
+        bd_p->SA_ADDR = (unsigned int)KVA_TO_PA(&sa) ;
+        bd_p->SRCADDR = (unsigned int)KVA_TO_PA(in) ;
+        bd_p->DSTADDR = (unsigned int)KVA_TO_PA(out);
+        bd_p->MSGLEN = sz ;
+
+        CECON = 1 << 6;
+        while (CECON);
+
+        /* Run the engine */
+        CEBDPADDR = (unsigned int)KVA_TO_PA(&bd) ;
+        CEINTEN = 0x07;
+        CECON = 0x27;
+
+        WAIT_ENGINE ;
+
+        if((cryptoalgo == PIC32_CRYPTOALGO_CBC) ||
+           (cryptoalgo == PIC32_CRYPTOALGO_TCBC)||
+           (cryptoalgo == PIC32_CRYPTOALGO_RCBC)) {
+            /* set iv for the next call */
+            if(dir == PIC32_ENCRYPTION) {
+                XMEMCPY((void *)aes->iv_ce,
+                        (void*)KVA0_TO_KVA1(out + sz - AES_BLOCK_SIZE),
+                        AES_BLOCK_SIZE) ;
+            } else {
+                ByteReverseWords((word32*)aes->iv_ce,
+                        (word32 *)KVA0_TO_KVA1(in + sz - AES_BLOCK_SIZE),
+                        AES_BLOCK_SIZE);
+            }
+        }
+        XMEMCPY((byte *)out, (byte *)KVA0_TO_KVA1(out), sz) ;
+        ByteReverseWords((word32*)out, (word32 *)out, sz);
+    }
+
+    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        wc_AesCrypt(aes, out, in, sz, PIC32_ENCRYPTION, PIC32_ALGO_AES,
+                                                      PIC32_CRYPTOALGO_RCBC );
+        return 0 ;
+    }
+
+    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        wc_AesCrypt(aes, out, in, sz, PIC32_DECRYPTION, PIC32_ALGO_AES,
+                                                      PIC32_CRYPTOALGO_RCBC);
+        return 0 ;
+    }
+
+#else
+    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        word32 blocks = sz / AES_BLOCK_SIZE;
+
+    #ifdef HAVE_CAVIUM
+        if (aes->magic == WOLFSSL_AES_CAVIUM_MAGIC)
+            return wc_AesCaviumCbcEncrypt(aes, out, in, sz);
+    #endif
+
+    #ifdef WOLFSSL_AESNI
+        if (haveAESNI) {
+            #ifdef DEBUG_AESNI
+                printf("about to aes cbc encrypt\n");
+                printf("in  = %p\n", in);
+                printf("out = %p\n", out);
+                printf("aes->key = %p\n", aes->key);
+                printf("aes->reg = %p\n", aes->reg);
+                printf("aes->rounds = %d\n", aes->rounds);
+                printf("sz = %d\n", sz);
+            #endif
+
+            /* check alignment, decrypt doesn't need alignment */
+            if ((wolfssl_word)in % 16) {
+            #ifndef NO_WOLFSSL_ALLOC_ALIGN
+                byte* tmp = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
+                if (tmp == NULL) return MEMORY_E;
+
+                XMEMCPY(tmp, in, sz);
+                AES_CBC_encrypt(tmp, tmp, (byte*)aes->reg, sz, (byte*)aes->key,
+                            aes->rounds);
+                /* store iv for next call */
+                XMEMCPY(aes->reg, tmp + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+
+                XMEMCPY(out, tmp, sz);
+                XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                return 0;
+            #else
+                return BAD_ALIGN_E;
+            #endif
+            }
+
+            AES_CBC_encrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
+                            aes->rounds);
+            /* store iv for next call */
+            XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+
+            return 0;
+        }
+    #endif
+
+        while (blocks--) {
+            xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE);
+            wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg);
+            XMEMCPY(out, aes->reg, AES_BLOCK_SIZE);
+
+            out += AES_BLOCK_SIZE;
+            in  += AES_BLOCK_SIZE;
+        }
+
+        return 0;
+    }
+
+    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+    {
+        word32 blocks = sz / AES_BLOCK_SIZE;
+
+    #ifdef HAVE_CAVIUM
+        if (aes->magic == WOLFSSL_AES_CAVIUM_MAGIC)
+            return wc_AesCaviumCbcDecrypt(aes, out, in, sz);
+    #endif
+
+    #ifdef WOLFSSL_AESNI
+        if (haveAESNI) {
+            #ifdef DEBUG_AESNI
+                printf("about to aes cbc decrypt\n");
+                printf("in  = %p\n", in);
+                printf("out = %p\n", out);
+                printf("aes->key = %p\n", aes->key);
+                printf("aes->reg = %p\n", aes->reg);
+                printf("aes->rounds = %d\n", aes->rounds);
+                printf("sz = %d\n", sz);
+            #endif
+
+            /* if input and output same will overwrite input iv */
+            XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+            AES_CBC_decrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
+                            aes->rounds);
+            /* store iv for next call */
+            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
+            return 0;
+        }
+    #endif
+
+        while (blocks--) {
+            XMEMCPY(aes->tmp, in, AES_BLOCK_SIZE);
+            wc_AesDecrypt(aes, (byte*)aes->tmp, out);
+            xorbuf(out, (byte*)aes->reg, AES_BLOCK_SIZE);
+            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
+
+            out += AES_BLOCK_SIZE;
+            in  += AES_BLOCK_SIZE;
+        }
+
+        return 0;
+    }
+
+#endif /* STM32F2_CRYPTO, AES-CBC block */
+
+/* AES-CTR */
+#ifdef WOLFSSL_AES_COUNTER
+
+    #ifdef STM32F2_CRYPTO
+        void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+        {
+            word32 *enc_key, *iv;
+            CRYP_InitTypeDef AES_CRYP_InitStructure;
+            CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
+            CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
+
+            enc_key = aes->key;
+            iv = aes->reg;
+
+            /* crypto structure initialization */
+            CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
+            CRYP_StructInit(&AES_CRYP_InitStructure);
+            CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
+
+            /* reset registers to their default values */
+            CRYP_DeInit();
+
+            /* load key into correct registers */
+            switch(aes->rounds)
+            {
+                case 10: /* 128-bit key */
+                    AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
+                    AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[0];
+                    AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1];
+                    AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[2];
+                    AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3];
+                    break;
+
+                case 12: /* 192-bit key */
+                    AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
+                    AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[0];
+                    AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1];
+                    AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[2];
+                    AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3];
+                    AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[4];
+                    AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5];
+                    break;
+
+                case 14: /* 256-bit key */
+                    AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
+                    AES_CRYP_KeyInitStructure.CRYP_Key0Left  = enc_key[0];
+                    AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1];
+                    AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[2];
+                    AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3];
+                    AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[4];
+                    AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5];
+                    AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[6];
+                    AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7];
+                    break;
+
+                default:
+                    break;
+            }
+            CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
+
+            /* set iv */
+            ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
+            AES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
+            AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
+            AES_CRYP_IVInitStructure.CRYP_IV1Left  = iv[2];
+            AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3];
+            CRYP_IVInit(&AES_CRYP_IVInitStructure);
+
+            /* set direction, mode, and datatype */
+            AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
+            AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
+            AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
+            CRYP_Init(&AES_CRYP_InitStructure);
+
+            /* enable crypto processor */
+            CRYP_Cmd(ENABLE);
+
+            while (sz > 0)
+            {
+                /* flush IN/OUT FIFOs */
+                CRYP_FIFOFlush();
+
+                CRYP_DataIn(*(uint32_t*)&in[0]);
+                CRYP_DataIn(*(uint32_t*)&in[4]);
+                CRYP_DataIn(*(uint32_t*)&in[8]);
+                CRYP_DataIn(*(uint32_t*)&in[12]);
+
+                /* wait until the complete message has been processed */
+                while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+                *(uint32_t*)&out[0]  = CRYP_DataOut();
+                *(uint32_t*)&out[4]  = CRYP_DataOut();
+                *(uint32_t*)&out[8]  = CRYP_DataOut();
+                *(uint32_t*)&out[12] = CRYP_DataOut();
+
+                /* store iv for next call */
+                XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+
+                sz  -= 16;
+                in  += 16;
+                out += 16;
+            }
+
+            /* disable crypto processor */
+            CRYP_Cmd(DISABLE);
+        }
+
+    #elif defined(WOLFSSL_PIC32MZ_CRYPT)
+        void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+        {
+            int i ;
+            char out_block[AES_BLOCK_SIZE] ;
+            int odd ;
+            int even ;
+            char *tmp ; /* (char *)aes->tmp, for short */
+
+            tmp = (char *)aes->tmp ;
+            if(aes->left) {
+                if((aes->left + sz) >= AES_BLOCK_SIZE){
+                    odd = AES_BLOCK_SIZE - aes->left ;
+                } else {
+                    odd = sz ;
+                }
+                XMEMCPY(tmp+aes->left, in, odd) ;
+                if((odd+aes->left) == AES_BLOCK_SIZE){
+                    wc_AesCrypt(aes, out_block, tmp, AES_BLOCK_SIZE,
+                        PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
+                    XMEMCPY(out, out_block+aes->left, odd) ;
+                    aes->left = 0 ;
+                    XMEMSET(tmp, 0x0, AES_BLOCK_SIZE) ;
+                    /* Increment IV */
+                    for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
+                        if (++((byte *)aes->iv_ce)[i])
+                            break ;
+                    }
+                }
+                in += odd ;
+                out+= odd ;
+                sz -= odd ;
+            }
+            odd = sz % AES_BLOCK_SIZE ;  /* if there is tail flagment */
+            if(sz / AES_BLOCK_SIZE) {
+                even = (sz/AES_BLOCK_SIZE)*AES_BLOCK_SIZE ;
+                wc_AesCrypt(aes, out, in, even, PIC32_ENCRYPTION, PIC32_ALGO_AES,
+                                                        PIC32_CRYPTOALGO_RCTR);
+                out += even ;
+                in  += even ;
+                do {  /* Increment IV */
+                    for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
+                        if (++((byte *)aes->iv_ce)[i])
+                            break ;
+                    }
+                    even -= AES_BLOCK_SIZE ;
+                } while((int)even > 0) ;
+            }
+            if(odd) {
+                XMEMSET(tmp+aes->left, 0x0, AES_BLOCK_SIZE - aes->left) ;
+                XMEMCPY(tmp+aes->left, in, odd) ;
+                wc_AesCrypt(aes, out_block, tmp, AES_BLOCK_SIZE,
+                        PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
+                XMEMCPY(out, out_block+aes->left,odd) ;
+                aes->left += odd ;
+            }
+        }
+
+    #elif defined(HAVE_COLDFIRE_SEC)
+        #error "Coldfire SEC doesn't currently support AES-CTR mode"
+
+    #elif defined(FREESCALE_MMCAU)
+        #error "Freescale mmCAU doesn't currently support AES-CTR mode"
+
+    #else
+        /* Increment AES counter */
+        static INLINE void IncrementAesCounter(byte* inOutCtr)
+        {
+            int i;
+
+            /* in network byte order so start at end and work back */
+            for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
+                if (++inOutCtr[i])  /* we're done unless we overflow */
+                    return;
+            }
+        }
+
+        void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+        {
+            byte* tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
+
+            /* consume any unused bytes left in aes->tmp */
+            while (aes->left && sz) {
+               *(out++) = *(in++) ^ *(tmp++);
+               aes->left--;
+               sz--;
+            }
+
+            /* do as many block size ops as possible */
+            while (sz >= AES_BLOCK_SIZE) {
+                wc_AesEncrypt(aes, (byte*)aes->reg, out);
+                IncrementAesCounter((byte*)aes->reg);
+                xorbuf(out, in, AES_BLOCK_SIZE);
+
+                out += AES_BLOCK_SIZE;
+                in  += AES_BLOCK_SIZE;
+                sz  -= AES_BLOCK_SIZE;
+                aes->left = 0;
+            }
+
+            /* handle non block size remaining and sotre unused byte count in left */
+            if (sz) {
+                wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp);
+                IncrementAesCounter((byte*)aes->reg);
+
+                aes->left = AES_BLOCK_SIZE;
+                tmp = (byte*)aes->tmp;
+
+                while (sz--) {
+                    *(out++) = *(in++) ^ *(tmp++);
+                    aes->left--;
+                }
+            }
+        }
+
+    #endif /* STM32F2_CRYPTO, AES-CTR block */
+
+#endif /* WOLFSSL_AES_COUNTER */
+
+#ifdef HAVE_AESGCM
+
+/*
+ * The IV for AES GCM, stored in struct Aes's member reg, is comprised of
+ * three parts in order:
+ *   1. The implicit IV. This is generated from the PRF using the shared
+ *      secrets between endpoints. It is 4 bytes long.
+ *   2. The explicit IV. This is set by the user of the AES. It needs to be
+ *      unique for each call to encrypt. The explicit IV is shared with the
+ *      other end of the transaction in the clear.
+ *   3. The counter. Each block of data is encrypted with its own sequence
+ *      number counter.
+ */
+
+#ifdef STM32F2_CRYPTO
+    #error "STM32F2 crypto doesn't currently support AES-GCM mode"
+
+#elif defined(HAVE_COLDFIRE_SEC)
+    #error "Coldfire SEC doesn't currently support AES-GCM mode"
+
+#endif
+
+enum {
+    CTR_SZ = 4
+};
+
+
+static INLINE void InitGcmCounter(byte* inOutCtr)
+{
+    inOutCtr[AES_BLOCK_SIZE - 4] = 0;
+    inOutCtr[AES_BLOCK_SIZE - 3] = 0;
+    inOutCtr[AES_BLOCK_SIZE - 2] = 0;
+    inOutCtr[AES_BLOCK_SIZE - 1] = 1;
+}
+
+
+static INLINE void IncrementGcmCounter(byte* inOutCtr)
+{
+    int i;
+
+    /* in network byte order so start at end and work back */
+    for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) {
+        if (++inOutCtr[i])  /* we're done unless we overflow */
+            return;
+    }
+}
+
+
+#if defined(GCM_SMALL) || defined(GCM_TABLE)
+
+static INLINE void FlattenSzInBits(byte* buf, word32 sz)
+{
+    /* Multiply the sz by 8 */
+    word32 szHi = (sz >> (8*sizeof(sz) - 3));
+    sz <<= 3;
+
+    /* copy over the words of the sz into the destination buffer */
+    buf[0] = (szHi >> 24) & 0xff;
+    buf[1] = (szHi >> 16) & 0xff;
+    buf[2] = (szHi >>  8) & 0xff;
+    buf[3] = szHi & 0xff;
+    buf[4] = (sz >> 24) & 0xff;
+    buf[5] = (sz >> 16) & 0xff;
+    buf[6] = (sz >>  8) & 0xff;
+    buf[7] = sz & 0xff;
+}
+
+
+static INLINE void RIGHTSHIFTX(byte* x)
+{
+    int i;
+    int carryOut = 0;
+    int carryIn = 0;
+    int borrow = x[15] & 0x01;
+
+    for (i = 0; i < AES_BLOCK_SIZE; i++) {
+        carryOut = x[i] & 0x01;
+        x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0);
+        carryIn = carryOut;
+    }
+    if (borrow) x[0] ^= 0xE1;
+}
+
+#endif /* defined(GCM_SMALL) || defined(GCM_TABLE) */
+
+
+#ifdef GCM_TABLE
+
+static void GenerateM0(Aes* aes)
+{
+    int i, j;
+    byte (*m)[AES_BLOCK_SIZE] = aes->M0;
+
+    XMEMCPY(m[128], aes->H, AES_BLOCK_SIZE);
+
+    for (i = 64; i > 0; i /= 2) {
+        XMEMCPY(m[i], m[i*2], AES_BLOCK_SIZE);
+        RIGHTSHIFTX(m[i]);
+    }
+
+    for (i = 2; i < 256; i *= 2) {
+        for (j = 1; j < i; j++) {
+            XMEMCPY(m[i+j], m[i], AES_BLOCK_SIZE);
+            xorbuf(m[i+j], m[j], AES_BLOCK_SIZE);
+        }
+    }
+
+    XMEMSET(m[0], 0, AES_BLOCK_SIZE);
+}
+
+#endif /* GCM_TABLE */
+
+
+int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
+{
+    int  ret;
+    byte iv[AES_BLOCK_SIZE];
+
+    if (!((len == 16) || (len == 24) || (len == 32)))
+        return BAD_FUNC_ARG;
+
+    XMEMSET(iv, 0, AES_BLOCK_SIZE);
+    ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
+
+    if (ret == 0) {
+        wc_AesEncrypt(aes, iv, aes->H);
+    #ifdef GCM_TABLE
+        GenerateM0(aes);
+    #endif /* GCM_TABLE */
+    }
+
+    return ret;
+}
+
+
+#if defined(GCM_SMALL)
+
+static void GMULT(byte* X, byte* Y)
+{
+    byte Z[AES_BLOCK_SIZE];
+    byte V[AES_BLOCK_SIZE];
+    int i, j;
+
+    XMEMSET(Z, 0, AES_BLOCK_SIZE);
+    XMEMCPY(V, X, AES_BLOCK_SIZE);
+    for (i = 0; i < AES_BLOCK_SIZE; i++)
+    {
+        byte y = Y[i];
+        for (j = 0; j < 8; j++)
+        {
+            if (y & 0x80) {
+                xorbuf(Z, V, AES_BLOCK_SIZE);
+            }
+
+            RIGHTSHIFTX(V);
+            y = y << 1;
+        }
+    }
+    XMEMCPY(X, Z, AES_BLOCK_SIZE);
+}
+
+
+static void GHASH(Aes* aes, const byte* a, word32 aSz,
+                                const byte* c, word32 cSz, byte* s, word32 sSz)
+{
+    byte x[AES_BLOCK_SIZE];
+    byte scratch[AES_BLOCK_SIZE];
+    word32 blocks, partial;
+    byte* h = aes->H;
+
+    XMEMSET(x, 0, AES_BLOCK_SIZE);
+
+    /* Hash in A, the Additional Authentication Data */
+    if (aSz != 0 && a != NULL) {
+        blocks = aSz / AES_BLOCK_SIZE;
+        partial = aSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            xorbuf(x, a, AES_BLOCK_SIZE);
+            GMULT(x, h);
+            a += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
+            XMEMCPY(scratch, a, partial);
+            xorbuf(x, scratch, AES_BLOCK_SIZE);
+            GMULT(x, h);
+        }
+    }
+
+    /* Hash in C, the Ciphertext */
+    if (cSz != 0 && c != NULL) {
+        blocks = cSz / AES_BLOCK_SIZE;
+        partial = cSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            xorbuf(x, c, AES_BLOCK_SIZE);
+            GMULT(x, h);
+            c += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
+            XMEMCPY(scratch, c, partial);
+            xorbuf(x, scratch, AES_BLOCK_SIZE);
+            GMULT(x, h);
+        }
+    }
+
+    /* Hash in the lengths of A and C in bits */
+    FlattenSzInBits(&scratch[0], aSz);
+    FlattenSzInBits(&scratch[8], cSz);
+    xorbuf(x, scratch, AES_BLOCK_SIZE);
+    GMULT(x, h);
+
+    /* Copy the result into s. */
+    XMEMCPY(s, x, sSz);
+}
+
+/* end GCM_SMALL */
+#elif defined(GCM_TABLE)
+
+static const byte R[256][2] = {
+    {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
+    {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
+    {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
+    {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
+    {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
+    {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
+    {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
+    {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
+    {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
+    {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
+    {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
+    {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
+    {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
+    {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
+    {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
+    {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
+    {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
+    {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
+    {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
+    {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
+    {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
+    {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
+    {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
+    {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
+    {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
+    {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
+    {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
+    {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
+    {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
+    {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
+    {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
+    {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
+    {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
+    {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
+    {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
+    {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
+    {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
+    {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
+    {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
+    {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
+    {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
+    {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
+    {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
+    {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
+    {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
+    {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
+    {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
+    {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
+    {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
+    {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
+    {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
+    {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
+    {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
+    {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
+    {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
+    {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
+    {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
+    {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
+    {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
+    {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
+    {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
+    {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
+    {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
+    {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
+
+
+static void GMULT(byte *x, byte m[256][AES_BLOCK_SIZE])
+{
+    int i, j;
+    byte Z[AES_BLOCK_SIZE];
+    byte a;
+
+    XMEMSET(Z, 0, sizeof(Z));
+
+    for (i = 15; i > 0; i--) {
+        xorbuf(Z, m[x[i]], AES_BLOCK_SIZE);
+        a = Z[15];
+
+        for (j = 15; j > 0; j--) {
+            Z[j] = Z[j-1];
+        }
+
+        Z[0] = R[a][0];
+        Z[1] ^= R[a][1];
+    }
+    xorbuf(Z, m[x[0]], AES_BLOCK_SIZE);
+
+    XMEMCPY(x, Z, AES_BLOCK_SIZE);
+}
+
+
+static void GHASH(Aes* aes, const byte* a, word32 aSz,
+                                const byte* c, word32 cSz, byte* s, word32 sSz)
+{
+    byte x[AES_BLOCK_SIZE];
+    byte scratch[AES_BLOCK_SIZE];
+    word32 blocks, partial;
+
+    XMEMSET(x, 0, AES_BLOCK_SIZE);
+
+    /* Hash in A, the Additional Authentication Data */
+    if (aSz != 0 && a != NULL) {
+        blocks = aSz / AES_BLOCK_SIZE;
+        partial = aSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            xorbuf(x, a, AES_BLOCK_SIZE);
+            GMULT(x, aes->M0);
+            a += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
+            XMEMCPY(scratch, a, partial);
+            xorbuf(x, scratch, AES_BLOCK_SIZE);
+            GMULT(x, aes->M0);
+        }
+    }
+
+    /* Hash in C, the Ciphertext */
+    if (cSz != 0 && c != NULL) {
+        blocks = cSz / AES_BLOCK_SIZE;
+        partial = cSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            xorbuf(x, c, AES_BLOCK_SIZE);
+            GMULT(x, aes->M0);
+            c += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
+            XMEMCPY(scratch, c, partial);
+            xorbuf(x, scratch, AES_BLOCK_SIZE);
+            GMULT(x, aes->M0);
+        }
+    }
+
+    /* Hash in the lengths of A and C in bits */
+    FlattenSzInBits(&scratch[0], aSz);
+    FlattenSzInBits(&scratch[8], cSz);
+    xorbuf(x, scratch, AES_BLOCK_SIZE);
+    GMULT(x, aes->M0);
+
+    /* Copy the result into s. */
+    XMEMCPY(s, x, sSz);
+}
+
+/* end GCM_TABLE */
+#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
+
+static void GMULT(word64* X, word64* Y)
+{
+    word64 Z[2] = {0,0};
+    word64 V[2] ; 
+    int i, j;
+    V[0] = X[0] ;  V[1] = X[1] ;
+
+    for (i = 0; i < 2; i++)
+    {
+        word64 y = Y[i];
+        for (j = 0; j < 64; j++)
+        {
+            if (y & 0x8000000000000000ULL) {
+                Z[0] ^= V[0];
+                Z[1] ^= V[1];
+            }
+
+            if (V[1] & 0x0000000000000001) {
+                V[1] >>= 1;
+                V[1] |= ((V[0] & 0x0000000000000001) ? 0x8000000000000000ULL : 0);
+                V[0] >>= 1;
+                V[0] ^= 0xE100000000000000ULL;
+            }
+            else {
+                V[1] >>= 1;
+                V[1] |= ((V[0] & 0x0000000000000001) ? 0x8000000000000000ULL : 0);
+                V[0] >>= 1;
+            }
+            y <<= 1;
+        }
+    }
+    X[0] = Z[0];
+    X[1] = Z[1];
+}
+
+
+static void GHASH(Aes* aes, const byte* a, word32 aSz,
+                                const byte* c, word32 cSz, byte* s, word32 sSz)
+{
+    word64 x[2] = {0,0};
+    word32 blocks, partial;
+    word64 bigH[2];
+
+    XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);
+    #ifdef LITTLE_ENDIAN_ORDER
+        ByteReverseWords64(bigH, bigH, AES_BLOCK_SIZE); 
+    #endif
+
+    /* Hash in A, the Additional Authentication Data */
+    if (aSz != 0 && a != NULL) {
+        word64 bigA[2];
+        blocks = aSz / AES_BLOCK_SIZE;
+        partial = aSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            XMEMCPY(bigA, a, AES_BLOCK_SIZE);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigA[0];
+            x[1] ^= bigA[1];
+            GMULT(x, bigH);
+            a += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(bigA, 0, AES_BLOCK_SIZE);
+            XMEMCPY(bigA, a, partial);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigA[0];
+            x[1] ^= bigA[1];
+            GMULT(x, bigH);
+        }
+    }
+
+    /* Hash in C, the Ciphertext */
+    if (cSz != 0 && c != NULL) {
+        word64 bigC[2];
+        blocks = cSz / AES_BLOCK_SIZE;
+        partial = cSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            XMEMCPY(bigC, c, AES_BLOCK_SIZE);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigC[0];
+            x[1] ^= bigC[1];
+            GMULT(x, bigH);
+            c += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(bigC, 0, AES_BLOCK_SIZE);
+            XMEMCPY(bigC, c, partial);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigC[0];
+            x[1] ^= bigC[1];
+            GMULT(x, bigH);
+        }
+    }
+
+    /* Hash in the lengths in bits of A and C */
+    {
+        word64 len[2] ; 
+        len[0] = aSz ; len[1] = cSz;
+
+        /* Lengths are in bytes. Convert to bits. */
+        len[0] *= 8;
+        len[1] *= 8;
+
+        x[0] ^= len[0];
+        x[1] ^= len[1];
+        GMULT(x, bigH);
+    }
+    #ifdef LITTLE_ENDIAN_ORDER
+        ByteReverseWords64(x, x, AES_BLOCK_SIZE);
+    #endif
+    XMEMCPY(s, x, sSz);
+}
+
+/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
+#else /* GCM_WORD32 */
+
+static void GMULT(word32* X, word32* Y)
+{
+    word32 Z[4] = {0,0,0,0};
+    word32 V[4] ;
+    int i, j;
+
+    V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
+
+    for (i = 0; i < 4; i++)
+    {
+        word32 y = Y[i];
+        for (j = 0; j < 32; j++)
+        {
+            if (y & 0x80000000) {
+                Z[0] ^= V[0];
+                Z[1] ^= V[1];
+                Z[2] ^= V[2];
+                Z[3] ^= V[3];
+            }
+
+            if (V[3] & 0x00000001) {
+                V[3] >>= 1;
+                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
+                V[2] >>= 1;
+                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
+                V[1] >>= 1;
+                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
+                V[0] >>= 1;
+                V[0] ^= 0xE1000000;
+            } else {
+                V[3] >>= 1;
+                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
+                V[2] >>= 1;
+                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
+                V[1] >>= 1;
+                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
+                V[0] >>= 1;
+            }
+            y <<= 1;
+        }
+    }
+    X[0] = Z[0];
+    X[1] = Z[1];
+    X[2] = Z[2];
+    X[3] = Z[3];
+}
+
+
+static void GHASH(Aes* aes, const byte* a, word32 aSz,
+                                const byte* c, word32 cSz, byte* s, word32 sSz)
+{
+    word32 x[4] = {0,0,0,0};
+    word32 blocks, partial;
+    word32 bigH[4];
+
+    XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);
+    #ifdef LITTLE_ENDIAN_ORDER
+        ByteReverseWords(bigH, bigH, AES_BLOCK_SIZE);
+    #endif
+
+    /* Hash in A, the Additional Authentication Data */
+    if (aSz != 0 && a != NULL) {
+        word32 bigA[4];
+        blocks = aSz / AES_BLOCK_SIZE;
+        partial = aSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            XMEMCPY(bigA, a, AES_BLOCK_SIZE);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigA[0];
+            x[1] ^= bigA[1];
+            x[2] ^= bigA[2];
+            x[3] ^= bigA[3];
+            GMULT(x, bigH);
+            a += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(bigA, 0, AES_BLOCK_SIZE);
+            XMEMCPY(bigA, a, partial);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigA[0];
+            x[1] ^= bigA[1];
+            x[2] ^= bigA[2];
+            x[3] ^= bigA[3];
+            GMULT(x, bigH);
+        }
+    }
+
+    /* Hash in C, the Ciphertext */
+    if (cSz != 0 && c != NULL) {
+        word32 bigC[4];
+        blocks = cSz / AES_BLOCK_SIZE;
+        partial = cSz % AES_BLOCK_SIZE;
+        while (blocks--) {
+            XMEMCPY(bigC, c, AES_BLOCK_SIZE);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigC[0];
+            x[1] ^= bigC[1];
+            x[2] ^= bigC[2];
+            x[3] ^= bigC[3];
+            GMULT(x, bigH);
+            c += AES_BLOCK_SIZE;
+        }
+        if (partial != 0) {
+            XMEMSET(bigC, 0, AES_BLOCK_SIZE);
+            XMEMCPY(bigC, c, partial);
+            #ifdef LITTLE_ENDIAN_ORDER
+                ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
+            #endif
+            x[0] ^= bigC[0];
+            x[1] ^= bigC[1];
+            x[2] ^= bigC[2];
+            x[3] ^= bigC[3];
+            GMULT(x, bigH);
+        }
+    }
+
+    /* Hash in the lengths in bits of A and C */
+    {
+        word32 len[4];
+
+        /* Lengths are in bytes. Convert to bits. */
+        len[0] = (aSz >> (8*sizeof(aSz) - 3));
+        len[1] = aSz << 3;
+        len[2] = (cSz >> (8*sizeof(cSz) - 3));
+        len[3] = cSz << 3;
+
+        x[0] ^= len[0];
+        x[1] ^= len[1];
+        x[2] ^= len[2];
+        x[3] ^= len[3];
+        GMULT(x, bigH);
+    }
+    #ifdef LITTLE_ENDIAN_ORDER
+        ByteReverseWords(x, x, AES_BLOCK_SIZE);
+    #endif
+    XMEMCPY(s, x, sSz);
+}
+
+#endif /* end GCM_WORD32 */
+
+
+int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
+                   const byte* iv, word32 ivSz,
+                   byte* authTag, word32 authTagSz,
+                   const byte* authIn, word32 authInSz)
+{
+    word32 blocks = sz / AES_BLOCK_SIZE;
+    word32 partial = sz % AES_BLOCK_SIZE;
+    const byte* p = in;
+    byte* c = out;
+    byte counter[AES_BLOCK_SIZE];
+    byte *ctr ;
+    byte scratch[AES_BLOCK_SIZE];
+
+    WOLFSSL_ENTER("AesGcmEncrypt");
+
+#ifdef WOLFSSL_PIC32MZ_CRYPT
+    ctr = (char *)aes->iv_ce ;
+#else
+    ctr = counter ;
+#endif
+
+    XMEMSET(ctr, 0, AES_BLOCK_SIZE);
+    XMEMCPY(ctr, iv, ivSz);
+    InitGcmCounter(ctr);
+
+#ifdef WOLFSSL_PIC32MZ_CRYPT
+    if(blocks)
+        wc_AesCrypt(aes, out, in, blocks*AES_BLOCK_SIZE,
+             PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM );
+#endif
+    while (blocks--) {
+        IncrementGcmCounter(ctr);
+        #ifndef WOLFSSL_PIC32MZ_CRYPT
+            wc_AesEncrypt(aes, ctr, scratch);
+            xorbuf(scratch, p, AES_BLOCK_SIZE);
+            XMEMCPY(c, scratch, AES_BLOCK_SIZE);
+        #endif
+        p += AES_BLOCK_SIZE;
+        c += AES_BLOCK_SIZE;
+    }
+
+    if (partial != 0) {
+        IncrementGcmCounter(ctr);
+        wc_AesEncrypt(aes, ctr, scratch);
+        xorbuf(scratch, p, partial);
+        XMEMCPY(c, scratch, partial);
+
+    }
+
+    GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);
+    InitGcmCounter(ctr);
+    wc_AesEncrypt(aes, ctr, scratch);
+    xorbuf(authTag, scratch, authTagSz);
+
+    return 0;
+}
+
+
+int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
+                   const byte* iv, word32 ivSz,
+                   const byte* authTag, word32 authTagSz,
+                   const byte* authIn, word32 authInSz)
+{
+    word32 blocks = sz / AES_BLOCK_SIZE;
+    word32 partial = sz % AES_BLOCK_SIZE;
+    const byte* c = in;
+    byte* p = out;
+    byte counter[AES_BLOCK_SIZE];
+    byte *ctr ;
+    byte scratch[AES_BLOCK_SIZE];
+
+    WOLFSSL_ENTER("AesGcmDecrypt");
+
+#ifdef WOLFSSL_PIC32MZ_CRYPT
+    ctr = (char *)aes->iv_ce ;
+#else
+    ctr = counter ;
+#endif
+
+    XMEMSET(ctr, 0, AES_BLOCK_SIZE);
+    XMEMCPY(ctr, iv, ivSz);
+    InitGcmCounter(ctr);
+
+    /* Calculate the authTag again using the received auth data and the
+     * cipher text. */
+    {
+        byte Tprime[AES_BLOCK_SIZE];
+        byte EKY0[AES_BLOCK_SIZE];
+
+        GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
+        wc_AesEncrypt(aes, ctr, EKY0);
+        xorbuf(Tprime, EKY0, sizeof(Tprime));
+
+        if (ConstantCompare(authTag, Tprime, authTagSz) != 0) {
+            return AES_GCM_AUTH_E;
+        }
+    }
+
+#ifdef WOLFSSL_PIC32MZ_CRYPT
+    if(blocks)
+        wc_AesCrypt(aes, out, in, blocks*AES_BLOCK_SIZE,
+             PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM );
+#endif
+
+    while (blocks--) {
+        IncrementGcmCounter(ctr);
+        #ifndef WOLFSSL_PIC32MZ_CRYPT
+            wc_AesEncrypt(aes, ctr, scratch);
+            xorbuf(scratch, c, AES_BLOCK_SIZE);
+            XMEMCPY(p, scratch, AES_BLOCK_SIZE);
+        #endif
+        p += AES_BLOCK_SIZE;
+        c += AES_BLOCK_SIZE;
+    }
+    if (partial != 0) {
+        IncrementGcmCounter(ctr);
+        wc_AesEncrypt(aes, ctr, scratch);
+        xorbuf(scratch, c, partial);
+        XMEMCPY(p, scratch, partial);
+    }
+    return 0;
+}
+
+
+
+WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
+{
+    return wc_AesGcmSetKey(&gmac->aes, key, len);
+}
+
+
+WOLFSSL_API int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
+                              const byte* authIn, word32 authInSz,
+                              byte* authTag, word32 authTagSz)
+{
+    return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
+                                         authTag, authTagSz, authIn, authInSz);
+}
+
+#endif /* HAVE_AESGCM */
+
+
+#ifdef HAVE_AESCCM
+
+#ifdef STM32F2_CRYPTO
+    #error "STM32F2 crypto doesn't currently support AES-CCM mode"
+
+#elif defined(HAVE_COLDFIRE_SEC)
+    #error "Coldfire SEC doesn't currently support AES-CCM mode"
+
+#elif defined(WOLFSSL_PIC32MZ_CRYPT)
+    #error "PIC32MZ doesn't currently support AES-CCM mode"
+
+#endif
+
+void wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
+{
+    byte nonce[AES_BLOCK_SIZE];
+
+    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
+        return;
+
+    XMEMSET(nonce, 0, sizeof(nonce));
+    wc_AesSetKey(aes, key, keySz, nonce, AES_ENCRYPTION);
+}
+
+
+static void roll_x(Aes* aes, const byte* in, word32 inSz, byte* out)
+{
+    /* process the bulk of the data */
+    while (inSz >= AES_BLOCK_SIZE) {
+        xorbuf(out, in, AES_BLOCK_SIZE);
+        in += AES_BLOCK_SIZE;
+        inSz -= AES_BLOCK_SIZE;
+
+        wc_AesEncrypt(aes, out, out);
+    }
+
+    /* process remainder of the data */
+    if (inSz > 0) {
+        xorbuf(out, in, inSz);
+        wc_AesEncrypt(aes, out, out);
+    }
+}
+
+
+static void roll_auth(Aes* aes, const byte* in, word32 inSz, byte* out)
+{
+    word32 authLenSz;
+    word32 remainder;
+
+    /* encode the length in */
+    if (inSz <= 0xFEFF) {
+        authLenSz = 2;
+        out[0] ^= ((inSz & 0xFF00) >> 8);
+        out[1] ^=  (inSz & 0x00FF);
+    }
+    else if (inSz <= 0xFFFFFFFF) {
+        authLenSz = 6;
+        out[0] ^= 0xFF; out[1] ^= 0xFE;
+        out[2] ^= ((inSz & 0xFF000000) >> 24);
+        out[3] ^= ((inSz & 0x00FF0000) >> 16);
+        out[4] ^= ((inSz & 0x0000FF00) >>  8);
+        out[5] ^=  (inSz & 0x000000FF);
+    }
+    /* Note, the protocol handles auth data up to 2^64, but we are
+     * using 32-bit sizes right now, so the bigger data isn't handled
+     * else if (inSz <= 0xFFFFFFFFFFFFFFFF) {} */
+    else
+        return;
+
+    /* start fill out the rest of the first block */
+    remainder = AES_BLOCK_SIZE - authLenSz;
+    if (inSz >= remainder) {
+        /* plenty of bulk data to fill the remainder of this block */
+        xorbuf(out + authLenSz, in, remainder);
+        inSz -= remainder;
+        in += remainder;
+    }
+    else {
+        /* not enough bulk data, copy what is available, and pad zero */
+        xorbuf(out + authLenSz, in, inSz);
+        inSz = 0;
+    }
+    wc_AesEncrypt(aes, out, out);
+
+    if (inSz > 0)
+        roll_x(aes, in, inSz, out);
+}
+
+
+static INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
+{
+    word32 i;
+
+    for (i = 0; i < lenSz; i++) {
+        if (++B[AES_BLOCK_SIZE - 1 - i] != 0) return;
+    }
+}
+
+
+/* return 0 on success */
+int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
+                   const byte* nonce, word32 nonceSz,
+                   byte* authTag, word32 authTagSz,
+                   const byte* authIn, word32 authInSz)
+{
+    byte A[AES_BLOCK_SIZE];
+    byte B[AES_BLOCK_SIZE];
+    byte lenSz;
+    word32 i;
+    byte mask     = 0xFF;
+    word32 wordSz = (word32)sizeof(word32);
+
+    /* sanity check on arugments */
+    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
+            || authTag == NULL || nonceSz < 7 || nonceSz > 13)
+        return BAD_FUNC_ARG;
+
+    XMEMCPY(B+1, nonce, nonceSz);
+    lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
+    B[0] = (authInSz > 0 ? 64 : 0)
+         + (8 * (((byte)authTagSz - 2) / 2))
+         + (lenSz - 1);
+    for (i = 0; i < lenSz; i++) {
+        if (mask && i >= wordSz)
+            mask = 0x00;
+        B[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
+    }
+
+    wc_AesEncrypt(aes, B, A);
+
+    if (authInSz > 0)
+        roll_auth(aes, authIn, authInSz, A);
+    if (inSz > 0)
+        roll_x(aes, in, inSz, A);
+    XMEMCPY(authTag, A, authTagSz);
+
+    B[0] = lenSz - 1;
+    for (i = 0; i < lenSz; i++)
+        B[AES_BLOCK_SIZE - 1 - i] = 0;
+    wc_AesEncrypt(aes, B, A);
+    xorbuf(authTag, A, authTagSz);
+
+    B[15] = 1;
+    while (inSz >= AES_BLOCK_SIZE) {
+        wc_AesEncrypt(aes, B, A);
+        xorbuf(A, in, AES_BLOCK_SIZE);
+        XMEMCPY(out, A, AES_BLOCK_SIZE);
+
+        AesCcmCtrInc(B, lenSz);
+        inSz -= AES_BLOCK_SIZE;
+        in += AES_BLOCK_SIZE;
+        out += AES_BLOCK_SIZE;
+    }
+    if (inSz > 0) {
+        wc_AesEncrypt(aes, B, A);
+        xorbuf(A, in, inSz);
+        XMEMCPY(out, A, inSz);
+    }
+
+    ForceZero(A, AES_BLOCK_SIZE);
+    ForceZero(B, AES_BLOCK_SIZE);
+
+    return 0;
+}
+
+
+int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
+                   const byte* nonce, word32 nonceSz,
+                   const byte* authTag, word32 authTagSz,
+                   const byte* authIn, word32 authInSz)
+{
+    byte A[AES_BLOCK_SIZE];
+    byte B[AES_BLOCK_SIZE];
+    byte* o;
+    byte lenSz;
+    word32 i, oSz;
+    int result = 0;
+    byte mask     = 0xFF;
+    word32 wordSz = (word32)sizeof(word32);
+
+    /* sanity check on arugments */
+    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
+            || authTag == NULL || nonceSz < 7 || nonceSz > 13)
+        return BAD_FUNC_ARG;
+
+    o = out;
+    oSz = inSz;
+    XMEMCPY(B+1, nonce, nonceSz);
+    lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
+
+    B[0] = lenSz - 1;
+    for (i = 0; i < lenSz; i++)
+        B[AES_BLOCK_SIZE - 1 - i] = 0;
+    B[15] = 1;
+
+    while (oSz >= AES_BLOCK_SIZE) {
+        wc_AesEncrypt(aes, B, A);
+        xorbuf(A, in, AES_BLOCK_SIZE);
+        XMEMCPY(o, A, AES_BLOCK_SIZE);
+
+        AesCcmCtrInc(B, lenSz);
+        oSz -= AES_BLOCK_SIZE;
+        in += AES_BLOCK_SIZE;
+        o += AES_BLOCK_SIZE;
+    }
+    if (inSz > 0) {
+        wc_AesEncrypt(aes, B, A);
+        xorbuf(A, in, oSz);
+        XMEMCPY(o, A, oSz);
+    }
+
+    for (i = 0; i < lenSz; i++)
+        B[AES_BLOCK_SIZE - 1 - i] = 0;
+    wc_AesEncrypt(aes, B, A);
+
+    o = out;
+    oSz = inSz;
+
+    B[0] = (authInSz > 0 ? 64 : 0)
+         + (8 * (((byte)authTagSz - 2) / 2))
+         + (lenSz - 1);
+    for (i = 0; i < lenSz; i++) {
+        if (mask && i >= wordSz)
+            mask = 0x00;
+        B[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
+    }
+
+    wc_AesEncrypt(aes, B, A);
+
+    if (authInSz > 0)
+        roll_auth(aes, authIn, authInSz, A);
+    if (inSz > 0)
+        roll_x(aes, o, oSz, A);
+
+    B[0] = lenSz - 1;
+    for (i = 0; i < lenSz; i++)
+        B[AES_BLOCK_SIZE - 1 - i] = 0;
+    wc_AesEncrypt(aes, B, B);
+    xorbuf(A, B, authTagSz);
+
+    if (ConstantCompare(A, authTag, authTagSz) != 0) {
+        /* If the authTag check fails, don't keep the decrypted data.
+         * Unfortunately, you need the decrypted data to calculate the
+         * check value. */
+        XMEMSET(out, 0, inSz);
+        result = AES_CCM_AUTH_E;
+    }
+
+    ForceZero(A, AES_BLOCK_SIZE);
+    ForceZero(B, AES_BLOCK_SIZE);
+    o = NULL;
+
+    return result;
+}
+
+#endif /* HAVE_AESCCM */
+
+
+#ifdef HAVE_CAVIUM
+
+#include <wolfssl/ctaocrypt/logging.h>
+#include "cavium_common.h"
+
+/* Initiliaze Aes for use with Nitrox device */
+int wc_AesInitCavium(Aes* aes, int devId)
+{
+    if (aes == NULL)
+        return -1;
+
+    if (CspAllocContext(CONTEXT_SSL, &aes->contextHandle, devId) != 0)
+        return -1;
+
+    aes->devId = devId;
+    aes->magic = WOLFSSL_AES_CAVIUM_MAGIC;
+
+    return 0;
+}
+
+
+/* Free Aes from use with Nitrox device */
+void wc_AesFreeCavium(Aes* aes)
+{
+    if (aes == NULL)
+        return;
+
+    if (aes->magic != WOLFSSL_AES_CAVIUM_MAGIC)
+        return;
+
+    CspFreeContext(CONTEXT_SSL, aes->contextHandle, aes->devId);
+    aes->magic = 0;
+}
+
+
+static int wc_AesCaviumSetKey(Aes* aes, const byte* key, word32 length,
+                           const byte* iv)
+{
+    if (aes == NULL)
+        return -1;
+
+    XMEMCPY(aes->key, key, length);   /* key still holds key, iv still in reg */
+    if (length == 16)
+        aes->type = AES_128;
+    else if (length == 24)
+        aes->type = AES_192;
+    else if (length == 32)
+        aes->type = AES_256;
+
+    return wc_AesSetIV(aes, iv);
+}
+
+
+static int AesCaviumCbcEncrypt(Aes* aes, byte* out, const byte* in,
+                               word32 length)
+{
+    wolfssl_word offset = 0;
+    word32 requestId;
+
+    while (length > WOLFSSL_MAX_16BIT) {
+        word16 slen = (word16)WOLFSSL_MAX_16BIT;
+        if (CspEncryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE,
+                          aes->type, slen, (byte*)in + offset, out + offset,
+                          (byte*)aes->reg, (byte*)aes->key, &requestId,
+                          aes->devId) != 0) {
+            WOLFSSL_MSG("Bad Cavium Aes Encrypt");
+            return -1;
+        }
+        length -= WOLFSSL_MAX_16BIT;
+        offset += WOLFSSL_MAX_16BIT;
+        XMEMCPY(aes->reg, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+    }
+    if (length) {
+        word16 slen = (word16)length;
+        if (CspEncryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE,
+                          aes->type, slen, (byte*)in + offset, out + offset,
+                          (byte*)aes->reg, (byte*)aes->key, &requestId,
+                          aes->devId) != 0) {
+            WOLFSSL_MSG("Bad Cavium Aes Encrypt");
+            return -1;
+        }
+        XMEMCPY(aes->reg, out + offset+length - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+    }
+    return 0;
+}
+
+static int AesCaviumCbcDecrypt(Aes* aes, byte* out, const byte* in,
+                               word32 length)
+{
+    word32 requestId;
+    wolfssl_word offset = 0;
+
+    while (length > WOLFSSL_MAX_16BIT) {
+        word16 slen = (word16)WOLFSSL_MAX_16BIT;
+        XMEMCPY(aes->tmp, in + offset + slen - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+        if (CspDecryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE,
+                          aes->type, slen, (byte*)in + offset, out + offset,
+                          (byte*)aes->reg, (byte*)aes->key, &requestId,
+                          aes->devId) != 0) {
+            WOLFSSL_MSG("Bad Cavium Aes Decrypt");
+            return -1;
+        }
+        length -= WOLFSSL_MAX_16BIT;
+        offset += WOLFSSL_MAX_16BIT;
+        XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
+    }
+    if (length) {
+        word16 slen = (word16)length;
+        XMEMCPY(aes->tmp, in + offset + slen - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+        if (CspDecryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE,
+                          aes->type, slen, (byte*)in + offset, out + offset,
+                          (byte*)aes->reg, (byte*)aes->key, &requestId,
+                          aes->devId) != 0) {
+            WOLFSSL_MSG("Bad Cavium Aes Decrypt");
+            return -1;
+        }
+        XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
+    }
+    return 0;
+}
+
+#endif /* HAVE_CAVIUM */
+
+#endif /* WOLFSSL_TI_CRYPT */
+
+#endif /* HAVE_FIPS */
+
+#endif /* NO_AES */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/arc4.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/arc4.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/arc4.c	(revision 164)
@@ -0,0 +1,178 @@
+/* arc4.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_RC4
+
+#include <wolfssl/wolfcrypt/arc4.h>
+
+#ifdef HAVE_CAVIUM
+    static void wc_Arc4CaviumSetKey(Arc4* arc4, const byte* key, word32 length);
+    static void wc_Arc4CaviumProcess(Arc4* arc4, byte* out, const byte* in,
+                                  word32 length);
+#endif
+
+
+void wc_Arc4SetKey(Arc4* arc4, const byte* key, word32 length)
+{
+    word32 i;
+    word32 keyIndex = 0, stateIndex = 0;
+
+#ifdef HAVE_CAVIUM
+    if (arc4->magic == WOLFSSL_ARC4_CAVIUM_MAGIC)
+        return wc_Arc4CaviumSetKey(arc4, key, length);
+#endif
+
+    arc4->x = 1;
+    arc4->y = 0;
+
+    for (i = 0; i < ARC4_STATE_SIZE; i++)
+        arc4->state[i] = (byte)i;
+
+    for (i = 0; i < ARC4_STATE_SIZE; i++) {
+        word32 a = arc4->state[i];
+        stateIndex += key[keyIndex] + a;
+        stateIndex &= 0xFF;
+        arc4->state[i] = arc4->state[stateIndex];
+        arc4->state[stateIndex] = (byte)a;
+
+        if (++keyIndex >= length)
+            keyIndex = 0;
+    }
+}
+
+
+static INLINE byte MakeByte(word32* x, word32* y, byte* s)
+{
+    word32 a = s[*x], b;
+    *y = (*y+a) & 0xff;
+
+    b = s[*y];
+    s[*x] = (byte)b;
+    s[*y] = (byte)a;
+    *x = (*x+1) & 0xff;
+
+    return s[(a+b) & 0xff];
+}
+
+
+void wc_Arc4Process(Arc4* arc4, byte* out, const byte* in, word32 length)
+{
+    word32 x;
+    word32 y;
+
+#ifdef HAVE_CAVIUM
+    if (arc4->magic == WOLFSSL_ARC4_CAVIUM_MAGIC)
+        return wc_Arc4CaviumProcess(arc4, out, in, length);
+#endif
+
+    x = arc4->x;
+    y = arc4->y;
+
+    while(length--)
+        *out++ = *in++ ^ MakeByte(&x, &y, arc4->state);
+
+    arc4->x = (byte)x;
+    arc4->y = (byte)y;
+}
+
+
+#ifdef HAVE_CAVIUM
+
+#include <wolfssl/wolfcrypt/logging.h>
+#include "cavium_common.h"
+
+/* Initiliaze Arc4 for use with Nitrox device */
+int wc_Arc4InitCavium(Arc4* arc4, int devId)
+{
+    if (arc4 == NULL)
+        return -1;
+
+    if (CspAllocContext(CONTEXT_SSL, &arc4->contextHandle, devId) != 0)
+        return -1;
+
+    arc4->devId = devId;
+    arc4->magic = WOLFSSL_ARC4_CAVIUM_MAGIC;
+
+    return 0;
+}
+
+
+/* Free Arc4 from use with Nitrox device */
+void wc_Arc4FreeCavium(Arc4* arc4)
+{
+    if (arc4 == NULL)
+        return;
+
+    if (arc4->magic != WOLFSSL_ARC4_CAVIUM_MAGIC)
+        return;
+
+    CspFreeContext(CONTEXT_SSL, arc4->contextHandle, arc4->devId);
+    arc4->magic = 0;
+}
+
+
+static void wc_Arc4CaviumSetKey(Arc4* arc4, const byte* key, word32 length)
+{
+    word32 requestId;
+
+    if (CspInitializeRc4(CAVIUM_BLOCKING, arc4->contextHandle, length,
+                         (byte*)key, &requestId, arc4->devId) != 0) {
+        WOLFSSL_MSG("Bad Cavium Arc4 Init");
+    }
+}
+
+
+static void wc_Arc4CaviumProcess(Arc4* arc4, byte* out, const byte* in,
+                              word32 length)
+{
+    wolfssl_word offset = 0;
+    word32 requestId;
+
+    while (length > WOLFSSL_MAX_16BIT) {
+        word16 slen = (word16)WOLFSSL_MAX_16BIT;
+        if (CspEncryptRc4(CAVIUM_BLOCKING, arc4->contextHandle,CAVIUM_UPDATE,
+                          slen, (byte*)in + offset, out + offset, &requestId,
+                          arc4->devId) != 0) {
+            WOLFSSL_MSG("Bad Cavium Arc4 Encrypt");
+        }
+        length -= WOLFSSL_MAX_16BIT;
+        offset += WOLFSSL_MAX_16BIT;
+    }
+    if (length) {
+        word16 slen = (word16)length;
+        if (CspEncryptRc4(CAVIUM_BLOCKING, arc4->contextHandle,CAVIUM_UPDATE,
+                          slen, (byte*)in + offset, out + offset, &requestId,
+                          arc4->devId) != 0) {
+            WOLFSSL_MSG("Bad Cavium Arc4 Encrypt");
+        }
+    }
+}
+
+#endif /* HAVE_CAVIUM */
+
+#endif /* NO_RC4 */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/asn.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/asn.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/asn.c	(revision 164)
@@ -0,0 +1,9322 @@
+/* asn.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_ASN
+
+#ifdef HAVE_RTP_SYS
+    #include "os.h"           /* dc_rtc_api needs    */
+    #include "dc_rtc_api.h"   /* to get current time */
+#endif
+
+#include <wolfssl/wolfcrypt/asn.h>
+#include <wolfssl/wolfcrypt/coding.h>
+//#include <wolfssl/wolfcrypt/md2.h>
+#include <wolfssl/wolfcrypt/hmac.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/pwdbased.h>
+#include <wolfssl/wolfcrypt/des3.h>
+#include <wolfssl/wolfcrypt/logging.h>
+
+#include <wolfssl/wolfcrypt/random.h>
+#include <wolfssl/wolfcrypt/hash.h>
+
+
+#ifndef NO_RC4
+    #include <wolfssl/wolfcrypt/arc4.h>
+#endif
+
+#ifdef HAVE_NTRU
+    #include "libntruencrypt/ntru_crypto.h"
+#endif
+
+#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
+    #include <wolfssl/wolfcrypt/sha512.h>
+#endif
+
+#ifndef NO_SHA256
+    #include <wolfssl/wolfcrypt/sha256.h>
+#endif
+
+#ifdef HAVE_ECC
+    #include <wolfssl/wolfcrypt/ecc.h>
+#endif
+
+#ifdef WOLFSSL_DEBUG_ENCODING
+    #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+        #if MQX_USE_IO_OLD
+            #include <fio.h>
+        #else
+            #include <nio.h>
+        #endif
+    #else
+        #include <stdio.h>
+    #endif
+#endif
+
+#ifdef _MSC_VER
+    /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
+    #pragma warning(disable: 4996)
+#endif
+
+
+#ifndef TRUE
+    #define TRUE  1
+#endif
+#ifndef FALSE
+    #define FALSE 0
+#endif
+
+
+#ifdef HAVE_RTP_SYS
+    /* uses parital <time.h> structures */
+    #define XTIME(tl)  (0)
+    #define XGMTIME(c, t) my_gmtime((c))
+    #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
+#elif defined(MICRIUM)
+    #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
+        #define XVALIDATE_DATE(d,f,t) NetSecure_ValidateDateHandler((d),(f),(t))
+    #else
+        #define XVALIDATE_DATE(d, f, t) (0)
+    #endif
+    #define NO_TIME_H
+    /* since Micrium not defining XTIME or XGMTIME, CERT_GEN not available */
+#elif defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
+    #include <time.h>
+    #define XTIME(t1) pic32_time((t1))
+    #define XGMTIME(c, t) gmtime((c))
+    #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
+#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+    #define XTIME(t1)  mqx_time((t1))
+    #define XGMTIME(c, t) mqx_gmtime((c), (t))
+    #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
+#elif defined(FREESCALE_KSDK_BM)
+    #include <time.h>
+    #define XTIME(t1)  ksdk_time((t1))
+    #define XGMTIME(c, t) gmtime((c))
+    #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
+
+#elif defined(USER_TIME)
+    /* user time, and gmtime compatible functions, there is a gmtime
+       implementation here that WINCE uses, so really just need some ticks
+       since the EPOCH
+    */
+
+    struct tm {
+    int tm_sec;     /* seconds after the minute [0-60] */
+    int tm_min;     /* minutes after the hour [0-59] */
+    int tm_hour;    /* hours since midnight [0-23] */
+    int tm_mday;    /* day of the month [1-31] */
+    int tm_mon;     /* months since January [0-11] */
+    int tm_year;    /* years since 1900 */
+    int tm_wday;    /* days since Sunday [0-6] */
+    int tm_yday;    /* days since January 1 [0-365] */
+    int tm_isdst;   /* Daylight Savings Time flag */
+    long    tm_gmtoff;  /* offset from CUT in seconds */
+    char    *tm_zone;   /* timezone abbreviation */
+    };
+    typedef long time_t;
+
+    /* forward declaration */
+    struct tm* gmtime(const time_t* timer);
+    extern time_t XTIME(time_t * timer);
+
+    #define XGMTIME(c, t) gmtime((c))
+    #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
+
+    #ifdef STACK_TRAP
+        /* for stack trap tracking, don't call os gmtime on OS X/linux,
+           uses a lot of stack spce */
+        extern time_t time(time_t * timer);
+        #define XTIME(tl)  time((tl))
+    #endif /* STACK_TRAP */
+
+#elif defined(TIME_OVERRIDES)
+    /* user would like to override time() and gmtime() functionality */
+
+    #ifndef HAVE_TIME_T_TYPE
+        typedef long time_t;
+    #endif
+    extern time_t XTIME(time_t * timer);
+
+    #ifndef HAVE_TM_TYPE
+        struct tm {
+            int  tm_sec;     /* seconds after the minute [0-60] */
+            int  tm_min;     /* minutes after the hour [0-59] */
+            int  tm_hour;    /* hours since midnight [0-23] */
+            int  tm_mday;    /* day of the month [1-31] */
+            int  tm_mon;     /* months since January [0-11] */
+            int  tm_year;    /* years since 1900 */
+            int  tm_wday;    /* days since Sunday [0-6] */
+            int  tm_yday;    /* days since January 1 [0-365] */
+            int  tm_isdst;   /* Daylight Savings Time flag */
+            long tm_gmtoff;  /* offset from CUT in seconds */
+            char *tm_zone;   /* timezone abbreviation */
+        };
+    #endif
+    extern struct tm* XGMTIME(const time_t* timer, struct tm* tmp);
+
+    #ifndef HAVE_VALIDATE_DATE
+        #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
+    #endif
+
+#elif defined(IDIRECT_DEV_TIME)
+    /*Gets the timestamp from cloak software owned by VT iDirect
+    in place of time() from <time.h> */
+    #include <time.h>
+    #define XTIME(t1)  idirect_time((t1))
+    #define XGMTIME(c) gmtime((c))
+    #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
+
+#else
+    /* default */
+    /* uses complete <time.h> facility */
+    #include <time.h>
+    #define XTIME(tl)     time((tl))
+    #define XGMTIME(c, t) gmtime((c))
+    #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
+#endif
+
+
+#ifdef _WIN32_WCE
+/* no time() or gmtime() even though in time.h header?? */
+
+#include <windows.h>
+
+
+time_t time(time_t* timer)
+{
+    SYSTEMTIME     sysTime;
+    FILETIME       fTime;
+    ULARGE_INTEGER intTime;
+    time_t         localTime;
+
+    if (timer == NULL)
+        timer = &localTime;
+
+    GetSystemTime(&sysTime);
+    SystemTimeToFileTime(&sysTime, &fTime);
+
+    XMEMCPY(&intTime, &fTime, sizeof(FILETIME));
+    /* subtract EPOCH */
+    intTime.QuadPart -= 0x19db1ded53e8000;
+    /* to secs */
+    intTime.QuadPart /= 10000000;
+    *timer = (time_t)intTime.QuadPart;
+
+    return *timer;
+}
+
+#endif /*  _WIN32_WCE */
+#if defined( _WIN32_WCE ) || defined( USER_TIME )
+
+struct tm* gmtime(const time_t* timer)
+{
+    #define YEAR0          1900
+    #define EPOCH_YEAR     1970
+    #define SECS_DAY       (24L * 60L * 60L)
+    #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400)))
+    #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
+
+    static const int _ytab[2][12] =
+    {
+        {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+        {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
+    };
+
+    static struct tm st_time;
+    struct tm* ret = &st_time;
+    time_t secs = *timer;
+    unsigned long dayclock, dayno;
+    int year = EPOCH_YEAR;
+
+    dayclock = (unsigned long)secs % SECS_DAY;
+    dayno    = (unsigned long)secs / SECS_DAY;
+
+    ret->tm_sec  = (int) dayclock % 60;
+    ret->tm_min  = (int)(dayclock % 3600) / 60;
+    ret->tm_hour = (int) dayclock / 3600;
+    ret->tm_wday = (int) (dayno + 4) % 7;        /* day 0 a Thursday */
+
+    while(dayno >= (unsigned long)YEARSIZE(year)) {
+        dayno -= YEARSIZE(year);
+        year++;
+    }
+
+    ret->tm_year = year - YEAR0;
+    ret->tm_yday = (int)dayno;
+    ret->tm_mon  = 0;
+
+    while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) {
+        dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon];
+        ret->tm_mon++;
+    }
+
+    ret->tm_mday  = (int)++dayno;
+    ret->tm_isdst = 0;
+
+    return ret;
+}
+
+#endif /* _WIN32_WCE  || USER_TIME */
+
+
+#ifdef HAVE_RTP_SYS
+
+#define YEAR0          1900
+
+struct tm* my_gmtime(const time_t* timer)       /* has a gmtime() but hangs */
+{
+    static struct tm st_time;
+    struct tm* ret = &st_time;
+
+    DC_RTC_CALENDAR cal;
+    dc_rtc_time_get(&cal, TRUE);
+
+    ret->tm_year  = cal.year - YEAR0;       /* gm starts at 1900 */
+    ret->tm_mon   = cal.month - 1;          /* gm starts at 0 */
+    ret->tm_mday  = cal.day;
+    ret->tm_hour  = cal.hour;
+    ret->tm_min   = cal.minute;
+    ret->tm_sec   = cal.second;
+
+    return ret;
+}
+
+#endif /* HAVE_RTP_SYS */
+
+
+#if defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
+
+/*
+ * time() is just a stub in Microchip libraries. We need our own
+ * implementation. Use SNTP client to get seconds since epoch.
+ */
+time_t pic32_time(time_t* timer)
+{
+#ifdef MICROCHIP_TCPIP_V5
+    DWORD sec = 0;
+#else
+    uint32_t sec = 0;
+#endif
+    time_t localTime;
+
+    if (timer == NULL)
+        timer = &localTime;
+
+#ifdef MICROCHIP_MPLAB_HARMONY
+    sec = TCPIP_SNTP_UTCSecondsGet();
+#else
+    sec = SNTPGetUTCSeconds();
+#endif
+    *timer = (time_t) sec;
+
+    return *timer;
+}
+
+#endif /* MICROCHIP_TCPIP */
+
+
+#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+
+time_t mqx_time(time_t* timer)
+{
+    time_t localTime;
+    TIME_STRUCT time_s;
+
+    if (timer == NULL)
+        timer = &localTime;
+
+    _time_get(&time_s);
+    *timer = (time_t) time_s.SECONDS;
+
+    return *timer;
+}
+
+/* CodeWarrior GCC toolchain only has gmtime_r(), no gmtime() */
+struct tm* mqx_gmtime(const time_t* clock, struct tm* tmpTime)
+{
+    return gmtime_r(clock, tmpTime);
+}
+
+#endif /* FREESCALE_MQX */
+
+#ifdef FREESCALE_KSDK_BM
+
+/* setting for PIT timer */
+#define PIT_INSTANCE 0
+#define PIT_CHANNEL  0
+
+#include "fsl_pit_driver.h"
+
+time_t ksdk_time(time_t* timer)
+{
+    time_t localTime;
+
+    if (timer == NULL)
+        timer = &localTime;
+
+    *timer = (PIT_DRV_ReadTimerUs(PIT_INSTANCE, PIT_CHANNEL)) / 1000000;
+    return *timer;
+}
+
+#endif /* FREESCALE_KSDK_BM */
+
+#ifdef WOLFSSL_TIRTOS
+
+time_t XTIME(time_t * timer)
+{
+    time_t sec = 0;
+
+    sec = (time_t) Seconds_get();
+
+    if (timer != NULL)
+        *timer = sec;
+
+    return sec;
+}
+
+#endif /* WOLFSSL_TIRTOS */
+
+static INLINE word32 btoi(byte b)
+{
+    return b - 0x30;
+}
+
+
+/* two byte date/time, add to value */
+static INLINE void GetTime(int* value, const byte* date, int* idx)
+{
+    int i = *idx;
+
+    *value += btoi(date[i++]) * 10;
+    *value += btoi(date[i++]);
+
+    *idx = i;
+}
+
+
+#if defined(MICRIUM)
+
+CPU_INT32S NetSecure_ValidateDateHandler(CPU_INT08U *date, CPU_INT08U format,
+                                         CPU_INT08U dateType)
+{
+    CPU_BOOLEAN  rtn_code;
+    CPU_INT32S   i;
+    CPU_INT32S   val;
+    CPU_INT16U   year;
+    CPU_INT08U   month;
+    CPU_INT16U   day;
+    CPU_INT08U   hour;
+    CPU_INT08U   min;
+    CPU_INT08U   sec;
+
+    i    = 0;
+    year = 0u;
+
+    if (format == ASN_UTC_TIME) {
+        if (btoi(date[0]) >= 5)
+            year = 1900;
+        else
+            year = 2000;
+    }
+    else  { /* format == GENERALIZED_TIME */
+        year += btoi(date[i++]) * 1000;
+        year += btoi(date[i++]) * 100;
+    }
+
+    val = year;
+    GetTime(&val, date, &i);
+    year = (CPU_INT16U)val;
+
+    val = 0;
+    GetTime(&val, date, &i);
+    month = (CPU_INT08U)val;
+
+    val = 0;
+    GetTime(&val, date, &i);
+    day = (CPU_INT16U)val;
+
+    val = 0;
+    GetTime(&val, date, &i);
+    hour = (CPU_INT08U)val;
+
+    val = 0;
+    GetTime(&val, date, &i);
+    min = (CPU_INT08U)val;
+
+    val = 0;
+    GetTime(&val, date, &i);
+    sec = (CPU_INT08U)val;
+
+    return NetSecure_ValidateDate(year, month, day, hour, min, sec, dateType);
+}
+
+#endif /* MICRIUM */
+
+#if defined(IDIRECT_DEV_TIME)
+
+extern time_t getTimestamp();
+
+time_t idirect_time(time_t * timer)
+{
+    time_t sec = getTimestamp();
+
+    if (timer != NULL)
+        *timer = sec;
+
+    return sec;
+}
+
+#endif
+
+
+WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
+                           word32 maxIdx)
+{
+    int     length = 0;
+    word32  i = *inOutIdx;
+    byte    b;
+
+    *len = 0;    /* default length */
+
+    if ( (i+1) > maxIdx) {   /* for first read */
+        WOLFSSL_MSG("GetLength bad index on input");
+        return BUFFER_E;
+    }
+
+    b = input[i++];
+    if (b >= ASN_LONG_LENGTH) {
+        word32 bytes = b & 0x7F;
+
+        if ( (i+bytes) > maxIdx) {   /* for reading bytes */
+            WOLFSSL_MSG("GetLength bad long length");
+            return BUFFER_E;
+        }
+
+        while (bytes--) {
+            b = input[i++];
+            length = (length << 8) | b;
+        }
+    }
+    else
+        length = b;
+
+    if ( (i+length) > maxIdx) {   /* for user of length */
+        WOLFSSL_MSG("GetLength value exceeds buffer length");
+        return BUFFER_E;
+    }
+
+    *inOutIdx = i;
+    if (length > 0)
+        *len = length;
+
+    return length;
+}
+
+
+WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
+                           word32 maxIdx)
+{
+    int    length = -1;
+    word32 idx    = *inOutIdx;
+
+    if (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
+            GetLength(input, &idx, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    *len      = length;
+    *inOutIdx = idx;
+
+    return length;
+}
+
+
+WOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
+                        word32 maxIdx)
+{
+    int    length = -1;
+    word32 idx    = *inOutIdx;
+
+    if (input[idx++] != (ASN_SET | ASN_CONSTRUCTED) ||
+            GetLength(input, &idx, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    *len      = length;
+    *inOutIdx = idx;
+
+    return length;
+}
+
+
+/* winodws header clash for WinCE using GetVersion */
+WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx,
+                               int* version)
+{
+    word32 idx = *inOutIdx;
+
+    WOLFSSL_ENTER("GetMyVersion");
+
+    if (input[idx++] != ASN_INTEGER)
+        return ASN_PARSE_E;
+
+    if (input[idx++] != 0x01)
+        return ASN_VERSION_E;
+
+    *version  = input[idx++];
+    *inOutIdx = idx;
+
+    return *version;
+}
+
+
+#ifndef NO_PWDBASED
+/* Get small count integer, 32 bits or less */
+static int GetShortInt(const byte* input, word32* inOutIdx, int* number)
+{
+    word32 idx = *inOutIdx;
+    word32 len;
+
+    *number = 0;
+
+    if (input[idx++] != ASN_INTEGER)
+        return ASN_PARSE_E;
+
+    len = input[idx++];
+    if (len > 4)
+        return ASN_PARSE_E;
+
+    while (len--) {
+        *number  = *number << 8 | input[idx++];
+    }
+
+    *inOutIdx = idx;
+
+    return *number;
+}
+#endif /* !NO_PWDBASED */
+
+
+/* May not have one, not an error */
+static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version)
+{
+    word32 idx = *inOutIdx;
+
+    WOLFSSL_ENTER("GetExplicitVersion");
+    if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
+        *inOutIdx = ++idx;  /* eat header */
+        return GetMyVersion(input, inOutIdx, version);
+    }
+
+    /* go back as is */
+    *version = 0;
+
+    return 0;
+}
+
+
+WOLFSSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx,
+                  word32 maxIdx)
+{
+    word32 i = *inOutIdx;
+    byte   b = input[i++];
+    int    length;
+
+    if (b != ASN_INTEGER)
+        return ASN_PARSE_E;
+
+    if (GetLength(input, &i, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    if ( (b = input[i++]) == 0x00)
+        length--;
+    else
+        i--;
+
+    if (mp_init(mpi) != MP_OKAY)
+        return MP_INIT_E;
+
+    if (mp_read_unsigned_bin(mpi, (byte*)input + i, length) != 0) {
+        mp_clear(mpi);
+        return ASN_GETINT_E;
+    }
+
+    *inOutIdx = i + length;
+    return 0;
+}
+
+
+static int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
+                     word32 maxIdx)
+{
+    int    length;
+    word32 i = *inOutIdx;
+    byte   b;
+    *oid = 0;
+
+    b = input[i++];
+    if (b != ASN_OBJECT_ID)
+        return ASN_OBJECT_ID_E;
+
+    if (GetLength(input, &i, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    while(length--)
+        *oid += input[i++];
+    /* just sum it up for now */
+
+    *inOutIdx = i;
+
+    return 0;
+}
+
+
+WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
+                     word32 maxIdx)
+{
+    int    length;
+    word32 i = *inOutIdx;
+    byte   b;
+    *oid = 0;
+
+    WOLFSSL_ENTER("GetAlgoId");
+
+    if (GetSequence(input, &i, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    b = input[i++];
+    if (b != ASN_OBJECT_ID)
+        return ASN_OBJECT_ID_E;
+
+    if (GetLength(input, &i, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    while(length--) {
+        /* odd HC08 compiler behavior here when input[i++] */
+        *oid += input[i];
+        i++;
+    }
+    /* just sum it up for now */
+
+    /* could have NULL tag and 0 terminator, but may not */
+    b = input[i++];
+
+    if (b == ASN_TAG_NULL) {
+        b = input[i++];
+        if (b != 0)
+            return ASN_EXPECT_0_E;
+    }
+    else
+    /* go back, didn't have it */
+        i--;
+
+    *inOutIdx = i;
+
+    return 0;
+}
+
+#ifndef NO_RSA
+
+
+#ifdef HAVE_CAVIUM
+
+static int GetCaviumInt(byte** buff, word16* buffSz, const byte* input,
+                        word32* inOutIdx, word32 maxIdx, void* heap)
+{
+    word32 i = *inOutIdx;
+    byte   b = input[i++];
+    int    length;
+
+    if (b != ASN_INTEGER)
+        return ASN_PARSE_E;
+
+    if (GetLength(input, &i, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    if ( (b = input[i++]) == 0x00)
+        length--;
+    else
+        i--;
+
+    *buffSz = (word16)length;
+    *buff   = XMALLOC(*buffSz, heap, DYNAMIC_TYPE_CAVIUM_RSA);
+    if (*buff == NULL)
+        return MEMORY_E;
+
+    XMEMCPY(*buff, input + i, *buffSz);
+
+    *inOutIdx = i + length;
+    return 0;
+}
+
+static int CaviumRsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
+                                     RsaKey* key, word32 inSz)
+{
+    int   version, length;
+    void* h = key->heap;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetMyVersion(input, inOutIdx, &version) < 0)
+        return ASN_PARSE_E;
+
+    key->type = RSA_PRIVATE;
+
+    if (GetCaviumInt(&key->c_n,  &key->c_nSz,   input, inOutIdx, inSz, h) < 0 ||
+        GetCaviumInt(&key->c_e,  &key->c_eSz,   input, inOutIdx, inSz, h) < 0 ||
+        GetCaviumInt(&key->c_d,  &key->c_dSz,   input, inOutIdx, inSz, h) < 0 ||
+        GetCaviumInt(&key->c_p,  &key->c_pSz,   input, inOutIdx, inSz, h) < 0 ||
+        GetCaviumInt(&key->c_q,  &key->c_qSz,   input, inOutIdx, inSz, h) < 0 ||
+        GetCaviumInt(&key->c_dP, &key->c_dP_Sz, input, inOutIdx, inSz, h) < 0 ||
+        GetCaviumInt(&key->c_dQ, &key->c_dQ_Sz, input, inOutIdx, inSz, h) < 0 ||
+        GetCaviumInt(&key->c_u,  &key->c_uSz,   input, inOutIdx, inSz, h) < 0 )
+            return ASN_RSA_KEY_E;
+
+    return 0;
+}
+
+
+#endif /* HAVE_CAVIUM */
+
+#ifndef HAVE_USER_RSA
+int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
+                        word32 inSz)
+{
+    int    version, length;
+
+#ifdef HAVE_CAVIUM
+    if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
+        return CaviumRsaPrivateKeyDecode(input, inOutIdx, key, inSz);
+#endif
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetMyVersion(input, inOutIdx, &version) < 0)
+        return ASN_PARSE_E;
+
+    key->type = RSA_PRIVATE;
+
+    if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->e,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->d,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->u,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
+
+    return 0;
+}
+#endif /* HAVE_USER_RSA */
+#endif /* NO_RSA */
+
+/* Remove PKCS8 header, move beginning of traditional to beginning of input */
+int ToTraditional(byte* input, word32 sz)
+{
+    word32 inOutIdx = 0, oid;
+    int    version, length;
+
+    if (GetSequence(input, &inOutIdx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetMyVersion(input, &inOutIdx, &version) < 0)
+        return ASN_PARSE_E;
+
+    if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (input[inOutIdx] == ASN_OBJECT_ID) {
+        /* pkcs8 ecc uses slightly different format */
+        inOutIdx++;  /* past id */
+        if (GetLength(input, &inOutIdx, &length, sz) < 0)
+            return ASN_PARSE_E;
+        inOutIdx += length;  /* over sub id, key input will verify */
+    }
+
+    if (input[inOutIdx++] != ASN_OCTET_STRING)
+        return ASN_PARSE_E;
+
+    if (GetLength(input, &inOutIdx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    XMEMMOVE(input, input + inOutIdx, length);
+
+    return length;
+}
+
+
+#ifndef NO_PWDBASED
+
+/* Check To see if PKCS version algo is supported, set id if it is return 0
+   < 0 on error */
+static int CheckAlgo(int first, int second, int* id, int* version)
+{
+    *id      = ALGO_ID_E;
+    *version = PKCS5;   /* default */
+
+    if (first == 1) {
+        switch (second) {
+        case 1:
+            *id = PBE_SHA1_RC4_128;
+            *version = PKCS12;
+            return 0;
+        case 3:
+            *id = PBE_SHA1_DES3;
+            *version = PKCS12;
+            return 0;
+        default:
+            return ALGO_ID_E;
+        }
+    }
+
+    if (first != PKCS5)
+        return ASN_INPUT_E;  /* VERSION ERROR */
+
+    if (second == PBES2) {
+        *version = PKCS5v2;
+        return 0;
+    }
+
+    switch (second) {
+    case 3:                   /* see RFC 2898 for ids */
+        *id = PBE_MD5_DES;
+        return 0;
+    case 10:
+        *id = PBE_SHA1_DES;
+        return 0;
+    default:
+        return ALGO_ID_E;
+
+    }
+}
+
+
+/* Check To see if PKCS v2 algo is supported, set id if it is return 0
+   < 0 on error */
+static int CheckAlgoV2(int oid, int* id)
+{
+    switch (oid) {
+    case 69:
+        *id = PBE_SHA1_DES;
+        return 0;
+    case 652:
+        *id = PBE_SHA1_DES3;
+        return 0;
+    default:
+        return ALGO_ID_E;
+
+    }
+}
+
+
+/* Decrypt intput in place from parameters based on id */
+static int DecryptKey(const char* password, int passwordSz, byte* salt,
+                      int saltSz, int iterations, int id, byte* input,
+                      int length, int version, byte* cbcIv)
+{
+    int typeH;
+    int derivedLen;
+    int decryptionType;
+    int ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* key;
+#else
+    byte key[MAX_KEY_SIZE];
+#endif
+
+    (void)input;
+    (void)length;
+
+    switch (id) {
+        case PBE_MD5_DES:
+            typeH = MD5;
+            derivedLen = 16;           /* may need iv for v1.5 */
+            decryptionType = DES_TYPE;
+            break;
+
+        case PBE_SHA1_DES:
+            typeH = SHA;
+            derivedLen = 16;           /* may need iv for v1.5 */
+            decryptionType = DES_TYPE;
+            break;
+
+        case PBE_SHA1_DES3:
+            typeH = SHA;
+            derivedLen = 32;           /* may need iv for v1.5 */
+            decryptionType = DES3_TYPE;
+            break;
+
+        case PBE_SHA1_RC4_128:
+            typeH = SHA;
+            derivedLen = 16;
+            decryptionType = RC4_TYPE;
+            break;
+
+        default:
+            return ALGO_ID_E;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    key = (byte*)XMALLOC(MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (key == NULL)
+        return MEMORY_E;
+#endif
+
+    if (version == PKCS5v2)
+        ret = wc_PBKDF2(key, (byte*)password, passwordSz,
+                        salt, saltSz, iterations, derivedLen, typeH);
+#ifndef NO_SHA
+    else if (version == PKCS5)
+        ret = wc_PBKDF1(key, (byte*)password, passwordSz,
+                        salt, saltSz, iterations, derivedLen, typeH);
+#endif
+    else if (version == PKCS12) {
+        int  i, idx = 0;
+        byte unicodePasswd[MAX_UNICODE_SZ];
+
+        if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) {
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return UNICODE_SIZE_E;
+        }
+
+        for (i = 0; i < passwordSz; i++) {
+            unicodePasswd[idx++] = 0x00;
+            unicodePasswd[idx++] = (byte)password[i];
+        }
+        /* add trailing NULL */
+        unicodePasswd[idx++] = 0x00;
+        unicodePasswd[idx++] = 0x00;
+
+        ret =  wc_PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz,
+                            iterations, derivedLen, typeH, 1);
+        if (decryptionType != RC4_TYPE)
+            ret += wc_PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz,
+                                iterations, 8, typeH, 2);
+    }
+    else {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return ALGO_ID_E;
+    }
+
+    if (ret != 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return ret;
+    }
+
+    switch (decryptionType) {
+#ifndef NO_DES3
+        case DES_TYPE:
+        {
+            Des    dec;
+            byte*  desIv = key + 8;
+
+            if (version == PKCS5v2 || version == PKCS12)
+                desIv = cbcIv;
+
+            ret = wc_Des_SetKey(&dec, key, desIv, DES_DECRYPTION);
+            if (ret != 0) {
+#ifdef WOLFSSL_SMALL_STACK
+                XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+                return ret;
+            }
+
+            wc_Des_CbcDecrypt(&dec, input, input, length);
+            break;
+        }
+
+        case DES3_TYPE:
+        {
+            Des3   dec;
+            byte*  desIv = key + 24;
+
+            if (version == PKCS5v2 || version == PKCS12)
+                desIv = cbcIv;
+            ret = wc_Des3_SetKey(&dec, key, desIv, DES_DECRYPTION);
+            if (ret != 0) {
+#ifdef WOLFSSL_SMALL_STACK
+                XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+                return ret;
+            }
+            ret = wc_Des3_CbcDecrypt(&dec, input, input, length);
+            if (ret != 0) {
+#ifdef WOLFSSL_SMALL_STACK
+                XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+                return ret;
+            }
+            break;
+        }
+#endif
+#ifndef NO_RC4
+        case RC4_TYPE:
+        {
+            Arc4    dec;
+
+            wc_Arc4SetKey(&dec, key, derivedLen);
+            wc_Arc4Process(&dec, input, input, length);
+            break;
+        }
+#endif
+
+        default:
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return ALGO_ID_E;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return 0;
+}
+
+
+/* Remove Encrypted PKCS8 header, move beginning of traditional to beginning
+   of input */
+int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
+{
+    word32 inOutIdx = 0, oid;
+    int    first, second, length, version, saltSz, id;
+    int    iterations = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  salt = NULL;
+    byte*  cbcIv = NULL;
+#else
+    byte   salt[MAX_SALT_SIZE];
+    byte   cbcIv[MAX_IV_SIZE];
+#endif
+
+    if (GetSequence(input, &inOutIdx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
+        return ASN_PARSE_E;
+
+    first  = input[inOutIdx - 2];   /* PKCS version alwyas 2nd to last byte */
+    second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
+
+    if (CheckAlgo(first, second, &id, &version) < 0)
+        return ASN_INPUT_E;  /* Algo ID error */
+
+    if (version == PKCS5v2) {
+
+        if (GetSequence(input, &inOutIdx, &length, sz) < 0)
+            return ASN_PARSE_E;
+
+        if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
+            return ASN_PARSE_E;
+
+        if (oid != PBKDF2_OID)
+            return ASN_PARSE_E;
+    }
+
+    if (GetSequence(input, &inOutIdx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (input[inOutIdx++] != ASN_OCTET_STRING)
+        return ASN_PARSE_E;
+
+    if (GetLength(input, &inOutIdx, &saltSz, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (saltSz > MAX_SALT_SIZE)
+        return ASN_PARSE_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+    salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (salt == NULL)
+        return MEMORY_E;
+#endif
+
+    XMEMCPY(salt, &input[inOutIdx], saltSz);
+    inOutIdx += saltSz;
+
+    if (GetShortInt(input, &inOutIdx, &iterations) < 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return ASN_PARSE_E;
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (cbcIv == NULL) {
+        XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    if (version == PKCS5v2) {
+        /* get encryption algo */
+        if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) {
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return ASN_PARSE_E;
+        }
+
+        if (CheckAlgoV2(oid, &id) < 0) {
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return ASN_PARSE_E;  /* PKCS v2 algo id error */
+        }
+
+        if (input[inOutIdx++] != ASN_OCTET_STRING) {
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return ASN_PARSE_E;
+        }
+
+        if (GetLength(input, &inOutIdx, &length, sz) < 0) {
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return ASN_PARSE_E;
+        }
+
+        XMEMCPY(cbcIv, &input[inOutIdx], length);
+        inOutIdx += length;
+    }
+
+    if (input[inOutIdx++] != ASN_OCTET_STRING) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return ASN_PARSE_E;
+    }
+
+    if (GetLength(input, &inOutIdx, &length, sz) < 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return ASN_PARSE_E;
+    }
+
+    if (DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
+                   input + inOutIdx, length, version, cbcIv) < 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return ASN_INPUT_E;  /* decrypt failure */
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    XMEMMOVE(input, input + inOutIdx, length);
+    return ToTraditional(input, length);
+}
+
+#endif /* NO_PWDBASED */
+
+#ifndef NO_RSA
+
+#ifndef HAVE_USER_RSA
+int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
+                       word32 inSz)
+{
+    int    length;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    key->type = RSA_PUBLIC;
+
+#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
+    {
+    byte b = input[*inOutIdx];
+    if (b != ASN_INTEGER) {
+        /* not from decoded cert, will have algo id, skip past */
+        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
+
+        b = input[(*inOutIdx)++];
+        if (b != ASN_OBJECT_ID)
+            return ASN_OBJECT_ID_E;
+
+        if (GetLength(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
+
+        *inOutIdx += length;   /* skip past */
+
+        /* could have NULL tag and 0 terminator, but may not */
+        b = input[(*inOutIdx)++];
+
+        if (b == ASN_TAG_NULL) {
+            b = input[(*inOutIdx)++];
+            if (b != 0)
+                return ASN_EXPECT_0_E;
+        }
+        else
+        /* go back, didn't have it */
+            (*inOutIdx)--;
+
+        /* should have bit tag length and seq next */
+        b = input[(*inOutIdx)++];
+        if (b != ASN_BIT_STRING)
+            return ASN_BITSTR_E;
+
+        if (GetLength(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
+
+        /* could have 0 */
+        b = input[(*inOutIdx)++];
+        if (b != 0)
+            (*inOutIdx)--;
+
+        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+            return ASN_PARSE_E;
+    }  /* end if */
+    }  /* openssl var block */
+#endif /* OPENSSL_EXTRA */
+
+    if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->e,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
+
+    return 0;
+}
+
+/* import RSA public key elements (n, e) into RsaKey structure (key) */
+int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
+                             word32 eSz, RsaKey* key)
+{
+    if (n == NULL || e == NULL || key == NULL)
+        return BAD_FUNC_ARG;
+
+    key->type = RSA_PUBLIC;
+
+    if (mp_init(&key->n) != MP_OKAY)
+        return MP_INIT_E;
+
+    if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) {
+        mp_clear(&key->n);
+        return ASN_GETINT_E;
+    }
+
+    if (mp_init(&key->e) != MP_OKAY) {
+        mp_clear(&key->n);
+        return MP_INIT_E;
+    }
+
+    if (mp_read_unsigned_bin(&key->e, e, eSz) != 0) {
+        mp_clear(&key->n);
+        mp_clear(&key->e);
+        return ASN_GETINT_E;
+    }
+
+    return 0;
+}
+#endif /* HAVE_USER_RSA */
+#endif
+
+#ifndef NO_DH
+
+int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
+{
+    int    length;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->g,  input, inOutIdx, inSz) < 0 )  return ASN_DH_KEY_E;
+
+    return 0;
+}
+
+
+int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
+                 byte* g, word32* gInOutSz)
+{
+    word32 i = 0;
+    byte   b;
+    int    length;
+
+    if (GetSequence(input, &i, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    b = input[i++];
+    if (b != ASN_INTEGER)
+        return ASN_PARSE_E;
+
+    if (GetLength(input, &i, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if ( (b = input[i++]) == 0x00)
+        length--;
+    else
+        i--;
+
+    if (length <= (int)*pInOutSz) {
+        XMEMCPY(p, &input[i], length);
+        *pInOutSz = length;
+    }
+    else
+        return BUFFER_E;
+
+    i += length;
+
+    b = input[i++];
+    if (b != ASN_INTEGER)
+        return ASN_PARSE_E;
+
+    if (GetLength(input, &i, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (length <= (int)*gInOutSz) {
+        XMEMCPY(g, &input[i], length);
+        *gInOutSz = length;
+    }
+    else
+        return BUFFER_E;
+
+    return 0;
+}
+
+#endif /* NO_DH */
+
+
+#ifndef NO_DSA
+
+int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
+                        word32 inSz)
+{
+    int    length;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->y,  input, inOutIdx, inSz) < 0 )
+        return ASN_DH_KEY_E;
+
+    key->type = DSA_PUBLIC;
+    return 0;
+}
+
+
+int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
+                        word32 inSz)
+{
+    int    length, version;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetMyVersion(input, inOutIdx, &version) < 0)
+        return ASN_PARSE_E;
+
+    if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->y,  input, inOutIdx, inSz) < 0 ||
+        GetInt(&key->x,  input, inOutIdx, inSz) < 0 )
+        return ASN_DH_KEY_E;
+
+    key->type = DSA_PRIVATE;
+    return 0;
+}
+
+static mp_int* GetDsaInt(DsaKey* key, int idx)
+{
+    if (idx == 0)
+        return &key->p;
+    if (idx == 1)
+        return &key->q;
+    if (idx == 2)
+        return &key->g;
+    if (idx == 3)
+        return &key->y;
+    if (idx == 4)
+        return &key->x;
+
+    return NULL;
+}
+
+/* Release Tmp DSA resources */
+static INLINE void FreeTmpDsas(byte** tmps)
+{
+    int i;
+
+    for (i = 0; i < DSA_INTS; i++)
+        XFREE(tmps[i], NULL, DYNAMIC_TYPE_DSA);
+}
+
+/* Convert DsaKey key to DER format, write to output (inLen), return bytes
+ written */
+int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
+{
+    word32 seqSz, verSz, rawLen, intTotalLen = 0;
+    word32 sizes[DSA_INTS];
+    int    i, j, outLen, ret = 0, lbit;
+
+    byte  seq[MAX_SEQ_SZ];
+    byte  ver[MAX_VERSION_SZ];
+    byte* tmps[DSA_INTS];
+
+    if (!key || !output)
+        return BAD_FUNC_ARG;
+
+    if (key->type != DSA_PRIVATE)
+        return BAD_FUNC_ARG;
+
+    for (i = 0; i < DSA_INTS; i++)
+        tmps[i] = NULL;
+
+    /* write all big ints from key to DER tmps */
+    for (i = 0; i < DSA_INTS; i++) {
+        mp_int* keyInt = GetDsaInt(key, i);
+
+        /* leading zero */
+        if ((mp_count_bits(keyInt) & 7) == 0 || mp_iszero(keyInt) == MP_YES)
+            lbit = 1;
+        else
+            lbit = 0;
+
+        rawLen = mp_unsigned_bin_size(keyInt) + lbit;
+
+        tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, NULL, DYNAMIC_TYPE_DSA);
+        if (tmps[i] == NULL) {
+            ret = MEMORY_E;
+            break;
+        }
+
+        tmps[i][0] = ASN_INTEGER;
+        sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1 + lbit; /* tag & lbit */
+
+        if (sizes[i] <= MAX_SEQ_SZ) {
+            int err;
+
+            /* leading zero */
+            if (lbit)
+                tmps[i][sizes[i]-1] = 0x00;
+
+            err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]);
+            if (err == MP_OKAY) {
+                sizes[i] += (rawLen-lbit); /* lbit included in rawLen */
+                intTotalLen += sizes[i];
+            }
+            else {
+                ret = err;
+                break;
+            }
+        }
+        else {
+            ret = ASN_INPUT_E;
+            break;
+        }
+    }
+
+    if (ret != 0) {
+        FreeTmpDsas(tmps);
+        return ret;
+    }
+
+    /* make headers */
+    verSz = SetMyVersion(0, ver, FALSE);
+    seqSz = SetSequence(verSz + intTotalLen, seq);
+
+    outLen = seqSz + verSz + intTotalLen;
+    if (outLen > (int)inLen)
+        return BAD_FUNC_ARG;
+
+    /* write to output */
+    XMEMCPY(output, seq, seqSz);
+    j = seqSz;
+    XMEMCPY(output + j, ver, verSz);
+    j += verSz;
+
+    for (i = 0; i < DSA_INTS; i++) {
+        XMEMCPY(output + j, tmps[i], sizes[i]);
+        j += sizes[i];
+    }
+    FreeTmpDsas(tmps);
+
+    return outLen;
+}
+
+#endif /* NO_DSA */
+
+
+void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
+{
+    cert->publicKey       = 0;
+    cert->pubKeySize      = 0;
+    cert->pubKeyStored    = 0;
+    cert->version         = 0;
+    cert->signature       = 0;
+    cert->subjectCN       = 0;
+    cert->subjectCNLen    = 0;
+    cert->subjectCNEnc    = CTC_UTF8;
+    cert->subjectCNStored = 0;
+    cert->weOwnAltNames   = 0;
+    cert->altNames        = NULL;
+#ifndef IGNORE_NAME_CONSTRAINTS
+    cert->altEmailNames   = NULL;
+    cert->permittedNames  = NULL;
+    cert->excludedNames   = NULL;
+#endif /* IGNORE_NAME_CONSTRAINTS */
+    cert->issuer[0]       = '\0';
+    cert->subject[0]      = '\0';
+    cert->source          = source;  /* don't own */
+    cert->srcIdx          = 0;
+    cert->maxIdx          = inSz;    /* can't go over this index */
+    cert->heap            = heap;
+    XMEMSET(cert->serial, 0, EXTERNAL_SERIAL_SIZE);
+    cert->serialSz        = 0;
+    cert->extensions      = 0;
+    cert->extensionsSz    = 0;
+    cert->extensionsIdx   = 0;
+    cert->extAuthInfo     = NULL;
+    cert->extAuthInfoSz   = 0;
+    cert->extCrlInfo      = NULL;
+    cert->extCrlInfoSz    = 0;
+    XMEMSET(cert->extSubjKeyId, 0, KEYID_SIZE);
+    cert->extSubjKeyIdSet = 0;
+    XMEMSET(cert->extAuthKeyId, 0, KEYID_SIZE);
+    cert->extAuthKeyIdSet = 0;
+    cert->extKeyUsageSet  = 0;
+    cert->extKeyUsage     = 0;
+    cert->extExtKeyUsageSet = 0;
+    cert->extExtKeyUsage    = 0;
+    cert->isCA            = 0;
+#ifdef HAVE_PKCS7
+    cert->issuerRaw       = NULL;
+    cert->issuerRawLen    = 0;
+#endif
+#ifdef WOLFSSL_CERT_GEN
+    cert->subjectSN       = 0;
+    cert->subjectSNLen    = 0;
+    cert->subjectSNEnc    = CTC_UTF8;
+    cert->subjectC        = 0;
+    cert->subjectCLen     = 0;
+    cert->subjectCEnc     = CTC_PRINTABLE;
+    cert->subjectL        = 0;
+    cert->subjectLLen     = 0;
+    cert->subjectLEnc     = CTC_UTF8;
+    cert->subjectST       = 0;
+    cert->subjectSTLen    = 0;
+    cert->subjectSTEnc    = CTC_UTF8;
+    cert->subjectO        = 0;
+    cert->subjectOLen     = 0;
+    cert->subjectOEnc     = CTC_UTF8;
+    cert->subjectOU       = 0;
+    cert->subjectOULen    = 0;
+    cert->subjectOUEnc    = CTC_UTF8;
+    cert->subjectEmail    = 0;
+    cert->subjectEmailLen = 0;
+#endif /* WOLFSSL_CERT_GEN */
+    cert->beforeDate      = NULL;
+    cert->beforeDateLen   = 0;
+    cert->afterDate       = NULL;
+    cert->afterDateLen    = 0;
+#ifdef OPENSSL_EXTRA
+    XMEMSET(&cert->issuerName, 0, sizeof(DecodedName));
+    XMEMSET(&cert->subjectName, 0, sizeof(DecodedName));
+    cert->extBasicConstSet = 0;
+    cert->extBasicConstCrit = 0;
+    cert->extBasicConstPlSet = 0;
+    cert->pathLength = 0;
+    cert->extSubjAltNameSet = 0;
+    cert->extSubjAltNameCrit = 0;
+    cert->extAuthKeyIdCrit = 0;
+    cert->extSubjKeyIdCrit = 0;
+    cert->extKeyUsageCrit = 0;
+    cert->extExtKeyUsageCrit = 0;
+    cert->extExtKeyUsageSrc = NULL;
+    cert->extExtKeyUsageSz = 0;
+    cert->extExtKeyUsageCount = 0;
+    cert->extAuthKeyIdSrc = NULL;
+    cert->extAuthKeyIdSz = 0;
+    cert->extSubjKeyIdSrc = NULL;
+    cert->extSubjKeyIdSz = 0;
+#endif /* OPENSSL_EXTRA */
+#if defined(OPENSSL_EXTRA) || !defined(IGNORE_NAME_CONSTRAINTS)
+    cert->extNameConstraintSet = 0;
+#endif /* OPENSSL_EXTRA || !IGNORE_NAME_CONSTRAINTS */
+#ifdef HAVE_ECC
+    cert->pkCurveOID = 0;
+#endif /* HAVE_ECC */
+#ifdef WOLFSSL_SEP
+    cert->deviceTypeSz = 0;
+    cert->deviceType = NULL;
+    cert->hwTypeSz = 0;
+    cert->hwType = NULL;
+    cert->hwSerialNumSz = 0;
+    cert->hwSerialNum = NULL;
+    #ifdef OPENSSL_EXTRA
+        cert->extCertPolicySet = 0;
+        cert->extCertPolicyCrit = 0;
+    #endif /* OPENSSL_EXTRA */
+#endif /* WOLFSSL_SEP */
+#ifdef WOLFSSL_CERT_EXT
+    XMEMSET(cert->extCertPolicies, 0, MAX_CERTPOL_NB*MAX_CERTPOL_SZ);
+    cert->extCertPoliciesNb = 0;
+#endif
+}
+
+
+void FreeAltNames(DNS_entry* altNames, void* heap)
+{
+    (void)heap;
+
+    while (altNames) {
+        DNS_entry* tmp = altNames->next;
+
+        XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
+        XFREE(altNames,       heap, DYNAMIC_TYPE_ALTNAME);
+        altNames = tmp;
+    }
+}
+
+#ifndef IGNORE_NAME_CONSTRAINTS
+
+void FreeNameSubtrees(Base_entry* names, void* heap)
+{
+    (void)heap;
+
+    while (names) {
+        Base_entry* tmp = names->next;
+
+        XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME);
+        XFREE(names,       heap, DYNAMIC_TYPE_ALTNAME);
+        names = tmp;
+    }
+}
+
+#endif /* IGNORE_NAME_CONSTRAINTS */
+
+void FreeDecodedCert(DecodedCert* cert)
+{
+    if (cert->subjectCNStored == 1)
+        XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
+    if (cert->pubKeyStored == 1)
+        XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    if (cert->weOwnAltNames && cert->altNames)
+        FreeAltNames(cert->altNames, cert->heap);
+#ifndef IGNORE_NAME_CONSTRAINTS
+    if (cert->altEmailNames)
+        FreeAltNames(cert->altEmailNames, cert->heap);
+    if (cert->permittedNames)
+        FreeNameSubtrees(cert->permittedNames, cert->heap);
+    if (cert->excludedNames)
+        FreeNameSubtrees(cert->excludedNames, cert->heap);
+#endif /* IGNORE_NAME_CONSTRAINTS */
+#ifdef WOLFSSL_SEP
+    XFREE(cert->deviceType, cert->heap, 0);
+    XFREE(cert->hwType, cert->heap, 0);
+    XFREE(cert->hwSerialNum, cert->heap, 0);
+#endif /* WOLFSSL_SEP */
+#ifdef OPENSSL_EXTRA
+    if (cert->issuerName.fullName != NULL)
+        XFREE(cert->issuerName.fullName, NULL, DYNAMIC_TYPE_X509);
+    if (cert->subjectName.fullName != NULL)
+        XFREE(cert->subjectName.fullName, NULL, DYNAMIC_TYPE_X509);
+#endif /* OPENSSL_EXTRA */
+}
+
+
+static int GetCertHeader(DecodedCert* cert)
+{
+    int ret = 0, len;
+    byte serialTmp[EXTERNAL_SERIAL_SIZE];
+#if defined(WOLFSSL_SMALL_STACK) && defined(USE_FAST_MATH)
+    mp_int* mpi = NULL;
+#else
+    mp_int stack_mpi;
+    mp_int* mpi = &stack_mpi;
+#endif
+
+    if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    cert->certBegin = cert->srcIdx;
+
+    if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
+        return ASN_PARSE_E;
+    cert->sigIndex = len + cert->srcIdx;
+
+    if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version) < 0)
+        return ASN_PARSE_E;
+
+#if defined(WOLFSSL_SMALL_STACK) && defined(USE_FAST_MATH)
+    mpi = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (mpi == NULL)
+        return MEMORY_E;
+#endif
+
+    if (GetInt(mpi, cert->source, &cert->srcIdx, cert->maxIdx) < 0) {
+#if defined(WOLFSSL_SMALL_STACK) && defined(USE_FAST_MATH)
+        XFREE(mpi, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return ASN_PARSE_E;
+    }
+
+    len = mp_unsigned_bin_size(mpi);
+    if (len < (int)sizeof(serialTmp)) {
+        if ( (ret = mp_to_unsigned_bin(mpi, serialTmp)) == MP_OKAY) {
+            XMEMCPY(cert->serial, serialTmp, len);
+            cert->serialSz = len;
+        }
+    }
+    mp_clear(mpi);
+
+#if defined(WOLFSSL_SMALL_STACK) && defined(USE_FAST_MATH)
+    XFREE(mpi, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+#if !defined(NO_RSA)
+/* Store Rsa Key, may save later, Dsa could use in future */
+static int StoreRsaKey(DecodedCert* cert)
+{
+    int    length;
+    word32 recvd = cert->srcIdx;
+
+    if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    recvd = cert->srcIdx - recvd;
+    length += recvd;
+
+    while (recvd--)
+       cert->srcIdx--;
+
+    cert->pubKeySize = length;
+    cert->publicKey = cert->source + cert->srcIdx;
+    cert->srcIdx += length;
+
+    return 0;
+}
+#endif
+
+
+#ifdef HAVE_ECC
+
+    /* return 0 on sucess if the ECC curve oid sum is supported */
+    static int CheckCurve(word32 oid)
+    {
+        int ret = 0;
+
+        switch (oid) {
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
+            case ECC_160R1:
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
+            case ECC_192R1:
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
+            case ECC_224R1:
+#endif
+#if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
+            case ECC_256R1:
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
+            case ECC_384R1:
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
+            case ECC_521R1:
+#endif
+                break;
+
+            default:
+                ret = ALGO_ID_E;
+        }
+
+        return ret;
+    }
+
+#endif /* HAVE_ECC */
+
+
+static int GetKey(DecodedCert* cert)
+{
+    int length;
+#ifdef HAVE_NTRU
+    int tmpIdx = cert->srcIdx;
+#endif
+
+    if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    if (GetAlgoId(cert->source, &cert->srcIdx, &cert->keyOID, cert->maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    switch (cert->keyOID) {
+   #ifndef NO_RSA
+        case RSAk:
+        {
+            byte b = cert->source[cert->srcIdx++];
+            if (b != ASN_BIT_STRING)
+                return ASN_BITSTR_E;
+
+            if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0)
+                return ASN_PARSE_E;
+            b = cert->source[cert->srcIdx++];
+            if (b != 0x00)
+                return ASN_EXPECT_0_E;
+
+            return StoreRsaKey(cert);
+        }
+
+    #endif /* NO_RSA */
+    #ifdef HAVE_NTRU
+        case NTRUk:
+        {
+            const byte* key = &cert->source[tmpIdx];
+            byte*       next = (byte*)key;
+            word16      keyLen;
+            word32      rc;
+            word32      remaining = cert->maxIdx - cert->srcIdx;
+#ifdef WOLFSSL_SMALL_STACK
+            byte*       keyBlob = NULL;
+#else
+            byte        keyBlob[MAX_NTRU_KEY_SZ];
+#endif
+            rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
+                                &keyLen, NULL, &next, &remaining);
+            if (rc != NTRU_OK)
+                return ASN_NTRU_KEY_E;
+            if (keyLen > MAX_NTRU_KEY_SZ)
+                return ASN_NTRU_KEY_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+            keyBlob = (byte*)XMALLOC(MAX_NTRU_KEY_SZ, NULL,
+                                     DYNAMIC_TYPE_TMP_BUFFER);
+            if (keyBlob == NULL)
+                return MEMORY_E;
+#endif
+
+            rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
+                                &keyLen, keyBlob, &next, &remaining);
+            if (rc != NTRU_OK) {
+#ifdef WOLFSSL_SMALL_STACK
+                XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+                return ASN_NTRU_KEY_E;
+            }
+
+            if ( (next - key) < 0) {
+#ifdef WOLFSSL_SMALL_STACK
+                XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+                return ASN_NTRU_KEY_E;
+            }
+
+            cert->srcIdx = tmpIdx + (int)(next - key);
+
+            cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap,
+                                              DYNAMIC_TYPE_PUBLIC_KEY);
+            if (cert->publicKey == NULL) {
+#ifdef WOLFSSL_SMALL_STACK
+                XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+                return MEMORY_E;
+            }
+            XMEMCPY(cert->publicKey, keyBlob, keyLen);
+            cert->pubKeyStored = 1;
+            cert->pubKeySize   = keyLen;
+
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+            return 0;
+        }
+    #endif /* HAVE_NTRU */
+    #ifdef HAVE_ECC
+        case ECDSAk:
+        {
+            int    oidSz = 0;
+            byte   b = cert->source[cert->srcIdx++];
+
+            if (b != ASN_OBJECT_ID)
+                return ASN_OBJECT_ID_E;
+
+            if (GetLength(cert->source,&cert->srcIdx,&oidSz,cert->maxIdx) < 0)
+                return ASN_PARSE_E;
+
+            while(oidSz--)
+                cert->pkCurveOID += cert->source[cert->srcIdx++];
+
+            if (CheckCurve(cert->pkCurveOID) < 0)
+                return ECC_CURVE_OID_E;
+
+            /* key header */
+            b = cert->source[cert->srcIdx++];
+            if (b != ASN_BIT_STRING)
+                return ASN_BITSTR_E;
+
+            if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0)
+                return ASN_PARSE_E;
+            b = cert->source[cert->srcIdx++];
+            if (b != 0x00)
+                return ASN_EXPECT_0_E;
+
+            /* actual key, use length - 1 since ate preceding 0 */
+            length -= 1;
+
+            cert->publicKey = (byte*) XMALLOC(length, cert->heap,
+                                              DYNAMIC_TYPE_PUBLIC_KEY);
+            if (cert->publicKey == NULL)
+                return MEMORY_E;
+            XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length);
+            cert->pubKeyStored = 1;
+            cert->pubKeySize   = length;
+
+            cert->srcIdx += length;
+
+            return 0;
+        }
+    #endif /* HAVE_ECC */
+        default:
+            return ASN_UNKNOWN_OID_E;
+    }
+}
+
+
+/* process NAME, either issuer or subject */
+static int GetName(DecodedCert* cert, int nameType)
+{
+    int    length;  /* length of all distinguished names */
+    int    dummy;
+    int    ret;
+    char*  full;
+    byte*  hash;
+    word32 idx;
+    #ifdef OPENSSL_EXTRA
+        DecodedName* dName =
+                  (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName;
+    #endif /* OPENSSL_EXTRA */
+
+    WOLFSSL_MSG("Getting Cert Name");
+
+    if (nameType == ISSUER) {
+        full = cert->issuer;
+        hash = cert->issuerHash;
+    }
+    else {
+        full = cert->subject;
+        hash = cert->subjectHash;
+    }
+
+    if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) {
+        WOLFSSL_MSG("Trying optional prefix...");
+
+        if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
+            return ASN_PARSE_E;
+
+        cert->srcIdx += length;
+        WOLFSSL_MSG("Got optional prefix");
+    }
+
+    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
+     * calculated over the entire DER encoding of the Name field, including
+     * the tag and length. */
+    idx = cert->srcIdx;
+    if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
+        return ASN_PARSE_E;
+
+#ifdef NO_SHA
+    ret = wc_Sha256Hash(&cert->source[idx], length + cert->srcIdx - idx, hash);
+#else
+    ret = wc_ShaHash(&cert->source[idx], length + cert->srcIdx - idx, hash);
+#endif
+    if (ret != 0)
+        return ret;
+
+    length += cert->srcIdx;
+    idx = 0;
+
+#ifdef HAVE_PKCS7
+    /* store pointer to raw issuer */
+    if (nameType == ISSUER) {
+        cert->issuerRaw = &cert->source[cert->srcIdx];
+        cert->issuerRawLen = length - cert->srcIdx;
+    }
+#endif
+#ifndef IGNORE_NAME_CONSTRAINTS
+    if (nameType == SUBJECT) {
+        cert->subjectRaw = &cert->source[cert->srcIdx];
+        cert->subjectRawLen = length - cert->srcIdx;
+    }
+#endif
+
+    while (cert->srcIdx < (word32)length) {
+        byte   b;
+        byte   joint[2];
+        byte   tooBig = FALSE;
+        int    oidSz;
+
+        if (GetSet(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) {
+            WOLFSSL_MSG("Cert name lacks set header, trying sequence");
+        }
+
+        if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0)
+            return ASN_PARSE_E;
+
+        b = cert->source[cert->srcIdx++];
+        if (b != ASN_OBJECT_ID)
+            return ASN_OBJECT_ID_E;
+
+        if (GetLength(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx) < 0)
+            return ASN_PARSE_E;
+
+        XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint));
+
+        /* v1 name types */
+        if (joint[0] == 0x55 && joint[1] == 0x04) {
+            byte   id;
+            byte   copy = FALSE;
+            int    strLen;
+
+            cert->srcIdx += 2;
+            id = cert->source[cert->srcIdx++];
+            b  = cert->source[cert->srcIdx++]; /* encoding */
+
+            if (GetLength(cert->source, &cert->srcIdx, &strLen,
+                          cert->maxIdx) < 0)
+                return ASN_PARSE_E;
+
+            if ( (strLen + 14) > (int)(ASN_NAME_MAX - idx)) {
+                /* include biggest pre fix header too 4 = "/serialNumber=" */
+                WOLFSSL_MSG("ASN Name too big, skipping");
+                tooBig = TRUE;
+            }
+
+            if (id == ASN_COMMON_NAME) {
+                if (nameType == SUBJECT) {
+                    cert->subjectCN = (char *)&cert->source[cert->srcIdx];
+                    cert->subjectCNLen = strLen;
+                    cert->subjectCNEnc = b;
+                }
+
+                if (!tooBig) {
+                    XMEMCPY(&full[idx], "/CN=", 4);
+                    idx += 4;
+                    copy = TRUE;
+                }
+                #ifdef OPENSSL_EXTRA
+                    dName->cnIdx = cert->srcIdx;
+                    dName->cnLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+            else if (id == ASN_SUR_NAME) {
+                if (!tooBig) {
+                    XMEMCPY(&full[idx], "/SN=", 4);
+                    idx += 4;
+                    copy = TRUE;
+                }
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectSN = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectSNLen = strLen;
+                        cert->subjectSNEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #ifdef OPENSSL_EXTRA
+                    dName->snIdx = cert->srcIdx;
+                    dName->snLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+            else if (id == ASN_COUNTRY_NAME) {
+                if (!tooBig) {
+                    XMEMCPY(&full[idx], "/C=", 3);
+                    idx += 3;
+                    copy = TRUE;
+                }
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectC = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectCLen = strLen;
+                        cert->subjectCEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #ifdef OPENSSL_EXTRA
+                    dName->cIdx = cert->srcIdx;
+                    dName->cLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+            else if (id == ASN_LOCALITY_NAME) {
+                if (!tooBig) {
+                    XMEMCPY(&full[idx], "/L=", 3);
+                    idx += 3;
+                    copy = TRUE;
+                }
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectL = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectLLen = strLen;
+                        cert->subjectLEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #ifdef OPENSSL_EXTRA
+                    dName->lIdx = cert->srcIdx;
+                    dName->lLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+            else if (id == ASN_STATE_NAME) {
+                if (!tooBig) {
+                    XMEMCPY(&full[idx], "/ST=", 4);
+                    idx += 4;
+                    copy = TRUE;
+                }
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectST = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectSTLen = strLen;
+                        cert->subjectSTEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #ifdef OPENSSL_EXTRA
+                    dName->stIdx = cert->srcIdx;
+                    dName->stLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+            else if (id == ASN_ORG_NAME) {
+                if (!tooBig) {
+                    XMEMCPY(&full[idx], "/O=", 3);
+                    idx += 3;
+                    copy = TRUE;
+                }
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectO = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectOLen = strLen;
+                        cert->subjectOEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #ifdef OPENSSL_EXTRA
+                    dName->oIdx = cert->srcIdx;
+                    dName->oLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+            else if (id == ASN_ORGUNIT_NAME) {
+                if (!tooBig) {
+                    XMEMCPY(&full[idx], "/OU=", 4);
+                    idx += 4;
+                    copy = TRUE;
+                }
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectOU = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectOULen = strLen;
+                        cert->subjectOUEnc = b;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #ifdef OPENSSL_EXTRA
+                    dName->ouIdx = cert->srcIdx;
+                    dName->ouLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+            else if (id == ASN_SERIAL_NUMBER) {
+                if (!tooBig) {
+                   XMEMCPY(&full[idx], "/serialNumber=", 14);
+                   idx += 14;
+                   copy = TRUE;
+                }
+                #ifdef OPENSSL_EXTRA
+                    dName->snIdx = cert->srcIdx;
+                    dName->snLen = strLen;
+                #endif /* OPENSSL_EXTRA */
+            }
+
+            if (copy && !tooBig) {
+                XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
+                idx += strLen;
+            }
+
+            cert->srcIdx += strLen;
+        }
+        else {
+            /* skip */
+            byte email = FALSE;
+            byte uid   = FALSE;
+            int  adv;
+
+            if (joint[0] == 0x2a && joint[1] == 0x86)  /* email id hdr */
+                email = TRUE;
+
+            if (joint[0] == 0x9  && joint[1] == 0x92)  /* uid id hdr */
+                uid = TRUE;
+
+            cert->srcIdx += oidSz + 1;
+
+            if (GetLength(cert->source, &cert->srcIdx, &adv, cert->maxIdx) < 0)
+                return ASN_PARSE_E;
+
+            if (adv > (int)(ASN_NAME_MAX - idx)) {
+                WOLFSSL_MSG("ASN name too big, skipping");
+                tooBig = TRUE;
+            }
+
+            if (email) {
+                if ( (14 + adv) > (int)(ASN_NAME_MAX - idx)) {
+                    WOLFSSL_MSG("ASN name too big, skipping");
+                    tooBig = TRUE;
+                }
+                if (!tooBig) {
+                    XMEMCPY(&full[idx], "/emailAddress=", 14);
+                    idx += 14;
+                }
+
+                #ifdef WOLFSSL_CERT_GEN
+                    if (nameType == SUBJECT) {
+                        cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
+                        cert->subjectEmailLen = adv;
+                    }
+                #endif /* WOLFSSL_CERT_GEN */
+                #ifdef OPENSSL_EXTRA
+                    dName->emailIdx = cert->srcIdx;
+                    dName->emailLen = adv;
+                #endif /* OPENSSL_EXTRA */
+                #ifndef IGNORE_NAME_CONSTRAINTS
+                    {
+                        DNS_entry* emailName = NULL;
+
+                        emailName = (DNS_entry*)XMALLOC(sizeof(DNS_entry),
+                                              cert->heap, DYNAMIC_TYPE_ALTNAME);
+                        if (emailName == NULL) {
+                            WOLFSSL_MSG("\tOut of Memory");
+                            return MEMORY_E;
+                        }
+                        emailName->name = (char*)XMALLOC(adv + 1,
+                                              cert->heap, DYNAMIC_TYPE_ALTNAME);
+                        if (emailName->name == NULL) {
+                            WOLFSSL_MSG("\tOut of Memory");
+                            return MEMORY_E;
+                        }
+                        XMEMCPY(emailName->name,
+                                              &cert->source[cert->srcIdx], adv);
+                        emailName->name[adv] = 0;
+
+                        emailName->next = cert->altEmailNames;
+                        cert->altEmailNames = emailName;
+                    }
+                #endif /* IGNORE_NAME_CONSTRAINTS */
+                if (!tooBig) {
+                    XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
+                    idx += adv;
+                }
+            }
+
+            if (uid) {
+                if ( (5 + adv) > (int)(ASN_NAME_MAX - idx)) {
+                    WOLFSSL_MSG("ASN name too big, skipping");
+                    tooBig = TRUE;
+                }
+                if (!tooBig) {
+                    XMEMCPY(&full[idx], "/UID=", 5);
+                    idx += 5;
+
+                    XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
+                    idx += adv;
+                }
+                #ifdef OPENSSL_EXTRA
+                    dName->uidIdx = cert->srcIdx;
+                    dName->uidLen = adv;
+                #endif /* OPENSSL_EXTRA */
+            }
+
+            cert->srcIdx += adv;
+        }
+    }
+    full[idx++] = 0;
+
+    #ifdef OPENSSL_EXTRA
+    {
+        int totalLen = 0;
+
+        if (dName->cnLen != 0)
+            totalLen += dName->cnLen + 4;
+        if (dName->snLen != 0)
+            totalLen += dName->snLen + 4;
+        if (dName->cLen != 0)
+            totalLen += dName->cLen + 3;
+        if (dName->lLen != 0)
+            totalLen += dName->lLen + 3;
+        if (dName->stLen != 0)
+            totalLen += dName->stLen + 4;
+        if (dName->oLen != 0)
+            totalLen += dName->oLen + 3;
+        if (dName->ouLen != 0)
+            totalLen += dName->ouLen + 4;
+        if (dName->emailLen != 0)
+            totalLen += dName->emailLen + 14;
+        if (dName->uidLen != 0)
+            totalLen += dName->uidLen + 5;
+        if (dName->serialLen != 0)
+            totalLen += dName->serialLen + 14;
+
+        dName->fullName = (char*)XMALLOC(totalLen + 1, NULL, DYNAMIC_TYPE_X509);
+        if (dName->fullName != NULL) {
+            idx = 0;
+
+            if (dName->cnLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], "/CN=", 4);
+                idx += 4;
+                XMEMCPY(&dName->fullName[idx],
+                                     &cert->source[dName->cnIdx], dName->cnLen);
+                dName->cnIdx = idx;
+                idx += dName->cnLen;
+            }
+            if (dName->snLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], "/SN=", 4);
+                idx += 4;
+                XMEMCPY(&dName->fullName[idx],
+                                     &cert->source[dName->snIdx], dName->snLen);
+                dName->snIdx = idx;
+                idx += dName->snLen;
+            }
+            if (dName->cLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], "/C=", 3);
+                idx += 3;
+                XMEMCPY(&dName->fullName[idx],
+                                       &cert->source[dName->cIdx], dName->cLen);
+                dName->cIdx = idx;
+                idx += dName->cLen;
+            }
+            if (dName->lLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], "/L=", 3);
+                idx += 3;
+                XMEMCPY(&dName->fullName[idx],
+                                       &cert->source[dName->lIdx], dName->lLen);
+                dName->lIdx = idx;
+                idx += dName->lLen;
+            }
+            if (dName->stLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], "/ST=", 4);
+                idx += 4;
+                XMEMCPY(&dName->fullName[idx],
+                                     &cert->source[dName->stIdx], dName->stLen);
+                dName->stIdx = idx;
+                idx += dName->stLen;
+            }
+            if (dName->oLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], "/O=", 3);
+                idx += 3;
+                XMEMCPY(&dName->fullName[idx],
+                                       &cert->source[dName->oIdx], dName->oLen);
+                dName->oIdx = idx;
+                idx += dName->oLen;
+            }
+            if (dName->ouLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], "/OU=", 4);
+                idx += 4;
+                XMEMCPY(&dName->fullName[idx],
+                                     &cert->source[dName->ouIdx], dName->ouLen);
+                dName->ouIdx = idx;
+                idx += dName->ouLen;
+            }
+            if (dName->emailLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], "/emailAddress=", 14);
+                idx += 14;
+                XMEMCPY(&dName->fullName[idx],
+                               &cert->source[dName->emailIdx], dName->emailLen);
+                dName->emailIdx = idx;
+                idx += dName->emailLen;
+            }
+            if (dName->uidLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], "/UID=", 5);
+                idx += 5;
+                XMEMCPY(&dName->fullName[idx],
+                                   &cert->source[dName->uidIdx], dName->uidLen);
+                dName->uidIdx = idx;
+                idx += dName->uidLen;
+            }
+            if (dName->serialLen != 0) {
+                dName->entryCount++;
+                XMEMCPY(&dName->fullName[idx], "/serialNumber=", 14);
+                idx += 14;
+                XMEMCPY(&dName->fullName[idx],
+                             &cert->source[dName->serialIdx], dName->serialLen);
+                dName->serialIdx = idx;
+                idx += dName->serialLen;
+            }
+            dName->fullName[idx] = '\0';
+            dName->fullNameLen = totalLen;
+        }
+    }
+    #endif /* OPENSSL_EXTRA */
+
+    return 0;
+}
+
+
+#ifndef NO_TIME_H
+
+/* to the second */
+static int DateGreaterThan(const struct tm* a, const struct tm* b)
+{
+    if (a->tm_year > b->tm_year)
+        return 1;
+
+    if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
+        return 1;
+
+    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
+           a->tm_mday > b->tm_mday)
+        return 1;
+
+    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
+        a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
+        return 1;
+
+    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
+        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
+        a->tm_min > b->tm_min)
+        return 1;
+
+    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
+        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
+        a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
+        return 1;
+
+    return 0; /* false */
+}
+
+
+static INLINE int DateLessThan(const struct tm* a, const struct tm* b)
+{
+    return DateGreaterThan(b,a);
+}
+
+
+/* like atoi but only use first byte */
+/* Make sure before and after dates are valid */
+int ValidateDate(const byte* date, byte format, int dateType)
+{
+    time_t ltime;
+    struct tm  certTime;
+    struct tm* localTime;
+    struct tm* tmpTime = NULL;
+    int    i = 0;
+
+#if defined(FREESCALE_MQX) || defined(TIME_OVERRIDES)
+    struct tm tmpTimeStorage;
+    tmpTime = &tmpTimeStorage;
+#else
+    (void)tmpTime;
+#endif
+
+    ltime = XTIME(0);
+    XMEMSET(&certTime, 0, sizeof(certTime));
+
+    if (format == ASN_UTC_TIME) {
+        if (btoi(date[0]) >= 5)
+            certTime.tm_year = 1900;
+        else
+            certTime.tm_year = 2000;
+    }
+    else  { /* format == GENERALIZED_TIME */
+        certTime.tm_year += btoi(date[i++]) * 1000;
+        certTime.tm_year += btoi(date[i++]) * 100;
+    }
+
+    /* adjust tm_year, tm_mon */
+    GetTime((int*)&certTime.tm_year, date, &i); certTime.tm_year -= 1900;
+    GetTime((int*)&certTime.tm_mon,  date, &i); certTime.tm_mon  -= 1;
+    GetTime((int*)&certTime.tm_mday, date, &i);
+    GetTime((int*)&certTime.tm_hour, date, &i);
+    GetTime((int*)&certTime.tm_min,  date, &i);
+    GetTime((int*)&certTime.tm_sec,  date, &i);
+
+        if (date[i] != 'Z') {     /* only Zulu supported for this profile */
+        WOLFSSL_MSG("Only Zulu time supported for this profile");
+        return 0;
+    }
+
+    localTime = XGMTIME(&ltime, tmpTime);
+
+    if (localTime == NULL) {
+        WOLFSSL_MSG("XGMTIME failed");
+        return 0;
+    }
+
+    if (dateType == BEFORE) {
+        if (DateLessThan(localTime, &certTime))
+            return 0;
+    }
+    else
+        if (DateGreaterThan(localTime, &certTime))
+            return 0;
+
+    return 1;
+}
+
+#endif /* NO_TIME_H */
+
+
+static int GetDate(DecodedCert* cert, int dateType)
+{
+    int    length;
+    byte   date[MAX_DATE_SIZE];
+    byte   b;
+    word32 startIdx = 0;
+
+    if (dateType == BEFORE)
+        cert->beforeDate = &cert->source[cert->srcIdx];
+    else
+        cert->afterDate = &cert->source[cert->srcIdx];
+    startIdx = cert->srcIdx;
+
+    b = cert->source[cert->srcIdx++];
+    if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
+        return ASN_TIME_E;
+
+    if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
+        return ASN_DATE_SZ_E;
+
+    XMEMCPY(date, &cert->source[cert->srcIdx], length);
+    cert->srcIdx += length;
+
+    if (dateType == BEFORE)
+        cert->beforeDateLen = cert->srcIdx - startIdx;
+    else
+        cert->afterDateLen  = cert->srcIdx - startIdx;
+
+    if (!XVALIDATE_DATE(date, b, dateType)) {
+        if (dateType == BEFORE)
+            return ASN_BEFORE_DATE_E;
+        else
+            return ASN_AFTER_DATE_E;
+    }
+
+    return 0;
+}
+
+
+static int GetValidity(DecodedCert* cert, int verify)
+{
+    int length;
+    int badDate = 0;
+
+    if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    if (GetDate(cert, BEFORE) < 0 && verify)
+        badDate = ASN_BEFORE_DATE_E;           /* continue parsing */
+
+    if (GetDate(cert, AFTER) < 0 && verify)
+        return ASN_AFTER_DATE_E;
+
+    if (badDate != 0)
+        return badDate;
+
+    return 0;
+}
+
+
+int DecodeToKey(DecodedCert* cert, int verify)
+{
+    int badDate = 0;
+    int ret;
+
+    if ( (ret = GetCertHeader(cert)) < 0)
+        return ret;
+
+    WOLFSSL_MSG("Got Cert Header");
+
+    if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID,
+                          cert->maxIdx)) < 0)
+        return ret;
+
+    WOLFSSL_MSG("Got Algo ID");
+
+    if ( (ret = GetName(cert, ISSUER)) < 0)
+        return ret;
+
+    if ( (ret = GetValidity(cert, verify)) < 0)
+        badDate = ret;
+
+    if ( (ret = GetName(cert, SUBJECT)) < 0)
+        return ret;
+
+    WOLFSSL_MSG("Got Subject Name");
+
+    if ( (ret = GetKey(cert)) < 0)
+        return ret;
+
+    WOLFSSL_MSG("Got Key");
+
+    if (badDate != 0)
+        return badDate;
+
+    return ret;
+}
+
+
+static int GetSignature(DecodedCert* cert)
+{
+    int    length;
+    byte   b = cert->source[cert->srcIdx++];
+
+    if (b != ASN_BIT_STRING)
+        return ASN_BITSTR_E;
+
+    if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    cert->sigLength = length;
+
+    b = cert->source[cert->srcIdx++];
+    if (b != 0x00)
+        return ASN_EXPECT_0_E;
+
+    cert->sigLength--;
+    cert->signature = &cert->source[cert->srcIdx];
+    cert->srcIdx += cert->sigLength;
+
+    return 0;
+}
+
+
+static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
+{
+    output[0] = ASN_OCTET_STRING;
+    output[1] = (byte)digSz;
+    XMEMCPY(&output[2], digest, digSz);
+
+    return digSz + 2;
+}
+
+
+static word32 BytePrecision(word32 value)
+{
+    word32 i;
+    for (i = sizeof(value); i; --i)
+        if (value >> ((i - 1) * WOLFSSL_BIT_SIZE))
+            break;
+
+    return i;
+}
+
+
+WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output)
+{
+    word32 i = 0, j;
+
+    if (length < ASN_LONG_LENGTH)
+        output[i++] = (byte)length;
+    else {
+        output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
+
+        for (j = BytePrecision(length); j; --j) {
+            output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
+            i++;
+        }
+    }
+
+    return i;
+}
+
+
+WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output)
+{
+    output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
+    return SetLength(len, output + 1) + 1;
+}
+
+WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output)
+{
+    output[0] = ASN_OCTET_STRING;
+    return SetLength(len, output + 1) + 1;
+}
+
+/* Write a set header to output */
+WOLFSSL_LOCAL word32 SetSet(word32 len, byte* output)
+{
+    output[0] = ASN_SET | ASN_CONSTRUCTED;
+    return SetLength(len, output + 1) + 1;
+}
+
+WOLFSSL_LOCAL word32 SetImplicit(byte tag, byte number, word32 len, byte* output)
+{
+
+    output[0] = ((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0)
+                    | ASN_CONTEXT_SPECIFIC | number;
+    return SetLength(len, output + 1) + 1;
+}
+
+WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output)
+{
+    output[0] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number;
+    return SetLength(len, output + 1) + 1;
+}
+
+
+#if defined(HAVE_ECC) && (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
+
+static int SetCurve(ecc_key* key, byte* output)
+{
+
+    /* curve types */
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
+    static const byte ECC_192v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
+                                             0x03, 0x01, 0x01};
+#endif
+#if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
+    static const byte ECC_256v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
+                                            0x03, 0x01, 0x07};
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
+    static const byte ECC_160r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
+                                             0x02};
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
+    static const byte ECC_224r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
+                                             0x21};
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
+    static const byte ECC_384r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
+                                             0x22};
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
+    static const byte ECC_521r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
+                                             0x23};
+#endif
+
+    int    oidSz = 0;
+    int    idx = 0;
+    int    lenSz = 0;
+    const  byte* oid = 0;
+
+    output[0] = ASN_OBJECT_ID;
+    idx++;
+
+    switch (key->dp->size) {
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
+        case 20:
+            oidSz = sizeof(ECC_160r1_AlgoID);
+            oid   =        ECC_160r1_AlgoID;
+            break;
+#endif
+
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
+        case 24:
+            oidSz = sizeof(ECC_192v1_AlgoID);
+            oid   =        ECC_192v1_AlgoID;
+            break;
+#endif
+
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
+        case 28:
+            oidSz = sizeof(ECC_224r1_AlgoID);
+            oid   =        ECC_224r1_AlgoID;
+            break;
+#endif
+
+#if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
+        case 32:
+            oidSz = sizeof(ECC_256v1_AlgoID);
+            oid   =        ECC_256v1_AlgoID;
+            break;
+#endif
+
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
+        case 48:
+            oidSz = sizeof(ECC_384r1_AlgoID);
+            oid   =        ECC_384r1_AlgoID;
+            break;
+#endif
+
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
+        case 66:
+            oidSz = sizeof(ECC_521r1_AlgoID);
+            oid   =        ECC_521r1_AlgoID;
+            break;
+#endif
+
+        default:
+            return ASN_UNKNOWN_OID_E;
+    }
+    lenSz = SetLength(oidSz, output+idx);
+    idx += lenSz;
+
+    XMEMCPY(output+idx, oid, oidSz);
+    idx += oidSz;
+
+    return idx;
+}
+
+#endif /* HAVE_ECC && WOLFSSL_CERT_GEN */
+
+
+WOLFSSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
+{
+    /* adding TAG_NULL and 0 to end */
+
+    /* hashTypes */
+    static const byte shaAlgoID[]    = { 0x2b, 0x0e, 0x03, 0x02, 0x1a,
+                                         0x05, 0x00 };
+    static const byte sha256AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+                                         0x04, 0x02, 0x01, 0x05, 0x00 };
+    static const byte sha384AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+                                         0x04, 0x02, 0x02, 0x05, 0x00 };
+    static const byte sha512AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+                                         0x04, 0x02, 0x03, 0x05, 0x00 };
+    static const byte md5AlgoID[]    = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+                                         0x02, 0x05, 0x05, 0x00  };
+    static const byte md2AlgoID[]    = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+                                         0x02, 0x02, 0x05, 0x00};
+
+    /* blkTypes, no NULL tags because IV is there instead */
+    static const byte desCbcAlgoID[]  = { 0x2B, 0x0E, 0x03, 0x02, 0x07 };
+    static const byte des3CbcAlgoID[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
+                                          0x0D, 0x03, 0x07 };
+
+    /* RSA sigTypes */
+    #ifndef NO_RSA
+        static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
+                                            0x0d, 0x01, 0x01, 0x04, 0x05, 0x00};
+        static const byte shawRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
+                                            0x0d, 0x01, 0x01, 0x05, 0x05, 0x00};
+        static const byte sha256wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
+                                            0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00};
+        static const byte sha384wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
+                                            0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00};
+        static const byte sha512wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
+                                            0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00};
+    #endif /* NO_RSA */
+
+    /* ECDSA sigTypes */
+    #ifdef HAVE_ECC
+        static const byte shawECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
+                                                 0x04, 0x01, 0x05, 0x00};
+        static const byte sha256wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
+                                                 0x04, 0x03, 0x02, 0x05, 0x00};
+        static const byte sha384wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
+                                                 0x04, 0x03, 0x03, 0x05, 0x00};
+        static const byte sha512wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
+                                                 0x04, 0x03, 0x04, 0x05, 0x00};
+    #endif /* HAVE_ECC */
+
+    /* RSA keyType */
+    #ifndef NO_RSA
+        static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+                                            0x01, 0x01, 0x01, 0x05, 0x00};
+    #endif /* NO_RSA */
+
+    #ifdef HAVE_ECC
+        /* ECC keyType */
+        /* no tags, so set tagSz smaller later */
+        static const byte ECC_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
+                                           0x02, 0x01};
+    #endif /* HAVE_ECC */
+
+    int    algoSz = 0;
+    int    tagSz  = 2;   /* tag null and terminator */
+    word32 idSz, seqSz;
+    const  byte* algoName = 0;
+    byte ID_Length[MAX_LENGTH_SZ];
+    byte seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */
+
+    if (type == hashType) {
+        switch (algoOID) {
+        case SHAh:
+            algoSz = sizeof(shaAlgoID);
+            algoName = shaAlgoID;
+            break;
+
+        case SHA256h:
+            algoSz = sizeof(sha256AlgoID);
+            algoName = sha256AlgoID;
+            break;
+
+        case SHA384h:
+            algoSz = sizeof(sha384AlgoID);
+            algoName = sha384AlgoID;
+            break;
+
+        case SHA512h:
+            algoSz = sizeof(sha512AlgoID);
+            algoName = sha512AlgoID;
+            break;
+
+        case MD2h:
+            algoSz = sizeof(md2AlgoID);
+            algoName = md2AlgoID;
+            break;
+
+        case MD5h:
+            algoSz = sizeof(md5AlgoID);
+            algoName = md5AlgoID;
+            break;
+
+        default:
+            WOLFSSL_MSG("Unknown Hash Algo");
+            return 0;  /* UNKOWN_HASH_E; */
+        }
+    }
+    else if (type == blkType) {
+        switch (algoOID) {
+        case DESb:
+            algoSz = sizeof(desCbcAlgoID);
+            algoName = desCbcAlgoID;
+            tagSz = 0;
+            break;
+        case DES3b:
+            algoSz = sizeof(des3CbcAlgoID);
+            algoName = des3CbcAlgoID;
+            tagSz = 0;
+            break;
+        default:
+            WOLFSSL_MSG("Unknown Block Algo");
+            return 0;
+        }
+    }
+    else if (type == sigType) {    /* sigType */
+        switch (algoOID) {
+        #ifndef NO_RSA
+            case CTC_MD5wRSA:
+                algoSz = sizeof(md5wRSA_AlgoID);
+                algoName = md5wRSA_AlgoID;
+                break;
+
+            case CTC_SHAwRSA:
+                algoSz = sizeof(shawRSA_AlgoID);
+                algoName = shawRSA_AlgoID;
+                break;
+
+            case CTC_SHA256wRSA:
+                algoSz = sizeof(sha256wRSA_AlgoID);
+                algoName = sha256wRSA_AlgoID;
+                break;
+
+            case CTC_SHA384wRSA:
+                algoSz = sizeof(sha384wRSA_AlgoID);
+                algoName = sha384wRSA_AlgoID;
+                break;
+
+            case CTC_SHA512wRSA:
+                algoSz = sizeof(sha512wRSA_AlgoID);
+                algoName = sha512wRSA_AlgoID;
+                break;
+        #endif /* NO_RSA */
+        #ifdef HAVE_ECC
+            case CTC_SHAwECDSA:
+                algoSz = sizeof(shawECDSA_AlgoID);
+                algoName = shawECDSA_AlgoID;
+                break;
+
+            case CTC_SHA256wECDSA:
+                algoSz = sizeof(sha256wECDSA_AlgoID);
+                algoName = sha256wECDSA_AlgoID;
+                break;
+
+            case CTC_SHA384wECDSA:
+                algoSz = sizeof(sha384wECDSA_AlgoID);
+                algoName = sha384wECDSA_AlgoID;
+                break;
+
+            case CTC_SHA512wECDSA:
+                algoSz = sizeof(sha512wECDSA_AlgoID);
+                algoName = sha512wECDSA_AlgoID;
+                break;
+        #endif /* HAVE_ECC */
+        default:
+            WOLFSSL_MSG("Unknown Signature Algo");
+            return 0;
+        }
+    }
+    else if (type == keyType) {    /* keyType */
+        switch (algoOID) {
+        #ifndef NO_RSA
+            case RSAk:
+                algoSz = sizeof(RSA_AlgoID);
+                algoName = RSA_AlgoID;
+                break;
+        #endif /* NO_RSA */
+        #ifdef HAVE_ECC
+            case ECDSAk:
+                algoSz = sizeof(ECC_AlgoID);
+                algoName = ECC_AlgoID;
+                tagSz = 0;
+                break;
+        #endif /* HAVE_ECC */
+        default:
+            WOLFSSL_MSG("Unknown Key Algo");
+            return 0;
+        }
+    }
+    else {
+        WOLFSSL_MSG("Unknown Algo type");
+        return 0;
+    }
+
+    idSz  = SetLength(algoSz - tagSz, ID_Length); /* don't include tags */
+    seqSz = SetSequence(idSz + algoSz + 1 + curveSz, seqArray);
+                 /* +1 for object id, curveID of curveSz follows for ecc */
+    seqArray[seqSz++] = ASN_OBJECT_ID;
+
+    XMEMCPY(output, seqArray, seqSz);
+    XMEMCPY(output + seqSz, ID_Length, idSz);
+    XMEMCPY(output + seqSz + idSz, algoName, algoSz);
+
+    return seqSz + idSz + algoSz;
+
+}
+
+
+word32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz,
+                          int hashOID)
+{
+    byte digArray[MAX_ENCODED_DIG_SZ];
+    byte algoArray[MAX_ALGO_SZ];
+    byte seqArray[MAX_SEQ_SZ];
+    word32 encDigSz, algoSz, seqSz;
+
+    encDigSz = SetDigest(digest, digSz, digArray);
+    algoSz   = SetAlgoID(hashOID, algoArray, hashType, 0);
+    seqSz    = SetSequence(encDigSz + algoSz, seqArray);
+
+    XMEMCPY(out, seqArray, seqSz);
+    XMEMCPY(out + seqSz, algoArray, algoSz);
+    XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
+
+    return encDigSz + algoSz + seqSz;
+}
+
+
+int wc_GetCTC_HashOID(int type)
+{
+    switch (type) {
+#ifdef WOLFSSL_MD2
+        case MD2:
+            return MD2h;
+#endif
+#ifndef NO_MD5
+        case MD5:
+            return MD5h;
+#endif
+#ifndef NO_SHA
+        case SHA:
+            return SHAh;
+#endif
+#ifndef NO_SHA256
+        case SHA256:
+            return SHA256h;
+#endif
+#ifdef WOLFSSL_SHA384
+        case SHA384:
+            return SHA384h;
+#endif
+#ifdef WOLFSSL_SHA512
+        case SHA512:
+            return SHA512h;
+#endif
+        default:
+            return 0;
+    };
+}
+
+
+/* return true (1) or false (0) for Confirmation */
+static int ConfirmSignature(const byte* buf, word32 bufSz,
+    const byte* key, word32 keySz, word32 keyOID,
+    const byte* sig, word32 sigSz, word32 sigOID,
+    void* heap)
+{
+    int  typeH = 0, digestSz = 0, ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* digest;
+#else
+    byte digest[MAX_DIGEST_SIZE];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    digest = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (digest == NULL)
+        return 0; /* not confirmed */
+#endif
+
+    (void)key;
+    (void)keySz;
+    (void)sig;
+    (void)sigSz;
+    (void)heap;
+
+    switch (sigOID) {
+    #ifndef NO_MD5
+        case CTC_MD5wRSA:
+        if (wc_Md5Hash(buf, bufSz, digest) == 0) {
+            typeH    = MD5h;
+            digestSz = MD5_DIGEST_SIZE;
+        }
+        break;
+    #endif
+    #if defined(WOLFSSL_MD2)
+        case CTC_MD2wRSA:
+        if (wc_Md2Hash(buf, bufSz, digest) == 0) {
+            typeH    = MD2h;
+            digestSz = MD2_DIGEST_SIZE;
+        }
+        break;
+    #endif
+    #ifndef NO_SHA
+        case CTC_SHAwRSA:
+        case CTC_SHAwDSA:
+        case CTC_SHAwECDSA:
+        if (wc_ShaHash(buf, bufSz, digest) == 0) {
+            typeH    = SHAh;
+            digestSz = SHA_DIGEST_SIZE;
+        }
+        break;
+    #endif
+    #ifndef NO_SHA256
+        case CTC_SHA256wRSA:
+        case CTC_SHA256wECDSA:
+        if (wc_Sha256Hash(buf, bufSz, digest) == 0) {
+            typeH    = SHA256h;
+            digestSz = SHA256_DIGEST_SIZE;
+        }
+        break;
+    #endif
+    #ifdef WOLFSSL_SHA512
+        case CTC_SHA512wRSA:
+        case CTC_SHA512wECDSA:
+        if (wc_Sha512Hash(buf, bufSz, digest) == 0) {
+            typeH    = SHA512h;
+            digestSz = SHA512_DIGEST_SIZE;
+        }
+        break;
+    #endif
+    #ifdef WOLFSSL_SHA384
+        case CTC_SHA384wRSA:
+        case CTC_SHA384wECDSA:
+        if (wc_Sha384Hash(buf, bufSz, digest) == 0) {
+            typeH    = SHA384h;
+            digestSz = SHA384_DIGEST_SIZE;
+        }
+        break;
+    #endif
+        default:
+            WOLFSSL_MSG("Verify Signautre has unsupported type");
+    }
+
+    if (typeH == 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return 0; /* not confirmed */
+    }
+
+    switch (keyOID) {
+    #ifndef NO_RSA
+        case RSAk:
+        {
+            word32 idx = 0;
+            int    encodedSigSz, verifySz;
+            byte*  out;
+#ifdef WOLFSSL_SMALL_STACK
+            RsaKey* pubKey;
+            byte* plain;
+            byte* encodedSig;
+#else
+            RsaKey pubKey[1];
+            byte plain[MAX_ENCODED_SIG_SZ];
+            byte encodedSig[MAX_ENCODED_SIG_SZ];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+            pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            plain = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+
+            if (pubKey == NULL || plain == NULL || encodedSig == NULL) {
+                WOLFSSL_MSG("Failed to allocate memory at ConfirmSignature");
+
+                if (pubKey)
+                    XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                if (plain)
+                    XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                if (encodedSig)
+                    XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+                break; /* not confirmed */
+            }
+#endif
+
+            if (sigSz > MAX_ENCODED_SIG_SZ) {
+                WOLFSSL_MSG("Verify Signautre is too big");
+            }
+            else if (wc_InitRsaKey(pubKey, heap) != 0) {
+                WOLFSSL_MSG("InitRsaKey failed");
+            }
+            else if (wc_RsaPublicKeyDecode(key, &idx, pubKey, keySz) < 0) {
+                WOLFSSL_MSG("ASN Key decode error RSA");
+            }
+            else {
+                XMEMCPY(plain, sig, sigSz);
+
+                if ((verifySz = wc_RsaSSL_VerifyInline(plain, sigSz, &out,
+                                                                 pubKey)) < 0) {
+                    WOLFSSL_MSG("Rsa SSL verify error");
+                }
+                else {
+                    /* make sure we're right justified */
+                    encodedSigSz =
+                        wc_EncodeSignature(encodedSig, digest, digestSz, typeH);
+                    if (encodedSigSz != verifySz ||
+                                XMEMCMP(out, encodedSig, encodedSigSz) != 0) {
+                        WOLFSSL_MSG("Rsa SSL verify match encode error");
+                    }
+                    else
+                        ret = 1; /* match */
+
+                    #ifdef WOLFSSL_DEBUG_ENCODING
+                    {
+                        int x;
+
+                        printf("wolfssl encodedSig:\n");
+
+                        for (x = 0; x < encodedSigSz; x++) {
+                            printf("%02x ", encodedSig[x]);
+                            if ( (x % 16) == 15)
+                                printf("\n");
+                        }
+
+                        printf("\n");
+                        printf("actual digest:\n");
+
+                        for (x = 0; x < verifySz; x++) {
+                            printf("%02x ", out[x]);
+                            if ( (x % 16) == 15)
+                                printf("\n");
+                        }
+
+                        printf("\n");
+                    }
+                    #endif /* WOLFSSL_DEBUG_ENCODING */
+
+                }
+
+            }
+
+            wc_FreeRsaKey(pubKey);
+
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(pubKey,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(plain,      NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            break;
+        }
+
+    #endif /* NO_RSA */
+    #ifdef HAVE_ECC
+        case ECDSAk:
+        {
+            int verify = 0;
+#ifdef WOLFSSL_SMALL_STACK
+            ecc_key* pubKey;
+#else
+            ecc_key pubKey[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+            pubKey = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+            if (pubKey == NULL) {
+                WOLFSSL_MSG("Failed to allocate pubKey");
+                break; /* not confirmed */
+            }
+#endif
+
+            if (wc_ecc_init(pubKey) < 0) {
+                WOLFSSL_MSG("Failed to initialize key");
+                break; /* not confirmed */
+            }
+            if (wc_ecc_import_x963(key, keySz, pubKey) < 0) {
+                WOLFSSL_MSG("ASN Key import error ECC");
+            }
+            else {
+                if (wc_ecc_verify_hash(sig, sigSz, digest, digestSz, &verify,
+                                                                pubKey) != 0) {
+                    WOLFSSL_MSG("ECC verify hash error");
+                }
+                else if (1 != verify) {
+                    WOLFSSL_MSG("ECC Verify didn't match");
+                } else
+                    ret = 1; /* match */
+
+            }
+            wc_ecc_free(pubKey);
+
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            break;
+        }
+    #endif /* HAVE_ECC */
+        default:
+            WOLFSSL_MSG("Verify Key type unknown");
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+#ifndef IGNORE_NAME_CONSTRAINTS
+
+static int MatchBaseName(int type, const char* name, int nameSz,
+                         const char* base, int baseSz)
+{
+    if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 ||
+            name[0] == '.' || nameSz < baseSz ||
+            (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE))
+        return 0;
+
+    /* If an email type, handle special cases where the base is only
+     * a domain, or is an email address itself. */
+    if (type == ASN_RFC822_TYPE) {
+        const char* p = NULL;
+        int count = 0;
+
+        if (base[0] != '.') {
+            p = base;
+            count = 0;
+
+            /* find the '@' in the base */
+            while (*p != '@' && count < baseSz) {
+                count++;
+                p++;
+            }
+
+            /* No '@' in base, reset p to NULL */
+            if (count >= baseSz)
+                p = NULL;
+        }
+
+        if (p == NULL) {
+            /* Base isn't an email address, it is a domain name,
+             * wind the name forward one character past its '@'. */
+            p = name;
+            count = 0;
+            while (*p != '@' && count < baseSz) {
+                count++;
+                p++;
+            }
+
+            if (count < baseSz && *p == '@') {
+                name = p + 1;
+                nameSz -= count + 1;
+            }
+        }
+    }
+
+    if ((type == ASN_DNS_TYPE || type == ASN_RFC822_TYPE) && base[0] == '.') {
+        int szAdjust = nameSz - baseSz;
+        name += szAdjust;
+        nameSz -= szAdjust;
+    }
+
+    while (nameSz > 0) {
+        if (XTOLOWER((unsigned char)*name++) !=
+                                               XTOLOWER((unsigned char)*base++))
+            return 0;
+        nameSz--;
+    }
+
+    return 1;
+}
+
+
+static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
+{
+    if (signer == NULL || cert == NULL)
+        return 0;
+
+    /* Check against the excluded list */
+    if (signer->excludedNames) {
+        Base_entry* base = signer->excludedNames;
+
+        while (base != NULL) {
+            if (base->type == ASN_DNS_TYPE) {
+                DNS_entry* name = cert->altNames;
+                while (name != NULL) {
+                    if (MatchBaseName(ASN_DNS_TYPE,
+                                          name->name, (int)XSTRLEN(name->name),
+                                          base->name, base->nameSz))
+                        return 0;
+                    name = name->next;
+                }
+            }
+            else if (base->type == ASN_RFC822_TYPE) {
+                DNS_entry* name = cert->altEmailNames;
+                while (name != NULL) {
+                    if (MatchBaseName(ASN_RFC822_TYPE,
+                                          name->name, (int)XSTRLEN(name->name),
+                                          base->name, base->nameSz))
+                        return 0;
+
+                    name = name->next;
+                }
+            }
+            else if (base->type == ASN_DIR_TYPE) {
+                if (cert->subjectRawLen == base->nameSz &&
+                    XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) {
+
+                    return 0;
+                }
+            }
+            base = base->next;
+        }
+    }
+
+    /* Check against the permitted list */
+    if (signer->permittedNames != NULL) {
+        int needDns = 0;
+        int matchDns = 0;
+        int needEmail = 0;
+        int matchEmail = 0;
+        int needDir = 0;
+        int matchDir = 0;
+        Base_entry* base = signer->permittedNames;
+
+        while (base != NULL) {
+            if (base->type == ASN_DNS_TYPE) {
+                DNS_entry* name = cert->altNames;
+
+                if (name != NULL)
+                    needDns = 1;
+
+                while (name != NULL) {
+                    matchDns = MatchBaseName(ASN_DNS_TYPE,
+                                          name->name, (int)XSTRLEN(name->name),
+                                          base->name, base->nameSz);
+                    name = name->next;
+                }
+            }
+            else if (base->type == ASN_RFC822_TYPE) {
+                DNS_entry* name = cert->altEmailNames;
+
+                if (name != NULL)
+                    needEmail = 1;
+
+                while (name != NULL) {
+                    matchEmail = MatchBaseName(ASN_DNS_TYPE,
+                                          name->name, (int)XSTRLEN(name->name),
+                                          base->name, base->nameSz);
+                    name = name->next;
+                }
+            }
+            else if (base->type == ASN_DIR_TYPE) {
+                needDir = 1;
+                if (cert->subjectRaw != NULL &&
+                    cert->subjectRawLen == base->nameSz &&
+                    XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) {
+
+                    matchDir = 1;
+                }
+            }
+            base = base->next;
+        }
+
+        if ((needDns && !matchDns) || (needEmail && !matchEmail) ||
+            (needDir && !matchDir)) {
+
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+#endif /* IGNORE_NAME_CONSTRAINTS */
+
+
+static int DecodeAltNames(byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0;
+    int length = 0;
+
+    WOLFSSL_ENTER("DecodeAltNames");
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tBad Sequence");
+        return ASN_PARSE_E;
+    }
+
+    cert->weOwnAltNames = 1;
+
+    while (length > 0) {
+        byte       b = input[idx++];
+
+        length--;
+
+        /* Save DNS Type names in the altNames list. */
+        /* Save Other Type names in the cert's OidMap */
+        if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
+            DNS_entry* dnsEntry;
+            int strLen;
+            word32 lenStartIdx = idx;
+
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfail: str length");
+                return ASN_PARSE_E;
+            }
+            length -= (idx - lenStartIdx);
+
+            dnsEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
+                                        DYNAMIC_TYPE_ALTNAME);
+            if (dnsEntry == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                return ASN_PARSE_E;
+            }
+
+            dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
+                                         DYNAMIC_TYPE_ALTNAME);
+            if (dnsEntry->name == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
+                return ASN_PARSE_E;
+            }
+
+            XMEMCPY(dnsEntry->name, &input[idx], strLen);
+            dnsEntry->name[strLen] = '\0';
+
+            dnsEntry->next = cert->altNames;
+            cert->altNames = dnsEntry;
+
+            length -= strLen;
+            idx    += strLen;
+        }
+#ifndef IGNORE_NAME_CONSTRAINTS
+        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
+            DNS_entry* emailEntry;
+            int strLen;
+            word32 lenStartIdx = idx;
+
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfail: str length");
+                return ASN_PARSE_E;
+            }
+            length -= (idx - lenStartIdx);
+
+            emailEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
+                                        DYNAMIC_TYPE_ALTNAME);
+            if (emailEntry == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                return ASN_PARSE_E;
+            }
+
+            emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
+                                         DYNAMIC_TYPE_ALTNAME);
+            if (emailEntry->name == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
+                return ASN_PARSE_E;
+            }
+
+            XMEMCPY(emailEntry->name, &input[idx], strLen);
+            emailEntry->name[strLen] = '\0';
+
+            emailEntry->next = cert->altEmailNames;
+            cert->altEmailNames = emailEntry;
+
+            length -= strLen;
+            idx    += strLen;
+        }
+#endif /* IGNORE_NAME_CONSTRAINTS */
+#ifdef WOLFSSL_SEP
+        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))
+        {
+            int strLen;
+            word32 lenStartIdx = idx;
+            word32 oid = 0;
+
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfail: other name length");
+                return ASN_PARSE_E;
+            }
+            /* Consume the rest of this sequence. */
+            length -= (strLen + idx - lenStartIdx);
+
+            if (GetObjectId(input, &idx, &oid, sz) < 0) {
+                WOLFSSL_MSG("\tbad OID");
+                return ASN_PARSE_E;
+            }
+
+            if (oid != HW_NAME_OID) {
+                WOLFSSL_MSG("\tincorrect OID");
+                return ASN_PARSE_E;
+            }
+
+            if (input[idx++] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
+                WOLFSSL_MSG("\twrong type");
+                return ASN_PARSE_E;
+            }
+
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfail: str len");
+                return ASN_PARSE_E;
+            }
+
+            if (GetSequence(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tBad Sequence");
+                return ASN_PARSE_E;
+            }
+
+            if (input[idx++] != ASN_OBJECT_ID) {
+                WOLFSSL_MSG("\texpected OID");
+                return ASN_PARSE_E;
+            }
+
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfailed: str len");
+                return ASN_PARSE_E;
+            }
+
+            cert->hwType = (byte*)XMALLOC(strLen, cert->heap, 0);
+            if (cert->hwType == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                return MEMORY_E;
+            }
+
+            XMEMCPY(cert->hwType, &input[idx], strLen);
+            cert->hwTypeSz = strLen;
+            idx += strLen;
+
+            if (input[idx++] != ASN_OCTET_STRING) {
+                WOLFSSL_MSG("\texpected Octet String");
+                return ASN_PARSE_E;
+            }
+
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfailed: str len");
+                return ASN_PARSE_E;
+            }
+
+            cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap, 0);
+            if (cert->hwSerialNum == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                return MEMORY_E;
+            }
+
+            XMEMCPY(cert->hwSerialNum, &input[idx], strLen);
+            cert->hwSerialNum[strLen] = '\0';
+            cert->hwSerialNumSz = strLen;
+            idx += strLen;
+        }
+#endif /* WOLFSSL_SEP */
+        else {
+            int strLen;
+            word32 lenStartIdx = idx;
+
+            WOLFSSL_MSG("\tUnsupported name type, skipping");
+
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfail: unsupported name length");
+                return ASN_PARSE_E;
+            }
+            length -= (strLen + idx - lenStartIdx);
+            idx += strLen;
+        }
+    }
+    return 0;
+}
+
+
+static int DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0;
+    int length = 0;
+
+    WOLFSSL_ENTER("DecodeBasicCaConstraint");
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: bad SEQUENCE");
+        return ASN_PARSE_E;
+    }
+
+    if (length == 0)
+        return 0;
+
+    /* If the basic ca constraint is false, this extension may be named, but
+     * left empty. So, if the length is 0, just return. */
+
+    if (input[idx++] != ASN_BOOLEAN)
+    {
+        WOLFSSL_MSG("\tfail: constraint not BOOLEAN");
+        return ASN_PARSE_E;
+    }
+
+    if (GetLength(input, &idx, &length, sz) < 0)
+    {
+        WOLFSSL_MSG("\tfail: length");
+        return ASN_PARSE_E;
+    }
+
+    if (input[idx++])
+        cert->isCA = 1;
+
+    #ifdef OPENSSL_EXTRA
+        /* If there isn't any more data, return. */
+        if (idx >= (word32)sz)
+            return 0;
+
+        /* Anything left should be the optional pathlength */
+        if (input[idx++] != ASN_INTEGER) {
+            WOLFSSL_MSG("\tfail: pathlen not INTEGER");
+            return ASN_PARSE_E;
+        }
+
+        if (input[idx++] != 1) {
+            WOLFSSL_MSG("\tfail: pathlen too long");
+            return ASN_PARSE_E;
+        }
+
+        cert->pathLength = input[idx];
+        cert->extBasicConstPlSet = 1;
+    #endif /* OPENSSL_EXTRA */
+
+    return 0;
+}
+
+
+#define CRLDP_FULL_NAME 0
+    /* From RFC3280 SS4.2.1.14, Distribution Point Name*/
+#define GENERALNAME_URI 6
+    /* From RFC3280 SS4.2.1.7, GeneralName */
+
+static int DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0;
+    int length = 0;
+
+    WOLFSSL_ENTER("DecodeCrlDist");
+
+    /* Unwrap the list of Distribution Points*/
+    if (GetSequence(input, &idx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    /* Unwrap a single Distribution Point */
+    if (GetSequence(input, &idx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    /* The Distribution Point has three explicit optional members
+     *  First check for a DistributionPointName
+     */
+    if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
+    {
+        idx++;
+        if (GetLength(input, &idx, &length, sz) < 0)
+            return ASN_PARSE_E;
+
+        if (input[idx] ==
+                    (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME))
+        {
+            idx++;
+            if (GetLength(input, &idx, &length, sz) < 0)
+                return ASN_PARSE_E;
+
+            if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
+            {
+                idx++;
+                if (GetLength(input, &idx, &length, sz) < 0)
+                    return ASN_PARSE_E;
+
+                cert->extCrlInfoSz = length;
+                cert->extCrlInfo = input + idx;
+                idx += length;
+            }
+            else
+                /* This isn't a URI, skip it. */
+                idx += length;
+        }
+        else
+            /* This isn't a FULLNAME, skip it. */
+            idx += length;
+    }
+
+    /* Check for reasonFlags */
+    if (idx < (word32)sz &&
+        input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
+    {
+        idx++;
+        if (GetLength(input, &idx, &length, sz) < 0)
+            return ASN_PARSE_E;
+        idx += length;
+    }
+
+    /* Check for cRLIssuer */
+    if (idx < (word32)sz &&
+        input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
+    {
+        idx++;
+        if (GetLength(input, &idx, &length, sz) < 0)
+            return ASN_PARSE_E;
+        idx += length;
+    }
+
+    if (idx < (word32)sz)
+    {
+        WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
+                   "but we only use the first one.");
+    }
+
+    return 0;
+}
+
+
+static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
+/*
+ *  Read the first of the Authority Information Access records. If there are
+ *  any issues, return without saving the record.
+ */
+{
+    word32 idx = 0;
+    int length = 0;
+    byte b;
+    word32 oid;
+
+    WOLFSSL_ENTER("DecodeAuthInfo");
+
+    /* Unwrap the list of AIAs */
+    if (GetSequence(input, &idx, &length, sz) < 0)
+        return ASN_PARSE_E;
+
+    while (idx < (word32)sz) {
+        /* Unwrap a single AIA */
+        if (GetSequence(input, &idx, &length, sz) < 0)
+            return ASN_PARSE_E;
+
+        oid = 0;
+        if (GetObjectId(input, &idx, &oid, sz) < 0)
+            return ASN_PARSE_E;
+
+        /* Only supporting URIs right now. */
+        b = input[idx++];
+        if (GetLength(input, &idx, &length, sz) < 0)
+            return ASN_PARSE_E;
+
+        if (b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI) &&
+            oid == AIA_OCSP_OID)
+        {
+            cert->extAuthInfoSz = length;
+            cert->extAuthInfo = input + idx;
+            break;
+        }
+        idx += length;
+    }
+
+    return 0;
+}
+
+
+static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0;
+    int length = 0, ret = 0;
+
+    WOLFSSL_ENTER("DecodeAuthKeyId");
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: should be a SEQUENCE\n");
+        return ASN_PARSE_E;
+    }
+
+    if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
+        WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available\n");
+        return 0;
+    }
+
+    if (GetLength(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: extension data length");
+        return ASN_PARSE_E;
+    }
+
+    #ifdef OPENSSL_EXTRA
+        cert->extAuthKeyIdSrc = &input[idx];
+        cert->extAuthKeyIdSz = length;
+    #endif /* OPENSSL_EXTRA */
+
+    if (length == KEYID_SIZE) {
+        XMEMCPY(cert->extAuthKeyId, input + idx, length);
+    }
+    else {
+    #ifdef NO_SHA
+        ret = wc_Sha256Hash(input + idx, length, cert->extAuthKeyId);
+    #else
+        ret = wc_ShaHash(input + idx, length, cert->extAuthKeyId);
+    #endif
+    }
+
+    return ret;
+}
+
+
+static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0;
+    int length = 0, ret = 0;
+
+    WOLFSSL_ENTER("DecodeSubjKeyId");
+
+    if (input[idx++] != ASN_OCTET_STRING) {
+        WOLFSSL_MSG("\tfail: should be an OCTET STRING");
+        return ASN_PARSE_E;
+    }
+
+    if (GetLength(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: extension data length");
+        return ASN_PARSE_E;
+    }
+
+    #ifdef OPENSSL_EXTRA
+        cert->extSubjKeyIdSrc = &input[idx];
+        cert->extSubjKeyIdSz = length;
+    #endif /* OPENSSL_EXTRA */
+
+    if (length == SIGNER_DIGEST_SIZE) {
+        XMEMCPY(cert->extSubjKeyId, input + idx, length);
+    }
+    else {
+    #ifdef NO_SHA
+        ret = wc_Sha256Hash(input + idx, length, cert->extSubjKeyId);
+    #else
+        ret = wc_ShaHash(input + idx, length, cert->extSubjKeyId);
+    #endif
+    }
+
+    return ret;
+}
+
+
+static int DecodeKeyUsage(byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0;
+    int length;
+    WOLFSSL_ENTER("DecodeKeyUsage");
+
+    if (input[idx++] != ASN_BIT_STRING) {
+        WOLFSSL_MSG("\tfail: key usage expected bit string");
+        return ASN_PARSE_E;
+    }
+
+    if (GetLength(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: key usage bad length");
+        return ASN_PARSE_E;
+    }
+
+    /* pass the unusedBits value */
+    idx++; length--;
+
+    cert->extKeyUsage = (word16)(input[idx]);
+    if (length == 2)
+        cert->extKeyUsage |= (word16)(input[idx+1] << 8);
+
+    return 0;
+}
+
+
+static int DecodeExtKeyUsage(byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0, oid;
+    int length;
+
+    WOLFSSL_ENTER("DecodeExtKeyUsage");
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
+        return ASN_PARSE_E;
+    }
+
+    #ifdef OPENSSL_EXTRA
+        cert->extExtKeyUsageSrc = input + idx;
+        cert->extExtKeyUsageSz = length;
+    #endif
+
+    while (idx < (word32)sz) {
+        if (GetObjectId(input, &idx, &oid, sz) < 0)
+            return ASN_PARSE_E;
+
+        switch (oid) {
+            case EKU_ANY_OID:
+                cert->extExtKeyUsage |= EXTKEYUSE_ANY;
+                break;
+            case EKU_SERVER_AUTH_OID:
+                cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
+                break;
+            case EKU_CLIENT_AUTH_OID:
+                cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
+                break;
+            case EKU_OCSP_SIGN_OID:
+                cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
+                break;
+        }
+
+        #ifdef OPENSSL_EXTRA
+            cert->extExtKeyUsageCount++;
+        #endif
+    }
+
+    return 0;
+}
+
+
+#ifndef IGNORE_NAME_CONSTRAINTS
+static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap)
+{
+    word32 idx = 0;
+
+    (void)heap;
+
+    while (idx < (word32)sz) {
+        int seqLength, strLength;
+        word32 nameIdx;
+        byte b;
+
+        if (GetSequence(input, &idx, &seqLength, sz) < 0) {
+            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
+            return ASN_PARSE_E;
+        }
+
+        nameIdx = idx;
+        b = input[nameIdx++];
+        if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
+            WOLFSSL_MSG("\tinvalid length");
+            return ASN_PARSE_E;
+        }
+
+        if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE) ||
+            b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE) ||
+            b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
+
+            Base_entry* entry = (Base_entry*)XMALLOC(sizeof(Base_entry),
+                                                    heap, DYNAMIC_TYPE_ALTNAME);
+
+            if (entry == NULL) {
+                WOLFSSL_MSG("allocate error");
+                return MEMORY_E;
+            }
+
+            entry->name = (char*)XMALLOC(strLength, heap, DYNAMIC_TYPE_ALTNAME);
+            if (entry->name == NULL) {
+                WOLFSSL_MSG("allocate error");
+                return MEMORY_E;
+            }
+
+            XMEMCPY(entry->name, &input[nameIdx], strLength);
+            entry->nameSz = strLength;
+            entry->type = b & 0x0F;
+
+            entry->next = *head;
+            *head = entry;
+        }
+
+        idx += seqLength;
+    }
+
+    return 0;
+}
+
+
+static int DecodeNameConstraints(byte* input, int sz, DecodedCert* cert)
+{
+    word32 idx = 0;
+    int length = 0;
+
+    WOLFSSL_ENTER("DecodeNameConstraints");
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
+        return ASN_PARSE_E;
+    }
+
+    while (idx < (word32)sz) {
+        byte b = input[idx++];
+        Base_entry** subtree = NULL;
+
+        if (GetLength(input, &idx, &length, sz) <= 0) {
+            WOLFSSL_MSG("\tinvalid length");
+            return ASN_PARSE_E;
+        }
+
+        if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
+            subtree = &cert->permittedNames;
+        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
+            subtree = &cert->excludedNames;
+        else {
+            WOLFSSL_MSG("\tinvalid subtree");
+            return ASN_PARSE_E;
+        }
+
+        DecodeSubtree(input + idx, length, subtree, cert->heap);
+
+        idx += length;
+    }
+
+    return 0;
+}
+#endif /* IGNORE_NAME_CONSTRAINTS */
+
+#if defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_SEP)
+
+static int Word32ToString(char* d, word32 number)
+{
+    int i = 0;
+
+    if (d != NULL) {
+        word32 order = 1000000000;
+        word32 digit;
+
+        if (number == 0) {
+            d[i++] = '0';
+        }
+        else {
+            while (order) {
+                digit = number / order;
+                if (i > 0 || digit != 0) {
+                    d[i++] = (char)digit + '0';
+                }
+                if (digit != 0)
+                    number %= digit * order;
+                if (order > 1)
+                    order /= 10;
+                else
+                    order = 0;
+            }
+        }
+        d[i] = 0;
+    }
+
+    return i;
+}
+
+
+/* Decode ITU-T X.690 OID format to a string representation
+ * return string length */
+static int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz)
+{
+    word32 val, idx = 0, nb_bytes;
+    size_t w_bytes = 0;
+
+    if (out == NULL || in == NULL || outSz < 4 || inSz < 2)
+        return BAD_FUNC_ARG;
+
+    /* first two byte must be interpreted as : 40 * int1 + int2 */
+    val = (word16)in[idx++];
+
+    w_bytes = Word32ToString(out, val / 40);
+    out[w_bytes++] = '.';
+    w_bytes += Word32ToString(out+w_bytes, val % 40);
+
+    while (idx < inSz) {
+        /* init value */
+        val = 0;
+        nb_bytes = 0;
+
+        /* check that output size is ok */
+        if (w_bytes > (outSz - 3))
+            return BUFFER_E;
+
+        /* first bit is used to set if value is coded on 1 or multiple bytes */
+        while ((in[idx+nb_bytes] & 0x80))
+            nb_bytes++;
+
+        if (!nb_bytes)
+            val = (word32)(in[idx++] & 0x7f);
+        else {
+            word32 base = 1, tmp = nb_bytes;
+
+            while (tmp != 0) {
+                val += (word32)(in[idx+tmp] & 0x7f) * base;
+                base *= 128;
+                tmp--;
+            }
+            val += (word32)(in[idx++] & 0x7f) * base;
+
+            idx += nb_bytes;
+        }
+
+        out[w_bytes++] = '.';
+        w_bytes += Word32ToString(out+w_bytes, val);
+    }
+
+    return 0;
+}
+#endif /* WOLFSSL_CERT_EXT && !WOLFSSL_SEP */
+
+#if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
+    static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert)
+    {
+        word32 idx = 0;
+        int total_length = 0, length = 0;
+
+        WOLFSSL_ENTER("DecodeCertPolicy");
+
+        /* Unwrap certificatePolicies */
+        if (GetSequence(input, &idx, &total_length, sz) < 0) {
+            WOLFSSL_MSG("\tdeviceType isn't OID");
+            return ASN_PARSE_E;
+        }
+
+        if (GetSequence(input, &idx, &length, sz) < 0) {
+            WOLFSSL_MSG("\tdeviceType isn't OID");
+            return ASN_PARSE_E;
+        }
+        total_length -= (length+1);
+
+        if (input[idx++] != ASN_OBJECT_ID) {
+            WOLFSSL_MSG("\tdeviceType isn't OID");
+            return ASN_PARSE_E;
+        }
+        total_length--;
+
+        if (GetLength(input, &idx, &length, sz) < 0) {
+            WOLFSSL_MSG("\tCouldn't read length of deviceType");
+            return ASN_PARSE_E;
+        }
+
+        if (length > 0) {
+#if defined(WOLFSSL_SEP)
+            cert->deviceType = (byte*)XMALLOC(length, cert->heap, 0);
+            if (cert->deviceType == NULL) {
+                WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
+                return MEMORY_E;
+            }
+            cert->deviceTypeSz = length;
+            XMEMCPY(cert->deviceType, input + idx, length);
+#elif defined(WOLFSSL_CERT_EXT)
+            /* decode cert policy */
+            if (DecodePolicyOID(cert->extCertPolicies[0], MAX_CERTPOL_SZ,
+                                input+idx, length) != 0) {
+                WOLFSSL_MSG("\tCouldn't read Policy OID 1");
+                return ASN_PARSE_E;
+            }
+            cert->extCertPoliciesNb++;
+
+            /* check if we have a second value */
+            if (total_length) {
+                idx += length;
+
+                if (GetSequence(input, &idx, &length, sz) < 0) {
+                    WOLFSSL_MSG("\tdeviceType isn't OID");
+                    return ASN_PARSE_E;
+                }
+
+                if (input[idx++] != ASN_OBJECT_ID) {
+                    WOLFSSL_MSG("\tdeviceType isn't OID");
+                    return ASN_PARSE_E;
+                }
+
+                if (GetLength(input, &idx, &length, sz) < 0) {
+                    WOLFSSL_MSG("\tCouldn't read length of deviceType");
+                    return ASN_PARSE_E;
+                }
+
+                /* decode cert policy */
+                if (DecodePolicyOID(cert->extCertPolicies[1], MAX_CERTPOL_SZ,
+                                    input+idx, length) != 0) {
+                    WOLFSSL_MSG("\tCouldn't read Policy OID 2");
+                    return ASN_PARSE_E;
+                }
+                cert->extCertPoliciesNb++;
+            }
+#else
+            WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0);
+            return 0;
+#endif
+        }
+
+        WOLFSSL_LEAVE("DecodeCertPolicy", 0);
+        return 0;
+    }
+#endif /* WOLFSSL_SEP */
+
+
+static int DecodeCertExtensions(DecodedCert* cert)
+/*
+ *  Processing the Certificate Extensions. This does not modify the current
+ *  index. It is works starting with the recorded extensions pointer.
+ */
+{
+    word32 idx = 0;
+    int sz = cert->extensionsSz;
+    byte* input = cert->extensions;
+    int length;
+    word32 oid;
+    byte critical = 0;
+    byte criticalFail = 0;
+
+    WOLFSSL_ENTER("DecodeCertExtensions");
+
+    if (input == NULL || sz == 0)
+        return BAD_FUNC_ARG;
+
+    if (input[idx++] != ASN_EXTENSIONS) {
+        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
+        return ASN_PARSE_E;
+    }
+
+    if (GetLength(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: invalid length");
+        return ASN_PARSE_E;
+    }
+
+    if (GetSequence(input, &idx, &length, sz) < 0) {
+        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
+        return ASN_PARSE_E;
+    }
+
+    while (idx < (word32)sz) {
+        if (GetSequence(input, &idx, &length, sz) < 0) {
+            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
+            return ASN_PARSE_E;
+        }
+
+        oid = 0;
+        if (GetObjectId(input, &idx, &oid, sz) < 0) {
+            WOLFSSL_MSG("\tfail: OBJECT ID");
+            return ASN_PARSE_E;
+        }
+
+        /* check for critical flag */
+        critical = 0;
+        if (input[idx] == ASN_BOOLEAN) {
+            int boolLength = 0;
+            idx++;
+            if (GetLength(input, &idx, &boolLength, sz) < 0) {
+                WOLFSSL_MSG("\tfail: critical boolean length");
+                return ASN_PARSE_E;
+            }
+            if (input[idx++])
+                critical = 1;
+        }
+
+        /* process the extension based on the OID */
+        if (input[idx++] != ASN_OCTET_STRING) {
+            WOLFSSL_MSG("\tfail: should be an OCTET STRING");
+            return ASN_PARSE_E;
+        }
+
+        if (GetLength(input, &idx, &length, sz) < 0) {
+            WOLFSSL_MSG("\tfail: extension data length");
+            return ASN_PARSE_E;
+        }
+
+        switch (oid) {
+            case BASIC_CA_OID:
+                #ifdef OPENSSL_EXTRA
+                    cert->extBasicConstSet = 1;
+                    cert->extBasicConstCrit = critical;
+                #endif
+                if (DecodeBasicCaConstraint(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            case CRL_DIST_OID:
+                if (DecodeCrlDist(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            case AUTH_INFO_OID:
+                if (DecodeAuthInfo(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            case ALT_NAMES_OID:
+                #ifdef OPENSSL_EXTRA
+                    cert->extSubjAltNameSet = 1;
+                    cert->extSubjAltNameCrit = critical;
+                #endif
+                if (DecodeAltNames(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            case AUTH_KEY_OID:
+                cert->extAuthKeyIdSet = 1;
+                #ifdef OPENSSL_EXTRA
+                    cert->extAuthKeyIdCrit = critical;
+                #endif
+                if (DecodeAuthKeyId(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            case SUBJ_KEY_OID:
+                cert->extSubjKeyIdSet = 1;
+                #ifdef OPENSSL_EXTRA
+                    cert->extSubjKeyIdCrit = critical;
+                #endif
+                if (DecodeSubjKeyId(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            case CERT_POLICY_OID:
+                WOLFSSL_MSG("Certificate Policy extension not supported yet.");
+                #ifdef WOLFSSL_SEP
+                    #ifdef OPENSSL_EXTRA
+                        cert->extCertPolicySet = 1;
+                        cert->extCertPolicyCrit = critical;
+                    #endif
+                #endif
+                #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
+                if (DecodeCertPolicy(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                #endif
+                break;
+
+            case KEY_USAGE_OID:
+                cert->extKeyUsageSet = 1;
+                #ifdef OPENSSL_EXTRA
+                    cert->extKeyUsageCrit = critical;
+                #endif
+                if (DecodeKeyUsage(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            case EXT_KEY_USAGE_OID:
+                cert->extExtKeyUsageSet = 1;
+                #ifdef OPENSSL_EXTRA
+                    cert->extExtKeyUsageCrit = critical;
+                #endif
+                if (DecodeExtKeyUsage(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+
+            #ifndef IGNORE_NAME_CONSTRAINTS
+            case NAME_CONS_OID:
+                cert->extNameConstraintSet = 1;
+                #ifdef OPENSSL_EXTRA
+                    cert->extNameConstraintCrit = critical;
+                #endif
+                if (DecodeNameConstraints(&input[idx], length, cert) < 0)
+                    return ASN_PARSE_E;
+                break;
+            #endif /* IGNORE_NAME_CONSTRAINTS */
+
+            case INHIBIT_ANY_OID:
+                WOLFSSL_MSG("Inhibit anyPolicy extension not supported yet.");
+                break;
+
+            default:
+                /* While it is a failure to not support critical extensions,
+                 * still parse the certificate ignoring the unsupported
+                 * extention to allow caller to accept it with the verify
+                 * callback. */
+                if (critical)
+                    criticalFail = 1;
+                break;
+        }
+        idx += length;
+    }
+
+    return criticalFail ? ASN_CRIT_EXT_E : 0;
+}
+
+
+int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
+{
+    int   ret;
+    char* ptr;
+
+    ret = ParseCertRelative(cert, type, verify, cm);
+    if (ret < 0)
+        return ret;
+
+    if (cert->subjectCNLen > 0) {
+        ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,
+                              DYNAMIC_TYPE_SUBJECT_CN);
+        if (ptr == NULL)
+            return MEMORY_E;
+        XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);
+        ptr[cert->subjectCNLen] = '\0';
+        cert->subjectCN = ptr;
+        cert->subjectCNStored = 1;
+    }
+
+    if (cert->keyOID == RSAk &&
+                          cert->publicKey != NULL  && cert->pubKeySize > 0) {
+        ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,
+                              DYNAMIC_TYPE_PUBLIC_KEY);
+        if (ptr == NULL)
+            return MEMORY_E;
+        XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
+        cert->publicKey = (byte *)ptr;
+        cert->pubKeyStored = 1;
+    }
+
+    return ret;
+}
+
+
+/* from SSL proper, for locking can't do find here anymore */
+#ifdef __cplusplus
+    extern "C" {
+#endif
+    WOLFSSL_LOCAL Signer* GetCA(void* signers, byte* hash);
+    #ifndef NO_SKID
+        WOLFSSL_LOCAL Signer* GetCAByName(void* signers, byte* hash);
+    #endif
+#ifdef __cplusplus
+    }
+#endif
+
+
+#ifdef WOLFCRYPT_ONLY
+
+/* dummy functions, not using wolfSSL so don't need actual ones */
+Signer* GetCA(void* signers, byte* hash)
+{
+    (void)hash;
+
+    return (Signer*)signers;
+}
+
+#ifndef NO_SKID
+Signer* GetCAByName(void* signers, byte* hash)
+{
+    (void)hash;
+
+    return (Signer*)signers;
+}
+#endif /* NO_SKID */
+
+#endif /* WOLFCRYPT_ONLY */
+
+
+int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
+{
+    word32 confirmOID;
+    int    ret;
+    int    badDate     = 0;
+    int    criticalExt = 0;
+
+    if ((ret = DecodeToKey(cert, verify)) < 0) {
+        if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
+            badDate = ret;
+        else
+            return ret;
+    }
+
+    WOLFSSL_MSG("Parsed Past Key");
+
+    if (cert->srcIdx < cert->sigIndex) {
+        #ifndef ALLOW_V1_EXTENSIONS
+            if (cert->version < 2) {
+                WOLFSSL_MSG("    v1 and v2 certs not allowed extensions");
+                return ASN_VERSION_E;
+            }
+        #endif
+        /* save extensions */
+        cert->extensions    = &cert->source[cert->srcIdx];
+        cert->extensionsSz  =  cert->sigIndex - cert->srcIdx;
+        cert->extensionsIdx = cert->srcIdx;   /* for potential later use */
+
+        if ((ret = DecodeCertExtensions(cert)) < 0) {
+            if (ret == ASN_CRIT_EXT_E)
+                criticalExt = ret;
+            else
+                return ret;
+        }
+
+        /* advance past extensions */
+        cert->srcIdx =  cert->sigIndex;
+    }
+
+    if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID,
+                         cert->maxIdx)) < 0)
+        return ret;
+
+    if ((ret = GetSignature(cert)) < 0)
+        return ret;
+
+    if (confirmOID != cert->signatureOID)
+        return ASN_SIG_OID_E;
+
+    #ifndef NO_SKID
+        if (cert->extSubjKeyIdSet == 0
+                          && cert->publicKey != NULL && cert->pubKeySize > 0) {
+        #ifdef NO_SHA
+            ret = wc_Sha256Hash(cert->publicKey, cert->pubKeySize,
+                                                            cert->extSubjKeyId);
+        #else
+            ret = wc_ShaHash(cert->publicKey, cert->pubKeySize,
+                                                            cert->extSubjKeyId);
+        #endif
+            if (ret != 0)
+                return ret;
+        }
+    #endif
+
+    if (verify && type != CA_TYPE) {
+        Signer* ca = NULL;
+        #ifndef NO_SKID
+            if (cert->extAuthKeyIdSet)
+                ca = GetCA(cm, cert->extAuthKeyId);
+            if (ca == NULL)
+                ca = GetCAByName(cm, cert->issuerHash);
+        #else /* NO_SKID */
+            ca = GetCA(cm, cert->issuerHash);
+        #endif /* NO SKID */
+        WOLFSSL_MSG("About to verify certificate signature");
+
+        if (ca) {
+#ifdef HAVE_OCSP
+            /* Need the ca's public key hash for OCSP */
+    #ifdef NO_SHA
+            ret = wc_Sha256Hash(ca->publicKey, ca->pubKeySize,
+                                cert->issuerKeyHash);
+    #else /* NO_SHA */
+            ret = wc_ShaHash(ca->publicKey, ca->pubKeySize,
+                                cert->issuerKeyHash);
+    #endif /* NO_SHA */
+            if (ret != 0)
+                return ret;
+#endif /* HAVE_OCSP */
+            /* try to confirm/verify signature */
+            if (!ConfirmSignature(cert->source + cert->certBegin,
+                        cert->sigIndex - cert->certBegin,
+                    ca->publicKey, ca->pubKeySize, ca->keyOID,
+                    cert->signature, cert->sigLength, cert->signatureOID,
+                    cert->heap)) {
+                WOLFSSL_MSG("Confirm signature failed");
+                return ASN_SIG_CONFIRM_E;
+            }
+#ifndef IGNORE_NAME_CONSTRAINTS
+            /* check that this cert's name is permitted by the signer's
+             * name constraints */
+            if (!ConfirmNameConstraints(ca, cert)) {
+                WOLFSSL_MSG("Confirm name constraint failed");
+                return ASN_NAME_INVALID_E;
+            }
+#endif /* IGNORE_NAME_CONSTRAINTS */
+        }
+        else {
+            /* no signer */
+            WOLFSSL_MSG("No CA signer to verify with");
+            return ASN_NO_SIGNER_E;
+        }
+    }
+
+    if (badDate != 0)
+        return badDate;
+
+    if (criticalExt != 0)
+        return criticalExt;
+
+    return 0;
+}
+
+
+/* Create and init an new signer */
+Signer* MakeSigner(void* heap)
+{
+    Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
+                                       DYNAMIC_TYPE_SIGNER);
+    if (signer) {
+        signer->pubKeySize = 0;
+        signer->keyOID     = 0;
+        signer->publicKey  = NULL;
+        signer->nameLen    = 0;
+        signer->name       = NULL;
+        #ifndef IGNORE_NAME_CONSTRAINTS
+            signer->permittedNames = NULL;
+            signer->excludedNames = NULL;
+        #endif /* IGNORE_NAME_CONSTRAINTS */
+        signer->next       = NULL;
+    }
+    (void)heap;
+
+    return signer;
+}
+
+
+/* Free an individual signer */
+void FreeSigner(Signer* signer, void* heap)
+{
+    XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
+    XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
+    #ifndef IGNORE_NAME_CONSTRAINTS
+        if (signer->permittedNames)
+            FreeNameSubtrees(signer->permittedNames, heap);
+        if (signer->excludedNames)
+            FreeNameSubtrees(signer->excludedNames, heap);
+    #endif
+    XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
+
+    (void)heap;
+}
+
+
+/* Free the whole singer table with number of rows */
+void FreeSignerTable(Signer** table, int rows, void* heap)
+{
+    int i;
+
+    for (i = 0; i < rows; i++) {
+        Signer* signer = table[i];
+        while (signer) {
+            Signer* next = signer->next;
+            FreeSigner(signer, heap);
+            signer = next;
+        }
+        table[i] = NULL;
+    }
+}
+
+
+WOLFSSL_LOCAL int SetMyVersion(word32 version, byte* output, int header)
+{
+    int i = 0;
+
+    if (output == NULL)
+        return BAD_FUNC_ARG;
+
+    if (header) {
+        output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
+        output[i++] = ASN_BIT_STRING;
+    }
+    output[i++] = ASN_INTEGER;
+    output[i++] = 0x01;
+    output[i++] = (byte)version;
+
+    return i;
+}
+
+
+WOLFSSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output)
+{
+    int result = 0;
+
+    WOLFSSL_ENTER("SetSerialNumber");
+
+    if (sn == NULL || output == NULL)
+        return BAD_FUNC_ARG;
+
+    if (snSz <= EXTERNAL_SERIAL_SIZE) {
+        output[0] = ASN_INTEGER;
+        /* The serial number is always positive. When encoding the
+         * INTEGER, if the MSB is 1, add a padding zero to keep the
+         * number positive. */
+        if (sn[0] & 0x80) {
+            output[1] = (byte)snSz + 1;
+            output[2] = 0;
+            XMEMCPY(&output[3], sn, snSz);
+            result = snSz + 3;
+        }
+        else {
+            output[1] = (byte)snSz;
+            XMEMCPY(&output[2], sn, snSz);
+            result = snSz + 2;
+        }
+    }
+    return result;
+}
+
+
+
+const char* BEGIN_CERT         = "-----BEGIN CERTIFICATE-----";
+const char* END_CERT           = "-----END CERTIFICATE-----";
+const char* BEGIN_CERT_REQ     = "-----BEGIN CERTIFICATE REQUEST-----";
+const char* END_CERT_REQ       = "-----END CERTIFICATE REQUEST-----";
+const char* BEGIN_DH_PARAM     = "-----BEGIN DH PARAMETERS-----";
+const char* END_DH_PARAM       = "-----END DH PARAMETERS-----";
+const char* BEGIN_X509_CRL     = "-----BEGIN X509 CRL-----";
+const char* END_X509_CRL       = "-----END X509 CRL-----";
+const char* BEGIN_RSA_PRIV     = "-----BEGIN RSA PRIVATE KEY-----";
+const char* END_RSA_PRIV       = "-----END RSA PRIVATE KEY-----";
+const char* BEGIN_PRIV_KEY     = "-----BEGIN PRIVATE KEY-----";
+const char* END_PRIV_KEY       = "-----END PRIVATE KEY-----";
+const char* BEGIN_ENC_PRIV_KEY = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
+const char* END_ENC_PRIV_KEY   = "-----END ENCRYPTED PRIVATE KEY-----";
+const char* BEGIN_EC_PRIV      = "-----BEGIN EC PRIVATE KEY-----";
+const char* END_EC_PRIV        = "-----END EC PRIVATE KEY-----";
+const char* BEGIN_DSA_PRIV     = "-----BEGIN DSA PRIVATE KEY-----";
+const char* END_DSA_PRIV       = "-----END DSA PRIVATE KEY-----";
+const char* BEGIN_PUB_KEY      = "-----BEGIN PUBLIC KEY-----";
+const char* END_PUB_KEY        = "-----END PUBLIC KEY-----";
+
+#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN)
+
+/* Used for compatibility API */
+int wc_DerToPem(const byte* der, word32 derSz,
+                byte* output, word32 outSz, int type)
+{
+    return wc_DerToPemEx(der, derSz, output, outSz, NULL, type);
+}
+
+/* convert der buffer to pem into output, can't do inplace, der and output
+   need to be different */
+int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz,
+             byte *cipher_info, int type)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    char* header = NULL;
+    char* footer = NULL;
+#else
+    char header[40 + HEADER_ENCRYPTED_KEY_SIZE];
+    char footer[40];
+#endif
+
+    int headerLen = 40 + HEADER_ENCRYPTED_KEY_SIZE;
+    int footerLen = 40;
+    int i;
+    int err;
+    int outLen;   /* return length or error */
+
+    if (der == output)      /* no in place conversion */
+        return BAD_FUNC_ARG;
+
+#ifdef WOLFSSL_SMALL_STACK
+    header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (header == NULL)
+        return MEMORY_E;
+
+    footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (footer == NULL) {
+        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+    if (type == CERT_TYPE) {
+        XSTRNCPY(header, BEGIN_CERT, headerLen);
+        XSTRNCAT(header, "\n", 1);
+
+        XSTRNCPY(footer, END_CERT, footerLen);
+        XSTRNCAT(footer, "\n", 1);
+    }
+    else if (type == PRIVATEKEY_TYPE) {
+        XSTRNCPY(header, BEGIN_RSA_PRIV, headerLen);
+        XSTRNCAT(header, "\n", 1);
+
+        XSTRNCPY(footer, END_RSA_PRIV, footerLen);
+        XSTRNCAT(footer, "\n", 1);
+    }
+#ifndef NO_DSA
+    else if (type == DSA_PRIVATEKEY_TYPE) {
+        XSTRNCPY(header, BEGIN_DSA_PRIV, headerLen);
+        XSTRNCAT(header, "\n", 1);
+
+        XSTRNCPY(footer, END_DSA_PRIV, footerLen);
+        XSTRNCAT(footer, "\n", 1);
+    }
+#endif
+#ifdef HAVE_ECC
+    else if (type == ECC_PRIVATEKEY_TYPE) {
+        XSTRNCPY(header, BEGIN_EC_PRIV, headerLen);
+        XSTRNCAT(header, "\n", 1);
+
+        XSTRNCPY(footer, END_EC_PRIV, footerLen);
+        XSTRNCAT(footer, "\n", 1);
+    }
+#endif
+#ifdef WOLFSSL_CERT_REQ
+    else if (type == CERTREQ_TYPE)
+    {
+        XSTRNCPY(header, BEGIN_CERT_REQ, headerLen);
+        XSTRNCAT(header, "\n", 1);
+
+        XSTRNCPY(footer, END_CERT_REQ, footerLen);
+        XSTRNCAT(footer, "\n", 1);
+    }
+#endif
+    else {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return BAD_FUNC_ARG;
+    }
+
+    /* extra header information for encrypted key */
+    if (cipher_info != NULL) {
+        XSTRNCAT(header, "Proc-Type: 4,ENCRYPTED\n", 23);
+        XSTRNCAT(header, "DEK-Info: ", 10);
+        XSTRNCAT(header, (char*)cipher_info, XSTRLEN((char*)cipher_info));
+        XSTRNCAT(header, "\n\n", 2);
+    }
+
+    headerLen = (int)XSTRLEN(header);
+    footerLen = (int)XSTRLEN(footer);
+
+    if (!der || !output) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return BAD_FUNC_ARG;
+    }
+
+    /* don't even try if outSz too short */
+    if (outSz < headerLen + footerLen + derSz) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return BAD_FUNC_ARG;
+    }
+
+    /* header */
+    XMEMCPY(output, header, headerLen);
+    i = headerLen;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    /* body */
+    outLen = outSz - (headerLen + footerLen);  /* input to Base64_Encode */
+    if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return err;
+    }
+    i += outLen;
+
+    /* footer */
+    if ( (i + footerLen) > (int)outSz) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return BAD_FUNC_ARG;
+    }
+    XMEMCPY(output + i, footer, footerLen);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return outLen + headerLen + footerLen;
+}
+
+#endif /* WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN */
+
+#if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || (defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA)))
+/* USER RSA ifdef portions used instead of refactor in consideration for
+   possible fips build */
+/* Write a public RSA key to output */
+static int SetRsaPublicKey(byte* output, RsaKey* key,
+                           int outLen, int with_header)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    byte* n = NULL;
+    byte* e = NULL;
+#else
+    byte n[MAX_RSA_INT_SZ];
+    byte e[MAX_RSA_E_SZ];
+#endif
+    byte seq[MAX_SEQ_SZ];
+    byte len[MAX_LENGTH_SZ + 1];  /* trailing 0 */
+    int  nSz;
+    int  eSz;
+    int  seqSz;
+    int  lenSz;
+    int  idx;
+    int  rawLen;
+    int  leadingBit;
+    int  err;
+
+    if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ)
+        return BAD_FUNC_ARG;
+
+    /* n */
+#ifdef WOLFSSL_SMALL_STACK
+    n = (byte*)XMALLOC(MAX_RSA_INT_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (n == NULL)
+        return MEMORY_E;
+#endif
+
+#ifdef HAVE_USER_RSA
+    leadingBit = wc_Rsa_leading_bit(key->n);
+    rawLen = wc_Rsa_unsigned_bin_size(key->n) + leadingBit;
+#else
+    leadingBit = mp_leading_bit(&key->n);
+    rawLen = mp_unsigned_bin_size(&key->n) + leadingBit;
+#endif
+    n[0] = ASN_INTEGER;
+    nSz  = SetLength(rawLen, n + 1) + 1;  /* int tag */
+
+    if ( (nSz + rawLen) < MAX_RSA_INT_SZ) {
+        if (leadingBit)
+            n[nSz] = 0;
+#ifdef HAVE_USER_RSA
+        err = wc_Rsa_to_unsigned_bin(key->n, n + nSz, rawLen);
+#else
+        err = mp_to_unsigned_bin(&key->n, n + nSz + leadingBit);
+#endif
+        if (err == MP_OKAY)
+            nSz += rawLen;
+        else {
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return MP_TO_E;
+        }
+    }
+    else {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return BUFFER_E;
+    }
+
+    /* e */
+#ifdef WOLFSSL_SMALL_STACK
+    e = (byte*)XMALLOC(MAX_RSA_E_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (e == NULL) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return MEMORY_E;
+    }
+#endif
+
+#ifdef HAVE_USER_RSA
+    leadingBit = wc_Rsa_leading_bit(key->e);
+    rawLen = wc_Rsa_unsigned_bin_size(key->e) + leadingBit;
+#else
+    leadingBit = mp_leading_bit(&key->e);
+    rawLen = mp_unsigned_bin_size(&key->e) + leadingBit;
+#endif
+    e[0] = ASN_INTEGER;
+    eSz  = SetLength(rawLen, e + 1) + 1;  /* int tag */
+
+    if ( (eSz + rawLen) < MAX_RSA_E_SZ) {
+        if (leadingBit)
+            e[eSz] = 0;
+#ifdef HAVE_USER_RSA
+        err = wc_Rsa_to_unsigned_bin(key->e, e + eSz, rawLen);
+#else
+        err = mp_to_unsigned_bin(&key->e, e + eSz + leadingBit);
+#endif
+        if (err == MP_OKAY)
+            eSz += rawLen;
+        else {
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return MP_TO_E;
+        }
+    }
+    else {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return BUFFER_E;
+    }
+
+    seqSz  = SetSequence(nSz + eSz, seq);
+
+    /* check output size */
+    if ( (seqSz + nSz + eSz) > outLen) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(n,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(e,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return BUFFER_E;
+    }
+
+    /* headers */
+    if (with_header) {
+        int  algoSz;
+#ifdef WOLFSSL_SMALL_STACK
+        byte* algo = NULL;
+
+        algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (algo == NULL) {
+            XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return MEMORY_E;
+        }
+#else
+        byte algo[MAX_ALGO_SZ];
+#endif
+        algoSz = SetAlgoID(RSAk, algo, keyType, 0);
+        lenSz  = SetLength(seqSz + nSz + eSz + 1, len);
+        len[lenSz++] = 0;   /* trailing 0 */
+
+        /* write, 1 is for ASN_BIT_STRING */
+        idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output);
+
+        /* check output size */
+        if ( (idx + algoSz + 1 + lenSz + seqSz + nSz + eSz) > outLen) {
+            #ifdef WOLFSSL_SMALL_STACK
+                XFREE(n,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(e,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+                XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            #endif
+
+            return BUFFER_E;
+        }
+
+        /* algo */
+        XMEMCPY(output + idx, algo, algoSz);
+        idx += algoSz;
+        /* bit string */
+        output[idx++] = ASN_BIT_STRING;
+        /* length */
+        XMEMCPY(output + idx, len, lenSz);
+        idx += lenSz;
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+    }
+    else
+        idx = 0;
+
+    /* seq */
+    XMEMCPY(output + idx, seq, seqSz);
+    idx += seqSz;
+    /* n */
+    XMEMCPY(output + idx, n, nSz);
+    idx += nSz;
+    /* e */
+    XMEMCPY(output + idx, e, eSz);
+    idx += eSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(n,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(e,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return idx;
+}
+#endif /* !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) ||
+                               defined(WOLFSSL_KEY_GEN)) */
+
+
+#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
+
+
+static mp_int* GetRsaInt(RsaKey* key, int idx)
+{
+    if (idx == 0)
+        return &key->n;
+    if (idx == 1)
+        return &key->e;
+    if (idx == 2)
+        return &key->d;
+    if (idx == 3)
+        return &key->p;
+    if (idx == 4)
+        return &key->q;
+    if (idx == 5)
+        return &key->dP;
+    if (idx == 6)
+        return &key->dQ;
+    if (idx == 7)
+        return &key->u;
+
+    return NULL;
+}
+
+
+/* Release Tmp RSA resources */
+static INLINE void FreeTmpRsas(byte** tmps, void* heap)
+{
+    int i;
+
+    (void)heap;
+
+    for (i = 0; i < RSA_INTS; i++)
+        XFREE(tmps[i], heap, DYNAMIC_TYPE_RSA);
+}
+
+
+/* Convert RsaKey key to DER format, write to output (inLen), return bytes
+   written */
+int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
+{
+    word32 seqSz, verSz, rawLen, intTotalLen = 0;
+    word32 sizes[RSA_INTS];
+    int    i, j, outLen, ret = 0, lbit;
+
+    byte  seq[MAX_SEQ_SZ];
+    byte  ver[MAX_VERSION_SZ];
+    byte* tmps[RSA_INTS];
+
+    if (!key || !output)
+        return BAD_FUNC_ARG;
+
+    if (key->type != RSA_PRIVATE)
+        return BAD_FUNC_ARG;
+
+    for (i = 0; i < RSA_INTS; i++)
+        tmps[i] = NULL;
+
+    /* write all big ints from key to DER tmps */
+    for (i = 0; i < RSA_INTS; i++) {
+        mp_int* keyInt = GetRsaInt(key, i);
+
+        /* leading zero */
+        if ((mp_count_bits(keyInt) & 7) == 0 || mp_iszero(keyInt) == MP_YES)
+            lbit = 1;
+        else
+            lbit = 0;
+
+        rawLen = mp_unsigned_bin_size(keyInt) + lbit;
+
+        tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
+                                 DYNAMIC_TYPE_RSA);
+        if (tmps[i] == NULL) {
+            ret = MEMORY_E;
+            break;
+        }
+
+        tmps[i][0] = ASN_INTEGER;
+        sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1 + lbit; /* tag & lbit */
+
+        if (sizes[i] <= MAX_SEQ_SZ) {
+            int err;
+
+            /* leading zero */
+            if (lbit)
+                tmps[i][sizes[i]-1] = 0x00;
+
+            err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]);
+            if (err == MP_OKAY) {
+                sizes[i] += (rawLen-lbit); /* lbit included in rawLen */
+                intTotalLen += sizes[i];
+            }
+            else {
+                ret = err;
+                break;
+            }
+        }
+        else {
+            ret = ASN_INPUT_E;
+            break;
+        }
+    }
+
+    if (ret != 0) {
+        FreeTmpRsas(tmps, key->heap);
+        return ret;
+    }
+
+    /* make headers */
+    verSz = SetMyVersion(0, ver, FALSE);
+    seqSz = SetSequence(verSz + intTotalLen, seq);
+
+    outLen = seqSz + verSz + intTotalLen;
+    if (outLen > (int)inLen)
+        return BAD_FUNC_ARG;
+
+    /* write to output */
+    XMEMCPY(output, seq, seqSz);
+    j = seqSz;
+    XMEMCPY(output + j, ver, verSz);
+    j += verSz;
+
+    for (i = 0; i < RSA_INTS; i++) {
+        XMEMCPY(output + j, tmps[i], sizes[i]);
+        j += sizes[i];
+    }
+    FreeTmpRsas(tmps, key->heap);
+
+    return outLen;
+}
+
+
+/* Convert Rsa Public key to DER format, write to output (inLen), return bytes
+   written */
+int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
+{
+    return SetRsaPublicKey(output, key, inLen, 1);
+}
+
+#endif /* WOLFSSL_KEY_GEN && !NO_RSA */
+
+
+#if defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA)
+
+
+#ifdef min
+#define WOLFSSL_HAVE_MIN
+#endif
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+
+#endif /* WOLFSSL_HAVE_MIN */
+
+
+/* Initialize and Set Certficate defaults:
+   version    = 3 (0x2)
+   serial     = 0
+   sigType    = SHA_WITH_RSA
+   issuer     = blank
+   daysValid  = 500
+   selfSigned = 1 (true) use subject as issuer
+   subject    = blank
+*/
+void wc_InitCert(Cert* cert)
+{
+    cert->version    = 2;   /* version 3 is hex 2 */
+    cert->sigType    = CTC_SHAwRSA;
+    cert->daysValid  = 500;
+    cert->selfSigned = 1;
+    cert->isCA       = 0;
+    cert->bodySz     = 0;
+#ifdef WOLFSSL_ALT_NAMES
+    cert->altNamesSz   = 0;
+    cert->beforeDateSz = 0;
+    cert->afterDateSz  = 0;
+#endif
+#ifdef WOLFSSL_CERT_EXT
+    cert->skidSz = 0;
+    cert->akidSz = 0;
+    cert->keyUsage = 0;
+    cert->certPoliciesNb = 0;
+    XMEMSET(cert->akid, 0, CTC_MAX_AKID_SIZE);
+    XMEMSET(cert->skid, 0, CTC_MAX_SKID_SIZE);
+    XMEMSET(cert->certPolicies, 0, CTC_MAX_CERTPOL_NB*CTC_MAX_CERTPOL_SZ);
+#endif
+    cert->keyType    = RSA_KEY;
+    XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE);
+
+    cert->issuer.country[0] = '\0';
+    cert->issuer.countryEnc = CTC_PRINTABLE;
+    cert->issuer.state[0] = '\0';
+    cert->issuer.stateEnc = CTC_UTF8;
+    cert->issuer.locality[0] = '\0';
+    cert->issuer.localityEnc = CTC_UTF8;
+    cert->issuer.sur[0] = '\0';
+    cert->issuer.surEnc = CTC_UTF8;
+    cert->issuer.org[0] = '\0';
+    cert->issuer.orgEnc = CTC_UTF8;
+    cert->issuer.unit[0] = '\0';
+    cert->issuer.unitEnc = CTC_UTF8;
+    cert->issuer.commonName[0] = '\0';
+    cert->issuer.commonNameEnc = CTC_UTF8;
+    cert->issuer.email[0] = '\0';
+
+    cert->subject.country[0] = '\0';
+    cert->subject.countryEnc = CTC_PRINTABLE;
+    cert->subject.state[0] = '\0';
+    cert->subject.stateEnc = CTC_UTF8;
+    cert->subject.locality[0] = '\0';
+    cert->subject.localityEnc = CTC_UTF8;
+    cert->subject.sur[0] = '\0';
+    cert->subject.surEnc = CTC_UTF8;
+    cert->subject.org[0] = '\0';
+    cert->subject.orgEnc = CTC_UTF8;
+    cert->subject.unit[0] = '\0';
+    cert->subject.unitEnc = CTC_UTF8;
+    cert->subject.commonName[0] = '\0';
+    cert->subject.commonNameEnc = CTC_UTF8;
+    cert->subject.email[0] = '\0';
+
+#ifdef WOLFSSL_CERT_REQ
+    cert->challengePw[0] ='\0';
+#endif
+}
+
+
+/* DER encoded x509 Certificate */
+typedef struct DerCert {
+    byte size[MAX_LENGTH_SZ];          /* length encoded */
+    byte version[MAX_VERSION_SZ];      /* version encoded */
+    byte serial[CTC_SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */
+    byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
+    byte issuer[ASN_NAME_MAX];         /* issuer  encoded */
+    byte subject[ASN_NAME_MAX];        /* subject encoded */
+    byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2];  /* before and after dates */
+    byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */
+    byte ca[MAX_CA_SZ];                /* basic constraint CA true size */
+    byte extensions[MAX_EXTENSIONS_SZ]; /* all extensions */
+#ifdef WOLFSSL_CERT_EXT
+    byte skid[MAX_KID_SZ];             /* Subject Key Identifier extension */
+    byte akid[MAX_KID_SZ];             /* Authority Key Identifier extension */
+    byte keyUsage[MAX_KEYUSAGE_SZ];    /* Key Usage extension */
+    byte certPolicies[MAX_CERTPOL_NB*MAX_CERTPOL_SZ]; /* Certificate Policies */
+#endif
+#ifdef WOLFSSL_CERT_REQ
+    byte attrib[MAX_ATTRIB_SZ];        /* Cert req attributes encoded */
+#endif
+#ifdef WOLFSSL_ALT_NAMES
+    byte altNames[CTC_MAX_ALT_SIZE];   /* Alternative Names encoded */
+#endif
+    int  sizeSz;                       /* encoded size length */
+    int  versionSz;                    /* encoded version length */
+    int  serialSz;                     /* encoded serial length */
+    int  sigAlgoSz;                    /* enocded sig alog length */
+    int  issuerSz;                     /* encoded issuer length */
+    int  subjectSz;                    /* encoded subject length */
+    int  validitySz;                   /* encoded validity length */
+    int  publicKeySz;                  /* encoded public key length */
+    int  caSz;                         /* encoded CA extension length */
+#ifdef WOLFSSL_CERT_EXT
+    int  skidSz;                       /* encoded SKID extension length */
+    int  akidSz;                       /* encoded SKID extension length */
+    int  keyUsageSz;                   /* encoded KeyUsage extension length */
+    int  certPoliciesSz;               /* encoded CertPolicies extension length*/
+#endif
+#ifdef WOLFSSL_ALT_NAMES
+    int  altNamesSz;                   /* encoded AltNames extension length */
+#endif
+    int  extensionsSz;                 /* encoded extensions total length */
+    int  total;                        /* total encoded lengths */
+#ifdef WOLFSSL_CERT_REQ
+    int  attribSz;
+#endif
+} DerCert;
+
+
+#ifdef WOLFSSL_CERT_REQ
+
+/* Write a set header to output */
+static word32 SetUTF8String(word32 len, byte* output)
+{
+    output[0] = ASN_UTF8STRING;
+    return SetLength(len, output + 1) + 1;
+}
+
+#endif /* WOLFSSL_CERT_REQ */
+
+
+/* Write a serial number to output */
+static int SetSerial(const byte* serial, byte* output)
+{
+    int length = 0;
+
+    output[length++] = ASN_INTEGER;
+    length += SetLength(CTC_SERIAL_SIZE, &output[length]);
+    XMEMCPY(&output[length], serial, CTC_SERIAL_SIZE);
+
+    return length + CTC_SERIAL_SIZE;
+}
+
+
+#ifdef HAVE_ECC
+
+
+/* Write a public ECC key to output */
+static int SetEccPublicKey(byte* output, ecc_key* key, int with_header)
+{
+    byte len[MAX_LENGTH_SZ + 1];  /* trailing 0 */
+    int  algoSz;
+    int  curveSz;
+    int  lenSz;
+    int  idx;
+    word32 pubSz = ECC_BUFSIZE;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* algo = NULL;
+    byte* curve = NULL;
+    byte* pub = NULL;
+#else
+    byte algo[MAX_ALGO_SZ];
+    byte curve[MAX_ALGO_SZ];
+    byte pub[ECC_BUFSIZE];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pub == NULL)
+        return MEMORY_E;
+#endif
+
+    int ret = wc_ecc_export_x963(key, pub, &pubSz);
+    if (ret != 0) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return ret;
+    }
+
+    /* headers */
+    if (with_header) {
+#ifdef WOLFSSL_SMALL_STACK
+        curve = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (curve == NULL) {
+            XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return MEMORY_E;
+        }
+#endif
+        curveSz = SetCurve(key, curve);
+        if (curveSz <= 0) {
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return curveSz;
+        }
+
+#ifdef WOLFSSL_SMALL_STACK
+        algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (algo == NULL) {
+            XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return MEMORY_E;
+        }
+#endif
+        algoSz  = SetAlgoID(ECDSAk, algo, keyType, curveSz);
+
+        lenSz   = SetLength(pubSz + 1, len);
+        len[lenSz++] = 0;   /* trailing 0 */
+
+        /* write, 1 is for ASN_BIT_STRING */
+        idx = SetSequence(pubSz + curveSz + lenSz + 1 + algoSz, output);
+        /* algo */
+        XMEMCPY(output + idx, algo, algoSz);
+        idx += algoSz;
+       /* curve */
+        XMEMCPY(output + idx, curve, curveSz);
+        idx += curveSz;
+        /* bit string */
+        output[idx++] = ASN_BIT_STRING;
+        /* length */
+        XMEMCPY(output + idx, len, lenSz);
+        idx += lenSz;
+    }
+    else
+        idx = 0;
+
+    /* pub */
+    XMEMCPY(output + idx, pub, pubSz);
+    idx += pubSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    if (with_header) {
+        XFREE(algo,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+    XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return idx;
+}
+
+
+#endif /* HAVE_ECC */
+
+
+static INLINE byte itob(int number)
+{
+    return (byte)number + 0x30;
+}
+
+
+/* write time to output, format */
+static void SetTime(struct tm* date, byte* output)
+{
+    int i = 0;
+
+    output[i++] = itob((date->tm_year % 10000) / 1000);
+    output[i++] = itob((date->tm_year % 1000)  /  100);
+    output[i++] = itob((date->tm_year % 100)   /   10);
+    output[i++] = itob( date->tm_year % 10);
+
+    output[i++] = itob(date->tm_mon / 10);
+    output[i++] = itob(date->tm_mon % 10);
+
+    output[i++] = itob(date->tm_mday / 10);
+    output[i++] = itob(date->tm_mday % 10);
+
+    output[i++] = itob(date->tm_hour / 10);
+    output[i++] = itob(date->tm_hour % 10);
+
+    output[i++] = itob(date->tm_min / 10);
+    output[i++] = itob(date->tm_min % 10);
+
+    output[i++] = itob(date->tm_sec / 10);
+    output[i++] = itob(date->tm_sec % 10);
+
+    output[i] = 'Z';  /* Zulu profile */
+}
+
+
+#ifdef WOLFSSL_ALT_NAMES
+
+/* Copy Dates from cert, return bytes written */
+static int CopyValidity(byte* output, Cert* cert)
+{
+    int seqSz;
+
+    WOLFSSL_ENTER("CopyValidity");
+
+    /* headers and output */
+    seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output);
+    XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz);
+    XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
+                                                 cert->afterDateSz);
+    return seqSz + cert->beforeDateSz + cert->afterDateSz;
+}
+
+#endif
+
+
+/* for systems where mktime() doesn't normalize fully */
+static void RebuildTime(time_t* in, struct tm* out)
+{
+    #ifdef FREESCALE_MQX
+        out = localtime_r(in, out);
+    #else
+        (void)in;
+        (void)out;
+    #endif
+}
+
+
+/* Set Date validity from now until now + daysValid
+ * return size in bytes written to output, 0 on error */
+static int SetValidity(byte* output, int daysValid)
+{
+    byte before[MAX_DATE_SIZE];
+    byte  after[MAX_DATE_SIZE];
+
+    int beforeSz;
+    int afterSz;
+    int seqSz;
+
+    time_t     ticks;
+    time_t     normalTime;
+    struct tm* now;
+    struct tm* tmpTime = NULL;
+    struct tm  local;
+
+#if defined(FREESCALE_MQX) || defined(TIME_OVERRIDES)
+    /* for use with gmtime_r */
+    struct tm tmpTimeStorage;
+    tmpTime = &tmpTimeStorage;
+#else
+    (void)tmpTime;
+#endif
+
+    ticks = XTIME(0);
+    now   = XGMTIME(&ticks, tmpTime);
+
+    if (now == NULL) {
+        WOLFSSL_MSG("XGMTIME failed");
+        return 0;   /* error */
+    }
+
+    /* before now */
+    local = *now;
+    before[0] = ASN_GENERALIZED_TIME;
+    beforeSz  = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
+
+    /* subtract 1 day for more compliance */
+    local.tm_mday -= 1;
+    normalTime = mktime(&local);
+    RebuildTime(&normalTime, &local);
+
+    /* adjust */
+    local.tm_year += 1900;
+    local.tm_mon  +=    1;
+
+    SetTime(&local, before + beforeSz);
+    beforeSz += ASN_GEN_TIME_SZ;
+
+    /* after now + daysValid */
+    local = *now;
+    after[0] = ASN_GENERALIZED_TIME;
+    afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
+
+    /* add daysValid */
+    local.tm_mday += daysValid;
+    normalTime = mktime(&local);
+    RebuildTime(&normalTime, &local);
+
+    /* adjust */
+    local.tm_year += 1900;
+    local.tm_mon  +=    1;
+
+    SetTime(&local, after + afterSz);
+    afterSz += ASN_GEN_TIME_SZ;
+
+    /* headers and output */
+    seqSz = SetSequence(beforeSz + afterSz, output);
+    XMEMCPY(output + seqSz, before, beforeSz);
+    XMEMCPY(output + seqSz + beforeSz, after, afterSz);
+
+    return seqSz + beforeSz + afterSz;
+}
+
+
+/* ASN Encoded Name field */
+typedef struct EncodedName {
+    int  nameLen;                /* actual string value length */
+    int  totalLen;               /* total encoded length */
+    int  type;                   /* type of name */
+    int  used;                   /* are we actually using this one */
+    byte encoded[CTC_NAME_SIZE * 2]; /* encoding */
+} EncodedName;
+
+
+/* Get Which Name from index */
+static const char* GetOneName(CertName* name, int idx)
+{
+    switch (idx) {
+    case 0:
+       return name->country;
+
+    case 1:
+       return name->state;
+
+    case 2:
+       return name->locality;
+
+    case 3:
+       return name->sur;
+
+    case 4:
+       return name->org;
+
+    case 5:
+       return name->unit;
+
+    case 6:
+       return name->commonName;
+
+    case 7:
+       return name->email;
+
+    default:
+       return 0;
+    }
+}
+
+
+/* Get Which Name Encoding from index */
+static char GetNameType(CertName* name, int idx)
+{
+    switch (idx) {
+    case 0:
+       return name->countryEnc;
+
+    case 1:
+       return name->stateEnc;
+
+    case 2:
+       return name->localityEnc;
+
+    case 3:
+       return name->surEnc;
+
+    case 4:
+       return name->orgEnc;
+
+    case 5:
+       return name->unitEnc;
+
+    case 6:
+       return name->commonNameEnc;
+
+    default:
+       return 0;
+    }
+}
+
+
+/* Get ASN Name from index */
+static byte GetNameId(int idx)
+{
+    switch (idx) {
+    case 0:
+       return ASN_COUNTRY_NAME;
+
+    case 1:
+       return ASN_STATE_NAME;
+
+    case 2:
+       return ASN_LOCALITY_NAME;
+
+    case 3:
+       return ASN_SUR_NAME;
+
+    case 4:
+       return ASN_ORG_NAME;
+
+    case 5:
+       return ASN_ORGUNIT_NAME;
+
+    case 6:
+       return ASN_COMMON_NAME;
+
+    case 7:
+       /* email uses different id type */
+       return 0;
+
+    default:
+       return 0;
+    }
+}
+
+/*
+ Extensions ::= SEQUENCE OF Extension
+
+ Extension ::= SEQUENCE {
+ extnId     OBJECT IDENTIFIER,
+ critical   BOOLEAN DEFAULT FALSE,
+ extnValue  OCTET STRING }
+ */
+
+/* encode all extensions, return total bytes written */
+static int SetExtensions(byte* out, word32 outSz, int *IdxInOut,
+                         const byte* ext, int extSz)
+{
+    if (out == NULL || IdxInOut == NULL || ext == NULL)
+        return BAD_FUNC_ARG;
+
+    if (outSz < (word32)(*IdxInOut+extSz))
+        return BUFFER_E;
+
+    XMEMCPY(&out[*IdxInOut], ext, extSz);  /* extensions */
+    *IdxInOut += extSz;
+
+    return *IdxInOut;
+}
+
+/* encode extensions header, return total bytes written */
+static int SetExtensionsHeader(byte* out, word32 outSz, int extSz)
+{
+    byte sequence[MAX_SEQ_SZ];
+    byte len[MAX_LENGTH_SZ];
+    int seqSz, lenSz, idx = 0;
+
+    if (out == NULL)
+        return BAD_FUNC_ARG;
+
+    if (outSz < 3)
+        return BUFFER_E;
+
+    seqSz = SetSequence(extSz, sequence);
+
+    /* encode extensions length provided */
+    lenSz = SetLength(extSz+seqSz, len);
+
+    if (outSz < (word32)(lenSz+seqSz+1))
+        return BUFFER_E;
+
+    out[idx++] = ASN_EXTENSIONS; /* extensions id */
+    XMEMCPY(&out[idx], len, lenSz);  /* length */
+    idx += lenSz;
+
+    XMEMCPY(&out[idx], sequence, seqSz);  /* sequence */
+    idx += seqSz;
+
+    return idx;
+}
+
+
+/* encode CA basic constraint true, return total bytes written */
+static int SetCa(byte* out, word32 outSz)
+{
+    static const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
+                               0x05, 0x30, 0x03, 0x01, 0x01, 0xff };
+
+    if (out == NULL)
+        return BAD_FUNC_ARG;
+
+    if (outSz < sizeof(ca))
+        return BUFFER_E;
+
+    XMEMCPY(out, ca, sizeof(ca));
+
+    return (int)sizeof(ca);
+}
+
+
+#ifdef WOLFSSL_CERT_EXT
+/* encode OID and associated value, return total bytes written */
+static int SetOidValue(byte* out, word32 outSz, const byte *oid, word32 oidSz,
+                       byte *in, word32 inSz)
+{
+    int idx = 0;
+
+    if (out == NULL || oid == NULL || in == NULL)
+        return BAD_FUNC_ARG;
+
+    if (outSz < 3)
+        return BUFFER_E;
+
+    /* sequence,  + 1 => byte to put value size */
+    idx = SetSequence(inSz + oidSz + 1, out);
+
+    if (outSz < idx + inSz + oidSz + 1)
+        return BUFFER_E;
+
+    XMEMCPY(out+idx, oid, oidSz);
+    idx += oidSz;
+    out[idx++] = (byte)inSz;
+    XMEMCPY(out+idx, in, inSz);
+
+    return (idx+inSz);
+}
+
+/* encode Subject Key Identifier, return total bytes written
+ * RFC5280 : non-critical */
+static int SetSKID(byte* output, word32 outSz, byte *input, word32 length)
+{
+    byte skid_len[MAX_LENGTH_SZ];
+    byte skid_enc_len[MAX_LENGTH_SZ];
+    int idx = 0, skid_lenSz, skid_enc_lenSz;
+    static const byte skid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04 };
+
+    if (output == NULL || input == NULL)
+        return BAD_FUNC_ARG;
+
+    /* length of value */
+    skid_lenSz = SetLength(length, skid_len);
+
+    /* length of encoded value */
+    skid_enc_lenSz = SetLength(length + skid_lenSz + 1, skid_enc_len);
+
+    if (outSz < 3)
+        return BUFFER_E;
+
+    /* sequence, + 1 => byte to put type size */
+    idx = SetSequence(length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz+1,
+                      output);
+
+    if (outSz < length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz + 1)
+        return BUFFER_E;
+
+    /* put oid */
+    XMEMCPY(output+idx, skid_oid, sizeof(skid_oid));
+    idx += sizeof(skid_oid);
+
+    /* put encoded len */
+    XMEMCPY(output+idx, skid_enc_len, skid_enc_lenSz);
+    idx += skid_enc_lenSz;
+
+    /* put type */
+    output[idx++] = ASN_OCTET_STRING;
+
+    /* put value len */
+    XMEMCPY(output+idx, skid_len, skid_lenSz);
+    idx += skid_lenSz;
+
+    /* put value */
+    XMEMCPY(output+idx, input, length);
+    idx += length;
+
+    return idx;
+}
+
+/* encode Authority Key Identifier, return total bytes written
+ * RFC5280 : non-critical */
+static int SetAKID(byte* output, word32 outSz, byte *input, word32 length)
+{
+    byte    *enc_val;
+    int     ret, enc_valSz;
+    static const byte akid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04};
+    static const byte akid_cs[] = { 0x80 };
+
+    if (output == NULL || input == NULL)
+        return BAD_FUNC_ARG;
+
+    enc_val = (byte *)XMALLOC(length+3+sizeof(akid_cs), NULL,
+                               DYNAMIC_TYPE_TMP_BUFFER);
+    if (enc_val == NULL)
+        return MEMORY_E;
+
+    /* sequence for ContentSpec & value */
+    enc_valSz = SetOidValue(enc_val, length+3+sizeof(akid_cs),
+                            akid_cs, sizeof(akid_cs), input, length);
+    if (enc_valSz == 0) {
+        XFREE(enc_val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return 0;
+    }
+
+    ret = SetOidValue(output, outSz, akid_oid,
+                      sizeof(akid_oid), enc_val, enc_valSz);
+
+    XFREE(enc_val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    return ret;
+}
+
+/* encode Key Usage, return total bytes written
+ * RFC5280 : critical */
+static int SetKeyUsage(byte* output, word32 outSz, word16 input)
+{
+    byte ku[5];
+    int unusedBits = 0;
+    static const byte keyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0f,
+                                         0x01, 0x01, 0xff, 0x04};
+
+    if (output == NULL)
+        return BAD_FUNC_ARG;
+
+    /* Key Usage is a BitString */
+    ku[0] = ASN_BIT_STRING;
+
+    /* put the Bit String size */
+    if (input > 255) {
+        ku[1] = (byte)3;
+
+        /* compute unused bits */
+        while (((((input >> 8) & 0xff) >> unusedBits) & 0x01) == 0)
+            unusedBits++;
+    }
+    else {
+        ku[1] = (byte)2;
+
+        /* compute unused bits */
+        while (((input >> unusedBits) & 0x01) == 0)
+            unusedBits++;
+    }
+
+    /* put unused bits value */
+    ku[2] = (byte)unusedBits;
+
+    /* compute byte value */
+    ku[3] = (byte)(input & 0xff);
+    if (input > 255)
+        ku[4] = (byte)((input >> 8) & 0xff);
+
+    return SetOidValue(output, outSz, keyusage_oid, sizeof(keyusage_oid),
+                       ku, (int)ku[1]+2);
+}
+
+/* Encode OID string representation to ITU-T X.690 format */
+static int EncodePolicyOID(byte *out, word32 *outSz, const char *in)
+{
+    word32 val, idx = 0, nb_val;
+    char *token, *str, *ptr;
+    word32 len;
+
+    if (out == NULL || outSz == NULL || *outSz < 2 || in == NULL)
+        return BAD_FUNC_ARG;
+
+    len = (word32)XSTRLEN(in);
+
+    str = (char *)XMALLOC(len+1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (str == NULL)
+        return MEMORY_E;
+
+    XSTRNCPY(str, in, len);
+    str[len] = 0x00;
+
+    nb_val = 0;
+
+    /* parse value, and set corresponding Policy OID value */
+    token = XSTRTOK(str, ".", &ptr);
+    while (token != NULL)
+    {
+        val = (word32)atoi(token);
+
+        if (nb_val == 0) {
+            if (val > 2) {
+                XFREE(str, NUL, DYNAMIC_TYPE_TMP_BUFFER);
+                return ASN_OBJECT_ID_E;
+            }
+
+            out[idx] = (byte)(40 * val);
+        }
+        else if (nb_val == 1) {
+            if (val > 127) {
+                XFREE(str, NUL, DYNAMIC_TYPE_TMP_BUFFER);
+                return ASN_OBJECT_ID_E;
+            }
+
+            if (idx > *outSz) {
+                XFREE(str, NUL, DYNAMIC_TYPE_TMP_BUFFER);
+                return BUFFER_E;
+            }
+
+            out[idx++] += (byte)val;
+        }
+        else {
+            word32  tb = 0, x;
+            int     i = 0;
+            byte    oid[MAX_OID_SZ];
+
+            while (val >= 128) {
+                x = val % 128;
+                val /= 128;
+                oid[i++] = (byte) (((tb++) ? 0x80 : 0) | x);
+            }
+
+            if ((idx+(word32)i) > *outSz) {
+                XFREE(str, NUL, DYNAMIC_TYPE_TMP_BUFFER);
+                return BUFFER_E;
+            }
+
+            oid[i] = (byte) (((tb++) ? 0x80 : 0) | val);
+
+            /* push value in the right order */
+            while (i >= 0)
+                out[idx++] = oid[i--];
+        }
+
+        token = XSTRTOK(NULL, ".", &ptr);
+        nb_val++;
+    }
+
+    *outSz = idx;
+
+    XFREE(str, NUL, DYNAMIC_TYPE_TMP_BUFFER);
+    return 0;
+}
+
+/* encode Certificate Policies, return total bytes written
+ * each input value must be ITU-T X.690 formatted : a.b.c...
+ * input must be an array of values with a NULL terminated for the latest
+ * RFC5280 : non-critical */
+static int SetCertificatePolicies(byte *output,
+                                  word32 outputSz,
+                                  char input[MAX_CERTPOL_NB][MAX_CERTPOL_SZ],
+                                  word16 nb_certpol)
+{
+    byte    oid[MAX_OID_SZ],
+            der_oid[MAX_CERTPOL_NB][MAX_OID_SZ],
+            out[MAX_CERTPOL_SZ];
+    word32  oidSz;
+    word32  outSz, i = 0, der_oidSz[MAX_CERTPOL_NB];
+    int     ret;
+
+    static const byte certpol_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04 };
+    static const byte oid_oid[] = { 0x06 };
+
+    if (output == NULL || input == NULL || nb_certpol > MAX_CERTPOL_NB)
+        return BAD_FUNC_ARG;
+
+    for (i = 0; i < nb_certpol; i++) {
+        oidSz = sizeof(oid);
+        XMEMSET(oid, 0, oidSz);
+
+        ret = EncodePolicyOID(oid, &oidSz, input[i]);
+        if (ret != 0)
+            return ret;
+
+        /* compute sequence value for the oid */
+        ret = SetOidValue(der_oid[i], MAX_OID_SZ, oid_oid,
+                          sizeof(oid_oid), oid, oidSz);
+        if (ret <= 0)
+            return ret;
+        else
+            der_oidSz[i] = (word32)ret;
+    }
+
+    /* concatene oid, keep two byte for sequence/size of the created value */
+    for (i = 0, outSz = 2; i < nb_certpol; i++) {
+        XMEMCPY(out+outSz, der_oid[i], der_oidSz[i]);
+        outSz += der_oidSz[i];
+    }
+
+    /* add sequence */
+    ret = SetSequence(outSz-2, out);
+    if (ret <= 0)
+        return ret;
+
+    /* add Policy OID to compute final value */
+    return SetOidValue(output, outputSz, certpol_oid, sizeof(certpol_oid),
+                      out, outSz);
+}
+#endif /* WOLFSSL_CERT_EXT */
+
+#ifdef WOLFSSL_ALT_NAMES
+/* encode Alternative Names, return total bytes written */
+static int SetAltNames(byte *out, word32 outSz, byte *input, word32 length)
+{
+    if (out == NULL || input == NULL)
+        return BAD_FUNC_ARG;
+
+    if (outSz < length)
+        return BUFFER_E;
+
+    /* Alternative Names come from certificate or computed by
+     * external function, so already encoded. Just copy value */
+    XMEMCPY(out, input, length);
+    return length;
+}
+#endif /* WOLFSL_ALT_NAMES */
+
+
+/* encode CertName into output, return total bytes written */
+static int SetName(byte* output, word32 outputSz, CertName* name)
+{
+    int          totalBytes = 0, i, idx;
+#ifdef WOLFSSL_SMALL_STACK
+    EncodedName* names = NULL;
+#else
+    EncodedName  names[NAME_ENTRIES];
+#endif
+
+    if (output == NULL || name == NULL)
+        return BAD_FUNC_ARG;
+
+    if (outputSz < 3)
+        return BUFFER_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+    names = (EncodedName*)XMALLOC(sizeof(EncodedName) * NAME_ENTRIES, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (names == NULL)
+        return MEMORY_E;
+#endif
+
+    for (i = 0; i < NAME_ENTRIES; i++) {
+        const char* nameStr = GetOneName(name, i);
+        if (nameStr) {
+            /* bottom up */
+            byte firstLen[MAX_LENGTH_SZ];
+            byte secondLen[MAX_LENGTH_SZ];
+            byte sequence[MAX_SEQ_SZ];
+            byte set[MAX_SET_SZ];
+
+            int email = i == (NAME_ENTRIES - 1) ? 1 : 0;
+            int strLen  = (int)XSTRLEN(nameStr);
+            int thisLen = strLen;
+            int firstSz, secondSz, seqSz, setSz;
+
+            if (strLen == 0) { /* no user data for this item */
+                names[i].used = 0;
+                continue;
+            }
+
+            secondSz = SetLength(strLen, secondLen);
+            thisLen += secondSz;
+            if (email) {
+                thisLen += EMAIL_JOINT_LEN;
+                thisLen ++;                               /* id type */
+                firstSz  = SetLength(EMAIL_JOINT_LEN, firstLen);
+            }
+            else {
+                thisLen++;                                 /* str type */
+                thisLen++;                                 /* id  type */
+                thisLen += JOINT_LEN;
+                firstSz = SetLength(JOINT_LEN + 1, firstLen);
+            }
+            thisLen += firstSz;
+            thisLen++;                                /* object id */
+
+            seqSz = SetSequence(thisLen, sequence);
+            thisLen += seqSz;
+            setSz = SetSet(thisLen, set);
+            thisLen += setSz;
+
+            if (thisLen > (int)sizeof(names[i].encoded)) {
+#ifdef WOLFSSL_SMALL_STACK
+                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+                return BUFFER_E;
+            }
+
+            /* store it */
+            idx = 0;
+            /* set */
+            XMEMCPY(names[i].encoded, set, setSz);
+            idx += setSz;
+            /* seq */
+            XMEMCPY(names[i].encoded + idx, sequence, seqSz);
+            idx += seqSz;
+            /* asn object id */
+            names[i].encoded[idx++] = ASN_OBJECT_ID;
+            /* first length */
+            XMEMCPY(names[i].encoded + idx, firstLen, firstSz);
+            idx += firstSz;
+            if (email) {
+                const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+                                           0x01, 0x09, 0x01, 0x16 };
+                /* email joint id */
+                XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
+                idx += (int)sizeof(EMAIL_OID);
+            }
+            else {
+                /* joint id */
+                byte bType = GetNameId(i);
+                names[i].encoded[idx++] = 0x55;
+                names[i].encoded[idx++] = 0x04;
+                /* id type */
+                names[i].encoded[idx++] = bType;
+                /* str type */
+                names[i].encoded[idx++] = GetNameType(name, i);
+            }
+            /* second length */
+            XMEMCPY(names[i].encoded + idx, secondLen, secondSz);
+            idx += secondSz;
+            /* str value */
+            XMEMCPY(names[i].encoded + idx, nameStr, strLen);
+            idx += strLen;
+
+            totalBytes += idx;
+            names[i].totalLen = idx;
+            names[i].used = 1;
+        }
+        else
+            names[i].used = 0;
+    }
+
+    /* header */
+    idx = SetSequence(totalBytes, output);
+    totalBytes += idx;
+    if (totalBytes > ASN_NAME_MAX) {
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+        return BUFFER_E;
+    }
+
+    for (i = 0; i < NAME_ENTRIES; i++) {
+        if (names[i].used) {
+            if (outputSz < (word32)(idx+names[i].totalLen)) {
+#ifdef WOLFSSL_SMALL_STACK
+                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+                return BUFFER_E;
+            }
+
+            XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
+            idx += names[i].totalLen;
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return totalBytes;
+}
+
+/* encode info from cert into DER encoded format */
+static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
+                      WC_RNG* rng, const byte* ntruKey, word16 ntruSz)
+{
+    int ret;
+
+    (void)eccKey;
+    (void)ntruKey;
+    (void)ntruSz;
+
+    if (cert == NULL || der == NULL || rng == NULL)
+        return BAD_FUNC_ARG;
+
+    /* init */
+    XMEMSET(der, 0, sizeof(DerCert));
+
+    /* version */
+    der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
+
+    /* serial number */
+    ret = wc_RNG_GenerateBlock(rng, cert->serial, CTC_SERIAL_SIZE);
+    if (ret != 0)
+        return ret;
+
+    cert->serial[0] = 0x01;   /* ensure positive */
+    der->serialSz  = SetSerial(cert->serial, der->serial);
+
+    /* signature algo */
+    der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, sigType, 0);
+    if (der->sigAlgoSz == 0)
+        return ALGO_ID_E;
+
+    /* public key */
+    if (cert->keyType == RSA_KEY) {
+        if (rsaKey == NULL)
+            return PUBLIC_KEY_E;
+        der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
+                                           sizeof(der->publicKey), 1);
+        if (der->publicKeySz <= 0)
+            return PUBLIC_KEY_E;
+    }
+
+#ifdef HAVE_ECC
+    if (cert->keyType == ECC_KEY) {
+        if (eccKey == NULL)
+            return PUBLIC_KEY_E;
+        der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, 1);
+        if (der->publicKeySz <= 0)
+            return PUBLIC_KEY_E;
+    }
+#endif /* HAVE_ECC */
+
+#ifdef HAVE_NTRU
+    if (cert->keyType == NTRU_KEY) {
+        word32 rc;
+        word16 encodedSz;
+
+        rc  = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
+                                                   ntruKey, &encodedSz, NULL);
+        if (rc != NTRU_OK)
+            return PUBLIC_KEY_E;
+        if (encodedSz > MAX_PUBLIC_KEY_SZ)
+            return PUBLIC_KEY_E;
+
+        rc  = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
+                                         ntruKey, &encodedSz, der->publicKey);
+        if (rc != NTRU_OK)
+            return PUBLIC_KEY_E;
+
+        der->publicKeySz = encodedSz;
+    }
+#endif /* HAVE_NTRU */
+
+    der->validitySz = 0;
+#ifdef WOLFSSL_ALT_NAMES
+    /* date validity copy ? */
+    if (cert->beforeDateSz && cert->afterDateSz) {
+        der->validitySz = CopyValidity(der->validity, cert);
+        if (der->validitySz == 0)
+            return DATE_E;
+    }
+#endif
+
+    /* date validity */
+    if (der->validitySz == 0) {
+        der->validitySz = SetValidity(der->validity, cert->daysValid);
+        if (der->validitySz == 0)
+            return DATE_E;
+    }
+
+    /* subject name */
+    der->subjectSz = SetName(der->subject, sizeof(der->subject), &cert->subject);
+    if (der->subjectSz == 0)
+        return SUBJECT_E;
+
+    /* issuer name */
+    der->issuerSz = SetName(der->issuer, sizeof(der->issuer), cert->selfSigned ?
+             &cert->subject : &cert->issuer);
+    if (der->issuerSz == 0)
+        return ISSUER_E;
+
+    /* set the extensions */
+    der->extensionsSz = 0;
+
+    /* CA */
+    if (cert->isCA) {
+        der->caSz = SetCa(der->ca, sizeof(der->ca));
+        if (der->caSz == 0)
+            return CA_TRUE_E;
+
+        der->extensionsSz += der->caSz;
+    }
+    else
+        der->caSz = 0;
+
+#ifdef WOLFSSL_ALT_NAMES
+    /* Alternative Name */
+    if (cert->altNamesSz) {
+        der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
+                                      cert->altNames, cert->altNamesSz);
+        if (der->altNamesSz == 0)
+            return ALT_NAME_E;
+
+        der->extensionsSz += der->altNamesSz;
+    }
+    else
+        der->altNamesSz = 0;
+#endif
+
+#ifdef WOLFSSL_CERT_EXT
+    /* SKID */
+    if (cert->skidSz) {
+        /* check the provided SKID size */
+        if (cert->skidSz > (int)sizeof(der->skid))
+            return SKID_E;
+
+        der->skidSz = SetSKID(der->skid, sizeof(der->skid),
+                              cert->skid, cert->skidSz);
+        if (der->skidSz == 0)
+            return SKID_E;
+
+        der->extensionsSz += der->skidSz;
+    }
+    else
+        der->skidSz = 0;
+
+    /* AKID */
+    if (cert->akidSz) {
+        /* check the provided AKID size */
+        if (cert->akidSz > (int)sizeof(der->akid))
+            return AKID_E;
+
+        der->akidSz = SetAKID(der->akid, sizeof(der->akid),
+                              cert->akid, cert->akidSz);
+        if (der->akidSz == 0)
+            return AKID_E;
+
+        der->extensionsSz += der->akidSz;
+    }
+    else
+        der->akidSz = 0;
+
+    /* Key Usage */
+    if (cert->keyUsage != 0){
+        der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
+                                      cert->keyUsage);
+        if (der->keyUsageSz == 0)
+            return KEYUSAGE_E;
+
+        der->extensionsSz += der->keyUsageSz;
+    }
+    else
+        der->keyUsageSz = 0;
+
+    /* Certificate Policies */
+    if (cert->certPoliciesNb != 0) {
+        der->certPoliciesSz = SetCertificatePolicies(der->certPolicies,
+                                                     sizeof(der->certPolicies),
+                                                     cert->certPolicies,
+                                                     cert->certPoliciesNb);
+        if (der->certPoliciesSz == 0)
+            return CERTPOLICIES_E;
+
+        der->extensionsSz += der->certPoliciesSz;
+    }
+    else
+        der->certPoliciesSz = 0;
+#endif /* WOLFSSL_CERT_EXT */
+
+    /* put extensions */
+    if (der->extensionsSz > 0) {
+
+        /* put the start of extensions sequence (ID, Size) */
+        der->extensionsSz = SetExtensionsHeader(der->extensions,
+                                                sizeof(der->extensions),
+                                                der->extensionsSz);
+        if (der->extensionsSz == 0)
+            return EXTENSIONS_E;
+
+        /* put CA */
+        if (der->caSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->ca, der->caSz);
+            if (ret == 0)
+                return EXTENSIONS_E;
+        }
+
+#ifdef WOLFSSL_ALT_NAMES
+        /* put Alternative Names */
+        if (der->altNamesSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->altNames, der->altNamesSz);
+            if (ret == 0)
+                return EXTENSIONS_E;
+        }
+#endif
+
+#ifdef WOLFSSL_CERT_EXT
+        /* put SKID */
+        if (der->skidSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->skid, der->skidSz);
+            if (ret == 0)
+                return EXTENSIONS_E;
+        }
+
+        /* put AKID */
+        if (der->akidSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->akid, der->akidSz);
+            if (ret == 0)
+                return EXTENSIONS_E;
+        }
+
+        /* put KeyUsage */
+        if (der->keyUsageSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->keyUsage, der->keyUsageSz);
+            if (ret == 0)
+                return EXTENSIONS_E;
+        }
+
+        /* put Certificate Policies */
+        if (der->certPoliciesSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->certPolicies, der->certPoliciesSz);
+            if (ret == 0)
+                return EXTENSIONS_E;
+        }
+#endif /* WOLFSSL_CERT_EXT */
+    }
+
+    der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
+        der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
+        der->extensionsSz;
+
+    return 0;
+}
+
+
+/* write DER encoded cert to buffer, size already checked */
+static int WriteCertBody(DerCert* der, byte* buffer)
+{
+    int idx;
+
+    /* signed part header */
+    idx = SetSequence(der->total, buffer);
+    /* version */
+    XMEMCPY(buffer + idx, der->version, der->versionSz);
+    idx += der->versionSz;
+    /* serial */
+    XMEMCPY(buffer + idx, der->serial, der->serialSz);
+    idx += der->serialSz;
+    /* sig algo */
+    XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz);
+    idx += der->sigAlgoSz;
+    /* issuer */
+    XMEMCPY(buffer + idx, der->issuer, der->issuerSz);
+    idx += der->issuerSz;
+    /* validity */
+    XMEMCPY(buffer + idx, der->validity, der->validitySz);
+    idx += der->validitySz;
+    /* subject */
+    XMEMCPY(buffer + idx, der->subject, der->subjectSz);
+    idx += der->subjectSz;
+    /* public key */
+    XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
+    idx += der->publicKeySz;
+    if (der->extensionsSz) {
+        /* extensions */
+        XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
+                                                   sizeof(der->extensions)));
+        idx += der->extensionsSz;
+    }
+
+    return idx;
+}
+
+
+/* Make RSA signature from buffer (sz), write to sig (sigSz) */
+static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
+                         RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,
+                         int sigAlgoType)
+{
+    int encSigSz, digestSz, typeH = 0, ret = 0;
+    byte digest[MAX_DIGEST_SIZE]; /* max size */
+#ifdef WOLFSSL_SMALL_STACK
+    byte* encSig;
+#else
+    byte encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ];
+#endif
+
+    (void)digest;
+    (void)digestSz;
+    (void)encSig;
+    (void)encSigSz;
+    (void)typeH;
+
+    (void)buffer;
+    (void)sz;
+    (void)sig;
+    (void)sigSz;
+    (void)rsaKey;
+    (void)eccKey;
+    (void)rng;
+
+    switch (sigAlgoType) {
+    #ifndef NO_MD5
+        case CTC_MD5wRSA:
+        if ((ret = wc_Md5Hash(buffer, sz, digest)) == 0) {
+            typeH    = MD5h;
+            digestSz = MD5_DIGEST_SIZE;
+        }
+        break;
+    #endif
+    #ifndef NO_SHA
+        case CTC_SHAwRSA:
+        case CTC_SHAwECDSA:
+        if ((ret = wc_ShaHash(buffer, sz, digest)) == 0) {
+            typeH    = SHAh;
+            digestSz = SHA_DIGEST_SIZE;
+        }
+        break;
+    #endif
+    #ifndef NO_SHA256
+        case CTC_SHA256wRSA:
+        case CTC_SHA256wECDSA:
+        if ((ret = wc_Sha256Hash(buffer, sz, digest)) == 0) {
+            typeH    = SHA256h;
+            digestSz = SHA256_DIGEST_SIZE;
+        }
+        break;
+    #endif
+    #ifdef WOLFSSL_SHA512
+        case CTC_SHA512wRSA:
+        case CTC_SHA512wECDSA:
+        if ((ret = wc_Sha512Hash(buffer, sz, digest)) == 0) {
+            typeH    = SHA256h;
+            digestSz = SHA256_DIGEST_SIZE;
+        }
+        break;
+    #endif
+        default:
+            WOLFSSL_MSG("MakeSignautre called with unsupported type");
+            ret = ALGO_ID_E;
+    }
+
+    if (ret != 0)
+        return ret;
+
+#ifdef WOLFSSL_SMALL_STACK
+    encSig = (byte*)XMALLOC(MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ,
+                                                 NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (encSig == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = ALGO_ID_E;
+
+#ifndef NO_RSA
+    if (rsaKey) {
+        /* signature */
+        encSigSz = wc_EncodeSignature(encSig, digest, digestSz, typeH);
+        ret = wc_RsaSSL_Sign(encSig, encSigSz, sig, sigSz, rsaKey, rng);
+    }
+#endif
+
+#ifdef HAVE_ECC
+    if (!rsaKey && eccKey) {
+        word32 outSz = sigSz;
+        ret = wc_ecc_sign_hash(digest, digestSz, sig, &outSz, rng, eccKey);
+
+        if (ret == 0)
+            ret = outSz;
+    }
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(encSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+/* add signature to end of buffer, size of buffer assumed checked, return
+   new length */
+static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz,
+                        int sigAlgoType)
+{
+    byte seq[MAX_SEQ_SZ];
+    int  idx = bodySz, seqSz;
+
+    /* algo */
+    idx += SetAlgoID(sigAlgoType, buffer + idx, sigType, 0);
+    /* bit string */
+    buffer[idx++] = ASN_BIT_STRING;
+    /* length */
+    idx += SetLength(sigSz + 1, buffer + idx);
+    buffer[idx++] = 0;   /* trailing 0 */
+    /* signature */
+    XMEMCPY(buffer + idx, sig, sigSz);
+    idx += sigSz;
+
+    /* make room for overall header */
+    seqSz = SetSequence(idx, seq);
+    XMEMMOVE(buffer + seqSz, buffer, idx);
+    XMEMCPY(buffer, seq, seqSz);
+
+    return idx + seqSz;
+}
+
+
+/* Make an x509 Certificate v3 any key type from cert input, write to buffer */
+static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
+                       RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,
+                       const byte* ntruKey, word16 ntruSz)
+{
+    int ret;
+#ifdef WOLFSSL_SMALL_STACK
+    DerCert* der;
+#else
+    DerCert der[1];
+#endif
+
+    cert->keyType = eccKey ? ECC_KEY : (rsaKey ? RSA_KEY : NTRU_KEY);
+
+#ifdef WOLFSSL_SMALL_STACK
+    der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (der == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = EncodeCert(cert, der, rsaKey, eccKey, rng, ntruKey, ntruSz);
+    if (ret == 0) {
+        if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
+            ret = BUFFER_E;
+        else
+            ret = cert->bodySz = WriteCertBody(der, derBuffer);
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+/* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
+int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
+             ecc_key* eccKey, WC_RNG* rng)
+{
+    return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0);
+}
+
+
+#ifdef HAVE_NTRU
+
+int wc_MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,
+                  const byte* ntruKey, word16 keySz, WC_RNG* rng)
+{
+    return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz);
+}
+
+#endif /* HAVE_NTRU */
+
+
+#ifdef WOLFSSL_CERT_REQ
+
+static int SetReqAttrib(byte* output, char* pw, int extSz)
+{
+    static const byte cpOid[] =
+        { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+                         0x09, 0x07 };
+    static const byte erOid[] =
+        { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+                         0x09, 0x0e };
+
+    int sz      = 0; /* overall size */
+    int cpSz    = 0; /* Challenge Password section size */
+    int cpSeqSz = 0;
+    int cpSetSz = 0;
+    int cpStrSz = 0;
+    int pwSz    = 0;
+    int erSz    = 0; /* Extension Request section size */
+    int erSeqSz = 0;
+    int erSetSz = 0;
+    byte cpSeq[MAX_SEQ_SZ];
+    byte cpSet[MAX_SET_SZ];
+    byte cpStr[MAX_PRSTR_SZ];
+    byte erSeq[MAX_SEQ_SZ];
+    byte erSet[MAX_SET_SZ];
+
+    output[0] = 0xa0;
+    sz++;
+
+    if (pw && pw[0]) {
+        pwSz = (int)XSTRLEN(pw);
+        cpStrSz = SetUTF8String(pwSz, cpStr);
+        cpSetSz = SetSet(cpStrSz + pwSz, cpSet);
+        cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq);
+        cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz;
+    }
+
+    if (extSz) {
+        erSetSz = SetSet(extSz, erSet);
+        erSeqSz = SetSequence(erSetSz + sizeof(erOid) + extSz, erSeq);
+        erSz = extSz + erSetSz + erSeqSz + sizeof(erOid);
+    }
+
+    /* Put the pieces together. */
+    sz += SetLength(cpSz + erSz, &output[sz]);
+
+    if (cpSz) {
+        XMEMCPY(&output[sz], cpSeq, cpSeqSz);
+        sz += cpSeqSz;
+        XMEMCPY(&output[sz], cpOid, sizeof(cpOid));
+        sz += sizeof(cpOid);
+        XMEMCPY(&output[sz], cpSet, cpSetSz);
+        sz += cpSetSz;
+        XMEMCPY(&output[sz], cpStr, cpStrSz);
+        sz += cpStrSz;
+        XMEMCPY(&output[sz], pw, pwSz);
+        sz += pwSz;
+    }
+
+    if (erSz) {
+        XMEMCPY(&output[sz], erSeq, erSeqSz);
+        sz += erSeqSz;
+        XMEMCPY(&output[sz], erOid, sizeof(erOid));
+        sz += sizeof(erOid);
+        XMEMCPY(&output[sz], erSet, erSetSz);
+        sz += erSetSz;
+        /* The actual extension data will be tacked onto the output later. */
+    }
+
+    return sz;
+}
+
+
+/* encode info from cert into DER encoded format */
+static int EncodeCertReq(Cert* cert, DerCert* der,
+                         RsaKey* rsaKey, ecc_key* eccKey)
+{
+    (void)eccKey;
+
+    if (cert == NULL || der == NULL)
+        return BAD_FUNC_ARG;
+
+    /* init */
+    XMEMSET(der, 0, sizeof(DerCert));
+
+    /* version */
+    der->versionSz = SetMyVersion(cert->version, der->version, FALSE);
+
+    /* subject name */
+    der->subjectSz = SetName(der->subject, sizeof(der->subject), &cert->subject);
+    if (der->subjectSz == 0)
+        return SUBJECT_E;
+
+    /* public key */
+    if (cert->keyType == RSA_KEY) {
+        if (rsaKey == NULL)
+            return PUBLIC_KEY_E;
+        der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
+                                           sizeof(der->publicKey), 1);
+        if (der->publicKeySz <= 0)
+            return PUBLIC_KEY_E;
+    }
+
+#ifdef HAVE_ECC
+    if (cert->keyType == ECC_KEY) {
+        if (eccKey == NULL)
+            return PUBLIC_KEY_E;
+        der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, 1);
+        if (der->publicKeySz <= 0)
+            return PUBLIC_KEY_E;
+    }
+#endif /* HAVE_ECC */
+
+    /* set the extensions */
+    der->extensionsSz = 0;
+
+    /* CA */
+    if (cert->isCA) {
+        der->caSz = SetCa(der->ca, sizeof(der->ca));
+        if (der->caSz == 0)
+            return CA_TRUE_E;
+
+        der->extensionsSz += der->caSz;
+    }
+    else
+        der->caSz = 0;
+
+#ifdef WOLFSSL_CERT_EXT
+    /* SKID */
+    if (cert->skidSz) {
+        /* check the provided SKID size */
+        if (cert->skidSz > (int)sizeof(der->skid))
+            return SKID_E;
+
+        der->skidSz = SetSKID(der->skid, sizeof(der->skid),
+                              cert->skid, cert->skidSz);
+        if (der->skidSz == 0)
+            return SKID_E;
+
+        der->extensionsSz += der->skidSz;
+    }
+    else
+        der->skidSz = 0;
+
+    /* Key Usage */
+    if (cert->keyUsage != 0){
+        der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
+                                      cert->keyUsage);
+        if (der->keyUsageSz == 0)
+            return KEYUSAGE_E;
+
+        der->extensionsSz += der->keyUsageSz;
+    }
+    else
+        der->keyUsageSz = 0;
+#endif /* WOLFSSL_CERT_EXT */
+
+    /* put extensions */
+    if (der->extensionsSz > 0) {
+        int ret;
+
+        /* put the start of sequence (ID, Size) */
+        der->extensionsSz = SetSequence(der->extensionsSz, der->extensions);
+        if (der->extensionsSz == 0)
+            return EXTENSIONS_E;
+
+        /* put CA */
+        if (der->caSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->ca, der->caSz);
+            if (ret == 0)
+                return EXTENSIONS_E;
+        }
+
+#ifdef WOLFSSL_CERT_EXT
+        /* put SKID */
+        if (der->skidSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->skid, der->skidSz);
+            if (ret == 0)
+                return EXTENSIONS_E;
+        }
+
+        /* put AKID */
+        if (der->akidSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->akid, der->akidSz);
+            if (ret == 0)
+                return EXTENSIONS_E;
+        }
+
+        /* put KeyUsage */
+        if (der->keyUsageSz) {
+            ret = SetExtensions(der->extensions, sizeof(der->extensions),
+                                &der->extensionsSz,
+                                der->keyUsage, der->keyUsageSz);
+            if (ret == 0)
+                return EXTENSIONS_E;
+        }
+
+#endif /* WOLFSSL_CERT_EXT */
+    }
+
+    der->attribSz = SetReqAttrib(der->attrib,
+                                 cert->challengePw, der->extensionsSz);
+    if (der->attribSz == 0)
+        return REQ_ATTRIBUTE_E;
+
+    der->total = der->versionSz + der->subjectSz + der->publicKeySz +
+        der->extensionsSz + der->attribSz;
+
+    return 0;
+}
+
+
+/* write DER encoded cert req to buffer, size already checked */
+static int WriteCertReqBody(DerCert* der, byte* buffer)
+{
+    int idx;
+
+    /* signed part header */
+    idx = SetSequence(der->total, buffer);
+    /* version */
+    XMEMCPY(buffer + idx, der->version, der->versionSz);
+    idx += der->versionSz;
+    /* subject */
+    XMEMCPY(buffer + idx, der->subject, der->subjectSz);
+    idx += der->subjectSz;
+    /* public key */
+    XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
+    idx += der->publicKeySz;
+    /* attributes */
+    XMEMCPY(buffer + idx, der->attrib, der->attribSz);
+    idx += der->attribSz;
+    /* extensions */
+    if (der->extensionsSz) {
+        XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
+                                                   sizeof(der->extensions)));
+        idx += der->extensionsSz;
+    }
+
+    return idx;
+}
+
+
+int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
+                RsaKey* rsaKey, ecc_key* eccKey)
+{
+    int ret;
+#ifdef WOLFSSL_SMALL_STACK
+    DerCert* der;
+#else
+    DerCert der[1];
+#endif
+
+    cert->keyType = eccKey ? ECC_KEY : RSA_KEY;
+
+#ifdef WOLFSSL_SMALL_STACK
+    der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (der == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = EncodeCertReq(cert, der, rsaKey, eccKey);
+
+    if (ret == 0) {
+        if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
+            ret = BUFFER_E;
+        else
+            ret = cert->bodySz = WriteCertReqBody(der, derBuffer);
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+#endif /* WOLFSSL_CERT_REQ */
+
+
+int wc_SignCert(int requestSz, int sType, byte* buffer, word32 buffSz,
+             RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)
+{
+    int sigSz;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* sig;
+#else
+    byte sig[MAX_ENCODED_SIG_SZ];
+#endif
+
+    if (requestSz < 0)
+        return requestSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (sig == NULL)
+        return MEMORY_E;
+#endif
+
+    sigSz = MakeSignature(buffer, requestSz, sig, MAX_ENCODED_SIG_SZ, rsaKey,
+                          eccKey, rng, sType);
+
+    if (sigSz >= 0) {
+        if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
+            sigSz = BUFFER_E;
+        else
+            sigSz = AddSignature(buffer, requestSz, sig, sigSz, sType);
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return sigSz;
+}
+
+
+int wc_MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz,
+                    RsaKey* key, WC_RNG* rng)
+{
+    int ret;
+
+    ret = wc_MakeCert(cert, buffer, buffSz, key, NULL, rng);
+    if (ret < 0)
+        return ret;
+
+    return wc_SignCert(cert->bodySz, cert->sigType,
+                       buffer, buffSz, key, NULL, rng);
+}
+
+
+#ifdef WOLFSSL_CERT_EXT
+
+/* Set KID from RSA or ECC public key */
+static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
+                                 byte *ntruKey, word16 ntruKeySz, int kid_type)
+{
+    byte    *buffer;
+    int     bufferSz, ret;
+
+#ifndef HAVE_NTRU
+    (void)ntruKeySz;
+#endif
+
+    if (cert == NULL || (rsakey == NULL && eckey == NULL && ntruKey == NULL) ||
+        (rsakey != NULL && eckey != NULL) ||
+        (rsakey != NULL && ntruKey != NULL) ||
+        (ntruKey != NULL && eckey != NULL) ||
+        (kid_type != SKID_TYPE && kid_type != AKID_TYPE))
+        return BAD_FUNC_ARG;
+
+    buffer = (byte *)XMALLOC(MAX_PUBLIC_KEY_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buffer == NULL)
+        return MEMORY_E;
+
+    /* RSA public key */
+    if (rsakey != NULL)
+        bufferSz = SetRsaPublicKey(buffer, rsakey, MAX_PUBLIC_KEY_SZ, 0);
+#ifdef HAVE_ECC
+    /* ECC public key */
+    else if (eckey != NULL)
+        bufferSz = SetEccPublicKey(buffer, eckey, 0);
+#endif /* HAVE_ECC */
+#ifdef HAVE_NTRU
+    /* NTRU public key */
+    else if (ntruKey != NULL) {
+        bufferSz = MAX_PUBLIC_KEY_SZ;
+        ret = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(
+                        ntruKeySz, ntruKey, (word16 *)(&bufferSz), buffer);
+        if (ret != NTRU_OK)
+            bufferSz = -1;
+    }
+#endif
+    else
+        bufferSz = -1;
+
+    if (bufferSz <= 0) {
+        XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return PUBLIC_KEY_E;
+    }
+
+    /* Compute SKID by hashing public key */
+#ifdef NO_SHA
+    if (kid_type == SKID_TYPE) {
+        ret = wc_Sha256Hash(buffer, bufferSz, cert->skid);
+        cert->skidSz = SHA256_DIGEST_SIZE;
+    }
+    else if (kid_type == AKID_TYPE) {
+        ret = wc_Sha256Hash(buffer, bufferSz, cert->akid);
+        cert->akidSz = SHA256_DIGEST_SIZE;
+    }
+    else
+        ret = BAD_FUNC_ARG;
+#else /* NO_SHA */
+    if (kid_type == SKID_TYPE) {
+        ret = wc_ShaHash(buffer, bufferSz, cert->skid);
+        cert->skidSz = SHA_DIGEST_SIZE;
+    }
+    else if (kid_type == AKID_TYPE) {
+        ret = wc_ShaHash(buffer, bufferSz, cert->akid);
+        cert->akidSz = SHA_DIGEST_SIZE;
+    }
+    else
+        ret = BAD_FUNC_ARG;
+#endif /* NO_SHA */
+
+    XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    return ret;
+}
+
+/* Set SKID from RSA or ECC public key */
+int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
+{
+    return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, SKID_TYPE);
+}
+
+#ifdef HAVE_NTRU
+/* Set SKID from NTRU public key */
+int wc_SetSubjectKeyIdFromNtruPublicKey(Cert *cert,
+                                        byte *ntruKey, word16 ntruKeySz)
+{
+    return SetKeyIdFromPublicKey(cert, NULL,NULL,ntruKey, ntruKeySz, SKID_TYPE);
+}
+#endif
+
+/* Set SKID from RSA or ECC public key */
+int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
+{
+    return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, AKID_TYPE);
+}
+
+
+#ifndef NO_FILESYSTEM
+
+/* Set SKID from public key file in PEM */
+int wc_SetSubjectKeyId(Cert *cert, const char* file)
+{
+    int     ret, derSz;
+    byte*   der;
+    word32  idx;
+    RsaKey  *rsakey = NULL;
+    ecc_key *eckey = NULL;
+
+    if (cert == NULL || file == NULL)
+        return BAD_FUNC_ARG;
+
+    der = (byte*)XMALLOC(MAX_PUBLIC_KEY_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (der == NULL) {
+        WOLFSSL_MSG("wc_SetSubjectKeyId memory Problem");
+        return MEMORY_E;
+    }
+
+    derSz = wolfSSL_PemPubKeyToDer(file, der, MAX_PUBLIC_KEY_SZ);
+    if (derSz <= 0)
+    {
+        XFREE(der, NULL, DYNAMIC_TYPE_CERT);
+        return derSz;
+    }
+
+    /* Load PubKey in internal structure */
+    rsakey = (RsaKey*) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
+    if (rsakey == NULL) {
+        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+
+    if (wc_InitRsaKey(rsakey, NULL) != 0) {
+        WOLFSSL_MSG("wc_InitRsaKey failure");
+        XFREE(rsakey, NULL, DYNAMIC_TYPE_RSA);
+        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+
+    idx = 0;
+    ret = wc_RsaPublicKeyDecode(der, &idx, rsakey, derSz);
+    if (ret != 0) {
+        WOLFSSL_MSG("wc_RsaPublicKeyDecode failed");
+        wc_FreeRsaKey(rsakey);
+        XFREE(rsakey, NULL, DYNAMIC_TYPE_RSA);
+        rsakey = NULL;
+#ifdef HAVE_ECC
+        /* Check to load ecc public key */
+        eckey = (ecc_key*) XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
+        if (eckey == NULL) {
+            XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return MEMORY_E;
+        }
+
+        if (wc_ecc_init(eckey) != 0) {
+            WOLFSSL_MSG("wc_ecc_init failure");
+            wc_ecc_free(eckey);
+            XFREE(eckey, NULL, DYNAMIC_TYPE_ECC);
+            XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return MEMORY_E;
+        }
+
+        idx = 0;
+        ret = wc_EccPublicKeyDecode(der, &idx, eckey, derSz);
+        if (ret != 0) {
+            WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
+            XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            wc_ecc_free(eckey);
+            return PUBLIC_KEY_E;
+        }
+#else
+        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return PUBLIC_KEY_E;
+#endif /* HAVE_ECC */
+    }
+
+    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    ret = wc_SetSubjectKeyIdFromPublicKey(cert, rsakey, eckey);
+
+    wc_FreeRsaKey(rsakey);
+    XFREE(rsakey, NULL, DYNAMIC_TYPE_RSA);
+#ifdef HAVE_ECC
+    wc_ecc_free(eckey);
+    XFREE(eckey, NULL, DYNAMIC_TYPE_ECC);
+#endif
+    return ret;
+}
+
+#endif /* NO_FILESYSTEM */
+
+/* Set AKID from certificate contains in buffer (DER encoded) */
+int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz)
+{
+    int ret;
+
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* decoded;
+#else
+    DecodedCert decoded[1];
+#endif
+
+    if (cert == NULL || der == NULL || derSz <= 0)
+        return BAD_FUNC_ARG;
+
+#ifdef WOLFSSL_SMALL_STACK
+    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
+                                    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (decoded == NULL)
+        return MEMORY_E;
+#endif
+
+    /* decode certificate and get SKID that will be AKID of current cert */
+    InitDecodedCert(decoded, (byte*)der, derSz, 0);
+    ret = ParseCert(decoded, CERT_TYPE, NO_VERIFY, 0);
+    if (ret != 0) {
+        FreeDecodedCert(decoded);
+        return ret;
+    }
+
+    /* Subject Key Id not found !! */
+    if (decoded->extSubjKeyIdSet == 0) {
+        FreeDecodedCert(decoded);
+        return ASN_NO_SKID;
+    }
+
+    /* SKID invalid size */
+    if (sizeof(cert->akid) < sizeof(decoded->extSubjKeyId)) {
+        FreeDecodedCert(decoded);
+        return MEMORY_E;
+    }
+
+    /* Put the SKID of CA to AKID of certificate */
+    XMEMCPY(cert->akid, decoded->extSubjKeyId, KEYID_SIZE);
+    cert->akidSz = KEYID_SIZE;
+
+    FreeDecodedCert(decoded);
+    return 0;
+}
+
+
+#ifndef NO_FILESYSTEM
+
+/* Set AKID from certificate file in PEM */
+int wc_SetAuthKeyId(Cert *cert, const char* file)
+{
+    int         ret;
+    int         derSz;
+    byte*       der;
+
+    if (cert == NULL || file == NULL)
+        return BAD_FUNC_ARG;
+
+    der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
+    if (der == NULL) {
+        WOLFSSL_MSG("wc_SetAuthKeyId OOF Problem");
+        return MEMORY_E;
+    }
+
+    derSz = wolfSSL_PemCertToDer(file, der, EIGHTK_BUF);
+    if (derSz <= 0)
+    {
+        XFREE(der, NULL, DYNAMIC_TYPE_CERT);
+        return derSz;
+    }
+
+    ret = wc_SetAuthKeyIdFromCert(cert, der, derSz);
+    XFREE(der, NULL, DYNAMIC_TYPE_CERT);
+
+    return ret;
+}
+
+#endif /* NO_FILESYSTEM */
+
+/* Set KeyUsage from human readale string */
+int wc_SetKeyUsage(Cert *cert, const char *value)
+{
+    char *token, *str, *ptr;
+    word32 len;
+
+    if (cert == NULL || value == NULL)
+        return BAD_FUNC_ARG;
+
+    cert->keyUsage = 0;
+
+    str = (char *)XMALLOC(XSTRLEN(value)+1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (str == NULL)
+        return MEMORY_E;
+
+    XMEMSET(str, 0, XSTRLEN(value)+1);
+    XSTRNCPY(str, value, XSTRLEN(value));
+
+    /* parse value, and set corresponding Key Usage value */
+    token = XSTRTOK(str, ",", &ptr);
+    while (token != NULL)
+    {
+        len = (word32)XSTRLEN(token);
+
+        if (!XSTRNCASECMP(token, "digitalSignature", len))
+            cert->keyUsage |= KEYUSE_DIGITAL_SIG;
+        else if (!XSTRNCASECMP(token, "nonRepudiation", len) ||
+                 !XSTRNCASECMP(token, "contentCommitment", len))
+            cert->keyUsage |= KEYUSE_CONTENT_COMMIT;
+        else if (!XSTRNCASECMP(token, "keyEncipherment", len))
+            cert->keyUsage |= KEYUSE_KEY_ENCIPHER;
+        else if (!XSTRNCASECMP(token, "dataEncipherment", len))
+            cert->keyUsage |= KEYUSE_DATA_ENCIPHER;
+        else if (!XSTRNCASECMP(token, "keyAgreement", len))
+            cert->keyUsage |= KEYUSE_KEY_AGREE;
+        else if (!XSTRNCASECMP(token, "keyCertSign", len))
+            cert->keyUsage |= KEYUSE_KEY_CERT_SIGN;
+        else if (!XSTRNCASECMP(token, "cRLSign", len))
+            cert->keyUsage |= KEYUSE_CRL_SIGN;
+        else if (!XSTRNCASECMP(token, "encipherOnly", len))
+            cert->keyUsage |= KEYUSE_ENCIPHER_ONLY;
+        else if (!XSTRNCASECMP(token, "decipherOnly", len))
+            cert->keyUsage |= KEYUSE_DECIPHER_ONLY;
+        else
+            return KEYUSAGE_E;
+
+        token = XSTRTOK(NULL, ",", &ptr);
+    }
+
+    XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    return 0;
+}
+#endif /* WOLFSSL_CERT_EXT */
+
+
+#ifdef WOLFSSL_ALT_NAMES
+
+/* Set Alt Names from der cert, return 0 on success */
+static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
+{
+    int ret;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* decoded;
+#else
+    DecodedCert decoded[1];
+#endif
+
+    if (derSz < 0)
+        return derSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (decoded == NULL)
+        return MEMORY_E;
+#endif
+
+    InitDecodedCert(decoded, (byte*)der, derSz, 0);
+    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
+
+    if (ret < 0) {
+        WOLFSSL_MSG("ParseCertRelative error");
+    }
+    else if (decoded->extensions) {
+        byte   b;
+        int    length;
+        word32 maxExtensionsIdx;
+
+        decoded->srcIdx = decoded->extensionsIdx;
+        b = decoded->source[decoded->srcIdx++];
+
+        if (b != ASN_EXTENSIONS) {
+            ret = ASN_PARSE_E;
+        }
+        else if (GetLength(decoded->source, &decoded->srcIdx, &length,
+                                                         decoded->maxIdx) < 0) {
+            ret = ASN_PARSE_E;
+        }
+        else if (GetSequence(decoded->source, &decoded->srcIdx, &length,
+                                                         decoded->maxIdx) < 0) {
+            ret = ASN_PARSE_E;
+        }
+        else {
+            maxExtensionsIdx = decoded->srcIdx + length;
+
+            while (decoded->srcIdx < maxExtensionsIdx) {
+                word32 oid;
+                word32 startIdx = decoded->srcIdx;
+                word32 tmpIdx;
+
+                if (GetSequence(decoded->source, &decoded->srcIdx, &length,
+                            decoded->maxIdx) < 0) {
+                    ret = ASN_PARSE_E;
+                    break;
+                }
+
+                tmpIdx = decoded->srcIdx;
+                decoded->srcIdx = startIdx;
+
+                if (GetAlgoId(decoded->source, &decoded->srcIdx, &oid,
+                              decoded->maxIdx) < 0) {
+                    ret = ASN_PARSE_E;
+                    break;
+                }
+
+                if (oid == ALT_NAMES_OID) {
+                    cert->altNamesSz = length + (tmpIdx - startIdx);
+
+                    if (cert->altNamesSz < (int)sizeof(cert->altNames))
+                        XMEMCPY(cert->altNames, &decoded->source[startIdx],
+                                cert->altNamesSz);
+                    else {
+                        cert->altNamesSz = 0;
+                        WOLFSSL_MSG("AltNames extensions too big");
+                        ret = ALT_NAME_E;
+                        break;
+                    }
+                }
+                decoded->srcIdx = tmpIdx + length;
+            }
+        }
+    }
+
+    FreeDecodedCert(decoded);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret < 0 ? ret : 0;
+}
+
+
+/* Set Dates from der cert, return 0 on success */
+static int SetDatesFromCert(Cert* cert, const byte* der, int derSz)
+{
+    int ret;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* decoded;
+#else
+    DecodedCert decoded[1];
+#endif
+
+    WOLFSSL_ENTER("SetDatesFromCert");
+    if (derSz < 0)
+        return derSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (decoded == NULL)
+        return MEMORY_E;
+#endif
+
+    InitDecodedCert(decoded, (byte*)der, derSz, 0);
+    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
+
+    if (ret < 0) {
+        WOLFSSL_MSG("ParseCertRelative error");
+    }
+    else if (decoded->beforeDate == NULL || decoded->afterDate == NULL) {
+        WOLFSSL_MSG("Couldn't extract dates");
+        ret = -1;
+    }
+    else if (decoded->beforeDateLen > MAX_DATE_SIZE ||
+                                        decoded->afterDateLen > MAX_DATE_SIZE) {
+        WOLFSSL_MSG("Bad date size");
+        ret = -1;
+    }
+    else {
+        XMEMCPY(cert->beforeDate, decoded->beforeDate, decoded->beforeDateLen);
+        XMEMCPY(cert->afterDate,  decoded->afterDate,  decoded->afterDateLen);
+
+        cert->beforeDateSz = decoded->beforeDateLen;
+        cert->afterDateSz  = decoded->afterDateLen;
+    }
+
+    FreeDecodedCert(decoded);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret < 0 ? ret : 0;
+}
+
+
+#endif /* WOLFSSL_ALT_NAMES && !NO_RSA */
+
+
+/* Set cn name from der buffer, return 0 on success */
+static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
+{
+    int ret, sz;
+#ifdef WOLFSSL_SMALL_STACK
+    DecodedCert* decoded;
+#else
+    DecodedCert decoded[1];
+#endif
+
+    if (derSz < 0)
+        return derSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+    if (decoded == NULL)
+        return MEMORY_E;
+#endif
+
+    InitDecodedCert(decoded, (byte*)der, derSz, 0);
+    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
+
+    if (ret < 0) {
+        WOLFSSL_MSG("ParseCertRelative error");
+    }
+    else {
+        if (decoded->subjectCN) {
+            sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen
+                                                         : CTC_NAME_SIZE - 1;
+            strncpy(cn->commonName, decoded->subjectCN, CTC_NAME_SIZE);
+            cn->commonName[sz] = 0;
+            cn->commonNameEnc = decoded->subjectCNEnc;
+        }
+        if (decoded->subjectC) {
+            sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen
+                                                        : CTC_NAME_SIZE - 1;
+            strncpy(cn->country, decoded->subjectC, CTC_NAME_SIZE);
+            cn->country[sz] = 0;
+            cn->countryEnc = decoded->subjectCEnc;
+        }
+        if (decoded->subjectST) {
+            sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen
+                                                         : CTC_NAME_SIZE - 1;
+            strncpy(cn->state, decoded->subjectST, CTC_NAME_SIZE);
+            cn->state[sz] = 0;
+            cn->stateEnc = decoded->subjectSTEnc;
+        }
+        if (decoded->subjectL) {
+            sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen
+                                                        : CTC_NAME_SIZE - 1;
+            strncpy(cn->locality, decoded->subjectL, CTC_NAME_SIZE);
+            cn->locality[sz] = 0;
+            cn->localityEnc = decoded->subjectLEnc;
+        }
+        if (decoded->subjectO) {
+            sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen
+                                                        : CTC_NAME_SIZE - 1;
+            strncpy(cn->org, decoded->subjectO, CTC_NAME_SIZE);
+            cn->org[sz] = 0;
+            cn->orgEnc = decoded->subjectOEnc;
+        }
+        if (decoded->subjectOU) {
+            sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen
+                                                         : CTC_NAME_SIZE - 1;
+            strncpy(cn->unit, decoded->subjectOU, CTC_NAME_SIZE);
+            cn->unit[sz] = 0;
+            cn->unitEnc = decoded->subjectOUEnc;
+        }
+        if (decoded->subjectSN) {
+            sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen
+                                                         : CTC_NAME_SIZE - 1;
+            strncpy(cn->sur, decoded->subjectSN, CTC_NAME_SIZE);
+            cn->sur[sz] = 0;
+            cn->surEnc = decoded->subjectSNEnc;
+        }
+        if (decoded->subjectEmail) {
+            sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
+               ?  decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
+            strncpy(cn->email, decoded->subjectEmail, CTC_NAME_SIZE);
+            cn->email[sz] = 0;
+        }
+    }
+
+    FreeDecodedCert(decoded);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret < 0 ? ret : 0;
+}
+
+
+#ifndef NO_FILESYSTEM
+
+/* Set cert issuer from issuerFile in PEM */
+int wc_SetIssuer(Cert* cert, const char* issuerFile)
+{
+    int         ret;
+    int         derSz;
+    byte*       der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
+
+    if (der == NULL) {
+        WOLFSSL_MSG("wc_SetIssuer OOF Problem");
+        return MEMORY_E;
+    }
+    derSz = wolfSSL_PemCertToDer(issuerFile, der, EIGHTK_BUF);
+    cert->selfSigned = 0;
+    ret = SetNameFromCert(&cert->issuer, der, derSz);
+    XFREE(der, NULL, DYNAMIC_TYPE_CERT);
+
+    return ret;
+}
+
+
+/* Set cert subject from subjectFile in PEM */
+int wc_SetSubject(Cert* cert, const char* subjectFile)
+{
+    int         ret;
+    int         derSz;
+    byte*       der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
+
+    if (der == NULL) {
+        WOLFSSL_MSG("wc_SetSubject OOF Problem");
+        return MEMORY_E;
+    }
+    derSz = wolfSSL_PemCertToDer(subjectFile, der, EIGHTK_BUF);
+    ret = SetNameFromCert(&cert->subject, der, derSz);
+    XFREE(der, NULL, DYNAMIC_TYPE_CERT);
+
+    return ret;
+}
+
+
+#ifdef WOLFSSL_ALT_NAMES
+
+/* Set atl names from file in PEM */
+int wc_SetAltNames(Cert* cert, const char* file)
+{
+    int         ret;
+    int         derSz;
+    byte*       der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
+
+    if (der == NULL) {
+        WOLFSSL_MSG("wc_SetAltNames OOF Problem");
+        return MEMORY_E;
+    }
+    derSz = wolfSSL_PemCertToDer(file, der, EIGHTK_BUF);
+    ret = SetAltNamesFromCert(cert, der, derSz);
+    XFREE(der, NULL, DYNAMIC_TYPE_CERT);
+
+    return ret;
+}
+
+#endif /* WOLFSSL_ALT_NAMES */
+
+#endif /* NO_FILESYSTEM */
+
+/* Set cert issuer from DER buffer */
+int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
+{
+    cert->selfSigned = 0;
+    return SetNameFromCert(&cert->issuer, der, derSz);
+}
+
+
+/* Set cert subject from DER buffer */
+int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
+{
+    return SetNameFromCert(&cert->subject, der, derSz);
+}
+
+
+#ifdef WOLFSSL_ALT_NAMES
+
+/* Set cert alt names from DER buffer */
+int wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
+{
+    return SetAltNamesFromCert(cert, der, derSz);
+}
+
+/* Set cert dates from DER buffer */
+int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz)
+{
+    return SetDatesFromCert(cert, der, derSz);
+}
+
+#endif /* WOLFSSL_ALT_NAMES */
+
+#endif /* WOLFSSL_CERT_GEN */
+
+
+#ifdef HAVE_ECC
+
+/* Der Encode r & s ints into out, outLen is (in/out) size */
+int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
+{
+    word32 idx = 0;
+    word32 rSz;                           /* encoding size */
+    word32 sSz;
+    word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
+
+    /* If the leading bit on the INTEGER is a 1, add a leading zero */
+    int rLeadingZero = mp_leading_bit(r);
+    int sLeadingZero = mp_leading_bit(s);
+    int rLen = mp_unsigned_bin_size(r);   /* big int size */
+    int sLen = mp_unsigned_bin_size(s);
+    int err;
+
+    if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero +
+                   headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
+        return BAD_FUNC_ARG;
+
+    idx = SetSequence(rLen+rLeadingZero+sLen+sLeadingZero+headerSz, out);
+
+    /* store r */
+    out[idx++] = ASN_INTEGER;
+    rSz = SetLength(rLen + rLeadingZero, &out[idx]);
+    idx += rSz;
+    if (rLeadingZero)
+        out[idx++] = 0;
+    err = mp_to_unsigned_bin(r, &out[idx]);
+    if (err != MP_OKAY) return err;
+    idx += rLen;
+
+    /* store s */
+    out[idx++] = ASN_INTEGER;
+    sSz = SetLength(sLen + sLeadingZero, &out[idx]);
+    idx += sSz;
+    if (sLeadingZero)
+        out[idx++] = 0;
+    err = mp_to_unsigned_bin(s, &out[idx]);
+    if (err != MP_OKAY) return err;
+    idx += sLen;
+
+    *outLen = idx;
+
+    return 0;
+}
+
+
+/* Der Decode ECC-DSA Signautre, r & s stored as big ints */
+int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
+{
+    word32 idx = 0;
+    int    len = 0;
+
+    if (GetSequence(sig, &idx, &len, sigLen) < 0)
+        return ASN_ECC_KEY_E;
+
+    if ((word32)len > (sigLen - idx))
+        return ASN_ECC_KEY_E;
+
+    if (GetInt(r, sig, &idx, sigLen) < 0)
+        return ASN_ECC_KEY_E;
+
+    if (GetInt(s, sig, &idx, sigLen) < 0)
+        return ASN_ECC_KEY_E;
+
+    return 0;
+}
+
+
+int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
+                        word32 inSz)
+{
+    word32 oid = 0;
+    int    version, length;
+    int    privSz, pubSz;
+    byte   b;
+    int    ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* priv;
+    byte* pub;
+#else
+    byte priv[ECC_MAXSIZE+1];
+    byte pub[2*(ECC_MAXSIZE+1)]; /* public key has two parts plus header */
+#endif
+
+    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
+        return BAD_FUNC_ARG;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetMyVersion(input, inOutIdx, &version) < 0)
+        return ASN_PARSE_E;
+
+    b = input[*inOutIdx];
+    *inOutIdx += 1;
+
+    /* priv type */
+    if (b != 4 && b != 6 && b != 7)
+        return ASN_PARSE_E;
+
+    if (GetLength(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+    if (length > ECC_MAXSIZE)
+        return BUFFER_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+    priv = (byte*)XMALLOC(ECC_MAXSIZE+1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (priv == NULL)
+        return MEMORY_E;
+
+    pub = (byte*)XMALLOC(2*(ECC_MAXSIZE+1), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pub == NULL) {
+        XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    /* priv key */
+    privSz = length;
+    XMEMCPY(priv, &input[*inOutIdx], privSz);
+    *inOutIdx += length;
+
+    /* prefix 0, may have */
+    b = input[*inOutIdx];
+    if (b == ECC_PREFIX_0) {
+        *inOutIdx += 1;
+
+        if (GetLength(input, inOutIdx, &length, inSz) < 0)
+            ret = ASN_PARSE_E;
+        else {
+            /* object id */
+            b = input[*inOutIdx];
+            *inOutIdx += 1;
+
+            if (b != ASN_OBJECT_ID) {
+                ret = ASN_OBJECT_ID_E;
+            }
+            else if (GetLength(input, inOutIdx, &length, inSz) < 0) {
+                ret = ASN_PARSE_E;
+            }
+            else {
+                while(length--) {
+                    oid += input[*inOutIdx];
+                    *inOutIdx += 1;
+                }
+                if (CheckCurve(oid) < 0)
+                    ret = ECC_CURVE_OID_E;
+            }
+        }
+    }
+
+    if (ret == 0) {
+        /* prefix 1 */
+        b = input[*inOutIdx];
+        *inOutIdx += 1;
+
+        if (b != ECC_PREFIX_1) {
+            ret = ASN_ECC_KEY_E;
+        }
+        else if (GetLength(input, inOutIdx, &length, inSz) < 0) {
+            ret = ASN_PARSE_E;
+        }
+        else {
+            /* key header */
+            b = input[*inOutIdx];
+            *inOutIdx += 1;
+
+            if (b != ASN_BIT_STRING) {
+                ret = ASN_BITSTR_E;
+            }
+            else if (GetLength(input, inOutIdx, &length, inSz) < 0) {
+                ret = ASN_PARSE_E;
+            }
+            else if (length <= 0) {
+                /* pubkey needs some size */
+                ret = ASN_INPUT_E;
+            }
+            else {
+                b = input[*inOutIdx];
+                *inOutIdx += 1;
+
+                if (b != 0x00) {
+                    ret = ASN_EXPECT_0_E;
+                }
+                else {
+                    /* pub key */
+                    pubSz = length - 1;  /* null prefix */
+                    if (pubSz < 2*(ECC_MAXSIZE+1)) {
+                        XMEMCPY(pub, &input[*inOutIdx], pubSz);
+                        *inOutIdx += length;
+                        ret = wc_ecc_import_private_key(priv, privSz, pub, pubSz,
+                                                     key);
+                    } else
+                        ret = BUFFER_E;
+                }
+            }
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(pub,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
+                          ecc_key* key, word32 inSz)
+{
+    int    length;
+    int    ret = 0;
+
+    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
+        return BAD_FUNC_ARG;
+
+    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+        return ASN_PARSE_E;
+
+#if defined(OPENSSL_EXTRA) || defined(ECC_DECODE_EXTRA)
+    {
+        byte b = input[*inOutIdx];
+        if (b != ASN_INTEGER) {
+            /* not from decoded cert, will have algo id, skip past */
+            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
+                return ASN_PARSE_E;
+
+            b = input[(*inOutIdx)++];
+            if (b != ASN_OBJECT_ID)
+                return ASN_OBJECT_ID_E;
+
+            if (GetLength(input, inOutIdx, &length, inSz) < 0)
+                return ASN_PARSE_E;
+
+            *inOutIdx += length;   /* skip past */
+
+            /* ecc params information */
+            b = input[(*inOutIdx)++];
+            if (b != ASN_OBJECT_ID)
+                return ASN_OBJECT_ID_E;
+
+            if (GetLength(input, inOutIdx, &length, inSz) < 0)
+                return ASN_PARSE_E;
+
+            *inOutIdx += length;   /* skip past */
+
+            /* key header */
+            b = input[*inOutIdx];
+            *inOutIdx += 1;
+
+            if (b != ASN_BIT_STRING)
+                ret = ASN_BITSTR_E;
+            else if (GetLength(input, inOutIdx, &length, inSz) < 0)
+                ret = ASN_PARSE_E;
+            else {
+                b = input[*inOutIdx];
+                *inOutIdx += 1;
+
+                if (b != 0x00)
+                    ret = ASN_EXPECT_0_E;
+            }
+        }
+    }  /* openssl var block */
+#endif /* OPENSSL_EXTRA */
+
+    if (wc_ecc_import_x963(input+*inOutIdx, inSz - *inOutIdx, key) != 0)
+        return ASN_ECC_KEY_E;
+
+    return ret;
+}
+
+
+#ifdef WOLFSSL_KEY_GEN
+
+/* Write a Private ecc key to DER format, length on success else < 0 */
+int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
+{
+    byte   curve[MAX_ALGO_SZ+2];
+    byte   ver[MAX_VERSION_SZ];
+    byte   seq[MAX_SEQ_SZ];
+    byte   *prv, *pub;
+    int    ret, totalSz, curveSz, verSz;
+    int    privHdrSz  = ASN_ECC_HEADER_SZ;
+    int    pubHdrSz   = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;
+
+    word32 idx = 0, prvidx = 0, pubidx = 0, curveidx = 0;
+    word32 seqSz, privSz, pubSz = ECC_BUFSIZE;
+
+    if (key == NULL || output == NULL || inLen == 0)
+        return BAD_FUNC_ARG;
+
+    /* curve */
+    curve[curveidx++] = ECC_PREFIX_0;
+    curveidx++ /* to put the size after computation */;
+    curveSz = SetCurve(key, curve+curveidx);
+    if (curveSz < 0)
+        return curveSz;
+    /* set computed size */
+    curve[1] = (byte)curveSz;
+    curveidx += curveSz;
+
+    /* private */
+    privSz = key->dp->size;
+    prv = (byte*)XMALLOC(privSz + privHdrSz + MAX_SEQ_SZ,
+                         NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (prv == NULL) {
+        return MEMORY_E;
+    }
+    prv[prvidx++] = ASN_OCTET_STRING;
+    prv[prvidx++] = (byte)key->dp->size;
+    ret = wc_ecc_export_private_only(key, prv + prvidx, &privSz);
+    if (ret < 0) {
+        XFREE(prv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+    prvidx += privSz;
+
+    /* public */
+    ret = wc_ecc_export_x963(key, NULL, &pubSz);
+    if (ret != LENGTH_ONLY_E) {
+        XFREE(prv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+
+    pub = (byte*)XMALLOC(pubSz + pubHdrSz + MAX_SEQ_SZ,
+                         NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (pub == NULL) {
+        XFREE(prv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+
+    pub[pubidx++] = ECC_PREFIX_1;
+    if (pubSz > 128) /* leading zero + extra size byte */
+        pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx);
+    else /* leading zero */
+        pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx);
+    pub[pubidx++] = ASN_BIT_STRING;
+    pubidx += SetLength(pubSz + 1, pub+pubidx);
+    pub[pubidx++] = (byte)0; /* leading zero */
+    ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz);
+    if (ret != 0) {
+        XFREE(prv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    }
+    pubidx += pubSz;
+
+    /* make headers */
+    verSz = SetMyVersion(1, ver, FALSE);
+    seqSz = SetSequence(verSz + prvidx + pubidx + curveidx, seq);
+
+    totalSz = prvidx + pubidx + curveidx + verSz + seqSz;
+    if (totalSz > (int)inLen) {
+        XFREE(prv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return BAD_FUNC_ARG;
+    }
+
+    /* write out */
+    /* seq */
+    XMEMCPY(output + idx, seq, seqSz);
+    idx = seqSz;
+
+    /* ver */
+    XMEMCPY(output + idx, ver, verSz);
+    idx += verSz;
+
+    /* private */
+    XMEMCPY(output + idx, prv, prvidx);
+    idx += prvidx;
+    XFREE(prv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    /* curve */
+    XMEMCPY(output + idx, curve, curveidx);
+    idx += curveidx;
+
+    /* public */
+    XMEMCPY(output + idx, pub, pubidx);
+    /* idx += pubidx;  not used after write, if more data remove comment */
+    XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    return totalSz;
+}
+
+#endif /* WOLFSSL_KEY_GEN */
+
+#endif  /* HAVE_ECC */
+
+
+#if defined(HAVE_OCSP) || defined(HAVE_CRL)
+
+/* Get raw Date only, no processing, 0 on success */
+static int GetBasicDate(const byte* source, word32* idx, byte* date,
+                        byte* format, int maxIdx)
+{
+    int    length;
+
+    WOLFSSL_ENTER("GetBasicDate");
+
+    *format = source[*idx];
+    *idx += 1;
+    if (*format != ASN_UTC_TIME && *format != ASN_GENERALIZED_TIME)
+        return ASN_TIME_E;
+
+    if (GetLength(source, idx, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
+        return ASN_DATE_SZ_E;
+
+    XMEMCPY(date, &source[*idx], length);
+    *idx += length;
+
+    return 0;
+}
+
+#endif
+
+
+#ifdef HAVE_OCSP
+
+static int GetEnumerated(const byte* input, word32* inOutIdx, int *value)
+{
+    word32 idx = *inOutIdx;
+    word32 len;
+
+    WOLFSSL_ENTER("GetEnumerated");
+
+    *value = 0;
+
+    if (input[idx++] != ASN_ENUMERATED)
+        return ASN_PARSE_E;
+
+    len = input[idx++];
+    if (len > 4)
+        return ASN_PARSE_E;
+
+    while (len--) {
+        *value  = *value << 8 | input[idx++];
+    }
+
+    *inOutIdx = idx;
+
+    return *value;
+}
+
+
+static int DecodeSingleResponse(byte* source,
+                            word32* ioIndex, OcspResponse* resp, word32 size)
+{
+    word32 idx = *ioIndex, prevIndex, oid;
+    int length, wrapperSz;
+    CertStatus* cs = resp->status;
+
+    WOLFSSL_ENTER("DecodeSingleResponse");
+
+    /* Outer wrapper of the SEQUENCE OF Single Responses. */
+    if (GetSequence(source, &idx, &wrapperSz, size) < 0)
+        return ASN_PARSE_E;
+
+    prevIndex = idx;
+
+    /* When making a request, we only request one status on one certificate
+     * at a time. There should only be one SingleResponse */
+
+    /* Wrapper around the Single Response */
+    if (GetSequence(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+
+    /* Wrapper around the CertID */
+    if (GetSequence(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+    /* Skip the hash algorithm */
+    if (GetAlgoId(source, &idx, &oid, size) < 0)
+        return ASN_PARSE_E;
+    /* Save reference to the hash of CN */
+    if (source[idx++] != ASN_OCTET_STRING)
+        return ASN_PARSE_E;
+    if (GetLength(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+    resp->issuerHash = source + idx;
+    idx += length;
+    /* Save reference to the hash of the issuer public key */
+    if (source[idx++] != ASN_OCTET_STRING)
+        return ASN_PARSE_E;
+    if (GetLength(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+    resp->issuerKeyHash = source + idx;
+    idx += length;
+
+    /* Read the serial number, it is handled as a string, not as a
+     * proper number. Just XMEMCPY the data over, rather than load it
+     * as an mp_int. */
+    if (source[idx++] != ASN_INTEGER)
+        return ASN_PARSE_E;
+    if (GetLength(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+    if (length <= EXTERNAL_SERIAL_SIZE)
+    {
+        if (source[idx] == 0)
+        {
+            idx++;
+            length--;
+        }
+        XMEMCPY(cs->serial, source + idx, length);
+        cs->serialSz = length;
+    }
+    else
+    {
+        return ASN_GETINT_E;
+    }
+    idx += length;
+
+    /* CertStatus */
+    switch (source[idx++])
+    {
+        case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
+            cs->status = CERT_GOOD;
+            idx++;
+            break;
+        case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
+            cs->status = CERT_REVOKED;
+            if (GetLength(source, &idx, &length, size) < 0)
+                return ASN_PARSE_E;
+            idx += length;
+            break;
+        case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
+            cs->status = CERT_UNKNOWN;
+            idx++;
+            break;
+        default:
+            return ASN_PARSE_E;
+    }
+
+    if (GetBasicDate(source, &idx, cs->thisDate,
+                                                &cs->thisDateFormat, size) < 0)
+        return ASN_PARSE_E;
+    if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE))
+        return ASN_BEFORE_DATE_E;
+
+    /* The following items are optional. Only check for them if there is more
+     * unprocessed data in the singleResponse wrapper. */
+
+    if (((int)(idx - prevIndex) < wrapperSz) &&
+        (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)))
+    {
+        idx++;
+        if (GetLength(source, &idx, &length, size) < 0)
+            return ASN_PARSE_E;
+        if (GetBasicDate(source, &idx, cs->nextDate,
+                                                &cs->nextDateFormat, size) < 0)
+            return ASN_PARSE_E;
+    }
+    if (((int)(idx - prevIndex) < wrapperSz) &&
+        (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)))
+    {
+        idx++;
+        if (GetLength(source, &idx, &length, size) < 0)
+            return ASN_PARSE_E;
+        idx += length;
+    }
+
+    *ioIndex = idx;
+
+    return 0;
+}
+
+static int DecodeOcspRespExtensions(byte* source,
+                            word32* ioIndex, OcspResponse* resp, word32 sz)
+{
+    word32 idx = *ioIndex;
+    int length;
+    int ext_bound; /* boundary index for the sequence of extensions */
+    word32 oid;
+
+    WOLFSSL_ENTER("DecodeOcspRespExtensions");
+
+    if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
+        return ASN_PARSE_E;
+
+    if (GetLength(source, &idx, &length, sz) < 0) return ASN_PARSE_E;
+
+    if (GetSequence(source, &idx, &length, sz) < 0) return ASN_PARSE_E;
+
+    ext_bound = idx + length;
+
+    while (idx < (word32)ext_bound) {
+        if (GetSequence(source, &idx, &length, sz) < 0) {
+            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
+            return ASN_PARSE_E;
+        }
+
+        oid = 0;
+        if (GetObjectId(source, &idx, &oid, sz) < 0) {
+            WOLFSSL_MSG("\tfail: OBJECT ID");
+            return ASN_PARSE_E;
+        }
+
+        /* check for critical flag */
+        if (source[idx] == ASN_BOOLEAN) {
+            WOLFSSL_MSG("\tfound optional critical flag, moving past");
+            idx += (ASN_BOOL_SIZE + 1);
+        }
+
+        /* process the extension based on the OID */
+        if (source[idx++] != ASN_OCTET_STRING) {
+            WOLFSSL_MSG("\tfail: should be an OCTET STRING");
+            return ASN_PARSE_E;
+        }
+
+        if (GetLength(source, &idx, &length, sz) < 0) {
+            WOLFSSL_MSG("\tfail: extension data length");
+            return ASN_PARSE_E;
+        }
+
+        if (oid == OCSP_NONCE_OID) {
+            resp->nonce = source + idx;
+            resp->nonceSz = length;
+        }
+
+        idx += length;
+    }
+
+    *ioIndex = idx;
+    return 0;
+}
+
+
+static int DecodeResponseData(byte* source,
+                            word32* ioIndex, OcspResponse* resp, word32 size)
+{
+    word32 idx = *ioIndex, prev_idx;
+    int length;
+    int version;
+    word32 responderId = 0;
+
+    WOLFSSL_ENTER("DecodeResponseData");
+
+    resp->response = source + idx;
+    prev_idx = idx;
+    if (GetSequence(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+    resp->responseSz = length + idx - prev_idx;
+
+    /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
+     * item isn't an EXPLICIT[0], then set version to zero and move
+     * onto the next item.
+     */
+    if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
+    {
+        idx += 2; /* Eat the value and length */
+        if (GetMyVersion(source, &idx, &version) < 0)
+            return ASN_PARSE_E;
+    } else
+        version = 0;
+
+    responderId = source[idx++];
+    if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) ||
+        (responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)))
+    {
+        if (GetLength(source, &idx, &length, size) < 0)
+            return ASN_PARSE_E;
+        idx += length;
+    }
+    else
+        return ASN_PARSE_E;
+
+    /* save pointer to the producedAt time */
+    if (GetBasicDate(source, &idx, resp->producedDate,
+                                        &resp->producedDateFormat, size) < 0)
+        return ASN_PARSE_E;
+
+    if (DecodeSingleResponse(source, &idx, resp, size) < 0)
+        return ASN_PARSE_E;
+
+    if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
+        return ASN_PARSE_E;
+
+    *ioIndex = idx;
+    return 0;
+}
+
+
+static int DecodeCerts(byte* source,
+                            word32* ioIndex, OcspResponse* resp, word32 size)
+{
+    word32 idx = *ioIndex;
+
+    WOLFSSL_ENTER("DecodeCerts");
+
+    if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
+    {
+        int length;
+
+        if (GetLength(source, &idx, &length, size) < 0)
+            return ASN_PARSE_E;
+
+        if (GetSequence(source, &idx, &length, size) < 0)
+            return ASN_PARSE_E;
+
+        resp->cert = source + idx;
+        resp->certSz = length;
+
+        idx += length;
+    }
+    *ioIndex = idx;
+    return 0;
+}
+
+static int DecodeBasicOcspResponse(byte* source,
+                            word32* ioIndex, OcspResponse* resp, word32 size)
+{
+    int length;
+    word32 idx = *ioIndex;
+    word32 end_index;
+
+    WOLFSSL_ENTER("DecodeBasicOcspResponse");
+
+    if (GetSequence(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+
+    if (idx + length > size)
+        return ASN_INPUT_E;
+    end_index = idx + length;
+
+    if (DecodeResponseData(source, &idx, resp, size) < 0)
+        return ASN_PARSE_E;
+
+    /* Get the signature algorithm */
+    if (GetAlgoId(source, &idx, &resp->sigOID, size) < 0)
+        return ASN_PARSE_E;
+
+    /* Obtain pointer to the start of the signature, and save the size */
+    if (source[idx++] == ASN_BIT_STRING)
+    {
+        int sigLength = 0;
+        if (GetLength(source, &idx, &sigLength, size) < 0)
+            return ASN_PARSE_E;
+        resp->sigSz = sigLength;
+        resp->sig = source + idx;
+        idx += sigLength;
+    }
+
+    /*
+     * Check the length of the BasicOcspResponse against the current index to
+     * see if there are certificates, they are optional.
+     */
+    if (idx < end_index)
+    {
+        DecodedCert cert;
+        int ret;
+
+        if (DecodeCerts(source, &idx, resp, size) < 0)
+            return ASN_PARSE_E;
+
+        InitDecodedCert(&cert, resp->cert, resp->certSz, 0);
+        ret = ParseCertRelative(&cert, CA_TYPE, NO_VERIFY, 0);
+        if (ret < 0)
+            return ret;
+
+        ret = ConfirmSignature(resp->response, resp->responseSz,
+                            cert.publicKey, cert.pubKeySize, cert.keyOID,
+                            resp->sig, resp->sigSz, resp->sigOID, NULL);
+        FreeDecodedCert(&cert);
+
+        if (ret == 0)
+        {
+            WOLFSSL_MSG("\tOCSP Confirm signature failed");
+            return ASN_OCSP_CONFIRM_E;
+        }
+    }
+
+    *ioIndex = idx;
+    return 0;
+}
+
+
+void InitOcspResponse(OcspResponse* resp, CertStatus* status,
+                                                    byte* source, word32 inSz)
+{
+    WOLFSSL_ENTER("InitOcspResponse");
+
+    resp->responseStatus = -1;
+    resp->response = NULL;
+    resp->responseSz = 0;
+    resp->producedDateFormat = 0;
+    resp->issuerHash = NULL;
+    resp->issuerKeyHash = NULL;
+    resp->sig = NULL;
+    resp->sigSz = 0;
+    resp->sigOID = 0;
+    resp->status = status;
+    resp->nonce = NULL;
+    resp->nonceSz = 0;
+    resp->source = source;
+    resp->maxIdx = inSz;
+}
+
+
+int OcspResponseDecode(OcspResponse* resp)
+{
+    int length = 0;
+    word32 idx = 0;
+    byte* source = resp->source;
+    word32 size = resp->maxIdx;
+    word32 oid;
+
+    WOLFSSL_ENTER("OcspResponseDecode");
+
+    /* peel the outer SEQUENCE wrapper */
+    if (GetSequence(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+
+    /* First get the responseStatus, an ENUMERATED */
+    if (GetEnumerated(source, &idx, &resp->responseStatus) < 0)
+        return ASN_PARSE_E;
+
+    if (resp->responseStatus != OCSP_SUCCESSFUL)
+        return 0;
+
+    /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
+    if (idx >= size)
+        return ASN_INPUT_E;
+    if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
+        return ASN_PARSE_E;
+    if (GetLength(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+
+    /* Get the responseBytes SEQUENCE */
+    if (GetSequence(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+
+    /* Check ObjectID for the resposeBytes */
+    if (GetObjectId(source, &idx, &oid, size) < 0)
+        return ASN_PARSE_E;
+    if (oid != OCSP_BASIC_OID)
+        return ASN_PARSE_E;
+    if (source[idx++] != ASN_OCTET_STRING)
+        return ASN_PARSE_E;
+
+    if (GetLength(source, &idx, &length, size) < 0)
+        return ASN_PARSE_E;
+
+    if (DecodeBasicOcspResponse(source, &idx, resp, size) < 0)
+        return ASN_PARSE_E;
+
+    return 0;
+}
+
+
+static word32 SetOcspReqExtensions(word32 extSz, byte* output,
+                                            const byte* nonce, word32 nonceSz)
+{
+    static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+                                       0x30, 0x01, 0x02 };
+    byte seqArray[5][MAX_SEQ_SZ];
+    word32 seqSz[5], totalSz;
+
+    WOLFSSL_ENTER("SetOcspReqExtensions");
+
+    if (nonce == NULL || nonceSz == 0) return 0;
+
+    seqArray[0][0] = ASN_OCTET_STRING;
+    seqSz[0] = 1 + SetLength(nonceSz, &seqArray[0][1]);
+
+    seqArray[1][0] = ASN_OBJECT_ID;
+    seqSz[1] = 1 + SetLength(sizeof(NonceObjId), &seqArray[1][1]);
+
+    totalSz = seqSz[0] + seqSz[1] + nonceSz + (word32)sizeof(NonceObjId);
+
+    seqSz[2] = SetSequence(totalSz, seqArray[2]);
+    totalSz += seqSz[2];
+
+    seqSz[3] = SetSequence(totalSz, seqArray[3]);
+    totalSz += seqSz[3];
+
+    seqArray[4][0] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2);
+    seqSz[4] = 1 + SetLength(totalSz, &seqArray[4][1]);
+    totalSz += seqSz[4];
+
+    if (totalSz < extSz)
+    {
+        totalSz = 0;
+        XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
+        totalSz += seqSz[4];
+        XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
+        totalSz += seqSz[3];
+        XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
+        totalSz += seqSz[2];
+        XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
+        totalSz += seqSz[1];
+        XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
+        totalSz += (word32)sizeof(NonceObjId);
+        XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
+        totalSz += seqSz[0];
+        XMEMCPY(output + totalSz, nonce, nonceSz);
+        totalSz += nonceSz;
+    }
+
+    return totalSz;
+}
+
+
+int EncodeOcspRequest(OcspRequest* req)
+{
+    byte seqArray[5][MAX_SEQ_SZ];
+    /* The ASN.1 of the OCSP Request is an onion of sequences */
+    byte algoArray[MAX_ALGO_SZ];
+    byte issuerArray[MAX_ENCODED_DIG_SZ];
+    byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
+    byte snArray[MAX_SN_SZ];
+    byte extArray[MAX_OCSP_EXT_SZ];
+    byte* output = req->dest;
+    word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz;
+    int i;
+
+    WOLFSSL_ENTER("EncodeOcspRequest");
+
+#ifdef NO_SHA
+    algoSz = SetAlgoID(SHA256h, algoArray, hashType, 0);
+#else
+    algoSz = SetAlgoID(SHAh, algoArray, hashType, 0);
+#endif
+
+    req->issuerHash = req->cert->issuerHash;
+    issuerSz = SetDigest(req->cert->issuerHash, KEYID_SIZE, issuerArray);
+
+    req->issuerKeyHash = req->cert->issuerKeyHash;
+    issuerKeySz = SetDigest(req->cert->issuerKeyHash,
+                                                    KEYID_SIZE, issuerKeyArray);
+
+    req->serial = req->cert->serial;
+    req->serialSz = req->cert->serialSz;
+    snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray);
+
+    extSz = 0;
+    if (req->useNonce) {
+        WC_RNG rng;
+        if (wc_InitRng(&rng) != 0) {
+            WOLFSSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
+        } else {
+            if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)
+                WOLFSSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce.");
+            else {
+                req->nonceSz = MAX_OCSP_NONCE_SZ;
+                extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray,
+                                                      req->nonce, req->nonceSz);
+            }
+            wc_FreeRng(&rng);
+        }
+    }
+
+    totalSz = algoSz + issuerSz + issuerKeySz + snSz;
+
+    for (i = 4; i >= 0; i--) {
+        seqSz[i] = SetSequence(totalSz, seqArray[i]);
+        totalSz += seqSz[i];
+        if (i == 2) totalSz += extSz;
+    }
+    totalSz = 0;
+    for (i = 0; i < 5; i++) {
+        XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
+        totalSz += seqSz[i];
+    }
+    XMEMCPY(output + totalSz, algoArray, algoSz);
+    totalSz += algoSz;
+    XMEMCPY(output + totalSz, issuerArray, issuerSz);
+    totalSz += issuerSz;
+    XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
+    totalSz += issuerKeySz;
+    XMEMCPY(output + totalSz, snArray, snSz);
+    totalSz += snSz;
+    if (extSz != 0) {
+        XMEMCPY(output + totalSz, extArray, extSz);
+        totalSz += extSz;
+    }
+
+    return totalSz;
+}
+
+
+void InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
+                                                    byte* dest, word32 destSz)
+{
+    WOLFSSL_ENTER("InitOcspRequest");
+
+    req->cert = cert;
+    req->useNonce = useNonce;
+    req->nonceSz = 0;
+    req->issuerHash = NULL;
+    req->issuerKeyHash = NULL;
+    req->serial = NULL;
+    req->dest = dest;
+    req->destSz = destSz;
+}
+
+
+int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
+{
+    int cmp;
+
+    WOLFSSL_ENTER("CompareOcspReqResp");
+
+    if (req == NULL)
+    {
+        WOLFSSL_MSG("\tReq missing");
+        return -1;
+    }
+
+    if (resp == NULL)
+    {
+        WOLFSSL_MSG("\tResp missing");
+        return 1;
+    }
+
+    /* Nonces are not critical. The responder may not necessarily add
+     * the nonce to the response. */
+    if (req->useNonce && resp->nonceSz != 0) {
+        cmp = req->nonceSz - resp->nonceSz;
+        if (cmp != 0)
+        {
+            WOLFSSL_MSG("\tnonceSz mismatch");
+            return cmp;
+        }
+
+        cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);
+        if (cmp != 0)
+        {
+            WOLFSSL_MSG("\tnonce mismatch");
+            return cmp;
+        }
+    }
+
+    cmp = XMEMCMP(req->issuerHash, resp->issuerHash, KEYID_SIZE);
+    if (cmp != 0)
+    {
+        WOLFSSL_MSG("\tissuerHash mismatch");
+        return cmp;
+    }
+
+    cmp = XMEMCMP(req->issuerKeyHash, resp->issuerKeyHash, KEYID_SIZE);
+    if (cmp != 0)
+    {
+        WOLFSSL_MSG("\tissuerKeyHash mismatch");
+        return cmp;
+    }
+
+    cmp = req->serialSz - resp->status->serialSz;
+    if (cmp != 0)
+    {
+        WOLFSSL_MSG("\tserialSz mismatch");
+        return cmp;
+    }
+
+    cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz);
+    if (cmp != 0)
+    {
+        WOLFSSL_MSG("\tserial mismatch");
+        return cmp;
+    }
+
+    return 0;
+}
+
+#endif
+
+
+/* store SHA hash of NAME */
+WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
+                             int maxIdx)
+{
+    int    length;  /* length of all distinguished names */
+    int    ret;
+    word32 dummy;
+
+    WOLFSSL_ENTER("GetNameHash");
+
+    if (source[*idx] == ASN_OBJECT_ID) {
+        WOLFSSL_MSG("Trying optional prefix...");
+
+        if (GetLength(source, idx, &length, maxIdx) < 0)
+            return ASN_PARSE_E;
+
+        *idx += length;
+        WOLFSSL_MSG("Got optional prefix");
+    }
+
+    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
+     * calculated over the entire DER encoding of the Name field, including
+     * the tag and length. */
+    dummy = *idx;
+    if (GetSequence(source, idx, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+#ifdef NO_SHA
+    ret = wc_Sha256Hash(source + dummy, length + *idx - dummy, hash);
+#else
+    ret = wc_ShaHash(source + dummy, length + *idx - dummy, hash);
+#endif
+
+    *idx += length;
+
+    return ret;
+}
+
+
+#ifdef HAVE_CRL
+
+/* initialize decoded CRL */
+void InitDecodedCRL(DecodedCRL* dcrl)
+{
+    WOLFSSL_MSG("InitDecodedCRL");
+
+    dcrl->certBegin    = 0;
+    dcrl->sigIndex     = 0;
+    dcrl->sigLength    = 0;
+    dcrl->signatureOID = 0;
+    dcrl->certs        = NULL;
+    dcrl->totalCerts   = 0;
+}
+
+
+/* free decoded CRL resources */
+void FreeDecodedCRL(DecodedCRL* dcrl)
+{
+    RevokedCert* tmp = dcrl->certs;
+
+    WOLFSSL_MSG("FreeDecodedCRL");
+
+    while(tmp) {
+        RevokedCert* next = tmp->next;
+        XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED);
+        tmp = next;
+    }
+}
+
+
+/* Get Revoked Cert list, 0 on success */
+static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
+                      int maxIdx)
+{
+    int    len;
+    word32 end;
+    byte   b;
+    RevokedCert* rc;
+
+    WOLFSSL_ENTER("GetRevoked");
+
+    if (GetSequence(buff, idx, &len, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    end = *idx + len;
+
+    /* get serial number */
+    b = buff[*idx];
+    *idx += 1;
+
+    if (b != ASN_INTEGER) {
+        WOLFSSL_MSG("Expecting Integer");
+        return ASN_PARSE_E;
+    }
+
+    if (GetLength(buff, idx, &len, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    if (len > EXTERNAL_SERIAL_SIZE) {
+        WOLFSSL_MSG("Serial Size too big");
+        return ASN_PARSE_E;
+    }
+
+    rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), NULL, DYNAMIC_TYPE_CRL);
+    if (rc == NULL) {
+        WOLFSSL_MSG("Alloc Revoked Cert failed");
+        return MEMORY_E;
+    }
+
+    XMEMCPY(rc->serialNumber, &buff[*idx], len);
+    rc->serialSz = len;
+
+    /* add to list */
+    rc->next = dcrl->certs;
+    dcrl->certs = rc;
+    dcrl->totalCerts++;
+
+    *idx += len;
+
+    /* get date */
+    b = buff[*idx];
+    *idx += 1;
+
+    if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) {
+        WOLFSSL_MSG("Expecting Date");
+        return ASN_PARSE_E;
+    }
+
+    if (GetLength(buff, idx, &len, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    /* skip for now */
+    *idx += len;
+
+    if (*idx != end)  /* skip extensions */
+        *idx = end;
+
+    return 0;
+}
+
+
+/* Get CRL Signature, 0 on success */
+static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
+                            int maxIdx)
+{
+    int    length;
+    byte   b;
+
+    WOLFSSL_ENTER("GetCRL_Signature");
+
+    b = source[*idx];
+    *idx += 1;
+    if (b != ASN_BIT_STRING)
+        return ASN_BITSTR_E;
+
+    if (GetLength(source, idx, &length, maxIdx) < 0)
+        return ASN_PARSE_E;
+
+    dcrl->sigLength = length;
+
+    b = source[*idx];
+    *idx += 1;
+    if (b != 0x00)
+        return ASN_EXPECT_0_E;
+
+    dcrl->sigLength--;
+    dcrl->signature = (byte*)&source[*idx];
+
+    *idx += dcrl->sigLength;
+
+    return 0;
+}
+
+
+/* prase crl buffer into decoded state, 0 on success */
+int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
+{
+    int     version, len, doNextDate = 1;
+    word32  oid, idx = 0, dateIdx;
+    Signer* ca = NULL;
+
+    WOLFSSL_MSG("ParseCRL");
+
+    /* raw crl hash */
+    /* hash here if needed for optimized comparisons
+     * Sha     sha;
+     * wc_InitSha(&sha);
+     * wc_ShaUpdate(&sha, buff, sz);
+     * wc_ShaFinal(&sha, dcrl->crlHash); */
+
+    if (GetSequence(buff, &idx, &len, sz) < 0)
+        return ASN_PARSE_E;
+
+    dcrl->certBegin = idx;
+
+    if (GetSequence(buff, &idx, &len, sz) < 0)
+        return ASN_PARSE_E;
+    dcrl->sigIndex = len + idx;
+
+    /* may have version */
+    if (buff[idx] == ASN_INTEGER) {
+        if (GetMyVersion(buff, &idx, &version) < 0)
+            return ASN_PARSE_E;
+    }
+
+    if (GetAlgoId(buff, &idx, &oid, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
+        return ASN_PARSE_E;
+
+    dateIdx = idx;
+
+    if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
+    {
+#ifndef WOLFSSL_NO_CRL_NEXT_DATE
+        (void)dateIdx;
+        return ASN_PARSE_E;
+#else
+        dcrl->nextDateFormat = ASN_OTHER_TYPE;  /* skip flag */
+        doNextDate = 0;
+        idx = dateIdx;
+#endif
+    }
+
+    if (doNextDate && !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat,
+                                      AFTER)) {
+        WOLFSSL_MSG("CRL after date is no longer valid");
+        return ASN_AFTER_DATE_E;
+    }
+
+    if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) {
+        if (GetSequence(buff, &idx, &len, sz) < 0)
+            return ASN_PARSE_E;
+
+        len += idx;
+
+        while (idx < (word32)len) {
+            if (GetRevoked(buff, &idx, dcrl, sz) < 0)
+                return ASN_PARSE_E;
+        }
+    }
+
+    if (idx != dcrl->sigIndex)
+        idx = dcrl->sigIndex;   /* skip extensions */
+
+    if (GetAlgoId(buff, &idx, &dcrl->signatureOID, sz) < 0)
+        return ASN_PARSE_E;
+
+    if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
+        return ASN_PARSE_E;
+
+    /* openssl doesn't add skid by default for CRLs cause firefox chokes
+       we're not assuming it's available yet */
+    #if !defined(NO_SKID) && defined(CRL_SKID_READY)
+        if (dcrl->extAuthKeyIdSet)
+            ca = GetCA(cm, dcrl->extAuthKeyId);
+        if (ca == NULL)
+            ca = GetCAByName(cm, dcrl->issuerHash);
+    #else /* NO_SKID */
+        ca = GetCA(cm, dcrl->issuerHash);
+    #endif /* NO_SKID */
+    WOLFSSL_MSG("About to verify CRL signature");
+
+    if (ca) {
+        WOLFSSL_MSG("Found CRL issuer CA");
+        /* try to confirm/verify signature */
+        #ifndef IGNORE_KEY_EXTENSIONS
+            if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
+                WOLFSSL_MSG("CA cannot sign CRLs");
+                return ASN_CRL_NO_SIGNER_E;
+            }
+        #endif /* IGNORE_KEY_EXTENSIONS */
+        if (!ConfirmSignature(buff + dcrl->certBegin,
+                dcrl->sigIndex - dcrl->certBegin,
+                ca->publicKey, ca->pubKeySize, ca->keyOID,
+                dcrl->signature, dcrl->sigLength, dcrl->signatureOID, NULL)) {
+            WOLFSSL_MSG("CRL Confirm signature failed");
+            return ASN_CRL_CONFIRM_E;
+        }
+    }
+    else {
+        WOLFSSL_MSG("Did NOT find CRL issuer CA");
+        return ASN_CRL_NO_SIGNER_E;
+    }
+
+    return 0;
+}
+
+#endif /* HAVE_CRL */
+#endif
+
+#ifdef WOLFSSL_SEP
+
+
+
+#endif /* WOLFSSL_SEP */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/blake2b.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/blake2b.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/blake2b.c	(revision 164)
@@ -0,0 +1,434 @@
+/*
+   BLAKE2 reference source code package - reference C implementations
+
+   Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
+
+   To the extent possible under law, the author(s) have dedicated all copyright
+   and related and neighboring rights to this software to the public domain
+   worldwide. This software is distributed without any warranty.
+
+   You should have received a copy of the CC0 Public Domain Dedication along with
+   this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
+*/
+/* blake2b.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef HAVE_BLAKE2
+
+#include <wolfssl/wolfcrypt/blake2.h>
+#include <wolfssl/wolfcrypt/blake2-impl.h>
+
+
+static const word64 blake2b_IV[8] =
+{
+  0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
+  0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
+  0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+  0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
+};
+
+static const byte blake2b_sigma[12][16] =
+{
+  {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
+  { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,
+  { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,
+  {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,
+  {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,
+  {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,
+  { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,
+  { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,
+  {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,
+  { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 } ,
+  {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
+  { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 }
+};
+
+
+static INLINE int blake2b_set_lastnode( blake2b_state *S )
+{
+  S->f[1] = ~0ULL;
+  return 0;
+}
+
+/* Some helper functions, not necessarily useful */
+static INLINE int blake2b_set_lastblock( blake2b_state *S )
+{
+  if( S->last_node ) blake2b_set_lastnode( S );
+
+  S->f[0] = ~0ULL;
+  return 0;
+}
+
+static INLINE int blake2b_increment_counter( blake2b_state *S, const word64
+                                             inc )
+{
+  S->t[0] += inc;
+  S->t[1] += ( S->t[0] < inc );
+  return 0;
+}
+
+static INLINE int blake2b_init0( blake2b_state *S )
+{
+  int i;
+  XMEMSET( S, 0, sizeof( blake2b_state ) );
+
+  for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
+
+  return 0;
+}
+
+/* init xors IV with input parameter block */
+int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
+{
+  word32 i;
+  byte *p ;
+  blake2b_init0( S );
+  p =  ( byte * )( P );
+  
+  /* IV XOR ParamBlock */
+  for( i = 0; i < 8; ++i )
+    S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
+
+  return 0;
+}
+
+
+
+int blake2b_init( blake2b_state *S, const byte outlen )
+{
+  blake2b_param P[1];
+
+  if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
+
+  P->digest_length = outlen;
+  P->key_length    = 0;
+  P->fanout        = 1;
+  P->depth         = 1;
+  store32( &P->leaf_length, 0 );
+  store64( &P->node_offset, 0 );
+  P->node_depth    = 0;
+  P->inner_length  = 0;
+  XMEMSET( P->reserved, 0, sizeof( P->reserved ) );
+  XMEMSET( P->salt,     0, sizeof( P->salt ) );
+  XMEMSET( P->personal, 0, sizeof( P->personal ) );
+  return blake2b_init_param( S, P );
+}
+
+
+int blake2b_init_key( blake2b_state *S, const byte outlen, const void *key,
+                      const byte keylen )
+{
+  blake2b_param P[1];
+
+  if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
+
+  if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
+
+  P->digest_length = outlen;
+  P->key_length    = keylen;
+  P->fanout        = 1;
+  P->depth         = 1;
+  store32( &P->leaf_length, 0 );
+  store64( &P->node_offset, 0 );
+  P->node_depth    = 0;
+  P->inner_length  = 0;
+  XMEMSET( P->reserved, 0, sizeof( P->reserved ) );
+  XMEMSET( P->salt,     0, sizeof( P->salt ) );
+  XMEMSET( P->personal, 0, sizeof( P->personal ) );
+
+  if( blake2b_init_param( S, P ) < 0 ) return -1;
+
+  {
+#ifdef WOLFSSL_SMALL_STACK
+    byte* block;
+
+    block = (byte*)XMALLOC(BLAKE2B_BLOCKBYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if ( block == NULL ) return -1;
+#else
+    byte block[BLAKE2B_BLOCKBYTES];
+#endif
+
+    XMEMSET( block, 0, BLAKE2B_BLOCKBYTES );
+    XMEMCPY( block, key, keylen );
+    blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
+    secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from */
+                                                     /* memory */
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(block, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+  }
+  return 0;
+}
+
+static int blake2b_compress( blake2b_state *S,
+                             const byte block[BLAKE2B_BLOCKBYTES] )
+{
+  int i;
+
+#ifdef WOLFSSL_SMALL_STACK
+  word64* m;
+  word64* v;
+
+  m = (word64*)XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+  if ( m == NULL ) return -1;
+
+  v = (word64*)XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+  if ( v == NULL )
+  {
+    XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    return -1;
+  }
+#else
+  word64 m[16];
+  word64 v[16];
+#endif
+
+  for( i = 0; i < 16; ++i )
+    m[i] = load64( block + i * sizeof( m[i] ) );
+
+  for( i = 0; i < 8; ++i )
+    v[i] = S->h[i];
+
+  v[ 8] = blake2b_IV[0];
+  v[ 9] = blake2b_IV[1];
+  v[10] = blake2b_IV[2];
+  v[11] = blake2b_IV[3];
+  v[12] = S->t[0] ^ blake2b_IV[4];
+  v[13] = S->t[1] ^ blake2b_IV[5];
+  v[14] = S->f[0] ^ blake2b_IV[6];
+  v[15] = S->f[1] ^ blake2b_IV[7];
+#define G(r,i,a,b,c,d) \
+  do { \
+    a = a + b + m[blake2b_sigma[r][2*i+0]]; \
+    d = rotr64(d ^ a, 32); \
+    c = c + d; \
+    b = rotr64(b ^ c, 24); \
+    a = a + b + m[blake2b_sigma[r][2*i+1]]; \
+    d = rotr64(d ^ a, 16); \
+    c = c + d; \
+    b = rotr64(b ^ c, 63); \
+  } while(0)
+#define ROUND(r)  \
+  do { \
+    G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
+    G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
+    G(r,2,v[ 2],v[ 6],v[10],v[14]); \
+    G(r,3,v[ 3],v[ 7],v[11],v[15]); \
+    G(r,4,v[ 0],v[ 5],v[10],v[15]); \
+    G(r,5,v[ 1],v[ 6],v[11],v[12]); \
+    G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
+    G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
+  } while(0)
+  ROUND( 0 );
+  ROUND( 1 );
+  ROUND( 2 );
+  ROUND( 3 );
+  ROUND( 4 );
+  ROUND( 5 );
+  ROUND( 6 );
+  ROUND( 7 );
+  ROUND( 8 );
+  ROUND( 9 );
+  ROUND( 10 );
+  ROUND( 11 );
+
+  for( i = 0; i < 8; ++i )
+    S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
+
+#undef G
+#undef ROUND
+
+#ifdef WOLFSSL_SMALL_STACK
+  XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+  XFREE(v, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+  return 0;
+}
+
+/* inlen now in bytes */
+int blake2b_update( blake2b_state *S, const byte *in, word64 inlen )
+{
+  while( inlen > 0 )
+  {
+    word64 left = S->buflen;
+    word64 fill = 2 * BLAKE2B_BLOCKBYTES - left;
+
+    if( inlen > fill )
+    {
+      XMEMCPY( S->buf + left, in, (wolfssl_word)fill ); /* Fill buffer */
+      S->buflen += fill;
+      blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
+
+      if ( blake2b_compress( S, S->buf ) < 0 ) return -1; /* Compress */
+
+      XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES );
+              /* Shift buffer left */
+      S->buflen -= BLAKE2B_BLOCKBYTES;
+      in += fill;
+      inlen -= fill;
+    }
+    else /* inlen <= fill */
+    {
+      XMEMCPY( S->buf + left, in, (wolfssl_word)inlen );
+      S->buflen += inlen; /* Be lazy, do not compress */
+      in += inlen;
+      inlen -= inlen;
+    }
+  }
+
+  return 0;
+}
+
+/* Is this correct? */
+int blake2b_final( blake2b_state *S, byte *out, byte outlen )
+{
+  byte buffer[BLAKE2B_OUTBYTES];
+  int     i;
+
+  if( S->buflen > BLAKE2B_BLOCKBYTES )
+  {
+    blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
+
+    if ( blake2b_compress( S, S->buf ) < 0 ) return -1;
+
+    S->buflen -= BLAKE2B_BLOCKBYTES;
+    XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, (wolfssl_word)S->buflen );
+  }
+
+  blake2b_increment_counter( S, S->buflen );
+  blake2b_set_lastblock( S );
+  XMEMSET( S->buf + S->buflen, 0, (wolfssl_word)(2 * BLAKE2B_BLOCKBYTES - S->buflen) );
+         /* Padding */
+  if ( blake2b_compress( S, S->buf ) < 0 ) return -1;
+
+  for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
+    store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
+
+  XMEMCPY( out, buffer, outlen );
+  return 0;
+}
+
+/* inlen, at least, should be word64. Others can be size_t. */
+int blake2b( byte *out, const void *in, const void *key, const byte outlen,
+             const word64 inlen, byte keylen )
+{
+  blake2b_state S[1];
+
+  /* Verify parameters */
+  if ( NULL == in ) return -1;
+
+  if ( NULL == out ) return -1;
+
+  if( NULL == key ) keylen = 0;
+
+  if( keylen > 0 )
+  {
+    if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
+  }
+  else
+  {
+    if( blake2b_init( S, outlen ) < 0 ) return -1;
+  }
+
+  if ( blake2b_update( S, ( byte * )in, inlen ) < 0) return -1;
+
+  return blake2b_final( S, out, outlen );
+}
+
+#if defined(BLAKE2B_SELFTEST)
+#include <string.h>
+#include "blake2-kat.h"
+int main( int argc, char **argv )
+{
+  byte key[BLAKE2B_KEYBYTES];
+  byte buf[KAT_LENGTH];
+
+  for( word32 i = 0; i < BLAKE2B_KEYBYTES; ++i )
+    key[i] = ( byte )i;
+
+  for( word32 i = 0; i < KAT_LENGTH; ++i )
+    buf[i] = ( byte )i;
+
+  for( word32 i = 0; i < KAT_LENGTH; ++i )
+  {
+    byte hash[BLAKE2B_OUTBYTES];
+    if ( blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 )
+    {
+      puts( "error" );
+      return -1;
+    }
+
+    if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
+    {
+      puts( "error" );
+      return -1;
+    }
+  }
+
+  puts( "ok" );
+  return 0;
+}
+#endif
+
+
+/* wolfCrypt API */
+
+/* Init Blake2b digest, track size incase final doesn't want to "remember" */
+int wc_InitBlake2b(Blake2b* b2b, word32 digestSz)
+{
+    b2b->digestSz = digestSz;
+
+    return blake2b_init(b2b->S, (byte)digestSz);
+}
+
+
+/* Blake2b Update */
+int wc_Blake2bUpdate(Blake2b* b2b, const byte* data, word32 sz)
+{
+    return blake2b_update(b2b->S, data, sz);
+}
+
+
+/* Blake2b Final, if pass in zero size we use init digestSz */
+int wc_Blake2bFinal(Blake2b* b2b, byte* final, word32 requestSz)
+{
+    word32 sz = requestSz ? requestSz : b2b->digestSz;
+
+    return blake2b_final(b2b->S, final, (byte)sz);
+}
+
+
+/* end CTaoCrypt API */
+
+#endif  /* HAVE_BLAKE2 */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/camellia.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/camellia.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/camellia.c	(revision 164)
@@ -0,0 +1,1620 @@
+/* camellia.c ver 1.2.0
+ *
+ * Copyright (c) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer as
+ *   the first lines of this file unmodified.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* camellia.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Algorithm Specification 
+ *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef HAVE_CAMELLIA
+
+#include <wolfssl/wolfcrypt/camellia.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+/* u32 must be 32bit word */
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+/* key constants */
+
+#define CAMELLIA_SIGMA1L ((u32)0xA09E667FL)
+#define CAMELLIA_SIGMA1R ((u32)0x3BCC908BL)
+#define CAMELLIA_SIGMA2L ((u32)0xB67AE858L)
+#define CAMELLIA_SIGMA2R ((u32)0x4CAA73B2L)
+#define CAMELLIA_SIGMA3L ((u32)0xC6EF372FL)
+#define CAMELLIA_SIGMA3R ((u32)0xE94F82BEL)
+#define CAMELLIA_SIGMA4L ((u32)0x54FF53A5L)
+#define CAMELLIA_SIGMA4R ((u32)0xF1D36F1CL)
+#define CAMELLIA_SIGMA5L ((u32)0x10E527FAL)
+#define CAMELLIA_SIGMA5R ((u32)0xDE682D1DL)
+#define CAMELLIA_SIGMA6L ((u32)0xB05688C2L)
+#define CAMELLIA_SIGMA6R ((u32)0xB3E6C1FDL)
+
+/*
+ *  macros
+ */
+
+
+#if defined(_MSC_VER)
+
+# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+# define GETU32(p) SWAP(*((u32 *)(p)))
+# define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));}
+
+#else /* not MS-VC */
+
+# define GETU32(pt)				\
+    (((u32)(pt)[0] << 24)			\
+     ^ ((u32)(pt)[1] << 16)			\
+     ^ ((u32)(pt)[2] <<  8)			\
+     ^ ((u32)(pt)[3]))
+
+# define PUTU32(ct, st)  {			\
+	(ct)[0] = (u8)((st) >> 24);		\
+	(ct)[1] = (u8)((st) >> 16);		\
+	(ct)[2] = (u8)((st) >>  8);		\
+	(ct)[3] = (u8)(st); }
+
+#endif
+
+#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
+#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
+
+/* rotation right shift 1byte */
+#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
+/* rotation left shift 1bit */
+#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
+/* rotation left shift 1byte */
+#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
+
+#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits)	\
+    do {						\
+	w0 = ll;					\
+	ll = (ll << bits) + (lr >> (32 - bits));	\
+	lr = (lr << bits) + (rl >> (32 - bits));	\
+	rl = (rl << bits) + (rr >> (32 - bits));	\
+	rr = (rr << bits) + (w0 >> (32 - bits));	\
+    } while(0)
+
+#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits)	\
+    do {						\
+	w0 = ll;					\
+	w1 = lr;					\
+	ll = (lr << (bits - 32)) + (rl >> (64 - bits));	\
+	lr = (rl << (bits - 32)) + (rr >> (64 - bits));	\
+	rl = (rr << (bits - 32)) + (w0 >> (64 - bits));	\
+	rr = (w0 << (bits - 32)) + (w1 >> (64 - bits));	\
+    } while(0)
+
+#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
+#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
+#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
+#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
+
+#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)	\
+    do {							\
+	il = xl ^ kl;						\
+	ir = xr ^ kr;						\
+	t0 = il >> 16;						\
+	t1 = ir >> 16;						\
+	yl = CAMELLIA_SP1110(ir & 0xff)				\
+	    ^ CAMELLIA_SP0222((t1 >> 8) & 0xff)			\
+	    ^ CAMELLIA_SP3033(t1 & 0xff)			\
+	    ^ CAMELLIA_SP4404((ir >> 8) & 0xff);		\
+	yr = CAMELLIA_SP1110((t0 >> 8) & 0xff)			\
+	    ^ CAMELLIA_SP0222(t0 & 0xff)			\
+	    ^ CAMELLIA_SP3033((il >> 8) & 0xff)			\
+	    ^ CAMELLIA_SP4404(il & 0xff);			\
+	yl ^= yr;						\
+	yr = CAMELLIA_RR8(yr);					\
+	yr ^= yl;						\
+    } while(0)
+
+
+/*
+ * for speed up
+ *
+ */
+#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
+    do {								\
+	t0 = kll;							\
+	t0 &= ll;							\
+	lr ^= CAMELLIA_RL1(t0);						\
+	t1 = klr;							\
+	t1 |= lr;							\
+	ll ^= t1;							\
+									\
+	t2 = krr;							\
+	t2 |= rr;							\
+	rl ^= t2;							\
+	t3 = krl;							\
+	t3 &= rl;							\
+	rr ^= CAMELLIA_RL1(t3);						\
+    } while(0)
+
+#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)	\
+    do {								\
+	ir = CAMELLIA_SP1110(xr & 0xff)					\
+	    ^ CAMELLIA_SP0222((xr >> 24) & 0xff)			\
+	    ^ CAMELLIA_SP3033((xr >> 16) & 0xff)			\
+	    ^ CAMELLIA_SP4404((xr >> 8) & 0xff);			\
+	il = CAMELLIA_SP1110((xl >> 24) & 0xff)				\
+	    ^ CAMELLIA_SP0222((xl >> 16) & 0xff)			\
+	    ^ CAMELLIA_SP3033((xl >> 8) & 0xff)				\
+	    ^ CAMELLIA_SP4404(xl & 0xff);				\
+	il ^= kl;							\
+	ir ^= kr;							\
+	ir ^= il;							\
+	il = CAMELLIA_RR8(il);						\
+	il ^= ir;							\
+	yl ^= ir;							\
+	yr ^= il;							\
+    } while(0)
+
+
+static const u32 camellia_sp1110[256] = {
+    0x70707000,0x82828200,0x2c2c2c00,0xececec00,
+    0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
+    0xe4e4e400,0x85858500,0x57575700,0x35353500,
+    0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
+    0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
+    0x45454500,0x19191900,0xa5a5a500,0x21212100,
+    0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
+    0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
+    0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
+    0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
+    0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
+    0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
+    0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
+    0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
+    0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
+    0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
+    0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
+    0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
+    0x74747400,0x12121200,0x2b2b2b00,0x20202000,
+    0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
+    0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
+    0x34343400,0x7e7e7e00,0x76767600,0x05050500,
+    0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
+    0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
+    0x14141400,0x58585800,0x3a3a3a00,0x61616100,
+    0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
+    0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
+    0x53535300,0x18181800,0xf2f2f200,0x22222200,
+    0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
+    0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
+    0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
+    0x60606000,0xfcfcfc00,0x69696900,0x50505000,
+    0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
+    0xa1a1a100,0x89898900,0x62626200,0x97979700,
+    0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
+    0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
+    0x10101000,0xc4c4c400,0x00000000,0x48484800,
+    0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
+    0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
+    0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
+    0x87878700,0x5c5c5c00,0x83838300,0x02020200,
+    0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
+    0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
+    0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
+    0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
+    0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
+    0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
+    0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
+    0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
+    0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
+    0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
+    0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
+    0x78787800,0x98989800,0x06060600,0x6a6a6a00,
+    0xe7e7e700,0x46464600,0x71717100,0xbababa00,
+    0xd4d4d400,0x25252500,0xababab00,0x42424200,
+    0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
+    0x72727200,0x07070700,0xb9b9b900,0x55555500,
+    0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
+    0x36363600,0x49494900,0x2a2a2a00,0x68686800,
+    0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
+    0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
+    0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
+    0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
+    0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
+};
+
+static const u32 camellia_sp0222[256] = {
+    0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
+    0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
+    0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
+    0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
+    0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
+    0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
+    0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
+    0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
+    0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
+    0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
+    0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
+    0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
+    0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
+    0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
+    0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
+    0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
+    0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
+    0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
+    0x00e8e8e8,0x00242424,0x00565656,0x00404040,
+    0x00e1e1e1,0x00636363,0x00090909,0x00333333,
+    0x00bfbfbf,0x00989898,0x00979797,0x00858585,
+    0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
+    0x00dadada,0x006f6f6f,0x00535353,0x00626262,
+    0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
+    0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
+    0x00bdbdbd,0x00363636,0x00222222,0x00383838,
+    0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
+    0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
+    0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
+    0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
+    0x00484848,0x00101010,0x00d1d1d1,0x00515151,
+    0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
+    0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
+    0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
+    0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
+    0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
+    0x00202020,0x00898989,0x00000000,0x00909090,
+    0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
+    0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
+    0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
+    0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
+    0x009b9b9b,0x00949494,0x00212121,0x00666666,
+    0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
+    0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
+    0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
+    0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
+    0x00030303,0x002d2d2d,0x00dedede,0x00969696,
+    0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
+    0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
+    0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
+    0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
+    0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
+    0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
+    0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
+    0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
+    0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
+    0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
+    0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
+    0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
+    0x00787878,0x00707070,0x00e3e3e3,0x00494949,
+    0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
+    0x00777777,0x00939393,0x00868686,0x00838383,
+    0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
+    0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
+};
+
+static const u32 camellia_sp3033[256] = {
+    0x38003838,0x41004141,0x16001616,0x76007676,
+    0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
+    0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
+    0x75007575,0x06000606,0x57005757,0xa000a0a0,
+    0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
+    0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
+    0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
+    0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
+    0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
+    0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
+    0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
+    0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
+    0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
+    0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
+    0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
+    0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
+    0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
+    0xfd00fdfd,0x66006666,0x58005858,0x96009696,
+    0x3a003a3a,0x09000909,0x95009595,0x10001010,
+    0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
+    0xef00efef,0x26002626,0xe500e5e5,0x61006161,
+    0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
+    0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
+    0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
+    0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
+    0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
+    0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
+    0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
+    0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
+    0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
+    0x12001212,0x04000404,0x74007474,0x54005454,
+    0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
+    0x55005555,0x68006868,0x50005050,0xbe00bebe,
+    0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
+    0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
+    0x70007070,0xff00ffff,0x32003232,0x69006969,
+    0x08000808,0x62006262,0x00000000,0x24002424,
+    0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
+    0x45004545,0x81008181,0x73007373,0x6d006d6d,
+    0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
+    0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
+    0xe600e6e6,0x25002525,0x48004848,0x99009999,
+    0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
+    0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
+    0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
+    0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
+    0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
+    0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
+    0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
+    0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
+    0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
+    0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
+    0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
+    0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
+    0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
+    0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
+    0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
+    0x7c007c7c,0x77007777,0x56005656,0x05000505,
+    0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
+    0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
+    0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
+    0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
+    0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
+    0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
+};
+
+static const u32 camellia_sp4404[256] = {
+    0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
+    0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
+    0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
+    0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
+    0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
+    0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
+    0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
+    0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
+    0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
+    0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
+    0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
+    0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
+    0x14140014,0x3a3a003a,0xdede00de,0x11110011,
+    0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
+    0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
+    0x24240024,0xe8e800e8,0x60600060,0x69690069,
+    0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
+    0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
+    0x10100010,0x00000000,0xa3a300a3,0x75750075,
+    0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
+    0x87870087,0x83830083,0xcdcd00cd,0x90900090,
+    0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
+    0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
+    0x81810081,0x6f6f006f,0x13130013,0x63630063,
+    0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
+    0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
+    0x78780078,0x06060006,0xe7e700e7,0x71710071,
+    0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
+    0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
+    0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
+    0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
+    0x15150015,0xadad00ad,0x77770077,0x80800080,
+    0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
+    0x85850085,0x35350035,0x0c0c000c,0x41410041,
+    0xefef00ef,0x93930093,0x19190019,0x21210021,
+    0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
+    0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
+    0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
+    0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
+    0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
+    0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
+    0x12120012,0x20200020,0xb1b100b1,0x99990099,
+    0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
+    0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
+    0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
+    0x0f0f000f,0x16160016,0x18180018,0x22220022,
+    0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
+    0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
+    0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
+    0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
+    0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
+    0x03030003,0xdada00da,0x3f3f003f,0x94940094,
+    0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
+    0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
+    0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
+    0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
+    0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
+    0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
+    0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
+    0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
+    0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
+    0x49490049,0x68680068,0x38380038,0xa4a400a4,
+    0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
+    0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
+};
+
+
+/**
+ * Stuff related to the Camellia key schedule
+ */
+#define subl(x) subL[(x)]
+#define subr(x) subR[(x)]
+
+static int camellia_setup128(const unsigned char *key, u32 *subkey)
+{
+    u32 kll, klr, krl, krr;
+    u32 il, ir, t0, t1, w0, w1;
+    u32 kw4l, kw4r, dw, tl, tr;
+
+#ifdef WOLFSSL_SMALL_STACK
+    u32* subL;
+    u32* subR;
+
+    subL = (u32*) XMALLOC(sizeof(u32) * 26, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (subL == NULL)
+        return MEMORY_E;
+
+    subR = (u32*) XMALLOC(sizeof(u32) * 26, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (subR == NULL) {
+        XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#else
+    u32 subL[26];
+    u32 subR[26];
+#endif
+
+    /**
+     *  k == kll || klr || krl || krr (|| is concatination)
+     */
+    kll = GETU32(key     );
+    klr = GETU32(key +  4);
+    krl = GETU32(key +  8);
+    krr = GETU32(key + 12);
+    /**
+     * generate KL dependent subkeys
+     */
+    subl(0) = kll; subr(0) = klr;
+    subl(1) = krl; subr(1) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(4) = kll; subr(4) = klr;
+    subl(5) = krl; subr(5) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+    subl(10) = kll; subr(10) = klr;
+    subl(11) = krl; subr(11) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(13) = krl; subr(13) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(16) = kll; subr(16) = klr;
+    subl(17) = krl; subr(17) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(18) = kll; subr(18) = klr;
+    subl(19) = krl; subr(19) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(22) = kll; subr(22) = klr;
+    subl(23) = krl; subr(23) = krr;
+
+    /* generate KA */
+    kll = subl(0); klr = subr(0);
+    krl = subl(1); krr = subr(1);
+    CAMELLIA_F(kll, klr,
+	       CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+	       w0, w1, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+	       CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+	       kll, klr, il, ir, t0, t1);
+    CAMELLIA_F(kll, klr,
+	       CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+	       krl, krr, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+	       CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+	       w0, w1, il, ir, t0, t1);
+    kll ^= w0; klr ^= w1;
+
+    /* generate KA dependent subkeys */
+    subl(2) = kll; subr(2) = klr;
+    subl(3) = krl; subr(3) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(6) = kll; subr(6) = klr;
+    subl(7) = krl; subr(7) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(8) = kll; subr(8) = klr;
+    subl(9) = krl; subr(9) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(12) = kll; subr(12) = klr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(14) = kll; subr(14) = klr;
+    subl(15) = krl; subr(15) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+    subl(20) = kll; subr(20) = klr;
+    subl(21) = krl; subr(21) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(24) = kll; subr(24) = klr;
+    subl(25) = krl; subr(25) = krr;
+
+
+    /* absorb kw2 to other subkeys */
+    subl(3) ^= subl(1); subr(3) ^= subr(1);
+    subl(5) ^= subl(1); subr(5) ^= subr(1);
+    subl(7) ^= subl(1); subr(7) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(9);
+    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(11) ^= subl(1); subr(11) ^= subr(1);
+    subl(13) ^= subl(1); subr(13) ^= subr(1);
+    subl(15) ^= subl(1); subr(15) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(17);
+    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(19) ^= subl(1); subr(19) ^= subr(1);
+    subl(21) ^= subl(1); subr(21) ^= subr(1);
+    subl(23) ^= subl(1); subr(23) ^= subr(1);
+    subl(24) ^= subl(1); subr(24) ^= subr(1);
+
+    /* absorb kw4 to other subkeys */
+    kw4l = subl(25); kw4r = subr(25);
+    subl(22) ^= kw4l; subr(22) ^= kw4r;
+    subl(20) ^= kw4l; subr(20) ^= kw4r;
+    subl(18) ^= kw4l; subr(18) ^= kw4r;
+    kw4l ^= kw4r & ~subr(16);
+    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+    subl(14) ^= kw4l; subr(14) ^= kw4r;
+    subl(12) ^= kw4l; subr(12) ^= kw4r;
+    subl(10) ^= kw4l; subr(10) ^= kw4r;
+    kw4l ^= kw4r & ~subr(8);
+    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+    subl(6) ^= kw4l; subr(6) ^= kw4r;
+    subl(4) ^= kw4l; subr(4) ^= kw4r;
+    subl(2) ^= kw4l; subr(2) ^= kw4r;
+    subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+    /* key XOR is end of F-function */
+    CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+    CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+    CamelliaSubkeyL(2) = subl(3);
+    CamelliaSubkeyR(2) = subr(3);
+    CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+    CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+    CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+    CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+    CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+    CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+    CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+    CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+    tl = subl(10) ^ (subr(10) & ~subr(8));
+    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(7) = subl(6) ^ tl;
+    CamelliaSubkeyR(7) = subr(6) ^ tr;
+    CamelliaSubkeyL(8) = subl(8);
+    CamelliaSubkeyR(8) = subr(8);
+    CamelliaSubkeyL(9) = subl(9);
+    CamelliaSubkeyR(9) = subr(9);
+    tl = subl(7) ^ (subr(7) & ~subr(9));
+    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(10) = tl ^ subl(11);
+    CamelliaSubkeyR(10) = tr ^ subr(11);
+    CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+    CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+    CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+    CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+    CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+    CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+    CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+    CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+    tl = subl(18) ^ (subr(18) & ~subr(16));
+    dw = tl & subl(16),	tr = subr(18) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(15) = subl(14) ^ tl;
+    CamelliaSubkeyR(15) = subr(14) ^ tr;
+    CamelliaSubkeyL(16) = subl(16);
+    CamelliaSubkeyR(16) = subr(16);
+    CamelliaSubkeyL(17) = subl(17);
+    CamelliaSubkeyR(17) = subr(17);
+    tl = subl(15) ^ (subr(15) & ~subr(17));
+    dw = tl & subl(17),	tr = subr(15) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(18) = tl ^ subl(19);
+    CamelliaSubkeyR(18) = tr ^ subr(19);
+    CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+    CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+    CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+    CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+    CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+    CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+    CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+    CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+    CamelliaSubkeyL(23) = subl(22);
+    CamelliaSubkeyR(23) = subr(22);
+    CamelliaSubkeyL(24) = subl(24) ^ subl(23);
+    CamelliaSubkeyR(24) = subr(24) ^ subr(23);
+
+    /* apply the inverse of the last half of P-function */
+    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(subR, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return 0;
+}
+
+static int camellia_setup256(const unsigned char *key, u32 *subkey)
+{
+    u32 kll,klr,krl,krr;           /* left half of key */
+    u32 krll,krlr,krrl,krrr;       /* right half of key */
+    u32 il, ir, t0, t1, w0, w1;    /* temporary variables */
+    u32 kw4l, kw4r, dw, tl, tr;
+
+#ifdef WOLFSSL_SMALL_STACK
+    u32* subL;
+    u32* subR;
+
+    subL = (u32*) XMALLOC(sizeof(u32) * 34, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (subL == NULL)
+        return MEMORY_E;
+
+    subR = (u32*) XMALLOC(sizeof(u32) * 34, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (subR == NULL) {
+        XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#else
+    u32 subL[34];
+    u32 subR[34];
+#endif
+
+    /**
+     *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
+     *  (|| is concatination)
+     */
+
+    kll  = GETU32(key     );
+    klr  = GETU32(key +  4);
+    krl  = GETU32(key +  8);
+    krr  = GETU32(key + 12);
+    krll = GETU32(key + 16);
+    krlr = GETU32(key + 20);
+    krrl = GETU32(key + 24);
+    krrr = GETU32(key + 28);
+
+    /* generate KL dependent subkeys */
+    subl(0) = kll; subr(0) = klr;
+    subl(1) = krl; subr(1) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
+    subl(12) = kll; subr(12) = klr;
+    subl(13) = krl; subr(13) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(16) = kll; subr(16) = klr;
+    subl(17) = krl; subr(17) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(22) = kll; subr(22) = klr;
+    subl(23) = krl; subr(23) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+    subl(30) = kll; subr(30) = klr;
+    subl(31) = krl; subr(31) = krr;
+
+    /* generate KR dependent subkeys */
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+    subl(4) = krll; subr(4) = krlr;
+    subl(5) = krrl; subr(5) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+    subl(8) = krll; subr(8) = krlr;
+    subl(9) = krrl; subr(9) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(18) = krll; subr(18) = krlr;
+    subl(19) = krrl; subr(19) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+    subl(26) = krll; subr(26) = krlr;
+    subl(27) = krrl; subr(27) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+
+    /* generate KA */
+    kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
+    krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
+    CAMELLIA_F(kll, klr,
+	       CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+	       w0, w1, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+	       CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+	       kll, klr, il, ir, t0, t1);
+    kll ^= krll; klr ^= krlr;
+    CAMELLIA_F(kll, klr,
+	       CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+	       krl, krr, il, ir, t0, t1);
+    krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
+    CAMELLIA_F(krl, krr,
+	       CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+	       w0, w1, il, ir, t0, t1);
+    kll ^= w0; klr ^= w1;
+
+    /* generate KB */
+    krll ^= kll; krlr ^= klr;
+    krrl ^= krl; krrr ^= krr;
+    CAMELLIA_F(krll, krlr,
+	       CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
+	       w0, w1, il, ir, t0, t1);
+    krrl ^= w0; krrr ^= w1;
+    CAMELLIA_F(krrl, krrr,
+	       CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
+	       w0, w1, il, ir, t0, t1);
+    krll ^= w0; krlr ^= w1;
+
+    /* generate KA dependent subkeys */
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(6) = kll; subr(6) = klr;
+    subl(7) = krl; subr(7) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+    subl(14) = kll; subr(14) = klr;
+    subl(15) = krl; subr(15) = krr;
+    subl(24) = klr; subr(24) = krl;
+    subl(25) = krr; subr(25) = kll;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
+    subl(28) = kll; subr(28) = klr;
+    subl(29) = krl; subr(29) = krr;
+
+    /* generate KB dependent subkeys */
+    subl(2) = krll; subr(2) = krlr;
+    subl(3) = krrl; subr(3) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(10) = krll; subr(10) = krlr;
+    subl(11) = krrl; subr(11) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(20) = krll; subr(20) = krlr;
+    subl(21) = krrl; subr(21) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
+    subl(32) = krll; subr(32) = krlr;
+    subl(33) = krrl; subr(33) = krrr;
+
+    /* absorb kw2 to other subkeys */
+    subl(3) ^= subl(1); subr(3) ^= subr(1);
+    subl(5) ^= subl(1); subr(5) ^= subr(1);
+    subl(7) ^= subl(1); subr(7) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(9);
+    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(11) ^= subl(1); subr(11) ^= subr(1);
+    subl(13) ^= subl(1); subr(13) ^= subr(1);
+    subl(15) ^= subl(1); subr(15) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(17);
+    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(19) ^= subl(1); subr(19) ^= subr(1);
+    subl(21) ^= subl(1); subr(21) ^= subr(1);
+    subl(23) ^= subl(1); subr(23) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(25);
+    dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(27) ^= subl(1); subr(27) ^= subr(1);
+    subl(29) ^= subl(1); subr(29) ^= subr(1);
+    subl(31) ^= subl(1); subr(31) ^= subr(1);
+    subl(32) ^= subl(1); subr(32) ^= subr(1);
+
+    /* absorb kw4 to other subkeys */
+    kw4l = subl(33); kw4r = subr(33);
+    subl(30) ^= kw4l; subr(30) ^= kw4r;
+    subl(28) ^= kw4l; subr(28) ^= kw4r;
+    subl(26) ^= kw4l; subr(26) ^= kw4r;
+    kw4l ^= kw4r & ~subr(24);
+    dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw);
+    subl(22) ^= kw4l; subr(22) ^= kw4r;
+    subl(20) ^= kw4l; subr(20) ^= kw4r;
+    subl(18) ^= kw4l; subr(18) ^= kw4r;
+    kw4l ^= kw4r & ~subr(16);
+    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+    subl(14) ^= kw4l; subr(14) ^= kw4r;
+    subl(12) ^= kw4l; subr(12) ^= kw4r;
+    subl(10) ^= kw4l; subr(10) ^= kw4r;
+    kw4l ^= kw4r & ~subr(8);
+    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+    subl(6) ^= kw4l; subr(6) ^= kw4r;
+    subl(4) ^= kw4l; subr(4) ^= kw4r;
+    subl(2) ^= kw4l; subr(2) ^= kw4r;
+    subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+    /* key XOR is end of F-function */
+    CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+    CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+    CamelliaSubkeyL(2) = subl(3);
+    CamelliaSubkeyR(2) = subr(3);
+    CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+    CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+    CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+    CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+    CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+    CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+    CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+    CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+    tl = subl(10) ^ (subr(10) & ~subr(8));
+    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(7) = subl(6) ^ tl;
+    CamelliaSubkeyR(7) = subr(6) ^ tr;
+    CamelliaSubkeyL(8) = subl(8);
+    CamelliaSubkeyR(8) = subr(8);
+    CamelliaSubkeyL(9) = subl(9);
+    CamelliaSubkeyR(9) = subr(9);
+    tl = subl(7) ^ (subr(7) & ~subr(9));
+    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(10) = tl ^ subl(11);
+    CamelliaSubkeyR(10) = tr ^ subr(11);
+    CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+    CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+    CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+    CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+    CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+    CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+    CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+    CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+    tl = subl(18) ^ (subr(18) & ~subr(16));
+    dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(15) = subl(14) ^ tl;
+    CamelliaSubkeyR(15) = subr(14) ^ tr;
+    CamelliaSubkeyL(16) = subl(16);
+    CamelliaSubkeyR(16) = subr(16);
+    CamelliaSubkeyL(17) = subl(17);
+    CamelliaSubkeyR(17) = subr(17);
+    tl = subl(15) ^ (subr(15) & ~subr(17));
+    dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(18) = tl ^ subl(19);
+    CamelliaSubkeyR(18) = tr ^ subr(19);
+    CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+    CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+    CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+    CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+    CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+    CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+    CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+    CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+    tl = subl(26) ^ (subr(26) & ~subr(24));
+    dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(23) = subl(22) ^ tl;
+    CamelliaSubkeyR(23) = subr(22) ^ tr;
+    CamelliaSubkeyL(24) = subl(24);
+    CamelliaSubkeyR(24) = subr(24);
+    CamelliaSubkeyL(25) = subl(25);
+    CamelliaSubkeyR(25) = subr(25);
+    tl = subl(23) ^ (subr(23) &  ~subr(25));
+    dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(26) = tl ^ subl(27);
+    CamelliaSubkeyR(26) = tr ^ subr(27);
+    CamelliaSubkeyL(27) = subl(26) ^ subl(28);
+    CamelliaSubkeyR(27) = subr(26) ^ subr(28);
+    CamelliaSubkeyL(28) = subl(27) ^ subl(29);
+    CamelliaSubkeyR(28) = subr(27) ^ subr(29);
+    CamelliaSubkeyL(29) = subl(28) ^ subl(30);
+    CamelliaSubkeyR(29) = subr(28) ^ subr(30);
+    CamelliaSubkeyL(30) = subl(29) ^ subl(31);
+    CamelliaSubkeyR(30) = subr(29) ^ subr(31);
+    CamelliaSubkeyL(31) = subl(30);
+    CamelliaSubkeyR(31) = subr(30);
+    CamelliaSubkeyL(32) = subl(32) ^ subl(31);
+    CamelliaSubkeyR(32) = subr(32) ^ subr(31);
+
+    /* apply the inverse of the last half of P-function */
+    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+    dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw;
+    dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw;
+    dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw;
+    dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw;
+    dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw;
+    dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw;
+    
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(subR, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return 0;
+}
+
+static int camellia_setup192(const unsigned char *key, u32 *subkey)
+{
+    unsigned char kk[32];
+    u32 krll, krlr, krrl,krrr;
+
+    XMEMCPY(kk, key, 24);
+    XMEMCPY((unsigned char *)&krll, key+16,4);
+    XMEMCPY((unsigned char *)&krlr, key+20,4);
+    krrl = ~krll;
+    krrr = ~krlr;
+    XMEMCPY(kk+24, (unsigned char *)&krrl, 4);
+    XMEMCPY(kk+28, (unsigned char *)&krrr, 4);
+
+    return camellia_setup256(kk, subkey);
+}
+
+
+/**
+ * Stuff related to camellia encryption/decryption
+ *
+ * "io" must be 4byte aligned and big-endian data.
+ */
+static void camellia_encrypt128(const u32 *subkey, u32 *io)
+{
+    u32 il, ir, t0, t1;
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(0);
+    io[1] ^= CamelliaSubkeyR(0);
+    /* main iteration */
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+		 CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+		 CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+		     io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(24);
+    io[3] ^= CamelliaSubkeyR(24);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+	
+    return;
+}
+
+static void camellia_decrypt128(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;               /* temporary valiables */
+    
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(24);
+    io[1] ^= CamelliaSubkeyR(24);
+
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+		 CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+		 CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+		     io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(0);
+    io[3] ^= CamelliaSubkeyR(0);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+/**
+ * stuff for 192 and 256bit encryption/decryption
+ */
+static void camellia_encrypt256(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;           /* temporary valiables */
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(0);
+    io[1] ^= CamelliaSubkeyR(0);
+
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+		 CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+		 CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+		 CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+		     io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(32);
+    io[3] ^= CamelliaSubkeyR(32);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+static void camellia_decrypt256(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;           /* temporary valiables */
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(32);
+    io[1] ^= CamelliaSubkeyR(32);
+	
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+		 CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+		 CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+		     io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+		 CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+		 CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+		 t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+		     io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+		     CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+		     io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+		     CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+		     io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(0);
+    io[3] ^= CamelliaSubkeyR(0);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+/***
+ *
+ * API for compatibility
+ */
+
+static void Camellia_EncryptBlock(const int keyBitLength, 
+			   const unsigned char *plaintext, 
+			   const KEY_TABLE_TYPE keyTable, 
+			   unsigned char *ciphertext)
+{
+    u32 tmp[4];
+
+    tmp[0] = GETU32(plaintext);
+    tmp[1] = GETU32(plaintext + 4);
+    tmp[2] = GETU32(plaintext + 8);
+    tmp[3] = GETU32(plaintext + 12);
+
+    switch (keyBitLength) {
+    case 128:
+	camellia_encrypt128(keyTable, tmp);
+	break;
+    case 192:
+	/* fall through */
+    case 256:
+	camellia_encrypt256(keyTable, tmp);
+	break;
+    default:
+	break;
+    }
+
+    PUTU32(ciphertext, tmp[0]);
+    PUTU32(ciphertext + 4, tmp[1]);
+    PUTU32(ciphertext + 8, tmp[2]);
+    PUTU32(ciphertext + 12, tmp[3]);
+}
+
+static void Camellia_DecryptBlock(const int keyBitLength, 
+			   const unsigned char *ciphertext, 
+			   const KEY_TABLE_TYPE keyTable, 
+			   unsigned char *plaintext)
+{
+    u32 tmp[4];
+
+    tmp[0] = GETU32(ciphertext);
+    tmp[1] = GETU32(ciphertext + 4);
+    tmp[2] = GETU32(ciphertext + 8);
+    tmp[3] = GETU32(ciphertext + 12);
+
+    switch (keyBitLength) {
+    case 128:
+	camellia_decrypt128(keyTable, tmp);
+	break;
+    case 192:
+	/* fall through */
+    case 256:
+	camellia_decrypt256(keyTable, tmp);
+	break;
+    default:
+	break;
+    }
+    PUTU32(plaintext, tmp[0]);
+    PUTU32(plaintext + 4, tmp[1]);
+    PUTU32(plaintext + 8, tmp[2]);
+    PUTU32(plaintext + 12, tmp[3]);
+}
+
+
+
+/* wolfCrypt wrappers to the Camellia code */
+
+int wc_CamelliaSetKey(Camellia* cam, const byte* key, word32 len, const byte* iv)
+{
+    int ret = 0;
+
+    if (cam == NULL) return BAD_FUNC_ARG;
+
+    XMEMSET(cam->key, 0, sizeof(KEY_TABLE_TYPE));
+
+    switch (len) {
+        case 16:
+        	ret = camellia_setup128(key, cam->key);
+            break;
+        case 24:
+        	ret = camellia_setup192(key, cam->key);
+            break;
+        case 32:
+            ret = camellia_setup256(key, cam->key);
+            break;
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    if (ret != 0)
+        return ret;
+
+    cam->keySz = len * 8;
+
+    return wc_CamelliaSetIV(cam, iv);
+}
+
+
+int wc_CamelliaSetIV(Camellia* cam, const byte* iv)
+{
+    if (cam == NULL)
+        return BAD_FUNC_ARG;
+
+    if (iv)
+        XMEMCPY(cam->reg, iv, CAMELLIA_BLOCK_SIZE);
+    else
+        XMEMSET(cam->reg,  0, CAMELLIA_BLOCK_SIZE);
+
+    return 0;
+}
+
+
+void wc_CamelliaEncryptDirect(Camellia* cam, byte* out, const byte* in)
+{
+    Camellia_EncryptBlock(cam->keySz, in, cam->key, out);
+}
+
+
+void wc_CamelliaDecryptDirect(Camellia* cam, byte* out, const byte* in)
+{
+    Camellia_DecryptBlock(cam->keySz, in, cam->key, out);
+}
+
+
+void wc_CamelliaCbcEncrypt(Camellia* cam, byte* out, const byte* in, word32 sz)
+{
+    word32 blocks = sz / CAMELLIA_BLOCK_SIZE;
+
+    while (blocks--) {
+        xorbuf((byte*)cam->reg, in, CAMELLIA_BLOCK_SIZE);
+        Camellia_EncryptBlock(cam->keySz, (byte*)cam->reg,
+                                                     cam->key, (byte*)cam->reg);
+        XMEMCPY(out, cam->reg, CAMELLIA_BLOCK_SIZE);
+
+        out += CAMELLIA_BLOCK_SIZE;
+        in  += CAMELLIA_BLOCK_SIZE;
+    }
+}
+
+
+void wc_CamelliaCbcDecrypt(Camellia* cam, byte* out, const byte* in, word32 sz)
+{
+    word32 blocks = sz / CAMELLIA_BLOCK_SIZE;
+
+    while (blocks--) {
+        XMEMCPY(cam->tmp, in, CAMELLIA_BLOCK_SIZE);
+        Camellia_DecryptBlock(cam->keySz, (byte*)cam->tmp, cam->key, out);
+        xorbuf(out, (byte*)cam->reg, CAMELLIA_BLOCK_SIZE);
+        XMEMCPY(cam->reg, cam->tmp, CAMELLIA_BLOCK_SIZE);
+
+        out += CAMELLIA_BLOCK_SIZE;
+        in  += CAMELLIA_BLOCK_SIZE;
+    }
+}
+
+
+#endif /* HAVE_CAMELLIA */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/coding.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/coding.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/coding.c	(revision 164)
@@ -0,0 +1,451 @@
+/* coding.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_CODING
+
+#include <wolfssl/wolfcrypt/coding.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+
+
+enum {
+    BAD         = 0xFF,  /* invalid encoding */
+    PAD         = '=',
+    PEM_LINE_SZ = 64
+};
+
+
+static
+const byte base64Decode[] = { 62, BAD, BAD, BAD, 63,   /* + starts at 0x2B */
+                              52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+                              BAD, BAD, BAD, BAD, BAD, BAD, BAD,
+                              0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                              10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+                              20, 21, 22, 23, 24, 25,
+                              BAD, BAD, BAD, BAD, BAD, BAD,
+                              26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+                              36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+                              46, 47, 48, 49, 50, 51
+                            };
+
+
+int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
+{
+    word32 i = 0;
+    word32 j = 0;
+    word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ );
+    const byte maxIdx = (byte)sizeof(base64Decode) + 0x2B - 1;
+
+    plainSz = (plainSz * 3 + 3) / 4;
+    if (plainSz > *outLen) return BAD_FUNC_ARG;
+
+    while (inLen > 3) {
+        byte b1, b2, b3;
+        byte e1 = in[j++];
+        byte e2 = in[j++];
+        byte e3 = in[j++];
+        byte e4 = in[j++];
+
+        int pad3 = 0;
+        int pad4 = 0;
+
+        if (e1 == 0)            /* end file 0's */
+            break;
+        if (e3 == PAD)
+            pad3 = 1;
+        if (e4 == PAD)
+            pad4 = 1;
+
+        if (e1 < 0x2B || e2 < 0x2B || e3 < 0x2B || e4 < 0x2B) {
+            WOLFSSL_MSG("Bad Base64 Decode data, too small");
+            return ASN_INPUT_E;
+        }
+
+        if (e1 > maxIdx || e2 > maxIdx || e3 > maxIdx || e4 > maxIdx) {
+            WOLFSSL_MSG("Bad Base64 Decode data, too big");
+            return ASN_INPUT_E;
+        }
+
+        e1 = base64Decode[e1 - 0x2B];
+        e2 = base64Decode[e2 - 0x2B];
+        e3 = (e3 == PAD) ? 0 : base64Decode[e3 - 0x2B];
+        e4 = (e4 == PAD) ? 0 : base64Decode[e4 - 0x2B];
+
+        b1 = (byte)((e1 << 2) | (e2 >> 4));
+        b2 = (byte)(((e2 & 0xF) << 4) | (e3 >> 2));
+        b3 = (byte)(((e3 & 0x3) << 6) | e4);
+
+        out[i++] = b1;
+        if (!pad3)
+            out[i++] = b2;
+        if (!pad4)
+            out[i++] = b3;
+        else
+            break;
+
+        inLen -= 4;
+        if (inLen && (in[j] == ' ' || in[j] == '\r' || in[j] == '\n')) {
+            byte endLine = in[j++];
+            inLen--;
+            while (inLen && endLine == ' ') {   /* allow trailing whitespace */
+                endLine = in[j++];
+                inLen--;
+            }
+            if (endLine == '\r') {
+                if (inLen) {
+                    endLine = in[j++];
+                    inLen--;
+                }
+            }
+            if (endLine != '\n') {
+                WOLFSSL_MSG("Bad end of line in Base64 Decode");
+                return ASN_INPUT_E;
+            }
+        }
+    }
+    *outLen = i;
+
+    return 0;
+}
+
+
+#if defined(WOLFSSL_BASE64_ENCODE)
+
+static
+const byte base64Encode[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+                              'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+                              'U', 'V', 'W', 'X', 'Y', 'Z',
+                              'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+                              'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+                              'u', 'v', 'w', 'x', 'y', 'z',
+                              '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+                              '+', '/'
+                            };
+
+
+/* make sure *i (idx) won't exceed max, store and possibly escape to out,
+ * raw means use e w/o decode,  0 on success */
+static int CEscape(int escaped, byte e, byte* out, word32* i, word32 max,
+                  int raw, int getSzOnly)
+{
+    int    doEscape = 0;
+    word32 needed = 1;
+    word32 idx = *i;
+
+    byte basic;
+    byte plus    = 0;
+    byte equals  = 0;
+    byte newline = 0;
+
+    if (raw)
+        basic = e;
+    else
+        basic = base64Encode[e];
+
+    /* check whether to escape. Only escape for EncodeEsc */
+    if (escaped == WC_ESC_NL_ENC) {
+        switch ((char)basic) {
+            case '+' :
+                plus     = 1;
+                doEscape = 1;
+                needed  += 2;
+                break;
+            case '=' :
+                equals   = 1;
+                doEscape = 1;
+                needed  += 2;
+                break;
+            case '\n' :
+                newline  = 1;
+                doEscape = 1;
+                needed  += 2;
+                break;
+            default:
+                /* do nothing */
+                break;
+        }
+    }
+
+    /* check size */
+    if ( (idx+needed) > max && !getSzOnly) {
+        WOLFSSL_MSG("Escape buffer max too small");
+        return BUFFER_E;
+    }
+
+    /* store it */
+    if (doEscape == 0) {
+        if(getSzOnly)
+            idx++;
+        else
+            out[idx++] = basic;
+    }
+    else {
+        if(getSzOnly)
+            idx+=3;
+        else {
+            out[idx++] = '%';  /* start escape */
+
+            if (plus) {
+                out[idx++] = '2';
+                out[idx++] = 'B';
+            }
+            else if (equals) {
+                out[idx++] = '3';
+                out[idx++] = 'D';
+            }
+            else if (newline) {
+                out[idx++] = '0';
+                out[idx++] = 'A';
+            }
+        }
+    }
+    *i = idx;
+
+    return 0;
+}
+
+
+/* internal worker, handles both escaped and normal line endings.
+   If out buffer is NULL, will return sz needed in outLen */
+static int DoBase64_Encode(const byte* in, word32 inLen, byte* out,
+                           word32* outLen, int escaped)
+{
+    int    ret = 0;
+    word32 i = 0,
+           j = 0,
+           n = 0;   /* new line counter */
+
+    int    getSzOnly = (out == NULL);
+
+    word32 outSz = (inLen + 3 - 1) / 3 * 4;
+    word32 addSz = (outSz + PEM_LINE_SZ - 1) / PEM_LINE_SZ;  /* new lines */
+
+    if (escaped == WC_ESC_NL_ENC)
+        addSz *= 3;   /* instead of just \n, we're doing %0A triplet */
+    else if (escaped == WC_NO_NL_ENC)
+        addSz = 0;    /* encode without \n */
+
+    outSz += addSz;
+
+    /* if escaped we can't predetermine size for one pass encoding, but
+     * make sure we have enough if no escapes are in input
+     * Also need to ensure outLen valid before dereference */
+    if (!outLen || (outSz > *outLen && !getSzOnly)) return BAD_FUNC_ARG;
+
+    while (inLen > 2) {
+        byte b1 = in[j++];
+        byte b2 = in[j++];
+        byte b3 = in[j++];
+
+        /* encoded idx */
+        byte e1 = b1 >> 2;
+        byte e2 = (byte)(((b1 & 0x3) << 4) | (b2 >> 4));
+        byte e3 = (byte)(((b2 & 0xF) << 2) | (b3 >> 6));
+        byte e4 = b3 & 0x3F;
+
+        /* store */
+        ret = CEscape(escaped, e1, out, &i, *outLen, 0, getSzOnly);
+        if (ret != 0) break;
+        ret = CEscape(escaped, e2, out, &i, *outLen, 0, getSzOnly);
+        if (ret != 0) break;
+        ret = CEscape(escaped, e3, out, &i, *outLen, 0, getSzOnly);
+        if (ret != 0) break;
+        ret = CEscape(escaped, e4, out, &i, *outLen, 0, getSzOnly);
+        if (ret != 0) break;
+
+        inLen -= 3;
+
+        /* Insert newline after PEM_LINE_SZ, unless no \n requested */
+        if (escaped != WC_NO_NL_ENC && (++n % (PEM_LINE_SZ/4)) == 0 && inLen){
+            ret = CEscape(escaped, '\n', out, &i, *outLen, 1, getSzOnly);
+            if (ret != 0) break;
+        }
+    }
+
+    /* last integral */
+    if (inLen && ret == 0) {
+        int twoBytes = (inLen == 2);
+
+        byte b1 = in[j++];
+        byte b2 = (twoBytes) ? in[j++] : 0;
+
+        byte e1 = b1 >> 2;
+        byte e2 = (byte)(((b1 & 0x3) << 4) | (b2 >> 4));
+        byte e3 = (byte)((b2 & 0xF) << 2);
+
+        ret = CEscape(escaped, e1, out, &i, *outLen, 0, getSzOnly);
+        if (ret == 0)
+            ret = CEscape(escaped, e2, out, &i, *outLen, 0, getSzOnly);
+        if (ret == 0) {
+            /* third */
+            if (twoBytes)
+                ret = CEscape(escaped, e3, out, &i, *outLen, 0, getSzOnly);
+            else
+                ret = CEscape(escaped, '=', out, &i, *outLen, 1, getSzOnly);
+        }
+        /* fourth always pad */
+        if (ret == 0)
+            ret = CEscape(escaped, '=', out, &i, *outLen, 1, getSzOnly);
+    }
+
+    if (ret == 0 && escaped != WC_NO_NL_ENC)
+        ret = CEscape(escaped, '\n', out, &i, *outLen, 1, getSzOnly);
+
+    if (i != outSz && escaped != 1 && ret == 0)
+        return ASN_INPUT_E;
+
+    *outLen = i;
+    if(ret == 0)
+        return getSzOnly ? LENGTH_ONLY_E : 0;
+    return ret;
+}
+
+
+/* Base64 Encode, PEM style, with \n line endings */
+int Base64_Encode(const byte* in, word32 inLen, byte* out, word32* outLen)
+{
+    return DoBase64_Encode(in, inLen, out, outLen, WC_STD_ENC);
+}
+
+
+/* Base64 Encode, with %0A esacped line endings instead of \n */
+int Base64_EncodeEsc(const byte* in, word32 inLen, byte* out, word32* outLen)
+{
+    return DoBase64_Encode(in, inLen, out, outLen, WC_ESC_NL_ENC);
+}
+
+int Base64_Encode_NoNl(const byte* in, word32 inLen, byte* out, word32* outLen)
+{
+    return DoBase64_Encode(in, inLen, out, outLen, WC_NO_NL_ENC);
+}
+
+#endif  /* defined(WOLFSSL_BASE64_ENCODE) */
+
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_FIPS)
+
+static
+const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                           BAD, BAD, BAD, BAD, BAD, BAD, BAD,
+                           10, 11, 12, 13, 14, 15,  /* upper case A-F */
+                           BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
+                           BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
+                           BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
+                           BAD, BAD,  /* G - ` */
+                           10, 11, 12, 13, 14, 15   /* lower case a-f */
+                         };  /* A starts at 0x41 not 0x3A */
+
+int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
+{
+    word32 inIdx  = 0;
+    word32 outIdx = 0;
+
+    if (inLen == 1 && *outLen && in) {
+        byte b = in[inIdx++] - 0x30;  /* 0 starts at 0x30 */
+
+        /* sanity check */
+        if (b >=  sizeof(hexDecode)/sizeof(hexDecode[0]))
+            return ASN_INPUT_E;
+
+        b  = hexDecode[b];
+
+        if (b == BAD)
+            return ASN_INPUT_E;
+        
+        out[outIdx++] = b;
+
+        *outLen = outIdx;
+        return 0;
+    }
+
+    if (inLen % 2)
+        return BAD_FUNC_ARG;
+
+    if (*outLen < (inLen / 2))
+        return BAD_FUNC_ARG;
+
+    while (inLen) {
+        byte b  = in[inIdx++] - 0x30;  /* 0 starts at 0x30 */
+        byte b2 = in[inIdx++] - 0x30;
+
+        /* sanity checks */
+        if (b >=  sizeof(hexDecode)/sizeof(hexDecode[0]))
+            return ASN_INPUT_E;
+        if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0]))
+            return ASN_INPUT_E;
+
+        b  = hexDecode[b];
+        b2 = hexDecode[b2];
+
+        if (b == BAD || b2 == BAD)
+            return ASN_INPUT_E;
+        
+        out[outIdx++] = (byte)((b << 4) | b2);
+        inLen -= 2;
+    }
+
+    *outLen = outIdx;
+    return 0;
+}
+
+int Base16_Encode(const byte* in, word32 inLen, byte* out, word32* outLen)
+{
+    word32 outIdx = 0;
+    word32 i;
+    byte   hb, lb;
+
+    if (*outLen < (2 * inLen + 1))
+        return BAD_FUNC_ARG;
+
+    for (i = 0; i < inLen; i++) {
+        hb = in[i] >> 4;
+        lb = in[i] & 0x0f;
+
+        /* ASCII value */
+        hb += '0';
+        if (hb > '9')
+            hb += 7;
+
+        /* ASCII value */
+        lb += '0';
+        if (lb>'9')
+            lb += 7;
+
+        out[outIdx++] = hb;
+        out[outIdx++] = lb;
+    }
+
+    /* force 0 at this end */
+    out[outIdx++] = 0;
+
+    *outLen = outIdx;
+    return 0;
+}
+
+#endif /* (OPENSSL_EXTRA) || (HAVE_WEBSERVER) || (HAVE_FIPS) */
+
+#endif /* NO_CODING */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/des3.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/des3.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/des3.c	(revision 164)
@@ -0,0 +1,1628 @@
+/* des3.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_DES3
+
+#include <wolfssl/wolfcrypt/des3.h>
+
+#ifdef HAVE_FIPS
+#ifdef HAVE_CAVIUM
+    static int wc_Des3_CaviumSetKey(Des3* des3, const byte* key, const byte* iv);
+    static int wc_Des3_CaviumCbcEncrypt(Des3* des3, byte* out, const byte* in,
+                                      word32 length);
+    static int wc_Des3_CaviumCbcDecrypt(Des3* des3, byte* out, const byte* in,
+                                      word32 length);
+#endif
+
+int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
+{
+    return Des_SetKey(des, key, iv, dir);
+}
+
+
+int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
+{
+    return Des3_SetKey_fips(des, key, iv, dir);
+}
+
+
+int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+{
+    return Des_CbcEncrypt(des, out, in, sz);
+}
+
+
+int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
+{
+    return Des_CbcDecrypt(des, out, in, sz);
+}
+
+
+int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+{
+    return Des3_CbcEncrypt_fips(des, out, in, sz);
+}
+
+
+int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
+{
+    return Des3_CbcDecrypt_fips(des, out, in, sz);
+}
+
+
+#ifdef WOLFSSL_DES_ECB
+
+/* One block, compatibility only */
+int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+{
+    return Des_EcbEncrypt(des, out, in, sz);
+}
+
+#endif /* WOLFSSL_DES_ECB */
+
+
+void wc_Des_SetIV(Des* des, const byte* iv)
+{
+    Des_SetIV(des, iv);
+}
+
+
+int wc_Des3_SetIV(Des3* des, const byte* iv)
+{
+    return Des3_SetIV_fips(des, iv);
+}
+
+
+#ifdef HAVE_CAVIUM
+
+/* Initiliaze Des3 for use with Nitrox device */
+int wc_Des3_InitCavium(Des3* des3, int devId)
+{
+    return Des3_InitCavium(des3, devId);
+}
+
+
+/* Free Des3 from use with Nitrox device */
+void wc_Des3_FreeCavium(Des3* des3)
+{
+    Des3_FreeCavium(des3);
+}
+
+
+#endif /* HAVE_CAVIUM */
+#else /* build without fips */
+
+#if defined(WOLFSSL_TI_CRYPT)
+    #include <wolfcrypt/src/port/ti/ti-des3.c>
+#else
+
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+
+#ifdef HAVE_CAVIUM
+    static int wc_Des3_CaviumSetKey(Des3* des3, const byte* key, const byte* iv);
+    static int wc_Des3_CaviumCbcEncrypt(Des3* des3, byte* out, const byte* in,
+                                      word32 length);
+    static int wc_Des3_CaviumCbcDecrypt(Des3* des3, byte* out, const byte* in,
+                                      word32 length);
+#endif
+
+
+
+
+#ifdef STM32F2_CRYPTO
+    /*
+     * STM32F2 hardware DES/3DES support through the STM32F2 standard
+     * peripheral library. Documentation located in STM32F2xx Standard
+     * Peripheral Library document (See note in README).
+     */
+    #include "stm32f2xx.h"
+		#include "stm32f2xx_cryp.h"
+
+    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
+    {
+        word32 *dkey = des->key;
+
+        XMEMCPY(dkey, key, 8);
+        ByteReverseWords(dkey, dkey, 8);
+
+        wc_Des_SetIV(des, iv);
+
+        return 0;
+    }
+
+    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
+    {
+        word32 *dkey1 = des->key[0];
+        word32 *dkey2 = des->key[1];
+        word32 *dkey3 = des->key[2];
+
+        XMEMCPY(dkey1, key, 8);         /* set key 1 */
+        XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */
+        XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */
+
+        ByteReverseWords(dkey1, dkey1, 8);
+        ByteReverseWords(dkey2, dkey2, 8);
+        ByteReverseWords(dkey3, dkey3, 8);
+
+        return wc_Des3_SetIV(des, iv);
+    }
+
+    void DesCrypt(Des* des, byte* out, const byte* in, word32 sz,
+                  int dir, int mode)
+    {
+        word32 *dkey, *iv;
+        CRYP_InitTypeDef DES_CRYP_InitStructure;
+        CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure;
+        CRYP_IVInitTypeDef DES_CRYP_IVInitStructure;
+
+        dkey = des->key;
+        iv = des->reg;
+
+        /* crypto structure initialization */
+        CRYP_KeyStructInit(&DES_CRYP_KeyInitStructure);
+        CRYP_StructInit(&DES_CRYP_InitStructure);
+        CRYP_IVStructInit(&DES_CRYP_IVInitStructure);
+
+        /* reset registers to their default values */
+        CRYP_DeInit();
+
+        /* set direction, mode, and datatype */
+        if (dir == DES_ENCRYPTION) {
+            DES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
+        } else { /* DES_DECRYPTION */
+            DES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
+        }
+
+        if (mode == DES_CBC) {
+            DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_CBC;
+        } else { /* DES_ECB */
+            DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_ECB;
+        }
+
+        DES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
+        CRYP_Init(&DES_CRYP_InitStructure);
+
+        /* load key into correct registers */
+        DES_CRYP_KeyInitStructure.CRYP_Key1Left  = dkey[0];
+        DES_CRYP_KeyInitStructure.CRYP_Key1Right = dkey[1];
+        CRYP_KeyInit(&DES_CRYP_KeyInitStructure);
+
+        /* set iv */
+        ByteReverseWords(iv, iv, DES_BLOCK_SIZE);
+        DES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
+        DES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
+        CRYP_IVInit(&DES_CRYP_IVInitStructure);
+
+        /* enable crypto processor */
+        CRYP_Cmd(ENABLE);
+
+        while (sz > 0)
+        {
+            /* flush IN/OUT FIFOs */
+            CRYP_FIFOFlush();
+
+            /* if input and output same will overwrite input iv */
+            XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
+
+            CRYP_DataIn(*(uint32_t*)&in[0]);
+            CRYP_DataIn(*(uint32_t*)&in[4]);
+
+            /* wait until the complete message has been processed */
+            while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+            *(uint32_t*)&out[0]  = CRYP_DataOut();
+            *(uint32_t*)&out[4]  = CRYP_DataOut();
+
+            /* store iv for next call */
+            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
+
+            sz  -= DES_BLOCK_SIZE;
+            in  += DES_BLOCK_SIZE;
+            out += DES_BLOCK_SIZE;
+        }
+
+        /* disable crypto processor */
+        CRYP_Cmd(DISABLE);
+    }
+
+    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_CBC);
+        return 0;
+    }
+
+    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        DesCrypt(des, out, in, sz, DES_DECRYPTION, DES_CBC);
+        return 0;
+    }
+
+    int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_ECB);
+        return 0;
+    }
+
+    void Des3Crypt(Des3* des, byte* out, const byte* in, word32 sz,
+                   int dir)
+    {
+        word32 *dkey1, *dkey2, *dkey3, *iv;
+        CRYP_InitTypeDef DES3_CRYP_InitStructure;
+        CRYP_KeyInitTypeDef DES3_CRYP_KeyInitStructure;
+        CRYP_IVInitTypeDef DES3_CRYP_IVInitStructure;
+
+        dkey1 = des->key[0];
+        dkey2 = des->key[1];
+        dkey3 = des->key[2];
+        iv = des->reg;
+
+        /* crypto structure initialization */
+        CRYP_KeyStructInit(&DES3_CRYP_KeyInitStructure);
+        CRYP_StructInit(&DES3_CRYP_InitStructure);
+        CRYP_IVStructInit(&DES3_CRYP_IVInitStructure);
+
+        /* reset registers to their default values */
+        CRYP_DeInit();
+
+        /* set direction, mode, and datatype */
+        if (dir == DES_ENCRYPTION) {
+            DES3_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
+        } else {
+            DES3_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
+        }
+
+        DES3_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_TDES_CBC;
+        DES3_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
+        CRYP_Init(&DES3_CRYP_InitStructure);
+
+        /* load key into correct registers */
+        DES3_CRYP_KeyInitStructure.CRYP_Key1Left  = dkey1[0];
+        DES3_CRYP_KeyInitStructure.CRYP_Key1Right = dkey1[1];
+        DES3_CRYP_KeyInitStructure.CRYP_Key2Left  = dkey2[0];
+        DES3_CRYP_KeyInitStructure.CRYP_Key2Right = dkey2[1];
+        DES3_CRYP_KeyInitStructure.CRYP_Key3Left  = dkey3[0];
+        DES3_CRYP_KeyInitStructure.CRYP_Key3Right = dkey3[1];
+        CRYP_KeyInit(&DES3_CRYP_KeyInitStructure);
+
+        /* set iv */
+        ByteReverseWords(iv, iv, DES_BLOCK_SIZE);
+        DES3_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
+        DES3_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
+        CRYP_IVInit(&DES3_CRYP_IVInitStructure);
+
+        /* enable crypto processor */
+        CRYP_Cmd(ENABLE);
+
+        while (sz > 0)
+        {
+            /* flush IN/OUT FIFOs */
+            CRYP_FIFOFlush();
+
+            CRYP_DataIn(*(uint32_t*)&in[0]);
+            CRYP_DataIn(*(uint32_t*)&in[4]);
+
+            /* wait until the complete message has been processed */
+            while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
+
+            *(uint32_t*)&out[0]  = CRYP_DataOut();
+            *(uint32_t*)&out[4]  = CRYP_DataOut();
+
+            /* store iv for next call */
+            XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
+
+            sz  -= DES_BLOCK_SIZE;
+            in  += DES_BLOCK_SIZE;
+            out += DES_BLOCK_SIZE;
+        }
+
+        /* disable crypto processor */
+        CRYP_Cmd(DISABLE);
+
+    }
+
+    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        Des3Crypt(des, out, in, sz, DES_ENCRYPTION);
+        return 0;
+    }
+
+    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        Des3Crypt(des, out, in, sz, DES_DECRYPTION);
+        return 0;
+    }
+
+#elif defined(HAVE_COLDFIRE_SEC)
+
+#include <wolfssl/ctaocrypt/types.h>
+
+#include "sec.h"
+#include "mcf5475_sec.h"
+#include "mcf5475_siu.h"
+
+#if defined (HAVE_THREADX)
+#include "memory_pools.h"
+extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
+#endif
+
+#define DES_BUFFER_SIZE (DES_BLOCK_SIZE * 64)
+static unsigned char *desBuffIn = NULL ;
+static unsigned char *desBuffOut = NULL ;
+static byte *secIV ; 
+static byte *secKey ; 
+static volatile SECdescriptorType *secDesc ;
+
+static wolfSSL_Mutex Mutex_DesSEC ;
+
+#define SEC_DESC_DES_CBC_ENCRYPT  0x20500010
+#define SEC_DESC_DES_CBC_DECRYPT  0x20400010
+#define SEC_DESC_DES3_CBC_ENCRYPT 0x20700010
+#define SEC_DESC_DES3_CBC_DECRYPT 0x20600010
+
+#define DES_IVLEN 8
+#define DES_KEYLEN 8
+#define DES3_IVLEN 8
+#define DES3_KEYLEN 24
+
+extern volatile unsigned char __MBAR[];
+
+static void wc_Des_Cbc(byte* out, const byte* in, word32 sz, 
+                    byte *key, byte *iv, word32 desc)
+{
+    #ifdef DEBUG_WOLFSSL
+    int ret ;  int stat1,stat2 ; 
+	  #endif
+    int size ;
+    volatile int v ;
+ 
+    LockMutex(&Mutex_DesSEC) ;
+    
+    secDesc->length1 = 0x0;
+    secDesc->pointer1 = NULL;
+    if((desc==SEC_DESC_DES_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_DECRYPT)){
+        secDesc->length2 = DES_IVLEN ;  
+        secDesc->length3 = DES_KEYLEN ;
+    } else {
+        secDesc->length2 = DES3_IVLEN ; 
+        secDesc->length3 = DES3_KEYLEN ;
+    }
+    secDesc->pointer2 = secIV ;
+    secDesc->pointer3 = secKey;
+    secDesc->pointer4 = desBuffIn ;
+    secDesc->pointer5 = desBuffOut ;
+    secDesc->length6 = 0; 
+    secDesc->pointer6 = NULL; 
+    secDesc->length7 = 0x0;
+    secDesc->pointer7 = NULL;
+    secDesc->nextDescriptorPtr = NULL ; 
+    
+    while(sz) {
+        XMEMCPY(secIV, iv, secDesc->length2) ;
+        if((sz%DES_BUFFER_SIZE) == sz) {
+            size = sz ;
+            sz = 0 ;
+        } else {
+            size = DES_BUFFER_SIZE ;
+            sz -= DES_BUFFER_SIZE ;
+        }
+        
+        XMEMCPY(desBuffIn, in, size) ;
+        XMEMCPY(secKey, key, secDesc->length3) ;
+        
+        secDesc->header = desc ;
+        secDesc->length4 = size;
+        secDesc->length5 = size;
+        /* Point SEC to the location of the descriptor */
+        MCF_SEC_FR0 = (uint32)secDesc;
+        /* Initialize SEC and wait for encryption to complete */
+        MCF_SEC_CCCR0 = 0x0000001a;
+        /* poll SISR to determine when channel is complete */
+        v=0 ;
+        while((secDesc->header>> 24) != 0xff) {
+            if(v++ > 1000)break ;
+        }
+				
+#ifdef DEBUG_WOLFSSL
+        ret = MCF_SEC_SISRH;
+        stat1 = MCF_SEC_DSR ; 
+        stat2 = MCF_SEC_DISR ; 
+        if(ret & 0xe0000000) {
+            /* db_printf("Des_Cbc(%x):ISRH=%08x, DSR=%08x, DISR=%08x\n", desc, ret, stat1, stat2) ; */
+        }
+#endif
+				
+        XMEMCPY(out, desBuffOut, size) ;
+
+        if((desc==SEC_DESC_DES3_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_ENCRYPT)) {
+            XMEMCPY((void*)iv, (void*)&(out[size-secDesc->length2]), secDesc->length2) ;
+        } else {
+            XMEMCPY((void*)iv, (void*)&(in[size-secDesc->length2]), secDesc->length2) ;
+        }
+        
+        in  += size ;   
+        out += size ;
+                
+    }
+    UnLockMutex(&Mutex_DesSEC) ;
+    
+}
+
+
+int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+{
+    wc_Des_Cbc(out, in, sz,  (byte *)des->key,  (byte *)des->reg, SEC_DESC_DES_CBC_ENCRYPT) ;
+    return 0;
+}
+
+int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
+{
+    wc_Des_Cbc(out, in, sz,   (byte *)des->key,  (byte *)des->reg, SEC_DESC_DES_CBC_DECRYPT) ;
+    return 0;
+}
+
+int wc_Des3_CbcEncrypt(Des3* des3, byte* out, const byte* in, word32 sz)
+{
+    wc_Des_Cbc(out, in, sz,  (byte *)des3->key,  (byte *)des3->reg, SEC_DESC_DES3_CBC_ENCRYPT) ;
+	  return 0;
+}
+
+
+int wc_Des3_CbcDecrypt(Des3* des3, byte* out, const byte* in, word32 sz)
+{
+    wc_Des_Cbc(out, in, sz,   (byte *)des3->key,  (byte *)des3->reg, SEC_DESC_DES3_CBC_DECRYPT) ;
+	  return 0;
+}
+
+static void setParity(byte *buf, int len) 
+{
+    int i, j ;
+    byte v ;
+    int bits ;
+
+    for(i=0; i<len; i++) 
+    {
+        v = buf[i] >> 1 ;
+        buf[i] = v << 1 ;
+        bits = 0 ;
+        for(j=0; j<7; j++)
+        {
+            bits += (v&0x1) ;
+            v = v >> 1 ;
+        }
+        buf[i] |= (1 - (bits&0x1)) ;
+    }
+    
+}
+
+
+int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
+{
+    if(desBuffIn == NULL) {
+        #if defined (HAVE_THREADX)
+			  int s1, s2, s3, s4, s5 ;
+        s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc, 
+                                                     sizeof(SECdescriptorType), TX_NO_WAIT);
+        s1 = tx_byte_allocate(&mp_ncached,(void *)&desBuffIn,  DES_BUFFER_SIZE, TX_NO_WAIT);
+        s2 = tx_byte_allocate(&mp_ncached,(void *)&desBuffOut, DES_BUFFER_SIZE, TX_NO_WAIT);
+        /* Don't know des or des3 to be used. Allocate larger buffers */
+        s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey,     DES3_KEYLEN,TX_NO_WAIT);
+        s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV,      DES3_IVLEN,  TX_NO_WAIT);              
+        #else
+        #warning "Allocate non-Cache buffers"
+        #endif
+        
+        InitMutex(&Mutex_DesSEC) ;
+    }
+     
+    XMEMCPY(des->key, key, DES_KEYLEN);  
+    setParity((byte *)des->key, DES_KEYLEN) ;  
+		
+    if (iv) {
+        XMEMCPY(des->reg, iv, DES_IVLEN);
+    }   else {
+        XMEMSET(des->reg, 0x0, DES_IVLEN) ;
+    }
+		return 0;
+}
+
+int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
+{
+    
+    if(desBuffIn == NULL) {
+        #if defined (HAVE_THREADX)
+			  int s1, s2, s3, s4, s5 ;
+        s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc, 
+                                                     sizeof(SECdescriptorType), TX_NO_WAIT);
+        s1 = tx_byte_allocate(&mp_ncached,(void *)&desBuffIn,  DES_BUFFER_SIZE, TX_NO_WAIT);
+        s2 = tx_byte_allocate(&mp_ncached,(void *)&desBuffOut, DES_BUFFER_SIZE, TX_NO_WAIT);
+        s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey,     DES3_KEYLEN,TX_NO_WAIT);
+        s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV,      DES3_IVLEN,  TX_NO_WAIT);              
+        #else
+        #warning "Allocate non-Cache buffers"
+        #endif
+        
+        InitMutex(&Mutex_DesSEC) ;
+    }
+    
+    XMEMCPY(des3->key[0], key, DES3_KEYLEN); 
+    setParity((byte *)des3->key[0], DES3_KEYLEN) ;  
+		
+    if (iv) {
+        XMEMCPY(des3->reg, iv, DES3_IVLEN);
+    }   else {
+        XMEMSET(des3->reg, 0x0, DES3_IVLEN) ;
+    }
+    return 0;
+
+}
+
+#elif defined FREESCALE_MMCAU
+    /*
+     * Freescale mmCAU hardware DES/3DES support through the CAU/mmCAU library.
+     * Documentation located in ColdFire/ColdFire+ CAU and Kinetis mmCAU
+     * Software Library User Guide (See note in README).
+     */
+    #include "cau_api.h"
+
+    const unsigned char parityLookup[128] =
+    {
+        1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+        0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+        0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+        1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
+     };
+
+    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
+    {
+        int i = 0;
+        byte* dkey = (byte*)des->key;
+
+        XMEMCPY(dkey, key, 8);
+
+        wc_Des_SetIV(des, iv);
+
+        /* fix key parity, if needed */
+        for (i = 0; i < 8; i++) {
+            dkey[i] = ((dkey[i] & 0xFE) | parityLookup[dkey[i] >> 1]);
+        }
+
+        return 0;
+    }
+
+    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
+    {
+        int i = 0, ret = 0;
+        byte* dkey1 = (byte*)des->key[0];
+        byte* dkey2 = (byte*)des->key[1];
+        byte* dkey3 = (byte*)des->key[2];
+
+        XMEMCPY(dkey1, key, 8);         /* set key 1 */
+        XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */
+        XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */
+
+        ret = wc_Des3_SetIV(des, iv);
+        if (ret != 0)
+            return ret;
+
+        /* fix key parity if needed */
+        for (i = 0; i < 8; i++)
+           dkey1[i] = ((dkey1[i] & 0xFE) | parityLookup[dkey1[i] >> 1]);
+
+        for (i = 0; i < 8; i++)
+           dkey2[i] = ((dkey2[i] & 0xFE) | parityLookup[dkey2[i] >> 1]);
+
+        for (i = 0; i < 8; i++)
+           dkey3[i] = ((dkey3[i] & 0xFE) | parityLookup[dkey3[i] >> 1]);
+
+        return ret;
+    }
+
+    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        int i;
+        int offset = 0;
+        int len = sz;
+        int ret = 0;
+        byte *iv;
+        byte temp_block[DES_BLOCK_SIZE];
+
+        iv = (byte*)des->reg;
+
+        if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
+            WOLFSSL_MSG("Bad cau_des_encrypt alignment"); 
+            return BAD_ALIGN_E;
+        }
+
+        while (len > 0)
+        {
+            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
+
+            /* XOR block with IV for CBC */
+            for (i = 0; i < DES_BLOCK_SIZE; i++)
+                temp_block[i] ^= iv[i];
+
+            ret = wolfSSL_CryptHwMutexLock();
+            if(ret != 0) {
+                return ret;
+            }
+            cau_des_encrypt(temp_block, (byte*)des->key, out + offset);
+            wolfSSL_CryptHwMutexUnLock();
+
+            len    -= DES_BLOCK_SIZE;
+            offset += DES_BLOCK_SIZE;
+
+            /* store IV for next block */
+            XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
+        }
+
+        return ret;
+    }
+
+    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        int i;
+        int offset = 0;
+        int len = sz;
+        int ret = 0;
+        byte* iv;
+        byte temp_block[DES_BLOCK_SIZE];
+
+        iv = (byte*)des->reg;
+
+        if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
+            WOLFSSL_MSG("Bad cau_des_decrypt alignment"); 
+            return BAD_ALIGN_E;
+        }
+
+        while (len > 0)
+        {
+            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
+
+            ret = wolfSSL_CryptHwMutexLock();
+            if(ret != 0) {
+                return ret;
+            }
+            cau_des_decrypt(in + offset, (byte*)des->key, out + offset);
+            wolfSSL_CryptHwMutexUnLock();
+
+            /* XOR block with IV for CBC */
+            for (i = 0; i < DES_BLOCK_SIZE; i++)
+                (out + offset)[i] ^= iv[i];
+
+            /* store IV for next block */
+            XMEMCPY(iv, temp_block, DES_BLOCK_SIZE);
+
+            len     -= DES_BLOCK_SIZE;
+            offset += DES_BLOCK_SIZE;
+        }
+
+        return ret;
+    }
+
+    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        int i;
+        int offset = 0;
+        int len = sz;
+        int ret = 0;
+
+        byte *iv;
+        byte temp_block[DES_BLOCK_SIZE];
+
+        iv = (byte*)des->reg;
+
+        if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
+            WOLFSSL_MSG("Bad 3ede cau_des_encrypt alignment"); 
+            return BAD_ALIGN_E;
+        }
+
+        while (len > 0)
+        {
+            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
+
+            /* XOR block with IV for CBC */
+            for (i = 0; i < DES_BLOCK_SIZE; i++)
+                temp_block[i] ^= iv[i];
+
+            ret = wolfSSL_CryptHwMutexLock();
+            if(ret != 0) {
+                return ret;
+            }
+            cau_des_encrypt(temp_block  , (byte*)des->key[0], out + offset);
+            cau_des_decrypt(out + offset, (byte*)des->key[1], out + offset);
+            cau_des_encrypt(out + offset, (byte*)des->key[2], out + offset);
+            wolfSSL_CryptHwMutexUnLock();
+
+            len    -= DES_BLOCK_SIZE;
+            offset += DES_BLOCK_SIZE;
+
+            /* store IV for next block */
+            XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
+        }
+
+        return ret;
+    }
+
+    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        int i;
+        int offset = 0;
+        int len = sz;
+        int ret = 0;
+
+        byte* iv;
+        byte temp_block[DES_BLOCK_SIZE];
+
+        iv = (byte*)des->reg;
+
+        if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
+            WOLFSSL_MSG("Bad 3ede cau_des_decrypt alignment"); 
+            return BAD_ALIGN_E;
+        }
+
+        while (len > 0)
+        {
+            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
+
+            ret = wolfSSL_CryptHwMutexLock();
+            if(ret != 0) {
+                return ret;
+            }
+            cau_des_decrypt(in + offset , (byte*)des->key[2], out + offset);
+            cau_des_encrypt(out + offset, (byte*)des->key[1], out + offset);
+            cau_des_decrypt(out + offset, (byte*)des->key[0], out + offset);
+            wolfSSL_CryptHwMutexUnLock();
+
+            /* XOR block with IV for CBC */
+            for (i = 0; i < DES_BLOCK_SIZE; i++)
+                (out + offset)[i] ^= iv[i];
+
+            /* store IV for next block */
+            XMEMCPY(iv, temp_block, DES_BLOCK_SIZE);
+
+            len    -= DES_BLOCK_SIZE;
+            offset += DES_BLOCK_SIZE;
+        }
+
+        return ret;
+    }
+
+
+#elif defined(WOLFSSL_PIC32MZ_CRYPT)
+
+    #include "wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h"
+
+void wc_Des_SetIV(Des* des, const byte* iv);
+int  wc_Des3_SetIV(Des3* des, const byte* iv);
+
+    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
+    {
+        word32 *dkey = des->key ;
+        word32 *dreg = des->reg ;
+
+        XMEMCPY((byte *)dkey, (byte *)key, 8);
+        ByteReverseWords(dkey, dkey, 8);
+        XMEMCPY((byte *)dreg, (byte *)iv, 8);
+        ByteReverseWords(dreg, dreg, 8);
+
+        return 0;
+    }
+
+    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
+    {
+        word32 *dkey1 = des->key[0];
+        word32 *dreg = des->reg ;
+
+        XMEMCPY(dkey1, key, 24);
+        ByteReverseWords(dkey1, dkey1, 24);
+        XMEMCPY(dreg, iv, 8);
+        ByteReverseWords(dreg, dreg, 8) ;
+
+        return 0;
+    }
+
+    void DesCrypt(word32 *key, word32 *iv, byte* out, const byte* in, word32 sz,
+                  int dir, int algo, int cryptoalgo)
+    {
+        securityAssociation *sa_p ;
+        bufferDescriptor *bd_p ;
+        const byte *in_p, *in_l ;
+        byte *out_p, *out_l ;
+        volatile securityAssociation sa __attribute__((aligned (8)));
+        volatile bufferDescriptor bd __attribute__((aligned (8)));
+        volatile int k ;
+        
+        /* get uncached address */
+
+        in_l = in;
+        out_l = out ;
+        sa_p = KVA0_TO_KVA1(&sa) ; 
+        bd_p = KVA0_TO_KVA1(&bd) ;
+        in_p = KVA0_TO_KVA1(in_l) ;
+        out_p= KVA0_TO_KVA1(out_l);
+        
+        if(PIC32MZ_IF_RAM(in_p))
+            XMEMCPY((void *)in_p, (void *)in, sz);
+        XMEMSET((void *)out_p, 0, sz);
+
+        /* Set up the Security Association */
+        XMEMSET((byte *)KVA0_TO_KVA1(&sa), 0, sizeof(sa));
+        sa_p->SA_CTRL.ALGO = algo ; 
+        sa_p->SA_CTRL.LNC = 1;
+        sa_p->SA_CTRL.LOADIV = 1;
+        sa_p->SA_CTRL.FB = 1;
+        sa_p->SA_CTRL.ENCTYPE = dir ; /* Encryption/Decryption */
+        sa_p->SA_CTRL.CRYPTOALGO = cryptoalgo;
+        sa_p->SA_CTRL.KEYSIZE = 1 ; /* KEY is 192 bits */
+        XMEMCPY((byte *)KVA0_TO_KVA1(&sa.SA_ENCKEY[algo==PIC32_ALGO_TDES ? 2 : 6]),
+                (byte *)key, algo==PIC32_ALGO_TDES ? 24 : 8);
+        XMEMCPY((byte *)KVA0_TO_KVA1(&sa.SA_ENCIV[2]), (byte *)iv, 8);
+
+        XMEMSET((byte *)KVA0_TO_KVA1(&bd), 0, sizeof(bd));
+        /* Set up the Buffer Descriptor */
+        bd_p->BD_CTRL.BUFLEN = sz;
+        bd_p->BD_CTRL.LIFM = 1;
+        bd_p->BD_CTRL.SA_FETCH_EN = 1;
+        bd_p->BD_CTRL.LAST_BD = 1;
+        bd_p->BD_CTRL.DESC_EN = 1;
+    
+        bd_p->SA_ADDR = (unsigned int)KVA_TO_PA(&sa) ; /* (unsigned int)sa_p; */
+        bd_p->SRCADDR = (unsigned int)KVA_TO_PA(in) ; /* (unsigned int)in_p; */
+        bd_p->DSTADDR = (unsigned int)KVA_TO_PA(out); /* (unsigned int)out_p; */
+        bd_p->NXTPTR = (unsigned int)KVA_TO_PA(&bd);
+        bd_p->MSGLEN = sz ;
+        
+        /* Fire in the hole! */
+        CECON = 1 << 6;
+        while (CECON);
+        
+        /* Run the engine */
+        CEBDPADDR = (unsigned int)KVA_TO_PA(&bd) ; /* (unsigned int)bd_p ; */
+        CEINTEN = 0x07;
+        CECON = 0x27;
+
+        WAIT_ENGINE ;
+
+        if((cryptoalgo == PIC32_CRYPTOALGO_CBC) ||
+           (cryptoalgo == PIC32_CRYPTOALGO_TCBC)||
+           (cryptoalgo == PIC32_CRYPTOALGO_RCBC)) {
+            /* set iv for the next call */
+            if(dir == PIC32_ENCRYPTION) {
+	        XMEMCPY((void *)iv, (void*)&(out_p[sz-DES_IVLEN]), DES_IVLEN) ;
+	        } else {
+                ByteReverseWords((word32*)iv, (word32 *)&(in_p[sz-DES_IVLEN]),
+                                 DES_IVLEN);
+	        }
+
+        }
+
+        ByteReverseWords((word32*)out, (word32 *)KVA0_TO_KVA1(out), sz);
+    }
+
+    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        DesCrypt(des->key, des->reg, out, in, sz, 
+                PIC32_ENCRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC );
+        return 0;
+    }
+
+    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
+    {
+        DesCrypt(des->key, des->reg, out, in, sz, 
+                PIC32_DECRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC);
+        return 0;
+    }
+
+    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        DesCrypt(des->key[0], des->reg, out, in, sz, 
+                PIC32_ENCRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC);
+        return 0;
+    }
+
+    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
+    {
+        DesCrypt(des->key[0], des->reg, out, in, sz, 
+                PIC32_DECRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC);
+        return 0;
+    }
+    
+#else /* CTaoCrypt software implementation */
+
+/* permuted choice table (key) */
+static const byte pc1[] = {
+       57, 49, 41, 33, 25, 17,  9,
+        1, 58, 50, 42, 34, 26, 18,
+       10,  2, 59, 51, 43, 35, 27,
+       19, 11,  3, 60, 52, 44, 36,
+
+       63, 55, 47, 39, 31, 23, 15,
+        7, 62, 54, 46, 38, 30, 22,
+       14,  6, 61, 53, 45, 37, 29,
+       21, 13,  5, 28, 20, 12,  4
+};
+
+/* number left rotations of pc1 */
+static const byte totrot[] = {
+       1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
+};
+
+/* permuted choice key (table) */
+static const byte pc2[] = {
+       14, 17, 11, 24,  1,  5,
+        3, 28, 15,  6, 21, 10,
+       23, 19, 12,  4, 26,  8,
+       16,  7, 27, 20, 13,  2,
+       41, 52, 31, 37, 47, 55,
+       30, 40, 51, 45, 33, 48,
+       44, 49, 39, 56, 34, 53,
+       46, 42, 50, 36, 29, 32
+};
+
+/* End of DES-defined tables */
+
+/* bit 0 is left-most in byte */
+static const int bytebit[] = {
+       0200,0100,040,020,010,04,02,01
+};
+
+static const word32 Spbox[8][64] = {
+{
+0x01010400,0x00000000,0x00010000,0x01010404,
+0x01010004,0x00010404,0x00000004,0x00010000,
+0x00000400,0x01010400,0x01010404,0x00000400,
+0x01000404,0x01010004,0x01000000,0x00000004,
+0x00000404,0x01000400,0x01000400,0x00010400,
+0x00010400,0x01010000,0x01010000,0x01000404,
+0x00010004,0x01000004,0x01000004,0x00010004,
+0x00000000,0x00000404,0x00010404,0x01000000,
+0x00010000,0x01010404,0x00000004,0x01010000,
+0x01010400,0x01000000,0x01000000,0x00000400,
+0x01010004,0x00010000,0x00010400,0x01000004,
+0x00000400,0x00000004,0x01000404,0x00010404,
+0x01010404,0x00010004,0x01010000,0x01000404,
+0x01000004,0x00000404,0x00010404,0x01010400,
+0x00000404,0x01000400,0x01000400,0x00000000,
+0x00010004,0x00010400,0x00000000,0x01010004},
+{
+0x80108020,0x80008000,0x00008000,0x00108020,
+0x00100000,0x00000020,0x80100020,0x80008020,
+0x80000020,0x80108020,0x80108000,0x80000000,
+0x80008000,0x00100000,0x00000020,0x80100020,
+0x00108000,0x00100020,0x80008020,0x00000000,
+0x80000000,0x00008000,0x00108020,0x80100000,
+0x00100020,0x80000020,0x00000000,0x00108000,
+0x00008020,0x80108000,0x80100000,0x00008020,
+0x00000000,0x00108020,0x80100020,0x00100000,
+0x80008020,0x80100000,0x80108000,0x00008000,
+0x80100000,0x80008000,0x00000020,0x80108020,
+0x00108020,0x00000020,0x00008000,0x80000000,
+0x00008020,0x80108000,0x00100000,0x80000020,
+0x00100020,0x80008020,0x80000020,0x00100020,
+0x00108000,0x00000000,0x80008000,0x00008020,
+0x80000000,0x80100020,0x80108020,0x00108000},
+{
+0x00000208,0x08020200,0x00000000,0x08020008,
+0x08000200,0x00000000,0x00020208,0x08000200,
+0x00020008,0x08000008,0x08000008,0x00020000,
+0x08020208,0x00020008,0x08020000,0x00000208,
+0x08000000,0x00000008,0x08020200,0x00000200,
+0x00020200,0x08020000,0x08020008,0x00020208,
+0x08000208,0x00020200,0x00020000,0x08000208,
+0x00000008,0x08020208,0x00000200,0x08000000,
+0x08020200,0x08000000,0x00020008,0x00000208,
+0x00020000,0x08020200,0x08000200,0x00000000,
+0x00000200,0x00020008,0x08020208,0x08000200,
+0x08000008,0x00000200,0x00000000,0x08020008,
+0x08000208,0x00020000,0x08000000,0x08020208,
+0x00000008,0x00020208,0x00020200,0x08000008,
+0x08020000,0x08000208,0x00000208,0x08020000,
+0x00020208,0x00000008,0x08020008,0x00020200},
+{
+0x00802001,0x00002081,0x00002081,0x00000080,
+0x00802080,0x00800081,0x00800001,0x00002001,
+0x00000000,0x00802000,0x00802000,0x00802081,
+0x00000081,0x00000000,0x00800080,0x00800001,
+0x00000001,0x00002000,0x00800000,0x00802001,
+0x00000080,0x00800000,0x00002001,0x00002080,
+0x00800081,0x00000001,0x00002080,0x00800080,
+0x00002000,0x00802080,0x00802081,0x00000081,
+0x00800080,0x00800001,0x00802000,0x00802081,
+0x00000081,0x00000000,0x00000000,0x00802000,
+0x00002080,0x00800080,0x00800081,0x00000001,
+0x00802001,0x00002081,0x00002081,0x00000080,
+0x00802081,0x00000081,0x00000001,0x00002000,
+0x00800001,0x00002001,0x00802080,0x00800081,
+0x00002001,0x00002080,0x00800000,0x00802001,
+0x00000080,0x00800000,0x00002000,0x00802080},
+{
+0x00000100,0x02080100,0x02080000,0x42000100,
+0x00080000,0x00000100,0x40000000,0x02080000,
+0x40080100,0x00080000,0x02000100,0x40080100,
+0x42000100,0x42080000,0x00080100,0x40000000,
+0x02000000,0x40080000,0x40080000,0x00000000,
+0x40000100,0x42080100,0x42080100,0x02000100,
+0x42080000,0x40000100,0x00000000,0x42000000,
+0x02080100,0x02000000,0x42000000,0x00080100,
+0x00080000,0x42000100,0x00000100,0x02000000,
+0x40000000,0x02080000,0x42000100,0x40080100,
+0x02000100,0x40000000,0x42080000,0x02080100,
+0x40080100,0x00000100,0x02000000,0x42080000,
+0x42080100,0x00080100,0x42000000,0x42080100,
+0x02080000,0x00000000,0x40080000,0x42000000,
+0x00080100,0x02000100,0x40000100,0x00080000,
+0x00000000,0x40080000,0x02080100,0x40000100},
+{
+0x20000010,0x20400000,0x00004000,0x20404010,
+0x20400000,0x00000010,0x20404010,0x00400000,
+0x20004000,0x00404010,0x00400000,0x20000010,
+0x00400010,0x20004000,0x20000000,0x00004010,
+0x00000000,0x00400010,0x20004010,0x00004000,
+0x00404000,0x20004010,0x00000010,0x20400010,
+0x20400010,0x00000000,0x00404010,0x20404000,
+0x00004010,0x00404000,0x20404000,0x20000000,
+0x20004000,0x00000010,0x20400010,0x00404000,
+0x20404010,0x00400000,0x00004010,0x20000010,
+0x00400000,0x20004000,0x20000000,0x00004010,
+0x20000010,0x20404010,0x00404000,0x20400000,
+0x00404010,0x20404000,0x00000000,0x20400010,
+0x00000010,0x00004000,0x20400000,0x00404010,
+0x00004000,0x00400010,0x20004010,0x00000000,
+0x20404000,0x20000000,0x00400010,0x20004010},
+{
+0x00200000,0x04200002,0x04000802,0x00000000,
+0x00000800,0x04000802,0x00200802,0x04200800,
+0x04200802,0x00200000,0x00000000,0x04000002,
+0x00000002,0x04000000,0x04200002,0x00000802,
+0x04000800,0x00200802,0x00200002,0x04000800,
+0x04000002,0x04200000,0x04200800,0x00200002,
+0x04200000,0x00000800,0x00000802,0x04200802,
+0x00200800,0x00000002,0x04000000,0x00200800,
+0x04000000,0x00200800,0x00200000,0x04000802,
+0x04000802,0x04200002,0x04200002,0x00000002,
+0x00200002,0x04000000,0x04000800,0x00200000,
+0x04200800,0x00000802,0x00200802,0x04200800,
+0x00000802,0x04000002,0x04200802,0x04200000,
+0x00200800,0x00000000,0x00000002,0x04200802,
+0x00000000,0x00200802,0x04200000,0x00000800,
+0x04000002,0x04000800,0x00000800,0x00200002},
+{
+0x10001040,0x00001000,0x00040000,0x10041040,
+0x10000000,0x10001040,0x00000040,0x10000000,
+0x00040040,0x10040000,0x10041040,0x00041000,
+0x10041000,0x00041040,0x00001000,0x00000040,
+0x10040000,0x10000040,0x10001000,0x00001040,
+0x00041000,0x00040040,0x10040040,0x10041000,
+0x00001040,0x00000000,0x00000000,0x10040040,
+0x10000040,0x10001000,0x00041040,0x00040000,
+0x00041040,0x00040000,0x10041000,0x00001000,
+0x00000040,0x10040040,0x00001000,0x00041040,
+0x10001000,0x00000040,0x10000040,0x10040000,
+0x10040040,0x10000000,0x00040000,0x10001040,
+0x00000000,0x10041040,0x00040040,0x10000040,
+0x10040000,0x10001000,0x10001040,0x00000000,
+0x10041040,0x00041000,0x00041000,0x00001040,
+0x00001040,0x00040040,0x10000000,0x10041000}
+};
+
+
+static INLINE void IPERM(word32* left, word32* right)
+{
+    word32 work;
+
+    *right = rotlFixed(*right, 4U);
+    work = (*left ^ *right) & 0xf0f0f0f0;
+    *left ^= work;
+
+    *right = rotrFixed(*right^work, 20U);
+    work = (*left ^ *right) & 0xffff0000;
+    *left ^= work;
+
+    *right = rotrFixed(*right^work, 18U);
+    work = (*left ^ *right) & 0x33333333;
+    *left ^= work;
+
+    *right = rotrFixed(*right^work, 6U);
+    work = (*left ^ *right) & 0x00ff00ff;
+    *left ^= work;
+
+    *right = rotlFixed(*right^work, 9U);
+    work = (*left ^ *right) & 0xaaaaaaaa;
+    *left = rotlFixed(*left^work, 1U);
+    *right ^= work;
+}
+
+
+static INLINE void FPERM(word32* left, word32* right)
+{
+    word32 work;
+
+    *right = rotrFixed(*right, 1U);
+    work = (*left ^ *right) & 0xaaaaaaaa;
+    *right ^= work;
+
+    *left = rotrFixed(*left^work, 9U);
+    work = (*left ^ *right) & 0x00ff00ff;
+    *right ^= work;
+
+    *left = rotlFixed(*left^work, 6U);
+    work = (*left ^ *right) & 0x33333333;
+    *right ^= work;
+
+    *left = rotlFixed(*left^work, 18U);
+    work = (*left ^ *right) & 0xffff0000;
+    *right ^= work;
+
+    *left = rotlFixed(*left^work, 20U);
+    work = (*left ^ *right) & 0xf0f0f0f0;
+    *right ^= work;
+
+    *left = rotrFixed(*left^work, 4U);
+}
+
+
+static int DesSetKey(const byte* key, int dir, word32* out)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    byte* buffer = (byte*)XMALLOC(56+56+8, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (buffer == NULL)
+        return MEMORY_E;
+#else
+    byte buffer[56+56+8];
+#endif
+
+    {
+        byte* const  pc1m = buffer;               /* place to modify pc1 into */
+        byte* const  pcr  = pc1m + 56;            /* place to rotate pc1 into */
+        byte* const  ks   = pcr  + 56;
+        register int i, j, l;
+        int          m;
+
+        for (j = 0; j < 56; j++) {             /* convert pc1 to bits of key  */
+            l = pc1[j] - 1;                    /* integer bit location        */
+            m = l & 07;                        /* find bit                    */
+            pc1m[j] = (key[l >> 3] &           /* find which key byte l is in */
+                bytebit[m])                    /* and which bit of that byte  */
+                ? 1 : 0;                       /* and store 1-bit result      */
+        }
+
+        for (i = 0; i < 16; i++) {            /* key chunk for each iteration */
+            XMEMSET(ks, 0, 8);                /* Clear key schedule */
+
+            for (j = 0; j < 56; j++)          /* rotate pc1 the right amount  */
+                pcr[j] =
+                      pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l-28];
+
+            /* rotate left and right halves independently */
+            for (j = 0; j < 48; j++) {        /* select bits individually     */
+                if (pcr[pc2[j] - 1]) {        /* check bit that goes to ks[j] */
+                    l= j % 6;                 /* mask it in if it's there     */
+                    ks[j/6] |= bytebit[l] >> 2;
+                }
+            }
+
+            /* Now convert to odd/even interleaved form for use in F */
+            out[2*i] = ((word32) ks[0] << 24)
+                     | ((word32) ks[2] << 16)
+                     | ((word32) ks[4] << 8)
+                     | ((word32) ks[6]);
+
+            out[2*i + 1] = ((word32) ks[1] << 24)
+                         | ((word32) ks[3] << 16)
+                         | ((word32) ks[5] << 8)
+                         | ((word32) ks[7]);
+        }
+
+        /* reverse key schedule order */
+        if (dir == DES_DECRYPTION) {
+            for (i = 0; i < 16; i += 2) {
+                word32 swap = out[i];
+                out[i] = out[DES_KS_SIZE - 2 - i];
+                out[DES_KS_SIZE - 2 - i] = swap;
+    
+                swap = out[i + 1];
+                out[i + 1] = out[DES_KS_SIZE - 1 - i];
+                out[DES_KS_SIZE - 1 - i] = swap;
+            }
+        }
+
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+    }
+
+    return 0;
+}
+
+
+static INLINE int Reverse(int dir)
+{
+    return !dir;
+}
+
+
+int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
+{
+    wc_Des_SetIV(des, iv);
+
+    return DesSetKey(key, dir, des->key);
+}
+
+
+int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
+{
+    int ret;
+
+#ifdef HAVE_CAVIUM
+    if (des->magic == WOLFSSL_3DES_CAVIUM_MAGIC)
+        return wc_Des3_CaviumSetKey(des, key, iv);
+#endif
+
+    ret = DesSetKey(key + (dir == DES_ENCRYPTION ? 0:16), dir, des->key[0]);
+    if (ret != 0)
+        return ret;
+
+    ret = DesSetKey(key + 8, Reverse(dir), des->key[1]);
+    if (ret != 0)
+        return ret;
+
+    ret = DesSetKey(key + (dir == DES_DECRYPTION ? 0:16), dir, des->key[2]);
+    if (ret != 0)
+        return ret;
+
+    return wc_Des3_SetIV(des, iv);
+}
+
+
+static void DesRawProcessBlock(word32* lIn, word32* rIn, const word32* kptr)
+{
+    word32 l = *lIn, r = *rIn, i;
+
+    for (i=0; i<8; i++)
+    {
+        word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
+        l ^= Spbox[6][(work) & 0x3f]
+          ^  Spbox[4][(work >> 8) & 0x3f]
+          ^  Spbox[2][(work >> 16) & 0x3f]
+          ^  Spbox[0][(work >> 24) & 0x3f];
+        work = r ^ kptr[4*i+1];
+        l ^= Spbox[7][(work) & 0x3f]
+          ^  Spbox[5][(work >> 8) & 0x3f]
+          ^  Spbox[3][(work >> 16) & 0x3f]
+          ^  Spbox[1][(work >> 24) & 0x3f];
+
+        work = rotrFixed(l, 4U) ^ kptr[4*i+2];
+        r ^= Spbox[6][(work) & 0x3f]
+          ^  Spbox[4][(work >> 8) & 0x3f]
+          ^  Spbox[2][(work >> 16) & 0x3f]
+          ^  Spbox[0][(work >> 24) & 0x3f];
+        work = l ^ kptr[4*i+3];
+        r ^= Spbox[7][(work) & 0x3f]
+          ^  Spbox[5][(work >> 8) & 0x3f]
+          ^  Spbox[3][(work >> 16) & 0x3f]
+          ^  Spbox[1][(work >> 24) & 0x3f];
+    }
+
+    *lIn = l; *rIn = r;
+}
+
+
+static void DesProcessBlock(Des* des, const byte* in, byte* out)
+{
+    word32 l, r;
+
+    XMEMCPY(&l, in, sizeof(l));
+    XMEMCPY(&r, in + sizeof(l), sizeof(r));
+    #ifdef LITTLE_ENDIAN_ORDER
+        l = ByteReverseWord32(l);
+        r = ByteReverseWord32(r);
+    #endif
+    IPERM(&l,&r);
+    
+    DesRawProcessBlock(&l, &r, des->key);   
+
+    FPERM(&l,&r);
+    #ifdef LITTLE_ENDIAN_ORDER
+        l = ByteReverseWord32(l);
+        r = ByteReverseWord32(r);
+    #endif
+    XMEMCPY(out, &r, sizeof(r));
+    XMEMCPY(out + sizeof(r), &l, sizeof(l));
+}
+
+
+static void Des3ProcessBlock(Des3* des, const byte* in, byte* out)
+{
+    word32 l, r;
+
+    XMEMCPY(&l, in, sizeof(l));
+    XMEMCPY(&r, in + sizeof(l), sizeof(r));
+    #ifdef LITTLE_ENDIAN_ORDER
+        l = ByteReverseWord32(l);
+        r = ByteReverseWord32(r);
+    #endif
+    IPERM(&l,&r);
+    
+    DesRawProcessBlock(&l, &r, des->key[0]);   
+    DesRawProcessBlock(&r, &l, des->key[1]);   
+    DesRawProcessBlock(&l, &r, des->key[2]);   
+
+    FPERM(&l,&r);
+    #ifdef LITTLE_ENDIAN_ORDER
+        l = ByteReverseWord32(l);
+        r = ByteReverseWord32(r);
+    #endif
+    XMEMCPY(out, &r, sizeof(r));
+    XMEMCPY(out + sizeof(r), &l, sizeof(l));
+}
+
+
+int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+{
+    word32 blocks = sz / DES_BLOCK_SIZE;
+
+    while (blocks--) {
+        xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
+        DesProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
+        XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
+
+        out += DES_BLOCK_SIZE;
+        in  += DES_BLOCK_SIZE;
+    }
+    return 0;
+}
+
+
+int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
+{
+    word32 blocks = sz / DES_BLOCK_SIZE;
+
+    while (blocks--) {
+        XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
+        DesProcessBlock(des, (byte*)des->tmp, out);
+        xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
+        XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
+
+        out += DES_BLOCK_SIZE;
+        in  += DES_BLOCK_SIZE;
+    }
+    return 0;
+}
+
+
+int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+{
+    word32 blocks;
+
+#ifdef HAVE_CAVIUM
+    if (des->magic == WOLFSSL_3DES_CAVIUM_MAGIC)
+        return wc_Des3_CaviumCbcEncrypt(des, out, in, sz);
+#endif
+
+    blocks = sz / DES_BLOCK_SIZE;
+    while (blocks--) {
+        xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
+        Des3ProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
+        XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
+
+        out += DES_BLOCK_SIZE;
+        in  += DES_BLOCK_SIZE;
+    }
+    return 0;
+}
+
+
+int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
+{
+    word32 blocks;
+
+#ifdef HAVE_CAVIUM
+    if (des->magic == WOLFSSL_3DES_CAVIUM_MAGIC)
+        return wc_Des3_CaviumCbcDecrypt(des, out, in, sz);
+#endif
+
+    blocks = sz / DES_BLOCK_SIZE;
+    while (blocks--) {
+        XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
+        Des3ProcessBlock(des, (byte*)des->tmp, out);
+        xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
+        XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
+
+        out += DES_BLOCK_SIZE;
+        in  += DES_BLOCK_SIZE; 
+    }
+    return 0;
+}
+
+#ifdef WOLFSSL_DES_ECB
+
+/* One block, compatibility only */
+int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+{
+    word32 blocks = sz / DES_BLOCK_SIZE;
+
+    while (blocks--) {
+        DesProcessBlock(des, in, out);
+
+        out += DES_BLOCK_SIZE;
+        in  += DES_BLOCK_SIZE; 
+    }
+    return 0;
+}
+
+#endif /* WOLFSSL_DES_ECB */
+
+#endif /* STM32F2_CRYPTO */
+
+void wc_Des_SetIV(Des* des, const byte* iv)
+{
+    if (des && iv)
+        XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
+    else if (des)
+        XMEMSET(des->reg,  0, DES_BLOCK_SIZE);
+}
+
+
+int wc_Des3_SetIV(Des3* des, const byte* iv)
+{
+    if (des && iv)
+        XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
+    else if (des)
+        XMEMSET(des->reg,  0, DES_BLOCK_SIZE);
+
+    return 0;
+}
+
+
+#ifdef HAVE_CAVIUM
+
+#include "cavium_common.h"
+
+/* Initiliaze Des3 for use with Nitrox device */
+int wc_Des3_InitCavium(Des3* des3, int devId)
+{
+    if (des3 == NULL)
+        return -1;
+
+    if (CspAllocContext(CONTEXT_SSL, &des3->contextHandle, devId) != 0)
+        return -1;
+
+    des3->devId = devId;
+    des3->magic = WOLFSSL_3DES_CAVIUM_MAGIC;
+   
+    return 0;
+}
+
+
+/* Free Des3 from use with Nitrox device */
+void wc_Des3_FreeCavium(Des3* des3)
+{
+    if (des3 == NULL)
+        return;
+
+    if (des3->magic != WOLFSSL_3DES_CAVIUM_MAGIC)
+        return;
+
+    CspFreeContext(CONTEXT_SSL, des3->contextHandle, des3->devId);
+    des3->magic = 0;
+}
+
+
+static int wc_Des3_CaviumSetKey(Des3* des3, const byte* key, const byte* iv)
+{
+    if (des3 == NULL)
+        return -1;
+
+    /* key[0] holds key, iv in reg */
+    XMEMCPY(des3->key[0], key, DES_BLOCK_SIZE*3);
+
+    return wc_Des3_SetIV(des3, iv);
+}
+
+
+static int wc_Des3_CaviumCbcEncrypt(Des3* des3, byte* out, const byte* in,
+                                  word32 length)
+{
+    wolfssl_word offset = 0;
+    word32 requestId;
+   
+    while (length > WOLFSSL_MAX_16BIT) {
+        word16 slen = (word16)WOLFSSL_MAX_16BIT;
+        if (CspEncrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
+                           CAVIUM_NO_UPDATE, slen, (byte*)in + offset,
+                           out + offset, (byte*)des3->reg, (byte*)des3->key[0],
+                           &requestId, des3->devId) != 0) {
+            WOLFSSL_MSG("Bad Cavium 3DES Cbc Encrypt");
+            return -1;
+        }
+        length -= WOLFSSL_MAX_16BIT;
+        offset += WOLFSSL_MAX_16BIT;
+        XMEMCPY(des3->reg, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
+    }
+    if (length) {
+        word16 slen = (word16)length;
+
+        if (CspEncrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
+                           CAVIUM_NO_UPDATE, slen, (byte*)in + offset,
+                           out + offset, (byte*)des3->reg, (byte*)des3->key[0],
+                           &requestId, des3->devId) != 0) {
+            WOLFSSL_MSG("Bad Cavium 3DES Cbc Encrypt");
+            return -1;
+        }
+        XMEMCPY(des3->reg, out+offset+length - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
+    }
+    return 0;
+}
+
+static int wc_Des3_CaviumCbcDecrypt(Des3* des3, byte* out, const byte* in,
+                                 word32 length)
+{
+    word32 requestId;
+    wolfssl_word offset = 0;
+
+    while (length > WOLFSSL_MAX_16BIT) {
+        word16 slen = (word16)WOLFSSL_MAX_16BIT;
+        XMEMCPY(des3->tmp, in + offset + slen - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
+        if (CspDecrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
+                           CAVIUM_NO_UPDATE, slen, (byte*)in+offset, out+offset,
+                           (byte*)des3->reg, (byte*)des3->key[0], &requestId,
+                           des3->devId) != 0) {
+            WOLFSSL_MSG("Bad Cavium 3Des Decrypt");
+            return -1;
+        }
+        length -= WOLFSSL_MAX_16BIT;
+        offset += WOLFSSL_MAX_16BIT;
+        XMEMCPY(des3->reg, des3->tmp, DES_BLOCK_SIZE);
+    }
+    if (length) {
+        word16 slen = (word16)length;
+        XMEMCPY(des3->tmp, in + offset + slen - DES_BLOCK_SIZE,DES_BLOCK_SIZE);
+        if (CspDecrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
+                           CAVIUM_NO_UPDATE, slen, (byte*)in+offset, out+offset,
+                           (byte*)des3->reg, (byte*)des3->key[0], &requestId,
+                           des3->devId) != 0) {
+            WOLFSSL_MSG("Bad Cavium 3Des Decrypt");
+            return -1;
+        }
+        XMEMCPY(des3->reg, des3->tmp, DES_BLOCK_SIZE);
+    }
+    return 0;
+}
+
+#endif /* HAVE_CAVIUM */
+#endif /* WOLFSSL_TI_CRYPT */
+#endif /* HAVE_FIPS */
+#endif /* NO_DES3 */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/dh.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/dh.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/dh.c	(revision 164)
@@ -0,0 +1,219 @@
+/* dh.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_DH
+
+#include <wolfssl/wolfcrypt/dh.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+#ifndef USER_MATH_LIB
+    #include <math.h>
+    #define XPOW(x,y) pow((x),(y))
+    #define XLOG(x)   log((x))
+#else
+    /* user's own math lib */
+#endif
+
+
+#ifdef min
+#define WOLFSSL_HAVE_MIN
+#endif
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+
+#endif /* WOLFSSL_HAVE_MIN */
+
+
+void wc_InitDhKey(DhKey* key)
+{
+    (void)key;
+/* TomsFastMath doesn't use memory allocation */
+#ifndef USE_FAST_MATH
+    key->p.dp = 0;
+    key->g.dp = 0;
+#endif
+}
+
+
+void wc_FreeDhKey(DhKey* key)
+{
+    (void)key;
+/* TomsFastMath doesn't use memory allocation */
+#ifndef USE_FAST_MATH
+    mp_clear(&key->p);
+    mp_clear(&key->g);
+#endif
+}
+
+
+static word32 DiscreteLogWorkFactor(word32 n)
+{
+    /* assuming discrete log takes about the same time as factoring */
+    if (n<5)
+        return 0;
+    else
+        return (word32)(2.4 * XPOW((double)n, 1.0/3.0) *
+                XPOW(XLOG((double)n), 2.0/3.0) - 5);
+}
+
+
+static int GeneratePrivate(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz)
+{
+    int ret;
+    word32 sz = mp_unsigned_bin_size(&key->p);
+    sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /
+                                           WOLFSSL_BIT_SIZE + 1);
+
+    ret = wc_RNG_GenerateBlock(rng, priv, sz);
+    if (ret != 0)
+        return ret;
+
+    priv[0] |= 0x0C;
+
+    *privSz = sz;
+
+    return 0;
+}
+
+
+static int GeneratePublic(DhKey* key, const byte* priv, word32 privSz,
+                          byte* pub, word32* pubSz)
+{
+    int ret = 0;
+
+    mp_int x; 
+    mp_int y;
+
+    if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY)
+        return MP_INIT_E;
+
+    if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
+        ret = MP_READ_E;
+
+    if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY)
+        ret = MP_EXPTMOD_E;
+
+    if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY)
+        ret = MP_TO_E;
+
+    if (ret == 0)
+        *pubSz = mp_unsigned_bin_size(&y);
+
+    mp_clear(&y);
+    mp_clear(&x);
+
+    return ret;
+}
+
+
+int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz,
+                      byte* pub, word32* pubSz)
+{
+    int ret = GeneratePrivate(key, rng, priv, privSz);
+
+    return (ret != 0) ? ret : GeneratePublic(key, priv, *privSz, pub, pubSz);
+}
+
+int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
+            word32 privSz, const byte* otherPub, word32 pubSz)
+{
+    int ret = 0;
+
+    mp_int x; 
+    mp_int y;
+    mp_int z;
+
+    if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY)
+        return MP_INIT_E;
+
+    if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
+        ret = MP_READ_E;
+
+    if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY)
+        ret = MP_READ_E;
+
+    if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY)
+        ret = MP_EXPTMOD_E;
+
+    if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY)
+        ret = MP_TO_E;
+
+    if (ret == 0)
+        *agreeSz = mp_unsigned_bin_size(&z);
+
+    mp_clear(&z);
+    mp_clear(&y);
+    mp_clear(&x);
+
+    return ret;
+}
+
+
+/* not in asn anymore since no actual asn types used */
+int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
+                word32 gSz)
+{
+    if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0)
+        return BAD_FUNC_ARG;
+
+    /* may have leading 0 */
+    if (p[0] == 0) {
+        pSz--; p++;
+    }
+
+    if (g[0] == 0) {
+        gSz--; g++;
+    }
+
+    if (mp_init(&key->p) != MP_OKAY)
+        return MP_INIT_E;
+    if (mp_read_unsigned_bin(&key->p, p, pSz) != 0) {
+        mp_clear(&key->p);
+        return ASN_DH_KEY_E;
+    }
+
+    if (mp_init(&key->g) != MP_OKAY) {
+        mp_clear(&key->p);
+        return MP_INIT_E;
+    }
+    if (mp_read_unsigned_bin(&key->g, g, gSz) != 0) {
+        mp_clear(&key->g);
+        mp_clear(&key->p);
+        return ASN_DH_KEY_E;
+    }
+
+    return 0;
+}
+
+
+#endif /* NO_DH */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/dsa.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/dsa.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/dsa.c	(revision 164)
@@ -0,0 +1,494 @@
+/* dsa.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_DSA
+
+#include <wolfssl/wolfcrypt/random.h>
+#include <wolfssl/wolfcrypt/integer.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+#include <wolfssl/wolfcrypt/sha.h>
+#include <wolfssl/wolfcrypt/dsa.h>
+
+
+enum {
+    DSA_HALF_SIZE = 20,   /* r and s size  */
+    DSA_SIG_SIZE  = 40    /* signature size */
+};
+
+
+#ifdef min
+#define WOLFSSL_HAVE_MIN
+#endif
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+
+#endif /* WOLFSSL_HAVE_MIN */
+
+
+void wc_InitDsaKey(DsaKey* key)
+{
+    key->type = -1;  /* haven't decided yet */
+
+/* TomsFastMath doesn't use memory allocation */
+#ifndef USE_FAST_MATH
+    key->p.dp = 0;   /* public  alloc parts */
+    key->q.dp = 0;    
+    key->g.dp = 0;    
+    key->y.dp = 0;    
+
+    key->x.dp = 0;   /* private alloc parts */
+#endif
+}
+
+
+void wc_FreeDsaKey(DsaKey* key)
+{
+    (void)key;
+/* TomsFastMath doesn't use memory allocation */
+#ifndef USE_FAST_MATH
+    if (key->type == DSA_PRIVATE)
+        mp_clear(&key->x);
+    mp_clear(&key->y);
+    mp_clear(&key->g);
+    mp_clear(&key->q);
+    mp_clear(&key->p);
+#endif
+}
+
+#ifdef WOLFSSL_KEY_GEN
+
+int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa)
+{
+    unsigned char *buf;
+    int qsize, err;
+
+    if (rng == NULL || dsa == NULL)
+        return BAD_FUNC_ARG;
+
+    qsize = mp_unsigned_bin_size(&dsa->q);
+    if (qsize == 0)
+        return BAD_FUNC_ARG;
+
+    /* allocate ram */
+    buf = (unsigned char *)XMALLOC(qsize, NULL,
+                                   DYNAMIC_TYPE_TMP_BUFFER);
+    if (buf == NULL)
+        return MEMORY_E;
+
+    if (mp_init(&dsa->x) != MP_OKAY) {
+        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MP_INIT_E;
+    }
+
+    do {
+        /* make a random exponent mod q */
+        err = wc_RNG_GenerateBlock(rng, buf, qsize);
+        if (err != MP_OKAY) {
+            mp_clear(&dsa->x);
+            XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return err;
+        }
+
+        err = mp_read_unsigned_bin(&dsa->x, buf, qsize);
+        if (err != MP_OKAY) {
+            mp_clear(&dsa->x);
+            XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            return err;
+        }
+    } while (mp_cmp_d(&dsa->x, 1) != MP_GT);
+
+    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (mp_init(&dsa->y) != MP_OKAY) {
+        mp_clear(&dsa->x);
+        return MP_INIT_E;
+    }
+
+    /* public key : y = g^x mod p */
+    err = mp_exptmod(&dsa->g, &dsa->x, &dsa->p, &dsa->y);
+    if (err != MP_OKAY) {
+        mp_clear(&dsa->x);
+        mp_clear(&dsa->y);
+        return err;
+    }
+
+    dsa->type = DSA_PRIVATE;
+    
+    return MP_OKAY;
+}
+
+/* modulus_size in bits */
+int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa)
+{
+    mp_int  tmp, tmp2;
+    int     err, msize, qsize,
+            loop_check_prime = 0,
+            check_prime = MP_NO;
+    unsigned char   *buf;
+
+    if (rng == NULL || dsa == NULL)
+        return BAD_FUNC_ARG;
+
+    /* set group size in bytes from modulus size
+     * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256)
+     */
+    switch (modulus_size) {
+        case 1024:
+            qsize = 20;
+            break;
+        case 2048:
+        case 3072:
+            qsize = 32;
+            break;
+        default:
+            return BAD_FUNC_ARG;
+            break;
+    }
+
+    /* modulus size in bytes */
+    msize = modulus_size / 8;
+
+    /* allocate ram */
+    buf = (unsigned char *)XMALLOC(msize - qsize,
+                                   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buf == NULL) {
+        return MEMORY_E;
+    }
+
+    /* make a random string that will be multplied against q */
+    err = wc_RNG_GenerateBlock(rng, buf, msize - qsize);
+    if (err != MP_OKAY) {
+        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return err;
+    }
+
+    /* force magnitude */
+    buf[0] |= 0xC0;
+
+    /* force even */
+    buf[msize - qsize - 1] &= ~1;
+
+    if (mp_init_multi(&tmp2, &dsa->p, &dsa->q, 0, 0, 0) != MP_OKAY) {
+        mp_clear(&dsa->q);
+        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MP_INIT_E;
+    }
+
+    err = mp_read_unsigned_bin(&tmp2, buf, msize - qsize);
+    if (err != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp2);
+        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return err;
+    }
+    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    /* make our prime q */
+    err = mp_rand_prime(&dsa->q, qsize, rng, NULL);
+    if (err != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp2);
+        return err;
+    }
+
+    /* p = random * q */
+    err = mp_mul(&dsa->q, &tmp2, &dsa->p);
+    if (err != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp2);
+        return err;
+    }
+
+    /* p = random * q + 1, so q is a prime divisor of p-1 */
+    err = mp_add_d(&dsa->p, 1, &dsa->p);
+    if (err != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp2);
+        return err;
+    }
+
+    if (mp_init(&tmp) != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp2);
+        return MP_INIT_E;
+    }
+
+    /* tmp = 2q  */
+    err = mp_add(&dsa->q, &dsa->q, &tmp);
+    if (err != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp);
+        mp_clear(&tmp2);
+        return err;
+    }
+
+    /* loop until p is prime */
+    while (check_prime == MP_NO) {
+        err = mp_prime_is_prime(&dsa->p, 8, &check_prime);
+        if (err != MP_OKAY) {
+            mp_clear(&dsa->q);
+            mp_clear(&dsa->p);
+            mp_clear(&tmp);
+            mp_clear(&tmp2);
+            return err;
+        }
+
+        if (check_prime != MP_YES) {
+            /* p += 2q */
+            err = mp_add(&tmp, &dsa->p, &dsa->p);
+            if (err != MP_OKAY) {
+                mp_clear(&dsa->q);
+                mp_clear(&dsa->p);
+                mp_clear(&tmp);
+                mp_clear(&tmp2);
+                return err;
+            }
+
+            loop_check_prime++;
+        }
+    }
+
+    /* tmp2 += (2*loop_check_prime)
+     * to have p = (q * tmp2) + 1 prime
+     */
+    if (loop_check_prime) {
+        err = mp_add_d(&tmp2, 2*loop_check_prime, &tmp2);
+        if (err != MP_OKAY) {
+            mp_clear(&dsa->q);
+            mp_clear(&dsa->p);
+            mp_clear(&tmp);
+            mp_clear(&tmp2);
+            return err;
+        }
+    }
+
+    if (mp_init(&dsa->g) != MP_OKAY) {
+        mp_clear(&dsa->q);
+        mp_clear(&dsa->p);
+        mp_clear(&tmp);
+        mp_clear(&tmp2);
+        return MP_INIT_E;
+    }
+
+    /* find a value g for which g^tmp2 != 1 */
+    mp_set(&dsa->g, 1);
+
+    do {
+        err = mp_add_d(&dsa->g, 1, &dsa->g);
+        if (err != MP_OKAY) {
+            mp_clear(&dsa->q);
+            mp_clear(&dsa->p);
+            mp_clear(&dsa->g);
+            mp_clear(&tmp);
+            mp_clear(&tmp2);
+            return err;
+        }
+
+        err = mp_exptmod(&dsa->g, &tmp2, &dsa->p, &tmp);
+        if (err != MP_OKAY) {
+            mp_clear(&dsa->q);
+            mp_clear(&dsa->p);
+            mp_clear(&dsa->g);
+            mp_clear(&tmp);
+            mp_clear(&tmp2);
+            return err;
+        }
+
+    } while (mp_cmp_d(&tmp, 1) == MP_EQ);
+
+    /* at this point tmp generates a group of order q mod p */
+    mp_exch(&tmp, &dsa->g);
+
+    mp_clear(&tmp);
+    mp_clear(&tmp2);
+
+    return MP_OKAY;
+}
+#endif /* WOLFSSL_KEY_GEN */
+
+
+int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
+{
+    mp_int k, kInv, r, s, H;
+    int    ret, sz;
+    byte   buffer[DSA_HALF_SIZE];
+
+    sz = min(sizeof(buffer), mp_unsigned_bin_size(&key->q));
+
+    /* generate k */
+    ret = wc_RNG_GenerateBlock(rng, buffer, sz);
+    if (ret != 0)
+        return ret;
+
+    buffer[0] |= 0x0C;
+
+    if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY)
+        return MP_INIT_E;
+
+    if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY)
+        ret = MP_READ_E;
+
+    if (ret == 0 && mp_cmp_d(&k, 1) != MP_GT)
+        ret = MP_CMP_E;
+
+    /* inverse k mod q */
+    if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY)
+        ret = MP_INVMOD_E;
+
+    /* generate r, r = (g exp k mod p) mod q */
+    if (ret == 0 && mp_exptmod(&key->g, &k, &key->p, &r) != MP_OKAY)
+        ret = MP_EXPTMOD_E;
+
+    if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY)
+        ret = MP_MOD_E;
+
+    /* generate H from sha digest */
+    if (ret == 0 && mp_read_unsigned_bin(&H, digest,SHA_DIGEST_SIZE) != MP_OKAY)
+        ret = MP_READ_E;
+
+    /* generate s, s = (kInv * (H + x*r)) % q */
+    if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY)
+        ret = MP_MUL_E;
+
+    if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY)
+        ret = MP_ADD_E;
+
+    if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY)
+        ret = MP_MULMOD_E;
+
+    /* write out */
+    if (ret == 0)  {
+        int rSz = mp_unsigned_bin_size(&r);
+        int sSz = mp_unsigned_bin_size(&s);
+
+        if (rSz == DSA_HALF_SIZE - 1) {
+            out[0] = 0;
+            out++;
+        }
+
+        if (mp_to_unsigned_bin(&r, out) != MP_OKAY)
+            ret = MP_TO_E;
+        else {
+            if (sSz == DSA_HALF_SIZE - 1) {
+                out[rSz] = 0;
+                out++;
+            }    
+            ret = mp_to_unsigned_bin(&s, out + rSz);
+        }
+    }
+
+    mp_clear(&H);
+    mp_clear(&s);
+    mp_clear(&r);
+    mp_clear(&kInv);
+    mp_clear(&k);
+
+    return ret;
+}
+
+
+int wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer)
+{
+    mp_int w, u1, u2, v, r, s;
+    int    ret = 0;
+
+    if (mp_init_multi(&w, &u1, &u2, &v, &r, &s) != MP_OKAY)
+        return MP_INIT_E;
+
+    /* set r and s from signature */
+    if (mp_read_unsigned_bin(&r, sig, DSA_HALF_SIZE) != MP_OKAY ||
+        mp_read_unsigned_bin(&s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY)
+        ret = MP_READ_E;
+
+    /* sanity checks */
+    if (ret == 0) {
+        if (mp_iszero(&r) == MP_YES || mp_iszero(&s) == MP_YES ||
+                mp_cmp(&r, &key->q) != MP_LT || mp_cmp(&s, &key->q) != MP_LT) {
+            ret = MP_ZERO_E;
+        }
+    }
+
+    /* put H into u1 from sha digest */
+    if (ret == 0 && mp_read_unsigned_bin(&u1,digest,SHA_DIGEST_SIZE) != MP_OKAY)
+        ret = MP_READ_E;
+
+    /* w = s invmod q */
+    if (ret == 0 && mp_invmod(&s, &key->q, &w) != MP_OKAY)
+        ret = MP_INVMOD_E;
+
+    /* u1 = (H * w) % q */
+    if (ret == 0 && mp_mulmod(&u1, &w, &key->q, &u1) != MP_OKAY)
+        ret = MP_MULMOD_E;
+
+    /* u2 = (r * w) % q */
+    if (ret == 0 && mp_mulmod(&r, &w, &key->q, &u2) != MP_OKAY)
+        ret = MP_MULMOD_E;
+
+    /* verify v = ((g^u1 * y^u2) mod p) mod q */
+    if (ret == 0 && mp_exptmod(&key->g, &u1, &key->p, &u1) != MP_OKAY)
+        ret = MP_EXPTMOD_E;
+
+    if (ret == 0 && mp_exptmod(&key->y, &u2, &key->p, &u2) != MP_OKAY)
+        ret = MP_EXPTMOD_E;
+
+    if (ret == 0 && mp_mulmod(&u1, &u2, &key->p, &v) != MP_OKAY)
+        ret = MP_MULMOD_E;
+
+    if (ret == 0 && mp_mod(&v, &key->q, &v) != MP_OKAY)
+        ret = MP_MULMOD_E;
+
+    /* do they match */
+    if (ret == 0 && mp_cmp(&r, &v) == MP_EQ)
+        *answer = 1;
+    else
+        *answer = 0;
+
+    mp_clear(&s);
+    mp_clear(&r);
+    mp_clear(&u1);
+    mp_clear(&u2);
+    mp_clear(&w);
+    mp_clear(&v);
+
+    return ret;
+}
+
+
+#endif /* NO_DSA */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/ecc.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/ecc.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/ecc.c	(revision 164)
@@ -0,0 +1,5557 @@
+/* ecc.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+/* in case user set HAVE_ECC there */
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef HAVE_ECC
+
+#include <wolfssl/wolfcrypt/ecc.h>
+#include <wolfssl/openssl/ec.h>
+#include <wolfssl/wolfcrypt/asn.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+#ifdef HAVE_ECC_ENCRYPT
+    #include <wolfssl/wolfcrypt/hmac.h>
+    #include <wolfssl/wolfcrypt/aes.h>
+#endif
+
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+/* map
+
+   ptmul -> mulmod
+
+*/
+
+
+/* p256 curve on by default whether user curves or not */
+#if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)
+    #define ECC112
+#endif
+#if defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)
+    #define ECC128
+#endif
+#if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
+    #define ECC160
+#endif
+#if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
+    #define ECC192
+#endif
+#if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
+    #define ECC224
+#endif
+#if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
+    #define ECC256
+#endif
+#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+    #define ECC384
+#endif
+#if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+    #define ECC521
+#endif
+
+
+
+/* This holds the key settings.  ***MUST*** be organized by size from
+   smallest to largest. */
+
+const ecc_set_type ecc_sets[] = {
+#ifdef ECC112
+{
+        14,
+        NID_secp111r1,
+        "SECP112R1",
+        "DB7C2ABF62E35E668076BEAD208B",
+        "DB7C2ABF62E35E668076BEAD2088",
+        "659EF8BA043916EEDE8911702B22",
+        "DB7C2ABF62E35E7628DFAC6561C5",
+        "09487239995A5EE76B55F9C2F098",
+        "A89CE5AF8724C0A23E0E0FF77500"
+},
+#endif
+#ifdef ECC128
+{
+        16,
+        NID_secp128r1,
+        "SECP128R1",
+        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
+        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
+        "E87579C11079F43DD824993C2CEE5ED3",
+        "FFFFFFFE0000000075A30D1B9038A115",
+        "161FF7528B899B2D0C28607CA52C5B86",
+        "CF5AC8395BAFEB13C02DA292DDED7A83",
+},
+#endif
+#ifdef ECC160
+{
+        20,
+        NID_secp160r1,
+        "SECP160R1",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
+        "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
+        "0100000000000000000001F4C8F927AED3CA752257",
+        "4A96B5688EF573284664698968C38BB913CBFC82",
+        "23A628553168947D59DCC912042351377AC5FB32",
+},
+#endif
+#ifdef ECC192
+{
+        24,
+        NID_cert192,
+        "ECC-192",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+        "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
+        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
+        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
+        "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
+},
+#endif
+#ifdef ECC224
+{
+        28,
+        NID_cert224,
+        "ECC-224",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
+        "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
+        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
+        "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
+},
+#endif
+#ifdef ECC256
+{
+        32,
+        NID_X9_62_prime256v1,
+        "nistp256",
+        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
+        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
+        "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
+        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
+        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
+        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
+},
+#endif
+#ifdef ECC384
+{
+        48,
+        NID_secp384r1,
+        "nistp384",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
+        "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
+        "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
+        "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
+},
+#endif
+#ifdef ECC521
+{
+        66,
+        NID_secp521r1,
+        "nistp521",
+        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
+        "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
+        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
+        "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
+        "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
+},
+#endif
+{
+   0, -1,
+   NULL, NULL, NULL, NULL, NULL, NULL, NULL
+}
+};
+
+
+int  ecc_map(ecc_point*, mp_int*, mp_digit*);
+int  ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
+                              mp_int* modulus, mp_digit* mp);
+int  ecc_projective_dbl_point(ecc_point* P, ecc_point* R, mp_int* modulus,
+                              mp_digit* mp);
+static int ecc_check_pubkey_order(ecc_key* key, mp_int* prime, mp_int* order);
+#ifdef ECC_SHAMIR
+static int ecc_mul2add(ecc_point* A, mp_int* kA, ecc_point* B, mp_int* kB,
+                       ecc_point* C, mp_int* modulus);
+#endif
+
+int mp_jacobi(mp_int* a, mp_int* p, int* c);
+int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
+int mp_submod(mp_int* a, mp_int* b, mp_int* c, mp_int* d);
+
+#ifdef HAVE_COMP_KEY
+static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen);
+#endif
+
+/* helper for either lib */
+static int get_digit_count(mp_int* a)
+{
+    if (a == NULL)
+        return 0;
+
+    return a->used;
+}
+
+/* helper for either lib */
+static mp_digit get_digit(mp_int* a, int n)
+{
+    if (a == NULL)
+        return 0;
+
+    return (n >= a->used || n < 0) ? 0 : a->dp[n];
+}
+
+
+#if defined(USE_FAST_MATH)
+
+/* fast math accelerated version, but not for fp ecc yet */
+
+/**
+   Add two ECC points
+   P        The point to add
+   Q        The point to add
+   R        [out] The destination of the double
+   modulus  The modulus of the field the ECC curve is in
+   mp       The "b" value from montgomery_setup()
+   return   MP_OKAY on success
+*/
+int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R,
+                             mp_int* modulus, mp_digit* mp)
+{
+   fp_int t1, t2, x, y, z;
+   int    err;
+
+   if (P == NULL || Q == NULL || R == NULL || modulus == NULL || mp == NULL)
+       return ECC_BAD_ARG_E;
+
+   if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != MP_OKAY) {
+      return err;
+   }
+
+   /* should we dbl instead? */
+   fp_sub(modulus, Q->y, &t1);
+   if ( (fp_cmp(P->x, Q->x) == FP_EQ) &&
+        (get_digit_count(Q->z) && fp_cmp(P->z, Q->z) == FP_EQ) &&
+        (fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) {
+        return ecc_projective_dbl_point(P, R, modulus, mp);
+   }
+
+   fp_copy(P->x, &x);
+   fp_copy(P->y, &y);
+   fp_copy(P->z, &z);
+
+   /* if Z is one then these are no-operations */
+   if (get_digit_count(Q->z)) {
+      /* T1 = Z' * Z' */
+      fp_sqr(Q->z, &t1);
+      fp_montgomery_reduce(&t1, modulus, *mp);
+      /* X = X * T1 */
+      fp_mul(&t1, &x, &x);
+      fp_montgomery_reduce(&x, modulus, *mp);
+      /* T1 = Z' * T1 */
+      fp_mul(Q->z, &t1, &t1);
+      fp_montgomery_reduce(&t1, modulus, *mp);
+      /* Y = Y * T1 */
+      fp_mul(&t1, &y, &y);
+      fp_montgomery_reduce(&y, modulus, *mp);
+   }
+
+   /* T1 = Z*Z */
+   fp_sqr(&z, &t1);
+   fp_montgomery_reduce(&t1, modulus, *mp);
+   /* T2 = X' * T1 */
+   fp_mul(Q->x, &t1, &t2);
+   fp_montgomery_reduce(&t2, modulus, *mp);
+   /* T1 = Z * T1 */
+   fp_mul(&z, &t1, &t1);
+   fp_montgomery_reduce(&t1, modulus, *mp);
+   /* T1 = Y' * T1 */
+   fp_mul(Q->y, &t1, &t1);
+   fp_montgomery_reduce(&t1, modulus, *mp);
+
+   /* Y = Y - T1 */
+   fp_sub(&y, &t1, &y);
+   if (fp_cmp_d(&y, 0) == FP_LT) {
+      fp_add(&y, modulus, &y);
+   }
+   /* T1 = 2T1 */
+   fp_add(&t1, &t1, &t1);
+   if (fp_cmp(&t1, modulus) != FP_LT) {
+      fp_sub(&t1, modulus, &t1);
+   }
+   /* T1 = Y + T1 */
+   fp_add(&t1, &y, &t1);
+   if (fp_cmp(&t1, modulus) != FP_LT) {
+      fp_sub(&t1, modulus, &t1);
+   }
+   /* X = X - T2 */
+   fp_sub(&x, &t2, &x);
+   if (fp_cmp_d(&x, 0) == FP_LT) {
+      fp_add(&x, modulus, &x);
+   }
+   /* T2 = 2T2 */
+   fp_add(&t2, &t2, &t2);
+   if (fp_cmp(&t2, modulus) != FP_LT) {
+      fp_sub(&t2, modulus, &t2);
+   }
+   /* T2 = X + T2 */
+   fp_add(&t2, &x, &t2);
+   if (fp_cmp(&t2, modulus) != FP_LT) {
+      fp_sub(&t2, modulus, &t2);
+   }
+
+   /* if Z' != 1 */
+   if (get_digit_count(Q->z)) {
+      /* Z = Z * Z' */
+      fp_mul(&z, Q->z, &z);
+      fp_montgomery_reduce(&z, modulus, *mp);
+   }
+
+   /* Z = Z * X */
+   fp_mul(&z, &x, &z);
+   fp_montgomery_reduce(&z, modulus, *mp);
+
+   /* T1 = T1 * X  */
+   fp_mul(&t1, &x, &t1);
+   fp_montgomery_reduce(&t1, modulus, *mp);
+   /* X = X * X */
+   fp_sqr(&x, &x);
+   fp_montgomery_reduce(&x, modulus, *mp);
+   /* T2 = T2 * x */
+   fp_mul(&t2, &x, &t2);
+   fp_montgomery_reduce(&t2, modulus, *mp);
+   /* T1 = T1 * X  */
+   fp_mul(&t1, &x, &t1);
+   fp_montgomery_reduce(&t1, modulus, *mp);
+
+   /* X = Y*Y */
+   fp_sqr(&y, &x);
+   fp_montgomery_reduce(&x, modulus, *mp);
+   /* X = X - T2 */
+   fp_sub(&x, &t2, &x);
+   if (fp_cmp_d(&x, 0) == FP_LT) {
+      fp_add(&x, modulus, &x);
+   }
+
+   /* T2 = T2 - X */
+   fp_sub(&t2, &x, &t2);
+   if (fp_cmp_d(&t2, 0) == FP_LT) {
+      fp_add(&t2, modulus, &t2);
+   }
+   /* T2 = T2 - X */
+   fp_sub(&t2, &x, &t2);
+   if (fp_cmp_d(&t2, 0) == FP_LT) {
+      fp_add(&t2, modulus, &t2);
+   }
+   /* T2 = T2 * Y */
+   fp_mul(&t2, &y, &t2);
+   fp_montgomery_reduce(&t2, modulus, *mp);
+   /* Y = T2 - T1 */
+   fp_sub(&t2, &t1, &y);
+   if (fp_cmp_d(&y, 0) == FP_LT) {
+      fp_add(&y, modulus, &y);
+   }
+   /* Y = Y/2 */
+   if (fp_isodd(&y)) {
+      fp_add(&y, modulus, &y);
+   }
+   fp_div_2(&y, &y);
+
+   fp_copy(&x, R->x);
+   fp_copy(&y, R->y);
+   fp_copy(&z, R->z);
+
+   return MP_OKAY;
+}
+
+
+/**
+   Double an ECC point
+   P   The point to double
+   R   [out] The destination of the double
+   modulus  The modulus of the field the ECC curve is in
+   mp       The "b" value from montgomery_setup()
+   return   MP_OKAY on success
+*/
+int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* modulus,
+                             mp_digit* mp)
+{
+   fp_int   t1, t2;
+   int      err;
+
+   if (P == NULL || R == NULL || modulus == NULL || mp == NULL)
+       return ECC_BAD_ARG_E;
+
+   if (P != R) {
+      fp_copy(P->x, R->x);
+      fp_copy(P->y, R->y);
+      fp_copy(P->z, R->z);
+   }
+
+   if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
+      return err;
+   }
+
+   /* t1 = Z * Z */
+   fp_sqr(R->z, &t1);
+   fp_montgomery_reduce(&t1, modulus, *mp);
+   /* Z = Y * Z */
+   fp_mul(R->z, R->y, R->z);
+   fp_montgomery_reduce(R->z, modulus, *mp);
+   /* Z = 2Z */
+   fp_add(R->z, R->z, R->z);
+   if (fp_cmp(R->z, modulus) != FP_LT) {
+      fp_sub(R->z, modulus, R->z);
+   }
+
+   /* &t2 = X - T1 */
+   fp_sub(R->x, &t1, &t2);
+   if (fp_cmp_d(&t2, 0) == FP_LT) {
+      fp_add(&t2, modulus, &t2);
+   }
+   /* T1 = X + T1 */
+   fp_add(&t1, R->x, &t1);
+   if (fp_cmp(&t1, modulus) != FP_LT) {
+      fp_sub(&t1, modulus, &t1);
+   }
+   /* T2 = T1 * T2 */
+   fp_mul(&t1, &t2, &t2);
+   fp_montgomery_reduce(&t2, modulus, *mp);
+   /* T1 = 2T2 */
+   fp_add(&t2, &t2, &t1);
+   if (fp_cmp(&t1, modulus) != FP_LT) {
+      fp_sub(&t1, modulus, &t1);
+   }
+   /* T1 = T1 + T2 */
+   fp_add(&t1, &t2, &t1);
+   if (fp_cmp(&t1, modulus) != FP_LT) {
+      fp_sub(&t1, modulus, &t1);
+   }
+
+   /* Y = 2Y */
+   fp_add(R->y, R->y, R->y);
+   if (fp_cmp(R->y, modulus) != FP_LT) {
+      fp_sub(R->y, modulus, R->y);
+   }
+   /* Y = Y * Y */
+   fp_sqr(R->y, R->y);
+   fp_montgomery_reduce(R->y, modulus, *mp);
+   /* T2 = Y * Y */
+   fp_sqr(R->y, &t2);
+   fp_montgomery_reduce(&t2, modulus, *mp);
+   /* T2 = T2/2 */
+   if (fp_isodd(&t2)) {
+      fp_add(&t2, modulus, &t2);
+   }
+   fp_div_2(&t2, &t2);
+   /* Y = Y * X */
+   fp_mul(R->y, R->x, R->y);
+   fp_montgomery_reduce(R->y, modulus, *mp);
+
+   /* X  = T1 * T1 */
+   fp_sqr(&t1, R->x);
+   fp_montgomery_reduce(R->x, modulus, *mp);
+   /* X = X - Y */
+   fp_sub(R->x, R->y, R->x);
+   if (fp_cmp_d(R->x, 0) == FP_LT) {
+      fp_add(R->x, modulus, R->x);
+   }
+   /* X = X - Y */
+   fp_sub(R->x, R->y, R->x);
+   if (fp_cmp_d(R->x, 0) == FP_LT) {
+      fp_add(R->x, modulus, R->x);
+   }
+
+   /* Y = Y - X */
+   fp_sub(R->y, R->x, R->y);
+   if (fp_cmp_d(R->y, 0) == FP_LT) {
+      fp_add(R->y, modulus, R->y);
+   }
+   /* Y = Y * T1 */
+   fp_mul(R->y, &t1, R->y);
+   fp_montgomery_reduce(R->y, modulus, *mp);
+   /* Y = Y - T2 */
+   fp_sub(R->y, &t2, R->y);
+   if (fp_cmp_d(R->y, 0) == FP_LT) {
+      fp_add(R->y, modulus, R->y);
+   }
+
+   return MP_OKAY;
+}
+
+#else /* USE_FAST_MATH */
+
+/**
+   Add two ECC points
+   P        The point to add
+   Q        The point to add
+   R        [out] The destination of the double
+   modulus  The modulus of the field the ECC curve is in
+   mp       The "b" value from montgomery_setup()
+   return   MP_OKAY on success
+*/
+int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
+                             mp_int* modulus, mp_digit* mp)
+{
+   mp_int t1;
+   mp_int t2;
+   mp_int x;
+   mp_int y;
+   mp_int z;
+   int    err;
+
+   if (P == NULL || Q == NULL || R == NULL || modulus == NULL || mp == NULL)
+       return ECC_BAD_ARG_E;
+
+   if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != MP_OKAY) {
+      return err;
+   }
+
+   /* should we dbl instead? */
+   err = mp_sub(modulus, Q->y, &t1);
+
+   if (err == MP_OKAY) {
+       if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
+            (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
+            (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, &t1) == MP_EQ)) {
+                mp_clear(&t1);
+                mp_clear(&t2);
+                mp_clear(&x);
+                mp_clear(&y);
+                mp_clear(&z);
+
+                return ecc_projective_dbl_point(P, R, modulus, mp);
+       }
+   }
+
+   if (err == MP_OKAY)
+       err = mp_copy(P->x, &x);
+   if (err == MP_OKAY)
+       err = mp_copy(P->y, &y);
+   if (err == MP_OKAY)
+       err = mp_copy(P->z, &z);
+
+   /* if Z is one then these are no-operations */
+   if (err == MP_OKAY) {
+       if (get_digit_count(Q->z)) {
+           /* T1 = Z' * Z' */
+           err = mp_sqr(Q->z, &t1);
+           if (err == MP_OKAY)
+               err = mp_montgomery_reduce(&t1, modulus, *mp);
+
+           /* X = X * T1 */
+           if (err == MP_OKAY)
+               err = mp_mul(&t1, &x, &x);
+           if (err == MP_OKAY)
+               err = mp_montgomery_reduce(&x, modulus, *mp);
+
+           /* T1 = Z' * T1 */
+           if (err == MP_OKAY)
+               err = mp_mul(Q->z, &t1, &t1);
+           if (err == MP_OKAY)
+               err = mp_montgomery_reduce(&t1, modulus, *mp);
+
+           /* Y = Y * T1 */
+           if (err == MP_OKAY)
+               err = mp_mul(&t1, &y, &y);
+           if (err == MP_OKAY)
+               err = mp_montgomery_reduce(&y, modulus, *mp);
+       }
+   }
+
+   /* T1 = Z*Z */
+   if (err == MP_OKAY)
+       err = mp_sqr(&z, &t1);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(&t1, modulus, *mp);
+
+   /* T2 = X' * T1 */
+   if (err == MP_OKAY)
+       err = mp_mul(Q->x, &t1, &t2);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(&t2, modulus, *mp);
+
+   /* T1 = Z * T1 */
+   if (err == MP_OKAY)
+       err = mp_mul(&z, &t1, &t1);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(&t1, modulus, *mp);
+
+   /* T1 = Y' * T1 */
+   if (err == MP_OKAY)
+       err = mp_mul(Q->y, &t1, &t1);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(&t1, modulus, *mp);
+
+   /* Y = Y - T1 */
+   if (err == MP_OKAY)
+       err = mp_sub(&y, &t1, &y);
+   if (err == MP_OKAY) {
+       if (mp_cmp_d(&y, 0) == MP_LT)
+           err = mp_add(&y, modulus, &y);
+   }
+   /* T1 = 2T1 */
+   if (err == MP_OKAY)
+       err = mp_add(&t1, &t1, &t1);
+   if (err == MP_OKAY) {
+       if (mp_cmp(&t1, modulus) != MP_LT)
+           err = mp_sub(&t1, modulus, &t1);
+   }
+   /* T1 = Y + T1 */
+   if (err == MP_OKAY)
+       err = mp_add(&t1, &y, &t1);
+   if (err == MP_OKAY) {
+       if (mp_cmp(&t1, modulus) != MP_LT)
+           err = mp_sub(&t1, modulus, &t1);
+   }
+   /* X = X - T2 */
+   if (err == MP_OKAY)
+       err = mp_sub(&x, &t2, &x);
+   if (err == MP_OKAY) {
+       if (mp_cmp_d(&x, 0) == MP_LT)
+           err = mp_add(&x, modulus, &x);
+   }
+   /* T2 = 2T2 */
+   if (err == MP_OKAY)
+       err = mp_add(&t2, &t2, &t2);
+   if (err == MP_OKAY) {
+       if (mp_cmp(&t2, modulus) != MP_LT)
+           err = mp_sub(&t2, modulus, &t2);
+   }
+   /* T2 = X + T2 */
+   if (err == MP_OKAY)
+       err = mp_add(&t2, &x, &t2);
+   if (err == MP_OKAY) {
+       if (mp_cmp(&t2, modulus) != MP_LT)
+           err = mp_sub(&t2, modulus, &t2);
+   }
+
+   if (err == MP_OKAY) {
+       if (get_digit_count(Q->z)) {
+           /* Z = Z * Z' */
+           err = mp_mul(&z, Q->z, &z);
+           if (err == MP_OKAY)
+               err = mp_montgomery_reduce(&z, modulus, *mp);
+       }
+   }
+
+   /* Z = Z * X */
+   if (err == MP_OKAY)
+       err = mp_mul(&z, &x, &z);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(&z, modulus, *mp);
+
+   /* T1 = T1 * X  */
+   if (err == MP_OKAY)
+       err = mp_mul(&t1, &x, &t1);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(&t1, modulus, *mp);
+
+   /* X = X * X */
+   if (err == MP_OKAY)
+       err = mp_sqr(&x, &x);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(&x, modulus, *mp);
+
+   /* T2 = T2 * x */
+   if (err == MP_OKAY)
+       err = mp_mul(&t2, &x, &t2);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(&t2, modulus, *mp);
+
+   /* T1 = T1 * X  */
+   if (err == MP_OKAY)
+       err = mp_mul(&t1, &x, &t1);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(&t1, modulus, *mp);
+
+   /* X = Y*Y */
+   if (err == MP_OKAY)
+       err = mp_sqr(&y, &x);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(&x, modulus, *mp);
+
+   /* X = X - T2 */
+   if (err == MP_OKAY)
+       err = mp_sub(&x, &t2, &x);
+   if (err == MP_OKAY) {
+       if (mp_cmp_d(&x, 0) == MP_LT)
+           err = mp_add(&x, modulus, &x);
+   }
+   /* T2 = T2 - X */
+   if (err == MP_OKAY)
+       err = mp_sub(&t2, &x, &t2);
+   if (err == MP_OKAY) {
+       if (mp_cmp_d(&t2, 0) == MP_LT)
+           err = mp_add(&t2, modulus, &t2);
+   }
+   /* T2 = T2 - X */
+   if (err == MP_OKAY)
+       err = mp_sub(&t2, &x, &t2);
+   if (err == MP_OKAY) {
+       if (mp_cmp_d(&t2, 0) == MP_LT)
+           err = mp_add(&t2, modulus, &t2);
+   }
+   /* T2 = T2 * Y */
+   if (err == MP_OKAY)
+       err = mp_mul(&t2, &y, &t2);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(&t2, modulus, *mp);
+
+   /* Y = T2 - T1 */
+   if (err == MP_OKAY)
+       err = mp_sub(&t2, &t1, &y);
+   if (err == MP_OKAY) {
+       if (mp_cmp_d(&y, 0) == MP_LT)
+           err = mp_add(&y, modulus, &y);
+   }
+   /* Y = Y/2 */
+   if (err == MP_OKAY) {
+       if (mp_isodd(&y))
+           err = mp_add(&y, modulus, &y);
+   }
+   if (err == MP_OKAY)
+       err = mp_div_2(&y, &y);
+
+   if (err == MP_OKAY)
+       err = mp_copy(&x, R->x);
+   if (err == MP_OKAY)
+       err = mp_copy(&y, R->y);
+   if (err == MP_OKAY)
+       err = mp_copy(&z, R->z);
+
+   /* clean up */
+   mp_clear(&t1);
+   mp_clear(&t2);
+   mp_clear(&x);
+   mp_clear(&y);
+   mp_clear(&z);
+
+   return err;
+}
+
+
+/**
+   Double an ECC point
+   P   The point to double
+   R   [out] The destination of the double
+   modulus  The modulus of the field the ECC curve is in
+   mp       The "b" value from montgomery_setup()
+   return   MP_OKAY on success
+*/
+int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* modulus,
+                             mp_digit* mp)
+{
+   mp_int t1;
+   mp_int t2;
+   int    err;
+
+   if (P == NULL || R == NULL || modulus == NULL || mp == NULL)
+       return ECC_BAD_ARG_E;
+
+   if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
+      return err;
+   }
+
+   if (P != R) {
+      err = mp_copy(P->x, R->x);
+      if (err == MP_OKAY)
+          err = mp_copy(P->y, R->y);
+      if (err == MP_OKAY)
+          err = mp_copy(P->z, R->z);
+   }
+
+   /* t1 = Z * Z */
+   if (err == MP_OKAY)
+       err = mp_sqr(R->z, &t1);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(&t1, modulus, *mp);
+
+   /* Z = Y * Z */
+   if (err == MP_OKAY)
+       err = mp_mul(R->z, R->y, R->z);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(R->z, modulus, *mp);
+
+   /* Z = 2Z */
+   if (err == MP_OKAY)
+       err = mp_add(R->z, R->z, R->z);
+   if (err == MP_OKAY) {
+       if (mp_cmp(R->z, modulus) != MP_LT)
+           err = mp_sub(R->z, modulus, R->z);
+   }
+
+   /* T2 = X - T1 */
+   if (err == MP_OKAY)
+       err = mp_sub(R->x, &t1, &t2);
+   if (err == MP_OKAY) {
+       if (mp_cmp_d(&t2, 0) == MP_LT)
+           err = mp_add(&t2, modulus, &t2);
+   }
+   /* T1 = X + T1 */
+   if (err == MP_OKAY)
+       err = mp_add(&t1, R->x, &t1);
+   if (err == MP_OKAY) {
+       if (mp_cmp(&t1, modulus) != MP_LT)
+           err = mp_sub(&t1, modulus, &t1);
+   }
+   /* T2 = T1 * T2 */
+   if (err == MP_OKAY)
+       err = mp_mul(&t1, &t2, &t2);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(&t2, modulus, *mp);
+
+   /* T1 = 2T2 */
+   if (err == MP_OKAY)
+       err = mp_add(&t2, &t2, &t1);
+   if (err == MP_OKAY) {
+       if (mp_cmp(&t1, modulus) != MP_LT)
+           err = mp_sub(&t1, modulus, &t1);
+   }
+   /* T1 = T1 + T2 */
+   if (err == MP_OKAY)
+       err = mp_add(&t1, &t2, &t1);
+   if (err == MP_OKAY) {
+       if (mp_cmp(&t1, modulus) != MP_LT)
+           err = mp_sub(&t1, modulus, &t1);
+   }
+   /* Y = 2Y */
+   if (err == MP_OKAY)
+       err = mp_add(R->y, R->y, R->y);
+   if (err == MP_OKAY) {
+       if (mp_cmp(R->y, modulus) != MP_LT)
+           err = mp_sub(R->y, modulus, R->y);
+   }
+   /* Y = Y * Y */
+   if (err == MP_OKAY)
+       err = mp_sqr(R->y, R->y);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(R->y, modulus, *mp);
+
+   /* T2 = Y * Y */
+   if (err == MP_OKAY)
+       err = mp_sqr(R->y, &t2);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(&t2, modulus, *mp);
+
+   /* T2 = T2/2 */
+   if (err == MP_OKAY) {
+       if (mp_isodd(&t2))
+           err = mp_add(&t2, modulus, &t2);
+   }
+   if (err == MP_OKAY)
+       err = mp_div_2(&t2, &t2);
+
+   /* Y = Y * X */
+   if (err == MP_OKAY)
+       err = mp_mul(R->y, R->x, R->y);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(R->y, modulus, *mp);
+
+   /* X  = T1 * T1 */
+   if (err == MP_OKAY)
+       err = mp_sqr(&t1, R->x);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(R->x, modulus, *mp);
+
+   /* X = X - Y */
+   if (err == MP_OKAY)
+       err = mp_sub(R->x, R->y, R->x);
+   if (err == MP_OKAY) {
+       if (mp_cmp_d(R->x, 0) == MP_LT)
+           err = mp_add(R->x, modulus, R->x);
+   }
+   /* X = X - Y */
+   if (err == MP_OKAY)
+       err = mp_sub(R->x, R->y, R->x);
+   if (err == MP_OKAY) {
+       if (mp_cmp_d(R->x, 0) == MP_LT)
+           err = mp_add(R->x, modulus, R->x);
+   }
+   /* Y = Y - X */
+   if (err == MP_OKAY)
+       err = mp_sub(R->y, R->x, R->y);
+   if (err == MP_OKAY) {
+       if (mp_cmp_d(R->y, 0) == MP_LT)
+           err = mp_add(R->y, modulus, R->y);
+   }
+   /* Y = Y * T1 */
+   if (err == MP_OKAY)
+       err = mp_mul(R->y, &t1, R->y);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(R->y, modulus, *mp);
+
+   /* Y = Y - T2 */
+   if (err == MP_OKAY)
+       err = mp_sub(R->y, &t2, R->y);
+   if (err == MP_OKAY) {
+       if (mp_cmp_d(R->y, 0) == MP_LT)
+           err = mp_add(R->y, modulus, R->y);
+   }
+
+   /* clean up */
+   mp_clear(&t1);
+   mp_clear(&t2);
+
+   return err;
+}
+
+#endif /* USE_FAST_MATH */
+
+/**
+  Map a projective jacbobian point back to affine space
+  P        [in/out] The point to map
+  modulus  The modulus of the field the ECC curve is in
+  mp       The "b" value from montgomery_setup()
+  return   MP_OKAY on success
+*/
+int ecc_map(ecc_point* P, mp_int* modulus, mp_digit* mp)
+{
+   mp_int t1;
+   mp_int t2;
+   int    err;
+
+   if (P == NULL || mp == NULL || modulus == NULL)
+       return ECC_BAD_ARG_E;
+
+   /* special case for point at infinity */
+   if (mp_cmp_d(P->z, 0) == MP_EQ) {
+       mp_set(P->x, 0);
+       mp_set(P->y, 0);
+       mp_set(P->z, 1);
+       return MP_OKAY;
+   }
+
+   if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
+      return MEMORY_E;
+   }
+
+   /* first map z back to normal */
+   err = mp_montgomery_reduce(P->z, modulus, *mp);
+
+   /* get 1/z */
+   if (err == MP_OKAY)
+       err = mp_invmod(P->z, modulus, &t1);
+
+   /* get 1/z^2 and 1/z^3 */
+   if (err == MP_OKAY)
+       err = mp_sqr(&t1, &t2);
+   if (err == MP_OKAY)
+       err = mp_mod(&t2, modulus, &t2);
+   if (err == MP_OKAY)
+       err = mp_mul(&t1, &t2, &t1);
+   if (err == MP_OKAY)
+       err = mp_mod(&t1, modulus, &t1);
+
+   /* multiply against x/y */
+   if (err == MP_OKAY)
+       err = mp_mul(P->x, &t2, P->x);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(P->x, modulus, *mp);
+   if (err == MP_OKAY)
+       err = mp_mul(P->y, &t1, P->y);
+   if (err == MP_OKAY)
+       err = mp_montgomery_reduce(P->y, modulus, *mp);
+
+   if (err == MP_OKAY)
+       mp_set(P->z, 1);
+
+   /* clean up */
+   mp_clear(&t1);
+   mp_clear(&t2);
+
+   return err;
+}
+
+
+#ifndef ECC_TIMING_RESISTANT
+
+/* size of sliding window, don't change this! */
+#define WINSIZE 4
+
+/**
+   Perform a point multiplication
+   k    The scalar to multiply by
+   G    The base point
+   R    [out] Destination for kG
+   modulus  The modulus of the field the ECC curve is in
+   map      Boolean whether to map back to affine or not
+                (1==map, 0 == leave in projective)
+   return MP_OKAY on success
+*/
+#ifdef FP_ECC
+static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R,
+                      mp_int* modulus, int map)
+#else
+int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus,
+               int map)
+#endif
+{
+   ecc_point *tG, *M[8];
+   int           i, j, err;
+   mp_int        mu;
+   mp_digit      mp;
+   mp_digit      buf;
+   int           first = 1, bitbuf = 0, bitcpy = 0, bitcnt = 0, mode = 0,
+                 digidx = 0;
+
+   if (k == NULL || G == NULL || R == NULL || modulus == NULL)
+       return ECC_BAD_ARG_E;
+
+   /* init montgomery reduction */
+   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
+      return err;
+   }
+   if ((err = mp_init(&mu)) != MP_OKAY) {
+      return err;
+   }
+   if ((err = mp_montgomery_calc_normalization(&mu, modulus)) != MP_OKAY) {
+      mp_clear(&mu);
+      return err;
+   }
+
+  /* alloc ram for window temps */
+  for (i = 0; i < 8; i++) {
+      M[i] = wc_ecc_new_point();
+      if (M[i] == NULL) {
+         for (j = 0; j < i; j++) {
+             wc_ecc_del_point(M[j]);
+         }
+         mp_clear(&mu);
+         return MEMORY_E;
+      }
+  }
+
+   /* make a copy of G incase R==G */
+   tG = wc_ecc_new_point();
+   if (tG == NULL)
+       err = MEMORY_E;
+
+   /* tG = G  and convert to montgomery */
+   if (err == MP_OKAY) {
+       if (mp_cmp_d(&mu, 1) == MP_EQ) {
+           err = mp_copy(G->x, tG->x);
+           if (err == MP_OKAY)
+               err = mp_copy(G->y, tG->y);
+           if (err == MP_OKAY)
+               err = mp_copy(G->z, tG->z);
+       } else {
+           err = mp_mulmod(G->x, &mu, modulus, tG->x);
+           if (err == MP_OKAY)
+               err = mp_mulmod(G->y, &mu, modulus, tG->y);
+           if (err == MP_OKAY)
+               err = mp_mulmod(G->z, &mu, modulus, tG->z);
+       }
+   }
+   mp_clear(&mu);
+
+   /* calc the M tab, which holds kG for k==8..15 */
+   /* M[0] == 8G */
+   if (err == MP_OKAY)
+       err = ecc_projective_dbl_point(tG, M[0], modulus, &mp);
+   if (err == MP_OKAY)
+       err = ecc_projective_dbl_point(M[0], M[0], modulus, &mp);
+   if (err == MP_OKAY)
+       err = ecc_projective_dbl_point(M[0], M[0], modulus, &mp);
+
+   /* now find (8+k)G for k=1..7 */
+   if (err == MP_OKAY)
+       for (j = 9; j < 16; j++) {
+           err = ecc_projective_add_point(M[j-9], tG, M[j-8], modulus, &mp);
+           if (err != MP_OKAY) break;
+       }
+
+   /* setup sliding window */
+   if (err == MP_OKAY) {
+       mode   = 0;
+       bitcnt = 1;
+       buf    = 0;
+       digidx = get_digit_count(k) - 1;
+       bitcpy = bitbuf = 0;
+       first  = 1;
+
+       /* perform ops */
+       for (;;) {
+           /* grab next digit as required */
+           if (--bitcnt == 0) {
+               if (digidx == -1) {
+                   break;
+               }
+               buf    = get_digit(k, digidx);
+               bitcnt = (int) DIGIT_BIT;
+               --digidx;
+           }
+
+           /* grab the next msb from the ltiplicand */
+           i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
+           buf <<= 1;
+
+           /* skip leading zero bits */
+           if (mode == 0 && i == 0)
+               continue;
+
+           /* if the bit is zero and mode == 1 then we double */
+           if (mode == 1 && i == 0) {
+               err = ecc_projective_dbl_point(R, R, modulus, &mp);
+               if (err != MP_OKAY) break;
+               continue;
+           }
+
+           /* else we add it to the window */
+           bitbuf |= (i << (WINSIZE - ++bitcpy));
+           mode = 2;
+
+           if (bitcpy == WINSIZE) {
+               /* if this is the first window we do a simple copy */
+               if (first == 1) {
+                   /* R = kG [k = first window] */
+                   err = mp_copy(M[bitbuf-8]->x, R->x);
+                   if (err != MP_OKAY) break;
+
+                   err = mp_copy(M[bitbuf-8]->y, R->y);
+                   if (err != MP_OKAY) break;
+
+                   err = mp_copy(M[bitbuf-8]->z, R->z);
+                   first = 0;
+               } else {
+                   /* normal window */
+                   /* ok window is filled so double as required and add  */
+                   /* double first */
+                   for (j = 0; j < WINSIZE; j++) {
+                       err = ecc_projective_dbl_point(R, R, modulus, &mp);
+                       if (err != MP_OKAY) break;
+                   }
+                   if (err != MP_OKAY) break;  /* out of first for(;;) */
+
+                   /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranted */
+                   err = ecc_projective_add_point(R,M[bitbuf-8],R,modulus,&mp);
+               }
+               if (err != MP_OKAY) break;
+               /* empty window and reset */
+               bitcpy = bitbuf = 0;
+               mode = 1;
+           }
+       }
+   }
+
+   /* if bits remain then double/add */
+   if (err == MP_OKAY) {
+       if (mode == 2 && bitcpy > 0) {
+           /* double then add */
+           for (j = 0; j < bitcpy; j++) {
+               /* only double if we have had at least one add first */
+               if (first == 0) {
+                   err = ecc_projective_dbl_point(R, R, modulus, &mp);
+                   if (err != MP_OKAY) break;
+               }
+
+               bitbuf <<= 1;
+               if ((bitbuf & (1 << WINSIZE)) != 0) {
+                   if (first == 1) {
+                       /* first add, so copy */
+                       err = mp_copy(tG->x, R->x);
+                       if (err != MP_OKAY) break;
+
+                       err = mp_copy(tG->y, R->y);
+                       if (err != MP_OKAY) break;
+
+                       err = mp_copy(tG->z, R->z);
+                       if (err != MP_OKAY) break;
+                       first = 0;
+                   } else {
+                       /* then add */
+                       err = ecc_projective_add_point(R, tG, R, modulus, &mp);
+                       if (err != MP_OKAY) break;
+                   }
+               }
+           }
+       }
+   }
+
+   /* map R back from projective space */
+   if (err == MP_OKAY && map)
+       err = ecc_map(R, modulus, &mp);
+
+   mp_clear(&mu);
+   wc_ecc_del_point(tG);
+   for (i = 0; i < 8; i++) {
+       wc_ecc_del_point(M[i]);
+   }
+   return err;
+}
+
+#undef WINSIZE
+
+#else /* ECC_TIMING_RESISTANT */
+
+/**
+   Perform a point multiplication  (timing resistant)
+   k    The scalar to multiply by
+   G    The base point
+   R    [out] Destination for kG
+   modulus  The modulus of the field the ECC curve is in
+   map      Boolean whether to map back to affine or not
+            (1==map, 0 == leave in projective)
+   return MP_OKAY on success
+*/
+#ifdef FP_ECC
+static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R,
+                      mp_int* modulus, int map)
+#else
+int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus,
+              int map)
+#endif
+{
+   ecc_point    *tG, *M[3];
+   int           i, j, err;
+   mp_int        mu;
+   mp_digit      mp;
+   mp_digit      buf;
+   int           bitcnt = 0, mode = 0, digidx = 0;
+
+   if (k == NULL || G == NULL || R == NULL || modulus == NULL)
+       return ECC_BAD_ARG_E;
+
+   /* init montgomery reduction */
+   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
+      return err;
+   }
+   if ((err = mp_init(&mu)) != MP_OKAY) {
+      return err;
+   }
+   if ((err = mp_montgomery_calc_normalization(&mu, modulus)) != MP_OKAY) {
+      mp_clear(&mu);
+      return err;
+   }
+
+  /* alloc ram for window temps */
+  for (i = 0; i < 3; i++) {
+      M[i] = wc_ecc_new_point();
+      if (M[i] == NULL) {
+         for (j = 0; j < i; j++) {
+             wc_ecc_del_point(M[j]);
+         }
+         mp_clear(&mu);
+         return MEMORY_E;
+      }
+  }
+
+   /* make a copy of G incase R==G */
+   tG = wc_ecc_new_point();
+   if (tG == NULL)
+       err = MEMORY_E;
+
+   /* tG = G  and convert to montgomery */
+   if (err == MP_OKAY) {
+       err = mp_mulmod(G->x, &mu, modulus, tG->x);
+       if (err == MP_OKAY)
+           err = mp_mulmod(G->y, &mu, modulus, tG->y);
+       if (err == MP_OKAY)
+           err = mp_mulmod(G->z, &mu, modulus, tG->z);
+   }
+   mp_clear(&mu);
+
+   /* calc the M tab */
+   /* M[0] == G */
+   if (err == MP_OKAY)
+       err = mp_copy(tG->x, M[0]->x);
+   if (err == MP_OKAY)
+       err = mp_copy(tG->y, M[0]->y);
+   if (err == MP_OKAY)
+       err = mp_copy(tG->z, M[0]->z);
+
+   /* M[1] == 2G */
+   if (err == MP_OKAY)
+       err = ecc_projective_dbl_point(tG, M[1], modulus, &mp);
+
+   /* setup sliding window */
+   mode   = 0;
+   bitcnt = 1;
+   buf    = 0;
+   digidx = get_digit_count(k) - 1;
+
+   /* perform ops */
+   if (err == MP_OKAY) {
+       for (;;) {
+           /* grab next digit as required */
+           if (--bitcnt == 0) {
+               if (digidx == -1) {
+                   break;
+               }
+               buf = get_digit(k, digidx);
+               bitcnt = (int) DIGIT_BIT;
+               --digidx;
+           }
+
+           /* grab the next msb from the ltiplicand */
+           i = (buf >> (DIGIT_BIT - 1)) & 1;
+           buf <<= 1;
+
+           if (mode == 0 && i == 0) {
+               /* dummy operations */
+               if (err == MP_OKAY)
+                   err = ecc_projective_add_point(M[0], M[1], M[2], modulus,
+                                                  &mp);
+               if (err == MP_OKAY)
+                   err = ecc_projective_dbl_point(M[1], M[2], modulus, &mp);
+               if (err == MP_OKAY)
+                   continue;
+           }
+
+           if (mode == 0 && i == 1) {
+               mode = 1;
+               /* dummy operations */
+               if (err == MP_OKAY)
+                   err = ecc_projective_add_point(M[0], M[1], M[2], modulus,
+                                                  &mp);
+               if (err == MP_OKAY)
+                   err = ecc_projective_dbl_point(M[1], M[2], modulus, &mp);
+               if (err == MP_OKAY)
+                   continue;
+           }
+
+           if (err == MP_OKAY)
+               err = ecc_projective_add_point(M[0], M[1], M[i^1], modulus, &mp);
+           if (err == MP_OKAY)
+               err = ecc_projective_dbl_point(M[i], M[i], modulus, &mp);
+           if (err != MP_OKAY)
+               break;
+       } /* end for */
+   }
+
+   /* copy result out */
+   if (err == MP_OKAY)
+       err = mp_copy(M[0]->x, R->x);
+   if (err == MP_OKAY)
+       err = mp_copy(M[0]->y, R->y);
+   if (err == MP_OKAY)
+       err = mp_copy(M[0]->z, R->z);
+
+   /* map R back from projective space */
+   if (err == MP_OKAY && map)
+      err = ecc_map(R, modulus, &mp);
+
+   /* done */
+   mp_clear(&mu);
+   wc_ecc_del_point(tG);
+   for (i = 0; i < 3; i++) {
+       wc_ecc_del_point(M[i]);
+   }
+   return err;
+}
+
+#endif /* ECC_TIMING_RESISTANT */
+
+
+#ifdef ALT_ECC_SIZE
+
+static void alt_fp_init(fp_int* a)
+{
+    a->size = FP_SIZE_ECC;
+    fp_zero(a);
+}
+
+#endif /* ALT_ECC_SIZE */
+
+
+/**
+   Allocate a new ECC point
+   return A newly allocated point or NULL on error
+*/
+ecc_point* wc_ecc_new_point(void)
+{
+   ecc_point* p;
+
+   p = (ecc_point*)XMALLOC(sizeof(ecc_point), 0, DYNAMIC_TYPE_ECC);
+   if (p == NULL) {
+      return NULL;
+   }
+   XMEMSET(p, 0, sizeof(ecc_point));
+
+#ifndef USE_FAST_MATH
+   p->x->dp = NULL;
+   p->y->dp = NULL;
+   p->z->dp = NULL;
+#endif
+
+#ifndef ALT_ECC_SIZE
+   if (mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL) != MP_OKAY) {
+      XFREE(p, 0, DYNAMIC_TYPE_ECC);
+      return NULL;
+   }
+#else
+   p->x = (mp_int*)&p->xyz[0];
+   p->y = (mp_int*)&p->xyz[1];
+   p->z = (mp_int*)&p->xyz[2];
+   alt_fp_init(p->x);
+   alt_fp_init(p->y);
+   alt_fp_init(p->z);
+#endif
+
+   return p;
+}
+
+/** Free an ECC point from memory
+  p   The point to free
+*/
+void wc_ecc_del_point(ecc_point* p)
+{
+   /* prevents free'ing null arguments */
+   if (p != NULL) {
+      mp_clear(p->x);
+      mp_clear(p->y);
+      mp_clear(p->z);
+      XFREE(p, 0, DYNAMIC_TYPE_ECC);
+   }
+}
+
+/** Copy the value of a point to an other one
+  p    The point to copy
+  r    The created point
+*/
+int wc_ecc_copy_point(ecc_point* p, ecc_point *r)
+{
+    int ret;
+
+    /* prevents null arguments */
+    if (p == NULL || r == NULL)
+        return ECC_BAD_ARG_E;
+
+    ret = mp_copy(p->x, r->x);
+    if (ret != MP_OKAY)
+        return ret;
+    ret = mp_copy(p->y, r->y);
+    if (ret != MP_OKAY)
+        return ret;
+    ret = mp_copy(p->z, r->z);
+    if (ret != MP_OKAY)
+        return ret;
+
+    return MP_OKAY;
+}
+
+/** Compare the value of a point with an other one
+ a    The point to compare
+ b    The othe point to compare
+
+ return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
+ */
+int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
+{
+    int ret;
+
+    /* prevents null arguments */
+    if (a == NULL || b == NULL)
+        return BAD_FUNC_ARG;
+
+    ret = mp_cmp(a->x, b->x);
+    if (ret != MP_EQ)
+        return ret;
+    ret = mp_cmp(a->y, b->y);
+    if (ret != MP_EQ)
+        return ret;
+    ret = mp_cmp(a->z, b->z);
+    if (ret != MP_EQ)
+        return ret;
+
+    return MP_EQ;
+}
+
+/** Returns whether an ECC idx is valid or not
+  n      The idx number to check
+  return 1 if valid, 0 if not
+*/
+int wc_ecc_is_valid_idx(int n)
+{
+   int x;
+
+   for (x = 0; ecc_sets[x].size != 0; x++)
+       ;
+   /* -1 is a valid index --- indicating that the domain params
+      were supplied by the user */
+   if ((n >= -1) && (n < x)) {
+      return 1;
+   }
+   return 0;
+}
+
+
+/**
+  Create an ECC shared secret between two keys
+  private_key      The private ECC key
+  public_key       The public key
+  out              [out] Destination of the shared secret
+                   Conforms to EC-DH from ANSI X9.63
+  outlen           [in/out] The max size and resulting size of the shared secret
+  return           MP_OKAY if successful
+*/
+int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
+                      word32* outlen)
+{
+   word32         x = 0;
+   ecc_point*     result;
+   mp_int         prime;
+   int            err;
+
+   if (private_key == NULL || public_key == NULL || out == NULL ||
+                                                    outlen == NULL)
+       return BAD_FUNC_ARG;
+
+   /* type valid? */
+   if (private_key->type != ECC_PRIVATEKEY) {
+      return ECC_BAD_ARG_E;
+   }
+
+   if (wc_ecc_is_valid_idx(private_key->idx) == 0 ||
+       wc_ecc_is_valid_idx(public_key->idx)  == 0)
+      return ECC_BAD_ARG_E;
+
+   if (XSTRNCMP(private_key->dp->name, public_key->dp->name, ECC_MAXNAME) != 0)
+      return ECC_BAD_ARG_E;
+
+   /* make new point */
+   result = wc_ecc_new_point();
+   if (result == NULL) {
+      return MEMORY_E;
+   }
+
+   if ((err = mp_init(&prime)) != MP_OKAY) {
+      wc_ecc_del_point(result);
+      return err;
+   }
+
+   err = mp_read_radix(&prime, (char *)private_key->dp->prime, 16);
+
+   if (err == MP_OKAY)
+       err = wc_ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime,1);
+
+   if (err == MP_OKAY) {
+       x = mp_unsigned_bin_size(&prime);
+       if (*outlen < x)
+          err = BUFFER_E;
+   }
+
+   if (err == MP_OKAY) {
+       XMEMSET(out, 0, x);
+       err = mp_to_unsigned_bin(result->x,out + (x -
+                                              mp_unsigned_bin_size(result->x)));
+       *outlen = x;
+   }
+
+   mp_clear(&prime);
+   wc_ecc_del_point(result);
+
+   return err;
+}
+
+/**
+ Create an ECC shared secret between two keys
+ private_key      The private ECC key
+ point              The point to use (public key)
+ out              [out] Destination of the shared secret
+ Conforms to EC-DH from ANSI X9.63
+ outlen           [in/out] The max size and resulting size of the shared secret
+ return           MP_OKAY if successful
+ */
+int wc_ecc_shared_secret_ssh(ecc_key* private_key, ecc_point* point,
+                             byte* out, word32 *outlen)
+{
+    word32         x = 0;
+    ecc_point*     result;
+    mp_int         prime;
+    int            err;
+
+    if (private_key == NULL || point == NULL || out == NULL || outlen == NULL)
+        return BAD_FUNC_ARG;
+
+    /* type valid? */
+    if (private_key->type != ECC_PRIVATEKEY) {
+        return ECC_BAD_ARG_E;
+    }
+
+    if (wc_ecc_is_valid_idx(private_key->idx) == 0)
+        return ECC_BAD_ARG_E;
+
+    /* make new point */
+    result = wc_ecc_new_point();
+    if (result == NULL) {
+        return MEMORY_E;
+    }
+
+    if ((err = mp_init(&prime)) != MP_OKAY) {
+        wc_ecc_del_point(result);
+        return err;
+    }
+
+    err = mp_read_radix(&prime, (char *)private_key->dp->prime, 16);
+
+    if (err == MP_OKAY)
+        err = wc_ecc_mulmod(&private_key->k, point, result, &prime, 1);
+
+    if (err == MP_OKAY) {
+        x = mp_unsigned_bin_size(&prime);
+        if (*outlen < x)
+            err = BUFFER_E;
+    }
+
+    if (err == MP_OKAY) {
+        XMEMSET(out, 0, x);
+        err = mp_to_unsigned_bin(result->x,out +
+                                 (x - mp_unsigned_bin_size(result->x)));
+        *outlen = x;
+    }
+
+    mp_clear(&prime);
+    wc_ecc_del_point(result);
+
+    return err;
+}
+
+
+/* return 1 if point is at infinity, 0 if not, < 0 on error */
+int wc_ecc_point_is_at_infinity(ecc_point* p)
+{
+    if (p == NULL)
+        return BAD_FUNC_ARG;
+
+    if (get_digit_count(p->x) == 0 && get_digit_count(p->y) == 0)
+        return 1;
+
+    return 0;
+}
+
+
+static int wc_ecc_make_key_ex(WC_RNG* rng, ecc_key* key, const ecc_set_type* dp)
+{
+   int            err;
+   ecc_point*     base;
+   mp_int         prime;
+   mp_int         order;
+#ifdef WOLFSSL_SMALL_STACK
+   byte*          buf;
+#else
+   byte           buf[ECC_MAXSIZE_GEN];
+#endif
+   int            keysize;
+   int            po_init = 0;  /* prime order Init flag for clear */
+
+   if (key == NULL || rng == NULL || dp == NULL)
+       return ECC_BAD_ARG_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+   buf = (byte*)XMALLOC(ECC_MAXSIZE_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+   if (buf == NULL)
+       return MEMORY_E;
+#endif
+
+   key->idx = -1;
+   key->dp  = dp;
+
+   /*generate 8 extra bytes to mitigate bias from the modulo operation below*/
+   /*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/
+   keysize  = dp->size + 8;
+
+   /* allocate ram */
+   base = NULL;
+
+   /* make up random string */
+   err = wc_RNG_GenerateBlock(rng, buf, keysize);
+
+   /* setup the key variables */
+   if (err == 0) {
+#ifndef ALT_ECC_SIZE
+       err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z,
+                            &key->k, &prime, &order);
+#else
+       key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
+       key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
+       key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
+       alt_fp_init(key->pubkey.x);
+       alt_fp_init(key->pubkey.y);
+       alt_fp_init(key->pubkey.z);
+       err = mp_init_multi(&key->k, &prime, &order, NULL, NULL, NULL);
+#endif
+       if (err != MP_OKAY)
+           err = MEMORY_E;
+       else
+           po_init = 1;
+   }
+
+   if (err == MP_OKAY) {
+       base = wc_ecc_new_point();
+       if (base == NULL)
+           err = MEMORY_E;
+   }
+
+   /* read in the specs for this key */
+   if (err == MP_OKAY)
+       err = mp_read_radix(&prime,   (char *)key->dp->prime, 16);
+   if (err == MP_OKAY)
+       err = mp_read_radix(&order,   (char *)key->dp->order, 16);
+   if (err == MP_OKAY)
+       err = mp_read_radix(base->x, (char *)key->dp->Gx, 16);
+   if (err == MP_OKAY)
+       err = mp_read_radix(base->y, (char *)key->dp->Gy, 16);
+
+   if (err == MP_OKAY)
+       mp_set(base->z, 1);
+   if (err == MP_OKAY)
+       err = mp_read_unsigned_bin(&key->k, (byte*)buf, keysize);
+
+   /* quick sanity check to make sure we're not dealing with a 0 key */
+   if (err == MP_OKAY) {
+       if (MP_YES == mp_iszero(&key->k))
+           err = MP_ZERO_E;
+   }
+
+   /* the key should be smaller than the order of base point */
+   if (err == MP_OKAY) {
+       if (mp_cmp(&key->k, &order) != MP_LT)
+           err = mp_mod(&key->k, &order, &key->k);
+   }
+   /* make the public key */
+   if (err == MP_OKAY)
+       err = wc_ecc_mulmod(&key->k, base, &key->pubkey, &prime, 1);
+
+#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
+   /* validate the public key, order * pubkey = point at infinity */
+   if (err == MP_OKAY)
+       err = ecc_check_pubkey_order(key, &prime, &order);
+#endif /* WOLFSSL_VALIDATE_KEYGEN */
+
+   if (err == MP_OKAY)
+       key->type = ECC_PRIVATEKEY;
+
+   if (err != MP_OKAY) {
+       /* clean up */
+       mp_clear(key->pubkey.x);
+       mp_clear(key->pubkey.y);
+       mp_clear(key->pubkey.z);
+       mp_clear(&key->k);
+   }
+   wc_ecc_del_point(base);
+   if (po_init) {
+       mp_clear(&prime);
+       mp_clear(&order);
+   }
+
+   ForceZero(buf, ECC_MAXSIZE);
+#ifdef WOLFSSL_SMALL_STACK
+   XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+   return err;
+}
+
+/**
+ Make a new ECC key
+ rng          An active RNG state
+ keysize      The keysize for the new key (in octets from 20 to 65 bytes)
+ key          [out] Destination of the newly created key
+ return       MP_OKAY if successful,
+ upon error all allocated memory will be freed
+ */
+int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
+{
+    int x, err;
+
+    if (key == NULL || rng == NULL)
+        return ECC_BAD_ARG_E;
+
+    /* find key size */
+    for (x = 0; (keysize > ecc_sets[x].size) && (ecc_sets[x].size != 0); x++)
+        ;
+    keysize = ecc_sets[x].size;
+
+    if (keysize > ECC_MAXSIZE || ecc_sets[x].size == 0) {
+        return BAD_FUNC_ARG;
+    }
+    err = wc_ecc_make_key_ex(rng, key, &ecc_sets[x]);
+    key->idx = x;
+
+    return err;
+}
+
+/* Setup dynamic pointers is using normal math for proper freeing */
+int wc_ecc_init(ecc_key* key)
+{
+    (void)key;
+
+#ifndef USE_FAST_MATH
+    key->pubkey.x->dp = NULL;
+    key->pubkey.y->dp = NULL;
+    key->pubkey.z->dp = NULL;
+
+    key->k.dp = NULL;
+#endif
+
+#ifdef ALT_ECC_SIZE
+    if (mp_init(&key->k) != MP_OKAY)
+        return MEMORY_E;
+
+    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
+    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
+    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
+    alt_fp_init(key->pubkey.x);
+    alt_fp_init(key->pubkey.y);
+    alt_fp_init(key->pubkey.z);
+#endif
+
+    return MP_OKAY;
+}
+
+
+/**
+ Sign a message digest
+ in        The message digest to sign
+ inlen     The length of the digest
+ out       [out] The destination for the signature
+ outlen    [in/out] The max size and resulting size of the signature
+ key       A private ECC key
+ return    MP_OKAY if successful
+ */
+int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
+                     WC_RNG* rng, ecc_key* key)
+{
+    mp_int    r;
+    mp_int    s;
+    int        err;
+
+    if (in == NULL || out == NULL || outlen == NULL ||
+        key == NULL || rng == NULL)
+        return ECC_BAD_ARG_E;
+
+    if ((err = mp_init_multi(&r, &s, NULL, NULL, NULL, NULL)) != MP_OKAY) {
+        return err;
+    }
+
+    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, &r, &s);
+    if (err == MP_OKAY)
+        err = StoreECC_DSA_Sig(out, outlen, &r, &s);
+
+    mp_clear(&r);
+    mp_clear(&s);
+
+    return err;
+}
+
+/**
+  Sign a message digest
+  in        The message digest to sign
+  inlen     The length of the digest
+  out       [out] The destination for the signature
+  outlen    [in/out] The max size and resulting size of the signature
+  key       A private ECC key
+  r         [out] The destination for r component of the signature
+  s            [out] The destination for s component of the signature
+  return    MP_OKAY if successful
+*/
+int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
+                     ecc_key* key, mp_int *r, mp_int *s)
+{
+   mp_int        e;
+   mp_int        p;
+   int           err;
+
+   if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL)
+       return ECC_BAD_ARG_E;
+
+   /* is this a private key? */
+   if (key->type != ECC_PRIVATEKEY) {
+      return ECC_BAD_ARG_E;
+   }
+
+   /* is the IDX valid ?  */
+   if (wc_ecc_is_valid_idx(key->idx) != 1) {
+      return ECC_BAD_ARG_E;
+   }
+
+   /* get the hash and load it as a bignum into 'e' */
+   /* init the bignums */
+   if ((err = mp_init_multi(&p, &e, NULL, NULL, NULL, NULL)) != MP_OKAY) {
+      return err;
+   }
+   err = mp_read_radix(&p, (char *)key->dp->order, 16);
+
+   if (err == MP_OKAY) {
+       /* we may need to truncate if hash is longer than key size */
+       word32 orderBits = mp_count_bits(&p);
+
+       /* truncate down to byte size, may be all that's needed */
+       if ( (WOLFSSL_BIT_SIZE * inlen) > orderBits)
+           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1)/WOLFSSL_BIT_SIZE;
+       err = mp_read_unsigned_bin(&e, (byte*)in, inlen);
+
+       /* may still need bit truncation too */
+       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
+           mp_rshb(&e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
+   }
+
+   /* make up a key and export the public copy */
+   if (err == MP_OKAY) {
+       int loop_check = 0;
+       ecc_key pubkey;
+       if (wc_ecc_init(&pubkey) == MP_OKAY) {
+           for (;;) {
+               if (++loop_check > 64) {
+                    err = RNG_FAILURE_E;
+                    break;
+               }
+               err = wc_ecc_make_key_ex(rng, &pubkey, key->dp);
+               if (err != MP_OKAY) break;
+
+               /* find r = x1 mod n */
+               err = mp_mod(pubkey.pubkey.x, &p, r);
+               if (err != MP_OKAY) break;
+
+               if (mp_iszero(r) == MP_YES) {
+                   mp_clear(pubkey.pubkey.x);
+                   mp_clear(pubkey.pubkey.y);
+                   mp_clear(pubkey.pubkey.z);
+                   mp_clear(&pubkey.k);
+               }
+               else {
+                   /* find s = (e + xr)/k */
+                   err = mp_invmod(&pubkey.k, &p, &pubkey.k);
+                   if (err != MP_OKAY) break;
+
+                   err = mp_mulmod(&key->k, r, &p, s);   /* s = xr */
+                   if (err != MP_OKAY) break;
+
+                   err = mp_add(&e, s, s);               /* s = e +  xr */
+                   if (err != MP_OKAY) break;
+
+                   err = mp_mod(s, &p, s);               /* s = e +  xr */
+                   if (err != MP_OKAY) break;
+
+                   err = mp_mulmod(s, &pubkey.k, &p, s); /* s = (e + xr)/k */
+                   if (err != MP_OKAY) break;
+
+                   if (mp_iszero(s) == MP_NO)
+                       break;
+                }
+           }
+           wc_ecc_free(&pubkey);
+       }
+   }
+
+   mp_clear(&p);
+   mp_clear(&e);
+
+   return err;
+}
+
+
+/**
+  Free an ECC key from memory
+  key   The key you wish to free
+*/
+void wc_ecc_free(ecc_key* key)
+{
+   if (key == NULL)
+       return;
+
+   mp_clear(key->pubkey.x);
+   mp_clear(key->pubkey.y);
+   mp_clear(key->pubkey.z);
+   mp_clear(&key->k);
+}
+
+
+#ifdef USE_FAST_MATH
+    #define GEN_MEM_ERR FP_MEM
+#else
+    #define GEN_MEM_ERR MP_MEM
+#endif
+
+#ifdef ECC_SHAMIR
+
+/** Computes kA*A + kB*B = C using Shamir's Trick
+  A        First point to multiply
+  kA       What to multiple A by
+  B        Second point to multiply
+  kB       What to multiple B by
+  C        [out] Destination point (can overlap with A or B)
+  modulus  Modulus for curve
+  return MP_OKAY on success
+*/
+#ifdef FP_ECC
+static int normal_ecc_mul2add(ecc_point* A, mp_int* kA,
+                             ecc_point* B, mp_int* kB,
+                             ecc_point* C, mp_int* modulus)
+#else
+static int ecc_mul2add(ecc_point* A, mp_int* kA,
+                    ecc_point* B, mp_int* kB,
+                    ecc_point* C, mp_int* modulus)
+#endif
+{
+  ecc_point*     precomp[16];
+  unsigned       bitbufA, bitbufB, lenA, lenB, len, x, y, nA, nB, nibble;
+  unsigned char* tA;
+  unsigned char* tB;
+  int            err = MP_OKAY, first;
+  int            muInit    = 0;
+  int            tableInit = 0;
+  mp_digit mp;
+  mp_int   mu;
+
+  /* argchks */
+  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
+                   modulus == NULL)
+    return ECC_BAD_ARG_E;
+
+
+  /* allocate memory */
+  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+  if (tA == NULL) {
+     return GEN_MEM_ERR;
+  }
+  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+  if (tB == NULL) {
+     XFREE(tA, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+     return GEN_MEM_ERR;
+  }
+  XMEMSET(tA, 0, ECC_BUFSIZE);
+  XMEMSET(tB, 0, ECC_BUFSIZE);
+
+  /* get sizes */
+  lenA = mp_unsigned_bin_size(kA);
+  lenB = mp_unsigned_bin_size(kB);
+  len  = MAX(lenA, lenB);
+
+  /* sanity check */
+  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
+     err = BAD_FUNC_ARG;
+  }
+
+  if (err == MP_OKAY) {
+    /* extract and justify kA */
+    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
+
+    /* extract and justify kB */
+    if (err == MP_OKAY)
+        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
+
+    /* allocate the table */
+    if (err == MP_OKAY) {
+        for (x = 0; x < 16; x++) {
+            precomp[x] = wc_ecc_new_point();
+            if (precomp[x] == NULL) {
+                for (y = 0; y < x; ++y) {
+                    wc_ecc_del_point(precomp[y]);
+                }
+                err = GEN_MEM_ERR;
+                break;
+            }
+        }
+    }
+  }
+
+  if (err == MP_OKAY)
+    tableInit = 1;
+
+  if (err == MP_OKAY)
+   /* init montgomery reduction */
+   err = mp_montgomery_setup(modulus, &mp);
+
+  if (err == MP_OKAY)
+    err = mp_init(&mu);
+  if (err == MP_OKAY)
+    muInit = 1;
+
+  if (err == MP_OKAY)
+    err = mp_montgomery_calc_normalization(&mu, modulus);
+
+  if (err == MP_OKAY)
+    /* copy ones ... */
+    err = mp_mulmod(A->x, &mu, modulus, precomp[1]->x);
+
+  if (err == MP_OKAY)
+    err = mp_mulmod(A->y, &mu, modulus, precomp[1]->y);
+  if (err == MP_OKAY)
+    err = mp_mulmod(A->z, &mu, modulus, precomp[1]->z);
+
+  if (err == MP_OKAY)
+    err = mp_mulmod(B->x, &mu, modulus, precomp[1<<2]->x);
+  if (err == MP_OKAY)
+    err = mp_mulmod(B->y, &mu, modulus, precomp[1<<2]->y);
+  if (err == MP_OKAY)
+    err = mp_mulmod(B->z, &mu, modulus, precomp[1<<2]->z);
+
+  if (err == MP_OKAY)
+    /* precomp [i,0](A + B) table */
+    err = ecc_projective_dbl_point(precomp[1], precomp[2], modulus, &mp);
+
+  if (err == MP_OKAY)
+    err = ecc_projective_add_point(precomp[1], precomp[2], precomp[3],
+                                   modulus, &mp);
+  if (err == MP_OKAY)
+    /* precomp [0,i](A + B) table */
+    err = ecc_projective_dbl_point(precomp[1<<2], precomp[2<<2], modulus, &mp);
+
+  if (err == MP_OKAY)
+    err = ecc_projective_add_point(precomp[1<<2], precomp[2<<2], precomp[3<<2],
+                                   modulus, &mp);
+
+  if (err == MP_OKAY) {
+    /* precomp [i,j](A + B) table (i != 0, j != 0) */
+    for (x = 1; x < 4; x++) {
+        for (y = 1; y < 4; y++) {
+            if (err == MP_OKAY)
+                err = ecc_projective_add_point(precomp[x], precomp[(y<<2)],
+                                               precomp[x+(y<<2)], modulus, &mp);
+        }
+    }
+  }
+
+  if (err == MP_OKAY) {
+    nibble  = 3;
+    first   = 1;
+    bitbufA = tA[0];
+    bitbufB = tB[0];
+
+    /* for every byte of the multiplicands */
+    for (x = -1;; ) {
+        /* grab a nibble */
+        if (++nibble == 4) {
+            ++x; if (x == len) break;
+            bitbufA = tA[x];
+            bitbufB = tB[x];
+            nibble  = 0;
+        }
+
+        /* extract two bits from both, shift/update */
+        nA = (bitbufA >> 6) & 0x03;
+        nB = (bitbufB >> 6) & 0x03;
+        bitbufA = (bitbufA << 2) & 0xFF;
+        bitbufB = (bitbufB << 2) & 0xFF;
+
+        /* if both zero, if first, continue */
+        if ((nA == 0) && (nB == 0) && (first == 1)) {
+            continue;
+        }
+
+        /* double twice, only if this isn't the first */
+        if (first == 0) {
+            /* double twice */
+            if (err == MP_OKAY)
+                err = ecc_projective_dbl_point(C, C, modulus, &mp);
+            if (err == MP_OKAY)
+                err = ecc_projective_dbl_point(C, C, modulus, &mp);
+            else
+                break;
+        }
+
+        /* if not both zero */
+        if ((nA != 0) || (nB != 0)) {
+            if (first == 1) {
+                /* if first, copy from table */
+                first = 0;
+                if (err == MP_OKAY)
+                    err = mp_copy(precomp[nA + (nB<<2)]->x, C->x);
+
+                if (err == MP_OKAY)
+                    err = mp_copy(precomp[nA + (nB<<2)]->y, C->y);
+
+                if (err == MP_OKAY)
+                    err = mp_copy(precomp[nA + (nB<<2)]->z, C->z);
+                else
+                    break;
+            } else {
+                /* if not first, add from table */
+                if (err == MP_OKAY)
+                    err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C,
+                                                   modulus, &mp);
+                else
+                    break;
+            }
+        }
+    }
+  }
+
+  if (err == MP_OKAY)
+    /* reduce to affine */
+    err = ecc_map(C, modulus, &mp);
+
+  /* clean up */
+  if (muInit)
+    mp_clear(&mu);
+
+  if (tableInit) {
+    for (x = 0; x < 16; x++) {
+       wc_ecc_del_point(precomp[x]);
+    }
+  }
+   ForceZero(tA, ECC_BUFSIZE);
+   ForceZero(tB, ECC_BUFSIZE);
+   XFREE(tA, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+   XFREE(tB, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+   return err;
+}
+
+
+#endif /* ECC_SHAMIR */
+
+
+
+/* verify
+ *
+ * w  = s^-1 mod n
+ * u1 = xw
+ * u2 = rw
+ * X = u1*G + u2*Q
+ * v = X_x1 mod n
+ * accept if v == r
+ */
+
+/**
+ Verify an ECC signature
+ sig         The signature to verify
+ siglen      The length of the signature (octets)
+ hash        The hash (message digest) that was signed
+ hashlen     The length of the hash (octets)
+ stat        Result of signature, 1==valid, 0==invalid
+ key         The corresponding public ECC key
+ return      MP_OKAY if successful (even if the signature is not valid)
+ */
+int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
+                       word32 hashlen, int* stat, ecc_key* key)
+{
+    mp_int    r;
+    mp_int    s;
+    int        err;
+
+    if (sig == NULL || hash == NULL || stat == NULL || key == NULL)
+        return ECC_BAD_ARG_E;
+
+    /* default to invalid signature */
+    *stat = 0;
+
+    /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
+     * If either of those don't allocate correctly, none of
+     * the rest of this function will execute, and everything
+     * gets cleaned up at the end. */
+    XMEMSET(&r, 0, sizeof(r));
+    XMEMSET(&s, 0, sizeof(s));
+
+    err = DecodeECC_DSA_Sig(sig, siglen, &r, &s);
+
+    if (err == MP_OKAY)
+        err = wc_ecc_verify_hash_ex(&r, &s, hash, hashlen, stat, key);
+
+    mp_clear(&r);
+    mp_clear(&s);
+
+    return err;
+}
+
+/**
+   Verify an ECC signature
+   r           The signature R component to verify
+   s           The signature S component to verify
+   hash        The hash (message digest) that was signed
+   hashlen     The length of the hash (octets)
+   stat        Result of signature, 1==valid, 0==invalid
+   key         The corresponding public ECC key
+   return      MP_OKAY if successful (even if the signature is not valid)
+*/
+int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
+                    word32 hashlen, int* stat, ecc_key* key)
+{
+   ecc_point    *mG, *mQ;
+   mp_int        v;
+   mp_int        w;
+   mp_int        u1;
+   mp_int        u2;
+   mp_int        e;
+   mp_int        p;
+   mp_int        m;
+   int           err;
+
+   if (r == NULL || s == NULL || hash == NULL || stat == NULL || key == NULL)
+       return ECC_BAD_ARG_E;
+
+   /* default to invalid signature */
+   *stat = 0;
+
+   /* is the IDX valid ?  */
+   if (wc_ecc_is_valid_idx(key->idx) != 1) {
+      return ECC_BAD_ARG_E;
+   }
+
+   /* allocate ints */
+   if ((err = mp_init_multi(&v, &w, &u1, &u2, &p, &e)) != MP_OKAY) {
+      return MEMORY_E;
+   }
+
+   if ((err = mp_init(&m)) != MP_OKAY) {
+      mp_clear(&v);
+      mp_clear(&w);
+      mp_clear(&u1);
+      mp_clear(&u2);
+      mp_clear(&p);
+      mp_clear(&e);
+      return MEMORY_E;
+   }
+
+   /* allocate points */
+   mG = wc_ecc_new_point();
+   mQ = wc_ecc_new_point();
+   if (mQ  == NULL || mG == NULL)
+      err = MEMORY_E;
+
+   /* get the order */
+   if (err == MP_OKAY)
+       err = mp_read_radix(&p, (char *)key->dp->order, 16);
+
+   /* get the modulus */
+   if (err == MP_OKAY)
+       err = mp_read_radix(&m, (char *)key->dp->prime, 16);
+
+   /* check for zero */
+   if (err == MP_OKAY) {
+       if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, &p) != MP_LT ||
+           mp_cmp(s, &p) != MP_LT)
+           err = MP_ZERO_E;
+   }
+   /* read hash */
+   if (err == MP_OKAY) {
+       /* we may need to truncate if hash is longer than key size */
+       unsigned int orderBits = mp_count_bits(&p);
+
+       /* truncate down to byte size, may be all that's needed */
+       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
+           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1)/WOLFSSL_BIT_SIZE;
+       err = mp_read_unsigned_bin(&e, hash, hashlen);
+
+       /* may still need bit truncation too */
+       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
+           mp_rshb(&e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
+   }
+
+   /*  w  = s^-1 mod n */
+   if (err == MP_OKAY)
+       err = mp_invmod(s, &p, &w);
+
+   /* u1 = ew */
+   if (err == MP_OKAY)
+       err = mp_mulmod(&e, &w, &p, &u1);
+
+   /* u2 = rw */
+   if (err == MP_OKAY)
+       err = mp_mulmod(r, &w, &p, &u2);
+
+   /* find mG and mQ */
+   if (err == MP_OKAY)
+       err = mp_read_radix(mG->x, (char *)key->dp->Gx, 16);
+
+   if (err == MP_OKAY)
+       err = mp_read_radix(mG->y, (char *)key->dp->Gy, 16);
+   if (err == MP_OKAY)
+       mp_set(mG->z, 1);
+
+   if (err == MP_OKAY)
+       err = mp_copy(key->pubkey.x, mQ->x);
+   if (err == MP_OKAY)
+       err = mp_copy(key->pubkey.y, mQ->y);
+   if (err == MP_OKAY)
+       err = mp_copy(key->pubkey.z, mQ->z);
+
+#ifndef ECC_SHAMIR
+    {
+       mp_digit      mp;
+
+       /* compute u1*mG + u2*mQ = mG */
+       if (err == MP_OKAY)
+           err = wc_ecc_mulmod(&u1, mG, mG, &m, 0);
+       if (err == MP_OKAY)
+           err = wc_ecc_mulmod(&u2, mQ, mQ, &m, 0);
+
+       /* find the montgomery mp */
+       if (err == MP_OKAY)
+           err = mp_montgomery_setup(&m, &mp);
+
+       /* add them */
+       if (err == MP_OKAY)
+           err = ecc_projective_add_point(mQ, mG, mG, &m, &mp);
+
+       /* reduce */
+       if (err == MP_OKAY)
+           err = ecc_map(mG, &m, &mp);
+    }
+#else
+       /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
+       if (err == MP_OKAY)
+           err = ecc_mul2add(mG, &u1, mQ, &u2, mG, &m);
+#endif /* ECC_SHAMIR */
+
+   /* v = X_x1 mod n */
+   if (err == MP_OKAY)
+       err = mp_mod(mG->x, &p, &v);
+
+   /* does v == r */
+   if (err == MP_OKAY) {
+       if (mp_cmp(&v, r) == MP_EQ)
+           *stat = 1;
+   }
+
+   wc_ecc_del_point(mG);
+   wc_ecc_del_point(mQ);
+
+   mp_clear(&v);
+   mp_clear(&w);
+   mp_clear(&u1);
+   mp_clear(&u2);
+   mp_clear(&p);
+   mp_clear(&e);
+   mp_clear(&m);
+
+   return err;
+}
+
+/* import point from der */
+int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
+                            ecc_point* point)
+{
+    int err = 0;
+    int compressed = 0;
+
+    if (in == NULL || point == NULL || (curve_idx < 0) ||
+        (wc_ecc_is_valid_idx(curve_idx) == 0))
+        return ECC_BAD_ARG_E;
+
+    /* must be odd */
+    if ((inLen & 1) == 0) {
+        return ECC_BAD_ARG_E;
+    }
+
+    /* init point */
+#ifdef ALT_ECC_SIZE
+    point->x = (mp_int*)&point->xyz[0];
+    point->y = (mp_int*)&point->xyz[1];
+    point->z = (mp_int*)&point->xyz[2];
+    alt_fp_init(point->x);
+    alt_fp_init(point->y);
+    alt_fp_init(point->z);
+#else
+    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
+#endif
+    if (err != MP_OKAY)
+        return MEMORY_E;
+
+    /* check for 4, 2, or 3 */
+    if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) {
+        err = ASN_PARSE_E;
+    }
+
+    if (in[0] == 0x02 || in[0] == 0x03) {
+#ifdef HAVE_COMP_KEY
+        compressed = 1;
+#else
+        err = NOT_COMPILED_IN;
+#endif
+    }
+
+    /* read data */
+    if (err == MP_OKAY)
+        err = mp_read_unsigned_bin(point->x, (byte*)in+1, (inLen-1)>>1);
+
+#ifdef HAVE_COMP_KEY
+    if (err == MP_OKAY && compressed == 1) {   /* build y */
+        mp_int t1, t2, prime, a, b;
+
+        if (mp_init_multi(&t1, &t2, &prime, &a, &b, NULL) != MP_OKAY)
+            err = MEMORY_E;
+
+        /* load prime */
+        if (err == MP_OKAY)
+            err = mp_read_radix(&prime, (char *)ecc_sets[curve_idx].prime, 16);
+
+        /* load a */
+        if (err == MP_OKAY)
+            err = mp_read_radix(&a, (char *)ecc_sets[curve_idx].Af, 16);
+
+        /* load b */
+        if (err == MP_OKAY)
+            err = mp_read_radix(&b, (char *)ecc_sets[curve_idx].Bf, 16);
+
+        /* compute x^3 */
+        if (err == MP_OKAY)
+            err = mp_sqr(point->x, &t1);
+
+        if (err == MP_OKAY)
+            err = mp_mulmod(&t1, point->x, &prime, &t1);
+
+        /* compute x^3 + a*x */
+        if (err == MP_OKAY)
+            err = mp_mulmod(&a, point->x, &prime, &t2);
+
+        if (err == MP_OKAY)
+            err = mp_add(&t1, &t2, &t1);
+
+        /* compute x^3 + a*x + b */
+        if (err == MP_OKAY)
+            err = mp_add(&t1, &b, &t1);
+
+        /* compute sqrt(x^3 + a*x + b) */
+        if (err == MP_OKAY)
+            err = mp_sqrtmod_prime(&t1, &prime, &t2);
+
+        /* adjust y */
+        if (err == MP_OKAY) {
+            if ((mp_isodd(&t2) && in[0] == 0x03) ||
+                (!mp_isodd(&t2) && in[0] == 0x02)) {
+                err = mp_mod(&t2, &prime, point->y);
+            }
+            else {
+                err = mp_submod(&prime, &t2, &prime, point->y);
+            }
+        }
+
+        mp_clear(&a);
+        mp_clear(&b);
+        mp_clear(&prime);
+        mp_clear(&t2);
+        mp_clear(&t1);
+    }
+#endif
+
+    if (err == MP_OKAY && compressed == 0)
+        err = mp_read_unsigned_bin(point->y,
+                                   (byte*)in+1+((inLen-1)>>1), (inLen-1)>>1);
+    if (err == MP_OKAY)
+        mp_set(point->z, 1);
+
+    if (err != MP_OKAY) {
+        mp_clear(point->x);
+        mp_clear(point->y);
+        mp_clear(point->z);
+    }
+
+    return err;
+}
+
+/* export point to der */
+int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
+                            word32* outLen)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  buf;
+#else
+    byte   buf[ECC_BUFSIZE];
+#endif
+    word32 numlen;
+    int    ret = MP_OKAY;
+
+    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
+        return ECC_BAD_ARG_E;
+
+    /* return length needed only */
+    if (point != NULL && out == NULL && outLen != NULL) {
+        numlen = ecc_sets[curve_idx].size;
+        *outLen = 1 + 2*numlen;
+        return LENGTH_ONLY_E;
+    }
+
+    if (point == NULL || out == NULL || outLen == NULL)
+        return ECC_BAD_ARG_E;
+
+    numlen = ecc_sets[curve_idx].size;
+
+    if (*outLen < (1 + 2*numlen)) {
+        *outLen = 1 + 2*numlen;
+        return BUFFER_E;
+    }
+
+    /* store byte 0x04 */
+    out[0] = 0x04;
+
+#ifdef WOLFSSL_SMALL_STACK
+    buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buf == NULL)
+        return MEMORY_E;
+#endif
+
+    /* pad and store x */
+    XMEMSET(buf, 0, ECC_BUFSIZE);
+    ret = mp_to_unsigned_bin(point->x, buf +
+                                 (numlen - mp_unsigned_bin_size(point->x)));
+    if (ret != MP_OKAY)
+        goto done;
+    XMEMCPY(out+1, buf, numlen);
+
+    /* pad and store y */
+    XMEMSET(buf, 0, ECC_BUFSIZE);
+    ret = mp_to_unsigned_bin(point->y, buf +
+                                 (numlen - mp_unsigned_bin_size(point->y)));
+    if (ret != MP_OKAY)
+        goto done;
+    XMEMCPY(out+1+numlen, buf, numlen);
+
+    *outLen = 1 + 2*numlen;
+
+done:
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+/* export public ECC key in ANSI X9.63 format */
+int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
+{
+#ifdef WOLFSSL_SMALL_STACK
+   byte*  buf;
+#else
+   byte   buf[ECC_BUFSIZE];
+#endif
+   word32 numlen;
+   int    ret = MP_OKAY;
+
+   /* return length needed only */
+   if (key != NULL && out == NULL && outLen != NULL) {
+      numlen = key->dp->size;
+      *outLen = 1 + 2*numlen;
+      return LENGTH_ONLY_E;
+   }
+
+   if (key == NULL || out == NULL || outLen == NULL)
+      return ECC_BAD_ARG_E;
+
+   if (wc_ecc_is_valid_idx(key->idx) == 0) {
+      return ECC_BAD_ARG_E;
+   }
+   numlen = key->dp->size;
+
+   if (*outLen < (1 + 2*numlen)) {
+      *outLen = 1 + 2*numlen;
+      return BUFFER_E;
+   }
+
+   /* store byte 0x04 */
+   out[0] = 0x04;
+
+#ifdef WOLFSSL_SMALL_STACK
+   buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+   if (buf == NULL)
+      return MEMORY_E;
+#endif
+
+    /* pad and store x */
+    XMEMSET(buf, 0, ECC_BUFSIZE);
+    ret = mp_to_unsigned_bin(key->pubkey.x,
+                         buf + (numlen - mp_unsigned_bin_size(key->pubkey.x)));
+    if (ret != MP_OKAY)
+        goto done;
+    XMEMCPY(out+1, buf, numlen);
+
+    /* pad and store y */
+    XMEMSET(buf, 0, ECC_BUFSIZE);
+    ret = mp_to_unsigned_bin(key->pubkey.y,
+                         buf + (numlen - mp_unsigned_bin_size(key->pubkey.y)));
+    if (ret != MP_OKAY)
+        goto done;
+    XMEMCPY(out+1+numlen, buf, numlen);
+
+    *outLen = 1 + 2*numlen;
+
+done:
+#ifdef WOLFSSL_SMALL_STACK
+   XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+   return ret;
+}
+
+
+/* export public ECC key in ANSI X9.63 format, extended with
+ * compression option */
+int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
+                          int compressed)
+{
+    if (compressed == 0)
+        return wc_ecc_export_x963(key, out, outLen);
+#ifdef HAVE_COMP_KEY
+    else
+        return wc_ecc_export_x963_compressed(key, out, outLen);
+#endif
+
+    return NOT_COMPILED_IN;
+}
+
+
+/* is ec point on curve descriped by dp ? */
+static int ecc_is_point(const ecc_set_type* dp, ecc_point* ecp, mp_int* prime)
+{
+   mp_int b, t1, t2;
+   int err;
+
+   if ((err = mp_init_multi(&b, &t1, &t2, NULL, NULL, NULL)) != MP_OKAY) {
+      return err;
+   }
+
+   /* load  b */
+   err = mp_read_radix(&b, dp->Bf, 16);
+
+   /* compute y^2 */
+   if (err == MP_OKAY)
+       err = mp_sqr(ecp->y, &t1);
+
+   /* compute x^3 */
+   if (err == MP_OKAY)
+       err = mp_sqr(ecp->x, &t2);
+   if (err == MP_OKAY)
+       err = mp_mod(&t2, prime, &t2);
+   if (err == MP_OKAY)
+       err = mp_mul(ecp->x, &t2, &t2);
+
+   /* compute y^2 - x^3 */
+   if (err == MP_OKAY)
+       err = mp_sub(&t1, &t2, &t1);
+
+   /* compute y^2 - x^3 + 3x */
+   if (err == MP_OKAY)
+       err = mp_add(&t1, ecp->x, &t1);
+   if (err == MP_OKAY)
+       err = mp_add(&t1, ecp->x, &t1);
+   if (err == MP_OKAY)
+       err = mp_add(&t1, ecp->x, &t1);
+   if (err == MP_OKAY)
+       err = mp_mod(&t1, prime, &t1);
+
+   while (err == MP_OKAY && mp_cmp_d(&t1, 0) == MP_LT) {
+      err = mp_add(&t1, prime, &t1);
+   }
+   while (err == MP_OKAY && mp_cmp(&t1, prime) != MP_LT) {
+      err = mp_sub(&t1, prime, &t1);
+   }
+
+   /* compare to b */
+   if (err == MP_OKAY) {
+       if (mp_cmp(&t1, &b) != MP_EQ) {
+          err = MP_VAL;
+       } else {
+          err = MP_OKAY;
+       }
+   }
+
+   mp_clear(&b);
+   mp_clear(&t1);
+   mp_clear(&t2);
+
+   return err;
+}
+
+
+/* validate privkey * generator == pubkey, 0 on success */
+static int ecc_check_privkey_gen(ecc_key* key, mp_int* prime)
+{
+    ecc_point* base = NULL;
+    ecc_point* res  = NULL;
+    int        err;
+
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    base = wc_ecc_new_point();
+    if (base == NULL)
+        return MEMORY_E;
+
+    /* set up base generator */
+    err = mp_read_radix(base->x, (char*)key->dp->Gx, 16);
+    if (err == MP_OKAY)
+        err = mp_read_radix(base->y, (char*)key->dp->Gy, 16);
+    if (err == MP_OKAY)
+        mp_set(base->z, 1);
+
+    if (err == MP_OKAY) {
+        res = wc_ecc_new_point();
+        if (res == NULL)
+            err = MEMORY_E;
+        else {
+            err = wc_ecc_mulmod(&key->k, base, res, prime, 1);
+            if (err == MP_OKAY) {
+                /* compare result to public key */
+                if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
+                    mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
+                    mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
+                    /* didn't match */
+                    err = ECC_PRIV_KEY_E;
+                }
+            }
+        }
+    }
+
+    wc_ecc_del_point(res);
+    wc_ecc_del_point(base);
+
+    return err;
+}
+
+
+#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
+
+/* check privkey generator helper, creates prime needed */
+static int ecc_check_privkey_gen_helper(ecc_key* key)
+{
+    mp_int prime;
+    int    err;
+
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    err = mp_init(&prime);
+    if (err != MP_OKAY)
+        return err;
+
+    err = mp_read_radix(&prime, (char*)key->dp->prime, 16);
+
+    if (err == MP_OKAY);
+        err = ecc_check_privkey_gen(key, &prime);
+
+    mp_clear(&prime);
+
+    return err;
+}
+
+#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
+
+
+/* validate order * pubkey = point at infinity, 0 on success */
+static int ecc_check_pubkey_order(ecc_key* key, mp_int* prime, mp_int* order)
+{
+    ecc_point* inf = NULL;
+    int        err;
+
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    inf = wc_ecc_new_point();
+    if (inf == NULL)
+        err = MEMORY_E;
+    else {
+        err = wc_ecc_mulmod(order, &key->pubkey, inf, prime, 1);
+        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
+            err = ECC_INF_E;
+    }
+
+    wc_ecc_del_point(inf);
+
+    return err;
+}
+
+
+/* perform sanity checks on ec key validity, 0 on success */
+int wc_ecc_check_key(ecc_key* key)
+{
+    mp_int prime;  /* used by multiple calls so let's cache */
+    mp_int order;  /* other callers have, so let's gen here */
+    int    err;
+
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    /* pubkey point cannot be at inifinity */
+    if (wc_ecc_point_is_at_infinity(&key->pubkey))
+        return ECC_INF_E;
+
+    err = mp_init_multi(&prime, &order, NULL, NULL, NULL, NULL);
+    if (err != MP_OKAY)
+        return err;
+
+    err = mp_read_radix(&prime, (char*)key->dp->prime, 16);
+
+    /* make sure point is actually on curve */
+    if (err == MP_OKAY)
+        err = ecc_is_point(key->dp, &key->pubkey, &prime);
+
+    if (err == MP_OKAY)
+        err = mp_read_radix(&order, (char*)key->dp->order, 16);
+
+    /* pubkey * order must be at infinity */
+    if (err == MP_OKAY)
+        err = ecc_check_pubkey_order(key, &prime, &order);
+
+    /* private * base generator must equal pubkey */
+    if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
+        err = ecc_check_privkey_gen(key, &prime);
+
+    mp_clear(&order);
+    mp_clear(&prime);
+
+    return err;
+}
+
+
+/* import public ECC key in ANSI X9.63 format */
+int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
+{
+   int x, err;
+   int compressed = 0;
+
+   if (in == NULL || key == NULL)
+       return ECC_BAD_ARG_E;
+
+   /* must be odd */
+   if ((inLen & 1) == 0) {
+      return ECC_BAD_ARG_E;
+   }
+
+   /* init key */
+#ifdef ALT_ECC_SIZE
+   key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
+   key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
+   key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
+   alt_fp_init(key->pubkey.x);
+   alt_fp_init(key->pubkey.y);
+   alt_fp_init(key->pubkey.z);
+   err = mp_init(&key->k);
+#else
+   err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, &key->k,
+                     NULL, NULL);
+#endif
+   if (err != MP_OKAY)
+      return MEMORY_E;
+
+   /* check for 4, 2, or 3 */
+   if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) {
+      err = ASN_PARSE_E;
+   }
+
+   if (in[0] == 0x02 || in[0] == 0x03) {
+#ifdef HAVE_COMP_KEY
+       compressed = 1;
+#else
+       err = NOT_COMPILED_IN;
+#endif
+   }
+
+   if (err == MP_OKAY) {
+      /* determine the idx */
+
+      if (compressed)
+          inLen = (inLen-1)*2 + 1;  /* used uncompressed len */
+
+      for (x = 0; ecc_sets[x].size != 0; x++) {
+         if ((unsigned)ecc_sets[x].size >= ((inLen-1)>>1)) {
+            break;
+         }
+      }
+      if (ecc_sets[x].size == 0) {
+         err = ASN_PARSE_E;
+      } else {
+          /* set the idx */
+          key->idx  = x;
+          key->dp = &ecc_sets[x];
+          key->type = ECC_PUBLICKEY;
+      }
+   }
+
+   /* read data */
+   if (err == MP_OKAY)
+       err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in+1, (inLen-1)>>1);
+
+#ifdef HAVE_COMP_KEY
+   if (err == MP_OKAY && compressed == 1) {   /* build y */
+        mp_int t1, t2, prime, a, b;
+
+        if (mp_init_multi(&t1, &t2, &prime, &a, &b, NULL) != MP_OKAY)
+            err = MEMORY_E;
+
+        /* load prime */
+        if (err == MP_OKAY)
+            err = mp_read_radix(&prime, (char *)key->dp->prime, 16);
+
+        /* load a */
+        if (err == MP_OKAY)
+            err = mp_read_radix(&a, (char *)key->dp->Af, 16);
+
+        /* load b */
+        if (err == MP_OKAY)
+            err = mp_read_radix(&b, (char *)key->dp->Bf, 16);
+
+        /* compute x^3 */
+        if (err == MP_OKAY)
+            err = mp_sqr(key->pubkey.x, &t1);
+
+        if (err == MP_OKAY)
+            err = mp_mulmod(&t1, key->pubkey.x, &prime, &t1);
+
+        /* compute x^3 + a*x */
+        if (err == MP_OKAY)
+            err = mp_mulmod(&a, key->pubkey.x, &prime, &t2);
+
+        if (err == MP_OKAY)
+            err = mp_add(&t1, &t2, &t1);
+
+        /* compute x^3 + a*x + b */
+        if (err == MP_OKAY)
+            err = mp_add(&t1, &b, &t1);
+
+        /* compute sqrt(x^3 + a*x + b) */
+        if (err == MP_OKAY)
+            err = mp_sqrtmod_prime(&t1, &prime, &t2);
+
+        /* adjust y */
+        if (err == MP_OKAY) {
+            if ((mp_isodd(&t2) && in[0] == 0x03) ||
+               (!mp_isodd(&t2) && in[0] == 0x02)) {
+                err = mp_mod(&t2, &prime, key->pubkey.y);
+            }
+            else {
+                err = mp_submod(&prime, &t2, &prime, key->pubkey.y);
+            }
+        }
+
+        mp_clear(&a);
+        mp_clear(&b);
+        mp_clear(&prime);
+        mp_clear(&t2);
+        mp_clear(&t1);
+   }
+#endif
+
+   if (err == MP_OKAY && compressed == 0)
+       err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in+1+((inLen-1)>>1),
+                                  (inLen-1)>>1);
+   if (err == MP_OKAY)
+       mp_set(key->pubkey.z, 1);
+
+#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
+   if (err == MP_OKAY)
+       err = wc_ecc_check_key(key);
+#endif
+
+   if (err != MP_OKAY) {
+       mp_clear(key->pubkey.x);
+       mp_clear(key->pubkey.y);
+       mp_clear(key->pubkey.z);
+       mp_clear(&key->k);
+   }
+
+   return err;
+}
+
+
+/* export ecc private key only raw, outLen is in/out size
+   return MP_OKAY on success */
+int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
+{
+   word32 numlen;
+
+   if (key == NULL || out == NULL || outLen == NULL)
+       return ECC_BAD_ARG_E;
+
+   if (wc_ecc_is_valid_idx(key->idx) == 0) {
+      return ECC_BAD_ARG_E;
+   }
+   numlen = key->dp->size;
+
+   if (*outLen < numlen) {
+      *outLen = numlen;
+      return BUFFER_E;
+   }
+   *outLen = numlen;
+   XMEMSET(out, 0, *outLen);
+   return mp_to_unsigned_bin(&key->k, out + (numlen -
+                                             mp_unsigned_bin_size(&key->k)));
+}
+
+
+/* ecc private key import, public key in ANSI X9.63 format, private raw */
+int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
+                           word32 pubSz, ecc_key* key)
+{
+    int ret = wc_ecc_import_x963(pub, pubSz, key);
+    if (ret != 0)
+        return ret;
+
+    key->type = ECC_PRIVATEKEY;
+
+    ret = mp_read_unsigned_bin(&key->k, priv, privSz);
+
+#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
+    if (ret == MP_OKAY)
+        ret = ecc_check_privkey_gen_helper(key);
+#endif
+
+    return ret;
+}
+
+/**
+   Convert ECC R,S to signature
+   r       R component of signature
+   s       S component of signature
+   out     DER-encoded ECDSA signature
+   outlen  [in/out] output buffer size, output signature size
+   return  MP_OKAY on success
+*/
+int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
+{
+    int err;
+    mp_int rtmp;
+    mp_int stmp;
+
+    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
+        return ECC_BAD_ARG_E;
+
+    err = mp_init_multi(&rtmp, &stmp, NULL, NULL, NULL, NULL);
+    if (err != MP_OKAY)
+        return err;
+
+    err = mp_read_radix(&rtmp, r, 16);
+    if (err == MP_OKAY)
+        err = mp_read_radix(&stmp, s, 16);
+
+    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
+    if (err == MP_OKAY)
+        err = StoreECC_DSA_Sig(out, outlen, &rtmp, &stmp);
+
+    if (err == MP_OKAY) {
+        if (mp_iszero(&rtmp) || mp_iszero(&stmp))
+            err = MP_ZERO_E;
+    }
+
+    mp_clear(&rtmp);
+    mp_clear(&stmp);
+
+    return err;
+}
+
+/**
+   Import raw ECC key
+   key       The destination ecc_key structure
+   qx        x component of base point, as ASCII hex string
+   qy        y component of base point, as ASCII hex string
+   d         private key, as ASCII hex string
+   curveName ECC curve name, from ecc_sets[]
+   return    MP_OKAY on success
+*/
+int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
+                   const char* d, const char* curveName)
+{
+    int err, x;
+
+    if (key == NULL || qx == NULL || qy == NULL || d == NULL ||
+        curveName == NULL)
+        return ECC_BAD_ARG_E;
+
+    /* init key */
+#ifdef ALT_ECC_SIZE
+    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
+    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
+    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
+    alt_fp_init(key->pubkey.x);
+    alt_fp_init(key->pubkey.y);
+    alt_fp_init(key->pubkey.z);
+    err = mp_init(&key->k);
+#else
+    err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, &key->k,
+                      NULL, NULL);
+#endif
+    if (err != MP_OKAY)
+        return MEMORY_E;
+
+    /* read Qx */
+    if (err == MP_OKAY)
+        err = mp_read_radix(key->pubkey.x, qx, 16);
+
+    /* read Qy */
+    if (err == MP_OKAY)
+        err = mp_read_radix(key->pubkey.y, qy, 16);
+
+    if (err == MP_OKAY)
+        mp_set(key->pubkey.z, 1);
+
+    /* read and set the curve */
+    if (err == MP_OKAY) {
+        for (x = 0; ecc_sets[x].size != 0; x++) {
+            if (XSTRNCMP(ecc_sets[x].name, curveName,
+                         XSTRLEN(curveName)) == 0) {
+                break;
+            }
+        }
+        if (ecc_sets[x].size == 0) {
+            err = ASN_PARSE_E;
+        } else {
+            /* set the curve */
+            key->idx = x;
+            key->dp = &ecc_sets[x];
+            key->type = ECC_PUBLICKEY;
+        }
+    }
+
+    /* import private key */
+    if (err == MP_OKAY) {
+        key->type = ECC_PRIVATEKEY;
+        err = mp_read_radix(&key->k, d, 16);
+    }
+
+#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
+    if (err == MP_OKAY)
+        err = wc_ecc_check_key(key);
+#endif
+
+    if (err != MP_OKAY) {
+        mp_clear(key->pubkey.x);
+        mp_clear(key->pubkey.y);
+        mp_clear(key->pubkey.z);
+        mp_clear(&key->k);
+    }
+
+    return err;
+}
+
+
+/* key size in octets */
+int wc_ecc_size(ecc_key* key)
+{
+    if (key == NULL) return 0;
+
+    return key->dp->size;
+}
+
+
+/* worst case estimate, check actual return from wc_ecc_sign_hash for actual
+   value of signature size in octets */
+int wc_ecc_sig_size(ecc_key* key)
+{
+    int sz = wc_ecc_size(key);
+    if (sz <= 0)
+        return sz;
+
+    return sz * 2 + SIG_HEADER_SZ + 4;  /* (4) worst case estimate */
+}
+
+
+#ifdef FP_ECC
+
+/* fixed point ECC cache */
+/* number of entries in the cache */
+#ifndef FP_ENTRIES
+    #define FP_ENTRIES 16
+#endif
+
+/* number of bits in LUT */
+#ifndef FP_LUT
+    #define FP_LUT     8U
+#endif
+
+#ifdef ECC_SHAMIR
+    /* Sharmir requires a bigger LUT, TAO */
+    #if (FP_LUT > 12) || (FP_LUT < 4)
+        #error FP_LUT must be between 4 and 12 inclusively
+    #endif
+#else
+    #if (FP_LUT > 12) || (FP_LUT < 2)
+        #error FP_LUT must be between 2 and 12 inclusively
+    #endif
+#endif
+
+
+/** Our FP cache */
+typedef struct {
+   ecc_point* g;               /* cached COPY of base point */
+   ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
+   mp_int     mu;              /* copy of the montgomery constant */
+   int        lru_count;       /* amount of times this entry has been used */
+   int        lock;            /* flag to indicate cache eviction */
+                               /* permitted (0) or not (1) */
+} fp_cache_t;
+
+/* if HAVE_THREAD_LS this cache is per thread, no locking needed */
+static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
+
+#ifndef HAVE_THREAD_LS
+    static volatile int initMutex = 0;  /* prevent multiple mutex inits */
+    static wolfSSL_Mutex ecc_fp_lock;
+#endif /* HAVE_THREAD_LS */
+
+/* simple table to help direct the generation of the LUT */
+static const struct {
+   int ham, terma, termb;
+} lut_orders[] = {
+   { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
+   { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
+   { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
+   { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
+   { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
+   { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
+   { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
+   { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
+#if FP_LUT > 6
+   { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
+   { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
+   { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
+   { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
+   { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
+   { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
+   { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
+   { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
+#if FP_LUT > 7
+   { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
+   { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
+   { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
+   { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
+   { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
+   { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
+   { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
+   { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
+   { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
+   { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
+   { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
+   { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
+   { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
+   { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
+   { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
+   { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
+#if FP_LUT > 8
+   { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
+   { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
+   { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
+   { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
+   { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
+   { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
+   { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
+   { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
+   { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
+   { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
+   { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
+   { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
+   { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
+   { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
+   { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
+   { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
+   { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
+   { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
+   { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
+   { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
+   { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
+   { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
+   { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
+   { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
+   { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
+   { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
+   { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
+   { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
+   { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
+   { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
+   { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
+   { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
+#if FP_LUT > 9
+   { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
+   { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
+   { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
+   { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
+   { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
+   { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
+   { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
+   { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
+   { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
+   { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
+   { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
+   { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
+   { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
+   { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
+   { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
+   { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
+   { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
+   { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
+   { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
+   { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
+   { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
+   { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
+   { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
+   { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
+   { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
+   { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
+   { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
+   { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
+   { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
+   { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
+   { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
+   { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
+   { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
+   { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
+   { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
+   { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
+   { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
+   { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
+   { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
+   { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
+   { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
+   { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
+   { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
+   { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
+   { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
+   { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
+   { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
+   { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
+   { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
+   { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
+   { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
+   { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
+   { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
+   { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
+   { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
+   { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
+   { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
+   { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
+   { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
+   { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
+   { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
+   { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
+   { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
+   { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
+#if FP_LUT > 10
+   { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
+   { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
+   { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
+   { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
+   { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
+   { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
+   { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
+   { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
+   { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
+   { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
+   { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
+   { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
+   { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
+   { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
+   { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
+   { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
+   { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
+   { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
+   { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
+   { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
+   { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
+   { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
+   { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
+   { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
+   { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
+   { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
+   { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
+   { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
+   { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
+   { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
+   { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
+   { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
+   { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
+   { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
+   { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
+   { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
+   { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
+   { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
+   { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
+   { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
+   { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
+   { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
+   { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
+   { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
+   { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
+   { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
+   { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
+   { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
+   { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
+   { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
+   { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
+   { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
+   { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
+   { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
+   { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
+   { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
+   { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
+   { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
+   { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
+   { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
+   { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
+   { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
+   { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
+   { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
+   { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
+   { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
+   { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
+   { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
+   { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
+   { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
+   { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
+   { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
+   { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
+   { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
+   { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
+   { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
+   { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
+   { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
+   { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
+   { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
+   { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
+   { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
+   { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
+   { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
+   { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
+   { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
+   { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
+   { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
+   { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
+   { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
+   { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
+   { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
+   { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
+   { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
+   { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
+   { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
+   { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
+   { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
+   { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
+   { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
+   { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
+   { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
+   { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
+   { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
+   { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
+   { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
+   { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
+   { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
+   { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
+   { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
+   { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
+   { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
+   { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
+   { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
+   { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
+   { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
+   { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
+   { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
+   { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
+   { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
+   { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
+   { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
+   { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
+   { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
+   { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
+   { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
+   { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
+   { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
+#if FP_LUT > 11
+   { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
+   { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
+   { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
+   { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
+   { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
+   { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
+   { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
+   { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
+   { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
+   { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
+   { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
+   { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
+   { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
+   { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
+   { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
+   { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
+   { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
+   { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
+   { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
+   { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
+   { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
+   { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
+   { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
+   { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
+   { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
+   { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
+   { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
+   { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
+   { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
+   { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
+   { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
+   { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
+   { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
+   { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
+   { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
+   { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
+   { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
+   { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
+   { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
+   { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
+   { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
+   { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
+   { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
+   { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
+   { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
+   { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
+   { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
+   { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
+   { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
+   { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
+   { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
+   { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
+   { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
+   { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
+   { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
+   { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
+   { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
+   { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
+   { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
+   { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
+   { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
+   { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
+   { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
+   { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
+   { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
+   { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
+   { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
+   { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
+   { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
+   { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
+   { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
+   { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
+   { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
+   { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
+   { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
+   { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
+   { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
+   { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
+   { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
+   { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
+   { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
+   { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
+   { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
+   { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
+   { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
+   { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
+   { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
+   { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
+   { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
+   { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
+   { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
+   { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
+   { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
+   { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
+   { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
+   { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
+   { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
+   { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
+   { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
+   { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
+   { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
+   { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
+   { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
+   { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
+   { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
+   { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
+   { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
+   { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
+   { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
+   { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
+   { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
+   { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
+   { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
+   { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
+   { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
+   { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
+   { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
+   { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
+   { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
+   { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
+   { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
+   { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
+   { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
+   { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
+   { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
+   { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
+   { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
+   { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
+   { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
+   { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
+   { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
+   { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
+   { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
+   { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
+   { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
+   { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
+   { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
+   { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
+   { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
+   { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
+   { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
+   { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
+   { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
+   { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
+   { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
+   { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
+   { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
+   { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
+   { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
+   { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
+   { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
+   { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
+   { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
+   { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
+   { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
+   { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
+   { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
+   { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
+   { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
+   { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
+   { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
+   { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
+   { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
+   { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
+   { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
+   { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
+   { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
+   { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
+   { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
+   { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
+   { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
+   { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
+   { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
+   { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
+   { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
+   { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
+   { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
+   { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
+   { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
+   { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
+   { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
+   { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
+   { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
+   { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
+   { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
+   { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
+   { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
+   { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
+   { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
+   { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
+   { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
+   { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
+   { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
+   { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
+   { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
+   { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
+   { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
+   { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
+   { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
+   { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
+   { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
+   { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
+   { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
+   { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
+   { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
+   { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
+   { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
+   { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
+   { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
+   { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
+   { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
+   { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
+   { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
+   { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
+   { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
+   { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
+   { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
+   { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
+   { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
+   { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
+   { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
+   { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
+   { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
+   { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
+   { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
+   { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
+   { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
+   { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
+   { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
+   { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
+   { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
+   { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
+   { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
+   { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
+   { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
+   { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
+   { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
+   { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
+   { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
+   { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
+   { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
+   { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
+   { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
+   { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
+   { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
+   { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
+   { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
+   { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
+   { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
+   { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
+   { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
+   { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
+   { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
+   { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
+   { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
+   { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+};
+
+/* find a hole and free as required, return -1 if no hole found */
+static int find_hole(void)
+{
+   unsigned x;
+   int      y, z;
+   for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
+       if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
+          z = x;
+          y = fp_cache[x].lru_count;
+       }
+   }
+
+   /* decrease all */
+   for (x = 0; x < FP_ENTRIES; x++) {
+      if (fp_cache[x].lru_count > 3) {
+         --(fp_cache[x].lru_count);
+      }
+   }
+
+   /* free entry z */
+   if (z >= 0 && fp_cache[z].g) {
+      mp_clear(&fp_cache[z].mu);
+      wc_ecc_del_point(fp_cache[z].g);
+      fp_cache[z].g  = NULL;
+      for (x = 0; x < (1U<<FP_LUT); x++) {
+         wc_ecc_del_point(fp_cache[z].LUT[x]);
+         fp_cache[z].LUT[x] = NULL;
+      }
+      fp_cache[z].lru_count = 0;
+   }
+   return z;
+}
+
+/* determine if a base is already in the cache and if so, where */
+static int find_base(ecc_point* g)
+{
+   int x;
+   for (x = 0; x < FP_ENTRIES; x++) {
+      if (fp_cache[x].g != NULL &&
+          mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
+          mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
+          mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
+         break;
+      }
+   }
+   if (x == FP_ENTRIES) {
+      x = -1;
+   }
+   return x;
+}
+
+/* add a new base to the cache */
+static int add_entry(int idx, ecc_point *g)
+{
+   unsigned x, y;
+
+   /* allocate base and LUT */
+   fp_cache[idx].g = wc_ecc_new_point();
+   if (fp_cache[idx].g == NULL) {
+      return GEN_MEM_ERR;
+   }
+
+   /* copy x and y */
+   if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
+       (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
+       (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
+      wc_ecc_del_point(fp_cache[idx].g);
+      fp_cache[idx].g = NULL;
+      return GEN_MEM_ERR;
+   }
+
+   for (x = 0; x < (1U<<FP_LUT); x++) {
+      fp_cache[idx].LUT[x] = wc_ecc_new_point();
+      if (fp_cache[idx].LUT[x] == NULL) {
+         for (y = 0; y < x; y++) {
+            wc_ecc_del_point(fp_cache[idx].LUT[y]);
+            fp_cache[idx].LUT[y] = NULL;
+         }
+         wc_ecc_del_point(fp_cache[idx].g);
+         fp_cache[idx].g         = NULL;
+         fp_cache[idx].lru_count = 0;
+         return GEN_MEM_ERR;
+      }
+   }
+
+   fp_cache[idx].lru_count = 0;
+
+   return MP_OKAY;
+}
+
+/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
+ *
+ * The algorithm builds patterns in increasing bit order by first making all
+ * single bit input patterns, then all two bit input patterns and so on
+ */
+static int build_lut(int idx, mp_int* modulus, mp_digit* mp, mp_int* mu)
+{
+   unsigned x, y, err, bitlen, lut_gap;
+   mp_int tmp;
+
+   if (mp_init(&tmp) != MP_OKAY)
+       return GEN_MEM_ERR;
+
+   /* sanity check to make sure lut_order table is of correct size,
+      should compile out to a NOP if true */
+   if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
+       err = BAD_FUNC_ARG;
+   }
+   else {
+    /* get bitlen and round up to next multiple of FP_LUT */
+    bitlen  = mp_unsigned_bin_size(modulus) << 3;
+    x       = bitlen % FP_LUT;
+    if (x) {
+      bitlen += FP_LUT - x;
+    }
+    lut_gap = bitlen / FP_LUT;
+
+    /* init the mu */
+    err = mp_init_copy(&fp_cache[idx].mu, mu);
+   }
+
+   /* copy base */
+   if (err == MP_OKAY) {
+     if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
+                  fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
+         (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
+                  fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
+         (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
+                  fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
+       err = MP_MULMOD_E;
+     }
+   }
+
+   /* make all single bit entries */
+   for (x = 1; x < FP_LUT; x++) {
+      if (err != MP_OKAY)
+          break;
+      if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x,
+                   fp_cache[idx].LUT[1<<x]->x) != MP_OKAY) ||
+          (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y,
+                   fp_cache[idx].LUT[1<<x]->y) != MP_OKAY) ||
+          (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z,
+                   fp_cache[idx].LUT[1<<x]->z) != MP_OKAY)){
+          err = MP_INIT_E;
+          break;
+      } else {
+
+         /* now double it bitlen/FP_LUT times */
+         for (y = 0; y < lut_gap; y++) {
+             if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[1<<x],
+                            fp_cache[idx].LUT[1<<x], modulus, mp)) != MP_OKAY) {
+                 break;
+             }
+         }
+     }
+  }
+
+   /* now make all entries in increase order of hamming weight */
+   for (x = 2; x <= FP_LUT; x++) {
+       if (err != MP_OKAY)
+           break;
+       for (y = 0; y < (1UL<<FP_LUT); y++) {
+           if (err != MP_OKAY)
+             break;
+           if (lut_orders[y].ham != (int)x) continue;
+
+           /* perform the add */
+           if ((err = ecc_projective_add_point(
+                           fp_cache[idx].LUT[lut_orders[y].terma],
+                           fp_cache[idx].LUT[lut_orders[y].termb],
+                           fp_cache[idx].LUT[y], modulus, mp)) != MP_OKAY) {
+              break;
+           }
+       }
+   }
+
+   /* now map all entries back to affine space to make point addition faster */
+   for (x = 1; x < (1UL<<FP_LUT); x++) {
+       if (err != MP_OKAY)
+           break;
+
+       /* convert z to normal from montgomery */
+       err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, *mp);
+
+       /* invert it */
+       if (err == MP_OKAY)
+         err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
+                         fp_cache[idx].LUT[x]->z);
+
+       if (err == MP_OKAY)
+         /* now square it */
+         err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, &tmp);
+
+       if (err == MP_OKAY)
+         /* fix x */
+         err = mp_mulmod(fp_cache[idx].LUT[x]->x, &tmp, modulus,
+                         fp_cache[idx].LUT[x]->x);
+
+       if (err == MP_OKAY)
+         /* get 1/z^3 */
+         err = mp_mulmod(&tmp, fp_cache[idx].LUT[x]->z, modulus, &tmp);
+
+       if (err == MP_OKAY)
+         /* fix y */
+         err = mp_mulmod(fp_cache[idx].LUT[x]->y, &tmp, modulus,
+                         fp_cache[idx].LUT[x]->y);
+
+       if (err == MP_OKAY)
+         /* free z */
+         mp_clear(fp_cache[idx].LUT[x]->z);
+   }
+   mp_clear(&tmp);
+
+   if (err == MP_OKAY)
+     return MP_OKAY;
+
+   /* err cleanup */
+   for (y = 0; y < (1U<<FP_LUT); y++) {
+      wc_ecc_del_point(fp_cache[idx].LUT[y]);
+      fp_cache[idx].LUT[y] = NULL;
+   }
+   wc_ecc_del_point(fp_cache[idx].g);
+   fp_cache[idx].g         = NULL;
+   fp_cache[idx].lru_count = 0;
+   mp_clear(&fp_cache[idx].mu);
+   mp_clear(&tmp);
+
+   return err;
+}
+
+/* perform a fixed point ECC mulmod */
+static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* modulus,
+                        mp_digit* mp, int map)
+{
+#define KB_SIZE 128
+
+#ifdef WOLFSSL_SMALL_STACK
+   unsigned char* kb;
+#else
+   unsigned char kb[128];
+#endif
+   int      x;
+   unsigned y, z, err, bitlen, bitpos, lut_gap, first;
+   mp_int   tk;
+
+   if (mp_init(&tk) != MP_OKAY)
+       return MP_INIT_E;
+
+   /* if it's smaller than modulus we fine */
+   if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
+      mp_int order;
+      if (mp_init(&order) != MP_OKAY) {
+        mp_clear(&tk);
+        return MP_INIT_E;
+      }
+
+      /* find order */
+      y = mp_unsigned_bin_size(modulus);
+      for (x = 0; ecc_sets[x].size; x++) {
+         if (y <= (unsigned)ecc_sets[x].size) break;
+      }
+
+      /* back off if we are on the 521 bit curve */
+      if (y == 66) --x;
+
+      if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) {
+         mp_clear(&order);
+         mp_clear(&tk);
+         return err;
+      }
+
+      /* k must be less than modulus */
+      if (mp_cmp(k, &order) != MP_LT) {
+         if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) {
+            mp_clear(&tk);
+            mp_clear(&order);
+            return err;
+         }
+      } else {
+         mp_copy(k, &tk);
+      }
+      mp_clear(&order);
+   } else {
+      mp_copy(k, &tk);
+   }
+
+   /* get bitlen and round up to next multiple of FP_LUT */
+   bitlen  = mp_unsigned_bin_size(modulus) << 3;
+   x       = bitlen % FP_LUT;
+   if (x) {
+      bitlen += FP_LUT - x;
+   }
+   lut_gap = bitlen / FP_LUT;
+
+   /* get the k value */
+   if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) {
+      mp_clear(&tk);
+      return BUFFER_E;
+   }
+
+   /* store k */
+#ifdef WOLFSSL_SMALL_STACK
+   kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+   if (kb == NULL)
+      return MEMORY_E;
+#endif
+
+   XMEMSET(kb, 0, KB_SIZE);
+   if ((err = mp_to_unsigned_bin(&tk, kb)) != MP_OKAY) {
+      mp_clear(&tk);
+   }
+   else {
+      /* let's reverse kb so it's little endian */
+      x = 0;
+      y = mp_unsigned_bin_size(&tk) - 1;
+      mp_clear(&tk);
+
+      while ((unsigned)x < y) {
+         z = kb[x]; kb[x] = kb[y]; kb[y] = z;
+         ++x; --y;
+      }
+
+      /* at this point we can start, yipee */
+      first = 1;
+      for (x = lut_gap-1; x >= 0; x--) {
+          /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
+             by x bits from the start */
+          bitpos = x;
+          for (y = z = 0; y < FP_LUT; y++) {
+             z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y;
+             bitpos += lut_gap;  /* it's y*lut_gap + x, but here we can avoid
+                                    the mult in each loop */
+          }
+
+          /* double if not first */
+          if (!first) {
+             if ((err = ecc_projective_dbl_point(R, R, modulus,
+                                                              mp)) != MP_OKAY) {
+                break;
+             }
+          }
+
+          /* add if not first, otherwise copy */
+          if (!first && z) {
+             if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R,
+                                                     modulus, mp)) != MP_OKAY) {
+                break;
+             }
+          } else if (z) {
+             if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
+                 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
+                 (mp_copy(&fp_cache[idx].mu,       R->z) != MP_OKAY)) {
+                 err = GEN_MEM_ERR;
+                 break;
+             }
+                 first = 0;
+          }
+      }
+   }
+
+   if (err == MP_OKAY) {
+      z = 0;
+      ForceZero(kb, KB_SIZE);
+      /* map R back from projective space */
+      if (map) {
+         err = ecc_map(R, modulus, mp);
+      } else {
+         err = MP_OKAY;
+      }
+   }
+
+#ifdef WOLFSSL_SMALL_STACK
+   XFREE(kb, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+#undef KB_SIZE
+
+   return err;
+}
+
+#ifdef ECC_SHAMIR
+/* perform a fixed point ECC mulmod */
+static int accel_fp_mul2add(int idx1, int idx2,
+                            mp_int* kA, mp_int* kB,
+                            ecc_point *R, mp_int* modulus, mp_digit* mp)
+{
+#define KB_SIZE 128
+
+#ifdef WOLFSSL_SMALL_STACK
+   unsigned char* kb[2];
+#else
+   unsigned char kb[2][128];
+#endif
+   int      x;
+   unsigned y, z, err, bitlen, bitpos, lut_gap, first, zA, zB;
+   mp_int tka;
+   mp_int tkb;
+   mp_int order;
+
+   if (mp_init_multi(&tka, &tkb, 0, 0, 0, 0) != MP_OKAY)
+       return MP_INIT_E;
+
+   /* if it's smaller than modulus we fine */
+   if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
+      /* find order */
+      y = mp_unsigned_bin_size(modulus);
+      for (x = 0; ecc_sets[x].size; x++) {
+         if (y <= (unsigned)ecc_sets[x].size) break;
+      }
+
+      /* back off if we are on the 521 bit curve */
+      if (y == 66) --x;
+
+      if ((err = mp_init(&order)) != MP_OKAY) {
+         mp_clear(&tkb);
+         mp_clear(&tka);
+         return err;
+      }
+      if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) {
+         mp_clear(&tkb);
+         mp_clear(&tka);
+         mp_clear(&order);
+         return err;
+      }
+
+      /* kA must be less than modulus */
+      if (mp_cmp(kA, &order) != MP_LT) {
+         if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) {
+            mp_clear(&tkb);
+            mp_clear(&tka);
+            mp_clear(&order);
+            return err;
+         }
+      } else {
+         mp_copy(kA, &tka);
+      }
+      mp_clear(&order);
+   } else {
+      mp_copy(kA, &tka);
+   }
+
+   /* if it's smaller than modulus we fine */
+   if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
+      /* find order */
+      y = mp_unsigned_bin_size(modulus);
+      for (x = 0; ecc_sets[x].size; x++) {
+         if (y <= (unsigned)ecc_sets[x].size) break;
+      }
+
+      /* back off if we are on the 521 bit curve */
+      if (y == 66) --x;
+
+      if ((err = mp_init(&order)) != MP_OKAY) {
+         mp_clear(&tkb);
+         mp_clear(&tka);
+         return err;
+      }
+      if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) {
+         mp_clear(&tkb);
+         mp_clear(&tka);
+         mp_clear(&order);
+         return err;
+      }
+
+      /* kB must be less than modulus */
+      if (mp_cmp(kB, &order) != MP_LT) {
+         if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) {
+            mp_clear(&tkb);
+            mp_clear(&tka);
+            mp_clear(&order);
+            return err;
+         }
+      } else {
+         mp_copy(kB, &tkb);
+      }
+      mp_clear(&order);
+   } else {
+      mp_copy(kB, &tkb);
+   }
+
+   /* get bitlen and round up to next multiple of FP_LUT */
+   bitlen  = mp_unsigned_bin_size(modulus) << 3;
+   x       = bitlen % FP_LUT;
+   if (x) {
+      bitlen += FP_LUT - x;
+   }
+   lut_gap = bitlen / FP_LUT;
+
+   /* get the k value */
+   if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) ||
+       (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2))  ) {
+      mp_clear(&tka);
+      mp_clear(&tkb);
+      return BUFFER_E;
+   }
+
+   /* store k */
+#ifdef WOLFSSL_SMALL_STACK
+   kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+   if (kb[0] == NULL)
+      return MEMORY_E;
+#endif
+
+   XMEMSET(kb[0], 0, KB_SIZE);
+   if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) {
+      mp_clear(&tka);
+      mp_clear(&tkb);
+#ifdef WOLFSSL_SMALL_STACK
+      XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+      return err;
+   }
+
+   /* let's reverse kb so it's little endian */
+   x = 0;
+   y = mp_unsigned_bin_size(&tka) - 1;
+   mp_clear(&tka);
+   while ((unsigned)x < y) {
+      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = z;
+      ++x; --y;
+   }
+
+   /* store b */
+#ifdef WOLFSSL_SMALL_STACK
+   kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+   if (kb[1] == NULL) {
+      XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER);
+      return MEMORY_E;
+   }
+#endif
+
+   XMEMSET(kb[1], 0, KB_SIZE);
+   if ((err = mp_to_unsigned_bin(&tkb, kb[1])) != MP_OKAY) {
+      mp_clear(&tkb);
+   }
+   else {
+      x = 0;
+      y = mp_unsigned_bin_size(&tkb) - 1;
+      mp_clear(&tkb);
+      while ((unsigned)x < y) {
+         z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z;
+         ++x; --y;
+      }
+
+      /* at this point we can start, yipee */
+      first = 1;
+      for (x = lut_gap-1; x >= 0; x--) {
+          /* extract FP_LUT bits from kb spread out by lut_gap bits and
+             offset by x bits from the start */
+          bitpos = x;
+          for (y = zA = zB = 0; y < FP_LUT; y++) {
+             zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y;
+             zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y;
+             bitpos += lut_gap;    /* it's y*lut_gap + x, but here we can avoid
+                                      the mult in each loop */
+          }
+
+          /* double if not first */
+          if (!first) {
+             if ((err = ecc_projective_dbl_point(R, R, modulus,
+                                                              mp)) != MP_OKAY) {
+                break;
+             }
+          }
+
+          /* add if not first, otherwise copy */
+          if (!first) {
+             if (zA) {
+                if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA],
+                                                  R, modulus, mp)) != MP_OKAY) {
+                   break;
+                }
+             }
+             if (zB) {
+                if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB],
+                                                  R, modulus, mp)) != MP_OKAY) {
+                   break;
+                }
+             }
+          } else {
+             if (zA) {
+                 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
+                    (mp_copy(fp_cache[idx1].LUT[zA]->y,  R->y) != MP_OKAY) ||
+                    (mp_copy(&fp_cache[idx1].mu,         R->z) != MP_OKAY)) {
+                     err = GEN_MEM_ERR;
+                     break;
+                 }
+                    first = 0;
+             }
+             if (zB && first == 0) {
+                if (zB) {
+                   if ((err = ecc_projective_add_point(R,
+                           fp_cache[idx2].LUT[zB], R, modulus, mp)) != MP_OKAY){
+                      break;
+                   }
+                }
+             } else if (zB && first == 1) {
+                 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
+                    (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
+                    (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {
+                     err = GEN_MEM_ERR;
+                     break;
+                 }
+                    first = 0;
+             }
+          }
+      }
+   }
+
+   ForceZero(kb[0], KB_SIZE);
+   ForceZero(kb[1], KB_SIZE);
+
+#ifdef WOLFSSL_SMALL_STACK
+   XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER);
+   XFREE(kb[1], NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+#undef KB_SIZE
+
+   return ecc_map(R, modulus, mp);
+}
+
+/** ECC Fixed Point mulmod global
+  Computes kA*A + kB*B = C using Shamir's Trick
+  A        First point to multiply
+  kA       What to multiple A by
+  B        Second point to multiply
+  kB       What to multiple B by
+  C        [out] Destination point (can overlap with A or B)
+  modulus  Modulus for curve
+  return MP_OKAY on success
+*/
+int ecc_mul2add(ecc_point* A, mp_int* kA,
+                ecc_point* B, mp_int* kB,
+                ecc_point* C, mp_int* modulus)
+{
+   int  idx1 = -1, idx2 = -1, err = MP_OKAY, mpInit = 0;
+   mp_digit mp;
+   mp_int   mu;
+
+   err = mp_init(&mu);
+   if (err != MP_OKAY)
+       return err;
+
+#ifndef HAVE_THREAD_LS
+   if (initMutex == 0) {
+        InitMutex(&ecc_fp_lock);
+        initMutex = 1;
+   }
+   if (LockMutex(&ecc_fp_lock) != 0)
+      return BAD_MUTEX_E;
+#endif /* HAVE_THREAD_LS */
+
+      /* find point */
+      idx1 = find_base(A);
+
+      /* no entry? */
+      if (idx1 == -1) {
+         /* find hole and add it */
+         if ((idx1 = find_hole()) >= 0) {
+            err = add_entry(idx1, A);
+         }
+      }
+      if (err == MP_OKAY && idx1 != -1) {
+         /* increment LRU */
+         ++(fp_cache[idx1].lru_count);
+      }
+
+      if (err == MP_OKAY)
+        /* find point */
+        idx2 = find_base(B);
+
+      if (err == MP_OKAY) {
+        /* no entry? */
+        if (idx2 == -1) {
+           /* find hole and add it */
+           if ((idx2 = find_hole()) >= 0)
+              err = add_entry(idx2, B);
+         }
+      }
+
+      if (err == MP_OKAY && idx2 != -1) {
+         /* increment LRU */
+         ++(fp_cache[idx2].lru_count);
+      }
+
+      if (err == MP_OKAY) {
+        /* if it's 2 build the LUT, if it's higher just use the LUT */
+        if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) {
+           /* compute mp */
+           err = mp_montgomery_setup(modulus, &mp);
+
+           if (err == MP_OKAY) {
+             mpInit = 1;
+             err = mp_montgomery_calc_normalization(&mu, modulus);
+           }
+
+           if (err == MP_OKAY)
+             /* build the LUT */
+               err = build_lut(idx1, modulus, &mp, &mu);
+        }
+      }
+
+      if (err == MP_OKAY) {
+        /* if it's 2 build the LUT, if it's higher just use the LUT */
+        if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) {
+           if (mpInit == 0) {
+                /* compute mp */
+                err = mp_montgomery_setup(modulus, &mp);
+                if (err == MP_OKAY) {
+                    mpInit = 1;
+                    err = mp_montgomery_calc_normalization(&mu, modulus);
+                }
+            }
+
+            if (err == MP_OKAY)
+            /* build the LUT */
+              err = build_lut(idx2, modulus, &mp, &mu);
+        }
+      }
+
+
+      if (err == MP_OKAY) {
+        if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 &&
+                                     fp_cache[idx2].lru_count >= 2) {
+           if (mpInit == 0) {
+              /* compute mp */
+              err = mp_montgomery_setup(modulus, &mp);
+           }
+           if (err == MP_OKAY)
+             err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, &mp);
+        } else {
+           err = normal_ecc_mul2add(A, kA, B, kB, C, modulus);
+        }
+    }
+
+#ifndef HAVE_THREAD_LS
+    UnLockMutex(&ecc_fp_lock);
+#endif /* HAVE_THREAD_LS */
+    mp_clear(&mu);
+
+    return err;
+}
+#endif /* ECC_SHAMIR */
+
+/** ECC Fixed Point mulmod global
+    k        The multiplicand
+    G        Base point to multiply
+    R        [out] Destination of product
+    modulus  The modulus for the curve
+    map      [boolean] If non-zero maps the point back to affine co-ordinates,
+             otherwise it's left in jacobian-montgomery form
+    return MP_OKAY if successful
+*/
+int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus,
+               int map)
+{
+   int   idx, err = MP_OKAY;
+   mp_digit mp;
+   mp_int   mu;
+   int      mpSetup = 0;
+
+   if (mp_init(&mu) != MP_OKAY)
+       return MP_INIT_E;
+
+#ifndef HAVE_THREAD_LS
+   if (initMutex == 0) {
+        InitMutex(&ecc_fp_lock);
+        initMutex = 1;
+   }
+
+   if (LockMutex(&ecc_fp_lock) != 0)
+      return BAD_MUTEX_E;
+#endif /* HAVE_THREAD_LS */
+
+      /* find point */
+      idx = find_base(G);
+
+      /* no entry? */
+      if (idx == -1) {
+         /* find hole and add it */
+         idx = find_hole();
+
+         if (idx >= 0)
+            err = add_entry(idx, G);
+      }
+      if (err == MP_OKAY && idx >= 0) {
+         /* increment LRU */
+         ++(fp_cache[idx].lru_count);
+      }
+
+
+      if (err == MP_OKAY) {
+        /* if it's 2 build the LUT, if it's higher just use the LUT */
+        if (idx >= 0 && fp_cache[idx].lru_count == 2) {
+           /* compute mp */
+           err = mp_montgomery_setup(modulus, &mp);
+
+           if (err == MP_OKAY) {
+             /* compute mu */
+             mpSetup = 1;
+             err = mp_montgomery_calc_normalization(&mu, modulus);
+           }
+
+           if (err == MP_OKAY)
+             /* build the LUT */
+             err = build_lut(idx, modulus, &mp, &mu);
+        }
+      }
+
+      if (err == MP_OKAY) {
+        if (idx >= 0 && fp_cache[idx].lru_count >= 2) {
+           if (mpSetup == 0) {
+              /* compute mp */
+              err = mp_montgomery_setup(modulus, &mp);
+           }
+           if (err == MP_OKAY)
+             err = accel_fp_mul(idx, k, R, modulus, &mp, map);
+        } else {
+           err = normal_ecc_mulmod(k, G, R, modulus, map);
+        }
+     }
+
+#ifndef HAVE_THREAD_LS
+    UnLockMutex(&ecc_fp_lock);
+#endif /* HAVE_THREAD_LS */
+    mp_clear(&mu);
+
+    return err;
+}
+
+/* helper function for freeing the cache ...
+   must be called with the cache mutex locked */
+static void wc_ecc_fp_free_cache(void)
+{
+   unsigned x, y;
+   for (x = 0; x < FP_ENTRIES; x++) {
+      if (fp_cache[x].g != NULL) {
+         for (y = 0; y < (1U<<FP_LUT); y++) {
+            wc_ecc_del_point(fp_cache[x].LUT[y]);
+            fp_cache[x].LUT[y] = NULL;
+         }
+         wc_ecc_del_point(fp_cache[x].g);
+         fp_cache[x].g         = NULL;
+         mp_clear(&fp_cache[x].mu);
+         fp_cache[x].lru_count = 0;
+         fp_cache[x].lock = 0;
+      }
+   }
+}
+
+/** Free the Fixed Point cache */
+void wc_ecc_fp_free(void)
+{
+#ifndef HAVE_THREAD_LS
+   if (initMutex == 0) {
+        InitMutex(&ecc_fp_lock);
+        initMutex = 1;
+   }
+
+   if (LockMutex(&ecc_fp_lock) == 0) {
+#endif /* HAVE_THREAD_LS */
+
+       wc_ecc_fp_free_cache();
+
+#ifndef HAVE_THREAD_LS
+       UnLockMutex(&ecc_fp_lock);
+       FreeMutex(&ecc_fp_lock);
+       initMutex = 0;
+   }
+#endif /* HAVE_THREAD_LS */
+}
+
+
+#endif /* FP_ECC */
+
+#ifdef HAVE_ECC_ENCRYPT
+
+
+enum ecCliState {
+    ecCLI_INIT      = 1,
+    ecCLI_SALT_GET  = 2,
+    ecCLI_SALT_SET  = 3,
+    ecCLI_SENT_REQ  = 4,
+    ecCLI_RECV_RESP = 5,
+    ecCLI_BAD_STATE = 99
+};
+
+enum ecSrvState {
+    ecSRV_INIT      = 1,
+    ecSRV_SALT_GET  = 2,
+    ecSRV_SALT_SET  = 3,
+    ecSRV_RECV_REQ  = 4,
+    ecSRV_SENT_RESP = 5,
+    ecSRV_BAD_STATE = 99
+};
+
+
+struct ecEncCtx {
+    const byte* kdfSalt;   /* optional salt for kdf */
+    const byte* kdfInfo;   /* optional info for kdf */
+    const byte* macSalt;   /* optional salt for mac */
+    word32    kdfSaltSz;   /* size of kdfSalt */
+    word32    kdfInfoSz;   /* size of kdfInfo */
+    word32    macSaltSz;   /* size of macSalt */
+    byte      clientSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
+    byte      serverSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
+    byte      encAlgo;     /* which encryption type */
+    byte      kdfAlgo;     /* which key derivation function type */
+    byte      macAlgo;     /* which mac function type */
+    byte      protocol;    /* are we REQ_RESP client or server ? */
+    byte      cliSt;       /* protocol state, for sanity checks */
+    byte      srvSt;       /* protocol state, for sanity checks */
+};
+
+
+const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
+{
+    if (ctx == NULL || ctx->protocol == 0)
+        return NULL;
+
+    if (ctx->protocol == REQ_RESP_CLIENT) {
+        if (ctx->cliSt == ecCLI_INIT) {
+            ctx->cliSt =  ecCLI_SALT_GET;
+            return ctx->clientSalt;
+        }
+        else {
+            ctx->cliSt = ecCLI_BAD_STATE;
+            return NULL;
+        }
+    }
+    else if (ctx->protocol == REQ_RESP_SERVER) {
+        if (ctx->srvSt == ecSRV_INIT) {
+            ctx->srvSt =  ecSRV_SALT_GET;
+            return ctx->serverSalt;
+        }
+        else {
+            ctx->srvSt = ecSRV_BAD_STATE;
+            return NULL;
+        }
+    }
+
+    return NULL;
+}
+
+
+/* optional set info, can be called before or after set_peer_salt */
+int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
+{
+    if (ctx == NULL || info == 0 || sz < 0)
+        return BAD_FUNC_ARG;
+
+    ctx->kdfInfo   = info;
+    ctx->kdfInfoSz = sz;
+
+    return 0;
+}
+
+
+static const char* exchange_info = "Secure Message Exchange";
+
+int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
+{
+    byte tmp[EXCHANGE_SALT_SZ/2];
+    int  halfSz = EXCHANGE_SALT_SZ/2;
+
+    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ctx->protocol == REQ_RESP_CLIENT) {
+        XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
+        if (ctx->cliSt == ecCLI_SALT_GET)
+            ctx->cliSt =  ecCLI_SALT_SET;
+        else {
+            ctx->cliSt =  ecCLI_BAD_STATE;
+            return BAD_ENC_STATE_E;
+        }
+    }
+    else {
+        XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
+        if (ctx->srvSt == ecSRV_SALT_GET)
+            ctx->srvSt =  ecSRV_SALT_SET;
+        else {
+            ctx->srvSt =  ecSRV_BAD_STATE;
+            return BAD_ENC_STATE_E;
+        }
+    }
+
+    /* mix half and half */
+    /* tmp stores 2nd half of client before overwrite */
+    XMEMCPY(tmp, ctx->clientSalt + halfSz, halfSz);
+    XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, halfSz);
+    XMEMCPY(ctx->serverSalt, tmp, halfSz);
+
+    ctx->kdfSalt   = ctx->clientSalt;
+    ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
+
+    ctx->macSalt   = ctx->serverSalt;
+    ctx->macSaltSz = EXCHANGE_SALT_SZ;
+
+    if (ctx->kdfInfo == NULL) {
+        /* default info */
+        ctx->kdfInfo   = (const byte*)exchange_info;
+        ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
+    }
+
+    return 0;
+}
+
+
+static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, WC_RNG* rng)
+{
+    byte* saltBuffer = NULL;
+
+    if (ctx == NULL || rng == NULL || flags == 0)
+        return BAD_FUNC_ARG;
+
+    saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
+
+    return wc_RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ);
+}
+
+
+static void ecc_ctx_init(ecEncCtx* ctx, int flags)
+{
+    if (ctx) {
+        XMEMSET(ctx, 0, sizeof(ecEncCtx));
+
+        ctx->encAlgo  = ecAES_128_CBC;
+        ctx->kdfAlgo  = ecHKDF_SHA256;
+        ctx->macAlgo  = ecHMAC_SHA256;
+        ctx->protocol = (byte)flags;
+
+        if (flags == REQ_RESP_CLIENT)
+            ctx->cliSt = ecCLI_INIT;
+        if (flags == REQ_RESP_SERVER)
+            ctx->srvSt = ecSRV_INIT;
+    }
+}
+
+
+/* allow ecc context reset so user doesn't have to init/free for resue */
+int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
+{
+    if (ctx == NULL || rng == NULL)
+        return BAD_FUNC_ARG;
+
+    ecc_ctx_init(ctx, ctx->protocol);
+    return ecc_ctx_set_salt(ctx, ctx->protocol, rng);
+}
+
+
+/* alloc/init and set defaults, return new Context  */
+ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
+{
+    int       ret = 0;
+    ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), 0, DYNAMIC_TYPE_ECC);
+
+    if (ctx)
+        ctx->protocol = (byte)flags;
+
+    ret = wc_ecc_ctx_reset(ctx, rng);
+    if (ret != 0) {
+        wc_ecc_ctx_free(ctx);
+        ctx = NULL;
+    }
+
+    return ctx;
+}
+
+
+/* free any resources, clear any keys */
+void wc_ecc_ctx_free(ecEncCtx* ctx)
+{
+    if (ctx) {
+        ForceZero(ctx, sizeof(ecEncCtx));
+        XFREE(ctx, 0, DYNAMIC_TYPE_ECC);
+    }
+}
+
+
+static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
+                             int* keysLen, word32* digestSz, word32* blockSz)
+{
+    if (ctx) {
+        switch (ctx->encAlgo) {
+            case ecAES_128_CBC:
+                *encKeySz = KEY_SIZE_128;
+                *ivSz     = IV_SIZE_128;
+                *blockSz  = AES_BLOCK_SIZE;
+                break;
+            default:
+                return BAD_FUNC_ARG;
+        }
+
+        switch (ctx->macAlgo) {
+            case ecHMAC_SHA256:
+                *digestSz = SHA256_DIGEST_SIZE;
+                break;
+            default:
+                return BAD_FUNC_ARG;
+        }
+    } else
+        return BAD_FUNC_ARG;
+
+    *keysLen  = *encKeySz + *ivSz + *digestSz;
+
+    return 0;
+}
+
+
+/* ecc encrypt with shared secret run through kdf
+   ctx holds non default algos and inputs
+   msgSz should be the right size for encAlgo, i.e., already padded
+   return 0 on success */
+int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
+                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
+{
+    int          ret;
+    word32       blockSz;
+    word32       digestSz;
+    ecEncCtx     localCtx;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*        sharedSecret;
+    byte*        keys;
+#else
+    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
+    byte         keys[ECC_BUFSIZE];         /* max size */
+#endif
+    word32       sharedSz = ECC_MAXSIZE;
+    int          keysLen;
+    int          encKeySz;
+    int          ivSz;
+    int          offset = 0;         /* keys offset if doing msg exchange */
+    byte*        encKey;
+    byte*        encIv;
+    byte*        macKey;
+
+    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
+                           outSz  == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ctx == NULL) {  /* use defaults */
+        ecc_ctx_init(&localCtx, 0);
+        ctx = &localCtx;
+    }
+
+    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
+                            &blockSz);
+    if (ret != 0)
+        return ret;
+
+    if (ctx->protocol == REQ_RESP_SERVER) {
+        offset = keysLen;
+        keysLen *= 2;
+
+        if (ctx->srvSt != ecSRV_RECV_REQ)
+            return BAD_ENC_STATE_E;
+
+        ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
+    }
+    else if (ctx->protocol == REQ_RESP_CLIENT) {
+        if (ctx->cliSt != ecCLI_SALT_SET)
+            return BAD_ENC_STATE_E;
+
+        ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
+    }
+
+    if (keysLen > ECC_BUFSIZE) /* keys size */
+        return BUFFER_E;
+
+    if ( (msgSz%blockSz) != 0)
+        return BAD_PADDING_E;
+
+    if (*outSz < (msgSz + digestSz))
+        return BUFFER_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+    sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (sharedSecret == NULL)
+        return MEMORY_E;
+
+    keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (keys == NULL) {
+        XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
+
+    if (ret == 0) {
+       switch (ctx->kdfAlgo) {
+           case ecHKDF_SHA256 :
+               ret = wc_HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
+                          ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
+                          keys, keysLen);
+               break;
+
+           default:
+               ret = BAD_FUNC_ARG;
+               break;
+       }
+    }
+
+    if (ret == 0) {
+       encKey = keys + offset;
+       encIv  = encKey + encKeySz;
+       macKey = encKey + encKeySz + ivSz;
+
+       switch (ctx->encAlgo) {
+           case ecAES_128_CBC:
+               {
+                   Aes aes;
+                   ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,
+                                                                AES_ENCRYPTION);
+                   if (ret != 0)
+                       break;
+                   ret = wc_AesCbcEncrypt(&aes, out, msg, msgSz);
+               }
+               break;
+
+           default:
+               ret = BAD_FUNC_ARG;
+               break;
+       }
+    }
+
+    if (ret == 0) {
+       switch (ctx->macAlgo) {
+           case ecHMAC_SHA256:
+               {
+                   Hmac hmac;
+                   ret = wc_HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE);
+                   if (ret != 0)
+                       break;
+                   ret = wc_HmacUpdate(&hmac, out, msgSz);
+                   if (ret != 0)
+                       break;
+                   ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
+                   if (ret != 0)
+                       break;
+                   ret = wc_HmacFinal(&hmac, out+msgSz);
+               }
+               break;
+
+           default:
+               ret = BAD_FUNC_ARG;
+               break;
+       }
+    }
+
+    if (ret == 0)
+       *outSz = msgSz + digestSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(keys, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+/* ecc decrypt with shared secret run through kdf
+   ctx holds non default algos and inputs
+   return 0 on success */
+int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
+                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
+{
+    int          ret;
+    word32       blockSz;
+    word32       digestSz;
+    ecEncCtx     localCtx;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*        sharedSecret;
+    byte*        keys;
+#else
+    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
+    byte         keys[ECC_BUFSIZE];         /* max size */
+#endif
+    word32       sharedSz = ECC_MAXSIZE;
+    int          keysLen;
+    int          encKeySz;
+    int          ivSz;
+    int          offset = 0;       /* in case using msg exchange */
+    byte*        encKey;
+    byte*        encIv;
+    byte*        macKey;
+
+    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
+                           outSz  == NULL)
+        return BAD_FUNC_ARG;
+
+    if (ctx == NULL) {  /* use defaults */
+        ecc_ctx_init(&localCtx, 0);
+        ctx = &localCtx;
+    }
+
+    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
+                            &blockSz);
+    if (ret != 0)
+        return ret;
+
+    if (ctx->protocol == REQ_RESP_CLIENT) {
+        offset = keysLen;
+        keysLen *= 2;
+
+        if (ctx->cliSt != ecCLI_SENT_REQ)
+            return BAD_ENC_STATE_E;
+
+        ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
+    }
+    else if (ctx->protocol == REQ_RESP_SERVER) {
+        if (ctx->srvSt != ecSRV_SALT_SET)
+            return BAD_ENC_STATE_E;
+
+        ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
+    }
+
+    if (keysLen > ECC_BUFSIZE) /* keys size */
+        return BUFFER_E;
+
+    if ( ((msgSz-digestSz) % blockSz) != 0)
+        return BAD_PADDING_E;
+
+    if (*outSz < (msgSz - digestSz))
+        return BUFFER_E;
+
+#ifdef WOLFSSL_SMALL_STACK
+    sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (sharedSecret == NULL)
+        return MEMORY_E;
+
+    keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (keys == NULL) {
+        XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
+
+    if (ret == 0) {
+       switch (ctx->kdfAlgo) {
+           case ecHKDF_SHA256 :
+               ret = wc_HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
+                          ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
+                          keys, keysLen);
+               break;
+
+           default:
+               ret = BAD_FUNC_ARG;
+               break;
+       }
+    }
+
+    if (ret == 0) {
+       encKey = keys + offset;
+       encIv  = encKey + encKeySz;
+       macKey = encKey + encKeySz + ivSz;
+
+       switch (ctx->macAlgo) {
+           case ecHMAC_SHA256:
+               {
+                   byte verify[SHA256_DIGEST_SIZE];
+                   Hmac hmac;
+                   ret = wc_HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE);
+                   if (ret != 0)
+                       break;
+                   ret = wc_HmacUpdate(&hmac, msg, msgSz-digestSz);
+                   if (ret != 0)
+                       break;
+                   ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
+                   if (ret != 0)
+                       break;
+                   ret = wc_HmacFinal(&hmac, verify);
+                   if (ret != 0)
+                       break;
+                   if (memcmp(verify, msg + msgSz - digestSz, digestSz) != 0)
+                       ret = -1;
+               }
+               break;
+
+           default:
+               ret = BAD_FUNC_ARG;
+               break;
+       }
+    }
+
+    if (ret == 0) {
+       switch (ctx->encAlgo) {
+           case ecAES_128_CBC:
+               {
+                   Aes aes;
+                   ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,
+                                                                AES_DECRYPTION);
+                   if (ret != 0)
+                       break;
+                   ret = wc_AesCbcDecrypt(&aes, out, msg, msgSz-digestSz);
+               }
+               break;
+
+           default:
+               ret = BAD_FUNC_ARG;
+               break;
+       }
+    }
+
+    if (ret == 0)
+       *outSz = msgSz - digestSz;
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(keys, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+#endif /* HAVE_ECC_ENCRYPT */
+
+
+#ifdef HAVE_COMP_KEY
+
+/* computes the jacobi c = (a | n) (or Legendre if n is prime)
+ * HAC pp. 73 Algorithm 2.149
+ */
+int mp_jacobi(mp_int* a, mp_int* p, int* c)
+{
+  mp_int   a1, p1;
+  int      k, s, r, res;
+  mp_digit residue;
+
+  /* if p <= 0 return MP_VAL */
+  if (mp_cmp_d(p, 0) != MP_GT) {
+     return MP_VAL;
+  }
+
+  /* step 1.  if a == 0, return 0 */
+  if (mp_iszero (a) == 1) {
+    *c = 0;
+    return MP_OKAY;
+  }
+
+  /* step 2.  if a == 1, return 1 */
+  if (mp_cmp_d (a, 1) == MP_EQ) {
+    *c = 1;
+    return MP_OKAY;
+  }
+
+  /* default */
+  s = 0;
+
+  /* step 3.  write a = a1 * 2**k  */
+  if ((res = mp_init_copy (&a1, a)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_init (&p1)) != MP_OKAY) {
+    mp_clear(&a1);
+    return res;
+  }
+
+  /* divide out larger power of two */
+  k = mp_cnt_lsb(&a1);
+  res = mp_div_2d(&a1, k, &a1, NULL);
+
+  if (res == MP_OKAY) {
+    /* step 4.  if e is even set s=1 */
+    if ((k & 1) == 0) {
+      s = 1;
+    } else {
+      /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
+      residue = p->dp[0] & 7;
+
+      if (residue == 1 || residue == 7) {
+        s = 1;
+      } else if (residue == 3 || residue == 5) {
+        s = -1;
+      }
+    }
+
+    /* step 5.  if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */
+    if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) {
+      s = -s;
+    }
+  }
+
+  if (res == MP_OKAY) {
+    /* if a1 == 1 we're done */
+    if (mp_cmp_d (&a1, 1) == MP_EQ) {
+      *c = s;
+    } else {
+      /* n1 = n mod a1 */
+      res = mp_mod (p, &a1, &p1);
+      if (res == MP_OKAY)
+        res = mp_jacobi (&p1, &a1, &r);
+
+      if (res == MP_OKAY)
+      *c = s * r;
+    }
+  }
+
+  /* done */
+  mp_clear (&p1);
+  mp_clear (&a1);
+
+  return res;
+}
+
+
+int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
+{
+  int res, legendre, done = 0;
+  mp_int t1, C, Q, S, Z, M, T, R, two;
+  mp_digit i;
+
+  /* first handle the simple cases */
+  if (mp_cmp_d(n, 0) == MP_EQ) {
+    mp_zero(ret);
+    return MP_OKAY;
+  }
+  if (mp_cmp_d(prime, 2) == MP_EQ)       return MP_VAL; /* prime must be odd */
+  /* TAO removed
+  if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY)      return res;
+  if (legendre == -1)  return MP_VAL; */ /* quadratic non-residue mod prime */
+
+  if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY)
+    return res;
+
+  if ((res = mp_init_multi(&T, &R, &two, NULL, NULL, NULL))
+                          != MP_OKAY) {
+    mp_clear(&t1); mp_clear(&C); mp_clear(&Q); mp_clear(&S); mp_clear(&Z);
+    mp_clear(&M);
+    return res;
+  }
+
+  /* SPECIAL CASE: if prime mod 4 == 3
+   * compute directly: res = n^(prime+1)/4 mod prime
+   * Handbook of Applied Cryptography algorithm 3.36
+   */
+  res = mp_mod_d(prime, 4, &i);
+  if (res == MP_OKAY && i == 3) {
+    res = mp_add_d(prime, 1, &t1);
+
+    if (res == MP_OKAY)
+      res = mp_div_2(&t1, &t1);
+    if (res == MP_OKAY)
+      res = mp_div_2(&t1, &t1);
+    if (res == MP_OKAY)
+      res = mp_exptmod(n, &t1, prime, ret);
+
+    done = 1;
+  }
+
+  /* NOW: TonelliShanks algorithm */
+
+ if (res == MP_OKAY && done == 0) {
+
+   /* factor out powers of 2 from prime-1, defining Q and S
+    *                                      as: prime-1 = Q*2^S */
+    res = mp_copy(prime, &Q);
+    if (res == MP_OKAY)
+      res = mp_sub_d(&Q, 1, &Q);
+    /* Q = prime - 1 */
+    if (res == MP_OKAY)
+      mp_zero(&S);
+    /* S = 0 */
+    while (res == MP_OKAY && mp_iseven(&Q)) {
+      res = mp_div_2(&Q, &Q);
+      /* Q = Q / 2 */
+      if (res == MP_OKAY)
+        res = mp_add_d(&S, 1, &S);
+        /* S = S + 1 */
+    }
+
+    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
+    if (res == MP_OKAY)
+      res = mp_set_int(&Z, 2);
+    /* Z = 2 */
+    while (res == MP_OKAY) {
+      res = mp_jacobi(&Z, prime, &legendre);
+      if (res == MP_OKAY && legendre == -1)
+        break;
+      if (res == MP_OKAY)
+        res = mp_add_d(&Z, 1, &Z);
+        /* Z = Z + 1 */
+    }
+
+    if (res == MP_OKAY)
+      res = mp_exptmod(&Z, &Q, prime, &C);
+      /* C = Z ^ Q mod prime */
+    if (res == MP_OKAY)
+      res = mp_add_d(&Q, 1, &t1);
+    if (res == MP_OKAY)
+      res = mp_div_2(&t1, &t1);
+      /* t1 = (Q + 1) / 2 */
+    if (res == MP_OKAY)
+      res = mp_exptmod(n, &t1, prime, &R);
+    /* R = n ^ ((Q + 1) / 2) mod prime */
+    if (res == MP_OKAY)
+      res = mp_exptmod(n, &Q, prime, &T);
+    /* T = n ^ Q mod prime */
+    if (res == MP_OKAY)
+      res = mp_copy(&S, &M);
+    /* M = S */
+    if (res == MP_OKAY)
+      res = mp_set_int(&two, 2);
+
+    while (res == MP_OKAY && done == 0) {
+      res = mp_copy(&T, &t1);
+      i = 0;
+      while (res == MP_OKAY) {
+        if (mp_cmp_d(&t1, 1) == MP_EQ)
+            break;
+        res = mp_exptmod(&t1, &two, prime, &t1);
+        if (res == MP_OKAY)
+          i++;
+      }
+      if (res == MP_OKAY && i == 0) {
+        mp_copy(&R, ret);
+        res = MP_OKAY;
+        done = 1;
+      }
+
+      if (done == 0) {
+        if (res == MP_OKAY)
+          res = mp_sub_d(&M, i, &t1);
+        if (res == MP_OKAY)
+          res = mp_sub_d(&t1, 1, &t1);
+        if (res == MP_OKAY)
+          res = mp_exptmod(&two, &t1, prime, &t1);
+        /* t1 = 2 ^ (M - i - 1) */
+        if (res == MP_OKAY)
+          res = mp_exptmod(&C, &t1, prime, &t1);
+        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
+        if (res == MP_OKAY)
+          res = mp_sqrmod(&t1, prime, &C);
+        /* C = (t1 * t1) mod prime */
+        if (res == MP_OKAY)
+          res = mp_mulmod(&R, &t1, prime, &R);
+        /* R = (R * t1) mod prime */
+        if (res == MP_OKAY)
+          res = mp_mulmod(&T, &C, prime, &T);
+        /* T = (T * C) mod prime */
+        if (res == MP_OKAY)
+          mp_set(&M, i);
+        /* M = i */
+      }
+    }
+  }
+
+  /* done */
+  mp_clear(&t1);
+  mp_clear(&C);
+  mp_clear(&Q);
+  mp_clear(&S);
+  mp_clear(&Z);
+  mp_clear(&M);
+  mp_clear(&T);
+  mp_clear(&R);
+  mp_clear(&two);
+
+  return res;
+}
+
+
+/* export public ECC key in ANSI X9.63 format compressed */
+int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
+{
+   word32 numlen;
+   int    ret = MP_OKAY;
+
+   if (key == NULL || out == NULL || outLen == NULL)
+       return ECC_BAD_ARG_E;
+
+   if (wc_ecc_is_valid_idx(key->idx) == 0) {
+      return ECC_BAD_ARG_E;
+   }
+   numlen = key->dp->size;
+
+   if (*outLen < (1 + numlen)) {
+      *outLen = 1 + numlen;
+      return BUFFER_E;
+   }
+
+   /* store first byte */
+   out[0] = mp_isodd(key->pubkey.y) ? 0x03 : 0x02;
+
+   /* pad and store x */
+   XMEMSET(out+1, 0, numlen);
+   ret = mp_to_unsigned_bin(key->pubkey.x,
+                       out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x)));
+   *outLen = 1 + numlen;
+   return ret;
+}
+
+
+/* d = a - b (mod c) */
+int mp_submod(mp_int* a, mp_int* b, mp_int* c, mp_int* d)
+{
+  int     res;
+  mp_int  t;
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_sub (a, b, &t)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+  res = mp_mod (&t, c, d);
+  mp_clear (&t);
+
+  return res;
+}
+
+
+#endif /* HAVE_COMP_KEY */
+
+#endif /* HAVE_ECC */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/error.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/error.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/error.c	(revision 164)
@@ -0,0 +1,352 @@
+/* error.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+#ifdef _MSC_VER
+    /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
+    #pragma warning(disable: 4996)
+#endif
+
+const char* wc_GetErrorString(int error)
+{
+#ifdef NO_ERROR_STRINGS
+
+    (void)error;
+    return "no support for error strings built in";
+
+#else
+
+    switch (error) {
+
+    case OPEN_RAN_E :
+        return "opening random device error";
+
+    case READ_RAN_E :
+        return "reading random device error";
+
+    case WINCRYPT_E :
+        return "windows crypt init error";
+
+    case CRYPTGEN_E :
+        return "windows crypt generation error";
+
+    case RAN_BLOCK_E :
+        return "random device read would block error";
+
+    case BAD_MUTEX_E :
+        return "Bad mutex, operation failed";
+
+    case MP_INIT_E :
+        return "mp_init error state";
+
+    case MP_READ_E :
+        return "mp_read error state";
+
+    case MP_EXPTMOD_E :
+        return "mp_exptmod error state";
+
+    case MP_TO_E :
+        return "mp_to_xxx error state, can't convert";
+
+    case MP_SUB_E :
+        return "mp_sub error state, can't subtract";
+
+    case MP_ADD_E :
+        return "mp_add error state, can't add";
+
+    case MP_MUL_E :
+        return "mp_mul error state, can't multiply";
+
+    case MP_MULMOD_E :
+        return "mp_mulmod error state, can't multiply mod";
+
+    case MP_MOD_E :
+        return "mp_mod error state, can't mod";
+
+    case MP_INVMOD_E :
+        return "mp_invmod error state, can't inv mod";
+
+    case MP_CMP_E :
+        return "mp_cmp error state";
+
+    case MP_ZERO_E :
+        return "mp zero result, not expected";
+
+    case MEMORY_E :
+        return "out of memory error";
+
+    case RSA_WRONG_TYPE_E :
+        return "RSA wrong block type for RSA function";
+
+    case RSA_BUFFER_E :
+        return "RSA buffer error, output too small or input too big";
+
+    case BUFFER_E :
+        return "Buffer error, output too small or input too big";
+
+    case ALGO_ID_E :
+        return "Setting Cert AlogID error";
+
+    case PUBLIC_KEY_E :
+        return "Setting Cert Public Key error";
+
+    case DATE_E :
+        return "Setting Cert Date validity error";
+
+    case SUBJECT_E :
+        return "Setting Cert Subject name error";
+
+    case ISSUER_E :
+        return "Setting Cert Issuer name error";
+
+    case CA_TRUE_E :
+        return "Setting basic constraint CA true error";
+
+    case EXTENSIONS_E :
+        return "Setting extensions error";
+
+    case ASN_PARSE_E :
+        return "ASN parsing error, invalid input";
+
+    case ASN_VERSION_E :
+        return "ASN version error, invalid number";
+
+    case ASN_GETINT_E :
+        return "ASN get big int error, invalid data";
+
+    case ASN_RSA_KEY_E :
+        return "ASN key init error, invalid input";
+
+    case ASN_OBJECT_ID_E :
+        return "ASN object id error, invalid id";
+
+    case ASN_TAG_NULL_E :
+        return "ASN tag error, not null";
+
+    case ASN_EXPECT_0_E :
+        return "ASN expect error, not zero";
+
+    case ASN_BITSTR_E :
+        return "ASN bit string error, wrong id";
+
+    case ASN_UNKNOWN_OID_E :
+        return "ASN oid error, unknown sum id";
+
+    case ASN_DATE_SZ_E :
+        return "ASN date error, bad size";
+
+    case ASN_BEFORE_DATE_E :
+        return "ASN date error, current date before";
+
+    case ASN_AFTER_DATE_E :
+        return "ASN date error, current date after";
+
+    case ASN_SIG_OID_E :
+        return "ASN signature error, mismatched oid";
+
+    case ASN_TIME_E :
+        return "ASN time error, unkown time type";
+
+    case ASN_INPUT_E :
+        return "ASN input error, not enough data";
+
+    case ASN_SIG_CONFIRM_E :
+        return "ASN sig error, confirm failure";
+
+    case ASN_SIG_HASH_E :
+        return "ASN sig error, unsupported hash type";
+
+    case ASN_SIG_KEY_E :
+        return "ASN sig error, unsupported key type";
+
+    case ASN_DH_KEY_E :
+        return "ASN key init error, invalid input";
+
+    case ASN_NTRU_KEY_E :
+        return "ASN NTRU key decode error, invalid input";
+
+    case ASN_CRIT_EXT_E:
+        return "X.509 Critical extension ignored";
+
+    case ECC_BAD_ARG_E :
+        return "ECC input argument wrong type, invalid input";
+
+    case ASN_ECC_KEY_E :
+        return "ECC ASN1 bad key data, invalid input";
+
+    case ECC_CURVE_OID_E :
+        return "ECC curve sum OID unsupported, invalid input";
+
+    case BAD_FUNC_ARG :
+        return "Bad function argument";
+
+    case NOT_COMPILED_IN :
+        return "Feature not compiled in";
+
+    case UNICODE_SIZE_E :
+        return "Unicode password too big";
+
+    case NO_PASSWORD :
+        return "No password provided by user";
+
+    case ALT_NAME_E :
+        return "Alt Name problem, too big";
+
+    case AES_GCM_AUTH_E:
+        return "AES-GCM Authentication check fail";
+
+    case AES_CCM_AUTH_E:
+        return "AES-CCM Authentication check fail";
+
+    case CAVIUM_INIT_E:
+        return "Cavium Init type error";
+
+    case COMPRESS_INIT_E:
+        return "Compress Init error";
+
+    case COMPRESS_E:
+        return "Compress error";
+
+    case DECOMPRESS_INIT_E:
+        return "DeCompress Init error";
+
+    case DECOMPRESS_E:
+        return "DeCompress error";
+
+    case BAD_ALIGN_E:
+        return "Bad alignment error, no alloc help";
+
+    case ASN_NO_SIGNER_E :
+        return "ASN no signer error to confirm failure";
+
+    case ASN_CRL_CONFIRM_E :
+        return "ASN CRL sig error, confirm failure";
+
+    case ASN_CRL_NO_SIGNER_E :
+        return "ASN CRL no signer error to confirm failure";
+
+    case ASN_OCSP_CONFIRM_E :
+        return "ASN OCSP sig error, confirm failure";
+
+    case BAD_ENC_STATE_E:
+        return "Bad ecc encrypt state operation";
+
+    case BAD_PADDING_E:
+        return "Bad padding, message wrong length";
+
+    case REQ_ATTRIBUTE_E:
+        return "Setting cert request attributes error";
+
+    case PKCS7_OID_E:
+        return "PKCS#7 error: mismatched OID value";
+
+    case PKCS7_RECIP_E:
+        return "PKCS#7 error: no matching recipient found";
+
+    case FIPS_NOT_ALLOWED_E:
+        return "FIPS mode not allowed error";
+
+    case ASN_NAME_INVALID_E:
+        return "Name Constraint error";
+
+    case RNG_FAILURE_E:
+        return "Random Number Generator failed";
+
+    case HMAC_MIN_KEYLEN_E:
+        return "FIPS Mode HMAC Minimum Key Length error";
+
+    case RSA_PAD_E:
+        return "Rsa Padding error";
+
+    case LENGTH_ONLY_E:
+        return "Output length only set, not for other use error";
+
+    case IN_CORE_FIPS_E:
+        return "In Core Integrity check FIPS error";
+
+    case AES_KAT_FIPS_E:
+        return "AES Known Answer Test check FIPS error";
+
+    case DES3_KAT_FIPS_E:
+        return "DES3 Known Answer Test check FIPS error";
+
+    case HMAC_KAT_FIPS_E:
+        return "HMAC Known Answer Test check FIPS error";
+
+    case RSA_KAT_FIPS_E:
+        return "RSA Known Answer Test check FIPS error";
+
+    case DRBG_KAT_FIPS_E:
+        return "DRBG Known Answer Test check FIPS error";
+
+    case DRBG_CONT_FIPS_E:
+        return "DRBG Continuous Test FIPS error";
+
+    case AESGCM_KAT_FIPS_E:
+        return "AESGCM Known Answer Test check FIPS error";
+
+    case THREAD_STORE_KEY_E:
+        return "Thread Storage Key Create error";
+
+    case THREAD_STORE_SET_E:
+        return "Thread Storage Set error";
+
+    case MAC_CMP_FAILED_E:
+        return "MAC comparison failed";
+
+    case IS_POINT_E:
+        return "ECC is point on curve failed";
+
+    case ECC_INF_E:
+        return " ECC point at infinity error";
+
+    case ECC_PRIV_KEY_E:
+        return " ECC private key is not valid error";
+
+    case SRP_CALL_ORDER_E:
+        return "SRP function called in the wrong order error";
+
+    case SRP_VERIFY_E:
+        return "SRP proof verification error";
+
+    case SRP_BAD_KEY_E:
+        return "SRP bad key values error";
+
+    default:
+        return "unknown error number";
+
+    }
+
+#endif /* NO_ERROR_STRINGS */
+
+}
+
+void wc_ErrorString(int error, char* buffer)
+{
+    XSTRNCPY(buffer, wc_GetErrorString(error), WOLFSSL_MAX_ERROR_SZ);
+}
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/hash.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/hash.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/hash.c	(revision 164)
@@ -0,0 +1,212 @@
+/* hash.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+#include <wolfssl/wolfcrypt/logging.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+#if !defined(WOLFSSL_TI_HASH)
+
+#include <wolfssl/wolfcrypt/hash.h>
+
+#if !defined(NO_MD5)
+void wc_Md5GetHash(Md5* md5, byte* hash)
+{
+    Md5 save = *md5 ;
+    wc_Md5Final(md5, hash) ;
+    *md5 = save ;
+}
+
+WOLFSSL_API void wc_Md5RestorePos(Md5* m1, Md5* m2) {
+    *m1 = *m2 ;
+}
+
+#endif
+
+#if !defined(NO_SHA)
+int wc_ShaGetHash(Sha* sha, byte* hash)
+{
+    int ret ;
+    Sha save = *sha ;
+    ret = wc_ShaFinal(sha, hash) ;
+    *sha = save ;
+    return ret ;
+}
+
+WOLFSSL_API void wc_ShaRestorePos(Sha* s1, Sha* s2) {
+    *s1 = *s2 ;
+}
+
+int wc_ShaHash(const byte* data, word32 len, byte* hash)
+{
+    int ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    Sha* sha;
+#else
+    Sha sha[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (sha == NULL)
+        return MEMORY_E;
+#endif
+
+    if ((ret = wc_InitSha(sha)) != 0) {
+        WOLFSSL_MSG("wc_InitSha failed");
+    }
+    else {
+        wc_ShaUpdate(sha, data, len);
+        wc_ShaFinal(sha, hash);
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+
+}
+
+#endif /* !defined(NO_SHA) */
+
+#if !defined(NO_SHA256)
+int wc_Sha256GetHash(Sha256* sha256, byte* hash)
+{
+    int ret ;
+    Sha256 save = *sha256 ;
+    ret = wc_Sha256Final(sha256, hash) ;
+    *sha256 = save ;
+    return ret ;
+}
+
+WOLFSSL_API void wc_Sha256RestorePos(Sha256* s1, Sha256* s2) {
+    *s1 = *s2 ;
+}
+
+int wc_Sha256Hash(const byte* data, word32 len, byte* hash)
+{
+    int ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    Sha256* sha256;
+#else
+    Sha256 sha256[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (sha256 == NULL)
+        return MEMORY_E;
+#endif
+
+    if ((ret = wc_InitSha256(sha256)) != 0) {
+        WOLFSSL_MSG("InitSha256 failed");
+    }
+    else if ((ret = wc_Sha256Update(sha256, data, len)) != 0) {
+        WOLFSSL_MSG("Sha256Update failed");
+    }
+    else if ((ret = wc_Sha256Final(sha256, hash)) != 0) {
+        WOLFSSL_MSG("Sha256Final failed");
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+#endif /* !defined(NO_SHA256) */
+
+#endif /* !defined(WOLFSSL_TI_HASH) */
+
+#if defined(WOLFSSL_SHA512)
+int wc_Sha512Hash(const byte* data, word32 len, byte* hash)
+{
+    int ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    Sha512* sha512;
+#else
+    Sha512 sha512[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (sha512 == NULL)
+        return MEMORY_E;
+#endif
+
+    if ((ret = wc_InitSha512(sha512)) != 0) {
+        WOLFSSL_MSG("InitSha512 failed");
+    }
+    else if ((ret = wc_Sha512Update(sha512, data, len)) != 0) {
+        WOLFSSL_MSG("Sha512Update failed");
+    }
+    else if ((ret = wc_Sha512Final(sha512, hash)) != 0) {
+        WOLFSSL_MSG("Sha512Final failed");
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sha512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+#if defined(WOLFSSL_SHA384)
+int wc_Sha384Hash(const byte* data, word32 len, byte* hash)
+{
+    int ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    Sha384* sha384;
+#else
+    Sha384 sha384[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (sha384 == NULL)
+        return MEMORY_E;
+#endif
+
+    if ((ret = wc_InitSha384(sha384)) != 0) {
+        WOLFSSL_MSG("InitSha384 failed");
+    }
+    else if ((ret = wc_Sha384Update(sha384, data, len)) != 0) {
+        WOLFSSL_MSG("Sha384Update failed");
+    }
+    else if ((ret = wc_Sha384Final(sha384, hash)) != 0) {
+        WOLFSSL_MSG("Sha384Final failed");
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+#endif /* defined(WOLFSSL_SHA384) */
+#endif /* defined(WOLFSSL_SHA512) */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/hc128.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/hc128.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/hc128.c	(revision 164)
@@ -0,0 +1,399 @@
+/* hc128.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef HAVE_HC128
+
+#include <wolfssl/wolfcrypt/hc128.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/hc128.h>
+		#include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+
+#ifdef BIG_ENDIAN_ORDER
+    #define LITTLE32(x) ByteReverseWord32(x)
+#else
+    #define LITTLE32(x) (x)
+#endif
+
+
+/*h1 function*/
+#define h1(ctx, x, y) {                         \
+     byte a,c;                                  \
+     a = (byte) (x);                            \
+     c = (byte) ((x) >> 16);                    \
+     y = (ctx->T[512+a])+(ctx->T[512+256+c]);   \
+}
+
+/*h2 function*/
+#define h2(ctx, x, y) {                         \
+     byte a,c;                                  \
+     a = (byte) (x);                            \
+     c = (byte) ((x) >> 16);                    \
+     y = (ctx->T[a])+(ctx->T[256+c]);           \
+}
+
+/*one step of HC-128, update P and generate 32 bits keystream*/
+#define step_P(ctx,u,v,a,b,c,d,n){              \
+     word32 tem0,tem1,tem2,tem3;                \
+     h1((ctx),(ctx->X[(d)]),tem3);              \
+     tem0 = rotrFixed((ctx->T[(v)]),23);        \
+     tem1 = rotrFixed((ctx->X[(c)]),10);        \
+     tem2 = rotrFixed((ctx->X[(b)]),8);         \
+     (ctx->T[(u)]) += tem2+(tem0 ^ tem1);       \
+     (ctx->X[(a)]) = (ctx->T[(u)]);             \
+     (n) = tem3 ^ (ctx->T[(u)]) ;               \
+}       
+
+/*one step of HC-128, update Q and generate 32 bits keystream*/
+#define step_Q(ctx,u,v,a,b,c,d,n){              \
+     word32 tem0,tem1,tem2,tem3;                \
+     h2((ctx),(ctx->Y[(d)]),tem3);              \
+     tem0 = rotrFixed((ctx->T[(v)]),(32-23));   \
+     tem1 = rotrFixed((ctx->Y[(c)]),(32-10));   \
+     tem2 = rotrFixed((ctx->Y[(b)]),(32-8));    \
+     (ctx->T[(u)]) += tem2 + (tem0 ^ tem1);     \
+     (ctx->Y[(a)]) = (ctx->T[(u)]);             \
+     (n) = tem3 ^ (ctx->T[(u)]) ;               \
+}   
+
+/*16 steps of HC-128, generate 512 bits keystream*/
+static void generate_keystream(HC128* ctx, word32* keystream)  
+{
+   word32 cc,dd;
+   cc = ctx->counter1024 & 0x1ff;
+   dd = (cc+16)&0x1ff;
+
+   if (ctx->counter1024 < 512)	
+   {   		
+      ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;
+      step_P(ctx, cc+0, cc+1, 0, 6, 13,4, keystream[0]);
+      step_P(ctx, cc+1, cc+2, 1, 7, 14,5, keystream[1]);
+      step_P(ctx, cc+2, cc+3, 2, 8, 15,6, keystream[2]);
+      step_P(ctx, cc+3, cc+4, 3, 9, 0, 7, keystream[3]);
+      step_P(ctx, cc+4, cc+5, 4, 10,1, 8, keystream[4]);
+      step_P(ctx, cc+5, cc+6, 5, 11,2, 9, keystream[5]);
+      step_P(ctx, cc+6, cc+7, 6, 12,3, 10,keystream[6]);
+      step_P(ctx, cc+7, cc+8, 7, 13,4, 11,keystream[7]);
+      step_P(ctx, cc+8, cc+9, 8, 14,5, 12,keystream[8]);
+      step_P(ctx, cc+9, cc+10,9, 15,6, 13,keystream[9]);
+      step_P(ctx, cc+10,cc+11,10,0, 7, 14,keystream[10]);
+      step_P(ctx, cc+11,cc+12,11,1, 8, 15,keystream[11]);
+      step_P(ctx, cc+12,cc+13,12,2, 9, 0, keystream[12]);
+      step_P(ctx, cc+13,cc+14,13,3, 10,1, keystream[13]);
+      step_P(ctx, cc+14,cc+15,14,4, 11,2, keystream[14]);
+      step_P(ctx, cc+15,dd+0, 15,5, 12,3, keystream[15]);
+   }
+   else				    
+   {
+	  ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;
+      step_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13,4, keystream[0]);
+      step_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14,5, keystream[1]);
+      step_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15,6, keystream[2]);
+      step_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0, 7, keystream[3]);
+      step_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1, 8, keystream[4]);
+      step_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2, 9, keystream[5]);
+      step_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3, 10,keystream[6]);
+      step_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4, 11,keystream[7]);
+      step_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5, 12,keystream[8]);
+      step_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6, 13,keystream[9]);
+      step_Q(ctx, 512+cc+10,512+cc+11,10,0, 7, 14,keystream[10]);
+      step_Q(ctx, 512+cc+11,512+cc+12,11,1, 8, 15,keystream[11]);
+      step_Q(ctx, 512+cc+12,512+cc+13,12,2, 9, 0, keystream[12]);
+      step_Q(ctx, 512+cc+13,512+cc+14,13,3, 10,1, keystream[13]);
+      step_Q(ctx, 512+cc+14,512+cc+15,14,4, 11,2, keystream[14]);
+      step_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12,3, keystream[15]);
+   }
+}
+
+
+/* The following defines the initialization functions */
+#define f1(x)  (rotrFixed((x),7)  ^ rotrFixed((x),18) ^ ((x) >> 3))
+#define f2(x)  (rotrFixed((x),17) ^ rotrFixed((x),19) ^ ((x) >> 10))
+
+/*update table P*/
+#define update_P(ctx,u,v,a,b,c,d){                  \
+     word32 tem0,tem1,tem2,tem3;                    \
+     tem0 = rotrFixed((ctx->T[(v)]),23);            \
+     tem1 = rotrFixed((ctx->X[(c)]),10);            \
+     tem2 = rotrFixed((ctx->X[(b)]),8);             \
+     h1((ctx),(ctx->X[(d)]),tem3);                  \
+     (ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3;     \
+     (ctx->X[(a)]) = (ctx->T[(u)]);                 \
+}  
+
+/*update table Q*/
+#define update_Q(ctx,u,v,a,b,c,d){                  \
+     word32 tem0,tem1,tem2,tem3;                    \
+     tem0 = rotrFixed((ctx->T[(v)]),(32-23));       \
+     tem1 = rotrFixed((ctx->Y[(c)]),(32-10));       \
+     tem2 = rotrFixed((ctx->Y[(b)]),(32-8));        \
+     h2((ctx),(ctx->Y[(d)]),tem3);                  \
+     (ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3;     \
+     (ctx->Y[(a)]) = (ctx->T[(u)]);                 \
+}     
+
+/*16 steps of HC-128, without generating keystream, */
+/*but use the outputs to update P and Q*/
+static void setup_update(HC128* ctx)  /*each time 16 steps*/
+{
+   word32 cc,dd;
+   cc = ctx->counter1024 & 0x1ff;
+   dd = (cc+16)&0x1ff;
+
+   if (ctx->counter1024 < 512)	
+   {   		
+      ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;
+      update_P(ctx, cc+0, cc+1, 0, 6, 13, 4);
+      update_P(ctx, cc+1, cc+2, 1, 7, 14, 5);
+      update_P(ctx, cc+2, cc+3, 2, 8, 15, 6);
+      update_P(ctx, cc+3, cc+4, 3, 9, 0,  7);
+      update_P(ctx, cc+4, cc+5, 4, 10,1,  8);
+      update_P(ctx, cc+5, cc+6, 5, 11,2,  9);
+      update_P(ctx, cc+6, cc+7, 6, 12,3,  10);
+      update_P(ctx, cc+7, cc+8, 7, 13,4,  11);
+      update_P(ctx, cc+8, cc+9, 8, 14,5,  12);
+      update_P(ctx, cc+9, cc+10,9, 15,6,  13);
+      update_P(ctx, cc+10,cc+11,10,0, 7,  14);
+      update_P(ctx, cc+11,cc+12,11,1, 8,  15);
+      update_P(ctx, cc+12,cc+13,12,2, 9,  0);
+      update_P(ctx, cc+13,cc+14,13,3, 10, 1);
+      update_P(ctx, cc+14,cc+15,14,4, 11, 2);
+      update_P(ctx, cc+15,dd+0, 15,5, 12, 3);   
+   }
+   else				    
+   {
+      ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;
+      update_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13, 4);
+      update_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14, 5);
+      update_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15, 6);
+      update_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0,  7);
+      update_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1,  8);
+      update_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2,  9);
+      update_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3,  10);
+      update_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4,  11);
+      update_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5,  12);
+      update_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6,  13);
+      update_Q(ctx, 512+cc+10,512+cc+11,10,0, 7,  14);
+      update_Q(ctx, 512+cc+11,512+cc+12,11,1, 8,  15);
+      update_Q(ctx, 512+cc+12,512+cc+13,12,2, 9,  0);
+      update_Q(ctx, 512+cc+13,512+cc+14,13,3, 10, 1);
+      update_Q(ctx, 512+cc+14,512+cc+15,14,4, 11, 2);
+      update_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12, 3); 
+   }       
+}
+
+
+/* for the 128-bit key:  key[0]...key[15]
+*  key[0] is the least significant byte of ctx->key[0] (K_0);
+*  key[3] is the most significant byte of ctx->key[0]  (K_0);
+*  ...
+*  key[12] is the least significant byte of ctx->key[3] (K_3)
+*  key[15] is the most significant byte of ctx->key[3]  (K_3)
+*
+*  for the 128-bit iv:  iv[0]...iv[15]
+*  iv[0] is the least significant byte of ctx->iv[0] (IV_0);
+*  iv[3] is the most significant byte of ctx->iv[0]  (IV_0);
+*  ...
+*  iv[12] is the least significant byte of ctx->iv[3] (IV_3)
+*  iv[15] is the most significant byte of ctx->iv[3]  (IV_3)
+*/
+
+
+
+static void Hc128_SetIV(HC128* ctx, const byte* inIv)
+{ 
+    word32 i;
+    word32 iv[4];
+
+    if (inIv)
+        XMEMCPY(iv, inIv, sizeof(iv));
+    else
+        XMEMSET(iv,    0, sizeof(iv));
+    
+	for (i = 0; i < (128 >> 5); i++)
+        ctx->iv[i] = LITTLE32(iv[i]);
+	
+    for (; i < 8; i++) ctx->iv[i] = ctx->iv[i-4];
+  
+    /* expand the key and IV into the table T */ 
+    /* (expand the key and IV into the table P and Q) */ 
+	
+	for (i = 0; i < 8;  i++)   ctx->T[i] = ctx->key[i];
+	for (i = 8; i < 16; i++)   ctx->T[i] = ctx->iv[i-8];
+
+    for (i = 16; i < (256+16); i++) 
+		ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) +
+                                                       ctx->T[i-16]+i;
+    
+	for (i = 0; i < 16;  i++)  ctx->T[i] = ctx->T[256+i];
+
+	for (i = 16; i < 1024; i++) 
+		ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) +
+                                                       ctx->T[i-16]+256+i;
+    
+    /* initialize counter1024, X and Y */
+	ctx->counter1024 = 0;
+	for (i = 0; i < 16; i++) ctx->X[i] = ctx->T[512-16+i];
+    for (i = 0; i < 16; i++) ctx->Y[i] = ctx->T[512+512-16+i];
+    
+    /* run the cipher 1024 steps before generating the output */
+	for (i = 0; i < 64; i++)  setup_update(ctx);  
+}
+
+
+static INLINE int DoKey(HC128* ctx, const byte* key, const byte* iv)
+{ 
+  word32 i;  
+
+  /* Key size in bits 128 */ 
+  for (i = 0; i < (128 >> 5); i++)
+      ctx->key[i] = LITTLE32(((word32*)key)[i]);
+ 
+  for ( ; i < 8 ; i++) ctx->key[i] = ctx->key[i-4];
+
+  Hc128_SetIV(ctx, iv);
+
+  return 0;
+}
+
+
+/* Key setup */
+int wc_Hc128_SetKey(HC128* ctx, const byte* key, const byte* iv)
+{
+#ifdef XSTREAM_ALIGN
+    if ((wolfssl_word)key % 4) {
+        int alignKey[4];
+
+        /* iv gets aligned in SetIV */
+        WOLFSSL_MSG("Hc128SetKey unaligned key");
+
+        XMEMCPY(alignKey, key, sizeof(alignKey));
+
+        return DoKey(ctx, (const byte*)alignKey, iv);
+    }
+#endif /* XSTREAM_ALIGN */
+
+    return DoKey(ctx, key, iv);
+}
+
+
+
+/* The following defines the encryption of data stream */
+static INLINE int DoProcess(HC128* ctx, byte* output, const byte* input,
+                            word32 msglen)
+{
+  word32 i, keystream[16];
+
+  for ( ; msglen >= 64; msglen -= 64, input += 64, output += 64)
+  {
+	  generate_keystream(ctx, keystream);
+
+      /* unroll loop */
+	  ((word32*)output)[0]  = ((word32*)input)[0]  ^ LITTLE32(keystream[0]);
+	  ((word32*)output)[1]  = ((word32*)input)[1]  ^ LITTLE32(keystream[1]);
+	  ((word32*)output)[2]  = ((word32*)input)[2]  ^ LITTLE32(keystream[2]);
+	  ((word32*)output)[3]  = ((word32*)input)[3]  ^ LITTLE32(keystream[3]);
+	  ((word32*)output)[4]  = ((word32*)input)[4]  ^ LITTLE32(keystream[4]);
+	  ((word32*)output)[5]  = ((word32*)input)[5]  ^ LITTLE32(keystream[5]);
+	  ((word32*)output)[6]  = ((word32*)input)[6]  ^ LITTLE32(keystream[6]);
+	  ((word32*)output)[7]  = ((word32*)input)[7]  ^ LITTLE32(keystream[7]);
+	  ((word32*)output)[8]  = ((word32*)input)[8]  ^ LITTLE32(keystream[8]);
+	  ((word32*)output)[9]  = ((word32*)input)[9]  ^ LITTLE32(keystream[9]);
+	  ((word32*)output)[10] = ((word32*)input)[10] ^ LITTLE32(keystream[10]);
+	  ((word32*)output)[11] = ((word32*)input)[11] ^ LITTLE32(keystream[11]);
+	  ((word32*)output)[12] = ((word32*)input)[12] ^ LITTLE32(keystream[12]);
+	  ((word32*)output)[13] = ((word32*)input)[13] ^ LITTLE32(keystream[13]);
+	  ((word32*)output)[14] = ((word32*)input)[14] ^ LITTLE32(keystream[14]);
+	  ((word32*)output)[15] = ((word32*)input)[15] ^ LITTLE32(keystream[15]);
+  }
+
+  if (msglen > 0)
+  {
+      XMEMSET(keystream, 0, sizeof(keystream)); /* hush the static analysis */
+      generate_keystream(ctx, keystream);
+
+#ifdef BIG_ENDIAN_ORDER
+      {
+          word32 wordsLeft = msglen / sizeof(word32);
+          if (msglen % sizeof(word32)) wordsLeft++;
+          
+          ByteReverseWords(keystream, keystream, wordsLeft * sizeof(word32));
+      }
+#endif
+
+      for (i = 0; i < msglen; i++)
+	      output[i] = input[i] ^ ((byte*)keystream)[i];
+  }
+
+  return 0;
+}
+
+
+/* Encrypt/decrypt a message of any size */
+int wc_Hc128_Process(HC128* ctx, byte* output, const byte* input, word32 msglen)
+{
+#ifdef XSTREAM_ALIGN
+    if ((wolfssl_word)input % 4 || (wolfssl_word)output % 4) {
+        #ifndef NO_WOLFSSL_ALLOC_ALIGN
+            byte* tmp;
+            WOLFSSL_MSG("Hc128Process unaligned");
+
+            tmp = (byte*)XMALLOC(msglen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            if (tmp == NULL) return MEMORY_E;
+
+            XMEMCPY(tmp, input, msglen);
+            DoProcess(ctx, tmp, tmp, msglen);
+            XMEMCPY(output, tmp, msglen);
+
+            XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+            return 0;
+        #else
+            return BAD_ALIGN_E;
+        #endif
+    }
+#endif /* XSTREAM_ALIGN */
+
+    return DoProcess(ctx, output, input, msglen);
+}
+
+
+#else  /* HAVE_HC128 */
+
+
+#ifdef _MSC_VER
+    /* 4206 warning for blank file */
+    #pragma warning(disable: 4206)
+#endif
+
+
+#endif /* HAVE_HC128 */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/hmac.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/hmac.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/hmac.c	(revision 164)
@@ -0,0 +1,874 @@
+/* hmac.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_HMAC
+
+#include <wolfssl/wolfcrypt/hmac.h>
+
+#ifdef HAVE_FIPS
+/* does init */
+int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 keySz)
+{
+    return HmacSetKey_fips(hmac, type, key, keySz);
+}
+
+
+int wc_HmacUpdate(Hmac* hmac, const byte* in, word32 sz)
+{
+    return HmacUpdate_fips(hmac, in, sz);
+}
+
+
+int wc_HmacFinal(Hmac* hmac, byte* out)
+{
+    return HmacFinal_fips(hmac, out);
+}
+
+
+#ifdef HAVE_CAVIUM
+    int  wc_HmacInitCavium(Hmac* hmac, int i)
+    {
+        return HmacInitCavium(hmac, i);
+    }
+
+
+    void wc_HmacFreeCavium(Hmac* hmac)
+    {
+        HmacFreeCavium(hmac);
+    }
+#endif
+
+int wolfSSL_GetHmacMaxSize(void)
+{
+    return CyaSSL_GetHmacMaxSize();
+}
+
+#ifdef HAVE_HKDF
+
+int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
+                    const byte* salt, word32 saltSz,
+                    const byte* info, word32 infoSz,
+                    byte* out, word32 outSz)
+{
+    return HKDF(type, inKey, inKeySz, salt, saltSz, info, infoSz, out, outSz);
+}
+
+
+#endif /* HAVE_HKDF */
+#else /* else build without fips */
+#ifdef WOLFSSL_PIC32MZ_HASH
+
+#define wc_InitMd5   wc_InitMd5_sw
+#define wc_Md5Update wc_Md5Update_sw
+#define wc_Md5Final  wc_Md5Final_sw
+
+#define wc_InitSha   wc_InitSha_sw
+#define wc_ShaUpdate wc_ShaUpdate_sw
+#define wc_ShaFinal  wc_ShaFinal_sw
+
+#define wc_InitSha256   wc_InitSha256_sw
+#define wc_Sha256Update wc_Sha256Update_sw
+#define wc_Sha256Final  wc_Sha256Final_sw
+
+#endif
+
+#ifdef HAVE_FIPS
+    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
+    #define FIPS_NO_WRAPPERS
+#endif
+
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+
+#ifdef HAVE_CAVIUM
+    static void HmacCaviumFinal(Hmac* hmac, byte* hash);
+    static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length);
+    static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key,
+                                 word32 length);
+#endif
+
+static int InitHmac(Hmac* hmac, int type)
+{
+    int ret = 0;
+
+    hmac->innerHashKeyed = 0;
+    hmac->macType = (byte)type;
+
+    if (!(type == MD5 || type == SHA    || type == SHA256 || type == SHA384
+                      || type == SHA512 || type == BLAKE2B_ID))
+        return BAD_FUNC_ARG;
+
+    switch (type) {
+        #ifndef NO_MD5
+        case MD5:
+            wc_InitMd5(&hmac->hash.md5);
+        break;
+        #endif
+
+        #ifndef NO_SHA
+        case SHA:
+            ret = wc_InitSha(&hmac->hash.sha);
+        break;
+        #endif
+
+        #ifndef NO_SHA256
+        case SHA256:
+            ret = wc_InitSha256(&hmac->hash.sha256);
+        break;
+        #endif
+
+        #ifdef WOLFSSL_SHA384
+        case SHA384:
+            ret = wc_InitSha384(&hmac->hash.sha384);
+        break;
+        #endif
+
+        #ifdef WOLFSSL_SHA512
+        case SHA512:
+            ret = wc_InitSha512(&hmac->hash.sha512);
+        break;
+        #endif
+
+        #ifdef HAVE_BLAKE2
+        case BLAKE2B_ID:
+            ret = wc_InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256);
+        break;
+        #endif
+
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    return ret;
+}
+
+
+int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
+{
+    byte*  ip = (byte*) hmac->ipad;
+    byte*  op = (byte*) hmac->opad;
+    word32 i, hmac_block_size = 0;
+    int    ret;
+
+#ifdef HAVE_CAVIUM
+    if (hmac->magic == WOLFSSL_HMAC_CAVIUM_MAGIC)
+        return HmacCaviumSetKey(hmac, type, key, length);
+#endif
+
+    ret = InitHmac(hmac, type);
+    if (ret != 0)
+        return ret;
+
+#ifdef HAVE_FIPS
+    if (length < HMAC_FIPS_MIN_KEY)
+        return HMAC_MIN_KEYLEN_E;
+#endif
+
+    switch (hmac->macType) {
+        #ifndef NO_MD5
+        case MD5:
+        {
+            hmac_block_size = MD5_BLOCK_SIZE;
+            if (length <= MD5_BLOCK_SIZE) {
+                XMEMCPY(ip, key, length);
+            }
+            else {
+                wc_Md5Update(&hmac->hash.md5, key, length);
+                wc_Md5Final(&hmac->hash.md5, ip);
+                length = MD5_DIGEST_SIZE;
+            }
+        }
+        break;
+        #endif
+
+        #ifndef NO_SHA
+        case SHA:
+        {
+            hmac_block_size = SHA_BLOCK_SIZE;
+            if (length <= SHA_BLOCK_SIZE) {
+                XMEMCPY(ip, key, length);
+            }
+            else {
+                wc_ShaUpdate(&hmac->hash.sha, key, length);
+                wc_ShaFinal(&hmac->hash.sha, ip);
+                length = SHA_DIGEST_SIZE;
+            }
+        }
+        break;
+        #endif
+
+        #ifndef NO_SHA256
+        case SHA256:
+        {
+    		hmac_block_size = SHA256_BLOCK_SIZE;
+            if (length <= SHA256_BLOCK_SIZE) {
+                XMEMCPY(ip, key, length);
+            }
+            else {
+                ret = wc_Sha256Update(&hmac->hash.sha256, key, length);
+                if (ret != 0)
+                    return ret;
+
+                ret = wc_Sha256Final(&hmac->hash.sha256, ip);
+                if (ret != 0)
+                    return ret;
+
+                length = SHA256_DIGEST_SIZE;
+            }
+        }
+        break;
+        #endif
+
+        #ifdef WOLFSSL_SHA384
+        case SHA384:
+        {
+            hmac_block_size = SHA384_BLOCK_SIZE;
+            if (length <= SHA384_BLOCK_SIZE) {
+                XMEMCPY(ip, key, length);
+            }
+            else {
+                ret = wc_Sha384Update(&hmac->hash.sha384, key, length);
+                if (ret != 0)
+                    return ret;
+
+                ret = wc_Sha384Final(&hmac->hash.sha384, ip);
+                if (ret != 0)
+                    return ret;
+
+                length = SHA384_DIGEST_SIZE;
+            }
+        }
+        break;
+        #endif
+
+        #ifdef WOLFSSL_SHA512
+        case SHA512:
+        {
+            hmac_block_size = SHA512_BLOCK_SIZE;
+            if (length <= SHA512_BLOCK_SIZE) {
+                XMEMCPY(ip, key, length);
+            }
+            else {
+                ret = wc_Sha512Update(&hmac->hash.sha512, key, length);
+                if (ret != 0)
+                    return ret;
+
+                ret = wc_Sha512Final(&hmac->hash.sha512, ip);
+                if (ret != 0)
+                    return ret;
+
+                length = SHA512_DIGEST_SIZE;
+            }
+        }
+        break;
+        #endif
+
+        #ifdef HAVE_BLAKE2
+        case BLAKE2B_ID:
+        {
+            hmac_block_size = BLAKE2B_BLOCKBYTES;
+            if (length <= BLAKE2B_BLOCKBYTES) {
+                XMEMCPY(ip, key, length);
+            }
+            else {
+                ret = wc_Blake2bUpdate(&hmac->hash.blake2b, key, length);
+                if (ret != 0)
+                    return ret;
+
+                ret = wc_Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256);
+                if (ret != 0)
+                    return ret;
+
+                length = BLAKE2B_256;
+            }
+        }
+        break;
+        #endif
+
+        default:
+            return BAD_FUNC_ARG;
+    }
+    if (length < hmac_block_size)
+        XMEMSET(ip + length, 0, hmac_block_size - length);
+
+    for(i = 0; i < hmac_block_size; i++) {
+        op[i] = ip[i] ^ OPAD;
+        ip[i] ^= IPAD;
+    }
+    return 0;
+}
+
+
+static int HmacKeyInnerHash(Hmac* hmac)
+{
+    int ret = 0;
+
+    switch (hmac->macType) {
+        #ifndef NO_MD5
+        case MD5:
+            wc_Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, MD5_BLOCK_SIZE);
+        break;
+        #endif
+
+        #ifndef NO_SHA
+        case SHA:
+            wc_ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, SHA_BLOCK_SIZE);
+        break;
+        #endif
+
+        #ifndef NO_SHA256
+        case SHA256:
+            ret = wc_Sha256Update(&hmac->hash.sha256,
+                                         (byte*) hmac->ipad, SHA256_BLOCK_SIZE);
+            if (ret != 0)
+                return ret;
+        break;
+        #endif
+
+        #ifdef WOLFSSL_SHA384
+        case SHA384:
+            ret = wc_Sha384Update(&hmac->hash.sha384,
+                                         (byte*) hmac->ipad, SHA384_BLOCK_SIZE);
+            if (ret != 0)
+                return ret;
+        break;
+        #endif
+
+        #ifdef WOLFSSL_SHA512
+        case SHA512:
+            ret = wc_Sha512Update(&hmac->hash.sha512,
+                                         (byte*) hmac->ipad, SHA512_BLOCK_SIZE);
+            if (ret != 0)
+                return ret;
+        break;
+        #endif
+
+        #ifdef HAVE_BLAKE2
+        case BLAKE2B_ID:
+            ret = wc_Blake2bUpdate(&hmac->hash.blake2b,
+                                         (byte*) hmac->ipad,BLAKE2B_BLOCKBYTES);
+            if (ret != 0)
+                return ret;
+        break;
+        #endif
+
+        default:
+        break;
+    }
+
+    hmac->innerHashKeyed = 1;
+
+    return ret;
+}
+
+
+int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length)
+{
+    int ret;
+
+#ifdef HAVE_CAVIUM
+    if (hmac->magic == WOLFSSL_HMAC_CAVIUM_MAGIC)
+        return HmacCaviumUpdate(hmac, msg, length);
+#endif
+
+    if (!hmac->innerHashKeyed) {
+        ret = HmacKeyInnerHash(hmac);
+        if (ret != 0)
+            return ret;
+    }
+
+    switch (hmac->macType) {
+        #ifndef NO_MD5
+        case MD5:
+            wc_Md5Update(&hmac->hash.md5, msg, length);
+        break;
+        #endif
+
+        #ifndef NO_SHA
+        case SHA:
+            wc_ShaUpdate(&hmac->hash.sha, msg, length);
+        break;
+        #endif
+
+        #ifndef NO_SHA256
+        case SHA256:
+            ret = wc_Sha256Update(&hmac->hash.sha256, msg, length);
+            if (ret != 0)
+                return ret;
+        break;
+        #endif
+
+        #ifdef WOLFSSL_SHA384
+        case SHA384:
+            ret = wc_Sha384Update(&hmac->hash.sha384, msg, length);
+            if (ret != 0)
+                return ret;
+        break;
+        #endif
+
+        #ifdef WOLFSSL_SHA512
+        case SHA512:
+            ret = wc_Sha512Update(&hmac->hash.sha512, msg, length);
+            if (ret != 0)
+                return ret;
+        break;
+        #endif
+
+        #ifdef HAVE_BLAKE2
+        case BLAKE2B_ID:
+            ret = wc_Blake2bUpdate(&hmac->hash.blake2b, msg, length);
+            if (ret != 0)
+                return ret;
+        break;
+        #endif
+
+        default:
+        break;
+    }
+
+    return 0;
+}
+
+
+int wc_HmacFinal(Hmac* hmac, byte* hash)
+{
+    int ret;
+
+#ifdef HAVE_CAVIUM
+    if (hmac->magic == WOLFSSL_HMAC_CAVIUM_MAGIC)
+        return HmacCaviumFinal(hmac, hash);
+#endif
+
+    if (!hmac->innerHashKeyed) {
+        ret = HmacKeyInnerHash(hmac);
+        if (ret != 0)
+            return ret;
+    }
+
+    switch (hmac->macType) {
+        #ifndef NO_MD5
+        case MD5:
+        {
+            wc_Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash);
+
+            wc_Md5Update(&hmac->hash.md5, (byte*) hmac->opad, MD5_BLOCK_SIZE);
+            wc_Md5Update(&hmac->hash.md5,
+                                     (byte*) hmac->innerHash, MD5_DIGEST_SIZE);
+
+            wc_Md5Final(&hmac->hash.md5, hash);
+        }
+        break;
+        #endif
+
+        #ifndef NO_SHA
+        case SHA:
+        {
+            wc_ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash);
+
+            wc_ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, SHA_BLOCK_SIZE);
+            wc_ShaUpdate(&hmac->hash.sha,
+                                     (byte*) hmac->innerHash, SHA_DIGEST_SIZE);
+
+            wc_ShaFinal(&hmac->hash.sha, hash);
+        }
+        break;
+        #endif
+
+        #ifndef NO_SHA256
+        case SHA256:
+        {
+            ret = wc_Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash);
+            if (ret != 0)
+                return ret;
+
+            ret = wc_Sha256Update(&hmac->hash.sha256,
+                                (byte*) hmac->opad, SHA256_BLOCK_SIZE);
+            if (ret != 0)
+                return ret;
+
+            ret = wc_Sha256Update(&hmac->hash.sha256,
+                                (byte*) hmac->innerHash, SHA256_DIGEST_SIZE);
+            if (ret != 0)
+                return ret;
+
+            ret = wc_Sha256Final(&hmac->hash.sha256, hash);
+            if (ret != 0)
+                return ret;
+        }
+        break;
+        #endif
+
+        #ifdef WOLFSSL_SHA384
+        case SHA384:
+        {
+            ret = wc_Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash);
+            if (ret != 0)
+                return ret;
+
+            ret = wc_Sha384Update(&hmac->hash.sha384,
+                                 (byte*) hmac->opad, SHA384_BLOCK_SIZE);
+            if (ret != 0)
+                return ret;
+
+            ret = wc_Sha384Update(&hmac->hash.sha384,
+                                 (byte*) hmac->innerHash, SHA384_DIGEST_SIZE);
+            if (ret != 0)
+                return ret;
+
+            ret = wc_Sha384Final(&hmac->hash.sha384, hash);
+            if (ret != 0)
+                return ret;
+        }
+        break;
+        #endif
+
+        #ifdef WOLFSSL_SHA512
+        case SHA512:
+        {
+            ret = wc_Sha512Final(&hmac->hash.sha512, (byte*) hmac->innerHash);
+            if (ret != 0)
+                return ret;
+
+            ret = wc_Sha512Update(&hmac->hash.sha512,
+                                 (byte*) hmac->opad, SHA512_BLOCK_SIZE);
+            if (ret != 0)
+                return ret;
+
+            ret = wc_Sha512Update(&hmac->hash.sha512,
+                                 (byte*) hmac->innerHash, SHA512_DIGEST_SIZE);
+            if (ret != 0)
+                return ret;
+
+            ret = wc_Sha512Final(&hmac->hash.sha512, hash);
+            if (ret != 0)
+                return ret;
+        }
+        break;
+        #endif
+
+        #ifdef HAVE_BLAKE2
+        case BLAKE2B_ID:
+        {
+            ret = wc_Blake2bFinal(&hmac->hash.blake2b, (byte*) hmac->innerHash,
+                         BLAKE2B_256);
+            if (ret != 0)
+                return ret;
+
+            ret = wc_Blake2bUpdate(&hmac->hash.blake2b,
+                                 (byte*) hmac->opad, BLAKE2B_BLOCKBYTES);
+            if (ret != 0)
+                return ret;
+
+            ret = wc_Blake2bUpdate(&hmac->hash.blake2b,
+                                 (byte*) hmac->innerHash, BLAKE2B_256);
+            if (ret != 0)
+                return ret;
+
+            ret = wc_Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256);
+            if (ret != 0)
+                return ret;
+        }
+        break;
+        #endif
+
+        default:
+        break;
+    }
+
+    hmac->innerHashKeyed = 0;
+
+    return 0;
+}
+
+
+#ifdef HAVE_CAVIUM
+
+/* Initiliaze Hmac for use with Nitrox device */
+int wc_HmacInitCavium(Hmac* hmac, int devId)
+{
+    if (hmac == NULL)
+        return -1;
+
+    if (CspAllocContext(CONTEXT_SSL, &hmac->contextHandle, devId) != 0)
+        return -1;
+
+    hmac->keyLen  = 0;
+    hmac->dataLen = 0;
+    hmac->type    = 0;
+    hmac->devId   = devId;
+    hmac->magic   = WOLFSSL_HMAC_CAVIUM_MAGIC;
+    hmac->data    = NULL;        /* buffered input data */
+
+    hmac->innerHashKeyed = 0;
+
+    return 0;
+}
+
+
+/* Free Hmac from use with Nitrox device */
+void wc_HmacFreeCavium(Hmac* hmac)
+{
+    if (hmac == NULL)
+        return;
+
+    CspFreeContext(CONTEXT_SSL, hmac->contextHandle, hmac->devId);
+    hmac->magic = 0;
+    XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP);
+    hmac->data = NULL;
+}
+
+
+static void HmacCaviumFinal(Hmac* hmac, byte* hash)
+{
+    word32 requestId;
+
+    if (CspHmac(CAVIUM_BLOCKING, hmac->type, NULL, hmac->keyLen,
+                (byte*)hmac->ipad, hmac->dataLen, hmac->data, hash, &requestId,
+                hmac->devId) != 0) {
+        WOLFSSL_MSG("Cavium Hmac failed");
+    }
+    hmac->innerHashKeyed = 0;  /* tell update to start over if used again */
+}
+
+
+static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length)
+{
+    word16 add = (word16)length;
+    word32 total;
+    byte*  tmp;
+
+    if (length > WOLFSSL_MAX_16BIT) {
+        WOLFSSL_MSG("Too big msg for cavium hmac");
+        return;
+    }
+
+    if (hmac->innerHashKeyed == 0) {  /* starting new */
+        hmac->dataLen        = 0;
+        hmac->innerHashKeyed = 1;
+    }
+
+    total = add + hmac->dataLen;
+    if (total > WOLFSSL_MAX_16BIT) {
+        WOLFSSL_MSG("Too big msg for cavium hmac");
+        return;
+    }
+
+    tmp = XMALLOC(hmac->dataLen + add, NULL,DYNAMIC_TYPE_CAVIUM_TMP);
+    if (tmp == NULL) {
+        WOLFSSL_MSG("Out of memory for cavium update");
+        return;
+    }
+    if (hmac->dataLen)
+        XMEMCPY(tmp, hmac->data,  hmac->dataLen);
+    XMEMCPY(tmp + hmac->dataLen, msg, add);
+
+    hmac->dataLen += add;
+    XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP);
+    hmac->data = tmp;
+}
+
+
+static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key,
+                             word32 length)
+{
+    hmac->macType = (byte)type;
+    if (type == MD5)
+        hmac->type = MD5_TYPE;
+    else if (type == SHA)
+        hmac->type = SHA1_TYPE;
+    else if (type == SHA256)
+        hmac->type = SHA256_TYPE;
+    else  {
+        WOLFSSL_MSG("unsupported cavium hmac type");
+    }
+
+    hmac->innerHashKeyed = 0;  /* should we key Startup flag */
+
+    hmac->keyLen = (word16)length;
+    /* store key in ipad */
+    XMEMCPY(hmac->ipad, key, length);
+}
+
+#endif /* HAVE_CAVIUM */
+
+int wolfSSL_GetHmacMaxSize(void)
+{
+    return MAX_DIGEST_SIZE;
+}
+
+#ifdef HAVE_HKDF
+
+#ifdef min
+#define WOLFSSL_HAVE_MIN
+#endif
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+
+#endif /* WOLFSSL_HAVE_MIN */
+
+
+static INLINE int GetHashSizeByType(int type)
+{
+    if (!(type == MD5 || type == SHA    || type == SHA256 || type == SHA384
+                      || type == SHA512 || type == BLAKE2B_ID))
+        return BAD_FUNC_ARG;
+
+    switch (type) {
+        #ifndef NO_MD5
+        case MD5:
+            return MD5_DIGEST_SIZE;
+        #endif
+
+        #ifndef NO_SHA
+        case SHA:
+            return SHA_DIGEST_SIZE;
+        #endif
+
+        #ifndef NO_SHA256
+        case SHA256:
+            return SHA256_DIGEST_SIZE;
+        #endif
+
+        #ifdef WOLFSSL_SHA384
+        case SHA384:
+            return SHA384_DIGEST_SIZE;
+        #endif
+
+        #ifdef WOLFSSL_SHA512
+        case SHA512:
+            return SHA512_DIGEST_SIZE;
+        #endif
+
+        #ifdef HAVE_BLAKE2
+        case BLAKE2B_ID:
+            return BLAKE2B_OUTBYTES;
+        #endif
+
+        default:
+            return BAD_FUNC_ARG;
+    }
+}
+
+
+/* HMAC-KDF with hash type, optional salt and info, return 0 on success */
+int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
+                   const byte* salt,  word32 saltSz,
+                   const byte* info,  word32 infoSz,
+                   byte* out,         word32 outSz)
+{
+    Hmac   myHmac;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* tmp;
+    byte* prk;
+#else
+    byte   tmp[MAX_DIGEST_SIZE]; /* localSalt helper and T */
+    byte   prk[MAX_DIGEST_SIZE];
+#endif
+    const  byte* localSalt;  /* either points to user input or tmp */
+    int    hashSz = GetHashSizeByType(type);
+    word32 outIdx = 0;
+    byte   n = 0x1;
+    int    ret;
+
+    if (hashSz < 0)
+        return BAD_FUNC_ARG;
+
+#ifdef WOLFSSL_SMALL_STACK
+    tmp = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmp == NULL)
+        return MEMORY_E;
+
+    prk = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (prk == NULL) {
+        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    localSalt = salt;
+    if (localSalt == NULL) {
+        XMEMSET(tmp, 0, hashSz);
+        localSalt = tmp;
+        saltSz    = hashSz;
+    }
+
+    do {
+    ret = wc_HmacSetKey(&myHmac, type, localSalt, saltSz);
+    if (ret != 0)
+        break;
+    ret = wc_HmacUpdate(&myHmac, inKey, inKeySz);
+    if (ret != 0)
+        break;
+    ret = wc_HmacFinal(&myHmac,  prk);
+    } while (0);
+
+    if (ret == 0) {
+        while (outIdx < outSz) {
+            int    tmpSz = (n == 1) ? 0 : hashSz;
+            word32 left = outSz - outIdx;
+
+            ret = wc_HmacSetKey(&myHmac, type, prk, hashSz);
+            if (ret != 0)
+                break;
+            ret = wc_HmacUpdate(&myHmac, tmp, tmpSz);
+            if (ret != 0)
+                break;
+            ret = wc_HmacUpdate(&myHmac, info, infoSz);
+            if (ret != 0)
+                break;
+            ret = wc_HmacUpdate(&myHmac, &n, 1);
+            if (ret != 0)
+                break;
+            ret = wc_HmacFinal(&myHmac, tmp);
+            if (ret != 0)
+                break;
+
+            left = min(left, (word32)hashSz);
+            XMEMCPY(out+outIdx, tmp, left);
+
+            outIdx += hashSz;
+            n++;
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(prk, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+#endif /* HAVE_HKDF */
+
+#endif /* HAVE_FIPS */
+#endif /* NO_HMAC */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/integer.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/integer.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/integer.c	(revision 164)
@@ -0,0 +1,4737 @@
+/* integer.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/*
+ * Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@iahu.ca,
+ * http://math.libtomcrypt.com
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+/* in case user set USE_FAST_MATH there */
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_BIG_INT
+
+#ifndef USE_FAST_MATH
+
+#include <wolfssl/wolfcrypt/integer.h>
+
+#ifndef NO_WOLFSSL_SMALL_STACK
+    #ifndef WOLFSSL_SMALL_STACK
+        #define WOLFSSL_SMALL_STACK
+    #endif
+#endif
+
+#ifdef SHOW_GEN
+    #ifdef FREESCALE_MQX
+        #if MQX_USE_IO_OLD
+            #include <fio.h>
+        #else
+            #include <nio.h>
+        #endif
+    #else
+        #include <stdio.h>
+    #endif
+#endif
+
+/* reverse an array, used for radix code */
+static void
+bn_reverse (unsigned char *s, int len)
+{
+    int     ix, iy;
+    unsigned char t;
+
+    ix = 0;
+    iy = len - 1;
+    while (ix < iy) {
+        t     = s[ix];
+        s[ix] = s[iy];
+        s[iy] = t;
+        ++ix;
+        --iy;
+    }
+}
+
+/* math settings check */
+word32 CheckRunTimeSettings(void)
+{
+    return CTC_SETTINGS;
+}
+
+
+/* handle up to 6 inits */
+int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e,
+                  mp_int* f)
+{
+    int res = MP_OKAY;
+
+    if (a && ((res = mp_init(a)) != MP_OKAY))
+        return res;
+
+    if (b && ((res = mp_init(b)) != MP_OKAY)) {
+        mp_clear(a);
+        return res;
+    }
+
+    if (c && ((res = mp_init(c)) != MP_OKAY)) {
+        mp_clear(a); mp_clear(b);
+        return res;
+    }
+
+    if (d && ((res = mp_init(d)) != MP_OKAY)) {
+        mp_clear(a); mp_clear(b); mp_clear(c);
+        return res;
+    }
+
+    if (e && ((res = mp_init(e)) != MP_OKAY)) {
+        mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d);
+        return res;
+    }
+
+    if (f && ((res = mp_init(f)) != MP_OKAY)) {
+        mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d); mp_clear(e);
+        return res;
+    }
+
+    return res;
+}
+
+
+/* init a new mp_int */
+int mp_init (mp_int * a)
+{
+  int i;
+
+  /* allocate memory required and clear it */
+  a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC, 0,
+                                      DYNAMIC_TYPE_BIGINT);
+  if (a->dp == NULL) {
+    return MP_MEM;
+  }
+
+  /* set the digits to zero */
+  for (i = 0; i < MP_PREC; i++) {
+      a->dp[i] = 0;
+  }
+
+  /* set the used to zero, allocated digits to the default precision
+   * and sign to positive */
+  a->used  = 0;
+  a->alloc = MP_PREC;
+  a->sign  = MP_ZPOS;
+
+  return MP_OKAY;
+}
+
+
+/* clear one (frees)  */
+void
+mp_clear (mp_int * a)
+{
+  int i;
+
+  if (a == NULL)
+      return;
+
+  /* only do anything if a hasn't been freed previously */
+  if (a->dp != NULL) {
+    /* first zero the digits */
+    for (i = 0; i < a->used; i++) {
+        a->dp[i] = 0;
+    }
+
+    /* free ram */
+    XFREE(a->dp, 0, DYNAMIC_TYPE_BIGINT);
+
+    /* reset members to make debugging easier */
+    a->dp    = NULL;
+    a->alloc = a->used = 0;
+    a->sign  = MP_ZPOS;
+  }
+}
+
+
+/* get the size for an unsigned equivalent */
+int mp_unsigned_bin_size (mp_int * a)
+{
+  int     size = mp_count_bits (a);
+  return (size / 8 + ((size & 7) != 0 ? 1 : 0));
+}
+
+
+/* returns the number of bits in an int */
+int
+mp_count_bits (mp_int * a)
+{
+  int     r;
+  mp_digit q;
+
+  /* shortcut */
+  if (a->used == 0) {
+    return 0;
+  }
+
+  /* get number of digits and add that */
+  r = (a->used - 1) * DIGIT_BIT;
+
+  /* take the last digit and count the bits in it */
+  q = a->dp[a->used - 1];
+  while (q > ((mp_digit) 0)) {
+    ++r;
+    q >>= ((mp_digit) 1);
+  }
+  return r;
+}
+
+
+int mp_leading_bit (mp_int * a)
+{
+    int bit = 0;
+    mp_int t;
+
+    if (mp_init_copy(&t, a) != MP_OKAY)
+        return 0;
+
+    while (mp_iszero(&t) == 0) {
+#ifndef MP_8BIT
+        bit = (t.dp[0] & 0x80) != 0;
+#else
+        bit = (t.dp[0] | ((t.dp[1] & 0x01) << 7)) & 0x80 != 0;
+#endif
+        if (mp_div_2d (&t, 8, &t, NULL) != MP_OKAY)
+            break;
+    }
+    mp_clear(&t);
+    return bit;
+}
+
+
+/* store in unsigned [big endian] format */
+int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
+{
+  int     x, res;
+  mp_int  t;
+
+  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+    return res;
+  }
+
+  x = 0;
+  while (mp_iszero (&t) == 0) {
+#ifndef MP_8BIT
+      b[x++] = (unsigned char) (t.dp[0] & 255);
+#else
+      b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));
+#endif
+    if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {
+      mp_clear (&t);
+      return res;
+    }
+  }
+  bn_reverse (b, x);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+
+
+/* creates "a" then copies b into it */
+int mp_init_copy (mp_int * a, mp_int * b)
+{
+  int     res;
+
+  if ((res = mp_init (a)) != MP_OKAY) {
+    return res;
+  }
+  return mp_copy (b, a);
+}
+
+
+/* copy, b = a */
+int
+mp_copy (mp_int * a, mp_int * b)
+{
+  int     res, n;
+
+  /* if dst == src do nothing */
+  if (a == b) {
+    return MP_OKAY;
+  }
+
+  /* grow dest */
+  if (b->alloc < a->used) {
+     if ((res = mp_grow (b, a->used)) != MP_OKAY) {
+        return res;
+     }
+  }
+
+  /* zero b and copy the parameters over */
+  {
+    register mp_digit *tmpa, *tmpb;
+
+    /* pointer aliases */
+
+    /* source */
+    tmpa = a->dp;
+
+    /* destination */
+    tmpb = b->dp;
+
+    /* copy all the digits */
+    for (n = 0; n < a->used; n++) {
+      *tmpb++ = *tmpa++;
+    }
+
+    /* clear high digits */
+    for (; n < b->used; n++) {
+      *tmpb++ = 0;
+    }
+  }
+
+  /* copy used count and sign */
+  b->used = a->used;
+  b->sign = a->sign;
+  return MP_OKAY;
+}
+
+
+/* grow as required */
+int mp_grow (mp_int * a, int size)
+{
+  int     i;
+  mp_digit *tmp;
+
+  /* if the alloc size is smaller alloc more ram */
+  if (a->alloc < size) {
+    /* ensure there are always at least MP_PREC digits extra on top */
+    size += (MP_PREC * 2) - (size % MP_PREC);
+
+    /* reallocate the array a->dp
+     *
+     * We store the return in a temporary variable
+     * in case the operation failed we don't want
+     * to overwrite the dp member of a.
+     */
+    tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size, 0,
+                                       DYNAMIC_TYPE_BIGINT);
+    if (tmp == NULL) {
+      /* reallocation failed but "a" is still valid [can be freed] */
+      return MP_MEM;
+    }
+
+    /* reallocation succeeded so set a->dp */
+    a->dp = tmp;
+
+    /* zero excess digits */
+    i        = a->alloc;
+    a->alloc = size;
+    for (; i < a->alloc; i++) {
+      a->dp[i] = 0;
+    }
+  }
+  return MP_OKAY;
+}
+
+
+/* shift right by a certain bit count (store quotient in c, optional
+   remainder in d) */
+int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
+{
+  int     D, res;
+  mp_int  t;
+
+
+  /* if the shift count is <= 0 then we do no work */
+  if (b <= 0) {
+    res = mp_copy (a, c);
+    if (d != NULL) {
+      mp_zero (d);
+    }
+    return res;
+  }
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  /* get the remainder */
+  if (d != NULL) {
+    if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
+      mp_clear (&t);
+      return res;
+    }
+  }
+
+  /* copy */
+  if ((res = mp_copy (a, c)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+
+  /* shift by as many digits in the bit count */
+  if (b >= (int)DIGIT_BIT) {
+    mp_rshd (c, b / DIGIT_BIT);
+  }
+
+  /* shift any bit count < DIGIT_BIT */
+  D = (b % DIGIT_BIT);
+  if (D != 0) {
+    mp_rshb(c, D);
+  }
+  mp_clamp (c);
+  if (d != NULL) {
+    mp_exch (&t, d);
+  }
+  mp_clear (&t);
+  return MP_OKAY;
+}
+
+
+/* set to zero */
+void mp_zero (mp_int * a)
+{
+  int       n;
+  mp_digit *tmp;
+
+  a->sign = MP_ZPOS;
+  a->used = 0;
+
+  tmp = a->dp;
+  for (n = 0; n < a->alloc; n++) {
+     *tmp++ = 0;
+  }
+}
+
+
+/* trim unused digits
+ *
+ * This is used to ensure that leading zero digits are
+ * trimed and the leading "used" digit will be non-zero
+ * Typically very fast.  Also fixes the sign if there
+ * are no more leading digits
+ */
+void
+mp_clamp (mp_int * a)
+{
+  /* decrease used while the most significant digit is
+   * zero.
+   */
+  while (a->used > 0 && a->dp[a->used - 1] == 0) {
+    --(a->used);
+  }
+
+  /* reset the sign flag if used == 0 */
+  if (a->used == 0) {
+    a->sign = MP_ZPOS;
+  }
+}
+
+
+/* swap the elements of two integers, for cases where you can't simply swap the
+ * mp_int pointers around
+ */
+void
+mp_exch (mp_int * a, mp_int * b)
+{
+  mp_int  t;
+
+  t  = *a;
+  *a = *b;
+  *b = t;
+}
+
+
+/* shift right a certain number of bits */
+void mp_rshb (mp_int *c, int x)
+{
+    register mp_digit *tmpc, mask, shift;
+    mp_digit r, rr;
+    mp_digit D = x;
+
+    /* mask */
+    mask = (((mp_digit)1) << D) - 1;
+
+    /* shift for lsb */
+    shift = DIGIT_BIT - D;
+
+    /* alias */
+    tmpc = c->dp + (c->used - 1);
+
+    /* carry */
+    r = 0;
+    for (x = c->used - 1; x >= 0; x--) {
+      /* get the lower  bits of this word in a temp */
+      rr = *tmpc & mask;
+
+      /* shift the current word and mix in the carry bits from previous word */
+      *tmpc = (*tmpc >> D) | (r << shift);
+      --tmpc;
+
+      /* set the carry to the carry bits of the current word found above */
+      r = rr;
+    }
+}
+
+
+/* shift right a certain amount of digits */
+void mp_rshd (mp_int * a, int b)
+{
+  int     x;
+
+  /* if b <= 0 then ignore it */
+  if (b <= 0) {
+    return;
+  }
+
+  /* if b > used then simply zero it and return */
+  if (a->used <= b) {
+    mp_zero (a);
+    return;
+  }
+
+  {
+    register mp_digit *bottom, *top;
+
+    /* shift the digits down */
+
+    /* bottom */
+    bottom = a->dp;
+
+    /* top [offset into digits] */
+    top = a->dp + b;
+
+    /* this is implemented as a sliding window where
+     * the window is b-digits long and digits from
+     * the top of the window are copied to the bottom
+     *
+     * e.g.
+
+     b-2 | b-1 | b0 | b1 | b2 | ... | bb |   ---->
+                 /\                   |      ---->
+                  \-------------------/      ---->
+     */
+    for (x = 0; x < (a->used - b); x++) {
+      *bottom++ = *top++;
+    }
+
+    /* zero the top digits */
+    for (; x < a->used; x++) {
+      *bottom++ = 0;
+    }
+  }
+
+  /* remove excess digits */
+  a->used -= b;
+}
+
+
+/* calc a value mod 2**b */
+int
+mp_mod_2d (mp_int * a, int b, mp_int * c)
+{
+  int     x, res;
+
+  /* if b is <= 0 then zero the int */
+  if (b <= 0) {
+    mp_zero (c);
+    return MP_OKAY;
+  }
+
+  /* if the modulus is larger than the value than return */
+  if (b >= (int) (a->used * DIGIT_BIT)) {
+    res = mp_copy (a, c);
+    return res;
+  }
+
+  /* copy */
+  if ((res = mp_copy (a, c)) != MP_OKAY) {
+    return res;
+  }
+
+  /* zero digits above the last digit of the modulus */
+  for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
+    c->dp[x] = 0;
+  }
+  /* clear the digit that is not completely outside/inside the modulus */
+  c->dp[b / DIGIT_BIT] &= (mp_digit) ((((mp_digit) 1) <<
+              (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
+  mp_clamp (c);
+  return MP_OKAY;
+}
+
+
+/* reads a unsigned char array, assumes the msb is stored first [big endian] */
+int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
+{
+  int     res;
+
+  /* make sure there are at least two digits */
+  if (a->alloc < 2) {
+     if ((res = mp_grow(a, 2)) != MP_OKAY) {
+        return res;
+     }
+  }
+
+  /* zero the int */
+  mp_zero (a);
+
+  /* read the bytes in */
+  while (c-- > 0) {
+    if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
+      return res;
+    }
+
+#ifndef MP_8BIT
+      a->dp[0] |= *b++;
+      a->used += 1;
+#else
+      a->dp[0] = (*b & MP_MASK);
+      a->dp[1] |= ((*b++ >> 7U) & 1);
+      a->used += 2;
+#endif
+  }
+  mp_clamp (a);
+  return MP_OKAY;
+}
+
+
+/* shift left by a certain bit count */
+int mp_mul_2d (mp_int * a, int b, mp_int * c)
+{
+  mp_digit d;
+  int      res;
+
+  /* copy */
+  if (a != c) {
+     if ((res = mp_copy (a, c)) != MP_OKAY) {
+       return res;
+     }
+  }
+
+  if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
+     if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
+       return res;
+     }
+  }
+
+  /* shift by as many digits in the bit count */
+  if (b >= (int)DIGIT_BIT) {
+    if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* shift any bit count < DIGIT_BIT */
+  d = (mp_digit) (b % DIGIT_BIT);
+  if (d != 0) {
+    register mp_digit *tmpc, shift, mask, r, rr;
+    register int x;
+
+    /* bitmask for carries */
+    mask = (((mp_digit)1) << d) - 1;
+
+    /* shift for msbs */
+    shift = DIGIT_BIT - d;
+
+    /* alias */
+    tmpc = c->dp;
+
+    /* carry */
+    r    = 0;
+    for (x = 0; x < c->used; x++) {
+      /* get the higher bits of the current word */
+      rr = (*tmpc >> shift) & mask;
+
+      /* shift the current word and OR in the carry */
+      *tmpc = ((*tmpc << d) | r) & MP_MASK;
+      ++tmpc;
+
+      /* set the carry to the carry bits of the current word */
+      r = rr;
+    }
+
+    /* set final carry */
+    if (r != 0) {
+       c->dp[(c->used)++] = r;
+    }
+  }
+  mp_clamp (c);
+  return MP_OKAY;
+}
+
+
+/* shift left a certain amount of digits */
+int mp_lshd (mp_int * a, int b)
+{
+  int     x, res;
+
+  /* if its less than zero return */
+  if (b <= 0) {
+    return MP_OKAY;
+  }
+
+  /* grow to fit the new digits */
+  if (a->alloc < a->used + b) {
+     if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
+       return res;
+     }
+  }
+
+  {
+    register mp_digit *top, *bottom;
+
+    /* increment the used by the shift amount then copy upwards */
+    a->used += b;
+
+    /* top */
+    top = a->dp + a->used - 1;
+
+    /* base */
+    bottom = a->dp + a->used - 1 - b;
+
+    /* much like mp_rshd this is implemented using a sliding window
+     * except the window goes the otherway around.  Copying from
+     * the bottom to the top.  see bn_mp_rshd.c for more info.
+     */
+    for (x = a->used - 1; x >= b; x--) {
+      *top-- = *bottom--;
+    }
+
+    /* zero the lower digits */
+    top = a->dp;
+    for (x = 0; x < b; x++) {
+      *top++ = 0;
+    }
+  }
+  return MP_OKAY;
+}
+
+
+/* this is a shell function that calls either the normal or Montgomery
+ * exptmod functions.  Originally the call to the montgomery code was
+ * embedded in the normal function but that wasted alot of stack space
+ * for nothing (since 99% of the time the Montgomery code would be called)
+ */
+int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
+{
+  int dr;
+
+  /* modulus P must be positive */
+  if (P->sign == MP_NEG) {
+     return MP_VAL;
+  }
+
+  /* if exponent X is negative we have to recurse */
+  if (X->sign == MP_NEG) {
+#ifdef BN_MP_INVMOD_C
+     mp_int tmpG, tmpX;
+     int err;
+
+     /* first compute 1/G mod P */
+     if ((err = mp_init(&tmpG)) != MP_OKAY) {
+        return err;
+     }
+     if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
+        mp_clear(&tmpG);
+        return err;
+     }
+
+     /* now get |X| */
+     if ((err = mp_init(&tmpX)) != MP_OKAY) {
+        mp_clear(&tmpG);
+        return err;
+     }
+     if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
+        mp_clear(&tmpG);
+        mp_clear(&tmpX);
+        return err;
+     }
+
+     /* and now compute (1/G)**|X| instead of G**X [X < 0] */
+     err = mp_exptmod(&tmpG, &tmpX, P, Y);
+     mp_clear(&tmpG);
+     mp_clear(&tmpX);
+     return err;
+#else
+     /* no invmod */
+     return MP_VAL;
+#endif
+  }
+
+/* modified diminished radix reduction */
+#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && \
+  defined(BN_S_MP_EXPTMOD_C)
+  if (mp_reduce_is_2k_l(P) == MP_YES) {
+     return s_mp_exptmod(G, X, P, Y, 1);
+  }
+#endif
+
+#ifdef BN_MP_DR_IS_MODULUS_C
+  /* is it a DR modulus? */
+  dr = mp_dr_is_modulus(P);
+#else
+  /* default to no */
+  dr = 0;
+#endif
+
+#ifdef BN_MP_REDUCE_IS_2K_C
+  /* if not, is it a unrestricted DR modulus? */
+  if (dr == 0) {
+     dr = mp_reduce_is_2k(P) << 1;
+  }
+#endif
+
+  /* if the modulus is odd or dr != 0 use the montgomery method */
+#ifdef BN_MP_EXPTMOD_FAST_C
+  if (mp_isodd (P) == 1 || dr !=  0) {
+    return mp_exptmod_fast (G, X, P, Y, dr);
+  } else {
+#endif
+#ifdef BN_S_MP_EXPTMOD_C
+    /* otherwise use the generic Barrett reduction technique */
+    return s_mp_exptmod (G, X, P, Y, 0);
+#else
+    /* no exptmod for evens */
+    return MP_VAL;
+#endif
+#ifdef BN_MP_EXPTMOD_FAST_C
+  }
+#endif
+}
+
+
+/* b = |a|
+ *
+ * Simple function copies the input and fixes the sign to positive
+ */
+int
+mp_abs (mp_int * a, mp_int * b)
+{
+  int     res;
+
+  /* copy a to b */
+  if (a != b) {
+     if ((res = mp_copy (a, b)) != MP_OKAY) {
+       return res;
+     }
+  }
+
+  /* force the sign of b to positive */
+  b->sign = MP_ZPOS;
+
+  return MP_OKAY;
+}
+
+
+/* hac 14.61, pp608 */
+int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
+{
+  /* b cannot be negative */
+  if (b->sign == MP_NEG || mp_iszero(b) == 1) {
+    return MP_VAL;
+  }
+
+#ifdef BN_FAST_MP_INVMOD_C
+  /* if the modulus is odd we can use a faster routine instead */
+  if (mp_isodd (b) == 1) {
+    return fast_mp_invmod (a, b, c);
+  }
+#endif
+
+#ifdef BN_MP_INVMOD_SLOW_C
+  return mp_invmod_slow(a, b, c);
+#endif
+}
+
+
+/* computes the modular inverse via binary extended euclidean algorithm,
+ * that is c = 1/a mod b
+ *
+ * Based on slow invmod except this is optimized for the case where b is
+ * odd as per HAC Note 14.64 on pp. 610
+ */
+int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int  x, y, u, v, B, D;
+  int     res, neg, loop_check = 0;
+
+  /* 2. [modified] b must be odd   */
+  if (mp_iseven (b) == 1) {
+    return MP_VAL;
+  }
+
+  /* init all our temps */
+  if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D)) != MP_OKAY) {
+     return res;
+  }
+
+  /* x == modulus, y == value to invert */
+  if ((res = mp_copy (b, &x)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+
+  /* we need y = |a| */
+  if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+
+  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
+  if ((res = mp_copy (&x, &u)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+  if ((res = mp_copy (&y, &v)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+  mp_set (&D, 1);
+
+top:
+  /* 4.  while u is even do */
+  while (mp_iseven (&u) == 1) {
+    /* 4.1 u = u/2 */
+    if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    /* 4.2 if B is odd then */
+    if (mp_isodd (&B) == 1) {
+      if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
+        goto LBL_ERR;
+      }
+    }
+    /* B = B/2 */
+    if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* 5.  while v is even do */
+  while (mp_iseven (&v) == 1) {
+    /* 5.1 v = v/2 */
+    if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    /* 5.2 if D is odd then */
+    if (mp_isodd (&D) == 1) {
+      /* D = (D-x)/2 */
+      if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
+        goto LBL_ERR;
+      }
+    }
+    /* D = D/2 */
+    if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* 6.  if u >= v then */
+  if (mp_cmp (&u, &v) != MP_LT) {
+    /* u = u - v, B = B - D */
+    if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  } else {
+    /* v - v - u, D = D - B */
+    if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* if not zero goto step 4 */
+  if (mp_iszero (&u) == 0) {
+    if (++loop_check > 4096) {
+        res = MP_VAL;
+        goto LBL_ERR;
+    }
+    goto top;
+  }
+
+  /* now a = C, b = D, gcd == g*v */
+
+  /* if v != 1 then there is no inverse */
+  if (mp_cmp_d (&v, 1) != MP_EQ) {
+    res = MP_VAL;
+    goto LBL_ERR;
+  }
+
+  /* b is now the inverse */
+  neg = a->sign;
+  while (D.sign == MP_NEG) {
+    if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+  /* too big */
+  while (mp_cmp_mag(&D, b) != MP_LT) {
+      if ((res = mp_sub(&D, b, &D)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+  }
+  mp_exch (&D, c);
+  c->sign = neg;
+  res = MP_OKAY;
+
+LBL_ERR:mp_clear(&x);
+        mp_clear(&y);
+        mp_clear(&u);
+        mp_clear(&v);
+        mp_clear(&B);
+        mp_clear(&D);
+  return res;
+}
+
+
+/* hac 14.61, pp608 */
+int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int  x, y, u, v, A, B, C, D;
+  int     res;
+
+  /* b cannot be negative */
+  if (b->sign == MP_NEG || mp_iszero(b) == 1) {
+    return MP_VAL;
+  }
+
+  /* init temps */
+  if ((res = mp_init_multi(&x, &y, &u, &v,
+                           &A, &B)) != MP_OKAY) {
+     return res;
+  }
+
+  /* init rest of tmps temps */
+  if ((res = mp_init_multi(&C, &D, 0, 0, 0, 0)) != MP_OKAY) {
+     return res;
+  }
+
+  /* x = a, y = b */
+  if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
+      goto LBL_ERR;
+  }
+  if ((res = mp_copy (b, &y)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+
+  /* 2. [modified] if x,y are both even then return an error! */
+  if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) {
+    res = MP_VAL;
+    goto LBL_ERR;
+  }
+
+  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
+  if ((res = mp_copy (&x, &u)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+  if ((res = mp_copy (&y, &v)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+  mp_set (&A, 1);
+  mp_set (&D, 1);
+
+top:
+  /* 4.  while u is even do */
+  while (mp_iseven (&u) == 1) {
+    /* 4.1 u = u/2 */
+    if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    /* 4.2 if A or B is odd then */
+    if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) {
+      /* A = (A+y)/2, B = (B-x)/2 */
+      if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+      if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+    }
+    /* A = A/2, B = B/2 */
+    if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* 5.  while v is even do */
+  while (mp_iseven (&v) == 1) {
+    /* 5.1 v = v/2 */
+    if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    /* 5.2 if C or D is odd then */
+    if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) {
+      /* C = (C+y)/2, D = (D-x)/2 */
+      if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+      if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+    }
+    /* C = C/2, D = D/2 */
+    if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* 6.  if u >= v then */
+  if (mp_cmp (&u, &v) != MP_LT) {
+    /* u = u - v, A = A - C, B = B - D */
+    if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  } else {
+    /* v - v - u, C = C - A, D = D - B */
+    if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* if not zero goto step 4 */
+  if (mp_iszero (&u) == 0)
+    goto top;
+
+  /* now a = C, b = D, gcd == g*v */
+
+  /* if v != 1 then there is no inverse */
+  if (mp_cmp_d (&v, 1) != MP_EQ) {
+    res = MP_VAL;
+    goto LBL_ERR;
+  }
+
+  /* if its too low */
+  while (mp_cmp_d(&C, 0) == MP_LT) {
+      if ((res = mp_add(&C, b, &C)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+  }
+
+  /* too big */
+  while (mp_cmp_mag(&C, b) != MP_LT) {
+      if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+  }
+
+  /* C is now the inverse */
+  mp_exch (&C, c);
+  res = MP_OKAY;
+LBL_ERR:mp_clear(&x);
+        mp_clear(&y);
+        mp_clear(&u);
+        mp_clear(&v);
+        mp_clear(&A);
+        mp_clear(&B);
+        mp_clear(&C);
+        mp_clear(&D);
+  return res;
+}
+
+
+/* compare maginitude of two ints (unsigned) */
+int mp_cmp_mag (mp_int * a, mp_int * b)
+{
+  int     n;
+  mp_digit *tmpa, *tmpb;
+
+  /* compare based on # of non-zero digits */
+  if (a->used > b->used) {
+    return MP_GT;
+  }
+
+  if (a->used < b->used) {
+    return MP_LT;
+  }
+
+  /* alias for a */
+  tmpa = a->dp + (a->used - 1);
+
+  /* alias for b */
+  tmpb = b->dp + (a->used - 1);
+
+  /* compare based on digits  */
+  for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
+    if (*tmpa > *tmpb) {
+      return MP_GT;
+    }
+
+    if (*tmpa < *tmpb) {
+      return MP_LT;
+    }
+  }
+  return MP_EQ;
+}
+
+
+/* compare two ints (signed)*/
+int
+mp_cmp (mp_int * a, mp_int * b)
+{
+  /* compare based on sign */
+  if (a->sign != b->sign) {
+     if (a->sign == MP_NEG) {
+        return MP_LT;
+     } else {
+        return MP_GT;
+     }
+  }
+
+  /* compare digits */
+  if (a->sign == MP_NEG) {
+     /* if negative compare opposite direction */
+     return mp_cmp_mag(b, a);
+  } else {
+     return mp_cmp_mag(a, b);
+  }
+}
+
+
+/* compare a digit */
+int mp_cmp_d(mp_int * a, mp_digit b)
+{
+  /* compare based on sign */
+  if (a->sign == MP_NEG) {
+    return MP_LT;
+  }
+
+  /* compare based on magnitude */
+  if (a->used > 1) {
+    return MP_GT;
+  }
+
+  /* compare the only digit of a to b */
+  if (a->dp[0] > b) {
+    return MP_GT;
+  } else if (a->dp[0] < b) {
+    return MP_LT;
+  } else {
+    return MP_EQ;
+  }
+}
+
+
+/* set to a digit */
+void mp_set (mp_int * a, mp_digit b)
+{
+  mp_zero (a);
+  a->dp[0] = b & MP_MASK;
+  a->used  = (a->dp[0] != 0) ? 1 : 0;
+}
+
+/* chek if a bit is set */
+int mp_is_bit_set (mp_int *a, mp_digit b)
+{
+    if ((mp_digit)a->used < b/DIGIT_BIT)
+        return 0;
+
+    return (int)((a->dp[b/DIGIT_BIT] >> b%DIGIT_BIT) & (mp_digit)1);
+}
+
+/* c = a mod b, 0 <= c < b */
+int
+mp_mod (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int  t;
+  int     res;
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+
+  if (t.sign != b->sign) {
+    res = mp_add (b, &t, c);
+  } else {
+    res = MP_OKAY;
+    mp_exch (&t, c);
+  }
+
+  mp_clear (&t);
+  return res;
+}
+
+
+/* slower bit-bang division... also smaller */
+int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+   mp_int ta, tb, tq, q;
+   int    res, n, n2;
+
+  /* is divisor zero ? */
+  if (mp_iszero (b) == 1) {
+    return MP_VAL;
+  }
+
+  /* if a < b then q=0, r = a */
+  if (mp_cmp_mag (a, b) == MP_LT) {
+    if (d != NULL) {
+      res = mp_copy (a, d);
+    } else {
+      res = MP_OKAY;
+    }
+    if (c != NULL) {
+      mp_zero (c);
+    }
+    return res;
+  }
+
+  /* init our temps */
+  if ((res = mp_init_multi(&ta, &tb, &tq, &q, 0, 0)) != MP_OKAY) {
+     return res;
+  }
+
+
+  mp_set(&tq, 1);
+  n = mp_count_bits(a) - mp_count_bits(b);
+  if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
+      ((res = mp_abs(b, &tb)) != MP_OKAY) ||
+      ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
+      ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
+      goto LBL_ERR;
+  }
+
+  while (n-- >= 0) {
+     if (mp_cmp(&tb, &ta) != MP_GT) {
+        if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
+            ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
+           goto LBL_ERR;
+        }
+     }
+     if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
+         ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
+           goto LBL_ERR;
+     }
+  }
+
+  /* now q == quotient and ta == remainder */
+  n  = a->sign;
+  n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);
+  if (c != NULL) {
+     mp_exch(c, &q);
+     c->sign  = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
+  }
+  if (d != NULL) {
+     mp_exch(d, &ta);
+     d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
+  }
+LBL_ERR:
+   mp_clear(&ta);
+   mp_clear(&tb);
+   mp_clear(&tq);
+   mp_clear(&q);
+   return res;
+}
+
+
+/* b = a/2 */
+int mp_div_2(mp_int * a, mp_int * b)
+{
+  int     x, res, oldused;
+
+  /* copy */
+  if (b->alloc < a->used) {
+    if ((res = mp_grow (b, a->used)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  oldused = b->used;
+  b->used = a->used;
+  {
+    register mp_digit r, rr, *tmpa, *tmpb;
+
+    /* source alias */
+    tmpa = a->dp + b->used - 1;
+
+    /* dest alias */
+    tmpb = b->dp + b->used - 1;
+
+    /* carry */
+    r = 0;
+    for (x = b->used - 1; x >= 0; x--) {
+      /* get the carry for the next iteration */
+      rr = *tmpa & 1;
+
+      /* shift the current digit, add in carry and store */
+      *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
+
+      /* forward carry to next iteration */
+      r = rr;
+    }
+
+    /* zero excess digits */
+    tmpb = b->dp + b->used;
+    for (x = b->used; x < oldused; x++) {
+      *tmpb++ = 0;
+    }
+  }
+  b->sign = a->sign;
+  mp_clamp (b);
+  return MP_OKAY;
+}
+
+
+/* high level addition (handles signs) */
+int mp_add (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     sa, sb, res;
+
+  /* get sign of both inputs */
+  sa = a->sign;
+  sb = b->sign;
+
+  /* handle two cases, not four */
+  if (sa == sb) {
+    /* both positive or both negative */
+    /* add their magnitudes, copy the sign */
+    c->sign = sa;
+    res = s_mp_add (a, b, c);
+  } else {
+    /* one positive, the other negative */
+    /* subtract the one with the greater magnitude from */
+    /* the one of the lesser magnitude.  The result gets */
+    /* the sign of the one with the greater magnitude. */
+    if (mp_cmp_mag (a, b) == MP_LT) {
+      c->sign = sb;
+      res = s_mp_sub (b, a, c);
+    } else {
+      c->sign = sa;
+      res = s_mp_sub (a, b, c);
+    }
+  }
+  return res;
+}
+
+
+/* low level addition, based on HAC pp.594, Algorithm 14.7 */
+int
+s_mp_add (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int *x;
+  int     olduse, res, min, max;
+
+  /* find sizes, we let |a| <= |b| which means we have to sort
+   * them.  "x" will point to the input with the most digits
+   */
+  if (a->used > b->used) {
+    min = b->used;
+    max = a->used;
+    x = a;
+  } else {
+    min = a->used;
+    max = b->used;
+    x = b;
+  }
+
+  /* init result */
+  if (c->alloc < max + 1) {
+    if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* get old used digit count and set new one */
+  olduse = c->used;
+  c->used = max + 1;
+
+  {
+    register mp_digit u, *tmpa, *tmpb, *tmpc;
+    register int i;
+
+    /* alias for digit pointers */
+
+    /* first input */
+    tmpa = a->dp;
+
+    /* second input */
+    tmpb = b->dp;
+
+    /* destination */
+    tmpc = c->dp;
+
+    /* zero the carry */
+    u = 0;
+    for (i = 0; i < min; i++) {
+      /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
+      *tmpc = *tmpa++ + *tmpb++ + u;
+
+      /* U = carry bit of T[i] */
+      u = *tmpc >> ((mp_digit)DIGIT_BIT);
+
+      /* take away carry bit from T[i] */
+      *tmpc++ &= MP_MASK;
+    }
+
+    /* now copy higher words if any, that is in A+B
+     * if A or B has more digits add those in
+     */
+    if (min != max) {
+      for (; i < max; i++) {
+        /* T[i] = X[i] + U */
+        *tmpc = x->dp[i] + u;
+
+        /* U = carry bit of T[i] */
+        u = *tmpc >> ((mp_digit)DIGIT_BIT);
+
+        /* take away carry bit from T[i] */
+        *tmpc++ &= MP_MASK;
+      }
+    }
+
+    /* add carry */
+    *tmpc++ = u;
+
+    /* clear digits above oldused */
+    for (i = c->used; i < olduse; i++) {
+      *tmpc++ = 0;
+    }
+  }
+
+  mp_clamp (c);
+  return MP_OKAY;
+}
+
+
+/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
+int
+s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     olduse, res, min, max;
+
+  /* find sizes */
+  min = b->used;
+  max = a->used;
+
+  /* init result */
+  if (c->alloc < max) {
+    if ((res = mp_grow (c, max)) != MP_OKAY) {
+      return res;
+    }
+  }
+  olduse = c->used;
+  c->used = max;
+
+  {
+    register mp_digit u, *tmpa, *tmpb, *tmpc;
+    register int i;
+
+    /* alias for digit pointers */
+    tmpa = a->dp;
+    tmpb = b->dp;
+    tmpc = c->dp;
+
+    /* set carry to zero */
+    u = 0;
+    for (i = 0; i < min; i++) {
+      /* T[i] = A[i] - B[i] - U */
+      *tmpc = *tmpa++ - *tmpb++ - u;
+
+      /* U = carry bit of T[i]
+       * Note this saves performing an AND operation since
+       * if a carry does occur it will propagate all the way to the
+       * MSB.  As a result a single shift is enough to get the carry
+       */
+      u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
+
+      /* Clear carry from T[i] */
+      *tmpc++ &= MP_MASK;
+    }
+
+    /* now copy higher words if any, e.g. if A has more digits than B  */
+    for (; i < max; i++) {
+      /* T[i] = A[i] - U */
+      *tmpc = *tmpa++ - u;
+
+      /* U = carry bit of T[i] */
+      u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
+
+      /* Clear carry from T[i] */
+      *tmpc++ &= MP_MASK;
+    }
+
+    /* clear digits above used (since we may not have grown result above) */
+    for (i = c->used; i < olduse; i++) {
+      *tmpc++ = 0;
+    }
+  }
+
+  mp_clamp (c);
+  return MP_OKAY;
+}
+
+
+/* high level subtraction (handles signs) */
+int
+mp_sub (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     sa, sb, res;
+
+  sa = a->sign;
+  sb = b->sign;
+
+  if (sa != sb) {
+    /* subtract a negative from a positive, OR */
+    /* subtract a positive from a negative. */
+    /* In either case, ADD their magnitudes, */
+    /* and use the sign of the first number. */
+    c->sign = sa;
+    res = s_mp_add (a, b, c);
+  } else {
+    /* subtract a positive from a positive, OR */
+    /* subtract a negative from a negative. */
+    /* First, take the difference between their */
+    /* magnitudes, then... */
+    if (mp_cmp_mag (a, b) != MP_LT) {
+      /* Copy the sign from the first */
+      c->sign = sa;
+      /* The first has a larger or equal magnitude */
+      res = s_mp_sub (a, b, c);
+    } else {
+      /* The result has the *opposite* sign from */
+      /* the first number. */
+      c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
+      /* The second has a larger magnitude */
+      res = s_mp_sub (b, a, c);
+    }
+  }
+  return res;
+}
+
+
+/* determines if reduce_2k_l can be used */
+int mp_reduce_is_2k_l(mp_int *a)
+{
+   int ix, iy;
+
+   if (a->used == 0) {
+      return MP_NO;
+   } else if (a->used == 1) {
+      return MP_YES;
+   } else if (a->used > 1) {
+      /* if more than half of the digits are -1 we're sold */
+      for (iy = ix = 0; ix < a->used; ix++) {
+          if (a->dp[ix] == MP_MASK) {
+              ++iy;
+          }
+      }
+      return (iy >= (a->used/2)) ? MP_YES : MP_NO;
+
+   }
+   return MP_NO;
+}
+
+
+/* determines if mp_reduce_2k can be used */
+int mp_reduce_is_2k(mp_int *a)
+{
+   int ix, iy, iw;
+   mp_digit iz;
+
+   if (a->used == 0) {
+      return MP_NO;
+   } else if (a->used == 1) {
+      return MP_YES;
+   } else if (a->used > 1) {
+      iy = mp_count_bits(a);
+      iz = 1;
+      iw = 1;
+
+      /* Test every bit from the second digit up, must be 1 */
+      for (ix = DIGIT_BIT; ix < iy; ix++) {
+          if ((a->dp[iw] & iz) == 0) {
+             return MP_NO;
+          }
+          iz <<= 1;
+          if (iz > (mp_digit)MP_MASK) {
+             ++iw;
+             iz = 1;
+          }
+      }
+   }
+   return MP_YES;
+}
+
+
+/* determines if a number is a valid DR modulus */
+int mp_dr_is_modulus(mp_int *a)
+{
+   int ix;
+
+   /* must be at least two digits */
+   if (a->used < 2) {
+      return 0;
+   }
+
+   /* must be of the form b**k - a [a <= b] so all
+    * but the first digit must be equal to -1 (mod b).
+    */
+   for (ix = 1; ix < a->used; ix++) {
+       if (a->dp[ix] != MP_MASK) {
+          return 0;
+       }
+   }
+   return 1;
+}
+
+
+/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
+ *
+ * Uses a left-to-right k-ary sliding window to compute the modular
+ * exponentiation.
+ * The value of k changes based on the size of the exponent.
+ *
+ * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
+ */
+
+#ifdef MP_LOW_MEM
+   #define TAB_SIZE 32
+#else
+   #define TAB_SIZE 256
+#endif
+
+int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,
+                     int redmode)
+{
+  mp_int res;
+  mp_digit buf, mp;
+  int     err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
+#ifdef WOLFSSL_SMALL_STACK
+  mp_int* M = NULL;
+#else
+  mp_int M[TAB_SIZE];
+#endif
+  /* use a pointer to the reduction algorithm.  This allows us to use
+   * one of many reduction algorithms without modding the guts of
+   * the code with if statements everywhere.
+   */
+  int     (*redux)(mp_int*,mp_int*,mp_digit);
+
+#ifdef WOLFSSL_SMALL_STACK
+  M = (mp_int*) XMALLOC(sizeof(mp_int) * TAB_SIZE, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+  if (M == NULL)
+    return MP_MEM;
+#endif
+
+  /* find window size */
+  x = mp_count_bits (X);
+  if (x <= 7) {
+    winsize = 2;
+  } else if (x <= 36) {
+    winsize = 3;
+  } else if (x <= 140) {
+    winsize = 4;
+  } else if (x <= 450) {
+    winsize = 5;
+  } else if (x <= 1303) {
+    winsize = 6;
+  } else if (x <= 3529) {
+    winsize = 7;
+  } else {
+    winsize = 8;
+  }
+
+#ifdef MP_LOW_MEM
+  if (winsize > 5) {
+     winsize = 5;
+  }
+#endif
+
+  /* init M array */
+  /* init first cell */
+  if ((err = mp_init(&M[1])) != MP_OKAY) {
+#ifdef WOLFSSL_SMALL_STACK
+  XFREE(M, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+     return err;
+  }
+
+  /* now init the second half of the array */
+  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+    if ((err = mp_init(&M[x])) != MP_OKAY) {
+      for (y = 1<<(winsize-1); y < x; y++) {
+        mp_clear (&M[y]);
+      }
+      mp_clear(&M[1]);
+
+#ifdef WOLFSSL_SMALL_STACK
+      XFREE(M, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+      return err;
+    }
+  }
+
+  /* determine and setup reduction code */
+  if (redmode == 0) {
+#ifdef BN_MP_MONTGOMERY_SETUP_C
+     /* now setup montgomery  */
+     if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
+        goto LBL_M;
+     }
+#else
+     err = MP_VAL;
+     goto LBL_M;
+#endif
+
+     /* automatically pick the comba one if available (saves quite a few
+        calls/ifs) */
+#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
+     if (((P->used * 2 + 1) < MP_WARRAY) &&
+          P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+        redux = fast_mp_montgomery_reduce;
+     } else
+#endif
+     {
+#ifdef BN_MP_MONTGOMERY_REDUCE_C
+        /* use slower baseline Montgomery method */
+        redux = mp_montgomery_reduce;
+#else
+        err = MP_VAL;
+        goto LBL_M;
+#endif
+     }
+  } else if (redmode == 1) {
+#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
+     /* setup DR reduction for moduli of the form B**k - b */
+     mp_dr_setup(P, &mp);
+     redux = mp_dr_reduce;
+#else
+     err = MP_VAL;
+     goto LBL_M;
+#endif
+  } else {
+#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
+     /* setup DR reduction for moduli of the form 2**k - b */
+     if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
+        goto LBL_M;
+     }
+     redux = mp_reduce_2k;
+#else
+     err = MP_VAL;
+     goto LBL_M;
+#endif
+  }
+
+  /* setup result */
+  if ((err = mp_init (&res)) != MP_OKAY) {
+    goto LBL_M;
+  }
+
+  /* create M table
+   *
+
+   *
+   * The first half of the table is not computed though accept for M[0] and M[1]
+   */
+
+  if (redmode == 0) {
+#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+     /* now we need R mod m */
+     if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
+       goto LBL_RES;
+     }
+#else
+     err = MP_VAL;
+     goto LBL_RES;
+#endif
+
+     /* now set M[1] to G * R mod m */
+     if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
+       goto LBL_RES;
+     }
+  } else {
+     mp_set(&res, 1);
+     if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
+        goto LBL_RES;
+     }
+  }
+
+  /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times*/
+  if ((err = mp_copy (&M[1], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {
+    goto LBL_RES;
+  }
+
+  for (x = 0; x < (winsize - 1); x++) {
+    if ((err = mp_sqr (&M[(mp_digit)(1 << (winsize - 1))],
+                       &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {
+      goto LBL_RES;
+    }
+    if ((err = redux (&M[(mp_digit)(1 << (winsize - 1))], P, mp)) != MP_OKAY) {
+      goto LBL_RES;
+    }
+  }
+
+  /* create upper table */
+  for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
+    if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
+      goto LBL_RES;
+    }
+    if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
+      goto LBL_RES;
+    }
+  }
+
+  /* set initial mode and bit cnt */
+  mode   = 0;
+  bitcnt = 1;
+  buf    = 0;
+  digidx = X->used - 1;
+  bitcpy = 0;
+  bitbuf = 0;
+
+  for (;;) {
+    /* grab next digit as required */
+    if (--bitcnt == 0) {
+      /* if digidx == -1 we are out of digits so break */
+      if (digidx == -1) {
+        break;
+      }
+      /* read next digit and reset bitcnt */
+      buf    = X->dp[digidx--];
+      bitcnt = (int)DIGIT_BIT;
+    }
+
+    /* grab the next msb from the exponent */
+    y     = (int)(buf >> (DIGIT_BIT - 1)) & 1;
+    buf <<= (mp_digit)1;
+
+    /* if the bit is zero and mode == 0 then we ignore it
+     * These represent the leading zero bits before the first 1 bit
+     * in the exponent.  Technically this opt is not required but it
+     * does lower the # of trivial squaring/reductions used
+     */
+    if (mode == 0 && y == 0) {
+      continue;
+    }
+
+    /* if the bit is zero and mode == 1 then we square */
+    if (mode == 1 && y == 0) {
+      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, mp)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      continue;
+    }
+
+    /* else we add it to the window */
+    bitbuf |= (y << (winsize - ++bitcpy));
+    mode    = 2;
+
+    if (bitcpy == winsize) {
+      /* ok window is filled so square as required and multiply  */
+      /* square first */
+      for (x = 0; x < winsize; x++) {
+        if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+        if ((err = redux (&res, P, mp)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+      }
+
+      /* then multiply */
+      if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, mp)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+
+      /* empty window and reset */
+      bitcpy = 0;
+      bitbuf = 0;
+      mode   = 1;
+    }
+  }
+
+  /* if bits remain then square/multiply */
+  if (mode == 2 && bitcpy > 0) {
+    /* square then multiply if the bit is set */
+    for (x = 0; x < bitcpy; x++) {
+      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, mp)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+
+      /* get next bit of the window */
+      bitbuf <<= 1;
+      if ((bitbuf & (1 << winsize)) != 0) {
+        /* then multiply */
+        if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+        if ((err = redux (&res, P, mp)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+      }
+    }
+  }
+
+  if (redmode == 0) {
+     /* fixup result if Montgomery reduction is used
+      * recall that any value in a Montgomery system is
+      * actually multiplied by R mod n.  So we have
+      * to reduce one more time to cancel out the factor
+      * of R.
+      */
+     if ((err = redux(&res, P, mp)) != MP_OKAY) {
+       goto LBL_RES;
+     }
+  }
+
+  /* swap res with Y */
+  mp_exch (&res, Y);
+  err = MP_OKAY;
+LBL_RES:mp_clear (&res);
+LBL_M:
+  mp_clear(&M[1]);
+  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+    mp_clear (&M[x]);
+  }
+
+#ifdef WOLFSSL_SMALL_STACK
+  XFREE(M, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+  return err;
+}
+
+
+/* setups the montgomery reduction stuff */
+int
+mp_montgomery_setup (mp_int * n, mp_digit * rho)
+{
+  mp_digit x, b;
+
+/* fast inversion mod 2**k
+ *
+ * Based on the fact that
+ *
+ * XA = 1 (mod 2**n)  =>  (X(2-XA)) A = 1 (mod 2**2n)
+ *                    =>  2*X*A - X*X*A*A = 1
+ *                    =>  2*(1) - (1)     = 1
+ */
+  b = n->dp[0];
+
+  if ((b & 1) == 0) {
+    return MP_VAL;
+  }
+
+  x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
+  x *= 2 - b * x;               /* here x*a==1 mod 2**8 */
+#if !defined(MP_8BIT)
+  x *= 2 - b * x;               /* here x*a==1 mod 2**16 */
+#endif
+#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
+  x *= 2 - b * x;               /* here x*a==1 mod 2**32 */
+#endif
+#ifdef MP_64BIT
+  x *= 2 - b * x;               /* here x*a==1 mod 2**64 */
+#endif
+
+  /* rho = -1/m mod b */
+  /* TAO, switched mp_word casts to mp_digit to shut up compiler */
+  *rho = (((mp_digit)1 << ((mp_digit) DIGIT_BIT)) - x) & MP_MASK;
+
+  return MP_OKAY;
+}
+
+
+/* computes xR**-1 == x (mod N) via Montgomery Reduction
+ *
+ * This is an optimized implementation of montgomery_reduce
+ * which uses the comba method to quickly calculate the columns of the
+ * reduction.
+ *
+ * Based on Algorithm 14.32 on pp.601 of HAC.
+*/
+int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
+{
+  int     ix, res, olduse;
+#ifdef WOLFSSL_SMALL_STACK
+  mp_word* W;    /* uses dynamic memory and slower */
+#else
+  mp_word W[MP_WARRAY];
+#endif
+
+  /* get old used count */
+  olduse = x->used;
+
+  /* grow a as required */
+  if (x->alloc < n->used + 1) {
+    if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+#ifdef WOLFSSL_SMALL_STACK
+  W = (mp_word*)XMALLOC(sizeof(mp_word) * MP_WARRAY, 0, DYNAMIC_TYPE_BIGINT);
+  if (W == NULL)
+    return MP_MEM;
+#endif
+
+  /* first we have to get the digits of the input into
+   * an array of double precision words W[...]
+   */
+  {
+    register mp_word *_W;
+    register mp_digit *tmpx;
+
+    /* alias for the W[] array */
+    _W   = W;
+
+    /* alias for the digits of  x*/
+    tmpx = x->dp;
+
+    /* copy the digits of a into W[0..a->used-1] */
+    for (ix = 0; ix < x->used; ix++) {
+      *_W++ = *tmpx++;
+    }
+
+    /* zero the high words of W[a->used..m->used*2] */
+    for (; ix < n->used * 2 + 1; ix++) {
+      *_W++ = 0;
+    }
+  }
+
+  /* now we proceed to zero successive digits
+   * from the least significant upwards
+   */
+  for (ix = 0; ix < n->used; ix++) {
+    /* mu = ai * m' mod b
+     *
+     * We avoid a double precision multiplication (which isn't required)
+     * by casting the value down to a mp_digit.  Note this requires
+     * that W[ix-1] have  the carry cleared (see after the inner loop)
+     */
+    register mp_digit mu;
+    mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
+
+    /* a = a + mu * m * b**i
+     *
+     * This is computed in place and on the fly.  The multiplication
+     * by b**i is handled by offseting which columns the results
+     * are added to.
+     *
+     * Note the comba method normally doesn't handle carries in the
+     * inner loop In this case we fix the carry from the previous
+     * column since the Montgomery reduction requires digits of the
+     * result (so far) [see above] to work.  This is
+     * handled by fixing up one carry after the inner loop.  The
+     * carry fixups are done in order so after these loops the
+     * first m->used words of W[] have the carries fixed
+     */
+    {
+      register int iy;
+      register mp_digit *tmpn;
+      register mp_word *_W;
+
+      /* alias for the digits of the modulus */
+      tmpn = n->dp;
+
+      /* Alias for the columns set by an offset of ix */
+      _W = W + ix;
+
+      /* inner loop */
+      for (iy = 0; iy < n->used; iy++) {
+          *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
+      }
+    }
+
+    /* now fix carry for next digit, W[ix+1] */
+    W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
+  }
+
+  /* now we have to propagate the carries and
+   * shift the words downward [all those least
+   * significant digits we zeroed].
+   */
+  {
+    register mp_digit *tmpx;
+    register mp_word *_W, *_W1;
+
+    /* nox fix rest of carries */
+
+    /* alias for current word */
+    _W1 = W + ix;
+
+    /* alias for next word, where the carry goes */
+    _W = W + ++ix;
+
+    for (; ix <= n->used * 2 + 1; ix++) {
+      *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
+    }
+
+    /* copy out, A = A/b**n
+     *
+     * The result is A/b**n but instead of converting from an
+     * array of mp_word to mp_digit than calling mp_rshd
+     * we just copy them in the right order
+     */
+
+    /* alias for destination word */
+    tmpx = x->dp;
+
+    /* alias for shifted double precision result */
+    _W = W + n->used;
+
+    for (ix = 0; ix < n->used + 1; ix++) {
+      *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
+    }
+
+    /* zero oldused digits, if the input a was larger than
+     * m->used+1 we'll have to clear the digits
+     */
+    for (; ix < olduse; ix++) {
+      *tmpx++ = 0;
+    }
+  }
+
+  /* set the max used and clamp */
+  x->used = n->used + 1;
+  mp_clamp (x);
+
+#ifdef WOLFSSL_SMALL_STACK
+  XFREE(W, 0, DYNAMIC_TYPE_BIGINT);
+#endif
+
+  /* if A >= m then A = A - m */
+  if (mp_cmp_mag (x, n) != MP_LT) {
+    return s_mp_sub (x, n, x);
+  }
+  return MP_OKAY;
+}
+
+
+/* computes xR**-1 == x (mod N) via Montgomery Reduction */
+int
+mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
+{
+  int     ix, res, digs;
+  mp_digit mu;
+
+  /* can the fast reduction [comba] method be used?
+   *
+   * Note that unlike in mul you're safely allowed *less*
+   * than the available columns [255 per default] since carries
+   * are fixed up in the inner loop.
+   */
+  digs = n->used * 2 + 1;
+  if ((digs < MP_WARRAY) &&
+      n->used <
+      (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+    return fast_mp_montgomery_reduce (x, n, rho);
+  }
+
+  /* grow the input as required */
+  if (x->alloc < digs) {
+    if ((res = mp_grow (x, digs)) != MP_OKAY) {
+      return res;
+    }
+  }
+  x->used = digs;
+
+  for (ix = 0; ix < n->used; ix++) {
+    /* mu = ai * rho mod b
+     *
+     * The value of rho must be precalculated via
+     * montgomery_setup() such that
+     * it equals -1/n0 mod b this allows the
+     * following inner loop to reduce the
+     * input one digit at a time
+     */
+    mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);
+
+    /* a = a + mu * m * b**i */
+    {
+      register int iy;
+      register mp_digit *tmpn, *tmpx, u;
+      register mp_word r;
+
+      /* alias for digits of the modulus */
+      tmpn = n->dp;
+
+      /* alias for the digits of x [the input] */
+      tmpx = x->dp + ix;
+
+      /* set the carry to zero */
+      u = 0;
+
+      /* Multiply and add in place */
+      for (iy = 0; iy < n->used; iy++) {
+        /* compute product and sum */
+        r       = ((mp_word)mu) * ((mp_word)*tmpn++) +
+                  ((mp_word) u) + ((mp_word) * tmpx);
+
+        /* get carry */
+        u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+
+        /* fix digit */
+        *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
+      }
+      /* At this point the ix'th digit of x should be zero */
+
+
+      /* propagate carries upwards as required*/
+      while (u) {
+        *tmpx   += u;
+        u        = *tmpx >> DIGIT_BIT;
+        *tmpx++ &= MP_MASK;
+      }
+    }
+  }
+
+  /* at this point the n.used'th least
+   * significant digits of x are all zero
+   * which means we can shift x to the
+   * right by n.used digits and the
+   * residue is unchanged.
+   */
+
+  /* x = x/b**n.used */
+  mp_clamp(x);
+  mp_rshd (x, n->used);
+
+  /* if x >= n then x = x - n */
+  if (mp_cmp_mag (x, n) != MP_LT) {
+    return s_mp_sub (x, n, x);
+  }
+
+  return MP_OKAY;
+}
+
+
+/* determines the setup value */
+void mp_dr_setup(mp_int *a, mp_digit *d)
+{
+   /* the casts are required if DIGIT_BIT is one less than
+    * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
+    */
+   *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) -
+        ((mp_word)a->dp[0]));
+}
+
+
+/* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
+ *
+ * Based on algorithm from the paper
+ *
+ * "Generating Efficient Primes for Discrete Log Cryptosystems"
+ *                 Chae Hoon Lim, Pil Joong Lee,
+ *          POSTECH Information Research Laboratories
+ *
+ * The modulus must be of a special format [see manual]
+ *
+ * Has been modified to use algorithm 7.10 from the LTM book instead
+ *
+ * Input x must be in the range 0 <= x <= (n-1)**2
+ */
+int
+mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
+{
+  int      err, i, m;
+  mp_word  r;
+  mp_digit mu, *tmpx1, *tmpx2;
+
+  /* m = digits in modulus */
+  m = n->used;
+
+  /* ensure that "x" has at least 2m digits */
+  if (x->alloc < m + m) {
+    if ((err = mp_grow (x, m + m)) != MP_OKAY) {
+      return err;
+    }
+  }
+
+/* top of loop, this is where the code resumes if
+ * another reduction pass is required.
+ */
+top:
+  /* aliases for digits */
+  /* alias for lower half of x */
+  tmpx1 = x->dp;
+
+  /* alias for upper half of x, or x/B**m */
+  tmpx2 = x->dp + m;
+
+  /* set carry to zero */
+  mu = 0;
+
+  /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
+  for (i = 0; i < m; i++) {
+      r         = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;
+      *tmpx1++  = (mp_digit)(r & MP_MASK);
+      mu        = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
+  }
+
+  /* set final carry */
+  *tmpx1++ = mu;
+
+  /* zero words above m */
+  for (i = m + 1; i < x->used; i++) {
+      *tmpx1++ = 0;
+  }
+
+  /* clamp, sub and return */
+  mp_clamp (x);
+
+  /* if x >= n then subtract and reduce again
+   * Each successive "recursion" makes the input smaller and smaller.
+   */
+  if (mp_cmp_mag (x, n) != MP_LT) {
+    s_mp_sub(x, n, x);
+    goto top;
+  }
+  return MP_OKAY;
+}
+
+
+/* reduces a modulo n where n is of the form 2**p - d */
+int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d)
+{
+   mp_int q;
+   int    p, res;
+
+   if ((res = mp_init(&q)) != MP_OKAY) {
+      return res;
+   }
+
+   p = mp_count_bits(n);
+top:
+   /* q = a/2**p, a = a mod 2**p */
+   if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
+      goto ERR;
+   }
+
+   if (d != 1) {
+      /* q = q * d */
+      if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) {
+         goto ERR;
+      }
+   }
+
+   /* a = a + q */
+   if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
+      goto ERR;
+   }
+
+   if (mp_cmp_mag(a, n) != MP_LT) {
+      s_mp_sub(a, n, a);
+      goto top;
+   }
+
+ERR:
+   mp_clear(&q);
+   return res;
+}
+
+
+/* determines the setup value */
+int mp_reduce_2k_setup(mp_int *a, mp_digit *d)
+{
+   int res, p;
+   mp_int tmp;
+
+   if ((res = mp_init(&tmp)) != MP_OKAY) {
+      return res;
+   }
+
+   p = mp_count_bits(a);
+   if ((res = mp_2expt(&tmp, p)) != MP_OKAY) {
+      mp_clear(&tmp);
+      return res;
+   }
+
+   if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {
+      mp_clear(&tmp);
+      return res;
+   }
+
+   *d = tmp.dp[0];
+   mp_clear(&tmp);
+   return MP_OKAY;
+}
+
+
+/* set the b bit of a */
+int
+mp_set_bit (mp_int * a, int b)
+{
+    int i = b / DIGIT_BIT, res;
+
+    if (a->used < (int)(i + 1)) {
+        /* grow a to accomodate the single bit */
+        if ((res = mp_grow (a, i + 1)) != MP_OKAY) {
+            return res;
+        }
+
+        /* set the used count of where the bit will go */
+        a->used = (int)(i + 1);
+    }
+
+    /* put the single bit in its place */
+    a->dp[i] |= ((mp_digit)1) << (b % DIGIT_BIT);
+
+    return MP_OKAY;
+}
+
+/* computes a = 2**b
+ *
+ * Simple algorithm which zeroes the int, set the required bit
+ */
+int
+mp_2expt (mp_int * a, int b)
+{
+    /* zero a as per default */
+    mp_zero (a);
+
+    return mp_set_bit(a, b);
+}
+
+/* multiply by a digit */
+int
+mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
+{
+  mp_digit u, *tmpa, *tmpc;
+  mp_word  r;
+  int      ix, res, olduse;
+
+  /* make sure c is big enough to hold a*b */
+  if (c->alloc < a->used + 1) {
+    if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* get the original destinations used count */
+  olduse = c->used;
+
+  /* set the sign */
+  c->sign = a->sign;
+
+  /* alias for a->dp [source] */
+  tmpa = a->dp;
+
+  /* alias for c->dp [dest] */
+  tmpc = c->dp;
+
+  /* zero carry */
+  u = 0;
+
+  /* compute columns */
+  for (ix = 0; ix < a->used; ix++) {
+    /* compute product and carry sum for this term */
+    r       = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);
+
+    /* mask off higher bits to get a single digit */
+    *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+    /* send carry into next iteration */
+    u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+  }
+
+  /* store final carry [if any] and increment ix offset  */
+  *tmpc++ = u;
+  ++ix;
+
+  /* now zero digits above the top */
+  while (ix++ < olduse) {
+     *tmpc++ = 0;
+  }
+
+  /* set used count */
+  c->used = a->used + 1;
+  mp_clamp(c);
+
+  return MP_OKAY;
+}
+
+
+/* d = a * b (mod c) */
+int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+  int     res;
+  mp_int  t;
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+  res = mp_mod (&t, c, d);
+  mp_clear (&t);
+  return res;
+}
+
+
+/* computes b = a*a */
+int
+mp_sqr (mp_int * a, mp_int * b)
+{
+  int     res;
+
+  {
+#ifdef BN_FAST_S_MP_SQR_C
+    /* can we use the fast comba multiplier? */
+    if ((a->used * 2 + 1) < MP_WARRAY &&
+         a->used <
+         (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {
+      res = fast_s_mp_sqr (a, b);
+    } else
+#endif
+#ifdef BN_S_MP_SQR_C
+      res = s_mp_sqr (a, b);
+#else
+      res = MP_VAL;
+#endif
+  }
+  b->sign = MP_ZPOS;
+  return res;
+}
+
+
+/* high level multiplication (handles sign) */
+int mp_mul (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res, neg;
+  neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
+
+  {
+    /* can we use the fast multiplier?
+     *
+     * The fast multiplier can be used if the output will
+     * have less than MP_WARRAY digits and the number of
+     * digits won't affect carry propagation
+     */
+    int     digs = a->used + b->used + 1;
+
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
+    if ((digs < MP_WARRAY) &&
+        MIN(a->used, b->used) <=
+        (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+      res = fast_s_mp_mul_digs (a, b, c, digs);
+    } else
+#endif
+#ifdef BN_S_MP_MUL_DIGS_C
+      res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */
+#else
+      res = MP_VAL;
+#endif
+
+  }
+  c->sign = (c->used > 0) ? neg : MP_ZPOS;
+  return res;
+}
+
+
+/* b = a*2 */
+int mp_mul_2(mp_int * a, mp_int * b)
+{
+  int     x, res, oldused;
+
+  /* grow to accomodate result */
+  if (b->alloc < a->used + 1) {
+    if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  oldused = b->used;
+  b->used = a->used;
+
+  {
+    register mp_digit r, rr, *tmpa, *tmpb;
+
+    /* alias for source */
+    tmpa = a->dp;
+
+    /* alias for dest */
+    tmpb = b->dp;
+
+    /* carry */
+    r = 0;
+    for (x = 0; x < a->used; x++) {
+
+      /* get what will be the *next* carry bit from the
+       * MSB of the current digit
+       */
+      rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
+
+      /* now shift up this digit, add in the carry [from the previous] */
+      *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
+
+      /* copy the carry that would be from the source
+       * digit into the next iteration
+       */
+      r = rr;
+    }
+
+    /* new leading digit? */
+    if (r != 0) {
+      /* add a MSB which is always 1 at this point */
+      *tmpb = 1;
+      ++(b->used);
+    }
+
+    /* now zero any excess digits on the destination
+     * that we didn't write to
+     */
+    tmpb = b->dp + b->used;
+    for (x = b->used; x < oldused; x++) {
+      *tmpb++ = 0;
+    }
+  }
+  b->sign = a->sign;
+  return MP_OKAY;
+}
+
+
+/* divide by three (based on routine from MPI and the GMP manual) */
+int
+mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
+{
+  mp_int   q;
+  mp_word  w, t;
+  mp_digit b;
+  int      res, ix;
+
+  /* b = 2**DIGIT_BIT / 3 */
+  b = (mp_digit) ( (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3) );
+
+  if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
+     return res;
+  }
+
+  q.used = a->used;
+  q.sign = a->sign;
+  w = 0;
+  for (ix = a->used - 1; ix >= 0; ix--) {
+     w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
+
+     if (w >= 3) {
+        /* multiply w by [1/3] */
+        t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
+
+        /* now subtract 3 * [w/3] from w, to get the remainder */
+        w -= t+t+t;
+
+        /* fixup the remainder as required since
+         * the optimization is not exact.
+         */
+        while (w >= 3) {
+           t += 1;
+           w -= 3;
+        }
+      } else {
+        t = 0;
+      }
+      q.dp[ix] = (mp_digit)t;
+  }
+
+  /* [optional] store the remainder */
+  if (d != NULL) {
+     *d = (mp_digit)w;
+  }
+
+  /* [optional] store the quotient */
+  if (c != NULL) {
+     mp_clamp(&q);
+     mp_exch(&q, c);
+  }
+  mp_clear(&q);
+
+  return res;
+}
+
+
+/* init an mp_init for a given size */
+int mp_init_size (mp_int * a, int size)
+{
+  int x;
+
+  /* pad size so there are always extra digits */
+  size += (MP_PREC * 2) - (size % MP_PREC);
+
+  /* alloc mem */
+  a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size, 0,
+                                      DYNAMIC_TYPE_BIGINT);
+  if (a->dp == NULL) {
+    return MP_MEM;
+  }
+
+  /* set the members */
+  a->used  = 0;
+  a->alloc = size;
+  a->sign  = MP_ZPOS;
+
+  /* zero the digits */
+  for (x = 0; x < size; x++) {
+      a->dp[x] = 0;
+  }
+
+  return MP_OKAY;
+}
+
+
+/* the jist of squaring...
+ * you do like mult except the offset of the tmpx [one that
+ * starts closer to zero] can't equal the offset of tmpy.
+ * So basically you set up iy like before then you min it with
+ * (ty-tx) so that it never happens.  You double all those
+ * you add in the inner loop
+
+After that loop you do the squares and add them in.
+*/
+
+int fast_s_mp_sqr (mp_int * a, mp_int * b)
+{
+  int       olduse, res, pa, ix, iz;
+#ifdef WOLFSSL_SMALL_STACK
+  mp_digit* W;    /* uses dynamic memory and slower */
+#else
+  mp_digit W[MP_WARRAY];
+#endif
+  mp_digit  *tmpx;
+  mp_word   W1;
+
+  /* grow the destination as required */
+  pa = a->used + a->used;
+  if (b->alloc < pa) {
+    if ((res = mp_grow (b, pa)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  if (pa > MP_WARRAY)
+    return MP_RANGE;  /* TAO range check */
+
+#ifdef WOLFSSL_SMALL_STACK
+  W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, 0, DYNAMIC_TYPE_BIGINT);
+  if (W == NULL)
+    return MP_MEM;
+#endif
+
+  /* number of output digits to produce */
+  W1 = 0;
+  for (ix = 0; ix < pa; ix++) {
+      int      tx, ty, iy;
+      mp_word  _W;
+      mp_digit *tmpy;
+
+      /* clear counter */
+      _W = 0;
+
+      /* get offsets into the two bignums */
+      ty = MIN(a->used-1, ix);
+      tx = ix - ty;
+
+      /* setup temp aliases */
+      tmpx = a->dp + tx;
+      tmpy = a->dp + ty;
+
+      /* this is the number of times the loop will iterrate, essentially
+         while (tx++ < a->used && ty-- >= 0) { ... }
+       */
+      iy = MIN(a->used-tx, ty+1);
+
+      /* now for squaring tx can never equal ty
+       * we halve the distance since they approach at a rate of 2x
+       * and we have to round because odd cases need to be executed
+       */
+      iy = MIN(iy, (ty-tx+1)>>1);
+
+      /* execute loop */
+      for (iz = 0; iz < iy; iz++) {
+         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+      }
+
+      /* double the inner product and add carry */
+      _W = _W + _W + W1;
+
+      /* even columns have the square term in them */
+      if ((ix&1) == 0) {
+         _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
+      }
+
+      /* store it */
+      W[ix] = (mp_digit)(_W & MP_MASK);
+
+      /* make next carry */
+      W1 = _W >> ((mp_word)DIGIT_BIT);
+  }
+
+  /* setup dest */
+  olduse  = b->used;
+  b->used = a->used+a->used;
+
+  {
+    mp_digit *tmpb;
+    tmpb = b->dp;
+    for (ix = 0; ix < pa; ix++) {
+      *tmpb++ = W[ix] & MP_MASK;
+    }
+
+    /* clear unused digits [that existed in the old copy of c] */
+    for (; ix < olduse; ix++) {
+      *tmpb++ = 0;
+    }
+  }
+  mp_clamp (b);
+
+#ifdef WOLFSSL_SMALL_STACK
+  XFREE(W, 0, DYNAMIC_TYPE_BIGINT);
+#endif
+
+  return MP_OKAY;
+}
+
+
+/* Fast (comba) multiplier
+ *
+ * This is the fast column-array [comba] multiplier.  It is
+ * designed to compute the columns of the product first
+ * then handle the carries afterwards.  This has the effect
+ * of making the nested loops that compute the columns very
+ * simple and schedulable on super-scalar processors.
+ *
+ * This has been modified to produce a variable number of
+ * digits of output so if say only a half-product is required
+ * you don't have to compute the upper half (a feature
+ * required for fast Barrett reduction).
+ *
+ * Based on Algorithm 14.12 on pp.595 of HAC.
+ *
+ */
+int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+  int     olduse, res, pa, ix, iz;
+#ifdef WOLFSSL_SMALL_STACK
+  mp_digit* W;    /* uses dynamic memory and slower */
+#else
+  mp_digit W[MP_WARRAY];
+#endif
+  register mp_word  _W;
+
+  /* grow the destination as required */
+  if (c->alloc < digs) {
+    if ((res = mp_grow (c, digs)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* number of output digits to produce */
+  pa = MIN(digs, a->used + b->used);
+  if (pa > MP_WARRAY)
+    return MP_RANGE;  /* TAO range check */
+
+#ifdef WOLFSSL_SMALL_STACK
+  W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, 0, DYNAMIC_TYPE_BIGINT);
+  if (W == NULL)
+    return MP_MEM;
+#endif
+
+  /* clear the carry */
+  _W = 0;
+  for (ix = 0; ix < pa; ix++) {
+      int      tx, ty;
+      int      iy;
+      mp_digit *tmpx, *tmpy;
+
+      /* get offsets into the two bignums */
+      ty = MIN(b->used-1, ix);
+      tx = ix - ty;
+
+      /* setup temp aliases */
+      tmpx = a->dp + tx;
+      tmpy = b->dp + ty;
+
+      /* this is the number of times the loop will iterrate, essentially
+         while (tx++ < a->used && ty-- >= 0) { ... }
+       */
+      iy = MIN(a->used-tx, ty+1);
+
+      /* execute loop */
+      for (iz = 0; iz < iy; ++iz) {
+         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+
+      }
+
+      /* store term */
+      W[ix] = ((mp_digit)_W) & MP_MASK;
+
+      /* make next carry */
+      _W = _W >> ((mp_word)DIGIT_BIT);
+ }
+
+  /* setup dest */
+  olduse  = c->used;
+  c->used = pa;
+
+  {
+    register mp_digit *tmpc;
+    tmpc = c->dp;
+    for (ix = 0; ix < pa+1; ix++) {
+      /* now extract the previous digit [below the carry] */
+      *tmpc++ = W[ix];
+    }
+
+    /* clear unused digits [that existed in the old copy of c] */
+    for (; ix < olduse; ix++) {
+      *tmpc++ = 0;
+    }
+  }
+  mp_clamp (c);
+
+#ifdef WOLFSSL_SMALL_STACK
+  XFREE(W, 0, DYNAMIC_TYPE_BIGINT);
+#endif
+
+  return MP_OKAY;
+}
+
+
+/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
+int s_mp_sqr (mp_int * a, mp_int * b)
+{
+  mp_int  t;
+  int     res, ix, iy, pa;
+  mp_word r;
+  mp_digit u, tmpx, *tmpt;
+
+  pa = a->used;
+  if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
+    return res;
+  }
+
+  /* default used is maximum possible size */
+  t.used = 2*pa + 1;
+
+  for (ix = 0; ix < pa; ix++) {
+    /* first calculate the digit at 2*ix */
+    /* calculate double precision result */
+    r = ((mp_word) t.dp[2*ix]) +
+        ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
+
+    /* store lower part in result */
+    t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
+
+    /* get the carry */
+    u           = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+
+    /* left hand side of A[ix] * A[iy] */
+    tmpx        = a->dp[ix];
+
+    /* alias for where to store the results */
+    tmpt        = t.dp + (2*ix + 1);
+
+    for (iy = ix + 1; iy < pa; iy++) {
+      /* first calculate the product */
+      r       = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
+
+      /* now calculate the double precision result, note we use
+       * addition instead of *2 since it's easier to optimize
+       */
+      r       = ((mp_word) *tmpt) + r + r + ((mp_word) u);
+
+      /* store lower part */
+      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+      /* get carry */
+      u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+    }
+    /* propagate upwards */
+    while (u != ((mp_digit) 0)) {
+      r       = ((mp_word) *tmpt) + ((mp_word) u);
+      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+      u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+    }
+  }
+
+  mp_clamp (&t);
+  mp_exch (&t, b);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+
+
+/* multiplies |a| * |b| and only computes upto digs digits of result
+ * HAC pp. 595, Algorithm 14.12  Modified so you can control how
+ * many digits of output are created.
+ */
+int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+  mp_int  t;
+  int     res, pa, pb, ix, iy;
+  mp_digit u;
+  mp_word r;
+  mp_digit tmpx, *tmpt, *tmpy;
+
+  /* can we use the fast multiplier? */
+  if (((digs) < MP_WARRAY) &&
+      MIN (a->used, b->used) <
+          (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+    return fast_s_mp_mul_digs (a, b, c, digs);
+  }
+
+  if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
+    return res;
+  }
+  t.used = digs;
+
+  /* compute the digits of the product directly */
+  pa = a->used;
+  for (ix = 0; ix < pa; ix++) {
+    /* set the carry to zero */
+    u = 0;
+
+    /* limit ourselves to making digs digits of output */
+    pb = MIN (b->used, digs - ix);
+
+    /* setup some aliases */
+    /* copy of the digit from a used within the nested loop */
+    tmpx = a->dp[ix];
+
+    /* an alias for the destination shifted ix places */
+    tmpt = t.dp + ix;
+
+    /* an alias for the digits of b */
+    tmpy = b->dp;
+
+    /* compute the columns of the output and propagate the carry */
+    for (iy = 0; iy < pb; iy++) {
+      /* compute the column as a mp_word */
+      r       = ((mp_word)*tmpt) +
+                ((mp_word)tmpx) * ((mp_word)*tmpy++) +
+                ((mp_word) u);
+
+      /* the new column is the lower part of the result */
+      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+      /* get the carry word from the result */
+      u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+    }
+    /* set carry if it is placed below digs */
+    if (ix + iy < digs) {
+      *tmpt = u;
+    }
+  }
+
+  mp_clamp (&t);
+  mp_exch (&t, c);
+
+  mp_clear (&t);
+  return MP_OKAY;
+}
+
+
+/*
+ * shifts with subtractions when the result is greater than b.
+ *
+ * The method is slightly modified to shift B unconditionally upto just under
+ * the leading bit of b.  This saves alot of multiple precision shifting.
+ */
+int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
+{
+  int     x, bits, res;
+
+  /* how many bits of last digit does b use */
+  bits = mp_count_bits (b) % DIGIT_BIT;
+
+  if (b->used > 1) {
+     if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1))
+         != MP_OKAY) {
+        return res;
+     }
+  } else {
+     mp_set(a, 1);
+     bits = 1;
+  }
+
+
+  /* now compute C = A * B mod b */
+  for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
+    if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
+      return res;
+    }
+    if (mp_cmp_mag (a, b) != MP_LT) {
+      if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {
+        return res;
+      }
+    }
+  }
+
+  return MP_OKAY;
+}
+
+
+#ifdef MP_LOW_MEM
+   #define TAB_SIZE 32
+#else
+   #define TAB_SIZE 256
+#endif
+
+int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
+{
+  mp_int  M[TAB_SIZE], res, mu;
+  mp_digit buf;
+  int     err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
+  int (*redux)(mp_int*,mp_int*,mp_int*);
+
+  /* find window size */
+  x = mp_count_bits (X);
+  if (x <= 7) {
+    winsize = 2;
+  } else if (x <= 36) {
+    winsize = 3;
+  } else if (x <= 140) {
+    winsize = 4;
+  } else if (x <= 450) {
+    winsize = 5;
+  } else if (x <= 1303) {
+    winsize = 6;
+  } else if (x <= 3529) {
+    winsize = 7;
+  } else {
+    winsize = 8;
+  }
+
+#ifdef MP_LOW_MEM
+    if (winsize > 5) {
+       winsize = 5;
+    }
+#endif
+
+  /* init M array */
+  /* init first cell */
+  if ((err = mp_init(&M[1])) != MP_OKAY) {
+     return err;
+  }
+
+  /* now init the second half of the array */
+  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+    if ((err = mp_init(&M[x])) != MP_OKAY) {
+      for (y = 1<<(winsize-1); y < x; y++) {
+        mp_clear (&M[y]);
+      }
+      mp_clear(&M[1]);
+      return err;
+    }
+  }
+
+  /* create mu, used for Barrett reduction */
+  if ((err = mp_init (&mu)) != MP_OKAY) {
+    goto LBL_M;
+  }
+
+  if (redmode == 0) {
+     if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {
+        goto LBL_MU;
+     }
+     redux = mp_reduce;
+  } else {
+     if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) {
+        goto LBL_MU;
+     }
+     redux = mp_reduce_2k_l;
+  }
+
+  /* create M table
+   *
+   * The M table contains powers of the base,
+   * e.g. M[x] = G**x mod P
+   *
+   * The first half of the table is not
+   * computed though accept for M[0] and M[1]
+   */
+  if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
+    goto LBL_MU;
+  }
+
+  /* compute the value at M[1<<(winsize-1)] by squaring
+   * M[1] (winsize-1) times
+   */
+  if ((err = mp_copy (&M[1], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {
+    goto LBL_MU;
+  }
+
+  for (x = 0; x < (winsize - 1); x++) {
+    /* square it */
+    if ((err = mp_sqr (&M[(mp_digit)(1 << (winsize - 1))],
+                       &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {
+      goto LBL_MU;
+    }
+
+    /* reduce modulo P */
+    if ((err = redux (&M[(mp_digit)(1 << (winsize - 1))], P, &mu)) != MP_OKAY) {
+      goto LBL_MU;
+    }
+  }
+
+  /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
+   * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
+   */
+  for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
+    if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
+      goto LBL_MU;
+    }
+    if ((err = redux (&M[x], P, &mu)) != MP_OKAY) {
+      goto LBL_MU;
+    }
+  }
+
+  /* setup result */
+  if ((err = mp_init (&res)) != MP_OKAY) {
+    goto LBL_MU;
+  }
+  mp_set (&res, 1);
+
+  /* set initial mode and bit cnt */
+  mode   = 0;
+  bitcnt = 1;
+  buf    = 0;
+  digidx = X->used - 1;
+  bitcpy = 0;
+  bitbuf = 0;
+
+  for (;;) {
+    /* grab next digit as required */
+    if (--bitcnt == 0) {
+      /* if digidx == -1 we are out of digits */
+      if (digidx == -1) {
+        break;
+      }
+      /* read next digit and reset the bitcnt */
+      buf    = X->dp[digidx--];
+      bitcnt = (int) DIGIT_BIT;
+    }
+
+    /* grab the next msb from the exponent */
+    y     = (int)(buf >> (mp_digit)(DIGIT_BIT - 1)) & 1;
+    buf <<= (mp_digit)1;
+
+    /* if the bit is zero and mode == 0 then we ignore it
+     * These represent the leading zero bits before the first 1 bit
+     * in the exponent.  Technically this opt is not required but it
+     * does lower the # of trivial squaring/reductions used
+     */
+    if (mode == 0 && y == 0) {
+      continue;
+    }
+
+    /* if the bit is zero and mode == 1 then we square */
+    if (mode == 1 && y == 0) {
+      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      continue;
+    }
+
+    /* else we add it to the window */
+    bitbuf |= (y << (winsize - ++bitcpy));
+    mode    = 2;
+
+    if (bitcpy == winsize) {
+      /* ok window is filled so square as required and multiply  */
+      /* square first */
+      for (x = 0; x < winsize; x++) {
+        if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+        if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+      }
+
+      /* then multiply */
+      if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+
+      /* empty window and reset */
+      bitcpy = 0;
+      bitbuf = 0;
+      mode   = 1;
+    }
+  }
+
+  /* if bits remain then square/multiply */
+  if (mode == 2 && bitcpy > 0) {
+    /* square then multiply if the bit is set */
+    for (x = 0; x < bitcpy; x++) {
+      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+
+      bitbuf <<= 1;
+      if ((bitbuf & (1 << winsize)) != 0) {
+        /* then multiply */
+        if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+        if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+      }
+    }
+  }
+
+  mp_exch (&res, Y);
+  err = MP_OKAY;
+LBL_RES:mp_clear (&res);
+LBL_MU:mp_clear (&mu);
+LBL_M:
+  mp_clear(&M[1]);
+  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+    mp_clear (&M[x]);
+  }
+  return err;
+}
+
+
+/* pre-calculate the value required for Barrett reduction
+ * For a given modulus "b" it calulates the value required in "a"
+ */
+int mp_reduce_setup (mp_int * a, mp_int * b)
+{
+  int     res;
+
+  if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {
+    return res;
+  }
+  return mp_div (a, b, a, NULL);
+}
+
+
+/* reduces x mod m, assumes 0 < x < m**2, mu is
+ * precomputed via mp_reduce_setup.
+ * From HAC pp.604 Algorithm 14.42
+ */
+int mp_reduce (mp_int * x, mp_int * m, mp_int * mu)
+{
+  mp_int  q;
+  int     res, um = m->used;
+
+  /* q = x */
+  if ((res = mp_init_copy (&q, x)) != MP_OKAY) {
+    return res;
+  }
+
+  /* q1 = x / b**(k-1)  */
+  mp_rshd (&q, um - 1);
+
+  /* according to HAC this optimization is ok */
+  if (((mp_word) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) {
+    if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) {
+      goto CLEANUP;
+    }
+  } else {
+#ifdef BN_S_MP_MUL_HIGH_DIGS_C
+    if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
+      goto CLEANUP;
+    }
+#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
+    if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
+      goto CLEANUP;
+    }
+#else
+    {
+      res = MP_VAL;
+      goto CLEANUP;
+    }
+#endif
+  }
+
+  /* q3 = q2 / b**(k+1) */
+  mp_rshd (&q, um + 1);
+
+  /* x = x mod b**(k+1), quick (no division) */
+  if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
+    goto CLEANUP;
+  }
+
+  /* q = q * m mod b**(k+1), quick (no division) */
+  if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) {
+    goto CLEANUP;
+  }
+
+  /* x = x - q */
+  if ((res = mp_sub (x, &q, x)) != MP_OKAY) {
+    goto CLEANUP;
+  }
+
+  /* If x < 0, add b**(k+1) to it */
+  if (mp_cmp_d (x, 0) == MP_LT) {
+    mp_set (&q, 1);
+    if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)
+      goto CLEANUP;
+    if ((res = mp_add (x, &q, x)) != MP_OKAY)
+      goto CLEANUP;
+  }
+
+  /* Back off if it's too big */
+  while (mp_cmp (x, m) != MP_LT) {
+    if ((res = s_mp_sub (x, m, x)) != MP_OKAY) {
+      goto CLEANUP;
+    }
+  }
+
+CLEANUP:
+  mp_clear (&q);
+
+  return res;
+}
+
+
+/* reduces a modulo n where n is of the form 2**p - d
+   This differs from reduce_2k since "d" can be larger
+   than a single digit.
+*/
+int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d)
+{
+   mp_int q;
+   int    p, res;
+
+   if ((res = mp_init(&q)) != MP_OKAY) {
+      return res;
+   }
+
+   p = mp_count_bits(n);
+top:
+   /* q = a/2**p, a = a mod 2**p */
+   if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
+      goto ERR;
+   }
+
+   /* q = q * d */
+   if ((res = mp_mul(&q, d, &q)) != MP_OKAY) {
+      goto ERR;
+   }
+
+   /* a = a + q */
+   if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
+      goto ERR;
+   }
+
+   if (mp_cmp_mag(a, n) != MP_LT) {
+      s_mp_sub(a, n, a);
+      goto top;
+   }
+
+ERR:
+   mp_clear(&q);
+   return res;
+}
+
+
+/* determines the setup value */
+int mp_reduce_2k_setup_l(mp_int *a, mp_int *d)
+{
+   int    res;
+   mp_int tmp;
+
+   if ((res = mp_init(&tmp)) != MP_OKAY) {
+      return res;
+   }
+
+   if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) {
+      goto ERR;
+   }
+
+   if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) {
+      goto ERR;
+   }
+
+ERR:
+   mp_clear(&tmp);
+   return res;
+}
+
+
+/* multiplies |a| * |b| and does not compute the lower digs digits
+ * [meant to get the higher part of the product]
+ */
+int
+s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+  mp_int  t;
+  int     res, pa, pb, ix, iy;
+  mp_digit u;
+  mp_word r;
+  mp_digit tmpx, *tmpt, *tmpy;
+
+  /* can we use the fast multiplier? */
+#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
+  if (((a->used + b->used + 1) < MP_WARRAY)
+      && MIN (a->used, b->used) <
+      (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+    return fast_s_mp_mul_high_digs (a, b, c, digs);
+  }
+#endif
+
+  if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) {
+    return res;
+  }
+  t.used = a->used + b->used + 1;
+
+  pa = a->used;
+  pb = b->used;
+  for (ix = 0; ix < pa; ix++) {
+    /* clear the carry */
+    u = 0;
+
+    /* left hand side of A[ix] * B[iy] */
+    tmpx = a->dp[ix];
+
+    /* alias to the address of where the digits will be stored */
+    tmpt = &(t.dp[digs]);
+
+    /* alias for where to read the right hand side from */
+    tmpy = b->dp + (digs - ix);
+
+    for (iy = digs - ix; iy < pb; iy++) {
+      /* calculate the double precision result */
+      r       = ((mp_word)*tmpt) +
+                ((mp_word)tmpx) * ((mp_word)*tmpy++) +
+                ((mp_word) u);
+
+      /* get the lower part */
+      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+      /* carry the carry */
+      u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+    }
+    *tmpt = u;
+  }
+  mp_clamp (&t);
+  mp_exch (&t, c);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+
+
+/* this is a modified version of fast_s_mul_digs that only produces
+ * output digits *above* digs.  See the comments for fast_s_mul_digs
+ * to see how it works.
+ *
+ * This is used in the Barrett reduction since for one of the multiplications
+ * only the higher digits were needed.  This essentially halves the work.
+ *
+ * Based on Algorithm 14.12 on pp.595 of HAC.
+ */
+int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+  int     olduse, res, pa, ix, iz;
+#ifdef WOLFSSL_SMALL_STACK
+  mp_digit* W;    /* uses dynamic memory and slower */
+#else
+  mp_digit W[MP_WARRAY];
+#endif
+  mp_word  _W;
+
+  /* grow the destination as required */
+  pa = a->used + b->used;
+  if (c->alloc < pa) {
+    if ((res = mp_grow (c, pa)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  if (pa > MP_WARRAY)
+    return MP_RANGE;  /* TAO range check */
+
+#ifdef WOLFSSL_SMALL_STACK
+  W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, 0, DYNAMIC_TYPE_BIGINT);
+  if (W == NULL)
+    return MP_MEM;
+#endif
+
+  /* number of output digits to produce */
+  pa = a->used + b->used;
+  _W = 0;
+  for (ix = digs; ix < pa; ix++) {
+      int      tx, ty, iy;
+      mp_digit *tmpx, *tmpy;
+
+      /* get offsets into the two bignums */
+      ty = MIN(b->used-1, ix);
+      tx = ix - ty;
+
+      /* setup temp aliases */
+      tmpx = a->dp + tx;
+      tmpy = b->dp + ty;
+
+      /* this is the number of times the loop will iterrate, essentially its
+         while (tx++ < a->used && ty-- >= 0) { ... }
+       */
+      iy = MIN(a->used-tx, ty+1);
+
+      /* execute loop */
+      for (iz = 0; iz < iy; iz++) {
+         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+      }
+
+      /* store term */
+      W[ix] = ((mp_digit)_W) & MP_MASK;
+
+      /* make next carry */
+      _W = _W >> ((mp_word)DIGIT_BIT);
+  }
+
+  /* setup dest */
+  olduse  = c->used;
+  c->used = pa;
+
+  {
+    register mp_digit *tmpc;
+
+    tmpc = c->dp + digs;
+    for (ix = digs; ix <= pa; ix++) {
+      /* now extract the previous digit [below the carry] */
+      *tmpc++ = W[ix];
+    }
+
+    /* clear unused digits [that existed in the old copy of c] */
+    for (; ix < olduse; ix++) {
+      *tmpc++ = 0;
+    }
+  }
+  mp_clamp (c);
+
+#ifdef WOLFSSL_SMALL_STACK
+  XFREE(W, 0, DYNAMIC_TYPE_BIGINT);
+#endif
+
+  return MP_OKAY;
+}
+
+
+/* set a 32-bit const */
+int mp_set_int (mp_int * a, unsigned long b)
+{
+  int     x, res;
+
+  mp_zero (a);
+
+  /* set four bits at a time */
+  for (x = 0; x < 8; x++) {
+    /* shift the number up four bits */
+    if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
+      return res;
+    }
+
+    /* OR in the top four bits of the source */
+    a->dp[0] |= (b >> 28) & 15;
+
+    /* shift the source up to the next four bits */
+    b <<= 4;
+
+    /* ensure that digits are not clamped off */
+    a->used += 1;
+  }
+  mp_clamp (a);
+  return MP_OKAY;
+}
+
+
+#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_ECC)
+
+/* c = a * a (mod b) */
+int mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res;
+  mp_int  t;
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_sqr (a, &t)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+  res = mp_mod (&t, b, c);
+  mp_clear (&t);
+  return res;
+}
+
+#endif
+
+
+#if defined(HAVE_ECC) || !defined(NO_PWDBASED) || defined(WOLFSSL_SNIFFER) || \
+    defined(WOLFSSL_HAVE_WOLFSCEP) || defined(WOLFSSL_KEY_GEN)
+
+/* single digit addition */
+int mp_add_d (mp_int* a, mp_digit b, mp_int* c)
+{
+  int     res, ix, oldused;
+  mp_digit *tmpa, *tmpc, mu;
+
+  /* grow c as required */
+  if (c->alloc < a->used + 1) {
+     if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
+        return res;
+     }
+  }
+
+  /* if a is negative and |a| >= b, call c = |a| - b */
+  if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
+     /* temporarily fix sign of a */
+     a->sign = MP_ZPOS;
+
+     /* c = |a| - b */
+     res = mp_sub_d(a, b, c);
+
+     /* fix sign  */
+     a->sign = c->sign = MP_NEG;
+
+     /* clamp */
+     mp_clamp(c);
+
+     return res;
+  }
+
+  /* old number of used digits in c */
+  oldused = c->used;
+
+  /* sign always positive */
+  c->sign = MP_ZPOS;
+
+  /* source alias */
+  tmpa    = a->dp;
+
+  /* destination alias */
+  tmpc    = c->dp;
+
+  /* if a is positive */
+  if (a->sign == MP_ZPOS) {
+     /* add digit, after this we're propagating
+      * the carry.
+      */
+     *tmpc   = *tmpa++ + b;
+     mu      = *tmpc >> DIGIT_BIT;
+     *tmpc++ &= MP_MASK;
+
+     /* now handle rest of the digits */
+     for (ix = 1; ix < a->used; ix++) {
+        *tmpc   = *tmpa++ + mu;
+        mu      = *tmpc >> DIGIT_BIT;
+        *tmpc++ &= MP_MASK;
+     }
+     /* set final carry */
+     if (ix < c->alloc) {
+        ix++;
+        *tmpc++  = mu;
+     }
+
+     /* setup size */
+     c->used = a->used + 1;
+  } else {
+     /* a was negative and |a| < b */
+     c->used  = 1;
+
+     /* the result is a single digit */
+     if (a->used == 1) {
+        *tmpc++  =  b - a->dp[0];
+     } else {
+        *tmpc++  =  b;
+     }
+
+     /* setup count so the clearing of oldused
+      * can fall through correctly
+      */
+     ix       = 1;
+  }
+
+  /* now zero to oldused */
+  while (ix++ < oldused) {
+     *tmpc++ = 0;
+  }
+  mp_clamp(c);
+
+  return MP_OKAY;
+}
+
+
+/* single digit subtraction */
+int mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
+{
+  mp_digit *tmpa, *tmpc, mu;
+  int       res, ix, oldused;
+
+  /* grow c as required */
+  if (c->alloc < a->used + 1) {
+     if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
+        return res;
+     }
+  }
+
+  /* if a is negative just do an unsigned
+   * addition [with fudged signs]
+   */
+  if (a->sign == MP_NEG) {
+     a->sign = MP_ZPOS;
+     res     = mp_add_d(a, b, c);
+     a->sign = c->sign = MP_NEG;
+
+     /* clamp */
+     mp_clamp(c);
+
+     return res;
+  }
+
+  /* setup regs */
+  oldused = c->used;
+  tmpa    = a->dp;
+  tmpc    = c->dp;
+
+  /* if a <= b simply fix the single digit */
+  if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
+     if (a->used == 1) {
+        *tmpc++ = b - *tmpa;
+     } else {
+        *tmpc++ = b;
+     }
+     ix      = 1;
+
+     /* negative/1digit */
+     c->sign = MP_NEG;
+     c->used = 1;
+  } else {
+     /* positive/size */
+     c->sign = MP_ZPOS;
+     c->used = a->used;
+
+     /* subtract first digit */
+     *tmpc    = *tmpa++ - b;
+     mu       = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
+     *tmpc++ &= MP_MASK;
+
+     /* handle rest of the digits */
+     for (ix = 1; ix < a->used; ix++) {
+        *tmpc    = *tmpa++ - mu;
+        mu       = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
+        *tmpc++ &= MP_MASK;
+     }
+  }
+
+  /* zero excess digits */
+  while (ix++ < oldused) {
+     *tmpc++ = 0;
+  }
+  mp_clamp(c);
+  return MP_OKAY;
+}
+
+#endif /* defined(HAVE_ECC) || !defined(NO_PWDBASED) */
+
+
+#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(HAVE_ECC)
+
+static const int lnz[16] = {
+   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+};
+
+/* Counts the number of lsbs which are zero before the first zero bit */
+int mp_cnt_lsb(mp_int *a)
+{
+    int x;
+    mp_digit q, qq;
+
+    /* easy out */
+    if (mp_iszero(a) == 1) {
+        return 0;
+    }
+
+    /* scan lower digits until non-zero */
+    for (x = 0; x < a->used && a->dp[x] == 0; x++);
+    q = a->dp[x];
+    x *= DIGIT_BIT;
+
+    /* now scan this digit until a 1 is found */
+    if ((q & 1) == 0) {
+        do {
+            qq  = q & 15;
+            x  += lnz[qq];
+            q >>= 4;
+        } while (qq == 0);
+    }
+    return x;
+}
+
+
+
+
+static int s_is_power_of_two(mp_digit b, int *p)
+{
+   int x;
+
+   /* fast return if no power of two */
+   if ((b==0) || (b & (b-1))) {
+      return 0;
+   }
+
+   for (x = 0; x < DIGIT_BIT; x++) {
+      if (b == (((mp_digit)1)<<x)) {
+         *p = x;
+         return 1;
+      }
+   }
+   return 0;
+}
+
+/* single digit division (based on routine from MPI) */
+static int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
+{
+  mp_int  q;
+  mp_word w;
+  mp_digit t;
+  int     res = MP_OKAY, ix;
+
+  /* cannot divide by zero */
+  if (b == 0) {
+     return MP_VAL;
+  }
+
+  /* quick outs */
+  if (b == 1 || mp_iszero(a) == 1) {
+     if (d != NULL) {
+        *d = 0;
+     }
+     if (c != NULL) {
+        return mp_copy(a, c);
+     }
+     return MP_OKAY;
+  }
+
+  /* power of two ? */
+  if (s_is_power_of_two(b, &ix) == 1) {
+     if (d != NULL) {
+        *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
+     }
+     if (c != NULL) {
+        return mp_div_2d(a, ix, c, NULL);
+     }
+     return MP_OKAY;
+  }
+
+#ifdef BN_MP_DIV_3_C
+  /* three? */
+  if (b == 3) {
+     return mp_div_3(a, c, d);
+  }
+#endif
+
+  /* no easy answer [c'est la vie].  Just division */
+  if (c != NULL) {
+      if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
+        return res;
+      }
+
+      q.used = a->used;
+      q.sign = a->sign;
+  }
+
+  w = 0;
+  for (ix = a->used - 1; ix >= 0; ix--) {
+     w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
+
+     if (w >= b) {
+        t = (mp_digit)(w / b);
+        w -= ((mp_word)t) * ((mp_word)b);
+      } else {
+        t = 0;
+      }
+      if (c != NULL)
+        q.dp[ix] = (mp_digit)t;
+  }
+
+  if (d != NULL) {
+     *d = (mp_digit)w;
+  }
+
+  if (c != NULL) {
+     mp_clamp(&q);
+     mp_exch(&q, c);
+     mp_clear(&q);
+  }
+
+  return res;
+}
+
+
+int mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
+{
+  return mp_div_d(a, b, NULL, c);
+}
+
+#endif /* defined(WOLFSSL_KEY_GEN)||defined(HAVE_COMP_KEY)||defined(HAVE_ECC) */
+
+#ifdef WOLFSSL_KEY_GEN
+
+const mp_digit ltm_prime_tab[] = {
+  0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
+  0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
+  0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
+  0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
+#ifndef MP_8BIT
+  0x0083,
+  0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
+  0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
+  0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
+  0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
+
+  0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
+  0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
+  0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
+  0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
+  0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
+  0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
+  0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
+  0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
+
+  0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
+  0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
+  0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
+  0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
+  0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
+  0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
+  0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
+  0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
+
+  0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
+  0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
+  0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
+  0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
+  0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
+  0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
+  0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
+  0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
+#endif
+};
+
+
+/* Miller-Rabin test of "a" to the base of "b" as described in
+ * HAC pp. 139 Algorithm 4.24
+ *
+ * Sets result to 0 if definitely composite or 1 if probably prime.
+ * Randomly the chance of error is no more than 1/4 and often
+ * very much lower.
+ */
+static int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
+{
+  mp_int  n1, y, r;
+  int     s, j, err;
+
+  /* default */
+  *result = MP_NO;
+
+  /* ensure b > 1 */
+  if (mp_cmp_d(b, 1) != MP_GT) {
+     return MP_VAL;
+  }
+
+  /* get n1 = a - 1 */
+  if ((err = mp_init_copy (&n1, a)) != MP_OKAY) {
+    return err;
+  }
+  if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) {
+    goto LBL_N1;
+  }
+
+  /* set 2**s * r = n1 */
+  if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) {
+    goto LBL_N1;
+  }
+
+  /* count the number of least significant bits
+   * which are zero
+   */
+  s = mp_cnt_lsb(&r);
+
+  /* now divide n - 1 by 2**s */
+  if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
+    goto LBL_R;
+  }
+
+  /* compute y = b**r mod a */
+  if ((err = mp_init (&y)) != MP_OKAY) {
+    goto LBL_R;
+  }
+  if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) {
+    goto LBL_Y;
+  }
+
+  /* if y != 1 and y != n1 do */
+  if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) {
+    j = 1;
+    /* while j <= s-1 and y != n1 */
+    while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) {
+      if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) {
+         goto LBL_Y;
+      }
+
+      /* if y == 1 then composite */
+      if (mp_cmp_d (&y, 1) == MP_EQ) {
+         goto LBL_Y;
+      }
+
+      ++j;
+    }
+
+    /* if y != n1 then composite */
+    if (mp_cmp (&y, &n1) != MP_EQ) {
+      goto LBL_Y;
+    }
+  }
+
+  /* probably prime now */
+  *result = MP_YES;
+LBL_Y:mp_clear (&y);
+LBL_R:mp_clear (&r);
+LBL_N1:mp_clear (&n1);
+  return err;
+}
+
+
+/* determines if an integers is divisible by one
+ * of the first PRIME_SIZE primes or not
+ *
+ * sets result to 0 if not, 1 if yes
+ */
+static int mp_prime_is_divisible (mp_int * a, int *result)
+{
+  int     err, ix;
+  mp_digit res;
+
+  /* default to not */
+  *result = MP_NO;
+
+  for (ix = 0; ix < PRIME_SIZE; ix++) {
+    /* what is a mod LBL_prime_tab[ix] */
+    if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) {
+      return err;
+    }
+
+    /* is the residue zero? */
+    if (res == 0) {
+      *result = MP_YES;
+      return MP_OKAY;
+    }
+  }
+
+  return MP_OKAY;
+}
+
+static const int USE_BBS = 1;
+
+int mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap)
+{
+    int   err, res, type;
+    byte* buf;
+
+    if (N == NULL || rng == NULL)
+        return MP_VAL;
+
+    /* get type */
+    if (len < 0) {
+        type = USE_BBS;
+        len = -len;
+    } else {
+        type = 0;
+    }
+
+    /* allow sizes between 2 and 512 bytes for a prime size */
+    if (len < 2 || len > 512) {
+        return MP_VAL;
+    }
+
+    /* allocate buffer to work with */
+    buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_RSA);
+    if (buf == NULL) {
+        return MP_MEM;
+    }
+    XMEMSET(buf, 0, len);
+
+    do {
+#ifdef SHOW_GEN
+        printf(".");
+        fflush(stdout);
+#endif
+        /* generate value */
+        err = wc_RNG_GenerateBlock(rng, buf, len);
+        if (err != 0) {
+            XFREE(buf, heap, DYNAMIC_TYPE_RSA);
+            return err;
+        }
+
+        /* munge bits */
+        buf[0]     |= 0x80 | 0x40;
+        buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);
+
+        /* load value */
+        if ((err = mp_read_unsigned_bin(N, buf, len)) != MP_OKAY) {
+            XFREE(buf, heap, DYNAMIC_TYPE_RSA);
+            return err;
+        }
+
+        /* test */
+        if ((err = mp_prime_is_prime(N, 8, &res)) != MP_OKAY) {
+            XFREE(buf, heap, DYNAMIC_TYPE_RSA);
+            return err;
+        }
+    } while (res == MP_NO);
+
+    XMEMSET(buf, 0, len);
+    XFREE(buf, heap, DYNAMIC_TYPE_RSA);
+    
+    return MP_OKAY;
+}
+
+/*
+ * Sets result to 1 if probably prime, 0 otherwise
+ */
+int mp_prime_is_prime (mp_int * a, int t, int *result)
+{
+  mp_int  b;
+  int     ix, err, res;
+
+  /* default to no */
+  *result = MP_NO;
+
+  /* valid value of t? */
+  if (t <= 0 || t > PRIME_SIZE) {
+    return MP_VAL;
+  }
+
+  /* is the input equal to one of the primes in the table? */
+  for (ix = 0; ix < PRIME_SIZE; ix++) {
+      if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
+         *result = 1;
+         return MP_OKAY;
+      }
+  }
+
+  /* first perform trial division */
+  if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
+    return err;
+  }
+
+  /* return if it was trivially divisible */
+  if (res == MP_YES) {
+    return MP_OKAY;
+  }
+
+  /* now perform the miller-rabin rounds */
+  if ((err = mp_init (&b)) != MP_OKAY) {
+    return err;
+  }
+
+  for (ix = 0; ix < t; ix++) {
+    /* set the prime */
+    mp_set (&b, ltm_prime_tab[ix]);
+
+    if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
+      goto LBL_B;
+    }
+
+    if (res == MP_NO) {
+      goto LBL_B;
+    }
+  }
+
+  /* passed the test */
+  *result = MP_YES;
+LBL_B:mp_clear (&b);
+  return err;
+}
+
+
+/* computes least common multiple as |a*b|/(a, b) */
+int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res;
+  mp_int  t1, t2;
+
+
+  if ((res = mp_init_multi (&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
+    return res;
+  }
+
+  /* t1 = get the GCD of the two inputs */
+  if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
+    goto LBL_T;
+  }
+
+  /* divide the smallest by the GCD */
+  if (mp_cmp_mag(a, b) == MP_LT) {
+     /* store quotient in t2 such that t2 * b is the LCM */
+     if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
+        goto LBL_T;
+     }
+     res = mp_mul(b, &t2, c);
+  } else {
+     /* store quotient in t2 such that t2 * a is the LCM */
+     if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
+        goto LBL_T;
+     }
+     res = mp_mul(a, &t2, c);
+  }
+
+  /* fix the sign to positive */
+  c->sign = MP_ZPOS;
+
+LBL_T:
+  mp_clear(&t1);
+  mp_clear(&t2);
+  return res;
+}
+
+
+
+/* Greatest Common Divisor using the binary method */
+int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
+{
+    mp_int  u, v;
+    int     k, u_lsb, v_lsb, res;
+
+    /* either zero than gcd is the largest */
+    if (mp_iszero (a) == MP_YES) {
+        return mp_abs (b, c);
+    }
+    if (mp_iszero (b) == MP_YES) {
+        return mp_abs (a, c);
+    }
+
+    /* get copies of a and b we can modify */
+    if ((res = mp_init_copy (&u, a)) != MP_OKAY) {
+        return res;
+    }
+
+    if ((res = mp_init_copy (&v, b)) != MP_OKAY) {
+        goto LBL_U;
+    }
+
+    /* must be positive for the remainder of the algorithm */
+    u.sign = v.sign = MP_ZPOS;
+
+    /* B1.  Find the common power of two for u and v */
+    u_lsb = mp_cnt_lsb(&u);
+    v_lsb = mp_cnt_lsb(&v);
+    k     = MIN(u_lsb, v_lsb);
+
+    if (k > 0) {
+        /* divide the power of two out */
+        if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
+            goto LBL_V;
+        }
+
+        if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
+            goto LBL_V;
+        }
+    }
+
+    /* divide any remaining factors of two out */
+    if (u_lsb != k) {
+        if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
+            goto LBL_V;
+        }
+    }
+
+    if (v_lsb != k) {
+        if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
+            goto LBL_V;
+        }
+    }
+
+    while (mp_iszero(&v) == 0) {
+        /* make sure v is the largest */
+        if (mp_cmp_mag(&u, &v) == MP_GT) {
+            /* swap u and v to make sure v is >= u */
+            mp_exch(&u, &v);
+        }
+
+        /* subtract smallest from largest */
+        if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
+            goto LBL_V;
+        }
+
+        /* Divide out all factors of two */
+        if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
+            goto LBL_V;
+        }
+    }
+
+    /* multiply by 2**k which we divided out at the beginning */
+    if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {
+        goto LBL_V;
+    }
+    c->sign = MP_ZPOS;
+    res = MP_OKAY;
+LBL_V:mp_clear (&u);
+LBL_U:mp_clear (&v);
+    return res;
+}
+
+#endif /* WOLFSSL_KEY_GEN */
+
+
+#if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
+
+/* chars used in radix conversions */
+const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+                         abcdefghijklmnopqrstuvwxyz+/";
+#endif
+
+#ifdef HAVE_ECC
+/* read a string [ASCII] in a given radix */
+int mp_read_radix (mp_int * a, const char *str, int radix)
+{
+  int     y, res, neg;
+  char    ch;
+
+  /* zero the digit bignum */
+  mp_zero(a);
+
+  /* make sure the radix is ok */
+  if (radix < 2 || radix > 64) {
+    return MP_VAL;
+  }
+
+  /* if the leading digit is a
+   * minus set the sign to negative.
+   */
+  if (*str == '-') {
+    ++str;
+    neg = MP_NEG;
+  } else {
+    neg = MP_ZPOS;
+  }
+
+  /* set the integer to the default of zero */
+  mp_zero (a);
+
+  /* process each digit of the string */
+  while (*str) {
+    /* if the radix < 36 the conversion is case insensitive
+     * this allows numbers like 1AB and 1ab to represent the same  value
+     * [e.g. in hex]
+     */
+    ch = (char) ((radix < 36) ? XTOUPPER((unsigned char)*str) : *str);
+    for (y = 0; y < 64; y++) {
+      if (ch == mp_s_rmap[y]) {
+         break;
+      }
+    }
+
+    /* if the char was found in the map
+     * and is less than the given radix add it
+     * to the number, otherwise exit the loop.
+     */
+    if (y < radix) {
+      if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {
+         return res;
+      }
+      if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {
+         return res;
+      }
+    } else {
+      break;
+    }
+    ++str;
+  }
+
+  /* set the sign only if a != 0 */
+  if (mp_iszero(a) != 1) {
+     a->sign = neg;
+  }
+  return MP_OKAY;
+}
+#endif /* HAVE_ECC */
+
+#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
+
+/* returns size of ASCII representation */
+int mp_radix_size (mp_int *a, int radix, int *size)
+{
+    int     res, digs;
+    mp_int  t;
+    mp_digit d;
+
+    *size = 0;
+
+    /* special case for binary */
+    if (radix == 2) {
+        *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
+        return MP_OKAY;
+    }
+
+    /* make sure the radix is in range */
+    if (radix < 2 || radix > 64) {
+        return MP_VAL;
+    }
+
+    if (mp_iszero(a) == MP_YES) {
+        *size = 2;
+        return MP_OKAY;
+    }
+
+    /* digs is the digit count */
+    digs = 0;
+
+    /* if it's negative add one for the sign */
+    if (a->sign == MP_NEG) {
+        ++digs;
+    }
+
+    /* init a copy of the input */
+    if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+        return res;
+    }
+
+    /* force temp to positive */
+    t.sign = MP_ZPOS;
+
+    /* fetch out all of the digits */
+    while (mp_iszero (&t) == MP_NO) {
+        if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+            mp_clear (&t);
+            return res;
+        }
+        ++digs;
+    }
+    mp_clear (&t);
+
+    /* return digs + 1, the 1 is for the NULL byte that would be required. */
+    *size = digs + 1;
+    return MP_OKAY;
+}
+
+/* stores a bignum as a ASCII string in a given radix (2..64) */
+int mp_toradix (mp_int *a, char *str, int radix)
+{
+    int     res, digs;
+    mp_int  t;
+    mp_digit d;
+    char   *_s = str;
+
+    /* check range of the radix */
+    if (radix < 2 || radix > 64) {
+        return MP_VAL;
+    }
+
+    /* quick out if its zero */
+    if (mp_iszero(a) == 1) {
+        *str++ = '0';
+        *str = '\0';
+        return MP_OKAY;
+    }
+
+    if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+        return res;
+    }
+
+    /* if it is negative output a - */
+    if (t.sign == MP_NEG) {
+        ++_s;
+        *str++ = '-';
+        t.sign = MP_ZPOS;
+    }
+
+    digs = 0;
+    while (mp_iszero (&t) == 0) {
+        if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+            mp_clear (&t);
+            return res;
+        }
+        *str++ = mp_s_rmap[d];
+        ++digs;
+    }
+
+    /* reverse the digits of the string.  In this case _s points
+     * to the first digit [exluding the sign] of the number]
+     */
+    bn_reverse ((unsigned char *)_s, digs);
+
+    /* append a NULL so the string is properly terminated */
+    *str = '\0';
+
+    mp_clear (&t);
+    return MP_OKAY;
+}
+
+#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
+
+#endif /* USE_FAST_MATH */
+
+#endif /* NO_BIG_INT */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/logging.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/logging.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/logging.c	(revision 164)
@@ -0,0 +1,166 @@
+/* logging.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+/* submitted by eof */
+
+#include <wolfssl/wolfcrypt/logging.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+    WOLFSSL_API int  wolfSSL_Debugging_ON(void);
+    WOLFSSL_API void wolfSSL_Debugging_OFF(void);
+#ifdef __cplusplus
+    } 
+#endif
+
+
+#ifdef DEBUG_WOLFSSL
+
+/* Set these to default values initially. */
+static wolfSSL_Logging_cb log_function = 0;
+static int loggingEnabled = 0;
+
+#endif /* DEBUG_WOLFSSL */
+
+
+int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb f)
+{
+#ifdef DEBUG_WOLFSSL
+    int res = 0;
+
+    if (f)
+        log_function = f;
+    else
+        res = BAD_FUNC_ARG;
+
+    return res;
+#else
+    (void)f;
+    return NOT_COMPILED_IN;
+#endif
+}
+
+
+int wolfSSL_Debugging_ON(void)
+{
+#ifdef DEBUG_WOLFSSL
+    loggingEnabled = 1;
+    return 0;
+#else
+    return NOT_COMPILED_IN;
+#endif
+}
+
+
+void wolfSSL_Debugging_OFF(void)
+{
+#ifdef DEBUG_WOLFSSL
+    loggingEnabled = 0;
+#endif
+}
+
+
+#ifdef DEBUG_WOLFSSL
+
+#ifdef FREESCALE_MQX
+    #if MQX_USE_IO_OLD
+        #include <fio.h>
+    #else
+        #include <nio.h>
+    #endif
+#else
+    #include <stdio.h>   /* for default printf stuff */
+#endif
+
+#ifdef THREADX
+    int dc_log_printf(char*, ...);
+#endif
+
+static void wolfssl_log(const int logLevel, const char *const logMessage)
+{
+    if (log_function)
+        log_function(logLevel, logMessage);
+    else {
+        if (loggingEnabled) {
+#ifdef THREADX
+            dc_log_printf("%s\n", logMessage);
+#elif defined(MICRIUM)
+        #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
+            NetSecure_TraceOut((CPU_CHAR *)logMessage);
+        #endif
+#elif defined(WOLFSSL_MDK_ARM)
+            fflush(stdout) ;
+            printf("%s\n", logMessage);
+            fflush(stdout) ;
+#else
+            fprintf(stderr, "%s\n", logMessage);
+#endif
+        }
+    }
+}
+
+
+void WOLFSSL_MSG(const char* msg)
+{
+    if (loggingEnabled)
+        wolfssl_log(INFO_LOG , msg);
+}
+
+
+void WOLFSSL_ENTER(const char* msg)
+{
+    if (loggingEnabled) {
+        char buffer[80];
+        sprintf(buffer, "wolfSSL Entering %s", msg);
+        wolfssl_log(ENTER_LOG , buffer);
+    }
+}
+
+
+void WOLFSSL_LEAVE(const char* msg, int ret)
+{
+    if (loggingEnabled) {
+        char buffer[80];
+        sprintf(buffer, "wolfSSL Leaving %s, return %d", msg, ret);
+        wolfssl_log(LEAVE_LOG , buffer);
+    }
+}
+
+
+void WOLFSSL_ERROR(int error)
+{
+    if (loggingEnabled) {
+        char buffer[80];
+        sprintf(buffer, "wolfSSL error occured, error = %d", error);
+        wolfssl_log(ERROR_LOG , buffer);
+    }
+}
+
+#endif  /* DEBUG_WOLFSSL */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/md4.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/md4.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/md4.c	(revision 164)
@@ -0,0 +1,223 @@
+/* md4.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_MD4
+
+#include <wolfssl/wolfcrypt/md4.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+
+#ifdef min
+#define WOLFSSL_HAVE_MIN
+#endif
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+
+#endif /* WOLFSSL_HAVE_MIN */
+
+
+void wc_InitMd4(Md4* md4)
+{
+    md4->digest[0] = 0x67452301L;
+    md4->digest[1] = 0xefcdab89L;
+    md4->digest[2] = 0x98badcfeL;
+    md4->digest[3] = 0x10325476L;
+
+    md4->buffLen = 0;
+    md4->loLen   = 0;
+    md4->hiLen   = 0;
+}
+
+
+static void Transform(Md4* md4)
+{
+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+
+    /* Copy context->state[] to working vars  */
+    word32 A = md4->digest[0];
+    word32 B = md4->digest[1];
+    word32 C = md4->digest[2];
+    word32 D = md4->digest[3];
+
+#define function(a,b,c,d,k,s) a=rotlFixed(a+F(b,c,d)+md4->buffer[k],s);
+    function(A,B,C,D, 0, 3);
+    function(D,A,B,C, 1, 7);
+    function(C,D,A,B, 2,11);
+    function(B,C,D,A, 3,19);
+    function(A,B,C,D, 4, 3);
+    function(D,A,B,C, 5, 7);
+    function(C,D,A,B, 6,11);
+    function(B,C,D,A, 7,19);
+    function(A,B,C,D, 8, 3);
+    function(D,A,B,C, 9, 7);
+    function(C,D,A,B,10,11);
+    function(B,C,D,A,11,19);
+    function(A,B,C,D,12, 3);
+    function(D,A,B,C,13, 7);
+    function(C,D,A,B,14,11);
+    function(B,C,D,A,15,19);
+
+#undef function	  
+#define function(a,b,c,d,k,s) \
+    a=rotlFixed(a+G(b,c,d)+md4->buffer[k]+0x5a827999,s);
+
+    function(A,B,C,D, 0, 3);
+    function(D,A,B,C, 4, 5);
+    function(C,D,A,B, 8, 9);
+    function(B,C,D,A,12,13);
+    function(A,B,C,D, 1, 3);
+    function(D,A,B,C, 5, 5);
+    function(C,D,A,B, 9, 9);
+    function(B,C,D,A,13,13);
+    function(A,B,C,D, 2, 3);
+    function(D,A,B,C, 6, 5);
+    function(C,D,A,B,10, 9);
+    function(B,C,D,A,14,13);
+    function(A,B,C,D, 3, 3);
+    function(D,A,B,C, 7, 5);
+    function(C,D,A,B,11, 9);
+    function(B,C,D,A,15,13);
+
+#undef function	 
+#define function(a,b,c,d,k,s) \
+    a=rotlFixed(a+H(b,c,d)+md4->buffer[k]+0x6ed9eba1,s);
+
+    function(A,B,C,D, 0, 3);
+    function(D,A,B,C, 8, 9);
+    function(C,D,A,B, 4,11);
+    function(B,C,D,A,12,15);
+    function(A,B,C,D, 2, 3);
+    function(D,A,B,C,10, 9);
+    function(C,D,A,B, 6,11);
+    function(B,C,D,A,14,15);
+    function(A,B,C,D, 1, 3);
+    function(D,A,B,C, 9, 9);
+    function(C,D,A,B, 5,11);
+    function(B,C,D,A,13,15);
+    function(A,B,C,D, 3, 3);
+    function(D,A,B,C,11, 9);
+    function(C,D,A,B, 7,11);
+    function(B,C,D,A,15,15);
+    
+    /* Add the working vars back into digest state[]  */
+    md4->digest[0] += A;
+    md4->digest[1] += B;
+    md4->digest[2] += C;
+    md4->digest[3] += D;
+}
+
+
+static INLINE void AddLength(Md4* md4, word32 len)
+{
+    word32 tmp = md4->loLen;
+    if ( (md4->loLen += len) < tmp)
+        md4->hiLen++;                       /* carry low to high */
+}
+
+
+void wc_Md4Update(Md4* md4, const byte* data, word32 len)
+{
+    /* do block size increments */
+    byte* local = (byte*)md4->buffer;
+
+    while (len) {
+        word32 add = min(len, MD4_BLOCK_SIZE - md4->buffLen);
+        XMEMCPY(&local[md4->buffLen], data, add);
+
+        md4->buffLen += add;
+        data         += add;
+        len          -= add;
+
+        if (md4->buffLen == MD4_BLOCK_SIZE) {
+            #ifdef BIG_ENDIAN_ORDER
+                ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE);
+            #endif
+            Transform(md4);
+            AddLength(md4, MD4_BLOCK_SIZE);
+            md4->buffLen = 0;
+        }
+    }
+}
+
+
+void wc_Md4Final(Md4* md4, byte* hash)
+{
+    byte* local = (byte*)md4->buffer;
+
+    AddLength(md4, md4->buffLen);               /* before adding pads */
+
+    local[md4->buffLen++] = 0x80;  /* add 1 */
+
+    /* pad with zeros */
+    if (md4->buffLen > MD4_PAD_SIZE) {
+        XMEMSET(&local[md4->buffLen], 0, MD4_BLOCK_SIZE - md4->buffLen);
+        md4->buffLen += MD4_BLOCK_SIZE - md4->buffLen;
+
+        #ifdef BIG_ENDIAN_ORDER
+            ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE);
+        #endif
+        Transform(md4);
+        md4->buffLen = 0;
+    }
+    XMEMSET(&local[md4->buffLen], 0, MD4_PAD_SIZE - md4->buffLen);
+   
+    /* put lengths in bits */
+    md4->hiLen = (md4->loLen >> (8*sizeof(md4->loLen) - 3)) + 
+                 (md4->hiLen << 3);
+    md4->loLen = md4->loLen << 3;
+
+    /* store lengths */
+    #ifdef BIG_ENDIAN_ORDER
+        ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE);
+    #endif
+    /* ! length ordering dependent on digest endian type ! */
+    XMEMCPY(&local[MD4_PAD_SIZE], &md4->loLen, sizeof(word32));
+    XMEMCPY(&local[MD4_PAD_SIZE + sizeof(word32)], &md4->hiLen, sizeof(word32));
+
+    Transform(md4);
+    #ifdef BIG_ENDIAN_ORDER
+        ByteReverseWords(md4->digest, md4->digest, MD4_DIGEST_SIZE);
+    #endif
+    XMEMCPY(hash, md4->digest, MD4_DIGEST_SIZE);
+
+    wc_InitMd4(md4);  /* reset state */
+}
+
+
+#endif /* NO_MD4 */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/md5.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/md5.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/md5.c	(revision 164)
@@ -0,0 +1,412 @@
+/* md5.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#if !defined(NO_MD5)
+
+#if defined(WOLFSSL_TI_HASH)
+    /* #include <wolfcrypt/src/port/ti/ti-hash.c> included by wc_port.c */
+#else
+
+#ifdef WOLFSSL_PIC32MZ_HASH
+#define wc_InitMd5   wc_InitMd5_sw
+#define wc_Md5Update wc_Md5Update_sw
+#define wc_Md5Final  wc_Md5Final_sw
+#endif
+
+#include <wolfssl/wolfcrypt/md5.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+#ifdef FREESCALE_MMCAU
+    #include "cau_api.h"
+    #define XTRANSFORM(S,B)  Transform((S), (B))
+#else
+    #define XTRANSFORM(S,B)  Transform((S))
+#endif
+
+
+#ifdef STM32F2_HASH
+    /*
+     * STM32F2 hardware MD5 support through the STM32F2 standard peripheral
+     * library. Documentation located in STM32F2xx Standard Peripheral Library
+     * document (See note in README).
+     */
+    #include "stm32f2xx.h"
+
+    void wc_InitMd5(Md5* md5)
+    {
+        /* STM32F2 struct notes:
+         * md5->buffer  = first 4 bytes used to hold partial block if needed 
+         * md5->buffLen = num bytes currently stored in md5->buffer
+         * md5->loLen   = num bytes that have been written to STM32 FIFO
+         */
+        XMEMSET(md5->buffer, 0, MD5_REG_SIZE);
+			
+        md5->buffLen = 0;
+        md5->loLen = 0;
+
+        /* initialize HASH peripheral */
+        HASH_DeInit();
+
+        /* configure algo used, algo mode, datatype */
+        HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE);
+        HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HASH 
+                 | HASH_DataType_8b);
+
+        /* reset HASH processor */
+        HASH->CR |= HASH_CR_INIT;
+    }
+
+    void wc_Md5Update(Md5* md5, const byte* data, word32 len)
+    {
+        word32 i = 0;
+        word32 fill = 0;
+        word32 diff = 0;
+
+        /* if saved partial block is available */
+        if (md5->buffLen > 0) {
+            fill = 4 - md5->buffLen;
+
+            /* if enough data to fill, fill and push to FIFO */
+            if (fill <= len) {
+                XMEMCPY((byte*)md5->buffer + md5->buffLen, data, fill);
+                HASH_DataIn(*(uint32_t*)md5->buffer);
+
+                data += fill;
+                len -= fill;
+                md5->loLen += 4;
+                md5->buffLen = 0;
+            } else {
+                /* append partial to existing stored block */
+                XMEMCPY((byte*)md5->buffer + md5->buffLen, data, len);
+                md5->buffLen += len;
+                return;
+            }
+        }
+
+        /* write input block in the IN FIFO */
+        for (i = 0; i < len; i += 4)
+        {
+            diff = len - i;
+            if (diff < 4) {
+                /* store incomplete last block, not yet in FIFO */
+                XMEMSET(md5->buffer, 0, MD5_REG_SIZE);
+                XMEMCPY((byte*)md5->buffer, data, diff);
+                md5->buffLen = diff;
+            } else {
+                HASH_DataIn(*(uint32_t*)data);
+                data+=4;
+            }
+        }
+
+        /* keep track of total data length thus far */
+        md5->loLen += (len - md5->buffLen);
+    }
+
+    void wc_Md5Final(Md5* md5, byte* hash)
+    {
+        __IO uint16_t nbvalidbitsdata = 0;
+
+        /* finish reading any trailing bytes into FIFO */
+        if (md5->buffLen > 0) {
+            HASH_DataIn(*(uint32_t*)md5->buffer);
+            md5->loLen += md5->buffLen;
+        }
+
+        /* calculate number of valid bits in last word of input data */
+        nbvalidbitsdata = 8 * (md5->loLen % MD5_REG_SIZE);
+
+        /* configure number of valid bits in last word of the data */
+        HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
+
+        /* start HASH processor */
+        HASH_StartDigest();
+
+        /* wait until Busy flag == RESET */
+        while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {}
+        
+        /* read message digest */
+        md5->digest[0] = HASH->HR[0];
+        md5->digest[1] = HASH->HR[1];
+        md5->digest[2] = HASH->HR[2];
+        md5->digest[3] = HASH->HR[3];
+
+        ByteReverseWords(md5->digest, md5->digest, MD5_DIGEST_SIZE);
+
+        XMEMCPY(hash, md5->digest, MD5_DIGEST_SIZE);
+
+        wc_InitMd5(md5);  /* reset state */
+    }
+
+#else /* CTaoCrypt software implementation */
+
+#ifdef min
+#define WOLFSSL_HAVE_MIN
+#endif
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+
+#endif /* WOLFSSL_HAVE_MIN */
+
+void wc_InitMd5(Md5* md5)
+{
+    md5->digest[0] = 0x67452301L;
+    md5->digest[1] = 0xefcdab89L;
+    md5->digest[2] = 0x98badcfeL;
+    md5->digest[3] = 0x10325476L;
+
+    md5->buffLen = 0;
+    md5->loLen   = 0;
+    md5->hiLen   = 0;
+}
+
+#ifdef FREESCALE_MMCAU
+static int Transform(Md5* md5, byte* data)
+{
+    int ret = wolfSSL_CryptHwMutexLock();
+    if(ret == 0) {
+        cau_md5_hash_n(data, 1, (unsigned char*)md5->digest);
+        wolfSSL_CryptHwMutexUnLock();
+    }
+    return ret;
+}
+#endif /* FREESCALE_MMCAU */
+
+#ifndef FREESCALE_MMCAU
+
+static void Transform(Md5* md5)
+{
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+#define MD5STEP(f, w, x, y, z, data, s) \
+    w = rotlFixed(w + f(x, y, z) + data, s) + x
+
+    /* Copy context->state[] to working vars  */
+    word32 a = md5->digest[0];
+    word32 b = md5->digest[1];
+    word32 c = md5->digest[2];
+    word32 d = md5->digest[3];
+
+    MD5STEP(F1, a, b, c, d, md5->buffer[0]  + 0xd76aa478,  7);
+    MD5STEP(F1, d, a, b, c, md5->buffer[1]  + 0xe8c7b756, 12);
+    MD5STEP(F1, c, d, a, b, md5->buffer[2]  + 0x242070db, 17);
+    MD5STEP(F1, b, c, d, a, md5->buffer[3]  + 0xc1bdceee, 22);
+    MD5STEP(F1, a, b, c, d, md5->buffer[4]  + 0xf57c0faf,  7);
+    MD5STEP(F1, d, a, b, c, md5->buffer[5]  + 0x4787c62a, 12);
+    MD5STEP(F1, c, d, a, b, md5->buffer[6]  + 0xa8304613, 17);
+    MD5STEP(F1, b, c, d, a, md5->buffer[7]  + 0xfd469501, 22);
+    MD5STEP(F1, a, b, c, d, md5->buffer[8]  + 0x698098d8,  7);
+    MD5STEP(F1, d, a, b, c, md5->buffer[9]  + 0x8b44f7af, 12);
+    MD5STEP(F1, c, d, a, b, md5->buffer[10] + 0xffff5bb1, 17);
+    MD5STEP(F1, b, c, d, a, md5->buffer[11] + 0x895cd7be, 22);
+    MD5STEP(F1, a, b, c, d, md5->buffer[12] + 0x6b901122,  7);
+    MD5STEP(F1, d, a, b, c, md5->buffer[13] + 0xfd987193, 12);
+    MD5STEP(F1, c, d, a, b, md5->buffer[14] + 0xa679438e, 17);
+    MD5STEP(F1, b, c, d, a, md5->buffer[15] + 0x49b40821, 22);
+
+    MD5STEP(F2, a, b, c, d, md5->buffer[1]  + 0xf61e2562,  5);
+    MD5STEP(F2, d, a, b, c, md5->buffer[6]  + 0xc040b340,  9);
+    MD5STEP(F2, c, d, a, b, md5->buffer[11] + 0x265e5a51, 14);
+    MD5STEP(F2, b, c, d, a, md5->buffer[0]  + 0xe9b6c7aa, 20);
+    MD5STEP(F2, a, b, c, d, md5->buffer[5]  + 0xd62f105d,  5);
+    MD5STEP(F2, d, a, b, c, md5->buffer[10] + 0x02441453,  9);
+    MD5STEP(F2, c, d, a, b, md5->buffer[15] + 0xd8a1e681, 14);
+    MD5STEP(F2, b, c, d, a, md5->buffer[4]  + 0xe7d3fbc8, 20);
+    MD5STEP(F2, a, b, c, d, md5->buffer[9]  + 0x21e1cde6,  5);
+    MD5STEP(F2, d, a, b, c, md5->buffer[14] + 0xc33707d6,  9);
+    MD5STEP(F2, c, d, a, b, md5->buffer[3]  + 0xf4d50d87, 14);
+    MD5STEP(F2, b, c, d, a, md5->buffer[8]  + 0x455a14ed, 20);
+    MD5STEP(F2, a, b, c, d, md5->buffer[13] + 0xa9e3e905,  5);
+    MD5STEP(F2, d, a, b, c, md5->buffer[2]  + 0xfcefa3f8,  9);
+    MD5STEP(F2, c, d, a, b, md5->buffer[7]  + 0x676f02d9, 14);
+    MD5STEP(F2, b, c, d, a, md5->buffer[12] + 0x8d2a4c8a, 20);
+
+    MD5STEP(F3, a, b, c, d, md5->buffer[5]  + 0xfffa3942,  4);
+    MD5STEP(F3, d, a, b, c, md5->buffer[8]  + 0x8771f681, 11);
+    MD5STEP(F3, c, d, a, b, md5->buffer[11] + 0x6d9d6122, 16);
+    MD5STEP(F3, b, c, d, a, md5->buffer[14] + 0xfde5380c, 23);
+    MD5STEP(F3, a, b, c, d, md5->buffer[1]  + 0xa4beea44,  4);
+    MD5STEP(F3, d, a, b, c, md5->buffer[4]  + 0x4bdecfa9, 11);
+    MD5STEP(F3, c, d, a, b, md5->buffer[7]  + 0xf6bb4b60, 16);
+    MD5STEP(F3, b, c, d, a, md5->buffer[10] + 0xbebfbc70, 23);
+    MD5STEP(F3, a, b, c, d, md5->buffer[13] + 0x289b7ec6,  4);
+    MD5STEP(F3, d, a, b, c, md5->buffer[0]  + 0xeaa127fa, 11);
+    MD5STEP(F3, c, d, a, b, md5->buffer[3]  + 0xd4ef3085, 16);
+    MD5STEP(F3, b, c, d, a, md5->buffer[6]  + 0x04881d05, 23);
+    MD5STEP(F3, a, b, c, d, md5->buffer[9]  + 0xd9d4d039,  4);
+    MD5STEP(F3, d, a, b, c, md5->buffer[12] + 0xe6db99e5, 11);
+    MD5STEP(F3, c, d, a, b, md5->buffer[15] + 0x1fa27cf8, 16);
+    MD5STEP(F3, b, c, d, a, md5->buffer[2]  + 0xc4ac5665, 23);
+
+    MD5STEP(F4, a, b, c, d, md5->buffer[0]  + 0xf4292244,  6);
+    MD5STEP(F4, d, a, b, c, md5->buffer[7]  + 0x432aff97, 10);
+    MD5STEP(F4, c, d, a, b, md5->buffer[14] + 0xab9423a7, 15);
+    MD5STEP(F4, b, c, d, a, md5->buffer[5]  + 0xfc93a039, 21);
+    MD5STEP(F4, a, b, c, d, md5->buffer[12] + 0x655b59c3,  6);
+    MD5STEP(F4, d, a, b, c, md5->buffer[3]  + 0x8f0ccc92, 10);
+    MD5STEP(F4, c, d, a, b, md5->buffer[10] + 0xffeff47d, 15);
+    MD5STEP(F4, b, c, d, a, md5->buffer[1]  + 0x85845dd1, 21);
+    MD5STEP(F4, a, b, c, d, md5->buffer[8]  + 0x6fa87e4f,  6);
+    MD5STEP(F4, d, a, b, c, md5->buffer[15] + 0xfe2ce6e0, 10);
+    MD5STEP(F4, c, d, a, b, md5->buffer[6]  + 0xa3014314, 15);
+    MD5STEP(F4, b, c, d, a, md5->buffer[13] + 0x4e0811a1, 21);
+    MD5STEP(F4, a, b, c, d, md5->buffer[4]  + 0xf7537e82,  6);
+    MD5STEP(F4, d, a, b, c, md5->buffer[11] + 0xbd3af235, 10);
+    MD5STEP(F4, c, d, a, b, md5->buffer[2]  + 0x2ad7d2bb, 15);
+    MD5STEP(F4, b, c, d, a, md5->buffer[9]  + 0xeb86d391, 21);
+    
+    /* Add the working vars back into digest state[]  */
+    md5->digest[0] += a;
+    md5->digest[1] += b;
+    md5->digest[2] += c;
+    md5->digest[3] += d;
+}
+
+#endif /* FREESCALE_MMCAU */
+
+
+static INLINE void AddLength(Md5* md5, word32 len)
+{
+    word32 tmp = md5->loLen;
+    if ( (md5->loLen += len) < tmp)
+        md5->hiLen++;                       /* carry low to high */
+}
+
+
+void wc_Md5Update(Md5* md5, const byte* data, word32 len)
+{
+    /* do block size increments */
+    byte* local = (byte*)md5->buffer;
+
+    while (len) {
+        word32 add = min(len, MD5_BLOCK_SIZE - md5->buffLen);
+        XMEMCPY(&local[md5->buffLen], data, add);
+
+        md5->buffLen += add;
+        data         += add;
+        len          -= add;
+
+        if (md5->buffLen == MD5_BLOCK_SIZE) {
+            #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+                ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE);
+            #endif
+            XTRANSFORM(md5, local);
+            AddLength(md5, MD5_BLOCK_SIZE);
+            md5->buffLen = 0;
+        }
+    }
+}
+
+
+void wc_Md5Final(Md5* md5, byte* hash)
+{
+    byte* local = (byte*)md5->buffer;
+
+    AddLength(md5, md5->buffLen);  /* before adding pads */
+
+    local[md5->buffLen++] = 0x80;  /* add 1 */
+
+    /* pad with zeros */
+    if (md5->buffLen > MD5_PAD_SIZE) {
+        XMEMSET(&local[md5->buffLen], 0, MD5_BLOCK_SIZE - md5->buffLen);
+        md5->buffLen += MD5_BLOCK_SIZE - md5->buffLen;
+
+        #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+            ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE);
+        #endif
+        XTRANSFORM(md5, local);
+        md5->buffLen = 0;
+    }
+    XMEMSET(&local[md5->buffLen], 0, MD5_PAD_SIZE - md5->buffLen);
+   
+    /* put lengths in bits */
+    md5->hiLen = (md5->loLen >> (8*sizeof(md5->loLen) - 3)) + 
+                 (md5->hiLen << 3);
+    md5->loLen = md5->loLen << 3;
+
+    /* store lengths */
+    #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+        ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE);
+    #endif
+    /* ! length ordering dependent on digest endian type ! */
+    XMEMCPY(&local[MD5_PAD_SIZE], &md5->loLen, sizeof(word32));
+    XMEMCPY(&local[MD5_PAD_SIZE + sizeof(word32)], &md5->hiLen, sizeof(word32));
+
+    XTRANSFORM(md5, local);
+    #ifdef BIG_ENDIAN_ORDER
+        ByteReverseWords(md5->digest, md5->digest, MD5_DIGEST_SIZE);
+    #endif
+    XMEMCPY(hash, md5->digest, MD5_DIGEST_SIZE);
+
+    wc_InitMd5(md5);  /* reset state */
+}
+
+#endif /* STM32F2_HASH */
+
+
+int wc_Md5Hash(const byte* data, word32 len, byte* hash)
+{
+#ifdef WOLFSSL_SMALL_STACK
+    Md5* md5;
+#else
+    Md5 md5[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (md5 == NULL)
+        return MEMORY_E;
+#endif
+
+    wc_InitMd5(md5);
+    wc_Md5Update(md5, data, len);
+    wc_Md5Final(md5, hash);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return 0;
+}
+
+#endif /* WOLFSSL_TI_HASH */
+
+#endif /* NO_MD5 */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/memory.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/memory.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/memory.c	(revision 164)
@@ -0,0 +1,191 @@
+/* memory.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+/* check old macros @wc_fips */
+#if defined(USE_CYASSL_MEMORY) && !defined(USE_WOLFSSL_MEMORY)
+    #define USE_WOLFSSL_MEMORY
+#endif
+#if defined(CYASSL_MALLOC_CHECK) && !defined(WOLFSSL_MALLOC_CHECK)
+    #define WOLFSSL_MALLOC_CHECK
+#endif
+
+#ifdef USE_WOLFSSL_MEMORY
+
+#include <wolfssl/wolfcrypt/memory.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+#ifdef WOLFSSL_MALLOC_CHECK
+    #include <stdio.h>
+#endif
+
+/* Set these to default values initially. */
+static wolfSSL_Malloc_cb  malloc_function = 0;
+static wolfSSL_Free_cb    free_function = 0;
+static wolfSSL_Realloc_cb realloc_function = 0;
+
+int wolfSSL_SetAllocators(wolfSSL_Malloc_cb  mf,
+                          wolfSSL_Free_cb    ff,
+                          wolfSSL_Realloc_cb rf)
+{
+    int res = 0;
+
+    if (mf)
+        malloc_function = mf;
+    else
+        res = BAD_FUNC_ARG;
+
+    if (ff)
+        free_function = ff;
+    else
+        res = BAD_FUNC_ARG;
+
+    if (rf)
+        realloc_function = rf;
+    else
+        res = BAD_FUNC_ARG;
+
+    return res;
+}
+
+
+void* wolfSSL_Malloc(size_t size)
+{
+    void* res = 0;
+
+    if (malloc_function)
+        res = malloc_function(size);
+    else
+        res = malloc(size);
+
+    #ifdef WOLFSSL_MALLOC_CHECK
+        if (res == NULL)
+            puts("wolfSSL_malloc failed");
+    #endif
+                
+    return res;
+}
+
+void wolfSSL_Free(void *ptr)
+{
+    if (free_function)
+        free_function(ptr);
+    else
+        free(ptr);
+}
+
+void* wolfSSL_Realloc(void *ptr, size_t size)
+{
+    void* res = 0;
+
+    if (realloc_function)
+        res = realloc_function(ptr, size);
+    else
+        res = realloc(ptr, size);
+
+    return res;
+}
+
+#endif /* USE_WOLFSSL_MEMORY */
+
+
+#ifdef HAVE_IO_POOL
+
+/* Example for user io pool, shared build may need definitions in lib proper */
+
+#include <wolfssl/wolfcrypt/types.h>
+#include <stdlib.h>
+
+#ifndef HAVE_THREAD_LS
+    #error "Oops, simple I/O pool example needs thread local storage"
+#endif
+
+
+/* allow simple per thread in and out pools */
+/* use 17k size sense max record size is 16k plus overhead */
+static THREAD_LS_T byte pool_in[17*1024];
+static THREAD_LS_T byte pool_out[17*1024];
+
+
+void* XMALLOC(size_t n, void* heap, int type)
+{
+    (void)heap;
+
+    if (type == DYNAMIC_TYPE_IN_BUFFER) {
+        if (n < sizeof(pool_in))
+            return pool_in;
+        else
+            return NULL;
+    }
+
+    if (type == DYNAMIC_TYPE_OUT_BUFFER) {
+        if (n < sizeof(pool_out))
+            return pool_out;
+        else
+            return NULL;
+    }
+
+    return malloc(n);
+}
+
+void* XREALLOC(void *p, size_t n, void* heap, int type)
+{
+    (void)heap;
+
+    if (type == DYNAMIC_TYPE_IN_BUFFER) {
+        if (n < sizeof(pool_in))
+            return pool_in;
+        else
+            return NULL;
+    }
+
+    if (type == DYNAMIC_TYPE_OUT_BUFFER) {
+        if (n < sizeof(pool_out))
+            return pool_out;
+        else
+            return NULL;
+    }
+
+    return realloc(p, n);
+}
+
+
+/* unit api calls, let's make sure visible with WOLFSSL_API */
+WOLFSSL_API void XFREE(void *p, void* heap, int type)
+{
+    (void)heap;
+
+    if (type == DYNAMIC_TYPE_IN_BUFFER)
+        return;  /* do nothing, static pool */
+
+    if (type == DYNAMIC_TYPE_OUT_BUFFER)
+        return;  /* do nothing, static pool */
+
+    free(p);
+}
+
+#endif /* HAVE_IO_POOL */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/misc.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/misc.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/misc.c	(revision 164)
@@ -0,0 +1,201 @@
+/* misc.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef WOLF_CRYPT_MISC_C
+#define WOLF_CRYPT_MISC_C
+
+#include <wolfssl/wolfcrypt/misc.h>
+
+/* inlining these functions is a huge speed increase and a small size decrease, 
+   because the functions are smaller than function call setup/cleanup, e.g.,
+   md5 benchmark is twice as fast with inline.  If you don't want it, then
+   define NO_INLINE and compile this file into wolfssl, otherwise it's used as
+   a source header
+ */
+
+#ifdef NO_INLINE
+    #define STATIC
+#else
+    #define STATIC static
+#endif
+
+
+#ifdef INTEL_INTRINSICS
+
+    #include <stdlib.h>      /* get intrinsic definitions */
+
+    /* for non visual studio probably need no long version, 32 bit only
+     * i.e., _rotl and _rotr */
+    #pragma intrinsic(_lrotl, _lrotr)
+
+    STATIC INLINE word32 rotlFixed(word32 x, word32 y)
+    {
+        return y ? _lrotl(x, y) : x;
+    }
+
+    STATIC INLINE word32 rotrFixed(word32 x, word32 y)
+    {
+        return y ? _lrotr(x, y) : x;
+    }
+
+#else /* generic */
+
+    STATIC INLINE word32 rotlFixed(word32 x, word32 y)
+    {
+        return (x << y) | (x >> (sizeof(y) * 8 - y));
+    }   
+
+
+    STATIC INLINE word32 rotrFixed(word32 x, word32 y)
+    {
+        return (x >> y) | (x << (sizeof(y) * 8 - y));
+    }
+
+#endif
+
+
+STATIC INLINE word32 ByteReverseWord32(word32 value)
+{
+#ifdef PPC_INTRINSICS
+    /* PPC: load reverse indexed instruction */
+    return (word32)__lwbrx(&value,0);
+#elif defined(KEIL_INTRINSICS)
+    return (word32)__rev(value);
+#elif defined(FAST_ROTATE)
+    /* 5 instructions with rotate instruction, 9 without */
+    return (rotrFixed(value, 8U) & 0xff00ff00) |
+           (rotlFixed(value, 8U) & 0x00ff00ff);
+#else
+    /* 6 instructions with rotate instruction, 8 without */
+    value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
+    return rotlFixed(value, 16U);
+#endif
+}
+
+
+STATIC INLINE void ByteReverseWords(word32* out, const word32* in,
+                                    word32 byteCount)
+{
+    word32 count = byteCount/(word32)sizeof(word32), i;
+
+    for (i = 0; i < count; i++)
+        out[i] = ByteReverseWord32(in[i]);
+
+}
+
+
+#ifdef WORD64_AVAILABLE
+
+
+STATIC INLINE word64 rotlFixed64(word64 x, word64 y)
+{
+    return (x << y) | (x >> (sizeof(y) * 8 - y));
+}  
+
+
+STATIC INLINE word64 rotrFixed64(word64 x, word64 y)
+{
+    return (x >> y) | (x << (sizeof(y) * 8 - y));
+}
+
+
+STATIC INLINE word64 ByteReverseWord64(word64 value)
+{
+#ifdef WOLFCRYPT_SLOW_WORD64
+	return (word64)(ByteReverseWord32((word32)value)) << 32 | 
+                    ByteReverseWord32((word32)(value>>32));
+#else
+	value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) |
+            ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
+	value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) |
+            ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
+	return rotlFixed64(value, 32U);
+#endif
+}
+
+
+STATIC INLINE void ByteReverseWords64(word64* out, const word64* in,
+                                      word32 byteCount)
+{
+    word32 count = byteCount/(word32)sizeof(word64), i;
+
+    for (i = 0; i < count; i++)
+        out[i] = ByteReverseWord64(in[i]);
+
+}
+
+#endif /* WORD64_AVAILABLE */
+
+
+STATIC INLINE void XorWords(wolfssl_word* r, const wolfssl_word* a, word32 n)
+{
+    word32 i;
+
+    for (i = 0; i < n; i++) r[i] ^= a[i];
+}
+
+
+STATIC INLINE void xorbuf(void* buf, const void* mask, word32 count)
+{
+    if (((wolfssl_word)buf | (wolfssl_word)mask | count) % WOLFSSL_WORD_SIZE == 0)
+        XorWords( (wolfssl_word*)buf,
+                  (const wolfssl_word*)mask, count / WOLFSSL_WORD_SIZE);
+    else {
+        word32 i;
+        byte*       b = (byte*)buf;
+        const byte* m = (const byte*)mask;
+
+        for (i = 0; i < count; i++) b[i] ^= m[i];
+    }
+}
+
+
+/* Make sure compiler doesn't skip */
+STATIC INLINE void ForceZero(const void* mem, word32 len)
+{
+    volatile byte* z = (volatile byte*)mem;
+
+    while (len--) *z++ = 0;
+}
+
+
+/* check all length bytes for equality, return 0 on success */
+STATIC INLINE int ConstantCompare(const byte* a, const byte* b, int length)
+{
+    int i;
+    int compareSum = 0;
+
+    for (i = 0; i < length; i++) {
+        compareSum |= a[i] ^ b[i];
+    }
+
+    return compareSum;
+}
+
+#undef STATIC
+
+#endif /* WOLF_CRYPT_MISC_C */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/pwdbased.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/pwdbased.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/pwdbased.c	(revision 164)
@@ -0,0 +1,565 @@
+/* pwdbased.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_PWDBASED
+
+#ifdef WOLFSSL_PIC32MZ_HASH
+    #ifndef NO_MD5
+        #define wc_InitMd5   wc_InitMd5_sw
+        #define wc_Md5Update wc_Md5Update_sw
+        #define wc_Md5Final  wc_Md5Final_sw
+    #endif /* NO_MD5 */
+
+    #define wc_InitSha   wc_InitSha_sw
+    #define wc_ShaUpdate wc_ShaUpdate_sw
+    #define wc_ShaFinal  wc_ShaFinal_sw
+
+    #define wc_InitSha256   wc_InitSha256_sw
+    #define wc_Sha256Update wc_Sha256Update_sw
+    #define wc_Sha256Final  wc_Sha256Final_sw
+#endif
+
+#include <wolfssl/wolfcrypt/pwdbased.h>
+#include <wolfssl/wolfcrypt/hmac.h>
+#include <wolfssl/wolfcrypt/integer.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
+    #include <wolfssl/wolfcrypt/sha512.h>
+#endif
+
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+#ifdef min
+#define WOLFSSL_HAVE_MIN
+#endif
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+
+#endif /* WOLFSSL_HAVE_MIN */
+
+
+#ifndef NO_SHA
+/* PBKDF1 needs at least SHA available */
+int wc_PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt,
+           int sLen, int iterations, int kLen, int hashType)
+{
+    Sha  sha;
+#ifndef NO_MD5
+    Md5  md5;
+#endif
+    int  hLen = (int)SHA_DIGEST_SIZE;
+    int  i, ret = 0;
+    byte buffer[SHA_DIGEST_SIZE];  /* max size */
+
+    if (hashType != MD5 && hashType != SHA)
+        return BAD_FUNC_ARG;
+
+#ifndef NO_MD5
+    if (hashType == MD5)
+        hLen = (int)MD5_DIGEST_SIZE;
+#endif
+
+    if (kLen > hLen)
+        return BAD_FUNC_ARG;
+
+    if (iterations < 1)
+        return BAD_FUNC_ARG;
+
+    switch (hashType) {
+#ifndef NO_MD5
+        case MD5:
+            wc_InitMd5(&md5);
+            wc_Md5Update(&md5, passwd, pLen);
+            wc_Md5Update(&md5, salt,   sLen);
+            wc_Md5Final(&md5,  buffer);
+            break;
+#endif /* NO_MD5 */
+        case SHA:
+        default:
+            ret = wc_InitSha(&sha);
+            if (ret != 0)
+                return ret;
+            wc_ShaUpdate(&sha, passwd, pLen);
+            wc_ShaUpdate(&sha, salt,   sLen);
+            wc_ShaFinal(&sha,  buffer);
+            break;
+    }
+
+    for (i = 1; i < iterations; i++) {
+        if (hashType == SHA) {
+            wc_ShaUpdate(&sha, buffer, hLen);
+            wc_ShaFinal(&sha,  buffer);
+        }
+#ifndef NO_MD5
+        else {
+            wc_Md5Update(&md5, buffer, hLen);
+            wc_Md5Final(&md5,  buffer);
+        }
+#endif
+    }
+    XMEMCPY(output, buffer, kLen);
+
+    return 0;
+}
+#endif /* NO_SHA */
+
+
+int GetDigestSize(int hashType)
+{
+    int hLen;
+
+    switch (hashType) {
+#ifndef NO_MD5
+        case MD5:
+            hLen = MD5_DIGEST_SIZE;
+            break;
+#endif
+#ifndef NO_SHA
+        case SHA:
+            hLen = SHA_DIGEST_SIZE;
+            break;
+#endif
+#ifndef NO_SHA256
+        case SHA256:
+            hLen = SHA256_DIGEST_SIZE;
+            break;
+#endif
+#ifdef WOLFSSL_SHA512
+        case SHA512:
+            hLen = SHA512_DIGEST_SIZE;
+            break;
+#endif
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    return hLen;
+}
+
+
+int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
+           int sLen, int iterations, int kLen, int hashType)
+{
+    word32 i = 1;
+    int    hLen;
+    int    j, ret;
+    Hmac   hmac;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  buffer;
+#else
+    byte   buffer[MAX_DIGEST_SIZE];
+#endif
+
+    hLen = GetDigestSize(hashType);
+    if (hLen < 0)
+        return BAD_FUNC_ARG;
+
+#ifdef WOLFSSL_SMALL_STACK
+    buffer = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (buffer == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = wc_HmacSetKey(&hmac, hashType, passwd, pLen);
+
+    if (ret == 0) {
+        while (kLen) {
+            int currentLen;
+
+            ret = wc_HmacUpdate(&hmac, salt, sLen);
+            if (ret != 0)
+                break;
+
+            /* encode i */
+            for (j = 0; j < 4; j++) {
+                byte b = (byte)(i >> ((3-j) * 8));
+
+                ret = wc_HmacUpdate(&hmac, &b, 1);
+                if (ret != 0)
+                    break;
+            }
+
+            /* check ret from inside for loop */
+            if (ret != 0)
+                break;
+
+            ret = wc_HmacFinal(&hmac, buffer);
+            if (ret != 0)
+                break;
+
+            currentLen = min(kLen, hLen);
+            XMEMCPY(output, buffer, currentLen);
+
+            for (j = 1; j < iterations; j++) {
+                ret = wc_HmacUpdate(&hmac, buffer, hLen);
+                if (ret != 0)
+                    break;
+                ret = wc_HmacFinal(&hmac, buffer);
+                if (ret != 0)
+                    break;
+                xorbuf(output, buffer, currentLen);
+            }
+
+            /* check ret from inside for loop */
+            if (ret != 0)
+                break;
+
+            output += currentLen;
+            kLen   -= currentLen;
+            i++;
+        }
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+#ifdef WOLFSSL_SHA512
+    #define PBKDF_DIGEST_SIZE SHA512_BLOCK_SIZE
+#elif !defined(NO_SHA256)
+    #define PBKDF_DIGEST_SIZE SHA256_BLOCK_SIZE
+#else
+    #define PBKDF_DIGEST_SIZE SHA_DIGEST_SIZE
+#endif
+
+/* helper for wc_PKCS12_PBKDF(), sets block and digest sizes */
+int GetPKCS12HashSizes(int hashType, word32* v, word32* u)
+{
+    if (!v || !u)
+        return BAD_FUNC_ARG;
+
+    switch (hashType) {
+#ifndef NO_MD5
+        case MD5:
+            *v = MD5_BLOCK_SIZE;
+            *u = MD5_DIGEST_SIZE;
+            break;
+#endif
+#ifndef NO_SHA
+        case SHA:
+            *v = SHA_BLOCK_SIZE;
+            *u = SHA_DIGEST_SIZE;
+            break;
+#endif
+#ifndef NO_SHA256
+        case SHA256:
+            *v = SHA256_BLOCK_SIZE;
+            *u = SHA256_DIGEST_SIZE;
+            break;
+#endif
+#ifdef WOLFSSL_SHA512
+        case SHA512:
+            *v = SHA512_BLOCK_SIZE;
+            *u = SHA512_DIGEST_SIZE;
+            break;
+#endif
+        default:
+            return BAD_FUNC_ARG;
+    }
+
+    return 0;
+}
+
+/* helper for PKCS12_PBKDF(), does hash operation */
+int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen,
+                 byte* Ai, word32 u, int iterations)
+{
+    int i;
+    int ret = 0;
+
+    if (buffer == NULL || Ai == NULL)
+        return BAD_FUNC_ARG;
+
+    switch (hashType) {
+#ifndef NO_MD5
+        case MD5:
+            {
+                Md5 md5;
+                wc_InitMd5(&md5);
+                wc_Md5Update(&md5, buffer, totalLen);
+                wc_Md5Final(&md5, Ai);
+
+                for (i = 1; i < iterations; i++) {
+                    wc_Md5Update(&md5, Ai, u);
+                    wc_Md5Final(&md5, Ai);
+                }
+            }
+            break;
+#endif /* NO_MD5 */
+#ifndef NO_SHA
+        case SHA:
+            {
+                Sha sha;
+                ret = wc_InitSha(&sha);
+                if (ret != 0)
+                    break;
+                wc_ShaUpdate(&sha, buffer, totalLen);
+                wc_ShaFinal(&sha, Ai);
+
+                for (i = 1; i < iterations; i++) {
+                    wc_ShaUpdate(&sha, Ai, u);
+                    wc_ShaFinal(&sha, Ai);
+                }
+            }
+            break;
+#endif /* NO_SHA */
+#ifndef NO_SHA256
+        case SHA256:
+            {
+                Sha256 sha256;
+                ret = wc_InitSha256(&sha256);
+                if (ret != 0)
+                    break;
+
+                ret = wc_Sha256Update(&sha256, buffer, totalLen);
+                if (ret != 0)
+                    break;
+
+                ret = wc_Sha256Final(&sha256, Ai);
+                if (ret != 0)
+                    break;
+
+                for (i = 1; i < iterations; i++) {
+                    ret = wc_Sha256Update(&sha256, Ai, u);
+                    if (ret != 0)
+                        break;
+
+                    ret = wc_Sha256Final(&sha256, Ai);
+                    if (ret != 0)
+                        break;
+                }
+            }
+            break;
+#endif /* NO_SHA256 */
+#ifdef WOLFSSL_SHA512
+        case SHA512:
+            {
+                Sha512 sha512;
+                ret = wc_InitSha512(&sha512);
+                if (ret != 0)
+                    break;
+
+                ret = wc_Sha512Update(&sha512, buffer, totalLen);
+                if (ret != 0)
+                    break;
+
+                ret = wc_Sha512Final(&sha512, Ai);
+                if (ret != 0)
+                    break;
+
+                for (i = 1; i < iterations; i++) {
+                    ret = wc_Sha512Update(&sha512, Ai, u);
+                    if (ret != 0)
+                        break;
+
+                    ret = wc_Sha512Final(&sha512, Ai);
+                    if (ret != 0)
+                        break;
+                }
+            }
+            break;
+#endif /* WOLFSSL_SHA512 */
+
+        default:
+            ret = BAD_FUNC_ARG;
+            break;
+    }
+
+    return ret;
+}
+
+int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
+                 int saltLen, int iterations, int kLen, int hashType, int id)
+{
+    /* all in bytes instead of bits */
+    word32 u, v, dLen, pLen, iLen, sLen, totalLen;
+    int    dynamic = 0;
+    int    ret = 0;
+    int    i;
+    byte   *D, *S, *P, *I;
+#ifdef WOLFSSL_SMALL_STACK
+    byte   staticBuffer[1]; /* force dynamic usage */
+#else
+    byte   staticBuffer[1024];
+#endif
+    byte*  buffer = staticBuffer;
+
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  Ai;
+    byte*  B;
+#else
+    byte   Ai[PBKDF_DIGEST_SIZE];
+    byte   B[PBKDF_DIGEST_SIZE];
+#endif
+
+    if (!iterations)
+        iterations = 1;
+
+    ret = GetPKCS12HashSizes(hashType, &v, &u);
+    if (ret < 0)
+        return BAD_FUNC_ARG;
+
+#ifdef WOLFSSL_SMALL_STACK
+    Ai = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (Ai == NULL)
+        return MEMORY_E;
+
+    B = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (B == NULL) {
+        XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    XMEMSET(Ai, 0, PBKDF_DIGEST_SIZE);
+    XMEMSET(B,  0, PBKDF_DIGEST_SIZE);
+
+    dLen = v;
+    sLen =  v * ((saltLen + v - 1) / v);
+    if (passLen)
+        pLen = v * ((passLen + v - 1) / v);
+    else
+        pLen = 0;
+    iLen = sLen + pLen;
+
+    totalLen = dLen + sLen + pLen;
+
+    if (totalLen > sizeof(staticBuffer)) {
+        buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY);
+        if (buffer == NULL) {
+#ifdef WOLFSSL_SMALL_STACK
+            XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(B,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+            return MEMORY_E;
+        }
+        dynamic = 1;
+    }
+
+    D = buffer;
+    S = D + dLen;
+    P = S + sLen;
+    I = S;
+
+    XMEMSET(D, id, dLen);
+
+    for (i = 0; i < (int)sLen; i++)
+        S[i] = salt[i % saltLen];
+    for (i = 0; i < (int)pLen; i++)
+        P[i] = passwd[i % passLen];
+
+    while (kLen > 0) {
+        word32 currentLen;
+        mp_int B1;
+
+        ret = DoPKCS12Hash(hashType, buffer, totalLen, Ai, u, iterations);
+        if (ret < 0)
+            break;
+
+        for (i = 0; i < (int)v; i++)
+            B[i] = Ai[i % u];
+
+        if (mp_init(&B1) != MP_OKAY)
+            ret = MP_INIT_E;
+        else if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY)
+            ret = MP_READ_E;
+        else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY)
+            ret = MP_ADD_E;
+
+        if (ret != 0) {
+            mp_clear(&B1);
+            break;
+        }
+
+        for (i = 0; i < (int)iLen; i += v) {
+            int    outSz;
+            mp_int i1;
+            mp_int res;
+
+            if (mp_init_multi(&i1, &res, NULL, NULL, NULL, NULL) != MP_OKAY) {
+                ret = MP_INIT_E;
+                break;
+            }
+            if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY)
+                ret = MP_READ_E;
+            else if (mp_add(&i1, &B1, &res) != MP_OKAY)
+                ret = MP_ADD_E;
+            else if ( (outSz = mp_unsigned_bin_size(&res)) < 0)
+                ret = MP_TO_E;
+            else {
+                if (outSz > (int)v) {
+                    /* take off MSB */
+                    byte  tmp[129];
+                    ret = mp_to_unsigned_bin(&res, tmp);
+                    XMEMCPY(I + i, tmp + 1, v);
+                }
+                else if (outSz < (int)v) {
+                    XMEMSET(I + i, 0, v - outSz);
+                    ret = mp_to_unsigned_bin(&res, I + i + v - outSz);
+                }
+                else
+                    ret = mp_to_unsigned_bin(&res, I + i);
+            }
+
+            mp_clear(&i1);
+            mp_clear(&res);
+            if (ret < 0) break;
+        }
+
+        currentLen = min(kLen, (int)u);
+        XMEMCPY(output, Ai, currentLen);
+        output += currentLen;
+        kLen   -= currentLen;
+        mp_clear(&B1);
+    }
+
+    if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(B,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+#undef PBKDF_DIGEST_SIZE
+
+#endif /* NO_PWDBASED */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/rabbit.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/rabbit.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/rabbit.c	(revision 164)
@@ -0,0 +1,310 @@
+/* rabbit.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_RABBIT
+
+#include <wolfssl/wolfcrypt/rabbit.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+
+#ifdef BIG_ENDIAN_ORDER
+    #define LITTLE32(x) ByteReverseWord32(x)
+#else
+    #define LITTLE32(x) (x)
+#endif
+
+#define U32V(x) ((word32)(x) & 0xFFFFFFFFU)
+
+
+/* Square a 32-bit unsigned integer to obtain the 64-bit result and return */
+/* the upper 32 bits XOR the lower 32 bits */
+static word32 RABBIT_g_func(word32 x)
+{
+    /* Temporary variables */
+    word32 a, b, h, l;
+
+    /* Construct high and low argument for squaring */
+    a = x&0xFFFF;
+    b = x>>16;
+
+    /* Calculate high and low result of squaring */
+    h = (((U32V(a*a)>>17) + U32V(a*b))>>15) + b*b;
+    l = x*x;
+
+    /* Return high XOR low */
+    return U32V(h^l);
+}
+
+
+/* Calculate the next internal state */
+static void RABBIT_next_state(RabbitCtx* ctx)
+{
+    /* Temporary variables */
+    word32 g[8], c_old[8], i;
+
+    /* Save old counter values */
+    for (i=0; i<8; i++)
+        c_old[i] = ctx->c[i];
+
+    /* Calculate new counter values */
+    ctx->c[0] = U32V(ctx->c[0] + 0x4D34D34D + ctx->carry);
+    ctx->c[1] = U32V(ctx->c[1] + 0xD34D34D3 + (ctx->c[0] < c_old[0]));
+    ctx->c[2] = U32V(ctx->c[2] + 0x34D34D34 + (ctx->c[1] < c_old[1]));
+    ctx->c[3] = U32V(ctx->c[3] + 0x4D34D34D + (ctx->c[2] < c_old[2]));
+    ctx->c[4] = U32V(ctx->c[4] + 0xD34D34D3 + (ctx->c[3] < c_old[3]));
+    ctx->c[5] = U32V(ctx->c[5] + 0x34D34D34 + (ctx->c[4] < c_old[4]));
+    ctx->c[6] = U32V(ctx->c[6] + 0x4D34D34D + (ctx->c[5] < c_old[5]));
+    ctx->c[7] = U32V(ctx->c[7] + 0xD34D34D3 + (ctx->c[6] < c_old[6]));
+    ctx->carry = (ctx->c[7] < c_old[7]);
+   
+    /* Calculate the g-values */
+    for (i=0;i<8;i++)
+        g[i] = RABBIT_g_func(U32V(ctx->x[i] + ctx->c[i]));
+
+    /* Calculate new state values */
+    ctx->x[0] = U32V(g[0] + rotlFixed(g[7],16) + rotlFixed(g[6], 16));
+    ctx->x[1] = U32V(g[1] + rotlFixed(g[0], 8) + g[7]);
+    ctx->x[2] = U32V(g[2] + rotlFixed(g[1],16) + rotlFixed(g[0], 16));
+    ctx->x[3] = U32V(g[3] + rotlFixed(g[2], 8) + g[1]);
+    ctx->x[4] = U32V(g[4] + rotlFixed(g[3],16) + rotlFixed(g[2], 16));
+    ctx->x[5] = U32V(g[5] + rotlFixed(g[4], 8) + g[3]);
+    ctx->x[6] = U32V(g[6] + rotlFixed(g[5],16) + rotlFixed(g[4], 16));
+    ctx->x[7] = U32V(g[7] + rotlFixed(g[6], 8) + g[5]);
+}
+
+
+/* IV setup */
+static void wc_RabbitSetIV(Rabbit* ctx, const byte* inIv)
+{
+    /* Temporary variables */
+    word32 i0, i1, i2, i3, i;
+    word32 iv[2];
+
+    if (inIv)
+        XMEMCPY(iv, inIv, sizeof(iv));
+    else
+        XMEMSET(iv,    0, sizeof(iv));
+      
+    /* Generate four subvectors */
+    i0 = LITTLE32(iv[0]);
+    i2 = LITTLE32(iv[1]);
+    i1 = (i0>>16) | (i2&0xFFFF0000);
+    i3 = (i2<<16) | (i0&0x0000FFFF);
+
+    /* Modify counter values */
+    ctx->workCtx.c[0] = ctx->masterCtx.c[0] ^ i0;
+    ctx->workCtx.c[1] = ctx->masterCtx.c[1] ^ i1;
+    ctx->workCtx.c[2] = ctx->masterCtx.c[2] ^ i2;
+    ctx->workCtx.c[3] = ctx->masterCtx.c[3] ^ i3;
+    ctx->workCtx.c[4] = ctx->masterCtx.c[4] ^ i0;
+    ctx->workCtx.c[5] = ctx->masterCtx.c[5] ^ i1;
+    ctx->workCtx.c[6] = ctx->masterCtx.c[6] ^ i2;
+    ctx->workCtx.c[7] = ctx->masterCtx.c[7] ^ i3;
+
+    /* Copy state variables */
+    for (i=0; i<8; i++)
+        ctx->workCtx.x[i] = ctx->masterCtx.x[i];
+    ctx->workCtx.carry = ctx->masterCtx.carry;
+
+    /* Iterate the system four times */
+    for (i=0; i<4; i++)
+        RABBIT_next_state(&(ctx->workCtx));
+}
+
+
+/* Key setup */
+static INLINE int DoKey(Rabbit* ctx, const byte* key, const byte* iv)
+{
+    /* Temporary variables */
+    word32 k0, k1, k2, k3, i;
+
+    /* Generate four subkeys */
+    k0 = LITTLE32(*(word32*)(key+ 0));
+    k1 = LITTLE32(*(word32*)(key+ 4));
+    k2 = LITTLE32(*(word32*)(key+ 8));
+    k3 = LITTLE32(*(word32*)(key+12));
+
+    /* Generate initial state variables */
+    ctx->masterCtx.x[0] = k0;
+    ctx->masterCtx.x[2] = k1;
+    ctx->masterCtx.x[4] = k2;
+    ctx->masterCtx.x[6] = k3;
+    ctx->masterCtx.x[1] = U32V(k3<<16) | (k2>>16);
+    ctx->masterCtx.x[3] = U32V(k0<<16) | (k3>>16);
+    ctx->masterCtx.x[5] = U32V(k1<<16) | (k0>>16);
+    ctx->masterCtx.x[7] = U32V(k2<<16) | (k1>>16);
+
+    /* Generate initial counter values */
+    ctx->masterCtx.c[0] = rotlFixed(k2, 16);
+    ctx->masterCtx.c[2] = rotlFixed(k3, 16);
+    ctx->masterCtx.c[4] = rotlFixed(k0, 16);
+    ctx->masterCtx.c[6] = rotlFixed(k1, 16);
+    ctx->masterCtx.c[1] = (k0&0xFFFF0000) | (k1&0xFFFF);
+    ctx->masterCtx.c[3] = (k1&0xFFFF0000) | (k2&0xFFFF);
+    ctx->masterCtx.c[5] = (k2&0xFFFF0000) | (k3&0xFFFF);
+    ctx->masterCtx.c[7] = (k3&0xFFFF0000) | (k0&0xFFFF);
+
+    /* Clear carry bit */
+    ctx->masterCtx.carry = 0;
+
+    /* Iterate the system four times */
+    for (i=0; i<4; i++)
+        RABBIT_next_state(&(ctx->masterCtx));
+
+    /* Modify the counters */
+    for (i=0; i<8; i++)
+        ctx->masterCtx.c[i] ^= ctx->masterCtx.x[(i+4)&0x7];
+
+    /* Copy master instance to work instance */
+    for (i=0; i<8; i++) {
+        ctx->workCtx.x[i] = ctx->masterCtx.x[i];
+        ctx->workCtx.c[i] = ctx->masterCtx.c[i];
+    }
+    ctx->workCtx.carry = ctx->masterCtx.carry;
+
+    wc_RabbitSetIV(ctx, iv);
+
+    return 0;
+}
+
+
+/* Key setup */
+int wc_RabbitSetKey(Rabbit* ctx, const byte* key, const byte* iv)
+{
+#ifdef XSTREAM_ALIGN
+    if ((wolfssl_word)key % 4) {
+        int alignKey[4];
+
+        /* iv aligned in SetIV */
+        WOLFSSL_MSG("wc_RabbitSetKey unaligned key");
+
+        XMEMCPY(alignKey, key, sizeof(alignKey));
+
+        return DoKey(ctx, (const byte*)alignKey, iv);
+    }
+#endif /* XSTREAM_ALIGN */
+
+    return DoKey(ctx, key, iv);
+}
+
+
+/* Encrypt/decrypt a message of any size */
+static INLINE int DoProcess(Rabbit* ctx, byte* output, const byte* input,
+                            word32 msglen)
+{
+    /* Encrypt/decrypt all full blocks */
+    while (msglen >= 16) {
+        /* Iterate the system */
+        RABBIT_next_state(&(ctx->workCtx));
+
+        /* Encrypt/decrypt 16 bytes of data */
+        *(word32*)(output+ 0) = *(word32*)(input+ 0) ^
+                   LITTLE32(ctx->workCtx.x[0] ^ (ctx->workCtx.x[5]>>16) ^
+                   U32V(ctx->workCtx.x[3]<<16));
+        *(word32*)(output+ 4) = *(word32*)(input+ 4) ^
+                   LITTLE32(ctx->workCtx.x[2] ^ (ctx->workCtx.x[7]>>16) ^
+                   U32V(ctx->workCtx.x[5]<<16));
+        *(word32*)(output+ 8) = *(word32*)(input+ 8) ^
+                   LITTLE32(ctx->workCtx.x[4] ^ (ctx->workCtx.x[1]>>16) ^
+                   U32V(ctx->workCtx.x[7]<<16));
+        *(word32*)(output+12) = *(word32*)(input+12) ^
+                   LITTLE32(ctx->workCtx.x[6] ^ (ctx->workCtx.x[3]>>16) ^
+                   U32V(ctx->workCtx.x[1]<<16));
+
+        /* Increment pointers and decrement length */
+        input  += 16;
+        output += 16;
+        msglen -= 16;
+    }
+
+    /* Encrypt/decrypt remaining data */
+    if (msglen) {
+
+        word32 i;
+        word32 tmp[4];
+        byte*  buffer = (byte*)tmp;
+
+        XMEMSET(tmp, 0, sizeof(tmp));   /* help static analysis */
+
+        /* Iterate the system */
+        RABBIT_next_state(&(ctx->workCtx));
+
+        /* Generate 16 bytes of pseudo-random data */
+        tmp[0] = LITTLE32(ctx->workCtx.x[0] ^
+                  (ctx->workCtx.x[5]>>16) ^ U32V(ctx->workCtx.x[3]<<16));
+        tmp[1] = LITTLE32(ctx->workCtx.x[2] ^ 
+                  (ctx->workCtx.x[7]>>16) ^ U32V(ctx->workCtx.x[5]<<16));
+        tmp[2] = LITTLE32(ctx->workCtx.x[4] ^ 
+                  (ctx->workCtx.x[1]>>16) ^ U32V(ctx->workCtx.x[7]<<16));
+        tmp[3] = LITTLE32(ctx->workCtx.x[6] ^ 
+                  (ctx->workCtx.x[3]>>16) ^ U32V(ctx->workCtx.x[1]<<16));
+
+        /* Encrypt/decrypt the data */
+        for (i=0; i<msglen; i++)
+            output[i] = input[i] ^ buffer[i];
+    }
+
+    return 0;
+}
+
+
+/* Encrypt/decrypt a message of any size */
+int wc_RabbitProcess(Rabbit* ctx, byte* output, const byte* input, word32 msglen)
+{
+#ifdef XSTREAM_ALIGN
+    if ((wolfssl_word)input % 4 || (wolfssl_word)output % 4) {
+        #ifndef NO_WOLFSSL_ALLOC_ALIGN
+            byte* tmp;
+            WOLFSSL_MSG("wc_RabbitProcess unaligned");
+
+            tmp = (byte*)XMALLOC(msglen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            if (tmp == NULL) return MEMORY_E;
+
+            XMEMCPY(tmp, input, msglen);
+            DoProcess(ctx, tmp, tmp, msglen);
+            XMEMCPY(output, tmp, msglen);
+
+            XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+            return 0;
+        #else
+            return BAD_ALIGN_E;
+        #endif
+    }
+#endif /* XSTREAM_ALIGN */
+
+    return DoProcess(ctx, output, input, msglen);
+}
+
+
+#endif /* NO_RABBIT */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/random.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/random.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/random.c	(revision 164)
@@ -0,0 +1,1360 @@
+/* random.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+ 
+#include <wolfssl/wolfcrypt/settings.h>
+
+/* on HPUX 11 you may need to install /dev/random see
+   http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I
+
+*/
+
+#include <wolfssl/wolfcrypt/random.h>
+
+#ifdef HAVE_FIPS
+int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz)
+{
+    return GenerateSeed(os, seed, sz);
+}
+
+#ifdef HAVE_CAVIUM
+    int  wc_InitRngCavium(WC_RNG* rng, int i)
+    {
+        return InitRngCavium(rng, i);
+    }
+#endif
+
+
+int  wc_InitRng(WC_RNG* rng)
+{
+    return InitRng_fips(rng);
+}
+
+
+int  wc_RNG_GenerateBlock(WC_RNG* rng, byte* b, word32 sz)
+{
+    return RNG_GenerateBlock_fips(rng, b, sz);
+}
+
+
+int  wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
+{
+    return RNG_GenerateByte(rng, b);
+}
+
+#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
+
+    int wc_FreeRng(WC_RNG* rng)
+    {
+        return FreeRng_fips(rng);
+    }
+
+
+    int wc_RNG_HealthTest(int reseed,
+                                        const byte* entropyA, word32 entropyASz,
+                                        const byte* entropyB, word32 entropyBSz,
+                                        byte* output, word32 outputSz)
+    {
+        return RNG_HealthTest_fips(reseed, entropyA, entropyASz,
+                              entropyB, entropyBSz, output, outputSz);
+    }
+#endif /* HAVE_HASHDRBG || NO_RC4 */
+#else /* else build without fips */
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
+
+    #include <wolfssl/wolfcrypt/sha256.h>
+
+    #ifdef NO_INLINE
+        #include <wolfssl/wolfcrypt/misc.h>
+    #else
+        #include <wolfcrypt/src/misc.c>
+    #endif
+#endif /* HAVE_HASHDRBG || NO_RC4 */
+
+#if defined(USE_WINDOWS_API)
+    #ifndef _WIN32_WINNT
+        #define _WIN32_WINNT 0x0400
+    #endif
+    #include <windows.h>
+    #include <wincrypt.h>
+#else
+    #if !defined(NO_DEV_RANDOM) && !defined(CUSTOM_RAND_GENERATE) && \
+        !defined(WOLFSSL_GENSEED_FORTEST) && !defined(WOLFSSL_MDK_ARM) && \
+        !defined(WOLFSSL_IAR_ARM) && !defined(WOLFSSL_ROWLEY_ARM)
+            //#include <fcntl.h>
+        #ifndef EBSNET
+            //#include <unistd.h>
+        #endif
+    #elif defined(FREESCALE_TRNG)
+        #define TRNG_INSTANCE (0)
+        #include "fsl_device_registers.h"
+        #include "fsl_trng_driver.h"
+    #else
+        /* include headers that may be needed to get good seed */
+    #endif
+#endif /* USE_WINDOWS_API */
+
+#ifdef HAVE_INTEL_RDGEN
+    static int wc_InitRng_IntelRD(void) ;
+    #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
+	static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz) ;
+    #else
+    static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz) ;
+    #endif
+    static word32 cpuid_check = 0 ;
+    static word32 cpuid_flags = 0 ;
+    #define CPUID_RDRAND 0x4
+    #define CPUID_RDSEED 0x8
+    #define IS_INTEL_RDRAND     (cpuid_flags&CPUID_RDRAND)
+    #define IS_INTEL_RDSEED     (cpuid_flags&CPUID_RDSEED)
+#endif
+
+#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
+
+/* Start NIST DRBG code */
+
+#define OUTPUT_BLOCK_LEN  (SHA256_DIGEST_SIZE)
+#define MAX_REQUEST_LEN   (0x10000)
+#define RESEED_INTERVAL   (1000000)
+#define SECURITY_STRENGTH (256)
+#define ENTROPY_SZ        (SECURITY_STRENGTH/8)
+#define NONCE_SZ          (ENTROPY_SZ/2)
+#define ENTROPY_NONCE_SZ  (ENTROPY_SZ+NONCE_SZ)
+
+/* Internal return codes */
+#define DRBG_SUCCESS      0
+#define DRBG_ERROR        1
+#define DRBG_FAILURE      2
+#define DRBG_NEED_RESEED  3
+#define DRBG_CONT_FAILURE 4
+
+/* RNG health states */
+#define DRBG_NOT_INIT     0
+#define DRBG_OK           1
+#define DRBG_FAILED       2
+#define DRBG_CONT_FAILED  3
+
+
+enum {
+    drbgInitC     = 0,
+    drbgReseed    = 1,
+    drbgGenerateW = 2,
+    drbgGenerateH = 3,
+    drbgInitV
+};
+
+
+typedef struct DRBG {
+    word32 reseedCtr;
+    word32 lastBlock;
+    byte V[DRBG_SEED_LEN];
+    byte C[DRBG_SEED_LEN];
+    byte   matchCount;
+} DRBG;
+
+
+static int wc_RNG_HealthTestLocal(int reseed);
+
+/* Hash Derivation Function */
+/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
+static int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type,
+                                                  const byte* inA, word32 inASz,
+                                                  const byte* inB, word32 inBSz)
+{
+    byte ctr;
+    int i;
+    int len;
+    word32 bits = (outSz * 8); /* reverse byte order */
+    Sha256 sha;
+    byte digest[SHA256_DIGEST_SIZE];
+
+    (void)drbg;
+    #ifdef LITTLE_ENDIAN_ORDER
+        bits = ByteReverseWord32(bits);
+    #endif
+    len = (outSz / OUTPUT_BLOCK_LEN)
+        + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
+
+    for (i = 0, ctr = 1; i < len; i++, ctr++)
+    {
+        if (wc_InitSha256(&sha) != 0)
+            return DRBG_FAILURE;
+
+        if (wc_Sha256Update(&sha, &ctr, sizeof(ctr)) != 0)
+            return DRBG_FAILURE;
+
+        if (wc_Sha256Update(&sha, (byte*)&bits, sizeof(bits)) != 0)
+            return DRBG_FAILURE;
+
+        /* churning V is the only string that doesn't have the type added */
+        if (type != drbgInitV)
+            if (wc_Sha256Update(&sha, &type, sizeof(type)) != 0)
+                return DRBG_FAILURE;
+
+        if (wc_Sha256Update(&sha, inA, inASz) != 0)
+            return DRBG_FAILURE;
+
+        if (inB != NULL && inBSz > 0)
+            if (wc_Sha256Update(&sha, inB, inBSz) != 0)
+                return DRBG_FAILURE;
+
+        if (wc_Sha256Final(&sha, digest) != 0)
+            return DRBG_FAILURE;
+
+        if (outSz > OUTPUT_BLOCK_LEN) {
+            XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);
+            outSz -= OUTPUT_BLOCK_LEN;
+            out += OUTPUT_BLOCK_LEN;
+        }
+        else {
+            XMEMCPY(out, digest, outSz);
+        }
+    }
+    ForceZero(digest, sizeof(digest));
+
+    return DRBG_SUCCESS;
+}
+
+
+/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
+static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz)
+{
+    byte seed[DRBG_SEED_LEN];
+
+    if (Hash_df(drbg, seed, sizeof(seed), drbgReseed, drbg->V, sizeof(drbg->V),
+                                          entropy, entropySz) != DRBG_SUCCESS) {
+        return DRBG_FAILURE;
+    }
+
+    XMEMCPY(drbg->V, seed, sizeof(drbg->V));
+    ForceZero(seed, sizeof(seed));
+
+    if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
+                                    sizeof(drbg->V), NULL, 0) != DRBG_SUCCESS) {
+        return DRBG_FAILURE;
+    }
+
+    drbg->reseedCtr = 1;
+    drbg->lastBlock = 0;
+    drbg->matchCount = 0;
+    return DRBG_SUCCESS;
+}
+
+static INLINE void array_add_one(byte* data, word32 dataSz)
+{
+    int i;
+
+    for (i = dataSz - 1; i >= 0; i--)
+    {
+        data[i]++;
+        if (data[i] != 0) break;
+    }
+}
+
+
+/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
+static int Hash_gen(DRBG* drbg, byte* out, word32 outSz, const byte* V)
+{
+    byte data[DRBG_SEED_LEN];
+    int i;
+    int len;
+    word32 checkBlock;
+    Sha256 sha;
+    byte digest[SHA256_DIGEST_SIZE];
+
+    /* Special case: outSz is 0 and out is NULL. wc_Generate a block to save for
+     * the continuous test. */
+
+    if (outSz == 0) outSz = 1;
+
+    len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
+
+    XMEMCPY(data, V, sizeof(data));
+    for (i = 0; i < len; i++) {
+        if (wc_InitSha256(&sha) != 0 ||
+            wc_Sha256Update(&sha, data, sizeof(data)) != 0 ||
+            wc_Sha256Final(&sha, digest) != 0) {
+
+            return DRBG_FAILURE;
+        }
+
+        XMEMCPY(&checkBlock, digest, sizeof(word32));
+        if (drbg->reseedCtr > 1 && checkBlock == drbg->lastBlock) {
+            if (drbg->matchCount == 1) {
+                return DRBG_CONT_FAILURE;
+            }
+            else {
+                if (i == len) {
+                    len++;
+                }
+                drbg->matchCount = 1;
+            }
+        }
+        else {
+            drbg->matchCount = 0;
+            drbg->lastBlock = checkBlock;
+        }
+
+        if (outSz >= OUTPUT_BLOCK_LEN) {
+            XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);
+            outSz -= OUTPUT_BLOCK_LEN;
+            out += OUTPUT_BLOCK_LEN;
+            array_add_one(data, DRBG_SEED_LEN);
+        }
+        else if (out != NULL && outSz != 0) {
+            XMEMCPY(out, digest, outSz);
+            outSz = 0;
+        }
+    }
+    ForceZero(data, sizeof(data));
+
+    return DRBG_SUCCESS;
+}
+
+
+static INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
+{
+    word16 carry = 0;
+
+    if (dLen > 0 && sLen > 0 && dLen >= sLen) {
+        int sIdx, dIdx;
+
+        for (sIdx = sLen - 1, dIdx = dLen - 1; sIdx >= 0; dIdx--, sIdx--)
+        {
+            carry += d[dIdx] + s[sIdx];
+            d[dIdx] = (byte)carry;
+            carry >>= 8;
+        }
+
+        for (; carry != 0 && dIdx >= 0; dIdx--) {
+            carry += d[dIdx];
+            d[dIdx] = (byte)carry;
+            carry >>= 8;
+        }
+    }
+}
+
+
+/* Returns: DRBG_SUCCESS, DRBG_NEED_RESEED, or DRBG_FAILURE */
+static int Hash_DRBG_Generate(DRBG* drbg, byte* out, word32 outSz)
+{
+    int ret = DRBG_NEED_RESEED;
+    Sha256 sha;
+    byte digest[SHA256_DIGEST_SIZE];
+
+    if (drbg->reseedCtr != RESEED_INTERVAL) {
+        byte type = drbgGenerateH;
+        word32 reseedCtr = drbg->reseedCtr;
+
+        ret = Hash_gen(drbg, out, outSz, drbg->V);
+        if (ret == DRBG_SUCCESS) {
+            if (wc_InitSha256(&sha) != 0 ||
+                wc_Sha256Update(&sha, &type, sizeof(type)) != 0 ||
+                wc_Sha256Update(&sha, drbg->V, sizeof(drbg->V)) != 0 ||
+                wc_Sha256Final(&sha, digest) != 0) {
+
+                ret = DRBG_FAILURE;
+            }
+            else {
+                array_add(drbg->V, sizeof(drbg->V), digest, sizeof(digest));
+                array_add(drbg->V, sizeof(drbg->V), drbg->C, sizeof(drbg->C));
+                #ifdef LITTLE_ENDIAN_ORDER
+                    reseedCtr = ByteReverseWord32(reseedCtr);
+                #endif
+                array_add(drbg->V, sizeof(drbg->V),
+                                          (byte*)&reseedCtr, sizeof(reseedCtr));
+                ret = DRBG_SUCCESS;
+            }
+            drbg->reseedCtr++;
+        }
+    }
+    ForceZero(digest, sizeof(digest));
+
+    return ret;
+}
+
+
+/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
+static int Hash_DRBG_Instantiate(DRBG* drbg, const byte* seed, word32 seedSz,
+                                             const byte* nonce, word32 nonceSz)
+{
+    int ret = DRBG_FAILURE;
+
+    XMEMSET(drbg, 0, sizeof(DRBG));
+
+    if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz,
+                                              nonce, nonceSz) == DRBG_SUCCESS &&
+        Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
+                                    sizeof(drbg->V), NULL, 0) == DRBG_SUCCESS) {
+
+        drbg->reseedCtr = 1;
+        drbg->lastBlock = 0;
+        drbg->matchCount = 0;
+        ret = DRBG_SUCCESS;
+    }
+
+    return ret;
+}
+
+
+/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
+static int Hash_DRBG_Uninstantiate(DRBG* drbg)
+{
+    word32 i;
+    int    compareSum = 0;
+    byte*  compareDrbg = (byte*)drbg;
+
+    ForceZero(drbg, sizeof(DRBG));
+
+    for (i = 0; i < sizeof(DRBG); i++)
+        compareSum |= compareDrbg[i] ^ 0;
+
+    return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
+}
+
+/* End NIST DRBG Code */
+
+
+/* Get seed and key cipher */
+int wc_InitRng(WC_RNG* rng)
+{
+    int ret = BAD_FUNC_ARG;
+
+    if (rng != NULL) {
+        if (wc_RNG_HealthTestLocal(0) == 0) {
+            byte entropy[ENTROPY_NONCE_SZ];
+
+            rng->drbg =
+                    (struct DRBG*)XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG);
+            if (rng->drbg == NULL) {
+                ret = MEMORY_E;
+            }
+            /* This doesn't use a separate nonce. The entropy input will be
+             * the default size plus the size of the nonce making the seed
+             * size. */
+            else if (wc_GenerateSeed(&rng->seed,
+                                              entropy, ENTROPY_NONCE_SZ) == 0 &&
+                     Hash_DRBG_Instantiate(rng->drbg,
+                          entropy, ENTROPY_NONCE_SZ, NULL, 0) == DRBG_SUCCESS) {
+
+                ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
+            }
+            else
+                ret = DRBG_FAILURE;
+
+            ForceZero(entropy, ENTROPY_NONCE_SZ);
+        }
+        else
+            ret = DRBG_CONT_FAILURE;
+
+        if (ret == DRBG_SUCCESS) {
+            rng->status = DRBG_OK;
+            ret = 0;
+        }
+        else if (ret == DRBG_CONT_FAILURE) {
+            rng->status = DRBG_CONT_FAILED;
+            ret = DRBG_CONT_FIPS_E;
+        }
+        else if (ret == DRBG_FAILURE) {
+            rng->status = DRBG_FAILED;
+            ret = RNG_FAILURE_E;
+        }
+        else {
+            rng->status = DRBG_FAILED;
+        }
+    }
+
+    return ret;
+}
+
+
+/* place a generated block in output */
+int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz)
+{
+    int ret;
+
+    if (rng == NULL || output == NULL || sz > MAX_REQUEST_LEN)
+        return BAD_FUNC_ARG;
+
+    if (rng->status != DRBG_OK)
+        return RNG_FAILURE_E;
+
+    ret = Hash_DRBG_Generate(rng->drbg, output, sz);
+
+    if (ret == DRBG_NEED_RESEED) {
+        if (wc_RNG_HealthTestLocal(1) == 0) {
+            byte entropy[ENTROPY_SZ];
+
+            if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 &&
+                Hash_DRBG_Reseed(rng->drbg, entropy, ENTROPY_SZ)
+                                                              == DRBG_SUCCESS) {
+
+                ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
+                if (ret == DRBG_SUCCESS)
+                    ret = Hash_DRBG_Generate(rng->drbg, output, sz);
+            }
+            else
+                ret = DRBG_FAILURE;
+
+            ForceZero(entropy, ENTROPY_SZ);
+        }
+        else
+            ret = DRBG_CONT_FAILURE;
+    }
+
+    if (ret == DRBG_SUCCESS) {
+        ret = 0;
+    }
+    else if (ret == DRBG_CONT_FAILURE) {
+        ret = DRBG_CONT_FIPS_E;
+        rng->status = DRBG_CONT_FAILED;
+    }
+    else {
+        ret = RNG_FAILURE_E;
+        rng->status = DRBG_FAILED;
+    }
+
+    return ret;
+}
+
+
+int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
+{
+    return wc_RNG_GenerateBlock(rng, b, 1);
+}
+
+
+int wc_FreeRng(WC_RNG* rng)
+{
+    int ret = BAD_FUNC_ARG;
+
+    if (rng != NULL) {
+        if (rng->drbg != NULL) {
+            if (Hash_DRBG_Uninstantiate(rng->drbg) == DRBG_SUCCESS)
+                ret = 0;
+            else
+                ret = RNG_FAILURE_E;
+
+            XFREE(rng->drbg, NULL, DYNAMIC_TYPE_RNG);
+            rng->drbg = NULL;
+        }
+
+        rng->status = DRBG_NOT_INIT;
+    }
+
+    return ret;
+}
+
+
+int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,
+                                  const byte* entropyB, word32 entropyBSz,
+                                  byte* output, word32 outputSz)
+{
+    DRBG drbg;
+
+    if (entropyA == NULL || output == NULL)
+        return BAD_FUNC_ARG;
+
+    if (reseed != 0 && entropyB == NULL)
+        return BAD_FUNC_ARG;
+
+    if (outputSz != (SHA256_DIGEST_SIZE * 4))
+        return -1;
+
+    if (Hash_DRBG_Instantiate(&drbg, entropyA, entropyASz, NULL, 0) != 0)
+        return -1;
+
+    if (reseed) {
+        if (Hash_DRBG_Reseed(&drbg, entropyB, entropyBSz) != 0) {
+            Hash_DRBG_Uninstantiate(&drbg);
+            return -1;
+        }
+    }
+
+    if (Hash_DRBG_Generate(&drbg, output, outputSz) != 0) {
+        Hash_DRBG_Uninstantiate(&drbg);
+        return -1;
+    }
+
+    if (Hash_DRBG_Generate(&drbg, output, outputSz) != 0) {
+        Hash_DRBG_Uninstantiate(&drbg);
+        return -1;
+    }
+
+    if (Hash_DRBG_Uninstantiate(&drbg) != 0) {
+        return -1;
+    }
+
+    return 0;
+}
+
+
+const byte entropyA[] = {
+    0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4,
+    0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00,
+    0x45, 0x4e, 0x81, 0xe9, 0x53, 0x58, 0xa5, 0x69, 0x80, 0x8a, 0xa3, 0x8f,
+    0x2a, 0x72, 0xa6, 0x23, 0x59, 0x91, 0x5a, 0x9f, 0x8a, 0x04, 0xca, 0x68
+};
+
+const byte reseedEntropyA[] = {
+    0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3,
+    0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22,
+    0x80, 0x01, 0x0a, 0x67, 0x39, 0xbc, 0x83, 0xd3
+};
+
+const byte outputA[] = {
+    0x04, 0xee, 0xc6, 0x3b, 0xb2, 0x31, 0xdf, 0x2c, 0x63, 0x0a, 0x1a, 0xfb,
+    0xe7, 0x24, 0x94, 0x9d, 0x00, 0x5a, 0x58, 0x78, 0x51, 0xe1, 0xaa, 0x79,
+    0x5e, 0x47, 0x73, 0x47, 0xc8, 0xb0, 0x56, 0x62, 0x1c, 0x18, 0xbd, 0xdc,
+    0xdd, 0x8d, 0x99, 0xfc, 0x5f, 0xc2, 0xb9, 0x20, 0x53, 0xd8, 0xcf, 0xac,
+    0xfb, 0x0b, 0xb8, 0x83, 0x12, 0x05, 0xfa, 0xd1, 0xdd, 0xd6, 0xc0, 0x71,
+    0x31, 0x8a, 0x60, 0x18, 0xf0, 0x3b, 0x73, 0xf5, 0xed, 0xe4, 0xd4, 0xd0,
+    0x71, 0xf9, 0xde, 0x03, 0xfd, 0x7a, 0xea, 0x10, 0x5d, 0x92, 0x99, 0xb8,
+    0xaf, 0x99, 0xaa, 0x07, 0x5b, 0xdb, 0x4d, 0xb9, 0xaa, 0x28, 0xc1, 0x8d,
+    0x17, 0x4b, 0x56, 0xee, 0x2a, 0x01, 0x4d, 0x09, 0x88, 0x96, 0xff, 0x22,
+    0x82, 0xc9, 0x55, 0xa8, 0x19, 0x69, 0xe0, 0x69, 0xfa, 0x8c, 0xe0, 0x07,
+    0xa1, 0x80, 0x18, 0x3a, 0x07, 0xdf, 0xae, 0x17
+};
+
+const byte entropyB[] = {
+    0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3,
+    0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19,
+    0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, 0x85, 0x81, 0xf9, 0x31,
+    0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d, 0xdb, 0xcb, 0xcc, 0x2e
+};
+
+const byte outputB[] = {
+    0xd3, 0xe1, 0x60, 0xc3, 0x5b, 0x99, 0xf3, 0x40, 0xb2, 0x62, 0x82, 0x64,
+    0xd1, 0x75, 0x10, 0x60, 0xe0, 0x04, 0x5d, 0xa3, 0x83, 0xff, 0x57, 0xa5,
+    0x7d, 0x73, 0xa6, 0x73, 0xd2, 0xb8, 0xd8, 0x0d, 0xaa, 0xf6, 0xa6, 0xc3,
+    0x5a, 0x91, 0xbb, 0x45, 0x79, 0xd7, 0x3f, 0xd0, 0xc8, 0xfe, 0xd1, 0x11,
+    0xb0, 0x39, 0x13, 0x06, 0x82, 0x8a, 0xdf, 0xed, 0x52, 0x8f, 0x01, 0x81,
+    0x21, 0xb3, 0xfe, 0xbd, 0xc3, 0x43, 0xe7, 0x97, 0xb8, 0x7d, 0xbb, 0x63,
+    0xdb, 0x13, 0x33, 0xde, 0xd9, 0xd1, 0xec, 0xe1, 0x77, 0xcf, 0xa6, 0xb7,
+    0x1f, 0xe8, 0xab, 0x1d, 0xa4, 0x66, 0x24, 0xed, 0x64, 0x15, 0xe5, 0x1c,
+    0xcd, 0xe2, 0xc7, 0xca, 0x86, 0xe2, 0x83, 0x99, 0x0e, 0xea, 0xeb, 0x91,
+    0x12, 0x04, 0x15, 0x52, 0x8b, 0x22, 0x95, 0x91, 0x02, 0x81, 0xb0, 0x2d,
+    0xd4, 0x31, 0xf4, 0xc9, 0xf7, 0x04, 0x27, 0xdf
+};
+
+
+static int wc_RNG_HealthTestLocal(int reseed)
+{
+    int ret = 0;
+    byte check[SHA256_DIGEST_SIZE * 4];
+
+    if (reseed) {
+        ret = wc_RNG_HealthTest(1, entropyA, sizeof(entropyA),
+                                reseedEntropyA, sizeof(reseedEntropyA),
+                                check, sizeof(check));
+        if (ret == 0) {
+            if (ConstantCompare(check, outputA, sizeof(check)) != 0)
+                ret = -1;
+        }
+    }
+    else {
+        ret = wc_RNG_HealthTest(0, entropyB, sizeof(entropyB),
+                                NULL, 0,
+                                check, sizeof(check));
+        if (ret == 0) {
+            if (ConstantCompare(check, outputB, sizeof(check)) != 0)
+                ret = -1;
+        }
+    }
+
+    return ret;
+}
+
+
+#else /* HAVE_HASHDRBG || NO_RC4 */
+
+/* Get seed and key cipher */
+int wc_InitRng(WC_RNG* rng)
+{
+    int  ret;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* key;
+    byte* junk;
+#else
+    byte key[32];
+    byte junk[256];
+#endif
+
+#ifdef HAVE_INTEL_RDGEN
+    wc_InitRng_IntelRD() ;
+    if(IS_INTEL_RDRAND)return 0 ;
+#endif
+#ifdef HAVE_CAVIUM
+    if (rng->magic == WOLFSSL_RNG_CAVIUM_MAGIC)
+        return 0;
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    key = (byte*)XMALLOC(32, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (key == NULL)
+        return MEMORY_E;
+
+    junk = (byte*)XMALLOC(256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (junk == NULL) {
+        XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return MEMORY_E;
+    }
+#endif
+
+    ret = wc_GenerateSeed(&rng->seed, key, 32);
+
+    if (ret == 0) {
+        wc_Arc4SetKey(&rng->cipher, key, sizeof(key));
+
+        ret = wc_RNG_GenerateBlock(rng, junk, 256); /*rid initial state*/
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(junk, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+#ifdef HAVE_CAVIUM
+    static void CaviumRNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz);
+#endif
+
+/* place a generated block in output */
+int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz)
+{
+#ifdef HAVE_INTEL_RDGEN
+    if(IS_INTEL_RDRAND)
+        return wc_GenerateRand_IntelRD(NULL, output, sz) ;
+#endif
+#ifdef HAVE_CAVIUM
+    if (rng->magic == WOLFSSL_RNG_CAVIUM_MAGIC)
+        return CaviumRNG_GenerateBlock(rng, output, sz);
+#endif
+    XMEMSET(output, 0, sz);
+    wc_Arc4Process(&rng->cipher, output, output, sz);
+
+    return 0;
+}
+
+
+int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
+{
+    return wc_RNG_GenerateBlock(rng, b, 1);
+}
+
+
+int wc_FreeRng(WC_RNG* rng)
+{
+    (void)rng;
+    return 0;
+}
+
+
+#ifdef HAVE_CAVIUM
+
+#include <wolfssl/ctaocrypt/logging.h>
+#include "cavium_common.h"
+
+/* Initiliaze RNG for use with Nitrox device */
+int wc_InitRngCavium(WC_RNG* rng, int devId)
+{
+    if (rng == NULL)
+        return -1;
+
+    rng->devId = devId;
+    rng->magic = WOLFSSL_RNG_CAVIUM_MAGIC;
+
+    return 0;
+}
+
+
+static void CaviumRNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz)
+{
+    wolfssl_word offset = 0;
+    word32      requestId;
+
+    while (sz > WOLFSSL_MAX_16BIT) {
+        word16 slen = (word16)WOLFSSL_MAX_16BIT;
+        if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId,
+                      rng->devId) != 0) {
+            WOLFSSL_MSG("Cavium RNG failed");
+        }
+        sz     -= WOLFSSL_MAX_16BIT;
+        offset += WOLFSSL_MAX_16BIT;
+    }
+    if (sz) {
+        word16 slen = (word16)sz;
+        if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId,
+                      rng->devId) != 0) {
+            WOLFSSL_MSG("Cavium RNG failed");
+        }
+    }
+}
+
+#endif /* HAVE_CAVIUM */
+
+#endif /* HAVE_HASHDRBG || NO_RC4 */
+
+
+#if defined(HAVE_INTEL_RDGEN)
+
+#ifndef _MSC_VER
+    #define cpuid(reg, leaf, sub)\
+            __asm__ __volatile__ ("cpuid":\
+             "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3]) :\
+             "a" (leaf), "c"(sub));
+
+    #define XASM_LINK(f) asm(f)
+#else
+
+    #include <intrin.h>
+    #define cpuid(a,b) __cpuid((int*)a,b)
+
+    #define XASM_LINK(f)
+
+#endif /* _MSC_VER */
+
+#define EAX 0
+#define EBX 1
+#define ECX 2 
+#define EDX 3
+
+static word32 cpuid_flag(word32 leaf, word32 sub, word32 num, word32 bit) {
+    int got_intel_cpu=0;
+    unsigned int reg[5]; 
+    
+    reg[4] = '\0' ;
+    cpuid(reg, 0, 0);  
+    if(memcmp((char *)&(reg[EBX]), "Genu", 4) == 0 &&  
+                memcmp((char *)&(reg[EDX]), "ineI", 4) == 0 &&  
+                memcmp((char *)&(reg[ECX]), "ntel", 4) == 0) {  
+        got_intel_cpu = 1;  
+    }    
+    if (got_intel_cpu) {
+        cpuid(reg, leaf, sub);
+        return((reg[num]>>bit)&0x1) ;
+    }
+    return 0 ;
+}
+
+static int wc_InitRng_IntelRD()
+{
+    if(cpuid_check==0) {
+        if(cpuid_flag(1, 0, ECX, 30)){ cpuid_flags |= CPUID_RDRAND ;} 
+        if(cpuid_flag(7, 0, EBX, 18)){ cpuid_flags |= CPUID_RDSEED ;}
+        cpuid_check = 1 ;
+    }
+    return 1 ;
+}
+
+#define INTELRD_RETRY 10
+
+#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
+
+/* return 0 on success */
+static INLINE int IntelRDseed32(unsigned int *seed)  
+{  
+    int rdseed;  unsigned char ok ;
+
+    __asm__ volatile("rdseed %0; setc %1":"=r"(rdseed), "=qm"(ok));  
+    if(ok){
+        *seed = rdseed ;
+        return 0 ;
+    } else
+        return 1;
+}
+
+/* return 0 on success */
+static INLINE int IntelRDseed32_r(unsigned int *rnd)  
+{  
+    int i ;
+    for(i=0; i<INTELRD_RETRY;i++) {
+       if(IntelRDseed32(rnd) == 0) return 0 ;
+    }
+    return 1 ;
+}
+
+/* return 0 on success */
+static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz)
+{
+    (void) os ;
+    int ret ;
+    unsigned int rndTmp ;
+
+    for(  ; sz/4 > 0; sz-=4, output+=4) {
+        if(IS_INTEL_RDSEED)ret = IntelRDseed32_r((word32 *)output) ;
+        else return 1 ;
+        if(ret)
+             return 1 ;
+    }
+    if(sz == 0)return 0 ;
+
+    if(IS_INTEL_RDSEED)ret = IntelRDseed32_r(&rndTmp) ;
+    else return 1 ;
+    if(ret)
+         return 1 ;
+    XMEMCPY(output, &rndTmp, sz) ;
+    return 0;
+}
+
+#else
+
+/* return 0 on success */
+static INLINE int IntelRDrand32(unsigned int *rnd)  
+{  
+    int rdrand; unsigned char ok ;  
+    __asm__ volatile("rdrand %0; setc %1":"=r"(rdrand), "=qm"(ok));  
+    if(ok){
+        *rnd = rdrand;
+        return 0 ;
+    } else
+        return 1;
+}
+
+/* return 0 on success */
+static INLINE int IntelRDrand32_r(unsigned int *rnd)  
+{  
+    int i ;
+    for(i=0; i<INTELRD_RETRY;i++) {
+       if(IntelRDrand32(rnd) == 0) return 0 ;
+    }
+    return 1 ;
+}
+
+/* return 0 on success */
+static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz)
+{
+    (void) os ;
+    int ret ;
+    unsigned int rndTmp;
+
+    for(  ; sz/4 > 0; sz-=4, output+=4) {
+        if(IS_INTEL_RDRAND)ret = IntelRDrand32_r((word32 *)output);
+        else return 1 ;
+        if(ret)
+             return 1 ;
+    }
+    if(sz == 0)return 0 ;
+
+    if(IS_INTEL_RDRAND)ret = IntelRDrand32_r(&rndTmp);
+    else return 1 ;
+    if(ret)
+         return 1 ;
+    XMEMCPY(output, &rndTmp, sz) ;
+    return 0;
+}
+#endif /* defined(HAVE_HASHDRBG) || defined(NO_RC4) */
+
+#endif /* HAVE_INTEL_RDGEN */
+
+
+#if defined(USE_WINDOWS_API)
+
+
+int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+{
+    if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
+                            CRYPT_VERIFYCONTEXT))
+        return WINCRYPT_E;
+
+    if (!CryptGenRandom(os->handle, sz, output))
+        return CRYPTGEN_E;
+
+    CryptReleaseContext(os->handle, 0);
+
+    return 0;
+}
+
+
+#elif defined(HAVE_RTP_SYS) || defined(EBSNET)
+
+#include "rtprand.h"   /* rtp_rand () */
+#include "rtptime.h"   /* rtp_get_system_msec() */
+
+
+int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+{
+    int i;
+    rtp_srand(rtp_get_system_msec());
+
+    for (i = 0; i < sz; i++ ) {
+        output[i] = rtp_rand() % 256;
+        if ( (i % 8) == 7)
+            rtp_srand(rtp_get_system_msec());
+    }
+
+    return 0;
+}
+
+
+#elif defined(MICRIUM)
+
+int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+{
+    #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
+        NetSecure_InitSeed(output, sz);
+    #endif
+    return 0;
+}
+
+#elif defined(MICROCHIP_PIC32)
+
+#ifdef MICROCHIP_MPLAB_HARMONY
+    #define PIC32_SEED_COUNT _CP0_GET_COUNT
+#else
+    #if !defined(WOLFSSL_MICROCHIP_PIC32MZ)
+        #include <peripheral/timer.h>
+    #endif
+    #define PIC32_SEED_COUNT ReadCoreTimer
+#endif
+    #ifdef WOLFSSL_MIC32MZ_RNG
+        #include "xc.h"
+        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+        {
+            int i ;
+            byte rnd[8] ;
+            word32 *rnd32 = (word32 *)rnd ;
+            word32 size = sz ;
+            byte* op = output ;
+
+            /* This part has to be replaced with better random seed */
+            RNGNUMGEN1 = ReadCoreTimer();
+            RNGPOLY1 = ReadCoreTimer();
+            RNGPOLY2 = ReadCoreTimer();
+            RNGNUMGEN2 = ReadCoreTimer();
+#ifdef DEBUG_WOLFSSL
+            printf("GenerateSeed::Seed=%08x, %08x\n", RNGNUMGEN1, RNGNUMGEN2) ;
+#endif
+            RNGCONbits.PLEN = 0x40;
+            RNGCONbits.PRNGEN = 1;
+            for(i=0; i<5; i++) { /* wait for RNGNUMGEN ready */
+                volatile int x ;
+                x = RNGNUMGEN1 ;
+                x = RNGNUMGEN2 ;
+            }
+            do {
+                rnd32[0] = RNGNUMGEN1;
+                rnd32[1] = RNGNUMGEN2;
+
+                for(i=0; i<8; i++, op++) {
+                    *op = rnd[i] ;
+                    size -- ;
+                    if(size==0)break ;
+                }
+            } while(size) ;
+            return 0;
+        }
+    #else  /* WOLFSSL_MIC32MZ_RNG */
+        /* uses the core timer, in nanoseconds to seed srand */
+        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+        {
+            int i;
+            srand(PIC32_SEED_COUNT() * 25);
+
+            for (i = 0; i < sz; i++ ) {
+                output[i] = rand() % 256;
+                if ( (i % 8) == 7)
+                    srand(PIC32_SEED_COUNT() * 25);
+            }
+            return 0;
+        }
+    #endif /* WOLFSSL_MIC32MZ_RNG */
+
+#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) || \
+      defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS)
+
+    #ifdef FREESCALE_K70_RNGA
+        /*
+         * wc_Generates a RNG seed using the Random Number Generator Accelerator
+         * on the Kinetis K70. Documentation located in Chapter 37 of
+         * K70 Sub-Family Reference Manual (see Note 3 in the README for link).
+         */
+        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+        {
+            int i;
+
+            /* turn on RNGA module */
+            SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK;
+
+            /* set SLP bit to 0 - "RNGA is not in sleep mode" */
+            RNG_CR &= ~RNG_CR_SLP_MASK;
+
+            /* set HA bit to 1 - "security violations masked" */
+            RNG_CR |= RNG_CR_HA_MASK;
+
+            /* set GO bit to 1 - "output register loaded with data" */
+            RNG_CR |= RNG_CR_GO_MASK;
+
+            for (i = 0; i < sz; i++) {
+
+                /* wait for RNG FIFO to be full */
+                while((RNG_SR & RNG_SR_OREG_LVL(0xF)) == 0) {}
+
+                /* get value */
+                output[i] = RNG_OR;
+            }
+
+            return 0;
+        }
+
+    #elif defined(FREESCALE_K53_RNGB)
+        /*
+         * wc_Generates a RNG seed using the Random Number Generator (RNGB)
+         * on the Kinetis K53. Documentation located in Chapter 33 of
+         * K53 Sub-Family Reference Manual (see note in the README for link).
+         */
+        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+        {
+            int i;
+
+            /* turn on RNGB module */
+            SIM_SCGC3 |= SIM_SCGC3_RNGB_MASK;
+
+            /* reset RNGB */
+            RNG_CMD |= RNG_CMD_SR_MASK;
+
+            /* FIFO generate interrupt, return all zeros on underflow,
+             * set auto reseed */
+            RNG_CR |= (RNG_CR_FUFMOD_MASK | RNG_CR_AR_MASK);
+
+            /* gen seed, clear interrupts, clear errors */
+            RNG_CMD |= (RNG_CMD_GS_MASK | RNG_CMD_CI_MASK | RNG_CMD_CE_MASK);
+
+            /* wait for seeding to complete */
+            while ((RNG_SR & RNG_SR_SDN_MASK) == 0) {}
+
+            for (i = 0; i < sz; i++) {
+
+                /* wait for a word to be available from FIFO */
+                while((RNG_SR & RNG_SR_FIFO_LVL_MASK) == 0) {}
+
+                /* get value */
+                output[i] = RNG_OUT;
+            }
+
+            return 0;
+        }
+
+    #elif defined(FREESCALE_TRNG)
+
+        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+        {
+            TRNG_DRV_GetRandomData(TRNG_INSTANCE, output, sz);
+            return(0);
+        }
+
+    #else
+        #warning "write a real random seed!!!!, just for testing now"
+
+        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+        {
+            int i;
+            for (i = 0; i < sz; i++ )
+                output[i] = i;
+
+            return 0;
+        }
+    #endif /* FREESCALE_K70_RNGA */
+
+#elif defined(WOLFSSL_SAFERTOS) || defined(WOLFSSL_LEANPSK) \
+   || defined(WOLFSSL_IAR_ARM)  || defined(WOLFSSL_MDK_ARM) \
+   || defined(WOLFSSL_uITRON4)  || defined(WOLFSSL_uTKERNEL2)\
+   || defined(WOLFSSL_GENSEED_FORTEST)
+
+#if 0 //ndef _MSC_VER
+#warning "write a real random seed!!!!, just for testing now"
+//#else
+#pragma message("Warning: write a real random seed!!!!, just for testing now")
+
+int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+{
+    word32 i;
+    for (i = 0; i < sz; i++ )
+        output[i] = i;
+
+    (void)os;
+
+    return 0;
+}
+#endif
+
+#elif defined(STM32F2_RNG)
+    #undef RNG
+    #include "stm32f2xx_rng.h"
+    #include "stm32f2xx_rcc.h"
+    /*
+     * wc_Generate a RNG seed using the hardware random number generator
+     * on the STM32F2. Documentation located in STM32F2xx Standard Peripheral
+     * Library document (See note in README).
+     */
+    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+    {
+        int i;
+
+        /* enable RNG clock source */
+        RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
+
+        /* enable RNG peripheral */
+        RNG_Cmd(ENABLE);
+
+        for (i = 0; i < sz; i++) {
+            /* wait until RNG number is ready */
+            while(RNG_GetFlagStatus(RNG_FLAG_DRDY)== RESET) { }
+
+            /* get value */
+            output[i] = RNG_GetRandomNumber();
+        }
+
+        return 0;
+    }
+#elif defined(WOLFSSL_LPC43xx) || defined(WOLFSSL_STM32F2xx) || defined(MBED)
+
+    #warning "write a real random seed!!!!, just for testing now"
+
+    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+    {
+        int i;
+
+        for (i = 0; i < sz; i++ )
+            output[i] = i;
+
+        return 0;
+    }
+
+#elif defined(WOLFSSL_TIRTOS)
+
+    #include <xdc/runtime/Timestamp.h>
+    #include <stdlib.h>
+    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+    {
+        int i;
+        srand(xdc_runtime_Timestamp_get32());
+
+        for (i = 0; i < sz; i++ ) {
+            output[i] = rand() % 256;
+            if ((i % 8) == 7) {
+                srand(xdc_runtime_Timestamp_get32());
+            }
+        }
+
+        return 0;
+    }
+
+#elif defined(CUSTOM_RAND_GENERATE)
+
+   /* Implement your own random generation function
+    * word32 rand_gen(void);
+    * #define CUSTOM_RAND_GENERATE  rand_gen  */
+
+    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+    {
+        word32 i;
+
+        (void)os;
+
+        for (i = 0; i < sz; i++ )
+            output[i] = CUSTOM_RAND_GENERATE();
+
+        return 0;
+    }
+
+#elif defined(NO_DEV_RANDOM)
+
+#error "you need to write an os specific wc_GenerateSeed() here"
+
+/*
+int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+{
+    return 0;
+}
+*/
+
+
+#elif defined(IDIRECT_DEV_RANDOM)
+
+extern int getRandom( int sz, unsigned char *output );
+
+int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+{
+    int num_bytes_returned = 0;
+
+    num_bytes_returned = getRandom( (int) sz, (unsigned char *) output );
+
+    return 0;
+}
+
+
+#else /* !USE_WINDOWS_API && !HAVE_RPT_SYS && !MICRIUM && !NO_DEV_RANDOM */
+
+/* may block */
+int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+{
+    int ret = 0;
+
+
+#if defined(HAVE_INTEL_RDGEN) && (defined(HAVE_HASHDRBG) || defined(NO_RC4))
+    wc_InitRng_IntelRD() ; /* set cpuid_flags if not yet */
+    if(IS_INTEL_RDSEED)
+         return wc_GenerateSeed_IntelRD(NULL, output, sz) ;
+#endif
+
+    os->fd = open("/dev/urandom",O_RDONLY);
+    if (os->fd == -1) {
+        /* may still have /dev/random */
+        os->fd = open("/dev/random",O_RDONLY);
+        if (os->fd == -1)
+            return OPEN_RAN_E;
+    }
+
+    while (sz) {
+        int len = (int)read(os->fd, output, sz);
+        if (len == -1) {
+            ret = READ_RAN_E;
+            break;
+        }
+
+        sz     -= len;
+        output += len;
+
+        if (sz) {
+#ifdef BLOCKING
+            sleep(0);             /* context switch */
+#else
+            ret = RAN_BLOCK_E;
+            break;
+#endif
+        }
+    }
+    close(os->fd);
+
+    return ret;
+}
+
+#endif /* USE_WINDOWS_API */
+#endif /* HAVE_FIPS */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/ripemd.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/ripemd.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/ripemd.c	(revision 164)
@@ -0,0 +1,357 @@
+/* ripemd.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef WOLFSSL_RIPEMD
+
+#include <wolfssl/wolfcrypt/ripemd.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+
+#ifdef min
+#define WOLFSSL_HAVE_MIN
+#endif
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+
+#endif /* WOLFSSL_HAVE_MIN */
+
+void wc_InitRipeMd(RipeMd* ripemd)
+{
+    ripemd->digest[0] = 0x67452301L;
+    ripemd->digest[1] = 0xEFCDAB89L;
+    ripemd->digest[2] = 0x98BADCFEL;
+    ripemd->digest[3] = 0x10325476L;
+    ripemd->digest[4] = 0xC3D2E1F0L;
+
+    ripemd->buffLen = 0;
+    ripemd->loLen   = 0;
+    ripemd->hiLen   = 0;
+}
+
+
+/* for all */
+#define F(x, y, z)    (x ^ y ^ z) 
+#define G(x, y, z)    (z ^ (x & (y^z)))
+#define H(x, y, z)    (z ^ (x | ~y))
+#define I(x, y, z)    (y ^ (z & (x^y)))
+#define J(x, y, z)    (x ^ (y | ~z))
+
+#define k0 0
+#define k1 0x5a827999
+#define k2 0x6ed9eba1
+#define k3 0x8f1bbcdc
+#define k4 0xa953fd4e
+#define k5 0x50a28be6
+#define k6 0x5c4dd124
+#define k7 0x6d703ef3
+#define k8 0x7a6d76e9
+#define k9 0
+
+/* for 160 and 320 */
+#define Subround(f, a, b, c, d, e, x, s, k) \
+    a += f(b, c, d) + x + k;\
+    a = rotlFixed((word32)a, s) + e;\
+    c = rotlFixed((word32)c, 10U)
+
+static void Transform(RipeMd* ripemd)
+{
+    word32 a1, b1, c1, d1, e1, a2, b2, c2, d2, e2;
+    a1 = a2 = ripemd->digest[0];
+    b1 = b2 = ripemd->digest[1];
+    c1 = c2 = ripemd->digest[2];
+    d1 = d2 = ripemd->digest[3];
+    e1 = e2 = ripemd->digest[4];
+
+    Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 11, k0);
+    Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[ 1], 14, k0);
+    Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[ 2], 15, k0);
+    Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[ 3], 12, k0);
+    Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[ 4],  5, k0);
+    Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[ 5],  8, k0);
+    Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[ 6],  7, k0);
+    Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[ 7],  9, k0);
+    Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 11, k0);
+    Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[ 9], 13, k0);
+    Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[10], 14, k0);
+    Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[11], 15, k0);
+    Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[12],  6, k0);
+    Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[13],  7, k0);
+    Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[14],  9, k0);
+    Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[15],  8, k0);
+
+    Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 7],  7, k1);
+    Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[ 4],  6, k1);
+    Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[13],  8, k1);
+    Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[ 1], 13, k1);
+    Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[10], 11, k1);
+    Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 6],  9, k1);
+    Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[15],  7, k1);
+    Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[ 3], 15, k1);
+    Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[12],  7, k1);
+    Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 12, k1);
+    Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 9], 15, k1);
+    Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[ 5],  9, k1);
+    Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[ 2], 11, k1);
+    Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[14],  7, k1);
+    Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[11], 13, k1);
+    Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 8], 12, k1);
+
+    Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[ 3], 11, k2);
+    Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[10], 13, k2);
+    Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[14],  6, k2);
+    Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[ 4],  7, k2);
+    Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 9], 14, k2);
+    Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[15],  9, k2);
+    Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 13, k2);
+    Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[ 1], 15, k2);
+    Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[ 2], 14, k2);
+    Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 7],  8, k2);
+    Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[ 0], 13, k2);
+    Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[ 6],  6, k2);
+    Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[13],  5, k2);
+    Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[11], 12, k2);
+    Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 5],  7, k2);
+    Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[12],  5, k2);
+
+    Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 1], 11, k3);
+    Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[ 9], 12, k3);
+    Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[11], 14, k3);
+    Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[10], 15, k3);
+    Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 0], 14, k3);
+    Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 15, k3);
+    Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[12],  9, k3);
+    Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[ 4],  8, k3);
+    Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[13],  9, k3);
+    Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 3], 14, k3);
+    Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 7],  5, k3);
+    Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[15],  6, k3);
+    Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[14],  8, k3);
+    Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[ 5],  6, k3);
+    Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 6],  5, k3);
+    Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 2], 12, k3);
+
+    Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[ 4],  9, k4);
+    Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 15, k4);
+    Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[ 5],  5, k4);
+    Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[ 9], 11, k4);
+    Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[ 7],  6, k4);
+    Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[12],  8, k4);
+    Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 2], 13, k4);
+    Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[10], 12, k4);
+    Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[14],  5, k4);
+    Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[ 1], 12, k4);
+    Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[ 3], 13, k4);
+    Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 8], 14, k4);
+    Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[11], 11, k4);
+    Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[ 6],  8, k4);
+    Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[15],  5, k4);
+    Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[13],  6, k4);
+
+    Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[ 5],  8, k5);
+    Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[14],  9, k5);
+    Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 7],  9, k5);
+    Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[ 0], 11, k5);
+    Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 13, k5);
+    Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[ 2], 15, k5);
+    Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[11], 15, k5);
+    Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 4],  5, k5);
+    Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[13],  7, k5);
+    Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 6],  7, k5);
+    Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[15],  8, k5);
+    Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 11, k5);
+    Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 1], 14, k5);
+    Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[10], 14, k5);
+    Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 3], 12, k5);
+    Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[12],  6, k5);
+
+    Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 6],  9, k6); 
+    Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[11], 13, k6);
+    Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[ 3], 15, k6);
+    Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[ 7],  7, k6);
+    Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 12, k6);
+    Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[13],  8, k6);
+    Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[ 5],  9, k6);
+    Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[10], 11, k6);
+    Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[14],  7, k6);
+    Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[15],  7, k6);
+    Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 12, k6);
+    Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[12],  7, k6);
+    Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[ 4],  6, k6);
+    Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 15, k6);
+    Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[ 1], 13, k6);
+    Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 2], 11, k6);
+
+    Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[15],  9, k7);
+    Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 5],  7, k7);
+    Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[ 1], 15, k7);
+    Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[ 3], 11, k7);
+    Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 7],  8, k7);
+    Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[14],  6, k7);
+    Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 6],  6, k7);
+    Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 14, k7);
+    Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[11], 12, k7);
+    Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 13, k7);
+    Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[12],  5, k7);
+    Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 14, k7);
+    Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[10], 13, k7);
+    Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 13, k7);
+    Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 4],  7, k7);
+    Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[13],  5, k7);
+
+    Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[ 8], 15, k8);
+    Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[ 6],  5, k8);
+    Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 4],  8, k8);
+    Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 1], 11, k8);
+    Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[ 3], 14, k8);
+    Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[11], 14, k8);
+    Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[15],  6, k8);
+    Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 14, k8);
+    Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 5],  6, k8);
+    Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[12],  9, k8);
+    Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 12, k8);
+    Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[13],  9, k8);
+    Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 9], 12, k8);
+    Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 7],  5, k8);
+    Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[10], 15, k8);
+    Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[14],  8, k8);
+
+    Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[12],  8, k9);
+    Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[15],  5, k9);
+    Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[10], 12, k9);
+    Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 4],  9, k9);
+    Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 1], 12, k9);
+    Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[ 5],  5, k9);
+    Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[ 8], 14, k9);
+    Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[ 7],  6, k9);
+    Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 6],  8, k9);
+    Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 13, k9);
+    Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[13],  6, k9);
+    Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[14],  5, k9);
+    Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[ 0], 15, k9);
+    Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 3], 13, k9);
+    Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 9], 11, k9);
+    Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[11], 11, k9);
+
+    c1                = ripemd->digest[1] + c1 + d2;
+    ripemd->digest[1] = ripemd->digest[2] + d1 + e2;
+    ripemd->digest[2] = ripemd->digest[3] + e1 + a2;
+    ripemd->digest[3] = ripemd->digest[4] + a1 + b2;
+    ripemd->digest[4] = ripemd->digest[0] + b1 + c2;
+    ripemd->digest[0] = c1;
+}
+
+
+static INLINE void AddLength(RipeMd* ripemd, word32 len)
+{
+    word32 tmp = ripemd->loLen;
+    if ( (ripemd->loLen += len) < tmp)
+        ripemd->hiLen++;                       /* carry low to high */
+}
+
+
+void wc_RipeMdUpdate(RipeMd* ripemd, const byte* data, word32 len)
+{
+    /* do block size increments */
+    byte* local = (byte*)ripemd->buffer;
+
+    while (len) {
+        word32 add = min(len, RIPEMD_BLOCK_SIZE - ripemd->buffLen);
+        XMEMCPY(&local[ripemd->buffLen], data, add);
+
+        ripemd->buffLen += add;
+        data         += add;
+        len          -= add;
+
+        if (ripemd->buffLen == RIPEMD_BLOCK_SIZE) {
+            #ifdef BIG_ENDIAN_ORDER
+                ByteReverseWords(ripemd->buffer, ripemd->buffer,
+                                 RIPEMD_BLOCK_SIZE);
+            #endif
+            Transform(ripemd);
+            AddLength(ripemd, RIPEMD_BLOCK_SIZE);
+            ripemd->buffLen = 0;
+        }
+    }
+}
+
+
+void wc_RipeMdFinal(RipeMd* ripemd, byte* hash)
+{
+    byte* local = (byte*)ripemd->buffer;
+
+    AddLength(ripemd, ripemd->buffLen);               /* before adding pads */
+
+    local[ripemd->buffLen++] = 0x80;  /* add 1 */
+
+    /* pad with zeros */
+    if (ripemd->buffLen > RIPEMD_PAD_SIZE) {
+        XMEMSET(&local[ripemd->buffLen], 0, RIPEMD_BLOCK_SIZE - ripemd->buffLen);
+        ripemd->buffLen += RIPEMD_BLOCK_SIZE - ripemd->buffLen;
+
+        #ifdef BIG_ENDIAN_ORDER
+            ByteReverseWords(ripemd->buffer, ripemd->buffer, RIPEMD_BLOCK_SIZE);
+        #endif
+        Transform(ripemd);
+        ripemd->buffLen = 0;
+    }
+    XMEMSET(&local[ripemd->buffLen], 0, RIPEMD_PAD_SIZE - ripemd->buffLen);
+   
+    /* put lengths in bits */
+    ripemd->loLen = ripemd->loLen << 3;
+    ripemd->hiLen = (ripemd->loLen >> (8*sizeof(ripemd->loLen) - 3)) + 
+                 (ripemd->hiLen << 3);
+
+    /* store lengths */
+    #ifdef BIG_ENDIAN_ORDER
+        ByteReverseWords(ripemd->buffer, ripemd->buffer, RIPEMD_BLOCK_SIZE);
+    #endif
+    /* ! length ordering dependent on digest endian type ! */
+    XMEMCPY(&local[RIPEMD_PAD_SIZE], &ripemd->loLen, sizeof(word32));
+    XMEMCPY(&local[RIPEMD_PAD_SIZE + sizeof(word32)], &ripemd->hiLen, 
+           sizeof(word32));
+
+    Transform(ripemd);
+    #ifdef BIG_ENDIAN_ORDER
+        ByteReverseWords(ripemd->digest, ripemd->digest, RIPEMD_DIGEST_SIZE);
+    #endif
+    XMEMCPY(hash, ripemd->digest, RIPEMD_DIGEST_SIZE);
+
+    wc_InitRipeMd(ripemd);  /* reset state */
+}
+
+
+#endif /* WOLFSSL_RIPEMD */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/rsa.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/rsa.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/rsa.c	(revision 164)
@@ -0,0 +1,895 @@
+/* rsa.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_RSA
+
+#include <wolfssl/wolfcrypt/rsa.h>
+
+#ifdef HAVE_FIPS
+int  wc_InitRsaKey(RsaKey* key, void* ptr)
+{
+    return InitRsaKey_fips(key, ptr);
+}
+
+
+int  wc_FreeRsaKey(RsaKey* key)
+{
+    return FreeRsaKey_fips(key);
+}
+
+
+int  wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
+                                 word32 outLen, RsaKey* key, WC_RNG* rng)
+{
+    return RsaPublicEncrypt_fips(in, inLen, out, outLen, key, rng);
+}
+
+
+int  wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out,
+                                        RsaKey* key)
+{
+    return RsaPrivateDecryptInline_fips(in, inLen, out, key);
+}
+
+
+int  wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
+                                  word32 outLen, RsaKey* key)
+{
+    return RsaPrivateDecrypt_fips(in, inLen, out, outLen, key);
+}
+
+
+int  wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out,
+                            word32 outLen, RsaKey* key, WC_RNG* rng)
+{
+    return RsaSSL_Sign_fips(in, inLen, out, outLen, key, rng);
+}
+
+
+int  wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
+{
+    return RsaSSL_VerifyInline_fips(in, inLen, out, key);
+}
+
+
+int  wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out,
+                              word32 outLen, RsaKey* key)
+{
+    return RsaSSL_Verify_fips(in, inLen, out, outLen, key);
+}
+
+
+int  wc_RsaEncryptSize(RsaKey* key)
+{
+    return RsaEncryptSize_fips(key);
+}
+
+
+int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b,
+                           word32* bSz)
+{
+    /* not specified as fips so not needing _fips */
+    return RsaFlattenPublicKey(key, a, aSz, b, bSz);
+}
+#ifdef WOLFSSL_KEY_GEN
+    int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
+    {
+        return MakeRsaKey(key, size, e, rng);
+    }
+#endif
+
+
+#ifdef HAVE_CAVIUM
+    int  wc_RsaInitCavium(RsaKey* key, int i)
+    {
+        return RsaInitCavium(key, i);
+    }
+
+
+    void wc_RsaFreeCavium(RsaKey* key)
+    {
+        RsaFreeCavium(key);
+    }
+#endif
+
+/* these are functions in asn and are routed to wolfssl/wolfcrypt/asn.c
+* wc_RsaPrivateKeyDecode
+* wc_RsaPublicKeyDecode
+*/
+
+#else /* else build without fips */
+#include <wolfssl/wolfcrypt/random.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+#ifdef HAVE_CAVIUM
+    static int  InitCaviumRsaKey(RsaKey* key, void* heap);
+    static int  FreeCaviumRsaKey(RsaKey* key);
+    static int  CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
+                                       word32 outLen, RsaKey* key);
+    static int  CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
+                                        word32 outLen, RsaKey* key);
+    static int  CaviumRsaSSL_Sign(const byte* in, word32 inLen, byte* out,
+                                  word32 outLen, RsaKey* key);
+    static int  CaviumRsaSSL_Verify(const byte* in, word32 inLen, byte* out,
+                                    word32 outLen, RsaKey* key);
+#endif
+
+enum {
+    RSA_PUBLIC_ENCRYPT  = 0,
+    RSA_PUBLIC_DECRYPT  = 1,
+    RSA_PRIVATE_ENCRYPT = 2,
+    RSA_PRIVATE_DECRYPT = 3,
+
+    RSA_BLOCK_TYPE_1 = 1,
+    RSA_BLOCK_TYPE_2 = 2,
+
+    RSA_MIN_SIZE = 512,
+    RSA_MAX_SIZE = 4096,
+
+    RSA_MIN_PAD_SZ   = 11      /* seperator + 0 + pad value + 8 pads */
+};
+
+
+int wc_InitRsaKey(RsaKey* key, void* heap)
+{
+#ifdef HAVE_CAVIUM
+    if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
+        return InitCaviumRsaKey(key, heap);
+#endif
+
+    key->type = -1;  /* haven't decided yet */
+    key->heap = heap;
+
+/* TomsFastMath doesn't use memory allocation */
+#ifndef USE_FAST_MATH
+    key->n.dp = key->e.dp = 0;  /* public  alloc parts */
+
+    key->d.dp = key->p.dp  = 0;  /* private alloc parts */
+    key->q.dp = key->dP.dp = 0;  
+    key->u.dp = key->dQ.dp = 0;
+#else
+    mp_init(&key->n);
+    mp_init(&key->e);
+    mp_init(&key->d);
+    mp_init(&key->p);
+    mp_init(&key->q);
+    mp_init(&key->dP);
+    mp_init(&key->dQ);
+    mp_init(&key->u);
+#endif
+
+    return 0;
+}
+
+
+int wc_FreeRsaKey(RsaKey* key)
+{
+    (void)key;
+
+#ifdef HAVE_CAVIUM
+    if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
+        return FreeCaviumRsaKey(key);
+#endif
+
+/* TomsFastMath doesn't use memory allocation */
+#ifndef USE_FAST_MATH
+    if (key->type == RSA_PRIVATE) {
+        mp_clear(&key->u);
+        mp_clear(&key->dQ);
+        mp_clear(&key->dP);
+        mp_clear(&key->q);
+        mp_clear(&key->p);
+        mp_clear(&key->d);
+    }
+    mp_clear(&key->e);
+    mp_clear(&key->n);
+#endif
+
+    return 0;
+}
+
+static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,
+                   word32 pkcsBlockLen, byte padValue, WC_RNG* rng)
+{
+    if (inputLen == 0)
+        return 0;
+
+    pkcsBlock[0] = 0x0;       /* set first byte to zero and advance */
+    pkcsBlock++; pkcsBlockLen--;
+    pkcsBlock[0] = padValue;  /* insert padValue */
+
+    if (padValue == RSA_BLOCK_TYPE_1)
+        /* pad with 0xff bytes */
+        XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2);
+    else {
+        /* pad with non-zero random bytes */
+        word32 padLen = pkcsBlockLen - inputLen - 1, i;
+        int    ret    = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen);
+
+        if (ret != 0)
+            return ret;
+
+        /* remove zeros */
+        for (i = 1; i < padLen; i++)
+            if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01;
+    }
+
+    pkcsBlock[pkcsBlockLen-inputLen-1] = 0;     /* separator */
+    XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
+
+    return 0;
+}
+
+
+/* UnPad plaintext, set start to *output, return length of plaintext,
+ * < 0 on error */
+static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
+                       byte **output, byte padValue)
+{
+    word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0,
+           invalid = 0,
+           i = 1,
+           outputLen;
+
+    if (pkcsBlock[0] != 0x0) /* skip past zero */
+        invalid = 1;
+    pkcsBlock++; pkcsBlockLen--;
+
+    /* Require block type padValue */
+    invalid = (pkcsBlock[0] != padValue) || invalid;
+
+    /* verify the padding until we find the separator */
+    if (padValue == RSA_BLOCK_TYPE_1) {
+        while (i<pkcsBlockLen && pkcsBlock[i++] == 0xFF) {/* Null body */}
+    }
+    else {
+        while (i<pkcsBlockLen && pkcsBlock[i++]) {/* Null body */}
+    }
+
+    if(!(i==pkcsBlockLen || pkcsBlock[i-1]==0)) {
+        WOLFSSL_MSG("RsaUnPad error, bad formatting");
+        return RSA_PAD_E;
+    }
+
+    outputLen = pkcsBlockLen - i;
+    invalid = (outputLen > maxOutputLen) || invalid;
+
+    if (invalid) {
+        WOLFSSL_MSG("RsaUnPad error, bad formatting");
+        return RSA_PAD_E;
+    }
+
+    *output = (byte *)(pkcsBlock + i);
+    return outputLen;
+}
+
+
+static int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
+                          word32* outLen, int type, RsaKey* key)
+{
+    #define ERROR_OUT(x) { ret = (x); goto done;}
+
+    mp_int tmp;
+    int    ret = 0;
+    word32 keyLen, len;
+
+    if (mp_init(&tmp) != MP_OKAY)
+        return MP_INIT_E;
+
+    if (mp_read_unsigned_bin(&tmp, (byte*)in, inLen) != MP_OKAY)
+        ERROR_OUT(MP_READ_E);
+
+    if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
+        #ifdef RSA_LOW_MEM      /* half as much memory but twice as slow */
+            if (mp_exptmod(&tmp, &key->d, &key->n, &tmp) != MP_OKAY)
+                ERROR_OUT(MP_EXPTMOD_E);
+        #else
+            #define INNER_ERROR_OUT(x) { ret = (x); goto inner_done; }
+
+            mp_int tmpa, tmpb;
+
+            if (mp_init(&tmpa) != MP_OKAY)
+                ERROR_OUT(MP_INIT_E);
+
+            if (mp_init(&tmpb) != MP_OKAY) {
+                mp_clear(&tmpa);
+                ERROR_OUT(MP_INIT_E);
+            }
+
+            /* tmpa = tmp^dP mod p */
+            if (mp_exptmod(&tmp, &key->dP, &key->p, &tmpa) != MP_OKAY)
+                INNER_ERROR_OUT(MP_EXPTMOD_E);
+
+            /* tmpb = tmp^dQ mod q */
+            if (mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb) != MP_OKAY)
+                INNER_ERROR_OUT(MP_EXPTMOD_E);
+
+            /* tmp = (tmpa - tmpb) * qInv (mod p) */
+            if (mp_sub(&tmpa, &tmpb, &tmp) != MP_OKAY)
+                INNER_ERROR_OUT(MP_SUB_E);
+
+            if (mp_mulmod(&tmp, &key->u, &key->p, &tmp) != MP_OKAY)
+                INNER_ERROR_OUT(MP_MULMOD_E);
+
+            /* tmp = tmpb + q * tmp */
+            if (mp_mul(&tmp, &key->q, &tmp) != MP_OKAY)
+                INNER_ERROR_OUT(MP_MUL_E);
+
+            if (mp_add(&tmp, &tmpb, &tmp) != MP_OKAY)
+                INNER_ERROR_OUT(MP_ADD_E);
+
+        inner_done:
+            mp_clear(&tmpa);
+            mp_clear(&tmpb);
+
+            if (ret != 0) return ret;
+
+        #endif   /* RSA_LOW_MEM */
+    }
+    else if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PUBLIC_DECRYPT) {
+        if (mp_exptmod(&tmp, &key->e, &key->n, &tmp) != MP_OKAY)
+            ERROR_OUT(MP_EXPTMOD_E);
+    }
+    else
+        ERROR_OUT(RSA_WRONG_TYPE_E);
+
+    keyLen = mp_unsigned_bin_size(&key->n);
+    if (keyLen > *outLen)
+        ERROR_OUT(RSA_BUFFER_E);
+
+    len = mp_unsigned_bin_size(&tmp);
+
+    /* pad front w/ zeros to match key length */
+    while (len < keyLen) {
+        *out++ = 0x00;
+        len++;
+    }
+
+    *outLen = keyLen;
+
+    /* convert */
+    if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY)
+        ERROR_OUT(MP_TO_E);
+
+done:
+    mp_clear(&tmp);
+    if (ret == MP_EXPTMOD_E) {
+        WOLFSSL_MSG("RSA_FUNCTION MP_EXPTMOD_E: memory/config problem");
+    }
+    return ret;
+}
+
+
+int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
+                     RsaKey* key, WC_RNG* rng)
+{
+    int sz, ret;
+
+#ifdef HAVE_CAVIUM
+    if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
+        return CaviumRsaPublicEncrypt(in, inLen, out, outLen, key);
+#endif
+
+    sz = mp_unsigned_bin_size(&key->n);
+    if (sz > (int)outLen)
+        return RSA_BUFFER_E;
+
+    if (inLen > (word32)(sz - RSA_MIN_PAD_SZ))
+        return RSA_BUFFER_E;
+
+    ret = wc_RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_2, rng);
+    if (ret != 0)
+        return ret;
+
+    if ((ret = wc_RsaFunction(out, sz, out, &outLen,
+                              RSA_PUBLIC_ENCRYPT, key)) < 0)
+        sz = ret;
+
+    return sz;
+}
+
+
+int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
+{
+    int ret;
+
+#ifdef HAVE_CAVIUM
+    if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) {
+        ret = CaviumRsaPrivateDecrypt(in, inLen, in, inLen, key);
+        if (ret > 0)
+            *out = in;
+        return ret;
+    }
+#endif
+
+    if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key))
+            < 0) {
+        return ret;
+    }
+ 
+    return RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_2);
+}
+
+
+int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
+                     RsaKey* key)
+{
+    int plainLen;
+    byte*  tmp;
+    byte*  pad = 0;
+
+#ifdef HAVE_CAVIUM
+    if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
+        return CaviumRsaPrivateDecrypt(in, inLen, out, outLen, key);
+#endif
+
+    tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA);
+    if (tmp == NULL) {
+        return MEMORY_E;
+    }
+
+    XMEMCPY(tmp, in, inLen);
+
+    if ( (plainLen = wc_RsaPrivateDecryptInline(tmp, inLen, &pad, key) ) < 0) {
+        XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
+        return plainLen;
+    }
+    if (plainLen > (int)outLen)
+        plainLen = BAD_FUNC_ARG;
+    else
+        XMEMCPY(out, pad, plainLen);
+
+    ForceZero(tmp, inLen);
+    XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
+
+    return plainLen;
+}
+
+
+/* for Rsa Verify */
+int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
+{
+    int ret;
+
+#ifdef HAVE_CAVIUM
+    if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) {
+        ret = CaviumRsaSSL_Verify(in, inLen, in, inLen, key);
+        if (ret > 0)
+            *out = in;
+        return ret;
+    }
+#endif
+
+    if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PUBLIC_DECRYPT, key))
+            < 0) {
+        return ret;
+    }
+  
+    return RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_1);
+}
+
+
+int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,
+                     RsaKey* key)
+{
+    int plainLen;
+    byte*  tmp;
+    byte*  pad = 0;
+
+#ifdef HAVE_CAVIUM
+    if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
+        return CaviumRsaSSL_Verify(in, inLen, out, outLen, key);
+#endif
+
+    tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA);
+    if (tmp == NULL) {
+        return MEMORY_E;
+    }
+
+    XMEMCPY(tmp, in, inLen);
+
+    if ( (plainLen = wc_RsaSSL_VerifyInline(tmp, inLen, &pad, key) ) < 0) {
+        XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
+        return plainLen;
+    }
+
+    if (plainLen > (int)outLen)
+        plainLen = BAD_FUNC_ARG;
+    else
+        XMEMCPY(out, pad, plainLen);
+
+    ForceZero(tmp, inLen);
+    XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
+
+    return plainLen;
+}
+
+
+/* for Rsa Sign */
+int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
+                      RsaKey* key, WC_RNG* rng)
+{
+    int sz, ret;
+
+#ifdef HAVE_CAVIUM
+    if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
+        return CaviumRsaSSL_Sign(in, inLen, out, outLen, key);
+#endif
+
+    sz = mp_unsigned_bin_size(&key->n);
+    if (sz > (int)outLen)
+        return RSA_BUFFER_E;
+
+    if (inLen > (word32)(sz - RSA_MIN_PAD_SZ))
+        return RSA_BUFFER_E;
+
+    ret = wc_RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1, rng);
+    if (ret != 0)
+        return ret;
+
+    if ((ret = wc_RsaFunction(out, sz, out, &outLen,
+                              RSA_PRIVATE_ENCRYPT,key)) < 0)
+        sz = ret;
+    
+    return sz;
+}
+
+
+int wc_RsaEncryptSize(RsaKey* key)
+{
+#ifdef HAVE_CAVIUM
+    if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
+        return key->c_nSz;
+#endif
+    return mp_unsigned_bin_size(&key->n);
+}
+
+/* flatten RsaKey structure into individual elements (e, n) */
+int wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n,
+                           word32* nSz)
+{
+    int sz, ret;
+
+    if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL)
+       return BAD_FUNC_ARG;
+
+    sz = mp_unsigned_bin_size(&key->e);
+    if ((word32)sz > *nSz)
+        return RSA_BUFFER_E;
+    ret = mp_to_unsigned_bin(&key->e, e);
+    if (ret != MP_OKAY)
+        return ret;
+    *eSz = (word32)sz;
+
+    sz = mp_unsigned_bin_size(&key->n);
+    if ((word32)sz > *nSz)
+        return RSA_BUFFER_E;
+    ret = mp_to_unsigned_bin(&key->n, n);
+    if (ret != MP_OKAY)
+        return ret;
+    *nSz = (word32)sz;
+
+    return 0;
+}
+
+#ifdef WOLFSSL_KEY_GEN
+/* Make an RSA key for size bits, with e specified, 65537 is a good e */
+int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
+{
+    mp_int p, q, tmp1, tmp2, tmp3;
+    int    err;
+
+    if (key == NULL || rng == NULL)
+        return BAD_FUNC_ARG;
+
+    if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE)
+        return BAD_FUNC_ARG;
+
+    if (e < 3 || (e & 1) == 0)
+        return BAD_FUNC_ARG;
+
+    if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY)
+        return err;
+
+    err = mp_set_int(&tmp3, e);
+
+    /* make p */
+    if (err == MP_OKAY) {
+        do {
+            err = mp_rand_prime(&p, size/16, rng, key->heap); /* size in bytes/2 */
+
+            if (err == MP_OKAY)
+                err = mp_sub_d(&p, 1, &tmp1);  /* tmp1 = p-1 */
+
+            if (err == MP_OKAY)
+                err = mp_gcd(&tmp1, &tmp3, &tmp2);  /* tmp2 = gcd(p-1, e) */
+        } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0);  /* e divdes p-1 */
+    }
+
+    /* make q */
+    if (err == MP_OKAY) {
+        do {
+            err = mp_rand_prime(&q, size/16, rng, key->heap); /* size in bytes/2 */
+
+            if (err == MP_OKAY)
+                err = mp_sub_d(&q, 1, &tmp1);  /* tmp1 = q-1 */
+
+            if (err == MP_OKAY)
+                err = mp_gcd(&tmp1, &tmp3, &tmp2);  /* tmp2 = gcd(q-1, e) */
+        } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0);  /* e divdes q-1 */
+    }
+
+    if (err == MP_OKAY)
+        err = mp_init_multi(&key->n, &key->e, &key->d, &key->p, &key->q, NULL);
+
+    if (err == MP_OKAY)
+        err = mp_init_multi(&key->dP, &key->dQ, &key->u, NULL, NULL, NULL);
+
+    if (err == MP_OKAY)
+        err = mp_sub_d(&p, 1, &tmp2);  /* tmp2 = p-1 */
+
+    if (err == MP_OKAY)
+        err = mp_lcm(&tmp1, &tmp2, &tmp1);  /* tmp1 = lcm(p-1, q-1),last loop */
+
+    /* make key */
+    if (err == MP_OKAY)
+        err = mp_set_int(&key->e, e);  /* key->e = e */
+
+    if (err == MP_OKAY)                /* key->d = 1/e mod lcm(p-1, q-1) */
+        err = mp_invmod(&key->e, &tmp1, &key->d);
+
+    if (err == MP_OKAY)
+        err = mp_mul(&p, &q, &key->n);  /* key->n = pq */
+
+    if (err == MP_OKAY)
+        err = mp_sub_d(&p, 1, &tmp1);
+
+    if (err == MP_OKAY)
+        err = mp_sub_d(&q, 1, &tmp2);
+
+    if (err == MP_OKAY)
+        err = mp_mod(&key->d, &tmp1, &key->dP);
+
+    if (err == MP_OKAY)
+        err = mp_mod(&key->d, &tmp2, &key->dQ);
+
+    if (err == MP_OKAY)
+        err = mp_invmod(&q, &p, &key->u);
+
+    if (err == MP_OKAY)
+        err = mp_copy(&p, &key->p);
+
+    if (err == MP_OKAY)
+        err = mp_copy(&q, &key->q);
+
+    if (err == MP_OKAY)
+        key->type = RSA_PRIVATE; 
+
+    mp_clear(&tmp3); 
+    mp_clear(&tmp2); 
+    mp_clear(&tmp1); 
+    mp_clear(&q); 
+    mp_clear(&p);
+
+    if (err != MP_OKAY) {
+        wc_FreeRsaKey(key);        
+        return err;
+    }
+
+    return 0;
+}
+
+
+#endif /* WOLFSSL_KEY_GEN */
+
+
+#ifdef HAVE_CAVIUM
+
+#include <cyassl/ctaocrypt/logging.h>
+#include "cavium_common.h"
+
+/* Initiliaze RSA for use with Nitrox device */
+int RsaInitCavium(RsaKey* rsa, int devId)
+{
+    if (rsa == NULL)
+        return -1;
+
+    if (CspAllocContext(CONTEXT_SSL, &rsa->contextHandle, devId) != 0)
+        return -1;
+
+    rsa->devId = devId;
+    rsa->magic = WOLFSSL_RSA_CAVIUM_MAGIC;
+   
+    return 0;
+}
+
+
+/* Free RSA from use with Nitrox device */
+void wc_RsaFreeCavium(RsaKey* rsa)
+{
+    if (rsa == NULL)
+        return;
+
+    CspFreeContext(CONTEXT_SSL, rsa->contextHandle, rsa->devId);
+    rsa->magic = 0;
+}
+
+
+/* Initialize cavium RSA key */
+static int InitCaviumRsaKey(RsaKey* key, void* heap)
+{
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    key->heap = heap;
+    key->type = -1;   /* don't know yet */
+
+    key->c_n  = NULL;
+    key->c_e  = NULL;
+    key->c_d  = NULL;
+    key->c_p  = NULL;
+    key->c_q  = NULL;
+    key->c_dP = NULL;
+    key->c_dQ = NULL;
+    key->c_u  = NULL;
+
+    key->c_nSz   = 0;
+    key->c_eSz   = 0;
+    key->c_dSz   = 0;
+    key->c_pSz   = 0;
+    key->c_qSz   = 0;
+    key->c_dP_Sz = 0;
+    key->c_dQ_Sz = 0;
+    key->c_uSz   = 0;
+    
+    return 0;
+}
+
+
+/* Free cavium RSA key */
+static int FreeCaviumRsaKey(RsaKey* key)
+{
+    if (key == NULL)
+        return BAD_FUNC_ARG;
+
+    XFREE(key->c_n,  key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
+    XFREE(key->c_e,  key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
+    XFREE(key->c_d,  key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
+    XFREE(key->c_p,  key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
+    XFREE(key->c_q,  key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
+    XFREE(key->c_dP, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
+    XFREE(key->c_dQ, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
+    XFREE(key->c_u,  key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
+
+    return InitCaviumRsaKey(key, key->heap);  /* reset pointers */
+}
+
+
+static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
+                                   word32 outLen, RsaKey* key)
+{
+    word32 requestId;
+    word32 ret;
+
+    if (key == NULL || in == NULL || out == NULL || outLen < (word32)key->c_nSz)
+        return -1;
+
+    ret = CspPkcs1v15Enc(CAVIUM_BLOCKING, BT2, key->c_nSz, key->c_eSz,
+                         (word16)inLen, key->c_n, key->c_e, (byte*)in, out,
+                         &requestId, key->devId);
+    if (ret != 0) {
+        WOLFSSL_MSG("Cavium Enc BT2 failed");
+        return -1;
+    }
+    return key->c_nSz;
+}
+
+
+static INLINE void ato16(const byte* c, word16* u16)
+{
+    *u16 = (c[0] << 8) | (c[1]);
+}
+
+
+static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
+                                    word32 outLen, RsaKey* key)
+{
+    word32 requestId;
+    word32 ret;
+    word16 outSz = (word16)outLen;
+
+    if (key == NULL || in == NULL || out == NULL || inLen != (word32)key->c_nSz)
+        return -1;
+
+    ret = CspPkcs1v15CrtDec(CAVIUM_BLOCKING, BT2, key->c_nSz, key->c_q,
+                            key->c_dQ, key->c_p, key->c_dP, key->c_u,
+                            (byte*)in, &outSz, out, &requestId, key->devId);
+    if (ret != 0) {
+        WOLFSSL_MSG("Cavium CRT Dec BT2 failed");
+        return -1;
+    }
+    ato16((const byte*)&outSz, &outSz); 
+
+    return outSz;
+}
+
+
+static int CaviumRsaSSL_Sign(const byte* in, word32 inLen, byte* out,
+                             word32 outLen, RsaKey* key)
+{
+    word32 requestId;
+    word32 ret;
+
+    if (key == NULL || in == NULL || out == NULL || inLen == 0 || outLen <
+                                                             (word32)key->c_nSz)
+        return -1;
+
+    ret = CspPkcs1v15CrtEnc(CAVIUM_BLOCKING, BT1, key->c_nSz, (word16)inLen,
+                            key->c_q, key->c_dQ, key->c_p, key->c_dP, key->c_u,
+                            (byte*)in, out, &requestId, key->devId);
+    if (ret != 0) {
+        WOLFSSL_MSG("Cavium CRT Enc BT1 failed");
+        return -1;
+    }
+    return key->c_nSz;
+}
+
+
+static int CaviumRsaSSL_Verify(const byte* in, word32 inLen, byte* out,
+                               word32 outLen, RsaKey* key)
+{
+    word32 requestId;
+    word32 ret;
+    word16 outSz = (word16)outLen;
+
+    if (key == NULL || in == NULL || out == NULL || inLen != (word32)key->c_nSz)
+        return -1;
+
+    ret = CspPkcs1v15Dec(CAVIUM_BLOCKING, BT1, key->c_nSz, key->c_eSz,
+                         key->c_n, key->c_e, (byte*)in, &outSz, out,
+                         &requestId, key->devId);
+    if (ret != 0) {
+        WOLFSSL_MSG("Cavium Dec BT1 failed");
+        return -1;
+    }
+    outSz = ntohs(outSz);
+
+    return outSz;
+}
+
+
+#endif /* HAVE_CAVIUM */
+
+#endif /* HAVE_FIPS */
+#endif /* NO_RSA */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/sha.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/sha.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/sha.c	(revision 164)
@@ -0,0 +1,444 @@
+/* sha.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#if !defined(NO_SHA)
+
+#include <wolfssl/wolfcrypt/sha.h>
+#include <wolfssl/wolfcrypt/logging.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+/* fips wrapper calls, user can call direct */
+#ifdef HAVE_FIPS
+	int wc_InitSha(Sha* sha)
+	{
+	    return InitSha_fips(sha);
+	}
+
+
+	int wc_ShaUpdate(Sha* sha, const byte* data, word32 len)
+	{
+	    return ShaUpdate_fips(sha, data, len);
+	}
+
+
+	int wc_ShaFinal(Sha* sha, byte* out)
+	{
+	    return ShaFinal_fips(sha,out);
+    }
+
+#else /* else build without fips */
+
+#if defined(WOLFSSL_TI_HASH)
+    /* #include <wolfcrypt/src/port/ti/ti-hash.c> included by wc_port.c */
+#else
+
+#ifdef WOLFSSL_PIC32MZ_HASH
+#define wc_InitSha   wc_InitSha_sw
+#define wc_ShaUpdate wc_ShaUpdate_sw
+#define wc_ShaFinal  wc_ShaFinal_sw
+#endif
+
+
+#ifdef FREESCALE_MMCAU
+    #include "cau_api.h"
+    #define XTRANSFORM(S,B)  Transform((S), (B))
+#else
+    #define XTRANSFORM(S,B)  Transform((S))
+#endif
+
+#ifdef STM32F2_HASH
+/*
+ * STM32F2 hardware SHA1 support through the STM32F2 standard peripheral
+ * library. Documentation located in STM32F2xx Standard Peripheral Library
+ * document (See note in README).
+ */
+#include "stm32f2xx.h"
+#include "stm32f2xx_hash.h"
+
+int wc_InitSha(Sha* sha)
+{
+    /* STM32F2 struct notes:
+     * sha->buffer  = first 4 bytes used to hold partial block if needed
+     * sha->buffLen = num bytes currently stored in sha->buffer
+     * sha->loLen   = num bytes that have been written to STM32 FIFO
+     */
+    XMEMSET(sha->buffer, 0, SHA_REG_SIZE);
+    sha->buffLen = 0;
+    sha->loLen = 0;
+
+    /* initialize HASH peripheral */
+    HASH_DeInit();
+
+    /* configure algo used, algo mode, datatype */
+    HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE);
+    HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HASH
+                 | HASH_DataType_8b);
+
+    /* reset HASH processor */
+    HASH->CR |= HASH_CR_INIT;
+
+    return 0;
+}
+
+int wc_ShaUpdate(Sha* sha, const byte* data, word32 len)
+{
+    word32 i = 0;
+    word32 fill = 0;
+    word32 diff = 0;
+
+    /* if saved partial block is available */
+    if (sha->buffLen) {
+        fill = 4 - sha->buffLen;
+
+        /* if enough data to fill, fill and push to FIFO */
+        if (fill <= len) {
+            XMEMCPY((byte*)sha->buffer + sha->buffLen, data, fill);
+            HASH_DataIn(*(uint32_t*)sha->buffer);
+
+            data += fill;
+            len -= fill;
+            sha->loLen += 4;
+            sha->buffLen = 0;
+        } else {
+            /* append partial to existing stored block */
+            XMEMCPY((byte*)sha->buffer + sha->buffLen, data, len);
+            sha->buffLen += len;
+            return;
+        }
+    }
+
+    /* write input block in the IN FIFO */
+    for(i = 0; i < len; i += 4)
+    {
+        diff = len - i;
+        if ( diff < 4) {
+            /* store incomplete last block, not yet in FIFO */
+            XMEMSET(sha->buffer, 0, SHA_REG_SIZE);
+            XMEMCPY((byte*)sha->buffer, data, diff);
+            sha->buffLen = diff;
+        } else {
+            HASH_DataIn(*(uint32_t*)data);
+            data+=4;
+        }
+    }
+
+    /* keep track of total data length thus far */
+    sha->loLen += (len - sha->buffLen);
+
+    return 0;
+}
+
+int wc_ShaFinal(Sha* sha, byte* hash)
+{
+    __IO uint16_t nbvalidbitsdata = 0;
+
+    /* finish reading any trailing bytes into FIFO */
+    if (sha->buffLen) {
+        HASH_DataIn(*(uint32_t*)sha->buffer);
+        sha->loLen += sha->buffLen;
+    }
+
+    /* calculate number of valid bits in last word of input data */
+    nbvalidbitsdata = 8 * (sha->loLen % SHA_REG_SIZE);
+
+    /* configure number of valid bits in last word of the data */
+    HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
+
+    /* start HASH processor */
+    HASH_StartDigest();
+
+    /* wait until Busy flag == RESET */
+    while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {}
+
+    /* read message digest */
+    sha->digest[0] = HASH->HR[0];
+    sha->digest[1] = HASH->HR[1];
+    sha->digest[2] = HASH->HR[2];
+    sha->digest[3] = HASH->HR[3];
+    sha->digest[4] = HASH->HR[4];
+
+    ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
+
+    XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE);
+
+    return wc_InitSha(sha);  /* reset state */
+}
+
+#else /* wc_ software implementation */
+
+#ifdef min
+#define WOLFSSL_HAVE_MIN
+#endif
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+
+#endif /* WOLFSSL_HAVE_MIN */
+
+
+int wc_InitSha(Sha* sha)
+{
+    int ret = 0;
+#ifdef FREESCALE_MMCAU
+    ret = wolfSSL_CryptHwMutexLock();
+    if(ret != 0) {
+        return ret;
+    }
+    cau_sha1_initialize_output(sha->digest);
+    wolfSSL_CryptHwMutexUnLock();
+#else
+    sha->digest[0] = 0x67452301L;
+    sha->digest[1] = 0xEFCDAB89L;
+    sha->digest[2] = 0x98BADCFEL;
+    sha->digest[3] = 0x10325476L;
+    sha->digest[4] = 0xC3D2E1F0L;
+#endif
+
+    sha->buffLen = 0;
+    sha->loLen   = 0;
+    sha->hiLen   = 0;
+
+    return ret;
+}
+
+#ifdef FREESCALE_MMCAU
+static int Transform(Sha* sha, byte* data)
+{
+    int ret = wolfSSL_CryptHwMutexLock();
+    if(ret == 0) {
+        cau_sha1_hash_n(data, 1, sha->digest);
+        wolfSSL_CryptHwMutexUnLock();
+    }
+    return ret;
+}
+#endif /* FREESCALE_MMCAU */
+        
+#ifndef FREESCALE_MMCAU
+
+#define blk0(i) (W[i] = sha->buffer[i])
+#define blk1(i) (W[(i)&15] = \
+rotlFixed(W[((i)+13)&15]^W[((i)+8)&15]^W[((i)+2)&15]^W[(i)&15],1))
+
+#define f1(x,y,z) ((z)^((x) &((y)^(z))))
+#define f2(x,y,z) ((x)^(y)^(z))
+#define f3(x,y,z) (((x)&(y))|((z)&((x)|(y))))
+#define f4(x,y,z) ((x)^(y)^(z))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk0((i)) + 0x5A827999+ \
+rotlFixed((v),5); (w) = rotlFixed((w),30);
+#define R1(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk1((i)) + 0x5A827999+ \
+rotlFixed((v),5); (w) = rotlFixed((w),30);
+#define R2(v,w,x,y,z,i) (z)+= f2((w),(x),(y)) + blk1((i)) + 0x6ED9EBA1+ \
+rotlFixed((v),5); (w) = rotlFixed((w),30);
+#define R3(v,w,x,y,z,i) (z)+= f3((w),(x),(y)) + blk1((i)) + 0x8F1BBCDC+ \
+rotlFixed((v),5); (w) = rotlFixed((w),30);
+#define R4(v,w,x,y,z,i) (z)+= f4((w),(x),(y)) + blk1((i)) + 0xCA62C1D6+ \
+rotlFixed((v),5); (w) = rotlFixed((w),30);
+
+static void Transform(Sha* sha)
+{
+    word32 W[SHA_BLOCK_SIZE / sizeof(word32)];
+
+    /* Copy context->state[] to working vars */
+    word32 a = sha->digest[0];
+    word32 b = sha->digest[1];
+    word32 c = sha->digest[2];
+    word32 d = sha->digest[3];
+    word32 e = sha->digest[4];
+
+#ifdef USE_SLOW_SHA
+    word32 t, i;
+
+    for (i = 0; i < 16; i++) {
+        R0(a, b, c, d, e, i);
+        t = e; e = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 20; i++) {
+        R1(a, b, c, d, e, i);
+        t = e; e = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 40; i++) {
+        R2(a, b, c, d, e, i);
+        t = e; e = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 60; i++) {
+        R3(a, b, c, d, e, i);
+        t = e; e = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 80; i++) {
+        R4(a, b, c, d, e, i);
+        t = e; e = d; d = c; c = b; b = a; a = t;
+    }
+#else
+    /* nearly 1 K bigger in code size but 25% faster  */
+    /* 4 rounds of 20 operations each. Loop unrolled. */
+    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+
+    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+
+    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+
+    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+
+    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+#endif
+
+    /* Add the working vars back into digest state[] */
+    sha->digest[0] += a;
+    sha->digest[1] += b;
+    sha->digest[2] += c;
+    sha->digest[3] += d;
+    sha->digest[4] += e;
+}
+
+#endif /* FREESCALE_MMCAU */
+
+
+static INLINE void AddLength(Sha* sha, word32 len)
+{
+    word32 tmp = sha->loLen;
+    if ( (sha->loLen += len) < tmp)
+        sha->hiLen++;                       /* carry low to high */
+}
+
+
+int wc_ShaUpdate(Sha* sha, const byte* data, word32 len)
+{
+    /* do block size increments */
+    byte* local = (byte*)sha->buffer;
+
+    while (len) {
+        word32 add = min(len, SHA_BLOCK_SIZE - sha->buffLen);
+        XMEMCPY(&local[sha->buffLen], data, add);
+
+        sha->buffLen += add;
+        data         += add;
+        len          -= add;
+
+        if (sha->buffLen == SHA_BLOCK_SIZE) {
+#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+            ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE);
+#endif
+            XTRANSFORM(sha, local);
+            AddLength(sha, SHA_BLOCK_SIZE);
+            sha->buffLen = 0;
+        }
+    }
+
+    return 0;
+}
+
+
+int wc_ShaFinal(Sha* sha, byte* hash)
+{
+    byte* local = (byte*)sha->buffer;
+
+    AddLength(sha, sha->buffLen);  /* before adding pads */
+
+    local[sha->buffLen++] = 0x80;  /* add 1 */
+
+    /* pad with zeros */
+    if (sha->buffLen > SHA_PAD_SIZE) {
+        XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen);
+        sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen;
+
+#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+        ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE);
+#endif
+        XTRANSFORM(sha, local);
+        sha->buffLen = 0;
+    }
+    XMEMSET(&local[sha->buffLen], 0, SHA_PAD_SIZE - sha->buffLen);
+
+    /* put lengths in bits */
+    sha->hiLen = (sha->loLen >> (8*sizeof(sha->loLen) - 3)) +
+    (sha->hiLen << 3);
+    sha->loLen = sha->loLen << 3;
+
+    /* store lengths */
+#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+    ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE);
+#endif
+    /* ! length ordering dependent on digest endian type ! */
+    XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32));
+    XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32));
+
+#ifdef FREESCALE_MMCAU
+    /* Kinetis requires only these bytes reversed */
+    ByteReverseWords(&sha->buffer[SHA_PAD_SIZE/sizeof(word32)],
+                     &sha->buffer[SHA_PAD_SIZE/sizeof(word32)],
+                     2 * sizeof(word32));
+#endif
+
+    XTRANSFORM(sha, local);
+#ifdef LITTLE_ENDIAN_ORDER
+    ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
+#endif
+    XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE);
+
+    return wc_InitSha(sha);  /* reset state */
+}
+
+#endif /* STM32F2_HASH */
+
+
+
+#endif /* HAVE_FIPS */
+#endif /* WOLFSSL_TI_HASH */
+#endif /* NO_SHA */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/sha256.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/sha256.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/sha256.c	(revision 164)
@@ -0,0 +1,1742 @@
+/* sha256.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* code submitted by raphael.huck@efixo.com */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+#include <wolfssl/wolfcrypt/sha256.h>
+
+#if !defined(NO_SHA256)
+#ifdef HAVE_FIPS
+
+int wc_InitSha256(Sha256* sha)
+{
+    return InitSha256_fips(sha);
+}
+
+
+int wc_Sha256Update(Sha256* sha, const byte* data, word32 len)
+{
+    return Sha256Update_fips(sha, data, len);
+}
+
+
+int wc_Sha256Final(Sha256* sha, byte* out)
+{
+    return Sha256Final_fips(sha, out);
+}
+
+
+#else /* else build without fips */
+
+#if !defined(NO_SHA256) && defined(WOLFSSL_TI_HASH)
+    /* #include <wolfcrypt/src/port/ti/ti-hash.c> included by wc_port.c */
+#else
+
+#if !defined (ALIGN32)
+    #if defined (__GNUC__)
+        #define ALIGN32 __attribute__ ( (aligned (32)))
+    #elif defined(_MSC_VER)
+        /* disable align warning, we want alignment ! */
+        #pragma warning(disable: 4324)
+        #define ALIGN32 __declspec (align (32))
+    #else
+        #define ALIGN32
+    #endif
+#endif
+
+#ifdef WOLFSSL_PIC32MZ_HASH
+#define wc_InitSha256   wc_InitSha256_sw
+#define wc_Sha256Update wc_Sha256Update_sw
+#define wc_Sha256Final  wc_Sha256Final_sw
+#endif
+
+#ifdef HAVE_FIPS
+    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
+    #define FIPS_NO_WRAPPERS
+#endif
+
+#if defined(USE_INTEL_SPEEDUP)
+#define HAVE_INTEL_AVX1
+#define HAVE_INTEL_AVX2
+
+#if defined(DEBUG_XMM)
+#include "stdio.h"
+#endif
+
+#endif
+
+#if defined(HAVE_INTEL_AVX2)
+#define HAVE_INTEL_RORX
+#endif
+ 
+
+/*****
+Intel AVX1/AVX2 Macro Control Structure
+
+#define HAVE_INTEL_AVX1
+#define HAVE_INTEL_AVX2
+
+#define HAVE_INTEL_RORX
+
+
+int InitSha256(Sha256* sha256) { 
+     Save/Recover XMM, YMM
+     ...
+}
+
+#if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
+  Transform() ; Function prototype 
+#else
+  Transform() {   }
+  int Sha256Final() { 
+     Save/Recover XMM, YMM
+     ...
+  }
+#endif
+
+#if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
+    #if defined(HAVE_INTEL_RORX
+         #define RND with rorx instuction
+    #else
+        #define RND
+    #endif
+#endif
+
+#if defined(HAVE_INTEL_AVX1)
+   
+   #define XMM Instructions/inline asm
+   
+   int Transform() {
+       Stitched Message Sched/Round
+    } 
+   
+#elif defined(HAVE_INTEL_AVX2)
+  
+  #define YMM Instructions/inline asm
+  
+  int Transform() {
+      More granural Stitched Message Sched/Round
+  }
+  
+*/
+
+
+#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+
+/* Each platform needs to query info type 1 from cpuid to see if aesni is
+ * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
+ */
+
+#ifndef _MSC_VER
+    #define cpuid(reg, leaf, sub)\
+            __asm__ __volatile__ ("cpuid":\
+             "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3]) :\
+             "a" (leaf), "c"(sub));
+
+    #define XASM_LINK(f) asm(f)
+#else
+
+    #include <intrin.h>
+    #define cpuid(a,b) __cpuid((int*)a,b)
+
+    #define XASM_LINK(f)
+
+#endif /* _MSC_VER */
+
+#define EAX 0
+#define EBX 1
+#define ECX 2 
+#define EDX 3
+    
+#define CPUID_AVX1   0x1
+#define CPUID_AVX2   0x2
+#define CPUID_RDRAND 0x4
+#define CPUID_RDSEED 0x8
+#define CPUID_BMI2   0x10   /* MULX, RORX */
+
+#define IS_INTEL_AVX1       (cpuid_flags&CPUID_AVX1)
+#define IS_INTEL_AVX2       (cpuid_flags&CPUID_AVX2)
+#define IS_INTEL_BMI2       (cpuid_flags&CPUID_BMI2)
+#define IS_INTEL_RDRAND     (cpuid_flags&CPUID_RDRAND)
+#define IS_INTEL_RDSEED     (cpuid_flags&CPUID_RDSEED)
+
+static word32 cpuid_check = 0 ;
+static word32 cpuid_flags = 0 ;
+
+static word32 cpuid_flag(word32 leaf, word32 sub, word32 num, word32 bit) {
+    int got_intel_cpu=0;
+    unsigned int reg[5]; 
+    
+    reg[4] = '\0' ;
+    cpuid(reg, 0, 0);  
+    if(memcmp((char *)&(reg[EBX]), "Genu", 4) == 0 &&  
+                memcmp((char *)&(reg[EDX]), "ineI", 4) == 0 &&  
+                memcmp((char *)&(reg[ECX]), "ntel", 4) == 0) {  
+        got_intel_cpu = 1;  
+    }    
+    if (got_intel_cpu) {
+        cpuid(reg, leaf, sub);
+        return((reg[num]>>bit)&0x1) ;
+    }
+    return 0 ;
+}
+
+static int set_cpuid_flags(void) {  
+    if(cpuid_check==0) {
+        if(cpuid_flag(1, 0, ECX, 28)){ cpuid_flags |= CPUID_AVX1 ;}
+        if(cpuid_flag(7, 0, EBX, 5)){  cpuid_flags |= CPUID_AVX2 ; }
+        if(cpuid_flag(7, 0, EBX, 8)) { cpuid_flags |= CPUID_BMI2 ; }
+        if(cpuid_flag(1, 0, ECX, 30)){ cpuid_flags |= CPUID_RDRAND ;  } 
+        if(cpuid_flag(7, 0, EBX, 18)){ cpuid_flags |= CPUID_RDSEED ;  }
+        cpuid_check = 1 ;
+        return 0 ;
+    }
+    return 1 ;
+}
+
+
+/* #if defined(HAVE_INTEL_AVX1/2) at the tail of sha512 */
+static int Transform(Sha256* sha256);
+
+#if defined(HAVE_INTEL_AVX1)
+static int Transform_AVX1(Sha256 *sha256) ;
+#endif
+#if defined(HAVE_INTEL_AVX2)
+static int Transform_AVX2(Sha256 *sha256) ; 
+static int Transform_AVX1_RORX(Sha256 *sha256) ; 
+#endif
+
+static int (*Transform_p)(Sha256* sha256) /* = _Transform */;
+
+#define XTRANSFORM(sha256, B)  (*Transform_p)(sha256)
+
+static void set_Transform(void) {
+     if(set_cpuid_flags())return ;
+
+#if defined(HAVE_INTEL_AVX2)
+     if(IS_INTEL_AVX2 && IS_INTEL_BMI2){ 
+         Transform_p = Transform_AVX1_RORX; return ; 
+         Transform_p = Transform_AVX2      ; 
+                  /* for avoiding warning,"not used" */
+     }
+#endif
+#if defined(HAVE_INTEL_AVX1)
+     Transform_p = ((IS_INTEL_AVX1) ? Transform_AVX1 : Transform) ; return ;
+#endif
+     Transform_p = Transform ; return ;
+}
+
+#else
+   #if defined(FREESCALE_MMCAU)
+      #define XTRANSFORM(sha256, B) Transform(sha256, B)
+   #else
+      #define XTRANSFORM(sha256, B) Transform(sha256)
+   #endif
+#endif
+
+/* Dummy for saving MM_REGs on behalf of Transform */
+#if defined(HAVE_INTEL_AVX2)&& !defined(HAVE_INTEL_AVX1)
+#define  SAVE_XMM_YMM   __asm__ volatile("or %%r8d, %%r8d":::\
+  "%ymm4","%ymm5","%ymm6","%ymm7","%ymm8","%ymm9","%ymm10","%ymm11","%ymm12","%ymm13","%ymm14","%ymm15")
+#elif defined(HAVE_INTEL_AVX1)
+#define  SAVE_XMM_YMM   __asm__ volatile("or %%r8d, %%r8d":::\
+    "xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7","xmm8","xmm9","xmm10",\
+    "xmm11","xmm12","xmm13","xmm14","xmm15")
+#else
+#define  SAVE_XMM_YMM
+#endif
+
+#ifdef WOLFSSL_PIC32MZ_HASH
+#define InitSha256   InitSha256_sw
+#define Sha256Update Sha256Update_sw
+#define Sha256Final  Sha256Final_sw
+#endif
+
+#include <wolfssl/wolfcrypt/logging.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+#ifdef FREESCALE_MMCAU
+    #include "cau_api.h"
+#endif
+
+#ifdef min
+#define WOLFSSL_HAVE_MIN
+#endif
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+
+#endif /* WOLFSSL_HAVE_MIN */
+
+
+int wc_InitSha256(Sha256* sha256)
+{
+    int ret = 0;
+    #ifdef FREESCALE_MMCAU
+        ret = wolfSSL_CryptHwMutexLock();
+        if(ret != 0) {
+            return ret;
+        }
+        cau_sha256_initialize_output(sha256->digest);
+        wolfSSL_CryptHwMutexUnLock();
+    #else
+        sha256->digest[0] = 0x6A09E667L;
+        sha256->digest[1] = 0xBB67AE85L;
+        sha256->digest[2] = 0x3C6EF372L;
+        sha256->digest[3] = 0xA54FF53AL;
+        sha256->digest[4] = 0x510E527FL;
+        sha256->digest[5] = 0x9B05688CL;
+        sha256->digest[6] = 0x1F83D9ABL;
+        sha256->digest[7] = 0x5BE0CD19L;
+    #endif
+
+    sha256->buffLen = 0;
+    sha256->loLen   = 0;
+    sha256->hiLen   = 0;
+    
+#if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
+    set_Transform() ; /* choose best Transform function under this runtime environment */
+#endif
+
+    return ret;
+}
+
+
+#if !defined(FREESCALE_MMCAU)
+static const ALIGN32 word32 K[64] = {
+    0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL,
+    0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L,
+    0x243185BEL, 0x550C7DC3L, 0x72BE5D74L, 0x80DEB1FEL, 0x9BDC06A7L,
+    0xC19BF174L, 0xE49B69C1L, 0xEFBE4786L, 0x0FC19DC6L, 0x240CA1CCL,
+    0x2DE92C6FL, 0x4A7484AAL, 0x5CB0A9DCL, 0x76F988DAL, 0x983E5152L,
+    0xA831C66DL, 0xB00327C8L, 0xBF597FC7L, 0xC6E00BF3L, 0xD5A79147L,
+    0x06CA6351L, 0x14292967L, 0x27B70A85L, 0x2E1B2138L, 0x4D2C6DFCL,
+    0x53380D13L, 0x650A7354L, 0x766A0ABBL, 0x81C2C92EL, 0x92722C85L,
+    0xA2BFE8A1L, 0xA81A664BL, 0xC24B8B70L, 0xC76C51A3L, 0xD192E819L,
+    0xD6990624L, 0xF40E3585L, 0x106AA070L, 0x19A4C116L, 0x1E376C08L,
+    0x2748774CL, 0x34B0BCB5L, 0x391C0CB3L, 0x4ED8AA4AL, 0x5B9CCA4FL,
+    0x682E6FF3L, 0x748F82EEL, 0x78A5636FL, 0x84C87814L, 0x8CC70208L,
+    0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L
+};
+
+#endif
+
+#if defined(FREESCALE_MMCAU)
+
+static int Transform(Sha256* sha256, byte* buf)
+{
+    int ret = wolfSSL_CryptHwMutexLock();
+    if(ret == 0) {
+        cau_sha256_hash_n(buf, 1, sha256->digest);
+        wolfSSL_CryptHwMutexUnLock();
+    }
+    return ret;
+}
+
+#endif /* FREESCALE_MMCAU */
+
+#define Ch(x,y,z)       ((z) ^ ((x) & ((y) ^ (z))))
+#define Maj(x,y,z)      ((((x) | (y)) & (z)) | ((x) & (y)))
+#define R(x, n)         (((x)&0xFFFFFFFFU)>>(n))
+
+#define S(x, n)         rotrFixed(x, n)
+#define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
+#define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
+#define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
+#define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
+
+#define RND(a,b,c,d,e,f,g,h,i) \
+     t0 = (h) + Sigma1((e)) + Ch((e), (f), (g)) + K[(i)] + W[(i)]; \
+     t1 = Sigma0((a)) + Maj((a), (b), (c)); \
+     (d) += t0; \
+     (h)  = t0 + t1;
+
+#if !defined(FREESCALE_MMCAU)
+static int Transform(Sha256* sha256)
+{
+    word32 S[8], t0, t1;
+    int i;
+
+#ifdef WOLFSSL_SMALL_STACK
+    word32* W;
+
+    W = (word32*) XMALLOC(sizeof(word32) * 64, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (W == NULL)
+        return MEMORY_E;
+#else
+    word32 W[64];
+#endif
+
+    /* Copy context->state[] to working vars */
+    for (i = 0; i < 8; i++)
+        S[i] = sha256->digest[i];
+
+    for (i = 0; i < 16; i++)
+        W[i] = sha256->buffer[i];
+
+    for (i = 16; i < 64; i++)
+        W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15]) + W[i-16];
+
+    for (i = 0; i < 64; i += 8) {
+        RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
+        RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
+        RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
+        RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
+        RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
+        RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
+        RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
+        RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
+    }
+
+    /* Add the working vars back into digest state[] */
+    for (i = 0; i < 8; i++) {
+        sha256->digest[i] += S[i];
+    }
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return 0;
+}
+
+#endif /* #if !defined(FREESCALE_MMCAU) */
+
+static INLINE void AddLength(Sha256* sha256, word32 len)
+{
+    word32 tmp = sha256->loLen;
+    if ( (sha256->loLen += len) < tmp)
+        sha256->hiLen++;                       /* carry low to high */
+}
+
+int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len)
+{
+
+    /* do block size increments */
+    byte* local = (byte*)sha256->buffer;
+
+    SAVE_XMM_YMM ; /* for Intel AVX */
+
+    while (len) {
+        word32 add = min(len, SHA256_BLOCK_SIZE - sha256->buffLen);
+        XMEMCPY(&local[sha256->buffLen], data, add);
+
+        sha256->buffLen += add;
+        data            += add;
+        len             -= add;
+
+        if (sha256->buffLen == SHA256_BLOCK_SIZE) {
+            int ret;
+
+            #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+                #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+                if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2)
+                #endif
+                ByteReverseWords(sha256->buffer, sha256->buffer,
+                                 SHA256_BLOCK_SIZE);
+            #endif
+            ret = XTRANSFORM(sha256, local);
+            if (ret != 0)
+                return ret;
+
+            AddLength(sha256, SHA256_BLOCK_SIZE);
+            sha256->buffLen = 0;
+        }
+    }
+
+    return 0;
+}
+
+int wc_Sha256Final(Sha256* sha256, byte* hash)
+{
+    byte* local = (byte*)sha256->buffer;
+    int ret;
+    
+    SAVE_XMM_YMM ; /* for Intel AVX */
+
+    AddLength(sha256, sha256->buffLen);  /* before adding pads */
+
+    local[sha256->buffLen++] = 0x80;     /* add 1 */
+
+    /* pad with zeros */
+    if (sha256->buffLen > SHA256_PAD_SIZE) {
+        XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen);
+        sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen;
+
+        #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+            #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+            if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2)
+            #endif
+            ByteReverseWords(sha256->buffer, sha256->buffer, SHA256_BLOCK_SIZE);
+        #endif
+
+        ret = XTRANSFORM(sha256, local);
+        if (ret != 0)
+            return ret;
+
+        sha256->buffLen = 0;
+    }
+    XMEMSET(&local[sha256->buffLen], 0, SHA256_PAD_SIZE - sha256->buffLen);
+
+    /* put lengths in bits */
+    sha256->hiLen = (sha256->loLen >> (8*sizeof(sha256->loLen) - 3)) +
+                 (sha256->hiLen << 3);
+    sha256->loLen = sha256->loLen << 3;
+
+    /* store lengths */
+    #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+        #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+        if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2)
+        #endif
+            ByteReverseWords(sha256->buffer, sha256->buffer, SHA256_BLOCK_SIZE);
+    #endif
+    /* ! length ordering dependent on digest endian type ! */
+    XMEMCPY(&local[SHA256_PAD_SIZE], &sha256->hiLen, sizeof(word32));
+    XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen,
+            sizeof(word32));
+
+    #if defined(FREESCALE_MMCAU) || defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+        /* Kinetis requires only these bytes reversed */
+        #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+        if(IS_INTEL_AVX1 || IS_INTEL_AVX2)
+        #endif
+        ByteReverseWords(&sha256->buffer[SHA256_PAD_SIZE/sizeof(word32)],
+                         &sha256->buffer[SHA256_PAD_SIZE/sizeof(word32)],
+                         2 * sizeof(word32));
+    #endif
+
+    ret = XTRANSFORM(sha256, local);
+    if (ret != 0)
+        return ret;
+
+    #if defined(LITTLE_ENDIAN_ORDER)
+        ByteReverseWords(sha256->digest, sha256->digest, SHA256_DIGEST_SIZE);
+    #endif
+    XMEMCPY(hash, sha256->digest, SHA256_DIGEST_SIZE);
+
+    return wc_InitSha256(sha256);  /* reset state */
+}
+
+
+
+
+#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+
+#define _DigestToReg(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
+    { word32 d ;\
+    d = sha256->digest[0]; __asm__ volatile("movl %0, %"#S_0::"r"(d):SSE_REGs) ;\
+    d = sha256->digest[1]; __asm__ volatile("movl %0, %"#S_1::"r"(d):SSE_REGs) ;\
+    d = sha256->digest[2]; __asm__ volatile("movl %0, %"#S_2::"r"(d):SSE_REGs) ;\
+    d = sha256->digest[3]; __asm__ volatile("movl %0, %"#S_3::"r"(d):SSE_REGs) ;\
+    d = sha256->digest[4]; __asm__ volatile("movl %0, %"#S_4::"r"(d):SSE_REGs) ;\
+    d = sha256->digest[5]; __asm__ volatile("movl %0, %"#S_5::"r"(d):SSE_REGs) ;\
+    d = sha256->digest[6]; __asm__ volatile("movl %0, %"#S_6::"r"(d):SSE_REGs) ;\
+    d = sha256->digest[7]; __asm__ volatile("movl %0, %"#S_7::"r"(d):SSE_REGs) ;\
+}
+
+#define _RegToDigest(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
+    { word32 d ; \
+    __asm__ volatile("movl %"#S_0", %0":"=r"(d)::SSE_REGs) ; sha256->digest[0] += d;\
+    __asm__ volatile("movl %"#S_1", %0":"=r"(d)::SSE_REGs) ; sha256->digest[1] += d;\
+    __asm__ volatile("movl %"#S_2", %0":"=r"(d)::SSE_REGs) ; sha256->digest[2] += d;\
+    __asm__ volatile("movl %"#S_3", %0":"=r"(d)::SSE_REGs) ; sha256->digest[3] += d;\
+    __asm__ volatile("movl %"#S_4", %0":"=r"(d)::SSE_REGs) ; sha256->digest[4] += d;\
+    __asm__ volatile("movl %"#S_5", %0":"=r"(d)::SSE_REGs) ; sha256->digest[5] += d;\
+    __asm__ volatile("movl %"#S_6", %0":"=r"(d)::SSE_REGs) ; sha256->digest[6] += d;\
+    __asm__ volatile("movl %"#S_7", %0":"=r"(d)::SSE_REGs) ; sha256->digest[7] += d;\
+}
+
+
+#define DigestToReg(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
+    _DigestToReg(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )
+
+#define RegToDigest(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
+    _RegToDigest(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )
+
+
+
+
+#define S_0 %r15d 
+#define S_1 %r10d
+#define S_2 %r11d       
+#define S_3 %r12d
+#define S_4 %r13d
+#define S_5 %r14d
+#define S_6 %ebx
+#define S_7 %r9d
+
+#define SSE_REGs "%edi", "%ecx", "%esi", "%edx", "%ebx","%r8","%r9","%r10","%r11","%r12","%r13","%r14","%r15"
+
+#if defined(HAVE_INTEL_RORX)
+#define RND_STEP_RORX_1(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("rorx  $6, %"#e", %%edx\n\t":::"%edx",SSE_REGs);  /* edx = e>>6 */\
+
+#define RND_STEP_RORX_2(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("rorx  $11, %"#e",%%edi\n\t":::"%edi",SSE_REGs); /* edi = e>>11  */\
+__asm__ volatile("xorl  %%edx, %%edi\n\t":::"%edx","%edi",SSE_REGs); /* edi = (e>>11) ^ (e>>6)  */\
+__asm__ volatile("rorx  $25, %"#e", %%edx\n\t":::"%edx",SSE_REGs);   /* edx = e>>25             */\
+
+#define RND_STEP_RORX_3(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("movl  %"#f", %%esi\n\t":::"%esi",SSE_REGs);  /* esi = f   */\
+__asm__ volatile("xorl  %"#g", %%esi\n\t":::"%esi",SSE_REGs);  /* esi = f ^ g  */\
+__asm__ volatile("xorl  %%edi, %%edx\n\t":::"%edi","%edx",SSE_REGs);  /* edx = Sigma1(e)  */\
+__asm__ volatile("andl  %"#e", %%esi\n\t":::"%esi",SSE_REGs);  /* esi = (f ^ g) & e       */\
+__asm__ volatile("xorl  %"#g", %%esi\n\t":::"%esi",SSE_REGs);  /* esi = Ch(e,f,g)         */\
+
+#define RND_STEP_RORX_4(a,b,c,d,e,f,g,h,i)\
+/*__asm__ volatile("movl    %0, %%edx\n\t"::"m"(w_k):"%edx");*/\
+__asm__ volatile("addl  %0, %"#h"\n\t"::"r"(W_K[i]):SSE_REGs);    /* h += w_k  */\
+__asm__ volatile("addl  %%edx, %"#h"\n\t":::"%edx",SSE_REGs);     /* h = h + w_k + Sigma1(e) */\
+__asm__ volatile("rorx  $2, %"#a", %%r8d\n\t":::"%r8",SSE_REGs);  /* r8d = a>>2   */\
+__asm__ volatile("rorx  $13, %"#a", %%edi\n\t":::"%edi",SSE_REGs);/* edi = a>>13  */\
+
+#define RND_STEP_RORX_5(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("rorx  $22, %"#a", %%edx\n\t":::"%edx",SSE_REGs); /* edx = a>>22 */\
+__asm__ volatile("xorl  %%r8d, %%edi\n\t":::"%edi","%r8",SSE_REGs);/* edi = (a>>2) ^ (a>>13)  */\
+__asm__ volatile("xorl  %%edi, %%edx\n\t":::"%edi","%edx",SSE_REGs);  /* edx = Sigma0(a)      */\
+ 
+#define RND_STEP_RORX_6(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("movl  %"#b", %%edi\n\t":::"%edi",SSE_REGs);  /* edi = b          */\
+__asm__ volatile("orl   %"#a", %%edi\n\t":::"%edi",SSE_REGs);  /* edi = a | b      */\
+__asm__ volatile("andl  %"#c", %%edi\n\t":::"%edi",SSE_REGs);  /* edi = (a | b) & c*/\
+__asm__ volatile("movl  %"#b", %%r8d\n\t":::"%r8",SSE_REGs);  /* r8d = b           */\
+
+#define RND_STEP_RORX_7(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("addl  %%esi, %"#h"\n\t":::"%esi",SSE_REGs);  /* h += Ch(e,f,g)   */\
+__asm__ volatile("andl  %"#a", %%r8d\n\t":::"%r8",SSE_REGs);  /* r8d = b & a       */\
+__asm__ volatile("orl   %%edi, %%r8d\n\t":::"%edi","%r8",SSE_REGs); /* r8d = Maj(a,b,c) */\
+
+#define RND_STEP_RORX_8(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("addl  "#h", "#d"\n\t");  /* d += h + w_k + Sigma1(e) + Ch(e,f,g) */\
+__asm__ volatile("addl  %"#h", %%r8d\n\t":::"%r8",SSE_REGs); \
+__asm__ volatile("addl  %%edx, %%r8d\n\t":::"%edx","%r8",SSE_REGs); \
+__asm__ volatile("movl  %r8d, "#h"\n\t");   
+
+#endif
+
+#define RND_STEP_1(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("movl  %"#e", %%edx\n\t":::"%edx",SSE_REGs);\
+__asm__ volatile("roll  $26, %%edx\n\t":::"%edx",SSE_REGs);  /* edx = e>>6     */\
+__asm__ volatile("movl  %"#e", %%edi\n\t":::"%edi",SSE_REGs);\
+
+#define RND_STEP_2(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("roll  $21, %%edi\n\t":::"%edi",SSE_REGs);         /* edi = e>>11 */\
+__asm__ volatile("xorl  %%edx, %%edi\n\t":::"%edx","%edi",SSE_REGs); /* edi = (e>>11) ^ (e>>6)  */\
+__asm__ volatile("movl  %"#e", %%edx\n\t":::"%edx",SSE_REGs);   /* edx = e      */\
+__asm__ volatile("roll  $7, %%edx\n\t":::"%edx",SSE_REGs);      /* edx = e>>25  */\
+
+#define RND_STEP_3(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("movl  %"#f", %%esi\n\t":::"%esi",SSE_REGs);  /* esi = f       */\
+__asm__ volatile("xorl  %"#g", %%esi\n\t":::"%esi",SSE_REGs);  /* esi = f ^ g   */\
+__asm__ volatile("xorl  %%edi, %%edx\n\t":::"%edi","%edx",SSE_REGs); /* edx = Sigma1(e) */\
+__asm__ volatile("andl  %"#e", %%esi\n\t":::"%esi",SSE_REGs);  /* esi = (f ^ g) & e  */\
+__asm__ volatile("xorl  %"#g", %%esi\n\t":::"%esi",SSE_REGs);  /* esi = Ch(e,f,g)    */\
+
+#define RND_STEP_4(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("addl  %0, %"#h"\n\t"::"r"(W_K[i]):SSE_REGs); /* h += w_k  */\
+__asm__ volatile("addl  %%edx, %"#h"\n\t":::"%edx",SSE_REGs); /* h = h + w_k + Sigma1(e) */\
+__asm__ volatile("movl  %"#a", %%r8d\n\t":::"%r8",SSE_REGs);  /* r8d = a    */\
+__asm__ volatile("roll  $30, %%r8d\n\t":::"%r8",SSE_REGs);    /* r8d = a>>2 */\
+__asm__ volatile("movl  %"#a", %%edi\n\t":::"%edi",SSE_REGs);  /* edi = a   */\
+__asm__ volatile("roll  $19, %%edi\n\t":::"%edi",SSE_REGs);    /* edi = a>>13 */\
+__asm__ volatile("movl  %"#a", %%edx\n\t":::"%edx",SSE_REGs);  /* edx = a     */\
+
+#define RND_STEP_5(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("roll  $10, %%edx\n\t":::"%edx",SSE_REGs);    /* edx = a>>22 */\
+__asm__ volatile("xorl  %%r8d, %%edi\n\t":::"%edi","%r8",SSE_REGs); /* edi = (a>>2) ^ (a>>13)  */\
+__asm__ volatile("xorl  %%edi, %%edx\n\t":::"%edi","%edx",SSE_REGs);/* edx = Sigma0(a)         */\
+
+#define RND_STEP_6(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("movl  %"#b", %%edi\n\t":::"%edi",SSE_REGs);  /* edi = b      */\
+__asm__ volatile("orl   %"#a", %%edi\n\t":::"%edi",SSE_REGs);  /* edi = a | b  */\
+__asm__ volatile("andl  %"#c", %%edi\n\t":::"%edi",SSE_REGs);  /* edi = (a | b) & c */\
+__asm__ volatile("movl  %"#b", %%r8d\n\t":::"%r8",SSE_REGs);  /* r8d = b       */\
+
+#define RND_STEP_7(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("addl  %%esi, %"#h"\n\t":::"%esi",SSE_REGs);  /* h += Ch(e,f,g)        */\
+__asm__ volatile("andl  %"#a", %%r8d\n\t":::"%r8",SSE_REGs);  /* r8d = b & a            */\
+__asm__ volatile("orl   %%edi, %%r8d\n\t":::"%edi","%r8",SSE_REGs); /* r8d = Maj(a,b,c) */\
+
+#define RND_STEP_8(a,b,c,d,e,f,g,h,i)\
+__asm__ volatile("addl  "#h", "#d"\n\t");  /* d += h + w_k + Sigma1(e) + Ch(e,f,g) */\
+__asm__ volatile("addl  %"#h", %%r8d\n\t":::"%r8",SSE_REGs); \
+                 /* r8b = h + w_k + Sigma1(e) + Ch(e,f,g) + Maj(a,b,c) */\
+__asm__ volatile("addl  %%edx, %%r8d\n\t":::"%edx","%r8",SSE_REGs);\
+                 /* r8b = h + w_k + Sigma1(e) Sigma0(a) + Ch(e,f,g) + Maj(a,b,c)     */\
+__asm__ volatile("movl  %%r8d, %"#h"\n\t":::"%r8", SSE_REGs); \
+                 /* h = h + w_k + Sigma1(e) + Sigma0(a) + Ch(e,f,g) + Maj(a,b,c) */ \
+
+#define RND_X(a,b,c,d,e,f,g,h,i) \
+       RND_STEP_1(a,b,c,d,e,f,g,h,i); \
+       RND_STEP_2(a,b,c,d,e,f,g,h,i); \
+       RND_STEP_3(a,b,c,d,e,f,g,h,i); \
+       RND_STEP_4(a,b,c,d,e,f,g,h,i); \
+       RND_STEP_5(a,b,c,d,e,f,g,h,i); \
+       RND_STEP_6(a,b,c,d,e,f,g,h,i); \
+       RND_STEP_7(a,b,c,d,e,f,g,h,i); \
+       RND_STEP_8(a,b,c,d,e,f,g,h,i); 
+
+#define RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i);
+#define RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_7,S_0,S_1,S_2,S_3,S_4,S_5,S_6,_i);
+#define RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_6,S_7,S_0,S_1,S_2,S_3,S_4,S_5,_i);
+#define RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_5,S_6,S_7,S_0,S_1,S_2,S_3,S_4,_i);
+#define RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,_i);
+#define RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_3,S_4,S_5,S_6,S_7,S_0,S_1,S_2,_i);
+#define RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_2,S_3,S_4,S_5,S_6,S_7,S_0,S_1,_i);
+#define RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_1,S_2,S_3,S_4,S_5,S_6,S_7,S_0,_i);
+
+
+#define RND_1_3(a,b,c,d,e,f,g,h,i) {\
+       RND_STEP_1(a,b,c,d,e,f,g,h,i); \
+       RND_STEP_2(a,b,c,d,e,f,g,h,i); \
+       RND_STEP_3(a,b,c,d,e,f,g,h,i); \
+}
+
+#define RND_4_6(a,b,c,d,e,f,g,h,i) {\
+       RND_STEP_4(a,b,c,d,e,f,g,h,i); \
+       RND_STEP_5(a,b,c,d,e,f,g,h,i); \
+       RND_STEP_6(a,b,c,d,e,f,g,h,i); \
+}
+
+#define RND_7_8(a,b,c,d,e,f,g,h,i) {\
+       RND_STEP_7(a,b,c,d,e,f,g,h,i); \
+       RND_STEP_8(a,b,c,d,e,f,g,h,i); \
+}
+
+#define RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i);
+#define RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_7,S_0,S_1,S_2,S_3,S_4,S_5,S_6,_i);
+#define RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_6,S_7,S_0,S_1,S_2,S_3,S_4,S_5,_i);
+#define RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_5,S_6,S_7,S_0,S_1,S_2,S_3,S_4,_i);
+#define RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,_i);
+#define RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_3,S_4,S_5,S_6,S_7,S_0,S_1,S_2,_i);
+#define RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_2,S_3,S_4,S_5,S_6,S_7,S_0,S_1,_i);
+#define RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_1,S_2,S_3,S_4,S_5,S_6,S_7,S_0,_i);
+
+
+#define RND_0_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i);
+#define RND_7_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_7,S_0,S_1,S_2,S_3,S_4,S_5,S_6,_i);
+#define RND_6_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_6,S_7,S_0,S_1,S_2,S_3,S_4,S_5,_i);
+#define RND_5_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_5,S_6,S_7,S_0,S_1,S_2,S_3,S_4,_i);
+#define RND_4_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,_i);
+#define RND_3_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_3,S_4,S_5,S_6,S_7,S_0,S_1,S_2,_i);
+#define RND_2_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_2,S_3,S_4,S_5,S_6,S_7,S_0,S_1,_i);
+#define RND_1_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_1,S_2,S_3,S_4,S_5,S_6,S_7,S_0,_i);
+
+#define RND_0_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i);
+#define RND_7_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_7,S_0,S_1,S_2,S_3,S_4,S_5,S_6,_i);
+#define RND_6_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_6,S_7,S_0,S_1,S_2,S_3,S_4,S_5,_i);
+#define RND_5_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_5,S_6,S_7,S_0,S_1,S_2,S_3,S_4,_i);
+#define RND_4_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,_i);
+#define RND_3_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_3,S_4,S_5,S_6,S_7,S_0,S_1,S_2,_i);
+#define RND_2_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_2,S_3,S_4,S_5,S_6,S_7,S_0,S_1,_i);
+#define RND_1_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_1,S_2,S_3,S_4,S_5,S_6,S_7,S_0,_i);
+
+#define RND_0_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i);
+#define RND_7_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_7,S_0,S_1,S_2,S_3,S_4,S_5,S_6,_i);
+#define RND_6_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_6,S_7,S_0,S_1,S_2,S_3,S_4,S_5,_i);
+#define RND_5_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_5,S_6,S_7,S_0,S_1,S_2,S_3,S_4,_i);
+#define RND_4_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,_i);
+#define RND_3_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_3,S_4,S_5,S_6,S_7,S_0,S_1,S_2,_i);
+#define RND_2_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_2,S_3,S_4,S_5,S_6,S_7,S_0,S_1,_i);
+#define RND_1_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_1,S_2,S_3,S_4,S_5,S_6,S_7,S_0,_i);
+
+#define FOR(cnt, init, max, inc, loop)  \
+    __asm__ volatile("movl $"#init", %0\n\t"#loop":"::"m"(cnt):) 
+#define END(cnt, init, max, inc, loop)  \
+    __asm__ volatile("addl $"#inc", %0\n\tcmpl $"#max", %0\n\tjle "#loop"\n\t":"=m"(cnt)::) ;
+
+#endif  /* defined(HAVE_INTEL_AVX1) ||  defined(HAVE_INTEL_AVX2) */
+
+#if defined(HAVE_INTEL_AVX1) /* inline Assember for Intel AVX1 instructions */
+
+#define VPALIGNR(op1,op2,op3,op4) __asm__ volatile("vpalignr $"#op4", %"#op3", %"#op2", %"#op1:::XMM_REGs) 
+#define VPADDD(op1,op2,op3)       __asm__ volatile("vpaddd %"#op3", %"#op2", %"#op1:::XMM_REGs)
+#define VPSRLD(op1,op2,op3)       __asm__ volatile("vpsrld $"#op3", %"#op2", %"#op1:::XMM_REGs)
+#define VPSRLQ(op1,op2,op3)       __asm__ volatile("vpsrlq $"#op3", %"#op2", %"#op1:::XMM_REGs)
+#define VPSLLD(op1,op2,op3)       __asm__ volatile("vpslld $"#op3", %"#op2", %"#op1:::XMM_REGs)
+#define VPOR(op1,op2,op3)         __asm__ volatile("vpor   %"#op3", %"#op2", %"#op1:::XMM_REGs)
+#define VPXOR(op1,op2,op3)        __asm__ volatile("vpxor  %"#op3", %"#op2", %"#op1:::XMM_REGs)
+#define VPSHUFD(op1,op2,op3)      __asm__ volatile("vpshufd $"#op3", %"#op2", %"#op1:::XMM_REGs)
+#define VPSHUFB(op1,op2,op3)      __asm__ volatile("vpshufb %"#op3", %"#op2", %"#op1:::XMM_REGs)
+
+#define MessageSched(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER, SHUF_00BA, SHUF_DC00,\
+     a,b,c,d,e,f,g,h,_i)\
+            RND_STEP_1(a,b,c,d,e,f,g,h,_i);\
+    VPALIGNR (XTMP0, X3, X2, 4) ;\
+            RND_STEP_2(a,b,c,d,e,f,g,h,_i);\
+    VPADDD   (XTMP0, XTMP0, X0) ;\
+            RND_STEP_3(a,b,c,d,e,f,g,h,_i);\
+    VPALIGNR (XTMP1, X1, X0, 4) ;   /* XTMP1 = W[-15] */\
+            RND_STEP_4(a,b,c,d,e,f,g,h,_i);\
+    VPSRLD   (XTMP2, XTMP1, 7) ;\
+            RND_STEP_5(a,b,c,d,e,f,g,h,_i);\
+    VPSLLD   (XTMP3, XTMP1, 25) ; /* VPSLLD   (XTMP3, XTMP1, (32-7)) */\
+            RND_STEP_6(a,b,c,d,e,f,g,h,_i);\
+    VPOR     (XTMP3, XTMP3, XTMP2)  ;  /* XTMP1 = W[-15] MY_ROR 7 */\
+            RND_STEP_7(a,b,c,d,e,f,g,h,_i);\
+    VPSRLD   (XTMP2, XTMP1,18) ;\
+            RND_STEP_8(a,b,c,d,e,f,g,h,_i);\
+\
+            RND_STEP_1(h,a,b,c,d,e,f,g,_i+1);\
+    VPSRLD   (XTMP4, XTMP1, 3)      ;  /* XTMP4 = W[-15] >> 3 */\
+            RND_STEP_2(h,a,b,c,d,e,f,g,_i+1);\
+    VPSLLD   (XTMP1, XTMP1, 14) ; /* VPSLLD   (XTMP1, XTMP1, (32-18)) */\
+            RND_STEP_3(h,a,b,c,d,e,f,g,_i+1);\
+    VPXOR    (XTMP3, XTMP3, XTMP1)  ;\
+            RND_STEP_4(h,a,b,c,d,e,f,g,_i+1);\
+    VPXOR    (XTMP3, XTMP3, XTMP2)  ;  /* XTMP1 = W[-15] MY_ROR 7 ^ W[-15] MY_ROR 18 */\
+            RND_STEP_5(h,a,b,c,d,e,f,g,_i+1);\
+    VPXOR    (XTMP1, XTMP3, XTMP4)  ;  /* XTMP1 = s0 */\
+            RND_STEP_6(h,a,b,c,d,e,f,g,_i+1);\
+    VPSHUFD(XTMP2, X3, 0b11111010)  ;  /* XTMP2 = W[-2] {BBAA}*/\
+            RND_STEP_7(h,a,b,c,d,e,f,g,_i+1);\
+    VPADDD   (XTMP0, XTMP0, XTMP1)  ;  /* XTMP0 = W[-16] + W[-7] + s0 */\
+            RND_STEP_8(h,a,b,c,d,e,f,g,_i+1);\
+\
+            RND_STEP_1(g,h,a,b,c,d,e,f,_i+2);\
+    VPSRLD   (XTMP4, XTMP2, 10) ;      /* XTMP4 = W[-2] >> 10 {BBAA} */\
+            RND_STEP_2(g,h,a,b,c,d,e,f,_i+2);\
+    VPSRLQ   (XTMP3, XTMP2, 19) ;      /* XTMP3 = W[-2] MY_ROR 19 {xBxA} */\
+            RND_STEP_3(g,h,a,b,c,d,e,f,_i+2);\
+    VPSRLQ   (XTMP2, XTMP2, 17) ;      /* XTMP2 = W[-2] MY_ROR 17 {xBxA} */\
+            RND_STEP_4(g,h,a,b,c,d,e,f,_i+2);\
+    VPXOR    (XTMP2, XTMP2, XTMP3) ;\
+            RND_STEP_5(g,h,a,b,c,d,e,f,_i+2);\
+    VPXOR    (XTMP4, XTMP4, XTMP2) ;   /* XTMP4 = s1 {xBxA} */\
+            RND_STEP_6(g,h,a,b,c,d,e,f,_i+2);\
+    VPSHUFB  (XTMP4, XTMP4, SHUF_00BA)  ;  /* XTMP4 = s1 {00BA} */\
+            RND_STEP_7(g,h,a,b,c,d,e,f,_i+2);\
+    VPADDD   (XTMP0, XTMP0, XTMP4)  ;  /* XTMP0 = {..., ..., W[1], W[0]} */\
+            RND_STEP_8(g,h,a,b,c,d,e,f,_i+2);\
+\
+            RND_STEP_1(f,g,h,a,b,c,d,e,_i+3);\
+    VPSHUFD  (XTMP2, XTMP0, 0b01010000) ; /* XTMP2 = W[-2] {DDCC} */\
+            RND_STEP_2(f,g,h,a,b,c,d,e,_i+3);\
+    VPSRLD   (XTMP5, XTMP2, 10);       /* XTMP5 = W[-2] >> 10 {DDCC} */\
+            RND_STEP_3(f,g,h,a,b,c,d,e,_i+3);\
+    VPSRLQ   (XTMP3, XTMP2, 19);       /* XTMP3 = W[-2] MY_ROR 19 {xDxC} */\
+            RND_STEP_4(f,g,h,a,b,c,d,e,_i+3);\
+    VPSRLQ   (XTMP2, XTMP2, 17) ;      /* XTMP2 = W[-2] MY_ROR 17 {xDxC} */\
+            RND_STEP_5(f,g,h,a,b,c,d,e,_i+3);\
+    VPXOR    (XTMP2, XTMP2, XTMP3) ;\
+            RND_STEP_6(f,g,h,a,b,c,d,e,_i+3);\
+    VPXOR    (XTMP5, XTMP5, XTMP2) ;   /* XTMP5 = s1 {xDxC} */\
+            RND_STEP_7(f,g,h,a,b,c,d,e,_i+3);\
+    VPSHUFB  (XTMP5, XTMP5, SHUF_DC00) ; /* XTMP5 = s1 {DC00} */\
+            RND_STEP_8(f,g,h,a,b,c,d,e,_i+3);\
+    VPADDD   (X0, XTMP5, XTMP0) ;      /* X0 = {W[3], W[2], W[1], W[0]} */\
+
+#if defined(HAVE_INTEL_RORX)
+
+#define MessageSched_RORX(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, \
+                          XFER, SHUF_00BA, SHUF_DC00,a,b,c,d,e,f,g,h,_i)\
+            RND_STEP_RORX_1(a,b,c,d,e,f,g,h,_i);\
+    VPALIGNR (XTMP0, X3, X2, 4) ;\
+            RND_STEP_RORX_2(a,b,c,d,e,f,g,h,_i);\
+    VPADDD   (XTMP0, XTMP0, X0) ;\
+            RND_STEP_RORX_3(a,b,c,d,e,f,g,h,_i);\
+    VPALIGNR (XTMP1, X1, X0, 4) ;   /* XTMP1 = W[-15] */\
+            RND_STEP_RORX_4(a,b,c,d,e,f,g,h,_i);\
+    VPSRLD   (XTMP2, XTMP1, 7) ;\
+            RND_STEP_RORX_5(a,b,c,d,e,f,g,h,_i);\
+    VPSLLD   (XTMP3, XTMP1, 25) ; /* VPSLLD   (XTMP3, XTMP1, (32-7)) */\
+            RND_STEP_RORX_6(a,b,c,d,e,f,g,h,_i);\
+    VPOR     (XTMP3, XTMP3, XTMP2)  ;  /* XTMP1 = W[-15] MY_ROR 7 */\
+            RND_STEP_RORX_7(a,b,c,d,e,f,g,h,_i);\
+    VPSRLD   (XTMP2, XTMP1,18) ;\
+            RND_STEP_RORX_8(a,b,c,d,e,f,g,h,_i);\
+\
+            RND_STEP_RORX_1(h,a,b,c,d,e,f,g,_i+1);\
+    VPSRLD   (XTMP4, XTMP1, 3)      ;  /* XTMP4 = W[-15] >> 3 */\
+            RND_STEP_RORX_2(h,a,b,c,d,e,f,g,_i+1);\
+    VPSLLD   (XTMP1, XTMP1, 14) ; /* VPSLLD   (XTMP1, XTMP1, (32-18)) */\
+            RND_STEP_RORX_3(h,a,b,c,d,e,f,g,_i+1);\
+    VPXOR    (XTMP3, XTMP3, XTMP1)  ;\
+            RND_STEP_RORX_4(h,a,b,c,d,e,f,g,_i+1);\
+    VPXOR    (XTMP3, XTMP3, XTMP2)  ;  /* XTMP1 = W[-15] MY_ROR 7 ^ W[-15] MY_ROR 18 */\
+            RND_STEP_RORX_5(h,a,b,c,d,e,f,g,_i+1);\
+    VPXOR    (XTMP1, XTMP3, XTMP4)  ;  /* XTMP1 = s0 */\
+            RND_STEP_RORX_6(h,a,b,c,d,e,f,g,_i+1);\
+    VPSHUFD(XTMP2, X3, 0b11111010)  ;  /* XTMP2 = W[-2] {BBAA}*/\
+            RND_STEP_RORX_7(h,a,b,c,d,e,f,g,_i+1);\
+    VPADDD   (XTMP0, XTMP0, XTMP1)  ;  /* XTMP0 = W[-16] + W[-7] + s0 */\
+            RND_STEP_RORX_8(h,a,b,c,d,e,f,g,_i+1);\
+\
+            RND_STEP_RORX_1(g,h,a,b,c,d,e,f,_i+2);\
+    VPSRLD   (XTMP4, XTMP2, 10) ;      /* XTMP4 = W[-2] >> 10 {BBAA} */\
+            RND_STEP_RORX_2(g,h,a,b,c,d,e,f,_i+2);\
+    VPSRLQ   (XTMP3, XTMP2, 19) ;      /* XTMP3 = W[-2] MY_ROR 19 {xBxA} */\
+            RND_STEP_RORX_3(g,h,a,b,c,d,e,f,_i+2);\
+    VPSRLQ   (XTMP2, XTMP2, 17) ;      /* XTMP2 = W[-2] MY_ROR 17 {xBxA} */\
+            RND_STEP_RORX_4(g,h,a,b,c,d,e,f,_i+2);\
+    VPXOR    (XTMP2, XTMP2, XTMP3) ;\
+            RND_STEP_RORX_5(g,h,a,b,c,d,e,f,_i+2);\
+    VPXOR    (XTMP4, XTMP4, XTMP2) ;   /* XTMP4 = s1 {xBxA} */\
+            RND_STEP_RORX_6(g,h,a,b,c,d,e,f,_i+2);\
+    VPSHUFB  (XTMP4, XTMP4, SHUF_00BA)  ;  /* XTMP4 = s1 {00BA} */\
+            RND_STEP_RORX_7(g,h,a,b,c,d,e,f,_i+2);\
+    VPADDD   (XTMP0, XTMP0, XTMP4)  ;  /* XTMP0 = {..., ..., W[1], W[0]} */\
+            RND_STEP_RORX_8(g,h,a,b,c,d,e,f,_i+2);\
+\
+            RND_STEP_RORX_1(f,g,h,a,b,c,d,e,_i+3);\
+    VPSHUFD  (XTMP2, XTMP0, 0b01010000) ; /* XTMP2 = W[-2] {DDCC} */\
+            RND_STEP_RORX_2(f,g,h,a,b,c,d,e,_i+3);\
+    VPSRLD   (XTMP5, XTMP2, 10);       /* XTMP5 = W[-2] >> 10 {DDCC} */\
+            RND_STEP_RORX_3(f,g,h,a,b,c,d,e,_i+3);\
+    VPSRLQ   (XTMP3, XTMP2, 19);       /* XTMP3 = W[-2] MY_ROR 19 {xDxC} */\
+            RND_STEP_RORX_4(f,g,h,a,b,c,d,e,_i+3);\
+    VPSRLQ   (XTMP2, XTMP2, 17) ;      /* XTMP2 = W[-2] MY_ROR 17 {xDxC} */\
+            RND_STEP_RORX_5(f,g,h,a,b,c,d,e,_i+3);\
+    VPXOR    (XTMP2, XTMP2, XTMP3) ;\
+            RND_STEP_RORX_6(f,g,h,a,b,c,d,e,_i+3);\
+    VPXOR    (XTMP5, XTMP5, XTMP2) ;   /* XTMP5 = s1 {xDxC} */\
+            RND_STEP_RORX_7(f,g,h,a,b,c,d,e,_i+3);\
+    VPSHUFB  (XTMP5, XTMP5, SHUF_DC00) ; /* XTMP5 = s1 {DC00} */\
+            RND_STEP_RORX_8(f,g,h,a,b,c,d,e,_i+3);\
+    VPADDD   (X0, XTMP5, XTMP0) ;      /* X0 = {W[3], W[2], W[1], W[0]} */\
+
+#endif
+
+
+#define W_K_from_buff\
+         __asm__ volatile("vmovdqu %0, %%xmm4\n\t"\
+                          "vpshufb %%xmm13, %%xmm4, %%xmm4\n\t"\
+                          :: "m"(sha256->buffer[0]):"%xmm4") ;\
+         __asm__ volatile("vmovdqu %0, %%xmm5\n\t"\
+                          "vpshufb %%xmm13, %%xmm5, %%xmm5\n\t"\
+                          ::"m"(sha256->buffer[4]):"%xmm5") ;\
+         __asm__ volatile("vmovdqu %0, %%xmm6\n\t"\
+                          "vpshufb %%xmm13, %%xmm6, %%xmm6\n\t"\
+                          ::"m"(sha256->buffer[8]):"%xmm6") ;\
+         __asm__ volatile("vmovdqu %0, %%xmm7\n\t"\
+                          "vpshufb %%xmm13, %%xmm7, %%xmm7\n\t"\
+                          ::"m"(sha256->buffer[12]):"%xmm7") ;\
+
+#define _SET_W_K_XFER(reg, i)\
+    __asm__ volatile("vpaddd %0, %"#reg", %%xmm9"::"m"(K[i]):XMM_REGs) ;\
+    __asm__ volatile("vmovdqa %%xmm9, %0":"=m"(W_K[i])::XMM_REGs) ;
+
+#define SET_W_K_XFER(reg, i) _SET_W_K_XFER(reg, i)
+
+static const ALIGN32 word64 mSHUF_00BA[] = { 0x0b0a090803020100, 0xFFFFFFFFFFFFFFFF } ; /* shuffle xBxA -> 00BA */
+static const ALIGN32 word64 mSHUF_DC00[] = { 0xFFFFFFFFFFFFFFFF, 0x0b0a090803020100 } ; /* shuffle xDxC -> DC00 */
+static const ALIGN32 word64 mBYTE_FLIP_MASK[] =  { 0x0405060700010203, 0x0c0d0e0f08090a0b } ;
+
+
+#define _Init_Masks(mask1, mask2, mask3)\
+__asm__ volatile("vmovdqu %0, %"#mask1 ::"m"(mBYTE_FLIP_MASK[0])) ;\
+__asm__ volatile("vmovdqu %0, %"#mask2 ::"m"(mSHUF_00BA[0])) ;\
+__asm__ volatile("vmovdqu %0, %"#mask3 ::"m"(mSHUF_DC00[0])) ;
+
+#define Init_Masks(BYTE_FLIP_MASK, SHUF_00BA, SHUF_DC00)\
+    _Init_Masks(BYTE_FLIP_MASK, SHUF_00BA, SHUF_DC00)
+
+#define X0 %xmm4
+#define X1 %xmm5
+#define X2 %xmm6
+#define X3 %xmm7
+#define X_ X0
+
+#define XTMP0 %xmm0
+#define XTMP1 %xmm1
+#define XTMP2 %xmm2
+#define XTMP3 %xmm3
+#define XTMP4 %xmm8
+#define XTMP5 %xmm9
+#define XFER  %xmm10
+
+#define SHUF_00BA   %xmm11 /* shuffle xBxA -> 00BA */
+#define SHUF_DC00   %xmm12 /* shuffle xDxC -> DC00 */
+#define BYTE_FLIP_MASK  %xmm13
+
+#define XMM_REGs   /* Registers are saved in Sha256Update/Finel */
+                   /*"xmm4","xmm5","xmm6","xmm7","xmm8","xmm9","xmm10","xmm11","xmm12","xmm13" */
+
+static int Transform_AVX1(Sha256* sha256)
+{
+
+    word32 W_K[64] ;  /* temp for W+K */
+
+    #if defined(DEBUG_XMM)
+    int i, j ;
+    word32 xmm[29][4*15] ;
+    #endif
+
+    Init_Masks(BYTE_FLIP_MASK, SHUF_00BA, SHUF_DC00) ;
+    W_K_from_buff ; /* X0, X1, X2, X3 = W[0..15] ; */
+
+    DigestToReg(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7) ;
+  
+    SET_W_K_XFER(X0, 0) ;
+    MessageSched(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER, 
+            SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,0) ;
+    SET_W_K_XFER(X1, 4) ;
+    MessageSched(X1, X2, X3, X0, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER,
+            SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,4) ;
+    SET_W_K_XFER(X2, 8) ;
+    MessageSched(X2, X3, X0, X1, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER, 
+            SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,8) ;
+    SET_W_K_XFER(X3, 12) ;
+    MessageSched(X3, X0, X1, X2, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER, 
+            SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,12) ;
+    SET_W_K_XFER(X0, 16) ;
+    MessageSched(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER, 
+            SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,16) ;
+    SET_W_K_XFER(X1, 20) ;
+    MessageSched(X1, X2, X3, X0, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER, 
+            SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,20) ;
+    SET_W_K_XFER(X2, 24) ;
+    MessageSched(X2, X3, X0, X1, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER, 
+            SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,24) ;
+    SET_W_K_XFER(X3, 28) ;
+    MessageSched(X3, X0, X1, X2, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER, 
+            SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,28) ;
+    SET_W_K_XFER(X0, 32) ;
+    MessageSched(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER, 
+            SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,32) ;
+    SET_W_K_XFER(X1, 36) ;
+    MessageSched(X1, X2, X3, X0, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER, 
+            SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,36) ;
+    SET_W_K_XFER(X2, 40) ;
+    MessageSched(X2, X3, X0, X1, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER, 
+            SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,40) ;
+    SET_W_K_XFER(X3, 44) ;
+    MessageSched(X3, X0, X1, X2, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER, 
+            SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,44) ;
+
+    SET_W_K_XFER(X0, 48) ;
+    SET_W_K_XFER(X1, 52) ;
+    SET_W_K_XFER(X2, 56) ;
+    SET_W_K_XFER(X3, 60) ;
+    
+    RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,48) ;
+    RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,49) ;
+    RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,50) ;
+    RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,51) ;
+
+    RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,52) ;
+    RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,53) ;
+    RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,54) ;
+    RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,55) ;
+
+    RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,56) ;     
+    RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,57) ;
+    RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,58) ;
+    RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,59) ;
+
+    RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,60) ;
+    RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,61) ;
+    RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,62) ;
+    RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,63) ;
+        
+    RegToDigest(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7) ;  
+        
+    #if defined(DEBUG_XMM)
+    for(i=0; i<29; i++) {
+        for(j=0; j<4*14; j+=4)
+            printf("xmm%d[%d]=%08x,%08x,%08x,%08x\n", j/4, i, 
+                   xmm[i][j],xmm[i][j+1],xmm[i][j+2],xmm[i][j+3]) ;
+        printf("\n") ;
+    }
+        
+    for(i=0; i<64; i++)printf("W_K[%d]%08x\n", i, W_K[i]) ;
+    #endif
+
+    return 0;
+}
+
+#if defined(HAVE_INTEL_RORX)
+static int Transform_AVX1_RORX(Sha256* sha256)
+{
+
+    word32 W_K[64] ;  /* temp for W+K */
+
+    #if defined(DEBUG_XMM)
+    int i, j ;
+    word32 xmm[29][4*15] ;
+    #endif
+
+    Init_Masks(BYTE_FLIP_MASK, SHUF_00BA, SHUF_DC00) ;
+    W_K_from_buff ; /* X0, X1, X2, X3 = W[0..15] ; */
+
+    DigestToReg(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7) ;
+    SET_W_K_XFER(X0, 0) ;
+    MessageSched_RORX(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, 
+            XFER, SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,0) ;
+    SET_W_K_XFER(X1, 4) ;
+    MessageSched_RORX(X1, X2, X3, X0, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, 
+            XFER, SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,4) ;
+    SET_W_K_XFER(X2, 8) ;
+    MessageSched_RORX(X2, X3, X0, X1, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, 
+            XFER, SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,8) ;
+    SET_W_K_XFER(X3, 12) ;
+    MessageSched_RORX(X3, X0, X1, X2, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, 
+            XFER, SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,12) ;
+    SET_W_K_XFER(X0, 16) ;
+    MessageSched_RORX(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, 
+            XFER, SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,16) ;
+    SET_W_K_XFER(X1, 20) ;
+    MessageSched_RORX(X1, X2, X3, X0, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, 
+            XFER, SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,20) ;
+    SET_W_K_XFER(X2, 24) ;
+    MessageSched_RORX(X2, X3, X0, X1, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, 
+            XFER, SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,24) ;
+    SET_W_K_XFER(X3, 28) ;
+    MessageSched_RORX(X3, X0, X1, X2, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, 
+            XFER, SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,28) ;
+    SET_W_K_XFER(X0, 32) ;
+    MessageSched_RORX(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, 
+            XFER, SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,32) ;
+    SET_W_K_XFER(X1, 36) ;
+    MessageSched_RORX(X1, X2, X3, X0, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, 
+            XFER, SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,36) ;
+    SET_W_K_XFER(X2, 40) ;
+    MessageSched_RORX(X2, X3, X0, X1, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5,
+            XFER, SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,40) ;
+    SET_W_K_XFER(X3, 44) ;
+    MessageSched_RORX(X3, X0, X1, X2, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5,
+            XFER, SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,44) ;
+
+    SET_W_K_XFER(X0, 48) ;
+    SET_W_K_XFER(X1, 52) ;
+    SET_W_K_XFER(X2, 56) ;
+    SET_W_K_XFER(X3, 60) ;
+    
+    RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,48) ;
+    RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,49) ;
+    RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,50) ;
+    RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,51) ;
+
+    RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,52) ;
+    RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,53) ;
+    RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,54) ;
+    RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,55) ;
+
+    RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,56) ;     
+    RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,57) ;
+    RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,58) ;
+    RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,59) ;
+
+    RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,60) ;
+    RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,61) ;
+    RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,62) ;
+    RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,63) ;
+        
+    RegToDigest(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7) ;  
+        
+    #if defined(DEBUG_XMM)
+    for(i=0; i<29; i++) {
+        for(j=0; j<4*14; j+=4)
+            printf("xmm%d[%d]=%08x,%08x,%08x,%08x\n", j/4, i, 
+                    xmm[i][j],xmm[i][j+1],xmm[i][j+2],xmm[i][j+3]) ;
+        printf("\n") ;
+    }
+        
+    for(i=0; i<64; i++)printf("W_K[%d]%08x\n", i, W_K[i]) ;
+    #endif
+
+    return 0;
+}
+#endif  /* HAVE_INTEL_RORX */
+
+#endif  /* HAVE_INTEL_AVX1 */
+
+
+#if defined(HAVE_INTEL_AVX2)
+
+#define _MOVE_to_REG(ymm, mem)       __asm__ volatile("vmovdqu %0, %%"#ymm" ":: "m"(mem):YMM_REGs) ;
+#define _MOVE_to_MEM(mem, ymm)       __asm__ volatile("vmovdqu %%"#ymm", %0" : "=m"(mem)::YMM_REGs) ;
+#define _BYTE_SWAP(ymm, map)              __asm__ volatile("vpshufb %0, %%"#ymm", %%"#ymm"\n\t"\
+                                                       :: "m"(map):YMM_REGs) ;
+#define _MOVE_128(ymm0, ymm1, ymm2, map)   __asm__ volatile("vperm2i128  $"#map", %%"\
+                                  #ymm2", %%"#ymm1", %%"#ymm0" ":::YMM_REGs) ;
+#define _MOVE_BYTE(ymm0, ymm1, map)  __asm__ volatile("vpshufb %0, %%"#ymm1", %%"\
+                                  #ymm0"\n\t":: "m"(map):YMM_REGs) ;
+#define _S_TEMP(dest, src, bits, temp)    __asm__ volatile("vpsrld  $"#bits", %%"\
+         #src", %%"#dest"\n\tvpslld  $32-"#bits", %%"#src", %%"#temp"\n\tvpor %%"\
+         #temp",%%"#dest", %%"#dest" ":::YMM_REGs) ;
+#define _AVX2_R(dest, src, bits)          __asm__ volatile("vpsrld  $"#bits", %%"\
+                                  #src", %%"#dest" ":::YMM_REGs) ;
+#define _XOR(dest, src1, src2)       __asm__ volatile("vpxor   %%"#src1", %%"\
+         #src2", %%"#dest" ":::YMM_REGs) ;
+#define _OR(dest, src1, src2)       __asm__ volatile("vpor    %%"#src1", %%"\
+         #src2", %%"#dest" ":::YMM_REGs) ;
+#define _ADD(dest, src1, src2)       __asm__ volatile("vpaddd   %%"#src1", %%"\
+         #src2", %%"#dest" ":::YMM_REGs) ;
+#define _ADD_MEM(dest, src1, mem)    __asm__ volatile("vpaddd   %0, %%"#src1", %%"\
+         #dest" "::"m"(mem):YMM_REGs) ;
+#define _BLEND(map, dest, src1, src2)    __asm__ volatile("vpblendd    $"#map", %%"\
+         #src1",   %%"#src2", %%"#dest" ":::YMM_REGs) ;
+
+#define    _EXTRACT_XMM_0(xmm, mem)  __asm__ volatile("vpextrd $0, %%"#xmm", %0 ":"=r"(mem)::YMM_REGs) ;
+#define    _EXTRACT_XMM_1(xmm, mem)  __asm__ volatile("vpextrd $1, %%"#xmm", %0 ":"=r"(mem)::YMM_REGs) ;
+#define    _EXTRACT_XMM_2(xmm, mem)  __asm__ volatile("vpextrd $2, %%"#xmm", %0 ":"=r"(mem)::YMM_REGs) ;
+#define    _EXTRACT_XMM_3(xmm, mem)  __asm__ volatile("vpextrd $3, %%"#xmm", %0 ":"=r"(mem)::YMM_REGs) ;
+#define    _EXTRACT_XMM_4(ymm, xmm, mem)\
+      __asm__ volatile("vperm2i128 $0x1, %%"#ymm", %%"#ymm", %%"#ymm" ":::YMM_REGs) ;\
+      __asm__ volatile("vpextrd $0, %%"#xmm", %0 ":"=r"(mem)::YMM_REGs) ;
+#define    _EXTRACT_XMM_5(xmm, mem)  __asm__ volatile("vpextrd $1, %%"#xmm", %0 ":"=r"(mem)::YMM_REGs) ;
+#define    _EXTRACT_XMM_6(xmm, mem)  __asm__ volatile("vpextrd $2, %%"#xmm", %0 ":"=r"(mem)::YMM_REGs) ;
+#define    _EXTRACT_XMM_7(xmm, mem)  __asm__ volatile("vpextrd $3, %%"#xmm", %0 ":"=r"(mem)::YMM_REGs) ;
+
+#define    _SWAP_YMM_HL(ymm)   __asm__ volatile("vperm2i128 $0x1, %%"#ymm", %%"#ymm", %%"#ymm" ":::YMM_REGs) ;
+#define     SWAP_YMM_HL(ymm)   _SWAP_YMM_HL(ymm) 
+
+#define MOVE_to_REG(ymm, mem)      _MOVE_to_REG(ymm, mem)
+#define MOVE_to_MEM(mem, ymm)      _MOVE_to_MEM(mem, ymm)
+#define BYTE_SWAP(ymm, map)        _BYTE_SWAP(ymm, map)
+#define MOVE_128(ymm0, ymm1, ymm2, map) _MOVE_128(ymm0, ymm1, ymm2, map) 
+#define MOVE_BYTE(ymm0, ymm1, map) _MOVE_BYTE(ymm0, ymm1, map)
+#define XOR(dest, src1, src2)      _XOR(dest, src1, src2)
+#define OR(dest, src1, src2)       _OR(dest, src1, src2)
+#define ADD(dest, src1, src2)      _ADD(dest, src1, src2)
+#define ADD_MEM(dest, src1, mem)  _ADD_MEM(dest, src1, mem)
+#define BLEND(map, dest, src1, src2) _BLEND(map, dest, src1, src2)
+
+#define S_TMP(dest, src, bits, temp) _S_TEMP(dest, src, bits, temp); 
+#define AVX2_S(dest, src, bits)      S_TMP(dest, src, bits, S_TEMP)
+#define AVX2_R(dest, src, bits)      _AVX2_R(dest, src, bits)
+
+#define GAMMA0(dest, src)      AVX2_S(dest, src, 7);  AVX2_S(G_TEMP, src, 18); \
+    XOR(dest, G_TEMP, dest) ; AVX2_R(G_TEMP, src, 3);  XOR(dest, G_TEMP, dest) ;
+#define GAMMA0_1(dest, src)    AVX2_S(dest, src, 7);  AVX2_S(G_TEMP, src, 18); 
+#define GAMMA0_2(dest, src)    XOR(dest, G_TEMP, dest) ; AVX2_R(G_TEMP, src, 3);  \
+    XOR(dest, G_TEMP, dest) ;
+
+#define GAMMA1(dest, src)      AVX2_S(dest, src, 17); AVX2_S(G_TEMP, src, 19); \
+    XOR(dest, G_TEMP, dest) ; AVX2_R(G_TEMP, src, 10); XOR(dest, G_TEMP, dest) ;
+#define GAMMA1_1(dest, src)    AVX2_S(dest, src, 17); AVX2_S(G_TEMP, src, 19); 
+#define GAMMA1_2(dest, src)    XOR(dest, G_TEMP, dest) ; AVX2_R(G_TEMP, src, 10); \
+    XOR(dest, G_TEMP, dest) ;
+
+#define    FEEDBACK1_to_W_I_2    MOVE_BYTE(YMM_TEMP0, W_I, mMAP1toW_I_2[0]) ; \
+    BLEND(0x0c, W_I_2, YMM_TEMP0, W_I_2) ;
+#define    FEEDBACK2_to_W_I_2    MOVE_128(YMM_TEMP0, W_I, W_I, 0x08) ;  \
+    MOVE_BYTE(YMM_TEMP0, YMM_TEMP0, mMAP2toW_I_2[0]) ; BLEND(0x30, W_I_2, YMM_TEMP0, W_I_2) ; 
+#define    FEEDBACK3_to_W_I_2    MOVE_BYTE(YMM_TEMP0, W_I, mMAP3toW_I_2[0]) ; \
+    BLEND(0xc0, W_I_2, YMM_TEMP0, W_I_2) ; 
+
+#define    FEEDBACK_to_W_I_7     MOVE_128(YMM_TEMP0, W_I, W_I, 0x08) ;\
+    MOVE_BYTE(YMM_TEMP0, YMM_TEMP0, mMAPtoW_I_7[0]) ; BLEND(0x80, W_I_7, YMM_TEMP0, W_I_7) ;
+
+#undef voitle
+
+#define W_I_16  ymm8
+#define W_I_15  ymm9
+#define W_I_7  ymm10
+#define W_I_2  ymm11
+#define W_I    ymm12
+#define G_TEMP     ymm13
+#define S_TEMP     ymm14
+#define YMM_TEMP0  ymm15
+#define YMM_TEMP0x xmm15
+#define W_I_TEMP   ymm7
+#define W_K_TEMP   ymm15
+#define W_K_TEMPx  xmm15
+
+#define YMM_REGs /* Registers are saved in Sha256Update/Finel */
+ /* "%ymm7","%ymm8","%ymm9","%ymm10","%ymm11","%ymm12","%ymm13","%ymm14","%ymm15"*/
+
+
+#define MOVE_15_to_16(w_i_16, w_i_15, w_i_7)\
+    __asm__ volatile("vperm2i128  $0x01, %%"#w_i_15", %%"#w_i_15", %%"#w_i_15" ":::YMM_REGs) ;\
+    __asm__ volatile("vpblendd    $0x08, %%"#w_i_15", %%"#w_i_7", %%"#w_i_16" ":::YMM_REGs) ;\
+    __asm__ volatile("vperm2i128 $0x01,  %%"#w_i_7",  %%"#w_i_7", %%"#w_i_15" ":::YMM_REGs) ;\
+    __asm__ volatile("vpblendd    $0x80, %%"#w_i_15", %%"#w_i_16", %%"#w_i_16" ":::YMM_REGs) ;\
+    __asm__ volatile("vpshufd    $0x93,  %%"#w_i_16", %%"#w_i_16" ":::YMM_REGs) ;\
+
+#define MOVE_7_to_15(w_i_15, w_i_7)\
+    __asm__ volatile("vmovdqu                 %%"#w_i_7",  %%"#w_i_15" ":::YMM_REGs) ;\
+
+#define MOVE_I_to_7(w_i_7, w_i)\
+    __asm__ volatile("vperm2i128 $0x01,       %%"#w_i",   %%"#w_i",   %%"#w_i_7" ":::YMM_REGs) ;\
+    __asm__ volatile("vpblendd    $0x01,       %%"#w_i_7",   %%"#w_i", %%"#w_i_7" ":::YMM_REGs) ;\
+    __asm__ volatile("vpshufd    $0x39, %%"#w_i_7", %%"#w_i_7" ":::YMM_REGs) ;\
+
+#define MOVE_I_to_2(w_i_2, w_i)\
+    __asm__ volatile("vperm2i128 $0x01,       %%"#w_i", %%"#w_i", %%"#w_i_2" ":::YMM_REGs) ;\
+    __asm__ volatile("vpshufd    $0x0e, %%"#w_i_2", %%"#w_i_2" ":::YMM_REGs) ;\
+
+#define ROTATE_W(w_i_16, w_i_15, w_i_7, w_i_2, w_i)\
+    MOVE_15_to_16(w_i_16, w_i_15, w_i_7) ; \
+    MOVE_7_to_15(w_i_15, w_i_7) ; \
+    MOVE_I_to_7(w_i_7, w_i) ; \
+    MOVE_I_to_2(w_i_2, w_i) ;\
+
+#define _RegToDigest(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
+    { word32 d ;\
+    __asm__ volatile("movl %"#S_0", %0":"=r"(d)::SSE_REGs) ;\
+    sha256->digest[0] += d;\
+    __asm__ volatile("movl %"#S_1", %0":"=r"(d)::SSE_REGs) ;\
+    sha256->digest[1] += d;\
+    __asm__ volatile("movl %"#S_2", %0":"=r"(d)::SSE_REGs) ;\
+    sha256->digest[2] += d;\
+    __asm__ volatile("movl %"#S_3", %0":"=r"(d)::SSE_REGs) ;\
+    sha256->digest[3] += d;\
+    __asm__ volatile("movl %"#S_4", %0":"=r"(d)::SSE_REGs) ;\
+    sha256->digest[4] += d;\
+    __asm__ volatile("movl %"#S_5", %0":"=r"(d)::SSE_REGs) ;\
+    sha256->digest[5] += d;\
+    __asm__ volatile("movl %"#S_6", %0":"=r"(d)::SSE_REGs) ;\
+    sha256->digest[6] += d;\
+    __asm__ volatile("movl %"#S_7", %0":"=r"(d)::SSE_REGs) ;\
+    sha256->digest[7] += d;\
+}
+
+#define _DumpS(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
+  { word32 d[8] ;\
+    __asm__ volatile("movl %"#S_0", %0":"=r"(d[0])::SSE_REGs) ;\
+    __asm__ volatile("movl %"#S_1", %0":"=r"(d[1])::SSE_REGs) ;\
+    __asm__ volatile("movl %"#S_2", %0":"=r"(d[2])::SSE_REGs) ;\
+    __asm__ volatile("movl %"#S_3", %0":"=r"(d[3])::SSE_REGs) ;\
+    __asm__ volatile("movl %"#S_4", %0":"=r"(d[4])::SSE_REGs) ;\
+    __asm__ volatile("movl %"#S_5", %0":"=r"(d[5])::SSE_REGs) ;\
+    __asm__ volatile("movl %"#S_6", %0":"=r"(d[6])::SSE_REGs) ;\
+    __asm__ volatile("movl %"#S_7", %0":"=r"(d[7])::SSE_REGs) ;\
+        printf("S[0..7]=%08x,%08x,%08x,%08x,%08x,%08x,%08x,%08x\n", d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7]);\
+    __asm__ volatile("movl %0, %"#S_0::"r"(d[0]):SSE_REGs) ;\
+    __asm__ volatile("movl %0, %"#S_1::"r"(d[1]):SSE_REGs) ;\
+    __asm__ volatile("movl %0, %"#S_2::"r"(d[2]):SSE_REGs) ;\
+    __asm__ volatile("movl %0, %"#S_3::"r"(d[3]):SSE_REGs) ;\
+    __asm__ volatile("movl %0, %"#S_4::"r"(d[4]):SSE_REGs) ;\
+    __asm__ volatile("movl %0, %"#S_5::"r"(d[5]):SSE_REGs) ;\
+    __asm__ volatile("movl %0, %"#S_6::"r"(d[6]):SSE_REGs) ;\
+    __asm__ volatile("movl %0, %"#S_7::"r"(d[7]):SSE_REGs) ;\
+}
+
+
+#define DigestToReg(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
+    _DigestToReg(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )
+
+#define RegToDigest(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
+    _RegToDigest(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )
+
+#define DumS(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
+    _DumpS(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )
+
+        
+    /* Byte swap Masks to ensure that rest of the words are filled with zero's. */
+    static const unsigned long mBYTE_FLIP_MASK_16[] =  
+        { 0x0405060700010203, 0x0c0d0e0f08090a0b, 0x0405060700010203, 0x0c0d0e0f08090a0b } ;
+    static const unsigned long mBYTE_FLIP_MASK_15[] =  
+        { 0x0405060700010203, 0x0c0d0e0f08090a0b, 0x0405060700010203, 0x0c0d0e0f08090a0b } ;
+    static const unsigned long mBYTE_FLIP_MASK_7 [] =  
+        { 0x0405060700010203, 0x0c0d0e0f08090a0b, 0x0405060700010203, 0x8080808008090a0b } ;
+    static const unsigned long mBYTE_FLIP_MASK_2 [] =  
+        { 0x0405060700010203, 0x8080808080808080, 0x8080808080808080, 0x8080808080808080 } ;
+
+    static const unsigned long mMAPtoW_I_7[] =  
+        { 0x8080808080808080, 0x8080808080808080, 0x8080808080808080, 0x0302010080808080 } ;
+    static const unsigned long mMAP1toW_I_2[] = 
+        { 0x8080808080808080, 0x0706050403020100, 0x8080808080808080, 0x8080808080808080 } ;
+    static const unsigned long mMAP2toW_I_2[] = 
+        { 0x8080808080808080, 0x8080808080808080, 0x0f0e0d0c0b0a0908, 0x8080808080808080 } ;
+    static const unsigned long mMAP3toW_I_2[] = 
+        { 0x8080808080808080, 0x8080808080808080, 0x8080808080808080, 0x0706050403020100 } ;
+ 
+static int Transform_AVX2(Sha256* sha256)
+{
+
+    #ifdef WOLFSSL_SMALL_STACK
+        word32* W_K;
+        W_K = (word32*) XMALLOC(sizeof(word32) * 64, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (W_K == NULL)
+            return MEMORY_E;
+    #else
+        word32 W_K[64]  ;
+    #endif
+
+    MOVE_to_REG(W_I_16, sha256->buffer[0]);     BYTE_SWAP(W_I_16, mBYTE_FLIP_MASK_16[0]) ;
+    MOVE_to_REG(W_I_15, sha256->buffer[1]);     BYTE_SWAP(W_I_15, mBYTE_FLIP_MASK_15[0]) ;
+    MOVE_to_REG(W_I,    sha256->buffer[8]) ;    BYTE_SWAP(W_I,    mBYTE_FLIP_MASK_16[0]) ;
+    MOVE_to_REG(W_I_7,  sha256->buffer[16-7]) ; BYTE_SWAP(W_I_7,  mBYTE_FLIP_MASK_7[0])  ;
+    MOVE_to_REG(W_I_2,  sha256->buffer[16-2]) ; BYTE_SWAP(W_I_2,  mBYTE_FLIP_MASK_2[0])  ;
+
+    DigestToReg(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7) ;
+
+    ADD_MEM(W_K_TEMP, W_I_16, K[0]) ;
+    MOVE_to_MEM(W_K[0], W_K_TEMP) ; 
+
+    RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,0) ;
+    RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,1) ;
+    RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,2) ;
+    RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,3) ;  
+    RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,4) ;
+    RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,5) ;
+    RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,6) ;
+    RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,7) ;
+
+    ADD_MEM(YMM_TEMP0, W_I, K[8]) ;
+    MOVE_to_MEM(W_K[8], YMM_TEMP0) ; 
+
+        /* W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15] + W[i-16]) */
+                RND_0_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,8) ;
+        GAMMA0_1(W_I_TEMP, W_I_15) ;
+                RND_0_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,8) ;
+        GAMMA0_2(W_I_TEMP, W_I_15) ;
+                RND_0_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,8) ;
+        ADD(W_I_TEMP, W_I_16, W_I_TEMP) ;/* for saving W_I before adding incomplete W_I_7 */
+                RND_7_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,9) ;
+        ADD(W_I, W_I_7, W_I_TEMP);
+                RND_7_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,9) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ; 
+                RND_7_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,9) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ; 
+                RND_6_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,10) ;
+        ADD(W_I, W_I, YMM_TEMP0) ;/* now W[16..17] are completed */
+                RND_6_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,10) ;
+        FEEDBACK1_to_W_I_2 ;
+                RND_6_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,10) ;
+        FEEDBACK_to_W_I_7 ; 
+                RND_5_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,11) ;
+        ADD(W_I_TEMP, W_I_7, W_I_TEMP);
+                RND_5_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,11) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ; 
+                RND_5_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,11) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ; 
+                RND_4_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,12) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ;/* now W[16..19] are completed */
+                RND_4_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,12) ;
+        FEEDBACK2_to_W_I_2 ;
+                RND_4_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,12) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ;
+                RND_3_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,13) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ; 
+                RND_3_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,13) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ; /* now W[16..21] are completed */
+                RND_3_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,13) ;
+        FEEDBACK3_to_W_I_2 ;
+                RND_2_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,14) ;
+        GAMMA1(YMM_TEMP0, W_I_2) ;
+                RND_2_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,14) ;
+                RND_2_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,14) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ; /* now W[16..23] are completed */
+                RND_1_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,15) ;
+
+        MOVE_to_REG(YMM_TEMP0, K[16]) ;    
+                RND_1_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,15) ;
+        ROTATE_W(W_I_16, W_I_15, W_I_7, W_I_2, W_I) ;
+                RND_1_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,15) ;
+        ADD(YMM_TEMP0, YMM_TEMP0, W_I) ;
+        MOVE_to_MEM(W_K[16], YMM_TEMP0) ;
+
+        /* W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15] + W[i-16]) */
+                RND_0_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,16) ;
+        GAMMA0_1(W_I_TEMP, W_I_15) ;
+                RND_0_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,16) ;
+        GAMMA0_2(W_I_TEMP, W_I_15) ;
+                RND_0_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,16) ;
+        ADD(W_I_TEMP, W_I_16, W_I_TEMP) ;/* for saving W_I before adding incomplete W_I_7 */
+                RND_7_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,17) ;
+        ADD(W_I, W_I_7, W_I_TEMP);
+                RND_7_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,17) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ; 
+                RND_7_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,17) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ; 
+                RND_6_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,18) ;
+        ADD(W_I, W_I, YMM_TEMP0) ;/* now W[16..17] are completed */
+                RND_6_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,18) ;
+        FEEDBACK1_to_W_I_2 ;
+                RND_6_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,18) ;
+        FEEDBACK_to_W_I_7 ; 
+                RND_5_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,19) ;
+        ADD(W_I_TEMP, W_I_7, W_I_TEMP);
+                RND_5_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,19) ;
+        GAMMA1(YMM_TEMP0, W_I_2) ; 
+                RND_5_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,19) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ; 
+                RND_4_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,20) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ;/* now W[16..19] are completed */
+                RND_4_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,20) ;
+        FEEDBACK2_to_W_I_2 ;
+                RND_4_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,20) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ;
+                RND_3_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,21) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ; 
+                RND_3_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,21) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ; /* now W[16..21] are completed */
+                RND_3_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,21) ;
+        FEEDBACK3_to_W_I_2 ;
+                RND_2_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,22) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ;
+                RND_2_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,22) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ; 
+                RND_2_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,22) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ; /* now W[16..23] are completed */
+                RND_1_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,23) ;
+
+        MOVE_to_REG(YMM_TEMP0, K[24]) ;    
+                RND_1_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,23) ;
+        ROTATE_W(W_I_16, W_I_15, W_I_7, W_I_2, W_I) ;
+                RND_1_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,23) ;
+        ADD(YMM_TEMP0, YMM_TEMP0, W_I) ;
+        MOVE_to_MEM(W_K[24], YMM_TEMP0) ;
+
+                /* W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15] + W[i-16]) */
+                RND_0_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,24) ;
+        GAMMA0_1(W_I_TEMP, W_I_15) ;
+                RND_0_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,24) ;
+        GAMMA0_2(W_I_TEMP, W_I_15) ;
+                RND_0_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,24) ;
+        ADD(W_I_TEMP, W_I_16, W_I_TEMP) ;/* for saving W_I before adding incomplete W_I_7 */
+                RND_7_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,25) ;
+        ADD(W_I, W_I_7, W_I_TEMP);
+                RND_7_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,25) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ; 
+                RND_7_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,25) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ; 
+                RND_6_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,26) ;
+        ADD(W_I, W_I, YMM_TEMP0) ;/* now W[16..17] are completed */
+                RND_6_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,26) ;
+        FEEDBACK1_to_W_I_2 ;
+                RND_6_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,26) ;
+        FEEDBACK_to_W_I_7 ; 
+                RND_5_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,27) ;
+        ADD(W_I_TEMP, W_I_7, W_I_TEMP);
+                RND_5_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,27) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ; 
+                RND_5_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,27) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ; 
+                RND_4_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,28) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ;/* now W[16..19] are completed */
+                RND_4_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,28) ;
+        FEEDBACK2_to_W_I_2 ;
+                RND_4_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,28) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ;
+                RND_3_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,29) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ; 
+                RND_3_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,29) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ; /* now W[16..21] are completed */
+                RND_3_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,29) ;
+        FEEDBACK3_to_W_I_2 ;
+                RND_2_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,30) ;
+        GAMMA1(YMM_TEMP0, W_I_2) ;
+                RND_2_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,30) ;
+                RND_2_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,30) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ; /* now W[16..23] are completed */
+                RND_1_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,31) ;
+
+        MOVE_to_REG(YMM_TEMP0, K[32]) ;    
+                RND_1_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,31) ;
+        ROTATE_W(W_I_16, W_I_15, W_I_7, W_I_2, W_I) ;
+                RND_1_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,31) ;
+        ADD(YMM_TEMP0, YMM_TEMP0, W_I) ;
+        MOVE_to_MEM(W_K[32], YMM_TEMP0) ;
+
+        
+                /* W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15] + W[i-16]) */
+                RND_0_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,32) ;
+        GAMMA0_1(W_I_TEMP, W_I_15) ;
+                RND_0_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,32) ;
+        GAMMA0_2(W_I_TEMP, W_I_15) ;
+                RND_0_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,32) ;
+        ADD(W_I_TEMP, W_I_16, W_I_TEMP) ;/* for saving W_I before adding incomplete W_I_7 */
+                RND_7_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,33) ;
+        ADD(W_I, W_I_7, W_I_TEMP);
+                RND_7_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,33) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ;
+                RND_7_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,33) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ; 
+                RND_6_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,34) ;
+        ADD(W_I, W_I, YMM_TEMP0) ;/* now W[16..17] are completed */
+                RND_6_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,34) ;
+        FEEDBACK1_to_W_I_2 ;
+                RND_6_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,34) ;
+        FEEDBACK_to_W_I_7 ; 
+                RND_5_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,35) ;
+        ADD(W_I_TEMP, W_I_7, W_I_TEMP);
+                RND_5_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,35) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ;
+                RND_5_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,35) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ;
+                RND_4_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,36) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ;/* now W[16..19] are completed */
+                RND_4_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,36) ;
+        FEEDBACK2_to_W_I_2 ;
+                RND_4_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,36) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ;
+                RND_3_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,37) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ;
+                RND_3_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,37) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ; /* now W[16..21] are completed */
+                RND_3_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,37) ;
+        FEEDBACK3_to_W_I_2 ;
+                RND_2_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,38) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ;
+                RND_2_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,38) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ;
+                RND_2_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,38) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ; /* now W[16..23] are completed */
+                RND_1_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,39) ;
+
+        MOVE_to_REG(YMM_TEMP0, K[40]) ;    
+                RND_1_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,39) ;
+        ROTATE_W(W_I_16, W_I_15, W_I_7, W_I_2, W_I) ;
+                RND_1_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,39) ;
+        ADD(YMM_TEMP0, YMM_TEMP0, W_I) ;
+        MOVE_to_MEM(W_K[40], YMM_TEMP0) ;
+
+                /* W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15] + W[i-16]) */
+                RND_0_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,40) ;
+        GAMMA0_1(W_I_TEMP, W_I_15) ;
+                RND_0_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,40) ;
+        GAMMA0_2(W_I_TEMP, W_I_15) ;
+                RND_0_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,40) ;
+        ADD(W_I_TEMP, W_I_16, W_I_TEMP) ;/* for saving W_I before adding incomplete W_I_7 */
+                RND_7_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,41) ;
+        ADD(W_I, W_I_7, W_I_TEMP);
+                RND_7_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,41) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ;
+                RND_7_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,41) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ;
+                RND_6_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,42) ;
+        ADD(W_I, W_I, YMM_TEMP0) ;/* now W[16..17] are completed */
+                RND_6_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,42) ;
+        FEEDBACK1_to_W_I_2 ;
+                RND_6_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,42) ;
+        FEEDBACK_to_W_I_7 ; 
+                RND_5_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,43) ;
+        ADD(W_I_TEMP, W_I_7, W_I_TEMP);
+                RND_5_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,43) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ; 
+                RND_5_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,43) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ;
+                RND_4_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,44) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ;/* now W[16..19] are completed */
+                RND_4_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,44) ;
+        FEEDBACK2_to_W_I_2 ;
+                RND_4_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,44) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ;
+                RND_3_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,45) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ;
+                RND_3_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,45) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ; /* now W[16..21] are completed */
+                RND_3_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,45) ;
+        FEEDBACK3_to_W_I_2 ;
+                RND_2_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,46) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ;
+                RND_2_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,46) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ;
+                RND_2_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,46) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ; /* now W[16..23] are completed */
+                RND_1_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,47) ;
+
+        MOVE_to_REG(YMM_TEMP0, K[48]) ;    
+                RND_1_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,47) ;
+        ROTATE_W(W_I_16, W_I_15, W_I_7, W_I_2, W_I) ;
+                RND_1_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,47) ;
+        ADD(YMM_TEMP0, YMM_TEMP0, W_I) ;
+        MOVE_to_MEM(W_K[48], YMM_TEMP0) ;
+        
+                /* W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15] + W[i-16]) */
+                RND_0_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,48) ;
+        GAMMA0_1(W_I_TEMP, W_I_15) ;
+                RND_0_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,48) ;
+        GAMMA0_2(W_I_TEMP, W_I_15) ;
+                RND_0_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,48) ;
+        ADD(W_I_TEMP, W_I_16, W_I_TEMP) ;/* for saving W_I before adding incomplete W_I_7 */
+                RND_7_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,49) ;
+        ADD(W_I, W_I_7, W_I_TEMP);
+                RND_7_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,49) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ; 
+                RND_7_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,49) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ;
+                RND_6_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,50) ;
+        ADD(W_I, W_I, YMM_TEMP0) ;/* now W[16..17] are completed */
+                RND_6_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,50) ;
+        FEEDBACK1_to_W_I_2 ;
+                RND_6_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,50) ;
+        FEEDBACK_to_W_I_7 ; 
+                RND_5_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,51) ;
+        ADD(W_I_TEMP, W_I_7, W_I_TEMP);
+                RND_5_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,51) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ;
+                RND_5_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,51) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ;
+                RND_4_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,52) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ;/* now W[16..19] are completed */
+                RND_4_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,52) ;
+        FEEDBACK2_to_W_I_2 ;
+                RND_4_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,52) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ;
+                RND_3_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,53) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ;
+                RND_3_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,53) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ; /* now W[16..21] are completed */
+                RND_3_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,53) ;
+        FEEDBACK3_to_W_I_2 ;
+                RND_2_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,54) ;
+        GAMMA1_1(YMM_TEMP0, W_I_2) ;
+                RND_2_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,54) ;
+        GAMMA1_2(YMM_TEMP0, W_I_2) ;
+                RND_2_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,54) ;
+        ADD(W_I, W_I_TEMP, YMM_TEMP0) ; /* now W[16..23] are completed */
+                RND_1_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,55) ;
+
+        MOVE_to_REG(YMM_TEMP0, K[56]) ;    
+                RND_1_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,55) ;
+        ROTATE_W(W_I_16, W_I_15, W_I_7, W_I_2, W_I) ;
+                RND_1_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,55) ;
+        ADD(YMM_TEMP0, YMM_TEMP0, W_I) ;
+        MOVE_to_MEM(W_K[56], YMM_TEMP0) ;        
+        
+        RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,56) ;
+        RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,57) ;
+        RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,58) ;
+        RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,59) ;
+
+        RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,60) ;
+        RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,61) ;
+        RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,62) ;
+        RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,63) ;
+
+    RegToDigest(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7) ;  
+
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    #endif
+    
+    return 0;
+}
+
+#endif   /* HAVE_INTEL_AVX2 */
+
+#endif   /* HAVE_FIPS */
+
+#endif   /* WOLFSSL_TI_HAHS */
+
+#endif /* NO_SHA256 */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/sha512.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/sha512.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/sha512.c	(revision 164)
@@ -0,0 +1,1737 @@
+/* sha512.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+#include <wolfssl/wolfcrypt/sha512.h>
+
+#ifdef WOLFSSL_SHA512
+
+#ifdef HAVE_FIPS
+int wc_InitSha512(Sha512* sha)
+{
+    return InitSha512_fips(sha);
+}
+
+
+int wc_Sha512Update(Sha512* sha, const byte* data, word32 len)
+{
+    return Sha512Update_fips(sha, data, len);
+}
+
+
+int wc_Sha512Final(Sha512* sha, byte* out)
+{
+    return Sha512Final_fips(sha, out);
+}
+
+
+#if defined(WOLFSSL_SHA384) || defined(HAVE_AESGCM)
+
+int wc_InitSha384(Sha384* sha)
+{
+    return InitSha384_fips(sha);
+}
+
+
+int wc_Sha384Update(Sha384* sha, const byte* data, word32 len)
+{
+    return Sha384Update_fips(sha, data, len);
+}
+
+
+int wc_Sha384Final(Sha384* sha, byte* out)
+{
+    return Sha384Final_fips(sha, out);
+}
+
+
+#endif /* WOLFSSL_SHA384 */
+#else /* else build without using fips */
+#include <wolfssl/wolfcrypt/logging.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+
+#ifdef min
+#define WOLFSSL_HAVE_MIN
+#endif
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
+
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+
+#endif /* WOLFSSL_HAVE_MIN */
+
+#if defined(USE_INTEL_SPEEDUP)
+  #define HAVE_INTEL_AVX1
+  #define HAVE_INTEL_AVX2
+#endif
+
+#if defined(HAVE_INTEL_AVX1)
+/* #define DEBUG_XMM  */
+#endif
+
+#if defined(HAVE_INTEL_AVX2)
+#define HAVE_INTEL_RORX
+/* #define DEBUG_YMM  */
+#endif
+
+/*****
+Intel AVX1/AVX2 Macro Control Structure
+
+#if defined(HAVE_INteL_SPEEDUP)
+    #define HAVE_INTEL_AVX1
+    #define HAVE_INTEL_AVX2
+#endif
+
+int InitSha512(Sha512* sha512) { 
+     Save/Recover XMM, YMM
+     ...
+
+     Check Intel AVX cpuid flags
+}
+
+#if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
+  Transform_AVX1() ; # Function prototype 
+  Transform_AVX2() ; #
+#endif
+
+  _Transform() {     # Native Transform Function body
+  
+  }
+  
+  int Sha512Update() { 
+     Save/Recover XMM, YMM
+     ...
+  }
+  
+  int Sha512Final() { 
+     Save/Recover XMM, YMM
+     ...
+  }
+
+
+#if defined(HAVE_INTEL_AVX1)
+   
+   XMM Instructions/INLINE asm Definitions
+
+#endif
+
+#if defined(HAVE_INTEL_AVX2)
+
+   YMM Instructions/INLINE asm Definitions
+
+#endif
+
+#if defnied(HAVE_INTEL_AVX1)
+  
+  int Transform_AVX1() {
+      Stitched Message Sched/Round
+  }
+
+#endif
+
+#if defnied(HAVE_INTEL_AVX2)
+  
+  int Transform_AVX2() {
+      Stitched Message Sched/Round
+  }
+#endif
+
+
+*/
+
+#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+
+
+/* Each platform needs to query info type 1 from cpuid to see if aesni is
+ * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
+ */
+
+#ifndef _MSC_VER
+    #define cpuid(reg, leaf, sub)\
+            __asm__ __volatile__ ("cpuid":\
+             "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3]) :\
+             "a" (leaf), "c"(sub));
+
+    #define XASM_LINK(f) asm(f)
+#else
+
+    #include <intrin.h>
+    #define cpuid(a,b) __cpuid((int*)a,b)
+
+    #define XASM_LINK(f)
+
+#endif /* _MSC_VER */
+
+#define EAX 0
+#define EBX 1
+#define ECX 2 
+#define EDX 3
+    
+#define CPUID_AVX1   0x1
+#define CPUID_AVX2   0x2
+#define CPUID_RDRAND 0x4
+#define CPUID_RDSEED 0x8
+#define CPUID_BMI2   0x10   /* MULX, RORX */
+
+#define IS_INTEL_AVX1       (cpuid_flags&CPUID_AVX1)
+#define IS_INTEL_AVX2       (cpuid_flags&CPUID_AVX2)
+#define IS_INTEL_BMI2       (cpuid_flags&CPUID_BMI2)
+#define IS_INTEL_RDRAND     (cpuid_flags&CPUID_RDRAND)
+#define IS_INTEL_RDSEED     (cpuid_flags&CPUID_RDSEED)
+
+static word32 cpuid_check = 0 ;
+static word32 cpuid_flags = 0 ;
+
+static word32 cpuid_flag(word32 leaf, word32 sub, word32 num, word32 bit) {
+    int got_intel_cpu=0;
+    unsigned int reg[5]; 
+    
+    reg[4] = '\0' ;
+    cpuid(reg, 0, 0);  
+    if(memcmp((char *)&(reg[EBX]), "Genu", 4) == 0 &&  
+                memcmp((char *)&(reg[EDX]), "ineI", 4) == 0 &&  
+                memcmp((char *)&(reg[ECX]), "ntel", 4) == 0) {  
+        got_intel_cpu = 1;  
+    }    
+    if (got_intel_cpu) {
+        cpuid(reg, leaf, sub);
+        return((reg[num]>>bit)&0x1) ;
+    }
+    return 0 ;
+}
+
+#define CHECK_SHA512 0x1
+#define CHECK_SHA384 0x2
+
+static int set_cpuid_flags(int sha) {  
+    if((cpuid_check & sha) ==0) {
+        if(cpuid_flag(1, 0, ECX, 28)){ cpuid_flags |= CPUID_AVX1 ;}
+        if(cpuid_flag(7, 0, EBX, 5)){  cpuid_flags |= CPUID_AVX2 ; }
+        if(cpuid_flag(7, 0, EBX, 8)) { cpuid_flags |= CPUID_BMI2 ; }
+        if(cpuid_flag(1, 0, ECX, 30)){ cpuid_flags |= CPUID_RDRAND ;  } 
+        if(cpuid_flag(7, 0, EBX, 18)){ cpuid_flags |= CPUID_RDSEED ;  }
+		cpuid_check |= sha ;
+		return 0 ;
+    }
+    return 1 ;
+}
+
+
+/* #if defined(HAVE_INTEL_AVX1/2) at the tail of sha512 */
+
+#if defined(HAVE_INTEL_AVX1)
+static int Transform_AVX1(Sha512 *sha512) ;
+#endif
+
+#if defined(HAVE_INTEL_AVX2)
+static int Transform_AVX2(Sha512 *sha512) ; 
+
+#if defined(HAVE_INTEL_AVX1) && defined(HAVE_INTEL_AVX2) && defined(HAVE_INTEL_RORX)
+static int Transform_AVX1_RORX(Sha512 *sha512) ;
+#endif
+
+#endif
+
+static int _Transform(Sha512 *sha512) ; 
+    
+static int (*Transform_p)(Sha512* sha512) = _Transform ;
+
+#define Transform(sha512) (*Transform_p)(sha512)
+
+static void set_Transform(void) {
+     if(set_cpuid_flags(CHECK_SHA512)) return ;
+
+#if defined(HAVE_INTEL_AVX2)
+     if(IS_INTEL_AVX2 && IS_INTEL_BMI2){ 
+         Transform_p = Transform_AVX1_RORX; return ; 
+         Transform_p = Transform_AVX2      ; 
+                  /* for avoiding warning,"not used" */
+     }
+#endif
+#if defined(HAVE_INTEL_AVX1)
+     Transform_p = ((IS_INTEL_AVX1) ? Transform_AVX1 : _Transform) ; return ;
+#endif
+     Transform_p = _Transform ; return ;
+}
+
+#else
+   #define Transform(sha512) _Transform(sha512)
+#endif
+
+/* Dummy for saving MM_REGs on behalf of Transform */
+/* #if defined(HAVE_INTEL_AVX2)
+ #define  SAVE_XMM_YMM   __asm__ volatile("orq %%r8, %%r8":::\
+   "%ymm0","%ymm1","%ymm2","%ymm3","%ymm4","%ymm5","%ymm6","%ymm7","%ymm8","%ymm9","%ymm10","%ymm11",\
+   "%ymm12","%ymm13","%ymm14","%ymm15")
+*/
+#if defined(HAVE_INTEL_AVX1)
+   #define  SAVE_XMM_YMM   __asm__ volatile("orq %%r8, %%r8":::\
+    "xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7","xmm8","xmm9","xmm10","xmm11","xmm12","xmm13","xmm14","xmm15")
+#else
+#define  SAVE_XMM_YMM
+#endif
+
+#if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
+
+#include <string.h>
+
+#endif /* defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2) */
+
+
+#if defined(HAVE_INTEL_RORX)
+#define ROTR(func, bits, x) \
+word64 func(word64 x) {  word64 ret ;\
+    __asm__ ("rorx $"#bits", %1, %0\n\t":"=r"(ret):"r"(x):) ;\
+    return ret ;\
+}
+
+static INLINE ROTR(rotrFixed64_28, 28, x)
+static INLINE ROTR(rotrFixed64_34, 34, x)
+static INLINE ROTR(rotrFixed64_39, 39, x)
+static INLINE ROTR(rotrFixed64_14, 14, x)
+static INLINE ROTR(rotrFixed64_18, 18, x)
+static INLINE ROTR(rotrFixed64_41, 41, x)
+
+#define S0_RORX(x) (rotrFixed64_28(x)^rotrFixed64_34(x)^rotrFixed64_39(x))
+#define S1_RORX(x) (rotrFixed64_14(x)^rotrFixed64_18(x)^rotrFixed64_41(x))
+#endif
+
+#if defined(HAVE_BYTEREVERSE64) && !defined(HAVE_INTEL_AVX1) && !defined(HAVE_INTEL_AVX2)
+#define ByteReverseWords64(out, in, size) ByteReverseWords64_1(out, size)
+#define ByteReverseWords64_1(buf, size)\
+ { unsigned int i ;\
+   for(i=0; i< size/sizeof(word64); i++){\
+       __asm__ volatile("bswapq %0":"+r"(buf[i])::) ;\
+   }\
+}
+#endif
+
+
+int wc_InitSha512(Sha512* sha512)
+{
+    sha512->digest[0] = W64LIT(0x6a09e667f3bcc908);
+    sha512->digest[1] = W64LIT(0xbb67ae8584caa73b);
+    sha512->digest[2] = W64LIT(0x3c6ef372fe94f82b);
+    sha512->digest[3] = W64LIT(0xa54ff53a5f1d36f1);
+    sha512->digest[4] = W64LIT(0x510e527fade682d1);
+    sha512->digest[5] = W64LIT(0x9b05688c2b3e6c1f);
+    sha512->digest[6] = W64LIT(0x1f83d9abfb41bd6b);
+    sha512->digest[7] = W64LIT(0x5be0cd19137e2179);
+
+    sha512->buffLen = 0;
+    sha512->loLen   = 0;
+    sha512->hiLen   = 0;
+    
+#if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
+    set_Transform() ; /* choose best Transform function under this runtime environment */
+#endif
+    
+    return 0 ;
+}
+
+
+static const word64 K512[80] = {
+	W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
+	W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
+	W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
+	W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
+	W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
+	W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
+	W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
+	W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
+	W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
+	W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
+	W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
+	W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
+	W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
+	W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
+	W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
+	W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
+	W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
+	W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
+	W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
+	W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
+	W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
+	W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
+	W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
+	W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
+	W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
+	W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
+	W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
+	W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
+	W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
+	W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
+	W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
+	W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
+	W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
+	W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
+	W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
+	W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
+	W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
+	W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
+	W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
+	W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
+};
+
+
+
+#define blk0(i) (W[i] = sha512->buffer[i])
+
+#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
+
+#define Ch(x,y,z) (z^(x&(y^z)))
+#define Maj(x,y,z) ((x&y)|(z&(x|y)))
+
+#define a(i) T[(0-i)&7]
+#define b(i) T[(1-i)&7]
+#define c(i) T[(2-i)&7]
+#define d(i) T[(3-i)&7]
+#define e(i) T[(4-i)&7]
+#define f(i) T[(5-i)&7]
+#define g(i) T[(6-i)&7]
+#define h(i) T[(7-i)&7]
+
+#define S0(x) (rotrFixed64(x,28)^rotrFixed64(x,34)^rotrFixed64(x,39))
+#define S1(x) (rotrFixed64(x,14)^rotrFixed64(x,18)^rotrFixed64(x,41))
+#define s0(x) (rotrFixed64(x,1)^rotrFixed64(x,8)^(x>>7))
+#define s1(x) (rotrFixed64(x,19)^rotrFixed64(x,61)^(x>>6))
+
+#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j]+(j?blk2(i):blk0(i));\
+    d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
+
+#define blk384(i) (W[i] = sha384->buffer[i])
+
+#define R2(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j]+(j?blk2(i):blk384(i));\
+    d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
+
+static int _Transform(Sha512* sha512)
+{
+    const word64* K = K512;
+
+    word32 j;
+    word64 T[8];
+
+
+#ifdef WOLFSSL_SMALL_STACK
+    word64* W;
+    W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (W == NULL)
+        return MEMORY_E;
+#else
+    word64 W[16];
+#endif
+
+    /* Copy digest to working vars */
+    XMEMCPY(T, sha512->digest, sizeof(T));
+
+#ifdef USE_SLOW_SHA2
+    /* over twice as small, but 50% slower */
+    /* 80 operations, not unrolled */
+    for (j = 0; j < 80; j += 16) {
+        int m; 
+        for (m = 0; m < 16; m++) { /* braces needed here for macros {} */
+            R(m);
+        }
+    }
+#else
+    /* 80 operations, partially loop unrolled */
+    for (j = 0; j < 80; j += 16) {
+        R( 0); R( 1); R( 2); R( 3);
+        R( 4); R( 5); R( 6); R( 7);
+        R( 8); R( 9); R(10); R(11);
+        R(12); R(13); R(14); R(15);
+    }
+#endif /* USE_SLOW_SHA2 */
+
+    /* Add the working vars back into digest */
+
+    sha512->digest[0] += a(0);
+    sha512->digest[1] += b(0);
+    sha512->digest[2] += c(0);
+    sha512->digest[3] += d(0);
+    sha512->digest[4] += e(0);
+    sha512->digest[5] += f(0);
+    sha512->digest[6] += g(0);
+    sha512->digest[7] += h(0);
+
+    /* Wipe variables */
+    ForceZero(W, sizeof(word64) * 16);
+    ForceZero(T, sizeof(T));
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return 0;
+}
+
+
+static INLINE void AddLength(Sha512* sha512, word32 len)
+{
+    word32 tmp = sha512->loLen;
+    if ( (sha512->loLen += len) < tmp)
+        sha512->hiLen++;                       /* carry low to high */
+}
+
+int wc_Sha512Update(Sha512* sha512, const byte* data, word32 len)
+{
+    /* do block size increments */
+    byte* local = (byte*)sha512->buffer;
+    SAVE_XMM_YMM ; /* for Intel AVX */
+
+    while (len) {
+        word32 add = min(len, SHA512_BLOCK_SIZE - sha512->buffLen);
+        XMEMCPY(&local[sha512->buffLen], data, add);
+
+        sha512->buffLen += add;
+        data         += add;
+        len          -= add;
+
+        if (sha512->buffLen == SHA512_BLOCK_SIZE) {
+            int ret;
+            #if defined(LITTLE_ENDIAN_ORDER)
+                #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+                if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2) 
+                #endif
+                    ByteReverseWords64(sha512->buffer, sha512->buffer,
+                                   SHA512_BLOCK_SIZE);
+            #endif
+            ret = Transform(sha512);
+            if (ret != 0)
+                return ret;
+
+            AddLength(sha512, SHA512_BLOCK_SIZE);
+            sha512->buffLen = 0;
+        }
+    }
+    return 0;
+}
+
+
+int wc_Sha512Final(Sha512* sha512, byte* hash)
+{
+    byte* local = (byte*)sha512->buffer;
+    int ret;
+
+    SAVE_XMM_YMM ; /* for Intel AVX */
+    AddLength(sha512, sha512->buffLen);               /* before adding pads */
+
+    local[sha512->buffLen++] = 0x80;  /* add 1 */
+
+    /* pad with zeros */
+    if (sha512->buffLen > SHA512_PAD_SIZE) {
+        XMEMSET(&local[sha512->buffLen], 0, SHA512_BLOCK_SIZE -sha512->buffLen);
+        sha512->buffLen += SHA512_BLOCK_SIZE - sha512->buffLen;
+        #if defined(LITTLE_ENDIAN_ORDER) 
+            #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+            if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2)
+            #endif
+            ByteReverseWords64(sha512->buffer,sha512->buffer,SHA512_BLOCK_SIZE);
+        #endif
+        ret = Transform(sha512);
+        if (ret != 0)
+            return ret;
+
+        sha512->buffLen = 0;
+    }
+    XMEMSET(&local[sha512->buffLen], 0, SHA512_PAD_SIZE - sha512->buffLen);
+   
+    /* put lengths in bits */
+    sha512->hiLen = (sha512->loLen >> (8*sizeof(sha512->loLen) - 3)) + 
+                 (sha512->hiLen << 3);
+    sha512->loLen = sha512->loLen << 3;
+
+    /* store lengths */
+    #if defined(LITTLE_ENDIAN_ORDER)
+        #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+        if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2)
+        #endif
+        ByteReverseWords64(sha512->buffer, sha512->buffer, SHA512_PAD_SIZE);
+    #endif
+    /* ! length ordering dependent on digest endian type ! */
+
+    sha512->buffer[SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen;
+    sha512->buffer[SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen;
+    #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+    if(IS_INTEL_AVX1 || IS_INTEL_AVX2)
+        ByteReverseWords64(&(sha512->buffer[SHA512_BLOCK_SIZE / sizeof(word64) - 2]),
+                           &(sha512->buffer[SHA512_BLOCK_SIZE / sizeof(word64) - 2]),
+                           SHA512_BLOCK_SIZE - SHA512_PAD_SIZE);
+    #endif
+    ret = Transform(sha512);
+    if (ret != 0)
+        return ret;
+
+    #ifdef LITTLE_ENDIAN_ORDER
+        ByteReverseWords64(sha512->digest, sha512->digest, SHA512_DIGEST_SIZE);
+    #endif
+    XMEMCPY(hash, sha512->digest, SHA512_DIGEST_SIZE);
+
+    return wc_InitSha512(sha512);  /* reset state */
+}
+
+
+
+#if defined(HAVE_INTEL_AVX1)
+
+#define Rx_1(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j] + W_X[i] ;
+#define Rx_2(i) d(i)+=h(i);
+#define Rx_3(i) h(i)+=S0(a(i))+Maj(a(i),b(i),c(i));
+
+#if defined(HAVE_INTEL_RORX)
+#define Rx_RORX_1(i) h(i)+=S1_RORX(e(i))+Ch(e(i),f(i),g(i))+K[i+j] + W_X[i] ;
+#define Rx_RORX_2(i) d(i)+=h(i);
+#define Rx_RORX_3(i) h(i)+=S0_RORX(a(i))+Maj(a(i),b(i),c(i));
+#endif
+
+#endif
+
+#if defined(HAVE_INTEL_AVX2) 
+#define Ry_1(i, w) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j] + w ; 
+#define Ry_2(i, w) d(i)+=h(i);
+#define Ry_3(i, w) h(i)+=S0(a(i))+Maj(a(i),b(i),c(i));
+#endif
+
+#if defined(HAVE_INTEL_AVX1) /* INLINE Assember for Intel AVX1 instructions */
+#if defined(DEBUG_XMM)
+
+#define SAVE_REG(i)     __asm__ volatile("vmovdqu %%xmm"#i", %0 \n\t":"=m"(reg[i][0])::XMM_REGs);
+#define RECV_REG(i)     __asm__ volatile("vmovdqu %0, %%xmm"#i" \n\t"::"m"(reg[i][0]):XMM_REGs);
+
+#define _DUMP_REG(REG, name)\
+    { word64 buf[16] ;word64 reg[16][2];int k ;\
+      SAVE_REG(0); SAVE_REG(1); SAVE_REG(2);  SAVE_REG(3);  SAVE_REG(4);  \
+      SAVE_REG(5);   SAVE_REG(6); SAVE_REG(7);SAVE_REG(8); SAVE_REG(9); SAVE_REG(10);\
+       SAVE_REG(11); SAVE_REG(12); SAVE_REG(13); SAVE_REG(14); SAVE_REG(15); \
+      __asm__ volatile("vmovdqu %%"#REG", %0 \n\t":"=m"(buf[0])::XMM_REGs);\
+      printf(" "#name":\t") ; for(k=0; k<2; k++) printf("%016lx.", (word64)(buf[k])); printf("\n") ; \
+      RECV_REG(0); RECV_REG(1); RECV_REG(2);  RECV_REG(3);  RECV_REG(4);\
+      RECV_REG(5);   RECV_REG(6); RECV_REG(7); RECV_REG(8); RECV_REG(9);\
+      RECV_REG(10); RECV_REG(11); RECV_REG(12); RECV_REG(13); RECV_REG(14); RECV_REG(15);\
+    }
+
+#define DUMP_REG(REG) _DUMP_REG(REG, #REG) 
+#define PRINTF(fmt, ...) 
+
+#else
+
+#define DUMP_REG(REG) 
+#define PRINTF(fmt, ...) 
+
+#endif
+
+#define _MOVE_to_REG(xymm, mem)       __asm__ volatile("vmovdqu %0, %%"#xymm" "\
+        :: "m"(mem):XMM_REGs) ;
+#define _MOVE_to_MEM(mem,i, xymm)     __asm__ volatile("vmovdqu %%"#xymm", %0" :\
+         "=m"(mem[i]),"=m"(mem[i+1]),"=m"(mem[i+2]),"=m"(mem[i+3])::XMM_REGs) ;
+#define _MOVE(dest, src)              __asm__ volatile("vmovdqu %%"#src",  %%"\
+        #dest" ":::XMM_REGs) ;
+
+#define _S_TEMP(dest, src, bits, temp)  __asm__ volatile("vpsrlq  $"#bits", %%"\
+        #src", %%"#dest"\n\tvpsllq  $64-"#bits", %%"#src", %%"#temp"\n\tvpor %%"\
+        #temp",%%"#dest", %%"#dest" ":::XMM_REGs) ;
+#define _AVX1_R(dest, src, bits)      __asm__ volatile("vpsrlq  $"#bits", %%"\
+        #src", %%"#dest" ":::XMM_REGs) ;
+#define _XOR(dest, src1, src2)        __asm__ volatile("vpxor   %%"#src1", %%"\
+        #src2", %%"#dest" ":::XMM_REGs) ;
+#define _OR(dest, src1, src2)         __asm__ volatile("vpor    %%"#src1", %%"\
+        #src2", %%"#dest" ":::XMM_REGs) ;
+#define _ADD(dest, src1, src2)        __asm__ volatile("vpaddq   %%"#src1", %%"\
+        #src2", %%"#dest" ":::XMM_REGs) ;
+#define _ADD_MEM(dest, src1, mem)     __asm__ volatile("vpaddq   %0, %%"#src1", %%"\
+        #dest" "::"m"(mem):XMM_REGs) ;
+
+#define MOVE_to_REG(xymm, mem)      _MOVE_to_REG(xymm, mem)
+#define MOVE_to_MEM(mem, i, xymm)   _MOVE_to_MEM(mem, i, xymm)
+#define MOVE(dest, src)             _MOVE(dest, src)  
+
+#define XOR(dest, src1, src2)      _XOR(dest, src1, src2)
+#define OR(dest, src1, src2)       _OR(dest, src1, src2)
+#define ADD(dest, src1, src2)      _ADD(dest, src1, src2)
+
+#define S_TMP(dest, src, bits, temp) _S_TEMP(dest, src, bits, temp);
+#define AVX1_S(dest, src, bits)      S_TMP(dest, src, bits, S_TEMP)
+#define AVX1_R(dest, src, bits)      _AVX1_R(dest, src, bits)
+
+#define Init_Mask(mask) \
+     __asm__ volatile("vmovdqu %0, %%xmm1\n\t"::"m"(mask):"%xmm1") ;
+     
+#define _W_from_buff1(w, buff, xmm) \
+    /* X0..3(xmm4..7), W[0..15] = sha512->buffer[0.15];  */\
+     __asm__ volatile("vmovdqu %1, %%"#xmm"\n\t"\
+                      "vpshufb %%xmm1, %%"#xmm", %%"#xmm"\n\t"\
+                      "vmovdqu %%"#xmm", %0"\
+                      :"=m"(w): "m"(buff):"%xmm0") ;
+
+#define W_from_buff1(w, buff, xmm) _W_from_buff1(w, buff, xmm) 
+
+#define W_from_buff(w, buff)\
+     Init_Mask(mBYTE_FLIP_MASK[0]) ;\
+     W_from_buff1(w[0], buff[0], W_0);\
+     W_from_buff1(w[2], buff[2], W_2);\
+     W_from_buff1(w[4], buff[4], W_4);\
+     W_from_buff1(w[6], buff[6], W_6);\
+     W_from_buff1(w[8], buff[8], W_8);\
+     W_from_buff1(w[10],buff[10],W_10);\
+     W_from_buff1(w[12],buff[12],W_12);\
+     W_from_buff1(w[14],buff[14],W_14);
+                          
+static word64 mBYTE_FLIP_MASK[] =  { 0x0001020304050607, 0x08090a0b0c0d0e0f } ;
+
+#define W_I_15  xmm14
+#define W_I_7   xmm11
+#define W_I_2   xmm13
+#define W_I     xmm12
+#define G_TEMP  xmm0
+#define S_TEMP  xmm1
+#define XMM_TEMP0  xmm2
+
+#define W_0     xmm12
+#define W_2     xmm3
+#define W_4     xmm4
+#define W_6     xmm5
+#define W_8     xmm6
+#define W_10    xmm7
+#define W_12    xmm8
+#define W_14    xmm9
+
+#define XMM_REGs
+
+#define s0_1(dest, src)      AVX1_S(dest, src, 1); 
+#define s0_2(dest, src)      AVX1_S(G_TEMP, src, 8); XOR(dest, G_TEMP, dest) ; 
+#define s0_3(dest, src)      AVX1_R(G_TEMP, src, 7);  XOR(dest, G_TEMP, dest) ;
+
+#define s1_1(dest, src)      AVX1_S(dest, src, 19);
+#define s1_2(dest, src)      AVX1_S(G_TEMP, src, 61); XOR(dest, G_TEMP, dest) ; 
+#define s1_3(dest, src)      AVX1_R(G_TEMP, src, 6); XOR(dest, G_TEMP, dest) ;
+
+#define s0_(dest, src)       s0_1(dest, src) ; s0_2(dest, src) ; s0_3(dest, src)
+#define s1_(dest, src)       s1_1(dest, src) ; s1_2(dest, src) ; s1_3(dest, src)
+        
+#define Block_xx_1(i) \
+    MOVE_to_REG(W_I_15, W_X[(i-15)&15]) ;\
+    MOVE_to_REG(W_I_7,  W_X[(i- 7)&15]) ;\
+        
+#define Block_xx_2(i) \
+    MOVE_to_REG(W_I_2,  W_X[(i- 2)&15]) ;\
+    MOVE_to_REG(W_I,    W_X[(i)]) ;\
+        
+#define Block_xx_3(i) \
+    s0_ (XMM_TEMP0, W_I_15) ;\
+        
+#define Block_xx_4(i) \
+    ADD(W_I, W_I, XMM_TEMP0) ;\
+    ADD(W_I, W_I, W_I_7) ;\
+        
+#define Block_xx_5(i) \
+    s1_ (XMM_TEMP0, W_I_2) ;\
+    
+#define Block_xx_6(i) \
+    ADD(W_I, W_I, XMM_TEMP0) ;\
+    MOVE_to_MEM(W_X,i, W_I) ;\
+    if(i==0)\
+        MOVE_to_MEM(W_X,16, W_I) ;\
+
+#define Block_xx_7(i) \
+    MOVE_to_REG(W_I_15, W_X[(i-15)&15]) ;\
+    MOVE_to_REG(W_I_7,  W_X[(i- 7)&15]) ;\
+            
+#define Block_xx_8(i) \
+    MOVE_to_REG(W_I_2,  W_X[(i- 2)&15]) ;\
+    MOVE_to_REG(W_I,    W_X[(i)]) ;\
+
+#define Block_xx_9(i) \
+    s0_ (XMM_TEMP0, W_I_15) ;\
+
+#define Block_xx_10(i) \
+    ADD(W_I, W_I, XMM_TEMP0) ;\
+    ADD(W_I, W_I, W_I_7) ;\
+
+#define Block_xx_11(i) \
+    s1_ (XMM_TEMP0, W_I_2) ;\
+
+#define Block_xx_12(i) \
+    ADD(W_I, W_I, XMM_TEMP0) ;\
+    MOVE_to_MEM(W_X,i, W_I) ;\
+    if((i)==0)\
+        MOVE_to_MEM(W_X,16, W_I) ;\
+
+static INLINE void Block_0_1(word64 *W_X) { Block_xx_1(0) ; }
+static INLINE void Block_0_2(word64 *W_X) { Block_xx_2(0) ; }
+static INLINE void Block_0_3(void) { Block_xx_3(0) ; }
+static INLINE void Block_0_4(void) { Block_xx_4(0) ; }
+static INLINE void Block_0_5(void) { Block_xx_5(0) ; }
+static INLINE void Block_0_6(word64 *W_X) { Block_xx_6(0) ; }
+static INLINE void Block_0_7(word64 *W_X) { Block_xx_7(2) ; }
+static INLINE void Block_0_8(word64 *W_X) { Block_xx_8(2) ; }
+static INLINE void Block_0_9(void) { Block_xx_9(2) ; }
+static INLINE void Block_0_10(void){ Block_xx_10(2) ; }
+static INLINE void Block_0_11(void){ Block_xx_11(2) ; }
+static INLINE void Block_0_12(word64 *W_X){ Block_xx_12(2) ; }
+
+static INLINE void Block_4_1(word64 *W_X) { Block_xx_1(4) ; }
+static INLINE void Block_4_2(word64 *W_X) { Block_xx_2(4) ; }
+static INLINE void Block_4_3(void) { Block_xx_3(4) ; }
+static INLINE void Block_4_4(void) { Block_xx_4(4) ; }
+static INLINE void Block_4_5(void) { Block_xx_5(4) ; }
+static INLINE void Block_4_6(word64 *W_X) { Block_xx_6(4) ; }
+static INLINE void Block_4_7(word64 *W_X) { Block_xx_7(6) ; }
+static INLINE void Block_4_8(word64 *W_X) { Block_xx_8(6) ; }
+static INLINE void Block_4_9(void) { Block_xx_9(6) ; }
+static INLINE void Block_4_10(void){ Block_xx_10(6) ; }
+static INLINE void Block_4_11(void){ Block_xx_11(6) ; }
+static INLINE void Block_4_12(word64 *W_X){ Block_xx_12(6) ; }
+
+static INLINE void Block_8_1(word64 *W_X) { Block_xx_1(8) ; }
+static INLINE void Block_8_2(word64 *W_X) { Block_xx_2(8) ; }
+static INLINE void Block_8_3(void) { Block_xx_3(8) ; }
+static INLINE void Block_8_4(void) { Block_xx_4(8) ; }
+static INLINE void Block_8_5(void) { Block_xx_5(8) ; }
+static INLINE void Block_8_6(word64 *W_X) { Block_xx_6(8) ; }
+static INLINE void Block_8_7(word64 *W_X) { Block_xx_7(10) ; }
+static INLINE void Block_8_8(word64 *W_X) { Block_xx_8(10) ; }
+static INLINE void Block_8_9(void) { Block_xx_9(10) ; }
+static INLINE void Block_8_10(void){ Block_xx_10(10) ; }
+static INLINE void Block_8_11(void){ Block_xx_11(10) ; }
+static INLINE void Block_8_12(word64 *W_X){ Block_xx_12(10) ; }
+
+static INLINE void Block_12_1(word64 *W_X) { Block_xx_1(12) ; }
+static INLINE void Block_12_2(word64 *W_X) { Block_xx_2(12) ; }
+static INLINE void Block_12_3(void) { Block_xx_3(12) ; }
+static INLINE void Block_12_4(void) { Block_xx_4(12) ; }
+static INLINE void Block_12_5(void) { Block_xx_5(12) ; }
+static INLINE void Block_12_6(word64 *W_X) { Block_xx_6(12) ; }
+static INLINE void Block_12_7(word64 *W_X) { Block_xx_7(14) ; }
+static INLINE void Block_12_8(word64 *W_X) { Block_xx_8(14) ; }
+static INLINE void Block_12_9(void) { Block_xx_9(14) ; }
+static INLINE void Block_12_10(void){ Block_xx_10(14) ; }
+static INLINE void Block_12_11(void){ Block_xx_11(14) ; }
+static INLINE void Block_12_12(word64 *W_X){ Block_xx_12(14) ; }
+
+#endif
+
+#if defined(HAVE_INTEL_AVX2)
+static const unsigned long mBYTE_FLIP_MASK_Y[] =
+   { 0x0001020304050607, 0x08090a0b0c0d0e0f, 0x0001020304050607, 0x08090a0b0c0d0e0f } ;
+
+#define W_from_buff_Y(buff)\
+    { /* X0..3(ymm9..12), W_X[0..15] = sha512->buffer[0.15];  */\
+     __asm__ volatile("vmovdqu %0, %%ymm8\n\t"::"m"(mBYTE_FLIP_MASK_Y[0]):YMM_REGs) ;\
+     __asm__ volatile("vmovdqu %0, %%ymm12\n\t"\
+                      "vmovdqu %1, %%ymm4\n\t"\
+                      "vpshufb %%ymm8, %%ymm12, %%ymm12\n\t"\
+                      "vpshufb %%ymm8, %%ymm4, %%ymm4\n\t"\
+                      :: "m"(buff[0]),  "m"(buff[4]):YMM_REGs) ;\
+     __asm__ volatile("vmovdqu %0, %%ymm5\n\t"\
+                      "vmovdqu %1, %%ymm6\n\t"\
+                      "vpshufb %%ymm8, %%ymm5, %%ymm5\n\t"\
+                      "vpshufb %%ymm8, %%ymm6, %%ymm6\n\t"\
+                      :: "m"(buff[8]),  "m"(buff[12]):YMM_REGs) ;\
+    }
+
+#if defined(DEBUG_YMM)
+
+#define SAVE_REG_Y(i) __asm__ volatile("vmovdqu %%ymm"#i", %0 \n\t":"=m"(reg[i-4][0])::YMM_REGs);
+#define RECV_REG_Y(i) __asm__ volatile("vmovdqu %0, %%ymm"#i" \n\t"::"m"(reg[i-4][0]):YMM_REGs);
+
+#define _DUMP_REG_Y(REG, name)\
+    { word64 buf[16] ;word64 reg[16][2];int k ;\
+      SAVE_REG_Y(4);  SAVE_REG_Y(5);   SAVE_REG_Y(6); SAVE_REG_Y(7); \
+      SAVE_REG_Y(8); SAVE_REG_Y(9); SAVE_REG_Y(10); SAVE_REG_Y(11); SAVE_REG_Y(12);\
+      SAVE_REG_Y(13); SAVE_REG_Y(14); SAVE_REG_Y(15); \
+      __asm__ volatile("vmovdqu %%"#REG", %0 \n\t":"=m"(buf[0])::YMM_REGs);\
+      printf(" "#name":\t") ; for(k=0; k<4; k++) printf("%016lx.", (word64)buf[k]) ; printf("\n") ; \
+      RECV_REG_Y(4);  RECV_REG_Y(5);   RECV_REG_Y(6); RECV_REG_Y(7); \
+      RECV_REG_Y(8); RECV_REG_Y(9); RECV_REG_Y(10); RECV_REG_Y(11); RECV_REG_Y(12); \
+      RECV_REG_Y(13); RECV_REG_Y(14); RECV_REG_Y(15);\
+    }
+
+#define DUMP_REG_Y(REG) _DUMP_REG_Y(REG, #REG) 
+#define DUMP_REG2_Y(REG) _DUMP_REG_Y(REG, #REG) 
+#define PRINTF_Y(fmt, ...) 
+
+#else
+
+#define DUMP_REG_Y(REG) 
+#define DUMP_REG2_Y(REG)
+#define PRINTF_Y(fmt, ...) 
+
+#endif
+
+#define _MOVE_to_REGy(ymm, mem)         __asm__ volatile("vmovdqu %0, %%"#ymm" "\
+                                        :: "m"(mem):YMM_REGs) ;
+#define _MOVE_to_MEMy(mem,i, ymm)       __asm__ volatile("vmovdqu %%"#ymm", %0" \
+        : "=m"(mem[i]),"=m"(mem[i+1]),"=m"(mem[i+2]),"=m"(mem[i+3])::YMM_REGs) ;
+#define _MOVE_128y(ymm0, ymm1, ymm2, map)  __asm__ volatile("vperm2i128  $"\
+        #map", %%"#ymm2", %%"#ymm1", %%"#ymm0" ":::YMM_REGs) ;
+#define _S_TEMPy(dest, src, bits, temp) \
+         __asm__ volatile("vpsrlq  $"#bits", %%"#src", %%"#dest"\n\tvpsllq  $64-"#bits\
+        ", %%"#src", %%"#temp"\n\tvpor %%"#temp",%%"#dest", %%"#dest" ":::YMM_REGs) ;
+#define _AVX2_R(dest, src, bits)        __asm__ volatile("vpsrlq  $"#bits", %%"\
+         #src", %%"#dest" ":::YMM_REGs) ;
+#define _XORy(dest, src1, src2)         __asm__ volatile("vpxor   %%"#src1", %%"\
+         #src2", %%"#dest" ":::YMM_REGs) ;
+#define _ADDy(dest, src1, src2)         __asm__ volatile("vpaddq   %%"#src1", %%"\
+         #src2", %%"#dest" ":::YMM_REGs) ;
+#define _BLENDy(map, dest, src1, src2)  __asm__ volatile("vpblendd    $"#map", %%"\
+         #src1",   %%"#src2", %%"#dest" ":::YMM_REGs) ;
+#define _BLENDQy(map, dest, src1, src2) __asm__ volatile("vblendpd   $"#map", %%"\
+         #src1",   %%"#src2", %%"#dest" ":::YMM_REGs) ;
+#define _PERMQy(map, dest, src)         __asm__ volatile("vpermq  $"#map", %%"\
+         #src", %%"#dest" ":::YMM_REGs) ;
+
+#define MOVE_to_REGy(ymm, mem)      _MOVE_to_REGy(ymm, mem)
+#define MOVE_to_MEMy(mem, i, ymm)   _MOVE_to_MEMy(mem, i, ymm)
+
+#define MOVE_128y(ymm0, ymm1, ymm2, map) _MOVE_128y(ymm0, ymm1, ymm2, map) 
+#define XORy(dest, src1, src2)      _XORy(dest, src1, src2)
+#define ADDy(dest, src1, src2)      _ADDy(dest, src1, src2)
+#define BLENDy(map, dest, src1, src2) _BLENDy(map, dest, src1, src2)
+#define BLENDQy(map, dest, src1, src2) _BLENDQy(map, dest, src1, src2)
+#define PERMQy(map, dest, src)      _PERMQy(map, dest, src)
+
+
+#define S_TMPy(dest, src, bits, temp) _S_TEMPy(dest, src, bits, temp);
+#define AVX2_S(dest, src, bits)      S_TMPy(dest, src, bits, S_TEMPy)
+#define AVX2_R(dest, src, bits)      _AVX2_R(dest, src, bits)
+
+
+#define    FEEDBACK1_to_W_I_2(w_i_2, w_i)    MOVE_128y(YMM_TEMP0, w_i, w_i, 0x08) ;\
+                                       BLENDy(0xf0, w_i_2, YMM_TEMP0, w_i_2) ; 
+
+#define    MOVE_W_to_W_I_15(w_i_15, w_0, w_4)  BLENDQy(0x1, w_i_15, w_4, w_0) ;\
+                                       PERMQy(0x39, w_i_15, w_i_15) ;
+#define    MOVE_W_to_W_I_7(w_i_7,  w_8, w_12)  BLENDQy(0x1, w_i_7, w_12, w_8) ;\
+                                       PERMQy(0x39, w_i_7, w_i_7) ; 
+#define    MOVE_W_to_W_I_2(w_i_2,  w_12)       BLENDQy(0xc, w_i_2, w_12, w_i_2) ;\
+                                       PERMQy(0x0e, w_i_2, w_i_2) ;
+
+
+#define W_I_16y  ymm8
+#define W_I_15y  ymm9
+#define W_I_7y  ymm10
+#define W_I_2y  ymm11
+#define W_Iy    ymm12
+#define G_TEMPy     ymm13
+#define S_TEMPy     ymm14
+#define YMM_TEMP0  ymm15
+#define YMM_TEMP0x xmm15
+#define W_I_TEMPy   ymm7
+#define W_K_TEMPy   ymm15
+#define W_K_TEMPx  xmm15
+#define W_0y     ymm12
+#define W_4y     ymm4
+#define W_8y     ymm5
+#define W_12y    ymm6
+
+#define YMM_REGs
+/* Registers are saved in Sha512Update/Final */
+                 /* "%ymm7","%ymm8","%ymm9","%ymm10","%ymm11","%ymm12","%ymm13","%ymm14","%ymm15"*/
+
+#define MOVE_15_to_16(w_i_16, w_i_15, w_i_7)\
+    __asm__ volatile("vperm2i128  $0x01, %%"#w_i_15", %%"#w_i_15", %%"#w_i_15" ":::YMM_REGs) ;\
+    __asm__ volatile("vpblendd    $0x08, %%"#w_i_15", %%"#w_i_7", %%"#w_i_16" ":::YMM_REGs) ;\
+    __asm__ volatile("vperm2i128 $0x01,  %%"#w_i_7",  %%"#w_i_7", %%"#w_i_15" ":::YMM_REGs) ;\
+    __asm__ volatile("vpblendd    $0x80, %%"#w_i_15", %%"#w_i_16", %%"#w_i_16" ":::YMM_REGs) ;\
+    __asm__ volatile("vpshufd    $0x93,  %%"#w_i_16", %%"#w_i_16" ":::YMM_REGs) ;\
+
+#define MOVE_7_to_15(w_i_15, w_i_7)\
+    __asm__ volatile("vmovdqu                 %%"#w_i_7",  %%"#w_i_15" ":::YMM_REGs) ;\
+
+#define MOVE_I_to_7(w_i_7, w_i)\
+    __asm__ volatile("vperm2i128 $0x01,       %%"#w_i",   %%"#w_i",   %%"#w_i_7" ":::YMM_REGs) ;\
+    __asm__ volatile("vpblendd    $0x01,       %%"#w_i_7",   %%"#w_i", %%"#w_i_7" ":::YMM_REGs) ;\
+    __asm__ volatile("vpshufd    $0x39, %%"#w_i_7", %%"#w_i_7" ":::YMM_REGs) ;\
+
+#define MOVE_I_to_2(w_i_2, w_i)\
+    __asm__ volatile("vperm2i128 $0x01,       %%"#w_i", %%"#w_i", %%"#w_i_2" ":::YMM_REGs) ;\
+    __asm__ volatile("vpshufd    $0x0e, %%"#w_i_2", %%"#w_i_2" ":::YMM_REGs) ;\
+
+#endif
+
+
+/***  Transform Body ***/
+#if defined(HAVE_INTEL_AVX1)
+
+static int Transform_AVX1(Sha512* sha512)
+{
+    const word64* K = K512;
+    word64 W_X[16+4];
+    word32 j;
+    word64 T[8];
+    /* Copy digest to working vars */
+    XMEMCPY(T, sha512->digest, sizeof(T));
+
+    W_from_buff(W_X, sha512->buffer) ;
+    for (j = 0; j < 80; j += 16) {
+        Rx_1( 0); Block_0_1(W_X); Rx_2( 0); Block_0_2(W_X); Rx_3( 0); Block_0_3(); 
+        Rx_1( 1); Block_0_4(); Rx_2( 1); Block_0_5(); Rx_3( 1); Block_0_6(W_X); 
+        Rx_1( 2); Block_0_7(W_X); Rx_2( 2); Block_0_8(W_X); Rx_3( 2); Block_0_9();
+        Rx_1( 3); Block_0_10();Rx_2( 3); Block_0_11();Rx_3( 3); Block_0_12(W_X);   
+        
+        Rx_1( 4); Block_4_1(W_X); Rx_2( 4); Block_4_2(W_X); Rx_3( 4); Block_4_3(); 
+        Rx_1( 5); Block_4_4(); Rx_2( 5); Block_4_5(); Rx_3( 5); Block_4_6(W_X); 
+        Rx_1( 6); Block_4_7(W_X); Rx_2( 6); Block_4_8(W_X); Rx_3( 6); Block_4_9();
+        Rx_1( 7); Block_4_10();Rx_2( 7); Block_4_11();Rx_3( 7); Block_4_12(W_X);   
+        
+        Rx_1( 8); Block_8_1(W_X); Rx_2( 8); Block_8_2(W_X); Rx_3( 8); Block_8_3(); 
+        Rx_1( 9); Block_8_4(); Rx_2( 9); Block_8_5(); Rx_3( 9); Block_8_6(W_X); 
+        Rx_1(10); Block_8_7(W_X); Rx_2(10); Block_8_8(W_X); Rx_3(10); Block_8_9();
+        Rx_1(11); Block_8_10();Rx_2(11); Block_8_11();Rx_3(11); Block_8_12(W_X);   
+        
+        Rx_1(12); Block_12_1(W_X); Rx_2(12); Block_12_2(W_X); Rx_3(12); Block_12_3(); 
+        Rx_1(13); Block_12_4(); Rx_2(13); Block_12_5(); Rx_3(13); Block_12_6(W_X); 
+        Rx_1(14); Block_12_7(W_X); Rx_2(14); Block_12_8(W_X); Rx_3(14); Block_12_9();
+        Rx_1(15); Block_12_10();Rx_2(15); Block_12_11();Rx_3(15); Block_12_12(W_X);     
+    }
+
+    /* Add the working vars back into digest */
+
+    sha512->digest[0] += a(0);
+    sha512->digest[1] += b(0);
+    sha512->digest[2] += c(0);
+    sha512->digest[3] += d(0);
+    sha512->digest[4] += e(0);
+    sha512->digest[5] += f(0);
+    sha512->digest[6] += g(0);
+    sha512->digest[7] += h(0);
+
+    /* Wipe variables */
+    #if !defined(HAVE_INTEL_AVX1)&&!defined(HAVE_INTEL_AVX2)
+    XMEMSET(W_X, 0, sizeof(word64) * 16);
+    #endif
+    XMEMSET(T, 0, sizeof(T));
+
+    return 0;
+}
+
+#endif
+
+#if defined(HAVE_INTEL_AVX2) && defined(HAVE_INTEL_AVX1) && defined(HAVE_INTEL_RORX)
+
+static int Transform_AVX1_RORX(Sha512* sha512)
+{
+    const word64* K = K512;
+    word64 W_X[16+4];
+    word32 j;
+    word64 T[8];
+    /* Copy digest to working vars */
+    XMEMCPY(T, sha512->digest, sizeof(T));
+
+    W_from_buff(W_X, sha512->buffer) ;
+    for (j = 0; j < 80; j += 16) {
+        Rx_RORX_1( 0); Block_0_1(W_X); Rx_RORX_2( 0); Block_0_2(W_X); 
+                                    Rx_RORX_3( 0); Block_0_3(); 
+        Rx_RORX_1( 1); Block_0_4(); Rx_RORX_2( 1); Block_0_5(); 
+                                    Rx_RORX_3( 1); Block_0_6(W_X); 
+        Rx_RORX_1( 2); Block_0_7(W_X); Rx_RORX_2( 2); Block_0_8(W_X); 
+                                    Rx_RORX_3( 2); Block_0_9();
+        Rx_RORX_1( 3); Block_0_10();Rx_RORX_2( 3); Block_0_11();
+                                    Rx_RORX_3( 3); Block_0_12(W_X);   
+        
+        Rx_RORX_1( 4); Block_4_1(W_X); Rx_RORX_2( 4); Block_4_2(W_X); 
+                                    Rx_RORX_3( 4); Block_4_3(); 
+        Rx_RORX_1( 5); Block_4_4(); Rx_RORX_2( 5); Block_4_5(); 
+                                    Rx_RORX_3( 5); Block_4_6(W_X); 
+        Rx_RORX_1( 6); Block_4_7(W_X); Rx_RORX_2( 6); Block_4_8(W_X); 
+                                    Rx_RORX_3( 6); Block_4_9();
+        Rx_RORX_1( 7); Block_4_10();Rx_RORX_2( 7); Block_4_11();
+                                    Rx_RORX_3( 7); Block_4_12(W_X);   
+        
+        Rx_RORX_1( 8); Block_8_1(W_X); Rx_RORX_2( 8); Block_8_2(W_X); 
+                                    Rx_RORX_3( 8); Block_8_3(); 
+        Rx_RORX_1( 9); Block_8_4(); Rx_RORX_2( 9); Block_8_5(); 
+                                    Rx_RORX_3( 9); Block_8_6(W_X); 
+        Rx_RORX_1(10); Block_8_7(W_X); Rx_RORX_2(10); Block_8_8(W_X); 
+                                    Rx_RORX_3(10); Block_8_9();
+        Rx_RORX_1(11); Block_8_10();Rx_RORX_2(11); Block_8_11();
+                                    Rx_RORX_3(11); Block_8_12(W_X);   
+        
+        Rx_RORX_1(12); Block_12_1(W_X); Rx_RORX_2(12); Block_12_2(W_X); 
+                                     Rx_RORX_3(12); Block_12_3(); 
+        Rx_RORX_1(13); Block_12_4(); Rx_RORX_2(13); Block_12_5(); 
+                                     Rx_RORX_3(13); Block_12_6(W_X); 
+        Rx_RORX_1(14); Block_12_7(W_X); Rx_RORX_2(14); Block_12_8(W_X); 
+                                     Rx_RORX_3(14); Block_12_9();
+        Rx_RORX_1(15); Block_12_10();Rx_RORX_2(15); Block_12_11();
+                                     Rx_RORX_3(15); Block_12_12(W_X);     
+    }
+    /* Add the working vars back into digest */
+
+    sha512->digest[0] += a(0);
+    sha512->digest[1] += b(0);
+    sha512->digest[2] += c(0);
+    sha512->digest[3] += d(0);
+    sha512->digest[4] += e(0);
+    sha512->digest[5] += f(0);
+    sha512->digest[6] += g(0);
+    sha512->digest[7] += h(0);
+
+    /* Wipe variables */
+    #if !defined(HAVE_INTEL_AVX1)&&!defined(HAVE_INTEL_AVX2)
+    XMEMSET(W_X, 0, sizeof(word64) * 16);
+    #endif
+    XMEMSET(T, 0, sizeof(T));
+
+    return 0;
+}
+#endif
+
+#if defined(HAVE_INTEL_AVX2)
+
+#define s0_1y(dest, src)      AVX2_S(dest, src, 1); 
+#define s0_2y(dest, src)      AVX2_S(G_TEMPy, src, 8); XORy(dest, G_TEMPy, dest) ; 
+#define s0_3y(dest, src)      AVX2_R(G_TEMPy, src, 7);  XORy(dest, G_TEMPy, dest) ;
+
+#define s1_1y(dest, src)      AVX2_S(dest, src, 19);
+#define s1_2y(dest, src)      AVX2_S(G_TEMPy, src, 61); XORy(dest, G_TEMPy, dest) ; 
+#define s1_3y(dest, src)      AVX2_R(G_TEMPy, src, 6); XORy(dest, G_TEMPy, dest) ;
+
+#define s0_y(dest, src)       s0_1y(dest, src) ; s0_2y(dest, src) ; s0_3y(dest, src)
+#define s1_y(dest, src)       s1_1y(dest, src) ; s1_2y(dest, src) ; s1_3y(dest, src)
+
+#define blk384(i) (W[i] = sha384->buffer[i])
+
+
+#define Block_Y_xx_1(i, w_0, w_4, w_8, w_12)\
+    MOVE_W_to_W_I_15(W_I_15y, w_0, w_4) ;\
+    MOVE_W_to_W_I_7 (W_I_7y,  w_8, w_12) ;\
+    MOVE_W_to_W_I_2 (W_I_2y,  w_12) ;\
+
+#define Block_Y_xx_2(i, w_0, w_4, w_8, w_12)\
+    s0_1y (YMM_TEMP0, W_I_15y) ;\
+
+#define Block_Y_xx_3(i, w_0, w_4, w_8, w_12)\
+    s0_2y (YMM_TEMP0, W_I_15y) ;\
+
+#define Block_Y_xx_4(i, w_0, w_4, w_8, w_12)\
+    s0_3y (YMM_TEMP0, W_I_15y) ;\
+
+#define Block_Y_xx_5(i, w_0, w_4, w_8, w_12)\
+    ADDy(W_I_TEMPy, w_0, YMM_TEMP0) ;\
+
+#define Block_Y_xx_6(i, w_0, w_4, w_8, w_12)\
+    ADDy(W_I_TEMPy, W_I_TEMPy, W_I_7y) ;\
+    s1_1y (YMM_TEMP0, W_I_2y) ;\
+
+#define Block_Y_xx_7(i, w_0, w_4, w_8, w_12)\
+    s1_2y (YMM_TEMP0, W_I_2y) ;\
+
+#define Block_Y_xx_8(i, w_0, w_4, w_8, w_12)\
+    s1_3y (YMM_TEMP0, W_I_2y) ;\
+    ADDy(w_0, W_I_TEMPy, YMM_TEMP0) ;\
+
+#define Block_Y_xx_9(i, w_0, w_4, w_8, w_12)\
+    FEEDBACK1_to_W_I_2(W_I_2y, w_0) ;\
+
+#define Block_Y_xx_10(i, w_0, w_4, w_8, w_12) \
+    s1_1y (YMM_TEMP0, W_I_2y) ;\
+
+#define Block_Y_xx_11(i, w_0, w_4, w_8, w_12) \
+    s1_2y (YMM_TEMP0, W_I_2y) ;\
+
+#define Block_Y_xx_12(i, w_0, w_4, w_8, w_12)\
+    s1_3y (YMM_TEMP0, W_I_2y) ;\
+    ADDy(w_0, W_I_TEMPy, YMM_TEMP0) ;\
+    MOVE_to_MEMy(w,0, w_4) ;\
+
+
+static INLINE void Block_Y_0_1(void) { Block_Y_xx_1(0, W_0y, W_4y, W_8y, W_12y) ; }
+static INLINE void Block_Y_0_2(void) { Block_Y_xx_2(0, W_0y, W_4y, W_8y, W_12y) ; }
+static INLINE void Block_Y_0_3(void) { Block_Y_xx_3(0, W_0y, W_4y, W_8y, W_12y) ; }
+static INLINE void Block_Y_0_4(void) { Block_Y_xx_4(0, W_0y, W_4y, W_8y, W_12y) ; }
+static INLINE void Block_Y_0_5(void) { Block_Y_xx_5(0, W_0y, W_4y, W_8y, W_12y) ; }
+static INLINE void Block_Y_0_6(void) { Block_Y_xx_6(0, W_0y, W_4y, W_8y, W_12y) ; }
+static INLINE void Block_Y_0_7(void) { Block_Y_xx_7(0, W_0y, W_4y, W_8y, W_12y) ; }
+static INLINE void Block_Y_0_8(void) { Block_Y_xx_8(0, W_0y, W_4y, W_8y, W_12y) ; }
+static INLINE void Block_Y_0_9(void) { Block_Y_xx_9(0, W_0y, W_4y, W_8y, W_12y) ; }
+static INLINE void Block_Y_0_10(void){ Block_Y_xx_10(0, W_0y, W_4y, W_8y, W_12y) ; }
+static INLINE void Block_Y_0_11(void){ Block_Y_xx_11(0, W_0y, W_4y, W_8y, W_12y) ; }
+static INLINE void Block_Y_0_12(word64 *w){ Block_Y_xx_12(0, W_0y, W_4y, W_8y, W_12y) ; }
+
+static INLINE void Block_Y_4_1(void) { Block_Y_xx_1(4, W_4y, W_8y, W_12y, W_0y) ; }
+static INLINE void Block_Y_4_2(void) { Block_Y_xx_2(4, W_4y, W_8y, W_12y, W_0y) ; }
+static INLINE void Block_Y_4_3(void) { Block_Y_xx_3(4, W_4y, W_8y, W_12y, W_0y) ; }
+static INLINE void Block_Y_4_4(void) { Block_Y_xx_4(4, W_4y, W_8y, W_12y, W_0y) ; }
+static INLINE void Block_Y_4_5(void) { Block_Y_xx_5(4, W_4y, W_8y, W_12y, W_0y) ; }
+static INLINE void Block_Y_4_6(void) { Block_Y_xx_6(4, W_4y, W_8y, W_12y, W_0y) ; }
+static INLINE void Block_Y_4_7(void) { Block_Y_xx_7(4, W_4y, W_8y, W_12y, W_0y) ; }
+static INLINE void Block_Y_4_8(void) { Block_Y_xx_8(4, W_4y, W_8y, W_12y, W_0y) ; }
+static INLINE void Block_Y_4_9(void) { Block_Y_xx_9(4, W_4y, W_8y, W_12y, W_0y) ; }
+static INLINE void Block_Y_4_10(void) { Block_Y_xx_10(4, W_4y, W_8y, W_12y, W_0y) ; }
+static INLINE void Block_Y_4_11(void) { Block_Y_xx_11(4, W_4y, W_8y, W_12y, W_0y) ; }
+static INLINE void Block_Y_4_12(word64 *w) { Block_Y_xx_12(4, W_4y, W_8y, W_12y, W_0y) ; }
+
+static INLINE void Block_Y_8_1(void) { Block_Y_xx_1(8, W_8y, W_12y, W_0y, W_4y) ; }
+static INLINE void Block_Y_8_2(void) { Block_Y_xx_2(8, W_8y, W_12y, W_0y, W_4y) ; }
+static INLINE void Block_Y_8_3(void) { Block_Y_xx_3(8, W_8y, W_12y, W_0y, W_4y) ; }
+static INLINE void Block_Y_8_4(void) { Block_Y_xx_4(8, W_8y, W_12y, W_0y, W_4y) ; }
+static INLINE void Block_Y_8_5(void) { Block_Y_xx_5(8, W_8y, W_12y, W_0y, W_4y) ; }
+static INLINE void Block_Y_8_6(void) { Block_Y_xx_6(8, W_8y, W_12y, W_0y, W_4y) ; }
+static INLINE void Block_Y_8_7(void) { Block_Y_xx_7(8, W_8y, W_12y, W_0y, W_4y) ; }
+static INLINE void Block_Y_8_8(void) { Block_Y_xx_8(8, W_8y, W_12y, W_0y, W_4y) ; }
+static INLINE void Block_Y_8_9(void) { Block_Y_xx_9(8, W_8y, W_12y, W_0y, W_4y) ; }
+static INLINE void Block_Y_8_10(void) { Block_Y_xx_10(8, W_8y, W_12y, W_0y, W_4y) ; }
+static INLINE void Block_Y_8_11(void) { Block_Y_xx_11(8, W_8y, W_12y, W_0y, W_4y) ; }
+static INLINE void Block_Y_8_12(word64 *w) { Block_Y_xx_12(8, W_8y, W_12y, W_0y, W_4y) ; }
+
+static INLINE void Block_Y_12_1(void) { Block_Y_xx_1(12, W_12y, W_0y, W_4y, W_8y) ; }
+static INLINE void Block_Y_12_2(void) { Block_Y_xx_2(12, W_12y, W_0y, W_4y, W_8y) ; }
+static INLINE void Block_Y_12_3(void) { Block_Y_xx_3(12, W_12y, W_0y, W_4y, W_8y) ; }
+static INLINE void Block_Y_12_4(void) { Block_Y_xx_4(12, W_12y, W_0y, W_4y, W_8y) ; }
+static INLINE void Block_Y_12_5(void) { Block_Y_xx_5(12, W_12y, W_0y, W_4y, W_8y) ; }
+static INLINE void Block_Y_12_6(void) { Block_Y_xx_6(12, W_12y, W_0y, W_4y, W_8y) ; }
+static INLINE void Block_Y_12_7(void) { Block_Y_xx_7(12, W_12y, W_0y, W_4y, W_8y) ; }
+static INLINE void Block_Y_12_8(void) { Block_Y_xx_8(12, W_12y, W_0y, W_4y, W_8y) ; }
+static INLINE void Block_Y_12_9(void) { Block_Y_xx_9(12, W_12y, W_0y, W_4y, W_8y) ; }
+static INLINE void Block_Y_12_10(void) { Block_Y_xx_10(12, W_12y, W_0y, W_4y, W_8y) ; }
+static INLINE void Block_Y_12_11(void) { Block_Y_xx_11(12, W_12y, W_0y, W_4y, W_8y) ; }
+static INLINE void Block_Y_12_12(word64 *w) { Block_Y_xx_12(12, W_12y, W_0y, W_4y, W_8y) ; }
+
+
+static int Transform_AVX2(Sha512* sha512)
+{
+    const word64* K = K512;
+    word64 w[4] ;
+    word32 j /*, k*/;
+    word64 T[8];
+    /* Copy digest to working vars */
+    XMEMCPY(T, sha512->digest, sizeof(T));
+
+    W_from_buff_Y(sha512->buffer) ;
+    MOVE_to_MEMy(w,0, W_0y) ; 
+    for (j = 0; j < 80; j += 16) {
+        Ry_1( 0, w[0]); Block_Y_0_1(); Ry_2( 0, w[0]); Block_Y_0_2(); 
+                                       Ry_3( 0, w[0]); Block_Y_0_3(); 
+        Ry_1( 1, w[1]); Block_Y_0_4(); Ry_2( 1, w[1]); Block_Y_0_5(); 
+                                       Ry_3( 1, w[1]); Block_Y_0_6();  
+        Ry_1( 2, w[2]); Block_Y_0_7(); Ry_2( 2, w[2]); Block_Y_0_8(); 
+                                       Ry_3( 2, w[2]); Block_Y_0_9();
+        Ry_1( 3, w[3]); Block_Y_0_10();Ry_2( 3, w[3]); Block_Y_0_11();
+                                       Ry_3( 3, w[3]); Block_Y_0_12(w);
+        
+        Ry_1( 4, w[0]); Block_Y_4_1(); Ry_2( 4, w[0]); Block_Y_4_2(); 
+                                       Ry_3( 4, w[0]); Block_Y_4_3(); 
+        Ry_1( 5, w[1]); Block_Y_4_4(); Ry_2( 5, w[1]); Block_Y_4_5(); 
+                                       Ry_3( 5, w[1]); Block_Y_4_6();
+        Ry_1( 6, w[2]); Block_Y_4_7(); Ry_2( 6, w[2]); Block_Y_4_8(); 
+                                       Ry_3( 6, w[2]); Block_Y_4_9();
+        Ry_1( 7, w[3]); Block_Y_4_10(); Ry_2( 7, w[3]);Block_Y_4_11(); 
+                                        Ry_3( 7, w[3]);Block_Y_4_12(w);  
+        
+        Ry_1( 8, w[0]); Block_Y_8_1(); Ry_2( 8, w[0]); Block_Y_8_2(); 
+                                       Ry_3( 8, w[0]); Block_Y_8_3();
+        Ry_1( 9, w[1]); Block_Y_8_4(); Ry_2( 9, w[1]); Block_Y_8_5(); 
+                                       Ry_3( 9, w[1]); Block_Y_8_6();
+        Ry_1(10, w[2]); Block_Y_8_7(); Ry_2(10, w[2]); Block_Y_8_8(); 
+                                       Ry_3(10, w[2]); Block_Y_8_9(); 
+        Ry_1(11, w[3]); Block_Y_8_10();Ry_2(11, w[3]); Block_Y_8_11();
+                                       Ry_3(11, w[3]); Block_Y_8_12(w);
+                 
+        Ry_1(12, w[0]); Block_Y_12_1(); Ry_2(12, w[0]); Block_Y_12_2(); 
+                                        Ry_3(12, w[0]); Block_Y_12_3();
+        Ry_1(13, w[1]); Block_Y_12_4(); Ry_2(13, w[1]); Block_Y_12_5(); 
+                                        Ry_3(13, w[1]); Block_Y_12_6(); 
+        Ry_1(14, w[2]); Block_Y_12_7(); Ry_2(14, w[2]); Block_Y_12_8(); 
+                                        Ry_3(14, w[2]); Block_Y_12_9();
+        Ry_1(15, w[3]); Block_Y_12_10();Ry_2(15, w[3]); Block_Y_12_11();
+                                        Ry_3(15, w[3]);Block_Y_12_12(w);
+    }
+ 
+    /* Add the working vars back into digest */
+
+    sha512->digest[0] += a(0);
+    sha512->digest[1] += b(0);
+    sha512->digest[2] += c(0);
+    sha512->digest[3] += d(0);
+    sha512->digest[4] += e(0);
+    sha512->digest[5] += f(0);
+    sha512->digest[6] += g(0);
+    sha512->digest[7] += h(0);
+
+    /* Wipe variables */
+    #if !defined(HAVE_INTEL_AVX1)&&!defined(HAVE_INTEL_AVX2)
+    XMEMSET(W, 0, sizeof(word64) * 16);
+    #endif
+    XMEMSET(T, 0, sizeof(T));
+
+    return 0;
+}
+
+#endif
+
+
+#ifdef WOLFSSL_SHA384
+
+#if defined(HAVE_INTEL_AVX1) ||  defined(HAVE_INTEL_AVX2) 
+
+#if defined(HAVE_INTEL_AVX1)
+static int Transform384_AVX1(Sha384 *sha384) ;
+#endif
+#if defined(HAVE_INTEL_AVX2)
+static int Transform384_AVX2(Sha384 *sha384) ; 
+#endif
+
+#if defined(HAVE_INTEL_AVX1) &&  defined(HAVE_INTEL_AVX2) &&defined(HAVE_INTEL_RORX)
+static int Transform384_AVX1_RORX(Sha384 *sha384) ; 
+#endif
+
+static int _Transform384(Sha384 *sha384) ; 
+static int (*Transform384_p)(Sha384* sha384) = _Transform384 ;
+
+#define Transform384(sha384) (*Transform384_p)(sha384)
+static void set_Transform384(void) {
+     if(set_cpuid_flags(CHECK_SHA384))return ;
+
+#if defined(HAVE_INTEL_AVX1) && !defined(HAVE_INTEL_AVX2)
+     Transform384_p = ((IS_INTEL_AVX1) ? Transform384_AVX1 : _Transform384) ;
+#elif defined(HAVE_INTEL_AVX2)
+     #if defined(HAVE_INTEL_AVX1) && defined(HAVE_INTEL_RORX)
+     if(IS_INTEL_AVX2 && IS_INTEL_BMI2) { Transform384_p = Transform384_AVX1_RORX ; return ; }
+     #endif
+     if(IS_INTEL_AVX2) { Transform384_p = Transform384_AVX2 ; return ; }
+     #if defined(HAVE_INTEL_AVX1)
+     Transform384_p = ((IS_INTEL_AVX1) ? Transform384_AVX1 : _Transform384) ;
+     #endif
+#else
+     Transform384_p = ((IS_INTEL_AVX1) ? Transform384_AVX1 : _Transform384) ;
+#endif
+}
+
+#else
+   #define Transform384(sha512) _Transform384(sha512)
+#endif
+
+int wc_InitSha384(Sha384* sha384)
+{
+    sha384->digest[0] = W64LIT(0xcbbb9d5dc1059ed8);
+    sha384->digest[1] = W64LIT(0x629a292a367cd507);
+    sha384->digest[2] = W64LIT(0x9159015a3070dd17);
+    sha384->digest[3] = W64LIT(0x152fecd8f70e5939);
+    sha384->digest[4] = W64LIT(0x67332667ffc00b31);
+    sha384->digest[5] = W64LIT(0x8eb44a8768581511);
+    sha384->digest[6] = W64LIT(0xdb0c2e0d64f98fa7);
+    sha384->digest[7] = W64LIT(0x47b5481dbefa4fa4);
+
+    sha384->buffLen = 0;
+    sha384->loLen   = 0;
+    sha384->hiLen   = 0;
+
+#if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
+    set_Transform384() ;
+#endif
+    
+    return 0;
+}
+
+static int _Transform384(Sha384* sha384)
+{
+    const word64* K = K512;
+
+    word32 j;
+    word64 T[8];
+
+#ifdef WOLFSSL_SMALL_STACK
+    word64* W;
+
+    W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (W == NULL)
+        return MEMORY_E;
+#else
+    word64 W[16];
+#endif
+
+    /* Copy digest to working vars */
+    XMEMCPY(T, sha384->digest, sizeof(T));
+
+#ifdef USE_SLOW_SHA2
+    /* over twice as small, but 50% slower */
+    /* 80 operations, not unrolled */
+    for (j = 0; j < 80; j += 16) {
+        int m;
+        for (m = 0; m < 16; m++) {  /* braces needed for macros {} */
+            R2(m);
+        }
+    }
+#else
+    /* 80 operations, partially loop unrolled */
+    for (j = 0; j < 80; j += 16) {
+        R2( 0); R2( 1); R2( 2); R2( 3);
+        R2( 4); R2( 5); R2( 6); R2( 7);
+        R2( 8); R2( 9); R2(10); R2(11);
+        R2(12); R2(13); R2(14); R2(15);
+    }
+#endif /* USE_SLOW_SHA2 */
+
+    /* Add the working vars back into digest */
+
+    sha384->digest[0] += a(0);
+    sha384->digest[1] += b(0);
+    sha384->digest[2] += c(0);
+    sha384->digest[3] += d(0);
+    sha384->digest[4] += e(0);
+    sha384->digest[5] += f(0);
+    sha384->digest[6] += g(0);
+    sha384->digest[7] += h(0);
+
+    /* Wipe variables */
+    XMEMSET(W, 0, sizeof(word64) * 16);
+    XMEMSET(T, 0, sizeof(T));
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return 0;
+}
+
+static INLINE void AddLength384(Sha384* sha384, word32 len)
+{
+    word32 tmp = sha384->loLen;
+    if ( (sha384->loLen += len) < tmp)
+        sha384->hiLen++;                       /* carry low to high */
+}
+
+int wc_Sha384Update(Sha384* sha384, const byte* data, word32 len)
+{
+    /* do block size increments */
+    byte* local = (byte*)sha384->buffer;
+	
+    SAVE_XMM_YMM ; /* for Intel AVX */
+    
+    while (len) {
+        word32 add = min(len, SHA384_BLOCK_SIZE - sha384->buffLen);
+        XMEMCPY(&local[sha384->buffLen], data, add);
+
+        sha384->buffLen += add;
+        data         += add;
+        len          -= add;
+
+        if (sha384->buffLen == SHA384_BLOCK_SIZE) {
+            int ret;
+
+            #if defined(LITTLE_ENDIAN_ORDER)
+                #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+                if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2) 
+                #endif
+                    ByteReverseWords64(sha384->buffer, sha384->buffer,
+                                   SHA384_BLOCK_SIZE);
+            #endif
+            ret = Transform384(sha384);
+            if (ret != 0)
+                return ret;
+
+            AddLength384(sha384, SHA384_BLOCK_SIZE);
+            sha384->buffLen = 0;
+        }
+    }
+    return 0;
+}
+
+
+int wc_Sha384Final(Sha384* sha384, byte* hash)
+{
+    byte* local = (byte*)sha384->buffer;
+    int ret;
+
+    SAVE_XMM_YMM ; /* for Intel AVX */
+    AddLength384(sha384, sha384->buffLen);              /* before adding pads */
+
+    local[sha384->buffLen++] = 0x80;  /* add 1 */
+
+    /* pad with zeros */
+    if (sha384->buffLen > SHA384_PAD_SIZE) {
+        XMEMSET(&local[sha384->buffLen], 0, SHA384_BLOCK_SIZE -sha384->buffLen);
+        sha384->buffLen += SHA384_BLOCK_SIZE - sha384->buffLen;
+
+        #if defined(LITTLE_ENDIAN_ORDER)
+            #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+            if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2) 
+            #endif
+                 ByteReverseWords64(sha384->buffer, sha384->buffer,
+                               SHA384_BLOCK_SIZE);
+        #endif
+        ret = Transform384(sha384);
+        if (ret !=  0)
+            return ret;
+
+        sha384->buffLen = 0;
+    }
+    XMEMSET(&local[sha384->buffLen], 0, SHA384_PAD_SIZE - sha384->buffLen);
+   
+    /* put lengths in bits */
+    sha384->hiLen = (sha384->loLen >> (8*sizeof(sha384->loLen) - 3)) + 
+                 (sha384->hiLen << 3);
+    sha384->loLen = sha384->loLen << 3;
+
+    /* store lengths */
+    #if defined(LITTLE_ENDIAN_ORDER)
+        #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+        if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2) 
+        #endif
+             ByteReverseWords64(sha384->buffer, sha384->buffer,
+                           SHA384_BLOCK_SIZE);
+    #endif
+    /* ! length ordering dependent on digest endian type ! */
+    sha384->buffer[SHA384_BLOCK_SIZE / sizeof(word64) - 2] = sha384->hiLen;
+    sha384->buffer[SHA384_BLOCK_SIZE / sizeof(word64) - 1] = sha384->loLen;
+    #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+    if(IS_INTEL_AVX1 || IS_INTEL_AVX2)
+        ByteReverseWords64(&(sha384->buffer[SHA384_BLOCK_SIZE / sizeof(word64) - 2]),
+                           &(sha384->buffer[SHA384_BLOCK_SIZE / sizeof(word64) - 2]),
+                           SHA384_BLOCK_SIZE - SHA384_PAD_SIZE);
+    #endif
+    ret = Transform384(sha384);
+    if (ret != 0)
+        return ret;
+
+    #ifdef LITTLE_ENDIAN_ORDER
+        ByteReverseWords64(sha384->digest, sha384->digest, SHA384_DIGEST_SIZE);
+    #endif
+    XMEMCPY(hash, sha384->digest, SHA384_DIGEST_SIZE);
+
+    return wc_InitSha384(sha384);  /* reset state */
+}
+
+
+
+#if defined(HAVE_INTEL_AVX1)
+ 
+static int Transform384_AVX1(Sha384* sha384)
+{
+    const word64* K = K512;
+    word64 W_X[16+4];
+    word32 j;
+    word64 T[8];
+
+    /* Copy digest to working vars */
+    XMEMCPY(T, sha384->digest, sizeof(T));
+    W_from_buff(W_X, sha384->buffer) ;
+    for (j = 0; j < 80; j += 16) {
+        Rx_1( 0); Block_0_1(W_X); Rx_2( 0); Block_0_2(W_X); Rx_3( 0); Block_0_3(); 
+        Rx_1( 1); Block_0_4(); Rx_2( 1); Block_0_5(); Rx_3( 1); Block_0_6(W_X); 
+        Rx_1( 2); Block_0_7(W_X); Rx_2( 2); Block_0_8(W_X); Rx_3( 2); Block_0_9();
+        Rx_1( 3); Block_0_10();Rx_2( 3); Block_0_11();Rx_3( 3); Block_0_12(W_X);   
+        
+        Rx_1( 4); Block_4_1(W_X); Rx_2( 4); Block_4_2(W_X); Rx_3( 4); Block_4_3(); 
+        Rx_1( 5); Block_4_4(); Rx_2( 5); Block_4_5(); Rx_3( 5); Block_4_6(W_X); 
+        Rx_1( 6); Block_4_7(W_X); Rx_2( 6); Block_4_8(W_X); Rx_3( 6); Block_4_9();
+        Rx_1( 7); Block_4_10();Rx_2( 7); Block_4_11();Rx_3( 7); Block_4_12(W_X);   
+        
+        Rx_1( 8); Block_8_1(W_X); Rx_2( 8); Block_8_2(W_X); Rx_3( 8); Block_8_3(); 
+        Rx_1( 9); Block_8_4(); Rx_2( 9); Block_8_5(); Rx_3( 9); Block_8_6(W_X); 
+        Rx_1(10); Block_8_7(W_X); Rx_2(10); Block_8_8(W_X); Rx_3(10); Block_8_9();
+        Rx_1(11); Block_8_10();Rx_2(11); Block_8_11();Rx_3(11); Block_8_12(W_X);   
+        
+        Rx_1(12); Block_12_1(W_X); Rx_2(12); Block_12_2(W_X); Rx_3(12); Block_12_3(); 
+        Rx_1(13); Block_12_4(); Rx_2(13); Block_12_5(); Rx_3(13); Block_12_6(W_X); 
+        Rx_1(14); Block_12_7(W_X); Rx_2(14); Block_12_8(W_X); Rx_3(14); Block_12_9();
+        Rx_1(15); Block_12_10();Rx_2(15); Block_12_11();Rx_3(15); Block_12_12(W_X);     
+    }
+
+    /* Add the working vars back into digest */
+
+    sha384->digest[0] += a(0);
+    sha384->digest[1] += b(0);
+    sha384->digest[2] += c(0);
+    sha384->digest[3] += d(0);
+    sha384->digest[4] += e(0);
+    sha384->digest[5] += f(0);
+    sha384->digest[6] += g(0);
+    sha384->digest[7] += h(0);
+
+    /* Wipe variables */
+    #if !defined(HAVE_INTEL_AVX1)&&!defined(HAVE_INTEL_AVX2)
+    XMEMSET(W, 0, sizeof(word64) * 16);
+    #endif
+    XMEMSET(T, 0, sizeof(T));
+
+    return 0;
+}
+
+#endif
+
+#if defined(HAVE_INTEL_AVX1) && defined(HAVE_INTEL_AVX2) && defined(HAVE_INTEL_RORX)
+static int Transform384_AVX1_RORX(Sha384* sha384)
+{
+    const word64* K = K512;
+    word64 W_X[16+4];
+    word32 j;
+    word64 T[8];
+
+    /* Copy digest to working vars */
+    XMEMCPY(T, sha384->digest, sizeof(T));
+
+    W_from_buff(W_X, sha384->buffer) ;
+    for (j = 0; j < 80; j += 16) {
+        Rx_RORX_1( 0); Block_0_1(W_X); Rx_RORX_2( 0); 
+            Block_0_2(W_X); Rx_RORX_3( 0); Block_0_3(); 
+        Rx_RORX_1( 1); Block_0_4(); Rx_RORX_2( 1); 
+            Block_0_5(); Rx_RORX_3( 1); Block_0_6(W_X); 
+        Rx_RORX_1( 2); Block_0_7(W_X); Rx_RORX_2( 2); 
+            Block_0_8(W_X); Rx_RORX_3( 2); Block_0_9();
+        Rx_RORX_1( 3); Block_0_10();Rx_RORX_2( 3); 
+            Block_0_11();Rx_RORX_3( 3); Block_0_12(W_X);   
+        
+        Rx_RORX_1( 4); Block_4_1(W_X); Rx_RORX_2( 4); 
+            Block_4_2(W_X); Rx_RORX_3( 4); Block_4_3(); 
+        Rx_RORX_1( 5); Block_4_4(); Rx_RORX_2( 5); 
+            Block_4_5(); Rx_RORX_3( 5); Block_4_6(W_X); 
+        Rx_RORX_1( 6); Block_4_7(W_X); Rx_RORX_2( 6); 
+            Block_4_8(W_X); Rx_RORX_3( 6); Block_4_9();
+        Rx_RORX_1( 7); Block_4_10();Rx_RORX_2( 7); 
+            Block_4_11();Rx_RORX_3( 7); Block_4_12(W_X);   
+        
+        Rx_RORX_1( 8); Block_8_1(W_X); Rx_RORX_2( 8); 
+            Block_8_2(W_X); Rx_RORX_3( 8); Block_8_3(); 
+        Rx_RORX_1( 9); Block_8_4(); Rx_RORX_2( 9); 
+            Block_8_5(); Rx_RORX_3( 9); Block_8_6(W_X); 
+        Rx_RORX_1(10); Block_8_7(W_X); Rx_RORX_2(10); 
+            Block_8_8(W_X); Rx_RORX_3(10); Block_8_9();
+        Rx_RORX_1(11); Block_8_10();Rx_RORX_2(11); 
+            Block_8_11();Rx_RORX_3(11); Block_8_12(W_X);   
+        
+        Rx_RORX_1(12); Block_12_1(W_X); Rx_RORX_2(12);
+            Block_12_2(W_X); Rx_RORX_3(12); Block_12_3(); 
+        Rx_RORX_1(13); Block_12_4(); Rx_RORX_2(13); 
+            Block_12_5(); Rx_RORX_3(13); Block_12_6(W_X); 
+        Rx_RORX_1(14); Block_12_7(W_X); Rx_RORX_2(14); 
+            Block_12_8(W_X); Rx_RORX_3(14); Block_12_9();
+        Rx_RORX_1(15); Block_12_10();Rx_RORX_2(15); 
+            Block_12_11();Rx_RORX_3(15); Block_12_12(W_X);     
+    }
+
+    /* Add the working vars back into digest */
+
+    sha384->digest[0] += a(0);
+    sha384->digest[1] += b(0);
+    sha384->digest[2] += c(0);
+    sha384->digest[3] += d(0);
+    sha384->digest[4] += e(0);
+    sha384->digest[5] += f(0);
+    sha384->digest[6] += g(0);
+    sha384->digest[7] += h(0);
+
+    /* Wipe variables */
+    #if !defined(HAVE_INTEL_AVX1)&&!defined(HAVE_INTEL_AVX2)
+    XMEMSET(W, 0, sizeof(word64) * 16);
+    #endif
+    XMEMSET(T, 0, sizeof(T));
+
+    return 0;
+}
+#endif
+
+#if defined(HAVE_INTEL_AVX2)
+
+static int Transform384_AVX2(Sha384* sha384)
+{
+    const word64* K = K512;
+    word64 w[4] ;
+    word32 j;
+    word64 T[8];
+
+    /* Copy digest to working vars */
+    XMEMCPY(T, sha384->digest, sizeof(T));
+
+    /* over twice as small, but 50% slower */
+    /* 80 operations, not unrolled */
+
+    W_from_buff_Y(sha384->buffer) ;
+
+    MOVE_to_MEMy(w,0, W_0y) ;
+    for (j = 0; j < 80; j += 16) {
+        Ry_1( 0, w[0]); Block_Y_0_1(); Ry_2( 0, w[0]); 
+            Block_Y_0_2(); Ry_3( 0, w[0]); Block_Y_0_3(); 
+        Ry_1( 1, w[1]); Block_Y_0_4(); Ry_2( 1, w[1]); 
+            Block_Y_0_5(); Ry_3( 1, w[1]); Block_Y_0_6();  
+        Ry_1( 2, w[2]); Block_Y_0_7(); Ry_2( 2, w[2]); 
+            Block_Y_0_8(); Ry_3( 2, w[2]); Block_Y_0_9();
+        Ry_1( 3, w[3]); Block_Y_0_10();Ry_2( 3, w[3]); 
+            Block_Y_0_11();Ry_3( 3, w[3]); Block_Y_0_12(w);
+        
+        Ry_1( 4, w[0]); Block_Y_4_1(); Ry_2( 4, w[0]); 
+            Block_Y_4_2(); Ry_3( 4, w[0]); Block_Y_4_3(); 
+        Ry_1( 5, w[1]); Block_Y_4_4(); Ry_2( 5, w[1]);   
+            Block_Y_4_5(); Ry_3( 5, w[1]); Block_Y_4_6();
+        Ry_1( 6, w[2]); Block_Y_4_7(); Ry_2( 6, w[2]); 
+            Block_Y_4_8(); Ry_3( 6, w[2]); Block_Y_4_9();
+        Ry_1( 7, w[3]); Block_Y_4_10(); Ry_2( 7, w[3]);
+            Block_Y_4_11(); Ry_3( 7, w[3]);Block_Y_4_12(w);  
+        
+        Ry_1( 8, w[0]); Block_Y_8_1(); Ry_2( 8, w[0]); 
+            Block_Y_8_2(); Ry_3( 8, w[0]); Block_Y_8_3();
+        Ry_1( 9, w[1]); Block_Y_8_4(); Ry_2( 9, w[1]);
+            Block_Y_8_5(); Ry_3( 9, w[1]); Block_Y_8_6();
+        Ry_1(10, w[2]); Block_Y_8_7(); Ry_2(10, w[2]); 
+            Block_Y_8_8(); Ry_3(10, w[2]); Block_Y_8_9(); 
+        Ry_1(11, w[3]); Block_Y_8_10();Ry_2(11, w[3]); 
+           Block_Y_8_11();Ry_3(11, w[3]); Block_Y_8_12(w);
+                 
+        Ry_1(12, w[0]); Block_Y_12_1(); Ry_2(12, w[0]); 
+            Block_Y_12_2(); Ry_3(12, w[0]); Block_Y_12_3();
+        Ry_1(13, w[1]); Block_Y_12_4(); Ry_2(13, w[1]); 
+            Block_Y_12_5(); Ry_3(13, w[1]); Block_Y_12_6(); 
+        Ry_1(14, w[2]); Block_Y_12_7(); Ry_2(14, w[2]); 
+            Block_Y_12_8(); Ry_3(14, w[2]); Block_Y_12_9();
+        Ry_1(15, w[3]); Block_Y_12_10();Ry_2(15, w[3]); 
+            Block_Y_12_11();Ry_3(15, w[3]); Block_Y_12_12(w);
+    }
+
+    /* Add the working vars back into digest */
+
+    sha384->digest[0] += a(0);
+    sha384->digest[1] += b(0);
+    sha384->digest[2] += c(0);
+    sha384->digest[3] += d(0);
+    sha384->digest[4] += e(0);
+    sha384->digest[5] += f(0);
+    sha384->digest[6] += g(0);
+    sha384->digest[7] += h(0);
+
+    /* Wipe variables */
+    XMEMSET(T, 0, sizeof(T));
+
+    return 0;
+}
+
+#endif
+
+#endif /* WOLFSSL_SHA384 */
+
+#endif /* HAVE_FIPS */
+
+#endif /* WOLFSSL_SHA512 */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/wc_encrypt.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/wc_encrypt.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/wc_encrypt.c	(revision 164)
@@ -0,0 +1,201 @@
+/* wc_encrypt.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+#include <wolfssl/wolfcrypt/aes.h>
+#include <wolfssl/wolfcrypt/des3.h>
+#include <wolfssl/wolfcrypt/wc_encrypt.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+
+
+#ifndef NO_AES
+int wc_AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz,
+                                  const byte* key, word32 keySz, const byte* iv)
+{
+    int  ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    Aes* aes = NULL;
+#else
+    Aes  aes[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (aes == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);
+    if (ret == 0)
+        ret = wc_AesCbcDecrypt(aes, out, in, inSz);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(aes, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+int wc_AesCbcEncryptWithKey(byte* out, const byte* in, word32 inSz,
+                            const byte* key, word32 keySz, const byte* iv)
+{
+    int  ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    Aes* aes = NULL;
+#else
+    Aes  aes[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (aes == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION);
+    if (ret == 0)
+        ret = wc_AesCbcEncrypt(aes, out, in, inSz);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(aes, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+#endif /* !NO_AES */
+
+
+#ifndef NO_DES3
+int wc_Des_CbcEncryptWithKey(byte* out, const byte* in, word32 sz,
+                             const byte* key, const byte* iv)
+{
+    int ret  = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    Des* des = NULL;
+#else
+    Des  des[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    des = (Des*)XMALLOC(sizeof(Des), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (des == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = wc_Des_SetKey(des, key, iv, DES_ENCRYPTION);
+    if (ret == 0)
+        ret = wc_Des_CbcEncrypt(des, out, in, sz);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(des, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+int wc_Des_CbcDecryptWithKey(byte* out, const byte* in, word32 sz,
+                             const byte* key, const byte* iv)
+{
+    int ret  = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    Des* des = NULL;
+#else
+    Des  des[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    des = (Des*)XMALLOC(sizeof(Des), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (des == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = wc_Des_SetKey(des, key, iv, DES_DECRYPTION);
+    if (ret == 0)
+        ret = wc_Des_CbcDecrypt(des, out, in, sz);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(des, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+int wc_Des3_CbcEncryptWithKey(byte* out, const byte* in, word32 sz,
+                              const byte* key, const byte* iv)
+{
+    int ret    = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    Des3* des3 = NULL;
+#else
+    Des3  des3[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    des3 = (Des3*)XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (des3 == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = wc_Des3_SetKey(des3, key, iv, DES_ENCRYPTION);
+    if (ret == 0)
+        ret = wc_Des3_CbcEncrypt(des3, out, in, sz);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(des3, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+
+int wc_Des3_CbcDecryptWithKey(byte* out, const byte* in, word32 sz,
+                              const byte* key, const byte* iv)
+{
+    int ret    = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    Des3* des3 = NULL;
+#else
+    Des3  des3[1];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    des3 = (Des3*)XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (des3 == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = wc_Des3_SetKey(des3, key, iv, DES_DECRYPTION);
+    if (ret == 0)
+        ret = wc_Des3_CbcDecrypt(des3, out, in, sz);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(des3, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
+}
+
+#endif /* !NO_DES3 */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/wc_port.c
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/wc_port.c	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/wc_port.c	(revision 164)
@@ -0,0 +1,769 @@
+/* port.c
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+#include <wolfssl/wolfcrypt/types.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+
+/* IPP header files for library initialization */
+#ifdef HAVE_FAST_RSA
+#include <ipp.h>
+#include <ippcp.h>
+#endif
+
+#ifdef _MSC_VER
+    /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
+    #pragma warning(disable: 4996)
+#endif
+
+
+/* Used to initialize state for wolfcrypt
+   return 0 on success
+ */
+int wolfcrypt_Init()
+{
+    /* if defined have fast RSA then initialize Intel IPP */
+    #ifdef HAVE_FAST_RSA
+        WOLFSSL_MSG("Setting up IPP Library");
+        if (ippInit() != ippStsNoErr) {
+            WOLFSSL_MSG("Error setting up optimized Intel library to use!");
+            return -1;
+        }
+    #endif
+
+    return 0;
+}
+
+
+#if WOLFSSL_CRYPT_HW_MUTEX
+/* Mutex for protection of cryptograpghy hardware */
+static wolfSSL_Mutex wcCryptHwMutex;
+static int wcCryptHwMutexInit = 0;
+
+int wolfSSL_CryptHwMutexInit(void) {
+    int ret = 0;
+    if(wcCryptHwMutexInit == 0) {
+        ret = InitMutex(&wcCryptHwMutex);
+        if(ret == 0) {
+            wcCryptHwMutexInit = 1;
+        }
+    }
+    return ret;
+}
+
+int wolfSSL_CryptHwMutexLock(void) {
+    int ret = BAD_MUTEX_E;
+
+    /* Make sure HW Mutex has been initialized */
+    wolfSSL_CryptHwMutexInit();
+
+    if(wcCryptHwMutexInit) {
+        ret = LockMutex(&wcCryptHwMutex);
+    }
+    return ret;
+}
+
+int wolfSSL_CryptHwMutexUnLock(void) {
+    int ret = BAD_MUTEX_E;
+    
+    if(wcCryptHwMutexInit) {
+        ret = UnLockMutex(&wcCryptHwMutex);
+    }
+    return ret;
+}
+#endif /* WOLFSSL_CRYPT_HW_MUTEX */
+
+
+#ifdef SINGLE_THREADED
+
+int InitMutex(wolfSSL_Mutex* m)
+{
+    (void)m;
+    return 0;
+}
+
+
+int FreeMutex(wolfSSL_Mutex *m)
+{
+    (void)m;
+    return 0;
+}
+
+
+int LockMutex(wolfSSL_Mutex *m)
+{
+    (void)m;
+    return 0;
+}
+
+
+int UnLockMutex(wolfSSL_Mutex *m)
+{
+    (void)m;
+    return 0;
+}
+
+#else /* MULTI_THREAD */
+
+    #if defined(FREERTOS)  || defined(FREERTOS_TCP)
+
+        int InitMutex(wolfSSL_Mutex* m)
+        {
+            int iReturn;
+
+            *m = ( wolfSSL_Mutex ) xSemaphoreCreateMutex();
+            if( *m != NULL )
+                iReturn = 0;
+            else
+                iReturn = BAD_MUTEX_E;
+
+            return iReturn;
+        }
+
+        int FreeMutex(wolfSSL_Mutex* m)
+        {
+            vSemaphoreDelete( *m );
+            return 0;
+        }
+
+        int LockMutex(wolfSSL_Mutex* m)
+        {
+            /* Assume an infinite block, or should there be zero block? */
+            xSemaphoreTake( *m, portMAX_DELAY );
+            return 0;
+        }
+
+        int UnLockMutex(wolfSSL_Mutex* m)
+        {
+            xSemaphoreGive( *m );
+            return 0;
+        }
+
+    #elif defined(WOLFSSL_SAFERTOS)
+
+        int InitMutex(wolfSSL_Mutex* m)
+        {
+            vSemaphoreCreateBinary(m->mutexBuffer, m->mutex);
+            if (m->mutex == NULL)
+                return BAD_MUTEX_E;
+
+            return 0;
+        }
+
+        int FreeMutex(wolfSSL_Mutex* m)
+        {
+            (void)m;
+            return 0;
+        }
+
+        int LockMutex(wolfSSL_Mutex* m)
+        {
+            /* Assume an infinite block */
+            xSemaphoreTake(m->mutex, portMAX_DELAY);
+            return 0;
+        }
+
+        int UnLockMutex(wolfSSL_Mutex* m)
+        {
+            xSemaphoreGive(m->mutex);
+            return 0;
+        }
+
+
+    #elif defined(USE_WINDOWS_API)
+
+        int InitMutex(wolfSSL_Mutex* m)
+        {
+            InitializeCriticalSection(m);
+            return 0;
+        }
+
+
+        int FreeMutex(wolfSSL_Mutex* m)
+        {
+            DeleteCriticalSection(m);
+            return 0;
+        }
+
+
+        int LockMutex(wolfSSL_Mutex* m)
+        {
+            EnterCriticalSection(m);
+            return 0;
+        }
+
+
+        int UnLockMutex(wolfSSL_Mutex* m)
+        {
+            LeaveCriticalSection(m);
+            return 0;
+        }
+
+    #elif defined(WOLFSSL_PTHREADS)
+
+        int InitMutex(wolfSSL_Mutex* m)
+        {
+            if (pthread_mutex_init(m, 0) == 0)
+                return 0;
+            else
+                return BAD_MUTEX_E;
+        }
+
+
+        int FreeMutex(wolfSSL_Mutex* m)
+        {
+            if (pthread_mutex_destroy(m) == 0)
+                return 0;
+            else
+                return BAD_MUTEX_E;
+        }
+
+
+        int LockMutex(wolfSSL_Mutex* m)
+        {
+            if (pthread_mutex_lock(m) == 0)
+                return 0;
+            else
+                return BAD_MUTEX_E;
+        }
+
+
+        int UnLockMutex(wolfSSL_Mutex* m)
+        {
+            if (pthread_mutex_unlock(m) == 0)
+                return 0;
+            else
+                return BAD_MUTEX_E;
+        }
+
+    #elif defined(THREADX)
+
+        int InitMutex(wolfSSL_Mutex* m)
+        {
+            if (tx_mutex_create(m, "wolfSSL Mutex", TX_NO_INHERIT) == 0)
+                return 0;
+            else
+                return BAD_MUTEX_E;
+        }
+
+
+        int FreeMutex(wolfSSL_Mutex* m)
+        {
+            if (tx_mutex_delete(m) == 0)
+                return 0;
+            else
+                return BAD_MUTEX_E;
+        }
+
+
+        int LockMutex(wolfSSL_Mutex* m)
+        {
+            if (tx_mutex_get(m, TX_WAIT_FOREVER) == 0)
+                return 0;
+            else
+                return BAD_MUTEX_E;
+        }
+
+
+        int UnLockMutex(wolfSSL_Mutex* m)
+        {
+            if (tx_mutex_put(m) == 0)
+                return 0;
+            else
+                return BAD_MUTEX_E;
+        }
+
+    #elif defined(MICRIUM)
+
+        int InitMutex(wolfSSL_Mutex* m)
+        {
+            #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
+                if (NetSecure_OS_MutexCreate(m) == 0)
+                    return 0;
+                else
+                    return BAD_MUTEX_E;
+            #else
+                return 0;
+            #endif
+        }
+
+
+        int FreeMutex(wolfSSL_Mutex* m)
+        {
+            #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
+                if (NetSecure_OS_FreeMutex(m) == 0)
+                    return 0;
+                else
+                    return BAD_MUTEX_E;
+            #else
+                return 0;
+            #endif
+        }
+
+
+        int LockMutex(wolfSSL_Mutex* m)
+        {
+            #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
+                if (NetSecure_OS_LockMutex(m) == 0)
+                    return 0;
+                else
+                    return BAD_MUTEX_E;
+            #else
+                return 0;
+            #endif
+        }
+
+
+        int UnLockMutex(wolfSSL_Mutex* m)
+        {
+            #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
+                if (NetSecure_OS_UnLockMutex(m) == 0)
+                    return 0;
+                else
+                    return BAD_MUTEX_E;
+            #else
+                return 0;
+            #endif
+
+        }
+
+    #elif defined(EBSNET)
+
+        int InitMutex(wolfSSL_Mutex* m)
+        {
+            if (rtp_sig_mutex_alloc(m, "wolfSSL Mutex") == -1)
+                return BAD_MUTEX_E;
+            else
+                return 0;
+        }
+
+        int FreeMutex(wolfSSL_Mutex* m)
+        {
+            rtp_sig_mutex_free(*m);
+            return 0;
+        }
+
+        int LockMutex(wolfSSL_Mutex* m)
+        {
+            if (rtp_sig_mutex_claim_timed(*m, RTIP_INF) == 0)
+                return 0;
+            else
+                return BAD_MUTEX_E;
+        }
+
+        int UnLockMutex(wolfSSL_Mutex* m)
+        {
+            rtp_sig_mutex_release(*m);
+            return 0;
+        }
+
+    #elif defined(FREESCALE_MQX)
+
+        int InitMutex(wolfSSL_Mutex* m)
+        {
+            if (_mutex_init(m, NULL) == MQX_EOK)
+                return 0;
+            else
+                return BAD_MUTEX_E;
+        }
+
+        int FreeMutex(wolfSSL_Mutex* m)
+        {
+            if (_mutex_destroy(m) == MQX_EOK)
+                return 0;
+            else
+                return BAD_MUTEX_E;
+        }
+
+        int LockMutex(wolfSSL_Mutex* m)
+        {
+            if (_mutex_lock(m) == MQX_EOK)
+                return 0;
+            else
+                return BAD_MUTEX_E;
+        }
+
+        int UnLockMutex(wolfSSL_Mutex* m)
+        {
+            if (_mutex_unlock(m) == MQX_EOK)
+                return 0;
+            else
+                return BAD_MUTEX_E;
+        }
+
+    #elif defined (WOLFSSL_TIRTOS)
+        #include <xdc/runtime/Error.h>
+        int InitMutex(wolfSSL_Mutex* m)
+        {
+           Semaphore_Params params;
+           Error_Block eb;
+           Error_init(&eb);
+           Semaphore_Params_init(&params);
+           params.mode = Semaphore_Mode_BINARY;
+
+           *m = Semaphore_create(1, &params, &eb);
+           if( Error_check( &eb )  )
+           {
+               Error_raise( &eb, Error_E_generic, "Failed to Create the semaphore.",NULL);
+           } else return 0;
+        }
+
+        int FreeMutex(wolfSSL_Mutex* m)
+        {
+            Semaphore_delete(m);
+
+            return 0;
+        }
+
+        int LockMutex(wolfSSL_Mutex* m)
+        {
+            Semaphore_pend(*m, BIOS_WAIT_FOREVER);
+
+            return 0;
+        }
+
+        int UnLockMutex(wolfSSL_Mutex* m)
+        {
+            Semaphore_post(*m);
+
+            return 0;
+        }
+
+    #elif defined(WOLFSSL_LWIP)
+
+        int InitMutex(wolfSSL_Mutex* m)
+        {
+            err_t err;
+            err = sys_mutex_new(m);
+            return (err == ERR_OK) ? 0 : -1;
+        }
+
+        int FreeMutex(wolfSSL_Mutex* m)
+        {
+            sys_mutex_free(m);
+            return 0;
+        }
+
+        int LockMutex(wolfSSL_Mutex* m)
+        {
+            sys_mutex_lock(m);
+            return 0;
+        }
+
+        int UnLockMutex(wolfSSL_Mutex* m)
+        {
+            sys_mutex_unlock(m);
+            return 0;
+        }
+
+        int uITRON4_minit(size_t poolsz)
+        {
+            return 0;
+        }
+
+        void *uITRON4_malloc(size_t sz)
+        {
+            return sys_malloc(sz);
+        }
+
+        void *uITRON4_realloc(void *p, size_t sz)
+        {
+            return sys_realloc(p, sz);
+        }
+
+        void uITRON4_free(void *p)
+        {
+            sys_free(p);
+        }
+
+    #elif defined(WOLFSSL_uITRON4)
+        #include "stddef.h"
+        #include "kernel.h"
+        int InitMutex(wolfSSL_Mutex* m)
+        {
+            int iReturn;
+            m->sem.sematr  = TA_TFIFO ;
+            m->sem.isemcnt = 1 ;
+            m->sem.maxsem  = 1 ;
+            m->sem.name    = NULL ;
+
+            m->id = acre_sem(&m->sem);
+            if( m->id != E_OK )
+                iReturn = 0;
+            else
+                iReturn = BAD_MUTEX_E;
+
+            return iReturn;
+        }
+
+        int FreeMutex(wolfSSL_Mutex* m)
+        {
+            del_sem( m->id );
+            return 0;
+        }
+
+        int LockMutex(wolfSSL_Mutex* m)
+        {
+            wai_sem(m->id);
+            return 0;
+        }
+
+        int UnLockMutex(wolfSSL_Mutex* m)
+        {
+            sig_sem(m->id);
+            return 0;
+        }
+
+        /****  uITRON malloc/free ***/
+        static ID ID_wolfssl_MPOOL = 0 ;
+        static T_CMPL wolfssl_MPOOL = {TA_TFIFO, 0, NULL, "wolfSSL_MPOOL"};
+
+        int uITRON4_minit(size_t poolsz) {
+            ER ercd;
+            wolfssl_MPOOL.mplsz = poolsz ;
+            ercd = acre_mpl(&wolfssl_MPOOL);
+            if (ercd > 0) {
+                ID_wolfssl_MPOOL = ercd;
+                return 0;
+            } else {
+                return -1;
+            }
+        }
+
+        void *uITRON4_malloc(size_t sz) {
+            ER ercd;
+            void *p ;
+            ercd = get_mpl(ID_wolfssl_MPOOL, sz, (VP)&p);
+            if (ercd == E_OK) {
+                return p;
+            } else {
+                return 0 ;
+            }
+        }
+
+        void *uITRON4_realloc(void *p, size_t sz) {
+          ER ercd;
+          void *newp ;
+          if(p) {
+              ercd = get_mpl(ID_wolfssl_MPOOL, sz, (VP)&newp);
+              if (ercd == E_OK) {
+                  XMEMCPY(newp, p, sz) ;
+                  ercd = rel_mpl(ID_wolfssl_MPOOL, (VP)p);
+                  if (ercd == E_OK) {
+                      return newp;
+                  }
+              }
+          }
+          return 0 ;
+        }
+
+        void uITRON4_free(void *p) {
+            ER ercd;
+            ercd = rel_mpl(ID_wolfssl_MPOOL, (VP)p);
+            if (ercd == E_OK) {
+                return ;
+            } else {
+                return ;
+            }
+        }
+
+#elif defined(WOLFSSL_uTKERNEL2)
+        #include "tk/tkernel.h"
+        int InitMutex(wolfSSL_Mutex* m)
+        {
+            int iReturn;
+            m->sem.sematr  = TA_TFIFO ;
+            m->sem.isemcnt = 1 ;
+            m->sem.maxsem  = 1 ;
+
+            m->id = tk_cre_sem(&m->sem);
+            if( m->id != NULL )
+                iReturn = 0;
+            else
+                iReturn = BAD_MUTEX_E;
+
+            return iReturn;
+        }
+
+        int FreeMutex(wolfSSL_Mutex* m)
+        {
+            tk_del_sem( m->id );
+            return 0;
+        }
+
+        int LockMutex(wolfSSL_Mutex* m)
+        {
+            tk_wai_sem(m->id, 1, TMO_FEVR);
+            return 0;
+        }
+
+        int UnLockMutex(wolfSSL_Mutex* m)
+        {
+            tk_sig_sem(m->id, 1);
+            return 0;
+        }
+
+        /****  uT-Kernel malloc/free ***/
+        static ID ID_wolfssl_MPOOL = 0 ;
+        static T_CMPL wolfssl_MPOOL =
+                     {(void *)NULL,
+        TA_TFIFO , 0,   "wolfSSL_MPOOL"};
+
+        int uTKernel_init_mpool(unsigned int sz) {
+            ER ercd;
+            wolfssl_MPOOL.mplsz = sz ;
+            ercd = tk_cre_mpl(&wolfssl_MPOOL);
+            if (ercd > 0) {
+                ID_wolfssl_MPOOL = ercd;
+                return 0;
+            } else {
+                return -1;
+            }
+        }
+
+        void *uTKernel_malloc(unsigned int sz) {
+            ER ercd;
+            void *p ;
+            ercd = tk_get_mpl(ID_wolfssl_MPOOL, sz, (VP)&p, TMO_FEVR);
+            if (ercd == E_OK) {
+                return p;
+            } else {
+                return 0 ;
+            }
+        }
+
+        void *uTKernel_realloc(void *p, unsigned int sz) {
+          ER ercd;
+          void *newp ;
+          if(p) {
+              ercd = tk_get_mpl(ID_wolfssl_MPOOL, sz, (VP)&newp, TMO_FEVR);
+              if (ercd == E_OK) {
+                  XMEMCPY(newp, p, sz) ;
+                  ercd = tk_rel_mpl(ID_wolfssl_MPOOL, (VP)p);
+                  if (ercd == E_OK) {
+                      return newp;
+                  }
+              }
+          }
+          return 0 ;
+        }
+
+        void uTKernel_free(void *p) {
+            ER ercd;
+            ercd = tk_rel_mpl(ID_wolfssl_MPOOL, (VP)p);
+            if (ercd == E_OK) {
+                return ;
+            } else {
+                return ;
+            }
+        }
+
+    #elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_CMSIS_RTOS)
+    
+        #if defined(WOLFSSL_CMSIS_RTOS)
+            #include "cmsis_os.h"
+            #define CMSIS_NMUTEX 10
+            osMutexDef(wolfSSL_mt0) ;  osMutexDef(wolfSSL_mt1) ;  osMutexDef(wolfSSL_mt2) ;
+            osMutexDef(wolfSSL_mt3) ;  osMutexDef(wolfSSL_mt4) ;  osMutexDef(wolfSSL_mt5) ;  
+            osMutexDef(wolfSSL_mt6) ;  osMutexDef(wolfSSL_mt7) ;  osMutexDef(wolfSSL_mt8) ;  
+            osMutexDef(wolfSSL_mt9) ;  
+            
+            static const osMutexDef_t *CMSIS_mutex[] = { osMutex(wolfSSL_mt0),   
+                osMutex(wolfSSL_mt1),    osMutex(wolfSSL_mt2),   osMutex(wolfSSL_mt3),    
+                osMutex(wolfSSL_mt4),    osMutex(wolfSSL_mt5),   osMutex(wolfSSL_mt6),
+                osMutex(wolfSSL_mt7),    osMutex(wolfSSL_mt8),    osMutex(wolfSSL_mt9) } ;                 
+            
+            static osMutexId CMSIS_mutexID[CMSIS_NMUTEX] = {0} ;
+
+            int InitMutex(wolfSSL_Mutex* m)
+            {
+                int i ;
+                for (i=0; i<CMSIS_NMUTEX; i++) {
+                    if(CMSIS_mutexID[i] == 0) {
+                        CMSIS_mutexID[i] = osMutexCreate(CMSIS_mutex[i]) ;
+                        (*m) = CMSIS_mutexID[i] ;
+                    return 0 ;
+                    }
+                }
+                return -1 ;
+            }
+
+            int FreeMutex(wolfSSL_Mutex* m)
+            {
+                int i ;
+                osMutexDelete   (*m) ;
+                for (i=0; i<CMSIS_NMUTEX; i++) {
+                    if(CMSIS_mutexID[i] == (*m)) {
+                        CMSIS_mutexID[i] = 0 ;
+                        return(0) ;
+                    }
+                }
+                return(-1) ;
+            }
+            
+            int LockMutex(wolfSSL_Mutex* m)
+            {
+                osMutexWait(*m, osWaitForever) ;
+                return(0) ;
+            }
+
+            int UnLockMutex(wolfSSL_Mutex* m)
+            {
+                osMutexRelease (*m);
+                return 0;
+            }
+        #else
+        int InitMutex(wolfSSL_Mutex* m)
+        {
+            os_mut_init (m); 
+            return 0;
+        }
+
+        int FreeMutex(wolfSSL_Mutex* m)
+        {
+            return(0) ;
+        }
+
+        int LockMutex(wolfSSL_Mutex* m)
+        {
+            os_mut_wait (m, 0xffff);
+            return(0) ;
+        }
+
+        int UnLockMutex(wolfSSL_Mutex* m)
+        {
+            os_mut_release (m);
+            return 0;
+        }
+        #endif
+    #endif /* USE_WINDOWS_API */
+
+#endif /* SINGLE_THREADED */
+        
+#if defined(WOLFSSL_TI_CRYPT) ||  defined(WOLFSSL_TI_HASH)
+    #include <wolfcrypt/src/port/ti/ti-ccm.c>  /* initialize and Mutex for TI Crypt Engine */
+    #include <wolfcrypt/src/port/ti/ti-hash.c> /* md5, sha1, sha224, sha256 */
+#endif
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/random.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/random.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/random.h	(revision 164)
@@ -0,0 +1,38 @@
+/* random.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef CTAO_CRYPT_RANDOM_H
+#define CTAO_CRYPT_RANDOM_H
+
+    /* for random.h compatibility */
+    #include <wolfssl/wolfcrypt/random.h>
+    #define InitRng           wc_InitRng
+    #define RNG_GenerateBlock wc_RNG_GenerateBlock
+    #define RNG_GenerateByte  wc_RNG_GenerateByte
+    #define FreeRng        wc_FreeRng
+
+	#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
+	    #define RNG_HealthTest wc_RNG_HealthTest
+	#endif /* HAVE_HASHDRBG || NO_RC4 */
+
+#endif /* CTAO_CRYPT_RANDOM_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/settings.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/settings.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/settings.h	(revision 164)
@@ -0,0 +1,745 @@
+/* settings.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Place OS specific preprocessor flags, defines, includes here, will be
+   included into every file because types.h includes it */
+
+
+#ifndef CTAO_CRYPT_SETTINGS_H
+#define CTAO_CRYPT_SETTINGS_H
+
+/* for reverse compatibility after name change */
+#include <cyassl/ctaocrypt/settings_comp.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+/* Uncomment next line if using IPHONE */
+/* #define IPHONE */
+
+/* Uncomment next line if using ThreadX */
+/* #define THREADX */
+
+/* Uncomment next line if using Micrium ucOS */
+/* #define MICRIUM */
+
+/* Uncomment next line if using Mbed */
+/* #define MBED */
+
+/* Uncomment next line if using Microchip PIC32 ethernet starter kit */
+/* #define MICROCHIP_PIC32 */
+
+/* Uncomment next line if using Microchip TCP/IP stack, version 5 */
+/* #define MICROCHIP_TCPIP_V5 */
+
+/* Uncomment next line if using Microchip TCP/IP stack, version 6 or later */
+/* #define MICROCHIP_TCPIP */
+
+/* Uncomment next line if using PIC32MZ Crypto Engine */
+/* #define CYASSL_MICROCHIP_PIC32MZ */
+        
+/* Uncomment next line if using FreeRTOS */
+/* #define FREERTOS */
+
+/* Uncomment next line if using FreeRTOS Windows Simulator */
+/* #define FREERTOS_WINSIM */
+
+/* Uncomment next line if using RTIP */
+/* #define EBSNET */
+
+/* Uncomment next line if using lwip */
+/* #define CYASSL_LWIP */
+
+/* Uncomment next line if building CyaSSL for a game console */
+/* #define CYASSL_GAME_BUILD */
+
+/* Uncomment next line if building CyaSSL for LSR */
+/* #define CYASSL_LSR */
+
+/* Uncomment next line if building CyaSSL for Freescale MQX/RTCS/MFS */
+/* #define FREESCALE_MQX */
+
+/* Uncomment next line if using STM32F2 */
+/* #define CYASSL_STM32F2 */
+
+/* Uncomment next line if using Comverge settings */
+/* #define COMVERGE */
+
+/* Uncomment next line if using QL SEP settings */
+/* #define CYASSL_QL */
+
+/* Uncomment next line if building for EROAD */
+/* #define CYASSL_EROAD */
+      
+/* Uncomment next line if building for IAR EWARM */
+/* #define CYASSL_IAR_ARM */
+
+/* Uncomment next line if using TI-RTOS settings */
+/* #define CYASSL_TIRTOS */
+
+/* Uncomment next line if building with PicoTCP */
+/* #define CYASSL_PICOTCP */
+
+/* Uncomment next line if building for PicoTCP demo bundle */
+/* #define CYASSL_PICOTCP_DEMO */
+
+#include <cyassl/ctaocrypt/visibility.h>
+
+#ifdef IPHONE
+    #define SIZEOF_LONG_LONG 8
+#endif
+
+
+#ifdef CYASSL_USER_SETTINGS
+    #include <user_settings.h>
+#endif
+
+
+#ifdef COMVERGE
+    #define THREADX
+    #define HAVE_NETX
+    #define CYASSL_USER_IO
+    #define NO_WRITEV
+    #define NO_DEV_RANDOM
+    #define NO_FILESYSTEM
+    #define NO_SHA512
+    #define NO_DH
+    #define NO_DSA
+    #define NO_HC128
+    #define NO_RSA
+    #define NO_SESSION_CACHE
+    #define HAVE_ECC 
+#endif
+
+
+#ifdef THREADX 
+    #define SIZEOF_LONG_LONG 8
+#endif
+
+#ifdef HAVE_NETX
+    #include "nx_api.h"
+#endif
+
+#if defined(HAVE_LWIP_NATIVE) /* using LwIP native TCP socket */
+    #define CYASSL_LWIP
+    #define NO_WRITEV
+    #define SINGLE_THREADED
+    #define CYASSL_USER_IO
+    #define NO_FILESYSTEM
+#endif 
+    
+#if defined(CYASSL_IAR_ARM)
+    #define NO_MAIN_DRIVER
+    #define SINGLE_THREADED
+    #define USE_CERT_BUFFERS_1024
+    #define BENCH_EMBEDDED
+    #define NO_FILESYSTEM
+    #define NO_WRITEV
+    #define CYASSL_USER_IO
+    #define  BENCH_EMBEDDED
+#endif
+      
+#ifdef MICROCHIP_PIC32
+    /* #define CYASSL_MICROCHIP_PIC32MZ */
+    #define SIZEOF_LONG_LONG 8
+    #define SINGLE_THREADED
+    #define CYASSL_USER_IO
+    #define NO_WRITEV
+    #define NO_DEV_RANDOM
+    #define NO_FILESYSTEM
+    #define USE_FAST_MATH
+    #define TFM_TIMING_RESISTANT
+#endif
+
+#ifdef CYASSL_MICROCHIP_PIC32MZ
+    #define CYASSL_PIC32MZ_CE
+    #define CYASSL_PIC32MZ_CRYPT
+    #define HAVE_AES_ENGINE
+    #define CYASSL_PIC32MZ_RNG
+    /* #define CYASSL_PIC32MZ_HASH */
+    #define CYASSL_AES_COUNTER
+    #define HAVE_AESGCM
+    #define NO_BIG_INT
+
+#endif
+
+#ifdef MICROCHIP_TCPIP_V5
+    /* include timer functions */
+    #include "TCPIP Stack/TCPIP.h"
+#endif
+
+#ifdef MICROCHIP_TCPIP
+    /* include timer, NTP functions */
+    #ifdef MICROCHIP_MPLAB_HARMONY
+        #include "tcpip/tcpip.h"
+    #else
+        #include "system/system_services.h"
+        #include "tcpip/sntp.h"
+    #endif
+#endif
+
+#ifdef MBED
+    #define CYASSL_USER_IO
+    #define NO_FILESYSTEM
+    #define NO_CERT
+    #define USE_CERT_BUFFERS_1024
+    #define NO_WRITEV
+    #define NO_DEV_RANDOM
+    #define NO_SHA512
+    #define NO_DH
+    #define NO_DSA
+    #define NO_HC128
+    #define HAVE_ECC
+    #define NO_SESSION_CACHE
+    #define CYASSL_CMSIS_RTOS
+#endif
+
+
+#ifdef CYASSL_EROAD
+    #define FREESCALE_MQX
+    #define FREESCALE_MMCAU
+    #define SINGLE_THREADED
+    #define NO_STDIO_FILESYSTEM
+    #define CYASSL_LEANPSK
+    #define HAVE_NULL_CIPHER
+    #define NO_OLD_TLS
+    #define NO_ASN
+    #define NO_BIG_INT
+    #define NO_RSA
+    #define NO_DSA
+    #define NO_DH
+    #define NO_CERTS
+    #define NO_PWDBASED
+    #define NO_DES3
+    #define NO_MD4
+    #define NO_RC4
+    #define NO_MD5
+    #define NO_SESSION_CACHE
+    #define NO_MAIN_DRIVER
+#endif
+
+#ifdef CYASSL_PICOTCP
+    #define errno pico_err
+    #include "pico_defines.h"
+    #include "pico_stack.h"
+    #include "pico_constants.h"
+    #define CUSTOM_RAND_GENERATE pico_rand
+#endif
+
+#ifdef CYASSL_PICOTCP_DEMO
+    #define CYASSL_STM32
+    #define USE_FAST_MATH
+    #define TFM_TIMING_RESISTANT
+    #define XMALLOC(s, h, type)  PICO_ZALLOC((s))
+    #define XFREE(p, h, type)    PICO_FREE((p))
+    #define SINGLE_THREADED
+    #define NO_WRITEV
+    #define CYASSL_USER_IO
+    #define NO_DEV_RANDOM
+    #define NO_FILESYSTEM
+#endif
+
+#ifdef FREERTOS_WINSIM
+    #define FREERTOS
+    #define USE_WINDOWS_API
+#endif
+
+
+/* Micrium will use Visual Studio for compilation but not the Win32 API */
+#if defined(_WIN32) && !defined(MICRIUM) && !defined(FREERTOS) \
+        && !defined(EBSNET) && !defined(CYASSL_EROAD)
+    #define USE_WINDOWS_API
+#endif
+
+
+#if defined(CYASSL_LEANPSK) && !defined(XMALLOC_USER)
+    #include <stdlib.h>
+    #define XMALLOC(s, h, type)  malloc((s))
+    #define XFREE(p, h, type)    free((p)) 
+    #define XREALLOC(p, n, h, t) realloc((p), (n))
+#endif
+
+#if defined(XMALLOC_USER) && defined(SSN_BUILDING_LIBYASSL)
+    #undef  XMALLOC
+    #define XMALLOC     yaXMALLOC
+    #undef  XFREE
+    #define XFREE       yaXFREE
+    #undef  XREALLOC
+    #define XREALLOC    yaXREALLOC
+#endif
+
+
+#ifdef FREERTOS
+    #ifndef NO_WRITEV
+        #define NO_WRITEV
+    #endif
+    #ifndef NO_SHA512
+        #define NO_SHA512
+    #endif
+    #ifndef NO_DH
+        #define NO_DH
+    #endif
+    #ifndef NO_DSA
+        #define NO_DSA
+    #endif
+    #ifndef NO_HC128
+        #define NO_HC128
+    #endif
+
+    #ifndef SINGLE_THREADED
+        #include "FreeRTOS.h"
+        #include "semphr.h"
+    #endif
+#endif
+
+#ifdef CYASSL_TIRTOS
+    #define SIZEOF_LONG_LONG 8
+    #define NO_WRITEV
+    #define NO_CYASSL_DIR
+    #define USE_FAST_MATH
+    #define TFM_TIMING_RESISTANT
+    #define NO_DEV_RANDOM
+    #define NO_FILESYSTEM
+    #define USE_CERT_BUFFERS_2048
+    #define NO_ERROR_STRINGS
+    #define USER_TIME
+
+    #ifdef __IAR_SYSTEMS_ICC__
+        #pragma diag_suppress=Pa089
+    #elif !defined(__GNUC__)
+        /* Suppress the sslpro warning */
+        #pragma diag_suppress=11
+    #endif
+
+    #include <ti/ndk/nettools/mytime/mytime.h>
+#endif
+
+#ifdef EBSNET
+    #include "rtip.h"
+
+    /* #define DEBUG_CYASSL */
+    #define NO_CYASSL_DIR  /* tbd */
+
+    #if (POLLOS)
+        #define SINGLE_THREADED
+    #endif
+
+    #if (RTPLATFORM)
+        #if (!RTP_LITTLE_ENDIAN)
+            #define BIG_ENDIAN_ORDER
+        #endif
+    #else
+        #if (!KS_LITTLE_ENDIAN)
+            #define BIG_ENDIAN_ORDER
+        #endif
+    #endif
+
+    #if (WINMSP3)
+        #undef SIZEOF_LONG
+        #define SIZEOF_LONG_LONG 8
+    #else
+        #sslpro: settings.h - please implement SIZEOF_LONG and SIZEOF_LONG_LONG
+    #endif
+
+    #define XMALLOC(s, h, type) ((void *)rtp_malloc((s), SSL_PRO_MALLOC))
+    #define XFREE(p, h, type) (rtp_free(p))
+    #define XREALLOC(p, n, h, t) realloc((p), (n))
+
+#endif /* EBSNET */
+
+#ifdef CYASSL_GAME_BUILD
+    #define SIZEOF_LONG_LONG 8
+    #if defined(__PPU) || defined(__XENON)
+        #define BIG_ENDIAN_ORDER
+    #endif
+#endif
+
+#ifdef CYASSL_LSR
+    #define HAVE_WEBSERVER
+    #define SIZEOF_LONG_LONG 8
+    #define CYASSL_LOW_MEMORY
+    #define NO_WRITEV
+    #define NO_SHA512
+    #define NO_DH
+    #define NO_DSA
+    #define NO_HC128
+    #define NO_DEV_RANDOM
+    #define NO_CYASSL_DIR
+    #define NO_RABBIT
+    #ifndef NO_FILESYSTEM
+        #define LSR_FS
+        #include "inc/hw_types.h"
+        #include "fs.h"
+    #endif
+    #define CYASSL_LWIP
+    #include <errno.h>  /* for tcp errno */
+    #define CYASSL_SAFERTOS
+    #if defined(__IAR_SYSTEMS_ICC__)
+        /* enum uses enum */
+        #pragma diag_suppress=Pa089
+    #endif
+#endif
+
+#ifdef CYASSL_SAFERTOS
+    #ifndef SINGLE_THREADED
+        #include "SafeRTOS/semphr.h"
+    #endif
+
+    #include "SafeRTOS/heap.h"
+    #define XMALLOC(s, h, type)  pvPortMalloc((s))
+    #define XFREE(p, h, type)    vPortFree((p)) 
+    #define XREALLOC(p, n, h, t) pvPortRealloc((p), (n))
+#endif
+
+#ifdef CYASSL_LOW_MEMORY
+    #undef  RSA_LOW_MEM
+    #define RSA_LOW_MEM
+    #undef  CYASSL_SMALL_STACK
+    #define CYASSL_SMALL_STACK
+    #undef  TFM_TIMING_RESISTANT
+    #define TFM_TIMING_RESISTANT
+#endif
+
+#ifdef FREESCALE_MQX
+    #define SIZEOF_LONG_LONG 8
+    #define NO_WRITEV
+    #define NO_DEV_RANDOM
+    #define NO_RABBIT
+    #define NO_CYASSL_DIR
+    #define USE_FAST_MATH
+    #define TFM_TIMING_RESISTANT
+    #define FREESCALE_K70_RNGA
+    /* #define FREESCALE_K53_RNGB */
+    #include "mqx.h"
+    #ifndef NO_FILESYSTEM
+        #include "mfs.h"
+        #include "fio.h"
+    #endif
+    #ifndef SINGLE_THREADED
+        #include "mutex.h"
+    #endif
+
+    #define XMALLOC(s, h, t)    (void *)_mem_alloc_system((s))
+    #define XFREE(p, h, t)      {void* xp = (p); if ((xp)) _mem_free((xp));}
+    /* Note: MQX has no realloc, using fastmath above */
+#endif
+
+#ifdef CYASSL_STM32F2
+    #define SIZEOF_LONG_LONG 8
+    #define NO_DEV_RANDOM
+    #define NO_CYASSL_DIR
+    #define NO_RABBIT
+    #define STM32F2_RNG
+    #define STM32F2_CRYPTO
+    #define KEIL_INTRINSICS
+#endif
+
+#ifdef MICRIUM
+
+    #include "stdlib.h"
+    #include "net_cfg.h"
+    #include "ssl_cfg.h"
+    #include "net_secure_os.h"
+
+    #define CYASSL_TYPES
+
+    typedef CPU_INT08U byte;
+    typedef CPU_INT16U word16;
+    typedef CPU_INT32U word32;
+
+    #if (NET_SECURE_MGR_CFG_WORD_SIZE == CPU_WORD_SIZE_32)
+        #define SIZEOF_LONG        4
+        #undef  SIZEOF_LONG_LONG
+    #else
+        #undef  SIZEOF_LONG
+        #define SIZEOF_LONG_LONG   8
+    #endif
+
+    #define STRING_USER
+
+    #define XSTRLEN(pstr) ((CPU_SIZE_T)Str_Len((CPU_CHAR *)(pstr)))
+    #define XSTRNCPY(pstr_dest, pstr_src, len_max) \
+                    ((CPU_CHAR *)Str_Copy_N((CPU_CHAR *)(pstr_dest), \
+                     (CPU_CHAR *)(pstr_src), (CPU_SIZE_T)(len_max)))
+    #define XSTRNCMP(pstr_1, pstr_2, len_max) \
+                    ((CPU_INT16S)Str_Cmp_N((CPU_CHAR *)(pstr_1), \
+                     (CPU_CHAR *)(pstr_2), (CPU_SIZE_T)(len_max)))  
+    #define XSTRSTR(pstr, pstr_srch) \
+                    ((CPU_CHAR *)Str_Str((CPU_CHAR *)(pstr), \
+                     (CPU_CHAR *)(pstr_srch)))
+    #define XMEMSET(pmem, data_val, size) \
+                    ((void)Mem_Set((void *)(pmem), (CPU_INT08U) (data_val), \
+                    (CPU_SIZE_T)(size)))
+    #define XMEMCPY(pdest, psrc, size) ((void)Mem_Copy((void *)(pdest), \
+                     (void *)(psrc), (CPU_SIZE_T)(size)))
+    #define XMEMCMP(pmem_1, pmem_2, size) \
+                   (((CPU_BOOLEAN)Mem_Cmp((void *)(pmem_1), (void *)(pmem_2), \
+                     (CPU_SIZE_T)(size))) ? DEF_NO : DEF_YES)
+    #define XMEMMOVE XMEMCPY
+
+#if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
+    #define MICRIUM_MALLOC    
+    #define XMALLOC(s, h, type) ((void *)NetSecure_BlkGet((CPU_INT08U)(type), \
+                                 (CPU_SIZE_T)(s), (void *)0))
+    #define XFREE(p, h, type)   (NetSecure_BlkFree((CPU_INT08U)(type), \
+                                 (p), (void *)0))
+    #define XREALLOC(p, n, h, t) realloc((p), (n))
+#endif
+
+    #if (NET_SECURE_MGR_CFG_FS_EN == DEF_ENABLED)
+        #undef  NO_FILESYSTEM
+    #else
+        #define NO_FILESYSTEM
+    #endif
+
+    #if (SSL_CFG_TRACE_LEVEL == CYASSL_TRACE_LEVEL_DBG)
+        #define DEBUG_CYASSL
+    #else
+        #undef  DEBUG_CYASSL
+    #endif
+
+    #if (SSL_CFG_OPENSSL_EN == DEF_ENABLED)
+        #define OPENSSL_EXTRA
+    #else
+        #undef  OPENSSL_EXTRA
+    #endif
+
+    #if (SSL_CFG_MULTI_THREAD_EN == DEF_ENABLED)
+        #undef  SINGLE_THREADED
+    #else
+        #define SINGLE_THREADED
+    #endif
+
+    #if (SSL_CFG_DH_EN == DEF_ENABLED)
+        #undef  NO_DH
+    #else
+        #define NO_DH
+    #endif
+
+    #if (SSL_CFG_DSA_EN == DEF_ENABLED)
+        #undef  NO_DSA
+    #else
+        #define NO_DSA
+    #endif
+
+    #if (SSL_CFG_PSK_EN == DEF_ENABLED)
+        #undef  NO_PSK
+    #else
+        #define NO_PSK
+    #endif
+
+    #if (SSL_CFG_3DES_EN == DEF_ENABLED)
+        #undef  NO_DES
+    #else
+        #define NO_DES
+    #endif
+
+    #if (SSL_CFG_AES_EN == DEF_ENABLED)
+        #undef  NO_AES
+    #else
+        #define NO_AES
+    #endif
+
+    #if (SSL_CFG_RC4_EN == DEF_ENABLED)
+        #undef  NO_RC4
+    #else
+        #define NO_RC4
+    #endif
+
+    #if (SSL_CFG_RABBIT_EN == DEF_ENABLED)
+        #undef  NO_RABBIT
+    #else
+        #define NO_RABBIT
+    #endif
+
+    #if (SSL_CFG_HC128_EN == DEF_ENABLED)
+        #undef  NO_HC128
+    #else
+        #define NO_HC128
+    #endif
+
+    #if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG)
+        #define BIG_ENDIAN_ORDER
+    #else
+        #undef  BIG_ENDIAN_ORDER
+        #define LITTLE_ENDIAN_ORDER
+    #endif
+
+    #if (SSL_CFG_MD4_EN == DEF_ENABLED)
+        #undef  NO_MD4
+    #else
+        #define NO_MD4
+    #endif
+
+    #if (SSL_CFG_WRITEV_EN == DEF_ENABLED)
+        #undef  NO_WRITEV
+    #else
+        #define NO_WRITEV
+    #endif
+
+    #if (SSL_CFG_USER_RNG_SEED_EN == DEF_ENABLED)
+        #define NO_DEV_RANDOM   
+    #else
+        #undef  NO_DEV_RANDOM
+    #endif
+
+    #if (SSL_CFG_USER_IO_EN == DEF_ENABLED)
+        #define CYASSL_USER_IO   
+    #else
+        #undef  CYASSL_USER_IO
+    #endif
+
+    #if (SSL_CFG_DYNAMIC_BUFFERS_EN == DEF_ENABLED)
+        #undef  LARGE_STATIC_BUFFERS
+        #undef  STATIC_CHUNKS_ONLY
+    #else
+        #define LARGE_STATIC_BUFFERS
+        #define STATIC_CHUNKS_ONLY
+    #endif
+
+    #if (SSL_CFG_DER_LOAD_EN == DEF_ENABLED)
+        #define  CYASSL_DER_LOAD
+    #else
+        #undef   CYASSL_DER_LOAD
+    #endif
+
+    #if (SSL_CFG_DTLS_EN == DEF_ENABLED)
+        #define  CYASSL_DTLS
+    #else
+        #undef   CYASSL_DTLS
+    #endif
+
+    #if (SSL_CFG_CALLBACKS_EN == DEF_ENABLED)
+         #define CYASSL_CALLBACKS
+    #else
+         #undef  CYASSL_CALLBACKS
+    #endif
+
+    #if (SSL_CFG_FAST_MATH_EN == DEF_ENABLED)
+         #define USE_FAST_MATH
+    #else
+         #undef  USE_FAST_MATH
+    #endif
+
+    #if (SSL_CFG_TFM_TIMING_RESISTANT_EN == DEF_ENABLED)
+         #define TFM_TIMING_RESISTANT
+    #else
+         #undef  TFM_TIMING_RESISTANT
+    #endif
+
+#endif /* MICRIUM */
+
+
+#ifdef CYASSL_QL
+    #ifndef CYASSL_SEP
+        #define CYASSL_SEP
+    #endif
+    #ifndef OPENSSL_EXTRA
+        #define OPENSSL_EXTRA
+    #endif
+    #ifndef SESSION_CERTS
+        #define SESSION_CERTS
+    #endif
+    #ifndef HAVE_AESCCM
+        #define HAVE_AESCCM
+    #endif
+    #ifndef ATOMIC_USER
+        #define ATOMIC_USER
+    #endif
+    #ifndef CYASSL_DER_LOAD
+        #define CYASSL_DER_LOAD
+    #endif
+    #ifndef KEEP_PEER_CERT
+        #define KEEP_PEER_CERT
+    #endif
+    #ifndef HAVE_ECC
+        #define HAVE_ECC
+    #endif
+    #ifndef SESSION_INDEX
+        #define SESSION_INDEX
+    #endif
+#endif /* CYASSL_QL */
+
+
+#if !defined(XMALLOC_USER) && !defined(MICRIUM_MALLOC) && \
+    !defined(CYASSL_LEANPSK) && !defined(NO_CYASSL_MEMORY)
+    #define USE_CYASSL_MEMORY
+#endif
+
+
+#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS)
+    #undef  KEEP_PEER_CERT
+    #define KEEP_PEER_CERT
+#endif
+
+
+/* stream ciphers except arc4 need 32bit alignment, intel ok without */
+#ifndef XSTREAM_ALIGNMENT
+    #if defined(__x86_64__) || defined(__ia64__) || defined(__i386__)
+        #define NO_XSTREAM_ALIGNMENT
+    #else
+        #define XSTREAM_ALIGNMENT
+    #endif
+#endif
+
+
+/* FreeScale MMCAU hardware crypto has 4 byte alignment */
+#ifdef FREESCALE_MMCAU
+    #define CYASSL_MMCAU_ALIGNMENT 4
+#endif
+
+/* if using hardware crypto and have alignment requirements, specify the
+   requirement here.  The record header of SSL/TLS will prvent easy alignment.
+   This hint tries to help as much as possible.  */
+#ifndef CYASSL_GENERAL_ALIGNMENT
+    #ifdef CYASSL_AESNI
+        #define CYASSL_GENERAL_ALIGNMENT 16
+    #elif defined(XSTREAM_ALIGNMENT)
+        #define CYASSL_GENERAL_ALIGNMENT  4
+    #elif defined(FREESCALE_MMCAU)
+        #define CYASSL_GENERAL_ALIGNMENT  CYASSL_MMCAU_ALIGNMENT
+    #else 
+        #define CYASSL_GENERAL_ALIGNMENT  0 
+    #endif
+#endif
+
+#ifdef HAVE_CRL
+    /* not widely supported yet */
+    #undef NO_SKID
+    #define NO_SKID
+#endif
+
+
+#ifdef __INTEL_COMPILER
+    #pragma warning(disable:2259) /* explicit casts to smaller sizes, disable */
+#endif
+
+
+/* Place any other flags or defines here */
+
+
+#ifdef __cplusplus
+    }   /* extern "C" */
+#endif
+
+
+#endif /* CTAO_CRYPT_SETTINGS_H */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/settings_comp.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/settings_comp.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/settings_comp.h	(revision 164)
@@ -0,0 +1,71 @@
+/* settings_comp.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef CTAO_CRYPT_SETTINGS_C_H
+#define CTAO_CRYPT_SETTINGS_C_H
+
+
+/* since fips overrides rsa.h map compatibility here */
+#if !defined(NO_RSA)
+	#ifdef WOLFSSL_KEY_GEN
+	    #define RsaKeyToDer wc_RsaKeyToDer
+	#endif
+
+	#define RsaPrivateKeyDecode   wc_RsaPrivateKeyDecode
+	#define RsaPublicKeyDecode    wc_RsaPublicKeyDecode
+	#define RsaPublicKeyDecodeRaw wc_RsaPublicKeyDecodeRaw
+#endif /* have rsa and HAVE_FIPS */
+
+/* Macro redefinitions for compatibility */
+#ifdef HAVE_NTRU
+    #define MakeNtruCert wc_MakeNtruCert
+#endif
+#if defined(WOLFSSL_SHA512) && !defined(CYASSL_SHA512)
+    #define CYASSL_SHA512
+#endif
+#if defined(WOLFSSL_SHA384) && !defined(CYASSL_SHA384)
+    #define CYASSL_SHA384
+#endif
+#if defined(WOLFSSL_LEANPSK) && !defined(CYASSL_LEANPSK)
+    #define CYASSL_LEANPSK
+#endif
+#if defined(NO_WOLFSSL_MEMORY) && !defined(NO_CYASSL_MEMORY)
+    #define NO_CYASSL_MEMORY
+#endif
+#if defined(WOLFSSL_KEY_GEN) && !defined(CYASSL_KEY_GEN)
+    #define CYASSL_KEY_GEN
+#endif
+
+/* AES */
+#if defined(WOLFSSL_AES_DIRECT) && !defined(CYASSL_AES_DIRECT)
+    #define CYASSL_AES_DIRECT
+#endif
+#if defined(WOLFSSL_AES_COUNTER) && !defined(CYASSL_AES_COUNTER)
+    #define CYASSL_AES_COUNTER
+#endif
+
+/* DES */
+#if defined(WOLFSSL_DES_ECB) && !defined(CYASSL_DES_ECB)
+    #define CYASSL_DES_ECB
+#endif
+
+#endif /* CTAO_CRYPT_SETTINGS_C_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/sha256.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/sha256.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/sha256.h	(revision 164)
@@ -0,0 +1,39 @@
+/* sha256.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* code submitted by raphael.huck@efixo.com */
+
+
+#ifndef NO_SHA256
+
+#ifndef CTAO_CRYPT_SHA256_H
+#define CTAO_CRYPT_SHA256_H
+
+#include <wolfssl/wolfcrypt/sha256.h>
+#define InitSha256   wc_InitSha256
+#define Sha256Update wc_Sha256Update
+#define Sha256Final  wc_Sha256Final
+#define Sha256Hash   wc_Sha256Hash
+
+#endif /* CTAO_CRYPT_SHA256_H */
+#endif /* NO_SHA256 */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/types.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/types.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/types.h	(revision 164)
@@ -0,0 +1,39 @@
+/* types.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef CTAO_CRYPT_TYPES_H
+#define CTAO_CRYPT_TYPES_H
+
+#include <cyassl/ctaocrypt/wc_port.h>
+#include <cyassl/ctaocrypt/settings.h>
+#include <wolfssl/wolfcrypt/types.h>
+
+/* compatibility macros */
+#define CYASSL_WORD_SIZE    WOLFSSL_WORD_SIZE
+#define CYASSL_BIT_SIZE     WOLFSSL_BIT_SIZE
+#define CYASSL_MAX_16BIT    WOLFSSL_MAX_16BIT
+#define CYASSL_MAX_ERROR_SZ WOLFSSL_MAX_ERROR_SZ
+#define cyassl_word         wolfssl_word
+#define CYASSL_MAX_ERROR_SZ WOLFSSL_MAX_ERROR_SZ
+
+#endif /* CTAO_CRYPT_TYPES_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/visibility.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/visibility.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/visibility.h	(revision 164)
@@ -0,0 +1,72 @@
+/* visibility.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Visibility control macros */
+
+#ifndef CTAO_CRYPT_VISIBILITY_H
+#define CTAO_CRYPT_VISIBILITY_H
+
+/* fips compatibility @wc_fips */
+#ifndef HAVE_FIPS
+    #include <wolfssl/wolfcrypt/visibility.h>
+    #define CYASSL_API   WOLFSSL_API
+	#define CYASSL_LOCAL WOLFSSL_LOCAL
+#else
+/* CYASSL_API is used for the public API symbols.
+        It either imports or exports (or does nothing for static builds)
+
+   CYASSL_LOCAL is used for non-API symbols (private).
+*/
+
+#if defined(BUILDING_WOLFSSL)
+    #if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
+        #define CYASSL_API   __attribute__ ((visibility("default")))
+        #define CYASSL_LOCAL __attribute__ ((visibility("hidden")))
+    #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
+        #define CYASSL_API   __global
+        #define CYASSL_LOCAL __hidden
+    #elif defined(_MSC_VER)
+        #ifdef CYASSL_DLL
+            #define CYASSL_API extern __declspec(dllexport)
+        #else
+            #define CYASSL_API
+        #endif
+        #define CYASSL_LOCAL
+    #else
+        #define CYASSL_API
+        #define CYASSL_LOCAL
+    #endif /* HAVE_VISIBILITY */
+#else /* BUILDING_WOLFSSL */
+    #if defined(_MSC_VER)
+        #ifdef CYASSL_DLL
+            #define CYASSL_API extern __declspec(dllimport)
+        #else
+            #define CYASSL_API
+        #endif
+        #define CYASSL_LOCAL
+    #else
+        #define CYASSL_API
+        #define CYASSL_LOCAL
+    #endif
+#endif /* BUILDING_WOLFSSL */
+#endif /* HAVE_FIPS */
+#endif /* CTAO_CRYPT_VISIBILITY_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/wc_port.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/wc_port.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ctaocrypt/wc_port.h	(revision 164)
@@ -0,0 +1,31 @@
+/* port.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef CTAO_CRYPT_PORT_H
+#define CTAO_CRYPT_PORT_H
+
+#include <cyassl/ctaocrypt/visibility.h>
+#include <wolfssl/wolfcrypt/wc_port.h>
+#define CyaSSL_Mutex wolfSSL_Mutex
+
+#endif /* CTAO_CRYPT_PORT_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/error-ssl.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/error-ssl.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/error-ssl.h	(revision 164)
@@ -0,0 +1,22 @@
+/* error-ssl.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wolfssl/error-ssl.h>
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/openssl/ssl.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/openssl/ssl.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/openssl/ssl.h	(revision 164)
@@ -0,0 +1,33 @@
+/* ssl.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * a with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/*  ssl.h defines openssl compatibility layer
+ *
+ */
+#ifndef CYASSL_OPENSSL_H_
+#define CYASSL_OPENSSL_H_
+
+#include <cyassl/ssl.h>
+#include <wolfssl/openssl/ssl.h>
+
+#endif
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ssl.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ssl.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/ssl.h	(revision 164)
@@ -0,0 +1,720 @@
+/* ssl.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * a with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * ssl.h makes wolfssl backwards compatibile with cyassl
+ */
+
+#ifndef WOLFSSL_CYASSL_H_
+#define WOLFSSL_CYASSL_H_
+/*
+ * Name change
+ * include the new ssl.h
+ */
+#include <wolfssl/ssl.h>
+#include <cyassl/ctaocrypt/types.h>
+#include <cyassl/ctaocrypt/settings.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#ifdef _WIN32
+    /* wincrypt.h clashes */
+    #undef X509_NAME
+#endif
+
+#ifdef CYASSL_TIRTOS
+    #undef CYASSL_TIRTOS
+    #define CYASSL_TIRTOS WOLFSSL_TIRTOS
+#endif
+
+#define CYASSL          WOLFSSL
+#define DEBUG_CYASSL    DEBUG_WOLFSSL
+#define CYASSL_CTX      WOLFSSL_CTX
+#define CYASSL_METHOD   WOLFSSL_METHOD
+#define CYASSL_SESSION  WOLFSSL_SESSION
+
+#define CYASSL_X509       WOLFSSL_X509
+#define CYASSL_X509_NAME  WOLFSSL_X509_NAME
+#define CYASSL_X509_CHAIN WOLFSSL_X509_CHAIN
+#ifdef WOLFSSL_SNIFFER
+    #define CYASSL_SNIFFER    WOLFSSL_SNIFFER
+#endif
+
+/* redeclare guard */
+#define CYASSL_TYPES_DEFINED WOLFSSL_TYPES_DEFINED
+
+/* legacy defines */
+#define yasslIP          wolfSSLIP                                         /**/
+#define yasslPort        wolfSSLPort                                       /**/
+
+/* cyassl/ssl.h (structs) */
+#define CYASSL_RSA                WOLFSSL_RSA
+#define CYASSL_DSA                WOLFSSL_DSA
+#define CYASSL_BIO                WOLFSSL_BIO
+#define CYASSL_CIPHER             WOLFSSL_CIPHER
+#define CYASSL_MD4_CTX            WOLFSSL_MD4_CTX
+#define CYASSL_MFL_2_9            WOLFSSL_MFL_2_9                          /**/
+#define CYASSL_MFL_2_13           WOLFSSL_MFL_2_13                         /**/
+#define CYASSL_EVP_PKEY           WOLFSSL_EVP_PKEY
+#define CYASSL_X509_CRL           WOLFSSL_X509_CRL
+#define CYASSL_ASN1_TIME          WOLFSSL_ASN1_TIME
+#define CYASSL_BIO_METHOD         WOLFSSL_BIO_METHOD
+#define CYASSL_X509_STORE         WOLFSSL_X509_STORE
+#define CYASSL_X509_OBJECT        WOLFSSL_X509_OBJECT
+#define CYASSL_X509_LOOKUP        WOLFSSL_X509_LOOKUP
+#define CYASSL_ASN1_OBJECT        WOLFSSL_ASN1_OBJECT
+#define CYASSL_ASN1_STRING        WOLFSSL_ASN1_STRING
+#define CYASSL_COMP_METHOD        WOLFSSL_COMP_METHOD
+#define CYASSL_CRL_CHECKALL       WOLFSSL_CRL_CHECKALL
+#define CYASSL_ASN1_INTEGER       WOLFSSL_ASN1_INTEGER
+#define CYASSL_X509_REVOKED       WOLFSSL_X509_REVOKED
+#define CYASSL_dynlock_value      WOLFSSL_dynlock_value
+#define CYASSL_X509_EXTENSION     WOLFSSL_X509_EXTENSION
+#define CYASSL_X509_STORE_CTX     WOLFSSL_X509_STORE_CTX
+#define CYASSL_X509_LOOKUP_METHOD WOLFSSL_X509_LOOKUP_METHOD
+
+#define CyaSSL_LoadCRL            wolfSSL_LoadCRL
+#define CyaSSL_EnableCRL          wolfSSL_EnableCRL
+#define CyaSSL_SetCRL_Cb          wolfSSL_SetCRL_Cb
+
+/* cyassl/test.h */
+#ifdef CyaSSL_TEST_H
+    #define CYASSL_THREAD         WOLFSSL_THREAD
+#endif
+
+/* src/ssl.c */
+#define CYASSL_CRL                       WOLFSSL_CRL
+#define CYASSL_SSLV3                     WOLFSSL_SSLV3
+#define CYASSL_TLSV1                     WOLFSSL_TLSV1
+#define CYASSL_TLSV1_1                   WOLFSSL_TLSV1_1
+#define CYASSL_TLSV1_2                   WOLFSSL_TLSV1_2
+#define CYASSL_USER_CA                   WOLFSSL_USER_CA
+#define CYASSL_CLIENT_END                WOLFSSL_CLIENT_END
+#define CYASSL_CERT_MANAGER              WOLFSSL_CERT_MANAGER
+#define MAX_CYASSL_FILE_SIZE             MAX_WOLFSSL_FILE_SIZE
+
+#define CyaSSL_get_cipher                wolfSSL_get_cipher
+#define CyaSSL_get_ciphers               wolfSSL_get_ciphers
+#define CyaSSL_KeyPemToDer               wolfSSL_KeyPemToDer
+#define CyaSSL_get_version               wolfSSL_get_version
+#define CyaSSL_SetServerID               wolfSSL_SetServerID
+#define CyaSSL_use_old_poly              wolfSSL_use_old_poly
+#define CyaSSL_SetCertCbCtx              wolfSSL_SetCertCbCtx
+#define CyaSSL_CertPemToDer              wolfSSL_CertPemToDer
+#define CyaSSL_get_shutdown              wolfSSL_get_shutdown
+#define CyaSSL_SetMinVersion             wolfSSL_SetMinVersion
+#define CyaSSL_CTX_UnloadCAs             wolfSSL_CTX_UnloadCAs
+#define CyaSSL_session_reused            wolfSSL_session_reused
+#define CyaSSL_UnloadCertsKeys           wolfSSL_UnloadCertsKeys
+#define CyaSSL_CIPHER_get_name           wolfSSL_CIPHER_get_name
+#define CyaSSL_is_init_finished          wolfSSL_is_init_finished
+#define CyaSSL_get_alert_history         wolfSSL_get_alert_history
+#define CyaSSL_get_current_cipher        wolfSSL_get_current_cipher
+#define CyaSSL_CertManagerUnloadCAs      wolfSSL_CertManagerUnloadCAs
+#define CyaSSL_CertManagerEnableOCSP     wolfSSL_CertManagerEnableOCSP
+#define CyaSSL_CTX_check_private_key     wolfSSL_CTX_check_private_key
+#define CyaSSL_CertManagerDisableOCSP    wolfSSL_CertManagerDisableOCSP
+#define CyaSSL_get_current_cipher_suite  wolfSSL_get_current_cipher_suite
+#define CyaSSL_CTX_load_verify_locations wolfSSL_CTX_load_verify_locations
+#define CyaSSL_CTX_set_default_passwd_cb wolfSSL_CTX_set_default_passwd_cb
+
+#define CyaSSL_save_session_cache        wolfSSL_save_session_cache
+#define CyaSSL_restore_session_cache     wolfSSL_restore_session_cache
+#define CyaSSL_memsave_session_cache     wolfSSL_memsave_session_cache
+#define CyaSSL_memrestore_session_cache  wolfSSL_memrestore_session_cache
+#define CyaSSL_get_session_cache_memsize wolfSSL_get_session_cache_memsize
+
+/* certificate cache persistence, uses ctx since certs are per ctx */
+#define CyaSSL_CTX_save_cert_cache        wolfSSL_CTX_save_cert_cache
+#define CyaSSL_CTX_restore_cert_cache     wolfSSL_CTX_restore_cert_cache
+#define CyaSSL_CTX_memsave_cert_cache     wolfSSL_CTX_memsave_cert_cache
+#define CyaSSL_CTX_memrestore_cert_cache  wolfSSL_CTX_memrestore_cert_cache
+#define CyaSSL_CTX_get_cert_cache_memsize wolfSSL_CTX_get_cert_cache_memsize
+
+/* wolfSSL extensions */
+/* get wolfSSL peer X509_CHAIN */
+#define CyaSSL_get_chain_count wolfSSL_get_chain_count
+/* index cert length */
+#define CyaSSL_get_chain_length wolfSSL_get_chain_length
+/* index cert in X509 */
+#define CyaSSL_get_chain_X509 wolfSSL_get_chain_X509
+/* free X509 */
+#define CyaSSL_FreeX509 wolfSSL_FreeX509
+/* get index cert in PEM */
+#define CyaSSL_X509_get_subjectCN wolfSSL_X509_get_subjectCN
+#define CyaSSL_X509_get_der       wolfSSL_X509_get_der
+#define CyaSSL_X509_notBefore     wolfSSL_X509_notBefore
+#define CyaSSL_X509_notAfter      wolfSSL_X509_notAfter
+#define CyaSSL_X509_version       wolfSSL_X509_version
+
+#define CyaSSL_cmp_peer_cert_to_file wolfSSL_cmp_peer_cert_to_file
+
+#define CyaSSL_X509_get_next_altname wolfSSL_X509_get_next_altname
+
+#define CyaSSL_X509_d2i wolfSSL_X509_d2i
+#ifndef NO_FILESYSTEM
+    #ifndef NO_STDIO_FILESYSTEM
+        #define CyaSSL_X509_d2i_fp wolfSSL_X509_d2i_fp
+    #endif
+#define CyaSSL_X509_load_certificate_file wolfSSL_X509_load_certificate_file
+#endif
+
+#ifdef WOLFSSL_SEP
+#define CyaSSL_X509_get_device_type      wolfSSL_X509_get_device_type
+#define CyaSSL_X509_get_hw_type          wolfSSL_X509_get_hw_type
+#define CyaSSL_X509_get_hw_serial_number wolfSSL_X509_get_hw_serial_number
+#endif
+
+#define CyaSSL_CTX_SetGenCookie wolfSSL_CTX_SetGenCookie
+#define CyaSSL_SetCookieCtx     wolfSSL_SetCookieCtx
+#define CyaSSL_GetCookieCtx     wolfSSL_GetCookieCtx
+#define CyaSSL_ERR_get_error_line_data wolfSSL_ERR_get_error_line_data
+#define CyaSSL_ERR_get_error           wolfSSL_ERR_get_error
+#define CyaSSL_ERR_clear_error         wolfSSL_ERR_clear_error
+#define CyaSSL_RAND_status             wolfSSL_RAND_status
+#define CyaSSL_RAND_bytes              wolfSSL_RAND_bytes
+#define CyaSSL_CTX_set_options         wolfSSL_CTX_set_options
+#define CyaSSL_ERR_free_strings        wolfSSL_ERR_free_strings
+#define CyaSSL_ERR_remove_state        wolfSSL_ERR_remove_state
+#define CyaSSL_EVP_cleanup             wolfSSL_EVP_cleanup
+#define CyaSSL_cleanup_all_ex_data     wolfSSL_cleanup_all_ex_data
+#define CyaSSL_CTX_set_mode            wolfSSL_CTX_set_mode
+#define CyaSSL_CTX_get_mode            wolfSSL_CTX_get_mode
+#define CyaSSL_CTX_set_default_read_ahead   wolfSSL_CTX_set_default_read_ahead
+#define CyaSSL_CTX_sess_set_cache_size      wolfSSL_CTX_sess_set_cache_size
+#define CyaSSL_CTX_set_default_verify_paths wolfSSL_CTX_set_default_verify_paths
+#define CyaSSL_CTX_set_session_id_context   wolfSSL_CTX_set_session_id_context
+#define CyaSSL_get_peer_certificate         wolfSSL_get_peer_certificate
+#define CyaSSL_BIO_printf                   wolfSSL_BIO_printf
+#define CyaSSL_ASN1_UTCTIME_print           wolfSSL_ASN1_UTCTIME_print
+#define CyaSSL_sk_num                       wolfSSL_sk_num
+#define CyaSSL_sk_value                     wolfSSL_sk_value
+
+/* stunnel 4.28 needs */
+#define CyaSSL_CTX_get_ex_data        wolfSSL_CTX_get_ex_data
+#define CyaSSL_CTX_set_ex_data        wolfSSL_CTX_set_ex_data
+#define CyaSSL_CTX_sess_set_get_cb    wolfSSL_CTX_sess_set_get_cb
+#define CyaSSL_CTX_sess_set_new_cb    wolfSSL_CTX_sess_set_new_cb
+#define CyaSSL_CTX_sess_set_remove_cb wolfSSL_CTX_sess_set_remove_cb
+
+#define CyaSSL_i2d_SSL_SESSION wolfSSL_i2d_SSL_SESSION
+#define CyaSSL_d2i_SSL_SESSION wolfSSL_d2i_SSL_SESSION
+
+#define CyaSSL_SESSION_get_timeout  wolfSSL_SESSION_get_timeout
+#define CyaSSL_SESSION_get_time     wolfSSL_SESSION_get_time
+#define CyaSSL_CTX_get_ex_new_index wolfSSL_CTX_get_ex_new_index
+
+
+/* io.c */
+#define CYASSL_CBIO_ERR_ISR        WOLFSSL_CBIO_ERR_ISR
+#define CYASSL_CBIO_ERR_TIMEOUT    WOLFSSL_CBIO_ERR_TIMEOUT
+#define CYASSL_CBIO_ERR_GENERAL    WOLFSSL_CBIO_ERR_GENERAL
+#define CYASSL_CBIO_ERR_CONN_RST   WOLFSSL_CBIO_ERR_CONN_RST
+#define CYASSL_CBIO_ERR_WANT_READ  WOLFSSL_CBIO_ERR_WANT_READ
+#define CYASSL_CBIO_ERR_WANT_WRITE WOLFSSL_CBIO_ERR_WANT_WRITE
+#define CYASSL_CBIO_ERR_CONN_CLOSE WOLFSSL_CBIO_ERR_CONN_CLOSE
+
+#define CyaSSL_GetIOReadCtx        wolfSSL_GetIOReadCtx
+#define CyaSSL_GetIOWriteCtx       wolfSSL_GetIOWriteCtx
+
+/* src/tls.c */
+#define CYASSL_SERVER_END          WOLFSSL_SERVER_END
+#define CYASSL_TLS_HMAC_INNER_SZ   WOLFSSL_TLS_HMAC_INNER_SZ
+
+#define CyaSSL_DeriveTlsKeys       wolfSSL_DeriveTlsKeys
+#define CyaSSL_make_eap_keys       wolfSSL_make_eap_keys
+#define CyaSSL_MakeTlsMasterSecret wolfSSL_MakeTlsMasterSecret
+
+/* src/internal.c */
+#define CYASSL_CHAIN_CA                WOLFSSL_CHAIN_CA
+#define CYASSL_ALERT_HISTORY           WOLFSSL_ALERT_HISTORY
+#define CYASSL_SESSION_TIMEOUT         WOLFSSL_SESSION_TIMEOUT
+#define CYASSL_CBIO_ERR_CONN_RST       WOLFSSL_CBIO_ERR_CONN_RST
+
+#define cyassl_rc4                     wolfssl_rc4
+#define cyassl_aes                     wolfssl_aes
+#define cyassl_chacha                  wolfssl_chacha
+#define CyaSSL_ERR_reason_error_string wolfSSL_ERR_reason_error_string
+
+#define CyaSSL_set_ex_data  wolfSSL_set_ex_data
+#define CyaSSL_get_shutdown wolfSSL_get_shutdown
+#define CyaSSL_set_rfd      wolfSSL_set_rfd
+#define CyaSSL_set_wfd      wolfSSL_set_wfd
+#define CyaSSL_set_shutdown wolfSSL_set_shutdown
+#define CyaSSL_set_session_id_context wolfSSL_set_session_id_context
+#define CyaSSL_set_connect_state      wolfSSL_set_connect_state
+#define CyaSSL_set_accept_state       wolfSSL_set_accept_state
+#define CyaSSL_session_reused         wolfSSL_session_reused
+#define CyaSSL_SESSION_free           wolfSSL_SESSION_free
+#define CyaSSL_is_init_finished       wolfSSL_is_init_finished
+
+#define CyaSSL_get_version              wolfSSL_get_version
+#define CyaSSL_get_current_cipher_suite wolfSSL_get_current_cipher_suite
+#define CyaSSL_get_current_cipher       wolfSSL_get_current_cipher
+#define CyaSSL_CIPHER_description       wolfSSL_CIPHER_description
+#define CyaSSL_CIPHER_get_name          wolfSSL_CIPHER_get_name
+#define CyaSSL_get_cipher               wolfSSL_get_cipher
+#define CyaSSL_get1_session             wolfSSL_get1_session
+
+#define CyaSSL_X509_free      wolfSSL_X509_free
+#define CyaSSL_OPENSSL_free   wolfSSL_OPENSSL_free
+#define CyaSSL_OCSP_parse_url wolfSSL_OCSP_parse_url
+
+#define CyaSSLv23_client_method wolfSSLv23_client_method
+#define CyaSSLv2_client_method  wolfSSLv2_client_method
+#define CyaSSLv2_server_method  wolfSSLv2_server_method
+
+#define CyaSSL_MD4_Init     wolfSSL_MD4_Init
+#define CyaSSL_MD4_Update   wolfSSL_MD4_Update
+#define CyaSSL_MD4_Final    wolfSSL_MD4_Final
+
+
+#define CyaSSL_BIO_new      wolfSSL_BIO_new
+#define CyaSSL_BIO_free     wolfSSL_BIO_free
+#define CyaSSL_BIO_free_all wolfSSL_BIO_free_all
+#define CyaSSL_BIO_read     wolfSSL_BIO_read
+#define CyaSSL_BIO_write    wolfSSL_BIO_write
+#define CyaSSL_BIO_push     wolfSSL_BIO_push
+#define CyaSSL_BIO_pop      wolfSSL_BIO_pop
+#define CyaSSL_BIO_flush    wolfSSL_BIO_flush
+#define CyaSSL_BIO_pending  wolfSSL_BIO_pending
+
+#define CyaSSL_BIO_f_buffer              wolfSSL_BIO_f_buffer
+#define CyaSSL_BIO_set_write_buffer_size wolfSSL_BIO_set_write_buffer_size
+#define CyaSSL_BIO_f_ssl                 wolfSSL_BIO_f_ssl
+#define CyaSSL_BIO_new_socket            wolfSSL_BIO_new_socket
+#define CyaSSL_BIO_eof                   wolfSSL_BIO_eof
+
+#define CyaSSL_BIO_s_mem        wolfSSL_BIO_s_mem
+#define CyaSSL_BIO_f_base64     wolfSSL_BIO_f_base64
+#define CyaSSL_BIO_set_flags    wolfSSL_BIO_set_flags
+#define CyaSSL_BIO_get_mem_data wolfSSL_BIO_get_mem_data
+#define CyaSSL_BIO_new_mem_buf  wolfSSL_BIO_new_mem_buf
+
+
+#define CyaSSL_BIO_set_ssl wolfSSL_BIO_set_ssl
+#define CyaSSL_set_bio     wolfSSL_set_bio
+
+#define CyaSSL_add_all_algorithms wolfSSL_add_all_algorithms
+#define CyaSSL_RAND_screen        wolfSSL_RAND_screen
+#define CyaSSL_RAND_file_name     wolfSSL_RAND_file_name
+#define CyaSSL_RAND_write_file    wolfSSL_RAND_write_file
+#define CyaSSL_RAND_load_file     wolfSSL_RAND_load_file
+#define CyaSSL_RAND_egd           wolfSSL_RAND_egd
+#define CyaSSL_RAND_seed          wolfSSL_RAND_seed
+#define CyaSSL_RAND_add           wolfSSL_RAND_add
+
+#define CyaSSL_COMP_zlib wolfSSL_COMP_zlib
+#define CyaSSL_COMP_rle  wolfSSL_COMP_rle
+#define CyaSSL_COMP_add_compression_method  wolfSSL_COMP_add_compression_method
+#define CyaSSL_set_dynlock_create_callback  wolfSSL_set_dynlock_create_callback
+#define CyaSSL_set_dynlock_lock_callback    wolfSSL_set_dynlock_lock_callback
+#define CyaSSL_set_dynlock_destroy_callback wolfSSL_set_dynlock_destroy_callback
+#define CyaSSL_get_ex_new_index     wolfSSL_get_ex_new_index
+#define CyaSSL_set_id_callback      wolfSSL_set_id_callback
+#define CyaSSL_set_locking_callback wolfSSL_set_locking_callback
+#define CyaSSL_num_locks            wolfSSL_num_locks
+
+#define CyaSSL_X509_STORE_CTX_get_current_cert wolfSSL_X509_STORE_CTX_get_current_cert
+#define CyaSSL_X509_STORE_CTX_get_error        wolfSSL_X509_STORE_CTX_get_error
+#define CyaSSL_X509_STORE_CTX_get_error_depth  wolfSSL_X509_STORE_CTX_get_error_depth
+
+#define CyaSSL_X509_NAME_oneline            wolfSSL_X509_NAME_oneline
+#define CyaSSL_X509_get_issuer_name         wolfSSL_X509_get_issuer_name
+#define CyaSSL_X509_get_subject_name        wolfSSL_X509_get_subject_name
+#define CyaSSL_X509_ext_isSet_by_NID        wolfSSL_X509_ext_isSet_by_NID
+#define CyaSSL_X509_ext_get_critical_by_NID wolfSSL_X509_ext_get_critical_by_NID
+#define CyaSSL_X509_get_isCA                wolfSSL_X509_get_isCA
+#define CyaSSL_X509_get_isSet_pathLength    wolfSSL_X509_get_isSet_pathLength
+#define CyaSSL_X509_get_pathLength          wolfSSL_X509_get_pathLength
+#define CyaSSL_X509_get_keyUsage            wolfSSL_X509_get_keyUsage
+#define CyaSSL_X509_get_authorityKeyID      wolfSSL_X509_get_authorityKeyID
+#define CyaSSL_X509_get_subjectKeyID        wolfSSL_X509_get_subjectKeyID
+#define CyaSSL_X509_NAME_entry_count        wolfSSL_X509_NAME_entry_count
+#define CyaSSL_X509_NAME_get_text_by_NID    wolfSSL_X509_NAME_get_text_by_NID
+#define CyaSSL_X509_verify_cert             wolfSSL_X509_verify_cert
+#define CyaSSL_X509_verify_cert_error_string wolfSSL_X509_verify_cert_error_string
+#define CyaSSL_X509_get_signature_type      wolfSSL_X509_get_signature_type
+#define CyaSSL_X509_get_signature           wolfSSL_X509_get_signature
+
+#define CyaSSL_X509_LOOKUP_add_dir   wolfSSL_X509_LOOKUP_add_dir
+#define CyaSSL_X509_LOOKUP_load_file wolfSSL_X509_LOOKUP_load_file
+#define CyaSSL_X509_LOOKUP_hash_dir  wolfSSL_X509_LOOKUP_hash_dir
+#define CyaSSL_X509_LOOKUP_file      wolfSSL_X509_LOOKUP_file
+
+#define CyaSSL_X509_STORE_add_lookup wolfSSL_X509_STORE_add_lookup
+#define CyaSSL_X509_STORE_new        wolfSSL_X509_STORE_new
+#define CyaSSL_X509_STORE_free       wolfSSL_X509_STORE_free
+#define CyaSSL_X509_STORE_add_cert   wolfSSL_X509_STORE_add_cert
+#define CyaSSL_X509_STORE_set_default_paths wolfSSL_X509_STORE_set_default_paths
+#define CyaSSL_X509_STORE_get_by_subject    wolfSSL_X509_STORE_get_by_subject
+#define CyaSSL_X509_STORE_CTX_new           wolfSSL_X509_STORE_CTX_new
+#define CyaSSL_X509_STORE_CTX_init          wolfSSL_X509_STORE_CTX_init
+#define CyaSSL_X509_STORE_CTX_free          wolfSSL_X509_STORE_CTX_free
+#define CyaSSL_X509_STORE_CTX_cleanup       wolfSSL_X509_STORE_CTX_cleanup
+
+#define CyaSSL_X509_CRL_get_lastUpdate wolfSSL_X509_CRL_get_lastUpdate
+#define CyaSSL_X509_CRL_get_nextUpdate wolfSSL_X509_CRL_get_nextUpdate
+
+#define CyaSSL_X509_get_pubkey wolfSSL_X509_get_pubkey
+#define CyaSSL_X509_CRL_verify wolfSSL_X509_CRL_verify
+#define CyaSSL_X509_STORE_CTX_set_error  wolfSSL_X509_STORE_CTX_set_error
+#define CyaSSL_X509_OBJECT_free_contents wolfSSL_X509_OBJECT_free_contents
+#define CyaSSL_EVP_PKEY_free             wolfSSL_EVP_PKEY_free
+#define CyaSSL_X509_cmp_current_time     wolfSSL_X509_cmp_current_time
+#define CyaSSL_sk_X509_REVOKED_num       wolfSSL_sk_X509_REVOKED_num
+
+#define CyaSSL_X509_CRL_get_REVOKED     wolfSSL_X509_CRL_get_REVOKED
+#define CyaSSL_sk_X509_REVOKED_value    wolfSSL_sk_X509_REVOKED_value
+#define CyaSSL_X509_get_serialNumber    wolfSSL_X509_get_serialNumber
+#define CyaSSL_ASN1_TIME_print          wolfSSL_ASN1_TIME_print
+#define CyaSSL_ASN1_INTEGER_cmp         wolfSSL_ASN1_INTEGER_cmp
+#define CyaSSL_ASN1_INTEGER_get         wolfSSL_ASN1_INTEGER_get
+#define CyaSSL_load_client_CA_file      wolfSSL_load_client_CA_file
+#define CyaSSL_CTX_set_client_CA_list   wolfSSL_CTX_set_client_CA_list
+#define CyaSSL_X509_STORE_CTX_get_ex_data     wolfSSL_X509_STORE_CTX_get_ex_data
+#define CyaSSL_get_ex_data_X509_STORE_CTX_idx wolfSSL_get_ex_data_X509_STORE_CTX_idx
+#define CyaSSL_get_ex_data                    wolfSSL_get_ex_data
+
+#define CyaSSL_CTX_set_default_passwd_cb_userdata wolfSSL_CTX_set_default_passwd_cb_userdata
+#define CyaSSL_CTX_set_default_passwd_cb          wolfSSL_CTX_set_default_passwd_cb
+#define CyaSSL_CTX_set_info_callback  wolfSSL_CTX_set_info_callback
+#define CyaSSL_ERR_peek_error         wolfSSL_ERR_peek_error
+#define CyaSSL_GET_REASON             wolfSSL_GET_REASON
+#define CyaSSL_alert_type_string_long wolfSSL_alert_type_string_long
+#define CyaSSL_alert_desc_string_long wolfSSL_alert_desc_string_long
+#define CyaSSL_state_string_long      wolfSSL_state_string_long
+
+#define CyaSSL_RSA_generate_key         wolfSSL_RSA_generate_key
+#define CyaSSL_CTX_set_tmp_rsa_callback wolfSSL_CTX_set_tmp_rsa_callback
+#define CyaSSL_PEM_def_callback         wolfSSL_PEM_def_callback
+#define CyaSSL_CTX_sess_accept          wolfSSL_CTX_sess_accept
+#define CyaSSL_CTX_sess_connect         wolfSSL_CTX_sess_connect
+#define CyaSSL_CTX_sess_accept_good     wolfSSL_CTX_sess_accept_good
+#define CyaSSL_CTX_sess_connect_good    wolfSSL_CTX_sess_connect_good
+#define CyaSSL_CTX_sess_accept_renegotiate  wolfSSL_CTX_sess_accept_renegotiate
+#define CyaSSL_CTX_sess_connect_renegotiate wolfSSL_CTX_sess_connect_renegotiate
+#define CyaSSL_CTX_sess_hits                wolfSSL_CTX_sess_hits
+#define CyaSSL_CTX_sess_cb_hits             wolfSSL_CTX_sess_cb_hits
+#define CyaSSL_CTX_sess_cache_full          wolfSSL_CTX_sess_cache_full
+#define CyaSSL_CTX_sess_misses              wolfSSL_CTX_sess_misses
+#define CyaSSL_CTX_sess_timeouts            wolfSSL_CTX_sess_timeouts
+#define CyaSSL_CTX_sess_number              wolfSSL_CTX_sess_number
+#define CyaSSL_CTX_sess_get_cache_size      wolfSSL_CTX_sess_get_cache_size
+
+
+
+/* src/keys.c */
+#define cyassl_triple_des wolfssl_triple_des
+
+/* Initialization and Shutdown */
+#define CyaSSL_Init         wolfSSL_Init
+#define CyaSSL_library_init wolfSSL_library_init
+#define CyaSSL_Cleanup      wolfSSL_Cleanup
+#define CyaSSL_shutdown     wolfSSL_shutdown
+
+/* Certs and keys */
+#define CyaSSL_SetTmpDH                     wolfSSL_SetTmpDH
+#define CyaSSL_KeepArrays                   wolfSSL_KeepArrays
+#define CyaSSL_FreeArrays                   wolfSSL_FreeArrays
+#define CyaSSL_SetTmpDH_file                wolfSSL_SetTmpDH_file
+#define CyaSSL_use_PrivateKey_buffer        wolfSSL_use_PrivateKey_buffer
+#define CyaSSL_use_certificate_buffer       wolfSSL_use_certificate_buffer
+#define CyaSSL_CTX_load_verify_buffer       wolfSSL_CTX_load_verify_buffer
+#define CyaSSL_CTX_use_PrivateKey_file      wolfSSL_CTX_use_PrivateKey_file
+#define CyaSSL_CTX_use_certificate_file     wolfSSL_CTX_use_certificate_file
+#define CyaSSL_CTX_use_PrivateKey_buffer    wolfSSL_CTX_use_PrivateKey_buffer
+#define CyaSSL_CTX_use_PrivateKey_buffer    wolfSSL_CTX_use_PrivateKey_buffer
+#define CyaSSL_CTX_use_certificate_buffer   wolfSSL_CTX_use_certificate_buffer
+#define CyaSSL_CTX_use_NTRUPrivateKey_file  wolfSSL_CTX_use_NTRUPrivateKey_file
+#define CyaSSL_use_certificate_chain_buffer wolfSSL_use_certificate_chain_buffer
+#define CyaSSL_CTX_der_load_verify_locations    \
+                                            wolfSSL_CTX_der_load_verify_locations
+#define CyaSSL_CTX_use_certificate_chain_file   \
+                                            wolfSSL_CTX_use_certificate_chain_file
+#define CyaSSL_CTX_use_certificate_chain_buffer \
+                                            wolfSSL_CTX_use_certificate_chain_buffer
+
+/* Context and Session Setup*/
+#define CyaSSL_new                        wolfSSL_new
+#define CyaSSL_free                       wolfSSL_free
+#define CyaSSL_set_fd                     wolfSSL_set_fd
+#define CyaSSL_CTX_new                    wolfSSL_CTX_new
+#define CyaSSL_CTX_free                   wolfSSL_CTX_free
+#define CyaSSL_SetVersion                 wolfSSL_SetVersion
+#define CyaSSL_set_verify                 wolfSSL_set_verify
+#define CyaSSL_set_session                wolfSSL_set_session
+#define CyaSSL_set_timeout                wolfSSL_set_timeout
+#define CyaSSL_CTX_set_verify             wolfSSL_CTX_set_verify
+#define CyaSSL_CTX_set_timeout            wolfSSL_CTX_set_timeout
+#define CyaSSL_set_cipher_list            wolfSSL_set_cipher_list
+#define CyaSSL_set_compression            wolfSSL_set_compression
+#define CyaTLSv1_client_method            wolfTLSv1_client_method
+#define CyaTLSv1_server_method            wolfTLSv1_server_method
+#define CyaSSLv3_client_method            wolfSSLv3_client_method
+#define CyaSSLv3_server_method            wolfSSLv3_server_method
+#define CyaSSLv23_client_method           wolfSSLv23_client_method
+#define CyaSSLv23_server_method           wolfSSLv23_server_method
+#define CyaDTLSv1_client_method           wolfDTLSv1_client_method
+#define CyaDTLSv1_server_method           wolfDTLSv1_server_method
+#define CyaSSL_check_domain_name          wolfSSL_check_domain_name
+#define CyaTLSv1_1_client_method          wolfTLSv1_1_client_method
+#define CyaTLSv1_1_server_method          wolfTLSv1_1_server_method
+#define CyaTLSv1_2_client_method          wolfTLSv1_2_client_method
+#define CyaTLSv1_2_server_method          wolfTLSv1_2_server_method
+#define CyaDTLSv1_2_client_method         wolfDTLSv1_2_client_method
+#define CyaDTLSv1_2_server_method         wolfDTLSv1_2_server_method
+#define CyaSSL_set_group_messages         wolfSSL_set_group_messages
+#define CyaSSL_set_using_nonblock         wolfSSL_set_using_nonblock
+#define CyaSSL_CTX_set_cipher_list        wolfSSL_CTX_set_cipher_list
+#define CyaSSL_CTX_set_group_messages     wolfSSL_CTX_set_group_messages
+#define CyaSSL_CTX_set_session_cache_mode wolfSSL_CTX_set_session_cache_mode
+
+/* Callbacks */
+
+/* 
+ * Empty commment denotes not listed in CyaSSL Manual
+ * (soon to be wolfSSL Manual) 
+ */
+
+#define CyaSSL_accept_ex              wolfSSL_accept_ex
+#define CyaSSL_SetIORecv              wolfSSL_SetIORecv
+#define CyaSSL_SetIOSend              wolfSSL_SetIOSend
+#define CyaSSL_connect_ex             wolfSSL_connect_ex
+#define CyaSSL_CTX_SetCACb            wolfSSL_CTX_SetCACb
+#define CyaSSL_SetIOReadCtx           wolfSSL_SetIOReadCtx
+#define CyaSSL_SetRsaEncCtx           wolfSSL_SetRsaEncCtx
+#define CyaSSL_GetRsaEncCtx           wolfSSL_GetRsaEncCtx
+#define CyaSSL_SetRsaDecCtx           wolfSSL_SetRsaDecCtx
+#define CyaSSL_GetRsaDecCtx           wolfSSL_GetRsaDecCtx
+#define CyaSSL_SetLoggingCb           wolfSSL_SetLoggingCb
+#define CyaSSL_SetEccSignCtx          wolfSSL_SetEccSignCtx
+#define CyaSSL_GetEccSignCtx          wolfSSL_GetEccSignCtx
+#define CyaSSL_SetRsaSignCtx          wolfSSL_SetRsaSignCtx
+#define CyaSSL_GetRsaSignCtx          wolfSSL_GetRsaSignCtx
+#define CyaSSL_SetIOWriteCtx          wolfSSL_SetIOWriteCtx
+#define CyaSSL_SetIOReadFlags         wolfSSL_SetIOReadFlags
+#define CyaSSL_SetEccVerifyCtx        wolfSSL_SetEccVerifyCtx
+#define CyaSSL_GetEccVerifyCtx        wolfSSL_GetEccVerifyCtx
+#define CyaSSL_SetRsaVerifyCtx        wolfSSL_SetRsaVerifyCtx
+#define CyaSSL_GetRsaVerifyCtx        wolfSSL_GetRsaVerifyCtx
+#define CyaSSL_CTX_SetRsaEncCb        wolfSSL_CTX_SetRsaEncCb
+#define CyaSSL_CTX_SetRsaDecCb        wolfSSL_CTX_SetRsaDecCb
+#define CyaSSL_SetIOWriteFlags        wolfSSL_SetIOWriteFlags
+#define CyaSSL_SetTlsHmacInner        wolfSSL_SetTlsHmacInner
+#define CyaSSL_SetMacEncryptCtx       wolfSSL_SetMacEncryptCtx
+#define CyaSSL_GetMacEncryptCtx       wolfSSL_GetMacEncryptCtx
+#define CyaSSL_CTX_SetEccSignCb       wolfSSL_CTX_SetEccSignCb
+#define CyaSSL_CTX_SetRsaSignCb       wolfSSL_CTX_SetRsaSignCb
+#define CyaSSL_CTX_SetEccVerifyCb     wolfSSL_CTX_SetEccVerifyCb
+#define CyaSSL_CTX_SetRsaVerifyCb     wolfSSL_CTX_SetRsaVerifyCb
+#define CyaSSL_CTX_SetMacEncryptCb    wolfSSL_CTX_SetMacEncryptCb
+#define CyaSSL_SetDecryptVerifyCtx    wolfSSL_SetDecryptVerifyCtx
+#define CyaSSL_GetDecryptVerifyCtx    wolfSSL_GetDecryptVerifyCtx
+#define CyaSSL_CTX_SetDecryptVerifyCb wolfSSL_CTX_SetDecryptVerifyCb
+
+/* psk specific */
+#ifndef NO_PSK
+
+#define CyaSSL_get_psk_identity          wolfSSL_get_psk_identity          /**/
+#define CyaSSL_get_psk_identity_hint     wolfSSL_get_psk_identity_hint     /**/
+#define CyaSSL_use_psk_identity_hint     wolfSSL_use_psk_identity_hint     /**/
+#define CyaSSL_set_psk_client_callback   wolfSSL_set_psk_client_callback   /**/
+#define CyaSSL_set_psk_server_callback   wolfSSL_set_psk_server_callback   /**/
+#define CyaSSL_CTX_use_psk_identity_hint wolfSSL_CTX_use_psk_identity_hint /**/
+#define CyaSSL_CTX_set_psk_client_callback \
+                                      wolfSSL_CTX_set_psk_client_callback  /**/
+#define CyaSSL_CTX_set_psk_server_callback \
+                                      wolfSSL_CTX_set_psk_server_callback  /**/
+
+#endif
+/* end psk specific */
+
+/* Anonymous */
+#define CyaSSL_CTX_allow_anon_cipher wolfSSL_CTX_allow_anon_cipher         /**/
+
+/* Error Handling and Debugging*/
+#define CyaSSL_get_error           wolfSSL_get_error
+#define CyaSSL_want_read           wolfSSL_want_read
+#define CyaSSL_want_write          wolfSSL_want_write
+#define CyaSSL_Debugging_ON        wolfSSL_Debugging_ON
+#define CyaSSL_Debugging_OFF       wolfSSL_Debugging_OFF
+#define CyaSSL_ERR_error_string    wolfSSL_ERR_error_string
+#define CyaSSL_load_error_strings  wolfSSL_load_error_strings
+#define CyaSSL_ERR_error_string_n  wolfSSL_ERR_error_string_n
+#define CyaSSL_ERR_print_errors_fp wolfSSL_ERR_print_errors_fp
+
+/* OCSP and CRL */
+
+/* 
+ * Empty commment denotes not listed in CyaSSL Manual
+ * (soon to be wolfSSL Manual) 
+ */
+
+#define CYASSL_CRL_MONITOR               WOLFSSL_CRL_MONITOR               /**/
+#define CYASSL_CRL_START_MON             WOLFSSL_CRL_START_MON             /**/
+#define CYASSL_OCSP_NO_NONCE             WOLFSSL_OCSP_NO_NONCE             /**/
+#define CYASSL_OCSP_URL_OVERRIDE         WOLFSSL_OCSP_URL_OVERRIDE
+#define CYASSL_OCSP_CHECKALL             WOLFSSL_OCSP_CHECKALL
+
+#define CyaSSL_CTX_EnableOCSP            wolfSSL_CTX_EnableOCSP
+#define CyaSSL_CTX_OCSP_set_options      wolfSSL_CTX_OCSP_set_options      /**/
+#define CyaSSL_CTX_SetOCSP_OverrideURL   wolfSSL_CTX_SetOCSP_OverrideURL   /**/
+#define CyaSSL_CTX_OCSP_set_override_url wolfSSL_CTX_OCSP_set_override_url /**/
+
+/* Informational */
+#define CyaSSL_GetSide            wolfSSL_GetSide
+#define CyaSSL_IsTLSv1_1          wolfSSL_IsTLSv1_1
+#define CyaSSL_GetKeySize         wolfSSL_GetKeySize
+#define CyaSSL_GetHmacSize        wolfSSL_GetHmacSize
+#define CyaSSL_GetHmacType        wolfSSL_GetHmacType
+#define CyaSSL_GetMacSecret       wolfSSL_GetMacSecret
+#define CyaSSL_GetObjectSize      wolfSSL_GetObjectSize
+#define CyaSSL_GetBulkCipher      wolfSSL_GetBulkCipher
+#define CyaSSL_GetCipherType      wolfSSL_GetCipherType
+#define CyaSSL_GetAeadMacSize     wolfSSL_GetAeadMacSize
+#define CyaSSL_GetClientWriteIV   wolfSSL_GetClientWriteIV
+#define CyaSSL_GetServerWriteIV   wolfSSL_GetServerWriteIV
+#define CyaSSL_GetClientWriteKey  wolfSSL_GetClientWriteKey
+#define CyaSSL_GetServerWriteKey  wolfSSL_GetServerWriteKey
+#define CyaSSL_GetCipherBlockSize wolfSSL_GetCipherBlockSize
+
+/* Connection, Session, and I/O */
+#define CyaSSL_peek               wolfSSL_peek
+#define CyaSSL_read               wolfSSL_read
+#define CyaSSL_recv               wolfSSL_recv
+#define CyaSSL_send               wolfSSL_send
+#define CyaSSL_write              wolfSSL_write
+#define CyaSSL_writev             wolfSSL_writev
+#define CyaSSL_accept             wolfSSL_accept
+#define CyaSSL_get_fd             wolfSSL_get_fd
+#define CyaSSL_connect            wolfSSL_connect
+#define CyaSSL_pending            wolfSSL_pending
+#define CyaSSL_negotiate          wolfSSL_negotiate
+#define CyaSSL_get_session        wolfSSL_get_session
+#define CyaSSL_connect_cert       wolfSSL_connect_cert
+#define CyaSSL_flush_sessions     wolfSSL_flush_sessions
+#define CyaSSL_get_using_nonblock wolfSSL_get_using_nonblock
+#define CyaSSL_PrintSessionStats  wolfSSL_PrintSessionStats
+
+/* DTLS Specific */
+#define CyaSSL_dtls                     wolfSSL_dtls
+#define CyaSSL_dtls_set_peer            wolfSSL_dtls_set_peer
+#define CyaSSL_dtls_get_peer            wolfSSL_dtls_get_peer
+#define CyaSSL_dtls_got_timeout         wolfSSL_dtls_got_timeout
+#define CyaSSL_dtls_get_current_timeout wolfSSL_dtls_get_current_timeout
+
+/* Certificate Manager */
+#define CyaSSL_CertManagerNew          wolfSSL_CertManagerNew
+#define CyaSSL_CertManagerFree         wolfSSL_CertManagerFree
+#define CyaSSL_CertManagerLoadCA       wolfSSL_CertManagerLoadCA
+#define CyaSSL_CertManagerVerify       wolfSSL_CertManagerVerify
+#define CyaSSL_CertManagerEnableCRL    wolfSSL_CertManagerEnableCRL
+#define CyaSSL_CertManagerDisableCRL   wolfSSL_CertManagerDisableCRL
+#define CyaSSL_CertManagerVerifyBuffer wolfSSL_CertManagerVerifyBuffer
+#ifndef NO_CERTS
+	#define CyaSSL_CertManagerCheckCRL   wolfSSL_CertManagerCheckCRL
+	#define CyaSSL_CertManagerLoadCRL    wolfSSL_CertManagerLoadCRL
+	#define CyaSSL_CertManagerSetCRL_Cb  wolfSSL_CertManagerSetCRL_Cb
+	#define CyaSSL_CertManagerCheckOCSP  wolfSSL_CertManagerCheckOCSP
+	#define CyaSSL_CertManagerSetOCSP_Cb wolfSSL_CertManagerSetOCSP_Cb
+	#define CyaSSL_CertManagerSetOCSPOverrideURL \
+                                          wolfSSL_CertManagerSetOCSPOverrideURL
+
+	#define CyaSSL_DisableCRL          wolfSSL_DisableCRL
+	#define CyaSSL_EnableOCSP          wolfSSL_EnableOCSP
+	#define CyaSSL_DisableOCSP         wolfSSL_DisableOCSP
+	#define CyaSSL_SetOCSP_OverrideURL wolfSSL_SetOCSP_OverrideURL
+	#define CyaSSL_SetOCSP_Cb          wolfSSL_SetOCSP_Cb
+
+	#define CyaSSL_CTX_EnableCRL   wolfSSL_CTX_EnableCRL
+	#define CyaSSL_CTX_DisableCRL  wolfSSL_CTX_DisableCRL
+	#define CyaSSL_CTX_LoadCRL     wolfSSL_CTX_LoadCRL
+	#define CyaSSL_CTX_SetCRL_Cb   wolfSSL_CTX_SetCRL_Cb
+	#define CyaSSL_CTX_DisableOCSP wolfSSL_CTX_DisableOCSP
+	#define CyaSSL_CTX_SetOCSP_Cb  wolfSSL_CTX_SetOCSP_Cb
+#endif /* !NO_CERTS */
+
+
+/* OpenSSL Compatibility Layer */
+#define CyaSSL_PemCertToDer               wolfSSL_PemCertToDer
+#define CyaSSL_get_sessionID              wolfSSL_get_sessionID
+#define CyaSSL_get_peer_count             wolfSSL_get_peer_count
+#define CyaSSL_get_chain_cert             wolfSSL_get_chain_cert
+#define CyaSSL_get_peer_chain             wolfSSL_get_peer_chain
+#define CyaSSL_get_peer_length            wolfSSL_get_peer_length
+#define CyaSSL_get_chain_cert_pem         wolfSSL_get_chain_cert_pem
+#define CyaSSL_use_PrivateKey_file        wolfSSL_use_PrivateKey_file
+#define CyaSSL_use_certificate_file       wolfSSL_use_certificate_file
+#define CyaSSL_use_RSAPrivateKey_file     wolfSSL_use_RSAPrivateKey_file
+#define CyaSSL_X509_get_serial_number     wolfSSL_X509_get_serial_number
+#define CyaSSL_CTX_use_RSAPrivateKey_file wolfSSL_CTX_use_RSAPrivateKey_file
+#define CyaSSL_use_certificate_chain_file wolfSSL_use_certificate_chain_file
+
+/* TLS Extensions */
+#define CYASSL_SNI_HOST_NAME         WOLFSSL_SNI_HOST_NAME
+
+#define CyaSSL_UseSNI                wolfSSL_UseSNI
+#define CyaSSL_CTX_UseSNI            wolfSSL_CTX_UseSNI
+#define CyaSSL_SNI_SetOptions        wolfSSL_SNI_SetOptions
+#define CyaSSL_SNI_GetRequest        wolfSSL_SNI_GetRequest
+#define CyaSSL_UseMaxFragment        wolfSSL_UseMaxFragment
+#define CyaSSL_UseTruncatedHMAC      wolfSSL_UseTruncatedHMAC
+#define CyaSSL_UseSupportedCurve     wolfSSL_UseSupportedCurve
+#define CyaSSL_SNI_GetFromBuffer     wolfSSL_SNI_GetFromBuffer
+#define CyaSSL_CTX_SNI_SetOptions    wolfSSL_CTX_SNI_SetOptions
+#define CyaSSL_CTX_UseMaxFragment    wolfSSL_CTX_UseMaxFragment
+#define CyaSSL_CTX_UseTruncatedHMAC  wolfSSL_CTX_UseTruncatedHMAC
+#define CyaSSL_CTX_UseSupportedCurve wolfSSL_CTX_UseSupportedCurve
+
+/* End wolfssl -> cyassl -> openssl compatibility */
+
+/* JRB macro redefinitions and api calls for cryptography for reverse compat. */
+
+#ifdef WOLFSSL_SMALL_STACK
+    #define CYASSL_SMALL_STACK
+#endif
+
+
+/*
+ * wrapper around macros until they are changed in cyassl code
+ * needs investigation in regards to macros in fips
+ */
+#define NO_WOLFSSL_ALLOC_ALIGN NO_CYASSL_ALLOC_ALIGN /* @TODO */
+
+
+/* examples/client/client.h */
+#define CYASSL_THREAD WOLFSSL_THREAD
+#ifdef WOLFSSL_DTLS
+    #define CYASSL_DTLS   WOLFSSL_DTLS
+#endif
+
+/* examples/client/client.c */
+#define LIBCYASSL_VERSION_STRING LIBWOLFSSL_VERSION_STRING
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+
+#endif /* CyaSSL_openssl_h__ */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/version.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/version.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/cyassl/version.h	(revision 164)
@@ -0,0 +1,26 @@
+/* cyassl/version.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wolfssl/version.h>
+
+#define LIBCYASSL_VERSION_STRING LIBWOLFSSL_VERSION_STRING
+#define LIBCYASSL_VERSION_HEX LIBWOLFSSL_VERSION_HEX
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/error-ssl.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/error-ssl.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/error-ssl.h	(revision 164)
@@ -0,0 +1,172 @@
+/* error-ssl.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef WOLFSSL_ERROR_H
+#define WOLFSSL_ERROR_H
+
+#include <wolfssl/wolfcrypt/error-crypt.h>   /* pull in wolfCrypt errors */
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+enum wolfSSL_ErrorCodes {
+    INPUT_CASE_ERROR        = -301,        /* process input state error */
+    PREFIX_ERROR            = -302,        /* bad index to key rounds  */
+    MEMORY_ERROR            = -303,        /* out of memory            */
+    VERIFY_FINISHED_ERROR   = -304,        /* verify problem on finished */
+    VERIFY_MAC_ERROR        = -305,        /* verify mac problem       */
+    PARSE_ERROR             = -306,        /* parse error on header    */
+    UNKNOWN_HANDSHAKE_TYPE  = -307,        /* weird handshake type     */
+    SOCKET_ERROR_E          = -308,        /* error state on socket    */
+    SOCKET_NODATA           = -309,        /* expected data, not there */
+    INCOMPLETE_DATA         = -310,        /* don't have enough data to
+                                              complete task            */
+    UNKNOWN_RECORD_TYPE     = -311,        /* unknown type in record hdr */
+    DECRYPT_ERROR           = -312,        /* error during decryption  */
+    FATAL_ERROR             = -313,        /* recvd alert fatal error  */
+    ENCRYPT_ERROR           = -314,        /* error during encryption  */
+    FREAD_ERROR             = -315,        /* fread problem            */
+    NO_PEER_KEY             = -316,        /* need peer's key          */
+    NO_PRIVATE_KEY          = -317,        /* need the private key     */
+    RSA_PRIVATE_ERROR       = -318,        /* error during rsa priv op */
+    NO_DH_PARAMS            = -319,        /* server missing DH params */
+    BUILD_MSG_ERROR         = -320,        /* build message failure    */
+
+    BAD_HELLO               = -321,        /* client hello malformed   */
+    DOMAIN_NAME_MISMATCH    = -322,        /* peer subject name mismatch */
+    WANT_READ               = -323,        /* want read, call again    */
+    NOT_READY_ERROR         = -324,        /* handshake layer not ready */
+    PMS_VERSION_ERROR       = -325,        /* pre m secret version error */
+    VERSION_ERROR           = -326,        /* record layer version error */
+    WANT_WRITE              = -327,        /* want write, call again   */
+    BUFFER_ERROR            = -328,        /* malformed buffer input   */
+    VERIFY_CERT_ERROR       = -329,        /* verify cert error        */
+    VERIFY_SIGN_ERROR       = -330,        /* verify sign error        */
+    CLIENT_ID_ERROR         = -331,        /* psk client identity error  */
+    SERVER_HINT_ERROR       = -332,        /* psk server hint error  */
+    PSK_KEY_ERROR           = -333,        /* psk key error  */
+    ZLIB_INIT_ERROR         = -334,        /* zlib init error  */
+    ZLIB_COMPRESS_ERROR     = -335,        /* zlib compression error  */
+    ZLIB_DECOMPRESS_ERROR   = -336,        /* zlib decompression error  */
+
+    GETTIME_ERROR           = -337,        /* gettimeofday failed ??? */
+    GETITIMER_ERROR         = -338,        /* getitimer failed ??? */
+    SIGACT_ERROR            = -339,        /* sigaction failed ??? */
+    SETITIMER_ERROR         = -340,        /* setitimer failed ??? */
+    LENGTH_ERROR            = -341,        /* record layer length error */
+    PEER_KEY_ERROR          = -342,        /* can't decode peer key */
+    ZERO_RETURN             = -343,        /* peer sent close notify */
+    SIDE_ERROR              = -344,        /* wrong client/server type */
+    NO_PEER_CERT            = -345,        /* peer didn't send key */
+    NTRU_KEY_ERROR          = -346,        /* NTRU key error  */
+    NTRU_DRBG_ERROR         = -347,        /* NTRU drbg error  */
+    NTRU_ENCRYPT_ERROR      = -348,        /* NTRU encrypt error  */
+    NTRU_DECRYPT_ERROR      = -349,        /* NTRU decrypt error  */
+    ECC_CURVETYPE_ERROR     = -350,        /* Bad ECC Curve Type */
+    ECC_CURVE_ERROR         = -351,        /* Bad ECC Curve */
+    ECC_PEERKEY_ERROR       = -352,        /* Bad Peer ECC Key */
+    ECC_MAKEKEY_ERROR       = -353,        /* Bad Make ECC Key */
+    ECC_EXPORT_ERROR        = -354,        /* Bad ECC Export Key */
+    ECC_SHARED_ERROR        = -355,        /* Bad ECC Shared Secret */
+    NOT_CA_ERROR            = -357,        /* Not a CA cert error */
+    BAD_PATH_ERROR          = -358,        /* Bad path for opendir */
+    BAD_CERT_MANAGER_ERROR  = -359,        /* Bad Cert Manager */
+    OCSP_CERT_REVOKED       = -360,        /* OCSP Certificate revoked */
+    CRL_CERT_REVOKED        = -361,        /* CRL Certificate revoked */
+    CRL_MISSING             = -362,        /* CRL Not loaded */
+    MONITOR_RUNNING_E       = -363,        /* CRL Monitor already running */
+    THREAD_CREATE_E         = -364,        /* Thread Create Error */
+    OCSP_NEED_URL           = -365,        /* OCSP need an URL for lookup */
+    OCSP_CERT_UNKNOWN       = -366,        /* OCSP responder doesn't know */
+    OCSP_LOOKUP_FAIL        = -367,        /* OCSP lookup not successful */
+    MAX_CHAIN_ERROR         = -368,        /* max chain depth exceeded */
+    COOKIE_ERROR            = -369,        /* dtls cookie error */
+    SEQUENCE_ERROR          = -370,        /* dtls sequence error */
+    SUITES_ERROR            = -371,        /* suites pointer error */
+    SSL_NO_PEM_HEADER       = -372,        /* no PEM header found */
+    OUT_OF_ORDER_E          = -373,        /* out of order message */
+    BAD_KEA_TYPE_E          = -374,        /* bad KEA type found */
+    SANITY_CIPHER_E         = -375,        /* sanity check on cipher error */
+    RECV_OVERFLOW_E         = -376,        /* RXCB returned more than rqed */
+    GEN_COOKIE_E            = -377,        /* Generate Cookie Error */
+    NO_PEER_VERIFY          = -378,        /* Need peer cert verify Error */
+    FWRITE_ERROR            = -379,        /* fwrite problem */
+    CACHE_MATCH_ERROR       = -380,        /* chache hdr match error */
+    UNKNOWN_SNI_HOST_NAME_E = -381,        /* Unrecognized host name Error */
+    UNKNOWN_MAX_FRAG_LEN_E  = -382,        /* Unrecognized max frag len Error */
+    KEYUSE_SIGNATURE_E      = -383,        /* KeyUse digSignature error */
+    KEYUSE_ENCIPHER_E       = -385,        /* KeyUse keyEncipher error */
+    EXTKEYUSE_AUTH_E        = -386,        /* ExtKeyUse server|client_auth */
+    SEND_OOB_READ_E         = -387,        /* Send Cb out of bounds read */
+    SECURE_RENEGOTIATION_E  = -388,        /* Invalid Renegotiation Info */
+    SESSION_TICKET_LEN_E    = -389,        /* Session Ticket too large */
+    SESSION_TICKET_EXPECT_E = -390,        /* Session Ticket missing   */
+    SCR_DIFFERENT_CERT_E    = -391,        /* SCR Different cert error  */
+    SESSION_SECRET_CB_E     = -392,        /* Session secret Cb fcn failure */
+    NO_CHANGE_CIPHER_E      = -393,        /* Finished before change cipher */
+    SANITY_MSG_E            = -394,        /* Sanity check on msg order error */
+    DUPLICATE_MSG_E         = -395,        /* Duplicate message error */
+    SNI_UNSUPPORTED         = -396,        /* SSL 3.0 does not support SNI */
+    SOCKET_PEER_CLOSED_E    = -397,        /* Underlying transport closed */
+
+    BAD_TICKET_KEY_CB_SZ    = -398,        /* Bad session ticket key cb size */
+    BAD_TICKET_MSG_SZ       = -399,        /* Bad session ticket msg size    */
+    BAD_TICKET_ENCRYPT      = -400,        /* Bad user ticket encrypt        */
+
+    DH_KEY_SIZE_E           = -401,        /* DH Key too small */
+    SNI_ABSENT_ERROR        = -402,        /* No SNI request. */
+    RSA_SIGN_FAULT          = -403,        /* RSA Sign fault */
+    HANDSHAKE_SIZE_ERROR    = -404,        /* Handshake message too large */
+
+    UNKNOWN_ALPN_PROTOCOL_NAME_E = -405,   /* Unrecognized protocol name Error*/
+
+    /* add strings to SetErrorString !!!!! */
+
+    /* begin negotiation parameter errors */
+    UNSUPPORTED_SUITE       = -500,        /* unsupported cipher suite */
+    MATCH_SUITE_ERROR       = -501         /* can't match cipher suite */
+    /* end negotiation parameter errors only 10 for now */
+    /* add strings to SetErrorString !!!!! */
+
+    /* no error stings go down here, add above negotiation errors !!!! */
+};
+
+
+#ifdef WOLFSSL_CALLBACKS
+    enum {
+        MIN_PARAM_ERR = UNSUPPORTED_SUITE,
+        MAX_PARAM_ERR = MIN_PARAM_ERR - 10
+    };
+#endif
+
+
+WOLFSSL_LOCAL
+void SetErrorString(int err, char* buff);
+
+
+#ifdef __cplusplus
+    }  /* extern "C" */
+#endif
+
+
+#endif /* wolfSSL_ERROR_H */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/internal.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/internal.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/internal.h	(revision 164)
@@ -0,0 +1,2724 @@
+/* internal.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as wolfSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef WOLFSSL_INT_H
+#define WOLFSSL_INT_H
+
+
+#include <wolfssl/wolfcrypt/types.h>
+#include <wolfssl/ssl.h>
+#ifdef HAVE_CRL
+    #include <wolfssl/crl.h>
+#endif
+#include <wolfssl/wolfcrypt/random.h>
+#ifndef NO_DES3
+    #include <wolfssl/wolfcrypt/des3.h>
+#endif
+#ifndef NO_HC128
+    #include <wolfssl/wolfcrypt/hc128.h>
+#endif
+#ifndef NO_RABBIT
+    #include <wolfssl/wolfcrypt/rabbit.h>
+#endif
+#ifdef HAVE_CHACHA
+    #include <wolfssl/wolfcrypt/chacha.h>
+#endif
+#ifndef NO_ASN
+    #include <wolfssl/wolfcrypt/asn.h>
+#endif
+#ifndef NO_MD5
+    #include <wolfssl/wolfcrypt/md5.h>
+#endif
+#ifndef NO_SHA
+    #include <wolfssl/wolfcrypt/sha.h>
+#endif
+#ifndef NO_AES
+    #include <wolfssl/wolfcrypt/aes.h>
+#endif
+#ifdef HAVE_POLY1305
+    #include <wolfssl/wolfcrypt/poly1305.h>
+#endif
+#ifdef HAVE_CAMELLIA
+    #include <wolfssl/wolfcrypt/camellia.h>
+#endif
+#include <wolfssl/wolfcrypt/logging.h>
+#ifndef NO_HMAC
+    #include <wolfssl/wolfcrypt/hmac.h>
+#endif
+#ifndef NO_RC4
+    #include <wolfssl/wolfcrypt/arc4.h>
+#endif
+#ifdef HAVE_ECC
+    #include <wolfssl/wolfcrypt/ecc.h>
+#endif
+#ifndef NO_SHA256
+    #include <wolfssl/wolfcrypt/sha256.h>
+#endif
+#ifdef HAVE_OCSP
+    #include <wolfssl/ocsp.h>
+#endif
+#ifdef WOLFSSL_SHA512
+    #include <wolfssl/wolfcrypt/sha512.h>
+#endif
+
+#ifdef HAVE_AESGCM
+    #include <wolfssl/wolfcrypt/sha512.h>
+#endif
+
+#ifdef WOLFSSL_RIPEMD
+    #include <wolfssl/wolfcrypt/ripemd.h>
+#endif
+
+#ifdef HAVE_IDEA
+    #include <wolfssl/wolfcrypt/idea.h>
+#endif
+
+#include <wolfssl/wolfcrypt/hash.h>
+
+#ifdef WOLFSSL_CALLBACKS
+    #include <wolfssl/callbacks.h>
+    #include <signal.h>
+#endif
+
+#ifdef USE_WINDOWS_API
+    #ifdef WOLFSSL_GAME_BUILD
+        #include "system/xtl.h"
+    #else
+        #if defined(_WIN32_WCE) || defined(WIN32_LEAN_AND_MEAN)
+            /* On WinCE winsock2.h must be included before windows.h */
+            #include <winsock2.h>
+        #endif
+        #include <windows.h>
+    #endif
+#elif defined(THREADX)
+    #ifndef SINGLE_THREADED
+        #include "tx_api.h"
+    #endif
+#elif defined(MICRIUM)
+    /* do nothing, just don't pick Unix */
+#elif defined(FREERTOS) || defined(FREERTOS_TCP) || defined(WOLFSSL_SAFERTOS)
+    /* do nothing */
+#elif defined(EBSNET)
+    /* do nothing */
+#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+    /* do nothing */
+#elif defined(WOLFSSL_uITRON4)
+        /* do nothing */
+#elif defined(WOLFSSL_uTKERNEL2)
+        /* do nothing */
+#elif defined(WOLFSSL_MDK_ARM)
+    #if defined(WOLFSSL_MDK5)
+         #include "cmsis_os.h"
+    #else
+        #include <rtl.h>
+    #endif
+#elif defined(WOLFSSL_CMSIS_RTOS)
+    #include "cmsis_os.h"
+#elif defined(MBED)
+#elif defined(WOLFSSL_TIRTOS)
+    /* do nothing */
+#else
+    #ifndef SINGLE_THREADED
+        #define WOLFSSL_PTHREADS
+        #include <pthread.h>
+    #endif
+    #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
+        #include <unistd.h>      /* for close of BIO */
+    #endif
+#endif
+
+
+#ifdef HAVE_LIBZ
+    #include "zlib.h"
+#endif
+
+#ifdef _MSC_VER
+    /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
+    #pragma warning(disable: 4996)
+#endif
+
+#ifdef NO_AES
+    #if !defined (ALIGN16)
+        #define ALIGN16
+    #endif
+#endif
+
+#ifdef NO_SHA
+    #define SHA_DIGEST_SIZE 20
+#endif
+
+#ifdef NO_SHA256
+    #define SHA256_DIGEST_SIZE 32
+#endif
+
+#ifdef NO_MD5
+    #define MD5_DIGEST_SIZE 16
+#endif
+
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+#ifdef USE_WINDOWS_API
+    typedef unsigned int SOCKET_T;
+#else
+    typedef int SOCKET_T;
+#endif
+
+
+typedef byte word24[3];
+
+/* Define or comment out the cipher suites you'd like to be compiled in
+   make sure to use at least one BUILD_SSL_xxx or BUILD_TLS_xxx is defined
+
+   When adding cipher suites, add name to cipher_names, idx to cipher_name_idx
+
+   Now that there is a maximum strength crypto build, the following BUILD_XXX
+   flags need to be divided into two groups selected by WOLFSSL_MAX_STRENGTH.
+   Those that do not use Perfect Forward Security and do not use AEAD ciphers
+   need to be switched off. Allowed suites use (EC)DHE, AES-GCM|CCM, or
+   CHACHA-POLY.
+*/
+
+/* Check that if WOLFSSL_MAX_STRENGTH is set that all the required options are
+ * not turned off. */
+#if defined(WOLFSSL_MAX_STRENGTH) && \
+    ((!defined(HAVE_ECC) && (defined(NO_DH) || defined(NO_RSA))) || \
+     (!defined(HAVE_AESGCM) && !defined(HAVE_AESCCM) && \
+      (!defined(HAVE_POLY1305) || !defined(HAVE_CHACHA))) || \
+     (defined(NO_SHA256) && !defined(WOLFSSL_SHA384)) || \
+     !defined(NO_OLD_TLS))
+
+    #error "You are trying to build max strength with requirements disabled."
+#endif
+
+/* Have QSH : Quantum-safe Handshake */
+#if defined(HAVE_QSH)
+    #define BUILD_TLS_QSH
+#endif
+
+#ifndef WOLFSSL_MAX_STRENGTH
+
+    #if !defined(NO_RSA) && !defined(NO_RC4)
+        #if defined(WOLFSSL_STATIC_RSA)
+            #if !defined(NO_SHA)
+                #define BUILD_SSL_RSA_WITH_RC4_128_SHA
+            #endif
+            #if !defined(NO_MD5)
+                #define BUILD_SSL_RSA_WITH_RC4_128_MD5
+            #endif
+        #endif
+        #if !defined(NO_TLS) && defined(HAVE_NTRU) && !defined(NO_SHA)
+            #define BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
+        #endif
+    #endif
+
+    #if !defined(NO_RSA) && !defined(NO_DES3)
+        #if !defined(NO_SHA)
+            #if defined(WOLFSSL_STATIC_RSA)
+                #define BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
+            #endif
+            #if !defined(NO_TLS) && defined(HAVE_NTRU)
+                    #define BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
+            #endif
+        #endif
+    #endif
+
+    #if !defined(NO_RSA) && defined(HAVE_IDEA)
+        #if !defined(NO_SHA) && defined(WOLFSSL_STATIC_RSA)
+            #define BUILD_SSL_RSA_WITH_IDEA_CBC_SHA
+        #endif
+    #endif
+
+    #if !defined(NO_RSA) && !defined(NO_AES) && !defined(NO_TLS)
+        #if !defined(NO_SHA)
+            #if defined(WOLFSSL_STATIC_RSA)
+                #define BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
+                #define BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
+            #endif
+            #if defined(HAVE_NTRU)
+                    #define BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
+                    #define BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
+            #endif
+        #endif
+        #if defined(WOLFSSL_STATIC_RSA)
+            #if !defined (NO_SHA256)
+                #define BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
+                #define BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
+            #endif
+            #if defined (HAVE_AESGCM)
+                #define BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
+                #if defined (WOLFSSL_SHA384)
+                    #define BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
+                #endif
+            #endif
+            #if defined (HAVE_AESCCM)
+                #define BUILD_TLS_RSA_WITH_AES_128_CCM_8
+                #define BUILD_TLS_RSA_WITH_AES_256_CCM_8
+            #endif
+            #if defined(HAVE_BLAKE2)
+                #define BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
+                #define BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
+            #endif
+        #endif
+    #endif
+
+    #if defined(HAVE_CAMELLIA) && !defined(NO_TLS)
+        #ifndef NO_RSA
+          #if defined(WOLFSSL_STATIC_RSA)
+            #if !defined(NO_SHA)
+                #define BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+                #define BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+            #endif
+            #ifndef NO_SHA256
+                #define BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+                #define BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+            #endif
+          #endif
+            #if !defined(NO_DH)
+              #if !defined(NO_SHA)
+                #define BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+                #define BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+              #endif
+                #ifndef NO_SHA256
+                    #define BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+                    #define BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+                #endif
+            #endif
+        #endif
+    #endif
+
+#if defined(WOLFSSL_STATIC_PSK)
+    #if !defined(NO_PSK) && !defined(NO_AES) && !defined(NO_TLS)
+        #if !defined(NO_SHA)
+            #define BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
+            #define BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
+        #endif
+        #ifndef NO_SHA256
+            #define BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
+            #ifdef HAVE_AESGCM
+                #define BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
+            #endif
+            #ifdef HAVE_AESCCM
+                #define BUILD_TLS_PSK_WITH_AES_128_CCM_8
+                #define BUILD_TLS_PSK_WITH_AES_256_CCM_8
+                #define BUILD_TLS_PSK_WITH_AES_128_CCM
+                #define BUILD_TLS_PSK_WITH_AES_256_CCM
+            #endif
+        #endif
+        #ifdef WOLFSSL_SHA384
+            #define BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
+            #ifdef HAVE_AESGCM
+                #define BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
+            #endif
+        #endif
+    #endif
+#endif
+
+    #if !defined(NO_TLS) && defined(HAVE_NULL_CIPHER)
+        #if !defined(NO_RSA)
+            #if defined(WOLFSSL_STATIC_RSA)
+                #if !defined(NO_SHA)
+                    #define BUILD_TLS_RSA_WITH_NULL_SHA
+                #endif
+                #ifndef NO_SHA256
+                    #define BUILD_TLS_RSA_WITH_NULL_SHA256
+                #endif
+            #endif
+        #endif
+        #if !defined(NO_PSK) && defined(WOLFSSL_STATIC_PSK)
+            #if !defined(NO_SHA)
+                #define BUILD_TLS_PSK_WITH_NULL_SHA
+            #endif
+            #ifndef NO_SHA256
+                #define BUILD_TLS_PSK_WITH_NULL_SHA256
+            #endif
+            #ifdef WOLFSSL_SHA384
+                #define BUILD_TLS_PSK_WITH_NULL_SHA384
+            #endif
+        #endif
+    #endif
+
+#if defined(WOLFSSL_STATIC_RSA)
+    #if !defined(NO_HC128) && !defined(NO_RSA) && !defined(NO_TLS)
+        #ifndef NO_MD5
+            #define BUILD_TLS_RSA_WITH_HC_128_MD5
+        #endif
+        #if !defined(NO_SHA)
+            #define BUILD_TLS_RSA_WITH_HC_128_SHA
+        #endif
+        #if defined(HAVE_BLAKE2)
+            #define BUILD_TLS_RSA_WITH_HC_128_B2B256
+        #endif
+    #endif
+
+    #if !defined(NO_RABBIT) && !defined(NO_TLS) && !defined(NO_RSA)
+        #if !defined(NO_SHA)
+            #define BUILD_TLS_RSA_WITH_RABBIT_SHA
+        #endif
+    #endif
+#endif
+
+    #if !defined(NO_DH) && !defined(NO_AES) && !defined(NO_TLS) && \
+        !defined(NO_RSA)
+
+        #if !defined(NO_SHA)
+            #define BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+            #define BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+        #endif
+        #if !defined(NO_SHA256)
+            #define BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+            #define BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+        #endif
+    #endif
+
+    #if defined(HAVE_ANON) && !defined(NO_TLS) && !defined(NO_DH) && \
+        !defined(NO_AES) && !defined(NO_SHA)
+        #define BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
+    #endif
+
+    #if !defined(NO_DH) && !defined(NO_PSK) && !defined(NO_TLS)
+        #ifndef NO_SHA256
+            #ifndef NO_AES
+                #define BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+            #endif
+            #ifdef HAVE_NULL_CIPHER
+                #define BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
+            #endif
+        #endif
+        #ifdef WOLFSSL_SHA384
+            #ifndef NO_AES
+                #define BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+            #endif
+            #ifdef HAVE_NULL_CIPHER
+                #define BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
+            #endif
+        #endif
+    #endif
+
+    #if defined(HAVE_ECC) && !defined(NO_TLS)
+        #if !defined(NO_AES)
+            #if !defined(NO_SHA)
+                #if !defined(NO_RSA)
+                    #define BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+                    #define BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+                    #if defined(WOLFSSL_STATIC_DH)
+                        #define BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+                        #define BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+                    #endif
+                #endif
+
+                #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+                #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+
+                #if defined(WOLFSSL_STATIC_DH)
+                    #define BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+                    #define BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+                #endif
+            #endif /* NO_SHA */
+            #ifndef NO_SHA256
+                #if !defined(NO_RSA)
+                    #define BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+                    #if defined(WOLFSSL_STATIC_DH)
+                        #define BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+                    #endif
+                #endif
+                #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+                #if defined(WOLFSSL_STATIC_DH)
+                    #define BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+                #endif
+            #endif
+
+            #ifdef WOLFSSL_SHA384
+                #if !defined(NO_RSA)
+                    #define BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+                    #if defined(WOLFSSL_STATIC_DH)
+                        #define BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+                    #endif
+                #endif
+                #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+                #if defined(WOLFSSL_STATIC_DH)
+                    #define BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+                #endif
+            #endif
+
+            #if defined (HAVE_AESGCM)
+                #if !defined(NO_RSA)
+                    #if defined(WOLFSSL_STATIC_DH)
+                        #define BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+                    #endif
+                    #if defined(WOLFSSL_SHA384)
+                        #if defined(WOLFSSL_STATIC_DH)
+                            #define BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+                        #endif
+                    #endif
+                #endif
+
+                #if defined(WOLFSSL_STATIC_DH)
+                    #define BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+                #endif
+
+                #if defined(WOLFSSL_SHA384)
+                    #if defined(WOLFSSL_STATIC_DH)
+                        #define BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+                    #endif
+                #endif
+            #endif
+        #endif /* NO_AES */
+        #if !defined(NO_RC4)
+            #if !defined(NO_SHA)
+                #if !defined(NO_RSA)
+                    #define BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+                    #if defined(WOLFSSL_STATIC_DH)
+                        #define BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
+                    #endif
+                #endif
+
+                #define BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+                #if defined(WOLFSSL_STATIC_DH)
+                    #define BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+                #endif
+            #endif
+        #endif
+        #if !defined(NO_DES3)
+            #ifndef NO_SHA
+                #if !defined(NO_RSA)
+                    #define BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+                    #if defined(WOLFSSL_STATIC_DH)
+                        #define BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+                    #endif
+                #endif
+
+                #define BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+                #if defined(WOLFSSL_STATIC_DH)
+                    #define BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+                #endif
+            #endif /* NO_SHA */
+        #endif
+    #endif
+
+#endif /* !WOLFSSL_MAX_STRENGTH */
+
+#if !defined(NO_DH) && !defined(NO_AES) && !defined(NO_TLS) && \
+    !defined(NO_RSA) && defined(HAVE_AESGCM)
+
+    #ifndef NO_SHA256
+        #define BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+    #endif
+
+    #ifdef WOLFSSL_SHA384
+        #define BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+    #endif
+#endif
+
+#if !defined(NO_DH) && !defined(NO_PSK) && !defined(NO_TLS)
+    #ifndef NO_SHA256
+        #ifdef HAVE_AESGCM
+            #define BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+        #endif
+        #ifdef HAVE_AESCCM
+            #define BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
+            #define BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
+        #endif
+    #endif
+    #if defined(WOLFSSL_SHA384) && defined(HAVE_AESGCM)
+        #define BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+    #endif
+#endif
+
+#if defined(HAVE_ECC) && !defined(NO_TLS) && !defined(NO_AES)
+    #ifdef HAVE_AESGCM
+        #ifndef NO_SHA256
+            #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+            #ifndef NO_RSA
+                #define BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+            #endif
+        #endif
+        #ifdef WOLFSSL_SHA384
+            #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+            #ifndef NO_RSA
+                #define BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+            #endif
+        #endif
+    #endif
+    #if defined(HAVE_AESCCM) && !defined(NO_SHA256)
+        #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+        #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
+    #endif
+#endif
+
+#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(NO_SHA256)
+    #ifdef HAVE_ECC
+        #define BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+        #ifndef NO_RSA
+            #define BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+        #endif
+    #endif
+    #if !defined(NO_DH) && !defined(NO_RSA)
+        #define BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    #endif
+#endif
+
+
+#if defined(BUILD_SSL_RSA_WITH_RC4_128_SHA) || \
+    defined(BUILD_SSL_RSA_WITH_RC4_128_MD5)
+    #define BUILD_ARC4
+#endif
+
+#if defined(BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA)
+    #define BUILD_DES3
+#endif
+
+#if defined(BUILD_TLS_RSA_WITH_AES_128_CBC_SHA) || \
+    defined(BUILD_TLS_RSA_WITH_AES_256_CBC_SHA) || \
+    defined(BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256) || \
+    defined(BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256)
+    #undef  BUILD_AES
+    #define BUILD_AES
+#endif
+
+#if defined(BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256) || \
+    defined(BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256) || \
+    defined(BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) || \
+    defined(BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256) || \
+    defined(BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256)
+    #define BUILD_AESGCM
+#endif
+
+#if defined(BUILD_TLS_RSA_WITH_HC_128_SHA) || \
+    defined(BUILD_TLS_RSA_WITH_HC_128_MD5) || \
+    defined(BUILD_TLS_RSA_WITH_HC_128_B2B256)
+    #define BUILD_HC128
+#endif
+
+#if defined(BUILD_TLS_RSA_WITH_RABBIT_SHA)
+    #define BUILD_RABBIT
+#endif
+
+#ifdef NO_DES3
+    #define DES_BLOCK_SIZE 8
+#else
+    #undef  BUILD_DES3
+    #define BUILD_DES3
+#endif
+
+#ifdef NO_AES
+    #define AES_BLOCK_SIZE 16
+#else
+    #undef  BUILD_AES
+    #define BUILD_AES
+#endif
+
+#ifndef NO_RC4
+    #undef  BUILD_ARC4
+    #define BUILD_ARC4
+#endif
+
+#ifdef HAVE_CHACHA
+    #define CHACHA20_BLOCK_SIZE 16
+#endif
+
+#if defined(WOLFSSL_MAX_STRENGTH) || \
+    defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \
+    (defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
+
+    #define HAVE_AEAD
+#endif
+
+#if defined(WOLFSSL_MAX_STRENGTH) || \
+    defined(HAVE_ECC) || !defined(NO_DH)
+
+    #define HAVE_PFS
+#endif
+
+#if defined(BUILD_SSL_RSA_WITH_IDEA_CBC_SHA)
+    #define BUILD_IDEA
+#endif
+
+/* actual cipher values, 2nd byte */
+enum {
+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA  = 0x39,
+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA  = 0x33,
+    TLS_DH_anon_WITH_AES_128_CBC_SHA  = 0x34,
+    TLS_RSA_WITH_AES_256_CBC_SHA      = 0x35,
+    TLS_RSA_WITH_AES_128_CBC_SHA      = 0x2F,
+    TLS_RSA_WITH_NULL_SHA             = 0x02,
+    TLS_PSK_WITH_AES_256_CBC_SHA      = 0x8d,
+    TLS_PSK_WITH_AES_128_CBC_SHA256   = 0xae,
+    TLS_PSK_WITH_AES_256_CBC_SHA384   = 0xaf,
+    TLS_PSK_WITH_AES_128_CBC_SHA      = 0x8c,
+    TLS_PSK_WITH_NULL_SHA256          = 0xb0,
+    TLS_PSK_WITH_NULL_SHA384          = 0xb1,
+    TLS_PSK_WITH_NULL_SHA             = 0x2c,
+    SSL_RSA_WITH_RC4_128_SHA          = 0x05,
+    SSL_RSA_WITH_RC4_128_MD5          = 0x04,
+    SSL_RSA_WITH_3DES_EDE_CBC_SHA     = 0x0A,
+    SSL_RSA_WITH_IDEA_CBC_SHA         = 0x07,
+
+    /* ECC suites, first byte is 0xC0 (ECC_BYTE) */
+    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA    = 0x14,
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA    = 0x13,
+    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA  = 0x0A,
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA  = 0x09,
+    TLS_ECDHE_RSA_WITH_RC4_128_SHA        = 0x11,
+    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA      = 0x07,
+    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA   = 0x12,
+    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0x08,
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256   = 0x27,
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0x23,
+    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384   = 0x28,
+    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0x24,
+
+    /* static ECDH, first byte is 0xC0 (ECC_BYTE) */
+    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA    = 0x0F,
+    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA    = 0x0E,
+    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA  = 0x05,
+    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA  = 0x04,
+    TLS_ECDH_RSA_WITH_RC4_128_SHA        = 0x0C,
+    TLS_ECDH_ECDSA_WITH_RC4_128_SHA      = 0x02,
+    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA   = 0x0D,
+    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0x03,
+    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256   = 0x29,
+    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0x25,
+    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384   = 0x2A,
+    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0x26,
+
+    /* wolfSSL extension - eSTREAM */
+    TLS_RSA_WITH_HC_128_MD5       = 0xFB,
+    TLS_RSA_WITH_HC_128_SHA       = 0xFC,
+    TLS_RSA_WITH_RABBIT_SHA       = 0xFD,
+
+    /* wolfSSL extension - Blake2b 256 */
+    TLS_RSA_WITH_AES_128_CBC_B2B256   = 0xF8,
+    TLS_RSA_WITH_AES_256_CBC_B2B256   = 0xF9,
+    TLS_RSA_WITH_HC_128_B2B256        = 0xFA,   /* eSTREAM too */
+
+    /* wolfSSL extension - NTRU */
+    TLS_NTRU_RSA_WITH_RC4_128_SHA      = 0xe5,
+    TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA = 0xe6,
+    TLS_NTRU_RSA_WITH_AES_128_CBC_SHA  = 0xe7,  /* clashes w/official SHA-256 */
+    TLS_NTRU_RSA_WITH_AES_256_CBC_SHA  = 0xe8,
+
+    /* wolfSSL extension - NTRU , Quantum-safe Handshake
+       first byte is 0xD0 (QSH_BYTE) */
+    TLS_QSH      = 0x01,
+
+    /* SHA256 */
+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x6b,
+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x67,
+    TLS_RSA_WITH_AES_256_CBC_SHA256     = 0x3d,
+    TLS_RSA_WITH_AES_128_CBC_SHA256     = 0x3c,
+    TLS_RSA_WITH_NULL_SHA256            = 0x3b,
+    TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 = 0xb2,
+    TLS_DHE_PSK_WITH_NULL_SHA256        = 0xb4,
+
+    /* SHA384 */
+    TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 = 0xb3,
+    TLS_DHE_PSK_WITH_NULL_SHA384        = 0xb5,
+
+    /* AES-GCM */
+    TLS_RSA_WITH_AES_128_GCM_SHA256          = 0x9c,
+    TLS_RSA_WITH_AES_256_GCM_SHA384          = 0x9d,
+    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256      = 0x9e,
+    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384      = 0x9f,
+    TLS_PSK_WITH_AES_128_GCM_SHA256          = 0xa8,
+    TLS_PSK_WITH_AES_256_GCM_SHA384          = 0xa9,
+    TLS_DHE_PSK_WITH_AES_128_GCM_SHA256      = 0xaa,
+    TLS_DHE_PSK_WITH_AES_256_GCM_SHA384      = 0xab,
+
+    /* ECC AES-GCM, first byte is 0xC0 (ECC_BYTE) */
+    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256  = 0x2b,
+    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384  = 0x2c,
+    TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256   = 0x2d,
+    TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384   = 0x2e,
+    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256    = 0x2f,
+    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384    = 0x30,
+    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256     = 0x31,
+    TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384     = 0x32,
+
+    /* AES-CCM, first byte is 0xC0 but isn't ECC,
+     * also, in some of the other AES-CCM suites
+     * there will be second byte number conflicts
+     * with non-ECC AES-GCM */
+    TLS_RSA_WITH_AES_128_CCM_8         = 0xa0,
+    TLS_RSA_WITH_AES_256_CCM_8         = 0xa1,
+    TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xae,
+    TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xaf,
+    TLS_PSK_WITH_AES_128_CCM           = 0xa4,
+    TLS_PSK_WITH_AES_256_CCM           = 0xa5,
+    TLS_PSK_WITH_AES_128_CCM_8         = 0xa8,
+    TLS_PSK_WITH_AES_256_CCM_8         = 0xa9,
+    TLS_DHE_PSK_WITH_AES_128_CCM       = 0xa6,
+    TLS_DHE_PSK_WITH_AES_256_CCM       = 0xa7,
+
+    /* Camellia */
+    TLS_RSA_WITH_CAMELLIA_128_CBC_SHA        = 0x41,
+    TLS_RSA_WITH_CAMELLIA_256_CBC_SHA        = 0x84,
+    TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256     = 0xba,
+    TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256     = 0xc0,
+    TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA    = 0x45,
+    TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA    = 0x88,
+    TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xbe,
+    TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0xc4,
+
+    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256   = 0x13,
+    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0x14,
+    TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256     = 0x15,
+
+    /* Renegotiation Indication Extension Special Suite */
+    TLS_EMPTY_RENEGOTIATION_INFO_SCSV        = 0xff
+};
+
+
+#ifndef WOLFSSL_SESSION_TIMEOUT
+    #define WOLFSSL_SESSION_TIMEOUT 500
+    /* default session resumption cache timeout in seconds */
+#endif
+
+
+enum Misc {
+    ECC_BYTE    =  0xC0,           /* ECC first cipher suite byte */
+    QSH_BYTE    = 0xD0,            /* Quantum-safe Handshake cipher suite */
+    CHACHA_BYTE = 0xCC,            /* ChaCha first cipher suite */
+
+    SEND_CERT       = 1,
+    SEND_BLANK_CERT = 2,
+
+    DTLS_MAJOR      = 0xfe,     /* DTLS major version number */
+    DTLS_MINOR      = 0xff,     /* DTLS minor version number */
+    DTLSv1_2_MINOR  = 0xfd,     /* DTLS minor version number */
+    SSLv3_MAJOR     = 3,        /* SSLv3 and TLSv1+  major version number */
+    SSLv3_MINOR     = 0,        /* TLSv1   minor version number */
+    TLSv1_MINOR     = 1,        /* TLSv1   minor version number */
+    TLSv1_1_MINOR   = 2,        /* TLSv1_1 minor version number */
+    TLSv1_2_MINOR   = 3,        /* TLSv1_2 minor version number */
+    OLD_HELLO_ID    = 0x01,     /* SSLv2 Client Hello Indicator */
+    INVALID_BYTE    = 0xff,     /* Used to initialize cipher specs values */
+    NO_COMPRESSION  =  0,
+    ZLIB_COMPRESSION = 221,     /* wolfSSL zlib compression */
+    HELLO_EXT_SIG_ALGO = 13,    /* ID for the sig_algo hello extension */
+    SECRET_LEN      = 48,       /* pre RSA and all master */
+    ENCRYPT_LEN     = 512,      /* allow 4096 bit static buffer */
+    SIZEOF_SENDER   =  4,       /* clnt or srvr           */
+    FINISHED_SZ     = 36,       /* MD5_DIGEST_SIZE + SHA_DIGEST_SIZE */
+    MAX_RECORD_SIZE = 16384,    /* 2^14, max size by standard */
+    MAX_MSG_EXTRA   = 38 + MAX_DIGEST_SIZE,
+                                /* max added to msg, mac + pad  from */
+                                /* RECORD_HEADER_SZ + BLOCK_SZ (pad) + Max
+                                   digest sz + BLOC_SZ (iv) + pad byte (1) */
+    MAX_COMP_EXTRA  = 1024,     /* max compression extra */
+    MAX_MTU         = 1500,     /* max expected MTU */
+    MAX_UDP_SIZE    = 8192 - 100, /* was MAX_MTU - 100 */
+    MAX_DH_SZ       = 1036,     /* 4096 p, pub, g + 2 byte size for each */
+    MAX_STR_VERSION = 8,        /* string rep of protocol version */
+
+    PAD_MD5        = 48,       /* pad length for finished */
+    PAD_SHA        = 40,       /* pad length for finished */
+    MAX_PAD_SIZE   = 256,      /* maximum length of padding */
+    COMPRESS_DUMMY_SIZE = 64,  /* compression dummy round size */
+    COMPRESS_CONSTANT   = 13,  /* compression calc constant */
+    COMPRESS_UPPER      = 55,  /* compression calc numerator */
+    COMPRESS_LOWER      = 64,  /* compression calc denominator */
+
+    PEM_LINE_LEN   = 80,       /* PEM line max + fudge */
+    LENGTH_SZ      =  2,       /* length field for HMAC, data only */
+    VERSION_SZ     =  2,       /* length of proctocol version */
+    SEQ_SZ         =  8,       /* 64 bit sequence number  */
+    BYTE3_LEN      =  3,       /* up to 24 bit byte lengths */
+    ALERT_SIZE     =  2,       /* level + description     */
+    VERIFY_HEADER  =  2,       /* always use 2 bytes      */
+    EXT_ID_SZ      =  2,       /* always use 2 bytes      */
+    MAX_DH_SIZE    = 513,      /* 4096 bit plus possible leading 0 */
+    SESSION_HINT_SZ = 4,       /* session timeout hint */
+
+    MAX_SUITE_SZ = 200,        /* 100 suites for now! */
+    RAN_LEN      = 32,         /* random length           */
+    SEED_LEN     = RAN_LEN * 2, /* tls prf seed length    */
+    ID_LEN       = 32,         /* session id length       */
+    COOKIE_SECRET_SZ = 14,     /* dtls cookie secret size */
+    MAX_COOKIE_LEN = 32,       /* max dtls cookie size    */
+    COOKIE_SZ    = 20,         /* use a 20 byte cookie    */
+    SUITE_LEN    =  2,         /* cipher suite sz length  */
+    ENUM_LEN     =  1,         /* always a byte           */
+    OPAQUE8_LEN  =  1,         /* 1 byte                  */
+    OPAQUE16_LEN =  2,         /* 2 bytes                 */
+    OPAQUE24_LEN =  3,         /* 3 bytes                 */
+    OPAQUE32_LEN =  4,         /* 4 bytes                 */
+    COMP_LEN     =  1,         /* compression length      */
+    CURVE_LEN    =  2,         /* ecc named curve length  */
+    SERVER_ID_LEN = 20,        /* server session id length  */
+    
+    HANDSHAKE_HEADER_SZ   = 4,  /* type + length(3)        */
+    RECORD_HEADER_SZ      = 5,  /* type + version + len(2) */
+    CERT_HEADER_SZ        = 3,  /* always 3 bytes          */
+    REQ_HEADER_SZ         = 2,  /* cert request header sz  */
+    HINT_LEN_SZ           = 2,  /* length of hint size field */
+    TRUNCATED_HMAC_SZ     = 10, /* length of hmac w/ truncated hmac extension */
+    HELLO_EXT_TYPE_SZ     = 2,  /* length of a hello extension type */
+    HELLO_EXT_SZ          = 8,  /* total length of the lazy hello extensions */
+    HELLO_EXT_LEN         = 6,  /* length of the lazy hello extensions */
+    HELLO_EXT_SIGALGO_SZ  = 2,  /* length of signature algo extension  */
+    HELLO_EXT_SIGALGO_MAX = 32, /* number of items in the signature algo list */
+
+    DTLS_HANDSHAKE_HEADER_SZ = 12, /* normal + seq(2) + offset(3) + length(3) */
+    DTLS_RECORD_HEADER_SZ    = 13, /* normal + epoch(2) + seq_num(6) */
+    DTLS_HANDSHAKE_EXTRA     = 8,  /* diff from normal */
+    DTLS_RECORD_EXTRA        = 8,  /* diff from normal */
+    DTLS_HANDSHAKE_SEQ_SZ    = 2,  /* handshake header sequence number */
+    DTLS_HANDSHAKE_FRAG_SZ   = 3,  /* fragment offset and length are 24 bit */
+    DTLS_POOL_SZ             = 5,  /* buffers to hold in the retry pool */
+
+    FINISHED_LABEL_SZ   = 15,  /* TLS finished label size */
+    TLS_FINISHED_SZ     = 12,  /* TLS has a shorter size  */
+    MASTER_LABEL_SZ     = 13,  /* TLS master secret label sz */
+    KEY_LABEL_SZ        = 13,  /* TLS key block expansion sz */
+    MAX_PRF_HALF        = 256, /* Maximum half secret len */
+    MAX_PRF_LABSEED     = 128, /* Maximum label + seed len */
+    MAX_PRF_DIG         = 224, /* Maximum digest len      */
+    MAX_REQUEST_SZ      = 256, /* Maximum cert req len (no auth yet */
+    SESSION_FLUSH_COUNT = 256, /* Flush session cache unless user turns off */ 
+
+    RC4_KEY_SIZE        = 16,  /* always 128bit           */
+    DES_KEY_SIZE        =  8,  /* des                     */
+    DES3_KEY_SIZE       = 24,  /* 3 des ede               */
+    DES_IV_SIZE         = DES_BLOCK_SIZE,
+    AES_256_KEY_SIZE    = 32,  /* for 256 bit             */
+    AES_192_KEY_SIZE    = 24,  /* for 192 bit             */
+    AES_IV_SIZE         = 16,  /* always block size       */
+    AES_128_KEY_SIZE    = 16,  /* for 128 bit             */
+
+    AEAD_SEQ_OFFSET     = 4,        /* Auth Data: Sequence number */
+    AEAD_TYPE_OFFSET    = 8,        /* Auth Data: Type            */
+    AEAD_VMAJ_OFFSET    = 9,        /* Auth Data: Major Version   */
+    AEAD_VMIN_OFFSET    = 10,       /* Auth Data: Minor Version   */
+    AEAD_LEN_OFFSET     = 11,       /* Auth Data: Length          */
+    AEAD_AUTH_DATA_SZ   = 13,       /* Size of the data to authenticate */
+    AEAD_IMP_IV_SZ      = 4,        /* Size of the implicit IV     */
+    AEAD_EXP_IV_SZ      = 8,        /* Size of the explicit IV     */
+    AEAD_NONCE_SZ       = AEAD_EXP_IV_SZ + AEAD_IMP_IV_SZ,
+
+    AES_GCM_AUTH_SZ     = 16, /* AES-GCM Auth Tag length    */
+    AES_CCM_16_AUTH_SZ  = 16, /* AES-CCM-16 Auth Tag length */
+    AES_CCM_8_AUTH_SZ   = 8,  /* AES-CCM-8 Auth Tag Length  */
+
+    CAMELLIA_128_KEY_SIZE = 16, /* for 128 bit */
+    CAMELLIA_192_KEY_SIZE = 24, /* for 192 bit */
+    CAMELLIA_256_KEY_SIZE = 32, /* for 256 bit */
+    CAMELLIA_IV_SIZE      = 16, /* always block size */
+
+    CHACHA20_256_KEY_SIZE = 32,  /* for 256 bit             */
+    CHACHA20_128_KEY_SIZE = 16,  /* for 128 bit             */
+    CHACHA20_IV_SIZE      =  8,  /* 64 bits for iv          */
+
+    POLY1305_AUTH_SZ    = 16,  /* 128 bits                */
+
+    HC_128_KEY_SIZE     = 16,  /* 128 bits                */
+    HC_128_IV_SIZE      = 16,  /* also 128 bits           */
+
+    RABBIT_KEY_SIZE     = 16,  /* 128 bits                */
+    RABBIT_IV_SIZE      =  8,  /* 64 bits for iv          */
+
+    EVP_SALT_SIZE       =  8,  /* evp salt size 64 bits   */
+
+    ECDHE_SIZE          = 32,  /* ECHDE server size defaults to 256 bit */
+    MAX_EXPORT_ECC_SZ   = 256, /* Export ANS X9.62 max future size */
+
+#ifdef HAVE_QSH
+    /* qsh handshake sends 600+ size keys over hello extensions */
+    MAX_HELLO_SZ       = 2048,  /* max client or server hello */
+#else
+    MAX_HELLO_SZ       = 128,  /* max client or server hello */
+#endif
+    MAX_CERT_VERIFY_SZ = 1024, /* max   */
+    CLIENT_HELLO_FIRST =  35,  /* Protocol + RAN_LEN + sizeof(id_len) */
+    MAX_SUITE_NAME     =  48,  /* maximum length of cipher suite string */
+
+    DTLS_TIMEOUT_INIT       =  1, /* default timeout init for DTLS receive  */
+    DTLS_TIMEOUT_MAX        = 64, /* default max timeout for DTLS receive */
+    DTLS_TIMEOUT_MULTIPLIER =  2, /* default timeout multiplier for DTLS recv */
+
+    MAX_PSK_ID_LEN     = 128,  /* max psk identity/hint supported */
+    MAX_PSK_KEY_LEN    =  64,  /* max psk key supported */
+
+    MAX_WOLFSSL_FILE_SIZE = 1024 * 1024 * 4,  /* 4 mb file size alloc limit */
+
+#if defined(FORTRESS) || defined (HAVE_STUNNEL)
+    MAX_EX_DATA        =   3,  /* allow for three items of ex_data */
+#endif
+
+    MAX_X509_SIZE      = 2048, /* max static x509 buffer size */
+    CERT_MIN_SIZE      =  256, /* min PEM cert size with header/footer */
+    MAX_FILENAME_SZ    =  256, /* max file name length */
+    FILE_BUFFER_SIZE   = 1024, /* default static file buffer size for input,
+                                  will use dynamic buffer if not big enough */
+
+    MAX_NTRU_PUB_KEY_SZ = 1027, /* NTRU max for now */
+    MAX_NTRU_ENCRYPT_SZ = 1027, /* NTRU max for now */
+    MAX_NTRU_BITS       =  256, /* max symmetric bit strength */
+    NO_SNIFF           =   0,  /* not sniffing */
+    SNIFF              =   1,  /* currently sniffing */
+
+    HASH_SIG_SIZE      =   2,  /* default SHA1 RSA */
+
+    NO_CAVIUM_DEVICE   =  -2,  /* invalid cavium device id */
+
+    NO_COPY            =   0,  /* should we copy static buffer for write */
+    COPY               =   1   /* should we copy static buffer for write */
+};
+
+
+#ifndef WOLFSSL_MIN_DHKEY_BITS
+    #ifdef WOLFSSL_MAX_STRENGTH
+        #define WOLFSSL_MIN_DHKEY_BITS 2048
+    #else
+        #define WOLFSSL_MIN_DHKEY_BITS 1024
+    #endif
+#endif
+#if (WOLFSSL_MIN_DHKEY_BITS % 8)
+    #error DH minimum bit size must be multiple of 8
+#endif
+#if (WOLFSSL_MIN_DHKEY_BITS > 16000)
+    #error DH minimum bit size must not be greater than 16000
+#endif
+#define MIN_DHKEY_SZ (WOLFSSL_MIN_DHKEY_BITS / 8)
+
+
+#ifdef SESSION_INDEX
+/* Shift values for making a session index */
+#define SESSIDX_ROW_SHIFT 4
+#define SESSIDX_IDX_MASK  0x0F
+#endif
+
+
+/* max cert chain peer depth */
+#ifndef MAX_CHAIN_DEPTH
+    #define MAX_CHAIN_DEPTH 9
+#endif
+
+/* max size of a certificate message payload */
+/* assumes MAX_CHAIN_DEPTH number of certificates at 2kb per certificate */
+#ifndef MAX_CERTIFICATE_SZ
+    #define MAX_CERTIFICATE_SZ \
+                CERT_HEADER_SZ + \
+                (MAX_X509_SIZE + CERT_HEADER_SZ) * MAX_CHAIN_DEPTH
+#endif
+
+/* max size of a handshake message, currently set to the certificate */
+#ifndef MAX_HANDSHAKE_SZ
+    #define MAX_HANDSHAKE_SZ MAX_CERTIFICATE_SZ
+#endif
+
+#ifndef SESSION_TICKET_LEN
+    #define SESSION_TICKET_LEN 256
+#endif
+
+#ifndef SESSION_TICKET_HINT_DEFAULT
+    #define SESSION_TICKET_HINT_DEFAULT 300
+#endif
+
+
+/* don't use extra 3/4k stack space unless need to */
+#ifdef HAVE_NTRU
+    #define MAX_ENCRYPT_SZ MAX_NTRU_ENCRYPT_SZ
+#else
+    #define MAX_ENCRYPT_SZ ENCRYPT_LEN
+#endif
+
+
+/* states */
+enum states {
+    NULL_STATE = 0,
+
+    SERVER_HELLOVERIFYREQUEST_COMPLETE,
+    SERVER_HELLO_COMPLETE,
+    SERVER_CERT_COMPLETE,
+    SERVER_KEYEXCHANGE_COMPLETE,
+    SERVER_HELLODONE_COMPLETE,
+    SERVER_FINISHED_COMPLETE,
+
+    CLIENT_HELLO_COMPLETE,
+    CLIENT_KEYEXCHANGE_COMPLETE,
+    CLIENT_FINISHED_COMPLETE,
+
+    HANDSHAKE_DONE
+};
+
+
+#if defined(__GNUC__)
+    #define WOLFSSL_PACK __attribute__ ((packed))
+#else
+    #define WOLFSSL_PACK
+#endif
+
+/* SSL Version */
+typedef struct ProtocolVersion {
+    byte major;
+    byte minor;
+} WOLFSSL_PACK ProtocolVersion;
+
+
+WOLFSSL_LOCAL ProtocolVersion MakeSSLv3(void);
+WOLFSSL_LOCAL ProtocolVersion MakeTLSv1(void);
+WOLFSSL_LOCAL ProtocolVersion MakeTLSv1_1(void);
+WOLFSSL_LOCAL ProtocolVersion MakeTLSv1_2(void);
+
+#ifdef WOLFSSL_DTLS
+    WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1(void);
+    WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1_2(void);
+#endif
+
+
+enum BIO_TYPE {
+    BIO_BUFFER = 1,
+    BIO_SOCKET = 2,
+    BIO_SSL    = 3,
+    BIO_MEMORY = 4
+};
+
+
+/* wolfSSL BIO_METHOD type */
+struct WOLFSSL_BIO_METHOD {
+    byte type;               /* method type */
+};
+
+
+/* wolfSSL BIO type */
+struct WOLFSSL_BIO {
+    byte        type;          /* method type */
+    byte        close;         /* close flag */
+    byte        eof;           /* eof flag */
+    WOLFSSL*     ssl;           /* possible associated ssl */
+    byte*       mem;           /* memory buffer */
+    int         memLen;        /* memory buffer length */
+    int         fd;            /* possible file descriptor */
+    WOLFSSL_BIO* prev;          /* previous in chain */
+    WOLFSSL_BIO* next;          /* next in chain */
+};
+
+
+/* wolfSSL method type */
+struct WOLFSSL_METHOD {
+    ProtocolVersion version;
+    byte            side;         /* connection side, server or client */
+    byte            downgrade;    /* whether to downgrade version, default no */
+};
+
+
+/* defautls to client */
+WOLFSSL_LOCAL void InitSSL_Method(WOLFSSL_METHOD*, ProtocolVersion);
+
+/* for sniffer */
+WOLFSSL_LOCAL int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                            word32 size, word32 totalSz, int sniff);
+WOLFSSL_LOCAL int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx);
+
+
+/* wolfSSL buffer type */
+typedef struct buffer {
+    byte*  buffer;
+    word32 length;
+} buffer;
+
+
+enum {
+    FORCED_FREE = 1,
+    NO_FORCED_FREE = 0
+};
+
+
+/* only use compression extra if using compression */
+#ifdef HAVE_LIBZ
+    #define COMP_EXTRA MAX_COMP_EXTRA
+#else
+    #define COMP_EXTRA 0
+#endif
+
+/* only the sniffer needs space in the buffer for extra MTU record(s) */
+#ifdef WOLFSSL_SNIFFER
+    #define MTU_EXTRA MAX_MTU * 3 
+#else
+    #define MTU_EXTRA 0
+#endif
+
+
+/* embedded callbacks require large static buffers, make sure on */
+#ifdef WOLFSSL_CALLBACKS
+    #undef  LARGE_STATIC_BUFFERS
+    #define LARGE_STATIC_BUFFERS
+#endif
+
+
+/* give user option to use 16K static buffers */
+#if defined(LARGE_STATIC_BUFFERS)
+    #define RECORD_SIZE MAX_RECORD_SIZE
+#else
+    #ifdef WOLFSSL_DTLS
+        #define RECORD_SIZE MAX_MTU 
+    #else
+        #define RECORD_SIZE 128 
+    #endif
+#endif
+
+
+/* user option to turn off 16K output option */
+/* if using small static buffers (default) and SSL_write tries to write data
+   larger than the record we have, dynamically get it, unless user says only
+   write in static buffer chuncks  */
+#ifndef STATIC_CHUNKS_ONLY
+    #define OUTPUT_RECORD_SIZE MAX_RECORD_SIZE
+#else
+    #define OUTPUT_RECORD_SIZE RECORD_SIZE
+#endif
+
+/* wolfSSL input buffer
+
+   RFC 2246:
+
+   length
+       The length (in bytes) of the following TLSPlaintext.fragment.
+       The length should not exceed 2^14.
+*/
+#if defined(LARGE_STATIC_BUFFERS)
+    #define STATIC_BUFFER_LEN RECORD_HEADER_SZ + RECORD_SIZE + COMP_EXTRA + \
+             MTU_EXTRA + MAX_MSG_EXTRA
+#else
+    /* don't fragment memory from the record header */
+    #define STATIC_BUFFER_LEN RECORD_HEADER_SZ
+#endif
+
+typedef struct {
+    ALIGN16 byte staticBuffer[STATIC_BUFFER_LEN];
+    byte*  buffer;       /* place holder for static or dynamic buffer */
+    word32 length;       /* total buffer length used */
+    word32 idx;          /* idx to part of length already consumed */
+    word32 bufferSize;   /* current buffer size */
+    byte   dynamicFlag;  /* dynamic memory currently in use */
+    byte   offset;       /* alignment offset attempt */
+} bufferStatic;
+
+/* Cipher Suites holder */
+typedef struct Suites {
+    word16 suiteSz;                 /* suite length in bytes        */
+    word16 hashSigAlgoSz;           /* SigAlgo extension length in bytes */
+    byte   suites[MAX_SUITE_SZ];
+    byte   hashSigAlgo[HELLO_EXT_SIGALGO_MAX]; /* sig/algo to offer */
+    byte   setSuites;               /* user set suites from default */
+    byte   hashAlgo;                /* selected hash algorithm */
+    byte   sigAlgo;                 /* selected sig algorithm */
+} Suites;
+
+
+WOLFSSL_LOCAL
+void InitSuites(Suites*, ProtocolVersion, word16, word16, word16, word16,
+                word16, word16, int);
+WOLFSSL_LOCAL
+int  SetCipherList(Suites*, const char* list);
+
+#ifndef PSK_TYPES_DEFINED
+    typedef unsigned int (*wc_psk_client_callback)(WOLFSSL*, const char*, char*,
+                          unsigned int, unsigned char*, unsigned int);
+    typedef unsigned int (*wc_psk_server_callback)(WOLFSSL*, const char*,
+                          unsigned char*, unsigned int);
+#endif /* PSK_TYPES_DEFINED */
+
+
+#ifdef HAVE_NETX
+    WOLFSSL_LOCAL int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx);
+    WOLFSSL_LOCAL int NetX_Send(WOLFSSL *ssl, char *buf, int sz, void *ctx);
+#endif /* HAVE_NETX */
+
+
+/* wolfSSL Cipher type just points back to SSL */
+struct WOLFSSL_CIPHER {
+    WOLFSSL* ssl;
+};
+
+
+typedef struct OCSP_Entry OCSP_Entry;
+
+#ifdef NO_SHA
+    #define OCSP_DIGEST_SIZE SHA256_DIGEST_SIZE
+#else
+    #define OCSP_DIGEST_SIZE SHA_DIGEST_SIZE
+#endif
+
+#ifdef NO_ASN 
+    /* no_asn won't have */
+    typedef struct CertStatus CertStatus;
+#endif
+
+struct OCSP_Entry {
+    OCSP_Entry* next;                        /* next entry             */
+    byte    issuerHash[OCSP_DIGEST_SIZE];    /* issuer hash            */ 
+    byte    issuerKeyHash[OCSP_DIGEST_SIZE]; /* issuer public key hash */
+    CertStatus* status;                      /* OCSP response list     */
+    int         totalStatus;                 /* number on list         */
+};
+
+
+#ifndef HAVE_OCSP
+    typedef struct WOLFSSL_OCSP WOLFSSL_OCSP;
+#endif
+
+/* wolfSSL OCSP controller */
+struct WOLFSSL_OCSP {
+    WOLFSSL_CERT_MANAGER* cm;            /* pointer back to cert manager */
+    OCSP_Entry*          ocspList;      /* OCSP response list */
+    wolfSSL_Mutex         ocspLock;      /* OCSP list lock */
+};
+
+#ifndef MAX_DATE_SIZE
+#define MAX_DATE_SIZE 32
+#endif
+
+typedef struct CRL_Entry CRL_Entry;
+
+#ifdef NO_SHA
+    #define CRL_DIGEST_SIZE SHA256_DIGEST_SIZE
+#else
+    #define CRL_DIGEST_SIZE SHA_DIGEST_SIZE
+#endif
+
+#ifdef NO_ASN
+    typedef struct RevokedCert RevokedCert;
+#endif
+
+/* Complete CRL */
+struct CRL_Entry {
+    CRL_Entry* next;                      /* next entry */
+    byte    issuerHash[CRL_DIGEST_SIZE];  /* issuer hash                 */ 
+    /* byte    crlHash[CRL_DIGEST_SIZE];      raw crl data hash           */ 
+    /* restore the hash here if needed for optimized comparisons */
+    byte    lastDate[MAX_DATE_SIZE]; /* last date updated  */
+    byte    nextDate[MAX_DATE_SIZE]; /* next update date   */
+    byte    lastDateFormat;          /* last date format */
+    byte    nextDateFormat;          /* next date format */
+    RevokedCert* certs;              /* revoked cert list  */
+    int          totalCerts;         /* number on list     */
+};
+
+
+typedef struct CRL_Monitor CRL_Monitor;
+
+/* CRL directory monitor */
+struct CRL_Monitor {
+    char* path;      /* full dir path, if valid pointer we're using */
+    int   type;      /* PEM or ASN1 type */
+};
+
+
+#ifndef HAVE_CRL
+    typedef struct WOLFSSL_CRL WOLFSSL_CRL;
+#endif
+
+#if defined(HAVE_CRL) && defined(NO_FILESYSTEM)
+    #undef HAVE_CRL_MONITOR
+#endif
+
+/* wolfSSL CRL controller */
+struct WOLFSSL_CRL {
+    WOLFSSL_CERT_MANAGER* cm;            /* pointer back to cert manager */
+    CRL_Entry*           crlList;       /* our CRL list */
+    wolfSSL_Mutex         crlLock;       /* CRL list lock */
+    CRL_Monitor          monitors[2];   /* PEM and DER possible */
+#ifdef HAVE_CRL_MONITOR
+    pthread_t            tid;           /* monitoring thread */
+    int                  mfd;           /* monitor fd, -1 if no init yet */
+#endif
+};
+
+
+#ifdef NO_ASN
+    typedef struct Signer Signer;
+#endif
+
+
+#ifndef CA_TABLE_SIZE
+    #define CA_TABLE_SIZE 11
+#endif
+
+/* wolfSSL Certificate Manager */
+struct WOLFSSL_CERT_MANAGER {
+    Signer*         caTable[CA_TABLE_SIZE]; /* the CA signer table */
+    void*           heap;               /* heap helper */
+    WOLFSSL_CRL*    crl;                /* CRL checker */
+    WOLFSSL_OCSP*   ocsp;               /* OCSP checker */
+    char*           ocspOverrideURL;    /* use this responder */
+    void*           ocspIOCtx;          /* I/O callback CTX */
+    CallbackCACache caCacheCallback;    /* CA cache addition callback */
+    CbMissingCRL    cbMissingCRL;       /* notify through cb of missing crl */
+    CbOCSPIO        ocspIOCb;           /* I/O callback for OCSP lookup */
+    CbOCSPRespFree  ocspRespFreeCb;     /* Frees OCSP Response from IO Cb */
+    wolfSSL_Mutex   caLock;             /* CA list lock */
+    byte            crlEnabled;         /* is CRL on ? */
+    byte            crlCheckAll;        /* always leaf, but all ? */
+    byte            ocspEnabled;        /* is OCSP on ? */
+    byte            ocspCheckAll;       /* always leaf, but all ? */
+    byte            ocspSendNonce;      /* send the OCSP nonce ? */
+    byte            ocspUseOverrideURL; /* ignore cert's responder, override */
+};
+
+WOLFSSL_LOCAL int CM_SaveCertCache(WOLFSSL_CERT_MANAGER*, const char*);
+WOLFSSL_LOCAL int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER*, const char*);
+WOLFSSL_LOCAL int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER*, void*, int, int*);
+WOLFSSL_LOCAL int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER*, const void*, int);
+WOLFSSL_LOCAL int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER*);
+
+/* wolfSSL Sock Addr */
+struct WOLFSSL_SOCKADDR {
+    unsigned int sz; /* sockaddr size */
+    void*        sa; /* pointer to the sockaddr_in or sockaddr_in6 */
+};
+
+typedef struct WOLFSSL_DTLS_CTX {
+    WOLFSSL_SOCKADDR peer;
+    int fd;
+} WOLFSSL_DTLS_CTX;
+
+
+#ifdef WOLFSSL_DTLS
+
+    #ifdef WORD64_AVAILABLE
+        typedef word64 DtlsSeq;
+    #else
+        typedef word32 DtlsSeq;
+    #endif
+    #define DTLS_SEQ_BITS (sizeof(DtlsSeq) * CHAR_BIT)
+
+    typedef struct DtlsState {
+        DtlsSeq window;     /* Sliding window for current epoch    */
+        word16 nextEpoch;   /* Expected epoch in next record       */
+        word32 nextSeq;     /* Expected sequence in next record    */
+
+        word16 curEpoch;    /* Received epoch in current record    */
+        word32 curSeq;      /* Received sequence in current record */
+
+        DtlsSeq prevWindow; /* Sliding window for old epoch        */
+        word32 prevSeq;     /* Next sequence in allowed old epoch  */
+    } DtlsState;
+
+#endif /* WOLFSSL_DTLS */
+
+
+/* keys and secrets */
+typedef struct Keys {
+    byte client_write_MAC_secret[MAX_DIGEST_SIZE];   /* max sizes */
+    byte server_write_MAC_secret[MAX_DIGEST_SIZE];
+    byte client_write_key[AES_256_KEY_SIZE];         /* max sizes */
+    byte server_write_key[AES_256_KEY_SIZE];
+    byte client_write_IV[AES_IV_SIZE];               /* max sizes */
+    byte server_write_IV[AES_IV_SIZE];
+#ifdef HAVE_AEAD
+    byte aead_exp_IV[AEAD_EXP_IV_SZ];
+    byte aead_enc_imp_IV[AEAD_IMP_IV_SZ];
+    byte aead_dec_imp_IV[AEAD_IMP_IV_SZ];
+#endif
+
+    word32 peer_sequence_number;
+    word32 sequence_number;
+
+#ifdef WOLFSSL_DTLS
+    DtlsState dtls_state;                       /* Peer's state */
+    word16 dtls_peer_handshake_number;
+    word16 dtls_expected_peer_handshake_number;
+
+    word16 dtls_epoch;                          /* Current tx epoch    */
+    word32 dtls_sequence_number;                /* Current tx sequence */
+    word16 dtls_handshake_number;               /* Current tx handshake seq */
+#endif
+
+    word32 encryptSz;             /* last size of encrypted data   */
+    word32 padSz;                 /* how much to advance after decrypt part */
+    byte   encryptionOn;          /* true after change cipher spec */
+    byte   decryptedCur;          /* only decrypt current record once */
+} Keys;
+
+
+
+/* RFC 6066 TLS Extensions */
+#ifdef HAVE_TLS_EXTENSIONS
+
+typedef enum {
+    SERVER_NAME_INDICATION = 0x0000,
+    MAX_FRAGMENT_LENGTH    = 0x0001,
+    TRUNCATED_HMAC         = 0x0004,
+    ELLIPTIC_CURVES        = 0x000a,
+    SESSION_TICKET         = 0x0023,
+    SECURE_RENEGOTIATION   = 0xff01,
+    WOLFSSL_QSH            = 0x0018, /* Quantum-Safe-Hybrid */
+    WOLFSSL_ALPN           = 0x0010  /* Application-Layer Protocol Name */
+} TLSX_Type;
+
+typedef struct TLSX {
+    TLSX_Type    type; /* Extension Type  */
+    void*        data; /* Extension Data  */
+    byte         resp; /* IsResponse Flag */
+    struct TLSX* next; /* List Behavior   */
+} TLSX;
+
+WOLFSSL_LOCAL TLSX*  TLSX_Find(TLSX* list, TLSX_Type type);
+WOLFSSL_LOCAL void   TLSX_FreeAll(TLSX* list);
+WOLFSSL_LOCAL int    TLSX_SupportExtensions(WOLFSSL* ssl);
+WOLFSSL_LOCAL int    TLSX_PopulateExtensions(WOLFSSL* ssl, byte isRequest);
+
+#ifndef NO_WOLFSSL_CLIENT
+WOLFSSL_LOCAL word16 TLSX_GetRequestSize(WOLFSSL* ssl);
+WOLFSSL_LOCAL word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output);
+#endif
+
+#ifndef NO_WOLFSSL_SERVER
+WOLFSSL_LOCAL word16 TLSX_GetResponseSize(WOLFSSL* ssl);
+WOLFSSL_LOCAL word16 TLSX_WriteResponse(WOLFSSL* ssl, byte* output);
+#endif
+
+WOLFSSL_LOCAL int    TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                byte isRequest, Suites *suites);
+
+#elif defined(HAVE_SNI)                  \
+   || defined(HAVE_MAX_FRAGMENT)         \
+   || defined(HAVE_TRUNCATED_HMAC)       \
+   || defined(HAVE_SUPPORTED_CURVES)     \
+   || defined(HAVE_SECURE_RENEGOTIATION) \
+   || defined(HAVE_SESSION_TICKET) \
+   || defined(HAVE_ALPN)
+
+#error Using TLS extensions requires HAVE_TLS_EXTENSIONS to be defined.
+
+#endif /* HAVE_TLS_EXTENSIONS */
+
+/* Server Name Indication */
+#ifdef HAVE_SNI
+
+typedef struct SNI {
+    byte                       type;    /* SNI Type          */
+    union { char* host_name; } data;    /* SNI Data          */
+    struct SNI*                next;    /* List Behavior     */
+#ifndef NO_WOLFSSL_SERVER
+    byte                       options; /* Behaviour options */
+    byte                       status;  /* Matching result   */
+#endif
+} SNI;
+
+WOLFSSL_LOCAL int TLSX_UseSNI(TLSX** extensions, byte type, const void* data,
+                                                                   word16 size);
+
+#ifndef NO_WOLFSSL_SERVER
+WOLFSSL_LOCAL void   TLSX_SNI_SetOptions(TLSX* extensions, byte type,
+                                                                  byte options);
+WOLFSSL_LOCAL byte   TLSX_SNI_Status(TLSX* extensions, byte type);
+WOLFSSL_LOCAL word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type,
+                                                                   void** data);
+WOLFSSL_LOCAL int    TLSX_SNI_GetFromBuffer(const byte* buffer, word32 bufferSz,
+                                         byte type, byte* sni, word32* inOutSz);
+#endif
+
+#endif /* HAVE_SNI */
+
+/* Application-layer Protocol Name */
+#ifdef HAVE_ALPN
+typedef struct ALPN {
+    char*        protocol_name; /* ALPN protocol name */
+    struct ALPN* next;          /* List Behavior      */
+    byte         options;       /* Behaviour options */
+    byte         negociated;    /* ALPN protocol negociated or not */
+} ALPN;
+
+WOLFSSL_LOCAL int TLSX_ALPN_GetRequest(TLSX* extensions,
+                                       void** data, word16 *dataSz);
+
+WOLFSSL_LOCAL int TLSX_UseALPN(TLSX** extensions, const void* data,
+                               word16 size, byte options);
+
+WOLFSSL_LOCAL int TLSX_ALPN_SetOptions(TLSX** extensions, const byte option);
+
+#endif /* HAVE_ALPN */
+
+/* Maximum Fragment Length */
+#ifdef HAVE_MAX_FRAGMENT
+
+WOLFSSL_LOCAL int TLSX_UseMaxFragment(TLSX** extensions, byte mfl);
+
+#endif /* HAVE_MAX_FRAGMENT */
+
+#ifdef HAVE_TRUNCATED_HMAC
+
+WOLFSSL_LOCAL int TLSX_UseTruncatedHMAC(TLSX** extensions);
+
+#endif /* HAVE_TRUNCATED_HMAC */
+
+#ifdef HAVE_SUPPORTED_CURVES
+
+typedef struct EllipticCurve {
+    word16                name; /* CurveNames    */
+    struct EllipticCurve* next; /* List Behavior */
+} EllipticCurve;
+
+WOLFSSL_LOCAL int TLSX_UseSupportedCurve(TLSX** extensions, word16 name);
+
+#ifndef NO_WOLFSSL_SERVER
+WOLFSSL_LOCAL int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first,
+                                                                   byte second);
+#endif
+
+#endif /* HAVE_SUPPORTED_CURVES */
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+
+enum key_cache_state {
+    SCR_CACHE_NULL   = 0,       /* empty / begin state */
+    SCR_CACHE_NEEDED,           /* need to cache keys */
+    SCR_CACHE_COPY,             /* we have a cached copy */
+    SCR_CACHE_PARTIAL,          /* partial restore to real keys */
+    SCR_CACHE_COMPLETE          /* complete restore to real keys */
+};
+
+
+/* Additional Conection State according to rfc5746 section 3.1 */
+typedef struct SecureRenegotiation {
+   byte                 enabled;  /* secure_renegotiation flag in rfc */
+   byte                 startScr; /* server requested client to start scr */
+   enum key_cache_state cache_status;  /* track key cache state */
+   byte                 client_verify_data[TLS_FINISHED_SZ];  /* cached */
+   byte                 server_verify_data[TLS_FINISHED_SZ];  /* cached */
+   byte                 subject_hash[SHA_DIGEST_SIZE];  /* peer cert hash */
+   Keys                 tmp_keys;  /* can't overwrite real keys yet */
+} SecureRenegotiation;
+
+WOLFSSL_LOCAL int TLSX_UseSecureRenegotiation(TLSX** extensions);
+
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+#ifdef HAVE_SESSION_TICKET
+
+typedef struct SessionTicket {
+    word32 lifetime;
+    byte*  data;
+    word16 size;
+} SessionTicket;
+
+WOLFSSL_LOCAL int  TLSX_UseSessionTicket(TLSX** extensions, 
+                                                         SessionTicket* ticket);
+WOLFSSL_LOCAL SessionTicket* TLSX_SessionTicket_Create(word32 lifetime,
+                                                       byte* data, word16 size);
+WOLFSSL_LOCAL void TLSX_SessionTicket_Free(SessionTicket* ticket);
+#endif /* HAVE_SESSION_TICKET */
+
+#ifdef HAVE_QSH
+
+typedef struct QSHScheme {
+    struct QSHScheme* next; /* List Behavior   */
+    byte*             PK;
+    word16            name; /* QSHScheme Names */
+    word16            PKLen;
+} QSHScheme;
+
+typedef struct QSHkey {
+    struct QSHKey* next;
+    word16 name;
+    buffer pub;
+    buffer pri;
+} QSHKey;
+
+typedef struct QSHSecret {
+    QSHScheme* list;
+    buffer* SerSi;
+    buffer* CliSi;
+} QSHSecret;
+
+/* used in key exchange during handshake */
+WOLFSSL_LOCAL int TLSX_QSHCipher_Parse(WOLFSSL* ssl, const byte* input,
+                                                  word16 length, byte isServer);
+WOLFSSL_LOCAL word16 TLSX_QSHPK_Write(QSHScheme* list, byte* output);
+WOLFSSL_LOCAL word16 TLSX_QSH_GetSize(QSHScheme* list, byte isRequest);
+
+/* used by api for setting a specific QSH scheme */
+WOLFSSL_LOCAL int TLSX_UseQSHScheme(TLSX** extensions, word16 name,
+                                                     byte* pKey, word16 pKeySz);
+
+/* used when parsing in QSHCipher structs */
+WOLFSSL_LOCAL int QSH_Decrypt(QSHKey* key, byte* in, word32 szIn,
+                                                      byte* out, word16* szOut);
+#ifndef NO_WOLFSSL_SERVER
+WOLFSSL_LOCAL int TLSX_ValidateQSHScheme(TLSX** extensions, word16 name);
+#endif
+
+#endif /* HAVE_QSH */
+
+/* wolfSSL context type */
+struct WOLFSSL_CTX {
+    WOLFSSL_METHOD* method;
+    wolfSSL_Mutex   countMutex;    /* reference count mutex */
+    int         refCount;         /* reference count */
+#ifndef NO_DH
+    buffer      serverDH_P;
+    buffer      serverDH_G;
+#endif
+#ifndef NO_CERTS
+    buffer      certificate;
+    buffer      certChain;
+                 /* chain after self, in DER, with leading size for each cert */
+    buffer      privateKey;
+    WOLFSSL_CERT_MANAGER* cm;      /* our cert manager, ctx owns SSL will use */
+#endif
+    Suites*     suites;           /* make dynamic, user may not need/set */
+    void*       heap;             /* for user memory overrides */
+    byte        verifyPeer;
+    byte        verifyNone;
+    byte        failNoCert;
+    byte        sessionCacheOff;
+    byte        sessionCacheFlushOff;
+    byte        sendVerify;       /* for client side */
+    byte        haveRSA;          /* RSA available */
+    byte        haveDH;           /* server DH parms set by user */
+    byte        haveNTRU;         /* server private NTRU  key loaded */
+    byte        haveECDSAsig;     /* server cert signed w/ ECDSA */
+    byte        haveStaticECC;    /* static server ECC private key */
+    byte        partialWrite;     /* only one msg per write call */
+    byte        quietShutdown;    /* don't send close notify */
+    byte        groupMessages;    /* group handshake messages before sending */
+    byte        minDowngrade;     /* minimum downgrade version */
+#ifndef NO_DH
+    word16      minDhKeySz;       /* minimum DH key size */
+#endif
+    CallbackIORecv CBIORecv;
+    CallbackIOSend CBIOSend;
+#ifdef WOLFSSL_DTLS
+    CallbackGenCookie CBIOCookie;       /* gen cookie callback */
+#endif
+    VerifyCallback  verifyCallback;     /* cert verification callback */
+    word32          timeout;            /* session timeout */
+#ifdef HAVE_ECC
+    word16          eccTempKeySz;       /* in octets 20 - 66 */
+    word32          pkCurveOID;         /* curve Ecc_Sum */
+#endif
+#ifndef NO_PSK
+    byte        havePSK;                /* psk key set by user */
+    wc_psk_client_callback client_psk_cb;  /* client callback */
+    wc_psk_server_callback server_psk_cb;  /* server callback */
+    char        server_hint[MAX_PSK_ID_LEN];
+#endif /* NO_PSK */
+#ifdef HAVE_ANON
+    byte        haveAnon;               /* User wants to allow Anon suites */
+#endif /* HAVE_ANON */
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+    pem_password_cb passwd_cb;
+    void*           userdata;
+#endif /* OPENSSL_EXTRA */
+#ifdef HAVE_STUNNEL
+    void*           ex_data[MAX_EX_DATA];
+    CallbackSniRecv sniRecvCb;
+    void*           sniRecvCbArg;
+#endif
+#ifdef HAVE_OCSP
+    WOLFSSL_OCSP      ocsp;
+#endif
+#ifdef HAVE_CAVIUM
+    int              devId;            /* cavium device id to use */
+#endif
+#ifdef HAVE_TLS_EXTENSIONS
+    TLSX* extensions;                  /* RFC 6066 TLS Extensions data */
+    #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SEVER)
+        SessionTicketEncCb ticketEncCb;   /* enc/dec session ticket Cb */
+        void*              ticketEncCtx;  /* session encrypt context */
+        int                ticketHint;    /* ticket hint in seconds */
+    #endif
+#endif
+#ifdef ATOMIC_USER
+    CallbackMacEncrypt    MacEncryptCb;    /* Atomic User Mac/Encrypt Cb */
+    CallbackDecryptVerify DecryptVerifyCb; /* Atomic User Decrypt/Verify Cb */
+#endif
+#ifdef HAVE_PK_CALLBACKS
+    #ifdef HAVE_ECC
+        CallbackEccSign   EccSignCb;    /* User EccSign   Callback handler */
+        CallbackEccVerify EccVerifyCb;  /* User EccVerify Callback handler */
+    #endif /* HAVE_ECC */
+    #ifndef NO_RSA 
+        CallbackRsaSign   RsaSignCb;    /* User RsaSign   Callback handler */
+        CallbackRsaVerify RsaVerifyCb;  /* User RsaVerify Callback handler */
+        CallbackRsaEnc    RsaEncCb;     /* User Rsa Public Encrypt  handler */
+        CallbackRsaDec    RsaDecCb;     /* User Rsa Private Decrypt handler */
+    #endif /* NO_RSA */
+#endif /* HAVE_PK_CALLBACKS */
+};
+
+
+WOLFSSL_LOCAL
+int InitSSL_Ctx(WOLFSSL_CTX*, WOLFSSL_METHOD*);
+WOLFSSL_LOCAL
+void FreeSSL_Ctx(WOLFSSL_CTX*);
+WOLFSSL_LOCAL
+void SSL_CtxResourceFree(WOLFSSL_CTX*);
+
+WOLFSSL_LOCAL
+int DeriveTlsKeys(WOLFSSL* ssl);
+WOLFSSL_LOCAL
+int ProcessOldClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+                          word32 inSz, word16 sz);
+#ifndef NO_CERTS
+    WOLFSSL_LOCAL
+    int AddCA(WOLFSSL_CERT_MANAGER* ctx, buffer der, int type, int verify);
+    WOLFSSL_LOCAL
+    int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash);
+#endif
+
+/* All cipher suite related info */
+typedef struct CipherSpecs {
+    word16 key_size;
+    word16 iv_size;
+    word16 block_size;
+    word16 aead_mac_size;
+    byte bulk_cipher_algorithm;
+    byte cipher_type;               /* block, stream, or aead */
+    byte mac_algorithm;
+    byte kea;                       /* key exchange algo */
+    byte sig_algo;
+    byte hash_size;
+    byte pad_size;
+    byte static_ecdh;
+} CipherSpecs;
+
+
+void InitCipherSpecs(CipherSpecs* cs);
+
+
+/* Supported Message Authentication Codes from page 43 */
+enum MACAlgorithm { 
+    no_mac,
+    md5_mac,
+    sha_mac,
+    sha224_mac,
+    sha256_mac,     /* needs to match external KDF_MacAlgorithm */
+    sha384_mac,
+    sha512_mac,
+    rmd_mac,
+    blake2b_mac
+};
+
+
+/* Supported Key Exchange Protocols */
+enum KeyExchangeAlgorithm { 
+    no_kea,
+    rsa_kea, 
+    diffie_hellman_kea, 
+    fortezza_kea,
+    psk_kea,
+    dhe_psk_kea,
+    ntru_kea,
+    ecc_diffie_hellman_kea,
+    ecc_static_diffie_hellman_kea       /* for verify suite only */
+};
+
+
+/* Supported Authentication Schemes */
+enum SignatureAlgorithm {
+    anonymous_sa_algo,
+    rsa_sa_algo,
+    dsa_sa_algo,
+    ecc_dsa_sa_algo
+};
+
+
+/* Supprted ECC Curve Types */
+enum EccCurves {
+    named_curve = 3
+};
+
+
+/* Valid client certificate request types from page 27 */
+enum ClientCertificateType {    
+    rsa_sign            = 1, 
+    dss_sign            = 2,
+    rsa_fixed_dh        = 3,
+    dss_fixed_dh        = 4,
+    rsa_ephemeral_dh    = 5,
+    dss_ephemeral_dh    = 6,
+    fortezza_kea_cert   = 20,
+    ecdsa_sign          = 64,
+    rsa_fixed_ecdh      = 65,
+    ecdsa_fixed_ecdh    = 66
+};
+
+
+enum CipherType { stream, block, aead };
+
+
+
+
+
+
+/* cipher for now */
+typedef struct Ciphers {
+#ifdef BUILD_ARC4
+    Arc4*   arc4;
+#endif
+#ifdef BUILD_DES3
+    Des3*   des3;
+#endif
+#if defined(BUILD_AES) || defined(BUILD_AESGCM)
+    Aes*    aes;
+#endif
+#ifdef HAVE_CAMELLIA
+    Camellia* cam;
+#endif
+#ifdef HAVE_CHACHA
+    ChaCha*   chacha;
+#endif
+#ifdef HAVE_HC128
+    HC128*  hc128;
+#endif
+#ifdef BUILD_RABBIT
+    Rabbit* rabbit;
+#endif
+#ifdef HAVE_IDEA
+    Idea* idea;
+#endif
+    byte    setup;       /* have we set it up flag for detection */
+} Ciphers;
+
+
+#ifdef HAVE_ONE_TIME_AUTH
+/* Ciphers for one time authentication such as poly1305 */
+typedef struct OneTimeAuth {
+#ifdef HAVE_POLY1305
+    Poly1305* poly1305;
+#endif
+    byte    setup;      /* flag for if a cipher has been set */
+
+} OneTimeAuth;
+#endif
+
+
+WOLFSSL_LOCAL void InitCiphers(WOLFSSL* ssl);
+WOLFSSL_LOCAL void FreeCiphers(WOLFSSL* ssl);
+
+
+/* hashes type */
+typedef struct Hashes {
+    #ifndef NO_OLD_TLS
+        byte md5[MD5_DIGEST_SIZE];
+    #endif
+    byte sha[SHA_DIGEST_SIZE];
+    #ifndef NO_SHA256
+        byte sha256[SHA256_DIGEST_SIZE];
+    #endif
+    #ifdef WOLFSSL_SHA384
+        byte sha384[SHA384_DIGEST_SIZE];
+    #endif
+    #ifdef WOLFSSL_SHA512
+        byte sha512[SHA512_DIGEST_SIZE];
+    #endif
+} Hashes;
+
+
+/* Static x509 buffer */
+typedef struct x509_buffer {
+    int  length;                  /* actual size */
+    byte buffer[MAX_X509_SIZE];   /* max static cert size */
+} x509_buffer;
+
+
+/* wolfSSL X509_CHAIN, for no dynamic memory SESSION_CACHE */
+struct WOLFSSL_X509_CHAIN {
+    int         count;                    /* total number in chain */
+    x509_buffer certs[MAX_CHAIN_DEPTH];   /* only allow max depth 4 for now */
+};
+
+
+/* wolfSSL session type */
+struct WOLFSSL_SESSION {
+    word32       bornOn;                        /* create time in seconds   */
+    word32       timeout;                       /* timeout in seconds       */
+    byte         sessionID[ID_LEN];             /* id for protocol */
+    byte         sessionIDSz;
+    byte         masterSecret[SECRET_LEN];      /* stored secret */
+#ifdef SESSION_CERTS
+    WOLFSSL_X509_CHAIN chain;                    /* peer cert chain, static  */
+    ProtocolVersion version;                    /* which version was used */
+    byte            cipherSuite0;               /* first byte, normally 0 */
+    byte            cipherSuite;                /* 2nd byte, actual suite */
+#endif
+#ifndef NO_CLIENT_CACHE
+    word16       idLen;                         /* serverID length */
+    byte         serverID[SERVER_ID_LEN];       /* for easier client lookup */
+#endif
+#ifdef HAVE_SESSION_TICKET
+    word16       ticketLen;
+    byte         ticket[SESSION_TICKET_LEN];
+#endif
+#ifdef HAVE_STUNNEL
+    void*        ex_data[MAX_EX_DATA];
+#endif
+};
+
+
+WOLFSSL_LOCAL
+WOLFSSL_SESSION* GetSession(WOLFSSL*, byte*);
+WOLFSSL_LOCAL
+int          SetSession(WOLFSSL*, WOLFSSL_SESSION*);
+
+typedef int (*hmacfp) (WOLFSSL*, byte*, const byte*, word32, int, int);
+
+#ifndef NO_CLIENT_CACHE
+    WOLFSSL_SESSION* GetSessionClient(WOLFSSL*, const byte*, int);
+#endif
+
+/* client connect state for nonblocking restart */
+enum ConnectState {
+    CONNECT_BEGIN = 0,
+    CLIENT_HELLO_SENT,
+    HELLO_AGAIN,               /* HELLO_AGAIN s for DTLS case */
+    HELLO_AGAIN_REPLY,
+    FIRST_REPLY_DONE,
+    FIRST_REPLY_FIRST,
+    FIRST_REPLY_SECOND,
+    FIRST_REPLY_THIRD,
+    FIRST_REPLY_FOURTH,
+    FINISHED_DONE,
+    SECOND_REPLY_DONE
+};
+
+
+/* server accept state for nonblocking restart */
+enum AcceptState {
+    ACCEPT_BEGIN = 0,
+    ACCEPT_CLIENT_HELLO_DONE,
+    ACCEPT_FIRST_REPLY_DONE,
+    SERVER_HELLO_SENT,
+    CERT_SENT,
+    KEY_EXCHANGE_SENT,
+    CERT_REQ_SENT,
+    SERVER_HELLO_DONE,
+    ACCEPT_SECOND_REPLY_DONE,
+    TICKET_SENT,
+    CHANGE_CIPHER_SENT,
+    ACCEPT_FINISHED_DONE,
+    ACCEPT_THIRD_REPLY_DONE
+};
+
+
+typedef struct Buffers {
+    bufferStatic    inputBuffer;
+    bufferStatic    outputBuffer;
+    buffer          domainName;             /* for client check */
+    buffer          clearOutputBuffer;
+    int             prevSent;              /* previous plain text bytes sent
+                                              when got WANT_WRITE            */
+    int             plainSz;               /* plain text bytes in buffer to send
+                                              when got WANT_WRITE            */
+    byte            weOwnCert;             /* SSL own cert flag */
+    byte            weOwnCertChain;        /* SSL own cert chain flag */
+    byte            weOwnKey;              /* SSL own key  flag */
+    byte            weOwnDH;               /* SSL own dh (p,g)  flag */
+#ifndef NO_DH
+    buffer          serverDH_P;            /* WOLFSSL_CTX owns, unless we own */
+    buffer          serverDH_G;            /* WOLFSSL_CTX owns, unless we own */
+    buffer          serverDH_Pub;
+    buffer          serverDH_Priv;
+#endif
+#ifndef NO_CERTS
+    buffer          certificate;           /* WOLFSSL_CTX owns, unless we own */
+    buffer          key;                   /* WOLFSSL_CTX owns, unless we own */
+    buffer          certChain;             /* WOLFSSL_CTX owns, unless we own */
+                 /* chain after self, in DER, with leading size for each cert */
+#endif
+#ifdef WOLFSSL_DTLS
+    WOLFSSL_DTLS_CTX dtlsCtx;               /* DTLS connection context */
+    #ifndef NO_WOLFSSL_SERVER
+        buffer       dtlsCookieSecret;      /* DTLS cookie secret */
+    #endif /* NO_WOLFSSL_SERVER */
+#endif
+#ifdef HAVE_PK_CALLBACKS
+    #ifdef HAVE_ECC
+        buffer peerEccDsaKey;              /* we own for Ecc Verify Callbacks */
+    #endif /* HAVE_ECC */
+    #ifndef NO_RSA
+        buffer peerRsaKey;                 /* we own for Rsa Verify Callbacks */
+    #endif /* NO_RSA */
+#endif /* HAVE_PK_CALLBACKS */
+} Buffers;
+
+typedef struct Options {
+#ifndef NO_PSK
+    wc_psk_client_callback client_psk_cb;
+    wc_psk_server_callback server_psk_cb;
+    word16            havePSK:1;            /* psk key set by user */
+#endif /* NO_PSK */
+
+    /* on/off or small bit flags, optimize layout */
+    word16            sendVerify:2;     /* false = 0, true = 1, sendBlank = 2 */
+    word16            sessionCacheOff:1;
+    word16            sessionCacheFlushOff:1;
+    word16            side:1;             /* client or server end */
+    word16            verifyPeer:1;
+    word16            verifyNone:1;
+    word16            failNoCert:1;
+    word16            downgrade:1;        /* allow downgrade of versions */
+    word16            resuming:1;
+    word16            haveSessionId:1;    /* server may not send */
+    word16            tls:1;              /* using TLS ? */
+    word16            tls1_1:1;           /* using TLSv1.1+ ? */
+    word16            dtls:1;             /* using datagrams ? */
+    word16            connReset:1;        /* has the peer reset */
+    word16            isClosed:1;         /* if we consider conn closed */
+    word16            closeNotify:1;      /* we've recieved a close notify */
+    word16            sentNotify:1;       /* we've sent a close notify */
+    word16            usingCompression:1; /* are we using compression */
+    word16            haveRSA:1;          /* RSA available */
+    word16            haveDH:1;           /* server DH parms set by user */
+    word16            haveNTRU:1;         /* server NTRU  private key loaded */
+    byte              haveQSH:1;          /* have QSH ability */
+    word16            haveECDSAsig:1;     /* server ECDSA signed cert */
+    word16            haveStaticECC:1;    /* static server ECC private key */
+    word16            havePeerCert:1;     /* do we have peer's cert */
+    word16            havePeerVerify:1;   /* and peer's cert verify */
+    word16            usingPSK_cipher:1;  /* are using psk as cipher */
+    word16            usingAnon_cipher:1; /* are we using an anon cipher */
+    word16            sendAlertState:1;   /* nonblocking resume */
+    word16            partialWrite:1;     /* only one msg per write call */
+    word16            quietShutdown:1;    /* don't send close notify */
+    word16            certOnly:1;         /* stop once we get cert */
+    word16            groupMessages:1;    /* group handshake messages */
+    word16            usingNonblock:1;    /* are we using nonblocking socket */
+    word16            saveArrays:1;       /* save array Memory for user get keys
+                                           or psk */
+#ifdef HAVE_POLY1305
+    word16            oldPoly:1;        /* set when to use old rfc way of poly*/
+#endif
+#ifdef HAVE_ANON
+    word16            haveAnon:1;       /* User wants to allow Anon suites */
+#endif
+#ifdef HAVE_SESSION_TICKET
+    word16            createTicket:1;     /* Server to create new Ticket */
+    word16            useTicket:1;        /* Use Ticket not session cache */
+#endif
+
+    /* need full byte values for this section */
+    byte            processReply;           /* nonblocking resume */
+    byte            cipherSuite0;           /* first byte, normally 0 */
+    byte            cipherSuite;            /* second byte, actual suite */
+    byte            serverState;
+    byte            clientState;
+    byte            handShakeState;
+    byte            handShakeDone;      /* at least one handshake complete */
+    byte            minDowngrade;       /* minimum downgrade version */
+    byte            connectState;       /* nonblocking resume */
+    byte            acceptState;        /* nonblocking resume */
+#ifndef NO_DH
+    word16          minDhKeySz;         /* minimum DH key size */
+    word16          dhKeySz;            /* actual DH key size */
+#endif
+
+} Options;
+
+typedef struct Arrays {
+    byte*           pendingMsg;         /* defrag buffer */
+    word32          preMasterSz;        /* differs for DH, actual size */
+    word32          pendingMsgSz;       /* defrag buffer size */
+    word32          pendingMsgOffset;   /* current offset into defrag buffer */
+#ifndef NO_PSK
+    word32          psk_keySz;          /* acutal size */
+    char            client_identity[MAX_PSK_ID_LEN];
+    char            server_hint[MAX_PSK_ID_LEN];
+    byte            psk_key[MAX_PSK_KEY_LEN];
+#endif
+    byte            clientRandom[RAN_LEN];
+    byte            serverRandom[RAN_LEN];
+    byte            sessionID[ID_LEN];
+    byte            sessionIDSz;
+    byte            preMasterSecret[ENCRYPT_LEN];
+    byte            masterSecret[SECRET_LEN];
+#ifdef WOLFSSL_DTLS
+    byte            cookie[MAX_COOKIE_LEN];
+    byte            cookieSz;
+#endif
+    byte            pendingMsgType;    /* defrag buffer message type */
+} Arrays;
+
+#ifndef ASN_NAME_MAX
+#define ASN_NAME_MAX 256
+#endif
+
+#ifndef MAX_DATE_SZ
+#define MAX_DATE_SZ 32
+#endif
+
+struct WOLFSSL_X509_NAME {
+    char  *name;
+    char  staticName[ASN_NAME_MAX];
+    int   dynamicName;
+    int   sz;
+#ifdef OPENSSL_EXTRA
+    DecodedName fullName;
+#endif /* OPENSSL_EXTRA */
+};
+
+#ifndef EXTERNAL_SERIAL_SIZE
+    #define EXTERNAL_SERIAL_SIZE 32
+#endif
+
+#ifdef NO_ASN 
+    typedef struct DNS_entry DNS_entry;
+#endif
+
+struct WOLFSSL_X509 {
+    int              version;
+    WOLFSSL_X509_NAME issuer;
+    WOLFSSL_X509_NAME subject;
+    int              serialSz;
+    byte             serial[EXTERNAL_SERIAL_SIZE];
+    char             subjectCN[ASN_NAME_MAX];        /* common name short cut */
+#ifdef WOLFSSL_SEP
+    int              deviceTypeSz;
+    byte             deviceType[EXTERNAL_SERIAL_SIZE];
+    int              hwTypeSz;
+    byte             hwType[EXTERNAL_SERIAL_SIZE];
+    int              hwSerialNumSz;
+    byte             hwSerialNum[EXTERNAL_SERIAL_SIZE];
+    #ifdef OPENSSL_EXTRA
+        byte             certPolicySet;
+        byte             certPolicyCrit;
+    #endif /* OPENSSL_EXTRA */
+#endif
+    int              notBeforeSz;
+    byte             notBefore[MAX_DATE_SZ];
+    int              notAfterSz;
+    byte             notAfter[MAX_DATE_SZ];
+    int              sigOID;
+    buffer           sig;
+    int              pubKeyOID;
+    buffer           pubKey;
+    #ifdef HAVE_ECC
+        word32       pkCurveOID;
+    #endif /* HAVE_ECC */
+    buffer           derCert;                        /* may need  */
+    DNS_entry*       altNames;                       /* alt names list */
+    DNS_entry*       altNamesNext;                   /* hint for retrieval */
+    byte             dynamicMemory;                  /* dynamic memory flag */
+    byte             isCa;
+#ifdef OPENSSL_EXTRA
+    word32           pathLength;
+    word16           keyUsage;
+    byte             basicConstSet;
+    byte             basicConstCrit;
+    byte             basicConstPlSet;
+    byte             subjAltNameSet;
+    byte             subjAltNameCrit;
+    byte             authKeyIdSet;
+    byte             authKeyIdCrit;
+    byte*            authKeyId;
+    word32           authKeyIdSz;
+    byte             subjKeyIdSet;
+    byte             subjKeyIdCrit;
+    byte*            subjKeyId;
+    word32           subjKeyIdSz;
+    byte             keyUsageSet;
+    byte             keyUsageCrit;
+#endif /* OPENSSL_EXTRA */
+};
+
+
+/* record layer header for PlainText, Compressed, and CipherText */
+typedef struct RecordLayerHeader {
+    byte            type;
+    byte            pvMajor;
+    byte            pvMinor;
+    byte            length[2];
+} RecordLayerHeader;
+
+
+/* record layer header for DTLS PlainText, Compressed, and CipherText */
+typedef struct DtlsRecordLayerHeader {
+    byte            type;
+    byte            pvMajor;
+    byte            pvMinor;
+    byte            epoch[2];             /* increment on cipher state change */
+    byte            sequence_number[6];   /* per record */
+    byte            length[2];
+} DtlsRecordLayerHeader;
+
+
+typedef struct DtlsPool {
+    buffer          buf[DTLS_POOL_SZ];
+    int             used;
+} DtlsPool;
+
+typedef struct DtlsMsg {
+    struct DtlsMsg* next;
+    word32          seq;       /* Handshake sequence number    */
+    word32          sz;        /* Length of whole mesage       */
+    word32          fragSz;    /* Length of fragments received */
+    byte            type;
+    byte*           buf;
+    byte*           msg;
+} DtlsMsg;
+
+
+#ifdef HAVE_NETX
+
+    /* NETX I/O Callback default */
+    typedef struct NetX_Ctx {
+        NX_TCP_SOCKET* nxSocket;    /* send/recv socket handle */
+        NX_PACKET*     nxPacket;    /* incoming packet handle for short reads */
+        ULONG          nxOffset;    /* offset already read from nxPacket */
+        ULONG          nxWait;      /* wait option flag */
+    } NetX_Ctx;
+
+#endif
+
+
+/* Handshake messages recevied from peer (plus change cipher */
+typedef struct MsgsReceived {
+    word16 got_hello_request:1;
+    word16 got_client_hello:1;
+    word16 got_server_hello:1;
+    word16 got_hello_verify_request:1;
+    word16 got_session_ticket:1;
+    word16 got_certificate:1;
+    word16 got_server_key_exchange:1;
+    word16 got_certificate_request:1;
+    word16 got_server_hello_done:1;
+    word16 got_certificate_verify:1;
+    word16 got_client_key_exchange:1;
+    word16 got_finished:1;
+    word16 got_change_cipher:1;
+} MsgsReceived;
+
+
+/* Handshake hashes */
+typedef struct HS_Hashes {
+    Hashes          verifyHashes;
+    Hashes          certHashes;         /* for cert verify */
+#ifndef NO_OLD_TLS
+#ifndef NO_SHA
+    Sha             hashSha;            /* sha hash of handshake msgs */
+#endif
+#ifndef NO_MD5
+    Md5             hashMd5;            /* md5 hash of handshake msgs */
+#endif
+#endif /* NO_OLD_TLS */
+#ifndef NO_SHA256
+    Sha256          hashSha256;         /* sha256 hash of handshake msgs */
+#endif
+#ifdef WOLFSSL_SHA384
+    Sha384          hashSha384;         /* sha384 hash of handshake msgs */
+#endif
+#ifdef WOLFSSL_SHA512
+    Sha512          hashSha512;         /* sha512 hash of handshake msgs */
+#endif
+} HS_Hashes;
+
+
+/* wolfSSL ssl type */
+struct WOLFSSL {
+    WOLFSSL_CTX*    ctx;
+    Suites*         suites;             /* only need during handshake */
+    Arrays*         arrays;
+    HS_Hashes*      hsHashes;
+    void*           IOCB_ReadCtx;
+    void*           IOCB_WriteCtx;
+    WC_RNG*         rng;
+    void*           verifyCbCtx;        /* cert verify callback user ctx*/
+    VerifyCallback  verifyCallback;     /* cert verification callback */
+    void*           heap;               /* for user overrides */
+#ifndef NO_HANDSHAKE_DONE_CB
+    HandShakeDoneCb hsDoneCb;          /*  notify user handshake done */
+    void*           hsDoneCtx;         /*  user handshake cb context  */
+#endif
+    WOLFSSL_CIPHER  cipher;
+    hmacfp          hmac;
+    Ciphers         encrypt;
+    Ciphers         decrypt;
+    Buffers         buffers;
+    WOLFSSL_SESSION session;
+    WOLFSSL_ALERT_HISTORY alert_history;
+    int             error;
+    int             rfd;                /* read  file descriptor */
+    int             wfd;                /* write file descriptor */
+    int             rflags;             /* user read  flags */
+    int             wflags;             /* user write flags */
+    word32          timeout;            /* session timeout */
+    word32          fragOffset;         /* fragment offset */
+    word16          curSize;
+    RecordLayerHeader curRL;
+    MsgsReceived    msgsReceived;       /* peer messages received */
+    ProtocolVersion version;            /* negotiated version */
+    ProtocolVersion chVersion;          /* client hello version */
+    CipherSpecs     specs;
+    Keys            keys;
+    Options         options;
+#ifdef OPENSSL_EXTRA
+    WOLFSSL_BIO*     biord;              /* socket bio read  to free/close */
+    WOLFSSL_BIO*     biowr;              /* socket bio write to free/close */
+#endif
+#ifndef NO_RSA
+    RsaKey*         peerRsaKey;
+    byte            peerRsaKeyPresent;
+#endif
+#ifdef HAVE_QSH
+    QSHKey*         QSH_Key;
+    QSHKey*         peerQSHKey;
+    QSHSecret*      QSH_secret;
+    byte            isQSH;             /* is the handshake a QSH? */
+    byte            sendQSHKeys;       /* flag for if the client should sen
+                                          public keys */
+    byte            peerQSHKeyPresent;
+    byte            minRequest;
+    byte            maxRequest;
+    byte            user_set_QSHSchemes;
+#endif
+#ifdef HAVE_NTRU
+    word16          peerNtruKeyLen;
+    byte            peerNtruKey[MAX_NTRU_PUB_KEY_SZ];
+    byte            peerNtruKeyPresent;
+#endif
+#ifdef HAVE_ECC
+    ecc_key*        peerEccKey;              /* peer's  ECDHE key */
+    ecc_key*        peerEccDsaKey;           /* peer's  ECDSA key */
+    ecc_key*        eccTempKey;              /* private ECDHE key */
+    word32          pkCurveOID;              /* curve Ecc_Sum     */
+    word16          eccTempKeySz;            /* in octets 20 - 66 */
+    byte            peerEccKeyPresent;
+    byte            peerEccDsaKeyPresent;
+    byte            eccTempKeyPresent;
+#endif
+#ifdef HAVE_LIBZ
+    z_stream        c_stream;           /* compression   stream */
+    z_stream        d_stream;           /* decompression stream */
+    byte            didStreamInit;      /* for stream init and end */
+#endif
+#ifdef WOLFSSL_DTLS
+    int             dtls_timeout_init;  /* starting timeout vaule */
+    int             dtls_timeout_max;   /* maximum timeout value */
+    int             dtls_timeout;       /* current timeout value, changes */
+    DtlsPool*       dtls_pool;
+    DtlsMsg*        dtls_msg_list;
+    void*           IOCB_CookieCtx;     /* gen cookie ctx */
+    word32          dtls_expected_rx;
+#endif
+#ifdef WOLFSSL_CALLBACKS
+    HandShakeInfo   handShakeInfo;      /* info saved during handshake */
+    TimeoutInfo     timeoutInfo;        /* info saved during handshake */
+    byte            hsInfoOn;           /* track handshake info        */
+    byte            toInfoOn;           /* track timeout   info        */
+#endif
+#ifdef HAVE_FUZZER
+    CallbackFuzzer  fuzzerCb;           /* for testing with using fuzzer */
+    void*           fuzzerCtx;          /* user defined pointer */
+#endif
+#ifdef KEEP_PEER_CERT
+    WOLFSSL_X509     peerCert;           /* X509 peer cert */
+#endif
+#if defined(FORTRESS) || defined(HAVE_STUNNEL)
+    void*           ex_data[MAX_EX_DATA]; /* external data, for Fortress */
+#endif
+#ifdef HAVE_CAVIUM
+    int              devId;            /* cavium device id to use */
+#endif
+#ifdef HAVE_ONE_TIME_AUTH
+    OneTimeAuth     auth;
+#endif
+#ifdef HAVE_TLS_EXTENSIONS
+    TLSX* extensions;                  /* RFC 6066 TLS Extensions data */
+    #ifdef HAVE_MAX_FRAGMENT
+        word16 max_fragment;
+    #endif
+    #ifdef HAVE_TRUNCATED_HMAC
+        byte truncated_hmac;
+    #endif
+    #ifdef HAVE_SECURE_RENEGOTIATION
+        SecureRenegotiation* secure_renegotiation; /* valid pointer indicates */
+    #endif                                         /* user turned on */
+    #ifdef HAVE_ALPN
+        char*   alpn_client_list;  /* keep the client's list */
+    #endif                         /* of accepted protocols */
+    #if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET)
+        CallbackSessionTicket session_ticket_cb;
+        void*                 session_ticket_ctx;
+        byte                  expect_session_ticket;
+    #endif
+#endif /* HAVE_TLS_EXTENSIONS */
+#ifdef HAVE_NETX
+    NetX_Ctx        nxCtx;             /* NetX IO Context */
+#endif
+#ifdef SESSION_INDEX
+    int sessionIndex;                  /* Session's location in the cache. */
+#endif
+#ifdef ATOMIC_USER
+    void*    MacEncryptCtx;    /* Atomic User Mac/Encrypt Callback Context */
+    void*    DecryptVerifyCtx; /* Atomic User Decrypt/Verify Callback Context */
+#endif
+#ifdef HAVE_PK_CALLBACKS
+    #ifdef HAVE_ECC
+        void* EccSignCtx;     /* Ecc Sign   Callback Context */
+        void* EccVerifyCtx;   /* Ecc Verify Callback Context */
+    #endif /* HAVE_ECC */
+    #ifndef NO_RSA
+        void* RsaSignCtx;     /* Rsa Sign   Callback Context */
+        void* RsaVerifyCtx;   /* Rsa Verify Callback Context */
+        void* RsaEncCtx;      /* Rsa Public  Encrypt   Callback Context */
+        void* RsaDecCtx;      /* Rsa Private Decrypt   Callback Context */
+    #endif /* NO_RSA */
+#endif /* HAVE_PK_CALLBACKS */
+#ifdef HAVE_SECRET_CALLBACK
+        SessionSecretCb sessionSecretCb;
+        void*           sessionSecretCtx;
+#endif /* HAVE_SECRET_CALLBACK */
+#ifdef WOLFSSL_JNI
+        void* jObjectRef;     /* reference to WolfSSLSession in JNI wrapper */
+#endif /* WOLFSSL_JNI */
+};
+
+
+WOLFSSL_LOCAL
+int  SetSSL_CTX(WOLFSSL*, WOLFSSL_CTX*);
+WOLFSSL_LOCAL
+int  InitSSL(WOLFSSL*, WOLFSSL_CTX*);
+WOLFSSL_LOCAL
+void FreeSSL(WOLFSSL*);
+WOLFSSL_API void SSL_ResourceFree(WOLFSSL*);   /* Micrium uses */
+
+
+enum {
+    IV_SZ   = 32,          /* max iv sz */
+    NAME_SZ = 80          /* max one line */
+};
+
+
+typedef struct EncryptedInfo {
+    char     name[NAME_SZ];    /* encryption name */
+    byte     iv[IV_SZ];        /* encrypted IV */
+    word32   ivSz;             /* encrypted IV size */
+    long     consumed;         /* tracks PEM bytes consumed */
+    byte     set;              /* if encryption set */
+    WOLFSSL_CTX* ctx;              /* CTX owner */
+} EncryptedInfo;
+
+
+#ifndef NO_CERTS
+    WOLFSSL_LOCAL int PemToDer(const unsigned char* buff, long sz, int type,
+                              buffer* der, void* heap, EncryptedInfo* info,
+                              int* eccKey);
+
+    WOLFSSL_LOCAL int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format,
+                                 int type, WOLFSSL* ssl, int userChain,
+                                WOLFSSL_CRL* crl);
+#endif
+
+
+#ifdef WOLFSSL_CALLBACKS
+    WOLFSSL_LOCAL
+    void InitHandShakeInfo(HandShakeInfo*);
+    WOLFSSL_LOCAL 
+    void FinishHandShakeInfo(HandShakeInfo*, const WOLFSSL*);
+    WOLFSSL_LOCAL 
+    void AddPacketName(const char*, HandShakeInfo*);
+
+    WOLFSSL_LOCAL
+    void InitTimeoutInfo(TimeoutInfo*);
+    WOLFSSL_LOCAL 
+    void FreeTimeoutInfo(TimeoutInfo*, void*);
+    WOLFSSL_LOCAL 
+    void AddPacketInfo(const char*, TimeoutInfo*, const byte*, int, void*);
+    WOLFSSL_LOCAL 
+    void AddLateName(const char*, TimeoutInfo*);
+    WOLFSSL_LOCAL 
+    void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info);
+#endif
+
+
+/* Record Layer Header identifier from page 12 */
+enum ContentType {
+    no_type            = 0,
+    change_cipher_spec = 20, 
+    alert              = 21, 
+    handshake          = 22, 
+    application_data   = 23 
+};
+
+
+/* handshake header, same for each message type, pgs 20/21 */
+typedef struct HandShakeHeader {
+    byte            type;
+    word24          length;
+} HandShakeHeader;
+
+
+/* DTLS handshake header, same for each message type */
+typedef struct DtlsHandShakeHeader {
+    byte            type;
+    word24          length;
+    byte            message_seq[2];    /* start at 0, restransmit gets same # */
+    word24          fragment_offset;   /* bytes in previous fragments */
+    word24          fragment_length;   /* length of this fragment */
+} DtlsHandShakeHeader;
+
+
+enum HandShakeType {
+    no_shake            = -1,
+    hello_request       = 0, 
+    client_hello        = 1, 
+    server_hello        = 2,
+    hello_verify_request = 3,       /* DTLS addition */
+    session_ticket      =  4,
+    certificate         = 11, 
+    server_key_exchange = 12,
+    certificate_request = 13, 
+    server_hello_done   = 14,
+    certificate_verify  = 15, 
+    client_key_exchange = 16,
+    finished            = 20,
+    certificate_status  = 22,
+    change_cipher_hs    = 55      /* simulate unique handshake type for sanity
+                                     checks.  record layer change_cipher
+                                     conflicts with handshake finished */
+};
+
+
+static const byte client[SIZEOF_SENDER] = { 0x43, 0x4C, 0x4E, 0x54 };
+static const byte server[SIZEOF_SENDER] = { 0x53, 0x52, 0x56, 0x52 };
+
+static const byte tls_client[FINISHED_LABEL_SZ + 1] = "client finished";
+static const byte tls_server[FINISHED_LABEL_SZ + 1] = "server finished";
+
+
+/* internal functions */
+WOLFSSL_LOCAL int SendChangeCipher(WOLFSSL*);
+WOLFSSL_LOCAL int SendTicket(WOLFSSL*);
+WOLFSSL_LOCAL int DoClientTicket(WOLFSSL*, const byte*, word32);
+WOLFSSL_LOCAL int SendData(WOLFSSL*, const void*, int);
+WOLFSSL_LOCAL int SendCertificate(WOLFSSL*);
+WOLFSSL_LOCAL int SendCertificateRequest(WOLFSSL*);
+WOLFSSL_LOCAL int SendServerKeyExchange(WOLFSSL*);
+WOLFSSL_LOCAL int SendBuffered(WOLFSSL*);
+WOLFSSL_LOCAL int ReceiveData(WOLFSSL*, byte*, int, int);
+WOLFSSL_LOCAL int SendFinished(WOLFSSL*);
+WOLFSSL_LOCAL int SendAlert(WOLFSSL*, int, int);
+WOLFSSL_LOCAL int ProcessReply(WOLFSSL*);
+
+WOLFSSL_LOCAL int SetCipherSpecs(WOLFSSL*);
+WOLFSSL_LOCAL int MakeMasterSecret(WOLFSSL*);
+
+WOLFSSL_LOCAL int  AddSession(WOLFSSL*);
+WOLFSSL_LOCAL int  DeriveKeys(WOLFSSL* ssl);
+WOLFSSL_LOCAL int  StoreKeys(WOLFSSL* ssl, const byte* keyData);
+
+WOLFSSL_LOCAL int IsTLS(const WOLFSSL* ssl);
+WOLFSSL_LOCAL int IsAtLeastTLSv1_2(const WOLFSSL* ssl);
+
+WOLFSSL_LOCAL void FreeHandshakeResources(WOLFSSL* ssl);
+WOLFSSL_LOCAL void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree);
+WOLFSSL_LOCAL void ShrinkOutputBuffer(WOLFSSL* ssl);
+
+WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl);
+#ifndef NO_CERTS
+    #ifndef NO_RSA
+        WOLFSSL_LOCAL int VerifyRsaSign(const byte* sig, word32 sigSz,
+                                        const byte* plain, word32 plainSz,
+                                        RsaKey* key);
+    #endif
+    WOLFSSL_LOCAL Signer* GetCA(void* cm, byte* hash);
+    #ifndef NO_SKID
+        WOLFSSL_LOCAL Signer* GetCAByName(void* cm, byte* hash);
+    #endif
+#endif
+WOLFSSL_LOCAL int  BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes,
+                                   const byte* sender);
+WOLFSSL_LOCAL void FreeArrays(WOLFSSL* ssl, int keep);
+WOLFSSL_LOCAL  int CheckAvailableSize(WOLFSSL *ssl, int size);
+WOLFSSL_LOCAL  int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength);
+
+#ifndef NO_TLS
+    WOLFSSL_LOCAL int  MakeTlsMasterSecret(WOLFSSL*);
+    WOLFSSL_LOCAL int  TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in,
+                               word32 sz, int content, int verify);
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+    WOLFSSL_LOCAL int SendClientHello(WOLFSSL*);
+    WOLFSSL_LOCAL int SendClientKeyExchange(WOLFSSL*);
+    WOLFSSL_LOCAL int SendCertificateVerify(WOLFSSL*);
+#endif /* NO_WOLFSSL_CLIENT */
+
+#ifndef NO_WOLFSSL_SERVER
+    WOLFSSL_LOCAL int SendServerHello(WOLFSSL*);
+    WOLFSSL_LOCAL int SendServerHelloDone(WOLFSSL*);
+#endif /* NO_WOLFSSL_SERVER */
+
+#ifdef WOLFSSL_DTLS
+    WOLFSSL_LOCAL int  DtlsPoolInit(WOLFSSL*);
+    WOLFSSL_LOCAL int  DtlsPoolSave(WOLFSSL*, const byte*, int);
+    WOLFSSL_LOCAL int  DtlsPoolTimeout(WOLFSSL*);
+    WOLFSSL_LOCAL int  DtlsPoolSend(WOLFSSL*);
+    WOLFSSL_LOCAL void DtlsPoolReset(WOLFSSL*);
+    WOLFSSL_LOCAL void DtlsPoolDelete(WOLFSSL*);
+
+    WOLFSSL_LOCAL DtlsMsg* DtlsMsgNew(word32, void*);
+    WOLFSSL_LOCAL void DtlsMsgDelete(DtlsMsg*, void*);
+    WOLFSSL_LOCAL void DtlsMsgListDelete(DtlsMsg*, void*);
+    WOLFSSL_LOCAL void DtlsMsgSet(DtlsMsg*, word32, const byte*, byte,
+                                                             word32, word32);
+    WOLFSSL_LOCAL DtlsMsg* DtlsMsgFind(DtlsMsg*, word32);
+    WOLFSSL_LOCAL DtlsMsg* DtlsMsgStore(DtlsMsg*, word32, const byte*, word32,
+                                                byte, word32, word32, void*);
+    WOLFSSL_LOCAL DtlsMsg* DtlsMsgInsert(DtlsMsg*, DtlsMsg*);
+#endif /* WOLFSSL_DTLS */
+
+#ifndef NO_TLS
+    
+
+#endif /* NO_TLS */
+
+
+WOLFSSL_LOCAL word32  LowResTimer(void);
+
+WOLFSSL_LOCAL void InitX509Name(WOLFSSL_X509_NAME*, int);
+WOLFSSL_LOCAL void FreeX509Name(WOLFSSL_X509_NAME* name);
+WOLFSSL_LOCAL void InitX509(WOLFSSL_X509*, int);
+WOLFSSL_LOCAL void FreeX509(WOLFSSL_X509*);
+#ifndef NO_CERTS
+    WOLFSSL_LOCAL int  CopyDecodedToX509(WOLFSSL_X509*, DecodedCert*);
+#endif
+
+/* used by ssl.c and wolfssl_int.c */
+WOLFSSL_LOCAL void c32to24(word32 in, word24 out);
+
+WOLFSSL_LOCAL const char* const* GetCipherNames(void);
+WOLFSSL_LOCAL int GetCipherNamesSize(void);
+
+
+enum encrypt_side {
+    ENCRYPT_SIDE_ONLY = 1,
+    DECRYPT_SIDE_ONLY,
+    ENCRYPT_AND_DECRYPT_SIDE
+};
+
+WOLFSSL_LOCAL int SetKeysSide(WOLFSSL*, enum encrypt_side);
+
+
+#ifdef __cplusplus
+    }  /* extern "C" */
+#endif
+
+#endif /* wolfSSL_INT_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/bio.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/bio.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/bio.h	(revision 164)
@@ -0,0 +1,23 @@
+/* bio.h for openssl */
+
+
+#ifndef WOLFSSL_BIO_H_
+#define WOLFSSL_BIO_H_
+
+#include <wolfssl/openssl/ssl.h>
+
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+
+
+#ifdef __cplusplus
+    }  /* extern "C" */ 
+#endif
+
+
+#endif /* WOLFSSL_BIO_H_ */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/bn.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/bn.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/bn.h	(revision 164)
@@ -0,0 +1,151 @@
+/* bn.h for openssl */
+
+
+#ifndef WOLFSSL_BN_H_
+#define WOLFSSL_BN_H_
+
+#include <wolfssl/wolfcrypt/settings.h>
+#include <wolfssl/wolfcrypt/integer.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+typedef struct WOLFSSL_BIGNUM {
+    int   neg;              /* openssh deference */
+    void* internal;         /* our big num */
+} WOLFSSL_BIGNUM;
+
+
+#define WOLFSSL_BN_ULONG mp_digit
+
+typedef struct WOLFSSL_BN_CTX WOLFSSL_BN_CTX;
+typedef struct WOLFSSL_BN_GENCB WOLFSSL_BN_GENCB;
+
+WOLFSSL_API WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void);
+WOLFSSL_API void           wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX*);
+WOLFSSL_API void           wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX*);
+
+WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_BN_new(void);
+WOLFSSL_API void           wolfSSL_BN_free(WOLFSSL_BIGNUM*);
+WOLFSSL_API void           wolfSSL_BN_clear_free(WOLFSSL_BIGNUM*);
+
+
+WOLFSSL_API int wolfSSL_BN_sub(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*,
+                             const WOLFSSL_BIGNUM*);
+WOLFSSL_API int wolfSSL_BN_mod(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*,
+                             const WOLFSSL_BIGNUM*, const WOLFSSL_BN_CTX*);
+
+WOLFSSL_API const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void);
+
+
+WOLFSSL_API int wolfSSL_BN_num_bytes(const WOLFSSL_BIGNUM*);
+WOLFSSL_API int wolfSSL_BN_num_bits(const WOLFSSL_BIGNUM*);
+
+WOLFSSL_API int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM*);
+WOLFSSL_API int wolfSSL_BN_is_one(const WOLFSSL_BIGNUM*);
+WOLFSSL_API int wolfSSL_BN_is_odd(const WOLFSSL_BIGNUM*);
+
+WOLFSSL_API int wolfSSL_BN_cmp(const WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*);
+
+WOLFSSL_API int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM*, unsigned char*);
+WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char*, int len,
+                                WOLFSSL_BIGNUM* ret);
+
+WOLFSSL_API int wolfSSL_mask_bits(WOLFSSL_BIGNUM*, int n);
+
+WOLFSSL_API int wolfSSL_BN_rand(WOLFSSL_BIGNUM*, int bits, int top, int bottom);
+WOLFSSL_API int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM*, int n);
+WOLFSSL_API int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM**, const char* str);
+
+WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_BN_dup(const WOLFSSL_BIGNUM*);
+WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_BN_copy(WOLFSSL_BIGNUM*,
+                                            const WOLFSSL_BIGNUM*);
+
+WOLFSSL_API int   wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM**, const char* str);
+WOLFSSL_API char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM*);
+
+WOLFSSL_API int wolfSSL_BN_lshift(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, int);
+WOLFSSL_API int wolfSSL_BN_add_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG);
+WOLFSSL_API int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM*, int);
+WOLFSSL_API int wolfSSL_BN_set_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG);
+
+WOLFSSL_API int wolfSSL_BN_add(WOLFSSL_BIGNUM*, WOLFSSL_BIGNUM*,
+                               WOLFSSL_BIGNUM*);
+WOLFSSL_API char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM*);
+WOLFSSL_API int wolfSSL_BN_is_prime_ex(const WOLFSSL_BIGNUM*, int,
+                                       WOLFSSL_BN_CTX*, WOLFSSL_BN_GENCB*);
+WOLFSSL_API WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM*,
+                                                 WOLFSSL_BN_ULONG);
+#ifndef NO_FILESYSTEM
+    WOLFSSL_API int wolfSSL_BN_print_fp(XFILE , const WOLFSSL_BIGNUM*);
+#endif
+WOLFSSL_API int wolfSSL_BN_rshift(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, int);
+WOLFSSL_API WOLFSSL_BIGNUM *wolfSSL_BN_CTX_get(WOLFSSL_BN_CTX *ctx);
+WOLFSSL_API void wolfSSL_BN_CTX_start(WOLFSSL_BN_CTX *ctx);
+
+typedef WOLFSSL_BIGNUM BIGNUM;
+typedef WOLFSSL_BN_CTX BN_CTX;
+typedef WOLFSSL_BN_GENCB BN_GENCB;
+
+#define BN_CTX_new        wolfSSL_BN_CTX_new
+#define BN_CTX_init       wolfSSL_BN_CTX_init
+#define BN_CTX_free       wolfSSL_BN_CTX_free
+
+#define BN_new        wolfSSL_BN_new
+#define BN_free       wolfSSL_BN_free
+#define BN_clear_free wolfSSL_BN_clear_free
+
+#define BN_num_bytes wolfSSL_BN_num_bytes
+#define BN_num_bits  wolfSSL_BN_num_bits
+
+#define BN_is_zero  wolfSSL_BN_is_zero
+#define BN_is_one   wolfSSL_BN_is_one
+#define BN_is_odd   wolfSSL_BN_is_odd
+
+#define BN_cmp    wolfSSL_BN_cmp
+
+#define BN_bn2bin  wolfSSL_BN_bn2bin
+#define BN_bin2bn  wolfSSL_BN_bin2bn
+
+#define BN_mod       wolfSSL_BN_mod
+#define BN_sub       wolfSSL_BN_sub
+#define BN_value_one wolfSSL_BN_value_one
+
+#define BN_mask_bits wolfSSL_mask_bits
+
+#define BN_rand       wolfSSL_BN_rand
+#define BN_is_bit_set wolfSSL_BN_is_bit_set
+#define BN_hex2bn     wolfSSL_BN_hex2bn
+
+#define BN_dup  wolfSSL_BN_dup
+#define BN_copy wolfSSL_BN_copy
+
+#define BN_set_word wolfSSL_BN_set_word
+
+#define BN_dec2bn wolfSSL_BN_dec2bn
+#define BN_bn2dec wolfSSL_BN_bn2dec
+#define BN_bn2hex wolfSSL_BN_bn2hex
+
+#define BN_lshift wolfSSL_BN_lshift
+#define BN_add_word wolfSSL_BN_add_word
+#define BN_add wolfSSL_BN_add
+#define BN_set_word wolfSSL_BN_set_word
+#define BN_set_bit wolfSSL_BN_set_bit
+
+
+#define BN_is_prime_ex wolfSSL_BN_is_prime_ex
+#define BN_print_fp wolfSSL_BN_print_fp
+#define BN_rshift wolfSSL_BN_rshift
+#define BN_mod_word wolfSSL_BN_mod_word
+
+#define BN_CTX_get wolfSSL_BN_CTX_get
+#define BN_CTX_start wolfSSL_BN_CTX_start
+
+#ifdef __cplusplus
+    }  /* extern "C" */
+#endif
+
+
+#endif /* WOLFSSL__H_ */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/conf.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/conf.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/conf.h	(revision 164)
@@ -0,0 +1,2 @@
+/* conf.h for openssl */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/crypto.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/crypto.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/crypto.h	(revision 164)
@@ -0,0 +1,34 @@
+/* crypto.h for openSSL */
+
+#ifndef WOLFSSL_CRYPTO_H_
+#define WOLFSSL_CRYPTO_H_
+
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef WOLFSSL_PREFIX
+#include "prefix_crypto.h"
+#endif
+
+
+WOLFSSL_API const char*   wolfSSLeay_version(int type);
+WOLFSSL_API unsigned long wolfSSLeay(void);
+
+#define SSLeay_version wolfSSLeay_version
+#define SSLeay wolfSSLeay
+
+
+#define SSLEAY_VERSION 0x0090600fL
+#define SSLEAY_VERSION_NUMBER SSLEAY_VERSION
+
+#ifdef HAVE_STUNNEL
+#define CRYPTO_set_mem_ex_functions      wolfSSL_CRYPTO_set_mem_ex_functions
+#define FIPS_mode                        wolfSSL_FIPS_mode
+#define FIPS_mode_set                    wolfSSL_FIPS_mode_set
+typedef struct CRYPTO_EX_DATA            CRYPTO_EX_DATA;
+typedef void (CRYPTO_free_func)(void*parent, void*ptr, CRYPTO_EX_DATA *ad, int idx,
+        long argl, void* argp);
+#endif /* HAVE_STUNNEL */
+
+#endif /* header */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/des.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/des.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/des.h	(revision 164)
@@ -0,0 +1,106 @@
+/* des.h
+ *
+ * Copyright (C) 2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as wolfSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/*  des.h defines mini des openssl compatibility layer 
+ *
+ */
+
+
+#ifndef WOLFSSL_DES_H_
+#define WOLFSSL_DES_H_
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_DES3
+
+#ifdef WOLFSSL_PREFIX
+#include "prefix_des.h"
+#endif
+
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+typedef unsigned char WOLFSSL_DES_cblock[8];
+typedef /* const */ WOLFSSL_DES_cblock WOLFSSL_const_DES_cblock;
+typedef WOLFSSL_DES_cblock WOLFSSL_DES_key_schedule;
+
+
+enum {
+    DES_ENCRYPT = 1,
+    DES_DECRYPT = 0
+};
+
+
+WOLFSSL_API void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock*,
+                                             WOLFSSL_DES_key_schedule*);
+WOLFSSL_API int  wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key,
+                                     WOLFSSL_DES_key_schedule* schedule);
+WOLFSSL_API void wolfSSL_DES_cbc_encrypt(const unsigned char* input,
+                     unsigned char* output, long length,
+                     WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
+                     int enc);
+WOLFSSL_API void wolfSSL_DES_ncbc_encrypt(const unsigned char* input,
+                      unsigned char* output, long length,
+                      WOLFSSL_DES_key_schedule* schedule,
+                      WOLFSSL_DES_cblock* ivec, int enc);
+
+WOLFSSL_API void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock*);
+WOLFSSL_API void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock*, WOLFSSL_DES_cblock*,
+                                       WOLFSSL_DES_key_schedule*, int);
+
+
+typedef WOLFSSL_DES_cblock DES_cblock;
+typedef WOLFSSL_const_DES_cblock const_DES_cblock;
+typedef WOLFSSL_DES_key_schedule DES_key_schedule;
+
+#define DES_set_key_unchecked wolfSSL_DES_set_key_unchecked
+#define DES_key_sched wolfSSL_DES_key_sched
+#define DES_cbc_encrypt wolfSSL_DES_cbc_encrypt
+#define DES_ncbc_encrypt wolfSSL_DES_ncbc_encrypt
+#define DES_set_odd_parity wolfSSL_DES_set_odd_parity
+#define DES_ecb_encrypt wolfSSL_DES_ecb_encrypt
+#define DES_ede3_cbc_encrypt(input, output, sz, ks1, ks2, ks3, ivec, enc) \
+do {                                                         \
+    Des3 des;                                                \
+    byte key[24];/* EDE uses 24 size key */                  \
+    memcpy(key, (ks1), DES_BLOCK_SIZE);                      \
+    memcpy(&key[DES_BLOCK_SIZE], (ks2), DES_BLOCK_SIZE);     \
+    memcpy(&key[DES_BLOCK_SIZE * 2], (ks3), DES_BLOCK_SIZE); \
+    if (enc) {                                               \
+        wc_Des3_SetKey(&des, key, (const byte*)(ivec), DES_ENCRYPTION);    \
+        wc_Des3_CbcEncrypt(&des, (output), (input), (sz));    \
+    }                                                         \
+    else {                                                    \
+        wc_Des3_SetKey(&des, key, (const byte*)(ivec), DES_ENCRYPTION);    \
+        wc_Des3_CbcDecrypt(&des, (output), (input), (sz));    \
+    }                                                         \
+} while(0)
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* NO_DES3 */
+
+#endif /* WOLFSSL_DES_H_ */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/dh.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/dh.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/dh.h	(revision 164)
@@ -0,0 +1,54 @@
+/* dh.h for openSSL */
+
+
+#ifndef WOLFSSL_DH_H_
+#define WOLFSSL_DH_H_
+
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/openssl/bn.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+struct WOLFSSL_DH {
+    WOLFSSL_BIGNUM* p;
+    WOLFSSL_BIGNUM* g;
+    WOLFSSL_BIGNUM* pub_key;      /* openssh deference g^x */
+    WOLFSSL_BIGNUM* priv_key;     /* openssh deference x   */
+    void*          internal;     /* our DH */
+    char           inSet;        /* internal set from external ? */
+    char           exSet;        /* external set from internal ? */
+    /*added for lighttpd openssl compatability, go back and add a getter in 
+     * lighttpd src code.
+     */
+     int length;
+};
+
+
+WOLFSSL_API WOLFSSL_DH* wolfSSL_DH_new(void);
+WOLFSSL_API void       wolfSSL_DH_free(WOLFSSL_DH*);
+
+WOLFSSL_API int wolfSSL_DH_size(WOLFSSL_DH*);
+WOLFSSL_API int wolfSSL_DH_generate_key(WOLFSSL_DH*);
+WOLFSSL_API int wolfSSL_DH_compute_key(unsigned char* key, WOLFSSL_BIGNUM* pub,
+                                     WOLFSSL_DH*);
+
+typedef WOLFSSL_DH DH;
+
+#define DH_new  wolfSSL_DH_new 
+#define DH_free wolfSSL_DH_free
+
+#define DH_size         wolfSSL_DH_size
+#define DH_generate_key wolfSSL_DH_generate_key
+#define DH_compute_key  wolfSSL_DH_compute_key
+
+
+#ifdef __cplusplus
+    }  /* extern "C" */ 
+#endif
+
+#ifdef HAVE_STUNNEL
+#define DH_generate_parameters wolfSSL_DH_generate_parameters
+#endif /* HAVE_STUNNEL */
+#endif /* header */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/dsa.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/dsa.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/dsa.h	(revision 164)
@@ -0,0 +1,54 @@
+/* dsa.h for openSSL */
+
+
+#ifndef WOLFSSL_DSA_H_
+#define WOLFSSL_DSA_H_
+
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/openssl/bn.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+struct WOLFSSL_DSA {
+    WOLFSSL_BIGNUM* p;
+    WOLFSSL_BIGNUM* q;
+    WOLFSSL_BIGNUM* g;
+    WOLFSSL_BIGNUM* pub_key;      /* our y */
+    WOLFSSL_BIGNUM* priv_key;     /* our x */
+    void*          internal;     /* our Dsa Key */
+    char           inSet;        /* internal set from external ? */
+    char           exSet;        /* external set from internal ? */
+};
+
+
+WOLFSSL_API WOLFSSL_DSA* wolfSSL_DSA_new(void);
+WOLFSSL_API void wolfSSL_DSA_free(WOLFSSL_DSA*);
+
+WOLFSSL_API int wolfSSL_DSA_generate_key(WOLFSSL_DSA*);
+WOLFSSL_API int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA*, int bits,
+                   unsigned char* seed, int seedLen, int* counterRet,
+                   unsigned long* hRet, void* cb);
+
+WOLFSSL_API int wolfSSL_DSA_LoadDer(WOLFSSL_DSA*, const unsigned char*, int sz);
+
+WOLFSSL_API int wolfSSL_DSA_do_sign(const unsigned char* d,
+                                    unsigned char* sigRet, WOLFSSL_DSA* dsa);
+
+WOLFSSL_API int wolfSSL_DSA_do_verify(const unsigned char* d,
+                                      unsigned char* sig,
+                                      WOLFSSL_DSA* dsa, int *dsacheck);
+
+#define DSA_new wolfSSL_DSA_new
+#define DSA_free wolfSSL_DSA_free
+
+#define DSA_generate_key           wolfSSL_DSA_generate_key
+#define DSA_generate_parameters_ex wolfSSL_DSA_generate_parameters_ex
+
+
+#ifdef __cplusplus
+    }  /* extern "C" */ 
+#endif
+
+#endif /* header */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ec.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ec.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ec.h	(revision 164)
@@ -0,0 +1,165 @@
+/* ec.h for openssl */
+
+#ifndef WOLFSSL_EC_H_
+#define WOLFSSL_EC_H_
+
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/openssl/bn.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Map OpenSSL NID value */
+enum {
+    POINT_CONVERSION_UNCOMPRESSED = 4,
+    NID_secp111r1 = 0,
+    NID_secp128r1 = 1,
+    NID_secp160r1 = 2,
+    NID_cert192 = 3,
+    NID_cert224 = 4,
+    NID_X9_62_prime256v1 = 5,
+    NID_secp384r1 = 6,
+    NID_secp521r1 = 7,
+    NID_X9_62_prime_field = 100,
+    OPENSSL_EC_NAMED_CURVE  = 0x001
+};
+
+struct WOLFSSL_EC_POINT {
+    WOLFSSL_BIGNUM *X;
+    WOLFSSL_BIGNUM *Y;
+    WOLFSSL_BIGNUM *Z;
+
+    void*          internal;     /* our ECC point */
+    char           inSet;        /* internal set from external ? */
+    char           exSet;        /* external set from internal ? */
+};
+
+struct WOLFSSL_EC_GROUP {
+    int curve_idx; /* index of curve, used by WolfSSL as reference */
+    int curve_nid; /* NID of curve, used by OpenSSL/OpenSSH as reference */
+};
+
+struct WOLFSSL_EC_KEY {
+    WOLFSSL_EC_GROUP *group;
+    WOLFSSL_EC_POINT *pub_key;
+    WOLFSSL_BIGNUM *priv_key;
+
+    void*          internal;     /* our ECC Key */
+    char           inSet;        /* internal set from external ? */
+    char           exSet;        /* external set from internal ? */
+};
+
+WOLFSSL_API
+int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *curve,
+                        const WOLFSSL_EC_POINT *p,
+                        unsigned char *out, unsigned int *len);
+WOLFSSL_API
+int wolfSSL_ECPoint_d2i(unsigned char *in, unsigned int len,
+                        const WOLFSSL_EC_GROUP *curve, WOLFSSL_EC_POINT *p);
+WOLFSSL_API
+int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key,
+                           const unsigned char* der, int derSz);
+WOLFSSL_API
+void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key);
+WOLFSSL_API
+WOLFSSL_EC_POINT *wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY *key);
+WOLFSSL_API
+const WOLFSSL_EC_GROUP *wolfSSL_EC_KEY_get0_group(const WOLFSSL_EC_KEY *key);
+WOLFSSL_API
+int wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY *key,
+                                   const WOLFSSL_BIGNUM *priv_key);
+WOLFSSL_API
+WOLFSSL_BIGNUM *wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY *key);
+WOLFSSL_API
+WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid);
+WOLFSSL_API
+WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void);
+WOLFSSL_API
+int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group);
+WOLFSSL_API
+int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key);
+WOLFSSL_API
+void wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY *key, int asn1_flag);
+WOLFSSL_API
+int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key,
+                                  const WOLFSSL_EC_POINT *pub);
+WOLFSSL_API
+void wolfSSL_EC_GROUP_set_asn1_flag(WOLFSSL_EC_GROUP *group, int flag);
+WOLFSSL_API
+WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_new_by_curve_name(int nid);
+WOLFSSL_API
+int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b,
+                         WOLFSSL_BN_CTX *ctx);
+WOLFSSL_API
+int wolfSSL_EC_GROUP_get_curve_name(const WOLFSSL_EC_GROUP *group);
+WOLFSSL_API
+int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group);
+WOLFSSL_API
+int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group,
+                               WOLFSSL_BIGNUM *order, WOLFSSL_BN_CTX *ctx);
+WOLFSSL_API
+void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group);
+#if defined(DEBUG_WOLFSSL) && !defined(NO_FILESYSTEM)
+WOLFSSL_API
+void wolfssl_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *p);
+#endif
+WOLFSSL_API
+WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group);
+WOLFSSL_API
+int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group,
+                                                const WOLFSSL_EC_POINT *p,
+                                                WOLFSSL_BIGNUM *x,
+                                                WOLFSSL_BIGNUM *y,
+                                                WOLFSSL_BN_CTX *ctx);
+WOLFSSL_API
+int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r,
+                         const WOLFSSL_BIGNUM *n,
+                         const WOLFSSL_EC_POINT *q, const WOLFSSL_BIGNUM *m,
+                         WOLFSSL_BN_CTX *ctx);
+WOLFSSL_API
+void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *point);
+WOLFSSL_API
+int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group,
+                         const WOLFSSL_EC_POINT *a, const WOLFSSL_EC_POINT *b,
+                         WOLFSSL_BN_CTX *ctx);
+WOLFSSL_API
+void wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT *point);
+WOLFSSL_API
+int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group,
+                                    const WOLFSSL_EC_POINT *a);
+
+#define EC_KEY_free wolfSSL_EC_KEY_free
+#define EC_KEY_get0_public_key wolfSSL_EC_KEY_get0_public_key
+#define EC_KEY_get0_group wolfSSL_EC_KEY_get0_group
+#define EC_KEY_set_private_key wolfSSL_EC_KEY_set_private_key
+#define EC_KEY_get0_private_key wolfSSL_EC_KEY_get0_private_key
+#define EC_KEY_new_by_curve_name wolfSSL_EC_KEY_new_by_curve_name
+#define EC_KEY_set_group wolfSSL_EC_KEY_set_group
+#define EC_KEY_generate_key wolfSSL_EC_KEY_generate_key
+#define EC_KEY_set_asn1_flag wolfSSL_EC_KEY_set_asn1_flag
+#define EC_KEY_set_public_key wolfSSL_EC_KEY_set_public_key
+#define EC_KEY_new wolfSSL_EC_KEY_new
+
+#define EC_GROUP_set_asn1_flag wolfSSL_EC_GROUP_set_asn1_flag
+#define EC_GROUP_new_by_curve_name wolfSSL_EC_GROUP_new_by_curve_name
+#define EC_GROUP_cmp wolfSSL_EC_GROUP_cmp
+#define EC_GROUP_get_curve_name wolfSSL_EC_GROUP_get_curve_name
+#define EC_GROUP_get_degree wolfSSL_EC_GROUP_get_degree
+#define EC_GROUP_get_order wolfSSL_EC_GROUP_get_order
+#define EC_GROUP_free wolfSSL_EC_GROUP_free
+
+#define EC_POINT_new wolfSSL_EC_POINT_new
+#define EC_POINT_get_affine_coordinates_GFp \
+            wolfSSL_EC_POINT_get_affine_coordinates_GFp
+#define EC_POINT_mul wolfSSL_EC_POINT_mul
+#define EC_POINT_clear_free wolfSSL_EC_POINT_clear_free
+#define EC_POINT_cmp wolfSSL_EC_POINT_cmp
+#define EC_POINT_free wolfSSL_EC_POINT_free
+#define EC_POINT_is_at_infinity wolfSSL_EC_POINT_is_at_infinity
+
+#ifdef __cplusplus
+}  /* extern "C" */
+#endif
+
+#endif /* header */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ec25519.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ec25519.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ec25519.h	(revision 164)
@@ -0,0 +1,23 @@
+/* ec25519.h */
+
+#ifndef WOLFSSL_EC25519_H_
+#define WOLFSSL_EC25519_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+WOLFSSL_API
+int wolfSSL_EC25519_generate_key(unsigned char *priv, unsigned int *privSz,
+                                 unsigned char *pub, unsigned int *pubSz);
+
+WOLFSSL_API
+int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz,
+                               const unsigned char *priv, unsigned int privSz,
+                               const unsigned char *pub, unsigned int pubSz);
+
+#ifdef __cplusplus
+}  /* extern "C" */
+#endif
+
+#endif /* header */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ecdh.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ecdh.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ecdh.h	(revision 164)
@@ -0,0 +1,28 @@
+/* ecdh.h for openssl */
+
+#ifndef WOLFSSL_ECDH_H_
+#define WOLFSSL_ECDH_H_
+
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/openssl/bn.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+WOLFSSL_API int wolfSSL_ECDH_compute_key(void *out, size_t outlen,
+                                         const WOLFSSL_EC_POINT *pub_key,
+                                         WOLFSSL_EC_KEY *ecdh,
+                                         void *(*KDF) (const void *in,
+                                                       size_t inlen,
+                                                       void *out,
+                                                       size_t *outlen));
+
+#define ECDH_compute_key wolfSSL_ECDH_compute_key
+
+#ifdef __cplusplus
+}  /* extern C */
+#endif
+
+#endif /* header */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ecdsa.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ecdsa.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ecdsa.h	(revision 164)
@@ -0,0 +1,39 @@
+/* ecdsa.h for openssl */
+
+#ifndef WOLFSSL_ECDSA_H_
+#define WOLFSSL_ECDSA_H_
+
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/openssl/bn.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct WOLFSSL_ECDSA_SIG {
+    WOLFSSL_BIGNUM *r;
+    WOLFSSL_BIGNUM *s;
+};
+
+WOLFSSL_API void wolfSSL_ECDSA_SIG_free(WOLFSSL_ECDSA_SIG *sig);
+WOLFSSL_API WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_SIG_new(void);
+WOLFSSL_API WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *dgst,
+                                                     int dgst_len,
+                                                     WOLFSSL_EC_KEY *eckey);
+WOLFSSL_API int wolfSSL_ECDSA_do_verify(const unsigned char *dgst,
+                                        int dgst_len,
+                                        const WOLFSSL_ECDSA_SIG *sig,
+                                        WOLFSSL_EC_KEY *eckey);
+
+#define ECDSA_SIG_free wolfSSL_ECDSA_SIG_free
+#define ECDSA_SIG_new wolfSSL_ECDSA_SIG_new
+#define ECDSA_do_sign wolfSSL_ECDSA_do_sign
+#define ECDSA_do_verify wolfSSL_ECDSA_do_verify
+
+#ifdef __cplusplus
+}  /* extern "C" */
+#endif
+
+#endif /* header */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ed25519.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ed25519.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ed25519.h	(revision 164)
@@ -0,0 +1,26 @@
+/* ed25519.h */
+
+#ifndef WOLFSSL_ED25519_H_
+#define WOLFSSL_ED25519_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+WOLFSSL_API
+int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz,
+                                 unsigned char *pub, unsigned int *pubSz);
+WOLFSSL_API
+int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
+                         const unsigned char *priv, unsigned int privSz,
+                         unsigned char *sig, unsigned int *sigSz);
+WOLFSSL_API
+int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
+                           const unsigned char *pub, unsigned int pubSz,
+                           const unsigned char *sig, unsigned int sigSz);
+
+#ifdef __cplusplus
+}  /* extern "C" */
+#endif
+
+#endif /* header */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/err.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/err.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/err.h	(revision 164)
@@ -0,0 +1,3 @@
+/* err.h for openssl */
+#define ERR_load_crypto_strings          wolfSSL_ERR_load_crypto_strings
+#define ERR_peek_last_error              wolfSSL_ERR_peek_last_error
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/evp.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/evp.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/evp.h	(revision 164)
@@ -0,0 +1,268 @@
+/* evp.h
+ *
+ * Copyright (C) 2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/*  evp.h defines mini evp openssl compatibility layer 
+ *
+ */
+
+
+#ifndef WOLFSSL_EVP_H_
+#define WOLFSSL_EVP_H_
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef WOLFSSL_PREFIX
+#include "prefix_evp.h"
+#endif
+
+#ifndef NO_MD5
+    #include <wolfssl/openssl/md5.h>
+#endif
+#include <wolfssl/openssl/sha.h>
+#include <wolfssl/openssl/ripemd.h>
+#include <wolfssl/openssl/rsa.h>
+#include <wolfssl/openssl/dsa.h>
+#include <wolfssl/openssl/ec.h>
+
+#include <wolfssl/wolfcrypt/aes.h>
+#include <wolfssl/wolfcrypt/des3.h>
+#include <wolfssl/wolfcrypt/arc4.h>
+
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+typedef char WOLFSSL_EVP_MD;
+typedef char WOLFSSL_EVP_CIPHER;
+
+#ifndef NO_MD5
+    WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void);
+#endif
+WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void);
+WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void);
+WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void);
+WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void);
+WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_ripemd160(void);
+
+WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void);
+WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void);
+WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void);
+WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void);
+WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void);
+WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void);
+WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void);
+WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void);
+WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void);
+WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_idea_cbc(void);
+WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void);
+
+
+typedef union {
+    #ifndef NO_MD5
+        WOLFSSL_MD5_CTX    md5;
+    #endif
+    WOLFSSL_SHA_CTX    sha;
+    WOLFSSL_SHA256_CTX sha256;
+    #ifdef WOLFSSL_SHA384
+        WOLFSSL_SHA384_CTX sha384;
+    #endif
+    #ifdef WOLFSSL_SHA512
+        WOLFSSL_SHA512_CTX sha512;
+    #endif
+    #ifdef WOLFSSL_RIPEMD
+        WOLFSSL_RIPEMD_CTX ripemd;
+    #endif
+} WOLFSSL_Hasher;
+
+
+typedef struct WOLFSSL_EVP_MD_CTX {
+    unsigned char macType;
+    WOLFSSL_Hasher hash;
+} WOLFSSL_EVP_MD_CTX;
+
+
+typedef union {
+#ifndef NO_AES
+    Aes  aes;
+#endif
+#ifndef NO_DES3
+    Des  des;
+    Des3 des3;
+#endif
+    Arc4 arc4;
+#ifdef HAVE_IDEA
+    Idea idea;
+#endif
+} WOLFSSL_Cipher;
+
+
+enum {
+    AES_128_CBC_TYPE  = 1,
+    AES_192_CBC_TYPE  = 2,
+    AES_256_CBC_TYPE  = 3,
+    AES_128_CTR_TYPE  = 4,
+    AES_192_CTR_TYPE  = 5,
+    AES_256_CTR_TYPE  = 6,
+    DES_CBC_TYPE      = 7,
+    DES_EDE3_CBC_TYPE = 8,
+    ARC4_TYPE         = 9,
+    NULL_CIPHER_TYPE  = 10,
+    EVP_PKEY_RSA      = 11,
+    EVP_PKEY_DSA      = 12,
+	EVP_PKEY_EC		  = 13,
+    IDEA_CBC_TYPE     = 14,
+    NID_sha1          = 64,
+    NID_md5           =  4
+};
+
+
+typedef struct WOLFSSL_EVP_CIPHER_CTX {
+    int            keyLen;         /* user may set for variable */
+    unsigned char  enc;            /* if encrypt side, then true */
+    unsigned char  cipherType;
+#ifndef NO_AES
+    unsigned char  iv[AES_BLOCK_SIZE];    /* working iv pointer into cipher */
+#elif !defined(NO_DES3)
+    unsigned char  iv[DES_BLOCK_SIZE];    /* working iv pointer into cipher */
+#endif
+    WOLFSSL_Cipher  cipher;
+} WOLFSSL_EVP_CIPHER_CTX;
+
+
+WOLFSSL_API int  wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* md);
+WOLFSSL_API void wolfSSL_EVP_MD_CTX_init(WOLFSSL_EVP_MD_CTX* ctx);
+WOLFSSL_API int  wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx);
+
+WOLFSSL_API int wolfSSL_EVP_DigestInit(WOLFSSL_EVP_MD_CTX* ctx,
+                                     const WOLFSSL_EVP_MD* type);
+WOLFSSL_API int wolfSSL_EVP_DigestUpdate(WOLFSSL_EVP_MD_CTX* ctx, const void* data,
+                                       unsigned long sz);
+WOLFSSL_API int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md,
+                                      unsigned int* s);
+WOLFSSL_API int wolfSSL_EVP_DigestFinal_ex(WOLFSSL_EVP_MD_CTX* ctx,
+                                            unsigned char* md, unsigned int* s);
+#ifndef NO_MD5
+WOLFSSL_API int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER*,
+                              const WOLFSSL_EVP_MD*, const unsigned char*,
+                              const unsigned char*, int, int, unsigned char*,
+                              unsigned char*);
+#endif
+
+WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx);
+WOLFSSL_API int  wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx);
+
+WOLFSSL_API int  wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX*);
+
+
+WOLFSSL_API int  wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
+                                    const WOLFSSL_EVP_CIPHER* type,
+                                    unsigned char* key, unsigned char* iv,
+                                    int enc);
+WOLFSSL_API int  wolfSSL_EVP_CIPHER_CTX_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx);
+WOLFSSL_API int  wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx,
+                                                     int keylen);
+WOLFSSL_API int  wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx,
+                          unsigned char* dst, unsigned char* src,
+                          unsigned int len);
+
+WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int);
+
+WOLFSSL_API WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY*);
+WOLFSSL_API WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY*);
+WOLFSSL_API WOLFSSL_EC_KEY *wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY *key);
+
+/* these next ones don't need real OpenSSL type, for OpenSSH compat only */
+WOLFSSL_API void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx);
+WOLFSSL_API int   wolfSSL_EVP_X_STATE_LEN(const WOLFSSL_EVP_CIPHER_CTX* ctx);
+
+WOLFSSL_API void  wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
+                                unsigned char* iv, int len);
+WOLFSSL_API void  wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
+                                unsigned char* iv, int len);
+
+WOLFSSL_API int  wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx);
+WOLFSSL_API int  wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx);
+
+
+/* end OpenSSH compat */
+
+typedef WOLFSSL_EVP_MD         EVP_MD;
+typedef WOLFSSL_EVP_CIPHER     EVP_CIPHER;
+typedef WOLFSSL_EVP_MD_CTX     EVP_MD_CTX;
+typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX;
+
+#ifndef NO_MD5
+    #define EVP_md5       wolfSSL_EVP_md5
+#endif
+#define EVP_sha1      wolfSSL_EVP_sha1
+#define EVP_sha256    wolfSSL_EVP_sha256
+#define EVP_sha384    wolfSSL_EVP_sha384
+#define EVP_sha512    wolfSSL_EVP_sha512
+#define EVP_ripemd160 wolfSSL_EVP_ripemd160
+
+#define EVP_aes_128_cbc  wolfSSL_EVP_aes_128_cbc
+#define EVP_aes_192_cbc  wolfSSL_EVP_aes_192_cbc
+#define EVP_aes_256_cbc  wolfSSL_EVP_aes_256_cbc
+#define EVP_aes_128_ctr  wolfSSL_EVP_aes_128_ctr
+#define EVP_aes_192_ctr  wolfSSL_EVP_aes_192_ctr
+#define EVP_aes_256_ctr  wolfSSL_EVP_aes_256_ctr
+#define EVP_des_cbc      wolfSSL_EVP_des_cbc
+#define EVP_des_ede3_cbc wolfSSL_EVP_des_ede3_cbc
+#define EVP_rc4          wolfSSL_EVP_rc4
+#define EVP_idea_cbc     wolfSSL_EVP_idea_cbc
+#define EVP_enc_null     wolfSSL_EVP_enc_null
+
+#define EVP_MD_size        wolfSSL_EVP_MD_size
+#define EVP_MD_CTX_init    wolfSSL_EVP_MD_CTX_init
+#define EVP_MD_CTX_cleanup wolfSSL_EVP_MD_CTX_cleanup
+#define EVP_DigestInit     wolfSSL_EVP_DigestInit
+#define EVP_DigestUpdate   wolfSSL_EVP_DigestUpdate
+#define EVP_DigestFinal    wolfSSL_EVP_DigestFinal
+#define EVP_DigestFinal_ex wolfSSL_EVP_DigestFinal_ex
+#define EVP_BytesToKey     wolfSSL_EVP_BytesToKey
+
+#define EVP_CIPHER_CTX_init           wolfSSL_EVP_CIPHER_CTX_init
+#define EVP_CIPHER_CTX_cleanup        wolfSSL_EVP_CIPHER_CTX_cleanup
+#define EVP_CIPHER_CTX_iv_length      wolfSSL_EVP_CIPHER_CTX_iv_length
+#define EVP_CIPHER_CTX_key_length     wolfSSL_EVP_CIPHER_CTX_key_length
+#define EVP_CIPHER_CTX_set_key_length wolfSSL_EVP_CIPHER_CTX_set_key_length
+#define EVP_CipherInit                wolfSSL_EVP_CipherInit
+#define EVP_Cipher                    wolfSSL_EVP_Cipher
+
+#define EVP_get_digestbynid           wolfSSL_EVP_get_digestbynid
+
+#define EVP_PKEY_get1_RSA   wolfSSL_EVP_PKEY_get1_RSA
+#define EVP_PKEY_get1_DSA   wolfSSL_EVP_PKEY_get1_DSA
+#define EVP_PKEY_get1_EC_KEY wolfSSL_EVP_PKEY_get1_EC_KEY
+
+
+#ifndef EVP_MAX_MD_SIZE
+    #define EVP_MAX_MD_SIZE   64     /* sha512 */
+#endif
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+
+#endif /* WOLFSSL_EVP_H_ */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/hmac.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/hmac.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/hmac.h	(revision 164)
@@ -0,0 +1,81 @@
+/* hmac.h
+ *
+ * Copyright (C) 2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/*  hmac.h defines mini hamc openssl compatibility layer 
+ *
+ */
+
+
+#ifndef WOLFSSL_HMAC_H_
+#define WOLFSSL_HMAC_H_
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef WOLFSSL_PREFIX
+#include "prefix_hmac.h"
+#endif
+
+#include <wolfssl/openssl/evp.h>
+#include <wolfssl/wolfcrypt/hmac.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+WOLFSSL_API unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md,
+                               const void* key, int key_len,
+                               const unsigned char* d, int n, unsigned char* md,
+                               unsigned int* md_len);
+
+
+typedef struct WOLFSSL_HMAC_CTX {
+    Hmac hmac;
+    int  type;
+} WOLFSSL_HMAC_CTX;
+
+
+WOLFSSL_API void wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key,
+                                 int keylen, const EVP_MD* type);
+WOLFSSL_API void wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx,
+                                   const unsigned char* data, int len);
+WOLFSSL_API void wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash,
+                                  unsigned int* len);
+WOLFSSL_API void wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx);
+
+
+typedef struct WOLFSSL_HMAC_CTX HMAC_CTX;
+
+#define HMAC(a,b,c,d,e,f,g) wolfSSL_HMAC((a),(b),(c),(d),(e),(f),(g))
+
+#define HMAC_Init    wolfSSL_HMAC_Init
+#define HMAC_Update  wolfSSL_HMAC_Update
+#define HMAC_Final   wolfSSL_HMAC_Final
+#define HMAC_cleanup wolfSSL_HMAC_cleanup
+
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+
+#endif /* WOLFSSL_HMAC_H_ */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/md5.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/md5.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/md5.h	(revision 164)
@@ -0,0 +1,42 @@
+/* md5.h for openssl */
+
+
+#ifndef WOLFSSL_MD5_H_
+#define WOLFSSL_MD5_H_
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_MD5
+
+#ifdef WOLFSSL_PREFIX
+#include "prefix_md5.h"
+#endif
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+typedef struct WOLFSSL_MD5_CTX {
+    int holder[24];   /* big enough to hold wolfcrypt md5, but check on init */
+} WOLFSSL_MD5_CTX;
+
+WOLFSSL_API void wolfSSL_MD5_Init(WOLFSSL_MD5_CTX*);
+WOLFSSL_API void wolfSSL_MD5_Update(WOLFSSL_MD5_CTX*, const void*, unsigned long);
+WOLFSSL_API void wolfSSL_MD5_Final(unsigned char*, WOLFSSL_MD5_CTX*);
+
+
+typedef WOLFSSL_MD5_CTX MD5_CTX;
+
+#define MD5_Init wolfSSL_MD5_Init
+#define MD5_Update wolfSSL_MD5_Update
+#define MD5_Final wolfSSL_MD5_Final
+
+#ifdef __cplusplus
+    }  /* extern "C" */ 
+#endif
+
+#endif /* NO_MD5 */
+
+#endif /* WOLFSSL_MD5_H_ */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ocsp.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ocsp.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ocsp.h	(revision 164)
@@ -0,0 +1,1 @@
+/* ocsp.h for libcurl */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/opensslv.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/opensslv.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/opensslv.h	(revision 164)
@@ -0,0 +1,20 @@
+/* opensslv.h compatibility */
+
+#ifndef WOLFSSL_OPENSSLV_H_
+#define WOLFSSL_OPENSSLV_H_
+
+
+/* api version compatibility */
+#if defined(HAVE_STUNNEL) || defined(HAVE_LIGHTY)
+     /* version number can be increased for Lighty after compatibility for ECDH
+        is added */
+     #define OPENSSL_VERSION_NUMBER 0x0090700fL
+#else
+     #define OPENSSL_VERSION_NUMBER 0x0090810fL
+#endif
+
+#define OPENSSL_VERSION_TEXT             LIBWOLFSSL_VERSION_STRING
+
+
+#endif /* header */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/pem.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/pem.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/pem.h	(revision 164)
@@ -0,0 +1,125 @@
+/* pem.h for openssl */
+
+
+#ifndef WOLFSSL_PEM_H_
+#define WOLFSSL_PEM_H_
+
+#include <wolfssl/openssl/evp.h>
+#include <wolfssl/openssl/bio.h>
+#include <wolfssl/openssl/rsa.h>
+#include <wolfssl/openssl/dsa.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+/* RSA */
+WOLFSSL_API
+int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa,
+                                        const EVP_CIPHER* cipher,
+                                        unsigned char* passwd, int len,
+                                        pem_password_cb cb, void* arg);
+WOLFSSL_API
+int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher,
+                                        unsigned char* passwd, int len,
+                                        unsigned char **pem, int *plen);
+#if !defined(NO_FILESYSTEM)
+WOLFSSL_API
+int wolfSSL_PEM_write_RSAPrivateKey(XFILE fp, WOLFSSL_RSA *rsa,
+                                    const EVP_CIPHER *enc,
+                                    unsigned char *kstr, int klen,
+                                    pem_password_cb *cb, void *u);
+WOLFSSL_API
+WOLFSSL_RSA *wolfSSL_PEM_read_RSAPublicKey(XFILE fp, WOLFSSL_RSA **x,
+                                           pem_password_cb *cb, void *u);
+WOLFSSL_API
+int wolfSSL_PEM_write_RSAPublicKey(XFILE fp, WOLFSSL_RSA *x);
+
+WOLFSSL_API
+int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA *x);
+#endif /* NO_FILESYSTEM */
+
+/* DSA */
+WOLFSSL_API
+int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio,
+                                        WOLFSSL_DSA* dsa,
+                                        const EVP_CIPHER* cipher,
+                                        unsigned char* passwd, int len,
+                                        pem_password_cb cb, void* arg);
+WOLFSSL_API
+int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa,
+                                        const EVP_CIPHER* cipher,
+                                        unsigned char* passwd, int len,
+                                        unsigned char **pem, int *plen);
+#if !defined(NO_FILESYSTEM)
+WOLFSSL_API
+int wolfSSL_PEM_write_DSAPrivateKey(XFILE fp, WOLFSSL_DSA *dsa,
+                                    const EVP_CIPHER *enc,
+                                    unsigned char *kstr, int klen,
+                                    pem_password_cb *cb, void *u);
+WOLFSSL_API
+int wolfSSL_PEM_write_DSA_PUBKEY(XFILE fp, WOLFSSL_DSA *x);
+#endif /* NO_FILESYSTEM */
+
+/* ECC */
+WOLFSSL_API
+int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec,
+                                       const EVP_CIPHER* cipher,
+                                       unsigned char* passwd, int len,
+                                       pem_password_cb cb, void* arg);
+WOLFSSL_API
+int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* key,
+                                       const EVP_CIPHER* cipher,
+                                       unsigned char* passwd, int len,
+                                       unsigned char **pem, int *plen);
+#if !defined(NO_FILESYSTEM)
+WOLFSSL_API
+int wolfSSL_PEM_write_ECPrivateKey(XFILE fp, WOLFSSL_EC_KEY *key,
+                                   const EVP_CIPHER *enc,
+                                   unsigned char *kstr, int klen,
+                                   pem_password_cb *cb, void *u);
+WOLFSSL_API
+int wolfSSL_PEM_write_EC_PUBKEY(XFILE fp, WOLFSSL_EC_KEY *key);
+#endif /* NO_FILESYSTEM */
+
+/* EVP_KEY */
+WOLFSSL_API
+WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
+                                                  WOLFSSL_EVP_PKEY**,
+                                                  pem_password_cb cb,
+                                                  void* arg);
+WOLFSSL_API
+int wolfSSL_EVP_PKEY_type(int type);
+
+#if !defined(NO_FILESYSTEM)
+WOLFSSL_API
+WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, EVP_PKEY **x,
+										  pem_password_cb *cb, void *u);
+#endif /* NO_FILESYSTEM */
+
+/* RSA */
+#define PEM_write_bio_RSAPrivateKey wolfSSL_PEM_write_bio_RSAPrivateKey
+#define PEM_write_RSAPrivateKey     wolfSSL_PEM_write_RSAPrivateKey
+#define PEM_write_RSA_PUBKEY        wolfSSL_PEM_write_RSA_PUBKEY
+#define PEM_write_RSAPublicKey      wolfSSL_PEM_write_RSAPublicKey
+#define PEM_read_RSAPublicKey       wolfSSL_PEM_read_RSAPublicKey
+/* DSA */
+#define PEM_write_bio_DSAPrivateKey wolfSSL_PEM_write_bio_DSAPrivateKey
+#define PEM_write_DSAPrivateKey     wolfSSL_PEM_write_DSAPrivateKey
+#define PEM_write_DSA_PUBKEY        wolfSSL_PEM_write_DSA_PUBKEY
+/* ECC */
+#define PEM_write_bio_ECPrivateKey wolfSSL_PEM_write_bio_ECPrivateKey
+#define PEM_write_EC_PUBKEY        wolfSSL_PEM_write_EC_PUBKEY
+#define PEM_write_ECPrivateKey     wolfSSL_PEM_write_ECPrivateKey
+/* EVP_KEY */
+#define PEM_read_bio_PrivateKey wolfSSL_PEM_read_bio_PrivateKey
+#define PEM_read_PUBKEY         wolfSSL_PEM_read_PUBKEY
+#define EVP_PKEY_type           wolfSSL_EVP_PKEY_type
+
+#ifdef __cplusplus
+    }  /* extern "C" */ 
+#endif
+
+#endif /* WOLFSSL_PEM_H_ */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/rand.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/rand.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/rand.h	(revision 164)
@@ -0,0 +1,6 @@
+/* rand.h for openSSL */
+
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/wolfcrypt/random.h>
+
+#define RAND_set_rand_method     wolfSSL_RAND_set_rand_method
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ripemd.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ripemd.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ripemd.h	(revision 164)
@@ -0,0 +1,37 @@
+/* ripemd.h for openssl */
+
+
+#ifndef WOLFSSL_RIPEMD_H_
+#define WOLFSSL_RIPEMD_H_
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+typedef struct WOLFSSL_RIPEMD_CTX {
+    int holder[32];   /* big enough to hold wolfcrypt, but check on init */
+} WOLFSSL_RIPEMD_CTX;
+
+WOLFSSL_API void wolfSSL_RIPEMD_Init(WOLFSSL_RIPEMD_CTX*);
+WOLFSSL_API void wolfSSL_RIPEMD_Update(WOLFSSL_RIPEMD_CTX*, const void*,
+                                     unsigned long);
+WOLFSSL_API void wolfSSL_RIPEMD_Final(unsigned char*, WOLFSSL_RIPEMD_CTX*);
+
+
+typedef WOLFSSL_RIPEMD_CTX RIPEMD_CTX;
+
+#define RIPEMD_Init   wolfSSL_RIPEMD_Init
+#define RIPEMD_Update wolfSSL_RIPEMD_Update
+#define RIPEMD_Final  wolfSSL_RIPEMD_Final
+
+
+#ifdef __cplusplus
+    }  /* extern "C" */ 
+#endif
+
+
+#endif /* WOLFSSL_MD5_H_ */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/rsa.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/rsa.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/rsa.h	(revision 164)
@@ -0,0 +1,75 @@
+/* rsa.h for openSSL */
+
+
+#ifndef WOLFSSL_RSA_H_
+#define WOLFSSL_RSA_H_
+
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/openssl/bn.h>
+
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+enum  { 
+	RSA_PKCS1_PADDING = 1
+ };
+
+struct WOLFSSL_RSA {
+	WOLFSSL_BIGNUM* n;
+	WOLFSSL_BIGNUM* e;
+	WOLFSSL_BIGNUM* d;
+	WOLFSSL_BIGNUM* p;
+	WOLFSSL_BIGNUM* q;
+	WOLFSSL_BIGNUM* dmp1;      /* dP */
+	WOLFSSL_BIGNUM* dmq1;      /* dQ */
+	WOLFSSL_BIGNUM* iqmp;      /* u */
+    void*          internal;  /* our RSA */
+    char           inSet;     /* internal set from external ? */
+    char           exSet;     /* external set from internal ? */
+};
+
+
+WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSA_new(void);
+WOLFSSL_API void        wolfSSL_RSA_free(WOLFSSL_RSA*);
+
+WOLFSSL_API int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA*, int bits, WOLFSSL_BIGNUM*,
+                                          void* cb);
+
+WOLFSSL_API int wolfSSL_RSA_blinding_on(WOLFSSL_RSA*, WOLFSSL_BN_CTX*);
+WOLFSSL_API int wolfSSL_RSA_public_encrypt(int len, unsigned char* fr,
+	                               unsigned char* to, WOLFSSL_RSA*, int padding);
+WOLFSSL_API int wolfSSL_RSA_private_decrypt(int len, unsigned char* fr,
+	                               unsigned char* to, WOLFSSL_RSA*, int padding);
+
+WOLFSSL_API int wolfSSL_RSA_size(const WOLFSSL_RSA*);
+WOLFSSL_API int wolfSSL_RSA_sign(int type, const unsigned char* m,
+                               unsigned int mLen, unsigned char* sigRet,
+                               unsigned int* sigLen, WOLFSSL_RSA*);
+WOLFSSL_API int wolfSSL_RSA_public_decrypt(int flen, unsigned char* from,
+                                  unsigned char* to, WOLFSSL_RSA*, int padding);
+WOLFSSL_API int wolfSSL_RSA_GenAdd(WOLFSSL_RSA*);
+WOLFSSL_API int wolfSSL_RSA_LoadDer(WOLFSSL_RSA*, const unsigned char*, int sz);
+
+
+#define RSA_new  wolfSSL_RSA_new
+#define RSA_free wolfSSL_RSA_free
+
+#define RSA_generate_key_ex wolfSSL_RSA_generate_key_ex
+
+#define RSA_blinding_on     wolfSSL_RSA_blinding_on
+#define RSA_public_encrypt  wolfSSL_RSA_public_encrypt
+#define RSA_private_decrypt wolfSSL_RSA_private_decrypt
+
+#define RSA_size           wolfSSL_RSA_size
+#define RSA_sign           wolfSSL_RSA_sign
+#define RSA_public_decrypt wolfSSL_RSA_public_decrypt
+
+
+#ifdef __cplusplus
+    }  /* extern "C" */ 
+#endif
+
+#endif /* header */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/sha.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/sha.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/sha.h	(revision 164)
@@ -0,0 +1,125 @@
+/* sha.h for openssl */
+
+
+#ifndef WOLFSSL_SHA_H_
+#define WOLFSSL_SHA_H_
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef WOLFSSL_PREFIX
+#include "prefix_sha.h"
+#endif
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+typedef struct WOLFSSL_SHA_CTX {
+    int holder[24];   /* big enough to hold wolfcrypt sha, but check on init */
+} WOLFSSL_SHA_CTX;
+
+WOLFSSL_API void wolfSSL_SHA_Init(WOLFSSL_SHA_CTX*);
+WOLFSSL_API void wolfSSL_SHA_Update(WOLFSSL_SHA_CTX*, const void*, unsigned long);
+WOLFSSL_API void wolfSSL_SHA_Final(unsigned char*, WOLFSSL_SHA_CTX*);
+
+/* SHA1 points to above, shouldn't use SHA0 ever */
+WOLFSSL_API void wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX*);
+WOLFSSL_API void wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX*, const void*, unsigned long);
+WOLFSSL_API void wolfSSL_SHA1_Final(unsigned char*, WOLFSSL_SHA_CTX*);
+
+enum {
+    SHA_DIGEST_LENGTH = 20
+};
+
+
+typedef WOLFSSL_SHA_CTX SHA_CTX;
+
+#define SHA_Init wolfSSL_SHA_Init
+#define SHA_Update wolfSSL_SHA_Update
+#define SHA_Final wolfSSL_SHA_Final
+
+#define SHA1_Init wolfSSL_SHA1_Init
+#define SHA1_Update wolfSSL_SHA1_Update
+#define SHA1_Final wolfSSL_SHA1_Final
+
+
+typedef struct WOLFSSL_SHA256_CTX {
+    int holder[28];   /* big enough to hold wolfcrypt sha, but check on init */
+} WOLFSSL_SHA256_CTX;
+
+WOLFSSL_API void wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX*);
+WOLFSSL_API void wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX*, const void*,
+	                                 unsigned long);
+WOLFSSL_API void wolfSSL_SHA256_Final(unsigned char*, WOLFSSL_SHA256_CTX*);
+
+enum {
+    SHA256_DIGEST_LENGTH = 32 
+};
+
+
+typedef WOLFSSL_SHA256_CTX SHA256_CTX;
+
+#define SHA256_Init   wolfSSL_SHA256_Init
+#define SHA256_Update wolfSSL_SHA256_Update
+#define SHA256_Final  wolfSSL_SHA256_Final
+
+
+#ifdef WOLFSSL_SHA384
+
+typedef struct WOLFSSL_SHA384_CTX {
+    long long holder[32];   /* big enough, but check on init */
+} WOLFSSL_SHA384_CTX;
+
+WOLFSSL_API void wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX*);
+WOLFSSL_API void wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX*, const void*,
+	                                 unsigned long);
+WOLFSSL_API void wolfSSL_SHA384_Final(unsigned char*, WOLFSSL_SHA384_CTX*);
+
+enum {
+    SHA384_DIGEST_LENGTH = 48 
+};
+
+
+typedef WOLFSSL_SHA384_CTX SHA384_CTX;
+
+#define SHA384_Init   wolfSSL_SHA384_Init
+#define SHA384_Update wolfSSL_SHA384_Update
+#define SHA384_Final  wolfSSL_SHA384_Final
+
+#endif /* WOLFSSL_SHA384 */
+
+#ifdef WOLFSSL_SHA512
+
+typedef struct WOLFSSL_SHA512_CTX {
+    long long holder[36];   /* big enough, but check on init */
+} WOLFSSL_SHA512_CTX;
+
+WOLFSSL_API void wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX*);
+WOLFSSL_API void wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX*, const void*,
+	                                 unsigned long);
+WOLFSSL_API void wolfSSL_SHA512_Final(unsigned char*, WOLFSSL_SHA512_CTX*);
+
+enum {
+    SHA512_DIGEST_LENGTH = 64 
+};
+
+
+typedef WOLFSSL_SHA512_CTX SHA512_CTX;
+
+#define SHA512_Init   wolfSSL_SHA512_Init
+#define SHA512_Update wolfSSL_SHA512_Update
+#define SHA512_Final  wolfSSL_SHA512_Final
+
+#endif /* WOLFSSL_SHA512 */
+
+
+
+
+#ifdef __cplusplus
+    }  /* extern "C" */ 
+#endif
+
+
+#endif /* WOLFSSL_SHA_H_ */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ssl.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ssl.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ssl.h	(revision 164)
@@ -0,0 +1,504 @@
+/* ssl.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * a with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/*  ssl.h defines wolfssl_openssl compatibility layer 
+ *
+ */
+
+
+#ifndef WOLFSSL_OPENSSL_H_
+#define WOLFSSL_OPENSSL_H_
+
+/* wolfssl_openssl compatibility layer */
+#include <wolfssl/ssl.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#ifdef _WIN32
+    /* wincrypt.h clashes */
+    #undef X509_NAME
+#endif
+
+
+typedef WOLFSSL          SSL;
+typedef WOLFSSL_SESSION  SSL_SESSION;
+typedef WOLFSSL_METHOD   SSL_METHOD;
+typedef WOLFSSL_CTX      SSL_CTX;
+
+typedef WOLFSSL_X509       X509;
+typedef WOLFSSL_X509_NAME  X509_NAME;
+typedef WOLFSSL_X509_CHAIN X509_CHAIN;
+
+
+/* redeclare guard */
+#define WOLFSSL_TYPES_DEFINED
+
+
+typedef WOLFSSL_EVP_PKEY       EVP_PKEY;
+typedef WOLFSSL_RSA            RSA;
+typedef WOLFSSL_DSA            DSA;
+typedef WOLFSSL_EC_KEY         EC_KEY;
+typedef WOLFSSL_EC_GROUP       EC_GROUP;
+typedef WOLFSSL_EC_POINT       EC_POINT;
+typedef WOLFSSL_ECDSA_SIG	   ECDSA_SIG;
+typedef WOLFSSL_BIO            BIO;
+typedef WOLFSSL_BIO_METHOD     BIO_METHOD;
+typedef WOLFSSL_CIPHER         SSL_CIPHER;
+typedef WOLFSSL_X509_LOOKUP    X509_LOOKUP;
+typedef WOLFSSL_X509_LOOKUP_METHOD X509_LOOKUP_METHOD;
+typedef WOLFSSL_X509_CRL       X509_CRL;
+typedef WOLFSSL_X509_EXTENSION X509_EXTENSION;
+typedef WOLFSSL_ASN1_TIME      ASN1_TIME;
+typedef WOLFSSL_ASN1_INTEGER   ASN1_INTEGER;
+typedef WOLFSSL_ASN1_OBJECT    ASN1_OBJECT;
+typedef WOLFSSL_ASN1_STRING    ASN1_STRING;
+typedef WOLFSSL_dynlock_value  CRYPTO_dynlock_value;
+
+#define ASN1_UTCTIME WOLFSSL_ASN1_TIME
+
+typedef WOLFSSL_MD4_CTX        MD4_CTX;
+typedef WOLFSSL_COMP_METHOD    COMP_METHOD;
+typedef WOLFSSL_X509_STORE     X509_STORE;
+typedef WOLFSSL_X509_REVOKED   X509_REVOKED;
+typedef WOLFSSL_X509_OBJECT    X509_OBJECT;
+typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
+
+#define SSL_get_cipher_list(ctx,i)          wolfSSL_get_cipher_list((i))
+#define SSL_get_cipher_name(ctx)            wolfSSL_get_cipher((ctx))
+#define SSL_get_shared_ciphers(ctx,buf,len) \
+                                strncpy(buf, "Not Implemented, SSLv2 only", len)
+
+/* @TODO */
+#define ERR_print_errors_fp(file)
+
+/* at the moment only returns ok */
+#define SSL_get_verify_result(ctx)    X509_V_OK
+#define SSL_get_verify_mode           wolfSSL_SSL_get_mode
+#define SSL_get_verify_depth          wolfSSL_get_verify_depth
+#define SSL_CTX_get_verify_mode       wolfSSL_CTX_get_verify_mode
+#define SSL_CTX_get_verify_depth      wolfSSL_CTX_get_verify_depth
+#define SSL_get_certificate(ctx)      0 /* used to pass to get_privatekey */
+
+#define SSLv3_server_method wolfSSLv3_server_method
+#define SSLv3_client_method wolfSSLv3_client_method
+#define TLSv1_server_method wolfTLSv1_server_method
+#define TLSv1_client_method wolfTLSv1_client_method
+#define TLSv1_1_server_method wolfTLSv1_1_server_method
+#define TLSv1_1_client_method wolfTLSv1_1_client_method
+#define TLSv1_2_server_method wolfTLSv1_2_server_method
+#define TLSv1_2_client_method wolfTLSv1_2_client_method
+
+#ifdef WOLFSSL_DTLS
+    #define DTLSv1_client_method wolfDTLSv1_client_method
+    #define DTLSv1_server_method wolfDTLSv1_server_method
+    #define DTLSv1_2_client_method wolfDTLSv1_2_client_method
+    #define DTLSv1_2_server_method wolfDTLSv1_2_server_method
+#endif
+
+
+#ifndef NO_FILESYSTEM
+    #define SSL_CTX_use_certificate_file wolfSSL_CTX_use_certificate_file
+    #define SSL_CTX_use_PrivateKey_file wolfSSL_CTX_use_PrivateKey_file
+    #define SSL_CTX_load_verify_locations wolfSSL_CTX_load_verify_locations
+    #define SSL_CTX_use_certificate_chain_file wolfSSL_CTX_use_certificate_chain_file
+    #define SSL_CTX_use_RSAPrivateKey_file wolfSSL_CTX_use_RSAPrivateKey_file
+    
+    #define SSL_use_certificate_file wolfSSL_use_certificate_file
+    #define SSL_use_PrivateKey_file wolfSSL_use_PrivateKey_file
+    #define SSL_use_certificate_chain_file wolfSSL_use_certificate_chain_file
+    #define SSL_use_RSAPrivateKey_file wolfSSL_use_RSAPrivateKey_file
+#endif
+
+#define SSL_CTX_new wolfSSL_CTX_new
+#define SSL_new     wolfSSL_new
+#define SSL_set_fd  wolfSSL_set_fd
+#define SSL_get_fd  wolfSSL_get_fd
+#define SSL_connect wolfSSL_connect
+#define SSL_clear   wolfSSL_clear
+
+#define SSL_write    wolfSSL_write
+#define SSL_read     wolfSSL_read
+#define SSL_peek     wolfSSL_peek
+#define SSL_accept   wolfSSL_accept
+#define SSL_CTX_free wolfSSL_CTX_free
+#define SSL_free     wolfSSL_free
+#define SSL_shutdown wolfSSL_shutdown
+
+#define SSL_CTX_set_quiet_shutdown wolfSSL_CTX_set_quiet_shutdown
+#define SSL_set_quiet_shutdown wolfSSL_set_quiet_shutdown
+#define SSL_get_error wolfSSL_get_error
+#define SSL_set_session wolfSSL_set_session
+#define SSL_get_session wolfSSL_get_session
+#define SSL_flush_sessions wolfSSL_flush_sessions
+/* assume unlimited temporarly */
+#define SSL_CTX_get_session_cache_mode(ctx) 0
+
+#define SSL_CTX_set_verify wolfSSL_CTX_set_verify
+#define SSL_set_verify wolfSSL_set_verify
+#define SSL_pending wolfSSL_pending
+#define SSL_load_error_strings wolfSSL_load_error_strings
+#define SSL_library_init wolfSSL_library_init
+#define SSL_CTX_set_session_cache_mode wolfSSL_CTX_set_session_cache_mode
+#define SSL_CTX_set_cipher_list wolfSSL_CTX_set_cipher_list
+#define SSL_set_cipher_list     wolfSSL_set_cipher_list
+
+#define ERR_error_string wolfSSL_ERR_error_string
+#define ERR_error_string_n wolfSSL_ERR_error_string_n
+#define ERR_reason_error_string wolfSSL_ERR_reason_error_string
+
+#define SSL_set_ex_data wolfSSL_set_ex_data
+#define SSL_get_shutdown wolfSSL_get_shutdown
+#define SSL_set_rfd wolfSSL_set_rfd
+#define SSL_set_wfd wolfSSL_set_wfd
+#define SSL_set_shutdown wolfSSL_set_shutdown
+#define SSL_set_session_id_context wolfSSL_set_session_id_context
+#define SSL_set_connect_state wolfSSL_set_connect_state
+#define SSL_set_accept_state wolfSSL_set_accept_state
+#define SSL_session_reused wolfSSL_session_reused
+#define SSL_SESSION_free wolfSSL_SESSION_free
+#define SSL_is_init_finished wolfSSL_is_init_finished
+
+#define SSL_get_version wolfSSL_get_version
+#define SSL_get_current_cipher wolfSSL_get_current_cipher
+#define SSL_get_cipher wolfSSL_get_cipher
+#define SSL_CIPHER_description wolfSSL_CIPHER_description
+#define SSL_CIPHER_get_name wolfSSL_CIPHER_get_name
+#define SSL_get1_session wolfSSL_get1_session
+
+#define SSL_get_keyblock_size wolfSSL_get_keyblock_size
+#define SSL_get_keys          wolfSSL_get_keys
+
+#define X509_free wolfSSL_X509_free
+#define OPENSSL_free wolfSSL_OPENSSL_free
+
+#define OCSP_parse_url wolfSSL_OCSP_parse_url
+#define SSLv23_client_method wolfSSLv23_client_method
+#define SSLv2_client_method wolfSSLv2_client_method
+#define SSLv2_server_method wolfSSLv2_server_method
+
+#define MD4_Init wolfSSL_MD4_Init
+#define MD4_Update  wolfSSL_MD4_Update
+#define MD4_Final wolfSSL_MD4_Final
+
+#define BIO_new      wolfSSL_BIO_new
+#define BIO_free     wolfSSL_BIO_free
+#define BIO_free_all wolfSSL_BIO_free_all
+#define BIO_read     wolfSSL_BIO_read
+#define BIO_write    wolfSSL_BIO_write
+#define BIO_push     wolfSSL_BIO_push
+#define BIO_pop      wolfSSL_BIO_pop
+#define BIO_flush    wolfSSL_BIO_flush
+#define BIO_pending  wolfSSL_BIO_pending
+
+#define BIO_get_mem_data wolfSSL_BIO_get_mem_data
+#define BIO_new_mem_buf  wolfSSL_BIO_new_mem_buf
+
+#define BIO_f_buffer              wolfSSL_BIO_f_buffer
+#define BIO_set_write_buffer_size wolfSSL_BIO_set_write_buffer_size
+#define BIO_f_ssl                 wolfSSL_BIO_f_ssl
+#define BIO_new_socket            wolfSSL_BIO_new_socket
+#define SSL_set_bio               wolfSSL_set_bio
+#define BIO_eof                   wolfSSL_BIO_eof
+#define BIO_set_ss                wolfSSL_BIO_set_ss
+
+#define BIO_s_mem     wolfSSL_BIO_s_mem
+#define BIO_f_base64  wolfSSL_BIO_f_base64
+#define BIO_set_flags wolfSSL_BIO_set_flags
+
+#define OpenSSL_add_all_algorithms wolfSSL_add_all_algorithms
+#define SSLeay_add_ssl_algorithms  wolfSSL_add_all_algorithms
+#define SSLeay_add_all_algorithms wolfSSL_add_all_algorithms
+
+#define RAND_screen     wolfSSL_RAND_screen
+#define RAND_file_name  wolfSSL_RAND_file_name
+#define RAND_write_file wolfSSL_RAND_write_file
+#define RAND_load_file  wolfSSL_RAND_load_file
+#define RAND_egd        wolfSSL_RAND_egd
+#define RAND_seed       wolfSSL_RAND_seed
+#define RAND_add        wolfSSL_RAND_add
+
+#define COMP_zlib                       wolfSSL_COMP_zlib
+#define COMP_rle                        wolfSSL_COMP_rle
+#define SSL_COMP_add_compression_method wolfSSL_COMP_add_compression_method
+
+#define SSL_get_ex_new_index wolfSSL_get_ex_new_index
+
+#define CRYPTO_set_id_callback wolfSSL_set_id_callback
+#define CRYPTO_set_locking_callback wolfSSL_set_locking_callback
+#define CRYPTO_set_dynlock_create_callback wolfSSL_set_dynlock_create_callback
+#define CRYPTO_set_dynlock_lock_callback wolfSSL_set_dynlock_lock_callback
+#define CRYPTO_set_dynlock_destroy_callback wolfSSL_set_dynlock_destroy_callback
+#define CRYPTO_num_locks wolfSSL_num_locks
+
+#define X509_STORE_CTX_get_current_cert wolfSSL_X509_STORE_CTX_get_current_cert
+#define X509_STORE_CTX_get_error wolfSSL_X509_STORE_CTX_get_error
+#define X509_STORE_CTX_get_error_depth wolfSSL_X509_STORE_CTX_get_error_depth
+
+#define X509_NAME_oneline             wolfSSL_X509_NAME_oneline
+#define X509_get_issuer_name          wolfSSL_X509_get_issuer_name
+#define X509_get_subject_name         wolfSSL_X509_get_subject_name
+#define X509_verify_cert_error_string wolfSSL_X509_verify_cert_error_string
+
+#define X509_LOOKUP_add_dir wolfSSL_X509_LOOKUP_add_dir
+#define X509_LOOKUP_load_file wolfSSL_X509_LOOKUP_load_file
+#define X509_LOOKUP_hash_dir wolfSSL_X509_LOOKUP_hash_dir
+#define X509_LOOKUP_file wolfSSL_X509_LOOKUP_file
+
+#define X509_STORE_add_lookup wolfSSL_X509_STORE_add_lookup
+#define X509_STORE_new wolfSSL_X509_STORE_new
+#define X509_STORE_get_by_subject wolfSSL_X509_STORE_get_by_subject
+#define X509_STORE_CTX_init wolfSSL_X509_STORE_CTX_init
+#define X509_STORE_CTX_cleanup wolfSSL_X509_STORE_CTX_cleanup
+
+#define X509_CRL_get_lastUpdate wolfSSL_X509_CRL_get_lastUpdate
+#define X509_CRL_get_nextUpdate wolfSSL_X509_CRL_get_nextUpdate
+
+#define X509_get_pubkey           wolfSSL_X509_get_pubkey
+#define X509_CRL_verify           wolfSSL_X509_CRL_verify
+#define X509_STORE_CTX_set_error  wolfSSL_X509_STORE_CTX_set_error
+#define X509_OBJECT_free_contents wolfSSL_X509_OBJECT_free_contents
+#define EVP_PKEY_free             wolfSSL_EVP_PKEY_free
+#define X509_cmp_current_time     wolfSSL_X509_cmp_current_time
+#define sk_X509_REVOKED_num       wolfSSL_sk_X509_REVOKED_num
+#define X509_CRL_get_REVOKED      wolfSSL_X509_CRL_get_REVOKED
+#define sk_X509_REVOKED_value     wolfSSL_sk_X509_REVOKED_value
+#define X509_get_notBefore(cert)  (ASN1_TIME*)wolfSSL_X509_notBefore((cert))
+#define X509_get_notAfter(cert)   (ASN1_TIME*)wolfSSL_X509_notAfter((cert))
+
+
+#define X509_get_serialNumber wolfSSL_X509_get_serialNumber
+
+#define ASN1_TIME_print wolfSSL_ASN1_TIME_print
+
+#define ASN1_INTEGER_cmp wolfSSL_ASN1_INTEGER_cmp
+#define ASN1_INTEGER_get wolfSSL_ASN1_INTEGER_get
+
+#define SSL_load_client_CA_file wolfSSL_load_client_CA_file
+
+#define SSL_CTX_set_client_CA_list         wolfSSL_CTX_set_client_CA_list
+#define X509_STORE_CTX_get_ex_data         wolfSSL_X509_STORE_CTX_get_ex_data
+#define SSL_get_ex_data_X509_STORE_CTX_idx wolfSSL_get_ex_data_X509_STORE_CTX_idx
+#define SSL_get_ex_data wolfSSL_get_ex_data
+
+#define SSL_CTX_set_default_passwd_cb_userdata wolfSSL_CTX_set_default_passwd_cb_userdata
+#define SSL_CTX_set_default_passwd_cb wolfSSL_CTX_set_default_passwd_cb
+
+#define SSL_CTX_set_timeout(ctx, to) wolfSSL_CTX_set_timeout(ctx, (unsigned int) to)
+#define SSL_CTX_set_info_callback wolfSSL_CTX_set_info_callback
+
+#define ERR_peek_error wolfSSL_ERR_peek_error
+#define ERR_GET_REASON wolfSSL_ERR_GET_REASON
+
+#define SSL_alert_type_string wolfSSL_alert_type_string
+#define SSL_alert_desc_string wolfSSL_alert_desc_string
+#define SSL_state_string wolfSSL_state_string
+
+#define RSA_free wolfSSL_RSA_free
+#define RSA_generate_key wolfSSL_RSA_generate_key
+#define SSL_CTX_set_tmp_rsa_callback wolfSSL_CTX_set_tmp_rsa_callback
+
+#define PEM_def_callback wolfSSL_PEM_def_callback
+
+#define SSL_CTX_sess_accept wolfSSL_CTX_sess_accept
+#define SSL_CTX_sess_connect wolfSSL_CTX_sess_connect
+#define SSL_CTX_sess_accept_good wolfSSL_CTX_sess_accept_good
+#define SSL_CTX_sess_connect_good wolfSSL_CTX_sess_connect_good
+#define SSL_CTX_sess_accept_renegotiate wolfSSL_CTX_sess_accept_renegotiate
+#define SSL_CTX_sess_connect_renegotiate wolfSSL_CTX_sess_connect_renegotiate
+#define SSL_CTX_sess_hits wolfSSL_CTX_sess_hits
+#define SSL_CTX_sess_cb_hits wolfSSL_CTX_sess_cb_hits
+#define SSL_CTX_sess_cache_full wolfSSL_CTX_sess_cache_full
+#define SSL_CTX_sess_misses wolfSSL_CTX_sess_misses
+#define SSL_CTX_sess_timeouts wolfSSL_CTX_sess_timeouts
+#define SSL_CTX_sess_number wolfSSL_CTX_sess_number
+#define SSL_CTX_sess_get_cache_size wolfSSL_CTX_sess_get_cache_size
+
+
+#define SSL_DEFAULT_CIPHER_LIST WOLFSSL_DEFAULT_CIPHER_LIST
+#define RSA_F4 WOLFSSL_RSA_F4
+
+#define SSL_CTX_set_psk_client_callback wolfSSL_CTX_set_psk_client_callback
+#define SSL_set_psk_client_callback wolfSSL_set_psk_client_callback
+
+#define SSL_get_psk_identity_hint wolfSSL_get_psk_identity_hint
+#define SSL_get_psk_identity wolfSSL_get_psk_identity
+
+#define SSL_CTX_use_psk_identity_hint wolfSSL_CTX_use_psk_identity_hint
+#define SSL_use_psk_identity_hint wolfSSL_use_psk_identity_hint
+
+#define SSL_CTX_set_psk_server_callback wolfSSL_CTX_set_psk_server_callback
+#define SSL_set_psk_server_callback wolfSSL_set_psk_server_callback
+
+#define ERR_get_error_line_data wolfSSL_ERR_get_error_line_data
+
+#define ERR_get_error wolfSSL_ERR_get_error
+#define ERR_clear_error wolfSSL_ERR_clear_error
+
+#define RAND_status wolfSSL_RAND_status
+#define RAND_bytes wolfSSL_RAND_bytes
+#define SSLv23_server_method wolfSSLv23_server_method
+#define SSL_CTX_set_options wolfSSL_CTX_set_options 
+#define SSL_CTX_check_private_key wolfSSL_CTX_check_private_key
+
+#define ERR_free_strings wolfSSL_ERR_free_strings
+#define ERR_remove_state wolfSSL_ERR_remove_state
+#define EVP_cleanup wolfSSL_EVP_cleanup
+
+#define CRYPTO_cleanup_all_ex_data wolfSSL_cleanup_all_ex_data
+#define SSL_CTX_set_mode wolfSSL_CTX_set_mode
+#define SSL_CTX_get_mode wolfSSL_CTX_get_mode
+#define SSL_CTX_set_default_read_ahead wolfSSL_CTX_set_default_read_ahead
+
+#define SSL_CTX_sess_set_cache_size wolfSSL_CTX_sess_set_cache_size
+#define SSL_CTX_set_default_verify_paths wolfSSL_CTX_set_default_verify_paths
+
+#define SSL_CTX_set_session_id_context wolfSSL_CTX_set_session_id_context
+#define SSL_get_peer_certificate wolfSSL_get_peer_certificate
+
+#define SSL_want_read wolfSSL_want_read
+#define SSL_want_write wolfSSL_want_write
+
+#define BIO_prf wolfSSL_BIO_prf
+#define ASN1_UTCTIME_pr wolfSSL_ASN1_UTCTIME_pr
+
+#define sk_num wolfSSL_sk_num
+#define sk_value wolfSSL_sk_value
+
+#define SSL_CTX_get_ex_data wolfSSL_CTX_get_ex_data
+#define SSL_CTX_set_ex_data wolfSSL_CTX_set_ex_data
+#define SSL_CTX_sess_set_get_cb wolfSSL_CTX_sess_set_get_cb
+#define SSL_CTX_sess_set_new_cb wolfSSL_CTX_sess_set_new_cb
+#define SSL_CTX_sess_set_remove_cb wolfSSL_CTX_sess_set_remove_cb
+
+#define i2d_SSL_SESSION wolfSSL_i2d_SSL_SESSION
+#define d2i_SSL_SESSION wolfSSL_d2i_SSL_SESSION
+#define SSL_SESSION_set_timeout wolfSSL_SSL_SESSION_set_timeout
+#define SSL_SESSION_get_timeout wolfSSL_SESSION_get_timeout
+#define SSL_SESSION_get_time wolfSSL_SESSION_get_time
+#define SSL_CTX_get_ex_new_index wolfSSL_CTX_get_ex_new_index
+
+/* yassl had set the default to be 500 */
+#define SSL_get_default_timeout(ctx) 500
+
+/* Lighthttp compatability */
+
+#ifdef HAVE_LIGHTY                       
+typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY;
+
+#define SSL_CB_HANDSHAKE_START          0x10
+#define X509_NAME_free wolfSSL_X509_NAME_free
+#define SSL_CTX_use_certificate wolfSSL_CTX_use_certificate
+#define SSL_CTX_use_PrivateKey wolfSSL_CTX_use_PrivateKey
+#define BIO_read_filename wolfSSL_BIO_read_filename
+#define BIO_s_file wolfSSL_BIO_s_file
+#define OBJ_nid2sn wolf_OBJ_nid2sn
+#define OBJ_obj2nid wolf_OBJ_obj2nid
+#define OBJ_sn2nid wolf_OBJ_sn2nid
+#define PEM_read_bio_X509 PEM_read_bio_WOLFSSL_X509
+#define SSL_CTX_set_verify_depth wolfSSL_CTX_set_verify_depth
+#define SSL_get_app_data wolfSSL_get_app_data
+#define SSL_set_app_data wolfSSL_set_app_data
+#define X509_NAME_entry_count wolfSSL_X509_NAME_entry_count
+#define X509_NAME_ENTRY_get_object wolfSSL_X509_NAME_ENTRY_get_object
+#define X509_NAME_get_entry wolfSSL_X509_NAME_get_entry
+#define sk_X509_NAME_pop_free  wolfSSL_sk_X509_NAME_pop_free
+#define SHA1 wolfSSL_SHA1
+#define X509_check_private_key wolfSSL_X509_check_private_key
+#define SSL_dup_CA_list wolfSSL_dup_CA_list
+
+#endif
+
+#if defined(HAVE_STUNNEL) || defined(HAVE_LIGHTY)
+
+#define PEM_read_bio_DHparams wolfSSL_PEM_read_bio_DHparams
+#define PEM_write_bio_X509 PEM_write_bio_WOLFSSL_X509
+#define SSL_CTX_set_tmp_dh wolfSSL_CTX_set_tmp_dh
+#define BIO_new_file wolfSSL_BIO_new_file
+
+
+#endif /* HAVE_STUNNEL || HAVE_LIGHTY */
+
+#ifdef HAVE_STUNNEL
+#include <wolfssl/openssl/asn1.h>
+
+/* defined as: (SSL_ST_ACCEPT|SSL_CB_LOOP), which becomes 0x2001*/
+#define SSL_CB_ACCEPT_LOOP               0x2001 
+#define SSL2_VERSION                     0x0002
+#define SSL3_VERSION                     0x0300
+#define TLS1_VERSION                     0x0301
+#define DTLS1_VERSION                    0xFEFF
+#define SSL23_ST_SR_CLNT_HELLO_A        (0x210|0x2000)
+#define SSL3_ST_SR_CLNT_HELLO_A         (0x110|0x2000)
+#define ASN1_STRFLGS_ESC_MSB             4
+#define X509_V_ERR_CERT_REJECTED         28
+
+#define SSL_alert_desc_string_long       wolfSSL_alert_desc_string_long
+#define SSL_alert_type_string_long       wolfSSL_alert_type_string_long
+#define SSL_CIPHER_get_bits              wolfSSL_CIPHER_get_bits
+#define sk_X509_NAME_num                 wolfSSL_sk_X509_NAME_num
+#define sk_X509_num                      wolfSSL_sk_X509_num
+#define X509_NAME_print_ex               wolfSSL_X509_NAME_print_ex
+#define X509_get0_pubkey_bitstr          wolfSSL_X509_get0_pubkey_bitstr
+#define SSL_CTX_get_options              wolfSSL_CTX_get_options
+
+#define SSL_CTX_flush_sessions           wolfSSL_flush_sessions
+#define SSL_CTX_add_session              wolfSSL_CTX_add_session
+#define SSL_get_SSL_CTX                  wolfSSL_get_SSL_CTX
+#define SSL_version                      wolfSSL_version
+#define SSL_get_state                    wolfSSL_get_state
+#define SSL_state_string_long            wolfSSL_state_string_long
+#define SSL_get_peer_cert_chain          wolfSSL_get_peer_cert_chain
+#define sk_X509_NAME_value               wolfSSL_sk_X509_NAME_value
+#define sk_X509_value                    wolfSSL_sk_X509_value
+#define SSL_SESSION_get_ex_data          wolfSSL_SESSION_get_ex_data
+#define SSL_SESSION_set_ex_data          wolfSSL_SESSION_set_ex_data
+#define SSL_SESSION_get_ex_new_index     wolfSSL_SESSION_get_ex_new_index
+#define SSL_SESSION_get_id               wolfSSL_SESSION_get_id
+#define CRYPTO_dynlock_value             WOLFSSL_dynlock_value
+typedef WOLFSSL_ASN1_BIT_STRING    ASN1_BIT_STRING;
+
+#define SSL_TLSEXT_ERR_OK                    0
+#define SSL_TLSEXT_ERR_ALERT_FATAL           alert_fatal
+#define SSL_TLSEXT_ERR_NOACK                 alert_warning
+#define TLSEXT_NAMETYPE_host_name            WOLFSSL_SNI_HOST_NAME
+
+#define SSL_set_tlsext_host_name wolfSSL_set_tlsext_host_name
+#define SSL_get_servername wolfSSL_get_servername
+#define SSL_set_SSL_CTX                  wolfSSL_set_SSL_CTX
+#define SSL_CTX_get_verify_callback      wolfSSL_CTX_get_verify_callback
+#define SSL_CTX_set_tlsext_servername_callback      wolfSSL_CTX_set_servername_callback
+#define SSL_CTX_set_tlsext_servername_arg           wolfSSL_CTX_set_servername_arg
+
+#define PSK_MAX_PSK_LEN                      256
+#define PSK_MAX_IDENTITY_LEN                 128
+
+
+#endif /* HAVE_STUNNEL */
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+
+#endif /* wolfSSL_openssl_h__ */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ui.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ui.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/ui.h	(revision 164)
@@ -0,0 +1,2 @@
+/* ui.h for openssl */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/x509v3.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/x509v3.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/openssl/x509v3.h	(revision 164)
@@ -0,0 +1,2 @@
+/* x509v3.h for openssl */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/ssl.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/ssl.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/ssl.h	(revision 164)
@@ -0,0 +1,1700 @@
+/* ssl.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* wolfSSL API */
+
+#ifndef WOLFSSL_SSL_H
+#define WOLFSSL_SSL_H
+
+
+/* for users not using preprocessor flags*/
+#include <wolfssl/wolfcrypt/settings.h>
+#include <wolfssl/version.h>
+
+#ifndef NO_FILESYSTEM
+    #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+        #if MQX_USE_IO_OLD
+            #include <fio.h>
+        #else
+            #include <nio.h>
+        #endif
+    #else
+        #include <stdio.h>   /* ERR_printf */
+    #endif
+#endif
+
+#ifdef WOLFSSL_PREFIX
+    #include "prefix_ssl.h"
+#endif
+
+#ifdef LIBWOLFSSL_VERSION_STRING
+    #define WOLFSSL_VERSION LIBWOLFSSL_VERSION_STRING
+#endif
+
+#ifdef _WIN32
+    /* wincrypt.h clashes */
+    #undef OCSP_REQUEST
+    #undef OCSP_RESPONSE
+#endif
+
+
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+typedef struct WOLFSSL          WOLFSSL;
+typedef struct WOLFSSL_SESSION  WOLFSSL_SESSION;
+typedef struct WOLFSSL_METHOD   WOLFSSL_METHOD;
+typedef struct WOLFSSL_CTX      WOLFSSL_CTX;
+
+typedef struct WOLFSSL_X509       WOLFSSL_X509;
+typedef struct WOLFSSL_X509_NAME  WOLFSSL_X509_NAME;
+typedef struct WOLFSSL_X509_CHAIN WOLFSSL_X509_CHAIN;
+
+typedef struct WOLFSSL_CERT_MANAGER WOLFSSL_CERT_MANAGER;
+typedef struct WOLFSSL_SOCKADDR     WOLFSSL_SOCKADDR;
+
+/* redeclare guard */
+#define WOLFSSL_TYPES_DEFINED
+
+
+#ifndef WOLFSSL_RSA_TYPE_DEFINED /* guard on redeclaration */
+typedef struct WOLFSSL_RSA            WOLFSSL_RSA;
+#define WOLFSSL_RSA_TYPE_DEFINED
+#endif
+
+typedef struct WOLFSSL_DSA            WOLFSSL_DSA;
+typedef struct WOLFSSL_EC_KEY         WOLFSSL_EC_KEY;
+typedef struct WOLFSSL_EC_POINT       WOLFSSL_EC_POINT;
+typedef struct WOLFSSL_EC_GROUP       WOLFSSL_EC_GROUP;
+typedef struct WOLFSSL_ECDSA_SIG      WOLFSSL_ECDSA_SIG;
+typedef struct WOLFSSL_CIPHER         WOLFSSL_CIPHER;
+typedef struct WOLFSSL_X509_LOOKUP    WOLFSSL_X509_LOOKUP;
+typedef struct WOLFSSL_X509_LOOKUP_METHOD WOLFSSL_X509_LOOKUP_METHOD;
+typedef struct WOLFSSL_X509_CRL       WOLFSSL_X509_CRL;
+typedef struct WOLFSSL_BIO            WOLFSSL_BIO;
+typedef struct WOLFSSL_BIO_METHOD     WOLFSSL_BIO_METHOD;
+typedef struct WOLFSSL_X509_EXTENSION WOLFSSL_X509_EXTENSION;
+typedef struct WOLFSSL_ASN1_TIME      WOLFSSL_ASN1_TIME;
+typedef struct WOLFSSL_ASN1_INTEGER   WOLFSSL_ASN1_INTEGER;
+typedef struct WOLFSSL_ASN1_OBJECT    WOLFSSL_ASN1_OBJECT;
+
+typedef struct WOLFSSL_ASN1_STRING      WOLFSSL_ASN1_STRING;
+typedef struct WOLFSSL_dynlock_value    WOLFSSL_dynlock_value;
+typedef struct WOLFSSL_DH               WOLFSSL_DH;
+typedef struct WOLFSSL_ASN1_BIT_STRING  WOLFSSL_ASN1_BIT_STRING;
+
+#define WOLFSSL_ASN1_UTCTIME WOLFSSL_ASN1_TIME
+
+typedef struct WOLFSSL_EVP_PKEY {
+    int type;         /* openssh dereference */
+    int save_type;    /* openssh dereference */
+    int pkey_sz;
+    union {
+        char* ptr;
+    } pkey;
+    #ifdef HAVE_ECC
+        int pkey_curve;
+    #endif
+} WOLFSSL_EVP_PKEY;
+
+typedef struct WOLFSSL_MD4_CTX {
+    int buffer[32];      /* big enough to hold, check size in Init */
+} WOLFSSL_MD4_CTX;
+
+
+typedef struct WOLFSSL_COMP_METHOD {
+    int type;            /* stunnel dereference */
+} WOLFSSL_COMP_METHOD;
+
+
+typedef struct WOLFSSL_X509_STORE {
+    int                  cache;          /* stunnel dereference */
+    WOLFSSL_CERT_MANAGER* cm;
+} WOLFSSL_X509_STORE;
+
+typedef struct WOLFSSL_ALERT {
+    int code;
+    int level;
+} WOLFSSL_ALERT;
+
+typedef struct WOLFSSL_ALERT_HISTORY {
+    WOLFSSL_ALERT last_rx;
+    WOLFSSL_ALERT last_tx;
+} WOLFSSL_ALERT_HISTORY;
+
+typedef struct WOLFSSL_X509_REVOKED {
+    WOLFSSL_ASN1_INTEGER* serialNumber;          /* stunnel dereference */
+} WOLFSSL_X509_REVOKED;
+
+
+typedef struct WOLFSSL_X509_OBJECT {
+    union {
+        char* ptr;
+        WOLFSSL_X509 *x509;
+        WOLFSSL_X509_CRL* crl;           /* stunnel dereference */
+    } data;
+} WOLFSSL_X509_OBJECT;
+
+typedef struct WOLFSSL_X509_STORE_CTX {
+    WOLFSSL_X509_STORE* store;    /* Store full of a CA cert chain */
+    WOLFSSL_X509* current_cert;   /* stunnel dereference */
+    char* domain;                /* subject CN domain name */
+    void* ex_data;               /* external data, for fortress build */
+    void* userCtx;               /* user ctx */
+    int   error;                 /* current error */
+    int   error_depth;           /* cert depth for this error */
+    int   discardSessionCerts;   /* so verify callback can flag for discard */
+} WOLFSSL_X509_STORE_CTX;
+
+
+/* Valid Alert types from page 16/17 */
+enum AlertDescription {
+    close_notify            = 0,
+    unexpected_message      = 10,
+    bad_record_mac          = 20,
+    record_overflow         = 22,
+    decompression_failure   = 30,
+    handshake_failure       = 40,
+    no_certificate          = 41,
+    bad_certificate         = 42,
+    unsupported_certificate = 43,
+    certificate_revoked     = 44,
+    certificate_expired     = 45,
+    certificate_unknown     = 46,
+    illegal_parameter       = 47,
+    decrypt_error           = 51,
+    #ifdef WOLFSSL_MYSQL_COMPATIBLE
+    /* catch name conflict for enum protocol with MYSQL build */
+    wc_protocol_version     = 70,
+    #else
+    protocol_version        = 70,
+    #endif
+    no_renegotiation        = 100,
+    unrecognized_name       = 112,
+    no_application_protocol = 120
+};
+
+
+enum AlertLevel {
+    alert_warning = 1,
+    alert_fatal = 2
+};
+
+
+WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_server_method(void);
+WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_client_method(void);
+WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_server_method(void);
+WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_client_method(void);
+WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_1_server_method(void);
+WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_1_client_method(void);
+WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_2_server_method(void);
+WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_2_client_method(void);
+
+#ifdef WOLFSSL_DTLS
+    WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_client_method(void);
+    WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_server_method(void);
+    WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_client_method(void);
+    WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_server_method(void);
+#endif
+
+#ifdef HAVE_POLY1305
+    WOLFSSL_API int wolfSSL_use_old_poly(WOLFSSL*, int);
+#endif
+
+#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
+
+WOLFSSL_API int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX*, const char*, int);
+WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX*, const char*, int);
+WOLFSSL_API int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX*, const char*,
+                                                const char*);
+WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX *,
+                                                     const char *file);
+WOLFSSL_API int wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX*, const char*, int);
+
+WOLFSSL_API long wolfSSL_get_verify_depth(WOLFSSL* ssl);
+WOLFSSL_API long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx);
+WOLFSSL_API int wolfSSL_use_certificate_file(WOLFSSL*, const char*, int);
+WOLFSSL_API int wolfSSL_use_PrivateKey_file(WOLFSSL*, const char*, int);
+WOLFSSL_API int wolfSSL_use_certificate_chain_file(WOLFSSL*, const char *file);
+WOLFSSL_API int wolfSSL_use_RSAPrivateKey_file(WOLFSSL*, const char*, int);
+
+#ifdef WOLFSSL_DER_LOAD
+    WOLFSSL_API int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX*,
+                                                    const char*, int);
+#endif
+
+#ifdef HAVE_NTRU
+    WOLFSSL_API int wolfSSL_CTX_use_NTRUPrivateKey_file(WOLFSSL_CTX*, const char*);
+    /* load NTRU private key blob */
+#endif
+
+#ifndef WOLFSSL_PEMCERT_TODER_DEFINED
+    WOLFSSL_API int wolfSSL_PemCertToDer(const char*, unsigned char*, int);
+    #define WOLFSSL_PEMCERT_TODER_DEFINED
+#endif
+
+#endif /* !NO_FILESYSTEM && !NO_CERTS */
+
+WOLFSSL_API WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD*);
+WOLFSSL_API WOLFSSL* wolfSSL_new(WOLFSSL_CTX*);
+WOLFSSL_API int  wolfSSL_set_fd (WOLFSSL*, int);
+WOLFSSL_API char* wolfSSL_get_cipher_list(int priority);
+WOLFSSL_API int  wolfSSL_get_ciphers(char*, int);
+WOLFSSL_API int  wolfSSL_get_fd(const WOLFSSL*);
+WOLFSSL_API void wolfSSL_set_using_nonblock(WOLFSSL*, int);
+WOLFSSL_API int  wolfSSL_get_using_nonblock(WOLFSSL*);
+WOLFSSL_API int  wolfSSL_connect(WOLFSSL*);     /* please see note at top of README
+                                             if you get an error from connect */
+WOLFSSL_API int  wolfSSL_write(WOLFSSL*, const void*, int);
+WOLFSSL_API int  wolfSSL_read(WOLFSSL*, void*, int);
+WOLFSSL_API int  wolfSSL_peek(WOLFSSL*, void*, int);
+WOLFSSL_API int  wolfSSL_accept(WOLFSSL*);
+WOLFSSL_API void wolfSSL_CTX_free(WOLFSSL_CTX*);
+WOLFSSL_API void wolfSSL_free(WOLFSSL*);
+WOLFSSL_API int  wolfSSL_shutdown(WOLFSSL*);
+WOLFSSL_API int  wolfSSL_send(WOLFSSL*, const void*, int sz, int flags);
+WOLFSSL_API int  wolfSSL_recv(WOLFSSL*, void*, int sz, int flags);
+
+WOLFSSL_API void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX*, int);
+WOLFSSL_API void wolfSSL_set_quiet_shutdown(WOLFSSL*, int);
+
+WOLFSSL_API int  wolfSSL_get_error(WOLFSSL*, int);
+WOLFSSL_API int  wolfSSL_get_alert_history(WOLFSSL*, WOLFSSL_ALERT_HISTORY *);
+
+WOLFSSL_API int        wolfSSL_set_session(WOLFSSL* ssl,WOLFSSL_SESSION* session);
+WOLFSSL_API long       wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* session, long t);
+WOLFSSL_API WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl);
+WOLFSSL_API void       wolfSSL_flush_sessions(WOLFSSL_CTX *ctx, long tm);
+WOLFSSL_API int        wolfSSL_SetServerID(WOLFSSL* ssl, const unsigned char*,
+                                         int, int);
+
+#ifdef SESSION_INDEX
+WOLFSSL_API int wolfSSL_GetSessionIndex(WOLFSSL* ssl);
+WOLFSSL_API int wolfSSL_GetSessionAtIndex(int index, WOLFSSL_SESSION* session);
+#endif /* SESSION_INDEX */
+
+#if defined(SESSION_INDEX) && defined(SESSION_CERTS)
+WOLFSSL_API
+    WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session);
+#endif /* SESSION_INDEX && SESSION_CERTS */
+
+typedef int (*VerifyCallback)(int, WOLFSSL_X509_STORE_CTX*);
+typedef int (*pem_password_cb)(char*, int, int, void*);
+
+WOLFSSL_API void wolfSSL_CTX_set_verify(WOLFSSL_CTX*, int,
+                                      VerifyCallback verify_callback);
+WOLFSSL_API void wolfSSL_set_verify(WOLFSSL*, int, VerifyCallback verify_callback);
+WOLFSSL_API void wolfSSL_SetCertCbCtx(WOLFSSL*, void*);
+
+WOLFSSL_API int  wolfSSL_pending(WOLFSSL*);
+
+WOLFSSL_API void wolfSSL_load_error_strings(void);
+WOLFSSL_API int  wolfSSL_library_init(void);
+WOLFSSL_API long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX*, long);
+
+#ifdef HAVE_SECRET_CALLBACK
+typedef int (*SessionSecretCb)(WOLFSSL* ssl,
+                                        void* secret, int* secretSz, void* ctx);
+WOLFSSL_API int  wolfSSL_set_session_secret_cb(WOLFSSL*, SessionSecretCb, void*);
+#endif /* HAVE_SECRET_CALLBACK */
+
+/* session cache persistence */
+WOLFSSL_API int  wolfSSL_save_session_cache(const char*);
+WOLFSSL_API int  wolfSSL_restore_session_cache(const char*);
+WOLFSSL_API int  wolfSSL_memsave_session_cache(void*, int);
+WOLFSSL_API int  wolfSSL_memrestore_session_cache(const void*, int);
+WOLFSSL_API int  wolfSSL_get_session_cache_memsize(void);
+
+/* certificate cache persistence, uses ctx since certs are per ctx */
+WOLFSSL_API int  wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX*, const char*);
+WOLFSSL_API int  wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX*, const char*);
+WOLFSSL_API int  wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX*, void*, int, int*);
+WOLFSSL_API int  wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX*, const void*, int);
+WOLFSSL_API int  wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX*);
+
+/* only supports full name from cipher_name[] delimited by : */
+WOLFSSL_API int  wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX*, const char*);
+WOLFSSL_API int  wolfSSL_set_cipher_list(WOLFSSL*, const char*);
+
+/* Nonblocking DTLS helper functions */
+WOLFSSL_API int  wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl);
+WOLFSSL_API int  wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int);
+WOLFSSL_API int  wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int);
+WOLFSSL_API int  wolfSSL_dtls_got_timeout(WOLFSSL* ssl);
+WOLFSSL_API int  wolfSSL_dtls(WOLFSSL* ssl);
+
+WOLFSSL_API int  wolfSSL_dtls_set_peer(WOLFSSL*, void*, unsigned int);
+WOLFSSL_API int  wolfSSL_dtls_get_peer(WOLFSSL*, void*, unsigned int*);
+
+WOLFSSL_API int   wolfSSL_ERR_GET_REASON(unsigned long err);
+WOLFSSL_API char* wolfSSL_ERR_error_string(unsigned long,char*);
+WOLFSSL_API void  wolfSSL_ERR_error_string_n(unsigned long e, char* buf,
+                                           unsigned long sz);
+WOLFSSL_API const char* wolfSSL_ERR_reason_error_string(unsigned long);
+
+/* extras */
+
+#define STACK_OF(x) x
+
+WOLFSSL_API int  wolfSSL_set_ex_data(WOLFSSL*, int, void*);
+WOLFSSL_API int  wolfSSL_get_shutdown(const WOLFSSL*);
+WOLFSSL_API int  wolfSSL_set_rfd(WOLFSSL*, int);
+WOLFSSL_API int  wolfSSL_set_wfd(WOLFSSL*, int);
+WOLFSSL_API void wolfSSL_set_shutdown(WOLFSSL*, int);
+WOLFSSL_API int  wolfSSL_set_session_id_context(WOLFSSL*, const unsigned char*,
+                                           unsigned int);
+WOLFSSL_API void wolfSSL_set_connect_state(WOLFSSL*);
+WOLFSSL_API void wolfSSL_set_accept_state(WOLFSSL*);
+WOLFSSL_API int  wolfSSL_session_reused(WOLFSSL*);
+WOLFSSL_API void wolfSSL_SESSION_free(WOLFSSL_SESSION* session);
+WOLFSSL_API int  wolfSSL_is_init_finished(WOLFSSL*);
+
+WOLFSSL_API const char*  wolfSSL_get_version(WOLFSSL*);
+WOLFSSL_API int  wolfSSL_get_current_cipher_suite(WOLFSSL* ssl);
+WOLFSSL_API WOLFSSL_CIPHER*  wolfSSL_get_current_cipher(WOLFSSL*);
+WOLFSSL_API char*        wolfSSL_CIPHER_description(WOLFSSL_CIPHER*, char*, int);
+WOLFSSL_API const char*  wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher);
+WOLFSSL_API const char*  wolfSSL_get_cipher(WOLFSSL*);
+WOLFSSL_API WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl);
+                           /* what's ref count */
+
+WOLFSSL_API void wolfSSL_X509_free(WOLFSSL_X509*);
+WOLFSSL_API void wolfSSL_OPENSSL_free(void*);
+
+WOLFSSL_API int wolfSSL_OCSP_parse_url(char* url, char** host, char** port,
+                                     char** path, int* ssl);
+
+WOLFSSL_API WOLFSSL_METHOD* wolfSSLv23_client_method(void);
+WOLFSSL_API WOLFSSL_METHOD* wolfSSLv2_client_method(void);
+WOLFSSL_API WOLFSSL_METHOD* wolfSSLv2_server_method(void);
+
+WOLFSSL_API void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX*);
+WOLFSSL_API void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX*, const void*, unsigned long);
+WOLFSSL_API void wolfSSL_MD4_Final(unsigned char*, WOLFSSL_MD4_CTX*);
+
+
+WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD*);
+WOLFSSL_API int  wolfSSL_BIO_free(WOLFSSL_BIO*);
+WOLFSSL_API int  wolfSSL_BIO_free_all(WOLFSSL_BIO*);
+WOLFSSL_API int  wolfSSL_BIO_read(WOLFSSL_BIO*, void*, int);
+WOLFSSL_API int  wolfSSL_BIO_write(WOLFSSL_BIO*, const void*, int);
+WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_push(WOLFSSL_BIO*, WOLFSSL_BIO* append);
+WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO*);
+WOLFSSL_API int  wolfSSL_BIO_flush(WOLFSSL_BIO*);
+WOLFSSL_API int  wolfSSL_BIO_pending(WOLFSSL_BIO*);
+
+WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void);
+WOLFSSL_API long wolfSSL_BIO_set_write_buffer_size(WOLFSSL_BIO*, long size);
+WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void);
+WOLFSSL_API WOLFSSL_BIO*        wolfSSL_BIO_new_socket(int sfd, int flag);
+WOLFSSL_API int         wolfSSL_BIO_eof(WOLFSSL_BIO*);
+
+WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_mem(void);
+WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_base64(void);
+WOLFSSL_API void wolfSSL_BIO_set_flags(WOLFSSL_BIO*, int);
+
+WOLFSSL_API int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio,const unsigned char** p);
+WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_mem_buf(void* buf, int len);
+
+
+WOLFSSL_API long        wolfSSL_BIO_set_ssl(WOLFSSL_BIO*, WOLFSSL*, int flag);
+WOLFSSL_API void        wolfSSL_set_bio(WOLFSSL*, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr);
+
+WOLFSSL_API int  wolfSSL_add_all_algorithms(void);
+
+WOLFSSL_API void        wolfSSL_RAND_screen(void);
+WOLFSSL_API const char* wolfSSL_RAND_file_name(char*, unsigned long);
+WOLFSSL_API int         wolfSSL_RAND_write_file(const char*);
+WOLFSSL_API int         wolfSSL_RAND_load_file(const char*, long);
+WOLFSSL_API int         wolfSSL_RAND_egd(const char*);
+WOLFSSL_API int         wolfSSL_RAND_seed(const void*, int);
+WOLFSSL_API void        wolfSSL_RAND_add(const void*, int, double);
+
+WOLFSSL_API WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void);
+WOLFSSL_API WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void);
+WOLFSSL_API int wolfSSL_COMP_add_compression_method(int, void*);
+
+WOLFSSL_API int wolfSSL_get_ex_new_index(long, void*, void*, void*, void*);
+
+WOLFSSL_API void wolfSSL_set_id_callback(unsigned long (*f)(void));
+WOLFSSL_API void wolfSSL_set_locking_callback(void (*f)(int, int, const char*,
+                                                      int));
+WOLFSSL_API void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)
+                                                   (const char*, int));
+WOLFSSL_API void wolfSSL_set_dynlock_lock_callback(void (*f)(int,
+                                      WOLFSSL_dynlock_value*, const char*, int));
+WOLFSSL_API void wolfSSL_set_dynlock_destroy_callback(void (*f)
+                                     (WOLFSSL_dynlock_value*, const char*, int));
+WOLFSSL_API int  wolfSSL_num_locks(void);
+
+WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert(
+                                                        WOLFSSL_X509_STORE_CTX*);
+WOLFSSL_API int   wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX*);
+WOLFSSL_API int   wolfSSL_X509_STORE_CTX_get_error_depth(WOLFSSL_X509_STORE_CTX*);
+
+WOLFSSL_API char*       wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME*, char*, int);
+WOLFSSL_API WOLFSSL_X509_NAME*  wolfSSL_X509_get_issuer_name(WOLFSSL_X509*);
+WOLFSSL_API WOLFSSL_X509_NAME*  wolfSSL_X509_get_subject_name(WOLFSSL_X509*);
+WOLFSSL_API int  wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509*, int);
+WOLFSSL_API int  wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509*, int);
+WOLFSSL_API int  wolfSSL_X509_get_isCA(WOLFSSL_X509*);
+WOLFSSL_API int  wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509*);
+WOLFSSL_API unsigned int wolfSSL_X509_get_pathLength(WOLFSSL_X509*);
+WOLFSSL_API unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509*);
+WOLFSSL_API unsigned char* wolfSSL_X509_get_authorityKeyID(
+                                            WOLFSSL_X509*, unsigned char*, int*);
+WOLFSSL_API unsigned char* wolfSSL_X509_get_subjectKeyID(
+                                            WOLFSSL_X509*, unsigned char*, int*);
+WOLFSSL_API int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME*);
+WOLFSSL_API int wolfSSL_X509_NAME_get_text_by_NID(
+                                            WOLFSSL_X509_NAME*, int, char*, int);
+WOLFSSL_API int         wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX*);
+WOLFSSL_API const char* wolfSSL_X509_verify_cert_error_string(long);
+WOLFSSL_API int wolfSSL_X509_get_signature_type(WOLFSSL_X509*);
+WOLFSSL_API int wolfSSL_X509_get_signature(WOLFSSL_X509*, unsigned char*, int*);
+
+WOLFSSL_API int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP*,const char*,long);
+WOLFSSL_API int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP*, const char*,
+                                            long);
+WOLFSSL_API WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void);
+WOLFSSL_API WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void);
+
+WOLFSSL_API WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE*,
+                                                    WOLFSSL_X509_LOOKUP_METHOD*);
+WOLFSSL_API WOLFSSL_X509_STORE*  wolfSSL_X509_STORE_new(void);
+WOLFSSL_API void         wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE*);
+WOLFSSL_API int          wolfSSL_X509_STORE_add_cert(
+                                              WOLFSSL_X509_STORE*, WOLFSSL_X509*);
+WOLFSSL_API int          wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE*);
+WOLFSSL_API int          wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX*,
+                                   int, WOLFSSL_X509_NAME*, WOLFSSL_X509_OBJECT*);
+WOLFSSL_API WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void);
+WOLFSSL_API int  wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX*,
+                      WOLFSSL_X509_STORE*, WOLFSSL_X509*, STACK_OF(WOLFSSL_X509)*);
+WOLFSSL_API void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX*);
+WOLFSSL_API void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX*);
+
+WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL*);
+WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL*);
+
+WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509*);
+WOLFSSL_API int       wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL*, WOLFSSL_EVP_PKEY*);
+WOLFSSL_API void      wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX*,
+                                                     int);
+WOLFSSL_API void      wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT*);
+WOLFSSL_API void      wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY*);
+WOLFSSL_API int       wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME*);
+WOLFSSL_API int       wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED*);
+
+WOLFSSL_API WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL*);
+WOLFSSL_API WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
+                                                      WOLFSSL_X509_REVOKED*,int);
+WOLFSSL_API WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509*);
+
+WOLFSSL_API int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO*, const WOLFSSL_ASN1_TIME*);
+
+WOLFSSL_API int  wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER*,
+                                       const WOLFSSL_ASN1_INTEGER*);
+WOLFSSL_API long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER*);
+
+WOLFSSL_API STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char*);
+
+WOLFSSL_API void  wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX*,
+                                               STACK_OF(WOLFSSL_X509_NAME)*);
+WOLFSSL_API void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX*, int);
+WOLFSSL_API int   wolfSSL_get_ex_data_X509_STORE_CTX_idx(void);
+WOLFSSL_API void* wolfSSL_get_ex_data(const WOLFSSL*, int);
+
+WOLFSSL_API void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX*,
+                                                          void* userdata);
+WOLFSSL_API void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX*, pem_password_cb);
+
+
+WOLFSSL_API void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX*,
+                          void (*)(const WOLFSSL* ssl, int type, int val));
+
+WOLFSSL_API unsigned long wolfSSL_ERR_peek_error(void);
+WOLFSSL_API int           wolfSSL_GET_REASON(int);
+
+WOLFSSL_API char* wolfSSL_alert_type_string_long(int);
+WOLFSSL_API char* wolfSSL_alert_desc_string_long(int);
+WOLFSSL_API char* wolfSSL_state_string_long(const WOLFSSL*);
+
+WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSA_generate_key(int, unsigned long,
+                                               void(*)(int, int, void*), void*);
+WOLFSSL_API void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX*,
+                                             WOLFSSL_RSA*(*)(WOLFSSL*, int, int));
+
+WOLFSSL_API int wolfSSL_PEM_def_callback(char*, int num, int w, void* key);
+
+WOLFSSL_API long wolfSSL_CTX_sess_accept(WOLFSSL_CTX*);
+WOLFSSL_API long wolfSSL_CTX_sess_connect(WOLFSSL_CTX*);
+WOLFSSL_API long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX*);
+WOLFSSL_API long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX*);
+WOLFSSL_API long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX*);
+WOLFSSL_API long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX*);
+WOLFSSL_API long wolfSSL_CTX_sess_hits(WOLFSSL_CTX*);
+WOLFSSL_API long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX*);
+WOLFSSL_API long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX*);
+WOLFSSL_API long wolfSSL_CTX_sess_misses(WOLFSSL_CTX*);
+WOLFSSL_API long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX*);
+WOLFSSL_API long wolfSSL_CTX_sess_number(WOLFSSL_CTX*);
+WOLFSSL_API long wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX*);
+
+#define WOLFSSL_DEFAULT_CIPHER_LIST ""   /* default all */
+#define WOLFSSL_RSA_F4 0x10001L
+
+enum {
+    OCSP_NOCERTS     = 1,
+    OCSP_NOINTERN    = 2,
+    OCSP_NOSIGS      = 4,
+    OCSP_NOCHAIN     = 8,
+    OCSP_NOVERIFY    = 16,
+    OCSP_NOEXPLICIT  = 32,
+    OCSP_NOCASIGN    = 64,
+    OCSP_NODELEGATED = 128,
+    OCSP_NOCHECKS    = 256,
+    OCSP_TRUSTOTHER  = 512,
+    OCSP_RESPID_KEY  = 1024,
+    OCSP_NOTIME      = 2048,
+
+    OCSP_CERTID   = 2,
+    OCSP_REQUEST  = 4,
+    OCSP_RESPONSE = 8,
+    OCSP_BASICRESP = 16,
+
+    WOLFSSL_OCSP_URL_OVERRIDE = 1,
+    WOLFSSL_OCSP_NO_NONCE     = 2,
+    WOLFSSL_OCSP_CHECKALL     = 4,
+
+    WOLFSSL_CRL_CHECKALL = 1,
+
+    ASN1_GENERALIZEDTIME = 4,
+
+    SSL_OP_MICROSOFT_SESS_ID_BUG = 1,
+    SSL_OP_NETSCAPE_CHALLENGE_BUG = 2,
+    SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = 3,
+    SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG = 4,
+    SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER = 5,
+    SSL_OP_MSIE_SSLV2_RSA_PADDING = 6,
+    SSL_OP_SSLEAY_080_CLIENT_DH_BUG = 7,
+    SSL_OP_TLS_D5_BUG = 8,
+    SSL_OP_TLS_BLOCK_PADDING_BUG = 9,
+    SSL_OP_TLS_ROLLBACK_BUG = 10,
+    SSL_OP_ALL = 11,
+    SSL_OP_EPHEMERAL_RSA = 12,
+    SSL_OP_NO_SSLv3 = 13,
+    SSL_OP_NO_TLSv1 = 14,
+    SSL_OP_PKCS1_CHECK_1 = 15,
+    SSL_OP_PKCS1_CHECK_2 = 16,
+    SSL_OP_NETSCAPE_CA_DN_BUG = 17,
+    SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = 18,
+    SSL_OP_SINGLE_DH_USE = 19,
+    SSL_OP_NO_TICKET = 20,
+    SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = 21,
+    SSL_OP_NO_QUERY_MTU = 22,
+    SSL_OP_COOKIE_EXCHANGE = 23,
+    SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = 24,
+    SSL_OP_SINGLE_ECDH_USE = 25,
+    SSL_OP_CIPHER_SERVER_PREFERENCE = 26,
+
+    SSL_MAX_SSL_SESSION_ID_LENGTH = 32,
+
+    EVP_R_BAD_DECRYPT = 2,
+
+    SSL_CB_LOOP = 4,
+    SSL_ST_CONNECT = 5,
+    SSL_ST_ACCEPT  = 6,
+    SSL_CB_ALERT   = 7,
+    SSL_CB_READ    = 8,
+    SSL_CB_HANDSHAKE_DONE = 9,
+
+    SSL_MODE_ENABLE_PARTIAL_WRITE = 2,
+
+    BIO_FLAGS_BASE64_NO_NL = 1,
+    BIO_CLOSE   = 1,
+    BIO_NOCLOSE = 0,
+
+    NID_undef = 0,
+
+    X509_FILETYPE_PEM = 8,
+    X509_LU_X509      = 9,
+    X509_LU_CRL       = 12,
+
+    X509_V_ERR_CRL_SIGNATURE_FAILURE = 13,
+    X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 14,
+    X509_V_ERR_CRL_HAS_EXPIRED                = 15,
+    X509_V_ERR_CERT_REVOKED                   = 16,
+    X509_V_ERR_CERT_CHAIN_TOO_LONG            = 17,
+    X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT      = 18,
+    X509_V_ERR_CERT_NOT_YET_VALID             = 19,
+    X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD = 20,
+    X509_V_ERR_CERT_HAS_EXPIRED               = 21,
+    X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD  = 22,
+    X509_V_ERR_CERT_REJECTED                  = 23,
+    X509_V_OK = 0,
+
+    XN_FLAG_SPC_EQ  = (1 << 23),
+    XN_FLAG_ONELINE = 0,
+
+    CRYPTO_LOCK = 1,
+    CRYPTO_NUM_LOCKS = 10,
+
+    ASN1_STRFLGS_ESC_MSB = 4
+};
+
+/* extras end */
+
+#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
+#include <wolfssl/wolfcrypt/wc_port.h>
+/* wolfSSL extension, provide last error from SSL_get_error
+   since not using thread storage error queue */
+WOLFSSL_API void  wolfSSL_ERR_print_errors_fp(XFILE fp, int err);
+#endif
+
+enum { /* ssl Constants */
+    SSL_ERROR_NONE      =  0,   /* for most functions */
+    SSL_FAILURE         =  0,   /* for some functions */
+    SSL_SUCCESS         =  1,
+    SSL_SHUTDOWN_NOT_DONE =  2,  /* call wolfSSL_shutdown again to complete */
+
+    SSL_ALPN_NOT_FOUND  = -9,
+    SSL_BAD_CERTTYPE    = -8,
+    SSL_BAD_STAT        = -7,
+    SSL_BAD_PATH        = -6,
+    SSL_BAD_FILETYPE    = -5,
+    SSL_BAD_FILE        = -4,
+    SSL_NOT_IMPLEMENTED = -3,
+    SSL_UNKNOWN         = -2,
+    SSL_FATAL_ERROR     = -1,
+
+    SSL_FILETYPE_ASN1    = 2,
+    SSL_FILETYPE_PEM     = 1,
+    SSL_FILETYPE_DEFAULT = 2, /* ASN1 */
+    SSL_FILETYPE_RAW     = 3, /* NTRU raw key blob */
+
+    SSL_VERIFY_NONE                 = 0,
+    SSL_VERIFY_PEER                 = 1,
+    SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 2,
+    SSL_VERIFY_CLIENT_ONCE          = 4,
+
+    SSL_SESS_CACHE_OFF                = 30,
+    SSL_SESS_CACHE_CLIENT             = 31,
+    SSL_SESS_CACHE_SERVER             = 32,
+    SSL_SESS_CACHE_BOTH               = 33,
+    SSL_SESS_CACHE_NO_AUTO_CLEAR      = 34,
+    SSL_SESS_CACHE_NO_INTERNAL_LOOKUP = 35,
+
+    SSL_ERROR_WANT_READ        =  2,
+    SSL_ERROR_WANT_WRITE       =  3,
+    SSL_ERROR_WANT_CONNECT     =  7,
+    SSL_ERROR_WANT_ACCEPT      =  8,
+    SSL_ERROR_SYSCALL          =  5,
+    SSL_ERROR_WANT_X509_LOOKUP = 83,
+    SSL_ERROR_ZERO_RETURN      =  6,
+    SSL_ERROR_SSL              = 85,
+
+    SSL_SENT_SHUTDOWN     = 1,
+    SSL_RECEIVED_SHUTDOWN = 2,
+    SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER = 4,
+    SSL_OP_NO_SSLv2       = 8,
+
+    SSL_R_SSL_HANDSHAKE_FAILURE           = 101,
+    SSL_R_TLSV1_ALERT_UNKNOWN_CA          = 102,
+    SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN = 103,
+    SSL_R_SSLV3_ALERT_BAD_CERTIFICATE     = 104,
+
+    PEM_BUFSIZE = 1024
+};
+
+
+#ifndef NO_PSK
+    typedef unsigned int (*wc_psk_client_callback)(WOLFSSL*, const char*, char*,
+                                    unsigned int, unsigned char*, unsigned int);
+    WOLFSSL_API void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX*,
+                                                    wc_psk_client_callback);
+    WOLFSSL_API void wolfSSL_set_psk_client_callback(WOLFSSL*,
+                                                    wc_psk_client_callback);
+
+    WOLFSSL_API const char* wolfSSL_get_psk_identity_hint(const WOLFSSL*);
+    WOLFSSL_API const char* wolfSSL_get_psk_identity(const WOLFSSL*);
+
+    WOLFSSL_API int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX*, const char*);
+    WOLFSSL_API int wolfSSL_use_psk_identity_hint(WOLFSSL*, const char*);
+
+    typedef unsigned int (*wc_psk_server_callback)(WOLFSSL*, const char*,
+                          unsigned char*, unsigned int);
+    WOLFSSL_API void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX*,
+                                                    wc_psk_server_callback);
+    WOLFSSL_API void wolfSSL_set_psk_server_callback(WOLFSSL*,
+                                                    wc_psk_server_callback);
+
+    #define PSK_TYPES_DEFINED
+#endif /* NO_PSK */
+
+
+#ifdef HAVE_ANON
+    WOLFSSL_API int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX*);
+#endif /* HAVE_ANON */
+
+
+/* extra begins */
+
+enum {  /* ERR Constants */
+    ERR_TXT_STRING = 1
+};
+
+WOLFSSL_API unsigned long wolfSSL_ERR_get_error_line_data(const char**, int*,
+                                                 const char**, int *);
+
+WOLFSSL_API unsigned long wolfSSL_ERR_get_error(void);
+WOLFSSL_API void          wolfSSL_ERR_clear_error(void);
+
+
+WOLFSSL_API int  wolfSSL_RAND_status(void);
+WOLFSSL_API int  wolfSSL_RAND_bytes(unsigned char* buf, int num);
+WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_server_method(void);
+WOLFSSL_API long wolfSSL_CTX_set_options(WOLFSSL_CTX*, long);
+#ifndef NO_CERTS
+  WOLFSSL_API int  wolfSSL_CTX_check_private_key(WOLFSSL_CTX*);
+#endif /* !NO_CERTS */
+
+WOLFSSL_API void wolfSSL_ERR_free_strings(void);
+WOLFSSL_API void wolfSSL_ERR_remove_state(unsigned long);
+WOLFSSL_API void wolfSSL_EVP_cleanup(void);
+WOLFSSL_API int  wolfSSL_clear(WOLFSSL* ssl);
+
+WOLFSSL_API void wolfSSL_cleanup_all_ex_data(void);
+WOLFSSL_API long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode);
+WOLFSSL_API long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx);
+WOLFSSL_API void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m);
+WOLFSSL_API long wolfSSL_SSL_get_mode(WOLFSSL* ssl);
+
+WOLFSSL_API long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX*, long);
+
+WOLFSSL_API int  wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX*);
+WOLFSSL_API int  wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX*,
+                                            const unsigned char*, unsigned int);
+WOLFSSL_API WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl);
+
+WOLFSSL_API int wolfSSL_want_read(WOLFSSL*);
+WOLFSSL_API int wolfSSL_want_write(WOLFSSL*);
+
+WOLFSSL_API int wolfSSL_BIO_printf(WOLFSSL_BIO*, const char*, ...);
+WOLFSSL_API int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO*,
+                                         const WOLFSSL_ASN1_UTCTIME*);
+WOLFSSL_API int   wolfSSL_sk_num(WOLFSSL_X509_REVOKED*);
+WOLFSSL_API void* wolfSSL_sk_value(WOLFSSL_X509_REVOKED*, int);
+
+/* stunnel 4.28 needs */
+WOLFSSL_API void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX*, int);
+WOLFSSL_API int   wolfSSL_CTX_set_ex_data(WOLFSSL_CTX*, int, void*);
+WOLFSSL_API void  wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX*,
+                       WOLFSSL_SESSION*(*f)(WOLFSSL*, unsigned char*, int, int*));
+WOLFSSL_API void  wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX*,
+                                            int (*f)(WOLFSSL*, WOLFSSL_SESSION*));
+WOLFSSL_API void  wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX*,
+                                       void (*f)(WOLFSSL_CTX*, WOLFSSL_SESSION*));
+
+WOLFSSL_API int          wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION*,unsigned char**);
+WOLFSSL_API WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION**,
+                                                   const unsigned char**, long);
+
+WOLFSSL_API long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION*);
+WOLFSSL_API long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION*);
+WOLFSSL_API int  wolfSSL_CTX_get_ex_new_index(long, void*, void*, void*, void*);
+
+/* extra ends */
+
+
+/* wolfSSL extensions */
+
+/* call before SSL_connect, if verifying will add name check to
+   date check and signature check */
+WOLFSSL_API int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn);
+
+/* need to call once to load library (session cache) */
+WOLFSSL_API int wolfSSL_Init(void);
+/* call when done to cleanup/free session cache mutex / resources  */
+WOLFSSL_API int wolfSSL_Cleanup(void);
+
+/* which library version do we have */
+WOLFSSL_API const char* wolfSSL_lib_version(void);
+/* which library version do we have in hex */
+WOLFSSL_API unsigned int wolfSSL_lib_version_hex(void);
+
+/* turn logging on, only if compiled in */
+WOLFSSL_API int  wolfSSL_Debugging_ON(void);
+/* turn logging off */
+WOLFSSL_API void wolfSSL_Debugging_OFF(void);
+
+/* do accept or connect depedning on side */
+WOLFSSL_API int wolfSSL_negotiate(WOLFSSL* ssl);
+/* turn on wolfSSL data compression */
+WOLFSSL_API int wolfSSL_set_compression(WOLFSSL* ssl);
+
+WOLFSSL_API int wolfSSL_set_timeout(WOLFSSL*, unsigned int);
+WOLFSSL_API int wolfSSL_CTX_set_timeout(WOLFSSL_CTX*, unsigned int);
+
+/* get wolfSSL peer X509_CHAIN */
+WOLFSSL_API WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl);
+/* peer chain count */
+WOLFSSL_API int  wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain);
+/* index cert length */
+WOLFSSL_API int  wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN*, int idx);
+/* index cert */
+WOLFSSL_API unsigned char* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN*, int idx);
+/* index cert in X509 */
+WOLFSSL_API WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN*, int idx);
+/* free X509 */
+WOLFSSL_API void wolfSSL_FreeX509(WOLFSSL_X509*);
+/* get index cert in PEM */
+WOLFSSL_API int  wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN*, int idx,
+                                unsigned char* buffer, int inLen, int* outLen);
+WOLFSSL_API const unsigned char* wolfSSL_get_sessionID(const WOLFSSL_SESSION* s);
+WOLFSSL_API int  wolfSSL_X509_get_serial_number(WOLFSSL_X509*,unsigned char*,int*);
+WOLFSSL_API char*  wolfSSL_X509_get_subjectCN(WOLFSSL_X509*);
+WOLFSSL_API const unsigned char* wolfSSL_X509_get_der(WOLFSSL_X509*, int*);
+WOLFSSL_API const unsigned char* wolfSSL_X509_notBefore(WOLFSSL_X509*);
+WOLFSSL_API const unsigned char* wolfSSL_X509_notAfter(WOLFSSL_X509*);
+WOLFSSL_API int wolfSSL_X509_version(WOLFSSL_X509*);
+
+WOLFSSL_API int wolfSSL_cmp_peer_cert_to_file(WOLFSSL*, const char*);
+
+WOLFSSL_API char* wolfSSL_X509_get_next_altname(WOLFSSL_X509*);
+
+WOLFSSL_API WOLFSSL_X509*
+    wolfSSL_X509_d2i(WOLFSSL_X509** x509, const unsigned char* in, int len);
+#ifndef NO_FILESYSTEM
+    #ifndef NO_STDIO_FILESYSTEM
+    WOLFSSL_API WOLFSSL_X509*
+        wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file);
+    #endif
+WOLFSSL_API WOLFSSL_X509*
+    wolfSSL_X509_load_certificate_file(const char* fname, int format);
+#endif
+
+#ifdef WOLFSSL_SEP
+    WOLFSSL_API unsigned char*
+           wolfSSL_X509_get_device_type(WOLFSSL_X509*, unsigned char*, int*);
+    WOLFSSL_API unsigned char*
+           wolfSSL_X509_get_hw_type(WOLFSSL_X509*, unsigned char*, int*);
+    WOLFSSL_API unsigned char*
+           wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509*, unsigned char*, int*);
+#endif
+
+/* connect enough to get peer cert */
+WOLFSSL_API int  wolfSSL_connect_cert(WOLFSSL* ssl);
+
+#ifndef NO_DH
+/* server Diffie-Hellman parameters */
+WOLFSSL_API int  wolfSSL_SetTmpDH(WOLFSSL*, const unsigned char* p, int pSz,
+                                const unsigned char* g, int gSz);
+WOLFSSL_API int  wolfSSL_SetTmpDH_buffer(WOLFSSL*, const unsigned char* b, long sz,
+                                       int format);
+#ifndef NO_FILESYSTEM
+    WOLFSSL_API int  wolfSSL_SetTmpDH_file(WOLFSSL*, const char* f, int format);
+#endif
+
+/* server ctx Diffie-Hellman parameters */
+WOLFSSL_API int  wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX*, const unsigned char* p,
+                                    int pSz, const unsigned char* g, int gSz);
+WOLFSSL_API int  wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX*, const unsigned char* b,
+                                           long sz, int format);
+
+#ifndef NO_FILESYSTEM
+    WOLFSSL_API int  wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX*, const char* f,
+                                             int format);
+#endif
+
+WOLFSSL_API int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX*, unsigned short);
+WOLFSSL_API int wolfSSL_SetMinDhKey_Sz(WOLFSSL*, unsigned short);
+WOLFSSL_API int wolfSSL_GetDhKey_Sz(WOLFSSL*);
+#endif /* NO_DH */
+
+WOLFSSL_API int  wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL*, unsigned short);
+WOLFSSL_API int  wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX*, unsigned short);
+
+/* keyblock size in bytes or -1 */
+/* need to call wolfSSL_KeepArrays before handshake to save keys */
+WOLFSSL_API int wolfSSL_get_keyblock_size(WOLFSSL*);
+WOLFSSL_API int wolfSSL_get_keys(WOLFSSL*,unsigned char** ms, unsigned int* msLen,
+                                       unsigned char** sr, unsigned int* srLen,
+                                       unsigned char** cr, unsigned int* crLen);
+
+/* Computes EAP-TLS and EAP-TTLS keying material from the master_secret. */
+WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL*, void* key, unsigned int len,
+                                                             const char* label);
+
+
+#ifndef _WIN32
+    #ifndef NO_WRITEV
+        #ifdef __PPU
+            #include <sys/types.h>
+            #include <sys/socket.h>
+        #elif !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_IAR_ARM) && \
+              !defined(WOLFSSL_PICOTCP) && !defined(WOLFSSL_ROWLEY_ARM)
+            #include <sys/uio.h>
+        #endif
+        /* allow writev style writing */
+        WOLFSSL_API int wolfSSL_writev(WOLFSSL* ssl, const struct iovec* iov,
+                                     int iovcnt);
+    #endif
+#endif
+
+
+#ifndef NO_CERTS
+    /* SSL_CTX versions */
+    WOLFSSL_API int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX*);
+    WOLFSSL_API int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX*,
+                                               const unsigned char*, long, int);
+    WOLFSSL_API int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX*,
+                                               const unsigned char*, long, int);
+    WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX*,
+                                               const unsigned char*, long, int);
+    WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX*,
+                                                    const unsigned char*, long);
+
+    /* SSL versions */
+    WOLFSSL_API int wolfSSL_use_certificate_buffer(WOLFSSL*, const unsigned char*,
+                                               long, int);
+    WOLFSSL_API int wolfSSL_use_PrivateKey_buffer(WOLFSSL*, const unsigned char*,
+                                               long, int);
+    WOLFSSL_API int wolfSSL_use_certificate_chain_buffer(WOLFSSL*,
+                                               const unsigned char*, long);
+    WOLFSSL_API int wolfSSL_UnloadCertsKeys(WOLFSSL*);
+#endif
+
+WOLFSSL_API int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX*);
+WOLFSSL_API int wolfSSL_set_group_messages(WOLFSSL*);
+
+/* I/O callbacks */
+typedef int (*CallbackIORecv)(WOLFSSL *ssl, char *buf, int sz, void *ctx);
+typedef int (*CallbackIOSend)(WOLFSSL *ssl, char *buf, int sz, void *ctx);
+
+#ifdef HAVE_FUZZER
+enum fuzzer_type {
+    FUZZ_HMAC      = 0,
+    FUZZ_ENCRYPT   = 1,
+    FUZZ_SIGNATURE = 2,
+    FUZZ_HASH      = 3,
+    FUZZ_HEAD      = 4
+};
+
+typedef int (*CallbackFuzzer)(WOLFSSL* ssl, const unsigned char* buf, int sz,
+        int type, void* fuzzCtx);
+
+WOLFSSL_API void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx);
+#endif
+
+WOLFSSL_API void wolfSSL_SetIORecv(WOLFSSL_CTX*, CallbackIORecv);
+WOLFSSL_API void wolfSSL_SetIOSend(WOLFSSL_CTX*, CallbackIOSend);
+
+WOLFSSL_API void wolfSSL_SetIOReadCtx( WOLFSSL* ssl, void *ctx);
+WOLFSSL_API void wolfSSL_SetIOWriteCtx(WOLFSSL* ssl, void *ctx);
+
+WOLFSSL_API void* wolfSSL_GetIOReadCtx( WOLFSSL* ssl);
+WOLFSSL_API void* wolfSSL_GetIOWriteCtx(WOLFSSL* ssl);
+
+WOLFSSL_API void wolfSSL_SetIOReadFlags( WOLFSSL* ssl, int flags);
+WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags);
+
+
+#ifndef WOLFSSL_USER_IO
+    /* default IO callbacks */
+    WOLFSSL_API int EmbedReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx);
+    WOLFSSL_API int EmbedSend(WOLFSSL* ssl, char* buf, int sz, void* ctx);
+
+    #ifdef HAVE_OCSP
+        WOLFSSL_API int EmbedOcspLookup(void*, const char*, int, unsigned char*,
+                                       int, unsigned char**);
+        WOLFSSL_API void EmbedOcspRespFree(void*, unsigned char*);
+    #endif
+
+    #ifdef WOLFSSL_DTLS
+        WOLFSSL_API int EmbedReceiveFrom(WOLFSSL* ssl, char* buf, int sz, void*);
+        WOLFSSL_API int EmbedSendTo(WOLFSSL* ssl, char* buf, int sz, void* ctx);
+        WOLFSSL_API int EmbedGenerateCookie(WOLFSSL* ssl, unsigned char* buf,
+                                           int sz, void*);
+    #endif /* WOLFSSL_DTLS */
+#endif /* WOLFSSL_USER_IO */
+
+
+#ifdef HAVE_NETX
+    WOLFSSL_API void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket,
+                                      ULONG waitoption);
+#endif
+
+typedef int (*CallbackGenCookie)(WOLFSSL* ssl, unsigned char* buf, int sz,
+                                 void* ctx);
+WOLFSSL_API void  wolfSSL_CTX_SetGenCookie(WOLFSSL_CTX*, CallbackGenCookie);
+WOLFSSL_API void  wolfSSL_SetCookieCtx(WOLFSSL* ssl, void *ctx);
+WOLFSSL_API void* wolfSSL_GetCookieCtx(WOLFSSL* ssl);
+WOLFSSL_API int   wolfSSL_DTLS_SetCookieSecret(WOLFSSL*,
+                                               const unsigned char*,
+                                               unsigned int);
+
+
+/* I/O Callback default errors */
+enum IOerrors {
+    WOLFSSL_CBIO_ERR_GENERAL    = -1,     /* general unexpected err */
+    WOLFSSL_CBIO_ERR_WANT_READ  = -2,     /* need to call read  again */
+    WOLFSSL_CBIO_ERR_WANT_WRITE = -2,     /* need to call write again */
+    WOLFSSL_CBIO_ERR_CONN_RST   = -3,     /* connection reset */
+    WOLFSSL_CBIO_ERR_ISR        = -4,     /* interrupt */
+    WOLFSSL_CBIO_ERR_CONN_CLOSE = -5,     /* connection closed or epipe */
+    WOLFSSL_CBIO_ERR_TIMEOUT    = -6      /* socket timeout */
+};
+
+
+/* CA cache callbacks */
+enum {
+    WOLFSSL_SSLV3    = 0,
+    WOLFSSL_TLSV1    = 1,
+    WOLFSSL_TLSV1_1  = 2,
+    WOLFSSL_TLSV1_2  = 3,
+    WOLFSSL_USER_CA  = 1,          /* user added as trusted */
+    WOLFSSL_CHAIN_CA = 2           /* added to cache from trusted chain */
+};
+
+WOLFSSL_API int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version);
+WOLFSSL_API int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version);
+WOLFSSL_API int wolfSSL_GetObjectSize(void);  /* object size based on build */
+WOLFSSL_API int wolfSSL_SetVersion(WOLFSSL* ssl, int version);
+WOLFSSL_API int wolfSSL_KeyPemToDer(const unsigned char*, int,
+                                    unsigned char*, int, const char*);
+WOLFSSL_API int wolfSSL_CertPemToDer(const unsigned char*, int,
+                                     unsigned char*, int, int);
+#ifdef WOLFSSL_CERT_EXT
+    #ifndef WOLFSSL_PEMPUBKEY_TODER_DEFINED
+        WOLFSSL_API int wolfSSL_PemPubKeyToDer(const char* fileName,
+                                               unsigned char* derBuf, int derSz);
+        WOLFSSL_API int wolfSSL_PubKeyPemToDer(const unsigned char*, int,
+                                               unsigned char*, int);
+    #define WOLFSSL_PEMPUBKEY_TODER_DEFINED
+    #endif
+#endif /* WOLFSSL_CERT_EXT */
+
+typedef void (*CallbackCACache)(unsigned char* der, int sz, int type);
+typedef void (*CbMissingCRL)(const char* url);
+typedef int  (*CbOCSPIO)(void*, const char*, int,
+                                         unsigned char*, int, unsigned char**);
+typedef void (*CbOCSPRespFree)(void*,unsigned char*);
+
+/* User Atomic Record Layer CallBacks */
+typedef int (*CallbackMacEncrypt)(WOLFSSL* ssl, unsigned char* macOut,
+       const unsigned char* macIn, unsigned int macInSz, int macContent,
+       int macVerify, unsigned char* encOut, const unsigned char* encIn,
+       unsigned int encSz, void* ctx);
+WOLFSSL_API void  wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX*, CallbackMacEncrypt);
+WOLFSSL_API void  wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx);
+WOLFSSL_API void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl);
+
+typedef int (*CallbackDecryptVerify)(WOLFSSL* ssl,
+       unsigned char* decOut, const unsigned char* decIn,
+       unsigned int decSz, int content, int verify, unsigned int* padSz,
+       void* ctx);
+WOLFSSL_API void  wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX*,
+                                               CallbackDecryptVerify);
+WOLFSSL_API void  wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx);
+WOLFSSL_API void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl);
+
+WOLFSSL_API const unsigned char* wolfSSL_GetMacSecret(WOLFSSL*, int);
+WOLFSSL_API const unsigned char* wolfSSL_GetClientWriteKey(WOLFSSL*);
+WOLFSSL_API const unsigned char* wolfSSL_GetClientWriteIV(WOLFSSL*);
+WOLFSSL_API const unsigned char* wolfSSL_GetServerWriteKey(WOLFSSL*);
+WOLFSSL_API const unsigned char* wolfSSL_GetServerWriteIV(WOLFSSL*);
+WOLFSSL_API int                  wolfSSL_GetKeySize(WOLFSSL*);
+WOLFSSL_API int                  wolfSSL_GetIVSize(WOLFSSL*);
+WOLFSSL_API int                  wolfSSL_GetSide(WOLFSSL*);
+WOLFSSL_API int                  wolfSSL_IsTLSv1_1(WOLFSSL*);
+WOLFSSL_API int                  wolfSSL_GetBulkCipher(WOLFSSL*);
+WOLFSSL_API int                  wolfSSL_GetCipherBlockSize(WOLFSSL*);
+WOLFSSL_API int                  wolfSSL_GetAeadMacSize(WOLFSSL*);
+WOLFSSL_API int                  wolfSSL_GetHmacSize(WOLFSSL*);
+WOLFSSL_API int                  wolfSSL_GetHmacType(WOLFSSL*);
+WOLFSSL_API int                  wolfSSL_GetCipherType(WOLFSSL*);
+WOLFSSL_API int                  wolfSSL_SetTlsHmacInner(WOLFSSL*, unsigned char*,
+                                                       unsigned int, int, int);
+
+/* Atomic User Needs */
+enum {
+    WOLFSSL_SERVER_END = 0,
+    WOLFSSL_CLIENT_END = 1,
+    WOLFSSL_BLOCK_TYPE = 2,
+    WOLFSSL_STREAM_TYPE = 3,
+    WOLFSSL_AEAD_TYPE = 4,
+    WOLFSSL_TLS_HMAC_INNER_SZ = 13      /* SEQ_SZ + ENUM + VERSION_SZ + LEN_SZ */
+};
+
+/* for GetBulkCipher and internal use */
+enum BulkCipherAlgorithm {
+    wolfssl_cipher_null,
+    wolfssl_rc4,
+    wolfssl_rc2,
+    wolfssl_des,
+    wolfssl_triple_des,             /* leading 3 (3des) not valid identifier */
+    wolfssl_des40,
+    wolfssl_idea,
+    wolfssl_aes,
+    wolfssl_aes_gcm,
+    wolfssl_aes_ccm,
+    wolfssl_chacha,
+    wolfssl_camellia,
+    wolfssl_hc128,                  /* wolfSSL extensions */
+    wolfssl_rabbit
+};
+
+
+/* for KDF TLS 1.2 mac types */
+enum KDF_MacAlgorithm {
+    wolfssl_sha256 = 4,     /* needs to match internal MACAlgorithm */
+    wolfssl_sha384,
+    wolfssl_sha512
+};
+
+
+/* Public Key Callback support */
+typedef int (*CallbackEccSign)(WOLFSSL* ssl,
+       const unsigned char* in, unsigned int inSz,
+       unsigned char* out, unsigned int* outSz,
+       const unsigned char* keyDer, unsigned int keySz,
+       void* ctx);
+WOLFSSL_API void  wolfSSL_CTX_SetEccSignCb(WOLFSSL_CTX*, CallbackEccSign);
+WOLFSSL_API void  wolfSSL_SetEccSignCtx(WOLFSSL* ssl, void *ctx);
+WOLFSSL_API void* wolfSSL_GetEccSignCtx(WOLFSSL* ssl);
+
+typedef int (*CallbackEccVerify)(WOLFSSL* ssl,
+       const unsigned char* sig, unsigned int sigSz,
+       const unsigned char* hash, unsigned int hashSz,
+       const unsigned char* keyDer, unsigned int keySz,
+       int* result, void* ctx);
+WOLFSSL_API void  wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX*, CallbackEccVerify);
+WOLFSSL_API void  wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx);
+WOLFSSL_API void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl);
+
+typedef int (*CallbackRsaSign)(WOLFSSL* ssl,
+       const unsigned char* in, unsigned int inSz,
+       unsigned char* out, unsigned int* outSz,
+       const unsigned char* keyDer, unsigned int keySz,
+       void* ctx);
+WOLFSSL_API void  wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX*, CallbackRsaSign);
+WOLFSSL_API void  wolfSSL_SetRsaSignCtx(WOLFSSL* ssl, void *ctx);
+WOLFSSL_API void* wolfSSL_GetRsaSignCtx(WOLFSSL* ssl);
+
+typedef int (*CallbackRsaVerify)(WOLFSSL* ssl,
+       unsigned char* sig, unsigned int sigSz,
+       unsigned char** out,
+       const unsigned char* keyDer, unsigned int keySz,
+       void* ctx);
+WOLFSSL_API void  wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX*, CallbackRsaVerify);
+WOLFSSL_API void  wolfSSL_SetRsaVerifyCtx(WOLFSSL* ssl, void *ctx);
+WOLFSSL_API void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl);
+
+/* RSA Public Encrypt cb */
+typedef int (*CallbackRsaEnc)(WOLFSSL* ssl,
+       const unsigned char* in, unsigned int inSz,
+       unsigned char* out, unsigned int* outSz,
+       const unsigned char* keyDer, unsigned int keySz,
+       void* ctx);
+WOLFSSL_API void  wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX*, CallbackRsaEnc);
+WOLFSSL_API void  wolfSSL_SetRsaEncCtx(WOLFSSL* ssl, void *ctx);
+WOLFSSL_API void* wolfSSL_GetRsaEncCtx(WOLFSSL* ssl);
+
+/* RSA Private Decrypt cb */
+typedef int (*CallbackRsaDec)(WOLFSSL* ssl,
+       unsigned char* in, unsigned int inSz,
+       unsigned char** out,
+       const unsigned char* keyDer, unsigned int keySz,
+       void* ctx);
+WOLFSSL_API void  wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX*, CallbackRsaDec);
+WOLFSSL_API void  wolfSSL_SetRsaDecCtx(WOLFSSL* ssl, void *ctx);
+WOLFSSL_API void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl);
+
+
+#ifndef NO_CERTS
+    WOLFSSL_API void wolfSSL_CTX_SetCACb(WOLFSSL_CTX*, CallbackCACache);
+
+    WOLFSSL_API WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void);
+    WOLFSSL_API void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER*);
+
+    WOLFSSL_API int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER*, const char* f,
+                                                                 const char* d);
+    WOLFSSL_API int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER*,
+                                  const unsigned char* in, long sz, int format);
+    WOLFSSL_API int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm);
+    WOLFSSL_API int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER*, const char* f,
+                                                                    int format);
+    WOLFSSL_API int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm,
+                                const unsigned char* buff, long sz, int format);
+    WOLFSSL_API int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER*,
+                                                        unsigned char*, int sz);
+    WOLFSSL_API int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER*,
+                                                                   int options);
+    WOLFSSL_API int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER*);
+    WOLFSSL_API int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER*,
+                                                         const char*, int, int);
+    WOLFSSL_API int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER*,
+                                            const unsigned char*, long sz, int);
+    WOLFSSL_API int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER*,
+                                                                  CbMissingCRL);
+    WOLFSSL_API int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER*,
+                                                        unsigned char*, int sz);
+    WOLFSSL_API int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER*,
+                                                                   int options);
+    WOLFSSL_API int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER*);
+    WOLFSSL_API int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER*,
+                                                                   const char*);
+    WOLFSSL_API int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER*,
+                                               CbOCSPIO, CbOCSPRespFree, void*);
+
+    WOLFSSL_API int wolfSSL_EnableCRL(WOLFSSL* ssl, int options);
+    WOLFSSL_API int wolfSSL_DisableCRL(WOLFSSL* ssl);
+    WOLFSSL_API int wolfSSL_LoadCRL(WOLFSSL*, const char*, int, int);
+    WOLFSSL_API int wolfSSL_SetCRL_Cb(WOLFSSL*, CbMissingCRL);
+    WOLFSSL_API int wolfSSL_EnableOCSP(WOLFSSL*, int options);
+    WOLFSSL_API int wolfSSL_DisableOCSP(WOLFSSL*);
+    WOLFSSL_API int wolfSSL_SetOCSP_OverrideURL(WOLFSSL*, const char*);
+    WOLFSSL_API int wolfSSL_SetOCSP_Cb(WOLFSSL*, CbOCSPIO, CbOCSPRespFree, void*);
+
+    WOLFSSL_API int wolfSSL_CTX_EnableCRL(WOLFSSL_CTX* ctx, int options);
+    WOLFSSL_API int wolfSSL_CTX_DisableCRL(WOLFSSL_CTX* ctx);
+    WOLFSSL_API int wolfSSL_CTX_LoadCRL(WOLFSSL_CTX*, const char*, int, int);
+    WOLFSSL_API int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX*, CbMissingCRL);
+    WOLFSSL_API int wolfSSL_CTX_EnableOCSP(WOLFSSL_CTX*, int options);
+    WOLFSSL_API int wolfSSL_CTX_DisableOCSP(WOLFSSL_CTX*);
+    WOLFSSL_API int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX*, const char*);
+    WOLFSSL_API int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX*,
+                                               CbOCSPIO, CbOCSPRespFree, void*);
+#endif /* !NO_CERTS */
+
+/* end of handshake frees temporary arrays, if user needs for get_keys or
+   psk hints, call KeepArrays before handshake and then FreeArrays when done
+   if don't want to wait for object free */
+WOLFSSL_API void wolfSSL_KeepArrays(WOLFSSL*);
+WOLFSSL_API void wolfSSL_FreeArrays(WOLFSSL*);
+
+
+/* cavium additions */
+WOLFSSL_API int wolfSSL_UseCavium(WOLFSSL*, int devId);
+WOLFSSL_API int wolfSSL_CTX_UseCavium(WOLFSSL_CTX*, int devId);
+
+/* TLS Extensions */
+
+/* Server Name Indication */
+#ifdef HAVE_SNI
+
+/* SNI types */
+enum {
+    WOLFSSL_SNI_HOST_NAME = 0
+};
+
+WOLFSSL_API int wolfSSL_UseSNI(WOLFSSL* ssl, unsigned char type,
+                                         const void* data, unsigned short size);
+WOLFSSL_API int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, unsigned char type,
+                                         const void* data, unsigned short size);
+
+#ifndef NO_WOLFSSL_SERVER
+
+/* SNI options */
+enum {
+    /* Do not abort the handshake if the requested SNI didn't match. */
+    WOLFSSL_SNI_CONTINUE_ON_MISMATCH = 0x01,
+
+    /* Behave as if the requested SNI matched in a case of missmatch.  */
+    /* In this case, the status will be set to WOLFSSL_SNI_FAKE_MATCH. */
+    WOLFSSL_SNI_ANSWER_ON_MISMATCH   = 0x02,
+
+    /* Abort the handshake if the client didn't send a SNI request. */
+    WOLFSSL_SNI_ABORT_ON_ABSENCE     = 0x04,
+};
+
+WOLFSSL_API void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, unsigned char type,
+                                                         unsigned char options);
+WOLFSSL_API void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx,
+                                     unsigned char type, unsigned char options);
+
+/* SNI status */
+enum {
+    WOLFSSL_SNI_NO_MATCH   = 0,
+    WOLFSSL_SNI_FAKE_MATCH = 1, /**< @see WOLFSSL_SNI_ANSWER_ON_MISMATCH */
+    WOLFSSL_SNI_REAL_MATCH = 2,
+    WOLFSSL_SNI_FORCE_KEEP = 3  /** Used with -DWOLFSSL_ALWAYS_KEEP_SNI */
+};
+
+WOLFSSL_API unsigned char wolfSSL_SNI_Status(WOLFSSL* ssl, unsigned char type);
+
+WOLFSSL_API unsigned short wolfSSL_SNI_GetRequest(WOLFSSL *ssl,
+                                               unsigned char type, void** data);
+WOLFSSL_API int wolfSSL_SNI_GetFromBuffer(
+                 const unsigned char* clientHello, unsigned int helloSz,
+                 unsigned char type, unsigned char* sni, unsigned int* inOutSz);
+
+#endif
+#endif
+
+/* Application-Layer Protocol Name */
+#ifdef HAVE_ALPN
+
+/* ALPN status code */
+enum {
+    WOLFSSL_ALPN_NO_MATCH = 0,
+    WOLFSSL_ALPN_MATCH    = 1,
+    WOLFSSL_ALPN_CONTINUE_ON_MISMATCH = 2,
+    WOLFSSL_ALPN_FAILED_ON_MISMATCH = 4,
+};
+
+enum {
+    WOLFSSL_MAX_ALPN_PROTO_NAME_LEN = 255,
+    WOLFSSL_MAX_ALPN_NUMBER = 257
+};
+
+WOLFSSL_API int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
+                                unsigned int protocol_name_listSz,
+                                unsigned char options);
+
+WOLFSSL_API int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name,
+                                         unsigned short *size);
+
+WOLFSSL_API int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list,
+                                             unsigned short *listSz);
+#endif /* HAVE_ALPN */
+
+/* Maximum Fragment Length */
+#ifdef HAVE_MAX_FRAGMENT
+
+/* Fragment lengths */
+enum {
+    WOLFSSL_MFL_2_9  = 1, /*  512 bytes */
+    WOLFSSL_MFL_2_10 = 2, /* 1024 bytes */
+    WOLFSSL_MFL_2_11 = 3, /* 2048 bytes */
+    WOLFSSL_MFL_2_12 = 4, /* 4096 bytes */
+    WOLFSSL_MFL_2_13 = 5  /* 8192 bytes *//* wolfSSL ONLY!!! */
+};
+
+#ifndef NO_WOLFSSL_CLIENT
+
+WOLFSSL_API int wolfSSL_UseMaxFragment(WOLFSSL* ssl, unsigned char mfl);
+WOLFSSL_API int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, unsigned char mfl);
+
+#endif
+#endif
+
+/* Truncated HMAC */
+#ifdef HAVE_TRUNCATED_HMAC
+#ifndef NO_WOLFSSL_CLIENT
+
+WOLFSSL_API int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl);
+WOLFSSL_API int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx);
+
+#endif
+#endif
+
+/* Elliptic Curves */
+enum {
+    WOLFSSL_ECC_SECP160R1 = 0x10,
+    WOLFSSL_ECC_SECP192R1 = 0x13,
+    WOLFSSL_ECC_SECP224R1 = 0x15,
+    WOLFSSL_ECC_SECP256R1 = 0x17,
+    WOLFSSL_ECC_SECP384R1 = 0x18,
+    WOLFSSL_ECC_SECP521R1 = 0x19
+};
+
+#ifdef HAVE_SUPPORTED_CURVES
+#ifndef NO_WOLFSSL_CLIENT
+
+WOLFSSL_API int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, unsigned short name);
+WOLFSSL_API int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx,
+                                                           unsigned short name);
+
+#endif
+#endif
+
+
+/* Secure Renegotiation */
+#ifdef HAVE_SECURE_RENEGOTIATION
+
+WOLFSSL_API int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl);
+WOLFSSL_API int wolfSSL_Rehandshake(WOLFSSL* ssl);
+
+#endif
+
+/* Session Ticket */
+#ifdef HAVE_SESSION_TICKET
+
+#ifndef NO_WOLFSSL_CLIENT
+WOLFSSL_API int wolfSSL_UseSessionTicket(WOLFSSL* ssl);
+WOLFSSL_API int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx);
+WOLFSSL_API int wolfSSL_get_SessionTicket(WOLFSSL*, unsigned char*, unsigned int*);
+WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL*, unsigned char*, unsigned int);
+typedef int (*CallbackSessionTicket)(WOLFSSL*, const unsigned char*, int, void*);
+WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL*,
+                                                  CallbackSessionTicket, void*);
+#endif /* NO_WOLFSSL_CLIENT */
+
+#ifndef NO_WOLFSSL_SERVER
+
+#define WOLFSSL_TICKET_NAME_SZ 16
+#define WOLFSSL_TICKET_IV_SZ   16
+#define WOLFSSL_TICKET_MAC_SZ  32
+
+enum TicketEncRet {
+    WOLFSSL_TICKET_RET_FATAL  = -1,  /* fatal error, don't use ticket */
+    WOLFSSL_TICKET_RET_OK     =  0,  /* ok, use ticket */
+    WOLFSSL_TICKET_RET_REJECT,       /* don't use ticket, but not fatal */
+    WOLFSSL_TICKET_RET_CREATE        /* existing ticket ok and create new one */
+};
+
+typedef int (*SessionTicketEncCb)(WOLFSSL*,
+                                 unsigned char key_name[WOLFSSL_TICKET_NAME_SZ],
+                                 unsigned char iv[WOLFSSL_TICKET_IV_SZ],
+                                 unsigned char mac[WOLFSSL_TICKET_MAC_SZ],
+                                 int enc, unsigned char*, int, int*, void*);
+WOLFSSL_API int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx,
+                                            SessionTicketEncCb);
+WOLFSSL_API int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int);
+WOLFSSL_API int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void*);
+
+#endif /* NO_WOLFSSL_SERVER */
+
+#endif /* HAVE_SESSION_TICKET */
+
+#ifdef HAVE_QSH
+/* Quantum-safe Crypto Schemes */
+enum {
+    WOLFSSL_NTRU_EESS439 = 0x0101, /* max plaintext length of 65  */
+    WOLFSSL_NTRU_EESS593 = 0x0102, /* max plaintext length of 86  */
+    WOLFSSL_NTRU_EESS743 = 0x0103, /* max plaintext length of 106 */
+    WOLFSSL_LWE_XXX  = 0x0201,     /* Learning With Error encryption scheme */
+    WOLFSSL_HFE_XXX  = 0x0301,     /* Hidden Field Equotion scheme */
+    WOLFSSL_NULL_QSH = 0xFFFF      /* QSHScheme is not used */
+};
+
+
+/* test if the connection is using a QSH secure connection return 1 if so */
+WOLFSSL_API int wolfSSL_isQSH(WOLFSSL* ssl);
+WOLFSSL_API int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, unsigned short name);
+#ifndef NO_WOLFSSL_CLIENT
+    /* user control over sending client public key in hello
+       when flag = 1 will send keys if flag is 0 or function is not called
+       then will not send keys in the hello extension */
+    WOLFSSL_API int wolfSSL_UseClientQSHKeys(WOLFSSL* ssl, unsigned char flag);
+#endif
+#endif
+
+#define WOLFSSL_CRL_MONITOR   0x01   /* monitor this dir flag */
+#define WOLFSSL_CRL_START_MON 0x02   /* start monitoring flag */
+
+
+/* notify user the hanshake is done */
+typedef int (*HandShakeDoneCb)(WOLFSSL*, void*);
+WOLFSSL_API int wolfSSL_SetHsDoneCb(WOLFSSL*, HandShakeDoneCb, void*);
+
+
+WOLFSSL_API int wolfSSL_PrintSessionStats(void);
+WOLFSSL_API int wolfSSL_get_session_stats(unsigned int* active,
+                                          unsigned int* total,
+                                          unsigned int* peak,
+                                          unsigned int* maxSessions);
+/* External facing KDF */
+WOLFSSL_API
+int wolfSSL_MakeTlsMasterSecret(unsigned char* ms, unsigned int msLen,
+                               const unsigned char* pms, unsigned int pmsLen,
+                               const unsigned char* cr, const unsigned char* sr,
+                               int tls1_2, int hash_type);
+
+WOLFSSL_API
+int wolfSSL_DeriveTlsKeys(unsigned char* key_data, unsigned int keyLen,
+                               const unsigned char* ms, unsigned int msLen,
+                               const unsigned char* sr, const unsigned char* cr,
+                               int tls1_2, int hash_type);
+
+#ifdef WOLFSSL_CALLBACKS
+
+/* used internally by wolfSSL while OpenSSL types aren't */
+#include <wolfssl/callbacks.h>
+
+typedef int (*HandShakeCallBack)(HandShakeInfo*);
+typedef int (*TimeoutCallBack)(TimeoutInfo*);
+
+/* wolfSSL connect extension allowing HandShakeCallBack and/or TimeoutCallBack
+   for diagnostics */
+WOLFSSL_API int wolfSSL_connect_ex(WOLFSSL*, HandShakeCallBack, TimeoutCallBack,
+                                 Timeval);
+WOLFSSL_API int wolfSSL_accept_ex(WOLFSSL*, HandShakeCallBack, TimeoutCallBack,
+                                Timeval);
+
+#endif /* WOLFSSL_CALLBACKS */
+
+
+#ifdef WOLFSSL_HAVE_WOLFSCEP
+    WOLFSSL_API void wolfSSL_wolfSCEP(void);
+#endif /* WOLFSSL_HAVE_WOLFSCEP */
+
+#ifdef WOLFSSL_HAVE_CERT_SERVICE
+    WOLFSSL_API void wolfSSL_cert_service(void);
+#endif
+
+
+#ifdef OPENSSL_EXTRA /*lighttp compatibility */
+#ifdef HAVE_LIGHTY
+
+typedef struct WOLFSSL_X509_NAME_ENTRY {
+    WOLFSSL_ASN1_OBJECT* object;
+    WOLFSSL_ASN1_STRING* value;
+    int set;
+    int size;
+} WOLFSSL_X509_NAME_ENTRY;
+
+
+#include <wolfssl/openssl/dh.h>
+#include <wolfssl/openssl/asn1.h>
+
+WOLFSSL_API void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name);
+WOLFSSL_API char wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x);
+WOLFSSL_API int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey);
+WOLFSSL_API int wolfSSL_BIO_read_filename(WOLFSSL_BIO *b, const char *name);
+WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_file(void);
+/* These are to be merged shortly */
+WOLFSSL_API const char *  wolf_OBJ_nid2sn(int n);
+WOLFSSL_API int wolf_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o);
+WOLFSSL_API int wolf_OBJ_sn2nid(const char *sn);
+WOLFSSL_API WOLFSSL_X509 *PEM_read_bio_WOLFSSL_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u);
+WOLFSSL_API void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx,int depth);
+WOLFSSL_API void* wolfSSL_get_app_data( const WOLFSSL *ssl);
+WOLFSSL_API void wolfSSL_set_app_data(WOLFSSL *ssl, void *arg);
+WOLFSSL_API WOLFSSL_ASN1_OBJECT * wolfSSL_X509_NAME_ENTRY_get_object(WOLFSSL_X509_NAME_ENTRY *ne);
+WOLFSSL_API WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(WOLFSSL_X509_NAME *name, int loc);
+WOLFSSL_API void wolfSSL_sk_X509_NAME_pop_free(STACK_OF(WOLFSSL_X509_NAME)* sk, void f (WOLFSSL_X509_NAME*));
+WOLFSSL_API unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n, unsigned char *md);
+WOLFSSL_API int wolfSSL_X509_check_private_key(WOLFSSL_X509*, WOLFSSL_EVP_PKEY*);
+WOLFSSL_API STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list( STACK_OF(WOLFSSL_X509_NAME) *sk );
+
+/* end lighttpd*/
+#endif
+#endif
+
+#if defined(HAVE_STUNNEL) || defined(HAVE_LIGHTY)
+
+WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_file(const char *filename, const char *mode);
+WOLFSSL_API long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX*, WOLFSSL_DH*);
+WOLFSSL_API WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bp,
+    WOLFSSL_DH **x, pem_password_cb *cb, void *u);
+WOLFSSL_API int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 *x);
+
+
+#endif /* HAVE_STUNNEL || HAVE_LIGHTY */
+
+
+#ifdef HAVE_STUNNEL
+
+#include <wolfssl/openssl/crypto.h>
+
+/* SNI received callback type */
+typedef int (*CallbackSniRecv)(WOLFSSL *ssl, int *ret, void* exArg);
+
+WOLFSSL_API int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
+    void *(*r) (void *, size_t, const char *, int), void (*f) (void *));
+
+WOLFSSL_API WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator,
+    void (*callback) (int, int, void *), void *cb_arg);
+
+WOLFSSL_API void wolfSSL_ERR_load_crypto_strings(void);
+
+WOLFSSL_API unsigned long wolfSSL_ERR_peek_last_error(void);
+
+WOLFSSL_API int wolfSSL_FIPS_mode(void);
+
+WOLFSSL_API int wolfSSL_FIPS_mode_set(int r);
+
+WOLFSSL_API int wolfSSL_RAND_set_rand_method(const void *meth);
+
+WOLFSSL_API int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits);
+
+WOLFSSL_API int wolfSSL_sk_X509_NAME_num(const STACK_OF(WOLFSSL_X509_NAME) *s);
+
+WOLFSSL_API int wolfSSL_sk_X509_num(const STACK_OF(WOLFSSL_X509) *s);
+
+WOLFSSL_API int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO*,WOLFSSL_X509_NAME*,int,
+        unsigned long);
+
+WOLFSSL_API WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr(
+                            const WOLFSSL_X509*);
+
+WOLFSSL_API int        wolfSSL_CTX_add_session(WOLFSSL_CTX*, WOLFSSL_SESSION*);
+
+WOLFSSL_API WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl);
+
+WOLFSSL_API int  wolfSSL_version(WOLFSSL*);
+
+WOLFSSL_API int wolfSSL_get_state(const WOLFSSL*);
+
+WOLFSSL_API void* wolfSSL_sk_X509_NAME_value(STACK_OF(WOLFSSL_X509_NAME)*, int);
+
+WOLFSSL_API void* wolfSSL_sk_X509_value(STACK_OF(WOLFSSL_X509)*, int);
+
+WOLFSSL_API STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL*);
+
+WOLFSSL_API long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx);
+
+WOLFSSL_API void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION*, int);
+
+WOLFSSL_API int   wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION*, int, void*);
+
+WOLFSSL_API int wolfSSL_SESSION_get_ex_new_index(long,void*,void*,void*,
+        CRYPTO_free_func*);
+
+WOLFSSL_API int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME*);
+
+
+WOLFSSL_API const unsigned char* wolfSSL_SESSION_get_id(WOLFSSL_SESSION*,
+        unsigned int*);
+
+WOLFSSL_API int wolfSSL_set_tlsext_host_name(WOLFSSL *, const char *);
+
+WOLFSSL_API const char* wolfSSL_get_servername(WOLFSSL *, unsigned char);
+
+WOLFSSL_API WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL*,WOLFSSL_CTX*);
+
+WOLFSSL_API VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX*);
+
+WOLFSSL_API int wolfSSL_CTX_get_verify_mode(WOLFSSL_CTX* ctx);
+
+WOLFSSL_API void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX *,
+        CallbackSniRecv);
+
+WOLFSSL_API void wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX *, void*);
+#endif /* HAVE_STUNNEL */
+
+#ifdef WOLFSSL_JNI
+WOLFSSL_API int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr);
+WOLFSSL_API void* wolfSSL_get_jobject(WOLFSSL* ssl);
+#endif /* WOLFSSL_JNI */
+
+#ifdef __cplusplus
+    }  /* extern "C" */
+#endif
+
+
+#endif /* WOLFSSL_SSL_H */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/test.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/test.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/test.h	(revision 164)
@@ -0,0 +1,2051 @@
+/* test.h */
+
+#ifndef wolfSSL_TEST_H
+#define wolfSSL_TEST_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+#include <wolfssl/wolfcrypt/types.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/random.h>
+
+#ifdef ATOMIC_USER
+    #include <wolfssl/wolfcrypt/aes.h>
+    #include <wolfssl/wolfcrypt/arc4.h>
+    #include <wolfssl/wolfcrypt/hmac.h>
+#endif
+#ifdef HAVE_PK_CALLBACKS
+    #include <wolfssl/wolfcrypt/asn.h>
+    #ifdef HAVE_ECC
+        #include <wolfssl/wolfcrypt/ecc.h>
+    #endif /* HAVE_ECC */
+#endif /*HAVE_PK_CALLBACKS */
+
+#ifdef USE_WINDOWS_API
+    #include <winsock2.h>
+    #include <process.h>
+    #ifdef TEST_IPV6            /* don't require newer SDK for IPV4 */
+        #include <ws2tcpip.h>
+        #include <wspiapi.h>
+    #endif
+    #define SOCKET_T SOCKET
+    #define SNPRINTF _snprintf
+#elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
+    #include <string.h>
+    #include "rl_net.h"
+    #define SOCKET_T int
+        typedef int socklen_t ;
+        static unsigned long inet_addr(const char *cp)
+    {
+        unsigned int a[4] ; unsigned long ret ;
+        sscanf(cp, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) ;
+        ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ;
+        return(ret) ;
+    }
+        #if defined(HAVE_KEIL_RTX)
+        #define sleep(t) os_dly_wait(t/1000+1) ;
+    #elif defined (WOLFSSL_CMSIS_RTOS)
+        #define sleep(t)  osDelay(t/1000+1) ;
+    #endif
+
+    static int wolfssl_tcp_select(int sd, int timeout)
+    {        return 0 ;  }
+        #define tcp_select(sd,t)   wolfssl_tcp_select(sd, t)  /* avoid conflicting Keil TCP tcp_select */
+#elif defined(WOLFSSL_TIRTOS)
+    #include <string.h>
+    #include <netdb.h>
+    #include <sys/types.h>
+    #include <arpa/inet.h>
+    #include <sys/socket.h>
+    #include <ti/sysbios/knl/Task.h>
+    struct hostent {
+        char *h_name; /* official name of host */
+        char **h_aliases; /* alias list */
+        int h_addrtype; /* host address type */
+        int h_length; /* length of address */
+        char **h_addr_list; /* list of addresses from name server */
+    };
+    #define SOCKET_T int
+#elif defined(WOLFSSL_VXWORKS)
+    #include <hostLib.h>
+    #include <sockLib.h>
+    #include <arpa/inet.h>
+    #include <string.h>
+    #include <selectLib.h>
+    #include <sys/types.h>
+    #include <netinet/in.h>
+    #include <fcntl.h>
+    #include <sys/time.h>
+    #include <netdb.h>
+    #include <pthread.h>
+    #define SOCKET_T int
+#else
+    #include <string.h>
+    #include <sys/types.h>
+#if 0//ndef WOLFSSL_LEANPSK
+    #include <unistd.h>
+    #include <netdb.h>
+    #include <netinet/in.h>
+    #include <netinet/tcp.h>
+    #include <arpa/inet.h>
+    #include <sys/ioctl.h>
+    #include <sys/time.h>
+    #include <sys/socket.h>
+    #include <pthread.h>
+    #include <fcntl.h>
+    #ifdef TEST_IPV6
+        #include <netdb.h>
+    #endif
+#endif
+    #define SOCKET_T int
+    #ifndef SO_NOSIGPIPE
+        #include <signal.h>  /* ignore SIGPIPE */
+    #endif
+    #define SNPRINTF snprintf
+#endif /* USE_WINDOWS_API */
+
+#ifdef HAVE_CAVIUM
+    #include "cavium_sysdep.h"
+    #include "cavium_common.h"
+    #include "cavium_ioctl.h"
+#endif
+
+#ifdef _MSC_VER
+    /* disable conversion warning */
+    /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
+    #pragma warning(disable:4244 4996)
+#endif
+
+/* Buffer for benchmark tests */
+#ifndef TEST_BUFFER_SIZE
+#define TEST_BUFFER_SIZE 16384
+#endif
+
+#ifndef min
+    #define WOLFSSL_HAVE_MIN
+    static INLINE word32 min(word32 a, word32 b)
+    {
+        return a > b ? b : a;
+    }
+#endif /* WOLFSSL_HAVE_MIN */
+
+/* Socket Handling */
+#ifndef WOLFSSL_SOCKET_INVALID
+#ifdef USE_WINDOWS_API
+    #define WOLFSSL_SOCKET_INVALID  INVALID_SOCKET
+#elif defined(WOLFSSL_TIRTOS)
+    #define WOLFSSL_SOCKET_INVALID  -1
+#else
+    #define WOLFSSL_SOCKET_INVALID  0
+#endif
+#endif /* WOLFSSL_SOCKET_INVALID */
+
+#ifndef WOLFSSL_SOCKET_IS_INVALID
+#ifdef USE_WINDOWS_API
+    #define WOLFSSL_SOCKET_IS_INVALID(s)  ((s) == WOLFSSL_SOCKET_INVALID)
+#elif defined(WOLFSSL_TIRTOS)
+    #define WOLFSSL_SOCKET_IS_INVALID(s)  ((s) == WOLFSSL_SOCKET_INVALID)
+#else
+    #define WOLFSSL_SOCKET_IS_INVALID(s)  ((s) < WOLFSSL_SOCKET_INVALID)
+#endif
+#endif /* WOLFSSL_SOCKET_IS_INVALID */
+
+#if defined(__MACH__) || defined(USE_WINDOWS_API)
+    #ifndef _SOCKLEN_T
+        typedef int socklen_t;
+    #endif
+#endif
+
+#ifdef WOLFSSL_LWIP
+		/* lwIP needs to be configured to use sockets API in this mode */
+		/* LWIP_SOCKET 1 in lwip/opt.h or in build */
+#pragma warning(disable : 4005)
+#include <lwip/sockets.h>
+#include <lwip/netdb.h>
+#pragma warning(default : 4005)
+		//#include <errno.h>
+#ifndef LWIP_PROVIDE_ERRNO
+#define LWIP_PROVIDE_ERRNO 1
+#endif
+#endif
+
+/* HPUX doesn't use socklent_t for third parameter to accept, unless
+   _XOPEN_SOURCE_EXTENDED is defined */
+#if !defined(__hpux__) && !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_IAR_ARM)\
+ && !defined(WOLFSSL_ROWLEY_ARM)  && !defined(WOLFSSL_KEIL_TCP_NET)
+    typedef socklen_t* ACCEPT_THIRD_T;
+#else
+    #if defined _XOPEN_SOURCE_EXTENDED
+        typedef socklen_t* ACCEPT_THIRD_T;
+    #else
+        typedef int*       ACCEPT_THIRD_T;
+    #endif
+#endif
+
+
+#ifdef USE_WINDOWS_API
+    #define CloseSocket(s) closesocket(s)
+    #define StartTCP() { WSADATA wsd; WSAStartup(0x0002, &wsd); }
+#elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
+    #define CloseSocket(s) closesocket(s)
+    #define StartTCP()
+#else
+    #define CloseSocket(s) close(s)
+    #define StartTCP()
+#endif
+
+
+#ifdef SINGLE_THREADED
+    typedef unsigned int  THREAD_RETURN;
+    typedef void*         THREAD_TYPE;
+    #define WOLFSSL_THREAD
+#else
+    #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
+        typedef void*         THREAD_RETURN;
+        typedef pthread_t     THREAD_TYPE;
+        #define WOLFSSL_THREAD
+        #define INFINITE -1
+        #define WAIT_OBJECT_0 0L
+    #elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET)
+        typedef unsigned int  THREAD_RETURN;
+        typedef int           THREAD_TYPE;
+        #define WOLFSSL_THREAD
+    #elif defined(WOLFSSL_TIRTOS)
+        typedef void          THREAD_RETURN;
+        typedef Task_Handle   THREAD_TYPE;
+        #define WOLFSSL_THREAD
+    #else
+        typedef unsigned int  THREAD_RETURN;
+        typedef intptr_t      THREAD_TYPE;
+        #define WOLFSSL_THREAD __stdcall
+    #endif
+#endif
+
+
+#ifdef TEST_IPV6
+    typedef struct sockaddr_in6 SOCKADDR_IN_T;
+    #define AF_INET_V    AF_INET6
+#else
+    typedef struct sockaddr_in  SOCKADDR_IN_T;
+    #define AF_INET_V    AF_INET
+#endif
+
+
+#define SERVER_DEFAULT_VERSION 3
+#define SERVER_DTLS_DEFAULT_VERSION (-2)
+#define SERVER_INVALID_VERSION (-99)
+#define CLIENT_DEFAULT_VERSION 3
+#define CLIENT_DTLS_DEFAULT_VERSION (-2)
+#define CLIENT_INVALID_VERSION (-99)
+#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
+    #define DEFAULT_MIN_DHKEY_BITS 2048
+#else
+    #define DEFAULT_MIN_DHKEY_BITS 1024
+#endif
+
+/* all certs relative to wolfSSL home directory now */
+#if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL)
+#define caCert     "certs/ca-cert.pem"
+#define eccCert    "certs/server-ecc.pem"
+#define eccKey     "certs/ecc-key.pem"
+#define svrCert    "certs/server-cert.pem"
+#define svrKey     "certs/server-key.pem"
+#define cliCert    "certs/client-cert.pem"
+#define cliKey     "certs/client-key.pem"
+#define ntruCert   "certs/ntru-cert.pem"
+#define ntruKey    "certs/ntru-key.raw"
+#define dhParam    "certs/dh2048.pem"
+#define cliEccKey  "certs/ecc-client-key.pem"
+#define cliEccCert "certs/client-ecc-cert.pem"
+#define crlPemDir  "certs/crl"
+#else
+#define caCert     "./certs/ca-cert.pem"
+#define eccCert    "./certs/server-ecc.pem"
+#define eccKey     "./certs/ecc-key.pem"
+#define svrCert    "./certs/server-cert.pem"
+#define svrKey     "./certs/server-key.pem"
+#define cliCert    "./certs/client-cert.pem"
+#define cliKey     "./certs/client-key.pem"
+#define ntruCert   "./certs/ntru-cert.pem"
+#define ntruKey    "./certs/ntru-key.raw"
+#define dhParam    "./certs/dh2048.pem"
+#define cliEccKey  "./certs/ecc-client-key.pem"
+#define cliEccCert "./certs/client-ecc-cert.pem"
+#define crlPemDir  "./certs/crl"
+#endif
+
+typedef struct tcp_ready {
+    word16 ready;              /* predicate */
+    word16 port;
+#if defined(_POSIX_THREADS) && !defined(__MINGW32__)
+    pthread_mutex_t mutex;
+    pthread_cond_t  cond;
+#endif
+} tcp_ready;
+
+
+void InitTcpReady(tcp_ready*);
+void FreeTcpReady(tcp_ready*);
+
+typedef WOLFSSL_METHOD* (*method_provider)(void);
+typedef void (*ctx_callback)(WOLFSSL_CTX* ctx);
+typedef void (*ssl_callback)(WOLFSSL* ssl);
+
+typedef struct callback_functions {
+    method_provider method;
+    ctx_callback ctx_ready;
+    ssl_callback ssl_ready;
+    ssl_callback on_result;
+} callback_functions;
+
+typedef struct func_args {
+    int    argc;
+    char** argv;
+    int    return_code;
+    tcp_ready* signal;
+    callback_functions *callbacks;
+} func_args;
+
+void wait_tcp_ready(func_args*);
+
+typedef THREAD_RETURN WOLFSSL_THREAD THREAD_FUNC(void*);
+
+void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*);
+void join_thread(THREAD_TYPE);
+
+#undef INADDR_ANY
+static const char* const INADDR_ANY = "0.0.0.0";
+
+/* wolfSSL */
+#ifndef TEST_IPV6
+    static const char* const wolfSSLIP   = "127.0.0.1";
+#else
+    static const char* const wolfSSLIP   = "::1";
+#endif
+static const word16      wolfSSLPort = 11111;
+
+static INLINE void err_sys(const char* msg)
+{
+    printf("wolfSSL error: %s\n", msg);
+    if (msg)
+        exit(EXIT_FAILURE);
+}
+
+
+#define MY_EX_USAGE 2
+
+extern int   myoptind;
+extern char* myoptarg;
+
+static INLINE int mygetopt(int argc, char** argv, const char* optstring)
+{
+    static char* next = NULL;
+
+    char  c;
+    char* cp;
+
+    if (myoptind == 0)
+        next = NULL;   /* we're starting new/over */
+
+    if (next == NULL || *next == '\0') {
+        if (myoptind == 0)
+            myoptind++;
+
+        if (myoptind >= argc || argv[myoptind][0] != '-' ||
+                                argv[myoptind][1] == '\0') {
+            myoptarg = NULL;
+            if (myoptind < argc)
+                myoptarg = argv[myoptind];
+
+            return -1;
+        }
+
+        if (strcmp(argv[myoptind], "--") == 0) {
+            myoptind++;
+            myoptarg = NULL;
+
+            if (myoptind < argc)
+                myoptarg = argv[myoptind];
+
+            return -1;
+        }
+
+        next = argv[myoptind];
+        next++;                  /* skip - */
+        myoptind++;
+    }
+
+    c  = *next++;
+    /* The C++ strchr can return a different value */
+    cp = (char*)strchr(optstring, c);
+
+    if (cp == NULL || c == ':')
+        return '?';
+
+    cp++;
+
+    if (*cp == ':') {
+        if (*next != '\0') {
+            myoptarg = next;
+            next     = NULL;
+        }
+        else if (myoptind < argc) {
+            myoptarg = argv[myoptind];
+            myoptind++;
+        }
+        else
+            return '?';
+    }
+
+    return c;
+}
+
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+
+static INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
+{
+    (void)rw;
+    (void)userdata;
+    strncpy(passwd, "yassl123", sz);
+    return 8;
+}
+
+#endif
+
+
+#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
+
+static INLINE void ShowX509(WOLFSSL_X509* x509, const char* hdr)
+{
+    char* altName;
+    char* issuer  = wolfSSL_X509_NAME_oneline(
+                                       wolfSSL_X509_get_issuer_name(x509), 0, 0);
+    char* subject = wolfSSL_X509_NAME_oneline(
+                                      wolfSSL_X509_get_subject_name(x509), 0, 0);
+    byte  serial[32];
+    int   ret;
+    int   sz = sizeof(serial);
+
+    printf("%s\n issuer : %s\n subject: %s\n", hdr, issuer, subject);
+
+    while ( (altName = wolfSSL_X509_get_next_altname(x509)) != NULL)
+        printf(" altname = %s\n", altName);
+
+    ret = wolfSSL_X509_get_serial_number(x509, serial, &sz);
+    if (ret == SSL_SUCCESS) {
+        int  i;
+        int  strLen;
+        char serialMsg[80];
+
+        /* testsuite has multiple threads writing to stdout, get output
+           message ready to write once */
+        strLen = sprintf(serialMsg, " serial number");
+        for (i = 0; i < sz; i++)
+            sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]);
+        printf("%s\n", serialMsg);
+    }
+
+    XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
+    XFREE(issuer,  0, DYNAMIC_TYPE_OPENSSL);
+}
+
+#endif /* KEEP_PEER_CERT || SESSION_CERTS */
+
+
+static INLINE void showPeer(WOLFSSL* ssl)
+{
+
+    WOLFSSL_CIPHER* cipher;
+#ifdef KEEP_PEER_CERT
+    WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
+    if (peer)
+        ShowX509(peer, "peer's cert info:");
+    else
+        printf("peer has no cert!\n");
+    wolfSSL_FreeX509(peer);
+#endif
+    printf("SSL version is %s\n", wolfSSL_get_version(ssl));
+
+    cipher = wolfSSL_get_current_cipher(ssl);
+    printf("SSL cipher suite is %s\n", wolfSSL_CIPHER_get_name(cipher));
+
+#if defined(SESSION_CERTS) && defined(SHOW_CERTS)
+    {
+        WOLFSSL_X509_CHAIN* chain = wolfSSL_get_peer_chain(ssl);
+        int                count = wolfSSL_get_chain_count(chain);
+        int i;
+
+        for (i = 0; i < count; i++) {
+            int length;
+            unsigned char buffer[3072];
+            WOLFSSL_X509* chainX509;
+
+            wolfSSL_get_chain_cert_pem(chain,i,buffer, sizeof(buffer), &length);
+            buffer[length] = 0;
+            printf("cert %d has length %d data = \n%s\n", i, length, buffer);
+
+            chainX509 = wolfSSL_get_chain_X509(chain, i);
+            if (chainX509)
+                ShowX509(chainX509, "session cert info:");
+            else
+                printf("get_chain_X509 failed\n");
+            wolfSSL_FreeX509(chainX509);
+        }
+    }
+#endif
+  (void)ssl;
+}
+
+
+static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
+                              word16 port, int udp)
+{
+    int useLookup = 0;
+    (void)useLookup;
+    (void)udp;
+
+    memset(addr, 0, sizeof(SOCKADDR_IN_T));
+
+#ifndef TEST_IPV6
+    /* peer could be in human readable form */
+    if ( (peer != INADDR_ANY) && isalpha((int)peer[0])) {
+        #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
+            int err;
+            struct hostent* entry = gethostbyname(peer, &err);
+        #elif defined(WOLFSSL_TIRTOS)
+            struct hostent* entry = DNSGetHostByName(peer);
+        #elif defined(WOLFSSL_VXWORKS)
+            struct hostent* entry = (struct hostent*)hostGetByName(peer);
+        #else
+            struct hostent* entry = gethostbyname(peer);
+        #endif
+
+        if (entry) {
+            memcpy(&addr->sin_addr.s_addr, entry->h_addr_list[0],
+                   entry->h_length);
+            useLookup = 1;
+        }
+        else
+            err_sys("no entry for host");
+    }
+#endif
+
+
+#ifndef TEST_IPV6
+    #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
+        addr->sin_family = PF_INET;
+    #else
+        addr->sin_family = AF_INET_V;
+    #endif
+    addr->sin_port = htons(port);
+    if (peer == INADDR_ANY)
+        addr->sin_addr.s_addr = IPADDR_ANY;
+    else {
+        if (!useLookup)
+            addr->sin_addr.s_addr = inet_addr(peer);
+    }
+#else
+    addr->sin6_family = AF_INET_V;
+    addr->sin6_port = htons(port);
+    if (peer == INADDR_ANY)
+        addr->sin6_addr = in6addr_any;
+    else {
+        #ifdef HAVE_GETADDRINFO
+            struct addrinfo  hints;
+            struct addrinfo* answer = NULL;
+            int    ret;
+            char   strPort[80];
+
+            memset(&hints, 0, sizeof(hints));
+
+            hints.ai_family   = AF_INET_V;
+            hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM;
+            hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP;
+
+            SNPRINTF(strPort, sizeof(strPort), "%d", port);
+            strPort[79] = '\0';
+
+            ret = getaddrinfo(peer, strPort, &hints, &answer);
+            if (ret < 0 || answer == NULL)
+                err_sys("getaddrinfo failed");
+
+            memcpy(addr, answer->ai_addr, answer->ai_addrlen);
+            freeaddrinfo(answer);
+        #else
+            printf("no ipv6 getaddrinfo, loopback only tests/examples\n");
+            addr->sin6_addr = in6addr_loopback;
+        #endif
+    }
+#endif
+}
+
+
+static INLINE void tcp_socket(SOCKET_T* sockfd, int udp)
+{
+    if (udp)
+        *sockfd = socket(AF_INET_V, SOCK_DGRAM, 0);
+    else
+        *sockfd = socket(AF_INET_V, SOCK_STREAM, 0);
+
+    if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) {
+        err_sys("socket failed\n");
+    }
+
+#ifndef USE_WINDOWS_API
+#ifdef SO_NOSIGPIPE
+    {
+        int       on = 1;
+        socklen_t len = sizeof(on);
+        int       res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len);
+        if (res < 0)
+            err_sys("setsockopt SO_NOSIGPIPE failed\n");
+    }
+#elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS) ||\
+                                          defined(WOLFSSL_KEIL_TCP_NET)
+    /* nothing to define */
+#else  /* no S_NOSIGPIPE */
+    //signal(SIGPIPE, SIG_IGN);
+#endif /* S_NOSIGPIPE */
+
+#if defined(TCP_NODELAY)
+    if (!udp)
+    {
+        int       on = 1;
+        socklen_t len = sizeof(on);
+        int       res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len);
+        if (res < 0)
+            err_sys("setsockopt TCP_NODELAY failed\n");
+    }
+#endif
+#endif  /* USE_WINDOWS_API */
+}
+
+static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
+                               int udp, WOLFSSL* ssl)
+{
+    SOCKADDR_IN_T addr;
+    build_addr(&addr, ip, port, udp);
+    if(udp) {
+        wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
+    }
+    tcp_socket(sockfd, udp);
+
+    if (!udp) {
+        if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
+            err_sys("tcp connect failed");
+    }
+}
+
+
+static INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz)
+{
+    if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0)
+        err_sys("tcp connect failed");
+}
+
+
+enum {
+    TEST_SELECT_FAIL,
+    TEST_TIMEOUT,
+    TEST_RECV_READY,
+    TEST_ERROR_READY
+};
+
+
+#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && \
+                                 !defined(WOLFSSL_TIRTOS)
+static INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
+{
+    fd_set recvfds, errfds;
+    SOCKET_T nfds = socketfd + 1;
+    struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0};
+    int result;
+
+    FD_ZERO(&recvfds);
+    FD_SET(socketfd, &recvfds);
+    FD_ZERO(&errfds);
+    FD_SET(socketfd, &errfds);
+
+    result = select(nfds, &recvfds, NULL, &errfds, &timeout);
+
+    if (result == 0)
+        return TEST_TIMEOUT;
+    else if (result > 0) {
+        if (FD_ISSET(socketfd, &recvfds))
+            return TEST_RECV_READY;
+        else if(FD_ISSET(socketfd, &errfds))
+            return TEST_ERROR_READY;
+    }
+
+    return TEST_SELECT_FAIL;
+}
+#elif defined(WOLFSSL_TIRTOS)
+static INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
+{
+    return TEST_RECV_READY;
+}
+#endif /* !WOLFSSL_MDK_ARM */
+
+
+static INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr,
+                              int udp)
+{
+    SOCKADDR_IN_T addr;
+
+    /* don't use INADDR_ANY by default, firewall may block, make user switch
+       on */
+    build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp);
+    tcp_socket(sockfd, udp);
+
+#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\
+                              && !defined(WOLFSSL_KEIL_TCP_NET)
+    {
+        int       res, on  = 1;
+        socklen_t len = sizeof(on);
+        res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
+        if (res < 0)
+            err_sys("setsockopt SO_REUSEADDR failed\n");
+    }
+#endif
+
+    if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
+        err_sys("tcp bind failed");
+    if (!udp) {
+        if (listen(*sockfd, 5) != 0)
+            err_sys("tcp listen failed");
+    }
+    #if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS)
+        if (*port == 0) {
+            socklen_t len = sizeof(addr);
+            if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
+                #ifndef TEST_IPV6
+                    *port = ntohs(addr.sin_port);
+                #else
+                    *port = ntohs(addr.sin6_port);
+                #endif
+            }
+        }
+    #endif
+}
+
+
+#if 0
+static INLINE int udp_read_connect(SOCKET_T sockfd)
+{
+    SOCKADDR_IN_T cliaddr;
+    byte          b[1500];
+    int           n;
+    socklen_t     len = sizeof(cliaddr);
+
+    n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
+                      (struct sockaddr*)&cliaddr, &len);
+    if (n > 0) {
+        if (connect(sockfd, (const struct sockaddr*)&cliaddr,
+                    sizeof(cliaddr)) != 0)
+            err_sys("udp connect failed");
+    }
+    else
+        err_sys("recvfrom failed");
+
+    return sockfd;
+}
+#endif
+
+static INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
+                              int useAnyAddr, word16 port, func_args* args)
+{
+    SOCKADDR_IN_T addr;
+
+    (void)args;
+    build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), port, 1);
+    tcp_socket(sockfd, 1);
+
+
+#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM) \
+                              && !defined(WOLFSSL_KEIL_TCP_NET)
+    {
+        int       res, on  = 1;
+        socklen_t len = sizeof(on);
+        res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
+        if (res < 0)
+            err_sys("setsockopt SO_REUSEADDR failed\n");
+    }
+#endif
+
+    if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
+        err_sys("tcp bind failed");
+
+    #if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS)
+        if (port == 0) {
+            socklen_t len = sizeof(addr);
+            if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
+                #ifndef TEST_IPV6
+                    port = ntohs(addr.sin_port);
+                #else
+                    port = ntohs(addr.sin6_port);
+                #endif
+            }
+        }
+    #endif
+
+#if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
+    /* signal ready to accept data */
+    {
+    tcp_ready* ready = args->signal;
+    pthread_mutex_lock(&ready->mutex);
+    ready->ready = 1;
+    ready->port = port;
+    pthread_cond_signal(&ready->cond);
+    pthread_mutex_unlock(&ready->mutex);
+    }
+#elif defined (WOLFSSL_TIRTOS)
+    /* Need mutex? */
+    tcp_ready* ready = args->signal;
+    ready->ready = 1;
+    ready->port = port;
+#endif
+
+    *clientfd = *sockfd;
+}
+
+static INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
+                              func_args* args, word16 port, int useAnyAddr,
+                              int udp, int ready_file, int do_listen)
+{
+    SOCKADDR_IN_T client;
+    socklen_t client_len = sizeof(client);
+
+    if (udp) {
+        udp_accept(sockfd, clientfd, useAnyAddr, port, args);
+        return;
+    }
+
+    if(do_listen) {
+        tcp_listen(sockfd, &port, useAnyAddr, udp);
+
+    #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
+        /* signal ready to tcp_accept */
+        {
+        tcp_ready* ready = args->signal;
+        pthread_mutex_lock(&ready->mutex);
+        ready->ready = 1;
+        ready->port = port;
+        pthread_cond_signal(&ready->cond);
+        pthread_mutex_unlock(&ready->mutex);
+        }
+    #elif defined (WOLFSSL_TIRTOS)
+        /* Need mutex? */
+        tcp_ready* ready = args->signal;
+        ready->ready = 1;
+        ready->port = port;
+    #endif
+
+        if (ready_file) {
+    #ifndef NO_FILESYSTEM
+        #ifndef USE_WINDOWS_API
+            FILE* srf = fopen("/tmp/wolfssl_server_ready", "w");
+        #else
+            FILE* srf = fopen("wolfssl_server_ready", "w");
+        #endif
+
+            if (srf) {
+                fputs("ready", srf);
+                fclose(srf);
+            }
+    #endif
+        }
+    }
+
+    *clientfd = accept(*sockfd, (struct sockaddr*)&client,
+                      (ACCEPT_THIRD_T)&client_len);
+    if(WOLFSSL_SOCKET_IS_INVALID(*clientfd)) {
+        err_sys("tcp accept failed");
+    }
+}
+
+
+static INLINE void tcp_set_nonblocking(SOCKET_T* sockfd)
+{
+    #ifdef USE_WINDOWS_API
+        unsigned long blocking = 1;
+        int ret = ioctlsocket(*sockfd, FIONBIO, &blocking);
+        if (ret == SOCKET_ERROR)
+            err_sys("ioctlsocket failed");
+    #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) \
+        || defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS)
+         /* non blocking not suppported, for now */
+    #else
+        int flags = fcntl(*sockfd, F_GETFL, 0);
+        if (flags < 0)
+            err_sys("fcntl get failed");
+        flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK);
+        if (flags < 0)
+            err_sys("fcntl set failed");
+    #endif
+}
+
+
+#ifndef NO_PSK
+
+static INLINE unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint,
+        char* identity, unsigned int id_max_len, unsigned char* key,
+        unsigned int key_max_len)
+{
+    (void)ssl;
+    (void)hint;
+    (void)key_max_len;
+
+    /* identity is OpenSSL testing default for openssl s_client, keep same */
+    strncpy(identity, "Client_identity", id_max_len);
+
+
+    /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
+       unsigned binary */
+    key[0] = 26;
+    key[1] = 43;
+    key[2] = 60;
+    key[3] = 77;
+
+    return 4;   /* length of key in octets or 0 for error */
+}
+
+
+static INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity,
+        unsigned char* key, unsigned int key_max_len)
+{
+    (void)ssl;
+    (void)key_max_len;
+
+    /* identity is OpenSSL testing default for openssl s_client, keep same */
+    if (strncmp(identity, "Client_identity", 15) != 0)
+        return 0;
+
+    /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
+       unsigned binary */
+    key[0] = 26;
+    key[1] = 43;
+    key[2] = 60;
+    key[3] = 77;
+
+    return 4;   /* length of key in octets or 0 for error */
+}
+
+#endif /* NO_PSK */
+
+
+#ifdef USE_WINDOWS_API
+
+    #define WIN32_LEAN_AND_MEAN
+    #include <windows.h>
+
+    static INLINE double current_time()
+    {
+        static int init = 0;
+        static LARGE_INTEGER freq;
+
+        LARGE_INTEGER count;
+
+        if (!init) {
+            QueryPerformanceFrequency(&freq);
+            init = 1;
+        }
+
+        QueryPerformanceCounter(&count);
+
+        return (double)count.QuadPart / freq.QuadPart;
+    }
+
+#elif defined(WOLFSSL_TIRTOS)
+    extern double current_time();
+#elif defined(WOLFSSL_uITRON4)
+    #include <kernel.h>
+    static INLINE double current_time()
+    {
+        SYSTIM time;
+        get_tim(&time);
+        return (double)time;
+    }
+#else
+
+#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET)
+    #include <sys/time.h>
+
+    static INLINE double current_time(void)
+    {
+        struct timeval tv;
+        gettimeofday(&tv, 0);
+
+        return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
+    }
+
+#endif
+#endif /* USE_WINDOWS_API */
+
+
+#if defined(NO_FILESYSTEM) && !defined(NO_CERTS)
+
+    enum {
+        WOLFSSL_CA   = 1,
+        WOLFSSL_CERT = 2,
+        WOLFSSL_KEY  = 3
+    };
+
+    static INLINE void load_buffer(WOLFSSL_CTX* ctx, const char* fname, int type)
+    {
+        /* test buffer load */
+        long  sz = 0;
+        byte  buff[10000];
+        FILE* file = fopen(fname, "rb");
+
+        if (!file)
+            err_sys("can't open file for buffer load "
+                    "Please run from wolfSSL home directory if not");
+        fseek(file, 0, SEEK_END);
+        sz = ftell(file);
+        rewind(file);
+        fread(buff, sizeof(buff), 1, file);
+
+        if (type == WOLFSSL_CA) {
+            if (wolfSSL_CTX_load_verify_buffer(ctx, buff, sz, SSL_FILETYPE_PEM)
+                                              != SSL_SUCCESS)
+                err_sys("can't load buffer ca file");
+        }
+        else if (type == WOLFSSL_CERT) {
+            if (wolfSSL_CTX_use_certificate_buffer(ctx, buff, sz,
+                        SSL_FILETYPE_PEM) != SSL_SUCCESS)
+                err_sys("can't load buffer cert file");
+        }
+        else if (type == WOLFSSL_KEY) {
+            if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, sz,
+                        SSL_FILETYPE_PEM) != SSL_SUCCESS)
+                err_sys("can't load buffer key file");
+        }
+        fclose(file);
+    }
+
+#endif /* NO_FILESYSTEM */
+
+#ifdef VERIFY_CALLBACK
+
+static INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store)
+{
+    (void)preverify;
+    char buffer[WOLFSSL_MAX_ERROR_SZ];
+
+#ifdef OPENSSL_EXTRA
+    WOLFSSL_X509* peer;
+#endif
+
+    printf("In verification callback, error = %d, %s\n", store->error,
+                                 wolfSSL_ERR_error_string(store->error, buffer));
+#ifdef OPENSSL_EXTRA
+    peer = store->current_cert;
+    if (peer) {
+        char* issuer  = wolfSSL_X509_NAME_oneline(
+                                       wolfSSL_X509_get_issuer_name(peer), 0, 0);
+        char* subject = wolfSSL_X509_NAME_oneline(
+                                      wolfSSL_X509_get_subject_name(peer), 0, 0);
+        printf("peer's cert info:\n issuer : %s\n subject: %s\n", issuer,
+                                                                  subject);
+        XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
+        XFREE(issuer,  0, DYNAMIC_TYPE_OPENSSL);
+    }
+    else
+        printf("peer has no cert!\n");
+#endif
+    printf("Subject's domain name is %s\n", store->domain);
+
+    printf("Allowing to continue anyway (shouldn't do this, EVER!!!)\n");
+    return 1;
+}
+
+#endif /* VERIFY_CALLBACK */
+
+
+static INLINE int myDateCb(int preverify, WOLFSSL_X509_STORE_CTX* store)
+{
+    char buffer[WOLFSSL_MAX_ERROR_SZ];
+    (void)preverify;
+
+    printf("In verification callback, error = %d, %s\n", store->error,
+                                 wolfSSL_ERR_error_string(store->error, buffer));
+    printf("Subject's domain name is %s\n", store->domain);
+
+    if (store->error == ASN_BEFORE_DATE_E || store->error == ASN_AFTER_DATE_E) {
+        printf("Overriding cert date error as example for bad clock testing\n");
+        return 1;
+    }
+    printf("Cert error is not date error, not overriding\n");
+
+    return 0;
+}
+
+
+#ifdef HAVE_CRL
+
+static INLINE void CRL_CallBack(const char* url)
+{
+    printf("CRL callback url = %s\n", url);
+}
+
+#endif
+
+#ifndef NO_DH
+static INLINE void SetDH(WOLFSSL* ssl)
+{
+    /* dh1024 p */
+    static unsigned char p[] =
+    {
+        0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
+        0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
+        0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
+        0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
+        0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
+        0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
+        0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
+        0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
+        0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
+        0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
+        0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
+    };
+
+    /* dh1024 g */
+    static unsigned char g[] =
+    {
+      0x02,
+    };
+
+    wolfSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g));
+}
+
+static INLINE void SetDHCtx(WOLFSSL_CTX* ctx)
+{
+    /* dh1024 p */
+    static unsigned char p[] =
+    {
+        0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
+        0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
+        0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
+        0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
+        0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
+        0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
+        0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
+        0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
+        0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
+        0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
+        0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
+    };
+
+    /* dh1024 g */
+    static unsigned char g[] =
+    {
+      0x02,
+    };
+
+    wolfSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g));
+}
+#endif /* NO_DH */
+
+#ifndef NO_CERTS
+
+static INLINE void CaCb(unsigned char* der, int sz, int type)
+{
+    (void)der;
+    printf("Got CA cache add callback, derSz = %d, type = %d\n", sz, type);
+}
+
+#endif /* !NO_CERTS */
+
+#ifdef HAVE_CAVIUM
+
+static INLINE int OpenNitroxDevice(int dma_mode,int dev_id)
+{
+   Csp1CoreAssignment core_assign;
+   Uint32             device;
+
+   if (CspInitialize(CAVIUM_DIRECT,CAVIUM_DEV_ID))
+      return -1;
+   if (Csp1GetDevType(&device))
+      return -1;
+   if (device != NPX_DEVICE) {
+      if (ioctl(gpkpdev_hdlr[CAVIUM_DEV_ID], IOCTL_CSP1_GET_CORE_ASSIGNMENT,
+                (Uint32 *)&core_assign)!= 0)
+         return -1;
+   }
+   CspShutdown(CAVIUM_DEV_ID);
+
+   return CspInitialize(dma_mode, dev_id);
+}
+
+#endif /* HAVE_CAVIUM */
+
+
+#ifdef USE_WINDOWS_API
+
+/* do back x number of directories */
+static INLINE void ChangeDirBack(int x)
+{
+    char path[MAX_PATH];
+    XMEMSET(path, 0, MAX_PATH);
+    XSTRNCAT(path, ".\\", MAX_PATH);
+    while (x-- > 0) {
+        XSTRNCAT(path, "..\\", MAX_PATH);
+    }
+    SetCurrentDirectoryA(path);
+}
+
+/* does current dir contain str */
+static INLINE int CurrentDir(const char* str)
+{
+    char  path[MAX_PATH];
+    char* baseName;
+
+    GetCurrentDirectoryA(sizeof(path), path);
+
+    baseName = strrchr(path, '\\');
+    if (baseName)
+        baseName++;
+    else
+        baseName = path;
+
+    if (strstr(baseName, str))
+        return 1;
+
+    return 0;
+}
+
+#elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_FS)
+    /* KEIL-RL File System does not support relative directry */
+#elif defined(WOLFSSL_TIRTOS)
+#else
+
+#ifndef MAX_PATH
+    #define MAX_PATH 256
+#endif
+
+/* do back x number of directories */
+static INLINE void ChangeDirBack(int x)
+{
+    char path[MAX_PATH];
+    XMEMSET(path, 0, MAX_PATH);
+    XSTRNCAT(path, "./", MAX_PATH);
+    while (x-- > 0) {
+        XSTRNCAT(path, "../", MAX_PATH);
+    }
+    //if (chdir(path) < 0) {
+    //    printf("chdir to %s failed\n", path);
+    //}
+}
+
+/* does current dir contain str */
+static INLINE int CurrentDir(const char* str)
+{
+    char  path[MAX_PATH];
+    char* baseName;
+
+    //if (getcwd(path, sizeof(path)) == NULL) {
+    //    printf("no current dir?\n");
+    //    return 0;
+    //}
+
+    baseName = strrchr(path, '/');
+    if (baseName)
+        baseName++;
+    else
+        baseName = path;
+
+    if (strstr(baseName, str))
+        return 1;
+
+    return 0;
+}
+
+#endif /* USE_WINDOWS_API */
+
+
+#ifdef USE_WOLFSSL_MEMORY
+
+    typedef struct memoryStats {
+        size_t totalAllocs;     /* number of allocations */
+        size_t totalBytes;      /* total number of bytes allocated */
+        size_t peakBytes;       /* concurrent max bytes */
+        size_t currentBytes;    /* total current bytes in use */
+    } memoryStats;
+
+    typedef struct memHint {
+        size_t thisSize;      /* size of this memory */
+        void*  thisMemory;    /* actual memory for user */
+    } memHint;
+
+    typedef struct memoryTrack {
+        union {
+            memHint hint;
+            byte    alignit[16];   /* make sure we have strong alignment */
+        } u;
+    } memoryTrack;
+
+    #if defined(WOLFSSL_TRACK_MEMORY)
+        #define DO_MEM_STATS
+        static memoryStats ourMemStats;
+    #endif
+
+    static INLINE void* TrackMalloc(size_t sz)
+    {
+        memoryTrack* mt;
+
+        if (sz == 0)
+            return NULL;
+
+        mt = (memoryTrack*)malloc(sizeof(memoryTrack) + sz);
+        if (mt == NULL)
+            return NULL;
+
+        mt->u.hint.thisSize   = sz;
+        mt->u.hint.thisMemory = (byte*)mt + sizeof(memoryTrack);
+
+#ifdef DO_MEM_STATS
+        ourMemStats.totalAllocs++;
+        ourMemStats.totalBytes   += sz;
+        ourMemStats.currentBytes += sz;
+        if (ourMemStats.currentBytes > ourMemStats.peakBytes)
+            ourMemStats.peakBytes = ourMemStats.currentBytes;
+#endif
+
+        return mt->u.hint.thisMemory;
+    }
+
+
+    static INLINE void TrackFree(void* ptr)
+    {
+        memoryTrack* mt;
+
+        if (ptr == NULL)
+            return;
+
+        mt = (memoryTrack*)ptr;
+        --mt;   /* same as minus sizeof(memoryTrack), removes header */
+
+#ifdef DO_MEM_STATS
+        ourMemStats.currentBytes -= mt->u.hint.thisSize;
+#endif
+
+        free(mt);
+    }
+
+
+    static INLINE void* TrackRealloc(void* ptr, size_t sz)
+    {
+        void* ret = TrackMalloc(sz);
+
+        if (ptr) {
+            /* if realloc is bigger, don't overread old ptr */
+            memoryTrack* mt = (memoryTrack*)ptr;
+            --mt;  /* same as minus sizeof(memoryTrack), removes header */
+
+            if (mt->u.hint.thisSize < sz)
+                sz = mt->u.hint.thisSize;
+        }
+
+        if (ret && ptr)
+            memcpy(ret, ptr, sz);
+
+        if (ret)
+            TrackFree(ptr);
+
+        return ret;
+    }
+
+    static INLINE void InitMemoryTracker(void)
+    {
+        if (wolfSSL_SetAllocators(TrackMalloc, TrackFree, TrackRealloc) != 0)
+            err_sys("wolfSSL SetAllocators failed for track memory");
+
+    #ifdef DO_MEM_STATS
+        ourMemStats.totalAllocs  = 0;
+        ourMemStats.totalBytes   = 0;
+        ourMemStats.peakBytes    = 0;
+        ourMemStats.currentBytes = 0;
+    #endif
+    }
+
+    static INLINE void ShowMemoryTracker(void)
+    {
+    #ifdef DO_MEM_STATS
+        printf("total   Allocs = %9lu\n",
+                                       (unsigned long)ourMemStats.totalAllocs);
+        printf("total   Bytes  = %9lu\n",
+                                       (unsigned long)ourMemStats.totalBytes);
+        printf("peak    Bytes  = %9lu\n",
+                                       (unsigned long)ourMemStats.peakBytes);
+        printf("current Bytes  = %9lu\n",
+                                       (unsigned long)ourMemStats.currentBytes);
+    #endif
+    }
+
+#endif /* USE_WOLFSSL_MEMORY */
+
+
+#ifdef HAVE_STACK_SIZE
+
+typedef THREAD_RETURN WOLFSSL_THREAD (*thread_func)(void* args);
+
+
+static INLINE void StackSizeCheck(func_args* args, thread_func tf)
+{
+    int            ret, i, used;
+    unsigned char* myStack;
+    int            stackSize = 1024*128;
+    pthread_attr_t myAttr;
+    pthread_t      threadId;
+
+#ifdef PTHREAD_STACK_MIN
+    if (stackSize < PTHREAD_STACK_MIN)
+        stackSize = PTHREAD_STACK_MIN;
+#endif
+
+    ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
+    if (ret != 0)
+        err_sys("posix_memalign failed\n");
+
+    memset(myStack, 0x01, stackSize);
+
+    ret = pthread_attr_init(&myAttr);
+    if (ret != 0)
+        err_sys("attr_init failed");
+
+    ret = pthread_attr_setstack(&myAttr, myStack, stackSize);
+    if (ret != 0)
+        err_sys("attr_setstackaddr failed");
+
+    ret = pthread_create(&threadId, &myAttr, tf, args);
+    if (ret != 0) {
+        perror("pthread_create failed");
+        exit(EXIT_FAILURE);
+    }
+
+    ret = pthread_join(threadId, NULL);
+    if (ret != 0)
+        err_sys("pthread_join failed");
+
+    for (i = 0; i < stackSize; i++) {
+        if (myStack[i] != 0x01) {
+            break;
+        }
+    }
+
+    used = stackSize - i;
+    printf("stack used = %d\n", used);
+}
+
+
+#endif /* HAVE_STACK_SIZE */
+
+
+#ifdef STACK_TRAP
+
+/* good settings
+   --enable-debug --disable-shared C_EXTRA_FLAGS="-DUSER_TIME -DTFM_TIMING_RESISTANT -DPOSITIVE_EXP_ONLY -DSTACK_TRAP"
+
+*/
+
+#ifdef HAVE_STACK_SIZE
+    /* client only for now, setrlimit will fail if pthread_create() called */
+    /* STACK_SIZE does pthread_create() on client */
+    #error "can't use STACK_TRAP with STACK_SIZE, setrlimit will fail"
+#endif /* HAVE_STACK_SIZE */
+
+static INLINE void StackTrap(void)
+{
+    struct rlimit  rl;
+    if (getrlimit(RLIMIT_STACK, &rl) != 0)
+        err_sys("getrlimit failed");
+    printf("rlim_cur = %llu\n", rl.rlim_cur);
+    rl.rlim_cur = 1024*21;  /* adjust trap size here */
+    if (setrlimit(RLIMIT_STACK, &rl) != 0) {
+        perror("setrlimit");
+        err_sys("setrlimit failed");
+    }
+}
+
+#else /* STACK_TRAP */
+
+static INLINE void StackTrap(void)
+{
+}
+
+#endif /* STACK_TRAP */
+
+
+#ifdef ATOMIC_USER
+
+/* Atomic Encrypt Context example */
+typedef struct AtomicEncCtx {
+    int  keySetup;           /* have we done key setup yet */
+    Aes  aes;                /* for aes example */
+} AtomicEncCtx;
+
+
+/* Atomic Decrypt Context example */
+typedef struct AtomicDecCtx {
+    int  keySetup;           /* have we done key setup yet */
+    Aes  aes;                /* for aes example */
+} AtomicDecCtx;
+
+
+static INLINE int myMacEncryptCb(WOLFSSL* ssl, unsigned char* macOut,
+       const unsigned char* macIn, unsigned int macInSz, int macContent,
+       int macVerify, unsigned char* encOut, const unsigned char* encIn,
+       unsigned int encSz, void* ctx)
+{
+    int  ret;
+    Hmac hmac;
+    byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
+    AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx;
+    const char* tlsStr = "TLS";
+
+    /* example supports (d)tls aes */
+    if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
+        printf("myMacEncryptCb not using AES\n");
+        return -1;
+    }
+
+    if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
+        printf("myMacEncryptCb not using (D)TLS\n");
+        return -1;
+    }
+
+    /* hmac, not needed if aead mode */
+    wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
+
+    ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
+               wolfSSL_GetMacSecret(ssl, macVerify), wolfSSL_GetHmacSize(ssl));
+    if (ret != 0)
+        return ret;
+    ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
+    if (ret != 0)
+        return ret;
+    ret = wc_HmacUpdate(&hmac, macIn, macInSz);
+    if (ret != 0)
+        return ret;
+    ret = wc_HmacFinal(&hmac, macOut);
+    if (ret != 0)
+        return ret;
+
+
+    /* encrypt setup on first time */
+    if (encCtx->keySetup == 0) {
+        int   keyLen = wolfSSL_GetKeySize(ssl);
+        const byte* key;
+        const byte* iv;
+
+        if (wolfSSL_GetSide(ssl) == WOLFSSL_CLIENT_END) {
+            key = wolfSSL_GetClientWriteKey(ssl);
+            iv  = wolfSSL_GetClientWriteIV(ssl);
+        }
+        else {
+            key = wolfSSL_GetServerWriteKey(ssl);
+            iv  = wolfSSL_GetServerWriteIV(ssl);
+        }
+
+        ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION);
+        if (ret != 0) {
+            printf("AesSetKey failed in myMacEncryptCb\n");
+            return ret;
+        }
+        encCtx->keySetup = 1;
+    }
+
+    /* encrypt */
+    return wc_AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz);
+}
+
+
+static INLINE int myDecryptVerifyCb(WOLFSSL* ssl,
+       unsigned char* decOut, const unsigned char* decIn,
+       unsigned int decSz, int macContent, int macVerify,
+       unsigned int* padSz, void* ctx)
+{
+    AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx;
+    int ret      = 0;
+    int macInSz  = 0;
+    int ivExtra  = 0;
+    int digestSz = wolfSSL_GetHmacSize(ssl);
+    unsigned int pad     = 0;
+    unsigned int padByte = 0;
+    Hmac hmac;
+    byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
+    byte verify[MAX_DIGEST_SIZE];
+    const char* tlsStr = "TLS";
+
+    /* example supports (d)tls aes */
+    if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
+        printf("myMacEncryptCb not using AES\n");
+        return -1;
+    }
+
+    if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
+        printf("myMacEncryptCb not using (D)TLS\n");
+        return -1;
+    }
+
+    /*decrypt */
+    if (decCtx->keySetup == 0) {
+        int   keyLen = wolfSSL_GetKeySize(ssl);
+        const byte* key;
+        const byte* iv;
+
+        /* decrypt is from other side (peer) */
+        if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
+            key = wolfSSL_GetClientWriteKey(ssl);
+            iv  = wolfSSL_GetClientWriteIV(ssl);
+        }
+        else {
+            key = wolfSSL_GetServerWriteKey(ssl);
+            iv  = wolfSSL_GetServerWriteIV(ssl);
+        }
+
+        ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION);
+        if (ret != 0) {
+            printf("AesSetKey failed in myDecryptVerifyCb\n");
+            return ret;
+        }
+        decCtx->keySetup = 1;
+    }
+
+    /* decrypt */
+    ret = wc_AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz);
+    if (ret != 0)
+        return ret;
+
+    if (wolfSSL_GetCipherType(ssl) == WOLFSSL_AEAD_TYPE) {
+        *padSz = wolfSSL_GetAeadMacSize(ssl);
+        return 0; /* hmac, not needed if aead mode */
+    }
+
+    if (wolfSSL_GetCipherType(ssl) == WOLFSSL_BLOCK_TYPE) {
+        pad     = *(decOut + decSz - 1);
+        padByte = 1;
+        if (wolfSSL_IsTLSv1_1(ssl))
+            ivExtra = wolfSSL_GetCipherBlockSize(ssl);
+    }
+
+    *padSz  = wolfSSL_GetHmacSize(ssl) + pad + padByte;
+    macInSz = decSz - ivExtra - digestSz - pad - padByte;
+
+    wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
+
+    ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
+               wolfSSL_GetMacSecret(ssl, macVerify), digestSz);
+    if (ret != 0)
+        return ret;
+    ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
+    if (ret != 0)
+        return ret;
+    ret = wc_HmacUpdate(&hmac, decOut + ivExtra, macInSz);
+    if (ret != 0)
+        return ret;
+    ret = wc_HmacFinal(&hmac, verify);
+    if (ret != 0)
+        return ret;
+
+    if (memcmp(verify, decOut + decSz - digestSz - pad - padByte,
+               digestSz) != 0) {
+        printf("myDecryptVerify verify failed\n");
+        return -1;
+    }
+
+    return ret;
+}
+
+
+static INLINE void SetupAtomicUser(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
+{
+    AtomicEncCtx* encCtx;
+    AtomicDecCtx* decCtx;
+
+    encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx));
+    if (encCtx == NULL)
+        err_sys("AtomicEncCtx malloc failed");
+    memset(encCtx, 0, sizeof(AtomicEncCtx));
+
+    decCtx = (AtomicDecCtx*)malloc(sizeof(AtomicDecCtx));
+    if (decCtx == NULL) {
+        free(encCtx);
+        err_sys("AtomicDecCtx malloc failed");
+    }
+    memset(decCtx, 0, sizeof(AtomicDecCtx));
+
+    wolfSSL_CTX_SetMacEncryptCb(ctx, myMacEncryptCb);
+    wolfSSL_SetMacEncryptCtx(ssl, encCtx);
+
+    wolfSSL_CTX_SetDecryptVerifyCb(ctx, myDecryptVerifyCb);
+    wolfSSL_SetDecryptVerifyCtx(ssl, decCtx);
+}
+
+
+static INLINE void FreeAtomicUser(WOLFSSL* ssl)
+{
+    AtomicEncCtx* encCtx = (AtomicEncCtx*)wolfSSL_GetMacEncryptCtx(ssl);
+    AtomicDecCtx* decCtx = (AtomicDecCtx*)wolfSSL_GetDecryptVerifyCtx(ssl);
+
+    free(decCtx);
+    free(encCtx);
+}
+
+#endif /* ATOMIC_USER */
+
+
+#ifdef HAVE_PK_CALLBACKS
+
+#ifdef HAVE_ECC
+
+static INLINE int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz,
+        byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
+{
+    WC_RNG  rng;
+    int     ret;
+    word32  idx = 0;
+    ecc_key myKey;
+
+    (void)ssl;
+    (void)ctx;
+
+    ret = wc_InitRng(&rng);
+    if (ret != 0)
+        return ret;
+
+    wc_ecc_init(&myKey);
+
+    ret = wc_EccPrivateKeyDecode(key, &idx, &myKey, keySz);
+    if (ret == 0)
+        ret = wc_ecc_sign_hash(in, inSz, out, outSz, &rng, &myKey);
+    wc_ecc_free(&myKey);
+    wc_FreeRng(&rng);
+
+    return ret;
+}
+
+
+static INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
+        const byte* hash, word32 hashSz, const byte* key, word32 keySz,
+        int* result, void* ctx)
+{
+    int     ret;
+    ecc_key myKey;
+
+    (void)ssl;
+    (void)ctx;
+
+    wc_ecc_init(&myKey);
+
+    ret = wc_ecc_import_x963(key, keySz, &myKey);
+    if (ret == 0)
+        ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, result, &myKey);
+    wc_ecc_free(&myKey);
+
+    return ret;
+}
+
+#endif /* HAVE_ECC */
+
+#ifndef NO_RSA
+
+static INLINE int myRsaSign(WOLFSSL* ssl, const byte* in, word32 inSz,
+        byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
+{
+    WC_RNG  rng;
+    int     ret;
+    word32  idx = 0;
+    RsaKey  myKey;
+
+    (void)ssl;
+    (void)ctx;
+
+    ret = wc_InitRng(&rng);
+    if (ret != 0)
+        return ret;
+
+    wc_InitRsaKey(&myKey, NULL);
+
+    ret = wc_RsaPrivateKeyDecode(key, &idx, &myKey, keySz);
+    if (ret == 0)
+        ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, &myKey, &rng);
+    if (ret > 0) {  /* save and convert to 0 success */
+        *outSz = ret;
+        ret = 0;
+    }
+    wc_FreeRsaKey(&myKey);
+    wc_FreeRng(&rng);
+
+    return ret;
+}
+
+
+static INLINE int myRsaVerify(WOLFSSL* ssl, byte* sig, word32 sigSz,
+        byte** out,
+        const byte* key, word32 keySz,
+        void* ctx)
+{
+    int     ret;
+    word32  idx = 0;
+    RsaKey  myKey;
+
+    (void)ssl;
+    (void)ctx;
+
+    wc_InitRsaKey(&myKey, NULL);
+
+    ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
+    if (ret == 0)
+        ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey);
+    wc_FreeRsaKey(&myKey);
+
+    return ret;
+}
+
+
+static INLINE int myRsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz,
+                           byte* out, word32* outSz, const byte* key,
+                           word32 keySz, void* ctx)
+{
+    int     ret;
+    word32  idx = 0;
+    RsaKey  myKey;
+    WC_RNG  rng;
+
+    (void)ssl;
+    (void)ctx;
+
+    ret = wc_InitRng(&rng);
+    if (ret != 0)
+        return ret;
+
+    wc_InitRsaKey(&myKey, NULL);
+
+    ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
+    if (ret == 0) {
+        ret = wc_RsaPublicEncrypt(in, inSz, out, *outSz, &myKey, &rng);
+        if (ret > 0) {
+            *outSz = ret;
+            ret = 0;  /* reset to success */
+        }
+    }
+    wc_FreeRsaKey(&myKey);
+    wc_FreeRng(&rng);
+
+    return ret;
+}
+
+static INLINE int myRsaDec(WOLFSSL* ssl, byte* in, word32 inSz,
+                           byte** out,
+                           const byte* key, word32 keySz, void* ctx)
+{
+    int     ret;
+    word32  idx = 0;
+    RsaKey  myKey;
+
+    (void)ssl;
+    (void)ctx;
+
+    wc_InitRsaKey(&myKey, NULL);
+
+    ret = wc_RsaPrivateKeyDecode(key, &idx, &myKey, keySz);
+    if (ret == 0) {
+        ret = wc_RsaPrivateDecryptInline(in, inSz, out, &myKey);
+    }
+    wc_FreeRsaKey(&myKey);
+
+    return ret;
+}
+
+#endif /* NO_RSA */
+
+static INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
+{
+    (void)ctx;
+    (void)ssl;
+
+    #ifdef HAVE_ECC
+        wolfSSL_CTX_SetEccSignCb(ctx, myEccSign);
+        wolfSSL_CTX_SetEccVerifyCb(ctx, myEccVerify);
+    #endif /* HAVE_ECC */
+    #ifndef NO_RSA
+        wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign);
+        wolfSSL_CTX_SetRsaVerifyCb(ctx, myRsaVerify);
+        wolfSSL_CTX_SetRsaEncCb(ctx, myRsaEnc);
+        wolfSSL_CTX_SetRsaDecCb(ctx, myRsaDec);
+    #endif /* NO_RSA */
+}
+
+#endif /* HAVE_PK_CALLBACKS */
+
+
+
+
+
+#if defined(__hpux__) || defined(__MINGW32__) || defined (WOLFSSL_TIRTOS) \
+                      || defined(_MSC_VER)
+
+/* HP/UX doesn't have strsep, needed by test/suites.c */
+static INLINE char* strsep(char **stringp, const char *delim)
+{
+    char* start;
+    char* end;
+
+    start = *stringp;
+    if (start == NULL)
+        return NULL;
+
+    if ((end = strpbrk(start, delim))) {
+        *end++ = '\0';
+        *stringp = end;
+    } else {
+        *stringp = NULL;
+    }
+
+    return start;
+}
+
+#endif /* __hpux__ and others */
+
+/* Create unique filename, len is length of tempfn name, assuming
+   len does not include null terminating character,
+   num is number of characters in tempfn name to randomize */
+static INLINE const char* mymktemp(char *tempfn, int len, int num)
+{
+    int x, size;
+    static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                   "abcdefghijklmnopqrstuvwxyz";
+    WC_RNG rng;
+    byte   out;
+
+    if (tempfn == NULL || len < 1 || num < 1 || len <= num) {
+        printf("Bad input\n");
+        return NULL;
+    }
+
+    size = len - 1;
+
+    if (wc_InitRng(&rng) != 0) {
+        printf("InitRng failed\n");
+        return NULL;
+    }
+
+    for (x = size; x > size - num; x--) {
+        if (wc_RNG_GenerateBlock(&rng,(byte*)&out, sizeof(out)) != 0) {
+            printf("RNG_GenerateBlock failed\n");
+            return NULL;
+        }
+        tempfn[x] = alphanum[out % (sizeof(alphanum) - 1)];
+    }
+    tempfn[len] = '\0';
+
+    wc_FreeRng(&rng);
+
+    return tempfn;
+}
+
+
+
+#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
+                                    defined(HAVE_POLY1305)
+
+    #include <wolfssl/wolfcrypt/chacha20_poly1305.h>
+
+    typedef struct key_ctx {
+        byte name[WOLFSSL_TICKET_NAME_SZ];     /* name for this context */
+        byte key[16];                          /* cipher key */
+    } key_ctx;
+
+    static key_ctx myKey_ctx;
+    static WC_RNG myKey_rng;
+
+    static INLINE int TicketInit(void)
+    {
+        int ret = wc_InitRng(&myKey_rng);
+        if (ret != 0) return ret;
+
+        ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.key, sizeof(myKey_ctx.key));
+        if (ret != 0) return ret;
+
+        ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.name,sizeof(myKey_ctx.name));
+        if (ret != 0) return ret;
+
+        return 0;
+    }
+
+    static INLINE void TicketCleanup(void)
+    {
+        wc_FreeRng(&myKey_rng);
+    }
+
+    static INLINE int myTicketEncCb(WOLFSSL* ssl,
+                             byte key_name[WOLFSSL_TICKET_NAME_SZ],
+                             byte iv[WOLFSSL_TICKET_IV_SZ],
+                             byte mac[WOLFSSL_TICKET_MAC_SZ],
+                             int enc, byte* ticket, int inLen, int* outLen,
+                             void* userCtx)
+    {
+        (void)ssl;
+        (void)userCtx;
+
+        int ret;
+        word16 sLen = htons(inLen);
+        byte aad[WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2];
+        int  aadSz = WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2;
+        byte* tmp = aad;
+
+        if (enc) {
+            XMEMCPY(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ);
+
+            ret = wc_RNG_GenerateBlock(&myKey_rng, iv, WOLFSSL_TICKET_IV_SZ);
+            if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
+
+            /* build aad from key name, iv, and length */
+            XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
+            tmp += WOLFSSL_TICKET_NAME_SZ;
+            XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
+            tmp += WOLFSSL_TICKET_IV_SZ;
+            XMEMCPY(tmp, &sLen, 2);
+
+            ret = wc_ChaCha20Poly1305_Encrypt(myKey_ctx.key, iv,
+                                              aad, aadSz,
+                                              ticket, inLen,
+                                              ticket,
+                                              mac);
+            if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
+            *outLen = inLen;  /* no padding in this mode */
+        } else {
+            /* decrypt */
+
+            /* see if we know this key */
+            if (XMEMCMP(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ) != 0){
+                printf("client presented unknown ticket key name ");
+                return WOLFSSL_TICKET_RET_FATAL;
+            }
+
+            /* build aad from key name, iv, and length */
+            XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
+            tmp += WOLFSSL_TICKET_NAME_SZ;
+            XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
+            tmp += WOLFSSL_TICKET_IV_SZ;
+            XMEMCPY(tmp, &sLen, 2);
+
+            ret = wc_ChaCha20Poly1305_Decrypt(myKey_ctx.key, iv,
+                                              aad, aadSz,
+                                              ticket, inLen,
+                                              mac,
+                                              ticket);
+            if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
+            *outLen = inLen;  /* no padding in this mode */
+        }
+
+        return WOLFSSL_TICKET_RET_OK;
+    }
+
+#endif  /* HAVE_SESSION_TICKET && CHACHA20 && POLY1305 */
+
+#endif /* wolfSSL_TEST_H */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/version.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/version.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/version.h	(revision 164)
@@ -0,0 +1,35 @@
+/* wolfssl_version.h.in
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LIBWOLFSSL_VERSION_STRING "3.7.0"
+#define LIBWOLFSSL_VERSION_HEX 0x03007000
+
+#ifdef __cplusplus
+}
+#endif
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/aes.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/aes.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/aes.h	(revision 164)
@@ -0,0 +1,193 @@
+/* aes.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_AES_H
+#define WOLF_CRYPT_AES_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifndef NO_AES
+
+/* included for fips @wc_fips */
+#ifdef HAVE_FIPS
+#include <cyassl/ctaocrypt/aes.h>
+#if defined(CYASSL_AES_COUNTER) && !defined(WOLFSSL_AES_COUNTER)
+    #define WOLFSSL_AES_COUNTER
+#endif
+#if !defined(WOLFSSL_AES_DIRECT) && defined(CYASSL_AES_DIRECT)
+    #define WOLFSSL_AES_DIRECT
+#endif
+#endif
+
+#ifndef HAVE_FIPS /* to avoid redefinition of macros */
+#ifdef HAVE_CAVIUM
+    #include <wolfssl/ctaocrypt/logging.h>
+    #include "cavium_common.h"
+#endif
+
+#ifdef WOLFSSL_AESNI
+
+#include <wmmintrin.h>
+
+#if !defined (ALIGN16)
+    #if defined (__GNUC__)
+        #define ALIGN16 __attribute__ ( (aligned (16)))
+    #elif defined(_MSC_VER)
+        /* disable align warning, we want alignment ! */
+        #pragma warning(disable: 4324)
+        #define ALIGN16 __declspec (align (16))
+    #else
+        #define ALIGN16
+    #endif
+#endif
+
+#endif /* WOLFSSL_AESNI */
+
+#if !defined (ALIGN16)
+    #define ALIGN16
+#endif
+#endif /* HAVE_FIPS */
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#ifndef HAVE_FIPS /* to avoid redefinition of structures */
+#define WOLFSSL_AES_CAVIUM_MAGIC 0xBEEF0002
+
+enum {
+    AES_ENC_TYPE   = 1,   /* cipher unique type */
+    AES_ENCRYPTION = 0,
+    AES_DECRYPTION = 1,
+    AES_BLOCK_SIZE = 16
+};
+
+
+typedef struct Aes {
+    /* AESNI needs key first, rounds 2nd, not sure why yet */
+    ALIGN16 word32 key[60];
+    word32  rounds;
+
+    ALIGN16 word32 reg[AES_BLOCK_SIZE / sizeof(word32)];      /* for CBC mode */
+    ALIGN16 word32 tmp[AES_BLOCK_SIZE / sizeof(word32)];      /* same         */
+
+#ifdef HAVE_AESGCM
+    ALIGN16 byte H[AES_BLOCK_SIZE];
+#ifdef GCM_TABLE
+    /* key-based fast multiplication table. */
+    ALIGN16 byte M0[256][AES_BLOCK_SIZE];
+#endif /* GCM_TABLE */
+#endif /* HAVE_AESGCM */
+#ifdef WOLFSSL_AESNI
+    byte use_aesni;
+#endif /* WOLFSSL_AESNI */
+#ifdef HAVE_CAVIUM
+    AesType type;            /* aes key type */
+    int     devId;           /* nitrox device id */
+    word32  magic;           /* using cavium magic */
+    word64  contextHandle;   /* nitrox context memory handle */
+#endif
+#ifdef WOLFSSL_AES_COUNTER
+    word32  left;            /* unsued bytes left from last call */
+#endif
+#ifdef WOLFSSL_PIC32MZ_CRYPT
+    word32 key_ce[AES_BLOCK_SIZE*2/sizeof(word32)] ;
+    word32 iv_ce [AES_BLOCK_SIZE  /sizeof(word32)] ;
+    int    keylen ;
+#endif
+#ifdef WOLFSSL_TI_CRYPT
+    int    keylen ;
+#endif
+} Aes;
+
+
+#ifdef HAVE_AESGCM
+typedef struct Gmac {
+    Aes aes;
+} Gmac;
+#endif /* HAVE_AESGCM */
+#endif /* HAVE_FIPS */
+
+WOLFSSL_API int  wc_AesSetKey(Aes* aes, const byte* key, word32 len,
+                              const byte* iv, int dir);
+WOLFSSL_API int  wc_AesSetIV(Aes* aes, const byte* iv);
+WOLFSSL_API int  wc_AesCbcEncrypt(Aes* aes, byte* out,
+                                  const byte* in, word32 sz);
+WOLFSSL_API int  wc_AesCbcDecrypt(Aes* aes, byte* out,
+                                  const byte* in, word32 sz);
+
+/* AES-CTR */
+#ifdef WOLFSSL_AES_COUNTER
+ WOLFSSL_API void wc_AesCtrEncrypt(Aes* aes, byte* out,
+                                   const byte* in, word32 sz);
+#endif
+/* AES-DIRECT */
+#if defined(WOLFSSL_AES_DIRECT)
+ WOLFSSL_API void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in);
+ WOLFSSL_API void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in);
+ WOLFSSL_API int  wc_AesSetKeyDirect(Aes* aes, const byte* key, word32 len,
+                                const byte* iv, int dir);
+#endif
+#ifdef HAVE_AESGCM
+ WOLFSSL_API int  wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len);
+ WOLFSSL_API int  wc_AesGcmEncrypt(Aes* aes, byte* out,
+                                   const byte* in, word32 sz,
+                                   const byte* iv, word32 ivSz,
+                                   byte* authTag, word32 authTagSz,
+                                   const byte* authIn, word32 authInSz);
+ WOLFSSL_API int  wc_AesGcmDecrypt(Aes* aes, byte* out,
+                                   const byte* in, word32 sz,
+                                   const byte* iv, word32 ivSz,
+                                   const byte* authTag, word32 authTagSz,
+                                   const byte* authIn, word32 authInSz);
+
+ WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len);
+ WOLFSSL_API int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
+                               const byte* authIn, word32 authInSz,
+                               byte* authTag, word32 authTagSz);
+#endif /* HAVE_AESGCM */
+#ifdef HAVE_AESCCM
+ WOLFSSL_API void wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz);
+ WOLFSSL_API int  wc_AesCcmEncrypt(Aes* aes, byte* out,
+                                   const byte* in, word32 inSz,
+                                   const byte* nonce, word32 nonceSz,
+                                   byte* authTag, word32 authTagSz,
+                                   const byte* authIn, word32 authInSz);
+ WOLFSSL_API int  wc_AesCcmDecrypt(Aes* aes, byte* out,
+                                   const byte* in, word32 inSz,
+                                   const byte* nonce, word32 nonceSz,
+                                   const byte* authTag, word32 authTagSz,
+                                   const byte* authIn, word32 authInSz);
+#endif /* HAVE_AESCCM */
+
+#ifdef HAVE_CAVIUM
+     WOLFSSL_API int  wc_AesInitCavium(Aes*, int);
+     WOLFSSL_API void wc_AesFreeCavium(Aes*);
+#endif
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+
+#endif /* NO_AES */
+#endif /* WOLF_CRYPT_AES_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/arc4.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/arc4.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/arc4.h	(revision 164)
@@ -0,0 +1,65 @@
+/* arc4.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef WOLF_CRYPT_ARC4_H
+#define WOLF_CRYPT_ARC4_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#define WOLFSSL_ARC4_CAVIUM_MAGIC 0xBEEF0001
+
+enum {
+	ARC4_ENC_TYPE   = 4,    /* cipher unique type */
+    ARC4_STATE_SIZE = 256
+};
+
+/* ARC4 encryption and decryption */
+typedef struct Arc4 {
+    byte x;
+    byte y;
+    byte state[ARC4_STATE_SIZE];
+#ifdef HAVE_CAVIUM
+    int    devId;           /* nitrox device id */
+    word32 magic;           /* using cavium magic */
+    word64 contextHandle;   /* nitrox context memory handle */
+#endif
+} Arc4;
+
+WOLFSSL_API void wc_Arc4Process(Arc4*, byte*, const byte*, word32);
+WOLFSSL_API void wc_Arc4SetKey(Arc4*, const byte*, word32);
+
+#ifdef HAVE_CAVIUM
+    WOLFSSL_API int  wc_Arc4InitCavium(Arc4*, int);
+    WOLFSSL_API void wc_Arc4FreeCavium(Arc4*);
+#endif
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+
+#endif /* WOLF_CRYPT_ARC4_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/asn.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/asn.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/asn.h	(revision 164)
@@ -0,0 +1,782 @@
+/* asn.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_ASN_H
+#define WOLF_CRYPT_ASN_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifndef NO_ASN
+
+#include <wolfssl/wolfcrypt/integer.h>
+#ifndef NO_RSA
+    #include <wolfssl/wolfcrypt/rsa.h>
+#endif
+
+/* fips declare of RsaPrivateKeyDecode @wc_fips */
+#if defined(HAVE_FIPS) && !defined(NO_RSA)
+    #include <cyassl/ctaocrypt/rsa.h>
+#endif
+
+#ifndef NO_DH
+    #include <wolfssl/wolfcrypt/dh.h>
+#endif
+#ifndef NO_DSA
+    #include <wolfssl/wolfcrypt/dsa.h>
+#endif
+#ifndef NO_SHA
+    #include <wolfssl/wolfcrypt/sha.h>
+#endif
+#ifndef NO_MD5
+    #include <wolfssl/wolfcrypt/md5.h>
+#endif
+#include <wolfssl/wolfcrypt/sha256.h>
+#include <wolfssl/wolfcrypt/asn_public.h>   /* public interface */
+#ifdef HAVE_ECC
+    #include <wolfssl/wolfcrypt/ecc.h>
+#endif
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+enum {
+    ISSUER  = 0,
+    SUBJECT = 1,
+
+    EXTERNAL_SERIAL_SIZE = 32,
+
+    BEFORE  = 0,
+    AFTER   = 1
+};
+
+/* ASN Tags   */
+enum ASN_Tags {
+    ASN_BOOLEAN           = 0x01,
+    ASN_INTEGER           = 0x02,
+    ASN_BIT_STRING        = 0x03,
+    ASN_OCTET_STRING      = 0x04,
+    ASN_TAG_NULL          = 0x05,
+    ASN_OBJECT_ID         = 0x06,
+    ASN_ENUMERATED        = 0x0a,
+    ASN_UTF8STRING        = 0x0c,
+    ASN_SEQUENCE          = 0x10,
+    ASN_SET               = 0x11,
+    ASN_UTC_TIME          = 0x17,
+    ASN_OTHER_TYPE        = 0x00,
+    ASN_RFC822_TYPE       = 0x01,
+    ASN_DNS_TYPE          = 0x02,
+    ASN_DIR_TYPE          = 0x04,
+    ASN_GENERALIZED_TIME  = 0x18,
+    CRL_EXTENSIONS        = 0xa0,
+    ASN_EXTENSIONS        = 0xa3,
+    ASN_LONG_LENGTH       = 0x80
+};
+
+enum  ASN_Flags{
+    ASN_CONSTRUCTED       = 0x20,
+    ASN_CONTEXT_SPECIFIC  = 0x80
+};
+
+enum DN_Tags {
+    ASN_COMMON_NAME   = 0x03,   /* CN */
+    ASN_SUR_NAME      = 0x04,   /* SN */
+    ASN_SERIAL_NUMBER = 0x05,   /* serialNumber */
+    ASN_COUNTRY_NAME  = 0x06,   /* C  */
+    ASN_LOCALITY_NAME = 0x07,   /* L  */
+    ASN_STATE_NAME    = 0x08,   /* ST */
+    ASN_ORG_NAME      = 0x0a,   /* O  */
+    ASN_ORGUNIT_NAME  = 0x0b    /* OU */
+};
+
+enum PBES {
+    PBE_MD5_DES      = 0,
+    PBE_SHA1_DES     = 1,
+    PBE_SHA1_DES3    = 2,
+    PBE_SHA1_RC4_128 = 3,
+    PBES2            = 13       /* algo ID */
+};
+
+enum ENCRYPTION_TYPES {
+    DES_TYPE  = 0,
+    DES3_TYPE = 1,
+    RC4_TYPE  = 2
+};
+
+enum ECC_TYPES {
+    ECC_PREFIX_0 = 160,
+    ECC_PREFIX_1 = 161
+};
+
+enum Misc_ASN {
+    ASN_NAME_MAX        = 256,
+    MAX_SALT_SIZE       =  64,     /* MAX PKCS Salt length */
+    MAX_IV_SIZE         =  64,     /* MAX PKCS Iv length */
+    MAX_KEY_SIZE        =  64,     /* MAX PKCS Key  length */
+    PKCS5               =   5,     /* PKCS oid tag */
+    PKCS5v2             =   6,     /* PKCS #5 v2.0 */
+    PKCS12              =  12,     /* PKCS #12 */
+    MAX_UNICODE_SZ      = 256,
+    ASN_BOOL_SIZE       =   2,     /* including type */
+    ASN_ECC_HEADER_SZ   =   2,     /* String type + 1 byte len */
+    ASN_ECC_CONTEXT_SZ  =   2,     /* Content specific type + 1 byte len */
+#ifdef NO_SHA
+    KEYID_SIZE          = SHA256_DIGEST_SIZE,
+#else
+    KEYID_SIZE          = SHA_DIGEST_SIZE,
+#endif
+    RSA_INTS            =   8,     /* RSA ints in private key */
+    DSA_INTS            =   5,     /* DSA ints in private key */
+    MIN_DATE_SIZE       =  13,
+    MAX_DATE_SIZE       =  32,
+    ASN_GEN_TIME_SZ     =  15,     /* 7 numbers * 2 + Zulu tag */
+    MAX_ENCODED_SIG_SZ  = 512,
+    MAX_SIG_SZ          = 256,
+    MAX_ALGO_SZ         =  20,
+    MAX_SEQ_SZ          =   5,     /* enum(seq | con) + length(4) */
+    MAX_SET_SZ          =   5,     /* enum(set | con) + length(4) */
+    MAX_OCTET_STR_SZ    =   5,     /* enum(set | con) + length(4) */
+    MAX_EXP_SZ          =   5,     /* enum(contextspec|con|exp) + length(4) */
+    MAX_PRSTR_SZ        =   5,     /* enum(prstr) + length(4) */
+    MAX_VERSION_SZ      =   5,     /* enum + id + version(byte) + (header(2))*/
+    MAX_ENCODED_DIG_SZ  =  73,     /* sha512 + enum(bit or octet) + legnth(4) */
+    MAX_RSA_INT_SZ      = 517,     /* RSA raw sz 4096 for bits + tag + len(4) */
+    MAX_NTRU_KEY_SZ     = 610,     /* NTRU 112 bit public key */
+    MAX_NTRU_ENC_SZ     = 628,     /* NTRU 112 bit DER public encoding */
+    MAX_LENGTH_SZ       =   4,     /* Max length size for DER encoding */
+    MAX_RSA_E_SZ        =  16,     /* Max RSA public e size */
+    MAX_CA_SZ           =  32,     /* Max encoded CA basic constraint length */
+    MAX_SN_SZ           =  35,     /* Max encoded serial number (INT) length */
+#ifdef WOLFSSL_CERT_GEN
+    #ifdef WOLFSSL_CERT_REQ
+                          /* Max encoded cert req attributes length */
+        MAX_ATTRIB_SZ   = MAX_SEQ_SZ * 3 + (11 + MAX_SEQ_SZ) * 2 +
+                          MAX_PRSTR_SZ + CTC_NAME_SIZE, /* 11 is the OID size */
+    #endif
+    #if defined(WOLFSSL_ALT_NAMES) || defined(WOLFSSL_CERT_EXT)
+        MAX_EXTENSIONS_SZ   = 1 + MAX_LENGTH_SZ + CTC_MAX_ALT_SIZE,
+    #else
+        MAX_EXTENSIONS_SZ   = 1 + MAX_LENGTH_SZ + MAX_CA_SZ,
+    #endif
+                                   /* Max total extensions, id + len + others */
+#endif
+#ifdef WOLFSSL_CERT_EXT
+    MAX_KID_SZ			= 45,	   /* Max encoded KID length (SHA-256 case) */
+    MAX_KEYUSAGE_SZ     = 18,      /* Max encoded Key Usage length */
+    MAX_OID_SZ          = 32,      /* Max DER length of OID*/
+    MAX_OID_STRING_SZ   = 64,      /* Max string length representation of OID*/
+    MAX_CERTPOL_NB      = CTC_MAX_CERTPOL_NB,/* Max number of Cert Policy */
+    MAX_CERTPOL_SZ      = CTC_MAX_CERTPOL_SZ,
+#endif
+    MAX_OCSP_EXT_SZ     = 58,      /* Max OCSP Extension length */
+    MAX_OCSP_NONCE_SZ   = 18,      /* OCSP Nonce size           */
+    EIGHTK_BUF          = 8192,    /* Tmp buffer size           */
+    MAX_PUBLIC_KEY_SZ   = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2,
+                                   /* use bigger NTRU size */
+    HEADER_ENCRYPTED_KEY_SIZE = 88 /* Extra header size for encrypted key */
+};
+
+
+enum Oid_Types {
+    hashType  = 0,
+    sigType   = 1,
+    keyType   = 2,
+    curveType = 3,
+    blkType   = 4
+};
+
+
+enum Hash_Sum  {
+    MD2h    = 646,
+    MD5h    = 649,
+    SHAh    =  88,
+    SHA256h = 414,
+    SHA384h = 415,
+    SHA512h = 416
+};
+
+
+enum Block_Sum {
+    DESb  = 69,
+    DES3b = 652
+};
+
+
+enum Key_Sum {
+    DSAk   = 515,
+    RSAk   = 645,
+    NTRUk  = 274,
+    ECDSAk = 518
+};
+
+
+enum Ecc_Sum {
+    ECC_256R1 = 526,
+    ECC_384R1 = 210,
+    ECC_521R1 = 211,
+    ECC_160R1 = 184,
+    ECC_192R1 = 520,
+    ECC_224R1 = 209
+};
+
+
+enum KDF_Sum {
+    PBKDF2_OID = 660
+};
+
+
+enum Extensions_Sum {
+    BASIC_CA_OID    = 133,
+    ALT_NAMES_OID   = 131,
+    CRL_DIST_OID    = 145,
+    AUTH_INFO_OID   = 69,
+    CA_ISSUER_OID   = 117,
+    AUTH_KEY_OID    = 149,
+    SUBJ_KEY_OID    = 128,
+    CERT_POLICY_OID = 146,
+    KEY_USAGE_OID   = 129,  /* 2.5.29.15 */
+    INHIBIT_ANY_OID = 168,  /* 2.5.29.54 */
+    EXT_KEY_USAGE_OID = 151, /* 2.5.29.37 */
+    NAME_CONS_OID   = 144   /* 2.5.29.30 */
+};
+
+enum CertificatePolicy_Sum {
+    CP_ANY_OID      = 146  /* id-ce 32 0 */
+};
+
+enum SepHardwareName_Sum {
+    HW_NAME_OID     = 79   /* 1.3.6.1.5.5.7.8.4 from RFC 4108*/
+};
+
+enum AuthInfo_Sum {
+    AIA_OCSP_OID      = 116, /* 1.3.6.1.5.5.7.48.1 */
+    AIA_CA_ISSUER_OID = 117  /* 1.3.6.1.5.5.7.48.2 */
+};
+
+enum ExtKeyUsage_Sum { /* From RFC 5280 */
+    EKU_ANY_OID         = 151, /* 2.5.29.37.0, anyExtendedKeyUsage         */
+    EKU_SERVER_AUTH_OID = 71,  /* 1.3.6.1.5.5.7.3.1, id-kp-serverAuth      */
+    EKU_CLIENT_AUTH_OID = 72,  /* 1.3.6.1.5.5.7.3.2, id-kp-clientAuth      */
+    EKU_OCSP_SIGN_OID   = 79   /* 1.3.6.1.5.5.7.3.9, OCSPSigning           */
+};
+
+
+enum VerifyType {
+    NO_VERIFY = 0,
+    VERIFY    = 1
+};
+
+#ifdef WOLFSSL_CERT_EXT
+enum KeyIdType {
+    SKID_TYPE = 0,
+    AKID_TYPE = 1
+};
+#endif
+
+/* Key usage extension bits */
+#define KEYUSE_DIGITAL_SIG    0x0080
+#define KEYUSE_CONTENT_COMMIT 0x0040
+#define KEYUSE_KEY_ENCIPHER   0x0020
+#define KEYUSE_DATA_ENCIPHER  0x0010
+#define KEYUSE_KEY_AGREE      0x0008
+#define KEYUSE_KEY_CERT_SIGN  0x0004
+#define KEYUSE_CRL_SIGN       0x0002
+#define KEYUSE_ENCIPHER_ONLY  0x0001
+#define KEYUSE_DECIPHER_ONLY  0x8000
+
+#define EXTKEYUSE_ANY         0x08
+#define EXTKEYUSE_OCSP_SIGN   0x04
+#define EXTKEYUSE_CLIENT_AUTH 0x02
+#define EXTKEYUSE_SERVER_AUTH 0x01
+
+typedef struct DNS_entry   DNS_entry;
+
+struct DNS_entry {
+    DNS_entry* next;   /* next on DNS list */
+    char*      name;   /* actual DNS name */
+};
+
+
+typedef struct Base_entry  Base_entry;
+
+struct Base_entry {
+    Base_entry* next;   /* next on name base list */
+    char*       name;   /* actual name base */
+    int         nameSz; /* name length */
+    byte        type;   /* Name base type (DNS or RFC822) */
+};
+
+
+struct DecodedName {
+    char*   fullName;
+    int     fullNameLen;
+    int     entryCount;
+    int     cnIdx;
+    int     cnLen;
+    int     snIdx;
+    int     snLen;
+    int     cIdx;
+    int     cLen;
+    int     lIdx;
+    int     lLen;
+    int     stIdx;
+    int     stLen;
+    int     oIdx;
+    int     oLen;
+    int     ouIdx;
+    int     ouLen;
+    int     emailIdx;
+    int     emailLen;
+    int     uidIdx;
+    int     uidLen;
+    int     serialIdx;
+    int     serialLen;
+};
+
+
+typedef struct DecodedCert DecodedCert;
+typedef struct DecodedName DecodedName;
+typedef struct Signer      Signer;
+
+
+struct DecodedCert {
+    byte*   publicKey;
+    word32  pubKeySize;
+    int     pubKeyStored;
+    word32  certBegin;               /* offset to start of cert          */
+    word32  sigIndex;                /* offset to start of signature     */
+    word32  sigLength;               /* length of signature              */
+    word32  signatureOID;            /* sum of algorithm object id       */
+    word32  keyOID;                  /* sum of key algo  object id       */
+    int     version;                 /* cert version, 1 or 3             */
+    DNS_entry* altNames;             /* alt names list of dns entries    */
+#ifndef IGNORE_NAME_CONSTRAINTS
+    DNS_entry* altEmailNames;        /* alt names list of RFC822 entries */
+    Base_entry* permittedNames;      /* Permitted name bases             */
+    Base_entry* excludedNames;       /* Excluded name bases              */
+#endif /* IGNORE_NAME_CONSTRAINTS */
+    byte    subjectHash[KEYID_SIZE]; /* hash of all Names                */
+    byte    issuerHash[KEYID_SIZE];  /* hash of all Names                */
+#ifdef HAVE_OCSP
+    byte    issuerKeyHash[KEYID_SIZE]; /* hash of the public Key         */
+#endif /* HAVE_OCSP */
+    byte*   signature;               /* not owned, points into raw cert  */
+    char*   subjectCN;               /* CommonName                       */
+    int     subjectCNLen;            /* CommonName Length                */
+    char    subjectCNEnc;            /* CommonName Encoding              */
+    int     subjectCNStored;         /* have we saved a copy we own      */
+    char    issuer[ASN_NAME_MAX];    /* full name including common name  */
+    char    subject[ASN_NAME_MAX];   /* full name including common name  */
+    int     verify;                  /* Default to yes, but could be off */
+    byte*   source;                  /* byte buffer holder cert, NOT owner */
+    word32  srcIdx;                  /* current offset into buffer       */
+    word32  maxIdx;                  /* max offset based on init size    */
+    void*   heap;                    /* for user memory overrides        */
+    byte    serial[EXTERNAL_SERIAL_SIZE];  /* raw serial number          */
+    int     serialSz;                /* raw serial bytes stored */
+    byte*   extensions;              /* not owned, points into raw cert  */
+    int     extensionsSz;            /* length of cert extensions */
+    word32  extensionsIdx;           /* if want to go back and parse later */
+    byte*   extAuthInfo;             /* Authority Information Access URI */
+    int     extAuthInfoSz;           /* length of the URI                */
+    byte*   extCrlInfo;              /* CRL Distribution Points          */
+    int     extCrlInfoSz;            /* length of the URI                */
+    byte    extSubjKeyId[KEYID_SIZE]; /* Subject Key ID                  */
+    byte    extSubjKeyIdSet;         /* Set when the SKID was read from cert */
+    byte    extAuthKeyId[KEYID_SIZE]; /* Authority Key ID                */
+    byte    extAuthKeyIdSet;         /* Set when the AKID was read from cert */
+#ifndef IGNORE_NAME_CONSTRAINTS
+    byte    extNameConstraintSet;
+#endif /* IGNORE_NAME_CONSTRAINTS */
+    byte    isCA;                    /* CA basic constraint true         */
+    byte    weOwnAltNames;           /* altNames haven't been given to copy */
+    byte    extKeyUsageSet;
+    word16  extKeyUsage;             /* Key usage bitfield               */
+    byte    extExtKeyUsageSet;       /* Extended Key Usage               */
+    byte    extExtKeyUsage;          /* Extended Key usage bitfield      */
+#ifdef OPENSSL_EXTRA
+    byte    extBasicConstSet;
+    byte    extBasicConstCrit;
+    byte    extBasicConstPlSet;
+    word32  pathLength;              /* CA basic constraint path length, opt */
+    byte    extSubjAltNameSet;
+    byte    extSubjAltNameCrit;
+    byte    extAuthKeyIdCrit;
+#ifndef IGNORE_NAME_CONSTRAINTS
+    byte    extNameConstraintCrit;
+#endif /* IGNORE_NAME_CONSTRAINTS */
+    byte    extSubjKeyIdCrit;
+    byte    extKeyUsageCrit;
+    byte    extExtKeyUsageCrit;
+    byte*   extExtKeyUsageSrc;
+    word32  extExtKeyUsageSz;
+    word32  extExtKeyUsageCount;
+    byte*   extAuthKeyIdSrc;
+    word32  extAuthKeyIdSz;
+    byte*   extSubjKeyIdSrc;
+    word32  extSubjKeyIdSz;
+#endif
+#ifdef HAVE_ECC
+    word32  pkCurveOID;           /* Public Key's curve OID */
+#endif /* HAVE_ECC */
+    byte*   beforeDate;
+    int     beforeDateLen;
+    byte*   afterDate;
+    int     afterDateLen;
+#ifdef HAVE_PKCS7
+    byte*   issuerRaw;               /* pointer to issuer inside source */
+    int     issuerRawLen;
+#endif
+#ifndef IGNORE_NAME_CONSTRAINT
+    byte*   subjectRaw;               /* pointer to subject inside source */
+    int     subjectRawLen;
+#endif
+#if defined(WOLFSSL_CERT_GEN)
+    /* easy access to subject info for other sign */
+    char*   subjectSN;
+    int     subjectSNLen;
+    char    subjectSNEnc;
+    char*   subjectC;
+    int     subjectCLen;
+    char    subjectCEnc;
+    char*   subjectL;
+    int     subjectLLen;
+    char    subjectLEnc;
+    char*   subjectST;
+    int     subjectSTLen;
+    char    subjectSTEnc;
+    char*   subjectO;
+    int     subjectOLen;
+    char    subjectOEnc;
+    char*   subjectOU;
+    int     subjectOULen;
+    char    subjectOUEnc;
+    char*   subjectEmail;
+    int     subjectEmailLen;
+#endif /* WOLFSSL_CERT_GEN */
+#ifdef OPENSSL_EXTRA
+    DecodedName issuerName;
+    DecodedName subjectName;
+#endif /* OPENSSL_EXTRA */
+#ifdef WOLFSSL_SEP
+    int     deviceTypeSz;
+    byte*   deviceType;
+    int     hwTypeSz;
+    byte*   hwType;
+    int     hwSerialNumSz;
+    byte*   hwSerialNum;
+    #ifdef OPENSSL_EXTRA
+        byte    extCertPolicySet;
+        byte    extCertPolicyCrit;
+    #endif /* OPENSSL_EXTRA */
+#endif /* WOLFSSL_SEP */
+#ifdef WOLFSSL_CERT_EXT
+    char    extCertPolicies[MAX_CERTPOL_NB][MAX_CERTPOL_SZ];
+    int     extCertPoliciesNb;
+#endif /* WOLFSSL_CERT_EXT */
+};
+
+extern const char* BEGIN_CERT;
+extern const char* END_CERT;
+extern const char* BEGIN_CERT_REQ;
+extern const char* END_CERT_REQ;
+extern const char* BEGIN_DH_PARAM;
+extern const char* END_DH_PARAM;
+extern const char* BEGIN_X509_CRL;
+extern const char* END_X509_CRL;
+extern const char* BEGIN_RSA_PRIV;
+extern const char* END_RSA_PRIV;
+extern const char* BEGIN_PRIV_KEY;
+extern const char* END_PRIV_KEY;
+extern const char* BEGIN_ENC_PRIV_KEY;
+extern const char* END_ENC_PRIV_KEY;
+extern const char* BEGIN_EC_PRIV;
+extern const char* END_EC_PRIV;
+extern const char* BEGIN_DSA_PRIV;
+extern const char* END_DSA_PRIV;
+extern const char* BEGIN_PUB_KEY;
+extern const char* END_PUB_KEY;
+
+#ifdef NO_SHA
+    #define SIGNER_DIGEST_SIZE SHA256_DIGEST_SIZE
+#else
+    #define SIGNER_DIGEST_SIZE SHA_DIGEST_SIZE
+#endif
+
+/* CA Signers */
+/* if change layout change PERSIST_CERT_CACHE functions too */
+struct Signer {
+    word32  pubKeySize;
+    word32  keyOID;                  /* key type */
+    word16  keyUsage;
+    byte*   publicKey;
+    int     nameLen;
+    char*   name;                    /* common name */
+#ifndef IGNORE_NAME_CONSTRAINTS
+        Base_entry* permittedNames;
+        Base_entry* excludedNames;
+#endif /* IGNORE_NAME_CONSTRAINTS */
+    byte    subjectNameHash[SIGNER_DIGEST_SIZE];
+                                     /* sha hash of names in certificate */
+    #ifndef NO_SKID
+        byte    subjectKeyIdHash[SIGNER_DIGEST_SIZE];
+                                     /* sha hash of names in certificate */
+    #endif
+    Signer* next;
+};
+
+
+/* not for public consumption but may use for testing sometimes */
+#ifdef WOLFSSL_TEST_CERT
+    #define WOLFSSL_TEST_API WOLFSSL_API
+#else
+    #define WOLFSSL_TEST_API WOLFSSL_LOCAL
+#endif
+
+WOLFSSL_TEST_API void FreeAltNames(DNS_entry*, void*);
+#ifndef IGNORE_NAME_CONSTRAINTS
+    WOLFSSL_TEST_API void FreeNameSubtrees(Base_entry*, void*);
+#endif /* IGNORE_NAME_CONSTRAINTS */
+WOLFSSL_TEST_API void InitDecodedCert(DecodedCert*, byte*, word32, void*);
+WOLFSSL_TEST_API void FreeDecodedCert(DecodedCert*);
+WOLFSSL_TEST_API int  ParseCert(DecodedCert*, int type, int verify, void* cm);
+
+WOLFSSL_LOCAL int ParseCertRelative(DecodedCert*,int type,int verify,void* cm);
+WOLFSSL_LOCAL int DecodeToKey(DecodedCert*, int verify);
+
+WOLFSSL_LOCAL Signer* MakeSigner(void*);
+WOLFSSL_LOCAL void    FreeSigner(Signer*, void*);
+WOLFSSL_LOCAL void    FreeSignerTable(Signer**, int, void*);
+
+
+WOLFSSL_LOCAL int ToTraditional(byte* buffer, word32 length);
+WOLFSSL_LOCAL int ToTraditionalEnc(byte* buffer, word32 length,const char*,int);
+
+WOLFSSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType);
+
+/* ASN.1 helper functions */
+WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
+                           word32 maxIdx);
+WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
+                             word32 maxIdx);
+WOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
+                        word32 maxIdx);
+WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx,
+                              int* version);
+WOLFSSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx,
+                        word32 maxIdx);
+WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
+                           word32 maxIdx);
+WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output);
+WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output);
+WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output);
+WOLFSSL_LOCAL word32 SetImplicit(byte tag,byte number,word32 len,byte* output);
+WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output);
+WOLFSSL_LOCAL word32 SetSet(word32 len, byte* output);
+WOLFSSL_LOCAL word32 SetAlgoID(int algoOID,byte* output,int type,int curveSz);
+WOLFSSL_LOCAL int SetMyVersion(word32 version, byte* output, int header);
+WOLFSSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output);
+WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
+                             int maxIdx);
+
+#ifdef HAVE_ECC
+    /* ASN sig helpers */
+    WOLFSSL_LOCAL int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r,
+                                      mp_int* s);
+    WOLFSSL_LOCAL int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen,
+                                       mp_int* r, mp_int* s);
+#endif
+
+#ifdef WOLFSSL_CERT_GEN
+
+enum cert_enums {
+    NAME_ENTRIES    =  8,
+    JOINT_LEN       =  2,
+    EMAIL_JOINT_LEN =  9,
+    RSA_KEY         = 10,
+    NTRU_KEY        = 11,
+    ECC_KEY         = 12
+};
+
+#ifndef WOLFSSL_PEMCERT_TODER_DEFINED
+#ifndef NO_FILESYSTEM
+/* forward from wolfSSL */
+WOLFSSL_API
+int wolfSSL_PemCertToDer(const char* fileName,unsigned char* derBuf,int derSz);
+#define WOLFSSL_PEMCERT_TODER_DEFINED
+#endif
+#endif
+
+#endif /* WOLFSSL_CERT_GEN */
+
+
+
+/* for pointer use */
+typedef struct CertStatus CertStatus;
+
+#ifdef HAVE_OCSP
+
+enum Ocsp_Response_Status {
+    OCSP_SUCCESSFUL        = 0, /* Response has valid confirmations */
+    OCSP_MALFORMED_REQUEST = 1, /* Illegal confirmation request */
+    OCSP_INTERNAL_ERROR    = 2, /* Internal error in issuer */
+    OCSP_TRY_LATER         = 3, /* Try again later */
+    OCSP_SIG_REQUIRED      = 5, /* Must sign the request (4 is skipped) */
+    OCSP_UNAUTHROIZED      = 6  /* Request unauthorized */
+};
+
+
+enum Ocsp_Cert_Status {
+    CERT_GOOD    = 0,
+    CERT_REVOKED = 1,
+    CERT_UNKNOWN = 2
+};
+
+
+enum Ocsp_Sums {
+    OCSP_BASIC_OID = 117,
+    OCSP_NONCE_OID = 118
+};
+
+
+typedef struct OcspRequest  OcspRequest;
+typedef struct OcspResponse OcspResponse;
+
+
+struct CertStatus {
+    CertStatus* next;
+
+    byte serial[EXTERNAL_SERIAL_SIZE];
+    int serialSz;
+
+    int status;
+
+    byte thisDate[MAX_DATE_SIZE];
+    byte nextDate[MAX_DATE_SIZE];
+    byte thisDateFormat;
+    byte nextDateFormat;
+};
+
+
+struct OcspResponse {
+    int     responseStatus;  /* return code from Responder */
+
+    byte*   response;        /* Pointer to beginning of OCSP Response */
+    word32  responseSz;      /* length of the OCSP Response */
+
+    byte    producedDate[MAX_DATE_SIZE];
+                             /* Date at which this response was signed */
+    byte    producedDateFormat; /* format of the producedDate */
+    byte*   issuerHash;
+    byte*   issuerKeyHash;
+
+    byte*   cert;
+    word32  certSz;
+
+    byte*   sig;             /* Pointer to sig in source */
+    word32  sigSz;           /* Length in octets for the sig */
+    word32  sigOID;          /* OID for hash used for sig */
+
+    CertStatus* status;      /* certificate status to fill out */
+
+    byte*   nonce;           /* pointer to nonce inside ASN.1 response */
+    int     nonceSz;         /* length of the nonce string */
+
+    byte*   source;          /* pointer to source buffer, not owned */
+    word32  maxIdx;          /* max offset based on init size */
+};
+
+
+struct OcspRequest {
+    DecodedCert* cert;
+
+    byte    useNonce;
+    byte    nonce[MAX_OCSP_NONCE_SZ];
+    int     nonceSz;
+
+    byte*   issuerHash;      /* pointer to issuerHash in source cert */
+    byte*   issuerKeyHash;   /* pointer to issuerKeyHash in source cert */
+    byte*   serial;          /* pointer to serial number in source cert */
+    int     serialSz;        /* length of the serial number */
+
+    byte*   dest;            /* pointer to the destination ASN.1 buffer */
+    word32  destSz;          /* length of the destination buffer */
+};
+
+
+WOLFSSL_LOCAL void InitOcspResponse(OcspResponse*, CertStatus*, byte*, word32);
+WOLFSSL_LOCAL int  OcspResponseDecode(OcspResponse*);
+
+WOLFSSL_LOCAL void InitOcspRequest(OcspRequest*, DecodedCert*,
+                                                          byte, byte*, word32);
+WOLFSSL_LOCAL int  EncodeOcspRequest(OcspRequest*);
+
+WOLFSSL_LOCAL int  CompareOcspReqResp(OcspRequest*, OcspResponse*);
+
+
+#endif /* HAVE_OCSP */
+
+
+/* for pointer use */
+typedef struct RevokedCert RevokedCert;
+
+#ifdef HAVE_CRL
+
+struct RevokedCert {
+    byte         serialNumber[EXTERNAL_SERIAL_SIZE];
+    int          serialSz;
+    RevokedCert* next;
+};
+
+typedef struct DecodedCRL DecodedCRL;
+
+struct DecodedCRL {
+    word32  certBegin;               /* offset to start of cert          */
+    word32  sigIndex;                /* offset to start of signature     */
+    word32  sigLength;               /* length of signature              */
+    word32  signatureOID;            /* sum of algorithm object id       */
+    byte*   signature;               /* pointer into raw source, not owned */
+    byte    issuerHash[SIGNER_DIGEST_SIZE]; /* issuer hash               */
+    byte    crlHash[SIGNER_DIGEST_SIZE]; /* raw crl data hash            */
+    byte    lastDate[MAX_DATE_SIZE]; /* last date updated  */
+    byte    nextDate[MAX_DATE_SIZE]; /* next update date   */
+    byte    lastDateFormat;          /* format of last date */
+    byte    nextDateFormat;          /* format of next date */
+    RevokedCert* certs;              /* revoked cert list  */
+    int          totalCerts;         /* number on list     */
+};
+
+WOLFSSL_LOCAL void InitDecodedCRL(DecodedCRL*);
+WOLFSSL_LOCAL int  ParseCRL(DecodedCRL*, const byte* buff, word32 sz, void* cm);
+WOLFSSL_LOCAL void FreeDecodedCRL(DecodedCRL*);
+
+
+#endif /* HAVE_CRL */
+
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* !NO_ASN */
+#endif /* WOLF_CRYPT_ASN_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/asn_public.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/asn_public.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/asn_public.h	(revision 164)
@@ -0,0 +1,271 @@
+/* asn_public.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef WOLF_CRYPT_ASN_PUBLIC_H
+#define WOLF_CRYPT_ASN_PUBLIC_H
+
+#include <wolfssl/wolfcrypt/types.h>
+#ifdef HAVE_ECC
+    #include <wolfssl/wolfcrypt/ecc.h>
+#endif
+#if defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA)
+    #include <wolfssl/wolfcrypt/rsa.h>
+#endif
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+/* Certificate file Type */
+enum CertType {
+    CERT_TYPE       = 0,
+    PRIVATEKEY_TYPE,
+    DH_PARAM_TYPE,
+    CRL_TYPE,
+    CA_TYPE,
+    ECC_PRIVATEKEY_TYPE,
+    DSA_PRIVATEKEY_TYPE,
+    CERTREQ_TYPE,
+    DSA_TYPE,
+    ECC_TYPE,
+    RSA_TYPE,
+    PUBLICKEY_TYPE,
+    RSA_PUBLICKEY_TYPE,
+    ECC_PUBLICKEY_TYPE
+};
+
+
+/* Signature type, by OID sum */
+enum Ctc_SigType {
+    CTC_SHAwDSA      = 517,
+    CTC_MD2wRSA      = 646,
+    CTC_MD5wRSA      = 648,
+    CTC_SHAwRSA      = 649,
+    CTC_SHAwECDSA    = 520,
+    CTC_SHA256wRSA   = 655,
+    CTC_SHA256wECDSA = 524,
+    CTC_SHA384wRSA   = 656,
+    CTC_SHA384wECDSA = 525,
+    CTC_SHA512wRSA   = 657,
+    CTC_SHA512wECDSA = 526
+};
+
+enum Ctc_Encoding {
+    CTC_UTF8       = 0x0c, /* utf8      */
+    CTC_PRINTABLE  = 0x13  /* printable */
+};
+
+
+#ifdef WOLFSSL_CERT_GEN
+
+#ifndef HAVE_ECC
+    typedef struct ecc_key ecc_key;
+#endif
+
+enum Ctc_Misc {
+    CTC_NAME_SIZE     =    64,
+    CTC_DATE_SIZE     =    32,
+    CTC_MAX_ALT_SIZE  = 16384,   /* may be huge */
+    CTC_SERIAL_SIZE   =     8,
+#ifdef WOLFSSL_CERT_EXT
+    /* AKID could contains: hash + (Option) AuthCertIssuer,AuthCertSerialNum
+     * We support only hash */
+    CTC_MAX_SKID_SIZE = SHA256_DIGEST_SIZE,
+    CTC_MAX_AKID_SIZE = SHA256_DIGEST_SIZE,
+    CTC_MAX_CERTPOL_SZ = 64,
+    CTC_MAX_CERTPOL_NB = 2 /* Max number of Certificate Policy */
+#endif /* WOLFSSL_CERT_EXT */
+};
+
+typedef struct CertName {
+    char country[CTC_NAME_SIZE];
+    char countryEnc;
+    char state[CTC_NAME_SIZE];
+    char stateEnc;
+    char locality[CTC_NAME_SIZE];
+    char localityEnc;
+    char sur[CTC_NAME_SIZE];
+    char surEnc;
+    char org[CTC_NAME_SIZE];
+    char orgEnc;
+    char unit[CTC_NAME_SIZE];
+    char unitEnc;
+    char commonName[CTC_NAME_SIZE];
+    char commonNameEnc;
+    char email[CTC_NAME_SIZE];  /* !!!! email has to be last !!!! */
+} CertName;
+
+
+/* for user to fill for certificate generation */
+typedef struct Cert {
+    int      version;                   /* x509 version  */
+    byte     serial[CTC_SERIAL_SIZE];   /* serial number */
+    int      sigType;                   /* signature algo type */
+    CertName issuer;                    /* issuer info */
+    int      daysValid;                 /* validity days */
+    int      selfSigned;                /* self signed flag */
+    CertName subject;                   /* subject info */
+    int      isCA;                      /* is this going to be a CA */
+    /* internal use only */
+    int      bodySz;                    /* pre sign total size */
+    int      keyType;                   /* public key type of subject */
+#ifdef WOLFSSL_ALT_NAMES
+    byte     altNames[CTC_MAX_ALT_SIZE]; /* altNames copy */
+    int      altNamesSz;                 /* altNames size in bytes */
+    byte     beforeDate[CTC_DATE_SIZE];  /* before date copy */
+    int      beforeDateSz;               /* size of copy */
+    byte     afterDate[CTC_DATE_SIZE];   /* after date copy */
+    int      afterDateSz;                /* size of copy */
+#endif
+#ifdef WOLFSSL_CERT_EXT
+    byte    skid[CTC_MAX_SKID_SIZE];     /* Subject Key Identifier */
+    int     skidSz;                      /* SKID size in bytes */
+    byte    akid[CTC_MAX_AKID_SIZE];     /* Authority Key Identifier */
+    int     akidSz;                      /* AKID size in bytes */
+    word16  keyUsage;                    /* Key Usage */
+    char    certPolicies[CTC_MAX_CERTPOL_NB][CTC_MAX_CERTPOL_SZ];
+    word16  certPoliciesNb;              /* Number of Cert Policy */
+#endif
+#ifdef WOLFSSL_CERT_REQ
+    char     challengePw[CTC_NAME_SIZE];
+#endif
+} Cert;
+#endif /* WOLFSSL_CERT_GEN */
+
+
+#ifdef WOLFSSL_CERT_GEN
+
+
+
+/* Initialize and Set Certficate defaults:
+   version    = 3 (0x2)
+   serial     = 0 (Will be randomly generated)
+   sigType    = SHA_WITH_RSA
+   issuer     = blank
+   daysValid  = 500
+   selfSigned = 1 (true) use subject as issuer
+   subject    = blank
+   isCA       = 0 (false)
+   keyType    = RSA_KEY (default)
+*/
+WOLFSSL_API void wc_InitCert(Cert*);
+WOLFSSL_API int  wc_MakeCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*,
+                         ecc_key*, WC_RNG*);
+#ifdef WOLFSSL_CERT_REQ
+    WOLFSSL_API int  wc_MakeCertReq(Cert*, byte* derBuffer, word32 derSz,
+                                    RsaKey*, ecc_key*);
+#endif
+WOLFSSL_API int  wc_SignCert(int requestSz, int sigType, byte* derBuffer,
+                         word32 derSz, RsaKey*, ecc_key*, WC_RNG*);
+WOLFSSL_API int  wc_MakeSelfCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*,
+                             WC_RNG*);
+WOLFSSL_API int  wc_SetIssuer(Cert*, const char*);
+WOLFSSL_API int  wc_SetSubject(Cert*, const char*);
+#ifdef WOLFSSL_ALT_NAMES
+    WOLFSSL_API int  wc_SetAltNames(Cert*, const char*);
+#endif
+WOLFSSL_API int  wc_SetIssuerBuffer(Cert*, const byte*, int);
+WOLFSSL_API int  wc_SetSubjectBuffer(Cert*, const byte*, int);
+WOLFSSL_API int  wc_SetAltNamesBuffer(Cert*, const byte*, int);
+WOLFSSL_API int  wc_SetDatesBuffer(Cert*, const byte*, int);
+
+#ifdef WOLFSSL_CERT_EXT
+WOLFSSL_API int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey,
+                                             ecc_key *eckey);
+WOLFSSL_API int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz);
+WOLFSSL_API int wc_SetAuthKeyId(Cert *cert, const char* file);
+WOLFSSL_API int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey,
+                                                ecc_key *eckey);
+WOLFSSL_API int wc_SetSubjectKeyId(Cert *cert, const char* file);
+
+#ifdef HAVE_NTRU
+WOLFSSL_API int wc_SetSubjectKeyIdFromNtruPublicKey(Cert *cert, byte *ntruKey,
+                                                    word16 ntruKeySz);
+#endif
+
+/* Set the KeyUsage.
+ * Value is a string separated tokens with ','. Accepted tokens are :
+ * digitalSignature,nonRepudiation,contentCommitment,keyCertSign,cRLSign,
+ * dataEncipherment,keyAgreement,keyEncipherment,encipherOnly and decipherOnly.
+ *
+ * nonRepudiation and contentCommitment are for the same usage.
+ */
+WOLFSSL_API int wc_SetKeyUsage(Cert *cert, const char *value);
+
+/* encode Certificate Policies, return total bytes written
+ * each input value must be ITU-T X.690 formatted : a.b.c...
+ * input must be an array of values with a NULL terminated for the latest
+ * RFC5280 : non-critical */
+WOLFSSL_API int wc_SetCertificatePolicies(Cert *cert, const char **input);
+
+#ifndef WOLFSSL_PEMPUBKEY_TODER_DEFINED
+    #ifndef NO_FILESYSTEM
+    /* forward from wolfssl */
+    WOLFSSL_API int wolfSSL_PemPubKeyToDer(const char* fileName,
+                                           unsigned char* derBuf, int derSz);
+    #endif
+
+    /* forward from wolfssl */
+    WOLFSSL_API int wolfSSL_PubKeyPemToDer(const unsigned char*, int,
+                                           unsigned char*, int);
+    #define WOLFSSL_PEMPUBKEY_TODER_DEFINED
+#endif /* WOLFSSL_PEMPUBKEY_TODER_DEFINED */
+#endif /* WOLFSSL_CERT_EXT */
+
+    #ifdef HAVE_NTRU
+        WOLFSSL_API int  wc_MakeNtruCert(Cert*, byte* derBuffer, word32 derSz,
+                                     const byte* ntruKey, word16 keySz,
+                                     WC_RNG*);
+    #endif
+
+#endif /* WOLFSSL_CERT_GEN */
+
+
+#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) || !defined(NO_DSA)
+    WOLFSSL_API int wc_DerToPem(const byte* der, word32 derSz, byte* output,
+                                word32 outputSz, int type);
+    WOLFSSL_API int wc_DerToPemEx(const byte* der, word32 derSz, byte* output,
+                                word32 outputSz, byte *cipherIno, int type);
+#endif
+
+#ifdef HAVE_ECC
+    /* private key helpers */
+    WOLFSSL_API int wc_EccPrivateKeyDecode(const byte*, word32*,
+                                           ecc_key*, word32);
+    WOLFSSL_API int wc_EccKeyToDer(ecc_key*, byte* output, word32 inLen);
+
+    /* public key helper */
+    WOLFSSL_API int wc_EccPublicKeyDecode(const byte*, word32*,
+                                              ecc_key*, word32);
+#endif
+
+/* DER encode signature */
+WOLFSSL_API word32 wc_EncodeSignature(byte* out, const byte* digest,
+                                      word32 digSz, int hashOID);
+WOLFSSL_API int wc_GetCTC_HashOID(int type);
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* WOLF_CRYPT_ASN_PUBLIC_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/coding.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/coding.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/coding.h	(revision 164)
@@ -0,0 +1,75 @@
+/* coding.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef WOLF_CRYPT_CODING_H
+#define WOLF_CRYPT_CODING_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+WOLFSSL_API int Base64_Decode(const byte* in, word32 inLen, byte* out,
+                               word32* outLen);
+
+#if defined(OPENSSL_EXTRA) || defined(SESSION_CERTS) || defined(WOLFSSL_KEY_GEN)                         || defined(WOLFSSL_CERT_GEN) || defined(HAVE_WEBSERVER)                         || !defined(NO_DSA)
+    #ifndef WOLFSSL_BASE64_ENCODE
+        #define WOLFSSL_BASE64_ENCODE
+    #endif
+#endif
+
+
+#ifdef WOLFSSL_BASE64_ENCODE
+    enum Escaped {
+        WC_STD_ENC = 0,       /* normal \n line ending encoding */
+        WC_ESC_NL_ENC,        /* use escape sequence encoding   */
+        WC_NO_NL_ENC          /* no encoding at all             */
+    }; /* Encoding types */
+
+    /* encode isn't */
+    WOLFSSL_API
+    int Base64_Encode(const byte* in, word32 inLen, byte* out,
+                                  word32* outLen);
+    WOLFSSL_API
+    int Base64_EncodeEsc(const byte* in, word32 inLen, byte* out,
+                                  word32* outLen);
+    WOLFSSL_API
+    int Base64_Encode_NoNl(const byte* in, word32 inLen, byte* out,
+                                  word32* outLen);
+#endif
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_FIPS)
+    WOLFSSL_API
+    int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen);
+    WOLFSSL_API
+    int Base16_Encode(const byte* in, word32 inLen, byte* out, word32* outLen);
+#endif
+
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* WOLF_CRYPT_CODING_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/curve25519.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/curve25519.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/curve25519.h	(revision 164)
@@ -0,0 +1,141 @@
+/* curve25519.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_CURVE25519_H
+#define WOLF_CRYPT_CURVE25519_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef HAVE_CURVE25519
+
+#include <wolfssl/wolfcrypt/fe_operations.h>
+#include <wolfssl/wolfcrypt/random.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#define CURVE25519_KEYSIZE 32
+
+/* curve25519 set type */
+typedef struct {
+    int size;       /* The size of the curve in octets */
+    const char* name;     /* name of this curve */
+} curve25519_set_type;
+
+
+/* ECC point, the internal structure is Little endian
+ * the mathematical functions used the endianess */
+typedef struct {
+    byte point[CURVE25519_KEYSIZE];
+}ECPoint;
+
+/* A CURVE25519 Key */
+typedef struct {
+    int idx;            /* Index into the ecc_sets[] for the parameters of
+                           this curve if -1, this key is using user supplied
+                           curve in dp */
+    const curve25519_set_type* dp;   /* domain parameters, either points to
+                                   curves (idx >= 0) or user supplied */
+    ECPoint   p;        /* public key  */
+    ECPoint   k;        /* private key */
+} curve25519_key;
+
+enum {
+    EC25519_LITTLE_ENDIAN=0,
+    EC25519_BIG_ENDIAN=1
+};
+
+WOLFSSL_API
+int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key);
+
+WOLFSSL_API
+int wc_curve25519_shared_secret(curve25519_key* private_key,
+                                curve25519_key* public_key,
+                                byte* out, word32* outlen);
+
+WOLFSSL_API
+int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
+                                   curve25519_key* public_key,
+                                   byte* out, word32* outlen, int endian);
+
+WOLFSSL_API
+int wc_curve25519_init(curve25519_key* key);
+
+WOLFSSL_API
+void wc_curve25519_free(curve25519_key* key);
+
+
+/* raw key helpers */
+WOLFSSL_API
+int wc_curve25519_import_private(const byte* priv, word32 privSz,
+                                 curve25519_key* key);
+WOLFSSL_API
+int wc_curve25519_import_private_ex(const byte* priv, word32 privSz,
+                                    curve25519_key* key, int endian);
+
+WOLFSSL_API
+int wc_curve25519_import_private_raw(const byte* priv, word32 privSz,
+                            const byte* pub, word32 pubSz, curve25519_key* key);
+WOLFSSL_API
+int wc_curve25519_import_private_raw_ex(const byte* priv, word32 privSz,
+                                        const byte* pub, word32 pubSz,
+                                        curve25519_key* key, int endian);
+WOLFSSL_API
+int wc_curve25519_export_private_raw(curve25519_key* key, byte* out,
+                                     word32* outLen);
+WOLFSSL_API
+int wc_curve25519_export_private_raw_ex(curve25519_key* key, byte* out,
+                                        word32* outLen, int endian);
+
+WOLFSSL_API
+int wc_curve25519_import_public(const byte* in, word32 inLen,
+                                curve25519_key* key);
+WOLFSSL_API
+int wc_curve25519_import_public_ex(const byte* in, word32 inLen,
+                                   curve25519_key* key, int endian);
+
+WOLFSSL_API
+int wc_curve25519_export_public(curve25519_key* key, byte* out, word32* outLen);
+WOLFSSL_API
+int wc_curve25519_export_public_ex(curve25519_key* key, byte* out,
+                                   word32* outLen, int endian);
+
+WOLFSSL_API
+int wc_curve25519_export_key_raw(curve25519_key* key,
+                                 byte* priv, word32 *privSz,
+                                 byte* pub, word32 *pubSz);
+WOLFSSL_API
+int wc_curve25519_export_key_raw_ex(curve25519_key* key,
+                                    byte* priv, word32 *privSz,
+                                    byte* pub, word32 *pubSz,
+                                    int endian);
+/* size helper */
+WOLFSSL_API
+int wc_curve25519_size(curve25519_key* key);
+
+#ifdef __cplusplus
+    }    /* extern "C" */
+#endif
+
+#endif /* HAVE_CURVE25519 */
+#endif /* WOLF_CRYPT_CURVE25519_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/des3.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/des3.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/des3.h	(revision 164)
@@ -0,0 +1,115 @@
+/* des3.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_DES3_H
+#define WOLF_CRYPT_DES3_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifndef NO_DES3
+
+#ifdef HAVE_FIPS
+/* included for fips @wc_fips */
+#include <cyassl/ctaocrypt/des3.h>
+#endif
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#ifndef HAVE_FIPS /* to avoid redifinition of macros */
+#define WOLFSSL_3DES_CAVIUM_MAGIC 0xBEEF0003
+
+enum {
+    DES_ENC_TYPE    = 2,     /* cipher unique type */
+    DES3_ENC_TYPE   = 3,     /* cipher unique type */
+    DES_BLOCK_SIZE  = 8,
+    DES_KS_SIZE     = 32,
+
+    DES_ENCRYPTION  = 0,
+    DES_DECRYPTION  = 1
+};
+
+#define DES_IVLEN 8
+#define DES_KEYLEN 8
+#define DES3_IVLEN 8
+#define DES3_KEYLEN 24
+
+
+#ifdef STM32F2_CRYPTO
+enum {
+    DES_CBC = 0,
+    DES_ECB = 1
+};
+#endif
+
+
+/* DES encryption and decryption */
+typedef struct Des {
+    word32 reg[DES_BLOCK_SIZE / sizeof(word32)];      /* for CBC mode */
+    word32 tmp[DES_BLOCK_SIZE / sizeof(word32)];      /* same         */
+    word32 key[DES_KS_SIZE];
+} Des;
+
+
+/* DES3 encryption and decryption */
+typedef struct Des3 {
+    word32 key[3][DES_KS_SIZE];
+    word32 reg[DES_BLOCK_SIZE / sizeof(word32)];      /* for CBC mode */
+    word32 tmp[DES_BLOCK_SIZE / sizeof(word32)];      /* same         */
+#ifdef HAVE_CAVIUM
+    int     devId;           /* nitrox device id */
+    word32  magic;           /* using cavium magic */
+    word64  contextHandle;   /* nitrox context memory handle */
+#endif
+} Des3;
+#endif /* HAVE_FIPS */
+
+WOLFSSL_API int  wc_Des_SetKey(Des* des, const byte* key,
+                               const byte* iv, int dir);
+WOLFSSL_API void wc_Des_SetIV(Des* des, const byte* iv);
+WOLFSSL_API int  wc_Des_CbcEncrypt(Des* des, byte* out,
+                                   const byte* in, word32 sz);
+WOLFSSL_API int  wc_Des_CbcDecrypt(Des* des, byte* out,
+                                   const byte* in, word32 sz);
+WOLFSSL_API int  wc_Des_EcbEncrypt(Des* des, byte* out,
+                                   const byte* in, word32 sz);
+
+WOLFSSL_API int  wc_Des3_SetKey(Des3* des, const byte* key,
+                                const byte* iv,int dir);
+WOLFSSL_API int  wc_Des3_SetIV(Des3* des, const byte* iv);
+WOLFSSL_API int  wc_Des3_CbcEncrypt(Des3* des, byte* out,
+                                    const byte* in,word32 sz);
+WOLFSSL_API int  wc_Des3_CbcDecrypt(Des3* des, byte* out,
+                                    const byte* in,word32 sz);
+
+#ifdef HAVE_CAVIUM
+    WOLFSSL_API int  wc_Des3_InitCavium(Des3*, int);
+    WOLFSSL_API void wc_Des3_FreeCavium(Des3*);
+#endif
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* NO_DES3 */
+#endif /* WOLF_CRYPT_DES3_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/dh.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/dh.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/dh.h	(revision 164)
@@ -0,0 +1,66 @@
+/* dh.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_DH_H
+#define WOLF_CRYPT_DH_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifndef NO_DH
+
+#include <wolfssl/wolfcrypt/integer.h>
+#include <wolfssl/wolfcrypt/random.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+/* Diffie-Hellman Key */
+typedef struct DhKey {
+    mp_int p, g;                            /* group parameters  */
+} DhKey;
+
+
+WOLFSSL_API void wc_InitDhKey(DhKey* key);
+WOLFSSL_API void wc_FreeDhKey(DhKey* key);
+
+WOLFSSL_API int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng, byte* priv,
+                                 word32* privSz, byte* pub, word32* pubSz);
+WOLFSSL_API int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz,
+                       const byte* priv, word32 privSz, const byte* otherPub,
+                       word32 pubSz);
+
+WOLFSSL_API int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key,
+                           word32);
+WOLFSSL_API int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
+                        word32 gSz);
+WOLFSSL_API int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p,
+                            word32* pInOutSz, byte* g, word32* gInOutSz);
+
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* NO_DH */
+#endif /* WOLF_CRYPT_DH_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/dsa.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/dsa.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/dsa.h	(revision 164)
@@ -0,0 +1,80 @@
+/* dsa.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_DSA_H
+#define WOLF_CRYPT_DSA_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifndef NO_DSA
+
+#include <wolfssl/wolfcrypt/integer.h>
+#include <wolfssl/wolfcrypt/random.h>
+
+/* for DSA reverse compatibility */
+#define InitDsaKey wc_InitDsaKey
+#define FreeDsaKey wc_FreeDsaKey
+#define DsaSign wc_DsaSign
+#define DsaVerify wc_DsaVerify
+#define DsaPublicKeyDecode wc_DsaPublicKeyDecode
+#define DsaPrivateKeyDecode wc_DsaPrivateKeyDecode
+#define DsaKeyToDer wc_DsaKeyToDer
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+enum {
+    DSA_PUBLIC   = 0,
+    DSA_PRIVATE  = 1
+};
+
+/* DSA */
+typedef struct DsaKey {
+    mp_int p, q, g, y, x;
+    int type;                               /* public or private */
+} DsaKey;
+
+WOLFSSL_API void wc_InitDsaKey(DsaKey* key);
+WOLFSSL_API void wc_FreeDsaKey(DsaKey* key);
+WOLFSSL_API int wc_DsaSign(const byte* digest, byte* out,
+                           DsaKey* key, WC_RNG* rng);
+WOLFSSL_API int wc_DsaVerify(const byte* digest, const byte* sig,
+                             DsaKey* key, int* answer);
+WOLFSSL_API int wc_DsaPublicKeyDecode(const byte* input, word32* inOutIdx,
+                                      DsaKey*, word32);
+WOLFSSL_API int wc_DsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
+                                       DsaKey*, word32);
+WOLFSSL_API int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen);
+
+#ifdef WOLFSSL_KEY_GEN
+WOLFSSL_API int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa);
+WOLFSSL_API int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa);
+#endif
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* NO_DSA */
+#endif /* WOLF_CRYPT_DSA_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/ed25519.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/ed25519.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/ed25519.h	(revision 164)
@@ -0,0 +1,107 @@
+/* ed25519.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_ED25519_H
+#define WOLF_CRYPT_ED25519_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef HAVE_ED25519
+
+#include <wolfssl/wolfcrypt/fe_operations.h>
+#include <wolfssl/wolfcrypt/ge_operations.h>
+#include <wolfssl/wolfcrypt/random.h>
+#include <wolfssl/wolfcrypt/sha512.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+/* info about EdDSA curve specifically ed25519, defined as an elliptic curve
+   over GF(p) */
+/*
+    32,                key size
+    "ED25519",         curve name
+    "2^255-19",        prime number
+    "SHA512",          hash function
+    "-121665/121666",  value of d
+*/
+
+#define ED25519_KEY_SIZE     32 /* private key only */
+#define ED25519_SIG_SIZE     64
+
+#define ED25519_PUB_KEY_SIZE 32 /* compressed */
+/* both private and public key */
+#define ED25519_PRV_KEY_SIZE (ED25519_PUB_KEY_SIZE+ED25519_KEY_SIZE)
+
+/* An ED25519 Key */
+typedef struct {
+    byte    p[ED25519_PUB_KEY_SIZE]; /* compressed public key */
+    byte    k[ED25519_PRV_KEY_SIZE]; /* private key : 32 secret -- 32 public */
+} ed25519_key;
+
+
+WOLFSSL_API
+int wc_ed25519_make_key(WC_RNG* rng, int keysize, ed25519_key* key);
+WOLFSSL_API
+int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
+                        word32 *outlen, ed25519_key* key);
+WOLFSSL_API
+int wc_ed25519_verify_msg(byte* sig, word32 siglen, const byte* msg,
+                          word32 msglen, int* stat, ed25519_key* key);
+WOLFSSL_API
+int wc_ed25519_init(ed25519_key* key);
+WOLFSSL_API
+void wc_ed25519_free(ed25519_key* key);
+WOLFSSL_API
+int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key);
+WOLFSSL_API
+int wc_ed25519_import_private_key(const byte* priv, word32 privSz,
+                               const byte* pub, word32 pubSz, ed25519_key* key);
+WOLFSSL_API
+int wc_ed25519_export_public(ed25519_key*, byte* out, word32* outLen);
+WOLFSSL_API
+int wc_ed25519_export_private_only(ed25519_key* key, byte* out, word32* outLen);
+WOLFSSL_API
+int wc_ed25519_export_private(ed25519_key* key, byte* out, word32* outLen);
+WOLFSSL_API
+int wc_ed25519_export_key(ed25519_key* key,
+                          byte* priv, word32 *privSz,
+                          byte* pub, word32 *pubSz);
+
+/* size helper */
+WOLFSSL_API
+int wc_ed25519_size(ed25519_key* key);
+WOLFSSL_API
+int wc_ed25519_priv_size(ed25519_key* key);
+WOLFSSL_API
+int wc_ed25519_pub_size(ed25519_key* key);
+WOLFSSL_API
+int wc_ed25519_sig_size(ed25519_key* key);
+
+#ifdef __cplusplus
+    }    /* extern "C" */
+#endif
+
+#endif /* HAVE_ED25519 */
+#endif /* WOLF_CRYPT_ED25519_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/error-crypt.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/error-crypt.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/error-crypt.h	(revision 164)
@@ -0,0 +1,177 @@
+/* error-crypt.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef WOLF_CRYPT_ERROR_H
+#define WOLF_CRYPT_ERROR_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef HAVE_FIPS
+	#include <cyassl/ctaocrypt/error-crypt.h>
+#endif /* HAVE_FIPS */
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+/* error codes */
+enum {
+    MAX_CODE_E         = -100,  /* errors -101 - -299 */
+    OPEN_RAN_E         = -101,  /* opening random device error */
+    READ_RAN_E         = -102,  /* reading random device error */
+    WINCRYPT_E         = -103,  /* windows crypt init error */
+    CRYPTGEN_E         = -104,  /* windows crypt generation error */
+    RAN_BLOCK_E        = -105,  /* reading random device would block */
+    BAD_MUTEX_E        = -106,  /* Bad mutex operation */
+
+    MP_INIT_E          = -110,  /* mp_init error state */
+    MP_READ_E          = -111,  /* mp_read error state */
+    MP_EXPTMOD_E       = -112,  /* mp_exptmod error state */
+    MP_TO_E            = -113,  /* mp_to_xxx error state, can't convert */
+    MP_SUB_E           = -114,  /* mp_sub error state, can't subtract */
+    MP_ADD_E           = -115,  /* mp_add error state, can't add */
+    MP_MUL_E           = -116,  /* mp_mul error state, can't multiply */
+    MP_MULMOD_E        = -117,  /* mp_mulmod error state, can't multiply mod */
+    MP_MOD_E           = -118,  /* mp_mod error state, can't mod */
+    MP_INVMOD_E        = -119,  /* mp_invmod error state, can't inv mod */
+    MP_CMP_E           = -120,  /* mp_cmp error state */
+    MP_ZERO_E          = -121,  /* got a mp zero result, not expected */
+
+    MEMORY_E           = -125,  /* out of memory error */
+
+    RSA_WRONG_TYPE_E   = -130,  /* RSA wrong block type for RSA function */
+    RSA_BUFFER_E       = -131,  /* RSA buffer error, output too small or
+                                   input too large */
+    BUFFER_E           = -132,  /* output buffer too small or input too large */
+    ALGO_ID_E          = -133,  /* setting algo id error */
+    PUBLIC_KEY_E       = -134,  /* setting public key error */
+    DATE_E             = -135,  /* setting date validity error */
+    SUBJECT_E          = -136,  /* setting subject name error */
+    ISSUER_E           = -137,  /* setting issuer  name error */
+    CA_TRUE_E          = -138,  /* setting CA basic constraint true error */
+    EXTENSIONS_E       = -139,  /* setting extensions error */
+
+    ASN_PARSE_E        = -140,  /* ASN parsing error, invalid input */
+    ASN_VERSION_E      = -141,  /* ASN version error, invalid number */
+    ASN_GETINT_E       = -142,  /* ASN get big int error, invalid data */
+    ASN_RSA_KEY_E      = -143,  /* ASN key init error, invalid input */
+    ASN_OBJECT_ID_E    = -144,  /* ASN object id error, invalid id */
+    ASN_TAG_NULL_E     = -145,  /* ASN tag error, not null */
+    ASN_EXPECT_0_E     = -146,  /* ASN expect error, not zero */
+    ASN_BITSTR_E       = -147,  /* ASN bit string error, wrong id */
+    ASN_UNKNOWN_OID_E  = -148,  /* ASN oid error, unknown sum id */
+    ASN_DATE_SZ_E      = -149,  /* ASN date error, bad size */
+    ASN_BEFORE_DATE_E  = -150,  /* ASN date error, current date before */
+    ASN_AFTER_DATE_E   = -151,  /* ASN date error, current date after */
+    ASN_SIG_OID_E      = -152,  /* ASN signature error, mismatched oid */
+    ASN_TIME_E         = -153,  /* ASN time error, unknown time type */
+    ASN_INPUT_E        = -154,  /* ASN input error, not enough data */
+    ASN_SIG_CONFIRM_E  = -155,  /* ASN sig error, confirm failure */
+    ASN_SIG_HASH_E     = -156,  /* ASN sig error, unsupported hash type */
+    ASN_SIG_KEY_E      = -157,  /* ASN sig error, unsupported key type */
+    ASN_DH_KEY_E       = -158,  /* ASN key init error, invalid input */
+    ASN_NTRU_KEY_E     = -159,  /* ASN ntru key decode error, invalid input */
+    ASN_CRIT_EXT_E     = -160,  /* ASN unsupported critical extension */
+
+    ECC_BAD_ARG_E      = -170,  /* ECC input argument of wrong type */
+    ASN_ECC_KEY_E      = -171,  /* ASN ECC bad input */
+    ECC_CURVE_OID_E    = -172,  /* Unsupported ECC OID curve type */
+    BAD_FUNC_ARG       = -173,  /* Bad function argument provided */
+    NOT_COMPILED_IN    = -174,  /* Feature not compiled in */
+    UNICODE_SIZE_E     = -175,  /* Unicode password too big */
+    NO_PASSWORD        = -176,  /* no password provided by user */
+    ALT_NAME_E         = -177,  /* alt name size problem, too big */
+
+    AES_GCM_AUTH_E     = -180,  /* AES-GCM Authentication check failure */
+    AES_CCM_AUTH_E     = -181,  /* AES-CCM Authentication check failure */
+
+    CAVIUM_INIT_E      = -182,  /* Cavium Init type error */
+
+    COMPRESS_INIT_E    = -183,  /* Compress init error */
+    COMPRESS_E         = -184,  /* Compress error */
+    DECOMPRESS_INIT_E  = -185,  /* DeCompress init error */
+    DECOMPRESS_E       = -186,  /* DeCompress error */
+
+    BAD_ALIGN_E         = -187,  /* Bad alignment for operation, no alloc */
+    ASN_NO_SIGNER_E     = -188,  /* ASN no signer to confirm failure */
+    ASN_CRL_CONFIRM_E   = -189,  /* ASN CRL signature confirm failure */
+    ASN_CRL_NO_SIGNER_E = -190,  /* ASN CRL no signer to confirm failure */
+    ASN_OCSP_CONFIRM_E  = -191,  /* ASN OCSP signature confirm failure */
+
+    BAD_ENC_STATE_E     = -192,  /* Bad ecc enc state operation */
+    BAD_PADDING_E       = -193,  /* Bad padding, msg not correct length  */
+
+    REQ_ATTRIBUTE_E     = -194,  /* setting cert request attributes error */
+
+    PKCS7_OID_E         = -195,  /* PKCS#7, mismatched OID error */
+    PKCS7_RECIP_E       = -196,  /* PKCS#7, recipient error */
+    FIPS_NOT_ALLOWED_E  = -197,  /* FIPS not allowed error */
+    ASN_NAME_INVALID_E  = -198,  /* ASN name constraint error */
+
+    RNG_FAILURE_E       = -199,  /* RNG Failed, Reinitialize */
+    HMAC_MIN_KEYLEN_E   = -200,  /* FIPS Mode HMAC Minimum Key Length error */
+    RSA_PAD_E           = -201,  /* RSA Padding Error */
+    LENGTH_ONLY_E       = -202,  /* Returning output length only */
+
+    IN_CORE_FIPS_E      = -203,  /* In Core Integrity check failure */
+    AES_KAT_FIPS_E      = -204,  /* AES KAT failure */
+    DES3_KAT_FIPS_E     = -205,  /* DES3 KAT failure */
+    HMAC_KAT_FIPS_E     = -206,  /* HMAC KAT failure */
+    RSA_KAT_FIPS_E      = -207,  /* RSA KAT failure */
+    DRBG_KAT_FIPS_E     = -208,  /* HASH DRBG KAT failure */
+    DRBG_CONT_FIPS_E    = -209,  /* HASH DRBG Continious test failure */
+    AESGCM_KAT_FIPS_E   = -210,  /* AESGCM KAT failure */
+    THREAD_STORE_KEY_E  = -211,  /* Thread local storage key create failure */
+    THREAD_STORE_SET_E  = -212,  /* Thread local storage key set failure */
+
+    MAC_CMP_FAILED_E    = -213,  /* MAC comparison failed */
+    IS_POINT_E          = -214,  /* ECC is point on curve failed */
+    ECC_INF_E           = -215,  /* ECC point infinity error */
+    ECC_PRIV_KEY_E      = -216,  /* ECC private key not valid error */
+
+    SRP_CALL_ORDER_E    = -217,  /* SRP function called in the wrong order. */
+    SRP_VERIFY_E        = -218,  /* SRP proof verification failed. */
+    SRP_BAD_KEY_E       = -219,  /* SRP bad ephemeral values. */
+
+    ASN_NO_SKID         = -220,  /* ASN no Subject Key Identifier found */
+    ASN_NO_AKID         = -221,  /* ASN no Authority Key Identifier found */
+    ASN_NO_KEYUSAGE     = -223,  /* ASN no Key Usage found */
+    SKID_E              = -224,  /* setting Subject Key Identifier error */
+    AKID_E              = -225,  /* setting Authority Key Identifier error */
+    KEYUSAGE_E          = -226,  /* Bad Key Usage value */
+    CERTPOLICIES_E      = -227,  /* setting Certificate Policies error */
+
+    WC_FAILURE_E        = -228,  /* wolfcrypt failed to initialize */
+
+    MIN_CODE_E          = -300   /* errors -101 - -299 */
+};
+
+
+WOLFSSL_API void wc_ErrorString(int err, char* buff);
+WOLFSSL_API const char* wc_GetErrorString(int error);
+
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+#endif /* WOLF_CRYPT_ERROR_H */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/hash.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/hash.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/hash.h	(revision 164)
@@ -0,0 +1,89 @@
+/* hash.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_HASH_H
+#define WOLF_CRYPT_HASH_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#ifndef NO_MD5
+#include <wolfssl/wolfcrypt/md5.h>
+WOLFSSL_API void wc_Md5GetHash(Md5*, byte*);
+WOLFSSL_API void wc_Md5RestorePos(Md5*, Md5*) ;
+#if defined(WOLFSSL_TI_HASH)
+    WOLFSSL_API void wc_Md5Free(Md5*);
+#else
+    #define wc_Md5Free(d)
+#endif
+#endif
+
+#ifndef NO_SHA
+#include <wolfssl/wolfcrypt/sha.h>
+WOLFSSL_API int wc_ShaGetHash(Sha*, byte*);
+WOLFSSL_API void wc_ShaRestorePos(Sha*, Sha*) ;
+WOLFSSL_API int wc_ShaHash(const byte*, word32, byte*);
+#if defined(WOLFSSL_TI_HASH)
+     WOLFSSL_API void wc_ShaFree(Sha*);
+#else
+    #define wc_ShaFree(d)
+#endif
+#endif
+
+#ifndef NO_SHA256
+#include <wolfssl/wolfcrypt/sha256.h>
+WOLFSSL_API int wc_Sha256GetHash(Sha256*, byte*);
+WOLFSSL_API void wc_Sha256RestorePos(Sha256*, Sha256*) ;
+WOLFSSL_API int wc_Sha256Hash(const byte*, word32, byte*);
+#if defined(WOLFSSL_TI_HASH)
+    WOLFSSL_API void wc_Sha256Free(Sha256*);
+#else
+    #define wc_Sha256Free(d)
+#endif
+#endif
+
+#ifdef WOLFSSL_SHA512
+#include <wolfssl/wolfcrypt/sha512.h>
+WOLFSSL_API int wc_Sha512Hash(const byte*, word32, byte*);
+#if defined(WOLFSSL_TI_HASH)
+    WOLFSSL_API void wc_Sha512Free(Sha512*);
+#else
+    #define wc_Sha512Free(d)
+#endif
+    #if defined(WOLFSSL_SHA384)
+        WOLFSSL_API int wc_Sha384Hash(const byte*, word32, byte*);
+        #if defined(WOLFSSL_TI_HASH)
+            WOLFSSL_API void wc_Sha384Free(Sha384*);
+        #else
+            #define wc_Sha384Free(d)
+        #endif
+    #endif /* defined(WOLFSSL_SHA384) */
+#endif /* WOLFSSL_SHA512 */
+
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* WOLF_CRYPT_HASH_H */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/hc128.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/hc128.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/hc128.h	(revision 164)
@@ -0,0 +1,58 @@
+/* hc128.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_HC128_H
+#define WOLF_CRYPT_HC128_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifndef NO_HC128
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+enum {
+	HC128_ENC_TYPE    =  6    /* cipher unique type */
+};
+
+/* HC-128 stream cipher */
+typedef struct HC128 {
+    word32 T[1024];             /* P[i] = T[i];  Q[i] = T[1024 + i ]; */
+    word32 X[16];
+    word32 Y[16];
+    word32 counter1024;         /* counter1024 = i mod 1024 at the ith step */
+    word32 key[8];
+    word32 iv[8];
+} HC128;
+
+
+WOLFSSL_API int wc_Hc128_Process(HC128*, byte*, const byte*, word32);
+WOLFSSL_API int wc_Hc128_SetKey(HC128*, const byte* key, const byte* iv);
+
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* HAVE_HC128 */
+#endif /* WOLF_CRYPT_HC128_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/hmac.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/hmac.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/hmac.h	(revision 164)
@@ -0,0 +1,190 @@
+/* hmac.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef NO_HMAC
+
+#ifndef WOLF_CRYPT_HMAC_H
+#define WOLF_CRYPT_HMAC_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifndef NO_MD5
+    #include <wolfssl/wolfcrypt/md5.h>
+#endif
+
+#ifndef NO_SHA
+    #include <wolfssl/wolfcrypt/sha.h>
+#endif
+
+#ifndef NO_SHA256
+    #include <wolfssl/wolfcrypt/sha256.h>
+#endif
+
+#ifdef WOLFSSL_SHA512
+    #include <wolfssl/wolfcrypt/sha512.h>
+#endif
+
+#ifdef HAVE_BLAKE2
+    #include <wolfssl/wolfcrypt/blake2.h>
+#endif
+
+#ifdef HAVE_FIPS
+/* for fips */
+    #include <cyassl/ctaocrypt/hmac.h>
+#endif
+
+#ifdef HAVE_CAVIUM
+    #include <wolfssl/wolfcrypt/logging.h>
+    #include "cavium_common.h"
+#endif
+
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+#ifndef HAVE_FIPS
+#define WOLFSSL_HMAC_CAVIUM_MAGIC 0xBEEF0005
+
+enum {
+    HMAC_FIPS_MIN_KEY = 14,   /* 112 bit key length minimum */
+
+    IPAD    = 0x36,
+    OPAD    = 0x5C,
+
+/* If any hash is not enabled, add the ID here. */
+#ifdef NO_MD5
+    MD5     = 0,
+#endif
+#ifdef NO_SHA
+    SHA     = 1,
+#endif
+#ifdef NO_SHA256
+    SHA256  = 2,
+#endif
+#ifndef WOLFSSL_SHA512
+    SHA512  = 4,
+#endif
+#ifndef WOLFSSL_SHA384
+    SHA384  = 5,
+#endif
+#ifndef HAVE_BLAKE2
+    BLAKE2B_ID = 7,
+#endif
+
+/* Select the largest available hash for the buffer size. */
+#if defined(WOLFSSL_SHA512)
+    MAX_DIGEST_SIZE = SHA512_DIGEST_SIZE,
+    HMAC_BLOCK_SIZE = SHA512_BLOCK_SIZE
+#elif defined(HAVE_BLAKE2)
+    MAX_DIGEST_SIZE = BLAKE2B_OUTBYTES,
+    HMAC_BLOCK_SIZE = BLAKE2B_BLOCKBYTES,
+#elif defined(WOLFSSL_SHA384)
+    MAX_DIGEST_SIZE = SHA384_DIGEST_SIZE,
+    HMAC_BLOCK_SIZE = SHA384_BLOCK_SIZE
+#elif !defined(NO_SHA256)
+    MAX_DIGEST_SIZE = SHA256_DIGEST_SIZE,
+    HMAC_BLOCK_SIZE = SHA256_BLOCK_SIZE
+#elif !defined(NO_SHA)
+    MAX_DIGEST_SIZE = SHA_DIGEST_SIZE,
+    HMAC_BLOCK_SIZE = SHA_BLOCK_SIZE
+#elif !defined(NO_MD5)
+    MAX_DIGEST_SIZE = MD5_DIGEST_SIZE,
+    HMAC_BLOCK_SIZE = MD5_BLOCK_SIZE
+#else
+    #error "You have to have some kind of hash if you want to use HMAC."
+#endif
+};
+
+
+/* hash union */
+typedef union {
+    #ifndef NO_MD5
+        Md5 md5;
+    #endif
+    #ifndef NO_SHA
+        Sha sha;
+    #endif
+    #ifndef NO_SHA256
+        Sha256 sha256;
+    #endif
+    #ifdef WOLFSSL_SHA384
+        Sha384 sha384;
+    #endif
+    #ifdef WOLFSSL_SHA512
+        Sha512 sha512;
+    #endif
+    #ifdef HAVE_BLAKE2
+        Blake2b blake2b;
+    #endif
+} Hash;
+
+/* Hmac digest */
+typedef struct Hmac {
+    Hash    hash;
+    word32  ipad[HMAC_BLOCK_SIZE  / sizeof(word32)];  /* same block size all*/
+    word32  opad[HMAC_BLOCK_SIZE  / sizeof(word32)];
+    word32  innerHash[MAX_DIGEST_SIZE / sizeof(word32)];
+    byte    macType;                                     /* md5 sha or sha256 */
+    byte    innerHashKeyed;                              /* keyed flag */
+#ifdef HAVE_CAVIUM
+    word16   keyLen;          /* hmac key length */
+    word16   dataLen;
+    HashType type;            /* hmac key type */
+    int      devId;           /* nitrox device id */
+    word32   magic;           /* using cavium magic */
+    word64   contextHandle;   /* nitrox context memory handle */
+    byte*    data;            /* buffered input data for one call */
+#endif
+} Hmac;
+
+#endif /* HAVE_FIPS */
+
+/* does init */
+WOLFSSL_API int wc_HmacSetKey(Hmac*, int type, const byte* key, word32 keySz);
+WOLFSSL_API int wc_HmacUpdate(Hmac*, const byte*, word32);
+WOLFSSL_API int wc_HmacFinal(Hmac*, byte*);
+
+#ifdef HAVE_CAVIUM
+    WOLFSSL_API int  wc_HmacInitCavium(Hmac*, int);
+    WOLFSSL_API void wc_HmacFreeCavium(Hmac*);
+#endif
+
+WOLFSSL_API int wolfSSL_GetHmacMaxSize(void);
+
+
+#ifdef HAVE_HKDF
+
+WOLFSSL_API int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
+                    const byte* salt, word32 saltSz,
+                    const byte* info, word32 infoSz,
+                    byte* out, word32 outSz);
+
+#endif /* HAVE_HKDF */
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* WOLF_CRYPT_HMAC_H */
+
+#endif /* NO_HMAC */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/idea.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/idea.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/idea.h	(revision 164)
@@ -0,0 +1,66 @@
+/* idea.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_IDEA_H
+#define WOLF_CRYPT_IDEA_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef HAVE_IDEA
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+enum {
+    IDEA_MODULO     = 0x10001,             /* 2^16+1 */
+    IDEA_2EXP16     = 0x10000,             /* 2^16 */
+    IDEA_MASK       = 0xFFFF,              /* 16 bits set to one */
+    IDEA_ROUNDS     = 8,                   /* number of rounds for IDEA */
+    IDEA_SK_NUM     = (6*IDEA_ROUNDS + 4), /* number of subkeys */
+    IDEA_KEY_SIZE   = 16,                  /* size of key in bytes */
+    IDEA_BLOCK_SIZE = 8,                   /* size of IDEA blocks in bytes */
+    IDEA_IV_SIZE    = 8,                   /* size of IDEA IV in bytes */
+    IDEA_ENCRYPTION = 0,
+    IDEA_DECRYPTION = 1
+};
+
+/* IDEA encryption and decryption */
+typedef struct Idea {
+    word32  reg[IDEA_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */
+    word32  tmp[IDEA_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */
+    word16  skey[IDEA_SK_NUM]; /* 832 bits expanded key */
+} Idea;
+
+WOLFSSL_API int wc_IdeaSetKey(Idea *idea, const byte* key, word16 keySz,
+                              const byte *iv, int dir);
+WOLFSSL_API int wc_IdeaSetIV(Idea *idea, const byte* iv);
+WOLFSSL_API void wc_IdeaCipher(Idea *idea, byte* out, const byte* in);
+WOLFSSL_API int wc_IdeaCbcEncrypt(Idea *idea, byte* out,
+                                  const byte* in, word32 len);
+WOLFSSL_API int wc_IdeaCbcDecrypt(Idea *idea, byte* out,
+                                  const byte* in, word32 len);
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* HAVE_IDEA */
+#endif /* WOLF_CRYPT_IDEA_H */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/integer.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/integer.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/integer.h	(revision 164)
@@ -0,0 +1,337 @@
+/* integer.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@iahu.ca,
+ * http://math.libtomcrypt.com
+ */
+
+
+#ifndef WOLF_CRYPT_INTEGER_H
+#define WOLF_CRYPT_INTEGER_H
+
+/* may optionally use fast math instead, not yet supported on all platforms and
+   may not be faster on all
+*/
+#include <wolfssl/wolfcrypt/types.h>       /* will set MP_xxBIT if not default */
+#ifdef USE_FAST_MATH
+    #include <wolfssl/wolfcrypt/tfm.h>
+#else
+
+#include <wolfssl/wolfcrypt/random.h> 
+
+#ifndef CHAR_BIT
+    #include <limits.h>
+#endif
+
+#include <wolfssl/wolfcrypt/mpi_class.h>
+
+#ifndef MIN
+   #define MIN(x,y) ((x)<(y)?(x):(y))
+#endif
+
+#ifndef MAX
+   #define MAX(x,y) ((x)>(y)?(x):(y))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+
+/* C++ compilers don't like assigning void * to mp_digit * */
+#define  OPT_CAST(x)  (x *)
+
+#else
+
+/* C on the other hand doesn't care */
+#define  OPT_CAST(x)
+
+#endif
+
+
+/* detect 64-bit mode if possible */
+#if defined(__x86_64__)
+   #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT))
+      #define MP_64BIT
+   #endif
+#endif
+/* if intel compiler doesn't provide 128 bit type don't turn on 64bit */
+#if defined(MP_64BIT) && defined(__INTEL_COMPILER) && !defined(HAVE___UINT128_T)
+    #undef MP_64BIT
+#endif
+
+
+/* allow user to define on mp_digit, mp_word, DIGIT_BIT types */
+#ifndef WOLFSSL_BIGINT_TYPES
+
+/* some default configurations.
+ *
+ * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
+ * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
+ *
+ * At the very least a mp_digit must be able to hold 7 bits
+ * [any size beyond that is ok provided it doesn't overflow the data type]
+ */
+#ifdef MP_8BIT
+   typedef unsigned char      mp_digit;
+   typedef unsigned short     mp_word;
+#elif defined(MP_16BIT) || defined(NO_64BIT)
+   typedef unsigned short     mp_digit;
+   typedef unsigned int       mp_word;
+#elif defined(MP_64BIT)
+   /* for GCC only on supported platforms */
+   typedef unsigned long long mp_digit;  /* 64 bit type, 128 uses mode(TI) */
+   typedef unsigned long      mp_word __attribute__ ((mode(TI)));
+
+   #define DIGIT_BIT          60
+#else
+   /* this is the default case, 28-bit digits */
+
+   #if defined(_MSC_VER) || defined(__BORLANDC__)
+      typedef unsigned __int64   ulong64;
+   #else
+      typedef unsigned long long ulong64;
+   #endif
+
+   typedef unsigned int       mp_digit;  /* long could be 64 now, changed TAO */
+   typedef ulong64            mp_word;
+
+#ifdef MP_31BIT
+   /* this is an extension that uses 31-bit digits */
+   #define DIGIT_BIT          31
+#else
+   /* default case is 28-bit digits, defines MP_28BIT as a handy test macro */
+   #define DIGIT_BIT          28
+   #define MP_28BIT
+#endif
+#endif
+
+#endif /* WOLFSSL_BIGINT_TYPES */
+
+/* otherwise the bits per digit is calculated automatically from the size of
+   a mp_digit */
+#ifndef DIGIT_BIT
+   #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1)))
+      /* bits per digit */
+#endif
+
+#define MP_DIGIT_BIT     DIGIT_BIT
+#define MP_MASK          ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
+#define MP_DIGIT_MAX     MP_MASK
+
+/* equalities */
+#define MP_LT        -1   /* less than */
+#define MP_EQ         0   /* equal to */
+#define MP_GT         1   /* greater than */
+
+#define MP_ZPOS       0   /* positive integer */
+#define MP_NEG        1   /* negative */
+
+#define MP_OKAY       0   /* ok result */
+#define MP_MEM        -2  /* out of mem */
+#define MP_VAL        -3  /* invalid input */
+#define MP_NOT_INF	  -4  /* point not at infinity */
+#define MP_RANGE      MP_NOT_INF
+
+#define MP_YES        1   /* yes response */
+#define MP_NO         0   /* no response */
+
+/* Primality generation flags */
+#define LTM_PRIME_BBS      0x0001 /* BBS style prime */
+#define LTM_PRIME_SAFE     0x0002 /* Safe prime (p-1)/2 == prime */
+#define LTM_PRIME_2MSB_ON  0x0008 /* force 2nd MSB to 1 */
+
+typedef int           mp_err;
+
+/* define this to use lower memory usage routines (exptmods mostly) */
+#define MP_LOW_MEM
+
+/* default precision */
+#ifndef MP_PREC
+   #ifndef MP_LOW_MEM
+      #define MP_PREC                 32     /* default digits of precision */
+   #else
+      #define MP_PREC                 1      /* default digits of precision */
+   #endif
+#endif
+
+/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD -
+   BITS_PER_DIGIT*2) */
+#define MP_WARRAY  (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
+
+/* the infamous mp_int structure */
+typedef struct  {
+    int used, alloc, sign;
+    mp_digit *dp;
+} mp_int;
+
+/* callback for mp_prime_random, should fill dst with random bytes and return
+   how many read [upto len] */
+typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
+
+
+#define USED(m)    ((m)->used)
+#define DIGIT(m,k) ((m)->dp[(k)])
+#define SIGN(m)    ((m)->sign)
+
+
+/* ---> Basic Manipulations <--- */
+#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
+#define mp_iseven(a) \
+    (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
+#define mp_isodd(a) \
+    (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
+
+
+/* number of primes */
+#ifdef MP_8BIT
+   #define PRIME_SIZE      31
+#else
+   #define PRIME_SIZE      256
+#endif
+
+#define mp_prime_random(a, t, size, bbs, cb, dat) \
+   mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat)
+
+#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
+#define mp_raw_size(mp)           mp_signed_bin_size(mp)
+#define mp_toraw(mp, str)         mp_to_signed_bin((mp), (str))
+#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
+#define mp_mag_size(mp)           mp_unsigned_bin_size(mp)
+#define mp_tomag(mp, str)         mp_to_unsigned_bin((mp), (str))
+
+#define mp_tobinary(M, S)  mp_toradix((M), (S), 2)
+#define mp_tooctal(M, S)   mp_toradix((M), (S), 8)
+#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
+#define mp_tohex(M, S)     mp_toradix((M), (S), 16)
+
+#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
+
+extern const char *mp_s_rmap;
+
+/* 6 functions needed by Rsa */
+int  mp_init (mp_int * a);
+void mp_clear (mp_int * a);
+int  mp_unsigned_bin_size(mp_int * a);
+int  mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c);
+int  mp_to_unsigned_bin (mp_int * a, unsigned char *b);
+int  mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y);
+/* end functions needed by Rsa */
+
+/* functions added to support above needed, removed TOOM and KARATSUBA */
+int  mp_count_bits (mp_int * a);
+int  mp_leading_bit (mp_int * a);
+int  mp_init_copy (mp_int * a, mp_int * b);
+int  mp_copy (mp_int * a, mp_int * b);
+int  mp_grow (mp_int * a, int size);
+int  mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d);
+void mp_zero (mp_int * a);
+void mp_clamp (mp_int * a);
+void mp_exch (mp_int * a, mp_int * b);
+void mp_rshd (mp_int * a, int b);
+void mp_rshb (mp_int * a, int b);
+int  mp_mod_2d (mp_int * a, int b, mp_int * c);
+int  mp_mul_2d (mp_int * a, int b, mp_int * c);
+int  mp_lshd (mp_int * a, int b);
+int  mp_abs (mp_int * a, mp_int * b);
+int  mp_invmod (mp_int * a, mp_int * b, mp_int * c);
+int  fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c);
+int  mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);
+int  mp_cmp_mag (mp_int * a, mp_int * b);
+int  mp_cmp (mp_int * a, mp_int * b);
+int  mp_cmp_d(mp_int * a, mp_digit b);
+void mp_set (mp_int * a, mp_digit b);
+int  mp_is_bit_set (mp_int * a, mp_digit b);
+int  mp_mod (mp_int * a, mp_int * b, mp_int * c);
+int  mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d);
+int  mp_div_2(mp_int * a, mp_int * b);
+int  mp_add (mp_int * a, mp_int * b, mp_int * c);
+int  s_mp_add (mp_int * a, mp_int * b, mp_int * c);
+int  s_mp_sub (mp_int * a, mp_int * b, mp_int * c);
+int  mp_sub (mp_int * a, mp_int * b, mp_int * c);
+int  mp_reduce_is_2k_l(mp_int *a);
+int  mp_reduce_is_2k(mp_int *a);
+int  mp_dr_is_modulus(mp_int *a);
+int  mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int);
+int  mp_montgomery_setup (mp_int * n, mp_digit * rho);
+int  fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho);
+int  mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho);
+void mp_dr_setup(mp_int *a, mp_digit *d);
+int  mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k);
+int  mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
+int  fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs);
+int  s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs);
+int  mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
+int  mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
+int  mp_reduce (mp_int * x, mp_int * m, mp_int * mu);
+int  mp_reduce_setup (mp_int * a, mp_int * b);
+int  s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode);
+int  mp_montgomery_calc_normalization (mp_int * a, mp_int * b);
+int  s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs);
+int  s_mp_sqr (mp_int * a, mp_int * b);
+int  fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs);
+int  fast_s_mp_sqr (mp_int * a, mp_int * b);
+int  mp_init_size (mp_int * a, int size);
+int  mp_div_3 (mp_int * a, mp_int *c, mp_digit * d);
+int  mp_mul_2(mp_int * a, mp_int * b);
+int  mp_mul (mp_int * a, mp_int * b, mp_int * c);
+int  mp_sqr (mp_int * a, mp_int * b);
+int  mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d);
+int  mp_mul_d (mp_int * a, mp_digit b, mp_int * c);
+int  mp_2expt (mp_int * a, int b);
+int  mp_set_bit (mp_int * a, int b);
+int  mp_reduce_2k_setup(mp_int *a, mp_digit *d);
+int  mp_add_d (mp_int* a, mp_digit b, mp_int* c);
+int mp_set_int (mp_int * a, unsigned long b);
+int mp_sub_d (mp_int * a, mp_digit b, mp_int * c);
+/* end support added functions */
+
+/* added */
+int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e,
+                  mp_int* f);
+int mp_toradix (mp_int *a, char *str, int radix);
+int mp_radix_size (mp_int * a, int radix, int *size);
+
+#if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN)
+    int mp_sqrmod(mp_int* a, mp_int* b, mp_int* c);
+#endif
+#if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN)
+    int mp_read_radix(mp_int* a, const char* str, int radix);
+#endif
+
+#ifdef WOLFSSL_KEY_GEN
+    int mp_prime_is_prime (mp_int * a, int t, int *result);
+    int mp_gcd (mp_int * a, mp_int * b, mp_int * c);
+    int mp_lcm (mp_int * a, mp_int * b, mp_int * c);
+    int mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap);
+#endif
+
+int mp_cnt_lsb(mp_int *a);
+int mp_mod_d(mp_int* a, mp_digit b, mp_digit* c);
+
+#ifdef __cplusplus
+   }
+#endif
+
+
+#endif /* USE_FAST_MATH */
+
+#endif  /* WOLF_CRYPT_INTEGER_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/logging.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/logging.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/logging.h	(revision 164)
@@ -0,0 +1,75 @@
+/* logging.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* submitted by eof */
+
+
+#ifndef WOLFSSL_LOGGING_H
+#define WOLFSSL_LOGGING_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+enum  CYA_Log_Levels {
+    ERROR_LOG = 0,
+    INFO_LOG,
+    ENTER_LOG,
+    LEAVE_LOG,
+    OTHER_LOG
+};
+
+typedef void (*wolfSSL_Logging_cb)(const int logLevel,
+                                  const char *const logMessage);
+
+WOLFSSL_API int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb log_function);
+
+#ifdef DEBUG_WOLFSSL
+    /* a is prepended to m and b is appended, creating a log msg a + m + b */
+    #define WOLFSSL_LOG_CAT(a, m, b) #a " " m " "  #b
+
+    void WOLFSSL_ENTER(const char* msg);
+    void WOLFSSL_LEAVE(const char* msg, int ret);
+    #define WOLFSSL_STUB(m) \
+        WOLFSSL_MSG(WOLFSSL_LOG_CAT(wolfSSL Stub, m, not implemented))
+
+    void WOLFSSL_ERROR(int);
+    void WOLFSSL_MSG(const char* msg);
+
+#else /* DEBUG_WOLFSSL   */
+
+    #define WOLFSSL_ENTER(m)
+    #define WOLFSSL_LEAVE(m, r)
+    #define WOLFSSL_STUB(m)
+
+    #define WOLFSSL_ERROR(e)
+    #define WOLFSSL_MSG(m)
+
+#endif /* DEBUG_WOLFSSL  */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* WOLFSSL_LOGGING_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/md4.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/md4.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/md4.h	(revision 164)
@@ -0,0 +1,62 @@
+/* md4.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_MD4_H
+#define WOLF_CRYPT_MD4_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifndef NO_MD4
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+/* in bytes */
+enum {
+    MD4_BLOCK_SIZE  = 64,
+    MD4_DIGEST_SIZE = 16,
+    MD4_PAD_SIZE    = 56
+};
+
+
+/* MD4 digest */
+typedef struct Md4 {
+    word32  buffLen;   /* in bytes          */
+    word32  loLen;     /* length in bytes   */
+    word32  hiLen;     /* length in bytes   */
+    word32  digest[MD4_DIGEST_SIZE / sizeof(word32)];
+    word32  buffer[MD4_BLOCK_SIZE  / sizeof(word32)];
+} Md4;
+
+
+WOLFSSL_API void wc_InitMd4(Md4*);
+WOLFSSL_API void wc_Md4Update(Md4*, const byte*, word32);
+WOLFSSL_API void wc_Md4Final(Md4*, byte*);
+
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* NO_MD4 */
+#endif /* WOLF_CRYPT_MD4_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/md5.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/md5.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/md5.h	(revision 164)
@@ -0,0 +1,85 @@
+/* md5.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_MD5_H
+#define WOLF_CRYPT_MD5_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifndef NO_MD5
+
+#ifdef HAVE_FIPS
+    #define wc_InitMd5   InitMd5
+    #define wc_Md5Update Md5Update
+    #define wc_Md5Final  Md5Final
+    #define wc_Md5Hash   Md5Hash
+#endif
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+/* in bytes */
+enum {
+#ifdef STM32F2_HASH
+    MD5_REG_SIZE    =  4,      /* STM32 register size, bytes */
+#endif
+    MD5             =  0,      /* hash type unique */
+    MD5_BLOCK_SIZE  = 64,
+    MD5_DIGEST_SIZE = 16,
+    MD5_PAD_SIZE    = 56
+};
+
+#if defined(WOLFSSL_PIC32MZ_HASH)
+#include "port/pic32/pic32mz-crypt.h"
+#endif
+
+#ifndef WOLFSSL_TI_HASH
+
+/* MD5 digest */
+typedef struct Md5 {
+    word32  buffLen;   /* in bytes          */
+    word32  loLen;     /* length in bytes   */
+    word32  hiLen;     /* length in bytes   */
+    word32  buffer[MD5_BLOCK_SIZE  / sizeof(word32)];
+    #if !defined(WOLFSSL_PIC32MZ_HASH)
+    word32  digest[MD5_DIGEST_SIZE / sizeof(word32)];
+    #else
+    word32  digest[PIC32_HASH_SIZE / sizeof(word32)];
+    pic32mz_desc desc ; /* Crypt Engine descripter */
+    #endif
+} Md5;
+
+#else /* WOLFSSL_TI_HASH */
+    #include "wolfssl/wolfcrypt/port/ti/ti-hash.h"
+#endif
+
+WOLFSSL_API void wc_InitMd5(Md5*);
+WOLFSSL_API void wc_Md5Update(Md5*, const byte*, word32);
+WOLFSSL_API void wc_Md5Final(Md5*, byte*);
+WOLFSSL_API int  wc_Md5Hash(const byte*, word32, byte*);
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* NO_MD5 */
+#endif /* WOLF_CRYPT_MD5_H */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/memory.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/memory.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/memory.h	(revision 164)
@@ -0,0 +1,56 @@
+/* memory.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* submitted by eof */
+
+
+#ifndef WOLFSSL_MEMORY_H
+#define WOLFSSL_MEMORY_H
+
+#include <stdlib.h>
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+typedef void *(*wolfSSL_Malloc_cb)(size_t size);
+typedef void (*wolfSSL_Free_cb)(void *ptr);
+typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size);
+
+
+/* Public set function */
+WOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb  malloc_function,
+                                    wolfSSL_Free_cb    free_function,
+                                    wolfSSL_Realloc_cb realloc_function);
+
+/* Public in case user app wants to use XMALLOC/XFREE */
+WOLFSSL_API void* wolfSSL_Malloc(size_t size);
+WOLFSSL_API void  wolfSSL_Free(void *ptr);
+WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size);
+
+
+#ifdef __cplusplus
+    }  /* extern "C" */
+#endif
+
+#endif /* WOLFSSL_MEMORY_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/misc.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/misc.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/misc.h	(revision 164)
@@ -0,0 +1,78 @@
+/* misc.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef WOLF_CRYPT_MISC_H
+#define WOLF_CRYPT_MISC_H
+
+
+#include <wolfssl/wolfcrypt/types.h>
+
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+#ifdef NO_INLINE
+WOLFSSL_LOCAL
+word32 rotlFixed(word32, word32);
+WOLFSSL_LOCAL
+word32 rotrFixed(word32, word32);
+
+WOLFSSL_LOCAL
+word32 ByteReverseWord32(word32);
+WOLFSSL_LOCAL
+void   ByteReverseWords(word32*, const word32*, word32);
+
+WOLFSSL_LOCAL
+void XorWords(wolfssl_word*, const wolfssl_word*, word32);
+WOLFSSL_LOCAL
+void xorbuf(void*, const void*, word32);
+
+WOLFSSL_LOCAL
+void ForceZero(const void*, word32);
+
+WOLFSSL_LOCAL
+int ConstantCompare(const byte*, const byte*, int);
+
+#ifdef WORD64_AVAILABLE
+WOLFSSL_LOCAL
+word64 rotlFixed64(word64, word64);
+WOLFSSL_LOCAL
+word64 rotrFixed64(word64, word64);
+
+WOLFSSL_LOCAL
+word64 ByteReverseWord64(word64);
+WOLFSSL_LOCAL
+void   ByteReverseWords64(word64*, const word64*, word32);
+#endif /* WORD64_AVAILABLE */
+
+#endif /* NO_INLINE */
+
+
+#ifdef __cplusplus
+    }   /* extern "C" */
+#endif
+
+
+#endif /* WOLF_CRYPT_MISC_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/mpi_class.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/mpi_class.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/mpi_class.h	(revision 164)
@@ -0,0 +1,1018 @@
+/* mpi_class.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#if !(defined(LTM1) && defined(LTM2) && defined(LTM3))
+#if defined(LTM2)
+#define LTM3
+#endif
+#if defined(LTM1)
+#define LTM2
+#endif
+#define LTM1
+
+#if defined(LTM_ALL)
+#define BN_ERROR_C
+#define BN_FAST_MP_INVMOD_C
+#define BN_FAST_MP_MONTGOMERY_REDUCE_C
+#define BN_FAST_S_MP_MUL_DIGS_C
+#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+#define BN_FAST_S_MP_SQR_C
+#define BN_MP_2EXPT_C
+#define BN_MP_ABS_C
+#define BN_MP_ADD_C
+#define BN_MP_ADD_D_C
+#define BN_MP_ADDMOD_C
+#define BN_MP_AND_C
+#define BN_MP_CLAMP_C
+#define BN_MP_CLEAR_C
+#define BN_MP_CLEAR_MULTI_C
+#define BN_MP_CMP_C
+#define BN_MP_CMP_D_C
+#define BN_MP_CMP_MAG_C
+#define BN_MP_CNT_LSB_C
+#define BN_MP_COPY_C
+#define BN_MP_COUNT_BITS_C
+#define BN_MP_DIV_C
+#define BN_MP_DIV_2_C
+#define BN_MP_DIV_2D_C
+#define BN_MP_DIV_3_C
+#define BN_MP_DIV_D_C
+#define BN_MP_DR_IS_MODULUS_C
+#define BN_MP_DR_REDUCE_C
+#define BN_MP_DR_SETUP_C
+#define BN_MP_EXCH_C
+#define BN_MP_EXPT_D_C
+#define BN_MP_EXPTMOD_C
+#define BN_MP_EXPTMOD_FAST_C
+#define BN_MP_EXTEUCLID_C
+#define BN_MP_FREAD_C
+#define BN_MP_FWRITE_C
+#define BN_MP_GCD_C
+#define BN_MP_GET_INT_C
+#define BN_MP_GROW_C
+#define BN_MP_INIT_C
+#define BN_MP_INIT_COPY_C
+#define BN_MP_INIT_MULTI_C
+#define BN_MP_INIT_SET_C
+#define BN_MP_INIT_SET_INT_C
+#define BN_MP_INIT_SIZE_C
+#define BN_MP_INVMOD_C
+#define BN_MP_INVMOD_SLOW_C
+#define BN_MP_IS_SQUARE_C
+#define BN_MP_JACOBI_C
+#define BN_MP_KARATSUBA_MUL_C
+#define BN_MP_KARATSUBA_SQR_C
+#define BN_MP_LCM_C
+#define BN_MP_LSHD_C
+#define BN_MP_MOD_C
+#define BN_MP_MOD_2D_C
+#define BN_MP_MOD_D_C
+#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+#define BN_MP_MONTGOMERY_REDUCE_C
+#define BN_MP_MONTGOMERY_SETUP_C
+#define BN_MP_MUL_C
+#define BN_MP_MUL_2_C
+#define BN_MP_MUL_2D_C
+#define BN_MP_MUL_D_C
+#define BN_MP_MULMOD_C
+#define BN_MP_N_ROOT_C
+#define BN_MP_NEG_C
+#define BN_MP_OR_C
+#define BN_MP_PRIME_FERMAT_C
+#define BN_MP_PRIME_IS_DIVISIBLE_C
+#define BN_MP_PRIME_IS_PRIME_C
+#define BN_MP_PRIME_MILLER_RABIN_C
+#define BN_MP_PRIME_NEXT_PRIME_C
+#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+#define BN_MP_PRIME_RANDOM_EX_C
+#define BN_MP_RADIX_SIZE_C
+#define BN_MP_RADIX_SMAP_C
+#define BN_MP_RAND_C
+#define BN_MP_READ_RADIX_C
+#define BN_MP_READ_SIGNED_BIN_C
+#define BN_MP_READ_UNSIGNED_BIN_C
+#define BN_MP_REDUCE_C
+#define BN_MP_REDUCE_2K_C
+#define BN_MP_REDUCE_2K_L_C
+#define BN_MP_REDUCE_2K_SETUP_C
+#define BN_MP_REDUCE_2K_SETUP_L_C
+#define BN_MP_REDUCE_IS_2K_C
+#define BN_MP_REDUCE_IS_2K_L_C
+#define BN_MP_REDUCE_SETUP_C
+#define BN_MP_RSHD_C
+#define BN_MP_SET_C
+#define BN_MP_SET_INT_C
+#define BN_MP_SHRINK_C
+#define BN_MP_SIGNED_BIN_SIZE_C
+#define BN_MP_SQR_C
+#define BN_MP_SQRMOD_C
+#define BN_MP_SQRT_C
+#define BN_MP_SUB_C
+#define BN_MP_SUB_D_C
+#define BN_MP_SUBMOD_C
+#define BN_MP_TO_SIGNED_BIN_C
+#define BN_MP_TO_SIGNED_BIN_N_C
+#define BN_MP_TO_UNSIGNED_BIN_C
+#define BN_MP_TO_UNSIGNED_BIN_N_C
+#define BN_MP_TOOM_MUL_C
+#define BN_MP_TOOM_SQR_C
+#define BN_MP_TORADIX_C
+#define BN_MP_TORADIX_N_C
+#define BN_MP_UNSIGNED_BIN_SIZE_C
+#define BN_MP_XOR_C
+#define BN_MP_ZERO_C
+#define BN_PRIME_TAB_C
+#define BN_REVERSE_C
+#define BN_S_MP_ADD_C
+#define BN_S_MP_EXPTMOD_C
+#define BN_S_MP_MUL_DIGS_C
+#define BN_S_MP_MUL_HIGH_DIGS_C
+#define BN_S_MP_SQR_C
+#define BN_S_MP_SUB_C
+#define BNCORE_C
+#endif
+
+#if defined(BN_ERROR_C)
+   #define BN_MP_ERROR_TO_STRING_C
+#endif
+
+#if defined(BN_FAST_MP_INVMOD_C)
+   #define BN_MP_ISEVEN_C
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_COPY_C
+   #define BN_MP_MOD_C
+   #define BN_MP_SET_C
+   #define BN_MP_DIV_2_C
+   #define BN_MP_ISODD_C
+   #define BN_MP_SUB_C
+   #define BN_MP_CMP_C
+   #define BN_MP_ISZERO_C
+   #define BN_MP_CMP_D_C
+   #define BN_MP_ADD_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_FAST_S_MP_MUL_DIGS_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_FAST_S_MP_SQR_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_2EXPT_C)
+   #define BN_MP_ZERO_C
+   #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_ABS_C)
+   #define BN_MP_COPY_C
+#endif
+
+#if defined(BN_MP_ADD_C)
+   #define BN_S_MP_ADD_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_ADD_D_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_SUB_D_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_ADDMOD_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_ADD_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_AND_C)
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_CLAMP_C)
+#endif
+
+#if defined(BN_MP_CLEAR_C)
+#endif
+
+#if defined(BN_MP_CLEAR_MULTI_C)
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_CMP_C)
+   #define BN_MP_CMP_MAG_C
+#endif
+
+#if defined(BN_MP_CMP_D_C)
+#endif
+
+#if defined(BN_MP_CMP_MAG_C)
+#endif
+
+#if defined(BN_MP_CNT_LSB_C)
+   #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_COPY_C)
+   #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_COUNT_BITS_C)
+#endif
+
+#if defined(BN_MP_DIV_C)
+   #define BN_MP_ISZERO_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_MP_COPY_C
+   #define BN_MP_ZERO_C
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_SET_C
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_ABS_C
+   #define BN_MP_MUL_2D_C
+   #define BN_MP_CMP_C
+   #define BN_MP_SUB_C
+   #define BN_MP_ADD_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_MULTI_C
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_INIT_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_LSHD_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_MUL_D_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DIV_2_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_DIV_2D_C)
+   #define BN_MP_COPY_C
+   #define BN_MP_ZERO_C
+   #define BN_MP_INIT_C
+   #define BN_MP_MOD_2D_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_DIV_3_C)
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DIV_D_C)
+   #define BN_MP_ISZERO_C
+   #define BN_MP_COPY_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_DIV_3_C
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DR_IS_MODULUS_C)
+#endif
+
+#if defined(BN_MP_DR_REDUCE_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_DR_SETUP_C)
+#endif
+
+#if defined(BN_MP_EXCH_C)
+#endif
+
+#if defined(BN_MP_EXPT_D_C)
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_SET_C
+   #define BN_MP_SQR_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_MUL_C
+#endif
+
+#if defined(BN_MP_EXPTMOD_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_INVMOD_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_ABS_C
+   #define BN_MP_CLEAR_MULTI_C
+   #define BN_MP_REDUCE_IS_2K_L_C
+   #define BN_S_MP_EXPTMOD_C
+   #define BN_MP_DR_IS_MODULUS_C
+   #define BN_MP_REDUCE_IS_2K_C
+   #define BN_MP_ISODD_C
+   #define BN_MP_EXPTMOD_FAST_C
+#endif
+
+#if defined(BN_MP_EXPTMOD_FAST_C)
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_INIT_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_MONTGOMERY_SETUP_C
+   #define BN_FAST_MP_MONTGOMERY_REDUCE_C
+   #define BN_MP_MONTGOMERY_REDUCE_C
+   #define BN_MP_DR_SETUP_C
+   #define BN_MP_DR_REDUCE_C
+   #define BN_MP_REDUCE_2K_SETUP_C
+   #define BN_MP_REDUCE_2K_C
+   #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+   #define BN_MP_MULMOD_C
+   #define BN_MP_SET_C
+   #define BN_MP_MOD_C
+   #define BN_MP_COPY_C
+   #define BN_MP_SQR_C
+   #define BN_MP_MUL_C
+   #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_EXTEUCLID_C)
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_SET_C
+   #define BN_MP_COPY_C
+   #define BN_MP_ISZERO_C
+   #define BN_MP_DIV_C
+   #define BN_MP_MUL_C
+   #define BN_MP_SUB_C
+   #define BN_MP_NEG_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_FREAD_C)
+   #define BN_MP_ZERO_C
+   #define BN_MP_S_RMAP_C
+   #define BN_MP_MUL_D_C
+   #define BN_MP_ADD_D_C
+   #define BN_MP_CMP_D_C
+#endif
+
+#if defined(BN_MP_FWRITE_C)
+   #define BN_MP_RADIX_SIZE_C
+   #define BN_MP_TORADIX_C
+#endif
+
+#if defined(BN_MP_GCD_C)
+   #define BN_MP_ISZERO_C
+   #define BN_MP_ABS_C
+   #define BN_MP_ZERO_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_CNT_LSB_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_MP_EXCH_C
+   #define BN_S_MP_SUB_C
+   #define BN_MP_MUL_2D_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_GET_INT_C)
+#endif
+
+#if defined(BN_MP_GROW_C)
+#endif
+
+#if defined(BN_MP_INIT_C)
+#endif
+
+#if defined(BN_MP_INIT_COPY_C)
+   #define BN_MP_COPY_C
+#endif
+
+#if defined(BN_MP_INIT_MULTI_C)
+   #define BN_MP_ERR_C
+   #define BN_MP_INIT_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_INIT_SET_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_SET_C
+#endif
+
+#if defined(BN_MP_INIT_SET_INT_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_SET_INT_C
+#endif
+
+#if defined(BN_MP_INIT_SIZE_C)
+   #define BN_MP_INIT_C
+#endif
+
+#if defined(BN_MP_INVMOD_C)
+   #define BN_MP_ISZERO_C
+   #define BN_MP_ISODD_C
+   #define BN_FAST_MP_INVMOD_C
+   #define BN_MP_INVMOD_SLOW_C
+#endif
+
+#if defined(BN_MP_INVMOD_SLOW_C)
+   #define BN_MP_ISZERO_C
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_MOD_C
+   #define BN_MP_COPY_C
+   #define BN_MP_ISEVEN_C
+   #define BN_MP_SET_C
+   #define BN_MP_DIV_2_C
+   #define BN_MP_ISODD_C
+   #define BN_MP_ADD_C
+   #define BN_MP_SUB_C
+   #define BN_MP_CMP_C
+   #define BN_MP_CMP_D_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_IS_SQUARE_C)
+   #define BN_MP_MOD_D_C
+   #define BN_MP_INIT_SET_INT_C
+   #define BN_MP_MOD_C
+   #define BN_MP_GET_INT_C
+   #define BN_MP_SQRT_C
+   #define BN_MP_SQR_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_JACOBI_C)
+   #define BN_MP_CMP_D_C
+   #define BN_MP_ISZERO_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_CNT_LSB_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_MOD_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_KARATSUBA_MUL_C)
+   #define BN_MP_MUL_C
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_SUB_C
+   #define BN_MP_ADD_C
+   #define BN_MP_LSHD_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_KARATSUBA_SQR_C)
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_SQR_C
+   #define BN_MP_SUB_C
+   #define BN_S_MP_ADD_C
+   #define BN_MP_LSHD_C
+   #define BN_MP_ADD_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_LCM_C)
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_GCD_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_MP_DIV_C
+   #define BN_MP_MUL_C
+   #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_LSHD_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_RSHD_C
+#endif
+
+#if defined(BN_MP_MOD_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_DIV_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_ADD_C
+   #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_MOD_2D_C)
+   #define BN_MP_ZERO_C
+   #define BN_MP_COPY_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MOD_D_C)
+   #define BN_MP_DIV_D_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C)
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_2EXPT_C
+   #define BN_MP_SET_C
+   #define BN_MP_MUL_2_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_REDUCE_C)
+   #define BN_FAST_MP_MONTGOMERY_REDUCE_C
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_SETUP_C)
+#endif
+
+#if defined(BN_MP_MUL_C)
+   #define BN_MP_TOOM_MUL_C
+   #define BN_MP_KARATSUBA_MUL_C
+   #define BN_FAST_S_MP_MUL_DIGS_C
+   #define BN_S_MP_MUL_C
+   #define BN_S_MP_MUL_DIGS_C
+#endif
+
+#if defined(BN_MP_MUL_2_C)
+   #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_MUL_2D_C)
+   #define BN_MP_COPY_C
+   #define BN_MP_GROW_C
+   #define BN_MP_LSHD_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MUL_D_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MULMOD_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_MUL_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_N_ROOT_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_SET_C
+   #define BN_MP_COPY_C
+   #define BN_MP_EXPT_D_C
+   #define BN_MP_MUL_C
+   #define BN_MP_SUB_C
+   #define BN_MP_MUL_D_C
+   #define BN_MP_DIV_C
+   #define BN_MP_CMP_C
+   #define BN_MP_SUB_D_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_NEG_C)
+   #define BN_MP_COPY_C
+   #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_OR_C)
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_FERMAT_C)
+   #define BN_MP_CMP_D_C
+   #define BN_MP_INIT_C
+   #define BN_MP_EXPTMOD_C
+   #define BN_MP_CMP_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_IS_DIVISIBLE_C)
+   #define BN_MP_MOD_D_C
+#endif
+
+#if defined(BN_MP_PRIME_IS_PRIME_C)
+   #define BN_MP_CMP_D_C
+   #define BN_MP_PRIME_IS_DIVISIBLE_C
+   #define BN_MP_INIT_C
+   #define BN_MP_SET_C
+   #define BN_MP_PRIME_MILLER_RABIN_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_MILLER_RABIN_C)
+   #define BN_MP_CMP_D_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_SUB_D_C
+   #define BN_MP_CNT_LSB_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_EXPTMOD_C
+   #define BN_MP_CMP_C
+   #define BN_MP_SQRMOD_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_NEXT_PRIME_C)
+   #define BN_MP_CMP_D_C
+   #define BN_MP_SET_C
+   #define BN_MP_SUB_D_C
+   #define BN_MP_ISEVEN_C
+   #define BN_MP_MOD_D_C
+   #define BN_MP_INIT_C
+   #define BN_MP_ADD_D_C
+   #define BN_MP_PRIME_MILLER_RABIN_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C)
+#endif
+
+#if defined(BN_MP_PRIME_RANDOM_EX_C)
+   #define BN_MP_READ_UNSIGNED_BIN_C
+   #define BN_MP_PRIME_IS_PRIME_C
+   #define BN_MP_SUB_D_C
+   #define BN_MP_DIV_2_C
+   #define BN_MP_MUL_2_C
+   #define BN_MP_ADD_D_C
+#endif
+
+#if defined(BN_MP_RADIX_SIZE_C)
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_ISZERO_C
+   #define BN_MP_DIV_D_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_RADIX_SMAP_C)
+   #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_RAND_C)
+   #define BN_MP_ZERO_C
+   #define BN_MP_ADD_D_C
+   #define BN_MP_LSHD_C
+#endif
+
+#if defined(BN_MP_READ_RADIX_C)
+   #define BN_MP_ZERO_C
+   #define BN_MP_S_RMAP_C
+   #define BN_MP_RADIX_SMAP_C
+   #define BN_MP_MUL_D_C
+   #define BN_MP_ADD_D_C
+   #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_READ_SIGNED_BIN_C)
+   #define BN_MP_READ_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_READ_UNSIGNED_BIN_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_ZERO_C
+   #define BN_MP_MUL_2D_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_REDUCE_C)
+   #define BN_MP_REDUCE_SETUP_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_MUL_C
+   #define BN_S_MP_MUL_HIGH_DIGS_C
+   #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+   #define BN_MP_MOD_2D_C
+   #define BN_S_MP_MUL_DIGS_C
+   #define BN_MP_SUB_C
+   #define BN_MP_CMP_D_C
+   #define BN_MP_SET_C
+   #define BN_MP_LSHD_C
+   #define BN_MP_ADD_C
+   #define BN_MP_CMP_C
+   #define BN_S_MP_SUB_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_MUL_D_C
+   #define BN_S_MP_ADD_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_L_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_MUL_C
+   #define BN_S_MP_ADD_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_SETUP_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_2EXPT_C
+   #define BN_MP_CLEAR_C
+   #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_SETUP_L_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_2EXPT_C
+   #define BN_MP_COUNT_BITS_C
+   #define BN_S_MP_SUB_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_IS_2K_C)
+   #define BN_MP_REDUCE_2K_C
+   #define BN_MP_COUNT_BITS_C
+#endif
+
+#if defined(BN_MP_REDUCE_IS_2K_L_C)
+#endif
+
+#if defined(BN_MP_REDUCE_SETUP_C)
+   #define BN_MP_2EXPT_C
+   #define BN_MP_DIV_C
+#endif
+
+#if defined(BN_MP_RSHD_C)
+   #define BN_MP_ZERO_C
+#endif
+
+#if defined(BN_MP_SET_C)
+   #define BN_MP_ZERO_C
+#endif
+
+#if defined(BN_MP_SET_INT_C)
+   #define BN_MP_ZERO_C
+   #define BN_MP_MUL_2D_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_SHRINK_C)
+#endif
+
+#if defined(BN_MP_SIGNED_BIN_SIZE_C)
+   #define BN_MP_UNSIGNED_BIN_SIZE_C
+#endif
+
+#if defined(BN_MP_SQR_C)
+   #define BN_MP_TOOM_SQR_C
+   #define BN_MP_KARATSUBA_SQR_C
+   #define BN_FAST_S_MP_SQR_C
+   #define BN_S_MP_SQR_C
+#endif
+
+#if defined(BN_MP_SQRMOD_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_SQR_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_SQRT_C)
+   #define BN_MP_N_ROOT_C
+   #define BN_MP_ISZERO_C
+   #define BN_MP_ZERO_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_DIV_C
+   #define BN_MP_ADD_C
+   #define BN_MP_DIV_2_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_SUB_C)
+   #define BN_S_MP_ADD_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_SUB_D_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_ADD_D_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_SUBMOD_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_SUB_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_TO_SIGNED_BIN_C)
+   #define BN_MP_TO_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TO_SIGNED_BIN_N_C)
+   #define BN_MP_SIGNED_BIN_SIZE_C
+   #define BN_MP_TO_SIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TO_UNSIGNED_BIN_C)
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_ISZERO_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_TO_UNSIGNED_BIN_N_C)
+   #define BN_MP_UNSIGNED_BIN_SIZE_C
+   #define BN_MP_TO_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TOOM_MUL_C)
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_MOD_2D_C
+   #define BN_MP_COPY_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_MUL_C
+   #define BN_MP_MUL_2_C
+   #define BN_MP_ADD_C
+   #define BN_MP_SUB_C
+   #define BN_MP_DIV_2_C
+   #define BN_MP_MUL_2D_C
+   #define BN_MP_MUL_D_C
+   #define BN_MP_DIV_3_C
+   #define BN_MP_LSHD_C
+   #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_TOOM_SQR_C)
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_MOD_2D_C
+   #define BN_MP_COPY_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_SQR_C
+   #define BN_MP_MUL_2_C
+   #define BN_MP_ADD_C
+   #define BN_MP_SUB_C
+   #define BN_MP_DIV_2_C
+   #define BN_MP_MUL_2D_C
+   #define BN_MP_MUL_D_C
+   #define BN_MP_DIV_3_C
+   #define BN_MP_LSHD_C
+   #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_TORADIX_C)
+   #define BN_MP_ISZERO_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_DIV_D_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_TORADIX_N_C)
+   #define BN_MP_ISZERO_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_DIV_D_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_UNSIGNED_BIN_SIZE_C)
+   #define BN_MP_COUNT_BITS_C
+#endif
+
+#if defined(BN_MP_XOR_C)
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_ZERO_C)
+#endif
+
+#if defined(BN_PRIME_TAB_C)
+#endif
+
+#if defined(BN_REVERSE_C)
+#endif
+
+#if defined(BN_S_MP_ADD_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_S_MP_EXPTMOD_C)
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_INIT_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_REDUCE_SETUP_C
+   #define BN_MP_REDUCE_C
+   #define BN_MP_REDUCE_2K_SETUP_L_C
+   #define BN_MP_REDUCE_2K_L_C
+   #define BN_MP_MOD_C
+   #define BN_MP_COPY_C
+   #define BN_MP_SQR_C
+   #define BN_MP_MUL_C
+   #define BN_MP_SET_C
+   #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_S_MP_MUL_DIGS_C)
+   #define BN_FAST_S_MP_MUL_DIGS_C
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_MUL_HIGH_DIGS_C)
+   #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_SQR_C)
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_SUB_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BNCORE_C)
+#endif
+
+#ifdef LTM3
+#define LTM_LAST
+#endif
+#include "mpi_superclass.h"
+#include "mpi_class.h"
+#else
+#define LTM_LAST
+#endif
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/mpi_superclass.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/mpi_superclass.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/mpi_superclass.h	(revision 164)
@@ -0,0 +1,95 @@
+/* mpi_superclass.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* super class file for PK algos */
+
+/* default ... include all MPI */
+#define LTM_ALL
+
+/* RSA only (does not support DH/DSA/ECC) */
+/* #define SC_RSA_1 */
+
+/* For reference.... On an Athlon64 optimizing for speed...
+
+   LTM's mpi.o with all functions [striped] is 142KiB in size.
+
+*/
+
+/* Works for RSA only, mpi.o is 68KiB */
+#ifdef SC_RSA_1
+   #define BN_MP_SHRINK_C
+   #define BN_MP_LCM_C
+   #define BN_MP_PRIME_RANDOM_EX_C
+   #define BN_MP_INVMOD_C
+   #define BN_MP_GCD_C
+   #define BN_MP_MOD_C
+   #define BN_MP_MULMOD_C
+   #define BN_MP_ADDMOD_C
+   #define BN_MP_EXPTMOD_C
+   #define BN_MP_SET_INT_C
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_CLEAR_MULTI_C
+   #define BN_MP_UNSIGNED_BIN_SIZE_C
+   #define BN_MP_TO_UNSIGNED_BIN_C
+   #define BN_MP_MOD_D_C
+   #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+   #define BN_REVERSE_C
+   #define BN_PRIME_TAB_C
+
+   /* other modifiers */
+   #define BN_MP_DIV_SMALL                    /* Slower division, not critical */
+
+   /* here we are on the last pass so we turn things off.  The functions classes are still there
+    * but we remove them specifically from the build.  This also invokes tweaks in functions
+    * like removing support for even moduli, etc...
+    */
+#ifdef LTM_LAST
+   #undef  BN_MP_TOOM_MUL_C
+   #undef  BN_MP_TOOM_SQR_C
+   #undef  BN_MP_KARATSUBA_MUL_C
+   #undef  BN_MP_KARATSUBA_SQR_C
+   #undef  BN_MP_REDUCE_C
+   #undef  BN_MP_REDUCE_SETUP_C
+   #undef  BN_MP_DR_IS_MODULUS_C
+   #undef  BN_MP_DR_SETUP_C
+   #undef  BN_MP_DR_REDUCE_C
+   #undef  BN_MP_REDUCE_IS_2K_C
+   #undef  BN_MP_REDUCE_2K_SETUP_C
+   #undef  BN_MP_REDUCE_2K_C
+   #undef  BN_S_MP_EXPTMOD_C
+   #undef  BN_MP_DIV_3_C
+   #undef  BN_S_MP_MUL_HIGH_DIGS_C
+   #undef  BN_FAST_S_MP_MUL_HIGH_DIGS_C
+   #undef  BN_FAST_MP_INVMOD_C
+
+   /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold
+    * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines] 
+    * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without
+    * trouble.  
+    */
+   #undef  BN_S_MP_MUL_DIGS_C
+   #undef  BN_S_MP_SQR_C
+   #undef  BN_MP_MONTGOMERY_REDUCE_C
+#endif
+
+#endif
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/pwdbased.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/pwdbased.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/pwdbased.h	(revision 164)
@@ -0,0 +1,65 @@
+/* pwdbased.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_PWDBASED_H
+#define WOLF_CRYPT_PWDBASED_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifndef NO_PWDBASED
+
+#ifndef NO_MD5
+    #include <wolfssl/wolfcrypt/md5.h>       /* for hash type */
+#endif
+
+#include <wolfssl/wolfcrypt/sha.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+/*
+ * hashType renamed to typeH to avoid shadowing global declation here:
+ * wolfssl/wolfcrypt/asn.h line 173 in enum Oid_Types
+ */
+WOLFSSL_API int wc_PBKDF1(byte* output, const byte* passwd, int pLen,
+                      const byte* salt, int sLen, int iterations, int kLen,
+                      int typeH);
+WOLFSSL_API int wc_PBKDF2(byte* output, const byte* passwd, int pLen,
+                      const byte* salt, int sLen, int iterations, int kLen,
+                      int typeH);
+WOLFSSL_API int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int pLen,
+                            const byte* salt, int sLen, int iterations,
+                            int kLen, int typeH, int purpose);
+
+/* helper functions */
+WOLFSSL_LOCAL int GetDigestSize(int typeH);
+WOLFSSL_LOCAL int GetPKCS12HashSizes(int typeH, word32* v, word32* u);
+WOLFSSL_LOCAL int DoPKCS12Hash(int typeH, byte* buffer, word32 totalLen,
+                               byte* Ai, word32 u, int iterations);
+
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* NO_PWDBASED */
+#endif /* WOLF_CRYPT_PWDBASED_H */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/rabbit.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/rabbit.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/rabbit.h	(revision 164)
@@ -0,0 +1,64 @@
+/* rabbit.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_RABBIT_H
+#define WOLF_CRYPT_RABBIT_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifndef NO_RABBIT
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+enum {
+	RABBIT_ENC_TYPE  = 5     /* cipher unique type */
+};
+
+
+/* Rabbit Context */
+typedef struct RabbitCtx {
+    word32 x[8];
+    word32 c[8];
+    word32 carry;
+} RabbitCtx;
+
+
+/* Rabbit stream cipher */
+typedef struct Rabbit {
+    RabbitCtx masterCtx;
+    RabbitCtx workCtx;
+} Rabbit;
+
+
+WOLFSSL_API int wc_RabbitProcess(Rabbit*, byte*, const byte*, word32);
+WOLFSSL_API int wc_RabbitSetKey(Rabbit*, const byte* key, const byte* iv);
+
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* NO_RABBIT */
+#endif /* WOLF_CRYPT_RABBIT_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/random.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/random.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/random.h	(revision 164)
@@ -0,0 +1,145 @@
+/* random.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef WOLF_CRYPT_RANDOM_H
+#define WOLF_CRYPT_RANDOM_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef HAVE_FIPS
+/* for fips @wc_fips */
+#include <cyassl/ctaocrypt/random.h>
+#endif
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#ifndef HAVE_FIPS /* avoid redefining structs and macros */
+#if defined(WOLFSSL_FORCE_RC4_DRBG) && defined(NO_RC4)
+    #error Cannot have WOLFSSL_FORCE_RC4_DRBG and NO_RC4 defined.
+#endif /* WOLFSSL_FORCE_RC4_DRBG && NO_RC4 */
+#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
+    #ifdef NO_SHA256
+        #error "Hash DRBG requires SHA-256."
+    #endif /* NO_SHA256 */
+
+    #include <wolfssl/wolfcrypt/sha256.h>
+#else /* HAVE_HASHDRBG || NO_RC4 */
+    #include <wolfssl/wolfcrypt/arc4.h>
+#endif /* HAVE_HASHDRBG || NO_RC4 */
+
+#if defined(USE_WINDOWS_API)
+    #if defined(_WIN64)
+        typedef unsigned __int64 ProviderHandle;
+        /* type HCRYPTPROV, avoid #include <windows.h> */
+    #else
+        typedef unsigned long ProviderHandle;
+    #endif
+#endif
+
+
+/* OS specific seeder */
+typedef struct OS_Seed {
+    #if defined(USE_WINDOWS_API)
+        ProviderHandle handle;
+    #else
+        int fd;
+    #endif
+} OS_Seed;
+
+#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
+
+
+#define DRBG_SEED_LEN (440/8)
+
+
+struct DRBG; /* Private DRBG state */
+
+
+/* Hash-based Deterministic Random Bit Generator */
+typedef struct WC_RNG {
+    struct DRBG* drbg;
+    OS_Seed seed;
+    byte status;
+} WC_RNG;
+
+
+#else /* HAVE_HASHDRBG || NO_RC4 */
+
+
+#define WOLFSSL_RNG_CAVIUM_MAGIC 0xBEEF0004
+
+/* secure Random Number Generator */
+
+
+typedef struct WC_RNG {
+    OS_Seed seed;
+    Arc4    cipher;
+#ifdef HAVE_CAVIUM
+    int    devId;           /* nitrox device id */
+    word32 magic;           /* using cavium magic */
+#endif
+} WC_RNG;
+
+
+#endif /* HAVE_HASH_DRBG || NO_RC4 */
+
+#endif /* HAVE_FIPS */
+
+/* NO_OLD_RNGNAME removes RNG struct name to prevent possible type conflicts,
+ * can't be used with CTaoCrypt FIPS */
+#if !defined(NO_OLD_RNGNAME) && !defined(HAVE_FIPS)
+    #define RNG WC_RNG
+#endif
+
+WOLFSSL_LOCAL
+int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz);
+
+#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
+
+#ifdef HAVE_CAVIUM
+    WOLFSSL_API int  wc_InitRngCavium(WC_RNG*, int);
+#endif
+
+#endif /* HAVE_HASH_DRBG || NO_RC4 */
+
+
+WOLFSSL_API int  wc_InitRng(WC_RNG*);
+WOLFSSL_API int  wc_RNG_GenerateBlock(WC_RNG*, byte*, word32 sz);
+WOLFSSL_API int  wc_RNG_GenerateByte(WC_RNG*, byte*);
+WOLFSSL_API int  wc_FreeRng(WC_RNG*);
+
+
+#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
+    WOLFSSL_API int wc_RNG_HealthTest(int reseed,
+                                        const byte* entropyA, word32 entropyASz,
+                                        const byte* entropyB, word32 entropyBSz,
+                                        byte* output, word32 outputSz);
+#endif /* HAVE_HASHDRBG || NO_RC4 */
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* WOLF_CRYPT_RANDOM_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/ripemd.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/ripemd.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/ripemd.h	(revision 164)
@@ -0,0 +1,63 @@
+/* ripemd.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_RIPEMD_H
+#define WOLF_CRYPT_RIPEMD_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef WOLFSSL_RIPEMD
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+/* in bytes */
+enum {
+    RIPEMD             =  3,    /* hash type unique */
+    RIPEMD_BLOCK_SIZE  = 64,
+    RIPEMD_DIGEST_SIZE = 20,
+    RIPEMD_PAD_SIZE    = 56
+};
+
+
+/* RipeMd 160 digest */
+typedef struct RipeMd {
+    word32  buffLen;   /* in bytes          */
+    word32  loLen;     /* length in bytes   */
+    word32  hiLen;     /* length in bytes   */
+    word32  digest[RIPEMD_DIGEST_SIZE / sizeof(word32)];
+    word32  buffer[RIPEMD_BLOCK_SIZE  / sizeof(word32)];
+} RipeMd;
+
+
+WOLFSSL_API void wc_InitRipeMd(RipeMd*);
+WOLFSSL_API void wc_RipeMdUpdate(RipeMd*, const byte*, word32);
+WOLFSSL_API void wc_RipeMdFinal(RipeMd*, byte*);
+
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* WOLFSSL_RIPEMD */
+#endif /* WOLF_CRYPT_RIPEMD_H */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/rsa.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/rsa.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/rsa.h	(revision 164)
@@ -0,0 +1,128 @@
+/* rsa.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_RSA_H
+#define WOLF_CRYPT_RSA_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifndef NO_RSA
+
+/* allow for user to plug in own crypto */
+#if !defined(HAVE_FIPS) && (defined(HAVE_USER_RSA) || defined(HAVE_FAST_RSA))
+    #include "user_rsa.h"
+#else
+
+#ifdef HAVE_FIPS
+/* for fips @wc_fips */
+#include <cyassl/ctaocrypt/rsa.h>
+#if defined(CYASSL_KEY_GEN) && !defined(WOLFSSL_KEY_GEN)
+    #define WOLFSSL_KEY_GEN
+#endif
+#else
+    #include <wolfssl/wolfcrypt/integer.h>
+    #include <wolfssl/wolfcrypt/random.h>
+#endif /* HAVE_FIPS */
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+/* avoid redefinition of structs */
+#if !defined(HAVE_FIPS)
+#define WOLFSSL_RSA_CAVIUM_MAGIC 0xBEEF0006
+
+enum {
+    RSA_PUBLIC   = 0,
+    RSA_PRIVATE  = 1,
+};
+
+
+/* RSA */
+typedef struct RsaKey {
+    mp_int n, e, d, p, q, dP, dQ, u;
+    int   type;                               /* public or private */
+    void* heap;                               /* for user memory overrides */
+#ifdef HAVE_CAVIUM
+    int    devId;           /* nitrox device id */
+    word32 magic;           /* using cavium magic */
+    word64 contextHandle;   /* nitrox context memory handle */
+    byte*  c_n;             /* cavium byte buffers for key parts */
+    byte*  c_e;
+    byte*  c_d;
+    byte*  c_p;
+    byte*  c_q;
+    byte*  c_dP;
+    byte*  c_dQ;
+    byte*  c_u;             /* sizes in bytes */
+    word16 c_nSz, c_eSz, c_dSz, c_pSz, c_qSz, c_dP_Sz, c_dQ_Sz, c_uSz;
+#endif
+} RsaKey;
+#endif /*HAVE_FIPS */
+
+WOLFSSL_API int  wc_InitRsaKey(RsaKey* key, void*);
+WOLFSSL_API int  wc_FreeRsaKey(RsaKey* key);
+
+WOLFSSL_API int  wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
+                                 word32 outLen, RsaKey* key, WC_RNG* rng);
+WOLFSSL_API int  wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out,
+                                        RsaKey* key);
+WOLFSSL_API int  wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
+                                  word32 outLen, RsaKey* key);
+WOLFSSL_API int  wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out,
+                            word32 outLen, RsaKey* key, WC_RNG* rng);
+WOLFSSL_API int  wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out,
+                                    RsaKey* key);
+WOLFSSL_API int  wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out,
+                              word32 outLen, RsaKey* key);
+WOLFSSL_API int  wc_RsaEncryptSize(RsaKey* key);
+
+#ifndef HAVE_FIPS /* to avoid asn duplicate symbols @wc_fips */
+WOLFSSL_API int  wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
+                                                               RsaKey*, word32);
+WOLFSSL_API int  wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx,
+                                                               RsaKey*, word32);
+WOLFSSL_API int  wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz,
+                                        const byte* e, word32 eSz, RsaKey* key);
+#ifdef WOLFSSL_KEY_GEN
+    WOLFSSL_API int wc_RsaKeyToDer(RsaKey*, byte* output, word32 inLen);
+#endif
+#endif /* HAVE_FIPS*/
+WOLFSSL_API int  wc_RsaFlattenPublicKey(RsaKey*, byte*, word32*, byte*,
+                                                                       word32*);
+
+#ifdef WOLFSSL_KEY_GEN
+    WOLFSSL_API int wc_RsaKeyToPublicDer(RsaKey*, byte* output, word32 inLen);
+    WOLFSSL_API int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng);
+#endif
+
+#ifdef HAVE_CAVIUM
+    WOLFSSL_API int  wc_RsaInitCavium(RsaKey*, int);
+    WOLFSSL_API void wc_RsaFreeCavium(RsaKey*);
+#endif
+#endif /* HAVE_USER_RSA */
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* NO_RSA */
+#endif /* WOLF_CRYPT_RSA_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/settings.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/settings.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/settings.h	(revision 164)
@@ -0,0 +1,1007 @@
+/* settings.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Place OS specific preprocessor flags, defines, includes here, will be
+   included into every file because types.h includes it */
+
+
+#ifndef WOLF_CRYPT_SETTINGS_H
+#define WOLF_CRYPT_SETTINGS_H
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+/* Uncomment next line if using IPHONE */
+/* #define IPHONE */
+
+/* Uncomment next line if using ThreadX */
+/* #define THREADX */
+
+/* Uncomment next line if using Micrium ucOS */
+/* #define MICRIUM */
+
+/* Uncomment next line if using Mbed */
+/* #define MBED */
+
+/* Uncomment next line if using Microchip PIC32 ethernet starter kit */
+/* #define MICROCHIP_PIC32 */
+
+/* Uncomment next line if using Microchip TCP/IP stack, version 5 */
+/* #define MICROCHIP_TCPIP_V5 */
+
+/* Uncomment next line if using Microchip TCP/IP stack, version 6 or later */
+/* #define MICROCHIP_TCPIP */
+
+/* Uncomment next line if using PIC32MZ Crypto Engine */
+/* #define WOLFSSL_MICROCHIP_PIC32MZ */
+
+/* Uncomment next line if using FreeRTOS */
+/* #define FREERTOS */
+
+/* Uncomment next line if using FreeRTOS+ TCP */
+/* #define FREERTOS_TCP */
+
+/* Uncomment next line if using FreeRTOS Windows Simulator */
+/* #define FREERTOS_WINSIM */
+
+/* Uncomment next line if using RTIP */
+/* #define EBSNET */
+
+/* Uncomment next line if using lwip */
+#define WOLFSSL_LWIP
+
+/* Uncomment next line if building wolfSSL for a game console */
+/* #define WOLFSSL_GAME_BUILD */
+
+/* Uncomment next line if building wolfSSL for LSR */
+/* #define WOLFSSL_LSR */
+
+/* Uncomment next line if building for Freescale Classic MQX/RTCS/MFS */
+/* #define FREESCALE_MQX */
+
+/* Uncomment next line if building for Freescale KSDK MQX/RTCS/MFS */
+/* #define FREESCALE_KSDK_MQX */
+
+/* Uncomment next line if building for Freescale KSDK Bare Metal */
+/* #define FREESCALE_KSDK_BM */
+
+/* Uncomment next line if building for Freescale FreeRTOS */
+/* #define FREESCALE_FREE_RTOS */
+
+/* Uncomment next line if using STM32F2 */
+/* #define WOLFSSL_STM32F2 */
+
+/* Uncomment next line if using Comverge settings */
+/* #define COMVERGE */
+
+/* Uncomment next line if using QL SEP settings */
+/* #define WOLFSSL_QL */
+
+/* Uncomment next line if building for EROAD */
+/* #define WOLFSSL_EROAD */
+
+/* Uncomment next line if building for IAR EWARM */
+/* #define WOLFSSL_IAR_ARM */
+
+/* Uncomment next line if building for Rowley CrossWorks ARM */
+/* #define WOLFSSL_ROWLEY_ARM */
+
+/* Uncomment next line if using TI-RTOS settings */
+/* #define WOLFSSL_TIRTOS */
+
+/* Uncomment next line if building with PicoTCP */
+/* #define WOLFSSL_PICOTCP */
+
+/* Uncomment next line if building for PicoTCP demo bundle */
+/* #define WOLFSSL_PICOTCP_DEMO */
+
+/* Uncomment next line if building for uITRON4  */
+#define WOLFSSL_uITRON4
+
+/* Uncomment next line if building for uT-Kernel */
+/* #define WOLFSSL_uTKERNEL2 */
+
+/* Uncomment next line if using Max Strength build */
+/* #define WOLFSSL_MAX_STRENGTH */
+
+/* Uncomment next line if building for VxWorks */
+/* #define WOLFSSL_VXWORKS */
+
+/* Uncomment next line to enable deprecated less secure static DH suites */
+/* #define WOLFSSL_STATIC_DH */
+
+/* Uncomment next line to enable deprecated less secure static RSA suites */
+/* #define WOLFSSL_STATIC_RSA */
+
+#define NO_PSK
+#define WOLFSSL_FATFS
+#define NO_WRITEV
+#define NO_MAIN_DRIVER
+#define WOLFSSL_LOW_MEMORY
+#define KEEP_PEER_CERT
+
+#include <wolfssl/wolfcrypt/visibility.h>
+
+#ifdef WOLFSSL_USER_SETTINGS
+    #include <user_settings.h>
+#endif
+
+
+/* make sure old RNG name is used with CTaoCrypt FIPS */
+#ifdef HAVE_FIPS
+    #define WC_RNG RNG
+#endif
+
+
+#ifdef IPHONE
+    #define SIZEOF_LONG_LONG 8
+#endif
+
+
+#ifdef COMVERGE
+    #define THREADX
+    #define HAVE_NETX
+    #define WOLFSSL_USER_IO
+    #define NO_WRITEV
+    #define NO_DEV_RANDOM
+    #define NO_FILESYSTEM
+    #define NO_SHA512
+    #define NO_DH
+    #define NO_DSA
+    #define NO_HC128
+    #define NO_RSA
+    #define NO_SESSION_CACHE
+    #define HAVE_ECC
+#endif
+
+
+#ifdef THREADX
+    #define SIZEOF_LONG_LONG 8
+#endif
+
+#ifdef HAVE_NETX
+    #include "nx_api.h"
+#endif
+
+#if defined(HAVE_LWIP_NATIVE) /* using LwIP native TCP socket */
+    #define WOLFSSL_LWIP
+    #define NO_WRITEV
+    #define SINGLE_THREADED
+    #define WOLFSSL_USER_IO
+    #define NO_FILESYSTEM
+#endif
+
+#if defined(WOLFSSL_IAR_ARM) || defined(WOLFSSL_ROWLEY_ARM)
+    #define NO_MAIN_DRIVER
+    #define SINGLE_THREADED
+    #define USE_CERT_BUFFERS_1024
+    #define BENCH_EMBEDDED
+    #define NO_FILESYSTEM
+    #define NO_WRITEV
+    #define WOLFSSL_USER_IO
+    #define BENCH_EMBEDDED
+#endif
+
+#ifdef MICROCHIP_PIC32
+    /* #define WOLFSSL_MICROCHIP_PIC32MZ */
+    #define SIZEOF_LONG_LONG 8
+    #define SINGLE_THREADED
+    #define WOLFSSL_USER_IO
+    #define NO_WRITEV
+    #define NO_DEV_RANDOM
+    #define NO_FILESYSTEM
+    #define USE_FAST_MATH
+    #define TFM_TIMING_RESISTANT
+    #define NEED_AES_TABLES
+    #define WOLFSSL_HAVE_MIN
+#endif
+
+#ifdef WOLFSSL_MICROCHIP_PIC32MZ
+    #define WOLFSSL_PIC32MZ_CE
+    #define WOLFSSL_PIC32MZ_CRYPT
+    #define HAVE_AES_ENGINE
+    #define WOLFSSL_PIC32MZ_RNG
+    /* #define WOLFSSL_PIC32MZ_HASH */
+    #define WOLFSSL_AES_COUNTER
+    #define HAVE_AESGCM
+    #define NO_BIG_INT
+#endif
+
+#ifdef MICROCHIP_TCPIP_V5
+    /* include timer functions */
+    #include "TCPIP Stack/TCPIP.h"
+#endif
+
+#ifdef MICROCHIP_TCPIP
+    /* include timer, NTP functions */
+    #ifdef MICROCHIP_MPLAB_HARMONY
+        #include "tcpip/tcpip.h"
+    #else
+        #include "system/system_services.h"
+        #include "tcpip/sntp.h"
+    #endif
+#endif
+
+#ifdef MBED
+    #define WOLFSSL_USER_IO
+    #define NO_FILESYSTEM
+    #define NO_CERT
+    #define USE_CERT_BUFFERS_1024
+    #define NO_WRITEV
+    #define NO_DEV_RANDOM
+    #define NO_SHA512
+    #define NO_DH
+    #define NO_DSA
+    #define NO_HC128
+    #define HAVE_ECC
+    #define NO_SESSION_CACHE
+    #define WOLFSSL_CMSIS_RTOS
+#endif
+
+
+#ifdef WOLFSSL_EROAD
+    #define FREESCALE_MQX
+    #define FREESCALE_MMCAU
+    #define SINGLE_THREADED
+    #define NO_STDIO_FILESYSTEM
+    #define WOLFSSL_LEANPSK
+    #define HAVE_NULL_CIPHER
+    #define NO_OLD_TLS
+    #define NO_ASN
+    #define NO_BIG_INT
+    #define NO_RSA
+    #define NO_DSA
+    #define NO_DH
+    #define NO_CERTS
+    #define NO_PWDBASED
+    #define NO_DES3
+    #define NO_MD4
+    #define NO_RC4
+    #define NO_MD5
+    #define NO_SESSION_CACHE
+    #define NO_MAIN_DRIVER
+#endif
+
+#ifdef WOLFSSL_PICOTCP
+    #ifndef errno
+        #define errno pico_err
+    #endif
+    #include "pico_defines.h"
+    #include "pico_stack.h"
+    #include "pico_constants.h"
+    #include "pico_protocol.h"
+    #define CUSTOM_RAND_GENERATE pico_rand
+#endif
+
+#ifdef WOLFSSL_PICOTCP_DEMO
+    #define WOLFSSL_STM32
+    #define USE_FAST_MATH
+    #define TFM_TIMING_RESISTANT
+    #define XMALLOC(s, h, type)  PICO_ZALLOC((s))
+    #define XFREE(p, h, type)    PICO_FREE((p))
+    #define SINGLE_THREADED
+    #define NO_WRITEV
+    #define WOLFSSL_USER_IO
+    #define NO_DEV_RANDOM
+    #define NO_FILESYSTEM
+#endif
+
+#ifdef FREERTOS_WINSIM
+    #define FREERTOS
+    #define USE_WINDOWS_API
+#endif
+
+
+#ifdef WOLFSSL_VXWORKS
+    #define NO_DEV_RANDOM
+    #define NO_WRITEV
+#endif
+
+
+/* Micrium will use Visual Studio for compilation but not the Win32 API */
+#if defined(_WIN32) && !defined(MICRIUM) && !defined(FREERTOS) && !defined(FREERTOS_TCP)\
+        && !defined(EBSNET) && !defined(WOLFSSL_EROAD) && !defined(WOLFSSL_uITRON4)
+    #define USE_WINDOWS_API
+#endif
+
+#if defined(WOLFSSL_uITRON4)
+
+#define XMALLOC_USER
+#include <stddef.h>
+#define ITRON_POOL_SIZE 1024*20
+extern int uITRON4_minit(size_t poolsz) ;
+extern void *uITRON4_malloc(size_t sz) ;
+extern void *uITRON4_realloc(void *p, size_t sz) ;
+extern void uITRON4_free(void *p) ;
+
+#define XMALLOC(sz, heap, type)     uITRON4_malloc(sz)
+#define XREALLOC(p, sz, heap, type) uITRON4_realloc(p, sz)
+#define XFREE(p, heap, type)        uITRON4_free(p)
+#endif
+
+#if defined(WOLFSSL_uTKERNEL2)
+#define WOLFSSL_CLOSESOCKET
+#define XMALLOC_USER
+int uTKernel_init_mpool(unsigned int sz) ; /* initializing malloc pool */
+void *uTKernel_malloc(unsigned int sz) ;
+void *uTKernel_realloc(void *p, unsigned int sz) ;
+void   uTKernel_free(void *p) ;
+#define XMALLOC(s, h, type) uTKernel_malloc((s))
+#define XREALLOC(p, n, h, t)  uTKernel_realloc((p), (n))
+#define XFREE(p, h, type)  uTKernel_free((p))
+
+#include <stdio.h>
+#include    "tm/tmonitor.h"
+static char *fgets(char *buff, int sz, XFILE fp)
+/*static char * gets(char *buff)*/
+{
+    char * p = buff ;
+    *p = '\0' ;
+    while(1) {
+        *p = tm_getchar(-1) ;
+        tm_putchar(*p) ;
+        if(*p == '\r') {
+            tm_putchar('\n') ;
+            *p = '\0' ;
+            break ;
+        }
+        p ++ ;
+    }
+    return buff ;
+}
+
+#endif
+
+
+#if defined(WOLFSSL_LEANPSK) && !defined(XMALLOC_USER)
+    #include <stdlib.h>
+    #define XMALLOC(s, h, type)  malloc((s))
+    #define XFREE(p, h, type)    free((p))
+    #define XREALLOC(p, n, h, t) realloc((p), (n))
+#endif
+
+#if defined(XMALLOC_USER) && defined(SSN_BUILDING_LIBYASSL)
+    #undef  XMALLOC
+    #define XMALLOC     yaXMALLOC
+    #undef  XFREE
+    #define XFREE       yaXFREE
+    #undef  XREALLOC
+    #define XREALLOC    yaXREALLOC
+#endif
+
+
+#ifdef FREERTOS
+    #include "FreeRTOS.h"
+
+    /* FreeRTOS pvPortRealloc() only in AVR32_UC3 port */
+    #if !defined(XMALLOC_USER) && !defined(NO_WOLFSSL_MEMORY)
+        #define XMALLOC(s, h, type)  pvPortMalloc((s))
+        #define XFREE(p, h, type)    vPortFree((p))
+    #endif
+
+    #ifndef NO_WRITEV
+        #define NO_WRITEV
+    #endif
+    #ifndef HAVE_SHA512
+        #ifndef NO_SHA512
+            #define NO_SHA512
+        #endif
+    #endif
+    #ifndef HAVE_DH
+        #ifndef NO_DH
+            #define NO_DH
+        #endif
+    #endif
+    #ifndef NO_DSA
+        #define NO_DSA
+    #endif
+    #ifndef NO_HC128
+        #define NO_HC128
+    #endif
+
+    #ifndef SINGLE_THREADED
+        #include "semphr.h"
+    #endif
+#endif
+
+#ifdef FREERTOS_TCP
+
+#if !defined(NO_WOLFSSL_MEMORY) && !defined(XMALLOC_USER)
+#define XMALLOC(s, h, type)  pvPortMalloc((s))
+#define XFREE(p, h, type)    vPortFree((p))
+#endif
+
+#define WOLFSSL_GENSEED_FORTEST
+
+#define NO_WOLFSSL_DIR
+#define NO_WRITEV
+#define WOLFSSL_HAVE_MIN
+#define USE_FAST_MATH
+#define TFM_TIMING_REGISTANT
+#define NO_MAIN_DRIVER
+
+#endif
+
+#ifdef WOLFSSL_TIRTOS
+    #define SIZEOF_LONG_LONG 8
+    #define NO_WRITEV
+    #define NO_WOLFSSL_DIR
+    #define USE_FAST_MATH
+    #define TFM_TIMING_RESISTANT
+    #define NO_DEV_RANDOM
+    #define NO_FILESYSTEM
+    #define USE_CERT_BUFFERS_2048
+    #define NO_ERROR_STRINGS
+    #define USER_TIME
+
+    #ifdef __IAR_SYSTEMS_ICC__
+        #pragma diag_suppress=Pa089
+    #elif !defined(__GNUC__)
+        /* Suppress the sslpro warning */
+        #pragma diag_suppress=11
+    #endif
+
+    #include <ti/sysbios/hal/Seconds.h>
+#endif
+
+#ifdef EBSNET
+    #include "rtip.h"
+
+    /* #define DEBUG_WOLFSSL */
+    #define NO_WOLFSSL_DIR  /* tbd */
+
+    #if (POLLOS)
+        #define SINGLE_THREADED
+    #endif
+
+    #if (RTPLATFORM)
+        #if (!RTP_LITTLE_ENDIAN)
+            #define BIG_ENDIAN_ORDER
+        #endif
+    #else
+        #if (!KS_LITTLE_ENDIAN)
+            #define BIG_ENDIAN_ORDER
+        #endif
+    #endif
+
+    #if (WINMSP3)
+        #undef SIZEOF_LONG
+        #define SIZEOF_LONG_LONG 8
+    #else
+        #sslpro: settings.h - please implement SIZEOF_LONG and SIZEOF_LONG_LONG
+    #endif
+
+    #define XMALLOC(s, h, type) ((void *)rtp_malloc((s), SSL_PRO_MALLOC))
+    #define XFREE(p, h, type) (rtp_free(p))
+    #define XREALLOC(p, n, h, t) realloc((p), (n))
+
+#endif /* EBSNET */
+
+#ifdef WOLFSSL_GAME_BUILD
+    #define SIZEOF_LONG_LONG 8
+    #if defined(__PPU) || defined(__XENON)
+        #define BIG_ENDIAN_ORDER
+    #endif
+#endif
+
+#ifdef WOLFSSL_LSR
+    #define HAVE_WEBSERVER
+    #define SIZEOF_LONG_LONG 8
+    #define WOLFSSL_LOW_MEMORY
+    #define NO_WRITEV
+    #define NO_SHA512
+    #define NO_DH
+    #define NO_DSA
+    #define NO_HC128
+    #define NO_DEV_RANDOM
+    #define NO_WOLFSSL_DIR
+    #define NO_RABBIT
+    #ifndef NO_FILESYSTEM
+        #define LSR_FS
+        #include "inc/hw_types.h"
+        #include "fs.h"
+    #endif
+    #define WOLFSSL_LWIP
+    #include <errno.h>  /* for tcp errno */
+    #define WOLFSSL_SAFERTOS
+    #if defined(__IAR_SYSTEMS_ICC__)
+        /* enum uses enum */
+        #pragma diag_suppress=Pa089
+    #endif
+#endif
+
+#ifdef WOLFSSL_SAFERTOS
+    #ifndef SINGLE_THREADED
+        #include "SafeRTOS/semphr.h"
+    #endif
+
+    #include "SafeRTOS/heap.h"
+    #define XMALLOC(s, h, type)  pvPortMalloc((s))
+    #define XFREE(p, h, type)    vPortFree((p))
+    #define XREALLOC(p, n, h, t) pvPortRealloc((p), (n))
+#endif
+
+#ifdef WOLFSSL_LOW_MEMORY
+    #undef  RSA_LOW_MEM
+    #define RSA_LOW_MEM
+    #undef  WOLFSSL_SMALL_STACK
+    #define WOLFSSL_SMALL_STACK
+    #undef  TFM_TIMING_RESISTANT
+    #define TFM_TIMING_RESISTANT
+#endif
+
+#ifdef FREESCALE_MQX
+    #define FREESCALE_COMMON
+    #include "mqx.h"
+    #ifndef NO_FILESYSTEM
+        #include "mfs.h"
+        #if MQX_USE_IO_OLD
+            #include "fio.h"
+        #else
+            #include "nio.h"
+        #endif
+    #endif
+    #ifndef SINGLE_THREADED
+        #include "mutex.h"
+    #endif
+
+    #define XMALLOC(s, h, t)    (void *)_mem_alloc_system((s))
+    #define XFREE(p, h, t)      {void* xp = (p); if ((xp)) _mem_free((xp));}
+    /* Note: MQX has no realloc, using fastmath above */
+#endif
+
+#ifdef FREESCALE_KSDK_MQX
+    #define FREESCALE_COMMON
+    #include <mqx.h>
+    #ifndef NO_FILESYSTEM
+        #if MQX_USE_IO_OLD
+            #include <fio.h>
+        #else
+            #include <stdio.h>
+            #include <nio.h>
+        #endif
+    #endif
+    #ifndef SINGLE_THREADED
+        #include <mutex.h>
+    #endif
+
+    #define XMALLOC(s, h, t)    (void *)_mem_alloc_system((s))
+    #define XFREE(p, h, t)      {void* xp = (p); if ((xp)) _mem_free((xp));}
+    #define XREALLOC(p, n, h, t) _mem_realloc((p), (n)) /* since MQX 4.1.2 */
+#endif
+
+#ifdef FREESCALE_KSDK_BM
+    #define FREESCALE_COMMON
+    #define WOLFSSL_USER_IO
+    #define SINGLE_THREADED
+    #define NO_FILESYSTEM
+    #define USE_WOLFSSL_MEMORY
+#endif
+
+#ifdef FREESCALE_FREE_RTOS
+    #define FREESCALE_COMMON
+    #define NO_FILESYSTEM
+    #define NO_MAIN_DRIVER
+    #define XMALLOC(s, h, t)  OSA_MemAlloc(s);
+    #define XFREE(p, h, t)    {void* xp = (p); if((xp)) OSA_MemFree((xp));}
+    #define XREALLOC(p, n, h, t) ksdk_realloc((p), (n), (h), (t));
+    #ifdef FREESCALE_KSDK_BM
+        #error Baremetal and FreeRTOS cannot be both enabled at the same time!
+    #endif
+    #ifndef SINGLE_THREADED
+        #include "FreeRTOS.h"
+        #include "semphr.h"
+    #endif
+#endif
+
+#ifdef FREESCALE_COMMON
+    #define SIZEOF_LONG_LONG 8
+    #define NO_WRITEV
+    #define NO_DEV_RANDOM
+    #define NO_RABBIT
+    #define NO_WOLFSSL_DIR
+    #define USE_FAST_MATH
+    #define TFM_TIMING_RESISTANT
+
+    #if FSL_FEATURE_SOC_ENET_COUNT == 0
+        #define WOLFSSL_USER_IO
+    #endif
+
+    /* random seed */
+    #define NO_OLD_RNGNAME
+    #if FSL_FEATURE_SOC_TRNG_COUNT > 0
+        #define FREESCALE_TRNG
+    #elif !defined(FREESCALE_KSDK_BM) && !defined(FREESCALE_FREE_RTOS)
+        #define FREESCALE_K70_RNGA
+        /* #define FREESCALE_K53_RNGB */
+    #endif
+
+    /* HW crypto */
+    /* #define FREESCALE_MMCAU */
+#endif
+
+#ifdef WOLFSSL_STM32F2
+    #define SIZEOF_LONG_LONG 8
+    #define NO_DEV_RANDOM
+    #define NO_WOLFSSL_DIR
+    #define NO_RABBIT
+    #define STM32F2_RNG
+    #define STM32F2_CRYPTO
+    #define KEIL_INTRINSICS
+#endif
+
+#ifdef MICRIUM
+
+    #include "stdlib.h"
+    #include "net_cfg.h"
+    #include "ssl_cfg.h"
+    #include "net_secure_os.h"
+
+    #define WOLFSSL_TYPES
+
+    typedef CPU_INT08U byte;
+    typedef CPU_INT16U word16;
+    typedef CPU_INT32U word32;
+
+    #if (NET_SECURE_MGR_CFG_WORD_SIZE == CPU_WORD_SIZE_32)
+        #define SIZEOF_LONG        4
+        #undef  SIZEOF_LONG_LONG
+    #else
+        #undef  SIZEOF_LONG
+        #define SIZEOF_LONG_LONG   8
+    #endif
+
+    #define STRING_USER
+
+    #define XSTRLEN(pstr) ((CPU_SIZE_T)Str_Len((CPU_CHAR *)(pstr)))
+    #define XSTRNCPY(pstr_dest, pstr_src, len_max) \
+                    ((CPU_CHAR *)Str_Copy_N((CPU_CHAR *)(pstr_dest), \
+                     (CPU_CHAR *)(pstr_src), (CPU_SIZE_T)(len_max)))
+    #define XSTRNCMP(pstr_1, pstr_2, len_max) \
+                    ((CPU_INT16S)Str_Cmp_N((CPU_CHAR *)(pstr_1), \
+                     (CPU_CHAR *)(pstr_2), (CPU_SIZE_T)(len_max)))
+    #define XSTRSTR(pstr, pstr_srch) \
+                    ((CPU_CHAR *)Str_Str((CPU_CHAR *)(pstr), \
+                     (CPU_CHAR *)(pstr_srch)))
+    #define XMEMSET(pmem, data_val, size) \
+                    ((void)Mem_Set((void *)(pmem), (CPU_INT08U) (data_val), \
+                    (CPU_SIZE_T)(size)))
+    #define XMEMCPY(pdest, psrc, size) ((void)Mem_Copy((void *)(pdest), \
+                     (void *)(psrc), (CPU_SIZE_T)(size)))
+    #define XMEMCMP(pmem_1, pmem_2, size) \
+                   (((CPU_BOOLEAN)Mem_Cmp((void *)(pmem_1), (void *)(pmem_2), \
+                     (CPU_SIZE_T)(size))) ? DEF_NO : DEF_YES)
+    #define XMEMMOVE XMEMCPY
+
+#if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
+    #define MICRIUM_MALLOC
+    #define XMALLOC(s, h, type) ((void *)NetSecure_BlkGet((CPU_INT08U)(type), \
+                                 (CPU_SIZE_T)(s), (void *)0))
+    #define XFREE(p, h, type)   (NetSecure_BlkFree((CPU_INT08U)(type), \
+                                 (p), (void *)0))
+    #define XREALLOC(p, n, h, t) realloc((p), (n))
+#endif
+
+    #if (NET_SECURE_MGR_CFG_FS_EN == DEF_ENABLED)
+        #undef  NO_FILESYSTEM
+    #else
+        #define NO_FILESYSTEM
+    #endif
+
+    #if (SSL_CFG_TRACE_LEVEL == WOLFSSL_TRACE_LEVEL_DBG)
+        #define DEBUG_WOLFSSL
+    #else
+        #undef  DEBUG_WOLFSSL
+    #endif
+
+    #if (SSL_CFG_OPENSSL_EN == DEF_ENABLED)
+        #define OPENSSL_EXTRA
+    #else
+        #undef  OPENSSL_EXTRA
+    #endif
+
+    #if (SSL_CFG_MULTI_THREAD_EN == DEF_ENABLED)
+        #undef  SINGLE_THREADED
+    #else
+        #define SINGLE_THREADED
+    #endif
+
+    #if (SSL_CFG_DH_EN == DEF_ENABLED)
+        #undef  NO_DH
+    #else
+        #define NO_DH
+    #endif
+
+    #if (SSL_CFG_DSA_EN == DEF_ENABLED)
+        #undef  NO_DSA
+    #else
+        #define NO_DSA
+    #endif
+
+    #if (SSL_CFG_PSK_EN == DEF_ENABLED)
+        #undef  NO_PSK
+    #else
+        #define NO_PSK
+    #endif
+
+    #if (SSL_CFG_3DES_EN == DEF_ENABLED)
+        #undef  NO_DES
+    #else
+        #define NO_DES
+    #endif
+
+    #if (SSL_CFG_AES_EN == DEF_ENABLED)
+        #undef  NO_AES
+    #else
+        #define NO_AES
+    #endif
+
+    #if (SSL_CFG_RC4_EN == DEF_ENABLED)
+        #undef  NO_RC4
+    #else
+        #define NO_RC4
+    #endif
+
+    #if (SSL_CFG_RABBIT_EN == DEF_ENABLED)
+        #undef  NO_RABBIT
+    #else
+        #define NO_RABBIT
+    #endif
+
+    #if (SSL_CFG_HC128_EN == DEF_ENABLED)
+        #undef  NO_HC128
+    #else
+        #define NO_HC128
+    #endif
+
+    #if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG)
+        #define BIG_ENDIAN_ORDER
+    #else
+        #undef  BIG_ENDIAN_ORDER
+        #define LITTLE_ENDIAN_ORDER
+    #endif
+
+    #if (SSL_CFG_MD4_EN == DEF_ENABLED)
+        #undef  NO_MD4
+    #else
+        #define NO_MD4
+    #endif
+
+    #if (SSL_CFG_WRITEV_EN == DEF_ENABLED)
+        #undef  NO_WRITEV
+    #else
+        #define NO_WRITEV
+    #endif
+
+    #if (SSL_CFG_USER_RNG_SEED_EN == DEF_ENABLED)
+        #define NO_DEV_RANDOM
+    #else
+        #undef  NO_DEV_RANDOM
+    #endif
+
+    #if (SSL_CFG_USER_IO_EN == DEF_ENABLED)
+        #define WOLFSSL_USER_IO
+    #else
+        #undef  WOLFSSL_USER_IO
+    #endif
+
+    #if (SSL_CFG_DYNAMIC_BUFFERS_EN == DEF_ENABLED)
+        #undef  LARGE_STATIC_BUFFERS
+        #undef  STATIC_CHUNKS_ONLY
+    #else
+        #define LARGE_STATIC_BUFFERS
+        #define STATIC_CHUNKS_ONLY
+    #endif
+
+    #if (SSL_CFG_DER_LOAD_EN == DEF_ENABLED)
+        #define  WOLFSSL_DER_LOAD
+    #else
+        #undef   WOLFSSL_DER_LOAD
+    #endif
+
+    #if (SSL_CFG_DTLS_EN == DEF_ENABLED)
+        #define  WOLFSSL_DTLS
+    #else
+        #undef   WOLFSSL_DTLS
+    #endif
+
+    #if (SSL_CFG_CALLBACKS_EN == DEF_ENABLED)
+         #define WOLFSSL_CALLBACKS
+    #else
+         #undef  WOLFSSL_CALLBACKS
+    #endif
+
+    #if (SSL_CFG_FAST_MATH_EN == DEF_ENABLED)
+         #define USE_FAST_MATH
+    #else
+         #undef  USE_FAST_MATH
+    #endif
+
+    #if (SSL_CFG_TFM_TIMING_RESISTANT_EN == DEF_ENABLED)
+         #define TFM_TIMING_RESISTANT
+    #else
+         #undef  TFM_TIMING_RESISTANT
+    #endif
+
+#endif /* MICRIUM */
+
+
+#ifdef WOLFSSL_QL
+    #ifndef WOLFSSL_SEP
+        #define WOLFSSL_SEP
+    #endif
+    #ifndef OPENSSL_EXTRA
+        #define OPENSSL_EXTRA
+    #endif
+    #ifndef SESSION_CERTS
+        #define SESSION_CERTS
+    #endif
+    #ifndef HAVE_AESCCM
+        #define HAVE_AESCCM
+    #endif
+    #ifndef ATOMIC_USER
+        #define ATOMIC_USER
+    #endif
+    #ifndef WOLFSSL_DER_LOAD
+        #define WOLFSSL_DER_LOAD
+    #endif
+    #ifndef KEEP_PEER_CERT
+        #define KEEP_PEER_CERT
+    #endif
+    #ifndef HAVE_ECC
+        #define HAVE_ECC
+    #endif
+    #ifndef SESSION_INDEX
+        #define SESSION_INDEX
+    #endif
+#endif /* WOLFSSL_QL */
+
+
+#if !defined(XMALLOC_USER) && !defined(MICRIUM_MALLOC) && \
+    !defined(WOLFSSL_LEANPSK) && !defined(NO_WOLFSSL_MEMORY)
+    #define USE_WOLFSSL_MEMORY
+#endif
+
+
+#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS)
+    #undef  KEEP_PEER_CERT
+    #define KEEP_PEER_CERT
+#endif
+
+
+/* stream ciphers except arc4 need 32bit alignment, intel ok without */
+#ifndef XSTREAM_ALIGN
+    #if defined(__x86_64__) || defined(__ia64__) || defined(__i386__)
+        #define NO_XSTREAM_ALIGN
+    #else
+        #define XSTREAM_ALIGN
+    #endif
+#endif
+
+
+/* FreeScale MMCAU hardware crypto has 4 byte alignment */
+#ifdef FREESCALE_MMCAU
+    #define WOLFSSL_MMCAU_ALIGNMENT 4
+#endif
+
+/* if using hardware crypto and have alignment requirements, specify the
+   requirement here.  The record header of SSL/TLS will prvent easy alignment.
+   This hint tries to help as much as possible.  */
+#ifndef WOLFSSL_GENERAL_ALIGNMENT
+    #ifdef WOLFSSL_AESNI
+        #define WOLFSSL_GENERAL_ALIGNMENT 16
+    #elif defined(XSTREAM_ALIGN)
+        #define WOLFSSL_GENERAL_ALIGNMENT  4
+    #elif defined(FREESCALE_MMCAU)
+        #define WOLFSSL_GENERAL_ALIGNMENT  WOLFSSL_MMCAU_ALIGNMENT
+    #else
+        #define WOLFSSL_GENERAL_ALIGNMENT  0
+    #endif
+#endif
+
+#if defined(WOLFSSL_GENERAL_ALIGNMENT) && (WOLFSSL_GENERAL_ALIGNMENT > 0)
+    #if defined(_MSC_VER)
+        #define XGEN_ALIGN __declspec(align(WOLFSSL_GENERAL_ALIGNMENT))
+    #elif defined(__GNUC__)
+        #define XGEN_ALIGN __attribute__((aligned(WOLFSSL_GENERAL_ALIGNMENT)))
+    #else
+        #define XGEN_ALIGN
+    #endif
+#else
+    #define XGEN_ALIGN
+#endif
+
+#ifdef HAVE_CRL
+    /* not widely supported yet */
+    #undef NO_SKID
+    #define NO_SKID
+#endif
+
+
+#ifdef __INTEL_COMPILER
+    #pragma warning(disable:2259) /* explicit casts to smaller sizes, disable */
+#endif
+
+/* user can specify what curves they want with ECC_USER_CURVES otherwise
+ * all curves are on by default for now */
+#ifndef ECC_USER_CURVES
+    #ifndef HAVE_ALL_CURVES
+        #define HAVE_ALL_CURVES
+    #endif
+#endif
+
+/* if desktop type system and fastmath increase default max bits */
+#ifdef WOLFSSL_X86_64_BUILD
+    #ifdef USE_FAST_MATH
+        #ifndef FP_MAX_BITS
+            #define FP_MAX_BITS 8192
+        #endif
+    #endif
+#endif
+
+/* If using the max strength build, ensure OLD TLS is disabled. */
+#ifdef WOLFSSL_MAX_STRENGTH
+    #undef NO_OLD_TLS
+    #define NO_OLD_TLS
+#endif
+
+/* If not forcing to use ARC4 as the DRBG, always enable Hash_DRBG */
+#undef HAVE_HASHDRBG
+#ifndef WOLFSSL_FORCE_RC4_DRBG
+    #define HAVE_HASHDRBG
+#endif
+
+
+/* sniffer requires:
+ * static RSA cipher suites
+ * session stats and peak stats
+ */
+#ifdef WOLFSSL_SNIFFER
+    #ifndef WOLFSSL_STATIC_RSA
+        #define WOLFSSL_STATIC_RSA
+    #endif
+    #ifndef WOLFSSL_SESSION_STATS
+        #define WOLFSSL_SESSION_STATS
+    #endif
+    #ifndef WOLFSSL_PEAK_SESSIONS
+        #define WOLFSSL_PEAK_SESSIONS
+    #endif
+#endif
+
+/* Certificate Request Extensions needs decode extras */
+#ifdef WOLFSSL_CERT_EXT
+    #ifndef RSA_DECODE_EXTRA
+        #define RSA_DECODE_EXTRA
+    #endif
+    #ifndef ECC_DECODE_EXTRA
+        #define ECC_DECODE_EXTRA
+    #endif
+#endif
+
+/* Place any other flags or defines here */
+
+
+#ifdef __cplusplus
+    }   /* extern "C" */
+#endif
+
+#endif
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/sha.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/sha.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/sha.h	(revision 164)
@@ -0,0 +1,86 @@
+/* sha.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_SHA_H
+#define WOLF_CRYPT_SHA_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifndef NO_SHA
+
+#ifdef HAVE_FIPS
+/* for fips @wc_fips */
+#include <cyassl/ctaocrypt/sha.h>
+#endif
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#ifndef HAVE_FIPS /* avoid redefining structs */
+/* in bytes */
+enum {
+#ifdef STM32F2_HASH
+    SHA_REG_SIZE     =  4,    /* STM32 register size, bytes */
+#endif
+    SHA              =  1,    /* hash type unique */
+    SHA_BLOCK_SIZE   = 64,
+    SHA_DIGEST_SIZE  = 20,
+    SHA_PAD_SIZE     = 56
+};
+
+#ifdef WOLFSSL_PIC32MZ_HASH
+#include "port/pic32/pic32mz-crypt.h"
+#endif
+
+#ifndef WOLFSSL_TI_HASH
+      
+/* Sha digest */
+typedef struct Sha {
+    word32  buffLen;   /* in bytes          */
+    word32  loLen;     /* length in bytes   */
+    word32  hiLen;     /* length in bytes   */
+    word32  buffer[SHA_BLOCK_SIZE  / sizeof(word32)];
+    #ifndef WOLFSSL_PIC32MZ_HASH
+        word32  digest[SHA_DIGEST_SIZE / sizeof(word32)];
+    #else
+        word32  digest[PIC32_HASH_SIZE / sizeof(word32)];
+        pic32mz_desc desc; /* Crypt Engine descripter */
+    #endif
+} Sha;
+
+#else /* WOLFSSL_TI_HASH */
+    #include "wolfssl/wolfcrypt/port/ti/ti-hash.h"
+#endif
+
+#endif /* HAVE_FIPS */
+
+WOLFSSL_API int wc_InitSha(Sha*);
+WOLFSSL_API int wc_ShaUpdate(Sha*, const byte*, word32);
+WOLFSSL_API int wc_ShaFinal(Sha*, byte*);
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* NO_SHA */
+#endif /* WOLF_CRYPT_SHA_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/sha256.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/sha256.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/sha256.h	(revision 164)
@@ -0,0 +1,84 @@
+/* sha256.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* code submitted by raphael.huck@efixo.com */
+
+#ifndef WOLF_CRYPT_SHA256_H
+#define WOLF_CRYPT_SHA256_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifndef NO_SHA256
+
+#ifdef HAVE_FIPS
+    /* for fips @wc_fips */
+    #include <cyassl/ctaocrypt/sha256.h>
+#endif
+
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#ifndef HAVE_FIPS /* avoid redefinition of structs */
+#ifdef WOLFSSL_PIC32MZ_HASH
+    #include "port/pic32/pic32mz-crypt.h"
+#endif
+
+/* in bytes */
+enum {
+    SHA256              =  2,   /* hash type unique */
+    SHA256_BLOCK_SIZE   = 64,
+    SHA256_DIGEST_SIZE  = 32,
+    SHA256_PAD_SIZE     = 56
+};
+
+#ifndef WOLFSSL_TI_HASH
+
+/* Sha256 digest */
+typedef struct Sha256 {
+    word32  buffLen;   /* in bytes          */
+    word32  loLen;     /* length in bytes   */
+    word32  hiLen;     /* length in bytes   */
+    word32  digest[SHA256_DIGEST_SIZE / sizeof(word32)];
+    word32  buffer[SHA256_BLOCK_SIZE  / sizeof(word32)];
+    #ifdef WOLFSSL_PIC32MZ_HASH
+        pic32mz_desc desc ; /* Crypt Engine descripter */
+    #endif
+} Sha256;
+
+#else /* WOLFSSL_TI_HASH */
+    #include "wolfssl/wolfcrypt/port/ti/ti-hash.h"
+#endif
+
+#endif /* HAVE_FIPS */
+
+WOLFSSL_API int wc_InitSha256(Sha256*);
+WOLFSSL_API int wc_Sha256Update(Sha256*, const byte*, word32);
+WOLFSSL_API int wc_Sha256Final(Sha256*, byte*);
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* NO_SHA256 */
+#endif /* WOLF_CRYPT_SHA256_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/sha512.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/sha512.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/sha512.h	(revision 164)
@@ -0,0 +1,102 @@
+/* sha512.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WOLF_CRYPT_SHA512_H
+#define WOLF_CRYPT_SHA512_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef WOLFSSL_SHA512
+
+/* for fips @wc_fips */
+#ifdef HAVE_FIPS
+    #define CYASSL_SHA512
+    #if defined(WOLFSSL_SHA384)
+        #define CYASSL_SHA384
+    #endif
+    #include <cyassl/ctaocrypt/sha512.h>
+#endif
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#ifndef HAVE_FIPS /* avoid redefinition of structs */
+
+/* in bytes */
+enum {
+    SHA512              =   4,   /* hash type unique */
+    SHA512_BLOCK_SIZE   = 128,
+    SHA512_DIGEST_SIZE  =  64,
+    SHA512_PAD_SIZE     = 112
+};
+
+
+/* Sha512 digest */
+typedef struct Sha512 {
+    word32  buffLen;   /* in bytes          */
+    word32  loLen;     /* length in bytes   */
+    word32  hiLen;     /* length in bytes   */
+    word64  digest[SHA512_DIGEST_SIZE / sizeof(word64)];
+    word64  buffer[SHA512_BLOCK_SIZE  / sizeof(word64)];
+} Sha512;
+
+#endif /* HAVE_FIPS */
+
+WOLFSSL_API int wc_InitSha512(Sha512*);
+WOLFSSL_API int wc_Sha512Update(Sha512*, const byte*, word32);
+WOLFSSL_API int wc_Sha512Final(Sha512*, byte*);
+
+#if defined(WOLFSSL_SHA384)
+
+#ifndef HAVE_FIPS /* avoid redefinition of structs */
+/* in bytes */
+enum {
+    SHA384              =   5,   /* hash type unique */
+    SHA384_BLOCK_SIZE   = 128,
+    SHA384_DIGEST_SIZE  =  48,
+    SHA384_PAD_SIZE     = 112
+};
+
+
+/* Sha384 digest */
+typedef struct Sha384 {
+    word32  buffLen;   /* in bytes          */
+    word32  loLen;     /* length in bytes   */
+    word32  hiLen;     /* length in bytes   */
+    word64  digest[SHA512_DIGEST_SIZE / sizeof(word64)]; /* for transform 512 */
+    word64  buffer[SHA384_BLOCK_SIZE  / sizeof(word64)];
+} Sha384;
+#endif /* HAVE_FIPS */
+
+WOLFSSL_API int wc_InitSha384(Sha384*);
+WOLFSSL_API int wc_Sha384Update(Sha384*, const byte*, word32);
+WOLFSSL_API int wc_Sha384Final(Sha384*, byte*);
+
+#endif /* WOLFSSL_SHA384 */
+
+#ifdef __cplusplus
+    } /* extern "C" */
+#endif
+
+#endif /* WOLFSSL_SHA512 */
+#endif /* WOLF_CRYPT_SHA512_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/types.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/types.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/types.h	(revision 164)
@@ -0,0 +1,341 @@
+/* types.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef WOLF_CRYPT_TYPES_H
+#define WOLF_CRYPT_TYPES_H
+
+	#include <wolfssl/wolfcrypt/settings.h>
+	#include <wolfssl/wolfcrypt/wc_port.h>
+
+	#ifdef __cplusplus
+	    extern "C" {
+	#endif
+
+
+	#if defined(WORDS_BIGENDIAN)
+	    #define BIG_ENDIAN_ORDER
+	#endif
+
+	#ifndef BIG_ENDIAN_ORDER
+	    #define LITTLE_ENDIAN_ORDER
+	#endif
+
+	#ifndef WOLFSSL_TYPES
+	    #ifndef byte
+	        typedef unsigned char  byte;
+	    #endif
+	    typedef unsigned short word16;
+	    typedef unsigned int   word32;
+	#endif
+
+
+	/* try to set SIZEOF_LONG or LONG_LONG if user didn't */
+	#if !defined(_MSC_VER) && !defined(__BCPLUSPLUS__)
+	    #if !defined(SIZEOF_LONG_LONG) && !defined(SIZEOF_LONG)
+	        #if (defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) \
+	                || defined(__mips64)  || defined(__x86_64__))
+	            /* long should be 64bit */
+	            #define SIZEOF_LONG 8
+	        #elif defined(__i386__) || defined(__CORTEX_M3__)
+	            /* long long should be 64bit */
+	            #define SIZEOF_LONG_LONG 8
+	        #endif
+	    #endif
+	#endif
+
+
+	#if defined(_MSC_VER) || defined(__BCPLUSPLUS__)
+	    #define WORD64_AVAILABLE
+	    #define W64LIT(x) x##ui64
+	    typedef unsigned __int64 word64;
+	#elif defined(SIZEOF_LONG) && SIZEOF_LONG == 8
+	    #define WORD64_AVAILABLE
+	    #define W64LIT(x) x##LL
+	    typedef unsigned long word64;
+	#elif defined(SIZEOF_LONG_LONG) && SIZEOF_LONG_LONG == 8
+	    #define WORD64_AVAILABLE
+	    #define W64LIT(x) x##LL
+	    typedef unsigned long long word64;
+	#elif defined(__SIZEOF_LONG_LONG__) && __SIZEOF_LONG_LONG__ == 8
+	    #define WORD64_AVAILABLE
+	    #define W64LIT(x) x##LL
+	    typedef unsigned long long word64;
+	#else
+	    #define MP_16BIT  /* for mp_int, mp_word needs to be twice as big as
+	                         mp_digit, no 64 bit type so make mp_digit 16 bit */
+	#endif
+
+
+	/* These platforms have 64-bit CPU registers.  */
+	#if (defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || \
+	     defined(__mips64)  || defined(__x86_64__) || defined(_M_X64))
+	    typedef word64 wolfssl_word;
+	#else
+	    typedef word32 wolfssl_word;
+	    #ifdef WORD64_AVAILABLE
+	        #define WOLFCRYPT_SLOW_WORD64
+	    #endif
+	#endif
+
+
+	enum {
+	    WOLFSSL_WORD_SIZE  = sizeof(wolfssl_word),
+	    WOLFSSL_BIT_SIZE   = 8,
+	    WOLFSSL_WORD_BITS  = WOLFSSL_WORD_SIZE * WOLFSSL_BIT_SIZE
+	};
+
+	#define WOLFSSL_MAX_16BIT 0xffffU
+
+	/* use inlining if compiler allows */
+	#ifndef INLINE
+	#ifndef NO_INLINE
+	    #ifdef _MSC_VER
+	        #define INLINE __inline
+	    #elif defined(__GNUC__)
+               #ifdef WOLFSSL_VXWORKS
+                   #define INLINE __inline__
+               #else
+                   #define INLINE inline
+               #endif
+	    #elif defined(__IAR_SYSTEMS_ICC__)
+	        #define INLINE inline
+	    #elif defined(THREADX)
+	        #define INLINE _Inline
+	    #else
+	        #define INLINE
+	    #endif
+	#else
+	    #define INLINE
+	#endif
+	#endif
+
+
+	/* set up rotate style */
+	#if defined(_MSC_VER) || defined(__BCPLUSPLUS__)
+	    #define INTEL_INTRINSICS
+	    #define FAST_ROTATE
+	#elif defined(__MWERKS__) && TARGET_CPU_PPC
+	    #define PPC_INTRINSICS
+	    #define FAST_ROTATE
+	#elif defined(__GNUC__) && defined(__i386__)
+	        /* GCC does peephole optimizations which should result in using rotate
+	           instructions  */
+	    #define FAST_ROTATE
+	#endif
+
+
+	/* set up thread local storage if available */
+	#ifdef HAVE_THREAD_LS
+	    #if defined(_MSC_VER)
+	        #define THREAD_LS_T __declspec(thread)
+	    /* Thread local storage only in FreeRTOS v8.2.1 and higher */
+	    #elif defined(FREERTOS)
+	        #define THREAD_LS_T
+	    #else
+	        #define THREAD_LS_T __thread
+	    #endif
+	#else
+	    #define THREAD_LS_T
+	#endif
+
+
+	/* Micrium will use Visual Studio for compilation but not the Win32 API */
+	#if defined(_WIN32) && !defined(MICRIUM) && !defined(FREERTOS) && !defined(FREERTOS_TCP) \
+	        && !defined(EBSNET) && !defined(WOLFSSL_uITRON4)
+	    #define USE_WINDOWS_API
+	#endif
+
+
+	/* idea to add global alloc override by Moises Guimaraes  */
+	/* default to libc stuff */
+	/* XREALLOC is used once in normal math lib, not in fast math lib */
+	/* XFREE on some embeded systems doesn't like free(0) so test  */
+	#if defined(XMALLOC_USER)
+	    /* prototypes for user heap override functions */
+	    #include <stddef.h>  /* for size_t */
+	    //extern void *XMALLOC(size_t n, void* heap, int type);
+	    //extern void *XREALLOC(void *p, size_t n, void* heap, int type);
+	    //extern void XFREE(void *p, void* heap, int type);
+	#elif defined(NO_WOLFSSL_MEMORY)
+	    /* just use plain C stdlib stuff if desired */
+	    #include <stdlib.h>
+	    #define XMALLOC(s, h, t)     ((void)h, (void)t, malloc((s)))
+	    #define XFREE(p, h, t)       {void* xp = (p); if((xp)) free((xp));}
+	    #define XREALLOC(p, n, h, t) realloc((p), (n))
+	#elif !defined(MICRIUM_MALLOC) && !defined(EBSNET) \
+	        && !defined(WOLFSSL_SAFERTOS) && !defined(FREESCALE_MQX) \
+	        && !defined(FREESCALE_KSDK_MQX) && !defined(FREESCALE_FREE_RTOS) \
+            && !defined(WOLFSSL_LEANPSK) && !defined(FREERTOS) && !defined(FREERTOS_TCP)\
+            && !defined(WOLFSSL_uITRON4) && !defined(WOLFSSL_uTKERNEL2)
+	    /* default C runtime, can install different routines at runtime via cbs */
+	    #include <wolfssl/wolfcrypt/memory.h>
+	    #define XMALLOC(s, h, t)     ((void)h, (void)t, wolfSSL_Malloc((s)))
+	    #define XFREE(p, h, t)       {void* xp = (p); if((xp)) wolfSSL_Free((xp));}
+	    #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n))
+	#endif
+
+	#ifndef STRING_USER
+	    #include <string.h>
+	    char* mystrnstr(const char* s1, const char* s2, unsigned int n);
+
+	    #define XMEMCPY(d,s,l)    memcpy((d),(s),(l))
+	    #define XMEMSET(b,c,l)    memset((b),(c),(l))
+	    #define XMEMCMP(s1,s2,n)  memcmp((s1),(s2),(n))
+	    #define XMEMMOVE(d,s,l)   memmove((d),(s),(l))
+
+	    #define XSTRLEN(s1)       strlen((s1))
+	    #define XSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n))
+	    /* strstr, strncmp, and strncat only used by wolfSSL proper,
+         * not required for wolfCrypt only */
+	    #define XSTRSTR(s1,s2)    strstr((s1),(s2))
+	    #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n))
+	    #define XSTRNCMP(s1,s2,n) strncmp((s1),(s2),(n))
+	    #define XSTRNCAT(s1,s2,n) strncat((s1),(s2),(n))
+	    #ifndef USE_WINDOWS_API
+	        #define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n))
+	    #else
+	        #define XSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n))
+	    #endif
+
+        #if defined(WOLFSSL_CERT_EXT) || defined(HAVE_ALPN)
+            /* use only Thread Safe version of strtok */
+            #ifndef USE_WINDOWS_API
+                #define XSTRTOK strtok_r
+            #else
+                #define XSTRTOK strtok_s
+            #endif
+        #endif
+	#endif
+
+	#ifndef CTYPE_USER
+	    #include <ctype.h>
+	    #if defined(HAVE_ECC) || defined(HAVE_OCSP) || defined(WOLFSSL_KEY_GEN)
+	        #define XTOUPPER(c)     toupper((c))
+	        #define XISALPHA(c)     isalpha((c))
+	    #endif
+	    /* needed by wolfSSL_check_domain_name() */
+	    #define XTOLOWER(c)      tolower((c))
+	#endif
+
+
+	/* memory allocation types for user hints */
+	enum {
+	    DYNAMIC_TYPE_CA           = 1,
+	    DYNAMIC_TYPE_CERT         = 2,
+	    DYNAMIC_TYPE_KEY          = 3,
+	    DYNAMIC_TYPE_FILE         = 4,
+	    DYNAMIC_TYPE_SUBJECT_CN   = 5,
+	    DYNAMIC_TYPE_PUBLIC_KEY   = 6,
+	    DYNAMIC_TYPE_SIGNER       = 7,
+	    DYNAMIC_TYPE_NONE         = 8,
+	    DYNAMIC_TYPE_BIGINT       = 9,
+	    DYNAMIC_TYPE_RSA          = 10,
+	    DYNAMIC_TYPE_METHOD       = 11,
+	    DYNAMIC_TYPE_OUT_BUFFER   = 12,
+	    DYNAMIC_TYPE_IN_BUFFER    = 13,
+	    DYNAMIC_TYPE_INFO         = 14,
+	    DYNAMIC_TYPE_DH           = 15,
+	    DYNAMIC_TYPE_DOMAIN       = 16,
+	    DYNAMIC_TYPE_SSL          = 17,
+	    DYNAMIC_TYPE_CTX          = 18,
+	    DYNAMIC_TYPE_WRITEV       = 19,
+	    DYNAMIC_TYPE_OPENSSL      = 20,
+	    DYNAMIC_TYPE_DSA          = 21,
+	    DYNAMIC_TYPE_CRL          = 22,
+	    DYNAMIC_TYPE_REVOKED      = 23,
+	    DYNAMIC_TYPE_CRL_ENTRY    = 24,
+	    DYNAMIC_TYPE_CERT_MANAGER = 25,
+	    DYNAMIC_TYPE_CRL_MONITOR  = 26,
+	    DYNAMIC_TYPE_OCSP_STATUS  = 27,
+	    DYNAMIC_TYPE_OCSP_ENTRY   = 28,
+	    DYNAMIC_TYPE_ALTNAME      = 29,
+	    DYNAMIC_TYPE_SUITES       = 30,
+	    DYNAMIC_TYPE_CIPHER       = 31,
+	    DYNAMIC_TYPE_RNG          = 32,
+	    DYNAMIC_TYPE_ARRAYS       = 33,
+	    DYNAMIC_TYPE_DTLS_POOL    = 34,
+	    DYNAMIC_TYPE_SOCKADDR     = 35,
+	    DYNAMIC_TYPE_LIBZ         = 36,
+	    DYNAMIC_TYPE_ECC          = 37,
+	    DYNAMIC_TYPE_TMP_BUFFER   = 38,
+	    DYNAMIC_TYPE_DTLS_MSG     = 39,
+	    DYNAMIC_TYPE_CAVIUM_TMP   = 40,
+	    DYNAMIC_TYPE_CAVIUM_RSA   = 41,
+	    DYNAMIC_TYPE_X509         = 42,
+	    DYNAMIC_TYPE_TLSX         = 43,
+	    DYNAMIC_TYPE_OCSP         = 44,
+	    DYNAMIC_TYPE_SIGNATURE    = 45,
+	    DYNAMIC_TYPE_HASHES       = 46,
+        DYNAMIC_TYPE_SRP          = 47,
+        DYNAMIC_TYPE_COOKIE_PWD   = 48,
+        DYNAMIC_TYPE_USER_CRYPTO  = 49
+	};
+
+	/* max error buffer string size */
+	enum {
+	    WOLFSSL_MAX_ERROR_SZ = 80
+	};
+
+	/* stack protection */
+	enum {
+	    MIN_STACK_BUFFER = 8
+	};
+
+
+
+	/* settings detection for compile vs runtime math incombatibilities */
+	enum {
+	#if !defined(USE_FAST_MATH) && !defined(SIZEOF_LONG) && !defined(SIZEOF_LONG_LONG)
+	    CTC_SETTINGS = 0x0
+	#elif !defined(USE_FAST_MATH) && defined(SIZEOF_LONG) && (SIZEOF_LONG == 8)
+	    CTC_SETTINGS = 0x1
+	#elif !defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8)
+	    CTC_SETTINGS = 0x2
+	#elif !defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 4)
+	    CTC_SETTINGS = 0x4
+	#elif defined(USE_FAST_MATH) && !defined(SIZEOF_LONG) && !defined(SIZEOF_LONG_LONG)
+	    CTC_SETTINGS = 0x8
+	#elif defined(USE_FAST_MATH) && defined(SIZEOF_LONG) && (SIZEOF_LONG == 8)
+	    CTC_SETTINGS = 0x10
+	#elif defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8)
+	    CTC_SETTINGS = 0x20
+	#elif defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 4)
+	    CTC_SETTINGS = 0x40
+	#else
+	    #error "bad math long / long long settings"
+	#endif
+	};
+
+
+	WOLFSSL_API word32 CheckRunTimeSettings(void);
+
+	/* If user uses RSA, DH, DSA, or ECC math lib directly then fast math and long
+	   types need to match at compile time and run time, CheckCtcSettings will
+	   return 1 if a match otherwise 0 */
+	#define CheckCtcSettings() (CTC_SETTINGS == CheckRunTimeSettings())
+
+
+	#ifdef __cplusplus
+	    }   /* extern "C" */
+	#endif
+
+#endif /* WOLF_CRYPT_TYPES_H */
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/visibility.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/visibility.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/visibility.h	(revision 164)
@@ -0,0 +1,75 @@
+/* visibility.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Visibility control macros */
+
+#ifndef WOLF_CRYPT_VISIBILITY_H
+#define WOLF_CRYPT_VISIBILITY_H
+
+
+/* for compatibility and so that fips is using same name of macro @wc_fips */
+#ifdef HAVE_FIPS
+    #include <cyassl/ctaocrypt/visibility.h>
+    #define WOLFSSL_API   CYASSL_API
+	#define WOLFSSL_LOCAL CYASSL_LOCAL
+#else
+
+/* WOLFSSL_API is used for the public API symbols.
+        It either imports or exports (or does nothing for static builds)
+
+   WOLFSSL_LOCAL is used for non-API symbols (private).
+*/
+
+#if defined(BUILDING_WOLFSSL)
+    #if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
+        #define WOLFSSL_API   __attribute__ ((visibility("default")))
+        #define WOLFSSL_LOCAL __attribute__ ((visibility("hidden")))
+    #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
+        #define WOLFSSL_API   __global
+        #define WOLFSSL_LOCAL __hidden
+    #elif defined(_MSC_VER)
+        #ifdef WOLFSSL_DLL
+            #define WOLFSSL_API __declspec(dllexport)
+        #else
+            #define WOLFSSL_API
+        #endif
+        #define WOLFSSL_LOCAL
+    #else
+        #define WOLFSSL_API
+        #define WOLFSSL_LOCAL
+    #endif /* HAVE_VISIBILITY */
+#else /* BUILDING_WOLFSSL */
+    #if defined(_MSC_VER)
+        #ifdef WOLFSSL_DLL
+            #define WOLFSSL_API __declspec(dllimport)
+        #else
+            #define WOLFSSL_API
+        #endif
+        #define WOLFSSL_LOCAL
+    #else
+        #define WOLFSSL_API
+        #define WOLFSSL_LOCAL
+    #endif
+#endif /* BUILDING_WOLFSSL */
+
+#endif /* HAVE_FIPS */
+#endif /* WOLF_CRYPT_VISIBILITY_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/wc_encrypt.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/wc_encrypt.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/wc_encrypt.h	(revision 164)
@@ -0,0 +1,62 @@
+/* wc_encrypt.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef WOLF_CRYPT_ENCRYPT_H
+#define WOLF_CRYPT_ENCRYPT_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#ifndef NO_AES
+WOLFSSL_API int  wc_AesCbcEncryptWithKey(byte* out, const byte* in, word32 inSz,
+                                         const byte* key, word32 keySz,
+                                         const byte* iv);
+WOLFSSL_API int  wc_AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz,
+                                         const byte* key, word32 keySz,
+                                         const byte* iv);
+#endif /* !NO_AES */
+
+
+#ifndef NO_DES3
+WOLFSSL_API int  wc_Des_CbcDecryptWithKey(byte* out,
+                                          const byte* in, word32 sz,
+                                          const byte* key, const byte* iv);
+WOLFSSL_API int  wc_Des_CbcEncryptWithKey(byte* out,
+                                          const byte* in, word32 sz,
+                                          const byte* key, const byte* iv);
+WOLFSSL_API int  wc_Des3_CbcEncryptWithKey(byte* out,
+                                           const byte* in, word32 sz,
+                                           const byte* key, const byte* iv);
+WOLFSSL_API int  wc_Des3_CbcDecryptWithKey(byte* out,
+                                           const byte* in, word32 sz,
+                                           const byte* key, const byte* iv);
+#endif /* !NO_DES3 */
+
+#ifdef __cplusplus
+    }  /* extern "C" */
+#endif
+
+#endif /* WOLF_CRYPT_ENCRYPT_H */
+
Index: UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/wc_port.h
===================================================================
--- UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/wc_port.h	(revision 164)
+++ UsbWattMeter/trunk/wolfssl-3.7.0/wolfssl/wolfcrypt/wc_port.h	(revision 164)
@@ -0,0 +1,267 @@
+/* wc_port.h
+ *
+ * Copyright (C) 2006-2015 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef WOLF_CRYPT_PORT_H
+#define WOLF_CRYPT_PORT_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+#ifdef USE_WINDOWS_API
+    #ifdef WOLFSSL_GAME_BUILD
+        #include "system/xtl.h"
+    #else
+        #ifndef WIN32_LEAN_AND_MEAN
+            #define WIN32_LEAN_AND_MEAN
+        #endif
+        #if defined(_WIN32_WCE) || defined(WIN32_LEAN_AND_MEAN)
+            /* On WinCE winsock2.h must be included before windows.h */
+            #include <winsock2.h>
+        #endif
+        #include <windows.h>
+    #endif
+#elif defined(THREADX)
+    #ifndef SINGLE_THREADED
+        #include "tx_api.h"
+    #endif
+#elif defined(MICRIUM)
+    /* do nothing, just don't pick Unix */
+#elif defined(FREERTOS) || defined(FREERTOS_TCP) || defined(WOLFSSL_SAFERTOS)
+    /* do nothing */
+#elif defined(EBSNET)
+    /* do nothing */
+#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+    /* do nothing */
+#elif defined(FREESCALE_FREE_RTOS)
+    #include "fsl_os_abstraction.h"
+#elif defined(WOLFSSL_LWIP)
+    #include "lwip/sys.h"
+#elif defined(WOLFSSL_uITRON4)
+    #include "kernel.h"
+#elif  defined(WOLFSSL_uTKERNEL2)
+    #include "tk/tkernel.h"
+#elif defined(WOLFSSL_MDK_ARM)
+    #if defined(WOLFSSL_MDK5)
+         #include "cmsis_os.h"
+    #else
+        #include <rtl.h>
+    #endif
+#elif defined(WOLFSSL_CMSIS_RTOS)
+    #include "cmsis_os.h"
+#elif defined(WOLFSSL_TIRTOS)
+    #include <ti/sysbios/BIOS.h>
+    #include <ti/sysbios/knl/Semaphore.h>
+#else
+    #ifndef SINGLE_THREADED
+        #define WOLFSSL_PTHREADS
+        #include <pthread.h>
+    #endif
+    #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
+        #include <unistd.h>      /* for close of BIO */
+    #endif
+#endif
+
+
+#ifdef SINGLE_THREADED
+    typedef int wolfSSL_Mutex;
+#else /* MULTI_THREADED */
+    /* FREERTOS comes first to enable use of FreeRTOS Windows simulator only */
+    #if defined(FREERTOS) 
+        typedef xSemaphoreHandle wolfSSL_Mutex;
+    #elif defined(FREERTOS_TCP)
+        #include "FreeRTOS.h"
+        #include "semphr.h"
+		typedef SemaphoreHandle_t  wolfSSL_Mutex;
+    #elif defined(WOLFSSL_SAFERTOS)
+        typedef struct wolfSSL_Mutex {
+            signed char mutexBuffer[portQUEUE_OVERHEAD_BYTES];
+            xSemaphoreHandle mutex;
+        } wolfSSL_Mutex;
+    #elif defined(USE_WINDOWS_API)
+        typedef CRITICAL_SECTION wolfSSL_Mutex;
+    #elif defined(WOLFSSL_PTHREADS)
+        typedef pthread_mutex_t wolfSSL_Mutex;
+    #elif defined(THREADX)
+        typedef TX_MUTEX wolfSSL_Mutex;
+    #elif defined(MICRIUM)
+        typedef OS_MUTEX wolfSSL_Mutex;
+    #elif defined(EBSNET)
+        typedef RTP_MUTEX wolfSSL_Mutex;
+    #elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+        typedef MUTEX_STRUCT wolfSSL_Mutex;
+    #elif defined(FREESCALE_FREE_RTOS)
+        typedef mutex_t wolfSSL_Mutex;
+    #elif defined(WOLFSSL_LWIP)
+        typedef sys_mutex_t wolfSSL_Mutex;
+    #elif defined(WOLFSSL_uITRON4)
+        typedef struct wolfSSL_Mutex {
+            T_CSEM sem ;
+            ID     id ;
+        } wolfSSL_Mutex;
+    #elif defined(WOLFSSL_uTKERNEL2)
+        typedef struct wolfSSL_Mutex {
+            T_CSEM sem ;
+            ID     id ;
+        } wolfSSL_Mutex;
+    #elif defined(WOLFSSL_MDK_ARM)
+        #if defined(WOLFSSL_CMSIS_RTOS)
+            typedef osMutexId wolfSSL_Mutex;
+        #else
+            typedef OS_MUT wolfSSL_Mutex;
+        #endif
+    #elif defined(WOLFSSL_CMSIS_RTOS)
+        typedef osMutexId wolfSSL_Mutex;
+    #elif defined(WOLFSSL_TIRTOS)
+        typedef ti_sysbios_knl_Semaphore_Handle wolfSSL_Mutex;
+    #else
+        #error Need a mutex type in multithreaded mode
+    #endif /* USE_WINDOWS_API */
+#endif /* SINGLE_THREADED */
+        
+/* Enable crypt HW mutex for Freescale MMCAU */
+#if defined(FREESCALE_MMCAU)
+    #ifndef WOLFSSL_CRYPT_HW_MUTEX
+        #define WOLFSSL_CRYPT_HW_MUTEX  1
+    #endif
+#endif /* FREESCALE_MMCAU */
+
+#ifndef WOLFSSL_CRYPT_HW_MUTEX
+    #define WOLFSSL_CRYPT_HW_MUTEX  0
+#endif
+
+#if WOLFSSL_CRYPT_HW_MUTEX
+    /* wolfSSL_CryptHwMutexInit is called on first wolfSSL_CryptHwMutexLock, 
+       however it's recommended to call this directly on Hw init to avoid possible 
+       race condition where two calls to wolfSSL_CryptHwMutexLock are made at 
+       the same time. */
+    int wolfSSL_CryptHwMutexInit(void);
+    int wolfSSL_CryptHwMutexLock(void);
+    int wolfSSL_CryptHwMutexUnLock(void);
+#else
+    /* Define stubs, since HW mutex is disabled */
+    #define wolfSSL_CryptHwMutexInit()      0 /* Success */
+    #define wolfSSL_CryptHwMutexLock()      0 /* Success */
+    #define wolfSSL_CryptHwMutexUnLock()    0 /* Success */
+#endif /* WOLFSSL_CRYPT_HW_MUTEX */
+
+/* Mutex functions */
+WOLFSSL_LOCAL int InitMutex(wolfSSL_Mutex*);
+WOLFSSL_LOCAL int FreeMutex(wolfSSL_Mutex*);
+WOLFSSL_LOCAL int LockMutex(wolfSSL_Mutex*);
+WOLFSSL_LOCAL int UnLockMutex(wolfSSL_Mutex*);
+
+/* main crypto initialization function */
+WOLFSSL_API int wolfcrypt_Init(void);
+
+/* filesystem abstraction layer, used by ssl.c */
+#ifndef NO_FILESYSTEM
+
+#if defined(EBSNET)
+    #define XFILE                    int
+    #define XFOPEN(NAME, MODE)       vf_open((const char *)NAME, VO_RDONLY, 0);
+    #define XFSEEK                   vf_lseek
+    #define XFTELL                   vf_tell
+    #define XREWIND                  vf_rewind
+    #define XFREAD(BUF, SZ, AMT, FD) vf_read(FD, BUF, SZ*AMT)
+    #define XFWRITE(BUF, SZ, AMT, FD) vf_write(FD, BUF, SZ*AMT)
+    #define XFCLOSE                  vf_close
+    #define XSEEK_END                VSEEK_END
+    #define XBADFILE                 -1
+#elif defined(LSR_FS)
+    #include <fs.h>
+    #define XFILE                   struct fs_file*
+    #define XFOPEN(NAME, MODE)      fs_open((char*)NAME);
+    #define XFSEEK(F, O, W)         (void)F
+    #define XFTELL(F)               (F)->len
+    #define XREWIND(F)              (void)F
+    #define XFREAD(BUF, SZ, AMT, F) fs_read(F, (char*)BUF, SZ*AMT)
+    #define XFWRITE(BUF, SZ, AMT, F) fs_write(F, (char*)BUF, SZ*AMT)
+    #define XFCLOSE                 fs_close
+    #define XSEEK_END               0
+    #define XBADFILE                NULL
+#elif defined(FREESCALE_MQX)
+    #define XFILE                   MQX_FILE_PTR
+    #define XFOPEN                  fopen
+    #define XFSEEK                  fseek
+    #define XFTELL                  ftell
+    #define XREWIND(F)              fseek(F, 0, IO_SEEK_SET)
+    #define XFREAD                  fread
+    #define XFWRITE                 fwrite
+    #define XFCLOSE                 fclose
+    #define XSEEK_END               IO_SEEK_END
+    #define XBADFILE                NULL
+#elif defined(MICRIUM)
+    #include <fs.h>
+    #define XFILE      FS_FILE*
+    #define XFOPEN     fs_fopen
+    #define XFSEEK     fs_fseek
+    #define XFTELL     fs_ftell
+    #define XREWIND    fs_rewind
+    #define XFREAD     fs_fread
+    #define XFWRITE    fs_fwrite
+    #define XFCLOSE    fs_fclose
+    #define XSEEK_END  FS_SEEK_END
+    #define XBADFILE   NULL
+#else
+    /* stdio, default case */
+    #define XFILE      FILE*
+    #if defined(WOLFSSL_MDK_ARM)
+        #include <stdio.h>
+        extern FILE * wolfSSL_fopen(const char *name, const char *mode) ;
+        #define XFOPEN     wolfSSL_fopen
+    #else
+        #define XFOPEN     fopen
+    #endif
+    #define XFSEEK     fseek
+    #define XFTELL     ftell
+    #define XREWIND    rewind
+    #define XFREAD     fread
+    #define XFWRITE    fwrite
+    #define XFCLOSE    fclose
+    #define XSEEK_END  SEEK_END
+    #define XBADFILE   NULL
+#endif
+
+#endif /* NO_FILESYSTEM */
+
+
+/* Windows API defines its own min() macro. */
+#if defined(USE_WINDOWS_API)
+    #ifdef min
+        #define WOLFSSL_HAVE_MIN
+    #endif /* min */
+    #ifdef max
+        #define WOLFSSL_HAVE_MAX
+    #endif /* max */
+#endif /* USE_WINDOWS_API */
+
+
+#ifdef __cplusplus
+    }  /* extern "C" */
+#endif
+
+#endif /* WOLF_CRYPT_PORT_H */
+
